NES TDD

254. Маршрутизация записи CHR маппера

Реализуйте маршрутизацию записи CHR через маппер.

Урок 254 из 356 · tests/chapter_03_ppu_memory_and_graphics_data/test_254_mapper_chr_write_routing.py

Справка

https://www.nesdev.org/wiki/PPU_memory_map
https://www.nesdev.org/wiki/NROM

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

emulator/cartridge/mapper_interface.py
emulator/cartridge/mapper000.py
emulator/bus/ppu_bus.py

Что такое память CHR? Память CHR — это место, откуда PPU читает байты шаблонов плиток. Диапазон адресов PPU $0000-$1FFF — это область CHR.

Простой пример

PPU reads $0000
mapper returns the first byte of CHR ROM

Для официального Mapper000/NROM в этом учебнике CHR — это ROM, поэтому записи отклоняются.

Почему этот шаг существует

PpuBus должен только маршрутизировать адреса. Он не должен решать, являются ли записи CHR законными. Маппер владеет этой политикой.

Правильное разделение ответственности

PpuBus.write($0000-$1FFF, value)
    -> mapper.write_chr(addr, value)

Mapper000.write_chr(addr, value)
    -> rejects writes because official Mapper000 CHR ROM is read-only

Предлагаемый пример реализации

class MapperInterface(Protocol):
    def read_prg(self, addr: int) -> int:
        ...

    def read_chr(self, addr: int) -> int:
        ...

    def write_chr(self, addr: int, value: int) -> None:
        ...

class Mapper000:
    def write_chr(self, addr: int, value: int) -> None:
        if not (CHR_ROM_START <= addr <= CHR_ROM_END):
            raise ValueError(f"Address out of CHR ROM range: {addr:04X}")

        raise ValueError("CHR ROM is read-only for official Mapper000")

class PpuBus:
    def write(self, addr: int, value: int) -> None:
        addr = addr & PPU_ADDRESS_MASK

        if CHR_START <= addr <= CHR_END:
            if self.mapper is not None:
                self.mapper.write_chr(addr, value)
                return

            self.vram.write(addr, value)
            return

Вне области действия

  • поддержка CHR RAM
  • нелицензированные/самодельные варианты Mapper000 с записываемым CHR RAM
  • переключение банков маппера
  • рендеринг плиток CHR

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

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