Simulated 16-bit Addition

z80 » Intermediate

Have you ever wanted to add an 8-bit register to a 16-bit register? You've probably just ran the following code to add a to hl.

  1. ld b,0 ;2 bytes 7 cycles
  2. ld c,a ;1 byte 4 cycles
  3. add hl,bc ;1 byte 11 cycles ;4 bytes 22 cycles (totals)

I wrote the opcode information to the right of each of those instructions for clock cycles and size. At the bottom I totalled the information so we can compare it with a new way of adding 8-bit registers to 16-bit ones totalled later on.

The faster way to do this is the following code using the carry flag.

  1. add a,l ;1 byte 4 cycles
  2. ld l,a ;1 byte 4 cycles
  3. adc a,h ;1 byte 4 cycles
  4. sub l ;1 byte 4 cycles
  5. ld h,a ;1 byte 4 cycles ;5 bytes 20 cycles (totals)

Line Explanation
1 Add the Least Significant Byte (LSB) of a to the LSB of hl. If there was a overflow, the carry flag will be set or reset accordingly.
2 Store the result in the LSB of hl. This does not dissrupt the carry flag's status.
3 Add the result again into h, this will also add 1 to that if the carry was set, or 0 if it was reset. The result is still in a.
4 Subtract the original result (what's now in l) from the most recent result. This has the effect of just adding the carry to h. It undoes what line 3 did so that we either added 1 or 0 to h.
5 Put that final result of the Most Significant Byte (MSB) into h giving us the final product:
	hl = hl + a

Our final routine saves us 2 clock cycles at a cost of 1 byte extra. In programs where speed is of the escence, this routine is a must compared to the original method.


More from z80 » Intermediate
All the Flags // Debugging // Down-Left Bug // _GetKey Codes // Logical Operators // Memory, ROM, RAM, and Safe Areas // Miscellaneous Instructions // PC and SP // Random Numbers // TI's ROM Calls // Restart Commands // Simulated 16-bit Addition // The Stack // Tables and Arrays // Text Display // Variables