This is an old revision of the document!
Table of Contents
The instructions are 16 bit words. Most instructions use a single word, however, some of them use a second word to store an immediate 16-bit value.
The general format is as follows:
| Bits | 15-12 | 11-9 | 8-6 | 5-3 | 2-0 | 
|---|---|---|---|---|---|
| Contents | Opcode0 | Operand A | Opcode1 | OPN | Operand B | 
| Contents | Opcode0 | Operand A | Opcode1 | 6-bit Immediate | |
Special instructions
“Special” instructions are identified by Opcode0 = 0xF
Multiplication
| Instruction | Opcode0 | Operand A | Opcode1 | OPN | Operand B | 
|---|---|---|---|---|---|
| MUL (unsigned) | F | Op.A | 0 | 1 | Op.B | 
| MUL (signed) | F | Op.A | 4 | 1 | Op.B | 
- document possible values for OPN
- document MAC instructions
- document unsigned-to-unsigned vs signed-to-unsigned instructions
- division instructions may have a similar format
Note: Operand A and Operand B cannot be 0, 6 or 7 (it is not possible to multiply SP, SR or PC with something).
CALL and GOTO
| Instruction | Opcode0 | Operand A | Opcode1 | 6-bit Immediate | Second word | |
|---|---|---|---|---|---|---|
| CALL | F | ? | 1 | CS: value | PC value | |
| GOTO | F | 7 | 2 | CS: value | PC value | 
The target address is formed by the immediate6 value (for CS:) and another word after the instruction (for PC)
Interrupts
| Instruction | Opcode0 | Operand A | Opcode1 | 6-bit Immediate | 
|---|---|---|---|---|
| INT OFF | F | ? | 5 | 00 | 
| INT IRQ | F | ? | 5 | 01 | 
| INT FIQ | F | ? | 5 | 02 | 
| INT IRQ,FIQ | F | ? | 5 | 03 | 
| FIR_MOV ON | F | ? | 5 | 04 | 
| FIR_MOV OFF | F | ? | 5 | 05 | 
| IRQ OFF | F | ? | 5 | 08 | 
| IRQ ON | F | ? | 5 | 09 | 
| FIQ OFF | F | ? | 5 | 0C | 
| FIQ ON | F | ? | 5 | 0E | 
| BREAK | F | ? | 5 | 20 | 
 probably other instructions (FRACTION, …) fit in here
Jump instructions
Jump instructions are identified by Operand A = 7 (makes sense, because they change the PC which is register 7)
| Instruction | Opcode0 | Operand A | Opcode1 | 6-bit Immediate | 
|---|---|---|---|---|
| JCC, JB, JNAE | 0 | 7 | Direction | Jump offset | 
| JCS, JNB, JAE | 1 | 7 | Direction | Jump offset | 
| JSC, JGE, JNL | 2 | 7 | Direction | Jump offset | 
| JSS, JNGE, JL | 3 | 7 | Direction | Jump offset | 
| JNE, JNZ | 4 | 7 | Direction | Jump offset | 
| JE, JZ | 5 | 7 | Direction | Jump offset | 
| JPL | 6 | 7 | Direction | Jump offset | 
| JMI | 7 | 7 | Direction | Jump offset | 
| JBE, JNA | 8 | 7 | Direction | Jump offset | 
| JNBE, JA | 9 | 7 | Direction | Jump offset | 
| JLE, JNG | A | 7 | Direction | Jump offset | 
| JNLE, JG | B | 7 | Direction | Jump offset | 
| JVC | C | 7 | Direction | Jump offset | 
| JVS | D | 7 | Direction | Jump offset | 
| JMP | E | 7 | Direction | Jump offset | 
| F | 7 | Reserved for special instructions | ||
Opcode1 indicates the jump direction, and can be 0 (jump forward) or 1 (jump back)
ALU instructions
| Instruction | Opcode0 | Operand A | Opcode1 | OPN | Operand B | 
|---|---|---|---|---|---|
| ADD | 0 | Op. A | Addr Mode | Param | Op. B | 
| ADC | 1 | Op. A | Addr Mode | Param | Op. B | 
| SUB | 2 | Op. A | Addr Mode | Param | Op. B | 
| SBC | 3 | Op. A | Addr Mode | Param | Op. B | 
| CMP | 4 | Op. A | Addr Mode | Param | Op. B | 
| NEG | 6 | Op. A | Addr Mode | Param | Op. B | 
| XOR | 8 | Op. A | Addr Mode | Param | Op. B | 
| LD | 9 | Op. A | Addr Mode | Param | Op. B | 
| POP | 9 | First reg - 1 | 2 | Register count | Stack pointer reg | 
| RETF | 9 | 5 (SR) | 2 | 2 (SR, PC) | 0 (SP) | 
| RETI | 9 | 5 (SR) | 2 | 3 (SR, PC, FR) | 0 (SP) | 
| OR | A | Op. A | Addr Mode | Param | Op. B | 
| AND | B | Op. A | Addr Mode | Param | Op. B | 
| TEST | C | Op. A | Addr Mode | Param | Op. B | 
| ST | D | Op. A | Addr Mode | Param | Op. B | 
| PUSH | D | Last reg -1 | 2 | Register count | Stack pointer reg | 
| F | Reserved for special instructions | ||||
Depending on opcode1, various addressing modes can be used:
| Addressing mode | Opcode0 | Operand A | Opcode1 | OPN | Operand B | ||
|---|---|---|---|---|---|---|---|
| [BP+Imm6] | ALU op | Op. A | 0 | 6-bit immediate | Op. A ≠ PC | ||
| #Imm6 | ALU op | Op. A | 1 | 6-bit immediate | Op. A ≠ PC | ||
| Special (POP, PUSH) | 2 | ||||||
| [Rs] | ALU op | Op. A | 3 | 0 | Rs | ||
| [Rs--] | ALU op | Op. A | 3 | 1 | Rs | ||
| [Rs++] | ALU op | Op. A | 3 | 2 | Rs | ||
| [++Rs] | ALU op | Op. A | 3 | 3 | Rs | ||
| D:[Rs] | ALU op | Op. A | 3 | 4 | Rs | ||
| D:[Rs--] | ALU op | Op. A | 3 | 5 | Rs | ||
| D:[Rs++] | ALU op | Op. A | 3 | 6 | Rs | ||
| D:[++Rs] | ALU op | Op. A | 3 | 7 | Rs | ||
| Rs | ALU op | Op. A | 4 | 0 | Rs | ||
| #Imm16 | ALU op | Op. A | 4 | 1 | Rs | 16-bit immediate in next word | |
| From [Addr16] | ALU op | Op. A | 4 | 2 | Rs | 16-bit address in next word | |
| To [Addr16] | ALU op | Op. A | 4 | 3 | Rs | 16-bit address in next word | |
| Rs ASR shift | ALU op | Op. A | 4 | 4 + (shift - 1) | Rs | ||
| Rs LSL shift | ALU op | Op. A | 5 | shift - 1 | Rs | ||
| Rs LSR shift | ALU op | Op. A | 5 | 4 + (shift - 1) | Rs | ||
| Rs ROL shift | ALU op | Op. A | 6 | shift - 1 | Rs | ||
| Rs ROR shift | ALU op | Op. A | 6 | 4 + (shift - 1) | Rs | ||
| [Addr6] | ALU op | Op. A | 7 | 6-bit address | |||
The instructions using Imm16 or Addr16 are 3-operand instructions, for example:
R3 = R2 + Imm16
smasm syntax:
ADD R3, R2, #Imm16
All other forms are 2-operand: operand A is always a register and used as both source and destination.
The LD operation uses operand A only as a target.
The ST operation uses the second source operand (Rs, address, …) as the target, and operand A (always a register) as the source.




