228. Enrutamiento de lecturas de registros de PPU en CpuBus

Enrutar las lecturas de CpuBus desde $2000-$3FFF a los registros de la PPU.

Lección 228 de 356 · tests/chapter_03_ppu_memory_and_graphics_data/test_228_cpu_bus_ppu_register_read_routing.py

Archivo a actualizar

emulator/bus/cpu_bus.py

Por qué existe este paso

La CPU ve los registros de la PPU a través del mapa de direcciones de CPU

$2000-$3FFF -> PPU registers, mirrored every 8 bytes

Solo $2000-$2007 son las direcciones base de registro de la PPU. El resto del rango son espejos de esos mismos 8 registros.

Fórmula de mirroring

unmirrored_addr = 0x2000 + ((addr - 0x2000) % 8)

Cómo funciona

1. addr - 0x2000 converts the CPU address into an offset from the start of
   the PPU register window.
2. % 8 folds that offset into the repeating 8-register range.
3. + 0x2000 converts the folded offset back into a base PPU register address.

Ejemplos

$2002:
    0x2000 + ((0x2002 - 0x2000) % 8)
    = 0x2000 + (2 % 8)
    = $2002

$200A:
    0x2000 + ((0x200A - 0x2000) % 8)
    = 0x2000 + (10 % 8)
    = $2002

$3FFF:
    0x2000 + ((0x3FFF - 0x2000) % 8)
    = 0x2000 + (8191 % 8)
    = $2007

Por qué CpuBus es el dueño de la fórmula

El mirroring es decodificación del mapa de direcciones de la CPU. PPU.read_register debería recibir una dirección de registro normalizada en $2000-$2007.

Pseudocódigo de implementación sugerido

if 0x2000 <= addr <= 0x3FFF:
    unmirrored_addr = 0x2000 + ((addr - 0x2000) % 8)
    return self.ppu.read_register(unmirrored_addr)

Ejecutar esta lección

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