Files
Digital-Research-Source-Code/CPM OPERATING SYSTEMS/CPM 68K/1.2 SOURCE/8/FFPATAN.S
Sepp J Morris 31738079c4 Upload
Digital Research
2020-11-06 18:50:37 +01:00

145 lines
6.3 KiB
ArmAsm
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

ttl fast floating point arctangent (ffpatan)
***************************************
* (c) copyright 1981 by motorola inc. *
***************************************
*************************************************
* ffpatan *
* fast floating point arctangent *
* *
* input: d7 - input argument *
* *
* output: d7 - arctangent radian result *
* *
* all other registers totally transparent *
* *
* code size: 132 bytes stack work: 32 bytes *
* *
* condition codes: *
* z - set if the result is zero *
* n - cleared *
* v - cleared *
* c - undefined *
* x - undefined *
* *
* *
* notes: *
* 1) spot checks show at least six digit *
* precision on all sampled cases. *
* *
* time: (8mhz no wait states assumed) *
* *
* the time is very data sensitive with *
* sample values ranging from 238 to *
* 465 microseconds *
* *
*************************************************
page
ffpatan idnt 1,2 ffp arctangent
opt pcs
section 9
xdef ffpatan entry point
xref ffptheta arctangent table
xref ffpdiv,ffpsub arithmetic primitives
xref ffptnorm transcendental normalize routine
xref ffpcpyrt copyright stub
piov2 equ $c90fdb41 float pi/2
fpone equ $80000041 float 1
********************
* arctangent entry *
********************
* save registers and perform argument reduction
ffpatan movem.l d1-d6/a0,-(sp) save caller's registers
move.b d7,-(sp) save original sign on stack
and.b #$7f,d7 take absolute value of arg
* insure less than one for cordic loop
move.l #fpone,d6 load up 1
clr.b -(sp) default no inverse required
cmp.b d6,d7 ? less than one
bcs.s fpainrg branch in range
bhi.s fpardc higher - must reduce
cmp.l d6,d7 ? less or equal to one
bls.s fpainrg branch yes, is in range
* argument > 1: atan(1/x) = pi/2 - atan(x)
fpardc not.b (sp) flag inverse taken
exg.l d6,d7 take inverse of argument
jsr ffpdiv perform divide
* perform cordic function
* convert to bin(31,29) precision
fpainrg sub.b #64+3,d7 adjust exponent
neg.b d7 for shift necessary
cmp.b #31,d7 ? too small to worry about
bls.s fpanotz branch if not too small
move.l #0,d6 convert to a zero
bra.s fpazro branch if zero
fpanotz lsr.l d7,d7 shift to bin(31,29) precision
*****************************************
* cordic calculation registers: *
* d1 - loop count a0 - table pointer *
* d2 - shift count *
* d3 - y' d5 - y *
* d4 - x' d6 - z *
* d7 - x *
*****************************************
move.l #0,d6 z=0
move.l #1<<29,d5 y=1
lea ffptheta+4,a0 to arctangent table
move.l #24,d1 loop 25 times
move.l #1,d2 prime shift counter
bra.s cordic enter cordic loop
* cordic loop
fplpls asr.l d2,d4 shift(x')
add.l d4,d5 y = y + x'
add.l (a0),d6 z = z + arctan(i)
cordic move.l d7,d4 x' = x
move.l d5,d3 y' = y
asr.l d2,d3 shift(y')
fplnlp sub.l d3,d7 x = x - y'
bpl.s fplpls branch negative
move.l d4,d7 restore x
add.l #4,a0 to next table entry
add.b #1,d2 increment shift count
lsr.l #1,d3 shift(y')
dbra d1,fplnlp and loop until done
* now convert to float and reconstruct the result
jsr ffptnorm float z
fpazro move.l d6,d7 copy answer to d7
tst.b (sp)+ ? was inverse taken
beq.s fpaninv branch if not
move.l #piov2,d7 take away from pi over two
jsr ffpsub subtract
fpaninv move.b (sp)+,d6 load original sign
tst.b d7 ? result zero
beq.s fpartn return if so
and.b #$80,d6 clear exponent portion
or.b d6,d7 if minus, give minus result
fpartn movem.l (sp)+,d1-d6/a0 restore caller's registers
rts return to caller
end
0 restore caller's registers
rts return to caller
end
0 restore caller's registers
rts return to caller
end
0 restore caller's registers
rts return to caller
end