我完成了编写6502仿真器的准备,可以开始对其进行测试了。我找到了nestest ROM,其中包含一些文档,但是我不确定装入ROM的正确方法是什么。作者说,仿真器应从0xC000开始,当我加载ROM时,它应包含0,因此我必须做错了什么。

因此,现在我的加载过程如下所示:

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

最佳答案

根据Nick Westgate的评论(因此,请参见即时社区Wiki),加载过程is a bit more complicated than you might naively guess


  目前,您可以加载从偏移量0x0010开始的0x4000字节,并映射
  作为ROM进入仿真的$ 8000- $ BFFF和$ C000- $ FFFF
  6502的内存映射。


“现在”假设您将要编写NES仿真器,因此有一天可以正确地解析存储测试的NES相关文件格式,并模拟导致内容镜像的NES特定内存映射方案。

忽略帖子中的评论之前,您应该在每个周期“ [记录] PC(和寄存器)”,以及该帖子及其后的含义;他的意思是:


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


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

进一步建议:

NES实际上并没有使用6502。它使用的克隆忽略了十进制模式-十进制标志根本无效。因此,如果您要模拟6502,则预期测试结果会有所不同。

有关其他良好的6502测试,请参阅:


AllSuiteA(测试一堆东西,使您通过或失败);
Klaus Dormann's tests(稍微麻烦一些;如果特定测试失败,将在某个地方简单地进入无限循环。您需要检查源以找出遇到的失败);和
Wolfgang Lorenz's tests(一大堆单独的测试,最初是要在C64上单独运行,但要易于运行,无需在6502之外执行任何操作,除了要在PETSCII中提供状态文本输出外,因此您还需要一个快速查找表以将其映射到ASCII)。


我使用了所有这三个方法来引导我最新的6502仿真器,以及一些自写的逐周期测试,以测试诸如中断之类的事情,您不会期望位于6502地址空间内的代码能够处理。

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


BCDTEST_beeb的内容加载到0x2900
JSR 2900h写入地址0x200;
RTS处放置0xffee,但还要确保可以捕获该地址;
将程序计数器设置为0x200并继续运行,直到它位于0x203为止;
然后测试0x84的值是0。如果还有其他问题,则表明存在故障。


为了获得更多反馈,只要PC进入0xffee,就在A寄存器中输出ASCII字符。

关于testing - 如何加载Nested ROM?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46998060/

10-12 05:18