15

我目前正在为老式的 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;

AND A,L(注意位掩码)

(read HL register; &0xFF) save in cache C
R->C = R->HL &0xFF;

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

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

如果有人能让我更清楚这一点,我将不胜感激,因为我只想拥有更多的背景知识(所有这些东西在内部是​​如何工作的),所以我知道自己在做什么对我来说非常重要。

4

1 回答 1

11

正如评论所指出的那样,您找到的实现将 H 和 L 寄存器一起存储为 16 位实体 HL,然后通过右移将其分解为 H,并通过屏蔽将其分解为 L,这纯粹是特定于实现的。

最初的 z80 有一个 4 位 ALU(请参阅 Shima 在计算机历史博物馆面板的抄本中从第 9 页底部开始的评论),因此它实际上将 (i) 与 L 的低四位和累加器;然后 (ii) 与 L 的高四位和累加器。然而,它将其寄存器公开为离散的 8 位实体,因此内部实现完全隐藏。

HL 之所以称为寄存器对,是因为它是将两个寄存器组合在一起形成一个 16 位的数量。忽略影子和索引寄存器,原来的 z80 实际上有其中三个——HL、BC 和 DE。BC 和 DE 作为间接加载(例如操作码 0x1a — LD A,(BC))和 16 位算术(例如,0x09 ADD HL,BC)的替代对存在于 Gameboy 的 CPU 中,并且在 a z80。

SP 和 PC 通常被认为是不可分割的 16 位寄存器(当然,您可以通过将它们存储到内存并单独读取字节来分割它们)并且 AF 存在用于推送和弹出但 F 是一个特殊情况,以至于 AF作为 16 位整数通常不是特别有用。

那么简短的总结:您在理解操作码必须如何实现方面没有问题,而只是特定作者如何实现它们。

于 2012-03-13T01:19:33.323 回答