Stackmaster-16 Instruction Set Architecture

To be able to design a CPU we first need an instruction set architecture. This is a first attempt at such an architecture. The idea is to implement part of this and then iterate based on the lessons learned.

The CPU in the FPRCade is called the Stackmaster-16. A name suggested by my friendly AI assistant Leo.

Stackmaster-16 is a 16 bit processor. It has a 16 bit data and address bus. Because the processor is going to be used to run Forth code it uses stacks instead of register sets to store data. The processor has four stacks, one for data, return addresses, control data, and temporary values. They are indicated by the letters: D, R, C, and T. It also has various instructions to manipulate the stack.

Instructions are 16 bit in size too. This to keep instruction decoding simple but at the expense of using a bit more memory. For each instruction the operation and operands are encoded in the 16 bits available. Bits 15 to 12 indicate the instruction category, the remaining bits are used to encode the function, stack id, signed/unsigned, and/or values. Stackmaster ISA V0.1 uses the following encoding

Bit
1111110000000000
5432109876543210
||||||||||||||||
0000xxxxxxxxxxxx unused
0001dddddddddddd BIF     branch if false
0010xxxxxxxxxxxx unused
0011xxxxxxxxxxxx unused
01dddddddddddddd ENTER
1000ffffxxxxxxxx
.   0000xxxxxxxx NOP
.   0001xxxxxxxx LEAVE
.   0010xxxxxxxx HALT
1001xxxxxxxxxxxx unused
1010xxxxxxxxxxxx unused
1011ffffssttxxxx Stack operations
.   0000         DROP Drop first cell on ss
.   0001         DUP  Duplicate first cell on ss
.   0010         SWAP Swap first two cells on ss
.   0011         MOV  Move from ss to tt
1100ssdddddddddd LDL  Load immediate low 10 bits to ss
1101ssddddddxxxx LDH  Load immediate high 6 bits to ss
1110fffffxxpxxxx Operates on data stack (2 values)
.   00000xx0xxxx ADDU Unsigned 16 bit addition
.   00000xx1xxxx ADD  Signed 16 bit addition
.   00001xx0xxxx MULU Unsigned 16 bit multiplication
.   00001xx1xxxx MUL  Signed 16 bit multiplication
.   00010xx0xxxx
.   00010xx1xxxx
.   00011xxxxxxx EQ   Equal
.   00100xx0xxxx ASRU Unsigned shift right
.   00100xx1xxxx ASR  Signed shift right, extends sign
.   00101xx0xxxx LTU  Unsigned less than
.   00101xx1xxxx LT   Signed less than
.   00110xx0xxxx GTU  Unsigned greater than
.   00110xx1xxxx GT   Signed greater than
.   00111xx0xxxx LTEU Unsigned less than or equal
.   00111xx1xxxx LTE  Signed less than or equal
.   01000xx0xxxx GTEU Unsigned greater than or equal
.   01000xx1xxxx GTE  Signed greater than or equal
.   01001xxxxxxx LSL  Shift left
.   01010xxxxxxx LSR  shift right
.   01011xxxxzzz STO  Store one/two/four bytes
.   01100xxxxxxx
.   01101xxxxxxx AND  16 bit and
.   01110xxxxxxx OR   16 bit or
.   01111xxxxxxx XOR  16 bit exclusive or
1111ffffxxxxxxxx Operates on data stack (1 values)
.   0000xxxxxxxx NEG
.   0001xxxxxxxx NOT
.   0010xxxxxzzz RD   Store one/two/four bytes

The meaning of the field names is as follows:

p   - 1/0  instruction is signed/unsigned
ddd - data

ss  - source stack id
tt  - target stack id
Where  00 - Data Stack, 01 - Return Stack, 10 - Control Stack, 11 - Temp Stack

fffff - function

xxx  - don't care

zzz  - operand size, where
000 illegal
001 1 byte
010 2 bytes
011 illegal
100 4 bytes

For instance the instruction

MOV D T

It encoded as

1011 0011 0011 0000

That is 1011 indicates it is in the category of stack operations. 0011 indicates the operation is MOV. 00 indicates the source stack is the data stack, 11 indicates the destination stack is the temp stack. The remaining 0000 is unused and ignored.

Assembly

The following is a short program in Stackmaster-16 assembly. It counts from zero up to ten and then halts.

; Test
.code
    nop
    ldl d 0x0000
label1:
    ldl d 0x0001
    add d
    dup d
    ldl d 0x000A
    gt
    bif label1
    halt
end:

To assemble this I have written an assembler called fa, that implements just enough instructions to assemble this program. If we store the above program in a file called test.asm and run

fa test.asm

a file named a.hex with the following content is produced

0000 8000 ; NOP
0002 c000 ; LDL D 0X0000
0004 c001 ; LDL D 0X0001
0006 e010 ; ADD D
0008 b100 ; DUP D
000a c00a ; LDL D 0X000A
000c e310 ; GT
000e 1ff6 ; BIF LABEL1  (0004)
0010 8200 ; HALT

Each line in this hex format list a memory address and the value that should be stored at that address. Anything after that is ignored and can be used for comments. In this case the assembler adds a copy the line that was assembled.

Next: an emulator