223. Validation cpu executes tiny ines rom
ВАЛИДАЦИОННЫЙ ТЕСТ: CPU выполняет крошечный сгенерированный iNES ROM.
Урок 223 из 356 · tests/chapter_02_rom_loading/test_223_VALIDATION_cpu_executes_tiny_ines_rom.py
Это не шаг реализации для студента.
Проверяемые предварительные условия
- this file: make_tiny_ines_rom and
test_cpu_executes_tiny_generated_ines_rom_from_reset_vector
- emulator/cartridge/ines.py: PRG_ROM_BANK_SIZE, CHR_ROM_BANK_SIZE,
parse_ines_header, and parse_ines_rom
- emulator/cartridge/cartridge.py: Cartridge.from_ines_bytes
- emulator/cartridge/mapper_factory.py: create_mapper
- emulator/cartridge/mapper000.py: Mapper000.read_prg
- emulator/bus/cpu_bus.py: CpuBus.__post_init__ and CpuBus.read
- emulator/cpu/cpu.py: CPU.reset, CPU.fetch_byte, and CPU.step
- emulator/cpu/opcodes.py: OPCODE_TABLE entry $A9
- emulator/cpu/instructions.py: ldaПоследовательность валидации
1. make_tiny_ines_rom builds a 16-byte iNES header declaring mapper 0, one
16KB PRG bank, one 8KB CHR bank, and no trainer.
2. It writes A9 42 (LDA #$42) and EA (NOP) at PRG offsets $0000-$0002,
corresponding to CPU $8000-$8002.
3. It writes reset-vector bytes 00 80 at PRG offsets $3FFC-$3FFD. Mapper000's
16KB mirror makes CPU reads $FFFC-$FFFD observe those bytes.
4. Cartridge.from_ines_bytes parses and slices the generated bytes.
5. CpuBus(cartridge=cartridge) creates Mapper000 through create_mapper.
6. CPU.reset reads the vector through CpuBus and Mapper000, producing
PC=$8000.
7. One CPU.step fetches $A9 through the same path, dispatches lda, fetches
operand $42, and leaves A=$42 and PC=$8002. The trailing NOP is fixture
data and is not executed by this test.Запустите именно эту валидацию с помощью
pytest -q tests/chapter_02_rom_loading/test_223_VALIDATION_cpu_executes_tiny_ines_rom.pyПолная проверяемая граница:
iNES bytes
-> Cartridge.from_ines_bytes(data)
-> CpuBus(cartridge=cartridge)
-> create_mapper(cartridge)
-> Mapper000
-> CPU.reset()
-> CPU.step()Почему этот шаг нужен
Валидация существует потому, что модульные тесты могут доказать корректность каждой части по отдельности, в то время как ошибки всё равно проявляются на границах компонентов. Этот тест не добавляет производственной реализации; он доказывает, что уроки 212-222 работают вместе, так что CPU может выбрать и выполнить инструкцию из PRG ROM, поддерживаемой картриджем, используя вектор сброса.
ROM генерируется внутри теста. Она намеренно крошечная и не использует PPU, APU, контроллеры, прерывания или любые возможности за пределами текущей области эмулятора.
Крошечная программа, размещённая по адресу CPU $8000:
A9 42 LDA #$42
EA NOPВектор сброса
CPU $FFFC = $00
CPU $FFFD = $80Таким образом, после сброса
PC = $8000Важная деталь Mapper000
Для 16КБ картриджа NROM CPU $FFFC-$FFFD отображается на смещения PRG ROM $3FFC-$3FFD, потому что $C000-$FFFF зеркалирует 16КБ банк PRG.
Инварианты
Полезная нагрузка iNES полная и находится в памяти; номер mapper'а и размеры банков переживают разбор; чтения вектора сброса и выборки опкода/операнда используют маршрутизацию PRG, поддерживаемую картриджем; сброс выбирает $8000; и одна инструкция потребляет ровно два байта. Распространённое заблуждение — размещать вектор по смещению $7FFC, как в раскладке 32КБ/FakeROM, или утверждать, что NOP был проверен уже после одного шага.
Вне рамок
Не добавляйте производственный код для этой валидации. Построение/маршрутизация регистров PPU (предстоящий переход к Главе 3), APU, контроллеры, прерывания, тайминг, записи в PRG, чтения CHR/PPU, внешние файлы ROM и последующая интеграция консоли/PPU намеренно не задействованы и не подразумеваются здесь.
Запустить этот урок
uv run pytest tests/chapter_02_rom_loading/test_223_VALIDATION_cpu_executes_tiny_ines_rom.py -v