; CONTIG.M68 -- Counts the number of free blocks and maximum number of
; contiguous free blocks on a disk.

; Mike Vandeman, Synanon Church
; May 31, 1983

; 06/05/84 Largely rewritten by Tom Dahlquist to make it 1) device
; independent, and 2) reentrant.

; 10/24/86 Bug fixed by Irwin Goldstein.  The bit map is read & tested in
; word units instead of longwords, because for some devices (most notably
; a 400 MB drive formatted to 13 logicals) where the bitmap does not use
; up all of the last longword, CONTIG was giving too many blocks free.
; (The LSR instruction was starting with the unused portion of the last
; longword.  This is probably due in part to the way the AM100/L swaps
; words around.)

; Usage: CONTIG devn:

       SEARCH  SYS
       SEARCH  SYSSYM
       RADIX   10                      ;use decimal arithmetic

;       Workspace map

       DSECT
DDB:    BLKB    D.DDB
MAXCNT: LWORD   0
WRKSIZ=.

       PSECT
       PHDR    -1,PV$RSM,PH$REU!PH$REE ;set program header

;       A0 -> work area throughout this code.

CONTIG: GETIMP  WRKSIZ,A0               ; get required memory and
       CLEAR   @A0,WRKSIZ              ; clear it.
       BYP                             ;find first non-blank character
       FSPEC   @A0                     ; get device specification...
       TST     D.FIL(A0)               ; no file name allowed...
       JNE     ERROR                   ; die if one given.
       INIT    @A0
       MOV     #2,D.REC(A0)            ;enter physical record # in DDB (start with 2)
       MOV     D.DVR(A0),A1            ; A1 -> device driver
       MOV     ^O24(A1),D0             ; D0 = # of blocks on device

;       Throughout the  rest of the code the following register assignments
;       are used:
;       A2:  -> next word to be read from current bitmap block
;       D0:  decremented counter of total # of blocks on disk
;       D1:  total # of free blocks
;       D2:  counter of # of contig blocks in current area
;       D3:  decremented counter of words in current bitmap block
;       D4:  decremented counter of bits in current word
;       D5:  current word

       CLR     D1                      ; clear total free block counter and
       CLR     D2                      ; current contig space counter.

LOOP1:  READ    @A0                     ;read disk block
       MOV     D.BUF(A0),A2            ;get address of buffer
       MOV     #255,D3                 ;# of words to be tested (-1)

LOOP2:  MOVW    (A2)+,D5                ;get next word to be tested
       MOV     #15,D4                  ;# of bits to be tested (-1)

LOOP3:  LSRW    D5,#1                   ;get bit to test
       BCS     ONE                     ;one?
       INC     D1                      ;increment # of free blocks
       INC     D2                      ;increment # of contiguous free blocks
       BR      NXTBIT

ONE:    CMP     D2,MAXCNT(A0)           ;new high for contig ?
       BLOS    1$                      ;no
       MOV     D2,MAXCNT(A0)           ;yes, save it
1$:     CLR     D2                      ;start counting again

NXTBIT: DEC     D0
       BEQ     DONE
       DBF     D4,LOOP3                ;loop to next bit
       DBF     D3,LOOP2                ;loop to the next longword
       CTRLC   EXIT                    ;let me out on a ^C
       INC     D.REC(A0)               ; go get next block of bitmap...
       BR      LOOP1

DONE:   CMP     D2,MAXCNT(A0)           ;new high for contig ?
       BLOS    TYPE                    ;no
       MOV     D2,MAXCNT(A0)           ;yes, save it

TYPE:   TYPESP  <Total free blocks:>            ;display # of free blocks
       DCVT    0,OT$TRM
       CRLF
       TYPESP  <Largest contiguous space:>     ;display # contig free blocks
       MOV     MAXCNT(A0),D1
       DCVT    0,OT$TRM
       CRLF

EXIT:   EXIT

ERROR:  TYPECR  <?Syntax is:  CONTIG devn:>
       EXIT

       EVEN
       END