The 6502 has the decimal mode, which causes the ALU to always output valid BCD if it's given valid BCD. Of course, you can turn it off, as any sane person always does.

I was just looking at the kludges provided by some of the other CPU families. They seem to use a separate opcode to do the same job. It's called daa, for "decimal adjustment" or whatever. The Z80 sets a flags to say that the last operation was a subtraction, and this influences any following daa. But the 6800 has no such flag exposed in the status register. So what if an interrupt happens in between?

Anyhow, I am looking for some kind of description of how this actually works on the 6800, 6801, 6809. I intend to use this to implement an emulator, so it would be great to also know all the weird edge cases, such as

  • what if the preceding instruction is not an add or subtract operation, but something else that's valid, like "MUL" or "INC"?

  • what if the preceding instruction is something that doesn't make sense in decimal, like "XOR" or "AND"?

  • what if the two operands to an add or subtract operation were not actually valid BCD?

What the 6502 does, and I can't see any other sensible way, is to compare the lower half to 0x09, and then maybe both add 0x10 and subtract 0x06, and then do the same on the upper half. But apparently their method was covered by some patent or other, so the earlier ones like 6800 can't have done it this way.

  • 1
    The question is, in large parts redundant to previous ones like Why does the Z80 have a half-carry bit? and others. – Raffzahn Jan 10 at 17:37
  • @Raffzahn not really, I did not ask my own question again. This question is about the Motorola chips and does not ask about half carry. Anyway, the behaviour needs to be different, depending on addition or subtraction. But the 6800 at least does not record this data in a visible way – OmarL Jan 10 at 18:52
  • 2
    Well, it asks exactly the same issue, and yes, the 6800 records it the same way as Z80 (half-carry) which is of course visible by looking at the CCR. Z80 DAA is even called the same. Asking the same question again with slightly different wording means it's either a wilful duplicate, or you didn't read the very answer you marked as accepted, which could easy be seen as missing research, don't you think so? In either case, you might notice that I didn't vote for closure, but simply put up a slight reminder to think a bit before posting. Arguing here doesn't make it look better, or does it? – Raffzahn Jan 10 at 19:27
  • Not worth putting as an answer, but one trick to convert a hexadecimal nibble $00 to $0F to its ASCII representation involved some ADDs and DAAs. That partially answers your third point. – DrSheldon Jan 12 at 4:14

The DAA instruction on 6800 just works on the accumulator based on the data it contains and the flags register as set by the previous instructions.

So it does not know what instruction it was and whether it was valid or not in relation to BCD arithmetic, it simply does what is told.

An interrupt happening before DAA instruction will not be an issue, as the flags register gets pushed to stack before entering the interrupt and popped from stack when returning from interrupt.

The DAA instruction looks at the carry flag C and half-carry flag H and the value in register A, and determines if it must add 0x00, 0x06, 0x60, or 0x66, and then sets the output flags C,N,Z accordingly.

Unfortunately, the programming manuals for various 6800 processors and clones only describe how it works based on the assumption that the inputs are based on valid operation on BCD numbers, there is no table that describes the operation for any arbitrary input data.

  • The result based on "un-adjusted" input values can't be regarded as reliable (the data sheet seems to say).Adding $0F and $0F gives $1E, sets the H flag. DAA adds 6 to the lower nibble which results in $24. The lower nibble is a valid BCD digit, which isn't needed to get corrected further (according to some emulator code I found for a 6809 CPU). Maybe the hardware DAA on a real CPU does cope with this situation, recognizes an overflow (from the +6 caused by the set H flag) and adds +6 again to honor the overflow giving $30 which represents the correct decimal result of 15+15. I don't know. – Johann Klasek Jan 20 at 19:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.