Table of Contents for Programming Languages: a survey



" At its inception, the programmer's view of the PDP-8 had only eight instructions and two registers (a 12-bit accumulator, AC, and a carry bit called the "link register", L). "

"PDP-8 •Very simple machine and instruction set •Has one register (the Accumulator) •12-bit instructions operate on 12-bit words •Very efficient implementation –35 operations along with indirect addressing, displacement addressing and indexing in 12 bits •The lack of registers is handled by using part of the first physical page of memory as a register file

PDP-8 Memory References •Main memory consisted of 4096 words divided into 32 128-word pages •Instructions with a memory reference had a 7-bit address plus two modifier bits (leaving 3 bits for opcode!) —Z/C bit Page 0 or current page (with this instruction) —D/I bit Direct or Indirect addressing •In addition the first 8 words of page 0 are treated as autoindex “registers” •Note that memory-indirect addressing was used because processor had no index registers Instruction Formats •A 3-bit opcode and three types of instructions —For opcodes 0–5 (6 basic instructions) we have single address mem ref with Z/C I/D bits •Opcode 6 is I/O with 6 device-select bits and 3 operation bits •Opcode 7 defines a register reference or microinstruction —Three groups, where bits are used to specify operation (e.g., clear accumulator) —Forerunner of modern microprogramming " --

" Basic instructions

    000 – AND – AND the memory operand with AC.
    001 – TAD – Two's complement ADd the memory operand to <L,AC> (a 12 bit signed value (AC) w. carry in L).
    010 – ISZ – Increment the memory operand and Skip next instruction if result is Zero.
    011 – DCA – Deposit AC into the memory operand and Clear AC.
    100 – JMS – JuMp to Subroutine (storing return address in first word of subroutine!).
    101 – JMP – JuMP.
    110 – IOT – Input/Output Transfer (see below).
    111 – OPR – microcoded OPeRations (see below).

IOT (Input-Output Transfer) instructions

The PDP-8 processor defined few of the IOT instructions, but simply provided a framework. Most IOT instructions were defined by the individual I/O devices. 0 2 3 8 9 11 6=IOT Device Function


Bits 3 through 8 of an IOT instruction selected an I/O device. Some of these device addresses were standardized by convention:

    00 was handled by the processor and not sent to any I/O device (see below)
    01 was usually the high-speed paper tape reader
    02 was the high-speed paper tape punch
    03 was the console keyboard (and any associated low-speed paper tape reader)
    04 was the console printer (and any associated low-speed paper tape punch)

Instructions for device 0 affected the processor as a whole. For example, ION (6001) enabled interrupt processing, and IOFF (6002) disabled it.


Bits 9 through 11 of an IOT instruction selected the function(s) the device would perform. Simple devices (such as the paper tape reader and punch and the console keyboard and printer) would use the bits in standard ways:

    Bit 11 caused the processor to skip the next instruction if the I/O device was ready
    Bit 10 cleared AC
    Bit 9 moved a word between AC and the device, initiated another I/O transfer, and cleared the device's "ready" flag

These operations took place in a well-defined order that gave useful results if more than one bit was set.

More complicated devices, such as disk drives, used these 3 bits in device-specific fashions. Typically, a device decoded the 3 bits to give 8 possible function codes. "

" OPR (OPeRate?)

Many operations were achieved using OPR, including most of the conditionals. OPR does not address a memory location; conditional execution is achieved by conditionally skipping one instruction, which was typically a JMP.

The OPR instruction was said to be "microcoded." This did not mean what the word means today (that a lower-level program fetched and interpreted the OPR instruction), but meant that each bit of the instruction word specified a certain action, and the programmer could achieve several actions in a single instruction cycle by setting multiple bits. In use, a programmer would write several instruction mnemonics alongside one another, and the assembler would combine them with OR to devise the actual instruction word. Many I/O devices supported "microcoded" IOT instructions.

Microcoded actions took place in a well-defined sequence designed to maximize the utility of many combinations.

The OPR instructions came in Groups. Bits 3, 8 and 11 identify the Group of an OPR instruction, so it was impossible to combine the microcoded actions from different groups. Group 1

           00 01 02 03 04 05 06 07 08 09 10 11
          | 1| 1| 1| 0|  |  |  |  |  |  |  |  |
                      |CLA   CMA   RAR   BSW
                          CLL   CML   RAL   IAC
       Execution order  1  1  2  2  4  4  4  3
    7200 – CLA – Clear Accumulator
    7100 –­ CLL – Clear the L Bit
    7040 – CMA – Ones Complement Accumulator
    7020 – CML – Complement L Bit
    7001 – IAC – Increment <L,AC>
    7010 – RAR – Rotate <L,AC> Right
    7004 – RAL – Rotate <L,AC> Left
    7012 – RTR – Rotate <L,AC> Right Twice
    7006 – RTL – Rotate <L,AC> Left Twice
    7002 – BSW – Byte Swap 6-bit "bytes" (PDP 8/e and up)

In most cases, the operations are sequenced so that they can be combined in the most useful ways. For example, combining CLA (CLear Accumulator), CLL (CLear Link), and IAC (Increment ACcumulator) first clears the AC and Link, then increments the accumulator, leaving it set to 1. Adding RAL to the mix (so CLA CLL IAC RAL) causes the accumulator to be cleared, incremented, then rotated left, leaving it set to 2. In this way, small integer constants were placed in the accumulator with a single instruction.

The combination CMA IAC, which the assembler let you abbreviate as CIA, produced the arithmetic inverse of AC: the twos-complement negation. Since there was no subtraction instruction, only the twos-complement add (TAD), computing the difference of two operands required first negating the subtrahend.

A Group 1 OPR instruction that has none of the microprogrammed bits set performs no action. The programmer can write NOP (No Operation) to assemble such an instruction. Group 2, Or Group

           00 01 02 03 04 05 06 07 08 09 10 11
          | 1| 1| 1| 1|  |  |  |  | 0|  |  | 0|
                      |CLA   SZA      OSR
                          SMA   SNL      HLT
                        2  1  1  1    3  3
    7600 – CLA – Clear AC
    7500 – SMA – Skip on AC < 0 (or group)
    7440 – SZA – Skip on AC = 0 (or group)
    7420 – SNL – Skip on L ≠ 0 (or group)
    7404 – OSR – logically 'or' front-panel switches with AC
    7402 – HLT – Halt

When bit 8 is clear, a skip is performed if any of the specified conditions are true. For example "SMA SZA", opcode 7540, skips if AC ≤ 0.

A Group 2 OPR instruction that has none of the microprogrammed bits set is another No-Op instruction. Group 2, And Group

           00 01 02 03 04 05 06 07 08 09 10 11
          | 1| 1| 1| 1|  |  |  |  | 1|  |  | 0|
                      |CLA   SNA      OSR
                          SPA   SZL      HLT
                        2  1  1  1    3  2
    7410 – SKP – Skip Unconditionally
    7610 – CLA – Clear AC
    7510 – SPA – Skip on AC ≥ 0 (and group)
    7450 – SNA – Skip on AC ≠ 0 (and group)
    7430 – SZL – Skip on L = 0 (and group) 

When bit 8 is set, the Group 2, Or skip condition is inverted: the skip is not performed if any of the group 2, Or conditions are true, meaning that all of the specified skip conditions must be true. For example, "SPA SNA", opcode 7550, skips if AC > 0. If none of bits 5–7 are set, then the skip is unconditional. Group 3

Unused bit combinations of OPR were defined as a third Group of microprogrammed actions mostly affecting the MQ (Multiplier/Quotient) register.

           00 01 02 03 04 05 06 07 08 09 10 11
          | 1| 1| 1| 1|  |  |  |  |  |  |  | 1|
                      |CLA   SCA   \_    _/
                      |   MQA   MQL  CODE
                        1* 2  2  2     3
    7601 – CLA – Clear AC
    7501 – MQA – Multiplier Quotient with AC (logical or MQ into AC)
    7441 – SCA – Step counter load into AC
    7421 – MQL – Multiplier Quotient Load (Transfer AC to MQ, clear AC)
    7621 – CAM – CLA + MQL clears both AC and MQ.

Typically CLA and MQA were combined to transfer MQ into AC. Another useful combination is MQA and MQL, to exchange the two registers.

Three bits specified a multiply/divide instruction to perform:

    7401 – No operation
    7403 – SCL – Step Counter Load (immediate word follows, PDP-8/I and up)
    7405 – MUY – Multiply
    7407 – DVI – Divide
    7411 – NMI – Normalize
    7413 – SHL – Shift left (immediate word follows)
    7415 – ASR – Arithmetic shift right
    7417 – LSR – Logical shift right


See also


" The CPU contained eight general-purpose 16-bit registers (R0 to R7). Register R7 was the program counter (PC). Although any register could be used as a stack pointer, R6 was the stack pointer (SP) used for hardware interrupts and traps. "

Addressing modes: register, register indirect, register indirect postincrement, register double indirect postincrement, register indirect predecrement, register double indirect predecrement, (register + offset) indirect, , (register + offset) double indirect

" Double-operand instructions "

General: MOV Logic: CMP, XOR Bit: BIT (bit test), BIC (bit clean), BIS (bit set), Arithmetic: ADD, SUB, MUL, DIV Bit arithmetic: ASH (Arithmetic shift), ASHC (Arithmetic shift combined: (R,R+1) 1= 1 1062 ASRB 0063 ASL Shift left: dest <<= 1 1063 ASLB 0064 MARK Return from subroutine, skip 0..63 instruction words 1064 MTPS Move to status: PS = src 0065 MFPI Move from previous I space: −(SP) = src 1065 MFPD Move from previous D space: −(SP) = src 0066 MTPI Move to previous I space: dest = (SP)+ 1066 MTPD Move to previous D space: dest = (SP)+ 0067 SXT Sign extend: dest = (16 copies of N flag) 1067 MFPS Move from status: dest = PS


" Conditional branch instructions


Opcode Mnemonic Effect 0000xx (System instructions) 0004xx BR Branch unconditionally 0010xx BNE Branch if not equal (Z=0) 0014xx BEQ Branch if equal (Z=1) 0020xx BGE Branch if greater that or equal (N

0024xx BLT Branch if less than (N0030xx BGT Branch if greater than (N^V = 1) 0034xx BLE Branch if less than or equal (N^V = 0) 1000xx BPL Branch if plus (N=0) 1004xx BMI Branch if minus (N=1) 1010xx BHI Branch if higher than (C1014xx BLOS Branch if lower or same (C1020xx BVC Branch if overflow clear (V=0) 1024xx BVS Branch if overflow set (V=1) 1030xx BCC Branch if carry clear (C=0) BHIS Branch if higher or same (C=0) 1034xx BCS Branch if carry set (C=1) BLO Branch if lower than (C=1) "
V = 0)
V = 1)
Z = 0)
Z = 1)

" Jump and subroutine instructions

    JMP (jump)
    JSR (jump to subroutine--see below)
    RTS (return from subroutine--see below)
    MARK (support of stack clean-up at return)
    EMT (emulator trap)
    TRAP, BPT (breakpoint trap)
    IOT (input/output trap)
    RTI & RTT (return from interrupt)

The JSR instruction could save any register on the stack. Programs that did not need this feature specified PC as the register (JSR PC,address) and the routine returned using RTS PC. If a routine were called with, for instance, "JSR R4, address", then the old value of R4 would be on the top of the stack and the return address (just after JSR) would be in R4. This let the routine gain access to values coded in-line by specifying (R4)+, or to in-line pointers by specifying @(R4)+. The autoincrementation moved past these data, to the point at which the caller's code resumed. Such a routine would have to specify RTS R4 to return to its caller. "

" Miscellaneous instructions

    HALT, WAIT (wait for interrupt)
    RESET (reset UNIBUS)

Condition-code operations

    CLC, CLV, CLZ, CLN, CCC (clear relevant condition code)
    SEC, SEV, SEZ, SEN, SCC (set relevant condition code)

The four condition codes in the processor status word (PSW) are

    N indicating a negative value
    Z indicating a zero (equal) condition
    V indicating an overflow condition, and
    C indicating a carry condition.

SCC and CCC respectively set and clear all four condition codes. "




Misc: SOB (Subtract one and branch; decrement and if result is non-zero, branch backward 0..63 words)

(also floating-point operations (075), system instructions (076))


" Single-operand instructions


Opcode Mnemonic Effect 0003 SWAB Swap bytes: rotate 8 bits 004r (Jump to subroutine) 104x (Emulator trap) 0050 CLR Clear: dest = 0 1050 CLRB 0051 COM Complement: dest = ~dest 1051 COMB 0052 INC Increment: dest += 1 1052 INCB 0053 DEC Decrement: dest −= 1 1053 DECB 0054 NEG Negate: dest = −dest 1054 NEGB 0055 ADC Add carry: dest += C 1055 ADCB 0056 SBC Subtract carry: dest −= C 1056 SBCB 0057 TST Test: Load src, set flags only 1057 TSTB 0060 ROR Rotate right 1 bit 1060 RORB 0061 ROL Rotate left 1 bit 1061 ROLB 0062 ASR Shift right: dest