Looking for work? Check out our jobs area.
*/
*/

View \MATH11.ASM

Floating point kit for 68HC11

Submitted By: WEBMASTER
Rating: Not rated (Rate It)


*******************************************************************************
*                               HC11FP                              *
*                                                                     *
*                            Copyright 1986              *
*                                 by                                   *
*                            Gordon Doughman          *
*                                                                     *
*       The source code for this floating point package for the MC68HC11      *
*       may be freely distributed under the rules of public domain. However   *
*       it is a copyrighted work and as such may not be sold as a product     *
*       or be included as part of a product for sale without the express      *
*       permission of the author. Any object code produced by the source      *
*       code may be included as part of a product for sale.              *
*                                                                     *
*       If there are any questions or comments about the floating point       *
*       package please feel free to contact me.                            *
*                                                                     *
*                            Gordon Doughman          *
*                            Motorola Semiconductor            *
*                            3490 South Dixie Drive            *
*                            Dayton, OH  45439                           *
*                            (513) 294-2231              *
*                                                                     *
*******************************************************************************
*                                                                     *
*                              MATH11                                  *
*                                                                     *
*                 Revisions to FP11 floating point code                    *
*                 Modifications Copyright 1988, Scott Wagner          *
*                                                                     *
*        The following improvements have been made to the HC11FP code:       *
*              1) Execution time and stack space requirements of the basic   *
*                 arithmetic operations (+-*/) have been reduced.           *
*              2) The efficiency of the trigonometric functions has been     *
*                 improved.                        *
*              3) New functions FLTATAN, FLTLN, FLTLGT, FLTETOX, FLT10TX     *
*                 and FLTXTOY have been added.                            *
*              4) The polynomial expansion routine POLYNOM is available to   *
*                 evaluate series of arbitrary order. The coefficient table *
*                 supplied by the user determines the polynomial order.      *
*              5) All floating point numbers are now stored in memory in the *
*                 IEEE floating point format for compatibility with other    *
*                 compilers.                  *
*                                                                     *
*        These modifications to the HC11FP package are provided under the     *
*        rules of public domain stated above.  Please direct comments about   *
*        these modifications to:                                         *
*                                   Scott Wagner               *
*                                   Rochester Instrument Systems         *
*                                   255 North Union Street        *
*                                   Rochester, New York 14605            *
*                                                                     *
*******************************************************************************
*
*
*
         ORG    $0000
*
FPACC1EX RMB    1        FLOATING POINT ACCUMULATOR #1..
FPACC1MN RMB    3
MANTSGN1 RMB    1        MANTISSA SIGN FOR FPACC1 (0=+, FF=-).
FPACC2EX RMB    1        FLOATING POINT ACCUMULATOR #2.
FPACC2MN RMB    3
MANTSGN2 RMB    1        MANTISSA SIGN FOR FPACC2 (0=+, FF=-).
*
*
FLTFMTER EQU    1       /* floating point format error in ASCFLT */
OVFERR  EQU      2         /* floating point overflow error */
UNFERR  EQU      3         /* floating point underflow error */
DIV0ERR EQU    4       /* division by 0 error */
TOLGSMER EQU    5       /* number too large or small to convert to int. */
NSQRTERR EQU    6       /* tried to take the square root of negative # */
TAN90ERR EQU    7       /* TANgent of 90 degrees attempted */
LNNEGERR EQU    8       /* LOG or LN of negative number or 0 */
*
*
         TTL    ASCFLT
******************************************************************************
*                                                                    *
*                      ASCII TO FLOATING POINT ROUTINE                   *
*                                                                    *
*       This routine will accept most any ASCII floating point format       *
*       and return a 32-bit floating point number.  The following are       *
*       some examples of legal ASCII floating point numbers.           *
*                                                                    *
*       20.095             *
*       0.125                     *
*       7.2984E10                                               *
*       167.824E5                                               *
*       5.9357E-7                                               *
*       500                                     *
*                                                                    *
*       The floating point number returned is in "FPACC1".                   *
*                                                                    *
*                                                                    *
*       The exponent is biased by 128 to facilitate floating point          *
*       comparisons.  A pointer to the ASCII string is passed to the        *
*       routine in the X-register.                              *
*                                                                    *
*                                                                    *
******************************************************************************
*
*
*        ORG   $0000
*
*        FPACC1EX RMB   1              FLOATING POINT ACCUMULATOR #1..
*        FPACC1MN RMB   3
*        MANTSGN1 RMB   1              MANTISSA SIGN FOR FPACC1 (0=+, FF=-).
*        FPACC2EX RMB   1              FLOATING POINT ACCUMULATOR #2.
*        FPACC2MN RMB   3
*        MANTSGN2 RMB   1              MANTISSA SIGN FOR FPACC2 (0=+, FF=-).
*
*
*        FLTFMTER EQU   1
*
*
*        LOCAL VARIABLES (ON STACK POINTED TO BY Y)
*
EXPSIGN EQU    0        EXPONENT SIGN (0=+, FF=-).
PWR10EXP EQU    1        POWER 10 EXPONENT.
*
*
         ORG    $C000            (TEST FOR EVB)
*
ASCFLT  EQU      *
         PSHX           SAVE POINTER TO ASCII STRING.
         JSR    PSHFPAC2     SAVE FPACC2.
         LDX    #0       PUSH ZEROS ON STACK TO INITIALIZE LOCALS.
         PSHX           ALLOCATE 2 BYTES FOR LOCALS.
         STX    FPACC1EX     CLEAR FPACC1.
         STX    FPACC1EX+2
         CLR    MANTSGN1     MAKE THE MANTISSA SIGN POSITIVE INITIALLY.
         TSY             POINT TO LOCALS.
         LDX    6,Y      GET POINTER TO ASCII STRING.
ASCFLT1  LDAA   0,X             GET 1ST CHARACTER IN STRING.
         JSR    NUMERIC      IS IT A NUMBER.
         BCS    ASCFLT4      YES. GO PROCESS IT.
*
*        LEADING MINUS SIGN ENCOUNTERED?
*
ASCFLT2  CMPA   #'-          NO. IS IT A MINUS SIGN?
         BNE    ASCFLT3      NO. GO CHECK FOR DECIMAL POINT.
         COM    MANTSGN1     YES. SET MANTISSA SIGN. LEADING MINUS BEFORE?
         INX             POINT TO NEXT CHARACTER.
         LDAA   0,X             GET IT.
         JSR    NUMERIC      IS IT A NUMBER?
         BCS    ASCFLT4      YES. GO PROCESS IT.
*
*        LEADING DECIMAL POINT?
*

ASCFLT3  CMPA   #'
.          IS IT A DECIMAL POINT?
         BNE    ASCFLT5      NO. FORMAT ERROR.
         INX             YES. POINT TO NEXT CHARACTER.
         LDAA   0,X             GET IT.
         JSR    NUMERIC      MUST HAVE AT LEAST ONE DIGIT AFTER D.P.
         BCC    ASCFLT5      GO REPORT ERROR.
         JMP    ASCFLT11     GO BUILD FRACTION.
*
*        FLOATING POINT FORMAT ERROR
*
ASCFLT5  INS             DE-ALLOCATE LOCALS.
         INS
         JSR    PULFPAC2     RESTORE FPACC2.
         PULX           GET POINTER TO TERMINATING CHARACTER IN STRING.
         LDAA   #FLTFMTER    FORMAT ERROR.
         SEC             SET ERROR FLAG.
         RTS             RETURN.
*
*        PRE DECIMAL POINT MANTISSA BUILD
*
ASCFLT4  LDAA   0,X
         JSR    NUMERIC
         BCC    ASCFLT10
         JSR    ADDNXTD
         INX
         BCC    ASCFLT4
*
*        PRE DECIMAL POINT MANTISSA OVERFLOW
*
ASCFLT6  INC    FPACC1EX     INC FOR EACH DIGIT ENCOUNTERED PRIOR TO D.P.
         LDAA   0,X             GET NEXT CHARACTER.
         INX             POINT TO NEXT.
         JSR    NUMERIC      IS IT S DIGIT?
         BCS    ASCFLT6      YES. KEEP BUILDING POWER 10 MANTISSA.
         CMPA   #'.          NO. IS IT A DECIMAL POINT?
         BNE    ASCFLT7      NO. GO CHECK FOR THE EXPONENT.
*
*        ANY FRACTIONAL DIGITS ARE NOT SIGNIFIGANT
*
ASCFLT8  LDAA   0,X             GET THE NEXT CHARACTER.
         JSR    NUMERIC      IS IT A DIGIT?
         BCC    ASCFLT7      NO. GO CHECK FOR AN EXPONENT.
         INX             POINT TO THE NEXT CHARACTER.
         BRA    ASCFLT8      FLUSH REMAINING DIGITS.
ASCFLT7  CMPA   #'
E          NO. IS IT THE EXPONENT?
         BEQ    ASCFLT13     YES. GO PROCESS IT.
         JMP    FINISH           NO. GO FINISH THE CONVERSION.
*
*        PROCESS THE EXPONENT
*
ASCFLT13 INX             POINT TO NEXT CHARACTER.
         LDAA   0,X             GET THE NEXT CHARACTER.
         JSR    NUMERIC      SEE IF IT'S A DIGIT.
         BCS    ASCFLT9      YES. GET THE EXPONENT.
         CMPA   #'
-          NO. IS IT A MINUS SIGN?
         BEQ    ASCFLT15     YES. GO FLAG A NEGATIVE EXPONENT.
         CMPA   #'+          NO. IS IT A PLUS SIGN?
         BEQ    ASCFLT16     YES. JUST IGNORE IT.
         BRA    ASCFLT5      NO. FORMAT ERROR.
ASCFLT15 COM    EXPSIGN,Y    FLAG A NEGATIVE EXPONENT. IS IT 1ST?
ASCFLT16 INX             POINT TO NEXT CHARACTER.
         LDAA   0,X             GET NEXT CHARACTER.
         JSR    NUMERIC      IS IT A NUMBER?
         BCC    ASCFLT5      NO. FORMAT ERROR.
ASCFLT9  SUBA   #$30            MAKE IT BINARY.
         STAA   PWR10EXP,Y   BUILD THE POWER 10 EXPONENT.
         INX             POINT TO NEXT CHARACTER.
         LDAA   0,X             GET IT.
         JSR    NUMERIC      IS IT NUMERIC?
         BCC    ASCFLT14     NO. GO FINISH UP THE CONVERSION.
         LDAB   PWR10EXP,Y   YES. GET PREVIOUS DIGIT.
         LSLB           MULT. BY 2.
         LSLB           NOW BY 4.
         ADDB   PWR10EXP,Y   BY 5.
         LSLB           BY 10.
         SUBA   #$30            MAKE SECOND DIGIT BINARY.
         ABA             ADD IT TO FIRST DIGIT.
         STAA   PWR10EXP,Y
         CMPA   #38             IS THE EXPONENT OUT OF RANGE?
         BHI    ASCFLT5      YES. REPORT ERROR.
ASCFLT14 LDAA   PWR10EXP,Y   GET POWER 10 EXPONENT.
         TST    EXPSIGN,Y    WAS IT NEGATIVE?
         BPL    ASCFLT12     NO. GO ADD IT TO BUILT 10 PWR EXPONENT.
         NEGA
ASCFLT12 ADDA   FPACC1EX     FINAL TOTAL PWR 10 EXPONENT.
         STAA   FPACC1EX     SAVE RESULT.
         BRA    FINISH           GO FINISH UP CONVERSION.
*
*        PRE-DECIMAL POINT NON-DIGIT FOUND, IS IT A DECIMAL POINT?
*
ASCFLT10 CMPA   #'
.          IS IT A DECIMAL POINT?
         BNE    ASCFLT7      NO. GO CHECK FOR THE EXPONENT.
         INX             YES. POINT TO NEXT CHARACTER.
*
*        POST DECIMAL POINT PROCESSING
*
ASCFLT11 LDAA   0,X             GET NEXT CHARACTER.
         JSR    NUMERIC      IS IT NUMERIC?
         BCC    ASCFLT7      NO. GO CHECK FOR EXPONENT.
         BSR    ADDNXTD      YES. ADD IN THE DIGIT.
         INX             POINT TO THE NEXT CHARACTER.
         BCS    ASCFLT8      IF OVER FLOW, FLUSH REMAINING DIGITS.
         DEC    FPACC1EX     ADJUST THE 10 POWER EXPONENT.
         BRA    ASCFLT11     PROCESS ALL FRACTIONAL DIGITS.
*
*
*
ADDNXTD  LDAA   FPACC1MN     GET UPPER 8 BITS.
         STAA   FPACC2MN     COPY INTO FPAC2.
         LDD    FPACC1MN+1   GET LOWER 16 BITS OF MANTISSA.
         STD    FPACC2MN+1   COPY INTO FPACC2.
         LSLD           MULT. BY 2.
         ROL    FPACC1MN     OVERFLOW?
         BCS    ADDNXTD1     YES. DON'T ADD THE DIGIT IN.
         LSLD           MULT BY 4.
         ROL    FPACC1MN     OVERFLOW?
         BCS    ADDNXTD1     YES. DON'
T ADD THE DIGIT IN.
         ADDD   FPACC2MN+1   BY 5.
         PSHA           SAVE A.
         LDAA   FPACC1MN     GET UPPER 8 BITS.
         ADCA   #0      ADDIN POSSABLE CARRY FROM LOWER 16 BITS.
         ADDA   FPACC2MN     ADD IN UPPER 8 BITS.
         STAA   FPACC1MN     SAVE IT.
         PULA           RESTORE A.
         BCS    ADDNXTD1     OVERFLOW? IF SO DON'T ADD IT IN.
         LSLD           BY 10.
         ROL    FPACC1MN
         STD    FPACC1MN+1   SAVE THE LOWER 16 BITS.
         BCS    ADDNXTD1     OVERFLOW? IF SO DON'
T ADD IT IN.
         LDAB   0,X             GET CURRENT DIGIT.
         SUBB   #$30            MAKE IT BINARY.
         CLRA           16-BIT.
         ADDD   FPACC1MN+1   ADD IT IN TO TOTAL.
         STD    FPACC1MN+1   SAVE THE RESULT.
         LDAA   FPACC1MN     GET UPPER 8 BITS.
         ADCA   #0      ADD IN POSSIBLE CARRY. OVERFLOW?
         BCS    ADDNXTD1     YES. COPY OLD MANTISSA FROM FPACC2.
         STAA   FPACC1MN     NO. EVERYHING OK.
         RTS             RETURN.
ADDNXTD1 LDD    FPACC2MN+1   RESTORE THE ORIGINAL MANTISSA BECAUSE
         STD    FPACC1MN+1   OF OVERFLOW.
         LDAA   FPACC2MN
         STAA   FPACC1MN
         RTS             RETURN.
*
*
*
*        NOW FINISH UP CONVERSION BY MULTIPLYING THE RESULTANT MANTISSA
*        BY 10 FOR EACH POSITIVE POWER OF 10 EXPONENT RECIEVED OR BY .1
*        (DIVIDE BY 10) FOR EACH NEGATIVE POWER OF 10 EXPONENT RECIEVED.
*
*
FINISH  EQU      *
         STX    6,Y      SAVE POINTER TO TERMINATING CHARACTER IN STRING.
         LDX    #FPACC1EX    POINT TO FPACC1.
         JSR    CHCK0            SEE IF THE NUMBER IS ZERO.
         BEQ    FINISH3      QUIT IF IT IS.
         LDAA   FPACC1EX     GET THE POWER 10 EXPONENT.
         STAA   PWR10EXP,Y   SAVE IT.
         LDAA   #$80+24      SET UP INITIAL EXPONENT (# OF BITS + BIAS).
         STAA   FPACC1EX
         JSR    FPNORM           GO NORMALIZE THE MANTISSA.
         TST    PWR10EXP,Y   IS THE POWER 10 EXPONENT POSITIVE OR ZERO?
         BEQ    FINISH3      IT'S ZERO, WE'RE DONE.
         BPL    FINISH1      IT'S POSITIVE MULTIPLY BY 10.
         LDX    #CONSTP1     NO. GET CONSTANT .1 (DIVIDE BY 10).
         JSR    GETFPAC2     GET CONSTANT INTO FPACC2.
         NEG    PWR10EXP,Y   MAKE THE POWER 10 EXPONENT POSITIVE.
         BRA    FINISH2      GO DO THE MULTIPLIES.
FINISH1  LDX    #CONST10     GET CONSTANT '
10' TO MULTIPLY BY.
         JSR    GETFPAC2     GET CONSTANT INTO FPACC2.
FINISH2  JSR    FLTMUL           GO MULTIPLY FPACC1 BY FPACC2, RESULT IN FPACC1.
         DEC    PWR10EXP,Y   DECREMENT THE POWER 10 EXPONENT.
         BNE    FINISH2      GO CHECK TO SEE IF WE'
RE DONE.
FINISH3  INS             DE-ALLOCATE LOCALS.
         INS
         JSR    PULFPAC2     RESTORE FPACC2.
         PULX           GET POINTER TO TERMINATING CHARACTER IN STRING.
         RTS             RETURN WITH NUMBER IN FPACC1.
*
*
NUMERIC EQU    *
         CMPA   #'0          IS IT LESS THAN AN ASCII 0?
         BLO    NUMERIC1     YES. NOT NUMERIC.
         CMPA   #'
9          IS IT GREATER THAN AN ASCII 9?
         BHI    NUMERIC1     YES. NOT NUMERIC.
         SEC             IT WAS NUMERIC. SET THE CARRY.
         RTS             RETURN.
NUMERIC1 CLC             NON-NUMERIC CHARACTER. CLEAR THE CARRY.
         RTS             RETURN.
*
FPNORM  EQU      *
         LDX    #FPACC1EX    POINT TO FPACC1.
         BSR    CHCK0            CHECK TO SEE IF IT'S 0.
         BEQ    FPNORM3      YES. JUST RETURN.
         TST    FPACC1MN     IS THE NUMBER ALREADY NORMALIZED?
         BMI    FPNORM3      YES. JUST RETURN..
FPNORM1  LDD    FPACC1MN+1   GET THE LOWER 16 BITS OF THE MANTISSA.
FPNORM2  DEC    FPACC1EX     DECREMENT THE EXPONENT FOR EACH SHIFT.
         BEQ    FPNORM4      EXPONENT WENT TO 0. UNDERFLOW.
         LSLD           SHIFT THE LOWER 16 BITS.
         ROL    FPACC1MN     ROTATE THE UPPER 8 BITS. NUMBER NORMALIZED?
         BPL    FPNORM2      NO. KEEP SHIFTING TO THE LEFT.
         STD    FPACC1MN+1   PUT THE LOWER 16 BITS BACK INTO FPACC1.
FPNORM3  CLC             SHOW NO ERRORS.
         RTS             YES. RETURN.
FPNORM4  SEC             FLAG ERROR.
         RTS             RETURN.
*
CHCK0    EQU       *           CHECKS FOR ZERO IN FPACC POINTED TO BY X.
         PSHB           SAVE D.
         PSHA
         LDD    0,X      GET FPACC EXPONENT & HIGH 8 BITS.
         BNE    CHCK01           NOT ZERO. RETURN.
         LDD    2,X      CHECK LOWER 16 BITS.
CHCK01   PULA               RESTORE D.
         PULB
         RTS             RETURN WITH CC SET.
*
CONSTP1  FCB    $3E,$CC,$CC,$CD     0.1 DECIMAL
CONST10  FCB    $42,$20,$00,$00     10.0 DECIMAL
*
*
         TTL    FLTMUL
******************************************************************************
*                                                                    *
*                     FPMULT: FLOATING POINT MULTIPLY        *
*                                                                    *
*       THIS FLOATING POINT MULTIPLY ROUTINE MULTIPLIES "FPACC1" BY          *
*       "FPACC2" AND PLACES THE RESULT IN TO FPACC1. FPACC2 REMAINS          *
*       UNCHANGED.                                        *
*                        WORSE CASE = 480 CYCLES = 240 uS @ 2MHz          *
*                                                                    *
******************************************************************************
*
*
FLTMUL   EQU      *
         TST    FPACC1EX     CHECK TO SEE IF FPACC1 IS ZERO.
         BEQ    FPMULT3      IT IS. ANSWER IS 0.
         TST    FPACC2EX     CHECK TO SEE IF FPACC2 IS ZERO.
         BNE    FPMULT8      IT IS NOT. GO DO MULTIPLY
FPMULT3  LDD    #0       ZERO RESULT
         STAA   MANTSGN1
         STD    FPACC1EX
         STD    FPACC1MN+1
         BRA    FPMULT6      RETURN.
FPMULT8  LDAA   MANTSGN1     GET FPACC1 EXPONENT.
         EORA   MANTSGN2     SET THE SIGN OF THE RESULT.
         STAA   MANTSGN1     SAVE THE SIGN OF THE RESULT.
         LDAA   FPACC1EX     GET FPACC1 EXPONENT.
         ADDA   FPACC2EX     ADD IT TO FPACC2 EXPONENT.
         BPL    FPMULT1      IF RESULT IS MINUS AND
         BCC    FPMULT2      THE CARRY IS SET THEN:
RTNMAX   LDAA     #OVFERR      OVERFLOW ERROR.
RTNDIV0  LDX    #$FFFF           MAXIMUM MAGNITUDE RESULT
         BRA    FPMULT7      DO IT AND RETURN.
FPMULT1  BCS    FPMULT2      IF RESULT IS PLUS & THE CARRY IS SET THEN ALL OK.
RTNZERO  LDAA   #UNFERR      ELSE UNDERFLOW ERROR OCCURED.
         LDX    #0       ZERO RESULT
         STX    FPACC1MN+2   THIS CLEARS MANTSGN1 BYTE
FPMULT7  STX    FPACC1EX
         STX    FPACC1MN+1
         SEC             FLAG ERROR.
         BRA    FPMULT6      RETURN.
FPMULT2  ADDA   #$80            ADD 128 BIAS BACK IN THAT WE LOST.
         STAA   FPACC1EX     SAVE THE NEW EXPONENT.
         LDX    #0
         PSHX           CREATE PARTIAL PRODUCT REGISTER AND COUNTER.
         PSHX
         TSX             POINT TO THE VARIABLES.
         JSR    UMULT            GO MULTIPLY THE "INTEGER" MANTISSAS.
         TST    0,X      DOES RESULT NEED TO BE NORMALIZED?
         BMI    FPMROUND     NO - GO ROUND RESULT
         ROL    3,X      FIRST NORMALIZE RESULT
         ROL    2,X
         ROL    1,X
         ROL    0,X
         DEC    FPACC1EX     NOW DECREMENT EXPONENT
FPMROUND TST    3,X      CHECK MSB OF BYTE 4 (TO BE DISCARDED LATER)
         BPL    FPMULT4      NO ROUNDING NECESSARY
         LDAA   2,X             ROUND LSB UP
         INCA           INCREMENT RESULT LSB
         STAA   2,X             PUT LSB BACK
         BNE    FPMULT4      IF NO CARRY TO RESULT BYTES 1 AND 2
         LDAB   #1      SET D REGISTER TO 1 (ACCA IS ALREADY 0)
         ADDD   0,X             INCREMENT BYTES 1 AND 2
         BCC    FPMULT5      NO OVERFLOW FROM BYTES 1 AND 2
         RORA           RESULT CHANGES FROM $7FFFFF TO $800000
         INC    FPACC1EX     EXPONENT INCREMENTED (BACK TO WHERE IT WAS)
FPMULT5  STD    0,X      PUT BYTES 1 AND 2 BACK
FPMULT4  PULX           RETRIEVE BYTES 1 AND 2
         STX    FPACC1MN     STORE IN MANTISSA HIGH BYTES
         PULA           RETRIEVE BYTE 3 (LSB)
         STAA   FPACC1MN+2   STORE IN MANTISSA LOW BYTE
         INS             DISCARD BYTE 4
         TST    FPACC1EX     WAS THERE AN UNDERFLOW ERROR?
         BEQ    RTNZERO      YES. RETURN ERROR.
         CLRA           SHOW NO ERRORS.
FPMULT6  RTS
*
*
UMULT    EQU       *
         LDAA   FPACC2MN+2   GET MULTIPLIER LSB
         LDAB   FPACC1MN+2   GET MULTIPLICAND LSB
         MUL
         STAA   1,X             TEMPORARILY SAVE RESULT MSB; DISCARD LSB (BYTE 6)
         LDAA   FPACC2MN+1   GET MULTIPLIER NSB
         LDAB   FPACC1MN+2   GET MULTIPLICAND LSB
         MUL
         ADDD   0,X             ADD IN LAST PARTIAL RESULT
         STD    0,X      TEMPORARILY SAVE RESULT
         LDAA   FPACC2MN+2   GET MULTIPLIER LSB
         LDAB   FPACC1MN+1   GET MULTIPLICAND NSB
         MUL
         ADDD   0,X             ADD IN LAST PARTIAL RESULT
         STAA   3,X             SAVE PARTIAL PRODUCT BYTE 4; DISCARD LSB (BYTE 5)
         BCC    UMULT1           IF NO CARRY OUT TO PRODUCT BYTE 3
         INC    2,X      CARRY TO PRODUCT BYTE 3
UMULT1   CLR      0,X        ZERO PRODUCT BYTES 1 & 2 (USED FOR TEMP. STORAGE)
         CLR    1,X
         LDAA   FPACC2MN     GET MULTIPLIER MSB
         LDAB   FPACC1MN+2   GET MULTIPLICAND LSB
         MUL
         ADDD   2,X             ADD IN LAST PARTIAL RESULT
         STD    2,X      SAVE IN PARTIAL PRODUCT BYTES 3 AND 4
REMCOMP  LDAA   FPACC2MN+1   GET MULTIPLIER NSB
         LDAB   FPACC1MN+1   GET MULTIPLICAND NSB
         MUL
         ADDD   2,X             ADD IN LAST PARTIAL RESULT
         STD    2,X      SAVE IN PARTIAL PRODUCT BYTES 3 AND 4
         BCC    UMULT2           IF NO CARRY OUT TO PRODUCT BYTE 2
         INC    1,X      CARRY TO PRODUCT BYTE 2
UMULT2   LDAA     FPACC2MN+2   GET MULTIPLIER LSB
         LDAB   FPACC1MN     GET MULTIPLICAND MSB
         MUL
         ADDD   2,X             ADD IN LAST PARTIAL RESULT
         STD    2,X      SAVE IN PARTIAL PRODUCT BYTES 3 AND 4
         BCC    UMULT3           IF NO CARRY OUT TO PRODUCT BYTE 2
         INC    1,X      CARRY TO PRODUCT BYTE 2
UMULT3   LDAA     FPACC2MN     GET MULTIPLIER MSB
         LDAB   FPACC1MN+1   GET MULTIPLICAND NSB
         MUL
         ADDD   1,X             ADD IN LAST PARTIAL RESULT
         STD    1,X      SAVE IN PARTIAL PRODUCT BYTES 2 AND 3
         BCC    UMULT4           IF NO CARRY OUT TO PRODUCT BYTE 1
         INC    0,X      CARRY TO PRODUCT BYTE 1
UMULT4   LDAA     FPACC2MN+1   GET MULTIPLIER NSB
         LDAB   FPACC1MN     GET MULTIPLICAND MSB
         MUL
         ADDD   1,X             ADD IN LAST PARTIAL RESULT
         STD    1,X      SAVE IN PARTIAL PRODUCT BYTES 2 AND 3
         BCC    UMULT5           IF NO CARRY OUT TO PRODUCT BYTE 1
         INC    0,X      CARRY TO PRODUCT BYTE 1
UMULT5   LDAA     FPACC2MN     GET MULTIPLIER MSB
         LDAB   FPACC1MN     GET MULTIPLICAND MSB
         MUL
         ADDD   0,X             ADD IN LAST PARTIAL RESULT
         STD    0,X      SAVE IN PARTIAL PRODUCT BYTES 2 AND 3
         RTS             RETURN TO DO NORMALIZATION AND ROUNDING
*
*
*
         TTL    FLTSUB
******************************************************************************
*                                                                    *
*                    FLOATING POINT SUBTRACT SUBROUTINE                   *
*                                                                    *
*       This subroutine performs floating point subtraction ( FPACC1-FPACC2) *
*       by inverting the sign of FPACC2 and then calling FLTADD since       *
*       FLTADD performs complete signed addition.  Upon returning from      *
*       FLTADD the sign of FPACC2 is again inverted to leave it unchanged    *
*       from its original value.                                        *
*                                                                    *
*                        WORSE CASE = 601 CYCLES = 301 uS @ 2MHz          *
*                                                                    *
******************************************************************************
*
*
FLTSUB   EQU      *
         BSR    FLTSUB1      INVERT SIGN.
         BSR    FLTADD           GO DO FLOATING POINT ADD.
FLTSUB1  LDAB   MANTSGN2     GET FPACC2 MANTISSA SIGN.
         EORB   #$FF            INVERT THE SIGN.
         STAB   MANTSGN2     PUT BACK.
         RTS             RETURN.
*
*
*
         TTL    FLTADD
******************************************************************************
*                                                                    *
*                     FLOATING POINT ADDITION                           *
*                                                                    *
*       This subroutine performs floating point addition of the two numbers  *
*       in FPACC1 and FPACC2.  The result of the addition is placed in      *
*       FPACC1 while FPACC2 remains unchanged. This subroutine performs     *
*       full signed addition so either number may be of the same or opposite *
*       sign.                     *
*                        WORSE CASE = 563 CYCLES = 282 uS @ 2MHz          *
*                                                                    *
******************************************************************************
*
*
FLTADD   EQU      *
         LDAA   FPACC1EX     LOAD FP1 EXPONENT
         BNE    FLTADD1      IF NOT ZERO
TFR2TO1  LDD    FPACC2EX     GET FPACC2 EXPONENT & HIGH 8 BIT OF MANTISSA.
         STD    FPACC1EX     PUT IT IN FPACC1.
         LDD    FPACC2MN+1   GET FPACC2 LOW 16 BITS OF MANTISSA.
         STD    FPACC1MN+1   PUT IT IN FPACC1.
         LDAA   MANTSGN2     TRANSFER THE SIGN.
         STAA   MANTSGN1
FLTADDR  RTS             RETURN.
FLTADD1  TST    FPACC2EX     CHECK FP2 EXPONENT
         BEQ    FLTADDR      RETURN IF ZERO
         LDAB   MANTSGN1     LOAD SIGN FROM 1
         EORB   MANTSGN2     DECIDE TO ADD OR SUBTRACT
         SUBA   FPACC2EX     COMPARE EXPONENTS
         BCS    FLTADD2      IF FPACC2 > FPACC1
         CMPA   #24             IF FPACC1 >> FPACC2
         BHI    FLTADDR      RETURN
         PSHY           SAVE Y REGISTER
         PSHA           SAVE SHIFT COUNTER
         LDX    #FPACC2MN    ADDEND TO BE DENORMALIZED POINTED TO BY X
         LDY    #FPACC1MN    ADDEND TO BE LEFT NORMALIZED POINTED TO BY Y
         BRA    FLTADD3      GO DO NORMALIZATION
FLTADD2  NEGA           CHANGE SIGN OF A FOR SHIFT COUNTER
         CMPA   #24             IF FPACC2 >> FPACC1
         BHI    TFR2TO1      PUT FPACC2 INTO FPACC1 AND RETURN
         PSHY           SAVE Y REGISTER
         PSHA           SAVE SHIFT COUNTER
         LDAA   FPACC2EX     LOAD EXPONENT FROM 2
         STAA   FPACC1EX     ... AND TRANSFER IT TO 1
         LDAA   MANTSGN2     LOAD SIGN FROM 2
         STAA   MANTSGN1     ... AND TRANSFER IT TO 1
         LDX    #FPACC1MN    ADDEND TO BE DENORMALIZED POINTED TO BY X
         LDY    #FPACC2MN    ADDEND TO BE LEFT NORMALIZED POINTED TO BY Y
FLTADD3  TBA             PUT ADD/SUBTRACT FLAG BYTE IN BOTH A AND B
         PSHA           CREATE 3 BYTE STACK WORKSPACE SET TO $00 FOR ...
         PSHA           ... ADDITION AND $FF FOR SUBTRACTION.
         PSHA
         EORA   0,X             LOAD MANTISSA MSB; COMPLEMENT IF SUBTRACTION
         PSHA           PUT IN STACK WORKSPACE
         TBA             PUT ADD/SUBTRACT FLAG INTO A AGAIN
         EORA   1,X             LOAD MANTISSA NSB; COMPLEMENT IF SUBTRACTION
         PSHA           PUT IN STACK WORKSPACE
         TBA             PUT ADD/SUBTRACT FLAG INTO A AGAIN
         EORA   2,X             LOAD MANTISSA LSB; COMPLEMENT IF SUBTRACTION
         PSHA           PUT IN STACK WORKSPACE
         TSX             PUT POINTER TO WORKSPACE IN X
         LDAA   6,X             GET SHIFT COUNTER
         STAB   6,X             SAVE ADD/SUBTRACT FLAG
         TAB             B REGISTER WILL BE BYTE DISPLACEMENT COUNTER
         ANDA   #$07            REMOVE BYTE DISPLACEMENT FROM A
         INCA           PRE-INCREMENT SHIFT COUNTER
         ANDB   #$18            REMOVE SHIFT DISPLACEMENT FROM B
         LSRB           RIGHT JUSTIFY BYTE DISPLACEMENT COUNTER
         LSRB
         LSRB
         ABX             DO BYTE DISPLACEMENT BY ADDING TO POINTER
         LDAB   3,X             LOAD ADD/SUBTRACT FLAG (OK SINCE FLAG IN 4 BYTES)
FLTADD4  DECA           DECREMENT BYTE SHIFT COUNTER
         BEQ    FLTADD5      IF DONE SHIFTING
         RORB           SHIFT ADD/SUBTRACT FLAG INTO CARRY
         ROR    2,X      SHIFT MANTISSA MSB
         ROR    1,X      SHIFT MANTISSA NSB
         ROR    0,X      SHIFT MANTISSA LSB
         BRA    FLTADD4      GO AROUND AGAIN
FLTADD5  RORB           SHIFT ADD/SUBTRACT FLAG INTO CARRY
         LDAA   2,Y             LOAD NORMALIZED ADDEND LSB
         ADCA   0,X             ADD IN DENORMALIZED ADDEND LSB
         STAA   FPACC1MN+2   STORE NORMALIZED SUM LSB
         LDAA   1,Y             LOAD NORMALIZED ADDEND NSB
         ADCA   1,X             ADD IN DENORMALIZED ADDEND NSB
         STAA   FPACC1MN+1   STORE NORMALIZED SUM NSB
         LDAA   0,Y             LOAD NORMALIZED ADDEND NSB
         ADCA   2,X             ADD IN DENORMALIZED ADDEND NSB
         STAA   FPACC1MN     STORE NORMALIZED SUM MSB
         TSX             RESTORE WORKSPACE POINTER
         LDAA   6,X             GET BACK ADD/SUBTRACT FLAG
         BMI    FLTADD6      OPERATION WAS SUBTRACTION
         BCC    FLTADD7      IF ADD AND NO CARRY, DO NOTHING
         ROR    FPACC1MN     CARRY WAS SET; ROTATE TO NORMALIZE OVERFLOW
         ROR    FPACC1MN+1
         ROR    FPACC1MN+2
         INC    FPACC1EX     NOW INCREMENT EXPONENT TO ACCOMODATE SHIFT
         BNE    FLTADD7      SUCCESSFUL COMPLETION
         LDD    #RTNMAX      OVERFLOW - RETURN MAXIMUM NUMBER
         BRA    FLTADD11
FLTADD6  BCS    FLTADD8      NO SIGN CHANGE
         COM    MANTSGN1     CHANGE SIGN OF RESULT
         NEG    FPACC1MN+2   CHANGE SIGN OF LSB
         BCC    FLTADD12     IF LSB WAS ZERO
         INC    FPACC1MN+1   CARRY FROM LSB
         BNE    FLTADD12     IF NSB NOT ZERO
         INC    FPACC1MN     CARRY FROM NSB
FLTADD12 NEG    FPACC1MN+1   CHANGE SIGN OF NSB
         BCC    FLTADD13     IF NSB WAS ZERO
         INC    FPACC1MN     CARRY FROM NSB
FLTADD13 NEG    FPACC1MN     CHANGE SIGN OF MSB
FLTADD8  TST    FPACC1MN     IS MANTISSA NORMALIZED?
         BMI    FLTADD7      YES - DONE
         BNE    FLTADD9      DO BIT SHIFT
         LDAA   FPACC1EX     DECREMENT EXPONENT BY 8 FOR BYTE SHIFT
         SUBA   #8
         BLS    FLTADD10     IF UNDERFLOW
         STAA   FPACC1EX     REPLACE DECREMENTED EXPONENT
         LDD    FPACC1MN+1   DO BYTE SHIFT
         BEQ    FLTADD10     IF RESULT MANTISSA IS ZERO
         CLR    FPACC1MN+2   CLEAR BYTE 3
         STD    FPACC1MN     STORE BYTES 1 AND 2
         BRA    FLTADD8
FLTADD9  DEC    FPACC1EX     DECREMENT EXPONENT TO ACCOMODATE SHIFT
         BEQ    FLTADD10     IF UNDERFLOW
         LSL    FPACC1MN+2   DO BIT SHIFT
         ROL    FPACC1MN+1
         ROL    FPACC1MN
         BPL    FLTADD9
FLTADD7  LDY    7,X      PULL Y FROM STACK
         LDAB   #9      RESTORE STACK - ADD 7 TO X (STACK BASE)
         ABX             DO ADDITION
         TXS             NEW STACK BASE (EFFECTIVELY PULLED STACK)
         CLRA           NO ERRORS
         RTS             RETURN
*
FLTADD10 LDD    #RTNZERO     UNDERFLOW - RETURN ZERO
FLTADD11 LDY    7,X      PULL Y FROM STACK
         STD    7,X      PUT RETURN ADDRESS ON STACK
         LDAB   #7      RESTORE STACK - ADD 5 TO X (STACK BASE)
         ABX             DO ADDITION
         TXS             NEW STACK BASE (EFFECTIVELY PULLED STACK)
         RTS             RETURN THROUGH OVERFLOW OR UNDERFLOW
*
*
*
         TTL    FLTDIV
******************************************************************************
*                                                                    *
*                       FLOATING POINT DIVIDE                           *
*                                                                    *
*        This subroutine performs signed floating point divide. The         *
*        operation performed is FPACC1/FPACC2. The divisor (FPACC2) is left *
*        unaltered and the answer is placed in FPACC1. There are several    *
*        error conditions that can be returned by this routine.  They are:   *
*        a) division by zero.  b) overflow.  c) underflow.  As with all      *
*        other routines, an error is indicated by the carry being set and    *
*        the error code being in the A-reg.                     *
*                                                                    *
*                        WORSE CASE = 495 CYCLES = 248 uS @ 2MHz          *
*                                                                    *
******************************************************************************
*
*
FLTDIV   EQU      *
         LDAA   MANTSGN2     GET FPACC2 MANTISSA SIGN.
         EORA   MANTSGN1     SET THE SIGN OF THE RESULT.
         STAA   MANTSGN1     SAVE THE RESULT.
         TST    FPACC2EX     IS THE DIVISOR 0?
         BNE    FLTDIV1      NO. GO SEE IF THE DIVIDEND IS ZERO.
         LDAA   #DIV0ERR     YES. RETURN A DIVIDE BY ZERO ERROR.
         JMP    RTNDIV0      FLAG ERROR AND RETURN.
FLTDIV1  TST    FPACC1EX     IS THE DIVIDEND 0?
         BNE    FLTDIV2      NO. GO PERFORM THE DIVIDE.
         CLRA           YES. ANSWER IS ZERO. NO ERRORS.
         CLR    MANTSGN1     SIGN OF ZERO IS POSITIVE.
         RTS             RETURN.
FLTDIV2  LDAA   FPACC1EX     NOW COMPUTE EXPONENT - GET NUMERATOR EXPONENT
         SUBA   FPACC2EX     SUBTRACT DENOMINATOR EXPONENT
         BCC    FLTDIV8      IF CARRY CLEAR, RESULT MUST BE POSITIVE
         BMI    FLTDIV6      RESULT IN RANGE
         JMP    RTNZERO      RETURN ZERO
FLTDIV8  BMI    FLTDIV7      OVERFLOW - RETURN MAX. NUMBER
FLTDIV6  ADDA   #$80            PUT BACK EXPONENT BIAS
         STAA   FPACC1EX     STORE CORRECTED QUOTIENT EXPONENT
         LDD    FPACC1MN     TO DO DIVIDE, NUMERATOR MANTISSA MUST BE LESS ...
         SUBD   FPACC2MN     ... THAN DENOMINATOR MANTISSA.
         BMI    FLTDIV3      BRANCH IF NUMERATOR LESS THAN DENOMINATOR MANTISSA
         BNE    FLTDIV4      TEST LSBs ONLY IF NUMERATOR = DENOMINATOR
         LDAA   FPACC1MN+2   CHECK LSBs SINCE BYTES 1 AND 2 OF ...
         SUBA   FPACC2MN+2   NUMERATOR AND DENOMINATOR ARE SAME.
         BMI    FLTDIV3      BRANCH IF NUMERATOR LESS THAN DENOMINATOR MANTISSA
FLTDIV4  LDD    FPACC1MN     DIVIDE NUMERATOR BY 2 SO IT IS SMALLER THAN DENOM
         LSRD           SHIFT TO DIVIDE BYTES 1 AND  2
         ROR    FPACC1MN+2   SHIFT BYTE 3
         STD    FPACC1MN     PUT BYTES 1 AND 2 BACK
         INC    FPACC1EX     NOW INCREMENT EXPONENT
         BNE    FLTDIV3      CHECK FOR OVERFLOW
FLTDIV7  JMP    RTNMAX           RETURN MAXIMUM MAGNITUDE NUMBER
FLTDIV3  LDD    FPACC1MN     GET PARTIAL NUMERATOR
         LDX    FPACC2MN     GET PARTIAL DENOMINATOR
         INX             PARTIAL QUOTIENT MUST BE LESS THAN FULL QUOTIENT
         BNE    FLTDIV5      IF X REGISTER ROLLED OVER, WE BLEW IT ...
         DEX             ... SO RESTORE X REGISTER TO WHERE IT WAS
FLTDIV5  FDIV           COMPUTE PARTIAL QUOTIENT
         PSHY           SAVE Y REGISTER
         LDY    FPACC1MN     TEMPORARY STORAGE FOR NUMERATOR
         STX    FPACC1MN     PARTIAL QUOTIENT TO MULTIPLY BY DENOMINATOR
         PSHX           SAVE PARTIAL QUOTIENT
         LDX    #0       SET UP WORK SPACE ON THE STACK.
         PSHX
         PSHX
         TSX             SET UP POINTER TO WORK SPACE.
         LDAA   FPACC2MN+2   MULTIPLY DENOMINATOR LS BYTE ...
         LDAB   FPACC1MN+1   ... BY NUMERATOR LS BYTE
         MUL
         STAA   3,X             SAVE PARTIAL RESULT ON STACK
         JSR    REMCOMP      JUMP INTO FLOATING MULTIPLY TO FINISH OPERATION
         STY    FPACC1MN     RESTORE NUMERATOR
         LDD    FPACC1MN+1   MOVE NUMERATOR BYTES 2 AND 3 TO D
         SUBD   1,X             SUBTRACT TO COMPUTE REMAINDER (ASSUME BYTE 1 SAME)
         LDX    FPACC2MN     LOAD DENOMINATOR
         FDIV           DIVIDE REMAINDER BY DENOMINATOR
         STX    FPACC1MN+1   STORE SECOND PARTIAL PRODUCT
         CLR    FPACC1MN     MS BYTE OF SECOND PARTIAL PRODUCT IS ZERO
         PULX           SCRAP STACK WORKSPACE
         PULX
         PULA           RETRIEVE FIRST PARTIAL PRODUCT
         PULB
         PULY           RETRIEVE Y REGISTER
         ADDD   FPACC1MN     ADD TO SECOND PARTIAL PRODUCT TO GET QUOTIENT
         STD    FPACC1MN     SAVE QUOTIENT IN FLOATING ACCUMULATOR
         CLRA           NO ERRORS
         RTS             DONE - RETURN
*
*
*
         TTL    FLTASC
******************************************************************************
*                                                                    *
*               FLOATING POINT TO ASCII CONVERSION SUBROUTINE       *
*                                                                    *
*        This subroutine performs floating point to ASCII conversion of      *
*        the number in FPACC1. The ascii string is placed in a buffer        *
*        pointed to by the X index register.  The buffer must be at least    *
*        14 bytes long to contain the ASCII conversion.  The resulting      *
*        ASCII string is terminated by a zero (0) byte.  Upon exit the      *
*        X Index register will be pointing to the first character of the     *
*        string.  FPACC1 and FPACC2 will remain unchanged.               *
*                                                                    *
******************************************************************************
*
*
FLTASC   EQU      *
         PSHX           SAVE THE POINTER TO THE STRING BUFFER.
         LDX    #FPACC1EX    POINT TO FPACC1.
         JSR    CHCK0            IS FPACC1 0?
         BNE    FLTASC1      NO. GO CONVERT THE NUMBER.
         PULX           RESTORE POINTER.
         LDD    #$3000           GET ASCII CHARACTER + TERMINATING BYTE.
         STD    0,X      PUT IT IN THE BUFFER.
         RTS             RETURN.
FLTASC1  LDX    FPACC1EX     SAVE FPACC1.
         PSHX
         LDX    FPACC1MN+1
         PSHX
         LDAA   MANTSGN1
         PSHA
         JSR    PSHFPAC2     SAVE FPACC2.
         LDX    #0
         PSHX           ALLOCATE LOCALS.
         PSHX
         PSHX           SAVE SPACE FOR STRING BUFFER POINTER.
         TSY             POINT TO LOCALS.
         LDX    15,Y             GET POINTER FROM STACK.
         LDAA   #$20            PUT A SPACE IN THE BUFFER IF NUMBER NOT NEGATIVE.
         TST    MANTSGN1     IS IT NEGATIVE?
         BEQ    FLTASC2      NO. GO PUT SPACE.
         CLR    MANTSGN1     MAKE NUMBER POSITIVE FOR REST OF CONVERSION.
         LDAA   #'
-          YES. PUT MINUS SIGN IN BUFFER.
FLTASC2  STAA   0,X
         INX             POINT TO NEXT LOCATION.
         STX    0,Y      SAVE POINTER.
FLTASC5  LDX    #N9999999    POINT TO CONSTANT 9999999.
         JSR    GETFPAC2     GET INTO FPACC2.
         JSR    FLTCMP           COMPARE THE NUMBERS. IS FPACC1 > 9999999?
         BHI    FLTASC3      YES. GO DIVIDE FPACC1 BY 10.
         LDX    #P9999999    POINT TO CONSTANT 999999.9
         JSR    GETFPAC2     MOVE IT INTO FPACC2.
         JSR    FLTCMP           COMPARE NUMBERS. IS FPACC1 > 999999.9?
         BHI    FLTASC4      YES. GO CONTINUE THE CONVERSION.
         DEC    2,Y      DECREMENT THE MULT./DIV. COUNT.
         LDX    #CONST10     NO. MULTIPLY BY 10. POINT TO CONSTANT.
FLTASC6  JSR    GETFPAC2     MOVE IT INTO FPACC2.
         JSR    FLTMUL
         BRA    FLTASC5      GO DO COMPARE AGAIN.
FLTASC3  INC    2,Y      INCREMENT THE MULT./DIV. COUNT.
         LDX    #CONSTP1     POINT TO CONSTANT ".1".
         BRA    FLTASC6      GO DIVIDE FPACC1 BY 10.
FLTASC4  LDX    #CONSTP5     POINT TO CONSTANT OF ".5".
         JSR    GETFPAC2     MOVE IT INTO FPACC2.
         JSR    FLTADD           ADD .5 TO NUMBER IN FPACC1 TO ROUND IT.
         LDAB   FPACC1EX     GET FPACC1 EXPONENT.
         SUBB   #$81            TAKE OUT BIAS +1.
         NEGB           MAKE IT NEGATIVE.
         ADDB   #23             ADD IN THE NUMBER OF MANTISSA BITS -1.
         BRA    FLTASC17     GO CHECK TO SEE IF WE NEED TO SHIFT AT ALL.
FLTASC7  LSR    FPACC1MN     SHIFT MANTISSA TO THE RIGHT BY THE RESULT (MAKE
         ROR    FPACC1MN+1   THE NUMBER AN INTEGER).
         ROR    FPACC1MN+2
         DECB           DONE SHIFTING?
FLTASC17 BNE    FLTASC7      NO. KEEP GOING.
         LDAA   #1      GET INITIAL VALUE OF "DIGITS AFTER D.P." COUNT.
         STAA   3,Y             INITIALIZE IT.
         LDAA   2,Y             GET DECIMAL EXPONENT.
         ADDA   #8      ADD THE NUMBER OF DECIMAL +1 TO THE EXPONENT.
*                          WAS THE ORIGINAL NUMBER > 9999999?
         BMI    FLTASC8      YES. MUST BE REPRESENTED IN SCIENTIFIC NOTATION.
         CMPA   #8      WAS THE ORIGINAL NUMBER < 1?
         BHS    FLTASC8      YES. MUST BE REPRESENTED IN SCIENTIFIC NOTATION.
         DECA           NO. NUMBER CAN BE REPRESENTED IN 7 DIGITS.
         STAA   3,Y             MAKE THE DECIMAL EXPONENT THE DIGIT COUNT BEFORE
*                          THE DECIMAL POINT.
         LDAA   #2      SETUP TO ZERO THE DECIMAL EXPONENT.
FLTASC8  SUBA   #2      SUBTRACT 2 FROM THE DECIMAL EXPONENT.
         STAA   2,Y             SAVE THE DECIMAL EXPONENT.
         TST    3,Y      DOES THE NUMBER HAVE AN INTEGER PART? (EXP. >0)
         BGT    FLTASC9      YES. GO PUT IT OUT.9
         LDAA   #'.          NO. GET DECIMAL POINT.
         LDX    0,Y      GET POINTER TO BUFFER.
         STAA   0,X             PUT THE DECIMAL POINT IN THE BUFFER.
         INX             POINT TO NEXT BUFFER LOCATION.
         TST    3,Y      IS THE DIGIT COUNT TILL EXPONENT =0?
         BEQ    FLTASC18     NO. NUMBER IS <.1
         LDAA   #'
0          YES. FORMAT NUMBER AS .0XXXXXXX
         STAA   0,X             PUT THE 0 IN THE BUFFER.
         INX             POINT TO THE NEXT LOCATION.
FLTASC18 STX    0,Y      SAVE NEW POINTER VALUE.
FLTASC9  LDX    #DECDIG      POINT TO THE TABLE OF DECIMAL DIGITS.
         LDAA   #7      INITIALIZE THE THE NUMBER OF DIGITS COUNT.
         STAA   5,Y
FLTASC10 CLR    4,Y      CLEAR THE DECIMAL DIGIT ACCUMULATOR.
FLTASC11 LDD    FPACC1MN+1   GET LOWER 16 BITS OF MANTISSA.
         SUBD   1,X             SUBTRACT LOWER 16 BITS OF CONSTANT.
         STD    FPACC1MN+1   SAVE RESULT.
         LDAA   FPACC1MN     GET UPPER 8 BITS.
         SBCA   0,X             SUBTRACT UPPER 8 BITS.
         STAA   FPACC1MN     SAVE RESULT. UNDERFLOW?
         BCS    FLTASC12     YES. GO ADD DECIMAL NUMBER BACK IN.
         INC    4,Y      ADD 1 TO DECIMAL NUMBER.
         BRA    FLTASC11     TRY ANOTHER SUBTRACTION.
FLTASC12 LDD    FPACC1MN+1   GET FPACC1 MANTISSA LOW 16 BITS.
         ADDD   1,X             ADD LOW 16 BITS BACK IN.
         STD    FPACC1MN+1   SAVE THE RESULT.
         LDAA   FPACC1MN     GET HIGH 8 BITS.
         ADCA   0,X             ADD IN HIGH 8 BITS OF CONSTANT.
         STAA   FPACC1MN     SAVE RESULT.
         LDAA   4,Y             GET DIGIT.
         ADDA   #$30            MAKE IT ASCII.
         PSHX           SAVE POINTER TO CONSTANTS.
         LDX    0,Y      GET POINTER TO BUFFER.
         STAA   0,X             PUT DIGIT IN BUFFER.
         INX             POINT TO NEXT BUFFER LOCATION.
         DEC    3,Y      SHOULD WE PUT A DECIMAL POINT IN THE BUFFER YET?
         BNE    FLTASC16     NO. CONTINUE THE CONVERSION.
         LDAA   #'.          YES. GET DECIMAL POINT.
         STAA   0,X             PUT IT IN THE BUFFER.
         INX             POINT TO THE NEXT BUFFER LOCATION.
FLTASC16 STX    0,Y      SAVE UPDATED POINTER.
         PULX           RESTORE POINTER TO CONSTANTS.
         INX             POINT TO NEXT CONSTANT.
         INX
         INX
         DEC    5,Y      DONE YET?
         BNE    FLTASC10     NO. CONTINUE CONVERSION OF "MANTISSA".
         LDX    0,Y      YES. POINT TO BUFFER STRING BUFFER.
FLTASC13 DEX             POINT TO LAST CHARACTER PUT IN THE BUFFER.
         LDAA   0,X             GET IT.
         CMPA   #$30            WAS IT AN ASCII 0?
         BEQ    FLTASC13     YES. REMOVE TRAILING ZEROS.
         INX             POINT TO NEXT AVAILABLE LOCATION IN BUFFER.
         LDAB   2,Y             DO WE NEED TO PUT OUT AN EXPONENT?
         BEQ    FLTASC15     NO. WE'
RE DONE.
         LDAA   #'E          YES. PUT AN 'E' IN THE BUFFER.
         STAA   0,X
         INX             POINT TO NEXT BUFFER LOCATION.
         LDAA   #'
+          ASSUME EXPONENT IS POSITIVE.
         STAA   0,X             PUT PLUS SIGN IN THE BUFFER.
         TSTB           IS IT REALLY MINUS?
         BPL    FLTASC14     NO. IS'S OK AS IS.
         NEGB           YES. MAKE IT POSITIVE.
         LDAA   #'
-          PUT THE MINUS SIGN IN THE BUFFER.
         STAA   0,X
FLTASC14 INX             POI