;
FRAG.MAR DISK_FRAGMENTATION_STATISTICS
.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