-
Notifications
You must be signed in to change notification settings - Fork 0
ISA
An instruction contains three parts:
Command
, 1st operand
, and 2nd operand
Example instruction that adds 2 to Register 1: ADD R1, =2
Example instruction that adds value of R2 to R1: ADD R1, R2
Example instruction that does both: ADD R1, =2(R2)
OPER Rj, MADDR(Ri)
, where
-
OPER
is the command -
Rj
is the 1st operand. It can only be a register R0..=R7 -
M
is the addressing mode. Value can be 0..=2 -
ADDR
is the address. -
Ri
is the second register.
The second operand consists of M
ADDR
Ri
.
-
Mode 0 - Immediate operand:
ADDR+Ri
is the value of second operand, used as is. -
Mode 1 - Direct addressing:
ADDR+Ri
points to the value in memory. It tells the address to fetch the value from. -
Mode 2 - Indirect addressing:
ADDR+Ri
points to a pointer (we do the fetch twice).
The mode design in TTK-91 is simple: the value corresponds to the number of memory fetches it takes to get 2nd operand.
By default, mode is 1. Adding a mode sign "=", or "@" will let you change that.
-
ADD R2, =2
Mode 0: Immediate -
ADD R2, 2
Mode 1: Direct -
ADD R2, @2
Mode 2: Indirect
Note that if you don't specify an address, the mode is decremented by 1:
-
ADD R2, =R1
Mode -1: Illegal, this will not compile -
ADD R2, R1
Mode 0: Immediate -
ADD R2, @R1
Mode 1: Direct
Some instructions operate on addresses. For them, default is 0:
-
STORE R2, =2
Mode -1: You can't store a value into a value! -
STORE R2, 2
Mode 0: Store value to an address. -
STORE R2, @2
Mode 1 -
STORE R2, =R1
Mode -2: Super illegal. -
STORE R2, R1
Mode -1: Still illegal. -
STORE R2, @R1
Mode 0: R1 contains the address
Other examples:
-
ADD R2, R1
Mode 0 -
ADD R2, (R1)
Mode 1 (parentheses imply it's a memory address) -
ADD R2, 0(R1)
Mode 1 -
ADD R2, 0
Mode 1
Ri is 3 bits long, which means that there are exactly 8 possible combinations, one for each of the 8 registers. But what if you don't want to specify a register? There's no room for such option! Therefore 0 is reserved for "no register", and not R0. The following instructions have the same effect regardless of what value R0 holds:
ADD R2, =7(R0)
ADD R2, =7
The 32 bits of an instruction is structured the following way:
Opcode | Rj | Mode | Ri | Address |
---|---|---|---|---|
8 bits | 3 bits | 2 bits | 3 bits | 16 bits |
Notice that unlike many other architectures, addressing mode and registers are not baked into the opcode.
Data in (parentheses) is subject to change.
Oper | Value | P | M | Description | Note |
---|---|---|---|---|---|
STORE | 0x01 | 0 | Memory IO: Write | ||
LOAD | 0x02 | 1 | Memory IO: Read | ||
IN | 0x03 | 1 | Port IO: Read | ||
OUT | 0x04 | 1 | Port IO: Write |
Oper | Value | P | M | Description | Note |
---|---|---|---|---|---|
ADD | 0x11 | 1 | |||
SUB | 0x12 | 1 | |||
MUL | 0x13 | 1 | |||
DIV | 0x14 | 1 | |||
MOD | 0x15 | 1 | |||
AND | 0x16 | 1 | |||
OR | 0x17 | 1 | |||
XOR | 0x18 | 1 | |||
SHL | 0x19 | 1 | |||
SHR | 0x1A | 1 | |||
NOT | 0x1B | 1 | 2nd operand is not used at all. | ||
SHRA | 0x1C | 1 | SHR but keep sign bit. | ||
COMP | 0x1F | 1 |
Oper | Value | P | M | Description | Note |
---|---|---|---|---|---|
JUMP | 0x20 | 0 | Jump to address | Rj is not used | |
JNEG | 0x21 | 0 | Jump if Rj is negative | ||
JZER | 0x22 | 0 | Jump if Rj is zero | ||
JPOS | 0x23 | 0 | Jump if Rj is positive | ||
JNNEG | 0x24 | 0 | Jump if Rj is not negative | ||
JNZER | 0x25 | 0 | Jump if Rj is not zero | ||
JNPOS | 0x26 | 0 | Jump if Rj is not positive | ||
JLES | 0x27 | 0 | Jump if comparison result L | Rj is not used | |
JEQU | 0x28 | 0 | Jump if comparison result E | Rj is not used | |
JGRE | 0x29 | 0 | Jump if comparison result G | Rj is not used | |
JNLES | 0x2A | 0 | Jump if comparison did not result L | Rj is not used | |
JNEQU | 0x2B | 0 | Jump if comparison did not result E | Rj is not used | |
JNGRE | 0x2C | 0 | Jump if comparison did not result G | Rj is not used |
Oper | Value | P | M | Description | Note |
---|---|---|---|---|---|
CALL | 0x31 | 0 | Subroutine call | ||
EXIT | 0x32 | 1 | Subroutine return | ||
IEXIT | (0x39) | * | 1 | Interrupt return | Only to be used by interrupt handlers. |
Oper | Value | P | M | Description | Note |
---|---|---|---|---|---|
PUSH | 0x33 | 1 | Push register to stack. | Rj is incremented before writing. Intended for SP, but any register works. | |
POP | 0x34 | 1 | Pop from stack to register. | Rj is decremented after reading. Intended for SP, but any register works. 2nd operand should not contain ADDR . |
|
PUSHR | 0x35 | 1 | Push registers R0..=R6 to stack. | 2nd operand is not used. | |
POPR | 0x36 | 1 | Pop registers R0..=R6 from stack. | 2nd operand is not used. |
Oper | Value | P | M | Description | Note |
---|---|---|---|---|---|
SVC | 0x70 | 1 | Supervisor call | ||
HLT | (0x71) | * | 1 | Halt. An interrupt will wake up the CPU. | |
HCF | (0x72) | * | 1 | Halt & Catch Fire. Emulation will stop. Use this to fully end your program. |
Oper | Value | P | M | Description | Note |
---|---|---|---|---|---|
NOP | 0x00 | 1 | No operation. Do nothing. | Neither operand or mode are used. |
P: Privileged instruction
M: Default Mode
Table of all commands (in TTK-91, mode is not part of opcode):
2nd byte🠖 1st byte🠗 |
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | NOP | STORE | LOAD | IN | OUT | |||||||||||
1 | ADD | SUB | MUL | DIV | MOD | AND | OR | XOR | SHL | SHR | NOT | SHRA | COMP | |||
2 | JUMP | JNEG | JZER | JPOS | JNNEG | JNZER | JNPOS | JLES | JEQU | JGRE | JNLES | JNEQU | JNGRE | |||
3 | CALL | EXIT | PUSH | POP | PUSHR | POPR | (IEXIT) | |||||||||
4* | ||||||||||||||||
5 | ||||||||||||||||
6 | ||||||||||||||||
7 | SVC | (HLT) | (HCF) | |||||||||||||
8 | ||||||||||||||||
9 | ||||||||||||||||
A | ||||||||||||||||
B | ||||||||||||||||
C | ||||||||||||||||
D | ||||||||||||||||
E | ||||||||||||||||
F |
*Reserved for floating point extension.