Google
 

Trailing-Edge - PDP-10 Archives - BB-H311D-RM - swskit-tools/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
	SEARCH	ZSUBS		;GET SUBROUTINE PACKAGE
	SALL			;NICE LOOKING MACROS
	.DIRECT	FLBLST		;AND NICE LISTING


;VERSION INFORMATION:


	VMAJOR==4		;MAJOR VERSION LEVEL
	VMINOR==0		;MINOR VERSION LEVEL
	VEDIT==^D145		;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
;	DS.CTL		CONTROL FILE TO BUILD DS
;	ZSUBS.UNV	SUPPORT ROUTINES UNIVERSAL FILES
;	ZSUBS.REL	SUPPORT ROUTINES CODE 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. . . . . . . . . . . . . . . . . . . . . . . . .  12
;  5. ENTRY VECTOR AND INITIALIZATION. . . . . . . . . . . . . . .  18
;  6. THE SIMPLE COMMANDS - EXIT, HELP . . . . . . . . . . . . . .  20
;  7. FILDDT COMMAND . . . . . . . . . . . . . . . . . . . . . . .  21
;  8. OUTPUT FILE SPECIFICATION COMMAND. . . . . . . . . . . . . .  22
;  9. DRIVE SPECIFICATION COMMAND. . . . . . . . . . . . . . . . .  23
; 10. DEFINE COMMAND TO BUILD MULTI-UNIT SDB . . . . . . . . . . .  24
; 11. GETCKU - ROUTINE TO READ CHANNEL, CONTROLLER, UNIT . . . . .  26
; 12. STRUCTURE SPECIFICATION COMMAND. . . . . . . . . . . . . . .  27
; 13. INFORMATION COMMAND TO DISPLAY DRIVE STATUS. . . . . . . . .  28
; 14. DIRECTORY COMMAND TO DO INDEX BLOCK ADDRESS DIRECTORY. . . .  31
; 15. DUMP COMMAND TO DUMP VARIOUS ITEMS . . . . . . . . . . . . .  33
; 16. DUMP COMMAND FOR DISK PAGES. . . . . . . . . . . . . . . . .  34
; 17. DUMP COMMAND FOR FILE INDEX BLOCKS . . . . . . . . . . . . .  36
; 18. DUMP COMMAND FOR HOME BLOCKS . . . . . . . . . . . . . . . .  41
; 19. DUMP COMMAND FOR BAT BLOCKS. . . . . . . . . . . . . . . . .  45
; 20. DUMP COMMAND FOR KS MICROPROCESSOR DIRECTORY . . . . . . . .  50
; 21. DUMP COMMAND FOR BIT-TABLE . . . . . . . . . . . . . . . . .  54
; 22. DUMP COMMAND FOR INDEX-TABLE . . . . . . . . . . . . . . . .  57
; 23. CHECK COMMANDS, CHECK PAGE . . . . . . . . . . . . . . . . .  59
; 24. CHECK COMMANDS, CHECK INDEX BLOCK. . . . . . . . . . . . . .  61
; 25. CHECK COMMANDS, CHECK FILE-READABILITY . . . . . . . . . . .  62
; 26. COPY COMMAND . . . . . . . . . . . . . . . . . . . . . . . .  67
; 27. COPY DIRECTORY COMMAND . . . . . . . . . . . . . . . . . . .  72
; 28. VERIFY COMMAND TO READ-CHECK A UNIT OR STRUCTURE . . . . . .  80
; 29. STSINT STATUS PSI INTERRUPT ROUTINE. . . . . . . . . . . . .  84
; 30. SEARCH COMMAND . . . . . . . . . . . . . . . . . . . . . . .  85
; 31. WATCH COMMAND TO WATCH DISK ADDRESS. . . . . . . . . . . . .  87
; 32. GENERAL DISK SCAN LOOP . . . . . . . . . . . . . . . . . . .  89
; 33. RPTERR - DISK ERROR REPORTING ROUTINE. . . . . . . . . . . .  90
; 34. RDCHK - ROUTINE TO READ IN AND CHECK DISK PAGE . . . . . . .  91
; 35. READ - ROUTINE TO DO THE DSKOP . . . . . . . . . . . . . . .  93
; 36. CKUINI - ROUTINE TO INITIALIZE CKUFLG STATE. . . . . . . . .  94
; 37. CHKSUM - ROUTINE TO COMPUTE INDEX BLOCK CHECKSUM . . . . . .  95
; 38. CHKUSE - CHECK UNIT USABILITY FOR COMMANDS . . . . . . . . .  96
; 39. STRINF - ROUTINE FOR RETURNING STRUCTURE INFO. . . . . . . .  97
; 40. UNTSTS - ROUTINE FOR STATUS OF NEXT UNIT . . . . . . . . . .  99
; 41. UNTINF - ROUTINE FOR STATUS OF PARTICULAR UNIT . . . . . . . 100
; 42. OUTPUT FORMATTING ROUTINES . . . . . . . . . . . . . . . . . 101
; 43. THE DATA AREA. . . . . . . . . . . . . . . . . . . . . . . . 105
	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.
;
; 113	JGZ	27-FEB-81
;		FIX BUG AT BATUNT: TXZN SHOULD HAVE BEEN TXZ!!!
;
;***** BEGIN VERSION 3 *****
;
; 114	JGZ	30-JUL-81
;		DO CONVERSION TO USE ZSUBS PACKAGE.
;
; 115	JGZ	11-NOV-81
;		EXTRA SPACE IN RPTERR TEXT TO PREVENT DISK ADDRESS RUNON.
;
; 116	JGZ	11-NOV-81
;		AVOID ACCUMULATING JFNS IN COPY COMMAND BY NOT CLEARING
;		JFNTMP UNTIL THE FILE IS OPEN.
;
; 117	JGZ	11-NOV-81
;		LET COPY COMMAND DO TTY ALSO...
;
; 120	JGZ	25-NOV-81
;		ADD DEFINITIONS FOR READ AFTER WRITE IN HOME BLOCKS.
;		PRINT THE FLAGS.
;
; 121	JGZ	25-NOV-81
;		ADD DIRECTORY (WITH INDEX BLOCK ADDRESSES) COMMAND.
;
; 122	JGZ	26-NOV-81
;		NEW TABLE OF CONTENTS, CLEANUP LISTING SOME...
;
; 123	JGZ	26-NOV-81
;		ADD PAGE COUNT, OFFLINE ATTRIBUTE TYPEOUT TO DIRECTORY
;		COMMAND OUTPUT.
;
; 124	JGZ	27-NOV-81
;		ADD CONTROL-E ABORT CODE TO THE COPY COMMAND FOR FILES.
;
; 125	JGZ	27-NOV-81
;		LET COPY DIRECTORY COMMAND SKIP OVER SWAPPING SPACE IN
;		ITS DISK SCAN TO SPEED IT UP A BIT.  SIDE EFFECT OF THE
;		CONTROL-A OUTPUT PERCENTAGE BEING RESET FOR EACH SEGMENT
;		HOWEVER....
;
; 126	JGZ	4-JAN-82
;		TURN OFF INTERRUPT CHARACTERS EARLIER IN COPY DIRECTORY.
;
; 127	JGZ	7-JAN-82
;		DEFAULT TO DSK: FOR STRUCTURE COMMAND AND HANDLE THAT CASE
;		SPECIFICALLY.
;
; 130	JGZ	21-JAN-82
;		COLLECT UN-HEADERED SYMBOL TABLE PAGES ALSO IN COPY DIRECTORY
;		COMMAND TO MAKE UP FOR MONITOR BUG THAT LOSES HEADERS.
;		REPORT THEM AS A WARNING.  DUE TO MONITOR NATURE, THERE MAY
;		BE PAGES WE DON'T FIND IF THE SYMBOL TABLE GETS BIGGER THAN
;		A PAGE.  PROBABLY BEST USER BET IS THEN TO SEARCH FOR THE
;		INDEX BLOCK FOR THE DIRECTORY WITH THE SEARCH COMMAND.
;
; 131	JGZ	21-JAN-82
;		ADD FUNCTIONALITY TO COPY PAGE COMMAND.  EXPAND FORMAT TO
;		COPY PAGE (AT DISK ADDRESS) N (TO) FILE (PAGE) M
;
; 132	JGZ	21-JAN-82
;		CLEAN UP LISTING, NEW TABLE OF CONTENTS.
;
; 133	JGZ	22-JAN-82
;		CHANGE MISLEADING STSCHN SYMBOL FOR CHNTAB ENTRY TO THE
;		SIMPLE VALUE 1 FOR PRIORITY LEVEL; STSCHN IS A CHANNEL,
;		NOT A LEVEL.
;
; 134	JGZ	24-JAN-82
;		TEXT MACRO HAS MOVED TO ZSUBS.
;
; 135	JGZ	28-JAN-82
;		MAKE USE OF NEW ZSUBS LUUOS TYPJFN/PRTJFN TO OUTPUT FILESPECS.
;
;***** BEGIN VERSION 4 *****
;
; 136	JGZ	4-FEB-83
;		DECIMAL EDIT NUMBERS, ADD RA80, RA81, RA60 DISK TYPES,
;		REMOVE IFNDEF CODE FOR NOW-DEFINED SYMBOLS (RP20), FLUSH RP08.
;
; 137	JGZ	9-APR-84
;		USE VI%DEC FOR DECIMAL VERSION NUMBER.
;
; 138	JGZ	4-JUL-84
;		CONVERT INFO COMMAND TYPEOUT AND DRIVE AND DEFINE COMMAND
;		INPUT TO NEW DECIMAL CKU STANDARD FOR 6.0.
;
; 139	JGZ	11-JUL-84
;		ADD CONDITIONAL DEFINITION AND TEST AND REPORT ON MS%CRY
;		IN THE HOME BLOCKS FOR PASSWORD ENCRYPTION.
;
; 140	JGZ	23-JUL-84
;		ACCOMMODATE CHANGED CALLING SEQUENCE TO DOFORK IN ZSUBS AS
;		PART OF THE PUSH COMMAND CHANGES FOR RELEASE 6.
;
; 141	JGZ	9-AUG-84
;		ADD DUMP BIT-TABLE AND DUMP INDEX-TABLE COMMANDS.  RUN THEM
;		OFF FILES, SINCE ONE CAN ALWAYS COPY OUT THE PAGES FROM
;		A DISK THAT IS NOT MOUNTABLE INTO ANOTHER FILE.
;
; 142	JGZ	22-AUG-84
;		CLEAN UP LISTING, NEW TABLE OF CONTENTS, COLLAPSE SIXWRD
;		INTO PSIX.
;
; 143	JGZ	23-AUG-84
;		SUPPRESS TYPEOUT OF ZERO PPNS IN DUMP INDEX-TABLE.
;
; 144	JGZ	31-AUG-84
;		USE NEW MECHANISM (DOP%PS) TO ADDRESS HOME/BAD BLOCKS
;		FOR V6, NEEDED BY RAXX/HSC50 SCREWUPS.  CHANGE CKUFLG
;		INITIALIZATION TO TEST FOR DOP%PS FOR BACKWARD
;		COMPATIBILITY WITH V4 AND V5.
;
; 145	JGZ	31-AUG-84
;		SAVE FLAGS AND SET FL%PHY IN HOMDMP AND BATDMP TO USE
;		UNIT RELATIVE ADDRESSING ALONG WITH DOP%PS TO GET THE
;		HOME AND BAT BLOCKS INSIDE MULTI-UNIT STRUCTURES.
;		NEW TABLE OF CONTENTS.
	SUBTTL	DEFINITIONS


;MACROS, OPDEFS, AND DEFSTRS:


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

	DEFINE	SAVSDB,<
	JSP	CX,.SVSDB		;;MACRO FOR SAVING SDB, FLAGS
>


	DEFSTR	DS%TYP,,35,2		;PAGE TYPE CODE PASSED TO RDCHK
;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
	FL%TTY==1B6		;COPY COMMAND OUTPUT IS TO TTY FLAG

	DS%PS==1B17		;USE PHYSICAL SECTOR ADDRESSING DSKOP
	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==400000		;PAGE ADDRESS FOR SUPER INDEX BLOCKS
	XBPAG==401000		;PAGE FOR INDEX BLOCKS
	DATPAG==402000		;PAGES FOR DATA DSKOPS (NPGS OR NDXPGS LONG)
	DIRMAP==600000		;SPACE FOR COPY DIRECTORY TABLE (2 WORD ENTRIES)
				;(0) RELATIVE DIR PAGE (-1 FOR SYMBOLS),,DIR #
				;(1) DISK ADDRESS OF PAGE
	   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

	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, ETC.
;*** UNTIL GENERALLY AVAILABLE IN MONSYM ***
   IFNDEF MS%RWS,<MS%RWS==1B7>	;READ AFTER WRITE FOR SWAPPING SPACE
   IFNDEF MS%RWD,<MS%RWD==1B8>	;READ AFTER WRITE FOR DATA OPERATIONS
   IFNDEF MS%CRY,<MS%CRY==1B11>	;PASSWORD ENCRYPTION ENABLED FOR STR
	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
	SYMCOD==400400		;CODE IN LH OF SYMBOL TABLE HEADER

;*** RAxx SYMBOLS UNTIL GENERALLY AVAILABLE IN MONSYM  ***

IFNDEF .MSR80,<.MSR80==27>	;RA80 UNIT TYPE CODE
IFNDEF .MSR81,<.MSR81==30>	;RA81 UNIT TYPE CODE
IFNDEF .MSR60,<.MSR60==31>	;RA60 UNIT TYPE CODE


;*** INDEX TABLE SYMBOLS (NORMALLY FROM PROLOG) ***

IFNDEF	MXDRNM,<MXDRNM==100>	;RELATES TO MAX NUMBER OF DIRECTORIES
IFNDEF	IDX%IV,<IDX%IV==1B5>	;IDXTAB ENTRY IS INVALID

	NDXPGS==<3*MXDRNM>/2	;NUMBER OF PAGES IN FULL SIZED (PPN) INDEX

	DEFSTR	IDXFB,DATPAG+0,35,18	;POINTER TO FDB FOR THIS DIRECTORY
	DEFSTR	IDXSD,DATPAG+0,17,18	;SUPERIOR DIRECTORY NUMBER
	DEFSTR	IDXIB,DATPAG+1,35,30	;DISK ADDRESS OF INDEX BLOCK OF DIR

;*** PHYSICAL SECTOR ADDRESSING (UNTIL GENERALLY AVAILABLE IN MONSYM) ***

IFNDEF DOP%PS,<DOP%PS==1B13>	;ADDRESS PHYSICAL SECTORS FOR HOME/BATS
	SUBTTL	ENTRY VECTOR AND INITIALIZATION

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



DS:	RESET			;CLEAR EVERYTHING
	$INIT			;INITIALIZE ZSUBS PACKAGE
	SETZ	F,		;CLEAR ALL FLAGS
	TYPE	<DS Disk Utility Program %>	;TYPE BANNER AND VERSION
	SETZM	OJFN		;NO OUTPUT JFN YET
	VERSIO	EVEC+2		;OUTPUT THE VERSION
	TYPE	<

>				;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
	SKIPGE	CKUFLG		;CAN WE USE CKU FORMAT DSKOPS? (-1 = NO)
	 WARN	CKU format DSKOPs are not available
	SKIPG	CKUFLG		;DOES DOP%PS WORK?
	 WARN	Physical sector address DSKOPs (DOP%PS) are not available

REEN:	MOVE	P,[IOWD PDLSIZ,PDL]	;SET UP A STACK
	SETOM	DIRCKU		;INIT DIRECTORY MAP TABLE
	MOVE	T1,[1,,STSINT]	;SETUP CONTROL-A TRANSFER ADDRESS
	MOVEM	T1,CHNTAB+STSCHN ;IN THE CHANNEL PSI TABLE
	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


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
	PARSE	[FLDDB. .CMINI]	;INITIALIZATION FUNCTION
	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
	PARSE	[FLDDB. (.CMKEY,,CMDTAB)] ;POINT TO COMMAND TABLE
	MOVE	T2,0(T2)	;GET ADDRESS OF ROUTINE
	CALL	0(T2)		;CALL IT
	JRST	NEWCMD		;AND GET A NEW COMMAND


;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	DIRECTORY,.DIRECTORY	;DIRECTORY COMMAND
	AA	DRIVE,.DRIVE		;SPECIFY DRIVE TO USE
	AA	DUMP,.DUMP		;DUMP COMMANDS
	AA	EXIT,.EXIT1		;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.


.EXIT1:	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 COMMAND


;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
	CALL	DOFORK		;TRY TO RUN IT
	 ERROR	Cannot get SYS:FILDDT.EXE
	RET			;SUCCESS
	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
	PARSE	[FLDDB. (.CMOFI,,,,<TTY:>)] ;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
	PARSE	[FLDDB. (.CMINI)] ;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...
	PARSE	[FLDDB. (.CMKEY,,DEFTAB)] ;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
	PARSE	[FLDDB. (.CMNUM,CM%SDH,^D10,<Channel number>,<0>)]
	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
	PARSE	[FLDDB. (.CMNUM,CM%SDH,^D10,<Controller number or -1>,<-1>)]
	STOR	T2,DOP%K2,P1	;STORE IN SDBCKU FIELD IN P1
	NOISE	(UNIT)		;MORE APPROPRIATE MUMBLE
	PARSE	[FLDDB. (.CMNUM,CM%SDH,^D10,<Unit number in decimal>,<0>)]
	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
	PARSE	[FLDDB. (.CMDEV,,,,<DSK:>)] ;TRY TO PARSE A DEVICE NAME
	CAMN	T2,[.DVDES+.DVDSK,,-1] ;DSK:?
	 JRST [	GJINF		;JOB INFO - CONNECTED DIR TO T2
		HLRZ	T2,T2	;PUT STR CODE TO RH
		HRLI	T2,.DVDES+.DVDSK ;AND BUILD DESIGNATOR
		JRST	.+1]	;THEN CONTINUE INLINE
	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
	DECOUT	MSBLK+.MSRCH,5	;FIVE DIGITS OF CHANNEL NUMBER

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

	SKIPGE	MSBLK+.MSRCT	;CONTROLLER EXIST?
	 JRST [	PRINT	<      -->	;NO, JUST DO DASHES
		JRST	.+2]		;AND GO ON
	DECOUT	MSBLK+.MSRCT,^D7 ;YES, DO 7 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
	.MSRM3,,[ASCIZ "RM03"]	;11 - RM03
	.MSR20,,[ASCIZ "RP20"]	;24 - RP20
	.MSR80,,[ASCIZ "RA80"]	;27 - RA80
	.MSR81,,[ASCIZ "RA81"]	;30 - RA81
	.MSR60,,[ASCIZ "RA60"]	;31 - RA60

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

	-1,,[ASCIZ "UNK "]	;NO MATCH TO THE ABOVE
	SUBTTL	DIRECTORY COMMAND TO DO INDEX BLOCK ADDRESS DIRECTORY

;THE DIRECTORY COMMAND COMES HERE TO PROCESS AN INDEX BLOCK DIRECTORY
;OF THE SPECIFIED FILESPEC.

.DIRECTORY:
	NOISE	(OF INDEX BLOCK ADDRESSES FOR) ;GUIDE
	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
	PARSE	[FLDDB. (.CMFIL,,,,<*.*.*>)]	;PARSE THE FILESPEC
	MOVEM	T2,JFNTMP	;SAVE JFN FOR NOW
	CONFRM			;CONFIRM THE COMMAND

;NOW DO THE DIRECTORY

	PRINT	<
Index Block Long   Page    Filename
  Address   File?  Count>		;HEADER


;LOOP OVER ALL THE FILES, START WITH XB ADR

DIRECL:	PRINT	<
>				;START ON A NEW LINE
	HRRZ	T1,JFNTMP	;GET THE JFN
	MOVE	T2,[1,,.FBADR]	;WHAT TO READ
	MOVEI	T3,T4		;WHERE TO READ IT
	GTFDB			;READ THE INDEX BLOCK ADDRESS
	 ERJMP	LOSE

	OCTOUT	T4,^D10		;OUTPUT THE LBN

;THE LONG FILE INDICATION

	MOVE	T2,[1,,.FBCTL]	;FLAGS WORD
	MOVEI	T3,T4		;WHERE TO READ IT
	GTFDB			;READ CTL WORD
	 ERJMP	LOSE

	TXNE	T4,FB%LNG	;LONG FILE?
	PRINT	<   Yes >	;YES, SAY SO
	TXNN	T4,FB%LNG	;OTHER SIDE OF FORMATTING
	PRINT	<	 >	;TAB OVER

	;...
;NOW THE PAGE COUNT OF THE FILE FROM THE FDB (NOT NECESSARILY RIGHT)

	MOVE	T2,[1,,.FBBYV]	;SIZE WORD FOR FB%PGC
	MOVEI	T3,T4		;WHERE TO READ IT
	GTFDB			;READ PAGE COUNT
	 ERJMP	LOSE
	LOAD	T4,FB%PGC,T4	;ISOLATE PAGE COUNT

	DECOUT	T4,^D6		;SIX DIGITS
	PRINT	<   >		;AND SPACE OVER

;AND FINALLY THE FILENAME

	PRTJFN	JFNTMP,FULL	;OUTPUT THE FILESPEC TO THE RIGHT PLACE

;NOW STEP THE FILE

	MOVE	T1,JFNTMP	;GET JFN AGAIN
	GNJFN			;STEP IT
	 ERJMP [CAIE	T1,GNJFX1	;NO MORE?
		JRST	LOSE		;SOME OTHER ERROR
		SETZM	JFNBLK+.GJNAM	;CLEAR WILDCARD STUFF
		SETZM	JFNBLK+.GJEXT	; THAT WE STORED
		SETZM	JFNBLK+.GJGEN	; IN THE GTJFN BLOCK
		SETZM	JFNTMP		;MARK UNUSED
		PRINT	<
>					;FINAL BLANK LINE
		RET]			;AND RETURN DONE
	HRRM	T1,JFNTMP	;SAVE THE NEXT JFN

	JRST	DIRECL		;AND LOOP TILL DONE
	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:	PARSE	[FLDDB. (.CMKEY,,DMPTAB)] ;INPUT KEYWORD
	MOVE	T2,0(T2)	;GET THE ADDRESS
	JRST	0(T2)		;TRANSFER AWAY

DMPTAB:	DMPLEN,,DMPLEN		;DUMP TYPES TABLE
	AA	B,.+1,CM%INV+CM%ABR	;EASY TO GET BAT BLOCKS
	AA	BAT-BLOCKS,DMPBAT	;BAT BLOCKS
	AA	BIT-TABLE,DMPBIT	;BITTABLE
	AA	HOME-BLOCKS,DMPHOM	;HOME BLOCKS
	AA	I,.+1,CM%INV+CM%ABR	;EASY TO GET INDEX BLOCKS
	AA	INDEX-BLOCKS,DMPIDX	;FILE INDEX BLOCKS
	AA	INDEX-TABLE,DMPDDX	;INDEX-TABLE.BIN
	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
	PARSE	[FLDDB. (.CMNUM,CM%SDH,^D8,<octal disk address>)]
	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:	SETABT	PAGABT		;SETUP CONTROL-E ABORT ROUTINE
	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	PSIX		;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
>
	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
	PARSE	[FLDDB. (.CMFIL)] ;PARSE THE FILESPEC
	MOVEM	T2,FILJFN	;SAVE THE JFN
	CONFRM			;CONFIRM THE LINE
DMPIDL:	PRINT	<
	Disk Addresses for File > ;HEADER LINE
	PRTJFN	FILJFN		;OUTPUT THE FILESPEC TO THE RIGHT PLACE
	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...
	SETABT	IDXABT		;SETUP CONTROL-E ABORT ROUTINE
	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
	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/]
	NOISE.	0(T2)		;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
	PUSH	P,F		;SAVE FLAGS SO WE CAN
	TXO	F,FL%PHY	;USE ADDRESS STRS UNIT BY UNIT PHYSICALLY
	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
	POP	P,F		;RESTORE SAVED FLAGS
	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	PRDCHK		;READ IN THE PHYSICAL SECTOR
	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	PRDCHK		;READ IN THE PHYSICAL SECTOR
	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/]
	NOISE.	0(T2)		;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
	PUSH	P,F		;SAVE FLAGS SO WE CAN
	TXO	F,FL%PHY	;USE ADDRESS STRS UNIT BY UNIT PHYSICALLY
	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
	POP	P,F		;RESTORE SAVED FLAGS
	RET			; AND FINALLY DONE
;DO EACH INDIVIDUAL UNIT

BATUNT:	TXZ	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	PRDCHK		;READ IN THE PHYSICAL SECTOR
	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	PRDCHK		;READ IN THE PHYSICAL SECTOR
	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/]
	NOISE.	0(T2)		;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:	SETABT	MICABT		;SETUP 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
		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,MXDRMS	;SPECIAL?
	MOVEI	T2,MXDRMS	;NO, USE INDIRECT FILE MESSAGE
	PRINT.	@MICMSG(T2)	;PRINT THE HEADER BLURB
	CAIL	T1,MXDRMS	;GIVE INDIRECT FILE NUMBER?
	JRST  [	SUBI	T1,MXDRMS	;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
	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>]
	MXDRMS==.-MICMSG		;LIMIT VALUE, REST ARE INDIRECT FILES
	[TEXT	<Indirect File #>]	;INDIRECT FILE HEADER LINE
	SUBTTL	DUMP COMMAND FOR BIT-TABLE

;HERE TO DUMP OUT THE SPECIFIED FILE AS IF WERE A VALID BIT-TABLE.

DMPBIT:	NOISE	(FOR)		;GUIDEWORDS
	PARSE	[FLDDB. (.CMNUM,CM%SDH,^D10,<Number of units in structure>,<1>)]
	MOVE	P1,T2		;SAVE VALUE TEMP
	NOISE	(PACK)		;MORE GUIDEWORDS
	PARSE	[FLDDB. (.CMKEY,,TYPTAB,,<RP06>)] ;PARSE UNIT TYPE
	HRRZ	P2,(T2)		;FETCH CODE FROM TABLE
	NOISE	(FROM FILE)	;GUIDEWORDS
	PARSE	[FLDDB. (.CMFIL,,,,<<ROOT-DIRECTORY>DSKBTTBL>)] ;PARSE FILESPEC
	MOVEM	T2,JFNTMP	;SAVE THE JFN FOR A BIT
	CONFRM			;CONFIRM THE COMMAND LINE

;	CALLRET	BITDMP		;PROCESS THE FILE
;
;HERE	P1/  NUMBER OF UNITS IN STR
;	P2/  ADDRESS OF SIZE TABLE
;
;CONVERT TO
;	P1/  -NUMBER OF CYLINDERS,,0
;	P2/  -NUMBER OF WORDS/CYL IN MAP
;	P3/  -NUMBER OF WORDS/CYL,,OFFSET FOR START OF BIT MAP
;	P4/  CALCULATED SIZE OF BITTABLE IN PAGES

BITDMP:	MOVE	P4,1(P2)	;WORDS/CYL (PART TWO)
	AOS	P4		; PLUS ONE (PART ONE)
	IMUL	P4,0(P2)	; TIMES NUMBER OF CYLINDERS
	IMUL	P4,P1		; TIMES NUMBER OF UNITS
	ADDI	P4,PGSIZ-1	;ROUND UP
	LSH	P4,-PGSFT	; AND CONVERT TO PAGES
	IMUL	P1,0(P2)	;TOTAL NUMBER OF CYLINDERS
	MOVE	P3,P1		; AND COPY IT
	MOVN	P1,P1		;NEGATE
	HRLZ	P1,P1		;-# CYL,,0 FOR AOBJN
	MOVN	P2,1(P2)	;-# WORDS/CYL FOR MAP
	HRL	P3,P2		;-# WORDS,,OFFSET FOR MAP

;MAP THE FILE

	HRRZ	T1,JFNTMP	;GET JFN
	MOVX	T2,OF%RD+OF%THW	;OPEN TO READ
	OPENF			;OPEN THE FILE
	 ERJMP	LOSE		; FAILED
	HRLZ	T1,JFNTMP	;FILE,,PAGE ZERO
	MOVE	T2,[.FHSLF,,DATPAG_<-PGSFT>] ;INTO DATPAG
	MOVX	T3,PM%CNT+PM%RD	;BITS
	HRR	T3,P4		;NUMBER OF PAGES
	PMAP			;MAP THE FILE
	 ERJMP	LOSE		; FAILED
	;...

	PRINT	<
Cylinder Free Pages		      Map
-------- ----------		      ---
>				;HEADER

BITD.1:	HRRZ	T1,P1		;CYLINDER NUMBER
	DECOUT	T1,6		;OUTPUT
	PRINT	<	 >	;SPACE
	MOVE	T1,DATPAG(P1)	;LOAD FREE PAGE COUNT FOR CYLINDER
	 ERJMP	BITD.E		;LOUSY FILE
	DECOUT	T1,6		;OUTPUT IT
	PRINT	<    >		;SPACE OVER

;NOW PRINT THE MAP AS OCTAL BITS

	SETABT	BITABT		;SETUP ABORT ADDRESS FOR CONTROL-E
	MOVEI	T4,4		;FOUR WORDS/LINE
BITD.2:	MOVE	T2,DATPAG(P3)	;FETCH WORD
	 ERJMP	BITD.E		;BAD FILE
	SKIPN	T1,OJFN		;SET OUTPUT
	 MOVX	T1,.PRIOU	; PROPERLY
	MOVX	T3,NO%MAG+NO%LFL+NO%ZRO+FLD(^D12,NO%COL)+^D8 ;12 OCTAL DIGITS
	NOUT			;OUTPUT THE WHOLE WORD
	 ERJMP	LOSE
	SOJLE	T4,[MOVEI T4,4	;RESET COUNTER
		PRINT	<
		   >		;SPACING
		JRST	.+1]	;CONTINUE
	PRINT	< >		;SPACING
	AOBJN	P3,BITD.2	;LOOP FOR ALL BIT WORDS FOR THIS CYLINDER
	PRINT	<
>				;NEW LINE
	HRL	P3,P2		;RESET AOBJN LH FOR COUNTER FOR NEXT
	AOBJN	P1,BITD.1	;LOOP FOR ALL CYLINDERS
	PRINT	<
>				;FINISH WITH CRLF
;UNMAP FILE

BITD.3:	SETO	T1,		;UNMAP FILE PAGES
	MOVE	T2,[.FHSLF,,DATPAG_<-PGSFT>] ;FROM DATPAG
	MOVX	T3,PM%CNT	;NUMBER OF PAGES
	HRR	T3,P4		;FROM P4
	PMAP			;UNMAP
	 ERJMP	LOSE
	HRRZ	T1,JFNTMP	;FINISH OFF FILE
	CLOSF			;CLOSE IT
	 ERJMP	LOSE
	SETZM	JFNTMP		;MARK IT
	RET			; AND DONE

BITD.E:	WARN	Missing file page -- terminating bittable dump
	JRST	BITD.3

;HERE ON CONTROL-E ABORT OF BIT TABLE DUMP

BITABT:	MOVX	T1,.PRIOU	;CLEAR
	CFOBF			; THE OUTPUT BUFFER
	 ERJMP	LOSE
	WARN	Bit table dump aborted
	MOVE	P,SAVPSI	;RE-ALIGN THE STACK
	JRST	BITD.3		;AND CLEAN UP ON THE WAY OUT

;TABLE OF UNIT TYPE NAMES, TO INDEX SIZE INFORMATION: # CYLINDERS, WORDS/CYL

TYPTAB:	TYPLEN,,TYPLEN
	AA	RA60,[DEC 2382,<<38*1/1>+35>/36]
	AA	RA80,[DEC  273,<<7*28/1>+35>/36]
	AA	RA81,[DEC 1248,<<161*1/1>+35>/36]
	AA	RM03,[DEC  820,<<30*5/4>+35>/36]
	AA	RP04,[DEC  400,<<19*20/4>+35>/36]
	AA	RP06,[DEC  800,<<19*20/4>+35>/36]
	AA	RP07,[DEC  629,<<43*32/4>+35>/36]
	AA	RP20,[DEC 1119,<<6*30/1>+35>/36]
	TYPLEN==.-TYPTAB-1
	SUBTTL	DUMP COMMAND FOR INDEX-TABLE

;HERE TO DUMP OUT THE CONTENTS OF THE SPECIFIED FILE AS IF IT
;WERE A VALID INDEX-TABLE.BIN.  THE PPN SECTION IS LISTED IF
;THE PROPER PAGES ARE EXISTANT IN THE FILE. (DEPENDS ON CONSTANT
;MXDRNM FROM PROLOG WHICH HAS NEVER CHANGED...).

DMPDDX:	NOISE	(FROM FILE)	;GUIDEWORDS
	PARSE	[FLDDB. (.CMFIL,,,,<<ROOT-DIRECTORY>INDEX-TABLE.BIN>)] ;FILE
	MOVEM	T2,JFNTMP	;SAVE THE JFN FOR A BIT
	CONFRM			;CONFIRM THE COMMAND LINE
	
;	CALLRET	DDXDMP		;DUMP THE FILE

DDXDMP:	HRRZ	T1,JFNTMP	;GET JFN
	MOVX	T2,OF%RD+OF%THW	;OPEN TO READ
	OPENF			;OPEN THE FILE
	 ERJMP	LOSE		; FAILED
	HRLZ	T1,JFNTMP	;FILE,,PAGE ZERO
	MOVE	T2,[.FHSLF,,DATPAG_<-PGSFT>] ;INTO DATPAG
	MOVX	T3,PM%CNT+PM%RD+NDXPGS ;FOR N PAGES
	PMAP			;MAP THE FILE
	 ERJMP	LOSE		; FAILED
	TXZ	F,FL%TMP	;CHECK PPN EXTENSION
	HRLZ	T1,JFNTMP	; BY SEEING IF
	HRRI	T1,NDXPGS-1	; IF THOSE  PAGES
	RPACS			; ARE IN THE FILE
	 ERJMP	LOSE
	TXNE	T2,PA%PEX	;PAGE EXIST?
	 TXO	F,FL%TMP	; YES - DO PPN EXTENSION
	MOVSI	P1,-<MXDRNM*PGSIZ/2>	;BUILD AOBJN POINTER TO INDEX ENTRIES

	SETABT	DDXABT		;SETUP CONTROL-E ABORT
	PRINT	<
Directory  Superior	 FDB	Disk Address of	  PPN of
 Number	   Directory	Offset	 Directory XB	 Directory
>

DDXD.1:	MOVX	T1,IDX%IV	;INVALID ENTRY BIT
	TDNE	T1,1(P1)	;SET?
	 JRST	DDXDMX		; YUP - SKIP THIS ONE

	HRRZ	T4,P1		;GET DIRECTORY NUMBER
	LSH	T4,-1		; TO T4
	LOAD	T3,IDXSD,(P1)	;GET SUPERIOR
	LOAD	T2,IDXFB,(P1)	;GET FDB OFFSET
	LOAD	T1,IDXIB,(P1)	;GET DIR XB DISK ADDRESS
	JUMPE	T1,DDXDMX	; ALSO ASSUME INVALID IF ZERO XB ADR
	PRINT	<
>
	;...

	OCTOUT	T4,6		;OUTPUT DIRECTORY
	PRINT	<	  >	;SPACE OVER
	OCTOUT	T3,6		;OUTPUT SUPERIOR
	PRINT	<       >	;SPACE OVER
	OCTOUT	T2,6		;OUTPUT OFFSET
	PRINT	<	 >	;SPACE OVER
	OCTOUT	T1,^D10		;OUTPUT XB ADR
	TXNE	F,FL%TMP	;PPN TO DO?
	SKIPN	T1,DATPAG+<MXDRNM*PGSIZ>(T4) ;SUPPRESS ZERO PPNS
	 JRST	DDXDMX		; NO - CONTINUE

	PRINT	<	  [>	;OPEN PPN BRACKET
	HLRZ	T1,DATPAG+<MXDRNM*PGSIZ>(T4) ;GET PPN LH
	OCTOUT	T1		;OUTPUT
	PRINT	<,>		;COMMA
	HRRZ	T1,DATPAG+<MXDRNM*PGSIZ>(T4) ; GET PPN RH
	OCTOUT	T1		;OUTPUT
	PRINT	<]>		;CLOSE BRACKET
DDXDMX:	AOJA	P1,.+1		;TWO WORD ENTRIES
	AOBJN	P1,DDXD.1	; TO LOOP OVER

	PRINT	<
>				;END WITH FINAL CRLF
DDXDME:	SETO	T1,		;UNMAP FILE PAGES
	MOVE	T2,[.FHSLF,,DATPAG_<-PGSFT>] ;FROM DATPAG
	MOVX	T3,PM%CNT+NDXPGS ;NUMBER OF PAGES
	PMAP			;UNMAP
	 ERJMP	LOSE
	HRRZ	T1,JFNTMP	;FINISH OFF FILE
	CLOSF			;CLOSE IT
	 ERJMP	LOSE
	SETZM	JFNTMP		;MARK IT
	RET			; AND RETURN



;HERE ON CONTROL-E ABORT OF INDEX TABLE DUMP

DDXABT:	MOVX	T1,.PRIOU	;CLEAR
	CFOBF			; THE OUTPUT BUFFER
	 ERJMP	LOSE
	WARN	Directory index table dump aborted
	MOVE	P,SAVPSI	;RE-ALIGN THE STACK
	JRST	DDXDME		;AND CLEAN UP ON THE WAY OUT
	SUBTTL	CHECK COMMANDS, CHECK PAGE

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

.CHECK:	PARSE	[FLDDB. (.CMKEY,,CHETAB)] ;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
	PARSE	[FLDDB. (.CMNUM,CM%SDH,^D8,<octal disk address>)]
	MOVE	P1,T2		;SAVE FOR CONFIRM
	NOISE	(NUMBER OF TIMES) ;DO GUIDEWORDS
	PARSE	[FLDDB. (.CMNUM,CM%SDH,^D10,<times to repeat>,<1>,[
		    FLDDB. (.CMKEY,,<[1,,1	;KEYWORD TABLE OF ONE
				 AA	(<UNTIL-STOPPED>,<0>)]>)])] ;ONLY ENTRY
	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
	SETABT	CHPABT		;SETUP CONTROL-E ABORT ROUTINE
	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
	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
	PARSE	[FLDDB. (.CMNUM,CM%SDH,^D8,<octal disk 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
	PARSE	[FLDDB. (.CMFIL,,,,<*.*.*>)]	;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
	SETABT	REDABT		;SETUP CONTROL-E ABORT ROUTINE
	SETZ	P4,		;START WITH NO ERRORS

CMDRE1:	TYPE	<
[Attempting to read file >	;TELL NAME FOR EACH
	TYPJFN	FILJFN		;TYPE OUT THE FILSPEC
	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:	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:	PARSE	[FLDDB. (.CMKEY,,CPYTAB,,<FILE>)] ;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/]
	NOISE.	0(T2)		;HANDLE THE GUIDEWORDS
	PARSE	[FLDDB. (.CMNUM,CM%SDH,^D8,<octal disk address>)]
	MOVEM	T2,P1		;SAVE ADDRESS FOR NOW
	NOISE	(TO)
	MOVX	T2,GJ%MSG	;CONFIRMATION MESSAGE
	MOVEM	T2,JFNBLK+.GJGEN ;SETUP FILE TYPE
	PARSE	[FLDDB. (.CMFIL)] ;PARSE A FILESPEC
	MOVEM	T2,JFNTMP	;SAVE THE JFN FOR A BIT
	TXNE	F,FL%TMP	;JUST A PAGE?
	 JRST [	NOISE	(PAGE)	;NOISE FOR WHICH PAGE
		PARSE	[FLDDB.	(.CMNUM,CM%SDH,^D10,<decimal file page>,<0>)]
		MOVEM	T2,P4	;SAVE THE VALUE
		JRST	.+1]	; AND CONTINUE IN-LINE
	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
	DVCHR			;GET DEVICE CHARACTERISTICS
	 ERJMP	LOSE
	LOAD	T2,DV%TYP,T2	;FETCH THE DEVICE TYPE
	CAIE	T2,.DVDSK	; WHICH HAD BETTER BE A DISK
	CAIN	T2,.DVTTY	; OR TTY
	 SKIPA			;WAS
	  ERROR	Output must be to a disk or terminal device
	TXZ	F,FL%TTY	;CLEAR TTY FLAG
	CAIN	T2,.DVTTY	;TTY?
	TXO	F,FL%TTY	;YES, REMEMBER FOR LATER
	HRRZ	T1,CJFN		;GET THE JFN BACK AGAIN
	MOVX	T2,FLD(7,OF%BSZ)+OF%RD+OF%WR ;OPEN TO WRITE, BYTE SIZE FOR TTY
	OPENF			;TRY THE OPEN
	 ERJMP	LOSE
	;...
	;...

	SETZM	JFNTMP		;FINALLY  MARK TEMP SLOT CLEAR
	SETABT	COPABT		;SETUP CONTROL-E ABORT
	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:	TXNE	F,FL%TTY	;OUTPUT TO TTY?
	 JRST [	MOVE	T1,CJFN	;YES, OUTPUT JFN
		HRROI	T2,DATPAG ;FROM DATPAG
		MOVNI	T3,PGSIZ*5 ;NUMBER OF BYTES
		SOUT		;OUTPUT IT
		 ERJMP	LOSE
		JRST	CMDCP6]	;AND CONTINUE
	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
	TXNE	F,FL%TMP	;SPECIAL PAGE GIVEN?
	HRR	T2,P4		; YES, USE IT
	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

	TXNE	F,FL%TTY	;TTY?
	 JRST	CMDCP9		;YES, SKIP FDB STUFF
	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
CMDCP9:	HRRZ	T1,CJFN		;GET BACK JFN
	CLOSF			;CLOSE THE FILE
	 ERJMP	LOSE
	CLRABT			;CLEAR CONTROL-E ABORT
	TYPE	<
[COPY completed]>
	RET			;AND THEN WE ARE DONE




;COPABT - TRANSFER TO HERE ON CONTROL-E TO FINISH ABORTING COPY

COPABT:	MOVX	T1,.PRIOU	;PRESUME TO 
	CFOBF			;CLEAR THE OUTPUT
	 ERJMP	LOSE
	WARN	COPY aborted
	HRRZ	T1,CJFN		;FETCH THE COPY JFN
	TXO	T1,CZ%ABT	;ABORT CLOSE
	CLOSF			;FLUSH IT
	 ERJMP	LOSE
	MOVE	P,SAVPSI	;PICK UP THE RIGHT STACK
	RET			; AND TERMINATE THE COMMAND




;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
	PARSE	[FLDBK. (.CMFLD,CM%BRK!CM%SDH,,<directory name>,,[
		BRMSK. (USRB0.,USRB1.,USRB2.,USRB3.)])]
	MOVE	T1,[ATMBUF,,DIRSTR] ;BLT POINTER
	BLT	T1,DIRSTR+7	;COPY THE STRING
	MOVEI	T2,[FLDDB. (.CMOFI)]
	NOISE	(TO)		;GUIDE ON
	PARSE	[FLDDB. (.CMOFI)] ;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 (LEAVE TMP FOR CLEANUP ON PROBS)
	MOVX	T2,OF%WR	;TO WRITE ONLY
	OPENF			;OPEN THE FILE
	 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

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

	SETABT	DIRABT		;SETUP CONTROL-E ROUTINE ADDRESS
	MOVE	T1,[.TICCA,,STSCHN] ;ACTIVATE
	ATI			; STATUS ON ^A
	 ERJMP	LOSE

	;...
;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
	SETZM	ERRCNT		;START WITH NO ERRORS
	MOVN	P1,SDBCNT	;SETUP TO AOBJN
	HRLZ	P1,P1		; OVER ALL UNITS IN SDB

DCLOOP:	CALL	SETSWP		;SETUP SRCBLK WITH SWAP SPACE LIMITS
	HRRZ	T1,P1		;LOGICAL UNIT NUMBER
	IMUL	T1,SDBSIZ	;TIMES SIZE EQUALS BEGIN ADDRESS
	MOVE	T2,SRCBLK	;AND GET START OF SWAP SPACE AS END
	MOVEI	T3,COCOPY	;COROUTINE ADDRESS
	CALL	SCAN		;SCAN THE FIRST PART OF THE UNIT
	MOVE	T1,SRCBLK+1	;THEN START AT END OF SWAP SPACE
	ADD	T1,SDBSPP	; AT THE NEXT PAGE
	HRRZ	T2,P1		;CREATE LAST ADDRESS
	AOS	T2		; FROM
	IMUL	T2,SDBSIZ	; UNIT NUMBER + 1 * SIZE - SEC/PAG
	SUB	T2,SDBSPP	;SUBTRACT ONE PAGE WORTH OF SECTORS
	MOVEI	T3,COCOPY	;COROUTINE ADDRESS
	CALL	SCAN		;SCAN FROM END OF SWAP SPACE TO END OF UNIT
	AOBJN	P1,DCLOOP	;AND LOOP OVER ALL UNITS

	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:	CALL	DIRDON		;TURN INTERRUPTS BACK OFF
	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
	CAIN	T1,-1		;SYMBOL TABLE PAGE MAYBE?
	 JRST [	WARN	<Possible directory symbol table page at disk address >
		TOCT	DIRMAP+1(P1) ;GIVE ADDRESS
		TYPE	<
>				;CRLF
		JRST	DIRCLX]	; AND LOOP
	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:	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
	MOVSI	T3,-PGSIZ	;SET TO LOOP OVER PAGE
	HRR	T3,T2		;ADDRESS OF START
COCOP1:	HLRZ	T1,0(T3)	;FETCH NEXT WORD
	CAIE	T1,SYMCOD	;SYMBOL TABLE HERE?
	AOBJN	T3,COCOP1	; NO, LOOP
	SKIPGE	T3		;FOUND ONE?
	 CALL	MRKSYM		; 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

;HERE TO MARK SYMBOL TABLE PAGES (ACCOMMODATE MONITOR BUG)

MRKSYM:	HRRO	T4,0(T3)	;GET -1,,DIRECTORY NUMBER
	SKIPA			;ENTER COMMON CODE

;HERE TO MARK DIRECTORY PAGES IN DIRMAP

MRKDIR:	MOVE	T4,1(T2)	;GET REL DIR PAGE #,,DIR #
	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
	MOVEM	T4,DIRMAP(T1)	;SAVE IT IN FIRST WORD OF ENTRY
	TLNN	T4,-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
	PARSE	[FLDDB. (.CMNUM,CM%SDH,^D8,<disk address>,<0>,[
		    FLDDB. (.CMKEY,,<[1,,1	;KEYWORD TABLE OF ONE
				 AA	(<SWAPPING-SPACE>,<0>)]>)])] ;ONLY ENTRY
	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
	PARSE	[FLDDB. (.CMNUM,CM%SDH,^D8,<disk address, -1 for all>,<-1>)]
	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
	TDEC	T2		;TYPE IN DECIMAL
	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
	TDEC	T2		;DO THE CONTROLLER
	TYPE	<, Unit >	;NOW THE UNIT
	LOAD	T2,DOP%U2,T1	;FETCH IT
	TDEC	T2		;ALSO DECIMAL
	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:	SETABT	VERABT		;SETUP CONTROL-E ABORT ROUTINE
	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:	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
	PARSE	[FLDDB. (.CMNUM,CM%SDH,^D8,<starting disk address>,<0>)]
	MOVEM	T2,SRCBLK+2	;BEGIN ADR IN THIRD WORD
	NOISE	(ENDING AT)	;GUIDE
	PARSE	[FLDDB. (.CMNUM,CM%SDH,^D8,<ending disk address>,<-1>)]
	MOVEM	T2,SRCBLK+3	;AND END ADR IN FOURTH WORD
	CONFRM			;CONFIRM THE COMMAND

	CALL	CHKUSE		;MAKE SURE WE HAVE USABLE STUFF
	SETABT	SRCABT		;SETUP CONTROL-E ABORT ROUTINE
	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:	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
	PARSE	[FLDDB. (.CMNUM,,^D8)] ;OCTAL OFFSET
	MOVE	P2,T2		;SAVE THE NUMBER IN P2 TIL CONFIRMED
	NOISE	(IN PAGE AT DISK ADDRESS) ;MORE QUIDEWORDS
	PARSE	[FLDDB. (.CMNUM,CM%SDH,^D8,<octal disk address>)]
	MOVE	P1,T2		;SAVE IN P1 FOR CONFIRM
	NOISE	(WITH INTERVAL OF) ;MORE GUIDEWORDS
	PARSE	[FLDDB. (.CMNUM,CM%SDH,^D10,<number of milliseconds>,<1000>)]
	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
	SETABT	WATABT		;SETUP CONTROL-E ABORT ROUTINE
	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	RDCHK - ROUTINE TO READ IN AND CHECK DISK PAGE

;RDCHK - ROUTINE TO READ IN AND CHECK A GIVEN PAGE OF THE DISK.
;PRDCHK - ROUTINE TO DO PHYSICAL SECTOR READS ALA RDCHK
;  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	OR	CALL	PRDCHK
;
;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.

PRDCHK:	TXOA	F,DS%PS		;SET PHYSICAL SECTOR BIT
RDCHK:	TXZ	F,DS%PS		;CLEAR PHYSICAL SECTOR BIT
	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
;	       DS%PS  ON MEANS PHYSICAL SECTOR ADDRESSING (HOM/BAT)
;  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:	SKIPL	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
	SKIPGE	CKUFLG		; AND IF SO
	 SKIPA			; THEN
	TXO	T2,DOP%NF	;SET CKU FORMAT FLAG
	TXNE	F,DS%PS		;PHYSICAL SECTOR?
	SKIPG	CKUFLG		;HAVE THE CAPABILITY?
	 SKIPA			; NO TO ONE OR THE OTHER
	TXO	T2,DOP%PS	;YES
	MOVE	T3,LSTDST	;WHERE TO READ IT
	DSKOP			;DO IT
	 ERJMP	LOSE		;FAILURE
	RET			;RETURN TO CALLER
	SUBTTL	CKUINI - ROUTINE TO INITIALIZE CKUFLG STATE
;CKUINI - ROUTINE TO INITIALIZE CKUFLG TO THE PROPER STATE:
;   -1 FOR NO CKU FORMAT AVAILABLE,
;    0 FOR CKU FORMAT, BUT NO DOP%PS AVAILABLE
;   +1 FOR CKU FORMAT AND DOP%PS AVAILABLE
;
;	CALL	CKUINI
;
;RETURNS  +1:	ALWAYS, WITH CKUFLG SET
;USES T1-T4.

CKUINI:	SETOM	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 TEST DSKOPS

	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	CKUI.0		;HANDLE ERROR
CKUERR:	TYPE	<
? DSKOP characterization failed!> ;TRY TO EXPLAIN
	HALTF			;THEN GET OUT
	 JRST	.-1		; AND STAY OUT

CKUI.0:	MOVX	T1,.FHSLF	;WE WANT TO GET
	GETER			; OUR LAST ERROR
	HRRZS	T2		;ISOLATE ERROR CODE
	CAIN	T2,DECRSV	;"DEC RESERVED BITS NOT ZERO"?
	 RET			; YES, RETURN -1
	SETZM	CKUFLG		;NO!  CAN USE CKU FORMAT
	MOVX	T1,FLD(.DOPPU,DOP%AT) ;PHYSICAL FORMAT DSKOP
	MOVX	T2,DOP%PS!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	CKUI.1		;HANDLE ERROR
	JRST	CKUERR		;BAD NEWS...

CKUI.1:	MOVX	T1,.FHSLF	;WE WANT TO GET
	GETER			; OUR LAST ERROR
	HRRZS	T2		;ISOLATE ERROR CODE
	CAIN	T2,DECRSV	;"DEC RESERVED BITS NOT ZERO"?
	 RET			; YES, RETURN 0
	AOS	CKUFLG		;NO!  CAN USE DOP%PS
	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	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		;SETUP PROPER
	 MOVX	T1,.PRIOU	; OUTPUT DESIGNATOR
	MOVE	T3,T2		;COPY THE WORD
	MOVEI	T4,6		;NUMBER OF CHARACTERS TO DO
PSIX.1:	SETZ	T2,		;CLEAR T2
	LSHC	T2,6		;SHIFT UP A BYTE
	ADDI	T2," "-' '	;MAKE INTO ASCII
	BOUT			;OUTPUT THE CHARACTER
	SOJG	T4,PSIX.1	;AND LOOP FOR SIX
	RET			; THEN RETURN


;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 FLAGS ARE MS%LIM,MS%RWS,MS%RWD,MS%CRY

PHFLGS:	SKIPN	T2		;ANYTHING?
	 PRINT	<No Flags Set: Unlimited Directories, No Verification>
	TXZE	T2,MS%LIM	;LIMIT FLAG SET?
	 PRINT	<MS%LIM - Directories are limited to 2040/50 size>
	TXNE	T2,MS%RWS	;RAW FOR SWAP SPACE?
	 PRINT	<
		MS%RWS - Read after write verification for swapping space>
	TXNE	T2,MS%RWD	;RAW FOR DATA?
	 PRINT	<
		MS%RWD - Read after write verification for data>
	TXNE	T2,MS%CRY	;PASSWORD ENCRYPTION FOR STR?
	 PRINT	<
		MS%CRY - Password encryption enabled>
	RET			;ALL FOR NOW


;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
	PARSE	PARFL1		;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
	PARSE	[FLDDB. (.CMNUM,CM%SDH,^D8,<right half>,<0>)]
	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	THE DATA AREA

	XLIST			;DUMP THE LITERALS
DSLITS:	LIT
	LIST


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

PIACS:	BLOCK	20		;SAVED ACS DURING STATUS PSI
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
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

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>