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