4

我正在用 C 编写我的第一个 NES 模拟器。目标是使其易于理解和循环准确(但不一定必须是代码高效的),以便以正常的“硬件”速度玩游戏。在深入研究 6502 的技术参考资料时,这些指令似乎消耗了多个 CPU 周期 - 并且根据给定条件(例如分支)也有不同的周期。我的计划是创建读写函数,并通过使用switch.

问题是:当我有一个多周期指令时,例如 a BRK,我是否需要模拟每个周期中到底发生了什么:

#Method 1

cycle - action

1 - read BRK opcode
2 - read padding byte (ignored)
3 - store high byte of PC
4 - store low byte of PC
5 - store status flags with B flag set
6 - low byte of target address
7 - high byte of target address

...或者我可以在一个“周期”(一个switch case)中执行所有必需的操作,而在剩余的周期中什么都不做吗?

#Method 2

1 - read BRK opcode,
read padding byte (ignored),
store high byte of PC,
store low byte of PC,
store status flags with B flag set,
low byte of target address,
high byte of target address
2 - do nothing
3 - do nothing
4 - do nothing
5 - do nothing
6 - do nothing
7 - do nothing

由于这两种方法都消耗了所需的 7 个周期,所以两者之间没有区别吗?(准确性方面)

就我个人而言,我认为方法 1 是可行的解决方案,但是我想不出一个合适的、简单的方法来实现它……(请帮忙!)

4

1 回答 1

9

你“需要”吗?这取决于软件。想象一个最简单的例子:

STA ($56), Y

...碰巧碰到了硬件寄存器。如果您至少没有在正确的周期上进行写入,那么您就引入了时序缺陷。您正在写入的寄存器将在错误的时间写入。如果它类似于调色板寄存器,而程序员正在运行光栅效果怎么办?然后你刚刚移动了颜色变化的地方。您已更改图形输出。

在实践中,聪明的程序员会做比这更聪明的事情——例如,一个人可能会使用读-修改-写操作以精确的周期读取硬件值,对其进行修改,然后在其他精确的周期将其写回。

所以我的回答是:

  1. 大多数软件的编写并不是为了使(1)和(2)之间的差异产生任何影响;但
  2. 有些肯定是,因为作者很聪明;和
  3. 有些肯定是,只是因为作者实验直到他们发现了一个很酷的效果,不管他们是否知道原因;和
  4. 无论如何,当您发现某些东西在您的模拟器上无法正常工作时,您想花多少时间考虑所有潜在原因的排列和组合?您可以考虑的每一个因素都少了一个需要考虑的因素。

大多数模拟器曾经使用您的方法(2)。通常情况下,它们可以与 90% 的软件一起使用。然后有一些情况不起作用,模拟器作者在这里放一个特例,那里放一个特例。那些通常以糟糕的交互告终,模拟器的余生都在支持可用软件的不同 95% 组合之间摇摆不定,直到有人写出更好的组合。

所以只需使用方法(1)。这将导致一些否则会被破坏的软件不会如此。它还会教你更多,它肯定会消除特殊情况的任何潜在动机,因此它会让你的代码更干净。它会稍微慢一些,但我认为您的计算机可能可以处理它。

其他提示:6502 只有几种寻址模式,寻址模式完全决定了时序。这份文件是你需要知道的一切,以获得完美的时机。如果您想要完美的清洁度,您的开关表可以选择寻址模式和中央操作,然后退出,您可以分支到寻址模式以执行主要操作。

如果您要使用 vanillareadwrite方法,这在 6502 上很智能,因为每个周期都是读取或写入,所以您几乎只需要说,请注意方法签名。例如,6502 有一个 SYNC 引脚,它允许观察者区分普通读取和操作码读取。检查 NES 是否将其暴露给磁带,因为它经常用于将其暴露于隐式分页的系统上,并且 NES 的主要识别特征是有数百种分页方案。

编辑:小更新:

  • 说 6502 总是读或写实际上并不完全正确;它也有一个RDY输入。如果 RDY 输入被置位并且 6502 打算读取,它将改为停止,同时保持预期的读取地址。在实践中很少使用,因为它不足以完成诸如允许其他人占用内存之类的常见任务——无论 RDY 输入如何,6502 都会写入,它实际上是为了帮助单步执行——并且似乎不包括在 NES墨盒引脚分配中,你不需要为那台机器实现它。
  • 根据相同的引脚排列,同步信号似乎也不会暴露在该系统上的磁带上。
于 2017-07-25T22:08:22.690 回答