All pastes #917239 Raw Edit

FFL2 internal bytecode decompile

public python v1 · immutable
#917239 ·published 2008-02-25 05:59 UTC
rendered paste body
import sys, array## constants#state_assign = 1state_compare = 2state_done = 3## functions#def prettyip(ip):	return ("ROMC:%04X" % (ip + 0x4000 - 0x30000))def arg_standard(mode):	global ip	if mode in (0, 1, 2):		sys.stdout.write("@CF%02X.%c " % (data[ip], "bwl"[mode]))		ip += 1	elif mode in (3, 4):		sys.stdout.write("@(CF%02X).%c " % (data[ip], "bw"[mode - 3]))		ip += 1	elif mode == 5:		sys.stdout.write("RANDOM(0x%02X) " % data[ip])		ip += 1	elif mode == 6:		sys.stdout.write("0x%02X " % data[ip])		ip += 1	else:		sys.stdout.write("0x%04X " % (data[ip] + 0x100 * data[ip+1]))		ip += 2def arg_random(mode):	global ip, state, state_compare	sys.stdout.write("RANDOM(@CF%02X.b) " % data[ip])	if mode:		sys.stderr.write("%s: Modeless token has mode bits set; wtf?!\n" % prettyip(ip - 1))	if state == state_compare:		sys.stderr.write("%s: RANDOM(address) used in an IF statement; this doesn't work!\n" % prettyip(ip - 1))	ip += 1def arg_16bit(mode):	global ip	if mode in (0, 1, 2):		sys.stdout.write("@%04X.%c " % ((data[ip] + 0x100 * data[ip+1]), "bwl"[mode]))	elif mode in (3, 4):		sys.stdout.write("@(%04X).%c " % ((data[ip] + 0x100 * data[ip+1]), "bw"[mode - 3]))	else:		sys.stdout.write("@(%04X).l " % (data[ip] + 0x100 * data[ip+1]))		sys.stderr.write("%s: 16-bit address token has weird mode bits set; wtf?!\n" % prettyip(ip - 1))	ip += 2def arg_let(mode):	global ip	if mode in (0, 1, 2):		sys.stdout.write("@CF%02X.%c " % (data[ip], "bwl"[mode]))		ip += 1	elif mode in (3, 4):		sys.stdout.write("@(CF%02X).%c " % (data[ip], "bw"[mode - 3]))		ip += 1	else:		sys.stdout.write("@%04X.%c " % ((data[ip] + 0x100 * data[ip+1]), "bwl"[mode - 5]))		ip += 2def arg_jump(mode):	global ip	sys.stdout.write("%04X " % (data[ip] + 0x100 * data[ip+1]))	if mode:		sys.stderr.write("%s: Modeless token has mode bits set; wtf?!\n" % prettyip(ip - 1))	ip += 2def arg_incdec(mode):	global ip	if mode in (0, 1, 2):		sys.stdout.write("@CF%02X.%c " % (data[ip], "bwl"[mode]))	else:		sys.stdout.write("@CF%02X.l " % data[ip])		sys.stderr.write("%s: INC/DEC token has weird mode bits set; wtf?!\n" % prettyip(ip - 1))	ip += 1def arg_indirect(mode):	global ip	sys.stdout.write("@CF%02X " % data[ip])	if mode:		sys.stderr.write("%s: Modeless token has mode bits set; wtf?!\n" % prettyip(ip - 1))	ip += 1def arg_unknown(mode):	global ip	sys.stdout.write("%02X " % data[ip])	if mode:		sys.stderr.write("%s: Modeless token has mode bits set; wtf?!\n" % prettyip(ip - 1))	ip += 1def arg_none(mode):	if mode:		sys.stderr.write("%s: Argumentless token has mode bits set; wtf?!\n" % prettyip(ip - 1))def arg_illegal(mode):	sys.stderr.write("%s: Illegal token; looks like we hit data!\n" % prettyip(ip - 1))## token definitions#statement_tokens = (	("LET ",    arg_let,      state_assign),	("IF ",     arg_standard, state_compare),	("GOTO ",   arg_jump,     state_done),	("SYS ",    arg_jump,     state_done),	("SET ",    arg_unknown,  state_done),	("GOSUB ",  arg_jump,     state_done),	("RETURN ", arg_none,     state_done),	("INC ",    arg_incdec,   state_done),	("DEC ",    arg_incdec,   state_done),	("GOSUB ",  arg_indirect, state_done),	("??? ",    arg_illegal,  state_done),	("??? ",    arg_illegal,  state_done),	("??? ",    arg_illegal,  state_done),	("??? ",    arg_illegal,  state_done),	("??? ",    arg_illegal,  state_done),	("??? ",    arg_illegal,  state_done),	("??? ",    arg_illegal,  state_done),	("??? ",    arg_illegal,  state_done),	("??? ",    arg_illegal,  state_done),	("??? ",    arg_illegal,  state_done),	("??? ",    arg_illegal,  state_done),	("??? ",    arg_illegal,  state_done),	("??? ",    arg_illegal,  state_done),	("??? ",    arg_illegal,  state_done),	("??? ",    arg_illegal,  state_done),	("??? ",    arg_illegal,  state_done),	("??? ",    arg_illegal,  state_done),	("??? ",    arg_illegal,  state_done),	("??? ",    arg_illegal,  state_done),	("??? ",    arg_illegal,  state_done),	("??? ",    arg_illegal,  state_done),	("END ",    arg_none,     state_done))expression_tokens = (	("",      arg_standard, 0),	("* ",    arg_standard, 0),	("/ ",    arg_standard, 0),	("+ ",    arg_standard, 0),	("- ",    arg_standard, 0),	("AND ",  arg_standard, 0),	("OR ",   arg_standard, 0),	("NAND ", arg_standard, 0),	("XOR ",  arg_standard, 0),	("NOT ",  arg_standard, 0),	(">> ",   arg_standard, 0),	("<< ",   arg_standard, 0),	("= ",    arg_standard, 0),	("< ",    arg_standard, 0),	("> ",    arg_standard, 0),	("<= ",   arg_standard, 0),	(">= ",   arg_standard, 0),	("-- ",   arg_standard, 0),	("= ",    arg_random,   0),	("= ",    arg_16bit,    0),	("",      arg_standard, 0),	("",      arg_standard, 0),	("",      arg_standard, 0),	("",      arg_standard, 0),	("",      arg_standard, 0),	("",      arg_standard, 0),	("",      arg_standard, 0),	("",      arg_standard, 0),	("",      arg_standard, 0),	("",      arg_standard, 0),	("",      arg_standard, 0),	("",      arg_none, state_done))## main program#try:	fn      = sys.argv[1]	startip = int(sys.argv[2],0)	endip   = int(sys.argv[3],0)except (IndexError, ValueError):	sys.exit("Usage: debasic filename start end\n")f = open(fn, "rb")data = array.array('B')data.fromstring(f.read())f.close()ip = startipstate = state_donewhile ip <= endip:	sys.stdout.write("%s " % prettyip(ip))	token = data[ip] & 0x1F	mode = data[ip] >> 5	ip += 1	sys.stdout.write(statement_tokens[token][0])	statement_tokens[token][1](mode)	state = statement_tokens[token][2]	while state != state_done:		token = data[ip] & 0x1F		mode = data[ip] >> 5		ip += 1		sys.stdout.write(expression_tokens[token][0])		expression_tokens[token][1](mode)		if expression_tokens[token][2]: state = expression_tokens[token][2] 	sys.stdout.write("\n")