254. Enrutamiento de escritura de CHR en el mapper

Implementa el enrutamiento de escrituras de CHR a través del mapper.

Lección 254 de 356 · tests/chapter_03_ppu_memory_and_graphics_data/test_254_mapper_chr_write_routing.py

Referencia

https://www.nesdev.org/wiki/PPU_memory_map
https://www.nesdev.org/wiki/NROM

Archivos a modificar

emulator/cartridge/mapper_interface.py
emulator/cartridge/mapper000.py
emulator/bus/ppu_bus.py

¿Qué es la memoria CHR? La memoria CHR es de donde la PPU lee los bytes de patrón de tile. El rango de direcciones de la PPU $0000-$1FFF es el área de CHR.

Ejemplo simple

PPU reads $0000
mapper returns the first byte of CHR ROM

Para el Mapper000/NROM oficial en este tutorial, la CHR es ROM, por lo que las escrituras se rechazan.

Por qué existe este paso

PpuBus solo debería enrutar direcciones. No debería decidir si las escrituras de CHR son legales. Esa política pertenece al mapper.

Reparto correcto de responsabilidades

PpuBus.write($0000-$1FFF, value)
    -> mapper.write_chr(addr, value)

Mapper000.write_chr(addr, value)
    -> rejects writes because official Mapper000 CHR ROM is read-only

Ejemplo de implementación sugerida

class MapperInterface(Protocol):
    def read_prg(self, addr: int) -> int:
        ...

    def read_chr(self, addr: int) -> int:
        ...

    def write_chr(self, addr: int, value: int) -> None:
        ...

class Mapper000:
    def write_chr(self, addr: int, value: int) -> None:
        if not (CHR_ROM_START <= addr <= CHR_ROM_END):
            raise ValueError(f"Address out of CHR ROM range: {addr:04X}")

        raise ValueError("CHR ROM is read-only for official Mapper000")

class PpuBus:
    def write(self, addr: int, value: int) -> None:
        addr = addr & PPU_ADDRESS_MASK

        if CHR_START <= addr <= CHR_END:
            if self.mapper is not None:
                self.mapper.write_chr(addr, value)
                return

            self.vram.write(addr, value)
            return

Fuera de alcance

  • soporte de CHR RAM
  • variantes no oficiales/homebrew del Mapper000 con CHR RAM escribible
  • conmutación de bancos del mapper
  • renderizado de tiles de CHR

Ejecutar esta lección

uv run pytest tests/chapter_03_ppu_memory_and_graphics_data/test_254_mapper_chr_write_routing.py -v