261. Solicitud NMI de la PPU en VBlank

Implementar la solicitud de NMI del lado de la PPU en VBlank.

Lección 261 de 356 · tests/chapter_04_ppu_timing_and_vblank/test_261_ppu_nmi_request_on_vblank.py

Referencia

https://www.nesdev.org/wiki/PPU_registers#PPUCTRL
https://www.nesdev.org/wiki/PPU_registers#Vblank_NMI

Archivo a actualizar

emulator/ppu/ppu.py

Estado a añadir

nmi_requested: bool = False

Por qué existe este paso

Muchos juegos de NES no consultan PPUSTATUS en su bucle principal. En su lugar, activan NMI en el bit 7 de PPUCTRL y esperan que la PPU solicite una interrupción cuando comience el VBlank.

En este paso, implementa solo la señal del lado de la PPU

if VBlank starts and PPUCTRL bit 7 is set:
    ppu.nmi_requested = True

La CPU aún no consume la NMI. Eso es un paso de integración posterior.

Ejemplo de implementación sugerido

nmi_requested: bool = False
...
...

if self.scanline == PPU_VBLANK_START_SCANLINE:
    self.status |= VBLANK_STARTED

    if self.ctrl & CTRL_NMI_ENABLE:
        self.nmi_requested = True

Concepto importante

La solicitud de NMI es un evento producido cuando comienza el VBlank. No debe producirse continuamente en cada ciclo del VBlank.

Fuera de alcance

  • Manejo de interrupciones de la CPU
  • lectura del vector NMI
  • envío de PC/estado a la pila de la CPU
  • borrado de nmi_requested por integración CPU/sistema
  • activación de NMI durante un VBlank ya activo
  • temporización de NMI precisa a nivel de punto/ciclo

Ejecutar esta lección

uv run pytest tests/chapter_04_ppu_timing_and_vblank/test_261_ppu_nmi_request_on_vblank.py -v