Google
 

Trailing-Edge - PDP-10 Archives - BB-H311B-RM - swskit-utilities/dskerr.mac
There are 5 other files named dskerr.mac in the archive. Click here to see a list.
	TITLE	DSKERR	PRODUCE COMPACT LISTING OF DISK ERRORS
	SUBTTL	J. G. ZIMA/JGZ	JANUARY 1979

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


;VERSION INFORMATION:


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



;	TABLE OF CONTENTS FOR DSKERR				  PAGE
;	----------------------------				  ----
;
;  1. J. G. ZIMA/JGZ JANUARY 1979. . . . . . . . . . . . . . . . .   1
;  2. COMMAND SCANNER AND INITIALIZATION . . . . . . . . . . . . .   5
;  3. THE SIMPLE COMMANDS. . . . . . . . . . . . . . . . . . . . .   7
;  4. PARAMETER SETTING AND SHOWING COMMANDS . . . . . . . . . . .  10
;  5. THE MAIN PROCESSING LOOP . . . . . . . . . . . . . . . . . .  17
;  6. ENTRY INPUT AND VALIDATION ROUTINES. . . . . . . . . . . . .  19
;  7. OUTPUT CONVERSION ROUTINES . . . . . . . . . . . . . . . . .  23
;  8. PAGE HEADER PRINTING ROUTINE . . . . . . . . . . . . . . . .  27
;  9. VERSION NUMBER PRINTING. . . . . . . . . . . . . . . . . . .  28
; 10. SUMMARY PRINTING ROUTINE . . . . . . . . . . . . . . . . . .  29
; 11. ERROR PROCESSING AND COMND HELPER ROUTINES . . . . . . . . .  30
; 12. THE DATA AREA. . . . . . . . . . . . . . . . . . . . . . . .  32
;REVISION HISTORY:
;
;   21	JGZ	8-FEB-79
;		BETTER FILE HANDLING ON EOF OR ERROR MARKER ENTRIES.
;
;   22	JGZ	9-FEB-79
;		ADD DRIVE COMMAND TO SELECT ENTRIES FROM A CERTAIN
;		DRIVE SERIAL NUMBER.
;
;   23	JGZ	15-FEB-79
;		CHANGE FLAG NAMING CONVENTION.
;
;   24	JGZ	20-FEB-79
;		ADD QUOTED STRING FUNCTION TO VOLUME COMMAND TO ALLOW
;		THINGS LIKE SPECIFYING BLANK VOLUME ID.
;
;   25	JGZ	22-FEB-79
;		ADD CONTROL-E INTERRUPT FEATURE TO ALLOW ABORTING THE
;		LIST COMMAND IN THE MIDDLE AND GET BACK TO COMMAND LEVEL.
;
;   26	JGZ	22-FEB-79
;		MAKE ALL SETTINGS BUT INPUT FILE SPECIFIED PRESERVED
;		ACROSS ERRORS.  FORMERLY, ALL FLAGS CLEARED.
;
;   27	JGZ	24-FEB-79
;		MAKE INPUT FILE SPECIFIED PRESERVED ALSO.
;
;   30	JGZ	9-MAR-79
;		ADD PUSH COMMAND.
;
;   31	JGZ	10-MAR-79
;		ADD TAKE COMMAND.
;
;   32	JGZ	29-JUN-79
;		WARN, RESYNCH, AND CONTINUE ON LOSS OF SYNCHRONIZATION.
;
;   33	JGZ	27-JAN-80
;		ADD RP20 TO TABLES, RANGE CHECK DEVICE TYPE.
;
;ACCUMULATORS:

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



;DEFAULT PARAMETERS:


	TXTLEN==^D100		;SIZE OF COMMAND BUFFERS
	PDLSIZ==30		;SIZE OF PUSHDOWN STACK
	PAGSIZ==^D55		;NUMBER OF LINES/PAGE
	VTBSIZ==20		;NUMBER OF VOLUMES IN SUMMARY MAX



;CONSTANTS:


	IS.ERR==1B2		;BIT IN IORB INDICATING HARD ERROR

	HF.ERR==377		;ENTRY TYPE INDICATING ERROR IN FILE
	HF.EOF==777		;ENTRY TYPE INDICATING END-OF-FILE
	HF.T20==1B17		;ENTRY HEADER BIT FOR TOPS-20
	HF.VER==1		;SYSERR VERSION WE KNOW ABOUT
	HDRDAT==1		;OFFSET TO DATE-TIME WORD
	SEROFF==MB%REG+10	;OFFSET TO SERIAL #

	SIZSUM==4		;SIZE OF A SUMTAB ENTRY
		VSUM==0			;OFFSET OF VOLUME ID IN SUMTAB ENTRY
		HSUM==1			;OFFSET OF HARD ERRORS IN SUMTAB ENTRY
		SSUM==2			;OFFSET OF SOFT ERRORS IN SUMTAB ENTRY
		USUM==3			;OFFSET OF UNIT TYPE IN SUMTAB ENTRY

	INTCHN==0		;CHANNEL FOR ^E INTERRUPT
;FLAGS:


	FL%TIM==1B0		;CHECK ENTRIES FOR TIME RANGE
	FL%VOL==1B1		;CHECK ENTRIES TO MATCH VOLUME ID
	FL%SSE==1B2		;SUPPRESS SOFT ERRORS
	FL%SHE==1B3		;SUPPRESS HARD ERRORS
	FL%IFS==1B4		;INPUT FILE SPECIFIED
	FL%SUM==1B5		;SUMMARY OUTPUT ONLY
	FL%TMV==1B6		;TOO MANY VOLUMES FOR SUMTAB
	FL%FDO==1B7		;FORCE DATE OUTPUT AT START OF PAGE
	FL%OFO==1B8		;OUTPUT FILE IS OPEN
	FL%SER==1B9		;CHECK ENTRIES TO MATCH DRIVE SERIAL NUMBER


;MACROS, OPDEFS, AND DEFSTRS:


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


	DEFINE	SPACE(NUMBER),<		;;MACRO FOR NUMBER OF SPACES
	MOVEI	P1,NUMBER		;;GET THE NUMBER
	CALL	SPCOUT			;;DO THE SPACES
>


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


	DEFSTR	F%SER,T2,35,16		;SERIAL NUMBER
	DEFSTR	F%TYP,T2,35,5		;UNIT TYPE
	DEFSTR	HDRLEN,HDRWRD,26,3	;HEADER LENGTH FIELD
	DEFSTR	ENTLEN,HDRWRD,35,9	;ENTRY LENGTH FIELD
	DEFSTR	HDRCOD,HDRWRD,8,9	;ENTRY TYPE CODE
	DEFSTR	HDRVER,HDRWRD,23,6	;VERSION LEVEL
	SUBTTL	COMMAND SCANNER AND INITIALIZATION




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




DSKERR:
REEN:	RESET			;CLEAR EVERYTHING
	MOVE	P,[IOWD PDLSIZ,PDL]	;SET UP A STACK
	TXZ	F,FL%TMV!FL%FDO!FL%OFO	;INITIALIZE FLAGS
	SETZM	OLDPRM		;CLEAR PRIMARY I/O SAVE CELL
	SETZM	TAKJFN		;CLEAR TAKE FILE JFN/STATE
	MOVX	T1,.FHSLF	;SETUP THE
	MOVE	T2,[LEVTAB,,CHNTAB] ; INTERRUPT SYSTEM
	SIR
	MOVX	T1,.FHSLF	;AND ACTIVATE
	MOVX	T2,1B<INTCHN>	;THE CHANNEL TO USE FOR ^E INTERRUPTS
	AIC
	MOVX	T1,.FHSLF	;AND FINALLY
	EIR			; TURN IT ON, WITH NOTHING ON THE CHANNEL


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


NEWPAR:	MOVE	P,SAVEP		;RESTORE THE STACK
	MOVEI	T1,CMDBLK	;POINT TO THE COMMAND BLOCK
	MOVEI	T2,[FLDDB. (.CMKEY,,CMDTAB)]	;POINT TO COMMAND TABLE
	CALL	COMMND		;READ IT
	MOVE	T2,(T2)		;GET ADDRESS OF ROUTINE
	CALL	(T2)		;CALL IT
	JRST	NEWCMD		;AND GET A NEW COMMAND


RSKP:	AOS	0(P)		;YE OLDE
R:	RET			;SKIP RETURN

;TABLE OF COMMANDS:


CMDTAB:	CMDLEN,,CMDLEN			;HEADER
	AA	DRIVE,CMDDRI		;SET DRIVE ID TO MATCH
	AA	EXIT,CMDXIT		;EXIT COMMAND
	AA	HELP,CMDHLP		;TYPE HELP MESSAGE
	AA	LIST,CMDLST		;SET UP OUTPUT SPEC
	AA	PUSH,CMDPSH		;PUSH TO A NEW EXEC
	AA	READ,CMDRED		;SET UP INPUT SPEC
	AA	SUPPRESS,CMDSUP		;SET SUPRESS FLAGS
	AA	TAKE,CMDTAK		;TAKE COMMANDS FROM FILE
	AA	TIME,CMDTIM		;SET BEGIN AND END TIMES
	AA	VOLUME,CMDVOL		;SET VOLUME ID TO MATCH
	AA	WHAT,CMDWHT		;TELL SETTINGS

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



;EXIT FROM PROGRAM.  "EXIT" COMMAND.


CMDXIT:	MOVEI	T2,[ASCIZ/FROM PROGRAM/]	;GET NOISE
	CALL	NOISE		;EAT NOISE WORDS
	CALL	CONFRM		;THEN CONFIRM THE COMMAND
	HALTF			;QUIT FOR THE NONCE
	RET			;RETURN FOR A NEW COMMAND



;THE "HELP" COMMAND.


CMDHLP:	CALL	CONFRM		;CONFIRM THE LINE
	HRROI	T1,HLPTXT	;POINT TO HELP MESSAGE
	PSOUT			;TYPE IT
	RET			;AND RETURN


HLPTXT:	TEXT<

     DSKERR is a program designed to produce a compact listing of  the
hard  and soft disk errors recorded for the system in the SYSERR file.
The listing contains the time an error occurred, the structure it  was
on, the serial number of the drive in use, the logical block number of
the error on the unit, the cylinder, surface and sector of the  error,
the  number  of  retries,  and  whether  it was a hard (unrecoverable)
error.  A by-volume summary gives the structure name, unit  type,  and
accumulated hard and soft error totals.

     The commands are:

	DRIVE		Specify specific drive serial number to list
				or ALL for all drives
        EXIT            Exit from the program
        HELP            Type this text
        LIST            Specify output file and begin processing
				May be aborted with Control-E
	PUSH		Push command level to a new EXEC
        READ            Specify alternate input ERROR.SYS format file
        SUPPRESS        Suppress listing of hard errors, or soft
                                errors, or detailed by error listing
                                section, or nothing
	TAKE		Take commands from specified file
        TIME            Set begin and end times for searching input
        VOLUME          Specify specific single structure to list or
                                * to do all structures
        WHAT            Tell current parameter settings
>

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

CMDPSH:	MOVEI	T2,[ASCIZ/COMMAND LEVEL/]	;GET NOISE
	CALL	NOISE		;PRINT IT
	CALL	CONFRM		;CONFIRM THE COMMAND
	MOVX	T1,GJ%PHY!GJ%OLD!GJ%SHT	;GTJFN BITS
	HRROI	T2,[ASCIZ/SYSTEM:EXEC.EXE/]	;FILENAME FOR EXEC
	GTJFN			;GET A HANDLE ON THE FILE
	 ERJMP	LOSE		;UNAVAILABLE???
	MOVEM	T1,JFNX		;SAVE JFN TO IT
	MOVX	T1,CR%CAP	;PRESERVE OUR CAPABILITIES
	CFORK			;BUILD A FORK
	 ERJMP	LOSE		;COULDN'T
	MOVEM	T1,HANDLE	;SAVE FORK HANDLE
	MOVSS	T1		;HANDLE TO LEFT HALF
	HRR	T1,JFNX		;JFN TO RIGHT
	GET			;GET THE FILE
	 ERJMP	LOSE		;COULDN'T
	MOVE	T1,HANDLE	;FETCH FORK HANDLE
	SETZ	T2,		;NORMAL START
	SFRKV			;START THE FORK UP
	 ERJMP	LOSE		;CAN'T
	WFORK			;WAIT FOR IT TO COME BACK
	 ERJMP	LOSE		;TROUBLE
	KFORK			;IS DONE, SO KILL IT
	 ERJMP	LOSE		;FAILED
	SETZM	HANDLE		;NO MORE FORK
	RET			; AND COMMAND IS FINISHED
;TAKE COMMAND TO READ COMMAND FROM DESIGNATED FILE BY SETTING UP
;THE PRIMARY I/O JFNS TO POINT TO THE FILE.
;UNTAKE ROUTINE CALLED TO RESET THE STATE WHEN THE END OF THE TAKE
;FILE IS ENCOUNTERED.

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


;UNTAKE ROUTINE CALLED TO UNDO THE EFFECTS OF THE TAKE COMMAND
;RESETS THE PRIMARY I/O AND CLEANS UP THE JFN.

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

;VOLUME COMMAND TO SET VOLUME ID TO MATCH


CMDVOL:	MOVEI	T2,[ASCIZ/ID TO LIST ERRORS FOR/]
	CALL	NOISE		;PROCESS THE NOISE
	MOVEI	T2,[FLDDB. (.CMQST,CM%SDH,,<Optionally quoted Volume ID or * for all>,<*>,[
		FLDDB. (.CMTXT,CM%SDH)])]
	CALL	COMMND		;READ IT
	MOVE	T1,[POINT 6,T4]	;POINTER TO OUTPUT
	MOVE	T2,[POINT 7,ATMBUF]	;POINTER TO INPUT
	MOVEI	P1,6		;COUNTER
	SETZ	T4,		;START CLEAR
SIXL:	ILDB	T3,T2		;GET NEXT BYTE
	CAIL	T3,"A"+40	;ASSURE CASE CONVERSION
	CAILE	T3,"Z"+40	;FIRST
	SKIPA
	SUBI	T3,40		;TO UPPER CASE
	CAIL	T3," "		;CHECK SIXBIT RANGE
	CAILE	T3," "+100	;ALL ALLOWED
	JRST	SIXFIN		;NO GOOD--MUST BE DONE
	SUBI	T3," "		;MAKE SIXBIT
	IDPB	T3,T1		;STORE
	SOJG	P1,SIXL		;ONLY TAKE SIX
SIXFIN:	TXO	F,FL%VOL	;REMEMBER
	MOVEM	T4,VOLIDM	;STORE NAME
	CAMN	T4,[SIXBIT/*/]	;CLEARING?
	TXZ	F,FL%VOL	;YES
	MOVEI	T1,CMDBLK	;RESTORE GARBAGED COMND ARG
	CALL	CONFRM		;CONFIRM THE LINE
	RET			;AND RETURN

;SUPPRESS COMMAND TO SET ERROR TYPE TO SUPPRESS


CMDSUP:	MOVEI	T2,[FLDDB. (.CMKEY,,HRDTAB,,<NOTHING>)]	;SETUP
	CALL	COMMND		;KEYWORD INPUT
	HRRZ	T4,(T2)		;VALUE
	CALL	CONFRM		;CONFIRM THE LINE
	XCT	[TXZ	F,FL%SSE+FL%SHE+FL%SUM ;SUPPRESS NOTHING
		 TXO	F,FL%SHE	;HARD
		 TXO	F,FL%SSE	;SOFT
		 TXO	F,FL%SUM](T4)	;MAIN LISTING
	RET		;AND RETURN


HRDTAB:	HRDLEN,,HRDLEN		;ERROR SUPPRESSION TABLE
	AA	DETAIL-LISTING,3;DETAILED LISTING SECTION
	AA	HARD-ERRORS,1	;HARD ERRORS
	AA	NOTHING,0	;NO ERRORS (DEFAULT)
	AA	SOFT-ERRORS,2	;SOFT ERRORS

	HRDLEN==.-HRDTAB-1

;WHAT COMMAND TO TELL SWITCH SETTINGS


CMDWHT:	MOVEI	T2,[ASCIZ/ARE PARAMETER SETTINGS/]	;NOISE
	CALL	NOISE		;PROCESS IT
	CALL	CONFRM		;CONFIRM IT
	TMSG<
Suppress >			;ERROR SUPRESSION
	HRROI	T1,[ASCIZ/No/]	;DEFAULT
	TXNE	F,FL%SSE	;SOFT?
	HRROI	T1,[ASCIZ/Soft/];YES
	TXNE	F,FL%SHE	;HARD?
	HRROI	T1,[ASCIZ/Hard/];YES
	TXC	F,FL%SHE+FL%SSE	;CHECK
	TXCE	F,FL%SHE+FL%SSE	; FOR BOTH ON
	SKIPA
	HRROI	T1,[ASCIZ/All/]	;BOTH
	PSOUT
	TMSG< Errors>		;END LINE
	TMSG<
Drive Serial Number to Report: >
	TXNE	F,FL%SER	;ALL?
	JRST	CMDWH0		;NO
	TMSG<All drives>	;YES--SAY SO
	JRST	CMDWH1		;AND CONTINUE
CMDWH0:	MOVE	P1,SERNOM	;FETCH THE SERIAL NUMBER
	MOVEI	T1,.PRIOU	; AND GET THE JFN
	CALL	SEROUX		; TO TYPE IT
CMDWH1:	TMSG<
Volume ID to Report: >		;VOLUMES
	TXNE	F,FL%VOL	;ALL?
	JRST	CMDWH2		;NO
	TMSG<All Volumes>	;YES
	JRST	CMDWH3		;AND CONTINUE
CMDWH2:	MOVE	P1,VOLIDM	;GET VOLUME NAME
	MOVEI	T1,.PRIOU	; AND THE JFN
	CALL	VOLOUX		; TO TYPE IT
CMDWH3:	TXNN	F,FL%TIM	;RANGES OF TIME?
	JRST	CMDWH4		;NOT SET
	TMSG<
Time Settings:	Begin: >	;SET--TYPE THEM
	MOVEI	T1,.PRIOU
	MOVE	T2,BGNTIM
	SETZ	T3,
	ODTIM
	 ERJMP	LOSE
	TMSG<
		End:   >	;AND END VALUE
	MOVEI	T1,.PRIOU
	MOVE	T2,ENDTIM
	SETZ	T3,
	ODTIM
	 ERJMP	LOSE
	JRST	CMDWH5		;AND CONTINUE
CMDWH4:	TMSG<
No Time Range Set>		;SAY NONE SET
CMDWH5:	TXNE	F,FL%IFS	;CHECK INPUT FILE SETUP
	JRST	CMDWH6		;ONE SPECIFIED
	TMSG<
Default Input Error File>	;NOT SET UP
	JRST	CMDWH7		;AND CONTINUE
CMDWH6:	TMSG<
Input Error File Specified: >	;PREFIX
	HRROI	T1,JFNSTR	;POINT TO FILENAME STRING
	PSOUT			;TYPE IT
	 ERJMP	LOSE
CMDWH7:	HRROI	T1,[ASCIZ/
Complete Output Listing/]	;ASSUME COMPLETE OUTPUT
	TXNE	F,FL%SUM	;JUST THE SUMMARY?
	HRROI	T1,[ASCIZ/
Summary Output Listing Only/]	;YUP
	PSOUT			;SAY SO
	TMSG<

>				;AND A CRLF
	RET			;AND RETURN
;DRIVE COMMAND TO SET DRIVE SERIAL NUMBER TO MATCH


CMDDRI:	MOVEI	T2,[ASCIZ/SERIAL NUMBER TO LIST ERRORS FOR/]
	CALL	NOISE		;PROCESS THE NOISE
	MOVEI	T2,[FLDDB. (.CMNUM,,^D10,,<ALL>,[FLDDB. (.CMKEY,,DRITAB)])]
	CALL	COMMND		;READ A DECIMAL FORM NUMBER
	TSC	T3,T3		;CHECK WHICH BLOCK WORKED
	JUMPN	T3,[	TXZ	F,FL%SER	;"ALL" SPECIFIED
			CALL	CONFRM		;CONFIRM IT
			RET]			;CLEAR FLAG AND RETURN
	TXO	F,FL%SER	;MARK TO CHECK
	MOVEI	P1,4		;CONVERT TO FOUR DIGIT BCD
	SETZM	T4		;START CLEAR
CMDDR0:	IDIVI	T2,^D10		;REMOVE DIGIT
	LSHC	T3,-4		;SHIFT DOWN
	SOJG	P1,CMDDR0	;LOOP FOR FOUR
	ROT	T4,^D16		;RIGHT JUSTIFIY
	MOVEM	T4,SERNOM	; AND SAVE FOR MATCHING
	CALL	CONFRM		;CONFIRM THE LINE
	RET			;AND RETURN


DRITAB:	DRILEN,,DRILEN		;HEADER
	AA	ALL,0		;ONLY ENTRY

	DRILEN==.-DRITAB-1	;NUMBER
;TIME COMMAND TO SET BEGIN AND END THRESHOLDS


CMDTIM:	MOVEI	T2,[ASCIZ/TO START LISTING ENTRIES/]
	CALL	NOISE		;PROCESS IT
	MOVEI	T2,[FLDDB.(.CMCFM,,,,,[FLDDB.(.CMTAD,,CM%IDA+CM%ITM,,,[
		FLDDB.(.CMTAD,,CM%IDA,,,[FLDDB.(.CMTAD,,CM%ITM)])])])]
	CALL	COMMND		;GET BEGIN
	TSC	T3,T3		;CHECK FOR JUST A CRLF
	JUMPE	T3,[	TXZ	F,FL%TIM	;YES--CLEAR TIME CHECKING
			RET]			; AND DONE HERE
	MOVEM	T2,BGNTIM	;SAVE IT
	MOVEI	T2,[ASCIZ/AND END AT/]	;MORE NOISE
	CALL	NOISE		;TO PROMPT FOR END
	MOVEI	T2,[FLDDB.(.CMCFM,,,,,[FLDDB.(.CMTAD,,CM%IDA+CM%ITM,,,[
		FLDDB.(.CMTAD,,CM%IDA,,,[FLDDB.(.CMTAD,,CM%ITM)])])])]
	CALL	COMMND		;ENDING VALUE
	TXO	F,FL%TIM	;REMEMBER
	MOVEM	T2,ENDTIM	;SAVE AWAY
	TSC	T3,T3		;CHECK FOR JUST CRLF (FIRST FLDDB.)
	JUMPE	T3,[GTAD	; IF SO, USE NOW
		    MOVEM T1,ENDTIM	; AS ENDING TIME
		    RET]		;AND DONE
	CALL	CONFRM		;OTHERWISE CONFIRM THE LINE
	RET			;AND RETURN


;READ COMMAND TO SET ALTERNATE INPUT FILE


CMDRED:	MOVEI	T2,[ASCIZ/ERROR DATA FROM/]	;NOISE
	CALL	NOISE		;PROCESS NOISE
	MOVX	T2,GJ%OLD	;FILE MUST EXIST
	MOVEM	T2,JFNBLK	;SET FLAGS
	MOVEI	T2,[FLDDB. (.CMIFI,,,,<SYSTEM:ERROR.SYS>)]
	CALL	COMMND		;PARSE INPUT FILENAME
	MOVEM	T2,IJFN		;SAVE THE INPUT JFN FOR LATER
	CALL	CONFRM		;CONFIRM THE LINE
	TXO	F,FL%IFS	;FILE SPECIFIED
	HRROI	T1,JFNSTR	;WHERE TO PUT THE STRING
	MOVE	T2,IJFN		;GET BACK THE JFN
	SETZB	T3,T4		;DEFAULT STRING
	JFNS			;PUT IT IN STRING BLOCK
	 ERJMP	LOSE		;FAILED
	MOVE	T1,IJFN		;AND PROCEED TO
	RLJFN			; UNLOAD JFN, SAVING STRING
	 ERJMP	LOSE		;FAILED
	RET			;AND RETURN


;LIST COMMAND TO SET OUTPUT FILE AND BEGIN


CMDLST:	MOVEI	T2,[ASCIZ/OUTPUT ON FILE/]	;NOISE
	CALL	NOISE		;PROCESS IT
	MOVEI	T2,[FLDDB. (.CMOFI,,,,<TTY:>)]	;SETUP
	CALL	COMMND		;READ OUTPUT SPEC
	MOVEM	T2,OJFN		;STORE JFN FOR OUTPUT
	MOVEI	T2,[ASCIZ/AND BEGIN PROCESSING/]
	CALL	NOISE		;FINAL NOISE
	CALL	CONFRM		;CONFIRM THE LINE
	MOVEM	P,SAVEL		;PRESERVE P IN CASE ABORT OCCURS
	MOVE	T1,[.TICCE,,INTCHN] ;ACTIVATE ABORT ON ^E
	ATI
	CALL	PROCES		;DO THE JOB
LSTDON:	MOVX	T1,.TICCE	;^E CODE
	DTI			;DISABLE INTERRUPTING ON IT
	 ERJMP	LOSE
	RET			;AND RETURN FOR ANOTHER COMMAND



;HERE ON A CONTROL-E INTERRUPT TO ABORT THE LIST COMMAND IN PROGRESS

LSTINT:	MOVEI	T1,LSTABT	;ADDRESS OF WHERE TO GO
	MOVEM	T1,CHNPC1	;IN PLACE OF RETURNING
	DEBRK			;TERMINATE THE INTERRUPT
	 ERJMP	LOSE		;FAILED


;DEBRK TRANSFERS CONTROL TO HERE TO ABORT THE LIST COMMAND

LSTABT:	MOVEI	T1,.PRIOU	;PRESUME TO CLEAR
	CFOBF			; THE OUTPUT IN CASE GOING TO TTY
	 ERJMP	LOSE
	TMSG	<
Listing Aborted
>				;YIELD UP AN ACKNOWLEDGEMENT
	TXZ	F,FL%IFS+FL%OFO	;ABORT CLOSE THE FILES
	MOVX	T1,CZ%ABT+.FHSLF; FOR THE  JOB
	CLZFF
	 ERJMP	LOSE
	MOVE	P,SAVEL		;ADJUST STACK BACK FOR ABORT
	JRST	LSTDON		; AND FINISH UP THE COMMAND
	SUBTTL	THE MAIN PROCESSING LOOP


PROCES:	MOVX	T1,GJ%OLD+GJ%SHT	;GETJFN BITS
	HRROI	T2,[ASCIZ/SYSTEM:ERROR.SYS/]	;ASSUME DEFAULT
	TXNE	F,FL%IFS	;SPECIAL FILE SPECIFIED?
	HRROI	T2,JFNSTR	;YES--POINT TO IT
	GTJFN			;TRY TO GET IT
	 ERJMP	LOSE		;FAILED
	MOVEM	T1,IJFN		;SAVE JFN

PROC1:	MOVE	T1,IJFN		;GET INPUT JFN
	MOVX	T2,^D36B5+OF%RD	;TO READ
	OPENF			;OPEN IT
	 ERJMP	LOSE		;FAILED

	MOVE	T1,OJFN		;NOW TRY OUTPUT JFN
	MOVX	T2,^D7B5+OF%WR	;TO WRITE IN ASCII
	OPENF			;OPEN IT
	 ERJMP LOSE		;FAILED
	TXO	F,FL%OFO	;MARK AS OPEN

	TMSG<
[ PROCESSING >			;SAY WHO
	PSOUT			;WE ARE DOING
	MOVEI	T1,.PRIOU	;OUTPUT TO USER
	MOVE	T2,IJFN		;INPUT FILE JFN
	SETZB	T3,T4		;JFNS ARGS
	JFNS			;SAY WHICH FILE
	 ERJMP	LOSE		;FAILED
	TMSG< ]

>				;AND A CRLF
	SETOM	LINENO		;INIT LINE COUNTER
	SETZM	PAGENO		;INIT PAGE NUMBER
	TXO	F,FL%FDO	;FORCE DATE OUTPUT
	SETZM	SUMCNT		;INIT SUMMARY TABLE
	SETZB	T1,T2		;ZERO SOME STUFF
	SETZ	T3,		;TO INDICATE MIDNIGHT
	IDCNV			;GET LOCAL MIDNITE
	 ERJMP	LOSE		;FAILED
	HRROM	T2,LSTDAT	;SET DATE PRINTING THRESHOLD

	CALL	FILINI		;INIT INPUT FILE POINTERS

PROCLP:	CALL	NXTENT		;GET NEXT ENTRY TO BUFFER
	JRST	PROCFN		;END OF FILE OR OTHER TERMINATION
	MOVE	P1,HDRTIM	;MAKE
	CALL	TIMCHK		; CHECK OF TIME
	JRST	PROCSM		;UNWANTED--BUT SUMMARIZE
	MOVE	P1,VOLID	;MAKE
	CALL	VOLCHK		; CHECK OF VOLUME
	JRST	PROCSM		;UNWANTED--BUT SUMMARIZE
	MOVE	P1,SERNO	;MAKE
	CALL	SERCHK		; CHECK OF DRIVE SERIAL NUMBER
	JRST	PROCSM		;UNWANTED--BUT SUMMARIZE
	MOVE	P1,IRBSTS	;MAKE
	CALL	HRDCHK		; CHECK OF ERROR TYPE
	JRST	PROCSM		;UNWANTED--BUT SUMMARIZE
	TXNE	F,FL%SUM	;SUMMARY ONLY?
	JRST	PROCSM		;YES

	CALL	TSTPAG		;WANT THIS ONE--
	MOVE	P1,HDRTIM	;OUTPUT TIME
	CALL	DATOUT
	SPACE	1
	MOVE	P1,VOLID	;OUTPUT VOLUME ID
	CALL	VOLOUT
	SPACE	2
	MOVE	P1,SERNO	;OUTPUT SERIAL NUMBER
	CALL	SEROUT
	SPACE	1
	MOVE	P1,LBN		;OUTPUT LOGICAL BLOCK NUMBER
	CALL	LBNOUT
	SPACE	1
	MOVE	P1,LBN		;OUTPUT CYL/SURF/SEC
	CALL	CYLOUT
	SPACE	2
	MOVE	P1,RETRY	;OUTPUT	RETRY COUNT
	CALL	TRYOUT
	SPACE	1
	MOVE	P1,IRBSTS	;OUTPUT HARD/SOFT
	CALL	HRDOUT
	CALL	CRLF		;OUTPUT CRLF
PROCSM:	MOVE	P1,VOLID	;VOLUME AND
	MOVE	P2,IRBSTS	; ERROR TYPE
	MOVE	P3,DEVTYP	; AND INTERNAL UNIT TYPE
	CALL	SUMVOL		;FOR SUMMARY BY VOLUME
	JRST	PROCLP		;AND LOOP


PROCFN:	CALL	SUMOUT		;PRINT THE SUMMARY
	MOVE	T1,IJFN		;INPUT JFN
	CLOSF			;CLOSE
	 ERJMP	LOSE
	MOVE	T1,OJFN		;OUTPUT JFN
	CLOSF			;SAME
	 ERJMP	LOSE
	TXZ	F,FL%IFS+FL%OFO	;MARK AS NOT OPEN
	RET			;AND DONE

;SUMVOL	DO THE SUMMARY OF HARD/SOFT ERRORS BY VOLUME


SUMVOL:	SKIPN	T2,SUMCNT	;ANYONE THERE?
	JRST	SUMADV		; NOT YET
	SETZ	T1,		;START AT THE BEGINNING
SUMSLP:	CAMN	P1,SUMTAB+VSUM(T1)	;VOLUMES MATCH?
	CAME	P3,SUMTAB+USUM(T1)	; AND UNIT TYPE TOO?
	SKIPA			;NO
	JRST	SUMINC		;YES--MAKE THE COUNTS
	ADDI	T1,SIZSUM	;LENGTH OF AN ENTRY
	SOJG	T2,SUMSLP	;NO FOUND YET--KEEP LOOKING

	MOVEI	T1,VTBSIZ	;NOT FOUND--CHECK FOR ROOM
	SUB	T1,SUMCNT	; TO ADD TO TABLE
	JUMPG	T1,SUMADV	;THERE IS ROOM
	TXO	F,FL%TMV	;NO ROOM--MARK
	RET			; AND FORGET FOR NOW

SUMADV:	MOVE	T1,SUMCNT	;GET COUNT OF ENTRIES
	IMULI	T1,SIZSUM	;SIZE OF AN ENTRY
	MOVEM	P1,SUMTAB+VSUM(T1)	;STORE VOLUME
	MOVEM	P3,SUMTAB+USUM(T1)	;SET UNIT TYPE
	SETZB	T2,T3			;INITIALIZE
	DMOVEM	T2,SUMTAB+VSUM+1(T1)	; HARD AND SOFT COUNTS
	AOSE	SUMCNT		;COUNT THE ENTRY
SUMINC:	TXNE	P2,IS.ERR	;HARD OR SOFT?
	AOSA	SUMTAB+HSUM(T1)	;HARD
	AOS	SUMTAB+SSUM(T1)	;SOFT
	RET			;AND RETURN
	SUBTTL	ENTRY INPUT AND VALIDATION ROUTINES


;ALL ROUTINES HERE RETSKP IF VALID AND RET IF ENTRY IS UNWANTED


;TIMCHK	VERIFY ENTRY TIME IN P1 IN RANGE

TIMCHK:	TXNN	F,FL%TIM	;DO WE CARE?
	RETSKP			;NO
	CAML	P1,BGNTIM	;TOO EARLY
	CAMLE	P1,ENDTIM	; OR TOO LATE?
	RET			;YUP
	RETSKP			;IN RANGE


;VOLCHK	VERIFY VOLUME ID IN P1

VOLCHK:	TXNE	F,FL%VOL	;DO WE CARE?
	CAMN	P1,VOLIDM	; OR DOES IT MATCH?
	RETSKP			;YES
	RET			;NO


;SERCHK	VERIFY DRIVE SERIAL NUMBER IN P1

SERCHK:	TXNE	F,FL%SER	;DO WE CARE?
	CAMN	P1,SERNOM	; OR DOES IT MATCH?
	RETSKP			;YES
	RET			;NO


;HRDCHK	VERIFY IF SUPPRESSING HARD OR SOFT ERRORS FROM IS.ERR IN P1

HRDCHK:	TXNN	P1,IS.ERR	;HARD OR SOFT?
	JRST	SOFCHK		;SOFT
	TXNN	F,FL%SHE	;SUPPRESS?
	RETSKP			;NO
	RET			;YES

SOFCHK:	TXNN	F,FL%SSE	;SUPPRESS?
	RETSKP			;NO
	RET			;YES
;FILINI	INITIALIZE INPUT FILE...


FILINI:	MOVEI	T1,1		;ADDRESS OF FIRST HEADER WORD
	MOVEM	T1,HDRADR	;INIT HDRADR
	SETZM	HDRWRD		;AND FAKE HDRWRD SO WILL BEGIN AT START
	RET			;AND RETURN



;NXTENT	READ IN THE NEXT MASSBUS ENTRY.  RETSKP OK, RET ON EOF.


NXTENT:	LOAD	T2,HDRLEN	;HEADER LENGTH
	LOAD	T1,ENTLEN	;ENTRY LENGTH
	ADD	T2,T1		;COMBINE
	CALL	GETWRD		;READ NEXT HEADER
	RET			;EOF???
	LOAD	T1,HDRCOD	;GET TYPE CODE
	CAIE	T1,HF.ERR	;IS IT AN ERROR MARKER
	CAIN	T1,HF.EOF	; OR THE NORMAL EOF MARKER?
	RET			;YES
	MOVEM	T3,HDRADR	;SET NEW HEADER ADDRESS
	MOVEM	T2,HDRWRD	;SET NEW HEADER WORD
	LOAD	T1,HDRVER	;GET VERSION
	CAIE	T1,HF.VER	;ONE WE KNOW?
	JRST	LOST		;NO--SANITY CHECK LOSES
	MOVE	T1,HDRWRD	;WORD
	TXNN	T1,HF.T20	;TOPS-20 ENTRY?
	JRST	LOST		;NO--SANITY CHECK LOSES
	LOAD	T1,HDRCOD	;GET TYPE CODE
	CAIE	T1,SEC%MB	;MASSBUS ERROR?
	JRST	NXTENT		;NO--LOOP
	CALL	RDENT		;OK, SO READ VALUES
	SKIPGE	DEVTYP		;DISK DEVICE?
	JRST	NXTENT		;NO--LOOP
	RETSKP			;AND RETURN SKIP

LOST:	TMSG<
% LOST SYNCHRONIZATION--ATTEMPTING TO CONTINUE

>				;SAY OOPS
	MOVE	T1,HDRADR	;GET CURRENT ADDRESS
	ADDI	T1,^D128	;MOVE TO NEXT BLOCK
	TRZ	T1,177		;AND ROUND BACK TO BEGINNING
	MOVEM	T1,HDRADR	;THEN STORE BACK
	MOVEI	T2,0		;ZERO OFFSET
	CALL	GETWRD		;READ THE POINTER WORD AT START OF BLOCK
	 RET			;APPARENTLY END OF FILE...
	HRRZS	T2		;OFFSET IS IN THE RIGHT HALF
	ADDM	T2,HDRADR	;POINT TO START OF NEXT ENTRY
	SETZM	HDRWRD		;NO FURTHER OFFSETS
	JRST	NXTENT		; AND TRY THE NEXT ENTRY
;RDENT	READ IN THE DATA FOR THE CURRENT ENTRY


RDENT:	MOVEI	T2,HDRDAT	;GET DATE-TIME
	CALL	GETWRD
	 JRST	OOPS
	MOVEM	T2,HDRTIM

	LOAD	T2,HDRLEN	;GET VOLUME ID
	ADDI	T2,MB%VID
	CALL	GETWRD
	 JRST	OOPS
	MOVEM	T2,VOLID

	LOAD	T2,HDRLEN	;GET LBN - ACTUALLY LINEAR UNIT ADR
	ADDI	T2,MB%LOC
	CALL	GETWRD
	 JRST	OOPS
	MOVEM	T2,LBN

	LOAD	T2,HDRLEN	;GET SERIAL #
	ADDI	T2,SEROFF
	CALL	GETWRD
	 JRST	OOPS
	LOAD	T2,F%SER
	MOVEM	T2,SERNO

	LOAD	T2,HDRLEN	;GET IORB STATUS
	ADDI	T2,MB%IRS
	CALL	GETWRD
	 JRST	OOPS
	MOVEM	T2,IRBSTS

	LOAD	T2,HDRLEN	;GET RETRY COUNT
	ADDI	T2,MB%FEC
	CALL	GETWRD
	 JRST	OOPS
	MOVEM	T2,RETRY

	LOAD	T2,HDRLEN	;GET UNIT TYPE
	ADDI	T2,MB%TYP
	CALL	GETWRD
	 JRST	OOPS
	LOAD	T2,F%TYP
	CAILE	T2,MXUTYP	;REASONABLE?
	SKIPA	T2,[-1]		; NO, FAKE AS UNKNOWN
	MOVE	T2,CVTTAB(T2)	;CONVERT TO INTERNAL FORM UNIT
	MOVEM	T2,DEVTYP
	RET			;AND RETURN

OOPS:	HRROI	T1,[ASCIZ/
? UNEXPECTED END-OF-FILE ON INPUT/]
	PSOUT			;WARN
	JRST	LOSE		;AND CYCLE

;GETWRD	ROUTINE TO RETURN DESIRED WORD FROM INPUT FILE
;CALLED WITH OFFSET FROM THE BEGINNING OF THE HEADER IN T2.
;RETURNS THE DESIRED WORD IN T2 RETSKP.  NONSKIP FOR END-OF-FILE.
;RETURNS WORD ADDRESS IN T3.
;COMPUTES THE ADJUSTMENTS NEEDED TO ACCOMODATE THE SYNCH WORD AT
;THE START OF EVERY 128-WORD BLOCK.


GETWRD:	MOVE	T1,HDRADR	;HEADER ADDRESS
	ADD	T2,T1		;PLUS OFFSET
	LSH	T1,-7		;DIVIDE BY BLOCKSIZE
	MOVE	T3,T2		;COPY FOR ADJUST
	LSH	T3,-7		;DIVIDE BY BLOCKSIZE
	SUB	T3,T1		;COUNT BLOCK CROSSINGS
	ADD	T3,T2		;UPDATE ADDRESS FOR PROPER ADJUSTMENT
	XOR	T2,T3		;AND CHECK TO SEE IF THE ADJUSTMENT
	TRNE	T2,200		; PUSHED US ACROSS ANOTHER BOUNDARY
	AOS	T3		;IT DID, ADD THE (FINAL!) ADJUSTMENT.
	MOVE	T1,IJFN		;INPUT JFN
	RIN			;READ THE WORD
	 ERJMP	CHKEOF		;WATCH FOR EOF
	RETSKP			;RETURN

CHKEOF:	GTSTS			;GET STATUS BITS
	TXNN	T2,GS%EOF	;END OF FILE?
	JRST	LOSE		;NO--SOME ERROR
	RET			;YES--NONSKIP
	SUBTTL	OUTPUT CONVERSION ROUTINES


;DATOUT	OUTPUT THE DATE-TIME PASSED IN P1.


DATOUT:	MOVE	T1,OJFN		;JFN
	MOVE	T2,P1		;THE DATE-TIME
	SETZ	T3,		;DEFAULT FORMAT
	TXNE	F,FL%FDO	;FORCED?
	JRST	DATOU1		;YES--MAKE SURE THRESHOLD OK
	CAMGE	T2,LSTDAT	;PAST THRESHOLD?
	JRST	[PUSH	P,T2	;SAVE ACROSS CALL
		 SPACE	12	; DO SPACING
		 POP	P,T2	;RESTORE
		 JRST	DATOU2]	;AND CONTINUE
	TXO	F,FL%FDO	;YES, FORCE DATE OUT
DATOU1:	HLLM	T2,LSTDAT	;UPDATE THE THRESHOLD
	MOVSI	T4,1		; AND ADJUST IT
	CAML	T2,LSTDAT	; TO BE CORRECT
	ADDM	T4,LSTDAT	; FOR NEXT DAY
DATOU2:	TXZN	F,FL%FDO	;FORCING?
	TXO	T3,OT%NDA	;NO--SUPPRESSING
	ODTIM			;DO IT
	 ERJMP	LOSE		;FAILED
	RET			;DONE



;VOLOUT	OUTPUT THE VOLUME ID FROM P1 (SIXBIT)
;ENTRY POINT VOLOUX FOR JFN ALREADY SETUP IN T1


VOLOUT:	MOVE	T1,OJFN		;JFN FOR OUTPUT
VOLOUX:	MOVE	T3,[POINT 6,P1]	;POINTER
	MOVEI	T4,6		;COUNTER
VOLOUL:	ILDB	T2,T3		;FETCH BYTE
	ADDI	T2," "		;MAKE ASCII
	BOUT			;OUTPUT
	 ERJMP	LOSE		;FAILED
	SOJG	T4,VOLOUL	;LOOP
	RET			;DONE



;LBNOUT	OUTPUT THE LOGICAL BLOCK NUMBER FROM P1 (OCTAL)


LBNOUT:	MOVE	T1,OJFN		;JFN FOR OUTPUT
	MOVE	T2,P1		;VALUE
	MOVE	T3,[NO%MAG+NO%LFL+^D10B17+10] ;TEN RIGHT-JUSTIFIED
	NOUT			; OCTAL DIGITS OUTPUT
	 ERJMP	LOSE		;FAILED
	RET			;DONE

;SEROUT	OUTPUT THE SERIAL NUMBER FROM P1 (BCD)
;ENTRY POINT SEROUX FOR JFN ALREADY SETUP IN T1


SEROUT:	MOVE	T1,OJFN		;JFN FOR OUTPUT
SEROUX:	MOVE	T2,P1		;VALUE
	MOVE	T3,[NO%MAG+NO%LFL+NO%ZRO+4B17+^D16] ;FOUR BCD DIGITS
	NOUT			; WITH ZERO FILL
	 ERJMP	LOSE		;FAILED
	MOVEI	T2,"."		;DECIMAL
	BOUT			; POINT
	 ERJMP	LOSE		;FAILED
	RET			;DONE



;TRYOUT	OUTPUT THE NUMBER OF RETRIES FROM P1 (DECIMAL)


TRYOUT:	MOVE	T1,OJFN		;JFN FOR OUTPUT
	MOVE	T2,P1		;VALUE
	MOVE	T3,[NO%MAG+NO%LFL+3B17+^D10] ;THREE RIGHT-JUSTIFIED
	NOUT			; DECIMAL DIGITS
	 ERJMP	LOSE		;FAILED
	MOVEI	T2,"."		;AND A DECIMAL POINT
	BOUT			;DO IT
	 ERJMP	LOSE		;FAILED
	RET			;DONE


;HRDOUT	OUTPUT IF HARD OR SOFT ERROR BASED ON IS.ERR IN P1


HRDOUT:	MOVE	T1,OJFN		;JFN FOR OUTPUT
	HRROI	T2,[ASCIZ/HARD/];HARD ERROR
	TXNN	P1,IS.ERR	;SET?
	HRROI	T2,[ASCIZ/    /];NO--SOFT
	SETZ	T3,		;ASCIZ STRING
	SOUT			;OUTPUT STRING
	 ERJMP	LOSE		;FAILED
	RET			;DONE


;SPCOUT	OUTPUT NUMBER OF SPACES SPECIFIED IN P1 (0 TO 39.)


SPCOUT:	MOVE	T1,OJFN		;JFN FOR OUTPUT
	HRROI	T2,[ASCIZ/                                       /]
	MOVN	T3,P1		;SOUT COUNT
	SOUT			;OUTPUT THE SPACES
	 ERJMP	LOSE		;FAILED
	RET			;DONE
;CRLF	OUTPUT A CRLF


CRLF:	MOVE	T1,OJFN		;JFN FOR OUTPUT
	FMSG	<
>				;OUTPUT THE CRLF
	 ERJMP	LOSE
	RET			;AND RETURN


;CYLOUT	OUTPUT CYLINDER/SURFACE/SECTOR FROM LBN IN P1


CYLOUT:	MOVE	T4,DEVTYP	;GET TYPE OF UNIT FOR INDEX
	CAMGE	P1,.MXBLK(T4)	;MORE THAN ONE UNIT FULL?
	JRST	CYLOU1		;NO
	SUB	P1,.MXBLK(T4)	;REDUCE BY SECTORS/UNIT
	JRST	.-3		;AND LOOP
CYLOU1:	IDIV	P1,.TRBLK(T4)	;DIVIDE BY SECTORS/CYLINDER
	MOVE	T2,P1		;TO GET CYLINDER
	MOVE	T1,OJFN		;JFN FOR OUTPUT
	MOVE	T3,[NO%MAG+NO%LFL+^D4B17+^D10]	;4 DIGIT CYLINDER
	NOUT			;OUTPUT
	 ERJMP	LOSE
	HRROI	T2,[ASCIZ/.  /]	;DECIMAL POINT AND SPACING
	SETZ	T3,		;ASCIZ
	SOUT
	 ERJMP LOSE

	MOVE	P1,P2		;MOVE
	IDIV	P1,.SUBLK(T4)	;DIVIDE BY SECTORS/SUFRACE
	MOVE	T2,P1		;TO GET SURFACE
	MOVE	T3,[NO%MAG+NO%LFL+^D2B17+^D10]	;2 DIGIT SURFACE
	NOUT			;OUTPUT
	 ERJMP	LOSE
	HRROI	T2,[ASCIZ/.  /]	;DECIMAL POINT AND SPACING
	SETZ	T3,		;ASCIZ
	SOUT
	 ERJMP	LOSE

	MOVE	P1,P2		;MOVE
	IMUL	P1,.SECBK(T4)	;MULTIPLY BY SECTORS/BLOCK
	MOVE	T2,P1		;TO GET SECTOR
	MOVE	T3,[NO%MAG+NO%LFL+^D3B17+^D10]	;3 DIGIT SECTOR
	NOUT			;OUTPUT
	 ERJMP	LOSE
	MOVEI	T2,"."		;DECIMAL
	BOUT			; POINT
	 ERJMP	LOSE

	RET			;AND RETURN
;CONVERSION FROM UNIT TO INTERNAL DISK UNIT, -1 FOR NON-DISK OR UNKNOWN

CVTTAB:	EXP	-1		;0 - UNKNOWN TYPE
	EXP	1		;1 - RP04
	EXP	0		;2 - RS04
	EXP	-1		;3 - TU45
	EXP	-1		;4 - TM02
	EXP	2		;5 - RP05
	EXP	3		;6 - RP06
	EXP	5		;7 - RP07
	EXP	-1		;10 - RP08--NOT YET HANDLING
	EXP	4		;11 - RM03
	EXP	-1		;12 - TM03
	EXP	-1		;13 - TU77
	EXP	-1		;14 - TM78
	EXP	-1		;15 - TU78
	EXP	-1		;16 - DX20-A (FOR TAPES)
	EXP	-1		;17 - TU70
	EXP	-1		;20 - TU71
	EXP	-1		;21 - TU72
	EXP	-1		;22 - TU7x
	EXP	-1		;23 - DX20-B (FOR DISKS)
	EXP	6		;24 - RP20

	MXUTYP==.-CVTTAB-1

;TABLES INDEXED BY INTERNAL UNIT TYPE

.DVTAB:	ASCIZ/RS04/
	ASCIZ/RP04/
	ASCIZ/RP05/
	ASCIZ/RP06/
	ASCIZ/RM03/
	ASCIZ/RP07/
	ASCIZ/RP20/

.MXBLK:	^D2048			;2048 BLOCKS PER RS04
	^D152000		;152000 BLOCKS PER RP04
	^D152000		;152000 BLOCKS PER RP05
	^D304000		;304000 FOR AN RP06
	^D121360		;121360 BLOCKS/PACK RM03
	^D502200		;502200 BLOCKS PER RP07
	^D201420		;201420 BLOCKS PER RP20

.TRBLK:	^D32			;32 BLOCKS/TRACK ON RS04
	^D380			;380 BLOCKS/CYL RP04
	^D380			;380 BLOCKS/CYL RP05
	^D380			;380 BLOCKS/CYL RP06
	^D148			;BLOCKS/CYL RM03  (LAST 2 SECTORS LOST)
	^D900			;900 BLOCKS/CYL RP07
	^D180			;180 SECTORS/CYL ON RP20

.SUBLK:	^D0			;RS04 BLOCKS/SURFACE
	^D20			;RP04 BLOCKS/SURFACE
	^D20			;RP05 BLOCKS/SURFACE
	^D20			;RP06 BLOCKS/SURFACE
	^D30			;BLOCKS / SURFACE FOR RM03
	^D30			;RP07 BLOCKS/SURFACE
	^D6			;RP20 SECTORS/SURFACE

.SECBK:	2			;2/BLOCK FOR RS04
	1			;1 PER FOR RP04
	1			;1 PER FOR RP05
	1			;1 PER FOR RP06
	1			;1 SECTOR / BLOCK FOR RM03
	1			;1 PER FOR RP07
	1			;1 SECTOR/BLOCK FOR RP20
	SUBTTL	PAGE HEADER PRINTING ROUTINE


;TSTPAG	ROUTINE CALLED PRIOR TO OUTPUTTING A LINE.  TESTS LINENO AND
;	PUTS OUT A NEW PAGE HEADER WHEN THE COUNTER EXPIRES.


TSTPAG:	AOSE	LINENO		;HEADER TIME
	RET			;NOT YET
	AOS	PAGENO		;NEW PAGE
	MOVE	T1,OJFN		;OUTPUT JFN
	MOVEI	T2,.CHFFD	;FORM FEED
	BOUT
	 ERJMP	LOSE
	HRROI	T2,[ASCIZ\
DSKERR %\]
	SETZ	T3,		;ASCIZ
	SOUT
	 ERJMP	LOSE
	CALL	VEROUT		;OUTPUT OUR VERSION NUMBER
	MOVEI	T2,.CHTAB	;AND A TAB
	BOUT
	 ERJMP	LOSE
	SETO	T2,		;-1=NOW
	ODTIM			;DATE AND TIME
	 ERJMP	LOSE
	HRROI	T2,[ASCIZ\				PAGE  \]
	SETZ	T3,		;ASCIZ
	SOUT
	 ERJMP	LOSE
	MOVE	T2,PAGENO	;AND FINALLY THE PAGE NUMBER
	MOVE	T3,[NO%MAG+NO%LFL+^D2B17+^D10]	;DECIMAL, 2 DIGIT
	NOUT
	 ERJMP	LOSE
	HRROI	T2,[ASCIZ\

   DATE     TIME   VOLUME SERIAL #    LBN    CYL  SURF  SEC  RETRY TYPE

\]				;COLUMN HEADER
	SETZ	T3,		;ASCIZ
	SOUT
	 ERJMP	LOSE

	MOVNI	T1,PAGSIZ	;RESET COUNTER
	MOVEM	T1,LINENO	; FOR NEXT TIME
	TXO	F,FL%FDO	;FORCE THE DATE ON FIRST LINE
	RET			;AND RETURN
	SUBTTL	VERSION NUMBER PRINTING


;VEROUT	PRINT OUT THE ASSEMBLED-IN VERSION NUMBER. (T1 ALREADY SET UP)

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

;SUMOUT	OUTPUT THE BY VOLUME SUMMARY ON A NEW PAGE


SUMOUT:	SKIPN	P2,SUMCNT	;ANYTHING TO DO
	JRST	[TMSG<No errors summarized>	;NOTHING ACCUMULATED
		 RET]		;SO DONE

	MOVE	T1,OJFN		;JFN FOR OUTPUT
	MOVEI	T2,.CHFFD	;FORM FEED FOR NEW PAGE
	BOUT			;OUTPUT
	 ERJMP	LOSE
	HRROI	T2,[ASCIZ/

ERROR SUMMARY BY VOLUME

VOLUME ID   UNIT TYPE    HARD ERRORS    SOFT ERRORS

/]				;THE HEADER LINE
	SETZ	T3,		;ASCIZ
	SOUT			; OUTPUT STRING
	 ERJMP	LOSE
	SETZ	P3,		;START OF TABLE
SUMOLP:	MOVE	P1,SUMTAB+VSUM(P3) ;VOLUME ID
	CALL	VOLOUT		;OUTPUT IT
	SPACE	10		;SPACING
	MOVE	T1,OJFN		;OUTPUT JFN
	MOVE	T2,SUMTAB+USUM(P3)	;UNIT TYPE
	HRROI	T2,.DVTAB(T2)	;POINT TO NAME
	SETZ	T3,		;ASCIZ
	SOUT			;STRING OUTPUT
	 ERJMP	LOSE
	SPACE	10		;SPACING
	MOVE	T2,SUMTAB+HSUM(P3) ;HARD ERROR COUNT
	MOVE	T3,[NO%MAG+NO%LFL+^D6B17+^D10]	;FORMAT
	NOUT			;OUTPUT THE NUMBER
	 ERJMP	LOSE
	MOVEI	T2,"."		;DECIMAL
	BOUT			; POINT
	 ERJMP	LOSE
	SPACE	10		;SPACING
	MOVE	T1,OJFN		;OUTPUT JFN
	MOVE	T2,SUMTAB+SSUM(P3) ;SOFT ERROR COUNT
	MOVE	T3,[NO%MAG+NO%LFL+^D6B17+^D10]	;FORMAT
	NOUT			;DO THE NUMBER
	 ERJMP	LOSE
	MOVEI	T2,"."		;DECIMAL
	BOUT			; POINT
	 ERJMP	LOSE
	CALL	CRLF		;AND END LINE
	ADDI	P3,SIZSUM	;SIZE OF AN ENTRY
	SOJG	P2,SUMOLP	;LOOP THRU TABLE
	TXNN	F,FL%TMV	;SOME NOT LISTED?
	RET			;NO, DONE.
	HRROI	T2,[ASCIZ/
*** Further volumes not listed because of insufficient room in table ***
/]				;PROVIDE A CLUE
	SETZ	T3,		;ASCIZ TEXT
	SOUT			; FOR OUTPUT
	 ERJMP	LOSE		;LOSE
	RET			;AND DONE
	SUBTTL	ERROR PROCESSING AND COMND HELPER ROUTINES


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


LOSFIN:	HRROI	T1,[ASCIZ/

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


TAKEOF:	CALL	UNTAKE		;CLEAN UP TAKE STATE
	TMSG	<
[Command file completed]>	;SAY SO
	JRST	REEN		;AND REENTER COMMAND LOOP

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



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




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

	XLIST			;DUMP THE LITERALS
	LIT
	LIST


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

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

LEVTAB:	EXP	CHNPC1		;WHERE TO STORE PC FOR LEVEL ONE INTERRUPT
	BLOCK	2		;OTHER LEVELS UNUSED
CHNTAB:	XWD	1,LSTINT	;VECTOR FOR INTERRUPT ON THIS CHANNEL
	BLOCK	^D35		;OTHER CHANNELS UNUSED
CHNPC1:	BLOCK	1		;INTERRUPT PC STORED HERE
SAVEL:	BLOCK	1		;P SAVED HERE FOR ADJUST ON ^E
JFNX:	BLOCK	1		;JFN ON EXEC TO PUSH TO
HANDLE:	BLOCK	1		;FORK HANDLE FOR INFERIOR EXEC
OLDPRM:	BLOCK	1		;STORAGE FOR OLD I/O DESIGNATORS DURING TAKE
TAKJFN:	BLOCK	1		;TAKE FILE JFN WHEN NONZERO


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

JFNSTR:	BLOCK	100		;STORAGE FOR INPUT FILENAME
IJFN:	BLOCK	1		;INPUT FILE JFN
OJFN:	BLOCK	1		;OUTPUT FILE JFN
PAGENO:	BLOCK	1		;PAGE NUMBER
LINENO:	BLOCK	1		;LINE NUMBER
BGNTIM:	BLOCK	1		;BEGIN TIME
ENDTIM:	BLOCK	1		;END TIME
VOLIDM:	BLOCK	1		;SIXBIT VOLUME ID TO MATCH
SERNOM:	BLOCK	1		;DRIVE SERIAL NUMBER TO MATCH
LSTDAT:	BLOCK	1		;LAST DATE OUTPUT WORD

;ENTRY DATA

HDRADR:	BLOCK	1		;ADDRESS OF CURRENT HEADER WORD

HDRWRD:	BLOCK	1		;CURRENT HEADER WORD
HDRTIM:	BLOCK	1		;DATE-TIME
DEVTYP:	BLOCK	1		;DEVICE TYPE WORD
VOLID:	BLOCK	1		;VOLUME ID
LBN:	BLOCK	1		;LOGICAL BLOCK NUMBER
RETRY:	BLOCK	1		;RETRY COUNT
IRBSTS:	BLOCK	1		;IORB STATUS WORD
SERNO:	BLOCK	1		;SERIAL NUMBER

SUMCNT:	BLOCK	1		;COUNT OF ENTRIES IN SUMTAB
SUMTAB:	BLOCK	SIZSUM*VTBSIZ	;SUMMARY TABLE--VOLID,HARD,SOFT


	END	<3,,EVEC>