.TITLE VLFREE .IDENT /V01/ .ENABL LC ;+ ; VLFREE ATTEMPTS TO CALCULATE THE PERCENTAGE OF ALLOCATED ; SPACE ON A MOUNTED VOLUME, ALONG WITH THE TOTAL FREE BLOCK ; SPACE ON THE VOLUME, AND PRINT IT OUT TO THE TERMINAL. ; ; IF THE VOLUME IS NOT MOUNTED, OR IS MARKED FOR DISMOUNT, ; VLFREE PRINTS A DIAGNOSTIC AND JUMPS TO GLOBAL LABEL ; ERREX (SO SYSTEM LISTS CAN BE UNLOCKED). ; ; IF THE DEVICE IS MOUNTED WITH THE /NOPUB OPTION IN EFFECT, ; A WARNING MESSAGE IS PRINTED, UNLESS THE DEVICE IS ALLOCATED ; TO THE TI: WHICH HAS ISSUED THE CWD/PWD COMMAND. ; ; NOTE: IF THE UNIT IS FOUND TO HAVE ONE OR MORE OF THE ; FOLLOWING CHARACERISTICS, THEN NO FREE SPACE INFORMATION ; IS CALCULATED, AND THE CW.UFD BIT IN $FLAG IS CLEARED SO ; THAT NO UFD SEARCH IS INITIATED: ; ; 1. IF THE UNIT IS SEQUENTIAL (I.E., A TAPE) ; 2. IF THE MOUNTED UNIT IS NOT FILES-11 STRUCTURED ; 3. IF THE UNIT IS A COMMUNICATIONS CHANNEL ; 4. IF THE UNIT IS A SINGLE DIRECTORY DEVICE ; ; INPUTS: ; VLUCB -- GLOBAL POINTER TO UCB OF VOLUME'S UNIT ; ; OUTPUTS: NONE ; ; ALL REGISTERS ARE DESTRYED BY THIS ROUTINE. ;- .MCALL ERROR,PRINT,PMSG .MCALL UCBDF$,F11DF$ UCBDF$ ; DEFINE UCB OFFSETS F11DF$ ; DEFINE VCB OFFSETS SPACE = <' > ; ASCII SPACE .PSECT TOTSAV: .WORD 0,0 ; TOTAL VOLUME CAPACITY DOUBLEWORD FBLK: .WORD 0,0 ; FREE BLOCK SPACE DOUBLEWORD .NLIST BEX VMFMS: .ASCII /DDN: is / VMPCT: .ASCII / NN.N% full (/ VMSTF: .BLKB 9. VMAP: .ASCIZ /. blocks free)/ .LIST BEX .ENABL LSB .PSECT VLFREE .PAGE ;+ ; ATTACH TEMPORARY LUN TO OUR NEW SY: AND GET FREE BLOCKS ON IT ;- VLFREE:: MOV VLUCB,R4 ; POINT TO UCB OF DEVICE MOV U.CW1(R4),R5 ; GET DEVICE CHARACTERISTICS BIT #DV.MNT,R5 ; DEVICE MOUNTABLE? BNE 10$ ; YES, SKIP AHEAD ERROR < CWD -- Device not mountable>,ERREX,VLFREE,0 10$: MOVB U.STS(R4),R1 ; GET FIRST STATUS BYTE BIT #US.MNT,R1 ; IS DEVICE MOUNTED? BEQ 20$ ; YES ERROR < CWD -- Device is not mounted>,ERREX,VLFREE,0 20$: BIT #US.MDM,R1 ; MARKED FOR DISMOUNT? BEQ 30$ ; NO ERROR < CWD -- Device is marked for dismount>,ERREX,VLFREE,0 30$: BITB #US.PUB,U.ST2(R4) ; IS DEVICE PUBLIC? BNE 40$ ; YES CMP U.OWN(R4),TIUCB ; NO, BUT DO WE OWN IT? BEQ 40$ ; YES, DON'T PRINT WARNING PRINT < CWD -- Device is unavailable for public use>,VLFREE,0 40$: BIT #DV.F11,R5 ; MOUNTED AS FILES-11? BEQ 410$ ; NO, BAIL OUT BIT #,R5 ; IF DEVICE IS SINGLE DIRECTORY, ; SEQUENTIAL, OR COM CHANNEL BEQ 480$ ; 410$: BIC #CW.UFD,$FLAG ; THEN STOP HERE - NO UFD SEARCH BR VLRET ; AND GO RETURN 480$: BIT #CW.FRE,$FLAG ; DO WE SHOW FREE SPACE? BEQ VLRET ; NO, JUST RETURN MOV #PWDBLK,R0 ; POINT TO PHYSICAL DEVICE NAME MOV #VMFMS,R1 ; POINT TO WHERE WE STUFF IT 50$: MOVB (R0)+,(R1) ; MOVE A BYTE OF IT CMPB #<':>,(R1)+ ; MOVED ALL OF IT YET? BNE 50$ ; NOT YET... MOV #TOTSAV,R5 ; POINT TO CAPACITY SAVE AREA MOV U.CW2(R4),(R5) ; STORE HIGH ORDER CAPACITY MOV U.CW3(R4),2(R5) ; STORE LOW ORDER MOV U.VCB(R4),R2 ; POINT TO VOLUME CONTROL BLOCK MOV #FBLK,R1 ; POINT TO FREE SPACE STUFF AREA MOV R1,R4 ; SAVE THE POINTER MOVB V.FRBK(R2),(R1) ; GET HIGH ORDER OF FREE BLOCKS MOV V.LRUC+1(R2),2(R1) ; GET LOW ORDER COUNT MOV #VMSTF,R0 ; GET ADDRESS FOR CONVERSION CLR R2 ; SUPPRESS LEADING ZEROS CALL $CDDMG ; CONVERT DOUBLE TO ASCII DECIMAL MOV #VMAP,R1 ; POINT TO STRING TO APPEND 60$: MOVB (R1)+,(R0)+ ; COPY INTO MESSAGE BNE 60$ ; UNTIL AT END OF STRING DEC R0 ; POINT BACK TO LAST CHAR SUB #VMFMS,R0 ; GET LENGTH OF MESSAGE MOV R0,-(SP) ; SAVE FOR NOW .PAGE MOV (R5),R1 ; GET HIGH ORDER CAPACITY MOV 2(R5),R0 ; GET LOW ORDER SUB 2(R4),R0 ; GET LOW ORDER ALLOCATED BLOCKS BCC 70$ ; SKIP AHEAD IF NO BORROW OUT DEC R1 ; ELSE BORROW A BIT 70$: SUB (R4),R1 ; GET HIGH ORDER ALLOCATED BLOCKS MOV R1,(R4) ; STORE BACK INTO SAVE AREA MOV R0,2(R4) ; STORE BACK LOW ORDER MOV #VMPCT,R3 ; POINT TO OUTPUT STUFF AREA CALL PERCNT ; CALCULATE PERCENTAGE MOV #VMFMS,R0 ; GET STARTING ADDRESS TO PRINT MOV (SP)+,R1 ; RECOVER MESSAGE LENGTH PMSG ,,#SPACE,0 ; PRINT MESSAGE VLRET: RETURN .DSABL LSB .PAGE ; ; THIS ROUTINE WILL RIGHT JUSTIFY THE TIME POINTED TO BY R0 ; INTO THE FOLLOWING FORMAT IN A FIELD 6 CHARACTERS WIDE: ; ; XX.X% ; ; INPUTS: ; R3 = ADDR OF OUTPUT BUFFER ; R4 = ADDR OF HIGH ORDER PORTION ; R5 = ADDR OF HIGH ORDER TOTAL ; ; OUTPUTS: ; R0, R1, R2 DESTROYED ; R3, R4, R5 PRESERVED ; PCTSIZ=6 ; FIELD WIDTH FOR PERCENTS ; PERCNT: MOV R3,-(SP) ; SAVE BUFFER ADDRESS MOV (R4),R2 ; GET HIGH ORDER NUMBER MOV 2(R4),R3 ; GET LOW ORDER MOV #1000.,R0 ; GET SCALE FACTOR CALL $DMUL ; AND MULTIPLY MOV R1,R2 ; GET THE INFO WHERE IT BELONGS MOV R0,R1 ; BMI 240$ ; IF < 0 , THEN AN OVERFLOW OCCURED MOV 2(R5),R0 ; GET LOW ORDER TOTAL TIME MOV (R5),-(SP) ; PUT HIGH ORDER ON THE STACK 200$: TST (SP) ; IS THERE ANY HIGH ORDER TIME LEFT? BNE 210$ ; YES. CONTINUE SCALING TST R0 ; IS THE LOW ORDER UNSIGNED YET? BPL 220$ ; YES. DO IT! 210$: ASR R1 ; DIVIDE HIGH ORDER BY 2 ROR R2 ; AND CONTINUE WITH LOW ORDER ASR (SP) ; SHIFT HIGH ORDER TOTAL ALSO ROR R0 ; AND LOW ORDER BR 200$ ; DO THE TEST. 220$: MOV R0,(SP) ; POP STACK AND SAVE DIVISOR CALL $DDIV ; DO D.P. DIVIDE MOV R2,R1 ; GET RESULT (PERCENT * 10.) MOV (SP)+,R2 ; POP DIVISOR FOR ROUNDOFF ASR R2 ; DIVIDE BY 2 CMP R2,R0 ; COMPARE WITH THE REMAINDER BGT 230$ ; ROUND UP RESULT? INC R1 ; IF LE, REMAINDER IS BIG ENOUGH 230$: CLR R2 ; SUPPRESS ZEROES MOV (SP)+,R3 ; RESTORE OUTPUT BUFFER POINTER MOV R3,R0 ; COPY FOR CALL CALL $CBDMG ; CONVERT TO ASCII MOVB -(R0),1(R0) ; MOVE LAST BYTE OVER TO MAKE ROOM MOVB #'.,(R0)+ ; PUT IN A DECIMAL POINT INC R0 ; STEP PAST LAST NUMBER MOVB #'%,(R0)+ ; MAKE IT A PERCENT MOV #PCTSIZ,R1 ; LOAD FIELD WIDTH CALL JUSTFY ; RIGHT JUSTIFY PERCENT RETURN ; AND RETURN 240$: MOV (SP)+,R3 ; POP BUFFER ADDRESS MOV #PCTSIZ,R1 ; GET FIELD WIDTH ADD R1,R3 ; SLIDE BUFF POINTER OVER 250$: MOVB #'*,-(R3) ; FILL WITH ASTERISKS SOB R1,250$ ; UNTIL DONE RETURN ; AND CONTINUE ;+ ; JUSTFY -- RIGHT JUSTIFY BUFFER CONTENTS TO FIELD WIDTH ; ; INPUTS: ; ; R0 = ADDR OF NEXT AVAILABLE BYTE IN BUFFER ; R1 = FIELD WIDTH ; R3 = ADDR OF START OF BUFFER ; ; OUTPUTS: ; ; R0, R1, R2 DESTROYED ; R3, R4, R5 PRESERVED ;- JUSTFY: MOV R0,R2 ; CALCULATE NUMBER OF SUB R3,R2 ; CHARACTERS TO MOVE OVER CMP R1,R2 ; FORGET IT IF THE FIELD BEQ 280$ ; IS FULL ADD R1,R3 ; POINT PAST LAST BYTE IN FIELD 260$: MOVB -(R0),-(R3) ; AND COPY THEM IN REVERSE DEC R1 ; THIS WILL BE THE REMAINDER SOB R2,260$ ; UNTIL DONE MOVB #SPACE,R2 ; FOR SPEED 270$: MOVB R2,-(R3) ; FILL IN LEADING BLANKS SOB R1,270$ ; UNTIL R3 IS BACK WHERE IT WAS 280$: RETURN ; AND RETURN .END