home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C!T ROM 2
/
ctrom_ii_b.zip
/
ctrom_ii_b
/
PROGRAM
/
PASCAL
/
TPL60N19
/
ARISOURC
/
F48FPOL.ASM
< prev
next >
Wrap
Assembly Source File
|
1993-01-24
|
6KB
|
123 lines
; *******************************************************
; * *
; * Turbo Pascal Runtime Library Version 6.0 *
; * Real Polynomial Evaluation Routine *
; * *
; * Copyright (C) 1989-1992 Norbert Juffa *
; * *
; *******************************************************
TITLE F48FPOL
INCLUDE SE.ASM
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