ALREM S BLIVOT S LDIV S LMUL S FPNEG S FPPWR S FPSIN S FPSQRT S FFPPWR S |}~FFPSIN S rFFPSINH S 8FFPSQRT S +ATAN S 3ETOA C 45ATOF C 678CEIL C 9R14),R9 move.l R0,(R9) unlk R14 rts (R14),R8 move.l (R8),-(sp) jsr _ldiv cmpm.l (sp)+,(sp)+ move.l _ldivr,R0 move.l 8(LREM S S S " SETJMP S SIGNAL C FPSUB S FSCANF C WFTOFFP C FTOL C FFPTHETAS FFPTNORMS FFPTOF C FLOOR C COSH S :FABS C ;FFPABS S <=>?FFPADD S M@ABCDEFGHI14),R9 move.l R0,(R9) unlk R14 rts (R14),R8 move.l (R8),-(sp) jsr _ldiv cmpm.l (sp)+,(sp)+ move.l _ldivr,R0 move.l 8(ULDIV S SALLOC S XSIGNAL S CPM H Y !"#$%&LTOF C SINH S TANH S MAKE SUBFMOD C FPADD S FPCMP S FPCOS S  .globl _sw_ _sw_: .text tst.l d5 beq ok move.l #-1,(sp) * Destroy the evidence divs #$0,d5 ok: rts *************FFPATAN S 2JKLMNOPFFPCMP S $QRSTUFFPCPYRTS VWFFPDIV S message move.l a0,d1 * load proper reg trap #2 * Issue message __exit: move.w #exit,d0100(a0),a0 * Chicken factor cmpa.l a0,sp * Compare bhis brkok * OK, continue move.l #-1,d0 * Load return reg * move.l a0,d0 * Found it subq.l #1,d0 * set return pointer rts * * * Data area * .data .globl ___ lea.l command(a0),a2 * a2 -> command line move.b (a2)+,d0 * d0 = byte count andi.l #$ff,d0 * clear junk move.w d0 le fillit: move.b d1,(a0)+ * move a byte dbra d0,fillit * Continue filldone: clr.l d0 * always return 0 rts * ound ID .dc.b 'CLEAR68K V02.00, Copyright(c) 1984, Digital Research ' serial: .dc.b 'XXXX-0000-654321' * serial number . * Exit trap #2 * now noovf: * Here if all OK unlk a6 * rts * Back to caller * * Block Fill function: rts * Return brkok: move.l d0,__break * Save the break clr.l d0 * Set OK return rts * return .globl ___pname * Program Name .globl ___tname * Terminal Name .globl ___lname * List device name .globl ___xeof * ^Z byte ,-(a7) * push length move.l a2,-(a7) * Push commnd clr.l a6 * Clear frame pointer jsr __main * call main routine * * Index function to find out if a particular character is in a string. * .globl _index .globl _strchr _index: _strceven start: move.l 4(a7),a0 * a0 -> Base page move.l a0,__base * Load C external move.l lbss(a0),a1 * a1 -> bss regio * * blkfill(dest,char,cnt); * * BYTE *dest; /* -> area to be filled */ * BYTE char; /* = char to fill */ * WORD cnt; /BDOS ___BDOS: link a6,#0 * link move.w 8(sp),d0 * Load func code move.l 10(sp),d1 * Load Paramter trap #2 * Enteovf: .dc.b 'Stack Overflow$' * Error message ___pname: .dc.b 'C runtime',0 * Program name ___tname: .dc.b 'CON:',0 * Consol jmp __exit * call "exit" * * .bss __base: .ds.l 1 * -> Base Page __break: .ds.l 1 * Break function ___cpmrv: .hr: move.l 4(a7),a0 * a0 -> String move.w 8(a7),d0 * D0 = desired character xindex: tst.b (a0) * EOS? bne notend n * move.l a1,a3 * Save it adda.l bsslen(a0),a1 * a1 -> 1st heap loc xclear: * Clear heap area * clr.w (a3)+ ** = # bytes to fill */ * .globl _blkfill _blkfill: move.l 4(a7),a0 * -> Output area move.w 8(a7),d1 * = output cr BDOS cmpa.l __break,sp * Check for stack ovf bhis noovf * NO overflow, continue __sovf: move.w #prtstr,d0 * Stringe name ___lname: .dc.b 'LST:',0 * List device name ___xeof: .dc.b $1a * Control-Z .end ds.w 1 * Last CP/M return val * * .globl _brk .text _brk: movea.l 4(sp),a0 * New break? move.l a0,d0 lea $ * No, continue to look clr.l d0 * Not found rts * Quit notend: cmp.b (a0)+,d0 * check for character bne xindex Clear a word * cmpa.l a3,sp * See if done * bhi xclear * Not yet, continue move.l a1,__break * Put in "break" loc har move.w 10(a7),d0 * = output count ext.l d0 * make it long subq.l #1,d0 * decrement ble filldone * Done if name ___lname: .dc.b 'LST:',0 * List device name ___xeof: .dc.b $1a * Control-Z .end ase ... movea.l (a0)+,a7 * Reset stack movea.l (a0)+,a6 * Reset frame move.l (a0)+,(a7) * Load TOS with return addr mp * do longjump * _setjmp: * Save environment movea.l 4(a7),a0 * a0 -> Environment buffer move.l a7,(a0)+ * Stack po name ___lname: .dc.b 'LST:',0 * List device name ___xeof: .dc.b $1a * Control-Z .end ovem.l (a0),d2-d7/a2-a5 * Restore register variables rts * and return  move.l (a0)+,(a7) * Load TOS with return addr minter to first long move.l a6,(a0)+ * Frame pointer to second long move.l (a7),(a0)+ * Return address to third long movevem.l (a0),d2-d7/a2-a5 * Restore register variables rts * and return  move.l (a0)+,(a7) * Load TOS with return addr mm.l d2-d7/a2-a5,(a0) * Save register variables clr.l d0 * Return 0 value rts * Return to caller * _longjmp: * Retu/****************************************************************************/ /* */ /* S i g n a l F u n c t vem.l (a0),d2-d7/a2-a5 * Restore register variables rts * and return  move.l (a0)+,(a7) * Load TOS with return addr mrn to saved point movea.l 4(a7),a0 * a0 -> Environment buffer move.w 8(a7),d0 * Load return value ext.l d0 * just in ci o n */ /* ----------------------------- */ /* */ /* The "signal" function allows a routine in C t* * Setjmp / longjmp implementation. See file "setjmp.h" for details. * .globl _setjmp * Set up longjump .globl _longjmo catch a 68000 */ /* interrupt, and service it with a C function. */ /* */ /* Calling Sequence: ,&_illinst); /* Privilege violation */ _setvec(10,&_illinst); /* Set vector #10 (line A) */ _setvec(11,&_illinst); T (*func)(); /* Function address */ { /* */ REG WORD i; /* Temp */ /* */ if(sig >= NSvector,func) /****************************/ WORD vector; /* Vector # */ BYTE *func; /* Function address */ */ /****************************/ EXTERN WORD *_illinst(); /* -> Illegal instruction ep*/ EXTERN WORD *_trace(); /*USERR PDP-11 trap 4 & 10*/ _setvec(2,&_buserr); /* Set nxm vector */ _setvec(3,&_buserr); /* Set addressing vector */ /* */ /* ret = signal(sig,func); */ /* */ /* Where: */ /* ret Is always /* Set vector #11 (line F) */ break; /****************************/ /* */ case SIGTRAP: /* Trace trapIG || sig < 0) /* Too big? */ return(BADSIG); /* Yes, return UNIX NFG code*/ /****************************/ { /****************************/ struct { /* A CP/M EPB structure */ WORD vec; /* Vector number */ BYT -> Trace trap epa */ EXTERN WORD *_trap(); /* -> TRAP instruction epa */ EXTERN WORD *_buserr(); /* -> BUSERR epa */ break; /****************************/ /* */ case SIGFPE: /* Arithmetic section */ for(i=5; 0 under CP/M. */ /* sig Is the UNIX signal number */ /* func -> the function to service the exception */ */ _setvec(9,&_trace); /* Set vector #9 */ break; /****************************/ /* */ case__signal[sig] = func; /* Save the function addr */ /* */ switch(sig) /* Do signal processing */ { E *userepa; /* User's epa */ BYTE *bdosepa; /* BDOS's epa */ } epb; /****************************/ epb.ve */ EXTERN WORD *_arith(); /* -> Arithmetic traps epa */ EXTERN BYTE *__signal[NSIG]; /* Holds user func addresses*/ i<8; i++) /* Set all misc vectors */ _setvec(i,&_arith); /* */ break; /****************************/ /* */ /****************************************************************************/ #include /* Incl SIGIOT: /* Bad TRAP instruction */ _setvec(32,&_trap); /* Trap 0 */ for(i=35; i<48; i++) /* Traps 4 - 15 /* */ case SIGILL: /* Illegal instruction */ _setvec( 4,&_illinst); /* Set vector #4 */ _setvec( 8c = vector; /* Set up vector */ epb.userepa = func; /* and function */ epb.bdosepa = 0L; /* Clear return word /* */ LONG signal(sig,func) /****************************/ REG DEFAULT sig; /* Signal number */ REG DEFAUL /* */ } /* */ return(0L); /* Return OK */ } /****************************/ VOID _setvec(ude standard stuff */ #include /* Include definitions */ #include /* Include BDOS Functions */ _setvec(i,&_trap); /* */ break; /****************************/ /* */ case SIGBUS: /* B */ __BDOS(SETVEC,&epb); /* Do it. */ } /****************************/ l R3-R7,-(sp) *line 20 move.l 8(R14),R7 *line 21 move.l 12(R14),R6 *line 22 tst.l R6 bne L2 *line 23 move.l #$80000000,(blt->blo) **/ * if( l2 > (l2<<1) ) /** comparison (bgt->bhi) **/ * break; /* detect overflow */ * l2 =<< 1; * b =<<*line 53 move.l R5,R0 bra L1 L1:tst.l (sp)+ movem.l (sp)+,R4-R7 unlk R14 rts .data LCYON * register long l1,l2; * /* you must modify comparisons in the assembler file * * for this routine to work. * */ *e 42 clr.l R5 L9: *line 43 tst.l R4 beq L8 *line 44 cmp.l R6,R7 blo L10 *<<<< blt *line 45 or.l R4,R5 *line 46 sub */ __BDOS(SETVEC,&epb); /* Do it. */ } /****************************/ _uldivr *line 24 move.l #$80000000,R0 divu #0,R0 *<<<<< cause divide by zero trap whf 3/7/84 bra L1 L2: *line 26 cmp.l 1; * } * q = 0; * while(b) { /* now do shifts and subtracts */ * if(l1>=l2) { /** comparison (blt->blo) **/ * q =| b#else * register unsigned long l1, l2; *#endif * register long q, b; * * l1 = al1; * l2 = al2; * if(l2==0) { * uldivr =.l R6,R7 L10: *line 48 lsr.l #1,R4 *<<<< asr *line 49 lsr.l #1,R6 *<<<< asr bra L9 L8:L5: *line 52 move.l R7,_uldivr  */ __BDOS(SETVEC,&epb); /* Do it. */ } /****************************/  R7,R6 bls L3 *<<<<< ble *line 27 move.l R7,_uldivr *line 28 clr.l R0 bra L1 L3: *line 30 cmp.l R6,R7 bne L4 *line ; * l1 =- l2; * } * b =>> 1; * l2 =>> 1; * } *doret: * uldivr = l1; * return(q); *} * * .globl _uldivr .data 0x80000000; * return(0x80000000); * } * if(l2 > l1) { /** comparison (ble->bls) **/ * uldivr = l1; * return(0); * } *line 53 move.l R5,R0 bra L1 L1:tst.l (sp)+ movem.l (sp)+,R4-R7 unlk R14 rts .data 31 move.l #1,R5 *line 32 clr.l R7 bra L5 L4: *line 35 move.l #1,R4 L7: *line 36 cmp.l R6,R7 blo L6 *<<<< blt *line_uldivr: .dc.w 0,0 .globl _uldiv .text _uldiv: ~~uldiv: ~b=R4 ~q=R5 ~l1=R7 ~l2=R6 ~al1=8 ~al2=12 link R14,#0 movem. * if(l1==l2) { * q = 1; * l1 = 0; * goto doret; * } * b = 1; /* bit value */ * while(l1>=l2) { /** comparison *line 53 move.l R5,R0 bra L1 L1:tst.l (sp)+ movem.l (sp)+,R4-R7 unlk R14 rts .data *#include *long uldivr = 0; * * *long uldiv(al1,al2) /* unsigned long divide */ *long al1,al2; *{ * *#ifdef A 38 move.l R6,R0 asl.l #1,R0 cmp.l R0,R6 bhi L6 *<<<< bgt *line 39 asl.l #1,R6 *line 40 asl.l #1,R4 bra L7 L6: *lin * and "return" *  .globl __trace * Trace Trap EPA .globl __trap * All trap instructions .globl __buserr * BUSERR, addressing EPAaddq.l #1+4,d0 * Round bclr.l #0,d0 * up to word move.l __break,a1 * a1 -> break area lea $100(a1),a1 * Add ch****************************************************************************** * * Assembly language interface to signal proce * and "return" *  .globl __arith * Arithmetic traps EPA .comm ___signal,64 * -> epa's of C functions .bss * Ugh! epa: .ds.l 1 icken factor lea 0(a1,d0.l),a1 * And size cmpa.l a1,sp * OK? bhi ok *sw Overflow, die jmp __sovf *sw Jump to ssing in C. * * Majority of work is done by "signal.c". All we do is take the * exception and call the proper C function. R* * _salloc function. * * This function allocates a data area on the stack. * * Calling Sequence: * * adr = _salloc(siz * non-reentrant!! .text __illinst: * move.l ___signal+16,epa * Set up epa add.l #2,2(a7) * Bump PC to next inst berror in s.o ok: sub.l d0,sp * allocate lea 4(sp),a1 * a1 -> area start move.l a1,d0 * set return code jmp (a0) egisters, condition * codes, etc. are all preserved. A return from the function causes * resumption of normal processing. * e); * * Returns the address of the area allocated. * * Pulled out of 'w.s' 1/84 whf * Fixed 2/84 sw * .globl __salloc _ra process * Process exception __trace: move.l ___signal+20,epa * Set up epa bra process * process __trap: * m * and "return" *  ****************************************************************************** .globl __illinst * Illegal instruction EPA _salloc: move.l (sp)+,a0 * Save return address clr.l d0 * Zap d0 high word move.w (sp)+,d0 * Get arg (word size) ove.l ___signal+24,epa * Select epa bra process * __buserr: * Here for buserr crap cmpm.l (a7)+,(a7)+ * Prune junk rsefn() return * 25-June-83 sw Add user number to file "fd" structure. * * This file contains O.S. speci ----------- * Copyright 1982,1983 by Digital Research Inc. All rights reserved. * * Edits: Plus) */ #define CPM4 0 /* CP/M version 4.x (Portable Concurrent) */ #define UNIX 0 /* UNIX */ #define VMS 0 /* DEC VMS */ * Resume processing ar out a6 jsr (a0) * Call processing routine movem.l (sp)+,d0-d7/a0-a6 * restore registers rtr ola 68000 */ #define CPM68K 1 /* CP/M 68000 ver 2.2 */ #define CPM 1 /* CP/M version 2.2 */ #define ALCYON 1 /* Alcyon C Comp move.l ___signal+40,epa * move in epa bra process * process exception __arith: * move.l ___signal+32,epa * move ific definitions for the * DRI CLEAR/C Run Time Library. * This file is intended only for inclusion with those * 17-Jan-84 whf Moved to 68K * 5-Jan-84 whf Moved MAXCCBS to channel.c * 29-Dec-83 whf Add F_TRUNC for tclose() /*** Compiler ***/ #define DRC 0 /* Digital Research C Compiler */ /*#endif */ /**********************/ /********* Resume processing ar out a6 jsr (a0) * Call processing routine movem.l (sp)+,d0-d7/a0-a6 * restore registers rtr iler */ /*#ifdef UNdefined*/ /* Unused DEFINEs */ /*** Processor ***/ #define I8086 0 /* Intel 8086/8088 */ #definen epa process: * Here to process exception movem.l d0-d7/a0-a6,-(sp) * Save all registers move.l epa,a0 * Load entry pfunctions * dealing directly with the O.S. interface, as well as any function * which has hardware dependent code (byt * 12-Dec-83 whf Change from "CPM.H" to "OSIF.H" * 9-Dec-83 whf Handle PCDOS differences * 3-Nov-83 whf Ad******************************************************************** * CP/M FCB definition ********************************* VAX 0 /* DEC VAX */ #define PDP11 0 /* DEC PDP-11 */ #define Z8000 0 /* Zilog Z8000 */ /*** Operating System ***/ #deoint clr.l a6 * Clear out a6 jsr (a0) * Call processing routine movem.l (sp)+,d0-d7/a0-a6 * restore registers rtr e storage order, for * instance). * ***********************************************************d multi-sector i/o * 19-Oct-83 whf Add QUEUE handling info * 6-Oct-83 whf Redefine reserved area in fcb for pa*******************************************/ #if CPM /****************************/ struct fcbtab /******************/*************************************************************************** * * O S I F . H * fine PCDOS 0 /* IBM PC DOS */ #define CCPM 0 /* Concurrent (multi-tasking) */ #define CPM3 0 /* CP/M version 3.x (Concurrent & * Resume processing ar out a6 jsr (a0) * Call processing routine movem.l (sp)+,d0-d7/a0-a6 * restore registers rtr *****************/ /* * "machine.h": to determine what kind of machine you want to run on. */ #define MC68000 1 /* Motor**********/ { /* */ BYTE drive; /* Disk drive field [0] */ BYTE fname[8]; /* File name [1-8] */ B/* to obtain nsecs on err */ /****************************/ /******************************************************ORD fcb_lrecsiz; /* Logical record size[14-15]*/ LONG fcb_filsiz; /* Num bytes in file [16-19]*/ WORD fcb_date; /* Las definition */ #define NULLFD ((FD *)0) /* NULLPTRs for FD */ /************************************/ /* Flags /****************************/ /**************************************************************************** * PC-DOS FC /*sw Flags byte */ BYTE user; /*sw User # */ BYTE chan; /* Channel number being used */ LONG offset; YTE ftype[3]; /* File type [9-11] */ BYTE extent; /* Current extent number[12]*/ BYTE s1,s2; /* "system reserved**********************/ /* */ /* Channel Control Block (CCB) */ /* */ /* One CCB is allocatet updated [20-21] */ BYTE fcb_resvd[10]; /* System reserved [22-31] */ BYTE fcb_currec; /* Rel Rec# within curblk[3word bit definitions */ /************************************/ #define OPENED 0x01 /* Channel is OPEN */ B definition ****************************************************************************/ #if PCDOS /******************* /* File offset word (bytes) */ LONG sector; /* Sector currently in buffer */ LONG hiwater; /* High water mark " [13-14]*/ BYTE reccnt; /* Record counter [15] */ BYTE fpasswd[8]; /* Parsefn passwd area[16-23]*/ BYTE fuser; d (statically) for each of the 16 possible open */ /* files under C (including STDIN, STDOUT, STDERR). Permanent data */ 2]*/ LONG record; /* Rel Rec# from bgn file */ /* [33-36] depends on lrecsiz*/ }; /*************************#define ISTTY 0x02 /* Channel open to TTT */ #define ISLPT 0x04 /* Channel open to LPT */ #define ISREAD 0x08 /**********/ struct fcbtab { /****************************/ BYTE drive; /* Disk drive field [0] */ BYTE fname[8]; */ struct fcbtab fcb; /* File FCB (may have TTY info)*/ BYTE buffer[SECSIZ]; /* Read/write buffer */ }; /******** /* Parsefn user# area [24] */ BYTE resvd[7]; /* More "system reserved" */ LONG record; /* Note -- we overlap [32-3/* regarding the channel is kept here. */ /* */ /* */ /******************************************/ #endif /****************************/ /* */ #define SECSIZ 128 /* size of CP/M sector */ Channel open readonly */ #define ISASCII 0x10 /* ASCII file attached */ #define ATEOF 0x20 /* End of file encount /* File name [1-8] */ BYTE ftype[3]; /* File type [9-11] */ WORD fcb_curblk; /* Curr 128 byte blk [12-13]*/ W****************************/ extern struct ccb _fds[]; /* */ /* Declare storage */ #define FD struct ccb /* FD Type6]*/ /* current record field to */ /* make this useful. */ }; /****************************/ #endif *************************************/ struct ccb /************************************/ { /* */ WORD flags;ered */ #define DIRTY 0x40 /* Buffer needs writing */ #define ISSPTTY 0x80 /* Special tty info */ #define ISA/ #define OPEN 15 /* OPEN a disk file */ #define CLOSE 16 /* Close a disk file */ #define SEARCHF 17 /* Sear* DRC does it this way */ #endif /* */ #if CPM /****************************/ #define EXIT 0 /* Exit ut */ #define LSTOUT 5 /* Direct list device output*/ #define CONIO 6 /* Direct console I/O */ #define C_WRITE i o n s */ /* ------------------------------------------------- */ /* */ /* Following are OSIF functioni-Sector Count */ #define P_CHAIN 47 /* Program Chain */ #define SETVEC 61 /* Set exception vector */ #defineUX 0x100 /*sw Auxiliary device */ #define ISQUE 0x0200 /*whf Queue device */ /******************************ch for first */ #define SEARCHN 18 /* Search for next */ #define DELETE 19 /* Delete a disk file */ #defineto BDOS */ #define CONIN 1 /* direct echoing con input */ #define CONOUT 2 /* Direct console output */ #definSTR 9 /* Console string output */ #define CONBUF 10 /* Read console buffer */ #define OPEN 15 /* OPEN a disk fi definitions used by the C runtime */ /* library. */ /* */ /************************************** N_NETSTAT 68 /* Get Network Status */ #define F_TRUNC 99 /* Truncate File function */ #define S_OSVER 163 /* Ge******/ #define READ 0 /* Read mode parameter for open */ #define WRITE 1 /* Write mode */ /* CCB manipulatio CREATE 22 /* Create a disk file */ #define F_RENAME 23 /* Rename a disk file */ #define SETDMA 26 /* Set DMA e LSTOUT 5 /* Direct list device output*/ #define CONIO 6 /* Direct console I/O */ #define C_WRITESTR 9 /* Console */ #define CLOSE 16 /* Close a disk file */ #define SEARCHF 17 /* Search for first */ #define SEARCHN 18**************************************/ /****************************/ #if CPM68K /* */ #define __OSIF(fn,at OS Version Number */ #endif /****************************/ #if PCDOS /****************************/ #define EXIn macros *************************************/ #define _getccb(i) (&_fds[i]) /* Get CCB addr */ /***************address */ #define USER 32 /*sw Get / set user number */ #define B_READ 33 /* Read Random record */ #define B_le string output */ #define CONBUF 10 /* Read console buffer */ #define S_BDOSVER 12 /* Get System BDOS Ver Num * /* Search for next */ #define DELETE 19 /* Delete a disk file */ #define CREATE 22 /* Create a disk file rg) __BDOS((fn),(LONG)(arg)) /* CPM68K does it this way */ #else /* */ #define __OSIF(fn,arg) __BDOS((fn),(arg)) /T 0 /* Exit to BDOS */ #define CONIN 1 /* direct echoing con input */ #define CONOUT 2 /* Direct console outp*************************************************************/ /* */ /* O S I F F u n c t i o n D e f i n i tWRITE 34 /* Write Random record */ #define FILSIZ 35 /* Compute File Size */ #define F_MULTISEC 44 /* Set Mult */ #define F_RENAME 23 /* Rename a disk file */ #define SETDMA 26 /* Set DMA address */ #define B_READ 33 /*use on */ BYTE lblolo; /* PDP-11, VAX, 8086,... */ BYTE lblohi; /* */ BYTE lbhilo; /* */ BYT /* Hi/Lo storage used in */ struct long_struct{ /* 68K */ BYTE lbhihi; /* Use this for accessing */ BYTof file character-^Z */ /****************************/ /*************************************************************************************/  Read Random record */ #define B_WRITE 34 /* Write Random record */ #define FILSIZ 35 /* Compute File Size *E lbhihi; /* */ }; /* */ struct word_struct{ /* */ WORD lwlo; /* */ WORD lwhi; /*E lbhilo; /* ordered bytes in 32 bit*/ BYTE lblohi; /* LONG qtys. */ BYTE lblolo; /* */ }; /* ***************/ /* Hardware dependencies */ /***********************************************************************/ #endif /****************************/ /****************************************************************************/ / */ }; /* */ #endif /****************************/ /*************************** end of osif.h ********* */ struct word_struct{ /* Use this for accessing */ WORD lwhi; /* ordered words in 32 bit*/ WORD lwlo; /*****/ /****************************/ #if MC68000 | Z8000 /* 68K or Z8000 */ #define HILO 1 /* used when by* Other CP/M definitions */ /****************************************************************************/ #define TE*************************/ * LONG qtys. */ }; /* */ #else /****************************/ struct long_struct{ /* Lo/Hi storage tes stored */ #else /* */ #define HILO 0 /* */ #endif /* */ /* */ #if HILO RM "CON:" /* Console file name */ #define LIST "LST:" /* List device file name */ #define EOFCHAR 0x1a /* End ************************/ cp68 -i 0: $1.c $1.i c068 $1.i $1.1 $1.2 $1.3 -e era $1.i c168 $1.1 $1.2 $1.s era $1.1 era $1.2 as68 -l -u -s 0: $1.s o68 -r -o $1.68k 0:s.o $1.o $2.o $3.o $4.o $5.o $6.o $7.o $8.o $9.o 0:clib 0:libf.a era $1.s ra $1.s $1vsend rear.sub $1vsend atan.s $1vsend atof.c $1vsend ceil.c $1vsend cosh.s $1vsend etoa.c $1vsend fabs.c $1vsend ffpabslo68 -r -o $1.68k 0:s.o $1.o $2.o $3.o $4.o $5.o $6.o $7.o $8.o $9.o 0:clib 0:libe.a .s $1vsend ffpadd.s $1vsend ffpatan.s $1vsend ffpcmp.s $1vsend ffpcpyrt.s $1vsend ffpdiv.s $1vsend ffpexp.s $1vsend ffphtlo68 -r -o $1.68k 0:s.o $1.o $2.o $3.o $4.o $5.o $6.o $7.o $8.o $9.o 0:clib 0:libf.a o68 -r -o $1.68k 0:s.o $1.o $2.o $3.o $4.o $5.o $6.o $7.o $8.o $9.o 0:clib 0:libe.a het.s $1vsend ffplog.s $1vsend ffpmul2.s $1vsend ffppwr.s $1vsend ffpsin.s $1vsend ffpsinh.s $1vsend ffpsqrt.s $1vsend ffstrrchr.c $1vsend access.c $1vsend blkmove.c $1vsend index.c $1vsend rindex.c $1vsend strcat.c $1vsend strcmp.c $1vsend sd read.c $1vsend xopen.c $1vsend open.c $1vsend optoff.c $1vsend getpass.c $1vsend ttyinraw.c $1vsend prtint.c $1vsend pu/* * Dummy routine for use with floating point stuff ... */ #include DOUBLE atof(); DOUBLE _atof(buf) BYTE *b1vsend fpftol.s $1vsend fpltof.s $1vsend libf.a $1vsend done $2[g0]=libf.a user 8!make $1 $2 ptheta.s $1vsend ffptnorm.s $1vsend ffptof.c $1vsend floor.c $1vsend fmod.c $1vsend fpadd.s $1vsend fpcmp.s $1vsend fpcosera libf.a $2ar68 rf $1 libF.a xdoprtfp.o $2ar68 rf $1 libF.a ftoa.o etoa.o atof.o ffptof.o ftoffp.o fabs.o floor.o $2ar68 rts.c $1vsend putw.c $1vsend qsort.c $1vsend rand.c $1vsend readasc.c $1vsend rename.c $1vsend setbuf.c $1vsend sprintf.c uf; { return(atof(buf)); } vsend fpftol.s $1vsend fpltof.s $1vsend libf.a $1vsend done 2[g0]=libf.a user 8!make $1 $2 .s $1vsend fpdiv.s $1vsend fpexp.s $1vsend fplog.s $1vsend fpmul.s $1vsend fpneg.s $1vsend fppwr.s $1vsend fprintf.c $1vf $1 libF.a ceil.o fmod.o fpadd.o fpcmp.o fpdiv.o fpcos.o fppwr.o $2ar68 rf $1 libF.a fpsin.o fpsqrt.o fpexp.o fplog.o ltof.o $1vsend sscanf.c $1vsend ttyin.c $1vsend unlink.c $1vsend wrtchr.c $1vsend atol.c $1vsend write.c $1vsend doprt.c $1vsenf; { return(atof(buf)); } vsend fpftol.s $1vsend fpltof.s $1vsend libf.a $1vsend done 2[g0]=libf.a user 8!make $1 $2 send fpsin.s $1vsend fpsqrt.s $1vsend fpsub.s $1vsend fscanf.c $1vsend ftoa.c $1vsend ftoffp.c $1vsend ftol.c $1vsend ltoftol.o fpmul.o $2ar68 rf $1 libF.a fpneg.o fpsub.o ffppwr.o ffpsin.o ffpsqrt.o ffpabs.o $2ar68 rf $1 libF.a ffpadd.o ffpcmp.d make.sub $1vsend sgtty.c $1vsend scanf.c $1vsend abort.s $1vsend yesfloat.c $1vsend parsefn.c $1vsend strchr.c $1vsend f; { return(atof(buf)); }  $1vsend gets.c $1vsend getw.c $1vsend fgets.c $1vsend lseek.c $1vsend ttyout.c $1vsend ungetc.c $1vsend malloc.c $1vsenf.c $1vsend printf.c $1vsend sinh.s $1vsend tanh.s $1vsend make.sub $1vsend xdoprtfp.c $1vsend send.sub $1vsend atoi.c $o ffpdiv.o ffpexp.o ffplog.o ffpmul2.o $2ar68 rf $1 libF.a ffptheta.o ffptnorm.o ffphthet.o ffpcpyrt.o atoi.o era *.o pip /o*/ #define _os_newmultisec 0x0040 /* does 3.1 multi-sector i/o*/ #define _os_multisectorio 0x0060 /* does multi-sector i/************************************************************** * OS Ability Bits definitions ********************************* _os_is8087) #define os_multisectorio (os_abilities & _os_multisectorio) #define os_oldmultisec (os_abilities & _os_oldmultisthe O.S. the program is * executing on. * * Last modified: * 2/28/84 whf add 'os_interrupts' * 1/24/84 whf handle link pr */ /**************************************************************************** * OS Ability Test Macros ***********o */ #define _os_truncates 0x0080 /* truncate file func */ /* capabilities for OSATTR.C documentation (not us********************************************/ #define _os_multitasking 0x0001 /* multi tasking OS */ #define _os_netinstaec) #define os_newmultisec (os_abilities & _os_newmultisec) #define os_truncates (os_abilities & _os_truncates) #define os_oblem on 68K * 1/5/84 whf & rsw add CPMZ8KV11 * 12/29/83 whf add os_truncates * 11/4/83 whf handle CCPM 3.1 & networking ********************************************************************/ #define os_multitasking (os_abilities & _os_multitasking) ed in RTL): */ #define _os_f_parse 0x0000 /* F_PARSE func available? */ #define _os_filesharing 0x0000 /* BDOS File Sharilled 0x0002 /* Net installed locally? */ #define _os_interrupts 0x0004 /* O.S. supports CTRL C? */ #define _os_0x0008 f_parse (os_abilities & _os_f_parse) #define os_filesharing (os_abilities & _os_filesharing) #define os_loadtime (os_abilit*************************************************************************/ #ifndef OSATTR extern unsigned short os_version; #define os_netinstalled (os_abilities & _os_netinstalled) #define os_interrupts (os_abilities & _os_interrupts) #define os_dng funcs? */ #define _os_loadtime 0x0000 /* OS supports load time fix*/ #define _os_swaps8087 0x0000 /* OS swaps 8087 regi 0x0008 #define _os_is8087 0x0010 /* Machine has real 8087 */ #define _os_oldmultisec 0x0020 /* does 3.0 multi-sector iies & _os_loadtime) #define os_swaps8087 (os_abilities & _os_swaps8087) /************************************************ /* A contrived version num */ extern unsigned short os_abilities; /* Flags indicating abilitys*/ #endif /***************atetime (os_abilities & _os_datetime) #define os_fastconio (os_abilities & _os_fastconio) #define os_is8087 (os_abilities &/**************************************************************************** * OSATTR.H - include file to define abilities of sters? */ #define _os_fastconio 0x0000 /* CPM+ fast Con I/O funcs */ #define _os_datetime 0x0000 /* OS keeps system time **************************** * OS (Func 12) version numbers ******************************************************************RT(expr) #endif  d7,-(sp) move.l 8(r14),r7 jsr ffpatan move.l r7,r0 move.l (sp)+,d7 unlk r14 rts  */ /* end of osattr.h ********************************************************/  * * Floating Point Arctangen: * Front End to FFP Floating Point Package. * * double * atan(farg) * double farg; * ***********/ #define CPM86V11 0x1022 /* CP/M-86 v1.0, v1.1 */ #define CPM68KV11 0x2022 /* CP/M-68K v1.1 */ #defin/* ASSERT macro */ #ifndef NDEBUG #define ASSERT(expr) {if(!(expr)) printf("assertion failed: expr\n");} #else #define ASS d7,-(sp) move.l 8(r14),r7 jsr ffpatan move.l r7,r0 move.l (sp)+,d7 unlk r14 rts  */ /* end of osattr.h ********************************************************/ * Returns : negated Floating point number * .globl _atan .globl ffpatan .text fpatan: _atan: ~~atan: link r14,#-4 move.e CCPM86V10 0x1430 /* CCP/M-86 PC v1.0 */ #define CCPM86V20 0x1431 /* CCP/M-86 v2.0 */ #define MPM86V21 0x1130 /ERT(expr) #endif l d7,-(sp) move.l 8(r14),r7 jsr ffpatan move.l r7,r0 move.l (sp)+,d7 unlk r14 rts * MP/M-86 v2.0, v2.1 */ #define CPM86V31 0x1031 /* CP/M-86 Plus */ #define CPMZ8KV11 0x3022 /* CP/M-Z8000 v1.1 RT(expr) #endif  d7,-(sp) move.l 8(r14),r7 jsr ffpatan move.l r7,r0 move.l (sp)+,d7 unlk r14 rts  */ /* end of osattr.h ********************************************************/ /* * Ftoa routine with rounding */ #include BYTE *etoa(x,str,prec) FLOAT x; /* Arg to convert */ BYTE *sr); } *= 10.0; } /* * Now output exponent */ *str++ = 'E'; if(ie < 0) { ie = -ie; /* Negate */ *str++ = '-'; } ign, ebin, places; float ibin, fp; ip = ibuf; ep = ebuf; dp = 0; places = 0L; while (*buf == ' ' || *buf == '\t') /* ign*= 10.0; ie--; } } while(x >= 10.0) { x /= 10.0; ie++; } /* * Now round. */ for(y=i=1; i < nPoint * * float * atof(buf) * char *buf; * * No more than 9 significant digits are allowed in single precision. * tr; /* -> Output area */ WORD prec; /* # digits right of dp */ { REG WORD ie,i,k,ndig; /* Temps */ BYTE *savstr *str++ = ie/10 + '0'; /* Drop in 1st digit*/ *str++ = ie%10 + '0'; /* and 2nd digit*/ *str++ = '\0'; return(savsore white spaces */ buf++; isign = (*buf == '-'); if (*buf == '-' || *buf == '+') buf++; while (*buf && *buf != 'e' dig; i++) y = y / 10.0; /* Compute round amount */ x += (y / 2.0); /* Round by 1/2 lsb */ if(x >= 10.0) /* Did we pLargest positive number is 3.4 * 10^18 and the smallest positive * number is 1.2 * 10^-20. * Rely's on the fact that a long ; /* Copy of str to return*/ DOUBLE y; /* Temp for rounding */ savstr = str; /* Preserve for later */ ndig = (ptr); } && *buf != 'E') { if (*buf == '.') dp++; else { /* digit seen */ *ip++ = *buf; if (dp) places++; } ush it over 10? */ { x = 1.0; ie++; } /* * Now convert result */ for(i=0; i 22) ? 23 : prec+1); ie = 0; if(x < 0) /* Fix for negative */ { *str++ = '-'; x = -x; /* Copyright 1982 Alcyon Corporation 8716 Production Ave. San Diego, Ca. 92121 */ /*char *version "@(#) atof - dec r); } buf++; } *ip = 0; if (*buf == 'e' || *buf == 'E') { /* exponent string */ buf++; esign = (*buf == '-'); if (*buf Truncate */ *str++ = k + '0'; /* ASCIIfy */ if(i == 0) /* Locate decimal point*/ *str++ = '.'; x -= (y=k); x long atof(buf) char *buf; { char ibuf[FRACSIZ], ebuf[EXPSIZ]; register char *ip, *ep; long ffp; int dp, esign, is /* Negate */ } /* * Normalize x to the range 0.0 <= x < 10.0 */ if(x > 0.0) { while (x < 1.0) { x 29, 1982"; */ /* * Ascii String to FFP Floating Point Routine : * FFP Standard Single Precision Representation Floating == '-' || *buf == '+') buf++; while (*buf) /* get exponent string */ *ep++ = *buf++; } *ep = 0; ibin = strbin(i  * * Floating Point Hyperbolic cosine: * Front End to FFP Floating Point Package. * * dour *p; { float f; for (f = 0.0; *p >= '0' && *p <= '9'; p++) { f = f * 10.0; f = f + (*p - '0'); } return(f); }f( x > 0 ) x += 0.999999999999; i = x; retval = i; return( retval ); } buf); ebin = atoi(ebuf); places = (esign) ? -ebin - places : ebin - places; fp = ibin * power10(places); ffp = fptoffp(f/* Copyright 1983 Alcyon Corporation 8716 Production Ave. San Diego, Ca. 92121 */ /*chable * cosh(farg) * double farg; * * Returns : negated Floating point number * .globl _co f( x > 0 ) x += 0.999999999999; i = x; retval = i; return( retval ); } p); if (isign) /* negative float */ ffp |= 0x80; return( ffp ); } float power10(pwr) /* 10^pwr */ int pwr; { fr *version "@(#)ceil.c 1.2 10/19/83";*/ /* ceil - returns the smallest integer (as a double precision sh .globl ffpcosh .text fpcosh: _cosh: ~~cosh: link r14,#-4 move.l d7,-(sp) move.l 8(r14),r7 jsr ffpco f( x > 0 ) x += 0.999999999999; i = x; retval = i; return( retval ); } loat f; if (pwr < 0) /* negative power */ for (f = 1.0; pwr < 0; pwr++) f = f / 10.0; else /* positive power */ number) not greater than x. */ double ceil(x) double x; { register long i; double retval; sh move.l r7,r0 move.l (sp)+,d7 unlk r14 rts   for (f = 1.0; pwr > 0; pwr--) f = f * 10.0; return(f); } float strbin(p) /* decimal string => binary long */ chaif( x > 0 ) x += 0.999999999999; i = x; retval = i; return( retval ); } h move.l r7,r0 move.l (sp)+,d7 unlk r14 rts orola inc. * *************************************** ************************************************************* * urn(f); } ************************************** page ffpabs idnt 1,1 ffp abs/neg xdef ffpabs fast flor *version "@(#)fabs.c 1.2 10/19/83";*/ /* * Floating Point Absolute : * Fast Floating Point Pan - cleared * * z - set if result is zero * * v h move.l r7,r0 move.l (sp)+,d7 unlk r14 rts  ffpabs * * fast floating point absolute value * * urn(f); } ating point absolute value xref ffpcpyrt copyright notice section 9 *********************ckage * * double * fabs(farg) * double farg; * * Returns : absolute Floa- cleared * * c - undefined * * x - h move.l r7,r0 move.l (sp)+,d7 unlk r14 rts  * * input: d7 - fast floating point argument * * urn(f); } ********* * absolute value entry point * ****************************** ffpabs and.b #$7f,d7 clear the sign bit ting point number */ long fabs(f) long f; { f = f & 0xffffff7f; /* turn off sign bit */ reundefined * * * * all r * * output: d7 - fast floating point absolute value result * * ttl fast floating point abs/neg (ffpabs/ffpneg) *************************************** * (c) copyright 1981 by mot rts and return to the caller page ************************************************************* turn(f); } egisters transparent * * * ***********************/* Copyright 1982 Alcyon Corporation 8716 Production Ave. San Diego, Ca. 92121 */ /*cha * * condition codes: * * * ffpneg * * fast floating point negate * *ler end ***************** * negate entry point * ********************** ffpneg tst.b d7 ? is argument a zero b * * input: * * f v - cleared * * c - undefined * * ttl fast floating point add/subtract (ffpadd/ffpsub) *************************************** * (c) copyright 1980 b * * input: d7 - fast floating point argument * * ler end eq.s ffprtn return if so eor.b #$80,d7 invert the sign bit ffprtn rts and return to cafpadd * * d6 - floating point addend * * x - undefined * * * * y motorola inc. * *************************************** ************************************************************* * * * output: d7 - fast floating point negated result * * ller end  d7 - floating point adder * * ffpsub * * d all registers transparent * * * *************** ffpadd/ffpsub * * fast floating point add/subtract * * * * condition codes: * * ler end 6 - floating point subtrahend * * d7 - floating point minuend * * ********************************************** page xdef ffpneg fast floating point negate ***** * * ffpadd/ffpsub - fast floating point add and subtract * * n - set if result is negative * * z - set if result is zero * * * * output: * * d7 - microseconds * * * * like signs 14.50 - 26.00 micrhest value with the * * correct sign and the 'v' bit set in the ccr. * * ***************** * subtract entry point * ************************ ffpsub move.b d6,d4 test arg1 beq.s fpa * * registers d3 thru d5 are volatile * * * * average 19.25 microseconds * * unlike signs 21.38 - 55.63 microseconds floating point add result * * * * condition codesoseconds * * average 18.00 microseconds * * unlike signs 20.13 - 54.38 microc * * time: (8 mhz no wait states assumed) * * rt2 return arg2 if arg1 zero eor.b #$80,d4 invert copied sign of arg1 bmi.s fpami1 branch arg1 minu * * code size: 228 bytes stack work area: 0 bytes * * * * average 23.25 microseconds * * : * * n - result is negative * * z - resuleconds * * average 22.00 microseconds * * * * composite average 20.625 microseconds * * s * + arg1 move.b d7,d5 copy and test arg2 bmi.s fpams branch arg2 minus bne.s fpals * * notes: * * 1) addend/subtrahend unal * ************************************************************* page ffpadd idnt 1,1 ffp add/subtract t is zero * * v - overflow has occured * * c - undefin * * subtract: arg1=0 4.25 microseconds * * arg2=0 9.88 microse * * add: arg1=0 7.75 microseconds * * arg2=0 5.25 branch positive not zero bra.s fpart1 return arg1 since arg2 is zero ******************* * add entry point tered (d6). * * 2) underflow returns zero and is unflagged. * * 3) overflow returns the hig xdef ffpadd,ffpsub entry points xref ffpcpyrt copyright notice section 9 *******ed * * x - undefined * * conds * * * * like signs 15.75 - 27.25 microseconds* ******************* ffpadd move.b d6,d4 test argument1 bmi.s fpami1 branch if arg1 minus beq.s rts return to caller * return argument2 fpart2 tst.b d7 test for returned value rt bvs.s fpa2os branch overflow bcc.s fparsr branch if no exponent overflow fpa2os moveq #-1,d7 create a bmi.s fpatlt branch if arg1 larger * arg1 <= arg2 cmp.b #24,d5 compare magnitude difference d6,d3 copy arg1 clr.b d3 clean off sign+exponent lsr.l d5,d3 shift to same magnitude f carry produced move.b d4,d7 restore sign/exponent rts return to caller * -arg1 fpami fpart2 return arg2 if zero * + arg1 move.b d7,d5 test argument2 bmi.s fpams branch if mixes return to caller * -arg1exp > -arg2exp * +arg1exp > +arg2exp fpa2lt cmp.b #-24,d5 ? arguments within rll ones sub.b #1,d4 back to highest exponent+sign move.b d4,d7 replace in result * or.b bcc.s fpart2 branch arg2 much bigger move.b d7,d4 arg2 s+exp dominates move.b d3,d7 setup carry move.b #$80,d7 force carry if lsb-1 on add.l d3,d7 add arguments bcs.s fpa2gc branch if carry 1 move.b d7,d5 test arg2's sign bmi.s fpals branch for like signs beq.s fpart1 if zero returnd signs beq.s fpart1 zero so return argument1 * +arg1 +arg2 * -arg1 -arg2 fpals sub.b d4,d5 test expange ble.s fpart1 nope, return larger neg.b d5 change difference to positive move.l d#$02,ccr show overflow occurred dc.l $003c0002 ****assembler error**** rts return to caller on arg2 move.l d6,d3 copy arg1 fpamss clr.b d3 clear extraneous bits lsr.l d5,d3 adjust produced fparsr move.b d4,d7 restore sign/exponent rts return to caller * add same sign overfl argument1 * -arg1 +arg2 * +arg1 -arg2 fpams moveq #-128,d3 create a carry mask ($80) eor.b d3,d5 stronent magnitudes bmi.s fpa2lt branch arg1 greater move.b d7,d4 setup stronger s+exp in d4 * arg16,d3 setup larger value clr.b d7 clean off sign+exponent lsr.l d5,d7 shift to same magnitude * return argument1 fpart1 move.l d6,d7 move in as result move.b d4,d7 move in prepared sign+exponent for magnitude sub.l d3,d7 subtract smaller from larger bmi.s fparsr return final result if no overfow normalization fpa2gc roxr.l #1,d7 shift carry back into result add.b #1,d4 add one to exponent ip sign off arg2 s+exp copy sub.b d4,d5 compare magnitudes beq.s fpaeq branch equal magnitudes exp <= arg2exp cmp.b #24,d5 overbearing size bcc.s fpart2 branch yes, return arg2 move.l move.b #$80,d3 force carry if lsb-1 on add.l d3,d7 add arguments bcs.s fpa2gc branch ilow * mixed signs normalize fpanor move.b d4,d5 save correct sign fpanrm clr.b d7 clear subtract residue o normalize end ing bit bra.s fpamss perform the addition * equal magnitudes fpaeq move.b d7,d5 save arg1 sign ffpatan * * fast floating point arctangent * * .s fpazro return zero if exponent underflowed rts return to caller * exponent underflowed - return sub.b #1,d4 make up for first shift cmp.l #$00007fff,d7 ? small enough for swap bhi.s fpa normalize end  exg.l d5,d4 swap arg2 with arg1 s+exp move.b d6,d7 insure same low byte sub.l d6,d7 obtain * * input: d7 - input argument * * * * output: d7 - ar zero fpazro moveq.l #0,d7 create a true zero rts return to caller * arg1 > arg2 fpatlt cmp.bxqn branch nope swap.w d7 shift left 16 bits real fast sub.b #16,d4 make up for 16 bit shift f normalize end difference beq.s fpazro return zero if identical bpl.s fpanor branch if arg2 bigger neg.l ctangent radian result * * * * all other registers totally transparent #-24,d5 ? arg1 >> arg2 ble.s fpart1 return it if so neg.b d5 absolutize difference ttl fast floating point arctangent (ffpatan) *************************************** * (c) copyright 1981 by mopaxqn add.l d7,d7 shift up one bit dbmi d4,fpaxqn decrement and branch if positive eor.b d4,d5  normalize end  d7 correct difference to positive move.b d5,d4 use arg2's sign + exponent bra.s fpanrm and g * * * * code size: 132 bytes stack work: 32 bytes * * move.l d7,d3 move arg2 as lower value move.l d6,d7 set up arg1 as high move.b #$80,d7 setup roundtorola inc. * *************************************** ************************************************* * ? same sign bmi.s fpazro branch underflow to zero move.b d4,d7 restore sign/exponent beq * * condition codes: * * z - set if the result is zero d1-d6/a0,-(sp) save caller's registers move.b d7,-(sp) save original sign on stack and.b entry point xref ffptheta arctangent table xref ffpdiv,ffpsub arithmeanch if not too small move.l #0,d6 convert to a zero bra.s fpazro branch i* * time: (8mhz no wait states assumed) * * * * the time is veargument > 1: atan(1/x) = pi/2 - atan(x) fpardc not.b (sp) flag inverse taken exg.l d6,d7 * * n - cleared * * v - cleared * * c - undefine #$7f,d7 take absolute value of arg * insure less than one for cordic loop move.l #fpone,d6 tic primitives xref ffptnorm transcendental normalize routine xref ffpcpyrt cof zero fpanotz lsr.l d7,d7 shift to bin(31,29) precision ***************************************** * cory data sensitive with * * sample values ranging from 238 to * * 465 microseconds * take inverse of argument jsr ffpdiv perform divide * perform cordic function * cd * * x - undefined * * load up 1 clr.b -(sp) default no inverse required cmp.b d6,d7 ? less pyright stub piov2 equ $c90fdb41 float pi/2 fpone equ $80000041 float 1 *********rdic calculation registers: * * d1 - loop count a0 - table pointer * * d2 - shift count * * d * * ************************************************* page ffpatan onvert to bin(31,29) precision fpainrg sub.b #64+3,d7 adjust exponent neg.b d7 f * * * * notes: * * 1) spot checks shthan one bcs.s fpainrg branch in range bhi.s fpardc higher - must reduce *********** * arctangent entry * ******************** * save registers and perform argument reduction ffpatan movem.l 3 - y' d5 - y * * d4 - x' d6 - z * * d7 - x * **idnt 1,2 ffp arctangent opt pcs section 9 xdef ffpatan or shift necessary cmp.b #31,d7 ? too small to worry about bls.s fpanotz brow at least six digit * * precision on all sampled cases. * * cmp.l d6,d7 ? less or equal to one bls.s fpainrg branch yes, is in range * *************************************** move.l #0,d6 z=0 move.l #1<<29,d5 y clear exponent portion or.b d6,d7 if minus, give minus result fpartn movem.l (sp)+,d1-d6/orm float z fpazro move.l d6,d7 copy answer to d7 tst.b (sp)+ ? was i asr.l d2,d3 shift(y') fplnlp sub.l d3,d7 x = x - y' bpl.s fplpls =1 lea ffptheta+4,a0 to arctangent table move.l #24,d1 loop 25 times ma0 restore caller's registers rts return to caller end nverse taken beq.s fpaninv branch if not move.l #piov2,d7 take away from pi ove branch negative move.l d4,d7 restore x add.l #4,a0 to next table eove.l #1,d2 prime shift counter bra.s cordic enter cordic loop * cordic loop fp0 restore caller's registers rts return to caller end r two jsr ffpsub subtract fpaninv move.b (sp)+,d6 load original sign tst. ttl fast floating point cmp/tst (ffpcmp/ffptst) *************************************** * (c) copyright 1981 by motntry add.b #1,d2 increment shift count lsr.l #1,d3 shift(y') dlpls asr.l d2,d4 shift(x') add.l d4,d5 y = y + x' add.l (a0),d6 0 restore caller's registers rts return to caller end b d7 ? result zero beq.s fpartn return if so and.b #$80,d6 orola inc. * *************************************** ************************************************************* * bra d1,fplnlp and loop until done * now convert to float and reconstruct the result jsr ffptn z = z + arctan(i) cordic move.l d7,d4 x' = x move.l d5,d3 y' = y 0 restore caller's registers rts return to caller end  ffpcmp * * fast floating point compare * * **************************** page ffpcmp idnt 1,1 ffp cmp/tst xdef ffpcmp fast floating poind * * z - set if result is zero * * v - cleared ot equal zero * * pl - argument is positive (includes zero)* * mi - argument is gt - destination greater * * ge - destination greater or equal to * * st * * fast floating point test * * * * input: d6 - fast floating point argument (source) * * t compare xref ffpcpyrt copyright notice section 9 *********************** * compare ent * * c - undefined * * x - undefined negative * * * * condition codes: eq - destination equal * * ne - destination not equal * * lt * * input: d7 - fast floating point argument * * d7 - fast floating point argument (destination) * * * * output: cory point * *********************** ffpcmp cmp.b d6,d7 compare sign and exponent only first bne.s ffpcr * * * * all registers t * * n - set if result is negative * * z - set if result is zero - destination less than * * le - destination less than or equal to * * * * output: condition codes set for the following branches: * * ndition code reflecting the following branches * * for the result of comparing the destination * * minutn return if that is sufficient cmp.l d6,d7 no, compare full longwords then ffpcrtn rts anransparent * * * ********************************* * * v - cleared * * c - undefined * * condition codes: * * n - cleare * * eq - argument equals zero * * ne - argument ns the source: * * * * d return to the caller page ************************************************************* * ffpt * * x - undefined * * ********************************* * ffp library copyright notice stub * * * * this module ola inc.' end sted condition code rts to caller end  ffpcpyrt equ * dc.b 'mc68343 floating point firmware ' dc.b '(c) copyright 1981 by moto * * all registers transparent * * is included by all * * link edits with the ffplib.ro * * library to protect motorola's * * copyright status. sted condition code rts to caller end rola inc.' end  * ************************************************************* page xdef ffptst fast * * * * code: 67 bytes * * sted condition code rts to caller end ola inc.' end  floating point test ******************** * test entry point * ******************** ffptst tst.b d7 return t* * note: this module must reside * * last in the library as it is * * referenced by all other mc68343 * * modul ttl mc68343 fast floating point copyright notice (ffpcpyrt) ffpcpyrt idnt 1,1 ffp copyright notice ****ola inc.' end ested condition code rts to caller end es. * ************************************* section 9 xdef ffpcpyrt ign and the 'v' * * bit set in the ccr. * * 4) if a divide by zero is attempted * * the divined * * * * registers d3 thru d5 volatile * * 9 * divide by zero exit fpddzr divu.w #0,d7 **force divide by zero ** * if the exception returns with altered d- floating point divisor * * d7 - floating point dividend * * * * * * time: (8 mhz no wait states assumed) * * dividend zero 5.250 microseconds * * minimum ide by zero exception trap * * is forced by this code with the * * original arguments intact. if the * * * * code: 150 bytes stack work: 0 bytes * * *enominator - continue divide tst.l d6 ? exception alter the zero bne.s ffpdiv branch if sooutput: * * d7 - floating point quotient * * time others 72.750 microseconds * * maximum time others 85.000 microseconds * * average others 76.687 microseconds * ttl fast floating point divide (ffpdiv) ***************************************** * (c) copyright 1980 by moto exception returns with the denom- * * inator altered the divide operation * * continues, otherwise an overflow * notes: * * 1) divisor is unaltered (d6). * * 2) underflows return zero with to continue * setup maximum number for divide overflow fpdovf or.l #$ffffff7f,d7 maximize with proper sign tst.b d * * condition codes: * * n - set if result negative * * z - set if result z* * ******************************************** page ffpdiv idnt 1,rola inc. * ***************************************** ******************************************** * ffpdiv sub * * is forced with the proper sign. * * the floating divide by zero can be * * distinguished from trueout * * any indicators set. * * 3) overflows return the highest value * * with the proper s7 set condition code for sign * or.w #$02,ccr set overflow bit dc.l $003c0002 ******sick assembler****ero * * v - set if result overflowed * * c - undefined * * x - undef1 ffp divide xdef ffpdiv entry point xref ffpcpyrt copyright notice sectionroutine * * * * input: * * d6 zero divide * * by the fact that it is an immediate * * zero dividing into register d7. * * ** fpdrtn rts return to caller * over or underflow detected fpdov2 swap.w d6 restore arg1 nent of result * now divide just using 16 bits into 24 move.l d7,d3 copy arg1 for initial divide divu.w swap.w d6 against arg1 and arg2 cmp.w d6,d7 ? check if overflow will occur bmi.s fpdnov branch i * compute last 8 bits with another divide. the exact remainder from the * multiply and compare above is divided again by aq.s fpdrtn return zero if dividend zero moveq #-128,d3 setup sign mask add.w d5,d5 isolate arg1 sign or swap.w d6 rebuild arg1 to normal move.w d6,d3 setup arg1 for product clr.b d3 zero swap.w d7 restore arg2 for sign fpdovfs eor.b d6,d7 setup correct sign bra.s fpdovf and enter oved6,d3 obtain test quotient move.w d3,d5 save test quotient * now multiply 16-bit divide result times full 24f not * adjust for fixed point divide overflow add.b #2,d4 adjust exponent up one bvs.s fpdov2 branch 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 efrom exponent add.w d4,d4 isolate arg2 sign from exponent eor.b d3,d5 adjust arg1 exponent to binary low byte mulu.w d5,d3 find remaining product sub.l d3,d7 now have full subtraction bcc.s fpdqrflow handling fpdouf bmi.s fpdovfs branch if overflow fpdund move.l #0,d7 underflow to zero rts a bit divisor and compare * with the dividend. multiplying back out with the full 24-bits allows * us to see if the result wasoverflow here ror.l #1,d7 shift down by power of two fpdnov swap.w d7 correct arg2 move.b d3,d5 xtra bit for rounding purposes) and this * divide always returns a precision of at least 9 bits. fpdqok move.l d6,d3 copy eor.b d3,d4 adjust arg2 exponent to binary sub.b d5,d4 subtract exponents bvs.s fpdouf branok branch first 16 bits correct * estimate too high, decrement quotient by one move.l d6,d3 rebuild divisor nd return to caller *************** * entry point * *************** * first subtract exponents ffpdiv move.b d6,d5 too large due to the 8 missing divisor bits * used in the hardware divide. the result can only be too large by 1 unit. move $80 into d5.b eor.w d5,d4 create sign and absolutize exponent lsr.w #1,d4 d4.b now has sign+expoarg1 again swap.w d3 first 16 bits divisor in d3.w clr.w d7 into first 16 bits of dividend ch if overflow/underflow clr.b d7 clear arg2 s+exp swap.w d7 prepare high 16 bit compare clr.b d3 reverse halves add.l d3,d7 add another divisor sub.w #1,d5 decrement quotient copy arg1 (divisor) beq.s fpddzr branch if divide by zero move.l d7,d4 copy arg2 (dividend) be mulu.w d6,d3 high divisor x quotient sub.l d3,d7 d7=partial subtraction swap.w d7 to low divis divu.w d3,d7 obtain final 16 bit result swap.w d5 first 16 quotient to high half bmi.s fpdisn b rts return result to caller end  * * x - undefined * * * eturn in d7 move.b d4,d7 finish result with sign+exponent beq.s fpdund underflow if zero exponent ential result * * * * all other registers are transparent ranch if normalized * rare occurrance - unnormalized * happends when mantissa arg1 < arg2 and they differ only in last 8 bits ttl fast floating point exponent (ffpexp) *************************************** * (c) copyright 1981 by motor * * * notes: * * 1) an overflow retur rts return result to caller end * * * * code size: 256 bytes stack work: 34 bytes * * move.w d7,d5 insert low word of quotient add.l d5,d5 shift mantissa left one sub.b #1,d4 aola inc. * *************************************** ************************************************* * ffns the largest * * magnitude number. * * 2) spot checks show at least 6.8 digit *  rts return result to caller end  * * condition codes: * * z - set if result in d7 is zero *djust exponent down (cannot zero) move.w d5,d7 cancel next instruction * rebuild our final result and return fppexp * * fast floating point exponent * * * accuracy for all abs(arg) < 30. * * * * time: (8mhz no wait sta rts return result to caller end  * n - cleared * * v - set if overlow occurred * * c - undefined disn move.w d7,d5 append next 16 bits add.l #$80,d5 round to 24 bits (cannot overflow) move.l d5,d7 r * * input: d7 - input argument * * * * output: d7 - expontes assumed) * * * * 488 microseconds * * no, continue move.l #0,d7 return a zero bra.s fpovrtn as result is too 4269504 cnjkhinv equ $9a8f4441 floating conjugate of k inverse * correctey log 2 base e for partial result fpepos move.l d7,d2 save original argument move.l #ln2inv,d6 opt pcs section 9 xdef ffpexp entry point xref st.b d7 set condition code properly rts return to caller ********** * * logic: 1) find n = int(arg/ln 2). this is * * added to thesmall fpovnzro move.l #-1,d7 set all zeroes lsr.b #1,d7 zero sign bit * or.d for the extra convergence * during shifts for 4 and 13 kfctseed equ $26a3d100 load inverse to multiply (faster) jsr ffpmul2 obtain division thru multiply bvs ffphthet hypertangent table xref ffpmul2,ffpsub arithmetic primitives xref **** * exp entry * ************** * save work registers and insure positive argument ffpexp movem.l d1-d6/a0,-(sp) mantissa at the end.* * 3) reduce argument to range by * * finding arg = mod(arg, ln 2). * * b #$02,ccr set overflow bit dc.l $003c0002 ***assembler error*** fpovrtn movem.l (s k cordic seed * overflow - return zero or highest value and "v" bit fpeovflw move.w (sp)+,d6 load s fpeovflw branch if too large * convert quotient to both fixed and float integer move.b d7,d5 ffptnorm transcendental normalize routine xref ffpcpyrt copyright stub ln2 equ save all work registers move.w d7,-(sp) save sign in low order byte for later beq.s ff 4) derive exp(arg) with cordic loop.* * 5) add n to exponent giving result. * * p)+,d1-d6/a0 restore registers rts return to caller * return one for zero argument ign word and work off stack tst.b d6 ? was argument negative bpl.s fpovnzro copy exponent over move.b d7,d6 copy exponent over sub.b #64+32,d5 $b1721840 ln 2 (base e) .693147180 ln2inv equ $b8aa3b41 inverse of ln 2 (base e) 1.4pe1 return a true one for zero exponent and.b #$7f,d7 take absolute value * divide b * ************************************************* page ffpexp idnt 1,2 ffp exp ffpe1 move.l #$80000041,d7 return a true one lea 7*4+2(sp),sp ignore stack saves tfind non-fractional precision neg.b d5 make positive cmp.b #24,d5 ? in convert to fixed point ***************************************** * cordic calculation registers: * * d1 - loop move.l d2,d7 back to original argument * convert argument to binary(31,29) precision fpeadj clr.b r through 13 bsr.s cordic second cordic loops sub.l #4,a0 back to entry 1iply by ln2 to find residue jsr ffpmul2 multiply back out move.l d7,d6 s prime shift counter * perform cordic loop repeating shifts 4 and 13 to guarantee convergence * (ref. "a unifiedsure not too large ble.s fpeovflw branch too large cmp.b #32,d5 ? test uppercount a0 - table pointer * * d2 - shift count * * d3 - y' d5 - y * * d4 - x' d7 clear sign and exponent sub.b #64+3,d2 obtain shift value neg.b d23 sub.w #1,d2 redo shift for 13 move.l #10,d1 now 13 through 23 etup to subtract multiple of ln 2 move.l d2,d7 move argument in jsr ffpsub algorithm for elementary functions" j.s.walther * pg. 380 spring joint computer conference 1971) move.l #3 range bge.s fpesml branch less than one lsr.l d5,d7 shift to integer d6 - x * * d7 - test argument * ***************************************** * input for 2 non-fraction bits cmp.b #31,d2 insure not too small bls.s fpeshbsr.s cordic and finish up * now finalize the result tst.b 1(sp) test original find remainder of ln 2 divide move.l d7,d2 copy float argument bra.s fpeadj ,d1 do shifts 1 thru 4 bsr.s cordic first cordic loops sub.l #4,a0 move.b d7,(sp) place adjusted exponent with sign byte lsl.l d5,d7 back to norm within range, now start cordic setup fpecom move.l #0,d5 y=0 move.l #kfctseed,d6 x=1 wif branch to shift if ok move.l #0,d7 force to zero fpeshf lsr.l d2,d7 sign bpl.s fsepos branch positive argument neg.l d5 change y for subtr adjust to fixed * multiple less than one fpesml clr.b (sp) default initial multiply to zero redo table entry sub.w #1,d2 redo shift count move.l #9,d1 do foual without fraction move.b d6,d7 re-insert sign+exponent move.l #ln2,d6 multth jkhinverse factored out lea ffphthet,a0 point to hperbolic tangent table move.l #0,d2 action neg.b (sp) negate adjusted exponent to subtract fsepos add.l d5,d6 add d1,cordic loop until done rts return end +x' add.l d3,d6 x=x+y' sub.l (a0)+,d7 arg=arg-table(n) dbra inary point is assumed between * * bits 27 and 28 with three leading non-fraction bits.) * *********************************to caller ************************* * cordic loop subroutine* ************************* cordic add.w #1,d2 section 9 xdef ffphthet external definition ****************************************************or subtract y to/from x jsr ffptnorm float x move.l d6,d7 setup result * d1,cordic loop until done rts return end d1,cordic loop until done rts return febmi sub.l d4,d5 y=************************ ffphthet dc.l $1193ea7a $8c9f53d0>>3 harctan(2**-1) .549306144 dc.l $4162b increment shift count move.l d5,d3 copy y move.l d6,d4 copy x ***** * inverse hyperbolic tangent table for cordic * * * * tadd ln2 factor integer to the exponent add.b (sp),d7 add to exponent bmi fpeovflw d1,cordic loop until done rts return end y-x' sub.l d3,d6 x=x-y' add.l (a0)+,d7 arg=arg+table(n) dbra be8>>3 harctan(2**-2) .255412812 dc.l $202b1238>>3 harctan(2**-3) dc.l $10055888>>3 harctan(2**- asr.l d2,d3 shift for y' asr.l d2,d4 shift for x' tst.l d7 he following table is used during cordic * * transcendental evaluations for log and exp. it has * * inverse hyp branch if too large beq fpeovflw branch if too small add.l #2,sp r ttl fast floating point cordic hyperbolic table (ffphthet) ffphthet idnt 1,1 ffp inverse hyperbolic table * d1,cordic loop until done rts return end 4) dc.l $0800aac0>>3 harctan(2**-5) dc.l $04001550>>3 harctan(2**-6) dc.l $020002a8 test arg value bmi.s febmi branch minus test add.l d4,d5 y=yerbolic tangent for 2**-n where n ranges * * from 1 to 24. the format is binary(31,29) * * precision (i.e. the bid work data off stack movem.l (sp)+,d1-d6/a0 restore registers rts return ************************************** * (c) copyright 1981 by motorola inc. * *************************************** >>3 harctan(2**-7) dc.l $01000050>>3 harctan(2**-8) dc.l $00800008>>3 harctan(2**-9) dc. $00000200>>3 harctan(2**-23) dc.l $00000100>>3 harctan(2**-24) end  * * c - undefined * * x - undefined * * rctan(2**-20) dc.l $00000800>>3 harctan(2**-21) dc.l $00000400>>3 harctan(2**-22) dc.l c result to base e * * * * all other registers totally transparent * * l $00400000>>3 harctan(2**-10) dc.l $00200000>>3 harctan(2**-11) dc.l $00100000>>3 harctan(2* ttl fast floating point log (ffplog) *************************************** * (c) copyright 1981 by motorola i * * * * notes: $00000200>>3 harctan(2**-23) dc.l $00000100>>3 harctan(2**-24) end  * * code size: 184 bytes stack work: 38 bytes * * *-12) dc.l $00080000>>3 harctan(2**-13) dc.l $00040000>>3 harctan(2**-14) dc.l $000nc. * *************************************** ************************************************* * ffplog * * 1) spot checks show errors bounded by * * 5 x 10**-8. * *  $00000200>>3 harctan(2**-23) dc.l $00000100>>3 harctan(2**-24) end  * * condition codes: * * z - set if the result is zero * * 20000>>3 harctan(2**-15) dc.l $00010000>>3 harctan(2**-16) dc.l $00008000>>3 harctan(2**-17) * * fast floating point logorithm * * * *2) negative arguments are illegal and cause* * the "v" bit to be set and the absolute * * value used instead.  $00000200>>3 harctan(2**-23) dc.l $00000100>>3 harctan(2**-24) end  n - set if result in is negative * * v - set if invalid negative argument * * or zero argument dc.l $00004000>>3 harctan(2**-18) dc.l $00002000>>3 harctan(2**-19) dc.l $00001000>>3 ha input: d7 - input argument * * * * output: d7 - logorithmi * * 3) a zero argument returns the largest * * negative value possible with the "v" bit* * ***assembler error*** rts return to caller * argument is zero - return largest negati log entry * ************** * insure argument positive ffplog tst.b d7 ? test sign beq.s.b #31,d7 ? insure not too small bls.s fplshf no, go shift move.l #0,d7 pcs section 9 xdef ffplog entry point xref ffphthet ffpadd create arg+1 exg.l d7,d2 swap result with argument jsr ffps set. * * * * time: (8mhz no wait states asve number with "v" bit fplzro move.l #-1,d7 return largest negative jmp fpsetv r fplzro branch argument zero bpl.s fplok branch alright * argument is negative force to zero fplshf lsr.l d7,d7 shift to bin(31,29) precision ************************* hypertangent table xref ffpadd,ffpdiv,ffpsub,ffpmul2 arithmetic primitives xref ub create arg-1 move.l d2,d6 prepare for divide jsr ffpdiv sumed) * * * * times are very data sensitive with * * eturn with "v" bit set * save work registers and strip exponent off fplok movem.l d1-d6/a0,-(sp) save all work re- use the absolute value and set the "v" bit and.b #$7f,d7 take absolute value bsr.s fpl**************** * cordic calculation registers: * * d1 - loop count a0 - table pointer * * d2 - shift count ffptnorm transcendental normalize routine xref ffpcpyrt copyright stub fpone equ result is (arg-1)/(arg+1) beq.s fplnocr zero so cordic not needed * convert to bin(31,29) precision samples ranging from 170 to 556 * * microseconds * * gisters move.b d7,-(sp) save original exponent move.b #64+1,d7 force between 1 aok find log(abs(x)) *psetv or.b #$02,ccr set overflow bit fpsetv dc.l $003c0002 * * d3 - y' d5 - y * * d4 - x' d6 - z * * d7 - x $80000041 floating value for one log2 equ $b1721840 log(2) = .6931471805 ************** * sub.b #64+3,d7 adjust exponent neg.b d7 for shift necessary cmp * ************************************************* page ffplog idnt 1,2 ffp log opt nd 2 move.l #fpone,d6 load up a one move.l d7,d2 copy argument jsr * ***************************************** move.l #0,d6 z=0 move.l #64+1,d6 convert exponent to binary beq.s fplzpr branch zero partial here movnent*log(2) for final result move.l #0,d7 default zero if too small jsr ffptnorm  rts return to caller end e.l d5,d3 y' = y asr.l d2,d3 shift(y') fplnlp sub.l d3,d7 x = extract sign or.b d1,d6 insert sign in move.l #log2,d7 multiply exponent #1<<29,d5 y=1 lea ffphthet,a0 to inverse hyperbolic tangent table move.l #22,d1 e.b d6,d1 save sign byte bpl.s fplpos branch positive value neg.b d6 float z beq.s fplnocr branch if too small add.b #1,d6 times two  rts return to caller end x - y' bpl.s fplpls branch negative move.l d4,d7 restore x add.lby log(2) jsr ffpmul2 multiply d6 and d7 move.l d2,d6 now add cordic resu loop 23 times move.l #1,d2 prime shift counter bra.s cordic e force positive fplpos ror.l #8,d6 prepare to convert to integer move.l #$47,d5 move.l d6,d7 setup in d7 in case exp=0 fplnocr move.l d7,d2 save result mov rts return to caller end  #4,a0 to next table entry add.b #1,d2 increment shift count lsr.l #lt jsr ffpadd for final answer fplzpr movem.l (sp)+,d1-d6/a0 restore registers nter cordic loop * cordic loop fplpls asr.l d2,d4 shift(x') sub.l d4,d5 y = setup exponent mask fplnorm add.l d6,d6 shift to left dbmi d5,fplnorm ee.l #0,d6 prepare original exponent load move.b (sp)+,d6 load it back sub.b 1,d3 shift(y') dbra d1,fplnlp and loop until done * now convert to float and add expo rts return to caller end  y - x' add.l (a0),d6 z = z + hypertan(i) cordic move.l d7,d4 x' = x movxp-1 and branch if not normalized move.b d5,d6 fix in exponent and.b #$80,d1 ttl fast floating point precise multiply (ffpmul2) ******************************************* * (c) copyright * * 2) underflows return zero with no * * indicator set. * * 3) overflows will r * * condition codes: * * n - set if result negative * * z - seft by one 4 add.w d4,d4 shift left by one 4 moveq #-128,d3 prepare exponentignificant bit due * * to truncation. * * * * input: *************** page ffpmul2 idnt 1,1 ffp high-precision multiply xdef ffpmul2 entry point 1980 by motorola inc. * ******************************************* ******************************************** * eturn the maximum * * value with the proper sign and the * * 'v' bit set in the ccr. * * t if result is zero * * v - set if overflow occurred * * c - undefined * * modifier ($80) 4 eor.b d3,d4 adjust arg1 exponent to binary 4 eor.b d3,d5 adjust arg2 exponent to * * d6 - floating point multiplier * * d7 - floating point multiplican * * xref ffpcpyrt copyright notice section 9 * ffpmul2 subroutine entry point ffpmul2 move.b d7,d5 ffpmul2 subroutine * * * * this module is the second of the * * times: (8mhz no wait states assumed) * * arg1 zero 5.750 microseconds * * a x - undefined * * * * code: 134 bytes stack work: 0 bytes binary 4 add.b d4,d5 add exponents 4 bvs.s ffmouf branch if overflow/underflow * * output: * * d7 - floating point result prepare sign/exponent work 4 beq.s ffmrtn return if result already zero 8/10 move.b d6,d4 cop * * multiply routines. it is 18% slower * * but provides the highest accuracy * * possible. the error is exarg2 zero 3.750 microseconds * * minimum time others 45.750 microseconds * * maximum time others 61.500 microsecon* * * * notes: * * 1) multipier unaltered (d6). 8/10 move.b d3,d4 overlay $80 constant into d4 4 eor.w d4,d5 d5 now has sign and exponent 4 * * * * registers d3 thru d5 are volatile * * y arg1 sign/exponent 4 beq.s ffmrt0 return zero if arg1=0 8/10 add.w d5,d5 shift lectly .5 * * least significant bit versus an error * * in the high-speed default routine of * * .50390625 least sds * * average others 52.875 microseconds * * * ***************************** ror.w #1,d5 move to low 8 bits 8 swap.w d5 save final s+exp in high word 4 mo ffmrt0 return zero if zero exponent 8/10 ffmrtn rts return to caller 16 * must normalird 4 swap.w d7 now top of arg2 4 mulu.w d6,d7 d7 = arg1highw x arg2highw ign 4 or.l #$ffffff7f,d7 force highest value possible 16 tst.b d7 set sign in return code 1lowb x arg2highw 38-54 (46) add.l d3,d4 d4 = partial product (no carry) 8 swap.w d6 to arg1b #1,d5 undo normalize attempt 4 ffmcln move.b d5,d7 insert sign and exponent 4 beq.s ffmrve.w d6,d5 copy arg1 low byte 4 clr.b d7 clear s+exp out of arg2 4 clr.b d5 ze result ffmnor sub.b #1,d5 bump exponent down by one 4 bvs.s ffmrt0 return zero if underflow 40-70 (54) swap.w d6 restore arg1 4 swap.w d5 restore s+exp to low word * ori.b #$02,ccr set overflow bit dc.l $003c0002 ****sick assembler**** high two bytes 4 move.l d6,d3 copy arg1highw over 4 mulu.w d7,d3 d3 = arg2lowb xt0 return zero if exponent zero 8/10 rts return to caller 16 * arg1 zero ffmrt0 clear s+exp out of arg1 low byte 4 move.w d5,d4 prepare arg1lowb for multiply 4 mulu.w d7,d4 d8/10 bcs.s ffmrt0 return zero if sign inverted 8/10 moveq #$40,d4 rounding factor 4 add.l d4,d7 add partial products 8 bpl ffmnor branch if must normalize 8/10 20 rts return to caller 16 end  arg1highw 38-54 (46) add.l d3,d4 d4 = partial product 8 clr.w d4 clear low end move.l #0,d7 return zero 4 rts return to caller 16 * overflow 4 = arg2lowb x arg1lowb 38-54 (46) swap.w d4 place result in low word 4 move.l d7,d3 add.l d4,d7 add in rounding factor 8 add.l d7,d7 shift to normalize 8 add.l #$80,d7 round up (cannot overflow) 16 move.b d5,d7 insert sign and exponent 4 beq.s 0 rts return to caller 16 end runoff 4 addx.b d4,d4 shift in carry if any 4 swap.w d4 put carry into high woor underflow exponent ffmouf bpl.s ffmrt0 branch if underflow to give zero 8/10 eor.b d6,d7 calculate proper scopy arg2 4 swap.w d3 to arg2highw 4 mulu.w d5,d3 d3 = argbcc.s ffmcln return normalized number 8/10 roxr.l #1,d7 rounding forced carry in top bit 10 add.0 rts return to caller 16 end  v - set if overflow occurred or base * * value argument was negative * * c - undefined * * * all registers but d7 are transparent * * ,1 ffp power opt pcs section 9 xdef ffppwr entry poin inc. * *************************************** ************************************************* * ffppweast six digit * * precision for 80 percent of the cases. * * * * t0 rts return to caller 16 end  * * x - undefined * * * * * * code size: 36 bytes stack work: 42 bytes * * * *t xref ffplog,ffpexp exponent and log functions xref ffpmul2 multiply function r * * fast floating point power function * * * ime: (8mhz no wait states assumed) * * * * the timing is very da notes: * * 1) a negative base value will force the use* * if its absolute valu calls subroutines: ffplog, ffpexp and ffpmul2 * * * * condition codes: xref ffpcpyrt copyright stub ***************** * power entry * ***************** * take the l * input: d6 - floating point exponent value * * d7 - floating point argument value * * ta sensitive with * * test samples ranging from 720 to * * 1206 microseconds * * e. the "v" bit will* * be set upon function return. * * 2) if the result overflows then the * * * * z - set if the result is zero * * n - cleared * *ogorithm of the base value ffppwr tst.b d7 ? negative base value bpl.s fpppos * * output: d7 - result of the value taken to * * the power specified * * ************************************************* page ffppwr idnt 1 ttl fast floating point power (ffppwr) *************************************** * (c) copyright 1981 by motorola maximum size value is returned with the * * "v" bit set in the condition code. * * 3) spot checks show at l branch positive and.b #$7f,d7 take absolute value bsr.s fpppos find result * * input: d7 - input argument (radian) * * * * o d6 - sin, d7 - cosine * * * * notes: ed, ffpexp will set "v" bit and return desired result anyway jmp ffpexp result is exponent c - undefined * * v - set if result is meaningless * * (input magnitude to using that * or.b #$02,ccr force "v" bit on for negative argument dc.l $003c0002 utput: d7 - function result * * (ffpsincs also returns d6) * * ttl ffp sine cosine tangent (ffpsin/ffpcos/ffptan/ffpsincs) *************************************** * (c) copyr * * 1) input values are in radians. * * 2) function ffpsincs returns both sine * * a end o large) * * x - undefined * * * * func *****assembler error***** rts return to caller fpppos jsr ffplog * * all other registers totally transparent * * * * coight 1981 by motorola inc. * *************************************** ************************************************* * nd cosine twice as fast as calculating * * the two functions independently for * * the same value. this is ha end tions: * * ffpsin - sine result * * ffpcos - cosine find log of the number to be used movem.l d3-d5,-(sp) save multiply work registers jsr ffpmde size: 334 bytes stack work: 38 bytes * * * * condition codes: ffpsin ffpcos ffptan ffpsincs * * fast floating point sine/cosine/tangent * * ndy for * * graphics processing. * * 2) input arguments larger than two pi * * su end result * * ffptan - tangent result * * ffpsincs - both sine and cosine * * ul2 multiply by the exponent movem.l (sp)+,d3-d5 restore multiply work registers * if overflow * * z - set if result in d7 is zero * * n - set if result in d7 is negative * * ffer reduced precision. the larger * * the argument, the smaller the precision.* * excessively large arguments pi skeleton to 32 bits precision inv2pi equ $a2f9833e inverse of two-pi kinv equ $9b74ee40 ne cosine tangent opt pcs section 9 xdef ffpsin,ffpcos,ffptan,ffpsincs entrynal parameter tst.b d7 set condition codes rts return to call seen. * * * * time: (8mhz no wait states and argument * * asss fpschl check very small values ************************** * cosine only entry point* ******************which have * * less than 5 bits of precision are * * returned unchanged with the "v" bit set.* * 3) for floating k inverse nkfact equ $ec916240 negative k inverse ******************************************* points xref ffptheta inverse tangent table xref ffpmul2,ffpdiv,ffpsub er ************************ * sine only entry point* ************************ ffpsin clr.w -(sp) flagumed within +-pi) * * * * ffpsin 413 microsecon******** ffpcos move.w #1,-(sp) flag cosine with positive value bra.s fpscom enter c tangent angles of infinite value * * the largest possible positive number * * is returned ($ffffff7f). this* * entry for returning both sine and cosine * ******************************************** ffpsincs move.w #-2,-(sp) multiply, divide and subtract xref ffptnorm transcendental normalize routine xref ffpcpy sine with zero * sine and tangent values < 2**-9 return identities fpschl tst.b d7 test sign ds * * ffpcos 409 microseconds * * ffptan 501 microseconds * * ffommon code * negative sine/tangent small value check fpschm cmp.b #$80+$40-8,d7 ? less or same as -2**-9 still * * gives results well within single * * precision calculation. * * 4) spot flag both sine and cosine wanted bra.s fpscom enter common code ********************** * trt copyright stub pi equ $c90fdb42 floating constant pi fixedpi equ $c90fdaa2 bmi.s fpschm branch minus cmp.b #$40-8,d7 ? less or same than 2**-9 bls.s psincs 420 microseconds * ************************************************* page ffpsin idnt 1,2 ffp si bhi.s fpscom continue if not too small * return argument fpsrti add.l #2,sp rid inter checks show errors bounded by * * 4 x 10**-7 but for arguments close to * * pi/2 intervals where 10**-5 isangent entry point* ********************** ffptan move.w #-1,-(sp) flag tangent with minus value bra. fpsrti return identity * save registers and insure input within + or - pi range fpscom movem.l d1-d6/a0, d5,d4 shift zeroes into fractional part or.b #$ff,d4 do not remove sign and exponentt argument jsr ffpmul2 divide by 2pi (via multiply inverse) * convert quotient to float integer bls.s fpssh1 no, go ahead and shift move.l #0,d7 force to zero fpssh1 lsr.l * or.b #$02,ccr force v bit on dc.l $003c0002 *****assembler error***** on for reduction within +-pi fpsnlr move.l #$0c90fdaa,d4 fixedpi>>4 load pi move.l d2,d7 c-(sp) save all work registers move.l d7,d2 copy input over add.b d7,d7 and.l d4,d7 strip fractional bits entirely move.l #pi+1,d6 load up 2*pi con move.b d7,d5 copy exponent over and.b #$7f,d5 rid sign from exponent d2,d7 convert to fixed point * force to +pi or below fpspck cmp.l d4,d7 ? greater than pi movem.l (sp)+,d1-d6/a0 restore registers add.l #2,sp clean internal argument off stack opy float argument clr.b d7 clear sign and exponent tst.b d2 test rid sign bit cmp.b #(64+5)<<1,d7 ? abs(arg) < 2**6 (32) bls.s fpsnlr branch yestant jsr ffpmul2 multiply back out move.l d7,d6 setup to subtract multip sub.b #64+24,d5 find fractional precision neg.b d5 make positive move.l ble.s fpsckm branch not sub.l d4,d7 subtract sub.l d4,d7 rts return to caller * we must find mod(arg,twopi) since argument is too large for subtractisign bmi.s fpsnmi branch negative sub.b #64+6,d2 obtain shift value s, not too large * argument is too large to subtract to within range cmp.b #(64+20)<<1,d7 ? test excessive sle of twopi move.l d2,d7 move argument in jsr ffpsub find remainder of t #-1,d4 setup mask of all ones clr.b d4 start zeroes at low byte lsl.l . twopi bra.s fpspck and check again fpsnmi sub.b #$80+64+6,d2 rid sign ons fpsgpr move.l #inv2pi,d6 load up 2*pi inverse constant move.l d2,d7 copy over inpu neg.b d2 for 5 bit non-fraction bits cmp.b #31,d2 ? very small number ize (>2**20) bls.s fpsgpr no, go ahead and use * error - argument so large result has no precision wopi divide move.l d7,d2 use it as new input argument * convert argument to binary(31,26) precisiand get shift value neg.b d2 for 5 non-fractional bits cmp.b #31,d2 ? ptheta,a0 load arctangent table move.l #23,d1 loop 24 times move.l #-1,d2 move.l #nkfact,d6 y=negative inverse k factor seed move.l #$3243f6a8,d4 fixedpi>>2, setup bpl.s fssincos branch for sine or cosine add.b #1,d1 see if was -1 for tangent . twopi bra.s fpsnck and check again ***************************************** * cordic ca sub.l (a0)+,d7 arg=arg-table(n) dbra d1,fsinlp loop until done bra.s very small number bls.s fpssh2 no, go ahead and shift move.l #0,d7 force t prime shift counter * cordic loop fsinlp add.w #1,d2 increment shift count move.l d5,d3 fixed pi/2 constant asl.l #3,d7 now to binary(31,29) precision bmi.s fpsap2 bne.s fsdual no, must be both sin and cosine * tangent finish bsr.s fsfloat lculation registers: * * d1 - loop count a0 - table pointer * * d2 - shift count * * d3 - x' fscom enter common code fsbmi add.l d4,d5 x=x+y' sub.l d3,d6 o zero fpssh2 lsr.l d2,d7 convert to fixed point neg.l d7 make negative copy x move.l d6,d4 copy y asr.l d2,d3 shift for x' branch if minus to add pi/2 neg.l d6 y=positive inverse k factor seed neg.l d4 float y (sin) move.l d6,d7 setup for divide into move.l d5,d6 prepare x d5 - x * * d4 - y' d6 - y * * d7 - test argument * *********y=y-x' add.l (a0)+,d7 arg=arg+table(n) dbra d1,fsinlp loop until done * no neg.l d4 make -pi * force to -pi or above fpsnck cmp.l d4,d7 ? less than -pi asr.l d2,d4 shift for y' tst.l d7 test arg value bmi.s fsbmi subtract pi/2 for positive argument fpsap2 add.l d4,d7 add constant lea ff bsr.s fsfloat float x (cos) beq.s fstinf branch infinite result jsr******************************** * input within range, now start cordic setup fpsckm move.l #0,d5 x=0 w split up tangent and ffpsincs from sine and cosine fscom move.w 7*4(sp),d1 reload internal parameter bge.s fpsckm branch not sub.l d4,d7 add sub.l d4,d7 branch minus test sub.l d4,d5 x=x-y' add.l d3,d6 y=y+x' ffpdiv tangent = sin/cos fsinfrt movem.l (sp)+,d1-d6/a0 restore registers add.l #2,sp return a zero rts return to caller fsfneg asr.l #8,d4 see if allrestore cosine derivitive bra.s fssine and continue restoring sine on the sly * fsfloat - float i tst.b d7 and condition code test movem.l (sp)+,d1-d6/a0 restore registers  jmp ffptnorm 16-bit no-MMU problem end  delete internal parameter rts return to caller * tangent is infinite. return ones bits 8-31 add.l #1,d4 ? goes to zero * bne ffptnorm normalize if not nternal precision but truncate to zero if < 2**-21 fsfloat move.l d6,d4 copy internal precision value add.l #2,sp delete internal parameter rts return to caller * both s jmp ffptnorm 16-bit no-MMU problem end  maximum positive number. fstinf move.l #$ffffff7f,d7 largest ffp number bra.s fsinfrt andtoo small bne dobranch bra.s fsfzro return zero dobranch: bmi.s fsfneg branch negative cmp.l #$000000ff,d6 ? test magnitude * bhi ffine and cosine fsdual move.l d5,-(sp) save cosine derivitive bsr.s fsfloat convert si clean up * sine and cosine fssincos beq.s fssine branch if sine move.l d5,d6 u jmp ffptnorm 16-bit no-MMU problem end ptnorm normalize if not too small bhi dobranch fsfzro move.l #0,d6 ne derivitive to float move.l d6,6*4(sp) place sine into saved d6 move.l (sp)+,d6 se x for cosine fssine bsr.s fsfloat convert to float move.l d6,d7 return result  jmp ffptnorm 16-bit no-MMU problem end  ttl fast floating point hyperbolics (ffpsinh) *************************************** * (c) copyright 1981 by m* * sinh 623 microseconds * * cosh 601 microseconds * * tanh 623 micr * * x - undefined * * * * notes: turn if overflow (result is highest number) move.l d7,-(sp) save result move.l d7,d6 setup for di * * * * code size: 36 bytes stack work: 50 bytes * * ****** * ffpcosh * * this function is defined as * * x -x * * otorola inc. * *************************************** ************************************************* * ffpsoseconds * * * ************************************************* * * 1) an overflow will produce the maximum * * signed value with the "v" bit set. vide into one move.l #fpone,d7 load floating point one jsr ffpdiv compute e to -x as the inverse * * calls: ffpexp, ffpdiv, ffpadd and ffpsub * * e + e * * -------- * * 2 * * we evaluate exactly as definedinh/ffpcosh/ffptanh * * fast floating point hyperbolics * * page ffpsinh idnt 1,2 ffp sinh cosh tanh opt pcs section 9 xdef * * 2) spot checks show at least seven digit * * precision. * * move.l (sp)+,d6 prepare to add together jsr ffpadd create the numerator beq.s fh * * condition codes: * * z - set if the result is zero * * n - set if * ********************************** ffpcosh move.l d6,-(sp) save our one work register and.b #$7f,d7 * * input: d7 - floating point argument * * * * output: d7 - h ffpsinh,ffpcosh,ffptanh entry points xref ffpexp,ffpdiv,ffpadd,ffpsub functions called xref * * time: (8mhz no wait states assumed) * * crtn return if zero result sub.b #1,d7 divide by two bvc.s fhcrtn return if no underflow the result is negative * * v - set if overflow occurred * * c - undefined force positive (results same but exp faster) jsr ffpexp evaluate e to the x bvs.s fhcrtn reyperbolic result * * * * all other registers are transparent ffpcpyrt copyright stub fpone equ $80000041 floating one **************************** move.l #0,d7 return zero if underflow fhcrtn movem.l (sp)+,d6 restore our work register rts n movem.l (sp)+,d6 restore our work register rts return to caller with answer page *** compute e to -x as the inverse move.l (sp),d6 prepare to add together jsr ffpadd create the jsr ffpsub create numerator move.l (sp)+,d6 restore denominator jsr ffpdiv creomes: * * x * * sinh = e - cosh * * * ******* ? zero beq.s ffptrtn return true zero if so add.b #1,d7 x times two bvs.s return to caller with answer page ********************************** * ffpsinh * ******************************* * ffptanh * * this function is defined as * * sinh/cosh which redunumerator beq.s fhszro branch if zero result sub.b #1,d7 divide by two bvc.s fhate result add.l #4,sp free e**2x off of stack ffptrtn move.l (sp)+,d6 restore our work register *************************** ffpsinh move.l d6,-(sp) save our one work register jsr ffpexp evaluate effptovf branch if overflow/underflow jsr ffpexp evaluate e to the 2x bvs.s ffptovf2 branch i * this function is defined as * * x -x * * e - e * * -------ces to: * * 2x * * e - 1 * * ------ * * szro branch if no underflow move.l #0,d7 zero if underflow fhszro move.l d7,d6 move for final subt rts return to caller with answer ffptovf move.l #$80000082,d7 float one with exponent over to left to the x bvs.s fhsrtn return if overlow for maximum value move.l d7,-(sp) save result f too large move.l d7,-(sp) save result move.l #fpone,d6 load floating point one jsr - * * 2 * * however, we evaluate it via * * the cosh formula since its * * a 2x * * e + 1 * * * * which we evaluate. ract move.l (sp)+,d7 reload e to x again and free jsr ffpsub result is e to x minus cosh fhsrt roxr.b #1,d7 shift in correct sign bra.s ffptrtn and return ffptovf2 move.l #fpone,d7 retumove.l d7,d6 setup for divide into one move.l #fpone,d7 load floating point one jsr ffpdiv ffpadd add 1 to e**2x move.l d7,-(sp) save denominator move.l 4(sp),d7 now prepare to subtract ddition in the numerator * * is safer than our subtraction * * * * thus the function bec * ********************************** ffptanh move.l d6,-(sp) save our one work register tst.b d7 rn +1 as result bra.s ffptrtn end  * * notes: * * 1) no overflows or underflows can * * occur. * * * * n - cleared * * z - set if rt move.b d7,d3 copy s+exponent over beq.s fpsrtn return zero if zero argument bmi.s fpsitorola inc. * ******************************************* ******************************************** * ffps********** page ffpsqrt idnt 1,1 ffp square root section 9 xdef ffpsqrt entry point n +1 as result bra.s ffptrtn end  * * 2) a negative argument causes the * * absolute value to be used and the * * "v" bit setresult is zero * * v - set if argument was negative* * c - cleared * * xnv negative, reject with special condition codes lsr.b #1,d3 divide exponent by two bcc.s fpsqrt subroutine * * * * input: * * xref ffpcpyrt copyright notice * negative argument handler fpsinv and.b #$7f,d7 take absolute value n +1 as result bra.s ffptrtn end  to indicate that a * * negative square root was attempted. * * * * times: - undefined * * * * registers d3 thru d6 are volatile * * even branch exponent was even add.b #1,d3 adjust odd values up by one lsr.l #1,d7 offset o d7 - floating point argument * * * * output: bsr.s ffpsqrt find sqrt(abs(x)) * or.b $02,ccr set "v" bit dc.l $003c0002 **assembler errorn +1 as result bra.s ffptrtn end  * * argument zero 3.50 microseconds * * minimum time > 0 187.50 microseconds * * * code: 194 bytes stack work: 4 bytes * * dd exponent's mantissa one bit fpseven add.b #$20,d3 renormalize exponent swap.w d3 save result s+ex * * d7 - floating point square root * * * * condition codes: ** rts return to caller ********************* * square root entry * ********************* ffpsq ttl fast floating point square root (ffpsqrt) ******************************************* * (c) copyright 1981 by mo * average time > 0 193.75 microseconds * * maximum time > 0 200.00 microseconds * **********************************p for final move move.w #23,d3 setup loop for 24 bit generation lsr.l #7,d7 prepare first test no rounding add.l #1,d7 round up (cannot overflow) fpsfin lsl.l #8,d7 normalize result md4 update new test value fpszero add.l d4,d4 multiply test result by two move.l d4,d5 copy in cas square root calculation * this is an optimized scheme for the recursive square root algorithm: * * step n+1: * dc.l 1<<7,1<<6,1<<5,1<<4,1<<3,1<<2,1<<1,1<<0 dc.l 0,0 end  value move.l d7,d4 d4 - previous value during loop move.l d7,d5 d5 - new test value during loove.l d6,a0 restore address register swap.w d3 restore s+exp save move.b d3,d7 move e next bit zero sub.l (a0)+,d5 subtract the '01' ending pattern sub.l d7,d5 subtract result bit 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 zedc.l 1<<7,1<<6,1<<5,1<<4,1<<3,1<<2,1<<1,1<<0 dc.l 0,0 end op move.l a0,d6 save address register lea fpstbl(pc),a0 load table address move.l in final sign+exponent fpsrtn rts return to caller * table to furnish '01' shifts during the algorithm los collected so far fpsent dbmi d3,fpsone branch if a one generated in the result dbpl d3,fpszero branch iro in result r n+1 * n+1 * precalculations are done sudc.l 1<<7,1<<6,1<<5,1<<4,1<<3,1<<2,1<<1,1<<0 dc.l 0,0 end #$00800000,d7 d7 - initial result (must be a one) sub.l d7,d4 preset old value in case zero bit next op 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 f a zero generated * all 24 bits calculated. now test result of 25th bit bls.s fpsfin branch next bit zero,ch that the entry is midway into step 2 fpsone bset d3,d7 insert a one into this position move.l d5, sub.l #$01200000,d5 combine first loop calculations bra.s fpsent go enter loop calculations * dc.l 1<<7,1<<6,1<<5,1<<4,1<<3,1<<2,1<<1,1<<0 dc.l 0,0 end  ttl arctangent cordic table - ffptheta ffptheta idnt 1,1 ffp arctangent table ****************************001ffff>>3 arctan(2**-15) dc.l $0000ffff>>3 arctan(2**-16) dc.l $00007fff>>3 arctan(2**-17) *-4) dc.l $07ff556e>>3 arctan(2**-5) dc.l $03ffeaab>>3 arctan(2**-6) dc.l $01fffdnt values 2**-n where * * n ranges from 0 to 24. the format is binary(31,29) * * precision (i.e. the binary point is betwe25) dc.l $0000003f>>3 arctan(2**-26) end *********** * (c) copyright 1981 by motorola inc. * *************************************** section 9 dc.l $00003fff>>3 arctan(2**-18) dc.l $00001fff>>3 arctan(2**-19) dc.l $00000fff>>3 55>>3 arctan(2**-7) dc.l $00ffffaa>>3 arctan(2**-8) dc.l $007ffff5>>3 arctan(2**-9) den bits * * 28 and 27 giving two leading non-fraction bits.) * *****************************************************25) dc.l $0000003f>>3 arctan(2**-26) end  xdef ffptheta external definition ********************************************************* * arctan(2**-20) dc.l $000007ff>>3 arctan(2**-21) dc.l $000003ff>>3 arctan(2**-22) dc.lc.l $003ffffe>>3 arctan(2**-10) dc.l $001fffff>>3 arctan(2**-11) dc.l $000fffff>>3 arctan( ttl ffp transcendental normalize internal routine (ffptnorm) ffptnorm idnt 1,2 ffp transcendental internal **** ffptheta dc.l $1921fb54 $c90fdaa2>>3 arctan(2**0) dc.l $76b19c15>>3 arctan(2**-1) d25) dc.l $0000003f>>3 arctan(2**-26) end  arctangent table for cordic * * * * the following table i $000001ff>>3 arctan(2**-23) dc.l $000000ff>>3 arctan(2**-24) dc.l $0000007f>>3 arctan(2**2**-12) dc.l $0007ffff>>3 arctan(2**-13) dc.l $0003ffff>>3 arctan(2**-14) dc.l $0normalize xdef ffptnorm section 9 *************************************** * (c) copyright 198c.l $3eb6ebf2>>3 arctan(2**-2) dc.l $1fd5ba9a>>3 arctan(2**-3) dc.l $0ffaaddb>>3 arctan(2*s used during cordic * * transcendental evaluations for sine, cosine, and * * tangent and represents arctange-25) dc.l $0000003f>>3 arctan(2**-26) end 1 by motorola inc. * *************************************** ****************************** * ffptnorm *t right fsfnrm move.b d4,d6 insert sign+exponent fsfrtn rts return to caller offset by 16 shifts fsfcont add.l d6,d6 shift another bit dbmi d4,fsfcont /* Copyright 1982 Alcyon Corporation 8716 Production Ave. San Diego, Ca. 92121 */ /*char *version "@(#)ffptof.c 1.2onent tst.l d6 test for non-negative beq.s fsfrtn return if zero * normalize bin(29,31) value * * and convert to float * * * * input: d6 - internal fixed * end  shift left until normalized tst.b d6 ? should we round up bpl.s fsfnrm 10/19/83"; */ /* * FFP Floating Point Representation to Internal Representation : * FFP Standard Single Precision Re bpl.s fsfpls branch is >= 0 neg.l d6 absolutize input move.b # * output: d6 - ffp float * * cc - reflect value * * notes: * * 1) d4 is destroyed. * end  no, branch rounded add.l #$100,d6 round up bcc.s fsfnrm branch no overflowpresentation Floating Point * * float * ffptof(lf) * long lf; * * Largest positive number is 3.4 * 10^18 and the sma$c2,d4 setup initial negative exponent fsfpls cmp.l #$00007fff,d6 test for a small number bhi * * * time: (8mhz no wait state) * * zero 4.0 microsec. * * avg else 17.0 microsec. * end  roxr.l #1,d6 adjust back for bit in 31 add.b #1,d4 make up for last shifllest positive * number is 1.2 * 10^-20. * Rely's on the fact that a long and a float are both 32 bits. */ float ffpto.s fsfcont branch if not small swap.w d6 swap halves sub.b #16,d4 * * ****************************** ffptnorm move.l #$42,d4 setup initial exp end f(lf) long lf; { register int exp, count, fsign; float f; if (lf == 0L) return(0.0); fsign = (lf & 0x80); exp = 10/19/83"; /* floor - returns the largest integer (as a double precision number) not greater than x. */ double fouble y; { double z; double retval; register long i; double fabs(); double absx; double absy; absx = fabs(x);  exp--; } if (fsign) f = -f; return(f); } urn( retval ); }  (lf & 0x7f) - 0x40; lf = (lf>>8) & 0xffffff; /* 24 bits of fraction */ f = lf; f = f / 16777216.0; /* 2 ^ 24 */ while (loor(x) double x; { register long i; double retval; if ( x < 0 ) x -= 0.99999999999999; i = x; retval = i; re absy = fabs(y); for(z = absx; z - absy >= 0. ; z -= absy) ; i = z; if( x < 0.0 ) i *= -1; retval = i; return(  exp--; } if (fsign) f = -f; return(f); } exp < 0) { /* negative exp : 2^-? */ f = f / 2.0; exp++; } while (exp > 0) { /* positive exp : 2^+? */ f = f * 2.0;turn( retval ); } retval ); } /* Copyright 1983 Alcyon Corporation 8716 Production Ave. San Diego, Ca. 92121 */ /*char *version "@(#)fmod.c 1.2 exp--; } if (fsign) f = -f; return(f); } urn( retval ); } /* Copyright 1983 Alcyon Corporation 8716 Production Ave. San Diego, Ca. 92121 */ /*char *version "@(#)floor.c 1.2 etval ); }  10/19/83"; /* fmod - returns the number f such that x = iy + f, and 0 <= f <= y. */ double fmod(x,y) double x; d exp--; } if (fsign) f = -f; return(f); } urn( retval ); } etval ); } ove.l 8(r14),r7 move.l 12(r14),r6 jsr ffpcmp movem.l (sp)+,d3-d7 unlk r14 rts r7 jsr ffpcos move.l r7,r0 movem.l (sp)+,d3-d7 unlk r14 rts +,d3-d7 unlk r14 rts * * Floating Point Cosine : * Front End to FFP Floating Point Package. * * double * etval ); } ve.l 8(r14),r7 move.l 12(r14),r6 jsr ffpcmp movem.l (sp)+,d3-d7 unlk r14 rts * * Floating Point Compare : * Front End to FFP Floating Point Package. * * int * r7 jsr ffpcos move.l r7,r0 movem.l (sp)+,d3-d7 unlk r14 rts ,d3-d7 unlk r14 rts  cos(farg) * double farg; * * Input : in radians * Returns : cosine of Floating point num* * Floating Point Addition : * Front End to FFP Floating Point Package. * * double * fpadd(addend,adder) * double adve.l 8(r14),r7 move.l 12(r14),r6 jsr ffpcmp movem.l (sp)+,d3-d7 unlk r14 rts  fpcmp(source,dest) * double source, dest; * * Returns : Condition codes based on Floating Point Cr7 jsr ffpcos move.l r7,r0 movem.l (sp)+,d3-d7 unlk r14 rts ,d3-d7 unlk r14 rts ber * .globl cos .globl _cos .globl ffpcos .text cos: _cos: ~~cos: link r14,#-4 movem.l d3-d7,-(sp) move.l 8(r14)dend, adder; * * Returns : Sum of two floating point numbers * .globl fpadd .globl _fpadd .globl ffpadd .text fpadd: _fve.l 8(r14),r7 move.l 12(r14),r6 jsr ffpcmp movem.l (sp)+,d3-d7 unlk r14 rts ompare * .globl fpcmp .globl _fpcmp .globl ffpcmp .text fpcmp: _fpcmp: ~~fpcmp: link r14,#-4 movem.l d3-d7,-(sp) m,d3-d7 unlk r14 rts ,r7 jsr ffpcos move.l r7,r0 movem.l (sp)+,d3-d7 unlk r14 rts padd: ~~fpadd: link r14,#-4 movem.l d3-d7,-(sp) move.l 8(r14),r7 move.l 12(r14),r6 jsr ffpadd move.l r7,r0 movem.l (sp)* * Floating Point Division : * Front End to FFP Floating Point Package. * * double * 0 movem.l (sp)+,d7 unlk r14 rts  exp(x) * double x; * * Returns : e ^ x (where e = 2.718...) * .globl exp .globl _exp .glo),r7 move.l 12(r14),r6 jsr ffpdiv move.l r7,r0 movem.l (sp)+,d3-d7 unlk r14 rts d7,-(sp) move.l 8(r14),r7 jsr ffplog move.l r7,r0 movem.l (sp)+,d7 unlk r14 rts  fpdiv(divisor,dividend) * double divisor, dividend; * * Return : Floating Point Quotient * 0 movem.l (sp)+,d7 unlk r14 rts bl ffpexp .text exp: _exp: ~~exp: link r14,#-4 movem.l d7,-(sp) move.l 8(r14),r7 jsr ffpexp move.l r7,),r7 move.l 12(r14),r6 jsr ffpdiv move.l r7,r0 movem.l (sp)+,d3-d7 unlk r14 rts 7,-(sp) move.l 8(r14),r7 jsr ffplog move.l r7,r0 movem.l (sp)+,d7 unlk r14 rts .globl fpdiv .globl _fpdiv .globl ffpdiv .text fpdiv: _fpdiv: ~~fpdiv: link r14,#-4 movem.l d3-d7,-(sp) move.l 8(r1r0 movem.l (sp)+,d7 unlk r14 rts * * Floating Point Multiplication : * Front End to FFP Floating Point Package. * * double7,-(sp) move.l 8(r14),r7 jsr ffplog move.l r7,r0 movem.l (sp)+,d7 unlk r14 rts 4),r7 move.l 12(r14),r6 jsr ffpdiv move.l r7,r0 movem.l (sp)+,d3-d7 unlk r14 rts * * Floating Point Logarithm : * Front End to FFP Floating Point Package. * * double * log(x) * double x; * * Retur0 movem.l (sp)+,d7 unlk r14 rts  * fpmul(multiplier,multiplicand) * double multiplier, multiplicand; * * Return : Result o* * Floating Point Exponent : * Front End to FFP Floating Point Package. * * double * 7,-(sp) move.l 8(r14),r7 jsr ffplog move.l r7,r0 movem.l (sp)+,d7 unlk r14 rts ),r7 move.l 12(r14),r6 jsr ffpdiv move.l r7,r0 movem.l (sp)+,d3-d7 unlk r14 rts ns : the floating point logarithm * .globl log .globl _log .globl ffplog .text log: _log: ~~log: link r14,#-4 movem.l f Floating Point Multiply * .globl fpmul .globl _fpmul .globl fpmult .globl _fpmult .globl ffpmul2 .text fpmult: _fpmulr14,#-4 movem.l d3-d7,-(sp) move.l 8(r14),r7 jsr ffpneg move.l r7,r0 movem.l (sp)+,d3-d7 unlk r14 rts * * Floating Point Sine : * Front End to FFP Floating Point Package. * * double * sin(farg) * double farg; * * Inpul2 move.l r7,r0 movem.l (sp)+,d3-d7 unlk r14 rts 14),r7 move.l 12(r14),r6 jsr ffppwr move.l r7,r0 movem.l (sp)+,d3-d7 unlk r14 rts t: fpmul: _fpmul: ~~fpmul: link r14,#-4 movem.l d3-d7,-(sp) move.l 8(r14),r7 move.l 12(r14),r6 jsr ffpm* * Floating Point Power : * Front End to FFP Floating Point Package. * * double * pow(x,y) * double x, y; * * Retur14,#-4 movem.l d3-d7,-(sp) move.l 8(r14),r7 jsr ffpneg move.l r7,r0 movem.l (sp)+,d3-d7 unlk r14 rts t : in radians * Returns : sine of Floating point number * .globl sin .globl _sin .globl ffpsin .text sin: _sin: ~~sin:* * Floating Point Negation : * Front End to FFP Floating Point Package. * * double * fpneg(farg) * double farg; * 14),r7 move.l 12(r14),r6 jsr ffppwr move.l r7,r0 movem.l (sp)+,d3-d7 unlk r14 rts ul2 move.l r7,r0 movem.l (sp)+,d3-d7 unlk r14 rts rns : x ^ y * .globl pow .globl _pow .globl ffppwr .text pow: _pow: ~~pow: link r14,#-4 movem.l d3-d7,-(sp) move.l 8(r14,#-4 movem.l d3-d7,-(sp) move.l 8(r14),r7 jsr ffpneg move.l r7,r0 movem.l (sp)+,d3-d7 unlk r14 rts  link r14,#-4 movem.l d3-d7,-(sp) move.l 8(r14),r7 jsr ffpsin move.l r7,r0 movem.l (sp)+,d3-d7 unlk r14 rts * Returns : negated Floating point number * .globl fpneg .globl _fpneg .globl ffpneg .text fpneg: _fpneg: ~~fpneg: linkl2 move.l r7,r0 movem.l (sp)+,d3-d7 unlk r14 rts r14),r7 move.l 12(r14),r6 jsr ffppwr move.l r7,r0 movem.l (sp)+,d3-d7 unlk r14 rts  link r14,#-4 movem.l d3-d7,-(sp) move.l 8(r14),r7 jsr ffpsin move.l r7,r0 movem.l (sp)+,d3-d7 unlk r14 rts  r14,#-4 movem.l d3-d7,-(sp) move.l 8(r14),r7 jsr ffpneg move.l r7,r0 movem.l (sp)+,d3-d7 unlk r14 rts l2 move.l r7,r0 movem.l (sp)+,d3-d7 unlk r14 rts 14),r7 move.l 12(r14),r6 jsr ffppwr move.l r7,r0 movem.l (sp)+,d3-d7 unlk r14 rts  link r14,#-4 movem.l d3-d7,-(sp) move.l 8(r14),r7 jsr ffpsin move.l r7,r0 movem.l (sp)+,d3-d7 unlk r14 rts double subtrahend, minuend; * * Returns : Floating point subtraction result * .globl fpsub .globl _fpsub .globl ffpsub .t r14 rts de #include /* Delimiters */ #define NEWLINE '\n' #define TAB '\t' #define SPACE ' ' #define * Input : in radians * Returns : square root of Floating point number * .globl sqrt .globl _sqrt .globl ffpsqrt .text s movem.l (sp)+,d3-d7 unlk r14 rts  link r14,#-4 movem.l d3-d7,-(sp) move.l 8(r14),r7 jsr ffpsin move.l r7,r0 movem.l (sp)+,d3-d7 unlk r14 rts ext fpsub: _fpsub: ~~fpsub: link r14,#-4 movem.l d3-d7,-(sp) move.l 8(r14),r7 move.l 12(r14),r6 jsr ffpsub move.l r7,r r14 rts NULL '\0' /* returns from __next() */ #define CHAR 0 #define NOT_WHT -1 #define NOT_WHT_NL 1 /* returnqrt: _sqrt: ~~sqrt: link r14,#-4 movem.l d3-d7,-(sp) move.l 8(r14),r7 jsr ffpsqrt move.l r7,r0 movem.l (sp)+,d3-d7 unl0 movem.l (sp)+,d3-d7 unlk r14 rts s from __scan() */ #define NORETURN 0 #define VALID 1 #define NOMATCH -1 #define AT_EOF -2 #define ERROk r14 rts /* Copyright 1982, 1983 Alcyon Corporation 8716 Production Ave. San Diego, Ca. 92121 @(#)fscanf.c 1.1 movem.l (sp)+,d3-d7 unlk r14 rts * * Floating Point Subtraction : * Front End to FFP Floating Point Package. * * double * fpsub(subtrahend,minuend) * R -3 FILE *__stream; char **_p, *__sstr, __holdch; int __smode, __hold; scanf(parlist) char *parlist; { __s r14 rts  11/9/83 */ /* ** formatted read routine ** ** functionally equivalent to scanf in portable C library */ #inclu* * Floating Point Square Root : * Front End to FFP Floating Point Package. * * double * sqrt(farg) * double farg; * movem.l (sp)+,d3-d7 unlk r14 rts mode = 0; _p = &parlist; return(__doscanf()); } fscanf(stream,parlist) FILE *stream; char *parlist; { if( k at characters in the conversion string * and do their bidding */ __scan(spec, result) char **spec; char *result; */ return(nmatch ? nmatch : NOMATCH); default: /* syntax error */ ); case 'x': case 'X': return(__dec(result, length ? length : 100, 16, longf)); ch = *format++) { case NULL: return(nmatch); case '%': if( *format != '%' ) { break; case 'l': if( longf ) return(ERROR); longf = 1; (stream->_flag&(_RMODE|_UPDATE)) == 0 || feof(stream) ) return(EOF); __smode = 1; __stream = strea { register int longf, length; register char ch; extern int __strend(), __splend(); longf = length = return(NOMATCH); } break; } format++; defaul case 'c': case 'C': if( longf ) return(ERROR); return(__char(result, switch (__scan(&format, *_p)) { case VALID: /* good return*/ _p break; case 'h': /* short */ if( longf ) return(ERROR); longf = Nm; _p = &parlist; return(__doscanf()); } sscanf(s,parlist) char *s, *parlist; { __smode = 2; __sstr = 0; while( 1 ) { switch (ch = *(*spec)++) { case '*': result = 0; break; t: match_ch = __next(CHAR); if( ch != match_ch ) { __unget(match_ch); length ? length : 1)); case 's': case 'S': if( longf ) return(ERROR); ++; nmatch++; case NORETURN: /* no return*/ break; OMATCH; break; case 'o': case 'O': return(__dec(result, length ? length : 10s; _p = &parlist; return(__doscanf()); } __doscanf() { register int nmatch; register char ch; case '0': case '1': case '2': case '3': case '4': case '5': return(nmatch ? nmatch : AT_EOF); } break; } } } /* * main scan routine -- loo return(__strx(result, length ? length : 100, __strend)); case 'e': case 'E': cas case NOMATCH: /* no match */ return(nmatch); case AT_EOF: /* end of file 0, 8, longf)); case 'd': case 'D': return(__dec(result, length ? length : 100, 10, longf) char *format; register char match_ch; nmatch = __hold = 0; format = *_p++; while( 1 ) { switch ( case '6': case '7': case '8': case '9': length = length * 10 + ch - '0'; e 'f': case 'F': if( longf ) return(ERROR); return(__float(result, length ?sult = result; *lresult = lres; } else *result = ires; return(VALID); } /* * get a floati= __next(NOT_WHT); } ok = 0; while( (val = __digit(ch, base)) >= 0 && ndigit++ < length ) { ok++; return(NOMATCH); if( ch <= '7' ) return(ch - '0'); if( base == 8 ) return(NOMATCH); if( ch <; int length; int base; int longf; { register char ch; register int val; register int ndigit; reF); if( mode == 0 ) return(ch); while( ch == SPACE || ch == TAB || ch == NEWLINE ) { if( ch == NEWLI length : 100)); /*return(ERROR); /* not yet implemented */ case '[': if( longfng point constant */ __float(result, length) register double *result; int length; { char buffer[100]; double val if( longf ) lres = lres * base + val; else ires = ires * base + val; ch = __next(= '9' ) return(ch - '0'); if( base == 10 || ch < 'A' ) return(NOMATCH); if( ch <= 'F' ) retgister long *lresult; register long lres; register int ires; register int minus, ok; ires = 0; NE && mode < 0 ) break; ch = __getch(); } return(ch); } /* * check an input character for ) return(ERROR); if( __inits(spec) ) return(ERROR); return(__strx(r; int ret, ch; ret = __strx(buffer, 100, __strend); val = atof(buffer); *result = val; return(ret); CHAR); } __unget(ch); if( !ok ) return(NOMATCH); if( !result ) return(NORETURN); if( urn(ch - 'A' + 10); if( ch < 'a' || ch > 'f' ) return(NOMATCH); return(ch - 'a' + 10); } /* * check for lres = 0; ndigit = minus = 0; switch (ch = __next(NOT_WHT_NL)) { case NULL: case EOF: a valid constant digit (octal, decimal, * or hex) if found, return the proper numeric value. Negative results * indicate eresult, length ? length : 100, __splend)); default: return(ERROR); } } } /* } __next(mode) int mode; { /* * mode -1: get next non-space or non-tab * mode 0: get next character * mode 1: gminus ) if( longf ) lres = -lres; else ires = -ires; if( longf ) { lre an end of string delimiter */ __strend(cha) char cha; { register char ch; if( (ch = cha) == EOF ) return(AT_EOF); case '-': minus = 1; case '+': ndigit++; ch ror. */ __digit(ch, base) register char ch; register int base; { register int n; if( ch < '0' ) * get a constant -- octal, decimal, or hex depending on base */ __dec(result, length, base, longf) register int *resultet next non-space, non-tab, or non-newline */ register int ch; if( (ch = __getch()) == EOF ) return(EO return(EOF); if( ch == SPACE || ch == TAB || ch == NEWLINE || ch == NULL ) return(VALID); return(NORETURN); if( !result ) return(NORETURN); *result = 0; return(VALID); } /* * getting a character constant */ ngth; register int (*endfn)(); { register char ch; extern int __splend(); register int imode, notok; c = *__sstr; if( c ) __sstr++; else return(EOF); return(c); } /* * put back a char forl; ch = *(*spec)++; if( ch == '^' ) { val = 0; ch = *(*spec)++; } else val = 1;{ case 0: return(__gstdi()); case 1: return(getc(__stream)); case 2: } char __splset[128]; /* * check for the occurrance of any character in the set which * the user wants to be end- __char(result, length) register char *result; register int length; { register char *r, ch; register int notok = 1; imode = (endfn != __splend); if (imode) { ch = __next(NOT_WHT_NL); __unget(ch); /* bypass tab further scanning */ __ungs(c) char c; { if( c ) __sstr--; } __gstdi() { if( !__hold) r for (i = 1; i < 128; i++) __splset[i] = val; val = 1 - val; while( ch != ']' ) { if( ch == 0 ) return(__gs()); } } __unget(ch) char ch; { switch(__smode) { case 0: __ugstdi(ch); of-string delimiters */ __splend(ch) char ch; { if( ch == EOF ) return(EOF); return(__splset[ch]); }l; r = result; l = length; while( l-- ) { if( (ch = __next(CHAR)) <= 0 ) { if( l + 1 ==or space... */ } while( !(*endfn)( (ch = __next(imode)) ) && length-- > 0 ) { if( result ) *result+eturn(getchar()); else { __hold = 0; return(__holdch); } } __ugstdi(ch) char ch; { __hold return(NOMATCH); __splset[ch & 0177] = val; ch = *(*spec)++; } __splset[0] = 1; r break; case 1: ungetc(ch,__stream); break; case 2: __ungs( /* * initialize the array which inidcates the special chars which the user * wants to be included (or not included) in s length ) return(ch == EOF ? AT_EOF : NOMATCH); else return(result != 0); + = ch; imode = notok = 0; } __unget(ch); if( notok ) return(ch == EOF ? AT_EOF : NOMATCH); = 1; __holdch = ch; } eturn(NORETURN); } /* * getting a string */ __strx(result, length, endfn) register char *result; register int lech); break; } } /* * return the next char pointed to by *s */ __gs() { register char c; trings. */ __inits(spec) register char **spec; { register char ch; register int i; register int va } if( result ) *result++ = ch; } return(result != 0); } __getch() { switch(__smode) = 1; __holdch = ch; }  l |= 0x80; return(l); } p, count, sign; long l; if (f == 0.0) return(0L); if (f < 0.0) { * fpftol(fparg) * double fparg; * * Return : Fixed Point representation of Floating Point Number */ long fpftol(f) r *version "@(#)ftoffp.c 1.2 10/19/83"; */ /* * Floating Point to FFP Floating Point Routine : * F= 1; __holdch = ch; }  l |= 0x80; return(l); } f = -f; sign = 1; } else sign = 0; exp = 0L; for( ; f >= 1 long f; { register long l; register int exp, sign; exp = (f & 0x7f) - 0x40; if (f == 0L || exp < 0) /* underflow or FP Standard Single Precision Representation Floating Point * * long * fptoffp(f) * float f; * * = 1; __holdch = ch; }  l |= 0x80; return(l); } .0; f = f / 2.0) exp++; for( ; f < 0.5; f = f * 2.0) exp--; f = f * 167772160 */ return(0L); sign = (f & 0x80); if (exp > 31) /* overflow */ return( (sign) ? 0x80000000 : 0x7fffffff); l = (fRely's on the fact that a long and a float are both 32 bits. */ long fptoffp(f) /* convert current ma/* Copyright 1982 Alcyon Corporation 8716 Production Ave. San Diego, Ca. 92121 */ /* char *version "@(#)ftol.c 1.2  l |= 0x80; return(l); } .0; /* 2 ^ 24 */ l = f; l <<= 8; exp += 0x40; l |= (exp & 0x7f); if (sign) >>8) & 0xffffff; exp -= 24; for( ; exp < 0 ; exp++) l >>= 1; for( ; exp > 0; exp--) l <<= 1; if (sign) l = -l; chine float to ffp rep */ float f; /* unsigned input, guaranteed positive */ { register int ex 10/19/83"; */ /* * Floating Point Float to Long Routine : * Front End to IEEE Floating Point Package. * * long /* Copyright 1982 Alcyon Corporation 8716 Production Ave. San Diego, Ca. 92121 */ /*cha return(l); } f(l) long l; { register long exp; register int sign; if (l < 0L) { /* signed ?? */ sign = 1; l = -l; } else += 0x40; l =| (exp & 0x7f); if (sign) l |= 0x80; return(l); }  return(l); }  sign = 0; if (l == 0L) return(0L); exp = 24L; for( ; l & 0x7f000000; exp++) /* something in upper 7 bits */ l >>=/* Copyright 1982 Alcyon Corporation 8716 Production Ave. San Diego, Ca. 92121 */ /*char *version "@(#)ltof.c 1.2 += 0x40; l =| (exp & 0x7f); if (sign) l |= 0x80; return(l); }  return(l); }  1; for( ; !(l & 0x00800000); exp--) /* get mantissa : .F */ l <<= 1; l =<< 8; /* mantissa (.F) into top 24 bits */ exp 10/19/83"; */ /* * Floating Point Long to Float Routine : * Front End to FFP Floating Point Package. * * double  return(l); }  += 0x40; l =| (exp & 0x7f); if (sign) l |= 0x80; return(l); }  * fpltof(larg) * long larg; * * Return : Floating Point representation of Long Fixed point integer */ long fplto+= 0x40; l =| (exp & 0x7f); if (sign) l |= 0x80; return(l); }  * * Floating Point Hyperbolic sine: * Front End to FFP Floating Point Package. * * double * sinh(farg) * double farg4 move.l d7,-(sp) move.l 8(r14),r7 jsr ffptanh move.l r7,r0 move.l (sp)+,d7 unlk r14 rts arg; * * Returns : negated Floating point number * .globl _tanh .globl ffptanh .text fptanh: _tanh: ~~tanh: link r14,#68 $1x.1 $1x.2 ffptof.s era $1x.1 era $1x.2 $2as68 -s 0$1 -f $1 -l -u FFPTOF.s era FFPTOF.s $2cp68 -i 0$1 FLOOR.c $1x.i move.l d7,-(sp) move.l 8(r14),r7 jsr ffpsinh move.l r7,r0 move.l (sp)+,d7 unlk r14 rts .1 $1x.2 ceil.s era $1x.1 era $1x.2 $2as68 -s 0$1 -f $1 -l -u CEIL.s era CEIL.s $2cp68 -i 0$1 ETOA.c $1x.i $2c068 $1x.i; * * Returns : negated Floating point number * .globl _sinh .globl ffpsinh .text fpsinh: _sinh: ~~sinh: link r14,#-4 -4 move.l d7,-(sp) move.l 8(r14),r7 jsr ffptanh move.l r7,r0 move.l (sp)+,d7 unlk r14 rts  $2c068 $1x.i $1x.1 $1x.2 $1x.3 -f era $1x.i $2c168 $1x.1 $1x.2 floor.s era $1x.1 era $1x.2 $2as68 -s 0$1 -f $1 -l -u FLOO $1x.1 $1x.2 $1x.3 -f era $1x.i $2c168 $1x.1 $1x.2 etoa.s era $1x.1 era $1x.2 $2as68 -s 0$1 -f $1 -l -u ETOA.s era ETOA.s move.l d7,-(sp) move.l 8(r14),r7 jsr ffpsinh move.l r7,r0 move.l (sp)+,d7 unlk r14 rts 4 move.l d7,-(sp) move.l 8(r14),r7 jsr ffptanh move.l r7,r0 move.l (sp)+,d7 unlk r14 rts R.s era FLOOR.s $2cp68 -i 0$1 FMOD.c $1x.i $2c068 $1x.i $1x.1 $1x.2 $1x.3 -f era $1x.i $2c168 $1x.1 $1x.2 fmod.s era $1x $2cp68 -i 0$1 FABS.c $1x.i $2c068 $1x.i $1x.1 $1x.2 $1x.3 -f era $1x.i $2c168 $1x.1 $1x.2 fabs.s era $1x.1 era $1x.2 $move.l d7,-(sp) move.l 8(r14),r7 jsr ffpsinh move.l r7,r0 move.l (sp)+,d7 unlk r14 rts $2cp68 -i 0$1 ATOF.c $1x.i $2c068 $1x.i $1x.1 $1x.2 $1x.3 -f era $1x.i $2c168 $1x.1 $1x.2 atof.s era $1x.1 era $1x.2 $2as64 move.l d7,-(sp) move.l 8(r14),r7 jsr ffptanh move.l r7,r0 move.l (sp)+,d7 unlk r14 rts .1 era $1x.2 $2as68 -s 0$1 -f $1 -l -u FMOD.s era FMOD.s $2cp68 -i 0$1 FTOA.c $1x.i $2c068 $1x.i $1x.1 $1x.2 $1x.3 -f e * * Floating Point Hyperbolic tangent: * Front End to FFP Floating Point Package. * * double * tanh(farg) * double f2as68 -s 0$1 -f $1 -l -u FABS.s era FABS.s $2cp68 -i 0$1 FFPTOF.c $1x.i $2c068 $1x.i $1x.1 $1x.2 $1x.3 -f era $1x.i $2c1move.l d7,-(sp) move.l 8(r14),r7 jsr ffpsinh move.l r7,r0 move.l (sp)+,d7 unlk r14 rts 8 -s 0$1 -f $1 -l -u ATOF.s era ATOF.s $2cp68 -i 0$1 CEIL.c $1x.i $2c068 $1x.i $1x.1 $1x.2 $1x.3 -f era $1x.i $2c168 $1xra $1x.i $2c168 $1x.1 $1x.2 ftoa.s era $1x.1 era $1x.2 $2as68 -s 0$1 -f $1 -l -u FTOA.s era FTOA.s $2cp68 -i 0$1 FTOFFP -l FPEXP.S $2as68 -s 0$1 -f $1 -l FPFTOL.S $2as68 -s 0$1 -f $1 -l FPLOG.S $2as68 -s 0$1 -f $1 -l FPLTOF.S $2as68 $1 -l FFPDIV.S $2as68 -s 0$1 -f $1 -l FFPEXP.S $2as68 -s 0$1 -f $1 -l FFPHTHET.S $2as68 -s 0$1 -f $1 -l FFPLOG.S i 0$1 XDOPRTFP.c $1x.i $2c068 $1x.i $1x.1 $1x.2 $1x.3 -f era $1x.i $2c168 $1x.1 $1x.2 xdoprtfp.s era $1x.1 era $1x.2 $2as6.c $1x.i $2c068 $1x.i $1x.1 $1x.2 $1x.3 -f era $1x.i $2c168 $1x.1 $1x.2 ftoffp.s era $1x.1 era $1x.2 $2as68 -s 0$1 -f $1 -s 0$1 -f $1 -l FPMUL.S $2as68 -s 0$1 -f $1 -l FPNEG.S $2as68 -s 0$1 -f $1 -l FPPWR.S $2as68 -s 0$1 -f $1 -l FPSI $2as68 -s 0$1 -f $1 -l FFPMUL2.S $2as68 -s 0$1 -f $1 -l FFPPWR.S $2as68 -s 0$1 -f $1 -l FFPSIN.S $2as68 -s 0$1 -f 8 -s 0$1 -f $1 -l -u XDOPRTFP.s era XDOPRTFP.s $2cp68 -i 0$1 ATOI.c $1x.i $2c068 $1x.i $1x.1 $1x.2 $1x.3 -f era $1x.i $2c-l -u FTOFFP.s era FTOFFP.s $2cp68 -i 0$1 FTOL.c $1x.i $2c068 $1x.i $1x.1 $1x.2 $1x.3 -f era $1x.i $2c168 $1x.1 $1x.2 ftoN.S $2as68 -s 0$1 -f $1 -l FPSQRT.S $2as68 -s 0$1 -f $1 -l FPSUB.S rear $1 $2 $1 -l FFPSQRT.S $2as68 -s 0$1 -f $1 -l FFPTHETA.S $2as68 -s 0$1 -f $1 -l FFPTNORM.S $2as68 -s 0$1 -f $1 -l FPADD.S168 $1x.1 $1x.2 atoi.s era $1x.1 era $1x.2 $2as68 -s 0$1 -f $1 -l -u ATOI.s era ATOI.s $2as68 -s 0$1 -f $1 -l FFPABS.S l.s era $1x.1 era $1x.2 $2as68 -s 0$1 -f $1 -l -u FTOL.s era FTOL.s $2cp68 -i 0$1 LTOF.c $1x.i $2c068 $1x.i $1x.1 $1x.2.S $2as68 -s 0$1 -f $1 -l FPSQRT.S $2as68 -s 0$1 -f $1 -l FPSUB.S rear $1 $2  $2as68 -s 0$1 -f $1 -l FPCMP.S $2as68 -s 0$1 -f $1 -l FPCOS.S $2as68 -s 0$1 -f $1 -l FPDIV.S $2as68 -s 0$1 -f $1 $2as68 -s 0$1 -f $1 -l FFPADD.S $2as68 -s 0$1 -f $1 -l FFPCMP.S $2as68 -s 0$1 -f $1 -l FFPCPYRT.S $2as68 -s 0$1 -f $1x.3 -f era $1x.i $2c168 $1x.1 $1x.2 ltof.s era $1x.1 era $1x.2 $2as68 -s 0$1 -f $1 -l -u LTOF.s era LTOF.s $2cp68 -.S $2as68 -s 0$1 -f $1 -l FPSQRT.S $2as68 -s 0$1 -f $1 -l FPSUB.S rear $1 $2