From:	SMTP%"Eduard.Vopicka@vse.cz" 20-MAY-1996 14:46:27.68
To:	everhart@star.zko.dec.com (Glenn C. Everhart 603 881 1497)
CC:	
Subj:	Re: Frag version

On May 20, 12:23pm, Glenn C. Everhart 603 881 1497 wrote:
} Subject: Re: Frag version

} No problem with keeping the field test version limited...

OK, here it goes...

Ed

=== BEGIN FRG.MAC ===
	.TITLE	FRG - F11 disk fragmentation
	.SBTTL	Title page
	.IDENT	/M03.09/

	.NLIST	MEB,BEX

M$$EIS	=	0		;Extended Instruction Set supported

;F11MAG	=	113		;Define to turn on check for DECFILE11A

;CKSUMS	=	0		;Define to turn on string checksum checking

; Date:		7/12/77
; By:		D. Michaud
;		Borg Instruments
;		Delavan Wisconsin
;
; Modified 6/15/78 by Greg Thompson
;		- changed it to double precision
;		- modified the error messages
;		- allowed unit number 0 as a default
;		- added largest free block output
;		- lower cased the output
;		- changed the hole ranges
;		- allowed non-priv user to use it
;		- build it /PR:0 since it doesn't reference Exec
;
; Modified for P/OS by R Uleski, Baker Instruments 23-Apr-86
;
; Modified for RSX-11M V4.2 by :
;
;	Eduard Vopicka, Computing centre,
;	Prague School of Economics, Czechoslovakia
;
;	E. Vopicka.	26-Sep-87
;		- improve overhead and make smaller  ( use FILES-11 QIOs
;		  instead of  FCS  OPEN$ / CLOSE$  to  access / deaccess
;		  bitmap file )
;		- build	 /-PR  in order to allow flying install for non-
;		  privileged  users.   This  also  disallows  access  to
;		  volumes not mounted by the user
;		- display statistics for SY0: if device name omitted
;		- allow  omission  of  trailing  collon  in  device name
;		  specification
;		- convert to lower case
;
;	E. Vopicka	07-Dec-87	M03.00
;		- erase  the  entire screen before outputting and change
;		  screen format
;		- added PIP-like display of total, free and in-use
;		  file headers
;		- split single, long terminal QIO into more shorten QIOs
;		- modified to run under RSX-11M-PLUS V3.0 (the high byte
;		  of U.CW2 is possibly non-zero on M+)
;
;	E. Vopicka	12-Dec-87	M03.01
;		- check the volume structure level
;		  (H.VLEV in the home block)
;		- check for valid FILES-11 volume
;		  (H.INDF in the home block)
;
;	E. Vopicka	22-Dec-87	M03.02
;		- do not allow any ZAP changes in ISTRNG
;
;	E. Vopicka	14-Sep-88	M03.03
;		- Fix $DSW to look better after syntax error
;
;	E. Vopicka	10-Apr-90	M03.04
;		- Keep count of bits processed during volume bitmap
;		  processing and stop on end of volume, e.g. do not
;		  process volume bitmap bits describing non-existent
;		  (past end of volume - device size) blocks.
;
;	E. Vopicka	12-Apr-90	M03.05
;		- Modify to use SOB instead of DEC/BNE.
;		- Use CLC/ROR instead of ASR.
;
;	E. Vopicka	24-Apr-91	M03.06
;		- Add /FR switch to produce PIP/FR like output.
;
;	E. Vopicka	27-Apr-91	M03.07
;		- Modify to use EXTTSK or EXTSCT TKB option.
;
;	E. Vopicka	08-Aug-95	M03.08
;		- Add support for large disks, handle different filesystem
;		  and device sizes.
;
;	E. Vopicka	13-May-96	M03.09
;		- Clean up a bit, remove some debug code.

; This  MCR task will produce fragmentation statistics for the specified
; FILES-11 device.  The output is a frequency count of  contiguous  free
; blocks (holes) falling within each of several ranges, the total number
; of blocks for each range,  and the total number of free blocks for the
; device.
;
; Output  text  or  error  messages  are directed to LUN 2, which may be
; assigned to any terminal or lineprinter.
	.SBTTL	Macro library calls, local macros

	.ENABL	MCL

	HMBOF$				;Define the Home Block offsets

	.MACRO	ASSUME	A,B=0
	.IIF NE	<A>-<B>	.ERROR	<A>-<B>	;Expressions not equal
	.ENDM	ASSUME

	.IF DF	CKSUMS

	.MACRO	.ASCIS	TXT,QC=#
	.IRPC	X,^'QC'TXT'QC
	.BYTE	<''X>
CKSM	=	CKSM+<''X>
	.ENDR
	.ENDM	.ASCIS

	.IFF	; DF	CKSUMS

	.MACRO	.ASCIS	TXT,QC=#
	.LIST 	ME
	.ASCII	QC'TXT'QC
	.ENDM	.ASCIS

	.ENDC	; DF	CKSUMS

	.MACRO	BLKW	NAM,N=1
	.IIF NE	<.DOT.-.BASE.>&1	.ERROR	;BLKW macro - odd address
NAM	=	.DOT.
.DOT.	=	.DOT.+<2*<N>>
	.ENDM	BLKW

	.MACRO	FATAL	MESS,QC=#
	JSR	R5,FATAL
CKSM	=	0
	.ASCIS	^QC'MESS'QC,QC
	.BYTE	0
	.EVEN
	.WORD	CKSM
	.ENDM	FATAL

	.IF NDF	R$$EIS&M$$EIS

	.MACRO	SOB	A,B
	DEC	A
	BNE	B
	.ENDM	SOB

	.ENDC	;NDF	R$$EIS&M$$EIS
	.SBTTL	Local data

ALUN:	ALUN$	1,SY,0			;Assign LUN 1
GLUN:	GLUN$	1,GLUNBF		;To see if device is F11 device

ACRDPB:	QIOW$	IO.ACR,1,1,,IOSB,,<BITFID,,,,100003>	;Access file
DACDPB:	QIOW$	IO.DAC,1,1,,IOSB,,<>			;Deaccess file
RVBDPB:	QIOW$	IO.RVB,1,1,,IOSB,,<INBUF,512.>		;Read virtual block
TTYDPB:	QIOW$	IO.WVB,2,1,,IOSB,,<INBUF>		;Write to LUN 2

IOSB:	.BLKW	2			;I/O status block

QIOLEN::.WORD	256.			;Max. length of single terminal QIO

BITFID:	.WORD	2,2,0			;FID of [0,0]BITMAP.SYS
INDFID:	.WORD	1,1,0			;FID of [0,0]INDEXF.SYS

TIME:	GTIM$	INBUF			;Get time parameters

EXSTAT:	.WORD	EX$SUC			;Exit status code

BINS:	.WORD	5.,25.,50.,100.,150.,200.,250.,300.,400.,600.,1000.,2000.
BSIZ	=	.-BINS/2		;Number of bins

;	**** Don't separate the below ****

; $EDMSG control block

EDTBLK:
BLKFCT:	.WORD	0			;Size of buffer in disk blocks
	.WORD	GLUNBF+G.LUNA		;Device name
EDTUN1:	.WORD	0			; and unit number
EDTTIM:	.BLKW	6.			;Six words for time parameters

$$$	=	0
	.REPT	BSIZ+1
	.WORD	BIN+<4*$$$>		;Address of frequency counter
	.WORD	BINSUM+<4*$$$>		;Address of subtotal
$$$	=	$$$+1
	.ENDR

EDTBLF:	.WORD	GLUNBF+G.LUNA		;Device name
EDTUN2:	.WORD	0			; and unit number
	.WORD	TOTAL			;Address of total doubleword
	.WORD	USED			;Used blocks
	.WORD	FSSIZE			;Filesystem size in blocks
	.WORD	LARGST			;Address of largest block doubleword

FREHDR:	.BLKW	1			;# of free file headers
USEHDR:	.BLKW	1			;# of file headers in use
MAXHDR:	.BLKW	1			;Max. # of files on volume

;WARN:	.WORD	FSSIZE			;Filesystem size
;	.WORD	GLUNBF+G.LUCW+2		;Device size

;	**** Don't separate the above ****

;	**** Don't separate the below ****

GMCRDS:	GMCR$				;
.	=	GMCRDS+G.MCRB

CKSM	=	0			;Initialize checksum

ISTRNG:	.ASCIS	^#FRG M03.09-E.V. (%D.) -- FILES-11 disk #
	.ASCIS	^#fragmentation statistics for %2A%Q:#
	.ASCIS	^#%2NContiguous free blocks (holes)#
	.ASCIS	^#		Date %Y  Time %3Z#
	.ASCIS	^#%2N	   Hole range	Frequency	Number of blocks#
	.ASCIS	^#%2N	   1. -    5.	%9<%T.%>		%T.#
	.ASCIS	 ^#%N	   6. -   25.	%9<%T.%>		%T.#
	.ASCIS	 ^#%N	  26. -   50.	%9<%T.%>		%T.#
	.ASCIS	 ^#%N	  51. -  100.	%9<%T.%>		%T.#
	.ASCIS	 ^#%N	 101. -  150.	%9<%T.%>		%T.#
	.ASCIS	 ^#%N	 151. -  200.	%9<%T.%>		%T.#
	.ASCIS	 ^#%N	 201. -  250.	%9<%T.%>		%T.#
	.ASCIS	 ^#%N	 250. -  300.	%9<%T.%>		%T.#
	.ASCIS	 ^#%N	 301. -  400.	%9<%T.%>		%T.#
	.ASCIS	 ^#%N	 401. -  600.	%9<%T.%>		%T.#
	.ASCIS	 ^#%N	 601. - 1000.	%9<%T.%>		%T.#
	.ASCIS	 ^#%N	1001. - 2000.	%9<%T.%>		%T.#
	.ASCIS	 ^#%N	2001.  and up	%9<%T.%>		%T.#
ISTRNF:	.ASCIS	^#%2N%2A%Q: has %T. blocks free, %T. blocks used out of %T.#
	.ASCIS   ^#%NLargest contiguous space = %T. blocks#
	.ASCIS	 ^#%N%D. file headers are free, %D. headers used out of %D.#
ISTRNT:	.ASCIS	 ^#%N#
	.ASCIZ	//
	.EVEN

	.IF DF	CKSUMS

ISTRSM:	.WORD	CKSM			;Checksum of ISTRNG; it must
					; follow ISTRNG
	.ENDC	;DF	CKSUMS

;	**** Don't separate the above ****

;WARNT:	.ASCII	/WARNING: /
;	.ASCIZ	/Filesystem and device size are different (%T., %T. blocks)/

	.IF DF	F11MAG

F11TXT:	.BYTE	'D+F11MAG+<.-F11TXT>
	.BYTE	'E+F11MAG+<.-F11TXT>
	.BYTE	'C+F11MAG+<.-F11TXT>
	.BYTE	'F+F11MAG+<.-F11TXT>
	.BYTE	'I+F11MAG+<.-F11TXT>
	.BYTE	'L+F11MAG+<.-F11TXT>
	.BYTE	'E+F11MAG+<.-F11TXT>
	.BYTE	'1+F11MAG+<.-F11TXT>
	.BYTE	'1+F11MAG+<.-F11TXT>
	.BYTE	'A+F11MAG+<.-F11TXT>
	.BYTE	' +F11MAG+<.-F11TXT>
	.BYTE	' +F11MAG+<.-F11TXT>
	.IIF NE	<.-F11TXT>-12. 	.ERROR	;Bad length of F11TXT

	.ENDC	;DF	F11MAG

PREFIX:	.ASCIZ	<15><12>/FRG -- /
DSWTXT:	.ASCIZ	/. $DSW=/
IOSTXT:	.ASCIZ	/, IOSB=/
	.EVEN

;**********************************************************************

	.PSECT	.99999

.BASE.	=	.
.DOT.	=	.

	BLKW	FSSIZE	,2		;Filesystem size in blocks
	BLKW	ENDPTR	,1		;End of buffer pointer
	BLKW	GLUNBF	,6		;Buffer for LUN info
	BLKW	BLKCNT	,1		;Count of blocks remaining to read

.CLR.	=	.DOT.			;Start of area to be cleared

	BLKW	FREFLG	,1		;/FR seen (0=no)

	BLKW	COUNTB	,2
	BLKW	BIN	,<<BSIZ+1>*2> 	;Holds frequency count for each bin
	BLKW	BINSUM	,<<BSIZ+1>*2> 	;Holds # of blocks for each bin

	BLKW	TOTAL	,2		;Total free blocks seen
	BLKW	USED	,2		;Used blocks
	BLKW	LARGST	,2		;Largest chunk of blocks seen

.VARS.	==	<.DOT.-.BASE.>

INBUF	=	.DOT.			;Buffer for storage bitmap blocks

	.PSECT
	.SBTTL	Initialize, get command line, assign LUN to device

;	**  FRG - Display fragmentation data for FILES-11 devices
;
; Syntax:
;		FRG ddn:
;
; where:
;		dd - a legal FILES-11 device name
;		n  - a legal unit number, range 0-377

	.ENABL	LSB

$FRGEP:	CLR	TTYDPB+Q.IOPL+4		;Reset carriage control for when
					; we are fixed in memory

	MOV	#IO.ATT,TTYDPB+Q.IOFN	;Try to attach output
	DIR$	#TTYDPB			; device (TI: by default)
	MOV	#IO.WVB,TTYDPB+Q.IOFN	;Set I/O function to write virtual

10$:	BR	20$			;This will be changed to NOP
	FATAL	<Task not fixable>

20$:	MOV	#240,10$		;No-op the branch, FRG is not fixable

	MOV	SP,R1			;Save SP - easier unwind
	SUB	#16.*2,SP		;Create temp buffer for GTSK$
	MOV	SP,R0			;Address of GTSK$ buffer
	GTSK$S	R0			;Get our task parameters
	MOV	G.TSTS(R0),R0		;Size of task region (C preserved)
	MOV	R1,SP			;Restore SP, C bit preserved
	BCC	21$			; If CC - OK, continue
	FATAL	<GTSK$ directive error>	; else declare error

21$:	CMP	R0,#INBUF+<3*512.>	;More than required minimum?
	BHIS	22$			; Yes
	FATAL	<Not enough memory available>

22$:	MOV	R0,ENDPTR		;Pointer past the last byte in INBUF
	SUB	#INBUF,R0		;Length of INBUF
	CLRB	R0			; in 512.
	SWAB	R0			; byte
	ASR	R0			; units
	MOV	R0,BLKFCT		;Store blocking factor (= number
					; of available 512. byte buffers)

	MOV	#.CLR.,R1		;Address of area to be cleared
	MOV	#<INBUF-.CLR.>/2,R2	;# of words to clear
23$:	CLR	(R1)+			;Clear a word
	SOB	R2,23$			;Loop	

	MOV	GMCRDS,INBUF		;Set up GMCR$ DPB
	DIR$	#INBUF			;Get command line
	BCS	70$			;If CS - no command line

	MOV	$DSW,R0			;Terminate command
	CLRB	INBUF+G.MCRB(R0)	; with zero byte

	RDAF$S	#INBUF+100.		;Set $DSW to 1 (no MOV #1,$DSW!!!)

	MOV	#INBUF+G.MCRB,R0	;Set address of command buffer
30$:
	MOVB	(R0)+,R1		;End of command line ?
	BEQ	70$			; Yes
	CMPB	R1,#'/			;Option goes?
	BEQ	50$			; Yes, process (FRG/FR)
	CMPB	R1,#40			;Space goes ? (FRG ddn... or FRG /FR)
	BNE	30$			; No, keep looping

40$:	MOVB	(R0)+,R1		;Skip
	CMPB	R1,#40			; over
	BEQ	40$			; spaces

	CMPB	R1,#'/			;Option goes?
	BEQ	50$			; Yes, process (FRG /FR),
					; else no, must be device name

	MOVB	R1,ALUN+A.LUNA+0	;Set up device
	BEQ	90$			; name for ALUN$,
	MOVB	(R0)+,ALUN+A.LUNA+1	; checking also for
	BEQ	90$			; end of line

	CALL	$COTB			;Now get unit #
	MOVB	R1,ALUN+A.LUNU		;Unit number for ALUN$
	SWAB	R1			;Unit number < 400 ?
	BNE	90$			; No, error
	
	TSTB	R2			;End of command reached ?
	BEQ	70$			; Yes, allow omission of ':
	CMPB	R2,#'/			;Option goes?
	BEQ	50$			; Yes, process
	CMPB	R2,#':			;Did we find the colon ?
	BNE	90$			; No, error

	CMPB	(R0),#'/		;Option goes?
	BNE	60$			; No, must be EOL
	INC	R0			; Yes, skip over / and process

50$:	CMPB	(R0)+,#'F		;Check
	BNE	90$			; for /FR
	CMPB	(R0)+,#'R		; switch
	BNE	90$			;  No, error
	MOV	SP,FREFLG		;Flag /FR seen

60$:	TSTB	(R0)+			;More characters on command line ?
	BNE	90$			; Yes, error

70$:	DIR$	#ALUN			;Assign LUN 1 to input device
	BCS	80$			; If CS - illegal device

	DIR$	#GLUN			;Obtain information about our device
	BCS	80$			; If CS - failed, must be illegal

	BIT	#40000,GLUNBF+G.LUCW+0	;Mountable FILES-11 device ?
	BEQ	80$			; No, error
	BIT	#40,GLUNBF+G.LUCW+0	;Sequential device ?
	BEQ	100$			; No
80$:	FATAL	<Illegal device>	;Not too good

90$:	FATAL	<Syntax error. Usage: FRG[ ddn[:]][/FR]>

100$:	DIR$	#ACRDPB			;Access the bitmap file
	BCS	110$			; OK
	TSTB	IOSB			;Success ?
	BGT	120$			; Yes
F11ERR:					;Ref. label
110$:	FATAL	<Failed to access storage bitmap file>

120$:	MOV	#1,RVBDPB+Q.IOPL+10	;Set VBN to 1
	MOV	#512.,RVBDPB+Q.IOPL+4	;Set to read single block
	DIR$	#RVBDPB			; and read it into memory
	TSTB	IOSB			;Any error ?
	BLE	121$			; No
	CMP	IOSB+2,RVBDPB+Q.IOPL+2	;Match on length?
	BEQ	122$			; Yes
121$:	FATAL	<Failed to read storage bitmap header>

122$:	MOV	RVBDPB+Q.IOPL+0,R1	;Get buffer address
	CLR	R3
	BISB	3(R1),R3
	BNE	302$
	MOV	10(R1),R3
302$:	;MOV	R3,???
	CMP	R3,#126.
	BHI	322$
	ASL	R3
	ASL	R3
	ADD	R3,R1
322$:	ADD	#4,R1
	MOV	(R1)+,FSSIZE
	MOV	(R1),FSSIZE+2

	MOV	#1,RVBDPB+Q.IOPL+10	;Start reading at VBN2 (2=1+1)
	MOV	FSSIZE+0,USED+0		;Initialize count of blocks
	MOV	FSSIZE+2,USED+2		; (= bitmap bits) processed

	ASSUME	.,RECORD
	
	.DSABL	LSB
	.SBTTL	Process volume free blocks bitmap

RECORD:
	MOVB	RVBDPB+Q.IOPL+2+1,R1	;Length of previous read
	ASR	R1			; in disk blocks
	ADD	R1,RVBDPB+Q.IOPL+10	;Advance VBN

	TST	USED+0			;Check high part of bits remaining
	BNE	4$			; If NE - full read
	MOV	USED+2,R1		;# of blocks remaining to read
	ADD	#512.*8.-1,R1		;Add # of bits in disk block minus one
	BCS	4$			; If CC - full read
	CLRB	R1			;256. bits
	SWAB	R1			; units,
	ASR	R1			; ...  512.
	ASR	R1			; ... 1024.
	ASR	R1			; ... 2048.
	ASR	R1			; ... 4096. (= # of disk blocks)
	CMP	R1,BLKFCT		;More than blocking factor?
	BLOS	5$			; No
4$:	MOV	BLKFCT,R1		; Yes, set to read as much as possible
5$:	ASL	R1			;Set # of bytes
	MOVB	R1,RVBDPB+Q.IOPL+2+1	; to read

	BIT	#777,RVBDPB+Q.IOPL+2
	BEQ	.+4
	IOT

	DIR$	#RVBDPB			; and read it into memory
	TSTB	IOSB			;Any error ?
	BGT	10$			; No
	FATAL	<Failed to read storage bitmap file>

10$:	MOV	RVBDPB+Q.IOPL+0,R0	;Get buffer address

BLOCKS:
	MOV	(R0)+,R1		;Get 16 blocks (or bits)
	TST	USED+0			;Less than 16. blocks remaining ?
	BNE	10$			; Certainly no
	MOV	USED+2,R2		; Maybe
	CMP	R2,#16.			; ...
	BLO	SHIFT			; Yes, must count them manually
10$:	TST	R1			;All blocks in use ?	
	BEQ	FULL			; All used
	CMP	R1,#177777		;All free ?
	BNE	COUNT			; Not all free

	ADD	#16.,COUNTB+2		;Count 16 free blocks
	ADC	COUNTB			; in double precision
	BR	END			;See if done

COUNT:					;Blocks not all free
	MOV	#16.,R2			;Bit shift counter
SHIFT:	CLC				;Check
	ROR	R1			; a block
	BCC	FULL			; If CC - block in use
					; If CS - block free

	ADD	#1,COUNTB+2		;Count a block free
	ADC	COUNTB			; in double precision
	BR	ENDLP			;See if we are done

FULL:					;All 16 blocks in use
	TST	COUNTB			;Any free blocks?
	BNE	10$			; Yes
	TST	COUNTB+2		;Check lower part
	BEQ	ENDLP			; None free

10$:	MOV	#BSIZ,R4		;Number of bins
	CLR	R3			;Clear bin pointer
	CMP	COUNTB,LARGST		;Is it a new largest block?
	BLO	30$			; No
	BHI	20$			; Yes
	CMP	COUNTB+2,LARGST+2	; Maybe, compare lower parts
	BLOS	30$			;  No
20$:	MOV	COUNTB,LARGST		;  Yes, save
	MOV	COUNTB+2,LARGST+2	;  the size

30$:	TST	COUNTB			;If high part non zero it is big,
	BNE	40$			; i.e. too big for all but last bucket
	CMP	COUNTB+2,BINS(R3)	;More than this bin ?
	BLOS	50$			; No
40$:	ADD	#2,R3			;Point to next bin

	SOB	R4,30$			;Process all bins

50$:	ADD	COUNTB+2,TOTAL+2	;Accumulate total
	ADC	TOTAL			;
	ADD	COUNTB,TOTAL		;

	ASL	R3			;Make offset into 2 word blocks
	ADD	COUNTB+2,BINSUM+2(R3)	;Accumulate total for each bin
	ADC	BINSUM(R3)		;
	ADD	COUNTB,BINSUM(R3)	;

	ADD	#1,BIN+2(R3)		;Increment bin
	ADC	BIN(R3)			;

	CLR	COUNTB+2		;Clear counter
	CLR	COUNTB			;

ENDLP:
	TST	R1			;Any free blocks still ?
	BEQ	END			; No

	DEC	R2			;Check
	BNE	SHIFT			; all blocks

END:	TST	USED+0			;16. or more blocks remaining ?
	BMI	ENDMAP			; (MI is end of bitmap)
	BNE	10$			; Yes
	CMP	USED+2,#16.		; Maybe not
	BHI	10$			; No, end of bitmap
	COM	USED+0			;Change to -1
	CLR	R1			;Indicate fake blocks in use
	BR	FULL			;Process blocks in the last bin

10$:	SUB	#16.,USED+2		;Subtract 16
	SBC	USED+0
	CMP	R0,ENDPTR		;Time to read another disk block?
	BLO	BLOCKS			; No
	JMP	RECORD			; Yes

ENDMAP:	DIR$	#DACDPB			;Deaccess the bitmap file
	BCS	10$			;Do not
	TSTB	IOSB			; accept any
	BGT	20$			; deaccess errors
10$:	FATAL	<Failed to deaccess storage bitmap file>

20$:					;Ref. label
	ASSUME	.,INDEX
	.SBTTL	Process index file bitmap

	.ENABL	LSB

INDEX:	MOV	#INDFID,ACRDPB+Q.IOPL+0	;Access the
	DIR$	#ACRDPB			; index file
	BCS	10$			;Handle
	TSTB	IOSB			; access
	BGT	20$			; errors
10$:	FATAL	<Failed to access index file>

20$:					;Ref. label

	MOV	#2,RVBDPB+Q.IOPL+10	;Set VBN of the Home Block
	MOV	#512.,RVBDPB+Q.IOPL+2	;Set length of the above
	DIR$	#RVBDPB			; and read it into memory
	BCS	30$			;Do not accept
	TSTB	IOSB			; any read
	BGT	50$			; errors
30$:	FATAL	<Failed to read home block>

	.IF DF	F11MAG

40$:	MOV	#IE.ICE&377,IOSB	;Set "Internal consistency error"
	JMP	F11ERR			; into IOSB and tell the user

	.IFTF	;DF	F11MAG

50$:					;Ref. label

	.IFT	;DF	F11MAG

	MOV	#F11TXT,R1		;Address of coded text
	MOV	#INBUF+H.INDF,R2	;Address of pure text
	MOV	#12.,R3			;Number of characters to check

60$:	CLRB	R0			;Get a byte
	BISB	(R1)+,R0		; of coded text
	SUB	#F11MAG,R0		;Subtract magic number
	ADD	#F11TXT+1,R0		;Subtract offset from
	SUB	R1,R0			; F11TXT to current char
	CMPB	R0,(R2)+		;Match on current character ?
F11CHK::BNE	40$			; Yes
	SOB	R3,60$			;Check all 12. characters

	.ENDC	;DF	F11MAG

	MOV	INBUF+H.FMAX,MAXHDR	;Save max. number of headers on volume
	MOV	INBUF+H.IBSZ,BLKCNT	; and index file bitmap size

	CMP	INBUF+H.VLEV,#401	;Volume level structure supported ?
	BEQ	80$			; Yes
	CMP	INBUF+H.VLEV,#402	;Maybe supported ?
	BEQ	80$			; Yes
70$:	FATAL	<Volume structure level not supported>

80$:					;Ref. label
	CLR	R5			;Clear used headers count

90$:	MOVB	RVBDPB+Q.IOPL+2+1,R1	;Length of previous read
	ASR	R1			; in disk blocks
	ADD	R1,RVBDPB+Q.IOPL+10	;Advance VBN

	MOV	BLKCNT,R1		;# of blocks remaining to read
	CMP	R1,BLKFCT		;More than blocking factor?
	BLOS	96$			; No
	MOV	BLKFCT,R1		; Yes, set to read as much as possible
96$:	SUB	R1,BLKCNT		;Subtract from from block counter
	ASL	R1			;Set # of bytes
	MOVB	R1,RVBDPB+Q.IOPL+2+1	; to read

	DIR$	#RVBDPB			;Read
	BCS	100$			; with
	TSTB	IOSB			; no
	BGT	110$			; errors
100$:	FATAL	<Failed to read index file bitmap>

110$:					;Ref. label
	MOV	RVBDPB+Q.IOPL+0,R4	;Address of buffer
	MOV	RVBDPB+Q.IOPL+2,R3	;Set # of words
	ASR	R3			; to check
120$:	MOV	(R4)+,R2		;Get a word
	BEQ	160$			; All 16. headers free, no accounting
	CMP	R2,#-1			;All headers in use ?
	BNE	130$			; No
	ADD	#16.,R5			; Yes, add 16. headers to used count
	BR	160$			;  and done with this word

130$:					;Ref. label
140$:	MOV	R2,R1			;Copy pattern
	BEQ	160$			; No more bits are set
	NEG	R1			;Clear
	BIC	R1,R2			; single bit
	INC	R5			;Header in use, count it
	BR	140$			;Do the next bit
 
160$:	SOB	R3,120$			;Process the whole input buffer

	TST	BLKCNT			;Any bitmap blocks remaining?
	BNE	90$			; Yes, process them

	MOV	R5,USEHDR		;Store # of file headers in use

	DIR$	#DACDPB			;Deaccess the index file
	BCS	170$			;Do not accept
	TSTB	IOSB			; any deacess
	BGT	180$			; errors
170$:	FATAL	<Failed to deaccess index file>

180$:					;Ref. label

	MOV	MAXHDR,FREHDR		;Max. # of headers minus # of headers
	SUB	USEHDR,FREHDR		; in use gives # of free headers

	.DSABL	LSB
	.SBTTL	Display volume data

	.ENABL	LSB

FINISH:	DIR$	#TIME			;Get time/date
	MOV	#INBUF,R0		;Move time
	MOV	#EDTTIM,R1		; parameters
	MOV	#6,R2			; into
10$:	MOV	(R0)+,(R1)+		; $EDMSG
	SOB	R2,10$			; control block

	MOVB	GLUNBF+G.LUNU,EDTUN1	;Set unit number everywhere
	MOVB	GLUNBF+G.LUNU,EDTUN2	; it is expected to be found

	CLRB	GLUNBF+G.LUCW+2+1	;Only 3 bytes for device size

	MOV	FSSIZE+2,USED+2 	;Device size
	MOV	FSSIZE+0,USED+0		; in blocks
	SUB	TOTAL+2,USED+2		; minus number of free
	SBC	USED			; blocks gives
	SUB	TOTAL+0,USED+0		; number of blocks in use

	.IF DF	CKSUMS

	MOV	#ISTRNG,R1		;Calculate and check
	CALL	CKSUM			; the checksum of control string

	.ENDC	;DF	CKSUMS

	MOV	#INBUF,R0		;Get new output string buffer
	MOV	#ISTRNF,R1		;Arrange for
	MOV	#EDTBLF,R2		; PIP /FR like output
	TST	FREFLG			;/FR seen?
	BNE	20$			; Yes
	CLRB	ISTRNT			;No trailing newline
	MOV	#ISTRNG,R1		;Get address of .ASCIZ control string
	MOV	#EDTBLK,R2		;Get arguments
20$:	CALL	$EDMSG			;Edit the message

	TST	FREFLG			;/FR seen?
	BNE	50$			; Yes, skip

	MOV	#PREFIX,TTYDPB+Q.IOPL+0	;Position the carriage in case
	MOV	#2,TTYDPB+Q.IOPL+2	; of output to hardcopy
	DIR$	#TTYDPB			; device
	BCS	30$			;Do not
	TSTB	IOSB			; accept
	BGT	40$			; any
30$:	IOT				; errors
TIERR1::				;Ref. label

40$:	MOV	#100401,TTYDPB+Q.IOPL+4	;Set to clear screen
50$:	SUB	#INBUF,R0		;Get size
	MOV	R0,TTYDPB+Q.IOPL+2	; and set it into DPB
	MOV	#INBUF,TTYDPB+Q.IOPL+0	;Set buffer address into DPB

	.DSABL	LSB
	.SBTTL	Subroutine to do per-partes terminal output

	.ENABL	LSB

OUT:	MOV	TTYDPB+Q.IOPL+2,R0	;Get length of write
10$:	MOV	QIOLEN,TTYDPB+Q.IOPL+2	;Default to maximum length
	CMP	R0,QIOLEN		;More than maximum remains ?
	BHI	20$			; Yes, use maximum length
	MOV	R0,TTYDPB+Q.IOPL+2	;Set length of rest of write

20$:	DIR$	#TTYDPB			;Print the message
	BCS	30$			;Do not
	TSTB	IOSB			; accept
	BGT	40$			; any
30$:	IOT				; errors
TIERR2::				;Ref. label

40$:	CLR	TTYDPB+Q.IOPL+4			;Reset carriage control
	ADD	TTYDPB+Q.IOPL+2,TTYDPB+Q.IOPL+0	;Address of next transfer
	SUB	TTYDPB+Q.IOPL+2,R0		;Subtract length of last xfer
	BNE	10$				; More to output

	EXST$S	EXSTAT				;Exit with status
	.SBTTL	Subroutine to output error messages

	.DSABL	LSB

	.IF DF	CKSUMS

TRICK:	FATAL	<Please no tricks with ZAP or his friends>

	.ENDC	;DF	CKSUMS

FATAL:	MOV	#EX$ERR,EXSTAT		;Set error exit status

	.IF DF	CKSUMS

	MOV	R5,R1			;Calculate and check
	CALL	CKSUM			; the checksum of message

	.ENDC	;DF	CKSUMS

	MOV	#ISTRNG,R0		;Get address of message buffer
	MOV	R0,TTYDPB+Q.IOPL+0	; and set it to DPB

	MOV	#PREFIX,R2		;Insert
	CALL	MOVE			; prefix string

	MOV	R5,R2			;Now insert
	CALL	MOVE			; the message itself

	MOV	#DSWTXT,R2		;Show
	MOV	$DSW,R1			; contents of
	CALL	10$			; $DSW

	MOV	#IOSTXT,R2		;Show
	MOVB	IOSB,R1			; contents of
	CALL	10$			; I/O status block

	SUB	TTYDPB+Q.IOPL+0,R0	;Set length
	MOV	R0,TTYDPB+Q.IOPL+2	; into DPB
	BR	OUT			;Print out message and exit

10$:	CALL	MOVE
	CLR	R2			;Zero suppress
	CALL	$CBDSG			;Convert to decimal
	MOVB	#'.,(R0)+		; and flag as decimal
	RETURN				;Done
	.SBTTL	Utilities

; Move .ASCIZ string
;	Input:	R2 - .ASCIZ source string, R0 - buffer pointer
;	Output:	R2 - past zero byte in .ASCIZ, R0 - updated
;		R1, R3 - preserved

MOVE:	MOVB	(R2)+,(R0)+		;Move a byte
	BNE	MOVE			; More to move
	DEC	R0			;Do not include terminating null
	RETURN				;All done

	.IF DF	CKSUMS

; Calculate checksum
;	Input:	R1	address of .ASCIZ string, followed by the checksum

CKSUM:	CLR	R2			;Init checksum

10$:	CLR	R0			;Get a byte
	BISB	(R1)+,R0		; from string
	BEQ	20$			; Zero is end of string
	ADD	R0,R2			;Add to checksum
	BR	10$			; and process next byte

20$:	INC	R1			;Make sure we are
	BIC	#1,R1			; on an even address

	CMP	R2,(R1)			;Checksum O.K. ?
	BEQ	30$			; Yes
	JMP	TRICK			;Bad checksum

30$:	RETURN				;Return the checksum in R1

	.ENDC	;DF	CKSUMS

	.END	$FRGEP
=== END FRG.MAC ===
=== BEGIN FRG.CMD ===
	.ENABLE SUBSTITUTION
	;
	; Command file to assemble and build the FILES-11 disk fragmentation
	; statistics program (FRG) on a mapped RSX-11M or RSX-11M-PLUS system.
	;
	PIP FRG.OBJ;*/DE/NM,FRG.TSK;*,FRG.LST;*,FRG.MAP;*,FRGBLD.TMP;*
	MAC FRG,FRG/-SP=FRG
.;	MAC FRG=FRG
	.IF	<EXSTAT> EQ <SUCCES>	.GOTO	CONT
	;
	; Assembly error. Sorry, FRG is not ready to run.
	;
	PIP FRG.OBJ;*/DE/NM
	.STOP

.CONT:	.SETS	LIBOP	""
	.;
	.; LB:[1,1]FCSRES is vectored, 4kw overlaid library, supplied by DEC.
	.;
	.TESTFILE LB:[1,1]FCSRES.STB
	.IF	<FILERR> EQ 1	.SETS	LIBOP	"RESLIB	=LB:[1,1]FCSRES/RO:7"
	.;
	.; LB:[1,1]FSCRESCOM is fake .STB acting as vectored, 8kw common block.
	.; This "fake" .STB is supplied on (E.V.) systems only.
	.;
	.TESTFILE LB:[1,1]FCSRESCOM.STB
	.IF	<FILERR> EQ 1	.SETS	LIBOP	"RESCOM	=LB:[1,1]FCSRESCOM/RO:6"

	.OPEN	FRGBLD.TMP
	.ENABLE	DATA
; Date:		7/12/77
; By:		D. Michaud
;		Borg Instruments
;		Delavan Wisconsin
;
; Modified 6/15/78 by Greg Thompson
;		- changed it to double precision
;		- modified the error messages
;		- allowed unit number 0 as a default
;		- added largest free block output
;		- lower cased the output
;		- changed the hole ranges
;		- allowed non-priv user to use it
;		- build it /PR:0 since it doesn't reference Exec
;
; Modified for P/OS by R Uleski, Baker Instruments 23-Apr-86
;
; Modified for RSX-11M V4.2 by :
;
;	Eduard Vopicka, Computing centre,
;	Prague School of Economics, Czechoslovakia
;
;	E. Vopicka.	26-Sep-87
;		- improve overhead and make smaller  ( use FILES-11 QIOs
;		  instead of  FCS  OPEN$ / CLOSE$  to  access / deaccess
;		  bitmap file )
;		- build	 /-PR  in order to allow flying install for non-
;		  privileged  users.   This  also  disallows  access  to
;		  volumes not mounted by the user
;		- display statistics for SY0: if device name omitted
;		- allow  omission  of  trailing  collon  in  device name
;		  specification
;		- convert to lower case
;
;	E. Vopicka	07-Dec-87	M03.00
;		- erase  the  entire screen before outputting and change
;		  screen format
;		- added PIP-like display of total, free and in-use
;		  file headers
;		- split single, long terminal QIO into more shorten QIOs
;		- modified to run under RSX-11M-PLUS V3.0 (the high byte
;		  of U.CW2 is possibly non-zero on M+)
;
;	E. Vopicka	12-Dec-87	M03.01
;		- check the volume structure level
;		  (H.VLEV in the home block)
;		- check for valid FILES-11 volume
;		  (H.INDF in the home block)
;
;	E. Vopicka	22-Dec-87	M03.02
;		- do not allow any ZAP changes in ISTRNG
;
;	E. Vopicka	14-Sep-88	M03.03
;		- Fix $DSW to look better after syntax error
;
;	E. Vopicka	10-Apr-90	M03.04
;		- Keep count of bits processed during volume bitmap
;		  processing and stop on end of volume, e.g. do not
;		  process volume bitmap bits describing non-existent
;		  (past end of volume - device size) blocks.
;
;	E. Vopicka	12-Apr-90	M03.05
;		- Modify to use SOB instead of DEC/BNE.
;		- Use CLC/ROR instead of ASR.
;
;	E. Vopicka	24-Apr-91	M03.06
;		- Add /FR switch to produce PIP/FR like output.
;
;	E. Vopicka	27-Apr-91	M03.07
;		- Modify to use EXTTSK or EXTSCT TKB option.
;
;	E. Vopicka	08-Aug-95	M03.08
;		- Add support for big disks, handle different filesystem
;		  and device sizes.
;
;	E. Vopicka	13-May-96	M03.09
;		- Clean up a bit, remove some debug code.
;
FRG/-PR/CP/-FP,FRG/MA/-WI/-SP=FRG
;FRG/-PR/CP/-FP,FRG/MA/-WI/-SP=FRG,LB:[1,1]DEBIL/DA
/
TASK	=...FRG
PRI	=51
STACK	=32
UNITS	=2
ASG	=TI000:1,TI000:2
;
; About the magic "n" below: it is the blocking factor used for
; BITMAP.SYS and INDEXF.SYS I/O. Must be >=3. The maximum useful
; value of n is the size minus 1 (in disk blocks) of the largest
; [0,0]BITMAP.SYS;1 on your system. .VARS. represents the value
; of .VARS. symbol from FRG.MAP. The blocking factor is displayed
; on the first line of FRG output as (n.).
; 
; For PLAS systems: EXTTSK = <<.VARS.>+<n*1000>>/2
; Caution: Octal values for this calculation, then convert result
; from octal to decimal. (EXTTSK: should be expressed in decimal,
; word (2 byte) units.)
; 
EXTTSK	=2630
;
; For non-PLAS systems: EXTSCT=.99999:<.VARS.>+<n*1000>
; Caution: Values and result in octal for this calculation.
; (EXTSCT: should be expressed in octal, 1 byte units.)
;
;EXTSCT	=.99999:12214
;
.DISABLE DATA
	.IF	LIBOP NE ""	.DATA ;
	.IF	LIBOP NE ""	.DATA 'LIBOP'
	.ENABLE	DATA
;
; Define length of QIOs used to print formatted output. The default value
; of 400(8) should be changed to a larger number if your system has a large
; terminal driver pool. I hope that 400(8) is good choice for both small
; and large systems.
;
GBLPAT	=FRG:QIOLEN:400
/
.DISABLE DATA
	.CLOSE
	TKB @FRGBLD.TMP
	.IF	<EXSTAT> EQ <SUCCES>	.GOTO	CONT
	;
	; Build error. Sorry, FRG is not ready to run.
	;
	PIP FRG.TSK;*/DE/NM,FRG.OBJ;*
	.STOP
.CONT:	;
	; All done, FRG is ready to run. Good luck !!!
	;
=== END FRG.CMD ===

-- 
"Eduard Vopicka, Computing Centre, Prague University of Economics,
W. Churchill Square 4, CZ 130 67 Prague 3" <Eduard.Vopicka@vse.cz>
================== RFC 822 Headers ==================
Return-Path: eda@vse.vse.cz
Received: by dimond.zko.dec.com (UCX V4.0-10B, OpenVMS V6.2 VAX);
	Mon, 20 May 1996 14:46:18 -0400
Received: from vse.vse.cz by mail11.digital.com (8.7.5/UNX 1.2/1.0/WV)
	id OAA21503; Mon, 20 May 1996 14:31:34 -0400 (EDT)
Received: by vse.vse.cz id AA10066
  (5.67a8/IDA-1.5 for everhart@star.zko.dec.com); Mon, 20 May 1996 20:06:18 +0200
Date: Mon, 20 May 1996 20:06:18 +0200
From: Eduard Vopicka <Eduard.Vopicka@vse.cz>
Message-Id: <199605201806.AA10066@vse.vse.cz>
In-Reply-To: everhart@star.zko.dec.com (Glenn C. Everhart 603 881 1497)
             Re: Frag version
Reply-To: Eduard Vopicka <Eduard.Vopicka@vse.cz>
X-Mailer: Mail User's Shell (7.2.5 10/14/92)
To: everhart@star.zko.dec.com (Glenn C. Everhart 603 881 1497)
Subject: Re: Frag version
X-Charset: ASCII
X-Char-Esc: 29
