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

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
技术宅的结界 门户 查看主题

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

发布者: lichao | 发布时间: 2026-5-17 13:15| 查看数: 63| 评论数: 0|帖子模式

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

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

×
本帖最后由 lichao 于 2026-5-17 13:26 编辑

大概从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`)
* 图形与音频库:优先使用 `Pygame` 或 `PySDL2`(确保 `MacOS` 上的流畅度和 `60 FPS` 时钟同步)。
* 【性能红线】:严禁在 `CPU/PPU` 的主循环(热点路径如 `tick()`, `render_pixel()`)中加入任何无条件的 `print` 或 `logging` 语句。所有调试日志必须有开关(`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` 编号。
3. 编写需求文档 (`./Requirement.md`):基于探测结果,明确模拟器必须支持该游戏的 `Mapper` 类型。
4. 编写总体设计文档 (`./Design.md`):
   - 明确主时钟循环(Master Clock Loop):必须遵循 **1 个 CPU 周期 = 3 个 PPU 周期** 的精确同步契约。
   - 制定各个 Python 模块的接口契约(`Interface Protocol`),统一方法签名(如 `read(addr)`, `write(addr, val)`)。
5. 划分模块文档:在 `design/` 下生成各模块的子文档,每个文档内必须包含详细的【开发与测试进度清单 (Checklist)】。
6. 生成总体进度清单 (`./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()`)中使用无条件的 `print` 或 `logging`。

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

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

## 1. 架构总览
本模拟器采用典型的总线架构,运行于 `./.venv/bin/python` 环境,通过 `Bus` 模块连接 `CPU`, `PPU`, `APU` 和 `Cartridge`。

## 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)

## 第一阶段:前置探测与架构设计
- [x] 前置探测:使用 `./.venv/bin/python` 解析 `shark.nes` 报头
- [x] 编写需求文档 (`Requirement.md`)
- [x] 编写总体设计文档 (`Design.md`)
- [x] 划分模块文档并生成 Checklist (`design/`)
- [x] 生成总体进度清单 (`Checklist.md`)

## 第二阶段:智能体协同开发
- [x] 创建项目目录结构 (`src/`)
- [x] 开发总线模块 (`bus.py`)
- [x] 开发卡带与 Mapper 0 模块 (`cartridge.py`)
- [x] 开发 CPU 6502 核心 (`cpu.py`)
- [x] 开发 PPU 渲染核心 (`ppu.py`)
- [x] 开发 APU 音频核心 (`apu.py`)
- [x] 开发输入映射模块 (`input.py`)
- [x] 开发主程序入口 (`main.py`)

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

# 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



最新评论

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

GMT+8, 2026-5-22 10:40 , Processed in 0.037147 second(s), 27 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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