Question

The Game Boy Z80 CPU has a half-carry flag, and I can't seem to find much information about when to set/clear it.

What I understand so far is that any 8-bit add, subtract, shift, or rotate operation (and maybe others?) set it to bit 4 of the result(?), and the DAA instruction sets/uses this somehow. What I'm not sure is how 16-bit instructions affect it and whether it's affected or not by the use of certain registers.

Was it helpful?

Solution

It's the carry from bit 3 to bit 4, just like the normal carry flag records carry from bit 7. So, e.g. to get the half carry bit in an add:

((a&0xf) + (value&0xf))&0x10

Which gives 0x10 if half carry should be set, 0 otherwise. Getting half carry from the other relevant ops follows naturally - the questions is whether there was carry from the low nibble to the high.

To put things in perspective, the z80 has a 4bit ALU and performs 8bit ops by doing two 4bit ops. So it gets half carry very naturally, as an intermediate result.

DAA is interested in the flag because if half carry is set then two digits that add up to more than 16 were added in the low nibble; that will have correctly produced carry into the upper nibble but will have left the low nibble 6 lower than it should be, since there were six more values between 10, when it should have generated carry, and 16, when it did.

OTHER TIPS

For 16-bit operations, the carry from bit 3 to bit 4 in the register's high byte sets the flag. In other words, bit 11 to bit 12.

(Note the above bits are labeled 0-15, from least to most significant)

See here: 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

Since the half-carry flag is one of the most common stumbling blocks for Game Boy emulator makers, I'll take the liberty to post a link to a recent question of mine regarding the subject as an answer:

Game Boy: Half-carry flag and 16-bit instructions (especially opcode 0xE8)


A summary of the above thread (answer by @gekkio):

It depends on the instruction, but the flags are always updated based on the same bit positions if you think in terms of 8-bit values...it just varies whether we're talking about the high or low byte of the 16-bit value. Bit 11 is just bit 3 of the high byte.

  • ADD SP, e: H from bit 3, C from bit 7 (flags from low byte op)
  • LD HL, SP+e: H from bit 3, C from bit 7 (flags from low byte op)
  • ADD HL, rr: H from bit 11, C from bit 15 (flags from high byte op)
  • INC rr: no flag updates (executed by the 16-bit inc/dec unit)
  • DEC rr: no flag updates (executed by the 16-bit inc/dec unit)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top