289. OAMDMA 4014
Реализовать OAMDMA по адресу CPU $4014.
Урок 289 из 356 · tests/chapter_06_rom_startup_preparation/test_289_oamdma_4014.py
Файл для обновления
emulator/bus/cpu_bus.pyЗачем нужен этот шаг
Реальные игры для NES обычно подготавливают байты спрайтов в памяти CPU, а затем запускают OAMDMA, чтобы скопировать эти байты в OAM PPU. Даже до появления рендеринга спрайтов этот механизм копирования важен, поскольку он позволяет коду запуска реальных ROM продолжать работу и предоставляет будущему рендереру спрайтов реальные данные OAM.
Что такое OAM? OAM означает Object Attribute Memory. Это 256-байтная память спрайтов PPU:
64 sprites * 4 bytes each = 256 bytesКаждая запись спрайта имеет форму
byte 0: Y position
byte 1: tile index
byte 2: attributes
byte 3: X positionЧто такое OAMDMA? OAMDMA — это механизм записи на шине CPU. Запись одного байта по адресу $4014 выбирает страницу памяти CPU и копирует все 256 байтов этой страницы в OAM PPU.
Минимальный пример
CPU writes $02 to $4014Это означает
copy CPU $0200-$02FF -> PPU.oam[0x00-0xFF]Пример предлагаемой реализации
def write(self, addr: int, value: int) -> None:
...
# OAMDMA: copy one CPU page into PPU OAM.
if addr == 0x4014:
page_start = (value & 0xFF) << 8
for offset in range(256):
self.ppu.oam[offset] = self.read(page_start + offset)
return
...Важная деталь
OAMDMA должен читать данные через CpuBus.read(), а не напрямую из «сырой» RAM. Источник — адресное пространство CPU. Большинство игр используют страницы вроде $0200-$02FF, но использование чтений через шину сохраняет корректность механизма и избавляет от будущих переработок.
Распространённое заблуждение
"OAMDMA means sprites are rendered."Нет. На этом шаге байты только копируются в PPU.oam. Декодирование/рендеринг спрайтов появится позже.
Поведение при чтении
В рамках этого курса $4014 — это регистр, срабатывающий только на запись. CpuBus.read($4014) пока должен оставаться неподдерживаемым.
Вне рамок этого шага
- рендеринг спрайтов
- приоритет спрайтов
- прозрачность спрайтов
- sprite 0 hit
- переполнение спрайтов
- тайминг задержки DMA в 513/514 циклов CPU
- контроллер $4016
Запустить этот урок
uv run pytest tests/chapter_06_rom_startup_preparation/test_289_oamdma_4014.py -v