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