From c2f80009a730ae936fa0e26a857e9f618530c9ea Mon Sep 17 00:00:00 2001 From: Gagan Kumar Date: Mon, 16 Dec 2024 22:20:09 -0800 Subject: [PATCH 1/5] Load BROM to load PROM --- output/programs/3_led_switch.bin | 2 +- output/programs/boot_sequence.bin | 25 +- output/programs/boot_sequence_resolved.asm | 33 +- output/programs/ping_pong.bin | 172 ++++---- output/programs/ping_pong_resolved.asm | 466 ++++++++++----------- planner/asm/program_parser.py | 2 +- planner/memory.py | 5 +- planner/sim/bin_parser.py | 20 +- planner/sim/devices.py | 49 ++- planner/sim/programs/ping_pong.py | 19 +- planner/util.py | 11 + programs/boot_sequence.asm | 51 ++- programs/ping_pong.asm | 25 +- 13 files changed, 460 insertions(+), 420 deletions(-) diff --git a/output/programs/3_led_switch.bin b/output/programs/3_led_switch.bin index 140edcd..334da93 100644 --- a/output/programs/3_led_switch.bin +++ b/output/programs/3_led_switch.bin @@ -1,4 +1,4 @@ -00000000 00000000 00000000 00001100 +00001100 00000000 00000000 00000000 00100100 00000010 00000100 00000101 00000100 00000100 00000110 00000100 00110101 00001001 01000000 00000000 diff --git a/output/programs/boot_sequence.bin b/output/programs/boot_sequence.bin index 08c42f7..8d0c3fa 100644 --- a/output/programs/boot_sequence.bin +++ b/output/programs/boot_sequence.bin @@ -1,16 +1,17 @@ -00000000 00000000 00000000 00111100 +01000000 00000000 00000000 00000000 00110100 00000010 00000000 00000000 -00000100 00000100 00010000 00000000 -00100100 00000010 00000000 00000000 -00110100 00000010 00010100 00000000 -00110100 00000010 00000100 00000001 -00110100 00000010 00001000 01000000 -00000100 00000100 00010000 00000100 -00100100 00000010 00001100 00100000 +00000100 00000100 00000010 00000000 +00100100 00000010 00000000 00000010 +01110011 00000010 00000000 00000010 +00110100 00000010 00000100 00000100 +00110100 00000010 00001000 11110000 +01110001 00000000 00000000 00000000 +00110101 00001011 01101100 00000000 +00000100 00000100 00000010 00000100 +00100100 00000010 00001100 00000010 01000100 00000110 00001000 00001100 01110000 00000010 00001000 00000100 01110000 00000010 00000100 00000100 -01110001 00000010 00000000 00000100 -01000001 00000000 00000000 00010100 -00110101 00001011 01000000 00000000 -00110101 00001001 10011000 00000000 +01110001 00000010 00000000 00000001 +00110101 00001001 01001000 00000000 +00110101 00001001 11110000 00000000 diff --git a/output/programs/boot_sequence_resolved.asm b/output/programs/boot_sequence_resolved.asm index 84b1fd5..3e3f7c3 100644 --- a/output/programs/boot_sequence_resolved.asm +++ b/output/programs/boot_sequence_resolved.asm @@ -1,16 +1,17 @@ -PROGRAM_ORG equ 128 -080: MOVC [0], 0 -084: OUT 16, [0] -088: IN [0], 0 -08c: MOVC [20], 0 -090: MOVC [4], 1 -094: MOVC [8], 64 -098: OUT 16, [4] -09c: IN [12], 32 -0a0: STORE [[8]], [12] -0a4: ADDC [8], 4 -0a8: ADDC [4], 4 -0ac: SUBC [0], 4 -0b0: CMP [0], [20] -0b4: JZ 64, 0 -0b8: JMP 152, 0 +PROGRAM_ORG equ 48 +030: MOVC [0], 0 +034: OUT 2, [0] +038: IN [0], 2 +03c: SHRC [0], 2 +040: MOVC [4], 4 +044: MOVC [8], 240 +048: CMPC [0], 0 +04c: JZ 108, 0 +050: OUT 2, [4] +054: IN [12], 2 +058: STORE [[8]], [12] +05c: ADDC [8], 4 +060: ADDC [4], 4 +064: SUBC [0], 1 +068: JMP 72, 0 +06c: JMP 240, 0 diff --git a/output/programs/ping_pong.bin b/output/programs/ping_pong.bin index 246aca5..804584c 100644 --- a/output/programs/ping_pong.bin +++ b/output/programs/ping_pong.bin @@ -1,8 +1,8 @@ -00000000 00000000 00000011 00110100 +00110100 00000011 00000000 00000000 00110100 00000010 00100000 11111111 01110010 00000010 00100000 00001000 01110111 00000010 00100000 11110000 -00110101 00001001 01110100 00000000 +00110101 00001001 10110100 00000000 00000010 00000000 00000000 00000000 00000010 00000000 00000000 00000000 00000111 00000000 00000000 00000000 @@ -15,91 +15,91 @@ 01110000 00000011 00101000 00010000 01110001 00000010 00100000 00000100 01000100 00000110 00100000 00101000 -00110101 00001001 01011100 00000001 +00110101 00001001 10011100 00000001 01110000 00000011 00101000 00010000 01110001 00000010 00100000 00000100 01000100 00000110 00100000 00101000 -00110101 00001001 11101100 00000000 +00110101 00001001 00101100 00000001 01110000 00000011 00101000 00010000 01110001 00000010 00100000 00000100 01000100 00000110 00100000 00101000 -00110101 00001001 00011100 00000010 -00110101 00001001 01110100 00000000 +00110101 00001001 01011100 00000010 +00110101 00001001 10110100 00000000 01110000 00000011 00101000 00010000 01110001 00000010 00100000 00000100 01000100 00000110 00100000 00101000 -00110101 00001001 11001100 00000000 +00110101 00001001 00001100 00000001 01110000 00000011 00101000 00010000 01110001 00000010 00100000 00000100 01000100 00000110 00100000 00101000 -00110101 00001001 01011100 00000001 -00110101 00001001 10101000 00000000 -01110001 00000000 01101100 00000000 -00110101 00001101 11011100 00000000 -01111000 00000010 01110000 00000001 -00110100 00000010 01101100 00000101 -01110001 00000010 01101100 00000001 +00110101 00001001 10011100 00000001 +00110101 00001001 11101000 00000000 +01110001 00000000 10101100 00000000 +00110101 00001101 00011100 00000001 +01111000 00000010 10110000 00000001 +00110100 00000010 10101100 00000101 +01110001 00000010 10101100 00000001 10000101 00000010 00101000 00100000 01110000 00000010 00100000 00000100 11110101 00001000 00101000 00000000 00100100 00000010 00000000 00000001 00110100 00000010 00000100 00000001 01000110 00000010 00000100 00000000 -00110101 00001011 00001000 00000001 -01110001 00000000 01010000 00000000 -00110101 00001011 00001000 00000001 -01110001 00000010 01010000 00000001 +00110101 00001011 01001000 00000001 +01110001 00000000 10010000 00000000 +00110101 00001011 01001000 00000001 +01110001 00000010 10010000 00000001 00110100 00000010 00000100 00000010 01000110 00000010 00000100 00000000 -00110101 00001011 00100000 00000001 -01110001 00000000 01010000 00000101 -00110101 00001011 00100000 00000001 -01110000 00000010 01010000 00000001 +00110101 00001011 01100000 00000001 +01110001 00000000 10010000 00000101 +00110101 00001011 01100000 00000001 +01110000 00000010 10010000 00000001 00110100 00000010 00000100 00000100 01000110 00000010 00000100 00000000 -00110101 00001011 00111000 00000001 -01110001 00000000 01010100 00000000 -00110101 00001011 00111000 00000001 -01110001 00000010 01010100 00000001 +00110101 00001011 01111000 00000001 +01110001 00000000 10010100 00000000 +00110101 00001011 01111000 00000001 +01110001 00000010 10010100 00000001 00110100 00000010 00000100 00001000 01000110 00000010 00000100 00000000 -00110101 00001011 01010000 00000001 -01110001 00000000 01010100 00000101 -00110101 00001011 01010000 00000001 -01110000 00000010 01010100 00000001 +00110101 00001011 10010000 00000001 +01110001 00000000 10010100 00000101 +00110101 00001011 10010000 00000001 +01110000 00000010 10010100 00000001 10000101 00000010 00101000 00100000 01110000 00000010 00100000 00000100 11110101 00001000 00101000 00000000 -01110001 00000000 01110000 00000000 -00110101 00001011 10111100 00000001 +01110001 00000000 10110000 00000000 +00110101 00001011 11111100 00000001 00110100 00000010 00000000 01111111 01110010 00000010 00000000 00001000 01111000 00000010 00000000 11111111 00110100 00000010 00000100 00000111 -01000010 00000010 00000100 01010000 +01000010 00000010 00000100 10010000 00000100 00000100 00000110 00000000 00000100 00000100 00000111 00000100 01110000 00000011 00101000 00010000 01110001 00000010 00100000 00000100 01000100 00000110 00100000 00101000 -00110101 00001001 00000000 00000010 +00110101 00001001 01000000 00000010 00110100 00000010 00000000 11111111 01110010 00000010 00000000 00001000 01111000 00000010 00000000 11111110 00110100 00000010 00000100 00000111 -01000010 00000010 00000100 01010100 +01000010 00000010 00000100 10010100 00000100 00000100 00000110 00000000 00000100 00000100 00000111 00000100 01110000 00000011 00101000 00010000 01110001 00000010 00100000 00000100 01000100 00000110 00100000 00101000 -00110101 00001001 00000000 00000010 -00000100 00000010 00000000 01011000 +00110101 00001001 01000000 00000010 +00000100 00000010 00000000 10011000 00110100 00000010 00000100 10000000 01110010 00000010 00000100 00001000 01000011 00000010 00000100 00000000 -01001000 00000010 00000100 01100000 -00000100 00000010 00000000 01011100 +01001000 00000010 00000100 10100000 +00000100 00000010 00000000 10011100 00110100 00000010 00001000 00000001 01000010 00000010 00001000 00000000 00000100 00000100 00000110 00000100 @@ -107,100 +107,100 @@ 01110000 00000011 00101000 00010000 01110001 00000010 00100000 00000100 01000100 00000110 00100000 00101000 -00110101 00001001 00000000 00000010 +00110101 00001001 01000000 00000010 10000101 00000010 00101000 00100000 01110000 00000010 00100000 00000100 11110101 00001000 00101000 00000000 00110100 00000010 00000000 11110000 01110010 00000010 00000000 00000001 01110001 00000010 00000000 00000001 -00110101 00001101 00001000 00000010 +00110101 00001101 01001000 00000010 10000101 00000010 00101000 00100000 01110000 00000010 00100000 00000100 11110101 00001000 00101000 00000000 -01110001 00000000 01100100 00000000 -00110101 00001101 00111000 00000010 -00110100 00000010 01100100 00000010 +01110001 00000000 10100100 00000000 +00110101 00001101 01111000 00000010 +00110100 00000010 10100100 00000010 01110000 00000011 00101000 00010000 01110001 00000010 00100000 00000100 01000100 00000110 00100000 00101000 -00110101 00001001 01001000 00000010 -01110001 00000010 01100100 00000001 +00110101 00001001 10001000 00000010 +01110001 00000010 10100100 00000001 10000101 00000010 00101000 00100000 01110000 00000010 00100000 00000100 11110101 00001000 00101000 00000000 -01110001 00000000 01011000 00001110 -00110101 00001011 10101100 00000010 -01110001 00000000 01011000 00000001 -00110101 00001011 11010000 00000010 -01110001 00000000 01011100 00000111 -00110101 00001011 01100000 00000011 -01110001 00000000 01011100 00000000 -00110101 00001011 01100000 00000011 -00000100 00000010 00000000 01101000 +01110001 00000000 10011000 00001110 +00110101 00001011 11101100 00000010 +01110001 00000000 10011000 00000001 +00110101 00001011 00010000 00000011 +01110001 00000000 10011100 00000111 +00110101 00001011 10100000 00000011 +01110001 00000000 10011100 00000000 +00110101 00001011 10100000 00000011 +00000100 00000010 00000000 10101000 01110110 00000010 00000000 00000001 -00110101 00001011 01111100 00000010 -01110000 00000010 01011000 00000001 -00110101 00001001 10000000 00000010 -01110001 00000010 01011000 00000001 -00000100 00000010 00000000 01101000 +00110101 00001011 10111100 00000010 +01110000 00000010 10011000 00000001 +00110101 00001001 11000000 00000010 +01110001 00000010 10011000 00000001 +00000100 00000010 00000000 10101000 01110110 00000010 00000000 00000100 -00110101 00001011 10010000 00000010 -01110001 00000010 01011100 00000001 -00000100 00000010 00000000 01101000 +00110101 00001011 11010000 00000010 +01110001 00000010 10011100 00000001 +00000100 00000010 00000000 10101000 01110110 00000010 00000000 00001000 -00110101 00001011 10100000 00000010 -01110000 00000010 01011100 00000001 +00110101 00001011 11100000 00000010 +01110000 00000010 10011100 00000001 10000101 00000010 00101000 00100000 01110000 00000010 00100000 00000100 11110101 00001000 00101000 00000000 01110001 00000010 00100000 00000100 -01000100 00000110 00100000 01010100 +01000100 00000110 00100000 10010100 01110000 00000011 00101000 00010000 01110001 00000010 00100000 00000100 01000100 00000110 00100000 00101000 -00110101 00001001 11110100 00000010 +00110101 00001001 00110100 00000011 10000101 00000010 00011100 00100000 01110000 00000010 00100000 00000100 -00110101 00001001 01011000 00000010 +00110101 00001001 10011000 00000010 01110001 00000010 00100000 00000100 -01000100 00000110 00100000 01010000 +01000100 00000110 00100000 10010000 01110000 00000011 00101000 00010000 01110001 00000010 00100000 00000100 01000100 00000110 00100000 00101000 -00110101 00001001 11110100 00000010 +00110101 00001001 00110100 00000011 10000101 00000010 00011100 00100000 01110000 00000010 00100000 00000100 -00110101 00001001 01011000 00000010 +00110101 00001001 10011000 00000010 00000100 00000010 00100100 00100000 01110000 00000010 00100100 00000100 10000101 00000010 00000100 00100100 -01111000 00000010 01101000 00000011 +01111000 00000010 10101000 00000011 00110100 00000010 00000000 00001100 01111000 00000010 00000000 11111111 -01000110 00000010 01101000 00000000 -01000001 00000000 01011100 00000100 -00110101 00001011 00110100 00000011 +01000110 00000010 10101000 00000000 +01000001 00000000 10011100 00000100 +00110101 00001011 01110100 00000011 01110000 00000010 00000100 00000001 -01000001 00000000 01011100 00000100 -00110101 00001011 01010100 00000011 +01000001 00000000 10011100 00000100 +00110101 00001011 10010100 00000011 01110000 00000010 00000100 00000001 -01000001 00000000 01011100 00000100 -00110101 00001011 01000100 00000011 -00110101 00001001 10101000 00000000 -01110111 00000010 01101000 00000100 +01000001 00000000 10011100 00000100 +00110101 00001011 10000100 00000011 +00110101 00001001 11101000 00000000 +01110111 00000010 10101000 00000100 10000101 00000010 00101000 00100000 01110000 00000010 00100000 00000100 11110101 00001000 00101000 00000000 -01110111 00000010 01101000 00001000 +01110111 00000010 10101000 00001000 10000101 00000010 00101000 00100000 01110000 00000010 00100000 00000100 11110101 00001000 00101000 00000000 10000101 00000010 00101000 00100000 01110000 00000010 00100000 00000100 11110101 00001000 00101000 00000000 -00000100 00000010 00000000 01101000 +00000100 00000010 00000000 10101000 01110110 00000010 00000000 00001100 -00110101 00001011 01101000 00000010 -01111000 00000010 01101000 00001100 -00110101 00001001 01101000 00000010 +00110101 00001011 10101000 00000010 +01111000 00000010 10101000 00001100 +00110101 00001001 10101000 00000010 diff --git a/output/programs/ping_pong_resolved.asm b/output/programs/ping_pong_resolved.asm index 4273b54..4354d0e 100644 --- a/output/programs/ping_pong_resolved.asm +++ b/output/programs/ping_pong_resolved.asm @@ -1,233 +1,233 @@ -PROGRAM_ORG equ 64 -040: MOVC [32], 255 -044: SHLC [32], 8 -048: ORC [32], 240 -04c: JMP 116, 0 -050: 02 -051: 00 -052: 00 -053: 00 -054: 02 -055: 00 -056: 00 -057: 00 -058: 07 -059: 00 -05a: 00 -05b: 00 -05c: 02 -05d: 00 -05e: 00 -05f: 00 -060: 255 -061: 255 -062: 00 -063: 00 -064: 00 -065: 00 -066: 00 -067: 00 -068: 06 -069: 00 -06a: 00 -06b: 00 -06c: 00 -06d: 00 -06e: 00 -06f: 00 -070: 01 -071: 00 -072: 00 -073: 00 -074: PCPLUS [40], 16 -078: SUBC [32], 4 -07c: STORE [[32]], [40] -080: JMP 92, 1 -084: PCPLUS [40], 16 -088: SUBC [32], 4 -08c: STORE [[32]], [40] -090: JMP 236, 0 -094: PCPLUS [40], 16 -098: SUBC [32], 4 -09c: STORE [[32]], [40] -0a0: JMP 28, 2 -0a4: JMP 116, 0 -0a8: PCPLUS [40], 16 -0ac: SUBC [32], 4 -0b0: STORE [[32]], [40] -0b4: JMP 204, 0 -0b8: PCPLUS [40], 16 -0bc: SUBC [32], 4 -0c0: STORE [[32]], [40] -0c4: JMP 92, 1 -0c8: JMP 168, 0 -0cc: CMPC [108], 0 -0d0: JNZ 220, 0 -0d4: XORC [112], 1 -0d8: MOVC [108], 5 -0dc: SUBC [108], 1 -0e0: LOAD [40], [[32]] -0e4: ADDC [32], 4 -0e8: JMPM [40], [0] -0ec: IN [0], 1 -0f0: MOVC [4], 1 -0f4: AND [4], [0] -0f8: JZ 8, 1 -0fc: CMPC [80], 0 -100: JZ 8, 1 -104: SUBC [80], 1 -108: MOVC [4], 2 -10c: AND [4], [0] -110: JZ 32, 1 -114: CMPC [80], 5 -118: JZ 32, 1 -11c: ADDC [80], 1 -120: MOVC [4], 4 -124: AND [4], [0] -128: JZ 56, 1 -12c: CMPC [84], 0 -130: JZ 56, 1 -134: SUBC [84], 1 -138: MOVC [4], 8 -13c: AND [4], [0] -140: JZ 80, 1 -144: CMPC [84], 5 -148: JZ 80, 1 -14c: ADDC [84], 1 -150: LOAD [40], [[32]] -154: ADDC [32], 4 -158: JMPM [40], [0] -15c: CMPC [112], 0 -160: JZ 188, 1 -164: MOVC [0], 127 -168: SHLC [0], 8 -16c: XORC [0], 255 -170: MOVC [4], 7 -174: SHL [4], [80] -178: OUT 6, [0] -17c: OUT 7, [4] -180: PCPLUS [40], 16 -184: SUBC [32], 4 -188: STORE [[32]], [40] -18c: JMP 0, 2 -190: MOVC [0], 255 -194: SHLC [0], 8 -198: XORC [0], 254 -19c: MOVC [4], 7 -1a0: SHL [4], [84] -1a4: OUT 6, [0] -1a8: OUT 7, [4] -1ac: PCPLUS [40], 16 -1b0: SUBC [32], 4 -1b4: STORE [[32]], [40] -1b8: JMP 0, 2 -1bc: MOV [0], [88] -1c0: MOVC [4], 128 -1c4: SHLC [4], 8 -1c8: SHR [4], [0] -1cc: XOR [4], [96] -1d0: MOV [0], [92] -1d4: MOVC [8], 1 -1d8: SHL [8], [0] -1dc: OUT 6, [4] -1e0: OUT 7, [8] -1e4: PCPLUS [40], 16 -1e8: SUBC [32], 4 -1ec: STORE [[32]], [40] -1f0: JMP 0, 2 -1f4: LOAD [40], [[32]] -1f8: ADDC [32], 4 -1fc: JMPM [40], [0] -200: MOVC [0], 240 -204: SHLC [0], 1 -208: SUBC [0], 1 -20c: JNZ 8, 2 -210: LOAD [40], [[32]] -214: ADDC [32], 4 -218: JMPM [40], [0] -21c: CMPC [100], 0 -220: JNZ 56, 2 -224: MOVC [100], 2 -228: PCPLUS [40], 16 -22c: SUBC [32], 4 -230: STORE [[32]], [40] -234: JMP 72, 2 -238: SUBC [100], 1 -23c: LOAD [40], [[32]] -240: ADDC [32], 4 -244: JMPM [40], [0] -248: CMPC [88], 14 -24c: JZ 172, 2 -250: CMPC [88], 1 -254: JZ 208, 2 -258: CMPC [92], 7 -25c: JZ 96, 3 -260: CMPC [92], 0 -264: JZ 96, 3 -268: MOV [0], [104] -26c: ANDC [0], 1 -270: JZ 124, 2 -274: ADDC [88], 1 -278: JMP 128, 2 -27c: SUBC [88], 1 -280: MOV [0], [104] -284: ANDC [0], 4 -288: JZ 144, 2 -28c: SUBC [92], 1 -290: MOV [0], [104] -294: ANDC [0], 8 -298: JZ 160, 2 -29c: ADDC [92], 1 -2a0: LOAD [40], [[32]] -2a4: ADDC [32], 4 -2a8: JMPM [40], [0] -2ac: SUBC [32], 4 -2b0: STORE [[32]], [84] -2b4: PCPLUS [40], 16 -2b8: SUBC [32], 4 -2bc: STORE [[32]], [40] -2c0: JMP 244, 2 -2c4: LOAD [28], [[32]] -2c8: ADDC [32], 4 -2cc: JMP 88, 2 -2d0: SUBC [32], 4 -2d4: STORE [[32]], [80] -2d8: PCPLUS [40], 16 -2dc: SUBC [32], 4 -2e0: STORE [[32]], [40] -2e4: JMP 244, 2 -2e8: LOAD [28], [[32]] -2ec: ADDC [32], 4 -2f0: JMP 88, 2 -2f4: MOV [36], [32] -2f8: ADDC [36], 4 -2fc: LOAD [4], [[36]] -300: XORC [104], 3 -304: MOVC [0], 12 -308: XORC [0], 255 -30c: AND [104], [0] -310: CMP [92], [4] -314: JZ 52, 3 -318: ADDC [4], 1 -31c: CMP [92], [4] -320: JZ 84, 3 -324: ADDC [4], 1 -328: CMP [92], [4] -32c: JZ 68, 3 -330: JMP 168, 0 -334: ORC [104], 4 -338: LOAD [40], [[32]] -33c: ADDC [32], 4 -340: JMPM [40], [0] -344: ORC [104], 8 -348: LOAD [40], [[32]] -34c: ADDC [32], 4 -350: JMPM [40], [0] -354: LOAD [40], [[32]] -358: ADDC [32], 4 -35c: JMPM [40], [0] -360: MOV [0], [104] -364: ANDC [0], 12 -368: JZ 104, 2 -36c: XORC [104], 12 -370: JMP 104, 2 +PROGRAM_ORG equ 128 +080: MOVC [32], 255 +084: SHLC [32], 8 +088: ORC [32], 240 +08c: JMP 180, 0 +090: 02 +091: 00 +092: 00 +093: 00 +094: 02 +095: 00 +096: 00 +097: 00 +098: 07 +099: 00 +09a: 00 +09b: 00 +09c: 02 +09d: 00 +09e: 00 +09f: 00 +0a0: 255 +0a1: 255 +0a2: 00 +0a3: 00 +0a4: 00 +0a5: 00 +0a6: 00 +0a7: 00 +0a8: 06 +0a9: 00 +0aa: 00 +0ab: 00 +0ac: 00 +0ad: 00 +0ae: 00 +0af: 00 +0b0: 01 +0b1: 00 +0b2: 00 +0b3: 00 +0b4: PCPLUS [40], 16 +0b8: SUBC [32], 4 +0bc: STORE [[32]], [40] +0c0: JMP 156, 1 +0c4: PCPLUS [40], 16 +0c8: SUBC [32], 4 +0cc: STORE [[32]], [40] +0d0: JMP 44, 1 +0d4: PCPLUS [40], 16 +0d8: SUBC [32], 4 +0dc: STORE [[32]], [40] +0e0: JMP 92, 2 +0e4: JMP 180, 0 +0e8: PCPLUS [40], 16 +0ec: SUBC [32], 4 +0f0: STORE [[32]], [40] +0f4: JMP 12, 1 +0f8: PCPLUS [40], 16 +0fc: SUBC [32], 4 +100: STORE [[32]], [40] +104: JMP 156, 1 +108: JMP 232, 0 +10c: CMPC [172], 0 +110: JNZ 28, 1 +114: XORC [176], 1 +118: MOVC [172], 5 +11c: SUBC [172], 1 +120: LOAD [40], [[32]] +124: ADDC [32], 4 +128: JMPM [40], [0] +12c: IN [0], 1 +130: MOVC [4], 1 +134: AND [4], [0] +138: JZ 72, 1 +13c: CMPC [144], 0 +140: JZ 72, 1 +144: SUBC [144], 1 +148: MOVC [4], 2 +14c: AND [4], [0] +150: JZ 96, 1 +154: CMPC [144], 5 +158: JZ 96, 1 +15c: ADDC [144], 1 +160: MOVC [4], 4 +164: AND [4], [0] +168: JZ 120, 1 +16c: CMPC [148], 0 +170: JZ 120, 1 +174: SUBC [148], 1 +178: MOVC [4], 8 +17c: AND [4], [0] +180: JZ 144, 1 +184: CMPC [148], 5 +188: JZ 144, 1 +18c: ADDC [148], 1 +190: LOAD [40], [[32]] +194: ADDC [32], 4 +198: JMPM [40], [0] +19c: CMPC [176], 0 +1a0: JZ 252, 1 +1a4: MOVC [0], 127 +1a8: SHLC [0], 8 +1ac: XORC [0], 255 +1b0: MOVC [4], 7 +1b4: SHL [4], [144] +1b8: OUT 6, [0] +1bc: OUT 7, [4] +1c0: PCPLUS [40], 16 +1c4: SUBC [32], 4 +1c8: STORE [[32]], [40] +1cc: JMP 64, 2 +1d0: MOVC [0], 255 +1d4: SHLC [0], 8 +1d8: XORC [0], 254 +1dc: MOVC [4], 7 +1e0: SHL [4], [148] +1e4: OUT 6, [0] +1e8: OUT 7, [4] +1ec: PCPLUS [40], 16 +1f0: SUBC [32], 4 +1f4: STORE [[32]], [40] +1f8: JMP 64, 2 +1fc: MOV [0], [152] +200: MOVC [4], 128 +204: SHLC [4], 8 +208: SHR [4], [0] +20c: XOR [4], [160] +210: MOV [0], [156] +214: MOVC [8], 1 +218: SHL [8], [0] +21c: OUT 6, [4] +220: OUT 7, [8] +224: PCPLUS [40], 16 +228: SUBC [32], 4 +22c: STORE [[32]], [40] +230: JMP 64, 2 +234: LOAD [40], [[32]] +238: ADDC [32], 4 +23c: JMPM [40], [0] +240: MOVC [0], 240 +244: SHLC [0], 1 +248: SUBC [0], 1 +24c: JNZ 72, 2 +250: LOAD [40], [[32]] +254: ADDC [32], 4 +258: JMPM [40], [0] +25c: CMPC [164], 0 +260: JNZ 120, 2 +264: MOVC [164], 2 +268: PCPLUS [40], 16 +26c: SUBC [32], 4 +270: STORE [[32]], [40] +274: JMP 136, 2 +278: SUBC [164], 1 +27c: LOAD [40], [[32]] +280: ADDC [32], 4 +284: JMPM [40], [0] +288: CMPC [152], 14 +28c: JZ 236, 2 +290: CMPC [152], 1 +294: JZ 16, 3 +298: CMPC [156], 7 +29c: JZ 160, 3 +2a0: CMPC [156], 0 +2a4: JZ 160, 3 +2a8: MOV [0], [168] +2ac: ANDC [0], 1 +2b0: JZ 188, 2 +2b4: ADDC [152], 1 +2b8: JMP 192, 2 +2bc: SUBC [152], 1 +2c0: MOV [0], [168] +2c4: ANDC [0], 4 +2c8: JZ 208, 2 +2cc: SUBC [156], 1 +2d0: MOV [0], [168] +2d4: ANDC [0], 8 +2d8: JZ 224, 2 +2dc: ADDC [156], 1 +2e0: LOAD [40], [[32]] +2e4: ADDC [32], 4 +2e8: JMPM [40], [0] +2ec: SUBC [32], 4 +2f0: STORE [[32]], [148] +2f4: PCPLUS [40], 16 +2f8: SUBC [32], 4 +2fc: STORE [[32]], [40] +300: JMP 52, 3 +304: LOAD [28], [[32]] +308: ADDC [32], 4 +30c: JMP 152, 2 +310: SUBC [32], 4 +314: STORE [[32]], [144] +318: PCPLUS [40], 16 +31c: SUBC [32], 4 +320: STORE [[32]], [40] +324: JMP 52, 3 +328: LOAD [28], [[32]] +32c: ADDC [32], 4 +330: JMP 152, 2 +334: MOV [36], [32] +338: ADDC [36], 4 +33c: LOAD [4], [[36]] +340: XORC [168], 3 +344: MOVC [0], 12 +348: XORC [0], 255 +34c: AND [168], [0] +350: CMP [156], [4] +354: JZ 116, 3 +358: ADDC [4], 1 +35c: CMP [156], [4] +360: JZ 148, 3 +364: ADDC [4], 1 +368: CMP [156], [4] +36c: JZ 132, 3 +370: JMP 232, 0 +374: ORC [168], 4 +378: LOAD [40], [[32]] +37c: ADDC [32], 4 +380: JMPM [40], [0] +384: ORC [168], 8 +388: LOAD [40], [[32]] +38c: ADDC [32], 4 +390: JMPM [40], [0] +394: LOAD [40], [[32]] +398: ADDC [32], 4 +39c: JMPM [40], [0] +3a0: MOV [0], [168] +3a4: ANDC [0], 12 +3a8: JZ 168, 2 +3ac: XORC [168], 12 +3b0: JMP 168, 2 diff --git a/planner/asm/program_parser.py b/planner/asm/program_parser.py index 54af788..905cd43 100644 --- a/planner/asm/program_parser.py +++ b/planner/asm/program_parser.py @@ -82,7 +82,7 @@ def get_str(self, resolved=False, rom_binary=False): assert len(_program_content) % 8 == 0 _program_size = len(_program_content) // 8 # bytes assert _program_size < 2**32 # as we are using 4 bytes for metadata - _binary_content = f"{_program_size:032b}" + _program_content + _binary_content = util.to_little_32binary(_program_size) + _program_content assert len(_binary_content) % 8 == 0 assert set(_binary_content) <= set(['0', '1']), "only binary context is expected" diff --git a/planner/memory.py b/planner/memory.py index 1366dff..25a1a05 100644 --- a/planner/memory.py +++ b/planner/memory.py @@ -16,6 +16,9 @@ def get_register_address(index): # free +# boot sequence +BOOTSEQUENCE_ORG = 0x30 + # user program -DEFAULT_PROGRAM_ORG = 0x40 +DEFAULT_PROGRAM_ORG = 0x80 diff --git a/planner/sim/bin_parser.py b/planner/sim/bin_parser.py index eb797f9..a4de469 100644 --- a/planner/sim/bin_parser.py +++ b/planner/sim/bin_parser.py @@ -2,10 +2,9 @@ import logging from typing import List, Optional -from planner import instruction, memory +from planner import instruction, memory, util from planner.sim import devices -PROGRAM_ORG = memory.DEFAULT_PROGRAM_ORG IO_DEVICES = 16 RAM_SIZE = 0x10000 # 64KB @@ -15,15 +14,15 @@ def binary_array_num(arr: List[int]): FLAGS_BIT_VW_ZERO = 0 class BinRunner: - def __init__(self, content): + def __init__(self, bootsequence_binary): self.ram = [] self.input_devices = [None]*IO_DEVICES self.output_devices = [None]*IO_DEVICES for _ in range(RAM_SIZE): self.ram.append(random.randint(0, 256)) - self.parse(content) - self.pc_next = PROGRAM_ORG + self.parse_bs(bootsequence_binary) + self.pc_next = memory.BOOTSEQUENCE_ORG self.pc = None # self.is_powered_on = False # self.step() @@ -37,16 +36,17 @@ def set_input_device(self, index: int, d: devices.InputDevice): def set_output_device(self, index: int, d: devices.Device): self.output_devices[index] = d - def parse(self, content: str): - content = content.replace(" ", "").replace("\n", "") + def parse_bs(self, bootsequence_binary: str): + content = bootsequence_binary.replace(" ", "").replace("\n", "") assert len(content)%8 == 0 assert set(content) <= set(['0', '1']) - program_size = int(content[:32], 2) + program_size = util.from_little_32binary(content[:32]) assert program_size*8+32 == len(content) - address = PROGRAM_ORG + address = memory.BOOTSEQUENCE_ORG for i in range(4, len(content)//8): self.ram[address] = (int(content[i*8:(i+1)*8], 2)) address += 1 + assert address <= memory.DEFAULT_PROGRAM_ORG def read_ram(self, addr: int, count: int) -> List[int]: ans = [] @@ -84,7 +84,7 @@ def m_fetch_and_store_stage1( # resize from 1 to 4 bytes return vr_source if sel == instruction.MBlockSelector_stage1.VR_SOURCE_IO: - value = input_devices[vr_source].take_input() + value = input_devices[vr_source].get() assert value >= 0 and value < (1<<32) return value raise Exception(f"unsupported selector: {sel}") diff --git a/planner/sim/devices.py b/planner/sim/devices.py index 93efc4d..7ddc131 100644 --- a/planner/sim/devices.py +++ b/planner/sim/devices.py @@ -1,4 +1,5 @@ -from typing import List +from planner import util +from typing import List, Optional import logging from threading import Thread from copy import deepcopy @@ -54,10 +55,6 @@ class InputDevice(Device): def __init__(self, *args, **kwargs): super(InputDevice, self).__init__(*args, **kwargs) - def take_input(self): - # empty device - pass - class LatchInput(InputDevice): def __init__(self, name: str, **kwargs): @@ -68,9 +65,9 @@ def __init__(self, name: str, **kwargs): def set_input(self, value: int): self.update(value) - def take_input(self): + def get(self): # print(f"Input for Latch[{self.name}]: ", end="") - return self.get() + return super().get() class Numpad(InputDevice): @@ -80,12 +77,12 @@ def __init__(self, name: str): self.name = name self.update(0) - def take_input(self): + def get(self): print(f"Input for Numpad[{self.name}]: ", end="") val = int(input()) assert val >= 0 and val <= 9 self.flip_bit(val) - return self.get() + return super().get() class IntegerOutput(Device): @@ -98,8 +95,7 @@ def _on_change(new_val, old_val): self.add_change_handler(_on_change) def on_change(self, new_val, old_val): - print(f"Output [{self.name}]: {new_val}") - + pass class LEDDisplay(Device): ''' @@ -111,7 +107,7 @@ class LEDDisplay(Device): +----------------+ ''' - def __init__(self, name: str, width_anode=16, height_cathode=8): + def __init__(self, name: str, use_print: Optional[bool] = True, width_anode=16, height_cathode=8): # Assume cathode (+ve) is at height # Assume anode (-ve) is at width @@ -126,6 +122,7 @@ def __init__(self, name: str, width_anode=16, height_cathode=8): self.leds_voltage_diff = [] self.anodes = [IntegerOutput("anode", bits=self.width)] self.cathodes = [IntegerOutput("cathode", bits=self.height)] + self.use_print = use_print self.led_brightness_threshold = 0.1 # led should be on for 0.02 secs to stay on self.led_brightness_recompute_lag = 0.01 # secs @@ -217,4 +214,30 @@ def display(self, only_if_changed=True): if only_if_changed and new_display == self.last_display: return self.last_display = new_display - print(new_display) + if self.use_print: + print(new_display) + + +class ProgramROM(object): + def __init__(self, name: str, content: str, **kwargs): + #super(ProgramROM, self).__init__(**kwargs, bits= 0) + self.name = name + self.content = self.parse(content) + self.address_bits = 16 + self.value_bits = 32 + self.address_line = IntegerOutput("address", bits=self.address_bits) + self.value_line = LatchInput("value", bits=self.value_bits) + def _on_change(_, __): + address = self.address_line.get() + value=util.from_little_32binary(self.content[address*8:address*8+32]) + self.value_line.update(value) + _on_change(self.address_line.get(), None) + self.address_line.add_change_handler(_on_change) + + def parse(self, content: str): + content = content.replace(" ", "").replace("\n", "") + assert len(content)%8 == 0 + assert set(content) <= set(['0', '1']) + program_size = util.from_little_32binary(content[:32]) + assert program_size*8+32 == len(content) + return content diff --git a/planner/sim/programs/ping_pong.py b/planner/sim/programs/ping_pong.py index 97b8a1a..d87c1f8 100644 --- a/planner/sim/programs/ping_pong.py +++ b/planner/sim/programs/ping_pong.py @@ -3,21 +3,30 @@ from threading import Thread import pygame +BOOTSEQUENCE_PATH = "programs/boot_sequence.asm" PROGRAM_PATH = "programs/ping_pong.asm" def step_runner(_bin): while True: _bin.step() -def start(): +def get_asm_binary(fname: str): asm = program_parser.AsmParser() - with open(PROGRAM_PATH, "r") as f: + with open(fname, "r") as f: asm.parse_lines(f.readlines()) - program_binary = asm.get_str(resolved=True, rom_binary=True) + return asm.get_str(resolved=True, rom_binary=True) + + +def start(): + bsrom_binary = get_asm_binary(BOOTSEQUENCE_PATH) + program_binary = get_asm_binary(PROGRAM_PATH) - _bin = bin_parser.BinRunner(program_binary) + _bin = bin_parser.BinRunner(bsrom_binary) gui_manager = gui_devices.GUIDeviceManager() + prom = devices.ProgramROM("prom", program_binary) + _bin.set_output_device(2, prom.address_line) + _bin.set_input_device(2, prom.value_line) input = devices.LatchInput("input", bits=4) gui_manager.add_device((0, 0), gui_devices.KeyPressedInput(input, { @@ -29,7 +38,7 @@ def start(): _bin.set_input_device(1, input) - display = devices.LEDDisplay("LED", width_anode=16, height_cathode=8) + display = devices.LEDDisplay("LED", use_print=False, width_anode=16, height_cathode=8) gui_manager.add_device((0, 0), gui_devices.GUILed(display)) _bin.set_output_device(6, display.get_anodes()[0]) _bin.set_output_device(7, display.get_cathodes()[0]) diff --git a/planner/util.py b/planner/util.py index a485688..5696997 100644 --- a/planner/util.py +++ b/planner/util.py @@ -13,3 +13,14 @@ def is_valid_label(msg): if msg in ["section", "data", "bss"]: return False return set(msg) <= set(string.ascii_uppercase + string.ascii_lowercase + string.digits + "_") + +def to_big_32binary(val): + return f"{val:032b}" + +def to_little_32binary(val): + big = to_big_32binary(val) + return ''.join([big[i*8:(i+1)*8] for i in range(4)[::-1]]) + +def from_little_32binary(little): + assert len(little) == 32 + return sum([int(little[i*8:(i+1)*8],2)<<(8*i) for i in range(4)]) diff --git a/programs/boot_sequence.asm b/programs/boot_sequence.asm index 2e5ba79..14de9af 100644 --- a/programs/boot_sequence.asm +++ b/programs/boot_sequence.asm @@ -1,15 +1,14 @@ -# TODO: This is not ready yet # Program # ROM[BootSequence] +# Small program to copy PROM[1+i] to RAM[org+i] # -# Input devices required at 0x0 -# * address -# Output devices -# * PROGRAM_ROM[address] at 0x0 -# Really small program to copy ROM[Program] to RAM[Program] +# output(2) = PROGRAM_ROM address line +PROM_ADDRESS_LINE equ 2 +# input(2) = PROGRAM_ROM value +PROM_VALUE_LINE equ 2 -PROGRAM_ORG equ 0x80 -PROGRAM_DEST equ 0x40 +PROGRAM_ORG equ 0x30 +RAM_PROGRAM_ORG equ 0x80 ROM_INPUT_VALUE equ 0x0 ROM_OUTPUT_ADDRESS equ 0x0 @@ -19,24 +18,22 @@ section .text # read metadata: program size # assume size mod 4 = 0 movc R0, 0 - out 0x10, R0 - in R0, ROM_INPUT_VALUE - movc R5, 0 - - movc R1, 1 - movc R2, PROGRAM_DEST - _copy_more: - out 0x10, R1 - in R3, 0x20 + out PROM_ADDRESS_LINE, R0 + in R0, PROM_VALUE_LINE + shrc R0, 2 + + movc R1, 4 + movc R2, RAM_PROGRAM_ORG + copy_more: + cmpc R0, 0 + jz copy_completed + out PROM_ADDRESS_LINE, R1 + in R3, PROM_VALUE_LINE store [R2], R3 - addc R2, 4 - addc R1, 4 - subc R0, 4 - - cmp R0, R5 - - # jmp to program if copy is completed - jz PROGRAM_DEST - - jmp _copy_more + addc R2, 4 + addc R1, 4 + subc R0, 1 + jmp copy_more + copy_completed: + jmp RAM_PROGRAM_ORG diff --git a/programs/ping_pong.asm b/programs/ping_pong.asm index b53257c..b572a27 100644 --- a/programs/ping_pong.asm +++ b/programs/ping_pong.asm @@ -2,8 +2,7 @@ # Two Player Ping Pong Game # # Controls -# Up/Down button for each player -# Game Reset button +# W/S/Up/Down keyys to move bat # Display (16*8) # # X @@ -13,25 +12,21 @@ # X # # -# Chip -# H/W: 4+1 buttons, 2 8x8 LED matrix -# OUT[0..7] = LED Matrix Row -# OUT[8..15] = LED Matrix 1 Col -# OUT[16..23] = LED Matrix 2 Col -# Input(1) = Numpad(0-7) -# Input(2) = Numpad(0-9) -# Output(6) = LED(width=16, low_is_enabled) -# Output(7) = LED(height=8, high_is_enabled) +# input(1) = Keyboard({"W": 0, "S": 1, "UP": 2, "DOWN": 3}) +INPUT_DEVICE equ 1 + +# display = LEDDisplay("LED", width_anode=16, height_cathode=8) +# output(6) = display.get_anodes()[0] +# Output(7) = display.get_cathodes()[0] +OUTPUT_WIDTH equ 6 +OUTPUT_HEGHT equ 7 -PROGRAM_ORG equ 0x40 +PROGRAM_ORG equ 0x80 BAT_H equ 3 BAT_MAXY equ 5 -OUTPUT_WIDTH equ 6 -OUTPUT_HEGHT equ 7 -INPUT_DEVICE equ 1 BALL_STEP_SIZE equ 2 GAME_OVER_BLINK_STEP equ 5 From 69a5330c329609a0467df0eceb34d08ee544c0a4 Mon Sep 17 00:00:00 2001 From: Gagan Kumar Date: Mon, 16 Dec 2024 23:01:51 -0800 Subject: [PATCH 2/5] Fine tune LED Matrix --- planner/sim/devices.py | 29 ++++++++++++------------ programs/ping_pong.asm | 50 +++++++++++++++++++++--------------------- 2 files changed, 39 insertions(+), 40 deletions(-) diff --git a/planner/sim/devices.py b/planner/sim/devices.py index 7ddc131..a855c68 100644 --- a/planner/sim/devices.py +++ b/planner/sim/devices.py @@ -119,18 +119,14 @@ def __init__(self, name: str, use_print: Optional[bool] = True, width_anode=16, assert self.width <= 32 assert self.height <= 32 self.leds = [] - self.leds_voltage_diff = [] + for _ in range(self.height): + self.leds.append([0]*self.width) self.anodes = [IntegerOutput("anode", bits=self.width)] self.cathodes = [IntegerOutput("cathode", bits=self.height)] self.use_print = use_print - self.led_brightness_threshold = 0.1 - # led should be on for 0.02 secs to stay on - self.led_brightness_recompute_lag = 0.01 # secs - # led will stay on for 0.1 secs - self.led_brightness_reduce_per_step = 0.1 - for _ in range(self.height): - self.leds.append([0]*self.width) - self.leds_voltage_diff.append([0]*self.width) + self.led_glow_duration = 0.05 # secs + self.led_brightness_recompute_lag = self.led_glow_duration/4 # secs/step + self.led_brightness_reduce_per_step = self.led_brightness_recompute_lag/self.led_glow_duration for i in range(len(self.cathodes)): def _on_change(new_val, old_val): @@ -169,31 +165,34 @@ def output_val_to_voltage(self, index: int, val): return 5 if (val&(1<0 else 0 def refetch_voltage(self): + leds_voltage_diff = [] + for _ in range(self.height): + leds_voltage_diff.append([0]*self.width) _i = 0 for i in range(len(self.cathodes)): for i2 in range(self.cathodes[i].get_bit_count()): _j = 0 for j in range(len(self.anodes)): for j2 in range(self.anodes[j].get_bit_count()): - self.leds_voltage_diff[_i][_j] = ( + leds_voltage_diff = ( self.output_val_to_voltage(i2, self.cathodes[i].get()) - self.output_val_to_voltage(j2, self.anodes[j].get()) ) + if leds_voltage_diff > 3: + # start glowing + self.leds[_i][_j] = 1 _j += 1 _i += 1 def recompute_brightness_step(self): for i in range(self.height): for j in range(self.width): - if self.leds_voltage_diff[i][j] > 3: - self.leds[i][j]=1 - else: - self.leds[i][j]=max(self.leds[i][j]-self.led_brightness_reduce_per_step, 0) + self.leds[i][j]=max(self.leds[i][j]-self.led_brightness_reduce_per_step, 0) def get_display_state(self): state = [] for i in range(self.height): - val = [x>self.led_brightness_threshold for x in self.leds[i]] + val = [x>0 for x in self.leds[i]] val = val[::-1] # lsb should support right most led state.append(val) return state diff --git a/programs/ping_pong.asm b/programs/ping_pong.asm index b572a27..1269cb7 100644 --- a/programs/ping_pong.asm +++ b/programs/ping_pong.asm @@ -20,7 +20,7 @@ INPUT_DEVICE equ 1 # output(6) = display.get_anodes()[0] # Output(7) = display.get_cathodes()[0] OUTPUT_WIDTH equ 6 -OUTPUT_HEGHT equ 7 +OUTPUT_HEIGHT equ 7 PROGRAM_ORG equ 0x80 @@ -28,8 +28,8 @@ PROGRAM_ORG equ 0x80 BAT_H equ 3 BAT_MAXY equ 5 -BALL_STEP_SIZE equ 2 -GAME_OVER_BLINK_STEP equ 5 +BALL_STEP_SIZE equ 3 +GAME_OVER_BLINK_STEP equ 15 BALL_DIR_RIGHT equ 1 BALL_DIR_LEFT equ 2 @@ -66,6 +66,11 @@ section .data game_over_blink_counter dd 0 game_over_blink dd 1 + bat1_anode_mask dd 0x7FFF + bat2_anode_mask dd 0xFFFE + displayoff_anode_mask dd 0xFFFF + + section .text game: call print @@ -87,7 +92,6 @@ section .text subc [game_over_blink_counter], 1 ret - read_input_p1_up: IN R0, INPUT_DEVICE movc R1, 0x1 @@ -127,27 +131,29 @@ section .text ## Player 1 # anode col - movc R0, 0x7F - shlc R0, 8 - xorc R0, 0xFF + mov R0, [bat1_anode_mask] # cathode row movc R1, 0x7 shl R1, [bat1_y] OUT OUTPUT_WIDTH, R0 - OUT OUTPUT_HEGHT, R1 - call sleep + OUT OUTPUT_HEIGHT, R1 + movc R1, 0 + mov R0, [displayoff_anode_mask] + OUT OUTPUT_HEIGHT, R1 + OUT OUTPUT_WIDTH, R0 ## Player 2 # anode col - movc R0, 0xFF - shlc R0, 8 - xorc R0, 0xFE + mov R0, [bat2_anode_mask] # cathode row movc R1, 0x7 shl R1, [bat2_y] OUT OUTPUT_WIDTH, R0 - OUT OUTPUT_HEGHT, R1 - call sleep + OUT OUTPUT_HEIGHT, R1 + movc R1, 0 + mov R0, [displayoff_anode_mask] + OUT OUTPUT_HEIGHT, R1 + OUT OUTPUT_WIDTH, R0 _draw_ball: ## Ball @@ -160,17 +166,11 @@ section .text movc R2, 1 shl R2, R0 OUT OUTPUT_WIDTH, R1 - OUT OUTPUT_HEGHT, R2 - call sleep - - ret - - sleep: - movc R0, 0xF0 - shlc R0, 1 - _sleep: - subc R0, 1 - jnz _sleep + OUT OUTPUT_HEIGHT, R2 + movc R2, 0 + mov R1, [displayoff_anode_mask] + OUT OUTPUT_HEIGHT, R2 + OUT OUTPUT_WIDTH, R1 ret step: From 5c705617ebc4485de8fa85d9446febbef51761f6 Mon Sep 17 00:00:00 2001 From: Gagan Kumar Date: Wed, 18 Dec 2024 01:04:53 -0800 Subject: [PATCH 3/5] Functional brom, ram, prom --- output/programs/boot_sequence.bin | 8 +- output/programs/boot_sequence_resolved.asm | 34 +- output/programs/ping_pong.bin | 124 +++---- output/programs/ping_pong_resolved.asm | 387 +++++++++++---------- planner/memory.py | 3 +- planner/sim/bin_parser.py | 186 ++++++---- planner/sim/devices.py | 91 ++++- planner/sim/programs/ping_pong.py | 16 +- planner/util.py | 19 +- programs/boot_sequence.asm | 2 +- 10 files changed, 510 insertions(+), 360 deletions(-) diff --git a/output/programs/boot_sequence.bin b/output/programs/boot_sequence.bin index 8d0c3fa..9d8f26a 100644 --- a/output/programs/boot_sequence.bin +++ b/output/programs/boot_sequence.bin @@ -4,14 +4,14 @@ 00100100 00000010 00000000 00000010 01110011 00000010 00000000 00000010 00110100 00000010 00000100 00000100 -00110100 00000010 00001000 11110000 +00110100 00000010 00001000 10000000 01110001 00000000 00000000 00000000 -00110101 00001011 01101100 00000000 +00110101 00001011 01110000 00000000 00000100 00000100 00000010 00000100 00100100 00000010 00001100 00000010 01000100 00000110 00001000 00001100 01110000 00000010 00001000 00000100 01110000 00000010 00000100 00000100 01110001 00000010 00000000 00000001 -00110101 00001001 01001000 00000000 -00110101 00001001 11110000 00000000 +00110101 00001001 01001100 00000000 +00110101 00001001 10000000 00000000 diff --git a/output/programs/boot_sequence_resolved.asm b/output/programs/boot_sequence_resolved.asm index 3e3f7c3..c53cfc2 100644 --- a/output/programs/boot_sequence_resolved.asm +++ b/output/programs/boot_sequence_resolved.asm @@ -1,17 +1,17 @@ -PROGRAM_ORG equ 48 -030: MOVC [0], 0 -034: OUT 2, [0] -038: IN [0], 2 -03c: SHRC [0], 2 -040: MOVC [4], 4 -044: MOVC [8], 240 -048: CMPC [0], 0 -04c: JZ 108, 0 -050: OUT 2, [4] -054: IN [12], 2 -058: STORE [[8]], [12] -05c: ADDC [8], 4 -060: ADDC [4], 4 -064: SUBC [0], 1 -068: JMP 72, 0 -06c: JMP 240, 0 +PROGRAM_ORG equ 52 +034: MOVC [0], 0 +038: OUT 2, [0] +03c: IN [0], 2 +040: SHRC [0], 2 +044: MOVC [4], 4 +048: MOVC [8], 128 +04c: CMPC [0], 0 +050: JZ 112, 0 +054: OUT 2, [4] +058: IN [12], 2 +05c: STORE [[8]], [12] +060: ADDC [8], 4 +064: ADDC [4], 4 +068: SUBC [0], 1 +06c: JMP 76, 0 +070: JMP 128, 0 diff --git a/output/programs/ping_pong.bin b/output/programs/ping_pong.bin index 804584c..195cf60 100644 --- a/output/programs/ping_pong.bin +++ b/output/programs/ping_pong.bin @@ -1,8 +1,8 @@ -00110100 00000011 00000000 00000000 +00010100 00000011 00000000 00000000 00110100 00000010 00100000 11111111 01110010 00000010 00100000 00001000 01110111 00000010 00100000 11110000 -00110101 00001001 10110100 00000000 +00110101 00001001 11000000 00000000 00000010 00000000 00000000 00000000 00000010 00000000 00000000 00000000 00000111 00000000 00000000 00000000 @@ -12,32 +12,35 @@ 00000110 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001 00000000 00000000 00000000 +11111111 01111111 00000000 00000000 +11111110 11111111 00000000 00000000 +11111111 11111111 00000000 00000000 01110000 00000011 00101000 00010000 01110001 00000010 00100000 00000100 01000100 00000110 00100000 00101000 -00110101 00001001 10011100 00000001 +00110101 00001001 10101000 00000001 01110000 00000011 00101000 00010000 01110001 00000010 00100000 00000100 01000100 00000110 00100000 00101000 -00110101 00001001 00101100 00000001 +00110101 00001001 00111000 00000001 01110000 00000011 00101000 00010000 01110001 00000010 00100000 00000100 01000100 00000110 00100000 00101000 -00110101 00001001 01011100 00000010 -00110101 00001001 10110100 00000000 +00110101 00001001 00111100 00000010 +00110101 00001001 11000000 00000000 01110000 00000011 00101000 00010000 01110001 00000010 00100000 00000100 01000100 00000110 00100000 00101000 -00110101 00001001 00001100 00000001 +00110101 00001001 00011000 00000001 01110000 00000011 00101000 00010000 01110001 00000010 00100000 00000100 01000100 00000110 00100000 00101000 -00110101 00001001 10011100 00000001 -00110101 00001001 11101000 00000000 +00110101 00001001 10101000 00000001 +00110101 00001001 11110100 00000000 01110001 00000000 10101100 00000000 -00110101 00001101 00011100 00000001 +00110101 00001101 00101000 00000001 01111000 00000010 10110000 00000001 -00110100 00000010 10101100 00000101 +00110100 00000010 10101100 00001111 01110001 00000010 10101100 00000001 10000101 00000010 00101000 00100000 01110000 00000010 00100000 00000100 @@ -45,55 +48,51 @@ 00100100 00000010 00000000 00000001 00110100 00000010 00000100 00000001 01000110 00000010 00000100 00000000 -00110101 00001011 01001000 00000001 +00110101 00001011 01010100 00000001 01110001 00000000 10010000 00000000 -00110101 00001011 01001000 00000001 +00110101 00001011 01010100 00000001 01110001 00000010 10010000 00000001 00110100 00000010 00000100 00000010 01000110 00000010 00000100 00000000 -00110101 00001011 01100000 00000001 +00110101 00001011 01101100 00000001 01110001 00000000 10010000 00000101 -00110101 00001011 01100000 00000001 +00110101 00001011 01101100 00000001 01110000 00000010 10010000 00000001 00110100 00000010 00000100 00000100 01000110 00000010 00000100 00000000 -00110101 00001011 01111000 00000001 +00110101 00001011 10000100 00000001 01110001 00000000 10010100 00000000 -00110101 00001011 01111000 00000001 +00110101 00001011 10000100 00000001 01110001 00000010 10010100 00000001 00110100 00000010 00000100 00001000 01000110 00000010 00000100 00000000 -00110101 00001011 10010000 00000001 +00110101 00001011 10011100 00000001 01110001 00000000 10010100 00000101 -00110101 00001011 10010000 00000001 +00110101 00001011 10011100 00000001 01110000 00000010 10010100 00000001 10000101 00000010 00101000 00100000 01110000 00000010 00100000 00000100 11110101 00001000 00101000 00000000 01110001 00000000 10110000 00000000 -00110101 00001011 11111100 00000001 -00110100 00000010 00000000 01111111 -01110010 00000010 00000000 00001000 -01111000 00000010 00000000 11111111 +00110101 00001011 11111000 00000001 +00000100 00000010 00000000 10110100 00110100 00000010 00000100 00000111 01000010 00000010 00000100 10010000 00000100 00000100 00000110 00000000 00000100 00000100 00000111 00000100 -01110000 00000011 00101000 00010000 -01110001 00000010 00100000 00000100 -01000100 00000110 00100000 00101000 -00110101 00001001 01000000 00000010 -00110100 00000010 00000000 11111111 -01110010 00000010 00000000 00001000 -01111000 00000010 00000000 11111110 +00110100 00000010 00000100 00000000 +00000100 00000010 00000000 10111100 +00000100 00000100 00000111 00000100 +00000100 00000100 00000110 00000000 +00000100 00000010 00000000 10111000 00110100 00000010 00000100 00000111 01000010 00000010 00000100 10010100 00000100 00000100 00000110 00000000 00000100 00000100 00000111 00000100 -01110000 00000011 00101000 00010000 -01110001 00000010 00100000 00000100 -01000100 00000110 00100000 00101000 -00110101 00001001 01000000 00000010 +00110100 00000010 00000100 00000000 +00000100 00000010 00000000 10111100 +00000100 00000100 00000111 00000100 +00000100 00000100 00000110 00000000 00000100 00000010 00000000 10011000 00110100 00000010 00000100 10000000 01110010 00000010 00000100 00001000 @@ -104,52 +103,45 @@ 01000010 00000010 00001000 00000000 00000100 00000100 00000110 00000100 00000100 00000100 00000111 00001000 -01110000 00000011 00101000 00010000 -01110001 00000010 00100000 00000100 -01000100 00000110 00100000 00101000 -00110101 00001001 01000000 00000010 -10000101 00000010 00101000 00100000 -01110000 00000010 00100000 00000100 -11110101 00001000 00101000 00000000 -00110100 00000010 00000000 11110000 -01110010 00000010 00000000 00000001 -01110001 00000010 00000000 00000001 -00110101 00001101 01001000 00000010 +00110100 00000010 00001000 00000000 +00000100 00000010 00000100 10111100 +00000100 00000100 00000111 00001000 +00000100 00000100 00000110 00000100 10000101 00000010 00101000 00100000 01110000 00000010 00100000 00000100 11110101 00001000 00101000 00000000 01110001 00000000 10100100 00000000 -00110101 00001101 01111000 00000010 -00110100 00000010 10100100 00000010 +00110101 00001101 01011000 00000010 +00110100 00000010 10100100 00000011 01110000 00000011 00101000 00010000 01110001 00000010 00100000 00000100 01000100 00000110 00100000 00101000 -00110101 00001001 10001000 00000010 +00110101 00001001 01101000 00000010 01110001 00000010 10100100 00000001 10000101 00000010 00101000 00100000 01110000 00000010 00100000 00000100 11110101 00001000 00101000 00000000 01110001 00000000 10011000 00001110 -00110101 00001011 11101100 00000010 +00110101 00001011 11001100 00000010 01110001 00000000 10011000 00000001 -00110101 00001011 00010000 00000011 +00110101 00001011 11110000 00000010 01110001 00000000 10011100 00000111 -00110101 00001011 10100000 00000011 +00110101 00001011 10000000 00000011 01110001 00000000 10011100 00000000 -00110101 00001011 10100000 00000011 +00110101 00001011 10000000 00000011 00000100 00000010 00000000 10101000 01110110 00000010 00000000 00000001 -00110101 00001011 10111100 00000010 +00110101 00001011 10011100 00000010 01110000 00000010 10011000 00000001 -00110101 00001001 11000000 00000010 +00110101 00001001 10100000 00000010 01110001 00000010 10011000 00000001 00000100 00000010 00000000 10101000 01110110 00000010 00000000 00000100 -00110101 00001011 11010000 00000010 +00110101 00001011 10110000 00000010 01110001 00000010 10011100 00000001 00000100 00000010 00000000 10101000 01110110 00000010 00000000 00001000 -00110101 00001011 11100000 00000010 +00110101 00001011 11000000 00000010 01110000 00000010 10011100 00000001 10000101 00000010 00101000 00100000 01110000 00000010 00100000 00000100 @@ -159,19 +151,19 @@ 01110000 00000011 00101000 00010000 01110001 00000010 00100000 00000100 01000100 00000110 00100000 00101000 -00110101 00001001 00110100 00000011 +00110101 00001001 00010100 00000011 10000101 00000010 00011100 00100000 01110000 00000010 00100000 00000100 -00110101 00001001 10011000 00000010 +00110101 00001001 01111000 00000010 01110001 00000010 00100000 00000100 01000100 00000110 00100000 10010000 01110000 00000011 00101000 00010000 01110001 00000010 00100000 00000100 01000100 00000110 00100000 00101000 -00110101 00001001 00110100 00000011 +00110101 00001001 00010100 00000011 10000101 00000010 00011100 00100000 01110000 00000010 00100000 00000100 -00110101 00001001 10011000 00000010 +00110101 00001001 01111000 00000010 00000100 00000010 00100100 00100000 01110000 00000010 00100100 00000100 10000101 00000010 00000100 00100100 @@ -180,14 +172,14 @@ 01111000 00000010 00000000 11111111 01000110 00000010 10101000 00000000 01000001 00000000 10011100 00000100 -00110101 00001011 01110100 00000011 +00110101 00001011 01010100 00000011 01110000 00000010 00000100 00000001 01000001 00000000 10011100 00000100 -00110101 00001011 10010100 00000011 +00110101 00001011 01110100 00000011 01110000 00000010 00000100 00000001 01000001 00000000 10011100 00000100 -00110101 00001011 10000100 00000011 -00110101 00001001 11101000 00000000 +00110101 00001011 01100100 00000011 +00110101 00001001 11110100 00000000 01110111 00000010 10101000 00000100 10000101 00000010 00101000 00100000 01110000 00000010 00100000 00000100 @@ -201,6 +193,6 @@ 11110101 00001000 00101000 00000000 00000100 00000010 00000000 10101000 01110110 00000010 00000000 00001100 -00110101 00001011 10101000 00000010 +00110101 00001011 10001000 00000010 01111000 00000010 10101000 00001100 -00110101 00001001 10101000 00000010 +00110101 00001001 10001000 00000010 diff --git a/output/programs/ping_pong_resolved.asm b/output/programs/ping_pong_resolved.asm index 4354d0e..b8f0c8f 100644 --- a/output/programs/ping_pong_resolved.asm +++ b/output/programs/ping_pong_resolved.asm @@ -2,7 +2,7 @@ PROGRAM_ORG equ 128 080: MOVC [32], 255 084: SHLC [32], 8 088: ORC [32], 240 -08c: JMP 180, 0 +08c: JMP 192, 0 090: 02 091: 00 092: 00 @@ -39,195 +39,196 @@ PROGRAM_ORG equ 128 0b1: 00 0b2: 00 0b3: 00 -0b4: PCPLUS [40], 16 -0b8: SUBC [32], 4 -0bc: STORE [[32]], [40] -0c0: JMP 156, 1 -0c4: PCPLUS [40], 16 -0c8: SUBC [32], 4 -0cc: STORE [[32]], [40] -0d0: JMP 44, 1 -0d4: PCPLUS [40], 16 -0d8: SUBC [32], 4 -0dc: STORE [[32]], [40] -0e0: JMP 92, 2 -0e4: JMP 180, 0 -0e8: PCPLUS [40], 16 -0ec: SUBC [32], 4 -0f0: STORE [[32]], [40] -0f4: JMP 12, 1 -0f8: PCPLUS [40], 16 -0fc: SUBC [32], 4 -100: STORE [[32]], [40] -104: JMP 156, 1 -108: JMP 232, 0 -10c: CMPC [172], 0 -110: JNZ 28, 1 -114: XORC [176], 1 -118: MOVC [172], 5 -11c: SUBC [172], 1 -120: LOAD [40], [[32]] -124: ADDC [32], 4 -128: JMPM [40], [0] -12c: IN [0], 1 -130: MOVC [4], 1 -134: AND [4], [0] -138: JZ 72, 1 -13c: CMPC [144], 0 -140: JZ 72, 1 -144: SUBC [144], 1 -148: MOVC [4], 2 -14c: AND [4], [0] -150: JZ 96, 1 -154: CMPC [144], 5 -158: JZ 96, 1 -15c: ADDC [144], 1 -160: MOVC [4], 4 -164: AND [4], [0] -168: JZ 120, 1 -16c: CMPC [148], 0 -170: JZ 120, 1 -174: SUBC [148], 1 -178: MOVC [4], 8 -17c: AND [4], [0] -180: JZ 144, 1 -184: CMPC [148], 5 -188: JZ 144, 1 -18c: ADDC [148], 1 -190: LOAD [40], [[32]] -194: ADDC [32], 4 -198: JMPM [40], [0] -19c: CMPC [176], 0 -1a0: JZ 252, 1 -1a4: MOVC [0], 127 -1a8: SHLC [0], 8 -1ac: XORC [0], 255 -1b0: MOVC [4], 7 -1b4: SHL [4], [144] -1b8: OUT 6, [0] -1bc: OUT 7, [4] -1c0: PCPLUS [40], 16 -1c4: SUBC [32], 4 -1c8: STORE [[32]], [40] -1cc: JMP 64, 2 -1d0: MOVC [0], 255 -1d4: SHLC [0], 8 -1d8: XORC [0], 254 -1dc: MOVC [4], 7 -1e0: SHL [4], [148] -1e4: OUT 6, [0] -1e8: OUT 7, [4] -1ec: PCPLUS [40], 16 -1f0: SUBC [32], 4 -1f4: STORE [[32]], [40] -1f8: JMP 64, 2 -1fc: MOV [0], [152] -200: MOVC [4], 128 -204: SHLC [4], 8 -208: SHR [4], [0] -20c: XOR [4], [160] -210: MOV [0], [156] -214: MOVC [8], 1 -218: SHL [8], [0] -21c: OUT 6, [4] -220: OUT 7, [8] -224: PCPLUS [40], 16 -228: SUBC [32], 4 -22c: STORE [[32]], [40] -230: JMP 64, 2 -234: LOAD [40], [[32]] -238: ADDC [32], 4 -23c: JMPM [40], [0] -240: MOVC [0], 240 -244: SHLC [0], 1 -248: SUBC [0], 1 -24c: JNZ 72, 2 -250: LOAD [40], [[32]] -254: ADDC [32], 4 -258: JMPM [40], [0] -25c: CMPC [164], 0 -260: JNZ 120, 2 -264: MOVC [164], 2 -268: PCPLUS [40], 16 -26c: SUBC [32], 4 -270: STORE [[32]], [40] -274: JMP 136, 2 -278: SUBC [164], 1 -27c: LOAD [40], [[32]] -280: ADDC [32], 4 -284: JMPM [40], [0] -288: CMPC [152], 14 -28c: JZ 236, 2 -290: CMPC [152], 1 -294: JZ 16, 3 -298: CMPC [156], 7 -29c: JZ 160, 3 -2a0: CMPC [156], 0 -2a4: JZ 160, 3 -2a8: MOV [0], [168] -2ac: ANDC [0], 1 -2b0: JZ 188, 2 -2b4: ADDC [152], 1 -2b8: JMP 192, 2 -2bc: SUBC [152], 1 -2c0: MOV [0], [168] -2c4: ANDC [0], 4 -2c8: JZ 208, 2 -2cc: SUBC [156], 1 -2d0: MOV [0], [168] -2d4: ANDC [0], 8 -2d8: JZ 224, 2 -2dc: ADDC [156], 1 -2e0: LOAD [40], [[32]] -2e4: ADDC [32], 4 -2e8: JMPM [40], [0] -2ec: SUBC [32], 4 -2f0: STORE [[32]], [148] -2f4: PCPLUS [40], 16 -2f8: SUBC [32], 4 -2fc: STORE [[32]], [40] -300: JMP 52, 3 -304: LOAD [28], [[32]] -308: ADDC [32], 4 -30c: JMP 152, 2 -310: SUBC [32], 4 -314: STORE [[32]], [144] -318: PCPLUS [40], 16 -31c: SUBC [32], 4 -320: STORE [[32]], [40] -324: JMP 52, 3 -328: LOAD [28], [[32]] -32c: ADDC [32], 4 -330: JMP 152, 2 -334: MOV [36], [32] -338: ADDC [36], 4 -33c: LOAD [4], [[36]] -340: XORC [168], 3 -344: MOVC [0], 12 -348: XORC [0], 255 -34c: AND [168], [0] -350: CMP [156], [4] -354: JZ 116, 3 -358: ADDC [4], 1 -35c: CMP [156], [4] -360: JZ 148, 3 -364: ADDC [4], 1 -368: CMP [156], [4] -36c: JZ 132, 3 -370: JMP 232, 0 -374: ORC [168], 4 -378: LOAD [40], [[32]] -37c: ADDC [32], 4 -380: JMPM [40], [0] -384: ORC [168], 8 -388: LOAD [40], [[32]] -38c: ADDC [32], 4 -390: JMPM [40], [0] -394: LOAD [40], [[32]] -398: ADDC [32], 4 -39c: JMPM [40], [0] -3a0: MOV [0], [168] -3a4: ANDC [0], 12 -3a8: JZ 168, 2 -3ac: XORC [168], 12 -3b0: JMP 168, 2 +0b4: 255 +0b5: 127 +0b6: 00 +0b7: 00 +0b8: 254 +0b9: 255 +0ba: 00 +0bb: 00 +0bc: 255 +0bd: 255 +0be: 00 +0bf: 00 +0c0: PCPLUS [40], 16 +0c4: SUBC [32], 4 +0c8: STORE [[32]], [40] +0cc: JMP 168, 1 +0d0: PCPLUS [40], 16 +0d4: SUBC [32], 4 +0d8: STORE [[32]], [40] +0dc: JMP 56, 1 +0e0: PCPLUS [40], 16 +0e4: SUBC [32], 4 +0e8: STORE [[32]], [40] +0ec: JMP 60, 2 +0f0: JMP 192, 0 +0f4: PCPLUS [40], 16 +0f8: SUBC [32], 4 +0fc: STORE [[32]], [40] +100: JMP 24, 1 +104: PCPLUS [40], 16 +108: SUBC [32], 4 +10c: STORE [[32]], [40] +110: JMP 168, 1 +114: JMP 244, 0 +118: CMPC [172], 0 +11c: JNZ 40, 1 +120: XORC [176], 1 +124: MOVC [172], 15 +128: SUBC [172], 1 +12c: LOAD [40], [[32]] +130: ADDC [32], 4 +134: JMPM [40], [0] +138: IN [0], 1 +13c: MOVC [4], 1 +140: AND [4], [0] +144: JZ 84, 1 +148: CMPC [144], 0 +14c: JZ 84, 1 +150: SUBC [144], 1 +154: MOVC [4], 2 +158: AND [4], [0] +15c: JZ 108, 1 +160: CMPC [144], 5 +164: JZ 108, 1 +168: ADDC [144], 1 +16c: MOVC [4], 4 +170: AND [4], [0] +174: JZ 132, 1 +178: CMPC [148], 0 +17c: JZ 132, 1 +180: SUBC [148], 1 +184: MOVC [4], 8 +188: AND [4], [0] +18c: JZ 156, 1 +190: CMPC [148], 5 +194: JZ 156, 1 +198: ADDC [148], 1 +19c: LOAD [40], [[32]] +1a0: ADDC [32], 4 +1a4: JMPM [40], [0] +1a8: CMPC [176], 0 +1ac: JZ 248, 1 +1b0: MOV [0], [180] +1b4: MOVC [4], 7 +1b8: SHL [4], [144] +1bc: OUT 6, [0] +1c0: OUT 7, [4] +1c4: MOVC [4], 0 +1c8: MOV [0], [188] +1cc: OUT 7, [4] +1d0: OUT 6, [0] +1d4: MOV [0], [184] +1d8: MOVC [4], 7 +1dc: SHL [4], [148] +1e0: OUT 6, [0] +1e4: OUT 7, [4] +1e8: MOVC [4], 0 +1ec: MOV [0], [188] +1f0: OUT 7, [4] +1f4: OUT 6, [0] +1f8: MOV [0], [152] +1fc: MOVC [4], 128 +200: SHLC [4], 8 +204: SHR [4], [0] +208: XOR [4], [160] +20c: MOV [0], [156] +210: MOVC [8], 1 +214: SHL [8], [0] +218: OUT 6, [4] +21c: OUT 7, [8] +220: MOVC [8], 0 +224: MOV [4], [188] +228: OUT 7, [8] +22c: OUT 6, [4] +230: LOAD [40], [[32]] +234: ADDC [32], 4 +238: JMPM [40], [0] +23c: CMPC [164], 0 +240: JNZ 88, 2 +244: MOVC [164], 3 +248: PCPLUS [40], 16 +24c: SUBC [32], 4 +250: STORE [[32]], [40] +254: JMP 104, 2 +258: SUBC [164], 1 +25c: LOAD [40], [[32]] +260: ADDC [32], 4 +264: JMPM [40], [0] +268: CMPC [152], 14 +26c: JZ 204, 2 +270: CMPC [152], 1 +274: JZ 240, 2 +278: CMPC [156], 7 +27c: JZ 128, 3 +280: CMPC [156], 0 +284: JZ 128, 3 +288: MOV [0], [168] +28c: ANDC [0], 1 +290: JZ 156, 2 +294: ADDC [152], 1 +298: JMP 160, 2 +29c: SUBC [152], 1 +2a0: MOV [0], [168] +2a4: ANDC [0], 4 +2a8: JZ 176, 2 +2ac: SUBC [156], 1 +2b0: MOV [0], [168] +2b4: ANDC [0], 8 +2b8: JZ 192, 2 +2bc: ADDC [156], 1 +2c0: LOAD [40], [[32]] +2c4: ADDC [32], 4 +2c8: JMPM [40], [0] +2cc: SUBC [32], 4 +2d0: STORE [[32]], [148] +2d4: PCPLUS [40], 16 +2d8: SUBC [32], 4 +2dc: STORE [[32]], [40] +2e0: JMP 20, 3 +2e4: LOAD [28], [[32]] +2e8: ADDC [32], 4 +2ec: JMP 120, 2 +2f0: SUBC [32], 4 +2f4: STORE [[32]], [144] +2f8: PCPLUS [40], 16 +2fc: SUBC [32], 4 +300: STORE [[32]], [40] +304: JMP 20, 3 +308: LOAD [28], [[32]] +30c: ADDC [32], 4 +310: JMP 120, 2 +314: MOV [36], [32] +318: ADDC [36], 4 +31c: LOAD [4], [[36]] +320: XORC [168], 3 +324: MOVC [0], 12 +328: XORC [0], 255 +32c: AND [168], [0] +330: CMP [156], [4] +334: JZ 84, 3 +338: ADDC [4], 1 +33c: CMP [156], [4] +340: JZ 116, 3 +344: ADDC [4], 1 +348: CMP [156], [4] +34c: JZ 100, 3 +350: JMP 244, 0 +354: ORC [168], 4 +358: LOAD [40], [[32]] +35c: ADDC [32], 4 +360: JMPM [40], [0] +364: ORC [168], 8 +368: LOAD [40], [[32]] +36c: ADDC [32], 4 +370: JMPM [40], [0] +374: LOAD [40], [[32]] +378: ADDC [32], 4 +37c: JMPM [40], [0] +380: MOV [0], [168] +384: ANDC [0], 12 +388: JZ 136, 2 +38c: XORC [168], 12 +390: JMP 136, 2 diff --git a/planner/memory.py b/planner/memory.py index 25a1a05..5ecc1ab 100644 --- a/planner/memory.py +++ b/planner/memory.py @@ -17,7 +17,8 @@ def get_register_address(index): # free # boot sequence -BOOTSEQUENCE_ORG = 0x30 +BOOTSEQUENCE_LOAD = 0x30 +BOOTSEQUENCE_ORG = 0x34 # as we have 4-byte rom size header at top # user program diff --git a/planner/sim/bin_parser.py b/planner/sim/bin_parser.py index a4de469..5c25175 100644 --- a/planner/sim/bin_parser.py +++ b/planner/sim/bin_parser.py @@ -13,16 +13,18 @@ def binary_array_num(arr: List[int]): return sum([x<<(8*i) for i, x in enumerate(arr)]) FLAGS_BIT_VW_ZERO = 0 + class BinRunner: - def __init__(self, bootsequence_binary): - self.ram = [] + def __init__(self, clock: devices.Clock, ram: devices.RAM, brom: devices.ROM): + self.ram = ram + self.brom = brom + self.ram.is_write.update(0) + self.input_devices = [None]*IO_DEVICES self.output_devices = [None]*IO_DEVICES - for _ in range(RAM_SIZE): - self.ram.append(random.randint(0, 256)) - self.parse_bs(bootsequence_binary) - self.pc_next = memory.BOOTSEQUENCE_ORG + # self.parse_bs(bootsequence_binary) + self.reg_pc_next = memory.BOOTSEQUENCE_ORG self.pc = None # self.is_powered_on = False # self.step() @@ -30,47 +32,45 @@ def __init__(self, bootsequence_binary): self.flags = [0] # self.step() + self.stage = 0 + def _on_clock_change(new_val, old_val): + if new_val[0] == 1: + assert old_val[0] == 0 + self.clock_up() + clock.add_change_handler(_on_clock_change) + + def clock_up(self): + if self.stage == 0: + self.trigger_stage0() + elif self.stage == 1: + self.trigger_stage1() + elif self.stage == 2: + self.trigger_stage2() + elif self.stage == 3: + self.trigger_stage3() + self.stage = (self.stage+1)%4 + def set_input_device(self, index: int, d: devices.InputDevice): self.input_devices[index] = d def set_output_device(self, index: int, d: devices.Device): self.output_devices[index] = d - def parse_bs(self, bootsequence_binary: str): - content = bootsequence_binary.replace(" ", "").replace("\n", "") - assert len(content)%8 == 0 - assert set(content) <= set(['0', '1']) - program_size = util.from_little_32binary(content[:32]) - assert program_size*8+32 == len(content) - address = memory.BOOTSEQUENCE_ORG - for i in range(4, len(content)//8): - self.ram[address] = (int(content[i*8:(i+1)*8], 2)) - address += 1 - assert address <= memory.DEFAULT_PROGRAM_ORG def read_ram(self, addr: int, count: int) -> List[int]: - ans = [] - assert addr >= 0 - for i in range(count): - if addr+i >= len(self.ram): - ans.append(random.randint(0, 256)) - else: - ans.append(self.ram[addr+i]) - - logging.debug("RAM[%04x] => %s", addr, ans) - return ans + assert count == 4 + self.ram.address_line.update(addr) + ins_binary = self.ram.value_out_line.get() + ins_binary_array = util.to_little_32binaryarray(ins_binary) + return ins_binary_array def write_ram(self, addr: int, count: int, value: int) -> List[int]: - arr_value = [] - for i in range(count): - arr_value.append(value&255) - value>>=8 + self.ram.address_line.update(addr) + assert count == 4 + self.ram.value_in_line.update(value) + self.ram.is_write.update(1) + self.ram.is_write.update(0) - assert addr >= 0 - for i in range(count): - self.ram[(i+addr)%len(self.ram)] = arr_value[i] - - logging.debug("RAM[%04x] <= %s", addr, arr_value) def m_fetch_and_store_stage1( self, @@ -131,17 +131,17 @@ def m_fetch_and_store_stage3( output_devices[vrw_source].update(vw_value) return if sel == instruction.MBlockSelector_stage3.PC_NEXT: - self.pc_next = vw_value + self.reg_pc_next = vw_value return if sel == instruction.MBlockSelector_stage3.PC_NEXT_IF_ZERO: # check previous vw_value flags if self.flags[FLAGS_BIT_VW_ZERO] == 1: - self.pc_next = vw_value + self.reg_pc_next = vw_value return if sel == instruction.MBlockSelector_stage3.PC_NEXT_IF_NOT_ZERO: # check previous vw_value flags if self.flags[FLAGS_BIT_VW_ZERO] == 0: - self.pc_next = vw_value + self.reg_pc_next = vw_value return if sel == instruction.MBlockSelector_stage3.HLT: self.is_powered_on = False @@ -157,43 +157,99 @@ def run_until_hlt(self): while self.is_powered_on: self.step() - def step(self): + def is_boot_sequence(self): + return self.pc >= memory.BOOTSEQUENCE_ORG and self.pc < memory.DEFAULT_PROGRAM_ORG + + def print_bootsequence_completed(self): + if hasattr(self, "_print_bootsequence_completed"): + return + self._print_bootsequence_completed = True + print("Boot sequence completed") + + def trigger_stage0(self): if not self.is_powered_on: return - self.pc = self.pc_next - self.pc_next = self.pc + 4 - logging.debug("PC: 0x%x, flags: %s", self.pc, self.flags) - ins_binary = self.read_ram(self.pc, 4) - ins = instruction.FullyEncodedInstruction.from_binary(ins_binary) + self.pc = self.reg_pc_next + logging.debug("[stage0] PC: 0x%x, flags: %s", self.pc, self.flags) + + # Read instruction + if self.is_boot_sequence(): + brom_address = self.pc-memory.BOOTSEQUENCE_LOAD + self.brom.address_line.update(brom_address) + ins_binary = self.brom.value_line.get() + else: + self.print_bootsequence_completed() + self.ram.is_write.update(0) + self.ram.address_line.update(self.pc) + ins_binary = self.ram.value_out_line.get() + ins_binary_array = util.to_little_32binaryarray(ins_binary) + ins = instruction.FullyEncodedInstruction.from_binary(ins_binary_array) logging.debug("Instruction data: %s", ins) logging.debug("Instruction encoding: %s", [str(x) for x in instruction.get_parsers_from_encoding(ins.encoded_instruction)]) - mblock_s1 = ins.encoded_instruction.mblock_s1 - mblock_s2 = ins.encoded_instruction.mblock_s2 - mblock_s3 = ins.encoded_instruction.mblock_s3 - alu_op = ins.encoded_instruction.alu_op - vr_source = ins.address_r.get() - vrw_source = ins.address_rw.get() + self.reg_mblock_s1 = ins.encoded_instruction.mblock_s1 + self.reg_mblock_s2 = ins.encoded_instruction.mblock_s2 + self.reg_mblock_s3 = ins.encoded_instruction.mblock_s3 + self.reg_alu_op = ins.encoded_instruction.alu_op - vr_value = self.m_fetch_and_store_stage1( + self.reg_vr_source = ins.address_r.get() + self.reg_vrw_source = ins.address_rw.get() + + def trigger_stage1(self): + if not self.is_powered_on: + return + self.reg_pc_next = self.pc + 4 + logging.debug("[stage1] reg_vr_source: 0x%x, reg_mblock_s1: %s", self.reg_vr_source, self.reg_mblock_s1) + self.reg_vr_value = self.m_fetch_and_store_stage1( self.input_devices, - vr_source, - mblock_s1) - vrw_value = self.m_fetch_and_store_stage2( - vr_source, - vr_value, - vrw_source, - mblock_s2) + self.reg_vr_source, + self.reg_mblock_s1) - vw_value = self.m_alu(vrw_value, vr_value, alu_op) + def trigger_stage2(self): + if not self.is_powered_on: + return + logging.debug("[stage2] reg_vr_source: 0x%x, " + "reg_vr_value: 0x%x, " + "reg_vrw_source: 0x%x, " + "reg_mblock_s2: %s, " + "reg_alu_op: %s", + self.reg_vr_source, + self.reg_vr_value, + self.reg_vrw_source, + self.reg_mblock_s2, + self.reg_alu_op) + self.reg_vrw_value = self.m_fetch_and_store_stage2( + self.reg_vr_source, + self.reg_vr_value, + self.reg_vrw_source, + self.reg_mblock_s2) + + self.reg_vw_value = self.m_alu( + self.reg_vrw_value, + self.reg_vr_value, + self.reg_alu_op) + + + def trigger_stage3(self): + if not self.is_powered_on: + return + logging.debug("[stage3] reg_vw_value: 0x%x, " + "reg_vrw_value: 0x%x, " + "reg_vrw_source: 0x%x, " + "reg_mblock_s3: %s", + self.reg_vw_value, + self.reg_vrw_value, + self.reg_vrw_source, + self.reg_mblock_s3) self.m_fetch_and_store_stage3( self.output_devices, - vw_value, - vrw_value, - vrw_source, - mblock_s3) + self.reg_vw_value, + self.reg_vrw_value, + self.reg_vrw_source, + self.reg_mblock_s3) + + self.flags[FLAGS_BIT_VW_ZERO] = 1 if (self.reg_vw_value==0) else 0 - self.flags[FLAGS_BIT_VW_ZERO] = 1 if (vw_value==0) else 0 diff --git a/planner/sim/devices.py b/planner/sim/devices.py index a855c68..6ceb1ba 100644 --- a/planner/sim/devices.py +++ b/planner/sim/devices.py @@ -1,9 +1,9 @@ from planner import util from typing import List, Optional -import logging from threading import Thread -from copy import deepcopy import time +import random +import logging class Device: def __init__(self, bits = 8): @@ -11,6 +11,7 @@ def __init__(self, bits = 8): self.bits = bits self.value = [0 for _ in range(bits)] self.change_handlers = [] + self._never_updated = True def get_bit_count(self): return self.bits @@ -19,9 +20,10 @@ def add_change_handler(self, f): self.change_handlers.append(f) def _new_value(self, val): - if val != self.value: + if self._never_updated or val != self.value: old_value = self.value self.value = val + self._never_updated = False for handle in self.change_handlers: handle(val, old_value) @@ -70,6 +72,28 @@ def get(self): return super().get() +class Clock(InputDevice): + def __init__(self): + super(Clock, self).__init__(bits=1) + self.name = "clock" + self.update(0) + self.thread = Thread(None, self.steps) + + def start(self): + self.thread.start() + + def steps(self,): + while True: + # full speed + self.tick() + + def tick(self): + self.flip_bit(0) + + def get(self): + return super().get() + + class Numpad(InputDevice): def __init__(self, name: str): bits = 10 @@ -216,10 +240,63 @@ def display(self, only_if_changed=True): if self.use_print: print(new_display) +RAM_SIZE = 0x10000 # 64KB -class ProgramROM(object): +class RAM(object): + def __init__(self): + self.name = "RAM" + self.size = RAM_SIZE + self.data = [] + for _ in range(RAM_SIZE): + self.data.append(random.randint(0, 256)) + self.address_bits = 16 + self.value_bits = 32 + self.address_line = IntegerOutput("ram_address", bits=self.address_bits) + self.is_write = IntegerOutput("ram_is_write", bits=1) + self.value_in_line = IntegerOutput("ram_value_in", bits=self.value_bits) + self.value_out_line = LatchInput("ram_value_out", bits=self.value_bits) + + def _on_address_change(_, __): + address = self.address_line.get() + value=util.from_littlearray_32binary(self.read_ram(address, 4)) + self.value_out_line.update(value) + self.address_line.add_change_handler(_on_address_change) + + def _on_write_change(new_val, old_val): + if new_val[0] == 1: + assert old_val[0] == 0 + address = self.address_line.get() + value = self.value_in_line.get() + self.write_ram(address, 4, value) + self.value_out_line.update(value) + self.is_write.add_change_handler(_on_write_change) + + def read_ram(self, addr: int, count: int) -> List[int]: + ans = [] + assert addr >= 0 + for i in range(count): + if addr+i >= len(self.data): + raise ValueError(f"attempted to read outside ram: {addr+i} >= {len(self.data)}") + else: + ans.append(self.data[addr+i]) + + logging.debug("RAM[%04x] => %s", addr, ans) + return ans + + def write_ram(self, addr: int, count: int, value: int) -> List[int]: + arr_value = [] + for i in range(count): + arr_value.append(value&255) + value>>=8 + + assert addr >= 0 + for i in range(count): + self.data[i+addr] = arr_value[i] + logging.debug("RAM[%04x] <= %s", addr, arr_value) + + +class ROM(object): def __init__(self, name: str, content: str, **kwargs): - #super(ProgramROM, self).__init__(**kwargs, bits= 0) self.name = name self.content = self.parse(content) self.address_bits = 16 @@ -229,8 +306,10 @@ def __init__(self, name: str, content: str, **kwargs): def _on_change(_, __): address = self.address_line.get() value=util.from_little_32binary(self.content[address*8:address*8+32]) + logging.debug("ROM[%04x] => %s, %s", address, value, self.content[address*8:address*8+32]) self.value_line.update(value) - _on_change(self.address_line.get(), None) + + _on_change(None, None) self.address_line.add_change_handler(_on_change) def parse(self, content: str): diff --git a/planner/sim/programs/ping_pong.py b/planner/sim/programs/ping_pong.py index d87c1f8..120a82c 100644 --- a/planner/sim/programs/ping_pong.py +++ b/planner/sim/programs/ping_pong.py @@ -21,10 +21,14 @@ def start(): bsrom_binary = get_asm_binary(BOOTSEQUENCE_PATH) program_binary = get_asm_binary(PROGRAM_PATH) - _bin = bin_parser.BinRunner(bsrom_binary) + clock = devices.Clock() + ram = devices.RAM() + brom = devices.ROM("brom", bsrom_binary) + + _bin = bin_parser.BinRunner(clock, ram, brom) gui_manager = gui_devices.GUIDeviceManager() - prom = devices.ProgramROM("prom", program_binary) + prom = devices.ROM("prom", program_binary) _bin.set_output_device(2, prom.address_line) _bin.set_input_device(2, prom.value_line) @@ -43,7 +47,11 @@ def start(): _bin.set_output_device(6, display.get_anodes()[0]) _bin.set_output_device(7, display.get_cathodes()[0]) + clock.start() + # for _ in range(8): + # clock.tick() + # clock.tick() - processor = Thread(None, step_runner, None, (_bin, )) - processor.start() + # processor = Thread(None, step_runner, None, (_bin, )) + # processor.start() gui_manager.draw_loop() diff --git a/planner/util.py b/planner/util.py index 5696997..8f26938 100644 --- a/planner/util.py +++ b/planner/util.py @@ -1,4 +1,6 @@ import string +from typing import List + LABEL_CONSTANT = "constant" LABEL_TMP = "__tmp__" @@ -14,13 +16,24 @@ def is_valid_label(msg): return False return set(msg) <= set(string.ascii_uppercase + string.ascii_lowercase + string.digits + "_") -def to_big_32binary(val): +def to_big_32binary(val: int): return f"{val:032b}" -def to_little_32binary(val): +def to_little_32binary(val: int): big = to_big_32binary(val) return ''.join([big[i*8:(i+1)*8] for i in range(4)[::-1]]) -def from_little_32binary(little): +def to_little_32binaryarray(value: int): + arr_value = [] + for i in range(4): + arr_value.append(value&255) + value>>=8 + return arr_value + +def from_little_32binary(little: str): assert len(little) == 32 return sum([int(little[i*8:(i+1)*8],2)<<(8*i) for i in range(4)]) + +def from_littlearray_32binary(little: List[int]): + assert len(little) == 4 + return sum([little[i]<<(8*i) for i in range(4)]) diff --git a/programs/boot_sequence.asm b/programs/boot_sequence.asm index 14de9af..fcce3a0 100644 --- a/programs/boot_sequence.asm +++ b/programs/boot_sequence.asm @@ -7,7 +7,7 @@ PROM_ADDRESS_LINE equ 2 # input(2) = PROGRAM_ROM value PROM_VALUE_LINE equ 2 -PROGRAM_ORG equ 0x30 +PROGRAM_ORG equ 0x34 RAM_PROGRAM_ORG equ 0x80 ROM_INPUT_VALUE equ 0x0 From 4bdfef984f0b51c66fe32ebdb60003d9712a5686 Mon Sep 17 00:00:00 2001 From: Gagan Kumar Date: Wed, 18 Dec 2024 18:12:53 -0800 Subject: [PATCH 4/5] Fixed tests with bs_rom --- planner/memory.py | 1 - planner/sim/bin_parser.py | 5 +-- planner/sim/bin_parser_test.py | 63 +++++++++++++++++++++---------- planner/sim/devices.py | 13 +++++-- planner/sim/programs/ping_pong.py | 14 +------ planner/util.py | 2 + 6 files changed, 60 insertions(+), 38 deletions(-) diff --git a/planner/memory.py b/planner/memory.py index 5ecc1ab..b1706d6 100644 --- a/planner/memory.py +++ b/planner/memory.py @@ -21,5 +21,4 @@ def get_register_address(index): BOOTSEQUENCE_ORG = 0x34 # as we have 4-byte rom size header at top # user program - DEFAULT_PROGRAM_ORG = 0x80 diff --git a/planner/sim/bin_parser.py b/planner/sim/bin_parser.py index 5c25175..6ca5e05 100644 --- a/planner/sim/bin_parser.py +++ b/planner/sim/bin_parser.py @@ -153,9 +153,8 @@ def m_alu(self, rw: int, r: int, op: instruction.ALU): assert r>=0 and r<(1<<32) return instruction.ALU.execute(op, rw, r) - def run_until_hlt(self): - while self.is_powered_on: - self.step() + def is_power_on(self): + return self.is_powered_on def is_boot_sequence(self): return self.pc >= memory.BOOTSEQUENCE_ORG and self.pc < memory.DEFAULT_PROGRAM_ORG diff --git a/planner/sim/bin_parser_test.py b/planner/sim/bin_parser_test.py index bf1c329..1e7dced 100644 --- a/planner/sim/bin_parser_test.py +++ b/planner/sim/bin_parser_test.py @@ -1,7 +1,19 @@ from planner.asm import program_parser from planner.sim import bin_parser from planner.sim import devices +from planner import util, memory from unittest import TestCase +from typing import List + + +def get_asm_binary_from_lines(lines: List[str]): + asm = program_parser.AsmParser() + asm.parse_lines(lines) + return asm.get_str(resolved=True, rom_binary=True) + +def get_asm_binary_from_file(fname: str): + with open(fname, "r") as f: + return get_asm_binary_from_lines(f.readlines()) class BinParserTest(TestCase): @@ -9,27 +21,40 @@ class BinParserTest(TestCase): FAKE_OUPUT_AT = 0x06 def setUp(self) -> None: - self.asm = program_parser.AsmParser() + self.clock = devices.Clock() + ram = devices.RAM() + + bsrom_binary = get_asm_binary_from_file(util.BOOTSEQUENCE_PATH) + brom = devices.ROM("brom", bsrom_binary) + self.fake_input = devices.LatchInput("fake", bits=32) self.fake_ouput = devices.Device(bits=32) - self.bin = None - - def execute(self, program: str): - self.asm.parse_lines(program.splitlines()) - binary_program = self.asm.get_str(resolved=True, rom_binary=True) - self.bin = bin_parser.BinRunner(binary_program) + self.bin = bin_parser.BinRunner(self.clock, ram, brom) self.bin.set_input_device(self.FAKE_INPUT_AT, self.fake_input) self.bin.set_output_device(self.FAKE_OUPUT_AT, self.fake_ouput) - self.bin.run_until_hlt() + + + def execute(self, program: str): + program_binary = get_asm_binary_from_lines(program.splitlines()) + + prom = devices.ROM("prom", program_binary) + self.bin.set_output_device(2, prom.address_line) + self.bin.set_input_device(2, prom.value_line) + + self.clock.start() + while self.bin.is_power_on(): + pass + # wait for hlt + self.clock.stop() def get_ram_byte(self, address: int): - return self.bin.read_ram(address, 1)[0] + return self.bin.read_ram(address, 4)[0] def test_io(self): self.fake_input.set_input(10) self.execute(f""" - PROGRAM_ORG equ 0x40 + PROGRAM_ORG equ {memory.DEFAULT_PROGRAM_ORG} section .text main: in R0, {self.FAKE_INPUT_AT} @@ -40,7 +65,7 @@ def test_io(self): def test_mov(self): self.execute(f""" - PROGRAM_ORG equ 0x40 + PROGRAM_ORG equ {memory.DEFAULT_PROGRAM_ORG} section .text main: movc R0, 0x45 @@ -53,7 +78,7 @@ def test_mov(self): def test_simple_alu(self): self.execute(f""" - PROGRAM_ORG equ 0x40 + PROGRAM_ORG equ {memory.DEFAULT_PROGRAM_ORG} section .text main: movc R0, 1 @@ -85,7 +110,7 @@ def test_simple_alu(self): def test_simple_aluc(self): self.execute(f""" - PROGRAM_ORG equ 0x40 + PROGRAM_ORG equ {memory.DEFAULT_PROGRAM_ORG} section .text main: movc R1, 9 @@ -117,7 +142,7 @@ def test_simple_aluc(self): def test_stack(self): self.fake_input.set_input(45) self.execute(f""" - PROGRAM_ORG equ 0x40 + PROGRAM_ORG equ {memory.DEFAULT_PROGRAM_ORG} section .text main: @@ -133,7 +158,7 @@ def test_stack(self): def test_jmp(self): self.fake_input.set_input(45) self.execute(f""" - PROGRAM_ORG equ 0x40 + PROGRAM_ORG equ {memory.DEFAULT_PROGRAM_ORG} section .text main: @@ -172,7 +197,7 @@ def test_jmp(self): def test_data_section(self): self.execute(f""" - PROGRAM_ORG equ 0x40 + PROGRAM_ORG equ {memory.DEFAULT_PROGRAM_ORG} section .text main: shlc [array_0], 2 @@ -193,7 +218,7 @@ def test_data_section(self): def test_bss_section(self): self.execute(f""" - PROGRAM_ORG equ 0x40 + PROGRAM_ORG equ {memory.DEFAULT_PROGRAM_ORG} section .text main: movc R0, array_end @@ -210,7 +235,7 @@ def test_bss_section(self): def test_load_store(self): self.execute(f""" - PROGRAM_ORG equ 0x40 + PROGRAM_ORG equ {memory.DEFAULT_PROGRAM_ORG} section .text main: movc [array_ptr], array_0 @@ -237,7 +262,7 @@ def test_load_store(self): def test_call(self): self.fake_input.set_input(45) self.execute(f""" - PROGRAM_ORG equ 0x40 + PROGRAM_ORG equ {memory.DEFAULT_PROGRAM_ORG} section .text main: diff --git a/planner/sim/devices.py b/planner/sim/devices.py index 6ceb1ba..39ef8d8 100644 --- a/planner/sim/devices.py +++ b/planner/sim/devices.py @@ -77,13 +77,20 @@ def __init__(self): super(Clock, self).__init__(bits=1) self.name = "clock" self.update(0) - self.thread = Thread(None, self.steps) + self.running_thread = None def start(self): - self.thread.start() + assert self.running_thread is None + self.running_thread = Thread(None, self.steps) + self.running_thread.start() + + def stop(self): + t = self.running_thread + self.running_thread = None + t.join() def steps(self,): - while True: + while self.running_thread: # full speed self.tick() diff --git a/planner/sim/programs/ping_pong.py b/planner/sim/programs/ping_pong.py index 120a82c..568a643 100644 --- a/planner/sim/programs/ping_pong.py +++ b/planner/sim/programs/ping_pong.py @@ -1,14 +1,10 @@ from planner.asm import program_parser from planner.sim import bin_parser, devices, gui_devices -from threading import Thread +from planner import util import pygame -BOOTSEQUENCE_PATH = "programs/boot_sequence.asm" PROGRAM_PATH = "programs/ping_pong.asm" -def step_runner(_bin): - while True: - _bin.step() def get_asm_binary(fname: str): asm = program_parser.AsmParser() @@ -18,7 +14,7 @@ def get_asm_binary(fname: str): def start(): - bsrom_binary = get_asm_binary(BOOTSEQUENCE_PATH) + bsrom_binary = get_asm_binary(util.BOOTSEQUENCE_PATH) program_binary = get_asm_binary(PROGRAM_PATH) clock = devices.Clock() @@ -48,10 +44,4 @@ def start(): _bin.set_output_device(7, display.get_cathodes()[0]) clock.start() - # for _ in range(8): - # clock.tick() - # clock.tick() - - # processor = Thread(None, step_runner, None, (_bin, )) - # processor.start() gui_manager.draw_loop() diff --git a/planner/util.py b/planner/util.py index 8f26938..3dd7c37 100644 --- a/planner/util.py +++ b/planner/util.py @@ -1,10 +1,12 @@ import string from typing import List +BOOTSEQUENCE_PATH = "programs/boot_sequence.asm" LABEL_CONSTANT = "constant" LABEL_TMP = "__tmp__" + def is_valid_label(msg): if len(msg) == 0: return False From 2b2dd1f918a91d4bbaba99c965ea71ed0a62c0ab Mon Sep 17 00:00:00 2001 From: Gagan Kumar Date: Wed, 18 Dec 2024 18:44:10 -0800 Subject: [PATCH 5/5] Update README.md --- README.md | 95 +++++++++++-------------------------------------------- 1 file changed, 19 insertions(+), 76 deletions(-) diff --git a/README.md b/README.md index a8d5e04..38b2928 100644 --- a/README.md +++ b/README.md @@ -12,85 +12,28 @@ The eventual goal(?) is to build a general-purpose processor integrated with sim * Generate resolved assembly: `python3 -m planner asm -r programs/ping_pong.asm` [[example](output/programs/ping_pong_resolved.asm)] * Generate binary: `python3 -m planner asm -b programs/ping_pong.asm` [[example](output/programs/ping_pong.bin)] * Run on emulator: `python3 -m planner compile_and_execute ping_pong` + * 16x8 LED display with W/S/Up/Down keyboard controller + * ![image](https://github.com/user-attachments/assets/9fa2f68f-73ae-465c-a29c-cc92b0dc421a) ## Design -This section is not up-to date. - ### Specs -* Address Line: 16-bits +* Memory Address Line: 16-bits (points to a byte) +* Memory Value Line: 32-bits (4 bytes) * Max Memory: 64KB - -### Constants - -* INSZ = 0x20, independent input bytes -* OUTSZ = 0x20, independent output bytes -* IPC = 0x0100, intial value of `PC` (or Program Counter). - -### Memory Allocation - -* `RAM[0:INSZ]` is mapped to I/O module input -* `RAM[INSZ:OUTSZ]` is mapped to I/O module output -* `RAM[IPC:IPC+x]` is loaded from ROM. So it essentially contains `.text`, `.data`. - -### Sequencing - - -* At boot - * Load `ROM[0:x]` into `RAM[IPC:IPC+x]` - * TODO: How? - -### Assembly - -* `.bss` must be the last section. -* Registers don't really exists. `R[0-7]` are mapped to memory location in `.bss` for convenience and some instructions return response. - -### Architecture - -#### I/O - -Hardware interact asynchronously with IOM (I/O Module) which then interact with RAM at program's will. (WE ARE NOT DOING IT) - -* Input devices publish state change in IOM and Output devices read from IOM. -* Program use `IN ` instructions to read from `IOM_in[index]` and write to `RAM[index]`. `IOM_in` won't cache input and it will be read as real-time value. If a input state needs to be cached, it's the input device responsibility. -* Program use `OUT ` instructions to read `RAM[INSZ+index]` and write to `IOM_out[index]`. - - - -# TODO - -## Processor - -* Address bits: 8 -* Register size: 8 -* Memory size: 2**8 = 256 bytes - -### Idea - -To keep number of component small, we would split a single instruction execution period into 4 cycles. - -* Reset - * Set `PC = 0` - * sub-cycle clock to cycle-0 -* Cycle 0 - * Fetch instruction from `ROM[$PC]` into `pin_INS` -* Cycle 1 - * Perform first read - -## Assembler - -### Details - -* Registers: R0, R1, R2, R3 or `R{NUM}` - -* Input/Output pin: IO0, IO1, ..., IO7 or `IO{NUM}` (8-bits) - -### Instructions - -* `IN R{NUM}`: short-blocking input with 8-bit response. -* `OUT R{NUM}`: short-blocking 8-bit output. - -## Syntax: High Level - -Not yet defined. +* Memory layout: [here](planner/memory.py) + +#### Boot Sequence +* `programs/boot_sequence.asm` binary (aka `BROM`) is mapped from address_line `BOOTSEQUENCE_LOAD = 0x30` +* Memory Read + * If `BOOTSEQUENCE_ORG <= address_line < DEFAULT_PROGRAM_ORG`, pulls value from `BROM` + * Otherwise, pulls the value from `RAM` +* Execution starts with `PC` at `BOOTSEQUENCE_ORG = 0x34` +* `BROM` goal is to copy `PROM` to RAM at `DEFAULT_PROGRAM_ORG = 0x80` +* Followed by `jmp DEFAULT_PROGRAM_ORG` + +#### PROM +* Programs like `programs/ping_pong.asm` are translated into binary and are referred to as `PROM`. +* `PROM` is connected to as input-output device. +* The equivalent program is loaded in RAM at `DEFAULT_PROGRAM_ORG = 0x80`, followed by execution after boot sequence.