The Z80 apparently had a 4-bit ALU, and computes 8-bit values in two stages. The half-carry bit preserves the carry from bits 3 to 4. Why did the designers of this chip choose to preserve that value in the flags register? Presumably, that intermediate result could have been stored (at less cost) in the Carry bit between the two halves of the addition/subtraction.
Why does the Z80 have a half-carry bit?
Because the ALU is only 4 bits wide. The Z80 needs to preserve the carry between bits 3 and 4.
Why did the designers of this chip choose to preserve that value in the flags register?
Good question. You can't access the
H bit directly except by saving the status register and then examining its contents, so there is no real purpose in having it visible. I suspect it was just easier or saved gates to put it in the same 8 bit register as the other user accessible flags. There are also two other undocumented flags in the status register that have less obvious uses.
Presumably, that intermediate result could have been stored (at less cost) in the Carry bit between the two halves of the addition/subtraction
Some Z80 arithmetic calculations should not affect the normal carry flag. For example address displacement calculations.
DAA instruction needs not just the final carry to be preserved but also the carry between "hex" digits so it knows how to adjust the digits to get the proper answer. For example 1 + 1 = 2 which is fine in hex and BCD but 9 + 9 =
0x12 in hex and the addition needs to be adjusted by
DAA to be
0x18. The only way to tell between the two cases is to know the value of the carry from the bottom hex digit to the top hex digit.
The intermediate carry flag, or "adjust flag", or half-carry flag is used to facilitate binary-coded decimal (BCD) arithmetic, where each decimal digit of a number is represented as a nibble (a group of 4 bits). The range of valid values for each nibble is 0 to 9 (0000 to 1001). If, after an arithmetic operation, the result contains a "non-decimal" nibble (1010 to 1111), it can be deduced from its bit pattern that a correction is necessary. However, it might also be necessary even if both nibbles of the result look "decimal".
Here's an example (from Wikipedia) why the flag is needed:
Adding the BCD values 3916 and 4816 produces 8116. This result does not have a non-decimal low nibble, but it does cause a carry out of the least significant digit (lower four bits) into the most significant digit (upper four bits). This is indicated by the CPU setting the half-carry flag. This value must also be corrected, by adding 0616 to 8116 to produce a corrected BCD result of 8716.
0011 1001 39 + 0100 1000 48 ----------- 1000 0001 81, intermediate result + 0110 06, adjustment ----------- 1000 0111 87, adjusted result
The Intel 4004 and 4040 were 4-bit CPUs. In some ways, the 8008 and its successor, the 8080 behaved as if it were two 4004s glued together, although the 8008 architecture was not just two 4004s glued together. For instance, the 8008 had an extensive carry prediction chunk attached to the ALU.
Adding either BCD or 4-bit values in the 4004 could result in overflow, indicated by the carry flag. In the 8008 and its descendants, this carry is preserved as the half-carry flag. This is why there is a half-carry flag in Intel's 8080, 8086, 8088, and subsequent x86 processors, as well as the Zilog Z80 and its descendants (e.g., the eZ80, released in 2007) and its clones. That the Z80 implements its ALU as a two-pass 4-bit ALU is a little weird, but is the way it was done. This choice of ALU design is not why there is a half-carry flag; this flag is present to preserve binary compatibility with the 8080.
The Motorola 6809 also had a half-carry flag. Weirdly, it is not affected by the DAA opcode (even if the DAA must carry between the nibbles) for fixing up BCD addition via single-byte adds. Here, the half-carry bit is set by the ADDA or ADCA and thus indicates binary inter-nibble carry, not BCD inter-digit carry. (This is a way that the English Wikipedia's article on the half-carry flag is not quite applicable to the MC68000.) Nevertheless, this led to the half-carry flag in the Motorola 68000 series and descendants as well.
Halfcarry is necessary for
DAA instruction and thus it makes sense to have it in
AF in a designated place (since it has a designated behavior).
DAA is needed for BCD arithmetic. But it's also useful to convert a nibble into ASCII:
ADD A,90H DAA ADC A,40H DAA
takes 6 bytes and 22 cycles. You cannot really do that with conditional jumps.
The halfcarry bit is not even the most obscure: there is a bit that is set when the last operation was a subtraction (or comparable) so that the
DAA instruction knows whether to adjust after an addition or a subtraction.
The 8088 (which is sort-of source code compatible to the 8080) has two different adjustment instructions for addition and subtraction, in contrast.
The reason there needs to be a visible "half carry" bit is a combination of two factors.
- BCD support
- Interrupt handling.
As other answers have pointed out the Z80 provided BCD support through an adjustment instruction run after the addition or subtraction operation (this constrasts with the 6502 that implemented it as a mode flag). This instruction needs to know whether or not there was a carry from the high nibble to the low nibble to correctly adjust the result.
But why does that flag need to be visible to the user as part of a status register rather than just an internal flag? the answer is interrupt handling.
Consider what happens if an interrupt happens between an arithmetic instruction and the corresponding DAA instruction. The interrupt must save the state of the half carry so it can be restored and correctly used by the DAA instruction after the interrupt returns.
This is why many flags that one would normally think of as "internal" are grouped together into a user-visible status register so they can be easilly saved and restored on interrupt.