.ENABL LC .TITLE FRG - DISK FRAGMENTATION .IDENT /M1/ ; ; DATE: 7/12/77 ; BY: D. MICHAUD ; BORG INSTRUMENTS ; DELAVAN WISCONSIN ; ; MODIFIED: 6/15/78 BY GREG THOMPSON ; - CHANGED IT TO DOUBLE PRECISION ; - MODIFIED THE ERROR MESSAGES ; - ALLOWED UNIT NUMBER 0 AS A DEFAULT ; - ADDED LARGEST FREE BLOCK OUTPUT ; - LOWER CASED THE OUTPUT ; - CHANGED THE HOLE RANGES ; - ALLOWED NON-PRIV USER TO USE IT ; - BUILD IT /PR:0 SINCE IT DOESN'T REFERENCE EXEC ; ; JGD01 -- IF FRAG STARTED VIA A RUN $FRAG, PROMPT FOR INPUT ; USING QIO'S RATHER THAN CSI1/CSI2. THIS RESULTS IN ; A MUCH SMALLER FASTER TASK. ADD MORE BINS AT LOW ; END AND RESTRUCTURE BIN SIZING. ; ; THIS MCR TASK WILL PRODUCE FRAGMENTATION STATISTICS FOR THE SPECIFIED ; FILES-11 DEVICE. THE OUTPUT IS A FREQUENCY COUNT OF CONTIGUOUS FREE ; BLOCKS (HOLES) FALLING WITHIN EACH OF SEVERAL RANGES, THE TOTAL NUMBER ; OF BLOCKS FOR EACH RANGE, AND THE TOTAL NUMBER OF FREE BLOCKS FOR THE ; DEVICE. ; ; OUTPUT IS DIRECTED TO LUN 2, WHICH MAY BE ASSIGNED TO ANY TERMINAL. ; ERROR MESSAGES ARE DIRECTED TO LUN 5. ; .NLIST MEB,BEX .MCALL GTIM$,QIOW$,CALL,EXIT$S,DIR$,GLUN$ .MCALL FCSMC$,TCBDF$,UCBDF$,ALUN$,GMCR$ FCSMC$ ; DEFIN FCS MACROS TCBDF$ ; DEFINE TCB OFFSETS UCBDF$ ; DEFINE UCB OFFSETS FSRSZ$ 0 ; NO FSR FOR BLOCK OPERATIONS FDB: FDBDF$ FDRC$A FD.RWM FDBK$A INBUF,512.,,10 FDOP$A 1,DSET DSET: .WORD 0,0 .WORD UICSIZ,UIC .WORD NAMSIZ,NAME UIC: .ASCII /[0,0]/ UICSIZ=.-UIC .EVEN NAME: .ASCII /BITMAP.SYS/ NAMSIZ=.-NAME .EVEN INBUF: .BLKB 512. ALUN: ALUN$ 1,DK,0 ; DUMMY ASSIGN LUN GMCR: GMCR$ ; BUF=GMCR+2 ; BUF OVERLAYS COMMAND LINE BUFFER TIME: GTIM$ BUF READ: QIOW$ IO.RVB,1,10,,IOST,, DPB: QIOW$ IO.WVB,5,1,,,, IDPB: QIOW$ IO.RVB,5,1,,IOSB,, ; ; JGD01 IOSB: .BLKW 2 ; I/O STATUS BLOCK ; JGD01 GLUN: GLUN$ 1,GBUF ; TO SEE IF DEVICE IS F11 DEVICE GBUF: .BLKW 6. ; BLOCK: .WORD 1 ; BLOCK COUNTER FOR QIO ; BLOCK 1 IS NOT PART OF BIT MAP, ; SO WILL START READING AT BLOCK 2 TOTAL: .WORD 0,0 LARGST: .WORD 0,0 ; LARGEST BLOCK SEEN COUNTB: .WORD 0,0 IOST: .BLKW 2 BINS: .WORD 5.,15.,30.,50.,75.,100.,200.,300.,600.,1000.,2000. BSIZ=11. ; NUMBER OF BINS - THE BIGGEST (< 2000. ) BIN: .BLKW *2 ;HOLDS FREQUENCY COUNT FOR EACH BIN BINSUM: .BLKW *2 ; HOLDS #BLOCKS FOR EACH BIN ISTRNG: .ASCII <11><11>/DISK FRAGMENTATION STATISTICS FOR / ASCDEV: .ASCII /DK0:/ .ASCII /%2N/<11><11><11>/%Y/<11>/%3Z/ .ASCII /%2N/<11><11>/CONTIGUOUS FREE BLOCKS (HOLES)/ .ASCII /%2NHOLE RANGE/<11>/FREQUENCY/<11>/NUMBER OF BLOCKS/ .ASCII /%N 1 - 5/<11>/%T/<11><11>/%T/ .ASCII /%N 6 - 15/<11>/%T/<11><11>/%T/ .ASCII /%N 16 - 30/<11>/%T/<11><11>/%T/ .ASCII /%N 31 - 50/<11>/%T/<11><11>/%T/ .ASCII /%N 51 - 75/<11>/%T/<11><11>/%T/ .ASCII /%N 76 - 100/<11>/%T/<11><11>/%T/ .ASCII /%N 101 - 200/<11>/%T/<11><11>/%T/ .ASCII /%N 201 - 300/<11>/%T/<11><11>/%T/ .ASCII /%N 301 - 600/<11>/%T/<11><11>/%T/ .ASCII /%N 601 - 1000/<11>/%T/<11><11>/%T/ .ASCII /%N1001 - 2000/<11>/%T/<11><11>/%T/ .ASCII /%N >2001/<11>/%T/<11><11>/%T/ .ASCII /%2N/<11>/LARGEST FREE BLOCK/<11>/%T/ .ASCIZ /%N/<11>/TOTAL FREE BLOCKS /<11>/%T/ .EVEN ER1: .ASCII /FRG -- NO COMMAND LINE/ ER1SIZ=.-ER1 .EVEN ER2: .ASCII /FRG -- FAILURE ON READING BITMAP.SYS/ ER2SIZ=.-ER2 .EVEN ER3: .ASCII /FRG -- DEVICE NAME MISSING/ ER3SIZ=.-ER3 .EVEN ER4: .ASCII /FRG -- ILLEGAL DEVICE/ ER4SIZ=.-ER4 FRG: .ASCII /FRG>/ FRGSIZ=.-FRG .EVEN .PAGE ERROR1: MOV #ER1,DPB+Q.IOPL ; GET ERROR STRING ; JGD01 MOV #ER1SIZ,DPB+Q.IOPL+2 ; GET SIZE ; JGD01 JMP OUT ; PRINT MESSAGE AND EXIT ; JGD01 ; ERROR3: MOV #ER3,DPB+Q.IOPL ; GET ERROR STRING MOV #ER3SIZ,DPB+Q.IOPL+2 ; GET SIZE JMP OUT ; ERROR4: MOV #ER4,DPB+Q.IOPL ; GET ERROR STRING MOV #ER4SIZ,DPB+Q.IOPL+2 ; GET SIZE JMP OUT ;+ ; ** FRAG - DISPLAY FRAGMENTATION DATA FOR FILES-11 DEVICES ; ; SYNTAX: ; FRG DDN: ; ; WHERE: ; DD - A LEGAL FILES-11 DEVICE NAME ; N - A LEGAL UNIT NUMBER < 8 ;- FRAG: DIR$ #GMCR ; GET COMMAND LINE BCC FRAG1 ; OK, HAVE COMMAND LINE ; JGD01 CALL GETLIN ; NO COMMAND LINE, TRY AND GET ONE ; JGD01 BCS ERROR1 ; SOMEHOW COULDN'T READ A COMMAND LINE ; JGD01 ; FRAG1: MOV #BUF+3,R0 ; COMMAND LINE ; JGD01 CMPB #' ,(R0)+ ; STRICT SYNTAX-MUST BE SPACE BNE ERROR3 ; MOV (R0),ALUN+A.LUNA MOVB (R0)+,ASCDEV ; MOVB (R0)+,ASCDEV+1 ; GET DEVICE NAME FOR OUTPUT CMPB (R0),#': ; DID HE LEAVE OFF NUMBER? BNE 7$ ; NO MOVB #'0,(R0) ; YES, PUT THE ZERO THERE FOR HIM 7$: MOVB (R0),ASCDEV+2 ; AND DEV NUMBER BIC #177770,(R0) ; STRIP ASCII MOV (R0),ALUN+A.LUNU ; DEV NUM FOR ALUN$ DIR$ #ALUN ; ASSIGN INPUT DEVICE BCS ERROR4 ; CS= ILLEGAL DEVICE DIR$ #GLUN ; SEE IF DEVICE IS A DISK BCS ERROR4 ; NO, MUST BE ILLEGAL IF CANT GET INFO BIT #40000,G.LUCW+GBUF ; IS IT A MOUNTABLE FILES-11 DEVICE? BEQ ERROR4 ; NO ; OPEN$R #FDB,,,,,,ERROR2 RECORD: INC BLOCK MOV BLOCK,READ+Q.IOPL+10 ; SET FOR NEXT BLOCK DIR$ #READ ; READ A BLOCK TSTB IOST ; DONE? BLT ERR ; LT=MAYBE MOV #INBUF,R0 ; GET RECORD BUFFER BLOCKS: MOV (R0)+,R1 ; GET 1ST 16 BLOCKS BEQ FULL ; EQ= ALL USED CMP R1,#-1 ; ALL FREE? BNE COUNT ; NE=NOT ALL FREE ADD #16.,COUNTB+2 ; COUNT 16 FREE BLOCKS ADC COUNTB ; HANDLE HIGH PART TOO BR END ; SEE IF DONE ; COUNT: MOV #16.,R2 ; BIT SHIFT COUNTER SHIFT: ASR R1 ; CHECK A BLOCK BCC FULL ; CC= A USED BLOCK ADD #1,COUNTB+2 ; COUNT A BLOCK FREE ADC COUNTB ; HANDLE HIGH PART BR ENDLP ; SEE IF DONE ; FULL: TST COUNTB ; ANY FREE BLOCKS? BNE 2$ ; YES TST COUNTB+2 ; CHECK LOWER PART BEQ ENDLP ; EQ = NONE FREE 2$: MOV #BSIZ,R4 ; NUMBER OF BINS CLR R3 ; CLEAR BIN POINTER CMP COUNTB,LARGST ; IS IT A NEW LARGEST BLOCK? BLO 5$ ; NO BHI 3$ ; YES CMP COUNTB+2,LARGST+2 ; MAYBE, COMPARE LOWER PARTS BLOS 5$ ; NO 3$: MOV COUNTB,LARGST ; YES, SAVE ITS SIZE MOV COUNTB+2,LARGST+2 ; 5$: TST COUNTB ; IF HIGH PART NON ZERO IT IS BIG! BNE 7$ ; IE TOO BIG FOR ALL BUT LAST BUCKET CMP COUNTB+2,BINS(R3) ; MORE THAN THIS BIN? BLOS 10$ ; LOS=NOPE 7$: ADD #2,R3 ; POINT TO NEXT BIN SOB R4,5$ ; CHECK NEXT BIN ; 10$: ADD COUNTB,TOTAL ; ACCUMULATE TOTAL ADD COUNTB+2,TOTAL+2 ; ADC TOTAL ; ASL R3 ; MAKE OFFSET INTO 2 WORD BLOCKS ADD COUNTB,BINSUM(R3) ; ACC TOTAL FOR EACH BIN ADD COUNTB+2,BINSUM+2(R3) ; ADC BINSUM(R3) ; ADD #1,BIN+2(R3) ; INCREMENT BIN ADC BIN(R3) ; CLR COUNTB ; CLEAR COUNTER CLR COUNTB+2 ; ENDLP: TST R1 ; ANY FREE BLOCKS STILL? BEQ END SOB R2,SHIFT ; CHECK ANOTHER BLOCK ; END: CMP R0,#ALUN ; READ ANOTHER DISK BLOCK? BHIS RECORD ; HIS=YES BR BLOCKS ; NO,LOOK AT ANOTHER 16 BITS ; ERR: CMPB #IE.EOF,IOST ; END OF FILE? BNE ERROR2 ; NE=OOPS! BR FINISH ; WRITE STATISTICS ; ERROR2: MOV #ER2,DPB+Q.IOPL ; GET ERROR STRING MOV #ER2SIZ,DPB+Q.IOPL+2 ; GET SIZE BR OUT ; FINISH: DIR$ #TIME ; GET TIME/DATE MOV #BSIZ+1,R0 ; # OF BINS MOV #BUF+14,R2 ; START OF NUMBERS MOV #BIN,R5 ; GET FREQUENCY BUFFER MOV #BINSUM,R4 ; GET SUBTOTALS BUFFER 10$: MOV R5,(R2)+ ; TRANSFER A FREQUENCY ADD #4,R5 ; MOV R4,(R2)+ ; TRANSFER A SUBTOTAL ADD #4,R4 ; SOB R0,10$ ; GET ANOTHER MOV #LARGST,(R2)+ ; LARGEST BLOCK FOUND MOV #TOTAL,(R2)+ ; TOTAL FREE BLOCKS MOV #BUF,R2 ; GET ARGUEMENTS MOV #INBUF,R0 ; GET NEW OUTPUT STRING BUFFER MOV #ISTRNG,R1 ; GET ASCIZ STRING CALL $EDMSG ; EDIT STRING SUB #INBUF,R0 ; GET SIZE MOV #INBUF,DPB+Q.IOPL ; GET STRING INTO DPB MOV R0,DPB+Q.IOPL+2 ; GET SIZE INTO DPB MOV #2,DPB+Q.IOLU ; USE LUN 2 OUT: CLOSE$ #FDB ; CLOSE THE FILE DIR$ #DPB EXIT$S ;+ ; JGD01 ; *** - INPUT - READ A LINE FROM TERMINAL ; JGD01 ; ; JGD01 ; INPUT: ; JGD01 ; R0 - BUFFER ADDRESS ; JGD01 ; R1 - LENGTH TO READ ; JGD01 ; ; JGD01 ; OUTPUT: ; JGD01 ; R0 - BUFFER ADDRESS ; JGD01 ;- ; JGD01 INPUT: MOV #IDPB,R4 ; GET INPUT DPB ADDRESS ; JGD01 DIR$ R4 ; ISSUE QIO ; JGD01 BCS 10$ ; WE HAVE AN ERROR, SO GIVE UP ; JGD01 CMP IOSB+2,#0 ; IF ONLY WE HAVE CMD LINE ERROR ; JGD01 BGT 5$ ; IS OK, CONTINUE ; JGD01 JMP ERROR1 ; ELSE WARN USER ; JGD01 5$: MOV R0,R1 ; GET BUFFER ADDRESS ; JGD01 ADD IOSB+2,R1 ; ADD NUMBER OF CHARACTERS READ ; JGD01 MOVB IOSB+1,(R1) ; STORE TERMINATOR ; JGD01 10$: RETURN ; JGD01 ;+ ; JGD01 ; TRY AND GET AN MCR COMMAND LINE ; JGD01 ; AND SIMULATE THE FRG>DEV: SYNTAX ; JGD01 ;- ; JGD01 GETLIN: MOV #FRG,DPB+Q.IOPL ; GET PROMPT STRING ; JGD01 MOV #FRGSIZ,DPB+Q.IOPL+2 ; GET LENGTH ; JGD01 MOV #44,DPB+Q.IOPL+4 ; SET FOR PROMPTING OUTPUT ; JGD01 DIR$ #DPB ; OUTPUT A 'FRG>' ; JGD01 MOV #40,DPB+Q.IOPL+4 ; RETURN NORMAL CARRIAGE CONTROL ; JGD01 CALL INPUT ; GET AN INPUT LINE ; JGD01 BCC 10$ ; ALL OK, CONTINUE ; JGD01 JMP ERROR1 ; READ FAILED, COMMAND ERRROR? ; JGD01 10$: MOV #BUF+3,R0 ; SET (BUF+3) TO SPACE ; JGD01 MOVB #' ,(R0) ; BECAUSE SYNTAX IS STRICT ; JGD01 RETURN ; OK, GO HOME ; JGD01 .END FRAG