Google
 

Trailing-Edge - PDP-10 Archives - BB-D868C-BM - 4-sources/chkpnt.mac
There are 32 other files named chkpnt.mac in the archive. Click here to see a list.
; UPD ID= 272, SNARK:<4.UTILITIES>CHKPNT.MAC.23,  19-Feb-80 08:45:48 by ENGEL
; UPD ID= 270, SNARK:<4.UTILITIES>CHKPNT.MAC.22,  18-Feb-80 14:25:07 by ENGEL
;THIS AND THE LAST EDIT ARE TCO #4.2602 - MAKE COLUMN OVERFLOW A WARNING
; UPD ID= 268, SNARK:<4.UTILITIES>CHKPNT.MAC.21,  18-Feb-80 14:18:35 by ENGEL
;<4.UTILITIES>CHKPNT.MAC.20,  3-Jan-80 15:24:53, EDIT BY R.ACE
;UPDATE COPYRIGHT DATE
;<4.UTILITIES>CHKPNT.MAC.19, 29-Oct-79 15:08:20, Edit by KONEN
;CORRECT ELASPED TIME DIVISION FOR STRUCTURE AND TAPE RECORDS
;<4.UTILITIES>CHKPNT.MAC.18,  5-Oct-79 14:13:06, Edit by KONEN
;comment CHKPNT command out.  (Monitor does checkpointing)
;<4.UTILITIES>CHKPNT.MAC.17, 25-Sep-79 15:52:17, Edit by KONEN
;DON'T IGNORE INVISIBLE FILES WHEN GATHERING DISK STATISTICS
;<4.UTILITIES>CHKPNT.MAC.16, 10-Jul-79 11:19:32, Edit by KONEN
;CORRECT USAGE TYPE FOR TAPE MOUNT RECORD
;<4.UTILITIES>CHKPNT.MAC.15, 10-Jul-79 10:05:26, Edit by KONEN
;INSERT EDIT LOST FROM 3A
;MOVED LABEL DODK60 -1 TO ALLOW DISK STATS FOR MULTIPLE STRUCTURES
;<4.UTILITIES>CHKPNT.MAC.14, 16-May-79 07:54:45, EDIT BY GRADY
;CLEAN UP REASONABLENESS CHECK IN GTITM1 ROUTINE...SPR 12846
;<4.UTILITIES>CHKPNT.MAC.13,  6-Apr-79 09:51:53, Edit by KONEN
;ADD ELAPSED TIME OF USE FOR STRUCTURES AND TAPES
;ADD ARCHIVAL, RETRIEVAL, MIGRATION RECORDS
;<4.UTILITIES>CHKPNT.MAC.12, 10-Mar-79 13:42:02, EDIT BY KONEN
;UPDATE COPYRIGHT FOR RELEASE 4
;<4.UTILITIES>CHKPNT.MAC.11,  6-Feb-79 08:43:09, EDIT BY DBELL
;CHANGE QUESTION MARKS TO PERCENT SIGNS NEAR GETUNK
;<4.UTILITIES>CHKPNT.MAC.10, 11-Jan-79 09:20:36, Edit by KONEN
;ADD STRUCTURE AND TAPE MOUNTS ACCOUNTING
;<4.UTILITIES>CHKPNT.MAC.8, 18-Jul-78 16:54:52, Edit by PORCHER
;<4.UTILITIES>CHKPNT.MAC.7, 18-Jul-78 16:03:07, Edit by PORCHER
;TCO # 1947 - Remove version number herald.
; Update to version 4(112)
;<3A.UTILITIES>CHKPNT.MAC.58, 11-Jul-78 13:39:40, Edit by PORCHER
;TCO # 1898 - ALLOW USER-DEFINED USAGE ENTRIES (5000-9999)
;<4.UTILITIES>CHKPNT.MAC.5,  2-Mar-78 10:05:35, Edit by PORCHER
;Add "CHANGE (ACCOUNTING SHIFT)" command
;<4.UTILITIES>CHKPNT.MAC.4, 28-Feb-78 12:12:59, Edit by KIRSCHEN
;<4.UTILITIES>CHKPNT.MAC.3, 28-Feb-78 12:08:50, Edit by KIRSCHEN
;<4.UTILITIES>CHKPNT.MAC.2, 28-Feb-78 12:01:04, Edit by KIRSCHEN
;FIX INCORRECT PADDING WHEN NOUT IN OUTDEC FAILS
TITLE CHKPNT - TOPS20 CHECKPOINTING PROGRAM
SUBTTL	D. KIRSCHEN		10-13-75



;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
;  OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) 1976,1977,1978,1979,1980 BY DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.

	SEARCH MONSYM, MACSYM, ACTSYM
	.REQUIRE SYS:MACREL

	SALL

	IFNDEF .PSECT,<.DIRECTIVE .XTABM>

; ACCUMULATOR DEFINITIONS

	T1=1		;TEMPORARY
	T2=2		;TEMPORARY
	T3=3		;TEMPORARY
	T4=4		;TEMPORARY
	P1=5		;PRESERVED
	P2=6		;PRESERVED
	P3=7		;PRESERVED
	AT=10		;ACCOUNT TABLE ENTRY ADDRESS
			;ACS FOR COPY ROUTINES
	TBL=11		;TABLE LENGTH
	DESC=12		;FORM DESCRIPTOR POINTER
	LEN=13		;FIELD LENGTH COUNT
	BPNTR=14	;LBUFR POINTER
			;...
	CX=16		;RESERVED FOR SUPPORT CODE
	P=17		;PUSH-DOWN POINTER

; VERSION NUMBER DEFINITIONS

VMAJOR==4		;MAJOR VERSION OF CHKPNT
VMINOR==0		;MINOR VERSION NUMBER
VEDIT==114		;EDIT NUMBER
VWHO==0			;GROUP WHO LAST EDITED PROGRAM (0=DEC DEVELOPMENT)

VCHKPT== <VWHO>B2+<VMAJOR>B11+<VMINOR>B17+VEDIT
; MISCELLANEOUS SYMBOL DEFINITIONS

.ATPGS==0		;OFFSET TO # OF PAGES WITH THIS ACCOUNT
.ATFIL==1		;OFFSET TO NUMBER OF FILES WITH THIS ACCOUNT
.ATSIZ==2		;SIZE OF ENTRIES IN ACCOUNT TABLE

DATFLG==1B9+1B17	;ODTIM FLAG - OUTPUT DATE ONLY
TIMFLG==400240,,0	;ODTIM FLAGS - OUTPUT TIME ONLY AS HHMM
PDLEN==50		;PUSH-DOWN STACK SIZE
DEFTIM==^D15*^D60*^D1000 ;DEFAULT TIME INTERVAL BETWEEN CHECKPOINTS
ACTMAX==^D39		;MAX CHARACTERS IN ACCOUNT STRINGS IN DISK ENTRIES
NCHPW==5		;NUMBER OF ASCII CHARACTERS PER WORD
APPMAX==50		;MAX SIZE OF APPEND KEYWORD TABLE
CMDMAX==100		;MAX SIZE OF COMMAND TABLE
ACTBSZ==10		;SIZE OF ACCOUNT STRING BUFFER
BUFSIZ==200		;SIZE OF INPUT TEXT BUFFER
ATMSIZ==BUFSIZ		;SIZE OF ATOM BUFFER FOR COMND JSYS
GJFSIZ==.GJRTY+2	;SIZE OF GTJFN BLOCK USED BY COMND JSYS
DATSIZ==20		;SIZE OF DATE AND TIME BUFFER
DEFISZ==^D5		;SIZE OF DEFAULT TIME INTERVAL STRING BUFFER
SVERSZ==20		;SIZE OF BUFFER FOR SYSTEM NAME AND VERSION
JOBSIZ==20		;SIZE OF JOB INFORMATION BLOCK FOR GETJI
ACTSIZ==1000		;SIZE OF ALPHANUMERIC ACCOUNT TABLE
ACPSIZ==ACTSIZ*.ATSIZ	;SIZE OF ALPHA ACCOUNT PAGES TABLE
STRBSZ==21		;SIZE OF DIRECTORY NAME BLOCK
STRMAX==STRBSZ*5	;MAXIMUM # OF CHARACTERS IN STRDIR
PAGLEN==^D55		;NUMBER OF LINES/PAGE ON DISK STATISTICS LISTING
GTDBSZ==13		;SIZE OF GTDIR BLOCK

;FORMAT OF DISK/DIRECTORY TYPE WORD

DEFSTR (FOND,,0,1)	;FILES ONLY INDICATOR
DEFSTR (STYP,,1,1)	;STRUCTURE TYPE (0 := FOREIGN, 1 := DOMESTIC)
DEFSTR (PSF,,2,1)	;PUBLIC STRUCTURE FLAG
DEFSTR (PPSF,,3,1)	;PRIMARY PUBLIC STR
			;UNUSED 4-11
DEFSTR (KTYP,,23,12)	;KONTROLER TYPE
DEFSTR (DTYP,,35,12)	;DRIVE TYPE

RH2TYP==6		;RH20 TYPE CODE
RP4TYP==0		;RP04 TYPE CODE
RP5TYP==1		;RP05 TYPE CODE
RP6TYP==2		;RP06 TYPE CODE

;GTJFN ARGUMENT BLOCK

GTJARG:	GJ%OLD!GJ%IFG!GJ%XTN ;MUST BE EXISTING FILE,CAN BE WILDCARDED
			; ARG BLOCK CONTAINS MORE THAN 10 WORDS
	.NULIO,,.NULIO	;NO INPUT OR OUTPUT JFNS
	0		;NO DEFAULT DEVICE
	0		;NO DEFAULT DIRECTORY
	0		;NO DEFAULT FILE NAME
	0		;NO DEFAULT FILE TYPE
	0		;NO DEFAULT FILE PROTECTION
	0		;NO DEFAULT FILE ACCOUNT
	0		;NO JFN TO ASSOCIATE WITH FILE SPEC
	G1%IIN		;DON'T IGNORE INVISIBLE FILES
	0		;NO USERS'S TYPESCRIPT
	0		;IGNORE NUMBER OF BYTES AVAILABLE
	0		;NO CTRL/R
	0		;IGNORE DESTINATION BUFFER
	0		;NO FILE SPEC ATTRIBUTE BLOCK
SUBTTL	MACRO DEFINITIONS

; FUNCTION DESCRIPTOR BLOCK FOR COMND JSYS

DEFINE CMFDB (TYPE,FLAGS,DATA,HELP,DEFLT,LST)
<	..XX== < FLD(TYPE,CM%FNC) + FLAGS + LST >
  IFNB <HELP>,< ..XX== ..XX+CM%HPP >
  IFNB <DEFLT>,< ..XX== ..XX+CM%DPP >
	..XX
  IFNB <DATA>,<DATA>
  IFB <DATA>,<0>
  IFNB <HELP>, <POINT 7,[ASCIZ\HELP\] >
  IFB <HELP>,  <0>
  IFNB <DEFLT>, <POINT 7,DEFLT >
  IFB <DEFLT>, <0>
>

DEFINE TXT(TEXT) <POINT 7,[ASCIZ\TEXT\]>
SUBTTL	MAIN ENTRY POINT AND INITIALIZATION

START:	RESET			;RESET THE WORLD
	MOVE P,[IOWD PDLEN,PDL]	;SET UP PUSH-DOWN STACK
	SETZM LSTJFN		;INDICATE NO LISTING FILE FOR DISK STATS
	MOVX T1,DEFTIM		;GET DEFAULT TIME BETWEEN CHECKPOINTS
	SKIPN CHKTIM		;IS TIME INTERVAL ALREADY SET ?
	MOVEM T1,CHKTIM		;NO, SAVE DEFAULT TIME INTERVAL
	HRROI T1,DEFINT		;GET POINTER TO DEFAULT INTERVAL BUFFER
	MOVE T2,CHKTIM		;GET DEFAULT TIME BETWEEN CHECKPOINT PASSES
	IDIV T2,[^D60*^D1000]	;CONVERT TO MINUTES FROM MILLISECONDS
	MOVEI T3,^D10		;USE DECIMAL RADIX
	NOUT			;OUTPUT DEFAULT TIME INTERVAL
	 JRST [	JSERR		;UNEXPECTED ERROR
		MOVE T1,[ASCIZ/15/] ;ASSUME A DEFAULT STRING
		MOVEM T1,DEFINT	;SAVE DEFAULT STRING
		JRST START0 ]	;REJOIN MAINLINE CODE
START0:	CIS			;CLEAR SOFTWARE INTERRUPT SYSTEM
	MOVEI T1,.FHSLF		;GET OUR FORK HANDLE
	MOVE T2,[LEVTAB,,CHNTAB] ;GET ADDRESS OF INTERRUPT TABLES
	SIR			;SET INTERRUPT REGISTERS
	MOVE T1,[.TICTI,,0]	;GET "TYPIN-TERMINAL-CODE",,CHANNEL 0
	ATI			;ATTACH TERMINAL CODE TO CHANNEL 0
	MOVE T1,[.TICCA,,1]	;GET "CONTROL-A-TERMINAL-CODE",,CHANNEL 1
	ATI			;ATTACH ^A TO SOFTWARE CHANNEL 1
	MOVEI T1,.FHSLF		;GET OUR FORK HANDLE
	MOVX T2,1B0+1B1		;DECATIVATE CHANNELS 0 AND 1 UNTIL LATER
	DIC			;DEACTIVATE ^A AND TYPIN CHANNELS
	MOVEI T1,.FHSLF		;GET OUR FORK HANDLE
	EIR			;ENABLE THE SOFTWARE INTERRUPT SYSTEM

; DETERMINE IF CHKPNT IS RUNNING UNDER JOB 0
;	IF RUNNING UNDER JOB 0, AUTOMATICALLY GO INTO CHECKPOINT LOOP
;	ELSE, GO PARSE COMMAND FROM USER

	SETOM T1		;INDICATE INFO WANTED FOR OUR JOB
	MOVE T2,[-1,,T4]	;ONE ITEM DESIRED, PUT INTO T4
	MOVEI T3,.JIJNO		;GET JOB NUMBER OF THIS JOB
	GETJI			;GET JOB INFORMATION
	 JRST [	JSERR		;UNEPXECTED ERROR
		GJINF		;TRY GETTING JOB NUMBER THIS WAY
		MOVE T4,T3	;GET OUR JOB NUMBER
		JRST START1 ]	;REJOIN MAIN-LINE CODE
START1:	MOVEM T4,JOBNUM		;SAVE OUR JOB NUMBER
	JUMPE T4,[HALTF		;TERMINATE IF JOB 0
		  MOVEI T4,0
		  JRST START1]	;INCASE CONTINUE
; GET NAME OF SYSTEM 

	MOVX T1,'SYSVER'	;GET NAME OF "SYSTEM NAME" TABLE
	SYSGT			;GET TABLE # AND # OF ENTRIES
	HLRE P1,T2		;GET -<NUMBER OF ENTRIES IN TABLE>
	MOVN P1,P1		;GET NUMBER OF ENTRIES IN TABLE
	SUBI P1,1		;FORM INDEX INTO TABLE
	HRRZ P2,T2		;SAVE TABLE NUMBER

START5:	HRLZ T1,P1		;GET INDEX INTO TABLE
	HRR T1,P2		;GET TABLE NUMBER
	GETAB			;GET ONE WORD FROM TABLE
	 JSERR			;UNEXPECTED ERROR
	MOVEM T1,SYSVER(P1)	;SAVE ONE WORD OF SYSTEM NAME
	SOJGE P1,START5		;GO GET NEXT WORD OF SYSTEM NAME
SUBTTL	COMMAND PARSER AND DISPATCH

	HRROI T1,PROMPT		;GET POINTER TO PROMPT STRING
	MOVEM T1,CMDBLK+.CMRTY	;PUT RE-TYPE PROMPT POINTER IN STATE BLOCK
	HRROI T1,BUFFER		;GET POINTER TO INPUT TEXT BUFFER
	MOVEM T1,CMDBLK+.CMPTR	;SAVE POINTER TO COMMAND STRING
	MOVEM T1,CMDBLK+.CMBFP	;SAVE POINTER TO START-OF-BUFFER
	MOVE T1,[.PRIIN,,.PRIOU] ;GET PRIMARY INPUT,, OUTPUT JFN'S
	MOVEM T1,CMDBLK+.CMIOJ	;SAVE PRIMARY JFN'S
	MOVEI T1,PARSE1		;GET RE-PARSE ADDRESS
	MOVEM T1,CMDBLK+.CMFLG	;SAVE RE-PARSE ADDRESS
	SETZM CMDBLK+.CMINC	;INITIALIZE # OF CHARACTERS AFTER POINTER
	MOVEI T1,BUFSIZ*NCHPW	;GET # OF CHARACTERS IN BUFFER AREA
	MOVEM T1,CMDBLK+.CMCNT	;SAVE INITIAL # OF FREE CHARACTER POSITIONS
	HRROI T1,ATMBFR		;GET POINTER TO ATOM BUFFER
	MOVEM T1,CMDBLK+.CMABP	;SAVE POINTER TO LAST ATOM INPUT
	MOVEI T1,ATMSIZ*NCHPW	;GET # OF CHARACTERS IN ATOM BUFFER
	MOVEM T1,CMDBLK+.CMABC	;SAVE COUNT OF SPACE LEFT IN ATOM BUFFER
PARSE:	MOVEI T1,CMDBLK		;GET ADDRESS OF COMMAND STATE BLOCK
	MOVEI T2,[CMFDB (.CMINI)] ;GET FUNCTION DESCRIPTOR BLOCK
	COMND			;INITIALIZE COMMAND SCANNER JSYS

PARSE1:	MOVE T1,[CZ%NCL+.FHSLF]	;DON'T CLOSE, OUR SELF + OUR INFERIORS
	CLZFF			;RELEASE ALL JFN'S
	MOVE P,[IOWD PDLEN,PDL]	;RESET PDL
	MOVE T1,[GJFBLK,,GJFBLK+1] ;SET UP TO CLEAR GTJFN BLOCK
	SETZM GJFBLK		;CLEAR FIRST WORD OF BLOCK
	BLT T1,GJFBLK+GJFSIZ-1	;CLEAR GTJFN BLOCK

	MOVEI T1,GJFBLK		;GET ADDRESS OF GTJFN BLOCK
	MOVEM T1,CMDBLK+.CMGJB	;STORE POINTER TO GTJFN BLOCK
	MOVEI T1,CMDBLK		;GET POINTER TO COMMAND STATE BLOCK
	MOVEI T2,[CMFDB (.CMKEY,,CMDTAB)] ;GET FUNCTION BLOCK
	COMND			;DO INITIAL PARSE
	TXNN T1,CM%NOP		;VALID COMMAND ENTERED ?
	JRST PARSE5		;YES, GO DISPATCH TO PROCESSING ROUTINE
	CALL TSTCOL		;TEST COLUMN POSITION, NEW LINE IF NEEDED
	TMSG <? CHKPNT: No such CHKPNT command as ">
	MOVE T1,CMDBLK+.CMABP	;GET POINTER TO ATOM BUFFER
	PSOUT			;OUTPUT STRING ENTERED BY USER
	TMSG <"
>				;OUTPUT END-OF-MESSAGE
	JRST PARSE		;GO TRY TO GET A COMMAND AGAIN

PARSE5:	HRRZ T1,(T2)		;GET DISPATCH ADDRESS
	CALL (T1)		;PERFORM REQUESTED FUNCTION
	JRST PARSE		;GO PARSE NEXT COMMAND
	SUBTTL CHANGE (ACCOUNTING SHIFT NOW)

.CHANGE:
	MOVEI T1,CMDBLK
	MOVEI T2,[CMFDB (.CMNOI,,<TXT<ACCOUNTING SHIFT NOW>>)]
	COMND			;Do guide words
	MOVEI T2,[CMFDB (.CMCFM)] ;GET FUNCTION BLOCK FOR CONFIRMATION
	COMND			;REQUIRE CONFIRMATION
	TXNE T1,CM%NOP		;VALID END-OF-COMMAND SEEN ?
	CALLRET COMER2		;NO, ISSUE ERROR MESSAGE AND RETURN
	MOVX T1,.USCAS		;Change accounting shift function
	USAGE			; . . .
	 ERJMP [JSERR			;Oops.
		RET]			;Give up
	RET			;All done with CHANGE
SUBTTL	CHECKPOINT EVERY N MINUTES

.CHECK:	MOVEI T1,CMDBLK		;GET ADDRESS OF COMMAND STATE BLOCK
	MOVEI T2,[CMFDB (.CMNOI,,<TXT(EVERY)>)] ;GET FUNCTION BLOCK
	COMND			;GO PARSE NOISE WORD
	MOVEI T2,[CMFDB (.CMNUM,CM%SDH,^D10,NUMBER OF MINUTES,DEFINT)]
				;GET FUNCTION BLOCK FOR DECIMAL #
	COMND			;GO PARSE A NUMBER
	TXNN T1,CM%NOP		;NUMBER CORRECTLY ENTERED ?
	JRST CHECK1		;YES, GO ON
	CALL TSTCOL		;SEE IF CRLF NEEDED
	TMSG <? CHKPNT: Time interval must be a number
>				;OUTPUT ERROR MESSAGE
	RET			;RETURN AND TRY NEXT COMMAND
CHECK1:	JUMPG T2,CHECK2		;GO ON IF INTERVAL ENTERED IS POSITIVE
	CALL TSTCOL		;GO SEE IF CRLF NEEDED
	TMSG <? CHKPNT: time interval must be a positive number of minutes
>				;OUTPUT ADVISORY MESSAGE
	RET			;RETURN AND TRY NEXT COMMAND

CHECK2:	IMUL T2,[^D60*^D1000]	;CONVERT TO MILLISECONDS
	MOVEM T2,CHKTIM		;SAVE INTERVAL BETWEEN CHECKPOINTS
	MOVEI T1,CMDBLK		;GET ADDRESS OF COMMAND BLOCK
	MOVEI T2,[CMFDB (.CMNOI,,<TXT(MINUTES)>)] ;GET FUNCTION BLOCK
	COMND			;GO PARSE LAST GUIDE PHRASE
	MOVEI T2,[CMFDB (.CMCFM)] ;GET FUNCTION BLOCK FOR CONFIRMATION
	COMND			;REQUIRE CONFIRMATION
	TXNE T1,CM%NOP		;VALID END-OF-COMMAND SEEN ?
	CALLRET COMER2		;NO, ISSUE ERROR MESSAGE AND RETURN

; ENTER CONTINUOUS CHECKPOINT LOOP

CHECK5:	MOVEI T1,.FHSLF		;GET OUR FORK HANDLE
	RCM			;GET ACTIVATED CHANNELS
	MOVE T2,T1		;COPY CHANNELS TO ACTIVATE
	TXO T2,1B0		;ADD CHANNEL 0 TO ACTIVATED CHANNELS
	MOVEI T1,.FHSLF		;GET OUR FORK HANDLE
	AIC			;ACTIVATE SOFTWARE INTERRUPT CHANNELS
CHECK7:	CALL CHKPNT		;TAKE ONE CHECKPOINT PASS
	MOVE T1,CHKTIM		;GET TIME UNTIL NEXT CHECKPOINT
	DISMS			;WAIT UNTIL TIME FOR NEXT PASS
	JRST CHECK7		;GO TAKE ANOTHER CHECKPOINT PASS
SUBTTL	ENTER SINGLE CHECKPOINT

.ENTER:	MOVEI T1,CMDBLK		;GET ADDRESS OF COMMAND STATE BLOCK
	MOVEI T2,[CMFDB (.CMNOI,,<TXT(SINGLE CHECKPOINT)>)] ;GET FUNCTION BLOCK
	COMND			;GO PARSE GUIDE WORDS
	MOVEI T2,[CMFDB (.CMCFM) ] ;GET FUNCTION BLOCK FOR CONFIRMATION
	COMND			;WAIT FOR CONFIRMATION
	TXNE T1,CM%NOP		;VALID END-OF-COMMAND SEEN ?
	CALLRET COMER2		;NO, ISSUE ERROR MESSAGE AND RETURN

; CHECK THAT USER IS ALLOWED TO MAKE ENTRIES IN FACT FILE

CHKPNT:	MOVEI T1,.FHSLF		;GET FORK HANDLE OF THIS PROCESS
	RPCAP			;READ OUR PROCESS CAPABILITIES
	TXNN T3,SC%WHL!SC%OPR	;WHEEL OR OPERATOR
	JRST CKERR1		;NO, GO ISSUE ERROR MESSAGE
	MOVEI T1,.USCKP		;CHECKPOINT FUNCTION
	MOVEI T2,0		;NO ARGUMENTS
	USAGE			;PERFORM A CHECKPOINT
	 ERJMP [JSERR
		JRST .+1]
	RET			;DONE
; ERROR ROUTINES

CKERR1:	CALL TSTCOL		;SEE IF CRLF NEEDED
	TMSG <? CHKPNT: WHEEL or OPERATOR capability required to do checkpointing
>
	RET			;RETURN TO WHENCE WE CAME ...
SUBTTL	LIST DISK-STATISTICS ON FILE-SPEC

.LIST:
LIST5:	MOVEI T1,CMDBLK		;GET ADDRESS OF COMMAND STATE BLOCK
	MOVEI T2,[ CMFDB(.CMNOI,,<TXT(DISK STATISTICS ON)>)]
	COMND			;PARSE NOISE WORD
	MOVE T1,[GJFBLK,,GJFBLK+1] ;SET UP TO CLEAR GTJFN BLOCK FOR COMND
	SETZM GJFBLK		;CLEAR FIRST WORD OF BLOCK
	BLT T1,GJFBLK+GJFSIZ-1	;CLEAR GTJFN BLOCK FOR COMND JSYS
	HRROI T1,[ASCIZ/DISK-STATISTICS/] ;GET DEFAULT FILE NAME
	MOVEM T1,GJFBLK+.GJNAM	;SAVE DEFAULT FILE NAME
	HRROI T1,[ASCIZ/LST/]	;GET DEFAULT EXTENSION
	MOVEM T1,GJFBLK+.GJEXT	;SAVE DEFAULT EXTENSION
	MOVX T1,GJ%FOU		;GET "FOR OUTPUT USE" FLAG
	HLLZM T1,GJFBLK+.GJGEN	;SAVE GTJFN FLAGS
	MOVEI T1,CMDBLK		;GET ADDRESS OF COMMAND STATE BLOCK
	MOVEI T2,[ CMFDB(.CMFIL)] ;GET FUNCTION BLOCK FOR FILE-SPEC
	COMND			;PARSE OUTPUT FILE SPEC
	TXNN T1,CM%NOP		;NAME PARSED OK?
	JRST LIST10		;YES, GO GET CONFIRMATION
	CALL TSTCOL		;OUTPUT CRLF IF NEEDED
	TMSG <? CHKPNT: Invalid file specification
>				;output error message
	RET			;RETURN

LIST10:	HRROI T1,LSTFIL		;CONVERT JFN TO STRING FOR NOW
	MOVEI T3,0		;GET FILSPEC DEFAULTS
	JFNS
	HRRZ T1,T2
	RLJFN			;RELEASE JFN
	 JFCL
	MOVEI T1,CMDBLK		;GET ADDRS OF COMMAND STATE BLOCK
	MOVEI T2,[CMFDB (.CMCFM)] ;GET FCN BLOCK FOR EOL
	COMND
	TXNE T1,CM%NOP		;FAILED?
	CALLRET COMER2		;YES - ISSUE ERROR MSG
	SETOM LSTJFN		;SAY WE HAVE A FILESPEC
	RET			;RETURN
SUBTTL EXPUNGE ALREADY PROCESSED SYSTEM DATA

.EXPNG:	MOVEI T1,CMDBLK		;COMMAND STATE BLOCK
	MOVEI T2,[CMFDB (.CMNOI,,<TXT (PROCESSED SYSTEM DATA)>)]
	COMND
	MOVEI T2,[CMFDB (.CMCFM)]
	COMND			;PARSE EOL
	TXNE T1,CM%NOP
	CALLRET COMER2

;NOW GET A JFN ON THE DESIRED FILES AND DO DELETE AND KEEP
; 1 GENERATION , THEN DO EXPUNGE

	MOVX T1,GJ%SHT!GJ%OLD
	HRROI T2,[ASCIZ /PS:<ACCOUNTS>SYSTEM-DATA.BIN.0/]
	GTJFN			;GET A JFN
	 JRST [	JSERR		;REPORT UNUSUAL FAILURE
		RET]		; AND EXIT
	HRRZM T1,DATJFN		;SAVE JFN
	MOVE T2,T1		;SETUP FOR RCDIR
	MOVX T1,RC%EMO		; TO GET DIRECTORY NUMBER
	RCDIR
	MOVEM T3,DIRNUM		;SAVE IT
	MOVE T1,T3		;NOW GET CURRENT ALLOCATION
	GTDAL
	MOVEM T2,HIGHV		;SAVE CURRENT USAGE

	MOVE T1,DATJFN		;GET THE JFN
	MOVEI T2,1		;KEEP 1 (THE CURRENT)
	DELNF			;DELETE THEM
	 JRST [	JSERR		;REPORT LOSAGE
		JRST EXPNGX]	;AND EXIT
	MOVEM T2,CURRV		;NUMBER OF FILES DELETED
	MOVEI T1,0		;NOTHING SPECIAL
	MOVE T2,DIRNUM		;DIRECTORY NUMBER
	DELDF			;DO EXPUNGE
	 ERJMP [JSERR
		JRST .+1]
EXPNGX:	MOVE T1,DATJFN		;RELEASE THIS
	RLJFN
	 JFCL
	MOVE T1,DIRNUM		;GET ALLOCATION NOW
	GTDAL
	SUBM T2,HIGHV		;GET DIFFERENCE FROM BEFORE
	TMSG <	[>
	SKIPN T2,CURRV		;ANYTHING DELETED?
	JRST [	TMSG <No>
		JRST EXPNX1]
	MOVEI T1,.PRIOU
	MOVEI T3,^D10		;DECIMAL NUMBER
	NOUT
	 JSERR
EXPNX1:	TMSG < file(s) deleted, >
	MOVN T2,HIGHV		;PAGES FREED
	MOVEI T1,.PRIOU
	MOVEI T3,^D10
	NOUT
	 JSERR
	TMSG < page(s) freed]
>
	RET			;DONE
SUBTTL COPY SYSTEM DATA TO FILE-SPEC

.COPY:	MOVEI T1,CMDBLK		;COMMAND STATE BLOCK
	MOVEI T2,[CMFDB (.CMNOI,,<TXT (SYSTEM DATA TO)>)]
	COMND			;PARSE GUIDE WORDS
	MOVE T1,[GJFBLK,,GJFBLK+1]
	SETZM GJFBLK		;CLEAR GTJFN BLOCK
	BLT T1,GJFBLK+GJFSIZ-1	;CLEAR ENTIRE GTJFN BLOCK
	MOVEI T1,GJFBLK		;GET ADDRESS OF GTJFN BLOCK
	MOVEM T1,CMDBLK+.CMGJB	;SAVE ADDRESS OF GTJFN BLOCK FOR COMND JSYS
	HRROI T1,[ASCIZ "USAGE"] ;GET DEFAULT FILE NAME
	MOVEM T1,GJFBLK+.GJNAM	;SAVE DEFAULT FILE NAME
	HRROI T1,[ASCIZ "OUT"]	;GET DEFAULT EXTENSION STRING
	MOVEM T1,GJFBLK+.GJEXT	;SAVE DEFAULT EXTENSION POINTER
	MOVX T1,GJ%FOU		;FILE FOR OUTPUT USE
	MOVEM T1,GJFBLK
	MOVEI T1,CMDBLK		;GET ADDRESS OF COMMAND STATE BLOCK
	MOVEI T2,[CMFDB (.CMFIL) ] ;GET FUNCTION BLOCK
	COMND			;PARSE NEXT PART OF COMMAND
	TXNN T1,CM%NOP		;ABLE TO GET A JFN ?
	JRST COPY1		;YES, GO ON
	CALL TSTCOL		;GO SEE IF CRLF NEEDED
	TMSG <? CHKPNT: Invalid file specification
>
	RET			;RETURN AND DO NEXT COMMAND

COPY1:	MOVEM T2,USGJFN		;SAVE JFN OF USAGE FILE
	MOVEI T2,[CMFDB (.CMCFM)]
	COMND			;PARSE EOL
	TXNE T1,CM%NOP
	CALLRET COMER2		;ISSUE MESSAGE AND RETURN
	;..
	;..

;NOW GET A JFN ON THE CURRENT SYSTEM-DATA FILE AND FIGURE
;OUT THE HIGHEST GENERATION NUMBER WE WILL WANT TO COPY

	MOVX T1,GJ%SHT!GJ%OLD
	HRROI T2,[ASCIZ /PS:<ACCOUNTS>SYSTEM-DATA.BIN.0/]
	GTJFN
	 JRST [	TMSG <?CHKPNT: Could not find SYSTEM-DATA file>
		JSERR
		RET]
	MOVE T2,T1		;COPY TO T2 FOR JFNS
	HRROI T1,HIGHV		;PLACE FOR STRING
	MOVX T3,<FLD (.JSAOF,JS%GEN)>
	JFNS			;GET GENERATION NUMBER
	MOVE T1,T2		;GET JFN BACK
	RLJFN			;RELEASE IT
	 JSHLT
	MOVEI T1,.USCLS		;CLOSE OFF USAGE FILE
	SETZ T2,
	USAGE			;...
	 ERJMP [JSERR
		RET]		;REPORT LOSAGE
	MOVX T1,GJ%SHT!GJ%IFG!GJ%OLD
	HRROI T2,[ASCIZ /PS:<ACCOUNTS>SYSTEM-DATA.BIN.*/]
	GTJFN			;GET JFN ON ALL DATA FILES
	 JRST [	JSERR		;REPORT ERROR
		RET]		; AND EXIT
	MOVEM T1,DATJFN		;SAVE IT

;NOW OPEN USAGE OUTPUT FILE

	MOVE T1,USGJFN		;GET OUTPUT JFN
	MOVX T2,7B5+OF%WR	;CREATE FILE
	OPENF
	 JRST [	TMSG <?CHKPNT: Could not open USAGE file.>
		JSERR
		RET]
	CALL FILHDR		;PUT OUT HEADER RECORD
	;..
	;..

;NOW LOOP OVER ALL EXISTING FILES AND CREATE USAGE FILE

COPY2:	HRRZ T1,DATJFN		;GET INPUT JFN
	MOVX T2,44B5+OF%RD	;36BIT MODE, READ
	OPENF			;OPEN DATA FILE
	 JRST [	TMSG <?CHKPNT: Could not open file: >
		HRRZ T2,DATJFN
		MOVEI T1,.PRIOU
		MOVEI T3,0
		JFNS		;REPORT FILE NAME
		JSERR		; THEN ERROR
		TMSG <% File being skipped...>
		JRST COPY3]
	CALL MAKUSG		;CONVERT FILE

;ALL DONE - CLOSE FILE AND CHECK IF DONE

	HRRZ T1,DATJFN		;CLOSE FILE
	TXO T1,CO%NRJ		; AND RETAIN JFN
	CLOSF
	 JSHLT			;IMPOSSIBLE
COPY3:	HRRZ T2,DATJFN		;NOW SEE IF THIS WAS THE LAST
	HRROI T1,CURRV		;BUFFER FOR GENERATION #
	MOVX T3,<FLD (.JSAOF,JS%GEN)>
	JFNS
	HRROI T1,CURRV
	HRROI T2,HIGHV
	STCMP			;COMPARE STRINGS
	JUMPE T1,COPY4		;MATCH - DONE
	MOVE T1,DATJFN		;NOMATCH - STEP TO NEXT FILE
	GNJFN			;...
	 JRST [	JSERR		;BETTER NOT HAPPEN
		RET]
	JRST COPY2
;ALL DONE - CLOSE OUTPUT AND RETURN

COPY4:	MOVE T1,USGJFN
	CLOSF			;CLOSE OUPUT FILE
	 JSERR
	RET			;RETURN
SUBTTL  DISK-STATISTICS

.DISK:	MOVEI T1,CMDBLK		;GET ADDRESS OF COMMAND STATE BLOCK
	MOVEI T2,[CMFDB (.CMNOI,,<TXT(FOR STRUCTURE)>)]
	COMND			;PARSE NOISE PHRASE
	HRROI T2,STRBUF		;INIT STRING
	MOVEM T2,STRPTR		; POINTER
	MOVEI T2,[CMFDB (.CMDEV,CM%SDH,,<STRUCTURE NAME>,<[ASCIZ "DSK"]>)]
	COMND
	TXNE T1,CM%NOP
	JRST [	TMSG <? CHKPNT: Invalid structure name given
>
		 RET]
	MOVE P1,T2		;SAVE DESIGNATOR
	MOVEI T2,[CMFDB (.CMCFM) ] ;GET FUNCTION BLOCK FOR CONFIRM
	COMND			;WAIT FOR CONFIRMATION
	TXNE T1,CM%NOP		;VALID END-OF-COMMAND SEEN ?
	CALLRET COMER2		;NO, ISSUE ERROR MESSAGE AND RETURN
	MOVE T1,P1		;GET DESIGNATOR
	DVCHR			;GET ITS CHARACTERISTICS
	LDB T1,[POINTR T2,DV%TYP]
	CAIE T1,.DVDSK		;MAKE SURE IT IS A DISK
	 JRST [	TMSG <?CHKPNT: Invalid structure name given
>
		 RET]
	MOVE T2,P1		;DESIGNATOR AGAIN
	MOVE T1,STRPTR		;POINTER TO BUFFER
	DEVST			;CONVERT TO STRING
	 JRST [	JSERR
		 RET]		;HANDLE ERROR
	MOVEI T2,":"		;PUT ON TERMINATING COLON
	IDPB T2,T1
	MOVEM T1,STRPTR		;UPDATED STRING POINTER
	HRROI T1,STRNAM		;GET STR NAME STRING ALONE
	MOVE T2,P1
	DEVST
	 JFCL			;IGNORE 

	CALL GSTINF		;GET STRUCTURE INFO
				;INTO TYPWRD
; OPEN LISTING FILE IF ANY SPECIFIED

	MOVE T1,LSTJFN		;GET FLAG
	SETOM LSTJFN		;MARK NON-EXISTANT
	JUMPE T1,DODSK		;NONE - PROCEEDE
	MOVX T1,GJ%FOU!GJ%SHT
	HRROI T2,LSTFIL		;FILE SPEC FROM BEFORE
	GTJFN			;GET A JFN ON IT
	 ERJMP	[TMSG <%Cannot get a JFN on listing file.>
		 JSERR
		 JRST DODSK]
	MOVX T2,<FLD (7,OF%BSZ)+OF%WR>
	OPENF
	 ERJMP	[TMSG <%Cannot open listing file.>
		 JSERR
		 JRST DODSK]
	MOVEM T1,LSTJFN		;SAVE JFN FOR LATER
;GET FIRST DIRECTORY NUMBER FOR THIS STRUCTURE

DODSK:	MOVE T1,STRPTR		;POINT TO STRUCTURE
	HRROI T2,[ASCIZ "<*>"]
	MOVEI T3,0
	SOUT			;BUILD FILESPEC
	MOVX T1,RC%AWL		;ALLOW STARS
	HRROI T2,STRBUF		;POINT TO STRING
	RCDIR			;GET DIRECTORY NUMBER
	 ERJMP [TMSG <?Unable to access directories>
		JSERR
		JRST DKERRX]
	MOVEM T3,DIRNUM		;SAVE FIRST NUMBER


;CHECK PROCESS CAPABILITIES

	MOVEI T1,.FHSLF		;GET OUR FORK HANDLE
	RPCAP			;READ PROCESS CAPABILITIES
	TXNN T3,SC%WHL!SC%OPR	;WHEEL OR OPERATOR POSSIBLE ?
	CALLRET DKERR3		;NO, GO ISSUE MESSAGE AND RETURN

; ACTIVATE SOFTWARE INTERRUPT CHANNEL 1 FOR ^A (FOR STATUS REPORT)

	MOVEI T1,.FHSLF		;GET OUR FORK HANDLE
	RCM			;GET ACTIVATED CHANNELS
	MOVE T2,T1		;COPY ACTIVATED CHANNELS
	TXO T2,1B1		;ADD CHANNEL 1
	MOVEI T1,.FHSLF		;GET OUR FORK HANDLE
	AIC			;ACTIVATE CHANNEL 1

; OUTPUT HEADER FOR LISTING FILE IF LISTING BEING MADE

	MOVEI T1,0		;GET INITIAL PAGE NUMBER
	MOVEM T1,PAGNUM		;INITIALIZE LISTING PAGE NUMBER
	MOVEI T1,1		;GET INITIAL LINE NUMBER
	MOVEM T1,LINNUM		;INITIALIZE LINE NUMBER ON PAGE
	SKIPG LSTJFN		;MAKING A LISTING FILE ?
	JRST DODSK2		;NO, GO CONNECT TO FIRST DIRECTORY
	CALL WRTHDR		;WRITE A HEADER ON THE LISTING FILE
	SETZM ASTEND		;CLEAR POINTER
	;..
	;..
; LOOP OVER ALL DIRECTORIES

; CLEAR TABLES AND INITIALIZE TABLE POINTERS

DODSK2:	SETZM TOTFIL		;CLEAR TOTAL NUMBER OF FILES FOR THIS DIRECTORY
	SETZM TOTPGS		;CLEAR TOTAL NUMBER OF PAGES FOR THIS DIRECTORY
	SETZM TOTACT		;CLEAR TOTAL NUMBER OF ACCOUNTS FOR THIS DIR
	SKIPN T2,ASTEND		;FIRST TIME HERE?
	JRST DODK2A		;YES - SKIP CLEAR
	SETZM STRACT		;ELSE CLEAR STRING SPACE
	MOVE T1,[STRACT,,STRACT+1] ;ALREADY USED
	BLT T1,-1(T2)		;...
DODK2A:	MOVE T1,[ACTTAB,,ACTTAB+1] ;SET UP TO CLEAR ALPHA ACCOUNT TABLE
	SETZM ACTTAB		;CLEAR FIRST WORD OF TABLE
	BLT T1,ACTTAB+ACTSIZ-1	;CLEAR ALPHA ACCOUNT TABLE
	MOVE T1,[ACPTAB,,ACPTAB+1] ;SET UP TO CLEAR ALPHA ACCOUNT PAGES TABLE
	SETZM ACPTAB		;CLEAR FIRST WORD OF TABLE
	BLT T1,ACPTAB+ACPSIZ-1	;CLEAR ALPHA ACCOUNT PAGE COUNT TABLE

	MOVEI T1,ACTSIZ		;GET CURRENT,,MAX SIZE OF ALPHA ACCT TABLE
	MOVEM T1,ACTTAB		;SAVE INITIAL TABLE HEADER WORD
	MOVEI T1,STRACT		;GET ADDRESS OF ALPHA ACCOUNT STRINGS
	MOVEM T1,ASTEND		;SAVE ADDRESS OF NEXT FREE WORD
	MOVEI T1,ACPTAB		;GET ADDRESS OF FIRST ENTRY IN SIZE TABLE
	MOVEM T1,ACPEND		;SAVE POINTER TO NEXT ENTRY IN SIZE TABLE
; GET AN INDEXABLE FILE HANDLE FOR ALL FILES IN THE CURRENT DIRECTORY

	HRROI T1,FILBUF		;CONSTRUCT FILESPEC
	MOVE T2,DIRNUM		;FORM DIRECTORY NAME
	DIRST
	 JRST [	JSERR
		JRST DODK45]	;IGNORE THIS ONE
	HRROI T2,[ASCIZ "*.*.*"]
	MOVEI T3,0
	SOUT			;APPEND FILESPEC
	MOVEI T1,GTJARG		;MOVE ARGUMENT TABLE ADDRESS TO T1
	HRROI T2,FILBUF		;ALL FILES
	GTJFN			;GET AN INDEXABLE FILE HANDLE
	 JRST [	CAIE T1,GJFX32	;ERROR - WAS IT NO FILES IN DIRECTORY ?
		JSERR		;NO, ISSUE ERROR MESSAGE
		JRST DODK45 ]	;GO ON TO NEXT DIRECTORY
	MOVEM T1,FILJFN		;SAVE JFN FOR ALL FILES IN DIRECTORY
	HRRZ T2,T1		;MAKE SPECIAL COPY OF
	HRROI T1,STRDIR		; STRUCTURE AND DIRECTORY NAME
	MOVX T3,1B2+1B5+1B35	; FOR ACCOUNT FILE BLOCK
	JFNS
	HRROI T1,DIRNAM		;ISOLATE DIRECTORY NAME
	MOVX T3,1B5
	JFNS

;GET DIRECTORY INFORMATION

	MOVEI T1,GTDBSZ		;SETUP BUFFER
	MOVEM T1,GTDBUF+.CDLEN	; LENGTH OF ITEMS WANTED
	MOVE T1,DIRNUM		;DIRECTORY NUMBER
	MOVEI T2,GTDBUF		;POINT TO BUFFER
	SETZ T3,		;NO PASSWORD
	GTDIR
	 ERJMP [JSERR		;LOSING ERROR
		JRST DODK45]	;SKIP DIRECTORY
	MOVE T2,[^D999999]	;MAX ALLOWABLE RANGE
	MOVM T1,GTDBUF+.CDLIQ	;GET LOGGED IN QUOTA
	CAML T1,[^D1000000]	;VALID RANGE?
	MOVEM T2,GTDBUF+.CDLIQ	;STUFF MAX ALLOWED
	MOVM T1,GTDBUF+.CDLOQ	;CHECK LOGGED OUT QUOTA
	CAML T1,[^D1000000]
	MOVEM T2,GTDBUF+.CDLOQ
	LDB T1,[POINTR <GTDBUF+.CDMOD>,CD%DIR]
	STOR T1,FOND,TYPWRD	;SAVE FILES ONLY INDICATOR
	;..
; LOOP OVER ALL FILES IN THE CURRENT DIRECTORY

DODSK3:	AOS TOTFIL		;INCREMENT # OF FILES IN CURRENT DIRECTORY
	MOVE T1,[ACTBUF,,ACTBUF+1] ;SET UP TO CLEAR ACCOUNT BUFFER
	SETZM ACTBUF		;CLEAR FIRST WORD OF ACCOUNT BUFFER
	BLT T1,ACTBUF+ACTBSZ-1	;CLEAR ASCIZ ACCOUNT BUFFER

	HRRZ T1,FILJFN		;GET JFN OF CURRENT FILE
	HRROI T2,ACTBUF		;GET POINTER TO ASCIZ ACCOUNT BUFFER
	GACTF			;GET ACCOUNT FOR CURRENT FILE
	 JRST [ JSERR		;UNEXPECTED ERROR
		JRST DODSK9 ]	;GO ON TO NEXT FILE IN DIRECTORY
	 JRST DODSK6		;ALPHANUMERIC ACCOUNT - SEE IF IN TABLE

;CONVERT ACCOUNT NUMBER TO STRING

	HRROI T1,ACTBUF		;ASCIZ POINTER
	TLZ T2,(7B2)		;CLEAR THIS JUNK
	MOVEI T3,^D10		;DECIMAL RADIX
	NOUT			;CONVERT TO STRING
	 JRST [	JSERR
		JRST .+1]

; HERE FOR ALPHANUMERIC ACCOUNTS

DODSK6:	MOVEI T1,ACTTAB		;GET ADDRESS OF TABLE HEADER WORD
	HRROI T2,ACTBUF		;GET POINTER TO ACCOUNT STRING
	TBLUK			;SEE IF STRING ALREADY IN TABLE
	TXNN T2,TL%EXM		;EXACT MATCH ?
	JRST DODSK7		;NO, GO ADD STRING TO TABLE
	HRRZ AT,(T1)		;YES, GET ADDRESS OF SIZE ENTRY
	JRST DODK7A		;GO GET SIZE OF THE FILE
; HERE TO ADD A NEW ALPHANUMERIC ACCOUNT STRING TO TABLE

DODSK7:	HRRO T1,ASTEND		;FORM POINTER TO WHERE STRING WILL GO
	HRROI T2,ACTBUF		;GET POINTER TO WHERE STRING IS NOW
	SETZM T3		;TERMINATE ON NULL BYTE
	SOUT			;MOVE STRING TO ALPHA ACCOUNT STRING AREA
	HRLZ T2,ASTEND		;GET ADDRESS WHERE STRING WAS JUST MOVED
	IBP T1			;INCREMENT POINTER PAST TEXT JUST MOVED
	AOS T1			;INCREMENT ADDRESS OF FREE POINTER
	HRRZM T1,ASTEND		;SAVE NEW FREE SPACE POINTE
	HRR T2,ACPEND		;GET ADDRESS OF ENTRY IN SIZE TABLE
	MOVEI T1,ACTTAB		;GET ADDRESS OF TABLE HEADER WORD
	TBADD			;ADD STRING TO TABLE
	MOVE AT,ACPEND		;GET ADDRESS OF NEXT ENTRY
	CAIL AT,ACPTAB+ACPSIZ	;AT END OF SIZE TABLE ?
	CALL DKERR2		;YES, ISSUE MESSAGE
	movei t1,.atsiz		;get size of table entries
	addm t1,acpend		;update pointer to next free entry
	AOS TOTACT		;INCREMENT # OF ACCOUNTS FOR THIS DIRECTORY

; GET SIZE OF CURRENT FILE AND ADD TO # OF PAGES FOR THIS ALPHA ACCOUNT

DODK7A:	HRRZ T1,FILJFN		;GET JFN OF CURRENT FILE
	SIZEF			;GET SIZE OF CURRENT FILE
	 JRST [	JSERR		;UNEXPECTED ERROR
		JRST DODSK9 ]	;GO ON TO NEXT FILE
	ADDM T3,.ATPGS(AT)	;ADD SIZE OF THIS FILE TO ACCOUNT TOTAL
	ADDM T3,TOTPGS		;ADD SIZE OF THIS FILE TO DIRECTORY TOTAL
	AOS .ATFIL(AT)		;INCREMENT # OF FILES WITH THIS ACCOUNT

; DONE WITH CURRENT FILE - GO ON TO NEXT FILE IN DIRECTORY

DODSK9:	MOVE T1,FILJFN		;GET INDEXABLE FILE HANDLE
	GNJFN			;GET NEXT JFN IN CURRENT DIRECTORY
	 JRST [	CAIE T1,GNJFX1	;ERROR - WAS IT NO MORE FILES IN SPECIFICATION ?
		JSERR		;NO, ISSUE ERROR MESSAGE
		JRST DODK10 ]	;GO OUTPUT CURRENT ACCOUNT INFORMATION
	JRST DODSK3		;GO ACCUMULATE INFORMATION ON NEXT FILE
;NOW DUMP DATA INTO SYSTEM USAGE FILE

DODK10:	HLRZ AT,ACTTAB		;GET # OF ENTRIES IN TABLE
	JUMPE AT,DODK40		;IF NO ACCOUNTS, GO TO NEXT DIR.
	MOVEI T1,.ATSIZ		;SET ITEM SIZE IN TABLE
	HRRM T1,ACTTAB		; FOR USAGE JSYS
	MOVEI T1,.USENT		;WRITE DISK STATS
	MOVEI T2,DSKBLK		;POINTER TO DATA
	USAGE
	 ERJMP [JSERR		;REPORT LOSAGE
		JRST .+1]	; AND CONTINUE
	;..
; HERE WHEN DONE WITH EACH DIRECTORY

DODK40:	SKIPLE LSTJFN		;listing of statistics wanted ?
	CALL LSTDSK		;YES, GO OUTPUT DISK STAT LISTING

DODK45:	MOVX T1,RC%STP!RC%AWL
	HRROI T2,STRBUF
	MOVE T3,DIRNUM		;WHERE WE ARE
	RCDIR			;TO NEXT
	 ERJMP [JSERR		;ERROR
		JRST DODK50]
	TXNE T1,RC%NMD		;MORE?
	JRST DODK50		;NO - DONE
	MOVEM T3,DIRNUM		;YES - SAVE NUMBER
	JRST DODSK2		;DO NEXT DIR

DODK50:	SKIPG LSTJFN		;USING A LISTING FILE ?
	JRST DODK60		;NO, GO TURN OFF OUT CAPABILITIES
	HRRZ T1,LSTJFN		;GET LISTING FILE JFN
	CLOSF			;CLOSE LISTING FILE
	 JSERR			;UNEXPECTED ERROR

DODK60:	SETZM LSTJFN		;INDICATE NO LISTING FILE FOR DISK STATS
	MOVEI T1,.FHSLF		;GET OUR FORK HANDLE
	MOVX T2,1B1		;GET SOFTWARE INTERRUPT CHANNEL 1 BIT
	DIC			;DEACTIVATE CHANNEL 1 (CONTROL-A)
	RET			;RETURN TO WHENCE WE CAME ...
;DISK STATISTICS TEMPLATE FOR USAGE JSYS

DSKBLK:	USENT. (.UTFLU,1,1)	;FILE USAGE RECORD TYPE
	USSTR. (<-1,,STRNAM>)	;STRUCTURE NAME STRING
	USDIR. (<-1,,DIRNAM>)	;DIRECTORY NAME STRING
	USNRF. (TOTACT)		;TOTAL NUMBER OF ACCOUNTS
	USTUS. (TOTPGS)		;TOTAL NUMBER OF PAGES
	USTNF. (TOTFIL)		;TOTAL NUMBER OF FILES
	USLIQ. (GTDBUF+.CDLIQ)	;LOGGED IN QUOTA
	USLOQ. (GTDBUF+.CDLOQ)	;LOGGED OUT QUOTA
	USLLI. (GTDBUF+.CDLLD)	;DATE/TIME LAST LOGGED IN
	USAGE. (.USDSX,0,.USOCT,0,TYPWRD) ;STR/DIR INFO
	USDSK. (ACTTAB)		;ACCOUNT TABLE INFO
	USPVR. (<ENTVEC+2>)	;VERSION NUMBER
	0			;END OF TABLE
;ROUTINE TO GET VARIOUS BITS OF STRUCTURE INFO INTO TYPWRD
; P1/	DEVICE DESIGNATOR

GSTINF:	MOVEM P1,STSBLK		;SETUP DEVICE DESIG.
	MOVE T1,[2,,.MSGSS]
	MOVEI T2,STSBLK
	MSTR			;GET STRUCTURE STATUS
	LDB T1,[POINTR <STSBLK+.MSGST>,MS%PS]
	STOR T1,PSF,TYPWRD	;PUBLIC STRUCTURE BIT
	LDB T1,[POINTR <STSBLK+.MSGST>,MS%DOM]
	STOR T1,STYP,TYPWRD	;FOREIGN/DOMESTIC BIT
	LDB T1,[POINTR <STSBLK+.MSGST>,MS%PPS]
	STOR T1,PPSF,TYPWRD	;PRIMARY PUBLIC STR BIT
	MOVEI T1,RH2TYP		;RH20 TYPE CODE
	STOR T1,KTYP,TYPWRD

;SETUP FOR FINDING UNIT IN STR TO GET DEVICE TYPE STUFF

	SETOM RNUBLK+.MSRCH	;INIT FOR FIRST UNIT
	SETOM RNUBLK+.MSRCT
	SETOM RNUBLK+.MSRUN
	MOVEI T1,RP4TYP		;DEFAULT TO RP04
	STOR T1,DTYP,TYPWRD

GSTIN1:	CALL GTUSTS		;GET UNIT STATUS
	 RET			;NO MORE UNITS
	CALL STRMAT		;MATCH STR WANTED?
	 JRST GSTIN1		;NO - TRY NEXT
	LDB T1,[POINTR <RNUBLK+.MSRST>,MS%TYP]
	MOVEI T2,RP4TYP		;DEFAULT IF NONE FOUND
	CAIN T1,.MSRP5		;RP05?
	MOVEI T2,RP5TYP
	CAIN T1,.MSRP6		;RP06
	MOVEI T2,RP6TYP
	STOR T2,DTYP,TYPWRD	;STORE DEVICE TYPE CODE
	RET			;RETURN

;ROUTINE TO READ-NEXT-UNIT STATUS

GTUSTS:	HRROI T1,FILBUF		;PLACE FOR STRUCTURE NAME
	MOVEM T1,RNUBLK+.MSRSN
	SETZM RNUBLK+.MSRSA	;DONT CARE ABOUT ALIAS
	MOVE T1,[.MSRLN,,.MSRNU] ; LEN,,FCN
	MOVEI T2,RNUBLK		;ADDRS OF ARGS
	MSTR			;GET STATUS
	 ERJMP [MOVEI T1,.FHSLF	;OURSELVES
		GETER
		HRRZ T1,T2
		CAIE T1,MSTX18	;NO MORE UNITS?
		JSERR		;ERROR
		RET]		;NO - RETURN
	RETSKP			;GOOD RETURN

;ROUTINE TO CHECK IF THIS UNIT IS OFF-LINE AND PART OF
;THE STRUCTURE WE WANT (STRNAM)

STRMAT:	MOVE T1,RNUBLK+.MSRST	;GET UNIT STATUS
	TXNN T1,MS%MNT		;MOUNTED?
	RET			;OFF-LINE, DIAG, OR BAD
	HRROI T1,FILBUF		;CONSIDER THIS NAME
	HRROI T2,STRNAM		;REQUESTED STRUCTURE
	STCMP			;MATCH STRINGS
	JUMPN T1,R		;RETURN IF NO MATCH
	RETSKP			;SKIP IF MATCH
; ROUTINE TO OUTPUT DISK STATISTICS TO LISTING FILE FOR EACH DIRECTORY

LSTDSK:	HRRZ T1,LSTJFN		;GET LISTING FILE JFN
	MOVE T2,DIRNUM		;GET CURRENT DIRECTORY NUMBER
	DIRST			;OUTPUT NAME OF CURRENT DIRECTORY
	 JSERR			;UNEXPECTED ERROR
	CALL TSTPAG		;SEE IF NEW PAGE NEEDED

	;..
; LOOP OVER ALL ALPHANUMERIC ACCOUNTS

LSTDS5:	HLRZ P1,ACTTAB		;GET # OF ENTRIES IN ALPHA ACCOUNT TABLE
	JUMPE P1,LSTDS8		;IF NO ALPHA ACCOUNTS, GO ON
	MOVN P1,P1		;GET NEGATIVE NUMBER OF ENTRIES
	HRLZ P1,P1		;GET - # OF ENTRIES,, 0
	HRRI P1,ACTTAB+1	;GET ADDRESS OF FIRST ENTRY

LSTDS6:	HRRZ T1,LSTJFN		;GET LISTING FILE JFN
	HRROI T2,[ASCIZ "		"] ;GET TABS
	SETZM T3		;TERMINATE ON NULL BYTE
	SOUT			;OUTPUT A TAB
	HLRO T2,(P1)		;GET POINTER TO ACCOUNT STRING
	MOVEI T3,ACTMAX		;GET MAX # OF CHARACTERS TO MOVE
	MOVEI T4,.CHNUL		;GET TERMINATING BYTE (NULL)
	SOUT			;OUTPUT ACCOUNT STRING
	SUBI T3,ACTMAX		;COMPUTE -<# OF CHARACTERS IN ACCOUNT STRING>
	MOVM T3,T3		;GET NUMBER OF CHARACTERS IN ACCOUNT STRING
	CAILE T3,^D8		;ANOTHER TAB REQUIRED ?
	JRST LSTD6A		;NO, GO SEE IF CRLF NEEDED
	HRRZ T1,LSTJFN		;YES, GET LISTING FILE JFN
	MOVEI T2,.CHTAB		;GET A TAB
	BOUT			;OUTPUT ANOTHER TAB FOR SPACING
	JRST LSTDS7		;GO ON
LSTD6A:	CAIG T3,^D15		;MORE THAN 15 COLUMNS ?
	JRST LSTDS7		;NO, GO OUTPUT A TAB
	call tstpag		;go output a crlf, see if new page needed
	HRRZ T1,LSTJFN		;GET LISTING FILE JFN
	HRROI T2,[ASCIZ "			"] ;GET THREE TABS
	SETZM T3		;TERMINATE ON NULL BYTE
	SOUT			;MAKE COLUMNS LINE UP
LSTDS7:	HRRZ T1,LSTJFN		;GET LISTING FILE JFN
	HRROI T2,[ASCIZ "	"] ;GET A TAB
	SETZM T3		;TERMINATE ON NULL
	SOUT			;OUTPUT A TAB
	HRRZ AT,(P1)		;GET ADDRESS OF ENTRY FOR THIS ACCOUNT
	HRRZ T1,LSTJFN		;GET LISTING FILE JFN
	MOVE T2,.ATPGS(AT)	;GET # OF PAGES FOR THIS ACCOUNT
	MOVEI T3,^D10		;GET DECIMAL RADIX
	TXO T3,1B2+6B17		;USE LEADING FILLER
	NOUT			;OUTPUT NUMBER OF PAGES
	 JSERR			;UNEXPECTED ERROR
	HRROI T2,[ASCIZ "	"] ;GET A TAB
	SETZM T3		;TERMINATE ON NULL
	SOUT			;OUTPUT PUNCTUATION
	MOVE T2,.ATFIL(AT)	;GET # OF FILES FOR THIS ACCOUNT
	MOVEI T3,^D10		;GET DECIMAL RADIX
	TXO T3,1B2+6B17		;USE LEADING FILLER
	NOUT			;OUTPUT # OF FILES FOR THIS ACCOUNT
	 JSERR			;UNEXPECTED ERROR
	call tstpag		;output a crlf, see if new page needed
	AOBJN P1,LSTDS6		;LOOP OVER ALL ALPHANUMERIC ACCOUNTS
; HERE WHEN DONE WITH ALL ACCOUNTS FOR THIS DIRECTORY

LSTDS8:	call tstpag		;go see if new page needed
	HRRZ T1,LSTJFN		;GET LISTING FILE JFN
	HRROI T2,[ASCIZ "  Total of "] ;GET FIRST PART OF SUMMARY LINE
	SETZM T3		;TERMINATE ON NULL BYTE
	SOUT			;OUTPUT INITIAL PART OF SUMMARY
	MOVE T2,TOTPGS		;GET TOTAL # OF PAGES FOR THIS DIRECTORY
	MOVEI T3,^D10		;GET DECIMAL RADIX
	NOUT			;OUTPUT # OF PAGES FOR THIS DIRECTORY
	 JSERR			;UNEXPECTED ERROR
	HRROI T2,[ASCIZ " page"];GET INITIAL PART OF STRING
	SETZM T3		;TERMINATE ON NULL
	SOUT			;OUTPUT STRING
	MOVEI T2,"s"		;GET PLURAL SUFFIX
	MOVE T3,TOTPGS		;GET TOTAL NUMBER OF PAGES
	CAIE T3,1		;JUST ONE PAGE ?
	BOUT			;NO, OUTPUT SUFFIX
	HRROI T2,[ASCIZ " in "] ;GET STRING
	SETZM T3		;TERMINATE ON NULL
	SOUT			;OUTPUT REST OF STRING
	MOVE T2,TOTFIL		;GET TOTAL NUMBER OF FILES FOR CURRENT DIR
	MOVEI T3,^D10		;GET DECIMAL RADIX
	NOUT			;OUTPUT TOTAL NUMBER OF FILES
	 JSERR			;UNEXPECTED ERROR
	HRROI T2,[ASCIZ " file"] ;GET FIRST PART OF STRING
	SETZM T3		;TERMINATE ON NULL BYTE
	SOUT			;OUTPUT END OF SUMMARY LINE
	MOVEI T2,"s"		;GET PLURAL SUFFIX
	MOVE T3,TOTFIL		;GET TOTAL NUMBER OF FILES
	CAIE T3,1		;EXACTLY ONE FILE ?
	BOUT			;NO, OUTPUT AN 'S'
	HRROI T2,[ASCIZ " in "]
	SETZM T3		;TERMINATE ON NULL
	SOUT			;OUTPUT REMAINDER OF STRING
	MOVE T2,TOTACT		;GET NUMBER OF ACCOUNTS FOR THIS DIRECTORY
	MOVEI T3,^D10		;GET DECIMAL RADIX
	NOUT			;OUTPUT NUMBER OF ACCOUNTS IN THIS DIRECTORY
	 JSERR			;UNEXPECTED ERROR
	HRROI T2,[ASCIZ " account"] ;GET FIRST PART OF STRING
	SETZM T3		;TERMINATE ON NULL
	SOUT			;OUTPUT END-OF-LINE
	MOVEI T2,"s"		;GET PLURAL SUFFIX
	MOVE T3,TOTACT		;GET TOTAL NUMBER OF ACCOUNTS
	CAIE T3,1		;EXACTLY ONE ACCOUNT ?
	BOUT			;NO, OUTPUT PLURAL SUFFIX
	CALL TSTPAG		;EXTRA CRLF
	CALLRET TSTPAG		;OUTPUT A CRLF
; SUBROUTINES FOR LISTING FILE PRODUCTION

; ROUTINE TO OUTPUT A FORM FEED AND A HEADER LINE ON A NEW PAGE OF LISTING

WRTHDR:	HRRZ T1,LSTJFN		;GET LISTING FILE JFN
	MOVEI T2,.CHFFD		;GET A FORMFEED
	BOUT			;NEW PAGE
	AOS PAGNUM		;INCREMENT CURRENT PAGE NUMBER
	HRRZ T1,LSTJFN		;GET LISTING FILE JFN
	HRROI T2,[ASCIZ "Disk Utilization Statistics		"]
	setzm t3		;terminate on null byte
	sout			;output disk statistics header line
	HRRZ T1,LSTJFN		;GET LISTING FILE JFN
	SETOM T2		;USE CURRENT DATE AND TIME
	SETZM T3		;USE NORMAL FORMAT
	ODTIM			;OUTPUT THE DATE AND TIME
	HRROI T2,[ASCIZ "	Page "]
	SETZM T3		;TERMINATE ON NULL BYTE
	SOUT			;OUTPUT REST OF STRING
	move t2,pagnum		;get current page number
	movei t3,^D10		;get decimal radix
	nout			;output current page number
	 jserr			;unexpected error
	HRRZ T1,LSTJFN		;GET LISTING FILE JFN
	hrroi t2,[asciz "
   "]				;get end-of-line
	setzm t3		;terminate on null
	sout			;output end of line
	HRRZ T1,LSTJFN		;GET LISTING FILE JFN
	HRROI T2,SYSVER		;GET POINTER TO SYSTEM NAME AND VERSION
	SOUT			;OUTPUT SYSTEM NAME AND VERSION
	HRRZ T1,LSTJFN		;GET LISTING FILE JFN
	HRROI T2,[ASCIZ "
Directory	Account		 Pages	 Files

"]				;GET END-OF-LINE
	SETZM T3		;TERMINATE ON NULL
	SOUT			;OUTPUT END-OF-LINE
	movei t1,4		;get current line number
	movem t1,linnum		;save current line number
	ret			;return to whence we came ...
; ROUTINE TO OUTPUT A CRLF AND TEST FOR NEW PAGE NEEDED

TSTPAG:	HRRZ T1,LSTJFN		;GET LISTING FILE JFN
	HRROI T2,[ASCIZ "
"]				;GET END-OF-LINE
	SETZM T3		;TERMINATE ON NULL BYTE
	SOUT			;OUTPUT A CRLF
	AOS T1,LINNUM		;INCREMENT # OF LINES OUTPUT ON CURRENT PAGE
	CAIL T1,PAGLEN		;AT END OF PAGE YET ?
	CALLRET WRTHDR		;YES, GO OUTPUT A FORM FEED AND HEADER LINE
	RET			;NO, RETURN
; ERROR ROUTINES

DKERR2:	TMSG <
% CHKPNT: Internal program error -
	Insufficient space in alphanumeric account size-table
	Statistics may not be computed for all accounts ...
>
	RET			;RETURN TO WHENCE WE CAME ...

DKERR3:	TMSG <
? CHKPNT: WHEEL or OPERATOR capability required to compute disk usage statistics
>

DKERRX:	RET			;RETURN TO COMMAND PARSER
SUBTTL	HELP AND EXIT COMMANDS

; HELP COMMAND

.HELP:	MOVEI T1,CMDBLK		;GET ADDRESS OF COMMAND STATE BLOCK
	MOVEI T2,[CMFDB (.CMCFM)] ;GET FUNCTION BLOCK FOR CONFIRMATION
	COMND			;WAIT FOR CONFIRMATION
	TXNE T1,CM%NOP		;VALID END-OF-COMMAND SEEN ?
	CALLRET COMER2		;NO, ISSUE ERROR MESSAGE AND RETURN
	HRROI T1,HLPMSG		;GET POINTER TO HELP MESSAGE
	PSOUT			;OUTPUT HELP MESSAGE
	RET			;GO PARSE NEXT COMMAND

; EXIT COMMAND

.EXIT:	MOVEI T1,CMDBLK		;GET ADDRESS OF COMMAND BLOCK
	MOVEI T2,[CMFDB (.CMNOI,,<TXT(TO MONITOR)>)]
	COMND			;PARSE NOISE PHRASE
	MOVEI T2,[CMFDB (.CMCFM)] ;GET FUNCTION BLOCK FOR CONFIM
	COMND			;PARSE CONFIRMATION
	TXNE T1,CM%NOP		;VALID END-OF-COMMAND SEEN ?
	CALLRET COMER2		;NO, ISSUE ERROR MESSAGE AND RETURN
	SETOM T1		;INDICATE ALL FILES SHOULD BE CLOSED
	CLOSF			;CLOSE ALL OPEN FILES
	 JSERR			;UNEXPECTED ERROR
	HALTF			;RETURN TO MONITOR
	JRST START		;IF CONTINUE'D, START OVER
SUBTTL  SET CHECKPOINT INTERVAL COMMAND

; SET CHECKPOINTING INTERVAL COMMAND

.SET:	STKVAR <INTRVL>		;ALLOCATE LOCAL STORAGE
	MOVEI T1,CMDBLK		;GET ADDRESS OF COMMAND STATE BLOCK
	MOVEI T2,[CMFDB (.CMNOI,,<TXT(CHECKPOINT INTERVAL TO)>)]
	COMND			;PARSE NOISE WORD
	MOVEI T2,[CMFDB (.CMNUM,CM%SDH,^D10,NUMBER OF MINUTES,DEFINT)]
	COMND			;GO PARSE NUMBER
	TXNN T1,CM%NOP		;NUMBER CORRECTLY ENTERED ?
	JRST SET1		;YES, GO ON
	TMSG <
? CHKPNT: Time interval must be a number
>				;output error message
	RET			;RETurn and try next command
SET1:	JUMPG T2,SET2		;go on if interval entered is positive
	TMSG <
? CHKPNT: time interval must be a positive number of minutes
>				;OUTPUT ADVISORY MESSAGE
	RET			;RETURN AND TRY NEXT COMMAND

SET2:	MOVEM T2,INTRVL		;SAVE INTERVAL
	MOVEI T1,CMDBLK		;GET ADDRESS OF COMMAND STATE BLOCK
	MOVEI T2,[CMFDB (.CMNOI,,<TXT(MINUTES)>)]
	COMND			;PARSE NOISE PHRASE
	MOVEI T2,[CMFDB (.CMCFM)] ;GET FUNCTION BLOCK FOR CONFIRM
	COMND			;WAIT FOR USER CONFIRMATION
	TXNE T1,CM%NOP		;VALID END-OF-COMMAND SEEN ?
	CALLRET COMER2		;NO, ISSUE ERROR MESSAGE AND RETURN
	MOVE T2,INTRVL		;GET THE NEW CHECKPOINTING INTERVAL
	MOVEI T1,.USCKI		;SET CHECKPOINT INTERVAL FUNCTION
	USAGE
	 ERJMP [JSERR
		RET]
	RET
SUBTTL	COMMAND ERROR SUBROUTINES

; INVALID END-OF-COMMAND

COMER2:	STKVAR <FBLK>		;ALLOCATE STORAGE FOR FUNCTION BLOCK ADDRESS
	MOVEM T2,FBLK		;SAVE ADDRESS OF FUNCTION BLOCK
	CALL TSTCOL		;TEST COLUMN POSITION
	TMSG <? CHKPNT: Garbage at end-of-command
>				;OUTPUT ERROR MESSAGE
	RET			;RETURN TO WHENCE WE CAME ...


; SUBROUTINE TO TEST COLUMN POSITION AND OUTPUT CRLF IF NEEDED

TSTCOL:	movei t1,.priou		;get primary output designator
	rfpos			;read file position
	hrrz t2,t2		;keep just the column position
	JUMPE T2,R		;IF AT COLUMN 1 DO NOT OUTPUT CRLF
	tmsg <
>				;no, output a crlf
	RET			;RETURN TO WHENCE WE CAME ...
SUBTTL	INTERRUPT ROUTINES

; HERE ON TYPIN FROM TERMINAL DURING CHECKPOINTING LOOPS

.TYPIN:	MOVEI T1,.FHSLF		;GET OUR FORK HANDLE
	MOVX T2,1B0		;GET CHANNEL 0 BIT
	DIC			;DEACTIVATE CHANNEL 0 (TYPIN CHANNEL)
	MOVEI T1,PARSE		;GET ADDRESS OF COMMAND PARSER
	MOVEM T1,RETPC1		;CHANGE RETURN ADDRESS FROM INTERRUPT
	DEBRK			;DISMISS INTERRUPT, RETURN TO PARSER
	TMSG <
? CHKPNT: Internal error, interrupt code entered (.TYPIN) with no interrupt
>				;OUTPUT ERROR MESSAGE
	HALTF			;FATAL ERROR, STOP PROCESSING
	JRST START		;START OVER IF CONTINUE'D

; HERE ON CONTROL-A (^A) DURING DISK STATISTICS

.CTRLA:	SKIPN DIRNUM		;ANYTHING?
	DEBRK			;NO - IGNORE
	MOVEM 17,SAVE17		;SAVE AC 17
	MOVEI 17,SAVREG		;SET UP TO SAVE REMAINING AC'S
	BLT 17,SAVREG+16	;SAVE REMAINING REGISTERS
	TMSG <[CHKPNT: Working on directory >
	MOVEI T1,.PRIOU		;GET PRIMARY OUTPUT JFN
	MOVE T2,DIRNUM		;GET CURRENT DIRECTORY NUMBER
	DIRST			;OUTPUT DIRECTORY NAME
	 JSERR			;UNEXPECTED ERROR
	TMSG <]
>
	MOVSI 17,SAVREG		;SET UP TO RESTORE AC'S 0-16
	BLT 17,16		;RESTORE AC'S 0 TO 16
	MOVE 17,SAVE17		;RESTORE AC 17
	DEBRK			;RETURN TO DISK STATISTICS CODE
	TMSG <
? CHKPNT: Internal error, interrupt code entered (.CTRLA) with no interrupt
>
	HALTF			;FATAL ERROR
	JRST START		;RESTART ON CONTINUATION
	SUBTTL USAGE FILE ROUTINES

;DEFINITIONS OF INTERNAL FORMAT OF SYSTEM-DATA FILE

DEFSTR (UHTYP,BUFF+0,17,18)	;TYPE CODE
DEFSTR (UHLEN,BUFF+0,35,18)	;ENTRY LENGTH
DEFSTR (UHTAD,BUFF+1,35,36)	;ENTRY DATE/TIME
DEFSTR (UHDRV,BUFF+2,5,6)	;DEC REVISION #
DEFSTR (UHCRV,BUFF+2,11,6)	;CUST REVISION #
DEFSTR (UHTMT,BUFF+2,17,6)	;TERMINAL TYPE CODE
DEFSTR (UHJNO,BUFF+2,35,18)	;JOB #
DEFSTR (UHPNM,BUFF+3,35,36)	;PROGRAM NAME (SIXBIT)
DEFSTR (UHPVR,BUFF+4,35,36)	;PROGRAM VERSION NUMBER (STD FORM)
DEFSTR (UHMVR,BUFF+5,35,36)	;MONITOR VERSION NUMBER (STD FORM)
DEFSTR (UHJTS,BUFF+6,0,1)	;BATCH/TS FLAG
DEFSTR (UHULN,BUFF+6,5,5)	;USER NAME STRING LEN
DEFSTR (UHSL1,BUFF+6,11,6)	;STRING LENGTH #1 (ACCOUNT)
DEFSTR (UHSL2,BUFF+6,17,6)	;STRING LENGTH #2 (SESSION REMARK)
DEFSTR (UHLNO,BUFF+6,35,18)	;LINE NUMBER
DEFSTR (UHNOD,BUFF+7,35,36)	;NODE NAME (SIXBIT)

UHNAM==BUFF+10			;LOC OF FIRST WORD OF USER NAME
UHMIN==UHNAM-BUFF+1		;MINIMUM ENTRY SIZE

MXRTYP==.UTCOL			;MAX RECORD TYPE WE WILL HANDLE
;COPY SYSTEM-DATA FILE TO USAGE FILE

MAKUSG:	CALL GETITM		;SET UP ITEM IN BUFFER
	 RET			;EOF RETURN
	LOAD T1,UHTYP		;GET RECORD TYPE
	CAIG T1,MXRTYP		;SUPPORTED RECORD?
	SKIPN FRMTBL(T1)	;SUPPORTED RECORD?
	 CAIL T1,.UTUSR		;NO-- USER-DEFINED RECORD?
	  JRST MAKUS1		;YES-- SUPPORTED OR USER-DEFINED-- OK
	TMSG <?CHKPNT: Unknown record type, record ignored...
>
	JRST MAKUSG		;INVALID RECORD TYPE, TRY NEXT ENTRY

MAKUS1:	MOVEI P1,UHNAM		;SETUP P1 FOR REMAINDER OF DATA
	OPSTR <ADD P1,>,UHULN
	OPSTR <ADD P1,>,UHSL1
	OPSTR <ADD P1,>,UHSL2	;AFTER ALL STRINGS
	CALL MAKHDR		;WRITE A HEADER RECORD
	LOAD T1,UHTYP		;GET TYPE AGAIN
	CAIL T1,.UTUSR		;USER-DEFINED ENTRY TYPE?
	 JRST [	CALL MAKARB		;YES-- MAKE ARBITRARY RECORDS
		JRST MAKUSG]		; AND LOOP FOR ANOTHER ENTRY
	HRRZ DESC,FRMTBL(T1)	;LOAD FORM POINTER
	MOVE DESC,0(DESC)
	CALL FILFRM		;FILL IN FORM
	CALL OCRLF		;CRLF AND DUMP RECORD
	LOAD T1,UHTYP		;GET TYPE ONCE MORE
	HLRZ T2,FRMTBL(T1)	;GET LHS OF TABLE
	JUMPE T2,MAKUSG		;DONE IF ZERO
	CALL USRREC		;ELSE WRITE USER ID RECORD
	JRST MAKUSG		;PROCESS NEXT RECORD

;FORM FILLING IN ROUTINE
;CALL:	DESC/	-N,,TABLE-ADDRS

FILFRM:	CALL MAKFST		;SETUP FIRST PART
FILFM0:	XCT 1(DESC)		;FETCH DATA INTO T1
	LDB T3,[POINTR (<0(DESC)>,US%TYP)] ;GET ITEM TYPE
	LDB LEN,[POINTR (<0(DESC)>,US%LEN)] ;GET ITEM LENGTH
	CALL OUTITM		;OUTPUT ITEM
	AOBJP DESC,.+1
	AOBJN DESC,FILFM0	;LOOP OVER ALL ITEMS
	RET			;RETURN
;ROUTINE TO FETCH NEXT ITEM OUT OF FILE AND PLACE IN BUFF

GETITM:	HRRZ T1,DATJFN		;FILE JFN
	BIN			;READ WORD
	JUMPE T2,CKEOF		;CHECK FOR EOF OR ERROR
GTITM1:	MOVEM T2,BUFF		;SAVE HEADER
	LOAD T2,UHTYP		;GET ENTRY TYPE
	CAIL T2,^D0001		;IS ENTRY TYPE
	CAILE T2,^D9999		; WITHIN RANGE?
	 JRST GETUNK		;NO-- SKIP THIS WORD
	LOAD T2,UHLEN		;GET LENGTH
	CAIGE T2,UHMIN		;IS ENTRY LENGTH REASONABLE?
	 JRST GETUNK		;NO-- SKIP THIS WORD
	MOVNI T3,-1(T2)		;COMPUTE RECORD SIZE
	MOVE T2,[POINT 36,BUFF+1]
	SIN			;READ REST OF RECORD
	MOVE T3,0(T2)		;FETCH LAST WORD
	CAME T3,BUFF		;BETTER BE SAME AS FIRST
	JRST GETUNK		;COMPLAIN
	RETSKP			;SKIP RETURN


;MAYBE EOF, MAYBE GARBAGE

CKEOF:	GTSTS			;GET FILE STATUS
	TXNE T2,GS%EOF		;REAL EOF
	RET			;YES - RETURN
	TMSG <%CHKPNT: Zeroes in file, continuing...
>
CKEOF1:	HRRZ T1,DATJFN		;NEED JFN
CKEOF2:	BIN			;READ ANOTHER WORD
	 ERJMP R		;RETURN ON EOF
	JUMPN T2,GTITM1		;TRY THIS ONE
	JRST CKEOF2		;KEEP GOING

GETUNK:	TMSG <%CHKPNT: Unknown data in file, continuing...
>
	JRST GETITM		;TRY AGAIN
; MAKARB -- MAKE ARBITRARY RECORD DATA FOR USER-DEFINED ENTRY TYPES (5000-9999)
; CALL:	P1/ POINTER TO START OF ENTRY-DEPENDENT DATA
; RETURNS: +1 ALWAYS

MAKARB:	SETO P2,		;INDICATE WE HAVE NOT SEEN ANY RECORDS YET

;FORM AOBJN POINTER TO DATA IN ENTRY

	LOAD T1,UHLEN		;GET TOTAL LENGTH OF ENTRY
	SUBI T1,1(P1)		;MINUS THE WORDS WE HAVE DEALT WITH ALREADY
				; AND THE TRAILER WORD
	MOVN T1,T1		;MAKE THAT -VE WORDS LEFT
	HRLZ P3,T1		; TO FORM AN
	HRR P3,P1		;  AOBJN POINTER...

;LOOP THROUGH ALL THE ITEM-TYPE/DATA PAIRS AND PUT THEM INTO USAGE FILE

MAKAR1:	LDB T1,[POINTR (0(P3),US%COD)] ;GET ITEM CODE
	CAIN T1,.USUAR		;USER-DEFINED ARBITRARY RECORD DELIMITER?
	 CALL [	AOSE P2			;YES-- ARE WE AT BEGINNING?
		 CALL OCRLF		;NO-- COMPLETE LAST RECORD
		CALLRET MAKFST]		; AND START NEW RECORD
	LDB T3,[POINTR (0(P3),US%TYP)] ;GET ITEM DATATYPE
	CAIL T3,MAXITM		;WITHIN TABLE RANGE?
	 JRST [	TMSG <?CHKPNT: Invalid item type code, record ignored...
>
		RET]		;NO-- GIVE UP RECORD
	LDB LEN,[POINTR (0(P3),US%LEN)] ;GET ITEM LENGTH IN CHARACTERS
	AOBJN P3,.+1		;BUMP OVER ITEM HEADER

	CAIN T3,.USSPC		;SPACE FILL?
	 JRST MAKAR2		;YES-- NO DATA
	CAIE T3,.USASC		;ASCII STRING?
	 JRST [	MOVE T1,0(P3)		;NO-- DATA IS ONLY ONE WORD
		AOBJN P3,MAKAR2		;COUNT THE WORD
		JRST MAKAR2]		; AND TURN IT INTO TEXT

;ASCII STRING TYPE-- MUST ACCOUNT FOR SIZE AND PROVIDE POINTER

	MOVEI T1,4(LEN)		;ROUND UP LEN
	IDIVI T1,5		; TO WORDS
	HRL T1,T1		;MAKE XWD LEN,LEN
	MOVE T2,T1		;MOVE THAT AROUND SO THAT WE HAVE T1 FREE
	HRROI T1,0(P3)		;FORM POINTER TO STRING IN T1
	ADD P3,T2		;NOW BUMP DATA BUFFER POINTER

;CONVERT ITEM TO TEXT
; T1/	DATA (OR POINTER)
; T3/	DATA TYPE CODE
; LEN/	LENGTH OF ITEM IN CHARACTERS

MAKAR2:	CALL OUTITM		;OUTPUT ITEM
	JUMPL P3,MAKAR1		;KEEP ON GOING IF MORE ITEMS TO DO
	
;END OF ENTRY-- FINISH UP

	AOSE P2			;HAVE WE WRITTEN ANY RECORDS?
	 CALL OCRLF		;YES-- FINISH THE LAST ONE OFF
	RET			;RETURN FROM MAKARB
;ROUTINE TO MAKE STANDARD RECORD HEADER

MAKHDR:	SETZM RSEQ		;INIT RECORD SEQ NUMBER
	MOVE DESC,[-UFHDRL,,UFHDRT] ;HEADER RECORD FORM
	CALL FILFRM		;FILL IN FORM
	CALLRET OCRLF		;OUTPUT CRLF

;ROUTINE TO MAKE FIRST PART OF RECORD

MAKFST:	MOVE T1,[POINT 7,LBUFR]
	MOVEM T1,BPNTR		;INIT RECORD POINTER
	LOAD T1,UHTYP		;GET TYPE CODE
	MOVEI LEN,4		;LENGTH
	CALL OUTDEC		;DUMP IT
	MOVEI T2,"2"		;TOPS20 ID
	IDPB T2,BPNTR
	AOS T2,RSEQ		;INCREMENT SEQUENCE NUMBER
	ADDI T2,"0"		;MAKE ASCII
	IDPB T2,BPNTR		;STORE
	HRROI T1,[ASCIZ "0101"] ;REVISION NUMBERS (HEADER)
	SETO LEN,		;-1 FOR ASCIZ STRING
	CALL OUTASC		;OUTPUT ASCIZ
	MOVEI LEN,^D10		;SPACE FILER
	CALLRET OUTSPC		;DUMPIT


; OUTITM -- OUTPUT AN ITEM
; CALL:	T1/ DATA FOR ITEM
;	T3/ ITEM TYPE
;	LEN/ LENGTH OF ITEM IN CHARACTERS

OUTITM:	CALLRET @ITMDSP(T3)	;CALL ROUTINE TO OUTPUT ITEM AND RETURN FROM OUTITM

;DISPATCH TABLE FOR DATA ITEM TYPES

ITMDSP:	Z OUTASC		;ASCII DATA
	Z OUTSIX		;SIXBIT DATA
	Z OUTOCT		;OCTAL DATA
	Z OUTDEC		;DECIMAL DATA
	Z OUTDAT		;DATE/TIME DATA
	Z OUTTBL		;TABULAR DATA (SPECIAL)
	Z OUTVER		;VERSION DATA
	Z OUTSPC		;SPACE FILLER
MAXITM==.-ITMDSP

;ROUTINE TO OUTPUT 'N' SPACES FOUND IN C(LEN)

OUTSPC:	JUMPLE LEN,R		;DO NOTHING IF NOTHING DESIRED
	MOVEI T2," "		;GET A SPACE
	IDPB T2,BPNTR			;DUMP
	SOJG LEN,.-1
	RET			;DONE - RETURN

;ROUTINE TO OUTPUT A SIXBIT ITEM
;CALL:	T1/	DATA ITEM
;	LEN/	LENGTH OF FIELD

OUTSIX:	MOVE T2,[POINT 6,T1]	;GET A POINTER
OUTSX1:	ILDB T3,T2		;GET A CHAR
	ADDI T3,40		;CONVERT TO ASCII
	IDPB T3,BPNTR		;STORE IT
	SOJG LEN,OUTSX1		;LOOP TILL DONE
	RET			;RETURN
;ROUTINE TO OUTPUT A STRING AND SPACE FILL
;CALL:	T1/	STRING POINTER
;	T2/	NUMBER OF WORDS
;	LEN/	-1 FOR ASCIZ STRING
;		+ LENGTH FOR FIXED STRING

OUTASC:	TLC T1,-1		;CHECK FOR -1,,ADDRS
	TLCN T1,-1
	HRLI T1,(POINT 7,,)	;CONVERT
	JUMPL LEN,OUTASZ	;HANDLE SPECIAL
OUTAS1:	ILDB T3,T1		;FETCH CHARACTER
	JUMPE T3,OUTSPC		;NULL-- SPACE FILL THE REST AND RETURN
	CAIGE T3,40		;VALID CHARACTER?
	MOVEI T3,"\"		;NO - INSERT BACKSLASH INSTEAD
	IDPB T3,BPNTR		;STORE CHAR
	SOJG LEN,OUTAS1		;LOOP FOR NEXT
	RET			; EXACT FIT - RETURN

OUTASZ:	ILDB T3,T1		;GET A CHAR
	JUMPE T3,R		;DONE ON NULL
	CAIGE T3,40		;VALID CHARACTER?
	MOVEI T3,"\"		;NO - INSERT BACKSLASH INSTEAD
	IDPB T3,BPNTR		;STASH
	JRST OUTASZ		;LOOP TILL NULL

;ROUTINE(S) TO OUTPUT NUMBERS
;CALL:	T1/	NUMBER
;	LEN/	LENGTH OF FIELD

OUTOCT:	SKIPA T3,[8]		;OCTAL ENTRY
OUTDEC:	MOVEI T3,^D10		;DECIMAL ENTRY
	MOVE T2,T1		;COPY NUMBER TO CORRECT PLACE
	MOVE T1,BPNTR		;GET OUTPUT POINTER
	HRL T3,LEN		;GET LENGTH OF FIELD
	TXO T3,NO%LFL!NO%ZRO	;LEADING ZERO FILL FLAGS
	NOUT			;COPY TO OUTPUT
	 JRST [	CAIN T3,NOUTX2	;IS THIS A COLUMN OVERFLOW?
		JRST [ HRROI T1,[ASCIZ/
%Output error. Column Overflow!
/]
			PSOUT
			MOVEI T1,0 ;PAD THIS FIELD WITH 0'S INSTEAD OF ORIGINAL #
			CALLRET OUTDEC]	; SO THAT SUBSEQUENT FIELDS ARE NOT OFFSET
		JSERR		;ERROR
		MOVEI T1,0	;PAD THIS FIELD WITH 0'S INSTEAD OF ORIGINAL #
		CALLRET OUTDEC]	; SO THAT SUBSEQUENT FIELDS ARE NOT OFFSET
	MOVEM T1,BPNTR		;SAVE UPDATED POINTER
	RET			;RETURN
;ROUTINE TO APPEND CRLF TO LBUFR AND DUMP IT

OCRLF:	MOVEI T1,15
	IDPB T1,BPNTR		;CR
	MOVEI T1,12
	IDPB T1,BPNTR		;LF
	MOVEI T1,0		;APPEND A NULL
	IDPB T1,BPNTR
	HRRZ T1,USGJFN		;GET OUTPUT JFN
	HRROI T2,LBUFR		;BUFFER POINTER
	SETZ T3,
	SOUT			;DUMP STRING
	RET			;RETURN

;ROUTINE TO OUTPUT DATE/TIME IN USAGE FORMAT
;CALL:	T1/	DATE/TIME WORD

OUTDAT:	JUMPE T1,OUTDEC		;JUST ZEROES IF NO DATE
	STKVAR <YRMON,DAY,TIM>
	MOVE T2,T1		;COPY TO T2
	MOVX T4,0		;LOCAL DATE/TIME FOR NOW
	ODCNV			;CONVERT FIELDS
	MOVEM T2,YRMON
	MOVEM T3,DAY
	MOVEM T4,TIM		;SAVE ARGS
	HLRZ T1,YRMON		;GET YEAR
	MOVEI LEN,4		;SIZE 4
	CALL OUTDEC
	HRRZ T1,YRMON		;GET MONTH
	CALL OUTDT1		;OUTPUT TWO DIGITS
	HLRZ T1,DAY		;GET DAY
	CALL OUTDT1		;OUTPUT TWO DIGITS
	HRRZ T1,TIM		;GET SECONDS SINCE MIDNITE
	IDIVI T1,^D3600		;HAVE HOURS
	MOVEM T2,TIM		;SAVE REMAINDER
	CALL OUTDT2
	MOVE T1,TIM		;GET BACK REM
	IDIVI T1,^D60		;MINUTES
	MOVEM T2,TIM		;SAVE SECS
	CALL OUTDT2
	MOVE T1,TIM		;OUTPUT SECONDS
	CALLRET OUTDT2

OUTDT1:	AOS T1			;ADD ONE FIRST
OUTDT2:	IDIVI T1,^D10		;FORM 2 DIGITS
	ADDI T1,"0"		;MAKE INTO ASCII
	IDPB T1,BPNTR		;STASH HIGH DIGIT
	ADDI T2,"0"		;CONVERT LOW DIGIT
	IDPB T2,BPNTR		;SAVE IT
	RET			;RETURN
;ROUTINE TO HANDLE SPECIAL TABULAR DATA

OUTTBL:	STKVAR <SVDESC>
	MOVEM DESC,SVDESC	;SAVE DESC
	MOVE AT,T1		;POINT TO TABLE
	LDB T1,[POINTR (<0(DESC)>,US%COD)]
	CAIN T1,.USDST		;TYPE WE KNOW?
	JRST GETDKS		;YES - DO DISK ACCOUNT STRINGS
	TMSG <? CHKPNT: Unknown table type, ignored...
>
	RET			;RETURN

OUTTBX:	MOVE DESC,SVDESC	;RESTORE CONTEXT
	RET			;AND RETURN

;HANDLE DISK ACCOUNT STRING RECORDS

GETDKS:	SKIPA TBL,0(P1)		;SETUP TABLE LENGTH
GETDK1:	SOS RSEQ		;ALL RECORDS ARE SAME SEQUENCE #
	CALL OCRLF		;DUMP PREVIOUS RECORD
	MOVE DESC,[-UFDASL,,UFDAST]
	CALL FILFRM		;FILL OUT RECORD
	HRRZ T1,0(AT)		;LENGTH OF ACCOUNT STRING
	ADDI AT,.ATSIZ+1(T1)	;STEP TO NEXT ENTRY
	SOJG TBL,GETDK1		;LOOP OVER ALL ENTRIES
	JRST OUTTBX		;COMMON EXIT

;RETURN POINTER TO ACCOUNT STRING

GETAST:	HRROI T1,3(AT)		;POINT TO STRING
	HRRZ T2,0(AT)		;SETUP LENGTH
	RET			;DONE
;DISK USAGE ACCOUNT STRING BLOCK

UFDAST:	USACT. <CALL GETAST>	;GET ACCOUNT STRING
	USDIR. <CALL GETST2>	;DIRECTORY NAME STRING (STRING 2)
	USALC. <MOVE T1,1(AT)>	;ALLOCATED (USED)
	USUSG. <MOVE T1,1(AT)>	;PAGES USED
	USFIL. <MOVE T1,2(AT)>	;TOTAL FILES IN THIS ACCOUNT
	USSTR. <CALL GETST1>	;STRUCTURE NAME (STRING 1)
	USSTP. <CALL [LOAD T1,STYP,<6(P1)>
		      ADDI T1,3	;3 := FORIEGN, 4 := DOMESTIC
		      RET]>
	USKTP. <LOAD T1,KTYP,<6(P1)>> ;CONTROLLER TYPE
	USDTP. <LOAD T1,DTYP,<6(P1)>> ;DEVICE TYPE
UFDASL==.-UFDAST
;ROUTINE TO OUTPUT VERSION NUMBER IN STANDARD FORMAT

OUTVER:	STKVAR <VERX,VPTR>
	MOVEM T1,VERX		;SAVE VERSION
	MOVEM BPNTR,VPTR	;SAVE CURRENT POINTER
	CALL OUTSPC		;PREFILL SPACES
	LDB T2,[POINT 9,VERX,11] ;MAJOR VERSION
	MOVE T1,VPTR		;START HERE
	MOVEI T3,10		;OCTAL
	NOUT			;NUMBER
	 JRST [	JSERR		;OUTPUT MESSAGE
		RET ]		;AND DONE
	LDB T2,[POINT 6,VERX,17] ;MINOR VERSION
	JUMPE T2,OUTVR1		;SKIP IF NONE
	SUBI T2,1		;NORMALIZE
	IDIVI T2,^D26		;MOD 26
	SKIPE T2		;TWO DIGITS?
	JRST [	ADDI T2,"A"-1(T2)
		IDPB T2,T1	;YES - PRINT FIRST
		JRST .+1]
	ADDI T3,"A"
	IDPB T3,T1		;THEN OTHER
OUTVR1:	MOVEI T2,"("		;OPEN PAREN
	IDPB T2,T1
	HRRZ T2,VERX		;GET EDIT NUMBER
	MOVEI T3,10		;OCTAL
	NOUT			;DUMP IT
	 JRST [	JSERR		;OUTPUT MESSAGE
		RET ]		;AND DONE
	MOVEI T2,")"		;CLOSE PAREN
	IDPB T2,T1
	LDB T2,[POINT 3,VERX,2]	;WHO LAST EDITED
	JUMPE T2,R		;DONE IF ZERO
	MOVEI T3,"-"
	IDPB T3,T1
	ADDI T2,"0"		;MAKE INTO ASCII
	IDPB T2,T1		;AND STORE
	RET			;DONE - RETURN

;ROUTINE TO OUTPUT USER NAME RECORD

USRREC:	CALL MAKFST		;GEN RECORD HEADER
	HRROI T1,UHNAM		;POINT TO USER NAME STRING
	LOAD T2,UHULN		;LENGTH IN WORDS
	MOVEI LEN,^D39		;SIZE OF STRING
	CALL OUTASC		;DUMP ASCII
	CALLRET OCRLF		;DUMP RECORD
;ROUTINE TO GENERATE A FILE HEADER RECORD FOR THE USAGE FILE

FILHDR:	RET			;*** TEMP ***
;FORM TABLE TABLE
;-1 IN LHS TO OUTPUT USER NAME RECORD

FRMTBL:	0,,0			;0 - ILLEGAL
	0,,[-UFRSTL,,UFRSTT]	;1 - RESTART RECORD
	-1,,[-UFLOGL,,UFLOGT]	;2 - SESSION ENTRY
	-1,,[-UFLOGL,,UFLOGT]	;3 - CHECKPOINT ENTRY
	0,,0			;4 - ILLEGAL
	0,,[-UFTADL,,UFTADT]	;5 - DATE/TIME
	0,,0			;6 - BATCH PROCESSOR
	-1,,[-UFINPL,,UFINPT]	;7 - INPUT SPOOLER
	-1,,[-UFOUTL,,UFOUTT]	;8 - OUTPUT SPOOLER
	0,,[-UFDSKL,,UFDSKT]	;9 - DISK STORAGE USAGE
	0,,0			;10 - DISK SPINDLE USAGE
	-1,,[-UFSTRL,,UFSTRT]	;11 - STRUCTURE MOUNT
	-1,,[-UFMTAL,,UFMTAT]	;12 - MAGTAPE MOUNT
	0,,0			;13 - DECTAPE MOUNT (???)
	0,,0			;14 - FILE COMMAND (!!!)
	-1,,[-UFRETL,,UFRETT]	;15 - FILE RETRIEVE
	-1,,[-UFRETL,,UFRETT]	;16 - FILE ARCHIVED
	-1,,[-UFRETL,,UFRETT]	;17 - FILE MIGRATED
	-1,,[-UFRETL,,UFRETT]	;18 - FILE COLLECTED
;RECORD DESCRIPTORS

;ENTRY HEADER RECORD

UFHDRT:	USJNO. <LOAD T1,UHJNO>	;JOB NUMBER
	USTAD. <LOAD T1,UHTAD>	;DATE/TIME
	USTRM. <CALL [LOAD T1,UHTMT
		      ADDI T1,40
		      JRST SNGASC]> ;TERMINAL TYPE
	USLNO. <CALL [LOAD T1,UHLNO
		      ANDI T1,7777
		      RET]>	;LINE NUMBER (4 DIGITS)
	USPNM. <LOAD T1,UHPNM>	;PROGRAM NAME
	USPVR. <LOAD T1,UHPVR>	;PROGRAM VERSION
	USAMV. <LOAD T1,UHMVR>	;MONITOR VERSION
	USNOD. <LOAD T1,UHNOD>	;NODE NAME
UFHDRL==.-UFHDRT

;RESTART RECORD

UFRSTT:	USSNM. <CALL GETST1>	;SYSTEM NAME (STRING 1)
	USMVR. <MOVE T1,0(P1)>	;MONITOR VERSION
	USMBD. <MOVE T1,1(P1)>	;MONITOR BUILD DATE/TIME
	USMUP. <MOVEI T1,0>	;MONITOR UPTIME
	USCPN. <MOVEI T1,1>	;NUMBER OF CPU'S
	USCP0. <MOVE T1,2(P1)>	;SERIAL NUMBER OF CPU0
	USCP1. <MOVEI T1,0>	;SERIAL NUMBER OF CPU1
	USCP2. <MOVEI T1,0>	;SERIAL NUMBER OF CPU2
	USCP3. <MOVEI T1,0>	;SERIAL NUMBER OF CPU3
	USCP4. <MOVEI T1,0>	;SERIAL NUMBER OF CPU4
	USCP5. <MOVEI T1,0>	;SERIAL NUMBER OF CPU5
	USLCK. <MOVE T1,3(P1)>	;LAST CHECKPOINT DATE/TIME
UFRSTL==.-UFRSTT
;SESSION RECORD

UFLOGT:	USACT. <CALL GETST1>	;ACCOUNT (STRING 1)
	USRTM. <MOVE T1,2(P1)>	;RUNTIME
	USSST. <MOVE T1,0(P1)>	;SESSION START TIME
	USJTY. <CALL [LOAD T1,UHJTS
		      AOJA T1,R]> ;1 := T/S , 2 := BATCH
	USBJN. <MOVE T1,3(P1)>	;BATCH JOB NAME
	USBSN. <MOVE T1,4(P1)>	;BATCH SEQUENCE NUMBER
	USCOM. <CALL GETST2>	;USER COMMENT (STRING 2)
	USCCT. <CALL [MOVE T1,1(P1)
		      IDIVI T1,^D1000
		      RET]>	;CONSOLE CONNECT TIME (SECONDS)
UFLOGL==.-UFLOGT

;DATE/TIME CHANGE RECORD

UFTADT:	USOFD. <CALL GETOFD>	;OFFSET IN DAYS
	USOFS. <CALL GETOFS>	;OFFSET IN SECONDS
	USODT. <MOVE T1,0(P1)>	;OLD DATE/TIME
UFTADL==.-UFTADT

;DISK STORAGE USAGE RECORD

UFDSKT:	USNRF. <MOVE T1,0(P1)>	;NUMBER OF ACCOUNTS
	USTAL. <MOVE T1,1(P1)>	;TOTAL ALLOCATED (USED)
	USTUS. <MOVE T1,1(P1)>	;TOTAL USED
	USTNF. <MOVE T1,2(P1)>	;TOTAL NUMBER OF FILES
	USSTR. <CALL GETST1>	;STRUCTURE NAME (STRING 1)
	USDIR. <CALL GETST2>	;DIRECTORY NAME (STRING 2)
	USSTP. <CALL [LOAD T1,STYP,<6(P1)>
		      ADDI T1,3 ;3 := FORIEGN, 4 := DOMESTIC
		      RET]>	;STRUCTURE TYPE
	USKTP. <LOAD T1,KTYP,<6(P1)>> ;CONTROLLER TYPE (RH20)
	USDTP. <LOAD T1,DTYP,<6(P1)>> ;DEVICE TYPE (RP04)
	USLIQ. <MOVE T1,3(P1)>	;LOGGED IN QUOTA
	USLOQ. <MOVE T1,4(P1)>	;LOGGED OUT QUOTA
	USLLI. <MOVE T1,5(P1)>	;DATE/TIME LAST LOGIN
	USLAT. <MOVEI T1,0>	;LAST ACCOUNTING DATE/TIME (NOT IMP)
	USEXP. <CALL [MOVEI T1,"N"
		      JRST SNGASC]> ;NOT EXPIRED
	USFON. <CALL [LOAD T2,FOND,<6(P1)>
		      MOVEI T1,"N"
		      SKIPE T2
		      MOVEI T1,"Y"
		      JRST SNGASC]> ;FILES ONLY INDICATOR
	USDSK. <MOVEI T1,7(P1)>	;DISK TABLE
UFDSKL==.-UFDSKT
;INPUT SPOOLER RECORD

UFINPT:	USACT. <CALL GETST1>	;ACCOUNT (STRING 1)
	USSRT. <MOVE T1,0(P1)>	;SPOOLER RUNTIME
	USSCI. <MOVEI T1,0>	;CORE-TIME INTEGRAL ???
	USSDR. <MOVE T1,1(P1)>	;SPOOLER DISK READS
	USSDW. <MOVE T1,2(P1)>	;SPOOLER DISK WRITES
	USJNM. <MOVE T1,3(P1)>	;JOB NAME
	USQNM. <MOVE T1,4(P1)>	;QUEUE NAME
	USSDV. <MOVE T1,5(P1)>	;INPUT DEVICE NAME
	USSSN. <MOVE T1,6(P1)>	;SEQUENCE NUMBER
	USSUN. <MOVE T1,7(P1)>	;CARDS READ
	USCRT. <MOVE T1,10(P1)>	;DATE/TIME
	USDSP. <MOVE T1,11(P1)>	;DISPOSITION
	USTXT. <CALL GETST2>	;SYSTEM TEXT
	USPRI. <MOVE T1,12(P1)>	;PRIORITY
UFINPL==.-UFINPT

;OUTPUT SPOOLER RECORD

UFOUTT:	USACT. <CALL GETST1>	;ACCOUNT (STRING 1)
	USSRT. <MOVE T1,0(P1)>	;SPOOLER RUNTIME
	USSCI. <MOVEI T1,0>	;CORE-TIME INTEGRAL ???
	USSDR. <MOVE T1,1(P1)>	;SPOOLER DISK READS
	USSDW. <MOVE T1,2(P1)>	;SPOOLER DISK WRITES
	USJNM. <MOVE T1,3(P1)>	;JOB NAME
	USQNM. <MOVE T1,4(P1)>	;QUEUE NAME
	USSDV. <MOVE T1,5(P1)>	;OUTPUT DEVICE NAME
	USSSN. <MOVE T1,6(P1)>	;SEQUENCE NUMBER
	USSUN. <MOVE T1,7(P1)>	;PAGES, FEET, CARDS, MINUTES
	USSNF. <MOVE T1,13(P1)>	;FILES, COPIES
	USCRT. <MOVE T1,10(P1)>	;DATE/TIME
	USSCD. <MOVE T1,14(P1)>	;SCHEDULED DATE/TIME
	USFRM. <MOVE T1,15(P1)>	;FORMS TYPE
	USDSP. <MOVE T1,11(P1)>	;DISPOSITION
	USTXT. <CALL GETST2>	;SYSTEM TEXT
	USPRI. <MOVE T1,12(P1)>	;PRIORITY
UFOUTL==.-UFOUTT
;STRUCTURE USE RECORD

UFSTRT:	USACT. <CALL GETST1>	;ACCOUNT (STRING 1)
	USSSI. <MOVE T1,0(P1)>	;STRUCTURE NAME
	USSTP. <MOVE T1,1(P1)>	;STRUCTURE TYPE
	USTNP. <MOVE T1,2(P1)>	;TOTAL NUMBER OF PACKS IN FILE STRUCTURE
	USKTP. <MOVE T1,3(P1)>	;CONTROLLER TYPE
	USDTP. <MOVE T1,4(P1)>	;DEVICE TYPE (RP04,ETC)
	USDSP. <MOVE T1,5(P1)>	;DISPOSITION
	USTXT. <CALL GETST2>	;SYSTEM TEXT
	USCRT. <MOVE T1,6(P1)>	;CREATION DATE/TIME OF REQUEST
	USSCD. <MOVE T1,7(P1)>	;SCHEDULED DATE/TIME
	USSRV. <MOVE T1,10(P1)>	;SERVICED DATE/TIME
	USMCT. <MOVE T1,11(P1)>	;MOUNT COUNT BEFORE MOUNT
	USDCT. <MOVE T1,12(P1)>	;MOUNT COUNT AFTER DISMOUNT
	USATP. <MOVE T1,13(P1)>	;ACCESS TYPE
	USEUT. <CALL [MOVE T1,14(P1)
		IDIVI T1,3
		RET]>		;ELAPSED TIME OF USE (SECONDS)
UFSTRL==.-UFSTRT

;TAPE MOUNT RECORD

UFMTAT:	USACT. <CALL GETST1>	;ACCOUNT (STRING 1)
	USVID. <MOVE T1,0(P1)>	;VOLUME IDENTIFIER IN VOL1 LABEL
	USVSN. <MOVE T1,1(P1)>	;VISUAL SERIAL NAME (SAME AS VOL ID)
	USMRF. <MOVE T1,2(P1)>	;THOUSANDS OF FRAMES READ
	USMWF. <MOVE T1,3(P1)>	;THOUSANDS OF FRAMES WRITTEN
	USDSP. <MOVE T1,4(P1)>	;DISPOSITION
	USTXT. <CALL GETST2>	;SYSTEM TEXT
	USCRT. <MOVE T1,5(P1)>	;CREATION DATE/TIME
	USSCD. <MOVE T1,6(P1)>	;SCHEDULED DATE/TIME
	USSRV. <MOVE T1,7(P1)>	;SERVICED DATE/TIME
	USKTP. <MOVE T1,10(P1)>	;CONTROLLER TYPE
	USMLT. <MOVE T1,11(P1)>	;LABEL TYPE
	USMLS. <MOVE T1,12(P1)>	;LABEL STATE
	USMRD. <MOVE T1,13(P1)>	;NUMBER OF PHYSICAL RECORDS READ
	USMWR. <MOVE T1,14(P1)>	;NUMBER OF PHYSICAL RECORDS WRITTEN
	USFSI. <MOVE T1,15(P1)>	;FILE SET IDENTIFIER
	USSRE. <MOVE T1,16(P1)>	;NUMBER OF SOFT READ ERRORS
	USSWE. <MOVE T1,17(P1)>	;NUMBER OF SOFT WRITE ERRORS
	USHRE. <MOVE T1,20(P1)>	;NUMBER OF HARD READ ERRORS
	USHWE. <MOVE T1,21(P1)>	;NUMBER OF HARD WRITE ERRORS
	USEUT. <CALL [MOVE T1,22(P1)
		IDIVI T1,3
		RET]>		;ELAPSED TIME OF USE (SECONDS)
UFMTAL==.-UFMTAT
;ARCHIVING, MIGRATING, RETRIEVAL RECORD

UFRETT:	USACT. <CALL GETST1>	;ACCOUNT OF FILE OR RETRIEVE REQUESTOR
				; (STRING 1)
	USSSI. <MOVE T1,0(P1)>	;STRUCTURE NAME
	USDIR. <CALL GETST2>	;DIRECTORY OF FILE (STRING 2)
	USUSG. <MOVE T1,1(P1)>	;# OF PAGES INVOLVED
	USTP1. <MOVE T1,2(P1)>	;TAPE 1 ID
	USTS1. <MOVE T1,3(P1)>	;SAVESET # FOR TAPE 1
	USTF1. <MOVE T1,4(P1)>	;TAPE FILE # FOR TAPE 1
	USTP2. <MOVE T1,5(P1)>	;TAPE 2 ID
	USTS2. <MOVE T1,6(P1)>	;SAVESET # FOR TAPE 2
	USTF2. <MOVE T1,7(P1)>	;TAPE FILE # FOR TAPE 2
	USRSN. <MOVE T1,10(P1)>	;CODE FOR REASON FILE MOVED OFF-LINE
UFRETL==.-UFRETT
;SPECIAL ROUTINES FOR FORMATTING INPUT

;HANDLE SINGLE ASCII CHARACTER

SNGASC:	SETZM TXTB		;CLEAR WORD
	DPB T1,[POINT 7,TXTB,6]	;PLACE CHAR IN BUFFER
	HRROI T1,TXTB		;RETURN POINTER TO STRING
	RET


;SET POINTER TO STRING 1

GETST1:	MOVEI T1,UHNAM		;START HERE
	OPSTR <ADD T1,>,UHULN	;ADD IN FIRST OFFSET
	TLO T1,-1		;MAKE INTO STRING POINTER
	LOAD T2,UHSL1		;SETUP LENGTH
	RET			;RETURN

;SET POINTER TO STRING 2

GETST2:	MOVEI T1,UHNAM		;STARTING POINT
	OPSTR <ADD T1,>,UHULN	;PLUS NAME STRING
	OPSTR <ADD T1,>,UHSL1	;PLUS STRING 1
	TLO T1,-1		;MAKE STRING POINTER
	LOAD T2,UHSL2		;SETUP LENGTH
	RET			;RETURN

;GET OFFSET IN DAYS

GETOFD:	HLRZ T1,0(P1)		;OLD DATE/TIME
	HLRZ T2,BUFF+1		;NEW DATE
	SUB T1,T2		;TAKE DIFFERENCE
	MOVMS T1		; MAGNITUDE
	RET			;RETURN


;GET OFFSET IN SECONDS

GETOFS:	HRRZ T1,0(P1)		;OLD TIME
	HRRZ T2,BUFF+1		;NEW TIME
	SUB T1,T2		;TAKE DIFFERENCE
	MOVMS T1		; ABS VALUE
	MULI T1,^D<24*3600>	;CONVERT TO SECONDS
	DIV T1,[1B17]
	RET			;RETURN (NO ROUNDING)
SUBTTL CONSTANTS AND TABLES

DEFINE TB(RTN,TXT)
<	[ASCIZ/TXT/] ,, RTN
>

CMDTAB:	CMDSIZ-1 ,, CMDMAX
	TB (.CHANGE,CHANGE)	;Change accounting shift
;	TB (.CHECK,CHECKPOINT)	;CHECKPOINT EVERY N MINUTES
	TB (.COPY,COPY)		;COPY SYSTEM-DATA TO FILE
	TB (.DISK,DISK-STATISTICS) ;DISK STATISTICS
	TB (.ENTER,ENTER)	;ENTER A SINGLE CHECKPOINT
	TB (.EXIT,EXIT)		;EXIT TO MONITOR
	TB (.EXPNG,EXPUNGE)	;EXPUNGE PROCESSED SYSTEM DATA
	TB (.HELP,HELP)		;OUTPUT HELP MESSAGE
	TB (.LIST,LIST)		;LIST DISK STATISTICS ON FILE-SPEC
	TB (.SET,SET)		;SET CHECKPOINTING INTERVAL

	CMDSIZ== .-CMDTAB

CMDFRE:	BLOCK CMDMAX-CMDSIZ	;FREE SPACE IN COMMAND TABLE

PROMPT:	ASCIZ /CHKPNT>/			;PROMPT STRING

; ENTRY VECTOR DEFINITION

ENTVEC:	JRST START		;MAIN ENTRY POINT
	JRST START		;REENTER ENTRY POINT
	EXP VCHKPT		;VERSION OF CHKPNT PROGRAM

; LEVEL TABLE FOR SOFTWARE INTERRUPT SYSTEM

LEVTAB:	RETPC1			;RETURN PC FOR LEVEL 1
	RETPC2			;RETURN PC FOR LEVEL 2
	RETPC3			;RETURN PC FOR LEVEL 3

; CHANNEL TABLE FOR SOFTWARE INTERRUPT SYSTEM

CHNTAB:	1,,.TYPIN		;TERMINAL INPUT DURING CHECKPOINTING LOOP
	1,,.CTRLA		;CONTROL-A - INFO REQUEST DURING DISK STATS
	BLOCK ^D34		;REMAINDER OF TABLE
; HELP TEXT FOR HELP COMMAND

HLPMSG:	ASCIZ \TOPS20 CHKPNT PROGRAM --

FUNCTIONS:

        1)  Compile  accounting  statistics  on  disk  space
        utilization.

	2) Set monitor checkpoint interval.

	3) Copy system data to an accounting file.

COMMANDS:

        CHANGE (ACCOUNTING SHIFT)
	COPY (SYSTEM DATA TO) FILE-SPEC
	DISK-STATISTICS (FOR STRUCTURE) STR:
	LIST (DISK STATISTICS ON) FILE-SPEC
        SET (CHECKPOINT INTERVAL TO) N (MINUTES)
	ENTER (SINGLE CHECKPOINT)
        HELP
        EXIT (TO MONITOR)
	EXPUNGE (PROCESSED SYSTEM DATA)

OPERATION:

	CHKPNT is usually run manually to gather disk utilization
	statistics one every week, month, or once per billing period.

EXAMPLE:

	To copy the current system data to a magtape for later 
processing:

@R CHKPNT
CHKPNT>COPY (SYSTEM DATA TO) MTA0:
CHKPNT>EXPUNGE (PROCESSED SYSTEM DATA)
	[123 Pages freed]
CHKPNT>EXIT (TO MONITOR)
@

RESTRICTIONS:

        WHEEL or OPERATOR capability is  required  to  write
        checkpoint data and to compile disk statistics.
\

; LITERALS

	XLIST		;NEXT LINE (NOT LISTED) IS "LIT"
	LIT		;PUT LITERALS HERE
	LIST		;RESUME LISTINE
SUBTTL	VARIABLES AND IMPURE DATA STORAGE

CMDBLK:	BLOCK .CMGJB+5		;COMMAND STATE BLOCK FOR COMND JSYS

LSTJFN:	BLOCK 1			;JFN FOR DISK STATISTICS LISTING FILE
USGJFN:	BLOCK 1			;JFN ON USAGE FILE
DATJFN:	BLOCK 1			;JFN ON SYSTEM-DATA FILE
FILJFN:	BLOCK 1			;JFN FOR *.*.* DURING DISK STATISTICS ROUTINE
CURRV:	BLOCK 2			;BUFFER FOR GENERATION NUMBER
HIGHV:	BLOCK 2			;BUFFER FOR HIGHEST GEN
RSEQ:	BLOCK 1			;USAGE RECORD SEQUENCE NUMBER
SYSVER:	BLOCK SVERSZ		;BUFFER FOR SYSTEM NAME AND VERSION
TOTFIL:	BLOCK 1			;TOTAL NUMBER OF FILES IN CURRENT DIRECTORY
TOTPGS:	BLOCK 1			;TOTAL NUMBER OF PAGES IN CURRENT DIRECTORY
TOTACT:	BLOCK 1			;TOTAL NUMBER OF ACCOUNTS IN CURRENT DIRECTORY
LINNUM:	BLOCK 1			;current line number for disk stats listing
PAGNUM:	BLOCK 1			;CURRENT PAGE # FOR DISK STAT LISTING
ACPEND:	BLOCK 1			;POINTER TO END OF ALPHA ACCOUNT SIZE TABLE
ASTEND:	BLOCK 1			;POINTER TO END OF ALPHA ACCOUNT STRINGS
ACTEND:	BLOCK 1			;POINTER TO END OF ACCOUNT TABLE
DIRNUM:	BLOCK 1			;CURRENT DIRECTORY NUMBER
TYPWRD:	BLOCK 1			;STR/DRIVE/KONTROLLER TYPE WORD
STRPTR:	BLOCK 1			;POINTER TO END OF STR NAME
STRBUF:	BLOCK 14		;BUFFER FOR STR:<*>
FILBUF:	BLOCK 24		;BUFFER FOR FILESPECS
STRDIR:	BLOCK STRBSZ		;STG FOR STR:<DIR> STRING
STRNAM:	BLOCK 10		;STRUCTURE NAME STRING
DIRNAM:	BLOCK 10		;DIRECTORY NAME STRING
GTDBUF:	BLOCK GTDBSZ+1		;BLOCK FOR GTDIR PARAMS
STSBLK:	BLOCK 2			;FOR STRUCTURE STATUS
RNUBLK:	BLOCK .MSRLN		;FOR UNIT STATUS
LSTFIL:	BLOCK 4*10+1		;STORAGE FOR LISTING FILESPEC
RETPC1:	BLOCK 1			;RETURN PC FOR LEVEL 1 INTERRUPTS
RETPC2:	BLOCK 1			;RETURN PC FOR LEVEL 2 INTERRUPTS
RETPC3:	BLOCK 1			;RETURN PC FOR LEVEL 3 INTERRUPTS
CHKTIM:	BLOCK 1			;TIME IN MS BETWEEN CHECKPOINTS
JOBNUM:	BLOCK 1			;JOB NUMBER OF THIS JOB
DEFINT:	BLOCK DEFISZ		;DEFAULT INTERVAL BETWEEN CHECKPOINTS (TEXT)
TXTB:	BLOCK 20		;TEMP TEXT BUFFER
ACPTAB:	BLOCK ACPSIZ		;TABLE OF # OF PAGES FOR ALPHA ACCOUNTS
ACTTAB:	BLOCK ACTSIZ		;TABLE OF ALPHA ACCOUNT STRINGS
ACTBUF:	BLOCK ACTBSZ		;BUFFER FOR ACCOUNT STRINGS
BUFFER:	BLOCK BUFSIZ		;INPUT TEXT STORED HERE
ATMBFR:	BLOCK ATMSIZ		;ATOM BUFFER FOR COMND JSYS
JOBBLK:	BLOCK JOBSIZ		;JOB INFORMATION FROM GETJI
DATBUF:	BLOCK DATSIZ		;DATE AND TIME STRING BUFFER
GJFBLK:	BLOCK GJFSIZ		;GTJFN BLOCK FOR COMND JSYS
SAVREG:	BLOCK ^D15		;AC'S 0-16 ARE SAVED HERE ON ^A INTERRUPT
SAVE17:	BLOCK 1			;AC 17 SAVED HERE ON ^A INTERRUPT

PDL:	BLOCK PDLEN		;PUSH DOWN POINTER

BUFF=100000			;BUFFER FOR SYSTEM-DATA RECORD
LBUFR=102000			;BUFFER FOR STRING OUTPUT RECORD

; STORAGE FOR ALPHANUMERIC ACCOUNT STRINGS DURING DISK STATS COLLECTION

STRACT=200000

	END <3,,ENTVEC>