aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Tuomi <jans.tuomi@gmail.com>2023-11-04 20:56:54 +0200
committerJan Tuomi <jans.tuomi@gmail.com>2023-11-06 14:01:09 +0200
commit7309d563c6661f6e17c1ed3577b40b9646a85bb4 (patch)
treea1c483744fe3592c7f6ab20e618ee8a52f0bebdb
parentc28c5320a4084c1c728c10ec35196630e35d94db (diff)
wip compiler
-rw-r--r--asm/atk16.py11
-rw-r--r--asm/bootstrap.atk1624
-rw-r--r--asm/fibo.atk162
-rw-r--r--asm/idle_loop.atk162
-rw-r--r--asm/test_py_src.atk16165
-rw-r--r--asm/test_py_src.py8
-rw-r--r--asm/test_py_src.pydis63
-rw-r--r--asm/text_mode.atk162
-rw-r--r--digital/atk16_mem.dig421
-rw-r--r--src/asm_ops.py2
-rw-r--r--src/compiler.py217
11 files changed, 699 insertions, 218 deletions
diff --git a/asm/atk16.py b/asm/atk16.py
new file mode 100644
index 0000000..143dd52
--- /dev/null
+++ b/asm/atk16.py
@@ -0,0 +1,11 @@
+def atk_store(addr: int, value: int):
+ return NotImplemented
+
+def atk_load(addr: int) -> int:
+ return NotImplemented
+
+def atk_put_char(c: int):
+ return NotImplemented
+
+def atk_enable_text_mode():
+ return NotImplemented
diff --git a/asm/bootstrap.atk16 b/asm/bootstrap.atk16
index a65fc99..6363d71 100644
--- a/asm/bootstrap.atk16
+++ b/asm/bootstrap.atk16
@@ -43,17 +43,17 @@
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 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
@@ -61,7 +61,7 @@
@address 0x0
; set up stack pointer to point to beginning of stack segment
ldi vt_stack_addr RA
- ldr RA RF
+ ldr RA __STACK_POINTER
jpi program_segment
@address program_segment
diff --git a/asm/fibo.atk16 b/asm/fibo.atk16
index fb375b3..34999a9 100644
--- a/asm/fibo.atk16
+++ b/asm/fibo.atk16
@@ -1,4 +1,4 @@
-@opt stack_pointer RF
+@opt stack_pointer RG
@opt csr_scratch RH
@use ext_std:*
diff --git a/asm/idle_loop.atk16 b/asm/idle_loop.atk16
index 442923c..dd7d879 100644
--- a/asm/idle_loop.atk16
+++ b/asm/idle_loop.atk16
@@ -1,4 +1,4 @@
-@opt stack_pointer RF
+@opt stack_pointer RG
@opt csr_scratch RH
@use ext_std:*
diff --git a/asm/test_py_src.atk16 b/asm/test_py_src.atk16
new file mode 100644
index 0000000..af8489b
--- /dev/null
+++ b/asm/test_py_src.atk16
@@ -0,0 +1,165 @@
+@opt stack_pointer RG
+@opt csr_scratch RH
+@use ext_std:*
+@include bootstrap
+@label py_consts
+; 0: 0
+ 0
+; 1: ('*',)
+ 0
+; 2: 63488
+ 63488
+; 3: 72
+ 72
+; 4: 63489
+ 63489
+; 5: 69
+ 69
+; 6: 63490
+ 63490
+; 7: 76
+ 76
+; 8: 63491
+ 63491
+; 9: 63492
+ 63492
+; 10: 79
+ 79
+; 11: None
+ 0
+@label atk_store
+ str RB RA
+ rsr
+@label atk_enable_text_mode
+ set_graphics_mode gr_text_mode
+ rsr
+@label main
+; PUSH_NULL None
+ ldi 0 RA
+ spu RA
+; LOAD_NAME 1
+ ldi atk_enable_text_mode RA
+ spu RA
+; PRECALL 0
+; CALL 0
+ spo RA
+ csr RA
+; POP_TOP None
+ spo RA
+; PUSH_NULL None
+ ldi 0 RA
+ spu RA
+; LOAD_NAME 2
+ ldi atk_store RA
+ spu RA
+; LOAD_CONST 2
+ ldi ${py_consts + 2} RA
+ ldr RA RA
+ spu RA
+; LOAD_CONST 3
+ ldi ${py_consts + 3} RA
+ ldr RA RA
+ spu RA
+; PRECALL 2
+; CALL 2
+ spo RB
+ spo RA
+ spo RC
+ csr RC
+; POP_TOP None
+ spo RA
+; PUSH_NULL None
+ ldi 0 RA
+ spu RA
+; LOAD_NAME 2
+ ldi atk_store RA
+ spu RA
+; LOAD_CONST 4
+ ldi ${py_consts + 4} RA
+ ldr RA RA
+ spu RA
+; LOAD_CONST 5
+ ldi ${py_consts + 5} RA
+ ldr RA RA
+ spu RA
+; PRECALL 2
+; CALL 2
+ spo RB
+ spo RA
+ spo RC
+ csr RC
+; POP_TOP None
+ spo RA
+; PUSH_NULL None
+ ldi 0 RA
+ spu RA
+; LOAD_NAME 2
+ ldi atk_store RA
+ spu RA
+; LOAD_CONST 6
+ ldi ${py_consts + 6} RA
+ ldr RA RA
+ spu RA
+; LOAD_CONST 7
+ ldi ${py_consts + 7} RA
+ ldr RA RA
+ spu RA
+; PRECALL 2
+; CALL 2
+ spo RB
+ spo RA
+ spo RC
+ csr RC
+; POP_TOP None
+ spo RA
+; PUSH_NULL None
+ ldi 0 RA
+ spu RA
+; LOAD_NAME 2
+ ldi atk_store RA
+ spu RA
+; LOAD_CONST 8
+ ldi ${py_consts + 8} RA
+ ldr RA RA
+ spu RA
+; LOAD_CONST 7
+ ldi ${py_consts + 7} RA
+ ldr RA RA
+ spu RA
+; PRECALL 2
+; CALL 2
+ spo RB
+ spo RA
+ spo RC
+ csr RC
+; POP_TOP None
+ spo RA
+; PUSH_NULL None
+ ldi 0 RA
+ spu RA
+; LOAD_NAME 2
+ ldi atk_store RA
+ spu RA
+; LOAD_CONST 9
+ ldi ${py_consts + 9} RA
+ ldr RA RA
+ spu RA
+; LOAD_CONST 10
+ ldi ${py_consts + 10} RA
+ ldr RA RA
+ spu RA
+; PRECALL 2
+; CALL 2
+ spo RB
+ spo RA
+ spo RC
+ csr RC
+; POP_TOP None
+ spo RA
+; LOAD_CONST 11
+ ldi ${py_consts + 11} RA
+ ldr RA RA
+ spu RA
+; RETURN_VALUE None
+@label keep_alive
+ jpi keep_alive \ No newline at end of file
diff --git a/asm/test_py_src.py b/asm/test_py_src.py
new file mode 100644
index 0000000..89658f8
--- /dev/null
+++ b/asm/test_py_src.py
@@ -0,0 +1,8 @@
+from atk16 import *
+
+atk_enable_text_mode()
+atk_store(0xF800, 65 + 7) # H
+atk_store(0xF801, 65 + 4) # E
+atk_store(0xF802, 65 + 11) # L
+atk_store(0xF803, 65 + 11) # L
+atk_store(0xF804, 65 + 14) # O
diff --git a/asm/test_py_src.pydis b/asm/test_py_src.pydis
new file mode 100644
index 0000000..483f073
--- /dev/null
+++ b/asm/test_py_src.pydis
@@ -0,0 +1,63 @@
+### Constants
+(0, ('*',), 63488, 72, 63489, 69, 63490, 76, 63491, 63492, 79, None)
+
+### Names
+('atk16', 'atk_enable_text_mode', 'atk_store')
+
+### Instructions
+RESUME 0
+LOAD_CONST 0
+LOAD_CONST 1
+IMPORT_NAME 0
+IMPORT_STAR None
+PUSH_NULL None
+LOAD_NAME 1
+PRECALL 0
+CALL 0
+POP_TOP None
+PUSH_NULL None
+LOAD_NAME 2
+LOAD_CONST 2
+LOAD_CONST 3
+PRECALL 2
+CALL 2
+POP_TOP None
+PUSH_NULL None
+LOAD_NAME 2
+LOAD_CONST 4
+LOAD_CONST 5
+PRECALL 2
+CALL 2
+POP_TOP None
+PUSH_NULL None
+LOAD_NAME 2
+LOAD_CONST 6
+LOAD_CONST 7
+PRECALL 2
+CALL 2
+POP_TOP None
+PUSH_NULL None
+LOAD_NAME 2
+LOAD_CONST 8
+LOAD_CONST 7
+PRECALL 2
+CALL 2
+POP_TOP None
+PUSH_NULL None
+LOAD_NAME 2
+LOAD_CONST 9
+LOAD_CONST 10
+PRECALL 2
+CALL 2
+POP_TOP None
+LOAD_CONST 11
+RETURN_VALUE None
+warn: cannot serialize <class 'tuple'> (('*',)), emitting zero
+warn: cannot serialize <class 'NoneType'> (None), emitting zero
+Skipping not implemented opcode: PRECALL
+Skipping not implemented opcode: PRECALL
+Skipping not implemented opcode: PRECALL
+Skipping not implemented opcode: PRECALL
+Skipping not implemented opcode: PRECALL
+Skipping not implemented opcode: PRECALL
+Skipping not implemented opcode: RETURN_VALUE
diff --git a/asm/text_mode.atk16 b/asm/text_mode.atk16
index 54741dc..f20eac9 100644
--- a/asm/text_mode.atk16
+++ b/asm/text_mode.atk16
@@ -1,4 +1,4 @@
-@opt stack_pointer RF
+@opt stack_pointer RG
@opt csr_scratch RH
@use ext_std:*
@use ext_string_io:*
diff --git a/digital/atk16_mem.dig b/digital/atk16_mem.dig
index 1ec8f11..356500f 100644
--- a/digital/atk16_mem.dig
+++ b/digital/atk16_mem.dig
@@ -1,10 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
<circuit>
<version>2</version>
<attributes>
<entry>
<string>romContent</string>
<romList>
- <roms />
+ <roms/>
</romList>
</entry>
<entry>
@@ -34,40 +35,56 @@
</entry>
<entry>
<string>Data</string>
- <data>4014,2a00,6019,8000,8000,8000,8000,8000,8000,8000,8000,8000,8000,8000,8000,8000,00c0,001a,001a,001a,8000,e000,e001,e002,e800,f800,4855,f000,4017,2000,4200,3008,6000,6001,f840,4422,2480,4220,3088,1488,4248,3088,1488,4245,3088,1488,424c,3088,1488,424c,3088,1488,424f,3088,1488,4220,3088,1488,4223,3088,1488,4276,3088,1488,4261,3088,1488,4269,3088,1488,426e,3088,1488,4263,3088,1488,426f,3088,1488,426f,3088,1488,4264,3088,1488,4269,3088,1488,426a,3088,1488,4275,3088,1488,4274,3088,1488,4275,3088,1488,4274,3088,1488,14b5,1488,14b7,4220,3088,1488,42bb,3088,1488,42bb,3088,1488,42bb,3088,1488,42bb,3088,1488,4220,3088,1488,4242,3088,1488,4259,3088,1488,4220,3088,1488,4240,3088,1488,426b,3088,1488,4261,3088,1488,426c,3088,1488,425f,3088,1488,426a,3088,1488,4261,3088,1488,426e,3088,1488,4220,3088,1488,42bb,3088,1488,42bb,3088,1488,42bb,3088,1488,42bb,3088,1488,14b5,1488,14b7,14b5,1488,14b7,4220,3088,1488,423e,3088,1488,4220,3088,1488,4017,2000,4201,3008,61ff,3140,1b48,3148,1b48,3158,1b48,4016,2000,2000,4215,2240,1600,16e9,16e9,8407,1600,16e9,16d9,8410,3080,1488,6012,14b5,1488,14b7,4220,3088,1488,423e,3088,1488,4220,3088,1488,6005,1489,4220,3088,1488,1489,3158,1b48,3148,1b48,3140,1b48,e000</data>
+ <data>4014,2c00,6029,13*8000,1c,1a,1a,1a,8000,e000,e001,e002,e800,f800
+,4855,f000,3180,1d88,3188,1d88,4016,2000,2000,4215,2240,3040,1800
+,3188,1d88,3180,1d88,e000,4017,2000,4200,3008,6017,0,0,f800,48
+,f801,45,f802,4c,f803,f804,4f,0,3008,1d89,2f80,51c0,4017,2000
+,4201,3008,1d89,2f80,51c0,4000,3180,1d88,4041,3180,1d88,1d89,2180
+,9e00,1fe0,31b8,1d88,5000,1d89,2180,4000,3180,1d88,403d,3180,1d88
+,4033,2000,3180,1d88,4034,2000,3180,1d88,1d89,2380,1d89,2180,1d89
+,2580,9e00,1fe0,31b8,1d88,5080,1d89,2180,4000,3180,1d88,403d,3180
+,1d88,4035,2000,3180,1d88,4036,2000,3180,1d88,1d89,2380,1d89,2180
+,1d89,2580,9e00,1fe0,31b8,1d88,5080,1d89,2180,4000,3180,1d88,403d
+,3180,1d88,4037,2000,3180,1d88,4038,2000,3180,1d88,1d89,2380,1d89
+,2180,1d89,2580,9e00,1fe0,31b8,1d88,5080,1d89,2180,4000,3180,1d88
+,403d,3180,1d88,4039,2000,3180,1d88,4038,2000,3180,1d88,1d89,2380
+,1d89,2180,1d89,2580,9e00,1fe0,31b8,1d88,5080,1d89,2180,4000,3180
+,1d88,403d,3180,1d88,403a,2000,3180,1d88,403b,2000,3180,1d88,1d89
+,2380,1d89,2180,1d89,2580,9e00,1fe0,31b8,1d88,5080,1d89,2180,403c
+,2000,3180,1d88,61ff</data>
</entry>
</elementAttributes>
- <pos x="740" y="100" />
+ <pos x="740" y="100"/>
</visualElement>
<visualElement>
<elementName>Ground</elementName>
<elementAttributes>
<entry>
<string>rotation</string>
- <rotation rotation="1" />
+ <rotation rotation="1"/>
</entry>
</elementAttributes>
- <pos x="720" y="160" />
+ <pos x="720" y="160"/>
</visualElement>
<visualElement>
<elementName>VDD</elementName>
<elementAttributes>
<entry>
<string>rotation</string>
- <rotation rotation="1" />
+ <rotation rotation="1"/>
</entry>
</elementAttributes>
- <pos x="720" y="120" />
+ <pos x="720" y="120"/>
</visualElement>
<visualElement>
<elementName>VDD</elementName>
<elementAttributes>
<entry>
<string>rotation</string>
- <rotation reference="../../../../visualElement[3]/elementAttributes/entry/rotation" />
+ <rotation reference="../../../../visualElement[3]/elementAttributes/entry/rotation"/>
</entry>
</elementAttributes>
- <pos x="720" y="180" />
+ <pos x="720" y="180"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
@@ -85,7 +102,7 @@
<int>16</int>
</entry>
</elementAttributes>
- <pos x="160" y="140" />
+ <pos x="160" y="140"/>
</visualElement>
<visualElement>
<elementName>Splitter</elementName>
@@ -99,12 +116,12 @@
<string>13,1,1,1</string>
</entry>
</elementAttributes>
- <pos x="220" y="140" />
+ <pos x="220" y="140"/>
</visualElement>
<visualElement>
<elementName>atk16_mem_mux.dig</elementName>
- <elementAttributes />
- <pos x="320" y="160" />
+ <elementAttributes/>
+ <pos x="320" y="160"/>
</visualElement>
<visualElement>
<elementName>Splitter</elementName>
@@ -118,7 +135,7 @@
<string>15</string>
</entry>
</elementAttributes>
- <pos x="320" y="80" />
+ <pos x="320" y="80"/>
</visualElement>
<visualElement>
<elementName>Splitter</elementName>
@@ -132,7 +149,7 @@
<string>2</string>
</entry>
</elementAttributes>
- <pos x="400" y="160" />
+ <pos x="400" y="160"/>
</visualElement>
<visualElement>
<elementName>Demultiplexer</elementName>
@@ -146,7 +163,7 @@
<int>15</int>
</entry>
</elementAttributes>
- <pos x="420" y="60" />
+ <pos x="420" y="60"/>
</visualElement>
<visualElement>
<elementName>Probe</elementName>
@@ -156,7 +173,7 @@
<string>ROM_OUT</string>
</entry>
</elementAttributes>
- <pos x="840" y="100" />
+ <pos x="840" y="100"/>
</visualElement>
<visualElement>
<elementName>Driver</elementName>
@@ -170,7 +187,7 @@
<boolean>true</boolean>
</entry>
</elementAttributes>
- <pos x="880" y="140" />
+ <pos x="880" y="140"/>
</visualElement>
<visualElement>
<elementName>Demultiplexer</elementName>
@@ -184,7 +201,7 @@
<boolean>true</boolean>
</entry>
</elementAttributes>
- <pos x="420" y="300" />
+ <pos x="420" y="300"/>
</visualElement>
<visualElement>
<elementName>Tunnel</elementName>
@@ -194,7 +211,7 @@
<string>RAM_IE</string>
</entry>
</elementAttributes>
- <pos x="480" y="320" />
+ <pos x="480" y="320"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
@@ -216,7 +233,7 @@
<boolean>true</boolean>
</entry>
</elementAttributes>
- <pos x="260" y="500" />
+ <pos x="260" y="500"/>
</visualElement>
<visualElement>
<elementName>Tunnel</elementName>
@@ -226,7 +243,7 @@
<string>CLK</string>
</entry>
</elementAttributes>
- <pos x="180" y="280" />
+ <pos x="180" y="280"/>
</visualElement>
<visualElement>
<elementName>RAMDualPort</elementName>
@@ -244,59 +261,59 @@
<int>16</int>
</entry>
</elementAttributes>
- <pos x="660" y="280" />
+ <pos x="660" y="280"/>
</visualElement>
<visualElement>
<elementName>VDD</elementName>
<elementAttributes>
<entry>
<string>rotation</string>
- <rotation rotation="1" />
+ <rotation rotation="1"/>
</entry>
</elementAttributes>
- <pos x="640" y="360" />
+ <pos x="640" y="360"/>
</visualElement>
<visualElement>
<elementName>Tunnel</elementName>
<elementAttributes>
<entry>
<string>rotation</string>
- <rotation rotation="2" />
+ <rotation rotation="2"/>
</entry>
<entry>
<string>NetName</string>
<string>CLK</string>
</entry>
</elementAttributes>
- <pos x="640" y="340" />
+ <pos x="640" y="340"/>
</visualElement>
<visualElement>
<elementName>Tunnel</elementName>
<elementAttributes>
<entry>
<string>rotation</string>
- <rotation rotation="2" />
+ <rotation rotation="2"/>
</entry>
<entry>
<string>NetName</string>
<string>RAM_IE</string>
</entry>
</elementAttributes>
- <pos x="640" y="320" />
+ <pos x="640" y="320"/>
</visualElement>
<visualElement>
<elementName>Tunnel</elementName>
<elementAttributes>
<entry>
<string>rotation</string>
- <rotation rotation="2" />
+ <rotation rotation="2"/>
</entry>
<entry>
<string>NetName</string>
<string>DBUS</string>
</entry>
</elementAttributes>
- <pos x="640" y="300" />
+ <pos x="640" y="300"/>
</visualElement>
<visualElement>
<elementName>Probe</elementName>
@@ -306,7 +323,7 @@
<string>RAM_OUT</string>
</entry>
</elementAttributes>
- <pos x="760" y="280" />
+ <pos x="760" y="280"/>
</visualElement>
<visualElement>
<elementName>Driver</elementName>
@@ -316,7 +333,7 @@
<int>16</int>
</entry>
</elementAttributes>
- <pos x="860" y="320" />
+ <pos x="860" y="320"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
@@ -330,7 +347,7 @@
<string>CLK</string>
</entry>
</elementAttributes>
- <pos x="160" y="280" />
+ <pos x="160" y="280"/>
</visualElement>
<visualElement>
<elementName>Out</elementName>
@@ -344,7 +361,7 @@
<string>MMIO_IE</string>
</entry>
</elementAttributes>
- <pos x="880" y="540" />
+ <pos x="880" y="540"/>
</visualElement>
<visualElement>
<elementName>Out</elementName>
@@ -358,7 +375,7 @@
<string>MMIO_OE</string>
</entry>
</elementAttributes>
- <pos x="880" y="600" />
+ <pos x="880" y="600"/>
</visualElement>
<visualElement>
<elementName>Tunnel</elementName>
@@ -368,7 +385,7 @@
<string>MMIO_S</string>
</entry>
</elementAttributes>
- <pos x="260" y="40" />
+ <pos x="260" y="40"/>
</visualElement>
<visualElement>
<elementName>Testcase</elementName>
@@ -394,7 +411,7 @@ C 0x8000 0 1 Z 0xAA
</testData>
</entry>
</elementAttributes>
- <pos x="540" y="480" />
+ <pos x="540" y="480"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
@@ -408,7 +425,7 @@ C 0x8000 0 1 Z 0xAA
<string>MEM_IE</string>
</entry>
</elementAttributes>
- <pos x="160" y="340" />
+ <pos x="160" y="340"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
@@ -422,17 +439,17 @@ C 0x8000 0 1 Z 0xAA
<string>MEM_OE</string>
</entry>
</elementAttributes>
- <pos x="260" y="560" />
+ <pos x="260" y="560"/>
</visualElement>
<visualElement>
<elementName>And</elementName>
<elementAttributes>
<entry>
<string>rotation</string>
- <rotation rotation="2" />
+ <rotation rotation="2"/>
</entry>
</elementAttributes>
- <pos x="960" y="280" />
+ <pos x="960" y="280"/>
</visualElement>
<visualElement>
<elementName>Tunnel</elementName>
@@ -442,7 +459,7 @@ C 0x8000 0 1 Z 0xAA
<string>RAM_OE</string>
</entry>
</elementAttributes>
- <pos x="960" y="280" />
+ <pos x="960" y="280"/>
</visualElement>
<visualElement>
<elementName>Tunnel</elementName>
@@ -452,7 +469,7 @@ C 0x8000 0 1 Z 0xAA
<string>MEM_OE</string>
</entry>
</elementAttributes>
- <pos x="280" y="560" />
+ <pos x="280" y="560"/>
</visualElement>
<visualElement>
<elementName>Tunnel</elementName>
@@ -462,7 +479,7 @@ C 0x8000 0 1 Z 0xAA
<string>MEM_OE</string>
</entry>
</elementAttributes>
- <pos x="960" y="240" />
+ <pos x="960" y="240"/>
</visualElement>
<visualElement>
<elementName>Tunnel</elementName>
@@ -472,17 +489,17 @@ C 0x8000 0 1 Z 0xAA
<string>DBUS</string>
</entry>
</elementAttributes>
- <pos x="900" y="320" />
+ <pos x="900" y="320"/>
</visualElement>
<visualElement>
<elementName>And</elementName>
<elementAttributes>
<entry>
<string>rotation</string>
- <rotation rotation="2" />
+ <rotation rotation="2"/>
</entry>
</elementAttributes>
- <pos x="960" y="200" />
+ <pos x="960" y="200"/>
</visualElement>
<visualElement>
<elementName>Tunnel</elementName>
@@ -492,7 +509,7 @@ C 0x8000 0 1 Z 0xAA
<string>ROM_OE</string>
</entry>
</elementAttributes>
- <pos x="960" y="200" />
+ <pos x="960" y="200"/>
</visualElement>
<visualElement>
<elementName>Tunnel</elementName>
@@ -502,7 +519,7 @@ C 0x8000 0 1 Z 0xAA
<string>MEM_OE</string>
</entry>
</elementAttributes>
- <pos x="960" y="160" />
+ <pos x="960" y="160"/>
</visualElement>
<visualElement>
<elementName>Tunnel</elementName>
@@ -512,7 +529,7 @@ C 0x8000 0 1 Z 0xAA
<string>DBUS</string>
</entry>
</elementAttributes>
- <pos x="920" y="120" />
+ <pos x="920" y="120"/>
</visualElement>
<visualElement>
<elementName>Tunnel</elementName>
@@ -522,7 +539,7 @@ C 0x8000 0 1 Z 0xAA
<string>DBUS</string>
</entry>
</elementAttributes>
- <pos x="280" y="500" />
+ <pos x="280" y="500"/>
</visualElement>
<visualElement>
<elementName>Decoder</elementName>
@@ -536,7 +553,7 @@ C 0x8000 0 1 Z 0xAA
<boolean>true</boolean>
</entry>
</elementAttributes>
- <pos x="460" y="180" />
+ <pos x="460" y="180"/>
</visualElement>
<visualElement>
<elementName>Tunnel</elementName>
@@ -546,7 +563,7 @@ C 0x8000 0 1 Z 0xAA
<string>ROM_OE</string>
</entry>
</elementAttributes>
- <pos x="500" y="180" />
+ <pos x="500" y="180"/>
</visualElement>
<visualElement>
<elementName>Tunnel</elementName>
@@ -556,7 +573,7 @@ C 0x8000 0 1 Z 0xAA
<string>RAM_OE</string>
</entry>
</elementAttributes>
- <pos x="500" y="200" />
+ <pos x="500" y="200"/>
</visualElement>
<visualElement>
<elementName>Tunnel</elementName>
@@ -566,7 +583,7 @@ C 0x8000 0 1 Z 0xAA
<string>MMIO_OE</string>
</entry>
</elementAttributes>
- <pos x="500" y="220" />
+ <pos x="500" y="220"/>
</visualElement>
<visualElement>
<elementName>Tunnel</elementName>
@@ -576,73 +593,73 @@ C 0x8000 0 1 Z 0xAA
<string>MMIO_IE</string>
</entry>
</elementAttributes>
- <pos x="480" y="340" />
+ <pos x="480" y="340"/>
</visualElement>
<visualElement>
<elementName>And</elementName>
- <elementAttributes />
- <pos x="780" y="580" />
+ <elementAttributes/>
+ <pos x="780" y="580"/>
</visualElement>
<visualElement>
<elementName>Tunnel</elementName>
<elementAttributes>
<entry>
<string>rotation</string>
- <rotation rotation="2" />
+ <rotation rotation="2"/>
</entry>
<entry>
<string>NetName</string>
<string>MEM_OE</string>
</entry>
</elementAttributes>
- <pos x="780" y="620" />
+ <pos x="780" y="620"/>
</visualElement>
<visualElement>
<elementName>Tunnel</elementName>
<elementAttributes>
<entry>
<string>rotation</string>
- <rotation rotation="2" />
+ <rotation rotation="2"/>
</entry>
<entry>
<string>NetName</string>
<string>MMIO_OE</string>
</entry>
</elementAttributes>
- <pos x="780" y="580" />
+ <pos x="780" y="580"/>
</visualElement>
<visualElement>
<elementName>And</elementName>
- <elementAttributes />
- <pos x="780" y="500" />
+ <elementAttributes/>
+ <pos x="780" y="500"/>
</visualElement>
<visualElement>
<elementName>Tunnel</elementName>
<elementAttributes>
<entry>
<string>rotation</string>
- <rotation rotation="2" />
+ <rotation rotation="2"/>
</entry>
<entry>
<string>NetName</string>
<string>MEM_IE</string>
</entry>
</elementAttributes>
- <pos x="780" y="540" />
+ <pos x="780" y="540"/>
</visualElement>
<visualElement>
<elementName>Tunnel</elementName>
<elementAttributes>
<entry>
<string>rotation</string>
- <rotation rotation="2" />
+ <rotation rotation="2"/>
</entry>
<entry>
<string>NetName</string>
<string>MMIO_IE</string>
</entry>
</elementAttributes>
- <pos x="780" y="500" />
+ <pos x="780" y="500"/>
</visualElement>
<visualElement>
<elementName>Out</elementName>
@@ -660,21 +677,21 @@ C 0x8000 0 1 Z 0xAA
<int>13</int>
</entry>
</elementAttributes>
- <pos x="880" y="460" />
+ <pos x="880" y="460"/>
</visualElement>
<visualElement>
<elementName>Tunnel</elementName>
<elementAttributes>
<entry>
<string>rotation</string>
- <rotation rotation="2" />
+ <rotation rotation="2"/>
</entry>
<entry>
<string>NetName</string>
<string>MMIO_S</string>
</entry>
</elementAttributes>
- <pos x="860" y="460" />
+ <pos x="860" y="460"/>
</visualElement>
<visualElement>
<elementName>Tunnel</elementName>
@@ -684,266 +701,266 @@ C 0x8000 0 1 Z 0xAA
<string>MEM_IE</string>
</entry>
</elementAttributes>
- <pos x="300" y="360" />
+ <pos x="300" y="360"/>
</visualElement>
</visualElements>
<wires>
<wire>
- <p1 x="720" y="160" />
- <p2 x="740" y="160" />
+ <p1 x="720" y="160"/>
+ <p2 x="740" y="160"/>
</wire>
<wire>
- <p1 x="240" y="160" />
- <p2 x="260" y="160" />
+ <p1 x="240" y="160"/>
+ <p2 x="260" y="160"/>
</wire>
<wire>
- <p1 x="380" y="160" />
- <p2 x="400" y="160" />
+ <p1 x="380" y="160"/>
+ <p2 x="400" y="160"/>
</wire>
<wire>
- <p1 x="420" y="160" />
- <p2 x="440" y="160" />
+ <p1 x="420" y="160"/>
+ <p2 x="440" y="160"/>
</wire>
<wire>
- <p1 x="260" y="160" />
- <p2 x="320" y="160" />
+ <p1 x="260" y="160"/>
+ <p2 x="320" y="160"/>
</wire>
<wire>
- <p1 x="440" y="160" />
- <p2 x="480" y="160" />
+ <p1 x="440" y="160"/>
+ <p2 x="480" y="160"/>
</wire>
<wire>
- <p1 x="460" y="320" />
- <p2 x="480" y="320" />
+ <p1 x="460" y="320"/>
+ <p2 x="480" y="320"/>
</wire>
<wire>
- <p1 x="640" y="320" />
- <p2 x="660" y="320" />
+ <p1 x="640" y="320"/>
+ <p2 x="660" y="320"/>
</wire>
<wire>
- <p1 x="720" y="320" />
- <p2 x="760" y="320" />
+ <p1 x="720" y="320"/>
+ <p2 x="760" y="320"/>
</wire>
<wire>
- <p1 x="880" y="320" />
- <p2 x="900" y="320" />
+ <p1 x="880" y="320"/>
+ <p2 x="900" y="320"/>
</wire>
<wire>
- <p1 x="760" y="320" />
- <p2 x="840" y="320" />
+ <p1 x="760" y="320"/>
+ <p2 x="840" y="320"/>
</wire>
<wire>
- <p1 x="620" y="100" />
- <p2 x="740" y="100" />
+ <p1 x="620" y="100"/>
+ <p2 x="740" y="100"/>
</wire>
<wire>
- <p1 x="260" y="100" />
- <p2 x="320" y="100" />
+ <p1 x="260" y="100"/>
+ <p2 x="320" y="100"/>
</wire>
<wire>
- <p1 x="380" y="100" />
- <p2 x="420" y="100" />
+ <p1 x="380" y="100"/>
+ <p2 x="420" y="100"/>
</wire>
<wire>
- <p1 x="860" y="260" />
- <p2 x="900" y="260" />
+ <p1 x="860" y="260"/>
+ <p2 x="900" y="260"/>
</wire>
<wire>
- <p1 x="240" y="200" />
- <p2 x="320" y="200" />
+ <p1 x="240" y="200"/>
+ <p2 x="320" y="200"/>
</wire>
<wire>
- <p1 x="640" y="360" />
- <p2 x="660" y="360" />
+ <p1 x="640" y="360"/>
+ <p2 x="660" y="360"/>
</wire>
<wire>
- <p1 x="280" y="360" />
- <p2 x="300" y="360" />
+ <p1 x="280" y="360"/>
+ <p2 x="300" y="360"/>
</wire>
<wire>
- <p1 x="240" y="40" />
- <p2 x="260" y="40" />
+ <p1 x="240" y="40"/>
+ <p2 x="260" y="40"/>
</wire>
<wire>
- <p1 x="840" y="520" />
- <p2 x="860" y="520" />
+ <p1 x="840" y="520"/>
+ <p2 x="860" y="520"/>
</wire>
<wire>
- <p1 x="640" y="300" />
- <p2 x="660" y="300" />
+ <p1 x="640" y="300"/>
+ <p2 x="660" y="300"/>
</wire>
<wire>
- <p1 x="800" y="140" />
- <p2 x="840" y="140" />
+ <p1 x="800" y="140"/>
+ <p2 x="840" y="140"/>
</wire>
<wire>
- <p1 x="160" y="140" />
- <p2 x="220" y="140" />
+ <p1 x="160" y="140"/>
+ <p2 x="220" y="140"/>
</wire>
<wire>
- <p1 x="840" y="140" />
- <p2 x="860" y="140" />
+ <p1 x="840" y="140"/>
+ <p2 x="860" y="140"/>
</wire>
<wire>
- <p1 x="860" y="460" />
- <p2 x="880" y="460" />
+ <p1 x="860" y="460"/>
+ <p2 x="880" y="460"/>
</wire>
<wire>
- <p1 x="240" y="80" />
- <p2 x="320" y="80" />
+ <p1 x="240" y="80"/>
+ <p2 x="320" y="80"/>
</wire>
<wire>
- <p1 x="340" y="80" />
- <p2 x="380" y="80" />
+ <p1 x="340" y="80"/>
+ <p2 x="380" y="80"/>
</wire>
<wire>
- <p1 x="460" y="80" />
- <p2 x="600" y="80" />
+ <p1 x="460" y="80"/>
+ <p2 x="600" y="80"/>
</wire>
<wire>
- <p1 x="260" y="560" />
- <p2 x="280" y="560" />
+ <p1 x="260" y="560"/>
+ <p2 x="280" y="560"/>
</wire>
<wire>
- <p1 x="720" y="180" />
- <p2 x="740" y="180" />
+ <p1 x="720" y="180"/>
+ <p2 x="740" y="180"/>
</wire>
<wire>
- <p1 x="240" y="180" />
- <p2 x="280" y="180" />
+ <p1 x="240" y="180"/>
+ <p2 x="280" y="180"/>
</wire>
<wire>
- <p1 x="380" y="180" />
- <p2 x="400" y="180" />
+ <p1 x="380" y="180"/>
+ <p2 x="400" y="180"/>
</wire>
<wire>
- <p1 x="880" y="180" />
- <p2 x="900" y="180" />
+ <p1 x="880" y="180"/>
+ <p2 x="900" y="180"/>
</wire>
<wire>
- <p1 x="280" y="180" />
- <p2 x="320" y="180" />
+ <p1 x="280" y="180"/>
+ <p2 x="320" y="180"/>
</wire>
<wire>
- <p1 x="640" y="340" />
- <p2 x="660" y="340" />
+ <p1 x="640" y="340"/>
+ <p2 x="660" y="340"/>
</wire>
<wire>
- <p1 x="160" y="340" />
- <p2 x="280" y="340" />
+ <p1 x="160" y="340"/>
+ <p2 x="280" y="340"/>
</wire>
<wire>
- <p1 x="460" y="340" />
- <p2 x="480" y="340" />
+ <p1 x="460" y="340"/>
+ <p2 x="480" y="340"/>
</wire>
<wire>
- <p1 x="280" y="340" />
- <p2 x="420" y="340" />
+ <p1 x="280" y="340"/>
+ <p2 x="420" y="340"/>
</wire>
<wire>
- <p1 x="260" y="500" />
- <p2 x="280" y="500" />
+ <p1 x="260" y="500"/>
+ <p2 x="280" y="500"/>
</wire>
<wire>
- <p1 x="160" y="280" />
- <p2 x="180" y="280" />
+ <p1 x="160" y="280"/>
+ <p2 x="180" y="280"/>
</wire>
<wire>
- <p1 x="600" y="280" />
- <p2 x="660" y="280" />
+ <p1 x="600" y="280"/>
+ <p2 x="660" y="280"/>
</wire>
<wire>
- <p1 x="720" y="120" />
- <p2 x="740" y="120" />
+ <p1 x="720" y="120"/>
+ <p2 x="740" y="120"/>
</wire>
<wire>
- <p1 x="280" y="120" />
- <p2 x="320" y="120" />
+ <p1 x="280" y="120"/>
+ <p2 x="320" y="120"/>
</wire>
<wire>
- <p1 x="900" y="120" />
- <p2 x="920" y="120" />
+ <p1 x="900" y="120"/>
+ <p2 x="920" y="120"/>
</wire>
<wire>
- <p1 x="840" y="600" />
- <p2 x="880" y="600" />
+ <p1 x="840" y="600"/>
+ <p2 x="880" y="600"/>
</wire>
<wire>
- <p1 x="460" y="60" />
- <p2 x="620" y="60" />
+ <p1 x="460" y="60"/>
+ <p2 x="620" y="60"/>
</wire>
<wire>
- <p1 x="860" y="540" />
- <p2 x="880" y="540" />
+ <p1 x="860" y="540"/>
+ <p2 x="880" y="540"/>
</wire>
<wire>
- <p1 x="480" y="160" />
- <p2 x="480" y="180" />
+ <p1 x="480" y="160"/>
+ <p2 x="480" y="180"/>
</wire>
<wire>
- <p1 x="260" y="100" />
- <p2 x="260" y="160" />
+ <p1 x="260" y="100"/>
+ <p2 x="260" y="160"/>
</wire>
<wire>
- <p1 x="900" y="120" />
- <p2 x="900" y="140" />
+ <p1 x="900" y="120"/>
+ <p2 x="900" y="140"/>
</wire>
<wire>
- <p1 x="840" y="100" />
- <p2 x="840" y="140" />
+ <p1 x="840" y="100"/>
+ <p2 x="840" y="140"/>
</wire>
<wire>
- <p1 x="620" y="60" />
- <p2 x="620" y="100" />
+ <p1 x="620" y="60"/>
+ <p2 x="620" y="100"/>
</wire>
<wire>
- <p1 x="240" y="40" />
- <p2 x="240" y="80" />
+ <p1 x="240" y="40"/>
+ <p2 x="240" y="80"/>
</wire>
<wire>
- <p1 x="240" y="80" />
- <p2 x="240" y="140" />
+ <p1 x="240" y="80"/>
+ <p2 x="240" y="140"/>
</wire>
<wire>
- <p1 x="880" y="160" />
- <p2 x="880" y="180" />
+ <p1 x="880" y="160"/>
+ <p2 x="880" y="180"/>
</wire>
<wire>
- <p1 x="280" y="120" />
- <p2 x="280" y="180" />
+ <p1 x="280" y="120"/>
+ <p2 x="280" y="180"/>
</wire>
<wire>
- <p1 x="280" y="340" />
- <p2 x="280" y="360" />
+ <p1 x="280" y="340"/>
+ <p2 x="280" y="360"/>
</wire>
<wire>
- <p1 x="440" y="140" />
- <p2 x="440" y="160" />
+ <p1 x="440" y="140"/>
+ <p2 x="440" y="160"/>
</wire>
<wire>
- <p1 x="440" y="160" />
- <p2 x="440" y="300" />
+ <p1 x="440" y="160"/>
+ <p2 x="440" y="300"/>
</wire>
<wire>
- <p1 x="600" y="80" />
- <p2 x="600" y="280" />
+ <p1 x="600" y="80"/>
+ <p2 x="600" y="280"/>
</wire>
<wire>
- <p1 x="760" y="280" />
- <p2 x="760" y="320" />
+ <p1 x="760" y="280"/>
+ <p2 x="760" y="320"/>
</wire>
<wire>
- <p1 x="380" y="80" />
- <p2 x="380" y="100" />
+ <p1 x="380" y="80"/>
+ <p2 x="380" y="100"/>
</wire>
<wire>
- <p1 x="860" y="520" />
- <p2 x="860" y="540" />
+ <p1 x="860" y="520"/>
+ <p2 x="860" y="540"/>
</wire>
<wire>
- <p1 x="860" y="260" />
- <p2 x="860" y="300" />
+ <p1 x="860" y="260"/>
+ <p2 x="860" y="300"/>
</wire>
</wires>
- <measurementOrdering />
+ <measurementOrdering/>
</circuit> \ No newline at end of file
diff --git a/src/asm_ops.py b/src/asm_ops.py
index a2631e3..e09e0fd 100644
--- a/src/asm_ops.py
+++ b/src/asm_ops.py
@@ -4,7 +4,7 @@ from dataclasses import dataclass
@dataclass
class Options:
- stack_pointer = "rf"
+ stack_pointer = "rg"
csr_scratch = "rh"
@dataclass
diff --git a/src/compiler.py b/src/compiler.py
new file mode 100644
index 0000000..d08d8db
--- /dev/null
+++ b/src/compiler.py
@@ -0,0 +1,217 @@
+#!/usr/bin/env python3
+# Generate .atk16 assembly from a subset of Python
+
+import sys
+import dis
+
+from dataclasses import dataclass
+from typing import Literal, Set, cast, Any
+from collections import OrderedDict
+
+if len(sys.argv) != 3:
+ print("usage: compiler.py <infile.py> <outfile.atk16>")
+ sys.exit(1)
+
+infile_path = sys.argv[1]
+outfile_path = sys.argv[2]
+
+with open(infile_path, "r") as f:
+ source_py = f.read()
+
+compiled_code = compile(source_py, infile_path, 'exec')
+disassembled = dis.get_instructions(compiled_code)
+
+co_consts = compiled_code.co_consts
+co_names = compiled_code.co_names
+print("### Constants")
+print(co_consts)
+print("\n### Names")
+print(co_names)
+print("\n### Instructions")
+instrs: list[tuple[str, int | None]] = []
+for instr in disassembled:
+ print(f"{instr.opname}\t{instr.arg}")
+ instrs.append((instr.opname, instr.arg))
+
+### compile
+asm_out: list[str] = []
+def emit(stmt: str) -> int:
+ ret = len(asm_out)
+ asm_out.append(stmt)
+ return ret
+
+_counter = 0
+def get_unique_name(prefix: str):
+ global _counter
+ ret = f"{prefix}_{_counter}"
+ _counter += 1
+ return ret
+
+@dataclass
+class Label:
+ label: str
+
+ def __str__(self):
+ return f"@label {self.label}"
+
+RegChar = Literal["A", "B", "C", "D", "E", "F", "G", "H"]
+GENERIC_REGS_LST: list[RegChar] = ["A", "B", "C", "D", "E", "F"]
+GENERIC_REGS: OrderedDict[RegChar, None] = OrderedDict()
+for char in GENERIC_REGS_LST:
+ GENERIC_REGS[cast(RegChar, char)] = None
+
+@dataclass
+class Reg:
+ reg: RegChar
+
+ def __str__(self):
+ return f"R{self.reg}"
+
+Value = Label | Reg
+
+reserved_regs: OrderedDict[RegChar, None] = OrderedDict()
+def alloc_reg() -> Reg:
+ for reg in GENERIC_REGS:
+ if not reg in reserved_regs:
+ reserved_regs[reg] = None
+ return Reg(reg)
+
+ raise Exception("Ran out of registers, TODO use stack")
+
+def free_reg(reg: Reg):
+ reserved_regs.pop(reg.reg)
+
+def emit_serialize_const(const: Any):
+ match const:
+ case int(v):
+ emit(f" {v}")
+ case _:
+ print(f"warn: cannot serialize {type(const)} ({const}), emitting zero")
+ emit(" 0")
+
+STACK_POINTER_REG = Reg('G')
+CSR_SCRATCH_REG = Reg('H')
+emit(f"@opt stack_pointer {STACK_POINTER_REG}")
+emit(f"@opt csr_scratch {CSR_SCRATCH_REG}")
+emit("@use ext_std:*")
+emit("@include bootstrap")
+
+py_consts_addr = emit("@label py_consts")
+
+for const_i, const in enumerate(co_consts):
+ emit(f"; {const_i}: {const}")
+ emit_serialize_const(const)
+
+emit("@label atk_store")
+_reg_value = alloc_reg()
+_reg_addr = alloc_reg()
+emit(f" str RB RA")
+emit(f" rsr")
+free_reg(_reg_value)
+free_reg(_reg_addr)
+
+emit("@label atk_enable_text_mode")
+emit(" set_graphics_mode gr_text_mode")
+emit(" rsr")
+
+emit("@label main")
+
+instr_i = 0
+
+def instr_pop():
+ global instr_i
+ ret = instrs[instr_i]
+ instr_i += 1
+ return ret
+
+def instr_pop_expect(opcode: str, arg: int | None = -1):
+ ret_op, ret_arg = instr_pop()
+ if ret_op != opcode:
+ raise Exception(f"Expected opcode {opcode}, got {ret_op}")
+ if arg != -1 and arg != ret_arg:
+ raise Exception(f"Expected instruction arg {arg}, got {ret_arg}")
+ return ret_op, ret_arg
+
+def instr_peek():
+ return instrs[instr_i]
+
+def instr_peek_expect(opcode: str, arg: int | None = -1):
+ ret_op, ret_arg = instr_peek()
+ if ret_op != opcode:
+ raise Exception(f"Expected {opcode}, got {ret_op}")
+ if arg != -1 and arg != ret_arg:
+ raise Exception(f"Expected instruction arg {arg}, got {ret_arg}")
+ return ret_op, ret_arg
+
+instr_pop_expect("RESUME")
+instr_pop_expect("LOAD_CONST", 0)
+instr_pop_expect("LOAD_CONST", 1)
+instr_pop_expect("IMPORT_NAME", 0)
+instr_pop_expect("IMPORT_STAR", None)
+
+while instr_i < len(instrs):
+ opcode, arg = instr_pop()
+ emit(f"; {opcode} {arg}")
+ match opcode:
+ case "LOAD_CONST":
+ reg = alloc_reg()
+ emit(f" ldi ${{py_consts + {cast(int, arg)}}} {reg}")
+ emit(f" ldr {reg} {reg}")
+ emit(f" spu {reg}")
+ free_reg(reg)
+ case "PUSH_NULL":
+ reg = alloc_reg()
+ emit(f" ldi 0 {reg}")
+ emit(f" spu {reg}")
+ free_reg(reg)
+ case "LOAD_NAME":
+ name = co_names[cast(int, arg)]
+ reg = alloc_reg()
+ emit(f" ldi {name} {reg}")
+ emit(f" spu {reg}")
+ free_reg(reg)
+ case "CALL":
+ arg_count = cast(int, arg)
+ # if arg_count > len(GENERIC_REGS_LST):
+ # raise Exception(f"Function calls with > {len(GENERIC_REGS_LST)} arguments not supported")
+
+ regs_to_restore: list[tuple[Reg, Reg]] = []
+ for j in range(arg_count):
+ i = arg_count - j - 1
+ ith_reg_char = GENERIC_REGS_LST[i]
+ ith_reg = Reg(ith_reg_char)
+ if ith_reg_char in reserved_regs:
+ reg = alloc_reg()
+ emit(f" mov {ith_reg} {reg}")
+ regs_to_restore.append((reg, ith_reg))
+
+ emit(f" spo {ith_reg}")
+ reserved_regs[ith_reg_char] = None # manually reserve ith_reg
+
+ fn_reg = alloc_reg()
+ emit(f" spo {fn_reg}")
+ # emit(f" ldr {fn_reg} {fn_reg}")
+ emit(f" csr {fn_reg}")
+ free_reg(fn_reg)
+
+ for from_reg, ith_reg in regs_to_restore:
+ emit(f" mov {from_reg} {ith_reg}")
+
+ for j in range(arg_count):
+ i = arg_count - j - 1
+ ith_reg_char = GENERIC_REGS_LST[i]
+ ith_reg = Reg(ith_reg_char)
+ free_reg(ith_reg)
+
+ case "POP_TOP":
+ reg = alloc_reg()
+ emit(f" spo {reg}")
+ free_reg(reg)
+ case _:
+ print(f"Skipping not implemented opcode: {opcode}")
+
+emit("@label keep_alive")
+emit(" jpi keep_alive")
+
+with open(outfile_path, "w") as f:
+ f.write("\n".join(asm_out))