summaryrefslogtreecommitdiff
path: root/tools/map2link.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/map2link.py')
-rw-r--r--tools/map2link.py187
1 files changed, 0 insertions, 187 deletions
diff --git a/tools/map2link.py b/tools/map2link.py
deleted file mode 100644
index f1cd3a3..0000000
--- a/tools/map2link.py
+++ /dev/null
@@ -1,187 +0,0 @@
-#!/bin/python3.6
-
-import argparse
-import re
-import sys
-from collections import OrderedDict
-
-
-class MapFile:
- LINETYPE_BLANK = -1
- LINETYPE_BANK = 0
- LINETYPE_SECTION = 1
- LINETYPE_SYMBOL = 2
- LINETYPE_SLACK = 3
- LINETYPE_EMPTY = 4
-
- bank_types = ('ROM', 'VRAM', 'SRAM', 'WRAM', 'OAM', 'HRAM')
- bank_starts = (0x4000, 0x8000, 0xa000, 0xd000, 0xfe00, 0xff80)
-
- class MapFileLine:
- def __init__(self, linestr):
- self.raw = linestr
-
- def __str__(self):
- return self.raw
-
- class BlankLine(MapFileLine):
- def __init__(self, linestr):
- super().__init__(linestr)
-
- class BankLine(MapFileLine):
- def __init__(self, linestr):
- super().__init__(linestr)
- match = re.search('#(\d+)', linestr, re.I)
- if match is None:
- self.bankno = 0
- else:
- self.bankno = int(match.group(1))
- bankname = linestr.split()[0].rstrip(':')
- try:
- self.banktype = MapFile.bank_types.index(bankname)
- except ValueError as e:
- raise ValueError(f'Unrecognized bank type: {bankname}') from e
-
- @property
- def name(self):
- if self.banktype == 0: # ROM
- if self.bankno == 0:
- return 'ROM0'
- else:
- return f'ROMX ${self.bankno:02x}'
- elif self.banktype == 3: # WRAM
- if self.bankno == 0:
- return 'WRAM0'
- else:
- return f'WRAMX ${self.bankno:02x}'
- elif self.banktype < 3:
- return f'{MapFile.bank_types[self.banktype]} {self.bankno:d}'
- else:
- return f'{MapFile.bank_types[self.banktype]}'
-
- @property
- def start(self):
- if self.bankno == 0:
- if self.banktype == 0:
- return 0x0000
- elif self.banktype == 3:
- return 0xc000
- return MapFile.bank_starts[self.banktype]
-
- def __hash__(self):
- return hash(self.name)
-
- class SectionLine(MapFileLine):
- def __init__(self, linestr):
- super().__init__(linestr)
- match = re.search(r'\$([0-9A-F]{4}) \(\$([0-9A-F]+) bytes\) \["(.+)"\]', linestr, re.I)
- end, size, self.name = match.groups()
- self.end = int(end, 16)
- self.size = int(size, 16)
- if self.size > 0:
- self.end += 1
- self.start = self.end - self.size
- self.symbols = []
-
- class SymbolLine(MapFileLine):
- def __init__(self, linestr):
- super().__init__(linestr)
-
- class SlackLine(MapFileLine):
- def __init__(self, linestr):
- super().__init__(linestr)
- match = re.search(r'\$([0-9A-F]{4}) bytes', linestr, re.I)
- self.slack = int(match.group(1), 16)
-
- class EmptyLine(MapFileLine):
- def __init__(self, linestr):
- super().__init__(linestr)
-
- line_classes = {
- LINETYPE_BLANK: BlankLine,
- LINETYPE_BANK: BankLine,
- LINETYPE_SECTION: SectionLine,
- LINETYPE_SYMBOL: SymbolLine,
- LINETYPE_SLACK: SlackLine,
- LINETYPE_EMPTY: EmptyLine
- }
-
- def __init__(self, fname, *fpargs, **fpkwargs):
- self.fname = fname
- self.fp = None
- self.fpargs = fpargs
- self.fpkwargs = fpkwargs
-
- def open(self):
- if self.fp is None or self.fp.closed:
- self.fp = open(self.fname, *self.fpargs, **self.fpkwargs)
-
- def close(self):
- if not self.fp.closed:
- self.fp.close()
- self.fp = None
-
- def __enter__(self):
- self.open()
- return self
-
- def __exit__(self, exc_type, exc_val, exc_tb):
- self.fp.__exit__(exc_type, exc_val, exc_tb)
- self.fp = None
-
- def __iter__(self):
- if self.fp is None or self.fp.closed:
- print('Warning: Cowardly refusing to read closed file', file=sys.stderr)
- raise StopIteration
- for line in self.fp:
- linestr = line.strip('\n')
- if linestr == '':
- line_type = self.LINETYPE_BLANK
- elif 'SECTION:' in linestr:
- line_type = self.LINETYPE_SECTION
- elif 'SLACK:' in linestr:
- line_type = self.LINETYPE_SLACK
- elif linestr == ' EMPTY':
- line_type = self.LINETYPE_EMPTY
- elif ' = ' in linestr:
- line_type = self.LINETYPE_SYMBOL
- else:
- line_type = self.LINETYPE_BANK
- yield self.line_classes[line_type](linestr)
-
-
-def main():
- parser = argparse.ArgumentParser()
- parser.add_argument('mapfile', type=MapFile)
- parser.add_argument('linkfile', type=argparse.FileType('w'))
- args = parser.parse_args()
-
- rom_map = OrderedDict()
- cur_bank = None
-
- print('; Automatically generated by map2link.py', file=args.linkfile)
-
- with args.mapfile:
- for line in args.mapfile:
- if isinstance(line, MapFile.BankLine):
- cur_bank = line
- rom_map[cur_bank] = []
- elif isinstance(line, MapFile.SectionLine):
- rom_map[cur_bank].append(line)
-
- for bank, sections in rom_map.items():
- if len(sections) == 0:
- continue
- sections.sort(key=lambda s: s.start)
- print(bank.name, file=args.linkfile)
- start = bank.start
- for section in sections:
- if section.start > start:
- print(f'\t; ${start:04x}', file=args.linkfile)
- print(f'\torg ${section.start:04x}', file=args.linkfile)
- print(f'\t"{section.name}" ; ${section.start:04x}, size: ${section.size:04x}', file=args.linkfile)
- start = section.end
-
-
-if __name__ == '__main__':
- main()