.TITLE DISK_FRAGMENTATION_STATISTICS .SUBTITLE DECLARE CONSTANTS AND MACROS .ENABLE DEBUG ; DISK FRAGMENTATION DISPLAY PROGRAM ; MICHAEL N. LEVINE ; CODE 3514 ; NAVAL WEAPONS CENTER ; CHINA LAKE ; CA ; (619)939-2465 AVN 437-2465 $DVIDEF $DCDEF ; MACRO TO CONVERT A LONG WORD BINARY NUMBER TO AN UNSIGNED INTEGER STRING .MACRO GENSTR SIZE,LOC,VAR MOVL SIZE,DESCRIPTER MOVAL LOC,DESCRIPTER+4 $FAO_S CTRSTR,,DESCRIPTER,VAR .ENDM .MACRO GENPCT VAR,LOC,DIVISOR,MULT,?AAA,?BBB,?CCC,?DDD,?EEE CVTLD VAR,TEMP BEQL DDD MULD2 TEN_K,TEMP .IF NB MULT CVTLD MULT,TEMP_2 MULD2 TEMP_2,TEMP .ENDC CVTLD DIVISOR,TEMP_2 BNEQ EEE CLRF TEMP BRB DDD EEE: DIVD2 TEMP_2,TEMP ADDD2 HALF,TEMP DDD: CVTDL TEMP,TEMP MOVL #5,DESCRIPTER MOVAL LOC,DESCRIPTER+4 $FAO_S CTRSTR_2,,DESCRIPTER,TEMP MOVC3 #2,LOC+3,LOC+4 MOVB #^A/./,LOC+3 CMPB #^A/ /,LOC+5 BNEQ AAA MOVB #^A/0/,LOC+5 AAA: CMPB #^A/ /,LOC+4 BNEQ BBB MOVB #^A/0/,LOC+4 BBB: CMPB #^A/ /,LOC+2 BNEQ CCC MOVB #^A/0/,LOC+2 CCC: .ENDM ; MACRO TO PRINT OUT A STRING .MACRO PUTSTR SIZE,LOC MOVL SIZE,DESCRIPTER MOVAL LOC,DESCRIPTER+4 CALLG OUTPUT_ARG,G^LIB$PUT_OUTPUT .ENDM .PAGE .SUBTITLE DATA STORAGE .PSECT PURE_DATA,RD,NOWRT,SHR,NOEXE,LONG,GBL,CON ; ; ARGUMENT LIST FOR ERROR MESSAGE THAT SELECTED DEVICE IS NOT A DISK ; NOT_DISK_ARG: .LONG 1 .ADDRESS NOT_DISK_STRING NOT_DISK_STRING: .ASCID /Specified device is not a disk/ ; ; ARGUMENT LIST FOR LIB$GET_FOREIGN ; GET_ARG: .LONG 4 .ADDRESS DEVICE_NAME .ADDRESS PROMPT .ADDRESS LENGTH .ADDRESS FORCE PROMPT: .ASCID /Device ? / ; ; Unable to flush bitmap message ; NO_FLUSH: .ASCID /Unable to flush bitmap-useing old data/ ; ; ITEM LIST FOR THE $GETDVI CALL ; ITEM_LIST: .WORD 4,DVI$_CLUSTER .ADDRESS CLUSTER_SIZE .LONG 0 .WORD 4,DVI$_DEVCLASS .ADDRESS CLASS .LONG 0 .WORD 4,DVI$_MAXBLOCK .ADDRESS MAXBLOCK .LONG 0 .WORD 4,DVI$_FREEBLOCKS .ADDRESS FREE .LONG 0 .LONG 0 ; ; LIST OF BOUNDRY VALUES FOR BUCKETS. THE FIRST MUST BE "1" AND THE ; LAST "-1", TO CHANGE THE BUCKET BOUNDRY VALUES AND NUMBER OF BUCKETS, ; JUST CHANGE THE LIST BELOW. THE PROGRAM IS WRITTEN TO TAKE CARE ; OF THE DETAILS.-- THE LIST MUST BE MONOTONICALLY INCREASING. ; BUCKET_SIZE_LIST: .LONG 1,5,10,25,50,75,100,250,500,750,1000,2500,5000,7500 .LONG 10000,25000,50000,75000,100000,250000,500000,750000 .LONG 1000000,2500000,5000000,7500000,10000000 .LONG -1 NUMBER_OF_BUCKETS = <<<.-BUCKET_SIZE_LIST>/4>-1> ; ; MAP THE BITS IN EACH 32 BIT WORD ; BIT_MAP:.LONG ^X1,^X2,^X4,^X8,^X10,^X20,^X40,^X80,^X100,^X200,^X400,^X800 .LONG ^X1000,^X2000,^X4000,^X8000,^X10000,^X20000,^X40000,^X80000 .LONG ^X100000,^X200000,^X400000,^X800000 .LONG ^X1000000,^X2000000,^X4000000,^X8000000 .LONG ^X10000000,^X20000000,^X40000000,^X80000000 ; ; STATISTICS CONSTANTS ; TEN_K: .DOUBLE 10000.0 HALF: .DOUBLE 0.5 ; ; Argument list for LIB$GET_COMMAND to see if next disspla is wanted ; NEXT_DISSPLA_ARG: .LONG 3 .ADDRESS YES_NO .ADDRESS P_PROMPT .ADDRESS YES_NO_LENGTH P_PROMPT: .ASCID !Do you want the distribution display (Y/N) [N] ? ! ; ; Plotting dispatch table ; PLOT_DISPATCH_TABLE: .ADDRESS PLT_5+11 .ADDRESS PLT_10+11 .ADDRESS PLT_15+11 .ADDRESS PLT_20+11 .ADDRESS PLT_25+11 .ADDRESS PLT_30+11 .ADDRESS PLT_35+11 .ADDRESS PLT_40+11 .ADDRESS PLT_45+11 .ADDRESS PLT_50+11 .ADDRESS PLT_55+11 .ADDRESS PLT_60+11 .ADDRESS PLT_65+11 .ADDRESS PLT_70+11 .ADDRESS PLT_75+11 .ADDRESS PLT_80+11 .ADDRESS PLT_85+11 .ADDRESS PLT_90+11 .ADDRESS PLT_95+11 .ADDRESS PLT_100+11 .PAGE .PSECT IMPURE_DATA,RD,WRT,NOSHR,NOEXE,QUAD,GBL,CON ; ; ARGUMENT LIST FOR LIB$PUT_OUTPUT ; OUTPUT_ARG: .LONG 1,DESCRIPTER ; ; FORMAT LIST FOR $FAO_S ; CTRSTR: .ASCID /!10UL/ CTRSTR_2:.ASCID /!5UL/ ; ; GENERIC STRING DESCRIPTER ; DESCRIPTER: .LONG 0,0 ; ; ASSORTED TEXT LINES AWAITING INSERTION OF INTEGER STRINGS FOR OUTPUT ; LINE_1: .ASCII /Disk size in blocks / LINE_1_DATA: .ASCII / / LINE_2: .ASCII /Number of free blocks / LINE_2_DATA: .ASCII / / LINE_3: .ASCII /Cluster size in blocks / LINE_3_DATA: .ASCII / / LINE_4: .ASCII /Largest free space in clusters / LINE_4_DATA: .ASCII / / LINE_9: .ASCII /Fragmentation factor (0-100%) / LINE_9_A:.ASCII / % / LINE_5: .ASCII / / LINE_6: .ASCII /Free area size in clusters Count of Total / .ASCII / % Disk % Free/ LINE_6_A:.ASCII / Fragments Clusters/ .ASCII / Space Space / LINE_7: .ASCII / -/ LINE_7_B:.ASCII / / LINE_7_A: .ASCII / (/ LINE_7_C:.ASCII ? /? LINE_7_D:.ASCII ? %/? LINE_7_E:.ASCII / %)/ LINE_8: .ASCII / Total / LINE_8_A:.ASCII / (/ LINE_8_B:.ASCII ? /? LINE_8_C:.ASCII ? %/? LINE_8_D:.ASCII / %)/ ; ; BUCKETS FOR COUNT OF NUMBER OF FRAGMENTS OF IN GIVEN SIZE RANGE ; BUCKET_BRIGADE: .BLKL NUMBER_OF_BUCKETS ; ; TOTAL NUMBER OF CLUSTERS IN A GIVEN BUCKET AND TOTAL FOUND (LAST SLOT) ; TOTALS: .BLKL NUMBER_OF_BUCKETS+1 ; ; TOTAL NUMBER OF FRAGMENTS FOUND ; TOTAL_FRAGS: .LONG 0 ; ; TEMPORARY STORAGE ; TEMP: .LONG 0,0 TEMP_2: .LONG 0,0 ; ; LAST BLOCK NUMBER IN SYS$DISK:[000000]BITMAP.SYS READ IN ; BLOCK_NUMBER: .LONG 0 .ALIGN QUAD ; ; BIT MAP BLOCK ; BLOCK: .BLKB 512 ; ; LONGEST FRAGMENT FOUND ; LONGEST:.LONG 0 ; ; WHAT DOES THE SYSTEM SAY THE NUMBER OF FREE BLOCKS IS ; FREE: .LONG 0 ; ; DISK SIZE IN BLOCKS ; MAXBLOCK: .LONG 0 ; ; WHAT TYPE OF DEVICE IS THIS (SHOULD BE A DISK) ; CLASS: .LONG 0 ; ; GET DISK CLUSTER SIZE ; CLUSTER_SIZE: .LONG 0 FRAGMENTATION_FACTOR: .LONG 0 ; ; FORCE THE PROMPT IF NO DEVICE SPECIFIED ON COMMAND LINE ; FORCE: .LONG 0 ; ; LENGTH OF INPUT STRING ; LENGTH: .LONG 0 ; ; SPECIFIED DEVICE STRING STORED HERE ; DEVICE_NAME: .ASCID / / ; ; IO STATUS BLOCK ; IOSB: .LONG 0,0 ; ; THIS IS THE FILE WANTED FOR THE BIT MAP ; DEFAULT_NAME: .ASCII /SYS$DISK:[000000]BITMAP.SYS/ DFLT_NAM_SIZ=.-DEFAULT_NAME ; ; DEFINE THE FAB AND RAB FORTHE BIT MAP FILE ; .ALIGN LONG FAB_1: $FAB ALQ=0,- DEQ=0,- DNA=DEFAULT_NAME,DNS=DFLT_NAM_SIZ,- FAC=,- FNA=,FNS=0,- SHR= .ALIGN LONG RAB_1: $RAB BKT=1,- FAB=FAB_1,- ROP=,- UBF=BLOCK,USZ=512 .ALIGN LONG FAB_2: $FAB ALQ=0,- DEQ=0,- DNA=DEFAULT_NAME,DNS=DFLT_NAM_SIZ,- FAC=,- FNA=,FNS=0,- FOP=,SHR= .ALIGN LONG RAB_2: $RAB BKT=1,- FAB=FAB_2,- ROP=,- UBF=BLOCK,USZ=512 ; ; Input for distribution dissplay ; YES_NO: .ASCID / / YES_NO_LENGTH: .LONG 0 ; ; Terminal dissplay for distribution-build up area ; .ASCID / Free fragment size (% of largest fragment) vs starting LBN (% of disk size)/ PLT_100:.ASCII / 100% + / PLT_100_LEN=.-PLT_100 PLT_95: .ASCII / | / PLT_95_LEN=.-PLT_95 PLT_90: .ASCII /F o | / PLT_90_LEN=.-PLT_90 PLT_85: .ASCII /r f | / PLT_85_LEN=.-PLT_85 PLT_80: .ASCII /e 80% + / PLT_80_LEN=.-PLT_80 PLT_75: .ASCII /e l | / PLT_75_LEN=.-PLT_75 PLT_70: .ASCII / a | / PLT_70_LEN=.-PLT_70 PLT_65: .ASCII /f r | / PLT_65_LEN=.-PLT_65 PLT_60: .ASCII /r g 60% + / PLT_60_LEN=.-PLT_60 PLT_55: .ASCII /a e | / PLT_55_LEN=.-PLT_55 PLT_50: .ASCII /g s | / PLT_50_LEN=.-PLT_50 PLT_45: .ASCII / t | / PLT_45_LEN=.-PLT_45 PLT_40: .ASCII /s 40% + / PLT_40_LEN=.-PLT_40 PLT_35: .ASCII /i f | / PLT_35_LEN=.-PLT_35 PLT_30: .ASCII /z r | / PLT_30_LEN=.-PLT_30 PLT_25: .ASCII /e a | / PLT_25_LEN=.-PLT_25 PLT_20: .ASCII /| g 20% + / PLT_20_LEN=.-PLT_20 PLT_15: .ASCII /% | / PLT_15_LEN=.-PLT_15 PLT_10: .ASCII / | / PLT_10_LEN=.-PLT_10 PLT_5: .ASCII / | / PLT_5_LEN=.-PLT_5 PLT_0: .ASCII / 0% +------------------------+------------------------+/ PLT_0_LEN=.-PLT_0 TITLE_2:.ASCID / 0% 50% 100%/ TITLE_3:.ASCID ? Free frag starting location-% (LBN/DISK_SIZE)*100? PLOT_100: .LONG PLT_100_LEN .ADDRESS PLT_100 PLOT_95: .LONG PLT_95_LEN .ADDRESS PLT_95 PLOT_90: .LONG PLT_90_LEN .ADDRESS PLT_90 PLOT_85: .LONG PLT_85_LEN .ADDRESS PLT_85 PLOT_80: .LONG PLT_80_LEN .ADDRESS PLT_80 PLOT_75: .LONG PLT_75_LEN .ADDRESS PLT_75 PLOT_70: .LONG PLT_70_LEN .ADDRESS PLT_70 PLOT_65: .LONG PLT_65_LEN .ADDRESS PLT_65 PLOT_60: .LONG PLT_60_LEN .ADDRESS PLT_60 PLOT_55: .LONG PLT_55_LEN .ADDRESS PLT_55 PLOT_50: .LONG PLT_50_LEN .ADDRESS PLT_50 PLOT_45: .LONG PLT_45_LEN .ADDRESS PLT_45 PLOT_40: .LONG PLT_40_LEN .ADDRESS PLT_40 PLOT_35: .LONG PLT_35_LEN .ADDRESS PLT_35 PLOT_30: .LONG PLT_30_LEN .ADDRESS PLT_30 PLOT_25: .LONG PLT_25_LEN .ADDRESS PLT_25 PLOT_20: .LONG PLT_20_LEN .ADDRESS PLT_20 PLOT_15: .LONG PLT_25_LEN .ADDRESS PLT_15 PLOT_10: .LONG PLT_10_LEN .ADDRESS PLT_10 PLOT_5: .LONG PLT_5_LEN .ADDRESS PLT_5 PLOT_0: .LONG PLT_0_LEN .ADDRESS PLT_0 .PAGE .SUBTITLE CODE .SUBTITLE INITIALIZATION .PSECT CODE,RD,NOWRT,SHR,EXE,LONG,GBL,CON .ENTRY START,0 ; ; GET THE DEVICE NAME ; CALLG GET_ARG,G^LIB$GET_FOREIGN CMPW #SS$_NORMAL,R0 BEQL 1$ $EXIT_S R0 1$: MOVL LENGTH,DEVICE_NAME ; ; GET INFORMATION ON SPECIFIED DEVICE ; $GETDVI_S #1,,DEVICE_NAME,ITEM_LIST,IOSB CMPW #SS$_NORMAL,R0 BEQL 2$ $EXIT_S R0 2$: $WAITFR_S #1 CMPW #SS$_NORMAL,IOSB BEQL 3$ CVTWL IOSB,R0 $EXIT_S R0 ; ; MUST BE A DISK ; 3$: CMPL #DC$_DISK,CLASS BEQL 103$ CALLG NOT_DISK_ARG,G^LIB$PUT_OUTPUT $EXIT_S ; ; OPEN THE BITMAP FILE TWICE ; THE FIRST TIME WITH NOSHARE OPTION TO FORCE THE ; BLOCKS OF THE BITMAP CACHED BY THE ACP TO BE ; WRITTEN OUT, AND THE TIME SECOND WITH SHARE OPTION ; TO ALLOW OHTER PEOPLE TO USE THE DISK ; 103$: MOVB LENGTH,FAB_1+FAB$B_FNS MOVB LENGTH,FAB_2+FAB$B_FNS $OPEN FAB=FAB_1 BLBC R0,4$ $CLOSE FAB=FAB_1 BLBS R0,5$ 4$: CMPL #RMS$_FLK,R0 BEQL 7$ $EXIT_S R0 7$: PUSHAL NO_FLUSH CALLS #1,G^LIB$PUT_OUTPUT 5$: $OPEN FAB=FAB_2 BLBS R0,1004$ $EXIT_S R0 1004$: $CONNECT RAB=RAB_2 BLBS R0,1005$ $EXIT_S R0 1005$: ; ; INIT ALL INTERNAL VARIBALES AND ARRAYS ; CLRL LONGEST MOVC5 #0,LONGEST,#0,#,BUCKET_BRIGADE MOVC5 #0,LONGEST,#0,#<*4>,TOTALS CLRL TOTAL_FRAGS ; ; BIT MAP STARTS IN LBN 2 ; MOVL #2,BLOCK_NUMBER MOVL #2,RAB_1+RAB$L_BKT MOVL #2,RAB_2+RAB$L_BKT ; ; READ IN FIRST BLOCK OF BITMAP AN INIT ALL REGISTERS ; $READ RAB=RAB_2 BLBS R0,6$ $EXIT_S R0 6$: CLRL R11 ;OFFSET INTO BITMAP BLOCK MOVL #32,R8 ;BITS PER WORD CLRL R6 ;OFFSET INTO BIT MASK ARRAY MOVL BLOCK(R11),R9 ;GET FIRST WORD IN BLOCK ADDL2 #4,R11 ;OFFSET TO NEXT WORD NEEDED CLRL R10 ;INIT FRAGMENT SIZE COUNT .PAGE .SUBTITLE ACCUMULATE DATA LOOP: BITL BIT_MAP[R6],R9 ;IS BIT SET SAYING IN USE BEQL NOT_SET ;BIT CLEAR-CLUSTER NO IN USE INCL R10 ;BUMP CLUSTER SIZE COUNT BRW END_LOOP ;GO TO NEXT CLUSTER FOR CHECK NOT_SET: ;BIT NOT SET TSTL R10 ;DOES IT SIGNAL END OF FRAGMENT BEQL END_LOOP ;NO CLRL R7 ;FIND BUCKET TO PUT COUNT IN BUCKET_LOOP: CMPL [R7],R10 ;CMP CLUSTER SIZE TO BUCKET BGTRU 1$ ;FOUND BUCKET BRACKETING SIZE INCL R7 ;NO-SKIP TO NEXT BUCKET BRW BUCKET_LOOP ;AND TEST IT 1$: INCL BUCKET_BRIGADE[R7] ;INC BUCKET COUNT INCL TOTAL_FRAGS ;IN TOTAL FRAGMENT COUNT ADDL2 R10,TOTALS[R7] ;INC BUCKET TOTAL CLUSTERS ADDL2 R10,TOTALS+;INC TOTAL FREE CLUSTERS CMPL R10,LONGEST ;SEE IF THIS LONGEST BLEQ 2$ ;NO MOVL R10,LONGEST ;YES-UPDATE LONGEST 2$: CLRL R10 ;RE-INIT SIZE OF FRAGMENT END_LOOP: INCL R6 ;BUMP BIT MASK POINTER SOBGTR R8,LOOP ;DEC COUNTER AND LOOP IF DONE CMPL #512,R11 ;SEE IF DONE WITH BITMAP BLOCK BGTR 1$ ;NO-SKIP NEXT INCL BLOCK_NUMBER ;SET UP READ OF NEXT BLOCK MOVL BLOCK_NUMBER,RAB_2+RAB$L_BKT $READ RAB=RAB_2 BLBS R0,2$ CMPL #RMS$_EOF,R0 ;WAS ERROR E.O.F BEQL BIT_MAP_IN ;YES-DONE-GO DO PRINTOUT $EXIT_S R0 2$: CLRL R11 ;INIT AS NEEDED FOR NEW BLOCK 1$: MOVL BLOCK(R11),R9 ;GET NEXT WORD AND INIT ADDL2 #4,R11 CLRL R6 MOVL #32,R8 BRW LOOP ;CONTINUE LOOP .PAGE .SUBTITLE CLEAN UP AND GEN OUTPUT BIT_MAP_IN: ;BIT MAP COMPLETLY INPUT TSTL R10 ;SEE IF LAST FRAGMENT IN BEQL CLOSE_DOWN_FILE ;NO-END OF DISK IN USE CLRL R7 ;FIND BUCKET TO PUT IT IN BUCKET_LOOP_2: CMPL [R7],R10 ;COMPARE TO BUCKET LIMITS BGTRU 1$ ;FOUND BUCKET INCL R7 ;CHECK NEXT BUCKET BRW BUCKET_LOOP_2 ;REPEAT TILL DONE 1$: INCL BUCKET_BRIGADE[R7] ;INC BUCKET FRAGMENT COUNT INCL TOTAL_FRAGS ;INC TOTAL FRAGMENT COUNT ADDL2 R10,TOTALS[R7] ;GET BUCKET TOTAL CLUSTERS ADDL2 R10,TOTALS+;GET TOTAL CLUSTERS CMPL R10,LONGEST ;CHECK IF LONGEST BLEQ CLOSE_DOWN_FILE ;NO MOVL R10,LONGEST ;YES-SAY SO CLOSE_DOWN_FILE: $DISCONNECT RAB=RAB_2 ;CLOSE BITMAP FILE $CLOSE FAB=FAB_2 ; ; FORMAT RESULTS FOR OUTPUT ; FIRST PUT OUT THE GENERAL LIST OF DATA ALWAYS DONE ; PLUS FIXED HEADERS ; GENSTR #14,LINE_1_DATA,MAXBLOCK GENSTR #14,LINE_2_DATA,FREE GENSTR #14,LINE_3_DATA,CLUSTER_SIZE GENSTR #14,LINE_4_DATA,LONGEST GENPCT TOTAL_FRAGS,LINE_9_A,> PUTSTR #46,LINE_1 PUTSTR #46,LINE_2 PUTSTR #46,LINE_3 PUTSTR #46,LINE_4 PUTSTR #46,LINE_9 PUTSTR #1,LINE_5 PUTSTR #77,LINE_6 PUTSTR #77,LINE_6_A ; ; INIT LOOP TO OUTPUT COLLECTED BUCKET STATS ; MOVL #NUMBER_OF_BUCKETS,R11 ;GET NUMBER OF BUCKETS CLRL R10 ;OFFSET INTO BUCKET ARRAYS 1$: TSTL BUCKET_BRIGADE[R10] ;SEE IF BUCKET EMPTY BNEQ 4$ ;NOT EMPTY BRW 3$ ;EMPTY-SKIP THIS BUCKET 4$: GENSTR #14,LINE_7,BUCKET_SIZE_LIST[R10];FILL IN BUCKET SIZE LIMITS SUBL3 #1,[R10],R0 GENSTR #14,LINE_7_B,R0 GENSTR #14,LINE_7_A,BUCKET_BRIGADE[R10];FILL IN FRAGMENT COUNT GENSTR #14,LINE_7_C,TOTALS[R10] ;FILL IN CLUSTER COUNT GENPCT TOTALS[R10],LINE_7_D,MAXBLOCK,CLUSTER_SIZE;% OF DISK GENPCT TOTALS[R10],LINE_7_E,>;% OF FREE PUTSTR #78,LINE_7 3$: INCL R10 ;NEXT BUCKET DECL R11 ;DEC COUNTER BLEQ 2$ ;IF DONE BRW 1$ ;NO-LOOP 2$: GENSTR #14,LINE_8_A,TOTAL_FRAGS ;GEN AND OUTPUT DISK TOTALS GENSTR #14,LINE_8_B,TOTALS[R10] GENPCT TOTALS[R10],LINE_8_C,MAXBLOCK,CLUSTER_SIZE GENPCT TOTALS[R10],LINE_8_D,TOTALS[R10] PUTSTR #78,LINE_8 .PAGE .SUBTITLE SEE IF DISTRIBUTION DISPLAY WANTED CLRL YES_NO_LENGTH CALLG NEXT_DISSPLA_ARG,G^LIB$GET_COMMAND TSTL YES_NO_LENGTH BNEQ 10$ $EXIT_S 10$: CMPB #^A/Y/,@YES_NO+4 BEQL 12$ CMPB #^A/y/,@YES_NO+4 BEQL 12$ $EXIT_S 12$: .PAGE .SUBTITLE SET UP FOR RESCAN ; ; Re-open the bitmap file for another scan ; $OPEN FAB=FAB_2 BLBS R0,1004$ $EXIT_S R0 1004$: $CONNECT RAB=RAB_2 BLBS R0,1005$ $EXIT_S R0 1005$: ; ; BIT MAP STARTS IN LBN 2 ; MOVL #2,BLOCK_NUMBER MOVL #2,RAB_1+RAB$L_BKT MOVL #2,RAB_2+RAB$L_BKT ; ; READ IN FIRST BLOCK OF BITMAP AN INIT ALL REGISTERS ; $READ RAB=RAB_2 BLBS R0,6$ $EXIT_S R0 6$: CLRL R11 ;OFFSET INTO BITMAP BLOCK MOVL #32,R8 ;BITS PER WORD CLRL R6 ;OFFSET INTO BIT MASK ARRAY MOVL BLOCK(R11),R9 ;GET FIRST WORD IN BLOCK ADDL2 #4,R11 ;OFFSET TO NEXT WORD NEEDED CLRL R10 ;INIT FRAGMENT SIZE COUNT CLRL R7 ;SET CURRENT LBN VALUE CLRL R5 ;SET STARTING LBN VALUE .PAGE .SUBTITLE ACCUMULATE DATA P_LOOP: BITL BIT_MAP[R6],R9 ;IS BIT SET SAYING IN USE BEQL P_NOT_SET ;BIT CLEAR-CLUSTER IN USE INCL R10 ;BUMP CLUSTER SIZE COUNT INCL R7 ;BUMP LBN COUNTER BRW P_END_LOOP ;GO TO NEXT CLUSTER FOR CHECK P_NOT_SET: ;BIT NOT SET INCL R7 ;BUMP LBN COUNTER TSTL R10 ;DOES IT SIGNAL END OF FRAGMENT BNEQ 6$ BRW PL_END_LOOP ;NO 6$: ; ; CALC SIZE OF LBN IN DISPLAY BUCKETS ; SUBL3 #1,R10,R1 ;GET END LBN OF FREE SPACE MULL2 #100,R1 MULL2 CLUSTER_SIZE,R1 DIVL2 MAXBLOCK,R1 DIVL2 #2,R1 CMPL #49,R1 BGEQ 3$ MOVL #49,R1 3$: INCL R1 ; ; FIRST CALC THE % SIZE OF FREE FRAG/LARGEST FRAG ; MULL2 #100,R10 DIVL2 LONGEST,R10 DIVL2 #5,R10 CMPL #19,R10 BGEQ 1$ MOVL #19,R10 1$: MOVL PLOT_DISPATCH_TABLE[R10],R0 ;GET ADDR OF PLOT LINE ; ; NEXT CALC LOC OF STARTING LBN ; MULL2 #100,R5 MULL2 CLUSTER_SIZE,R5 DIVL2 MAXBLOCK,R5 DIVL2 #2,R5 CMPL #49,R5 BGEQ 2$ MOVL #49,R5 ; ; LOAD LOC WITH MARKER ; 2$: MOVB #^A/X/,(R0)[R5] DECL R1 BLEQ 4$ 5$: INCL R0 MOVB #^A/-/,(R0)[R5] DECL R1 BGTR 5$ MOVB #^A/>/,(R0)[R5] 4$: CLRL R10 PL_END_LOOP: MOVL R7,R5 ;UPDATE STARTING LOC POINTER P_END_LOOP: INCL R6 ;BUMP BIT MASK POINTER DECL R8 BLEQ 3$ BRW P_LOOP ;DEC COUNTER AND LOOP IF DONE 3$: CMPL #512,R11 ;SEE IF DONE WITH BITMAP BLOCK BGTR 1$ ;NO-SKIP NEXT INCL BLOCK_NUMBER ;SET UP READ OF NEXT BLOCK MOVL BLOCK_NUMBER,RAB_2+RAB$L_BKT $READ RAB=RAB_2 BLBS R0,2$ CMPL #RMS$_EOF,R0 ;WAS ERROR E.O.F BEQL P_BIT_MAP_IN ;YES-DONE-GO DO PRINTOUT $EXIT_S R0 2$: CLRL R11 ;INIT AS NEEDED FOR NEW BLOCK 1$: MOVL BLOCK(R11),R9 ;GET NEXT WORD AND INIT ADDL2 #4,R11 CLRL R6 MOVL #32,R8 BRW P_LOOP ;CONTINUE LOOP .PAGE .SUBTITLE CLEAN UP AND GEN OUTPUT P_BIT_MAP_IN: ;BIT MAP COMPLETLY INPUT TSTL R10 ;SEE IF LAST FRAGMENT IN BEQL P_CLOSE_DOWN_FILE ;NO-END OF DISK IN USE ; ; FIRST CALC THE % SIZE OF FREE FRAG/LARGEST FRAG ; MULL2 #100,R10 DIVL2 LONGEST,R10 DIVL2 #5,R10 CMPL #19,R10 BGEQ 1$ MOVL #19,R10 1$: MOVL PLOT_DISPATCH_TABLE[R10],R0 ;GET ADDR OF PLOT LINE ; ; NEXT CALC LOC OF STARTING LBN ; MULL2 #100,R5 MULL2 CLUSTER_SIZE,R5 DIVL2 MAXBLOCK,R5 DIVL2 #2,R5 CMPL #49,R5 BGEQ 2$ MOVL #49,R5 ; ; LOAD LOC WITH MARKER ; 2$: MOVB #^A/X/,(R0)[R5] P_CLOSE_DOWN_FILE: $DISCONNECT RAB=RAB_2 ;CLOSE BITMAP FILE $CLOSE FAB=FAB_2 .PAGE .SUBTITLE OUTPUT DISTRIBUTION PLOT PUSHAL PLOT_100 CALLS #1,G^LIB$PUT_OUTPUT PUSHAL PLOT_95 CALLS #1,G^LIB$PUT_OUTPUT PUSHAL PLOT_90 CALLS #1,G^LIB$PUT_OUTPUT PUSHAL PLOT_85 CALLS #1,G^LIB$PUT_OUTPUT PUSHAL PLOT_80 CALLS #1,G^LIB$PUT_OUTPUT PUSHAL PLOT_75 CALLS #1,G^LIB$PUT_OUTPUT PUSHAL PLOT_70 CALLS #1,G^LIB$PUT_OUTPUT PUSHAL PLOT_65 CALLS #1,G^LIB$PUT_OUTPUT PUSHAL PLOT_60 CALLS #1,G^LIB$PUT_OUTPUT PUSHAL PLOT_55 CALLS #1,G^LIB$PUT_OUTPUT PUSHAL PLOT_50 CALLS #1,G^LIB$PUT_OUTPUT PUSHAL PLOT_45 CALLS #1,G^LIB$PUT_OUTPUT PUSHAL PLOT_40 CALLS #1,G^LIB$PUT_OUTPUT PUSHAL PLOT_35 CALLS #1,G^LIB$PUT_OUTPUT PUSHAL PLOT_30 CALLS #1,G^LIB$PUT_OUTPUT PUSHAL PLOT_25 CALLS #1,G^LIB$PUT_OUTPUT PUSHAL PLOT_20 CALLS #1,G^LIB$PUT_OUTPUT PUSHAL PLOT_15 CALLS #1,G^LIB$PUT_OUTPUT PUSHAL PLOT_10 CALLS #1,G^LIB$PUT_OUTPUT PUSHAL PLOT_5 CALLS #1,G^LIB$PUT_OUTPUT PUSHAL PLOT_0 CALLS #1,G^LIB$PUT_OUTPUT PUSHAL TITLE_2 CALLS #1,G^LIB$PUT_OUTPUT PUSHAL TITLE_3 CALLS #1,G^LIB$PUT_OUTPUT $EXIT_S .END START