144 lines
4.9 KiB
Python
144 lines
4.9 KiB
Python
|
#!/usr/bin/env python3
|
||
|
|
||
|
import struct
|
||
|
|
||
|
|
||
|
OP = [
|
||
|
# Mnemonic, mask, value, xmask, ymask, kmask, klabel
|
||
|
('CLS', '',
|
||
|
0xffff, 0x00e0, 0x0000, 0x0000, 0x0000, False),
|
||
|
('RET', '',
|
||
|
0xffff, 0x00ee, 0x0000, 0x0000, 0x0000, False),
|
||
|
('SYS', '{k}',
|
||
|
0xf000, 0x0000, 0x0000, 0x0000, 0x0fff, True),
|
||
|
('JP', '{k}',
|
||
|
0xf000, 0x1000, 0x0000, 0x0000, 0x0fff, True),
|
||
|
('CALL', '{k}',
|
||
|
0xf000, 0x2000, 0x0000, 0x0000, 0x0fff, True),
|
||
|
('SE', 'V{x:01x}, {k:02x}',
|
||
|
0xf000, 0x3000, 0x0f00, 0x0000, 0x00ff, False),
|
||
|
('SNE', 'V{x:01x}, {k:02x}',
|
||
|
0xf000, 0x4000, 0x0f00, 0x0000, 0x00ff, False),
|
||
|
('SE', 'V{x:01x}, V{y:01x}',
|
||
|
0xf00f, 0x5000, 0x0f00, 0x00f0, 0x0000, False),
|
||
|
('LD', 'V{x:01x}, {k:02x}',
|
||
|
0xf000, 0x6000, 0x0f00, 0x0000, 0x00ff, False),
|
||
|
('ADD', 'V{x:01x}, {k:02x}',
|
||
|
0xf000, 0x7000, 0x0f00, 0x0000, 0x00ff, False),
|
||
|
('LD', 'V{x:01x}, V{y:01x}',
|
||
|
0xf00f, 0x8000, 0x0f00, 0x00f0, 0x0000, False),
|
||
|
('OR', 'V{x:01x}, V{y:01x}',
|
||
|
0xf00f, 0x8001, 0x0f00, 0x00f0, 0x0000, False),
|
||
|
('AND', 'V{x:01x}, V{y:01x}',
|
||
|
0xf00f, 0x8002, 0x0f00, 0x00f0, 0x0000, False),
|
||
|
('XOR', 'V{x:01x}, V{y:01x}',
|
||
|
0xf00f, 0x8003, 0x0f00, 0x00f0, 0x0000, False),
|
||
|
('ADD', 'V{x:01x}, V{y:01x}',
|
||
|
0xf00f, 0x8004, 0x0f00, 0x00f0, 0x0000, False),
|
||
|
('SUB', 'V{x:01x}, V{y:01x}',
|
||
|
0xf00f, 0x8005, 0x0f00, 0x00f0, 0x0000, False),
|
||
|
('SHR', 'V{x:01x}, V{y:01x}',
|
||
|
0xf00f, 0x8006, 0x0f00, 0x00f0, 0x0000, False),
|
||
|
('SHL', 'V{x:01x}, V{y:01x}',
|
||
|
0xf00f, 0x800e, 0x0f00, 0x00f0, 0x0000, False),
|
||
|
('SNE', 'V{x:01x}, V{y:01x}',
|
||
|
0xf00f, 0x9000, 0x0f00, 0x00f0, 0x0000, False),
|
||
|
('LD', 'I, {k}',
|
||
|
0xf000, 0xa000, 0x0000, 0x0000, 0x0fff, True),
|
||
|
('JP', 'V0, {k}',
|
||
|
0xf000, 0xb000, 0x0000, 0x0000, 0x0fff, True),
|
||
|
('RND', 'V{x:01x}, {k:02x}',
|
||
|
0xf000, 0xc000, 0x0f00, 0x0000, 0x00ff, False),
|
||
|
('DRW', 'V{x:01x}, V{y:01x}, {k:02x}',
|
||
|
0xf000, 0xd000, 0x0f00, 0x00f0, 0x000f, False),
|
||
|
('SKP', 'V{x:01x}',
|
||
|
0xf0ff, 0xe09e, 0x0f00, 0x0000, 0x0000, False),
|
||
|
('SKNP', 'V{x:01x}',
|
||
|
0xf0ff, 0xe0a1, 0x0f00, 0x0000, 0x0000, False),
|
||
|
('LD', 'V{x:01x}, DT',
|
||
|
0xf0ff, 0xf007, 0x0f00, 0x0000, 0x0000, False),
|
||
|
('LD', 'V{x:01x}, K',
|
||
|
0xf0ff, 0xf00a, 0x0f00, 0x0000, 0x0000, False),
|
||
|
('LD', 'DT, V{x:01x}',
|
||
|
0xf0ff, 0xf015, 0x0f00, 0x0000, 0x0000, False),
|
||
|
('LD', 'ST, V{x:01x}',
|
||
|
0xf0ff, 0xf018, 0x0f00, 0x0000, 0x0000, False),
|
||
|
('ADD', 'I, V{x:01x}',
|
||
|
0xf0ff, 0xf01e, 0x0f00, 0x0000, 0x0000, False),
|
||
|
('LD', 'F, V{x:01x}',
|
||
|
0xf0ff, 0xf029, 0x0f00, 0x0000, 0x0000, False),
|
||
|
('LD', 'B, V{x:01x}',
|
||
|
0xf0ff, 0xf033, 0x0f00, 0x0000, 0x0000, False),
|
||
|
('LD', '[I], V{x:01x}',
|
||
|
0xf0ff, 0xf055, 0x0f00, 0x0000, 0x0000, False),
|
||
|
('LD', 'V{x:01x}, [I]',
|
||
|
0xf0ff, 0xf065, 0x0f00, 0x0000, 0x0000, False),
|
||
|
|
||
|
|
||
|
('DATA', '{k:04x}',
|
||
|
0x0000, 0x0000, 0x0000, 0x0000, 0xffff, False)
|
||
|
]
|
||
|
|
||
|
|
||
|
def c8decode(ins):
|
||
|
|
||
|
def _unmask(v, m):
|
||
|
if m == 0:
|
||
|
return None
|
||
|
r = v & m
|
||
|
while (m & 1) == 0:
|
||
|
m >>= 1
|
||
|
r >>= 1
|
||
|
return r
|
||
|
|
||
|
for mn, fmt, mask, value, xmask, ymask, kmask, klabel in OP:
|
||
|
if (ins & mask) == value:
|
||
|
xo = _unmask(ins, xmask)
|
||
|
yo = _unmask(ins, ymask)
|
||
|
ko = _unmask(ins, kmask)
|
||
|
return (mn, fmt, xo, yo, ko, klabel)
|
||
|
|
||
|
|
||
|
def disasm(filename, org=0x200):
|
||
|
pc = org
|
||
|
targets = set()
|
||
|
listing = []
|
||
|
with open(filename, 'rb') as f:
|
||
|
while True:
|
||
|
w = f.read(2)
|
||
|
if len(w) != 2:
|
||
|
break
|
||
|
instr = struct.unpack('>H', w)[0]
|
||
|
mn, fmt, xo, yo, ko, klabel = c8decode(instr)
|
||
|
if klabel:
|
||
|
targets.add(ko)
|
||
|
listing.append((pc, instr, mn, fmt, xo, yo, ko, klabel))
|
||
|
pc += 2
|
||
|
end = pc
|
||
|
|
||
|
print(f""";
|
||
|
; {filename}
|
||
|
; start={org:03x} end={end:03x} size={end-org}(dec)
|
||
|
;
|
||
|
""")
|
||
|
for pc, instr, mn, fmt, xo, yo, ko, klabel in listing:
|
||
|
if pc in targets:
|
||
|
label = "l%03x" % (pc,)
|
||
|
else:
|
||
|
label = ""
|
||
|
if klabel:
|
||
|
if org <= ko <= end:
|
||
|
ko = f"l{ko:03x}"
|
||
|
else:
|
||
|
ko = f"{ko:03x}"
|
||
|
o = fmt.format(x=xo, y=yo, k=ko)
|
||
|
print(f"{label:8s} {mn:5s} {o:12s} ; {pc:03x}: {instr:04x}")
|
||
|
|
||
|
|
||
|
if __name__ == '__main__':
|
||
|
import sys
|
||
|
|
||
|
for fn in sys.argv[1:]:
|
||
|
disasm(fn)
|
||
|
|