259. Contadores de temporización de la PPU

Implementa contadores básicos de temporización de la PPU.

Lección 259 de 356 · tests/chapter_04_ppu_timing_and_vblank/test_259_ppu_timing_counters.py

Referencia

https://www.nesdev.org/wiki/PPU_rendering#Line-by-line_timing

Archivo a modificar

emulator/ppu/ppu.py

Constantes a añadir

PPU_CYCLES_PER_SCANLINE = 341
PPU_SCANLINES_PER_FRAME = 262

Estado a añadir

cycle: int = 0
scanline: int = 0
frame: int = 0

Método a añadir

PPU.step(cycles: int = 1) -> None

Por qué existe este paso

La PPU es un dispositivo basado en tiempo. Más adelante, el VBlank, la NMI, el renderizado y el ritmo de fotogramas dependerán de saber en qué punto del fotograma actual se encuentra la PPU.

Para este paso, añade únicamente contadores

cycle    -> position inside the current scanline
scanline -> current scanline inside the frame
frame    -> completed frame count

Modelo de temporización inicial

341 PPU cycles per scanline
262 scanlines per frame

Ejemplo de implementación sugerida

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

Compatibilidad futura

Estas pruebas comprueban intencionadamente solo el comportamiento de los contadores. Todavía no requieren efectos secundarios exactos de VBlank/NMI. Pasos posteriores podrán añadir efectos secundarios dentro de PPU.step(), pero estos invariantes de los contadores deben seguir siendo válidos.

Fuera de alcance

  • generación de VBlank
  • solicitud de NMI
  • renderizado
  • sprite 0 hit
  • desbordamiento de sprites
  • salto de ciclo en fotograma impar

Ejecutar esta lección

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