nxu/extract-v2.py

81 lines
2.1 KiB
Python

#!/usr/bin/env python
# currently only extracts text metadata
import sys
def error(msg):
print(msg)
sys.exit(1)
def parsestr(data, start):
end = start + data[start:].find(b'\0')
return end + 1, data[start:end].decode('ascii')
def parsefields(data, pos0):
pos1, name = parsestr(data, pos0)
pos2, version = parsestr(data, pos1)
pos3, author = parsestr(data, pos2)
pos4, desc = parsestr(data, pos3)
return {'name': name, 'version': version, 'author': author, 'desc': desc}
def parse(data, pos0):
if len(data[pos0:]) < 6:
raise Exception('not enough data!')
a,b,c,d,e,f = data[pos0:pos0+6]
if a != 0xa0 or d != 0x80 or f != 0x37:
return None
else:
return (e, b, c)
def toaddr(x, y):
return x * 256 + y - 256
def main():
if len(sys.argv[1:]) != 1:
print('usage: %s ROMFILE' % sys.argv[0])
sys.exit(1)
f = open(sys.argv[1], 'rb')
data = f.read()
f.close()
if len(data) < 6:
return error("file too small: %d bytes" % len(data))
(kind, x, y) = parse(data, 0)
if kind != 0xf0:
head = ''.join(['%02x' % n for n in data[0:6]])
return error("file should start with 'a0____804037' but got %r" % head)
icon_type = None
icon_data = None
i = 6
while True:
res = parse(data, i)
if res is None:
break
i += 6
kind, x, y = res
xy = '%02x%02x' % (x, y)
if kind == 0xf2:
fields = parsefields(data, toaddr(x, y))
print('fields: %r' % fields)
elif kind == 0xf4:
icon_type = x * 256 - y
print('icon type: %s' % xy)
elif kind == 0xf6:
# TODO: extract icon data as BMP or similar
print('icon data at %s' % xy)
elif kind == 0xf8:
print('maximum memory address is %s' % xy)
elif kind == 0xfa:
# TODO: parse manifest structure
print('manifest data at %s' % xy)
else:
print('unknown field: %02x (%s)' % (kind, xy))
if __name__ == "__main__":
main()