.TITLE PWEXP - WRITE SHORT EXPONENTIAL .IDENT /790822/ ; PARMS ; 1. POINTER TO FILE BLOCK ; 2. REAL VALUE ; 3. FIELD WIDTH ; REGISTER USAGE ; R1: @FILEBLOCK, @BUFFER ; R0: SCRATCH ; R2: SCRATCH ; R3: @BUFFER, SCRATCH ; R4: SCRATCH ; CALLS: P$FPUT,$$$098(TRUNC),$$$201(FLOAT) ; .GLOBL P$FPUT,$$$098,$$$201 $$$041:: $$$043:: MOV 8.(SP),R1 ;SWAP @FILEVAR MOV (SP),8.(SP) ; WITH THE RETURN ADDRESS MOV R1,(SP) MOV R2,-(SP) ;SAVE R2 MOV R3,-(SP) ;SAVE R3 MOV R4,-(SP) ;SAVE R4 MOV SP,R3 ;R3 -> END OF BUFFER+1 SUB #BSIZ,SP ;MAKE ROOM FOR BUFFER IN STACK MOV SP,R1 ;R1 -> START OF BUFFER SUB #10,SP MOV 22+BSIZ(SP),4(SP) MOV 24+BSIZ(SP),6(SP) CLR R2 ;CLEAR EXPONENT CLR SIGN ;ASSUME > 0.0 TST 4(SP) BGT 1$ ;IF > 0.0 BEQ 3$ ;IF = 0.0 BIC #100000,4(SP) ;R<0.0 MAKE IT POSITIVE INC SIGN ;MAKE < 0.0 1$: MOV 6(SP),2(SP) ;SAVE NUMBER FOR LATER MOV 4(SP),(SP) CLR -(SP) MOV #ONE,-(SP) ;IS NUMBER < 1.0 FSUB SP TST (SP) BLT 2$ ;YES, NUMBER < 1.0 INC R2 ;NO, INCREMENT EXPONENT MOV 6(SP),-(SP) ;DIVIDE NUMBER BY 10 MOV 6(SP),-(SP) MOV #146315,-(SP) MOV #37314,-(SP) FMUL SP MOV (SP)+,6(SP) MOV (SP)+,6(SP) BR 1$ ;CONTINUE LOOP 2$: MOV 6(SP),2(SP) ;SAVE NUMBER FOR LATER MOV 4(SP),(SP) MOV #146315,-(SP) MOV #37314,-(SP) ;IS NUMBER >= 0.1 FSUB SP TST (SP) BGE 3$ ;YES, NUMBER >= 0.1 DEC R2 ;NO, DECREMENT EXPONENT MOV 6(SP),-(SP) MOV 6(SP),-(SP) CLR -(SP) MOV #TEN,-(SP) ;MULTIPLY NUMBER BY 10 FMUL SP MOV (SP)+,6(SP) MOV (SP)+,6(SP) BR 2$ ;CONTINUE LOOP 3$: MOV R2,EXP ;SAVE EXPONENT MOV 20+BSIZ(SP),R4 ;GET FIELDWIDTH FROM STACK SUB #7,R4 ;IS IT > 7 BGT 4$ ;YES MOV #7,R4 ;NO, SET IT TO DEFAULT (7) 4$: INC R4 ;ALLOW FOR EXTRA DIGIT MOV R4,NRDIG ;SAVE NUMBER OF DIGITS IN FRACTION 5$: MOV 6(SP),-(SP) MOV 6(SP),-(SP) CLR -(SP) MOV #TEN,-(SP) FMUL SP CLR -(SP) MOV 4(SP),-(SP) MOV 4(SP),-(SP) JSR PC,$$$098 MOV (SP),R0 MOV (SP),-(SP) MOV (SP),-(SP) JSR PC,$$$201 FSUB SP MOV (SP)+,6(SP) MOV (SP)+,6(SP) ADD #'0,R0 ;CONVERT DIGIT TO CHARACTER MOVB R0,(R1)+ ;PUT DIGIT INTO BUFFER SOB R4,5$ ;ANY DIGITS LEFT ADD #10,SP MOV R1,R2 ;SAVE CURRENT DIGIT POINTER DEC R2 ;SHOULD POINT AT LAST DIGIT MOV NRDIG,R4 ;GET NUMBER OF DIGITS MOVB (R2),R1 ;GET LAST (EXTRA) DIGIT ADD #5,R1 ;ROUND IT UP MOVB R1,(R2) ;PUT IT BACK IN THE BUFFER 6$: CMPB (R2),#'9 ;DIGIT > 9? BLE 7$ ;NO, ROUNDING UP IS DONE MOVB #'0,(R2) ;MAKE DIGIT A ZERO INCB -(R2) ;AND PROPAGATE CARRY, WHILE BACKING UP SOB R4,6$ ;PTR, CONTINUE FOR WHOLE STRING 7$: MOV NRDIG,R4 ;GET NUMBER OF DIGITS MOV 6+BSIZ(SP),R1 ;GET FILE VARIABLE MOVB #' ,@(R1) ;PRINT THE MOV #1,R0 ;(ONE CHARACTER) JSR PC,P$FPUT ;LEADING BLANK TST SIGN ;IS THE NUMBER NEGATIVE BEQ 8$ ;IF NO, THEN MOVB #'-,@(R1) ;PRINT A '-' BR 9$ ;ELSE 8$: MOVB #' ,@(R1) ;PRINT A ' ' 9$: MOV #1,R0 ;(ONE CHARACTER) JSR PC,P$FPUT ;PRINT THE SIGN CHARACTER MOV SP,R3 ;R3 -> START OF BUFFER MOVB (R3)+,@(R1) ;GET THE FIRST DIGIT MOV #1,R0 ;(ONE CHARACTER) JSR PC,P$FPUT ;AND PRINT IT DEC R4 ;DECREMENT COUNT OF NUMBER OF DIGITS MOVB #'.,@(R1) ;PRINT A '.' MOV #1,R0 ;(ONE CHARACTER) JSR PC,P$FPUT ;IN FRONT OF THE NUMBER DEC R4 ;DON'T PRINT EXTRA DIGIT TST R4 ;CHECK TO SEE IF WE ARE TO PRINT BLE 13$ ;A FRACTIONAL PART 10$: MOVB (R3)+,@(R1) ;GET DIGIT MOV #1,R0 ;(ONE CHARACTER) JSR PC,P$FPUT ;PRINT CHARACTER SOB R4,10$ ;CONTINUE FOR ALL DIGITS 13$: MOVB #'E,@(R1) ;PRINT THE 'E' MOV #1,R0 ;(ONE CHARACTER) JSR PC,P$FPUT ;NEXT MOV EXP,R4 ;GET EXPONENT DEC R4 ;ACCOUNT FOR DIGIT BEFORE THE '.' BLT 11$ ;IS EXPONENT NEGATIVE MOVB #'+,@(R1) ;NO, '+' SIGN TO BE PRINTED BR 12$ ;ELSE 11$: MOVB #'-,@(R1) ;'-' SIGN TO BE PRINTED NEG R4 ;MAKE EXPONENT POSITIVE 12$: MOV #1,R0 ;(ONE CHARACTER) JSR PC,P$FPUT ;PRINT THE SIGN OF THE EXPONENT MOV R4,R3 ;SAVE EXPONENT FOR LATER CLR R2 ;GET FIRST DIGIT DIV #10.,R2 ;OF EXPONENT ADD #'0,R2 ;CONVERT IT TO CHARACTER MOVB R2,@(R1) ;PRINT THE FIRST MOV #1,R0 ;(ONE CHARACTER) JSR PC,P$FPUT ;DIGIT OF THE EXPONENT SUB #'0,R2 ;CONVERT THE FIRST DIGIT BACK TO INTEGER MOV R2,R3 ;PREPARE FOR MULTIPLY MUL #10,R3 ;GET THE SECOND SUB R3,R4 ;DIGIT OF THE EXPONENT ADD #'0,R4 ;CONVERT IT TO CHARACTER MOVB R4,@(R1) ;PRINT THE SECOND MOV #1,R0 ;(ONE CHARACTER) JSR PC,P$FPUT ;DIGIT OF THE EXPONENT ADD #BSIZ,SP ;ERASE THE BUFFER MOV (SP)+,R4 ;RESTORE R4 MOV (SP)+,R3 ;RESTORE R3 MOV (SP)+,R2 ;RESTORE R2 ADD #10,SP RTS PC ;RETURN BSIZ = 40. ONE = 40200 TEN = 41040 .PSECT $VARBL SIGN: .WORD 0 NRDIG: .WORD 0 EXP: .WORD 0 .END