	NAME	FPINT
	CSEG
;
;
;	LINK TO EXTERNAL REFERENCES
;
	EXTRN	FSTOR,FLOAD,FADD,FTEST,FZERO,FABS,FMUL,FDIV
	EXTRN	FFLOAT,FFIX,FCHS,FSUB
	EXTRN	OVER
	EXTRN	OVERF,ACC2,ACCE
	EXTRN	SEED
	PUBLIC	IDV,FCOSH,FSQRT,FSIN,FCOS,FATAN,FSINH,FEXP,FLOG
	PUBLIC	RAND
;
;	ENTRY IDV - INVERSE FDIVIDE
;
;	STORAGE IN SCRATCH PAD
	SCRT:	DS	25
IDVT	EQU	SCRT + 00H
;
IDV:	PUSH	H
	CALL	FTEST	;FLOATING POINT ACCUMULATOR TO REGISTERS
	LXI	H,IDVT
	CALL	FSTOR	;FDIVISOR TO STORAGE
	POP	H
	CALL	FLOAD	;FDIVIDEND TO FLOATING POINT ACCUMULATOR
	LXI	H,IDVT
	JMP	FDIV	;RETURN THROUGH DIV ROUTINE
;
;
;
;	FLOATING POINT SQUARE ROOT ROUTINE BY NEWTONIAN ITERATION
;
;	THE SQUARE ROOT OF THE FABSOLUTE VALUE OF THE
;	CONTENTS OF THE FLOATING POINT ACCUMULATOR IS
;	RETURNED IN THE FLOATING POINT ACCUMULATOR.
;
;
;	STORAGE IN SCRATCH BANK
FSQRN	EQU	SCRT + 00H
FSQRX	EQU	SCRT + 04H
;
FSQRT:	CALL	FABS	;FORCE ARGUMENT POSITIVE, SET ZERO FLAG
	RZ		;RETURN ON ZERO
	LXI	H,FSQRN
	CALL	FSTOR
	ANA	A	;RESET CARRY BIT
	RAR		;HALVE THE EXPONENT
	ADI	40H	;RESTORE THE OFFSET
	LXI	H,FSQRX
	CALL	FSTOR
	MVI	D,5	;ITERATION COUNT
	PUSH	D	;STACKED
FSQRL:	LXI	H,FSQRN
	CALL	FLOAD
	LXI	H,FSQRX
	CALL	FDIV
	LXI	H,FSQRX
	CALL	FADD
	SUI	1	;HALVE THE RESULT
	LXI	H,FSQRX
	CALL	FSTOR
	POP	D	;RESTORE ITERATION COUNT
	DCR	D	;TALLY
	JZ	FSQRE	;EXIT WHEN COUNT EXHAUSTED
	PUSH	D	;SAVE IT OTHERWISE
	JMP	FSQRL	;TO NEXT ITERATION
FSQRE:	LXI	H,FSQRX	;RESULT TO ACCUMULATOR
	CALL	FLOAD
	RET
;
;	EVALUATION OF ELEMENTARY FUNCTION MACLAURIN SERIES
;
;
;	ENTRY FMACE FOR EXPONENTIAL TYPE SERIES, E.G.
;	SINH(Z) = Z/1 + Z^3/6 + Z^5/120 + ...
;		S(I-1) = (1. + X*S(I)/A(I)), S(N) = 1.
;
;	ENTRY FMACL FOR LOGARITHMIC TYPE SERIES, E.G.
;	ARCTAN(Z) = Z/1 - Z^3/3 + Z^5/5 - ...
;		S(I-1) = (1./A(I) + X*S(I)), S(N) = 0.
;
;	IN BOTH SERIES DEL^2(A(I)) MUST BE CONSTANT.
;	ENTER WITH X IN FMACX, A(N) IN D, D(A(N-1)) IN C,
;		D^2(A(1)) IN B.
;	RESULT IN FMACS, WHEN A(I) <= 0.
;
;	STORAGE IN SCRATCH BANK
FMACX	EQU	SCRT+00H
FMACS	EQU	SCRT+04H
FMACT	EQU	SCRT+08H
FMACG	EQU	SCRT+0CH
;
;	TWO SUBROUTINE LEVELS USED
;
FMACL:	XRA	A	;CLEAR A REGISTER FOR LOG TYPE SERIES
	LXI	H,FMACS	;POINT TO SIGMA
	MOV	M,A	;ZERO STORED
	LXI	H,FMACB	;PRESET BRANCH B
	JMP	FMACC	;JOINT CODE
FMACE:	LHLD	FONE	;MOVE 1.0 TO SIGMA FOR EXP TYPE SERIES
	SHLD	FMACS
	LHLD	FONE+2
	SHLD	FMACS+2
	LXI	H,FMACA	;PRESET BRANCH A
FMACC:	SHLD	FMACG	;STORE PRESET BRANCH
	MVI	E,32	;COUNT FOR THE FLOATING OF A(I)
FMACD:	PUSH	B	;CHAIN RULE LOOP
	PUSH	D	;SAVE A(I), D(A(I)), D^2(A(1))
	XRA	A	;ZERO THE LEAD POSITIONS OF A(I)
	MOV	B,A
	MOV	C,A
	CALL	FFLOAT	;FLOAT A(I)
	LXI	H,FMACT
	CALL	FSTOR
	LXI	H,FMACX
	CALL	FLOAD
	LXI	H,FMACS
	CALL	FMUL
	LHLD	FMACG	;CHOOSE THE BRANCH
	PCHL
FMACA:	LXI	H,FMACT
	CALL	FDIV
	LXI	H,FONE	;POINTS TO 1.0
	JMP	FMACF	;REJOIN COMMON CODE
FMACB:	LXI	H,FMACS
	CALL	FSTOR	;X*SIGMA
	LXI	H,FONE	;LOAD 1.0
	CALL	FLOAD
	LXI	H,FMACT
	CALL	FDIV	;1/A(I)
	LXI	H,FMACS
FMACF:	CALL	FADD
	LXI	H,FMACS
	CALL	FSTOR
	POP	D	;A(I) AND 32
	POP	B	;D(A) AND D^2(A)
	MOV	A,D
	SUB	C
	RZ	;DONE IF ZERO
	RC	;OR NEGATIVE
	MOV	D,A	;A(I-1)
	MOV	A,C	;D(A(I-1))
	SUB	B
	MOV	C,A	;D(A(I-2))
	JMP	FMACD	;NEXT ITERATION
FONE:	DB	81H,0,0,0	;CAN BE IN ROM
FPIV2:	DB	81H,49H,0FH,0DCH;PI/2
FLN2:	DB	80H,31H,72H,18H;LN 2
;
;
;	SINE-COSINE ROUTINE USING MACLAURIN SERIES
;
;
;	ENTRY FSIN FOR SIN(X)
;	ENTRY FCOS FOR COS(X)
;	ENTER WITH X IN RADIANS IN FLOATING POINT ACCUMULATOR
;	RETURNS WITH FUNCTION IN FLOATIG POINT ACCUMULATOR
;	(IF FABS(X) >= 2^24*PI, OVERFLOW FLAG IS SET)
;
;	STORAGE IN SCRATCH BANK
FSINX	EQU	SCRT+10H
;
;	THREE LEVELS OF SUBROUTINES USED
;
FCOS:	CALL	FCHS	;COMPLEMENT THE ANGLE
	LXI	H,FPIV2
	CALL	FADD
FSIN:	CALL	FTEST	;FETCH ARGUMENT
	LXI	H,FSINX
	CALL	FSTOR
	LXI	H,FPIV2	;REDUCE X TO REVOLUTIONS*4
	CALL	FDIV
	MVI	E,26	;REVOLUTIONS AT BINARY SCALE 24
	CALL	FFIX
	JC	OVERF	;QUIT IF ANGLE TO LARGE
	MVI	E,26
	MVI	D,0	;WIPE OUT FRACTIONAL REVOLUTIONS
	CALL	FFLOAT	;INTEGER PART OF REVOLUTIONS
	LXI	H,FPIV2	;TO RADIANS
	CALL	FMUL
	CALL	FCHS
FSINA:	LXI	H,FSINX
	CALL	FADD
	LXI	H,FSINX
	CALL	FSTOR
	CALL	FABS	;FORCE ANGLE INTO REDUCED RANGE
	LXI	H,FPIV2
	CALL	FSUB
	JM	FSINB	;IF NEGATIVE OR ZERO
	JZ	FSINB	;THEN ANDGLE IS REDUCED
	LXI	H,FPIV2	;FABS(X)-PI
	CALL	FSUB
	MOV	E,A	;SAVE A REGISTER
	LXI	H,FSINX+1
	MOV	A,M
	ANI	80H	;SIGN OF X
	XRI	80H	;INVERTED
	XRA	B	;-SIGN(X)*(FABS(X)-PI)
	MOV	B,A
	MOV	A,E	;RESTORE A REGISTER
	DCX	H	;POINT TO FSINX
	CALL	FSTOR	;REDUCED X
	CALL	FZERO	;CLEAR ACCUMULATOR
	JMP	FSINA	;REPEAT UNTIL FABS(X) <= PI/2
;
FSINB:	LXI	H,FSINX
	CALL	FLOAD
	LXI	H,FSINX
	CALL	FMUL
	CALL	FCHS	;-X^2
	LXI	H,FMACX
	CALL	FSTOR	;TO MACLAURIN SERIES
	MVI	D,72	;9*8, 11 TERM DISCARDED, 18 BITS PRECISION
	MVI	C,30	;9*8 - 7*6
	MVI	B,8	;(9*8 - 7*6) - (7*6 - 5*4)
	CALL	FMACE
	LXI	H,FMACS
	CALL	FLOAD
	LXI	H,FSINX
	CALL	FMUL
	CPI	81H	;SEE IF TAIL NEEDS CLEANING
	JC	FSINC	;NO, MAGNITUDE IS < 1.0
	LXI	H,ACC2
	XRA	A
	MOV	M,A
	INR	L
	MOV	M,A
FSINC:	CALL	FTEST	;RESTORE FLAGS AND REGISTERS FOR EXIT
	RET
;
;
;	ARCTAN ROUTINE USING MACLAURIN SERIES
;
;
;
;	ENTRY FATAN FOR ARCTAN(X), WITH X IN FLOATING POINT ACCUMULATOR
;	RESULT RETURNED IN FLOATING POINT ACCUMULATOR
;
;	STORAGE IN SCRATCH BANK
FATNT	EQU	SCRT+10H
FATNU	EQU	SCRT+14H
;
;	FOUR LEVELS OF STACK USED
;
FATAN:	CALL	FTEST	;GET F.P. ACC. INTO REGISTERS
	RZ
	CPI	81H	;TEST EXPONENT
	JC	FATN1	;RETURN TO CALLER FROM FATN1
	LXI	H,FONE	;1.0
	CALL	IDV	;1.0/X
	CALL	FATN1	;ARCTAN(1/X)
	LXI	H,FATNU
	CALL	FSTOR
	LXI	H,FPIV2	;PI/2
	CALL	FLOAD
	MOV	E,A	;SAVE A REGISTER
	LXI	H,FATNU+1	;SIGN(T)
	MOV	A,M	;TO A REGISTER
	ANI	80H
	ORA	B	;ATTACH TO PI/2
	MOV	B,A
	MOV	A,E	;RESTORE A REGISTER
	LXI	H,FATNT
	CALL	FSTOR
	LXI	H,FATNT
	CALL	FLOAD
	LXI	H,FATNU	;-SIGN(T)*(PI/S-FABS(T))
	CALL	FSUB	;=SIGN(T)*FABS(T) = T
	RET
;
;	EVALUATE ARCTAN OF ARGUMENTS < 1.0
FATN1:	LXI	H,FATNT	;POINT TO TEMP
	CALL	FSTOR	;TAN(T)
	LXI	H,FATNT
	CALL	FMUL	;TAN(T)^2
	LXI	H,FONE	;1.0
	CALL	FADD
	CALL	FSQRT
	LXI	H,FONE
	CALL	FADD	;1.0+SQRT(TAN(T)^2+1.0)
	LXI	H,FATNT
	CALL	IDV	;TAN(T/2)
	LXI	H,FATNT
	CALL	FSTOR
	LXI	H,FATNU
	INR	A	;2*TAN(T/2)
	CALL	FSTOR
	LXI	H,FATNT
	CALL	FMUL
	CALL	FCHS	;-TAN(T/2)^2
	LXI	H,FMACX
	CALL	FSTOR
	MVI	D,11	;TERM 13 DISCARDED, 16 BITS PRECISION IN RANGE
	MVI	C,2	;(11-9)
	MVI	B,0	;(11-9)-(9-7)
	CALL	FMACL
	LXI	H,FMACS
	CALL	FLOAD
	LXI	H,FATNU
	CALL	FMUL
	RET
;
;
;
;	HYPERBOLIC COSINE ROUTINE USING MACLAURIN SERIES
;
;
;
;	ENTRY FCOSH FOR COSH(X), WITH X IN THE FLOATING POINT ACCUMULATOR
;	THE RESULT IS RETURNED IN THE F.P. ACCUMULATOR.
;	IF FABS(X) > 88.0 THE OVERFLOW FLAG IS SET.
;
;	STORAGE IN SCRATCH BANK
FCSHD	EQU	SCRT+0EH	;DOUBLING COUNTER
;
;	THREE LEVELS OF STACK USED
;
FCOSH:	CALL	FTEST	;GET ARGUMENT INTO REGISTERS
	LXI	H,FMACX
	CALL	FSTOR
	LXI	H,FCSHD
	MVI	M,0
	SUI	80H	;REMOVE EXPONENT OFFSET
	JM	FCSHA	;DOUBLING COUNT AND X ARE OK
	CPI	8	;ELIMINATE OVERSIZE DOUBLING COUNT
	JP	OVERF	;RETURN THROUGH OVERFLOW ROUTINE
	MOV	M,A	;SAVE THE DOUBLING COUNT
	LXI	H,FMACX
	MVI	M,80H
	CALL	FLOAD	;PUT X INTO ACC
FCSHA:	LXI	H,FMACX
	CALL	FMUL	;X^2
	LXI	H,FMACX
	CALL	FSTOR
	MVI	D,56	;8*7, 10 TERM DISCARDED, 21 BITS PRECISION
	MVI	C,26	;(8*7-6*5)
	MVI	B,8	;(8*7-6*5) - (6*5-4*3)
	CALL	FMACE
FCSHB:	LXI	H,FCSHD	;ADDRESS THE DOUBLING COUNT
	DCR	M	;TALLY AT LOOP TOP
	JM	FCSHC	;DONE WHEN COUNT IS NEGATIVE
	LXI	H,FMACS	;FETCH COSH(X/2)
	CALL	FLOAD
	LXI	H,FMACS
	CALL	FMUL	;COSH(X/2)^2
	LXI	H,ACCE
	INR	M	;2*COSH(X/2)^2
	LXI	H,FONE	;-1.0
	CALL	FSUB	;=COSH(X)
	LXI	H,FMACS
	CALL	FSTOR
	JMP	FCSHB	;TEST DOUBLING COUNT
FCSHC:	CALL	FTEST	;RESTORE REGISTERS AND FLAGS
	RET
;
;
;
;	EXPONENTIAL AND HYPERBOLIC SIN ROUTINE
;
;
;	SCRATCH BANK STORAGE
FSNHD	EQU	SCRT+0EH
FEXOV	EQU	SCRT+0FH
FSNHX	EQU	SCRT+10H
;
;
;	ENTRY FEXP FOR EXP(X)
;	ENTRY SSINH FOR SINH(X)
;		ENTRY WITH X IN FP ACCUMULATOR
;		RETURNS WITH FUNCTION IN FP ACCUMULATOR.
;		IF FUNCTION EXCEEDS 2^127M OVERFLOW FLAG WILL BE SET
;
FSINH:	CALL	FTEST	;FETCH FP ACCUMULATOR
	LXI	H,FSNHX	;SAVE ARGUMENT
	CALL	FSTOR
	LXI	H,FSNHD	;ADDRESS DOUBLING COUNTER
	MVI	M,0
	SUI	80H	;REMOVE OFFSET FROM A
	JM	FSNHA	;DOUBLING COUNT AND X ARE OK
	CPI	8	;ELIMINATE OVERSIZE DOUBLING COUNT
	JP	OVERF	;RETURN THROUGH OVERFLOW ROUTINE
	MOV	M,A	;SAVE DOUBLING COUNT
	LXI	H,FSNHX	;BRING ARGUMENT INTO RANGE
	MVI	M,80H
	CALL	FLOAD	;PUT X INTO FLOATING ACCUMULATOR
FSNHA:	LXI	H,FSNHX
	CALL	FMUL	;X^2
	LXI	H,FMACX
	CALL	FSTOR
	MVI	D,42	;7*6, 9 TERM DISCARDED, 18 BITS PRECISION
	MVI	C,22	;7*6-5*4
	MVI	B,8	;(7*6-5*4)-(F*4-3*2)
	CALL	FMACE
	LXI	H,FMACS
	CALL	FLOAD
	LXI	H,FSNHX
	CALL	FMUL
	LXI	H,FSNHX	;SINH(X)
	CALL	FSTOR
	LXI	H,FSNHX	;SINH(X)^2
	CALL	FMUL
	LXI	H,FONE	;+1.0
	CALL	FADD
	CALL	FSQRT	;COSH(X) FOR DOUBLINE AND FOR EXP(X9
	LXI	H,FMACX	;TEMP
	CALL	FSTOR
FSNHB:	LXI	H,FSNHD	;ADDRESS DOUBLING COUNT
	DCR	M	;TALLY AT LOOP TOP
	JM	FSNHC	;DONE WHEN NEGATIVE
	LXI	H,FMACX	;COSH(X/2)
	CALL	FLOAD
	LXI	H,FSNHX	;SINH(X/2)
	CALL	FMUL
	INR	A	;2.*SINH(X/2)*COSH(X/2)
	LXI	H,FSNHX	;SINH(X)
	CALL	FSTOR
	LXI	H,FMACX	;COSH(X/2)
	CALL	FLOAD
	LXI	H,FMACX
	CALL	FMUL
	LXI	H,ACCE	;2.*COSH(X/2)^2
	INR	M
	LXI	H,FONE	;-1
	CALL	FSUB
	LXI	H,FMACX	;=COSH(X)
	CALL	FSTOR
	JMP	FSNHB	;TEST THE DOUBLING COUNT
FSNHC:	LXI	H,FSNHX
	CALL	FLOAD
	RET
FEXP:	CALL	FTEST
	JP	FEXPP
	LXI	H,OVER	;SAVE OVERFLOW FLAG
	MOV	E,M
	MVI	M,0
        LXI	H,FEXOV
	MOV	M,E	;OLD FLAG TO SAVE CELL
	CALL	FABS
	CALL	FEXPP	;EXP(-X) IN ACC
	LXI	H,FEXOV	;GET OLD OVERFLOW FLAG BACK
	MOV	E,M
	LXI	H,OVER	;PICK UP NEW ONE TO TEST
	MOV	A,M
	MOV	M,E	;RESTORE OLD OVERFLOW FLAG
	ANA	A	;SET FLAGS
	JNZ	FZERO	;RECIPROCAL OF OVERFLOW IS ZERO
	LXI	H,FONE
	CALL	IDV	;1./EXP(-X) = EXP(X)
	RET
FEXPP:	CALL	FSINH	;SINH(X)
	LXI	H,FMACX	;+COSH(X)
	CALL	FADD	;=EXP(X)
	RET
;
;
;
;	NATURAL LOGARITHM ROUTINE USING MACLAURIN SERIES
;
;
;
;
;	ENTRY POINTS IN MACLAURIN SERIES
;	STORAGE IN SCRATCH BANK
FLOGE	EQU	SCRT+0EH
FLOGX	EQU	SCRT+10H
;
;
;	ENTRY FLOG FOR LN(FABS(X)), WITH X IN F.P. ACCUMULATOR
;	RESULT IS RETURNED IN FLOATING POINT ACCUMULATOR
;	IF X = 0 THE OVERFLOW FLAG IS SET
;
;	3 LEVELS OF SUBROUTINES USED
;
FLOG:	CALL	FABS	;FORCE ARGUMENT POSITIVE, SET ZERO FLAG
	JZ	OVERF	;RETURN THROUGH OVERFLOW ROUTINE
	SUI	81H	;REMOVE EXPONENT OFFSET
	LXI	H,FLOGE
	MOV	M,A
	MVI	A,81H	;NORMALIZE ARGUMENT
	LXI	H,FLOGX
	CALL	FSTOR	;CALL IT X
	LXI	H,FLOGX
	CALL	FLOAD
	LXI	H,FONE
	CALL	FADD
	LXI	H,FMACS
	CALL	FSTOR	;X+1.0
	LXI	H,FLOGX
	CALL	FLOAD
	LXI	H,FONE
	CALL	FSUB	;X-1.0
	LXI	H,FMACS
	CALL	FDIV
	LXI	H,FLOGX
	CALL	FSTOR	;(X-1.0)/(X+1.0)
	LXI	H,FLOGX
	CALL	FMUL
	LXI	H,FMACX
	CALL	FSTOR	;((X-1.0)/(X+1.0))^2
	MVI	D,9	;DISCARD 11 TERM FOR 18 BITS PRECISION
	MVI	C,2	;9-7
	MVI	B,0	;(9-7)-(7-5)
	CALL	FMACL
	LXI	H,FMACS
	INR	M	;DOUBLE THE SUM
	CALL	FLOAD
	LXI	H,FLOGX
	CALL	FMUL	;LOGARITHM OF FRACTIONAL PART
	LXI	H,FLOGX
	CALL	FSTOR
	LXI	H,FLOGE
	MOV	A,M
	MVI	B,0
	MOV	C,B
	MOV	D,B
	MVI	E,8	;BINARY SCALE FACTOR FOR EXPONENT
	CALL	FFLOAT
	LXI	H,FLN2
	CALL	FMUL	;LOGARITHM OF 2^EXPONENT
	LXI	H,FLOGX	;LOG OF FRACTIONAL PART
	CALL	FADD
	RET
;
;	RANDOM NUMBER GENERATOR
;
;
RAND:	;COMPUTE NEXT RANDOM NUMBER, AND LEAVE AT SEED
	LXI	H,SEED
	MOV	C,M	;GET LEAST SIGNIFICANT BYTE
	INR	L
	MOV	B,M	;X(N) IN B,C
	DCR	L	;ADDRESS SEED FOR SBR2
	CALL	AROUT	;CALCUALTE X(N)*2053D
	LXI	H,CNST	;ADDRESS CONSTANT 13849
	CALL	SBR2
	LXI	H,SEED	;ADDRESS SEED AGAIN
	MOV	M,C	;STORE NEW SEED
	INR	L
	MOV	M,B
	RET		;WITH SEED SET TO RANDOM NUMBER
;
CNST:	DW	13849
;
AROUT:	;COMPUTE X(N)*2053D TO B,C
	MVI	D,9	;X(N)*2**9
	CALL	SBR1
	CALL	SBR2	;X(N)+X(N)*2**9
	MVI	D,2	;2**2*(X(N)+X(N)*2**9)
	CALL	SBR1
	CALL	SBR2	;ADD TO X(N)
	RET
;
SBR1:	;FORMS (B AND C)*2**D
	SUB	A	;CLEAR A AND CARRY
	MOV	A,C	;SHIFT C LEFT
	RAL
	MOV	C,A
	MOV	A,B	;SHIFT B LEFT
	RAL
	MOV	B,A
	DCR	D	;TEST D=0
	RZ		;IF YES, RETURN
	JMP	SBR1	;NO, SHIFT AGAIN
;
SBR2:	;16-BIT ADD OF B,C TO M(H,L), RESULT TO B,C
	SUB	A	;CLEAR A AND CARRY
	MOV	A,M	;LOAD LOW BYTE
	ADD	C	;M(H,L)+C
	MOV	C,A
	INR	L	;M(H,L+1)
	MOV	A,M
	ADC	B
	MOV	B,A
	DCR	L	;RESTORE H,L FOR NEXT OPERATION
	RET
	END
