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.
$00
to$0F
to its ASCII representation involved some ADDs and DAAs. That partially answers your third point.