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.py

Mé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 PPUADDR

Esos registros usan un conmutador interno de primera escritura / segunda escritura. En este tutorial, ese estado se llama:

second_write_toggle

Significado

False -> the next two-write register access is the first write
True  -> the next two-write register access is the second write

Comportamiento 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 byte

Pseudocó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