【GameBoy模拟器 4】实现所有LD指令及其寻址模式

先把LD指令全支持了再说

在上一part中,已经了解了实现一个新指令的流程,这一part,我们需要实现全部LD指令

目标:

  • 实现全部LD指令,及其所需的全部寻址模式
  • 继续体会寻址的过程、CPU取数据和执行指令的步骤
  • 了解指令的性质,能够把参考资料翻译成指令的实现(寻址模式、具体逻辑、机器周期开销等)

知识点

  • 原项目在指令实现上的一些的问题
    • gbemu原项目的寻址模式里,没有考虑读取opcode需要的机器(2位16进制数的opcode=8位2进制数->一个机器周期),忽略了这一点。
    • gbemu对于指令原理的讲解很缺失,开发过程中的实现也有问题。比如part4的bus_read16/bus_write16、proc_ld时钟周期开销不对
  • 大家学习时注意抓大放小
    • 不要太在意这部分,大多数细节最终会忘记的,挑一两个典型指令深入理解,能够在模拟器框架下对着参考资料实现出指令即可。
    • 更重要的是理解指令、CPU、总线的关系,CPU执行指令的流程、指令具有哪些性质、一个CPU大概有哪些指令?为什么要这样设计?这些才是有用的问题
  • 关于不同的指令参考资料

成果:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
(base) $ gbemu/gbemu ../../roms/cpu_instrs.gb 
Opened: ../../roms/cpu_instrs.gb
Cartridge Loaded:
         Title    : CPU_INSTRS
         Type     : 01 (MBC1)
         ROM Size : 64 KB
         RAM Size : 00
         LIC Code : 00 (None)
         ROM Vers : 00
         Checksum : 3B (PASSED)
Cart loaded..
SDL INIT
TTF INIT
0100: NOP      (00 C3 37) A: 01 B: 00 C: 00
0101: JP       (C3 37 06) A: 01 B: 00 C: 00
0637: JP       (C3 30 04) A: 01 B: 00 C: 00
0430: DI       (F3 31 FF) A: 01 B: 00 C: 00
0431: LD       (31 FF DF) A: 01 B: 00 C: 00
0434: LD       (EA 00 D6) A: 01 B: 00 C: 00
UNSIPPORTED bus_write(D600)
0437: LD       (3E 00 E0) A: 01 B: 00 C: 00
0439: <NONE>   (E0 07 3E) A: 00 B: 00 C: 00
INVALID INSTRUCTION!

可以看到,成功执行了31EA3E三种LD指令,并且通过debug输出,发现下一个应该支持的指令为E0

代码实现:

https://github.com/SimpleCodeJust4Fun/CBoy/pull/3

Licensed under CC BY-NC-SA 4.0
最后更新于 Jun 25, 2025 15:02 UTC
Built with Hugo
Jimmy 设计的 Stack 主题