ref: ff1536ddf9c70b9b98c5332c193ad099a103162d
parent: d39dc68a8836a10e728030961de88ddcb2ffffec
author: yenatch <[email protected]>
date: Thu Aug 1 10:54:33 EDT 2013
refactor symfile parser and add labels.json generator
--- a/extras/sym.py
+++ b/extras/sym.py
@@ -1,47 +1,89 @@
-# -*- 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
+ output = ''
+ 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:
- 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']))
+ sym.write(output)
-def make_sym_from_mapfile(filename = '../pokecrystal.sym', mapfile = '../mapfile.txt'):
+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:
+ 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 = ''
- # get label definitions
- with open(mapfile,'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'
-
+ 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)
@@ -48,7 +90,11 @@
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()
+