But is there any reason to try to avoid floating point? Just to make some advertisment for floating point, see the code for the floating point computation proposed in my post!
Code:
SIGN = $00
X2 = $01
M2 = $02
X1 = $05
M1 = $06
E = $09
Z = $0D
T = $11
SEXP = $15
INT = $19
*=$0300
;CONVERT I1 TO FLOAT
LDA I1
STA M1
LDA I1+1
STA M1+1
JSR FLOAT
;MOVE TO X2,M2 POSITION
LDX #$04
L1 LDA X1-1,X
STA X2-1,X
DEX
BNE L1
;CONVERT I2 TO FLOAT
LDA I2
STA M1
LDA I2+1
STA M1+1
JSR FLOAT
JSR FDIV
;MOVE TO X2,M2 POSITION
LDX #$04
L2 LDA X1-1,X
STA X2-1,X
DEX
BNE L2
;CONVERT IFF TO FLOAT
LDA IFF
STA M1
LDA IFF+1
STA M1+1
JSR FLOAT
;SAVE FLOATING POINT NUMBER F
LDX #$04
L3 LDA X1-1,X
STA F-1,X
DEX
BNE L3
JSR FDIV
;SAVE FLOATING POINT NUMBER G
LDX #$04
L4 LDA X1-1,X
STA G-1,X
DEX
BNE L4
;
;COMPUTE PI*I/32767
;
;CONVERT I TO FLOAT
LDA I
STA M1
LDA I+1
STA M1+1
JSR FLOAT
;RETRIEVE FLOATING POINT NUMBER G
LDX #$04
L5 LDA G-1,X
STA X2-1,X
DEX
BNE L5
JSR FMUL
; JSR SIN ;MISSING FUNCTION
;RETRIEVE FLOATING POINT NUMBER F
LDX #$04
L6 LDA F-1,X
STA X2-1,X
DEX
BNE L6
JSR FMUL
JSR FIX
BRK
IFF .DB $7F ;IFF = 32767
.DB $FF
I1 .DB $7A ;I1=31416
.DB $B8
I2 .DB $27 ;I2=10000
.DB $10
I .DB $16 ;I=5825 (32 DEG)
.DB $C1
F *=*+4
F1 *=*+4
F2 *=*+4
G *=*+4
; BASIC FLOATING POINT ROUTINES
;
ADD CLC ;CLEAR CARRY
LDX #$02 ;INDEX FOR 3-BYTE ADD
ADD1 LDA M1,X
ADC M2,X ;ADD A BYTE OF MANT2 TO MANT1
STA M1,X
DEX ;ADVANCE INDEX TO NEXT MORE SIGNIF.BYTE
BPL ADD1 ;LOOP UNTIL DONE.
RTS ;RETURN
MD1 ASL SIGN ;CLEAR LSB OF SIGN
JSR ABSWAP ;ABS VAL OF MANT1, THEN SWAP MANT2
ABSWAP BIT M1 ;MANT1 NEG?
BPL ABSWP1 ;NO,SWAP WITH MANT2 AND RETURN
JSR FCOMPL ;YES, COMPLIMENT IT.
INC SIGN ;INCR SIGN, COMPLEMENTING LSB
ABSWP1 SEC ;SET CARRY FOR RETURN TO MUL/DIV
;
; SWAP EXP/MANT1 WITH EXP/MANT2
;
SWAP LDX #$04 ;INDEX FOR 4-BYTE SWAP.
SWAP1 STY E-1,X
LDA X1-1,X ;SWAP A BYTE OF EXP/MANT1 WITH
LDY X2-1,X ;EXP/MANT2 AND LEAVEA COPY OF
STY X1-1,X ;MANT1 IN E(3BYTES). E+3 USED.
STA X2-1,X
DEX ;ADVANCE INDEX TO NEXT BYTE
BNE SWAP1 ;LOOP UNTIL DONE.
RTS
;
;
;
; CONVERT 16 BIT INTEGER IN M1(HIGH) AND M1+1(LOW) TO F.P.
; RESULT IN EXP/MANT1. EXP/MANT2 UNEFFECTED
;
;
FLOAT LDA #$8E
STA X1 ;SET EXPN TO 14 DEC
LDA #$00 ;CLEAR LOW ORDER BYTE
STA M1+2
BEQ NORM ;NORMALIZE RESULT
NORM1 DEC X1 ;DECREMENT EXP1
ASL M1+2
ROL M1+1 ;SHIFT MANT1 (3 BYTES) LEFT
ROL M1
NORM LDA M1 ;HIGH ORDER MANT1 BYTE
ASL ;UPPER TWO BITS UNEQUAL?
EOR M1
BMI RTS1 ;YES,RETURN WITH MANT1 NORMALIZED
LDA X1 ;EXP1 ZERO?
BNE NORM1 ;NO, CONTINUE NORMALIZING
RTS1 RTS ;RETURN
;
;
; EXP/MANT2-EXP/MANT1 RESULT IN EXP/MANT1
;
FSUB JSR FCOMPL ;CMPL MANT1 CLEARS CARRY UNLESS ZERO
SWPALG JSR ALGNSW ;RIGHT SHIFT MANT1 OR SWAP WITH MANT2 ON CARRY
;
; ADD EXP/MANT1 AND EXP/MANT2 RESULT IN EXP/MANT1
;
FADD LDA X2
CMP X1 ;COMPARE EXP1 WITH EXP2
BNE SWPALG ;IF UNEQUAL, SWAP ADDENDS OR ALIGN MANTISSAS
JSR ADD ;ADD ALIGNED MANTISSAS
ADDEND BVC NORM ;NO OVERFLOW, NORMALIZE RESULTS
BVS RTLOG ;OV: SHIFT MANT1 RIGHT. NOTE CARRY IS CORRECT SIGN
ALGNSW BCC SWAP ;SWAP IF CARRY CLEAR, ELSE SHIFT RIGHT ARITH.
RTAR LDA M1 ;SIGN OF MANT1 INTO CARRY FOR
ASL ;RIGHT ARITH SHIFT
RTLOG INC X1 ;INCR EXP1 TO COMPENSATE FOR RT SHIFT
BEQ OVFL ;EXP1 OUT OF RANGE.
RTLOG1 LDX #$FA ;INDEX FOR 6 BYTE RIGHT SHIFT
ROR1 LDA #$80
BCS ROR2
ASL
ROR2 LSR E+3,X ;SIMULATE ROR E+3,X
ORA E+3,X
STA E+3,X
INX ;NEXT BYTE OF SHIFT
BNE ROR1 ;LOOP UNTIL DONE
RTS ;RETURN
;
;
; EXP/MANT1 X EXP/MANT2 RESULT IN EXP/MANT1
;
FMUL JSR MD1 ;ABS. VAL OF MANT1, MANT2
ADC X1 ;ADD EXP1 TO EXP2 FOR PRODUCT EXPONENT
JSR MD2 ;CHECK PRODUCT EXP AND PREPARE FOR MUL
CLC ;CLEAR CARRY
MUL1 JSR RTLOG1 ;MANT1 AND E RIGHT.(PRODUCT AND MPLIER)
BCC MUL2 ;IF CARRY CLEAR, SKIP PARTIAL PRODUCT
JSR ADD ;ADD MULTIPLICAN TO PRODUCT
MUL2 DEY ;NEXT MUL ITERATION
BPL MUL1 ;LOOP UNTIL DONE
MDEND LSR SIGN ;TEST SIGN (EVEN/ODD)
NORMX BCC NORM ;IF EXEN, NORMALIZE PRODUCT, ELSE COMPLEMENT
FCOMPL SEC ;SET CARRY FOR SUBTRACT
LDX #$03 ;INDEX FOR 3 BYTE SUBTRACTION
COMPL1 LDA #$00 ;CLEAR A
SBC X1,X ;SUBTRACT BYTE OF EXP1
STA X1,X ;RESTORE IT
DEX ;NEXT MORE SIGNIFICANT BYTE
BNE COMPL1 ;LOOP UNTIL DONE
BEQ ADDEND ;NORMALIZE (OR SHIFT RIGHT IF OVERFLOW)
;
;
; EXP/MANT2 / EXP/MANT1 RESULT IN EXP/MANT1
;
FDIV JSR MD1 ;TAKE ABS VAL OF MANT1, MANT2
SBC X1 ;SUBTRACT EXP1 FROM EXP2
JSR MD2 ;SAVE AS QUOTIENT EXP
DIV1 SEC ;SET CARRY FOR SUBTRACT
LDX #$02 ;INDEX FOR 3-BYTE INSTRUCTION
DIV2 LDA M2,X
SBC E,X ;SUBTRACT A BYTE OF E FROM MANT2
PHA ;SAVE ON STACK
DEX ;NEXT MORE SIGNIF BYTE
BPL DIV2 ;LOOP UNTIL DONE
LDX #$FD ;INDEX FOR 3-BYTE CONDITIONAL MOVE
DIV3 PLA ;PULL A BYTE OF DIFFERENCE OFF STACK
BCC DIV4 ;IF MANT2<E THEN DONT RESTORE MANT2
STA M2+3,X
DIV4 INX ;NEXT LESS SIGNIF BYTE
BNE DIV3 ;LOOP UNTIL DONE
ROL M1+2
ROL M1+1 ;ROLL QUOTIENT LEFT, CARRY INTO LSB
ROL M1
ASL M2+2
ROL M2+1 ;SHIFT DIVIDEND LEFT
ROL M2
BCS OVFL ;OVERFLOW IS DUE TO UNNORMALIZED DIVISOR
DEY ;NEXT DIVIDE ITERATION
BNE DIV1 ;LOOP UNTIL DONE 23 ITERATIONS
BEQ MDEND ;NORMALIZE QUOTIENT AND CORRECT SIGN
MD2 STX M1+2
STX M1+1 ;CLR MANT1 (3 BYTES) FOR MUL/DIV
STX M1
BCS OVCHK ;IF EXP CALC SET CARRY, CHECK FOR OVFL
BMI MD3 ;IF NEG NO UNDERFLOW
PLA ;POP ONE
PLA ;RETURN LEVEL
BCC NORMX ;CLEAR X1 AND RETURN
MD3 EOR #$80 ;COMPLIMENT SIGN BIT OF EXP
STA X1 ;STORE IT
LDY #$17 ;COUNT FOR 24 MUL OR 23 DIV ITERATIONS
RTS ;RETURN
OVCHK BPL MD3 ;IF POS EXP THEN NO OVERFLOW
OVFL BRK
;
;
; CONVERT EXP/MANT1 TO INTEGER IN M1 (HIGH) AND M1+1(LOW)
; EXP/MANT2 UNEFFECTED
;
JSR RTAR ;SHIFT MANT1 RT AND INCREMENT EXPNT
FIX LDA X1 ;CHECK EXPONENT
CMP #$8E ;IS EXPONENT 14?
BNE FIX-3 ;NO, SHIFT
RTRN RTS ;RETURN
This is it! I see no reason to avoid floating point!
Code:
31416 $8E7AB8
10000 $8D4E20
PI $816487FC
32767 $8E7FFF
PI / 32767 $726488C4
PI * I / 32767 $7F477C5F (for I=5825)
(PI *I / 32767) * 32767 $8E477BD0
(= PI * 5825 = 18299 as the missing "SIN" is commented out)