Improving a Famous Architecture

When one thinks in terms of using a 12-bit word length, the famous PDP-8 from the legendary Digital Equipment Corporation comes immediately to mind.

Because of how it achieved more with less, though, it inevitably had limitations. And, thus, one might consider how, at the cost of some additional complexity, those limitations might be removed.

On the PDP-8, the DCA (Deposit and Clear Accumulator) instruction was present instead of a store instruction, so that the TAD (Two's Complement Add) instruction could do double duty, avoiding the need for a load instruction.

The first three lines in the illustration above shows a way to obtain more opcodes.

First, there are load and store memory-reference instructions which have both an indirect bit and a page bit:

000IP LDA  Load Accumulator
001IP STO  Store

Then, the various arithmetic instructions get a page bit, but no indirect bit:

0100P ADD  Add
0101P SUB  Subtract
0110P MUL  Multiply
0111P DIV  Divide
1000P AND  And
1001P ORA  Or Accumulator
1010P XOR  Exclusive OR
1011P ISZ  Increment and Skip if Zero

thus allowing opcodes for a full complement of instructions.

But this does mean that the opcode for the IOT instruction is still foregone, in order to have two jump instructions, which have an indirect bit, but no page bit:

110I0 JMP  Jump
110I1 JMS  Jump to Subroutine

Another improvement involves the operate instructions. Instead of having several possible useless combinations from setting the two bits for shifting right and shifting left at the same time, the bit used for switching the interpretation of the bits is used to select the direction instead of shift one or shift two.

Setting bits for shift one and shift two at the same time gives the obvious and useful meaning of shift three.

Having explicit multiply and divide instructions allows the same instruction set to be used if the computer is switched into alternate modes to operate on 24 bit integers, or on floating-point numbers. Of course, some of the operate instructions - and the bitwise logical operations - would not apply to floating-point numbers. One possibility is to use the codes for the elementary transcendental functions.

Another improvement that suggests itself in association with the change to the memory reference instructions is to have the page bit switch between two pages indicated by the contents of two page registers, instead of switching between page zero and the current page. Assuming pages are still within a 4K field, each page register would be five bits in length.

One could use a 12-bit register, with one bit reserved, as follows:

(reserved bit)
5 bits: page if page bit is zero
1 bit: if 1, current page used if page bit is one
5 bits: page if page bit is one (and previous bit is zero)

A bit isn't required to select page zero for when the page bit is zero, since the five bits giving the page can be zero to specify the page.

In the case of the jump instructions, with no page bit, though, they would always use the current page, since their requirements differ from those of instructions that operate on data.

The next question that comes up - aside from the one of which opcode might be used to load the page register - is about how to improve the jump to subroutine instruction. Storing the return address at the effective address, and then continuing excution with the following word, prevents its use for re-entrant code, and mixes data with instructions.

The obvious solution would be to introduce a stack, as most 8-bit microprocessors did.

However, instead of adding a new register, one could add only a single bit of machine state: when branching to a subroutine, initially, the instructions are interpreted in a different fashion.

  000 LDA  Load Accumulator
  001 STO  Store
  010 LMQ  Load Multiplier Quotient
  011 SMQ  Store Multiplier Quotient
  100 LPR  Load Page Register
  101 SPR  Save Page Register
  110 INC  Increment
* 111 SRA  Store Return Address

where the instructions marked with an asterisk cause an exit from this alternate mode of interpretation, but the others do not.

Thus, an indirect store return address, following an increment operation on the pointer used, allows a stack to be implemented.

To make the instructions for loading and saving the page register more useful, the load page register instruction moves the former page register contents to a buffer, and the save page register instruction actually saves the contents of that buffer - so that on return, the former value of the page register can be found. Of course, the return address is stored from a buffer in which the program counter contents were placed by the JMS instruction.

This suggests that a modified version of these instructions, ending like this:

  110 DEC  Decrement
* 111 RJP  Return Jump

should be offered as a mechanism to return from a subroutine.

In order that subroutines may be called from routines having different values contained in the page register, when the computer is in either of these modes, the page bit, if 1, will select the current page, from which indirect addresses may be used if required. But if it is zero, the appropriate bits from the page register will still be used; this will be useful if those bits do not change, and avoids the overuse of page zero as a limited resource.

So, let's go to the one un-needed opcode, rotate zero left, which remains for the shift instructions, and see how we might use it:

7002 ETS  Enter Single (return to normal 12-bit integer operation)
7022 ETD  Enter Double (24 bit integer operation)
7042 ETT  Enter Triple (36 bit integer operation)
7102 ETF  Enter Floating (36 bit)
7122 ETI  Enter Intermediate (48 bit)
7142 ETL  Enter Long (60 bit)
7162 ETE  Enter Extended (72 bit)
7222 EAD  Enter Auxilliary Double (24 bit integer operation)
7242 EAT  Enter Auxilliary Triple (36 bit integer operation)
7302 EAF  Enter Auxilliary Floating (36 bit)
7322 EAI  Enter Auxilliary Intermediate (48 bit)
7342 EAL  Enter Auxilliary Long (60 bit)
7362 EAE  Enter Auxilliary Extended (72 bit)
7003 ESR  Enter Subroutine Return
7023 EXM  Enter Index Mode
7043 ECM  Enter Compatible Mode
7063 ERM  Enter Reference Mode

where the Enter Auxilliary instructions shift to an instruction format similar to that of the FPP-12, similarly to the Start instructions in the FPP-12 instruction set, while the plain Enter instructions remain within the normal instruction format.

The FPP-12 used seven from a group of eight memory locations as index registers.

Index mode permits indexing without an index register. A portion of the possible instruction opcodes are interpreted normally. Another portion operate on the effective address of the following instruction instead of on the accumulator, thus achieving the effect of indexing without an index register. This technique was used in one early computer, the Elliott 803, but through the use of an extra bit for each pair of instructions.

The Jump, Jump to Subroutine, and operate instructions are only intelligible if they work normally. But the only really useful modified instructions are Add and perhaps Subtract. The ISZ instruction is associated with looping, and looping is where indexing is most useful, and so replacing it with the modified Add is not really the right way to go.

Upon reflection, it would be useful to allow the alternative of modifying the instruction itself rather than its effective address; in that case, even operate instructions could usefully be modified.

So, leaving the other instructions unmodified, the group of arithmmetic instructions with a page bit but no indirect bit will be changed like this:

0100P AEA  Add to Effective Address
0101P SEA  Subtract from Effective Address
0110P ADI  Add to Instruction
0111P SUI  Subtract from Insruction
1000P ANI  And to Instruction
1001P ORI  Or to Instruction
1010P XOI  Exclusive OR to Instruction
1011P ISZ  Increment and Skip if Zero (unmodified)

Only when an instruction is modified to perform an action of changing the following instruction is the following instruction then interpreted conventionally after the change; unmodified instructions are interpreted as singletons.

Enter Compatible Mode allows the computer to execute PDP-8 programs. Aside from an IOT instruction for switching to this improved mode, there is one other incompatibility: the floating-point formats accessed by instructions of the FPP-12 type are the modified IEEE-754 formats shown here (72-bit long floating point numbers will be the Extended precision, having a 12-bit exponent and no hidden bit, but the exponent will be offset in the IEEE-754 fashion, so they, also, will not be fully compatible).

Enter Reference Mode leaves the operate instructions in their improved form, but it also brings back the IOT instruction. As well, the operate instructions that skip the next instruction are modified so that they skip the next two locations in memory.

In that mode, memory reference instructions take the form:

thus allowing both the field registers and the page registers to be ignored, while making the whole 32K word virtual address space directly accessible.

Of course, it is envisioned that a chip implementing this instruction set would have more than 32K of on-chip memory, never mind how much RAM it might be connected to.

Hence, presumably the first three bits of a 15-bit address would be used to select the actual prefix to the physical address from a group of registers. Or, to avoid adding too many registers to the architecture, the prefixes could be retrieved from memory locations, as the physical translation of a virtual field value would only need to be refreshed when a program is loaded back into memory: changing it in the middle of execution, since that would produce invalid results, does not need to be supported.