<< Previous Message Main Index Next Message >>
<< Previous Message in Thread This Month Next Message in Thread >>
Date   : Sun, 15 Apr 1990 03:00:19 EDT
From   : dg%pallio.UUCP@XAIT.Xerox.COM (David Goodenough)
Subject: Z-80 DAA instruction & CP/M-on-unix

I tried mailing this, but someone burped on it. Anyway, this may
be of general interest .....

The DAA instruction promises to be a real horror. You'll need to note
three things from the last 8 or 16 bit add / subtract operation:
the standard carry (i.e. from bit 7), the half carry: this flags if
there was a carry out of bit 3, into bit 4: do something like:

       hc = ((op1 & 0x0f) + (op2 & 0x0f)) & 0x10

where op1 and op2 are the two operands in the add. Note also if it
was an addition or a subtraction. This is basically collecting the
following three Z80 flags: C, I, N (carry, half carry - aka intermediate
carry, and negative (i.e. subtraction). Note the N flag is distinct from
the S (sign) flag - the S simply echos bit 7 of the acc, whereas the N
notes whether the last 8 bit op was an addition or subtraction.

Now for the fun stuff:

       if (addition) /* i.e. N is clear: last op was an add)
        {
           if (half carry set || (acc & 0x0f) < 9)
               add 6 to acc
           if (main carry set || (acc & 0xf0) < 0x90)
               add 0x60 to acc
        }
       else            /* subtraction */
        {
           if (half carry set || (acc & 0x0f) < 9)
               subtract 6 from acc
           if (main carry set || (acc & 0xf0) < 0x90)
               subtract 0x60 from acc
        }

I think this is right, but I wouldn't want to swear to it.

I then dug out "The gospel according to Carr" (The Z80 user's manual,
by Joseph Carr, ISBN 0-8359-9516-X ) - It has the following table for
what happens in a DAA.

Used with         C         C          I       low       high      number
instruction     before    after      before    nibble    nibble    added
ADC\              0         0          0        0-9       0-9       00 
ADD >                  0         0          0        a-f       0-8       06
INC/              0         0          1        0-3       0-9       06
i.e. N flag clear  0        1          0        0-9       a-f       60
                  0         1          0        a-f       9-f       66
                  0         1          1        0-3       a-f       66
                  1         1          0        0-9       0-2       00
                  1         1          0        a-f       0-2       fa
                  1         1          1        0-3       0-3       a0
NEG\              0         0          0        0-9       0-9       00
SUB >                  0         0          1        6-f       0-8       fa
SBC/              1         1          0        0-9       7-f       a0
i.e. N flag set    1        1          1        6-f       6-f       9a

Now, the addition table looks OK, but I'm a little suspicious of the
subtraction table. By my reckoning there's only 2048 possible inputs
into this: 8 bits of acc data, C, I and N make another 3 for a total
of 11 bits - these can only take 2048 distinct inputs. It might be
instructive to write a little program to stuff all 2048 values into
a DAA instruction, and tabulate the results. That way you'd see what
a real Z80 does in all cases.
-- 
       dg@pallio.UUCP - David Goodenough               +---+
                                               IHS     | +-+-+
       ..... !harvard!xait!pallio!dg                   +-+-+ |
AKA:   dg%pallio.uucp@xait.xerox.com                     +---+

<< Previous Message Main Index Next Message >>
<< Previous Message in Thread This Month Next Message in Thread >>