From ff1536ddf9c70b9b98c5332c193ad099a103162d Mon Sep 17 00:00:00 2001 From: yenatch Date: Thu, 1 Aug 2013 14:54:33 -0400 Subject: [PATCH] refactor symfile parser and add labels.json generator --- extras/sym.py | 128 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 87 insertions(+), 41 deletions(-) diff --git a/extras/sym.py b/extras/sym.py index cc580fa67..b866ec87f 100644 --- a/extras/sym.py +++ b/extras/sym.py @@ -1,54 +1,100 @@ -# -*- coding: utf-8 -*- +# coding: utf-8 +import os +import sys import json -# from crystal import load_rom -# from gbz80disasm import load_labels - def make_sym_from_json(filename = '../pokecrystal.sym', j = 'labels.json'): - # todo: delete and remake labels.json at runtime - with open(filename, 'w') as sym: - for label in json.load(open(j)): - sym.write('{0:x}:{1:x} {2}\n'.format(label['bank'], label['address']%0x4000 + (0x4000 if label['bank'] else 0), label['label'])) - - -def make_sym_from_mapfile(filename = '../pokecrystal.sym', mapfile = '../mapfile.txt'): - # todo: sort label definitions by address - output = '' - # get label definitions - with open(mapfile,'r') as map: + labels = json.load(open(j)) + for label in labels: + output += '{0:x}:{1:x} {2}\n'.format(label['bank'], label['address'], label['label']) + with open(filename, 'w') as sym: + sym.write(output) + + +def make_json_from_mapfile(filename = 'labels.json', mapfile = '../pokecrystal.map'): + output = [] + labels = filter_wram_addresses(read_mapfile(mapfile)) + with open(filename, 'w') as out: + out.write(json.dumps(labels)) + + +def read_mapfile(filename = '../pokecrystal.map'): + """ + Scrape label addresses from an rgbds mapfile. + """ + + labels = [] + + with open(filename,'r') as map: lines = map.readlines() - for line in lines: - # bank # - if 'Bank #' in line: - cur_bank = int(line.lstrip('Bank #').strip(':\n').strip(' (HOME)')) - - # label definition - elif '=' in line: - thing = line.split('=') - spacing = ' ' * 11 # arbitrary - addr = int(thing[0].lstrip(spacing)[1:5],16) - - # rgbds doesn't support wram banks yet, - # so this hack is applied instead - if addr > 0xbfff: # 0xc000+ (wram only) - cur_bank = 0 - if addr > 0xcfff: # 0xd000+ (wram only) - cur_bank = 1 - - # convert to sym format (bank:addr label) - label = thing[1].strip('\n') - output += hex(cur_bank)[2:] + ':' + hex(addr)[2:] + ' ' + label + '\n' - + + for line in lines: + # bank # + if 'Bank #' in line: + cur_bank = int(line.lstrip('Bank #').strip(':\n').strip(' (HOME)')) + + # label definition + elif '=' in line: + address, label = line.split('=') + address = int(address.lstrip().replace('$','0x'), 16) + label = label.strip() + + # rgbds doesn't support ram banks yet + bank = cur_bank + offset = address + if 0x8000 <= address < 0xa000: + bank = 0 + elif 0xa000 <= address < 0xc000: + bank = 0 + elif 0xc000 <= address < 0xd000: + bank = 0 + elif 0xd000 <= address < 0xe000: + bank = 0 + else: + offset += (bank * 0x4000 - 0x4000) if bank > 0 else 0 + + labels += [{ + 'label': label, + 'bank': bank, + 'address': offset, + 'offset': offset, + 'local_address': address, + }] + + return labels + +def filter_wram_addresses(labels): + filtered_labels = [] + for label in labels: + if label['local_address'] < 0x8000: + filtered_labels += [label] + return filtered_labels + + +def make_sym_from_mapfile(filename = '../pokecrystal.sym'): + # todo: sort label definitions by address + + output = '' + labels = read_mapfile() + + # convert to sym format (bank:addr label) + for label in labels: + output += '%.2x:%.4x %s\n' % (label['bank'], label['address'], label['label']) + # dump contents to symfile with open(filename, 'w') as sym: sym.write(output) if __name__ == "__main__": - # default behavior: generate sym file from rgbds mapfile - try: make_sym_from_mapfile() - # if no mapfile exists, generate from labels.json - except: make_sym_from_json() + #if os.path.exists('../pokecrystal.sym'): + # sys.exit() + #elif os.path.exists('../pokecrystal.map'): + # make_sym_from_mapfile() + #elif os.path.exists('labels.json'): + # make_sym_from_json() + make_json_from_mapfile() +