每条指令6502周期时间

时间:2017-07-25 14:13:07

标签: emulation opcode 6502

我正在C中编写我的第一个NES模拟器。目标是使其易于理解并且周期准确(尽管不一定必须具有代码效率),以便以正常的“硬件”速度玩游戏。当深入研究6502的技术参考时,似乎指令消耗了多个CPU周期 - 并且根据给定条件(例如分支)也有不同的周期。我的计划是创建读写函数,并使用switch通过寻址模式对操作码进行分组。

问题是:当我有一个多周期指令时,例如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是即用型解决方案,但是我想不出一个适当,简单的方法来实现它...(请帮忙!)

1 个答案:

答案 0 :(得分:5)

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

STA ($56), Y

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

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

所以我的答案是:

  1. 大多数软件都没有写入,因此(1)和(2)之间的差异会产生任何影响;但
  2. 一些肯定是,因为作者非常聪明;和
  3. 一些肯定是,只是因为作者试验,直到他们发现了一个很酷的效果,无论他们是否认识到原因;和
  4. 在任何情况下,当您在模拟器上发现无法正常工作的内容时,考虑所有排列和潜在原因的组合,您希望花多少时间?你可以考虑的每一个都不用考虑。
  5. 大多数模拟器过去常用你的方法(2)。通常情况下,他们使用90%的软件。然后有一些不起作用的情况,模拟器作者在这里提出了一个特殊情况,一个特殊情况。那些通常最终会很糟糕地进行交互,并且仿真器在其余的生命周期中支持不同的95%可用软件组合,直到有人写出更好的软件。

    所以请使用方法(1)。它会导致一些本来会被破坏的软件不会如此。它还会教你更多,它肯定会消除特殊情况的任何潜在动机,因此它会让你的代码更清洁。它会慢一点,但我认为你的电脑可以处理它。

    其他提示:6502只有几种寻址模式,寻址模式完全决定了时序。 This document是您完美计时所需要知道的一切。如果您想要完美的清洁度,您的开关表可以选择寻址模式和中央操作,然后退出,您可以分支寻址模式进行主要操作。

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

    编辑:次要更新:

    • 说6502总是读或写是不完全正确的;它还有一个RDY输入。如果RDY输入被置位且6502打算读取,则它将在保持预期读取地址的同时停止。在实践中很少使用,因为它不足以完成普通任务,例如允许其他人拥有内存 - 无论RDY输入如何,6502都会写入,它实际上是为了帮助单步执行 - 而且似乎不包含在NES {{3你不需要为那台机器实现它。
    • 根据相同的引脚排列,同步信号似乎也不会暴露在该系统的磁带上。