Emulation 是否可以按程序确定特定指令在6502上的周期数?

Emulation 是否可以按程序确定特定指令在6502上的周期数?,emulation,6502,Emulation,6502,大多数模拟器将特定指令的周期数存储在查找表中,然后根据需要添加任何条件周期(例如,当跨越页面边界时) 我想知道是否有一种方法可以根据寻址模式和内存读/写,按程序确定一条指令的周期数 举个例子,我注意到所有使用直接寻址或相对寻址的指令都需要2个周期 所有零页指令都需要3个周期,如果更改内存,还需要另外2个周期 所有索引零页指令都需要4个周期,如果更改内存位置,还需要额外的2个周期 ……等等 那么,是否有一些完整记录的程序性方法来确定上述指令的周期数?在这样一个公式中,是否存在打破决定论的例外情况?

大多数模拟器将特定指令的周期数存储在查找表中,然后根据需要添加任何条件周期(例如,当跨越页面边界时)

我想知道是否有一种方法可以根据寻址模式和内存读/写,按程序确定一条指令的周期数

举个例子,我注意到所有使用直接寻址或相对寻址的指令都需要2个周期

所有零页指令都需要3个周期,如果更改内存,还需要另外2个周期

所有索引零页指令都需要4个周期,如果更改内存位置,还需要额外的2个周期

……等等


那么,是否有一些完整记录的程序性方法来确定上述指令的周期数?在这样一个公式中,是否存在打破决定论的例外情况?

是的-几乎所有精确的仿真器都是这样编写的*;请参阅文档,如。不过,这并不比简单的内存访问计数复杂多少——6502将在每个周期执行内存访问,它通常可以在访问后的剩余周期内获得有意义的结果(即,为了避免讨论什么是流水线的,什么不是流水线的;请参阅文档)

因此,例如,对于
ADC#54
,处理器必须(i)读取操作码;(ii)读取操作数。这是两个周期

对于
ADC($32),Y
即:

  • 读取操作码
  • 读取操作数
  • 从$32读取以获取地址的低字节
  • 从$33读取以获取地址的高字节,将Y添加到地址的低字节
  • 读取自(地址的高字节):(地址的低字节+Y),因为只有时间执行低字节计算
  • 哦,等等,如果有进位,那么最后的结果是错误的,最好再读一遍。如果不是的话,很好,一切都很好,不用担心这个周期
  • 所以要么是5个周期,要么是6个周期

    您始终可以将内存访问模拟为一步一步的定时操作,并将实际操作作为正交步骤执行。使用相同的逻辑进行读、写或读修改写也很容易:读和写具有相同的计时,但最后进行不同的内存访问,tead modify在计算实际结果时将所有读值写回一个周期,然后写入实际结果

    *)因为同时执行所有内存访问,而不包括任何冗余访问,所以将时间向前弯曲一点与实际硬件完全不同。一旦对任何具有独立时间概念的东西进行内存访问,它就会绊倒你——计时器或任何可能产生中断的东西,或者如果机器扫描RAM以获取其视频输出,它只会扫描RAM本身;不要介意它要求您在指令周围添加特殊情况,如
    CLI
    SEI
    **。仿真器的结构不再需要像20世纪90年代那样


    **)IRQ状态在每个操作的倒数第二个周期进行采样
    CLI
    SEI
    在最后一个循环中调整位。因此,即使中断处于挂起状态,
    CLI
    也不会导致中断,直到
    CLI
    之后的指令之后。它本身可能是一个
    SEI
    。因此,当中断挂起时,
    CLI
    /
    SEI
    对应在执行
    SEI
    后,设置中断标志,导致中断处理程序跳闸。如果您模拟6502的逐周期行为,这种情况会自然而然地发生。如果您正在逐操作和时间扭曲工作,则这可能是一个巨大的难题。或者,更可能的是,这种仿真器的行为显然是错误的。

    我总是必须使用类似a的参考来获取旧Atari 8位系列外围设备的精确计时,这些外围设备在串行接口上以52个周期或19个周期/位(1 mhz 6502)的速度手动发送或接收一个位。(~19200位/秒或~52600位/秒)。观察内存中所有读/写操作(包括冗余的读/写操作)的一个很好的资源是,这是SEI,而不是STI。@8位大师,这就是为什么你是大师!设置中断,不设置中断;固定的。