Digital Research
This commit is contained in:
2020-11-06 18:50:37 +01:00
parent 621ed8ccaf
commit 31738079c4
8481 changed files with 1888323 additions and 0 deletions

View File

@@ -0,0 +1,25 @@
*
* Floating Point Arctangen:
* Front End to FFP Floating Point Package.
*
* double
* atan(farg)
* double farg;
*
* Returns : negated Floating point number
*
.globl _atan
.globl iefatan
.text
fpatan:
_atan:
~~atan:
link r14,#-4
move.l d7,-(sp)
move.l 8(r14),r7
jsr iefatan
move.l r7,r0
move.l (sp)+,d7
unlk r14
rts

View File

@@ -0,0 +1,126 @@
/*
Copyright 1982, 1983
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
/*char *version "@(#)atof.c 1.3 12/29/83";*/
/*
* Ascii String to IEEE Floating Point Routine :
* IEEE Standard Single Precision Representation Floating Point
*
* float
* atof(buf)
* char *buf;
*
* No more than 9 significant digits are allowed in single precision.
* Largest positive number is 3.4 * 10^33 and the smallest positive
* number is 1.2 * 10^-38.
* Rely's on the fact that a long and a float are both 32 bits.
*/
#define BIAS 127L
#define EXPSIZ 4
#define FRACSIZ 20
long fptoieee();
float strbin();
float power10();
long
atof(buf)
char *buf;
{
char ibuf[FRACSIZ], ebuf[EXPSIZ];
register char *ip, *ep;
long ieee; /* return value */
int dp, esign, isign, ebin, places;
float ibin, fp;
ip = ibuf; ep = ebuf; dp = 0; places = 0L;
while (*buf == ' ' || *buf == '\t') /* ignore white spaces */
buf++;
isign = (*buf == '-');
if (*buf == '-' || *buf == '+')
buf++;
while (*buf && *buf != 'e' && *buf != 'E') {
if (*buf == '.')
dp++;
else { /* digit seen */
*ip++ = *buf;
if (dp)
places++;
}
buf++;
}
*ip = 0;
if (*buf == 'e' || *buf == 'E') { /* exponent string */
buf++;
esign = (*buf == '-');
if (*buf == '-' || *buf == '+')
buf++;
while (*buf) /* get exponent string */
*ep++ = *buf++;
}
*ep = 0;
ibin = strbin(ibuf);
ebin = atoi(ebuf);
places = (esign) ? -ebin - places : ebin - places;
fp = ibin * power10(places);
ieee = fptoieee(fp);
if (isign) /* negative float */
ieee =| 0x80000000;
return( ieee );
}
float
power10(pwr) /* 10^pwr */
int pwr;
{
float f;
if (pwr < 0L) /* negative power */
for (f = 1.0; pwr < 0; pwr++)
f = f / 10.0;
else /* positive power */
for (f = 1.0; pwr > 0; pwr--)
f = f * 10.0;
return(f);
}
long
fptoieee(f) /* convert current machine float to ieee rep */
float f; /* unsigned float... */
{
register long exp, l;
if (f == 0.0)
return(0L);
exp = 0L;
for( ; f >= 2.0; f = f / 2.0)
exp++;
for( ; f < 1.0; f = f * 2.0)
exp--;
f = f - 1.0; /* implicit 1, eg. 1.F */
if (f != 0.0)
f = f * 8388608.0; /* 2 ^ 23 */
l = f;
exp =+ BIAS;
l =| ((exp<<23) & 0x7f800000);
return(l);
}
float
strbin(p) /* decimal string => binary long */
char *p;
{
float f;
for (f = 0.0; *p >= '0' && *p <= '9'; p++) {
f = f * 10.0;
f = f + (*p - '0');
}
return(f);
}

View File

@@ -0,0 +1,13 @@
c68 -c -L -e atof.c
c68 -c -L -e ceil.c
c68 -c -L -e etoa.c
c68 -c -L -e fabs.c
c68 -c -L -e floor.c
c68 -c -L -e fmod.c
c68 -c -L -e fprintf.c
c68 -c -L -e ftoa.c
c68 -c -L -e ftol.c
c68 -c -L -e ieeetof.c
c68 -c -L -e ltof.c
c68 -c -L -e printf.c
c68 -c -L -e fscanf.c

View File

@@ -0,0 +1,26 @@
/*
Copyright 1983
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
/*char *version "@(#)ceil.c 1.2 10/19/83";*/
/* ceil - returns the smallest integer (as a double precision
number) not greater than x. */
double
ceil(x)
double x;
{
register long i;
double retval;
if( x > 0 )
x += 0.999999999999;
i = x;
retval = i;
return( retval );
}

View File

@@ -0,0 +1,25 @@
*
* Floating Point Hyperbolic cosine:
* Front End to FFP Floating Point Package.
*
* double
* cosh(farg)
* double farg;
*
* Returns : negated Floating point number
*
.globl _cosh
.globl iefcosh
.text
fpcosh:
_cosh:
~~cosh:
link r14,#-4
move.l d7,-(sp)
move.l 8(r14),r7
jsr iefcosh
move.l r7,r0
move.l (sp)+,d7
unlk r14
rts

View File

@@ -0,0 +1,61 @@
e:vax ATAN.S r
e:vax ATOF.C r
e:vax BUILDFILE. r
e:vax CEIL.C r
e:vax COSH.S r
e:vax DOWN.SUB r
e:vax ETOA.C r
e:vax FABS.C r
e:vax FFPABS.S r
e:vax FFPADD.S r
e:vax FFPATAN.S r
e:vax FFPCMP.S r
e:vax FFPCPYRT.S r
e:vax FFPDIV.S r
e:vax FFPEXP.S r
e:vax FFPHTHET.S r
e:vax FFPIEEE.S r
e:vax FFPLOG.S r
e:vax FFPMUL2.S r
e:vax FFPPWR.S r
e:vax FFPSIN.S r
e:vax FFPSQRT.S r
e:vax FFPTHETA.S r
e:vax FFPTNORM.S r
e:vax FLOOR.C r
e:vax FMOD.C r
e:vax FPADD.S r
e:vax FPCMP.S r
e:vax FPCOS.S r
e:vax FPDIV.S r
e:vax FPEXP.S r
e:vax FPLOG.S r
e:vax FPMUL.S r
e:vax FPNEG.S r
e:vax FPPWR.S r
e:vax FPRINTF.C r
e:vax FPSIN.S r
e:vax FPSQRT.S r
e:vax FPSUB.S r
e:vax FSCANF.C r
e:vax FTOA.C r
e:vax FTOL.C r
e:vax IEEETOF.C r
e:vax IEFABS.S r
e:vax IEFADD.S r
e:vax IEFATAN.S r
e:vax IEFBACK.S r
e:vax IEFCMP.S r
e:vax IEFDIV.S r
e:vax IEFEXP.S r
e:vax IEFFRONT.S r
e:vax IEFLOG.S r
e:vax IEFMUL.S r
e:vax IEFPWR.S r
e:vax IEFSIN.S r
e:vax IEFSINH.S r
e:vax IEFSQRT.S r
e:vax LTOF.C r
e:vax PRINTF.C r
e:vax SINH.S r
e:vax TANH.S r

View File

@@ -0,0 +1,66 @@
Directory _DRB0:[STEVE.CPM68K.V102A.LIBE]
ATAN.S;2
ATOF.C;2
BUILDFILE.;2
CEIL.C;2
COSH.S;2
DOWN.SUB;1
ETOA.C;2
FABS.C;2
FFPABS.S;2
FFPADD.S;2
FFPATAN.S;2
FFPCMP.S;2
FFPCPYRT.S;2
FFPDIV.S;2
FFPEXP.S;2
FFPHTHET.S;2
FFPIEEE.S;2
FFPLOG.S;2
FFPMUL2.S;2
FFPPWR.S;2
FFPSIN.S;2
FFPSQRT.S;2
FFPTHETA.S;2
FFPTNORM.S;2
FLOOR.C;2
FMOD.C;2
FPADD.S;2
FPCMP.S;2
FPCOS.S;2
FPDIV.S;2
FPEXP.S;2
FPLOG.S;2
FPMUL.S;2
FPNEG.S;2
FPPWR.S;2
FPRINTF.C;2
FPSIN.S;2
FPSQRT.S;2
FPSUB.S;2
FSCANF.C;2
FTOA.C;2
FTOL.C;2
IEEETOF.C;2
IEFABS.S;2
IEFADD.S;2
IEFATAN.S;2
IEFBACK.S;2
IEFCMP.S;2
IEFDIV.S;2
IEFEXP.S;2
IEFFRONT.S;2
IEFLOG.S;2
IEFMUL.S;2
IEFPWR.S;2
IEFSIN.S;2
IEFSINH.S;2
IEFSQRT.S;2
LTOF.C;2
PRINTF.C;2
SINH.S;2
TANH.S;2
Total of 61 files.

View File

@@ -0,0 +1,117 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
/*char *version "@(#) etoa - jan 24, 1982"; */
/*
* IEEE Floating Point to Ascii String Conversion Routine :
* IEEE Standard Single Precision Representation Floating Point
*
* char *
* etoa(f,buf,prec)
* float f;
* char *buf;
* int prec;
*
* No more than 9 decimal digits are allowed in single precision.
* Largest positive number is 3.4 * 10^33 and the smallest positive
* number is 1.2 * 10^-38.
* Rely's on the fact that a long and a float are both 32 bits.
*/
#define BIAS 127L
#ifndef ISIEEE
/* if this is compiled or executed with other than ieee fp */
float _ieeetof();
#else
float _efake();
#endif
char *
etoa(fl,buf,prec)
long fl; /* ieee formatted float */
char *buf;
int prec;
{
register char *bp;
register int exp, digit;
float f;
prec = (prec <= 0) ? 1 : (prec <= 9) ? prec : 9;
bp = buf;
if(fl == 0) goto shortcut;
if(fl == 0x7f800000) { /* positive infinity */
strcpy(bp,"+infinity");
return(bp);
}
if(fl == 0xff800000) { /* negative infinity */
strcpy(bp,"-infinity");
return(bp);
}
#ifndef ISIEEE
f = _ieeetof(fl); /* get floating point value */
#else
f = _efake(fl);
#endif
#ifndef ISIEEE
if (f < 0.0) { /* negative float */
#else
if (fl & 0x80000000) { /* negative float */
#endif
*bp++ = '-';
f = -f; /* make it positive */
}
#ifndef ISIEEE
if (f == 0.0) {
#else
if (fl == 0) {
#endif
shortcut:
*bp++ = '0'; *bp++ = '.';
while (prec--)
*bp++ = '0';
*bp++ = 'e'; *bp++ = '0'; *bp++ = '0'; *bp = 0;
return(buf);
}
for (exp=0; f < 1.0; f = f * 10.0) /* get negative exp */
exp--;
for ( ; f >= 1.0; f = f / 10.0) /* 0.XXXXXXE00 * 10^exp */
exp++;
exp--; /* for one explicit digit */
f = f * 10.0;
digit = f; /* get one digit */
f = f - digit;
*bp++ = digit + '0';
*bp++ = '.';
while(prec-- > 0) { /* get prec. decimal places */
f = f * 10.0;
digit = f;
f = f - digit;
*bp++ = digit + '0';
}
*bp++ = 'e';
if (exp < 0) {
exp = -exp;
*bp++ = '-';
}
*bp++ = (exp / 10) + '0';
*bp++ = (exp % 10) + '0';
*bp = 0;
return(buf);
}
#ifdef ISIEEE
/* if these routines are executed on a 68000 using ieee then no need to
do a translation !!! */
float
_efake(lf)
float lf;
{
return(lf);
}
#endif

View File

@@ -0,0 +1,27 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
/*char *version "@(#)fabs.c 1.2 10/19/83";*/
/*
* Floating Point Absolute :
* Fast Floating Point Package
*
* double
* fabs(farg)
* double farg;
*
* Returns : absolute Floating point number
*/
long
fabs(f)
long f;
{
f = f & 0x7fffffff; /* turn off sign bit */
return(f);
}

View File

@@ -0,0 +1,68 @@
ttl fast floating point abs/neg (ffpabs/ffpneg)
***************************************
* (c) copyright 1981 by motorola inc. *
***************************************
*************************************************************
* ffpabs *
* fast floating point absolute value *
* *
* input: d7 - fast floating point argument *
* *
* output: d7 - fast floating point absolute value result *
* *
* condition codes: *
* n - cleared *
* z - set if result is zero *
* v - cleared *
* c - undefined *
* x - undefined *
* *
* all registers transparent *
* *
*************************************************************
page
ffpabs idnt 1,1 ffp abs/neg
xdef ffpabs fast floating point absolute value
xref ffpcpyrt copyright notice
section 9
******************************
* absolute value entry point *
******************************
ffpabs and.b #$7f,d7 clear the sign bit
rts and return to the caller
page
*************************************************************
* ffpneg *
* fast floating point negate *
* *
* input: d7 - fast floating point argument *
* *
* output: d7 - fast floating point negated result *
* *
* condition codes: *
* n - set if result is negative *
* z - set if result is zero *
* v - cleared *
* c - undefined *
* x - undefined *
* *
* all registers transparent *
* *
*************************************************************
page
xdef ffpneg fast floating point negate
**********************
* negate entry point *
**********************
ffpneg tst.b d7 ? is argument a zero
beq.s ffprtn return if so
eor.b #$80,d7 invert the sign bit
ffprtn rts and return to caller
end

View File

@@ -0,0 +1,211 @@
ttl fast floating point add/subtract (ffpadd/ffpsub)
***************************************
* (c) copyright 1980 by motorola inc. *
***************************************
*************************************************************
* ffpadd/ffpsub *
* fast floating point add/subtract *
* *
* ffpadd/ffpsub - fast floating point add and subtract *
* *
* input: *
* ffpadd *
* d6 - floating point addend *
* d7 - floating point adder *
* ffpsub *
* d6 - floating point subtrahend *
* d7 - floating point minuend *
* *
* output: *
* d7 - floating point add result *
* *
* condition codes: *
* n - result is negative *
* z - result is zero *
* v - overflow has occured *
* c - undefined *
* x - undefined *
* *
* registers d3 thru d5 are volatile *
* *
* code size: 228 bytes stack work area: 0 bytes *
* *
* notes: *
* 1) addend/subtrahend unaltered (d6). *
* 2) underflow returns zero and is unflagged. *
* 3) overflow returns the highest value with the *
* correct sign and the 'v' bit set in the ccr. *
* *
* time: (8 mhz no wait states assumed) *
* *
* composite average 20.625 microseconds *
* *
* add: arg1=0 7.75 microseconds *
* arg2=0 5.25 microseconds *
* *
* like signs 14.50 - 26.00 microseconds *
* average 18.00 microseconds *
* unlike signs 20.13 - 54.38 microceconds *
* average 22.00 microseconds *
* *
* subtract: arg1=0 4.25 microseconds *
* arg2=0 9.88 microseconds *
* *
* like signs 15.75 - 27.25 microseconds *
* average 19.25 microseconds *
* unlike signs 21.38 - 55.63 microseconds *
* average 23.25 microseconds *
* *
*************************************************************
page
ffpadd idnt 1,1 ffp add/subtract
xdef ffpadd,ffpsub entry points
xref ffpcpyrt copyright notice
section 9
************************
* subtract entry point *
************************
ffpsub move.b d6,d4 test arg1
beq.s fpart2 return arg2 if arg1 zero
eor.b #$80,d4 invert copied sign of arg1
bmi.s fpami1 branch arg1 minus
* + arg1
move.b d7,d5 copy and test arg2
bmi.s fpams branch arg2 minus
bne.s fpals branch positive not zero
bra.s fpart1 return arg1 since arg2 is zero
*******************
* add entry point *
*******************
ffpadd move.b d6,d4 test argument1
bmi.s fpami1 branch if arg1 minus
beq.s fpart2 return arg2 if zero
* + arg1
move.b d7,d5 test argument2
bmi.s fpams branch if mixed signs
beq.s fpart1 zero so return argument1
* +arg1 +arg2
* -arg1 -arg2
fpals sub.b d4,d5 test exponent magnitudes
bmi.s fpa2lt branch arg1 greater
move.b d7,d4 setup stronger s+exp in d4
* arg1exp <= arg2exp
cmp.b #24,d5 overbearing size
bcc.s fpart2 branch yes, return arg2
move.l d6,d3 copy arg1
clr.b d3 clean off sign+exponent
lsr.l d5,d3 shift to same magnitude
move.b #$80,d7 force carry if lsb-1 on
add.l d3,d7 add arguments
bcs.s fpa2gc branch if carry produced
fparsr move.b d4,d7 restore sign/exponent
rts return to caller
* add same sign overflow normalization
fpa2gc roxr.l #1,d7 shift carry back into result
add.b #1,d4 add one to exponent
bvs.s fpa2os branch overflow
bcc.s fparsr branch if no exponent overflow
fpa2os moveq #-1,d7 create all ones
sub.b #1,d4 back to highest exponent+sign
move.b d4,d7 replace in result
* or.b #$02,ccr show overflow occurred
dc.l $003c0002 ****assembler error****
rts return to caller
* return argument1
fpart1 move.l d6,d7 move in as result
move.b d4,d7 move in prepared sign+exponent
rts return to caller
* return argument2
fpart2 tst.b d7 test for returned value
rts return to caller
* -arg1exp > -arg2exp
* +arg1exp > +arg2exp
fpa2lt cmp.b #-24,d5 ? arguments within range
ble.s fpart1 nope, return larger
neg.b d5 change difference to positive
move.l d6,d3 setup larger value
clr.b d7 clean off sign+exponent
lsr.l d5,d7 shift to same magnitude
move.b #$80,d3 force carry if lsb-1 on
add.l d3,d7 add arguments
bcs.s fpa2gc branch if carry produced
move.b d4,d7 restore sign/exponent
rts return to caller
* -arg1
fpami1 move.b d7,d5 test arg2's sign
bmi.s fpals branch for like signs
beq.s fpart1 if zero return argument1
* -arg1 +arg2
* +arg1 -arg2
fpams moveq #-128,d3 create a carry mask ($80)
eor.b d3,d5 strip sign off arg2 s+exp copy
sub.b d4,d5 compare magnitudes
beq.s fpaeq branch equal magnitudes
bmi.s fpatlt branch if arg1 larger
* arg1 <= arg2
cmp.b #24,d5 compare magnitude difference
bcc.s fpart2 branch arg2 much bigger
move.b d7,d4 arg2 s+exp dominates
move.b d3,d7 setup carry on arg2
move.l d6,d3 copy arg1
fpamss clr.b d3 clear extraneous bits
lsr.l d5,d3 adjust for magnitude
sub.l d3,d7 subtract smaller from larger
bmi.s fparsr return final result if no overflow
* mixed signs normalize
fpanor move.b d4,d5 save correct sign
fpanrm clr.b d7 clear subtract residue
sub.b #1,d4 make up for first shift
cmp.l #$00007fff,d7 ? small enough for swap
bhi.s fpaxqn branch nope
swap.w d7 shift left 16 bits real fast
sub.b #16,d4 make up for 16 bit shift
fpaxqn add.l d7,d7 shift up one bit
dbmi d4,fpaxqn decrement and branch if positive
eor.b d4,d5 ? same sign
bmi.s fpazro branch underflow to zero
move.b d4,d7 restore sign/exponent
beq.s fpazro return zero if exponent underflowed
rts return to caller
* exponent underflowed - return zero
fpazro moveq.l #0,d7 create a true zero
rts return to caller
* arg1 > arg2
fpatlt cmp.b #-24,d5 ? arg1 >> arg2
ble.s fpart1 return it if so
neg.b d5 absolutize difference
move.l d7,d3 move arg2 as lower value
move.l d6,d7 set up arg1 as high
move.b #$80,d7 setup rounding bit
bra.s fpamss perform the addition
* equal magnitudes
fpaeq move.b d7,d5 save arg1 sign
exg.l d5,d4 swap arg2 with arg1 s+exp
move.b d6,d7 insure same low byte
sub.l d6,d7 obtain difference
beq.s fpazro return zero if identical
bpl.s fpanor branch if arg2 bigger
neg.l d7 correct difference to positive
move.b d5,d4 use arg2's sign + exponent
bra.s fpanrm and go normalize
end

View File

@@ -0,0 +1,132 @@
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

View File

@@ -0,0 +1,83 @@
ttl fast floating point cmp/tst (ffpcmp/ffptst)
***************************************
* (c) copyright 1981 by motorola inc. *
***************************************
*************************************************************
* ffpcmp *
* fast floating point compare *
* *
* input: d6 - fast floating point argument (source) *
* d7 - fast floating point argument (destination) *
* *
* output: condition code reflecting the following branches *
* for the result of comparing the destination *
* minus the source: *
* *
* gt - destination greater *
* ge - destination greater or equal to *
* eq - destination equal *
* ne - destination not equal *
* lt - destination less than *
* le - destination less than or equal to *
* *
* condition codes: *
* n - cleared *
* z - set if result is zero *
* v - cleared *
* c - undefined *
* x - undefined *
* *
* all registers transparent *
* *
*************************************************************
page
ffpcmp idnt 1,1 ffp cmp/tst
xdef ffpcmp fast floating point compare
xref ffpcpyrt copyright notice
section 9
***********************
* compare entry point *
***********************
ffpcmp cmp.b d6,d7 compare sign and exponent only first
bne.s ffpcrtn return if that is sufficient
cmp.l d6,d7 no, compare full longwords then
ffpcrtn rts and return to the caller
page
*************************************************************
* ffptst *
* fast floating point test *
* *
* input: d7 - fast floating point argument *
* *
* output: condition codes set for the following branches: *
* *
* eq - argument equals zero *
* ne - argument not equal zero *
* pl - argument is positive (includes zero)*
* mi - argument is negative *
* *
* condition codes: *
* n - set if result is negative *
* z - set if result is zero *
* v - cleared *
* c - undefined *
* x - undefined *
* *
* all registers transparent *
* *
*************************************************************
page
xdef ffptst fast floating point test
********************
* test entry point *
********************
ffptst tst.b d7 return tested condition code
rts to caller
end

View File

@@ -0,0 +1,29 @@
ttl mc68343 fast floating point copyright notice (ffpcpyrt)
ffpcpyrt idnt 1,1 ffp copyright notice
*************************************
* ffp library copyright notice stub *
* *
* this module is included by all *
* link edits with the ffplib.ro *
* library to protect motorola's *
* copyright status. *
* *
* code: 67 bytes *
* *
* note: this module must reside *
* last in the library as it is *
* referenced by all other mc68343 *
* modules. *
*************************************
section 9
xdef ffpcpyrt
ffpcpyrt equ *
dc.b 'mc68343 floating point firmware '
dc.b '(c) copyright 1981 by motorola inc.'
end

View File

@@ -0,0 +1,166 @@
ttl fast floating point divide (ffpdiv)
*****************************************
* (c) copyright 1980 by motorola inc. *
*****************************************
********************************************
* ffpdiv subroutine *
* *
* input: *
* d6 - floating point divisor *
* d7 - floating point dividend *
* *
* output: *
* d7 - floating point quotient *
* *
* condition codes: *
* n - set if result negative *
* z - set if result zero *
* v - set if result overflowed *
* c - undefined *
* x - undefined *
* *
* registers d3 thru d5 volatile *
* *
* code: 150 bytes stack work: 0 bytes *
* *
* notes: *
* 1) divisor is unaltered (d6). *
* 2) underflows return zero without *
* any indicators set. *
* 3) overflows return the highest value *
* with the proper sign and the 'v' *
* bit set in the ccr. *
* 4) if a divide by zero is attempted *
* the divide by zero exception trap *
* is forced by this code with the *
* original arguments intact. if the *
* exception returns with the denom- *
* inator altered the divide operation *
* continues, otherwise an overflow *
* is forced with the proper sign. *
* the floating divide by zero can be *
* distinguished from true zero divide *
* by the fact that it is an immediate *
* zero dividing into register d7. *
* *
* time: (8 mhz no wait states assumed) *
* dividend zero 5.250 microseconds *
* minimum time others 72.750 microseconds *
* maximum time others 85.000 microseconds *
* average others 76.687 microseconds *
* *
********************************************
page
ffpdiv idnt 1,1 ffp divide
xdef ffpdiv entry point
xref ffpcpyrt copyright notice
section 9
* divide by zero exit
fpddzr divu.w #0,d7 **force divide by zero **
* if the exception returns with altered denominator - continue divide
tst.l d6 ? exception alter the zero
bne.s ffpdiv branch if so to continue
* setup maximum number for divide overflow
fpdovf or.l #$ffffff7f,d7 maximize with proper sign
tst.b d7 set condition code for sign
* or.w #$02,ccr set overflow bit
dc.l $003c0002 ******sick assembler******
fpdrtn rts return to caller
* over or underflow detected
fpdov2 swap.w d6 restore arg1
swap.w d7 restore arg2 for sign
fpdovfs eor.b d6,d7 setup correct sign
bra.s fpdovf and enter overflow handling
fpdouf bmi.s fpdovfs branch if overflow
fpdund move.l #0,d7 underflow to zero
rts and return to caller
***************
* entry point *
***************
* first subtract exponents
ffpdiv move.b d6,d5 copy arg1 (divisor)
beq.s fpddzr branch if divide by zero
move.l d7,d4 copy arg2 (dividend)
beq.s fpdrtn return zero if dividend zero
moveq #-128,d3 setup sign mask
add.w d5,d5 isolate arg1 sign from exponent
add.w d4,d4 isolate arg2 sign from exponent
eor.b d3,d5 adjust arg1 exponent to binary
eor.b d3,d4 adjust arg2 exponent to binary
sub.b d5,d4 subtract exponents
bvs.s fpdouf branch if overflow/underflow
clr.b d7 clear arg2 s+exp
swap.w d7 prepare high 16 bit compare
swap.w d6 against arg1 and arg2
cmp.w d6,d7 ? check if overflow will occur
bmi.s fpdnov branch if not
* adjust for fixed point divide overflow
add.b #2,d4 adjust exponent up one
bvs.s fpdov2 branch overflow here
ror.l #1,d7 shift down by power of two
fpdnov swap.w d7 correct arg2
move.b d3,d5 move $80 into d5.b
eor.w d5,d4 create sign and absolutize exponent
lsr.w #1,d4 d4.b now has sign+exponent of result
* now divide just using 16 bits into 24
move.l d7,d3 copy arg1 for initial divide
divu.w d6,d3 obtain test quotient
move.w d3,d5 save test quotient
* now multiply 16-bit divide result times full 24 bit divisor and compare
* with the dividend. multiplying back out with the full 24-bits allows
* us to see if the result was too large due to the 8 missing divisor bits
* used in the hardware divide. the result can only be too large by 1 unit.
mulu.w d6,d3 high divisor x quotient
sub.l d3,d7 d7=partial subtraction
swap.w d7 to low divisor
swap.w d6 rebuild arg1 to normal
move.w d6,d3 setup arg1 for product
clr.b d3 zero low byte
mulu.w d5,d3 find remaining product
sub.l d3,d7 now have full subtraction
bcc.s fpdqok branch first 16 bits correct
* estimate too high, decrement quotient by one
move.l d6,d3 rebuild divisor
clr.b d3 reverse halves
add.l d3,d7 add another divisor
sub.w #1,d5 decrement quotient
* compute last 8 bits with another divide. the exact remainder from the
* multiply and compare above is divided again by a 16-bit only divisor.
* however, this time we require only 9 bits of accuracy in the result
* (8 to make 24 bits total and 1 extra bit for rounding purposes) and this
* divide always returns a precision of at least 9 bits.
fpdqok move.l d6,d3 copy arg1 again
swap.w d3 first 16 bits divisor in d3.w
clr.w d7 into first 16 bits of dividend
divu.w d3,d7 obtain final 16 bit result
swap.w d5 first 16 quotient to high half
bmi.s fpdisn branch if normalized
* rare occurrance - unnormalized
* happends when mantissa arg1 < arg2 and they differ only in last 8 bits
move.w d7,d5 insert low word of quotient
add.l d5,d5 shift mantissa left one
sub.b #1,d4 adjust exponent down (cannot zero)
move.w d5,d7 cancel next instruction
* rebuild our final result and return
fpdisn move.w d7,d5 append next 16 bits
add.l #$80,d5 round to 24 bits (cannot overflow)
move.l d5,d7 return in d7
move.b d4,d7 finish result with sign+exponent
beq.s fpdund underflow if zero exponent
rts return result to caller
end

View File

@@ -0,0 +1,203 @@
ttl fast floating point exponent (ffpexp)
***************************************
* (c) copyright 1981 by motorola inc. *
***************************************
*************************************************
* ffpexp *
* fast floating point exponent *
* *
* input: d7 - input argument *
* *
* output: d7 - exponential result *
* *
* all other registers are transparent *
* *
* code size: 256 bytes stack work: 34 bytes *
* *
* condition codes: *
* z - set if result in d7 is zero *
* n - cleared *
* v - set if overlow occurred *
* c - undefined *
* x - undefined *
* *
* *
* notes: *
* 1) an overflow returns the largest *
* magnitude number. *
* 2) spot checks show at least 6.8 digit *
* accuracy for all abs(arg) < 30. *
* *
* time: (8mhz no wait states assumed) *
* *
* 488 microseconds *
* *
* logic: 1) find n = int(arg/ln 2). this is *
* added to the mantissa at the end.*
* 3) reduce argument to range by *
* finding arg = mod(arg, ln 2). *
* 4) derive exp(arg) with cordic loop.*
* 5) add n to exponent giving result. *
* *
*************************************************
page
ffpexp idnt 1,2 ffp exp
opt pcs
section 9
xdef ffpexp entry point
xref ffphthet hypertangent table
xref ffpmul2,ffpsub arithmetic primitives
xref ffptnorm transcendental normalize routine
xref ffpcpyrt copyright stub
ln2 equ $b1721840 ln 2 (base e) .693147180
ln2inv equ $b8aa3b41 inverse of ln 2 (base e) 1.44269504
cnjkhinv equ $9a8f4441 floating conjugate of k inverse
* corrected for the extra convergence
* during shifts for 4 and 13
kfctseed equ $26a3d100 k cordic seed
* overflow - return zero or highest value and "v" bit
fpeovflw move.w (sp)+,d6 load sign word and work off stack
tst.b d6 ? was argument negative
bpl.s fpovnzro no, continue
move.l #0,d7 return a zero
bra.s fpovrtn as result is too small
fpovnzro move.l #-1,d7 set all zeroes
lsr.b #1,d7 zero sign bit
* or.b #$02,ccr set overflow bit
dc.l $003c0002 ***assembler error***
fpovrtn movem.l (sp)+,d1-d6/a0 restore registers
rts return to caller
* return one for zero argument
ffpe1 move.l #$80000041,d7 return a true one
lea 7*4+2(sp),sp ignore stack saves
tst.b d7 set condition code properly
rts return to caller
**************
* exp entry *
**************
* save work registers and insure positive argument
ffpexp movem.l d1-d6/a0,-(sp) save all work registers
move.w d7,-(sp) save sign in low order byte for later
beq.s ffpe1 return a true one for zero exponent
and.b #$7f,d7 take absolute value
* divide by log 2 base e for partial result
fpepos move.l d7,d2 save original argument
move.l #ln2inv,d6 load inverse to multiply (faster)
jsr ffpmul2 obtain division thru multiply
bvs fpeovflw branch if too large
* convert quotient to both fixed and float integer
move.b d7,d5 copy exponent over
move.b d7,d6 copy exponent over
sub.b #64+32,d5 find non-fractional precision
neg.b d5 make positive
cmp.b #24,d5 ? insure not too large
ble.s fpeovflw branch too large
cmp.b #32,d5 ? test upper range
bge.s fpesml branch less than one
lsr.l d5,d7 shift to integer
move.b d7,(sp) place adjusted exponent with sign byte
lsl.l d5,d7 back to normal without fraction
move.b d6,d7 re-insert sign+exponent
move.l #ln2,d6 multiply by ln2 to find residue
jsr ffpmul2 multiply back out
move.l d7,d6 setup to subtract multiple of ln 2
move.l d2,d7 move argument in
jsr ffpsub find remainder of ln 2 divide
move.l d7,d2 copy float argument
bra.s fpeadj adjust to fixed
* multiple less than one
fpesml clr.b (sp) default initial multiply to zero
move.l d2,d7 back to original argument
* convert argument to binary(31,29) precision
fpeadj clr.b d7 clear sign and exponent
sub.b #64+3,d2 obtain shift value
neg.b d2 for 2 non-fraction bits
cmp.b #31,d2 insure not too small
bls.s fpeshf branch to shift if ok
move.l #0,d7 force to zero
fpeshf lsr.l d2,d7 convert to fixed point
*****************************************
* cordic calculation registers: *
* d1 - loop count a0 - table pointer *
* d2 - shift count *
* d3 - y' d5 - y *
* d4 - x' d6 - x *
* d7 - test argument *
*****************************************
* input within range, now start cordic setup
fpecom move.l #0,d5 y=0
move.l #kfctseed,d6 x=1 with jkhinverse factored out
lea ffphthet,a0 point to hperbolic tangent table
move.l #0,d2 prime shift counter
* perform cordic loop repeating shifts 4 and 13 to guarantee convergence
* (ref. "a unified algorithm for elementary functions" j.s.walther
* pg. 380 spring joint computer conference 1971)
move.l #3,d1 do shifts 1 thru 4
bsr.s cordic first cordic loops
sub.l #4,a0 redo table entry
sub.w #1,d2 redo shift count
move.l #9,d1 do four through 13
bsr.s cordic second cordic loops
sub.l #4,a0 back to entry 13
sub.w #1,d2 redo shift for 13
move.l #10,d1 now 13 through 23
bsr.s cordic and finish up
* now finalize the result
tst.b 1(sp) test original sign
bpl.s fsepos branch positive argument
neg.l d5 change y for subtraction
neg.b (sp) negate adjusted exponent to subtract
fsepos add.l d5,d6 add or subtract y to/from x
jsr ffptnorm float x
move.l d6,d7 setup result
* add ln2 factor integer to the exponent
add.b (sp),d7 add to exponent
bmi fpeovflw branch if too large
beq fpeovflw branch if too small
add.l #2,sp rid work data off stack
movem.l (sp)+,d1-d6/a0 restore registers
rts return to caller
*************************
* cordic loop subroutine*
*************************
cordic add.w #1,d2 increment shift count
move.l d5,d3 copy y
move.l d6,d4 copy x
asr.l d2,d3 shift for y'
asr.l d2,d4 shift for x'
tst.l d7 test arg value
bmi.s febmi branch minus test
add.l d4,d5 y=y+x'
add.l d3,d6 x=x+y'
sub.l (a0)+,d7 arg=arg-table(n)
dbra d1,cordic loop until done
rts return
febmi sub.l d4,d5 y=y-x'
sub.l d3,d6 x=x-y'
add.l (a0)+,d7 arg=arg+table(n)
dbra d1,cordic loop until done
rts return
end

View File

@@ -0,0 +1,48 @@
ttl fast floating point cordic hyperbolic table (ffphthet)
ffphthet idnt 1,1 ffp inverse hyperbolic table
***************************************
* (c) copyright 1981 by motorola inc. *
***************************************
section 9
xdef ffphthet external definition
*********************************************************
* inverse hyperbolic tangent table for cordic *
* *
* the following table is used during cordic *
* transcendental evaluations for log and exp. it has *
* inverse hyperbolic tangent for 2**-n where n ranges *
* from 1 to 24. the format is binary(31,29) *
* precision (i.e. the binary point is assumed between *
* bits 27 and 28 with three leading non-fraction bits.) *
*********************************************************
ffphthet dc.l $1193ea7a $8c9f53d0>>3 harctan(2**-1) .549306144
dc.l $4162bbe8>>3 harctan(2**-2) .255412812
dc.l $202b1238>>3 harctan(2**-3)
dc.l $10055888>>3 harctan(2**-4)
dc.l $0800aac0>>3 harctan(2**-5)
dc.l $04001550>>3 harctan(2**-6)
dc.l $020002a8>>3 harctan(2**-7)
dc.l $01000050>>3 harctan(2**-8)
dc.l $00800008>>3 harctan(2**-9)
dc.l $00400000>>3 harctan(2**-10)
dc.l $00200000>>3 harctan(2**-11)
dc.l $00100000>>3 harctan(2**-12)
dc.l $00080000>>3 harctan(2**-13)
dc.l $00040000>>3 harctan(2**-14)
dc.l $00020000>>3 harctan(2**-15)
dc.l $00010000>>3 harctan(2**-16)
dc.l $00008000>>3 harctan(2**-17)
dc.l $00004000>>3 harctan(2**-18)
dc.l $00002000>>3 harctan(2**-19)
dc.l $00001000>>3 harctan(2**-20)
dc.l $00000800>>3 harctan(2**-21)
dc.l $00000400>>3 harctan(2**-22)
dc.l $00000200>>3 harctan(2**-23)
dc.l $00000100>>3 harctan(2**-24)
end

View File

@@ -0,0 +1,220 @@
ttl ffpieee conversions to/from ffp (ffptieee,ffpfieee)
******************************************
* (c) copyright 1981 by motorola inc. *
******************************************
****************************************************
* ffptieee and ffpfieee subroutines *
* *
* this module contains single-precision *
* conversion routines for ieee format floating *
* point (draft 8.0) to and from motorola fast *
* floating point (ffp) values. *
* these can be used when large groups of numbers *
* need to be converted between formats. see *
* the mc68344 user's guide for a fuller *
* explanation of the various methods for ieee *
* format support. *
* *
* the fast floating point (non-ieee format) *
* provides results as precise as those required *
* by the ieee specification. however, this *
* format has some minor differences: *
* 1) if the true result of an operation *
* is exactly between representable *
* values, the ffp round-to-nearest *
* function may round to either even or odd. *
* 2) the ffp exponent allows half of the range *
* that the single-precision ieee format *
* provides (approx. 10 to the +-19 decimal). *
* 3) the ieee format specifies infinity, *
* not-a-number, and denormalized data *
* types that are not directly supported *
* by the ffp format. however, they may be *
* added via customizing or used via the ieee *
* format equivalent compatible calls *
* described in the mc68344 user's guide. *
* 4) all zeroes are considered positive *
* in ffp format. *
* 5) the slightly higher precision multiply *
* routine "ffpmul2" should be substituted *
* for the default routine "ffpmul" for *
* completely equivalent precision. *
* *
****************************************************
page
ffpieee idnt 1,1 ffp conversions to/from ieee format
section 9
xdef ffptieee,ffpfieee
****************************************************
* ffptieee *
* *
* fast floating point to ieee format *
* *
* input: d7 - fast floating point value *
* *
* output: d7 - ieee format floating point value *
* *
* condition codes: *
* n - set if the result is negative *
* z - set if the result is zero *
* v - undefined *
* c - undefined *
* x - undefined *
* *
* notes: *
* 1) no work storage or registers required. *
* 2) all zeroes will be converted positive. *
* 3) no not-a-number, inifinity, denormalized, *
* or indefinites generated. (unless *
* user customized.) *
* *
* times (assuming in-line code): *
* value zero 18 cycles *
* value not zero 66 cycles *
* *
****************************************************
ffptieee equ *
add.l d7,d7 delete mantissa high bit
beq.s done1 branch zero as finished
eor.b #$80,d7 to twos complement exponent
asr.b #1,d7 form 8-bit exponent
sub.b #$82,d7 adjust 64 to 127 and excessize
swap.w d7 swap for high byte placement
rol.l #7,d7 set sign+exp in high byte
done1 equ *
rts return to caller
page
************************************************************
* ffpfieee *
* fast floating point from ieee format *
* *
* input: d7 - ieee format floating point value *
* output: d7 - ffp format floating point value *
* *
* condition codes: *
* n - undefined *
* z - set if the result is zero *
* v - set if result overflowed ffp format *
* c - undefined *
* x - undefined *
* *
* notes: *
* 1) register d5 is used for work storage and not *
* transparent. *
* 2) not-a-number, inifinity, and denormalized *
* types as well as an exponent outside of ffp range *
* generate a branch to a specific part of the *
* routine. customizing may easily be done there. *
* *
* the default actions for the various types are: *
* label type default substitution *
* ----- ---- -------------------- *
* nan not-a-number zero *
* inf infinity largest ffp value same sign *
* ("v" set in ccr) *
* denor denormalized zero *
* exphi exp too large largest ffp value same sign *
* ("v" set in ccr) *
* explo exp too small zero *
* *
* times (assuming in-line code): *
* value zero 78 cycles *
* value not zero 72 cycles *
* *
************************************************************
vbit equ $02 condition code register "v" bit mask
ffpfieee equ *
swap.w d7 swap word halves
ror.l #7,d7 exponent to low byte
move.l #-128,d5 load $80 mask in work register
eor.b d5,d7 convert from excess 127 to two's-complement
add.b d7,d7 from 8 to 7 bit exponent
bvs.s ffpovf branch will not fit
add.b #2<<1+1,d7 adjust excess 127 to 64 and set mantissa high bit
bvs.s exphi branch exponent too large (overflow)
eor.b d5,d7 back to excess 64
ror.l #1,d7 to fast float representation ("v" cleared)
done2 equ *
rts return to caller
page
* overflow detected - caused by one of the following:
* - false overflow due to difference between excess 127 and 64 format
* - exponent too high or low to fit in 7 bits (exponent over/underflow)
* - an exponent of $ff representing an infinity
* - an exponent of $00 representing a zero, nan, or denormalized value
ffpovf bcc.s ffpovlw branch if overflow (exponent $ff or too large)
* overflow - check for possible false overflow due to different excess formats
cmp.b #$7c,d7 ? was original argument really in range
beq.s ffpovfls yes, branch false overflow
cmp.b #$7e,d7 ? was original argument really in range
bne.s ffptovf no, branch true overflow
ffpovfls add.b #$80+2<<1+1,d7 excess 64 adjustment and mantissa high bit
ror.l #1,d7 finalize to fast floating point format
tst.b d7 insure no illegal zero sign+exponent byte
bne.s done2 done if does not set s+exp all zeroes
bra.s explo treat as underflowed exponent otherwise
* exponent low - check for zero, denormalized value, or too small an exponent
ffptovf and.w #$feff,d7 clear sign bit out
tst.l d7 ? entire value now zero
beq.s done2 branch if value is zero
tst.b d7 ? denormalized number (significant#0, exp=0)
beq.s denor branch if denormalized
***************
*****explo - exponent to small for ffp format
***************
* the sign bit will be bit 8.
explo move.l #0,d7 default zero for this case ("v" cleared)
bra.s done2 return to mainline
***************
*****denor - denormalized number
***************
denor move.l #0,d7 default is to return a zero ("v" cleared)
bra.s done2 return to mainline
* exponent high - check for exponent too high, infinity, or nan
ffpovlw cmp.b #$fe,d7 ? was original exponent $ff
bne.s exphi no, branch exponent too large
lsr.l #8,d7 shift out exponent
lsr.l #1,d7 shift out sign
bne.s nan branch not-a-number
***************
*****inf - infinity
***************
* the carry and x bit represent the sign
inf move.l #-1,d7 setup maximum ffp value
roxr.b #1,d7 shift in sign
or.b #vbit,ccr show overflow occured [clh] was sr
bra.s done2 return with maximum same sign to mainline
***************
*****exphi - exponent to large for ffp format
***************
* the sign bit will be bit 8.
exphi lsl.w #8,d7 set x bit to sign
move.l #-1,d7 setup maximum number
roxr.b #1,d7 shift in sign
or.b #vbit,ccr show overflow ocurred [vlh] was sr
bra.s done2 return maximum same sign to mainline
***************
*****nan - not-a-number
***************
* bits 0 thru 22 contain the nan data field
nan move.l #0,d7 default to a zero ("v" bit cleared)
bra.s done2 return to mainline
end

View File

@@ -0,0 +1,161 @@
ttl fast floating point log (ffplog)
***************************************
* (c) copyright 1981 by motorola inc. *
***************************************
*************************************************
* ffplog *
* fast floating point logorithm *
* *
* input: d7 - input argument *
* *
* output: d7 - logorithmic result to base e *
* *
* all other registers totally transparent *
* *
* code size: 184 bytes stack work: 38 bytes *
* *
* condition codes: *
* z - set if the result is zero *
* n - set if result in is negative *
* v - set if invalid negative argument *
* or zero argument *
* c - undefined *
* x - undefined *
* *
* *
* notes: *
* 1) spot checks show errors bounded by *
* 5 x 10**-8. *
* 2) negative arguments are illegal and cause*
* the "v" bit to be set and the absolute *
* value used instead. *
* 3) a zero argument returns the largest *
* negative value possible with the "v" bit*
* set. *
* *
* time: (8mhz no wait states assumed) *
* *
* times are very data sensitive with *
* samples ranging from 170 to 556 *
* microseconds *
* *
*************************************************
page
ffplog idnt 1,2 ffp log
opt pcs
section 9
xdef ffplog entry point
xref ffphthet hypertangent table
xref ffpadd,ffpdiv,ffpsub,ffpmul2 arithmetic primitives
xref ffptnorm transcendental normalize routine
xref ffpcpyrt copyright stub
fpone equ $80000041 floating value for one
log2 equ $b1721840 log(2) = .6931471805
**************
* log entry *
**************
* insure argument positive
ffplog tst.b d7 ? test sign
beq.s fplzro branch argument zero
bpl.s fplok branch alright
* argument is negative - use the absolute value and set the "v" bit
and.b #$7f,d7 take absolute value
bsr.s fplok find log(abs(x))
*psetv or.b #$02,ccr set overflow bit
fpsetv dc.l $003c0002 ***assembler error***
rts return to caller
* argument is zero - return largest negative number with "v" bit
fplzro move.l #-1,d7 return largest negative
jmp fpsetv return with "v" bit set
* save work registers and strip exponent off
fplok movem.l d1-d6/a0,-(sp) save all work registers
move.b d7,-(sp) save original exponent
move.b #64+1,d7 force between 1 and 2
move.l #fpone,d6 load up a one
move.l d7,d2 copy argument
jsr ffpadd create arg+1
exg.l d7,d2 swap result with argument
jsr ffpsub create arg-1
move.l d2,d6 prepare for divide
jsr ffpdiv result is (arg-1)/(arg+1)
beq.s fplnocr zero so cordic not needed
* convert to bin(31,29) precision
sub.b #64+3,d7 adjust exponent
neg.b d7 for shift necessary
cmp.b #31,d7 ? insure not too small
bls.s fplshf no, go shift
move.l #0,d7 force to zero
fplshf 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 ffphthet,a0 to inverse hyperbolic tangent table
move.l #22,d1 loop 23 times
move.l #1,d2 prime shift counter
bra.s cordic enter cordic loop
* cordic loop
fplpls asr.l d2,d4 shift(x')
sub.l d4,d5 y = y - x'
add.l (a0),d6 z = z + hypertan(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 add exponent*log(2) for final result
move.l #0,d7 default zero if too small
jsr ffptnorm float z
beq.s fplnocr branch if too small
add.b #1,d6 times two
move.l d6,d7 setup in d7 in case exp=0
fplnocr move.l d7,d2 save result
move.l #0,d6 prepare original exponent load
move.b (sp)+,d6 load it back
sub.b #64+1,d6 convert exponent to binary
beq.s fplzpr branch zero partial here
move.b d6,d1 save sign byte
bpl.s fplpos branch positive value
neg.b d6 force positive
fplpos ror.l #8,d6 prepare to convert to integer
move.l #$47,d5 setup exponent mask
fplnorm add.l d6,d6 shift to left
dbmi d5,fplnorm exp-1 and branch if not normalized
move.b d5,d6 fix in exponent
and.b #$80,d1 extract sign
or.b d1,d6 insert sign in
move.l #log2,d7 multiply exponent by log(2)
jsr ffpmul2 multiply d6 and d7
move.l d2,d6 now add cordic result
jsr ffpadd for final answer
fplzpr movem.l (sp)+,d1-d6/a0 restore registers
rts return to caller
end

View File

@@ -0,0 +1,132 @@
ttl fast floating point precise multiply (ffpmul2)
*******************************************
* (c) copyright 1980 by motorola inc. *
*******************************************
********************************************
* ffpmul2 subroutine *
* *
* this module is the second of the *
* multiply routines. it is 18% slower *
* but provides the highest accuracy *
* possible. the error is exactly .5 *
* least significant bit versus an error *
* in the high-speed default routine of *
* .50390625 least significant bit due *
* to truncation. *
* *
* input: *
* d6 - floating point multiplier *
* d7 - floating point multiplican *
* *
* output: *
* d7 - floating point result *
* *
* registers d3 thru d5 are volatile *
* *
* condition codes: *
* n - set if result negative *
* z - set if result is zero *
* v - set if overflow occurred *
* c - undefined *
* x - undefined *
* *
* code: 134 bytes stack work: 0 bytes *
* *
* notes: *
* 1) multipier unaltered (d6). *
* 2) underflows return zero with no *
* indicator set. *
* 3) overflows will return the maximum *
* value with the proper sign and the *
* 'v' bit set in the ccr. *
* *
* times: (8mhz no wait states assumed) *
* arg1 zero 5.750 microseconds *
* arg2 zero 3.750 microseconds *
* minimum time others 45.750 microseconds *
* maximum time others 61.500 microseconds *
* average others 52.875 microseconds *
* *
********************************************
page
ffpmul2 idnt 1,1 ffp high-precision multiply
xdef ffpmul2 entry point
xref ffpcpyrt copyright notice
section 9
* ffpmul2 subroutine entry point
ffpmul2 move.b d7,d5 prepare sign/exponent work 4
beq.s ffmrtn return if result already zero 8/10
move.b d6,d4 copy arg1 sign/exponent 4
beq.s ffmrt0 return zero if arg1=0 8/10
add.w d5,d5 shift left by one 4
add.w d4,d4 shift left by one 4
moveq #-128,d3 prepare exponent modifier ($80) 4
eor.b d3,d4 adjust arg1 exponent to binary 4
eor.b d3,d5 adjust arg2 exponent to binary 4
add.b d4,d5 add exponents 4
bvs.s ffmouf branch if overflow/underflow 8/10
move.b d3,d4 overlay $80 constant into d4 4
eor.w d4,d5 d5 now has sign and exponent 4
ror.w #1,d5 move to low 8 bits 8
swap.w d5 save final s+exp in high word 4
move.w d6,d5 copy arg1 low byte 4
clr.b d7 clear s+exp out of arg2 4
clr.b d5 clear s+exp out of arg1 low byte 4
move.w d5,d4 prepare arg1lowb for multiply 4
mulu.w d7,d4 d4 = arg2lowb x arg1lowb 38-54 (46)
swap.w d4 place result in low word 4
move.l d7,d3 copy arg2 4
swap.w d3 to arg2highw 4
mulu.w d5,d3 d3 = arg1lowb x arg2highw 38-54 (46)
add.l d3,d4 d4 = partial product (no carry) 8
swap.w d6 to arg1 high two bytes 4
move.l d6,d3 copy arg1highw over 4
mulu.w d7,d3 d3 = arg2lowb x arg1highw 38-54 (46)
add.l d3,d4 d4 = partial product 8
clr.w d4 clear low end runoff 4
addx.b d4,d4 shift in carry if any 4
swap.w d4 put carry into high word 4
swap.w d7 now top of arg2 4
mulu.w d6,d7 d7 = arg1highw x arg2highw 40-70 (54)
swap.w d6 restore arg1 4
swap.w d5 restore s+exp to low word
add.l d4,d7 add partial products 8
bpl ffmnor branch if must normalize 8/10
add.l #$80,d7 round up (cannot overflow) 16
move.b d5,d7 insert sign and exponent 4
beq.s ffmrt0 return zero if zero exponent 8/10
ffmrtn rts return to caller 16
* must normalize result
ffmnor sub.b #1,d5 bump exponent down by one 4
bvs.s ffmrt0 return zero if underflow 8/10
bcs.s ffmrt0 return zero if sign inverted 8/10
moveq #$40,d4 rounding factor 4
add.l d4,d7 add in rounding factor 8
add.l d7,d7 shift to normalize 8
bcc.s ffmcln return normalized number 8/10
roxr.l #1,d7 rounding forced carry in top bit 10
add.b #1,d5 undo normalize attempt 4
ffmcln move.b d5,d7 insert sign and exponent 4
beq.s ffmrt0 return zero if exponent zero 8/10
rts return to caller 16
* arg1 zero
ffmrt0 move.l #0,d7 return zero 4
rts return to caller 16
* overflow or underflow exponent
ffmouf bpl.s ffmrt0 branch if underflow to give zero 8/10
eor.b d6,d7 calculate proper sign 4
or.l #$ffffff7f,d7 force highest value possible 16
tst.b d7 set sign in return code
* ori.b #$02,ccr set overflow bit
dc.l $003c0002 ****sick assembler**** 20
rts return to caller 16
end

View File

@@ -0,0 +1,80 @@
ttl fast floating point power (ffppwr)
***************************************
* (c) copyright 1981 by motorola inc. *
***************************************
*************************************************
* ffppwr *
* fast floating point power function *
* *
* input: d6 - floating point exponent value *
* d7 - floating point argument value *
* *
* output: d7 - result of the value taken to *
* the power specified *
* *
* all registers but d7 are transparent *
* *
* code size: 36 bytes stack work: 42 bytes *
* *
* calls subroutines: ffplog, ffpexp and ffpmul2 *
* *
* condition codes: *
* z - set if the result is zero *
* n - cleared *
* v - set if overflow occurred or base *
* value argument was negative *
* c - undefined *
* x - undefined *
* *
* notes: *
* 1) a negative base value will force the use*
* if its absolute value. the "v" bit will*
* be set upon function return. *
* 2) if the result overflows then the *
* maximum size value is returned with the *
* "v" bit set in the condition code. *
* 3) spot checks show at least six digit *
* precision for 80 percent of the cases. *
* *
* time: (8mhz no wait states assumed) *
* *
* the timing is very data sensitive with *
* test samples ranging from 720 to *
* 1206 microseconds *
* *
*************************************************
page
ffppwr idnt 1,1 ffp power
opt pcs
section 9
xdef ffppwr entry point
xref ffplog,ffpexp exponent and log functions
xref ffpmul2 multiply function
xref ffpcpyrt copyright stub
*****************
* power entry *
*****************
* take the logorithm of the base value
ffppwr tst.b d7 ? negative base value
bpl.s fpppos branch positive
and.b #$7f,d7 take absolute value
bsr.s fpppos find result using that
* or.b #$02,ccr force "v" bit on for negative argument
dc.l $003c0002 *****assembler error*****
rts return to caller
fpppos jsr ffplog find log of the number to be used
movem.l d3-d5,-(sp) save multiply work registers
jsr ffpmul2 multiply by the exponent
movem.l (sp)+,d3-d5 restore multiply work registers
* if overflowed, ffpexp will set "v" bit and return desired result anyway
jmp ffpexp result is exponent
end

View File

@@ -0,0 +1,283 @@
ttl ffp sine cosine tangent (ffpsin/ffpcos/ffptan/ffpsincs)
***************************************
* (c) copyright 1981 by motorola inc. *
***************************************
*************************************************
* ffpsin ffpcos ffptan ffpsincs *
* fast floating point sine/cosine/tangent *
* *
* input: d7 - input argument (radian) *
* *
* output: d7 - function result *
* (ffpsincs also returns d6) *
* *
* all other registers totally transparent *
* *
* code size: 334 bytes stack work: 38 bytes *
* *
* condition codes: *
* z - set if result in d7 is zero *
* n - set if result in d7 is negative *
* c - undefined *
* v - set if result is meaningless *
* (input magnitude too large) *
* x - undefined *
* *
* functions: *
* ffpsin - sine result *
* ffpcos - cosine result *
* ffptan - tangent result *
* ffpsincs - both sine and cosine *
* d6 - sin, d7 - cosine *
* *
* notes: *
* 1) input values are in radians. *
* 2) function ffpsincs returns both sine *
* and cosine twice as fast as calculating *
* the two functions independently for *
* the same value. this is handy for *
* graphics processing. *
* 2) input arguments larger than two pi *
* suffer reduced precision. the larger *
* the argument, the smaller the precision.*
* excessively large arguments which have *
* less than 5 bits of precision are *
* returned unchanged with the "v" bit set.*
* 3) for tangent angles of infinite value *
* the largest possible positive number *
* is returned ($ffffff7f). this still *
* gives results well within single *
* precision calculation. *
* 4) spot checks show errors bounded by *
* 4 x 10**-7 but for arguments close to *
* pi/2 intervals where 10**-5 is seen. *
* *
* time: (8mhz no wait states and argument *
* assumed within +-pi) *
* *
* ffpsin 413 microseconds *
* ffpcos 409 microseconds *
* ffptan 501 microseconds *
* ffpsincs 420 microseconds *
*************************************************
page
ffpsin idnt 1,2 ffp sine cosine tangent
opt pcs
section 9
xdef ffpsin,ffpcos,ffptan,ffpsincs entry points
xref ffptheta inverse tangent table
xref ffpmul2,ffpdiv,ffpsub multiply, divide and subtract
xref ffptnorm transcendental normalize routine
xref ffpcpyrt copyright stub
pi equ $c90fdb42 floating constant pi
fixedpi equ $c90fdaa2 pi skeleton to 32 bits precision
inv2pi equ $a2f9833e inverse of two-pi
kinv equ $9b74ee40 floating k inverse
nkfact equ $ec916240 negative k inverse
********************************************
* entry for returning both sine and cosine *
********************************************
ffpsincs move.w #-2,-(sp) flag both sine and cosine wanted
bra.s fpscom enter common code
**********************
* tangent entry point*
**********************
ffptan move.w #-1,-(sp) flag tangent with minus value
bra.s fpschl check very small values
**************************
* cosine only entry point*
**************************
ffpcos move.w #1,-(sp) flag cosine with positive value
bra.s fpscom enter common code
* negative sine/tangent small value check
fpschm cmp.b #$80+$40-8,d7 ? less or same as -2**-9
bhi.s fpscom continue if not too small
* return argument
fpsrti add.l #2,sp rid internal parameter
tst.b d7 set condition codes
rts return to caller
************************
* sine only entry point*
************************
ffpsin clr.w -(sp) flag sine with zero
* sine and tangent values < 2**-9 return identities
fpschl tst.b d7 test sign
bmi.s fpschm branch minus
cmp.b #$40-8,d7 ? less or same than 2**-9
bls.s fpsrti return identity
* save registers and insure input within + or - pi range
fpscom movem.l d1-d6/a0,-(sp) save all work registers
move.l d7,d2 copy input over
add.b d7,d7 rid sign bit
cmp.b #(64+5)<<1,d7 ? abs(arg) < 2**6 (32)
bls.s fpsnlr branch yes, not too large
* argument is too large to subtract to within range
cmp.b #(64+20)<<1,d7 ? test excessive size (>2**20)
bls.s fpsgpr no, go ahead and use
* error - argument so large result has no precision
* or.b #$02,ccr force v bit on
dc.l $003c0002 *****assembler error*****
movem.l (sp)+,d1-d6/a0 restore registers
add.l #2,sp clean internal argument off stack
rts return to caller
* we must find mod(arg,twopi) since argument is too large for subtractions
fpsgpr move.l #inv2pi,d6 load up 2*pi inverse constant
move.l d2,d7 copy over input argument
jsr ffpmul2 divide by 2pi (via multiply inverse)
* convert quotient to float integer
move.b d7,d5 copy exponent over
and.b #$7f,d5 rid sign from exponent
sub.b #64+24,d5 find fractional precision
neg.b d5 make positive
move.l #-1,d4 setup mask of all ones
clr.b d4 start zeroes at low byte
lsl.l d5,d4 shift zeroes into fractional part
or.b #$ff,d4 do not remove sign and exponent
and.l d4,d7 strip fractional bits entirely
move.l #pi+1,d6 load up 2*pi constant
jsr ffpmul2 multiply back out
move.l d7,d6 setup to subtract multiple of twopi
move.l d2,d7 move argument in
jsr ffpsub find remainder of twopi divide
move.l d7,d2 use it as new input argument
* convert argument to binary(31,26) precision for reduction within +-pi
fpsnlr move.l #$0c90fdaa,d4 fixedpi>>4 load pi
move.l d2,d7 copy float argument
clr.b d7 clear sign and exponent
tst.b d2 test sign
bmi.s fpsnmi branch negative
sub.b #64+6,d2 obtain shift value
neg.b d2 for 5 bit non-fraction bits
cmp.b #31,d2 ? very small number
bls.s fpssh1 no, go ahead and shift
move.l #0,d7 force to zero
fpssh1 lsr.l d2,d7 convert to fixed point
* force to +pi or below
fpspck cmp.l d4,d7 ? greater than pi
ble.s fpsckm branch not
sub.l d4,d7 subtract
sub.l d4,d7 . twopi
bra.s fpspck and check again
fpsnmi sub.b #$80+64+6,d2 rid sign and get shift value
neg.b d2 for 5 non-fractional bits
cmp.b #31,d2 ? very small number
bls.s fpssh2 no, go ahead and shift
move.l #0,d7 force to zero
fpssh2 lsr.l d2,d7 convert to fixed point
neg.l d7 make negative
neg.l d4 make -pi
* force to -pi or above
fpsnck cmp.l d4,d7 ? less than -pi
bge.s fpsckm branch not
sub.l d4,d7 add
sub.l d4,d7 . twopi
bra.s fpsnck and check again
*****************************************
* cordic calculation registers: *
* d1 - loop count a0 - table pointer *
* d2 - shift count *
* d3 - x' d5 - x *
* d4 - y' d6 - y *
* d7 - test argument *
*****************************************
* input within range, now start cordic setup
fpsckm move.l #0,d5 x=0
move.l #nkfact,d6 y=negative inverse k factor seed
move.l #$3243f6a8,d4 fixedpi>>2, setup fixed pi/2 constant
asl.l #3,d7 now to binary(31,29) precision
bmi.s fpsap2 branch if minus to add pi/2
neg.l d6 y=positive inverse k factor seed
neg.l d4 subtract pi/2 for positive argument
fpsap2 add.l d4,d7 add constant
lea ffptheta,a0 load arctangent table
move.l #23,d1 loop 24 times
move.l #-1,d2 prime shift counter
* cordic loop
fsinlp add.w #1,d2 increment shift count
move.l d5,d3 copy x
move.l d6,d4 copy y
asr.l d2,d3 shift for x'
asr.l d2,d4 shift for y'
tst.l d7 test arg value
bmi.s fsbmi branch minus test
sub.l d4,d5 x=x-y'
add.l d3,d6 y=y+x'
sub.l (a0)+,d7 arg=arg-table(n)
dbra d1,fsinlp loop until done
bra.s fscom enter common code
fsbmi add.l d4,d5 x=x+y'
sub.l d3,d6 y=y-x'
add.l (a0)+,d7 arg=arg+table(n)
dbra d1,fsinlp loop until done
* now split up tangent and ffpsincs from sine and cosine
fscom move.w 7*4(sp),d1 reload internal parameter
bpl.s fssincos branch for sine or cosine
add.b #1,d1 see if was -1 for tangent
bne.s fsdual no, must be both sin and cosine
* tangent finish
bsr.s fsfloat float y (sin)
move.l d6,d7 setup for divide into
move.l d5,d6 prepare x
bsr.s fsfloat float x (cos)
beq.s fstinf branch infinite result
jsr ffpdiv tangent = sin/cos
fsinfrt movem.l (sp)+,d1-d6/a0 restore registers
add.l #2,sp delete internal parameter
rts return to caller
* tangent is infinite. return maximum positive number.
fstinf move.l #$ffffff7f,d7 largest ffp number
bra.s fsinfrt and clean up
* sine and cosine
fssincos beq.s fssine branch if sine
move.l d5,d6 use x for cosine
fssine bsr.s fsfloat convert to float
move.l d6,d7 return result
tst.b d7 and condition code test
movem.l (sp)+,d1-d6/a0 restore registers
add.l #2,sp delete internal parameter
rts return to caller
* both sine and cosine
fsdual move.l d5,-(sp) save cosine derivitive
bsr.s fsfloat convert sine derivitive to float
move.l d6,6*4(sp) place sine into saved d6
move.l (sp)+,d6 restore cosine derivitive
bra.s fssine and continue restoring sine on the sly
* fsfloat - float internal precision but truncate to zero if < 2**-21
fsfloat move.l d6,d4 copy internal precision value
bmi.s fsfneg branch negative
cmp.l #$000000ff,d6 ? test magnitude
bhi dobranch ffptnorm normalize if not too small
fsfzro move.l #0,d6 return a zero
rts return to caller
fsfneg asr.l #8,d4 see if all ones bits 8-31
add.l #1,d4 ? goes to zero
bne dobranch ffptnorm normalize if not too small
bra.s fsfzro return zero
dobranch:
jmp ffptnorm for loader problem
end

View File

@@ -0,0 +1,112 @@
ttl fast floating point square root (ffpsqrt)
*******************************************
* (c) copyright 1981 by motorola inc. *
*******************************************
********************************************
* ffpsqrt subroutine *
* *
* input: *
* d7 - floating point argument *
* *
* output: *
* d7 - floating point square root *
* *
* condition codes: *
* *
* n - cleared *
* z - set if result is zero *
* v - set if argument was negative*
* c - cleared *
* x - undefined *
* *
* registers d3 thru d6 are volatile *
* *
* code: 194 bytes stack work: 4 bytes *
* *
* notes: *
* 1) no overflows or underflows can *
* occur. *
* 2) a negative argument causes the *
* absolute value to be used and the *
* "v" bit set to indicate that a *
* negative square root was attempted. *
* *
* times: *
* argument zero 3.50 microseconds *
* minimum time > 0 187.50 microseconds *
* average time > 0 193.75 microseconds *
* maximum time > 0 200.00 microseconds *
********************************************
page
ffpsqrt idnt 1,1 ffp square root
section 9
xdef ffpsqrt entry point
xref ffpcpyrt copyright notice
* negative argument handler
fpsinv and.b #$7f,d7 take absolute value
bsr.s ffpsqrt find sqrt(abs(x))
* or.b $02,ccr set "v" bit
dc.l $003c0002 **assembler error**
rts return to caller
*********************
* square root entry *
*********************
ffpsqrt move.b d7,d3 copy s+exponent over
beq.s fpsrtn return zero if zero argument
bmi.s fpsinv negative, reject with special condition codes
lsr.b #1,d3 divide exponent by two
bcc.s fpseven branch exponent was even
add.b #1,d3 adjust odd values up by one
lsr.l #1,d7 offset odd exponent's mantissa one bit
fpseven add.b #$20,d3 renormalize exponent
swap.w d3 save result s+exp for final move
move.w #23,d3 setup loop for 24 bit generation
lsr.l #7,d7 prepare first test value
move.l d7,d4 d4 - previous value during loop
move.l d7,d5 d5 - new test value during loop
move.l a0,d6 save address register
lea fpstbl(pc),a0 load table address
move.l #$00800000,d7 d7 - initial result (must be a one)
sub.l d7,d4 preset old value in case zero bit next
sub.l #$01200000,d5 combine first loop calculations
bra.s fpsent go enter loop calculations
* square root calculation
* this is an optimized scheme for the recursive square root algorithm:
*
* step n+1:
* test value <= .0 0 0 r r r 0 1 then generate a one in result r
* n 2 1 n 2 1 else a zero in result r n+1
* n+1
* precalculations are done such that the entry is midway into step 2
fpsone bset d3,d7 insert a one into this position
move.l d5,d4 update new test value
fpszero add.l d4,d4 multiply test result by two
move.l d4,d5 copy in case next bit zero
sub.l (a0)+,d5 subtract the '01' ending pattern
sub.l d7,d5 subtract result bits collected so far
fpsent dbmi d3,fpsone branch if a one generated in the result
dbpl d3,fpszero branch if a zero generated
* all 24 bits calculated. now test result of 25th bit
bls.s fpsfin branch next bit zero, no rounding
add.l #1,d7 round up (cannot overflow)
fpsfin lsl.l #8,d7 normalize result
move.l d6,a0 restore address register
swap.w d3 restore s+exp save
move.b d3,d7 move in final sign+exponent
fpsrtn rts return to caller
* table to furnish '01' shifts during the algorithm loop
fpstbl dc.l 1<<20,1<<19,1<<18,1<<17,1<<16,1<<15
dc.l 1<<14,1<<13,1<<12,1<<11,1<<10,1<<9,1<<8
dc.l 1<<7,1<<6,1<<5,1<<4,1<<3,1<<2,1<<1,1<<0
dc.l 0,0
end

View File

@@ -0,0 +1,50 @@
ttl arctangent cordic table - ffptheta
ffptheta idnt 1,1 ffp arctangent table
***************************************
* (c) copyright 1981 by motorola inc. *
***************************************
section 9
xdef ffptheta external definition
*********************************************************
* arctangent table for cordic *
* *
* the following table is used during cordic *
* transcendental evaluations for sine, cosine, and *
* tangent and represents arctangent values 2**-n where *
* n ranges from 0 to 24. the format is binary(31,29) *
* precision (i.e. the binary point is between bits *
* 28 and 27 giving two leading non-fraction bits.) *
*********************************************************
ffptheta dc.l $1921fb54 $c90fdaa2>>3 arctan(2**0)
dc.l $76b19c15>>3 arctan(2**-1)
dc.l $3eb6ebf2>>3 arctan(2**-2)
dc.l $1fd5ba9a>>3 arctan(2**-3)
dc.l $0ffaaddb>>3 arctan(2**-4)
dc.l $07ff556e>>3 arctan(2**-5)
dc.l $03ffeaab>>3 arctan(2**-6)
dc.l $01fffd55>>3 arctan(2**-7)
dc.l $00ffffaa>>3 arctan(2**-8)
dc.l $007ffff5>>3 arctan(2**-9)
dc.l $003ffffe>>3 arctan(2**-10)
dc.l $001fffff>>3 arctan(2**-11)
dc.l $000fffff>>3 arctan(2**-12)
dc.l $0007ffff>>3 arctan(2**-13)
dc.l $0003ffff>>3 arctan(2**-14)
dc.l $0001ffff>>3 arctan(2**-15)
dc.l $0000ffff>>3 arctan(2**-16)
dc.l $00007fff>>3 arctan(2**-17)
dc.l $00003fff>>3 arctan(2**-18)
dc.l $00001fff>>3 arctan(2**-19)
dc.l $00000fff>>3 arctan(2**-20)
dc.l $000007ff>>3 arctan(2**-21)
dc.l $000003ff>>3 arctan(2**-22)
dc.l $000001ff>>3 arctan(2**-23)
dc.l $000000ff>>3 arctan(2**-24)
dc.l $0000007f>>3 arctan(2**-25)
dc.l $0000003f>>3 arctan(2**-26)
end

View File

@@ -0,0 +1,51 @@
ttl ffp transcendental normalize internal routine (ffptnorm)
ffptnorm idnt 1,2 ffp transcendental internal normalize
xdef ffptnorm
section 9
***************************************
* (c) copyright 1981 by motorola inc. *
***************************************
******************************
* ffptnorm *
* normalize bin(29,31) value *
* and convert to float *
* *
* input: d6 - internal fixed *
* output: d6 - ffp float *
* cc - reflect value *
* notes: *
* 1) d4 is destroyed. *
* *
* time: (8mhz no wait state) *
* zero 4.0 microsec. *
* avg else 17.0 microsec. *
* *
******************************
ffptnorm move.l #$42,d4 setup initial exponent
tst.l d6 test for non-negative
beq.s fsfrtn return if zero
bpl.s fsfpls branch is >= 0
neg.l d6 absolutize input
move.b #$c2,d4 setup initial negative exponent
fsfpls cmp.l #$00007fff,d6 test for a small number
bhi.s fsfcont branch if not small
swap.w d6 swap halves
sub.b #16,d4 offset by 16 shifts
fsfcont add.l d6,d6 shift another bit
dbmi d4,fsfcont shift left until normalized
tst.b d6 ? should we round up
bpl.s fsfnrm no, branch rounded
add.l #$100,d6 round up
bcc.s fsfnrm branch no overflow
roxr.l #1,d6 adjust back for bit in 31
add.b #1,d4 make up for last shift right
fsfnrm move.b d4,d6 insert sign+exponent
fsfrtn rts return to caller
end

View File

@@ -0,0 +1,26 @@
/*
Copyright 1983
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
/*char *version "@(#)floor.c 1.2 10/19/83";
/* floor - returns the largest integer (as a double precision
number) not greater than x. */
double
floor(x)
double x;
{
register long i;
double retval;
if ( x < 0 )
x -= 0.99999999999999;
i = x;
retval = i;
return( retval );
}

View File

@@ -0,0 +1,34 @@
/*
Copyright 1983
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
/*char *version "@(#)fmod.c 1.2 10/19/83";
/* fmod - returns the number f such that x = iy + f, and
0 <= f <= y. */
double
fmod(x,y)
double x;
double y;
{
double z;
double retval;
register long i;
double fabs();
double absx;
double absy;
absx = fabs(x);
absy = fabs(y);
for(z = absx; z - absy >= 0. ; z -= absy)
;
i = z;
if( x < 0.0 )
i *= -1;
retval = i;
return( retval );
}

View File

@@ -0,0 +1,26 @@
*
* Floating Point Addition :
* Front End to IEEE Floating Point Package.
*
* double
* fpadd(addend,adder)
* double addend, adder;
*
* Returns : Sum of two floating point numbers
*
.globl fpadd
.globl _fpadd
.globl iefadd
.text
fpadd:
_fpadd:
~~fpadd:
link r14,#-4
movem.l d6-d7,-(sp)
move.l 8(r14),r7
move.l 12(r14),r6
jsr iefadd
move.l r7,r0
movem.l (sp)+,d6-d7
unlk r14
rts

View File

@@ -0,0 +1,25 @@
*
* Floating Point Compare :
* Front End to IEEE Floating Point Package.
*
* fpcmp(source,dest)
* double source, dest;
*
* Returns : Condition codes based on Floating Point Compare
* in the Condition code register
*
.globl fpcmp
.globl _fpcmp
.globl iefcmp
.text
fpcmp:
_fpcmp:
~~fpcmp:
link r14,#-4
movem.l d6-d7,-(sp)
move.l 8(r14),r7
move.l 12(r14),r6
jsr iefcmp
movem.l (sp)+,d6-d7
unlk r14
rts

View File

@@ -0,0 +1,26 @@
*
* Floating Point Cosine :
* Front End to IEEE Floating Point Package.
*
* double
* cos(farg)
* double farg;
*
* Input : in radians
* Returns : cosine of Floating point number
*
.globl cos
.globl _cos
.globl iefcos
.text
cos:
_cos:
~~cos:
link r14,#-4
movem.l d3-d7,-(sp)
move.l 8(r14),r7
jsr iefcos
move.l r7,r0
movem.l (sp)+,d3-d7
unlk r14
rts

View File

@@ -0,0 +1,26 @@
*
* Floating Point Division :
* Front End to IEEE Floating Point Package.
*
* double
* fpdiv(divisor,dividend)
* double divisor, dividend;
*
* Return : Floating Point Quotient
*
.globl fpdiv
.globl _fpdiv
.globl iefdiv
.text
fpdiv:
_fpdiv:
~~fpdiv:
link r14,#-4
movem.l d6-d7,-(sp)
move.l 8(r14),r7
move.l 12(r14),r6
jsr iefdiv
move.l r7,r0
movem.l (sp)+,d6-d7
unlk r14
rts

View File

@@ -0,0 +1,25 @@
*
* Floating Point Exponent :
* Front End to IEEE Floating Point Package.
*
* double
* exp(x)
* double x;
*
* Returns : e ^ x (where e = 2.718...)
*
.globl exp
.globl _exp
.globl iefexp
.text
exp:
_exp:
~~exp:
link r14,#-4
movem.l d7,-(sp)
move.l 8(r14),r7
jsr iefexp
move.l r7,r0
movem.l (sp)+,d7
unlk r14
rts

View File

@@ -0,0 +1,25 @@
*
* Floating Point Logarithm :
* Front End to IEEE Floating Point Package.
*
* double
* log(x)
* double x;
*
* Returns : the floating point logarithm
*
.globl log
.globl _log
.globl ieflog
.text
log:
_log:
~~log:
link r14,#-4
movem.l d7,-(sp)
move.l 8(r14),r7
jsr ieflog
move.l r7,r0
movem.l (sp)+,d7
unlk r14
rts

View File

@@ -0,0 +1,30 @@
*
* Floating Point Multiplication :
* Front End to IEEE Floating Point Package.
*
* double
* fpmul(multiplier,multiplicand)
* double multiplier, multiplicand;
*
* Return : Result of Floating Point Multiply
*
.globl fpmul
.globl _fpmul
.globl fpmult
.globl _fpmult
.globl iefmul
.text
fpmult:
_fpmult:
fpmul:
_fpmul:
~~fpmul:
link r14,#-4
movem.l d6-d7,-(sp)
move.l 8(r14),r7
move.l 12(r14),r6
jsr iefmul
move.l r7,r0
movem.l (sp)+,d6-d7
unlk r14
rts

View File

@@ -0,0 +1,25 @@
*
* Floating Point Negation :
* Front End to IEEE Floating Point Package.
*
* double
* fpneg(farg)
* double farg;
*
* Returns : negated Floating point number
*
.globl fpneg
.globl _fpneg
.globl iefneg
.text
fpneg:
_fpneg:
~~fpneg:
link r14,#-4
movem.l d7,-(sp)
move.l 8(r14),r7
jsr iefneg
move.l r7,r0
movem.l (sp)+,d7
unlk r14
rts

View File

@@ -0,0 +1,26 @@
*
* Floating Point Power :
* Front End to IEEE Floating Point Package.
*
* double
* pow(x,y)
* double x, y;
*
* Returns : x ^ y
*
.globl pow
.globl _pow
.globl iefpwr
.text
pow:
_pow:
~~pow:
link r14,#-4
movem.l d3-d7,-(sp)
move.l 8(r14),r7
move.l 12(r14),r6
jsr iefpwr
move.l r7,r0
movem.l (sp)+,d3-d7
unlk r14
rts

View File

@@ -0,0 +1,256 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
/**
** formated print
**/
/*char *version "@(#)fprintf - jan 24, 1982";*/
#include <stdio.h>
#define BUFSIZ 80
char *ftoa();
char *etoa();
char *petoa();
char *pftoa();
static char *__str;
FILE *__stream;
static char **_p;
fprintf(fp, plist)
FILE *fp;
char *plist;
{
if (!fp->_flag & _WMODE) return;
__stream = fp;
_p = &plist;
__doprintf(0);
fflush(fp);
}
sprintf(s, plist)
char *s, *plist;
{
__str = s;
_p = &plist;
__doprint(1);
*__str = NULL;
}
__doprint(mode)
int mode;
{
register char *fmt, c;
char buf[BUFSIZ];
extern char *__prtshort(), *__prtld();
register int *pi;
int width, prec;
int left, longf;
char padchar;
char *s;
int n;
auto (*fn)();
int len;
fmt = *_p++;
pi = _p;
while (c = *fmt++)
{
_p = pi;
if (c != '%')
{
__putch(mode, c);
continue;
}
left = 0;
if ((c = *fmt++) == '-')
{
c = *fmt++;
left++;
}
padchar = ' ';
if (c == '0')
{
padchar = c;
c = *fmt++;
}
width = -1;
while (c >= '0' && c <= '9')
{
if (width < 0)
width = 0;
width = width * 10 + (c - '0');
c = *fmt++;
}
prec = -1;
if (c == '.')
{
prec = 0;
c = *fmt++;
}
while (c >= '0' && c <= '9')
{
prec = prec * 10 + (c - '0');
c = *fmt++;
}
longf = 0;
if (c == 'l')
{
longf++;
c = *fmt++;
}
/*
* we now have all the prelims out of the way;
* let's see what we want to print
*/
s = buf;
switch (c)
{
case 'd': /* decimal signed */
case 'D':
if (longf)
fn = __prtld;
else
fn = __prtshort;
__prtint(pi++, buf, 10, 1, fn, 0);
if (longf)
pi++;
break;
case 'u': /* decimal unsigned */
case 'U':
__prtint(pi++, buf, 10, 0, __prtshort, 0);
break;
case 'o': /* octal unsigned */
case 'O':
if (longf)
fn = __prtld;
else
fn = __prtshort;
__prtint(pi++, buf, 8, 0, fn, 0);
if (longf)
pi++;
break;
case 'x': /* hexadecimal unsigned */
case 'X':
if (longf)
fn = __prtld;
else
fn = __prtshort;
__prtint(pi++, buf, 16, 0, fn, c == 'X');
if (longf)
pi++;
break;
case 's': /* string */
case 'S':
s = *_p++;
pi = _p;
break;
case 'c': /* character */
case 'C':
n = *pi++;
buf[0] = n;
buf[1] = '\0';
break;
case 'e': /* exponential */
case 'E':
petoa(pi, buf, prec);
pi =+ 2;
prec = -1;
break;
case 'f': /* floating */
case 'F':
pftoa(pi, buf, prec);
pi =+ 2;
prec = -1;
break;
case 'g': /* e or f */
case 'G':
pftoa(pi, buf, prec);
if (strlen(buf) > (7 + prec)) /* smallest fp string */
petoa(pi, buf, prec);
pi =+ 2;
prec = -1;
break;
default: /* just print the character */
__putch(mode, c);
continue;
}
len = __length(s);
if (prec < len && prec >= 0)
len = prec;
n = width - len;
if (!left)
{
if (padchar != ' ' && *s == '-')
{
len--;
__putch(mode, *s); s++;
}
while (n-- > 0)
__putch(mode, padchar);
}
while (len--) {
__putch(mode, *s); s++;
}
while (n-- > 0)
__putch(mode, padchar);
}
}
__putch(mode, c)
int mode;
char c;
{
if (mode)
*__str++ = c;
else
putc(c,__stream);
return (c);
}
char *
pftoa(addr,buf,prec)
float *addr;
char *buf;
int prec;
{
float fp;
if (prec<0)
prec = 6;
fp = *addr;
return( ftoa(fp, buf, prec) );
}
char *
petoa(addr,buf,prec)
float *addr;
char *buf;
int prec;
{
float fp;
if (prec<0)
prec = 6;
fp = *addr;
return( etoa(fp, buf, prec) );
}

View File

@@ -0,0 +1,26 @@
*
* Floating Point Sine :
* Front End to IEEE Floating Point Package.
*
* double
* sin(farg)
* double farg;
*
* Input : in radians
* Returns : sine of Floating point number
*
.globl sin
.globl _sin
.globl iefsin
.text
sin:
_sin:
~~sin:
link r14,#-4
movem.l d3-d7,-(sp)
move.l 8(r14),r7
jsr iefsin
move.l r7,r0
movem.l (sp)+,d3-d7
unlk r14
rts

View File

@@ -0,0 +1,26 @@
*
* Floating Point Square Root :
* Front End to IEEE Floating Point Package.
*
* double
* sqrt(farg)
* double farg;
*
* Input : in radians
* Returns : square root of Floating point number
*
.globl sqrt
.globl _sqrt
.globl iefsqrt
.text
sqrt:
_sqrt:
~~sqrt:
link r14,#-4
movem.l d3-d7,-(sp)
move.l 8(r14),r7
jsr iefsqrt
move.l r7,r0
movem.l (sp)+,d3-d7
unlk r14
rts

View File

@@ -0,0 +1,26 @@
*
* Floating Point Subtraction :
* Front End to IEEE Floating Point Package.
*
* double
* fpsub(subtrahend,minuend)
* double subtrahend, minuend;
*
* Returns : Floating point subtraction result
*
.globl fpsub
.globl _fpsub
.globl iefsub
.text
fpsub:
_fpsub:
~~fpsub:
link r14,#-4
movem.l d6-d7,-(sp)
move.l 8(r14),r7
move.l 12(r14),r6
jsr iefsub
move.l r7,r0
movem.l (sp)+,d6-d7
unlk r14
rts

View File

@@ -0,0 +1,529 @@
/*
Copyright 1982, 1983
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
@(#)fscanf.c 1.1 11/9/83
*/
/*
** formatted read routine
**
** functionally equivalent to scanf in portable C library
*/
#include <stdio.h>
#include <math.h>
/* Delimiters */
#define NEWLINE '\n'
#define TAB '\t'
#define SPACE ' '
#define NULL '\0'
/* returns from __next() */
#define CHAR 0
#define NOT_WHT -1
#define NOT_WHT_NL 1
/* returns from __scan() */
#define NORETURN 0
#define VALID 1
#define NOMATCH -1
#define AT_EOF -2
#define ERROR -3
FILE *__stream;
char **_p, *__sstr, __holdch;
int __smode, __hold;
scanf(parlist)
char *parlist;
{
__smode = 0;
_p = &parlist;
return(__doscanf());
}
fscanf(stream,parlist)
FILE *stream;
char *parlist;
{
if( (stream->_flag&(_RMODE|_UPDATE)) == 0 || feof(stream) )
return(EOF);
__smode = 1;
__stream = stream;
_p = &parlist;
return(__doscanf());
}
sscanf(s,parlist)
char *s, *parlist;
{
__smode = 2;
__sstr = s;
_p = &parlist;
return(__doscanf());
}
__doscanf()
{
register int nmatch;
register char ch;
char *format;
register char match_ch;
nmatch = __hold = 0;
format = *_p++;
while( 1 ) {
switch (ch = *format++) {
case NULL:
return(nmatch);
case '%':
if( *format != '%' ) {
switch (__scan(&format, *_p)) {
case VALID: /* good return*/
_p++;
nmatch++;
case NORETURN: /* no return*/
break;
case NOMATCH: /* no match */
return(nmatch);
case AT_EOF: /* end of file */
return(nmatch ? nmatch : NOMATCH);
default: /* syntax error */
return(NOMATCH);
}
break;
}
format++;
default:
match_ch = __next(CHAR);
if( ch != match_ch ) {
__unget(match_ch);
return(nmatch ? nmatch : AT_EOF);
}
break;
}
}
}
/*
* main scan routine -- look at characters in the conversion string
* and do their bidding
*/
__scan(spec, result)
char **spec;
char *result;
{
register int longf, length;
register char ch;
extern int __strend(), __splend();
longf = length = 0;
while( 1 ) {
switch (ch = *(*spec)++) {
case '*':
result = 0;
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
length = length * 10 + ch - '0';
break;
case 'l':
if( longf )
return(ERROR);
longf = 1;
break;
case 'h': /* short */
if( longf )
return(ERROR);
longf = NOMATCH;
break;
case 'o':
case 'O':
return(__dec(result, length ? length : 100, 8, longf));
case 'd':
case 'D':
return(__dec(result, length ? length : 100, 10, longf));
case 'x':
case 'X':
return(__dec(result, length ? length : 100, 16, longf));
case 'c':
case 'C':
if( longf )
return(ERROR);
return(__char(result, length ? length : 1));
case 's':
case 'S':
if( longf )
return(ERROR);
return(__strx(result, length ? length : 100, __strend));
case 'e':
case 'E':
case 'f':
case 'F':
if( longf )
return(ERROR);
return(__float(result, length ? length : 100));
/*return(ERROR); /* not yet implemented */
case '[':
if( longf )
return(ERROR);
if( __inits(spec) )
return(ERROR);
return(__strx(result, length ? length : 100, __splend));
default:
return(ERROR);
}
}
}
/*
* get a constant -- octal, decimal, or hex depending on base
*/
__dec(result, length, base, longf)
register int *result;
int length;
int base;
int longf;
{
register char ch;
register int val;
register int ndigit;
register long *lresult;
register long lres;
register int ires;
register int minus, ok;
ires = 0;
lres = 0;
ndigit = minus = 0;
switch (ch = __next(NOT_WHT_NL)) {
case NULL:
case EOF:
return(AT_EOF);
case '-':
minus = 1;
case '+':
ndigit++;
ch = __next(NOT_WHT);
}
ok = 0;
while( (val = __digit(ch, base)) >= 0 && ndigit++ < length ) {
ok++;
if( longf )
lres = lres * base + val;
else
ires = ires * base + val;
ch = __next(CHAR);
}
__unget(ch);
if( !ok )
return(NOMATCH);
if( !result )
return(NORETURN);
if( minus )
if( longf )
lres = -lres;
else
ires = -ires;
if( longf ) {
lresult = result;
*lresult = lres;
}
else
*result = ires;
return(VALID);
}
/*
* get a floating point constant
*/
__float(result, length)
register double *result;
int length;
{
char buffer[100];
double val;
int ret, ch;
ret = __strx(buffer, 100, __strend);
val = atof(buffer);
*result = val;
return(ret);
}
__next(mode)
int mode;
{
/*
* mode -1: get next non-space or non-tab
* mode 0: get next character
* mode 1: get next non-space, non-tab, or non-newline
*/
register int ch;
if( (ch = __getch()) == EOF )
return(EOF);
if( mode == 0 )
return(ch);
while( ch == SPACE || ch == TAB || ch == NEWLINE ) {
if( ch == NEWLINE && mode < 0 )
break;
ch = __getch();
}
return(ch);
}
/*
* check an input character for a valid constant digit (octal, decimal,
* or hex) if found, return the proper numeric value. Negative results
* indicate error.
*/
__digit(ch, base)
register char ch;
register int base;
{
register int n;
if( ch < '0' )
return(NOMATCH);
if( ch <= '7' )
return(ch - '0');
if( base == 8 )
return(NOMATCH);
if( ch <= '9' )
return(ch - '0');
if( base == 10 || ch < 'A' )
return(NOMATCH);
if( ch <= 'F' )
return(ch - 'A' + 10);
if( ch < 'a' || ch > 'f' )
return(NOMATCH);
return(ch - 'a' + 10);
}
/*
* check for an end of string delimiter
*/
__strend(cha)
char cha;
{
register char ch;
if( (ch = cha) == EOF )
return(EOF);
if( ch == SPACE || ch == TAB || ch == NEWLINE || ch == NULL )
return(VALID);
return(NORETURN);
}
char __splset[128];
/*
* check for the occurrance of any character in the set which
* the user wants to be end-of-string delimiters
*/
__splend(ch)
char ch;
{
if( ch == EOF )
return(EOF);
return(__splset[ch]);
}
/*
* initialize the array which inidcates the special chars which the user
* wants to be included (or not included) in strings.
*/
__inits(spec)
register char **spec;
{
register char ch;
register int i;
register int val;
ch = *(*spec)++;
if( ch == '^' ) {
val = 0;
ch = *(*spec)++;
}
else
val = 1;
for (i = 1; i < 128; i++)
__splset[i] = val;
val = 1 - val;
while( ch != ']' ) {
if( ch == 0 )
return(NOMATCH);
__splset[ch & 0177] = val;
ch = *(*spec)++;
}
__splset[0] = 1;
return(NORETURN);
}
/*
* getting a string
*/
__strx(result, length, endfn)
register char *result;
register int length;
register int (*endfn)();
{
register char ch;
extern int __splend();
register int imode, notok;
notok = 1;
imode = (endfn != __splend);
if (imode) {
ch = __next(NOT_WHT_NL);
__unget(ch); /* bypass tab or space... */
}
while( !(*endfn)( (ch = __next(imode)) ) && length-- > 0 ) {
if( result )
*result++ = ch;
imode = notok = 0;
}
__unget(ch);
if( notok )
return(ch == EOF ? AT_EOF : NOMATCH);
if( !result )
return(NORETURN);
*result = 0;
return(VALID);
}
/*
* getting a character constant
*/
__char(result, length)
register char *result;
register int length;
{
register char *r, ch;
register int l;
r = result;
l = length;
while( l-- ) {
if( (ch = __next(CHAR)) <= 0 ) {
if( l + 1 == length )
return(ch == EOF ? AT_EOF : NOMATCH);
else
return(result != 0);
}
if( result )
*result++ = ch;
}
return(result != 0);
}
__getch()
{
switch(__smode) {
case 0:
return(__gstdi());
case 1:
return(getc(__stream));
case 2:
return(__gs());
}
}
__unget(ch)
char ch;
{
switch(__smode) {
case 0:
__ugstdi(ch);
break;
case 1:
ungetc(ch,__stream);
break;
case 2:
__ungs(ch);
break;
}
}
/*
* return the next char pointed to by *s
*/
__gs()
{
register char c;
c = *__sstr;
if( c )
__sstr++;
else
return(EOF);
return(c);
}
/*
* put back a char for further scanning
*/
__ungs(c)
char c;
{
if( c )
__sstr--;
}
__gstdi()
{
if( !__hold)
return(getchar());
else {
__hold = 0;
return(__holdch);
}
}
__ugstdi(ch)
char ch;
{
__hold = 1;
__holdch = ch;
}

View File

@@ -0,0 +1,121 @@
/*
Copyright 1982, 1983
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
/*char *version "@(#)ftoa.c 1.4 12/29/83";*/
/*
* IEEE Floating Point to Ascii String Conversion Routine :
* IEEE Standard Single Precision Representation Floating Point
*
* char *
* ftoa(f,buf,prec)
* float f;
* char *buf;
* int prec;
*
* No more than 9 decimal digits are allowed in single precision.
* Largest positive number is 3.4 * 10^33 and the smallest positive
* number is 1.2 * 10^-38.
* Rely's on the fact that a long and a float are both 32 bits.
* 29 dec 83 - allow 0 decimal places !!!
*/
#define BIAS 127L
#ifdef ISIEEE
float _ffake();
#else
float _ieeetof();
#endif
char *
ftoa(fl,buf,prec)
long fl; /* ieee formatted float */
char *buf;
int prec;
{
register char *bp;
register int exp, digit;
float f;
prec = (prec <= 0) ? 0 : (prec <= 9) ? prec : 9;
bp = buf;
if(fl == 0) goto shortcut;
if(fl == 0x7f800000) { /* positive infinity */
strcpy(bp,"+infinity");
return(bp);
}
if(fl == 0xff800000) { /* negative infinity */
strcpy(bp,"-infinity");
return(bp);
}
#ifndef ISIEEE
f = _ieeetof(fl); /* get floating point value */
#else
f = _ffake(fl);
#endif
#ifndef ISIEEE
if (f < 0.0) { /* negative float */
#else
if (fl & 0x80000000) { /* negative float */
#endif
*bp++ = '-';
f = -f; /* make it positive */
}
#ifndef ISIEEE
if (f == 0.0) {
#else
if (fl == 0) {
#endif
shortcut:
*bp++ = '0';
if(prec) {
*bp++ = '.';
while (prec--)
*bp++ = '0';
}
*bp = 0;
return(buf);
}
for (exp=0; f < 1.0; f = f * 10.0) /* get negative exp */
exp--;
for ( ; f >= 1.0; f = f / 10.0) /* 0.XXXXXXE00 * 10^exp */
exp++;
if (exp<=0) /* one significant digit */
*bp++ = '0';
for ( ; exp>0; exp--) { /* get significant digits */
f = f * 10.0;
digit = f; /* get one digit */
f = f - digit;
*bp++ = digit + '0';
}
if(prec) {
*bp++ = '.';
for( ; exp<0 && prec; prec--, exp++) /* exp < 0 ? */
*bp++ = '0';
while(prec-- > 0) {
f = f * 10.0;
digit = f; /* get one digit */
f = f - digit;
*bp++ = digit + '0';
}
}
*bp = 0;
return(buf);
}
#ifdef ISIEEE
/* if these routines are executed on a 68000 using ieee then no need to
do a translation !!! */
float
_ffake(lf)
float lf;
{
return(lf);
}
#endif

View File

@@ -0,0 +1,46 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
/* char *version "@(#)ftol.c 1.2 10/19/83"; */
/*
* Floating Point Float to Long Routine :
* Front End to IEEE Floating Point Package.
*
* long
* fpftol(fparg)
* double fparg;
*
* Return : Fixed Point representation of Floating Point Number
*/
#define BIAS 127L
long
fpftol(f)
long f;
{
register long l;
register int exp, sign;
l = (f & 0x7f800000) >> 23;
exp = l - BIAS;
if (f == 0L || exp < 0) /* underflow or 0 */
return(0L);
sign = (f < 0L);
if (exp > 31) /* overflow */
return( (sign) ? 0x80000000 : 0x7fffffff);
exp =- 23;
l = (f & 0x7fffff) | 0x800000; /* 1.F */
for( ; exp < 0 ; exp++)
l =>> 1;
for( ; exp > 0; exp--)
l =<< 1;
if (sign)
l = -l;
return(l);
}

View File

@@ -0,0 +1,59 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
/*char *version "@(#) _ieeetof - dec 29, 1982"; */
/*
* IEEE Floating Point Representation to Internal Representation :
* IEEE Standard Single Precision Representation Floating Point
*
* float
* _ieeetof(lf)
* long lf;
*
* Largest positive number is 3.4 * 10^33 and the smallest positive
* number is 1.2 * 10^-38.
* Rely's on the fact that a long and a float are both 32 bits.
*/
#define BIAS 127L
float
_ieeetof(lf)
long lf;
{
register long exp;
register int count, fsign;
float f;
if (lf == 0L)
return(0.0);
if (lf < 0L) {
fsign = 1;
lf =& 0x7fffffff; /* mask MSB (sign) */
}
else
fsign = 0;
exp = (lf >> 23) & 0xff; /* biased ieee exponent */
exp =- BIAS;
lf =& 0x7fffff; /* 23 bits of fraction */
f = lf;
if (lf != 0) /* don't need to do floating point test !!! */
f = f / 8388608.0; /* 2 ^ 23 */
f = f + 1.0; /* ieee fraction : 1.F */
while (exp < 0) { /* negative exp : 2^-? */
f = f / 2.0;
exp++;
}
while (exp > 0) { /* positive exp : 2^+? */
f = f * 2.0;
exp--;
}
if (fsign)
f = -f;
return(f);
}

View File

@@ -0,0 +1,100 @@
ttl ieee format equivalent abs and neg (iefabs/iefneg)
***************************************
* (c) copyright 1981 by motorola inc. *
***************************************
*************************************************************
* iefabs *
* fast floating point ieee format equivalent absolute value*
* *
* input: d7 - ieee format number argument *
* *
* output: d7 - ieee format number absolute value result *
* *
* condition codes: *
* n - cleared *
* z - set if result is zero *
* v - set if result is nan (not-a-number) *
* (occurs only if input argument is nan) *
* c - undefined *
* x - undefined *
* *
* all registers transparent *
* *
* maximum stack used: 24 bytes *
* *
* notes: *
* 1) this routine properly handles all ieee floating *
* point values and number types. *
* 2) if the input argument is a nan (not-a-number) then *
* it will be returned as the result with the "v" bit *
* set in the condition code register. *
* *
*************************************************************
page
iefabs idnt 1,1 ieee format equivalent abs and neg
opt pcs
xdef iefabs ieee format absolute value
xref iefsop single argument conversion routine
xref iefrtod7 return caller's original d7 as result
xref ffpcpyrt copyright notice
section 9
******************************
* absolute value entry point *
******************************
iefabs jsr iefsop direct return to caller if nan encountered
nop +0 normalized return (or zero or denormalized)
* +2 infinity return
* all values may be absolutized by forcing a plus sign on the original value
bclr.b #7,16(sp) clear sign bit of original value
jmp iefrtod7 and return original value altered a wee bit
page
*************************************************************
* iefneg *
* fast floating point ieee format equivalent negate *
* *
* input: d7 - ieee format number argument *
* *
* output: d7 - ieee format number negated result *
* *
* condition codes: *
* n - set if result is negative *
* z - set if result is zero *
* v - set if result is nan (not-a-number) *
* (occurs only if input argument is nan) *
* c - undefined *
* x - undefined *
* *
* all registers transparent *
* *
* maximum stack used: 24 bytes *
* *
* notes: *
* 1) this routine properly handles all ieee floating *
* point values and number types. *
* 2) if the input argument is a nan (not-a-number) then *
* it will be returned as the result with the "v" bit *
* set in the condition code register. *
* *
*************************************************************
page
xdef iefneg ieee format negate
**********************
* negate entry point *
**********************
iefneg jsr iefsop direct return to caller if nan encountered
nop +0 normalized return (or zero or denormalized)
* +6 both infinity return
* all values may be negated by inverting the sign bit of the original value
bchg.b #7,16(sp) negate original sign bit
jmp iefrtod7 and return this modified original register
end

View File

@@ -0,0 +1,122 @@
ttl ieee format equivalent add/subtract (iefadd/iefsub)
***************************************
* (c) copyright 1981 by motorola inc. *
***************************************
*************************************************************
* iefadd/iefsub *
* fast floating point ieee format equivalent add/subtract *
* *
* iefadd - ieee format equivalent floating point addition *
* *
* input: d6 - ieee format number addend (source) *
* d7 - ieee format number adder (destination) *
* *
* iefsub - ieee format equivalent floating point subtract *
* *
* input: d6 - ieee format number subtrahend (source) *
* d7 - ieee format number minuend (destination) *
* *
* output: d7 - ieee format floating result of register d6 *
* added or subtracted from register d7 *
* *
* condition codes: *
* n - result is negative *
* z - result is zero *
* v - result is nan (not-a-number) *
* c - undefined *
* x - undefined *
* *
* all registers transparent *
* *
* maximum used stack: 28 bytes *
* *
* result matrix: arg 2 *
* others +inf -inf nan *
* arg 1 **************************************** *
* others * a * b * c * f * *
* +infinity * b * b * d * f * *
* -infinity * c * d * c * f * *
* nan * e * e * e * f * *
* **************************************** *
* a = return addition or subtraction result, *
* overflowing to infinity, underflowing to zero *
* b = return plus infinity *
* c = return minus infinity *
* d = return newly created nan (not-a-number) *
* e = return arg1 (nan) unchanged *
* f = return arg2 (nan) unchanged *
* *
* notes: *
* 1) for subtraction, the sign of the source is *
* inverted and then the operation is treated as *
* an addition using the decision matrix above. *
* 2) see the mc68344 user's guide for a description of *
* the possible differences between the results *
* returned here versus those required by the *
* ieee standard. *
* *
*************************************************************
page
iefadd idnt 1,1 ieee format equivalent add/subtract
opt pcs
xdef iefadd ieee format addition
xdef iefsub ieee format subtraction
xref iefdop double argument conversion routine
xref iefrtnan create and return nan result routine
xref iefrtd7 return contents of d7 as the result
xref iefrtsz return signed zero with sign of d7
xref ieftieee return and convert back to ieee format
xref ffpadd reference fast floating point add routine
xref ffpcpyrt copyright notice
section 9
************************
* subtract entry point *
************************
iefsub bchg.l #31,d6 invert sign of second argument for subtract
jsr iefadd and call add routine
move.w sr,-(sp) save ccr of result on the stack [vlh] was sr
bchg.l #31,d6 revert sign back to original condition
rtr return with result and condition codes
*******************
* add entry point *
*******************
iefadd jsr iefdop decode both operands
jmp iefnrm +0 branch normalized
jmp iefinf2 +2 branch arg2 infinity
jmp iefinf1 +4 branch arg1 infinity
* test for opposite signs +6 both are infinity
eor.l d6,d7 exclusive or signs
* bmi iefrtnan opposite signs - go return a nan
bmi GOTHERE
jmp iefinf1
GOTHERE jmp iefrtnan * loader problem
* otherwise both same and return same
* arg1 infinity - return it
iefinf1 move.l d6,d7 return arg1
* arg2 infinity - return it (already in d7)
iefinf2 jmp iefrtd7 return d7 as our result
* normalized numbers - do the addition
iefnrm jsr ffpadd do fast floating point add
* bne ieftieee convert result back to ieee format
bne DOIT
jmp NOPE
DOIT jmp ieftieee
* the above few lines had to be changed because of the loader problem
* result is zero - return with proper sign for rn (round-to-nearest)
NOPE
movem.l (sp),d3-d7 reload arguments (and rest of registers)
and.l d6,d7 return minus only if both minus
jmp iefrtsz return signed zero with sign of d7
end

View File

@@ -0,0 +1,66 @@
ttl ieee format equivalent arctangent (iefatan)
***************************************
* (c) copyright 1981 by motorola inc. *
***************************************
*************************************************
* iefatan *
* ieee format equivalent arctangent *
* *
* input: d7 - ieee format argument *
* *
* output: d7 - ieee format arctangent radian *
* result *
* *
* all other registers totally transparent *
* *
* condition codes: *
* z - set if result is zero *
* n - cleared *
* v - set if result is nan (not-a-number)*
* (set if the input argument was nan)
* c - undefined *
* x - undefined *
* *
* all other registers transparent *
* *
* maximum stack used: 54 bytes *
* *
* *
* notes: *
* 1) see the mc68344 user's guide for details*
* on ieee format range limitations. *
* 2) spot checks show at least six digit *
* precision on all sampled cases. *
* *
*************************************************
page
iefatan idnt 1,1 ieee format equivalent arctangent
opt pcs
section 9
xdef iefatan entry point
xref ffpatan fast floating point arctangent
xref iefsop front-end single operand convert
xref ieftieee back-end return ieee format
xref ffpfieee ffp to ieee convert routine
xref ffpcpyrt copyright stub
********************
* arctangent entry *
********************
* save registers and convert argument
iefatan jsr iefsop convert the single argument
bra.s iefnrm +0 branch normalized
* argument was infinite +2 infinity
jsr ffpfieee convert to maximum values allowed in ffp format
* argument was normalized
iefnrm jsr ffpatan call ffp arctangent routine
jmp ieftieee return in ieee format
end

View File

@@ -0,0 +1,186 @@
ttl ieee format equivalent back-end routines (iefback)
iefback idnt 1,1 ieee format equivalent back-end routines
******************************************
* (c) copyright 1981 by motorola inc. *
******************************************
section 9
****************************************************************
* iefrtnan (internal routine) *
* ieee format equivalent fast floating point return nan *
* *
* input: sp -> +0 original callers d3-d7 registers *
* +20 original callers return address *
* *
* output: d7 - a newly created nan (not-a-number) *
* ccr - the "v" bit is forced on *
* *
* and direct return to the original caller *
* *
* purpose: called whenever the result of an operation *
* is illegal or undefined and a nan result must *
* be generated as the final result. *
* *
* the ieee format defined nan is determined by an exponent *
* of all one's and a non-zero significand. the sign bit *
* is a don't care. the ieee standard leaves up to each *
* implementation what is placed in the significand. here *
* we will generate the low order 23 bits of the original *
* caller's return address. however, this may not be *
* sufficient - if all 23 bits happen to be zero or the *
* address is larger than 23 bits this would lead to an *
* incorrect result. therfore, if this happens only the low *
* order significand bit is set on with the rest zeroes. *
* this represents an odd address (illegal with current m68000*
* instruction alignment restrictions) and any interested *
* party can tell if such a substitution has taken place. *
* also, if this was illegally assumed to be an address and *
* used, an address exception trap would ensue thus not *
* allowing its use as a valid address. *
* *
****************************************************************
signmsk equ $80000000 ieee format sign isolation mask
expmsk equ $7f800000 ieee format exponent mask
vbit equ $0002 condition code "v" bit mask
zbit equ $0004 condition code "z" bit mask
xdef iefrtnan return nan result routine
iefrtnan movem.l (sp)+,d3-d7 restore callers registers
move.l (sp),d7 load up return address
and.l #signmsk+expmsk,d7 verify not larger than 23 bits
bne.s iefnone it is, cannot use it - return a one
move.l (sp),d7 load up return address
and.l #$007fffff,d7 isolate address bits required
bne.s iefnzro branch if not zero
iefnone move.l #1,d7 set only low bit on
iefnzro or.l #expmsk,d7 force exponent all ones
or.b #vbit,ccr return with "v" bit set [vlh]
rts return to original caller
page
**********************************************************
* ieftieee (internal subroutine) *
* ieee format compatible convert ffp to ieee format *
* *
* input: d7 - result of fast floating point operation *
* ccr - set for above result *
* sp -> +0 original callers saved d3-d7 *
* +20 original callers return address *
* *
* output: d7 - ieee format equivalent of the result *
* *
* condition code: *
* *
* n - set if the result is negative *
* z - set if the result is zero *
* v - cleared (not nan) *
* c - cleared *
* x - undefined *
* *
* all fast floating point numbers have an exact *
* ieee format representation. since the fast *
* floating point routines always set the "v" bit *
* for overflows and returns the proper sign, we *
* can easily change the result to an ieee infinity *
* and unflag the "v" bit. *
* *
**********************************************************
xdef ieftieee return ieee result to original caller
ieftieee bvs.s iefvset branch if overflow ffp result
add.l d7,d7 delete mantissa high bit
beq.s ieftrtn branch zero as finished
eor.b #$80,d7 to twos complement exponent
asr.b #1,d7 form 8-bit exponent
sub.b #$82,d7 adjust 64 to 127 and excessize
swap.w d7 swap for high byte placement
rol.l #7,d7 set sign+exp in high byte
ieftrtn tst.l d7 test "z" and "n", clear "v" and "c" in ccr
movem.l (sp)+,d3-d6 restore d3 thru d6 callers registers
add.l #4,sp skip original d7
rts return to original caller with result
* overflow - set to proper ieee format infinity
iefvset add.b d7,d7 save sign bit in "x"
move.l #expmsk<<1,d7 set exponent of ones shifted left
roxr.l #1,d7 insert proper sign
jmp ieftrtn and return to original caller
page
*******************************************************************
* general purpose return routines *
* *
* the following routines return a specific final result *
* to the original caller with the proper condition codes *
* set as follows: *
* *
* n - the result is negative *
* z - the result is a zero *
* v - cleared (not a nan) *
* c - undefined *
* x - undefined *
* *
* the routines are as follows: *
* *
* iefrtd7 - return the current contents of d7 *
* iefrtod7 - return the original contents of d7 *
* iefrtsz - return a signed zero (sign is bit 31 of d7) *
* iefrtie - return infinity with sign exclusive or of *
* original argument signs *
* iefrtsze - return signed zero with sign exclusiv or *
* of original argument signs *
* *
*******************************************************************
xdef iefrtd7,iefrtsz,iefrtod7,iefrtie,iefrtsze
**********************
* return original d7 *
* (cant be neg zero) *
**********************
iefrtod7 move.l 16(sp),d7 load original d7 into d7
*********************
* return current d7 *
* (cant be neg zero)*
*********************
iefrtd7 movem.l (sp)+,d3-d6 load all but d7 registers back up
add.l #4,sp skip original d7 on stack
add.l d7,d7 check for signed zero
beq.s iefwasz branch if was a zero
roxr.l #1,d7 value back into position set ccr ("v" clear)
rts return to caller with ccr and result
**************************************
* return signed zero with sign being *
* eor of the original operands *
**************************************
iefrtsze movem.l 12(sp),d6-d7 load original arguments
eor.l d6,d7 produce proper sign
**********************
* return signed zero *
* d7 bit31 has sign *
**********************
iefrtsz movem.l (sp)+,d3-d6 load all but d7 back up
add.l #4,sp skip original d7 on stack
add.l d7,d7 set sign bit into carry
move.l #0,d7 zero d7
iefwasz roxr.l #1,d7 set sign bit back in ("v" cleared)
or.b #zbit,ccr force zero bit on in ccr [vlh]
rts
*********************************
* return infinity with eor sign *
* of original arguments *
*********************************
iefrtie movem.l (sp)+,d3-d7 restore original arguments
eor.l d6,d7 produce proper sign
add.l d7,d7 shift sign out
move.l #expmsk<<1,d7 setup infinity (exponent all ones)
roxr.l #1,d7 set sign back in ("v" cleared)
rts return with result and ccr set
end

View File

@@ -0,0 +1,182 @@
ttl ieee format equivalent compare and test (iefcmp/ieftst)
***************************************
* (c) copyright 1981 by motorola inc. *
***************************************
*************************************************************
* iefcmp *
* fast floating point ieee format equivalent compare *
* *
* (result is test of destination - source) *
* *
* input: d6 - ieee format number (source) *
* d7 - ieee format number (destination) *
* *
* output: the condition code register is set to directly *
* reflect the following results of the test: *
* *
* eq equal *
* ne not equal *
* gt greater than *
* ge greater than or equal *
* lt less than *
* le less than or equal *
* cc ordered *
* cs unordered *
* *
* condition codes: *
* n - set for proper arithmetic tests *
* z - set if result is zero *
* v - set for proper arithmetic tests *
* c - set if result is unordered *
* (not-a-number operand) *
* x - undefined *
* *
* all registers transparent *
* *
* maximum stack usage: 32 bytes *
* *
* notes: *
* 1) the unordered condition results whenever any *
* argument is a nan (not-a-number). the carry bit *
* will be returned on if this occurs. this is *
* different from most of the other mc68344 ieee format*
* equivalent operations in that they return the "v" *
* bit set which is handy for use of the "trapv" *
* instruction. however, "v" must be used here for the*
* signed arithmetic comparisons. *
* 2) iefcmp recognizes and properly handles all single- *
* precision ieee format values and data types. *
* 3) infinities are handled in affine mode (plus and *
* minus infinities are allowed and operate with non- *
* infinities). *
* *
*************************************************************
page
iefcmp idnt 1,1 ieee format equivalent compare/test
opt pcs
xref iefdop double argument conversion routine
xref ffpcpyrt copyright notice
section 9
xdef iefcmp ieee format compare
ccrcbit equ $01 condition code register "c" bit mask
***********************
* compare entry point *
***********************
iefcmp move.l d7,-(sp) save callers original d7
jsr iefcall call internal routine (nans will return here)
* if control returns here it will be from iefdopt detecting a nan
move.l (sp)+,d7 restore original d7 in case arg1 nan and not arg2
or #ccrcbit,ccr set c-bit for unordered nan encntrd [vlh]
rts return to caller with "c" set
* internal subroutine. split nan's away via call to iefdop. iefdop will
* directly return to the code above if it detects either operand to be a nan.
iefcall jsr iefdop decode both operands
jmp iefnrm +0 normalized return (or zero or denormalized)
jmp iefinf2 +2 arg2 infnity return
jmp iefinf1 +4 arg1 infnity return
* +6 both infinity return
* both values are infinity. we can substitute +1 and -1 values for plus and
* minus infinity respectively, and continue with a straight arithmetic compare.
move.l #30,d5 setup shift count for sign propagation
asr.l d5,d7 change to plus or minus one
asr.l d5,d6 change to plus or minus one
jmp iefdocmp now finish with standard arithmetic compare
* arg2 is infinity and not arg1 - substitute $80000000 (lowest binary value)
* for negative infinity to force proper compare
iefinf2 tst.l d7 ? was this minus infinity
bpl.s iefinf2p branch if ok to compare
lsl.l #8,d7 change to smallest negative number for compare
iefinf2p jsr ieffix1 reload and fix arg1 negative zeroes
jmp iefdocmp now finish with compare
* arg1 is infinity and not arg2 - substitude $80000000 (lowest binary value)
* for negative infinity to force proper compare
iefinf1 tst.l d6 ? was this minus infinity
bpl.s iefdarg2 branch if not, ok to use
lsl.l #8,d6 set to smallest negative value
jmp iefdarg2 reload and fix arg2 negative zeroes
* all normalized, denormalized, or zeroes return here.
* except for minus zeroes, a simple arithmetic compare can be
* done directly on the original ieee arguments. minus zeroes are
* changed to true arithmetic zeroes.
iefnrm jsr ieffix1 load and fix negative zeroes for first argument
iefdarg2 move.l 16(sp),d7 reload arg2
add.l d7,d7 test for plus or minus zero
beq.s iefdocmp br zero, use true zero for compare
move.l 16(sp),d7 reload and use original value
iefdocmp cmp.l d6,d7 perform the compare (destination minus source)
and #$7f-ccrcbit,ccr force c-bit off for ordered cmpr [vlh]
movem.l (sp)+,d3-d7 restore callers original registers
add.l #8,sp skip over internal return address and saved d7
rts return with arithmetic compare condition code
* load and fix argument 1 for negative zeroes
ieffix1 move.l 12+4(sp),d6 reload it back
add.l d6,d6 check for plus or minus zero
beq.s ieffixr return if zero to use true zero
move.l 12+4(sp),d6 reload and use original value
ieffixr rts return to caller
page
*************************************************************
* ieftst *
* fast floating point ieee format equivalent test *
* *
* (result is test of destination minus zero) *
* *
* input: d7 - ieee format number (destination) *
* *
* output: the condition code register is set to directly *
* reflect the following results of the test: *
* *
* eq equal zero *
* ne not equal zero *
* pl positive value *
* mi negative value *
* vc not a nan (not-a-number) *
* vs nan (not-a-number) *
* *
* condition codes: *
* n - set if negative *
* z - set if zero *
* v - set if nan (not-a-number) *
* c - undefined *
* x - undefined *
* *
* all registers transparent *
* *
* total stack usage: 24 bytes *
* *
* notes: *
* 1) iefcmp recognizes and properly handles all single- *
* precision ieee format values and data types. *
* *
*************************************************************
page
xref iefsop single argument conversion routine
xref iefrtod7 return original d7 to caller as result
xdef ieftst ieee format test
********************
* test entry point *
********************
ieftst jsr iefsop separate out nans back to caller
nop +0 normalized zero or denormalized
* +2 argument was infinity
* merely return with d7 as the result. ccr will be set properly
jmp iefrtod7 return old original d7
end

View File

@@ -0,0 +1,99 @@
ttl ieee format equivalent divide (iefdiv)
***************************************
* (c) copyright 1981 by motorola inc. *
***************************************
*************************************************************
* iefdiv *
* fast floating point ieee format equivalent divide *
* *
* input: d6 - ieee format number divisor (source) *
* d7 - ieee format number dividend (destination) *
* *
* output: d7 - ieee format floating result of register d6 *
* divided into register d7 *
* *
* condition codes: *
* n - result is negative *
* z - result is zero *
* v - result is nan (not-a-number) *
* c - undefined *
* x - undefined *
* *
* all registers transparent *
* *
* maximum stack usage: 24 bytes *
* *
* result matrix: arg 2 *
* others zero infinity nan *
* arg 1 **************************************** *
* others * a * b * c * f * *
* zero * c * d * c * f * *
* infinity * b * b * d * f * *
* nan * e * e * e * f * *
* **************************************** *
* a = return divide result, overflowing to infinity, *
* underflowing to zero with proper sign *
* b = return zero with proper sign *
* c = return infinity with proper sign *
* d = return newly created nan (not-a-number) *
* e = return arg1 (nan) unchanged *
* f = return arg2 (nan) unchanged *
* *
* notes: *
* 1) see the mc68344 user's guide for a description of *
* the possible differences between the results *
* returned here versus those required by the *
* ieee standard. *
* *
*************************************************************
page
iefdiv idnt 1,1 ieee format equivalent divide
opt pcs
xdef iefdiv ieee format equivalent divide
xref iefdop double argument conversion routine
xref iefrtnan create and return nan result routine
xref ieftieee return and convert back to ieee format
xref iefrtsze return signed zero with exclusive or signs
xref iefrtie return infinity with exclusive or signs
xref ffpdiv reference fast floating point divide routine
xref ffpcpyrt copyright notice
section 9
**********************
* divide entry point *
**********************
iefdiv jsr iefdop decode both operands
jmp iefnrm +0 branch normalized
jmp iefrtinf +2 branch arg2 infinity
jmp iefrtzro +4 branch arg1 infinity
* both are infinity - return a nan +6 both are infinity
jmp iefrtnan return a nan for infinity into infinity
* arg1 infinity - return zero with proper sign
iefrtzro jmp iefrtsze return zero with exclusive or'ed sign
* arg2 infinity but not arg1 - return infinity with proper sign
iefrtinf jmp iefrtie return infinity with exclusive or'ed sign
* normalized numbers - test for zeroes
iefnrm tst.l d7 ? dividend zero (arg2)
bne.s ief2nz no, go test divisor for zero
tst.l d6 ? are both zero
bne.s iefrtzro no, just dividend - return a zero
jmp iefrtnan return a nan for zero into zero
* dividend (arg2) not zero
ief2nz tst.l d6 ? divisor zero (arg1) but not dividend (arg2)
beq.s iefrtinf yes, return infinity with proper sign
* both arguments non zero and normalized - do the divide
jsr ffpdiv do fast floating point divide
beq iefrtzro if result is zero return a proper sign zero
jmp ieftieee convert result back to ieee format
end

View File

@@ -0,0 +1,67 @@
ttl ieee format equivalent exponent (iefexp)
***************************************
* (c) copyright 1981 by motorola inc. *
***************************************
*************************************************
* iefexp *
* ieee format equivalent exponent function *
* *
* input: d7 - ieee floating point argument *
* *
* output: d7 - ieee floating point exponential*
* result *
* *
* all other registers are transparent *
* *
* maximum stack used: 54 bytes *
* *
* condition codes: *
* z - set if result in d7 is zero *
* n - cleared *
* v - set if result is nan (not-a-number)*
* c - undefined *
* x - undefined *
* *
* *
* notes: *
* 1) if the input argument is a nan (not-a- *
* number) then the "v" bit will be set *
* and the argument unchanged upon return. *
* 2) see the mc68344 user's guide for details*
* on the range of ieee normalized values *
* supported. *
* 2) spot checks show at least 6.8 digit *
* accuracy for all abs(arg) < 30. *
* *
*************************************************
page
iefexp idnt 1,1 ieee format equivalent exp
opt pcs
section 9
xdef iefexp entry point
xref ffpexp fast floating point exponent
xref iefsop front-end single argument routine
xref ieftieee back-end return to ieee format
xref iefrtd7 return to caller argument in d7
xref ffpcpyrt copyright stub
************************
* exponent entry point *
************************
iefexp jsr iefsop convert argument to ffp format
bra.s iefnrm branch normalized
* argument is an infinity
bpl.s iefdrtn branch if plus - return itself
move.l #0,d7 return plus zero if was negative infinity
iefdrtn jmp iefrtd7 return the result that is in d7
* argument is normalized
iefnrm jsr ffpexp call fast floating point exponent function
jmp ieftieee and return in ieee format
end

View File

@@ -0,0 +1,292 @@
ttl ieee format front-end routines (ieffront)
ieffront idnt 1,1 ieee format equivalent front-end routines
******************************************
* (c) copyright 1981 by motorola inc. *
******************************************
*******************************************************
* idfsop (internal subroutine) *
* ieee format equivalent process single operand *
* *
* input: d7 - ieee format number argument2 *
* sp -> +0 return address to caller *
* +4 original caller's return address *
* *
* output: d6 converted to fast floating point *
* format with user's original registers *
* d3-d7 stacked or a direct return bypassing*
* the first-line routine if either *
* parameter was a nan *
* *
* *
* return is via vectored branch with offset added *
* to the address on the stack. this allows easy *
* type descrimination by the caller for selected *
* data types: *
* *
* return +0 if the argument is normalized *
* (including zero and denormalized) *
* +2 if argument is an infinity *
* *
* the stack appears: s+0 original d3-d7 upon entry*
* s+20 original caller's return *
* *
* condition codes: *
* *
* (only if bypassed return done) *
* *
* n - undefined *
* z - cleared *
* v - set (result is a nan) *
* c - undefined *
* x - undefined *
* *
* (only if return to immediate caller) *
* *
* n - set if value is negative *
* z - set if value is a zero *
* v - undeinfed *
* c - undefined *
* x - undefined *
* *
* this routine is a front end for the ieee format *
* capatible routines (ief routines). it may *
* bypass the caller to directly return to the user *
* code if the argument is a nan (not-a-number) *
* since the result must be a nan (the same). *
* the call to this routine must be the *
* first instruction of the level-1 ief routine, *
* since it may return directly to the original *
* caller. also registers must be unaltered before *
* the call. *
* *
* logic: the following decision tree shows the *
* processing for this routine and what *
* values are returned for the argument *
* *
* if arg is nan then *
* set the "v" bit in the ccr and bypass the *
* caller returning with arg (d7) unchanged *
* *
* if arg is an infinity then adjust return address *
* and return with ccr set for plus or minus *
* at offset +2 *
* *
* if arg is denormalized then set it to zero *
* else it is normalized - convert to ffp format*
* *
* return to caller at +0 offset *
* *
* notes: *
* 1) during the conversion of normalized ieee format *
* numbers to ffp format, the exponent may be too *
* large for ffp magnitudes. when this is true *
* then the value is converted to an infinity with *
* the proper sign. if the exponent is too small *
* than a zero is returned. see the mc68344 user's*
* guide for complete details of the range handling*
* of the fast floating point format conversion. *
* 2) all zeroes are treated as positive values. *
* 3) denormalized values are treated as zeroes. *
* *
*******************************************************
section 9
xdef iefsop single operand convert
expmsk equ $7f800000 ieee format exponent mask
vbit equ $0002 condition code "v" bit mask
cbit equ $0001 condition code "c" bit mask
* call internal subroutine to parse argument (d7)
iefsop lea -16(sp),sp adjust stack for new return address position
move.l 16(sp),-(sp) move return address to new location
movem.l d3-d7,4(sp) save original caller's registers
bsr.s iefprse convert argument two
bcc.s iefargs branch not infinity
move.w sr,d5 save ccr [vlh] was sr
add.l #2,(sp) adjust return address
move.w d5,ccr restore ccr
iefargs rts return to caller at proper offset
page
*******************************************************
* idfdop (internal subroutine) *
* ieee format equivalent process double operand *
* *
* input: d6 - ieee format number argument1 *
* d7 - ieee format number argument2 *
* sp -> +0 return address to caller *
* +4 original caller's return address *
* *
* output: d6/d7 converted to fast floating point *
* format with user's original registers *
* d3-d7 stacked or a direct return bypassing*
* the first-line routine if either *
* parameter was a nan *
* *
* *
* return is via vectored branch with offset added *
* to the address on the stack. this allows easy *
* type descrimination by the caller for selected *
* data types: *
* *
* return +0 if both arguments normalized *
* (including zero and denormalized) *
* +2 if arg2 is an infinity *
* +4 if arg1 is an infinity *
* +6 if both arguments are infinities *
* *
* the stack appears: s+0 original d3-d7 upon entry*
* s+20 original caller's return *
* *
* condition codes: *
* *
* (only if bypassed return done) *
* *
* n - undefined *
* z - cleared *
* v - set (result is a nan) *
* c - undefined *
* x - undefined *
* *
* (only if return directly to immediate caller) *
* *
* n - set if arg1 is negative *
* z - set if arg1 is zero *
* v - undefined *
* c - set if arg1 is an infinity *
* x - undefined *
* *
* this routine is a front end for the ieee format *
* capatible routines (ief routines). it may *
* bypass the caller to directly return to the user *
* code if an argument is a nan (not-a-number) *
* since the result must be a nan. it must be the *
* first instruction of the level-1 ief routine, *
* since it may return directly to the original *
* caller. also registers must be unaltered before *
* the call. *
* *
* logic: the following decision tree shows the *
* processing for this routine and what *
* values are returned for arg1 and arg2 *
* *
* if arg2 is nan then *
* set the "v" bit in the ccr and bypass the *
* caller returning with arg2 (d7) unchanged *
* *
* if arg1 is nan then *
* set the "v" bit in the ccr and bypass the *
* caller returning with arg1 copied to arg2 *
* *
* if arg2 is an infinity then adjust return address *
* *
* if arg1 is an infinity then adjust return address *
* *
* if arg2 is denormalized then set it to zero *
* else it is normalized - convert to ffp format*
* *
* if arg1 is denormalized then set it to zero *
* else it is normalized - convert to ffp format*
* *
* return to caller at proper offset *
* *
* notes: *
* 1) during the conversion of normalized ieee format *
* numbers to ffp format, the exponent may be too *
* large for ffp magnitudes. when this is true *
* then the value is converted to an infinity with *
* the proper sign. if the exponent is too small *
* than a zero is returned. see the mc68344 user's*
* guide for complete details of the range *
* treatment by the fast floating point conversion.*
* 2) all zeroes are treated as positive values. *
* 3) denormalized values are treated as zeroes. *
* *
*******************************************************
section 9
xdef iefdop dual operand convert
* call internal subroutine to parse argument 2 (d7)
iefdop lea -16(sp),sp reset stack for register storage
move.l 16(sp),-(sp) move return address to new bottom of stack
movem.l d3-d7,4(sp) save original registers above return address
bsr.s iefprse convert argument two
bcc.s iefarg2 branch not infinity
add.l #2,(sp) adjust return address
iefarg2 exg.l d6,d7 swap arguments to convert arg1 (nan returns arg1)
bsr.s iefprse convert second argument
bcc.s iefnoti branch not infinity
move.w sr,d5 save ccr [vlh] was sr
add.l #4,(sp) adjust return address
move.w d5,ccr restore ccr
iefnoti exg.l d6,d7 swap arguments back into place
rts return to caller
page
*
* internal convert subroutine
* convert the argument in d7 to fast floating point format and return
* ccr set for test against sign and zero
*
* output:
* if nan - direct return bypassing caller with nan in d7 and "v" set
* else return with converted value and "c" bit if is an infnity
*
iefprse move.l d7,d5 save original argument
swap.w d7 swap word halves
ror.l #7,d7 exponent to low byte
eor.b #$80,d7 convert from excess 127 to two's-complement
add.b d7,d7 from 8 to 7 bit exponent
bvs.s iefovf branch will not fit
add.b #2<<1+1,d7 adjust excess 127 to 64 and set mantissa high bit
bvs.s iefexh branch exponent too large (overflow)
eor.b #$80,d7 back to excess 64
ror.l #1,d7 to fast float representation
tst.b d7 clear carry
rts return to caller
* overflow detected - caused by one of the following:
* - false exponent overflow due to difference in excess notations
* - exponent too high or low to fit in 7 bits (exponent over/underflow)
* - an exponent of $ff representing an infinity
* - an exponent of $00 representing a zero, nan, or denormalized value
iefovf bcc.s iefovlw branch if overflow (exponent $ff or too large)
* check for false overflow
cmp.b #$7c,d7 ? will corrected value be ok
beq.s ieffov yes, branch if false overflow
cmp.b #$7e,d7 ? will corrected value be in range
bne.s iefnotf no, branch not false overflow
ieffov add.b #$80+2<<1+1,d7 back to excess 64 and set mantissa high bit
ror.l #1,d7 to fast floating point representation
tst.b d7 insure not illegal zero sign+exponent byte
bne.s iefcrt no, is ok so return "c" cleared
* exponent low - is zero, denormalized value, or too small an exponent
iefnotf move.l #0,d7 return zero for all of these cases ("c" cleared)
iefcrt rts return to caller
* exponent high - check for exponent too high, infinity, or nan
iefovlw cmp.b #$fe,d7 ? was original exponent $ff
bne.s iefexh no, branch exponent too large
lsr.l #8,d7 shift out exponent
lsr.l #1,d7 shift sign out into "x" bit
beq.s iefexhi branch if true infinity
* arg2 is a nan - bypass caller and return as the result with "v" bit set
move.l d5,d7 return original argument
add.l #8,sp skip internal and caller return addresses
movem.l (sp)+,d3-d6 return registers intact
add.l #4,sp skip original d7
or.b #vbit,ccr set v bit on [vlh]
rts return to original caller
* arg2 is infinity or exponent too large so force to infinity (sign is bit 8)
iefexh lsl.w #8,d7 set "x" ccr bit same as sign
iefexhi move.l #expmsk<<1,d7 set exponent all ones for infinity and over 1
roxr.l #1,d7 shift sign and and finished result
or.b #cbit,ccr set "c" bit on for infinity notice [vlh]
rts return to conversion routine
end

View File

@@ -0,0 +1,68 @@
ttl ieee format equivalent log (ieflog)
***************************************
* (c) copyright 1981 by motorola inc. *
***************************************
*************************************************
* ieflog *
* fast floating point logorithm *
* *
* input: d7 - ieee format input argument *
* *
* output: d7 - ieee format logorithmic result *
* *
* all other registers totally transparent *
* *
* condition codes: *
* z - set if result is zero *
* n - set if result is negative *
* v - set if result is nan (not-a-number)*
* (negative or nan argument) *
* c - undefined *
* x - undefined *
* *
* all other registers transparent *
* *
* maximum stack used: 54 bytes *
* *
* notes: *
* 1) see the mc68344 user's guide for details*
* concerning ieee format normalized range *
* support limitations. *
* 2) spot checks show relative errors bounded*
* by 5 x 10**-8. *
* 2) negative arguments are illegal and cause*
* a nan (not-a-number) to be returned. *
* 3) a zero argument returns minus infinity. *
* *
*************************************************
page
ieflog idnt 1,1 ieee format equivalent logorithm
opt pcs
section 9
xdef ieflog entry point
xref ffplog ffp logorithm routine
xref iefsop front-end operand conversion routine
xref ieftieee back-end convert to ieee and return
xref iefrtnan back-end return nan routine
xref iefrtod7 return original d7 from the caller
xref ffpcpyrt copyright stub
**************
* log entry *
**************
ieflog jsr iefsop convert the operand
bra.s iefnrm +0 branch normalized value
* input argument is infinity +8
bmi iefrtnan return a nan for a negative argument
jmp iefrtod7 return plus infinity as the result
* argument is normalized
iefnrm bmi iefrtnan return a nan if argument is negative
jsr ffplog call fast floating point log routine
jmp ieftieee and return result in ieee format
end

View File

@@ -0,0 +1,102 @@
ttl ieee format equivalent multiply (iefmul)
***************************************
* (c) copyright 1981 by motorola inc. *
***************************************
*************************************************************
* iefmul *
* fast floating point ieee format equivalent multiply *
* *
* iefmul - ieee format equivalent floating point multiply *
* *
* input: d6 - ieee format number multiplier (source) *
* d7 - ieee format number multiplican (destination)*
* *
* output: d7 - ieee format floating result of register d6 *
* multiplied by register d7 *
* *
* condition codes: *
* n - result is negative *
* z - result is zero *
* v - result is nan (not-a-number) *
* c - undefined *
* x - undefined *
* *
* all registers transparent *
* *
* maximum stack used: 24 bytes *
* *
* result matrix: arg 2 *
* normalized zero inf nan *
* arg 1 **************************************** *
* normalized * a * b * c * f * *
* zero * b * b * d * f * *
* infinity * c * d * c * f * *
* nan * e * e * e * f * *
* **************************************** *
* (denormalized values are treated as zeroes) *
* a = return multiply result, overflow to infinity, *
* underflow to zero *
* b = return zero *
* c = return infinity *
* d = return newly created nan (not-a-number) for *
* illegal operation
* e = return arg1 (nan) unchanged *
* f = return arg2 (nan) unchanged *
* *
* notes: *
* 1) zeroes and infinities are returned with proper *
* sign (exclusive or of input argument sign bits). *
* 2) see the mc68344 user's guide for a description of *
* the possible differences between the results *
* returned here versus those required by the *
* ieee standard. *
* *
*************************************************************
page
iefmul idnt 1,1 ieee format equivalent multiply
opt pcs
xdef iefmul ieee format equivalent multiply
xref iefdop double argument conversion routine
xref iefrtnan create and return nan result routine
xref ieftieee return and convert back to ieee format
xref iefrtie return signed infinity exclusive or'ed
xref iefrtsze return signed zero exclusive or'ed
xref ffpmul2 reference ffp perfect precision mult routine
xref ffpcpyrt copyright notice
section 9
***********************************************
* ieee format equivalent multiply entry point *
***********************************************
iefmul jsr iefdop decode both operands
jmp iefnrm +0 branch normalized
jmp iefinf2 +2 branch only arg2 infinity
jmp iefinf1 +4 branch only arg1 infinity
* both infinity, return proper sign +6 both are infinity
iefrtinf jmp iefrtie returne infinity with proper sign
* arg1 infinity - swap arguments and treat as arg2
iefinf1 exg.l d6,d7 swap for next code portion
* arg2 infinity - if opposite argument is zero than illegal and return nan
iefinf2 tst.l d6 ? is opposite argument a zero
bne.s iefrtinf no, go return infinity with proper sign
jmp iefrtnan yes, return a nan for this illegal operation
* normalized numbers(or zero) - do the multiply
iefnrm jsr ffpmul2 do fast floating point add
* bne ieftieee convert result back to ieee format
bne DOIT
jmp NOPE
DOIT jmp ieftieee * loader problems again
* result is zero so return zero with proper sign
NOPE jmp iefrtsze return zero with exclusively or'ed signed
end

View File

@@ -0,0 +1,60 @@
ttl ieee format equivalent power function(iefpwr)
***************************************
* (c) copyright 1981 by motorola inc. *
***************************************
*************************************************
* iefpwr *
* ieee format equivalent power function *
* *
* input: d6 - ieee format exponent value *
* d7 - ieee format argument value *
* *
* output: d7 - result of the value taken to *
* the power specified *
* *
* all registers are transparent *
* *
* maximum stack used: 52 bytes *
* *
* condition codes: *
* z - set if result is zero *
* n - cleared *
* v - set if result is nan (not-a-number)*
* (input argument negative or nan) *
* c - undefined *
* x - undefined *
* *
* notes: *
* 1) see the mc68344 user's guide for details*
* concerning limitations on normalized *
* argument ranges. *
* 2) a negative base value, or zero to a *
* negative power is invalid and returns *
* a nan with the "v" bit set. *
* 3) spot checks show at least six digit *
* precision for 80 percent of the cases. *
* *
*************************************************
page
iefpwr idnt 1,1 ieee format equivalent power function
opt pcs
section 9
xdef iefpwr entry point
xref ieflog ieee log function
xref iefmul ieee multiply routine
xref iefexp ieee exponent function
xref ffpcpyrt copyright stub
*****************
* power entry *
*****************
iefpwr jsr ieflog find low of base value
jsr iefmul multiply by the power
jmp iefexp finish with exponent result
end

View File

@@ -0,0 +1,110 @@
ttl ieee format equivalent (iefsin/iefcos/ieftan)
***************************************
* (c) copyright 1981 by motorola inc. *
***************************************
*************************************************
* iefsin iefcos ieftan *
* ieee format equivalent sine/cosine/tangent *
* *
* input: d7 - ieee format argument (radians) *
* *
* output: d7 - ieee format function result *
* *
* all other registers totally transparent *
* *
* maximum stack used: 54 bytes *
* *
* condition codes: *
* z - set if result in d7 is zero *
* n - set if result in d7 is negative *
* c - undefined *
* v - set if result is nan (not-a-number)*
* (input magnitude too large or nan) *
* x - undefined *
* *
* functions: *
* iefsin - sine result *
* iefcos - cosine result *
* ieftan - tangent result *
* *
* notes: *
* 1) input values are in radians. *
* 2) input arguments larger than two pi *
* suffer reduced precision. the larger *
* the argument, the smaller the precision.*
* excessively large arguments which have *
* less than 5 bits of precision are *
* returned as a nan with the "v" bit set. *
* 3) the sign of tangents with infinite *
* value is undefined, however we return *
* a positive infinity. *
* 4) spot checks show relative errors bounded*
* by 4 x 10**-7 but for arguments close to*
* pi/2 intervals where 10**-5 is seen. *
* *
*************************************************
page
iefsin idnt 1,1 ieee format equivalent sine/cosine/tangent
opt pcs
section 9
xdef iefsin,iefcos,ieftan entry points
xref ffpsin,ffpcos,ffptan ffp transcendentals
xref iefsop single operand front-ender
xref ieftieee back-end convert back to ieee format
xref iefrtnan back-end return ieee nan routine
xref ffpcpyrt copyright stub
vbit equ $0002 condition code register "v" bit mask
ffpsign equ.b $80 sign in fast floating point value
***********************
* tangent entry point *
***********************
ieftan jsr iefsop parse the operand
bra.s ieftnrm +0 branch not infinity or nan
jmp iefrtnan +2 return nan for infinity
* perform tangent function with normalized number
ieftnrm jsr ffptan find tangent
bra.s iefcmn enter common exit code
**********************
* cosine entry point *
**********************
iefcos jsr iefsop parse the operand
bra.s iefcnrm +0 branch not infinity or nan
jmp iefrtnan +2 return nan for infinity
* perform cosine function with normalized number
iefcnrm jsr ffpcos find cosine
bra.s iefcmn enter common exit code
********************
* sine entry point *
********************
iefsin jsr iefsop parse the operand
bra.s iefsnrm +0 branch not infinity or nan
jmp iefrtnan +2 return nan for infinity
* perform sine function with normalized number
iefsnrm jsr ffpsin find sine
iefcmn bvc ieftieee return if had enough precision
* overflow can mean true infinity result or not enough precision
* we can test for not enough precision by checking for largest possible value
move.l d7,d5 copy over ffp format result
or.b #ffpsign,d5 set sign bit to a one
sub.l #1,d5 test for all one bits
* bne iefrtnan no, not enough precision, return a nan
bne dobranch for 16-bit non-MMU problem
tst.b d7 reset ccr as it was
or.b #vbit,ccr and show overflow occured
jmp ieftieee restore with infinity of proper sign
dobranch:
jmp iefrtnan
end

View File

@@ -0,0 +1,134 @@
ttl ieee format equivalent hyperbolics (iefsinh)
***************************************
* (c) copyright 1981 by motorola inc. *
***************************************
*************************************************
* iefsinh/iefcosh/ieftanh *
* ieee equivalent floating point hyperbolics *
* *
* input: d7 - ieee format argument *
* *
* output: d7 - ieee format hyperbolic result *
* *
* all other registers are transparent *
* *
* maximum stack useage: 54 bytes *
* *
* calls: iefexp, iefdiv, iefadd and iefsub *
* *
* condition codes: *
* z - set if result is zero *
* n - set if result is negative *
* v - set if result is nan (not-a-number)*
* (returned if input was nan) *
* c - undefined *
* x - undefined *
* *
* notes: *
* 1) see the mc68344 user's guide for the *
* limitations on ieee format normalized *
* values. *
* 2) if the input argument is a nan, it will *
* be returned with the "v" bit set. *
* 3) spot checks show at least seven digit *
* precision. *
* *
*************************************************
page
iefsinh idnt 1,1 ieee format equivalent hyperbolics
opt pcs
section 9
xdef iefsinh,iefcosh,ieftanh entry points
xref iefexp,iefmul,iefdiv,iefadd,iefsub called
xref ffpcpyrt copyright stub
fpone equ $3f800000 floating one
fptwo equ $40000000 floating two
**********************************
* iefcosh *
* this function is defined as *
* x -x *
* e + e *
* -------- *
* 2 *
* we evaluate exactly as defined *
**********************************
iefcosh move.l d6,-(sp) save our work register
jsr iefexp evaluate e to the x
move.l d7,-(sp) save result
move.l d7,d6 setup for divide into one
move.l #fpone,d7 load floating point one
jsr iefdiv compute e to -x as the inverse
move.l (sp)+,d6 prepare to add together
jsr iefadd create the numerator
move.l #fptwo,d6 prepare to divide by two
jsr iefdiv divide by two
movem.l (sp)+,d6 restore work register
rts return to caller
page
**********************************
* iefsinh *
* this function is defined as *
* x -x *
* e - e *
* -------- *
* 2 *
* we evaluate exactly as defined *
**********************************
iefsinh move.l d6,-(sp) save our work register
jsr iefexp evaluate e to the x
move.l d7,-(sp) save result
move.l d7,d6 setup for divide into one
move.l #fpone,d7 load floating point one
jsr iefdiv compute e to -x as the inverse
move.l d7,d6 prepare to subtract
move.l (sp)+,d7 from first calculation
jsr iefsub create the numerator
move.l #fptwo,d6 prepare to divide by two
jsr iefdiv divide by two
movem.l (sp)+,d6 restore work register
rts return to caller
page
**********************************
* ieftanh *
* this function is defined as *
* sinh/cosh which reduces to: *
* 2x *
* e - 1 *
* ------ *
* 2x *
* e + 1 *
* *
* which we evaluate. *
**********************************
ieftanh move.l d6,-(sp) save our one work register
move.l #fptwo,d6 prepare to multiply times two
jsr iefmul get argument times two
jsr iefexp evaluate e to the 2x
move.l d7,-(sp) save result
move.l #fpone,d6 load floating point one
jsr iefadd add 1 to e**2x
move.l d7,-(sp) save denominator
move.l 4(sp),d7 now prepare to subtract
jsr iefsub create numerator
movem.l (sp)+,d6 restore denominator (keep ccr same)
bvs.s ieftrtn branch if nan here
cmp.l d6,d7 ***allow infinity by infinity to be one***
bne.s ieftdod branch to do divide if not same value
move.l #fpone,d7 result is a one
bra.s ieftrtn and return
ieftdod jsr iefdiv create result
ieftrtn add.l #4,sp free e**2x off of stack
movem.l (sp)+,d6 restore our work register
rts return to caller with answer and ccr set
end

View File

@@ -0,0 +1,86 @@
ttl ieee format equivalent square root (iefsqrt)
*******************************************
* (c) copyright 1981 by motorola inc. *
*******************************************
*************************************************
* iefsqrt *
* ieee format equivalent square root *
* *
* input: *
* d7 - ieee format argument *
* *
* output: *
* d7 - ieee format square root *
* *
* condition codes: *
* *
* if the result is valid - *
* n - cleared *
* z - set if result is zero *
* v - cleared *
* c - undefined *
* x - undefined *
* *
* if the result is invalid due to a *
* negative non-zero or nan input argument- *
* n - undefined *
* z - cleared *
* v - set *
* c - undefined *
* x - undefined *
* *
* all registers are transparent *
* *
* maximum stack used: 24 bytes *
* *
* notes: *
* 1) valid results are obtained unless *
* the input argument was a negative *
* non-zero number or nan (not-a- *
* number) which can be determined by *
* the "v" bit setting in the ccr. *
* 2) see the mc68344 user's guide for *
* details on the ranges handled by *
* the fast floating point equivalent *
* routines. *
* *
*************************************************
page
iefsqrt idnt 1,1 ieee format equivalent square root
section 9
xdef iefsqrt entry point
xref ffpsqrt fast floating point square root routine
xref iefsop single operand front-end handler
xref ieftieee back-end handler to return ieee format
xref iefrtnan error handler to return a nan (not-a-number)
xref iefrtod7 return original caller's d7
xref ffpcpyrt copyright notice
*********************
* square root entry *
*********************
iefsqrt jsr iefsop convert the operand
bra.s iefnrm branch both normalized
* argument was infinity - return a nan if minus
* bmi iefrtnan return nan if it is minus infinity
bmi dobranch
jmp iefrtod7 just return input argument if plus infinity
* argument was normalized
* iefnrm bmi iefrtnan return nan for invalid negative argument
iefnrm bmi dobranch
move.l 16(sp),d5 insure was not a negative very small number
bpl.s iefsdoit branch was positive
add.l d5,d5 rid sign byte to check if was negative zero
* bne iefrtnan return nan for very small negative numbers also
bne dobranch
iefsdoit jsr ffpsqrt perform square root
jmp ieftieee and return ieee format back to caller
dobranch:
jmp iefrtnan 16-bit no MMU stuff
end

View File

@@ -0,0 +1,49 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
/*char *version "@(#)ltof.c 1.2 10/19/83"; */
/*
* Floating Point Long to Float Routine :
* Front End to IEEE Floating Point Package.
*
* double
* fpltof(larg)
* long larg;
*
* Return : Floating Point representation of Long Fixed point integer
*/
#define BIAS 127L
long
fpltof(l)
long l;
{
register long exp;
register int sign;
if (l < 0L) { /* signed ?? */
sign = 1;
l = -l;
}
else
sign = 0;
if (l == 0L)
return(0L);
exp = 23L;
for( ; l & 0x7f000000; exp++) /* something in upper 7 bits */
l =>> 1;
for( ; !(l & 0x00800000); exp--) /* get mantissa : 1.F */
l =<< 1;
l =& 0x007fffff; /* reduce to .F in 23 bits */
if (sign)
l =| 0x80000000;
exp = (exp + BIAS)<<23;
l =| exp;
return(l);
}

View File

@@ -0,0 +1,300 @@
/*
Copyright 1983
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
@(#)printf.c 1.2 10/19/83
*/
#include <stdio.h>
struct {
int word0;
int word1;
};
#define BUFSIZ 80
FILE *__stream;
static char *__str;
static char **_p;
extern char *__prtshort(), *__prtld();
char *etoa();
char *ftoa();
char *petoa();
char *pftoa();
printf(arg1,arg2,arg3)
char *arg1, *arg2, *arg3;
{
FILE *fp;
if( arg1 == -1 ) {
/*
* printf( ((char *)-1), buf, fmt...) is sprintf(buf, fmt...)
*/
__str = arg2;
_p = &arg3;
*__str = NULL;
__doprint(1);
*__str = NULL;
}
else if( arg1 < _NUFILE ) {
/*
* printf( ((char *)fd), fmt...) is fprintf( fd to fp, fmt,...)
*/
fp = fdopen( (arg1).word1 , "w");
__stream = fp;
_p = &arg2;
__doprintf(0);
fflush(fp);
fp->_flag = 0;
fp->_nextp = fp->_base = NULL;
}
else {
__stream = stdout;
_p = &arg1;
__doprintf(0);
}
}
fprintf(fp, plist)
FILE *fp;
char *plist;
{
if( (fp->_flag&(_WMODE|_UPDATE|_APPEND)) == 0 )
return;
__stream = fp;
_p = &plist;
__doprintf(0);
}
sprintf(s, plist)
char *s, *plist;
{
__str = s;
_p = &plist;
__doprint(1);
*__str = NULL;
}
__doprint(mode)
int mode;
{
register char *fmt, c;
register int *pi;
char buf[BUFSIZ];
int width, prec, left, longf, n, len, prepend;
char padchar;
char *s;
auto (*fn)();
fmt = *_p++;
pi = _p;
while( c = *fmt++ ) {
_p = pi;
if( c != '%' ) {
__putch(mode, c);
continue;
}
prepend = left = 0;
if( (c = *fmt++) == '-' ) {
c = *fmt++;
left++;
}
if (c == '#') { /* [vlh] 26 jul 83 */
c = *fmt++;
prepend++;
}
padchar = ' ';
if( c == '0' ) {
padchar = c;
c = *fmt++;
}
width = -1;
while( c >= '0' && c <= '9' ) {
if( width < 0 )
width = 0;
width = width * 10 + (c - '0');
c = *fmt++;
}
if (c == '*') { /* [vlh] 26 jul 83 */
c = *fmt++;
width = *pi++;
}
prec = -1;
if( c == '.' ) {
prec = 0;
c = *fmt++;
}
while( c >= '0' && c <= '9' ) {
prec = prec * 10 + (c - '0');
c = *fmt++;
}
if (c == '*') { /* [vlh] 26 jul 83 */
c = *fmt++;
prec = *pi++;
}
longf = 0;
if( c == 'l' ) {
longf++;
c = *fmt++;
}
/*
* we now have all the prelims out of the way;
* let's see what we want to print
*/
s = buf;
switch (c) {
case 'd': /* decimal signed */
case 'D':
if( longf )
fn = __prtld;
else
fn = __prtshort;
__prtint(pi++, buf, 10, 1, fn, 0);
if( longf )
pi++;
break;
case 'u': /* decimal unsigned */
case 'U':
__prtint(pi++, buf, 10, 0, __prtshort, 0);
break;
case 'o': /* octal unsigned */
case 'O':
if (prepend) /* [vlh] 26 jul 83 */
__putch(mode, '0');
if( longf )
fn = __prtld;
else
fn = __prtshort;
__prtint(pi++, buf, 8, 0, fn, 0);
if( longf )
pi++;
break;
case 'x': /* hexadecimal unsigned */
case 'X':
if (prepend) { /* [vlh] 26 jul 83 */
__putch(mode, '0');
__putch(mode, 'x');
}
if( longf )
fn = __prtld;
else
fn = __prtshort;
__prtint(pi++, buf, 16, 0, fn, c == 'X');
if( longf )
pi++;
break;
case 's': /* string */
case 'S':
s = *_p++;
pi = _p;
break;
case 'c': /* character */
case 'C':
n = *pi++;
buf[0] = n;
buf[1] = '\0';
break;
case 'e': /* exponential */
case 'E':
petoa(pi, buf, prec);
pi += 2;
prec = -1;
break;
case 'f': /* floating */
case 'F':
pftoa(pi, buf, prec);
pi += 2;
prec = -1;
break;
case 'g': /* e or f */
case 'G':
pftoa(pi, buf, prec);
if (strlen(buf) > (7 + prec) ) /* smallest fp string */
petoa(pi, buf, prec);
pi += 2;
prec = -1;
break;
default: /* just print the character */
__putch(mode, c);
continue;
}
len = __length(s);
if( prec < len && prec >= 0 )
len = prec;
n = width - len;
if( !left ) {
if( padchar != ' ' && *s == '-' ) {
len--;
__putch(mode, *s++);
}
while( n-- > 0 )
__putch(mode, padchar);
}
while( len-- )
__putch(mode, *s++);
while( n-- > 0 )
__putch(mode, padchar);
}
if( mode == 0 && (__stream->_flag&_UNBUF) )
fflush(__stream);
}
__putch(mode, c)
int mode;
char c;
{
if( mode )
*__str++ = c;
else
putc(c,__stream);
return (c);
}
char *
pftoa(addr,buf,prec)
float *addr;
char *buf;
int prec;
{
float fp;
if (prec<0)
prec = 6;
fp = *addr;
return( ftoa(fp, buf, prec) );
}
char *
petoa(addr,buf,prec)
float *addr;
char *buf;
int prec;
{
float fp;
if (prec<0)
prec = 6;
fp = *addr;
return( etoa(fp, buf, prec) );
}

View File

@@ -0,0 +1,25 @@
*
* Floating Point Hyperbolic sine:
* Front End to FFP Floating Point Package.
*
* double
* sinh(farg)
* double farg;
*
* Returns : negated Floating point number
*
.globl _sinh
.globl iefsinh
.text
fpsinh:
_sinh:
~~sinh:
link r14,#-4
move.l d7,-(sp)
move.l 8(r14),r7
jsr iefsinh
move.l r7,r0
move.l (sp)+,d7
unlk r14
rts

View File

@@ -0,0 +1,25 @@
*
* Floating Point Hyperbolic tangent:
* Front End to FFP Floating Point Package.
*
* double
* tanh(farg)
* double farg;
*
* Returns : negated Floating point number
*
.globl _tanh
.globl ieftanh
.text
fptanh:
_tanh:
~~tanh:
link r14,#-4
move.l d7,-(sp)
move.l 8(r14),r7
jsr ieftanh
move.l r7,r0
move.l (sp)+,d7
unlk r14
rts