Google
 

Trailing-Edge - PDP-10 Archives - BB-H138F-BM_1988 - 7-sources/checkd.mac
There are 35 other files named checkd.mac in the archive. Click here to see a list.
; UPD ID= 49, RIP:<7.UTILITIES>CHECKD.MAC.4,  19-Feb-88 17:50:36 by GSCOTT
;TCO 7.1236 - edit 26, update copyright notice.
; UPD ID= 30, RIP:<7.UTILITIES>CHECKD.MAC.3,  14-Dec-87 09:15:35 by BROOKS
;Increment version number for 7.0 ft1
; UPD ID= 23, RIP:<7.UTILITIES>CHECKD.MAC.2,   4-Nov-87 15:47:22 by MCCOLLUM
;TCO 7.1112 - Add ENABLE/DISABLE/SHOW LOGIN STRUCTURE commands.
; *** Edit 4 to CHECKD.MAC by RASPUZZI on 7-Jan-87, for SPR #21493
; Increase the amount of lost pages that CHECKD can handle from 1/3 of an RP06
; to about 1/3 of an RA81
; *** Edit 3 to CHECKD.MAC by MCCOLLUM on 18-Nov-86
; Print last directory seen if RCDIR fails in NXTDIR
; *** Edit 2 to CHECKD.MAC by GRANT on 26-Mar-86
; Allow multiple CHECKDs to simultaneously mount structures 
; UPD ID= 120, SNARK:<6.1.UTILITIES>CHECKD.MAC.64,   1-May-85 16:45:08 by LEACHE
;MORE OF PREVIOUS
; UPD ID= 114, SNARK:<6.1.UTILITIES>CHECKD.MAC.63,  14-Apr-85 15:59:33 by LEACHE
;TCO 6.1.1321 Add ENABLE BOOT-PARAMETERS
; UPD ID= 92, SNARK:<6.1.UTILITIES>CHECKD.MAC.62,   6-Mar-85 10:10:26 by HAUDEL
;TCO 6.1.1235 - Use Sixbit DONOCA for the DON'T CARE option.
; UPD ID= 78, SNARK:<6.1.UTILITIES>CHECKD.MAC.61,  13-Feb-85 15:33:10 by HAUDEL
;TCO 6.1.1199 - Remove the SET DRIVE SERIAL NUMBER command.
; UPD ID= 70, SNARK:<6.1.UTILITIES>CHECKD.MAC.60,  24-Jan-85 09:27:22 by HAUDEL
;TCO 6.1.1135 - Change an error message.
; UPD ID= 60, SNARK:<6.1.UTILITIES>CHECKD.MAC.59,  18-Dec-84 13:58:34 by TBOYLE
;TCO 6.1.1094 - Fix DISABLE AUTOMATIC-STARTUP At .AUTOS+6.
; UPD ID= 54, SNARK:<6.1.UTILITIES>CHECKD.MAC.58,   4-Dec-84 09:33:49 by TBOYLE
;TCO 6.1.1069 (QAR 706325) Put a space between filename and "is new" &vers 6.1
; UPD ID= 625, SNARK:<6.UTILITIES>CHECKD.MAC.57,  31-Oct-84 15:29:03 by TBOYLE
;More TCO 6.2116 - Ask for decimal serial number 
; UPD ID= 603, SNARK:<6.UTILITIES>CHECKD.MAC.56,   7-Oct-84 04:51:26 by TBOYLE
;More TCO 6.2116 - RP20 serial number by channel/kontroller/unit number.
; UPD ID= 602, SNARK:<6.UTILITIES>CHECKD.MAC.55,   6-Oct-84 02:33:06 by TBOYLE
;TCO 6.2237 (QAR 706247) Use SECPAG for BAT pairs. Also fix unit bit mask.
; UPD ID= 595, SNARK:<6.UTILITIES>CHECKD.MAC.54,  17-Sep-84 14:32:26 by PURRETTA
;Up edit level for previous edit.
; UPD ID= 590, SNARK:<6.UTILITIES>CHECKD.MAC.53,  10-Sep-84 14:04:09 by TBOYLE
;Use true sector size 1000 when writing RP20 serial number.
; UPD ID= 558, SNARK:<6.UTILITIES>CHECKD.MAC.52,   2-Jul-84 15:42:28 by TBOYLE
;Channel/Controller/Unit number on input and output now in decimal.
; UPD ID= 557, SNARK:<6.UTILITIES>CHECKD.MAC.51,   2-Jul-84 14:38:40 by TBOYLE
;TCO 6.2115 and 6.2116 - don't care disks and RP20 serial numbers.
; UPD ID= 551, SNARK:<6.UTILITIES>CHECKD.MAC.50,  18-Jun-84 17:04:12 by TBOYLE
;Fix a bug in 6.2067... At BATWRT use TRECPP/SECPAG to normalize
; UPD ID= 549, SNARK:<6.UTILITIES>CHECKD.MAC.49,  12-Jun-84 15:53:51 by TBOYLE
;TCO 6.2067 - Use DOP%PS at BATWRT, HOMIN, and BATIN.
; UPD ID= 402, SNARK:<6.UTILITIES>CHECKD.MAC.48,  14-Dec-83 11:38:34 by TSANG
;TCO 6.1871 Allow wildcard for input filespec.
; UPD ID= 400, SNARK:<6.UTILITIES>CHECKD.MAC.47,  13-Dec-83 16:14:26 by TBOYLE
;More TCO 6.1903 Changed to use TRANSL in HOMEIN, PSCHK, START0..
; UPD ID= 398, SNARK:<6.UTILITIES>CHECKD.MAC.46,  12-Dec-83 14:14:55 by TBOYLE
;TCO 6.1903 and 6.1905 Use real PS: name, and put in DOBE's and <returns>
; UPD ID= 396, SNARK:<6.UTILITIES>CHECKD.MAC.45,   7-Dec-83 14:58:31 by TBOYLE
;TCO 6.1898 Make VERIFY command use GTASTS and fix GETCK2. (5.1 ed. 54)
; UPD ID= 395, SNARK:<6.UTILITIES>CHECKD.MAC.44,   7-Dec-83 13:00:43 by TBOYLE
;TCO 6.1897 Make .BATEX update BAT BLOCKS after VERIFY. (5.1 ed. 76) Now ed. 46
; UPD ID= 394, SNARK:<6.UTILITIES>CHECKD.MAC.43,   6-Dec-83 17:26:10 by TBOYLE
;TCO 6.1895 Fix wrong serial # being loaded in HOM on ENA AUTO. (5.1 ed. 74)
; UPD ID= 393, SNARK:<6.UTILITIES>CHECKD.MAC.42,   6-Dec-83 16:30:36 by TBOYLE
;TCO 6.1894 Allow 14 chars on owner id for created structure. (5.1 Edit 31)
; UPD ID= 392, SNARK:<6.UTILITIES>CHECKD.MAC.41,   6-Dec-83 16:21:10 by TBOYLE
;TCO 6.1893 Be paranoid about directory names (5.1 Edit 32)
; UPD ID= 390, SNARK:<6.UTILITIES>CHECKD.MAC.40,   5-Dec-83 17:07:33 by TBOYLE
;TCO 6.1890 Move new SEEADR routine to development sources.
; UPD ID= 389, SNARK:<6.UTILITIES>CHECKD.MAC.39,   5-Dec-83 13:52:52 by TBOYLE
;More TCO 6.1869 use new MSTR to pick up LPPCYL of TCO 6.1876
; UPD ID= 376, SNARK:<6.UTILITIES>CHECKD.MAC.38,  21-Nov-83 17:43:21 by TBOYLE
;Fix last edit. Make GTASTS different from GTUSTS.
;TCO 6.1869 - Make CHECKD use MSTR% to obtain disk drive info.
; UPD ID= 344, SNARK:<6.UTILITIES>CHECKD.MAC.35,  17-Aug-83 10:06:14 by WEETON
;TCO 6.1776 - Fix arguments to DSKTAB for RA81s.
; UPD ID= 340, SNARK:<6.UTILITIES>CHECKD.MAC.34,   8-Aug-83 09:49:41 by WEETON
;TCO 6.1759 - Increase space for code in CHECKD.
; UPD ID= 336, SNARK:<6.UTILITIES>CHECKD.MAC.33,   2-Aug-83 15:53:02 by WEETON
;Make edit number ^D37
; UPD ID= 335, SNARK:<6.UTILITIES>CHECKD.MAC.32,   2-Aug-83 15:06:40 by WEETON
;TCO 6.1613 - Incorporate D1%INI function of DSKAS JSYS.
; UPD ID= 334, SNARK:<6.UTILITIES>CHECKD.MAC.31,   2-Aug-83 14:18:11 by WEETON
;TCO 6.1590 and 6.1591 - Wait for confirmation before adding APR serial number
;on new structure
; UPD ID= 333, SNARK:<6.UTILITIES>CHECKD.MAC.30,   2-Aug-83 14:06:55 by WEETON
;TCO 6.1582 - Make ADD command include APR serial number, and drive/con/kon no.
; UPD ID= 332, SNARK:<6.UTILITIES>CHECKD.MAC.29,   2-Aug-83 13:55:52 by WEETON
;TCO 6.1584 - Don't trash Multipack structure BAT blocks (supercedes TCO 6.1574
;; and TCO 6.1575)
; UPD ID= 331, SNARK:<6.UTILITIES>CHECKD.MAC.28,   2-Aug-83 13:45:42 by WEETON
;TCO 6.1573 - Can't add pages greater than largest already in BAT BLOCK
; UPD ID= 330, SNARK:<6.UTILITIES>CHECKD.MAC.27,   2-Aug-83 13:43:01 by WEETON
;TCO 6.1572 - Make Edit number decimal
; UPD ID= 327, SNARK:<6.UTILITIES>CHECKD.MAC.26,  28-Jul-83 11:33:42 by WEETON
;TCO 6.1738 - Report correct disk address on multiply assigned page
; UPD ID= 319, SNARK:<6.UTILITIES>CHECKD.MAC.25,  18-Jul-83 14:08:22 by WEETON
;TCO 6.1735 - Make RAxx disk types page mode.
; UPD ID= 239, SNARK:<6.UTILITIES>CHECKD.MAC.24,  23-Mar-83 14:24:34 by WEETON
;Yet more of TCO 6.1547 - Always run in section 1 and make PNTFIL read from
; section 2
; UPD ID= 237, SNARK:<6.UTILITIES>CHECKD.MAC.23,  21-Mar-83 08:59:55 by WEETON
;TCO 6.1548 - Increase lost pages buffer back to V5 size.
; UPD ID= 236, SNARK:<6.UTILITIES>CHECKD.MAC.22,  20-Mar-83 11:50:44 by WEETON
;More of TCO 6.1547 - Make XSIR% work right.
; UPD ID= 235, SNARK:<6.UTILITIES>CHECKD.MAC.21,  18-Mar-83 18:20:08 by WEETON
; UPD ID= 234, SNARK:<6.UTILITIES>CHECKD.MAC.20,  18-Mar-83 17:09:14 by WEETON
;TCO 6.1556 - If disk address is too big when deassigning page, quit.
; UPD ID= 233, SNARK:<6.UTILITIES>CHECKD.MAC.19,  18-Mar-83 16:33:46 by WEETON
;TCO 6.1553 - Write names of "new" files.
; UPD ID= 232, SNARK:<6.UTILITIES>CHECKD.MAC.18,  18-Mar-83 16:16:05 by WEETON
;TCO 6.1555 - Don' allow system to come up under some conditions.
; UPD ID= 231, SNARK:<6.UTILITIES>CHECKD.MAC.17,  18-Mar-83 16:09:42 by WEETON
;TCO 6.1552 - Check for invisible and deleted files when FIXCNTing of pages
; UPD ID= 230, SNARK:<6.UTILITIES>CHECKD.MAC.16,  18-Mar-83 15:58:17 by WEETON
;TCO 6.1550 - Notify users when CHECKD is going to run at system startup
; UPD ID= 225, SNARK:<6.UTILITIES>CHECKD.MAC.15,  15-Mar-83 14:52:42 by COBB
;TCO 6.1545 - Change major/minor version numbers
; UPD ID= 224, SNARK:<6.UTILITIES>CHECKD.MAC.14,  15-Mar-83 13:58:59 by COBB
;More TCO 6.1496 - Use T1, not T2 in HOMEIN:
; UPD ID= 203, SNARK:<6.UTILITIES>CHECKD.MAC.13,   4-Feb-83 05:10:56 by WACHS
;TCO 6.1496 - Add def'ns for RA80, RA81, RA60. Alllow controller 0 - 17
; UPD ID= 170, SNARK:<6.UTILITIES>CHECKD.MAC.12,  17-Nov-82 13:20:41 by LEACHE
;More TCO 6.1247
; UPD ID= 168, SNARK:<6.UTILITIES>CHECKD.MAC.11,  15-Nov-82 10:00:32 by DONAHUE
;TCO 6.1356 - Put ERJMP after first instruction that references FDB
; UPD ID= 163, SNARK:<6.UTILITIES>CHECKD.MAC.10,  26-Oct-82 13:44:25 by WEETON
;TCO 6.1329 - Check for old LOST-PAGES.BIN
; UPD ID= 162, SNARK:<6.UTILITIES>CHECKD.MAC.9,  26-Oct-82 09:37:31 by WEETON
;TCO 6.1328 - Don't default structure names
; UPD ID= 161, SNARK:<6.UTILITIES>CHECKD.MAC.8,  14-Oct-82 11:08:34 by WEETON
;TCO 6.1304 - After unsuccessful dismount of structure,return to CHECKD> prompt
; UPD ID= 160, SNARK:<6.UTILITIES>CHECKD.MAC.7,  14-Oct-82 11:05:17 by WEETON
;TCO 6.1303 - Read various definations from PROLOG
; UPD ID= 159, SNARK:<6.UTILITIES>CHECKD.MAC.6,  14-Oct-82 10:45:53 by WEETON
; UPD ID= 158, SNARK:<6.UTILITIES>CHECKD.MAC.5,  14-Oct-82 10:41:44 by WEETON
; UPD ID= 157, SNARK:<6.UTILITIES>CHECKD.MAC.4,  14-Oct-82 10:36:37 by WEETON
;TCO 6.1301 - Increase size of directory buffer to match larger directories
; UPD ID= 125, SNARK:<6.UTILITIES>CHECKD.MAC.3,   3-Sep-82 11:06:32 by LEACHE
;TCO 6.1247 Add ENABLE PASSWORD ENCRYPTION
; UPD ID= 120, SNARK:<6.UTILITIES>CHECKD.MAC.2,  19-Aug-82 15:24:35 by LEACHE
;TCO 6.1231 - Protect against user files with extension .DIRECTORY
; UPD ID= 84, SNARK:<5.UTILITIES>CHECKD.MAC.13,  24-Feb-82 14:36:12 by PAETZOLD
;TCO 5.1736 - Correct sense of PAGNN and MR%DIR tests in MRKBTB
; UPD ID= 80, SNARK:<5.UTILITIES>CHECKD.MAC.12,  18-Feb-82 17:56:35 by MURPHY
;TCO 5.1732 - Construct numeric string for default number pages in COMND call.
; UPD ID= 78, SNARK:<5.UTILITIES>CHECKD.MAC.11,   1-Feb-82 16:45:42 by PAETZOLD
;TCO 5.1713 - Use ^V's on characters of file name and type in FIXCNT
; UPD ID= 60, SNARK:<5.UTILITIES>CHECKD.MAC.10,  24-Nov-81 10:56:41 by DONAHUE
;TCO 5.1573 - Don't charge directory pages to superior
; UPD ID= 30, SNARK:<5.UTILITIES>CHECKD.MAC.9,   9-Sep-81 15:58:07 by DONAHUE
;TCO 5.1495 - Rewrite Bat block logic to account for lost pages
; UPD ID= 12, SNARK:<5.UTILITIES>CHECKD.MAC.8,  28-Jul-81 15:05:48 by LYONS
; fix some bugs in the last edits
; UPD ID= 11, SNARK:<5.UTILITIES>CHECKD.MAC.7,  27-Jul-81 14:31:13 by LYONS
;TCO 5.1297 - Add error return for SCANDI in QDONE
;ADD MORE OF THE VERIFY CODE (AGAIN) AND TCO 5.1280
; UPD ID= 1543, SNARK:<5.UTILITIES>CHECKD.MAC.5,   9-Feb-81 13:39:51 by LYONS
;ADD MORE OF THE VERIFY CODE
; UPD ID= 992, SNARK:<5.UTILITIES>CHECKD.MAC.4,   5-Sep-80 16:54:05 by LYONS
;GENERAL CLEANUP, ADD SOME CODE TO .VERIFY
; UPD ID= 750, SNARK:<5.UTILITIES>CHECKD.MAC.3,  10-Jul-80 20:42:34 by LYONS
;ADD WRITE VERIFICATION CONTROLS FOR SYSTEM
;ADD ENABLE AND DISABLE COMMANDS
;PUT CPU SERIAL NUMBER INTO HOME BLOCK FOR STRUCTURES WHICH BOOT SYSTEM
; UPD ID= 376, SNARK:<4.1.UTILITIES>CHECKD.MAC.2,  26-Mar-80 14:13:47 by DBELL
;TCO 4.1.1124 - ADD RP20 SUPPORT
;<4.UTILITIES>CHECKD.MAC.29, 11-Oct-79 15:24:06, EDIT BY GRADY
;<4.UTILITIES>CHECKD.MAC.28, 11-Oct-79 14:57:55, EDIT BY GRADY
;TCO 4.2496 - DELETE ALL GENERATIONS OF THE LOST PAGES FILE IN RLSPG2
;<4.UTILITIES>CHECKD.MAC.27,  8-Aug-79 11:33:07, EDIT BY GRANT
;TCO 4.2379 - CHANGE LF TO CRLF TO CLEAN UP SOME OUTPUT FORMATS
;<4.UTILITIES>CHECKD.MAC.26, 17-Apr-79 16:28:55, EDIT BY DBELL
;TCO 4.2232 - AT NXTPR ROUND DOWN BAT BLOCK ENTRIES TO PAGE BOUNDARIES
; SO THAT 3/4 OF THE PAGES WITH A BAD SECTOR WILL NOT BE MISSED.
;<4.UTILITIES>CHECKD.MAC.25, 10-Mar-79 13:39:25, EDIT BY KONEN
;UPDATE COPYRIGHT FOR RELEASE 4
;<4.UTILITIES>CHECKD.MAC.24,  8-Mar-79 13:25:35, EDIT BY R.ACE
;TAKE OUT TAPE-INIT FUNCTIONS
;<4.UTILITIES>CHECKD.MAC.23, 19-Feb-79 11:54:59, Edit by KONEN
;INCREMENT MOUNT COUNT AFTER MOUNTING A STRUCTURE
;<4.UTILITIES>CHECKD.MAC.22, 12-Feb-79 13:12:50, EDIT BY R.ACE
;CHANGE CKMNT TO ACCOMMODATE NEW GALAXY TEXT MESSAGE FORMAT
;<4.UTILITIES>CHECKD.MAC.21, 10-Jan-79 10:32:00, EDIT BY R.ACE
;RELEASE PID IN QUIT CODE
;<4.UTILITIES>CHECKD.MAC.20, 12-Dec-78 10:48:23, EDIT BY DBELL
;TCO 4.2119 - FIX BUG IN RELEASING MORE THAN 12K LOST PAGES
;<4.UTILITIES>CHECKD.MAC.19,  8-Dec-78 14:39:41, EDIT BY DBELL
;TCO 4.2115 - MOVE LOCATION HFLAGS TO PREVENT BAT LOGIC ERRORS
;<4.UTILITIES>CHECKD.MAC.18,  8-Dec-78 11:10:21, EDIT BY DBELL
;TCO 4.2114 - FIX BAT LOGIC AT NXTPR TO USE FULL 27 BIT ADDRESSES
;<4.UTILITIES>CHECKD.MAC.17, 27-Nov-78 10:31:31, Edit by LCAMPBELL
; Add QUIT as a synonym for EXIT
;<4.UTILITIES>CHECKD.MAC.16, 12-Nov-78 13:53:58, EDIT BY R.ACE
;CHANGE VOLID PARSING TO USE ^V INSTEAD OF QUOTED STRINGS
;<4.UTILITIES>CHECKD.MAC.15,  6-Nov-78 07:47:29, EDIT BY R.ACE
;TCO 4.2079 - ADD TAPE-INITIALIZATION FUNCTIONS
;PERFORM GENERAL CLEAN-UP
;<4.UTILITIES>CHECKD.MAC.14, 31-Aug-78 17:16:39, Edit by MCLEAN
;MAKE CYLUN2 HAVE 558 CYLINDERS PER UNIT FOR DIAGNOSTICS
;<4.UTILITIES>CHECKD.MAC.13, 24-Jul-78 07:38:08, EDIT BY MILLER
;CHANGE DEFINITION OF DSKMSK TO INCLUDE DSKNB
;<4.UTILITIES>CHECKD.MAC.12, 19-Jun-78 13:27:15, Edit by MCLEAN
;<1MCLEAN>CHECKD.MAC.6,  6-May-78 23:39:32, Edit by MCLEAN
;ADD RP07

;	COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1976, 1988.
;	ALL RIGHTS RESERVED.
;
;	THIS SOFTWARE IS FURNISHED UNDER A  LICENSE AND MAY BE USED AND  COPIED
;	ONLY IN  ACCORDANCE  WITH  THE  TERMS OF  SUCH  LICENSE  AND  WITH  THE
;	INCLUSION OF THE ABOVE  COPYRIGHT NOTICE.  THIS  SOFTWARE OR ANY  OTHER
;	COPIES THEREOF MAY NOT BE PROVIDED  OR OTHERWISE MADE AVAILABLE TO  ANY
;	OTHER PERSON.  NO  TITLE TO  AND OWNERSHIP  OF THE  SOFTWARE IS  HEREBY
;	TRANSFERRED.
;
;	THE INFORMATION IN THIS  SOFTWARE IS SUBJECT  TO CHANGE WITHOUT  NOTICE
;	AND SHOULD  NOT  BE CONSTRUED  AS  A COMMITMENT  BY  DIGITAL  EQUIPMENT
;	CORPORATION.
;
;	DIGITAL ASSUMES NO  RESPONSIBILITY FOR  THE USE OR  RELIABILITY OF  ITS
;	SOFTWARE ON EQUIPMENT THAT IS NOT SUPPLIED BY DIGITAL.
	TITLE CHECKD	CHECK/RECONSTRUCT CONSISTENCY OF FILE STRUCTURE
	SEARCH MONSYM,MACSYM,PROLOG
	.CPYRT <<1976, 1988>>

	.REQUIRE SYS:MACREL
	EXTERN .JBSA		;LH/ FIRST FREE LOC IN CHECKD
	SALL
	.DIRECTIVE FLBLST

;ENTRY VECTOR

PRGCST==0			;CUSTOMER ID
PRGVER==7			;[7.1112]VERSION NUMBER
PRGMIN==0			;[7.1112]MINOR VERSION
PRGEDT==VI%DEC+^D26		;[7.1112]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


;CHECKD OPERATES ACCORDING TO HOW IT WAS CALLED:
;
;1. CALLED BY MONITOR JOB 0 (AT SYSTEM STARTUP - MEXEC MODULE)
;	ENTRY VECTOR LOCATION 0 - CHECK PS: FILE CONSISTENCY
;	ENTRY VECTOR LOCATION 3 - INITIALIZE PS: BITTABLE
;
;2. RUN BY ENABLED WHEEL OR OPERATOR
;	ENTRY VECTOR LOCATIONS 0 AND 1 - ACCEPT COMMANDS FROM TTY
; AC'S

F=0
T1=1
T2=2
T3=3
T4=4
Q1=5
Q2=6
Q3=7
P1=10
P2=11
P3=12
S1=13
S2=14
S3=15
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
SUMBYT==.TICCA			;SUMMARY BYTE DURING SCANS
;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==^D10000			;DEFAULT PAGES FOR SWAPPING
DEFPFS==^D950			;DEFAULT PAGES FOR FRONT END

; Macro to change what section we are currently running in.
; Calling sequence
; SEC	SECNUM,ADDR
;  Where SECNUM is the section number
;  And   ADDR   is the address in the section
;   Defaults:
;	SECNUM = 0
;	ADDR   = PC + 1 (in new section)
DEFINE SEC(SECNUM<0>,ADDR<.+1>),<
	XJRSTF	[0
		SECNUM,,ADDR]
>

;MACRO TO CONVERT SYMBOL TO NUMBER IN STRING
;(SHOULD BE IN MACSYM NOW)

DEFINE FORS. (NUM,ARGS,STRING,%MN1)<
   DEFINE %MN1(ARGS)<STRING>
	..FORN==NUM
	.FORN1(%MN1)>
;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 IS FILLED IN BY A BLT FROM OTHER TABLES, SO DO NOT CHANGE
;THE ORDER OF THESE WORDS.

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
LPPCYL:	BLOCK 1			;LOST SECTORS PER CYL
TRECPP: BLOCK 1			;TRUE SECTORS PER PAGE
TRCUNT: BLOCK 1			;TRUE SECTORS PER UNIT

; THE ORDER OF THE FOLLOWING WORDS ARE NOT CRITICAL

DRRST:	BLOCK 1			;RETURNED SOFTWARE STATUS
;HOME BLOCKS.  EACH NUMBER IS A SECTOR NUMBER RELATIVE TO THE START
;OF A UNIT.  EVERY UNIT IN A STRUCTURE HAS THESE BLOCKS ASSIGNED.

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.
MR%DIR==1B4			;THIS IS A DIRECTORY

;MISCELLANEOUS BITS

FILNB==1B3			;NEW FILE BIT
DSKMSK==-1B15			;MASK TO SELECT ONLY DISK ADDRESS FIELD
ADRMSK==-1B13			;MASK FOR COMPLETE STORAGE ADDRESS
ADDERS==<-ADRMSK>-1		;MASK OF THE ADDRESS BITS
;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*2+1		;BAT PAIRS PLUS THE ORIGINAL WORDS
BATBUF:	BLOCK 200		;BUFFER FOR BAT BLOCK

BATBL1==2			;SECTOR NO. OF FIRST BAT BLOCK
BATBL2==13			;SECTOR NO. OF SECOND BAT BLOCK

;DATA PAIRS

DEFSTR BTUNM,0,17,8		;BIT MASK FOR UNIT 1B17=0,1B16=1,1B15=2..


;SPECIAL WORDS AT END OF BAT BLOCK

CODE=606060			;THE CODE

BT%FND==1B1			;FLAG INDICATES BAT BLOCK PAIR KNOWN, BUT NOT
				;RECORDED IN THE BAT BLOCKS
BT%MAP==1B2			;BAT ENTRY MADE BY MAPPER
BT%WBM==1B3			; WRITTEN BY MONITOR
BT%ANG==1B4			;ANYONE'S GUESS WHY THIS WAS ADDED
;LOCATIONS WHERE THINGS ARE MAPPED

;0 - 40000 ARE RESERVED FOR THE PROGRAM

FSTPAG==40000			;FIRST PAGE USED FOR STORAGE

; USED BY CREATE TO BUILD HELP TEXT FOR AVAILABLE UNITS

HBUF=FSTPAG			;HELP BUFFER
NHBUFP==2			;LENGTH OF HELP BUFFER

; USED BY SCAN, CHECK, REBUILD, AND RECONSTRUCT

;******  PT, PTT AND HBUF ALL OVERLAP ******

PT=HBUF				;WHERE TO MAP THE PAGE TABLE
PTT=PT+1000			;WHERE TO MAP THE PAGE TABLE TABLE

; USED BY CHECK

LOSBUF=PTT+1000			;WHERE TO SAVE LOST PAGES
MAXLOS==405000			;[04] NUMBER OF LOST PAGES THAT CAN BE ACCOUNTED FOR

; USED BY SCAN, CHECK, RECONSTRUCT, REBUILD, AND VERIFY
	; VERIFY USES SYSBTB TO KEEP THE BAT PAIRS FROM ITS
	; OWN SCAN OF THE DISK.

SYSBTB=LOSBUF+MAXLOS		;PLACE TO MAP THE BIT TABLE
BTBMAX==100000			;MAX SIZE OF THE BIT TABLE

; USED BY SCAN, CHECK, REBUILD, AND RECONSTRUCT

LOCBTB=SYSBTB+BTBMAX		;LOCAL COPY OF THE BIT TABLE

	; VERIFY USES DIRORG AS A SCRATCH AREA TO READ THE DISK INTO

DIRORG=2M			;START OF MAP AREA FOR DIRECTORY,Section 2
NDIRPG==DRMXSZ			;MAX SIZE OF DIR IN PAGES

LSTPPG==LOCBTB+BTBMAX		;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
RUNJFN:	BLOCK 1			;JFN OF PROGRAM WE ARE GOING TO RUN
HANDLE:	BLOCK 1			; HANDLE OF FORK WE ARE RUNNING THE PROGRAM IN

;FLAGS - SET ACCORDING TO COMMAND TYPED

BATFLG:	BLOCK 1			;ALLOW BAT BLOCK DELETION AS WELL AS
				; INSERTION ON DISK VERIFY PASS
SOFTFL:	BLOCK 1			; 0==> MARK HARD ERRORS OR ECC ERRORS ONLY,
				;  1==> MARK SOFT ERRORS AS WELL AS ECC ERRORS
ECCFLG: EXP 1	; DEFAULT ON	; 0==> MARK ONLY HARD ERRORS
				;  1==> MARK ECC ERRORS
REBLDF:	BLOCK 1			;REBUILD BITTAB IF NON-0
CHKFLF:	BLOCK 1			;CHECK FILES IF NON-0, ELSE DIRECTORIES ONLY
ENAFLG: BLOCK 1			;nonzero for ENABLE, zero for DISABLE
SETFLG: BLOCK 1			;nonzero for SET, zero for CLEAR
BEMFLG: BLOCK 1			; set to indicate that the editor was called
				; without a verify pass in front of it.
BATTYF: BLOCK 1			;FLAG THAT HEADERS HAVE BEEN DUMPED DURING
				;BAT BLOCK OUTPUT
;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
HFLAGS:	BLOCK 1			;FLAGS FROM HOME BLOCK
LOSTOT:	BLOCK 1			;NUMBER LOST PAGES
NLINB==^D100/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
PDLEN==100
PDL:	BLOCK PDLEN		;STACK
DIRNAM:	BLOCK 21		;NAME OF CURRENT DIRECTORY
DIRNUM:	BLOCK 1			;NUMBER OF CURRENT DIRECTORY
STRNAM:	BLOCK 10		;STRUCTURE NAME STRING
PSNAME: BLOCK 10		;ACTUAL NAME OF PS: (IF ANY)
STRHOM:	BLOCK 10		;STR NAME ACTUALLY IN HOME BLOCK
ALINAM:	BLOCK 2			;[2] ALIAS NAME
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)
BATLST: BLOCK 1			;LAST BLOCK WE PROCESSED LOOKING FOR BAT BLOCKS
BATMRK: BLOCK 1			;NUMBER OF BLOCKS MARKED BAD
FSTSEC: BLOCK 1			;THE FISRT PAGE TO READ WHILE DOING A SCAN
LSTSEC:	BLOCK 1			;THE LAST PAGE WE WILL LOOK AT WHEN DOING A BAT
				;BLOCK SCAN + 1
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:
CPUSER:	BLOCK 1			;SERIAL # OF CPU IF BOOTED FROM THIS STRUCTURE
MAXRED:	BLOCK 1			;MAX PAGES TO READ ON A VERIFY READ
THSUNI: BLOCK 1			;UNIT NUMBER WE ARE WORKING ON
;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

RET1:	BLOCK 2			;flags and PC saved here
RET2:	BLOCK 2
RET3:	BLOCK 2

LEVTAB:	RET1			; [LOCATION WHERE PC STORED BY LEVEL]
	RET2
	RET3
				; [LEVEL,,INTERRUPT ADDRESS]
CHNTAB:	XWD 20000,BADINT	;UNKNOWN CHANNEL
	XWD 10000,CONTC		;^C
	XWD 30000,SUMINT	;^Y
	XWD 30000,APUSH		;^P
	XX==4
	REPEAT ^D36-4,<20000,,DSPINT+XX
		XX=XX+1>
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]
>

;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/]
		CALL ERRDRV	;;CALL DRIVER ROUTINE
		JRST ADDR]>
;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)
;FDB DEFINITIONS

DEFSTR FBBK3,.FBBK3,35,36	;BACKUP WORD 3
DEFSTR FBBK4,.FBBK4,35,36	;BACKUP WORD 4
;HOME BLOCK DEFINITIONS - COPIED FROM <5.MONITOR>DSKALC.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)
HOMMID==:15			;MEDIA IDENTIFICATION (UNIQUE)
HOMDCF==:16			;DON'T CARE DISK FLAG (FILE SYSTEM PROTECTION
				;FOR FILE STRUCTURE IGNORED)
HOMBTF==17			;BOOT PARAMETER FLAGS

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

HOMFE2==:101			;BOOTSTRAP.BIN WORD 1 (SECTOR #)
HOMFE3==:102			;BOOTSTRAP.BIN WORD 2 (# OF SECTOR)

HOMLS1==:160			;[7.1112]Serial numbers of CPUs that
HOMLS2==:161			;[7.1112] can use this structure as a
HOMLS3==:162			;[7.1112] Login Structure
HOMLS4==:163			;[7.1112]
LGSLEN==4			;[7.1112]Number of consecutive words above

HOMSER==:164			;SERIAL # OF CPU THAT BOOTS FROM THIS STRUCTURE
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,CONBTS<0>)<
	IFE CONBTS,<XWD [ASCIZ /TXT/],DAT>
	IFN CONBTS,<XWD [CONBTS!CM%FW
			ASCIZ /TXT/],DAT>
>
	DEFINE TF (DAT,TXT)<
	[ASCIZ/TXT/],,[DAT]
>
;ADDRESSES FOR HANDLING EACH COMMAND

CMDTAB:	CMDSIZ,,CMDMAX		;NUMBER COMMANDS, MAXIMUM NUMBER
	TB (.CHECK,CHECK)	;CHECK (BITTABLE/DIRECTORY)
	TB (.CREAT,CREATE)	;CREATE NEW FILE SYSTEM
	TB (.DSABL,DISABLE)	;DISABLE AUTOMATIC STARTUP
	TB (.EDIT,EDIT)		; THE BAT BLOCKS
	TB (.ENABL,ENABLE)	;ENABLE AUTOMATIC STARTUP
	TB (.EXIT,EXIT)		;EXIT FROM CHECKD TO MONITOR
	TB (.FILDT,FILE-DDT)	;PUSH TO THE FILE DDT PROGRAM
	TB (.HELP,HELP)		;PRINT HELP TEXT
	TB (.PUSH,PUSH)		;PUSH TO A NEW EXEC
	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 (.SHOW,SHOW)		;SHOW COMMAND
	TB (.STATU,STATUS)	;TYPE THE SETTINGS OF THE KNOWN SWITCHES
	TB (.VERIF,VERIFY)	;VERIFY DISK FOR ERRORS

CMDSIZ==.-CMDTAB-1
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

DEFSTR (CMFNC,.CMFNP,8,9)	;FUNCTION CODE
DEFSTR (CMFFL,.CMFNP,17,9)	;FUNCTION FLAGS
DEFSTR (CMLST,.CMFNP,35,18)	;LIST POINTER TO NEXT FUNCTION BLOCK
DEFSTR (CMDAT,.CMDAT,35,36)	;FUNCTION SPECIFIC DATA
DEFSTR (CMHLP,.CMHLP,35,36)	;POINTER TO HELP TEXT STRING
DEFSTR (CMDEF,.CMDEF,35,36)	;POINTER TO DEFAULT STRING

;CONFIRMATION OR COMMA
FDCC:	FLDDB.(.CMCMA,,,,,FDCO)
FDCO:	FLDDB.(.CMCFM)
;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,.TICCP
	DTI
	MOVEI T1,SUMBYT		;TURN OFF PSI CHANNELS
	DTI
	MOVEI T1,.TICCC		;FOR ^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:	HLRZ T1,.JBSA		;GET ADDR OF 1ST LOCATION AFTER CHECKD
	CAIL T1,FSTPAG		;OVERLAPPING?
	JRST [	TMSG <?CHECKD program overlaps FSTPAG> ;YES
		HALTF]

;IF YOU GET THE ABOVE MESSAGE, YOU HAVE A LOT OF WORK TO DO

	SETZM REBLDF		;DEFAULT IS NO REBUILD BITTAB

;To get more space, the directory's have been mapped into section 2,
;and Sections 0 and 1 are mapped together.  Also, a macro (SEC)
;has been added to make it easy to change what section we are running in.

START0:
	MOVE	T1,[.FHSLF,,0]	;source is section 0
	MOVE	T2,[.FHSLF,,1]	;destination is section 1
	MOVE	T3,[SM%RD+SM%WR+SM%EX+SM%IND+1]	;map same as section 0,, one section only
	SMAP%			;map a new section
	 ERJMP	[JSERR		;error, write message
		HALTF		;stop
		JRST	.-1]	;no CONTINUEing
	SETZM	T1		;new section
	MOVE	T2,[.FHSLF,,2]	;section 2
	MOVE	T3,[SM%RD+SM%WR+1] ;read/write access to new section
	SMAP%			;map a new section
	 ERJMP	[JSERR		;error, write message
		HALTF		;stop
		JRST	.-1]	;no CONTINUEing

	SEC	1		;enter section 1 for all time
	MOVE P,[IOWD PDLEN,PDL]
	MOVE T1,[ASCII "PS"]	;SET STRNAM TO PS: IN CASE THIS IS JOB 0
	MOVEM T1,STRNAM
	CALL TRANSL		;BUT FIRST, GET THE REAL PS: NAME, IF ANY.
	HRROI T1,PSNAME		
	HRROI T2,STRNAM
	MOVEI T3,0
	SOUT			;COPY TO PSNAME FOR FUTURE REFERENCE
	CALL RESET
	SETOM CHKFLF		;DEFAULT IS CHECK FILES
	SETZM DIRNUM		;INITIALIZE DIRECTORY NUMBER
	SETZM BATLST		;INITIALIZE BAT BLOCK COUNTER
	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
	SETZM BEMFLG		;DEFAULT IS DO VERIFY FIRST
	GJINF
	MOVEM T3,JOBNO
	HRROI T1,ALINAM		;[2] BP TO ALIAS NAME LOCATION
	HRROI T2,[ASCII/CHK/]	;[2] BP TO FIRST PART OF ALIAS
	MOVNI T3,3		;[2] IT'S 3 CHARACTERS LONG
	SOUT%			;[2] MAKE BEGINNING OF ALIAS
	 ERJMP .+1		;[2] 
	MOVE T2,JOBNO		;[2] GET OUR JOB NUMBER
	MOVE T3,[FLD(1,NO%LFL)!FLD(1,NO%ZRO)!FLD(3,NO%COL)!FLD(<^D10>,NO%RDX)] ;[2] LEADING ZEROS, 3 COLUMNS, DECIMAL
	NOUT%			;[2] FINISH THE ALIAS STRING
	 ERJMP .+1		;[2] 
	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
	MOVEI T1,.FHSLF		;T1/FORK HANDLE
	CIS			;CLEAR THE INTERRUPT SYSTEM
	EIR			;ENABLE INTERRUPTS
	MOVEI T2,[3
		1,,LEVTAB
		1,,CHNTAB]		;DECLARE LEVTAB AND CHNTAB
	XSIR%
	SETO T2,		;DISABLE ALL CHANNELS
	DIC			;DEACTIVATE ALL CHANNELS
	MOVX T2,1B1+1B2+1B3	;T2/CHANNEL NUMBERS
	AIC			;ACTIVATE CHANNELS FOR TERM INTS
	MOVE T1,[XWD .TICCP,3]	;^P ON CHAN 3
	ATI
	MOVE T1,[XWD SUMBYT,2]	;CONTROL-Y ON CHANNEL 2 FOR STATUS REPORT
	ATI			;ASSIGN ^Y TO CHANNEL 2
	SKIPN JOBNO		;IF JOB 0,
	JRST DOJOB0		; DO SPECIAL ROUTINE
	MOVE T1,[XWD .TICCC,1]	;ASSIGN ^C TO CHANNEL 1
	ATI
	CALL PARSEI		; CALL COMMON ROUTINE TO DO WORK
PARSE1:	MOVE P,[IOWD PDLEN,PDL]	;RESET STACK
	HRROI T1,PROMPT		;POINTER TO PROMPT STRING
	CALL CMDINI		;INIT COMND (SETUP REPARSE)
	MOVE T1,[CZ%NCL+.FHSLF]
	CLZFF		;RELEASE ALL JFNS
	MOVEI T1,[FLDDB.(.CMKEY,,CMDTAB)] ;T1/ADDRESS OF FDB
	CALL COMNDX		;LOOK FOR A KEYWORD
	 ERROR PARSE1,<Not a CHECKD command> ;NO. START OVER
	HRRZ T1,(T2)		;YES. GO PROCESS IT
	JRST (T1)
;HERE TO SET UP THE PARSE STATE BLOCK

PARSEI:	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)
	RET
;SPECIAL JOB 0 ENTRY POINT TO CALL ROUTINES NECESSARY
;ACCORDING TO AUTOMATIC STARTUP

DOJOB0:
	MOVEI T1,.PRIOU		;WAIT FOR OUTPUT TO END.
	DOBE
	SETOM T1		;to everyone
	HRROI T2,[ASCIZ/ Checking system structure.
/]				;message
	TTMSG			;send message
	 ERJMP .+1		;don't care about errors.
	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
	SETOM	T1		;to everyone
	HRROI	T2,[ASCIZ/ Check of system structure completed.
/] ;message
	TTMSG			;send it
	 ERJMP	.+1		;don't care about errors
	MOVEI T1,.PRIOU
	DOBE			;WAIT FOR OUTPUT TO END.
	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

;DRIVER FOR "ERROR" MACRO - T1/ POINTER TO ASCIZ ERROR MESSAGE

ERRDRV:	ESOUT			;OUTPUT ERROR STRING TO TTY
	CALL CRLF		;OUTPUT CRLF
	MOVE T1,[CZ%NCL+.FHSLF]	;DUMP ALL CLOSED JFN'S
	CLZFF
	RET

;ROUTINE TO OUTPUT # SPACES IN T3

SPACN:	MOVEI T2,40		;SPACE
	IDPB T2,T1
	SOJG T3,.-1
	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 <:]
>
DISMN1:	MOVE T1,[1,,.MSDIS]	;FUNCTION TO DISMOUNT STR
	MOVEI T2,MNTBLK		;ADDRS OF ARGS
	MSTR			;DO FUNCTION
	 ERJMPR [CAIN T1,MSTX43	;error code in T1, can't dismount while INIing
		JRST DISMN2	;yes, go cancel the initialization
		JSERR		;write out why we failed
		JRST START0]	;return to startup code
	RET			;RETURN (DONE)

;Here to attempt to abort initialization of BITTABLE
DISMN2:	MOVX T1,DA%AIN		;set abort bit
	MOVE T2,STRDEV		;get structure's device designator
	DSKAS			;abort initialization
	 ERJMP	[JSERR		;why
		JRST	.+1]	;continue
	JRST	DISMN1		;try to dismount again.
;SETSTR - ROUTINE TO SET UP WORKING STRUCTURE INFO
;STSTRN - AS ABOVE, WITHOUT DISPLAY OF STSRUCTURE NAME

STSTRN:	SETZM T3
	SKIPA
SETSTR:	SETOM T3
	STKVAR <TYPSTR>
	MOVEM T3,TYPSTR		;SAVE ENTRY TYPE
	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
	SKIPN TYPSTR		;WANT STR NAME TYPED?
	JRST AFTTYP		;NO
	TMSG <
[Working on structure - >
	HRROI T1,STRHOM		;PRINT STR NAME
	PSOUT
	TMSG <:]
>
AFTTYP:	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
	IFJER.			;[3]IF A JSYS ERROR OCCURS
	 PNTERR(<Failed to get next directory>)	;[3]
	 HRROI T1,[ASCIZ/? CHECKD: Last directory seen was /] ;[3]TELL HIM WHERE WE WERE
	 PSOUT%			;[3]OUTPUT TO THE TTY:
	 MOVEI T1,.PRIOU	;[3]OUTPUT TO TTY:
	 MOVE T2,DIRNUM		;[3]GET THE LAST DIRECTORY NUMBER
	 DIRST%			;[3]PRINT IT OUT
	  ERJMP .+1		;[3]AT LEAST WE TRIED
	 TMSG <
>				;[3]FINISH OFF THE MESSAGE
	 SETZ T1,		;[3]CLEAR FLAGS FOR ERROR
	 SETZM DIRNUM		;[3]
	 RET			;[3]
	ENDIF.			;[3]
	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 TRANSLATE STRNAM FROM PS: TO ITS REAL NAME, IF ANY.

TRANSL:	HRROI T1,STRNAM
	STDEV			;GET INTERNAL REPRESENTATION
	 ERJMP R		;IF FAIL, RETURN, ITS NOT EVEN MOUNTED
	HRROI T1,STRNAM		;PUT IT HERE, PAL.
	DEVST			;GET THE REAL NAME
	 ERJMP JSERR0		;ERROR, REPORT, AND RETURN
	RET
;ROUTINE TO DO CONFIRMATION AND GET STRUCTURE NAME STRING

FCNFRM:	HRROI T1,[ASCIZ /FOR/]
	CALL CMDNOI		;XTRA GUIDE WORD
CONFRM:	SETZM	T1		;no default for structure name
	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

;ROUTINES TO PARSE STRUCTURE NAME STRING (DEFALUT IN T1)
;ENTRY:  PRSSTR		PARSE EXISTING STRUCTURE
;	 CMDSTR		PARSE NON-EXISTENT STRUCTURE

PRSSTR:	MOVX T2,<FLD(.CMDEV,CM%FNC)+<CM%SDH!CM%HPP!CM%DPP>>
	SKIPA
CMDSTR:	MOVX T2,<FLD(.CMFLD,CM%FNC)+<CM%SDH!CM%HPP!CM%DPP>>
	MOVEM T1,FCNBLK+.CMDEF	;SAVE DEFAULT
	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,FCNBLK		;FUNCTION BLOCK
	CALL COMNDX
	 ERROR PARSE1,<Invalid structure name>
	SKIPN CMDBLK+.CMINC	;ANY REMAINING CHARACTERS?
	RET			;NO - OK 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


	;ROUTINE TO GET STRUCTURE NAME
GETSTR:	SETZM T1		;No default
	CALL PRSSTR		;Get the structure
	HRROI T1,STRNAM		;PLACE TO STORE STRUCTURE NAME
	HRROI T2,ATMBUF		;COPY STRING TYPED BY USER
	MOVEI T3,0
	SOUT			;
	RET
;GENERAL COMND UTILITIES

;SET UP AND EXECUTE COMND JSYS
; T1/ ADDRESS OF FUNCTION DESCRIPTOR BLOCK
;RETURNS +1: PARSE FAILED (ITRAP OR CM%NOP SET)
;	 +2: PARSE SUCCEEDED, T1,T2,T3 AS RETURNED BY COMND JSYS

COMNDX:	MOVE T2,T1		;MOVE FDB ADDRESS TO T2
	MOVEI T1,CMDBLK		;GET COMND STATE BLOCK ADDR IN T1
	COMND			;THE ONLY COMND JSYS IN CHECKD
	 ERJMP R
	TXNE T1,CM%NOP		;PARSE OK?
	RET			;NO
	RETSKP			;YES

; COMNDE - PRINT ERROR MESSAGE FOR COMND
;  T2/ ERROR CODE (RETURNED BY COMND)
; RETURNS +1: ALWAYS

COMNDE:	HRROI T1,[ASCIZ/ /]
	ESOUT			;SET UP BEGINNING OF ERROR MESSAGE
	MOVEI T1,.PRIOU
	HRLI T2,.FHSLF
	SETZ T3,
	ERSTR			;PRINT ERROR MESSAGE
	 JFCL
	 JFCL
CRLF:	TMSG <
>
	RET

;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,[FLDDB.(.CMINI)] ;INIT FUNCTION
	CALL COMNDX
	 JFCL
	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,FCNBLK		;FUNCTION
	CALL COMNDX
	 JRST [	CALL COMNDE	;ERROR, TYPE MESSAGE
		JRST PARSE1]
	RET			;RETURN

;CHECK FOR EOL (RETURN +1 IF NONE)

CMDEOL:	MOVEI T1,[FLDDB.(.CMCFM)]
	CALL COMNDX		;CHECK CONFIRMATION
	 JRST COMNDE		;ERROR, TYPE MESSAGE AND RETURN
	RETSKP			;YES - SKIP 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:	CALL TRANSL		;GET REAL PS: NAME, IF ANY.
	SETZM PSFLG		;NOT PS: YET
	HRROI T1,STRNAM		;NAME OF STRUCTURE
	HRROI T2,PSNAME
	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:
	MOVE T1,[SIXBIT /DBUGSW/];SEE IF WE ARE TIMESHARING, AND ONLY
	SYSGT			; ALLOW WORKING ON PS IF NOT
	SKIPE T2		;DID WE GET THE ENTRY?
	JUMPE T1,R		;YES, WE DID, BUT WE ARE TIMESHARING
	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

GTASTS:				;GET STATUS OF ALIAS ID.
	HRROI T1,NAMBUF		;PLACE FOR STRUCTURE NAME
	MOVEM T1,RNUBLK+.MSRSA	;GET ALIAS NAME
	SETZM RNUBLK+.MSRSN	;DON'T CARE ABOUT ACTUAL STRUCTURE NAME
	JRST GTUST1;		;GO INLINE
	
GTUSTS:				;GET STATUS OF PHYSICAL ID.
	HRROI T1,NAMBUF		;PLACE FOR STRUCTURE NAME
	MOVEM T1,RNUBLK+.MSRSN	;ALWAYS GET ACTUAL STRUCTURE NAME
	SETZM RNUBLK+.MSRSA	;DONT CARE ABOUT ALIAS NAME
GTUST1:	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.

STRMAX:	TDZA T3,T3		; FLAG THAT WE DONT CARE ABOUT MOUNTED
STRMAT:	SETO T3,
	MOVE T1,RNUBLK+.MSRST	;GET UNIT STATUS
	TXNE T1,MS%HBB		;VALID HOME BLOCKS?
	JRST STMAT1		;GIVE WARNING
	TXNE T1,MS%OFL!MS%DIA
	RET			;OFF-LINE, OR DIAG
	SKIPE T3		;ARE WE LOOKING FOR MOUNTED UNITS?
	JRST [	TXNE T1,MS%MNT	;MOUNTED?
		RET
		JRST .+1]	;NO, IT OK
	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
	MOVEI T3,^D10		;DECIMAL OUTPUT
	CALL TTNOUT		;PRINT UNIT #
	SKIPGE RNUBLK+.MSRCT	;ANY CONTROLLER?
	JRST STMAT2		;NO, SKIP SOME OUTPUT
	TMSG < on controller >	;YES, TYPE SOME
	MOVE T2,RNUBLK+.MSRCT	;GET CONTROLLER NUMBER
	CALL TTNOUT		;TYPE IT
STMAT2:	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 STRUCTURE 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)
	MOVE T1,CPUSER		;CPU SERIAL NUMBER OF BOOTABLE STRUCTURE
	MOVEM T1,MNTBLK+.MSISN(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,.MSISN+1(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,ALINAM		;[2] GET STRUCTURE ALIAS
	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
	HRROI T1,ALINAM		;[2] GET STRUCTURE ALIAS
	MOVEM T1,MNTBLK+.MSDEV	;SET UP ALIAS NAME
	MOVE T1,[1,,.MSIMC]	;INCREMENT MOUNT COUNT FOR THIS STR
	MOVEI T2,MNTBLK		;POINT TO ARG BLOCK
	MSTR
	 ERJMP [JSERR		;REPORT LOSAGE
		JRST RESTRT]	;START OVER
	RET			;RETURN
 REPEAT 0, <
;SET COMMAND

.SET:	MOVEI T1,[FLDDB.(.CMKEY,,SETTAB)]	;SECONDARY KEYTABLE
	CALL COMNDX
	 ERROR PARSE1,<Not a CHECKD command>
	HRRZ T1,(T2)		;GET DISPATCH
	JRST (T1)		;PROCESS

;SET KEYWORD TABLE

SETTAB:	XWD SETSIZ,SETMAX
	TB (.DRVSNO,DRIVE-SERIAL-NUMBER)	;DRIVE SERIAL # FOR RP20
SETSIZ=.-SETTAB-1
SETMAX=SETSIZ
	;SET DRIVE-SERIAL-NUMBER
.DRVSNO: TRVAR <SERNO>
	HRROI T1,[ASCIZ /FOR RP20/]
	CALL CMDNOI		;NOISE WORDS
	CALL CMDEOL		;PARSE END OF LINE
	 JRST PARSE1		;ERROR RETURN
	CALL CNFINF		;GET CONFIGURATION INFORMATION
	MOVEI Q1,RNUBLK+.MSRCH	;CHANNEL,UNIT,CTL FOR .MSRUS MSTR FUNCTION
	CALL GETUNT		;GET UNIT INFO FOR ONE UNIT
	MOVE T1,[.MSRLN,,.MSRUS]
	XMOVEI T2,RNUBLK
	MSTR
	 ERJMP 	[JSERR
		JRST PARSE1]
	LOAD T1,MS%TYP,RNUBLK+.MSRST
	CAIE T1,.MSR20
	 ERROR PARSE1,<Drive is not an RP20>
SETDV1:	HRROI T1,[ASCIZ /Enter decimal serial number: /]
	CALL CMDINI
	MOVEI T1,[FLDDB.(.CMNUM,,^D10)]
	CALL COMNDX
	 ERROR SETDV1,<Invalid decimal number>
	MOVEM T2,SERNO
	MOVE T1,RNUBLK+.MSRCH
	STOR T1,DOP%C2,T4	;CHANNEL
	MOVE T1,RNUBLK+.MSRCT
	STOR T1,DOP%K2,T4	;CONTROLLER
	MOVE T1,RNUBLK+.MSRUN
	STOR T1,DOP%U2,T4	;UNIT
	MOVEI T1,3		;SECTOR THREE IS FOR THE SERIAL NUMBER
	TXO T1,<FLD .DOPPU,DOP%AT> ;RELATIVE ADDRESSES
	MOVEI T2,1000		;LENGTH OF BLOCK
	TXO T2,DOP%PS+DOP%NF	;TRUE PHYSICAL SECTORS, CHAN/CTL/UNIT
	MOVEI T3,BATBUF
	DSKOP
	 JUMPN T1,[JSERR
		JRST RESTRT]
	MOVEI T1,.MSR20
	IORI T1,400		;128 SERIES DRIVE AS IN PHYUBB-2
	LSH T1,20	
	MOVEM T1,BATBUF+0	;SAVE HIGH ORDER SERIAL NUMBER
	MOVE T1,SERNO
	MOVEM T1,BATBUF+1	;SAVE LOW ORDER SERIAL NUMBER
	MOVEI T1,3		;BACK TO SECTOR 3
	TXO T1,<FLD .DOPPU,DOP%AT> ;RELATIVE ADDRESSES
	TXO T2,DOP%WR		;WRITE
	DSKOP			;WRITE IT BACK
	 JUMPN T1,[JSERR
		JRST RESTRT]
	JRST RESTRT	
>				;END REPEAT 0
;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,[FLDDB.(.CMNUM,,^D10)]
	CALL COMNDX		;GET DECIMAL 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
	SETZM HBUF		;CLEAR THE HELP BUFFER
	MOVE T1,[HBUF,,HBUF+1]
	BLT T1,HBUF+<NHBUFP*1000>-1
CREAT3:	HRROI T1,[ASCIZ /Number of pages to allocate for swapping? /]
	CALL CMDINI		;PRINT PROMPT
	RADIX 10
	FORS. (DEFP4S,<NUMSWP>,<
		MOVEI T1,[FLDDB.(.CMNUM,CM%SDH,^D10,<0 for no swapping space or
   a decimal number between 2000 and 40000>,NUMSWP)]>)
	RADIX 8
	CALL COMNDX
	 SKIPA			;GIVE ERROR IF PARSE FAILED
	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
	RADIX 10
	FORS. (DEFPFS,<NUMFES>,<
		MOVEI T1,[FLDDB.(.CMNUM,CM%SDH,^D10,<0 for no front end file system or
   a decimal number between 250 and 10000>,NUMFES)]>)
	RADIX 8
	CALL COMNDX
	 SKIPA			;GIVE ERROR IF PARSE FAILED
	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,FCNBLK		;SETUP SPECIAL FUCNTION BLOCK
	CALL COMNDX		;GET RESPONSE
	 ERROR CREAT5,<Invalid owner name string>
	HRROI T2,ATMBUF		;RESPONSE
	HRROI T1,OWNRID		;COPY TO OWNER ID
	MOVEI T3,^D14		;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
CREAT6:	HRROI T1,[ASCIZ /Is this a system structure for startup? /]
	CALL YESNO
	JUMPE T1,[SETZ T2,	;NO, DON'T NEED CPU SERIAL NUMBER
		  JRST CRT6A]
CREAT7:	HRROI T1,[ASCIZ /Serial number of CPU started from this structure? /]
	CALL CMDINI		;PRINT PROMPT
	MOVEI T1,[FLDDB.(.CMNUM,CM%SDH,^D10,<Serial number of CPU or carriage return for this CPU>,0)]
	CALL COMNDX
	 ERROR CREAT6,<Invalid decimal number>
	MOVEM T2,CPUSER		;save serial number
	CALL CMDEOL		;confirmed?
	 JRST CREAT7		;no, try again
	SKIPGE CPUSER		;non negitive number given?
	 JRST [	TMSG <?Serial number must be non-negitive> ;no, write a message
		JRST CREAT7]	;try again
	SKIPE CPUSER		;yes, was a serial number given?
	 JRST CRT6A		;yes, have serial number, don't get this APR
	MOVEI T1,.APRID	;want APR serial number
	GETAB			;get it
	 ERROR RESTRT,<Couldn't get APR serial number>
	MOVEM T1,CPUSER		;store serial number

;NOW TRY TO INIT/MOUNT THE STRUCTURE

CRT6A:	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, CONTROLLER, AND UNIT NUMBERS FOR A DRIVE.
; C(Q1) := POINTER TO 3-WORD DRIVE INFO BLOCK
; C(Q2) := NUMBER OF UNITS

GETUNT:	HRROI T2,[ASCIZ /DECIMAL Channel, Controller, and Unit number: /]
	HRROI T1,TMPBUF
	MOVEI T3,0
	SOUT
	MOVEI Q2,1		;ONE UNIT
	JRST GETUN1		;JOIN COMMON CODE

GETUNI:	HRROI T2,[ASCIZ /DECIMAL Channel, Controller, and Unit numbers for logical unit /]
	HRROI T1,TMPBUF		;TEMP BUFFER
	MOVEI T3,0
	SOUT
	HRRZ T2,MNTBLK+.MSINU	;CALC UNIT #
	SUB T2,Q2
	MOVEI T3,^D10		;DECIMAL
	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,[FLDDB.(.CMCMA)]
	CALL COMNDX
	 ERROR GETUN1,<Comma expected between channel and controller numbers>
	CALL SPCNUM		;GET CONTROLLER NUMBER
	 JRST GETUN1		;INVALID
	CAML T2,[-1]		;VERIFY NOT TOO SMALL
	CAILE T2,17		;OR TOO LARGE
	 ERROR GETUN1,<Controller number not in range -1 to 15>
	MOVEM T2,.MSICT(Q1)	;STORE IT
	MOVEI T1,[FLDDB.(.CMCMA)]	;WANT ANOTHER COMMA
	CALL COMNDX		;GET IT
	 ERROR GETUN1,<Comma expected between controller and unit numbers>
	CALL SPCNUM		;GET UNIT NUMBER
	 JRST GETUN1		;INVALID NUMBER
	SKIPL T2		;VERIFY RANGE
	CAILE T2,377		;TO BE REASONABLE
	 ERROR GETUN1,<Unit number not in range 0-255>
	MOVEM T2,.MSIUN(Q1)	;STORE IT
	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,^D10		;SETUP RADIX
	MOVEM T1,FCNBLK+.CMDAT
	SETZM FCNBLK+.CMDEF	;NO DEFAULT
	MOVEI T1,FCNBLK		;T2/ FUNCTION BLOCK
	CALL COMNDX
	 SKIPA			;FAILED
	RETSKP			;GOOD RETURN
	TMSG <
?Invalid decimal 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
	MOVSI T1,-UNTYTN	;GET READY FOR SEARCH
	LDB T2,[POINTR (Q2,MS%TYP)]	;GET THIS UNIT'S TYPE
CNFIN4:	HLRZ T3,UNTYTB(T1)	;GET NEXT TABLE ENTRY
	CAME T2,T3		;FOUND THE UNIT TYPE YET?
	AOBJN T1,CNFIN4		;NO, KEEP LOOKING
	HRRO T2,UNTYTB(T1)	;CREATE POINTER TO TYPE STRING
	MOVE T1,Q1		;GET OUTPUT POINTER
	MOVEI T3,0
	SOUT			;DUMP IT
	MOVE T2,RNUBLK+.MSRCH	;GET CHANNEL NUMBER
	MOVE T3,[NO%LFL+<6,,^D10>] ;DECIMAL OUTPUT FILLED IN 6 COLUMNS
	NOUT			;CONVERT TO NUMBER
	 JFCL
	MOVE T2,RNUBLK+.MSRCT	;GET CONTROLLER NUMBER
	MOVE T3,[NO%LFL+<^D11,,^D10>] ;DECIMAL FILLED IN 11 COLUMNS
	NOUT			;TYPE IT
	 JFCL
	MOVE T2,RNUBLK+.MSRUN	;GET UNIT NUMBER
	MOVE T3,[NO%LFL+<^D9,,^D10>] ;DECIMAL FILLED IN 9 COLUMNS
	NOUT
	 JFCL
	MOVEI T3,4
	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

; NEXT PAGE .....
; ....
	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/RP04/]	;1 - RP04
	5,,[ASCIZ/RP05/]	;5 - RP05
	6,,[ASCIZ/RP06/]	;6 - RP06
	7,,[ASCIZ/RP07/]	;7 - RP07
	11,,[ASCIZ/RM03/]	;11 - RM03
	24,,[ASCIZ/RP20/]	;24 - RP20
	27,,[ASCIZ/RA80/]	;27 - RA80
	30,,[ASCIZ/RA81/]	;30 - RA81
	31,,[ASCIZ/RA60/]	;31 - RA60
	0,,[ASCIZ/UNK /]	;LAST ENTRY IS CATCH-ALL FOR UNKNOWNS

	UNTYTN==.-UNTYTB-1	;NUMBER OF REAL ENTRIES

;HELP MESSAGE HEADER

HHDR:	ASCIZ "

Triple of decimal numbers from one of the following:

Type  Channel  Controller  Unit  Structure name      Logical unit
----  -------  ----------  ----  --------------      ------------

"
;COMMON ROUTINE FOR CHECK COMMAND

.CHECK:	MOVEI T1,[FLDDB.(.CMKEY,,CKTAB)]	;SECONDARY KEYTABLE
	CALL COMNDX
	 ERROR PARSE1,<Not a CHECKD command>
	HRRZ T1,(T2)		;GET DISPATCH
	JRST (T1)		;PROCESS

;CHECK COMMAND KEYWORD TABLE

CKTAB:	XWD CKSIZ,CKMAX
	TB (.BITAB,BITTABLE)	;CHECK BITTABLE CONSISTENCY
	TB (.DIREC,DIRECTORY)	;CHECK DIRECTORY CONSISTENCY

CKSIZ=.-CKTAB-1
CKMAX=CKSIZ
;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
;BAT BLOCK EDITOR

.EDIT:	HRROI T1,[ASCIZ /BAT BLOCKS FOR/]
	CALL CMDNOI		;TYPE THE NOISE
	CALL CONFRM		;GET THE STRUCTURE
	CALL PSCHK		;SEE IF IT WAS PS
	 CALL XMNT		; EXCLUSIVE MOUNT IT
	CALL SETSTR		;SET UP INFO WE NEED
	CALL HOMEIN		;READ HOME BLOCKS
	 JRST RESTRT		; ONLY ON AN ERROR
	CALL BATIN		;READ USEFUL BAT BLOCK INFO
	SETOM BEMFLG		;INDICATE WE ARE HERE
	JRST BATWRK		;EDIT THE BAT BLOCKS, PLEASE
;ENABLE / DISABLE

.DSABL:	SETZM ENAFLG		;INDICATE THIS IS A DISABLE
	JRST ENABL1

.ENABL:	SETOM ENAFLG		;INDICATE THIS IS AN ENABLE

ENABL1:	MOVEI T1,[FLDDB.(.CMKEY,,ENTAB)]	;SECONDARY KEYTABLE
	CALL COMNDX
	 ERROR PARSE1,<Not a CHECKD command>
	HRRZ T1,(T2)		;GET DISPATCH
	JRST (T1)		;PROCESS

;ENABLE COMMAND KEYWORD TABLE

ENTAB:	XWD ENASIZ,ENAMAX
	TB (.AUTOS,AUTOMATIC-STARTUP) ;ENABLE SYSTEM STRUCTURE
	TB (.BATUP,BAT-BLOCK-DELETE)
	TB (.BOOTP,BOOT-PARAMETERS)
	TB (.DCARE,DON'T-CARE,CM%INV)
	TB (.ECC,ECC-ERROR-MARKING)
	TB (.UNLMT,LARGE-DIRECTORIES)
	TB (.LGSTR,LOGIN-STRUCTURE) ;[7.1112]
	TB (.PSENC,PASSWORD-ENCRYPTION)
	TB (.SOFT,SOFT-ERROR-MARKING)
	TB (.WRITE,WRITE-VERIFICATION)
ENASIZ=.-ENTAB-1
ENAMAX=ENASIZ
;ENABLE STRUCTURE FOR AUTOMATIC STARTUP BY SETTING CPU SERIAL NUMBER INTO
; THE HOME BLOCK(S)

.AUTOS:	HRROI T1,[ASCIZ /FROM STRUCTURE/]
	CALL CMDNOI		;NOISE WORDS
	CALL CONFRM		;GET STRUCTURE AND CONFIRM
	CALL SETSTR		;SET UP WORKING STRUCTURE INFO
	CALL HOMEIN		;READ HOME BLOCKS OF FIRST PACK
	 JRST RESTRT		;BAD BLOCKS
	SKIPN T2,ENAFLG		;IS THIS DISABLE?
	JRST AUTOS2		;YES, DON'T ASK FOR CPU SERIAL NUMBER
AUTOS1:	HRROI T1,[ASCIZ /Serial number of CPU to startup? /]
	CALL CMDINI		;PRINT PROMPT
	MOVEI T1,[FLDDB.(.CMNUM,CM%SDH,^D10,<Serial number of CPU or carriage return for this CPU>,0)]
	CALL COMNDX
	 ERROR AUTOS1,<Invalid decimal number>
	JUMPN T2,AUTOS2		;HAVE SERIAL NUMBER
	MOVE T1,[SIXBIT /APRID/]
	SYSGT			;GET CPU SERIAL NUMBER
	MOVE T2,T1		;USE T2 SINCE JUMPN ABOVE USES T2
AUTOS2:	MOVEM T2,HOMARG+.MSHVL	;STORE SERIAL NUMBER
	HRROI T1,STRNAM		;GET POINTER TO STRUCTURE NAME
	MOVEM T1,HOMARG+.MSHNM	;STORE STRUCTURE BEING MODIFIED
	MOVEI T1,HOMSER		;WORD WE WANT TO MODIFY
	MOVEM T1,HOMARG+.MSHOF
	SETOM HOMARG+.MSHMK	;CHANGING ENTIRE WORD
	DMOVE T1,[EXP <4,,.MSHOM>,HOMARG]
	MSTR			;MODIFY HOME BLOCK
	 ERCAL JSERR0		;FAILED. PRINT REASON
	JRST RESTRT		;RESTART
;SET/CLEAR BATBLOCK ENTRY DELETE FLAG

.BATUP:	HRROI T1,[ASCIZ /ON DISK VERIFICATION/]
	CALL CMDNOI		;NOISE WORDS
	MOVEI T1,[FLDDB.(.CMCFM)];CONFIRMATION ONLY
	CALL COMNDX
	 ERROR PARSE1,<Invalid command confirmation>
	MOVE T1,ENAFLG		;GET ENABLE/DISABLE FLAG
	MOVEM T1,BATFLG		;SAVE THE STATUS
	JRST RESTRT
;Enable/Disable BOOT parameters


BPTAB:	XWD BPSIZ,BPSIZ
	TF (BT%HOD,HALT-ON-DUMP-ERRORS)
	TF (BT%RPM,READ-PARAMETERS)
	BPSIZ=.-BPTAB-1
	;Flags for parameters


.BOOTP:	HRROI T1,[ASCIZ /FOR STRUCTURE/]
	CALL CMDNOI		;NOISE WORDS
	CALL GETSTR		;GET STRUCTURE NAME
	CALL STSTRN		;SETUP STRUCTURE DATA
	SETZM P6		;ZERO MASK WORD
	HRROI T1,[ASCIZ/PARAMETER/]
	CALL CMDNOI		;NOISE WORDS
PARMLP:	MOVEI T1,[FLDDB.(.CMKEY,,BPTAB,,,FDCC)]
	CALL COMNDX
	 ERROR PARSE1,<Not a valid parameter>
	HRRZS T3		;Get right-half only
	LOAD T3,CMFNC,0(T3)	;Good parse, get our function code
	CAIE T3,.CMKEY		;Was it a keyword?
	JRST NOTKEY		;No, try for something else
	HRRZ T2,(T2)		;Get pointer to the bit
	TDO P6,(T2)		;Set the bit
	JRST PARMLP		;Back for more
NOTKEY:	CAIN T3,.CMCMA		;Comma?
	JRST PARMLP		;Yes, back for more
	CAIE T3,.CMCFM		;Did he confirm?
	 ERROR PARSE1,<Not a valid parameter>


BPSTOR:	CALL HOMEIN		;READ HOME BLOCKS OF FIRST PACK
	 JRST RESTRT		;BAD BLOCKS
	MOVE T1,BATBUF+HOMBTF	;Get existing bits
	TDO T1,P6		;Assume we are setting
	SKIPN ENAFLG		;Are we setting?
	TDZ T1,P6		;No, so clear
	MOVEM T1,HOMARG+.MSHVL	;Store bits
	HRROI T1,STRNAM		;GET POINTER TO STRUCTURE NAME
	MOVEM T1,HOMARG+.MSHNM	;STORE STRUCTURE BEING MODIFIED
	MOVEI T1,HOMBTF		;WORD WE WANT TO MODIFY
	MOVEM T1,HOMARG+.MSHOF
	SETOM HOMARG+.MSHMK	;CHANGING ENTIRE WORD
	DMOVE T1,[EXP <4,,.MSHOM>,HOMARG]
	MSTR			;MODIFY HOME BLOCK
	 ERCAL JSERR0		;FAILED. PRINT REASON
	JRST RESTRT		;RESTART
;LIMIT/UNLIMIT (NUMBER OF FILES PER DIRECTORY ON STRUCTURE

.UNLMT:	MOVX T1,MS%LIM		;GET THE BIT TO ASSUME DISABLE (LIMIT)
	SKIPE ENAFLG		;WAS IT ENABLE
	SETZ T1,		;YES, CLEAR THE BIT INSTEAD
	STKVAR <NEWVAL>
	MOVEM T1,NEWVAL
	HRROI T1,[ASCIZ /ON STRUCTURE/]
	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 /[Large directories were allowed]
/]
	TXNE T2,MS%LIM		;ANNOUNCE OLD VALUE
	HRROI T1,[ASCIZ /[Large directories were not allowed]
/]
	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
;SET/CLEAR SOFT ERROR DURING VERIFY PHASE MARKING

.SOFT:	CALL SFTECC		;DO THE WORK
	MOVEM T1,SOFTFL		;SAVE THE STATUS
	JRST RESTRT

;HERE TO ENABLE /DISABLE ECC ERROR COUNTING

.ECC:	CALL SFTECC		;DO THE WORK
	MOVEM T1,ECCFLG		;SAVE THE STATUS
	JRST RESTRT

SFTECC:	HRROI T1,[ASCIZ /DURING VERIFICATION OF DISK SURFACE/]
	CALL CMDNOI
	MOVEI T1,[FLDDB.(.CMCFM)]
	CALL COMNDX
	 ERROR PARSE1,<Invalid command confirmation>
	MOVE T1,ENAFLG		;GET ENABLE/DISABLE FLAG
	RET
;ENABLE/DISABLE WRITE VERIFICATION ON DISK

;CHOICES ARE ENABLE/DISABLE WRITE OF SWAP/DATA/BOTH/NONE ON STR FOO

.WRITE:	STKVAR <BITMSK,BITVAL>	;MASK OF BITS TO CHANGE, NEWVALUE
	HRROI T1,[ASCIZ /OF/]
	CALL CMDNOI		;NOISE WORDS
	MOVEI T1,[FLDDB. (.CMKEY,,WRTTAB)] ;GET KEYWORD TABLE
	CALL COMNDX		;PARSE THE NEXT KEYWORD
	 ERROR PARSE1,<Not a CHECKD command>
	HRRZ T1,(T2)		;GET DISPATCH
	JRST (T1)		;AND GO THERE

WRTTAB:	XWD WRTSIZ,WRTSIZ
	TB (.DATA,DATA)		;DATA SPACE
	TB (.SWAP,SWAPPING)	;SWAP SPACE
WRTSIZ=.-WRTTAB-1		;SIZE OF THE TABLE

.SWAP:	MOVX T1,MS%RWS		;READ AFTER WRITE FOR SWAP
	SKIPA			;INTO COMMON CODE
.DATA:	MOVX T1,MS%RWD		;READ AFTER WRITE FOR DATA
	MOVEM T1,BITMSK		;SAVE FOR LATER
	AND T1,ENAFLG		;SEE IF WE ARE SETTING FUNCTIONALITY
	MOVEM T1,BITVAL		;REMEMBER ENABLE/DISABLE
	HRROI T1,[ASCIZ /ON STRUCTURE/]
	CALL CMDNOI		;NOISE WORDS
	CALL CONFRM		;GET STRUCTURE AND CONFIRM
	CALL SETSTR		;SET UP STRUCTURE
	CALL HOMEIN		;READ HOME BLOCKS OF STR
	 JRST RESTRT		;ON AN ERROR, GO BACK TO PROMPT
	MOVE T1,BITMSK		;MASK OF BIT TO CHANGE
	MOVEM T1,HOMARG+.MSHMK	;ONLY THIS BIT ALLOWED
	MOVE T1,BITVAL		;GET STATE OF BIT
	MOVEM T1,HOMARG+.MSHVL	;VALUE TO USE FOR FLAG
	HRROI T1,STRNAM		;POINTER TO STRUCTURE NAME
	MOVEM T1,HOMARG+.MSHNM
	MOVEI T1,HOMFLG		;WORD TO MODIFY
	MOVEM T1,HOMARG+.MSHOF
	DMOVE T1,[ XWD 4,.MSHOM
		   HOMARG]	;SET UP HEADER
	MSTR			;MODIFY THE HOME BLOCKS
	 ERCAL JSERR0		;REASON FOR FAILURE
	JRST RESTRT		;ALL DONE WITH THIS
;ENABLE/DISABLE STRUCTURE FOR DON'T CARE IF DISK PORTED TO UNKNOWN SYSTEM


.DCARE:	STKVAR <BITMSK,BITVAL>	;MASK OF BITS TO CHANGE, NEWVALUE
	SETOM BITMSK		;THE WHOLE WORD IS USED
	MOVE T1,[SIXBIT/DONOCA/];GET THE NAME TO USE
	AND T1,ENAFLG		;SEE IF WE ARE SETTING THE FUNCTION
	MOVEM T1,BITVAL		;REMEMBER ENABLE/DIABLE
	HRROI T1,[ASCIZ /IF PORTED TO UNKNOWN SYSTEM ON STRUCTURE/]
	CALL CMDNOI		;NOISE WORDS
	CALL CONFRM		;GET STRUCTURE AND CONFIRM
	CALL SETSTR		;SET UP STRUCTURE
	CALL HOMEIN		;READ HOME BLOCKS OF STR
	 JRST RESTRT		;ON AN ERROR, GO BACK TO PROMPT
	MOVE T1,BITMSK		;MASK OF BIT TO CHANGE
	MOVEM T1,HOMARG+.MSHMK	;ONLY THIS BIT ALLOWED
	MOVE T1,BITVAL		;GET STATE OF BIT
	MOVEM T1,HOMARG+.MSHVL	;VALUE TO USE FOR FLAG
	HRROI T1,STRNAM		;POINTER TO STRUCTURE NAME
	MOVEM T1,HOMARG+.MSHNM
	MOVEI T1,HOMDCF		;WORD TO MODIFY
	MOVEM T1,HOMARG+.MSHOF
	DMOVE T1,[ XWD 4,.MSHOM
		   HOMARG]	;SET UP HEADER
	MSTR			;MODIFY THE HOME BLOCKS
	 ERCAL JSERR0		;REASON FOR FAILURE
	JRST RESTRT		;ALL DONE WITH THIS
;.[7.1112]
;
; .LGSTR:
;
; This routine implements the ENABLE/DISABLE LOGIN-STRUCTURE command.
; It either enters a CPU serial number into, or removes a serial
; number from words HOMLS1, HOMLS2. HOMLS3, or HOMLS4 of a given
; structure's home blocks.
; Call:
;	JRST .LGSTR
; with:
;	ENAFLG/   0 to remove a serial number, -1 to add
; Returns:
;	To lable RESTRT, always
;
MINAPR==^D1025			;Minimum CPU serial number
MAXAPR==^D4095			;Maximum CPU serial number
.LGSTR:	STKVAR <CPUNUM>		;For saving serial number
	HRROI T1,[ASCIZ /FOR STRUCTURE/]
	CALL CMDNOI		;Noise words
	CALL GETSTR		;Get the structure name
	HRROI T1,[ASCIZ/FOR CPU/]
	CALL CMDNOI		;Parse guide words
	MOVEI T1,[FLDDB.(.CMNUM,CM%SDH,^D10,<CPU serial	number>,,[FLDDB.(.CMCFM,CM%SDH,,<or carriage for local CPU>,,)])]
	CALL COMNDX
	 ERROR AUTOS1,<Invalid decimal number>
	HRRZS T3		;Get FDB used
	LDB T1,[POINT 9,.CMFNP(T3),8] ;Get function code
	CAIE T1,.CMCFM		;Just confirmed?
	IFSKP.			;Yes...
	  HRRZI T1,.APRID	;Get processor serial number
	  GETAB%		; from system tables
	   JSERR		;Failed?
	  MOVEM T1,CPUNUM	;Save serial number
	ELSE.			;Got a decimal number
	  MOVEM T2,CPUNUM	;Save CPU serial number
	  CALL CMDEOL		;Confirm command
	   JRST PARSE1		;Failed
	  MOVE T2,CPUNUM	;Fetch serial number'
	  CAIL T2,MINAPR	;Too small?
	  CAILE T2,MAXAPR	;Or too large?
	  IFNSK.		;Yes...
	    ERROR (RESTRT,<CHECKD: CPU serial number must be between 1025 and 4095>)
	  ENDIF.
	ENDIF.			;Join common code
	CALL STSTRN		;()Set up structure info
	CALL HOMEIN		;()Read home block into
	 JRST RESTRT		;Failed. Do next command
	MOVSI T4,-LGSLEN	;Number of home block words
	HRRI T4,BATBUF+HOMLS1	;Address of first word to check
;
; If we are enabling, scan through the Login Structure words in the Home
; Block and see if the given serial number is already there.
;
	SKIPN ENAFLG		;Enabling?
	IFSKP.			;If yes...
	  MOVE T1,T4		;Get AOBJN pointer
ENALOP:	  HLRZ T2,(T1)		;Get LH of word
	  HRRZ T3,(T1)		;And right half of word
	  CAME T2,CPUNUM	;Is this the requested number
	  CAMN T3,CPUNUM	;Or is this?
	  JRST RESTRT		;Yes. Then it's been done!
	  AOBJN T1,ENALOP	;Check all words
	ENDIF.			;
;
; Do the actual DISABLE or ENABLE
;
LGSLOP:	MOVE T1,(T4)		;Get home block word to check
	HLRZ T2,T1		;Get LH of word T2
	HRRZ T3,T1		;And RH in T3
	SKIPN ENAFLG		;Are we enabling?
	IFSKP.			;If yes...
	  SKIPE T2		;Is LH available?
	  IFSKP.		;If so, then use it
	    MOVE T2,CPUNUM	;Get number to store
	    HRL T1,T2		;Make new word
	    JRST LGSHOM		;Go place in home blocks
	  ENDIF.		;
	  SKIPE T3		;Is RH available
	  IFSKP.		;If so, then use it
	    MOVE T3,CPUNUM	;Get CPU to use
	    HRR T1,T3		;Make new home block word
	    JRST LGSHOM		;Go stick it in
	  ENDIF.		;
	ELSE.			;If disabling...
	  CAME T2,CPUNUM	;Does LH match CPU number?
	  IFSKP.		;If so, clear out LH
	    HRRZS T1		;Zero LH of home block word
	    JRST LGSHOM		;Go write new word
	  ENDIF.		;
	  CAME T3,CPUNUM	;Does RH match CPU number?
	  IFSKP.		;If so, clear out RH
	    HLLZS T1		;Zero RH of home block word
	    JRST LGSHOM		;Go write new word
	  ENDIF.		;
	ENDIF.			;
	AOBJN T4,LGSLOP		;Loop through all home block words
	SKIPE ENAFLG		;Are we enabling
	ERROR (RESTRT,<CHECKD: No space in Home Block for serial number>) ;Enabling
	ERROR (RESTRT,<CHECKD: Serial number not found in Home Block>) ;Disabling
;
; T4 contains the home block word to change, T1 contains the new
; contents of that word.
;

LGSHOM:	MOVEM T1,HOMARG+.MSHVL	;Store new word in MSTR% argument block
	HRRZS T4		;Get address of home block word
	SUBI T4,BATBUF		;Get offset into home blocks
	MOVEM T4,HOMARG+.MSHOF	;Save in MSTR% block
	SETOM HOMARG+.MSHMK	;Mask of bits to change in word
	MOVE T1,STRDEV		;Get device designator of structure
	MOVEM T1,HOMARG+.MSHNM	;Stick in MSTR% argument block
	MOVE T1,[4,,.MSHOM]	;Length of arg block,,MSTR% function code
	MOVEI T2,HOMARG		;Address of arg block
	MSTR%			;Write the new home block word
	 ERCAL JSERR0		;Failed. Print error
	JRST RESTRT		;Finsihed
;ENABLE/DISABLE PASSWORD ENCRYPTION


.PSENC:	STKVAR <BITMSK,BITVAL>	;MASK OF BITS TO CHANGE, NEWVALUE
	MOVX T1,MS%CRY		;GET PASSWORD ENCRYPTION BIT
	MOVEM T1,BITMSK		;SAVE FOR LATER
	AND T1,ENAFLG		;SEE IF WE ARE SETTING FUNCTIONALITY
	MOVEM T1,BITVAL		;REMEMBER ENABLE/DISABLE
	HRROI T1,[ASCIZ /ON STRUCTURE/]
	CALL CMDNOI		;NOISE WORDS
	CALL CONFRM		;GET STRUCTURE AND CONFIRM
	CALL SETSTR		;SET UP STRUCTURE
	CALL HOMEIN		;READ HOME BLOCKS OF STR
	 JRST RESTRT		;ON AN ERROR, GO BACK TO PROMPT
	MOVE T1,BITMSK		;MASK OF BIT TO CHANGE
	MOVEM T1,HOMARG+.MSHMK	;ONLY THIS BIT ALLOWED
	MOVE T1,BITVAL		;GET STATE OF BIT
	MOVEM T1,HOMARG+.MSHVL	;VALUE TO USE FOR FLAG
	HRROI T1,STRNAM		;POINTER TO STRUCTURE NAME
	MOVEM T1,HOMARG+.MSHNM
	MOVEI T1,HOMFLG		;WORD TO MODIFY
	MOVEM T1,HOMARG+.MSHOF
	DMOVE T1,[ XWD 4,.MSHOM
		   HOMARG]	;SET UP HEADER
	MSTR			;MODIFY THE HOME BLOCKS
	 ERCAL JSERR0		;REASON FOR FAILURE
	JRST RESTRT		;ALL DONE WITH THIS
;EXIT (TO MONITOR)

;USER WANTS TO QUIT.  GET CONFIRMATION AND EXIT

.EXIT:	HRROI T1,[ASCIZ /TO MONITOR/]
	CALL CMDNOI
	MOVEI T1,[FLDDB. (.CMCFM)] ;T1/ADDRESS OF FUNCTION DESCRIPTOR BLOCK
	CALL COMNDX		;GET CONFIRMATION
	 ERROR PARSE1,<Invalid command confirmation> ;NO
	CALL RESET
	JRST QUIT
;FILE-DDT

;USER WISHES TO GET INTO THE ABSOLUTE DISK EDITOR, AND DO SOME MUNGING

.FILDT:	CALL FILDTX		;CALL THE REAL ROUTINE
	 JFCL			; IGNORE ANY ERRORS
	JRST PARSE1		; AND ON WITH THE WORK

FILDTX:	HRROI T1,[ASCIZ /THE DISKS/] ;NOISE WORDS
	CALL CMDNOI
	MOVEI T1,[FLDDB. (.CMCFM)]
	CALL COMNDX		; GET THE END OF LINE CONFIRM
	 ERROR R,<Invalid command confirmation>
	MOVX T1,GJ%OLD!GJ%SHT	; SHORT FORM JFN, OLD FILE
	HRROI T2,[ASCIZ /SYS:FILDDT.EXE/]
	CALL GETFRK
FILDTE:	 ERROR R,<Run of FILDDT failed>
	CALL RUNFRK
	 JRST FILDTE
	RETSKP
RUNFRK: MOVE T1,HANDLE		;GET THE FORK NUMBER
	SETZ T2,		;START AT NORMAL ADDRESS
	SFRKV			;DO IT.
	 ERJMP R
	WFORK			;WAIT FOR IT TO STOP
	 ERJMP R
	RFSTS			;GET STATUS AND PC OF FORK
	LDB T1,[POINTR (T1,RF%STS)]; STATUS CODE
	CAIE T1,3		;FORCED TERMINATION?
	JRST RUNFIN		;NO, OK
	TMSG <
?Error at PC >
	ANDI T2,-1		;PC ONLY
	MOVX T3,NO%LFL!NO%ZRO!<6,,10>
	CALL TTNOUT		;TYPE THE NUMBER AS A PC
	TMSG <: >
	MOVEI T1,.PRIOU
	HRLO T2,HANDLE
	SETZ T3,
	ERSTR			;DO IT
	 RET
	 RET
	TMSG <
>
	RETSKP

RUNFIN:	MOVE T1,HANDLE
	KFORK
	 ERJMP .+1
	SETZM HANDLE		;DONE
	RETSKP

GETFRK:	GTJFN			;GET A JFN ON THE FILE
	 ERJMP R
	MOVEM T1,RUNJFN		;SAVE FOR LATER
	MOVX T1,CR%CAP		;SET UP BITS TO KEEP CAPABILITIES
	CFORK			;CREATE AN INFERIOR
	 ERJMP R
	MOVEM T1,HANDLE		;SAVE THE HANDLE

	MOVS T1,T1		;PUT IN LEFT HALF
	HRR T1,RUNJFN		;GET JFN OF THE FILE
	GET			;READ IN THE PROG INTO THE FORK
	 ERJMP R
	SETZM RUNJFN		;CLEAR JFN SINCE NO LONGER OURS
	RETSKP			;RETURN
;PUSH (JUST LIKE FILDDT, BUT TO THE EXEC

.PUSH:	CALL PUSHX
	 JFCL
	JRST PARSE1

PUSHX:	HRROI T1,[ASCIZ /TO EXEC LEVEL/]
	CALL CMDNOI
	MOVEI T1,[FLDDB. (.CMCFM)] ;T1/ ADDRESS OF FDB
	CALL COMNDX
	 ERROR R,<Invalid command confirmation> ;NO. PRINT ERROR
PUSHEN:	MOVX T1,GJ%OLD!GJ%SHT
	HRROI T2,[ASCIZ /SYSTEM:EXEC.EXE/]
	CALL GETFRK
PUSHER:	 ERROR R,<Push to a new EXEC failed>
	CALL RUNFRK		; RUN IT
	 JRST PUSHER
	RETSKP

;HERE FOR AUTO PUSH

APUSH:	CALL DOPUSH		;DO THE REAL WORK
	DEBRK			;AND RETURN

DOPUSH:	SAVET			;SAVE THE TEMP AC'S
	TMSG <
[Pushing to a new EXEC]
>
	CALL PUSHEN		;PUSH TO EXEC NOW
	 RET			;RETURN TO CALLER, IGNORE ANY ERRORS
	RET
;HELP

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

.HELP:	MOVEI T1,[FLDDB. (.CMCFM)] ;T1/ ADDRESS OF FDB
	CALL COMNDX		;GET CONFIRMATION
	 ERROR PARSE1,<Invalid command confirmation> ;NO. PRINT ERROR
	MOVX T1,GJ%OLD!GJ%SHT!GJ%IFG	;[79]GET A JFN FOR THE HELP FILE
	HRROI T2,[ASCIZ /HLP:CHECKD.HLP/]
	GTJFN
	 JRST [	PNTERR (<GTJFN for the help file failed>)
		JRST PARSE1]
	MOVEM T1,INJFN		;SAVE THE JFN NUMBER
	HRRZ T1,T1		;[79]
	MOVE T2,[7B5!OF%RD]	;READ THE FILE 7 BITS AT A TIME
	OPENF
	 JRST [	PNTERR (<OPENF for the help file (HLP:CHECKD.HLP) failed>)
		JRST PARSE1]
HELP1:	HRRZ T1,INJFN		;[79] GET JFN FOR INPUT
	BIN			;READ THE BYTE
	 ERJMP HELP2		; DONE, GO CLEAN UP
	MOVE T1,T2		;MOVE THE BYTE TO ANOTHER AC
	PBOUT			; SO WE CAN OUTPUT IT.
	JRST HELP1		;AND LOOP TILL THE END OF THE FILE

HELP2:	MOVE T1,INJFN
	CLOSF
	 JRST [	PNTERR (<CLOSF for the help file failed>)
		JRST PARSE1]
	JRST PARSE1
;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
		SETZM	WRTLPF	;don't allow system to come up
		JRST RESTRT]
	RET			;RETURN
;RECONSTRUCT (ROOT-DIRECTORY)

;USER WANTS 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,[FLDDB.(.CMKEY,,RECTAB)] ;SECONDARY KEYTABLE
	CALL COMNDX
	 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,ALINAM		;[2] GET STRUCTURE ALIAS
	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,ALINAM		;[2] GET STRUCTURE ALIAS
	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,[FLDDB.(.CMFIL)] ;T1/ADDRESS OF FUNCTION DESCRIPTOR BLOCK
	CALL COMNDX		;GET INPUT FILE SPEC, DEFAULTING TO LOST-PAGES.BIN
	 JRST [	CALL COMNDE	;ERROR, TYPE MESSAGE
		JRST PARSE1]
	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	;get JFN of x-LOST-PAGES.BIN
	MOVEI	T2,T4		;want to put date in T4
	MOVEI	T3,1		;only want internal write date
	RFTAD			;get file's write date
	 ERJMP	[ PNTERR(<Failed to get last write date>)
		  MOVE	T1,INJFN ;get the JFN back
		  RLJFN		;release it
		   JFCL		;don't care about errors
		  JRST	PARSE1]	;return
	GTAD			;get current date and time
	CAMN	T1,[-1]		;system date and time set?
	 JRST	[ HRROI	T1,[ASCIZ/% System date and time not set.  Do you want to continue anyway? /] ;no, build a prompt
		  CALL	YESNO	;get either a YES or a NO
		  JUMPE	T1,PARSE1 ;if "NO", return
		  JRST	RLEAS1]	;if "YES", go ahead and do stuff anyway
	SUBI	T1,2*25253	;subtract 2 hours
	CAMG	T1,T4		;within range?
	JRST	RLEAS1		;yes, go ahead and do stuff
	HRROI	T1,[ASCIZ/% File is more than 2 hours old, do you want to continue anyway? /] ;build a new prompt
	CALL	YESNO		;get either a YES or a NO
	JUMPE	T1,PARSE1	;if "NO", go back to CHECKD>
				;if "YES", fall thru...
RLEAS1:	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
		MOVEI T1,.FHSLF	;this process
		GETER		;get last error
		 ERJMP .+1	;shouldn't happen
		HRRZS	T2	;error number only
		CAIE	T2,DSKX06 ;Invalid disk address?
		JRST RLSPG1	;no, ignore the failure
		JSERR		;yes, write why we failed
		JRST	RLSPG2]	;quit before we totally destroy the pack
	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
	SETZM T2		;DELETE ALL GENERATIONS OF
	DELNF			; THE LOST PAGES FILE
	 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,[FLDDB.(.CMIFI)] ;T1/ADDRESS OF FDB
	CALL COMNDX		;GET FILE TO SCAN
	 JRST [	CALL COMNDE	;ERROR, REPORT 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
;SHOW COMMAND


;SHOW KEYWORD TABLE

SHWTAB:	XWD SHWSIZ,SHWMAX
	TB (.SHWBP,BOOT-PARAMETERS)
	TB (.SHWLG,LOGIN-SERIAL-NUMBERS) ;[7.1112]
SHWSIZ=.-SHWTAB-1
SHWMAX=SHWSIZ


.SHOW:	HRROI T1,[ASCIZ/INFORMATION FOR/]
	CALL CMDNOI
	MOVEI T1,[FLDDB.(.CMKEY,,SHWTAB,,,)]
	CALL COMNDX
	 ERROR PARSE1,<Not a valid topic>
	HRRZ T1,(T2)		;GET DISPATCH
	JRST (T1)		;PROCESS
	;SHOW BOOT-PARAMETERS

ON:	ASCIZ/ON /
OFF:	ASCIZ/OFF/

.SHWBP:	HRROI T1,[ASCIZ /FOR STRUCTURE/]
	CALL CMDNOI		;NOISE WORDS
	CALL CONFRM		;Get structure name and confirm
	CALL STSTRN		;SETUP STRUCTURE DATA
	CALL HOMEIN		;READ HOME BLOCKS OF FIRST PACK
	 JRST RESTRT		;BAD BLOCKS
	MOVE P6,BATBUF+HOMBTF	;Get existing bits
	HRROI T1,[ASCIZ/
  BOOT will /]
	PSOUT
	HRROI T1,[ASCIZ/READ parameters

/]
	TXNN P6,BT%RPM		;Are parameters to be read?
	HRROI T1,[ASCIZ/IGNORE parameters

/]
	PSOUT
	HRROI T1,[ASCIZ/      BOOT PARAMETERS:

/]
	PSOUT
	HRROI T1,[ASCIZ/      PROCEED on dump errors

/]
	TXNE P6,BT%HOD
	HRROI T1,[ASCIZ/      HALT on dump errors

/]
	PSOUT
	JRST RESTRT

;[7.1112]
;
; .SHWLG:
;
; This routine is called to display all the CPUs which can use a given
; structure as a Login Structure. It does this by scanning the Home
; Block words HOMLS1 through HOMLS4. CPU numbers are entered in these
; words by halfwords.
; Call:
;	JRST .SHWLG
; Returns:
;	To label RESTRT, always
;
.SHWLG:	HRROI T1,[ASCIZ /FOR STRUCTURE/]
	CALL CMDNOI		;Noise words
	CALL CONFRM		;Get structure name and confirm
	CALL STSTRN		;Setup structure data
	CALL HOMEIN		;Read Home Block of first pack
	 JRST RESTRT		;Bad blocks
	MOVSI T4,-LGSLEN	;Get length of serial number block
	HRRI T4,BATBUF+HOMLS1	;Make AOBJN pointer to list
	MOVE T1,T4		;Get pointer
SHWLG1:	SKIPE (T1)		;Is a serial number present?
	JRST SHWLG2		;Yes. Go do list
	AOBJN T1,SHWLG1		;Scan entire block
;
; There are no serial numbers in the Home Block. Inform user
;
	TMSG <
>				;<crlf>
	HRROI T1,STRHOM		;Point to name
	PSOUT%			;Primary output
	 ERJMP RESTRT		;Failed
	TMSG <: is not a Login Structure
>				;Finish message
	JRST RESTRT		;Done
;
; Here to display a list of 1 to 8 CPU serial numbers from words
; HOMLS1 through HOMLS4 of the Home Block
;
SHWLG2:	TMSG <
>				;<crlf>
	HRROI T1,STRHOM		;Point to to structure name
	PSOUT%			;Print it
	 ERJMP RESTRT		;Failed
	TMSG  <: is a Login Structure for CPUs:
>
SHWLG3:	HLRZ T2,(T4)		;Get CPU number from LH
	JUMPE T2,SHWLG4		;No number here
	TMSG <	>		;<tab>
	MOVEI T3,^D10		;Decimal
	CALL TTNOUT		;Display it
SHWLG4:	HRRZ T2,(T4)		;Get RH CPU number
	JUMPE T2,SHWLG5		;None here
	TMSG <	>		;<tab>
	MOVEI T3,^D10		;Decimal
	CALL TTNOUT		;Display it
SHWLG5:	AOBJN T4,SHWLG3		;Show entire list
	TMSG <
>				;Finish with <crlf>
	JRST RESTRT		;Done
;HERE TO DISPLAY THE STATUS OF THE KNOWN SWITCHES

.STATU:	HRROI T1,[ASCIZ /OF CHECKD SWITCHES/]
	CALL CMDNOI		;TYPE THE NOISE ON THE USER
	MOVEI T1,[FLDDB. (.CMCFM)]
	CALL COMNDX		;GET A CONFIRMATION
	 ERROR PARSE1,<Invalid command confirmation> ;NO. PRINT ERROR
	TMSG <
CHECKD switch settings at >
	MOVEI T1,.PRIOU		;ON THE TTY
	SETO T2,		;CURRENT DATE AND TIME
	MOVX T3,OT%DAY!OT%FDY!OT%FMN!OT%4YR!OT%DAM!OT%SPA!OT%NSC!OT%12H!OT%TMZ!OT%SCL
	ODTIM
	TMSG <

>
	HRROI T1,[ASCIZ /BAT block entry deletion/]
	MOVE Q1,BATFLG
	CALL STATIT		; OUTPUT THE STATUS
	HRROI T1,[ASCIZ /Soft disk read error inclusion/]
	MOVE Q1,SOFTFL
	CALL STATIT
	HRROI T1,[ASCIZ /ECC disk read error inclusion/]
	MOVE Q1,ECCFLG
	CALL STATIT
	JRST PARSE1

STATIT:	PSOUT
	SKIPE Q1
	JRST [	TMSG < is enabled.
>
		RET]
	TMSG < is disabled.
>
	RET
;HERE TO VERIFY THE SWAP SPACE ON A DISK, OR THE ENTIRE DISK.
;USE THE VALUE OF BATFLG TO DECEIDE IF WE SHOULD ALLOW DELETION
;OF ENTRIES IN THE BAT BLOCKS, BUT ALWAYS ASK ABOUT ADDING THEM.

;DURING THE BAT BLOCK SCAN, SYSBTB IS USED AS A ORDERED PAIR
;LIST OF ALL THE BAT BLOCKS WE HAVE SEEN.

.VERIF:	STKVAR <VDSKFL>
	HRROI T1,[ASCIZ /DISK SURFACE FOR/]
	CALL CMDNOI		;OUT THE NOISE WORDS
	MOVEI T1,[FLDDB.(.CMKEY,,VETAB)]
	CALL COMNDX		;PARSE NEXT WORDS..
	 ERROR PARSE1,<not a CHECKD command>
	HRRZ T1,(T2)		;GET TABLE ADDR
	JRST (T1)		;DISPATCH TO THE ROUTINE.

VETAB:	XWD VESIZ,VEMAX
	TB (.VEDSK,FILE-SYSTEM)	;VERIFY ALL OF DISK SURFACE
	TB (.VESWP,SWAPPING)	;VERIFY ALL OF SWAP SPACE

VESIZ=.-VETAB-1
VEMAX=VESIZ
.VEDSK:	TDZA T1,T1		; 0==> ALL OF DISK
.VESWP:	SETO T1,		; 1==> ONLY SWAP SPACE
	MOVEM T1,VDSKFL		;SAVE THE FLAG FOR LATER
	HRROI T1,[ASCIZ /ON STRUCTURE/]
	CALL CMDNOI		;OUT THE NOISE
	CALL CONFRM		;GET STR AND CONFIRM
	CALL PSCHK		;SEE IF WE ARE ON PS?
	 CALL XMNT		;EXCLUSIVE MOUNT OF STRUCTURE IF NOT PS
	CALL SETSTR		;SET UP THE STRUCTURE
	CALL HOMEIN		;READ HOME BLOCKS FOR FIRST PACK
	 JRST RESTRT		;ERROR, PUNT THIS COMMAND
	CALL BATIN		;READ THE BAT BLOCKS IN
	SETZM SYSBTB		;CLEAR TABLE FOR BAT BLOCKS
	MOVEI T1,BPRBLK		;POINT TO FIRST PAIR OF BAT BLOCK PAIRS
	MOVEI T3,MAXPR		;TOTAL NUMBER OF ENTRIES
	SETZ T2,		;CLEAR COUNTER
VERLO2:	MOVE Q1,0(T1)		;GET FIRST WORD OF PAIR
	TXZ Q1,ADRMSK
	JUMPE Q1,VERCO1		;IF 0, END OF THE LIST
	ADD T2,1(T1)		;ADD IN UPPER END OF RANGE
	SUB T2,Q1		;SUBTRACT LOWER BOUND, AND ADD 1 TO ADJUST FOR
	ADDI T2,1		;COUNT, RATHER THAN RANGE
	ADDI T1,4		;DO THE NEXT PAIR OF WORDS
	SOJG T3,VERLO2		;AND LOOP TILL WE HAVE DONE THEM ALL
VERCO1:	TMSG <There are >
	MOVEI T3,^D10
	CALL TTNOUT
	TMSG < sectors marked as bad in the BAT blocks.
>
	MOVE T1,PAGCYL		;NUMBER OF PAGES PER CYLINDER
	CAIGE T1,^D100		;IS IT LESS THAN THE AMOUNT WE ARE WILLING
	JRST .+3		;YES, THATS THE NUMBER WE WANT
	LSH T1,-1		;READ HALF AS MUCH
	JRST .-3		;SEE IF THIS FITS
	MOVEM T1,MAXRED		;SAVE NUMBER OF PAGES TO READ
	SKIPE VDSKFL		; ARE WE DOING THE ENTIRE DISK?
	JRST VERSWP		;NO, JUST THE SWAP SPACE
	JRST VERFIL		;YES, GO DO THE FILE SPACE
; HERE TO VERIFY AN ENTIRE STRUCTURE, AND REPORT ANY DIFFERENCES
; BETWEEN THE BAT BLOCK, AND WHAT WE FIND

VERFIL:	MOVE T1,NPACKS		;GET THE NUMBER OF PACKS
	IMUL T1,SECUNT		;CALCULATE THE NUMBER OF SECTORS IN STRUCTURE
	MOVEM T1,LSTSEC		;AND SAVE THE COUNT FOR LATER
	SETZM FSTSEC		;START AT SECTOR 0
	CALL VERSCN		;SCAN THE DISK

; HERE AFTER THE DISK OR SWAP SPACE HAS BEEN GONE OVER

VERCO3:	MOVEI T1,SYSBTB		;POINT TO FIRST PAIR OF BAT BLOCK PAIRS
	SETZ T2,		;CLEAR COUNTER
VERLO1:	MOVE T3,0(T1)		;GET FIRST WORD OF PAIR
	TXZ T3,ADRMSK
	JUMPE T3,VERCO2		;CONTINUE, WE ARE ALL DONE IF IT IS 0
	ADD T2,1(T1)		;ADD IN UPPER END OF RANGE
	SUB T2,T3		;SUBTRACT LOWER BOUND, AND ADD 1 TO ADJUST FOR
	ADDI T2,1		;COUNT, RATHER THAN RANGE
	ADDI T1,4		;DO THE NEXT PAIR OF WORDS
	SOJG T3,VERLO1		;AND LOOP TILL WE HAVE DONE THEM ALL
VERCO2:	TMSG <Disk scan found >
	MOVEI T3,^D10
	JUMPE T2,[TMSG <no>
		  JRST .+2]	; INIDICATE NO ERRORS
	CALL TTNOUT
	TMSG < bad sectors.
>
	JRST BATWRK		; GO TO THE EDITOR
;HERE TO SCAN A DISK LOOKING BETWEEN FSTSEC AND LSTSEC FOR A BAD PAGE

; FOR THE FUTURE, ADD CODE TO READ MORE THAN A PAGE AT A TIME (MAXRED),
; AND GO BACK AND SINGLE STEP PAGES IF THERE IS AN ERROR.

VERSCN: MOVE P1,FSTSEC		;SET THE STARTING LOCATION
VERLO3:	CALL READCK		;READ THE BLOCK, AND SEE IF IT IS GOOD
	 CALL MARKCK		;MARK THAT FACT
	ADD P1,SECPAG		;GO TO NEXT SECTOR, PLEASE
	MOVEM P1,BATLST		;SAVE LAST BLOCK WE LOOKED AT
	CAMGE P1,LSTSEC		; PAST THE END?
	JRST VERLO3		;NO, LOOP FOR MORE
	RET			;ALL DONE
; Here to verify the swap space for each unit in the structure.

; We have to go and get the home blocks on each unit, and verify that they all
; have the swap space.  In the normal case, each unit will have exactly the
; same amount of swap space, and it will start at the save relative position
; on each unit, but places like Stanford insist on building kludge types of
; PS's, with three units and swap space on the first two only.  So go and get
; the pages for each unit, and if they try to build funny disks, we will not
; step on them.

VERSWP:	MOVE Q3,NPACKS		; THE NUMBER OF UNITS THAT HAVE SWAP SPACE
	SETZ Q2,		; THE NUMBER OF THE UNIT WE ARE WORKING ON
VERSW1:	MOVE Q1,SECUNT		; GET SIZE OF EACH UNIT
	IMUL Q1,Q2		; AND GET THE START OF THIS UNIT
	MOVEI T1,1		; NUMBER OF THE FIRST HOME BLOCK
	ADD T1,Q1		; ADD IN THE OFFSET
	CALL GETHOM		; AND READ IT IN.
	 JRST [	MOVEI T1,12	; FAILURE, SO TRY FOR THE SECOND ONE
		ADD T1,Q1
		CALL GETHOM
		 ERROR PARSE1,<Could not read the home blocks>
		JRST .+1]	; BACK TO THE MAIN LINE OF CODE
	CALL HOMIN1		; ENTER THE HOME BLOCK VERIFICATION CODE AFTER
				;  WE HAVE SET UP THE HOME BLOCK ON UNIT X
	 ERROR PARSE1,<Home blocks appear to have garbage in them>
	ADD Q1,FSSUN		; ADD IN THE OFFSET OF THE SWAP SPACE
	MOVEM Q1,FSTSEC		; AND RECORD IT AS THE PLACE TO START
	ADD Q1,NSSUN		; ADD THE LENGTH OF THE SWAP SPACE
	MOVEM Q1,LSTSEC		; AND THAT IS THE PLACE TO STOP
	MOVEM Q2,THSUNI		; RECORD THE UNIT NUMBER FOR PRYING EYES
	CALL VERSCN		; AND SCAN THAT PART OF THE DISK
	AOS Q2			; ON TO THE NEXT UNIT
	SOJG Q3,VERSW1		; GO OVER ALL THE UNITS
	JRST VERCO3		; JOIN THE COMMON CODE
; HERE TO DO THE WORK OF EDITING THE BAT BLOCKS

BATWRK:	SETZM BATLST		; CLEAR THE SCAN INDICATOR
	CALL PARSEI
BATEDI:	HRROI T1,BATPRM		; GET THE PROMPT
	CALL CMDINI		; AND SAY HELLO
	MOVEI T1,[FLDDB.(.CMKEY,,BATTAB)]
	CALL COMNDX		; GETS THE COMMAND
	 ERROR BATEDI,<Not a BAT block edit command>
	HRRZ T1,(T2)		; GET DISPATCH ADDR
	JRST (T1)		; GO TO IT.

BATPRM:	ASCIZ /BAT-EDIT>/

BATTAB:	BATTAL,,BATTAL
	TB (.BATAD,ADD)		; ADD TO THE BAT BLOCK
	TB (.BATDE,DELETE)	; DELETE FROM THE BAT BLOCKS
	TB (.BATEX,EXIT)	; EXIT AND WRITE NEW BLOCKS
	TB (.EFILD,FILE-DDT)	; CALL THE DISK EDIT PROGRAM
	TB (.BATLI,LIST)	; LIST STATUS OF KNOWN PAGES
	TB (.EPUSH,PUSH)	; CALL THE EXEC FOR LATER
	TB (.BATQU,QUIT)	; GIVE UP, LEAVE BAT BLOCKS ALONE
BATTAL==.-BATTAB-1
; here to exit and update the bat blocks

.BATEX:	HRROI T1,[ASCIZ /TO CHECKD COMMAND LEVEL AFTER UPDATING THE BAT BLOCKS/]
	CALL CMDNOI		; BITCH AT THE LOSER
	MOVEI T1,[FLDDB. (.CMCFM)]
	CALL COMNDX		; GET THE END OF THE LINE
	 ERROR BATEDI,<Invalid command confirmation>
	SETZ P1,		; FIRST SECTOR TO START AT
	MOVE P2,SECUNT		; SIZE OF FIRST PACK IN DISK
	MOVE P3,NPACKS		; NUMBER OF PACKS TO GO OVER
BATEX1:	CALL BATBLD		; BUILD BAT BLOCK FOR THIS UNIT
	 JRST [	TMSG <%Error, bat blocks not written; too many entries to add.>
		JRST BATEDI]
	ADD P1,SECUNT		; START AT BEGINNING OF NEXT PACK
	ADD P2,SECUNT
	SOJG P3,BATEX1		; LOOP OVER ALL PACKS

; HERE, AND WE CAN WRITE THE BLOCKS, BECAUSE WE KNOW THE WILL FIT

	SETZ P1,		; SAME AS LAST TIME
	MOVE P2,SECUNT
	MOVE P3,NPACKS
BATEX2:	CALL BATBLD		; BUILD THE BLOCKS
	 JRST [	TMSG <?Error on second pass of building bat blocks>
		JRST BATEDI]
	CALL BATWRT		; AND WRITE THEM IN BOTH PLACES
	 JRST [	TMSG <?Error writing bat blocks to disk, write is aborted.
%The bat blocks may be inconsistent at this time.
>
		JRST BATEDI]
	ADD P1,SECUNT
	ADD P2,SECUNT
	SOJG P3,BATEX2		; LOOP OVER ALL PACKS
	SETZM SYSBTB		; Never allow EXIT to copy old BAT entries.
	JRST RESTRT		; DONE, BACK FOR MORE
; HERE TO BUILD THE BAT BLOCK FOR A GIVIN DISK

; (P1) = LOWER BOUND
; (P2)-1 = UPPER BOUND
; (NPACKS)-(P3) = UNIT NUMBER

; BLOCKS ARE BUILT IN PT

BATBLD:	SETZM PT		; CLEAR AREA TO BUILD BLOCK IN
	MOVE T1,[PT,,PT+1]
	BLT T1,PT+777		; CLEAR THE DISK AREA
	MOVSI T1,(SIXBIT /BAT/)
	MOVEM T1,PT+BATNAM	; SET THE NAME (SIXBIT BAT IN FIRST WORD)
	MOVE T1,[CODE]
	MOVEM T1,PT+BATCOD	; SET SPECIAL CODE TO LOOK FOR
	MOVEI T1,BPRBLK		; POINT TO THE FIRST WORD
	MOVEI T2,PT+4		; START OF ENTRIES TO BUILD
	SETZ Q2,		; CLEAR COUNT OF NUMBER FOUND
	SKIPA
BATBL9:	ADDI T1,4		; POINT TO NEXT ENTRY
	SKIPN Q1,(T1)		; GET THE FIRST ADDRESS
	JRST BATBL3		; IT WILL BE 0 AT END OF THE LIST
	TXNN Q1,BT%MAP		; WAS IT DONE BY THE MAPPER?
	JRST BATBL9		; NO, LOOP FOR MORE
	TXZ Q1,ADRMSK		; CLEAR ANY FLAG BITS WE DON'T NEED
	CAML Q1,P1		; LESS THAN LOWER BOUND?
	CAML Q1,P2		; NO, IS IT LESS THAN UPPER BOUND?
	JRST BATBL9		; FAILS, LOOP FOR THE NEXT ONE
	DMOVE T3,2(T1)		; GET THE REAL WORDS
	DMOVEM T3,(T2)		; AND WRITE THE PAIR
	AOS Q2			; COUNT THE NEW ENTRY
	ADDI T2,2		; UPDATE THE POINTER
	JRST BATBL9		; AND GET THE NEXT ONE
; HERE AFTER WE ARE DONE ADDING THE HARDWARE TYPE ENTRIES, SO SEE IF WE
;  HAVE TOO MANY OR WHAT...

BATBL3:	CAILE Q2,MAXPAR		; DID WE GET TOO MANY?
	RET			; YES, ERROR RETURN
	MOVEI T3,PT		; BASE OF TABLE
	STOR Q2,BTHCT,(T3)	; SAVE THE NUMBER WE ADDED
	MOVEI T1,BPRBLK		; POINT TO THE FIRST WORD
	SETZ Q3,		; CLEAR COUNT OF NUMBER FOUND
	SKIPA
BATBL4:	ADDI T1,4		; POINT TO NEXT ENTRY
	SKIPN Q1,(T1)		; GET THE FIRST ADDRESS
	JRST BATBL5		; IT WILL BE 0 AT END OF THE LIST
	TXNN Q1,BT%ANG!BT%WBM!BT%FND ; DID WE GET IT THERE
	JRST BATBL4		; NO, LOOP FOR MORE
	TXZ Q1,ADRMSK		; CLEAR ANY FLAG BITS WE DON'T NEED
	CAML Q1,P1		; LESS THAN LOWER BOUND?
	CAML Q1,P2		; NO, IS IT LESS THAN UPPER BOUND?
	JRST BATBL4		; FAILS, LOOP FOR THE NEXT ONE
	DMOVE T3,2(T1)		; GET THE REAL WORDS
	DMOVEM T3,(T2)		; AND WRITE THE PAIR
	AOS Q3			; COUNT THE NEW ENTRY
	ADDI T2,2		; UPDATE THE POINTER
	JRST BATBL4		; AND GET THE NEXT ONE

; HERE AND Q2= MAPPER COUNT, Q3= WRITTEN BY MONITOR COUNT

BATBL5:	ADD Q2,Q3		;GET TOTAL OF BLOCKS
	CAILE Q2,MAXPAR		;OVER THE TOP ?
	RET			;YES, HANG IT UP
	SUB Q2,Q3		;No, assume SOFTFL is on
	SKIPN SOFTFL		;SOFT FLAG ON?
	JRST BATBL7		;NO, DON'T WRITE THE ADDRESSES TO BAT BLOCK
	MOVEI T1,SYSBTB		;POINT TO THE FIRST WORD
	SKIPA			;
BATBL6:	ADDI T1,4		;POINT TO NEXT ENTRY
	SKIPN Q1,(T1)		;GET THE FIRST ADDRESS
	JRST BATBL7		;IT WILL BE 0 AT END OF THE LIST
	TXNN Q1,BT%ANG!BT%WBM!BT%FND ;DID WE GET IT THERE
	JRST BATBL6		;NO, LOOP FOR MORE
	TXZ Q1,ADRMSK		;CLEAR ANY FLAG BITS WE DON'T NEED
	CAML Q1,P1		;LESS THAN LOWER BOUND?
	CAML Q1,P2		;NO, IS IT LESS THAN UPPER BOUND?
	JRST BATBL6		;FAILS, LOOP FOR THE NEXT ONE
	DMOVE T3,2(T1)		;GET THE REAL WORDS
	PUSH P,T1		;save table address
	MOVE T1,Q1		;put current address in T1
	CALL SEEADR		;AND LOOK FOR THIS ENTRY
	 JRST BATB10		;yes it's there, don't add it again
	DMOVEM T3,(T2)		;address not found, WRITE THE PAIR
	AOS Q3			;COUNT THE NEW ENTRY
	ADDI T2,2		;UPDATE THE POINTER
BATB10:	POP P,T1		;restore table address
	JRST BATBL6		;AND GET THE NEXT ONE

BATBL7:	MOVEI T3,PT		;GET BASE AGAIN
	STOR Q3,BTMCT,(T3)	; SAVE THIS FOR LATER
	ADD Q2,Q3		; GET TOTAL OF BLOCKS
	CAILE Q2,MAXPAR		; OVER THE TOP ?
	RET			; YES, HANG IT UP
	MOVEI Q3,MAXPAR		; GET TOTAL ALLOWED
	SUB Q3,Q2		; AND CALCULATE NUMBER FREE
	STOR Q3,BATFR,(T3)	; AND SAVE IT IN THE BLOCK
	RETSKP			; AND WE WIN FOR THIS BLOCK
; HERE TO WRITE THE BAT BLOCKS TO THE DISK

BATWRT:	MOVEI	T1,BATBL1	;get address of sector where BAT block goes
	MOVEM	T1,PT+BATBLK	;save it in BAT block
	MOVE 	T2,P1		;number of sectors to get on Nth unit
	IMUL	T2,TRECPP	;TRECPP/SECPAG = true sectors/sector
	IDIV	T2,SECPAG	;convert to true sectors
	ADD	T1,T2		;add number of sectors to get on Nth unit
	TXO	T1,<<FLD .DOPSR,DOP%AT>+DOP%SN> ;get flags
	MOVEI	T2,PGSIZ	;get page size
	IDIV	T2,TRECPP	;compute number or words to write
	TXO	T2,DOP%WR+DOP%PS ;write the data and use true physical sectors
	MOVEI	T3,PT		;address of data
	MOVE	T4,STRDEV	;get structure device number
	DSKOP			;write data to disk
	SKIPE T1		;any errors?
	RET			;yes, error, as AC1 .NE. 0
	MOVEI	T1,BATBL2	;get address of sector where BAT block goes
	MOVEM	T1,PT+BATBLK	;save it in BAT block
	MOVE	T2,P1		;get number of sectors to get on Nth unit
	IMUL	T2,TRECPP	;TRECPP/SECPAG = true sectors/sector
	IDIV	T2,SECPAG	;convert to true physical secotrs
	ADD	T1,T2		;add number of sectors to get on Nth unit
	TXO	T1,<<FLD .DOPSR,DOP%AT>!DOP%SN> ;get flags
	MOVEI	T2,PGSIZ	;get page size
	IDIV	T2,TRECPP	;compute number or words to write
	TXO	T2,DOP%WR+DOP%PS ;write the data and use true physical sectors
	MOVEI	T3,PT		;address of data
	MOVE	T4,STRDEV	;get structure device number
	DSKOP			;write data to disk
	SKIPE T1		;any errors?
	RET			;yes, error, as AC1 .NE. 0
	RETSKP			;done!
;HERE TO PUSH TO A NEW EXEC

.EPUSH:	CALL PUSHX		; CALL THE REAL ROUTINE
	 JFCL			; IGNORE ANE ERROR
	JRST BATEDI		; BACK TO WORK, PLEASE

;HERE TO CALL FILDDT

.EFILD:	CALL FILDTX		;CALL THE REAL ROUTINE
	 JFCL			; IGNORE ANY ERRORS
	JRST BATEDI		; AND ON WITH THE WORK
;HERE TO ADD AN ENTRY TO THE BAT BLOCKS

.BATAD:	HRROI T1,[ASCIZ /PAGE NUMBER/]
	CALL CMDNOI
	MOVEI T1,[FLDDB.(.CMNUM,CM%SDH,10,<Octal number of page to add to BAT block>,0)]
	CALL COMNDX
	 ERROR BATEDI,<Invalid octal number>
	MOVE P1,T2
	CALL CMDEOL
	 JRST BATEDI
	IMUL P1,SECPAG		; CONVERT TO A SECTOR
	SKIPG P1
	JRST [	TMSG <%The page number must be greater than 0.
>
		JRST BATEDI]	; GET COMMAND AGAIN
	MOVE T3,NPACKS
	IMUL T3,SECUNT		; GET TOTAL SIZE
	CAML P1,T3		; IS IT SMALL
	JRST [	TMSG <%The page number cannot be larger than >
		MOVE P1,T3
		SUBI P1,1
		CALL TYPEP1
		TMSG <.
>
		JRST BATEDI]	; BACK FOR MORE INPUT

; HERE, AND WE THINK THE NUMBER PASS THE RANGE CHECK
; T2 HAS THE SECTOR NUMBER IN IT

	MOVEI T1,BPRBLK		; ADDRESS OF TABLE TO LOOK THRU
	CALL BTTBSE		; SEARCH TABLE
	 JRST BATAD1		; NO MATCH, OK
	TMSG <
%Page >
	CALL TYPEP1
	TMSG < is already marked in the BAT blocks.
>
	JRST BATEDI		; AND GO BACK FOR MORE
;HERE TO DO THE REAL WORK OF ADDING A PAGE ENTRY

BATAD1:	MOVEI T1,BPRBLK		; POINT TO THE TABLE, PLEASE
	MOVNI T2,MAXPR/2	; TOTAL NUMBER OF ENTRIES WE ALLOW
	CALL BTTBAD		; ADD THIS ENTRY
	 JRST BATEDI
	MOVE Q2,T1		; KEEP A POINTER TO THIS ENTRY
	MOVEI T1,SYSBTB		; LOOK FOR THIS ENTRY IN OUR LIST
	MOVX Q1,BT%FND		; ASSUME WE FOUND IT OURSELF
	CALL BTTBSE		; SEE IF IT IS THERE
	 MOVX Q1,BT%ANG		; IF NOT THERE, ANYONES GUESS WHERE ITS FROM
	IORM Q1,(Q2)		; FLAG THAT IT IS OURS
	TXNE Q1,BT%FND		; CHECK WHICH WAY WE SET IT
	JRST [	DMOVE T2,2(T1)	; GET THE CKU FIELDS
		JRST .+2]
	SETZB T2,T3		; CLEAR THE CKU IF IT WAS BT%ANG
	DMOVEM T2,2(Q2)		; UPDATE THE CKU
	MOVEI Q1,2(Q2)		; POINT TO THE CKU FIELD
	LOAD T2,ADD27,(Q1)	; GET THE ADDRESS
	SKIPE T2		; SKIP IF IT IS ZERO, AND WE NEED TO FIX IT
	JRST BATEDI		; BACK TO THE MAIN LOOP
	MOVE T3,SECPAG		; GET PROPER NUMBER OF SECTORS
	SUBI T3,1		; LESS ONE, PER FORMAT OF BAT BLOCKS
	STOR T3,BATNB,(Q1)	; SAVE THE LENGTH
	SETO T3,		; SET FLAG BITS
	STOR T3,BADT,(Q1)	; INDICATE THIS IS THE NEW TYPE OF ENTRY
	MOVE T3,P1		; GET THIS SECTOR NUMBER
	IDIV T3,SECUNT		; GET OFFSET FOR THIS UNIT
	STOR T4,ADD27,(Q1)	; AND SAVE IN THE WORDS
	MOVEI	T1,.APRID	;want system serial number
	GETAB			;get it
	 ERJMP	.+1		;shouldn't happen
	STOR T1,APRNM,(Q1)	;save it
;	T1/ sector number adjusted for unit (used to check unit no)
;	T2/ address of units CHANnel, KONtroller, and UNIT block in MNTBLK
;	T3/ unit number sector is located on in structure
	MOVE T1,P1		;get a working copy of the sector number
	MOVEI T2,MNTBLK+.MSTUI	;address of first word of CHAN,KON,UNIT block
	MOVEI T3,1		;assume unit 1
BATAD3:	SUB T1,SECUNT		;subtract number of sectors/unit
	JUMPL T1,BATAD2		;found correct unit?
	ADDI T2,.MSTNO		;no, next address of next CHAN,KON,UNIT block
	AOS T3			;bump count of which pack we're on.
	CAMLE T3,NPACKS		;see if we're past end of structure
	 ERROR	BATEDI,<Sector too large for this structure>
				;error, shouldn't happen!
	JRST BATAD3		;go back and check again
BATAD2:	MOVE T1,.MSTCH(T2)	;get channel number
	STOR T1,BTKNM,(Q1)	;save channel number
	MOVE T1,.MSTUN(T2)	;get unit number
;CONVERT THE UNIT NUMBER TO A BIT PATTERN
	ANDI T1,7		;TRUNCATE UNIT NUMBER TO 3 BITS BECAUSE
				;RP20 AND HSC'S CAN HAVE HIGH NUMBERS
	MOVEI T2,1		;BEGIN WITH BIT FOR DRIVE 0
	LSH T2,(T1)		;SHIFT PROPER NUMBER OF BITS
	STOR T2,BTUNM,(Q1)	;BIT POSITIONING DONE, SAVE UNIT BIT PATTERN
	JRST BATEDI		; BACK TO THE MAIN LOOP
;HERE TO DELETE AN ENTRY FROM THE BAT BLOCKS

.BATDE:	HRROI T1,[ASCIZ /PAGE NUMBER/]
	CALL CMDNOI
	MOVEI T1,[FLDDB.(.CMNUM,CM%SDH,10,<Octal number of page to delete from the BAT block>,0)]
	CALL COMNDX
	 ERROR BATEDI,<Invalid octal number>
	MOVE P1,T2
	CALL CMDEOL
	 JRST BATEDI
	IMUL P1,SECPAG		; CONVERT TO A SECTOR
	SKIPG P1
	JRST [	TMSG <%The page number must be greater than 0.
>
		JRST BATEDI]	; GET COMMAND AGAIN
	MOVE T3,NPACKS
	IMUL T3,SECUNT		; GET TOTAL SIZE
	CAML P1,T3		; IS IT SMALL
	JRST [	TMSG <%The page number cannot be larger than >
		MOVE P1,T3
		SUBI P1,1
		CALL TYPEP1
		TMSG <.
>
		JRST BATEDI]	; BACK FOR MORE INPUT

; HERE, AND WE THINK THE NUMBER PASS THE RANGE CHECK
; T2 HAS THE SECTOR NUMBER IN IT

	SKIPN BATFLG
	 ERROR BATEDI,<BATBLOCK deletion has not been enabled>
	MOVEI T1,BPRBLK
	CALL BTTBDE		;DELETE THIS ENTRY IF IT IS THERE
	 JRST [	TMSG <%Page >
		CALL TYPEP1
		TMSG < is not marked in the bat blocks.
>
		JRST BATEDI]
	JRST BATEDI		; BACK FOR MORE INPUT
;HERE TO JUST QUIT THE BAT BLOCK EDITOR

.BATQU: HRROI T1,[ASCIZ /FROM THE EDITOR, DON'T UPDATE THE DISK/]
	CALL CMDNOI		; GIVE THE NOISE TO THE USERS
	MOVEI T1,[FLDDB.(.CMCFM)]
	CALL COMNDX		; GET THE CONFIRMATION
	 ERROR BATEDI,<Invalid command confirmation>
	JRST RESTRT		; RESTART THE WORLD.
;HERE TO LIST THE INFORMATION WE HAVE ABOUT BAT BLOCKS

.BATLI:	HRROI T1,[ASCIZ /BAT BLOCK INFORMATION/]
	CALL CMDNOI		; TYPE THE NOISE
	MOVEI T1,[FLDDB.(.CMCFM)]
	CALL COMNDX		; GET CONFORMATION
	 ERROR BATEDI,<Invalid command confirmation>
	TMSG <
The following pages are marked in the BAT blocks:
>
	MOVEI Q1,BPRBLK		; POINTER TO LIST
	SETZM BATTYF		; CLEAR HEADER FLAG
BATLI1:	SKIPN T1,(Q1)		; GET NEXT ENTRY IN LIST
	JRST BATLIR
	TXZ T1,ADRMSK		; BLANK OUT ANY EXTRA BITS
	JUMPE T1,BATLIR
	CALL BATTYP		; TYPE THIS BAT ENTRY
	ADDI Q1,4
	JRST BATLI1
BATLIR:	TMSG <
>
	SKIPE BEMFLG		;ONLY GO ON IF WE HAVE SOME GOOD INFO
	JRST BATEDI
	TMSG <The following pages are marked in the bat blocks, but were read
without errors.
>
	SETZM BATTYF		; CLEAR HEADER FLAG
	MOVEI Q1,BPRBLK		; GET THE REAL BAT BLOCK LIST
BATLI2:	SKIPN P1,(Q1)		; GET NEXT ENTRY, PLEASE
	JRST BATLIN		; END OF LIST, WE ARE DONE HERE
	TXZ P1,ADRMSK
	JUMPE P1,BATLIN
BATLI3:	MOVEI T1,SYSBTB		; POINT TO THE BAT LIST AGAIN
	CALL BTTBSE		; AND LOOK FOT THIS ENTRY
	 JRST [	PUSH P,T1	; SAVE THE T1 REG
		CALL BATTYP	; AND TYPE THE ENTRY, PLEASE
		POP P,T1	; PUT T1 BACK
		JRST .+1]	; AND RETURN
	ADD P1,SECPAG		; BUMP THE POINTER UP SOME
	CAMG P1,1(T1)		; SEE IF IT IS PAST THE END, PLEASE
	JRST BATLI3		; NO, SEE IF IT IS HIDDEN
	ADDI Q1,4		; GO TO THE NEXT ENTRY
	JRST BATLI2
BATLIN:	TMSG <
The following pages are not marked in the BAT blocks, and could not
be read.
	>
	SETZM BATTYF		; CLEAR HEADER FLAG
	MOVEI Q1,SYSBTB		; GET THE REAL BAT BLOCK LIST
BATLI4:	SKIPN P1,(Q1)		; GET NEXT ENTRY, PLEASE
	JRST BATWRK		; END OF LIST, WE ARE DONE HERE
	TXZ P1,ADRMSK
	JUMPE P1,BATWRK
BATLI5:	MOVEI T1,BPRBLK		; POINT TO THE BAT LIST AGAIN
	CALL BTTBSE		; AND LOOK FOT THIS ENTRY
	 JRST [	PUSH P,T1	; SAVE THE T1 REG
		CALL BATTYP	; AND TYPE THE ENTRY, PLEASE
		POP P,T1	; PUT T1 BACK
		JRST .+1]	; AND RETURN
	ADD P1,SECPAG		; BUMP THE POINTER UP SOME
	CAMG P1,1(T1)		; SEE IF IT IS PAST THE END, PLEASE
	JRST BATLI5		; NO, SEE IF IT IS HIDDEN
	ADDI Q1,4		; GO TO THE NEXT ENTRY
	JRST BATLI4
;HERE TO TYPE A SINGLE BAT BLOCK ENTRY
;
; Q1 POINTS THE 4 WORD ENTRY, AND BATTYF IS THE HEADER TYPE FLAG
;
BATTYP:	SKIPN BATTYF		; FLAG SET?
	JRST [	TMSG <
 Start    End    Type  Address  Length  APRID  Chan  Unit	Who
 (Pages     )          (Sectors      )

>
		SETOM BATTYF	; ONLY ONE HEADER
		JRST .+1]
	MOVE T2,(Q1)		; GET FIRST WORDS
	TXZ T2,ADRMSK		;CLEAR ALL BUT THE ADDRESS
	IDIV T2,SECPAG
	MOVE T3,[^D9,,10]
	CALL TTNOUT		; TYPE THE NUMBER (START)
	MOVE T2,1(Q1)
	IDIV T2,SECPAG
	MOVE T3,[^D9,,10]
	CALL TTNOUT		; TYPE THE NUMBER (END)
	PUSH P,Q1		; SAVE POINTER
	ADDI Q1,2		; SKIP OLD DATA
	LOAD T4,ADD27,(Q1)	; GET BIG ADDRESS
	LOAD T1,BADT,(Q1)	; GET TYPE FIELD
	SKIPN T1		; IS THIS AN OLD ONE?
	LOAD T4,ADD18,(Q1)	; YES, GET OLD ADDRESS
	SKIPN T1
	JRST [	TMSG <OLD  >
		JRST BATTY1]
	TMSG <NEW  >
BATTY1: MOVE T2,T4
	MOVE T3,[^D12,,10]	; 9 COL, DECIMAL
	CALL TTNOUT		; OUTPUT THE NUMBER (ADDRESS)
	LOAD T2,BATNB,(Q1)	; GET LENGTH
	ADDI T2,1		; FUDGE IT A LITTLE
	MOVE T3,[^D6,,^D10]
	CALL TTNOUT		; OUTPUT THE NUMBER (LENGTH)
	LOAD T2,APRNM,(Q1)	; GET APRID OF WRITER
	MOVE T3,[^D8,,^D10]
	CALL TTNOUT		; OUTPUT THE NUMBER (APRID)
	LOAD T2,BTKNM,(Q1)	; GET CONTROLER NUMBER
	MOVE T3,[^D5,,^D10]
	CALL TTNOUT
	LOAD T1,BTUNM,(Q1)	; GET UNIT NUMBERS FLAGS
	MOVE T3,[^D1,,^D10]
	JUMPE T1,BATTY2		; OUT OF HERE IF WE ARE ALL DONE
	SETO T2,
BATTY3:	AOS T2
	TRZE T1,1		; IS THE LOW ORDER BIT SET
	JRST [	PUSH P,T1	; SAVE OLD BIT MASK
		CALL TTNOUT	; TYPE THE UNIT NUMBER
		SKIPE (P)	; SEE IF THAT WAS THE LAST UNIT WE NEED TO TYPE
		CALL [	TMSG <,>
			RET]
		POP P,T1	; RESTORE FLAGS
		JRST .+1]	; AND CONTINUE
	LSH T1,-1		; SLIDE IT OVER A BIT
	JUMPN T1,BATTY3		; AND KEEP GOING IF THERE IS MORE
BATTY2:	TMSG <	>
	POP P,Q1
	MOVE T2,(Q1)		; GET THE FLAGS AND START SECTOR
	HRROI T1,[ASCIZ /   	Mapper
/]				; ASSUME THE MAPPER DID IT
	TXNE T2,BT%FND
	HRROI T1,[ASCIZ /   	CHECKD
/]				; WE FOUND IT IN OUR WANDERINDS
	TXNE T2,BT%WBM
	HRROI T1,[ASCIZ /   	Monitor
/]				; THE MONITOR (OR US SOME TIME IN THE PAST)
				; PLACED IT IN THE BAT BLOCK
	TXNE T2,BT%ANG
	HRROI T1,[ASCIZ /   	Unknown
/]				; IT JUST APPEARED FOR THE ETHIER
	PSOUT			; TELL THE LOSER
	RET
; HERE TO TRY TO READ A DISK PAGE, AND SEE IF WE CAN GET IT.  IN NO CASE,
; WILL WE ALLOW IT TO FIND ITS WAY INTO THE BAT BLOCKS
; CALL WITH P1 = THE SECTOR TO READ
; RETURN +1 IF ERROR
; RETURN +2 IF OK

; THIS CODE, THE BAT BLOCK ADD ROUTINE, THE SCAN ROUTINE (VERSCN), AND
; EVERYTHING THAT HAS ANYTHING TO DO WITH THIS CODE **KNOWS** WHAT AC'S
; ARE USABLE FOR WHAT.  IN GENERAL, ALL THE T'S ARE TRASHABLE, AS WELL
; AS Q1, (BUT WE USE IT AS A COUNTER), AND P1 *** MUST *** CONTAIN THE
; SECTOR NUMBER THAT WE ARE READING AT.

READCK:	MOVE T4,STRDEV		;SET DEVICE TO READ ON
	SETZ Q1,		;INDICATE WE HAVE DONE ANY READS YET
READ1:	MOVE T3,DIRORA		;READ INTO THE DIRECTORY AREA
	MOVE T1,P1		; LOAD THE PAGE ADDRESS
	TXO T1,<FLD .DOPSR,DOP%AT>
				; LINEAR ADDRESS, ALWAYS
	TXO T1,DOP%SN		;INDICATE A STRUCTURE REFERENCE
	MOVX T2,1000!DOP%IL!DOP%IR
				;1000 WORDS, AND SUPPRESS ERROR LOG,
				;  AND NO RETRY
	DSKOP			;READ THE PAGE
	 ERJMP	[JSERR		;write why we failed
		JRST	.+1]	;continue
	JUMPN T1,READE1		;READ ERROR
	SKIPE Q1		; FIRST TRY?
	JRST READE2		; NO, SEE WHATS UP
READR:	RETSKP			; NO ERROR, GOOD IN ANY CASE

; HERE IF WE WIN ON A SOFT ERROR AFTER THE FIRST TRY

READE2:	TMSG <Soft read error for page >

	; FALL INTO NEXT PAGE
; HERE TO TYPE PAGE NUMBER, AND IF WE ARE COUNTING SOFT ERRORS, RETURN A
; FAILED TO READ STATUS (NON SKIP RETURN)

READC:	CALL TYPEP1
	TMSG <.
>
	SKIPN SOFTFL		; SOFT ERRORS WANTED?
	JRST READR		; NO, RETURN

; HERE TO TELL USER PAGE IS COUNTED AS BAD, AND RETURN THE INFORMATION

READB:	TMSG <	The page will be considered bad.
>
	RET			; RETURN THE ERROR

; HERE IF WE HAD AN ERROR ON SOFT READS. TRY 8 TIMES BEFORE WE GIVE UP
; ON THIS SECTOR.

READE1: AOS Q1			; COUNT THE NUMBER OF TRYS
	CAIE Q1,10		; UP TO THE LIMIT YET
	JRST READ1		; NO, TRY AGAIN
	SETZ Q1,		; CLEAR OUT THE COUNT

;HERE FOR ECC READ RETRY

READ2:	MOVE T3,DIRORA
	MOVE T1,P1		; LOAD THE PAGE ADDRESS
	TXO T1,<FLD .DOPSR,DOP%AT>
				; LINEAR ADDRESS, ALWAYS
	TXO T1,DOP%SN		;INDICATE A STRUCTURE REFERENCE
	MOVX T2,1000!DOP%IL	;1000 WORDS, AND SUPPRESS ERROR LOG
	DSKOP			;READ THE PAGE
	JUMPN T1,READE3		;ECC ERROR, WE ARE DONE
	SKIPE Q1		;WAS THIS THE FIRST ATTEMPT?
	JRST READE4		;NO, SEE IF WE WANT SOFT OR ECC ERRORS

; HERE IF A "HARD" SOFT ERROR WAS RECOVREABLE ON THE FIRST ECC READ

	TMSG <Soft read error recovered by ECC for page >
	JRST READC		;TYPE PAGE NUMBER, AND COUNT IT IF WE ARE
				; LOOKING FOR SOFT ERRORS
;HERE ON FIRST THRU Nth ERR READ ERROR WITH ECC

READE3:	AOS Q1			;COUNT THIS ERROR
	CAIE Q1,10		;DID WE TRY 8 TIMES?
	JRST READ2		;NO, TRY FOR ALL 8

	TMSG <Hard error reading page >
	CALL TYPEP1
	TMSG <.
>
	JRST READB		;ALWAYS COUNT IT AS BAD

;HERE IF A RETRY WITH ECC AFTER THE FIRST ONE WINS

READE4:	TMSG <Recoverable ECC read error for page >
	CALL TYPEP1
	TMSG <.
>

; IF EITHER SOFTFL OR ECCFLG ARE SET, WE RETURN AN ERROR, ELSE IT IS OK

	SKIPE SOFTFL		;WANT SOFT ERRORS?
	JRST READB		; YES, INDICATE ERROR
	SKIPE ECCFLG		;WANT ECC ERRORS?
	JRST READB		; YES, ALSO INDICATE ERROR
	JRST READR		;RETURN, PLEASE, NO ERROR
; HERE TO MARK THE BIT TABLE WITH A BLOCK AS BEING BAD

MARKCK: MOVEI T1,SYSBTB		; POINT TO THE TABLE WE ADD TO
	MOVNI T2,<BTBMAX/4>-1	; LOTS OF ENTRIES
	CALL BTTBAD		; ADD IT TO THE TABLE
	 JFCL
	MOVX T2,BT%FND		; WE FOUNT IT, SO CLAIM IT
	IORM T2,(T1)
	CALLRET SETCKU		; SET THE CKU CORRECTLY
;HERE TO SET THE CKU OF THE PAIR POINTED TO BY T1

SETCKU:	PUSH P,T1		; SAVE ADDRESS OF THE BAT PAIR
	ADDI T1,2		; SKIP OUR STUFF
	MOVE T3,SECPAG		; GET PROPER LENGTH IN SECTORS
	SUBI T3,1		; LESS ONE PER FORMAT OF BAT BLOCKS
	STOR T3,BATNB,(T1)	; SAVE THE LENGTH
	SETO T3,		; SET FLAG BITS
	STOR T3,BADT,(T1)	; INDICATE THIS IS THE NEW TYPE OF ENTRY
	MOVE T3,P1		; GET THIS SECTOR NUMBER
	IDIV T3,SECUNT		; GET OFFSET FOR THIS UNIT
	STOR T4,ADD27,(T1)	; AND SAVE IN THE WORDS
	CALL GETCKU		; FIND THE CKU FOR THIS SECTOR
	POP P,Q2		; Q1,3 HAVE C, U, Q2= POINTER TO BLOCK
	ADDI Q2,2		; BUMP POINTERS TO THE REAL PAIRS.
	STOR Q1,BTKNM,(Q2)	; STASH THE CONTROLLER NUMBER
	LOAD Q1,BTUNM,(Q2)	; FETCH THE OLD UNIT FLAGS
	ANDI Q3,7		; TRUNCATE TO 3 BITS (FIX FOR HSC AND RP20'S)
	MOVN Q3,Q3		; NEGATE UNIT NUMBER
	IOR Q1,BITS+^D35(Q3)	; GET THE NEW UNIT BIT ADDED
	STOR Q1,BTUNM,(Q2)	; AND SAVE IT BACK AGAIN
	MOVE T1,[SIXBIT /APRID/]
	SYSGT			; GET OUR CPU NUMBER
	STOR T1,APRNM,(Q2)	; AND FILE THAT FOR THOSE WITH PEEKING EYES
	RET			; RETURN AND KEEP GOING
; HERE TO GET THE CKU FOR THE SECTOR IN P1

GETCKU:	SETOM RNUBLK+.MSRCH	;INIT FOR FIRST UNIT
	SETOM RNUBLK+.MSRCT
	SETOM RNUBLK+.MSRUN
	SETOM MNTBLK+.MSTNU	;INIT # OF UNITS IN STR
	MOVE Q1,P1		;THIS IS THE SECTOR NUMBER WE WANT
	IDIV Q1,SECUNT		;NOW WE HAVE THE UNIT NUMBER WE WANT
	ADDI Q1,1		;FOR SOME REASON, UNIT NUMBERS START AT 1
GETCK2: CALL GTASTS		;GET FIRST UNIT STATUS
	 JRST [	TMSG <
? Unit for page >
		CALL TYPEP1
		TMSG < not found.
>
		JRST GETCK1]
	CALL STRMAX		;IS THIS THE DISK WE ARE LOOKING FOR?
	 JRST GETCK2		; NO, LOOK FOR THE NEXT ONE
	HLRZ Q2,RNUBLK+.MSRNS	; GET THIS LOGICAL UNIT NUMBER
	AOS Q2			; UNIT NUMBERS START AT 1
	CAME Q2,Q1		; THE ONE WE ARE LOOKING FOR?
	 JRST GETCK2		; NO, LOOK YET AGAIN
	MOVE Q1,RNUBLK+.MSRCH	;CHANNEL
	MOVE Q2,RNUBLK+.MSRCT	;CONTROLLER
	MOVE Q3,RNUBLK+.MSRUN	;UNIT
	RET

;HERE ON AN ERROR, RETURN A CKU OF 0,0,0

GETCK1:	SETZB Q1,Q2
	SETZ Q3,
	RET
; HERE TO TYPE THE CONTENTS OF P1 AS A NUMBER BASE 8 , AND CONVERTED TO A
; PAGE NUMBER FROM A SECTOR NUMBER

TYPEP1:	MOVE T2,P1
	IDIV T2,SECPAG
	MOVEI T3,10		; OCTAL
	CALLRET TTNOUT
;BAT BLOCK TABLE SEARCH

;HERE TO SEE IF THERE IS AN OVERLAP BETWEEN THE PAGE POINTED TO BY P1,
;AND ANY ENTRY IN THE TABLE POINTED TO BY T1.
;
; SKIP RETURN ON A MATCH, NON SKIP RETURN ON NO OVERLAP

BTTBS1: ADDI T1,4
BTTBSE:	SKIPN T2,(T1)		; IS THE TABLE EXAUSTED?
	RET			; YES, WE ARE DONE
	TXZ T2,ADRMSK		; CLEAR ANY EXTRA BITS
	JUMPE T2,R		; RETURN IF ADDRESS IS ZERO
	CAML P1,T2		; SEE IF IT IS IN RANGE
	CAMLE P1,1(T1)		; IF NOT, THEN
	JRST BTTBS1		; LOOK FOR MORE
	RETSKP			; IN RANGE, A GOOD RETURN T1= ADDR OF ENTRY
;BAT BLOCK TABLE DELETE

;HERE TO DELETE A SET OF SECTORS FROM THE TABLE POINTED TO BY T1
;P1 HAS THE ENTRY TO DELETE.  A SKIP RETURN INDICATED OK, AN +1 RETURN
;IS FOR ERRORS (I.E. NOT FOUND)

BTTBDE:	TXZ P1,ADRMSK		; MAKE SURE WE HAVE NO EXTRA BITS
	SKIPN T2,(T1)		; END OF LIST?
	RET			; YES, AND WE HAVENT SEEN IT YET, SO ERROR
	TXZ T2,ADRMSK
	JUMPE T2,R		; RETURN IF THIS PART 0, TOO
	CAME P1,T2		; IS IT IN FORNT OF THE LIST?
	JRST [	ADDI T1,4	; GO FOR MORE
		JRST BTTBDE]	; TILL WE HAVE IT
	MOVE T2,T1		; FIND THE END OF THE LIST, PLEASE
	MOVE T3,(T2)
	TXNE T3,ADDERS
	AOJA T2,.-2		; IN A FAST LOOP
	HRLI T3,4(T1)		; SOURCE
	HRR T3,T1		; DESTINATION (FORWARD 4 WORDS)
	BLT T3,(T2)		; SO WHAT IF WE MOVE FOUR EXTRA WORDS
	RETSKP			; WE ARE DONE
;BAT BLOCK TABLE ADD

; HERE TO ADD A WORD PAIR TO A BAT TABLE.
; T1 POINTS TO THE TABLE, AND P1 HAS THE SECTOR TO ADD
; WE WILL ADD SECPAG NUMBERS. T1 WILL POINT TO THE ENTRY WHEN DONE
;

BTTBAD:	AOSLE T2		; BUMP COUNT, CHECK FOR OVERFLOW
	JRST [	TMSG < BATBLOCK table is full, some entries must be deleted to add more.
Error encountered on page >
		CALL TYPEP1	; TYPE THIS PAGE NUMBER
		TMSG <.
>
		RET]
	SKIPN (T1)		; GET NEXT ENTRY IN TABLE
	JRST BTTBA1		; NO, NEW ENTRY
	ADDI T1,4		; NEXT ENTRY
	JRST BTTBAD

BTTBA1:	MOVE T3,SECPAG		; GET NUMBER OF SECTORS PER PAGE
	TXZ P1,ADRMSK		; MAKE SURE WE HAVE NO EXTRA BITS
	ADD T3,P1		; NUMBER OF END + 1
	SUBI T3,1		; NUMBER OF END
	MOVEM P1,0(T1)		; SAVE THE START OF THIS ERROR REGION
	MOVEM T3,1(T1)		; UPDATE END POINTER
	SETZM 2(T1)		; CLEAR BAT BLOCK WORDS
	SETZM 3(T1)
	SETZM 4(T1)		; MAKE SURE WE CAN FIND THE END OF THE LIST
	RETSKP
;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
	TMSG <
>
	CALL INIBTB		;INITIALIZE LOCAL COPY OF BIT TABLE
	CALL SCANDI		;GO SCAN ALL THE DIRECTORIES
	 JRST QDON1		;AN ERROR, CLEAN UP
	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,.TICCP
	DTI
	MOVEI T1,SUMBYT		;T1/CODE FOR ^Y
	DTI			;DEASSIGN ^Y FROM CHANNEL 2
	SKIPN JOBNO		;CAME FROM JOB 0?
	HALTF			;YES. ^C WASN'T ASSIGNED
	MOVEI T1,.TICCC		;T1/CODE FOR ^C
	DTI			;DEASSIGN ^C FROM CHANNEL 1
	HALTF
	JRST .-1
;ROUTINE TO READ IN THE HOME BLOCKS AND SET NSSUN AND FSSUN

HOMEIN:	CALL TRANSL		;GET REAL PS: NAME, IF ANY.
	MOVEI T1,1		;READ IN FIRST HOME BLOCK
	CALL GETHOM
	 JRST HOMIN2		;FAILED, TRY SECOND HOME BLOCK
HOMIN1:
	SETOM RNUBLK+.MSRCH	;INIT FOR STRUCTURE SEARCH
	SETOM RNUBLK+.MSRCT	;ALSO INIT
	SETOM RNUBLK+.MSRUN	;ALSO INIT
	DO.
	 CALL GTASTS		;GET NEXT UNIT (ALIASES)
	 IFNSK.			;IF NO MORE THEN..
	  TMSG <		;TELL THE BAD NEWS
? HOMEIN: Structure not found.
>
	  SETZM WRTLPF		;DON'T ALLOW SYSTEM TO COME UP.
	  RET			;BAD RETURN
	 ENDIF.
	 CALL STRMAX		;SEE IF THIS IS IT.
	 JRST TOP.		;NO, SEARCH NEXT
	ENDDO.
HOMIN3:	MOVE T1,[RNUBLK+.MSRSP,,SECPAG] ;FOUND IT, PREPARE FOR BLT
	BLT T1,BTWCYL		;COPY INFO OUT.
	MOVE T1,RNUBLK+.MSRLS	;GET LOST SECTORS/CYL.
	MOVEM T1,LPPCYL		;COPY INFO OUT.
	MOVE T1,RNUBLK+.MSTSP	;GET TRUE SECTORS/PAGE
	MOVEM T1,TRECPP		;COPY INFO OUT.
	IDIV T1,SECPAG		;FORM TRUE SECTORS/SECTOR
	IMUL T1,SECUNT		;COMPUTE TRUE SECTORS PER UNIT
	MOVEM T1,TRCUNT		;STASH IT
	MOVE T1,RNUBLK+.MSRST	;GET RETURNED SOFTWARE STATUS
	MOVEM T1,DRRST		;STASH IT
	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
>
		SETZM	WRTLPF	;don't allow system to come up
		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>
	SETZM	WRTLPF		;don't allow system to come up
	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
	TXO T2,DOP%PS		;USE TRUE PHYSICAL SECTORS
	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:	SAVEQ
	STKVAR <LSXSEC,SAVWRK>
	MOVE T1,NPACKS		;# OF PACKS IN STRUCTURE
	IMUL T1,TRCUNT		;COMPUTE SECTORS IN STRUCTURE
	MOVEM T1,LSXSEC		;SAVE IT
	MOVEI Q1,2		;FIRST BAT ADDRESS
	MOVEM P1,SAVWRK		;SAVE PERMANENT REG
	MOVEI P1,BPRBLK		;START OF TABLE
	SETZM (P1)		;MARK TABLE AS EMPTY
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
	TXO T2,DOP%PS		;USE TRUE PHYSICAL SECTORS
	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 Q3,BTHCT,(T4)	;GET NUMBER OF PAIRS WRITTEN INITIALLY
	LOAD T3,BTMCT,(T4)	;GET NUMBER OF PAIRS MONITOR HAS WRITTEN
	MOVE Q2,Q3		;REMEMBER THE NUMBER WRITTEN BY THE MAPPER
	ADD Q3,T3		;TOTAL PAIRS WRITTEN
	CAILE Q3,MAXPAR		;DID BLOCK OVERFLOW?
	MOVEI Q3,MAXPAR		;YES. ONLY LOOK AT VALID PART THEN
	MOVEM Q3,OVERHD		;COUNT THESE AS OVERHEAD UNLESS THEY ARE
				; FOUND TO BE ASSIGNED LATER
	MOVEM Q3,BATCNT		;KEEP A SEPARATE COUNT, TOO
	JUMPE Q3,NONE		;IF NONQ1, GO TO NEXT UNIT
	MOVEI T3,BATBUF+4	;FIRST BAD PAIR IN BLOCK
	CALL NXTPR		;MOVE THE NEXT PAIR
	SOJG Q3,.-1		;DO ALL PAIRS
NONE:
	ADD Q1,TRCUNT		;NEXT PACK
	CAMGE Q1,LSXSEC		;OVER THE LAST PACK IN THE STRUCTURE?
	JRST GETBAT		;NO. GO DO IT
	MOVE P1,SAVWRK		;RESTORE PERMANENT REG
	RET			;AND DONE
; HERE TO MAVE A BAT BLOCK PAIR

; T3 POINTS TO THE PAIR WE ARE TO MOVE,
; Q1 HAS OFFSET OF DISK ADDRESS (I.E. 2 + (SECUNT*PACK))
; Q2 HAS NUMBER WRITTEN BY MAPPER, BUT LEFT TO BE PROCESSED
; Q3 HAS TOTAL NUMBER TO MOVE
; P1 POINTS TO WHERE THEY ARE GOING
; T1, T2, AND T4 ARE SCRATCH

NXTPR:	DMOVE T1,(T3)		; GET FIRST AND SECOND WORD
	DMOVEM T1,2(P1)		;SAVE ORIGINAL WORDS IN SECOND BLOCK HALF
	LOAD T4,ADD27,(T3)	;GET STARTING ADDRESS IF NEW FORMAT
	LOAD T1,BADT,(T3)	;GET TYPE FIELD
	SKIPN T1		;OLD FORMAT?
	LOAD T4,ADD18,(T3)	;YES, GET OLD STYLE ADDRESS INSTEAD
	ADD T4,Q1		;MAKE IT A LINEAR ADDRESS
	SUBI T4,2		;REMOVE BIAS FOR BAT BLOCK
	MOVE T1,T4		;COPY THE ADDRESS
	MOVE T2,SECCYL		;GET NUMBER OF SECTORS
	ADD T2,LPPCYL		;  PER CYLINDER
	IDIV T1,T2		;NUMBER OF CYLINDERS IN PHYSICAL ADDRESS
	IMUL T1,LPPCYL		;NUMBER OF LOST SECTORS IN PHYSICAL ADDRESS
	SUBB T4,T1		;TRANLSATE TO LOGICAL ADDRESS
	IDIV T1,SECPAG		;ROUND DOWN ADDRESS TO A PAGE BOUNDARY
	IMUL T1,SECPAG		;TO CATCH ERRORS IN MIDDLE OF A PAGE
	MOVEM T1,0(P1)		;SAVE AS FIRST ADDRESS OF REGION
	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
	SETZM 4(P1)		;FLAG END OF LIST
	MOVX T2,BT%MAP		;ASSUME IT WAS FROM THE MAPPER
	SOSGE Q2		;IF WE COUNT ALL THE MAPPER DID,
	MOVX T2,BT%WBM		;THE REST MUST BE BY THE MONITOR
	IORM T2,(P1)		;FLAG THE AUTHOR OF THIS ENTRY
	ADDI P1,4		;NEXT PAIR IN BUFFER
	ADDI T3,2		;NEXT PAIR IN BAT BLOCK
	RET
;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

	; FALL INTO NEXT PAGE
;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:	SAVEAC	<T1>		;save address we're working on
	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
	 JRST [	TXNN T1,RC%NMD	;NO MORE DIRECTORIES?
		RET		;NO, SOME OTHER ERROR, PASS IT DOWN
		RETSKP]		;YES, DONE, INDICATE SUCCESS
	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]
	MOVE T2,DIRORA
	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
	MOVE T4,DIRORA
	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
	ADD T3,DIRORA		; 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
	ADD T1,DIRORA		; GET ABS ADR OF FDB
	LOAD T2,FBNAM,(T1)	; GET POINTER TO NAME STRING
	 ERJMP [ TMSG <SYMBAD: Illegal address in symbol table> ;
		 CALL BADBLK	;PRINT DIRECTORY NAME
		 JRST SCAN1]	;SKIP THIS ONE AND CONTINUE
	ADD T2,[DIRORG+1]	; GET ABS ADR OF START OF STRING
	MOVEM 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.1/] ;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!1	;PHYSICAL ONLY, SHORT BLOCK, GENERATION 1
	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
	ADD T4,DIRORA		; 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
	ADD T1,[DIRORG+1]
	MOVEM 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
	ADD T4,DIRORA		; 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
	TMSG <
>
	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
	SKIPN T1,.FBADR(T4)	;GET DISK ADDRESS OF INDEX BLOCK
	RET			;disc address
	TLNE T1,(FILNB)		;IS IT A NEW FILE?
	 JRST	[TMSG <%>	;warning
		CALL PNTFIL	;print file name
		TMSG	< is a "new" file
>
		RET]		;new file, return.
	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
	MOVE T3,.FBCTL(T4)	; GET FLAG BITS
	TXNE T3,FB%DIR		; IS THIS A DIRECTORY FILE?
	MOVX F,MR%DIR		; YES, SAY SO
	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

;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.

; NEXT PAGE ....
	HRROI T1,[ASCIZ /
Faulty page table addresses in FDB: /]
	SKIPE T2,NDE
	CALL BUILDE
	HRROI T1,[ASCIZ /
Faulty long file page table addresses in FDB: /]
	SKIPE T2,NPTTE
	CALL BUILDE
	HRROI T1,[ASCIZ /
Faulty addresses in page table: /]
	SKIPE T2,NBPTE
	CALL BUILDE
	HRROI T1,[ASCIZ /
Page tables unreadable: /]
	SKIPE T2,NBPT
	CALL BUILDE
	HRROI T1,[ASCIZ /
Faulty addresses in long file page table: /]
	SKIPE T2,NBPTTE
	CALL BUILDE
	HRROI T1,[ASCIZ /
Long file page tables unreadable: /]
	SKIPE T2,NBPTT
	CALL BUILDE
	HRROI T1,[ASCIZ /
Illegal addresses: /]
	SKIPE T2,NIDA
	CALL BUILDE
	HRROI T1,[ASCIZ /
Multiply assigned addresses: /]
	SKIPE T2,NMDA
	CALL BUILDE
	HRROI T1,[ASCIZ /
Search addresses found: /]
	SKIPE T2,NSDA
	CALL BUILDE
	HRROI T1,[ASCIZ /
Disk read errors: /]
	SKIPE T2,NDSKER		;DISK ERRORS?
	CALL BUILDE
	HRROI T1,[ASCIZ /
File addresses not in bit table: /]
	SKIPE T2,NNBT		;PAGES ASSIGNED TO FILES BUT NOT IN BIT TABLE?
	CALL BUILDE
	HRROI T1,[ASCIZ /
Assigned pages marked in BAT blocks: /]
	SKIPE T2,NABAT		;ANY ASSIGNED PAGES THAT ARE BAD?
	CALL BUILDE
	TMSG <
-  -  -  -  -  -  -  -
>
	RET
BUILDE:	PSOUT			; THE STRING POINTER TO BY T1
	MOVEI T3,^D10		; BASE 10 TYPEOUT
	CALLRET TTNOUT		; AND TYPE THE NUMBER

;PNTFIL - PRINT FILE SPEC

PNTFIL:	HRROI T1,DIRNAM
	PSOUT			;PRINT STR:<DIRECTORY>
	DMOVE	T1,[G2BPT 2,7,0]
	MOVE	T2,DEFNAM
	MOVE	T3,[POINT 7,TMPBUF]
	ILDB	T4,T1
	IDPB	T4,T3
	SKIPE	T4
	JRST	.-3
	HRROI	T1,TMPBUF
	PSOUT			;PRINT THE FILE NAME
	MOVEI T1,"."
	PBOUT
	DMOVE	T1,[G2BPT 2,7,0]
	MOVE	T2,DEFEXT
	MOVE	T3,[POINT 7,TMPBUF]
	ILDB	T4,T1
	IDPB	T4,T3
	SKIPE	T4
	JRST	.-3
	HRROI	T1,TMPBUF
	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
	TXNN F,MR%DIR		;IS THIS A DIRECTORY FILE?
	SKIPGE PAGNN		;FILE PAGE?
	JRST [	AOS OVERHD	;DIRECTORY PAGE OR OVERHEAD SO COUNT IT
		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 >
	AOS NIDA		;INCREMENT COUNT OF ILLEGAL ADDRESS
	JRST SDA1
;THIS ADDRESS IS BEING SEARCHED FOR VIA SCAN COMMAND.

SDA:	TMSG <Found disk address >
	SETZ T4,		;INDICATE NOT AN ERROR TO AVOID NON-SKIP RETURN
	AOSA NSDA		;INCREMENT THE COUNT OF ADDRESSES FOUND
SDA1:	SETZM WRTLPF		;SUPPRESS LOST-PAGES FILE, ETC.
	MOVE T2,DATAB+1(T2)
	MOVEI T3,10
	CALL TTNOUT
	JRST MRKBTP

;PAGE WAS ALREADY ASSIGNED.

MDA:	MOVEM T1,DATAB+1(T2)	;Save address of multiply assigned page
	TMSG <Multiply assigned disk address >
	AOS NMDA		;INCREMENT COUNT OF MULTIPLY ASSIGNED ADDRESSES
	JRST SDA1

;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

FXCNAM:	BLOCK	21
FXCEXT:	BLOCK	21
FIXCNT:	SAVEAC	<Q1,Q2>		;save some ACs
	STKVAR<JFN1>
	DMOVE T1,[G2BPT 2,7,0]
	MOVE T2,DEFNAM		;GET THE NAME POINTER
	DMOVE T3,[G2BPT 0,7,FXCNAM] ;GET THE NEW STRING POINTER
	CALL FIXCN2		;BUILD A NICE STRING FOR GTJFN
	DMOVE T1,[G2BPT 2,7,0]
	MOVE T2,DEFEXT		;GET POINTER TO EXTENSION
	DMOVE T3,[G2BPT 0,7,FXCEXT] ;GET THE NEW STRING POINTER
	CALL FIXCN2		;BUILD A NICE STRING FOR GTJFN
	MOVEI T1,GTJBLK		;T1/ ADDRESS OF GTJFN BLOCK
	MOVX T2,GJ%DEL!GJ%XTN!GJ%OLD!GJ%PHY ;OLD FILE,deleted,extended block
	HRR T2,DEFVER		;VERSION NUMBER OF THIS FILE
	MOVEM T2,.GJGEN(T1)	;(FLAGS,,VERSION NUMBER)
	MOVX T2,G1%IIN		;invisible files too
	MOVEM T2,.GJF2(T1)	;mark in extended flags
	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
	MOVEI T2,FXCNAM		;POINTER TO CURRENT FILENAME
	MOVEM T2,.GJNAM(T1)	;MAKE THIS THE DEFAULT
	MOVEI T2,FXCEXT		;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

FIXCN2:				;ROUTINE TO JACKET STRINGS WITH ^V'S
				;T1/ OLD STRING POINTER
				;T4/ NEW STRING POINTER
	MOVEI Q1,"V"-100	;GET A CONTROL V
FIXCN3:	ILDB Q2,T1		;GET A BYTE
	JUMPE Q2,FIXCN4		;NULL BYTE?
	IDPB Q1,T3		;NO SO PUT A CONTROL V
	IDPB Q2,T3		;AND THEN THE REAL CHARACTER
	JRST FIXCN3		;AND LOOP
FIXCN4:	IDPB Q2,T3		;APPEND A NULL
	RET			;RETURN TO CALLER
;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
	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
	AOS T1			;next word
	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,(ADRMSK)
	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,(ADRMSK)
	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

;NEXT PAGE ....
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
	MOVE T3,LOSTOT		;GET NUMBER OF LOST PAGES
	CAILE T3,MAXLOS		;MORE THAN THE BUFFER SIZE?
	MOVEI T3,MAXLOS		;YES, DON'T WRITE MORE THAN WAS REMEMBERED
	MOVN T3,T3		;MAKE NEGATIVE
	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
	CAILE T2,MAXLOS		;STILL ROOM?
	JRST [	HRROI T1,[ASCIZ /
?Lost pages buffer full, further lost pages will be ignored.
/]
		CAIN T2,MAXLOS+1	;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:	SAVET			;SAVE ALL OF THE "T" ACS
	MOVEI T3,BPRBLK		;START OF THE PAIRS
SEEIF:	SKIPN (T3)		;AT THE END?
	RETSKP			;YES, RETURN +2
	MOVE T2,0(T3)		;GET START RANGE
	TLZ T2,777000		;MASK OUT FLAGS
	MOVE T4,1(T3)		;GET END RANGE
	TLZ T4,777000		;MASK OUT FLAGS
	CAML T1,T2		;IN RANGE?
	CAMLE T1,T4		;IN RANGE?
	SKIPA			;NO, NEXT PAIR
	RET			;YES,RETURN
	ADDI T3,4		;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/ JFN FROM WHICH TO READ

RDLIN:	PUSH P,Q1
	HRLZ T4,T1		;T4=INJFN,,OUTJFN
	HRRI T4,.PRIOU
	MOVEI T1,T2		;T1=ADR OF PARAMETER BLOCK
	MOVEI T2,4		;B=COUNT OF PARAMETERS
	MOVSI T3,(RD%BRK+RD%RAI+RD%BEL+RD%JFN) ;C=FLAGS, BREAK ON EOL AND USE JFNS
	HRROI Q1,LINBUF		;E=PTR TO LINE BUFFER
	MOVEI Q2,NLINB*5		;F=MAX BYTE COUNT
	TEXTI
	 JSHLT
	TLNN T3,(RD%BTM)		;TERMINATED PROPERLY?
	JFCL			;NO, MUST BE END OF FILE
	MOVE T1,Q1		;RETURN UPDATED BFR PTR
	POP P,Q1
	RET
;GET YES/NO ANSWER FROM TERMINAL. C(T1) := PROMPT STRING

YESNO:	STKVAR <ANSWER,QUEST>
	MOVEM T1,QUEST		;SAVE FOR ERROR
YESNO1:	MOVE T1,QUEST		;GET PROMPT STRING
	CALL CMDINI		;INIT CMD AND PROMPT
	MOVEI T1,[FLDDB.(.CMKEY,,YESNOT)]
	CALL COMNDX		;GET RESPONSE
	 ERROR YESNO1,<Invalid response>
	MOVEM T2,ANSWER		;SAVE ANSWER
	CALL CMDEOL		;GRNTEE CR
	 JRST YESNO1		;ERROR
	MOVE T2,ANSWER		;PICKUP RESPONSE
	HRRE T1,0(T2)		;RETURN -1 FOR YES, 0 FOR NO
	RET

YESNOT:	2,,2			;COUNT OF ENTRIES
	TB (0,NO)
	TB (-1,YES)
;ROUTINES TO CHECK CONSISTENCY OF DIRECTORY AND FDB'S

;ROUTINE TO CHECK THE CONSISTENCY OF THE HEADER ON THE FIRST DIR PAGE
;ASSUMES DIR IS MAPPED
;ACCEPTS IN T1/	DIR NUMBER
;	CALL DR0CHK
;RETURNS +1:	HEADER IS SCREWED UP
;	 +2:	OK
;DOES NOT SAVE TEMPORARY ACS

DR0CHK:	MOVE T4,DIRORA		;GET BASE ADR OF MAPPED DIR AREA
	LOAD T2,DRNUM,(T4)	;GET DIR NUMBER
	ERJMP DR0CHB		;ERROR IF NON-EXISTENT PAGE
	CAME T1,T2		;DO THE DIRECTORY NUMBERS MATCH?
	JRST DR0CHB		;NO
	LOAD T2,DRTYP,(T4)	;GET BLOCK TYPE
	CAIE T2,.TYDIR		;IS BLOCK TYPE CORRECT?
	JRST DR0CHB		;NO
	LOAD T2,DRRPN,(T4)	;GET RELATIVE PAGE #
	JUMPN T2,DR0CHB		;MUST BE 0
	LOAD T2,DRSTP,(T4)	;GET TOP OF SYMBOL TABLE
	SOS T2			;GET LAST WORD USED
	LSH T2,-PGSFT		;TURN IT INTO PAGE #
	CAIL T2,NDIRPG		;WITHIN BOUNDS?
	JRST DR0CHB		;NO
	LOAD T2,DRFFB,(T4)	;GET ADR OF FIRST FREE BLOCK
	TRZ T2,777		;IT MUST POINT ONTO THIS PAGE
	JUMPN T2,DR0CHB
	LOAD T1,DRNAM,(T4)	;NOW CHECK NAME BLOCK
	JUMPE T1,DR0CH1		;DONT WORRY IF NO NAME
	CALL NAMCHK		;MAKE SURE THIS IS A NAME BLOCK
	 RET			;NO
DR0CH1:	LOAD T1,DRPSW,(T4)	;GET PASSWORD POINTER
	JUMPE T1,DR0CH2		;COULD BE 0
	CALL NAMCHK		;CHECK BLOCK TYPE
	 RET			;FAILED CHECK
DR0CH2:	RETSKP			;EVERYTHING IS IN ORDER

DR0CHB:	TMSG <DR0CHK: Illegal format for page 0>
	RET
;FDBCHK - ROUTINE TO CHECK AN FDB
;ACCEPTS IN T1/	ABSOLUTE ADR OF FDB
;	CALL FDBCHK
;RETURNS +1:	BAD FDB
;	 +2:	FDB OK
;ALL ACS ARE SAVED AND RESTORED

FDBCHK:	SAVET			;SAVE ALL ACS USED
	STKVAR <FDBCHA,FDBCHF>
	MOVEM T1,FDBCHA		;SAVE ADR OF FDB
	CALL ADRCHK		;CHECK THIS ADDRESS
	 JRST FDBBAD		;NOT GOOD
	LOAD T2,FBTYP,(T1)	;GET BLOCK TYPE
	LOAD T3,FBLEN,(T1)	;GET LENGTH OF BLOCK
	CAIL T3,.FBLN0		;MUST BE GREATER THAN GROUND 0 LENGTH
	CAIE T2,.TYFDB		;BLOCK TYPE MUST BE "FDB"
	JRST FDBBAD		;BAD FDB
	LOAD T1,FBNAM,(T1)	;GET POINTER TO NAME STRING
	JUMPE T1,FDBBAD		;MUST ALWAYS BE SET UP
	CALL NAMCHK		;CHECK NAME
	 RET			;BAD
	MOVE T1,FDBCHA		;GET BACK FDB ADR
	LOAD T1,FBEXT,(T1)	;GET POINTER TO EXT STRING
	JUMPE T1,FDBCH2		;MIGHT NOT BE SET UP YET
	CALL EXTCHK		;CHECK EXT BLOCK
	 RET			;BAD
FDBCH2:	MOVE T1,FDBCHA		;GET FDB ADR AGAIN
	LOAD T1,FBACT,(T1)	;GET POINTER TO ACCOUNT STRING
	JUMPLE T1,FDBCH3		;SEE IF THERE IS AN ACCOUNT STRING
	CALL ACTCHK		;YES, CHECK ITS BLOCK TYPE
	 RET			;BAD
FDBCH3:	MOVE T1,FDBCHA		;GET BACK FDB ADDR
	LOAD T2,FBVER,(T1)	;GET VERSION #
	CAIGE T2,1		;VER #1 OR LATER?
	JRST FDBCH6		;OLDER - JUST EXIT
	LOAD T1,FBLWR,(T1)	;GET LAST WRITER STRING
	JUMPE T1,FDBCH5		;IGNORE OF NONE
	CALL UNSCHK		;CHECK ITS BLOCK TYPE
	 RET			;BAD
FDBCH5:	MOVE T1,FDBCHA		;FDB ADDRS AGAIN
	LOAD T1,FBAUT,(T1)	;GET AUTHOR STRING
	JUMPE T1,FDBCH6		;ALL DONE IF NONE
	CALL UNSCHK		;CHECK ITS BLOCK TYPE
	 RET			;BAD
FDBCH6:	RETSKP			;FDB LOOKS OK

FDBBAD:	TMSG <FDBBAD: Illegal format FDB>
	RET
;ROUTINE TO CHECK A NAME BLOCK
;ACCEPTS IN T1/	RELATIVE ADR OF NAME BLOCK
;	CALL NAMCHK
;RETURNS +1:	BAD BLOCK TYPE
;	 +2:	OK
;ALL ACS SAVED AND RESTORED

NAMCHK:	SAVET			;SAVE ALL ACS
	ADD T1,DIRORA		;MAKE ADDRESS ABSOLUTE
	CALL ADRCHK		;CHECK THIS ADDRESS
	 JRST NAMBAD		;NO GOOD
	LOAD T2,NMTYP,(T1)	;GET BLOCK TYPE
	LOAD T3,NMLEN,(T1)	;GET LENGTH
	CAIL T3,2		;MUST BE AT LEAST 2 WORDS LONG
	CAIE T2,.TYNAM		;AND MUST BE A NAME BLOCK
	JRST NAMBAD		;LOSE
	RETSKP			;NAME BLOCK OK

NAMBAD:	TMSG <NAMBAD: Illegal format for name block>
	RET
;ROUTINE TO CHECK AN EXTENSION BLOCK
;ACCEPTS IN T1/	RELATIVE ADR OF EXTENSION BLOCK
;	CALL EXTCHK
;RETURNS +1:	BAD BLOCK
;	 +2:	OK
;SAVES AND RESTORES ALL ACS

EXTCHK:	SAVET
	ADD T1,DIRORA		;MAKE ADDRESS ABSOLTE
	CALL ADRCHK		;SEE IF ADR IS GOOD
	 JRST EXTBAD		;NO GOOD
	LOAD T2,EXTYP,(T1)	;GET TYPE
	LOAD T3,EXLEN,(T1)	;AND LENGTH
	CAIL T3,2		;LENGTH MUST BE AT LEAST 2
	CAIE T2,.TYEXT		;EXTENSION TYPE OK?
	JRST EXTBAD		;NO GOOD
	RETSKP			;OK

EXTBAD:	TMSG <EXTBAD: Illegal format for extension block>
	RET
;ROUTINE TO CHECK AN ACCOUNT STRING BLOCK
;ACCEPTS IN T1/	RELATIVE ADR OF ACCOUNT STRING BLOCK
;	CALL ACTCHK
;RETURNS +1:	BAD ACCOUNT BLOCK
;	 +2:	OK
;SAVES AND RESTORES ALL ACS

ACTCHK:	SAVET
	ADD T1,DIRORA		;GET ABS ADR
	CALL ADRCHK		;CHECK ADR
	 JRST ACTBAD		;BAD ADR
	LOAD T2,ACTYP,(T1)	;GET BLOCK TYPE
	LOAD T3,ACLEN,(T1)	;AND LENGTH
	CAIL T3,3		;MUST BE AT LEAST 3 WORDS LONG
	CAIE T2,.TYACT		;ACCOUNT BLOCK TYPE?
	JRST ACTBAD		;NO
	RETSKP			;OK

ACTBAD:	TMSG <ACTBAD: Illegal format for account block>
	RET
;ROUTINE TO CHECK A USER NAME STRING BLOCK
;ACCEPTS IN T1/ RELATIVE ADR OF NAME STRING BLOCK
;	CALL UNSCHK
;RETURNS +1:	BAD USER NAME BLOCK
;	 +2:	OK
;SAVES AND RESTORES ALL ACS

UNSCHK:	SAVET
	ADD T1,DIRORA		;GET ABS ADDR
	CALL ADRCHK		;CHECK ADDR
	 JRST UNSBAD		;BAD ADDRS
	LOAD T2,UNTYP,(T1)	;GET BLOCK TYPE
	LOAD T3,UNLEN,(T1)	; AND LENGTH
	CAIL T3,3		;MUST BE AT LEAST 3
	CAIE T2,.TYUNS		;USER NAME BLOCK TYPE?
	JRST UNSBAD		;SOMETHING WRONG
	RETSKP			;GIVE GOOD RETURN

UNSBAD:	TMSG <UNSBAD: Illegal format for user name block>
	RET
;ROUTINE TO CHECK THAT AN ADR IS WITHIN THE DIR BOUNDS
;ACCEPTS IN T1/	ABS ADR TO BE CHECKED
;	CALL ADRCHK
;RETURNS +1:	ILLEGAL ADR
;	 +2:	OK

ADRCHK:	MOVE T2,DIRORA		;GET UPPER BOUNDS
	ADD T2,[NDIRPG*PGSIZ]
	CAML T1,DIRORA		;ABOVE LOWER LIMIT?
	CAML T1,T2		;AND BELOW UPPER LIMIT?
	RET			;NO
	RETSKP			;YES, ADR IS OK
;CALLED AT STARTUP AND EXIT.   CLOSE ALL FILES, RELEASE ALL JFN'S, CLEAR
;DEFAULT FILESPEC

RESET:	MOVNI T1,1
	CLOSF			;CLOSE ALL OPEN FILES
	 JFCL
	MOVE T1,[CZ%NCL+.FHSLF]
	CLZFF		;RELEASE ALL JFNS
	SETZM DEFVER
	MOVE T1,[XWD DEFVER,DEFVER+1]
	BLT T1,DEFEXT+4
	SETZM PSFLG		;RESET PS FLAG
	RET
DSPINT:	REPEAT ^D36,<
	  CALL BADINT>
;USER TYPED CTRL/Y OR SOME OTHER INTERUPT BYTE

SUMINT:	PUSH P,T1
	PUSH P,T2
	PUSH P,T3
	SKIPN DIRNUM		;ONLY IF ACTUALLY DOING SOMWTHING
	JRST SUMBAT
	TMSG <Working on directory >
	MOVEI T1,101
	MOVE T2,DIRNUM
	DIRST
	JFCL
	TMSG <
>
DBK:	POP P,T3
	POP P,T2
	POP P,T1
	DEBRK
SUMBAT:	SKIPN BATLST		; ARE WE DOING A VERIFY PASS?
	JRST DBK		; NO, IGNORE THE INTERUPT
	TMSG <Working on page >
	MOVE T2,BATLST		; GET LAST SECTOR WE STARTED AT
	IDIV T2,SECPAG		; CONVERT TO A PAGE NUMBER
	MOVEI T3,^D8
	CALL TTNOUT		; TYPE NUMBER
	TMSG < out of >
	MOVE T2,LSTSEC		; GET THE END
	SUB T2,FSTSEC		; GET THE LENGTH
	IDIV T2,SECPAG		; CONVERT TO A PAGE NUMBER
	MOVEI T3,^D8
	CALL TTNOUT		; AND TYPE IT
	SKIPN T2,FSTSEC		; ARE WE GOING OVER THE WHOLE DISK
	JRST SUMBT2		; YES, JUST GET OUT AND GIVE THE PERCENTAGE
	TMSG < (>		; INDICATE RANGE START
	IDIV T2,SECPAG		; CONVERT TO A PAGE NUMBER
	MOVEI T3,^D8
	CALL TTNOUT		; GIVE THE NUMBER
	TMSG </>
	MOVE T2,LSTSEC
	IDIV T2,SECPAG		; CONVERT TO A PAGE NUMBER
	MOVEI T3,^D8
	CALL TTNOUT
	TMSG <)>		; CLOSE OFF RANGE
SUMBT2:	TMSG < pages. (>
	MOVE T1,LSTSEC		; THE END OF THE AREA
	SUB T1,FSTSEC		; GET LENGTH
	MOVE T2,BATLST		; GET THE ONE WE ARE ON
	SUB T2,FSTSEC		; AND GET THE OFFSET INTO THE AREA
	IMULI T2,^D100		; SAVE TWO DECIMAL PLACES
	IDIV T2,T1		; AND CALCULATE THE PERCENTAGE
	MOVEI T3,^D10
	CALL TTNOUT		; OUTPUT THE NUMBER
	TMSG <%>
	SKIPN FSTSEC		; DID WE START AT THE START OF THE STRUCTURE
	JRST SUMBT3		; YES, FORGET THIS STUFF
	TMSG < of unit >
	MOVE T2,THSUNI		; GET OUR UNIT NUMBER
	ADDI T2,1		; LOGICAL UNITS START AT 1, NOT ZERO
	MOVEI T3,^D10
	CALL TTNOUT
SUMBT3:	TMSG <)
>
	JRST DBK		; DONE WITH THE INTERUPT
BADINT:	PUSH P,T1
	PUSH P,T2
	PUSH P,T3
	TMSG <
Unexpected interrupt, channel >
	HRRZ T2,-3(P)		;GET PC OF DISPATCH IN DSPINT
	SUBI T2,DSPINT+1		;MAKE RELATIVE
	MOVEI T1,.PRIOU
	MOVEI T3,^D8
	NOUT			;TYPE CHANNEL NUMBER
	 JFCL
	TMSG <
>
	POP P,T3
	POP P,T2
	POP P,T1
	POP P,0(P)
	DEBRK			;IGNORE IT
;USER TYPED CTRL/C

CONTC:	SKIPE REBLDF		;REBUILDING BIT TABLE?
	JRST NOCNTC		;YES - SPECIAL WARNING
	CALL DISMNT		;NO - DISMOUNT STR IF ANY
	TMSG <^C
>
	JRST QUIT


NOCNTC:	PUSH P,T1		;SAVE AN AC
	TMSG <% Cannot interrupt bit table rebuild, ignored ...
>
	POP P,T1
	DEBRK

	END <4,,ENTVEC>