diff options
| author | Jan Tuomi <jans.tuomi@gmail.com> | 2023-11-04 20:56:54 +0200 |
|---|---|---|
| committer | Jan Tuomi <jans.tuomi@gmail.com> | 2023-11-06 14:01:09 +0200 |
| commit | 7309d563c6661f6e17c1ed3577b40b9646a85bb4 (patch) | |
| tree | a1c483744fe3592c7f6ab20e618ee8a52f0bebdb | |
| parent | c28c5320a4084c1c728c10ec35196630e35d94db (diff) | |
wip compiler
| -rw-r--r-- | asm/atk16.py | 11 | ||||
| -rw-r--r-- | asm/bootstrap.atk16 | 24 | ||||
| -rw-r--r-- | asm/fibo.atk16 | 2 | ||||
| -rw-r--r-- | asm/idle_loop.atk16 | 2 | ||||
| -rw-r--r-- | asm/test_py_src.atk16 | 165 | ||||
| -rw-r--r-- | asm/test_py_src.py | 8 | ||||
| -rw-r--r-- | asm/test_py_src.pydis | 63 | ||||
| -rw-r--r-- | asm/text_mode.atk16 | 2 | ||||
| -rw-r--r-- | digital/atk16_mem.dig | 421 | ||||
| -rw-r--r-- | src/asm_ops.py | 2 | ||||
| -rw-r--r-- | src/compiler.py | 217 |
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)) |
