diff options
| author | uvok | 2026-01-05 14:27:14 +0100 |
|---|---|---|
| committer | uvok | 2026-01-05 14:27:14 +0100 |
| commit | 572e9f8d21896bf266bd88895dc1056576f6de2c (patch) | |
| tree | 89a5df8fa3858d739fa032946238d3bf158b2201 /nandgame/assembler | |
| parent | f0ea83ca7a5342d7cb1bdebeda7b80c1e4392543 (diff) | |
Canonicalize ops
Diffstat (limited to 'nandgame/assembler')
| -rwxr-xr-x | nandgame/assembler/disas.py | 52 |
1 files changed, 40 insertions, 12 deletions
diff --git a/nandgame/assembler/disas.py b/nandgame/assembler/disas.py index cabdcdd..607537a 100755 --- a/nandgame/assembler/disas.py +++ b/nandgame/assembler/disas.py @@ -11,11 +11,13 @@ import sys ZERO = "#0" DEST_NONE = "_" +JUMP_NONE = "" def decode_jump(ins: int) -> str: if (ins & 0x7) == 0: - return "" + return JUMP_NONE + if (ins & 0x7) == 0x7: return "jmp" @@ -111,7 +113,7 @@ def decode_dest(ins: int) -> str: return dest if dest else DEST_NONE -def decode_instruction_complete(ins: int) -> list[str]: +def decode_instruction(ins: int) -> list[str]: """ Will return a 5 element list/tuple/whatever mnemonic, destination, X, Y, jumpdest @@ -120,27 +122,45 @@ def decode_instruction_complete(ins: int) -> list[str]: # mov? ldr? ldi? aaaaaaaaaaa.... return ["mov", "A", f"#{ins}", "", ""] else: - codename, two_op = decode_ins(ins) + mnemonic, two_op = decode_ins(ins) dest = decode_dest(ins) op1 = decode_arg1(ins) op2 = decode_arg2(ins) if two_op else "" jumpdest = decode_jump(ins) + return [mnemonic, dest, op1, op2, jumpdest] + - # fixups - if op1 == ZERO and codename == "sub": - return ["neg", dest, op2, "", jumpdest] +def fixup_ins(ins: int) -> list[str]: + (mnemonic, dest, op1, op2, jumpdest) = decode_instruction(ins) + # fixups + # subtract something from #0 - subtraction + if op1 == ZERO and mnemonic == "sub": + return ["neg", dest, op2, "", jumpdest] - return [codename, dest, op1, op2, jumpdest] + # 0 AND something = 0 + # if no dest, only jump matters + if mnemonic == "and" and op1 == ZERO and dest == DEST_NONE: + # jump always or jump-if-zero --> always jump + if jumpdest in ["jgt", "jlt", "jne", JUMP_NONE]: + return ["nop", "", "", "", ""] + # all other jumps? <=, >=, =, <=> + else: + return ["jmp", "", "", "", ""] + return [mnemonic, dest, op1, op2, jumpdest] -def print_decoded(ins: int) -> str: - (codename, dest, op1, op2, jumpdest) = decode_instruction_complete(ins) + +def print_decoded(ins: int, simplify: bool) -> str: + if simplify: + (mnemonic, dest, op1, op2, jumpdest) = fixup_ins(ins) + else: + (mnemonic, dest, op1, op2, jumpdest) = decode_instruction(ins) jumpdest_str = f".{jumpdest}" if jumpdest else "" - opcode_str = f"{codename}{jumpdest_str}" + opcode_str = f"{mnemonic}{jumpdest_str}" dest_str = f"{dest}, " if dest else 7 * " " op1_str = f"{op1}{", " if op2 else ""}" - return f"{opcode_str:<9}{dest_str:<6}{op1_str:<4}{op2:<5}" + return f"{opcode_str:<9}{dest_str:<6}{op1_str:<4}{op2}" def main(): @@ -156,7 +176,15 @@ def main(): if not insb: break ins = int.from_bytes(insb) - print(f"\t{insb[0]:02x} {insb[1]:02x}\t{print_decoded(ins)}") + raw_ins = f"{insb[0]:02x} {insb[1]:02x}" + decoded_ins = print_decoded(ins, False) + decoded_ins2 = print_decoded(ins, True) + if decoded_ins == decoded_ins2: + line = f"\t{raw_ins}\t{decoded_ins}" + else: + line = f"\t{raw_ins}\t{decoded_ins2:<25}; {decoded_ins}" + + print(line) except FileNotFoundError: print(f"File {filename} not found.") |
