2017-10-29 126 views
0

我写完了我的6502模拟器,我准备开始测试它。我发现了带有一些文档的ROM,但我不确定,加载ROM的正确方式是什么。作者说,模拟器应该从0xC000开始,当我加载ROM时,它包含0,所以我必须做错了什么。如何加载最新的ROM?

所以现在我的加载过程看起来是这样的:

clear memory 
set PC to 0x8000 
open the file 
skip first 16 bytes (iNES header) 
load the rest of the file into RAM (starting at 0x8000) 
set PC to 0xC000 
+1

看起来你需要在[0x8000和0xC000](https://github.com/PyAndy/Py3NES/issues/1)上加载它。 –

+0

哦,这不是所谓的镜像吗? –

回答

2

按照尼克梅龙镇的评论(因此即时群体维基),加载过程is a bit more complicated than you might naively guess

现在,你可以从偏移量0x0010开始加载0x4000字节,并且将 作为ROM加载到仿真的 6502的存储器映射的$ 8000- $ BFFF和$ C000- $ FFFF中。

'现在'假设你要编写一个NES模拟器,因此有一天会正确解析测试存储在NES相关的文件格式并模拟NES特定的内存映射方案到内容的镜像。

在此之前,您应该忽略注释,您应该“在每个周期”[登录]您的PC(并注册)“,以及在该帖子之后的含义;他的意思是:

  1. 取出第一个操作码字节之前,做一个程序计数器和其他寄存器的内部记录;
  2. 在读完最终操作数字节后,记录您在步骤(1)中存储的所有值加上完整指令及其反汇编。

如果您已经简化了模拟器中的内容,以原子方式读取和执行每个操作,然后将时间提前跳过应花费的周期数,那么您可能会忽略临时存储。我怀疑生成示例日志的作者已经实现了这种模拟。关键线索将是由操作码索引的switch表,它不以某种方式作为协程和/或指令长度的查找表。

更多建议:

的NES实际上并不使用6502它采用省略了小数模式的克隆 - 十进制标志也没有效果。所以如果你正在模拟一个6502,期望测试结果在那里变化。

对于其他好6502周的测试,请参阅:

  • AllSuiteA(测试一大堆的东西,给你一个及格或不及格);
  • Klaus Dormann's tests(稍微有点麻烦;如果某个特定的测试失败,它会在某个地方简单地进入一个无限循环),你需要检查源代码来找出你的失败。和
  • Wolfgang Lorenz's tests(一大堆单独的测试,最初是为了在C64上单独运行,但很容易在没有任何实现超过6502的情况下运行,除此之外它将提供PETSCII中的状态文本输出,所以你也可以需要一个快速查找表来将其映射到ASCII)。

我用这三种方法来引导我最近的6502仿真器,再加上一些自行编写的循环周期测试,例如中断,你不希望代码位于6502的地址空间内能够处理。

我后来发现,我在十进制处理方面有一个很小的偏差 - 小到足以通过所有这些测试,但不足以通过详尽的6502比较。我在Acorn BBC社区发现了一个更好的测试,在档案attached to this post内。我选择通过:

  • 加载BCDTEST_beeb的内容在0x2900;
  • JSR 2900h地址0x200;
  • RTS置于0xffee,但也确保你可以捕获该地址;
  • 将程序计数器设置为0x200并继续运行,直到它在0x203;
  • 然后测试0x84的值是0。如果是别的东西,则表示失败。

想要获得更多反馈,任何时候PC进入0xffee,都要在A寄存器中输出ASCII字符。

+0

感谢您的努力!所以我得到了最新的加载和运行,我可以记录一切,所以这很好。是的,有一天我会解析iNES头,一旦其他组件完全实施。 –

+0

理光CPU实际上是否有BCD标志?我注意到它的最新测试,这很奇怪,因为nesdev wiki说旗子不应该有任何效果(我认为它甚至不存在)。我不打算实施BCD模式,所以我最初避免了任何测试BCD的测试。 –

+0

我的理解是它有它,但并不尊重它。所以你可以使用'CLD' /'SED',如果你使用'PHP',你可以看到差异,但'ADC'和'SBC'将总是作为二进制。假设测试完全适合NES,可能包含的测试是你忽略了它? – Tommy