213. Ines header dataclass

add

Lesson 213 of 356 · tests/chapter_02_rom_loading/test_213_ines_header_dataclass.py

add emulator/cartridge/ines.py::INesHeader.

Why this step exists

The object gives names to immutable metadata from the first 16 bytes and retains raw flags for later format features instead of making downstream code reparse the source bytes. Lesson 212's layout constants are the prerequisite vocabulary for the header represented here.

Suggested implementation after lesson 212's constants

from dataclasses import dataclass


@dataclass(frozen=True)
class INesHeader:
    prg_rom_banks: int
    chr_rom_banks: int
    mapper_number: int
    has_trainer: bool
    flags_6: int
    flags_7: int

Invariants: field order is exact, and the dataclass is frozen because parsed metadata is a fact about the file. prg_rom_banks and chr_rom_banks remain counts, not byte lengths. Do not discard flags_6/flags_7 after deriving the trainer and mapper values.

Out of scope for this step

1. Lesson 214 parses and validates the header bytes.
2. Lessons 215-216 represent and extract the ROM sections.
3. Mapper behavior and interpretation of mirroring bits come later.

Run this lesson

uv run pytest tests/chapter_02_rom_loading/test_213_ines_header_dataclass.py -v