This is a brief outline of the instruction set of the PDP-8, for a full reference see PDP-8 Small Computer Handbook
The PDP-8 was designed as a low-cost machine, so it’s architecture is very minimal, just a single 12-bit accumulator (AC), a 12-bit instruction pointer, a single bit link (carry) register (L) and an optional Multiplier Quotient (MQ) register.
Each instruction is 12-bits in length and has a three bit operation code, which gives (sort of) 8 possible instructions. One of the instructions, OPR – microcoded operations has a set of bits which initiate various operations giving roughly 34 extra instructions.
Instructions 0-5 have the same layout:
0 1 2 3 4 5 6 7 8 9 10 11 +-------+---+---+------------------+ | Op | I | Z | Offset | +-------+---+---+------------------+
bits 0-3 are the opcode
bit 3 is the indirect bit – any address generated by this instruction points to the actual address. There are some examples below
bit 4 is the zero page bit – if this is zero, the offset field references the current 512 byte page, if this is one, it refers to the first page of memory (0000-0077).
bits 5-11 are the offset into either the current page or the zero page.
Instructions 0-5
000 – AND and the memory field with AC, result to AC
001 – TAD add the memory field to AC. There is no load instruction, so to load a number into AC, it’s idiomatic to clear the accumulator and add the operand in.
010 – ISZ Increment the memory operand, and skip the next instruction if the result is zero
011 – DCA Deposit and clear AC – this is the complement to TAD, this allows a store followed by a load to be two instructions rather than three.
100 – JMS Jump to subroutine – Saves the next instruction address in the calculated memory address, and jumps to the address after the stored word. There is no return instruction, so to return from a subroutine, use an indirect jump to the subroutine address (example below)
101 – JMP Jump – transfer control to the calculated address
Instruction 6 IOT – I/O Transfer
This instrcution is used to communicate with the various PDP-8 peripherals, for example see my earlier post Dectape PDP-8 Interface for an example of how it is used.
The instruction has this format:
0 1 2 3 4 5 6 7 8 9 10 11 +--------+----------------+--------+ | 110 | Device |Function| +--------+----------------+--------+
I’ll describe the various IOT instructions along with the device.
Instruction 7 OPR – MIcrocoded Operations
This is the most complicated instruction of the PDP-8. Apart from the operation code, it is a set of bit fields which execute miscellaneous operations.
bit 3 = 0
4 - Clear AC 5 - Clear link 6 - Ones complement AC 7 - Complement link 11 - Increment I,AC 8 - Rotate L,AC left 9 - Rotate L,AC right 10 - Swap top six bits of AC with bottom 6 bit
The reason for the ordering is to allow for more useful combinations of instructions. For example:
7201 (111 010 000 001) – Clear AC, Clear link, Increment AC -> sets AC to 1 in a single instruction.
bit 3 = 1, bit 8 = 1, bit 11 = 0
5 - Skip next instruction if AC >= 0 6 - Skip next instruction if AC != 0 7 - Skip next instruction if L = 0 4 - Clear AC 9 - Inclusive OR front panel switches into AC 10 - Halt
bit 3 = 1, bit 11 = 1 – EAE expansion unit
4 - Clear AC 5 - Or MQ with AC 6 - Copy step counter to AC 7 - Move AC into MQ 8-10 - Arithmetic function: 000 - No op 001 - Step counter load (from next word) 010 - Multiply (MQ * next word => MQ,AC) 011 - Divide (MQ,AC / next word => MQ,AC) 100 - Normalise - Shift AC left until AC0,AC1 are differnt, number of shifts are stored in the step counter 101 - Shift left MQ,AC 110 - Arithmetic shift right MQ,AC 111 - Logical shift right MQ,AC
Examples
Add two numbers
0200 7300 CLA,CLL // Set AC to 0
0201 1004 TAD A // Add first number to AC
0202 1005 TAD B // Add second number to AC
0203 7402 HALT // Stop, AC will be displayed on the panel
0204 0012 A: 12
0205 0020 B: 20
Loop n times
<pre class="wp-block-syntaxhighlighter-code brush: plain; notranslate">0200 7300 CLA,CLL // Zero AC
0201 1055 TAD N // Load loop<br />0202 7401 CIA // Assembler shortcut for negate AC<br /> // Actually ones complement & increment<br /> // See OPR instruction above. <br /> // This is done because counting up <br /> // is easier than down<br />0203 4xxx LOOP: JSR DOSTUFF // Do loop function<br />0204 2000 ISZ // Increment AC and skip next if AC = 0<br />0205 7003 JMP LOOP // Repeat<br />// End of loop<br />0255 0010 N: 10</pre><p> </p>