214. Analizar la cabecera iNES

añade

Lección 214 de 356 · tests/chapter_02_rom_loading/test_214_parse_ines_header.py

añade emulator/cartridge/ines.py::parse_ines_header.

Por qué existe este paso

El analizador valida el envoltorio fijo antes de convertir los bytes 4-7 en el INesHeader inmutable presentado en la lección 213. Depende de las constantes de la lección 212 y de la dataclass de la lección 213.

Implementación sugerida

def parse_ines_header(data: bytes) -> INesHeader:
    if len(data) < INES_HEADER_SIZE:
        raise ValueError("iNES data is too short")
    if data[0:4] != INES_MAGIC:
        raise ValueError("Invalid iNES header")

    prg_rom_banks = data[4]
    chr_rom_banks = data[5]
    flags_6 = data[6]
    flags_7 = data[7]
    has_trainer = (flags_6 & 0b0000_0100) != 0
    mapper_number = (flags_6 >> 4) | (flags_7 & 0xF0)
    return INesHeader(
        prg_rom_banks,
        chr_rom_banks,
        mapper_number,
        has_trainer,
        flags_6,
        flags_7,
    )

Invariantes: rechaza la entrada demasiado corta antes de indexarla; exige b"NES"; usa el nibble superior de las flags 6 como bits 0-3 del mapper y el nibble superior de las flags 7 como bits 4-7; conserva ambas flags en bruto. Un error común es multiplicar aquí los bytes 4 y 5: siguen siendo recuentos de bancos.

Fuera de alcance para este paso

1. Lesson 215 groups a parsed header with ROM sections.
2. Lesson 216 extracts and validates declared PRG/CHR payload bytes.

Ejecutar esta lección

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