Z80内存刷新寄存器

Phi*_*987 9 z80 cpu-registers fetch opcodes

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

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

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

此致,菲尔波特

use*_*475 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)指令的6个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周期)

(RLC计算与M循环5和6重叠)

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

保罗


har*_*old 5

Sean Young的Z80未记载的功能有一个不同的故事.一次为无前缀,两次为单个前缀,两次为双前缀(仅限DDCB),一次为无操作前缀.

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


Ale*_*nze -2

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

  • 实际上,每个 M1 状态它都会递增一次。以 CBh、EDh(或 IX / IY 前缀)为前缀的指令将 R 递增两次。您甚至可以有这样的指令 DD DD DD DD DD 21 00 00 (即 LD IX,0000h 带有许多 DDh 前缀,这是有效的),它将 R 增加 6。 (6认同)