;FLOATING POINT ACCUMULATOR $B0-$B5
FAC=$B0
;WORK $B6-$C9
WORK=$B6
;THE EXPONENT FOR THE VALUE "1" USED BY COMMODORE WAS 129
;THE IEEE STANDARD IS NOW 127
BIAS=129
BIAS1=BIAS-1
BIASM=256-BIAS
BIAS31=BIAS+31
FLOAT  LDA #$00
       STA FAC+5    ;SIGN "+" HARDCODED
       LDA #BIAS31
       STA FAC      ;EXPONENT IF INTEGER LARGER THEN $80000000
       LDA FAC+1
       BMI FLOAT1   ;BRANCH IF NO SHIFTING NEEDED
       LDX #$1F
FLOAT0 DEC FAC
       ASL FAC+4
       ROL FAC+3
       ROL FAC+2
       ROL FAC+1
       BMI FLOAT1   ;BRANCH IF READY
       DEX
       BNE FLOAT0
;IT WAS ZERO! THE VALUE IN FAC (WHICH IS "BIAS") IS IRRELEVANT!
FLOAT1 RTS
;
;SUBROUTINE TO MOVE FLOATING POINT ACC TO ARG
;
TOARG  LDX #$FA 
TOARG0 LDA FAC+6,X
       STA WORK+6,X
       INX
       BNE TOARG0
       RTS
;
;SUBROUTINE TO SUBTRACT THE VALUE IN "FAC" FROM THE VALUE IN "ARG"
;I.E. "ARG" - "FAC" => "FAC"
;
FSUB   LDA FAC+5    ;CHANGE SIGN
       EOR #$FF
       STA FAC+5
;
;SUBROUTINE TO ADD THE VALUE IN "FAC" TO THE VALUE IN "ARG"
;I.E. "ARG" + "FAC" => "FAC"
;
FADD   LDA WORK+1
;
;CHECK IF WE ARE ADDING ZERO
       BNE   FADD0
       JMP   FADDH
;
;CHECK IF WE ARE ADDING SOMETHING TO ZERO
FADD0  LDA FAC+1
       BNE   FADD1
       JMP   FADDF
;
;COMPARE THE EXPONENTS
FADD1  LDA WORK
       SEC
       SBC FAC
       BEQ FADD5     ;BRANCH IF MANTISSAS ALREADY OK
       TAY           ;THE DIFFERENCE IN EXPONENTS
       BCS FADD3     ;BRANCH IF THE EXPONENT IN "WORK" IS LARGER
;
;IT IS THE MANTISSA OF "WORK" THAT SHALL BE SHIFTED
FADD2  LSR WORK+1    ;RIGHT SHIFT THE MANTISSA
       ROR WORK+2
       ROR WORK+3
       ROR WORK+4
       INY
       BNE FADD2
       BEQ FADD5     ;THE MANTISSA NOW OK!
;
;IT IS THE MANTISSA OF "FAC" THAT SHALL BE SHIFTED
FADD3  LDA WORK      ;THE PRELIMINARY EXPONENT OF THE RESULT
       STA FAC
FADD4  LSR FAC+1     ;RIGHT SHIFT THE MANTISSA
       ROR FAC+2
       ROR FAC+3
       ROR FAC+4
       DEY
       BNE FADD4
;
;THE MANTISSAS NOW ALIGNED
;
;CHECK IF THE NUMBERS HAVE THE SAME SIGN
FADD5  LDA WORK+5
       CMP FAC+5
       BEQ FADDD     ;BRANCH IF EQUAL SIGN
;
;DIFFERENT SIGNS
;
;WHICH NUMBER HAS THE LARGEST ABSOLUTE VALUE?
       LDX #$FC
FADD6  LDA FAC+5,X
       CMP WORK+5,X
       BCC FADD9     ;BRANCH IF THE VALUE IN "WORK" IS LARGER 
       BNE FADD7     ;BRANCH IF THE VALUE IN "FAC" IS LARGER
       INX
       BNE FADD6     ;BRANCH IF THE THE NEXT MOST SIGNIFICANT BYTE
;                     SHOULD BE COMPARED
;ALL BYTES WERE EQUAL, THE SUM IS ZERO
       LDA #$00
       STA FAC+1  
       BEQ FADDH
;
;THE VALUE IN "FAC" IS LARGER (THE SIGN IS OK!)
FADD7  LDX #$04 
FADD8  LDA FAC,X
       SBC WORK,X
       STA FAC,X
       DEX
       BNE FADD8
       BEQ FADDB      ;POSSIBLY SHOULD THE MANTISSA LEFT BE SHIFTED LEFT
;
;THE VALUE IN "WORK" IS LARGER (THE SIGN MUST BE CHANGED!)
FADD9  LDA FAC+5
       EOR #$FF
       STA FAC+5      ;CHANGE SIGN
       LDX #$04
       SEC
FADDA  LDA WORK,X
       SBC FAC,X
       STA FAC,X
       DEX
       BNE FADDA
;
;SHALL THE MANTISSA BE SHIFTED LEFT?
;(IT IS CERTAIN THAT AT LEAST ONE BIT IS SET!)
FADDB  LDA FAC+1
FADDC  BMI FADDH      ;BRANCH IF DONE
       DEC FAC
       BEQ FADDJ      ;UNDERFLOW
       ROL FAC+4
       ROL FAC+3
       ROL FAC+2
       ROL FAC+1
       JMP FADDC
;
;SAME SIGN
FADDD  LDX #$04
       CLC
FADDE  LDA FAC,X
       ADC WORK,X
       STA FAC,X
       DEX
       BNE FADDE
       BCC FADDH      ;BRANCH IF NO RIGHT SHIFT IS NEEDED
;
;SHIFT THE MANTISSA ONE STEP TO THE RIGHT
       INC FAC
       BEQ FADDI
       ROR FAC+1
       ROR FAC+2
       ROR FAC+3
       ROR FAC+4
       JMP FADDH      ;DONE!
;
;THE VALUE IN "FAC" WAS ZERO, I.E. THE SUM IS THE VALUE IN "WORK"
FADDF  LDX #$06
FADDG  LDA WORK-1,X
       STA FAC-1,X
       DEX
       BNE FADDG
FADDH  RTS
FADDI  DEC FAC        ;OVERFLOW, SET "FAC" TO $FF
       RTS
FADDJ  LDA #$00       ;UNDERFLOW, SET TO ZERO
       STA FAC+1
       RTS
;
;SUBROUTINE TO DIVIDE THE VALUE IN "ARG" WITH THE VALUE IN "FAC"
;I.E. "ARG" / "FAC" => "FAC"
;
FDIV   LDX #$00       ;THE SIGN "+"
       LDA WORK+5     ;THE SIGN OF THE DIVIDEND
       CMP FAC+5      ;THE SIGN OF THE DIVISOR
       BEQ FDIV0
       DEX            ;THE SIGN "-"
FDIV0  STX FAC+5      ;SET THE SIGN OF THE RATIO
       LDA FAC+1      ;IS THE DIVIDEND ZERO?
       BEQ FDIVD
       LDA WORK+1     ;IS THE DIVISOR ZERO?
       BNE FDIV1
       STA FAC+1
       JMP FDIVB
FDIV1  LDA #$00
       LDX #$0C
FDIV2  STA WORK+4,X   ;SET WORK AREA TO ZERO
       DEX
       BNE FDIV2
;
;GET THE MANTISSA OF THE DIVIDEND
       LDX #$04
FDIV3  LDA FAC,X
       STA WORK+8,X
       DEX
       BNE FDIV3
       LDY #$20       ;NUMBER OF BITS IN 4 BYTES
FDIV4  LDX #$F8
FDIV5  LDA WORK+9,X
       CMP WORK+17,X
       BCC FDIV8
       BNE FDIV6
       INX
       BNE FDIV5
FDIV6  LDX #$08
;
; CARRY IS SET AT THIS POINT!
FDIV7  LDA WORK,X
       SBC WORK+8,X
       STA WORK,X
       DEX
       BNE FDIV7
FDIV8  ROL FAC+4      ;ROLL IN BINARY DIGIT     
       ROL FAC+3
       ROL FAC+2
       ROL FAC+1
       LDX #$F8       ;ROLL RIGHT 8 BYTES
       CLC
FDIV9  ROR WORK+17,X
       INX
       BNE FDIV9
       DEY
       BNE FDIV4
;
;THE EXPONENT OF THE PRODUCT, 2 BYTE WORD
;BIAS+1 OR BIAS+2 TO BE SUBTRACTED LATER
       SEC
       LDA WORK
       SBC FAC
       STA WORK+19
       LDA #$01
       SBC #$00
       STA WORK+18
       LDA #BIASM
       STA WORK+17
;
;POSSIBLY A SHIFT ONE STEP TO THE LEFT
       LDA FAC+1
       BMI FDIVA
       ASL FAC+4
       ROL FAC+3
       ROL FAC+2
       ROL FAC+1
       INC WORK+17
FDIVA  SEC
       LDA WORK+19
       SBC WORK+17
       STA FAC
       LDA WORK+18
       SBC #$00
       BNE FDIVD
       BCC FDIVC
FDIVB  RTS
;
;UNDERFLOW, SET RESULT TO ZERO
FDIVC  LDA #$00
       STA FAC+1
       RTS
;
;OVERFLOW, "INF" MARKED ACCORDING TO IEEE
FDIVD  LDA #$FF
       STA FAC
       STA FAC+1      ;ANY NON-ZERO VALUE!
       RTS
;
;SUBROUTINE TO MULTIPLY THE VALUE IN "ARG" WITH THE VALUE IN "FAC"
;I.E. "ARG" * "FAC" => "FAC"
;
FMUL   LDX #$00       ;THE SIGN "+"
       LDA FAC+5      ;THE SIGN OF THE FIRST FACTOR
       CMP WORK+5     ;THE SIGN OF THE SECOND FACTOR
       BEQ FMUL0
       DEX            ;THE SIGN "-"
FMUL0  STX FAC+5      ;SET THE SIGN OF THE PRODUCT
       LDA WORK+1     ;IS THE SECOND FACTOR ZERO
       BNE FMUL1
       STA FAC+1      ;SET THE FIRST FACTOR ZERO
FMUL1  LDA FAC+1      ;IS THE FIRST FACTOR ZERO
       BEQ FMULD      ;THE NUMBER IN FAC - FAC+5 WHICH SHOULD BE THE PRODUCT IS ALREADY ZERO
;
;NONE OF THE FACTORS ZERO
       LDA #$00
       LDX #$0C       ;PREPARE WORKING AREA
FMUL2  STA WORK+4,X   
       DEX
       BNE FMUL2
       LDY #$20       ;NUMBER OF BITS IN 4 BYTES
FMUL3  LDX #$F8       ;ROLL RIGHT 8 BYTES
       CLC
FMUL4  ROR WORK+9,X
       INX
       BNE FMUL4
       ASL FAC+4
       ROL FAC+3
       ROL FAC+2
       ROL FAC+1
       BCC FMUL6      
;
;ADD CONTRIBUTION
       LDX #$08
       CLC
FMUL5  LDA WORK+8,X
       ADC WORK,X
       STA WORK+8,X
       DEX
       BNE FMUL5
FMUL6  DEY
       BNE FMUL3
;
;THE EXPONENT OF THE PRODUCT, 2 BYTE WORD
;BIAS+1 OR BIAS+2 TO BE SUBTRACTED LATER
       CLC
       LDA FAC
       ADC WORK
       STA WORK+19
       LDA #$00
       ADC #$00
       STA WORK+18
       LDA #BIAS1
       STA WORK+17
FMUL7  LDA WORK+9
       BMI FMUL8
;
;THE MSB BIT IS NOT SET, SHIFT LEFT     
       ASL WORK+13
       ROL WORK+12
       ROL WORK+11
       ROL WORK+10
       ROL WORK+9  
       INC WORK+17
;
;COMPUTE THE EXPONENT
FMUL8  SEC
       LDA WORK+19
       SBC WORK+17
       STA FAC
       LDA WORK+18
       SBC #$00
       BCC FMUL9
       BNE FMULA
       BEQ FMULB
;
;UNDERFLOW, SET RESULT TO ZERO
FMUL9  LDA #$00
       STA WORK+9
       BEQ FMULB
;
;OVERFLOW, "INF" MARKED ACCORDING TO IEEE
FMULA  LDA #$FF
       STA FAC
;
;MOVE THE RESULT TO FAC
FMULB  LDX #$04
FMULC  LDA WORK+8,X
       STA FAC,X
       DEX
       BNE FMULC
FMULD  RTS
;SUBROUTINE TO CONVERT A FLOATING POINT VALUE 
;TO A 4-BYTE UN-SIGNED INTEGER VALUE
;
;ONLY POSSIBLE IF THE EXPONENT IS SMALLER OR EQUAL TO "BIAS"+31
;IF THIS IS NOT THE CASE NOTHING IS DONE (OVERFLOW)!
;
;IF THE EXPONENT IS SMALLER THEN BIAS+31 AND THE SIGN OF THE FLOATING NUMBER IS "-"
;A NEGATIVE SIGNED INTEGER RESULTS
;
FIX    LDA FAC
       SEC
       SBC #BIAS31
       BCS FIX2
       TAY
FIX0   INC FAC
       LSR FAC+1
       ROR FAC+2
       ROR FAC+3
       ROR FAC+4
       INY
       BNE FIX0
       LDA FAC+5
       BPL FIX2
;NEGATIVE NUMBER
       SEC
       LDX #$04
FIX1   LDA #$00
       SBC FAC,X
       STA FAC,X
       DEX
       BNE FIX1
FIX2   RTS

    Source: geocities.com/matsr2007