#!/usr/bin/python 'generate EQU statements for CALL, JMP, LOOP statements' import sys, os, re instruction_pattern = '^\( [0-9A-F]{4},[0-9A-F]{4} \)\s+' + \ '(J|CALL|LOOP|\S+).* ([0-9A-F-]+) \(R[BWL],\).*$' long_instruction_pattern = '^\( [0-9A-F]{4},[0-9A-F]{4} \)\s+' + \ '(J|CALL|LOOP|\S+).* 0020,([0-9A-F-]+) I?L,.*$' address_pattern = '^\( ([0-9A-F]{4}),([0-9A-F]{4}) \)\s+' equ_pattern = '^([0-9A-F]+) EQU ' names = {'J': 'skip', 'CALL': 'subr', 'LOOP': 'loop'} def readall(filename): file = open(filename) lines = map(str.strip, file.readlines()) file.close() return lines def append(filename, lines): newfile = readall(filename) for line in lines: if line not in newfile: insert(newfile, line) file = open(filename, 'w') file.writelines(map(lambda l: l + os.linesep, newfile)) file.close() def insert(lines, new): '''insert new EQU line in numeric order for this to work, you must have manually inserted at least one EQU''' newvalue = int(re.compile(equ_pattern).match(new).groups()[0], 16) for index in range(len(lines)): first = re.compile(equ_pattern).match(lines[index]) second = re.compile(equ_pattern).match(lines[index + 1]) if not first: continue else: first = int(first.groups()[0], 16) if second: second = int(second.groups()[0], 16) else: second = 0xffffffffL if newvalue < first: lines.insert(index, new) break elif newvalue < second: lines.insert(index + 1, new) break def genequ(asmfile, culfile = None, equates = []): lines = readall(asmfile) for index in range(len(lines)): line = lines[index] instruction_match = re.compile(instruction_pattern).match(line) long_instruction_match = None #long_instruction_match = re.compile(long_instruction_pattern).match(line) if instruction_match: if index + 1 < len(lines) and \ re.compile(address_pattern).match(lines[index + 1]): instr, offset = instruction_match.groups() address = re.compile(address_pattern).match(lines[index + 1]).groups() final_address = int(address[0], 16) * 0x10000 + \ int(address[1], 16) + int(offset, 16) addr = '%X' % final_address elif long_instruction_match: instr, address = long_instruction_match.groups() final_address = 0x200000 + int(address, 16) addr = '0020,%04X' % (final_address & 0xffff) if instruction_match or long_instruction_match: try: label = '%s%X' % (names[instr], final_address) except: label = '%s%X' % ('data', final_address) equ = '%s EQU %s' % (addr, label) if re.compile('^[ABCDEF]').match(equ): equ = '0' + equ equates.append(equ) if culfile: append(culfile, equates) else: print repr(equates) if __name__ == '__main__': sys.argv += ['', ''] genequ(sys.argv[1], sys.argv[2])