325. Cartridge conserva el mirroring

Conservar los metadatos decodificados de mirroring de nametables en Cartridge.

Lección 325 de 356 · tests/chapter_12_mirroring/test_325_cartridge_preserves_mirroring.py

Archivo a actualizar

emulator/cartridge/cartridge.py

Por qué existe este paso

El paso 324 decodifica el bit 0 de iNES flags 6 mediante

INesHeader.is_vertical_mirroring

Esa información debe sobrevivir tras el parseo para que pasos posteriores de mapper y PpuBus puedan elegir el mapeo de direcciones de nametable correcto.

Ruta de metadatos para este paso

iNES flags 6
    -> INesHeader.is_vertical_mirroring
    -> Cartridge.is_vertical_mirroring

Cambios de implementación sugeridos

@dataclass
class Cartridge:
    prg_rom: bytes
    chr_rom: bytes
    mapper_number: int
    chr_ram: bytearray | None = None

    # --- NEW LINE ---
    is_vertical_mirroring: bool = False
    # --- END NEW LINE ---


@classmethod
def from_ines_bytes(cls, data: bytes) -> "Cartridge":
    ines_rom = parse_ines_rom(data)

    return cls(
        prg_rom=ines_rom.prg_rom,
        chr_rom=ines_rom.chr_rom,
        mapper_number=ines_rom.header.mapper_number,

        # --- NEW LINE ---
        is_vertical_mirroring=ines_rom.header.is_vertical_mirroring,
        # --- END NEW LINE ---
    )

¿Por qué añadir un campo con valor por defecto? El código histórico del tutorial construye Cartridge directamente con tres o cuatro argumentos posicionales. Añadir un campo con valor por defecto conserva esas formas del constructor mientras permite que las ROM parseadas proporcionen metadatos reales.

Significado

False -> horizontal mirroring
True  -> vertical mirroring

Fuera del alcance

  • cambiar Mapper000
  • cambiar MapperInterface
  • cambiar mapper_factory
  • cambiar el mapeo de nametables de PpuBus
  • mirroring de cuatro pantallas
  • scrolling
  • fixtures de ROM comerciales

Ejecutar esta lección

uv run pytest tests/chapter_12_mirroring/test_325_cartridge_preserves_mirroring.py -v