261. Запрос NMI от PPU при VBlank

Реализовать запрос NMI со стороны PPU при VBlank.

Урок 261 из 356 · tests/chapter_04_ppu_timing_and_vblank/test_261_ppu_nmi_request_on_vblank.py

Справочник

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

Файл для обновления

emulator/ppu/ppu.py

Добавляемое состояние

nmi_requested: bool = False

Зачем нужен этот шаг

Многие игры для NES не опрашивают PPUSTATUS в своём главном цикле. Вместо этого они включают NMI в бите 7 PPUCTRL и ожидают, что PPU запросит прерывание при начале VBlank.

Для этого шага реализуйте только сигнал со стороны PPU

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

CPU пока не обрабатывает этот NMI. Это отдельный шаг интеграции позже.

Пример предлагаемой реализации

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

Важное понятие

Запрос NMI — это событие, вырабатываемое при начале VBlank. Он не должен вырабатываться непрерывно на каждом такте VBlank.

Выходит за рамки

  • обработка прерываний CPU
  • чтение вектора NMI
  • занесение PC/регистра состояния в стек CPU
  • сброс nmi_requested при интеграции CPU/системы
  • включение NMI во время уже идущего VBlank
  • синхронизация NMI с точностью до точки/такта

Запустить этот урок

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