.TITLE FCONVT .IDENT /RICE/ ; ; CALL FCONVT(DATA,BUFFER,BYTES) ; ; DATA = FLOATING DATA TO CONVERT ; BUFFER = BUFFER FOR THE RESULT ; BYTES = # OF BYTES IN THE BUFFER ; FCONVT:: LDFPS #40000 ; SET SINGLE FLOATING MODE, NO ERR MOV #3,R0 CALL R5CHEK LDF @(R5)+,%0 MOV (R5)+,R0 ; BUFFER MOV @(R5)+,R4 ; DIGITS F0CNVT:: LDFPS #40000 ; SET SINGLE FLOATING MODE, NO ERR DEC R4 ; ONE LESS FOR SIGN MOV R4,-(SP) ; SAVE COUNT CMP R4,#8. ; IS IT TOO BIG? BLE 1$ ; NO MOV #8.,R4 ; YES, FIX IT 1$: MOV #1,R1 ; WILL BE EXPONENT CLR R2 ; AND POWER OF 10 TSTF %0 ; IS NUMBER NEGATIVE MOVB #' ,(R0)+ ; BLANK FOR SIGN CFCC BEQ 30$ ; ZERO BGT 2$ ; POSITIVE MOVB #'-,-1(R0) ; PUT NEG SIGN INTO BUFFER NEGF %0 ; NOW IS POSITIVE 2$: STEXP %0,R2 ; GET EXP POWER OF 2 LDCIF R2,%1 ; WILL BE POWER OF 10 MULF LOG2,%1 ; MULT BY LOG TO GET POWER 10 STCFI %1,R1 ; INTEGER POWER OF 10 RESULT INC R1 ; MAKE IT 1 LARGER MOV R1,R3 BGT 12$ ; POSITIVE NON ZERO EXPONENT NEG R3 ; SWITCH R3 TO POSITIVE 12$: BIC #177700,R3 ; ONLY 6 BITS NECESSARY MOV #E0,R2 ; POWERS OF TEN LDF (R2)+,%1 ; GET 1. 13$: ASR R3 ; TEST RH BIT BCC 14$ ; BIT IS ZERO MULF (R2),%1 ; NON ZERO,ADD POWER 10 14$: ADD #4,R2 ; NEXT POWER OF 10 TST R3 ; ARE WE DONE ? BNE 13$ ; NO MORE TO CONVERT TST R1 ; CHECK EXP BMI 15$ ; NEG EXP DIVF %1,%0 ; DIVIDE BY POWER OF 10 BR 20$ ; ALL CONVERTED 15$: MULF %1,%0 ; MULT TO CONVERT 20$: CMPF EM1,%0 ; IS NUMBER SMALLER THAN .1 CFCC BLE 21$ ; NO MULF E1,%0 ; YES, SCALE IT UP BY 10 DEC R1 ; DECREASE EXPONENT BY 1 21$: CLR R2 MOV R4,R3 ; SAVE DIGITS BLE CEND ; BAD DATA 22$: ASL R3 ; TABLE POINTER ASL R3 ADDF RTABL-4(R3),%0 ; ROUND OFF DATA CMPF E0,%0 ; IS NUMBER GREATER THAN 1 CFCC BGT 23$ ; NO SUBF RTABL-4(R3),%0 ; REMOVE LAST ROUND OFF MULF EM1,%0 ; DIVIDE NUMBER BY 10 INC R1 ; DECREASE EXPONENT BY 1 ADDF RTABL-4(R3),%0 ; ROUND OFF NUMBER 23$: CMP R1,R4 ; IS IT GREATER THAN OR EQUAL TO R4 BGE 25$ ; YES TST R1 ; IS IT NEGATIVE BGE 30$ ; NO 25$: MOV (SP),R2 ; TOTAL DIGITS SUB R4,R2 ; DIGITS FOR EXPONENT CMP R2,#4 ; ENOUGH FOR EXPONENT? BGE 27$ ; YES! ADDF RTABL-4(R3),%0 ; NO! , ADJUST THE EXPONENT MOV (SP),R4 ; TOTAL DIGITS SUB #4,R4 ; LESS EXPONENT BR 21$ ; TRY AGAIN 27$: MOV R1,R2 DEC R2 ; ACTUAL EXPONENT TO PRINT MOV #1,R1 30$: SUB R4,(SP) ; NUMBER OF UNCONVERTED CHAR CALL CONV ; MANTISSA IN BCD TO USER TST R2 ; IS IT 0 BEQ CEND ; YES MOVB #'E,(R0)+ ; SET UP EXPONENTIAL NOTATION TST R2 ; IS EXPONENT NEGATIVE? BGE 32$ ; NO MOVB #'-,(R0)+ ; YES NEG R2 ; MAKE IT POSITIVE BR 34$ 32$: MOVB #'+,(R0)+ ; GET PLUS SIGN 34$: LDCIF R2,%0 ; EXPONENT TO CONVERT ADDF RTABL,%0 ; FORCE ROUND OFF DIVF E2,%0 ; NOW IS CORRECT RANGE MOV #2,R4 ; 2 CHAR PER NUMBER MOV R4,R1 ; IS ALSO EXPONENT SUB #4,(SP) ; NUMBER OF UNCONVERTED CHAR CALL CONV ; POWER OF 10 TO USER CEND: MOV (SP)+,R4 ; SAVED DIGIT COUNT BLE 2$ ; NONE 1$: MOVB #' ,(R0)+ ; PAD WITH BLANKS SOB R4,1$ 2$: RETURN ; TBLE POWERS OF 10 E6: .FLT2 1.E6 EM1: .FLT2 0.1 E0: .FLT2 1. E1: .FLT2 10. E2: .FLT2 100. E4: .FLT2 1.E4 E8: .FLT2 1.E8 E16: .FLT2 1.E16 E32: .FLT2 1.E32 LOG2: .FLT2 .30103 RTABL: .FLT2 5.E-1 .FLT2 5.E-2 .FLT2 5.E-3 .FLT2 5.E-4 .FLT2 5.E-5 .FLT2 5.E-6 .FLT2 5.E-7 .FLT2 5.E-8 CONV: INC R1 1$: DEC R1 ; EXPONENT BNE 2$ ; NOT YET ZERO MOVB #'.,(R0)+ ; ZERO, SO ADD DECIMAL POINT BR 20$ ; NEXT DIGIT 2$: MODF E1,%0 ; MULTIPLY + INTEGERIZE FLOATING STCFI %1,R3 ; GET INTEGER PART ADD #'0,R3 ; NOW IS DIGIT MOVB R3,(R0)+ ; INTO BUFFER 20$: SOB R4,1$ RETURN .END