我正在用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...or我可以在一个“循环”(一个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是一种可行的解决方案,但是我想不出一种正确、简单的方法来实现它.(请救救!)
发布于 2017-07-25 22:08:22
你“需要”吗?这取决于软件。想象一下最简单的例子:
STA ($56), Y..。碰巧撞到了一个硬件寄存器。如果您至少没有对正确的周期进行写,那么您就引入了一个时间缺陷。您要写的寄存器将在错误的时间写到。如果它类似于调色板寄存器,而程序员运行的是光栅效果呢?然后你就移到了颜色变化的地方。您已经更改了图形输出。
实际上,聪明的程序员所做的事情要聪明得多--例如,一个人可能会使用读-修改-写操作在一个确切的周期读取一个硬件值,修改它,然后在另一个精确的周期中将它写回。
所以我的答案是:
大多数仿真器使用您的方法(2)。通常情况下,它们与90%的软件一起工作。然后有一些不起作用的情况,模拟器作者在这里加入了一个特例,一个特例。通常情况下,仿真器的交互效果很差,模拟器在支持不同的95%可用软件组合之间的余生都在振荡,直到有人写了一个更好的软件。
所以,就用方法(1)。它将导致一些软件,否则会被破坏,不是这样。此外,它还将教给您更多的知识,并且肯定会消除任何特殊情况的潜在动机,从而使您的代码更加整洁。它会稍微慢一点,但我认为你的电脑可能能处理它。
其他提示: 6502只有几种寻址模式,而寻址模式完全决定了时间。本文件是所有你需要知道的完美时机。如果您想要完美的清洁,您的开关表可以选择一个寻址模式和一个中央操作,然后退出,您可以分支到寻址模式来执行主要操作。
如果要使用普通的read和write方法,这在6502上是很聪明的,因为每个周期都是读或写,所以这几乎是您需要说的全部,小心方法签名就行了。例如,6502具有同步引脚,该同步引脚允许观察者区分普通读取和操作码读取。检查NES是否将其公开给墨盒,因为它通常用于公开它用于隐式分页的系统,NES的主要识别特征是有数百种寻呼方案。
编辑:小更新:
https://stackoverflow.com/questions/45305891
复制相似问题