diff options
| author | Jan Tuomi <jans.tuomi@gmail.com> | 2023-04-10 17:30:25 +0300 |
|---|---|---|
| committer | Jan Tuomi <jans.tuomi@gmail.com> | 2023-04-10 17:30:25 +0300 |
| commit | 56fd37c60eb0d58ed4762340ddc85b74347bcd71 (patch) | |
| tree | d4d6362cb591ddb9658536d831f8c4433089189f | |
| parent | 16b4fbd209d71bdb1a066bacd03a9ccd1cf3d16c (diff) | |
Do stuff
| -rw-r--r-- | digital/atk16.dig | 8 | ||||
| -rw-r--r-- | digital/atk16_mem.dig | 6 | ||||
| -rwxr-xr-x | src/assembler.py | 38 | ||||
| -rw-r--r-- | src/assembler_eval.py | 15 | ||||
| -rw-r--r-- | src/assembler_ops.py | 56 | ||||
| -rw-r--r-- | src/ext_std.py | 24 | ||||
| -rw-r--r-- | src/test_fibo.atk16 | 19 |
7 files changed, 89 insertions, 77 deletions
diff --git a/digital/atk16.dig b/digital/atk16.dig index 914baab..1345925 100644 --- a/digital/atk16.dig +++ b/digital/atk16.dig @@ -791,10 +791,10 @@ ,c,221,88,90,8000,0,0,0,c,221,88,90,8000,0,0,0,c,221,840,8000 ,4*0,c,221,840,8000,4*0,c,221,82,8000,4*0,c,221,82,8000,4*0,c ,221,902,8000,4*0,c,221,902,8000,4*0,c,221,8000,5*0,c,221,82,8000 -,4*0,c,221,8000,5*0,c,221,902,8000,4*0,c,221,8000,5*0,c,221,8000 -,5*0,c,221,8000,5*0,c,221,8000,5*0,c,221,8000,5*0,c,221,8000,5*0 -,c,221,8000,5*0,c,221,8000,5*0,c,221,8000,5*0,c,221,8000,5*0,c -,221,8000,5*0,c,221,8000,5*0,c,221,4000,5*0,c,221,4000</data> +,4*0,c,221,8000,5*0,c,221,902,8000,4*0,c,221,44,8000,4*0,c,221 +,44,8000,4*0,c,221,8000,5*0,c,221,8000,5*0,c,221,8000,5*0,c,221 +,8000,5*0,c,221,8000,5*0,c,221,8000,5*0,c,221,8000,5*0,c,221,8000 +,5*0,c,221,8000,5*0,c,221,8000,5*0,c,221,4000,5*0,c,221,4000</data> </entry> </elementAttributes> <pos x="780" y="280"/> diff --git a/digital/atk16_mem.dig b/digital/atk16_mem.dig index e3f3bc2..0a1b0e8 100644 --- a/digital/atk16_mem.dig +++ b/digital/atk16_mem.dig @@ -67,8 +67,10 @@ </entry> <entry> <string>Data</string> - <data>6001,8000,420a,4414,650,4801,2900,38c0,12c0,441e,651,8402,4202 -,f000,4201,f000</data> + <data>420a,9c00,3dc0,1fc8,6004,f000,35c0,1fc8,37c0,1fc8,4602,259,8609 +,39c0,1fc8,3bc0,1fc8,4a01,4400,4601,898,14c0,1700,269,8400,5ff6 +,1fc9,27c0,1fc9,25c0,1fc9,2dc0,5180,2840,1fc9,2bc0,1fc9,29c0,1fc9 +,27c0,1fc9,25c0,1fc9,2dc0,5180</data> </entry> </elementAttributes> <pos x="740" y="100"/> diff --git a/src/assembler.py b/src/assembler.py index 8a53a5c..a4ddde4 100755 --- a/src/assembler.py +++ b/src/assembler.py @@ -48,11 +48,7 @@ def parse(line: str) -> list[str]: return list(filter(lambda x: len(x) > 0, result)) # 1st pass, gather labels, set options, eval operations - -options: dict[str, str] = { - "stack_pointer": "6", # RG - "csr_scratch": "5", # RF -} +options = Options() address: int = 0 for (lineNo, line) in enumerate(src_lines): @@ -65,11 +61,14 @@ for (lineNo, line) in enumerate(src_lines): continue case "@label": labels[args[0]] = address + # todo bugi: 1st pass ei ota monirivisiä käskyjä huomioon continue case "@opt": - opt_name = args[0] - opt_value = constants.get(args[1], args[1]) - options[opt_name] = opt_value + opt_name, opt_value = args + match opt_name: + case "stack_pointer": options.stack_pointer = opt_value + case "csr_scratch": options.csr_scratch = opt_value + case _: raise Exception("Unknown @opt: " + opt_name) case "@use": module_name, ops = args[0].split(":") ops_split = ops.split(",") @@ -86,13 +85,6 @@ for (lineNo, line) in enumerate(src_lines): # 2nd pass -# def make_spu(reg: str) -> list[int]: -# stack_pointer = options["stack_pointer"] -# reg = eval_symbol(reg) -# words_inc: list[int] = make_inc(stack_pointer, stack_pointer) -# words_str: list[int] = make_str(reg, stack_pointer) -# return words_inc + words_str - address: int = 0 nop = bytearray([0b1000_0000, 0]) result = bytearray() @@ -104,8 +96,12 @@ for (lineNo, line) in enumerate(src_lines): if line == "": continue keyword, *args = parse(line.lower()) + meta = Meta( + address=address, + options=options + ) if keyword in operations: - words = operations[keyword](address, *args) + words = operations[keyword](meta, *args) else: match keyword: # Directives @@ -122,18 +118,20 @@ for (lineNo, line) in enumerate(src_lines): except: raise Exception(f"Invalid assembly at {infile_path}:{lineNo + 1}\n\n{line}") - if len(result) < 2 * address + 1: - result.extend((2 * address + 1 - len(result)) * nop) - for (label, label_addr) in labels.items(): if address == label_addr: print(f"{label}:") + line_printed = False for word in words: - print(f"{address:>08x} 0x{word:>04x} {line}") + if len(result) < 2 * address + 1: + result.extend((2 * address + 1 - len(result)) * nop) + + print(f"{address:>08x} 0x{word:>04x} {line if not line_printed else '...'}") result[2 * address + 0] = ((word >> 8) & 0xff) result[2 * address + 1] = ((word >> 0) & 0xff) address += 1 + line_printed = True with open(outfile_path, "wb") as f: f.write(result) diff --git a/src/assembler_eval.py b/src/assembler_eval.py index 7255572..07f22e7 100644 --- a/src/assembler_eval.py +++ b/src/assembler_eval.py @@ -5,8 +5,9 @@ constants: dict[str, str] = { "rb": "2", "rc": "3", "rd": "4", - "rf": "5", - "rg": "6", + "re": "5", + "rf": "6", + "rg": "7", # ALU instructions "al_plus": "0", "al_minus": "1", @@ -25,6 +26,10 @@ constants: dict[str, str] = { labels: dict[str, int] = {} +def check_size(bits: int, val: int) -> None: + if val >= 2 ** bits: + raise Exception(f"Value does not fit in {bits} bits: {val}") + def eval_symbol(c: str) -> str: if c in labels: return str(labels[c]) @@ -34,6 +39,8 @@ def eval_symbol(c: str) -> str: return c -def eval_expr(expr: str) -> int: +def eval_expr(expr: str, bits: int = 16) -> int: expr = eval_symbol(expr) - return eval(expr, labels.copy()) # eval as Python expr + ret = eval(expr, labels.copy()) # eval as Python expr + check_size(bits, ret) + return ret diff --git a/src/assembler_ops.py b/src/assembler_ops.py index 0177140..2313bfd 100644 --- a/src/assembler_ops.py +++ b/src/assembler_ops.py @@ -3,16 +3,21 @@ from assembler_eval import * from dataclasses import dataclass @dataclass +class Options: + stack_pointer = "RG" + csr_scratch = "RF" + +@dataclass class Meta: address: int - options: dict[str, str] + options: Options def make_alr(meta: Meta, alu_op: str, left: str, right: str, target: str) -> list[int]: """ALR 0000 TTTL LLRR RSSS""" - target_e = eval_expr(target) - left_e = eval_expr(left) - right_e = eval_expr(right) - alu_op_e = eval_expr(alu_op) + target_e = eval_expr(target, bits=3) + left_e = eval_expr(left, bits=3) + right_e = eval_expr(right, bits=3) + alu_op_e = eval_expr(alu_op, bits=3) word = (0b0000 << 12) + \ (target_e << 9) + \ (left_e << 6) + \ @@ -22,12 +27,10 @@ def make_alr(meta: Meta, alu_op: str, left: str, right: str, target: str) -> lis def make_ali(meta: Meta, alu_op: str, left: str, imm: str, target: str) -> list[int]: """ALI 0001 TTTL LLII ISSS""" - target_e = eval_expr(target) - left_e = eval_expr(left) - imm_e = eval_expr(imm) - if imm_e >= 2**3: - raise Exception("ALI immediate value does not fit in 3 bits: " + str(imm_e)) - alu_op_e = eval_expr(alu_op) + target_e = eval_expr(target, bits=3) + left_e = eval_expr(left, bits=3) + imm_e = eval_expr(imm, bits=3) + alu_op_e = eval_expr(alu_op, bits=3) word = (0b0001 << 12) + \ (target_e << 9) + \ (left_e << 6) + \ @@ -37,8 +40,8 @@ def make_ali(meta: Meta, alu_op: str, left: str, imm: str, target: str) -> list[ def make_ldr(meta: Meta, to_reg: str, addr_reg: str) -> list[int]: """LDR 0010 TTTR RRXX XXXX""" - to_reg_e = eval_expr(to_reg) - addr_reg_e = eval_expr(addr_reg) + to_reg_e = eval_expr(to_reg, bits=3) + addr_reg_e = eval_expr(addr_reg, bits=3) word = (0b0010 << 12) + \ (to_reg_e << 9) + \ (addr_reg_e << 6) @@ -46,8 +49,8 @@ def make_ldr(meta: Meta, to_reg: str, addr_reg: str) -> list[int]: def make_str(meta: Meta, from_reg: str, addr_reg: str) -> list[int]: """STR 0011 TTTR RRXX XXXX""" - from_reg_e = eval_expr(from_reg) - addr_reg_e = eval_expr(addr_reg) + from_reg_e = eval_expr(from_reg, bits=3) + addr_reg_e = eval_expr(addr_reg, bits=3) word = (0b0011 << 12) + \ (from_reg_e << 9) + \ (addr_reg_e << 6) @@ -55,8 +58,8 @@ def make_str(meta: Meta, from_reg: str, addr_reg: str) -> list[int]: def make_ldi(meta: Meta, to_reg: str, imm: str) -> list[int]: """LDI 0100 TTTI IIII IIII""" - to_reg_e = eval_expr(to_reg) - imm_e = eval_expr(imm) + to_reg_e = eval_expr(to_reg, bits=3) + imm_e = eval_expr(imm, bits=9) word = (0b0100 << 12) + \ (to_reg_e << 9) + \ imm_e @@ -64,26 +67,23 @@ def make_ldi(meta: Meta, to_reg: str, imm: str) -> list[int]: def make_jpr(meta: Meta, addr_reg: str) -> list[int]: """JPR 0101 XXXR RRXX XXXX""" - addr_reg_e = eval_expr(addr_reg) + addr_reg_e = eval_expr(addr_reg, bits=3) word = (0b0101 << 12) + \ (addr_reg_e << 6) return [word] def make_jpi(meta: Meta, imm: str) -> list[int]: """JPI 0110 XXXI IIII IIII""" - imm_e = eval_expr(imm) + imm_e = eval_expr(imm, bits=9) imm_e = imm_e - meta.address - 1 - if imm_e >= 2**9: - raise Exception("JPI relative value does not fit in 9 bits: " + str(imm_e)) - word = (0b0110 << 12) + \ imm_e return [word] def make_brr(meta: Meta, flag_s: str, addr_reg: str) -> list[int]: """brr 0111 XFFR RRXX XXXX""" - flag_s_e = eval_expr(flag_s) - addr_reg_e = eval_expr(addr_reg) + flag_s_e = eval_expr(flag_s, bits=2) + addr_reg_e = eval_expr(addr_reg, bits=3) word = (0b0111 << 12) + \ (flag_s_e << 9) + \ (addr_reg_e << 6) @@ -91,11 +91,9 @@ def make_brr(meta: Meta, flag_s: str, addr_reg: str) -> list[int]: def make_bri(meta: Meta, flag_s: str, imm: str) -> list[int]: """BRI 1000 XFFI IIII IIII""" - flag_s_e = eval_expr(flag_s) - imm_e = eval_expr(imm) + flag_s_e = eval_expr(flag_s, bits=2) + imm_e = eval_expr(imm, bits=9) imm_e = imm_e - meta.address - 1 - if imm_e >= 2**9: - raise Exception("BRI relative value does not fit in 9 bits: " + str(imm_e)) word = (0b1000 << 12) + \ (flag_s_e << 9) + \ imm_e @@ -103,7 +101,7 @@ def make_bri(meta: Meta, flag_s: str, imm: str) -> list[int]: def make_lpc(meta: Meta, target: str) -> list[int]: """LPC 1001 TTTX XXXX XXXX""" - target_e = eval_expr(target) + target_e = eval_expr(target, bits=3) word = (0b1001 << 12) + \ (target_e << 9) return [word] diff --git a/src/ext_std.py b/src/ext_std.py index c0a53c1..e78f5cc 100644 --- a/src/ext_std.py +++ b/src/ext_std.py @@ -6,6 +6,12 @@ def make_add(meta: Meta, left: str, right: str, target: str) -> list[int]: def make_sub(meta: Meta, left: str, right: str, target: str) -> list[int]: return make_alr(meta, "al_minus", left, right, target) +def make_addi(meta: Meta, left: str, imm: str, target: str) -> list[int]: + return make_ali(meta, "al_plus", left, imm, target) + +def make_subi(meta: Meta, left: str, imm: str, target: str) -> list[int]: + return make_ali(meta, "al_minus", left, imm, target) + def make_and(meta: Meta, left: str, right: str, target: str) -> list[int]: return make_alr(meta, "al_and", left, right, target) @@ -43,37 +49,39 @@ def make_mov(meta: Meta, from_reg: str, to_reg: str) -> list[int]: return make_ali(meta, "al_plus", from_reg, "0", to_reg) def make_spu(meta: Meta, reg: str) -> list[int]: - sp_reg = meta.options["stack_pointer"] + sp_reg = meta.options.stack_pointer str_word = make_str(meta, reg, sp_reg) inc_word = make_inc(meta, sp_reg) return str_word + inc_word def make_spo(meta: Meta, reg: str) -> list[int]: - sp_reg = meta.options["stack_pointer"] + sp_reg = meta.options.stack_pointer dec_word = make_dec(meta, sp_reg) ldr_word = make_ldr(meta, reg, sp_reg) return dec_word + ldr_word def make_csr(meta: Meta, addr_reg: str) -> list[int]: - lpc_word = make_lpc(meta, meta.options["csr_scratch"]) - spu_word = make_spu(meta, meta.options["csr_scratch"]) + lpc_word = make_lpc(meta, meta.options.csr_scratch) + spu_word = make_spu(meta, meta.options.csr_scratch) jpr_word = make_jpr(meta, addr_reg) return lpc_word + spu_word + jpr_word def make_csi(meta: Meta, addr_imm: str) -> list[int]: - lpc_word = make_lpc(meta, meta.options["csr_scratch"]) - spu_word = make_spu(meta, meta.options["csr_scratch"]) + lpc_word = make_lpc(meta, meta.options.csr_scratch) + spu_word = make_spu(meta, meta.options.csr_scratch) jpi_word = make_jpi(meta, addr_imm) return lpc_word + spu_word + jpi_word def make_rsr(meta: Meta) -> list[int]: - spo_word = make_spo(meta, meta.options["csr_scratch"]) - jpr_word = make_jpr(meta, meta.options["csr_scratch"]) + spo_word = make_spo(meta, meta.options.csr_scratch) + jpr_word = make_jpr(meta, meta.options.csr_scratch) return spo_word + jpr_word operations = { "add": make_add, "sub": make_sub, + "addi": make_addi, + "subi": make_subi, "and": make_and, "or": make_or, "xor": make_xor, diff --git a/src/test_fibo.atk16 b/src/test_fibo.atk16 index 7f1abb9..a03f14b 100644 --- a/src/test_fibo.atk16 +++ b/src/test_fibo.atk16 @@ -1,9 +1,12 @@ @opt stack_pointer RG +@opt csr_scratch RF + +@use ext_std:* @label program ; call fibo subroutine with parameter 10 ldi RA 10 - csr fibo + csi fibo hlt @label fibo @@ -13,24 +16,21 @@ ; return value: ; RA fibo(n) : u16 - spu RB ; prelude + spu RB ; prelude spu RC - ldi RC 2 ; if n < 2, return n - sub RA RC RA + subi RA 2 RA ; if n < 2, return n bri f_sign fibo_early spu RD ; prelude - spu RE - ldi RE 1 ; constant 1 ldi RB 0 ; a = 0 ldi RC 1 ; b = 1 @label fibo_loop add RB RC RD ; v = a + b mov RC RB ; a = b mov RD RC ; b = v - sub RA RE RA ; n -= 1 + dec RA ; n -= 1 bri f_zero fibo_done ; loop while n > 0 jpi fibo_loop @@ -39,9 +39,8 @@ spo RB rsr @label fibo_done - ldr RD RA - spo RE - spo RD + mov RD RA + spo RD ; restore registers spo RC spo RB rsr |
