加减如何影响GameBoy中的寄存器状态?



我目前正在开发一个GameBoy模拟器。在编码时,我开始质疑添加到寄存器如何影响它。

CPU 上有 8 个 8 位寄存器和 4 个 16 位寄存器。8位寄存器可以组合成16位寄存器。以下是我在代码中表示它们的方式。

struct Registers{
//8 bit registers
uint8_t a;
uint8_t b;
uint8_t c;
uint8_t d;
uint8_t e;
uint8_t f;
uint8_t h;
uint8_t l;
//16 bit registers
uint16_t af;
uint16_t bc;
uint16_t de;
uint16_t hl;
};

问题:

  1. 如果较低的寄存器的值为 0b11111111,我向其加 1。该位是延续到较高的寄存器,还是环绕到较低的8位寄存器的开头。

  2. 如果低寄存器的值为 0b00000000,并且 i 从中减去 1,它是保持零,还是该位换行到寄存器的顶部。

  3. 如果高寄存器的值为 0b00000000,并且 I 从中低于 1,它是否会影响较低的寄存器。

首先,我认为您组织寄存器的方式并不好,因为您有重复的信息(存储 a、f 和 af(。一种选择是使用工会;联合确保两个变量共享相同的内存位置。因此,您可以执行以下操作:

struct Registers{
union{
struct{
uint_8t f;
uint_8t a;
};
uint_16t af;
};
// And so on for the rest...
};

通过这种方式,您可以单独操作每个 8 位寄存器(registers.a(或同时操作两者(registers.af(。请注意,如果您在大端机中开发,则应交换 f 和 a 以确保正确的字节序。

如果您的编译器不支持匿名结构和联合,我认为更好的选择是创建一个函数来操作两个 8 位寄存器并将它们移位以形成 16 位寄存器。这样,您不必在每次修改它们时都访问 a 和 af。

现在谈谈你的实际问题。我的信息既基于此表(其中包含我被告知的一些错误,因此最好查看其他来源以确认它们(和本手册。

问题1: 不,它不会携带到更高的寄存器,它会溢出。

问题2: 同样的事情,它包装到0xFF。

问题3: 假设您使用的是 8 位 ALU 操作,那么不,它再次不会影响它。

请注意,如果您使用的是 16 位 ALU 操作,则它们会影响其他寄存器。例如:

假设 SP = 0x00FF;

ADD SP, 0x1 #Now SP does contain 0x0100 because you used 16 bit arithmetic.

然而:

假设 HL = 0x00FF;

ADD L, 1 # L Overflows to 0x00, however HL = 0x0000 because you used 8 bit arithmetic

最新更新