找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 921|回复: 1

利用AI实现简单的掌机模拟器

[复制链接]
发表于 2026-5-17 13:15:31 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有账号?立即注册→加入我们

×

大概从2025年底,以Claude为代表的商业AI在软件开发方面有了质的飞跃,为了跟上时代同时也更好地发挥自身优势,提前布局AI熟悉AI,了解AI的长处和不足,把"自己+AI"当成一个黑盒整体调优,是每个开发者最应该做的事。以下是笔者的一个简单AI调教过程

笔者环境:

  • macOS + Python + Gemini-cli
  • Gemini-cli + 手选gemini-3-flash

注意:

  • 御三家中Gemini的能力是垫底的,这里没有用写代码最强的Claude+Opus,也没有用gemini最强的模型gemini-3.1-pro,而只是用了gemini-3-flash,充分证明中档次商业AI甚至顶级开源模型也足矣完成大部分开发工作了
  • 本人对掌机模拟器,没玩过,也完全不了解,所以更没有开发经验,完全靠AI牛马写代码

作为一个完整软件项目,我们需要走一遍流程:

  1. 编写文档,包括可行性分析,需求分析,详细设计
  2. 开发,包括功能/模块拆分,写代码,进度报告
  3. 测试

首先手写一个简单的提示词,让AI据此生成一个生产可用的提示词。注意gemini-cli在Yolo模式下是全自动操作的

1. 编写需求文档(`./Requirement.md`),开发支持`MacOS`系统的基于`python`的`Nintendo NES`模拟器
2. 根据需求文档编写详细设计文档(`./Design.md`),包含开发和测试各个环节
3. 根据详细设计文档划分模块,每个模块一个文档(`design/<module>.md`),每个文档中包含进度清单(checklist)
4. 设计总体进度清单(checklist)
5. 在以上过程中,不要猜测我的意图,如果有任何不确定的地方向我提问
6. 根据以上文档开始开发,主agent控制整体流程,每个模块用一个子agent完成, 过程中及时更新总体和子模块进度清单,开发后自动进行测试,确保`shark.nes`能正常游戏

其他: 
* 使用python虚拟环境(`./.venv`)
* 目标游戏文件`./shark.nes`


最终AI生成的prompt.md如下

角色与目标

你是一个资深的软件架构师与 Multi-Agent 协调器。你的任务是带领开发团队,在 MacOS 系统上使用 Python 开发一个高性能、时钟精确的 Nintendo NES 模拟器。

核心环境与性能约束

  • 开发语言:Python 3.7+ (使用 requirements.txt 管理依赖,运行于 ./.venv
  • 图形与音频库:优先使用 PygamePySDL2(确保 MacOS 上的流畅度和 60 FPS 时钟同步)。
  • 【性能红线】:严禁在 CPU/PPU 的主循环(热点路径如 tick(), render_pixel())中加入任何无条件的 printlogging 语句。所有调试日志必须有开关(Debug Flag)控制。
  • 目标游戏文件:./shark.nes

严格的目录结构规范

所有 Agent 必须严格按照以下结构创建和读取文件,严禁擅自更改:
├── .venv/
├── design/              # 存放各模块设计文档
├── src/
│   ├── init.py
│   ├── main.py          # 模拟器主入口
│   ├── bus.py           # 系统总线 (连接 CPU, PPU, APU, Cartridge)
│   ├── cpu.py           # 6502 CPU 核心
│   ├── ppu.py           # PPU 画面渲染核心
│   ├── apu.py           # APU 音频核心
│   ├── cartridge.py     # 卡带读取与 Mapper 控制器
│   └── input.py         # 手柄输入映射
└── tests/               # 自动化测试脚本

执行流程

第一阶段:前置探测与架构设计(请在此阶段完成后停顿)

注意:

  • 禁止猜测:严格禁止猜测我的意图。遇到任何架构冲突、技术选型模糊的地方,立刻向我提问
  • 中文文档:所有文档用中文编写
  • 完成暂停:完成下面步骤后停止,输出探测到的游戏信息和设计架构。等待我对设计文档和接口契约进行评审
  1. 前置探测:优先编写轻量脚本解析 ./shark.nes 的 iNES 报头,提取并输出:PRG ROM 大小、CHR ROM 大小及Mapper 编号。
  2. 编写需求文档 (./Requirement.md):基于探测结果,明确模拟器必须支持该游戏的 Mapper 类型。
  3. 编写总体设计文档 (./Design.md):
    • 明确主时钟循环(Master Clock Loop):必须遵循 1 个 CPU 周期 = 3 个 PPU 周期 的精确同步契约。
    • 制定各个 Python 模块的接口契约(Interface Protocol),统一方法签名(如 read(addr), write(addr, val))。
  4. 划分模块文档:在 design/ 下生成各模块的子文档,每个文档内必须包含详细的【开发与测试进度清单 (Checklist)】。
  5. 生成总体进度清单 (./Checklist.md)。

第二阶段:智能体协同开发(收到确认指令后启动)

  1. 启动开发:由主 Agent 严格按照目录结构和接口契约,为 src/ 下的各模块分配子 Agent 独立编写代码。
  2. 动态同步:开发过程中,及时、自动更新总体和子模块的 Checklist。

第三阶段:闭环测试与交付

  1. 阶梯式自动化测试:
    • 阶段 A(单元测试):子模块独立测试(如 CPU 6502 指令集测试)。
    • 阶段 B(集成测试):引入 Blargg's test ROMs 进行 CPU/PPU 行为对齐。
    • 阶段 C(真机测试):运行 ./shark.nes,验证画面渲染、声音输出、手柄输入的正确性。
  2. 自动化 Debug 闭环:若测试失败,主 Agent 必须捕获报错日志,分配给对应的子 Agent 修复,直至测试完全通过。



接着,在gemini-cli中,让其执行./prompt.md中的任务,AI最终输出了

NES 模拟器需求文档 (Requirement.md)

1. 项目目标

开发一个高性能、时钟精确的 Nintendo NES 模拟器,能够在 MacOS 系统上使用 ./.venv/bin/python 流畅运行目标游戏 ./shark.nes

2. 目标游戏探测结果 (shark.nes)

  • PRG ROM 大小: 16384 字节 (1 个 Bank)
  • CHR ROM 大小: 8192 字节 (1 个 Bank)
  • Mapper 编号: 0 (NROM)
  • 镜像方式 (Mirroring): 垂直镜像 (Vertical)
  • 电池备份 RAM: 否
  • Trainer: 否
  • 四屏 VRAM: 否

3. 核心功能需求

3.1 CPU 模拟

  • 完整实现 Ricoh 2A03 (基于 MOS 6502,无十进制模式)。
  • 必须实现所有官方指令及寻址模式。

3.2 PPU 模拟

  • 实现 2C02 PPU。
  • 支持背景渲染和精灵渲染。
  • 实现时钟精确的扫描线渲染。

3.3 Mapper 支持

  • 必须支持 Mapper 0 (NROM):这是运行 shark.nes 的核心需求。
  • NROM 支持 16KB 或 32KB PRG ROM,以及 8KB CHR ROM。

3.4 性能要求

  • 在 MacOS 上达到稳定的 60 FPS。
  • 严禁在热点路径(如 tick(), render_pixel())中使用无条件的 printlogging

3.6 视觉验证需求

  • 截图测试机制:系统需支持将当前渲染帧导出为截图文件,用于与参考画面进行对比,确保渲染逻辑(如 Sprite 0 Hit, 背景滚动)的 100% 正确性。
  • 目标游戏测试:必须通过对比 shark.nes 在真机或成熟模拟器上的截图,验证本模拟器的渲染输出。

NES 模拟器总体设计文档 (Design.md)

1. 架构总览

本模拟器采用典型的总线架构,运行于 ./.venv/bin/python 环境,通过 Bus 模块连接 CPU, PPU, APUCartridge

2. 核心同步契约 (Master Clock Loop)

  • 主时钟频率: 约为 21.477272 MHz (NTSC)。
  • 同步原则:
    • 1 个 CPU 周期 = 3 个 PPU 周期。
    • APU 周期与 CPU 周期同步(或为 CPU 频率的一半,取决于实现细节)。
  • 循环逻辑: ...

3. 模块接口契约 (Interface Protocol)

为了保证各模块的解耦与互换性,统一采用 read/write 接口。

3.1 Bus 接口

  • read(addr: int) -> int: 从总线读取数据。
  • write(addr: int, val: int): 向总线写入数据。

3.2 CPU 接口

  • reset(): 重置 CPU 状态。
  • step() -> int: 执行下一条指令,返回消耗的 CPU 周期数。
  • interrupt_nmi(): 触发不可屏蔽中断。
  • interrupt_irq(): 触发普通中断请求。

3.3 PPU 接口

  • read_register(addr: int) -> int: CPU 读取 PPU 寄存器 ($2000-$2007)。
  • write_register(addr: int, val: int): CPU 写入 PPU 寄存器。
  • step(): PPU 步进一个时钟周期。

3.4 Cartridge/Mapper 接口

  • read_prg(addr: int) -> int: 读取 PRG ROM 数据。
  • write_prg(addr: int, val: int): 写入 PRG (通常用于 Mapper 控制)。
  • read_chr(addr: int) -> int: 读取 CHR ROM/RAM 数据。
  • write_chr(addr: int, val: int): 写入 CHR 数据。

4. 内存映射 (Memory Map)

  • CPU:
    • $0000 - $07FF: 2KB 内部 RAM (带有 3 个镜像,至 $1FFF)。
    • $2000 - $2007: PPU 寄存器 (每 8 字节镜像,至 $3FFF)。
    • $4000 - $4017: APU 与 I/O 寄存器。
    • $4020 - $FFFF: Cartridge 空间 (包含 PRG ROM, Mapper 寄存器等)。
  • PPU:
    • $0000 - $1FFF: Pattern Tables (CHR ROM/RAM)。
    • $2000 - $2FFF: Name Tables (VRAM)。
    • $3000 - $3EFF: Name Tables 镜像。
    • $3F00 - $3FFF: Palette RAM。

5. 调试与验证控制

  • 全局 DEBUG_MODE 开关。
  • 条件日志记录:if DEBUG_MODE: log(...)
  • 截图验证协议:主循环需集成截图触发接口,允许在特定周期或通过快捷键捕获当前 FrameBuffer,并将其保存为 .png.bmp 格式,作为回归测试的依据。

NES 模拟器总体进度清单 (Checklist.md)

第一阶段:前置探测与架构设计

  • √ 前置探测:使用 ./.venv/bin/python 解析 shark.nes 报头
  • √ 编写需求文档 (Requirement.md)
  • √ 编写总体设计文档 (Design.md)
  • √ 划分模块文档并生成 Checklist (design/)
  • √ 生成总体进度清单 (Checklist.md)

第二阶段:智能体协同开发

  • √ 创建项目目录结构 (src/)
  • √ 开发总线模块 (bus.py)
  • √ 开发卡带与 Mapper 0 模块 (cartridge.py)
  • √ 开发 CPU 6502 核心 (cpu.py)
  • √ 开发 PPU 渲染核心 (ppu.py)
  • √ 开发 APU 音频核心 (apu.py)
  • √ 开发输入映射模块 (input.py)
  • √ 开发主程序入口 (main.py)

第三阶段:闭环测试与交付

  • √ 阶段 A:使用 ./.venv/bin/python 进行 CPU 指令集单元测试
  • √ 阶段 B:集成测试 (Blargg's Test ROMs / 核心逻辑验证)
  • √ 阶段 C:真机测试 (使用 ./.venv/bin/python 运行 shark.nes 冒烟测试)
  • √ 视觉对齐测试:通过截图比对验证 shark.nes 渲染输出
  • √ 性能优化与 Bug 修复
  • √ 交付最终版本

APU 模块设计文档 (APU.md)

1. 目标

模拟 NES 音频产生单元,提供基本声音支持。

2. 通道支持

  • Pulse 1 & 2
  • Triangle
  • Noise
  • DMC (可选,视进度而定)

3. 开发与测试进度清单

  • ⚪ 实现 Pulse 通道逻辑
  • ⚪ 实现 Triangle 通道逻辑
  • ⚪ 实现 Noise 通道逻辑
  • ⚪ 实现 APU 帧计数器 (Frame Counter)
  • ⚪ 实现音频缓冲区与后端 (Pygame/PySDL2) 集成
  • ⚪ 验证基本音调输出

Bus 模块设计文档 (Bus.md)

1. 目标

连接所有硬件组件,管理 CPU 的内存映射。

2. 连接组件

  • CPU
  • PPU (通过寄存器映射)
  • APU (通过寄存器映射)
  • Cartridge (PRG/CHR 访问)
  • Controller (输入接口)

3. 内存路由逻辑

  • 0000-1FFF: RAM (含镜像)
  • 2000-3FFF: PPU 寄存器 (含镜像)
  • 4000-4017: APU/IO 寄存器
  • 4018-401F: 调试/禁用
  • 4020-FFFF: Cartridge (Mapper)

4. 开发与测试进度清单

  • ⚪ 实现基础 read/write 路由逻辑
  • ⚪ 实现 RAM 镜像支持
  • ⚪ 实现 PPU 寄存器镜像支持
  • ⚪ 实现 Cartridge 动态挂载接口
  • ⚪ 编写总线完整性测试脚本

Cartridge 模块设计文档 (Cartridge.md)

1. 目标

解析 .nes 文件并实现 Mapper 逻辑。

2. 支持范围

  • Mapper 0 (NROM):
    • PRG ROM: 16KB 或 32KB。
    • CHR ROM: 8KB。
    • 镜像: 垂直或水平。

3. 开发与测试进度清单

  • ⚪ 实现 iNES 文件解析器
  • ⚪ 实现基础 Mapper 接口
  • ⚪ 实现 Mapper 0 类
  • ⚪ 处理 PRG/CHR ROM 的内存映射
  • ⚪ 支持镜像模式切换
  • ⚪ 测试不同大小的 NROM 镜像

CPU 模块设计文档 (CPU.md)

1. 目标

实现 Ricoh 2A03 (6502) 核心,支持所有官方指令。

2. 状态寄存器 (P)

  • C: Carry
  • Z: Zero
  • I: Interrupt Disable
  • D: Decimal Mode (NES 中未使用,但物理存在)
  • B: Break
  • V: Overflow
  • N: Negative

3. 核心方法

  • reset(): 将 PC 指向中断向量 $FFFC/$FFFD
  • step(): 执行下一条指令。
  • read(addr): 通过 Bus 读取。
  • write(addr, val): 通过 Bus 写入。

4. 开发与测试进度清单

  • ⚪ 定义 CPU 寄存器和状态变量
  • ⚪ 实现基础寻址模式 (Immediate, ZeroPage, Absolute, etc.)
  • ⚪ 实现数据传输指令 (LDA, STX, etc.)
  • ⚪ 实现算术运算指令 (ADC, SBC, etc.)
  • ⚪ 实现逻辑运算指令 (AND, EOR, etc.)
  • ⚪ 实现分支与跳转指令 (JMP, BNE, etc.)
  • ⚪ 实现堆栈操作指令 (PHA, PLA, etc.)
  • ⚪ 实现中断处理 (NMI, IRQ, RESET)
  • ⚪ 集成 nestest.nes 进行指令集验证
  • ⚪ 优化热点路径性能
  • 时序验证:确保 CPU 与 PPU 的时序同步足以通过截图测试观察到正确的画面滚动与精灵碰撞。

Input 模块设计文档 (Input.md)

1. 目标

将 MacOS 键盘/手柄输入映射至 NES 控制器状态。

2. 寄存器映射

  • $4016: Controller 1
  • $4017: Controller 2

3. 开发与测试进度清单

  • ⚪ 定义控制器按键位掩码
  • ⚪ 实现 CPU 串行读取逻辑 (Strobe)
  • ⚪ 实现键盘输入映射 (Pygame Event -> NES State)
  • ⚪ 测试连发与多键同时按下

PPU 模块设计文档 (PPU.md)

1. 目标

实现 2C02 PPU,负责背景与精灵渲染。

2. 核心寄存器

  • $2000: PPUCTRL
  • $2001: PPUMASK
  • $2002: PPUSTATUS
  • $2003: OAMADDR
  • $2004: OAMDATA
  • $2005: PPUSCROLL
  • $2006: PPUADDR
  • $2007: PPUDATA

3. 渲染流程

  • 262 条扫描线 (NTSC)。
  • 每条扫描线 341 个 PPU 周期。
  • 实现背景 Tile 抓取逻辑。
  • 实现 Sprite 0 Hit 检测。
  • 实现 VBlank 中断触发。

4. 开发与测试进度清单

  • ⚪ 实现 PPU 内部寄存器读写逻辑
  • ⚪ 实现 VRAM 与 Palette RAM 存储
  • ⚪ 实现背景 Tile 渲染 (NameTable -> AttributeTable -> PatternTable)
  • ⚪ 实现精灵 (Sprite) 渲染与 OAM 管理
  • ⚪ 实现细粒度滚动 (Fine Scroll)
  • ⚪ 实现扫描线时序同步
  • ⚪ 实现 VBlank 中断逻辑
  • ⚪ 集成颜色调色板 (Palette)
  • ⚪ 通过图形单元测试验证渲染正确性
  • 视觉交付验证:实现 FrameBuffer 截图功能,并完成 shark.nes 的渲染画面对比测试。

自动写好文档后,根据文档指示,AI等待我们来审核。作为小白的我也没兴趣看这些文档,直接当牛马让其写代码呗,于是最后生成了以下文件

src/apu.py
src/bus.py
src/cartridge.py
src/cpu.py
src/input.py
src/main.py
src/ppu.py
test/screenshot_test.py
test/smoke_test.py
test/test_cpu_basic.py
test/test_cpu_instructions.py

刚写好的代码直接运行还是有瑕疵的,比如画面卡顿,但是让其自己优化2轮后,就已经很完美了,最后效果如下:



截屏2026-05-17 13.14.06.png
回复

使用道具 举报

发表于 2026-7-12 16:55:20 | 显示全部楼层
帮你处理了一下,现在可以显示了
回复 赞! 靠!

使用道具 举报

本版积分规则

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2026-8-16 17:11 , Processed in 0.024220 second(s), 8 queries , Gzip On, Redis On.

Powered by Discuz! X5.0

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表