Game Boy的Z80 CPU有一个半进位标志位,但我似乎找不到关于何时设置/清除它的信息。
目前我的理解是,任何8位加法、减法、移位或旋转操作(可能还有其他操作)都会将其设置为结果的第4位(?),而DAA指令以某种方式设置/使用它。 我不确定的是16位指令如何影响它以及是否受某些寄存器的影响。
Game Boy的Z80 CPU有一个半进位标志位,但我似乎找不到关于何时设置/清除它的信息。
目前我的理解是,任何8位加法、减法、移位或旋转操作(可能还有其他操作)都会将其设置为结果的第4位(?),而DAA指令以某种方式设置/使用它。 我不确定的是16位指令如何影响它以及是否受某些寄存器的影响。
这是从第3位到第4位的进位,就像正常进位标志记录了从第7位的进位一样。因此,例如在加法中获取半进位:
((a&0xf) + (value&0xf))&0x10
若需要设置半进位则返回0x10,否则返回0。从其他相关操作中获得半进位自然而然地遵循 - 问题是低四位是否向高四位进位。
为了更好地理解,z80具有4位ALU,并通过执行两个4位操作来执行8位操作。因此,它会很自然地获得半进位作为中间结果。
DAA对此标志感兴趣,因为如果设置了半进位,则在低四位中相加超过16的两个数字将正确地产生进位到高四位,但由于介于10和16之间时应该生成进位,所以低四位将比应有的值少6。
对于16位操作,寄存器高字节从第3位到第4位的进位将设置标志。换句话说,是第11位到第12位。
(请注意,上面的位从最低有效位标记为0到最高有效位标记为15)
参见这里:http://www.z80.info/z80code.htm
16 bit arithmetic
If you want to add numbers that are more than the 0-255 that can
be stored in the A register, then the HL, IX or IY registers can
be used. Thus LD HL,1000H:LD BC,2000H:ADD HL,BC will give
A CZPSNH BC DE HL IX IY A' CZPSNH' BC' DE' HL' SP
00 000000 2000 0000 3000 0000 0000 00 000000 0000 0000 0000 0000
The flags are set as follows.
C or carry flag 1 if answer >65535 else 0
Z or zero flag not changed
P flag not changed
S or sign flag not changed
N flag 0
H or half carry flag 1 if carry from bit 11 to bit 12 else 0
由于半进位标志是Game Boy模拟器制作者最常遇到的障碍之一,我想发表一个关于这个主题的最近问题链接作为答案:
Game Boy:半进位标志和16位指令(特别是操作码0xE8)
以上线程的摘要(由@gekkio回答):
这取决于指令,但如果您从8位值的角度考虑,标志始终基于相同的位位置更新...只是我们谈论16位值的高字节还是低字节有所不同。第11位只是高字节的第3位。
ADD SP,e
:H来自位3,C来自位7(来自低字节操作的标志)LD HL,SP + e
:H来自位3,C来自位7(来自低字节操作的标志)ADD HL,rr
:H来自位11,C来自位15(来自高字节操作的标志)INC rr
:没有标志更新(由16位inc / dec单元执行)DEC rr
:没有标志更新(由16位inc / dec单元执行)