Google
 

Trailing-Edge - PDP-10 Archives - BB-L288A-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==2		;MAJOR VERSION LEVEL
	VMINOR==0		;MINOR VERSION LEVEL
	VEDIT==112		;EDIT LEVEL
	VWHO==0			;WHO LAST EDITED




;DS IS A PRODUCT OF THE TOPS-20 MONITOR SUPPORT UNIT OF SOFTWARE SERVICES,
;PRIMARILY FOR INCLUSION ON THE TOPS-20 MONITOR SWSKIT.  THE PURPOSE OF DS
;IS TO PROVIDE DETAILED INFORMATION ABOUT TOPS-20 DISK UNITS, ESPECIALLY
;AS PART OF ANY ATTEMPTED RECOVERY A SOFTWARE SPECIALIST MIGHT TRY ON A
;DAMAGED DISK STRUCTURE.  THIS PROGRAM IS "TRUSTWORTHY" IN THAT IT WILL
;ONLY PROVIDE INFORMATION.  IT WILL NEVER ATTEMPT TO PERFORM PRIVLEGED
;WRITES TO A DISK PACK.
;
;RELATED FILES:
;	DS.HLP		HELP FILE FOR DS TYPED OUT ON HELP COMMAND
;	DS.MEM		USAGE GUIDE FOR DS WITH EXAMPLES
;	DS.MAC		THIS FILE
	SUBTTL	TABLE OF CONTENTS


;	TABLE OF CONTENTS					  PAGE
;	-----------------					  ----
;
;  1. J. G. ZIMA/JGZ  APRIL 1979 . . . . . . . . . . . . . . . . .   1
;  2. TABLE OF CONTENTS. . . . . . . . . . . . . . . . . . . . . .   2
;  3. REVISION HISTORY . . . . . . . . . . . . . . . . . . . . . .   3
;  4. DEFINITIONS. . . . . . . . . . . . . . . . . . . . . . . . .   9
;  5. ENTRY VECTOR AND INITIALIZATION. . . . . . . . . . . . . . .  15
;  6. THE SIMPLE COMMANDS - EXIT, HELP . . . . . . . . . . . . . .  17
;  7. FILDDT AND PUSH COMMANDS . . . . . . . . . . . . . . . . . .  18
;  8. TAKE COMMAND . . . . . . . . . . . . . . . . . . . . . . . .  19
;  9. OUTPUT FILE SPECIFICATION COMMAND. . . . . . . . . . . . . .  21
; 10. DRIVE SPECIFICATION COMMAND. . . . . . . . . . . . . . . . .  22
; 11. DEFINE COMMAND TO BUILD MULTI-UNIT SDB . . . . . . . . . . .  23
; 12. GETCKU - ROUTINE TO READ CHANNEL, CONTROLLER, UNIT . . . . .  25
; 13. STRUCTURE SPECIFICATION COMMAND. . . . . . . . . . . . . . .  26
; 14. INFORMATION COMMAND TO DISPLAY DRIVE STATUS. . . . . . . . .  27
; 15. DUMP COMMAND TO DUMP VARIOUS ITEMS . . . . . . . . . . . . .  30
; 16. DUMP COMMAND FOR DISK PAGES. . . . . . . . . . . . . . . . .  31
; 17. DUMP COMMAND FOR FILE INDEX BLOCKS . . . . . . . . . . . . .  33
; 18. DUMP COMMAND FOR HOME BLOCKS . . . . . . . . . . . . . . . .  38
; 19. DUMP COMMAND FOR BAT BLOCKS. . . . . . . . . . . . . . . . .  42
; 20. DUMP COMMAND FOR KS MICROPROCESSOR DIRECTORY . . . . . . . .  47
; 21. CHECK COMMANDS, CHECK PAGE . . . . . . . . . . . . . . . . .  51
; 22. CHECK COMMANDS, CHECK INDEX BLOCK. . . . . . . . . . . . . .  53
; 23. CHECK COMMANDS, CHECK FILE-READABILITY . . . . . . . . . . .  54
; 24. COPY COMMAND . . . . . . . . . . . . . . . . . . . . . . . .  59
; 25. COPY DIRECTORY COMMAND . . . . . . . . . . . . . . . . . . .  64
; 26. VERIFY COMMAND TO READ-CHECK A UNIT OR STRUCTURE . . . . . .  69
; 27. STSINT STATUS PSI INTERRUPT ROUTINE. . . . . . . . . . . . .  73
; 28. SEARCH COMMAND . . . . . . . . . . . . . . . . . . . . . . .  74
; 29. WATCH COMMAND TO WATCH DISK ADDRESS. . . . . . . . . . . . .  76
; 30. GENERAL DISK SCAN LOOP . . . . . . . . . . . . . . . . . . .  78
; 31. RPTERR - DISK ERROR REPORTING ROUTINE. . . . . . . . . . . .  79
; 32. SETABT, CLRABT AND ABTINT - PSI ROUTINES . . . . . . . . . .  80
; 33. RDCHK - ROUTINE TO READ IN AND CHECK DISK PAGE . . . . . . .  81
; 34. READ - ROUTINE TO DO THE DSKOP . . . . . . . . . . . . . . .  83
; 35. CHKSUM - ROUTINE TO COMPUTE INDEX BLOCK CHECKSUM . . . . . .  85
; 36. CHKUSE - CHECK UNIT USABILITY FOR COMMANDS . . . . . . . . .  86
; 37. STRINF - ROUTINE FOR RETURNING STRUCTURE INFO. . . . . . . .  87
; 38. UNTSTS - ROUTINE FOR STATUS OF NEXT UNIT . . . . . . . . . .  89
; 39. UNTINF - ROUTINE FOR STATUS OF PARTICULAR UNIT . . . . . . .  90
; 40. VERSION NUMBER PRINTING ROUTINE. . . . . . . . . . . . . . .  91
; 41. LUUO HANDLER AND PROCESSING ROUTINES . . . . . . . . . . . .  92
; 42. OUTPUT FORMATTING ROUTINES . . . . . . . . . . . . . . . . .  95
; 43. ERROR PROCESSING AND COMND HELPER ROUTINES . . . . . . . . . 100
; 44. THE DATA AREA. . . . . . . . . . . . . . . . . . . . . . . . 102
	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 INTERRUPTABLE. (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.
;
;***** BEGIN VERSION 2 ******
;
;  32	JGZ	23-APR-80
;		BEGIN VERSION 2.  PREPARE TO ADD SEARCH COMMANDS, SOME
;		DIRECTORY KNOWLEDGE, RP20 KNOWLEDGE, CKU FORMAT DSKOP,
;		SOME MULTIPLE DRIVE COORDINATION.
;
;  33	JGZ	3-MAY-80
;		CHANGE HELP COMMAND TO READ HLP:DS.HLP AND GET RID OF
;		THE ASSEMBLED-IN TEXT.
;
;  34	JGZ	17-MAY-80
;		MOVE NOISE BLOCK PAST LITERALS INTO IMPURE AREA.
;
;  35	JGZ	17-MAY-80
;		START BUILDING AN "SDB" FOR MULTI-UNIT PHYSICAL ADDRESSING.
;
;  36	JGZ	17-MAY-80
;		CHANGE ENOUGH SO THAT CURRENT COMMANDS WORK WITH CKU FORMAT
;		DSKOP CODE IN PLACE.  PUT THE CODE IN THE FORM OF RETROFIT
;		FOR OLD FORMAT DSKOP, SO IT'S FAIRLY EASY TO REMOVE OLD
;		FORMAT SOMETIME IN THE DIM FUTURE.
;
;  37	JGZ	17-MAY-80
;		ABORT CHECKING DATA PAGES IF INDEX BLOCK CHECKSUM IS BAD.
;		THE PAGE ADDRESSES MAY JUST BE MEANINGLESS....
;
;  40	JGZ	17-MAY-80
;		CLEAN UP LISTING A BIT, REMOVE THE :<CRLF> LABELS, MAKE A
;		FEW THINGS FIT ON A PAGE...
;
;  41	JGZ	18-MAY-80
;		CONVERT VEROUT TO NEWER FORMAT VERSION NUMBERS (ALMOST
;		DEC STANDARD, BUT OCTAL INSTEAD OF DECIMAL).
;
;  42	JGZ	18-MAY-80
;		MAKE DRIVE COMMAND TAKE CONTROLLER, ADJUST FOR NEW SDB,
;		UNTINF; BUILD SINGLE UNIT STR.  PUT LSTADR BACK IN READ,
;		MAKE VERIFY "WORKING ON" MESSAGE INCLUDE CONTROLLER.
;
;  43	JGZ	19-MAY-80
;		CONVERT UNIT NAME CODE TO SEARCH FROM TABLE LOOKUP.
;
;  44	JGZ	27-MAY-80
;		DON'T GO TO LOSE IF STDEV IN STRINF FAILS ON SOMETHING LIKE
;		A SICK PACK OUT THERE THAT DOESN'T RETURN A NAME STRING.
;
;  45	JGZ	28-MAY-80
;		PUT IN TOCT AND TDEC LUUOS; THEY MAY BE USEFUL AND DON'T
;		COST MUCH.
;
;  46	JGZ	28-MAY-80
;		USE TDEC AND TOCT IN A FEW PLACES.
;
;  47	JGZ	28-MAY-80
;		REPLACE ALL OUTADR CALLS WITH TOCT LSTADR'S.
;
;  50	JGZ	31-MAY-80
;		ADD DISK ADDRESS TYPEOUT TO ABORTS FOR SEARCH AND VERIFY.
;		FINISH UP SEARCH COMMAND EXCEPT FOR GOOD OCTAL INPUT.
;		CONVERT VERIFY COMMAND TO USE SCAN LOOP.  MAKE A FEW OTHER
;		ROUTINES USE RPTERR ROUTINE.
;
;  51	JGZ	2-JUN-80
;		FINISH UP SEARCH COMMAND BY DOING A HALFWORD OCTAL PARSE
;		FOR THE PATTERN AND MASK TO GET AROUND COMND'S COMPLAINT
;		ABOUT OVERFLOW.  CHANGE PARSE OPDEF AND HAVE A NEW ROUTINE
;		WHICH RETURNS ON COMND NOPARSE ERRORS.
;
;  52	JGZ	2-JUN-80
;		STRIP OUT THE GUTS OF THE DRIVE COMMAND INTO SUBROUTINE
;		GETCKU TO USE WHEN WE DO THE DEFINE COMMAND.
;
;  53	JGZ	2-JUN-80
;		STIR THE MUCK OF COMMAND PARSING AGAIN, MAKE LOSE "RETURN"
;		TO THE REPARSE ADDRESS-1 TO FACILITATE SUBCOMMANDS.  DO THE
;		DEFINE COMMAND TO IMPLEMENT MULTI-UNIT PHYSICAL ADDRESSING
;		STRUCTURES.
;
;  54	JGZ	4-JUN-80
;		MAKE DECUUO/TDECUU DO A BOUT INSTEAD OF A PRINT SO THAT
;		OUTPUT FILE DOESN'T COLLECT RANDOM "."'S FROM CONTROL-A
;		AND SUCH.
;
;  55	JGZ	8-JUN-80
;		CORRECT THE WAY SCAN SINGLE STEPS OVER A "BAD" REGION,
;		IT WAS CALLING MRDCHK AFTER EACH SINGLE PAGE.  HAVE
;		SCAN GIVE AN ERROR IF BEGADR IS GT MAX ALLOWED.
;
;  56	JGZ	8-JUN-80
;		FINISH UP VERIFY SWAPPING SPACE, DON'T CLEAR ERRCNT IN SCAN,
;		CLEAR ERRCNT BEFORE SCAN CALLS WHERE APPROPRIATE.
;
;  57	JGZ	8-JUN-80
;		ADD TSPACE AND PSPACE UUOS TO OUTPUT THE EFFECTIVE ADDRESS
;		NUMBER OF SPACES.  THEN CAN REPLACE A FEW SOUT'S AND CALLS
;		TO SPACEN AND REMOVE SPACEN.
;
;  60	JGZ	9-JUN-80
;		PUT TRIALS COUNTER INTO CHECK PAGE, AND PRINT IT OUT.
;
;  61	JGZ	9-JUN-80
;		OUTPUT PAGE DUMP EVEN IF PAGE IS "UNREADABLE" - WE MIGHT HAVE
;		GOTTEN SOMETHING USEFUL INTO CORE.
;
;  62	JGZ	13-JUN-80
;		IMPLEMENT COPY DIRECTORY COMMAND FOR THE CRUDE CASE WHERE
;		THE FULL SCAN IS DONE.  ADD OPTIMIZATIONS LIKE REUSING
;		DIRMAP LATER.
;
;  63	JGZ	13-JUN-80
;		IMPLEMENT DIRLIM TO HOLD THE PAGE LIMIT FOR THE DIRECTORY,
;		CLEAR AND SET IT FROM THE PAGE ZERO SYMBOL TABLE END POINTER.
;		HANDLE THE CASE OF DUPLICATE NAME STRINGS HAVING DIFFERENT
;		DIRECTORY NUMBERS.
;
;  64	JGZ	14-JUN-80
;		ADD CODE AT DIRCPC TO HANDLE THE CASE OF AN ALREADY BUILT
;		DIRMAP.  HANDLE ABORT CONDITION BETTER.
;
;  65	JGZ	15-JUN-80
;		MAKE DUMP HOMEBLOCKS AND DUMP BATBLOCKS WORK WITH DEFINED
;		STRUCTURES, REMOVE A FEW UNITSZ REFERENCES.
;
;  66	JGZ	25-JUN-80
;		CHANGE HOMAPR TO HOMSER EVERYWHERE.
;
;  67	JGZ	26-JUN-80
;		CHANGE SPACING IN STSINT.
;
;  70	JGZ	28-JUN-80
;		ADD ROUGH PAGES/SECOND CALCULATION TO VERIFY SUMMATION LINE
;		MAKE NPGS INTO NRPGS FOR LATER ADAPTIVE NUMBER CHOOSING...
;
;  71	JGZ	28-JUN-80
;		TELL ABOUT DIRECTORY PAGES AS THEY ARE COLLECTED IN THE
;		COPY DIRECTORY CODE.
;
;  72	JGZ	29-JUN-80
;		ADD SDB ENTRY SDBSPC FOR SECTORS/CYLINDER, CHANGE A FEW
;		PLACES TO USE IT, HAVE UNTINF RETURN IT IN T4.
;
;  73	JGZ	29-JUN-80
;		CHANGE SCAN CODE TO CHECK FOR CYLINDER OVERRUN AND DO LESS
;		PAGES FOR THAT CASE TO LOWER PERCENTAGE OF SINGLE PAGE
;		READS DONE.
;
;  74	JGZ	29-JUN-80
;		"INTELLIGENT" SUPPRESSION OF ZEROS IN DUMP PAGE COMMAND.
;
;  75	JGZ	6-JUL-80
;		CHANGE FORMAT OF DUMP INDEX NUMBER OF PAGES MESSAGE.
;		HAVE NON-ADDRESS CHECK KNOW ABOUT XBBAT BIT.
;

;  76	JGZ	6-JUL-80
;		FIX BROKEN COPY LONG-FILE COMMAND.  IT FORGOT TO COPY THE
;		SXB ADDRESS BACK TO T1 FOR RDCHK.
;
;  77	JGZ	7-JUL-80
;		CONVERT SVFLGS CONSTRUCT TO SAVSDB TO SAVE ALL SDB AND
;		FLAGS FOR FILE COMMANDS.
;
; 100	JGZ	11-JUL-80
;		FIX BUG FOR CASE WHERE BAT BLOCK HAS OVERFLOWED.
;
; 101	JGZ	13-JUL-80
;		MOVE CALL TO CKUINI AND WARN ON CKU FORMAT NOT AVAILABLE.
;
; 102	JGZ	29-JUL-80
;		MAKE SURE DRIVE COMMAND SETS SDBSPC.
;
; 103	JGZ	31-JUL-80
;		MOVE CRLF IN RPTERR TO END OF LINE.
;
; 104	JGZ	2-AUG-80
;		BE SURE TO CLEAR JFNTMP IN COPY COMMAND.
;
; 105	JGZ	22-AUG-80
;		MAKE SURE UUOS ARE AVAILABLE EARLY FOR CKUINI.
;
; 106	JGZ	3-DEC-80
;		FIX COMMAND SCANNER PROBLEM WITH OUTPUT FILE AND ERRORS.
;		DON'T CLEAR OJFN ON REEN ERRORS, AND REORDER OPEN AND
;		CLOSE IN CMDOUT.
;
; 107	JGZ	15-DEC-80
;		ADD WATCH COMMAND TO WATCH DISK ADDRESS WORD FOR CHANGES.
;
; 110	JGZ	15-DEC-80
;		IMPROVE HELP TEXTS ON MOST DISK ADDRESS PARSE BLOCKS.
;
; 111	JGZ	15-DEC-80
;		IN PREPARATION FOR VERSION 3, CHANGE COMMAND ROUTINE NAMES
;		TO FOLLOW THE ."NAME" STANDARD.
;
; 112	JGZ	14-JAN-80
;		SOME LISTING CLEANUPS IN ORDER TO FREEZE VERSION 2.
;
	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	SAVSDB,<
	JSP	CX,.SVSDB		;;MACRO FOR SAVING SDB, FLAGS
>
	OPDEF	CONFRM	[CALL	DOCNFM]	;COMND CONFIRN FUNCTION

	OPDEF	PARSE	[CALL	DOPARS]	;MAKE THE COMND CALL

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

	OPDEF	PRINT.	[1B8]		;PRINT LUUO
	OPDEF	TYPE.	[2B8]		;TYPE LUUO
	OPDEF	WARN.	[3B8]		;WARN LUUO
	OPDEF	ERROR.	[4B8]		;ERROR LUUO
	OPDEF	OCTOU.	[5B8]		;OCTAL OUTPUT LUUO
	OPDEF	DECOU.	[6B8]		;DECIMAL OUTPUT LUUO
	OPDEF	TOCT.	[7B8]		;OCTAL OUTPUT LUUO FOR .PRIOU
	OPDEF	TDEC.	[10B8]		;DECIMAL OUTPUT LUUO FOR .PRIOU
	OPDEF	TSPAC.	[11B8]		;TYPE SPACES LUUO
	OPDEF	PSPAC.	[12B8]		;PRINT SPACES LUUO

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

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

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

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

	DEFINE	OCTOUT(VALUE,SIZE),<	;;MACRO FOR CALLING OCTOUT LUUO
	IFB <SIZE>,<	OCTOU.	0,VALUE>
	IFNB <SIZE>,<	OCTOU.	SIZE,VALUE>
>
	DEFINE	DECOUT(VALUE,SIZE),<	;;MACRO FOR CALLING DECOUT LUUO
	IFB <SIZE>,<	DECOU.	0,VALUE>
	IFNB <SIZE>,<	DECOU.	SIZE,VALUE>
>
	DEFINE	TOCT(VALUE,SIZE),<	;;MACRO FOR CALLING TOCT LUUO
	IFB <SIZE>,<	TOCT.	0,VALUE>
	IFNB <SIZE>,<	TOCT.	SIZE,VALUE>
>
	DEFINE	TDEC(VALUE,SIZE),<	;;MACRO FOR CALLING TDEC LUUO
	IFB <SIZE>,<	TDEC.	0,VALUE>
	IFNB <SIZE>,<	TDEC.	SIZE,VALUE>
>
	DEFINE	TSPACE(VALUE),<TSPAC.	VALUE>	;;MACRO FOR CALLING TSPACE UUO

	DEFINE	PSPACE(VALUE),<PSPAC.	VALUE>	;;MACRO FOR CALLING PSPACE UUO


	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
	MXUNIT==30		;MAXIMUM UNITS WE ARE BUILT FOR
	NPGS==^D8		;NUMBER OF PAGES FOR MRDCHK CALLS



;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
	FL%ZRO==1B5		;ZERO SUPPRESSION FLAG FOR DUMP PAGE

	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==17,,777777	;MASK FOR A DISK ADDRESS
	XBBWRD==4		;OFFSET INTO INDEX BLOCK FOR BAT BIT
	XBBAT==1B0		;BAT BIT IN INDEX BLOCK
	DSKAB==10,,0		;DISK ADDRESS BIT


;PAGE AND DISK BLOCK VARIABLES

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

	SXBPAG==500000		;PAGE ADDRESS FOR SUPER INDEX BLOCKS
	XBPAG==501000		;PAGE FOR INDEX BLOCKS
	DATPAG==502000		;PAGES FOR DATA DSKOPS
	DIRMAP==600000		;SPACE FOR COPY DIRECTORY TABLE
	   DIRMXP==PGSIZ*40	;LIMIT TO DIRMAP SIZE

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

	BAT1AD==HOM2AD+HBLEN	;PRIMARY 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
	HOMSER==164		;APR SERIAL NUMBER FOR BOOT
	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

	DIRCOD==400300		;CODE IN LH OF WORD 0 OF DIRECTORY PAGES
	.DRSTP==4		;END OF SYMBOL TABLE WORD IN PAGE ZERO
	.DRNAM==15		;NAME POINTER WORD IN DIRECTORY PAGE ZERO

;*** CKU FORMAT DSKOP SYMBOLS, HERE UNTIL GENERALLY AVAILABLE IN MONSYM ***
;*** RP20 SYMBOLS AND RP08 SYMBOLS UNTIL GENERALLY AVAILABLE IN MONSYM  ***

IFNDEF DOP%NF,<DOP%NF==1B9>	;NEW FORMAT DSKOP BIT FOR T2
IFNDEF DOP%C2,<DOP%C2==7777B11>	;CHANNEL FIELD IN T4
IFNDEF DOP%K2,<DOP%K2==7777B23>	;CONTROLLER FIELD IN T4
IFNDEF DOP%U2,<DOP%U2==7777B35>	;UNIT FIELD IN T4

IFNDEF .MSR20,<.MSR20==24>	;RP20 UNIT TYPE CODE
IFNDEF .MSRP8,<.MSRP8==10>	;RP08 UNIT TYPE CODE
	SUBTTL	ENTRY VECTOR AND INITIALIZATION

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



DS:	RESET			;CLEAR EVERYTHING
	SETZ	F,		;CLEAR ALL FLAGS
	TMSG	<DS Disk Utility Program %>	;TYPE BANNER AND VERSION
	MOVE	P,[IOWD	PDLSIZ,PDL] ;SETUP A STACK
	MOVE	T1,[CALL UUOH]	;SET UP THE
	MOVEM	T1,.JB41##	;LUUO SYSTEM
	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
	CALL	CKUINI		;SEE IF WE CAN DO CKU FORMAT DSKOPS
	SKIPN	CKUFLG		;CAN WE USE CKU FORMAT DSKOPS?
	WARN	CKU format DSKOPs are not available
	SETZM	OJFN		;CLEAR OUTPUT JFN

REEN:	MOVE	P,[IOWD PDLSIZ,PDL]	;SET UP A STACK
	SETZM	TAKJFN		;CLEAR TAKE FILE JFN/STATE
	SETOM	DIRCKU		;INIT DIRECTORY MAP TABLE
	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:	HRROI	T1,[ASCIZ/DS>/]	;SET PROMPT
	MOVEM	T1,CMDBLK+.CMRTY ;IN COMND BLOCK
	MOVEI	T1,NEWPAR	;AND SET THE
	HRRM	T1,CMDBLK+.CMFLG ;REPARSE ADDRESS ALSO
	MOVEI	T2,[FLDDB. .CMINI]	;INITIALIZATION FUNCTION
	PARSE			;GO DO IT
	MOVEM	P,SAVEP		;SAVE STACK FOR REPARSING
	JRST	NEWPAR		;AND PARSE A NEW COMMAND

PARERR:	JRST	REEN		;REPARSE ADR-1=WHERE TO GO ON ERROR
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,.CHECK		;CHECK COMMANDS
	AA	COPY,.COPY		;COPY COMMAND
	AA	DEFINE,.DEFINE		;DEFINE STRUCTURE FOR PHYSICAL USE
	AA	DRIVE,.DRIVE		;SPECIFY DRIVE TO USE
	AA	DUMP,.DUMP		;DUMP COMMANDS
	AA	EXIT,.EXIT		;EXIT COMMAND
	AA	FILDDT,.FILDDT		;GET FILDDT IN A LOWER FORK
	AA	HELP,.HELP		;TYPE HELP MESSAGE
	AA	INFORMATION,.INFORMATION ;INFORMATION ABOUT DISK UNITS
	AA	OUTPUT,.OUTPUT		;SPECIFY OUTPUT JFN
	AA	PUSH,.PUSH		;PUSH TO A NEW EXEC
	AA	SEARCH,.SEARCH		;SEARCH FOR PATTERN
	AA	STRUCTURE,.STRUCTURE	;SPECIFY STRUCTURE TO USE
	AA	TAKE,.TAKE		;TAKE COMMANDS FROM FILE
	AA	VERIFY,.VERIFY		;VERIFY PACK BY DSKOP READS
	AA	WATCH,.WATCH		;WATCH DISK ADDRESS

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

;EXIT FROM PROGRAM.  "EXIT" COMMAND.


.EXIT:	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.


.HELP:	NOISE	(WITH COMMANDS)	;DO GUIDEWORDS
	CONFRM			;CONFIRM THE LINE
	MOVX	T1,GJ%OLD+GJ%SHT ;GET THE HELP FILE
	HRROI	T2,[ASCIZ/HLP:DS.HLP/] ;FROM HLP:
	GTJFN
	 ERJMP [WARN	Cannot find HLP:DS.HLP
		RET]		;SAY WE'RE SORRY
	MOVEM	T1,HLPJFN	;SAVE THE JFN
	MOVX	T2,FLD(7,OF%BSZ)+OF%RD ;READ IN ASCII
	OPENF			;OPEN THE HELP FILE
	 ERJMP [WARN	Cannot open HLP:DS.HLP
		MOVE	T1,HLPJFN ;RELEASE
		RLJFN		;JFN ON FILE
		 ERJMP	.+1
		RET]		;SORRY
HLPLUP:	MOVE	T1,HLPJFN	;HELP FILE JFN
	BIN			;INPUT A BYTE
	 ERJMP [GTSTS		;FIND OUT ERROR REASON
		TXNN	T2,GS%EOF ;END OF FILE?
		JRST	LOSE	;NO - REAL ERROR
		CLOSF		;YES, CLOSE FILE
		 ERJMP	.+1	;IGNORE THIS ERROR
		RET]		;DONE WITH COMMAND
	MOVEI	T1,.PRIOU	;OUTPUT TO TERMINAL
	BOUT			;SEND THE BYTE
	 ERJMP	LOSE
	JRST	HLPLUP		;LOOP TIL DONE
	SUBTTL	FILDDT AND PUSH COMMANDS

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

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



;FILDDT COMMAND TO PUSH TO FILDDT IN AN INFERIOR FORK

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


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

.TAKE:	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,FLD(7,OF%BSZ)+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.

.OUTPUT: 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
	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	;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]
	MOVEM	T1,OJFN		;STORE 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 SDBCKU FOR DSKOPS
;AND THE FL%PHY BIT IS SET TO INDICATE THAT WE ARE PROCESSING ON A UNIT,
;NOT A STRUCTURE BASIS WHERE APPROPRIATE.

.DRIVE:	CALL	GETCKU		;PARSE THE VALUE
	MOVEM	T1,SDBCKU	;AND STORE IN SDBCKU WORD
	MOVEM	T2,SDBSIZ	;AND SET SDB VALUE FOR SIZE
	MOVEM	T3,SDBSPP	;AND SECTORS PER PAGE
	MOVEM	T4,SDBSPC	;AND SECTORS PER CYLINDER
	MOVEI	T3,1		;SINGLE UNIT
	MOVEM	T3,SDBCNT	;SET COUNT IN SDB
	TXO	F,FL%PHY+FL%SUS	;AND FINALLY SET THE PHYSICAL ADDRESSES BIT
	RET			;THEN RETURN
	SUBTTL	DEFINE COMMAND TO BUILD MULTI-UNIT SDB

;THE DEFINE COMMAND COMES HERE TO BUILD AN SDB FOR ADDRESSING
;A MULTI-UNIT PHYSICAL STRUCTURE.  WE GO INTO A SUB-COMMAND
;MODE TO PICK UP ALL OF THE UNITS IN THE "STRUCTURE".

.DEFINE: NOISE	(PHYSICAL ADDRESSING STRUCTURE) ;GUIDEWORDS
	CONFRM			;CONFIRM THE INTENTION
	SETZM	SDBTMP		;CLEAR TEMP AREA COUNTER
	SETZM	SDBTMP+1	;AND CONSISTENCY WORD
	MOVEM	P,SAVEP1	;SAVE STACK BEFORE GETTING CRAZY
PARDEF:	MOVE	P,SAVEP1	;NORMALIZE STACK FOR REPARSES...
	MOVEI	T1,DEFPAR	;SET NEW COMND REPARSE
	HRRM	T1,CMDBLK+.CMFLG ;ROUTINE ADDRESS
	HRROI	T1,[ASCIZ/DS-DEFINE>>/]
	MOVEM	T1,CMDBLK+.CMRTY ;AND SET NEW PROMPT
	MOVEI	T2,[FLDDB. (.CMINI)]
	PARSE			;FORCE OUT THE PROMPT...
	MOVEM	P,SAVEP2	;SAVE STACK...
	JRST	DEFPAR		;PARSE A SUBCOMMAND

	JRST	PARDEF		;WHERE TO GO ON ERROR ADR=REPARSE-1
DEFPAR:	MOVE	P,SAVEP2	;RESTORE THE STACK...
	MOVEI	T2,[FLDDB. (.CMKEY,,DEFTAB)]
	PARSE			;PARSE A SUBCOMMAND KEYWORD
	MOVE	T2,0(T2)	;FETCH ROUTINE ADDRESS
	CALL	0(T2)		;CALL THE ROUTINE
	JRST	PARDEF		;LOOP FOR ANOTHER


DEFTAB:	DEFTBL,,DEFTBL
	AA	ABORT,DEFABT	;ABORT
	AA	DONE,DEFDON	;DONE
	AA	UNIT,DEFUNT	;GIVE UNIT
	DEFTBL==.-DEFTAB-1
;HERE TO ABORT THIS COMMAND

DEFABT:	NOISE	(THIS COMMAND)	;GUIDE
	CONFRM			;CONFIRM
	POP	P,T1		;REMOVE A STACK LEVEL
	RET			;AND RETURN TO OUR CALLER'S CALLER

;HERE WHEN WE ARE FINISHED AND WANT TO SET THE SDB UP FROM SDBTMP

DEFDON:	NOISE	(WITH DEFINITION)	
	CONFRM			;CONFIRM THE INTENT
	SKIPN	T1,SDBTMP	;GET THE COUNT
	 ERROR	No units given
	TXO	F,FL%SUS!FL%PHY	;SET THE PHYSICAL ADDRESSING FLAGS
	MOVEM	T1,SDBCNT	;SET COUNT IN SDB
	MOVN	T1,T1		;NEGATE
	HRLZ	T1,T1		;AND MAKE AOBJN POINTER
DEFDO1:	MOVE	T2,SDBTMP+2(T1)	;GET CKU
	MOVEM	T2,SDBCKU(T1)	;PUT IN SDB
	AOBJN	T1,DEFDO1	;LOOP
	MOVE	T1,SDBCKU	;GET A CKU WORD **NOTE** ASSUMES ALL UNITS
	CALL	UNTINF		; ARE OF THE SAME TYPE!
	MOVEM	T2,SDBSIZ	;STORE THE SIZE
	MOVEM	T3,SDBSPP	;AND SECTORS/PAGE
	MOVEM	T4,SDBSPC	;AND SECTORS/CYLINDER
	POP	P,T1		;POP OFF OUR RETURN ADDRESS
	RET			;AND RETURN TO OUR CALLER'S CALLER


;HERE TO SPECIFY A NEW UNIT

DEFUNT:	CALL	GETCKU		;PARSE THE CKU WORD
	SKIPN	T3,SDBTMP	;FETCH CURRENT COUNT
	 JRST	DEFUN1		;NOT A PROBLEM
	CAMN	T1,SDBTMP+2(T3)	;ALREADY GIVEN?
	 ERROR	Duplicate unit given
	SOJG	T3,.-2		;TRY ALL GIVEN

DEFUN1:	AOS	T3,SDBTMP	;BUMP THE COUNT
	CAIL	T3,MXUNIT	;SANITY CHECK
	 ERROR	Too many units given
	SKIPN	SDBTMP+1	;IF CONSISTENCY NOT SET YET
	MOVEM	T2,SDBTMP+1	;SET SIZE IN IT
	CAME	T2,SDBTMP+1	;IS THIS UNIT CONSISTENT WITH THE OTHERS?
	 ERROR	All units must be of the same type
	MOVEM	T1,SDBTMP+1(T3)	;STORE CKU WORD IN RIGHT PLACE
	RET			;AND DONE HERE
	SUBTTL	GETCKU - ROUTINE TO READ CHANNEL, CONTROLLER, UNIT

;GETCKU - ROUTINE TO PARSE CHANNEL, CONTROLLER, UNIT INFO
;
;	CALL	GETCKU
;
;RETURNS  +1:	ALWAYS (UNLESS NOPARSE)
;		T1/	CKU FORMAT WORD
;		T2/	UNIT SIZE IN SECTORS
;		T3/	SECTORS/PAGE
;
;USES T1-T4,P1.  CONFIRMS LINE AND OUTPUTS UNIT STATUS LINE

GETCKU:	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%C2,P1	;STORE IN SDBCKU FIELD IN P1
	NOISE	(CONTROLLER)	;GUIDEWORDS
	MOVEI	T2,[FLDDB. (.CMNUM,CM%SDH,^D8,<Controller number or -1>,<-1>)]
	PARSE			;PARSE THE CONTROLLER
	STOR	T2,DOP%K2,P1	;STORE IN SDBCKU 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,^D1024	; REASONABLENESS CHECK OF SOME SORT
	 ERROR	Unit number out of range
	STOR	T2,DOP%U2,P1	;STORE IN SDBCKU FIELD IN P1
	CONFRM			;CONFIRM THE LINE
	MOVE	T1,P1		;GET UNTINF ARGUMENT
	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
	MOVE	T1,P1		;RETURN CKU WORD IN T1
	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 SDBDES AND THE FLAG FL%PHY IS CLEARED TO INDICATE THAT
;STRUCTURE RELATIVE ADDRESSING IS USED.


.STRUCTURE: 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,SDBDES	;SAVE DESIGNATOR
	CALL	STRINF		;SET THE STRUCTURE PARAMETERS IN THE SDB
	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...)

.INFORMATION: 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
	PSPACE	0(T3)		;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
	PSPACE	0(T3)		;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
	MOVSI	T4,-MXUTYP	;AOBJN POINTER
	HLRZ	T3,UNTYTB(T4)	;GET TYPE FROM LH OF TABLE
	CAME	T2,T3		;MATCH?
	AOBJN	T4,.-2		;NO
	HRRO	T2,UNTYTB(T4)	;FETCH POINTER (MXUTYP+1 POINTS TO "UNK")
	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:	.MSRP4,,[ASCIZ "RP04"]	;1 - RP04
	.MSRP5,,[ASCIZ "RP05"]	;5 - RP05
	.MSRP6,,[ASCIZ "RP06"]	;6 - RP06
	.MSRP7,,[ASCIZ "RP07"]	;7 - RP07
	.MSRP8,,[ASCIZ "RP08"]	;10 - RP08 (IF EVER)
	.MSRM3,,[ASCIZ "RM03"]	;11 - RM03
	.MSR20,,[ASCIZ "RP20"]	;24 - RP20

	MXUTYP==.-UNTYTB-1	;SIZE OF TABLE

	-1,,[ASCIZ "UNK "]	;NO MATCH TO THE ABOVE
	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.


.DUMP:	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,CM%SDH,^D8,<octal disk address>)]
	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:	SETZM	DATPAG		;TO GET THE BEST RESULTS,
	MOVE	T2,[DATPAG,,DATPAG+1] ;CLEAR INPUT PAGE TO KNOWN STATE
	BLT	T2,DATPAG+PGSIZ-1 ;WITH BLT
	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...

	CALL	RPTERR		;REPORT ANY ERRORS

;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
	TXZ	F,FL%TMP	;CLEAR CROCK FLAG

	;...
PAGDML:	SKIPN	DATPAG(P1)	;SEE IF ZERO
	 JRST [	TXNE	F,FL%ZRO	;ZERO, CHECK FLAG
		JRST	PAGDMX		;SET, SKIP THIS ONE
		SKIPE	DATPAG+1(P1)	;CHECK NEXT WORD
		JRST	.+1		;NONZERO FOLLOWS, GO INLINE
		TXO	F,FL%ZRO	;HAVE MULTIPLE ZEROS
		JRST	PAGDMX]		;TO SKIP
	TXON	F,FL%TMP	;GOING TO OUTPUT SOMETHING, REMEMBER, AND
	PRINT	<
Address	       Octal   SIXBIT	   L-ASCII	R-ASCII	  11-ASCII
>				;DO HEADER IF HAVEN'T YET
	TXZE	F,FL%ZRO	;CLEAR FLAG AND
	PRINT	<
>				;DO EXTRA CRLF IF NEEDED
	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	;OUTPUT ANTHING
	PRINT	<
% Entire page is zero
>
	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:	SAVSDB			;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,SDBDES	;STORE DESIGNATOR
	LOAD	T2,DV%TYP,T2	;FETCH DEVICE TYPE FIELD
	CAIE	T2,.DVDSK	;DISK?
	 ERROR	File is not on a disk device
	CALL	STRINF		;SET UP FOR THE STRUCTURE
	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
		MOVX	T1,FB%OFF ;OFF-LINE BIT
		TDNE	T1,FDBBLK+.FBCTL ;TEST FOR IT
		WARN	File is off-line
		RET]		;GO NO FURTHER WITH THIS ONE
	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:
;  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	<

Pages in use by this Index Block: >
	DECOUT	P2,3		;DECIMAL COUNT OF USED PAGES
	PRINT	<
>				;END LINE
	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:	TXNN	F,FL%PHY	;UNIT OR STRUCTURE?
	CALL	STRINF		;GATHER THE STRUCTURE INFO
	MOVN	P2,SDBCNT	;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:	ADD	P1,SDBSIZ	;UPDATE OFFSET BY UNIT SIZE IN SECTORS
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	<
164   HOMSER   APR serial number for BOOT:  >
	DECOUT	HOM1AD+HOMSER	;DECIMAL SERIAL NUMBER
	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:	TXNN	F,FL%PHY	;UNIT OR STRUCTURE?
	CALL	STRINF		;STRUCTURE.  GET THE INFO SET UP
	SETZ	P1,		;START WITH FIRST UNIT
	MOVN	P2,SDBCNT	;GET NUMBER OF LOGICAL UNITS
	HRLZ	P2,P2		;-N,,0
	JRST	BATST1		;ENTER PAST OFFSET CALCULATION
BATSTR:	ADD	P1,SDBSIZ	;UPDATE OFFSET BY THE UNIT SIZE IN SECTORS
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		; AND OUTPUT
	PRINT	<  Total:  >	;AND ADD THEM UP
	ADD	T1,T2		;TO T1
	DECOUT	T1		;OUTPUT
	CAILE	T1,MAXBFR/2	;OVERFLOW?
	PRINT	<
% BAT Block has overflowed>	;yES, SAY SO NOW
	JUMPE	T1,R		;IF NO REGIONS, DONE HERE
	PRINT	<
Unit-Address	Size(Sectors)	APR number	Channel	Unit>
	CAILE	T1,MAXBFR/2	;OVERFLOW?
	MOVEI	T1,MAXBFR/2	;YUP, JUST DO MAX
	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		;SDBSPP 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 >
	TOCT	LSTADR		;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,SDBSPP	;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,SDBSPP	;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,SDBSPP	;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.

.CHECK:	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
;CHEPAG - CHECK PAGE AT SPECIFIED DISK ADDRESS
;BASICALLY JUST CALLS RDCHK AFTER FINISHING COMMAND PARSE.

CHEPAG:	NOISE	(AT DISK ADDRESS)	;DO GUIDEWORDS
	MOVEI	T2,[FLDDB. (.CMNUM,CM%SDH,^D8,<octal disk address>)]
	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
	SETZB	P3,ERRCNT	;CLEAR TRIAL AND ERROR COUNTERS
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	ERRCNT		;COUNT THE ERROR
	CALL	RPTERR		;REPORT THE ERROR
CHEPGE:	AOS	P3		;COUNT TRIAL
	SOJG	P2,CHEPGL	;LOOP TIL DONE
	CALL	CLRABT		;CLEAR THE INTERRUPT STUFF
CHEPGX:	PRINT	<
[ >				;GIVE ERROR COUNT
	DECOUT	ERRCNT		;FROM P3
	PRINT	< errors counted in >
	DECOUT	P3		;COUNTS
	PRINT	< trials ]
>				;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,CM%SDH,^D8,<octal disk address>)]
	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
	CALL	RPTERR		;TYPE 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-5>	;ALL BUT CHECKSUM WORDS AND XBBAT WORD
CHEIDL:	MOVE	T1,XBPAG+5(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:  >
	TDEC	P4		;DECIMAL ERROR COUNT
	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:	SAVSDB			;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,SDBDES	;STORE DESIGNATOR
	LOAD	T2,DV%TYP,T2	;FETCH DEVICE TYPE FIELD
	CAIE	T2,.DVDSK	;DISK?
	 ERROR	File is not on a disk device
	CALL	STRINF		;SETUP SDB
	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
		MOVX	T1,FB%OFF ;OFF-LINE BIT
		TDNE	T1,FDBBLK+.FBCTL ;TEST FOR IT
		WARN	File is off-line
		TDNN	T1,FDBBLK+.FBCTL ;TEST FOR IT
		AOS	P4	;COUNT ERROR
		RET]		;GO NO FURTHER WITH THIS ONE
	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>
		TOCT	LSTADR		;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
	HRRZ	T2,P2		;OUTPUT THE INDEX BLOCK NUMBER
	TOCT	T2		;DO IT IN OCTAL
	TYPE	< disk address >;AND DO DISK ADDRESS
	TOCT	LSTADR		;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
	CAIE	T1,.DSHRD	;IF UNREADABLE OR
	TXNE	F,DS%CHK	; IF BAD INDEX BLOCK CHECKSUM 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
	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 #
	TOCT	T2		;OUTPUT IN OCTAL TO TERMINAL
	TYPE	< disk address >;AND DO DISK ADDRESS
	TOCT	LSTADR		;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

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

.COPY:	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
	CAIN	T2,3		;DIRECTORY?
	JRST	DIRCPY		;YES, GO ELSEWHERE
	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,CM%SDH,^D8,<octal disk address>)]
	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
	MOVE	T1,P1		;COPY ADDRESS BACK 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 >
	HRRZ	T2,P2		;OUTPUT THE INDEX BLOCK
	TOCT	T2		;IN OCTAL TO THE TERMINAL
	TYPE	< disk address > ;AND DO DISK ADDRESS ALSO
	TOCT	LSTADR		;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
	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 #
	TOCT	T2		;TO THE TTY IN OCTAL
	TYPE	< disk address >;AND DO DISK ADDRESS
	TOCT	LSTADR		;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_<-PGSFT>] ;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	DIRECTORY,3	;SPECIAL DIRECTORY COPY
	AA	FILE,0		;NORMAL FILE
	AA	LONG-FILE,1	;LONG FILE
	AA	PAGE,2		;JUST GET PAGE
	CPYTBL==.-CPYTAB-1
	SUBTTL	COPY DIRECTORY COMMAND

;DIRCPY - HERE AFTER PARSING COPY DIRECTORY TO PARSE REST OF COMMAND
;AND DO THE DIRECTORY SEARCH AND COPY.

DIRCPY:	NOISE	(WITH NAME)	;GUIDE
	MOVEI	T2,[FLDBK. (.CMFLD,CM%BRK!CM%SDH,,<directory name>,,[
		BRMSK. (USRB0.,USRB1.,USRB2.,USRB3.)])]
	PARSE			;TRY TO READ IT
	MOVE	T1,[ATMBUF,,DIRSTR] ;BLT POINTER
	BLT	T1,DIRSTR+7	;COPY THE STRING
	MOVEI	T2,[FLDDB. (.CMOFI)]
	NOISE	(TO)		;GUIDE ON
	MOVEI	T2,[FLDDB. (.CMOFI)]
	PARSE			;READ OUTPUT FILENAME
	MOVEM	T2,JFNTMP	;SAVE JFN TIL CONFIRMED
	CONFRM			;CONFIRM THE COMMAND
	CALL	CHKUSE		;SEE IF IT'S WORTH GOING ON
	MOVE	T1,JFNTMP	;FETCH THE COPY JFN
	MOVEM	T1,CJFN		;ESTABLISH IT
	SETZM	JFNTMP		; AND MARK THE TEMP SLOT CLEAR
	MOVX	T2,OF%WR	;TO WRITE ONLY
	OPENF			;OPEN THE FILE
	 ERJMP	LOSE

;INITIALIZE FOR ^E AND ^A INTERRUPTS AND BEGIN.

	MOVEI	T1,DIRABT	;ABORT ROUTINE ADDRESS
	CALL	SETABT		;AND SETUP FOR THE INTERRUPT
	MOVE	T1,[.TICCA,,STSCHN] ;ACTIVATE
	ATI			; STATUS ON ^A
	 ERJMP	LOSE
	MOVE	T1,SDBCKU	;SEE IF WE CAN TRY TO USE A
	CAMN	T1,DIRCKU	; DIRECTORY MAP ALREADY IN CORE
	 JRST	DIRCPC		;MAYBE, TRY TO FIND THE STRING

;HERE WE NEED TO MAKE THE FIRST PASS ON THE DISK TO FIND DIRECTORY PAGES

DIRCP0:	TYPE	<
[Beginning mapping scan for directory pages]
>				;LET IT BE KNOWN IT WILL TAKE A WHILE

	SETZM	DIRPTR		;RESET POINTER
	SETZM	DIRNUM		;NUMBER NOT FOUND YET
	DMOVE	T1,[EXP	0,-1]	;START TO END (**NOTE** LATER NO SWAPPING)
	MOVEI	T3,COCOPY	;COROUTINE ADDRESS
	SETZM	ERRCNT		;START WITH NO ERRORS
	CALL	SCAN		;MAKE THE SCAN
	MOVE	T1,SDBCKU	;MARK ID OF THIS MAPPING
	MOVEM	T1,DIRCKU	; IN CASE IT MIGHT PROVE USEFUL
	SKIPN	DIRNUM		;FOUND IT?
	 JRST [	WARN	Matching directory string not found
		JRST	DIRDON]	;GO

;NOW BUILD THE DIRECTORY FROM THE MAP...

DIRCPL:	MOVN	P1,DIRPTR	;-N
	HRLZ	P1,P1		;TO LH FOR AOBJN
	SETZM	LSTCPY		;SET LAST PAGE TO INITAL VALUE
DIRCL0:	HRRZ	T1,DIRMAP(P1)	;THIS DIRECTORY NUMBER
	CAME	T1,DIRNUM	;MATCH?
	JRST	DIRCLX		;NO, LOOP MORE

;HERE WE HAVE A POSSIBLE PAGE: WRITE IT IF NOT ALREADY THERE
;AND IN RANGE

	HLRZ	T1,DIRMAP(P1)	;PAGE NUMBER TO RH
	CAML	T1,DIRLIM	;PAGE OUT OF RANGE?
	 JRST [	WARN	<Directory page >
		TDEC	T1	;GIVE THE NUMBER
		TYPE	< at disk address >
		TOCT	DIRMAP+1(P1) ;DO ADDRESS
		TYPE	< rejected - beyond symbol table limit
>
		JRST	DIRCLX]	;AND LOOP SOME MORE
	HRL	T1,CJFN		;JFN TO LH
	RPACS			;SEE IF THE PAGE IS THERE
	 ERJMP	LOSE
	TXNE	T2,PA%PEX	;IS IT?
	 JRST [	WARN	<Duplicate to directory page >
		HLRZ	T1,DIRMAP(P1)	;PAGE NUMBER AGAIN
		TDEC	T1	;OUTPUT IT
		TYPE	< at disk address >
		TOCT	DIRMAP+1(P1) ;DO ADDRESS
		TYPE	<
>
		JRST	DIRCLX]	; AND LOOP
	PRINT	< Directory page >
	HLRZ	T1,DIRMAP(P1)	;GET DIR PAGE NUMBER
	DECOUT	T1		;PRINT IT
	PRINT	< found at disk address >
	OCTOUT	DIRMAP+1(P1)	;DO ADDRESS
	PRINT	<
>				;CRLF
	MOVX	T1,.DSDAT	;DATA PAGE
	STOR	T1,DS%TYP,F	;SET FIELD
	MOVE	T1,DIRMAP+1(P1)	;GET DISK ADDRESS
	CALL	RDCHK		;READ IN THE PAGE TO DATPAG
	SKIPE	T1		;SKIP IF NO ERRORS
	CALL	RPTERR		;BUT REPORT THOSE THAT ARE THERE
	MOVE	T1,[.FHSLF,,<DATPAG_-PGSFT>]
	HRLZ	T2,CJFN		;DESTINATION IS FILE
	HLR	T2,DIRMAP(P1)	;SPECIFIC PAGE
	MOVX	T3,PM%WR	;TO WRITE
	PMAP			;WRITE IT OUT
	 ERJMP	LOSE
	HLRZ	T1,DIRMAP(P1)	;PAGE AGAIN
	CAMLE	T1,LSTCPY	;LARGEST SO FAR?
	MOVEM	T1,LSTCPY	;YES, REMEMBER FOR EOF SETTING
DIRCLX:	AOS	P1		;HANDLE 2 WORD ENTRY AND
	AOBJN	P1,DIRCL0	;LOOP TIL DONE


;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 DIRECTORY completed]>

;	JRST	DIRDON		;AND FINISH IT OFF



;HERE WHEN SCAN COMPLETE OR ON ABORT TO CLEAN UP

DIRDON:	CALL	CLRABT		;MAKE SURE CONTROL-E TURNED OFF
	MOVX	T1,.TICCA	;DISABLE ALSO THE
	DTI			; STATUS INTERRUPT
	 ERJMP	LOSE
	RET			;RETURN


;DEBRK OF ^E INTERRUPT TRANSFERS CONTROL HERE TO FINISH THE ABORT

DIRABT:	MOVEI	T1,.PRIOU	;PRESUME TO CLEAR
	CFOBF			; THE OUTPUT
	 ERJMP	LOSE
	WARN	<Directory mapping pass aborted at disk address >
	TOCT	LSTADR		;GIVE THE ADDRESS
	MOVE	T1,CJFN		;FLUSH THE COPY OUTPUT FILE
	TXO	T1,CZ%ABT	; WITH AN ABORT CLOSE
	CLOSF			; TO KEEP THEM FROM PILING UP
	 ERJMP	LOSE
	MOVE	P,SAVPSI	;RE-ADJUST STACK TO KNOWN POINT
	JRST	DIRDON		;AND CLOSE OUT THE COMMAND




;SCAN COROUTINE FOR THE COPY DIRECTORY COMMAND

COCOPY:	CAIN	T1,.DSHRD	;REAL TOUGH LUCK ON READ?
	 RET			;YES, IGNORE PAGE

COCOP0:	HLRZ	T1,0(T2)	;FETCH FIRST WORD OF PAGE
	CAIN	T1,DIRCOD	;POSSIBLE DIRECTORY PAGE?
	CALL	MRKDIR		; YES, MARK IT
	ADD	T2,[PGSIZ,,PGSIZ] ;STEP TO NEXT PAGE
	JUMPL	T2,COCOP0	;AND LOOP IF MORE TO DO
	RET			;RETURN TO READ MORE

MRKDIR:	MOVE	T1,DIRPTR	;ALLOCATE AN ENTRY
	CAIL	T1,DIRMXP	;CHECK HOW FULL
	 ERROR	Too many directory pages for table space
	MOVE	T3,LSTADR	;START OF BUFFER
	MOVEM	T3,DIRMAP+1(T1)	;SAVE DISK ADDRESS
	HRRZ	T3,T2		;COPY BUFFER ADDRESS OF PAGE START
	SUBI	T3,DATPAG	;SUBTRACT ORIGIN
	LSH	T3,-PGSFT	;MAKE PAGE OFFSET
	IMUL	T3,SDBSPP	;CONVERT TO SECTORS
	ADDM	T3,DIRMAP+1(T1)	;AND UPDATE DISK ADDRESS FOR THIS PAGE
	MOVE	T3,1(T2)	;RELATIVE PAGE,,DIR NUMBER FROM DIRECTORY
	MOVEM	T3,DIRMAP(T1)	;SAVE IT IN FIRST WORD OF ENTRY
	TLNN	T3,-1		;RELATIVE PAGE ZERO?
	CALL	DIRCMP		;YES, DO MORE WORK
	MOVEI	T3,2		;TWO WORD ENTRIES
	ADDM	T3,DIRPTR	;UPDATE DIRPTR FOR THIS ONE
	RET			;RETURN
;HERE TO MAKE THE NAME STRING COMPARISON

DIRCMP:	SAVEAC	<T2>		;SAVE OUR POINTER ACROSS JSYS
	HRROI	T1,1(T2)	;-1,,PAGE ADDRESS+1 (IE PAST NAME HEADER)
	ADD	T1,.DRNAM(T2)	;ADD OFFSET IN PAGE FOR TEST STRING
	MOVE	T3,.DRSTP(T2)	;SAVE END OF SYMBOL TABLE INCASE OF MATCH
	HRROI	T2,DIRSTR	;POINT TO OUR OBJECT STRING
	STCMP			;COMPARE
	 ERJMP	LOSE
	JUMPN	T1,R		;RETURN IF NO MATCH
	MOVE	T1,DIRPTR	;POINTER
	SKIPE	DIRNUM		;FOUND ONE ALREADY?
	 JRST [	WARN	<Duplicate name string found at disk address >
		TOCT	DIRMAP+1(T1)
		TYPE	<
>				;CRLF
		RET]		;AND FORGET THE DUPLICATE
	MOVE	T2,DIRMAP(T1)	;PAGE,,DIR NUMBER WORD
	MOVEM	T2,DIRNUM	;REMEMBER
	ADDI	T3,PGSIZ-1	;ROUND UP TO THE NEXT PAGE
	LSH	T3,-PGSFT	;MAKE INTO A PAGE
	MOVEM	T3,DIRLIM	;AND SAVE AS THE LAST DIRECTORY PAGE+1
	RET			; AND RETURN NOW
;HERE WHEN THERE IS ALREADY A DIRMAP TO USE.  TRY TO FIND THE RIGHT
;DIRECTORY PAGE ZERO USING IT.

DIRCPC:	SETZM	DIRNUM		;MARK HAVEN'T FOUND IT YET
	SETZM	DIRLIM		;CLEAR LIMIT TOO...
	MOVN	P1,DIRPTR	;BUILD
	HRLZ	P1,P1		;AOBJN POINTER FOR DIRMAP
DIRCP3:	HLRZ	T1,DIRMAP(P1)	;FETCH RELATIVE PAGE NUMBER
	JUMPN	T1,DIRCPX	;IF ZERO, TRY IT
	MOVX	T1,.DSDAT	;DATA PAGE
	STOR	T1,DS%TYP,F	;STORE FOR RDCHK
	MOVE	T1,DIRMAP+1(P1)	;DISK ADDRESS
	CALL	RDCHK		;READ IN THE PAGE
	CAIN	T1,.DSHRD	;GET IT?
	 JRST	DIRCPX		;NO...
	MOVE	T2,[-PGSIZ,,DATPAG] ;LOAD POINTER
	EXCH	P1,DIRPTR	;**DIRCMP EXPECTS TO USE DIRPTR
	CALL	DIRCMP		;AND CALL COMPARE ROUTINE
	EXCH	P1,DIRPTR	;**RESTORE P1, DIRPTR
DIRCPX:	AOS	P1		; ELSE JUST LOOP
	AOBJN	P1,DIRCP3	; OVER ALL OF DIRMAP
	SKIPN	DIRNUM		;DID WE FIND ONE?
	 ERROR	<Could not find specified directory string>
	JRST	DIRCPL		;FOUND AT LEAST ONE, BUILD IT

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


.VERIFY: NOISE	(BEGINNING AT)	;GUIDE
	TXZ	F,FL%TMP	;CLEAR TEMP FLAG
	MOVEI	T2,[FLDDB. (.CMNUM,CM%SDH,^D8,<disk address>,<0>,[
		    FLDDB. (.CMKEY,,<[1,,1	;KEYWORD TABLE OF ONE
				 AA	(<SWAPPING-SPACE>,<0>)]>)])] ;ONLY ENTRY
	PARSE			;READ START
	TSC	T3,T3		;NUMBER OR SWAPPING?
	JUMPN	T3,[TXO	F,FL%TMP ;MARK AS SWAPPING
		    JRST CMDVE0] ;AND COMPLETE COMMAND
	MOVEM	T2,SRCBLK	;SAVE START ADDRESS
	NOISE	(AND ENDING AT)	;GUIDE MORE
	MOVEI	T2,[FLDDB. (.CMNUM,CM%SDH,^D8,<disk address, -1 for all>,<-1>)]
	PARSE			;READ END
	MOVEM	T2,SRCBLK+1	;SAVE END ADDRESS
CMDVE0:	CONFRM			;CONFIRM THE LINE
	SETZM	P2		;ASSUME NORMAL
	TXNE	F,FL%TMP	;SWAPPING SPACE?
	SETOM	P2		;YES, NOTE
	CALL	CHKUSE		;VERIFY USABILITY
	MOVN	P1,SDBCNT	;FETCH UNIT COUNT
	HRLZ	P1,P1		; AS AOBJN POINTER THROUGH SDBCKU
	SKIPN	P2		;SWAPPING?
	HRROS	P1		;NO, ONLY LOOP ONCE
	SETZM	ERRCNT		;START WITH ZERO ERROR COUNT

;GET THE APPROPRIATE STRUCTURE/UNIT INFORMATION

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

	CALL	STRINF		;STRUCTURE, GATHER INFO
CMDVES:	TYPE	<
[ Working on Structure > 	;GIVE FEEDBACK
	MOVEI	T1,.PRIOU
	MOVE	T2,SDBDES	;DESIGNATOR
	DEVST			;DO THE STRING
	 ERJMP	LOSE
	SKIPN	P2		;STOP SHORT IF NOT SWAPPING SPACE
	TYPE	<: ]
>				;CLOSE BRACKET
	SKIPE	P2		;BUT IF SWAPPING, GIVE PACK NUMBER
	 JRST [	HRRZ	T1,P1	;GET LOGICAL UNIT NUMBER TO T1
		TYPE	<:, Unit >
		TDEC	T1	;GIVE NUMBER
		TYPE	< ]
>				;CLOSE BRACKET
		JRST	.+1]	;CONTINUE IN LINE
	SKIPE	P2		;SWAPPING SPACE?
	CALL	SETSWP		;YES, SET UP ARGS IN SRCBLK
	CALL	CMDVE2		;DO A UNIT/STR
	AOBJN	P1,CMDVES	;FINISH ALL NEEDED
	JRST	VERDON		; AND DONE


;HERE FOR A PHYSICAL UNIT

CMDVE1:	MOVE	T1,SDBCKU(P1)	;PICK UP THE UNIT DESIGNATOR
	CALL	UNTINF		;GET THE UNIT INFO
	SKIPE	P2		;SWAPPING SPACE?
	CALL	SETSWP		;YES, SET UP ARGS IN SRCBLK
	TYPE	<
[ Working on pack on Channel >	;GIVE FEEDBACK
	MOVE	T1,SDBCKU(P1)	;GET DESIGNATOR AGAIN
	LOAD	T2,DOP%C2,T1	;GET CHANNEL
	TOCT	T2		;TYPE IN OCTAL
	TYPE	<, Controller >	;NOW THE CONTROLLER
	LOAD	T2,DOP%K2,T1	;GET THE VALUE
	CAIN	T2,.RTJST(DOP%K2,DOP%K2) ;-1
	 JRST [	TYPE	<-1>	;-1 FOR NO CONTROLLER
		JRST	.+2]	;AND SKIP THE TOCT
	TOCT	T2		;DO THE CONTROLLER
	TYPE	<, Unit >	;NOW THE UNIT
	LOAD	T2,DOP%U2,T1	;FETCH IT
	TOCT	T2		;ALSO OCTAL
	TYPE	< ]
>				;CLOSE BRACKET AND CONTINUE
	CALL	CMDVE2		;DO A UNIT
	AOBJN	P1,CMDVE1	;STEP TO NEXT
	JRST	VERDON		; AND DONE
;INITIALIZE FOR ^E AND ^A INTERRUPTS AND BEGIN.

CMDVE2:	MOVEI	T1,VERABT	;ABORT ROUTINE ADDRESS
	CALL	SETABT		;AND SETUP FOR THE INTERRUPT
	MOVE	T1,[.TICCA,,STSCHN] ;ACTIVATE
	ATI			; STATUS ON ^A
	 ERJMP	LOSE
	TIME			;GET CURRENT UPTIME
	 ERJMP	LOSE
	MOVEM	T1,BEGTIM	;SAVE FOR PAGES/SEC CALCULATION
	DMOVE	T1,SRCBLK	;LOAD UP START, END ADDRESSES
	MOVEI	T3,COVERI	;VERIFY COROUTINE ADDRESS
	CALL	SCAN		;CALL THE BIG SCAN LOOP
	RET			;THEN GO BACK

;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
	TDEC	ERRCNT		;OUTPUT THE DECIMAL ERROR COUNT
	TYPE	<, Pages/Second = >
	TIME			;CURRENT UPTIME
	SUB	T1,BEGTIM	;MINUS START IN T1
	ADDI	T1,^D500	;ROUND
	IDIVI	T1,^D1000	;AND CONVERT TO SECONDS
	MOVE	T2,LSTADR	;LSTADR SHOULD BE CLOSE TO RIGHT
	SUB	T2,BEGADR	;DIFFERENCE
	IDIV	T2,SDBSPP	;CONVERT TO PAGES
	IDIV	T2,T1		;DIVIDE
	TDEC	T2		;OUTPUT
	TYPE	< ]>		;CLOSE BRACKET
	RET			; ALL DONE

;VERIFY COMMAND COROUTINE, MERELY REPORTS ANY ERRORS THAT OCCUR

COVERI:	JUMPE	T1,R		;JUST RETURN IF NO ERRORS
	CALLRET	RPTERR		;OTHERWISE JUST REPORT THE ERROR



;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 at disk address >
	TOCT	LSTADR		;GIVE THE ADDRESS
	MOVE	P,SAVPSI	;RE-ADJUST STACK TO KNOWN POINT
	POP	P,T1		;POP OFF CALL TO CMDVE2
	JRST	VERDON		;AND CLOSE OUT THE COMMAND


;SETSWP - HERE TO SETUP SRCBLK WITH THE SDB RELATED START AND END ADDRESSES
;FOR THE CURRENT UNIT TO CHECK THE SWAPPING SPACE.
;
;	CALL	SETSWP
;
;RETURNS  +1:	ALWAYS WITH SRCBLK, SRCBLK+1 SET TO CALL SCAN

SETSWP:	SAVEAC	<P1>		;MAKE SURE P1 IS SAFE
	HRRZ	P1,P1		;CURRENT UNIT
	IMUL	P1,SDBSIZ	;CREATE SDB OFFSET FOR THIS ONE
	MOVEM	P1,SRCBLK	;UPDATE START
	MOVEM	P1,SRCBLK+1	;UPDATE END
	TXZ	F,HB%1VB!HB%2VB!HB%1SB!HB%2SB!HB%1B!HB%2B!HB%IB ;CLEAR BITS
	CALL	REDHOM		;READ HOME BLOCKS
	TXNE	F,HB%1VB	;CHECK FOR BOTH UNREADABLE CASE
	TXNN	F,HB%2VB	; WHERE BOTH BITS SET
	SKIPA			;AT LEAST ONE BLOCK WAS READABLE
	 ERROR	Swapping space information unavailable from HOME blocks
	MOVE	T1,HOM1AD+HOMFST ;GET FIRST SWAPPING CYLINDER
	IMUL	T1,SDBSPC	;TIMES SECTORS/CYLINDER
	ADDM	T1,SRCBLK	;SET START
	MOVE	T1,HOM1AD+HOMP4S ;GET PAGES FOR SWAPPING
	IMUL	T1,SDBSPP	;CONVERT TO SECTORS
	ADD	T1,SRCBLK	;ADD TO START TO GET LAST ADDRESS
	MOVEM	T1,SRCBLK+1	;SET IT
	RET			;AND RETURN
	SUBTTL	STSINT STATUS PSI INTERRUPT ROUTINE

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

	MOVEI	T1,.PRIOU	;WAIT FOR SOME OF THE
	DOBE			; OUTPUT TO FINISH
	TYPE	<Working on disk address >
	TOCT	LSTADR		;OUTPUT THE DISK ADDRESS
	TYPE	< (>		;NOW DO PERCENT DONE
	MOVE	T2,LSTADR	;FETCH LAST ADDRESS
	SUB	T2,BEGADR	;SUBTRACT BEGIN OFFSET
	IMULI	T2,^D100	;SCALE FOR PERCENT
	MOVE	T3,ENDADR	;GET LAST ADDRESS
	SUB	T3,BEGADR	;COMPUTE THE SPAN
	IDIV	T2,T3		;AND FINALLY THE RATIO
	TDEC	T2		;TWO DECIMAL COLUMNS
	TYPE	<%), error count is >
	TDEC	ERRCNT		;DECIMAL ERROR COUNTER
	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	SEARCH COMMAND

;HERE TO FINISH PARSING SEARCH COMMAND AND MAKE THE SEARCH OF THE
;SELECTED UNITS IN ORDER TO FIND THE DESIRED PATTERN.
;THE COMMAND IS OF THE FORM:
;SEARCH (FOR PATTERN) OCTAL-PATTERN (WITH MASK) OCTAL-MASK (BEGINNING AT)
;	OCTAL-ADDRESS (AND ENDING AT) OCTAL-ADDRESS
;
;REPORTS EACH OCCURRANCE.

.SEARCH: NOISE	(FOR PATTERN)	;GUIDEWORDS
	HRROI	T1,[ASCIZ/halfword format octal pattern/] ;FIRST
	HRROI	T2,[ASCIZ/halfword format octal mask/] ;SECOND
	CALL	PARHWD		;PARSE THE PATTERN NUMBER
	MOVEM	T2,SRCBLK	;PATTERN IN FIRST WORD OF BLOCK
	NOISE	(WITH MASK)	;GUIDE
	HRROI	T1,[ASCIZ/halfword format octal mask/] ;FIRST
	HRROI	T2,[ASCIZ/starting disk address/] ;SECOND
	CALL	PARHWD		;PARSE THE MASK VALUE
	MOVEM	T2,SRCBLK+1	;MASK IN SECOND WORD
	NOISE	(STARTING AT)	;GUIDE
	MOVEI	T2,[FLDDB. (.CMNUM,CM%SDH,^D8,<starting disk address>,<0>)]
	PARSE			;GET THE NUMBER
	MOVEM	T2,SRCBLK+2	;BEGIN ADR IN THIRD WORD
	NOISE	(ENDING AT)	;GUIDE
	MOVEI	T2,[FLDDB. (.CMNUM,CM%SDH,^D8,<ending disk address>,<-1>)]
	PARSE			;GET THE NUMBER
	MOVEM	T2,SRCBLK+3	;AND END ADR IN FOURTH WORD
	CONFRM			;CONFIRM THE COMMAND

	CALL	CHKUSE		;MAKE SURE WE HAVE USABLE STUFF
	MOVEI	T1,SRCABT	;ABORT ROUTINE ADDRESS
	CALL	SETABT		;FOR CONTROL-E
	MOVE	T1,[.TICCA,,STSCHN] ;SETUP CONTROL-A
	ATI			;TO GO TO STSINT
	 ERJMP	LOSE
	DMOVE	T1,SRCBLK+2	;FETCH START,,END
	MOVEI	T3,COSRCH	;COROUTINE ADDRESS
	SETZM	ERRCNT		;START WITH NO ERRORS
	CALL	SCAN		;DO THE SCAN
SRCDON:	CALL	CLRABT		;CLEAR CONTROL-E ABORT
	MOVX	T1,.TICCA	; AND ALSO CLEAR
	DTI			; CONTROL-A
	 ERJMP	LOSE
	RET			;AND DONE FOR NOW

;SEARCH COROUTINE FOR SCAN LOOP

COSRCH:	JUMPE	T1,COSRC1	;GO ON IF NO ERRORS
	CALL	RPTERR		;REPORT THE ERROR
	CAIN	T1,.DSHRD	;UNUSABLE PAGE?
	 RET			;YES, RETURN WITHOUT LOOKING AT IT
COSRC1:	MOVE	T1,0(T2)	;GET THE WORD
	AND	T1,SRCBLK+1	;AND WITH MASK
	CAME	T1,SRCBLK	;SEE IF IT MATCHES
COSRCX:	AOBJN	T2,COSRC1	;AND LOOP IF IT DOESN'T
	JUMPGE	T2,R		;RET IF AOBJN POINTER EXHAUSTED

;HERE WE HAVE A MATCH, OUTPUT THE WORD AND LOCATION

	PRINT	<Disk address: >
	HRRZ	T1,T2		;COPY THE ADDRESS PART
	SUBI	T1,DATPAG	;SUBTRACT BASE
	LSH	T1,-PGSFT	;FIGURE PAGES
	IMUL	T1,SDBSPP	;CONVERT TO PAGES
	ADD	T1,LSTADR	;UPDATE FROM LSTADR
	OCTOUT	T1,^D8		;AND OUTPUT THE DISK ADDRESS
	PRINT	<, Offset: >
	MOVE	T1,T2		;COPY POINTER
	ANDX	T1,PGSIZ-1	;COMPUTE PAGE OFFSET
	OCTOUT	T1,3		;PRINT IT
	PRINT	<, Contents: >
	OCTOUT	0(T2),^D12
	PRINT	<
>				;FINISH WITH A CRLF
	JRST	COSRCX		;GO BACK TO COMPLETE THE LOOP


;HERE ON CONTROL-E TO ABORT SEARCH

SRCABT:	MOVX	T1,.PRIOU	;CANCEL
	CFOBF			;OUTPUT IN PROGRESS
	 ERJMP	LOSE
	WARN	<Search aborted at disk address >
	TOCT	LSTADR		;SAY WHERE
	MOVE	P,SAVPSI	;RESTORE THE WORLD
	JRST	SRCDON		;AND COMPLETE COMMAND
	SUBTTL	WATCH COMMAND TO WATCH DISK ADDRESS

;.WATCH - ROUTINE TO DO WATCH COMMAND.  FORMAT IS
;WATCH (WORD OFFSET) n (IN PAGE AT DISK ADDRESS) d (WITH INTERVAL OF) s (MS)

.WATCH:	NOISE	(WORD OFFSET)	;HANDLE GUIDEWORDS
	MOVEI	T2,[FLDDB. (.CMNUM,,^D8)] ;OCTAL OFFSET
	PARSE			;READ THE OFFSET
	MOVE	P2,T2		;SAVE THE NUMBER IN P2 TIL CONFIRMED
	NOISE	(IN PAGE AT DISK ADDRESS) ;MORE QUIDEWORDS
	MOVEI	T2,[FLDDB. (.CMNUM,CM%SDH,^D8,<octal disk address>)]
	PARSE			;READ THE DISK ADDRESS
	MOVE	P1,T2		;SAVE IN P1 FOR CONFIRM
	NOISE	(WITH INTERVAL OF) ;MORE GUIDEWORDS
	MOVEI	T2,[FLDDB. (.CMNUM,CM%SDH,^D10,<number of milliseconds>,<1000>)]
	PARSE			;READ THE SLEEP INTERVAL
	MOVE	P3,T2		;AND SAVE ACROSS CONFIRM
	NOISE	(MS)		;FINAL GUIDEWORDS
	CONFRM			;NOW CONFIRM THE COMMAND

	CALL	CHKUSE		;MAKE SURE THERE'S SOMETHING TO USE
	CAIL	P2,0		;RANGE CHECK THE OFFSET
	CAILE	P2,PGSIZ-1	;FOR A REASONABLE VALUE
	 ERROR	Page offset not in proper range
	LOAD	T1,STGADR,P1	;FETCH THE DISK ADDRESS
	CAME	T1,P1		;SEE IF VALID (MATCHES)
	 ERROR	Disk address specified is invalid
	TYPE	<[Type ^E to terminate]
>				;INFORM HOW TO GET OUT
	MOVEI	T1,WATABT	;ABORT ADDRESS FOR CONTROL-E
	CALL	SETABT		;SET UP FOR CONTROL-E
	MOVE	P4,['RANDOM']	;START WITH A RANDOM VALUE IN P4

WATCLP:	MOVE	T1,P1		;GET DISK ADDRESS
	MOVX	T2,.DSDAT	;DATA TYPE PAGE
	STOR	T2,DS%TYP,F	;SET UP F
	CALL	RDCHK		;READ THE PAGE
	CAIN	T1,.DSHRD	;REALLY BAD ERROR?
	 CALL	RPTERR		;REPORT ANY UNRECOVERED ERRORS
	EXCH	P4,DATPAG(P2)	;GET PROPERLY OFFSET WORD, UPDATE OLD
	CAMN	P4,DATPAG(P2)	;CHANGED?
	 JRST	WATDLY		;NO, JUST DELAY AND TRY AGAIN
	OCTOUT	P2		;OUTPUT OFFSET
	PRINT	</	>	;SLASH TAB
	OCTOUT	P4		;AND THE NEW VALUE
	PRINT	<
>				;AND FINISH LINE
	;...
	;...

WATDLY:	MOVE	T1,P3		;GET SLEEP TIME
	DISMS			;WAIT
	JRST	WATCLP		;AND LOOP TO DO IT AGAIN



;WATABT - HERE ON ^E ABORT OF WATCH COMMAND

WATABT:	MOVEI	T1,.PRIOU	;CLEAR OUTPUT
	CFOBF			; INSTEAD OF WAITING
	 ERJMP	LOSE
	WARN	WATCH aborted
	MOVE	P,SAVPSI	;RE-ADJUST STACK
	RET			;AND DONE
	SUBTTL	GENERAL DISK SCAN LOOP

;SCAN - ROUTINE TO HANDLE THE OVERHEAD OPERATIONS OF A GENERAL
;DISK SCAN BY PAGES.  ATTEMPTS TO USE MULTIPLE PAGE DSKOP FEATURE.
;ACCEPTS:
;  T1/	STARTING DISK ADDRESS
;  T2/	ENDING DISK ADDRESS (-1 FOR ALL OF STR)
;  T3/	ADDRESS OF ROUTINE TO BE CALLED AFTER EACH PAGE IS READ:
;
;	CALL	SCAN
;
;RETURNS  +1:	ALWAYS WHEN THE SCAN HAS DONE THE END ADDRESS.
;
;AT THE CALLS TO THE COROUTINE T1 WILL HAVE THE RDCHK CODE,
; T2 AN AOBJN POINTER FOR THE DATA AND SO ON...
;
;ON INTERRUPTS, ETC. THE "DATABASE" IS AS FOLLOWS:
;  BEGADR/  BEGINNING ADDRESS
;  ENDADR/  END ADDRESS
;  COSCAN/  EXIT ROUTINE ADDRESS
;  LSTADR/  LAST DISK ADDRESS (STORED BY READ)
;  ERRCNT/  ERROR COUNTER (RDCHK RETURNED ERROR)
;  P3/	    CURRENT DISK ADDRESS
;  DATPAG/  THE READ-IN PAGE(S)

SCAN:	MOVEM	T1,BEGADR	;SAVE BEGIN ADDRESS
	MOVEM	T2,ENDADR	; AND END ADDRESS
	MOVEM	T3,COSCAN	; AND EXIT ROUTINE ADDRESS
	CAMLE	T1,T2		;REASONABLENESS CHECK LIMITS
	SETOM	T2		;IF END .LT. BEG, SET TO -1
	MOVE	T1,SDBSIZ	;SIZE OF A SINGLE UNIT IN SECTORS
	IMUL	T1,SDBCNT	; TIMES NUMBER OF UNITS = MAX ADR
	CAIL	T2,0		;IF NEGATIVE OR
	CAMLE	T2,T1		; TOO LARGE,
	MOVEM	T1,ENDADR	; THEN USE MAX VALUE
	CAMGE	T1,BEGADR	;CHECK FOR BEGIN OUT OF RANGE
	 ERROR	Beginning disk scan address is out of range
	MOVE	P3,BEGADR	;INIT CURRENT ADDRESS VALUE
	SETZM	P4		; AND ERROR COUNTER

SCAN0:	SOJG	P4,SCAN2	;DO SINGLE PAGE IF IN ERROR RECOVERY
	MOVX	T1,.DSDAT	;READ INTO THE DATA PAGE
	STOR	T1,DS%TYP,F	;SET IT
	MOVE	T1,P3		;GET NEXT ADDRESS
	MOVE	T2,SDBSPP	;SECTORS/PAGE
	IMUL	T2,NRPGS	;THE BIG BUFFER
	ADD	T2,P3		;PLUS CURRENT
	CAMLE	T2,ENDADR	;SKIP IF STILL IN RANGE
	 JRST	SCAN2		; ELSE DO ONE AT A TIME
	IDIV	T1,SDBSPC	;DIVIDE BY SECTORS/CYLINER
	MOVE	T3,SDBSPP	;SECTORS/PAGE
	IMUL	T3,NRPGS	;TIMES PAGES
	ADD	T2,T3		;ADD TO OFFSET IN CYLINDER
	SUB	T2,SDBSPC	;SUBTRACT A CYLINDER'S WORTH
	JUMPLE	T2,SCANM	;IF NOT OFF THE END, DO IT
	IDIV	T2,SDBSPP	;ELSE TURN EXTRA BACK TO PAGES
	SUB	T2,NRPGS	;GET -NUMBER TO DO
	MOVN	T2,T2		;MAKE POSITIVE
	SKIPA			;AND DO IT
SCANM:	MOVE	T2,NRPGS	;NUMBER OF PAGES FOR MRDCHK
	MOVEM	T2,SCNSIZ	;SAVE LAST SIZE WE TRIED FOR
	MOVE	T1,P3		;BEGIN ADDRESS AGAIN
	CALL	MRDCHK		;MAKE THE BIG READ ATTEMPT
	JUMPN	T1,SCAN1	;DO EACH PAGE INDIVIDUALLY IF ERROR
	MOVN	T2,SCNSIZ	;-NUMBER OF PAGES DONE
	IMULI	T2,PGSIZ	;CONVERT TO WORDS
	HRLZ	T2,T2		;-WORDS TO LH
	HRRI	T2,DATPAG	;AND START TO RH COMPLETES AOBJN POINTER
	CALL	@COSCAN		;CALL THE PROCESSING ROUTINE
	MOVE	T1,SCNSIZ	;SIZE INCREMENT
	JRST	SCANXL		;FINISH THE LOOP


;HERE TO DO SINGLE PAGE READS OVER A REGION WITH ERRORS

SCAN1:	MOVE	P4,NRPGS	;NUMBER OF TIMES TO READ SINGLE PAGE

SCAN2:	MOVX	T1,.DSDAT	;READ INTO THE DATA PAGE
	STOR	T1,DS%TYP,F	;SET IT
	MOVE	T1,P3		;GET NEXT ADDRESS
	CALL	RDCHK		;TRY A SINGLE PAGE
	SKIPE	T1		;ERROR?
	AOS	ERRCNT		;YES
	MOVE	T2,[-PGSIZ,,DATPAG] ;POINTER FOR A SINGLE PAGE
	CALL	@COSCAN		;CALL THE EXIT ROUTINE FOR GOODIES
	MOVEI	T1,1		;NUMBER OF PAGES DONE
SCANXL:	IMUL	T1,SDBSPP	;CONVERT TO SECTORS
	ADD	P3,T1		;AND UPDATE P3
	CAMGE	P3,ENDADR	;DONE YET?
	JRST	SCAN0		;NO, LOOP
	RET			;YES, FINALLY DONE
	SUBTTL	RPTERR - DISK ERROR REPORTING ROUTINE

;RPTERR - REPORT DISK ERROR ROUTINE
;
;  LSTERR/  LAST RDCHK ERROR
;  LSTADR/  LAST RDCHK DISK ADDRESS
;
;	CALL	RPTERR
;
;RETURNS +1:	ALWAYS AFTER PRINTING OUT A MESSAGE INCLUDING
;		THE DISK ADDRESS AND REASON, T1 CONTAINING LSTERR.
;USES T1.

RPTERR:	MOVE	T1,LSTERR	;GET THE LAST RDCHK ERROR CODE
	PRINT.	@RPTXT1(T1)	;PRINT THE FIRST PART OF THE MESSAGE
	OCTOUT	LSTADR,^D8	;OUTPUT THE DISK ADDRESS
	PRINT.	@RPTXT2(T1)	;AND THE TERMINATING TEXT
	PRINT	<
>				;GET TO A CLEAN LINE
	RET			;AND ALL DONE

RPTXT1:	[TEXT	<No problems encountered reading page>]	;.DSOK
	[TEXT	<% Soft error at disk address >]	;.DSRND
	[TEXT	<% Soft error at disk address >]	;.DSECC
	[TEXT	<% Hard error at disk address >]	;.DSHRD

RPTXT2:	[TEXT	<>]					;.DSOK, NOTHING TO SAY
	[TEXT	< - Transient read error>]		;.DSRND
	[TEXT	< - ECC required to read page>]		;.DSECC
	[TEXT	< - Page is completely unreadable>]	;.DSHRD
	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
;  SDBDES/  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:	MOVX	T2,PGSIZ	;SINGLE PAGE READ
	MOVEM	T2,SDBXFL	;SET IN SDB FOR READ
	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



;MRDCHK - ROUTINE TO ATTEMPT A MULTIPLE PAGE DSKOP.
;MAKES A SINGLE TRY WITHOUT ERROR LOGGING OR CORRECTION FOR
;A BUFFER OF SIZE PROVIDED INTO DATPAG AND UP.
;
;  T1/	DISK ADDRESS
;  T2/	NUMBER OF PAGES IN BUFFER
;  F/	FLAGS SAME AS RDCHK (ALWAYS ASSUMES DATPAG...)
;
;	CALL	MRDCHK
;
;RETURNS  +1:	ALWAYS WITH THE CODE RETURNED BY READ IN T1.

MRDCHK:	IMULI	T2,PGSIZ	;CONVERT TO WORDS
	MOVEM	T2,SDBXFL	;SET THE TRANSFER LENGTH IN THE SDB FOR READ
	TXO	F,DS%NEC!DS%NEL	;NO LOGGING OR CORRECTION
	MOVX	T2,DATPAG	;WHERE TO READ IT
	CALLRET	READ		; AND DO THE WORK
	SUBTTL	READ - ROUTINE TO DO THE DSKOP

;READ - ROUTINE TO READ IN A REGION 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)
;  SDBDES/   STRUCTURE DESIGNATOR FOR DISK -OR-
;  SDBCKU/   CKU FORMAT DESIGNATOR FOR DISK IF USABLE (FL%PHY)
;  SDBXFL/   NUMBER OF WORDS TO ASK FOR
;
;	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 LAST ADDRESS TRIED
	ANDX	T1,DSKAB-1	;MAKE SURE IT'S A GOOD DISK ADDRESS
	MOVEM	T2,LSTDST	;SAVE THE DESTINATION TOO
	TXNE	F,FL%PHY	;UNIT OR STRUCTURE?
	 JRST	READ0		;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,SDBDES	;FETCH DESIGNATOR
	JRST	READ2		;CONTINUE...

READ0:	IDIV	T1,SDBSIZ	;FIND WHICH UNIT
	MOVE	T4,SDBCKU(T1)	;AND GET ITS CKU VALUE
	STOR	T2,DOP%RA,T1	;AND PUT UNIT ADDRESS IN ITS FIELD
	MOVX	T2,.DOPPU	;PHYSICAL FORMAT
	STOR	T2,DOP%AT,T1	;SET IT
READ1:	SKIPE	CKUFLG		;BUILD OLD-STYLE DSKOP?
	 JRST	READ2		;NO
	LOAD	T2,DOP%C2,T4	;GET CHANNEL FROM CKU WORD
	STOR	T2,DOP%CN,T1	;STORE IN OLD PLACE
	LOAD	T2,DOP%U2,T4	;GET UNIT FROM CKU WORD
	STOR	T2,DOP%UN,T1	;SET IN OLD PLACE
READ2:	HRRZ	T2,SDBXFL	;PICK UP TRANSFER SIZE
	TXNE	F,DS%NEC	;ERROR CORRECTION?
	TXO	T2,DOP%IR	;NO
	TXNE	F,DS%NEL	;ERROR LOGGING?
	TXO	T2,DOP%IL	;NO
	TXNE	F,FL%PHY	;FINALLY CHECK PHYSICAL/CKU AGAIN
	SKIPN	CKUFLG		; AND IF SO
	 SKIPA			; THEN
	TXO	T2,DOP%NF	;SET CKU FORMAT FLAG
	MOVE	T3,LSTDST	;WHERE TO READ IT
	DSKOP			;DO IT
	 ERJMP	LOSE		;FAILURE
	RET			;RETURN TO CALLER
;CKUINI - ROUTINE TO INITIALIZE CKUFLG TO THE PROPER STATE:
;ZERO FOR NON-CKU DSKOPS, AND -1 FOR CKU-FORMAT DSKOPS ALLOWED.
;
;	CALL	CKUINI
;
;RETURNS  +1:	ALWAYS, WITH CKUFLG SET
;USES T1-T4.

CKUINI:	SETZM	CKUFLG		;ASSUME THE WORST
	MOVE	T1,[1,,.JBVER##] ;PEEK THE MONITOR VERSION
	MOVEI	T2,T2		;INTO T2
	PEEK			;READ THE VERSION NUMBER
	 ERJMP	LOSE
	ANDX	T2,777B11	;ISOLATE MAJOR VERSION NUMBER
	CAMGE	T2,[4B11]	;SEE IF AT LEAST V4
	 RET			;NOT - CAN'T USE CKU AT ALL

;HERE WE FIND OUT BY ACTUAL EXPERIMENT WITH A TEST DSKOP

	MOVX	T1,FLD(.DOPPU,DOP%AT) ;PHYSICAL FORMAT DSKOP
	MOVX	T2,DOP%NF!DOP%IL!DOP%IR!PGSIZ ;NEW FORMAT
	MOVX	T3,DATPAG	;USUAL PLACE
	MOVX	T4,DOP%C2!DOP%K2!DOP%U2 ;ILLEGAL CHANNEL...
	DSKOP			;MAKE THE ATTEMPT TO GET AN ERROR
	 ERJMP	CKUIN0		;HANDLE ERROR
	TYPE	<
? DSKOP characterization failed!> ;TRY TO EXPLAIN
	HALTF			;THEN GET OUT
	 JRST	.-1		; AND STAY OUT

CKUIN0:	MOVX	T1,.FHSLF	;WE WANT TO GET
	GETER			; OUR LAST ERROR
	HRRZS	T2		;ISOLATE ERROR CODE
	CAIE	T2,DECRSV	;"DEC RESERVED BITS NOT ZERO"?
	SETOM	CKUFLG		;NO! USE CKU FORMAT
	RET			; DONE
	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	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 SET, MAKES SURE THAT ALL DRIVES ARE 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...
	SAVEAC	P1		;SAVE P1 FOR THE REST OF THE ROUTINE
	SKIPN	P1,SDBCNT	;CHECK THE COUNT
	 ERROR	No units specified
	MOVN	P1,P1		;NEGATE
	HRLZ	P1,P1		;AND BUILD AOBJN POINTER
CHKUS1:	MOVE	T1,SDBCKU(P1)	;FETCH NEXT UNIT DESIGNATOR
	CALL	UNTINF		;GET ITS STATUS
	TXNE	T1,MS%OFL	;CHECK FOR SAFELY ON-LINE
	 ERROR	Unit is off-line
	AOBJN	P1,CHKUS1	;LOOP FOR ALL
	RET			;THEN RETURN
	SUBTTL	STRINF - ROUTINE FOR RETURNING STRUCTURE INFO

;STRINF - ROUTINE TO COLLECT THE NEEDED UNIT INFORMATION FOR THE
;DISK STRUCTURE WHOSE DESIGNATOR IS GIVEN IN SDBDES.  THE DATA IS
;RETURNED IN THE SDB TABLE.
;UNITSZ WILL HAVE THE SIZE IN PAGES, INDEXED BY UNIT.
;
;  SDBDES/	DESIGNATOR FOR THE DESIRED STRUCTURE.
;
;	CALL	STRINF
;RETURNS  +1:	ALWAYS, SDBCNT, SDBSIZ, SDBSPP SET UP


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	SDBCNT		;WE HAVEN'T SEEN ANY UNITS YET

STRNXT:	CALL	UNTSTS		;GET STATUS OF NEXT UNIT
	JRST  [	SKIPN	T1,SDBCNT ;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 [SETOM	T2	;MARK T2 SO DOESN'T COMPARE
		JRST	.+1]	; AND CONTINUE IN LINE
	CAME	T2,SDBDES	;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	SDBCNT		;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)
	IMUL	T2,MSBLK+.MSRSP	;TIMES SECTORS/PAGE TO GET SECTORS
	MOVEM	T2,SDBSIZ	;SIZE OF A UNIT
	MOVE	T2,MSBLK+.MSRSP	;GET SECTORS/PAGE
	MOVEM	T2,SDBSPP	;SAVE IT
	IMUL	T2,MSBLK+.MSRPC	;TIMES PAGES/CYLINDER
	MOVEM	T2,SDBSPC	;GIVES SECTORS/CYLINDER WORD
	SETZM	SDBCKU(T1)	;CLEAR THAT CKU WORD
	MOVE	T2,MSBLK+.MSRCH	;CHANNEL
	STOR	T2,DOP%C2,SDBCKU(T1) ;STORE
	MOVE	T2,MSBLK+.MSRCT	;CONTROLLER
	STOR	T2,DOP%K2,SDBCKU(T1) ;STORE
	MOVE	T2,MSBLK+.MSRUN	;UNIT
	STOR	T2,DOP%U2,SDBCKU(T1) ;STORE
	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.
;
;  T1/	CKU FORMAT DESIGNATOR FOR UNIT
;	CALL	UNTINF
;RETURNS  +1:	ALWAYS,
;		T1/	UNIT STATUS
;		T2/	SIZE IN SECTORS
;		T3/	SECTORS/PAGE
;		T4/	SECTORS/CYLINDER
;		MSBLK/	MSTR DATA

UNTINF:	LOAD	T2,DOP%C2,T1	;CHANNEL NUMBER
	MOVEM	T2,MSBLK+.MSRCH	;SET IN MSTR BLOCK
	LOAD	T2,DOP%K2,T1	;CONTROLLER NUMBER
	CAMN	T2,[.RTJST(DOP%K2,DOP%K2)] ;MINUS ONE?
	SETOM	T2		;YES, MAKE IT SO
	MOVEM	T2,MSBLK+.MSRCT	;SET IT
	LOAD	T2,DOP%U2,T1	;UNIT NUMBER
	MOVEM	T2,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
	IMUL	T2,MSBLK+.MSRSP	; TIMES SECTORS/PAGE
	MOVE	T3,MSBLK+.MSRSP	;GET NUMBER OF SECTORS/PAGE
	MOVE	T1,MSBLK+.MSRST	;FINALLY, RETURN UNIT SOFTWARE STATUS
	MOVE	T4,MSBLK+.MSRPC	;PAGES/CYLINDER
	IMUL	T4,T3		;INTO SECTORS PER CYLINDER
	RET			;ALL DONE
	SUBTTL	VERSION NUMBER PRINTING ROUTINE


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

VEROUT:	MOVEI	T3,^D8		;NOUT FORMAT, OCTAL
	MOVEI	T2,VMAJOR	;MAJOR VERSION LEVEL
	NOUT			; ELSE PRINT
	 ERJMP	LOSE		;FAILED
	MOVEI	T2,VMINOR	;MINOR VERSION NUMBER
	JUMPE	T2,VEROU1	;DON'T BOTHER IF ZERO
	MOVEI	T2,"."		;GET THE DOT
	BOUT			; AND OUTPUT IT
	 ERJMP	LOSE
	MOVEI	T1,VMINOR	;MINOR AGAIN
	NOUT			;OUTPUT
	 ERJMP	LOSE
VEROU1:	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
	EXP	TOCTUU		;TOCT
	EXP	TDECUU		;TDEC
	EXP	TSPUUO		;TSPACE
	EXP	PSPUUO		;PSPACE
	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:	MOVEI	T1,LOSFIN	;SETUP TO TRANSFER TO
	EXCH	T1,0(P)		; THE CLEANUP ROUTINE
	HRRO	T1,-2(P)	;POINT TO THE STRING
	ESOUT			;OUTPUT IT ESOUT MANNER
	 ERJMP	LOSFIN		;GET TO LOSFIN
	RET			;IN ANY CASE
;OCTUUO - ROUTINE TO PROCESS THE OCTOUT UUO
;DECUUO - ROUTINE TO PROCESS THE DECOUT UUO
;TOCTUU - ROUTINE TO PROCESS THE TOCT UUO
;TDECUU - ROUTINE TO PROCESS THE TDEC UUO


TOCTUU:				;SAME ENTRY POINT
OCTUUO:	MOVE	T2,@.JBUUO##	;DO FETCH FIRST TO ALLOW USING ACS
	MOVX	T3,NO%MAG+^D8	;OCTAL RADIX ENTRY
	JRST	NUMUUO		;ENTER COMMON CODE

TDECUU:				;SHARED ENTRY POINT
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
	LOAD	T1,UUONUM	;GET THE UUO OPCODE
	CAIE	T1,<TOCT.>_<-^D27> ;TOCT OR
	CAIN	T1,<TDEC.>_<-^D27> ;TDEC?
	 SKIPA			;YES, USE .PRIOU
	SKIPN	T1,OJFN		;FETCH THE DESIRED
	MOVX	T1,.PRIOU	; OUTPUT DESIGNATOR
	NOUT			;DO THE OUTPUT
	 ERJMP	LOSE
	HRRZS	T3		;JUST THE RADIX
	CAIE	T3,^D10		;DECIMAL?
	RET			;NO, RETURN
	MOVEI	T2,"."		;YES, GET A DECIMAL POINT
	BOUT			; AND OUTPUT (T1 HAS CORRECT DESIGNATOR)
	 ERJMP	LOSE
	RET			;RETURN



;TSPUUO - ROUTINE TO PROCESS THE TSPACE UUO
;PSPUUO - ROUTINE TO PROCESS THE PSPACE UUO


PSPUUO:	SKIPN	T1,OJFN		;SELECT THE
TSPUUO:	MOVX	T1,.PRIOU	; PROPER DESIGNATOR
	MOVX	T2," "		;SPACE
	HRRZ	T3,.JBUUO##	;NUMBER TO DO
	JUMPE	T3,R		;IF ZERO, DO NONE
PSPUUL:	BOUT			;OUTPUT
	 ERJMP	LOSE
	SOJG	T3,PSPUUL	;LOOP FOR THAT NUMBER
	RET			;THEN 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

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



;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



;.SVSDB - INTERNAL ROUTINE TO SAVE REGISTER F AND SDB AND RESTORE THEM
;ON RETURN FROM CALLING ROUTINE.  CALLED VIA THE SAVSDB MACRO.
;USES CX.


.SVSDB:	PUSH	P,F		;SAVE THE FLAGS
	MOVE	F,[SDBBEG,,SDBTMP] ;BLT POINTER TO
	BLT	F,SDBTMP+<SDBEND-SDBBEG>-1 ;SAVE SDB IN TEMP AREA
	CALL	0(CX)		;CALL OUR CALLER
	 SKIPA			;HANDLE SKIP RETURNS
	AOS	-2(P)		; AND NON-SKIP RETURNS
	MOVE	F,[SDBTMP,,SDBBEG] ;BLT POINTER
	BLT	F,SDBEND-1	;FOR RESTORE
	POP	P,F		;RESTORE THE OLD FLAGS
	RET			;AND RETURN

;PARHWD - ROUTINE TO TRY DESPARATELY TO PARSE AN OCTAL NUMBER IN A,,B FORM.
;
;  T1/	POINTER TO HELP TEXT FOR FIRST FIELD
;  T2/	POINTER TO HELP TEXT FOR NEXT FIELD, TO GIVE AT ,, TIME
;
;	CALL	PARHWD
;
;RETURNS  +1:	ALWAYS WITH VALUE IN T2.
;USES T1-T4.

PARHWD:	MOVEM	T1,PARFL1+.CMHLP ;SET FIRST HELP TEXT
	MOVEM	T2,PARFL2+.CMHLP ;"SAVE" SECOND FOR LATER
	MOVEI	T2,PARFL1	;FIRST BLOCK FOR NUMBER
	PARSE			;TRY TO GET THE FIRST PART
	MOVE	T1,CMDBLK+.CMFLG ;GET PARSE FLAGS
	TXNE	T1,CM%ESC	;ESCAPE TYPED?
	 JRST	PARHDN		;YES, ASSUME DONE
	TLC	T2,-1		;TRY TO HANDLE MORE THAN 6 DIGITS HERE
	TLCE	T2,-1		; OR -M,,N CASE
	TLNN	T2,-1		; BY CONTINUING IF LH NOT ALL 0'S OR 1'S
	 SKIPA			;COULD BE MORE TO GET
	JRST	PARHDN		;ASSUME DONE, MORE THAN A HALFWORD GIVEN
	MOVE	T4,T2		;SAVE CURRENT HALFWORD
	HRROI	T1,PARHLP	;SECOND HELP TEXT IS HERE
	HRROI	T2,[ASCIZ/,, or
/]				;BUILD COMPOSITE
	SETZ	T3,0		;ASCIZ
	SOUT			;COPY STRING
	 ERJMP	LOSE
	MOVE	T2,PARFL2+.CMHLP ;REGET SECOND POINTER
	SOUT			;APPEND IT
	 ERJMP	LOSE
	HRROI	T1,PARHLP	;POINT BACK TO BEGINNING
	MOVEM	T1,PARFL2+.CMHLP ;SET HELP TEXT
	MOVEI	T2,PARFL2	;SECOND BLOCK FOR ",,"
	CALL	COMMND		;TRY FOR THE SEPARATOR
	 JRST [	MOVE	T2,T4	;NOT ,, SO TRY TO BELIEVE WE ARE DONE
		JRST	PARHDN]	; AND RETURN THE VALUE
	MOVEI	T2,[FLDDB. (.CMNUM,CM%SDH,^D8,<right half>,<0>)]
	PARSE			;TRY FOR RIGHT HALF
	TLC	T2,-1		;MAKE LH CHECKS AGAIN
	TLCE	T2,-1		; TO WEED OUT RH TOO BIG
	TLNN	T2,-1		; WHICH IS AN ERROR
	 JRST	PARHW1		;OK, FINISH
	ERROR	Right halfword exceeds 777777

PARHW1:	HRLM	T4,T2		;BUILD THE VALUE
PARHDN:	RET			;RETURN THE VALUE
	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
	MOVE	T1,[POINT 7,ERRBUF] ;POINT TO ERROR BUFFER
	MOVEI	T2," "		;SPACE BETWEEN
	IDPB	T2,T1		;? AND MESSAGE
	HRLOI	T2,.FHSLF	;LAST ERROR IN THIS FORK
	HRLI	T3,-TXTLEN	;MAX BYTES
	ERSTR			;GET THE ERROR
	 ERJMP	.+1		;FAILED
	 ERJMP	.+1		;FAILED
	HRROI	T1,ERRBUF	;POINT TO ERROR MESSAGE AGAIN
	ESOUT			;OUTPUT THE MESSAGE
	SKIPN	TAKJFN		;NEED TO ABORT TAKE?
	JRST	LOSFIN		;NO
	CALL	UNTAKE		;YES--SO DO IT
	TMSG	< -- command file aborted> ;AND SAY SO


LOSFIN:	TMSG	<

>				;FINAL STRING CRLF
	MOVX	T1,.PRIIN	;GET READY
	CFIBF			;CLEAR INPUT BUFFER
	HRRZ	T1,CMDBLK+.CMFLG ;GET REPARSE ADDRESS
	JRST	-1(T1)		;AND TRANSFER TO ONE LESS...


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	DOPARS		;AND GO DO COMND JSYS



;DOCNFM - ROUTINE TO HANDLE LINE CONFIRMATION FUNCTION.
;	CALL	DOCNFM	OR USE CONFRM MACRO
;RETURNS  +1:	ALWAYS

DOCNFM:	MOVEI	T2,[FLDDB. (.CMCFM)] ;GET CONFIRM FUNCTION
;	CALLRET	DOPARS		;AND DO THE PARSE



;DOPARS - ROUTINE CALLED BY THE PARSE MACRO.
;  T2/	ADDRESS OF COMND DESCRIPTOR BLOCK
;
;	CALL	DOPARS	   OR	  PARSE
;
;RETURNS  +1:	ALWAYS ON SUCCESSFUL PARSE, OTHERWISE EXITS VIA LOSE

DOPARS:	CALL	COMMND		;MAKE THE COMND CALL
	JRST	LOSE		;BLOW UP ON ERRORS
	RET			;AND RETURN +1 ON SUCCESS



;COMMND - CENTRAL ROUTINE TO PERFORM COMND JSYS CALL.
;  T2/	ADDRESS OF COMND DESCRIPRTOR BLOCK TO USE
;	CALL	COMMND	OR USE PARSE MACRO
;RETURNS  +1:	ON NOPARSE
;	  +2:	ON SUCCESSFUL PARSE

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?
	RET			;NO, COMPLAIN
	RETSKP			;YES, RETURN SUCCESSFULLY
	SUBTTL	THE DATA AREA

	XLIST			;DUMP THE LITERALS
DSLITS:	LIT
	LIST


;COMND VARIABLES

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

JFNTMP:	BLOCK	1		;WORD FOR COMND'S JFNS RETURNED DURING PARSE
TXTBUF:	BLOCK	TXTLEN/5+1	;BUFFER FOR COMMAND JSYS
ATMBUF:	BLOCK	TXTLEN/5+1	;BUFFER FOR ATOM BUFFER
ERRBUF:	BLOCK	TXTLEN/5+1	;BUFFER FOR ERROR MESSAGES

;GUIDEWORD DESCRIPTOR BLOCK USED BY NOISE ROUTINE

NOIBLK:	FLDDB.	(.CMNOI)	;BLOCK FOR NOISE FUNCTION

;DESCRIPTOR BLOCKS USED BY HALFWORD PARSE ROUTINE

PARFL1:	FLDDB. (.CMNUM,CM%HPP!CM%SDH,^D8,<>)
	BLOCK	4		;IN CASE OF BEING RIPPED BY OSMAN'S MACROS
PARFL2:	FLDDB. (.CMTOK,CM%HPP!CM%SDH,<-1,,[ASCIZ/,,/]>,<>)
	BLOCK	4
PARHLP:	BLOCK	10		;SECOND FIELD HELP MESSAGE ",, OR..."

;PSI SYSTEM VARIABLES

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
HLPJFN:	BLOCK	1		;FOR HELP FILE

SAVEP:	BLOCK	1		;STORAGE OF STACK
SAVEP1:	BLOCK	1		;LIKE SAVEP, BUT FOR SUBCOMMANDS
SAVEP2:	BLOCK	1		;LIKE SAVEP, BUT FOR SUBCOMMANDS
PDL:	BLOCK	PDLSIZ		;STACK ROOM
DIRCKU:	BLOCK	1		;CKU FOR CURRENT DIRECTORY MEM TABLE
DIRPTR:	BLOCK	1		;SIZE COUNTER/POINTER FOR DIRECTORY MAP
DIRNUM:	BLOCK	1		;NUMBER OF THE DESIRED DIRECTORY
DIRLIM:	BLOCK	1		;PAGE LIMIT FOR DIRECTORY (END SYMBOL TABLE)
DIRSTR:	BLOCK	10		;DIRECTORY NAME STRING FOR COPY DIRECTORY

OJFN:	BLOCK	1		;OUTPUT FILE JFN
CJFN:	BLOCK	1		;COPY FILE JFN
FILJFN:	BLOCK	1		;WORD USUALLY HOLDING FILE JFN
FDBBLK:	BLOCK	.FBADR+1	;SPACE FOR FDB DATA

CKUFLG:	BLOCK	1		;FLAG SET TO -1 IF CKU FORMAT DSKOP USABLE
SDBBEG:				;START OF SDB DATA
SDBCNT:	BLOCK	1		;NUMBER OF UNITS IN THIS "STRUCTURE"
SDBSIZ:	BLOCK	1		;SIZE OF EACH UNIT IN SECTORS
SDBSPP:	BLOCK	1		;SECTORS PER PAGE
SDBSPC:	BLOCK	1		;SECTORS PER CYLINDER
SDBXFL:	BLOCK	1		;HOW MANY WORDS FOR READ TO TRY FOR
SDBDES:	BLOCK	1		;STRUCTURE DESIGNATOR IF NOT PHYSICAL
SDBCKU:	BLOCK	MXUNIT		;CKU DESIGNATORS IF PHYSICAL ADDRESSING
SDBEND:				;END OF SDB DATA

SDBTMP:	BLOCK	SDBEND-SDBBEG	;FOR REPARSE TEMP STORE AND ACROSS FILE COMMANDS

RETRY:	BLOCK	1		;RETRY COUNTER FOR RDCHK
CHKADR:	BLOCK	1		;HOLDS DISK ADDRESS FOR RDCHK
LSTADR:	BLOCK	1		;DISK ADDRESS FOR READ
LSTERR:	BLOCK	1		;LAST DSKOP READ ERROR CODE FROM RDCHK
NRPGS:	EXP	NPGS		;NUMBER OF PAGES TO TRY FOR IN SCAN/MRDCHK
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
;SEARCH DATABASE

SRCBLK:	BLOCK	4		;SEARCH PATTERN, MASK, BEGIN, END

;SCAN ROUTINE VARIABLES

BEGADR:	BLOCK	1		;BEGINNING ADDRESS
ENDADR:	BLOCK	1		;ENDING ADDRESS
COSCAN:	BLOCK	1		;ADDRESS OF ROUTINE TO CALL FOR EACH PAGE
ERRCNT:	BLOCK	1		;ERROR COUNTER FOR SCAN
BEGTIM:	BLOCK	1		;UPTIME AT START OF VERIFY
SCNSIZ:	BLOCK	1		;NUMBER OF PAGES SCAN LAST TRIED FOR

;STRUCTURE AND UNIT VARIABLES

STRDAT:				;BEGINNING OF STRUCTURE DATA BLOCK
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
UNITSZ:	BLOCK	MXUNIT		;SIZE OF UNIT IN PAGES
	STREND==.-1		;END OF STRUCTURE BLOCK


	END	<3,,EVEC>