342. Копировать вертикальные биты прокрутки
Скопировать поля вертикальной прокрутки из временного адреса t в текущий адрес v.
Урок 342 из 356 · tests/chapter_13_scrolling/test_342_copy_vertical_scroll_bits.py
Файл для обновления
emulator/ppu/ppu.pyСсылки
https://www.nesdev.org/wiki/PPU_scrolling#During_dots_280_to_304_of_the_pre-render_scanline_(end_of_vblank)Зачем нужен этот шаг
Записи CPU подготавливают поля вертикальной прокрутки во временном адресе t, а рендеринг использует текущий адрес v. Во время pre-render scanline PPU выборочно обновляет вертикальные поля:
yyy NN YYYYY XXXXX
||| | |||||
||| | +++++-- coarse Y: bits 5-9
||| +--------- vertical nametable: bit 11
+++----------- fine Y: bits 12-14Вертикальная маска
0b111_10_11111_00000 = 0x7BE0Требуемый результат
fine Y <- t
vertical nametable <- t
coarse Y <- t
coarse X <- original v
horizontal nametable <- original v
every other unrelated bit <- original vМинимальный пример
v: horizontal state A, vertical state B
t: horizontal state C, vertical state D
result: horizontal state A, vertical state DРаспространённое заблуждение
Вертикальная перезагрузка — это не v = t. Копирование всего t перезапишет горизонтальное состояние после того, как оно было независимо подготовлено горизонтальной перезагрузкой.
Вне области действия
- изменение PPU.step()
- вертикальное увеличение на точке 256
- pre-render точки 280-304
- запись состояния scanline
- рендеринг framebuffer
Полный пример реализации
# emulator/ppu/ppu.py
# --- NEW LINE: FINE Y, VERTICAL NAMETABLE, AND COARSE Y ---
VERTICAL_SCROLL_BITS = 0b111_10_11111_00000
# --- NEW BLOCK: PURE VERTICAL t-TO-v COPY ---
def copy_vertical_scroll_bits(
vram_addr: int,
temp_vram_addr: int,
) -> int:
return (
(vram_addr & ~VERTICAL_SCROLL_BITS)
| (temp_vram_addr & VERTICAL_SCROLL_BITS)
)Запустить этот урок
uv run pytest tests/chapter_13_scrolling/test_342_copy_vertical_scroll_bits.py -v