NES TDD

225. Ppu write register

Добавление PPU.write_register(addr, value).

Урок 225 из 356 · tests/chapter_03_ppu_memory_and_graphics_data/test_225_ppu_write_register.py

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

emulator/ppu/ppu.py

Метод для реализации

PPU.write_register(addr: int, value: int) -> None

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

CPU записывает в регистры PPU через ввод-вывод с отображением в память. Когда CPU записывает по адресу $2000, он записывает не в RAM, а обновляет регистр PPUCTRL.

На этом шаге PPU.write_register получает нормализованные адреса регистров PPU в диапазоне $2000-$2007. Зеркалирование CpuBus для $2008-$3FFF будет реализовано на более позднем шаге.

Регистры, доступные для записи на этом упрощённом этапе

$2000 -> ctrl
$2001 -> mask
$2003 -> oam_addr
$2004 -> oam_data / OAMDATA port
$2005 -> scroll
$2006 -> addr
$2007 -> data

Обратите внимание, что $2002 намеренно отсутствует.

Почему $2002 недоступен для записи: $2002 — это PPUSTATUS. Со стороны CPU он доступен только для чтения. Тесты могут напрямую устанавливать ppu.status, когда им нужно смоделировать значение статуса, но write_register($2002, value) должен завершаться ошибкой.

Политика одного байта

Регистры PPU 8-битные. Пока что записи должны сохранять только младший байт значения. Это означает, что запись 0x123 сохранит 0x23.

Предлагаемый псевдокод реализации

def write_register(self, addr: int, value: int) -> None:
    value = value & 0xFF

    match addr:
        case 0x2000:
            self.ctrl = value
        case 0x2001:
            self.mask = value
        case 0x2003:
            self.oam_addr = value
        case 0x2004:
            self.oam_data = value
        case 0x2005:
            self.scroll = value
        case 0x2006:
            self.addr = value
        case 0x2007:
            self.data = value
        case _:
            raise ValueError(...)

Заметка на будущее

Позже $2004/OAMDATA станет портом во внутреннюю память спрайтов OAM. На этом этапе запись в $2004 также может увеличивать oam_addr. Этот ранний тест не должен требовать, чтобы oam_addr оставался неизменным после записи в OAMDATA.

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

uv run pytest tests/chapter_03_ppu_memory_and_graphics_data/test_225_ppu_write_register.py -v