Z80内存刷新寄存器

时间:2011-12-16 21:44:18

标签: fetch cpu-registers z80 opcodes

我再次提出另一个无关紧要的Z80问题:-)我的仿真器内核当前的结构方式,每次从内存中取出操作码字节时,我都会递增内存刷新寄存器的低7位 - 这意味着多字节我将递增寄存器两次 - 或者在诸如RLC(IX + d)之类的指令实例中递增三次(因为它的布局是opcode1-opcode2-d-opcode3)。

这是对的吗?我不确定 - Z80手册有点不清楚,因为它说CPDR(一个双字节指令)将它增加两倍,但是“存储器刷新寄存器”部分仅表示它在每次取指令后递增。我注意到J80(我检查的模拟器,因为我不确定)只在指令的第一个操作码字节后递增。

哪个是对的?我想这在任何情况下都不是非常重要,但是很高兴知道:-)非常感谢。

此致 菲尔波特

4 个答案:

答案 0 :(得分:13)

Zilog时序图可以解答您的问题。

在所有M1(操作码获取)周期的T3和T4期间发生刷新。

在单操作码指令的情况下,每个指令刷新一次。对于单前缀指令(使用M1周期读取前缀),每个指令刷新两次。

对于那些奇怪的DD-CB-disp-opcode和FD-CB-disp-opcode类型指令(很奇怪因为位移字节最终操作码之前而不是之后),所以刷新至少为3(对于两个前缀和最终操作码),但我不确定位移字节是作为M1周期的一部分(将触发另一次刷新)还是正常的存储器读周期(无刷新)读取。我倾向于相信这些指令在M1周期中读取位移字节,但我不确定。我问Sean Young这件事;他也不确定。有人知道吗?

更新:

我回答了我自己的问题,那些奇怪的DD-CB-disp-opcode和FD-CB-disp-opcode指令。如果您检查Zilog的文档以获取这些类型说明,例如 RLC(IX + d),你会注意到该指令需要6个M周期和23个T周期,分解为:(4,4,3,5,4,3)。

我们知道前两个M周期是M1周期,用于获取DD和CB前缀(每个4个T周期)。下一个M循环读取位移字节d。但是,M循环仅使用3个T循环,而不是4个循环,因此它不能是M1循环;相反,这是一个正常的内存读取周期。

以下是RLC(IX + d)指令的六个M周期的细分:

  1. M1循环读取0xDD前缀(4个T循环)
  2. M1循环读取0xCB前缀(4个T循环)
  3. 存储器读取周期以读取位移字节(3个T周期)
  4. M1循环以获取0x06操作码并将IX加载到ALU中(5个T循环)
  5. 存储器读取周期来计算和读取地址IX + d(4个T周期)
  6. 存储器写周期以计算RLC并将结果写入地址IX + d(3个T周期)
  7. (RLC计算与M循环5和6重叠。)

    这些类型指令的独特之处在于它们是唯一具有非连续M1周期的Z80指令(上面的M周期1,2和4)。它们也是最慢的!

答案 1 :(得分:5)

Sean Young's Z80 Undocumented Features有不同的故事。一次为无前缀,两次为单个前缀,两次为双前缀(仅限DDCB),一次为无操作前缀。

块指令当然会在每次运行时影响R(并且它们运行BC时间)。

答案 2 :(得分:1)

我现在看到一些评论,这些奇怪的DDCB和FDCB指令只增加R寄存器两次。

一直是我的假设(以及我实现Z80仿真器的方式)R寄存器是在每个 M1周期结束时实现的。

总结一下,这些奇怪的DDCB和FDCB指令长度为四个字节:

DD CB disp opcode

FD CB disp opcode

很明显,使用M1周期读取两个前缀操作码,导致R寄存器在每个周期结束时递增。

同样清楚的是,CB前缀之后的位移字节由正常的读周期读取,因此R寄存器在该周期结束时不会递增。

留下最终的操作码。如果它被一个M1周期读取,那么R寄存器在周期结束时递增,导致总共3个增量,或Z80特殊情况,这个M1周期并不增加R寄存器。

还有另一种可能性。如果最终的操作码是由正常的读周期读取的,比如它之前的位移字节,而不是M1周期?当然,这也会导致R寄存器仅为这些指令递增两次,并且不需要Z80在每个M1周期结束时不递增R寄存器。

就Z80的内部状态而言,这也可能更有意义。一旦它切换到正常读取周期以读取指令的附加字节(在这种情况下是CB前缀之后的位移字节),它就不会切换回M1周期,直到它开始下一条指令。

任何人都可以在真正的Z80硬件上进行测试,以确认R寄存器的值是否遵循其中一条DDCB或FDCB指令?

答案 3 :(得分:-2)

我可以在网上找到的所有参考文献都说R每个指令递增一次,无论其长度如何。

相关问题