Google
 

Trailing-Edge - PDP-10 Archives - steco_19840320_1er_E35 - 10,5676/teco/source/tecuuo.mac
There are 3 other files named tecuuo.mac in the archive. Click here to see a list.
	SUBTTL	Introduction

; Copyright (c) 1979, 1980 Stevens Institute of Technology, Hoboken, New Jersey
; 07030.

; This software may be used and copied provided that this copyright notice
;is included, and provided that copies of all modifications are sent to:
;
;	TECO Project
;	Computer Center
;	Stevens Institute of Technology
;	Castle Point Station
;	Hoboken, New Jersey    07030
;
;
; The information in this software is subject to change without notice
; and should not be construed as a commitment by Stevens Institute of
; Technology.

  ; Search needed universals

	SEARCH	TECUNV		; TECO universal file
	SEARCH	JOBDAT		; And get job data area systems

  ; Generate the prologue


	TECVER==200		; Major version number
	TECMIN==1		; Minor version number
	TECEDT==1171		; Edit level
	TECWHO==0		; Last editor


	PROLOGUE(UUO,<TECO LUUO and error processing>)	; Generate the TITLE and other stuff
	SUBTTL	Table of Contents

;+
;.pag.lit

;		Table of Contents for TECUUO - LUUO and interrupt handling
;
;
;			   Section			      Page
;   1. Introduction . . . . . . . . . . . . . . . . . . . . .    1
;   2. Table of Contents. . . . . . . . . . . . . . . . . . .    2
;   3. Revision History . . . . . . . . . . . . . . . . . . .    3
;   4. U$INIT - LUUO and error initialization . . . . . . . .    4
;   5. Error processing
;        5.1.   U$CINI - Per command initialization . . . . .    5
;        5.2.   U$PDLO - Stack overflow routine . . . . . . .    6
;        5.3.   U$UUOH. . . . . . . . . . . . . . . . . . . .    7
;        5.4.   U$ERR - Normal error processing . . . . . . .    8
;   6. U$WARN - Warning routine . . . . . . . . . . . . . . .   10
;   7. U$SVCM - Save last command for error processing. . . .   11
;   8. U$WERQ - Write the error message into the QRG. . . . .   12
;   9. U$CLNU - Clean up after a file error . . . . . . . . .   13
;  10. Error processing
;       10.1.   U$RDSK - Set up to read a message . . . . . .   14
;       10.2.   U$RDER - Read a character from the error file   15
;       10.3.   U$ERER - Process an error for the error file.   16
;       10.4.   ERRQUE. . . . . . . . . . . . . . . . . . . .   17
;       10.5.   ERRSLH. . . . . . . . . . . . . . . . . . . .   18
;  11. CHKEO processing . . . . . . . . . . . . . . . . . . .   19
;  12. Low segment. . . . . . . . . . . . . . . . . . . . . .   20
;  13. End of TECUUO. . . . . . . . . . . . . . . . . . . . .   21

;.end lit.pag
;-
	SUBTTL	Revision History

COMMENT	|

1000	Start of this version

1031	By: Robert McQueen		On: 22-August-1980
	Attempt to speed up reading characters by not saving T2 to T4 in F$READ and
	rearrange the checks in the routine so they are faster.
	Modules: TECFIL,TECUUO

1034	By: Nick Bush		On: 24-August-1980
	If an error occurs during the execution of TECONC, error processing
	blows up. Set up a flag to indicate whether TECONC has finished yet.
	If it is still set, error processing will skip writing the message
	into the Q-reg.
	Modules: TECUNV,TECUUO,TECONC

1044	By: Robert McQueen		On: 7-October-1980
	Don't smash T1 in the local UUO processing.
	Modules: TECUUO

1100	By: Robert McQueen		On: 8-Febuary-1981
	- Issue a ?TECNFO error message if there are no files for output on an EX
	  command or anything else that runs through FINI.0.
	- Cause the ?TECNFO error message from the above to only print one.  U$WW??
	  should not save TY.OBY on the stack, but use the ^X feature of $STRING.
	Modules: TECECM,TECUUO

1106	By: Nick Bush		On: 13-May-1981
	Improve screen updating for times when the new screen has portions which
	are identical with the old.  This will also fix most cases of wrapped
	around lines on the top of the section of the screen.
	Also fix some random /MODE:DUMP bugs.
	Modules: TECUNV,TECVID,TECCMD,TECECM,TECUUO,TECMEM

1126	By: Robert McQueen		On: 8-October-1981
	Make stopcodes more useful.  Create a U$STOP routine to type out more 
	information when a STOPCODE is encountered.  Save the registers in a place
	FILDDT can get at and do other good things.
	Modules: TECUNV,TECUUO

Start of Version 200A(1126)

1127	By: Nick Bush@SIT, Robert C. McQueen@SIT		On: 15-October-1981
	Add the following new features:
	- String arguments.  {...} is a string argument.
	- Make I take them, = and == return them.
	- Implement the FC command to define immediate command tables
	- Implement the E? command to return various items.
	- Start doing some work so that TECO will work on TOPS-20
	- Start doing some work so that TECO some day may run in a section
	  besides zero.
	Modules: TECUNV,TECERR,TECPRS,TECCMD,TECSRH,TECMEM,TECUUO,TECECM,TECMVM,TECCOM,TECINI

1171	By: Nick Bush		On: 29-June-1982
	Fix * and ? from screwing up after an error when a long prompt is being used.
	Modules: TECUNV,TECPRS,TECUUO
|
	SUBTTL	U$INIT - LUUO and error initialization

	$CODE			; This is in the code section

;+
;.HL1 U$INIT
; This routine will intialize the LUUO processing and any error traps
;required by TECO.  The traps include APR trapping for stack overflows.
;-

	LOC	.JB41		; Put LUUO instruction in when loading
	PUSHJ	P,U$UUOH	; To call the handler
	RELOC			; Back to hisegment

U$INIT:	SETZM	NOERFL		; Flag we should have an error file
	MOVE	T1,[JRST U$PDLO] ; Get the instruction for low segment
	MOVEM	T1,PDLTRP+1	; Save it
	MOVE	T1,[XWD 1,[EXP 2	; Set up the UTRP. call
		EXP	.UTPOV		; PDL ov trap
		JSR	PDLTRP]]	; Instruction to set
	UTRP.	T1,		; Enable the traps
	 JRST	.+2		; If it fails, use old type
	  JRST	U$IN.0		; Go do the rest
	MOVEI	T1,APRTRP	; Get the stack overflow routine address
	MOVEM	T1,.JBAPR	; Save it
	MOVX	T1,AP.REN!AP.POV ; Enable traping for stack overflows
	APRENB	T1,		; . . .
U$IN.0:	GTMSG.	T1		; Get the message level
	MOVEM	T1,PRMERR	; And save it
	MOVEM	T1,ERRLEN	; And for error processing
	SKIPN	ERFCNT		; Any messages in the error file?
	 PJRST	U$IN.2		; No, return
	MOVX	T1,<SIXBIT |SYS|> ; Get the default device
	CFXN.	,FDBDEV,+ERRFDB,0 ; Have a device?
	 STOR.	T1,FDBDEV,+ERRFDB ; No, use the default
	MOVX	T1,<SIXBIT |TECO|> ; Get the default file name
	CFXN.	,FDBNAM,+ERRFDB,0 ; Have a name?
	 STOR.	T1,FDBNAM,+ERRFDB ; No, use the default
	STORI.	<'ERR'>,T1,FDBEXT,+ERRFDB ; Store the default extension
	STORI.	$FMERR,T1,FDBMOD,+ERRFDB ; Store the mode
	MOVX	T1,FD.PTH	; Get the flag
	SKIPE	.FDPPN+ERRFDB	; Have a path?
	 IORM	T1,.FDFLG+ERRFDB ; Yes, flag it
	BITON	T1,FD.HEX,.FDFLG+ERRFDB ; And flag we have an extension
	MOVX	T1,$IOREA	; Get the access code
	MOVEI	T2,ERRFDB	; And the FDB address
	TXO	F,F.SFFI	; Supress file found in message
	PUSHJ	P,F$OPEN	; Open the file
	 PJRST	U$IN.2		; Give error reading error file
	MOVEI	P2,5		; Set up to read the first word
	MOVE	P3,[POINT 7,P4]	; Get the byte pointer to build the date/time word
	SETZ	P4,		; Clear to build the word

U$IN.1:	MOVEI	T1,ERRFDB	; Get the FDB address
	PUSHJ	P,F$READ	; Read a byte
	 PJRST	U$IN.2		; Couldn't
	IDPB	CH,P3		; Store the byte
	SOJG	P2,U$IN.1	; Loop for all 5 bytes
	CAME	P4,ERRDTM	; Correct value?
U$IN.2:	 SETOM	NOERFL		; No, no error file
	POPJ	P,		; Return
	SUBTTL	Error processing -- U$CINI - Per command initialization

;+
;.hl1 U$CINI
; This routine is called at the start of processing each command. It will
;save the current location within the command buffer for use by the for typeout of
;the command on an error.
;-

U$CINI:	LOAD.	T1,TPTADR,+XCTBUF ; Get the execution buffer address
	LOAD.	T2,BLKPT,(T1)	; Get the pointer
	SUB	T2,CPMLEN	; Minus the length of the prompt
	MOVEM	T2,ERRPT	; And save the start in case of error
	PJRST	U$CLNU		; Go clean up if necessary
	SUBTTL	Error processing -- U$PDLO - Stack overflow routine

;+
;.HL1 U$PDLO
;This routine is an APR trap routine for stack overflows.  Stack overflows
;can occur do to an internal error, or the user pushes too many things
;on the Q register stack.
;-

IFN FTKI,<
TRPPDL:	MOVEM	T1,PDLTRP	; Save the address
	JRST	U$PDLO		; and join common routine
> ; End of IFN FTKI

APRTRP:	PORTAL	.+1		; For EXO entry
	MOVE	T1,.JBTPC	; Get the PC
	AOJ	T1,		; Make it the same as the JSR produces
	MOVEM	T1,PDLTRP	; Save it

U$PDLO:	PORTAL	.+1		; In case EXO entry
	TXZ	F,F.COLN	; Clear the colon flag. Can't continue from these
	JUMPL	P,U$PD.1	; Main stack overflow?
	MOVE	P,SAVEP		; Reset P from start of command processing
	ERROR	E.PDL		; Yes, give up

U$PD.1:	JUMPL	XS,U$PD.3	; Execution stack?
	HRRZ	T1,PDLTRP	; Get the trap address
	HLRZ	T2,-1(T1)	; Get the opcode/ac fields
IFE FTKI,CAXE	T2,(ADJSP XS,)	; Was it the expected instruction?
IFN FTKI,CAXE	T2,(ADD XS,)	; This correct instruction?
	 JRST	U$PD.3		; No, give up
	HRRZ	T1,-1(T1)	; Get the amount the stack was changed
IFE FTKI,HRLI	T1,(T1)		; Put in both halves
IFN FTKI,MOVE	T1,(T1)		; Get the prebuild XWD
	SUB	XS,T1		; And fix up the pointer
	ERROR	E.PDX		; Yes, give that message

U$PD.3:	STOPCD	UPO,<Unknown PDL overflowed>	; Unknown PDL ov error
	SUBTTL	Error processing -- U$STOP - Stopcode processor

;+
;.hl2 U$STOP
;This routine will handle the execution of the STOPCD macro.  It will
;save the user's registers and print out the error message.  It will
;then enter DDT if that is present in the copy of SITGO.
;.literal
;
; Usage:
;	STOPCD	(XXX,<Text>)
;
; Code generated:
;
;	PUSHJ	P,U$STOP
;	JUMP	[Argument block]
;
; Argument block format:
;
;	EXP	<SIXBIT /MODULE/>
;	XWD	'XXX',0
;	ASCIZ	/Text/
;
;
;.end literal
;-

IFN FTDEBUG,<

U$STOP:	MOVEM	0,.SACS			; Store the first register
	HRLI	0,1			; Move the rest of the registers
	HRRI	0,.SACS+1		; . . .
	BLT	0,.SACS+17		; Move all the registers
	XMOVEI	T2,@(P)			; Get the address of the PC
	MOVEM	T2,.SPC			; Store the PC
	XMOVEI	T2,@(T2)		; Get the argument block address
	MOVE	T1,0(T2)		; Get the module name
	MOVEM	T1,.SMOD		; Store it for later
	HLLZ	T1,1(T2)		; Get the name
	MOVEM	T1,.SCODE		; Store the name
	XMOVEI	T1,2(T2)		; Get the address of the text
	MOVEM	T1,STPMSG		; Store it for later
	XMOVEI	T1,STPTXT		; Get the text to output
	PUSHJ	P,T$TYPE		; Output the text to the user
TOPS20<
	MOVX	T1,.FHSLF		; For self
	GETER%				; Get the last error
	  ERJMP	.+1			; Ignore the error return
	MOVEM	T2,.SERR		; Store the last error code
	XMOVEI	T1,[$STRING(<Last TOPS-20 error was: ^O/.SERR/>)]
	PUSHJ	P,T$TYPE		; Output it
>; End of TOPS20 conditional

; Now that the STOPCODE has been typed out we shall determine if we have
; DDT present.  If DDT is present we will jump to it.

	SKIPE	DDTADR			; DDT present?
	  JRST	USTP.0			; Yes, Go enter DDT
	MOVSI	17,.SACS		; Get the address
	BLT	17,17			; Restore the registers
TOPS20<	HALTF%>				; Exit
TOPS10<	EXIT	1,>			; . . .
	JRST	.-1			; Don't allow continues

USTP.0:
TOPS20<
	HRROI	T1,DDTTXT		; Get the address
	PSOUT%				; Output the text to the terminal
>; End of TOPS20 conditional
TOPS10<	OUTSTR	DDTTXT>			; Output the text
	MOVSI	17,.SACS		; Get the address
	BLT	17,17			; Restore the registers
	MOVEM	T1,1(P)			; Save T1 on the stack
	HRRZ	T1,DDTADR		; Get DDT's starting address
	EXCH	T1,1(P)			; Exchange with T1
	PUSHJ	P,@1(P)			; Call DDT
	POPJ	P,			; Return to the caller

; Text constants

STPTXT:	$STRING	(<^M^J?TECO stopcode ^W/.SCODE/ in module ^W/.SMOD/^M^J^T/@IFIW!STPMSG/^M^JEncountered at user PC ^O/.SPC/, Registers saved in .SACS>)

DDTTXT:	ASCIZ	|[Entering DDT]
|

>; End of IFN FTDEBUG
	SUBTTL	Error processing -- U$UUOH - LUUO handler

;+
;.hl2 U$UUOH
; This is the LUUO handling routine. It will handle the error LUUO's.
;-

U$UUOH:	PORTAL	.+1		; For EXO entry
	MOVEM	CH,ERRCH	; Save CH from the error
	PUSH	P,T1		; Save T1
	LOAD	T1,.JBUUO,IW.OPC ; Get the opcode
	CAILE	T1,LUULEN	; Too big?
	JRST	U$UU.E		; Yes, Give the other message
	MOVEI	T1,@LUUTAB(T1)	; Get the address
	EXCH	T1,(P)		; Stuff it on the stack
	POPJ	P,		; Dispatch to the routine

U$UU.E:	MOVE	T1,.JBUUO	; Get the UUO
	ERROR	E.UUO		; And give the UUO

DEFINE LUUENT(UUO,ADDRESS),<
	IFL ..MAX-<UUO_-<ALIGN.(IW.OPC)>>,<..MAX==<UUO_-<ALIGN.(IW.OPC)>>>
	.ORG LUUTAB+<UUO_-<ALIGN.(IW.OPC)>>
	EXP ADDRESS
> ; End of LUUENT definition

LUUTAB:				; Define the table
..MAX==0			; Initial max is zero
	LUUENT(0,U$UU.E)	; Zero is illegal
	LUUENT(.ERR,U$ERR)	; Normal error LUUO
	LUUENT(.WRN,U$WARN)	; Warning

	.ORG	LUUTAB+..MAX+1	; Set to the end of the table

LUULEN==.-LUUTAB		; Define the length
	SUBTTL	Error processing -- U$ERR - Normal error processing

;+
;.hl2 U$ERR
; This routine will process a normal error message. It will type
;out the portion of the message that the user requested, reset the stack
;and return to the command processor.
;-

U$ERR:	SKIPN	ERRLEN		; Have a message level yet?
	 SETOM	ERRLEN		; No, turn them all on
	MOVE	P,SAVEP		; Restore P
	TXZE	F,F.COLN	; Colon flag on?
	 JRST	[PUSHJ	P,U$CLNU	; Clean up
		TXO	F,F.ARG!F.ACLN	; Flag we now have an argument
		TXZ	F,F.COLN	;  and it is from a colon
		PJRST	RETZER]		; And return a zero

	PUSHJ	P,U$WERQ	; Write the error message into the Q-reg
	PUSHJ	P,U$SVCM	; Save the command
	MOVE	P,CMDSVP	; Get the correct stack pointer to abort the command
	PUSH	P,[EXP "?"]	; Store the error character
	POP	P,ERRPRC	; For later
	SETZM	XCTING		; Flag not executing commands anymore
	JMPNS	U$WA.0		; Always type errors if EVOFF
	PUSH	P,T1		; Save T1 a mintue
	LOAD	T1,$QRFLG+ERRQRG,QR$VID ; Get the display flag
	JMPF	T1,[POP P,T1		; If it is displayed, don't bother typing
		JRST	U$WA.0]		; Just return
	MOVX	T1,$CSQUE	; Only question mark allowable
	MOVEM	T1,CMDSTA	; Save it
	PJRST	.T1PJ		; And return
; Here to actually output the error or warning message

U$WA.0:	MOVEM	T1,TYPEAC+T1	; Save T1
	MOVEI	T1,@.JBUUO	; Get the address from the LUUO
	CAILE	T1,E.MAX##	; Is it within range?
	 STOPCD	(EIO,<Error index out of range>) ; No, give up
	ADD	T1,ERRIDX	; Get the address of the index block
	MOVEM	T1,ERRMSG	; And save in a safe place
	MOVE	T1,[XWD T2,TYPEAC+T2] ; Set up to save the AC's
	BLT	T1,TYPEAC+CH	; Through P4
	MOVE	P1,ERRMSG	; Get a copy of the block address
	LOAD.	T1,ERRPFX,(P1)	; Get the prefix
	HRLI	T1,(TECSIX)	; Plus the prefix
	MOVX	T2,$CSQS2	; Assume will only type prefix
	MOVEM	T2,CMDSTA	; Save the state
	MOVX	T2,JW.WPR	; Check if person wants prefix
	TDNN	T2,ERRLEN	;  .  .  .
	 SETZ	T1,		; No, clear it
	MOVEM	T1,ERRPRE	; Save the prefix portion
	MOVEI	T1,[$STRING(<^M^J^7/ERRPRC/^W/ERRPRE/ ^N>)] ; Type the prefix if needed
	PUSHJ	P,T$ERTY	;  .  .  .
	MOVX	T2,JW.WFL	; Need first line?
	TDNN	T2,ERRLEN	;  .  .  .
	 JRST	U$ER.2		; No, skip it
	MOVX	T2,$CSQS1	; Typing the first line, make only one slash legal
	MOVEM	T2,CMDSTA	; Save the new state
	MOVE	T1,ERRMSG	; Get the address
	MOVE	T2,$ERFLG(T1)	; Get the flags
	LOAD.	T1,ERRFST,(T1)	; And the address of the first line
	TXNE	T2,ER$DS1	; First line on disk?
	 PUSHJ	P,U$RDSK	; Set up to read the message
	PUSHJ	P,T$ERTY	; No, type the message

U$ER.2:	MOVX	T2,JW.WCN	; Want continuation?
	TDNN	T2,ERRLEN	;  .  .  .
	 JRST	U$ER.3		; No, skip it
	MOVX	T2,$CSQUE	; Get the new state (only question mark)
	MOVEM	T2,CMDSTA	; Store it
	MOVE	T1,ERRMSG	; Get the message address
	MOVE	T2,$ERFLG(T1)	; Get the flags
	LOAD.	T1,ERRCON,(T1)	; And the message address
	TXNE	T2,ER$DSC	; Continuation on disk?
	 PUSHJ	P,U$RDSK	; Yes, set up to read it
	PUSHJ	P,T$ERTY	; Type the message

U$ER.3:	MOVX	T2,JW.WCN!JW.WFL ; Want only prefix?
	TDNN	T2,ERRLEN	;  .  .  .
	 PJRST	.TCRLF		; Yes, type a crlf
	POPJ	P,		; Return
	SUBTTL	U$WARN - Warning routine

;+
;.hl1 U$WARN
; This routine will handle typeout of warning messages.
;-

U$WARN:	$SAVE	<T1,T2,T3,T4>	; Save the Tx ac's
	$SAVE	<P1,P2,P3,P4>	; Save the Px ac's
	PUSHJ	P,U$WWAQ	; Write the warning into the Q-register
	PUSH	P,[EXP "%"]	; Stack the prefix character
	POP	P,ERRPRC	; Save it
	LOAD	T1,$QRFLG+ERRQRG,QR$VID ; Get the display flag
	JMPT	T1,WARN.0	; Call the warning processor
	PUSHJ	P,U$WA.0	; First call common code with error
WARN.0:	MOVX	T1,$CSNRM	; And reset the command state
	MOVEM	T1,CMDSTA	;  .  .  .
	POPJ	P,		; And return
	SUBTTL	U$SVCM - Save last command for error processing

;+
;.hl1 U$SVCM
; This routine will save the last command in LSTCMD and Q-reg
;"?".
;-

U$SVCM:	$SAVE	<T1,T2,T3,T4,P1> ; Save the temp ac's
	MOVEI	P1,QTAB+QRGIDX(?) ; Get where to store the command
	LOAD.	T1,QRGDTP,(P1)	; Get the old data type
	MOVX	T2,$DTTXT	; And the new
	XCT	RQRGTB(T1)	; And set the new type
	LOAD.	T1,TPTADR,+$QRTPT+CMDBUF ; Get the address
	LOAD.	T3,BLKPT,(T1)	; Get the old pointer
	PUSH	P,T3		; Save it
	PUSHJ	P,C$SCMD	; Save this command in LSTCMD
	LOAD.	T1,TPTADR,+$QRTPT+LSTCMD ; Get the address
	MOVEI	T2,QTAB+QRGIDX(?) ; And the Q-register pointer
	PUSHJ	P,M$USEB	; Set the pointer
	LOAD.	T1,TPTADR,+QTAB+QRGIDX(?) ; Get the address
	POP	P,T2		; Get the old pointer back
	SUB	T2,CPMLEN	; Minus the length of the prompt
	STOR.	T2,BLKPT,(T1)	; And store it back
	MOVEI	T1,ERRBUF	; Get the pointer address
	SKIPE	ERRBUF		; Anything there?
	 PUSHJ	P,M$RELB	; Yes, release it
	LOAD.	T1,TPTADR,+XCTBUF ; Get the buffer address
	MOVEI	T2,ERRBUF	; Get the pointer address
	PJRST	M$USEB		; Set the pointer for the block
	SUBTTL	U$WERQ - Write the error message into the QRG

;+
;.hl1 U$WERQ
; Write the error message into the last error messae Q-register.
;-

	ND	D$EQRS,^D80	; Start with 80 chars

U$WERQ:	PUSH	P,[EXP "?"]	; Save the error character
	SKIPA			; And skip
U$WWAQ:	 PUSH	P,[EXP "%"]	; Save the character
	POP	P,ERRPRC	; Pop off the error prefix character
	SKIPE	ONCFLG		; Doing once only stuff?
	 POPJ	P,		; Yes, forget this
	MOVEM	T1,TYPEAC+T1	; Save T1
	MOVEI	T1,@.JBUUO	; Get the error index
	CAIN	T1,E.EEE##	; Special message?
	 PJRST	T$SRTN		; Yes, make sure the routines are correctly set up
	PUSH	P,T2		; Save T2
	PUSH	P,T3		; And T3
	PUSH	P,T4		; And T4
	BITON	T1,QR$UPD,$QRFLG+ERRQRG ; Flag forced update needed
	LOAD.	T1,TPTADR,+$QRTPT+ERRQRG ; Get the text buffer address
	ZERO.	,BLKPT,(T1)	; Clear the current PT for it
	LOAD.	T2,BLKEND,(T1)	; Get the end
	SETZ	T3,		; And where to delete
	PUSHJ	P,M$SRNK	; Shrink the buffer
	POP	P,T4		; Restore the ac's
	POP	P,T3		;  .  .  .
	POP	P,T2		;  .  .  .
	MOVEI	T1,@.JBUUO	; Get the Index
	ADD	T1,ERRIDX	; Plus the base address
	MOVEM	T1,ERRMSG	; Save the address
	MOVE	T1,[XWD T2,TYPEAC+T2] ; Set up to save the AC's
	BLT	T1,TYPEAC+CH	; Through P4
	MOVE	P1,ERRMSG	; Get a copy of the block address
	LOAD.	T1,ERRPFX,(P1)	; Get the prefix
	HRLI	T1,(TECSIX)	; Plus the prefix
	MOVEM	T1,ERRPRE	; Save the prefix
	MOVEI	T1,ERRQRG	; Get the Q-reg address
	MOVEM	T1,INSQRG	; Save for tye char routine
	MOVEI	T1,[$STRING(<^X/INSCHR/^7/ERRPRC/^W/ERRPRE/ ^N>)] ; Get the string to type the prefix
	PUSHJ	P,T$ERTY	; Type the prefix
	MOVE	T1,ERRMSG	; Get the message address back
	MOVE	T2,$ERFLG(T1)	; Get the flags
	LOAD.	T1,ERRFST,(T1)	; And get the address of the first line
	TXNN	T2,ER$DS1	; On disk?
	  JRST	E$WW.0		; No, Skip this
	PUSHJ	P,U$RDSK	; Yes, set up to read it
	HRRI	T1,INSCHR	; Get the output routine
	JRST	E$WW.1		; Skip the incore set upt

E$WW.0:	MOVEM	T1,ERRPRE	; Store the error prefix
	MOVEI	T1,[$STRING(<^X/INSCHR/^S/@ERRPRE/>)]
E$WW.1:	PUSHJ	P,T$ERTY	; Type the text out
	MOVE	T1,ERRMSG	; Get the address back
	MOVE	T2,$ERFLG(T1)	; And get the flags
	LOAD.	T1,ERRCON,(T1)	; Get the continuation address
	TXNN	T2,ER$DSC	; On disk?
	  JRST	E$WW.2		; No, Skip from reading disk
	PUSHJ	P,U$RDSK	; Set up to read it
	HRRI	T1,INSCHR	; Get the output routine
	JRST	E$WW.3		; Skip this

E$WW.2:	MOVEM	T1,ERRPRE	; Store the error text
	MOVEI	T1,[$STRING(<^X/INSCHR/^S/@ERRPRE/>)]

E$WW.3:	PUSHJ	P,T$ERTY	; Type it ot
	LOAD.	T1,TPTADR,+$QRTPT+ERRQRG ; Get the text buffer address
	SETZ	T2,		; Fix the pointer
	PUSHJ	P,SETINC	; Set it up
	 JFCL			; Ignore this
	POPJ	P,		; And return
	SUBTTL	U$CLNU - Clean up after a file error

;+
;.hl1 U$CLNU
; This routine will clean up the FDB if a file error occurs.
;-



U$CLNU:	SKIPN	T1,LASFDB	; Have an FDB to play with?
	 POPJ	P,		; No, just return
	PUSHJ	P,F$RSET	; Yes, reset the channel
	SETZ	T1,		; Clear the word
	EXCH	T1,LASFDB	; .  .  .
	CAIG	T1,IMPEND	; Is this a preallocated FDB
	 POPJ	P,		; Yes just return
	PJRST	M$RBLK		; And return the core
	SUBTTL	Error processing -- U$RDSK - Set up to read a message

;+
;.hl2 U$RDSK
; This routine will set up T1 for a call to T$ERTY to type a message
;from the error file.
;.b
;.literal
; Usage:
;	MOVE	T1,Disk.address
;	PUSHJ	P,U$RDSK
;	 (return)
;.end literal
;-

U$RDSK:
IFN FTDEBUG,<
	SKIPN	ERFCNT		; Any messages on disk?
	 STOPCD	EMD,<Error message disappeared>
> ; End of IFN FTDEBUG
	SKIPE	NOERFL		; Have the error file?
	 PJRST	U$ERER		; No, give up
	$SAVE	<P1,P2,LASFDB>	; Save P1/P2
	MOVE	P1,T1		; Get the address
	IDIVI	P1,200		; And make the block and word address
	MOVEI	T1,ERRFDB	; Get the FDB address
	MOVE	T2,P1		; And the block number
	ADDI	T2,1		; Point to the block, not the RIB
	PUSHJ	P,F$USET	; Set the block number to input
	 JRST	U$ERER		; Problem - Error reading error file
	ADDM	P2,.FDPTR+ERRFDB ; Fix up the byte pointers
	IMULI	P2,5		; Make this the number of characters
	EXCH	P2,.FDCTR+ERRFDB ; And the
	SUBM	P2,.FDCTR+ERRFDB ; counter
	MOVSI	T1,U$RDER	; Return address,,0
	POPJ	P,		; Return
	SUBTTL	Error processing -- U$RDER - Read a character from the error file

;+
;.hl2 U$RDER
; This routine will read a character from the error  file for the typeout routines.
;-

U$RDER:	$SAVE	<LASFDB>	; Save the LASFDB in case we need to type it
	$SAVE	<T1,T2,T3,T4>	; Save a few registers
	MOVEI	T1,ERRFDB	; Get the address of the FDB
	PUSHJ	P,F$READ	; Read a character
	 JRST	U$ERER		; Give up
	POPJ	P,		; And return it
	SUBTTL	Error processing -- U$ERER - Process an error for the error file

;+
;.hl2 U$ERER
; This routine will handle an error encountered while reading the error
;file.
;-

U$ERER:	ERROR	E.EEE		; Give the error message
	SUBTTL	Error processing -- ERRQUE

;+
;.hl2 ERRQUE
; This routine is called when a question mark (?) is typed after an error
;message has been output. It will type out the portion of the command that
;caused the error.
;-

ERRQUE:	LOAD.	T1,TPTADR,+ERRBUF ; Get the address of the command start
	PUSH	P,$QRTPT+TXTBUF	; Save the text buffer pointer
	STOR.	T1,TPTADR,+$QRTPT+TXTBUF ; And store the command buffer as the text address
	LOAD.	A1,BLKPT,(T1)	; Get the current pointer
	MOVE	A2,ERRPT	; And the starting pointer
	SUBI	A2,^D10		; Start 10 chars back
	JUMPGE	A2,.+2		; Or at start of buffer
	 SETZ	A2,		; It that brings us there
	PUSHJ	P,.TCRLF	; Type a carriage return
	PUSHJ	P,TYPE.1	; Type the command
	MOVEI	CH,"?"		; End with a question mark
	PUSHJ	P,T$OCHR	; Type it
	POP	P,$QRTPT+TXTBUF	; Restore the text buffer pointer
	PJRST	.TCRLF		; And type a crlf
	SUBTTL	Error processing -- ERRSLH

;+
;.hl2 ERRSLH
; This routine is called when a slash (/) is typed after an error message
;has been output. It will type out the next portion of the error message
;and remember it has output this portion.
;-

ERRSLH:	$SAVE	<P1>		; Save P1
	MOVE	P1,ERRMSG	; Get the address of the message block
	MOVE	T1,CMDSTA	; Get the current state
	CAXE	T1,$CSQS2	; Two slashes allowed?
	 JRST	ERRS.1		; No, only one
	LOAD.	T1,ERRFST,(P1)	; Yes, get the address of the first line
	MOVE	T2,$ERFLG(P1)	; And get the flags
	TXNE	T2,ER$DS1	; Message on disk?
	 PUSHJ	P,U$RDSK	; Yes, set up to read it
	PUSHJ	P,T$ERTY	; And type the message
	MOVX	T1,$CSQS1	; Get the new state
	MOVEM	T1,CMDSTA	; Save it
	POPJ	P,		; And return

ERRS.1:	LOAD.	T1,ERRCON,(P1)	; Get the address of the continuation message
	MOVE	T2,$ERFLG(P1)	; Get the flags
	TXNE	T2,ER$DSC	; This on disk?
	 PUSHJ	P,U$RDSK	; Yes, set it up
	PUSHJ	P,T$ERTY	; Type the message
	MOVX	T1,$CSQUE	; Only question mark allowed now
	MOVEM	T1,CMDSTA	; Save it
	POPJ	P,		; And return
	SUBTTL	Low segment

; The following is the low segment for LUUO processing

	$IMPURE			; Impure PSECT
	LOWVER(UUO,3)		; Low segment version number for this module

; STOPCODE locations

IFN FTDEBUG,<

.SPC:	BLOCK	1		; PC that the STOPCODE is at
TOPS20<
.SERR:	BLOCK	1		; Last TOPS-20 error code
>; End of TOPS20 conditional
.SCODE:	BLOCK	1		; Stopcode name
.SMOD:	BLOCK	1		; Module name
TOPS10<CRSHAC:>			; TOPS-10 FILDDT name
TOPS20<BUGACS:>			; TOPS-20 FILDDT name
.SACS:	BLOCK	20		; Stopcode registers
STPMSG:	BLOCK	1		; Address of the STOPCODE text
>; End of IFN FTDEBUG

; General error processing information

PDLTRP:	BLOCK	2		; PDL trap routine
ERRFDB:	BLOCK	.FDLEN		; The FDB for the error file
ERRQRG:	BLOCK	$QRLEN		; QRG holding the last error message
ERRMSG:	BLOCK	1		; Holds the address of the error index block
ERRPRE:	BLOCK	1		; The prefix
ERRPRC:	BLOCK	1		; The character to output before the message
PRMERR:	BLOCK	1		; Monitor error level
ERRLEN:	BLOCK	1		; The message level bits
ERRBUF:	BLOCK	1		; Address of text buffer where error occured
ERRPT:	BLOCK	1		; Index into command buffer for first charcter of command
ERRSTS:	BLOCK	1		; I/O status for error file
ERRCH:	BLOCK	1		; CH at time of error
NOERFL:	BLOCK	1		; -1 if no error file to read from

; Locations in CODE filled in by TECONC

	$CODE			; Put in code section

ERRIDX:	BLOCK	1		; Address of error message index
ERFCNT:	BLOCK	1		; Non-zero if any messages on disk
ERRDTM:	BLOCK	1		; UDT that error file was created
				; stored by TECONC in first word of error file
ONCFLG:	EXP	-1		; Flag saying we are still in TECONC.
				; It will be cleared before TECO.EXE is created
	SUBTTL	End of TECUUO

	END			; End of TECUUO