Question

I'm writing a Z80 emulator and am stuck trying to understand what the decimal adjust instruction does for certain operands. What is the result (in registers A & F) of these opcodes on a real Z80?

LD   A,1h
ADD  A,99h
DAA

My code currently finished with 0xA0 in the A register and the half carry and overflow bits set. But should it return 0?

Was it helpful?

Solution

After:

LD A, 1h
ADD A, 99h

A should contain 9Ah. Carry, half carry and overflow should all be reset as there was no carry from bit 3 to bit 4 or heading out of bit 7, and in a signed interpretation you added a positive to a negative so overflow was impossible.

When you then perform DAA, the processor will spot that the low nibble is greater in value than 0x9. It will therefore decide that it is going to add 0x6 to create a suitable decimal carry from the low digit.

Given that it's going to add 0x9 to the low nibble it will check whether it would then expect the high nibble to create decimal carry. The test is whether high nibble is greater than 0x8. It is. So DAA will decide also to add 0x6 to the high nibble.

So in totality DAA will decide to add 0x66.

(0x9a + 0x66) MOD 0x100 = 0x00

So the result left in A will be 0x00.

DAA decided to add 0x6 to the top nibble. So carry will now be set.

DAA also decided to add 0x6 to the bottom nibble. So half carry will also be set.

Sign, zero, etc will be set according to the 0x00 result.

If I had to guess, it looks like your code is spotting that the low nibble is incorrect and planning to create half carry. But it's then failing to check whether the top nibble will hence be made incorrect (ie, whether it's 0x8 or greater), and failing to plan to create a top-nibble carry too.

OTHER TIPS

Execute DAA only after ADD instruction that leaves a two BCD digit byte result in the A register.

The ADD operants should consist of two packed BCD digits. The DAA instruction adjusts A register to contain correct two-digit packed decimal result, overflow, carry and zero flags are also affected. Carry flag is set after DAA if result (after DAA execution) is bigger than 99.

x86 CPU also support DAA instruction which is very close to Z80 DAA instruction, so you can use it at emulation if you are working on x86 platform.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top