在业余时间,我开始为6502 CPU编写一个非常简单的C++模拟器。
我曾经为该CPU编写了大量的汇编代码,因此所有操作码,寻址模式和其他内容都不是什么大问题。

6502具有56种不同的指令以及13种寻址模式,总共提供151种不同的操作码。对我而言,速度不是问题,所以与其写一个巨大的switch-case语句并一次又一次地重复相同的代码(不同的操作码可以使用不同的寻址模式来引用同一条指令),我想将实际的指令代码与寻址模式代码:我发现此解决方案非常简洁,因为只需要编写13个寻址模式函数和56个指令函数就可以了。

寻址模式在这里起作用:

// Addressing modes
uint16_t Addr_ACC(); // ACCUMULATOR
uint16_t Addr_IMM(); // IMMEDIATE
uint16_t Addr_ABS(); // ABSOLUTE
uint16_t Addr_ZER(); // ZERO PAGE
uint16_t Addr_ZEX(); // INDEXED-X ZERO PAGE
uint16_t Addr_ZEY(); // INDEXED-Y ZERO PAGE
uint16_t Addr_ABX(); // INDEXED-X ABSOLUTE
uint16_t Addr_ABY(); // INDEXED-Y ABSOLUTE
uint16_t Addr_IMP(); // IMPLIED
uint16_t Addr_REL(); // RELATIVE
uint16_t Addr_INX(); // INDEXED-X INDIRECT
uint16_t Addr_INY(); // INDEXED-Y INDIRECT
uint16_t Addr_ABI(); // ABSOLUTE INDIRECT

它们都返回指令用来读取/写入操作数/结果的实际内存地址(16位)

指令函数原型(prototype)为:
void Op_ADC(uint16_t addr);
void Op_AND(uint16_t addr);
void Op_ASL(uint16_t addr);
    ...

它使用16位地址,执行自己的操作,更新状态标志和/或寄存器,并将结果(如果有)提交到相同的存储器地址上。

鉴于该代码框架,我发现很难使用ACCUMULATOR寻址模式,这是唯一一种返回A内部寄存器而不是内存地址的实际值的模式。我可以使用uin16_t返回类型返回A的值,并为这种寻址模式添加一个 bool 标志,但是我发现这是一个非常丑陋的解决方案。

指令功能应完全与寻址模式无关。

最佳答案

在Sharp6502(用C#编写的我的6502仿真引擎)中,我将内部寄存器和外部存储器都视为一类对象-MemoryManager类实例化了一个对象用于外部存储器,另一个实例化了内部寄存器,映射到了不同的数值范围。因此,内存访问和寄存器访问在功能级别上是相同的,因为它们都是通过MemoryManager根据基本上是索引的方式引用的。

地址模式的区别只是在仿真中过滤指令的位模式并执行非常简单的计算以确定要传递给MemoryManager的索引的问题-这可能是隐含的,或者需要一个或两个另外的字节,但是每条指令的基 native 制都是相同的。

10-04 11:32