[Simh] DAA Emulation

Al Williams al.williams at awce.com
Sat Dec 11 01:37:43 EST 2010


(note: I sent this to the mailing list, under the misunderstanding that this
was the SIMH maintainer's email from the bottom of the SIMH page; after
mailman bounced it, I joined the list and am resending it; while it starts
out talking about altair32, I do get around to SIMH before its done ;-) ).



I've been doing some work on Vince Briel's excellent AVR emulation of the
8080 and while rewriting DAA I came across what I think to be a harmless bug
but thought you might want to comment on it.

>From what I can glean DAA effects all flags including half carry. And I
_think_ that half carry occurs from the +6 (if it happens at all). So if you
don't adjust the LSD you get AC=0. If you add 6 then if adding the 6 gives
you a carry out of Bit 3 you get AC set. Note that the carry might ripple so
that's NOT to say Bit 4 is necessarily 1.

Here's part of Altair32's code:

static void daa ( OP_ARG_U )
{
// Decimal Adjust Accumulator
// DAA:: A=BCD format
// Flags: SZAPC
// *****

register /* FJS */ word tmp = ACCUM;

if ( (( tmp & 0x0f ) > 0x09 ) || ( FLAGS & AC_FLAG ))
 tmp += 0x06;

if (tmp > 0x0f)
FLAGS |= AC_FLAG; // if adjusted LSB > 0xf, set AC
 else
FLAGS &= ~AC_FLAG; // else clear SC


So since tmp is not masked off, any value >0xF gets AC set even if no carry
or add occurred! In other words, pretend the value of ACCUM is 90 (and thus
temp is 90) with AC=0. The first if does not fire. The second if does and AC
gets set. That's got to be wrong. Granted, who checks AC after DAA? But
still....


So why copy Bob? Well... I think SIMH has a similar but different problem.
Here's a snip from the DAA code:

/*opcode=0x27*/
static void i86op_daa(PC_ENV *m)
{
   uint16 dbyte;
   dbyte = m->R_AL;
   if (ACCESS_FLAG(m,F_AF)|| (dbyte&0xf) > 9)
     {
    dbyte += 6;
    if (dbyte&0x100)
      SET_FLAG(m, F_CF);
    SET_FLAG(m, F_AF);
     }
   else


Here we add 6 to dbyte and then AC is always set. If no +6 then AC is
cleared. This COULD be correct behavior, but I can't find any reference
material that says it is. In any event, SIMH and Altair32 are doing
something different here, so they both can't be right. Meanwhile I have my
own version of DAA in AVR assembler that I will spare you unless you ask.
The only real silicon I have even close to operational at the moment is a
Z80 and not only is it not operational, the DAA is one place where it is a
lot different so I don't trust the result there.

Oh. One other note about Altair32. In the debugger, the A and FLAGS display
is swapped in the debug console window. The Register display up top left is
ok though. I bet you've heard that one before.

If either of you can show documentation on the AC flag after DAA or point to
a real piece of silicon's behavior I'd like to know so I can fix the DAA
code in the Briel emulator to match. Otherwise, I thought you'd like to know
about this bug even though it is pretty innocuous as far as I can tell.


Al Williams
http://www.ddj.com/embedded (among others)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.trailing-edge.com/pipermail/simh/attachments/20101211/a7f4c160/attachment-0002.html>


More information about the Simh mailing list