216. Parse ines rom
add
Lesson 216 of 356 · tests/chapter_02_rom_loading/test_216_parse_ines_rom.py
add emulator/cartridge/ines.py::parse_ines_rom.
Why this step exists
This function turns header claims into clean PRG/CHR slices so later Cartridge and mapper code never needs to understand iNES headers or trainer offsets. It uses all of the format constants and parser models from lessons 212-215.
Suggested implementation
def parse_ines_rom(data: bytes) -> INesRom:
header = parse_ines_header(data)
prg_size = header.prg_rom_banks * PRG_ROM_BANK_SIZE
chr_size = header.chr_rom_banks * CHR_ROM_BANK_SIZE
prg_start = INES_HEADER_SIZE + (
TRAINER_SIZE if header.has_trainer else 0
)
prg_end = prg_start + prg_size
chr_start = prg_end
chr_end = chr_start + chr_size
if len(data) < chr_end:
raise ValueError(
"iNES data is too short for declared PRG/CHR ROM"
)
return INesRom(
header=header,
prg_rom=data[prg_start:prg_end],
chr_rom=data[chr_start:chr_end],
)Invariants: sizes come from bank counts; PRG starts after the header and optional 512-byte trainer; CHR immediately follows PRG; and all declared bytes must exist before slicing. Do not rely on forgiving short Python slices, which would accept a truncated image silently.
Out of scope for this step
1. Extra trailing-byte policy and CHR RAM allocation are not introduced here.
2. Lesson 217 constructs a `Cartridge` from this parser result.
3. Lessons 218-220 add mapper behavior and mapper selection.Run this lesson
uv run pytest tests/chapter_02_rom_loading/test_216_parse_ines_rom.py -v