241. La lectura de PPUSTATUS reinicia el conmutador de segunda escritura
Leer PPUSTATUS ($2002) reinicia el conmutador de segunda escritura de la PPU.
Lección 241 de 356 · tests/chapter_03_ppu_memory_and_graphics_data/test_241_ppustatus_read_resets_second_write_toggle.py
Archivo a actualizar
emulator/ppu/ppu.pyMétodo a actualizar
PPU.read_register(addr)Por qué existe este paso
La PPU de la NES tiene registros de doble escritura, especialmente
$2005 PPUSCROLL
$2006 PPUADDREsos registros usan un conmutador interno de primera escritura / segunda escritura. En este tutorial, ese estado se llama:
second_write_toggleSignificado
False -> the next two-write register access is the first write
True -> the next two-write register access is the second writeComportamiento importante de PPUSTATUS
Leer $2002 reinicia este conmutador y lo deja de nuevo en False.
Por qué
Los juegos suelen leer PPUSTATUS antes de escribir PPUSCROLL o PPUADDR, de modo que se sepa que la PPU está esperando de nuevo la primera escritura.
Ejemplo
write $23 to $2006
second_write_toggle = True
read $2002
second_write_toggle = False
write $20 to $2006
treated as first write / high byte, not as low bytePseudocódigo de implementación sugerido
def read_register(self, addr: int) -> int:
match addr:
case 0x2002:
value = self.status
self.status &= ~VBLANK_STARTED
self.second_write_toggle = False
return value
case 0x2004:
return self.oam_data
case 0x2007:
return self.data
case _:
raise ValueError(...)Invariante importante
Leer $2002 debe devolver el valor de estado anterior y después aplicar los efectos secundarios.
Efectos secundarios modelados actualmente
- borrar VBLANK_STARTED
- reiniciar second_write_toggle
Efectos secundarios aún no modelados
- comportamiento completo del latch de desplazamiento
- generación de temporización/VBlank
- comportamiento de NMI
Ejecutar esta lección
uv run pytest tests/chapter_03_ppu_memory_and_graphics_data/test_241_ppustatus_read_resets_second_write_toggle.py -v