aboutsummaryrefslogtreecommitdiffstats
path: root/resources/asm
diff options
context:
space:
mode:
Diffstat (limited to 'resources/asm')
-rw-r--r--resources/asm/aoc23_1a.atk16554
-rw-r--r--resources/asm/aoc23_1a.py48
-rw-r--r--resources/asm/ast_compiler_bootstrap.atk1674
-rw-r--r--resources/asm/bootstrap.atk1671
-rw-r--r--resources/asm/ext_std.py157
-rw-r--r--resources/asm/ext_string_io.py56
-rw-r--r--resources/asm/fibo.atk1657
-rw-r--r--resources/asm/idle_loop.atk1610
-rw-r--r--resources/asm/sum.atk1632
-rw-r--r--resources/asm/test_py_src.atk16301
-rw-r--r--resources/asm/text_mode.atk1658
11 files changed, 1418 insertions, 0 deletions
diff --git a/resources/asm/aoc23_1a.atk16 b/resources/asm/aoc23_1a.atk16
new file mode 100644
index 0000000..78c4622
--- /dev/null
+++ b/resources/asm/aoc23_1a.atk16
@@ -0,0 +1,554 @@
+;; BEGIN BOOTSTRAP
+
+@use ext_std:*
+
+@let sp RH ; stack pointer (points to empty slot at top of stack)
+@let fp RG ; frame pointer (points to base of currently active frame)
+
+@let vector_table 0x10
+@let vt_ISR0 0x10 ; ISR0
+@let vt_ISR1 0x11 ; ISR1
+@let vt_ISR2 0x12 ; ISR2
+@let vt_ISR3 0x13 ; ISR3
+@let vt_stack_addr 0x14 ; Stack address
+@let vt_term_pp_addr 0x15 ; Terminal peripheral address
+@let vt_kb_pp_addr 0x16 ; Keyboard peripheral address
+@let vt_gr_mode_addr 0x17 ; Graphics mode setting address
+@let vt_sprite_mem 0x18 ; Sprite memory address
+@let vt_text_mem 0x19 ; Text memory buffer address
+
+@let stack_segment 0x8000
+@let mmio_segment 0xE000
+@let terminal_addr 0xE000
+@let keyboard_addr 0xE001
+@let gr_mode_addr 0xE002
+@let sprite_mem 0xE800
+@let text_mem 0xF800
+
+@let gr_disabled_mode 0b00
+@let gr_text_mode 0b01
+@let gr_sprite_mode 0b10
+
+@address 0x0
+ ldi vt_stack_addr RA
+ ldr RA SP
+ mov SP FP
+ jpi program_segment
+
+@address vector_table
+ keyboard_isr ; 0x10
+ hlt_isr ; 0x11
+ hlt_isr ; 0x12
+ hlt_isr ; 0x13
+ stack_segment ; 0x14
+ terminal_addr ; 0x15
+ keyboard_addr ; 0x16
+ gr_mode_addr ; 0x17
+ sprite_mem ; 0x18
+ text_mem ; 0x19
+
+@label hlt_isr
+ hlt
+
+@label keyboard_isr
+ spu RA
+ spu RB
+ ldi vt_kb_pp_addr RA
+ ldr RA RA
+ ldr RA RA
+ ldi vt_term_pp_addr RB
+ ldr RB RB
+ str RA RB
+ spo RB
+ spo RA
+ rti
+
+@label program_segment
+ ldi vt_gr_mode_addr RA
+ ldr RA RA
+ ldi gr_disabled_mode RB
+ str RB RA
+
+ jpi main
+
+;; END BOOTSTRAP
+
+@label int_0
+ 8
+@label graphics_no_mode
+ 0
+@label graphics_text_mode
+ 1
+@label graphics_sprite_mode
+ 2
+@label graphics_mode_pp
+ 23
+@label text_mem_pp
+ 25
+@label input_p
+ 36864
+@label input_elem_size
+ 256
+@label int_1
+ 49
+@label int_2
+ 97
+@label int_3
+ 98
+@label int_4
+ 99
+@label int_5
+ 50
+
+
+
+@label main
+; stack frame with offsets
+; graphics_mode_p 0
+; text_mem_p 1
+; row_p 2
+; i 3
+; first 4
+; last 5
+; char_p 6
+; char 7
+ ldi int_0 RA
+ ldr RA RA
+ add SP RA SP
+; <ast.Assign object at 0x104353640>
+; assigning graphics_mode_p at FP + 0
+; evaluating value to be assigned
+; <ast.Call object at 0x1043535e0>
+; Builtin call load [<ast.Name object at 0x104353550>]
+; <ast.Name object at 0x104353550> (GRAPHICS_MODE_PP)
+ ldi graphics_mode_pp RC
+ ldr RC RC
+ spu RC
+; (load) dereferencing top of stack
+ spo RC
+ ldr RC RC
+ spu RC
+; assigning stack address (FP + 0) := top of stack
+ spo RA
+ ldi 0 RB
+ add RB FP RB
+ str RA RB
+; <ast.Assign object at 0x104353520>
+; assigning text_mem_p at FP + 1
+; evaluating value to be assigned
+; <ast.Call object at 0x1043534c0>
+; Builtin call load [<ast.Name object at 0x104353430>]
+; <ast.Name object at 0x104353430> (TEXT_MEM_PP)
+ ldi text_mem_pp RC
+ ldr RC RC
+ spu RC
+; (load) dereferencing top of stack
+ spo RC
+ ldr RC RC
+ spu RC
+; assigning stack address (FP + 1) := top of stack
+ spo RA
+ ldi 1 RB
+ add RB FP RB
+ str RA RB
+; <ast.Call object at 0x1043533d0>
+; Builtin call store [<ast.Name object at 0x104353340>, <ast.Name object at 0x104353310>]
+; <ast.Name object at 0x104353340> (graphics_mode_p)
+ ldi 0 RA
+ add FP RA RA
+ ldr RA RA
+ spu RA
+; <ast.Name object at 0x104353310> (GRAPHICS_TEXT_MODE)
+ ldi graphics_text_mode RA
+ ldr RA RA
+ spu RA
+ spo RB
+ spo RA
+ str RB RA
+ ldi 0 RA
+ spu RA
+; popping free-standing Expr result from stack
+ spo RA
+; <ast.Call object at 0x1043530d0>
+; Builtin call store [<ast.BinOp object at 0x104352a40>, <ast.Constant object at 0x104352d40>]
+; <ast.Add object at 0x10430ef80>
+; BinOp lhs <ast.BinOp object at 0x104352a40>
+; <ast.Name object at 0x104352da0> (INPUT_P)
+ ldi input_p RA
+ ldr RA RA
+ spu RA
+; BinOp rhs <ast.BinOp object at 0x104352a40>
+; <ast.Constant object at 0x104352d70>
+ ldi 0 RA
+ spu RA
+ spo RB
+ spo RA
+ add RA RB RA
+ spu RA
+; <ast.Constant object at 0x104352d40>
+ ldi int_1 RA
+ ldr RA RA ; int_1 = 49
+ spu RA
+ spo RB
+ spo RA
+ str RB RA
+ ldi 0 RA
+ spu RA
+; popping free-standing Expr result from stack
+ spo RA
+; <ast.Call object at 0x104352cb0>
+; Builtin call store [<ast.BinOp object at 0x104352e60>, <ast.Constant object at 0x104352dd0>]
+; <ast.Add object at 0x10430ef80>
+; BinOp lhs <ast.BinOp object at 0x104352e60>
+; <ast.Name object at 0x104352e30> (INPUT_P)
+ ldi input_p RA
+ ldr RA RA
+ spu RA
+; BinOp rhs <ast.BinOp object at 0x104352e60>
+; <ast.Constant object at 0x104352e00>
+ ldi 1 RA
+ spu RA
+ spo RB
+ spo RA
+ add RA RB RA
+ spu RA
+; <ast.Constant object at 0x104352dd0>
+ ldi int_2 RA
+ ldr RA RA ; int_2 = 97
+ spu RA
+ spo RB
+ spo RA
+ str RB RA
+ ldi 0 RA
+ spu RA
+; popping free-standing Expr result from stack
+ spo RA
+; <ast.Call object at 0x104352770>
+; Builtin call store [<ast.BinOp object at 0x1043526b0>, <ast.Constant object at 0x104352620>]
+; <ast.Add object at 0x10430ef80>
+; BinOp lhs <ast.BinOp object at 0x1043526b0>
+; <ast.Name object at 0x104352950> (INPUT_P)
+ ldi input_p RA
+ ldr RA RA
+ spu RA
+; BinOp rhs <ast.BinOp object at 0x1043526b0>
+; <ast.Constant object at 0x104352980>
+ ldi 2 RA
+ spu RA
+ spo RB
+ spo RA
+ add RA RB RA
+ spu RA
+; <ast.Constant object at 0x104352620>
+ ldi int_3 RA
+ ldr RA RA ; int_3 = 98
+ spu RA
+ spo RB
+ spo RA
+ str RB RA
+ ldi 0 RA
+ spu RA
+; popping free-standing Expr result from stack
+ spo RA
+; <ast.Call object at 0x1043525c0>
+; Builtin call store [<ast.BinOp object at 0x104352530>, <ast.Constant object at 0x1043524a0>]
+; <ast.Add object at 0x10430ef80>
+; BinOp lhs <ast.BinOp object at 0x104352530>
+; <ast.Name object at 0x104352500> (INPUT_P)
+ ldi input_p RA
+ ldr RA RA
+ spu RA
+; BinOp rhs <ast.BinOp object at 0x104352530>
+; <ast.Constant object at 0x1043524d0>
+ ldi 3 RA
+ spu RA
+ spo RB
+ spo RA
+ add RA RB RA
+ spu RA
+; <ast.Constant object at 0x1043524a0>
+ ldi int_4 RA
+ ldr RA RA ; int_4 = 99
+ spu RA
+ spo RB
+ spo RA
+ str RB RA
+ ldi 0 RA
+ spu RA
+; popping free-standing Expr result from stack
+ spo RA
+; <ast.Call object at 0x104352440>
+; Builtin call store [<ast.BinOp object at 0x1043523b0>, <ast.Constant object at 0x1043522f0>]
+; <ast.Add object at 0x10430ef80>
+; BinOp lhs <ast.BinOp object at 0x1043523b0>
+; <ast.Name object at 0x104352380> (INPUT_P)
+ ldi input_p RA
+ ldr RA RA
+ spu RA
+; BinOp rhs <ast.BinOp object at 0x1043523b0>
+; <ast.Constant object at 0x104352350>
+ ldi 4 RA
+ spu RA
+ spo RB
+ spo RA
+ add RA RB RA
+ spu RA
+; <ast.Constant object at 0x1043522f0>
+ ldi int_5 RA
+ ldr RA RA ; int_5 = 50
+ spu RA
+ spo RB
+ spo RA
+ str RB RA
+ ldi 0 RA
+ spu RA
+; popping free-standing Expr result from stack
+ spo RA
+; <ast.Call object at 0x1043521d0>
+; Builtin call store [<ast.BinOp object at 0x104352110>, <ast.Constant object at 0x104353040>]
+; <ast.Add object at 0x10430ef80>
+; BinOp lhs <ast.BinOp object at 0x104352110>
+; <ast.Name object at 0x1043520e0> (INPUT_P)
+ ldi input_p RA
+ ldr RA RA
+ spu RA
+; BinOp rhs <ast.BinOp object at 0x104352110>
+; <ast.Constant object at 0x104352ec0>
+ ldi 5 RA
+ spu RA
+ spo RB
+ spo RA
+ add RA RB RA
+ spu RA
+; <ast.Constant object at 0x104353040>
+ ldi 0 RA
+ spu RA
+ spo RB
+ spo RA
+ str RB RA
+ ldi 0 RA
+ spu RA
+; popping free-standing Expr result from stack
+ spo RA
+; <ast.Assign object at 0x104353010>
+; assigning row_p at FP + 2
+; evaluating value to be assigned
+; <ast.Name object at 0x104352fb0> (INPUT_P)
+ ldi input_p RC
+ ldr RC RC
+ spu RC
+; assigning stack address (FP + 2) := top of stack
+ spo RA
+ ldi 2 RB
+ add RB FP RB
+ str RA RB
+; <ast.Assign object at 0x104352f80>
+; assigning i at FP + 3
+; evaluating value to be assigned
+; <ast.Constant object at 0x104352f20>
+ ldi 0 RC
+ spu RC
+; assigning stack address (FP + 3) := top of stack
+ spo RA
+ ldi 3 RB
+ add RB FP RB
+ str RA RB
+; <ast.Assign object at 0x104352ef0>
+; assigning first at FP + 4
+; evaluating value to be assigned
+; <ast.Call object at 0x104352830>
+; Builtin call load [<ast.Name object at 0x104352650>]
+; <ast.Name object at 0x104352650> (row_p)
+ ldi 2 RC
+ add FP RC RC
+ ldr RC RC
+ spu RC
+; (load) dereferencing top of stack
+ spo RC
+ ldr RC RC
+ spu RC
+; assigning stack address (FP + 4) := top of stack
+ spo RA
+ ldi 4 RB
+ add RB FP RB
+ str RA RB
+; <ast.Assign object at 0x104352680>
+; assigning last at FP + 5
+; evaluating value to be assigned
+; <ast.Constant object at 0x104352b60>
+ ldi 0 RC
+ spu RC
+; assigning stack address (FP + 5) := top of stack
+ spo RA
+ ldi 5 RB
+ add RB FP RB
+ str RA RB
+; <ast.While object at 0x104352920>
+@label while_test_6
+; <ast.Constant object at 0x1043526e0>
+ ldi 1 RB
+ spu RB
+ spo RA
+ addi RA 0 RA
+ bri zero While_else_7
+; <ast.Assign object at 0x1042d85b0>
+; assigning char_p at FP + 6
+; evaluating value to be assigned
+; <ast.Add object at 0x10430ef80>
+; BinOp lhs <ast.BinOp object at 0x1042d8670>
+; <ast.Name object at 0x1042da800> (INPUT_P)
+ ldi input_p RC
+ ldr RC RC
+ spu RC
+; BinOp rhs <ast.BinOp object at 0x1042d8670>
+; <ast.Name object at 0x1042d9570> (i)
+ ldi 3 RC
+ add FP RC RC
+ ldr RC RC
+ spu RC
+ spo RD
+ spo RC
+ add RC RD RC
+ spu RC
+; assigning stack address (FP + 6) := top of stack
+ spo RA
+ ldi 6 RB
+ add RB FP RB
+ str RA RB
+; <ast.Assign object at 0x1042da4a0>
+; assigning char at FP + 7
+; evaluating value to be assigned
+; <ast.Call object at 0x1045e1840>
+; Builtin call load [<ast.Name object at 0x1045e17b0>]
+; <ast.Name object at 0x1045e17b0> (char_p)
+ ldi 6 RC
+ add FP RC RC
+ ldr RC RC
+ spu RC
+; (load) dereferencing top of stack
+ spo RC
+ ldr RC RC
+ spu RC
+; assigning stack address (FP + 7) := top of stack
+ spo RA
+ ldi 7 RB
+ add RB FP RB
+ str RA RB
+; <ast.If object at 0x1045e1780>
+; <ast.Compare object at 0x1045e1750>
+; <ast.Name object at 0x1045e1720> (char)
+ ldi 7 RA
+ add FP RA RA
+ ldr RA RA
+ spu RA
+; <ast.Constant object at 0x1045e16f0>
+ ldi 0 RA
+ spu RA
+; Comparing <ast.Name object at 0x1045e1720> <ast.Eq object at 0x10430e890> <ast.Constant object at 0x1045e16f0>
+ spo RA
+ addi RA 0 RA
+ bri zero If_false_branch_11
+; <ast.Break object at 0x1045e16c0>
+ jpi While_end_8
+ jpi If_end_branch_12
+@label if_false_branch_11
+@label if_end_branch_12
+; <ast.Assign object at 0x1045e1690>
+; assigning last at FP + 5
+; evaluating value to be assigned
+; <ast.Name object at 0x1045e1630> (char)
+ ldi 7 RC
+ add FP RC RC
+ ldr RC RC
+ spu RC
+; assigning stack address (FP + 5) := top of stack
+ spo RA
+ ldi 5 RB
+ add RB FP RB
+ str RA RB
+; <ast.Assign object at 0x104352260>
+; assigning i at FP + 3
+; evaluating value to be assigned
+; <ast.Add object at 0x10430ef80>
+; BinOp lhs <ast.BinOp object at 0x104352230>
+; <ast.Name object at 0x1045e15d0> (i)
+ ldi 3 RC
+ add FP RC RC
+ ldr RC RC
+ spu RC
+; BinOp rhs <ast.BinOp object at 0x104352230>
+; <ast.Constant object at 0x1045e15a0>
+ ldi 1 RC
+ spu RC
+ spo RD
+ spo RC
+ add RC RD RC
+ spu RC
+; assigning stack address (FP + 3) := top of stack
+ spo RA
+ ldi 3 RB
+ add RB FP RB
+ str RA RB
+ jpi While_test_6
+@label while_else_7
+@label while_end_8
+; <ast.Call object at 0x1045e1540>
+; Builtin call store [<ast.BinOp object at 0x1045e14b0>, <ast.Name object at 0x1045e1420>]
+; <ast.Add object at 0x10430ef80>
+; BinOp lhs <ast.BinOp object at 0x1045e14b0>
+; <ast.Name object at 0x1045e1480> (text_mem_p)
+ ldi 1 RA
+ add FP RA RA
+ ldr RA RA
+ spu RA
+; BinOp rhs <ast.BinOp object at 0x1045e14b0>
+; <ast.Constant object at 0x1045e1450>
+ ldi 0 RA
+ spu RA
+ spo RB
+ spo RA
+ add RA RB RA
+ spu RA
+; <ast.Name object at 0x1045e1420> (first)
+ ldi 4 RA
+ add FP RA RA
+ ldr RA RA
+ spu RA
+ spo RB
+ spo RA
+ str RB RA
+ ldi 0 RA
+ spu RA
+; popping free-standing Expr result from stack
+ spo RA
+; <ast.Call object at 0x1045e13c0>
+; Builtin call store [<ast.BinOp object at 0x1045e1330>, <ast.Name object at 0x1045e12a0>]
+; <ast.Add object at 0x10430ef80>
+; BinOp lhs <ast.BinOp object at 0x1045e1330>
+; <ast.Name object at 0x1045e1300> (text_mem_p)
+ ldi 1 RA
+ add FP RA RA
+ ldr RA RA
+ spu RA
+; BinOp rhs <ast.BinOp object at 0x1045e1330>
+; <ast.Constant object at 0x1045e12d0>
+ ldi 1 RA
+ spu RA
+ spo RB
+ spo RA
+ add RA RB RA
+ spu RA
+; <ast.Name object at 0x1045e12a0> (last)
+ ldi 5 RA
+ add FP RA RA
+ ldr RA RA
+ spu RA
+ spo RB
+ spo RA
+ str RB RA
+ ldi 0 RA
+ spu RA
+; popping free-standing Expr result from stack
+ spo RA
+ mov FP SP
+ hlt
diff --git a/resources/asm/aoc23_1a.py b/resources/asm/aoc23_1a.py
new file mode 100644
index 0000000..12e3953
--- /dev/null
+++ b/resources/asm/aoc23_1a.py
@@ -0,0 +1,48 @@
+import atk16
+
+GRAPHICS_NO_MODE: atk16.ConstWord16 = 0
+GRAPHICS_TEXT_MODE: atk16.ConstWord16 = 1
+GRAPHICS_SPRITE_MODE: atk16.ConstWord16 = 2
+
+GRAPHICS_MODE_PP: atk16.ConstWord16 = 0x17
+TEXT_MEM_PP: atk16.ConstWord16 = 0x19
+
+graphics_mode_p = atk16.load(GRAPHICS_MODE_PP)
+text_mem_p = atk16.load(TEXT_MEM_PP)
+
+atk16.store(graphics_mode_p, GRAPHICS_TEXT_MODE)
+
+INPUT_P: atk16.ConstWord16 = 0x9000
+INPUT_ELEM_SIZE: atk16.ConstWord16 = 256
+
+# 1a example
+
+atk16.store(INPUT_P + 0, "1")
+atk16.store(INPUT_P + 1, "a")
+atk16.store(INPUT_P + 2, "b")
+atk16.store(INPUT_P + 3, "c")
+atk16.store(INPUT_P + 4, "2")
+atk16.store(INPUT_P + 5, "\0")
+# atk16.store_const_vec(INPUT_P + 0, "1abc2\0")
+# atk16.store_const_vec(INPUT_P + 256, "pqr3stu8vwx\0")
+# atk16.store_const_vec(INPUT_P + 512, "a1b2c3d4e5f\0")
+# atk16.store_const_vec(INPUT_P + 768, "treb7uchet\0")
+
+row_p = INPUT_P
+i = 0
+
+first = atk16.load(row_p)
+last = 0
+
+while True:
+ char_p = INPUT_P + i
+ char = atk16.load(char_p)
+
+ if char == "\0":
+ break
+
+ last = char
+ i += 1
+
+atk16.store(text_mem_p + 0, first)
+atk16.store(text_mem_p + 1, last) \ No newline at end of file
diff --git a/resources/asm/ast_compiler_bootstrap.atk16 b/resources/asm/ast_compiler_bootstrap.atk16
new file mode 100644
index 0000000..2e112eb
--- /dev/null
+++ b/resources/asm/ast_compiler_bootstrap.atk16
@@ -0,0 +1,74 @@
+;; BEGIN BOOTSTRAP
+
+@use ext_std:*
+
+@let sp RH ; stack pointer (points to empty slot at top of stack)
+@let fp RG ; frame pointer (points to base of currently active frame)
+
+@let vector_table 0x10
+@let vt_ISR0 0x10 ; ISR0
+@let vt_ISR1 0x11 ; ISR1
+@let vt_ISR2 0x12 ; ISR2
+@let vt_ISR3 0x13 ; ISR3
+@let vt_stack_addr 0x14 ; Stack address
+@let vt_term_pp_addr 0x15 ; Terminal peripheral address
+@let vt_kb_pp_addr 0x16 ; Keyboard peripheral address
+@let vt_gr_mode_addr 0x17 ; Graphics mode setting address
+@let vt_sprite_mem 0x18 ; Sprite memory address
+@let vt_text_mem 0x19 ; Text memory buffer address
+
+@let stack_segment 0x8000
+@let mmio_segment 0xE000
+@let terminal_addr 0xE000
+@let keyboard_addr 0xE001
+@let gr_mode_addr 0xE002
+@let sprite_mem 0xE800
+@let text_mem 0xF800
+
+@let gr_disabled_mode 0b00
+@let gr_text_mode 0b01
+@let gr_sprite_mode 0b10
+
+@address 0x0
+ ldi vt_stack_addr RA
+ ldr RA SP
+ mov SP FP
+ jpi program_segment
+
+@address vector_table
+ keyboard_isr ; 0x10
+ hlt_isr ; 0x11
+ hlt_isr ; 0x12
+ hlt_isr ; 0x13
+ stack_segment ; 0x14
+ terminal_addr ; 0x15
+ keyboard_addr ; 0x16
+ gr_mode_addr ; 0x17
+ sprite_mem ; 0x18
+ text_mem ; 0x19
+
+@label hlt_isr
+ hlt
+
+@label keyboard_isr
+ spu RA
+ spu RB
+ ldi vt_kb_pp_addr RA
+ ldr RA RA
+ ldr RA RA
+ ldi vt_term_pp_addr RB
+ ldr RB RB
+ str RA RB
+ spo RB
+ spo RA
+ rti
+
+@label program_segment
+ ldi vt_gr_mode_addr RA
+ ldr RA RA
+ ldi gr_disabled_mode RB
+ str RB RA
+
+ jpi main
+
+;; END BOOTSTRAP \ No newline at end of file
diff --git a/resources/asm/bootstrap.atk16 b/resources/asm/bootstrap.atk16
new file mode 100644
index 0000000..4e5cd24
--- /dev/null
+++ b/resources/asm/bootstrap.atk16
@@ -0,0 +1,71 @@
+; vector table fields
+@let vector_table 0x10
+@let vt_ISR0 0x10 ; ISR0
+@let vt_ISR1 0x11 ; ISR1
+@let vt_ISR2 0x12 ; ISR2
+@let vt_ISR3 0x13 ; ISR3
+@let vt_stack_addr 0x14 ; Stack address
+@let vt_term_pp_addr 0x15 ; Terminal peripheral address
+@let vt_kb_pp_addr 0x16 ; Keyboard peripheral address
+@let vt_gr_mode_addr 0x17 ; Graphics mode setting address
+@let vt_sprite_mem 0x18 ; Sprite memory address
+@let vt_text_mem 0x19 ; Text memory buffer address
+
+; memory segments
+@let stack_segment 0x8000
+@let mmio_segment 0xE000
+@let terminal_addr 0xE000
+@let keyboard_addr 0xE001
+@let gr_mode_addr 0xE002
+@let sprite_mem 0xE800
+@let text_mem 0xF800 ; to 0xFFFF
+; note: sprite memory & text memory can use the same space
+; since they are never used at the same time
+
+; graphics mode settings
+@let gr_disabled_mode 0b00
+@let gr_text_mode 0b01
+@let gr_sprite_mode 0b10
+
+@address vector_table
+ keyboard_isr ; 0x10
+ hlt_isr ; 0x11
+ hlt_isr ; 0x12
+ hlt_isr ; 0x13
+ stack_segment ; 0x14
+ terminal_addr ; 0x15
+ keyboard_addr ; 0x16
+ gr_mode_addr ; 0x17
+ sprite_mem ; 0x18
+ text_mem ; 0x19
+
+@label hlt_isr
+ ldi 0x55 RE
+ hlt
+
+@label keyboard_isr
+ stack_stash RA RB
+ ldi vt_kb_pp_addr RA ; RA := Keyboard peripheral address pointer
+ ldr RA RA ; RA := Keyboard peripheral address deref
+ ldr RA RA ; RA := <16-bit keyboard character code> from MMIO register
+ ldi vt_term_pp_addr RB ; RB := Terminal peripheral address pointer
+ ldr RB RB ; RB := Terminal peripheral address deref
+ str RA RB ; terminal <- character code (ASCII?)
+ mov RA RE ; RE := character code (for debugging)
+ stack_restore RA RB
+ rti
+@label program_segment
+
+; define short prelude that sets up vital instructions
+; NOTE: must be shorter than the vector table offset
+@address 0x0
+; set up stack pointer to point to beginning of stack segment
+ ldi vt_stack_addr RA
+ ldr RA SP
+ jpi program_segment
+
+@address program_segment
+; set graphics mode to disabled
+ set_graphics_mode gr_disabled_mode
+; jump to main (user defined)
+ jpi main
diff --git a/resources/asm/ext_std.py b/resources/asm/ext_std.py
new file mode 100644
index 0000000..247e605
--- /dev/null
+++ b/resources/asm/ext_std.py
@@ -0,0 +1,157 @@
+from asm_ops import *
+
+def expand_add(left: str, right: str, target: str) -> ExpandResult:
+ return [["alr", "al_plus", left, right, target]]
+
+def expand_sub(left: str, right: str, target: str) -> ExpandResult:
+ return [["alr", "al_minus", left, right, target]]
+
+def expand_addi(left: str, imm: str, target: str) -> ExpandResult:
+ return [["ali", "al_plus", left, imm, target]]
+
+def expand_subi(left: str, imm: str, target: str) -> ExpandResult:
+ return [["ali", "al_minus", left, imm, target]]
+
+def expand_not(reg: str, target: str) -> ExpandResult:
+ return [["alr", "al_xor", reg, "0xFFFF", target]]
+
+def expand_noti(imm: str, target: str) -> ExpandResult:
+ return [["ali", "al_xor", imm, "0xFFFF", target]]
+
+def expand_and(left: str, right: str, target: str) -> ExpandResult:
+ return [["alr", "al_and", left, right, target]]
+
+def expand_andi(left: str, imm: str, target: str) -> ExpandResult:
+ return [["ali", "al_and", left, imm, target]]
+
+def expand_or(left: str, right: str, target: str) -> ExpandResult:
+ return [["alr", "al_or", left, right, target]]
+
+def expand_ori(left: str, imm: str, target: str) -> ExpandResult:
+ return [["ali", "al_or", left, imm, target]]
+
+def expand_xor(left: str, imm: str, target: str) -> ExpandResult:
+ return [["alr", "al_xor", left, imm, target]]
+
+def expand_xori(left: str, right: str, target: str) -> ExpandResult:
+ return [["ali", "al_xor", left, right, target]]
+
+def expand_sll(left: str, right: str, target: str) -> ExpandResult:
+ return [["alr", "al_sll", left, right, target]]
+
+def expand_slr(left: str, right: str, target: str) -> ExpandResult:
+ return [["alr", "al_slr", left, right, target]]
+
+def expand_sar(left: str, right: str, target: str) -> ExpandResult:
+ return [["alr", "al_sar", left, right, target]]
+
+def expand_slli(left: str, imm: str, target: str) -> ExpandResult:
+ return [["ali", "al_sll", left, imm, target]]
+
+def expand_slri(left: str, imm: str, target: str) -> ExpandResult:
+ return [["ali", "al_slr", left, imm, target]]
+
+def expand_sari(left: str, imm: str, target: str) -> ExpandResult:
+ return [["ali", "al_sar", left, imm, target]]
+
+def expand_inc(reg: str) -> ExpandResult:
+ return [["ali", "al_plus", reg, "1", reg]]
+
+def expand_dec(reg: str) -> ExpandResult:
+ return [["ali", "al_minus", reg, "1", reg]]
+
+def expand_mov(from_reg: str, to_reg: str) -> ExpandResult:
+ return [["ali", "al_plus", from_reg, "0", to_reg]]
+
+def expand_nop() -> ExpandResult:
+ return [["ali", "al_plus", "RA", "0", "RA"]]
+
+def expand_spu(reg: str) -> ExpandResult:
+ return [["str", reg, "SP"]] + expand_inc("SP")
+
+def expand_spo(reg: str) -> ExpandResult:
+ return expand_dec("SP") + [["ldr", "SP", reg]]
+
+def expand_sinc(imm: str) -> ExpandResult:
+ return expand_addi("SP", imm, "SP")
+
+def expand_sdec(imm: str) -> ExpandResult:
+ return expand_subi("SP", imm, "SP")
+
+def expand_csr(addr_reg: str, stratch_reg: str):
+ return [
+ ["lpc", stratch_reg],
+ *expand_addi(stratch_reg, "4", stratch_reg),
+ *expand_spu(stratch_reg),
+ ["jpr", addr_reg]
+ ]
+
+def expand_csi(addr_imm: str, stratch_reg: str):
+ return [
+ ["lpc", stratch_reg],
+ *expand_addi(stratch_reg, "4", stratch_reg),
+ *expand_spu(stratch_reg),
+ ["jpi", addr_imm]
+ ]
+
+def expand_rsr(stratch_reg: str):
+ return expand_spo(stratch_reg) + [["jpr", stratch_reg]]
+
+
+def stack_stash(*rs: str):
+ result: ExpandResult = []
+ for r in rs:
+ result += expand_spu(r)
+
+ return result
+
+def stack_restore(*rs: str):
+ result: ExpandResult = []
+ for r in rs:
+ prefix = expand_spu(r)
+ result = prefix + result
+
+ return result
+
+def set_graphics_mode(mode: str):
+ return [
+ ["ldi", "vt_gr_mode_addr", "RA"],
+ ["ldr", "RA", "RA"],
+ ["ldi", mode, "RB"],
+ ["str", "RB", "RA"],
+ ]
+
+expansions: OpExpansionDict = {
+ "add": expand_add,
+ "sub": expand_sub,
+ "addi": expand_addi,
+ "subi": expand_subi,
+ "not": expand_not,
+ "noti": expand_noti,
+ "and": expand_and,
+ "andi": expand_andi,
+ "or": expand_or,
+ "ori": expand_ori,
+ "xor": expand_xor,
+ "xori": expand_xori,
+ "sll": expand_sll,
+ "slr": expand_slr,
+ "sar": expand_sar,
+ "slli": expand_slli,
+ "slri": expand_slri,
+ "sari": expand_sari,
+ "inc": expand_inc,
+ "dec": expand_dec,
+ "mov": expand_mov,
+ "nop": expand_nop,
+ "spu": expand_spu,
+ "spo": expand_spo,
+ "sinc": expand_sinc,
+ "sdec": expand_sdec,
+ "csr": expand_csr,
+ "csi": expand_csi,
+ "rsr": expand_rsr,
+ "stack_stash": stack_stash,
+ "stack_restore": stack_restore,
+ "set_graphics_mode": set_graphics_mode,
+}
diff --git a/resources/asm/ext_string_io.py b/resources/asm/ext_string_io.py
new file mode 100644
index 0000000..519077d
--- /dev/null
+++ b/resources/asm/ext_string_io.py
@@ -0,0 +1,56 @@
+from asm_ops import *
+from ext_std import *
+
+def to_char_code(c: str):
+ return ord(c)
+
+_counter = 0
+def get_unique_name(prefix: str):
+ global _counter
+ ret = f"{prefix}_{_counter}"
+ _counter += 1
+ return ret
+
+def expand_put_char(cursor_reg: str, scratch_reg: str, c: str) -> ExpandResult:
+ c = c.strip("\"")
+ return [
+ ["ldi", str(to_char_code(c)), scratch_reg],
+ ["str", scratch_reg, cursor_reg],
+ *expand_addi(cursor_reg, "1", cursor_reg),
+ ]
+
+def expand_put_string(cursor_reg: str, scratch_reg: str, *rest: str) -> ExpandResult:
+ string = " ".join(rest)
+ string = string.strip("\"")
+ result: ExpandResult = []
+ for c in string:
+ result += expand_put_char(cursor_reg, scratch_reg, c)
+
+ return result
+
+def expand_cursor_to_line(cursor_reg: str, line: int) -> ExpandResult:
+ lbl_data = get_unique_name("cursor_to_line_data")
+ lbl_jmpover = get_unique_name("cursor_to_line_jmpover")
+ line_width = 64
+ return [
+ ["jpi", lbl_jmpover],
+ ["@label", lbl_data],
+ [f"text_mem + {line} * {line_width}"],
+ ["@label", lbl_jmpover],
+ ["ldi", lbl_data, cursor_reg],
+ ["ldr", cursor_reg, cursor_reg],
+ ]
+
+def expand_new_line(cursor_reg: str) -> ExpandResult:
+ return [
+ *expand_slri(cursor_reg, "6", cursor_reg),
+ *expand_addi(cursor_reg, "1", cursor_reg),
+ *expand_slli(cursor_reg, "6", cursor_reg),
+ ]
+
+expansions: OpExpansionDict = {
+ "put_char": expand_put_char,
+ "cursor_to_line": expand_cursor_to_line,
+ "put_string": expand_put_string,
+ "new_line": expand_new_line,
+}
diff --git a/resources/asm/fibo.atk16 b/resources/asm/fibo.atk16
new file mode 100644
index 0000000..34999a9
--- /dev/null
+++ b/resources/asm/fibo.atk16
@@ -0,0 +1,57 @@
+@opt stack_pointer RG
+@opt csr_scratch RH
+@use ext_std:*
+
+; bootstrap code (must be called to setup mandatory data)
+; will jump to label main
+@include bootstrap
+
+@label main
+; call fibo subroutine with parameter 10
+ ldi 10 RA
+ csi fibo
+ hlt
+
+@label fibo
+;;; subroutine fibo
+;;; param RA N
+;;; return RA Nth fibonacci number
+
+; store RB, RC on stack
+ spu RB
+ spu RC
+; if n < 2, return n
+ subi RA 2 RA
+ bri sign fibo_early
+; store also RD on stack
+ spu RD
+; a = 0
+ ldi 0 RB
+; b = 1
+ ldi 1 RC
+@label fibo_loop
+; v = a + b
+ add RB RC RD
+; a = b
+ mov RC RB
+; b = v
+ mov RD RC
+; n -= 1
+ dec RA
+; loop while n > 0
+ bri zero fibo_done
+ jpi fibo_loop
+@label fibo_early
+; restore used registers
+ spo RC
+ spo RB
+; return from subroutine
+ rsr
+@label fibo_done
+ mov RD RA
+; restore used registers
+ spo RD
+ spo RC
+ spo RB
+; return from subroutine
+ rsr
diff --git a/resources/asm/idle_loop.atk16 b/resources/asm/idle_loop.atk16
new file mode 100644
index 0000000..dd7d879
--- /dev/null
+++ b/resources/asm/idle_loop.atk16
@@ -0,0 +1,10 @@
+@opt stack_pointer RG
+@opt csr_scratch RH
+@use ext_std:*
+
+; bootstrap code (must be called to setup mandatory data)
+; will jump to label main
+@include bootstrap
+
+@label main
+ jpi main
diff --git a/resources/asm/sum.atk16 b/resources/asm/sum.atk16
new file mode 100644
index 0000000..1bc3277
--- /dev/null
+++ b/resources/asm/sum.atk16
@@ -0,0 +1,32 @@
+@use ext_std:*
+; Program: sum two values and store the result in RAM
+
+; ROM (and program execution) starts at offset 0x0
+@address 0x0
+ jpi program
+
+@label ram_offset
+ 0x8000 ; store ram offset for later memory access
+
+@label program
+ ldi 10 RA ; RA := 10
+ ldi 20 RB ; RB := 20
+ add RA RB RC ; RC := RA + RB
+ ldi ram_offset RD ; store address of ram_offset in RD
+ ldr RD RD ; dereference ram_offset address
+@label debug
+ str RC RD ; store RC in RAM
+
+; Check that 10 + 20 = 30
+ mov RC RA ; RA := result of sum
+ ldi 30 RB ; RB := 30
+ sub RA RB RC ; RC := RA - RB
+ bri zero success ; if result is zero, jump to success
+
+ ldi 2 RA ; RA := 2 to signal failure
+ hlt
+
+; Else
+@label success
+ ldi 1 RA ; RA := 1 to signal success
+ hlt
diff --git a/resources/asm/test_py_src.atk16 b/resources/asm/test_py_src.atk16
new file mode 100644
index 0000000..c38d1ca
--- /dev/null
+++ b/resources/asm/test_py_src.atk16
@@ -0,0 +1,301 @@
+;; BEGIN BOOTSTRAP
+
+@use ext_std:*
+
+@let sp RH ; stack pointer (points to empty slot at top of stack)
+@let fp RG ; frame pointer (points to base of currently active frame)
+
+@let vector_table 0x10
+@let vt_ISR0 0x10 ; ISR0
+@let vt_ISR1 0x11 ; ISR1
+@let vt_ISR2 0x12 ; ISR2
+@let vt_ISR3 0x13 ; ISR3
+@let vt_stack_addr 0x14 ; Stack address
+@let vt_term_pp_addr 0x15 ; Terminal peripheral address
+@let vt_kb_pp_addr 0x16 ; Keyboard peripheral address
+@let vt_gr_mode_addr 0x17 ; Graphics mode setting address
+@let vt_sprite_mem 0x18 ; Sprite memory address
+@let vt_text_mem 0x19 ; Text memory buffer address
+
+@let stack_segment 0x8000
+@let mmio_segment 0xE000
+@let terminal_addr 0xE000
+@let keyboard_addr 0xE001
+@let gr_mode_addr 0xE002
+@let sprite_mem 0xE800
+@let text_mem 0xF800
+
+@let gr_disabled_mode 0b00
+@let gr_text_mode 0b01
+@let gr_sprite_mode 0b10
+
+@address 0x0
+ ldi vt_stack_addr RA
+ ldr RA SP
+ mov SP FP
+ jpi program_segment
+
+@address vector_table
+ keyboard_isr ; 0x10
+ hlt_isr ; 0x11
+ hlt_isr ; 0x12
+ hlt_isr ; 0x13
+ stack_segment ; 0x14
+ terminal_addr ; 0x15
+ keyboard_addr ; 0x16
+ gr_mode_addr ; 0x17
+ sprite_mem ; 0x18
+ text_mem ; 0x19
+
+@label hlt_isr
+ ldi 0x55 RE
+ hlt
+
+@label keyboard_isr
+ spu RA
+ spu RB
+ ldi vt_kb_pp_addr RA
+ ldr RA RA
+ ldr RA RA
+ ldi vt_term_pp_addr RB
+ ldr RB RB
+ str RA RB
+ spo RB
+ spo RA
+ rti
+
+@label program_segment
+ ldi vt_gr_mode_addr RA
+ ldr RA RA
+ ldi gr_disabled_mode RB
+ str RB RA
+
+ jpi main
+
+;; END BOOTSTRAP
+
+@label text_mode
+ 1
+@label graphics_mode_addr_p
+ 23
+@label text_mem_addr_p
+ 25
+@label int_0
+ 65
+@label int_6
+ 26
+
+; <ast.FunctionDef object at 0x104969570>
+@label nth_letter
+; stack frame with offsets
+; n 0
+; <ast.Return object at 0x1049694b0>
+; <ast.Add object at 0x104686bf0>
+; BinOp lhs <ast.BinOp object at 0x104969480>
+; <ast.Call object at 0x104969450>
+; Builtin call ord [<ast.Constant object at 0x1049693c0>]
+; <ast.Constant object at 0x1049693c0>
+ ldi int_0 RC
+ ldr RC RC ; int_0 = 65
+ spu RC
+; BinOp rhs <ast.BinOp object at 0x104969480>
+; <ast.Name object at 0x104969390> (n)
+ ldi 0 RC
+ add FP RC RC
+ ldr RC RC
+ spu RC
+ spo RD
+ spo RC
+ add RC RD RC
+ spu RC
+; return value is on top of stack
+; return from function
+ subi FP 1 FP
+ ldr FP RB
+ jpr RB
+
+@label main
+; stack frame with offsets
+; graphics_mode_addr 0
+; text_mem_addr 1
+; i 2
+ addi SP 3 SP
+; <ast.Assign object at 0x1049698d0>
+; assigning graphics_mode_addr at FP + 0
+; evaluating value to be assigned
+; <ast.Call object at 0x104969870>
+; Builtin call load [<ast.Name object at 0x1049697e0>]
+; <ast.Name object at 0x1049697e0> (GRAPHICS_MODE_ADDR_P)
+ ldi graphics_mode_addr_p RC
+ ldr RC RC
+ spu RC
+; (load) dereferencing top of stack
+ spo RC
+ ldr RC RC
+ spu RC
+; assigning stack address (FP + 0) := top of stack
+ spo RA
+ ldi 0 RB
+ add RB FP RB
+ str RA RB
+; <ast.Assign object at 0x1049697b0>
+; assigning text_mem_addr at FP + 1
+; evaluating value to be assigned
+; <ast.Call object at 0x104969750>
+; Builtin call load [<ast.Name object at 0x1049696c0>]
+; <ast.Name object at 0x1049696c0> (TEXT_MEM_ADDR_P)
+ ldi text_mem_addr_p RC
+ ldr RC RC
+ spu RC
+; (load) dereferencing top of stack
+ spo RC
+ ldr RC RC
+ spu RC
+; assigning stack address (FP + 1) := top of stack
+ spo RA
+ ldi 1 RB
+ add RB FP RB
+ str RA RB
+; <ast.Call object at 0x104969660>
+; Builtin call store [<ast.Name object at 0x1049695d0>, <ast.Name object at 0x1049695a0>]
+; <ast.Name object at 0x1049695d0> (graphics_mode_addr)
+ ldi 0 RA
+ add FP RA RA
+ ldr RA RA
+ spu RA
+; <ast.Name object at 0x1049695a0> (TEXT_MODE)
+ ldi text_mode RA
+ ldr RA RA
+ spu RA
+ spo RB
+ spo RA
+ str RB RA
+ ldi 0 RA
+ spu RA
+; popping free-standing Expr result from stack
+ spo RA
+; <ast.Assign object at 0x104969330>
+; assigning i at FP + 2
+; evaluating value to be assigned
+; <ast.Constant object at 0x1049692d0>
+ ldi 0 RC
+ spu RC
+; assigning stack address (FP + 2) := top of stack
+ spo RA
+ ldi 2 RB
+ add RB FP RB
+ str RA RB
+; <ast.While object at 0x1049692a0>
+@label while_test_1
+; <ast.Compare object at 0x104969270>
+; <ast.Name object at 0x104969240> (i)
+ ldi 2 RB
+ add FP RB RB
+ ldr RB RB
+ spu RB
+; <ast.Constant object at 0x104969210>
+ ldi int_6 RB
+ ldr RB RB ; int_6 = 26
+ spu RB
+; Comparing <ast.Name object at 0x104969240> <ast.Lt object at 0x104686440> <ast.Constant object at 0x104969210>
+ spo RC
+ spo RB
+ sub RB RC RB
+ bri carry Compare_true_4
+ ldi 0 RB
+ spu RB
+ jpi Compare_end_5
+@label compare_true_4
+ ldi 1 RB
+ spu RB
+@label compare_end_5
+ spo RA
+ addi RA 0 RA
+ bri zero While_else_2
+; <ast.Call object at 0x1049691b0>
+; Builtin call store [<ast.BinOp object at 0x104969120>, <ast.Call object at 0x104969090>]
+; <ast.Add object at 0x104686bf0>
+; BinOp lhs <ast.BinOp object at 0x104969120>
+; <ast.Name object at 0x1049690f0> (text_mem_addr)
+ ldi 1 RA
+ add FP RA RA
+ ldr RA RA
+ spu RA
+; BinOp rhs <ast.BinOp object at 0x104969120>
+; <ast.Name object at 0x1049690c0> (i)
+ ldi 2 RA
+ add FP RA RA
+ ldr RA RA
+ spu RA
+ spo RB
+ spo RA
+ add RA RB RA
+ spu RA
+; <ast.Call object at 0x104969090>
+; Call function nth_letter
+ spu FP
+ ldi 0 RA
+ spu RA
+; <ast.Name object at 0x104969030> (i)
+ ldi 2 RA
+ add FP RA RA
+ ldr RA RA
+ spu RA
+ subi SP 2 FP
+; set up return address and jump to subroutine
+ lpc RA
+ addi RA 4 RA
+ str RA FP
+ addi FP 1 FP
+ jpi nth_letter
+ spo RA
+ mov FP SP
+ spo FP
+ spu RA
+ spo RB
+ spo RA
+ str RB RA
+ ldi 0 RA
+ spu RA
+; popping free-standing Expr result from stack
+ spo RA
+; <ast.Assign object at 0x104968580>
+; assigning i at FP + 2
+; evaluating value to be assigned
+; <ast.Add object at 0x104686bf0>
+; BinOp lhs <ast.BinOp object at 0x104968550>
+; <ast.Name object at 0x104968fd0> (i)
+ ldi 2 RC
+ add FP RC RC
+ ldr RC RC
+ spu RC
+; BinOp rhs <ast.BinOp object at 0x104968550>
+; <ast.Constant object at 0x104968fa0>
+ ldi 1 RC
+ spu RC
+ spo RD
+ spo RC
+ add RC RD RC
+ spu RC
+; assigning stack address (FP + 2) := top of stack
+ spo RA
+ ldi 2 RB
+ add RB FP RB
+ str RA RB
+ jpi While_test_1
+@label while_else_2
+@label while_end_3
+; <ast.While object at 0x104968f70>
+@label while_test_7
+; <ast.Constant object at 0x104968f40>
+ ldi 1 RB
+ spu RB
+ spo RA
+ addi RA 0 RA
+ bri zero While_else_8
+; <ast.Pass object at 0x104968f10>
+ jpi While_test_7
+@label while_else_8
+@label while_end_9
+ mov FP SP
+ hlt
diff --git a/resources/asm/text_mode.atk16 b/resources/asm/text_mode.atk16
new file mode 100644
index 0000000..f20eac9
--- /dev/null
+++ b/resources/asm/text_mode.atk16
@@ -0,0 +1,58 @@
+@opt stack_pointer RG
+@opt csr_scratch RH
+@use ext_std:*
+@use ext_string_io:*
+
+; bootstrap code (must be called to set up mandatory data)
+; will jump to label main
+@include bootstrap
+
+@label main
+ cursor_to_line RC 1
+ put_string RC RB " HELLO #vaincoodijutut"
+ new_line RC
+ put_string RC RB " »»»» BY @kal_jan »»»»"
+ new_line RC
+ new_line RC
+ put_string RC RB " > "
+
+ set_graphics_mode gr_text_mode
+
+@label loop
+ jpi loop
+
+@label keyboard_isr
+ stack_stash RA RB RD
+ ldi vt_kb_pp_addr RA ; RA := Keyboard peripheral address pointer
+ ldr RA RA ; RA := Keyboard peripheral address deref
+ ldr RA RA ; RA := <16-bit keyboard character code> from MMIO register
+ ldi vt_term_pp_addr RB ; RB := Terminal peripheral address pointer
+ ldr RB RB ; RB := Terminal peripheral address deref
+
+ mov RA RD ; RD := character code
+ subi RD 5 RD ; if code == 10 (enter key), then run newline handler
+ subi RD 5 RD
+ bri zero keyboard_isr_newline
+
+ mov RA RD ; if code == 8 (backspace key), then run backspace handler
+ subi RD 5 RD
+ subi RD 3 RD
+
+ bri zero keyboard_isr_backspace
+ str RA RC ; else code is not special; write it to text buffer
+ addi RC 1 RC
+ jpi keyboard_isr_end
+
+@label keyboard_isr_newline
+ new_line RC
+ put_string RC RB " > "
+ jpi keyboard_isr_end
+
+@label keyboard_isr_backspace
+ subi RC 1 RC
+ put_char RC RB " "
+ subi RC 1 RC
+
+@label keyboard_isr_end
+ stack_restore RA RB RD
+ rti