260. Generación de VBlank de la PPU a partir de la temporización
Implementa la generación de VBlank a partir de la temporización de la PPU.
Lección 260 de 356 · tests/chapter_04_ppu_timing_and_vblank/test_260_ppu_vblank_generation_from_timing.py
Referencia
https://www.nesdev.org/wiki/PPU_rendering#Line-by-line_timing
https://www.nesdev.org/wiki/PPU_registers#PPUSTATUSArchivo a modificar
emulator/ppu/ppu.pyConstantes a añadir
PPU_VBLANK_START_SCANLINE = 241
PPU_PRE_RENDER_SCANLINE = 261Por qué existe este paso
Muchos programas de NES esperan a VBlank antes de escribir en la memoria de la PPU. Habitualmente sondean PPUSTATUS ($2002) hasta que el bit 7 se activa.
Comportamiento conceptual para este paso del tutorial
when the PPU enters scanline 241:
set PPUSTATUS bit 7, VBLANK_STARTED
when the PPU enters scanline 261, the pre-render scanline:
clear PPUSTATUS bit 7Esto proporciona a las ROMs una señal básica de fotograma sin implementar todavía el renderizado completo.
Ejemplo de implementación sugerida
PPU_VBLANK_START_SCANLINE = 241
PPU_PRE_RENDER_SCANLINE = 261
def step(self, cycles: int = 1) -> None:
for _ in range(cycles):
self.cycle += 1
if self.cycle >= PPU_CYCLES_PER_SCANLINE:
self.cycle = 0
self.scanline += 1
if self.scanline >= PPU_SCANLINES_PER_FRAME:
self.scanline = 0
self.frame += 1
# Simplified scanline-level timing event.
if self.scanline == PPU_VBLANK_START_SCANLINE:
self.status |= VBLANK_STARTED
if self.scanline == PPU_PRE_RENDER_SCANLINE:
self.status &= ~VBLANK_STARTEDSimplificación importante
Esto no es una temporización de la PPU exacta por dot. En el hardware real, los cambios de estado ocurren en dots/ciclos concretos de la PPU, habitualmente modelados en torno al dot/ciclo 1 de la línea de barrido correspondiente. Por ahora, este tutorial usa un comportamiento de entrada de línea de barrido porque el objetivo es enseñar el concepto de fotograma/VBlank antes de la precisión total por ciclo.
Fuera de los objetivos del tutorial por ahora
- temporización de VBlank precisa por dot/ciclo
- salto de ciclo en fotograma impar
- renderizado de píxeles durante las líneas de barrido visibles
- sprite 0 hit
- desbordamiento de sprites
- generación de NMI/gestión de interrupciones de la CPU
Ejecutar esta lección
uv run pytest tests/chapter_04_ppu_timing_and_vblank/test_260_ppu_vblank_generation_from_timing.py -v