Annotation of coherent/b/lib/libc/gen/i8086/modf.s, revision 1.1.1.1

1.1       root        1: ////////
                      2: /
                      3: / Intel 8086 C runtime.
                      4: / Split a double into the fraction and whole integer parts.
                      5: / SMALL model.
                      6: /
                      7: ////////
                      8: 
                      9:        .globl  modf_
                     10:        .globl  _fpac_
                     11:        .globl  dpush
                     12:        .globl  dladd
                     13:        .globl  dlsub
                     14:        .globl  dzero
                     15: 
                     16: ////////
                     17: /
                     18: / double
                     19: / modf(d, *ip);
                     20: / double d;
                     21: / double *ip;
                     22: / The "integer part" of the double "d" is stored
                     23: / indirectly through "ip". The remaining fractional part
                     24: / is returned. The return value is always positive.
                     25: /
                     26: ////////
                     27: 
                     28: d      =       8                       / Double argument
                     29: ip     =       16                      / Whole part pointer.
                     30: 
                     31: EXP    =       -2                      / Exponant.
                     32: SIGN   =       -4                      / Sign flag.
                     33: CLAIM  =       4                       / # of bytes of autos.
                     34: 
                     35: modf_: push    si                      / Standard
                     36:        push    di                      / C
                     37:        push    bp                      / calling
                     38:        mov     bp,sp                   / sequence.
                     39: 
                     40:        sub     sp,$CLAIM               / Claim auto space
                     41:        cld                             / Incrementing.
                     42: 
                     43:        lea     si,d(bp)                / Copy the "d" argument
                     44:        mov     di,ip(bp)               / into the
                     45:        movsw                           / integer return
                     46:        movsw                           / value
                     47:        movsw                           / output
                     48:        movsw                           / area
                     49: 
                     50:        mov     ax,d+6(bp)              / Get the first word.
                     51:        shl     ax,$1                   / Slide off the sign and
                     52:        rclb    SIGN(bp),$1             / save it.
                     53:        movb    al,ah                   / Save the exponant
                     54:        subb    ah,ah                   / in the ax,
                     55:        sub     ax,$0x80                / unbias it, and
                     56:        mov     EXP(bp),ax              / save it away.
                     57: 
                     58: / If the exponant is <= 0, then there is no
                     59: / integer part. Set the integer part to 0.0, and get set
                     60: / to return the argument as the fractional part.
                     61: 
                     62:        jg      0f                      / Jump if exponant > 0
                     63: 
                     64:        sub     ax,ax                   / Set 
                     65:        mov     di,ip(bp)               / the
                     66:        stosw                           / integer
                     67:        stosw                           / part
                     68:        stosw                           / to
                     69:        stosw                           / zero.
                     70: 
                     71:        lea     si,d(bp)                / Copy
                     72:        mov     di,$_fpac_              / the
                     73:        movsw                           / argument
                     74:        movsw                           / to
                     75:        movsw                           / the
                     76:        movsw                           / return area.
                     77:        jmp     1f                      / Done.
                     78: 
                     79: / If the exponant is > 56 then there are no fractional bits
                     80: / at all. The integer part is correct. Zero out the floating point
                     81: / return value.
                     82: 
                     83: 0:     cmp     ax,$56                  / Any fractional bits ?
                     84:        jl      0f                      / Yes.
                     85: 
                     86:        call    dzero                   / Zero the _fpac_.
                     87:        jmp     1f                      / Done.
                     88: 
                     89: / Clear 56-exp bits, starting at the right hand end of the
                     90: / integer value. Clear as many full bytes as you can, then build a
                     91: / mask and get the rest.
                     92: 
                     93: 0:     neg     ax                      / Figure out
                     94:        add     ax,$56                  / 56-exp.
                     95:        mov     di,ip(bp)               / Point di at low end.
                     96: 
                     97: 0:     sub     ax,$8                   / Is there a full byte ?
                     98:        jl      0f                      / Nope.
                     99:        movb    (di),$0                 / Clear 8 bits.
                    100:        inc     di                      / Move to next byte and
                    101:        jmp     0b                      / try again.
                    102: 
                    103: 0:     add     ax,$8                   / Figure out
                    104:        movb    cl,al                   / the
                    105:        movb    al,$0xFF                / correct mask to
                    106:        shlb    al,cl                   / clear the rest, and
                    107:        andb    (di),al                 / do it.
                    108: 
                    109: / Scoop up the number. Shift the binary point to just above
                    110: / the hidden bit location, then shift it additional times to get
                    111: / it normalized.
                    112: 
                    113:        mov     cx,EXP(bp)              / Get exponant.
                    114: 
                    115:        movb    dl,d+6(bp)              / Scoop
                    116:        mov     ax,d+4(bp)              / up
                    117:        mov     si,d+2(bp)              / the
                    118:        mov     di,d+0(bp)              / number.
                    119: 
                    120: 0:     shl     di,$1                   / Slide
                    121:        rcl     si,$1                   / up
                    122:        rcl     ax,$1                   / one
                    123:        rclb    dl,$1                   / bit, and
                    124:        loop    0b                      / loop until done.
                    125: 
                    126:        mov     cx,di                   / Check
                    127:        or      cx,si                   / if
                    128:        or      cx,ax                   / we
                    129:        orb     cl,dl                   / have a zero.
                    130:        jnz     0f                      / Nope.
                    131:        subb    dh,dh                   / Make all zeros and
                    132:        jmp     2f                      / return.
                    133: 
                    134: 0:     mov     cx,$0x8000              / ch=exp, cl=0
                    135: 
                    136: 0:     orb     dl,dl                   / Normalized ?
                    137:        js      0f                      / Yes.
                    138:        shl     di,$1                   / Shift
                    139:        rcl     si,$1                   / up
                    140:        rcl     ax,$1                   / one
                    141:        rclb    dl,$1                   / place.
                    142:        decb    ch                      / Adjust exponant and
                    143:        jmp     0b                      / loop.
                    144: 
                    145: 0:     and     dx,$0x7F                / dh=0, dl=no hidden bit
                    146:        shrb    SIGN(bp),$1             / carry=sign
                    147:        rcr     cx,$1                   / Pull into correct place and
                    148:        or      dx,cx                   / pack up double.
                    149: 
                    150: 2:     mov     _fpac_+6,dx             / Save
                    151:        mov     _fpac_+4,ax             / into the
                    152:        mov     _fpac_+2,si             / return
                    153:        mov     _fpac_+0,di             / location.
                    154: 
                    155: 1:     mov     sp,bp                   / Standard
                    156:        pop     bp                      / C
                    157:        pop     di                      / function
                    158:        pop     si                      / return
                    159:        ret                             / code.
                    160: 
                    161:        .shrd
                    162: one:   .byte   0x00, 0x00, 0x00, 0x00
                    163:        .byte   0x00, 0x00, 0x80, 0x40

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.