gpt4 book ai didi

emulation - GBZ80 - ADC 指令失败测试

转载 作者:行者123 更新时间:2023-12-01 00:34:42 25 4
gpt4 key购买 nike

我一直在运行Blarggs CPU tests通过我的 Gameboy 模拟器,op r,r 测试表明我的 ADC 指令工作不正常,但 ADD 是。我的理解是两者之间的唯一区别是在添加之前将现有的进位标志添加到第二个操作数。因此,我的 ADC 代码如下:

void Emu::add8To8Carry(BYTE &a, BYTE b) //4 cycles - 1 byte
{
if((Flags >> FLAG_CARRY) & 1)
b++;
FLAGCLEAR_N;
halfCarryAdd8_8(a, b); //generates H flag based on addition
carryAdd8_8(a, b); //generates C flag appropriately
a+=b;
if(a == 0)
FLAGSET_Z;
else
FLAGCLEAR_Z;
}

我在测试 ROM 中输入了以下内容:
06 FE 3E 01 88

当进位标志被设置时,A 的值为 0 (Flags = B0),而当未设置时,则为 FF (Flags = 00)。就我的理解而言,这就是它应该如何工作。但是,它仍然无法通过测试。

根据我的研究,我相信标志以与 ADD 相同的方式受到影响。从字面上看,我的代码与工作 ADD 指令的唯一变化是在前两行中添加了标志检查/电位增量,我的测试代码似乎证明了这一点。

我错过了什么吗?也许 ADD/ADC 之间的标志状态有特殊性?作为旁注,SUB 指令也会通过,但 SBC 以同样的方式失败。

谢谢

最佳答案

问题是b是一个 8 位值。如 b是 0xff 并设置进位然后将 1 添加到 b如果添加 a 将其设置为 0 并且不会产生进位>= 1. 如果较低的 nybble 是 0xf,则半进位标志会出现类似的问题。

如果您调用 halfCarryAdd8_8(a, b + 1);,这可能会得到解决和 carryAdd8_8(a, b + 1);当进位设置时。但是,我怀疑这些例程也采用字节操作数,因此您可能必须在内部对它们进行更改。也许通过添加进位作为单独的参数,以便您可以执行 tmp = a + b + carry;没有 b 溢出.但我只能推测没有这些功能的来源。

在有点相关的说明中,有一种相当简单的方法来检查所有位的结转:

int sum = a + b;
int no_carry_sum = a ^ b;
int carry_into = sum ^ no_carry_sum;
int half_carry = carry_into & 0x10;
int carry = carry_info & 0x100;

这是如何运作的?如果没有进位进入该位,请考虑按位“异或”给出每个位的预期结果:0 ^ 0 == 0、1 ^ 0 == 0 ^ 1 == 1 和 1 ^ 1 == 0。通过 xoring sumno_carry_sum我们得到总和与逐位加法不同的位。 sum仅在特定位位置有进位时才不同。因此,可以几乎没有开销地获得半进位和进位位。

关于emulation - GBZ80 - ADC 指令失败测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42091214/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com