Skip to content
sevonj edited this page Apr 5, 2023 · 2 revisions

Instruction Set Architecture

Basics

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)

Full Syntax

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.

Second operand and addressing mode

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

R0 in second operand

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

Instruction binary layout

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.

Instructions Reference

Data in (parentheses) is subject to change.

Instruction List

Data transfer

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

Arithmetic and logic

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

Branching

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

Subroutines

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.

Stack

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.

System

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.

Misc

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

Opcode Matrix

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.