|
|
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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.