Google
 

Trailing-Edge - PDP-10 Archives - BB-H138A-BM - 3a-sources/checkd.mac
There are 35 other files named checkd.mac in the archive. Click here to see a list.
;<3A.UTILITIES>CHECKD.MAC.10, 25-May-78 10:49:23, EDIT BY OSMAN
;<3A.UTILITIES>CHECKD.MAC.9, 23-May-78 18:24:24, EDIT BY OSMAN
;<3A.UTILITIES>CHECKD.MAC.8, 23-May-78 18:18:51, EDIT BY OSMAN
;ADD LIMIT EXPLANATION TO HELP COMMAND
;ADD LIMIT/UNLIMIT COMMANDS
;<3A.UTILITIES>CHECKD.MAC.6,  6-May-78 23:41:06, Edit by MCLEAN
;<4.UTILITIES>CHECKD.MAC.3, 17-Dec-77 14:38:25, Edit by MCLEAN
;<4.UTILITIES>CHECKD.MAC.2, 11-Dec-77 19:03:11, Edit by MCLEAN
;ADD BATBLOCK SUPPORT FOR RM03
;<3-UTILITIES>CHECKD.MAC.15,  8-Nov-77 10:45:06, EDIT BY KIRSCHEN
;MORE COPYRIGHT UPDATING...
;<3-UTILITIES>CHECKD.MAC.14, 26-Oct-77 10:58:12, EDIT BY KIRSCHEN
;UPDATE COPYRIGHT FOR RELEASE 3
;<3-UTILITIES>CHECKD.MAC.13, 12-Oct-77 12:19:11, EDIT BY KIRSCHEN
;FIX TO TCO 1858 - MAKE RECONSTRUCT TABLE FOR COMND ALPHABETIC
;<3-UTILITIES>CHECKD.MAC.12, 29-Sep-77 15:34:18, EDIT BY BORCHEK
; TCO #1866 - INCORRECT REPORT OF MULTIPLE ASSIGNMENTS
;<3-UTILITIES>CHECKD.MAC.10, 28-Sep-77 16:27:07, EDIT BY OSMAN
;CHANGE RLJFN'S WITH -1 IN AC1 TO CLZFF SO OTHER PROCESS'S JFNS DON'T GET FLUSHED
;<3-UTILITIES>CHECKD.MAC.9,  1-Sep-77 10:11:53, EDIT BY KIRSCHEN
;TCO 1858 - ADD RECONSTRUCT INDEX-TABLE COMMAND
;<3-UTILITIES>CHECKD.MAC.8, 29-Aug-77 13:33:52, Edit by MCLEAN
;<3-UTILITIES>CHECKD.MAC.7, 26-Aug-77 15:20:28, Edit by MCLEAN
;ADD RM03 SUPPORT
;<3-UTILITIES>CHECKD.MAC.5, 25-Aug-77 10:57:02, EDIT BY KIRSCHEN
;FIX VERSION NUMBERS FOR RELEASE 3
;<3-UTILITIES>CHECKD.MAC.4, 18-Aug-77 13:48:27, EDIT BY HURLEY
;<3-UTILITIES>CHECKD.MAC.3, 18-Aug-77 13:44:12, EDIT BY HURLEY
;<3-UTILITIES>CHECKD.MAC.2, 17-Aug-77 16:25:14, EDIT BY HURLEY
;CLEAN UP MAPPED PAGE ALLOCATION
;<3-UTILITIES>CHECKD.MAC.1, 22-Jun-77 16:29:42, EDIT BY HALL
;TCO 1828 - MADE .DIREC AND .BITAB USE RCDIR FOR STEPPING
;<2-UTILITIES>CHECKD.MAC.63, 21-Feb-77 12:19:05, EDIT BY MILLER
;CHECK BAT BLOCKS FOR OVERFLOW WHEN READING IN
;<2-UTILITIES>CHECKD.MAC.62, 27-Dec-76 17:05:08, EDIT BY HURLEY
;<2-UTILITIES>CHECKD.MAC.61,  8-Dec-76 09:52:41, Edit by HESS
;FIX FORCE DISMOUNT LOGIC TO REMEMBER ACTUAL STRUCTURE ID
;<2-UTILITIES>CHECKD.MAC.60, 24-Nov-76 13:52:04, Edit by HESS
;<2-UTILITIES>CHECKD.MAC.59, 24-Nov-76 11:31:19, Edit by HESS
;ALLOW CHECKING OF A DISMOUNTED PS:
;<2-UTILITIES>CHECKD.MAC.58, 24-Nov-76 10:32:24, Edit by HESS
;FIX CONNECTED DIR IF STR DISMOUNTED, FIX ^C OUT OF FNDSTR
;<2-UTILITIES>CHECKD.MAC.57, 11-Nov-76 11:16:57, Edit by HESS
;ADD HELP TEXT TO SWAPPING SPACE AND FE FILE SYS QUESTIONS
;<2-UTILITIES>CHECKD.MAC.56,  9-Nov-76 11:20:33, Edit by HESS
;<2-UTILITIES>CHECKD.MAC.55,  8-Nov-76 14:54:32, Edit by HESS
;<2-UTILITIES>CHECKD.MAC.54,  8-Nov-76 14:29:54, Edit by HESS
;<2-UTILITIES>CHECKD.MAC.53,  8-Nov-76 13:53:06, Edit by HESS
;<2-UTILITIES>CHECKD.MAC.52,  8-Nov-76 11:52:20, Edit by HESS
;ASK FOR OWNER ID INFO IN CREATE COMMAND
;<2-UTILITIES>CHECKD.MAC.51,  8-Nov-76 10:58:36, Edit by HESS
;ADD HELP TEXT TO CHANNEL,UNIT QUESTION
;<2-UTILITIES>CHECKD.MAC.50,  5-Nov-76 10:01:44, Edit by HESS
;CHANGE ALREADY MOUNTED LOGIC , TRY TO MOUNT FOR "CHECK DIR"
;<2-UTILITIES>CHECKD.MAC.49,  4-Nov-76 10:02:07, Edit by HESS
;<2-UTILITIES>CHECKD.MAC.48,  3-Nov-76 14:15:55, Edit by HESS
;<2-UTILITIES>CHECKD.MAC.47,  2-Nov-76 16:28:17, Edit by HESS
;<2-UTILITIES>CHECKD.MAC.46,  2-Nov-76 13:34:21, Edit by HESS
; CHANGE TO ALWAYS MOUNT WITH AN ALIAS
;<2-UTILITIES>CHECKD.MAC.45,  1-Nov-76 17:12:49, Edit by HESS
;<2-UTILITIES>CHECKD.MAC.44,  1-Nov-76 16:16:40, Edit by HESS
;<2-UTILITIES>CHECKD.MAC.43,  1-Nov-76 15:05:41, Edit by HESS
;<2-UTILITIES>CHECKD.MAC.42,  1-Nov-76 14:14:41, Edit by HESS
;<2-UTILITIES>CHECKD.MAC.41,  1-Nov-76 13:47:40, Edit by HESS
;ADD CREATE (STRUCTURE) COMMAND
;<2-UTILITIES>CHECKD.MAC.40,  1-Nov-76 09:56:04, Edit by HESS
;<2-UTILITIES>CHECKD.MAC.39, 29-Oct-76 10:40:28, Edit by HESS
;CLEAR SF%CDE IF DOING CHECK BITTABLE ON PS: AND ALL OK
;<2-UTILITIES>CHECKD.MAC.38, 28-Oct-76 15:35:26, Edit by HESS
;<2-UTILITIES>CHECKD.MAC.37, 27-Oct-76 17:55:47, Edit by HESS
;<2-UTILITIES>CHECKD.MAC.36, 27-Oct-76 17:39:50, Edit by HESS
;ADD HANDLING OF IDA/MDA ERRORS, HANDLE SF%BTE & SF%CDE FLAGS
;<2-UTILITIES>CHECKD.MAC.35, 27-Oct-76 15:09:09, Edit by HESS
;<2-UTILITIES>CHECKD.MAC.34, 27-Oct-76 14:33:42, Edit by HESS
;HANDLE STRUCTURE DISMOUNTING ON <CTRL-C>
;<2-UTILITIES>CHECKD.MAC.33, 27-Oct-76 12:21:20, Edit by HESS
;<2-UTILITIES>CHECKD.MAC.32, 27-Oct-76 10:04:38, Edit by HESS
;<2-UTILITIES>CHECKD.MAC.31, 27-Oct-76 09:10:14, Edit by HESS
;<2-UTILITIES>CHECKD.MAC.30, 26-Oct-76 13:28:29, Edit by HESS
;<2-UTILITIES>CHECKD.MAC.29, 25-Oct-76 16:45:55, Edit by HESS
;<2-UTILITIES>CHECKD.MAC.28, 25-Oct-76 14:32:42, Edit by HESS
;<2-UTILITIES>CHECKD.MAC.27, 25-Oct-76 13:59:55, Edit by HESS
;<2-UTILITIES>CHECKD.MAC.26, 25-Oct-76 13:34:24, Edit by HESS
;TCO 1620 - NEW COMMANDS FOR STRUCTURE INIT
;<2-UTILITIES>CHECKD.MAC.21, 13-Oct-76 11:18:27, EDIT BY MILLER
;MAKE ^C CAPABILITY NOT ENABLED A FATAL ERROR
;<2-UTILITIES>CHECKD.MAC.20, 12-Oct-76 18:31:37, EDIT BY HURLEY
;PUT REBLD1 BACK. CALL SETSTR FROM INIT CODE IF JOB 0
;<2-UTILITIES>CHECKD.MAC.19, 12-Oct-76 16:26:37, EDIT BY HALL
;MOVED REBLD1 TO MAKE JOB 0 SET UP ITS CONNECTED STRUCTURE
;<2-UTILITIES>CHECKD.MAC.18, 11-Oct-76 17:55:04, EDIT BY HALL
;ADDED TO LOCAL COUNT OF USED PAGES THE PAGES MARKED AS BAD BUT NOT
;IN USE BY A FILE (OR SWAPPING SPACE OR HOME BLOCKS)
;<2-UTILITIES>CHECKD.MAC.17, 28-Sep-76 15:51:24, Edit by HESS
;CHANGE DSKOP CALL TO HAVE DEVICE DESIGNATOR
;<2-UTILITIES>CHECKD.MAC.16,  9-Sep-76 16:38:51, Edit by HESS
;<2-UTILITIES>CHECKD.MAC.15,  9-Sep-76 10:29:35, Edit by HESS
;<2-UTILITIES>CHECKD.MAC.14,  8-Sep-76 17:09:03, Edit by HESS
;<2-UTILITIES>CHECKD.MAC.13,  8-Sep-76 16:46:21, Edit by HESS
;<2-UTILITIES>CHECKD.MAC.12,  8-Sep-76 15:52:36, Edit by HESS
;TCO 1514 - CHANGE FORMAT OF LOST-PAGES.BIN
;<2-UTILITIES>CHECKD.MAC.11,  7-Sep-76 17:22:38, Edit by HESS
;<2-UTILITIES>CHECKD.MAC.6,  7-Sep-76 10:53:02, Edit by HESS
;TCO 1511 - ADD STRUCTURE SUPPORT
;<2-UTILITIES>CHECKD.MAC.3,  1-Aug-76 12:58:49, EDIT BY HALL
;MISCELLANEOUS CHANGES TO ERROR HANDLING
;<2-UTILITIES>CHECKD.MAC.2, 20-Jul-76 12:52:56, EDIT BY HALL
;FIXED TYPO IN FIXCNT
;<2-UTILITIES>CHECKD.MAC.1, 19-Jul-76 16:36:12, EDIT BY HALL
;MASSIVE EDITS TO MAKE CHECKD CONFORM TO RELEASE 2 BIT TABLE FORMAT
;AND VARIABLE DISK SIZES.  ALSO CHANGED ERROR MESSAGES
;<1B-UTILITIES>CHECKD.MAC.5, 27-MAY-76 16:22:42, EDIT BY MILLER
;<1B-UTILITIES>CHECKD.MAC.4, 27-MAY-76 16:20:27, EDIT BY MILLER
;<1B-UTILITIES>CHECKD.MAC.3, 24-MAY-76 15:42:01, EDIT BY HURLEY
;<1B-UTILITIES>CHECKD.MAC.2, 24-MAY-76 15:36:46, EDIT BY HURLEY
;<1B-UTILITIES>CHECKD.MAC.1, 24-MAY-76 12:37:52, EDIT BY MILLER
;TCO 1311. MAKE CHECKD WORK WITH RP04'S OR RP06'S
;<1A-UTILITIES>CHECKD.MAC.40,  6-MAY-76 10:50:37, EDIT BY HURLEY
;<V-SOURCES>CHECKD.MAC.34, 23-MAR-76 16:06:58, EDIT BY HURLEY
;TCO 1214 - ADD CHECKD HELP TEXT
;<V-SOURCES>CHECKD.MAC.33, 27-JAN-76 18:37:14, EDIT BY HURLEY
;MCO 19 - MOVE DSKBTTBL TO ROOT-DIRECTORY
;<V-SOURCES>CHECKD.MAC.32, 30-DEC-75 12:02:05, EDIT BY HURLEY
;<V-SOURCES>CHECKD.MAC.27, 25-NOV-75 14:54:31, EDIT BY MILLER
;<V-SOURCES>CHECKD.MAC;23, 12-AUG-75 11:58:54, EDIT BY MURPHY
;<MURPHY>CHECKD.MAC;20,  9-APR-75 22:52:16, EDIT BY MURPHY

;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 BY DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.

	TITLE CHECKD	;CHECK/RECONSTRUCT CONSISTENCY OF FILE STRUCTURE
	.REQUIRE SYS:MACREL
	SEARCH MONSYM,MACSYM
	SALL
IFNDEF .PSECT,<
	.DIRECT .XTABM
>

;ASSEMBLY SWITCHES

;ENTRY VECTOR

PRGCST==0			;CUSTOMER ID
PRGVER==3			;VERSION NUMBER
PRGMIN==1			;MINOR VERSION
PRGEDT==20			;EDIT NUMBER

ENTVEC:	JRST START		;MAIN START
	JRST START		;REENTER
	BYTE (3)PRGCST (9)PRGVER (6)PRGMIN (18)PRGEDT
	JRST REBST		;REBUILD THE BIT TABLE

; AC'S

F=0
T1=1
T2=2
T3=3
T4=4
Q1=5
Q2=6
Q3=7
P1=10
P2=11
P3=12
CX=16
P=17
;MISCELLANEOUS DEFINITIONS

NWSEC==200			;WORDS/SECTOR ON THE DISK
PGSIZ==1000			;PAGE SIZE
PGSFT==11			;SHIFT FOR CONVERTING ADDRESS TO PAGE

;SIZE OF BIT TABLE FILE IF WRITTEN BY PRE-RELEASE-2 MONITOR

OLDTOP=3100			;SIZE OF TOP HALF OF BIT TABLE
OLDBOT=11300			;SIZE OF BOTTOM HALF OF BIT TABLE

DEFP4S==^D3050			;DEFAULT PAGES FOR SWAPPING
DEFPFS==^D950			;DEFAULT PAGES FOR FRONT END

;INFORMATION ABOUT THE STRUCTURE BEING WORKED ON

BTBTOP:	BLOCK 1			;SIZE OF TOP HALF OF BIT TABLE
BTBBOT:	BLOCK 1			;SIZE OF BOTTOM HALF OF BIT TABLE
BTBPGS:	BLOCK 1			;NUMBER OF PAGES IN BIT TABLE
NSSUN:	BLOCK 1			;NUMBER OF SECTORS IN SWAPPING SPACE
FSSUN:	BLOCK 1			;FIRST SECTOR IN SWAPPING SPACE
NPACKS:	BLOCK 1			;NUMBER OF PACKS IN STRUCTURE
HITRK:	BLOCK 1			;LAST CYLINDER IN STRUCTURE
LOTRK:	BLOCK 1			;FIRST CYLINDER IN STRUCTURE

;INFORMATION ABOUT THE SIZE OF THE STRUCTURE BASED ON THE TYPE OF DISK
;THIS BLOCK WILL BE FILLED BY SUPPLYING THE STRUCTURE NAME TO A JSYS

SECPAG:	BLOCK 1			;SECTORS PER PAGE
SECCYL:	BLOCK 1			;SECTORS PER CYLINDER
PAGCYL:	BLOCK 1			;PAGES PER CYLINDER
CYLUNT:	BLOCK 1			;CYLINDERS PER UNIT
SECUNT:	BLOCK 1			;SECTORS PER UNIT
BTWCYL:	BLOCK 1			;BIT WORDS IN BIT TABLE PER CYLINDER
MINFRE:	BLOCK 1			;MINIMUM FREE PAGES FOR FREE CHOICE
HFLAGS:	BLOCK 1			;FLAGS FROM HOME BLOCK
LPPCYL:	BLOCK 1			;LOST SECTORS PER CYL

;HOME BLOCKS.  EACH NUMBER IS A SECTOR NUMBER RELATIVE TO THE START
;OF A UNIT.  EVERY UNIT IN A STRUCTURE HAS THESE BLOCKS ASSIGNED.
;COPIED FROM <2-MONITOR>STG.MAC 6/23/76

HOME::	0			;BOOT STRAP FOR THE 11
	1			;HOME BLOCK
	2			;BAT BLOCK
	3			;RESERVED
	4			;RESERVED
	5			;RESERVED
	6			;RESERVED
	7			;RESERVED
	10			;RESERVED
	11			;RESERVED
	12			;SECONDARY HOME BLOCK
	13			;SECONDARY BAT BLOCK
NHOME==:.-HOME

;ERROR BITS RETURNED FROM DSKASA

ER%IDA=1B0			;ILLEGAL DISK ADDRESS
ER%MDA=1B1			;MULTIPLY ASSIGNED DISK ADDRESS
ER%BAT=1B2			;BAD ADDRESS MARKED IN BAT BLOCKS

;FLAG BITS FOR MRKBTB TO KNOW WHAT KIND OF ADDRESS IT HAS

MR%PT=1B0			;PAGE TABLE
MR%PTT=1B1			;PAGE TABLE TABLE
MR%SWP=1B2			;SWAPPING SPACE
MR%SPC=1B3			;HOME BLOCKS, BAT BLOCKS, ETC.

;MISCELLANEOUS BITS

FILNB==1B3			;NEW FILE BIT
DSKMSK==-1B14			;MASK TO SELECT ONLY DISK ADDRESS FIELD
ADRMSK==-1B13			;MASK FOR COMPLETE STORAGE ADDRESS

;BAT BLOCK DEFINITIONS

;THE BAT BLOCK IS ONE SECTOR IN LENGTH.  IT CONSISTS OF 4 WORDS OF
;HEADER, FOLLOWED BY DATA, TWO WORDS PER ENTRY, INDICATING WHERE THE
;BAD SPOTS ON THE DISK ARE.  WORD ^D126 CONTAINS A SPECIAL CODE, AND
;WORD ^D127 CONTAINS THE SECTOR NUMBER OF THE BAT BLOCK

MAXBFR==172			;MAX FREE SPACE IN A BAT BLOCK
MAXPAR==MAXBFR/2		;MAX PAIRS IN A BAT BLOCK
MNPAKS==4			;MAXIMUM NO. OF PACKS IN A STRUCTURE
MAXPR==MAXBFR*MNPAKS		;SIZE OF BAT PAIR ARRAY
BPRBLK:	BLOCK MAXPR		;BAT PAIRS
BATBUF:	BLOCK 200		;BUFFER FOR BAT BLOCK

BATBL1==2			;SECTOR NO. OF FIRST BAT BLOCK

;HEADER

BATNAM==0			;OFFSET OF SIXBIT /BAT/
BATFRE==1			;WORD WITH FREE BLOCKS LEFT
DEFSTR BATFR,BATFRE,17,18	;FIELD WITH FREE COUNT
DEFSTR BTFR2,BATFRE+HBLEN,17,18	;IN THE SECONDARY BLOCK
DEFSTR BTHCT,2,17,9		;NUMBER OF PAIRS ADDED BY MAPPER
DEFSTR BTMCT,3,35,36		;COUNT OF PAIRS ADDED BY MONITOR
DEFSTR BTMC2,HBLEN+3,35,36	;IN SECONDARY BLOCK

;DATA PAIRS

DEFSTR BATNB,0,8,9		;COUNT OF BAD BLOCKS IN PAIR
PUBCNT==22			;RIGHT-MOST BIT OF UNARY UNIT FIELD
DEFSTR BTKNM,0,20,3		;MASSBUS CONTROLLER #
DEFSTR BADT,0,21,1		;TYPE FIELD IN BAT PAIR
DEFSTR APRNM,0,35,13		;APR SERIAL NUMBER FIELD
DEFSTR ADD18,1,35,18		;OLD STYLE DISK ADDRESS OF STARTING SECTOR
DEFSTR ADD27,1,35,27		;NEW STYLE ADDRESS OF STARTING SECTOR

;SPECIAL WORDS AT END OF BAT BLOCK

BATCOD==^D126			;OFFSET FOR UNLIKELY CODE 606060
CODE=606060			;THE CODE
BATBLK==^D127			;OFFSET FOR SECTOR NUMBER
;LOCATIONS WHERE THINGS ARE MAPPED

FSTPAG==20000			;FIRST PAGE USED FOR STORAGE
HBUF=FSTPAG			;HELP BUFFER
NHBUFP==4			;LENGTH OF HELP BUFFER
PT=HBUF+<NHBUFP*1000>		;WHERE TO MAP THE PAGE TABLE
PTT=PT+1000			;WHERE TO MAP THE PAGE TABLE TABLE
LOSBUF=PTT+1000			;WHERE TO SAVE LOST PAGES
MAXLOS==40000			;NUMBER OF LOST PAGES THAT CAN BE ACCOUNTED
SYSBTB=LOSBUF+MAXLOS		;PLACE TO MAP THE BIT TABLE
BTBMAX==50000			;MAX SIZE OF THE BIT TABLE
LOCBTB=SYSBTB+BTBMAX		;LOCAL COPY OF THE BIT TABLE
IDXORA=LOCBTB+BTBMAX		;START OF LOCAL COPY OF IDXFIL
NIDXPG==60
DIRORG=IDXORA+<NIDXPG*1000>	;START OF MAP AREA FOR DIRECTORY
NDIRPG==500			;MAX SIZE OF DIR IN PAGES

LSTPPG==DIRORG+<NDIRPG*1000>	;END OF PAGE AREA

IF2,<IFL <770000-LSTPPG>,<PRINTX MAPPED PAGE AREA OVERLAPS DDT AREA>>

;JFN'S

BTBJFN:	BLOCK 1			;JFN FOR BIT TABLE FILE
INJFN:	BLOCK 1			;JFN FOR INPUT FILE FOR RELEASE COMMAND
OUTJFN:	BLOCK 1			;JFN FOR OUTPUT FILE FOR LOST-PAGES.BIN
DAJFN:	BLOCK 1			;JFN OF FILE BEING READ BY SCAN COMMAND
FDJFN:	BLOCK 1			;JFN OF DIRECTORY BEING CHECKED

;FLAGS - SET ACCORDING TO COMMAND TYPED

REBLDF:	BLOCK 1			;REBUILD BITTAB IF NON-0
CHKFLF:	BLOCK 1			;CHECK FILES IF NON-0, ELSE DIRECTORIES ONLY

;COUNTS OF ERRORS FOUND BY BUILD
;ZSTART THRU ZEND ARE ZEROED BY BUILD

ZSTART:
NBAD:	BLOCK 1			;ALL ERRORS
NDE:	BLOCK 1			;BAD PAGE TABLE ADDRESSES IN FDB'S
NPTTE:	BLOCK 1			;BAD PAGE TABLE TABLE ADDRESSES IN FDB'S
NBPT:	BLOCK 1			;FAILURES TO READ PAGE TABLES
NBPTT:	BLOCK 1			;FAILURES TO READ PAGE TABLE TABLES
NBPTE:	BLOCK 1			;BAD ADDRESSES IN PAGE TABLES
NBPTTE:	BLOCK 1			;BAD ADDRESSES IN PAGE TABLE TABLES
NIDA:	BLOCK 1			;ILLEGAL ADDRESSES
NMDA:	BLOCK 1			;MULTIPLY ASSIGNED ADDRESSES
NSDA:	BLOCK 1			;SEARCHED-FOR ADDRESSES FOUND
NDSKER:	BLOCK 1			;DISK READ ERRORS
NNBT:	BLOCK 1			;ADDRESSES NOT IN BIT TABLE
				; (BELONGING TO A FILE, BUT NOT ASSIGNED)
NABAT:	BLOCK 1			;ASSIGNED PAGES THAT ARE MARKED AS BAD
ZEND=.-1

;MISCELLANEOUS STORAGE

DIRORA:	DIRORG			;POINTER TO BASE OF MAPPED DIR
SVEND:	BLOCK 1			;END OF BAT PAIR
LOSTOT:	BLOCK 1			;NUMBER LOST PAGES
NLINB==^D80/5			;SIZE OF INPUT LINE BUFFER
LINBUF:	BLOCK NLINB
PAGNN:	BLOCK 1			;CURRENT OFFSET IN INDEX BLOCK (PAGE NO. IN FILE)
DALIST:	BLOCK 1			;AOBJN POINTER TO DATAB
DASIZ==2000
TMPBUF:				;TEMPORARY STRING BUFFER
DATAB:	BLOCK DASIZ		;LIST OF DISK ADDRESSES BEING LOOKED FOR VIA SCAN COMMAND
PDL:	BLOCK 100		;STACK
DIRNAM:	BLOCK 21		;NAME OF CURRENT DIRECTORY
DIRNUM:	BLOCK 1			;NUMBER OF CURRENT DIRECTORY
STRNAM:	BLOCK 10		;STRUCTURE NAME STRING
STRHOM:	BLOCK 10		;STR NAME ACTUALLY IN HOME BLOCK
JOBNO:	BLOCK 1			;NUMBER OF THIS JOB
ZUSED:	BLOCK 1			;NO. PAGES USED BEFORE CHECKD RAN
WRTLPF:	BLOCK 1			;WRITE LOST-PAGES.BIN IF .NE. 0
LPFHED:	BLOCK 5			;HEADER ON LOST-PAGES FILE
SYMTOP:	BLOCK 1			;ADDRESS OF END OF SYMBOL TABLE
STRDEV:	BLOCK 1			;CURRENT STR (DEVICE DESIGNATOR)
OVERHD:	BLOCK 1			;COUNT OF USED PAGES NOT ASSIGNED TO FILES
BATCNT:	BLOCK 1			;COUNT OF BAD PAGES (DECREMENTED WHEN
				; THE PAGE IS USED BY A FILE)
PAGCNT:	BLOCK 1 		;COUNT OF FILE PAGES FOR THE CURRENT FILE
TOTPGS:	BLOCK 1			;TOTAL FILE PAGES IN USE
NAMBUF:	BLOCK 10		;BUFFER FOR STR NAME STRINGS
IDZB:!				;BEGIN OF ID ZERO AREA
UNITID:	BLOCK 4			;UNIT ID BUFFER
OWNRID:	BLOCK 4			;OWNER ID BUFFER
IDZZ==.-1			;END OF ID ZERO AREA
NPG4SW:	BLOCK 1			;NUMBER OF PAGES FOR SWAPPING
NPGFES: BLOCK 1			;NUMBER OF PAGES FOR FRONT-END
MNTBLK:	BLOCK 50		;STORAGE FOR MOUNTING STRS
HOMARG:	BLOCK 4			;ARG BLOCK FOR MODIFYING HOME BLOCK
RNUBLK:	BLOCK .MSRLN		;BLOCK FOR .MSRNU FCN
STRMNT:	BLOCK 1			;DEVICE DESIGNATOR OF MOUNTED STR.
FCNBLK:	BLOCK 4			;FUNCTION BLOCK FOR COMND
SAVREP:	BLOCK 1			;REPARSE PDL POINTER
SAVRET:	BLOCK 1			;REPARSE RETURN ADDRS
OKFLG:	BLOCK 1			;FLAG FOR FNDSTR
PSFLG:	BLOCK 1			;-1 IF THIS IS REALLY PS:

;THE FOLLOWING LOCATIONS ARE USED IN DIRECTORY SCANNING (GTFILE) TO CONVERT
;DIRECTORY NUMBER TO FILE NAME

ROOTDR:	BLOCK 20		;PLACE FOR STR:<ROOT-DIRECTORY>
ROOTPT:	BLOCK 1			;POINTER TO END OF ABOVE STRING
FILNAM:	BLOCK 25		;PLACE FOR STR:<DIRECTORY>SUBDIR.DIRECTORY
DOTPTR:	BLOCK 1			;POINTER TO LAST DOT
BRKPTR:	BLOCK 1			;POINTER TO LEFT BRACKET


;OVERHEAD IS ALL PAGES USED AS FOLLOWS:
;	HOME BLOCKS
;	SWAPPING SPACE
;	PAGE TABLE TABLE
;	PAGE TABLE
;	MARKED AS BAD AND NOT USED BY ANY OF THE ABOVE OR AS A FILE PAGE

;PAGNN SERVES AS A COUNTER INTO A FILE.  IT IS USED IN MRKBTB TO
;TELL WHAT PAGE AN ERROR IS IN.
;IF THE FILE IS LONG, THE PAGE NUMBER IS INCREMENTED ONCE FOR EVERY
;ENTRY IN A PAGE TABLE AND 1000 FOR EVERY ENTRY IN THE PAGE TABLE TABLE
;THAT IS ZERO.  THUS WITH A SPARSE FILE, PAGNN HAS THE SAME VALUE AS IF
;IT WERE NOT SPARSE. PAGNN IS -1 WHEN MRKBTB IS CALLED FOR ANY OTHER
;PAGE (PAGE TABLE, SWAPPING SPACE)


;VALUES FOR FILE CURRENTLY BEING SCANNED
;KEEP THESE IN ORDER

DEFVER:	BLOCK 1			;VERSION
DEFNAM:	BLOCK 1			;NAME
DEFEXT:	BLOCK 1			;EXTENSION
	BLOCK 4

;INTERRUPT LOCATIONS

;PC'S SAVED HERE

RET1:	BLOCK 1
RET2:	BLOCK 1
RET3:	BLOCK 1

; [LOCATION WHERE PC STORED BY LEVEL]

LEVTAB:	RET1
	RET2
	RET3

; [LEVEL,,INTERRUPT ADDRESS]

CHNTAB:	XWD 2,BADINT		;UNKNOWN CHANNEL
	XWD 1,CONTC		;^C
	XWD 3,SUMINT		;^A
	XX==3
	REPEAT ^D36-3,<2,,DSPINT+XX
		XX=XX+1>
; * * * *
;THIS PAGE REFLECTS SPECIFIC KNOWLEDGE OF THE TYPES OF DISKS THAT ARE
;SUPPORTED.  IT, AND THE ASSOCIATED HOME BLOCK CODE, SHOULD BE REPLACED
;BY AN MSTR THAT OBTAINS THE SAME DATA FOR THE SPECIFIC DRIVE.
; * * * *

;DATA FOR RP04 AND RP05

SECPG0==PGSIZ/NWSEC		;SECTORS PER PAGE
SECCY0==^D19*^D20		;SECTORS PER CYLINDER
LPPCT0==0			;LOST SECTORS PER CYL
PAGCY0==SECCY0/SECPG0		;PAGES PER CYLINDER
CYLUN0==^D400			;CYLINDERS PER UNIT
SECUN0==SECCY0*CYLUN0		;SECTORS PER UNIT
BTWCY0==<PAGCY0+^D35>/^D36	;NUMBER BIT WORDS IN BIT TABLE FOR A CYLINDER
MINFP0==PAGCY0/3		;MINIMUM FREE PAGES FOR FREE CHOICE ALLOCATION
				; IN DSKASN

;DATA FOR RP06

SECPG1==PGSIZ/NWSEC		;SECTORS PER PAGE
SECCY1==^D19*^D20		;SECTORS PER CYLINDER
LPPCT1==0			;LOST SECTORS PER CYL
PAGCY1==SECCY1/SECPG1		;PAGES PER CYLINDER
CYLUN1==^D800			;CYLINDERS PER UNIT
SECUN1==SECCY1*CYLUN1		;SECTORS PER UNIT
BTWCY1==<PAGCY1+^D35>/^D36	;NUMBER OF BIT WORDS PER CYLINDER IN BIT TABLE
MINFP1==PAGCY1/3		;MINIMUM FREE PAGES FOR FREE CHOICE ALLOCATION
				; IN DSKASN

;DATA FOR RM03

SECPG3==PGSIZ/NWSEC		;SECTORS PER PAGE
LPPCT3==2			;LOST SECTORS PER CYL
SECCY3==<^D5*^D30>-LPPCT3	;SECTORS PER CYLINDER
PAGCY3==SECCY3/SECPG3		;PAGES PER CYLINDER
CYLUN3==^D820			;CYLINDERS PER UNIT
SECUN3==SECCY3*CYLUN3		;SECTORS PER UNIT
BTWCY3==<PAGCY3+^D35>/^D36	;NUMBER OF BIT WORDS PER CYLINDER IN BITTABLE
MINFP3==PAGCY3/3		;MINIMUM FREE PAGES FOR FREE CHOICE ALLOCATION

;RP04 AND RP05

DSKSZ0::SECPG0			;SECTORS PER PAGE
	SECCY0			;SECTORS PER CYLINDER
	PAGCY0			;PAGES PER CYLINDER
	CYLUN0			;CYLINDERS PER UNIT
	SECUN0			;SECTORS PER UNIT
	BTWCY0			;BIT WORDS IN BIT TABLE PER CYLINDER
	MINFP0			;MINIMUM FREE PAGES FOR FREE CHOICE ALLOCATION
	LPPCT0			;LOST SECTORS PER CYL
				; IN DSKASN

;RP06

DSKSZ1::SECPG1			;SECTORS PER PAGE
	SECCY1			;SECTORS PER CYLINDER
	PAGCY1			;PAGES PER CYLINDER
	CYLUN1			;CYLINDERS PER UNIT
	SECUN1			;SECTORS PER UNIT
	BTWCY1			;BIT WORDS IN BIT TABLE PER CYLINDER
	MINFP1			;MINIMUM FREE PAGES FOR FREE CHOICE ALLOCATION
	LPPCT1			;LOST SECTORS PER CYL

;RM03

DSKSZ3::SECPG3		;SECTORS PER PAGE
	SECCY3		;SECTORS PER CYLINDER
	PAGCY3		;PAGES PER CYLINDER
	CYLUN3		;CYLINDERS PER UNIT
	SECUN3		;SECTORS PER UNIT
	BTWCY3		;BIT WORDS IN BITTABLE
	MINFP3			;MINIMUM FREE PAGES FOR FREE CHOICE ALLOCATION
	LPPCT3			;LOST SECTORS PER CYL

				; IN DSKASN

DEFINE SAVEQ<
	JSP CX,SAVQ>

SAVQ::	PUSH P,Q1		;SAVE Q1-Q3
	PUSH P,Q2
	PUSH P,Q3
	PUSHJ P,0(CX)		;CONTINUE ROUTINE, EXIT VIA .+1
RESTQ::	 SKIPA			;NON-SKIP RETURN
	AOS -3(P)		;SKIP RETURN
	POP P,Q3
	POP P,Q2
	POP P,Q1
	RET

DEFINE SAVET<
	JSP CX,SAVT>

SAVT::	PUSH P,T1		;SAVE T1-T4
	PUSH P,T2
	PUSH P,T3
	PUSH P,T4
	PUSHJ P,0(CX)		;CONTINUE ROUTINE, RETURN VIA .+1
RESTT:	SKIPA			;NO-SKIP RETURN
	AOS -4(P)		;PASS ALONG SKIP RETURN
	POP P,T4
	POP P,T3
	POP P,T2
	POP P,T1
	RET

;MACRO TO PRINT AN ERROR MESSAGE AND TRANSFER.  IF THE MSG FIELD IS
;SPECIFIED, IT IS PRINTED.  IF FILFLG IS NON-BLANK, THE FILE SPEC POINTED
;TO BY DIRNAM, DEFNAM, ETC., IF PRINTED AT THE END OF THE MESSAGE.
;A JSERR IS DONE TO GET THE LAST ERROR.  IF AN ADDRESS IS SPECIFIED, A
;JRST TO IT IS GENERERATED.  NOTE THAT THIS CODE IS NOT SKIPPABLE.

	DEFINE PNTERR (MSG,ADDR,FILFLG)<
	IFNB <MSG>,<
	HRROI T1,[ASCIZ/
? CHECKD: MSG /]
	PSOUT			;PRINT THE MESSAGE IF ANY
	IFNB <FILFLG>,<CALL PNTFIL>> ;PRINT THE FILE NAME IF REQUESTED
	JSERR			;DO STANDARD JSYS ERROR PRINTING
	IFNB <ADDR>,<JRST ADDR>	;JRST TO SPECIFIED ADDRESS IF ANY
	>

	DEFINE RETERR (MSG)<
	 JRST [	TMSG <
? CHECKD: MSG
>
		RET]
>
;BITS+N CONTAINS A WORD WITH A 1 IN BIT N

XX==0
BITS::	REPEAT ^D36,<EXP 1B<XX>
		XX=XX+1>
;DIRECTORY RELATED DEFSTR'S
;COPIED FROM PROLOG.MAC

;DIRECTORY HEADER (FOR PAGE 0; FIRST 3 WORDS ARE REPEATED ON
;SUBSEQUENT PAGES)

DEFSTR DRTYP,0,17,18		;BLOCK TYPE OF DIRECTORY (.TYDIR)
DEFSTR DRVER,0,23,6		;VERSION # OF DIRECTORY
DEFSTR DRHLN,0,35,12		;LENGTH OF HEADER AREA
DEFSTR DRRPN,1,17,18		;RELATIVE PAGE # WITHIN DIRECTORY
DEFSTR DRNUM,1,35,18		;DIRECTORY NUMBER
DEFSTR DRFFB,.DRFFB,35,36	;FIRST FREE BLOCK ON THIS PAGE
DEFSTR DRSBT,3,35,36		;ADDRESS OF BOTTOM OF SYMBOL TABLE
DEFSTR DRSTP,4,35,36		;ADDRESS OF TOP OF SYMBOL TABLE
DEFSTR DRFTP,5,35,36		;ADDRESS OF LAST USED WORD + 1
DEFSTR DRFBT,6,35,36		;POINTER TO FREE POOL BIT TABLE
DEFSTR DRDPW,7,35,36		;DEFAULT FILE PROTECTION
DEFSTR DRPRT,10,35,36		;DEFAULT DIRECTORY PROTECTION
	DEFSTR DRPOW,10,23,6	;OWNER FIELD
	DEFSTR DRPGP,10,29,6	;GROUP FIELD
	DEFSTR DRPWL,10,35,6	;WORLD FIELD
DEFSTR DRDBK,11,35,36		;BACKUP SPECIFICATION
DEFSTR DRLIQ,12,35,36		;LOGIN DISK QUOTA
DEFSTR DRLOQ,13,35,36		;LOGGED OUT QUOTA
DEFSTR DRDCA,14,35,36		;CURRENT DIR ALLOCATION
DEFSTR DRNAM,15,35,36		;POINTER TO NAME STRING
DEFSTR DRPSW,16,35,36		;POINTER TO PASSWORD STRING
DEFSTR DRPRV,17,35,36		;PRIVILEGE BITS
DEFSTR DRMOD,20,35,36		;MODE BITS
DEFSTR DRDAT,21,35,36		;TIME AND DATE OF LAST LOGIN
DEFSTR DRUGP,22,35,36		;USER GROUPS
DEFSTR DRDGP,23,35,36		;DIRECTORY GROUPS
DEFSTR DRUDT,24,35,36		;LAST UPDATE TIME OF DIR
DEFSTR DRSDC,25,35,18		;COUNT OF SUBDIRECTORIES
DEFSTR DRSDM,25,17,18		;MAXIMUM NUMBER OF SUBDIRECTORIES
DEFSTR DRCUG,26,35,36		;CRDIR ALLOWED SPECIFYING THESE USER GRPS

	.DIHL0==:100		;LENGTH OF DIR PAGE 0 HEADER (+ SPARES)
	.DIHL1==:3		;LENGTH OF HEADER FOR DIR PAGES 1 & UP
	.DRFFB==:2		;OFFSET OF FIRST FREE BLOCK POINTER
;GENERAL FORMAT FOR ALL BLOCKS

DEFSTR BLKTYP,0,17,18		;TYPE CODE FOR STANDARD FORMAT BLOCKS
				;NMTYP, EXTYP, ACTYP, SYMTY, DRTYP,
				;UNTYP, FBTYP, AND FRTYP
DEFSTR BLKVER,0,23,6		;VERSION NUMBER OF BLOCK
DEFSTR BLKLEN,0,35,12		;LENGTH OF STANDARD FORMAT BLOCK

;SYMBOL TABLE

;	SYMBOL TABLE HEADER

DEFSTR SYMTY,0,17,18		;SYMBOL TABLE TYPE CODE (.TYSYM)
DEFSTR SYMDN,0,35,18		;DIR NUMBER OF SYMBOL TABLE

;	SYMBOL TABLE ENTRIES

	SY%ET==:7B2		;SYMBOL TABLE ENTRY TYPE MASK
	.SYMAD==:0		;POSITION OF ADDRESSES IN SYMBOL TABLE
	.SYMVL==:1		;POSITION OF SYMBOL HASH VALUE WORD
	.SYMLN==:2		;# OF WORDS IN A SYMBOL TABLE ENTRY
DEFSTR SYMET,.SYMAD,2,3		;SYMBOL TABLE ENTRY TYPE
DEFSTR SYMAD,.SYMAD,35,33	;ADDRESS OF BLOCK IN DIR FOR THIS SYM
DEFSTR SYMVL,.SYMVL,35,36	;FIRST 5 CHARACTERS OF NAME OR ACCOUNT
	.ETNAM==:0		;ENTRY TYPE OF NAME
	.ETUNS==:2		;ENTRY TYPE OF USER NAME
	.ETACT==:4		;ENTRY TYPE OF ACCOUNT

;NAME BLOCK

DEFSTR NMTYP,0,17,18		;NAME BLOCK TYPE CODE (.TYNAM)
DEFSTR NMLEN,0,35,12		;LENGTH OF NAME BLOCK
DEFSTR NMVAL,1,35,36		;FIRST 5 CHARACTERS OF NAME STRING

;EXTENSION BLOCK

DEFSTR EXTYP,0,17,18		;EXTENSION BLOCK TYPE CODE (.TYEXT)
DEFSTR EXLEN,0,35,12		;LENGTH OF EXTENSION BLOCK

;ACCOUNT STRING BLOCK

DEFSTR ACTYP,0,17,18		;ACCOUNT STRING BLOCK TYPE CODE (.TYACT)
DEFSTR ACLEN,0,35,12		;LENGTH OF ACCOUNT BLOCK
DEFSTR ACSHR,1,35,36		;SHARE COUNT OF ACCOUNT STRING
	.ACVAL==2		;START OF ACCOUNT STRING
DEFSTR ACVAL,.ACVAL,35,36	;FIRST 5 CHARACTERS OF ACCOUNT STRING

;USER NAME STRING BLOCK

DEFSTR UNTYP,0,17,18		;USER STRING BLOCK TYPE CODE (.TYUNS)
DEFSTR UNLEN,0,35,12		;LENGTH OF USER NAME BLOCK
DEFSTR UNSHR,1,35,36		;SHARE COUNT OF USER NAME STRING
DEFSTR UNVAL,2,35,36		;FIRST 5 CHARS OF USER NAME STRING

;FREE POOL BLOCK

	.FRNFB==:1		;OFFSET OF NEXT FREE BLOCK POINTER
	.FRHLN==:2		;LENGTH OF FREE BLOCK HEADER
DEFSTR FRTYP,0,17,18		;FREE BLOCK TYPE CODE (.TYFRE)
DEFSTR FRVER,0,23,6		;VERSION # OF FREE BLOCK
DEFSTR FRLEN,0,35,12		;LENGTH OF THIS FREE BLOCK
DEFSTR FRNFB,.FRNFB,35,36	;POINTER TO NEXT FREE BLOCK
;FDB DEFINITIONS

DEFSTR FBTYP,.FBHDR,17,18	;FDB TYPE CODE (.TYFDB)
DEFSTR FBVER,.FBHDR,23,6	;VERSION # OF FDB (0 := PRE-V2)
DEFSTR FBLEN,.FBHDR,35,12	;LENGTH OF FDB
DEFSTR FBFLG,.FBCTL,35,36	;FLAGS
	MSKSTR (FBTMP,.FBCTL,FB%TMP)
	MSKSTR (FBPRM,.FBCTL,FB%PRM)
	MSKSTR (FBNEX,.FBCTL,FB%NEX)
	MSKSTR (FBDEL,.FBCTL,FB%DEL)
	MSKSTR (FBNXF,.FBCTL,FB%NXF)
	MSKSTR (FBLNG,.FBCTL,FB%LNG)
	MSKSTR (FBSHT,.FBCTL,FB%SHT)
	MSKSTR (FBDIR,.FBCTL,FB%DIR)
	MSKSTR (FBNOD,.FBCTL,FB%NOD)
DEFSTR FBEXL,.FBEXL,35,33	;LINK TO NEXT EXTENSION FDB
DEFSTR FBADR,.FBADR,35,36	;DISK ADDRESS OF INDEX BLOCK
DEFSTR FBPRT,.FBPRT,35,36	;PROTECTION OF THE FILE
DEFSTR FBCRE,.FBCRE,35,36	;TIME AND DATE OF LAST WRITE
DEFSTR FBLW0,.FBUSE,17,18	;VER #0 LAST WRITER DIR #
DEFSTR FBAT0,.FBUSE,35,18	;VER #0 AUTHOR DIR #
DEFSTR FBAUT,.FBAUT,35,36	;POINTER TO AUTHOR STRING
DEFSTR FBLWR,.FBLWR,35,36	;POINTER TO LAST WRITER STRING
DEFSTR FBGEN,.FBGEN,17,18	;GENERATION # OF FILE
DEFSTR FBDRN,.FBDRN,35,18	;DIR NUMBER (IF THIS IS A DIR FILE)
DEFSTR FBACT,.FBACT,35,36	;ACCOUNT # OR POINTER TO ACCOUNT BLOCK
DEFSTR FBGNR,.FBBYV,5,6		;GENERATION RETENTION COUNT
DEFSTR FBBSZ,.FBBYV,11,6	;BYTE SIZE OF DATA IN FILE
DEFSTR FBMOD,.FBBYV,17,4	;MODE OF LAST WRITE TO FILE
DEFSTR FBNPG,.FBBYV,35,18	;# OF PAGES IN FILE
DEFSTR FBSIZ,.FBSIZ,35,36	;# OF BYTES IN THE FILE
DEFSTR FBCRV,.FBCRV,35,36	;CREATION TIME AND DATE OF FILE
DEFSTR FBWRT,.FBWRT,35,36	;DATE AND TIME OF LAST USER WRITE
DEFSTR FBREF,.FBREF,35,36	;TIME AND DATE OF LAST NON-WRITE ACCESS
DEFSTR FBNWR,.FBCNT,17,18	;# OF WRITES TO FILE
DEFSTR FBNRF,.FBCNT,35,18	;# OF REFERENCES TO FILE
DEFSTR FBBK0,.FBBK0,35,36	;BACKUP WORD 0
DEFSTR FBBK1,.FBBK1,35,36	;BACKUP WORD 1
DEFSTR FBBK2,.FBBK2,35,36	;BACKUP WORD 2
DEFSTR FBBK3,.FBBK3,35,36	;BACKUP WORD 3
DEFSTR FBBK4,.FBBK4,35,36	;BACKUP WORD 4
DEFSTR FBUSW,.FBUSW,35,36	;USER SETTABLE WORD
DEFSTR FBGNL,.FBGNL,35,33	;LINK TO NEXT GENERATION
DEFSTR FBNAM,.FBNAM,35,36	;POINTER TO NAME STRING
DEFSTR FBEXT,.FBEXT,35,36	;POINTER TO EXTENSION STRING

	.FBLN0==:30		;MINIMUM LENGTH OF AN FDB

;BLOCK TYPE CODES - FOUND IN LEFT HALF OF WORD 0 OF THE BLOCK

	.TYNAM==:400001		;BLOCK TYPE OF NAME STRING
	.TYEXT==:400002		;BLOCK TYPE OF EXTENSION STRING
	.TYACT==:400003		;BLOCK TYPE OF ACCOUNT STRING
	.TYUNS==:400004		;BLOCK TYPE OF USER NAME STRING
	.TYFDB==:400100		;BLOCK TYPE OF FDB
	.TYLAC==:400200		;BLOCK TYPE OF LEGAL ACCOUNT LIST
	.TYDIR==:400300		;BLOCK TYPE OF DIRECTORY BLOCK
	.TYSYM==:400400		;BLOCK TYPE OF SYMBOL TABLE
	.TYFRE==:400500		;BLOCK TYPE OF BLOCK ON THE FREE LIST
	.TYFBT==:400600		;BLOCK TYPE OF FREE STORAGE BIT TABLE
	.TYGDB==:400700		;BLOCK TYPE OF GROUP DESCRIPTOR BLOCK
;HOME BLOCK DEFINITIONS - COPIED FROM <2-MONITOR>DSKAL1.MAC

CODHOM==:707070			;HOME BLOCK SPECIAL CODE
HBLEN==:200			;LENGTH OF HOME BLOCK
HM1BLK==:1			;BLOCK # OF FIRST HOME BLOCK
HM2BLK==:^D10			;BLOCK # OF SECOND HOME BLOCK

HOMNAM==:0			;SIXBIT /HOM/
HOMID==:1			;SIXBIT /ID/
HOMPHY==:2			;PHYSICAL ADR'S OF HOME BLOCKS
HOMSNM==:3			;SIXBIT /STRUCTURE NAME/
HOMLUN==:4			;XWD TOTAL PACKS, LOGICAL PACK #
HOMHOM==:5			;BLOCK # OF HOME BLK,, BLK # OF OTHER HB
HOMP4S==:6			;# OF PAGES FOR SWAPPING ON EACH UNIT
HOMFST==:7			;FIRST SWAPPING TRACK ON EACH UNIT
HOMRXB==:10			;ADR OF INDEX BLOCK OF ROOT DIRECTORY
HOMBXB==:11			;INDEX BLOCK ADR OF BACKUP FILE
HOMFLG==:12			;FLAGS
HOMSIZ==:13			;SIZE OF A UNIT IN SECTORS (BLOCKS)
HOMBTB==:14			;SIZE OF TOP HALF OF BIT TABLE (NUMBER OF TRACKS)

HOMFE0==:61			;FE FILE SYSTEM WORD ONE (SECTOR #)
HOMFE1==:62			;FE FILE SYSTEM WORD TWO (# OF SECTORS)

HOMUID==:165			;UNIT ID
HOMOID==:170			;OWNER ID
HOMFSN==:173			;FILE SYSTEM TYPE
HOMCOD==:176			;0 ,, CODHOM
HOMSLF==:177			;THIS HOME BLOCK #
;DATA AND MACROS FOR COMMAND PARSER (USES COMND JSYS)

;TB - MACRO TO SET UP COMMAND TABLE 

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

;ADDRESSES FOR HANDLING EACH COMMAND

CMDTAB:	CMDSIZ-1,,CMDMAX-1		;NUMBER COMMANDS, MAXIMUM NUMBER
	TB (.CHECK,CHECK)	;CHECK (BITTABLE/DIRECTORY)
	TB (.CREAT,CREATE)	;CREATE NEW FILE SYSTEM
	TB (.EXIT,EXIT)		;EXIT FROM CHECKD TO MONITOR
	TB (.HELP,HELP)		;PRINT HELP TEXT
	TB (.LIMIT,LIMIT)	;CONTROL SIZE OF DIRECTORIES
	TB (.REBLD,REBUILD)	;REBUILD BIT TABLE
	TB (.RECNS,RECONSTRUCT)	;RECONSTRUCT ROOT-DIRECTORY
	TB (.RLEAS,RELEASE)	;RELEASE LOST PAGES
	TB (.SCAN,SCAN)		;SCAN FILE FOR PAGE NUMBERS
	TB (.UNLIM,UNLIMIT)	;LET DIRECTORIES GROW LARGE

CMDSIZ==.-CMDTAB
CMDMAX==CMDSIZ			;MAXIMUM NUMBER OF COMMANDS
NCHPW==5			;NUMBER OF CHARACTERS PER WORD
PROMPT:	ASCIZ /CHECKD>/		;PROMPT
CMDBLK:	BLOCK .CMGJB+5		;COMMAND STATE BLOCK (LEAVE ROOM FOR GROWTH)
GJFSIZ==.GJBFP+2
GTJBLK:	BLOCK GJFSIZ		;GTJFN BLOCK (USED BY COMND)

BUFSIZ==150			
BUFFER:	BLOCK BUFSIZ		;BUFFER USER TYPES COMMAND INTO
ATMSIZ==BUFSIZ
ATMBUF:	BLOCK ATMSIZ		;BUFFER THAT COMND STORES LAST FIELD INTO

;THE FOLLOWING MACRO IS DEFINE IN MONSYM.  THIS COPY IS FOR REFERENCE

;FLDDB. - MACRO FOR BUILDING FUNCTION DESCRIPTOR BLOCK
;  ARGUMENTS:
;	TYP - FUNCTION TYPE (WORD 0)
;	FLGS - FUNCTION SPECIFIC FLAGS (WORD 0)
;	DATA - DATA FOR FUNCTION (WORD 1)
;	HLPM - HELP TEXT (WORD 2)
;	DEFM - DEFAULT STRING (WORD 3)
;	LST - ADDRESS OF NEXT FUNCTION DESCRIPTOR BLOCK
;IF HLPM IS NON-BLANK, SETS CM%HPP
;IF DEFM IS NON-BLANK, SETS CM%DPP

;DEFINE FLDDB. (TYP,FLGS,DATA,HLPM,DEFM,LST)<
;	..XX==<FLD(TYP,CM%FNC)>+FLGS+<Z LST>
;   IFNB <HLPM>,<..XX=..XX+CM%HPP>
;   IFNB <DEFM>,<..XX=..XX+CM%DPP>
;	..XX				;WORD 0
;   IFNB <DATA>,<DATA>			;WORD 1
;   IFB <DATA>,<0>
 ;   IFNB <HLPM>,<POINT 7,[ASCIZ \HLPM\]> ;WORD 2
;   IFB <HLPM>,<IFNB <DEFM>,<0>>
;   IFNB <DEFM>,<POINT 7,[ASCIZ \DEFM\]>> ;WORD 3

;ERROR - MACRO TO PRINT ERROR AND GO TO SPECIFIED LOCATION
;USED IN PARSING CODE WHEN COMND RETURNS CM%NOP

	DEFINE ERROR (ADDR,MSG)<
	JRST  [	HRROI T1,[ASCIZ /
? MSG
/]
		PSOUT		;PRINT THE MESSAGE
		MOVE T1,[CZ%NCL+.FHSLF]
		CLZFF		;RELEASE ALL JFNS
		JRST ADDR]>

;TXTPTR- MACRO TO SET UP BYTE POINTER TO A STRING

	DEFINE TXTPTR (MSG) <POINT 7,[ASCIZ/MSG/]>

;GTJFN BLOCK FOR LOST-PAGES.BIN (RELEASE COMMAND)

RLSGTJ:	GJ%OLD!GJ%PHY		;OLD FILE ONLY
	.PRIIN,,.PRIOU		;INPUT/OUTPUT JFN
	-1,,STRNAM		;DEFAULT STRUCTURE
	0			;NO DEFAULT DIRECTORY
	-1,,DIRNAM		;DEFAULT FILENAME
	-1,,[ASCIZ/BIN/]	;DEFAULT EXTENSION
	0			;NO DEFAULT PROTECTION
	0			;NO DEFAULT ACCOUNT NUMBER
	0			;NO JFN SPECIFIED
;FORMAT OF LOST-PAGES.BIN FILE

.LPFLG==0			;FLAG WORD
  .LPMJK==<252525,,'LPF'>	;MAJIK CONSTANT IN FLAG WORD
.LPTAD==1			;DATE-TIME STAMP
.LPSTR==2			;ASCIZ STR NAME
.LPCNT==4			;NUMBER OF ENTRIES
.LPDTA==5			;BEGINNING OF DATA
;ALL COMMANDS RETURN HERE TO RE-START CHECKD AND DISMOUNT
; ANY PREVIOUSLY MOUNTED STRUCTURE.

RESTRT:	SKIPN JOBNO		;ARE WE JOB 0
	JRST QUIT		;YES - JUST EXIT

	CALL DISMNT		;DISMOUNT IF NECESSARY
	CALL RESET		;RESET STORAGE
	MOVEI T1,1		;TURN OFF PSI CHANNELS
	DTI
	MOVEI T1,3		;FOR ^A AND ^C
	DTI
	TMSG <
>
	JRST START		;GO RESTART PROGRAM

;SPECIAL ENTRY IF REBUILDING BIT TABLE AUTOMATICALLY

REBST:	SETOM REBLDF		;INDICATE REBUILD REQUESTED
	JRST START0		;COMMON ENTRY

;NORMAL ENTRY

START:	SETZM REBLDF		;DEFAULT IS NO REBUILD BITTAB
START0:	MOVE P,[IOWD 100,PDL]
	CALL RESET
	SETOM CHKFLF		;DEFAULT IS CHECK FILES
	SETZM DIRNUM		;INITIALIZE DIRECTORY NUMBER
	SETZM TOTPGS		;INITIALIZE TOTAL FILE PAGES
	SETZM ZUSED		;CLEAR INFO ABOUT STG
	SETOM WRTLPF		;DEFAULT IS WRITE LOST PAGES FILE
	SETZM STRMNT		;NO STRUCTURE MOUNTED YET
	GJINF
	MOVEM T3,JOBNO
	MOVEI T1,.FHSLF
	RPCAP
	SKIPE JOBNO		;SKIP IF JOB 0
	JRST STRT1
	MOVX T3,SC%WHL!SC%OPR	;ENABLE CAPS
	EPCAP
	JRST STRT2
STRT1:	TXNN T3,SC%WHL!SC%OPR	;CHECK ENABLED CAPS
	JRST [	TMSG <?WHEEL or OPERATOR capability required
>
		JRST QUIT]
	TXNN T2,SC%CTC		;CHECK FOR ^C CAP
	JRST [	TMSG <? ^C capability not enabled
>
		HALTF
		JRST START]	;MAKE CONTINUE RESTART
	MOVX T3,SC%CTC!SC%WHL!SC%OPR
	EPCAP			;ENABLE ^C CAP ALSO
STRT2:	SETZM DALIST		; NO DISC ADDRESS LIST

;SET UP INTERRUPT SYSTEM

	MOVEI T1,.FHSLF		;T1/FORK HANDLE
	CIS			;CLEAR THE INTERRUPT SYSTEM
	EIR			;ENABLE INTERRUPTS
	MOVE T2,[XWD LEVTAB,CHNTAB] ;DECLARE LEVTAB AND CHNTAB
	SIR
	MOVNI T2,1		;T2/CHANNEL NUMBERS
	DIC			;DEACTIVATE ALL CHANNELS
	MOVX T2,1B1+1B2		;T2/CHANNEL NUMBERS
	AIC			;ACTIVATE CHANNELS FOR TERM INTS
	MOVE T1,[XWD 1,2]	;CONTROL-A ON CHANNEL 2 FOR STATUS REPORT
	ATI			;ASSIGN ^A TO CHANNEL 2
	SKIPN JOBNO		;IF JOB 0,
	JRST DOJOB0		; DO SPECIAL ROUTINE
	MOVE T1,[XWD 3,1]	;ASSIGN ^C TO CHANNEL 1
	ATI
				;FALL INTO PARSE
	; ..
;HERE TO START A NEW COMMAND.  SET UP THE COMMAND STATE  BLOCK

PARSE:	MOVEI T2,CMDBLK		;POINT TO START OF COMMAND STATE BLOCK
	MOVE T1,[.PRIIN,,.PRIOU] ;JFN'S FOR USER INPUT AND OUTPUT
	MOVEM T1,.CMIOJ(T2)
	HRROI T1,BUFFER		;POINTER TO START OF USER INPUT
	MOVEM T1,.CMBFP(T2)
	MOVEM T1,.CMPTR(T2)	;POINTER TO NEXT FIELD
	MOVEI T1,BUFSIZ*NCHPW	;SPACE REMAINING IN BUFFER
	MOVEM T1,.CMCNT(T2)
	SETZM .CMINC(T2)	;NUMBER OF UNPARSED CHARACTERS
	HRROI T1,ATMBUF		;POINTER TO ATOM BUFFER
	MOVEM T1,.CMABP(T2)
	MOVEI T1,ATMSIZ*NCHPW	;NUMBER CHARACTERS IN ATOM BUFFER
	MOVEM T1,.CMABC(T2)
	MOVEI T1,GTJBLK		;ADDRESS OF GTJFN BLOCK
	MOVEM T1,.CMGJB(T2)


;HERE WHEN ERROR OCCURS AND NEED TO START OVER.  REINIT THE COMND JSYS

PARSE1:	HRROI T1,PROMPT		;POINTER TO PROMPT STRING
	CALL CMDINI		;INIT COMND (SETUP REPARSE)

;HERE WHEN USER RUBOUTS INTO PREVIOUSLY GOTTEN TEXT

PARSE2:	MOVE T1,[CZ%NCL+.FHSLF]
	CLZFF		;RELEASE ALL JFNS
	MOVEI T1,CMDBLK		;T1/ADDRESS OF COMMAND STATE BLOCK
	MOVEI T2,[FLDDB.(.CMKEY,,CMDTAB)] ;T2/ADDRESS OF FDB
	COMND			;LOOK FOR A KEYWORD
	TXNE T1,CM%NOP		;DID WE FIND ONE?
	ERROR PARSE1,<Not a CHECKD command> ;NO. START OVER
	HRRZ T1,(T2)		;YES. GO PROCESS IT
	JRST (T1)	
;SPECIAL JOB 0 ENTRY POINT TO CALL ROUTINES NECESSARY
;ACCORDING TO AUTOMATIC STARTUP

DOJOB0:	MOVE T1,[ASCII "PS"]	;SET DEFAULT STR
	MOVEM T1,STRNAM		; NAME STRING
	SETOM PSFLG		;SAY REALLY DOING PS:
	CALL SETSTR		;SET UP DEVICE DESIGNATOR
	CALL CLRCDE		;CLEAR MONITOR FLAGS
				;BEFORE STARTING
	SETOM WRTLPF		;TURN ON LOST PAGES FILE
	SKIPE REBLDF		;REBUILDING?
	CALL BTBINI		;YES - INIT BITTABLE
	CALL QDONE		;SCAN DIRECTORIES
	MOVX T1,.SFCDE		;SETUP IN CASE OF ERRORS
	MOVEI T2,1
	SKIPN WRTLPF		;WAS THIS TURNED OFF?
	SMON			;YES - SET FLAG THEN
	JRST QUIT		;THROUGH - EXIT

;ROUTINE TO CLEAR SF%CDE AND SF%BTE FLAGS

CLRCDE:	MOVX T1,.SFCDE		;FLAG TO CLEAR
	MOVEI T2,0
	SMON			;CLEAR IT
	MOVX T1,.SFBTE		;OTHER FLAG
	SMON
	RET			;DONE - RETURN
;ROUTINE WHICH RETURNS LAST JSYS ERROR CODE IN AC1.

%GETER:	MOVEI T1,.FHSLF		;OURSELF
	GETER			;GET ERROR CODE
	HRRZ T1,T2
	RET

;ROUTINE TO SETUP MOUNTED STRUCTURE DEVICE DESIGNATOR
;USES MNTBLK TO GET CORRECT STRING

SETMNT:	SKIPN T1,MNTBLK+.MSTAL	;ALIAS IF PRESENT
	MOVE T1,MNTBLK+.MSTNM	;ELSE USE NAME STRING
	STDEV			;GET DEVICE DESIGNATOR
	 JSHLT			;CANT HAPPEND (WE JUST MOUNTED IT)
	MOVEM T2,STRMNT		;SAVE IT
	MOVE T2,MNTBLK+.MSTNM	;SAVE ACTUAL STR NAME
	HRROI T1,STRHOM
	MOVEI T3,0
	SOUT
	TMSG <
[>
	MOVE T1,MNTBLK+.MSTNM	;ACTUAL NAME
	PSOUT
	TMSG <: Mounted>
	SKIPN MNTBLK+.MSTAL	;SEE IF ALIAS
	JRST STMNT1		;NO - CONTINUE
	TMSG < as >
	MOVE T1,MNTBLK+.MSTAL
	PSOUT			;PRINT IT
	MOVEI T1,":"
	PBOUT
	HRROI T1,STRNAM		;COPY TO STRNAM
	MOVE T2,MNTBLK+.MSTAL	; THE ACTUAL STR NAME NOW
	MOVEI T3,0		; IN USE BY THE SYSTEM
	SOUT
STMNT1:	TMSG <]
>
	RET

;ROUTINE TO DISMOUNT ANY STRUCTURE MOUNTED BY CHECKD

DISMNT:	SKIPN T2,STRMNT		;DEVICE DESIGNATOR OF STR MNTED
	RET			;NONE - RETURN
	MOVEM T2,MNTBLK		;SAVE FOR MSTR
	SETZM STRMNT		;SAY NO LONGER MOUNTED
	TMSG <
[Dismounting structure - >
	HRROI T1,STRHOM		;PUBLISH NAME
	PSOUT
	TMSG <:]
>
	MOVE T1,[1,,.MSDIS]	;FUNCTION TO DISMOUNT STR
	MOVEI T2,MNTBLK		;ADDRS OF ARGS
	MSTR			;DO FUNCTION
	 ERCAL [JSERR]
	RET			;RETURN (DONE)
;SETSTR - ROUTINE TO SET UP WORKING STRUCTURE INFO

SETSTR:	SKIPE T2,STRMNT		;MOUNTED A STR?
	JRST STSTR1		;YES - ALREADY HAVE DEVICE DESIG
	HRROI T1,STRHOM		;COPY NAME FOR LATER INFO
	HRROI T2,STRNAM
	MOVEI T3,0
	SOUT			;...
	HRROI T1,STRNAM		;NO - GET STRING TYPED
	STDEV			;CONVERT TO DEVICE DESIGNATOR
	 JRST [	JSERR		;REPORT ERROR
		JRST RESTRT]
STSTR1:	MOVEM T2,STRDEV		;SAVE
	TMSG <
[Working on structure - >
	HRROI T1,STRHOM		;PRINT STR NAME
	PSOUT
	TMSG <:]
>
	SKIPE ZUSED		;CHECK IF HERE YET
	RET			;YES - RETURN
	MOVE T1,STRDEV		;GET DEVICE DESIGNATOR
	GDSKC			;GET DISK SPACE
	MOVEM T1,ZUSED
	RET			;RETURN

;GDNAM - ROUTINE TO WRITE CURRENT DIRECTORY NAME INTO DIRNAM

;RETURNS +1: FAILURE,
;		T1/ERROR CODE
;	  +2: SUCCESS

;WRITES STRUCTURE:<DIRECTORY> IN DIRNAM
;REQUIRES DIRNUM TO HAVE THE 36-BIT DIRECTORY NUMBER

GDNAM:	HRROI T1,DIRNAM		;GET THE NAME OF THIS DIRECTORY
	MOVE T2,DIRNUM		;T2/ DIRECTORY NUMBER
	DIRST			;WRITE ITS NAME
	 RET			;FAILED. RETURN FAILURE
	RETSKP			;SUCCEEDED
;FRSDIR - GET FIRST DIRECTORY ON THE STRUCTURE

;	CALL FRSDIR

;RETURNS +1: FAILURE
;	 +2: SUCCESS

;RETURNS WITH DIRNUM SET UP

FRSDIR:	HRROI T2,[ASCIZ/<*>/]	;ASK FOR ALL DIRECTORIES
	CALL ADDSTR		;ADD STRUCTURE STRING
	MOVX T1,RC%AWL!RC%EMO	;T1/ ALLOW WILD CARD, NO RECOGNITION
	RCDIR			;GET FIRST DIRECTORY NUMBER
	 ERJMP [ PNTERR(<Unable to reference directory files>)
		JSERR
		RET]
	TXNE T1,RC%AMB!RC%NOM!RC%NMD ;ANY ERRORS?
	JRST [	PNTERR(<Unable to reference directory files>)
		RET]
	MOVEM T3,DIRNUM		;NO. SAVE DIRECTORY NUMBER
	RETSKP

;NXTDIR - GET NEXT DIRECTORY

;	CALL NXTDIR

;RETURNS +1: FAILURE OR DONE
;	 +2: SUCCESS

;RETURNS WITH DIRNUM SET UP

NXTDIR:	MOVX T1,RC%EMO!RC%AWL!RC%STP ;T1/ NO RECOGNITION, ALLOW WILD CARDS, STEP
	HRROI T2,ATMBUF		;POINT TO STR:<*>
	MOVE T3,DIRNUM		;T3/ DIRECTORY WE GOT BEFORE
	RCDIR			;GET THE NEXT DIRECTORY
	 ERJMP [ PNTERR(<Failed to get next directory>)
		SETZM DIRNUM
		RET]
	TXNE T1,RC%NOM!RC%AMB	;DID WE GET A STRANGE ERROR?
	JRST [	PNTERR(<Failed to get next directory>)
		SETZM DIRNUM
		RET]
	TXNE T1,RC%NMD		;NO MORE DIRECTORIES?
	JRST  [	SETZM DIRNUM
		RET]
	MOVEM T3,DIRNUM		;NO. SAVE DIRECTORY NUMBER
	RETSKP
;CKDIR - ROUTINE TO DO DIRECTORY CONSISTENCY CHECK AND REBUILD
;IF THERE ARE ANY ERRORS
; DIRECTORY NUMBER IS IN "DIRNUM"

CKDIR:	MOVE T2,DIRNUM		;GET DIRECTORY NUMBER
	MOVX T1,DD%CHK		;CHECK ONLY
	DELDF
	 ERJMP CKDIR1		;ERROR - INFORM WORLD
	RET			;OK - RETURN

CKDIR1:	TMSG <% Rebuilding symbol table for >
	HRROI T1,DIRNAM		;PRINT NAME
	PSOUT
	MOVE T2,DIRNUM		;GET NUMBER AGAIN
	MOVX T1,DD%RST		;REBUILD FCN
	DELDF			;TRY IT
	 ERJMP CKDIR2		;CAN'T REBUILD
	TMSG < [OK]
>
	RET			;SAY OK AND RETURN

CKDIR2:	TMSG < [FAILED]
>
	RET			;RETURN

;ROUTINE TO GET CONNECTED STRUCTURE STRING INTO STRNAM

GETCON:	GJINF			;GET CONNECTED STR ID
	HLRZS T2		;STRUCTURE UNIQUE CODE
	HRLI T2,.DVDES		;MAKE INTO DEVICE DESIGNATOR
	HRROI T1,STRNAM
	DEVST			;CONVERT TO STRING
	 JRST GETCN1		;NOT CONNECTED - FIX
	RET			;RETURN

GETCN1:	SETO T1,		;SAY THIS JOB
	HRROI T2,T4		;ONE WORD INTO T4
	MOVX T3,.JILNO		;LOGGED IN DIR #
	GETJI
	 JSHLT
	MOVEM T4,FCNBLK		;SAVE IT
	SETZM FCNBLK+1		;NO PASSWORD
	SETOM FCNBLK+2		;THIS JOB
	MOVE T1,[AC%CON+3]
	MOVEI T2,FCNBLK		;ADDRS OF ARGS
	ACCES			;CONNECT TO LOGGED IN DIR
	 ERJMP [JSHLT]
	JRST GETCON		;LOOP BACK AND TRY AGAIN
;ROUTINE TO DO CONFIRMATION AND GET STRUCTURE NAME STRING

FCNFRM:	HRROI T1,[ASCIZ /FOR/]
	CALL CMDNOI		;XTRA GUIDE WORD
CONFRM:	CALL GETCON		;GET CONNECTED STRUCTURE
	HRROI T1,STRNAM		;POINT TO DEFAULT
	CALL CMDSTR		;GET STRUCTURE STRING
	HRROI T1,STRNAM		;PLACE TO STORE STRUCTURE NAME
	HRROI T2,ATMBUF		;COPY STRING TYPED BY USER
	MOVEI T3,0
	SOUT			;SLOW
	CALL CMDEOL		;PARSE TO EOL
	 JRST PARSE1		;ERROR
	RET

;ROUTINE TO PARSE STRUCTURE NAME STRING (DEFALUT IN T1)

CMDSTR:	MOVEM T1,FCNBLK+.CMDEF	;SAVE DEFAULT
	MOVX T2,<FLD(.CMFLD,CM%FNC)+<CM%SDH!CM%HPP!CM%DPP>>
	MOVEM T2,FCNBLK		;SETUP FUNCTION
	HRROI T1,[ASCIZ "STRUCTURE NAME"]
	MOVEM T1,FCNBLK+.CMHLP	;SETUP HELP TEXT
	SETZM FCNBLK+.CMDAT	;NO XTRA DATA
	MOVEI T1,CMDBLK		;STATE BLOCK
	MOVEI T2,FCNBLK		;FUNCTION BLOCK
	COMND
	TXNE T1,CM%NOP
	ERROR PARSE1,<Invalid structure name>
	SKIPN CMDBLK+.CMINC	;ANY REMAINING CHARS
	RET			;NO - RETURN
	MOVE T3,CMDBLK+.CMPTR	;YES - GET POINTER
	ILDB T2,T3		;GET NEXT CHARACTER
	CAIE T2,":"		;SEE IF A COLON?
	RET			;NO - OK RETURN
	MOVEM T3,CMDBLK+.CMPTR	;SKIP OVER CHARACTER
	SOS CMDBLK+.CMINC
	RET			; AND RETURN
;GENERAL COMND UTILITIES

;INIT COMND AND SETUP REPARSE TO BE THE RETURN ADDRS
;OF THE CALLER. C(T1) := POINTER TO PROMPT STRING

CMDINI:	MOVEM T1,CMDBLK+.CMRTY	;SETUP PROMPT
	POP P,SAVRET		; AND RETURN ADDRS
	MOVEM P,SAVREP		;SAVE PDL FOR REPARSE
	MOVEI T1,REPARS		;SETUP REPARSE ADDRS
	MOVEM T1,CMDBLK+.CMFLG
	MOVEI T1,CMDBLK		;POINT TO STATE BLOCK
	MOVEI T2,[FLDDB.(.CMINI)] ;INIT FCN
	COMND
	JRST @SAVRET		;RETURN

REPARS:	MOVE P,SAVREP		;RESET PDL
	JRST @SAVRET		; RETURN TO CALLER OF CMDINI

;NOISE PARSE ROUTINE
; C(T1) := GUIDE WORD STRING

CMDNOI:	MOVEM T1,FCNBLK+.CMDAT	;SAVE TEXT STRING
	MOVX T1,<FLD(.CMNOI,CM%FNC)>
	MOVEM T1,FCNBLK		;SET UP FUNCTION
	MOVEI T1,CMDBLK		;COMMAND STATE BLOCK
	MOVEI T2,FCNBLK		;FUNCTION
	COMND
	TXNE T1,CM%NOP		;OK?
	ERROR PARSE1,<Unrecognized guide word>
	RET			;RETURN

;CHECK FOR EOL (RETURN +1 IF NONE)

CMDEOL:	MOVEI T1,CMDBLK		;SET UP STATE BLOCK
	MOVEI T2,[FLDDB.(.CMCFM)]
	COMND			;CHECK CONFIRMATION
	TXNN T1,CM%NOP		;VALID?
	RETSKP			;YES - SKIP RETURN
	TMSG <
?Invalid confirmation.
>
	RET			;ERROR RETURN
;ROUTINE TO WRITE A HEADER FOR THE LOST-PAGES FILE

LPFWRT:	SETZM LPFHED+.LPSTR	;CLEAR STR NAME
	SETZM LPFHED+.LPSTR+1
	MOVE T1,[.LPMJK]		;MAJIK CONSTANT
	MOVEM T1,LPFHED+.LPFLG
	GTAD			;GET CURRENT DATE & TIME
	MOVEM T1,LPFHED+.LPTAD
	HRROI T1,LPFHED+.LPSTR	;POINT TO STR NAME
	HRROI T2,STRHOM		;POINT TO NAME STRING
	MOVEI T3,0		;OUTPUT TILL NULL
	SOUT
	MOVE T1,LOSTOT		;LOST PAGES COUNT
	MOVEM T1,LPFHED+.LPCNT
	MOVE T1,OUTJFN
	MOVE T2,[POINT 36,LPFHED]
	MOVNI T3,.LPDTA		;HEADER SIZE
	SOUT
	RET			;DUMP AND RETURN

;ROUTINE TO CHECK LOST-PAGE FILE HEADER

LPFCHK:	SETZM DIRNAM		;CLEAR STR NAME AREA
	SETZM DIRNAM+1
	MOVE T1,INJFN		;INPUT JFN
	MOVE T2,[POINT 36,LPFHED]
	MOVNI T3,.LPDTA		;SIZE OF RECORD
	SIN			;READ IT
	 ERJMP [JSHLT]
	MOVE T1,LPFHED+.LPFLG	;GET FLAG WORD
	CAME T1,[.LPMJK]		;CHECK CONSTANT
	JRST [	TMSG <?File not in correct format>
		JRST LPFCHE]
	HRROI T1,STRHOM		;CHECK MATCH OF STR
	HRROI T2,LPFHED+.LPSTR
	STCMP
	JUMPN T1,[TMSG <?File is for structure >
		 HRROI T1,LPFHED+.LPSTR
		 PSOUT
		 JRST LPFCHV]
LPFCH1:	TMSG <File written on: >
	MOVEI T1,.PRIOU
	MOVE T2,LPFHED+.LPTAD	;FILE DATE AND TIME
	MOVEI T3,0		;USE DEFAULT
	ODTIM
	TMSG < , contains >
	MOVEI T1,.PRIOU
	MOVE T2,LPFHED+.LPCNT
	MOVEI T3,^D10		;DECIMAL NUMBER
	NOUT
	 JFCL
	TMSG < entries.
>
	RETSKP			;GOOD RETURN

LPFCHE:	TMSG < , Aborting...
>
	RET			;ERROR RETURN

LPFCHV:	TMSG <
>
	HRROI T1,[ASCIZ "Do you want to proceed anyway? "]
	CALL YESNO		;GET CONFIRMATION
	JUMPL T1,LPFCH1		;YES - USE THIS FILE
	RET			;NO - TERMINATE
;ROUTINE TO ADD STRUCTURE NAME TO BEGINNING OF STRING

;ACCEPTS:
;	T2/ POINTER TO EXISTING STRING

;	CALL ADDSTR

;RETURNS +1: ALWAYS,
;		T2/ POINTER TO STRING WITH STRUCTURE IN FRONT

ADDSTR:	STKVAR <GJSTR>
	MOVEM T2,GJSTR		;SAVE POINTER TO STRING
	HRROI T1,ATMBUF		;BUILD FILESPEC HERE
	HRROI T2,STRNAM		;STRUCTURE NAME STRING
	MOVEI T3,0
	SOUT			;COPY STRUCTURE NAME
	MOVEI T2,":"		;APPEND COLON TO DEVICE NAME
	IDPB T2,T1
	MOVE T2,GJSTR
	SOUT			;COPY REMAINDER OF NAME
	HRROI T2,ATMBUF		;COMPLETE NAME
	RET			;RETURN WITH CORRECT POINTER

;ROUTINE TO CHECK FOR PS:

PSCHK:	SETZM PSFLG		;NOT PS: YET
	HRROI T1,STRNAM		;NAME OF STRUCTURE
	HRROI T2,[ASCIZ "PS"]
	STCMP			;COMPARE STRINGS
	JUMPN T1,R		;NOT PS - NON SKIP
	SETZM OKFLG		;FLAG FOR FNDSTR
	CALL FNDSTR		;SEE IF THERE IS A DISMOUNTED
	 SETO T1,		;CANT HAPPEN (ASSUME PS)
	JUMPE T1,R		;NEED TO MOUNT THIS PS
	SETOM PSFLG		;THIS IS THE REAL PS:
	RETSKP			;SKIP RETURN
;ROUTINE TO SCAN ALL DISK DRIVES LOOKING FOR STRUCTURE
;NAMED IN STRNAM AND CHECKING TO SEE IF IT IS DISMOUNTED
; RETURNS +1 IF ERROR
; RETURNS +2 C(T1) := -1 IF STR ALREADY MOUNTED
;	     C(T2) := 0 IF NEED TO MOUNT STR (MNTBLK SETUP)

FNDSTR:	STKVAR <NUNITS,DEVSAV>
FNDST0:	SETOM RNUBLK+.MSRCH	;INIT FOR FIRST UNIT
	SETOM RNUBLK+.MSRCT
	SETOM RNUBLK+.MSRUN
	SETOM MNTBLK+.MSTNU	;INIT # OF UNITS IN STR
	SETZM NUNITS		;INIT NUMBER OF UNITS FOUND

FNDST1:	CALL GTUSTS		;GET UNIT STATUS
	 JRST FNDST3		;NO MORE UNITS
	CALL STRMAT		;MATCH STRUCTURE WANTED
	 JRST FNDST1		;NO - TRY NEXT
	SKIPL MNTBLK+.MSTNU	;FIRST TIME HERE
	JRST FNDST2		;NO - JUST SETUP UNIT
	HRRZ T1,RNUBLK+.MSRNS	;YES - GET # OF UNITS IN STR
	CAILE T1,10		;MAX NUMBER WE CAN HANDLE
	RETERR <More than 8. units in structure>
	MOVEM T1,MNTBLK+.MSTNU
	SETOM MNTBLK+.MSTUI	;INIT MOUNT TABLE TO -1
	MOVE T1,[MNTBLK+.MSTUI,,MNTBLK+.MSTUI+1]
	BLT T1,MNTBLK+.MSTUI+.MSTNO*10-1
				;CLEAR TABLE
FNDST2:	HRRZ T1,RNUBLK+.MSRNS	;GET # OF UNITS
	CAME T1,MNTBLK+.MSTNU	;SAME AS BEFORE?
	RETERR <Ambiguous number of units found>
	HLRZ T1,RNUBLK+.MSRNS	;GET LOGICAL UNIT NUMBER
	IMULI T1,.MSTNO		;CALC OFFSET INTO TABLE
	ADDI T1,MNTBLK+.MSTUI
	SKIPL .MSTCH(T1)	;UNIT PREVIOUSLY NOT FOUND?
	RETERR <Multiple logical units found>
	HRLI T1,RNUBLK+.MSRCH	;SET UP XFER WORD
	MOVEI T2,.MSTUN(T1)
	BLT T1,0(T2)		;XFER DISK ADDRESS
	AOS NUNITS		;INCR NUMBER OF PACKS SO FAR
	JRST FNDST1		;GET MORE
;HERE WHEN NO MORE UNITS FOUND

FNDST3:	SKIPE T1,NUNITS		;FOUND ANYTHING?
	JRST FNDST8		;YES - GO ON
	HRROI T1,STRNAM		;SEE IF ALREADY ON-LINE
	STDEV
	 RETERR <Structure not found>
	MOVEM T2,DEVSAV		;SAVE DEVICE DESIG FOR DISMOUNT
	SKIPN OKFLG		;WANT TO WARN USER
	JRST [	SETO T1,	;DON'T MOUNT ANYTHING
		RETSKP]		;GOOD RETURN
	HRROI T1,[ASCIZ "% Structure already mounted. Forcibly dismount and proceed? "]
	CALL YESNO
	JUMPE T1,R		;DON'T PROCEDE
	HRROI T1,STRHOM		;COPY NAME TO HERE
	HRROI T2,STRNAM		; FOR DISMOUNT MSG
	MOVEI T3,0
	SOUT
	MOVE T1,DEVSAV		;SETUP DEVICE DESIGNATOR
	MOVEM T1,STRMNT
	MOVEM T1,MNTBLK		;SETUP FOR GET STR STATUS
	HRROI T1,STRNAM		;PUT STRUCTURE-ID HERE
	MOVEM T1,MNTBLK+.MSGSI
	MOVE T1,[.MSGLN,,.MSGSS]
	MOVEI T2,MNTBLK		;FUNCTION BLOCK
	MSTR			;GET STR ID
	 ERJMP [JSHLT]		;LOSE IF ERROR
	CALL DISMNT		;DISMOUNT STR
	JRST FNDST0		;AND START OVER

FNDST8:	CAME T1,MNTBLK+.MSTNU	;FOUND CORRECT NUMBER
	RETERR <Structure missing one or more units>
	HRROI T1,STRNAM		;SET NAME INTO BLOCK
	MOVEM T1,MNTBLK+.MSTNM
	SETZM MNTBLK+.MSTAL	;NO ALIAS
	SETZ T1,		;SAY NEED TO MOUNT
	RETSKP			;GIVE GOOD RETURN
;ROUTINE TO READ-NEXT-UNIT STATUS

GTUSTS:	HRROI T1,NAMBUF		;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 WHICH SKIPS IFF CURRENT UNIT IS PART OF STRUCTURE WE
;WANT.

STRMAT:	MOVE T1,RNUBLK+.MSRST	;GET UNIT STATUS
	TXNE T1,MS%HBB		;VALID HOME BLOCKS?
	JRST STMAT1		;GIVE WARNING
	TXNE T1,MS%MNT!MS%OFL!MS%DIA
	RET			;MOUNTED, OFF-LINE, OR DIAG
	HRROI T1,NAMBUF		;CONSIDER THIS NAME
	HRROI T2,STRNAM		;REQUESTED STRUCTURE
	STCMP			;MATCH STRINGS
	JUMPN T1,R		;RETURN IF NO MATCH
	RETSKP			;SKIP IF MATCH

STMAT1:	TMSG <% Unit >
	MOVE T2,RNUBLK+.MSRUN
	MOVE T3,[1,,10]
	CALL TTNOUT		;PRINT UNIT #
	TMSG < on channel >
	MOVE T2,RNUBLK+.MSRCH
	CALL TTNOUT		;AND CHANNEL
	TMSG < does not have valid home blocks - ignored.
>
	RET			;RETURN ERROR
;ROUTINE TO INITIALIZE A STURCTURE FROM INFORMATION GIVEN
;BY THE USER. C(T1) := FLAGS,,FCN

STRINI:	HLLM T1,MNTBLK+.MSINU	;STORE FLAGS AND FUNCTION
	HRRZ T2,MNTBLK+.MSINU	;GET NUMBER OF UNITS
	SOS T2			; -1
	IMULI T2,.MSINO		;WORDS / UNIT
	SETZM MNTBLK+.MSIST(T2)	;CLEAR STATUS WORD
	HRROI T1,STRNAM		;SET UP NAME STRING
	MOVEM T1,MNTBLK+.MSINM
	MOVE T1,NPG4SW		;# PAGES FOR SWAPPING
	MOVEM T1,MNTBLK+.MSISW(T2)
	MOVE T1,NPGFES		;# PAGES FOR FRONT-END
	MOVEM T1,MNTBLK+.MSIFE(T2)
	MOVEI T1,MNTBLK+.MSIUI(T2)
	HRLI T1,UNITID		;UNIT ID STRING
	BLT T1,MNTBLK+.MSIUI+2(T2) ;MOVE STRING (12 CHARS)
	MOVEI T1,MNTBLK+.MSIOI(T2)
	HRLI T1,OWNRID		;OWNER ID STRING
	BLT T1,MNTBLK+.MSIOI+2(T2) ;MOVE IT
	HRLZI T1,.MSIOI+3(T2)	;SIZE OF ARG LIST
	HRRI T1,.MSINI		; SIZE ,, FUNCTION
	MOVEI T2,MNTBLK		;POINT TO ARG BLOCK
	MSTR			;TRY TO MOUNT , ETC.
	 ERJMP [JSERR		;REPORT FAILURE
		RET]
	CALL SETMNT		;SET MOUNTED STR
	RETSKP			;GOOD RETURN

;INIT STRUCTURE PARAMETERS (SET DEFAULTS)

STRDEF:	SETZM NPG4SW		;ASSUME NO SWAPPING
	SETZM NPGFES		;AND NO FRONT-END FILE SYSTEM
	SETZM IDZB		;CLEAR ID FIELDS
	MOVE T1,[IDZB,,IDZB+1]
	BLT T1,IDZZ		;...
	RET			;RETURN
;ROUTINE TO MOUNT STRUCTURE FOR EXCLUSIVE USE

XMNTA:	TDZA T1,T1		;OK IF MOUNTED ENTRY
XMNT:	SETO T1,		;MUST FIND OFF-LINE
	MOVEM T1,OKFLG		;SAVE FLAG FOR FNDSTR
	CALL FNDSTR		;FIND STUCTURE
	 JRST RESTRT		; PROBLEM - START OVER
	JUMPL T1,R		;RETURN IF ALREADY MOUNTED
	HRROI T1,[ASCIZ /CHECKD/]
	MOVEM T1,MNTBLK+.MSTAL	;SETUP ALIAS FOR CHECKD
	MOVX T1,MS%XCL!MS%IGN	;EXCLUSIVE USE, IGNORE ERRORS
	HLLM T1,MNTBLK+.MSTNU	;SET FLAGS
	HRRZ T1,MNTBLK+.MSTNU	;CALC SIZE OF BLOCK
	IMULI T1,.MSTNO
	ADDI T1,.MSTUI		; PLUS CONSTANT SIZE
	HRLZS T1		;MOVE TO LHS
	HRRI T1,.MSMNT		;MOUNT FUNCTION
	MOVEI T2,MNTBLK		;POINT TO ARG BLOCK
	MSTR
	 ERJMP [JSERR		;REPORT LOSAGE
		JRST RESTRT]	;START OVER
	CALL SETMNT		;SET STRUCTURE MOUNTED
	RET			;RETURN
;CREATE NEW FILE SYSTEM

;ACCEPT FILE STRUCTURE DESCRIPTION AND BUILD A NEW STRUCTURE
;ON THE SPECIFIED UNITS. (.MSINI FUNCTION)

.CREAT:	HRROI T1,[ASCIZ /NEW FILE SYSTEM FOR/]
	CALL CMDNOI		;PRINT GUIDE WORDS
	CALL CONFRM		;GET STR NAME AND CONFIRM
	CALL STRDEF		;SET DEFAULTS
	HRROI T1,[ASCIZ /Enter alias: /]
	CALL CMDINI		;INIT AND PROMPT
	HRROI T1,[ASCIZ /CHECKD/]
	CALL CMDSTR		;PARSE STRUCTURE NAME
	HRROI T1,DIRNAM		;PLACE TO STORE ALIAS
	HRROI T2,ATMBUF		;WHAT HE TYPED
	MOVEI T3,0
	SOUT
	CALL CMDEOL		;PARSE TO EOL
	 JRST PARSE1		; ERROR

CREAT1:	HRROI T1,[ASCIZ /How many units in this structure? /]
	CALL CMDINI		;PRINT PROMPT
	MOVEI T1,CMDBLK
	MOVEI T2,[FLDDB.(.CMNUM,,^D10)]
	COMND			;GET DECIMAL NUMBER
	TXNE T1,CM%NOP		;VALID NUMBER?
	ERROR CREAT1,<Invalid decimal number>
	CAIG T2,8		;AND IN RANGE
	CAIGE T2,1
	ERROR CREAT1,<Number not in range 1-8>
	MOVEM T2,MNTBLK+.MSINU	;SAVE NUMBER OF UNITS
	CALL CMDEOL		;GET <CR>
	 JRST CREAT1		;TRY AGAIN

	CALL CNFINF		;GET CONFIG INFO
	MOVEI Q1,MNTBLK+.MSISU	;BEGINNING OF UNIT INFO
	HRRZ Q2,MNTBLK+.MSINU	;COUNT OF UNITS
CREAT2:	CALL GETUNI		;GET UNIT INFO
	ADDI Q1,.MSINO		;STEP TO NEXT
	SOJG Q2,CREAT2		;LOOP TILL DONE
	SETO T1,		;UNMAP HELP BUFFER
	MOVE T2,[.FHSLF,,<HBUF>B44]
	MOVX T3,PM%CNT+4
	PMAP
	;..
	;..
CREAT3:	HRROI T1,[ASCIZ /Number of pages to allocate for swapping? /]
	CALL CMDINI		;PRINT PROMPT
	MOVEI T1,CMDBLK
	MOVEI T2,[FLDDB.(.CMNUM,CM%SDH,^D10,<0 for no swapping space or
   a decimal number between 2000 and 40000>,3050)]
	COMND
	TXNN T1,CM%NOP		;VALID NUMBER
	SKIPGE T2		; AND IN RANGE
	ERROR CREAT3,<Invalid decimal number>
	JUMPE T2,CRT3A		;ZERO IS OK
	CAIG T2,^D40000		;VALIDATE RANGE
	CAIGE T2,^D2000
	ERROR CREAT3,<Swapping space value not in range 2000. to 40000.>
CRT3A:	MOVEM T2,NPG4SW		;SAVE FOR LATER
	CALL CMDEOL
	 JRST CREAT3

CREAT4:	HRROI T1,[ASCIZ /Number of pages to allocate for the Front End File System? /]
	CALL CMDINI		;PRINT PROMPT
	MOVEI T1,CMDBLK		;SETUP STATE BLOCK
	MOVEI T2,[FLDDB.(.CMNUM,CM%SDH,^D10,<0 for no front end file system or
   a decimal number between 250 and 10000>,950)]
	COMND
	TXNN T1,CM%NOP		;CHECK VALID ANSWER
	SKIPGE T2
	ERROR CREAT4,<Invalid decimal number>
	JUMPE T2,CRT4A		;ZERO IS OK
	CAIG T2,^D10000		;CHECK RANGE
	CAIGE T2,^D250
	ERROR CREAT4,<Value not in range 250. to 10000.>
CRT4A:	MOVEM T2,NPGFES		;SAVE NUMBER
	CALL CMDEOL
	 JRST CREAT4		;TRY AGAIN

	GJINF			;GET USER NAME
	MOVE T2,T1
	HRROI T1,NAMBUF
	MOVEM T1,FCNBLK+.CMDEF	;SET UP DEFAULT POINTER
	DIRST			; INTO NAMBUF
	 JSHLT
	MOVX T1,<FLD(.CMFLD,CM%FNC)+<CM%SDH!CM%HPP!CM%DPP>>
	MOVEM T1,FCNBLK		;SETUP FCN
	SETZM FCNBLK+.CMDAT	;NO XTRA DATA
	HRROI T1,[ASCIZ "NAME OF USER OWNING STRUCTURE"]
	MOVEM T1,FCNBLK+.CMHLP	;SETUP HELP TEXT
CREAT5:	HRROI T1,[ASCIZ "Owner name? "]
	CALL CMDINI		;PROMPT
	MOVEI T1,CMDBLK
	MOVEI T2,FCNBLK		;SETUP SPECIAL FUCNTION BLOCK
	COMND			;GET RESPONSE
	TXNE T1,CM%NOP		;VALID ANSWER
	ERROR CREAT5,<Invalid owner name string>
	HRROI T2,ATMBUF		;RESPONSE
	HRROI T1,OWNRID		;COPY TO OWNER ID
	MOVEI T3,^D13		;MAX CHARS
	MOVEI T4,0		;OR NULL (WHICHEVER COMES FIRST)
	SOUT
	SKIPN T3
	ERROR CREAT5,<Name string greater than 12. characters>
	CALL CMDEOL		;GRNTEE EOL
	 JRST CREAT5
;NOW TRY TO INIT/MOUNT THE STRUCTURE

	HRROI T1,UNITID		;SETUP UNIT ID STRING
	HRROI T2,STRNAM		;TO BE STRUCTURE NAME
	MOVEI T3,0
	SOUT			;...
	HRROI T1,DIRNAM		;ALIAS TEXT STRING
	MOVEM T1,MNTBLK+.MSIAL	;SET UP ALIAS
	MOVX T1,<FLD(.MSCRE,MS%FCN)+MS%XCL>
	CALL STRINI		;INIT STRUCTURE
	 JRST PARSE1		;FAILED
	JRST RESTRT		;OK - GET NEXT COMMAND
;ROUTINE TO GET CHANNEL AND UNIT NUMBER FOR A DRIVE
; C(Q1) := POINTER TO 3-WORD DRIVE INFO BLOCK

GETUNI:	HRROI T2,[ASCIZ /Channel , Drive for logical unit /]
	HRROI T1,TMPBUF		;TEMP BUFFER
	MOVEI T3,0
	SOUT
	HRRZ T2,MNTBLK+.MSINU	;CALC UNIT #
	SUB T2,Q2
	MOVEI T3,8		;OCTAL
	NOUT
	 JFCL
	HRROI T2,[ASCIZ /: /]
	MOVEI T3,0
	SOUT
GETUN1:	HRROI T1,TMPBUF		;POINT TO GENERATED PROMPT
	CALL CMDINI		;PRINT PROMPT
	CALL SPCNUM		;SPECIAL NUMBER ROUTINE
	 JRST GETUN1		;ERROR RETURN
	CAIG T2,7		;CHECK RANGE
	CAIGE T2,0
	ERROR GETUN1,<Channel number not in range 0-7>
	MOVEM T2,.MSICH(Q1)	;STORE IN PROPER PLACE

	MOVEI T1,CMDBLK
	MOVEI T2,[FLDDB.(.CMCMA)]
	COMND
	TXNE T1,CM%NOP
	ERROR GETUN1,<Comma expected between channel and drive numbers>

	CALL SPCNUM		;GET DRIVE NUMBER
	 JRST GETUN1		;INVALID NUMBER
	CAIG T2,7
	CAIGE T2,0
	ERROR GETUN1,<Drive number not in range 0-7>
	MOVEM T2,.MSIUN(Q1)	;STORE IT

	SETOM .MSICT(Q1)	;CONTROLLER # TO -1
	CALL CMDEOL		;GRNTEE EOL
	 JRST GETUN1		;ERROR
	RET			;OK - RETURN
;SPECIAL NUMBER ROUTINE WITH VERY LONG HELP TEXT

SPCNUM:	MOVX T1,<FLD(.CMNUM,CM%FNC)+CM%HPP!CM%SDH>
	MOVEM T1,FCNBLK		;SETUP FUNCTION
	HRROI T1,HBUF		;POINT TO HELP TEXT
	MOVEM T1,FCNBLK+.CMHLP
	MOVEI T1,8		;SETUP RADIX
	MOVEM T1,FCNBLK+.CMDAT
	SETZM FCNBLK+.CMDEF	;NO DEFAULT
	MOVEI T1,CMDBLK		;T1/ STATE BLOCK
	MOVEI T2,FCNBLK		;T2/ FUNCTION BLOCK
	COMND
	TXNN T1,CM%NOP
	RETSKP			;GOOD RETURN
	TMSG <
?Invalid octal number
>
	RET			;ERROR RETURN

;ROUTINE TO SETUP STRING CONTAINING AVAILABLE UNIT INFO

CNFINF:	SAVEQ			;SAVE Q1-Q3
	HRROI Q1,HBUF		;POINT TO BUFFER BEG
	MOVE T1,Q1		;GET FIRST STRING
	HRROI T2,HHDR		;POINT TO HEADER
	MOVEI T3,0
	SOUT
	MOVEM T1,Q1		;SAVE PNTR SO FAR

	SETOM RNUBLK+.MSRCH	;INIT FOR FIRST UNIT
	SETOM RNUBLK+.MSRCT
	SETOM RNUBLK+.MSRUN
CNFIN1:	CALL GTUSTS		;GET UNIT STATUS
	 JRST CNFIN3		;NO MORE - DONE
	MOVE Q2,RNUBLK+.MSRST	;GET STATUS
	TXNE Q2,MS%MNT		;MOUNTED STR?
	JRST CNFIN1		;YES IGNORE
	LDB T3,[POINTR (Q2,MS%TYP)]
	HRROI T2,[ASCIZ "UNK "]
	MOVE T1,Q1		;GET OUTPUT PNTR
	CAIG T3,MXUTYP		;VALID TYPE?
	MOVE T2,UNTYTB(T3)	;GET NAME OF UNIT TYPE
	MOVEI T3,0
	SOUT			;DUMP IT
	;..
	;..
	MOVEI T3,8		;SPACE OVER
	CALL SPACN
	MOVE T2,RNUBLK+.MSRCH	;GET CHANNEL NUMBER
	MOVEI T3,8
	NOUT			;CONVERT TO NUMBER
	 JFCL
	MOVEI T3,6		;SPACES
	CALL SPACN
	MOVE T2,RNUBLK+.MSRUN	;GET UNIT NUMBER
	MOVEI T3,8
	NOUT
	 JFCL
	MOVEI T3,2
	CALL SPACN		;MOVE OVER
	HRROI T2,NAMBUF		;ASSUME STR NAME
	TXNE Q2,MS%HBB		;VALID HOME BLOCKS?
	HRROI T2,[ASCIZ "Bad home blocks"]
	TXNE Q2,MS%DIA		;MAINT MODE?
	HRROI T2,[ASCIZ "Maintenance mode"]
	TXNE Q2,MS%OFL		;OFF-LINE
	HRROI T2,[ASCIZ "Off-line"]
	MOVEI T3,^D20		;MAX CHARS
	MOVEI T4,0		;TERMINATOR
	SOUT			;DUMP STRING SO FAR
	MOVNI T2,1		;BACKUP OVER NULL
	ADJBP T2,T1
	MOVE T1,T2		;RESTORE BP
	AOS T3			;ACCOUNT FOR IT
	CALL SPACN		;T3 HAS CHARS REMAINING
	TXNE Q2,MS%DIA!MS%OFL!MS%HBB
	JRST CNFIN2		;NO MORE INFO
	HLRZ T2,RNUBLK+.MSRNS	;GET LOGICAL UNIT #
	MOVEI T3,12		;DECIMAL
	NOUT
	 JFCL
	MOVEI T2," "
	IDPB T2,T1		;PUT IN SPACE
	MOVEI T2,"("
	IDPB T2,T1		;AND PAREN
	HLRZ T2,RNUBLK+.MSRNS	;GET UNIT # AGAIN
	AOS T2			;CHANGE TO ORDINAL
	NOUT			;DUMP IT
	 JFCL
	HRROI T2,[ASCIZ " of "]
	MOVEI T3,0
	SOUT
	HRRZ T2,RNUBLK+.MSRNS	;GET # OF UNITS IN STR
	MOVEI T3,^D10
	NOUT			;DUMP IT
	 JFCL
	MOVEI T2,")"		;CLOSE PAREN
	IDPB T2,T1
CNFIN2:	MOVEI T2,15		;CR
	IDPB T2,T1		;OUTPUT
	MOVEI T2,12		;LF
	IDPB T2,T1
	MOVEM T1,Q1		;SAVE PNTR
	JRST CNFIN1		;GET NEXT
CNFIN3:	MOVEI T2,15		;XTRA CRLF
	IDPB T2,Q1
	MOVEI T2,12
	IDPB T2,Q1		;...
	MOVEI T2,0		;TIE OFF STRING
	IDPB T2,Q1
	RET			;RETURN

;UNIT INFO TABLES

UNTYTB:	-1,,[ASCIZ "UNK "]	;0 - UNKNOWN
	-1,,[ASCIZ "RP04"]	;1 - RP04
	-1,,[ASCIZ "UNK "]	;2 - UNKNOWN
	-1,,[ASCIZ "UNK "]	;3 - UNKNOWN
	-1,,[ASCIZ "UNK "]	;4 - UNKNOWN
	-1,,[ASCIZ "RP05"]	;5 - RP05
	-1,,[ASCIZ "RP06"]	;6 - RP06
	-1,,[ASCIZ "UNK "]	;7
	-1,,[ASCIZ "UNK "]	;10
	-1,,[ASCIZ "RM03"]	;11 - RM03

MXUTYP==.-UNTYTB		;MAX UNIT TYPE

;HELP MESSAGE HEADER

HHDR:	ASCIZ "

Pair of octal numbers from one of the following:

Type  Channel  Drive  Structure name      Logical unit
----  -------  -----  --------------      ------------

"

;ROUTINE TO OUTPUT # SPACES IN T3

SPACN:	MOVEI T2,40		;SPACE
	IDPB T2,T1
	SOJG T3,.-1
	RET
;COMMON ROUTINE FOR CHECK COMMAND

.CHECK:	MOVEI T1,CMDBLK		;COMMAND STATE BLOCK
	MOVEI T2,[FLDDB.(.CMKEY,,CKTAB)]	;SECONDARY KEYTABLE
	COMND
	TXNE T1,CM%NOP
	ERROR PARSE1,<Not a CHECKD command>
	HRRZ T1,(T2)		;GET DISPATCH
	JRST (T1)		;PROCESS

;CHECK COMMAND KEYWORD TABLE

CKTAB:	2,,2			;SIZE OF TABLE
	TB (.BITAB,BITTABLE)	;CHECK BITTABLE CONSISTENCY
	TB (.DIREC,DIRECTORY)	;CHECK DIRECTORY CONSISTENCY
;CHECK (CONSISTENCY OF) BITTABLE

;USER WANTS TO CHECK BIT TABLE.
;  THIS IS THE STANDARD OPTION WHEN RUNNING FROM JOB 0.
;GET CONFIRMATION.  USE DEFAULT FLAG SETTINGS.

.BITAB:	HRROI T1,[ASCIZ /CONSISTENCY OF/]
	CALL CMDNOI		;NOISE WORDS
	CALL CONFRM		;GET STR AND CONFIRM
	CALL PSCHK		;SEE IF THIS IS PS:
	 CALL XMNT		;NO - MOUNT FOR EXCLUSIVE ACCESS
	CALL SETSTR		;SET CURRENT STR ETC.
	SETOM WRTLPF		;TURN ON LOST-PAGES FILE
	CALL QDONE		;SCAN DIRECTORIES
	SKIPN PSFLG		;WAS THIS THE REAL PS:
	 JRST RESTRT		;NO - RESTART CHECKD
	SKIPE WRTLPF		;STILL FOUND ERRORS?
	CALL CLRCDE		;PS IS OK - CLEAR MONITOR FLAGS
	JRST RESTRT		; AND RESTART
;CHECK (CONSISTENCY OF) DIRECTORY

;USER WANTS TO CHECK DIRECTORY CONSISTENCY.  GET CONFIRMATION

.DIREC:	HRROI T1,[ASCIZ /CONSISTENCY OF/]
	CALL CMDNOI		;GUIDE WORDS
	CALL CONFRM		;GET STR AND CONFIRM
	CALL PSCHK		;SEE IF THE PS:
	 CALL XMNTA		;NO - CHECK MOUNTED
	CALL SETSTR		;SET CURRENT STR

;GET THE FIRST DIRECTORY NUMBER AND STORE IT IN DIRNUM

	CALL FRSDIR		;GET FIRST DIRECTORY
	 JRST RESTRT		;FAILED.

;HAVE A DIRECTORY NUMBER. CHECK DIRECTORY'S CONSISTENCY

.DIRLP:	CALL GDNAM		;GET THE DIRECTORY NAME
	 JRST .DIRL1		;SKIP IF ERROR
	CALL CKDIR		;CHECK AND REBUILD IF NECESSARY
.DIRL1:
	CALL NXTDIR		;GET THE NEXT DIRECTORY		
	 JRST RESTRT		;FAILED OR DONE. START OVER
	JRST .DIRLP
;EXIT (TO MONITOR)

;USER WANTS TO QUIT.  GET CONFIRMATION AND EXIT

.EXIT:	HRROI T1,[ASCIZ /TO MONITOR/]
	CALL CMDNOI
	MOVEI T1,CMDBLK		;T1/ADDRESS OF COMMAND STATE BLOCK
	MOVEI T2,[FLDDB. (.CMCFM)] ;T2/ADDRESS OF FUNCTION DESCRIPTOR BLOCK
	COMND			;GET CONFIRMATION
	TXNE T1,CM%NOP		;DID WE GET IT?
	ERROR PARSE1,<Invalid command confirmation> ;NO
	CALL RESET
	JRST QUIT
;HELP

;USER WANTS AN EXPLANATION.  GET CONFIRMATION AND PRINT HELP TEXT

.HELP:	MOVEI T1,CMDBLK		;T1/ADDRESS OF COMMAND STATE BLOCK
	MOVEI T2,[FLDDB. (.CMCFM)] ;T2/ ADDRESS OF FDB
	COMND			;GET CONFIRMATION
	TXNE T1,CM%NOP		;DID WE GET IT?
	ERROR PARSE1,<Invalid command confirmation> ;NO. PRINT ERROR
	HRROI T1,HLPMSG
	PSOUT			;TYPE THE HELP MESSAGE TO USER'S TTY
	JRST PARSE1

;TEXT FOR HELP MESSAGE

HLPMSG:	ASCIZ/		TOPS-20 CHECKD
CHECKD is a program to check the filesystem and bittable for  consistent
data.   CHECKD  is  also  capable  of  rebuilding  the bittable from the
directory information and of scanning for  files  which  use  particular
disk addresses. Commands are in the general form:

	Keyword [optional arg] structure-name

Command			Description
-------			-----------

CHECK BITTABLE	Check the consistency of the bit table by comparing
		the pages marked as assigned against those pointed to
		by the file system. Also writes lost page addresses
		in a file.

CHECK DIRECTORY	Check just directory information on the specified
		structure.

LIMIT
UNLIMIT		Control whether directories may contain huge amounts
		of files or not.  Use LIMIT to guarantee that a
		particular structure can be used on small and large
		systems.  Use UNLIMIT to allow directories to grow
		large on a structure.  Note that if a directory grows
		large, the structure will no longer be usable on a
		small system.

REBUILD		Rebuild bittable from directory information on the
		specified structure.

RECONSTRUCT	Reconstucts the <ROOT-DIRECTORY> on the specified
		structure and then rebuilds the bit table.

CREATE		Accepts configuration information for a file
		structure and then creates a new file system on the
		specified units.

SCAN		Read a file of disk addresses and then scan the
		directories for the specified addresses. When each
		address is found, prints the name of the file that
		uses that address.

EXIT		Exit from CHECKD.

RELEASE		Deassign the pages whose addreses are contained 
		in the specified file.
/
;LIMIT/UNLIMIT (NUMBER OF FILES PER DIRECTORY ON STRUCTURE

.LIMIT:	MOVX T1,MS%LIM		;SET MS%LIM
	JRST LIM1

.UNLIM:	MOVEI T1,0		;CLEAR MS%LIM
	JRST LIM1

LIM1:	STKVAR <NEWVAL>
	MOVEM T1,NEWVAL
	HRROI T1,[ASCIZ /NUMBER OF FILES PER DIRECTORY ON/]
	CALL CMDNOI		;NOISE WORDS
	CALL CONFRM		;GET STR AND CONFIRM
	CALL SETSTR		;SET CURRENT STR
	CALL HOMEIN		;READ HOME BLOCKS (OF FIRST PACK)
	 JRST RESTRT		;GIVE UP IF CAN'T
	MOVE T2,HFLAGS	;GET OLD VALUE OF LIMIT BIT
	HRROI T1,[ASCIZ /[Directories were unlimited]
/]
	TXNE T2,MS%LIM		;ANNOUNCE OLD VALUE
	HRROI T1,[ASCIZ /[Directories were limited]
/]
	PSOUT
	HRROI T1,STRNAM		;GET POINTER TO STRUCTURE NAME
	MOVEM T1,HOMARG+.MSHNM	;STORE STRUCTURE BEING MODIFIED
	MOVEI T2,HOMFLG		;WORD WE WANT TO MODIFY
	MOVE T3,NEWVAL		;GET NEW VALUE FOR MS%LIM BIT
	MOVX T4,MS%LIM		;SPECIFY WHICH BIT TO MODIFY
	DMOVEM T1,HOMARG	;STORE ARGS IN ARG BLOCK
	DMOVEM T3,HOMARG+.MSHVL
	DMOVE T1,[EXP <4,,.MSHOM>,HOMARG]
	MSTR			;MODIFY HOME BLOCK
	 ERCAL JSERR0		;FAILED, PRINT REASON
	JRST RESTRT		;RESTART

;REBUILD (BIT TABLE).

;USER WANTS TO REBUILD THE BIT TABLE.  GET CONFIRMATION AND SET FLAG

.REBLD:	HRROI T1,[ASCIZ /BIT TABLE OF/]
	CALL CMDNOI		;NOISE WORDS
	CALL CONFRM		;GET STR AND CONFIRM
	CALL PSCHK		;CHECK FOR PS:
	 CALL XMNT		;NOT PS - MUST MOUNT IT
	CALL SETSTR		;SET CURRENT STR
	SETOM REBLDF		;YES. SET FLAG FOR QDONE CODE
	CALL BTBINI		;INIT BITTABLE
	CALL QDONE
	SKIPN PSFLG		;WAS THIS THE PS:?
	 JRST RESTRT		;NO - RESTART WHEN DONE
	CALL CLRCDE		;YES - CLEAR MONITOR FLAG
	JRST RESTRT		;AND RESTART

;ROUTINE TO INIT STRUCTURE BITTABLE

BTBINI:	MOVX T1,DA%INI		;T1/INITIALIZE BIT TABLE
	MOVE T2,STRDEV		;T2/STRUCTURE NUMBER
	DSKAS			;INITIALIZE A PRIVATE COPY OF THE BIT TABLE
	 JRST [	TMSG<
?Failed to initialize bit table
>
		JSERR
		JRST RESTRT]
	RET			;RETURN
;RECONSTURCT (ROOT-DIRECTORY)

;USER WANT TO TRY TO RECOVER A LOST FILE SYSTEM. FIRST COPY THE
;BACKUP COPY OF THE ROOT-DIRECTORY AND THEN REBUILD THE BITTABLE.

.RECNS:	MOVEI T1,CMDBLK		;COMMAND STATE BLOCK
	MOVEI T2,[FLDDB.(.CMKEY,,RECTAB)]	;SECONDARY KEYTABLE
	COMND
	TXNE T1,CM%NOP
	ERROR PARSE1,<Not a valid RECONSTRUCT option>
	HRRZ T1,(T2)		;GET DISPATCH
	JRST (T1)		;PROCESS

; TABLE OF OPTIONS FOR RECONSTRUCTION

RECTAB:	2,,2
	TB (.RECIT,INDEX-TABLE)
	TB (.RECRD,ROOT-DIRECTORY)
; RECONSTRUCT ROOT-DIRECTORY

.RECRD:	HRROI T1,[ASCIZ /OF/]
	CALL CMDNOI		;PRINT GUIDE WORDS
	CALL CONFRM		;GET STRUCTURE AND CONFIRM
	CALL PSCHK		;IS THIS THE PRIMARY PUBLIC STR
	 SKIPA			;NO - MUST GET EXCLUSIVE ACCESS
	ERROR PARSE1,<Cannot reconstruct PS: during time-sharing>
	SETZM OKFLG		;OK IF ON-LINE (MSG LATER)
	CALL FNDSTR		;FIND STRUCTURE (SET UP MNTBLK)
	 JRST PARSE1		;REASON ALREADY GIVEN
	JUMPL T1,[ERROR PARSE1,<Cannot reconstruct mounted structure>]
	CALL STRDEF		;SET UP DEFAULTS
	HRROI T1,[ASCIZ /CHECKD/]
	MOVEM T1,MNTBLK+.MSIAL	;SET UP ALIAS
	MOVX T1,MS%XCL+<FLD(.MSRRD,MS%FCN)> ;FCN FOR RECONSTRUCT
	CALL STRINI		;INIT STRUCTURE
	 JRST PARSE1		;FAILURE
	TMSG <[Reconstruction phase 1 complete]
>
	CALL SETSTR		;SET CURRENT STRUCTURE
	SETOM REBLDF		;FLAG FOR QDONE REBUILD
	CALL BTBINI		;INIT BITTABLE
	CALL QDONE		;SCAN DIRECTORIES
	JRST RESTRT		;RESTART PROGRAM
; RECONSTRUCT INDEX-TABLE

.RECIT:	HRROI T1,[ASCIZ /OF/]
	CALL CMDNOI		;PRINT GUIDE WORDS
	CALL CONFRM		;GET STRUCTURE AND CONFIRM
	CALL PSCHK		;IS THIS THE PRIMARY PUBLIC STR
	 SKIPA			;NO - MUST GET EXCLUSIVE ACCESS
	ERROR PARSE1,<Cannot reconstruct PS: during time-sharing>
	SETOM OKFLG		;ASK ABOUT DISMOUNTING IF NOW MOUNTED
	CALL FNDSTR		;FIND STRUCTURE (SET UP MNTBLK)
	 JRST PARSE1		;REASON ALREADY GIVEN
	JUMPL T1,[ERROR PARSE1,<Cannot reconstruct mounted structure>]
	CALL STRDEF		;SET UP DEFAULTS
	HRROI T1,[ASCIZ /CHECKD/]
	MOVEM T1,MNTBLK+.MSIAL	;SET UP ALIAS
	MOVX T1,MS%XCL+<FLD(.MSRIX,MS%FCN)> ;FCN FOR RECONSTRUCT
	CALL STRINI		;INIT STRUCTURE
	 JRST PARSE1		;FAILURE
	TMSG <[Reconstruction complete]
>
	JRST RESTRT		;DONE
;RELEASE (LOST PAGES)

;USER WANTS TO RELEASE LOST PAGES.  THESE ARE PAGES MARKED IN THE BIT
;TABLE AS USED AND NOT POINTED TO BY ANY FILE.  A PREVIOUS CALL TO
;CHECKD HAS PRODUCED A FILE OF THESE PAGES.  GET CONFIRMATION AND SET
;FLAGS AS NEEDED

.RLEAS:	STKVAR<DSKAD2,SAVCHN>
	HRROI T1,[ASCIZ /LOST PAGES FROM/]
	CALL CMDNOI		;PRINT NOISE WORDS

	MOVE T1,[RLSGTJ,,GTJBLK]	;COPY SPECIAL JFN BLOCK TO COMND'S JFN 
	BLT T1,GTJBLK+.GJJFN-1	; BLOCK TO SPECIFY DEFAULT FILE
	CALL GETCON		;SET UP CONNECTED STR
	HRROI T1,DIRNAM		;BUILD DEFAULT FILESPEC
	HRROI T2,STRNAM
	MOVEI T3,0
	SOUT
	MOVEI T2,"-"
	IDPB T2,T1
	HRROI T2,[ASCIZ "LOST-PAGES"]
	SOUT			;STR:STR-LOST-PAGES.BIN
	MOVEI T1,CMDBLK		;T1/ADDRESS OF COMMAND STATE BLOCK
	MOVEI T2,[FLDDB.(.CMFIL)] ;T2/ADDRESS OF FUNCTION DESCRIPTOR BLOCK
	COMND			;GET INPUT FILE SPEC, DEFAULTING TO LOST-PAGES.BIN
	TXNE T1,CM%NOP		;DID WE SUCCEED?
	JRST [	JSERR		;NO. GIVE THE LAST ERROR
		JRST PARSE1]	; AND START THE PARSE OVER
	HRRZM T2,INJFN		;YES. SAVE THE FILE'S JFN
	CALL FCNFRM		;(FOR) STR: & CONFIRM
	CALL PSCHK		;OK IF PS
	 CALL XMNTA		;MOUNT IF NOT ON LINE
	CALL SETSTR		;SET CURRENT STRUCTURE
	MOVE T1,INJFN		;T1/JFN FOR INPUT FILE
	MOVE T2,[44B5+1B19]
	OPENF			;OPEN THE INPUT FILE
	 JRST [	PNTERR(<Failed to open lost pages file>)
		MOVE T1,INJFN	;T1/JFN OF INPUT FILE
		RLJFN		;RELEASE THE JFN
		 JFCL		;IGNORE FAILURE
		JRST PARSE1]	;GO START PARSE AGAIN
	CALL LPFCHK		;CHECK FILE FORMAT
	 JRST [	MOVE T1,INJFN	;INPUT JFN
		RLJFN		;FLUSH IT
		 JFCL
		JRST RESTRT]	;FORGET IT
	SETZM LOSTOT		;CLEAR COUNT
;READ DISK ADDRESSES FROM FILE.   EACH ADDRESS IS A SECTOR NUMBER RELATIVE
;TO START OF STRUCTURE.  DEASSIGN VIA DSKAS JSYS.

RLSPG1:	MOVE T1,INJFN		;T1/JFN OF INPUT FILE
	BIN			;READ ONE ADDRESS
	 ERJMP RLSPG2		;ERROR OR EOF
	JUMPE T2,[TMSG <% Zero word -- ignored
>
		 JRST RLSPG1]
	MOVE T1,T2		;T1/SECTOR NUMBER
	MOVEM T1,DSKAD2
	TXO T1,DA%DEA
	MOVE T2,STRDEV		;T2/STRUCTURE NUMBER
	DSKAS
	 JRST [	TMSG <%Failed to deassign lost page at disk address>
		MOVE T2,DSKAD2	;T2/FAILING ADDRESS
		MOVEI T3,10	;T3/OCTAL RADIX
		CALL TTNOUT	;PRINT THE ADDRESS THAT FAILED
		JRST RLSPG1]	;IGNORE THE FAILURE
	AOS LOSTOT		;COUNT SUCCESS
	JRST RLSPG1		;LOOP UNTIL EOF

;COME HERE ON ERROR OR END OF FILE - CHECK WHICH

RLSPG2:	MOVE T1,INJFN
	GTSTS			;GET FILE STATUS
	TXNN T2,GS%EOF
	JRST [	TMSG <?Error while reading >
		MOVEI T1,.PRIOU
		MOVE T2,INJFN
		MOVEI T3,0
		JFNS		;PRINT FILE NAME
		TMSG < , Aborting...
>
		JRST .+1]
	TMSG < Released >
	MOVEI T1,.PRIOU
	MOVE T2,LOSTOT
	MOVEI T3,^D10
	NOUT			;TELL HOW MANY
	 JFCL
	TMSG < pages
>
	HRRZ T1,INJFN		;GET JFN BACK
	DELF			;DELETE FILE AND RELEASE JFN
	 JSERR
	HRRZ T1,INJFN
	CLOSF
	 JFCL
	JRST RESTRT		;DONE - RESTART
;SCAN (FOR DISK ADDRESSES FROM FILE) FILE-SPECIFICATION

;USER WANTS TO SEARCH A FILE CONTAINING DISK ADDRESSES THAT ARE ASSIGNED
;TO MORE THAN ONE FILE.  EACH TIME A FILE IS FOUND TO POINT TO ONE OF THESE
;ADDRESSES A MESSAGE WILL BE PRINTED.  GET THE NAME OF THE FILE TO BE 
;READ AND CONFIRMATION. SET FLAGS AS NEEDED.

.SCAN:	HRROI T1,[ASCIZ /FOR DISK ADDRESSES IN/]
	CALL CMDNOI		;PRINT NOISE WORDS
	MOVEI T1,CMDBLK		;T1/ADDRESS OF COMMAND STATE BLOCK
	MOVEI T2,[FLDDB.(.CMIFI)] ;T2/ADDRESS OF FDB
	COMND			;GET FILE TO SCAN
	TXNE T1,CM%NOP		;DID WE GET IT?
	JRST [	JSERR		;NO. REPORT ERROR AND START OVER
		JRST PARSE1]
	HRRZM T2,DAJFN		;YES. SAVE THE JFN
	CALL FCNFRM		;GET STR AND CONFIRM
	CALL PSCHK		;OK IF PS:
	 CALL XMNTA		;MOUNT IF NOT ONLINE
	CALL SETSTR		;SET CURRENT STR
	SETOM CHKFLF		;YES. SET FLAG FOR QDONE CODE
	MOVE T1,DAJFN		;T1/JFN
	MOVE T2,[XWD 70000,200000]
	OPENF
	 JRST [	PNTERR(<Failed to open specified file>)
		MOVE T1,DAJFN
		RLJFN
		 JFCL
		JRST PARSE1]
	MOVSI P1,-DASIZ
	;..
;READ EACH ADDRESS AND STORE 2 WORDS PER ADDRESS:
;1)	SOFTWARE ADDRESS
;2)	GIVEN ADDRESS

	;..
RDDALP:	MOVE T1,DAJFN
	CALL RDLIN		;READ ONE ADDRESS
	MOVE T1,[POINT 7,LINBUF]
	SETZ Q1,			;ASSUME SOFTWARE ADDRESS
RDDL1:	ILDB T2,T1
	CAIN T2," "		;FLUSH SPACES
	JRST RDDL1
	CAIE T2,"Z"-100		;EOF?
	CAIN T2,0
	JRST RDDAW		;YES, DONE
	CAIN T2,"H"		;HARDWARE ADDRESS?
	JRST [	SETO Q1,		;YES
		JRST RDDL1]
	CAIN T2,"S"		;SOFTWARE ADDRESS?
	JRST [	SETZ Q1,		;YES
		JRST RDDL1]
	CAIL T2,"0"		;OCTAL DIGIT?
	CAILE T2,"7"
	JRST [	TMSG <?Octal number required.
>
		JRST RDDALP]	;TRY AGAIN
	BKJFN			;BACKUP THE POINTER OVER FIRST DIGIT
	 JFCL
	MOVEI T3,^D8		;READ NUMBER IN OCTAL
	NIN
	 JRST [	JSERR
		TMSG <?Octal number required.
>
		JRST RDDALP]
	MOVE T1,T2
	MOVEM T1,DATAB+1(P1)	;STORE GIVEN ADDRESS
	SKIPE Q1			;USE GAVE SOFTWARE ADDRESS?
	JRST [	TXO T1,DA%CNV+DA%HWA
		MOVE T2,STRDEV	;T2/STRUCTURE NUMBER
		DSKAS		;NO, CONVERT
		 JSERR
		JRST .+1]
	MOVEM T1,DATAB(P1)	;STORE SOFTWARE ADDRESS
	AOBJN P1,.+1
	AOBJN P1,RDDALP
	TMSG <?Table full.
>

;REACHED END OF FILE.  EACH ADDRESS HAS BEEN WRITTEN IN 2 FORMS IN THE 
;DATAB ARRAY.  STORE AOBJN POINTER TO DATAB IN DALIST.

RDDAW:	HLRES P1		;NEGATIVE OF SPACE REMAINING
	MOVNS P1		;SPACE REMAINING
	SUBI P1,DASIZ		;NEGATIVE OF SPACE USED
	HRLZM P1,DALIST		;(-SPACE USET4,,0)
	MOVE T1,DAJFN		;T1/JFN FOR INPUT FILE
	CLOSF			;CLOSE THE FILE
	 JFCL			;IGNORE FAILURE
	CALL QDONE		;NO MORE QUESTIONS
	JRST RESTRT		;DONE - RESTART
;HERE WHEN USER HAS REQUESTED BITTABLE, REBUILT4, OR SCAN
;FLAGS INDICATE WHAT FUNCTIONS TO PERFORM

QDONE:	CALL HOMEIN		;GO COMPUTE HOME BLOCK STUFF
	 JRST QDON1		;ERROR
	CALL BATIN		;GO GET THE BAT BLOCKS
	MOVEI T1,.CHLFD		;T1/LINE FEED
	PBOUT			;PRINT A LINE FEED
	CALL INIBTB		;INITIALIZE LOCAL COPY OF BIT TABLE
	CALL SCANDI		;GO SCAN ALL THE DIRECTORIES
	SKIPN DALIST		;SCANNING FOR DISK ADDRESSES?
	SKIPN CHKFLF		;NO. CHECKING FILES?
	JRST QDON1		;SCANNING OR NOT CHECKING FILES. DON'T DO
				; BIT TABLE STUFF
	CALL FINBTB		;YES, DO SUMMARY, ETC.
QDON1:	CALL RESET
	RET			;RETURN TO CALLER

QUIT:	MOVEI T1,1		;T1/CODE FOR ^A
	DTI			;DEASSIGN ^A FROM CHANNEL 2
	SKIPN JOBNO		;CAME FROM JOB 0?
	HALTF			;YES. ^C WASN'T ASSIGNED
	MOVEI T1,3		;T1/CODE FOR ^C
	DTI			;DEASSIGN ^C FROM CHANNEL 1
	HALTF
	JRST .-1

;GET HERE ON FATAL ERROR

FATAL:	HRROI T1,[ASCIZ /CHECKD: unknown error condition/]
	ESOUT
	HALTF
	JRST RESTRT		;RESTART IF CONTINUED
;ROUTINE TO READ IN THE HOME BLOCKS AND SET NSSUN AND FSSUN

HOMEIN:	MOVEI T1,1		;READ IN FIRST HOME BLOCK
	CALL GETHOM
	 JRST HOMIN2		;FAILED, TRY SECOND HOME BLOCK

;TEMPORARY 

HOMIN1:
	MOVEI T2,SECPAG
	MOVE T1,BATBUF+HOMSIZ	;GET # OF PAGES FOR SWAPPING PER UNIT
	CAIN T1,SECUN0		;IS THIS AN RP04 OR RP05
	JRST [	HRLI T2,DSKSZ0	;YES. POINT TO THAT DATA
		JRST HOMIN3]
	CAMN T1,[SECUN1]		;IS THIS AN RP06?
	JRST [	HRLI T2,DSKSZ1	;YES. POINT TO THAT DATA
		JRST HOMIN3]
	CAMN T1,[SECUN3]	;IS THIS AN RM03?
	JRST [	HRLI T2,DSKSZ3	;YES. POINT TO THAT DATA
		JRST HOMIN3]
	TMSG <
? HOMEIN: Unknown disk drive type
>
	RET			;ERROR RETURN

HOMIN3:	BLT T2,LPPCYL		;COPY THE RIGHT SIZE DATA
	MOVE T1,BATBUF+HOMFLG	;GET HOME BLOCK FLAGS
	MOVEM T1,HFLAGS		;REMEMBER THEM
	MOVE T1,BATBUF+HOMP4S	;GET # OF PAGES FOR SWAPPING PER UNIT
	IMUL T1,SECPAG		;GET # OF SWAPPING SECTORS
	MOVEM T1,NSSUN
	MOVE T1,BATBUF+HOMFST	;GET FIRST SWAPPING CYLINDER
	IMUL T1,SECCYL		;CONVERT TO SECTOR
	MOVEM T1,FSSUN		;SECTOR OFFSET FOR SWAPPING SPACE
	HLRZ T1,BATBUF+HOMLUN	;GET NUMBER OF PACKS IN SYSTEM STR
	MOVEM T1,NPACKS
	SETZM LOTRK		;FIRST CYLINDER IS ALWAYS 0
	IMUL T1,CYLUNT		;COMPUTE LAST CYLINDER
	MOVEM T1,HITRK		;HITRK = NTKUN*NPACKS
	SKIPN T1,BATBUF+HOMBTB	;SEE IF SIZE OF BIT TABLE IS DEFINED
	JRST [	MOVEI T1,OLDTOP	;NO. MUST HAVE BEEN BUILT BY OLD MONITOR
		MOVEM T1,BTBTOP	;SAVE OLD SIZE OF TOP HALF OF BIT TABLE
		MOVEI T1,OLDBOT	; AND OLD SIZE OF BOTTOM HALF
		MOVEM T1,BTBBOT
		JRST HOMIN4]
	MOVEM T1,BTBTOP		;BUILT BY RELEASE 2 OR LATER.  SAVE SIZE
				; OF TOP HALF OF BIT TABLE
	IMUL T1,BTWCYL		;COMPUTE NUMBER OF BIT WORDS IN BOTTOM
	MOVEM T1,BTBBOT		; AND SAVE IT
HOMIN4:	ADD T1,BTBTOP		;COMPUTE TOTAL SPACE IN FILE
	CAILE T1,BTBMAX		;WILL IT FIT IN ADDRESS SPACE?
	JRST [	TMSG<
? HOMEIN: Bit table too large
>
		RET]
	ADDI T1,<PGSIZ-1>	;ROUND UP TO NEXT PAGE
	IDIVI T1,PGSIZ		;COMPUTE NUMBER OF PAGES IN FILE
	MOVEM T1,BTBPGS		;SAVE SIZE OF BIT TABLE FILE
	RETSKP

HOMIN2:	MOVEI T1,12		;SECOND HOME BLOCK
	CALL GETHOM		;READ IT IN
	 JRST NOHOME		;FAILED
	JRST HOMIN1		;SUCCESS

NOHOME:	TMSG <HOMEIN: Could not find a valid home block>
	RET

GETHOM:	TXO T1,<FLD .DOPSR,DOP%AT> ;LOGICAL ADDRESS
	MOVE T4,STRDEV		;GET STRUCTURE NUMBER
	TXO T1,DOP%SN		;SET MASK TO ALL ONES
	MOVEI T2,NWSEC		;LENGTH OF BLOCK
	MOVEI T3,BATBUF		;ADR OF AREA TO READ INTO
	DSKOP
	JUMPN T1,R		;IF ERROR, RETURN
	MOVS T1,BATBUF+HOMNAM	;CHECK CONSISTENCY
	CAIE T1,'HOM'
	RET
	MOVE T1,BATBUF+HOMCOD	;AND SPECIAL CODE
	CAIE T1,CODHOM
	RET
	RETSKP			;HOME BLOCK OK
;ROUTINE TO READ IN ALL OF THE BAT BLOCKS AND SET UP THE
;ERROR PAIRS

BATIN:	STKVAR <LSTSEC,SAVWRK>
	MOVE T1,NPACKS		;# OF PACKS IN STRUCTURE
	IMUL T1,SECUNT		;COMPUTE SECTORS IN STRUCTURE
	MOVEM T1,LSTSEC		;SAVE IT
	MOVEI Q1,2		;FIRST BAT ADDRESS
	MOVEM P1,SAVWRK		;SAVE PERMANENT REG
	MOVEI P1,BPRBLK		;START OF TABLE
GETBAT:	MOVE T1,Q1		;DISK ADDRESS
	TXO T1,<FLD .DOPSR,DOP%AT> ;LINEAR ADDRESS
	MOVE T4,STRDEV		;GET STRUCTURE NUMBER
	TXO T1,DOP%SN		;SET TO -1
	MOVEI T2,NWSEC		;SIZE OF A BLOCK
	MOVEI T3,BATBUF		;BUFFER FOR THE BAT BLOCK
	DSKOP			;GET THE BLOCK
	JUMPN T1,TRY2		;IF BAT4, TRY SECONDARY
	MOVS T1,BATBUF		;GET HEADER WORD
	CAIE T1,'BAT'		; A BAT BLOCK?
	JRST TRY2		;NO. TRY SECONDARY
	MOVE T1,BATBUF+BATCOD	;SEE IF UNIQUE CODE IS THERE
	CAIE T1,CODE		;IS IT?
	JRST TRY2		;NO. TRY SECONDARY THEN
GOTBAT:	MOVEI T4,BATBUF		;T4/ADDRESS OF START OF BAT BLOCK
	LOAD T2,BTHCT,(T4)	;GET NUMBER OF PAIRS WRITTEN INITIALLY
	LOAD T3,BTMCT,(T4)	;GET NUMBER OF PAIRS MONITOR HAS WRITTEN
	ADD T2,T3		;TOTAL PAIRS WRITTEN
	CAILE T2,MAXPAR		;DID BLOCK OVERFLOW?
	MOVEI T2,MAXPAR		;YES. ONLY LOOK AT VALID PART THEN
	MOVEM T2,OVERHD		;COUNT THESE AS OVERHEAD UNLESS THEY ARE
				; FOUND TO BE ASSIGNED LATER
	MOVEM T2,BATCNT		;KEEP A SEPARATE COUNT, TOO
	JUMPE T2,NONE		;IF NONQ1, GO TO NEXT UNIT
	MOVEI T3,BATBUF+4	;FIRST BAD PAIR IN BLOCK
NXTPR:	HRRZ T4,1(T3)		;GET START ADDRESS
	ADD T4,Q1		;MAKE IT A LINEAR ADDRESS
	SUBI T4,2		;REMOVE BIAS FOR BAT BLOCK
	MOVEM T4,0(P1)		;STASH IT IN ERROR BUFFER
	MOVE T1,0(T3)
	LSH T1,-^D27		;GET COUNT OF BAD BLOCKS
	ADDI T4,0(T1)		;CALCULATE LAST ONE
	MOVEM T4,1(P1)		;FINISH OFF PAIR
	ADDI P1,2		;NEXT PAIR IN BUFFER
	ADDI T3,2		;NEXT PAIR IN BAT BLOCK
	SOJG T2,NXTPR		;DO ALL PAIRS
NONE:	ADD Q1,SECUNT		;NEXT PACK
	CAMGE Q1,LSTSEC		;OVER THE LAST PACK IN THE STRUCTURE?
	JRST GETBAT		;NO. GO DO IT
	MOVEM P1,SVEND		;YES. SAVE END
	MOVE P1,SAVWRK		;RESTORE PERMANENT REG
	RET			;AND DONE
;PRIMARY BAT BLOCK WAS BAD. TRY THE SECONDARY

TRY2:	MOVE T1,Q1		;GET ADDRESS
	ADDI T1,11		;GET UP TO THE SECONDARY
	MOVE T4,STRDEV		;GET STRUCTURE NUMBER
	TXO T1,DOP%SN		;SET TO ONES
	TXO T1,<FLD .DOPSR,DOP%AT> ;LINEAR ADDRESS
	DSKOP			;READ IN THE SECONDARY
	JUMPN T1,NONE		;IF ERROR, NONE THERE
	MOVS T1,BATBUF
	CAIE T1,'BAT'		;A GOOD BAT BLOCK?
	JRST NONE		;NO. GIVE UP
	MOVE T1,BATBUF+BATCOD	;UNLIKELY CODE
	CAIE T1,CODE		;GOOD?
	JRST NONE		;NO. NO BAT BLOCKS
	JRST GOTBAT		;YES, USE THIS ONE
;INIBTB - INITIALIZE THE BIT TABLE

;ACCEPTS: NONE

;	CALL INIBTB

;RETURNS +1:ALWAYS

;THIS ROUTINE INITIALIZES THE LOCAL COPY OF THE BIT TABLE USING THE SAME CODE
;AS THE MONITOR USES IN DSKAL1.  FIRST IT INITIALIZES THE TABLE SO THAT ALL
;PAGES ARE FREE. THEN IT ASSIGNS THE SPECIAL SYSTEM BLOCKS ON EVERY PACK
;AND CALLS SWPASN TO ASSIGN THE SWAPPING SPACE

INIBTB:	SAVEQ
	STKVAR <LSTPAG>
	MOVE T1,PAGCYL		;GET NUMBER OF PAGES PER CYLINDER
	MOVN T2,BTBTOP		;GET SIZE OF TOP HALF OF BIT TABLE
	HRLZS T2		;T2/(-COUNT,,OFFSET IN TOP HALF)
INIBT2:	MOVEI T3,0(T2)		;GET OFFSET
	ADDI T3,LOCBTB		;ADDRESS OF CURRENT WORD
	MOVEM T1,0(T3)		;STORE FULL COUNT FOR EACH CYLINDER
	AOBJN T2,INIBT2		;GO TO NEXT WORD
	MOVE T2,BTBTOP		;START AT BEGINNING OF BIT PART OF BIT TABLE
	ADDI T2,LOCBTB		;COMPUTE ADDRESS OF FIRST BIT WORD
INIBT1:	SETOM 0(T2)		;INIT ONE BIT WORD
	SUBI T1,^D36		;REDUCE COUNT OF PAGES (1 BIT PER PAGE)
	CAILE T1,^D36		;LAST WORD?
	AOJA T2,INIBT1		;NO. GO INITIALIZE IT

	MOVN T1,BITS-1(T1)	;LAST WORD PARTIALLY FULL. SET ONLY VALID BITS
	MOVEM T1,1(T2)		;STORE LAST WORD FOR FIRST CYLINDER
	MOVEI T1,LOCBTB		;CONSTRUCT STARTING LOCATIONS FOR BLT
	HRLS T1			;(START OF TABLE,,START OF TABLE)
	MOVE T3,BTBTOP		;GET SIZE OF TOP HALF OF BIT TABLE
	HRLS T3			; IN BOTH HALVES
	ADD T1,T3		;(START OF BOTTOM HALF,,START OF BOTTOM HALF)
	ADD T1,BTWCYL		;(START OF BOTTOM HALF,,2ND GROUP OF WORDS)
	MOVEI T2,LOCBTB		;CONSTRUCT LIMIT FOR BLT
	ADD T2,BTBTOP		;POINT TO BOTTOM HALF OF BIT TABLE
	ADD T2,BTBBOT		;POINT JUST BEYOND END
	SUBI T2,1		;POINT TO LAST WORD FOR LIMIT OF BLT
	BLT T1,0(T2)		;COPY GROUPS OF BIT WORDS TO REST OF TABLE

;ASSIGN THE HOME BLOCKS

	SETZM NBAD		;INITIALIZE COUNT OF ERRORS
	SETOM PAGNN		;INDICATE NOT A FILE PAGE
	MOVSI Q3,-NHOME		;Q3/(-COUNT,,OFFSET TO HOME TABLE)
	SETOM LSTPAG		;INITIALIZE LAST PAGE ASSIGNED

;LOOP OVER SPECIAL SECTORS IN HOME BLOCK TABLE

HOMAS1:	MOVE T1,HOME(Q3)	;GET SECTOR NUMBER WITHIN UNIT
	IDIV T1,SECPAG		;CONVERT TO PAGE
	CAMN T1,LSTPAG		;SAAME AS LAST PAGE ASSIGNED?
	JRST HOMAS3		;YES. DON'T ASSIGN IT AGAIN
	
;ASSIGN THIS PAGE FOR ALL UNITS

	MOVEM T1,LSTPAG		;SAVE LAST PAGE ASSIGNED
	MOVN Q2,NPACKS		;NO. GET NUMBER OF UNITS IN STRUCTURE
	HRLZS Q2		;Q2/(-COUNT,,UNIT NUMBER)
HOMAS2:	MOVEI T1,0(Q2)		;GET UNIT NUMBER
	IMUL T1,SECUNT		;COMPUTE FIRST SECTOR IN THIS UNIT
	ADD T1,HOME(Q3)		;T1/SECTOR TO ASSIGN
	MOVX F,MR%SPC		;INDICATE SPECIAL BLOCKS
	CALL MRKBTB		;ASSIGN PAGE
	 JFCL			;IGNORE FAILURE. ERROR HAS BEEN REPORTED
	AOBJN Q2,HOMAS2		;LOOP TO NEXT UNIT IN STRUCTURE
HOMAS3:	AOBJN Q3,HOMAS1		;LOOP TO NEXT SPECIAL SECTOR
	SKIPE NBAD		;DID WE GET ANY ERRORS?
	JRST [	TMSG <- - - - - - -
>				;YES. PRINT DIVIDER TO SEPARATE FROM FILE OUTPUT
		SETZM NBAD	;RESET COUNT
		JRST .+1]
	CALL SWPASN		;MARK THE SWAPPING PAGES
	RET
;DSKASA - ASSIGN PAGE IN LOCAL BIT TABLE

;ACCEPTS:
;	1/SECTOR NUMBER RELATIVE TO START OF STRUCTURE

;	CALL DSKASA

;RETURNS +1: ILLEGAL ADDRESS OR ADDRESS ALREADY ASSIGNED
;		T4/ERROR CODE
;	 +2: SUCCESS, PAGE ASSIGNED

;THIS ROUTINE ASSIGNS A PAGE IN THE LOCAL BIT TABLE USING THE SAME METHOD
;AS THE MONITOR USES IN DSKAL1.  IT ASSIGNS THE PAGE CONTAINING THE
;SPECIFIED SECTOR.  IF THE PAGE IS ALREADY ASSIGNED, IT TAKES THE ERROR
;RETURN.

DSKASA:	
	SETZ T4,		;INITIALIZE ERROR FLAG
	IDIV T1,SECCYL		;T1/CYLINDER, T2/SECTOR WITHIN CYLINDER
	CAML T1,LOTRK		;NON-NEGATIVE CYLINDER NUMBER?
	CAML T1,HITRK		;WITHIN STRUCTURE'S LIMITS?
	JRST DSKAS1		;RETURN ILLEGAL ADDRESS
	CAML T1,BTBTOP		;WITHIN TOP HALF OF BIT TABLE?
	JRST DSKAS1		;NO. RETURN ILLEGAL ADDRESS
	MOVE T3,PAGCYL		;GET PAGES PER CYLINDER
	IMUL T3,SECPAG		;COMPUTE NUMBER SECTORS IN COMPLETE PAGES
	CAML T2,T3		;IS THIS SECTOR WITHIN A FULL PAGE (POSSIBLE
				; EXTRA SECTORS AT END OF CYLINDER)?
	JRST DSKAS1		;NO. RETURN ILLEGAL ADDRESS
	MOVE T4,T1		;4/CYLINDER NUMBER
	IDIV T2,SECPAG		;CONVERT SECTOR TO PAGE WITHIN CYLINDER
	JUMPN T3,DSKAS1		;MUST BE ON PAGE BOUNDARY
	IDIVI T2,^D36		;GET INDEX TO BIT WORD WITHIN CYLINDER
	IMUL T1,BTWCYL		;OFFSET IN BOTTOM FOR THIS CYLINDER
	ADD T1,T2		;OFFSET IN BOTTOM FOR THIS PAGE
	ADD T1,BTBTOP		;OFFSET IN BIT TABLE FOR BIT WORD
	MOVE T3,BITS(T3)	;BIT FOR THIS PAGE
	TDNN T3,LOCBTB(T1)	;IS PAGE ALREADY ASSIGNED?
	JRST DSKAS2		;YES. REPORT MULTIPLY ASSIGNED ADDRESS
	ANDCAM T3,LOCBTB(T1)	;NO. ASSIGN IT
	SOS LOCBTB(T4)		;REDUCE FREE COUNT
	RETSKP

DSKAS1:	MOVX T4,ER%IDA		;INDICATE ILLEGAL ADDRESS
	RET
DSKAS2:	MOVX T4,ER%MDA		;INDICATE MULTIPLY ASSIGNED
	RET
;ROUTINE TO ASSIGN THE SWAPPING BLOCKS
;	CALL SWPASN
;RETURNS +1:	ALWAYS

SWPASN:	MOVN P1,NPACKS		;SET UP AN AOBJN POINTER
	HRLZS P1		;FOR ALL PACKS IN SYSTEM
	SETZM NBAD		;INITIALIZE COUNT OF ERRORS
	SETOM PAGNN		;INDICATE NOT A FILE PAGE
SWPAS1:	MOVE P2,SECUNT		;GET # OF SECTORS PER UNIT
	IMULI P2,0(P1)		;GET LOGICAL ADR OF START OF THIS PACK
	ADD P2,FSSUN		;GET START OF SWAPPING SPACE ON UNIT
	MOVE P3,NSSUN		;GET # OF SWAPPING SECTORS PER UNIT
	ADD P3,SECPAG		;MAKE SURE TO EVEN UP TO FULL PAGE
	SUBI P3,1
	IDIV P3,SECPAG		;GET # OF PAGES FOR SWAPPING
	JUMPE P3,SWPAS3		;IF NO SWAPPING SKIP UNIT
SWPAS2:	MOVE T1,P2		;GET NEXT PAGE TO BE ASSIGNED
	MOVX F,MR%SWP		;INDICATE THIS IS SWAPPING SPACE
	CALL MRKBTB		;ASSIGN THE PAGE
	 JFCL			;IGNORE FAILURE.  ERROR HAS BEEN REPORTED
	ADD P2,SECPAG		;STEP TO THE NEXT PAGE
	SOJG P3,SWPAS2		;LOOP BACK FOR ALL PAGES ON UNIT
SWPAS3:	AOBJN P1,SWPAS1		;LOOP BACK FOR ALL UNITS
	SKIPE NBAD		;DID WE GET ANY ERRORS?
	 JRST [	TMSG <- - - - - - -
>				;PRINT DIVIDER TO SEPARATE FROM FILE OUTPUT
		SETZM NBAD	;RESET COUNT OF ERRORS
		JRST .+1]
	RET			;AND RETURN
;SCAN ALL DIRECTORIES. CALLS SCANFD WITH ONE DIRECTORY, LOOPS THROUGH ALL DIRECTORIES

SCANDI:

;SET UP STR:<ROOT-DIRECTORY> IN ROOTDR

	HRROI T1,ROOTDR		;T1/ DESTINATION  POINTER
	HRROI T2,STRNAM		;T2/ SOURCE IS STRUCTURE NAME
	SETZ T3,		;T3/ STOP ON NULL
	SOUT			;PUT STRUCTURE NAME IN ROOTDR
	MOVEI T2,":"		;T2/ A COLON
	IDPB T2,T1		;ADD A COLON AFTER STRUCTURE
	HRROI T2,[ASCIZ/<ROOT-DIRECTORY>/]		
	SETZ T3,		;STOP ON NULL
	SOUT			;ADD <ROOT-DIRECTORY> TO STRUCTURE
	MOVEM T1,ROOTPT		;SAVE POINTER TO END
	CALL FRSDIR		;GET THE FIRST DIRECTORY
	 RET			;FAILED. QUIT
SCAND2:	CALL GDNAM		;GET NAME & NUMBER
	 JRST SCAND1		;SKIP IF ERROR
	CALL CKDIR		;CHECK AND REBUILD IF NECESSARY
	CALL SCANFD		;SCAN THIS DIRECTORY
SCAND1:	CALL NXTDIR		;GET NEXT DIRECTORY
	 RET			;FAILED OR DONE
	JRST SCAND2		;GO CHECK THIS ONE
;SCAN ONE DIRECTORY. CALLS SCAN3 FOR A SYMBOL TABLE ENTRY, LOOPS THROUGH 
;ALL SYMBOL TABLE ENTRIES

;DIRNUM/DIRECTORY NUMBER

SCANFD:	HRRZ T1,DIRNUM		;USE NUMBER ONLY (ON THIS STR)
	CALL SETFD		; MAP THE APPROPRIATE DIRECTORY
				;DIRORG IS STARTING LOCATION
	 RET			;FAILED TO MAP OR HEADER WAS BAD
	MOVE T1,[POINT 7,DIRNAM]
	MOVEI T2,DIRORG
	LOAD T2,DRNUM,(T2)	; GET DIRECTORY NUMBER
	HRL T2,STRDEV		; ADD STR UNIQUE CODE
	DIRST			;PUT NAME OF DIRECTORY IN DIRNAM
	 JFCL
	MOVEI T2,0
	IDPB T2,T1		;TERMINATE WITH NULL
	MOVEI T4,DIRORG
	LOAD T1,DRSTP,(T4)	;GET LAST WORD USED BY SYMBOL TABLE
	MOVEM T1,SYMTOP
	LOAD T4,DRSBT,(T4)	;GET ADDRESS OF START OF SYMBOL TABLE

;NOTE: ASSUMES HEADER IS 2 WORDS

SCAN1:	ADDI T4,.SYMLN		; STEP TO NEXT SYMBOL
	CAMGE T4,SYMTOP		; REACHED END OF SYMBOL TABLE?
	JRST SCAN2		; NO

;END OF SYMBOL TABLE. UNMAP THE DIRECTORY

	CALL UNMAPD		;UNMAP THE DIRECTORY
	RET

SCAN2:	MOVE T3,T4		; GET POINTER TO SYMBOL
	ADDI T3,DIRORG		; GET ABS ADR OF SYMBOL
	LOAD T1,SYMET,(T3)	; GET ENTRY TYPE
	JUMPN T1,SCAN2A		; IF NOT A NAME, SKIP IT
	LOAD T1,SYMAD,(T3)	; GET ADDRESS OF FDB
	ADDI T1,DIRORG		; GET ABS ADR OF FDB
	LOAD T2,FBNAM,(T1)	; GET POINTER TO NAME STRING
	ADDI T2,DIRORG+1		; GET ABS ADR OF START OF STRING
	HRROM T2,DEFNAM
	PUSH P,T4		; SAVE POINTER TO SYMBOL TABLE
	LOAD T4,SYMAD,(T3)	; GET RELATIVE ADR OF FDB FROM SYMBOL TABLE
	CALL SCAN3		; GO DO NAME CHAIN
	POP P,T4		; GET BACK INDEX INTO SYMBOL TABLE
SCAN2A:	JRST SCAN1		; LOOP BACK FOR ALL SYMBOLS
;MAP ONE DIRECTORY INTO THIS FORK

;	T1/DIRECTORY NUMBER

SETFD:	PUSH P,T1		;SAVE DIRNUM
	CALL GTFILE		;GET JFN ON DIRECTORY FILE
	HRRZ T1,FDJFN		;OPEN THE DIRECTORY FILE
	MOVE T2,[440000,,OF%RD+OF%THW]
	OPENF
	 JRST [	TMSG <OPENF failed on directory >
		HRROI T1,DIRNAM	;T1/POINTER TO DIRECTORY NAME
		PSOUT		;PRINT DIRECTORY
		TMSG< - Skipped>
		JSERR		;OPEN FAILET4, GO TYPE OUT ERROR
		POP P,T1	;RESTORE DIRECTORY NUMBER
		RET]
	HRLZ T1,FDJFN		;NOW MAP IN DIRECTORY
	MOVE T2,[.FHSLF,,DIRORG/1000]
	MOVE T3,[PM%CNT+PM%RD+NDIRPG]
	PMAP
	POP P,T1		;GET BACK DIR #
	CALL DR0CHK		;CHECK CONSISTENCY OF HEADER
	 JRST [	CALL UNMAPD	;BAD HEADER. UNMAP THE DIRECTORY
	 	CALLRET BADBLK]	;HEADER IS BAD
	RETSKP

;ROUTINE TO UNMAP A DIRECTORY

UNMAPD:	SETO T1,			;PMAP -1 TO DIRORG
	MOVE T2,[.FHSLF,,DIRORG/1000]
	MOVE T3,[PM%CNT+PM%RD+NDIRPG]
	PMAP			;UNMAPPED!
	HRRZ T1,FDJFN		;T1/ JFN
	CLOSF			;CLOSE THIS FILE
	 JFCL
	RET			;AND EXIT
;GTFILE - GET FILE NAME FOR THIS DIRECTORY AND GET A JFN ON IT

;ASSUMES DIRNAM POINTS TO STR:<DIRECTORY>

;	CALL GTFILE

;RETURN +1: ALWAYS
;		FDJFN/ JFN FOR DIRECTORY FILE

GTFILE:	MOVE T1,[POINT 7,DIRNAM] ;POINT TO STR:<DIRECTORY>
	SETZM DOTPTR		;INDICATE DOT NOT FOUND YET
	SETZM BRKPTR		;INDICATE BRACKET NOT FOUND YET
GTFIL1:	ILDB T2,T1		;GET NEXT CHARACTER IN STRING
	CAIN T2,"<"		;LEFT BRACKET?
	JRST [	MOVEM T1,BRKPTR	;YES. SAVE ITS POINTER
		JRST GTFIL1]	;GO GET NEXT CHARACTER
	CAIN T2,"."		;IS IT A DOT?
	JRST [	MOVEM T1,DOTPTR	;YES. SAVE ITS POINTER
		JRST GTFIL1]	;GO GET NEXT CHARACTER
	CAIE T2,">"		;IS IT A RIGHT BRACKET?
	JRST GTFIL1		;NO. GO GET NEXT CHARACTER
	SKIPN DOTPTR		;FOUND RIGHT BRACKET. HAVE WE SEEN A DOT?
	JRST GTFIL2		;NO. MUST BE IN <ROOT-DIRECTORY>

;HERE WHEN THIS IS A SUBDIRECTORY.  ;WE HAVE STR:<DIRECTORY.SUBDIRECTORY>.
;CONVERT TO STR:<DIRECTORY>SUBDIRECTORY.DIRECTORY

	DPB T2,DOTPTR		;REPLACE DOT WITH RIGHT BRACKET
	MOVEI T2,"."		;GET A DOT
	DPB T2,T1		;REPLACE RIGHT BRACKET WITH DOT
	HRROI T2,[ASCIZ/DIRECTORY/] ;T2/ SOURCE IS THIS STRING
	SETZ T3,		;T3/ STOP ON NULL
	SOUT			;FORM STR:<DIR>SUBDIR.DIRECTORY
	HRROI T2,DIRNAM		;SET UP POINTER TO DIRECTORY
	JRST GTFIL3		;GO GET JFN

;HERE WHEN DIRECTORY IS IN ROOT-DIRECTORY. FORM STR:<ROOT-DIRECTORY>DIR.DIRECTORY

GTFIL2:	MOVE T1,ROOTPT		;POINT TO END OF STR:<ROOT-DIRECTORY>
	MOVE T2,BRKPTR		;POINT TO LEFT BRACKET
	MOVEI T3,^D40		;DIRECTORY NAME <=39 CHARACTERS
	MOVEI T4,">"		;STOP ON RIGHT BRACKET
	SOUT			;COPY DIRECTORY NAME
	SETOM T3		;BACK UP POINTER OVER THE BRACKET
	IBP T3,T1
	MOVEM T3,T1		;T1/ DESTINATION IS END OF DIRECTORY NAME
	HRROI T2,[ASCIZ/.DIRECTORY/] ;T2/ POINTER TO SOURCE
	SETZ T3,		;T3/ STOP ON NULL
	SOUT			;COPY ".DIRECTORY" TO END OF STRING
	HRROI T2,ROOTDR		;POINT TO START OF THIS STRING
	JRST GTFIL3		;GO GET JFN

;T2 POINTS TO FILE SPEC. GET A JFN ON THIS DIRECTORY FILE

GTFIL3:	MOVX T1,GJ%PHY!GJ%SHT	;PHYSICAL ONLY, SHORT BLOCK
	GTJFN			;GET A JFN
	 JSHLT			;FAILURE
	HRRZM T1,FDJFN		;SAVE JFN
	RET
;DO ONE NAME. STARTS WITH FDB FOR ONE NAME.  CALLS SCAN7 TO DO ALL GENERATIONS FOR
;ONE EXTENSION.  LOOPS THROUGH ALL EXTENSIONS FOR ONE NAME

;	T4/OFFSET IN DIRECTORY OF FDB

SCAN3:	SKIPN T4
	RET
	ADDI T4,DIRORG		; GET ABS ADR OF FDB
	MOVE T1,T4

;NOTE: REPEATED BELOW

	CALL FDBCHK		; MAKE SURE THIS IS A GOOD FDB
	 CALLRET BADBLK		; IT IS NOT
	LOAD T1,FBEXT,(T4)	; GET ADR OF EXT STRING
	ADDI T1,DIRORG+1
	HRROM T1,DEFEXT
	PUSH P,T4
	SUB T4,DIRORA		; GET RELATIVE ADR OF FDB
	CALL SCAN7
	POP P,T4
	LOAD T4,FBEXL,(T4)	; STEP TO NEXT EXT
	JRST SCAN3

;DO ONE EXTENSION. CALLS BUILD FOR ONE FDB.  LOOPS THROUGH ALL VERSIONS.

;	T4/OFFSET IN DIRECTORY OF FDB

SCAN7:	SKIPN T4
	RET
	ADDI T4,DIRORG		; GET ABS ADR OF FDB
	MOVE T1,T4
	CALL FDBCHK		; CHECK THE QUALITY OF THIS FDB
	 CALLRET BADBLK		; NO GOOD
	LOAD T1,FBGEN,(T4)	; GET VERSION #
	HRRM T1,DEFVER
	PUSH P,T4
	CALL BUILD		; DO ONE VERSION
	POP P,T4
	LOAD T4,FBGNL,(T4)	; STEP TO NEXT GENERATION FDB
	JRST SCAN7

;BADBLK - PRINT MESSAGE ABOUT BAD BLOCK IN DIRECTORY

BADBLK:	TMSG < in directory >
	HRROI T1,DIRNAM		;T1/POINTER TO DIRECTORY NAME
	PSOUT			;PRINT DIRECTORY NAME
	MOVEI T1,.CHLFD		;T1/LINE FEED
	PBOUT			;PRINT A LINE FEED
	RET
;ROUTINE CALLED FOR EACH FILE--FIND ALL ADDRESSES IN PT'S OF FILE

;	T4/ADDRESS OF FDB

BUILD:	STKVAR<DSKAD1,FDBCNT,PAGNO>
	SKIPN CHKFLF		;RETURN IMMED IF NOT CHECKING FILES
	RET
	SKIPE T1,.FBADR(T4)	;GET DISK ADDRESS OF INDEX BLOCK
	TLNE T1,(FILNB)		;IS IT A NEW FILE?
	RET			; NO DISC ADDRESS
	SETZM ZSTART		;CLEAR COUNTS OF ERRORS
	MOVE T2,[XWD ZSTART,ZSTART+1]
	BLT T2,ZEND
	SETZM PAGCNT		;INIT COUNT OF FILE PAGES FOR THIS FILE
	LOAD T3,FBNPG,(T4)	;GET COUNT IN FDB OF FILE PAGES
	MOVEM T3,FDBCNT		;SAVE IT FOR CHECKING LATER
	SETOM PAGNN		;INDICATE NOT IN FILE PAGE
	MOVE T3,.FBCTL(T4)	;GET FLAGS IN FDB
	TXNE T3,FB%LNG		;IS THIS A LONG FILE?
	JRST BUILNG		;YES. GO DO THE PAGE TABLE TABLE
	MOVX F,MR%PT		;INDICATE THIS IS PAGE TABLE
	CALL MRKBTB		;MARK BIT TABLE TO SHOW PAGE USED BY 
				; INDEX BLOCK
	JRST [	AOS NDE		;FAILED. INDICATE BAD ADDRESS FOR PAGE TABLE
		JRST BUILD1]
	SETZM PAGNN		;INITIALIZE FILE PAGE NUMBER
	CALL MRKPT		;MARK BIT TABLE TO SHOW PAGES POINTED
				; TO BY THE PAGE TABLE
	JRST BUILD1		;GO PRINT ERRORS IF ANY
;SCAN LONG FILE
;	T1/DISK ADDRESS OF PAGE TABLE TABLE

BUILNG:	MOVEM T1,DSKAD1		;SAVE ADDRESS OF PAGE TABLE TABLE
	MOVX F,MR%PTT 		;INDICATE THIS IS A PAGE TABLE TABLE
	CALL MRKBTB		;MARK BIT TABLE TO SHOW PAGE USED BY
				; PAGE TABLE TABLE
	 JRST [	AOS NPTTE	;INDICATE BAD ADDRESS FOR PAGE TABLE TABLE
		JRST BUILD1]	;GIVE UP ON THIS FILE
	MOVEI T2,PTT		;T2/WHERE TO READ PAGE TABLE TABLE INTO
	CALL DSKRED		;READ THE PAGE TABLE TABLE
	JRST [	AOS NBPTT	;INDICATE PAGE TABLE TABLE UNREADABLE
		AOS NBAD	;INCREMENT COUNT OF ALL ERRORS
		JRST BUILD1]	;GIVE UP ON THIS FILE
	MOVEI T1,PTT		;T1/ADDRESS OF WHERE TO LOOK FOR PTT
	CALL CHKCSM		;CHECK/RESET CHECKSUM
	 JRST [	AOS NBPTT	;NO GOOD
		AOS NBAD
		JRST BUILD1]
	SETZM PAGNN		;INITIALIZE COUNT OF FILE PAGES
	MOVSI P1,-1000		;P1/(-COUNT,,OFFSET IN PAGE TABLE TABLE)


;LOOP THROUGH ENTRIES IN PAGE TABLE TABLE MARKING BIT TABLE FOR PAGE USED
;BY PAGE TABLE AND PAGES USED BY FILE AS INDICATED BY PAGE TABLE

BUILN1:	MOVE T1,PTT(P1)		;GET DISK ADDRESS OF NEXT PAGE TABLE
	TLZ T1,(ADRMSK)		;GET STORAGE ADR
	JUMPE T1,[MOVEI T1,1000	;INCREMENT COUNT OF PAGES BY
		ADDM T1,PAGNN	; SIZE OF PAGE TABLE
		JRST BUILN2]	;GO TO NEXT ENTRY IN PAGE TABLE TABLE
	MOVEM T1,PTT(P1)
	MOVE T2,PAGNN		;SAVE CURRENT FILE PAGE NUMBER
	MOVEM T2,PAGNO
	SETOM PAGNN		;INDICATE IN PAGE TABLE
	MOVX F,MR%PT		;INDICATE THIS IS A PAGE TABLE
	CALL MRKBTB		;MARK BIT TABLE TO SHOW PAGE USED BY PAGE TABLE
	JRST [	AOS NBPTTE	;INDICATE BAD ADDRESS IN PAGE TABLE TABLE
		MOVE T2,PAGNO	;RESTORE FILE PAGE NUMBER
		MOVEM T2,PAGNN
		JRST BUILN2]	;GO TO NEXT ENTRY IN PTT
	MOVE T2,PAGNO		;RESTORE FILE PAGE NUMBER
	MOVEM T2,PAGNN
	CALL MRKPT		;MARK BIT TABLE TO SHOW PAGES POINTED
				; TO BY PAGE TABLE
BUILN2:	SKIPN NIDA		;QUIT IMMED IF SEEN ILLEG ADDRESSES
	AOBJN P1,BUILN1		;GO TO NEXT ENTRY IN PAGE TABLE TABLE

;PAGE TABLE TABLE IS DONE

	JRST BUILD1
;HERE WHEN ALL PAGES FOR A FILE HAVE BEEN ASSIGNED AND ERROR COUNTS
;INCREMENTED.  FIX PAGE COUNT IF NEEDED AND REPORT SUMMARY OF ERRORS 
;IF ANY.

BUILD1:	MOVE T2,PAGCNT		;GET LOCAL COUNT OF FILE PAGES
	ADDM T2,TOTPGS		;INCREMENT TOTAL FOR ALL FILES
	SKIPG T1,NBAD		;DID WE GET ANY ERRORS ON THIS FILE?
	JRST [	SKIPE DALIST	;NO. ARE WE SEARCHING?
		RET		;YES. DON'T FIX THE PAGE COUNT
		CAME T2,FDBCNT	;DOES LOCAL COUNT AGREE WITH THE FDB?
		CALL FIXCNT	;NO. FIX IT IN THE FDB
		RET]

;PRINT SUMMARY OF ERRORS FOR THIS FILE

	TMSG <Summary for file >
	CALL PNTFIL		;PRINT THE FILE SPEC
	MOVEI T1,.CHLFD
	PBOUT			;PRINT LINE FEED

;THE COUNTS THAT ARE REPORTED HERE HAVE BEEN INCREMENTED BY MRKPT,
;MRKBTB AND BUILD.  THEY WERE CLEARED BY THE BLT IN BUILD AND THUS
;CONTAIN THE ERROR COUNTS FOR THE CURRENT FILE ONLY.

	MOVE T3,[XWD 4,12]
	SKIPN T2,NDE
	JRST BAD0
	CALL TTNOUT
	TMSG < Faulty page table addresses in FDB
>
BAD0:	SKIPN T2,NPTTE	
	JRST BAD0A
	MOVE T3,[4,,12]
	CALL TTNOUT
	TMSG <Faulty long file page table addresses in FDB
>
	;..
	;..
BAD0A:	MOVE T3,[XWD 4,12]
	SKIPN T2,NBPTE
	JRST BAD1
	CALL TTNOUT
	TMSG < Faulty addresses in page table
>
BAD1:	SKIPN T2,NBPT
	JRST BAD2
	MOVE T3,[XWD 4,12]
	CALL TTNOUT
	TMSG < Page tables unreadable
>
BAD2:	SKIPN T2,NBPTTE
	JRST BAD2A
	MOVE T3,[XWD 4,12]
	CALL TTNOUT
	TMSG < Faulty addresses in long file page table
>
BAD2A:	SKIPN T2,NBPTT
	JRST BAD3
	MOVE T3,[XWD 4,12]
	CALL TTNOUT
	TMSG < Long file page tables unreadable
>
BAD3:	SKIPN T2,NIDA
	JRST BAD4
	MOVE T3,[XWD 4,12]
	CALL TTNOUT
	TMSG < Illegal addresses
>
BAD4:	SKIPN T2,NMDA
	JRST BAD5
	MOVE T3,[XWD 4,12]
	CALL TTNOUT
	TMSG < Multiply assigned addresses
>
BAD5:	SKIPN T2,NSDA
	 JRST BAD6
	MOVE T3,[XWD 4,12]
	CALL TTNOUT
	TMSG < Search addresses found
>
	;..
	;..
BAD6:	SKIPN T2,NDSKER		;DISK ERRORS?
	JRST BAD7		;NO
	MOVE T3,[4,,12]
	CALL TTNOUT
	TMSG < Disk read errors
>
BAD7:	SKIPN T2,NNBT		;PAGES ASSIGNED TO FILES BUT NOT IN BIT TABLE?
	JRST BAD8		;NO
	MOVE T3,[4,,12]
	CALL TTNOUT
	TMSG < File addresses not in bit table
>

BAD8:	SKIPN T2,NABAT		;ANY ASSIGNED PAGES THAT ARE BAD?
	JRST BAD9		;NO.
	MOVE T3,[4,,12]
	CALL TTNOUT		;OUTPUT DISK ADDRESS
	TMSG < Assigned pages marked in BAT blocks
>

BAD9:	TMSG <- - - - - - -
>
	RET
;PNTFIL - PRINT FILE SPEC

PNTFIL:	HRROI T1,DIRNAM
	PSOUT			;PRINT STR:<DIRECTORY>
	MOVE T1,DEFNAM
	PSOUT			;PRINT THE FILE NAME
	MOVEI T1,"."
	PBOUT
	MOVE T1,DEFEXT
	PSOUT			;PRINT EXTENSION
	MOVEI T1,"."
	PBOUT
	HRRZ T2,DEFVER
	MOVEI T1,.PRIOUT
	MOVEI T3,^D10
	NOUT			;PRINT VERSION
	 JFCL
	RET
;MRKPT - MARK THE BIT TABLE FOR ONE PAGE TABLE

;ACCEPTS:
;	T1/DISK ADDRESS OF INDEX BLOCK
;	F/MR%PT (PASSED TO MRKBTB)

;RETURNS +1:ALWAYS

;THIS ROUTINE IS CALLED DURING THE BITTABLE, REBUILD, AND SCAN FUNCTIONS.
;GIVEN THE DISK ADDRESS OF A PAGE TABLE (INDEX BLOCK), IT READS THE
;PAGE TABLE AND SCANS THE ADDRESSES IN IT.  FOR EACH NON-ZERO ADDRESS
;IT CALLS MRKBTB TO ASSIGN THE PAGE POINTED TO BY THE ADDRESS

MRKPT:	PUSH P,T1
	MOVEI T2,PT		;T2/STARTING ADDRESS TO READ INTO
	CALL DSKRED		;READ INDEX BLOCK
	JRST [	AOS NBPT	;INCREMENT COUNT OF UNREADABLE PAGE TABLES
		AOS NBAD	;INCREMENT TOTAL COUNT OF ERRORS
		POP P,T1	;RESTORE DISK ADDRESS
		RET]		;IGNORE THIS PAGE TABLE
	MOVEI T1,PT		;T1/ADDRESS OF PAGE TABLE
	CALL CHKCSM		;CHECK/RESET CHECKSUM
	 JRST [	AOS NBPT	;INCREMENT COUNT OF UNREADABLE PAGE TABLES
		AOS NBAD	;INCREMENT TOTAL COUNT OF ERRORS
		POP P,T1	;RESTORE DISK ADDRESS
		RET]		;IGNORE THIS PAGE TABLE

;LOOP THROUGH WORDS IN PAGE TABLE

	MOVSI P2,-1000		;P2/(-COUNT,,OFFSET INTO PT)
MRKPT1:	MOVE T1,PT(P2)		;GET NEXT ADDRESS FROM PAGE TABLE
	TLZ T1,(ADRMSK)		;GET STORAGE ADR
	JUMPE T1,MRKPT2		;SKIP IF ZERO
	MOVEM T1,PT(P2)		;SAVE ADDRESS OF PAGE IN FILE
	CALL MRKBTB		;ASSIGN PAGE IN BOTH BIT TABLES
	 AOS NBPTE		;FAILED. INCREMENT COUNT OF BAD ADDRESSES IN PT
MRKPT2:	AOS PAGNN		;POINT TO NEXT FILE  PAGE
	SKIPN NIDA		;QUIT IMMED IF SEEN ILLEG ADDRESSES
	AOBJN P2,MRKPT1		;GO TO NEXT ENTRY

;END OF PAGE TABLE

	POP P,T1		;RESTORE ADDRESS OF INDEX BLOCK
	RET
;MRKBTB - MARK THE BIT TABLE FOR ONE PAGE

;ACCEPTS:
;	T1/DISK ADDRESS TO MARK IN BIT TABLE
;	F/FLAG INDICATING WHAT CALLED THIS ROUTINE (MEANINGFUL ONLY IF
;	  PAGNN IS NEGATIVE)

;RETURNS +1:DISK ADDRESS BAD
;		1/DISK ADDRESS WITH BITS 0-14 TURNED OFF
;	  +2:DISK ADDRESS GOOD
;		1/DISK ADDRESS WITH BITS 0-14 TURNED OFF

;THIS ROUTINE IS CALLED DURING THE BITTABLE, REBUILD, AND SCAN FUNCTIONS
;WHEN A PAGE HAS BEEN IDENTIFIED AS IN USE (FILE PAGE, SWAP PAGE, ETC.)
;ACTION DEPENDS ON FUNCTION:
;SCAN - SEE IF THIS ADDRESS IS BEING SEARCHED FOR 
;BITTABLE - ASSIGN PAGE IN LOCAL BIT TABLE
;REBUILD - ASSIGN PAGE IN LOCAL AND SYSTEM BIT TABLE
;THIS ROUTINE PRINTS ONE-LINE MESSAGES THAT CONTAIN THE DISK ADDRESS AND
;DESCRIPTION OF HOW THE PAGE IS USED

MRKBTB:	TLZ T1,(DSKMSK)
	SAVET
	STKVAR <ASAVE>
	MOVEM T1,ASAVE		;SAVE DISK ADDRESS
	SKIPGE PAGNN		;FILE PAGE?
	JRST [	AOS OVERHD	;NO. COUNT AS OVERHEAD
		JRST MRKBT5]
	AOS PAGCNT		;YES. COUNT AS FILE PAGE
MRKBT5:	CALL SEEADR		;SEE IF ADDRESS IS MARKED IN BAT BLOCKS
	 JRST [	MOVX T4,ER%BAT	;INDICATE THIS IS A BAD BLOCK
		SOS OVERHD	;PREVIOUSLY COUNTED AS OVERHEAD. PAGE
				; IS IN USE
		SOS BATCNT	;DECREMENT COUNT OF UNUSED BAD PAGES
		JRST BATA]	;GO REPORT IT

MRKBT4:	SKIPN T2,DALIST		;AOBJN POINTER TO LIST OF ADDRESSES INPUT
				; VIA SCAN COMMAND
	 JRST MRKBT1		;NOT SCANNING FOR DISK ADDRESSES

;SCANNING FOR ADDRESSES CONTAINED IN DATAB LIST.  SEE IF THIS ADDRESS
;IS IN THE LIST.

	CAMN T1,DATAB(T2)
	 JRST SDA		; ADDRESS IS BEING SEARCHED
	AOBJN T2,.+1
	AOBJN T2,.-3
	RETSKP			;NOT IN THE LIST. DON'T TRY TO MARK BIT TABLE

;DOING BIT TABLE CONSISTENCY CHECK. ASSIGN THIS PAGE IN BOTH BIT TABLES
;T1/SECTOR NUMBER RELATIVE TO START OF STRUCTURE

MRKBT1:	CALL DSKASA		;ASSIGN IN LOCAL BIT TABLE
	 JRST [	TXNE T4,ER%IDA	;FAILED.  ILLEGAL ADDRESS?
		JRST IDA	;YES. GO REPORT ERROR
		TXNE T4,ER%MDA	;NO. PAGE NOT AVAILABLE?
		JRST MDA	;YES. GO REPORT ERROR
		TMSG <
% DSKASA returned unknown error
>
		JRST .+1]
	MOVE T1,ASAVE		;T1/SECTOR NUMBER
	MOVE T2,STRDEV		;T2/STRUCTURE 0
	DSKAS			;TRY TO ASSIGN THE PAGE
	 RETSKP			;FAILED. GOOD.

;TRIED TO ASSIGN PAGE IN SYSTEM BIT TABLE AND SUCCEEDED.  THIS IS AN
;ERROR  BECAUSE SYSTEM SHOULD HAVE KNOWN ABOUT THE FILE PAGE

	SKIPE REBLDF		;IF REBUILDING, BIT TABLE HAS BEEN INITIALIZED
	RETSKP			; SO IGNORE
	;..
	;..
;ERROR CONDITIONS.  T4 CONTAINS ERROR FLAG.  IF ERROR WAS ILLEGAL ADDRESS
;OR MULTIPLY ASSIGNED, TAKE NON-SKIP RETURN SO CALLER CAN INCREMENT COUNT
;OF FAULTY ADDRESSES.  IF ADDRESS IS MARKED IN BAT BLOCKS, CONTINUE
;AS IF NOTHING HAD HAPPENED.

;PAGE IS NOT ASSIGNED IN SYSTEM BIT TABLE

	TMSG <Disk address >
	MOVE T2,ASAVE		;T2/SECTOR NUMBER
	MOVEI T3,10		;T3/RADIX
	CALL TTNOUT		;PRINT THE SECTOR NUMBER
	TMSG < not in bit table >
	SETZ T4,		;INDICATE NOT AN ERROR TO AVOID FAILURE RETURN
	AOS NNBT		;INCREMENT COUNT OF NOT IN BT'S
	JRST MRKBTP

;DISK ADDRESS IS INVALID

IDA:	TMSG <Illegal disk address >
	MOVE T2,ASAVE		;T2/SECTOR NUMBER
	MOVEI T3,10
	CALL TTNOUT
	AOS NIDA		;INCREMENT COUNT OF ILLEGAL ADDRESS
	SETZM WRTLPF		;SUPPRESS LOST-PAGES FILE, ETC.
	JRST MRKBTP

;THIS ADDRESS IS BEING SEARCHED FOR VIA SCAN COMMAND. 

SDA:	TMSG <Found disk address >
	MOVE T2,DATAB+1(T2)
	MOVEI T3,10
	CALL TTNOUT
	SETZ T4,		;INDICATE NOT AN ERROR TO AVOID NON-SKIP RETURN
	AOS NSDA		;INCREMENT THE COUNT OF ADDRESSES FOUND
	JRST MRKBTP

;PAGE WAS ALREADY ASSIGNED.

MDA:	TMSG <Multiply assigned disk address >
	MOVE T2,ASAVE		;T2/SECTOR NUMBER
	MOVEI T3,10
	CALL TTNOUT
	AOS NMDA		;INCREMENT COUNT OF MULTIPLY ASSIGNED ADDRESSES
	SETZM WRTLPF		;SUPPRESS LOST-PAGES FILE, ETC.
	JRST MRKBTP

;THIS DISK ADDRESS IS RECORDED IN THE BAT BLOCKS.

BATA:	TMSG <Disk address >
	MOVE T2,ASAVE		;GET SECTOR NUMBER
	MOVEI T3,10		;T3/OCTAL
	CALL TTNOUT		;PRINT THE ADDRESS
	TMSG < marked in BAT blocks>
	AOS NABAT		;INCREMENT COUNT OF BAD ADDRESSES
	JRST MRKBTP		;GO PRINT THE FILE PAGE

;PRINT FILE PAGE WHERE ERROR OCCURRED

MRKBTP:	AOS NBAD		;INCREMENT COUNT OF TOTAL ERRORS
	SKIPGE T2,PAGNN		;GET PAGE NUMBER
	JRST MRKBT2		;NEGATIVE MEANS NOT A FILE PAGE
	TMSG <: File page >
	MOVEI T3,10		;T3/RADIX
	CALL TTNOUT		;PRINT PAGE NUMBER
	JRST MRKBT3

;NOT A FILE PAGE. F INDICATES WHAT IT IS.

MRKBT2:	TXNE F,MR%PT		;IS THIS A PAGE TABLE?
	JRST [	TMSG <: Page table> ;PAGE TABLE
		JRST MRKBT3]
	TXNE F,MR%PTT		;NO. IS IT A PAGE TABLE TABLE?
	JRST [	TMSG <: Long file page table>
		JRST MRKBT3]	;PAGE TABLE TABLE
	TXNE F,MR%SWP		;NO. IS IT SWAPPING SPACE?
	JRST [	TMSG <: Swapping space>
		JRST MRKBT3]
	TXNE F,MR%SPC		;NO. IS IT A SPECIAL BLOCK?
	JRST [	TMSG <: Special system blocks>
		JRST MRKBT3]

MRKBT3:	TMSG <
>
	JUMPE T4,RSKP		;IF NOT REALLY AN ERROR, TAKE SKIP RETURN
	TXNN T4,ER%BAT		;WAS IT A BAD ADDRESS
	RET			;NO. TAKE ERROR RETURN
	MOVE T1,ASAVE		;RESTORE SECTOR NUMBER
	JRST MRKBT4		;GO CONTINUE
;FIXCNT - FIX THE COUNT OF FILE PAGES FOR ONE FILE

;ACCEPTS:
;	NOTHING IN AC'S, BUT DIRNAM,DEFNAM,DEFEXT,DEFVER MUST BE SET UP

;RETURNS +1:ALWAYS

;CALLED BY BUILD WHEN A FILE'S PAGE COUNT IN THE FDB DISAGREES WITH
;LOCAL COUNT OF DATA PAGES.  DOES OPENF AND CLOSF TO FORCE THE UPDATE.
;NOTE THAT THE COUNT WILL NOT BE UPDATED IF ANYONE ELSE HAS THE FILE OPEN
;UNTIL THE LAST CLOSE OCCURS.  IN THE CASE OF ROOT-DIRECTORY.DIRECTORY
;AND SOME OTHERS THAT ARE NEVER CLOSED, THE COUNT WILL NOT BE UPDATED

FIXCNT:	STKVAR<JFN1>
	MOVEI T1,GTJBLK		;T1/ ADDRESS OF GTJFN BLOCK
	MOVX T2,GJ%OLD!GJ%PHY	;OLD FILE
	HRR T2,DEFVER		;VERSION NUMBER OF THIS FILE
	MOVEM T2,.GJGEN(T1)	;(FLAGS,,VERSION NUMBER)
	MOVE T2,[.NULIO,,.NULIO] ;NULL DEVICE FOR INPUT AND OUTPUT
	MOVEM T2,.GJSRC(T1)	;(INPUT JFN,,OUTPUT JFN)
	SETZM .GJDEV(T1)		;NO DEFAULT DEVICE
	SETZM .GJDIR(T1)		;NO DEFAULT DIRECTORY
	MOVE T2,DEFNAM		;POINTER TO CURRENT FILENAME
	MOVEM T2,.GJNAM(T1)	;MAKE THIS THE DEFAULT
	MOVE T2,DEFEXT		;POINTER TO CURRENT EXTENSION
	MOVEM T2,.GJEXT(T1)	;MAKE THIS THE DEFAULT
	SETZM .GJPRO(T1)		;NO DEFAULT PROTECTION
	SETZM .GJACT(T1)		;NO DEFAULT ACCOUNT STRING
	SETZM .GJJFN(T1)		;NO SPECIFIC JFN
	HRROI T2,DIRNAM		;T2/ STR:<DIRECTORY>
	GTJFN			;GET A JFN ON THE CURRENT FILE
	 JRST [	PNTERR (<Unable to fix count for file>,FIXCN1,FILE)]
	HRRZS T1		;T1/JFN WITHOUT FLAGS
	MOVEM T1,JFN1		;SAVE IT
	MOVX T2,OF%RD!OF%PDT	;T2/READ ACCESS, DON'T CHANGE ACCESS DATE
	OPENF			;OPEN THE FILE
	 JRST [	MOVE T1,JFN1	;FAILED. T1/JFN
		TXO T2,OF%THW!OF%RD!OF%PDT ;T2/THAWED, READ, DON'T CHANGE DATE
		OPENF		;OPEN IT THAWED THIS TIME
		 JRST [	PNTERR (<Unable to fix count for file>,FIXCN1,FILE)]
		JRST .+1]	;SUCCEEDED
	MOVE T1,JFN1		;T1/JFN
	MOVEI T4,.FBBYV		;OFFSET TO BE CHANGED
	STOR T4,CF%DSP,T1	;SAVE IT IN T1
	MOVX T2,FB%PGC		;T2/MASK FOR PAGE COUNT FIELD
	MOVE T3,PAGCNT		;T3/NEW PAGE COUNT TO BE STORED
	CHFDB			;PUT CORRECT PAGE COUNT IN FDB
	 ERJMP [PNTERR (<Unable to fix count for file>,,FILE)
		JRST .+1]
	MOVE T1,JFN1		;T1/JFN
	CLOSF			;CLOSE THE FILE
	 JFCL			;IGNORE FAILURE
FIXCN1:	RET
;CHECK CHECKSUM IF NEW FORMAT XB'S
; T1/ LOCATION OF XB

CHKCSM:	PUSH P,Q1
	PUSH P,T1		;SAVE XB LOCATION
	HRRZ T2,T1
	ADD T2,[XBCKSM]		;GET EXISTING CHECKSUM FROM XB
	MOVEI T1,Q1		;PUT IT INTO Q1
	CALL LDXBD
	MOVE T1,0(P)
	CALL DOCSM		;COMPUTE CHECKSUM
	SETCA Q1,		;SUBTRACT CHECKSUMS (1'S COMPL)
	ADD T1,Q1
	POP P,0(P)
	POP P,Q1
	CAME T1,[-1]		;0? (OR -0)
	JUMPN T1,[TMSG <	Checksum incorrect
>
		RET]
	JRST RSKP
;COMPUTE CHECKSUM
; T1/ ADDRESS OF PT

DOCSM:	MOVSI T4,-1000
	SETZ T3,			;COMPUTE CHECKSUM IN C
	HRLI T1,T4		; T1 = 0(T4)
	JCRY0 .+1
DOCSM1:	MOVE T2,@T1
	TLZ T2,(ADRMSK)		;LOOK ONLY AT ADDRESS PART OF WORD
	SKIPN T2		;EMPTY?
	HRRZ T2,T4		;YES, USE INDEX IN CHECKSUM
	ADD T3,T2
	JCRY0 [AOJA T3,.+1]	;DO END-AROUND CARRY
	AOBJN T4,DOCSM1
	MOVE T1,T3		;RETURN CHECKSUM IN T1
	RET
;LOAD/STORE DATA IN INDEX BLOCK.
;SINCE THE STORAGE ADDRESS IS ONLY 23 BITS, THE REMAINING PORTION
;OF EACH WORD CAN BE USED TO STORE USEFUL INFORMATION, E.G. A
;CHECKSUM OF THE INDEX BLOCK.  THESE ROUTINES PACK AND UNPACK
;THE DATA FROM THE XB USING B0-8 OF SUCCESSIVE WORDS.

; T1/ ADDRESS OF WORD(S)
; T2/ NUMBER OF XB WORDS,,XB ADDRESS + OFFSET
;	CALL STXBD/LDXBD
; RETURN +1 ALWAYS, DATA MOVED BETWEEN XB AND C(C(T1))

;STORE DATA INTO INDEX BLOCK

STXBD:	HRLI T1,(<POINT 9,0>)	;INIT PTR TO CALLERS DATA
STXBD1:	ILDB T3,T1		;GET BYTE FROM CALLER
	DPB T3,[POINT 9,0(T2),8]	;PUT IT IN XB
	AOBJN T2,STXBD1		;INCREMENT THROUGH XB
	RET

;LOAD FROM XB

LDXBD:	HRLI T1,(<POINT 9,0>)	;INIT PTR TO CALLERS STORAGE
LDXBD1:	LDB T3,[POINT 9,0(T2),8]	;GET BYTE FROM XB
	IDPB T3,T1		;PUT IT IN CALLERS STORAGE
	AOBJN T2,LDXBD1		;SCAN THROUGH XB
	RET

;ITEMS IN INDEX BLOCK VECTOR

XBCKSM==<-4,,0>			;CHECKSUM--4 WORDS BEGINNING AT 0
DSKRED:	PUSH P,T1
	MOVE T3,T2
	TLZ T1,(DSKMSK)
	MOVE T4,STRDEV		;GET STRUCTURE NUMBER
	TXO T1,DOP%SN		;SET TO ALL ONES
	TXO T1,<FLD .DOPSR,DOP%AT>
	MOVEI T2,1000		;WORD COUNT
	DSKOP
	SKIPE T1
	AOSA NDSKER		;DSK READ ERR
	AOS -1(P)
	POP P,T1
	MOVE T2,T3
	RET

DSKWRT:	PUSH P,T1
	MOVE T3,T2
	TLZ T1,(DSKMSK)
	TXO T1,<FLD .DOPSR,DOP%AT>
	MOVE T4,STRDEV		;GET STRUCTURE NUMBER
	TXO T1,DOP%SN		;SET TO -1
	MOVX T2,DOP%WR+1000
	DSKOP
	SKIPE T1
	JRST [	AOS NDSKER
		TMSG <Disk write error
>
		JRST .+1]
	POP P,T1
	MOVE T2,T3
	RET
;FINBTB - CALLED WHEN DONE.  PRINTS COUNTS OF FREE AND USED PAGES 
;BEFORE AND AFTER THE ASSIGNMENTS

FINBTB:	TMSG <
Local count of file pages: >
	MOVE T2,TOTPGS		;GET COUNT OF FILE PAGES
	MOVEI T3,12		;DECIMAL RADIX
	CALL TTNOUT
	TMSG <
Local count of overhead pages: >
	MOVE T2,OVERHD		;GET COUNT OF OVERHEAD PAGES
	MOVEI T3,12		;DECIMAL RADIX
	CALL TTNOUT		;PRINT THE COUNT
	TMSG <
Local count of used pages: >
	MOVE P1,LOTRK
	SUB P1,HITRK
	HRLZS P1
	HRR P1,LOTRK		;LOTRK-HITRK ,, LOTRK
	SETZ T2,
	ADD T2,LOCBTB(P1)	;COUNT FREE PAGES FOR CYLINDER
	AOBJN P1,.-1
	MOVNS T2		;NEGATIVE OF TOTAL FREE
	MOVE T3,HITRK
	IMUL T3,PAGCYL		;GET TOTAL PAGES
	ADD T2,T3		;TOTAL USED
	ADD T2,BATCNT		;ADD PAGES THAT ARE MARKED BAD BUT NOT
				; USED BY A FILE
	MOVEI T3,12
	CALL TTNOUT		;PRINT LOCAL COUNT OF USED PAGES
	TMSG <
>
	SKIPE REBLDF		;REBUILDING BIT TABLE?
	JRST FINBT1		;YES. NEXT COUNT IS MEANINGLESS
	TMSG<
System count before CHECKD: >
	MOVE T2,ZUSED		;SYSTEM'S COUNT OF USED AT BEGINNING
	MOVEI T3,12
	CALL TTNOUT		;PRINT ORIGINAL COUNT
FINBT1:	TMSG <
System count after CHECKD: >
	MOVE T1,STRDEV		;DEVICE DESIGNATOR FOR STR
	GDSKC			;GET SYSTEM COUNTS
	MOVE T2,T1		;GET COUNT OF USED
	CALL TTNOUT		;PRINT CURRENT COUNT
	TMSG <

>
;GENERATE LOST PAGES LIST.  MAP SYSTEM BIT TABLE AND COMPARE WITH
;LOCALLY GENERATED VERSION.  OUTPUT DIFFERENCES.

	; ..
	SKIPN REBLDF		;ARE WE REBUILDING THE BIT TABLE?
	JRST FNDLS8		;NO.
	MOVX T1,DA%WRT		;T1/WRITE THE BIT TABLE
	MOVE T2,STRDEV		;T2/STRUCTURE 0
	DSKAS			;COPY PRIVATE COPY OF BIT TABLE TO FILE
	 JRST [	PNTERR(<Failed to write bit table file>)
		JSERR
		RET]
	RET			;SUCCESS. DON'T DO THE REST

;HERE WHEN NOT REBUILDING THE BIT TABLE.  GET A JFN ON BIT TABLE FILE,
;OPEN IT AND MAP IT TO OUR ADDRESS SPACE

FNDLS8:	PUSH P,P1		;SAVE AC
	HRROI T2,[ASCIZ /<ROOT-DIRECTORY>DSKBTTBL/]
	CALL ADDSTR		;ADD STRUCTURE NAME
	MOVX T1,GJ%OLD!GJ%SHT!GJ%PHY
	GTJFN			;GET JFN ON BIT TABLE FILE
	 JRST [	PNTERR(<GTJFN failure for <ROOT-DIRECTORY>DSKBTTBL>)
		RET]
	MOVEM T1,BTBJFN		;SAVE THE JFN
	MOVEI T2,OF%RD+OF%THW	;T1/READ ACCESS, THAWED
	OPENF			;OPEN THE BIT TABLE FILE
	 JRST [	PNTERR(<OPENF failure for <ROOT-DIRECTORY>DSKBTTBL>)
		RET]
	HRLZ T1,BTBJFN		;SOURCE (PAGE 0 OF BIT TABLE FILE)
	MOVE T2,[.FHSLF,,SYSBTB/PGSIZ] ;DESTINATION (SYSBTB AREA OF THIS FORK)
	MOVE T3,BTBPGS		;NUMBER OF PAGES IN FILE
	TXO T3,PM%CNT+PM%RD+PM%CPY ;MAP WITH COPY-WRITE
	PMAP			;MAP BIT TABLE FILE TO CORE STARTING AT SYSFCT
	SETZM OUTJFN		;NO FILE YET
	SETZM LOSTOT		;INIT COUNT OF LOST PAGES
	MOVN P1,HITRK		;SETUP TO SCAN ALL TRACKS
	HRLZS P1

;LOOP THROUGH PAGES IN BIT TABLE, COMPARING WITH LOCAL COPY.  REPORT
;INCONSISTENCIES AND FIX WHERE NECESSARY

FNDLS1:	MOVE T1,LOCBTB(P1)	;GET OUR COUNT
	CAME T1,SYSBTB(P1)	;AGREES WITH SYSTEM?
	JRST [	CALL FNDLS2	;NO, FIGURE OUT DIFFERENCE
		JRST FNDLS1]	;TRY AGAIN
	AOBJN P1,FNDLS1		;DO ALL TRACKS
	; ..
;ALL CYLINDERS HAVE BEEN CHECKED.  WRITE FILE OF LOST PAGES IF THERE
;ARE ANY.  NOTE THAT WRITING IS SUPPRESSED IF ERRORS HAVE OCCURRED.

	; ..
	SKIPG LOSTOT		;ANY LOST PAGES?
	JRST [	TMSG <There are no lost pages.
>				;NO. DON'T CREATE LOST-PAGES FILE
		JRST FNDLSX]

;OPEN A FILE AND DUMP LOST PAGES LIST
	TMSG <There are >
	MOVE T2,LOSTOT
	MOVEI T3,^D10		;OUTPUT IT IN DECIMAL
	CALL TTNOUT
	TMSG < lost pages
>
	SKIPN WRTLPF		;WRITE FILE?
	JRST [	TMSG <%Suppressed writing of lost pages file , too many errors
>
		SKIPE JOBNO	;SKIP IF JOB 0
		SKIPN STRMNT	; OR NO MOUNTED STR
		JRST FNDLSX	;THEN DONE
		TMSG <% Warning -- structure still mounted with exclusive access
so that errors may be fixed.
>
		SETZM STRMNT	;CLEAR FLAG
		JRST FNDLSX]	;FINISH UP
	HRROI T1,ATMBUF		;BUILD FILESPEC HERE
	HRROI T2,STRHOM		;START WITH STR NAME
	MOVEI T3,0
	SOUT
	MOVEI T2,"-"
	IDPB T2,T1
	HRROI T2,[ASCIZ /LOST-PAGES.BIN/]
	SOUT			;COMPLETE SPEC
	MOVX T1,GJ%FOU!GJ%SHT!GJ%PHY
	HRROI T2,ATMBUF		;FILESPEC TEXT PNTR
	GTJFN			;GET A JFN FOR LOST PAGES FILE
	 JRST [	PNTERR(<GTJFN failure for lost pages file>,FNDLS9)]
	MOVEM T1,OUTJFN		;SAVE JFN FOR LOST PAGES FILE
	MOVE T2,[44B5+OF%WR]	;T2/36-BIT BYTES, WRITE ACCESS
	OPENF			;OPEN IT
	 JRST [	PNTERR(<Failed to open lost pages file>,FNDLS9)]
	TMSG<
Addresses are in file >
	MOVEI T1,.PRIOU
	MOVE T2,OUTJFN		;HAVE OUTPUT FILE?
	MOVX T3,1B2+1B5+1B8+1B11+1B14+1B35
	JFNS			;PRINT NAME
	TMSG <
>
	CALL LPFWRT		;WRITE THE HEADER
	MOVE T1,OUTJFN		;THE DESTINATION
	MOVE T2,[POINT 36,LOSBUF] ;POINT TO LIST
	MOVN T3,LOSTOT		;THE NUMBER
	SOUT			;WRITE THE FILE
	 ERJMP [PNTERR (<Output error or quota exceeded>,FNDLS9)]
	MOVE T1,OUTJFN
	CLOSF
	 JFCL
	JRST FNDLSX

FNDLS9:	TMSG <
?File was not written
>
;UNMAP THE BIT TABLE AND CLOSE THE FILE

FNDLSX:	SETO T1,
	MOVE T2,[.FHSLF,,SYSBTB/PGSIZ]
	MOVE T3,BTBPGS		;NUMBER OF PAGES
	TXO T3,PM%CNT
	PMAP			;UNMAP SYSTEM BIT TABLE PAGES
	MOVE T1,BTBJFN
	CLOSF
	 JFCL
	POP P,P1		;RESTORE AC
	RET
;FIND DIFFERENCE IN BITS, COMPUTE CORRESPONDING ADDRESS

FNDLS2:	HRRZ T4,P1		;GET TRACK NUMBER
	IMUL T4,BTWCYL		;COMPUTE INDEX TO BIT TABLE
	ADD T4,BTBTOP		;POINT INTO BOTTOM HALF
	MOVN T1,BTWCYL		;GET NUMBER OF BIT WORDS PER CYLINDER
	HRL T4,T1		;T4/(-COUNT,,T1DDRESS OF BIT WORD)
FNDLS4:	MOVE T1,LOCBTB(T4)	;GET OUR BIT WORD
	XOR T1,SYSBTB(T4)		;GET DIFFERENCE
	JFFO T1,FNDLS3		;JUMP IF HAVE A DIFFERENCE
	AOBJN T4,FNDLS4		;DIFFERENCE NOT IN THAT WORT4, TRY NEXT

;HERE WHEN THE LOCAL AND SYSTEM BIT TABLES DISAGREE IN FREE PAGE COUNT FOR
;A TRACK AND EITHER
;	1) ALL THE BIT WORDS FOR THAT CYLINDER AGREE
;		OR
;	2) ONE OR MORE PAGES ARE MARKED AS ASSIGNED IN THE LOCAL BIT AND
;	   FREE IN THE SYSTEM BIT TABLE
;NOTE THAT THE LATTER SHOULD NOT OCCUR SINCE IT SHOULD HAVE PRODUCED A
;'NOT IN BIT TABLE' MESSAGE EARLIER AND BEEN CORRECTED.
;IF PAGES ARE MARKED AS FREE IN THE LOCAL TABLE AND ASSIGNED IN THE SYSTEM
;TABLE, THEY WILL BE IDENTIFIED AS LOST PAGES

FNDLS7:	TMSG <?Bit tables inconsistent at cylinder >
	HRRZ T2,P1		;GET CYLINDER NUMBER
	MOVEI T3,10		;T3/OCTAL
	CALL TTNOUT		;PRINT THE CYLINDER NUMBER
	MOVE T1,LOCBTB(P1)	;COPY THE LOCAL (PRESUMED CORRECT) COUNT
	MOVEM T1,SYSBTB(P1)	; TO THE SYSTEM COUNT. NOTE: DOES NOT CHANGE
				; THE COPY ON THE DISK
	TMSG <
>
	RET

FNDLS3:	MOVSI T1,(1B0)		;GET BIT
	MOVN T3,T2
	LSH T1,0(T3)
	TDNE T1,SYSBTB(T4)	;BIT WAS OFF IN SYSTEM (PAGE ASSIGNED)?
	JRST FNDLS7		;NO. PAGE SHOULD HAVE BEEN ASSIGNED
	IORM T1,SYSBTB(T4)	;NOTE PAGE NOW NOT ASSIGNED
	AOS SYSBTB(P1)		;ADJUST COUNT
	HRRZ T1,P1		;GET TRACK NUMBER
	IMUL T1,SECCYL		;GET SECTOR COUNT
	HLRE T3,T4		;GET INDEX TO BIT TABLE
	ADD T3,BTWCYL
	IMULI T3,^D36		;COMPUTE PAGE WITHIN TRACK
	ADD T2,T3
	IMUL T2,SECPAG		;COMPUTE SECTOR WITHIN TRACK
	ADD T1,T2		;DSKADR = TRACK ADR + SEC WITHIN TRK
	CALL SEEADR		;SEE IF A BAT BLOCK
	 RET			;YES. DONT PUT IT IN LOST FILE
	AOS T2,LOSTOT		;COUNT IT
	CAIL T2,MAXLOS		;STILL ROOM?
	JRST [	HRROI T1,[ASCIZ /
?Lost pages exceeded buffer space. 
/]
		CAIN T2,MAXLOS	;FIRST TIME?
		PSOUT		;YES. TELL HIM
		RET]		;AND GIVE UP
	MOVEM T1,LOSBUF-1(T2)	;STORE LOST PAGE
	RET
;ROUTINE TO SEE IF A DISK ADDRESS IS A BAT BLOCK
; T1/ DISK ADDRESS
;
;RETURUNS +1: A BAT BLOCK
;	  +2: NOT A BAT BLOCK

SEEADR:	PUSH P,T3		;SAVE T3
	PUSH P,T1		;SAVE T1
	PUSH P,T2
	IDIV T1,SECCYL		;FIND THE NUMBER OF CYL'S
	IMUL T1,LPPCYL		;FIND OFFSET
	POP P,T2		;RESTORE T2
	ADD T1,0(P)		;GET THE REAL DISK ADDRESS
	MOVEI T3,BPRBLK		;START OF THE PAIRS
SEEIF:	CAMN T3,SVEND		;AT THE END?
	JRST [	POP P,T1	;YES. RESTORE T1
		POP P,T3	;RESTORE T3
		AOS (P)		;BUMP RETURN
		RET]		;AND RETURN GOOD
	CAML T1,0(T3)		;NO. WITHIN RANGE?
	CAMLE T1,1(T3)		;STILL?
	SKIPA			;IS NOT IN RANGE
	JRST [	POP P,T1	;RESTORE T1
		POP P,T3	;RESTORE T3
		RET]		;RETURN
	ADDI T3,2		;NEXT PAIR
	JRST SEEIF		;GO SEE IF THE NEXT PAIR IN ONE
;OUTPUT NUMBER IN B TO TERMINAL

;	2/NUMBER
;	3/RADIX

TTNOUT:	MOVEI T1,101
	NOUT
	 JFCL
	RET


;READ LINE INTO LINE BUFFER
; T1