260. Генерация VBlank PPU из синхронизации
Реализуйте генерацию VBlank из синхронизации PPU.
Урок 260 из 356 · tests/chapter_04_ppu_timing_and_vblank/test_260_ppu_vblank_generation_from_timing.py
Справка
https://www.nesdev.org/wiki/PPU_rendering#Line-by-line_timing
https://www.nesdev.org/wiki/PPU_registers#PPUSTATUSФайл для обновления
emulator/ppu/ppu.pyКонстанты для добавления
PPU_VBLANK_START_SCANLINE = 241
PPU_PRE_RENDER_SCANLINE = 261Почему этот шаг существует
Многие программы NES ждут VBlank перед записью в память PPU. Они обычно опрашивают PPUSTATUS ($2002) до тех пор, пока бит 7 не установится.
Концептуальное поведение для этого шага учебника
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 7Это даёт ROM базовый сигнал кадра без реализации полного рендеринга.
Предлагаемый пример реализации
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_STARTEDВажное упрощение
Это не точная по точкам синхронизация PPU. На реальном оборудовании изменения состояния происходят в определённых точках/циклах PPU, обычно моделируемых около точки/цикла 1 соответствующей строки развёртки. Пока этот учебник использует поведение входа в строку развёртки, потому что цель — научить концепции кадра/VBlank перед полной точностью цикла.
Вне целей учебника на данный момент
- точная по точкам/циклам синхронизация VBlank
- пропуск цикла нечётного кадра
- рендеринг пикселей во время видимых строк развёртки
- попадание спрайта 0
- переполнение спрайтов
- генерация NMI/обработка прерывания CPU
Запустить этот урок
uv run pytest tests/chapter_04_ppu_timing_and_vblank/test_260_ppu_vblank_generation_from_timing.py -v