aboutsummaryrefslogtreecommitdiffstats
path: root/atk16_fpga/isa_idea.md
diff options
context:
space:
mode:
authorJan Tuomi <jan@jantuomi.fi>2025-03-18 18:38:44 +0200
committerJan Tuomi <jan@jantuomi.fi>2025-03-18 18:38:44 +0200
commit69de37cdb25563f6cbd2a3c1a338b1e0dd47b3a4 (patch)
treec1895044fd0051f919a989460be3ac39a6ab09b8 /atk16_fpga/isa_idea.md
parent06e8b8dbadf769507abf5368caee253ded139adc (diff)
Start reworking fpga impl
Diffstat (limited to 'atk16_fpga/isa_idea.md')
-rw-r--r--atk16_fpga/isa_idea.md193
1 files changed, 0 insertions, 193 deletions
diff --git a/atk16_fpga/isa_idea.md b/atk16_fpga/isa_idea.md
deleted file mode 100644
index ef87189..0000000
--- a/atk16_fpga/isa_idea.md
+++ /dev/null
@@ -1,193 +0,0 @@
-## Registers
-
-There are 16 general-purpose registers, `R0` to `R15`.
-
-`R13` is the flag/condition register.
-`R14` is the program counter.
-`R15` is the stack pointer.
-
-Additionally, `R12` mey be clobbered by the assembler when expanding macros.
-
-## Instructions
-
-XXXX denotes ignored bits.
-
-**HLT** is a halt operation. It stops the processor.
-
-```python
-HLT
-0000 XXXX XXXX XXXX
-```
-
-**ALU** is a 16-bit ALU operation.
-
-- SSS selects the operation to perform
-- LLLL is the left operand and destination register.
-- In register mode (M=0), RRRR is the right operand register.
-- In immediate mode (M=1), the next word is interpreted as a 16-bit immediate value.
-
-```python
-ALU
-# register
-0001 SSSM LLLL RRRR
-# immediate
-0001 SSSM LLLL XXXX
-IIII IIII IIII IIII
-```
-
-**LD** is a load operation.
-
-- LLLL is the destination register.
-- In register mode (M=0), RRRR is the register holding the address to load from.
-- In immediate mode (M=1), the next word is interpreted as a 16-bit address to load from.
-- In direct mode (D=0), the address is used as-is.
-- In indirect mode (D=1), the address is used as a pointer to another address. An indirect load can be thought of as a pointer dereference.
-- In pop mode (P = 1), the RRRR register is incremented before loading. This in conjunction with an indirect load can be used as a stack pop operation. POP is only valid in register mode.
-
-```python
-LD
-# register
-0010 DPXM LLLL RRRR
-# immediate
-0010 DPXM LLLL XXXX
-IIII IIII IIII IIII
-```
-
-**MOV** is a move operation. It copies the value from one register to another.
-
-- LLLL is the destination register.
-- RRRR is the source register.
-
-```python
-MOV
-0011 XXXX LLLL RRRR
-```
-
-**ST** is a store operation.
-
-- LLLL is the source register.
-- In register mode (M=0), RRRR is the register holding the address to store to.
-- In immediate mode (M=1), the next word is interpreted as a 16-bit address to store to.
-- In direct mode (D=0), the address is used as-is.
-- In indirect mode (D=1), the address is used as a pointer to another address. An indirect store can be thought of as a pointer assignment.
-- In push mode (P = 1), the RRRR register is decremented after storing. This in conjunction with an indirect store can be used as a stack push operation. PUSH is only valid in register mode.
-
-```python
-ST
-# register
-0100 DPXM LLLL RRRR
-# immediate
-0100 DPXM LLLL XXXX
-IIII IIII IIII IIII
-```
-
-**BR** is a branch operation.
-
-- FF selects the condition to branch on (carry, overflow, zero, sign).
-- S determines if the selected flag should be set (1) or not set (0).
-- The I octet is an 8-bit signed offset.
-
-```python
-BR
-0101 FFXS IIII IIII
-```
-
-## Calling convention
-
-Arguments are passed in registers R0..R10. The return value is stored in R0.
-The return address is stored on the stack to support nested calls.
-
-Registers `R0..R3` are caller-saved (called function can clobber these registers, calling code must save them on the stack or higher registers if needed).
-Registers `R4..R10` are callee-saved (called function must save these on the stack or lower registers).
-
-## Example assembly
-
-```java
-@at 0x0
- LD R0 0x1
- LD R1 0x2
- ADD R0 R1 ; ADD = macro that expands to ALU 000
-
- BR SIGN UNSET $br_true
-br_false:
- LD R0 0xEE
- HLT
-br_true:
- LD R0 0xFF
- HLT
-```
-
-## Example macro assembly
-
-```java
-@macro ADD lhs rhs
- ALU 0 $lhs $rhs
-@endmacro
-
-@let threshold 0x80
-@if R1 < $threshold ; expands into a SUB and a BR
- LD R0 0x1
- LD R1 0x2
- ADD R0 R1
- HLT
-@else
- ; something
-@endif
-
-@let PC R14
-@let SP R15
-
-@macro SPUSH reg
- ST INDIRECT PUSH $reg $SP
-@endmacro
-
-@macro SPOP reg
- LD INDIRECT POP $reg $SP
-@endmacro
-
-@macro CALL1 fn_lbl arg
-@let ret_addr $gen_uniq ; generate a unique label
- LD R0 $arg ; load argument to R0
- LD R1 $ret_addr ; load return address to R1
- SPUSH R1 ; push return address to stack
- LD $PC $fn_lbl ; jump to function address
-$ret_addr:
- HLT
-@endmacro
-
-@at 0x0
-main:
- CALL1 :fn 0x1
- HLT
-
-; example of an absolute jump
- LD $SP
- $abs_jump_addr
-
-; example of a relative jump
- ADD $PC
- $rel_jump_offset
-
-; idea: syntax for passing the immediate on the same line
- ADD $PC % $rel_jump_offset
-
-; probably should just require the core instructions to be defined "correctly" and have convenience macros for the rest, such as
-
-@macro LOAD reg from
-@c_if immediate $from
- LD $reg
- $from
-$c_else
- LD $reg $from
-$c_endif
-@endmacro
-```
-
-### Assembler concepts
-
-- `R0` to `R15` are register literals.
-- Rows with no indentation are either directives (`@` prefix) or labels (`:` suffix).
-- Rows with indentation are instructions.
-- Comments are prefixed with `;`.
-- Labels can be literals (`my_label:`) or variables (`$my_label_var:`).
-- Compile time variables are defined with `@let` and used with `$`.