339. Копирование битов горизонтальной прокрутки

Копировать поля горизонтальной прокрутки из временного адреса t в текущий адрес v.

Урок 339 из 356 · tests/chapter_13_scrolling/test_339_copy_horizontal_scroll_bits.py

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

emulator/ppu/ppu.py

Справочные материалы

https://www.nesdev.org/wiki/PPU_scrolling#During_rendering
https://www.nesdev.org/wiki/PPU_scrolling#At_dot_257_of_each_scanline

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

Записи CPU подготавливают поля прокрутки во временном адресе t, но отрисовка фона использует текущий адрес v. PPU переносит только горизонтальные поля в точке горизонтальной перезагрузки:

yyy NN YYYYY XXXXX
    ||       +++++-- coarse X: bits 0-4
    |+-------------- horizontal nametable: bit 10
    +--------------- vertical nametable: bit 11, not copied here

Горизонтальная маска

0b000_01_00000_11111 = 0x041F

Требуемый результат

coarse X                    <- t
horizontal nametable       <- t
coarse Y                    <- original v
fine Y                      <- original v
vertical nametable         <- original v
every other unrelated bit  <- original v

Минимальный пример

v: coarse X 3,  horizontal nametable 0, vertical state A
t: coarse X 20, horizontal nametable 1, vertical state B

result: coarse X 20, horizontal nametable 1, vertical state A

Распространённое заблуждение

Горизонтальная перезагрузка — это не v = t. Копирование всего t заменило бы вертикальное состояние в неправильный момент. Более поздний шаг применит эту уже протестированную операцию в точке 257.

Вне объёма работ

  • изменение PPU.step()
  • таймирование в точке 257
  • горизонтальные инкременты адреса
  • вертикальные копирования из t в v
  • отрисовка фреймбуфера

Полный пример реализации

# emulator/ppu/ppu.py

# --- NEW LINE: COARSE X AND HORIZONTAL NAMETABLE FIELDS ---
HORIZONTAL_SCROLL_BITS = 0b000_01_00000_11111


# --- NEW BLOCK: PURE HORIZONTAL t-TO-v COPY ---
def copy_horizontal_scroll_bits(
    vram_addr: int,
    temp_vram_addr: int,
) -> int:
    return (
        (vram_addr & ~HORIZONTAL_SCROLL_BITS)
        | (temp_vram_addr & HORIZONTAL_SCROLL_BITS)
    )

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

uv run pytest tests/chapter_13_scrolling/test_339_copy_horizontal_scroll_bits.py -v