Google
 

Trailing-Edge - PDP-10 Archives - BB-H311B-RM - swskit-utilities/ds.mac
There are 6 other files named ds.mac in the archive. Click here to see a list.
	TITLE	DS	DISK STUFF - Disk Information Utility Program
	SUBTTL	J. G. ZIMA/JGZ  APRIL 1979

	SEARCH	MACSYM,MONSYM	;GET SYMBOLS
	SALL			;NICE LOOKING MACROS
	.DIRECT	FLBLST		;AND NICE LISTING


;VERSION INFORMATION:


	VMAJOR==1		;MAJOR VERSION LEVEL
	VMINOR==0		;MINOR VERSION LEVEL
	VEDIT==31		;EDIT LEVEL
	VWHO==0			;WHO LAST EDITED


;	TABLE OF CONTENTS					  PAGE
;	-----------------					  ----
;
;  1. J. G. ZIMA/JGZ  APRIL 1979 . . . . . . . . . . . . . . . . .   1
;  2. REVISION HISTORY . . . . . . . . . . . . . . . . . . . . . .   2
;  3. DEFINITIONS. . . . . . . . . . . . . . . . . . . . . . . . .   4
;  4. ENTRY VECTOR AND INITIALIZATION. . . . . . . . . . . . . . .   9
;  5. THE SIMPLE COMMANDS - EXIT, HELP . . . . . . . . . . . . . .  11
;  6. FILDDT AND PUSH COMMANDS . . . . . . . . . . . . . . . . . .  13
;  7. TAKE COMMAND . . . . . . . . . . . . . . . . . . . . . . . .  14
;  8. OUTPUT FILE SPECIFICATION COMMAND. . . . . . . . . . . . . .  16
;  9. DRIVE SPECIFICATION COMMAND. . . . . . . . . . . . . . . . .  17
; 10. STRUCTURE SPECIFICATION COMMAND. . . . . . . . . . . . . . .  18
; 11. INFORMATION COMMAND TO DISPLAY DRIVE STATUS. . . . . . . . .  19
; 12. DUMP COMMAND TO DUMP VARIOUS ITEMS . . . . . . . . . . . . .  22
; 13. DUMP COMMAND FOR DISK PAGES. . . . . . . . . . . . . . . . .  23
; 14. DUMP COMMAND FOR FILE INDEX BLOCKS . . . . . . . . . . . . .  25
; 15. DUMP COMMAND FOR HOME BLOCKS . . . . . . . . . . . . . . . .  30
; 16. DUMP COMMAND FOR BAT BLOCKS. . . . . . . . . . . . . . . . .  34
; 17. DUMP COMMAND FOR KS MICROPROCESSOR DIRECTORY . . . . . . . .  39
; 18. CHECK COMMANDS, CHECK PAGE . . . . . . . . . . . . . . . . .  43
; 19. CHECK COMMANDS, CHECK INDEX BLOCK. . . . . . . . . . . . . .  45
; 20. CHECK COMMANDS, CHECK FILE-READABILITY . . . . . . . . . . .  46
; 21. COPY COMMAND . . . . . . . . . . . . . . . . . . . . . . . .  51
; 22. CHKUSE - CHECK UNIT USABILITY FOR COMMANDS . . . . . . . . .  56
; 23. VERIFY COMMAND TO READ-CHECK A UNIT OR STRUCTURE . . . . . .  57
; 24. SETABT, CLRABT AND ABTINT - PSI ROUTINES . . . . . . . . . .  61
; 25. RDCHK - ROUTINE TO READ IN AND CHECK DISK PAGE . . . . . . .  62
; 26. READ - ROUTINE TO DO THE DSKOP . . . . . . . . . . . . . . .  64
; 27. CHKSUM - ROUTINE TO COMPUTE INDEX BLOCK CHECKSUM . . . . . .  65
; 28. STRINF - ROUTINE FOR RETURNING STRUCTURE INFO. . . . . . . .  66
; 29. UNTSTS - ROUTINE FOR STATUS OF NEXT UNIT . . . . . . . . . .  68
; 30. UNTINF - ROUTINE FOR STATUS OF PARTICULAR UNIT . . . . . . .  69
; 31. VERSION NUMBER PRINTING ROUTINE. . . . . . . . . . . . . . .  70
; 32. LUUO HANDLER AND PROCESSING ROUTINES . . . . . . . . . . . .  71
; 33. OUTPUT FORMATTING ROUTINES . . . . . . . . . . . . . . . . .  74
; 34. ERROR PROCESSING AND COMND HELPER ROUTINES . . . . . . . . .  79
; 35. THE DATA AREA. . . . . . . . . . . . . . . . . . . . . . . .  81
	SUBTTL	REVISION HISTORY

;REVISION HISTORY:

;
;   1	JGZ	8-OCT-79
;		BEGIN STABILIZATION OF DS.  START USING REVISION HISTORY
;		FROM NOW ON.
;
;   2	JGZ	8-OCT-79
;		MORE SUBTITLES.  CLEAN UP LISTING SOMEWHAT.
;
;   3	JGZ	10-OCT-79
;		POSITIVE FEEDBACK, ADD "COPY COMPLETED" TO END COPY COMMAND.
;
;   4	JGZ	12-OCT-79
;		ADD DUMP COMMAND FOR KS MICROPROCESSOR FILE SYSTEM DIRECTORY.
;
;   5	JGZ	19-OCT-79
;		MAKE CONSISTENCY CHECKS ON KS FRONT-END DIRECTORY AGAINST
;		THE HOME BLOCK SPECIFIED LENGTH
;
;   6	JGZ	19-OCT-79
;		HAVE CHECK INDEX BLOCK COMMAND TELL WHAT THE CORRECT VALUE
;		OF THE CHECKSUM SHOULD BE IF IT IS WRONG, AS AN AID TO THOSE
;		WHO MAY BE BUILDING OR REBUILDING THEM BY HAND.
;
;   7	JGZ	28-OCT-79
;		HAVE THE PROGRAM ENABLE PROCESS CAPABILITIES AND PUT THEM
;		BACK ON EXITING.
;
;  10	JGZ	30-OCT-79
;		PUT IN A CONTROL-E ABORT TO THE DUMP MICRO... COMMAND AND
;		INCLUDE IN HELP TEXT.
;
;  11	JGZ	3-NOV-79
;		CHANGE DUMP INDEX-BLOCKS COMMAND TO USE RDCHK INSTEAD OF
;		USING READ.  ALL ROUTINES NOW USE RDCHK.
;
;  12	JGZ	3-NOV-79
;		PUT A CONTROL-E ABORT INTO THE READ-CHECK COMMAND AND
;		INCLUDE IN THE HELP TEXT.
;
;  13	JGZ	3-NOV-79
;		CONVERT FORMER READ COMMAND TO CHECK FILE-READABILITY
;		COMMAND AND CHANGE HELP TEXT.
;
;  14	JGZ	3-NOV-79
;		CLEAR JFNBLK+.GJNAM IN TAKE COMMAND IN CASE SOMEBODY LEFT
;		SOMETHING THERE, LIKE A DEFAULT WILD STRING...
;
;  15	JGZ	5-NOV-79
;		POSITIVE FEEDBACK ON CHECK INDEX-BLOCK COMMAND FOR NO ERRORS.
;
;  16	JGZ	5-NOV-79
;		MAKE ABTINT DO THE DTI TO CLEAR CONTROL-E INTERRUPTS.
;
;  17	JGZ	5-NOV-79
;		ADD AN ERROR COUNTER TO CHECK FILE COMMAND FOR POSITIVE
;		FEEDBACK.
;
;  20	JGZ	13-NOV-79
;		ESTHETIC IMPROVEMENTS TO ERROR MESSAGES IN VERIFY.
;		SPACE BEFORE OUTADR, SEPARATE WITH CRLFS.
;
;  21	JGZ	23-NOV-79
;		CLEANUP BETTER AFTER GNJFNS, SETZM FILJFN.
;
;  22	JGZ	24-NOV-79
;		GET JFN BACK AGAIN AFTER DVCHR IN COPY COMMAND.
;
;  23	JGZ	26-NOV-79
;		ADD TABLE OF CONTENTS AND STABILIZE FOR THIS SWSKIT.
;
;  24	JGZ	6-DEC-79
;		ADD A WORD JFNTMP TO HOLD JFNS RETURNED BY COMMAND IN
;		ORDER TO RELEASE THEM SO THEY DON'T PILE UP ON REPARSES.
;
;  25	JGZ	6-DEC-79
;		MAKE CALLS TO CLRABT IN THE APPROPRIATE PLACES SO WE HAVE
;		NO UNEXPECTED INTERRUPTS ENABLED.
;
;  26	JGZ	6-DEC-79
;		SAVE .JBUUO IN STSINT SO LUUOS ARE INTERRUPTIBLE. (ABTINT
;		DOESN'T CONTINUE, SO NOT NEEDED THERE.)
;
;  27	JGZ	18-JAN-80
;		ADD CONTROLLER FIELD TO INFORMATION DISPLAY.  IT WILL BE
;		NEEDED IN THE FUTURE FOR RP20.  ADD RP20 TO DISK TYPE TABLE.
;
;  30	JGZ	28-JAN-80
;		ADD REPEAT COUNT AND CONTROL-E INTERRUPT TO CHECK PAGE TO
;		ALLOW "BEATING" ON A PAGE.  UPDATE HELP TEXT.
;
;  31	JGZ	28-JAN-80
;		MORE EXTRA CRLFS IN ERROR TEXTS NEEDED.
;
	SUBTTL	DEFINITIONS

;ACCUMULATORS:

	F=0			;FLAGS
	T1=1			;TEMPORARY AC'S
	T2=2
	T3=3
	T4=4
	Q1=5			;PRESERVED Q AC'S
	Q2=6
	Q3=7
	P1=10			;PRESERVED P AC'S
	P2=11
	P3=12
	P4=13
	P5=14
	P6=15
	CX=16			;USE BY MACROS,...
	P=17			;STACK




;MACROS, OPDEFS, AND DEFSTRS:


	DEFINE	AA(NAME,DATA),<		;;MACRO FOR COMMAND TABLES
	XWD	[ASCIZ/NAME/],DATA
>


	DEFINE	TEXT(STRING),<		;;MACRO FOR ASCIZ TEXT
	XLIST
	ASCIZ\STRING\
	LIST
>

	DEFINE	PTXT(STRING),<		;;MACRO FOR POINTER TO STRING
	POINT 7,[ASCIZ\
STRING\]
>

	DEFINE	SVFLGS,<
	JSP	CX,.SAVEF		;;MACRO FOR SAVING FLAGS
>

	OPDEF	CONFRM	[CALL	DOCNFM]	;COMND CONFIRN FUNCTION

	OPDEF	PARSE	[CALL	COMMND]	;MAKE THE COMND CALL

	DEFINE	NOISE(STRING),<		;;MACRO TO DO COMND GUIDEWORD CALL
	MOVEI	T2,[TEXT(STRING)]
	CALL	DONOIS
>

	OPDEF	PRINT.	[1B8]		;PRINT LUUO

	DEFINE	PRINT(STRING),<
	PRINT.	[ASCIZ\STRING\]		;;MACRO FOR CALLING PRINT LUUO
>

	OPDEF	TYPE.	[2B8]		;TYPE LUUO

	DEFINE	TYPE(STRING),<
	TYPE.	[ASCIZ\STRING\]		;;MACRO FOR CALLING TYPE LUUO
>

	OPDEF	WARN.	[3B8]		;WARN LUUO

	DEFINE	WARN(STRING),<
	WARN.	[ASCIZ\STRING\]		;;MACRO FOR CALLING WARN LUUO

>

	OPDEF	ERROR.	[4B8]		;ERROR LUUO

	DEFINE	ERROR(STRING),<
	ERROR.	[ASCIZ\STRING\]		;;MACRO FOR CALLING ERROR LUUO
>

	OPDEF	OCTOU.	[5B8]		;OCTAL OUTPUT LUUO

	DEFINE	OCTOUT(VALUE,SIZE),<	;;MACRO FOR CALLING OCTOUT LUUO
	IFB <SIZE>,<	OCTOU.	0,VALUE>
	IFNB <SIZE>,<	OCTOU.	SIZE,VALUE>
>

	OPDEF	DECOU.	[6B8]		;DECIMAL OUTPUT LUUO

	DEFINE	DECOUT(VALUE,SIZE),<	;;MACRO FOR CALLING DECOUT LUUO
	IFB <SIZE>,<	DECOU.	0,VALUE>
	IFNB <SIZE>,<	DECOU.	SIZE,VALUE>
>



	DEFSTR	DS%TYP,,35,2		;PAGE TYPE CODE PASSED TO RDCHK

	DEFSTR	UUONUM,.JBUUO##,8,9	;LUUO OPCODE FIELD
	DEFSTR	UUOAC,.JBUUO##,12,4	;LUUO AC FIELD
;DEFAULT PARAMETERS:


	TXTLEN==^D100		;SIZE OF COMMAND BUFFERS
	PDLSIZ==100		;SIZE OF PUSHDOWN STACK



;FLAGS:


	FL%PHY==1B1		;UNIT SPECIFIED, ZERO IMPLIES STRUCTURE
	FL%LNG==1B2		;LONG FILE NOTICED INDICATOR
	FL%SUS==1B3		;STRUCTURE OR UNIT HAS BEEN SPECIFIED
	FL%TMP==1B4		;TEMPORARY FLAG USED IN VARIOUS PLACES

	DS%BAT==1B18		;INDEX BLOCK IS MARKED FOR A BAD PAGE
	DS%CHK==1B19		;INDEX BLOCK CHECKSUP IS WRONG
	DS%NEC==1B20		;REQUEST NO ECC ON DSKOP
	DS%NEL==1B21		;REQUEST NO LOGGING ON DSKOP

				;NOTE: EQUIVALENT BAT AND HOME BLOCK BITS
				;ARE TIMESHARED
	HB%1B==1B22		;PRIMARY HOME BLOCK CHECKED OUT BAD
	HB%2B==1B23		;SECONDARY HOME BLOCK CHECKED OUT BAD
	HB%IB==1B24		;HOME BLOCKS ARE INCONSISTENT
	HB%1VB==1B25		;PRIMARY HOME BLOCK IS UNREADABLE
	HB%1SB==1B26		;PRIMARY HOME BLOCK READ ENCOUNTERED ERRORS
	HB%2VB==1B27		;SECONDARY HOME BLOCK IS UNREADABLE
	HB%2SB==1B28		;SECONDARY HOME BLOCK READ ENCOUNTERED ERRORS

	BB%1B==1B22		;PRIMARY BAT BLOCK CHECKED OUT BAD
	BB%2B==1B23		;SECONDARY BAT BLOCK CHECKED OUT BAD
	BB%IB==1B24		;BAT BLOCKS ARE INCONSISTENT
	BB%1VB==1B25		;PRIMARY BAT BLOCK IS UNREADABLE
	BB%1SB==1B26		;PRIMARY BAT BLOCK READ ENCOUNTERED ERRORS
	BB%2VB==1B27		;SECONDARY BAT BLOCK IS UNREADABLE
	BB%2SB==1B28		;SECONDARY BAT BLOCK READ ENCOUNTERED ERRORS
;CONSTANTS:
;PAGE TYPE CODES FOR THE DS%TYP FIELD

	.DSDAT==1		;DATA PAGE
	.DSXB==2		;INDEX BLOCK
	.DSSXB==3		;SUPER INDEX BLOCK

;RDCHK RETURN CODES FOR DISK READ

	.DSOK==0		;READ WITHOUT ERROR
	.DSRND==1		;TRANSIENT READ ERROR (WITHOUT ECC)
	.DSECC==2		;READ REQUIRED ECC
	.DSHRD==3		;UNREADABLE

;INDEX BLOCK CONSTANTS

	STGADR==77,,777777	;MASK FOR A DISK ADDRESS
	XBBWRD==4		;OFFSET INTO INDEX BLOCK FOR BAT BIT
	XBBAT==1B0		;BAT BIT IN INDEX BLOCK


;PAGE AND DISK BLOCK VARIABLES

	PGSIZ==1000		;SIZE OF A PAGE
	PGSHFT==^D9		;BITS IN A PAGE OFFSET FOR SHIFTS

	SXBPAG==500000		;PAGE ADDRESS FOR SUPER INDEX BLOCKS
	XBPAG==501000		;PAGE FOR INDEX BLOCKS
	DATPAG==502000		;PAGE FOR DATA DSKOPS

	HOM1AD==503000		;PRIMARY HOMEBLOCKS (BLT'ED HERE AFTER READ)
	HOM2AD==HOM1AD+HBLEN	;SECONDARY HOMEBLOCKS

	BAT1AD==HOM2AD+HBLEN	;PROMARY BAT BLOCKS
	BAT2AD==BAT1AD+HBLEN	;SECONDARY BAT BLOCKS


;PSI SYSTEM VARIABLES

	INTCHN==0		;CHANNEL FOR ^E INTERRUPT
	STSCHN==1		;CHANNEL FOR STATUS (^A) INTERRUPT
;HOME BLOCK DEFINITIONS

	HOMBL1==1		;SECTOR OF FIRST HOM BLOCK
	HOMBL2==^D10		;SECTOR OF SECOND HOM BLOCK

	HOMNAM==0		;SIXBIT/HOM/
	HOMID==1		;NOT USED BY TOPS-20
	HOMPHY==2		;NOT USED BY TOPS-20
	HOMSNM==3		;SIXBIT/STRUCTURE NAME/
	HOMLUN==4		;# PACKS IN STR,,LOGICAL UNIT IN STR
	HOMHOM==5		;THIS,,OTHER HOME BLOCK #
	HOMP4S==6		;# PAGES FOR SWAPPING
	HOMFST==7		;FIRST SWAPPING CYLINDER
	HOMRXB==10		;ADDRESS OF XB FOR ROOT-DIRECTORY
	HOMBXB==11		;ADDRESS OF XB FOR BACKUP-COPY-OF-ROOT-DIRECTORY
	HOMFLG==12		;FLAGS WORD - CONTAINS MS%LIM,
				; LIMIT/UNLIMIT BIT FOR DIRECTORIES
	HOMSIZ==13		;NUMBER OF SECTORS IN UNIT
	HOMBTB==14		;NUMBER OF TRACKS IN STRUCTURE
	HOMMID==15		;PACK UNIQUE CODE
	HOMFE0==61		;FRONT END FILE SYSTEM STARTING SECTOR
	HOMFE1==62		;FRONT END FILE SYSTEM SIZE IN SECTORS
	HOMFE2==101		;BOOTSTRAP.BIN STARTING SECTOR (KS FE)
	HOMFE3==102		;BOOTSTRAP.BIN SIZE IN SECTORS (KS FE)
	HOMFE4==103		;KS - 8080 CYLINDER/TRACK/SECTOR WORD
	DEFSTR	MICCYL,,11,9	; CYLINDER BITS
	DEFSTR	MICTRK,,27,5	; TRACK BITS
	DEFSTR	MICSEC,,35,5	; SECTOR BITS
	HOMUID==165		;3 WORDS - 12 CHAR -11 FORMAT UNIT ID
	HOMOID==170		;3 WORDS - 12 CHAR -11 FORMAT OWNER ID
	HOMFSN==173		;3 WORDS - 12 CHAR -11 FORMAT FILE SYSTEM NAME
	HOMCOD==176		;IDENTIFIABLE CODE 0,,707070
	CODHOM==707070		;THE CODE
	HOMSLF==177		;THIS BLOCK NUMBER

	HBLEN==200		;SIZE OF A HOM OR BAT BLOCK

;VARIABLES USED IN MOUNTING STRUCTURES

	HB%PUB==:1B0		;PUBLIC STR
	HB%1OK==:1B1		;FIRST HOME BLOCK OK
	HB%2OK==:1B2		;SECOND HOME BLOCK OK
	HB%HBM==:1B3		;HOME BLOCKS MATCH
	HB%MUN==:1B4		;MULTIPLE LOGICAL UNITS IN STR
	HB%WLK==:1B5		;THIS UNIT IS WRITE-LOCKED
;BAT BLOCK VARIABLES

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

	BATNAM==0		;SIXBIT/BAT/
	BATFRE==1		;-NUMBER OF FREE PAIRS,,OFFSET OF FIRST FREE
	DEFSTR	BATFR,BATFRE,17,18 ;FIELD WITH FREE COUNT
	MAXBFR==^D61*2		;MAXIMUM NUMBER OF BAT BLOCK PAIRS
	BATMAP==2		;MAPPER WORD
	DEFSTR	BTHCT,BATMAP,17,9 ;NUMBER OF PAIRS ADDED BY MAPPER
	BATCNT==3		;MONITOR WORD
	DEFSTR	BTMCT,BATCNT,35,36 ;NUMBER OF PAIRS ADDED BY MONITOR
	BAT1P==4		;OFFSET OF FIRST DATA PAIR
	BATCOD==176		;IDENTIFIABLE CODE 0,,606060
	CODBAT==606060		;THE CODE
	BATBLK==177		;THIS BLOCK NUMBER

	DEFSTR	BATNB,0,8,9	;SECTOR COUNT FOR BAD BLOCK PAIR-1
	DEFSTR	BTKNM,0,20,3	;MASSBUS CONTROLLER NUMBER
	DEFSTR	BTUNM,0,17,9	;BIT MASK FOR UNIT 1B17=0...
	DEFSTR	BADT,0,21,1	;TYPE - 0=ADD18, 1=ADD27 STGADR
	DEFSTR	APRNM,0,35,14	;APR SERIAL NUMBER OF DETECTING PROCESSOR

	DEFSTR	ADD18,1,35,18	;OLD STYLE DISK ADDRESS OF STARTING SECTOR
	DEFSTR	ADD27,1,35,27	;NEW STYLE ADDRESS OF STARTING SECTOR

;OTHER

	LNBRK==3		;MASK FOR LINE BREAK TEST IN XBDMP

	DEFSTR	ELVB0,,17,8	;ELEVEN-FORMAT BYTE 0 OF A WORD
	DEFSTR	ELVB1,,9,8	;BYTE 1
	DEFSTR	ELVB2,,35,8	;BYTE 2
	DEFSTR	ELVB3,,27,8	;BYTE 3

	DEFRDX==5740		;NORMAL ADDRESS FOR ROOT DIR XB
	DEFBRD==13700		;NORMAL ADDRESS FOR BACKUP ROOT DIR XB

	DEFMIC==224		;DEFAULT DISK ADR FOR KS DIR IF HOME UNREADABLE
	DEFSTR	MICLEN,1,35,18	;LENGTH IN PAGES FROM KS 8080 DIRECTORY
	DEFSTR	MICPGO,1,17,18	;PAGE OFFSET IN KS FE FILE OF START OF FILE
	MICUSD==700077,,760340	;MASK FOR UNUSED CYL/TRK/SEC BITS
	SUBTTL	ENTRY VECTOR AND INITIALIZATION

EVEC:	JRST	DS		;START
	JRST	REEN		;REENTER
	BYTE	(3)VWHO(9)VMAJOR(6)VMINOR(18)VEDIT	;VERSION



DS:	SETZ	F,		;CLEAR ALL FLAGS
	TMSG	<DS Disk Utility Program %>	;TYPE BANNER AND VERSION
	MOVE	P,[IOWD	PDLSIZ,PDL] ;SETUP A STACK
	MOVEI	T1,.PRIOU	;OUTPUT TO TERMINAL
	CALL	VEROUT		;DO THE VERSION NUMBER
	TMSG	<

>				;AND A CRLF
	MOVX	T1,.FHSLF	;FIND OUT OUR
	RPCAP			; CAPABILITIES
	MOVEM	T3,OLDCAP	;SAVE THE CURRENT ONES
	MOVE	T3,T2		;ASK FOR ALL WE CAN GET
	EPCAP			; ENABLED FOR US

REEN:	RESET			;CLEAR EVERYTHING
	MOVE	P,[IOWD PDLSIZ,PDL]	;SET UP A STACK
	SETZM	TAKJFN		;CLEAR TAKE FILE JFN/STATE
	SETZM	OJFN		;CLEAR OUTPUT JFN
	MOVE	T1,[CALL UUOH]	;SET UP THE
	MOVEM	T1,.JB41##	;LUUO SYSTEM
	MOVX	T1,.FHSLF	;SETUP THE
	MOVE	T2,[LEVTAB,,CHNTAB] ; INTERRUPT SYSTEM
	SIR
	MOVX	T1,.FHSLF	;AND ACTIVATE
	MOVX	T2,1B<INTCHN>+1B<STSCHN> ;THE CHANNEL TO USE FOR ^E INTERRUPTS
				; AND THE CHANNEL FOR STATUS INTERRUPTS
	AIC			;SET THEM UP
	MOVX	T1,.FHSLF	;AND FINALLY
	EIR			; TURN IT ON, WITH NOTHING ON THE CHANNEL


NEWCMD:	MOVEI	T1,CMDBLK	;POINT TO COMMAND BLOCK
	MOVEI	T2,[FLDDB. .CMINI]	;INITIALIZATION FUNCTION
	PARSE			;GO DO IT
	MOVEM	P,SAVEP		;SAVE STACK FOR REPARSING

	;...

NEWPAR:	MOVE	P,SAVEP		;RESTORE THE STACK
	SKIPE	T1,JFNTMP	;UNLOAD ANY LEFTOVER JFNS
	RLJFN			; FROM REPARSING,...
	 ERJMP	.+1		;DON'T WORRY ABOUT ERRORS
	SETZM	JFNTMP		;AND MARK THE "JFN STACK" EMPTY
	MOVEI	T1,CMDBLK	;POINT TO THE COMMAND BLOCK
	MOVEI	T2,[FLDDB. (.CMKEY,,CMDTAB)]	;POINT TO COMMAND TABLE
	PARSE			;READ IT
	MOVE	T2,0(T2)	;GET ADDRESS OF ROUTINE
	CALL	0(T2)		;CALL IT
	JRST	NEWCMD		;AND GET A NEW COMMAND


RSKP:	AOS	0(P)		;YE OLDE SKIP
R:	RET			; AND NONSKIP RETURNS


;TABLE OF COMMANDS:


CMDTAB:	CMDLEN,,CMDLEN			;HEADER
	AA	CHECK,CMDCHE		;CHECK COMMANDS
	AA	COPY,CMDCPY		;COPY COMMAND
	AA	DRIVE,CMDDRI		;SPECIFY DRIVE TO USE
	AA	DUMP,CMDDMP		;DUMP COMMANDS
	AA	EXIT,CMDXIT		;EXIT COMMAND
	AA	FILDDT,CMDDDT		;GET FILDDT IN A LOWER FORK
	AA	HELP,CMDHLP		;TYPE HELP MESSAGE
	AA	INFORMATION,CMDINF	;INFORMATION ABOUT DISK UNITS
	AA	OUTPUT,CMDOUT		;SPECIFY OUTPUT JFN
	AA	PUSH,CMDPSH		;PUSH TO A NEW EXEC
	AA	STRUCTURE,CMDSTR	;SPECIFY STRUCTURE TO USE
	AA	TAKE,CMDTAK		;TAKE COMMANDS FROM FILE
	AA	VERIFY,CMDVER		;VERIFY PACK BY DSKOP READS

	CMDLEN==.-CMDTAB-1		;NUMBER OF COMMANDS
	SUBTTL	THE SIMPLE COMMANDS - EXIT, HELP



;EXIT FROM PROGRAM.  "EXIT" COMMAND.


CMDXIT:	NOISE	(FROM PROGRAM)	;DO GUIDEWORDS
	CONFRM			;THEN CONFIRM THE COMMAND
	SKIPE	T1,OJFN		;CHECK AND
	CLOSF			; CLOSE ANY OUTPUT
	 ERJMP	.+1		; IGNORE
	MOVX	T1,.FHSLF	;READ OUR CAPABILITIES
	RPCAP			; TO GE MASK
	 ERJMP	.+1		;FORGET ERRORS
	MOVE	T3,OLDCAP	;GET OUR OLD CAPABILITIES
	EPCAP			; AND TRY TO RESTORE THEM
	 ERJMP	.+1		;FORGET THIS ERROR TOO
	HALTF			;QUIT FOR THE NONCE
	JRST	DS		; AND MAKE CONTINUE INTO A START



;THE "HELP" COMMAND.


CMDHLP:	NOISE	(WITH COMMANDS)	;DO GUIDEWORDS
	CONFRM			;CONFIRM THE LINE
	HRROI	T1,HLPTXT	;POINT TO HELP MESSAGE
	PSOUT			;TYPE IT
	RET			;AND RETURN
HLPTXT:	TEXT<
     DS is a program which is designed to provide information and certain
software diagnostic help concerning the disk file system.  Most functions
require privileges for operation.    The intent is not to take corrective
action with this program, but to provide information allowing such action
to be taken.  The commands are:

CHECK		Check and report the results on one of the following:

		FILE-READABILITY Check files specified by possibly wild
				file specification for readability by
				using DSKOPs and report any errors that
				are encountered.  Control-E will abort.
		INDEX-BLOCK	Check specified disk address for a
				valid index block including BAT bit,
				checksum, and non-address bits.
		PAGE		Check page at specified disk address
				report any problems reading page.
				Repeat count or UNTIL-STOPPED may be
				given.  Control-E will abort.
COPY		Copy out a regular or long file to a destination file by
		providing the disk address of the index block or address
		of the super index block, or provide address of a single
		disk page to be copied out.  The output must be to disk.
DRIVE		Specify a specific channel and unit to be accessed.
DUMP		Output an interpretive listing of one of:

		BAT-BLOCKS	Descriptive list of BAT block contents.
		HOME-BLOCKS	Descriptive list of HOME block contents.
		INDEX-BLOCKS	List of disk addresses in index block(s)
				for the specified file.
				Control-E will abort.
		MICROPROCESSOR-FILE-SYSTEM-DIRECTORY
				Descriptive list of directory page for
				microprocessor file system for the KS
				processor (2020).  Control-E will abort.
		PAGE		List contents of page at specified disk
				address in Octal and SIXBIT and ASCII.
				Control-E will abort.
EXIT		Exit from the program.
FILDDT		Transfer control to SYS:FILDDT in an inferior process.
HELP		Type this text.
INFORMATION	Displays the status of the disk drives on the system.
OUTPUT		Specify output file used for some of the commands.
PUSH		Transfer control to an EXEC in an inferior process.
STRUCTURE	Specify a disk structure to use in subsequent commands.
TAKE		Read subsequent commands from the specified file.
VERIFY		Read-check the selected structure or unit using DSKOPs.
		Output any errors encountered.  Interruptible by using
		Control-E to abort, and Control-A will output a status
		line of the current disk address and cumulative error
		total.
>
	SUBTTL	FILDDT AND PUSH COMMANDS

;PUSH COMMAND TO PUSH TO A NEW EXEC IN AN INFERIOR FORK

CMDPSH:	NOISE	(COMMAND LEVEL)	;DO GUIDEWORDS
	CONFRM			;CONFIRM THE COMMAND
	HRROI	T2,[ASCIZ/SYSTEM:EXEC.EXE/] ;FILENAME FOR EXEC
	JRST	DOFORK		;JOIN COMMON CODE



;FILDDT COMMAND TO PUSH TO FILDDT IN AN INFERIOR FORK

CMDDDT:	NOISE	(IN AN INFERIOR FORK)	;DO GUIDEWORDS
	CONFRM			;CONFIRM THE COMMAND
	HRROI	T2,[ASCIZ/SYS:FILDDT.EXE/] ;FILENAME FOR FILDDT


;COMMON CODE FOR HANDLING AN INFERIOR.  GET THE FILE, START IT UP
;IN AN INFERIOR FORK, AND WAIT FOR IT TO FINISH, THEN RETURN.

DOFORK:	MOVX	T1,GJ%PHY!GJ%OLD!GJ%SHT	;GTJFN BITS
	GTJFN			;GET A HANDLE ON THE FILE
	 ERJMP	LOSE		;UNAVAILABLE???
	MOVEM	T1,JFNX		;SAVE JFN TO IT
	MOVX	T1,CR%CAP	;PRESERVE OUR CAPABILITIES
	CFORK			;BUILD A FORK
	 ERJMP	LOSE		;COULDN'T
	MOVEM	T1,HANDLE	;SAVE FORK HANDLE
	MOVSS	T1		;HANDLE TO LEFT HALF
	HRR	T1,JFNX		;JFN TO RIGHT
	GET			;GET THE FILE
	 ERJMP	LOSE		;COULDN'T
	MOVE	T1,HANDLE	;FETCH FORK HANDLE
	SETZ	T2,		;NORMAL START
	SFRKV			;START THE FORK UP
	 ERJMP	LOSE		;CAN'T
	WFORK			;WAIT FOR IT TO COME BACK
	 ERJMP	LOSE		;TROUBLE
	KFORK			;IS DONE, SO KILL IT
	 ERJMP	LOSE		;FAILED
	SETZM	HANDLE		;NO MORE FORK
	RET			; AND COMMAND IS FINISHED
	SUBTTL	TAKE COMMAND


;TAKE COMMAND TO READ COMMAND FROM DESIGNATED FILE BY SETTING UP
;THE PRIMARY I/O JFNS TO POINT TO THE FILE.
;UNTAKE ROUTINE CALLED TO RESET THE STATE WHEN THE END OF THE TAKE
;FILE IS ENCOUNTERED.

CMDTAK:	NOISE	(COMMANDS FROM FILE)	;DO GUIDEWORDS
	SETZM	JFNBLK+.GJNAM	;CLEAR ANYTHING THAT MAY HAVE BEEN HERE
	HRROI	T2,[ASCIZ/CMD/]	;DEFAULT EXTENSION FOR FILE
	MOVEM	T2,JFNBLK+.GJEXT ;TO JFN BLOCK FOR GTJFN
	MOVX	T2,GJ%OLD	;FILE MUST EXIST
	MOVEM	T2,JFNBLK+.GJGEN
	MOVEI	T2,[FLDDB. (.CMFIL)] ;ASK FOR A FILE
	PARSE	
	MOVEM	T2,JFNTMP	;SAVE JFN FOR A MOMENT
	CONFRM			;CONFIRM THE COMMAND
	SKIPE	TAKJFN		;TEST--DON'T ALLOW NESTING
	JRST	[TMSG	<
? Nesting of TAKE files is not allowed -- command file aborted
>
		 CALL	UNTAKE		;CLEAR STATE AND
		 JRST	REEN]		;DIE SOMEHOW
	HRRZ	T1,JFNTMP	;GET BACK JFN
	MOVEM	T1,TAKJFN	;SAVE THE JFN
	SETZM	JFNTMP		; AND CLEAR THE TEMP SLOT
	MOVX	T2,7B5+OF%RD	;READ AS ASCII FILE
	OPENF			;OPEN IT
	 ERJMP	LOSE		;FAILED
	MOVEI	T1,.FHSLF	;OUR PROCESS
	GPJFN			;GET OLD PRIMARY I/O
	MOVEM	T2,OLDPRM	;SAVE FOR RESTORE
	HRL	T2,TAKJFN	;POINT TO TAKE FILE
	SPJFN			; AS PRIMARY INPUT
	 ERJMP	LOSE		;COULDN'T
	MOVX	T2,.NULIO	;MARK COMND BLOCK OUTPUT
	HRRM	T2,CMDBLK+.CMIOJ ; AS NUL SO DON'T GET PROMPTS
	RET			;AND DONE--RESET AT EOF BY UNTAKE
;UNTAKE - ROUTINE CALLED TO UNDO THE EFFECTS OF THE TAKE COMMAND
;RESETS THE PRIMARY I/O AND CLEANS UP THE JFN.

UNTAKE:	MOVEI	T1,.PRIOU	;RESET COMND BLOCK OUTPUT DESIGNATOR
	HRRM	T1,CMDBLK+.CMIOJ ;SO WE GET OUR PROMPTS,... BACK
	MOVEI	T1,.FHSLF	;OUR PROCESS
	SKIPE	T2,OLDPRM	;OLD DESIGNATORS
	SPJFN			;RESTORE
	SETZM	OLDPRM		;AND CLEAR
	SKIPE	T1,TAKJFN	;TAKE FILE JFN
	CLOSF			;CLOSE IT
	 ERJMP	.+1		;IGNORE ERRORS (AND POSSIBLE LOSE LOOP)
	SKIPE	T1,TAKJFN	;GET JFN AGAIN
	RLJFN			;RELEASE IT
	 ERJMP	.+1
	SETZM	TAKJFN		;RESET TAKE STATE
	RET			;DONE
	SUBTTL	OUTPUT FILE SPECIFICATION COMMAND

;THE OUTPUT COMMAND COMES HERE TO SPECIFY THE FILENAME TO ROUTE
;OUTPUT TO FOR THOSE COMMANDS THAT MIGHT DO IT, IE VIA THE PRINT LUUO.
;THE JFN IS STORED IN OJFN TO DENOTE THE FILE BEING OPEN.
;ANY PREVIOUS JFN IS CLOSED AND RELEASED.

CMDOUT:	NOISE	(INFORMATION TO FILE)	;DO GUIDEWORDS
	MOVEI	T2,[FLDDB. (.CMOFI,,,,<TTY:>)]
	PARSE			;GET A JFN
	MOVEM	T2,JFNTMP	;SAVE JFN FOR A MOMENT
	CONFRM			;CONFIRM THE LINE
	MOVE	T1,JFNTMP	;GET THE JFN
	MOVX	T2,FLD(7,OF%BSZ)+OF%WR ;WANT TO WRITE IN ASCII
	OPENF			;OPEN THE FILE
	 ERJMP	[ERROR	Cannot open file for output]
	SKIPE	T1,OJFN		;ONE ALREADY OPEN?
	 JRST	[CLOSF			;YES, TRY THE CLOSE
		  ERJMP	LOSE		;OH WELL...
		 JRST	.+1]	;AND CONTINUE IN LINE
	MOVE	T1,JFNTMP	;SETUP THE JFN
	MOVEM	T1,OJFN		; IN OFJN TO USE
	SETZM	JFNTMP		; AND CLEAR TEMP JFN
	RET			;AND WE ARE DONE HERE
	SUBTTL	DRIVE SPECIFICATION COMMAND

;THE DRIVE COMMAND COMES HERE TO SPECIFY THE SPECIFIC CHANNEL AND UNIT
;FOR THE DESIRED DRIVE.  THIS INFORMATION IS STORED IN DSKPHY FOR DSKOPS
;AND THE FL%PHY BIT IS SET TO INDICATE THAT WE ARE PROCESSING ON A UNIT,
;NOT A STRUCTURE BASIS WHERE APPROPRIATE.

CMDDRI:	NOISE	(TO USE IS ON CHANNEL)	;DO GUIDEWORDS
	SETZ	P1,		;START CLEAN
	MOVEI	T2,[FLDDB. (.CMNUM,CM%SDH,^D8,<Channel number>,<0>)]
	PARSE			;PARSE THE CHANNEL
	CAIL	T2,0		;SOME SORT OF
	CAILE	T2,^D7		; REASONABLENESS CHECK
	 ERROR	Channel number out of range
	STOR	T2,DOP%CN,P1	;STORE IN DSKPHY FIELD IN P1
	NOISE	(UNIT)		;MORE APPROPRIATE MUMBLE
	MOVEI	T2,[FLDDB. (.CMNUM,CM%SDH,^D8,<Unit number in octal>,<0>)]
	PARSE			;PARSE THE UNIT
	CAIL	T2,0		;ANOTHER
	CAILE	T2,^D7		; REASONABLENESS CHECK
	 ERROR	Unit number out of range
	STOR	T2,DOP%UN,P1	;STORE IN DSKPHY FIELD IN P1
	CONFRM			;CONFIRM THE LINE
	MOVEI	T2,.DOPPU	;PHYSICAL ADDRESSING CODE
	STOR	T2,DOP%AT,P1	;SET IT UP
	MOVEM	P1,DSKPHY	;AND STORE IN DSKPHY WORD
	TXO	F,FL%PHY+FL%SUS	;AND FINALLY SET THE PHYSICAL ADDRESSES BIT
	CALL	UNTINF		;MAKE SURE THERE IS A UNIT THERE
	TXNE	T1,MS%MNT	;TEST AND REPORT
	 WARN	Unit is part of a mounted Structure
	TXNE	T1,MS%DIA	;DIAGNOSTIC?
	 WARN	Unit is in use by an On-line Diagnostic
	TXNE	T1,MS%OFL	;OFF-LINE?
	 WARN	Unit is currently Off-line
	TXNE	T1,MS%ERR	;ERRORS?
	 WARN	Unit has had errors detected during reading
	TXNE	T1,MS%BBB	;BAT PROBS?
	 WARN	Unit has a bad BAT Block
	TXNE	T1,MS%HBB	;HOM PROBS?
	 WARN	Unit has a bad HOME Block
	TXNE	T1,MS%WLK	;WRITE LOCK?
	 WARN	Unit is Write-locked
	RET			;AND RETURN
	SUBTTL	STRUCTURE SPECIFICATION COMMAND

;THE STRUCTURE COMMAND COMES HERE TO SPECIFY THE STRUCTURE NAME TO
;USE FOR OTHER COMMANDS.  THE STRUCTURE DESIGNATOR IS STORED IN THE
;VARIABLE DSKSTR AND THE FLAG FL%PHY IS CLEARED TO INDICATE THAT
;STRUCTURE RELATIVE ADDRESSING IS USED.


CMDSTR:	NOISE	(TO USE)	;DO GUIDEWORDS
	MOVEI	T2,[FLDDB. (.CMDEV)]
	PARSE			;TRY TO PARSE A DEVICE NAME
	MOVE	T1,T2		;COPY AND
	DVCHR			; GET CHARACTERISTICS
	 ERJMP	LOSE
	LOAD	T3,DV%TYP,T2	;GET THE TYPE
	CAIE	T3,.DVDSK	;IS IT A DISK?
	 ERROR	Device is not a disk
	MOVE	P1,T1		;SAVE DESIGNATOR TIL CONFIRMED
	CONFRM			;CONFIRM THE LINE
	MOVEM	P1,DSKSTR	;SAVE DESIGNATOR
	TXZ	F,FL%PHY	;MARK NOT PHYSICAL ADDRESSING
	TXO	F,FL%SUS	;MARK STRUCTURE/UNIT SPECIFIED
	RET			; AND DONE
	SUBTTL	INFORMATION COMMAND TO DISPLAY DRIVE STATUS

;THE INFORMATION COMMAND COMES HERE TO TYPE OUT A DISPLAY OF THE STATUS
;OF THE DISK DRIVES ON THE SYSTEM.  THE FOLLOWING ITEMS ARE DISPLAYED:
;CHANNEL/UNIT, ALIAS, STRUCTURE-ID, LOGICAL UNIT, DRIVE TYPE, AND
;STATUS (MOUNTED, BAD BATS, DIAG, ERRORS, OFF-LINE...)

CMDINF:	NOISE	(ABOUT DISK UNITS)	;DO GUIDEWORDS
	CONFRM			;CONFIRM THE LINE
	CALLRET	DSKSTA		;AND DO THE DISK STATUS DISPLAY



;DSKSTA - ROUTINE TO DO DISK STATUS DISPLAY FOR INFO COMMAND
;	CALL	DSKSTA
;RETURNS  +1:	ALWAYS

DSKSTA:	PRINT	<
Channel Unit Controller Alias  Str-ID  Pack Type  Disk Status

>				;THE HEADER LINE
	SETOM	MSBLK+.MSRCH	;INITIALIZE THE CHANNEL,
	SETOM	MSBLK+.MSRCT	; CONTROLLER, AND
	SETOM	MSBLK+.MSRUN	; UNIT TO MINUS ONE FOR FIRST CALL

DSKSTL:	CALL	UNTSTS		;GET THE STATUS OF THE NEXT UNIT
	 JRST	[PRINT	<
>					;A FINAL CRLF
		 RET]			;AND ALL DONE

	MOVE	Q1,MSBLK+.MSRST	;HOLD STATUS HERE FOR EASY ACCESS
	OCTOUT	MSBLK+.MSRCH,6	;SIX DIGITS OF OCTAL CHANNEL NUMBER

	OCTOUT	MSBLK+.MSRUN,5	;FIVE DIGITS OF OCTAL UNIT NUMBER

	SKIPGE	MSBLK+.MSRCT	;CONTROLLER EXIST?
	 JRST	[PRINT	<      -->	;NO, JUST DO DASHES
		 JRST	.+2]		;AND GO ON
	OCTOUT	MSBLK+.MSRCT,^D8 ;YES, DO 8 DIGITS OF CONTROLLER

	PRINT	<     >		;SPACE OVER
	;...
	SKIPN	T1,OJFN		;PICK UP PROPER OUTPUT
	MOVX	T1,.PRIOU	; DESIGNATOR
	HRROI	T2,ALIAS	;POINT AT ALIAS
	TXNN	Q1,MS%MNT	;MOUNTED?
	HRROI	T2,[ASCIZ/      /] ;NO, BLANKS
	MOVEI	T3,^D8		;MAX CHARS
	MOVEI	T4,0		;END WITH NULL
	SOUT			;OUTPUT
	 ERJMP	LOSE
	CALL	SPACEN		;HANDLE SPACING

	HRROI	T2,STRID	;POINT AT STRUCTURE ID
	TXNE	Q1,MS%OFL	;OFF-LINE?
	HRROI	T2,[ASCIZ/      /] ;YES--NO STR ID THEN
	MOVEI	T3,^D8		;MAX CHARS
	MOVEI	T4,0
	SOUT
	 ERJMP	LOSE
	CALL	SPACEN		;HANDLE SPACING

	TXNE	Q1,MS%OFL	;NOT APPROPRIATE IF OFFLINE
	JRST	[PRINT	<      >	;SPACING
		 JRST	DSKST1]		;GO AHEAD
	HLRZ	T2,MSBLK+.MSRNS	;LOGICAL UNIT
	AOS	T2		;MAKES MORE SENSE
	OCTOUT	T2,2		;TWO OCTAL DIGITS
	PRINT	</>		;SEPARATOR
	HRRZ	T2,MSBLK+.MSRNS	;NUMBER OF UNITS
	OCTOUT	T2,1		;ONE OCTAL DIGIT
	PRINT	<  >		;SPACE OVER

DSKST1:	LOAD	T2,MS%TYP,Q1	;FETCH DRIVE TYPE
	CAILE	T2,MXUTYP	;RANGE CHECK
	SETZ	T2,		;FAKE WITH ZERO IF UNKNOWN
	MOVE	T2,UNTYTB(T2)	;FETCH POINTER
	SETZ	T3,
	SOUT			;OUTPUT THE FOUR CHARACTERS
	 ERJMP	LOSE

	PRINT	<  >		;SPACE OVER
	TXNN	Q1,MS%OFL	;OFF-LINE?
	JRST	DSKST2		;NO, CHECK THE REST
	PRINT	<Off-line>	;SAY OFF-LINE
	JRST	DSKST8		; AND NO MORE STATUS INFO
	;...

DSKST2:	TXNE	Q1,MS%MNT	;MOUNTED?
	PRINT	<Mounted >	;SAY SO

	TXNE	Q1,MS%DIA	;DIAGNOSTIC?
	PRINT	<Diagnostic >	;SAY SO

	TXNE	Q1,MS%ERR	;ERRORS?
	PRINT	<Errors >	;SAY SO

	TXNE	Q1,MS%BBB	;BAD BAT-BLOCKS?
	PRINT	<BadBAT >	;SAY SO

	TXNE	Q1,MS%HBB	;BAD HOME-BLOCKS?
	PRINT	<BadHOM >	;SAY SO

	TXNE	Q1,MS%WLK	;WRITE-LOCKED?
	PRINT	<Write-locked>	;SAY SO

DSKST8:	PRINT	<
>				;CRLF TO END LINE
	JRST	DSKSTL		;AND CONTINUE LOOPING



;DISK UNIT TYPE NAME TABLE

UNTYTB:	-1,,[ASCIZ "UNK "]	;0 - UNKNOWN
	-1,,[ASCIZ "RP04"]	;1 - RP04
	-1,,[ASCIZ "UNK "]	;2 - UNKNOWN
	-1,,[ASCIZ "UNK "]	;3 - UNKNOWN
	-1,,[ASCIZ "UNK "]	;4 - UNKNOWN
	-1,,[ASCIZ "RP05"]	;5 - RP05
	-1,,[ASCIZ "RP06"]	;6 - RP06
	-1,,[ASCIZ "RP07"]	;7 - RP07
	-1,,[ASCIZ "RP08"]	;10 - RP08 (IF EVER)
	-1,,[ASCIZ "RM03"]	;11 - RM03
	-1,,[ASCIZ "UNK "]	;12 - UNKNOWN
	-1,,[ASCIZ "UNK "]	;13 - UNKNOWN
	-1,,[ASCIZ "UNK "]	;14 - UNKNOWN
	-1,,[ASCIZ "UNK "]	;15 - UNKNOWN
	-1,,[ASCIZ "UNK "]	;16 - UNKNOWN
	-1,,[ASCIZ "UNK "]	;17 - UNKNOWN
	-1,,[ASCIZ "UNK "]	;20 - UNKNOWN
	-1,,[ASCIZ "UNK "]	;21 - UNKNOWN
	-1,,[ASCIZ "UNK "]	;22 - UNKNOWN
	-1,,[ASCIZ "UNK "]	;23 - UNKNOWN
	-1,,[ASCIZ "RP20"]	;24 - RP20

	MXUTYP==.-UNTYTB-1	;MAX UNIT TYPE
	SUBTTL	DUMP COMMAND TO DUMP VARIOUS ITEMS

;THE DUMP COMMAND BRANCHES OFF TO DUMP OUT IN HOPEFULLY USEFUL WAYS
;A NUMBER OF THE INTERESTING PARTS OF THE DISK.


CMDDMP:	MOVEI	T2,[FLDDB. (.CMKEY,,DMPTAB)]	;SETUP
	PARSE			;INPUT KEYWORD
	MOVE	T2,0(T2)	;GET THE ADDRESS
	JRST	0(T2)		;TRANSFER AWAY

DMPTAB:	DMPLEN,,DMPLEN		;DUMP TYPES TABLE
	AA	BAT-BLOCKS,DMPBAT	;BAT BLOCKS
	AA	HOME-BLOCKS,DMPHOM	;HOME BLOCKS
	AA	INDEX-BLOCKS,DMPIDX	;FILE INDEX BLOCKS
	AA	MICROPROCESSOR-FILE-SYSTEM-DIRECTORY,DMPMIC ;KS FE DIRECTORY
	AA	PAGE,DMPPAG		;PAGE OF DISK
	DMPLEN==.-DMPTAB-1	;SIZE OF TABLE
	SUBTTL	DUMP COMMAND FOR DISK PAGES

;DMPPAG - HERE WE APPARENTLY WANT TO DUMP OUT A PAGE OF THE DISK.
;GET THE REST OF THE PARAMETERS.

DMPPAG:	NOISE	(AT DISK ADDRESS) ;DO THE GUIDEWORDS
	MOVEI	T2,[FLDDB. (.CMNUM,,^D8)]	;OCTAL NUMBER
	PARSE	
	MOVE	P1,T2		;SAVE THE NUMBER TEMPORARILY
	CONFRM			;CONFIRM THE LINE
	CALL	CHKUSE		;MAKE SURE THERE IS SOMETHING THERE
	LOAD	T1,STGADR,P1	;RANGE CHECK THE VALUE
	CAME	T1,P1		; BY MAKING SURE NO OTHER BITS ARE THERE
	 ERROR	Invalid Disk Address specified
	CALLRET	PAGDMP		;AND GO TRY TO DO IT.




;PAGDMP - ROUTINE TO DUMP OUT A PAGE OF THE SELECTED DISK
;ACCEPTS
;  T1/	DISK ADDRESS OF PAGE TO BE DUMPED
;	CALL	PAGDMP
;RETURNS  +1:	ALWAYS WITH THE OUTPUT COMPLETE, UNLESS ERROR

PAGDMP:	MOVX	T2,.DSDAT	;A "DATA" PAGE
	STOR	T2,DS%TYP,F	;SET THE TYPE IN F
	CALL	RDCHK		;READ IN THE PAGE
	JUMPE	T1,PAGDM1	;CONTINUE IF READ OK

;HERE SOME TROUBLES WERE NOTED ON THE READ--EXPLAIN THEM...

	CAIN	T1,.DSHRD	;REALLY UNREADABLE?
	JRST	[ERROR	Page is unreadable] ;YUP
	 WARN	Some problems noted reading page

	;...
;DUMP THE DATA FROM DATPAG.  ALLOW ^E ABORT TO PAGABT.

PAGDM1:	MOVEI	T1,PAGABT	;WHERE TO WIND UP TO DO ABORT
	CALL	SETABT		;SET UP ABORT ON ^E TO PAGABT
	MOVSI	P1,-PGSIZ	;SIZE OF A PAGE
	MOVEI	T1,.PRIOU	;LOAD UP THE OUTPUT DESIGNATOR
	TXZ	F,FL%TMP	;CLEAR CROCK FLAG
	PRINT	<
Address	       Octal   SIXBIT	   L-ASCII	R-ASCII	  11-ASCII
>
PAGDML:	SKIPE	DATPAG(P1)	;SEE IF ZERO
	TXO	F,FL%TMP	;REMEMBER
	PRINT	<
>				;BEGIN WITH A CRLF
	SKIPN	T1,OJFN		;FETCH THE PROPER OUTPUT
	MOVEI	T1,.PRIOU	; DESIGNATOR
	HRRZ	T2,P1		;GET THE ADDRESS WITHIN THE PAGE
	OCTOUT	T2,3		;THREE OCTAL DIGITS OF ADDRESS
	PRINT	</	>	;DELIMIT
	OCTOUT	DATPAG(P1),^D12	;12 OCTAL DIGITS OF THE NEXT WORD
	PRINT	<   >		;SPACE OVER
	MOVE	T2,DATPAG(P1)	;FETCH THE WORD
	CALL	SIXWRD		;OUTPUT THE SIXBIT REPRESENTATION
	PRINT	<   >		;SPACE OVER
	MOVE	T2,DATPAG(P1)	;REFETCH THE WORD
	CALL	ASCWRD		;DO LEFT JUSTIFIED ASCII
	PRINT	<   >		;SPACE OVER
	MOVE	T2,DATPAG(P1)	;GET THE VALUE AGAIN
	LSH	T2,1		;MOVE LEFT A BIT TO DO
	CALL	ASCWRD		; THE RIGHT JUSTIFIED ASCII BIT
	PRINT	<   >		;SPACE OVER
	MOVE	T2,DATPAG(P1)	;AND ONCE AGAIN FETCH DATA
	CALL	ELVWRD		;TO DO ELEVEN FORMAT
PAGDMX:	AOBJN	P1,PAGDML	;LOOP OVER ALL PAGE
	TXZN	F,FL%TMP	;ALL ZERO?
	PRINT	<
% Entire page is zero> ;YES - SAY SO
	CALL	CLRABT		;CLEAR THE CONTROL-E ABORT
	RET			;AND DONE




;PAGABT - HERE ON ^E ABORT OF PAGE DUMP

PAGABT:	MOVEI	T1,.PRIOU	;CLEAR OUTPUT
	CFOBF			; INSTEAD OF WAITING
	 ERJMP	LOSE
	WARN	Page Dump aborted
	MOVE	P,SAVPSI	;RE-ADJUST STACK
	RET			;AND DONE
	SUBTTL	DUMP COMMAND FOR FILE INDEX BLOCKS

;DMPIDX HERE WE WANT TO DUMP THE INDEX BLOCK FOR A FILE.  WE NEED TO
;GET THE JFN ON THE FILE.

DMPIDX:	NOISE	(OF FILE)	;DO GUIDEWORDS
	MOVX	T2,GJ%OLD!GJ%IFG!GJ%FLG	;FILE MUST EXIST, MAY BE WILD
	MOVEM	T2,JFNBLK+.GJGEN
	MOVEI	T2,[FLDDB. (.CMFIL)]
	PARSE			;PARSE THE FILESPEC
	MOVEM	T2,FILJFN	;SAVE THE JFN
	CONFRM			;CONFIRM THE LINE
DMPIDL:	PRINT	<
	Disk Addresses for File > ;HEADER LINE
	HRRZ	T2,FILJFN	;FETCH JFN
	SKIPN	T1,OJFN		;FETCH SPECIFIED OR
	MOVEI	T1,.PRIOU	; NORMAL OUTPUT
	SETZ	T3,		;DEFAULT FORMAT
	JFNS			;TYPE THE FILENAME
	 ERJMP	LOSE
	PRINT	<
>				;AND A CRLF
	CALL	IDXDMP		;DO THE REAL WORK OF DUMPING THE BLOCKS
	MOVE	T1,FILJFN	;FETCH THE JFN TO
	GNJFN			;STEP IT TO THE NEXT
	 ERJMP	[CAIE	T1,GNJFX1	;NO MORE?
		 JRST	LOSE		;SOME OTHER ERROR
		 SETZM	FILJFN		;MARK UNUSED
		 RET]			;AND RETURN DONE
	HRRM	T1,FILJFN	;SAVE THE NEXT JFN
	JRST	DMPIDL		;AND LOOP
;IDXDMP - ROUTINE TO DUMP OUT THE INDEX BLOCKS FOR THE FILE WHOSE
;JFN IS IN FILJFN.
;
;	CALL	IDXDMP
;RETURNS  +1:	ALWAYS AFTER THE OUTPUT HAS BEEN DONE

IDXDMP:	
	SVFLGS			;SAVE OLD FLAGS IN CASE FL%PHY WAS SET...
	MOVEI	T1,IDXABT	;WHERE TO GO ON A ^E ABORT
	CALL	SETABT		; SETUP FOR THE INTERRUPT
	SETZ	F,		;AND CLEAR FLAGS
	HRRZ	T1,FILJFN	;GET THE JFN
	DVCHR			;GET CHARACTERISTICS AND DESIGNATOR
	MOVEM	T1,DSKSTR	;STORE DESIGNATOR
	LOAD	T2,DV%TYP,T2	;FETCH DEVICE TYPE FIELD
	CAIE	T2,.DVDSK	;DISK?
	 ERROR	File is not on a disk device
	HRRZ	T1,FILJFN	;GET THE JFN
	MOVE	T2,[.FBADR+1,,.FBHDR]	;READ UP TO .FBADR
	MOVEI	T3,FDBBLK	;WHERE TO PUT INFO
	GTFDB			;READ FDB
	 ERJMP	LOSE		;WON'T WORK
	MOVE	T1,FDBBLK+.FBCTL ;FETCH FDB BITS WORD
	TXNE	T1,FB%BAT	; AND SEE IF THE BAT BIT IS SET HERE
	 WARN	BAT bit is set in the file's FDB
	MOVE	T1,FDBBLK+.FBADR ;FETCH DISK ADDRESS
	ANDX	T1,STGADR	;MASK OUT OTHER BITS
	SKIPN	T1		;ASSURE NON-ZERO
	 ERROR	Disk address in FDB is zero
	MOVE	T2,FDBBLK+.FBCTL ;FETCH FLAGS WORD
	LOAD	T2,FB%LNG,T2	;COPY THE LONG FILE BIT
	STOR	T2,FL%LNG,F	; TO THE FLAGS REGISTER
	JN	FL%LNG,F,IDXDM0	;GO IF NEED TO GET SUPER INDEX BLOCK
	MOVEM	T1,SXBPAG	;FAKE SUPER INDEX BLOCK WITH SINGLE
	MOVSI	P2,-1		; WORD ENTRY
	JRST	IDXDM1		; AND JOIN CODE LATER

IDXDM0:	MOVSI	P2,-PGSIZ	;SIZE OF AN INDEX BLOCK
	MOVX	T2,.DSSXB	;RDCHK CODE FOR SUPER INDEX BLOCK
	STOR	T2,DS%TYP,F	;STORE IN F FOR CALL
	CALL	RDCHK		;READ IN THE PAGE
	JUMPN	T1,[	WARN	Problems with Super Index Block
			TYPE.	@SXBMSG(T1)	;TYPE APPROPRIATE ERROR MESSAGE
			CAIN	T1,.DSHRD	;REALLY UNREADABLE?
			ERROR	Cannot continue
			JRST	.+1]		;IF NOT, GO ON
	;...
	PRINT	<
Contents of Super Index Block, Disk Address >
	OCTOUT	LSTADR		;HEADER AND ADDRESS
	PRINT	<
>				;NEW LINE
	MOVE	T1,[SXBPAG,,XBPAG] ;COPY OVER DATA
	BLT	T1,XBPAG+PGSIZ-1 ; SO WE CAN CALL XBDMP
	CALL	XBDMP		;DUMP THE SXB

IDXDM1:	LOAD	T1,STGADR,SXBPAG(P2) ;FETCH NEXT XB ADR
	JUMPE	T1,IDXDMX	;ANYTHING THERE? GO IF NOT

IDXDM2:	MOVX	T2,.DSXB	;RDCHK CODE FOR INDEX BLOCK
	STOR	T2,DS%TYP,F	;SET IN F FOR CALL
	CALL	RDCHK		;READ THE PAGE
	JUMPE	T1,IDXDM3	;GO ON IF OK
	WARN	Problems with Index Block for Section
	HRRZ	T2,P2		;BLOCK NUMBER
	OCTOUT	T2		;OUTPUT BLOCK NUMBER IN OCTAL
	PRINT	<, Disk Address > ;AND DO DISK ADDRESS
	OCTOUT	LSTADR		;OUTPUT LAST DISK ADDRESS IN OCTAL
	MOVE	T1,LSTERR	;GET ERROR CODE AGAIN
	TYPE.	@XBMSG(T1)	;TYPE APPROPRIATE MESSAGE
	CAIN	T1,.DSHRD	;UNREADABLE?
	JRST	IDXDMX		; YES, JUST GO ON AND ITERATE LOOP

IDXDM3:	PRINT	<
Contents of Index Block for Section >	;LEAD-IN
	HRRZ	T2,P2		;INDEX BLOCK NUMBER
	OCTOUT	T2		;OUTPUT OCTAL INDEX BLOCK NUMBER
	PRINT	<, Disk Address > ;LEAD-IN TO DISK ADDRESS
	OCTOUT	LSTADR		;OUTPUT DISK ADDRESS OF INDEX BLOCK
	PRINT	<
>				;AN EXTRA CRLF
	CALL	XBDMP		;NOW DUMP THE INDEX BLOCK
IDXDMX:	AOBJN	P2,IDXDM1	;LOOP FOR ALL INDEX BLOCKS
	PRINT	<
>				;A FINAL CRLF
	CALL	CLRABT		;CLEAR THE CONTROL-E
	RET			;DONE, RETURN




;IDXABT - ROUTINE TO FINISH UP ON A CONTROL-E ABORT OF INDEX DUMP

IDXABT:	MOVEI	T1,.PRIOU	;GO AHEAD AND
	CFOBF			; CLEAR ANY PENDING OUTPUT
	 ERJMP	LOSE
	WARN	Index Block Dump aborted
	MOVE	P,SAVPSI	;RE-ALIGN THE STACK
	RET			; AND RETURN
;XBDMP - ROUTINE TO DO THE ACTUAL OUTPUT DUMP OF THE DISK ADDRESSES IN
; AN INDEX BLOCK.
;ACCEPTS:
;  T1/	OUTPUT DESIGNATOR
;  XBPAG/  INDEX BLOCK
;
;	CALL	XBDMP
;RETURNS  +1:	ALWAYS

XBDMP:	SAVEAC	<P1,P2>		;SAVE SOME ACS
	MOVEI	P1,PGSIZ	;SIZE OF AN INDEX BLOCK

;MAKE A PRE-PASS TO DETERMINE HOW FAR DOWN THE BLOCK WE SHOULD GO
;NOTE CHECKSUM IN FIRST WORDS "GUARANTEES" AT LEAST ONE LINE

	SKIPN	XBPAG-1(P1)	;NON-ZERO YET?
	SOJG	P1,.-1		;KEEP MOVING BACK
	ADDI	P1,LNBRK	;ROUND UP
	TRZ	P1,LNBRK	;AND ROUND OFF
	MOVN	P1,P1		;NEGATE THE COUNT
	HRLZ	P1,P1		;AND BUILD AOBJN POINTER
	SETZ	P2,		;COUNTER FOR USED PAGES

XBDMP0:	TXNE	P1,LNBRK	;TIME FOR A NEW LINE?
	JRST	XBDMP1		;NO, GO ON

	PRINT	<
>				;START WITH A CRLF
	HRRZ	T2,P1		;COPY THE NUMBER
	OCTOUT	T2,3		;THREE OCTAL COLUMNS OF OFFSET
	PRINT	</>		;DELIMIT VALUE

XBDMP1:	PRINT	<    >		;SOME SPACING
	LOAD	T2,STGADR,XBPAG(P1) ;FETCH THE ADDRESS
	JUMPE	T2,[	PRINT	<   --   >	;INDICATE UNUSED THUSLY
			JRST	XBDMP2]		;AND CONTINUE
	OCTOUT	T2,^D8		;EIGHT OCTAL COLUMNS OF DISK ADDRESS
	AOS	P2		;COUNT USED PAGE
XBDMP2:	AOBJN	P1,XBDMP0	;AND LOOP TIL DONE

	;...
	PRINT	<

>				;ANOTHER CRLF TO END LINE
	DECOUT	P2,3		;DECIMAL COUNT OF USED PAGES
	PRINT	< Pages in use by this Index Block
>				;SAY SO
	MOVEI	T1,XBPAG	;POINT AT THE PAGE
	CALL	CHKSUM		;TEST THE CHECKSUM, BAT BIT
	TXNE	F,DS%BAT	;XBBAT SET?
	PRINT	<BAT Bit is set for this Index Block
>
	CAME	T1,[-1]		;CHECKSUM CORRECT?
	PRINT	<Checksum for this Index Block is incorrect
>
	RET			;AND RETURN
	SUBTTL	DUMP COMMAND FOR HOME BLOCKS


DMPHOM:	MOVEI	T2,[ASCIZ/FOR UNIT/]	;SELECT THE
	TXNN	F,FL%PHY	;PROPER NOISE
	MOVEI	T2,[ASCIZ/FOR STRUCTURE/]
	CALL	DONOIS		;AND OUTPUT THE GUIDEWORDS
	CONFRM			;MAKE SURE
	CALL	CHKUSE		;MAKE SURE SOMETHING'S THERE TO USE
	CALLRET	HOMDMP		;AND TRY TO DUMP THE HOMEBLOCKS


;HOMDMP - ROUTINE TO DUMP OUT AND INTERPRETED SET OF HOME BLOCKS
;FROM THE INFORMATION GATHERED IN THE COMMAND LINE...

HOMDMP:	TXNE	F,FL%PHY	;UNIT OR STRUCTURE?
	JRST	[SETZ	P1,		;NO OFFSET FOR A UNIT ADDRESS
		 CALLRET HOMUNT]	;AND MAKE A SINGLE GO-THROUGH
	CALL	STRINF		;GATHER THE STRUCTURE INFO
	MOVN	P2,PACKCT	;FETCH THE NUMBER OF LOGICAL UNITS
	HRLZ	P2,P2		;BUILD -N,,0
	SETZ	P1,		;NO OFFSET THE FIRST TIME
	JRST	HOMST1		;ENTER PAST OFFSET CALCULATION
HOMSTR:	MOVE	T1,UNITSZ-1(P2)	;FETCH THE PREVIOUS SIZE
	IMUL	T1,SECPAG	;CONVERT TO SECTORS
	ADD	P1,T1		;AND UPDATE THE OFFSET TO THE NEXT STR
HOMST1:	PRINT	<

HOME Blocks for Logical Unit>	;DO THE HEADER LINE
	HRRZ	T1,P2		;FETCH THE CURRENT UNIT
	OCTOUT	T1,3		;OUTPUT WITH SPACING
	PRINT	<:
>				;FINISH THE LINE
	CALL	HOMUNT		;DO THE UNIT
	AOBJN	P2,HOMSTR	;LOOP FOR ALL UNITS
	RET			; AND FINALLY DONE

;DO EACH UNIT

HOMUNT:	TXZ	F,HB%1VB!HB%2VB!HB%1SB!HB%2SB!HB%1B!HB%2B!HB%IB
	CALL	REDHOM		;READ THE HOME BLOCKS

;NOW F CONTAINS THE FLAGS, SO TEST THEM AND OUTPUT SUMMARY HEADER INFO

	TXNE	F,HB%1VB
	PRINT	<Primary HOME Block is unreadable
>				;SAY SO
	TXNE	F,HB%1SB
	PRINT	<Read of Primary HOME Block encountered errors
>
	TXNE	F,HB%2VB
	PRINT	<Secondary HOME Block is unreadable
>
	TXNE	F,HB%2SB
	PRINT	<Read of Secondary HOME Block encountered errors
>
	TXNE	F,HB%1B
	PRINT	<Primary HOME Block is bad
>
	TXNE	F,HB%2B
	PRINT	<Secondary HOME Block is bad
>
	TXNE	F,HB%IB
	PRINT	<HOME Blocks are Inconsistent
>
	TXNN	F,HB%1VB!HB%2VB!HB%1SB!HB%2SB!HB%1B!HB%2B!HB%IB
	PRINT	<HOME Blocks appear to be ok
>

;NOW DUMP THE PRIMARY BLOCK

	TXNN	F,HB%1VB!HB%2VB	;TOO SICK TO BOTHER?
	SKIPA			;NO
	JRST	HOMUN2		;YES, DONE

	PRINT	<
  0   HOMNAM   SIXBIT/HOM/:  >
	MOVE	T2,HOM1AD+HOMNAM
	CALL	PSIX		;OUTPUT IN SIXBIT
	PRINT	<
  3   HOMSNM   SIXBIT/Structure Name/:  >
	MOVE	T2,HOM1AD+HOMSNM
	CALL	PSIX		;PRINT IN SIXBIT
	PRINT	<
  4   HOMLUN   # of Packs in STR,,Logical Unit in STR:  >
	MOVE	T2,HOM1AD+HOMLUN
	CALL	PXWD		;PRINT AS HALFWORDS
	PRINT	<
  5   HOMHOM   Sector Number of This HOME Block,,Sector # of Other:  >
	MOVE	T2,HOM1AD+HOMHOM
	CALL	PXWD		;PRINT AS HALFWORDS
	PRINT	<
  6   HOMP4S   Number of Pages for Swapping on this Unit:  >
	DECOUT	HOM1AD+HOMP4S	;PRINT IN DECIMAL
	PRINT	<
  7   HOMFST   First Swapping Cylinder on Unit:  >
	OCTOUT	HOM1AD+HOMFST	;PRINT IN OCTAL
	PRINT	<
 10   HOMRXB   Address of ROOT-DIRECTORY Index Block:  >
	OCTOUT	HOM1AD+HOMRXB	;PRINT IN OCTAL
	PRINT	<
 11   HOMBXB   Address for BACKUP-COPY-OF-ROOT-DIRECTORY:  >
	OCTOUT	HOM1AD+HOMBXB	;PRINT IN OCTAL
	PRINT	<
 12   HOMFLG   Flags:  >
	MOVE	T2,HOM1AD+HOMFLG
	CALL	PHFLGS		;PRINT HOME FLAGS
	PRINT	<
 13   HOMSIZ   Number of Sectors in this Unit:  >
	DECOUT	HOM1AD+HOMSIZ	;PRINT IN DECIMAL
	PRINT	<
 14   HOMBTB   Number of Cylinders in Structure:  >
	DECOUT	HOM1AD+HOMBTB	;PRINT IN DECIMAL
	PRINT	<
 15   HOMMID   Pack Unique Code:  >
	OCTOUT	HOM1AD+HOMMID	;PRINT IN OCTAL
	PRINT	<
 61   HOMFE0   Front End File System Starting Sector:  >
	OCTOUT	HOM1AD+HOMFE0	;PRINT IN OCTAL
	PRINT	<
 62   HOMFE1   Front End File System Size in Sectors:  >
	DECOUT	HOM1AD+HOMFE1	;PRINT IN DECIMAL
	PRINT	<
101   HOMFE2   BOOTSTRAP.BIN Starting Sector:  >
	OCTOUT	HOM1AD+HOMFE2	;PRINT IN OCTAL
	PRINT	<
102   HOMFE3   BOOTSTRAP.BIN Size in Sectors:  >
	DECOUT	HOM1AD+HOMFE3	;PRINT IN DECIMAL
	PRINT	<
165   HOMUID   -11 Format Unit I.D. (12 Characters):  >
	MOVE	T2,HOM1AD+HOMUID
	CALL	ELVWRD		;PRINT IN -11 FORMAT
	MOVE	T2,HOM1AD+HOMUID+1 ;NEXT
	CALL	ELVWRD		;PRINT IN -11 FORMAT
	MOVE	T2,HOM1AD+HOMUID+2 ;THIRD AND LAST
	CALL	ELVWRD		;PRINT IN -11 FORMAT
	PRINT	<
170   HOMOID   -11 Format Owner I.D. (12 Characters):  >
	MOVE	T2,HOM1AD+HOMOID
	CALL	ELVWRD		;PRINT IN -11 FORMAT
	MOVE	T2,HOM1AD+HOMOID+1 ;NEXT
	CALL	ELVWRD		;PRINT IN -11 FORMAT
	MOVE	T2,HOM1AD+HOMOID+2 ;THIRD AND LAST
	CALL	ELVWRD		;PRINT IN -11 FORMAT
	PRINT	<
173   HOMFSN   -11 Format File System Name:  >
	MOVE	T2,HOM1AD+HOMFSN
	CALL	ELVWRD		;PRINT IN -11 FORMAT
	MOVE	T2,HOM1AD+HOMFSN+1 ;NEXT
	CALL	ELVWRD		;PRINT IN -11 FORMAT
	MOVE	T2,HOM1AD+HOMFSN+2 ;THIRD AND LAST
	CALL	ELVWRD		;PRINT IN -11 FORMAT
	PRINT	<
176   HOMCOD   Unique Code 707070:  >
	OCTOUT	HOM1AD+HOMCOD	;PRINT IN OCTAL
	PRINT	<
177   HOMSLF   Sector Number of this Block:  >
	OCTOUT	HOM1AD+HOMSLF	;PRINT IN OCTAL
HOMUN2:	MOVEI	T1,HOM1AD	;POINT TO PRIMARY
	TXNE	F,HB%IB!HB%1B!HB%2B ;DIFFERENCES WE SHOULD LIST?
	CALL	DIFERS		;YUP, LIST DIFFERENCES
	RET			; ALL DONE
;REDHOM - ROUTINE TO READ THE HOME BLOCKS IN FOR A GIVEN UNIT.
;ACCEPTS
;  P1/	DISK ADDRESS OFFSET FOR HOME BLOCKS (FOR MULTI-UNIT STRS)
;	CALL	REDHOM
;RETURNS  +1:	ALWAYS
;READS THE HOMEBLOCKS IN AND BLTS THEM TO HOM1AD, HOM2AD
;CHECKS AND VERIFIES THE BLOCKS AND RETURNS THE FLAGS RELATING.

REDHOM:	MOVX	T1,.DSDAT	;READ INTO DATPAG
	STOR	T1,DS%TYP,F	;SET THE TYPE IN F
	MOVEI	T1,HOMBL1	;ADDRESS OF FIRST HOMEBLOCK
	ADD	T1,P1		;INCLUDE THE OFFSET INCASE OF STR
	CALL	RDCHK		;READ IN THE PAGE
	JUMPE	T1,REDHO1	;CONTINUE IF READ OK

;HERE SOME TROUBLES WERE NOTED ON THE READ--MARK THEM

	CAIN	T1,.DSHRD	;REALLY UNREADABLE?
	TXOA	F,HB%1VB	;MARK VERY BAD
	TXO	F,HB%1SB	;MARK TROUBLES

REDHO1:	MOVE	T1,[DATPAG,,HOM1AD]	;COPY PAGE INTO PLACE
	BLT	T1,HOM1AD+HBLEN-1	;IN ITS OWN BUFFER

	MOVX	T1,.DSDAT	;READ SECONDARY INTO DATPAG
	STOR	T1,DS%TYP,F	;SET THE TYPE IN F
	MOVEI	T1,HOMBL2	;ADDRESS OF SECOND HOMEBLOCK
	ADD	T1,P1		;ADD IN THE OFFSET
	CALL	RDCHK		;READ IN THE PAGE
	JUMPE	T1,REDHO2	;CONTINUE IF READ OK

;HERE SOME TROUBLES WERE NOTED ON THE READ--MARK THEM

	CAIN	T1,.DSHRD	;REALLY UNREADABLE?
	TXOA	F,HB%2VB	;MARK VERY BAD
	TXO	F,HB%2SB	;MARK TROUBLES

REDHO2:	MOVE	T1,[DATPAG,,HOM2AD]	;COPY PAGE INTO PLACE
	BLT	T1,HOM2AD+HBLEN-1	;IN ITS OWN BUFFER

;NOW DO THE COMPARISONS

	CALL	HOMCMP		;COMPARE
	TXNN	F,HB%1VB	;IS THE FIRST BAD?
	JRST	REDHO3		;NO, GO ON
	MOVE	T1,[HOM2AD,,HOM1AD] ;YES, BLT THE SECOND OVER THE TOP
	BLT	T1,HOM1AD+HBLEN-1 ; SO THERE IS SOMETHING THERE
REDHO3:	RET			; AND THAT DOES IT, FLAGS ALL SET
;HOMCHK - ROUTINE TO CHECK THE CONSISTENCY OF A HOME BLOCK
;ACCEPTS 
;  T1/	ADDRESS OF HOME BLOCK
;  T2/	HOME BLOCK #
;	CALL	HOMCHK
;RETURNS  +1:	NOT CONSISTENT OR MULTIPLE LOGICAL UNITS
;	  +2:	CONSISTENT, LOGICAL UNIT # IN T1

HOMCHK:	MOVSI	CX,'HOM'	;GET SIXBIT /HOM/
	CAME	CX,HOMNAM(T1)	;CHECK IT
	 RET			;NOT CORRECT
	MOVX	CX,CODHOM	;GET THE 707070 CODE
	CAME	CX,HOMCOD(T1)	;CHECK IT
	 RET			;NOT CORRECT
	CAME	T2,HOMSLF(T1)	;RIGHT BLOCK NUMBER SPECIFIED?
	 RET			;INCORRECT
	MOVE	CX,[BYTE (2)0(8)" "," "(2)0(8)"O","T"]
	CAME	CX,HOMFSN(T1)	;CORRECT FILE SYSTEM TYPE?
	 RET			;NO
	MOVE	CX,[BYTE (2)0(8)"S","P"(2)0(8)"2","-"]
	MOVE	T2,[BYTE (2)0(8)" ","0"(2)0(8)" "," "]
	CAMN	CX,HOMFSN+1(T1)	;CHECK CHARACTERS 5-8
	CAME	T2,HOMFSN+2(T1)	;CHECK CHARACTERS 9-12 OF TYPE
	 RET			;NOT A TOPS-20 PACK
	RETSKP			;HOME BLOCK IS OK


;HOMCMP - ROUTINE TO COMPARE THE PRIMARY AND SECONDARY HOME BLOCKS
;TO SEE IF EITHER OR BOTH IS VALID.
;ACCEPTS
;  HOM1AD/	ADDRESS OF FIRST HOME BLOCK
;  HOM2AD/	ADDRESS OF SECOND HOME BLOCK
;	CALL	HOMCMP
;RETURNS  +1:	ALWAYS WITH THE APPROPRIATE FLAG BIT SET IN F,
;		HB%1B, HB%2B, HB%IB

HOMCMP:	MOVEI	T1,HOM1AD	;POINT TO THE FIRST
	MOVX	T2,HOMBL1	; AND ITS BLOCK NUMBER
	CALL	HOMCHK		;CHECK IT OUT
	TXO	F,HB%1B		;FIRST IS BAD
	MOVEI	T1,HOM2AD	;POINT TO THE SECONDARY
	MOVX	T2,HOMBL2	; AND ITS BLOCK NUMBER
	CALL	HOMCHK		;NOW TEST IT
	TXO	F,HB%2B		;NOT GOOD
	MOVSS	HOM2AD+HOMHOM	;SWAP BLOCK NUMBERS SO SHOULD COMPARE...
	MOVSI	T1,-<HBLEN-1>	;SIZE OF HOME BLOCK MINUS THE HOMSLF WORD
HOMCML:	MOVE	T2,HOM1AD(T1)	;FETCH A WORD
	CAME	T2,HOM2AD(T1)	;DOES IT MATCH?
	TXO	F,HB%IB		; NO - BLOCKS ARE INCONSISTENT
	AOBJN	T1,HOMCML	;LOOP OVER THE BLOCK
	MOVSS	HOM2AD+HOMHOM	;PUT OLD VALUE BACK
	RET			; AND DONE
	SUBTTL DUMP COMMAND FOR BAT BLOCKS


DMPBAT:	MOVEI	T2,[ASCIZ/FOR UNIT/]	;SELECT
	TXNN	F,FL%PHY		; PROPER NOISE
	MOVEI	T2,[ASCIZ/FOR STRUCTURE/]
	CALL	DONOIS		;OUTPUT THE GUIDEWORDS
	CONFRM			;CONFIRM THE LINE
	CALL	CHKUSE		;MAKE SURE THERE'S SOMETHING TO USE
	CALLRET	BATDMP		;AND TRY TO DUMP THEM




;BATDMP	- ROUTINE TO DUMP OUT AN INTERPRETED SET OF BAT BLOCKS BASED
;ON THE INFORMATION COLLECTED BY THE COMMAND LINE

BATDMP:	TXNE	F,FL%PHY	;UNIT OR STRUCTURE?
	JRST	[SETZ	P1,		;NO OFFSET FOR UNITS
		 CALLRET BATUNT]	;AND MAKE A SINGLE PASS THROUGH
	CALL	STRINF		;STRUCTURE.  GET THE INFO SET UP
	SETZ	P1,		;START WITH FIRST UNIT
	MOVN	P2,PACKCT	;GET NUMBER OF LOGICAL UNITS
	HRLZ	P2,P2		;-N,,0
	JRST	BATST1		;ENTER PAST OFFSET CALCULATION
BATSTR:	MOVE	T1,UNITSZ-1(P2)	;GET SIZE IN PAGES
	IMUL	T1,SECPAG	;CONVERT TO SECTOR ADDRESS
	ADD	P1,T1		;UPDATE THE OFFSET
BATST1:	PRINT	<

BAT Blocks for Logical Unit>	;DO THE HEADER
	HRRZ	T1,P2		;FETCH THE UNIT
	OCTOUT	T1,3		; AND OUTPUT THE NUMBER
	PRINT	<:
>				;FOLLOWED BY A RETURN
	CALL	BATUNT		;DO THE UNIT
	AOBJN	P2,BATSTR	;LOOP FOR ALL LOGICAL UNITS
	RET			; AND FINALLY DONE
;DO EACH INDIVIDUAL UNIT

BATUNT:	TXZN	F,BB%1VB!BB%2VB!BB%1SB!BB%2SB!BB%1B!BB%2B!BB%IB ;START CLEAR
	CALL	REDBAT		;AND READ THE UNIT'S BAT BLOCKS

;NOW F HAS THE APPROPRIATE FLAGS SET, SO TEST AND REPORT

	TXNE	F,BB%1VB	;CHECK FOR UNREADABLE
	PRINT	<Primary BAT Block is unreadable
>				;SAY SO
	TXNE	F,BB%1SB
	PRINT	<Read of Primary BAT Block encountered errors
>
	TXNE	F,BB%2VB
	PRINT	<Secondary BAT Block is unreadable
>
	TXNE	F,BB%2SB
	PRINT	<Read of Secondary BAT Block encountered errors
>
	TXNE	F,BB%1B
	PRINT	<Primary BAT Block is bad
>
	TXNE	F,BB%2B
	PRINT	<Secondary BAT Block is bad
>
	TXNE	F,BB%IB
	PRINT	<BAT Blocks are Inconsistent
>
	TXNN	F,BB%1VB!BB%2VB!BB%1SB!BB%2SB!BB%1B!BB%2B!BB%IB
	PRINT	<BAT Blocks appear ok
>
	PRINT	<Mapper added count:  >	;OUTPUT THE REGION COUNTS
	MOVEI	T4,BAT1AD	;POINT TO THE BLOCK
	LOAD	T1,BTHCT,(T4)	;GET MAPPER COUNT
	DECOUT	T1,2		;OUTPUT IN DECIMAL
	PRINT	<  MONITOR added count:  > ;NOW THE MONITOR COUNT
	LOAD	T2,BTMCT,(T4)	;FETCH THE COUNT
	DECOUT	T2,2		; AND OUTPUT
	PRINT	<  Total:  >	;AND ADD THEM UP
	ADD	T1,T2		;TO T1
	DECOUT	T1,2		;OUTPUT (STILL BETTER BE LESS THAN 61)
	JUMPE	T1,R		;IF NO REGIONS, DONE HERE
	PRINT	<
Unit-Address	Size(Sectors)	APR number	Channel	Unit>
	MOVN	T1,T1		;BUILD THE AOBJN PTR TO SCAN
	HRLZS	T1		; THE PAIRS
	HRRI	T1,BAT1P(T4)	; USE THE FIRST PAIR OFFSET
BATUNL:	LOAD	T3,BADT,(T1)	;FETCH ADDRESS TYPE
	LOAD	T2,ADD27,(T1)	;ASSUME NEW ADDRESS FORMAT
	SKIPN	T3		;OLD OR NEW?
	LOAD	T2,ADD18,(T1)	;OLD ADDRESS FORMAT
	PRINT	<
  >				;SPACING
	OCTOUT	T2,^D8		;8 DIGIT OCTAL DISK ADDRESS
	PRINT	<	>	;SEPARATE WITH A TAB
	LOAD	T3,BATNB,(T1)	;SIZE OF REGION
	AOS	T3		;ACTUALLY IS ONE GREATER
	DECOUT	T3,3		;DO THE SIZE
	PRINT	<		> ;TAB OVER
	LOAD	T2,APRNM,(T1)	;GET THE APR SERIAL NUMBER
	DECOUT	T2,6		;DECIMAL
	PRINT	<		> ;TAB OVER
	LOAD	T2,BTKNM,(T1)	;CONTOLLER #
	OCTOUT	T2,4		;OCTAL
	PRINT	<	>	;TAB
	LOAD	T2,BTUNM,(T1)	;UNIT NUMBER FIELD - BITS
	JFFO	T2,.+1		;FIND WHICH BIT
	SUBI	T3,^D35		;COMPUTE THE
	MOVNS	T3		; UNIT NUMBER
	OCTOUT	T3,3		;AND OUTPUT IN OCTAL
	AOS	T1		;STEP ADDRESS BY TWO
	AOBJN	T1,BATUNL	;LOOP FOR THE REST
	PRINT	<
>				;FINAL CRLF
	MOVEI	T1,BAT1AD	;POINT TO THE PRIMARY
	TXNE	F,BB%IB!BB%1B!BB%2B ;ANY DIFFERENCES TO REPORT?
	CALL	DIFERS		;YES, LIST THEM
	RET			; ALL FOR NOW
;REDBAT - ROUTINE TO READ IN THE BAT BLOCKS FOR THE SPECIFIED UNIT
;INTO THE BAT BLOCK AREAS AND PERFORM THE PRELIMINARY CONSISTENCY
;CHECK, RETURNING FLAGS IN F.
;ACCEPTS
;  P1/	DISK ADDRESS OFFSET FOR USE WITH STRUCTURESS
;	CALL	REDBAT
;RETURNS  +1:	ALWAYS, WITH BAT BLOCKS READ IN AND APPROPRIATE FLAGS IN F

REDBAT:	MOVX	T1,.DSDAT	;READ INTO DATPAG
	STOR	T1,DS%TYP,F	;SET THE TYPE IN F
	MOVEI	T1,BATBL1	;ADDRESS OF FIRST HOMEBLOCK
	ADD	T1,P1		;ADD IN THE OFFSET
	CALL	RDCHK		;READ IN THE PAGE
	JUMPE	T1,REDBA1	;CONTINUE IF READ OK

;HERE SOME TROUBLES WERE NOTED ON THE READ--MARK THEM

	CAIN	T1,.DSHRD	;REALLY UNREADABLE?
	TXOA	F,BB%1VB	;MARK VERY BAD
	TXO	F,BB%1SB	;MARK TROUBLES

REDBA1:	MOVE	T1,[DATPAG,,BAT1AD]	;COPY PAGE INTO PLACE
	BLT	T1,BAT1AD+HBLEN-1	;IN ITS OWN BUFFER

	MOVX	T1,.DSDAT	;READ SECONDARY INTO DATPAG
	STOR	T1,DS%TYP,F	;SET THE TYPE IN F
	MOVEI	T1,BATBL2	;ADDRESS OF SECOND HOMEBLOCK
	ADD	T1,P1		;INCLUDE THE OFFSET
	CALL	RDCHK		;READ IN THE PAGE
	JUMPE	T1,REDBA2	;CONTINUE IF READ OK

;HERE SOME TROUBLES WERE NOTED ON THE READ--MARK THEM

	CAIN	T1,.DSHRD	;REALLY UNREADABLE?
	TXOA	F,BB%2VB	;MARK VERY BAD
	TXO	F,BB%2SB	;MARK TROUBLES

REDBA2:	MOVE	T1,[DATPAG,,BAT2AD]	;COPY PAGE INTO PLACE
	BLT	T1,BAT2AD+HBLEN-1	;IN ITS OWN BUFFER

;NOW DO THE COMPARISONS

	CALL	BATCMP		;COMPARE
	RET			; AND THAT DOES IT, FLAGS ALL SET
;BATCHK - ROUTINE TO CHECK THE CONSISTENCY OF A BAT BLOCK
;ACCEPTS
;  T1/	ADDRESS OF BAT BLOCK
;  T2/	NUMBER OF THE BAT BLOCK
;	CALL	BATCHK
;RETURNS  +1:	IF THE BLOCK IS INCONSISTENT
;	  +2:	IF THE BLOCK SEEMS OK


BATCHK:	MOVSI	CX,'BAT'	;SHOULD BE FIRST WORD
	CAME	CX,BATNAM(T1)	;CHECK IT
	 RET			;BAD
	MOVX	CX,CODBAT	;606060
	CAME	CX,BATCOD(T1)	;CHECK FOR IT
	 RET			;NOT THERE
	HLRE	CX,BATFRE(T1)	;SEE HOW MANY FREE PAIRS
	MOVN	CX,CX		; ARE SPECIFIED
	CAILE	CX,MAXBFR	;MORE THAN THE MAX?
	 RET			;YUP, BAD
	HRRZ	CX,BATFRE(T1)	;NOW CHECK THE OFFSET
	CAILE	CX,HBLEN	;OUTSIDE THE BLOCK?
	 RET			;YUP, BAD
	CAME	T2,BATBLK(T1)	;SECTOR NUMBER MATCH?
	 RET			;NO, BAD
	RETSKP			;YES, ALLOW THE BLOCK


;BATCMP - ROUTINE TO COMPARE TWO BAT BLOCKS TO SEE IF BOTH VALID
;ACCEPTS
;  BAT1AD/	FIRST BAT BLOCK
;  BAT2AD/	SECOND BAT BLOCK
;	CALL	BATCMP
;RETURNS  +1:	ALWAYS WITH APPROPRIATE FLAGS SET IN F
;		BB%1B, BB%2B, BB%IB

BATCMP:	TXZ	F,BB%1B!BB%2B!BB%IB	;ASSUME ALL IS WELL
	MOVEI	T1,BAT1AD	;POINT TO BLOCK
	MOVX	T2,BATBL1	;ALONG WITH ITS NUMBER
	CALL	BATCHK		;CHECK THE FIRST
	TXO	F,BB%1B		;FIRST NO GOOD
	MOVEI	T1,BAT2AD	;POINT TO SECONDARY
	MOVX	T2,BATBL2	;WITH ITS NUMBER
	CALL	BATCHK		;CHECK THE SECOND
	TXO	F,BB%2B		;SECOND BAD
	MOVSI	T1,-<HBLEN-1>	;MAKE AOBJN POINTER
BATCML:	MOVE	T2,BAT1AD(T1)	;FETCH A WORD FROM FIRST
	CAME	T2,BAT2AD(T1)	;SAME IN THE SECOND?
	TXO	F,BB%IB		;SET INCONSISTENT FLAG
	AOBJN	T1,BATCML	;LOOP TO END
	RET			; AND DONE

;DIFERS - ROUTINE TO PRINT THE DIFFERENCES BETWEEN TWO REGIONS
;USED FOR THE BAT BLOCKS AND HOME BLOCKS.  ASSUMES THE REGIONS
;ARE HBLEN APART AND ALL HBLEN OF THEM SHOULD BE COMPARED.
;ACCEPTS
;  T1/	ADDRESS OF THE FIRST REGION
;	CALL	DIFERS
;RETURNS  +1:	ALWAYS, AFTER PRINTING THE DIFFERENCES IN THE FORM
;		OFFSET/	WORD ONE	WORD TWO
;USES T1-T2.

DIFERS:	HRLI	T1,-HBLEN	;SET UP THE COUNT
	PRINT	<

Differences:
Offset	     Primary	   Secondary> ;HEADER
DIFERL:	MOVE	T2,0(T1)	;FETCH THE FIRST
	CAME	T2,HBLEN(T1)	;MAKE THE COMPARE
	JRST	[PRINT	<
>					;NEW LINE
		 HLRE	T2,T1		;-N
		 ADDI	T2,HBLEN 	;MAKE OFFSET
		 OCTOUT	T2,3		;DO 3 OCTAL DIGITS
		 PRINT	</	> 	;DELIMIT
		 OCTOUT	0(T1),^D12	;DO THE FIRST WORD
		 PRINT	<	>	;TAB AGAIN
		 OCTOUT	HBLEN(T1),^D12	;DO THE SECOND WORD
		 JRST	.+1]		;AND CONTINUE IN LINE
	AOBJN	T1,DIFERL	;LOOP FOR ALL DESIRED
	PRINT	<
>				;AND A TRAILING CRLF
	RET			;AND THEN RETURN
	SUBTTL	DUMP COMMAND FOR KS MICROPROCESSOR DIRECTORY

;HERE TO DO THE DIRECTORY OF THE FRONT END AREA FOR A 2020 USING THE
;POINTERS IN THE HOME BLOCK TO THE DIRECTORY PAGE.

DMPMIC:	MOVEI	T2,[ASCIZ/FOR UNIT/] ;SELECT
	TXNN	F,FL%PHY	;PROPER NOISE
	MOVEI	T2,[ASCIZ/FOR STRUCTURE/]
	CALL	DONOIS		;OUTPUT THE GUIDEWORDS
	CONFRM			;CONFIRM THE COMMAND
	CALL	CHKUSE		;MAKE SURE THERE'S SOMETHING TO USE
	TXNN	F,FL%PHY	;AND MAKE SURE
	CALL	STRINF		;SECPAG IS SET UP TO BE REFERENCED
	CALLRET	MICDMP		; AND GO DO IT


;MICDMP - ROUTINE TO DO THE ACTUAL DUMPING OF THE MICROPROCESSOR FILE
;SYSTEM DIRECTORY.  START WITH THE INFORMATION IN THE HOME BLOCK AND
;REPORT IT, THEN READ AND DUMP THE ACTUAL DIRECTORY PAGE.

MICDMP:	MOVEI	T1,MICABT	;SETUP
	CALL	SETABT		; CONTROL-E ABORT ROUTINE
	TXZ	F,HB%1VB!HB%2VB!HB%1SB!HB%2SB!HB%1B!HB%2B!HB%IB
	SETZ	P1,		;NO OFFSET AND
	CALL	REDHOM		; READ IN THE HOME BLOCKS
	TXNE	F,HB%1VB	;SEE IF EITHER HOME BLOCK
	TXNN	F,HB%2VB	; IS READABLE
	 SKIPA			;AT LEAST ONE IS
	JRST	[WARN	Both HOME Blocks unreadable - assuming address
		 MOVX	T1,DEFMIC	;ASSUME DEFAULT ADDRESS OF PAGE
		 MOVEM	T1,HOM1AD+HOMFE2 ;FAKE IT
		 SETZM	HOM1AD+HOMFE3	;AND CLEAR SIZE AND
		 SETZM	HOM1AD+HOMFE4	; 8080 WORD
		 TXZ	F,HB%1VB	;THEN SAY FIRST BLOCK "OK"
		 JRST	.+1]		;AND CONTINUE IN LINE

	PRINT	<
HOME Block Information:

101   HOMFE2   Microprocessor File System Starting Sector: >
	MOVE	T2,HOM1AD+HOMFE2 ;ASSUME PRIMARY GOOD
	TXNE	F,HB%1VB	;BUT CHECK
	MOVE	T2,HOM2AD+HOMFE2
	OCTOUT	T2		;OUTPUT THE DISK ADDRESS
	MOVEM	T2,MICBEG	;SAVE FOR LATER

	;...
	PRINT	<
102   HOMFE3   Microprocessor File System Size in Sectors: >
	MOVE	T2,HOM1AD+HOMFE3
	TXNE	F,HB%1VB
	MOVE	T2,HOM2AD+HOMFE3
	DECOUT	T2		;PRINT THE SIZE IN DECIMAL
	MOVEM	T2,MICSIZ	; AND SAVE FOR REASONABLENESS CHECKS
	PRINT	<
103   HOMFE4   Microprocessor Format Cylinder/Track/Sector: >
	MOVE	T2,HOM1AD+HOMFE4
	TXNE	F,HB%1VB
	MOVE	T2,HOM2AD+HOMFE4
	LOAD	T1,MICCYL,T2	;GET CYLINDER
	OCTOUT	T1		;OUTPUT
	PRINT	</>		;SEPARATE
	LOAD	T1,MICTRK,T2	;GET TRACK
	OCTOUT	T1		;OUTPUT
	PRINT	</>		;SEPARATE
	LOAD	T1,MICSEC,T2	;AND FINALLY SECTOR
	OCTOUT	T1		;OUTPUT
	PRINT	<

Directory Page Information:

>				;HEADER FOR NEXT SECTION
	LOAD	T1,STGADR,MICBEG ;FETCH ADDRESS BITS FOR DIRECTORY PAGE
	MOVX	T2,.DSDAT	;LOAD INTO
	STOR	T2,DS%TYP,F	; DATPAG
	CALL	RDCHK		;READ/CHECK THE DIRECTORY PAGE
	JUMPE	T1,MICDM0	;CONTINUE IF READ WAS OK

;HERE THERE WERE SOME TROUBLES READING THE DIRECTORY PAGE, SO GIVE THE
;APPROPRIATE WARNING MESSAGES.

	WARN	<Problem with disk address >
	CALL	OUTADR		;DO THE ADDRESS
	MOVE	T1,LSTERR	;RE-GET THE ERROR CODE
	TYPE.	@DATMSG(T1)	; FOLLOW WITH THE PARTICULAR ERROR
	CAIN	T1,.DSHRD	;UNREADABLE ERROR?
	JRST	[WARN	Cannot continue with directory dump
		 CALL	CLRABT	;CLEAR CONTROL-E
		 RET]		;WARNED AND DONE

	;...
;HERE WE ARE GOING TO DUMP OUT THE DIRECTORY PAGE

MICDM0:	MOVSI	P1,-PGSIZ	;BUILD AOBJN POINTER FOR PAGE IN P1
	HRRI	P1,DATPAG	;PAGE READ INTO DATPAG

MICDML:	SKIPN	1(P1)		;SUPPRESS ANY ENTRIES WITH OFFSET,,LEN ZERO
	JRST	MICDMX		; BY GOING TO BOTTOM OF LOOP
	MOVEI	T1,-DATPAG+1(P1) ;GET OFFSET
	IDIVI	T1,2		;CONVERT TO ENTRY NUMBER
	MOVE	T2,T1		;COPY TO T2
	CAILE	T1,MXDRNM	;SPECIAL?
	MOVEI	T2,MXDRNM	;NO, USE INDIRECT FILE MESSAGE
	PRINT.	@MICMSG(T2)	;PRINT THE HEADER BLURB
	CAIL	T1,MXDRNM	;GIVE INDIRECT FILE NUMBER?
	JRST	[SUBI	T1,MXDRNM	;CORRECT COUNT
		 DECOUT	T1,3		;DO IT
		 JRST	.+1]	; AND CONTINUE IN LINE
	PRINT	<
Starting Page Offset   Disk Address   CYL/TRK/SEC   Length in Pages
>				;HEADER LINE
	LOAD	T1,MICPGO,(P1)	;GET PAGE OFFSET
	PRINT	<       >	;SPACING
	DECOUT	T1,6		;OUTPUT IT
	IMUL	T1,SECPAG	;MAKE INTO SECTORS
	LOAD	T2,STGADR,MICBEG ;FETCH STARTING ADDRESS
	ADD	T1,T2		;AND ADD TO BEGINNING OF FILE
	PRINT	<          >	;SPACING
	OCTOUT	T1,^D9		; THEN OUTPUT IN OCTAL
	PRINT	<     >		;SPACING
	LOAD	T1,MICCYL,(P1)	;GET CYLINDER
	OCTOUT	T1,3		;CYLINDER OUTPUT
	PRINT	</>		;SEPARATOR
	LOAD	T1,MICTRK,(P1)	;TRACK
	OCTOUT	T1,3		;OUTPUT
	PRINT	</>		;SEPARATE
	LOAD	T1,MICSEC,(P1)	;SECTOR
	OCTOUT	T1,3		;OUTPUT
	PRINT	<      >	;SPACING
	LOAD	T1,MICLEN,(P1)	;FETCH THE LENGTH
	DECOUT	T1,6		;OUTPUT IN DECIMAL
	LOAD	T1,MICPGO,(P1)	;GET PAGE OFFSET AGAIN
	IMUL	T1,SECPAG	;CONVERT TO SECTORS
	CAML	T1,MICSIZ	; AND SEE IF IT IS REASONABLE
	 WARN	Page offset is outside of range allowed by HOME block
	LOAD	T1,MICLEN,(P1)	;NOW GET THE LENGTH AGAIN
	IMUL	T1,SECPAG	;CONVERT TO SECTORS ALSO
	CAML	T1,MICSIZ	; AND SEE IF LENGTH IS REASONABLE
	 WARN	File length is outside of range allowed by HOME block
	;...
	MOVX	T1,MICUSD	;SEE IF OTHER 8080 BITS ARE ZERO
	TDNE	T1,0(P1)	; BY CHECKING POINTER WORD
	 WARN	Unused Microprocessor CYL/TRK/SEC word bits non-zero
	PRINT	<

>				;BLANK LINE

MICDMX:	AOBJN	P1,.+1		;TWO WORD COUNTER
	AOBJN	P1,MICDML	;LOOP TILL DONE
	CALL	CLRABT		;CLEAR CONTROL-E ABORT
	RET			;AND ALL DONE




;HERE ON CONTROL-E TO ABORT THE MICROPROCESSOR DIRECTORY DUMP

MICABT:	MOVEI	T1,.PRIOU	;CLEAR
	CFOBF			;THE OUTPUT BUFFER
	 ERJMP	LOSE
	WARN	Microprocessor file system dump aborted
	MOVE	P,SAVPSI	;RESET STACK TO KNOWN VALUE
	RET			;AND RETURN




;TEXT STRINGS FOR THE "KNOWN" PREDEFINED MICROPROCESSOR FILES

MICMSG:	[TEXT	<Free Space Region>]	;*NOTE* THESE ARE IN ORDER
	[TEXT	<Microcode File>]
	[TEXT	<Monitor Pre-BOOT File>]
	[TEXT	<Diagnostic Pre-BOOT File>]
	[TEXT	<BOOTCHECK 2 File>]
	[TEXT	<Monitor BOOT File>]
	[TEXT	<Diagnostic BOOT File>]
	[TEXT	<Reserved Directory Words - Not Used>]
	MXDRNM==.-MICMSG		;LIMIT VALUE, REST ARE INDIRECT FILES
	[TEXT	<Indirect File #>]	;INDIRECT FILE HEADER LINE
	SUBTTL	CHECK COMMANDS, CHECK PAGE

;HERE TO HANDLE THE CHECK COMMAND.  SPLITS OFF TO THE VARIOUS SUB-FUNCTIONS
;TO HANDLE THEM INDIVIDUALLY.

CMDCHE:	MOVEI	T2,[FLDDB. (.CMKEY,,CHETAB)]	;SETUP
	PARSE			;INPUT KEYWORD
	MOVE	T2,0(T2)	;GET THE ADDRESS
	JRST	0(T2)		;TRANSFER AWAY

CHETAB:	CHELEN,,CHELEN		;DUMP TYPES TABLE
	AA	FILE-READABILITY,CHERED ;READ-CHECK FILES
	AA	INDEX-BLOCK,CHEIDX ;CHECK INDEX BLOCK
	AA	PAGE,CHEPAG	;CHECK DISK PAGE
	CHELEN==.-CHETAB-1	;SIZE OF TABLE




;TABLE OF APPROPRIATE RDCHK RESPONSE TEXTS

CHPGTB:	PTXT	<No problems encountered reading page>	;.DSOK
	PTXT	<% Transient read errors encountered reading page> ;.DSRND
	PTXT	<% ECC is required to read page>	;.DSECC
	PTXT	<% Page is completely unreadable>	;.DSHRD

;CHEPAG - CHECK PAGE AT SPECIFIED DISK ADDRESS
;BASICALLY JUST CALLS RDCHK AFTER FINISHING COMMAND PARSE.
;USES P1/	ADDRESS
;     P2/	REPEAT COUNT
;     P3/	ERROR COUNT

CHEPAG:	NOISE	(AT DISK ADDRESS)	;DO GUIDEWORDS
	MOVEI	T2,[FLDDB. (.CMNUM,,^D8)] ;OCTAL NUMBER
	PARSE			;GET THE ADDRESS
	MOVE	P1,T2		;SAVE FOR CONFIRM
	NOISE	(NUMBER OF TIMES) ;DO GUIDEWORDS
	MOVEI	T2,[FLDDB. (.CMNUM,CM%SDH,^D10,<times to repeat>,<1>,[
		    FLDDB. (.CMKEY,,<[1,,1	;KEYWORD TABLE OF ONE
				 AA	(<UNTIL-STOPPED>,<0>)]>)])] ;ONLY ENTRY
	PARSE			;SEE WHAT WE GET
	TSC	T3,T3		;NUMBER?
	SKIPE	T3		;SKIP IF NUMBER GIVEN
	MOVX	T2,^D1000000000	; ELSE JUST USE A BIG NUMBER
	MOVE	P2,T2		;SAVE IT FOR LATER
	CONFRM			;CONFIRM THE LINE
	CALL	CHKUSE		;MAKE SURE THERE'S SOMETHING TO USE
	MOVEI	T1,CHPABT	;ADDRESS OF THE CONTROL-E ABORT ROUTINE
	CALL	SETABT		;SET UP TO ABORT ON CONTROL-E
	SETZ	P3,		;CLEAR ERROR COUNTER
CHEPGL:	LOAD	T1,STGADR,P1	;FETCH THE DISK ADDRESS
	CAME	T1,P1		;SEE IF VALID (MATCHES)
	 ERROR	Disk address specified is invalid
	MOVX	T2,.DSDAT	;USE DATPAG
	STOR	T2,DS%TYP,F	;TO LOAD PAGE INTO
	CALL	RDCHK		;CHECK THE PAGE
	JUMPE	T1,CHEPGE	;DON'T OUTPUT IF NO ERROR
	AOS	P3		;COUNT THE ERROR
	TYPE.	@CHPGTB(T1)	;TYPE THE APPROPRIATE RESPONSE
CHEPGE:	SOJG	P2,CHEPGL	;LOOP TIL DONE
	CALL	CLRABT		;CLEAR THE INTERRUPT STUFF
CHEPGX:	PRINT	<
[ >				;GIVE ERROR COUNT
	DECOUT	P3		;FROM P3
	PRINT	< errors counted ]
>				;FINISH TEXT
	RET			;AND WE ARE ALL DONE


;HERE ON CONTROL-E ABORT OF CHECK PAGE

CHPABT:	MOVEI	T1,.PRIOU	;CLEAR
	CFOBF			;THE OUTPUT BUFFER
	 ERJMP	LOSE
	WARN	Check Page function aborted
	MOVE	P,SAVPSI	;RESET THE STACK TO A KNOWN VALUE
	JRST	CHEPGX		;AND EXIT TYPING COUNT
	SUBTTL	CHECK COMMANDS, CHECK INDEX BLOCK

;CHEIDX - CHECK INDEX BLOCK AT SPECIFIED DISK ADDRESS
;BASICALLY JUST CALLS RDCHK AFTER FINISHING COMMAND PARSE.

CHEIDX:	NOISE	(AT DISK ADDRESS)	;DO GUIDEWORDS
	MOVEI	T2,[FLDDB. (.CMNUM,,^D8)] ;OCTAL NUMBER
	PARSE			;GET THE ADDRESS
	MOVE	P1,T2		;SAVE FOR CONFIRM
	CONFRM			;CONFIRM THE LINE
	CALL	CHKUSE		;MAKE SURE THERE'S SOMETHING TO USE
	LOAD	T1,STGADR,P1	;FETCH THE DISK ADDRESS
	CAME	T1,P1		;SEE IF VALID (MATCHES)
	 ERROR	Disk address specified is invalid
	MOVX	T2,.DSXB	;USE XBPAG
	STOR	T2,DS%TYP,F	;TO LOAD PAGE INTO
	CALL	RDCHK		;CHECK THE PAGE
	TYPE.	@CHPGTB(T1)	;TYPE THE APPROPRIATE RESPONSE
	TXNE	F,DS%BAT	;SEE IF BAT BIT IS SET FOR BLOCK
	 WARN	BAT Bit is set for Index Block
	TXNE	F,DS%CHK	;SEE IF CHECKSUM IS OK
	 JRST	[WARN	<Checksum for Index Block is incorrect, should be >
		 MOVEI	T1,XBPAG	;POINT TO THE PAGE AGAIN TO 
		 MOVX	T2,STGADR	;PREPARE TO CLEAR
		 ANDM	T2,0(T1)	; THE OLD VALUE
		 ANDM	T2,1(T1)	; OF THE CHECKSUM
		 ANDM	T2,2(T1)	; SO ROUTINE WILL
		 ANDM	T2,3(T1)	; CALCULATE CORRECT VALUE
		 CALL	CHKSUM		;RECALCULATE THE CHECKSUM
		 MOVE	T2,T1		;COPY THE VALUE
		 CALL	PXWD		;PRINT AS HALFWORDS
		 JRST	.+1]		; AND CONTINUE IN LINE
	MOVSI	T2,-<PGSIZ-4>	;ALL BUT CHECKSUM WORDS
CHEIDL:	MOVE	T1,XBPAG+4(T2)	;FETCH A WORD OF THE BLOCK
	TXNE	T1,<-1-STGADR>	;NON-ADDRESS BITS ZEROED?
	JRST	[WARN	Non-address bits in Index Block are non-zero
		 RET]		;SAY SO AND DONE
	AOBJN	T2,CHEIDL	;LOOP OVER ALL OF BLOCK
	TXNN	F,DS%CHK!DS%BAT	;NO CONTENTS ERRORS?
	TYPE	<
Contents of Index Block appear to be consistent>
	RET			;AND WE ARE ALL DONE
	SUBTTL	CHECK COMMANDS, CHECK FILE-READABILITY

;THE CHECK FILE-READABILITY COMMAND PERFORMS THE SAME FUNCTION AS
;THE PROGRAM READ, USING THE SAME PARAMETERS.
;THE SPECIFIED FILES ARE SCANNED PAGE BY PAGE,
;READING DOWN FROM THE SUPER-INDEX BLOCK TO THE INDEX BLOCKS TO THE DATA
;PAGES.  ANY READING PROBLEMS ARE REPORTED, ALONG WITH THE SETTING OF
;XBBAT IN ANY INDEX BLOCK.


CHERED:	NOISE	(OF FILES)	;DO GUIDEWORDS
	MOVX	T2,GJ%OLD!GJ%IFG!GJ%FLG	;EXISTS, WILD, RETURN FLAGS
	MOVEM	T2,JFNBLK+.GJGEN ;SET UP GTJFN FLAGS
	HRROI	T2,[ASCIZ/*/]	;SETUP DEFAULTS FOR
	MOVEM	T2,JFNBLK+.GJNAM ;FILENAME
	MOVEM	T2,JFNBLK+.GJEXT ;EXTENSION
	MOVEI	T2,.GJALL	;AND GENERATIONS
	HRRM	T2,JFNBLK+.GJGEN ;ALL WILD
	MOVEI	T2,[FLDDB. (.CMFIL,,,,<*.*.*>)]	;INPUT FILE
	PARSE			;PARSE THE FILESPEC
	MOVEM	T2,JFNTMP	;SAVE THE JFN
	CONFRM			;CONFIRM THE LINE
	MOVE	T1,JFNTMP	;COPY OVER THE JFN
	MOVEM	T1,FILJFN	; AS THE ONE TO USE
	SETZM	JFNTMP		; AND CLEAR TEMP SLOT
	MOVEI	T1,REDABT	;GET ADDRESS OF ABORT ROUTINE
	CALL	SETABT		; AND SET UP FOR CONTROL-E INTERRUPT
	SETZ	P4,		;START WITH NO ERRORS

CMDRE1:	TYPE	<
[Attempting to read file >	;TELL NAME FOR EACH
	HRRZ	T2,FILJFN	;GET THE JFN
	MOVEI	T1,.PRIOU	;TO OUTPUT
	SETZM	T3		;DEFAULT FORMAT
	JFNS			;DO THE FILENAME
	 ERJMP	LOSE
	TYPE	<]>		;AND END THE LINE
	CALL	DOREAD		;PROCESS THE FILE
	MOVE	T1,FILJFN	;GET THE JFN
	GNJFN			;STEP IT
	 ERJMP	[ CAIE	T1,GNJFX1	;NO MORE?
		  JRST	LOSE		;OTHER ERROR
		  SETZM	FILJFN		;MARK UNUSED
		  SETZM	JFNBLK+.GJNAM	;CLEAR WILDCARD STUFF
		  SETZM	JFNBLK+.GJEXT	; THAT WE STORED
		  SETZM	JFNBLK+.GJGEN	; IN THE GTJFN BLOCK
		  JRST	CHERDN]		; AND RETURN WITH ERROR COUNT
	JRST	CMDRE1		;AND LOOP
;CHERDN - HERE TO GIVE THE ERROR TOTAL ON NORMAL DONE, OR AFTER
;CONTROL-E ABORT.

CHERDN:	CALL	CLRABT		;MAKE SURE CONTROL-E ABORT IS CLEARED
	TYPE	<
[ Total problems noted:  >
	MOVE	T2,P4		;COPY ERROR TOTAL
	MOVEI	T1,.PRIOU	;OUTPUT TO TERMINAL
	MOVX	T3,^D10		; IN DECIMAL
	NOUT			; THE ERROR COUNT
	 ERJMP	LOSE
	TYPE	<]>		;CLOSE THE BRACKET
	RET			; AND FINALLY DONE



;REDABT - HERE TO HANDLE A CONTROL-E ABORT INTERRUPT OF READ-CHECK

REDABT:	MOVEI	T1,.PRIOU	;CLEAR OUTPUT
	CFOBF			; INSTEAD OF WAITING
	 ERJMP	LOSE
	WARN	Read-check of files aborted
	MOVE	P,SAVPSI	;RE-ADJUST STACK
	JRST	CHERDN		; AND EXIT THROUGH ERROR TOTAL CODE
;DOREAD - SUBROUTINE TO READ-CHECK A FILE FOR THE READ COMMAND
;  P4/	CUMULATIVE ERROR COUNT, NOT RESET
;	CALL	DOREAD
;RETURNS  +1:	ALWAYS, UNLESS ERROR

DOREAD:
	SVFLGS			;SAVE THE OLD FLAGS AND
	SETZ	F,		;CLEAR IN CASE FL%PHY WAS SET...
	HRRZ	T1,FILJFN	;GET THE JFN
	DVCHR			;GET CHARACTERISTICS AND DESIGNATOR
	MOVEM	T1,DSKSTR	;STORE DESIGNATOR
	LOAD	T2,DV%TYP,T2	;FETCH DEVICE TYPE FIELD
	CAIE	T2,.DVDSK	;DISK?
	 ERROR	File is not on a disk device
	HRRZ	T1,FILJFN	;GET THE JFN
	MOVE	T2,[.FBADR+1,,.FBHDR]	;READ UP TO .FBADR
	MOVEI	T3,FDBBLK	;WHERE TO PUT INFO
	GTFDB			;READ FDB
	 ERJMP	LOSE		;WON'T WORK
	MOVE	T1,FDBBLK+.FBCTL ;FETCH FDB BITS WORD
	TXNE	T1,FB%BAT	; AND SEE IF THE BAT BIT IS SET HERE
	 WARN	BAT bit is set in the file's FDB
	MOVE	T1,FDBBLK+.FBADR ;FETCH DISK ADDRESS
	ANDX	T1,STGADR	;MASK OUT OTHER BITS
	SKIPN	T1		;ASSURE NON-ZERO
	 JRST	[WARN	<Disk address in FDB is zero>
		 AOS	P4	;COUNT
		 RET]		;INDICATE AND RETURN
	MOVE	T2,FDBBLK+.FBCTL ;FETCH FLAGS WORD
	TXNN	T2,FB%LNG	;IS THIS A LONG FILE?
	 JRST	[ MOVEM	T1,SXBPAG	;NO--FAKE IT IN SUPER BLOCK
		  MOVSI	P2,-1		; WITH SINGLE WORD ENTRY
		  JRST	RNXTXB]		; AND JOIN UP WITH GENERAL CASE
	MOVEI	T2,.DSSXB	;LONG FILE, GET TYPE CODE
	STOR	T2,DS%TYP,F	;STORE IT IN F
	CALL	RDCHK		;READ IN SUPER INDEX BLOCK, CHECK IT
	CAIN	T1,.DSHRD	;REALLY HARD ERROR?
	JRST	[WARN	<Super Index Block is unreadable, disk address>
		 CALL OUTADR		;OUTPUT THE DISK ADDRESS
		 AOS	P4		;COUNT THE ERROR
		 RET]			; AND DON'T CONTINUE WITH THIS ONE
	SKIPE	T1,SXBMSG(T1)	;POINT TO APPROPRIATE MESSAGE
	PSOUT			;AND TYPE IT
	TXNE	F,DS%CHK	;CHECKSUM OK?
	 WARN	Checksum of super index block is wrong
	TXNE	F,DS%BAT	;BAT BIT SET?
	 WARN	Super index block has BAT bit set
	TXNE	F,DS%CHK!DS%BAT	;IF EITHER SET
	AOS	P4		;COUNT AS AN ERROR
	MOVSI	P2,-PGSIZ	;NUMBER OF ENTRIES IN A PAGE
	;...
;LOOP OVER ALL OF THE INDEX BLOCKS, AND THE PAGES THEY POINT TO.

RNXTXB:	MOVE	T1,SXBPAG(P2)	;FETCH THE INDEX BLOCK ADDRESS
	ANDX	T1,STGADR	;MASK OUT ANY OTHER BITS
	JUMPE	T1,RNXTXX	;IF NULL, GO ON
	MOVX	T2,.DSXB	;CODE FOR DOING INDEX BLOCK
	STOR	T2,DS%TYP,F	;MARK IN F
	CALL	RDCHK		;READ AND CHECK INDEX BLOCK
	CAIN	T1,.DSOK	;NO TROUBLE?
	TXNE	F,DS%BAT!DS%CHK	;WITH BATS OR CHECKSUM EITHER?
	SKIPA			;TROUBLES TO REPORT
	JRST	RNXTD0		;NOTHING TO NOTE
	AOS	P4		;COUNT AN ERROR
	WARN	<Problems noted with index block >	;NOTE
	MOVEI	T1,.PRIOU	;PREPARE TO
	HRRZ	T2,P2		;OUTPUT THE INDEX BLOCK NUMBER
	MOVEI	T3,^D8		;IN OCTAL
	NOUT			;DO IT
	 ERJMP	LOSE
	TYPE	< disk address >;AND DO DISK ADDRESS
	CALL	OUTADR		;OUTPUT
	MOVE	T1,LSTERR	;REGET LAST RDCHK ERROR CODE
	SKIPE	T1,XBMSG(T1)	;FETCH APPROPRIATE MESSAGE
	PSOUT			;TELL THE NEWS
	TXNE	F,DS%BAT	;AND CHECK THE BAT BIT
	 WARN	Index block has BAT bit set
	TXNE	F,DS%CHK	; AND THE CHECKSUM
	 WARN	Checksum of index block is wrong
	MOVE	T1,LSTERR	;ERROR CODE AGAIN
	CAIN	T1,.DSHRD	;IF UNREADABLE THEN
	JRST 	RNXTXX		; SKIP ALL DATA PAGES AND STEP INDEX BLOCK
RNXTD0:	MOVSI	P3,-PGSIZ	;SIZE OF A PAGE MAP
	;...
;LOOP OVER ALL OF THE DATA PAGES IN THE INDEX BLOCK

RNXTDP:	MOVE	T1,XBPAG(P3)	;FETCH POINTER TO NEXT DATA PAGE
	ANDX	T1,STGADR	;ISOLATE ADDRESS BITS
	JUMPE	T1,RNXTDX	;IF NULL, GO ON TO NEXT
	MOVX	T2,.DSDAT	;CODE TO READ A DATA PAGE
	STOR	T2,DS%TYP,F	;MARK IN F
	CALL	RDCHK		;READ AND CHECK DATA PAGE
	CAIN	T1,.DSOK	;WAS READ OK?
	JRST	RNXTDX		;YES, NO MESSAGE, STEP TO NEXT

	AOS	P4		;COUNT THE ERROR
	WARN	<Problems noted with data page >	;NOTE
	MOVEI	T1,.PRIOU	;OUTPUT
	HRRZ	T2,P2		;INDEX BLOCK NUMBER
	IMULI	T2,PGSIZ	;NUMBER OF PAGES/INDEX PAGE
	ADDI	T2,0(P3)	;AND THE OFFSET INTO THE CURRENT=PAGE #
	MOVEI	T3,^D8		;OCTAL OF COURSE
	NOUT			;TYPE THE PAGE NUMBER
	 ERJMP	LOSE
	TYPE	< disk address >;AND DO DISK ADDRESS
	CALL	OUTADR		;OUTPUT
	MOVE	T1,LSTERR	;FETCH ERROR CODE BACK
	SKIPE	T1,DATMSG(T1)	;FETCH APPROPRIATE MESSAGE
	PSOUT			;AND OUTPUT IT
RNXTDX:	AOBJN	P3,RNXTDP	;LOOP FOR ALL PAGES IN INDEX BLOCK

RNXTXX:	AOBJN	P2,RNXTXB	;LOOP FOR ALL INDEX BLOCKS
	RET			;AND THEN WE ARE DONE



;APPROPRIATE MESSAGE TEXTS INDEXED BY RDCHK RETURN CODE

SXBMSG:	0			;.DSOK--NO MESSAGE
	PTXT<% Transient error reading super index block>	;.DSRND
	PTXT<% ECC needed to read super index block>		;.DSECC
	PTXT<% Super index block is unreadable--can't continue>	;.DSHRD
XBMSG:	0
	PTXT<% Transient error reading index block>
	PTXT<% ECC needed to read index block>
	PTXT<% Index block is unreadable--data not scanned>
DATMSG:	0
	PTXT<% Transient error reading data page>
	PTXT<% ECC needed to read data page>
	PTXT<% Data page is unreadable>
	SUBTTL	COPY COMMAND

;CMDCPY - HERE TO DO COPY COMMAND OF READING FILE FROM GIVEN INDEX OR
;SUPER INDEX BLOCK ADDRESS TO DESTINATION FILE.
;HERE TO PARSE THE COMMAND.

CMDCPY:	MOVEI	T2,[FLDDB. (.CMKEY,,CPYTAB,,<FILE>)]
	PARSE			;PARSE NEXT INPUT
	HRRZ	T2,0(T2)	;FETCH TYPE CODE
	TXZ	F,FL%LNG!FL%TMP	;CLEAR FLAG BITS
	CAIN	T2,1		;LONG FILE?
	TXO	F,FL%LNG	;SPECIFIED LONG FILE
	CAIN	T2,2		; OR JUST DISK ADDRESS?
	TXO	F,FL%TMP	;YES
	MOVEI	T2,[ASCIZ/WITH INDEX BLOCK ADDRESS/]
	TXNE	F,FL%TMP	;SELECT PROPER NOISEWORDS
	MOVEI	T2,[ASCIZ/AT ADDRESS/]
	CALL	DONOIS		;HANDLE THE GUIDEWORDS
	MOVEI	T2,[FLDDB. (.CMNUM,,^D8)]
	PARSE			;READ AN OCTAL DISK ADDRESS
	MOVEM	T2,P1		;SAVE ADDRESS FOR NOW
	NOISE	(TO)
	MOVEI	T2,[FLDDB. (.CMOFI)]
	PARSE			;PARSE AN OUTPUT FILE
	MOVEM	T2,JFNTMP	;SAVE THE JFN FOR A BIT
	CONFRM			;CONFIRM THE COMMAND
	LOAD	T1,STGADR,P1	;CHECK OUT THE DISK ADDRESS
	CAME	T1,P1		; FOR RANGE
	 ERROR	Invalid disk address specified
	CALL	CHKUSE		;MAKE SURE UNIT/STR USABLE
	MOVE	T1,JFNTMP	;GET BACK TEMP JFN
	MOVEM	T1,CJFN		; AND SET IT AS THE COPY JFN
	SETZM	JFNTMP		; AND MARK TEMP SLOT CLEAR
	MOVE	T1,CJFN		;GET IT BACK
	DVCHR			;GET DEVICE CHARACTERISTICS
	 ERJMP	LOSE
	LOAD	T2,DV%TYP,T2	;FETCH THE DEVICE TYPE
	CAIE	T2,.DVDSK	; WHICH HAD BETTER BE A DISK
	 ERROR	Output must be to a disk device
	HRRZ	T1,CJFN		;GET THE JFN BACK AGAIN
	MOVX	T2,OF%WR	;OPEN TO WRITE FOR PMAP'ING
	OPENF			;TRY THE OPEN
	 ERJMP	LOSE
	JN	FL%TMP,F,CMDCP0	;DATA PAGE?
	JN	FL%LNG,F,CMDCP1	;LONG FILE?
	MOVEM	P1,SXBPAG	; NO, FAKE SXB WITH XB ADR
	MOVSI	P2,-1		; AND KLUDGE UP AOBJN POINTER
	JRST	CMDCP2		; THEN GO INTO THE GENERAL LOOP

CMDCP0:	MOVSI	P2,-1		;FAKE UP P2
	MOVSI	P3,-1		; AND P3, AND
	MOVEM	P1,XBPAG	; FAKE XB ADR TO POINT TO PAGE
	JRST	CMDCP4		; THEN JUMP INTO GUTS OF GENERAL LOOP

;READ IN THE SUPER INDEX BLOCK

CMDCP1:	MOVSI	P2,-PGSIZ	;SIZE OF A SUPER INDEX BLOCK
	MOVEI	T2,.DSSXB	;SUPER INDEX BLOCK TYPE CODE
	STOR	T2,DS%TYP,F	;SET IT FOR RDCHK
	CALL	RDCHK		;READ IN THE SXB
	CAIN	T1,.DSHRD	;UNREADABLE?
	 JRST	[ERROR	Super Index Block is unreadable ]
	SKIPE	T1,SXBMSG(T1)	;FETCH APPROPRIATE READ ERROR MSG
	PSOUT			; AND WARN IF APPROPRIATE
	TXNE	F,DS%CHK	;CHECKSUM OK?
	 WARN	Checksum of Super Index Block is wrong
	TXNE	F,DS%BAT	;CHECK BAT BIT ALSO
	 WARN	Super Index Block has BAT bit set
	MOVSI	P2,-PGSIZ	;NUMBER OF ENTRIES ON PAGE

	;...
;TOP OF LOOP, READ IN INDEX BLOCK
;USE P2/  AOBJN POINTER FOR INDEX BLOCKS IN SUPER INDEX BLOCK
;    P3/  AOBJN POINTER FOR DATA PAGES WITHIN INDEX BLOCK

CMDCP2:	MOVE	T1,SXBPAG(P2)	;FETCH NEXT INDEX BLOCK ADDRESS
	ANDX	T1,STGADR	;MASK OUT ANY OTHER BITS
	JUMPE	T1,CMDCPX	; IF NO PAGES, GO ON TO NEXT
	MOVX	T2,.DSXB	;RDCHK CODE FOR INDEX BLOCK
	STOR	T2,DS%TYP,F	;SET IT
	CALL	RDCHK		;READ THE INDEX BLOCK
	CAIN	T1,.DSOK	;ALL RIGHT?
	TXNE	F,DS%BAT!DS%CHK	;WITH BAT OR CHECKSUM TOO?
	 SKIPA			;NO, REPORT TROUBLES
	JRST	CMDCP3		;NOTHING TO NOTE, CONTINUE

	WARN	<Problems noted with index block >
	MOVX	T1,.PRIOU	;PREPARE TO
	HRRZ	T2,P2		;OUTPUT THE INDEX BLOCK
	MOVEI	T3,^D8		;NUMBER IN OCTAL
	NOUT			;OUTPUT IT
	 ERJMP	LOSE
	TYPE	< disk address > ;AND DO DISK ADDRESS ALSO
	CALL	OUTADR		;OUTPUT IT
	MOVE	T1,LSTERR	;FETCH LAST ERROR CODE
	SKIPE	T1,XBMSG(T1)	;POINT TO PROPER MESSAGE
	PSOUT			;DELIVER IT IF APPROPRIATE
	TXNE	F,DS%BAT	;CHECK BAT BIT
	 WARN	Index block has BAT bit set
	TXNE	F,DS%CHK	;CHECKSUM BIT
	 WARN	Index block has incorrect checksum
	MOVE	T1,LSTERR	;GET ERROR CODE AGAIN
	CAIN	T1,.DSHRD	;UNREADABLE?
	JRST	CMDCPX		; YES, SO SKIP ALL ITS DATA PAGES.
	;...
;HERE TO START THE DATA PAGES FOR THE INDEX BLOCK

CMDCP3:	MOVSI	P3,-PGSIZ	;SIZE OF A PAGE MAP
CMDCP4:	MOVE	T1,XBPAG(P3)	;FETCH POINTER TO NEXT DATA PAGE
	ANDX	T1,STGADR	;ISOLATE ADDRESS BITS
	JUMPE	T1,CMDCP6	;IF NULL, GO ON TO NEXT

	MOVX	T2,.DSDAT	;CODE TO READ A DATA PAGE
	STOR	T2,DS%TYP,F	;MARK IN F
	CALL	RDCHK		;READ AND CHECK DATA PAGE
	CAIN	T1,.DSOK	;WAS READ OK?
	JRST	CMDCP5		;YES, NO MESSAGE, OUTPUT AND STEP

	WARN	<Problems noted with data page >	;NOTE
	MOVEI	T1,.PRIOU	;OUTPUT
	HRRZ	T2,P2		;INDEX BLOCK NUMBER
	IMULI	T2,PGSIZ	;NUMBER OF PAGES/INDEX PAGE
	ADDI	T2,0(P3)	;AND THE OFFSET INTO THE CURRENT=PAGE #
	MOVEI	T3,^D8		;OCTAL OF COURSE
	NOUT			;TYPE THE PAGE NUMBER
	 ERJMP	LOSE
	TYPE	< disk address >;AND DO DISK ADDRESS
	CALL	OUTADR		;OUTPUT
	MOVE	T1,LSTERR	;FETCH ERROR CODE BACK
	SKIPE	T1,DATMSG(T1)	;FETCH APPROPRIATE MESSAGE
	PSOUT			;AND OUTPUT IT
	MOVE	T1,LSTERR	;GET ERROR CODE AGAIN
	CAIN	T1,.DSHRD	;DON'T OUTPUT IF UNREADABLE
	JRST	CMDCP6		;JUST CONTINUE

;HERE TO OUTPUT DATA PAGE

CMDCP5:	MOVE	T1,[.FHSLF,,DATPAG_<-PGSHFT>] ;SOURCE IS DATPAG
	HRLZ	T2,CJFN		;DESTINATION JFN
	HRRZ	T3,P2		;INDEX BLOCK NUMBER
	IMULI	T3,PGSIZ	; TIMES PAGE SIZE GIVES SECTION
	ADDI	T3,0(P3)	; PLUS PAGE OFFSET IS DESTINATION PAGE
	HRR	T2,T3		;COPY IT OVER
	MOVX	T3,PM%WR	;WRITE REQUEST
	HRRZM	T2,LSTCPY	;SAVE LAST PAGE COPIED
	PMAP			;WRITE THE PAGE
	 ERJMP	LOSE
CMDCP6:	AOBJN	P3,CMDCP4	;LOOP FOR ALL PAGES IN INDEX BLOCK

CMDCPX:	AOBJN	P2,CMDCP2	;LOOP FOR ALL INDEX BLOCKS
	;...

;HERE WHEN ALL THE LOOPING IS DONE TO SET THE FILE SIZE AND CLOSE

	HRRZ	T1,CJFN		;GET THE OUTPUT COPY JFN
	HRLI	T1,.FBSIZ	;WORD IN FDB TO CHANGE
	SETO	T2,		;MASK IN T2
	MOVE	T3,LSTCPY	;GET LAST PAGE NUMBER
	ADDI	T3,1		;SINCE PAGES START WITH ZERO
	IMULI	T3,PGSIZ	;TURN TO WORDS
	CHFDB			;SET END OF FILE
	 ERJMP	LOSE
	HRLI	T1,.FBBYV	;BYTE SIZE WORD
	MOVX	T2,FB%BSZ	;MASK FOR BYTE SIZE
	MOVX	T3,FLD(^D36,FB%BSZ) ;36 BIT BYTES
	CHFDB			;SET BYTE SIZE
	 ERJMP	LOSE
	HRRZ	T1,CJFN		;GET BACK JFN
	CLOSF			;CLOSE THE FILE
	 ERJMP	LOSE
	TYPE	<
[COPY completed]>
	RET			;AND THEN WE ARE DONE




;KEYWORD TABLE FOR FILE TYPE

CPYTAB:	CPYTBL,,CPYTBL		;LENGTH
	AA	FILE,0		;NORMAL FILE
	AA	LONG-FILE,1	;LONG FILE
	AA	PAGE,2		;JUST GET PAGE
	CPYTBL==.-CPYTAB-1
	SUBTTL	CHKUSE - CHECK UNIT USABILITY FOR COMMANDS

;CHKUSE - ROUTINE TO MAKE GENERAL USE CHECK BEFORE PROCEEDING WITH
;CURRENT COMMAND.  VERIFIES THAT THE FL%SUS FLAG IS ON SO THAT A
;STRUCTURE OR UNIT HAS BEEN SPECIFIED, AND IN THE CASE OF SELECTING
;A PARTICULAR DRIVE, MAKES SURE THAT THE DRIVE IS INDEED ON-LINE TO
;AVOID HANGING NOINT IN A DSKOP FOR AN OFF-LINE PACK.
;
;	CALL	CHKUSE
;RETURNS  +1:	ALWAYS, IF THE ABOVE CONDITIONS SATISFIED

CHKUSE:	TXNN	F,FL%SUS	;SOMETHING WE WANT TO USE SPECIFIED?
	 ERROR	No Structure or Drive has been specified yet
	TXNN	F,FL%PHY	;DRIVE SPECIFIED?
	 RET			;NO - STRUCTURE, ASSUME ON-LINE...
	CALL	UNTINF		;CHECK OUT THE UNIT AGAIN
	TXNE	T1,MS%OFL	;SAFELY ON-LINE?
	 ERROR	Drive is off-line
	RET			;YES, RETURN
	SUBTTL	VERIFY COMMAND TO READ-CHECK A UNIT OR STRUCTURE

;HERE TO HANDLE THE VERIFY COMMAND.  AFTER CONFIRMATION, THE NECCESSARY
;PARAMETERS ARE FOUND, AND THE UNIT OR STRUCTURE IS READ, PAGE BY PAGE
;USING DSKOPS, IN ORDER TO FIND ANY BAD SPOTS, AND GET HARD ERRORS
;INTO THE BAT BLOCKS.  NOTE THAT HAVING A BLOCK IN THE BAT BLOCKS DOES
;NOT GUARANTEED THAT IT WON'T BE RE-USED, SINCE IF IT IS IN A FILE AND
;THE FILE IS NOT MARKED AS CONTAINING BAT-BLOCKS, THEN THE BAD PAGE
;MAY BE RELEASED WHEN THE FILE IS EXPUNGED, AND THEN REASSIGNED...
;SO, FOR A STRUCTURE WITH FILES ALREADY ON IT, SOMETHING LIKE PASSING
;THE ADDRESSES TO CHECKD TO SCAN FOR THE FILES, AND TAKING THE APPROPRIATE
;ACTION IS INDICATED.  THE VERIFY FUNCTION ALONE IS OF MORE DIRECT USE
;AFTER A PACK HAS JUST BEEN CREATED.

CMDVER:	MOVEI	T2,[ASCIZ/STRUCTURE/]
	TXNE	F,FL%PHY	;WHICH NOISE
	MOVEI	T2,[ASCIZ/UNIT/]
	CALL	DONOIS		;GIVE APPROPRIATE GUIDEWORD
	CONFRM			;CONFIRM THE LINE
	TXNN	F,FL%SUS	;STR/UNIT GIVEN YET?
	 ERROR	Structure or unit not yet specified

;GET THE APPROPRIATE STRUCTURE/UNIT INFORMATION

	TXNE	F,FL%PHY	;STRUCTURE OR UNIT?
	JRST	CMDVE1		;UNIT

	CALL	STRINF		;GET THE STRUCTURE INFO
	TYPE	<[ Working on Structure > ;GIVE FEEDBACK
	MOVEI	T1,.PRIOU
	MOVE	T2,DSKSTR	;DESIGNATOR
	DEVST			;DO THE STRING
	 ERJMP	LOSE
	TYPE	< ]
>				;CLOSE BRACKET
	JRST	CMDVE2		;AND CONTINUE

CMDVE1:	CALL	UNTINF		;GET THE UNIT INFO
	TYPE	<[ Working on pack on Channel >	;GIVE FEEDBACK
	MOVEI	T1,.PRIOU
	LOAD	T2,DOP%CN,DSKPHY ;GET CHANNEL
	MOVX	T3,^D8		;TYPE IN OCTAL
	NOUT
	 ERJMP	LOSE
	PRINT	<, Unit >	;NOW THE UNIT
	LOAD	T2,DOP%UN,DSKPHY ;FETCH IT
	MOVX	T3,^D8		;ALSO OCTAL
	NOUT
	 ERJMP	LOSE
	PRINT	< ]
>				;CLOSE BRACKET AND CONTINUE

;NOW THE UNIT SIZE IN PAGES IN IN UNITSZ(UNIT) AND THE NUMBER OF
;UNITS TO SCAN (IF DOING A STRUCTURE) IS IN PACKCT.
;INITIALIZE FOR ^E AND ^A INTERRUPTS AND BEGIN.
;REGISTER USE:
;	P1/ UNIT WORKING ON
;	P2/ DOWN COUNTER FOR UNIT
;	P3/ UNIT/STRUCTURE ADDRESS
;	P4/ CUMULATIVE ERROR COUNT

CMDVE2:	MOVE	T1,UNITSZ	;GET SIZE OF A UNIT
	IMUL	T1,PACKCT	; TIMES NUMBER OF UNITS
	IMUL	T1,SECPAG	; TIMES SECTORS/PAGE
	MOVEM	T1,MAXADR	; AND SAVE FOR PERCENT CALCULATIONS
	MOVEI	T1,VERABT	;WHERE TO ABORT TO ON ^E
	CALL	SETABT		;AND SETUP FOR THE INTERRUPT
	MOVE	T1,[.TICCA,,STSCHN] ;ACTIVATE
	ATI			; STATUS ON ^A
	 ERJMP	LOSE
	SETZ	P1,		;START WITH UNIT ZERO
	SETZ	P3,		;START WITH PAGE ZERO
	SETZ	P4,		;NO ERRORS YET
CMDVEL:	SKIPN	P2,UNITSZ(P1)	;SEE IF ANY PAGES, ERROR IF NOT
	ERROR	Unit with zero pages detected
CMDVLP:	MOVE	T1,P3		;COPY THE PAGE NUMBER
	MOVX	T2,.DSDAT	;READ AS A DATA PAGE
	STOR	T2,DS%TYP	; USING THE READ-CHECK ALGORITHM
	CALL	RDCHK		; IN ORDER TO REPORT VARIOUS PROBLEMS
	JUMPE	T1,CMDVLX	;JUMP IF OK
	;...
;PROBLEMS WITH THE READ--MENTION THEM

	AOS	P4		;COUNT THE ERROR
	WARN	<Problem with disk address  >
	CALL	OUTADR		;AND OUTPUT THE ADDRESS
	MOVE	T1,LSTERR	;REGET THE ERROR CODE
	TYPE.	@DATMSG(T1)	; FOLLOWED BY THE PARTICULAR ERROR TYPE
	TYPE	<
>				; AND SEPARATE WITH A BLANK LINE
CMDVLX:	ADD	P3,SECPAG	;SECTORS/PAGE TO GIVE NEXT PAGE ADDRESS
	SOJG	P2,CMDVLP	;LOOP TILL DONE WITH UNIT
	SOSLE	PACKCT		;COUNT UP ANOTHER UNIT
	AOJA	P1,CMDVEL	;AND KEEP GOING UNTIL OUT OF UNITS

;HERE WHEN VERIFY COMPLETE OR ON ABORT TO CLEAN UP AND DO ERROR TOTAL

VERDON:	CALL	CLRABT		;MAKE SURE CONTROL-E TURNED OFF
	MOVX	T1,.TICCA	;DISABLE ALSO THE
	DTI			; STATUS INTERRUPT
	 ERJMP	LOSE
	TYPE	<
[ Total problems noted: >	;LEAD-IN
	MOVE	T2,P4		;THE NUMBER
	MOVEI	T1,.PRIOU	;THE USUAL DESTINATION
	MOVX	T3,^D10		;IN DECIMAL
	NOUT			;OUTPUT THE COUNT
	 ERJMP	LOSE
	TYPE	< ]>		;CLOSE BRACKET
	RET			; ALL DONE




;DEBRK OF ^E INTERRUPT TRANSFERS CONTROL HERE TO FINISH THE ABORT
;FOR THE VERIFY COMMAND.

VERABT:	MOVEI	T1,.PRIOU	;PRESUME TO CLEAR
	CFOBF			; THE OUTPUT
	 ERJMP	LOSE
	WARN	Verification pass aborted
	MOVE	P,SAVPSI	;RE-ADJUST STACK TO KNOWN POINT
	JRST	VERDON		;AND CLOSE OUT THE COMMAND
;STSINT - HERE ON STATUS INTERRUPT TO GIVE THE CURRENT ADDRESS AND ERROR
;COUNT FOR THE OPERATION

STSINT:	MOVEM	P,PIACS+P	;SAVE AN AC TO USE
	MOVE	P,[0,,PIACS]	;SETUP AND DO
	BLT	P,PIACS+16	; BLT TO SAVE ACS
	MOVE	P,PIACS+P	;REGET P IN CASE WE NEED SOME STACK
	PUSH	P,.JBUUO##	;SAVE UUO LOC SO IT THEY ARE INTERRUPTIBLE

	MOVEI	T1,.PRIOU	;WAIT FOR SOME OF THE
	DOBE			; OUTPUT TO FINISH
	TYPE	<Working on disk address >
	CALL	OUTADR		;OUTPUT THE DISK ADDRESS
	TYPE	< (>		;NOW DO PERCENT DONE
	MOVE	T2,LSTADR	;FETCH LAST ADDRESS
	IMULI	T2,^D100	;SCALE FOR PERCENT
	IDIV	T2,MAXADR	;DIVIDE BY PROJECTED LAST ADDRESS
	MOVEI	T1,.PRIOU	;OUTPUT TO TERMINAL
	MOVX	T3,NO%LFL+FLD(2,NO%COL)+^D10 ;DECIMAL
	NOUT			;OUTPUT THE NUMBER
	 ERJMP	LOSE
	TYPE	<%), error count is >
	MOVEI	T1,.PRIOU	;AND OUTPUT
	MOVE	T2,P4		;THE ERROR COUNTER
	MOVX	T3,^D10		;IN DECIMAL
	NOUT
	 ERJMP	.+1
	TYPE	<
>				;FORMAT WITH A CRLF

	POP	P,.JBUUO##	;RESTORE UUO LOCATION
	MOVE	P,[PIACS,,0]	;SETUP BLT TO
	BLT	P,P		; RESTORE ACS
	DEBRK			; AND RETURN TO WHERE WE WERE
	 ERJMP	LOSE
	SUBTTL	SETABT, CLRABT AND ABTINT - PSI ROUTINES

;SETABT - ROUTINE TO SETUP FOR AN ABORT ON CONTROL-E (INTCHN)
;ACCEPTS
;  T1/	ADDRESS OF ROUTINE TO DEBRK TO ON INTERRUPT
;	CALL	SETABT
;RETURNS  +1:	ALWAYS WITH THE CHANNEL ENABLED AND KNOWN STACK VALUE
;		SAVED IN SAVPSI

SETABT:	MOVEM	T1,ABTADR	;SET THE ABORT HANDLER ADDRESS
	MOVE	T1,[.TICCE,,INTCHN] ;ACTIVATE ON
	ATI			; CONTROL-E
	 ERJMP	LOSE
	POP	P,T1		;POP OFF OUR RETURN ADDRESS AND
	MOVEM	P,SAVPSI	; SAVE A KNOWN STACK VALUE FOR CLEANUP
	JRST	0(T1)		; AND ALL DONE HERE FOR NOW




;CLRABT - ROUTINE TO CLEAR THE CONTROL-E INTERUPT ON INTCHN
;	CALL	CLRABT
;RETURNS  +1:	ALWAYS, AFTER DOING THE DTI

CLRABT:	MOVX	T1,.TICCE	;SETUP TO CLEAR THE CONTROL-E
	DTI			;DISABLE THE TERMINAL INTERRUPT
	 ERJMP	LOSE
	RET			; AND DONE




;ABTINT - HERE ON PSI INTERRUPT ON INTCHN, NORMALLY CONTROL-E ABORT.
;DEBREAK THROUGH ADDRESS IN ABTADR TO GET TO CLEANUP CODE.

ABTINT:	PUSH	P,T1		;GET A TEMP AC
	SKIPN	T1,ABTADR	;ADDRESS OF WHERE TO GO
	 ERROR	PSI error - abort address not initialized
	MOVEM	T1,CHNPC1	; IN PLACE OF RETURNING
	MOVX	T1,.TICCE	;CONTROL-E CODE
	DTI			;DISABLE THE INTERRUPT NOW
	 ERJMP	LOSE
	POP	P,T1		;RESTORE TEMP AC
	SETZM	ABTADR		;INDICATE GOT THE INTERRUPT
	DEBRK			;TERMINATE THE INTERRUPT
	 ERJMP	LOSE		;FAILED
	SUBTTL	RDCHK - ROUTINE TO READ IN AND CHECK DISK PAGE

;RDCHK - ROUTINE TO READ IN AND CHECK A GIVEN PAGE OF THE DISK.
;  T1/	DISK ADDRESS
;  F/	CODE IN DS%TYP FIELD--
;		.DSDAT DATA PAGE, USE DATPAG
;		.DSXB  INDEX BLOCK, USE XBPAG
;		.DSSXB SUPER INDEX BLOCK, USE SXBPAG
;  DSKSTR/  DEVICE DESIGNATOR FOR STRUCTURE
;
;	CALL	RDCHK
;
;RETURNS  +1:	ALWAYS, WITH CODE IN T1 INDICATING THE
;		RESULTS OF WHAT HAPPENED.  ALSO IN LSTERR.
;
;EIGHT TRIES ARE ATTEMPTED WITHOUT ECC OR LOGGING.  IF THESE FAIL,
;THEN A SINGLE TRY WITH ECC AND LOGGING IS DONE.  IF THE PAGE IS
;AN INDEX BLOCK, THEN THE CHECKSUM IS VALIDATED, AND THE BAT BIT IS
;CHECKED.


RDCHK:	TXZ	F,DS%BAT!DS%CHK	;INIT BAT BIT AND CHECKSUM BIT
	MOVEM	T1,CHKADR	;SAVE THE ADDRESS
	MOVEI	T3,10		;RETRY COUNT
	MOVEM	T3,RETRY	;INITIALIZE
RDCHK0:	LOAD	T1,DS%TYP,F	;GET TYPE CODE
	SKIPN	T2,TYPADR(T1)	;FETCH PROPER ADDRESS
	 ERROR	Incorrect page type passed to RDCHK
	TXO	F,DS%NEC!DS%NEL	;SPECIFY NO LOGGING AND NO ECC
	MOVE	T1,CHKADR	;FETCH THE DISK ADDRESS
	CALL	READ		;TRY TO READ THE PAGE
	JUMPE	T1,RDCHK1	;CONTINUE IF SUCCESSFUL
	SOSLE	RETRY		; ELSE COUNT THE TRY
	JRST	RDCHK0		; AND LOOP

;HERE THE RETRY COUNT HAS RUN OUT.  TRY USING ECC.

	LOAD	T1,DS%TYP,F	;PAGE TYPE
	MOVE	T2,TYPADR(T1)	;GET ADDRESS (SHOULD BE RIGHT NOW)
	TXZ	F,DS%NEC!DS%NEL	;ALLOW ECC AND LOGGING
	MOVE	T1,CHKADR	;DISK ADDRESS
	CALL	READ		;TRY IT NOW
	JUMPE	T1,RDCHK1	;SUCCEEDED, CONTINUE
	MOVEI	T1,.DSHRD	;RETURN HARD ERROR CODE IN T1
	MOVEM	T1,LSTERR	;AND IN LSTERR
	RET			; TO CALLER

	;...
;HERE WE HAVE COMPLETED A READ. IF AN INDEX BLOCK IS INVOLVED, THEN
;VALIDATE THE CHECKSUM AND THE BAT BIT.

RDCHK1:	LOAD	T1,DS%TYP,F	;GET THE TYPE FIELD AGAIN
	CAIN	T1,.DSDAT	;DATA PAGE?
	JRST	RDCHKX		;YES, RETURN RESULT CODE
	MOVE	T1,TYPADR(T1)	;INDEX BLOCK--FETCH ADDRESS OF PAGE
	CALL	CHKSUM		;DO THE CHECKSUM VALIDATION, AND 
				; CHECK THE BAT BIT
	AOSE	T1		;WAS CHECKSUM CORRECT?
	TXO	F,DS%CHK	; NO, REMEMBER
RDCHKX:	MOVEI	T1,.DSRND	;ASSUME TRANSIENT ERROR
	SKIPN	T2,RETRY	;CHECK RETRY COUNT
	MOVEI	T1,.DSECC	;ZERO--NEEDED ECC TO GET IT
	CAIN	T2,10		;FIRST TIME SUCCEED?
	MOVEI	T1,.DSOK	;YES--ERROR FREE
	MOVEM	T1,LSTERR	;SAVE CODE IN LSTERR ALSO
	RET			;AND RETURN

TYPADR:	EXP	0		;ZERO NOT A LEGAL TYPE - NOTE KEEP ORDERED
	EXP	DATPAG		;.DSDAT=1 DATA PAGE
	EXP	XBPAG		;.DSXB=2 INDEX BLOCK
	EXP	SXBPAG		;.DSSXB=3 SUPER INDEX BLOCK
	SUBTTL	READ - ROUTINE TO DO THE DSKOP

;READ - ROUTINE TO READ IN A PAGE OF THE DISK USING A DSKOP
;  F/	FLAGS--DS%NEC ON MEANS NO ERROR CORRECTION
;	       DS%NEL ON MEANS NO ERROR LOGGING
;  T1/	ADDRESS OF PAGE ON DISK
;  T2/	ADDRESS OF WHERE TO READ IT IN (SHOULD BE A PAGE BOUNDARY)
;  DSKSTR/   STRUCTURE DESIGNATOR FOR DISK -OR-
;  DSKPHY/   BYTE(2)1,(5)CHANNEL,(6)UNIT IF FL%PHY IS SET
;
;	CALL	READ
;
;RETURNS  +1:	ALWAYS, LSTADR CONTAINS THE DISK ADDRESS,
;			LSTDST CONTAINS THE ADDRESS READ INTO,
;			T1 CONTAINS THE VALUE RETURNED BY
;			THE DSKOP, ZERO IF NO ERROR OCCURRED.
;USES T1-T4.

READ:	MOVEM	T1,LSTADR	;SAVE THE ADDRESS
	MOVEM	T2,LSTDST	;SAVE THE DESTINATION TOO
	TXNE	F,FL%PHY	;UNIT OR STRUCTURE?
	JRST	READ1		;UNIT
	MOVX	T2,.DOPSR	;STRUCTURE RELATIVE ADDRESSING
	STOR	T2,DOP%AT,T1	;STORE FIELD
	SETONE	DOP%SN,T1	;SAY DEVICE DESIGNATOR IS IN T4
	MOVE	T4,DSKSTR	;FETCH DESIGNATOR
	SKIPA			;CONTINUE...
READ1:	IOR	T1,DSKPHY	;UNIT ADDRESSING, SET FIELDS
	HRRZI	T2,PGSIZ	;SIZE OF A PAGE
	TXNE	F,DS%NEC	;ERROR CORRECTION?
	TXO	T2,DOP%IR	;NO
	TXNE	F,DS%NEL	;ERROR LOGGING?
	TXO	T2,DOP%IL	;NO
	MOVE	T3,LSTDST	;WHERE TO READ IT
	DSKOP			;DO IT
	 ERJMP	LOSE		;FAILURE
	RET			;RETURN TO CALLER
	SUBTTL	CHKSUM - ROUTINE TO COMPUTE INDEX BLOCK CHECKSUM

;CHKSUM - ROUTINE TO DO THE CHECKSUM OF AN INDEX BLOCK
;EACH INDEX BLOCK CONTAINS ITS CHECKSUM IN THE FIRST NINE BITS OF
;THE FIRST FOUR WORDS OF THE BLOCK.
;THE BAT BIT, XBBAT IS BIT ZERO OF THE FOURTH WORD OF THE INDEX BLOCK,
;XBBWRD.
;
;  T1/	ADDRESS OF THE FIRST WORD OF THE BLOCK
;
;	CALL	CHKSUM
;
;RETURNS  +1:	ALWAYS, WITH COMPUTED CHECKSUM IN T1.
;		A CORRECT INDEX BLOCK WILL RETURN -1.
;		DS%BAT WILL BE SET IN F IF THE INDEX BLOCK IS MARKED
;		FOR HAVING AN ADDRESS IN THE BAT BLOCKS.
;USES T1-T4.

CHKSUM:	PUSH	P,P1		;SAVE AN AC
	MOVE	P1,T1		;TO USE AS A POINTER
	MOVE	T1,XBBWRD(P1)	;FETCH THE WORD WITH THE BAT BIT
	TXNE	T1,XBBAT	;IS THE BAT BIT SET?
	TXOA	F,DS%BAT	; YES
	TXZ	F,DS%BAT	; NO
	MOVSI	T2,-4		;CHECKSUM BYTES IN FIRST FOUR WORDS
	HRRI	T2,(P1)		;SO LOOP OVER THEM, GETTING THE FIRST
	MOVE	T3,[POINT 9,T1]	;NINE BITS TO STUFF INTO T1

CHKSM1:	LDB	T4,[POINT 9,0(T2),8]	;GET A BYTE OF THE CHECKSUM
	IDPB	T4,T3		;SAVE IT AWAY
	AOBJN	T2,CHKSM1	;GET ALL FOUR BYTES
	SETCA	T1,		;COMPLEMENT THE CHECKSUM
	JCRY0	.+1		;CLEAR CARRY BIT
	MOVSI	T2,-PGSIZ	;LOOP THE SIZE OF A PAGE
	HRLI	P1,T2		;SETUP INDEX FIELD IN P1 FOR INDIRECT

CHKSM2:	MOVE	T3,@P1		;GET NEXT WORD FROM INDEX BLOCK
	ANDX	T3,STGADR	;MASK TO DISK ADDRESS FIELD
	SKIPN	T3		;IF THERE IS NO ADDRESS PART
	MOVEI	T3,0(T2)	; USE THE OFFSET INTO THE PAGE
	ADD	T1,T3		;ADD IN THE RESULT TO THE CHECKSUM
	JCRY0	[AOJA	T1,.+1]	;ADD BACK IN ANY CARRY
	AOBJN	T2,CHKSM2	;LOOP FOR ALL WORDS IN PAGE
	POP	P,P1		;RESTORE THIS AC
	RET			;AND DONE
	SUBTTL	STRINF - ROUTINE FOR RETURNING STRUCTURE INFO

;STRINF - ROUTINE TO COLLECT THE NEEDED UNIT INFORMATION FOR THE
;DISK STRUCTURE WHOSE DESIGNATOR IS GIVEN IN DSKSTR.  THE DATA IS
;RETURNED IN THE APPROPRIATE TABLES, AND SOME CONSISTENCY CHECKING
;IS PERFORMED ON THE UNITS.
;PACKCT WILL RETURN THE NUMBER OF UNITS, UNITSZ THE SIZE IN PAGES,
;INDEXED BY UNIT, AND SECPAG THE NUMBER OF SECTORS PER PAGE (ASSUMES
;ALL UNITS ARE OF THE SAME TYPE).
;  DSKSTR/	DESIGNATOR FOR THE DESIRED STRUCTURE.
;
;	CALL	STRINF
;RETURNS  +1:	ALWAYS


STRINF:	MOVE	T1,[STRDAT,,STRDAT+1]	;CLEAR THE DATA AREA
	SETZM	STRDAT			;TO ZEROES BEFORE
	BLT	T1,STREND		;BEGINNING
	SETOM	MSBLK+.MSRCH	;INITIALIZE MSTR BLOCK
	SETOM	MSBLK+.MSRCT	;ALL ONES TO CHANNELS
	SETOM	MSBLK+.MSRUN	;UNITS AND CONTROLLERS
	SETZM	PACKCT		;WE HAVEN'T SEEN ANY UNITS YET

STRNXT:	CALL	UNTSTS		;GET STATUS OF NEXT UNIT
	JRST	[ SKIPN	T1,PACKCT	;GET ANY INFO?
		   ERROR	No units found for structure
		  CAME	T1,NPACKS	;DID WE GET THEM ALL?
		   ERROR Not all units of structure present
		  RET]			;YES--DONE
	MOVE	T1,MSBLK+.MSRST		;FETCH STATUS WORD
	TXNE	T1,MS%MNT		;IF IT IS NOT MOUNTED
	TXNE	T1,MS%OFL		; OR OFFLINE
	JRST	STRNXT			; WE ARE NOT INTERESTED

	;...
	HRROI	T1,ALIAS		;POINT TO RETURNED ALIAS
	STDEV				;GET A DESIGNATOR FROM IT
	 ERJMP	LOSE			;PROBLEMS
	CAME	T2,DSKSTR		;DOES IT MATCH?
	JRST	STRNXT			; NO--NOT INTERESTED
	HLRZ	T1,MSBLK+.MSRNS		;FETCH THE UNIT NUMBER
	CAIL	T1,MXUNIT		;TOO BIG FOR THE TABLE?
	 ERROR	Too many units in structure for internal tables
	SKIPE	UNITSZ(T1)		;ASSURE NO DUPLICATES
	 ERROR	Duplicate logical unit encountered for structure
	HRRZ	T2,MSBLK+.MSRNS		;NUMBER OF PACKS IN STR
	SKIPE	NPACKS			;DON'T CHECK FIRST TIME
	CAMN	T2,NPACKS		;MAKE SURE ALL OTHERS AGREE
	SKIPN	T2			; AND ZERO NOT GIVEN
	 ERROR	Units disagree about number of packs in structure
	MOVEM	T2,NPACKS		;SAVE THE VALUE
	AOS	PACKCT			;AND COUNT UP ANOTHER PACK
	SKIPN	T2,MSBLK+.MSRSU		;GET UNIT SIZE
	 ERROR	Unit claims to have zero sectors
	MOVE	T2,MSBLK+.MSRPC		;PAGES PER CYLINDER
	IMUL	T2,MSBLK+.MSRCU		;CYLINDERS PER UNIT
	MOVEM	T2,UNITSZ(T1)		;SAVE THE SIZE(LESS THAN A WORD)
	MOVE	T2,MSBLK+.MSRSP		;GET SECTORS/PAGE
	MOVEM	T2,SECPAG		;SAVE IT
	JRST	STRNXT			;AND LOOP FOR ALL UNITS
	SUBTTL	UNTSTS - ROUTINE FOR STATUS OF NEXT UNIT

;UNTSTS - ROUTINE TO RETURN THE NEXT UNIT STATUS IN THE MSTR BLOCK
;ACCEPTS:
;  MSBLK+.MSRCH/	PREVIOUS CHANNEL, -1 TO BEGIN
;  MSBLK+.MSRCH/	PREVIOUS CONTROLLER (-1)
;  MSBLK+.MSRUN/	PREVIOUS UNIT, -1 TO BEGIN
;
;	CALL	UNTSTS
;RETURNS  +1:	WHEN THE NUMBER OF UNITS IS EXHAUSTED
;	  +2:	WITH THE MSTR STATUS BLOCK SET UP IN MSBLK

UNTSTS:	HRROI	T1,ALIAS	;POINTER TO STRUCTURE ALIAS
	MOVEM	T1,MSBLK+.MSRSA	; TO BE RETURNED
	SETZM	ALIAS		;MAKE NULL IN CASE NONE RETURNED
	HRROI	T1,STRID	;POINTER TO STRUCTURE ID
	MOVEM	T1,MSBLK+.MSRSN	; TO BE RETURNED
	SETZM	STRID		;MAKE NULL IN CASE NONE RETURNED
	MOVE	T1,[.MSRBT+1,,.MSRNU]	;LENGTH,,FUNCTION
	MOVEI	T2,MSBLK	;ADDRESS OF ARGUMENT BLOCK
	MSTR			;DO THE OPERATION
	 ERJMP	[MOVEI	T1,.FHSLF	;US
		 GETER			;FIND THE ERROR
		 MOVEI	T1,0(T2)	;JUST THE ERROR CODE
		 CAIE	T1,MSTX18	;NO MORE UNITS?
		 JRST	LOSE		;SOME OTHER ERROR
		 RET]			;YES, DONE RETURN
	RETSKP			;SKIP RETURN WITH DATA
	SUBTTL	UNTINF - ROUTINE FOR STATUS OF PARTICULAR UNIT

;UNTINF - ROUTINE CALLED TO RETURN THE APPROPRIATE UNIT INFORMATION,
;SPECIFICALLY THE SIZE OF THE UNIT IN PAGES, RETURNED IN UNITSZ.
;THE VARIABLE PACKCT IS SET TO ONE AND THE VARIABLE SECPAG IS SET
;TO THE NUMBER OF SECTORS PER PAGE FOR THE UNIT.
;  DSKPHY/	DSKOP PROTOTYPE SET UP BY DRIVE COMMAND
;	CALL	UNTINF
;RETURNS  +1:	ALWAYS, UNIT STATUS IN T1

UNTINF:
	MOVEI	T1,1		;JUST ONE PACK
	MOVEM	T1,PACKCT	;SET IT
	LOAD	T1,DOP%CN,DSKPHY ;CHANNEL NUMBER
	MOVEM	T1,MSBLK+.MSRCH	;SET IN MSTR BLOCK
	SETOM	MSBLK+.MSRCT	;CONTROLLER
	LOAD	T1,DOP%UN,DSKPHY ;UNIT NUMBER
	MOVEM	T1,MSBLK+.MSRUN	;STORE
	SETZM	MSBLK+.MSRSA	;CLEAR POINTER TO ALIAS
	SETZM	MSBLK+.MSRSN	;NOT INTERESTED IN NAME EITHER
	MOVE	T1,[.MSRBT+1,,.MSRUS]	;LENGTH,,FUNCTION
	MOVEI	T2,MSBLK	;ADDRESS OF ARG BLOCK
	MSTR			;DO IT
	 ERJMP	LOSE		;FAILED
	MOVE	T2,MSBLK+.MSRPC	;PAGES PER CYLINDER
	IMUL	T2,MSBLK+.MSRCU	; TIMES CYLINDERS PER UNIT
	MOVEM	T2,UNITSZ	; GIVES PAGES PER UNIT.  SAVE IT
	MOVE	T1,MSBLK+.MSRSP	;GET NUMBER OF SECTORS/PAGE
	MOVEM	T1,SECPAG	;AND SAVE IT
	MOVE	T1,MSBLK+.MSRST	;FINALLY, RETURN UNIT SOFTWARE STATUS
	RET			;ALL DONE
	SUBTTL	VERSION NUMBER PRINTING ROUTINE


;VEROUT - PRINT OUT THE ASSEMBLED-IN VERSION NUMBER. (T1 ALREADY SET UP)
;  T1/	OUTPUT DESIGNATOR
;	CALL	VEROUT
;RETURNS  +1:	ALWAYS

VEROUT:	MOVEI	T3,10		;NOUT FORMAT, OCTAL
	MOVEI	T2,VMAJOR	;MAJOR VERSION LEVEL
	SKIPE	T2		;SKIP IF ZERO
	NOUT			; ELSE PRINT
	 ERJMP	LOSE		;FAILED
	MOVEI	T2,VMINOR+"A"-1	;LETTER FOR MINOR VERSION
	CAIE	T2,"A"-1	;DON'T BOTHER IF ZERO
	BOUT			; ELSE DO IT
	 ERJMP	LOSE
	MOVEI	T2,"("		;PARENS FOR EDIT LEVEL
	BOUT
	 ERJMP	LOSE
	MOVEI	T2,VEDIT	;ALWAYS DO EDIT NUMBER
	NOUT
	 ERJMP	LOSE
	MOVEI	T2,")"		;CLOSING PAREN
	BOUT
	 ERJMP	LOSE
	MOVEI	T4,VWHO		;LAST EDITOR
	JUMPE	T4,R		;DONE IF ZERO
	MOVEI	T2,"-"		; ELSE DO NUMBER
	BOUT			; AFTER DASH
	 ERJMP	LOSE
	MOVEI	T2,VWHO		;GET WHO BACK
	NOUT			;OUTPUT
	 ERJMP	LOSE
	RET			;AND DONE
	SUBTTL	LUUO HANDLER AND PROCESSING ROUTINES


;UUOH - THIS IS THE UUO HANDLER
;CALLED BY A CALL UUOH.  PRESERVES T1-T4 HERE ON THE STACK
;TO SAVE EFFORT FOR THE PROCESSING ROUTINES.  ALL PROCESSING
;ROUTINES SHOULD RETURN +1 FOR NOW, AND ALL UUOS.

UUOH:	ADJSP	P,4		;ALLOCATE SPACE ON THE STACK
	DMOVEM	T1,-3(P)	;SAVE T1,T2
	DMOVEM	T3,-1(P)	;SAVE T3,T4
	PUSH	P,.JBUUO##	;SAVE 40 TO ALLOW RECURSION
	LOAD	T1,UUONUM	;GET THE UUO NUMBER
	CAILE	T1,UUOMAX	;OUT OF RANGE?
	ERROR	DS Internal Error - LUUO Out of Range
	PUSH	P,UUODSP(T1)	;DISPATCH TO PROPER ROUTINE
	MOVE	T1,-5(P)	; AFTER RESTORING T1
	CALL	@0(P)		;CALL THE ROUTINE
	ADJSP	P,-1		;BUMP PAST CALL ADDRESS
	POP	P,.JBUUO##	;RESTORE LAST VALUE, SOMEONE MAY NEED IT
	DMOVE	T1,-3(P)	;RESTORE T1,T2
	DMOVE	T3,-1(P)	;RESTORE T3,T4
	ADJSP	P,-4		;DEALLOCATE STACK SPACE
	RET			;AND RETURN FROM LUUO

;THE UUO DISPATCH TABLE INDEXED BY UUO NUMBER

UUODSP:	EXP	LOSFIN		;IN CASE SOMEONE GETS HERE
	EXP	PRTUUO		;PRINT
	EXP	TYPUUO		;TYPE
	EXP	WRNUUO		;WARN
	EXP	ERRUUO		;ERROR
	EXP	OCTUUO		;OCTOUT
	EXP	DECUUO		;DECOUT
	UUOMAX==.-UUODSP-1	;COUNT
;PRTUUO - ROUTINE TO PROCESS THE PRINT UUO
;OUTPUTS TO THE JFN SET UP IN OJFN UNLESS IT IS ZERO, IN
;WHICH CASE .PRIOU IS USED

PRTUUO:
	SKIPN	T1,OJFN		;GET THE OUTPUT JFN
	MOVEI	T1,.PRIOU	;EITHER FILE OR TERMINAL
	HRRO	T2,.JBUUO##	;POINT TO THE STRING
	SETZ	T3,		;ASCIZ
	SOUT			;OUTPUT THE STRING
	 ERJMP	LOSE		;BLOW UP ON ERRORS
	RET			;AND RETURN TO THE CALLER



;TYPUUO - ROUTINE TO PROCESS THE TYPE UUO

TYPUUO:
	HRRO	T1,-2(P)	;POINT TO THE STRING (USE SAVED .JBUUO)
	PSOUT			;OUTPUT THE STRING
	 ERJMP	LOSE		;HANDLE BAD ERRORS
	RET			;AND RETURN TO CALLER

;WRNUUO - ROUTINE TO PROCESS THE WARN UUO

WRNUUO:
	MOVX	T1,.PRIOU	;SEE IF CRLF NEEDED
	DOBE			; BY WAITING FOR OUTPUT TO FINISH AND
	RFPOS			; BY GETTING POSITION
	TRNE	T2,-1		;AT LEFT?
	TYPE	<
>				;DO THE CRLF
	TYPE	<% >		;DO THE PERCENT
	CALLRET	TYPUUO		;AND THEN SAME AS TYPE


;ERRUUO - ROUTINE TO PROCESS THE ERROR UUO

ERRUUO:
	MOVX	T1,.PRIOU	;GET DESIGNATOR AND
	DOBE			; WAIT FOR OUTPUT TO FINISH, THEN
	RFPOS			; CHECK TO SEE IF CRLF NEEDED
	TRNE	T2,-1		;AT THE LEFT?
	TYPE	<
>				;DO THE CRLF
	TYPE	<? >		;TYPE THE LEADER
	MOVEI	T1,LOSFIN	;SETUP TO TRANSFER TO
	EXCH	T1,0(P)		; THE CLEANUP ROUTINE
	CALLRET	TYPUUO		; AND TYPE THE REST OF THE STRING
;OCTUUO - ROUTINE TO PROCESS THE OCTOUT UUO
;DECUUO - ROUTINE TO PROCESS THE DECOUT UUO


OCTUUO:	MOVE	T2,@.JBUUO	;DO FETCH FIRST TO ALLOW USING ACS
	MOVX	T3,NO%MAG+^D8	;OCTAL RADIX ENTRY
	JRST	NUMUUO		;ENTER COMMON CODE
DECUUO:	MOVE	T2,@.JBUUO##	;FETCH THE VALUE TO BE OUTPUT
	MOVEI	T3,^D10		;DECIMAL RADIX ENTRY
NUMUUO:	LOAD	T1,UUOAC	;GET COLUMN SIZE, 0 TO 17
	STOR	T1,NO%COL,T3	;SET UP THE COLUMNS FIELD
	SKIPE	T1		;IF ZERO PASSED, NO FILL IS USED
	TXO	T3,NO%LFL	; ELSE ASK FOR LEADING SPACE FILL
	SKIPN	T1,OJFN		;FETCH THE DESIRED
	MOVX	T1,.PRIOU	; OUTPUT DESIGNATOR
	NOUT			;DO THE OUTPUT
	 ERJMP	LOSE
	HRRZS	T3		;JUST THE RADIX
	CAIN	T3,^D10		;DECIMAL?
	PRINT	<.>		;YES, DO THE DECIMAL DOT
	RET			;AND RETURN
	SUBTTL	OUTPUT FORMATTING ROUTINES

;PXWD - ROUTINE TO OUTPUT AN OCTAL VALUE IN HALFWORD FORMAT
;ACCEPTS
;  T2/	VALUE TO BE OUTPUT
;	CALL	PXWD
;RETURNS  +1:	ALWAYS WITH NUMBER OUTPUT
;USES T2.

PXWD:	PUSH	P,T2		;SAVE THE VALUE
	HLRZS	T2		;DO THE LEFT HALF FIRST
	OCTOUT	T2		;BY USING OCTOUT
	PRINT	<,,>		;DO THE COMMAS TO SEPARATE
	POP	P,T2		;UNSTACK THE VALUE
	HRRZS	T2		;THE RIGHT HALF NOW
	OCTOUT	T2		;DO THE OUTPUT
	RET			; AND RETURN




;SPACEN - ROUTINE TO DO FORMATTING WITH SPACES
;ACCEPTS IN
;  T1/	OUTPUT DESIGNATOR
;  T3/	NUMBER OF SPACES TO OUTPUT
;	CALL	SPACEN
;RETURNS  +1:	ALWAYS

SPACEN:	MOVEI	T2," "		;GET A SPACE
	JUMPE	T3,R		;LEAVE IF DOING NONE
	BOUT			;OUTPUT A SPACE
	SOJG	T3,.-1		;LOOP TIL DONE
	RET			;AND THEN RETURN

;PSIX - ROUTINE TO OUTPUT A WORD IN SIXBIT TO THE SELECTED JFN
;ACCEPTS
;  T2/	VALUE TO BE OUTPUT
;	CALL	PSIX
;RETURNS  +1:	ALWAYS.  ALWAYS OUTPUTS SIX CHARACTERS
;USES T1-T4.

PSIX:	SKIPN	T1,OJFN		;GET THE SELECTED JFN
	MOVEI	T1,.PRIOU	; OR THE PRIMARY
	CALLRET	SIXWRD		;AND RETURN VIA SIXWRD




;PELV - ROUTINE TO OUTPUT A WORD IN -11 FORMAT IN CONTROLLED ASCII
;ACCEPTS
;  T2/	VALUE TO BE OUTPUT
;	CALL	PELV
;RETURNS  +1:	ALWAYS AFTER OUTPUTTING 8 CHARACTERS
;USES T1-T4, CALLS ELVWRD

PELV:	SKIPN	T1,OJFN		;GET THE SELECTED JFN
	MOVEI	T1,.PRIOU	; OR THE PRIMARY
	CALLRET	ELVWRD		;RETURN VIA ELVWRD TO DO THE WORK




;PHFLGS - ROUTINE TO OUTPUT THE HOME BLOCK FLAGS SET IN THE PASSED VALUE
;ACCEPTS
;  T2/	FLAGS WORD
;	CALL	PHFLGS
;RETURNS  +1:	ALWAYS AFTER TYPING THE FLAG NAMES, OR "NONE"
;ONLY CURRENT FLAG IS MS%LIM

PHFLGS:	SKIPN	T2		;ANYTHING?
	PRINT	<No Flags Set, Unlimited Directories Allowed>
	TXZE	T2,MS%LIM	;LIMIT FLAG SET?
	PRINT	<MS%LIM - Directories are limited to 2040/50 size>
	RET			;ALL FOR NOW
;SIXWRD - ROUTINE TO OUTPUT A WORD IN SIXBIT
;ACCEPTS
;  T1/	OUTPUT DESIGNATOR
;  T2/	WORD
;	CALL	SIXWRD
;RETURNS  +1:	ALWAYS AFTER OUTPUTTING SIX CHARACTERS
;CLOBBERS T2,T3,T4

SIXWRD:	MOVE	T3,T2		;COPY THE WORD
	MOVEI	T4,6		;NUMBER OF CHARACTERS TO DO
SIXWRL:	SETZ	T2,		;CLEAR T2
	LSHC	T2,6		;SHIFT UP A BYTE
	ADDI	T2," "-' '	;MAKE INTO ASCII
	BOUT			;OUTPUT THE CHARACTER
	SOJG	T4,SIXWRL	;AND LOOP FOR SIX
	RET			; THEN RETURN




;ASCWRD - ROUTINE TO OUTPUT A WORD IN CONTROLLED ASCII
;ACCEPTS
;  T1/	OUTPUT DESIGNATOR
;  T2/	WORD TO BE OUTPUT
;	CALL	ASCWRD
;RETURNS  +1:	ALWAYS
;CLOBBERS T2,T3,T4
;ALWAYS OUTPUTS TEN CHARACTERS, CONTROL CHARACTERS DENOTED BY ^<CHAR>.

ASCWRD:	MOVE	T3,T2		;COPY OVER WORD
	MOVEI	T4,5		;NUMBER OF BYTES TO DO
ASCWRL:	MOVEI	T2," "		;ASSUME NOT CONTROL CHARACTER
	TLNN	T3,(1B0!1B1)	;IS BYTE A CONTROL CHARACTER?
	MOVEI	T2,"^"		; YES, DO AN UP-ARROW
	BOUT			;OUTPUT FIRST CHARACTER
	SETZ	T2,		;CLEAR OUT GARBAGE
	LSHC	T2,7		;SHIFT UP A BYTE
	CAIGE	T2," "		;CONTROL?
	ADDI	T2,"@"		; YES, CONVERT TO A GRAPHIC
	CAIN	T2,.CHDEL	;AND IN CASE OF A NON-PRINTING RUBOUT
	MOVEI	T2," "		; TRY A SPACE FOR THE CHARACTER
	BOUT			;AND OUTPUT THE SECOND PART
	SOJG	T4,ASCWRL	;LOOP FOR FIVE
	RET			;THEN RETURN

;ELVWRD - ROUTINE TO OUTPUT CONTROLLED ASCII IN ELEVEN FORMAT
;ACCEPTS
;  T1/	OUTPUT DESIGNATOR
;  T2/	WORD TO BE OUTPUT
;	CALL	ELVWRD
;RETURNS  +1:	ALWAYS OUTPUTTING 8 CHARACTERS
;CLOBBERS T2,T3

ELVWRD:	MOVE	T3,T2		;SAVE THE WORD
	LOAD	T4,ELVB0,T3	;GET BYTE
	CALL	ELVASC		;CALL DO-IT ROUTINE
	LOAD	T4,ELVB1,T3	;NEXT...
	CALL	ELVASC
	LOAD	T4,ELVB2,T3
	CALL	ELVASC
	LOAD	T4,ELVB3,T3
	CALLRET	ELVASC		;DO LAST BYTE AND DONE

;ELVASC - LOCAL ROUTINE TO HANDLE CONTROL CHARACTERS,... FOR ELVWRD

ELVASC:	ANDI	T4,177		;LOOK AT ONLY 7 BITS
	CAIGE	T4," "		;CONTROL?
	SKIPA	T2,["^"]	;YES, PRECEDE WITH UP-ARROW
	MOVEI	T2," "		;NOT CONTROL, USE SPACE
	BOUT			;OUTPUT FIRST PART
	CAIL	T4," "		;CONTROL?
	SKIPA	T2,T4		;NO, JUST GET BYTE
	MOVEI	T2,"@"(T4)	; YES, MAKE INTO A GRAPHIC
	CAIN	T2,.CHDEL	;AND IN CASE OF A NON-PRINTING RUBOUT
	MOVEI	T2," "		; TRY A SPACE FOR NOW
	BOUT			;DO THE SECOND OUTPUT
	RET			;AND DONE
;OUTADR - ROUTINE TO TYPE OUT ON .PRIOU THE DISK ADDRESS LAST
;REFERENCED, IN OCTAL.
;  LSTADR/	LAST ADDRESS DSKOP'ED
;	CALL	OUTADR
;RETURNS  +1:	ALWAYS


OUTADR:
	MOVEI	T1,.PRIOU	;OUTPUT THE
	MOVE	T2,LSTADR	;DISK ADDRESS
	MOVX	T3,^D8		;IN OCTAL
	NOUT
	 ERJMP	LOSE
	RET			;AND DONE




;.SAVEF - INTERNAL ROUTINE TO SAVE REGISTER F AND RESTORE IT ON
;RETURN FROM CALLING ROUTINE.
;CALLED VIA THE SVFLGS MACRO
;USES CX.


.SAVEF:	PUSH	P,F		;SAVE THE FLAGS
	CALL	0(CX)		;CALL OUR CALLER
	SKIPA			;HANDLE SKIP RETURNS
	AOS	-1(P)		; AND NON-SKIP RETURNS
	POP	P,F		;RESTORE THE OLD FLAGS
	RET			;AND RETURN
	SUBTTL	ERROR PROCESSING AND COMND HELPER ROUTINES

;LOSE - GENERAL ROUTINE TO JRST/ERJMP TO.  OUTPUTS ERSTR MESSAGE
;AND SIMULATES REENTER.


LOSE:	SKIPE	T1,TAKJFN	;TAKE IN PROGRESS?
	JRST	[GTSTS			;YES--SEE IF EOF
		TXNE	T2,GS%EOF	;TEST BIT
		JRST	TAKEOF		;EOF
		JRST	.+1]		;OTHER ERROR, CONTINUE
	SKIPE	T1,OJFN		;TRY TO CLOSE OUTPUT IF
	CLOSF			; HAPPENED TO BE OPEN
	 ERJMP	.+1		;TOO BAD ON CLOSE ERRORS
	HRROI	T1,[ASCIZ/
? /]				;GET PRELIMINARY TEXT
	PSOUT			;TYPE IT
	MOVEI	T1,.PRIOU	;OUTPUT TO TERMINAL
	HRLOI	T2,.FHSLF	;LAST ERROR IN THIS FORK
	SETZ	T3,		;ALL OF THE TEXT
	ERSTR			;PRINT THE ERROR
	ERJMP	.+1		;FAILED
	ERJMP	.+1		;FAILED
	SKIPN	TAKJFN		;NEED TO ABORT TAKE?
	JRST	LOSFIN		;NO
	CALL	UNTAKE		;YES--SO DO IT
	TMSG	< -- command file aborted> ;AND SAY SO


LOSFIN:	HRROI	T1,[ASCIZ/

/]				;GET FINAL STRING
	PSOUT			;TYPE IT TOO
	MOVEI	T1,.PRIIN	;GET READY
	CFIBF			;CLEAR INPUT BUFFER
	JRST	REEN		;AND START OVER


TAKEOF:	CALL	UNTAKE		;CLEAN UP TAKE STATE
	TMSG	<
[Command file completed]>	;SAY SO
	JRST	REEN		;AND REENTER COMMAND LOOP
;DONOIS - ROUTINE TO HANDLE GUIDEWORD STRINGS.
;  T2/	ADDRESS OF ASCIZ GUIDEWORD STRING
;	CALL	DONOIS	OR USE NOISE MACRO
;RETURNS  +1:	ALWAYS


DONOIS:	HRROM	T2,NOIBLK+.CMDAT	;SAVE AS DATA
	MOVEI	T2,NOIBLK	;POINT TO BLOCK
	JRST	COMMND		;AND GO DO COMND JSYS


;DOCNFM - ROUTINE TO HANDLE LINE CONFIRMATION FUNCTION.
;	CALL	DOCNFM	OR USE CONFRM MACRO
;RETURNS  +1:	ALWAYS
;
;COMMND - CENTRAL ROUTINE TO PERFORM COMND JSYS CALL.
;  T2/	ADDRESS OF COMND DESCRIPRTOR BLOCK TO USE
;	CALL	COMMND	OR USE PARSE MACRO
;RETURNS  +1:	ALWAYS, UNLESS NOPARSE WHICH GENERATES ERROR


DOCNFM:	MOVEI	T2,[FLDDB. (.CMCFM)]	;GET CONFIRM FUNCTION
COMMND:	MOVEI	T1,CMDBLK	;POINT TO OUR (ONLY) COMMAND BLOCK
	COMND			;PARSE THE FUNCTION
	 ERJMP	LOSE		;ERROR, GO COMPLAIN
	TXNE	T1,CM%NOP	;DID IT PARSE?
	 JRST	LOSE		;NO, COMPLAIN
	RET			;YES, RETURN SUCCESSFULLY



;GUIDEWORD DESCRIPTOR BLOCK USED BY NOISE ROUTINE

NOIBLK:	FLDDB.	(.CMNOI)	;BLOCK FOR NOISE FUNCTION
	SUBTTL	THE DATA AREA

	XLIST			;DUMP THE LITERALS
DSLITS:	LIT
	LIST


CMDBLK:	0,,NEWPAR		;ADDRESS OF REPARSE ROUTINE
	.PRIIN,,.PRIOU		;INPUT,,OUTPUT JFNS
	-1,,[ASCIZ/DS>/]	;CONTROL-R POINTER
	-1,,TXTBUF		;POINTER TO TEXT BUFFER
	-1,,TXTBUF		;POINTER TO CURRENT POSITION
	TXTLEN			;NUMBER OF CHARS IN BUFFER
	0			;NUMBER OF UNPARSED CHARACTERS
	-1,,ATMBUF		;POINTER TO ATOM BUFFER
	TXTLEN			;NUMBER OF CHARACTERS IN BUFFER
	EXP	JFNBLK		;POINTER TO GTJFN BLOCK

JFNBLK:	GJ%OLD			;FLAGS,,GENERATION NUMBER
	.PRIIN,,.PRIOU		;INPUT,,OUTPUT JFNS
	BLOCK	20		;NO DEFAULTS

LEVTAB:	EXP	CHNPC1		;WHERE TO STORE PC FOR LEVEL ONE INTERRUPT
	BLOCK	2		;OTHER LEVELS UNUSED
CHNTAB:	XWD	1,ABTINT	;VECTOR FOR INTERRUPT ON THIS CHANNEL
	XWD	1,STSINT	;VECTOR FOR STATUS INTERRUPT
	BLOCK	^D34		;OTHER CHANNELS UNUSED
CHNPC1:	BLOCK	1		;INTERRUPT PC STORED HERE
SAVPSI:	BLOCK	1		;P SAVED HERE FOR ADJUST ON ^E
ABTADR:	BLOCK	1		;WHERE TO GO ON A ^E ABORT
PIACS:	BLOCK	20		;SAVED ACS DURING STATUS PSI
JFNX:	BLOCK	1		;JFN ON EXEC TO PUSH TO
HANDLE:	BLOCK	1		;FORK HANDLE FOR INFERIOR EXEC
OLDPRM:	BLOCK	1		;STORAGE FOR OLD I/O DESIGNATORS DURING TAKE
TAKJFN:	BLOCK	1		;TAKE FILE JFN WHEN NONZERO
OLDCAP:	BLOCK	1		;PRIOR PROCESS CAPABILITIES

SAVEP:	BLOCK	1		;STORAGE OF STACK
PDL:	BLOCK	PDLSIZ		;STACK ROOM
TXTBUF:	BLOCK	TXTLEN/5+1	;BUFFER FOR COMMAND JSYS
ATMBUF:	BLOCK	TXTLEN/5+1	;BUFFER FOR ATOM BUFFER

IJFN:	BLOCK	1		;INPUT FILE JFN
OJFN:	BLOCK	1		;OUTPUT FILE JFN
CJFN:	BLOCK	1		;COPY FILE JFN
FILJFN:	BLOCK	1		;WORD USUALLY HOLDING FILE JFN
JFNTMP:	BLOCK	1		;WORD FOR COMND'S JFNS RETURNED DURING PARSE
FDBBLK:	BLOCK	.FBADR+1	;SPACE FOR FDB DATA

DSKSTR:	BLOCK	1		;STRUCTURE DESIGNATOR FOR DSKOPS
DSKPHY:	BLOCK	1		;CHANNEL, UNIT DESIGNATOR FOR DSKOPS
RETRY:	BLOCK	1		;RETRY COUNTER FOR RDCHK
CHKADR:	BLOCK	1		;HOLDS DISK ADDRESS FOR RDCHK
LSTADR:	BLOCK	1		;DISK ADDRESS FOR READ
MAXADR:	BLOCK	1		;PROJECTED HIGHEST ADDRESS ON VERIFY
LSTERR:	BLOCK	1		;LAST DSKOP READ ERROR CODE FROM RDCHK
LSTDST:	BLOCK	1		;LAST DSKOP ADDRESS DESTINATION
LSTCPY:	BLOCK	1		;LAST PAGE NUMBER PMAP'ED OUT BY COPY

MICSIZ:	BLOCK	1		;SIZE OF KS FE AREA IN PAGES
MICBEG:	BLOCK	1		;WORD GIVING STARTING DISK ADDRESS FOR KS
				;MICROPROCESSOR FILE SYSTEM.  DIRECTORY PAGE

STRDAT:				;BEGINNING OF STRUCTURE DATA BLOCK
PACKCT:	BLOCK	1		;COUNT OF UNITS SEEN
SECPAG:	BLOCK	1		;SECTORS/PAGE ON UNITS
NPACKS:	BLOCK	1		;EXPECTED NUMBER OF UNITS IN STR
ALIAS:	BLOCK	10		;SPACE FOR STRUCTURE ALIAS STRING
STRID:	BLOCK	10		;SPACE FOR STRUCTURE-ID
MSBLK:	BLOCK	.MSRBT+1	;MSTR DATA BLOCK

	MXUNIT==30
UNITSZ:	BLOCK	MXUNIT		;SIZE OF UNIT IN PAGES
	STREND==.-1		;END OF STRUCTURE BLOCK


	END	<3,,EVEC>