.TITLE READ_BITMAP ; ; This program will read the storage bitmap file into an extension of ; process virtual address space. it will then look at the string as ; one long bit string. The GET_FREE_BLOCKS function will return ; either a -1, or the number of continguos bits which represent ; available disk space. This will serve as an indicator of ; fragmentation of a disk volume. ; ; SYMBOLIC DEFINITIONS ; $FABDEF $RABDEF .PSECT DATA PIC,NOEXE,LONG .ALIGN LONG INFAB: $FAB ;FAB FOR BITMAP FILE INRAB: $RAB FAB=INFAB,UBF=BUFFER,- USZ=512 ;RAB FOR BITMAP FILE BUFFER: .BLKB 512 ;BUFFER FOR READ OF 1ST BITMAP BLOCK FILNAM: .BLKB 80 ;STORAGE FOR BITMAP FILE SPEC LENGTH: .BLKL 1 ;COPY OF DEVICE NAME STRING LENGTH NAME: .ASCII /[0,0]BITMAP.SYS/ ;FILE SPEC FOR BITMAP SIZE=.-NAME ;SIZE OF NAME STRING CLUSTER:.BLKL 1 ;FOR VOLUME CLUSTER SIZE MAXBLCK:.BLKQ 1 ;FOR MAX LOG BLOCK NUMBER REM: .BLKL 1 ;COUNTERS BITS: .LONG 4096 ;BITS IN ONE BLOCK BYTES4: .BLKL 1 BLOCKS: .BLKL 1 ;BLOCKS IN BITMAP FILE VIRTUAL:.BLKL 1 ;CONTAINS EXTENSION OF VAS BIT_POS:.BLKL 1 FREE1: .BLKL 1 ;FIRST FREE BLOCK NUMBER FREE2: .BLKL 1 ;END OF FREE BLOCK RANGE RANGE: .BLKL 1 ;NUMBER OF FREE BLOCKS IN THIS RANGE .PSECT CODE PIC,NOWRT,LONG .ENTRY OPEN_BITMAP, ^M ;ENTRY MASK MOVAL @4(AP), R6 ;Pickup Adr of file name string arg. MOVZWL (R6), LENGTH ;SET DEVICE NAME SIZE IN LONGWORD addl2 #4, r6 movl (r6), r6 MOVC3 LENGTH,(R6),FILNAM ;SET DEVICE NAME IN BUFFER MOVAB FILNAM,R6 ;GET ADDRESS OF BUFFER ADDL2 LENGTH,R6 ;ADD LENGTH JUST PUT IN THE BUFFER MOVC3 #SIZE,NAME,(R6) ;SET FILE SPEC IN BUFFER MOVAB FILNAM,INFAB+FAB$L_FNA ;SET FILE NAME STRING ADDB3 LENGTH, #SIZE,- INFAB+FAB$B_FNS ;SET FILE NAME STRING SIZE $OPEN FAB=INFAB ;OPEN THE BITMAP FILE BLBS R0,10$ ;CHECK STATUS BRW END_OPEN 10$: $CONNECT RAB=INRAB ;CONNECT RECORD STREAM BLBS R0,20$ ;CHECK STATUS BRW END_OPEN 20$: $GET RAB=INRAB ;READ IN THE FIRST BLOCK MOVZWL BUFFER+2,CLUSTER ;GET CLUSTER FACTOR MOVL BUFFER+4, MAXBLCK ;GET VOLUME SIZE ; CALCULATIONS THAT MUST BE MADE BEFORE READING THE ACTUAL BITMAP ; ; CLUSTERS-ON-DISK= MAXBLK / CLUSTER_SIZE (NUMBER OF BITS IN BITMAP) ; BLOCKS-IN-BITMAP= MAXBLK / 4096 (BITS IN ONE BLOCK) ; BYTES NEEDED = BLOCKS * 512 (BYTES IN ONE BLOCK) ; DIVL2 CLUSTER,MAXBLCK ;NUMBER OF CLUSTERS (BITS IN BITMAP) EDIV BITS,MAXBLCK,BLOCKS,REM;FIGURE OUT NUMBER OF BLOCKS IN FILE TSTL REM ;WAS THERE A REMAINDER FROM THE DIVIDE? BEQL NO_REM ;BRANCH IF NO REMAINDER INCL BLOCKS ;IF SO, ROUND BLOCK COUNT UP NO_REM: MULL3 #512,BLOCKS,BYTES4 ;NUMBER OF BYTES NEEDED ; NOW ALLOCATED VIRTUAL MEMORY TO WRITE THE CONTENTS OF THE REST ; OF THE BITMAP, SO WE WON'T BE TYING UP THE FILE ; PUSHAL VIRTUAL ;GET ADDITIONAL BYTES FOR BITMAP BLOCKS PUSHAL BYTES4 ;BYTES NEEDED CALLS #2,G^LIB$GET_VM BLBS R0,10$ ;CHECK STATUS BRW END_OPEN 10$: MOVL VIRTUAL,INRAB+RAB$L_UBF ;SET ADDRESS OF NEW USER BUFFER MOVL BLOCKS,R11 ;SET NUMBER OF BLOCKS TO COPY LOOP: $GET RAB=INRAB ;COPY BITMAP BLOCK TO VIRT MEMORY MOVL R11,RANGE ADDL2 #512,INRAB+RAB$L_UBF ;SET NEXT BLOCK POINTER DECL R11 tstl R11 ;COPIED ALL BLOCKS ? BGTR LOOP ;COPIED ALL BLOCKS ? CLRL BIT_POS $CLOSE FAB=INFAB ;YES, CLOSE BITMAP FILE end_open: movl r0, @8(ap) RET ; .entry get_free_blocks, ^M MOVL VIRTUAL,R11 ;SET ADDRESS OF VIRT MEMORY MULL3 #4096,BLOCKS,BITS ;TOTAL BITS TO READ MOVL BIT_POS, R8 ;USE R8 AS POINTER REGISTER FFS_LOOP: FFS R8,#32,(R11),R8 ;LOOK FOR 1ST SET BIT, PUT INTO R8 BNEQ FFS_LOOP_EXIT ;BRANCH WHEN WE FIND ONE SET CMPL MAXBLCK,R8 ;HAVE WE READ ALL BITS YET ? BLEQ END_GET ;YES, EXIT OUT OF HERE BRB FFS_LOOP FFS_LOOP_EXIT: MULL3 CLUSTER,R8,FREE1 ;GET LOGICAL BLOCK NUMBER OF FREE BLOCK FFC_LOOP: FFC R8,#32,(R11),R8 ;NO, FIND CLEAR BIT (ALLOCATED BLOCK) BNEQ FFC_LOOP_EXIT ;BRANCH WHEN WE FIND ONE CMPL MAXBLCK,R8 ;HAVE WE READ ALL BITS YET ? BLEQ END_GET ;YES, EXIT OUT OF HERE BRB FFC_LOOP FFC_LOOP_EXIT: MULL3 CLUSTER,R8,FREE2 ;GET LOGICAL BLOCK NUMBER OF ALLOC BLK SUBL3 FREE1,FREE2,RANGE ;GET THE NUMBER OF BLOCKS IN THIS RANGE BRB DONE ;YES, EXIT OUT OF HERE END_GET:MNEGL #1, RANGE DONE: MOVL RANGE, R0 MOVL R8, BIT_POS RET .END