From f5823cfc933058198d0bc46a8622226d9fc0d6a4 Mon Sep 17 00:00:00 2001 From: Christian Vogelgsang Date: Sat, 7 Dec 2024 18:23:01 +0100 Subject: [PATCH] added roms to state support --- amitools/state/__init__.py | 2 +- amitools/state/asfparser.py | 43 +++++++++++++++++++++++++++++++---- amitools/vamos/tools/state.py | 10 +++++++- test/unit/asf_parser.py | 6 ++++- 4 files changed, 54 insertions(+), 7 deletions(-) diff --git a/amitools/state/__init__.py b/amitools/state/__init__.py index efa33789..1a0756ef 100644 --- a/amitools/state/__init__.py +++ b/amitools/state/__init__.py @@ -1,2 +1,2 @@ from .asffile import ASFFile -from .asfparser import ASFParser, MemChunk, MemType +from .asfparser import ASFParser, MemChunk, MemType, ROMChunk diff --git a/amitools/state/asfparser.py b/amitools/state/asfparser.py index 77e002b7..1d83dbaf 100644 --- a/amitools/state/asfparser.py +++ b/amitools/state/asfparser.py @@ -22,7 +22,7 @@ class MemChunk: @dataclass -class Expansion: +class ExpansionRAM: z2ram_base: int z3ram_base: int gfx_base: int @@ -30,17 +30,29 @@ class Expansion: z2ram_base2: int +@dataclass +class ROMChunk: + address: int + size: int + type: int + version: int + crc32: int + name: str + path: str + data: bytes = None + + class ASFParser: def __init__(self, asf_file): self.asf_file = asf_file - def get_expansion(self): + def get_expansion_ram(self): data = self.asf_file.load_chunk("EXPA") if not data: return None assert len(data) >= 5 * 4 z2b, z3b, gfx, boro, z2b2 = struct.unpack(">IIIII", data) - return Expansion(z2b, z3b, gfx, boro, z2b2) + return ExpansionRAM(z2b, z3b, gfx, boro, z2b2) def get_ram_layout(self, load_ram=False): layout = [] @@ -62,7 +74,7 @@ def get_ram_layout(self, load_ram=False): if a3khi: layout.append(a3khi) # z2ram/z3ram - expansion = self.get_expansion() + expansion = self.get_expansion_ram() if expansion: # z2ram z2rams = self._get_all_mem_chunks("FRAM", MemType.Z2RAM, load_ram) @@ -75,6 +87,7 @@ def get_ram_layout(self, load_ram=False): z2ram = z2rams[1] z2ram.address = expansion.z2ram_base2 layout.append(z2ram) + assert n < 3 # z2ram z3rams = self._get_all_mem_chunks("ZRAM", MemType.Z3RAM, load_ram) n = len(z3rams) @@ -82,8 +95,30 @@ def get_ram_layout(self, load_ram=False): z3ram = z3rams[0] z3ram.address = expansion.z3ram_base layout.append(z3ram) + assert n < 2 return layout + def get_roms(self): + datas = self.asf_file.load_all_chunks("ROM ") + if datas: + return list(map(lambda x: self._parse_rom(x), datas)) + + def _parse_rom(self, data): + addr, size, type, ver, crc = struct.unpack_from(">IIIII", data) + offset = 5 * 4 + name, offset = self.asf_file._read_string(data, offset) + path, offset = self.asf_file._read_string(data, offset) + chunk = ROMChunk(addr, size, type, ver, crc, name, path) + + # hack for missing start addr + if chunk.address == 0 and chunk.type == 1: + chunk.address = 0xF00000 + + # in place ROM? + if len(data) > offset: + chunk.data = data[offset:] + return chunk + def _get_all_mem_chunks(self, tag, type, load_ram): result = [] if load_ram: diff --git a/amitools/vamos/tools/state.py b/amitools/vamos/tools/state.py index 0c3e2dfd..0c226952 100644 --- a/amitools/vamos/tools/state.py +++ b/amitools/vamos/tools/state.py @@ -36,7 +36,7 @@ def run(self, args): # dump expansion if args.dump: - expansion = parser.get_expansion() + expansion = parser.get_expansion_ram() if expansion: print(expansion) @@ -55,4 +55,12 @@ def run(self, args): f"@{ram.address:08x} +{ram.size:08x} {ram.type.name:6s} {file}" ) + # show roms + print("ROM:") + roms = parser.get_roms() + for rom in roms: + print( + f"@{rom.address:08x} +{rom.size:08x} {rom.crc32:08x} {rom.name} {rom.path}" + ) + return 0 diff --git a/test/unit/asf_parser.py b/test/unit/asf_parser.py index 511a03a4..c04f7018 100644 --- a/test/unit/asf_parser.py +++ b/test/unit/asf_parser.py @@ -1,5 +1,5 @@ import pytest -from amitools.state import ASFFile, ASFParser, MemChunk, MemType +from amitools.state import ASFFile, ASFParser, MemChunk, MemType, ROMChunk ASF_LIST = ( "a500.uss", @@ -22,6 +22,10 @@ def asf_parser_test(asf_file): assert len(ram) > 0 ram2 = parser.get_ram_layout(True) assert len(ram) == len(ram2) + roms = parser.get_roms() + assert len(roms) == 2 + assert roms[0].address == 0xF80000 + assert roms[1].address == 0xF00000 def asf_parser_mem_layout_a500_test():