Game Boy Half-Carry Flag
  •  5 min read

The half-carry flag can be tricky to deal with at first, but with a little patience and practice you will understand the ins and outs of it and see how simple it really is.

What Is a Half-Carry Flag?

The Nintendo Gameboy is powered by a custom CPU built by Sharp that borrows design from both the 8080 and Z80. Among other things, it inherited from the Z80 the convention that the F register is for flags. One of these flags (H) is the half-carry flag. The half-carry flag is set when an arithmetic operation on two numbers causes a carry from bit #3 to bit #4 for 8-bit operations or a carry from bit #11 to bit #12 for 16-bit operations. In this post we will be examining 8-bit carries.

Wait, What Is Carrying Again?

Remember in grade school when you learned to add two numbers together? You probably learned to put your numbers into rows and if any column added together equaled 10 or more you carry the leftmost number over to the next column. Like this:

$$ \begin{array}{cc} \scriptsize 1 & \ \newline 1 & 3 \ \newline {+} & 8 \ \newline \hline 2 & 1 \end{array} $$

That 1 that was carried over is a carry. We do the exact same thing for the half-carry, but in binary!

Binary Arithmetic

Doing arithmetic, such as adding, in binary is very similar to doing it in base-10. First line up all of your digits:

$$ \begin{array}{cc} & 0 & 1 & 1 & 0 \ \newline {+} & 0 & 1 & 1 & 1 \ \newline \hline \end{array} $$

And then work your way from right-to-left adding columns together. Using these rules for carrying to the next column:

  1. 0 + 0 = 0
  2. 1 + 0 = 1
  3. 1 + 1 = Drop a 0 and carry a 1
  4. 1 + 1 + 1 = Drop a 1 and carry a 1

$$ \begin{array}{cc} & \scriptsize 1 & \scriptsize 1 & & \ \newline & 0 & 1 & 1 & 0 \ \newline {+} & 0 & 1 & 1 & 1 \ \newline \hline & 1 & 1 & 0 & 1 \end{array} $$

In this example we carried from bit #1 -> bit #2 and then from bit #2 -> bit #3 (we start counting from the right as bit #0).

Which Bit Are We Checking?

Remember that for the half-carry we are only looking for a carry from bit #3 to bit #4 - going from one nybble (4 bits) into the next. So if we are adding the numbers 10 + 12 in binary (1010 + 1100) would there be a half-carry?

$$ \begin{array}{cc} & & & & \scriptsize 1 & & \ \newline & 0 & 0 & 0 & 0 & 1 & 0 & 1 & 0 \ \newline {+} & 0 & 0 & 0 & 0 & 1 & 1 & 0 & 0 \ \newline \hline & 0 & 0 & 0 & 1 & 0 & 1 & 1 & 0 \ \end{array} $$

We carried a 1 from bit #3 to bit #4, so yes, there is a half-carry.

How about 5 + 4 (0101 + 0100)?

$$ \begin{array}{cc} & & & & & \scriptsize 1 & \ \newline & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 1 \ \newline {+} & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 \ \newline \hline & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 1 \ \end{array} $$

In this case nothing was carried from bit #3 to bit #4, so no, there is no half-carry.

Checking For A Carry

Here is a great answer on Stack Overflow about how to tell if a half-carry occured. Don't worry, we'll deconstruct the algorithm in the answer to see how it works. Blindley copying and pasting is bad for the (dev) environment.

Here is the algorithm. Where 'a' and 'b' are the two bytes that we are adding together:

(((a & 0xf) + (b & 0xf)) & 0x10) == 0x10

There are three basic parts to this. We'll look at the inner most expressions first.

The variables a and b are both being bitwise ANDed wth 0xf and then added together.

(a & 0xf) + (b & 0xf)

A bitwise AND simply means that a when the bits are lined up the result is 1 where both rows are already set to 1. For example 62 & 0xf looks like this in binary form:

$$ \begin{array}{cc} & 0 & 0 & 1 & 1 & 1 & 1 & 1 & 0 \ \newline \And & 0 & 0 & 0 & 0 & 1 & 1 & 1 & 1 \ \newline \hline & 0 & 0 & 0 & 0 & 1 & 1 & 1 & 0 \ \end{array} $$

If we were to set a=62 and b=34 this inner expression would result in:

$$ \begin{array}{cc} & & & & \scriptsize 1 & \scriptsize 1 & \scriptsize 1 \ \newline & 0 & 0 & 0 & 0 & 1 & 1 & 1 & 0 & \scriptsize (62 \And \text{0xf}) \ \newline {+} & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & \scriptsize (34 \And \text{0xf}) \ \newline \hline & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 \ \end{array} $$

After adding that inner expression together bit #4 is no longer 0, because there was a carry from bit #3. Now how do we check this bit for a carry? That's where the last part comes into play. We take the sum from that inner expression and bitwise AND it with 0x10. That gives us:

$$ \begin{array}{cc} & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 \ \newline \And & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 \ \newline \hline & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 \ \end{array} $$

Then we can simply check if that sum & 0x10 == 0x10:

if sum & 0x10 == 0x10 {
// a half-carry occured.
} else {
// a half-carry did not occur.
}

You can run this example in your browser see the entire algorithm in action. Just click the "run" button at the top of the page to run the code sample. Try playing around with different numbers in lines 12 and 13 to see if they result in a carry when added together.