.TITLE PFCVT -- WRITE OUT A REAL/DOUBLE IN FR0 .IDENT /831006/ ; $$FCVT: WRITE OUT A REAL/DOUBLE IN FR0 ; REGISTER USAGE ; R1: @FILEBLOCK, @BUFFER ; R0: SCRATCH ; R2: SCRATCH ; R3: @BUFFER, COUNT ; R4: COUNT ; FR0-FR3: CLOBBERED ; CALLS: P$FPAD, P$FPUT ; .GLOBL P$FPAD,P$FPUT F0=R0 F1=R1 F2=R2 F3=R3 F4=R4 $$FCVT:: MOV SP,R3 ;R3 -> END OF BUFFER+1 SUB #BSIZ,SP ;MAKE ROOM FOR BUFFER IN STACK MOV SP,R1 ;R1 -> START OF BUFFER CLR SIGN ;ASSUME > 0.0 CFCC ;GET FCC FROM LOAD IN CALLER BGT 1$ ;IF > 0.0 BEQ 4$ ;IF = 0.0 NEGD F0 ;R < 0.0 MAKE IT POSITIVE INC SIGN ;MAKE < 0.0 1$: MODD #ONE,F0 ;SEE IF < 1.0 TSTD F1 CFCC BEQ 5$ ;IT IS CLR R2 ;R2 = NR DIGITS IN INTEGER PART STD F0,F4 ;R >= 1.0 COMES HERE, SAVE FRACTION STD F1,F0 ;PUT INTEGER PART IN F0 2$: MODD TENTH,F0 ;PUT LOWER ORDER INTEGER DIGIT INTO FRACTION STD F0,F2 ;GET ACACTION IN F2 STD F1,F0 ;WILL GET TO REMAINING INTEGER PART LATER ADDD #NOISE,F2 ;BECAUSE 0.1 IS NOTERMINATING BINARY MODD #TEN,F2 ;ISOLATE THE LOWER ORDER INTEGER DIGIT STCDI F3,R0 ADD #'0,R0 MOVB R0,-(R3) ;PUT INTO BUFFER BACKWARDS INC R2 ;BUMP INTEGER FIELD COUNTER TSTD F0 ;ANYTHING LEFT IN INTEGER PART? CFCC BNE 2$ ;IF SO, CONTINUE MOV R2,R0 ;NUMBER OF DIGITS PRODUCED SO FAR 3$: MOVB (R3)+,(R1)+ ;MOVE THEM TO HEAD OF BUFFER SOB R0,3$ LDD F4,F0 ;RESTORE FRACTIONAL PART BR 5$ 4$: INC R2 ;R = 0.0 MOVB #'0,(R1)+ 5$: MOV 12.+BSIZ(SP),R4 ;NR FRACTIONAL DIGITS REQUESTED BLE 7$ INC R4 ;MAKE ONE MORE FOR ROUND UP MOV R4,NRDIG ;AND SAVE FOR LATER 6$: MODD #TEN,F0 STCDI F1,R0 ADD #'0,R0 MOVB R0,(R1)+ SOB R4,6$ 7$: TST NRDIG ;FRACTIONAL PART? BLE 9$ ; NO MOV R1,R2 ;SAVE PTR TO LAST DIGIT MOV R1,R4 SUB SP,R4 ;COMPUTE TOTAL DIGITS MOVB (R2),R0 ;GET LAST (EXTRA) DIGIT ADD #5,R0 ;ROUND IT UP MOVB R0,(R2) ; AND REPLACE 8$: CMPB (R2),#'9 ;BIGGER THAN A NINE? BLE 9$ ; NO ROUND UP DONE MOVB #'0,(R2) ;MAKE THIS A ZERO AND INCB -(R2) ; PROPAGATE CARRY, WHILE BACKING SOB R4,8$ ; UP PTR; DO THE WHOLE STRING 9$: MOV R1,R4 ;CALCULATE NR CHARS IN BUFFER SUB SP,R4 MOV 10.+BSIZ(SP),R1 ;R1 -> FILE VARIABLE MOV 14.+BSIZ(SP),R0 SUB R4,R0 ;COMPUTE PAD COUNT TST SIGN ;AND POSSIBLE SIGN BEQ 10$ DEC R0 10$: MOV #' ,R2 JSR PC,P$FPAD ;PAD WITH BLANKS MOV SP,R3 ;START OF BUFFER TST SIGN BEQ 11$ ;SIGN? MOVB #'-,@(R1) ;YES.. WRITE IT OUT MOV #1,R0 JSR PC,P$FPUT 11$: SUB NRDIG,R4 ;COMPUTE LENGTH OF INTEGER PART BLE 12$ ;NONE JSR PC,$$ODIG ;WRITE OUTTHE STING OF DIGITS 12$: MOVB #56,@(R1) ;PUT OUT '.' MOV #1,R0 JSR PC,P$FPUT MOV NRDIG,R4 DEC R4 ;ACCOUNT FOR EXTRA DIGIT BLE 13$ ;THERE IS NO FRACTIONAL PART JSR PC,$$ODIG ;OUTPUT FRACTIONAL PART 13$: ADD #BSIZ,SP RTS PC .PAGE ; ; $$ODIG: WRITE OUT A STRING OF DIGITS ; REGISTER USAGE ; R1: POINTER TO FILE BLOCK ; R0: SCRATCH ; R3: @BUFFER ; R4: BUFFER LENGTH ; $$ODIG:: MOVB (R3)+,@(R1) MOV #1,R0 JSR PC,P$FPUT SOB R4,$$ODIG RTS PC ; NOISE = 37114 ;LARGEST WORD LESS THAN 0.05 BSIZ = 40. ;MAX NR DIGITS BEFORE DECIMAL POINT +1 ONE = 40200 ; 1.0 TEN = 41040 ; 10.0 TENTH: 37314,146314,146314,146315; 1.0/10. TO 64 BITS .PSECT $VARBL ;PUT VARIABLES IN A SEPARATE CSECT SIGN: 0 ;FLAG FOR PRESENCE OF MINUS SIGN ON OUTPUT NRDIG: 0 ;LOCAL STORAGE FOR NUMBER OF DIGITS IN FRACTION .END