dcpu16/disasm.py

73 lines
2.1 KiB
Python
Executable File

#!/usr/bin/env python3
import struct
OPCODES = (
None , 'SET', 'ADD', 'SUB', 'MUL', 'MLI', 'DIV', 'DVI',
'MOD', 'MDI', 'AND', 'BOR', 'XOR', 'SHR', 'ASR', 'SHL',
'IFB', 'IFC', 'IFE', 'IFN', 'IFG', 'IFA', 'IFL', 'IFU',
None , None , 'ADX', 'SBX', None , None , 'STI', 'STD'
)
OPCODES_X = (
None , 'JSR', None , None , None , None , None , None ,
'INT', 'IAG', 'IAS', 'RFI', 'IAQ', None , None , None ,
'HWN', 'HWQ', 'HWI', None , None , None , None , None ,
None , None , None , None , None , None , None , None
)
ADDRESSING = (
'A', 'B', 'C', 'X', 'Y', 'Z', 'I', 'J',
'[A]', '[B]', '[C]', '[X]', '[Y]', '[Z]', '[I]', '[J]',
'[A+n]', '[B+n]', '[C+n]', '[X+n]', '[Y+n]', '[Z+n]', '[I+n]', '[J+n]',
'POP/PUSH', 'PEEK', 'PEEK n', 'SP', 'PC', 'EX', '[n]', 'n'
)
def read_word(f):
b = f.read(2)
if len(b) < 2:
raise EOFError()
return struct.unpack("<H", b)[0]
def disassemble(filename):
with open(filename, 'rb') as f:
pc = 0
while True:
try:
w = read_word(f)
except EOFError:
break
ins = [w]
op = w & 0x1f
b = (w >> 5) & 0x1f
a = (w >> 10) & 0x3f
if a < 0x20:
a_str = ADDRESSING[a]
if 'n' in a_str:
w = read_word(f)
ins.append(w)
a_str = a_str.replace('n', str(w))
else:
a_str = str(int(a) - 0x21)
a_str = a_str.split('/')[0]
if op == 0:
mnemonic = "%s %s" % (OPCODES_X[b], a_str)
else:
b_str = ADDRESSING[b]
if 'n' in b_str:
w = read_word(f)
ins.append(w)
b_str = b_str.replace('n', str(w))
b_str = b_str.split('/')[-1]
mnemonic = "%s %s, %s" % (OPCODES[op], b_str, a_str)
print("%5d:\t%-20s; %s" % (pc, mnemonic, ' '.join(["%04x" % x for x in ins])))
pc += len(ins)
if __name__ == '__main__':
import sys
if len(sys.argv) > 1:
disassemble(sys.argv[1])