home *** CD-ROM | disk | FTP | other *** search
- ;=============================================================================
- ; 8087 Number Conversion Routines
- ;
- ; These are routines to convert from floating point to integer numbers. All
- ; registers are preserved except those used to return parameters. All
- ; parameters are passed through registers. It is assumed that DS = ES = CS.
-
- ;================================================
- ; Convert a floating point real number to a
- ; decimal integer and a base ten exponent.
- ; Expects the number to be converted in ST and
- ; the number of significant bits (i.e. bits to
- ; place in the significand) in AX. The
- ; significand integer value is returned in ST
- ; and the signed exponent is returned in AX.
-
- Flt2dec Proc Near
- Push Bp
- Sub Sp, 8
- Mov Bp, Sp
-
- Fstcw Word [Bp] ;save control word
- Mov Word [Bp+2], 03bfh ;new control word, round to nearest
- Fldcw Word [Bp+2] ;load control word
- Mov Word [Bp+4], Ax
-
- ;--- convert number
-
- Fld St(0)
- Fxtract ;extract exponent
- Fstp St(0) ;pop top (significand)
- Fisubr Word [Bp+4] ;subtract bits for significand
- Fldl2t ;load log2(10)
- Fdiv ;divide, get 10**X
- Frndint ;round to nearest
- Fist Word [Bp+6] ;save exponent
- Call Exp10 ;get exponent factor
- Fmul ;adjust real number for exponent
-
- ;--- finished
-
- Fldcw Word [Bp] ;restore control word
- Add Sp, 6
- Pop Ax
- Neg Ax
- Pop Bp
- Ret
- Endp ;Flt2dec
-
- ;================================================
- ; Calculate 10 to the power of ST. Return result
- ; in ST. Uses 10**N = 2**(N*Log2(10)).
-
- Exp10 Proc Near
- Fldl2t ;load Log2(10)
- Fmul ;multiply
- Call Exp2 ;raise 2 to ST power.
- Ret
- Endp ;Exp10
-
- ;================================================
- ; Calculate 2 to the power of ST. Return result
- ; in ST(0).
-
- Exp2 Proc Near
- Push Bp
- Sub Sp, 6 ;room for local data
- Mov Bp, Sp ;start of local data
-
- Fstcw Word [Bp] ;save control word
- Mov Word [Bp+2], 03bfh ;new control word, round to nearest
- Fldcw Word [Bp+2] ;load control word
-
- ;--- for 2**X, where X = W + F or X = W - F, where W is a whole number and
- ;--- F is between 0 and .5 (inclusive), ST gets F and ST(1) gets W
-
- Fld St(0) ;duplicate number
- Frndint ;round to integer, ST => W
- Fxch ;exchange
- Fsub St, St(1) ;get difference, ST => F
-
- ;--- check sign of fractional portion (F)
-
- Ftst ;set flags
- Fstsw Word [Bp+4] ;save flags
- Fwait
- And Byte [Bp+5], 45h ;mask relevant bits
- Cmp Byte [Bp+5], 1 ;check negative bit
- Ja Exp2err ;jump if other bits set, error
- Je Exp2neg ;jump if negative
-
- ;--- fractional part is positive for
-
- F2xm1 ;ST => (2**F) - 1
- Fld1 ;load one
- Fadd ;ST => 2**F
- Fxch ;put whole portion (W) on top
- Fld1 ;load one
- Fscale ;ST => 2**W
- Fmulp St(2), St ;ST(2) => (2**F) * (2**W)
- Fstp St(0) ;pop stack
- Jmps Exp2don
-
- ;--- fractional part is negative
-
- Exp2neg
- Fabs ;take absolute value
- F2xm1 ;ST => (2**F) - 1
- Fld1 ;load one
- Fadd ;ST => 2**F
- Fxch ;put whole portion (W) on top
- Fld1 ;load one
- Fscale ;ST => 2**W
- Fdivrp St(2), St ;ST(2) => (2**W) / (2**F)
- Fstp St(0) ;pop stack
-
- ;--- finished
-
- Exp2don
- Fldcw Word [Bp] ;restore control word
- Add Sp, 6
- Pop Bp
- Ret
-
- ;--- zero or error
-
- Exp2err
- Fstp St(0)
- Fstp St(0) ;clear stack
- Fld1 ;return one
- Jmps Exp2don
- Endp ;Exp2
-