#!/usr/bin/env python3 import sys if len(sys.argv) != 2: print(f"Usage: {sys.argv[0]} [filename]") sys.exit(1) def decode_jump(ins: int) -> str: if (ins & 0x7) == 0: return "" if (ins & 0x7) == 0x7: return "; j" jl = (ins & (1 << 2)) != 0 je = (ins & (1 << 1)) != 0 jg = (ins & (1 << 0)) != 0 # implied: and not jg if jl and je: return "; jle" # implied: and not je if jl and jg: return "; jne" # implied: and not je if je and jg: return "; jge" # implied: only one flag is 1 if jl: return "; jl" if je: return "; je" if jg: return "; jg" return "; " # 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", 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}" else: 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()