### Instruction Set

Registers are written in upper case (the order may well change to assist in address decoding):

 A 000 general purpose B 001 general purpose C 010 general purpose (Call stack) D 011 general purpose (Data stack) E 100 general purpose (Execution pointer) Z 101 read Zero, write ignored P 110 program counter I 111 read 1 (Identity), write Instruction

Instructions are of one of these three forms:

 [condition] Rz = Rx op Ry 0xxx register to register through the ALU (xxx=op) [condition] Rx = *Rz, Rz +-= Ry 100x read from memory and subtract (x=0) or add (x=1) to memory pointer [condition] *Rz = Rx, Rz +-= Ry 101x write from memory and subtract (x=0) or add (x=1) to memory pointer

e.g. push onto a stack if the previous result was non-zero

ne0 && *E++ = A

Note that whilst the READ may be considered to do a POP instruction, the write is not the inverse of this.   The memory access and ALU run concurrently, to have an inverse would necessitate the ALU to run first and the resulting address used for memory access.

In the first form, Rz = Rx op Ry

 Rz = Rx & Ry 000 AND Rz = Rx | Ry 001 OR Rz = Rx ^ Ry 010 XOR exclusive or Rz = Rx >> 1 011 ASR arithmetic shift right Rz = Rx + Ry 100 ADD without carry Rz = Rx + Ry + c 101 ADD with carry Rz = Rx - Ry 110 SUB without carry Rz = Rx - Ry - c 111 SUB with carry

There is no NOT, just compute -1 (as 0 - 1) then XOR with that.

Here are some short cuts and implementation tricks:

Z = Rx op Ry sets the flags and discards the result
Rz = Rx is a synonym for Rz = Rx | Z, i.e. OR with zero does nothing
*Rz = Rx is STORE
Rz = *Rx++ is a synonym for *Rz = Rx, Rx += I i.e. POP with descending full stack
Rz = *P++ means load immediate.   P is incremented whether this instruction is run or not.
P = P + Ry means branch relative by Ry
P = *P means JUMP immediate

There are 8 conditions (total of three bits):

 nop 000 never execute 001 always execute eq0 010 last result == 0 ne0 011 last result != 0 lt0 100 last result < 0 le0 101 last result <= 0 ge0 110 last result >= 0 gt0 111 last result > 0

There is no test of the carry bit.  If you want to know what the carry bit is then ADD zero and zero (Z = Z + Z + c) then test.

The condition normally stops the whole instruction from executing.  However, if there is a add/sub on P then it happens regardless of the condition (as otherwise it wouldn't skip over the next instruction).  This leads to the classic C conundrum, P = *P++.   If this executes then it runs as P = *P, however if it doesn't execute then P++ does so that the next instruction is lined up as expected.

To call a subroutine is only two cycles (3 words):
• E = P + I
• P = *P, P += I   # JUMP immediate