From ee1b3cc0312d7b812345682e07039b02364bb550 Mon Sep 17 00:00:00 2001 From: uvok Date: Sun, 4 Jan 2026 16:56:30 +0100 Subject: disas: lowercase ops, arg decode main --- nandgame/assembler/disas.py | 113 ++++++++++++++++++++++++++++++-------------- 1 file changed, 78 insertions(+), 35 deletions(-) (limited to 'nandgame/assembler') diff --git a/nandgame/assembler/disas.py b/nandgame/assembler/disas.py index 402df5c..42c681a 100755 --- a/nandgame/assembler/disas.py +++ b/nandgame/assembler/disas.py @@ -30,49 +30,92 @@ def decode_jump(ins: int) -> str: return "; " - -def decode_ins(ins: int) -> str: +# return op, and whether it's a one-op or two-op +def decode_ins(ins: int) -> (str, bool): opcode = (ins >> 8) & 0x03 ar_n_log = (ins & (1<<10)) != 0 opcode |= (ar_n_log << 2) - if opcode == 0b000: return "AND" - if opcode == 0b001: return "OR" - if opcode == 0b010: return "XOR" - if opcode == 0b011: return "NEG" - if opcode == 0b100: return "ADD" - if opcode == 0b101: return "INC" - if opcode == 0b110: return "SUB" - if opcode == 0b111: return "DEC" + if opcode == 0b000: return "and", True + if opcode == 0b001: return "or", True + if opcode == 0b010: return "xor", True + if opcode == 0b011: return "neg", False + if opcode == 0b100: return "add", True + if opcode == 0b101: return "inc", False + if opcode == 0b110: return "sub", True + if opcode == 0b111: return "dec", False return "" +# normally, X = arg1 = D +def decode_arg1(ins: int) -> str: + use_mem = (ins & (1<<12)) != 0 + zx = (ins & (1<<7)) != 0 + sw = (ins & (1<<6)) != 0 + + if zx: return "0" +# and not sw? +# zx and swap: don't care, other arg is zeroed + + if not zx and not sw and not use_mem: return "A" + if not zx and not sw and use_mem: return "M" + + return "?" + +# normally, Y = arg2 = A +def decode_arg2(ins: int) -> str: + use_mem = (ins & (1<<12)) != 0 + zx = (ins & (1<<7)) != 0 + sw = (ins & (1<<6)) != 0 + + if zx and sw: return "0" + # zx and not swap: don't care, other arg is zeroed + + # zx ??? + if sw and not use_mem: return "A" + if sw and use_mem: return "M" + + return "?" + +def decode_dest(ins: int) -> str: + dA = (ins & (1<<5)) != 0 + dD = (ins & (1<<4)) != 0 + dM = (ins & (1<<3)) != 0 + dest_s = "" + if dA: dest_s += "A " + if dD: dest_s += "D " + if dM: dest_s += "M" + if dest_s: dest_s += ", " + return dest_s + def decode(ins: int) -> str: if (ins & 0x8000 == 0): # mov? ldr? ldi? aaaaaaaaaaa.... - return f"mov A, #{ins}" + return f"mov A, #{ins}" else: - use_mem = (ins & (1<<12)) != 0 - zx = (ins & (1<<7)) != 0 - sw = (ins & (1<<6)) != 0 - dA = (ins & (1<<5)) != 0 - dD = (ins & (1<<4)) != 0 - dM = (ins & (1<<3)) != 0 - - codename = decode_ins(ins) - return f"{codename:<5}{decode_jump(ins)}" - -try: - with open(sys.argv[1], "rb") as f: - while True: - insb = f.read(2) - if not insb: break - ins = int.from_bytes(insb) - print(f"\t{insb[0]:02x} {insb[1]:02x}\t{decode(ins)}") - -except FileNotFoundError: - print(f"File not found.") - sys.exit(1) -# head, tail... -except BrokenPipeError: - sys.exit(0) + dest_s = decode_dest(ins) + codename, two_op = decode_ins(ins) + op1 = decode_arg1(ins) + op2 = decode_arg2(ins) + + op2_s = f", {op2}" if two_op else "" + return f"{codename:<5}{dest_s:<8}{op1:<3}{op2_s:<5}{decode_jump(ins)}" + +def main(): + try: + with open(sys.argv[1], "rb") as f: + while True: + insb = f.read(2) + if not insb: break + ins = int.from_bytes(insb) + print(f"\t{insb[0]:02x} {insb[1]:02x}\t{decode(ins)}") + + except FileNotFoundError: + print(f"File not found.") + sys.exit(1) + # head, tail... + except BrokenPipeError: + sys.exit(0) + +if __name__ == "__main__": + main() -- cgit v1.2.3