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

1.1       root        1: head     1.2;
                      2: access   ;
                      3: symbols  ;
                      4: locks    bin:1.2;
                      5: comment  @/ @;
                      6: 
                      7: 
                      8: 1.2
                      9: date     92.05.07.23.26.58;  author bin;  state Exp;
                     10: branches ;
                     11: next   1.1;
                     12: 
                     13: 1.1
                     14: date     92.05.07.23.25.36;  author bin;  state Exp;
                     15: branches ;
                     16: next   ;
                     17: 
                     18: 
                     19: desc
                     20: @steve 5/7/92
                     21: Initial MWC RCS revision.
                     22: ,.
                     23: @
                     24: 
                     25: 
                     26: 1.2
                     27: log
                     28: @steve 5/7/92
                     29: Deleted code to adjust result for negative arguments.
                     30: According to ANSI, -1.15 should return -1 + -.15, not -2 + .85.
                     31: @
                     32: text
                     33: @////////
                     34: /
                     35: / Intel 8086 C runtime.
                     36: / Split a double into the fraction and whole integer parts.
                     37: / SMALL model.
                     38: /
                     39: ////////
                     40: 
                     41:        .globl  modf_
                     42:        .globl  _fpac_
                     43:        .globl  dpush
                     44:        .globl  dladd
                     45:        .globl  dlsub
                     46:        .globl  dzero
                     47: 
                     48: ////////
                     49: /
                     50: / double
                     51: / modf(d, *ip);
                     52: / double d;
                     53: / double *ip;
                     54: / The "integer part" of the double "d" is stored
                     55: / indirectly through "ip". The remaining fractional part
                     56: / is returned. The return value is always positive.
                     57: /
                     58: ////////
                     59: 
                     60: d      =       8                       / Double argument
                     61: ip     =       16                      / Whole part pointer.
                     62: 
                     63: EXP    =       -2                      / Exponant.
                     64: SIGN   =       -4                      / Sign flag.
                     65: CLAIM  =       4                       / # of bytes of autos.
                     66: 
                     67: modf_: push    si                      / Standard
                     68:        push    di                      / C
                     69:        push    bp                      / calling
                     70:        mov     bp,sp                   / sequence.
                     71: 
                     72:        sub     sp,$CLAIM               / Claim auto space
                     73:        cld                             / Incrementing.
                     74: 
                     75:        lea     si,d(bp)                / Copy the "d" argument
                     76:        mov     di,ip(bp)               / into the
                     77:        movsw                           / integer return
                     78:        movsw                           / value
                     79:        movsw                           / output
                     80:        movsw                           / area
                     81: 
                     82:        mov     ax,d+6(bp)              / Get the first word.
                     83:        shl     ax,$1                   / Slide off the sign and
                     84:        rclb    SIGN(bp),$1             / save it.
                     85:        movb    al,ah                   / Save the exponant
                     86:        subb    ah,ah                   / in the ax,
                     87:        sub     ax,$0x80                / unbias it, and
                     88:        mov     EXP(bp),ax              / save it away.
                     89: 
                     90: / If the exponant is <= 0, then there is no
                     91: / integer part. Set the integer part to 0.0, and get set
                     92: / to return the argument as the fractional part.
                     93: 
                     94:        jg      0f                      / Jump if exponant > 0
                     95: 
                     96:        sub     ax,ax                   / Set 
                     97:        mov     di,ip(bp)               / the
                     98:        stosw                           / integer
                     99:        stosw                           / part
                    100:        stosw                           / to
                    101:        stosw                           / zero.
                    102: 
                    103:        lea     si,d(bp)                / Copy
                    104:        mov     di,$_fpac_              / the
                    105:        movsw                           / argument
                    106:        movsw                           / to
                    107:        movsw                           / the
                    108:        movsw                           / return area.
                    109:        jmp     1f                      / Done.
                    110: 
                    111: / If the exponant is > 56 then there are no fractional bits
                    112: / at all. The integer part is correct. Zero out the floating point
                    113: / return value.
                    114: 
                    115: 0:     cmp     ax,$56                  / Any fractional bits ?
                    116:        jl      0f                      / Yes.
                    117: 
                    118:        call    dzero                   / Zero the _fpac_.
                    119:        jmp     1f                      / Done.
                    120: 
                    121: / Clear 56-exp bits, starting at the right hand end of the
                    122: / integer value. Clear as many full bytes as you can, then build a
                    123: / mask and get the rest.
                    124: 
                    125: 0:     neg     ax                      / Figure out
                    126:        add     ax,$56                  / 56-exp.
                    127:        mov     di,ip(bp)               / Point di at low end.
                    128: 
                    129: 0:     sub     ax,$8                   / Is there a full byte ?
                    130:        jl      0f                      / Nope.
                    131:        movb    (di),$0                 / Clear 8 bits.
                    132:        inc     di                      / Move to next byte and
                    133:        jmp     0b                      / try again.
                    134: 
                    135: 0:     add     ax,$8                   / Figure out
                    136:        movb    cl,al                   / the
                    137:        movb    al,$0xFF                / correct mask to
                    138:        shlb    al,cl                   / clear the rest, and
                    139:        andb    (di),al                 / do it.
                    140: 
                    141: / Scoop up the number. Shift the binary point to just above
                    142: / the hidden bit location, then shift it additional times to get
                    143: / it normalized.
                    144: 
                    145:        mov     cx,EXP(bp)              / Get exponant.
                    146: 
                    147:        movb    dl,d+6(bp)              / Scoop
                    148:        mov     ax,d+4(bp)              / up
                    149:        mov     si,d+2(bp)              / the
                    150:        mov     di,d+0(bp)              / number.
                    151: 
                    152: 0:     shl     di,$1                   / Slide
                    153:        rcl     si,$1                   / up
                    154:        rcl     ax,$1                   / one
                    155:        rclb    dl,$1                   / bit, and
                    156:        loop    0b                      / loop until done.
                    157: 
                    158:        mov     cx,di                   / Check
                    159:        or      cx,si                   / if
                    160:        or      cx,ax                   / we
                    161:        orb     cl,dl                   / have a zero.
                    162:        jnz     0f                      / Nope.
                    163:        subb    dh,dh                   / Make all zeros and
                    164:        jmp     2f                      / return.
                    165: 
                    166: 0:     mov     cx,$0x8000              / ch=exp, cl=0
                    167: 
                    168: 0:     orb     dl,dl                   / Normalized ?
                    169:        js      0f                      / Yes.
                    170:        shl     di,$1                   / Shift
                    171:        rcl     si,$1                   / up
                    172:        rcl     ax,$1                   / one
                    173:        rclb    dl,$1                   / place.
                    174:        decb    ch                      / Adjust exponant and
                    175:        jmp     0b                      / loop.
                    176: 
                    177: 0:     and     dx,$0x7F                / dh=0, dl=no hidden bit
                    178:        shrb    SIGN(bp),$1             / carry=sign
                    179:        rcr     cx,$1                   / Pull into correct place and
                    180:        or      dx,cx                   / pack up double.
                    181: 
                    182: 2:     mov     _fpac_+6,dx             / Save
                    183:        mov     _fpac_+4,ax             / into the
                    184:        mov     _fpac_+2,si             / return
                    185:        mov     _fpac_+0,di             / location.
                    186: 
                    187: 1:     mov     sp,bp                   / Standard
                    188:        pop     bp                      / C
                    189:        pop     di                      / function
                    190:        pop     si                      / return
                    191:        ret                             / code.
                    192: 
                    193:        .shrd
                    194: one:   .byte   0x00, 0x00, 0x00, 0x00
                    195:        .byte   0x00, 0x00, 0x80, 0x40
                    196: @
                    197: 
                    198: 
                    199: 1.1
                    200: log
                    201: @Initial revision
                    202: @
                    203: text
                    204: @d77 1
                    205: a77 1
                    206:        jmp     1f                      / Go check the sign.
                    207: d87 1
                    208: a87 1
                    209:        jmp     1f                      / Go check the sign.
                    210: d155 1
                    211: a155 29
                    212: / Final sign checks. The fractional part is always a
                    213: / positive number. If it is less than zero, add one to it and
                    214: / subtract one from the integer part.
                    215: 
                    216: 1:     test    _fpac_+6,$0x7F80        / Is the return value zero ?
                    217:        jz      0f                      / Yup.
                    218:        testb   _fpac_+7,$0x80          / Is the return value negative ?
                    219:        jz      0f                      / Nope.
                    220: 
                    221:        mov     si,$one                 / Get address of "1.0"
                    222:        push    si                      / Push for "dladd"
                    223:        call    dpush                   / Push fraction for "dlsub"
                    224:        push    si                      / Push for "dlsub"
                    225:        mov     di,ip(bp)               / di=pointer to the integer part.
                    226:        push    6(di)                   / Push
                    227:        push    4(di)                   / onto the
                    228:        push    2(di)                   / stack for
                    229:        push    0(di)                   / "dlsub"
                    230:        call    dlsub                   / Subtract 1 from integer part.
                    231:        add     sp,$10                  / Pop args.
                    232:        mov     si,$_fpac_              / Copy
                    233:        movsw                           / result
                    234:        movsw                           / to
                    235:        movsw                           / the integer
                    236:        movsw                           / part
                    237:        call    dladd                   / Add one to the fraction
                    238:        add     sp,$10                  / and clear args.
                    239: 
                    240: 0:     mov     sp,bp                   / Standard
                    241: @

unix.superglobalmegacorp.com

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