	.TITLE	BIGCONTIG - SUBROUTINE TO FIND LARGEST CONTIGUOUS SPACE ON DISK
	.IDENT	/1.0/

;*****************************************************************
;
; 	AUTHOR:	DEC - CSC/CS
;
;	MOD:	ROGER JENKINS
;	DATE:	11/6/86
;	DESCR:	CHANGED INTO A SUBROUTINE
;
; THIS SUBROUTINE WILL FIND THE LARGEST NUMBER OF CONTIGUOUS BLOCKS
; ON A DISK.  
;
; NOTE: SINCE THIS PROGRAM JUST FINDS OUT HOW MUCH FREE SPACE THERE IS AND
; DOESN'T ACTUALLY ALLOCATE THE SPACE, IT IS POSSIBLE THAT SOMEONE COULD 
; ALLOCATE THE SPACE BETWEEN THE TIME YOU MEASURE IT AND ACTUALLY TRY TO
; USE IT.
;
; THE CALLING PARAMETERS ARE:
;
; CALLING FORMAT:
;	BIGCONTIG disk, blocks [,status] 
;
; RETURNS:  STATUS IN R0
;
; ARGUMENTS:
;   disk
;	TYPE:      CHARACTER STRING
;	ACCESS:    READ ONLY
;	MECHANISM: BY DESCRIPTOR
;	THE NAME OF THE DISK ON WHICH THE LARGEST CONTIGUOUS SECTION 
;	WILL BE FOUND.
;
;   blocks
;	TYPE:      LONGWORD INTEGER (SIGNED)
;	ACCESS:    WRITE ONLY
;	MECHANISM: BY REFERENCE
;	THE LARGEST NUMBER OF CONTIGUOUS BLOCKS ON THE DISK.  SET TO ZERO
;	IF AN ERROR OCCURS.
;
;   status
;	TYPE:      LONGWORD INTEGER (SIGNED)
;	ACCESS:    WRITE ONLY
;	MECHANISM: BY REFERENCE
;	STATUS RETURNED FROM QIO IF LARGEST NUMBER OF CONTIGUOUS BLOCKS COULD
;	NOT BE DETERMINED.
;
;*****************************************************************

        .LIBRARY        /SYS$LIBRARY:LIB/
        $DVIDEF
        $FIBDEF
        $FATDEF
        $FCHDEF
        $ATRDEF


	.PAGE
;*****************************************************************
;
; DATA LOCAL TO SUBROUTINE
;
;*****************************************************************

        .PSECT        DATA, NOEXE, WRT, RD, PIC

NAME_OF_FILE:.ASCID /                                                       /

CHANNEL:
        .WORD   0                       ; Channel store
IOSB:   .QUAD   0

ITMLST:                                 ; Getdvi Item list
        .WORD   4                       ; 4 bytes of data
        .WORD   DVI$_MAXBLOCK           ; Maximum number of blocks
        .ADDRESS MAXBLOCK               ; Fill in the largest
                                        ; Space on disk
        .LONG   0                       ; No need for return length
        .LONG   0                       ; End of list

MAXBLOCK:
        .LONG   0                       ; Hold Maxblocks here
FIBDESC:
       .LONG    FIB$C_LENGTH
       .ADDRESS FIB

FIB:
       .BLKB    FIB$C_LENGTH

FILEATTR:
       .WORD    ATR$S_RECATTR           ; File Attributes list
       .WORD    ATR$C_RECATTR
       .ADDRESS ATTRIBUTES
UCHAR:                                  ; Characteristics of the file
       .WORD    ATR$S_UCHAR
       .WORD    ATR$C_UCHAR
       .ADDRESS CHARACTERISTICS
       .LONG    0                       ; End of list

ATTRIBUTES:
       .BYTE    0                       ; Fill by bit pushing
       .BYTE    FAT$M_NOSPAN
       .WORD    0                       ; Variable length records
       .QUAD    0                       ; Fill area
       .LONG    0                       ; Fill area No relation to Fixed
                                        ;  records
       .WORD    512                     ; Maximum record size
       .WORD    0                       ; Default Extent quantity
       .WORD    0                       ; Global Buffer Count
       .BLKB    6                       ; 6 spare bytes
       .WORD    0                       ; Version limit (directory only)
CHARACTERISTICS:
       .LONG    0                       ; A contiguous file

FILENAME:
       .ASCID   /BIG_CONTIG_$_BIG_CONTIG.TEMPORARY;1/

NPARAMS:
	.BLKL	1			; NUMBER OF PARAMETERS

DISK:	.BLKL	2			; DESCRIPTOR OF DISK NAME


	.PAGE
;*****************************************************************
;
; CODE
;
;*****************************************************************

       .PSECT   CODE, EXE, NOWRT
       .ENTRY   BIGCONTIG, ^M<>


;*****************************************************************
;
; GET PARAMETERS
;
;*****************************************************************

	MOVL	(AP)+,NPARAMS		; GET NUMBER OF PARAMETERS
	MOVQ	@(AP)+,DISK		; GET DISK DESCRIPTOR


;*****************************************************************
;
; ASSIGN I/O CHANNEL.
; GET DEVICE CHARACTERISTICS.
;
;*****************************************************************

	$ASSIGN_S  DEVNAM=DISK, -	; Get the channel to the disk
		   CHAN=CHANNEL
	BLBS	R0,GETDVI		; BRANCH IF NO ERROR
	BRW	ERROR			; BRANCH IF ERROR

GETDVI:
	$GETDVI_S  CHAN=CHANNEL, -	; Get the device info
		   ITMLST=ITMLST
	BLBS	R0,FIL_FIB		; BRANCH IF NO ERROR
	BRW	ERROR			; BRANCH IF ERROR


;*****************************************************************
;
; FILL IN FIB AND FAT CONTROL BLOCKS
;
;*****************************************************************

FIL_FIB:
	MOVL	#^X40004, -
		FIB+FIB$W_DID		; Fill the Directory ID

	MOVL	#FIB$M_WRITETHRU, -     ; Write File Header to disk
		FIB+FIB$L_ACCTL

	INSV	#FAT$C_VARIABLE, -      ; Set the Record type
		#FAT$V_RTYPE, -
		#FAT$S_RTYPE, -
		ATTRIBUTES

	INSV	#FAT$C_SEQUENTIAL, -    ; Sequential records
		#FAT$V_FILEORG, -
		#FAT$S_FILEORG, -
		ATTRIBUTES
                                        ; Specify a contiguous file
	MOVL	#FCH$M_CONTIG!FCH$M_NOBACKUP!FCH$M_MARKDEL, -
		CHARACTERISTICS

	MOVL	MAXBLOCK, FIB+FIB$L_EXSZ

	MOVW	#FIB$M_EXTEND!FIB$M_ALCON!FIB$M_ALCONB!FIB$M_FILCON!FIB$M_ALDEF, -
		FIB+FIB$W_EXCTL

	MOVL	#FIB$M_WRITETHRU, FIB+FIB$L_ACCTL


;*****************************************************************
;
; TRY TO CREATE LARGEST FILE POSSIBLE ON THE DISK.
; WE WILL ONLY GET THE LARGEST CONTIGUOUS PIECE AVAILABLE.
;
;*****************************************************************

	$QIOW_S	CHAN=CHANNEL, -         ; Access the file/Create
		FUNC=#IO$_CREATE!IO$M_CREATE!IO$M_EXTEND, -
		IOSB=IOSB, -            ; Check Create status
		P1=FIBDESC, -           ; Address of FIB
		P2=#FILENAME, -         ; Address of Filename
		P3=#NAME_OF_FILE,-
		P4=#NAME_OF_FILE,-
		P5=#FILEATTR            ; File Attributes

	BLBC	R0,ERROR		; QIO DIRECTIVE ERROR
	BLBS	IOSB,RETURN_SIZE	; BRANCH IF NO I/O ERROR
	CMPW	#SS$_DEVICEFULL, IOSB	; DEVICE FULL ERROR?
	BEQL	RETURN_SIZE		; THAT IS OK TOO.
	MOVZWL	IOSB, R0		; PUT STATUS IN R0
	BRW	ERROR			; RETURN WITH ERROR STATUS


;*****************************************************************
;
; RETURN FILE SIZE
;
;*****************************************************************

RETURN_SIZE:

	MOVL	IOSB+4,@(AP)+			; RETURN LARGEST BLOCK SIZE


;*****************************************************************
;
; DELETE THE FILE THAT WE CREATED
;
;*****************************************************************

	$QIOW_S	CHAN=CHANNEL, -
		FUNC=#IO$_DELETE!IO$M_DELETE, -
		IOSB=IOSB,-
		P1=FIBDESC,-
		P2=#NAME_OF_FILE

	MOVZWL	IOSB,-(SP)			; SAVE THE DELETE STATUS
	$DASSGN_S  CHAN=CHANNEL			; DEASSIGN THE CHANNEL
	POPR	#^M<R0>				; RESTORE DELETE STATUS
	BRB	EXIT				; RETURN TO CALLER


;*****************************************************************
;
; ERROR PROCESSING
;
;*****************************************************************

ERROR:
	CLRL	@(AP)+				; RETURN "NO BLOCKS"
	
EXIT:
	CMPL	#3,NPARAMS			; DO WE HAVE 3 PARAMETERS?
	BGTR	RETURN				; NO - DON'T RETURN STATUS
	MOVL	R0,@(AP)+			; YES - RETURN STATUS
RETURN:
	RET					; RETURN TO CALLER
	.END
