{
  "lead": "CHIP-8 是 1977 年为 COSMAC VIP 等 8 位电脑设计的一种虚拟机：4 KB 内存、16 个 8 位寄存器、64×32 的黑白屏幕、16 键键盘，只有 35 条指令。当年的游戏就是这种虚拟机的字节码。这个页面用 Rust 实现了完整的解释器，每秒按设定的速度取出一条条两字节的指令来执行。页面还带着一个汇编器：内置的三个程序都以汇编源码形式保存，可以直接修改、重新汇编并运行。",
  "formulas": [
    [
      "取指 → 译码 → 执行",
      "每条指令 2 字节，按最高 4 位分成 16 类，再由其余位取出寄存器号、立即数或地址"
    ],
    [
      "像素 ^= 精灵位，VF = 是否擦掉了像素",
      "绘图全靠异或：同一位置画两次就擦掉，同时得到碰撞检测"
    ]
  ],
  "terms": [
    [
      "指令循环",
      "程序计数器 PC 指向下一条指令，读出两个字节后 PC 加 2，再根据操作码执行：加载、算术、跳转、调用子程序（用 16 层的栈保存返回地址）、按键判断、画精灵等。模拟器并不「理解」游戏，只是忠实地逐条执行。"
    ],
    [
      "60Hz 定时器",
      "延时定时器 DT 和声音定时器 ST 每秒递减 60 次，与指令速度无关。游戏通过读 DT 控制节奏；ST 大于 0 时发出蜂鸣声（页面用 Web Audio 的方波振荡器）。浏览器每一帧可能不是 1/60 秒（比如 120Hz 屏幕），页面按真实时间累积，每满 1/60 秒才执行一帧的指令并推进定时器。"
    ],
    [
      "精灵与字体",
      "精灵是一串字节，每字节是一行 8 个像素。内存里内置了 0~F 十六个数字的 4×5 字体，<code>LD F, Vx</code> 指向对应字形，<code>LD B, Vx</code> 把数值拆成百位、十位、个位，Pong 的比分就是这样画出来的。"
    ],
    [
      "兼容性差异（quirks）",
      "CHIP-8 从来没有正式规范，不同年代的解释器对几条指令的理解不同：移位用 Vx 还是 Vy、批量存取寄存器后 I 是否前进、逻辑运算是否清 VF、精灵到边缘是裁剪还是绕回、每帧是否只允许画一次。页面提供原版 COSMAC VIP 和现代（CHIP-48 风格）两组设置；不支持 SUPER-CHIP 的扩展指令（高分辨率、滚屏）。"
    ],
    [
      "汇编与反汇编",
      "内置程序用常见的 Cowgod 助记符书写（<code>LD V0, 0x05</code>、<code>DRW V1, V2, 6</code>），汇编器扫描两遍：第一遍记下每个标签的地址，第二遍把每行翻译成操作码。调试面板里的反汇编是反方向的翻译；二进制 ROM 里代码和数据混在一起，所以数据区也会被当成指令显示。"
    ]
  ],
  "flow": [
    [
      "js",
      "选择程序时，JS 调用 <code>chip8_assemble(源码)</code> 得到 ROM 字节，再用 <code>chip8_load</code> 装入内存；本地 ROM 文件则直接装入。"
    ],
    [
      "rust",
      "每个 60Hz 帧 JS 调用一次 <code>chip8_frame(每帧指令数)</code>：Rust 连续执行这么多条指令（遇到等待按键、「每帧只画一次」或出错会提前停下），然后推进两个定时器。"
    ],
    [
      "js",
      "JS 读取 <code>chip8_display()</code> 的 2048 个像素画到 64×32 的 Canvas 上（CSS 放大并保持像素锐利，可选余辉效果减轻闪烁），按 <code>chip8_sound()</code> 开关蜂鸣，并用 <code>chip8_regs()</code> 和 <code>chip8_disasm()</code> 刷新调试面板。按键通过 <code>chip8_key</code> 传入。"
    ]
  ],
  "perf": [
    "原版 COSMAC VIP 每秒大约只能执行几百条 CHIP-8 指令，页面默认每帧 12 条（每秒 720 条），大多数游戏按这个速度设计。实测这个 WASM 解释器全速运行时每秒约 3 亿条指令，模拟本身几乎不占时间，开销主要在每帧画屏和刷新调试面板。",
    "闪烁是 CHIP-8 的特点：程序先用异或擦掉精灵、移动后再画上去，屏幕刷新恰好落在两者之间时就会看到半透明的闪烁。「余辉」选项模拟老式显示器的荧光余晖来减轻它。",
    "汇编整个 Pong 程序约 0.05ms。验证：解释器通过了 Timendus 的 CHIP-8 测试套件中的指令测试（corax+）、标志位测试（flags）和 COSMAC VIP 兼容性测试（quirks）。"
  ],
  "src": [
    [
      "crates/games/chip8/src/vm.rs",
      ""
    ],
    [
      "crates/games/chip8/src/asm.rs",
      ""
    ],
    [
      "crates/games/chip8/src/programs/pong.asm",
      ""
    ],
    [
      "www/chip8/index.js",
      ""
    ]
  ]
}
