GBZ80:什么构成"半携带"?

Ren*_*ena 35 z80 emulation gameboy

Game Boy Z80 CPU有一个半进位标志,我似乎无法找到有关何时设置/清除它的更多信息.

我的理解至今是任何8位加,减,移位或旋转操作(或者其他人?),将其设置为结果(?)的第4位,而DAA指令集/莫名其妙地使用这个.我不确定的是16位指令如何影响它以及它是否受到某些寄存器的影响.

Tom*_*mmy 30

它是从第3位到第4位的进位,就像正常进位标志记录从第7位进位一样.因此,例如,在add中获取半进位:

((a&0xf) + (value&0xf))&0x10
Run Code Online (Sandbox Code Playgroud)

如果应该设置一半进位,则给出0x10,否则为0.从其他相关操作中得到一半自然跟随 - 问题是是否存在从低半字节到高位的进位.

为了正确看待,z80有一个4位ALU,通过两个4位操作执行8位操作.所以它很自然地得到一半,作为中间结果.

DAA对该标志感兴趣,因为如果设置了半进位,则低半字节中加入两个加起来超过16的数字; 这将正确地产生进入高位半字节但会使低半字节6低于应有的值,因为当它应该产生进位时,在10之间还有6个值,而当它确实产生进位时,则为16.

  • 高字节; 这是最近的一半.你可能已经找到了它,但我发现http://datasheets.chipdb.org/Zilog/Z80/z80-documented-0.90.pdf对DAA有一个很好的描述,并解释了半携带来自何处像CCF这样的边缘情况(如果内存服务的话,它被设置为旧的携带). (3认同)
  • 好的,但是16位操作呢?是从高字节还是低字节设置半进位? (2认同)
  • 要添加的一件事使我很清楚:添加例如0x37和0x44不会导致半进位,因为您仅查看每个字节的低4位,将它们加在一起,然后看是否溢出即可。0x0F + 0x01可以,0x37 + 0x44可以。 (2认同)

Emi*_*dın 10

对于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
Run Code Online (Sandbox Code Playgroud)