pet-plcc-multirom/mk27c040.py
2023-03-19 02:02:29 +01:00

72 lines
2.2 KiB
Python
Executable file

#!/usr/bin/env python3
import re
import sys
import argparse
ROMSIZE = 512 * 1024
class FileMap:
def __init__(self, base: int, filename: str):
self.base = base
self.filename = filename
with open(filename, 'rb') as f:
self.data = f.read()
if len(self.data) == 0:
raise AttributeError(f'File {filename} is empty')
if len(self.data) > 4096:
raise AttributeError(f'File {filename} exceeds 4KiB')
self.end = self.base + len(self.data)
if self.base < 0 or self.end > ROMSIZE:
raise AttributeError(f'File {filename} out of bounds: {hex(self.base)[2:]}:{hex(self.end-1)[2:]}')
if self.base & 0x0fff != 0:
raise AttributeError(f'File {filename} not aligned to 4KiB boundary: {hex(self.base)[2:]}:{hex(self.end-1)[2:]}')
@staticmethod
def at(base: int):
def _filemap(f):
return FileMap(base, f)
return _filemap
def baseimage(byte):
b = int(byte, 16)
return bytearray([b]) * ROMSIZE
def create_image(ns):
buf = ns.fill
used = {}
for m in ns.maps:
if m.base in used:
raise KeyError(f'{m.filename} and {used[m.base]} are both mapped at {hex(m.base)[2:]}')
used[m.base] = m.filename
buf[m.base:m.end] = m.data
with open(ns.output, 'wb') as f:
f.write(buf)
def main():
ap = argparse.ArgumentParser()
ap.add_argument('--output', '-o', type=str, metavar='FILE', default='27c040.bin', help='Write image to FILE (default: 27c040.bin)')
ap.add_argument('--<NNNNN>', type=ValueError, metavar='FILE', help='Map FILE at the 4KiB-aligned sector starting at hex-address NNNNN.')
ap.add_argument('--fill', '-f', type=baseimage, default='FF', help='Fill unmapped areas with this hex byte (default: FF)')
# https://stackoverflow.com/a/37367814
ns, unknown = ap.parse_known_args(sys.argv[1:])
for arg in unknown:
m = re.match('^--([0-9a-fA-F]{5})$', arg)
if m is None:
continue
base = int(m.group(1), 16)
ap.add_argument(arg, type=FileMap.at(base), dest='maps', action='append')
ns = ap.parse_args(sys.argv[1:])
create_image(ns)
if __name__ == '__main__':
main()