Zilog Z80 OP-Code实现

Sep*_*ura 14 c z80 emulation opcodes gameboy

我正在为优秀的旧GameBoy开发一个模拟器,我正面临一些问题,如何必须实现一些基本的操作代码.

现在我正在实施AND操作; 前几个(0xA0 - > 0xA3; 0xA6和0xA7)非常简单,但寄存器H,L的AND操作有点不同.

您可以在以下链接下载z80的文档: um0080.pdf(第172页)

这里有一些例子来说明我的意思(使用伪代码),基本上我做了什么:

AND A,H(注意位移)

(read HL register; >> 8) save in cache C
R->C = R->HL >> 8;

perform AND operation with cache
AND_H(R->C);
R->A &= R->C;
Run Code Online (Sandbox Code Playgroud)

和A,L(注意位屏蔽)

(read HL register; &0xFF) save in cache C
R->C = R->HL &0xFF;
Run Code Online (Sandbox Code Playgroud)

我知道所有的位操作,我知道他们做了什么,但似乎我无法弄清楚为什么需要这样做.我有一些理论(如果我错了,请纠正我:-)):

我已经理解的是,寄存器H和L基本上是寄存器HL,它是一个16位寄存器.由于CPU /总线只能处理8位操作,因此需要将其拆分; 或更多的逻辑建议:由于它只有一个寄存器,H和L的值在寄存器中被屏蔽,它们只需要彼此分开(高/低半字节?).

如果有人能够让我更清楚,我会非常感激,因为我只想拥有更多的背景知识(所有这些内容如何在内部运作),所以对我来说非常重要,因为我知道自己在做什么.

Tom*_*mmy 11

作为注释所指出的,该实现你已经发现存储的H和L的事实一起注册为16位实体HL,然后分解该成通过屏蔽关闭右移并进入L H纯粹是特定的实现.

原始的z80有一个4位的ALU(参见Shima的评论,从计算机历史博物馆面板的这个记录中的第9页开始)所以它实际上(i)和L的低四位和累加器; 然后(ii)和L的高四位和累加器.但是,它将其寄存器公开为离散的8位实体,因此内部实现完全隐藏.

HL被称为寄存器对,因为它是两个寄存器,它们组合在一起形成一个16位的数量.忽略阴影和索引寄存器,原始的z80实际上有三个 - HL,BC和DE.BC和DE在Gameboy的CPU中存在作为间接加载的替代对(例如操作码0x1a-LD A,(BC))和16位算术(例如,0x09 ADD HL,BC)并且在a上具有一些其他用途. Z80.

SP和PC通常被认为是不可分割的16位寄存器(当然,你可以通过将它们存储到存储器并单独读回字节来划分它们)并且AF存在用于推送和弹出但是F是如此特殊的情况下AF通常不是特别有用的16位整数.

简短的摘要,然后:你不必与理解操作码的问题是如何必须实现的,只是他们是如何被特定作者实现.

  • 事实证明,使用未记录的操作码,IX和IY寄存器可以单独进行字节寻址.(将HL转换为IX/IY的操作码前缀为0xBD和0xFD.)实质上,使用0xBD对任何其他基于寄存器的操作加前缀,将对(HL)的引用转换为形式(IX + n)之一(na单字节)整数),但它也将H的引用转换为IX的高半部分,并将L的引用转换为IX的低半部分.同样,对于IY和操作码前缀FD. (2认同)