294. 手动 core_validator ROM 循环
添加手动 core_validator.py ROM 启动循环。
第 294 / 356 · tests/chapter_08_manual_main/test_294_manual_core_validator_rom_loop.py
在根目录创建的文件
core_validator.py为什么需要这一步
模拟器现在已具备足够的启动存活行为,可以创建一个对开发者有用的手动入口点:
iNES parsing
Mapper000/NROM
CPU reset vector
Console frame stepping
APU/audio no-op for out-of-scope audio
OAMDMA $4014
controller port 1 through $4016本步骤将 core_validator.py 打造为一个手动入口点,用于尝试加载本地 ROM 并在不使用 pygame 的情况下逐帧运行模拟器。
为什么用 core_validator.py 而不是 main.py?main.py 保留给可视化 pygame 运行器使用。core_validator.py 是一个小型非可视化运行器,在调试模拟器核心时无需窗口或前端事件循环即可使用。
重要的法律/测试规则
教程仓库不得包含商业 ROM 文件。自动化测试不得要求 MarioBros.nes。开发者如需手动运行 Mario Bros.,必须自行提供合法的本地副本:
MarioBros.nes教程开发期间使用的参考哈希 [Mario Bros. (World).nes]:
MD5 5d7bcc400a2fb5fa27346da345d3bb62 MarioBros.nes
SHA1 314b6e46e814f955b52ac954f67dab849582fe77此哈希仅供手动参考。测试不得要求此文件或此确切哈希,因为用户可能拥有不同的合法转储/版本。
建议的实现示例
from pathlib import Path
from emulator.bus.cpu_bus import CpuBus
from emulator.cartridge.cartridge import Cartridge
from emulator.console import Console
from emulator.cpu.cpu import CPU
ROM_PATH = Path("MarioBros.nes")
debug_mode = True
def main() -> None:
if not ROM_PATH.exists():
raise FileNotFoundError(
"MarioBros.nes not found. Provide your own legal local copy. "
"This file is intentionally not included in the tutorial repository."
)
cartridge = Cartridge.from_ines_bytes(ROM_PATH.read_bytes())
cpu_bus = CpuBus(cartridge=cartridge)
cpu = CPU(cpu_bus)
console = Console(cpu=cpu, ppu=cpu_bus.ppu)
cpu.reset()
print(f"Loaded {ROM_PATH}")
print(f"CPU reset PC = ${cpu.pc:04X}")
print("Starting frame loop. Press Ctrl+C to stop.")
try:
while True:
executed = console.step_until_next_frame()
if debug_mode:
print(
f"frame={console.ppu.frame} "
f"pc=${cpu.pc:04X} "
f"instructions={executed}"
)
except KeyboardInterrupt:
print("Stopped by user.")
if __name__ == "__main__":
main()手动命令
uv run python core_validator.py预期的手动行为
此命令不会自行退出。它会持续逐帧执行直到开发者按下 Ctrl+C。这是预期行为,因为 core_validator.py 是手动长时间运行的 ROM 执行工具,而非自动化测试。
为什么本测试不调用 main()
core_validator.py 是一个手动无限循环。自动化测试必须保持有限执行,且不得要求本地商业 ROM 文件。这些测试仅检查结构。
为什么只检查 debug_mode 是否存在:debug_mode 是手动控制旋钮。后续教程步骤可能根据教学内容将其设为 True 或 False。测试不应冻结该值。
超出本步骤范围
- pygame 显示
- 键盘映射
- 提交的 ROM 测试固件
- 断言 core_validator.py 产生正确的游戏运行结果
- 从 pytest 调用 main()
运行本课
uv run pytest tests/chapter_08_manual_main/test_294_manual_core_validator_rom_loop.py -v