home *** CD-ROM | disk | FTP | other *** search
-
- ; *******************************************************
- ; * *
- ; * Turbo Pascal Runtime Library Version 7.0 *
- ; * Real Polynomial Evaluation Routine *
- ; * *
- ; * Copyright (C) 1989-1993 Norbert Juffa *
- ; * *
- ; *******************************************************
-
- TITLE FPPOL
-
-
- CODE SEGMENT BYTE PUBLIC
-
- ASSUME CS:CODE
-
- ; Externals
-
- EXTRN RealAdd:NEAR,RealMul:NEAR,RealMulFNoChk:NEAR
- EXTRN RealSqrNoChk:NEAR
- EXTRN RealMulNoChk:NEAR,ShortMul:NEAR
-
- ; Publics
-
- PUBLIC RealPoly
-
- ;-------------------------------------------------------------------------------
- ; RealPoly is a routine that is used in the computation of all transcendental
- ; functions with the exception of the exponentiation routines. It is used to
- ; compute a polynomial approximation to the desired function. RealPoly computes
- ; either P(x^2)*x^2*x+x or P(x^2)*x^2 by way of Horner's method. A pointer to a
- ; table of coefficients for the polynomial is passed to the routine. The first
- ; coefficient is assumed to be of a special form, such that all but the sixteen
- ; most significant mantissa bits are zero. This makes the use of a special fast
- ; multiplication possible.
- ;
- ; INPUT: DX:BX:AX argument
- ; CS:DI pointer to a table of coefficients
- ; CX number of coefficients to be used
- ; SI SI <> 0 -> P(x^2) * x^2, SI = 0 -> P(x^2) * x^2 * x + x
- ;
- ; OUTPUT: DX:BX:AX approximated value of function
- ;
- ; DESTROYS: AX,BX,CX,DX,SI,DI,Flags
- ;-------------------------------------------------------------------------------
-
- RealPoly PROC NEAR
- CMP AL, 5Ch ; abs(argument) < 2^-36 ?
- JB $poly_end ; yes, result = arg. to machine precision
- OR SI, SI ; test flag
- PUSHF ; save flag setting
- PUSH DX ; save
- PUSH BX ; argument
- PUSH AX ; on stack
- PUSH CX ; save number of coefficients
- PUSH DI ; save pointer to table of coefficients
- CALL RealSqrNoChk ; multiply argument (!= 0) by itself
- POP DI ; get back pointer to table
- POP CX ; get back number of coefficients
- PUSH BP ; save TURBO-Pascal base pointer
- MOV BP, SP ; new base pointer to access argument
- PUSH DX ; put
- PUSH BX ; square of argument
- PUSH AX ; on stack
- PUSH CX ; save coefficient counter (CH = 0)
- mov cl, cs:[di]
- inc di
- push di
- mov di, cs:[di]
- call shortmul
- pop di
- pop cx
- inc di
- inc di
- dec cx
- jz $taylor_done
- ; MOV CL, CS:[DI] ; load exponent of first coefficient
- ; XOR SI, SI ; load mantissa middle byte of 1. coeff.
- ; SUB DI, 3 ; fake 6 coefficient bytes
- ; PUSH DI ; save pointer to current coefficient
- ; MOV DI, CS:[DI+4] ; load mantissa MSW of first coefficient
- ; JMPS $start ; start polynomial approximation
- $taylor_loop:PUSH CX ; save coefficient counter
- PUSH DI ; save pointer to current coefficient
- MOV CX, CS:[DI] ; get
- MOV SI, CS:[DI+2] ; coefficient
- MOV DI, CS:[DI+4] ; from table
- CALL RealAdd ; add coefficient
- MOV CX, [BP-6] ; get
- MOV SI, [BP-4] ; saved
- MOV DI, [BP-2] ; square of argument
- $start: CALL RealMulfNoChk ; multiply intermediate result by arg.
- POP DI ; get pointer to current coefficient
- POP CX ; get coefficient counter
- ADD DI, 6 ; pointer to next coefficient
- LOOP $taylor_loop ; loop until coefficients used up
- $taylor_done:MOV SP, BP ; remove square of argument from stack
- POP BP ; restore TURBO-Pascal base pointer
- POP CX ; get back
- POP SI ; original
- POP DI ; argument x
- POPF ; get polynomial type flag
- JNZ $poly_end ;
- PUSH DI ; save
- PUSH SI ; x on
- PUSH CX ; stack
- CALL RealMulfNoChk ; compute P(x^2)*x^2*x
- POP CX ; get
- POP SI ; x from
- POP DI ; stack
- JMP RealAdd ; compute P(x^2)*x^2*x+x, exit v. RealAdd
- $poly_end: RET ; done
- RealPoly ENDP
-
- ALIGN 4
-
- CODE ENDS
-
- END