mirror of
https://github.com/elliotnunn/ToolboxToolbox.git
synced 2025-01-19 18:30:08 +00:00
107 lines
2.5 KiB
Python
Executable File
107 lines
2.5 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
import sys
|
|
import struct
|
|
from os import path
|
|
import re
|
|
|
|
biglist = []
|
|
|
|
|
|
def could_be_rom(lb):
|
|
if not lb: return False
|
|
if lb == 0x300000: return True # special supermario case!
|
|
|
|
while not (lb & 1):
|
|
lb >>= 1
|
|
if lb != 1: return False
|
|
|
|
return True
|
|
|
|
|
|
for rompath in sys.argv[1:]:
|
|
try:
|
|
if not could_be_rom(path.getsize(rompath)): continue
|
|
rom = open(rompath, 'rb').read()
|
|
except IsADirectoryError:
|
|
continue
|
|
|
|
info = []
|
|
|
|
a, = struct.unpack_from('>H', rom, 8)
|
|
b, = struct.unpack_from('>H', rom, 18)
|
|
|
|
|
|
order = a << 64
|
|
|
|
|
|
if a == 0x69:
|
|
info.append('Original')
|
|
elif a == 0x75:
|
|
info.append('Plus')
|
|
elif a == 0x178:
|
|
info.append('II')
|
|
elif a == 0x276:
|
|
info.append('SE')
|
|
elif a == 0x37a:
|
|
info.append('Portable')
|
|
elif a == 0x67c:
|
|
info.append('IIci')
|
|
if rom[18] == 0x15:
|
|
order += 1 << 63
|
|
info.append('TERROR')
|
|
elif rom[18] == 0x17:
|
|
order += 2 << 63
|
|
info.append('Zydeco')
|
|
elif rom[20] & 1:
|
|
order += 3 << 63
|
|
info.append('Horror')
|
|
|
|
elif a == 0x77d:
|
|
info.append('SuperMario')
|
|
else:
|
|
order = 0
|
|
info.append('?-%X' % a)
|
|
|
|
if a >= 0x300:
|
|
info.append('Rel-%04x' % b)
|
|
order += b << 32
|
|
|
|
if a == 0x77d: # SuperMario
|
|
info.append('SubVer-%x' % struct.unpack_from('>H', rom, 0x4c))
|
|
order += struct.unpack_from('>H', rom, 0x4c)[0]
|
|
|
|
|
|
if a == 0x67c:
|
|
if b >= 0x12f1: info.append("EricksonSndMgr")
|
|
if b == 0x12f1: info.append("EricksonMistake")
|
|
|
|
if b'\x08.netBOOT' in rom:
|
|
info.append('netBOOT')
|
|
|
|
drvrs = re.finditer(rb'\x04\.MPP', rom)
|
|
drvrs = [m.start() - 18 for m in drvrs] # the actual possible drvr starts
|
|
for ofs in drvrs:
|
|
if rom[ofs] == 0: continue
|
|
if any(rom[ofs+1:ofs+8]): continue
|
|
routine_offsets = struct.unpack_from('>HHHHH', rom, ofs+8)
|
|
for ent in routine_offsets:
|
|
if ent < 0x1a or ent % 2 != 0: break
|
|
else:
|
|
info.append('MPP=%d' % rom[ofs+24])
|
|
|
|
biglist.append((order, ' '.join(info), rompath, rom))
|
|
|
|
biglist.sort()
|
|
wid = max(len(s) for _, s, *_ in biglist)
|
|
|
|
rom_paths = {}
|
|
for o, s, p, rom in biglist:
|
|
rom_paths.setdefault(rom, [s]).append(p)
|
|
|
|
for rom, (s, *pp) in rom_paths.items():
|
|
left = s.ljust(wid)
|
|
for p in pp:
|
|
print(left + ' ' + p)
|
|
left = ' ' * wid
|