Google
 

Trailing-Edge - PDP-10 Archives - AP-D543V_SB - errcon.mac
There are 13 other files named errcon.mac in the archive. Click here to see a list.
TITLE ERRCON - MONITOR DETECTED ERROR HANDLING ROUTINES - V5721
SUBTTL T. HASTINGS/TH/CHW/TW/RCC/DAL	07 NOV 78
	SEARCH	F,S
	$RELOC
	$HIGH



;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
;  OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) 1973,1974,1975,1976,1977,1978 BY DIGITAL EQUIPMENT CORP., MAYNARD, MASS.
XP VERRCN,5721
		;THIS MACRO PUTS VERSION NO. IN STORAGE MAP AND GLOB

	ENTRY	ERRCON		;ALWAYS LOAD ERRCON(IF LIB SEARCH)
ERRCON::

;THESE ERROR ROUTINE PRINT "ERROR IN JOB N"
;FOLLOWED BY AN APPROPRIATE ERROR MESSAGE
;THEN THE JOB IS STOPPED AND CONSOLE IS RETURNED TO
;MONITOR COMMAND MODE
;APR DETECTED ERRORS (AND MEMORY PARITY)
;PUSHDOWN OVERFLOW,ILLEGAL MEMORY, NONEXISTENT MEMORY
;FOR WHICH THE USER IS NOT ENABLED.
;SEE APRSER TO SEE HOW APR INTERRUPTS ARE HANDLED
;CALL:	MOVE S,.C0AEF	;RESULT OF CONI APR,.C0AEF (LH USED FOR MEM PARITY)
;	SKIPE S		;ANY ERRORS?
;	PUSHJ P,APRILM	;FROM CLK SERVICE ROUT.(LOWEST PRIOTITY PI)
;	RETURN TO RESCHEDULE NEW USER


APRILM::MOVEM	S,.CPSAC##(P4)	;HERE ON ANY APR ERROR OR MEM PARITY ON CPU0
	SKIPN	J,.CPJOB##(P4)	;CURRENT JOB ON THIS CPU (CPU0)
	SETOM	.CPNJE##(P4)	;MAKE SURE NULL JOBS AC'S ARE RESTORED
	MOVEI	T2,JS.APE	;APR ERROR FOR THIS JOB ON SOME CPU
	ANDCAM	T2,JBTSTS##(J)	;CLEAR FLAG NOW THAT HE IS ON CPU0
				; AND IS TO GET MESSAGE AND BE STOPPED
IFN FTMEMPAR,<			;MEMORY PAR FEATURE?
	JUMPGE	S,APRIL1	;MEMORY PARITY ERR OR PRINT OR SWEEP REQUEST?
	MOVE	T2,JBTPPN##(J)	;PICK UP CURRENT USER'S PPN
	MOVEM	T2,%SYSPP##	;SAVE IT FOR ERROR REPORT
	MOVE	T2,JBTNAM##(J)	;GET HIS PROGRAM
	MOVEM	T2,%SYSPN##	;SAVE IT
	TLNE	S,(CP.PSX!CP.CSX) ;REQUEST TO SWEEP BY CHANNEL OR
				; THIS OR ANOTHER CPU?
	PUSHJ	P,PARSWP	;YES, SWEEP CORE AND RECORD ALL BAD WORDS, FLAG JOBS
	PUSHJ	P,SAVE4##	;SAVE P1-P4(P4 HAS CDB ADR IN IT)
IFN FTMS,<			;DUAL CPU FEATURE?
	TLNE	S,(CP.PP1)	;CPU1 REQUEST PRINT?
	MOVEI	P4,.C1CDB##	;YES, CHANGE SO PRINT CPU1 RESULTS OF SWEEP
>
				; (RESTORE P4 ON EXIT)
;HERE (ON CPU0 ONLY) TO PRINT ERROR MESSAGES ON OPR (OR CTY)
;  AND USER CONSOLES AFTER COMPLETE SWEEP OF MEMORY - P4=CDB DATA TO BE PRINTED

	PUSHJ	P,PARCTY	;PRINT ON CTY AND HALT IF SERIOUS
				; RETURN IF NOT SERIOUS OR CONTINUE AFTER HALT

IFN FTOPRERR,<			;PRINT OPR MESSAGE
	HRRZ	U,OPRLDB##	;OPR (AS OPPOSED TO CTY) LINE DATA BLOCK
	PUSHJ	P,PARRNG	;PRINT RANGE ON OPR USING INTERRUPT SYS
>
	MOVE	J,HIGHJB##	;HIGHEST JOB NUMBER
IFN FTMEMNXM,<
	TRNE	S,UE.NXM	;NXM INSTEAD OF PARITY ERROR?
	JRST	NXMLOP		;YES, REPORT NXM TO ALL JOBS EFFECTED
>
;LOOP TO SCAN ALL JOBS TO PRINT MEMPAR ERROR MESSAGE
PARLOP:	MOVEI	T1,JS.MPE	;MEM PARITY FOR JOB
PARPT2:	TDNN	T1,JBTSTS##(J)	;JOB HAVE MEM PAR IN LOW OR HIGH SEG?
	SOJG	J,PARPT2	;NO, KEEP LOOKING, FINISHED?
	JUMPLE	J,PAREXT	;YES, END OF LOOP?
	ANDCAM	T1,JBTSTS##(J)	;CLEAR THE MPE BIT TO PREVENT REPEAT MESSAGES
	MOVEI	T1,JS.JDP	;PARITY ERROR IN JOB DATA AREA
	TDNN	T1,JBTSTS##(J)	;DID THIS JOB HAVE JOB DATA AREA PARITY?
	JRST	PARPT3		;NO, NO THREAT TO MONITOR THEN
	ANDCAM	T1,JBTSTS##(J)	;YES, CLEAR IN JOB STATUS WORD
	SKIPE	R,JBTADR##(J)	;YES, IS LOW SEG STILL IN CORE (SWAPOUT ERROR SO
				; MIGHT NOT BE)
	PUSHJ	P,CLRJOB##	;YES, CLEAR JOB DATA AREA, AND MAKE IT IMPOSSIBLE
				; FOR JOB TO CONTINUE (JERR), TURN OF JACCT
	PUSHJ	P,ZAPUSR	;RETURN ALL HIS RESOURCES TO SYSTEM
PARPT3:	PUSHJ	P,PARSTP	;PRINT ERROR IN JOB, STOP IT (JERR)
	SOJG	J,PARLOP	;ANYMORE JOBS TO BE LOOKED AT?
;EXIT FROM PARITY SWEEP AND PRINT ROUTINE
PAREXT:
	HRROI	S,UE.PEF	;CLEAR CPU0 APR PARITY ERROR FLAG WORD NOW THAT
				; ERROR HAS BEEN PRINTED
	ANDCAB	S,.C0AEF##	;OTHER APR ERRORS?
	JUMPN	S,APRILM	;YES, GO PROCESS THEM
	POPJ	P,		;RETURN (RESTORE P4 CDB ADR)
IFN FTMEMNXM,<	;DOING NXM?
NXMLOP:	MOVEI	T1,JS.NXM	;JOB OVERLAPS NXM BIT
	TDNN	T1,JBTSTS##(J)	;DOES THIS JOB OVERLAP NXM?
	JRST	NXMLP1		;NO, KEEP LOOKING
	ANDCAM	T1,JBTSTS##(J)	;CLEAR THE BIT
IFN FTMONL,<
	CAME	J,MOFLPG##	;IS THIS THE JOB THAT TYPED SET MEM ON?
>
	SKIPN	R,JBTADR##(J)	;DOES THIS JOB HAVE CORE IN CORE?
	JRST	NXMLP1		;IF NO TO EITHER, DO NOTHING
	PUSHJ	P,ZAPUSR	;ZAP THE PROGRAM
IFN FTLOCK,<
	PUSHJ	P,UNLOCK##	;UNLOCK IT IF LOCKED
>
	PUSHJ	P,NXMSTP	;STOP THE JOB AND TELL THE USER WHAT HAPPENED
NXMLP1:	SOJG	J,NXMLOP	;LOOP OVER ALL JOBS ON THE SYSTEM
	PUSHJ	P,@.CPNMF##(P4)	;FIX CORE ALLOCATION TABLES, ETC.
	 SKIPA			;CORMAX DECREASED
	JRST	NXMXIT		;ALL JOBS NOT ZAPPED CAN CONTINUE TO RUN
;HERE IF CORMAX WAS DECREASED SO ALL JOBS MUST BE SCANNED AND ANY
; WHICH ARE TOO BIG TOO BE SWAPPED IN MUST BE ZAPPED
	MOVEI	J,0		;STARTING WITH JOB 0,
NXMLP2:	MOVE	T1,CORMAX##	; AND THE CURRENT VALUE OF CORMAX (IT MAY
				; HAVE BEEN REDUCED
	PUSHJ	P,JBSTBG	;SEE IF THIS JOB IS NOW TO BIG TO BE RUN
	  JRST	NXMXIT		;ALL JOBS HAVE BEEN LOOKED AT
	PUSHJ	P,NXMSTP	;STOP THE JOB AND TELL THE USER
	JRST	NXMLP2		;SEE IF ANYMORE JOBS ARE TOO BIG
NXMXIT:	HRROI	S,UE.NXM	;CLEAR SOFTWARE NXM FLAG
	ANDCAB	S,.C0AEF##	; ..
	JUMPN	S,APRILM	;GO PROCESS OTHER ERRORS IF THEY EXIST
	POPJ	P,		;OTHERWISE, RETURN

NXMSTP:
IFN FTKI10!FTKL10,<
	PUSHJ	P,SVEUB##	;MAKE SURE JOB IS ADDRESSABLE
>
	PUSHJ	P,ZAPPGM##	;"CORE 0"
	JSP	T1,ERRPNT	;PRINT ERROR MESSAGE FOR THE USER
	ASCIZ	/Nxm error/
	AOS	.CPNJA##(P4)	;COUNT NUMBER OF JOBS ZAPPED BECAUSE OF NXM
	MOVE	T2,.C0MPP##	;PC WHERE THE NXM OCCURRED
	PUSHJ	P,PCP		;PRINT THAT
	PJRST	PCSTOP		;AND STOP THE JOB
>			;END FTMEMNXM
;SUBROUTINE TO PRINT MEM PAR ERROR FOR JOB N AND STOP JOB
;CALL:	MOVE	J,JOB NO
;	PUSHJ	P,PARSTP
;	ALWAYS RETURN

PARSTP:
IFN FTKI10!FTKL10,<
	PUSHJ	P,SVEUB##	;MAKE SURE JOB DATA AREA IS ADDRESSABLE
>
	JSP	T1,ERRPNT	;PRINT STANDARD ERROR IN JOB MESSAGE
	ASCIZ	/Mem par error/
	PUSHJ	P,SIMCHK##	;CAN THIS JOB BE STOPPED NOW?
	  JRST	PARST1		;YES, STOP HIM NOW AND SWAP HIM OUT
	MOVE	T2,.C0MPP##	;NO, GET PC OF MEM PAR INT.
	PUSHJ	P,PCP		;PRINT PC EXEC OR USER
	PUSHJ	P,PRRSP1##	;PRINT CRLF CRLF DOT
	PUSHJ	P,TTYSTC##	;START TTY FOR USER
	PJRST	ECONT		;CONTINUE FROM ERROR TO UUO EXIT

;HERE WHEN OK TO STOP JOB (USER MODE OR NO SHARABLE RESOURCES)
PARST1:	
IFN FTVM,<
	MOVSI	T1,SWP		;DON'T TURN ON JXPN,
	TDNN	T1,JBTSTS##(J)	;IF A SWAP IS IN PROGRESS
>
	PUSHJ	P,XPANDH##	;NO, SWAP HIM OUT - IN CASE HIGH SEG PARITY
				; AND COPY OF HIGH SEG ON DISK (WILL SUPERSEDE).
				; (DO NOT SWAP OUT IF LOCKED)
	PJRST	APRSCD		;AT EXEC/USER PC, START OUTPUT, STOP JOB
				; RETURN TO CALLER SINCE AT PI 7
				; POP OFF ACS WHICH ERRPNT PUSHED.

;SUBROUTINE TO CHECK IF SERIOUS MEM PARITY ERROR
; IF YES, PRINT RANGE FOR OPER  ON CTY THEN HALT


PARCTY::SKIPL	.CPMPC##(P4)	;IS THIS A SERIOUS PARITY ERROR
	POPJ	P,		;NO,
IFN FTKL10,<
	PUSHJ	P,SVPPC##	;IN CASE PRIMARY PROTOCOL IS RUNNING
>;END IFN FTKL10
IFN FTOPRERR,<
	PUSH	P,COMTOA##	;YES, SAVE ADR OF OUTPUT 1 CHARACTER ROUTINE
	MOVEI	T1,CTYWAT##	;REPLACE IT WITH ONE WHICH DOES NOT USE INTERRUPTS
	HRRM	T1,COMTOA##	;STORE SO MESSAGE WILL DEFINITELY GET TO OPER
	HRRZ	U,CTYLDB##	;CTY LINE DATA BLOCK ADDRESS
				; CANNOT USE OPR BECAUSE CANNOT DEPEND ON INTERRUPTS
	CONO	PI,PIOFF##	;NO INTERRUPTS DURING TYPEOUT
IFN FTMEMNXM,<
	SKIPN	.CPREP##(P4)	;A PARITY ERROR? (NOT NXM)
	JRST	NXMCTY		;NO, NXM REPORT NXM INSTEAD
>
	PUSHJ	P,INLMES##	;PRINT MESSAGE TO INFORM OPER OF HALT
	ASCIZ	/
?Mem par HALT/
	PUSHJ	P,PARRNG	;PRINT RANGE OF BAD ADDRESSES TO CTY SO HE CAN
				; RECONFIGURE
IFN FTKL10,<
PARCT0:	PUSHJ	P,INLMES##
	ASCIZ/
CONTINUE SYSTEM(Y OR <CR>)?/
	SETO	T1,		;FLAG, GE 0 MEANS CONTINUE
PARCT1:	PUSHJ	P,SPCGTI##	;GET CHARACTER IN T3
	  JRST	.-1		;NOT READY YET
	PUSHJ	P,CTYWAT##	;ECHO THE CHARACTER
	ANDI	T3,177		;JUST CHAR, NO PARITY
	CAIN	T3,15		;CR?
	JRST	PARCT2		;YES, DONE
	TRZ	T3,40		;CONVERT TO UPPER CASE
	CAIE	T3,"Y"		;FIRST CHAR A Y? (NOT LF OR CR)
	JRST	PARCT0		;NO, GO BITCH AND ASK AGAIN.
	AOJA	T1,PARCT1	;SAY YES AND LOOK FOR LF
PARCT2:	MOVEI	T3,12		;ECHO LINE FEED AS WELL AS CR
	PUSHJ	P,CTYWAT##	;TYPE IT OUT

>;END IFN FTKL10
	POP	P,COMTOA##	;RESTORE INTERRUPT DRIVEN OUTPUT (IN CASE CONT)
>				;END FTOPRERR
IFN FTKL10&FTOPRERR,<
	SKIPGE	T1		;SKIP IF CONTINUING SYSTEM
>
	STOPCD	.+1,HALT,MMP,	;++MONITOR MEMORY PARITY
				; MONITOR HAS REFERENCED AN INSTR. OR IMPORTANT
				; DATA WITH BAD PARITY
				; DO A REAL HALT SO OPER CAN PUSH CONT
				; IF TSTPAR, OR CAN TYPE PARITY TO WHY RELOAD
NXMCON:	HRRZS	.CPMPC##(P4)	;CLEAR SERIOUS ERROR FLAG (LH)
	AOS	.CPMPC##(P4)	;COUNT NO. OF CONTINUES -
				; SO IF CRASH LATER WE WILL KNOW
	PJRST	ONPOPJ##	; RETURN



IFN FTMEMNXM,<
NXMCTY:
IFN FTOPRERR,<
	PUSHJ	P,INLMES##	;INFORM OPR OF HALT
	ASCIZ	/?Nxm HALT/
	PUSHJ	P,PARRNG	;REPORT RANGE OF ERRORS SO OPR CAN RECONFIGURE
	POP	P,COMTOA##	;RESTORE INTERRUPT DRIVEN OUTPUT
>
	STOPCD	NXMCON,HALT,MMN,	;MONITOR MEMORY NON-EXISTANT
>
;SUBROUTINE TO PRINT RANGE OF BAD PARITY ADRS SO OPER CAN RECONFIGURE
;CALL:	HRRZ	U,LINE DATA BLOCK ADDRESS (CTY OR OPR)
;	PUSHJ	P,PARRNG
;	ALWAYS RETURN

IFN FTOPRERR,<			;PRINT MEMPAR TO OPER
PARRNG:	PUSHJ	P,SAVE1##	;SAVE P1
IFN FTDAEM,<
	MOVSI	T1,(P4)		;GET CDB ADDR IN LH OF T1 FOR DAEMON
	HRRI	T1,.ERMPE	; AND PARITY ERROR CODE IN RH FOR DAEMON
IFN FTMEMNXM,<
	SKIPN	.CPREP##(P4)	;A PARITY ERROR? (NOT NXM)
	HRRI	T1,.ERNXM	;NO, MAKE CODE SAY NXM
>
	PUSHJ	P,DAEEIM##	;CALL DAEMON TO LOG ERROR
>
	PUSHJ	P,INLMES##	;PRINT MESSAGE TO AWAKEN OPER
	ASCIZ	/
?/
IFN FTMEMNXM,<
	SKIPN	.CPREP##(P4)	;A PARITY ERROR? (NOT NXM)
	SKIPA	P1,.CPNTS##(P4)	;NO, NXM GET COUNT OR NXM LOCATIONS THIS SWEEP
>
	MOVE	P1,.CPPTS##(P4)	;NO. OF PARITY ERRORS THIS SWEEP
	MOVE	T1,P1		;NUMBER OF ERRORS
	PUSHJ	P,RADX10	;DECIMAL
	MOVEI	T1,[ASCIZ / mem par err/]
IFN FTMEMNXM,<
	SKIPN	.CPREP##(P4)	;A PARITY ERROR? (NOT NXM)
	MOVEI	T1,[ASCIZ  / nxm err/]
>
	PUSHJ	P,CONMES##	;TELL HIM WHAT NUMBERS ARE
	JUMPE	P1,PARJBN	;IF NONE FOUND, JUST PRINT JOB NUMBER
	MOVEI	T1,[ASCIZ /s from /]	;ASSUME PRINT PLURAL
	CAIG	P1,1		;YES, MORE THAN 1 PARITY ERROR?
	MOVEI	T1,[ASCIZ / at /]	;NO, JUST PRINT SINGULAR
	PUSHJ	P,CONMES##	;OUTPUT TO USER
IFN FTMEMNXM,<
	SKIPN	.CPREP##(P4)	;A PARITY ERROR? (NOT NXM)
	SKIPA	T1,.CPMNA##(P4)	;FIRST NXM ADDRESS
>
	MOVE	T1,.CPMPA##(P4)	;FIRST ABS. BAD MEMORY ADDRESS
	PUSHJ	P,PRT22A	;PRINT AS LEADING ZERO SUPPRESSED 22 BIT OCTAL
	SOJLE	P1,PARJBN	;DO NOT PRINT LAST ADR IF ONE OR LESS
	PUSHJ	P,INLMES##	;SEPARATE LOW AND HIGH
	ASCIZ	/ to /
IFN FTMEMNXM,<
	SKIPN	.CPREP##(P4)	;A PARITY ERROR? (NOT NXM)
	SKIPA	T1,.CPLNA##(P4)	;LAST NXM ADDRESS
>
	MOVE	T1,.CPLPA##(P4)	;LAST ABS. BAD MEMORY ADDRESS
	PUSHJ	P,PRT22A	;PRINT AS LEADING ZEROES SUPPRESSED 22 BIT OCTAL
PARJBN:	PUSHJ	P,INLMES##	;PRINT CPU WHICH FOUND ERROR
	ASCIZ	/ on /
	MOVE	S,.C0AEF##	;APR ERROR FLAG WORD FOR CPU0
				; (SINCE PRINT ONLY ON CPU0)
	TLNN	S,(CP.PSX!CP.PPX)	;PARITY FOUND BY SOME CPU (AS OPPOSED TO CHAN)?
	JRST	PARCHN		;NO, PRINT LOGICAL CHANNEL #
	MOVE	T2,.CPLOG##(P4)	;YES, PRINT CPUN (CPU0 OR CPU1)
	PUSHJ	P,PRNAME	;OF CPU WHICH FOUND BAD PARITY
	MOVEI	T1,JS.MPE	;JOB HAS BAD MEM PARITY JOB STATUS BIT
IFN FTMEMNXM,<
	SKIPN	.CPREP##(P4)	;A PARITY ERROR? (NOT NXM)
	MOVEI	T1,JS.NXM	;NO, REPORT ALL JOBS WHICH GOT NXM
>
	SETZM	.CPREP##(P4)	;NOW CLEAR THE FLAG WHICH TOLD US WHICH ERROR TO REPORT, PARITY OR NXM
	SKIPN	P1		;IF NO ERRORS
	 PJRST	CRLF##		;JUST PRINT A CRLF
	PJRST	OPRPJN		;PRINT ALL JOB # AND PROG NAME ON OPR
;HERE WHEN PARITY FOUND BY CHANNEL
PARCHN:	PUSHJ	P,INLMES##	;NO, PRINT CHANNEL NUMBER
	ASCIZ	/channel /
	MOVEI	T1,5		;START WITH CHANNEL 5
PARCLP:	ROT	S,-1		;NEXT CHANNEL
	TRNN	S,<CP.CS5_-1>	;IS IT THIS CHANNEL?
	SOJGE	T1,PARCLP	;NO, TRY NEXT CHANNEL
	PUSHJ	P,RADX10	;YES, PRINT CHANNEL NUMBER
	PJRST	CRLF##		;PRINT CRLF
;SUBROUTINE TO PRINT 22 BIT OCTAL ADDRESS
;CALL:	MOVE	T1,22 BIT ADDRESS
;	PUSHJ	P,PRT22A
;	ALWAYS RETURN

PRT22A::PUSH	P,T1		;SAVE 22 BIT ADDRESS
	HLRZ	T1,(P)		;GET HIGH ORDER HALF
	JUMPE	T1,PRT22B	;IS IT 0 (USUALLY EXCEPT BIG SYSTEMS)
	PUSHJ	P,PRTDI8	;NO, PRINT AS LEADING 0 SUPPRESSED OCTAL
PRT22B:	POP	P,T1		;GET LOW ORDER HALF
	PJRST	OCTPNT		;PRINT AS NON ZERO SUPPRESSED OCTAL (RH ONLY)
>				;END FTOPRERR
				; STILL INSIDE FTMEMPAR

;SUBROUTINE TO SWEEP CORE FOR ALL BAD MEMORY PARITY WORDS AND RECORD
;CALLED BY CPU0 AND CPU1
;CALL:
;	MOVE	J,CURRENT JOB NO. ON THIS CPU
;	MOVE	S,.CPAEF(P4) SWEEP REQUEST BITS
;	PUSHJ	P,PARSWP
;	ALWAYS RETURNS - LH .CPMPC SET NEG. IF SERIOUS MONITOR PARITY
;	S PRESERVED


PARSWP::

;SUB. TO SWEEP CORE ON APR PI OR PI 7 -
;CALLED AT APR PI IF MAY BE A SERIOUS ERROR IN MONITOR AND PIS IN PROGRESS
; AC S SET TO COPY OF .CPAEF LH INDICATING WHETHER CPU OR CHANNEL DETECTED PAR


PARSW1::
IFN FTMEMNXM,<
	TRNN	S,UE.PEF	;PARITY ERROR?
	JRST	NXMSWP		;NO, SWEEP FOR NXM
>
	SETOM	.CPREP##(P4)	;TELL REPORTERS WHICH ERROR TYPE TO REPORT
	SETOM	.CPPAA##(P4)	;YES, SET PARITY AND OF BAD ADDRESSES TO -1
	SETOM	.CPPAC##(P4)	;SET PARITY AND OF BAD CONTENTS TO -1
	SETZM	.CPPOA##(P4)	;SET PARITY OR OF BAD ADDRESSES TO 0
	SETZM	.CPPOC##(P4)	;SET PARITY OR OF BAD CONTENTS TO 0
	AOS	.CPPSC##(P4)	;INCREMENT PARITY SWEEP COUNT
	SETZM	.CPPTS##(P4)	;SET NO OF PARITIES THIS SWEEP TO 0
IFN FTKL10,<
	PUSHJ	P,SVPPC##	;SAVE PRIMARY PROTOCOL, GO BACK TO SECONDARY
>
	PUSHJ	P,@.CPMPS##(P4)	;CALL CPU DEPENDENT CORE SWEEP ROUTINE
				; IT WILL CALL PARRBD (BELOW) ON EACH BAD
				; WORD
	SETZM	.CPLPP##(P4)	;CLEAR LAST PARITY ERROR PC
				; (USED TO DETECT PARITY ERROR LOOPS AT APR LEVEL
				; ON INSTRUCTION FETCHES)
	SKIPE	.CPPTS##(P4)	;WERE SOME BAD WORDS FOUND ON SWEEP?
	POPJ P,			;YES RETURN AFTER MESSAGE
	TLNN	S,(CP.PSX)	;NO, DID PROCESSOR DETECT PARITY?
	AOSA	.CPPCS##(P4)	;NO, COUNT CHANNEL SPURIOUS COUNT
	AOSA	.CPSPE##(P4)	;YES, COUNT PROCESSOR SPURIOUS COUNT
	POPJ P,			;RETURN - CHANNEL SPURIOUS COUNT
;HERE ON NO PARITY FOUND ON SWEEP - COULD BE READ - PAUSE - WRITE
IFE FTKL10,<				;NOT FOR KL-10'S
	MOVE	T1,.CPAPC##(P4)	;MEMORY PARITY PC (STORED BEFORE SWEEP)
	TLNN	T1,(XC.USR)	;WAS PC IN USER MODE?
	HRROS	.CPMPC##(P4)	;NO, SERIOUS BECAUSE HAVE TO ASSUME
				; PARITY WAS IN MONITOR AREA - HALT FLAG
				; SO PRINT ON CTY
	MOVE	J,.CPJOB##(P4)	;CURRENT JOB # THIS CPU
IFN FT2REL,<			;2 RELOC REG. SOFTWARE?
	PUSHJ	P,HGHSPE##	;FLAG ALL JOBS IF HIGH SEG DOES NOT HAVE DISK COPY
				; SINCE PARITY MAY BE IN HIGH SEG, ELSE SWAP OUT ALL
				; JOBS USING HIGH SEG.
>
	PUSHJ	P,PARJB1		;ALWAYS FLAG CURRENT USER

	POPJ P,	
>;END IFE FTKL10
IFN FTKL10,<
	POPJ P,	
>;END IFN FTKL10
				; SINCE PARITY MAY BE IN HIS JOB (READ-PAUSE-WRITE)
;SUBROUTINE TO SWEEP CORE LOOKING FOR NON-EXISTANT MEMORY

IFN FTMEMNXM,<
NXMSWP:	SETOM	.CPNAA##(P4)	;CLEAR AND OF NON-EXISTANT ADDRESSES
	SETZM	.CPNOA##(P4)	; AND OR OF NON-EXISTANT ADDRESSES
	SETZM	.CPNJA##(P4)	;NO JOBS AFFECTED YET
	AOS	.CPNSC##(P4)	;INCREMENT THE NUMBER OF NXM SWEEPS DONE
	SETZM	.CPNTS##(P4)	;CLEAR THE COUNT OF NXMS SEEN THIS SWEEP
	PUSHJ	P,@.CPMPS##(P4)	;SWEEP CORE
	SETZM	.CPLPP##(P4)	;CLEAR FLAG SAYING SWEEP IN PROGRESS
	SKIPE	.CPNTS##(P4)	;ANY NON-EXISTANT MEMORY SEEN?
	POPJ P,			;YES, THINGS WILL BE REPORTED
	TLNE	S,(CP.PSX)	;DID THE PROCESSOR SEE THE NXM?
	AOSA	.CPTNE##(P4)	;YES, COUNT PROCESSOR SPURIOUS COUNT
	AOSA	.CPNCS##(P4)	;NO, COUNT SPURIOUS CHANNEL NXMS
	CONSZ	PI,PI.IPA-PI.IP7;??????
	POPJ P,			;RETURN IF NOT SEEN BY PROCESSOR
	JRST	APRNXM		;REPORT NXM (PROBABLY A SOFTWARE ERROR)

;HERE TO RECORD NON-EXISTANT MEMORY FOUND ON THE SWEEP

NXMRBD:	AOS	.CPTNE##(P4)	;COUNT TOTAL NUMBER OF NXMS SEEN
	AOS	T2,.CPNTS##(P4)	;COUNT UP THE NUMBER SEEN THIS SWEEP
	SOJG	T2,NXMSEC	;JUMP IF NOT THE FIRST NXM THIS SWEEP
	MOVEM	P1,.CPMNA##(P4)	;FIRST THIS SWEEP, RECORD BAD ADDRESS
	MOVEM	T1,.CPMNR##(P4)	;AND BAD RELATIVE ADDRESS
NXMSEC:	ANDM	P1,.CPNAA##(P4)	;AND OF BAD ADDRESSES
	IORM	P1,.CPNOA##(P4)	;OR OF BAD ADDRESSES
	MOVEI	T3,.CPBAT##(T2)	;ADDRESS OF BAD ADDRESS TABLE
	HRLI	T3,P4		;SET FOR INDIRECTION
	CAIGE	T2,M.CBAT##	;HAVE THE MAXIMUM NUMBER OF BAD ADDRESSES BEEN STORED?
	MOVEM	P1,@T3		;NO, STORE THIS ONE
	MOVEM	P1,.CPLNA##(P4)	;ALWAYS STORE THE LAST BAD ADDRESS
	MOVE	T1,P1		;BAD ADDRESS TO T1
	LSH	T1,W2PLSH##	;CONVERT TO BAD PAGE
	IDIVI	T1,^D36		;36 BITS/WORD
	MOVE	T2,BITTBL##(T2)	;BIT POSITION WITHIN THE WORD
	IORM	T2,NXMTAB##(T1)	;MARK THIS PAGE AS NON-EXISTANT
	JUMPL	J,CPOPJ##	;RETURN IF BAD ADDRESS NOT IN THE MONITOR OR A JOB
	JUMPN	J,NXMJHS	;JUMP IF BAD ADDRESS IN SOME SEGMENT
	HRROS	.CPMPC##(P4)	;BAD ADDRESS IS IN THE MONITOR,
				; FLAG THIS AS A SERIOUS ERROR
	POPJ	P,		;AND CONTINUE THE SWEEP
NXMJHS:	CAILE	J,JOBMAX##	;BAD ADDRESS IN A HIGH SEGMENT?
	PJRST	HGHPAR##	;YES, FLAG HIGH SEGMENT AS IN NXM
	MOVEI	T1,JS.NXM	;BAD ADDRESS IN A LOW SEGMENT, FLAG
	IORM	T1,JBTSTS##(J)	; THE JOB TO BE STOPPED
	POPJ	P,		;AND RETURN TO CONTINUE THE SWEEP
>

;SUBROUTINE TO RECORD MEM PARITY DATA FOR EACH BAD WORD
;CALL:	MOVE	T1,REL ADDR WITHIN HIGH OR LOW SEG,
;			-1 IF NEITHER IN MONITOR NOR HIGH NOR LOW SEG
;	MOVE	P1,ABS ADR OF BAD WORD (22 BITS)
;	MOVE	S,.CPAEF(P4) FLAG BITS
;				;FLAG JOBS TO STOP IS CPU SWEEP REQUEST ON
;	MOVE	P2,CONTENTS OF BAD WORD
;	PUSHJ	P,PARRBD	;RECORD BAD DATA
;	ALWAYS RETURN EVEN IF SERIOUS ERROR
;CALLED FROM CPU DPENDENT MEMORY SWEEP LOOP

PARRBD::
IFN FTMEMNXM,<
	TRNN	S,UE.PEF	;A PARITY ERROR?
	JRST	NXMRBD		;NO, RECORD NXM
>
	AOS	.CPTPE##(P4)	;INCREMENTATION NO OF MEM PARITY ERRORS FOR SYSTEM
	AOS	T2,.CPPTS##(P4)	;INCREMENT NO OF PARITY ERRORS THIS SWEEP
	SOJG	T2,PARSEC	;IS THIS THE FIRST ERROR THIS SWEEP?
	MOVEM	P1,.CPMPA##(P4)	;YES, SAVE BAD ADDRESS
	MOVEM	P2,.CPMPW##(P4)	;BAD CONTENTS
	MOVEM	T1,.CPMPR##(P4)	;RELATIVE (NOT VIRTUAL) ADDRESS WITHIN HIGH OR
				; LOW SEG.

;HERE ON SECOND AND SUCCEEDING BAD WORDS ON SWEEP
PARSEC:	ANDM	P1,.CPPAA##(P4)	;ACCUM AND OF BAD ADDRESSES THIS SWEEP
	ANDM	P2,.CPPAC##(P4)	;ACCUM AND OF BAD CONTENTS THIS SWEEP
	IORM	P1,.CPPOA##(P4)	;ACCUM OR OF BAD ADDRESSES THIS SWEEP
	IORM	P2,.CPPOC##(P4)	;ACCUM OR OF BAD CONTENTS THIS SWEEP
	MOVEI	T3,.CPBAT##(T2)	;REL. ADR IN CDB TO STORE BAD ADR.
	HRLI	T3,P4		;GET SET FOR DOUBLE INDEXING INTO CDB
	CAIGE	T2,M.CBAT##	;IS THERE ROOM FOR THIS BAD ADR IN TABLE?
	MOVEM	P1,@T3		;YES, STORE IN I-TH POSITION IN CDB
	MOVEM	P1,.CPLPA##(P4)	;ALWAYS STORE LAST PARITY ADDRESS
	JUMPL	T1,CPOPJ##	;IF ADDR NOT IN MONITOR OR LOW OR HIGH SEG, JUST POPJ
PARSC1:	JUMPN	J,PARJHS	;WAS ERROR IN A LOW OR HIGH SEG?
;HERE ON BAD PARITY IN MONITOR
	CAIE	P1,MLCPEW##	;IS IT IN THE PARITY TEST LOCATION
	HRROS	.CPMPC##(P4)	;NO, FLAG AS SERIOUS ERROR - MUST HALT AFTER PRINT
	POPJ	P,		;RETURN (CURRENT JOB ALREADY FLAGGED TO STOP)

;HERE IF BAD JOB OR HIGH SEG - T1 STILL HAS REL. ADR. WITHIN SEG
PARJHS:
IFN FT2REL,<
	CAILE	J,JOBMAX##	;IS PARITY ERROR IN LOW SEGMENT?
	PJRST	HGHPAR##	;NO, GO FIND ALL JOBS USING THIS HIGH SEG
				; AND CALL PARJOB FOR EACH ONE WHICH DOESN'T HAVE
				; HIGH SEG DISK COPY
>
;HERE IF LOW SEG AND PARITY ERROR IN IT
	MOVEI	T2,JS.JDP!JS.MPE  ;GET SET TO FLAG ERROR IN JOB DATA AREA
	CAIG	T1,JOBPFI##	;IS REL ADR IN PROTECTED PART OF JOB DATA AREA?
	IORM	T2,JBTSTS##(J)	;YES, FLAG THAT THIS CRITICAL DATA
				; IS NO LONGER TRUSTWORTHY
				; FALL INTO PARJOB
;SUBROUTINE TO FLAG JOB FOR MESSAGE - IF APR DETECTED (RATHER THAN CHANNEL)
;CALL:	MOVE	J,JOB NUMBER
;	MOVE	S.CPAEF(P4)	;CPU OR CHAN DETECTED PARITY
;	PUSHJ	P,PARJOB
;	ALWAYS RETURN
;CALLED ON CPU0 AND CPU1

PARJOB:	TLNN	S,(CP.PSX)	;PARITY FOUND BY ANY PROCESSOR?
	POPJ	P,		;NO, RETURN
				;YES, FALL INTO PARJB1
;SUBROUTINE TO FLAG JOB FOR MEM PAR MESSAGE - ALWAYS
;CALL:	MOVE	J,JOB NUMBER
;	PUSHJ	P,PARJB1
;	ALWAYS RETURN

PARJB1::MOVSI	T1,JACCT	;CLEAR JACCT SO THAT DAMAGED PROGRAM
	ANDCAM	T1,JBTSTS##(J)	; WILL NOT HAVE PRIVILEGES
	MOVEI	T1,JS.MPE	;MEMORY PARITY ERROR IN JOB FLAG
	IORM	T1,JBTSTS##(J)	;SET JOB STATUS WORD
	POPJ	P,		;RETURN

IFN FTMEMNXM,<

;SUBROUTINE TO RETURN ALL JOBS WHICH ARE OR WOULD BE TOO BIG TO RUN
; IF MEMORY HAS DROPPED OFF LINE OR WERE TO BE SET OFF LINE
;CALLING SEQUENCE:
;	MOVE	T1,NEW VALUE OF CORMAX
;	MOVEI	J,0	;FIRST CALL
;	PUSHJ	P,JBSTBG
;RETURN CPOPJ IF NO JOB OR NONE OF THE REMAINING JOBS ARE TOO BIG, CPOPJ1
; IF A JOB IS TOO BIG, J = JOB NUMBER OF THE JOB WHICH IS TOO BIG

JBSTBG::PUSH	P,T1		;SAVE THE NEW VALUE OF CORMAX
JBSTB1:	ADDI	J,1		;LOOK AT THE NEXT JOB
	CAMLE	J,HIGHJB##	;LOOKED AT ALL JOBS?
	JRST	TPOPJ##		;YES, GIVE ALL DONE RETURN
	PUSHJ	P,SEGSIZ##	;SIZE OF THIS JOBS LOW SEGMENT
	MOVE	T1,T2		;SAVE THAT
	PUSH	P,J		;SAVE THE JOB NUMBER
	MOVEI	T2,0		;ASSUME THAT THE JOB DOESN'T HAVE A HIGH SEGMENT
	SKIPLE	J,JBTSGN##(J)	;DOES IT?
	PUSHJ	P,SEGSIZ##	;YES, GET THE SIZE OF THE HIGH SEGMENT
	POP	P,J		;RESTORE THE JOB NUMBER
	ADD	T1,T2		;SIZE OF THE JOB IN PAGES
	LSH	T1,P2WLSH##	;SIZE OF THE JOB IN WORDS
	CAMLE	T1,(P)		;IS THE JOB TOO BIG TO CONTINUE TO RUN?
	JRST	TPOPJ1##	;YES, SKIP RETURN TO CALLER
	JRST	JBSTB1		;NO, LOOK AT THE NEXT JOB
> ;END FTMEMNXM
>				;FINALLY END FTMEMPAR
;HERE IF NO MEM PARITY - MUST BE APR ERROR
APRIL1:	SETZM	.C0AEF##	;CLEAR APR ERROR FLAG (IN CASE OTHER APR ERRORS
				; OCCUR BEFORE EXIT THIS CODE)
	MOVE	T1,.C0APC##	;ERROR PC STORED BY APR PI LEVEL
				; (REAL PC MAY HAVE BEEN ZEROED TO DISMISS INT)
	MOVEM	T1,.C0PC##	;STORE IN CURRENT USER PROTECTED PC
				; (SO DUMP WILL KNOW REAL PC)
IFN FTKI10!FTKL10,<
	TRNE	S,AP.PPV
	JRST	APRPPV
>
	TRNN	S,AP.ILM	;ILLEGAL MEMORY?
	JRST	APRNXM		;NO
IFN FTPI,<
	MOVEM	T1,JOBPD1##(R)	;SAVE TRAP PC FOR PSISER
	SIGNAL	C$IMR		;SIGNAL ILL MEM REF CONDITION
	  POPJ	P,		;WANTS INTERCEPT GO TO USER
>
	HRRZ	T1,.C0APC##	;PC STORED BY APR INTERRUPT
IFE FT2REL,<
	CAMG	T1,USRREL##	;IS PC IN BOUNDS/
>
IFN FT2REL,<
	CAMLE	T1,USRREL##	;IS PC IN BOUNDS(LOW SEG)?
	PUSHJ	P,SEGILM##	;NO, IS PC IN LEGAL MEMORY IN HIGH SEG?
>
	JRST	APRILR		;YES, GO PRINT ILL MEM REF
	JSP	T1,ERRPTU	;NO, PRINT PC EXCEEDS MEM BOUND
	ASCIZ	/PC out of bounds/
	JRST	APRSCD		;PRINT LOC, THEN STOP JOB

APRILR:	JSP	T1,ERRPTU
	ASCIZ	/Ill mem ref/
	JRST	APRSCD		;PRINT LOC, THEN STOP JOB

APRNXM:	TRNN	S,AP.NXM	;NON-EX MEM?
	JRST	APRPDL		;NO
IFN FTPI,<
	SIGNAL	C$NXM		;SIGNAL NXM CONDITION
	  POPJ	P,		;GO TO USER
>
	SKIPE	J,.C0JOB##	;JOB RUNNING WHEN NXM HAPPENED
	PUSHJ	P,GIVRES	;RETURN RESOURCES, ETC.
	JSP	T1,ERRPTU	;YES
NXMMES::ASCIZ	/Non ex mem/
	JRST	APRSCD		;PRINT LOC, THEN STOP JOB
IFN FTKI10!FTKL10,<
APRPPV:	JSP	T1,ERRPTU
	ASCIZ	/Proprietary violation/
	JRST	APRSCD
>
;SUBROUTINE TO PRINT JOB NUMBER AND PROG NAME ON OPR
;CALL:	MOVEI	T1,JOB STATUS BIT (JS.MPE OR JS.DPM)
;	MOVE	U,LINE DATA BLOCK FOR CTY OR OPR
;	PUSHJ	P,OPRPJN	;PRINT JOB NUMBERS
;	ALWAYS RETURN

IFN FTOPRERR*<FTMEMPAR+FTDAEM>,<	;INCLUDE IF FTOPRERR AND (MEM PARITY OR DAEMON)
OPRPJN:	PUSH	P,T1		;SAVE JOB STATUS BIT TO TEST FOR MESSAGE
	PUSHJ	P,INLMES##	;TELL HIM JOB NOS. SO HE WILL RESTART
				; SYSTEM JOBS IF THEY HAVE PROBLEM
	ASCIZ	/ for job/
	MOVE	J,HIGHJB##	;HIGHEST JOB NUMBER
;LOOP TO PRINT JOB NOS. AND PROGRAM NAME OF ALL JOBS WITH BAD PARITY
; OR DAEMON PROBLEM MESS
PARLP1:	MOVE	T1,JBTSTS##(J)	;JOB STATUS WORD
	TDNE	T1,(P)		;DOES THIS JOB HAVE BAD PARITY OR DAEMON
				; PROBLEM? (DEPENDING ON CALLERS ARG)
	PUSHJ	P,PRJBNM	;YES, PRINT JOB# AND PROGRAM NAME
	SOJG	J,PARLP1	;ANY MORE JOBS?
	POP	P,T1		;RESTORE STACK
	PJRST	CRLF##		;NO, PRINT CRLF AND RETURN
>				;END FTOPRERR AND (MEM PARITY OR DAEMON)

;SUBROUTINE TO PRINT SWAP OUT MEM PAR ERROR
;CALL:	MOVE	J,JOB USING HIGH SEG (WHETHER IN CORE OR NOT)
;	PUSHJ	P,SWOMES
;	ALWAYS RETURN JOB SWAPPED, DAEMON CALLED

SWOMES::MOVSI	T1,JERR		;SET JERR SO WE DO NOT
	IORM	T1,JBTSTS##(J)	;TRY TO INTERCEPT
	JSP	T1,ERRPNT	;PRINT MESSAGE
	ASCIZ	/Swap out chn mem par err/
	PJRST	APRSCD		;PRINT PC AND STOP JOB

IFN FTOPRERR,<
;SUBROUTINE TO PRINT <SPACE> JOB NO. [PROG. NAME]
;CALL:
;	MOVE	J,JOB NUMBER
;	MOVE	U,LDB FOR OPR OR CTY
;	PUSHJ	P,PRJBNM		;PRINT JOB NO. AND PROG. NAME
;	ALWAYS RETURN
PRJBNM::PUSHJ	P,PRSPC##	;YES, PRINT LEADING SPACE
	MOVE	T1,J		;PRINT JOB NO.
	PUSHJ	P,RADX10	;AS DECIMAL
	PUSHJ	P,PRLBK##	;PRINT LEFT BRACKET
	MOVE	T2,JBTPRG##(J)	;PROGRAM NAME
	PUSHJ	P,PRNAME	;PRINT SO OPER WILL RECOGNIZE HIS JOBS
	PUSHJ	P,PRRBK##	;PRINT RIGHT BRACKET
	POPJ	P,		;RETURN
>			;END FTOPRERR
;SUBROUTINE TO CHECK IF JOB HAS BEEN WAITING FOR TWO SUCCESSIVE
; MINUTE CHECKS FOR DAEMON.  CALLED ONCE A MINUTE FOR EACH JOB
;CALL:	MOVE	J,JOB NUMBER
;	PUSHJ	P,DPMJOB
;	  YES	RETURN - MESSAGE PRINTED ON JOB CONSOLE
;	NO RETURN

IFN FTDAEM,<			;DAEMON FEATURE?
DPMJOB::MOVE	T1,JBTSTS##(J)	;JOB STATUS WORD
	TRNN	T1,JS.DPM	;THIS JOB BEEN WAITING FOR 2 CONSECUTIVE MIN?
	JRST	CPOPJ1##	;NO
	PUSHJ	P,STDAEM##	;START DAEMON
	  PJRST	DAEDON##	;NO DAEMON
	PUSHJ	P,TTYFND##	;YES, FIND CONTROLLING TTY
	JUMPE	U,CPOPJ##
	PUSHJ	P,DAEPRB	;PRINT PROBLEM WITH DAEMON
	PUSHJ	P,INLMES##	;TELL USER WHAT SYSTEM IS DOING ABOUT IT
	ASCIZ	/, OPR action requested
/
	PJRST	TTYSTR##	;START TTY

;SUBROUTINE TO PRINT ON OPR PROBLEM WITH DAEMON
;CALLED ONCE A MIN ONLY IF A JOB IS STILL WAITING
;CALL:	PUSHJ	P,DPMOPR

DPMOPR::HRRZ	U,OPRLDB##	;OPR LINE DATA BLOCK HDR
	PUSHJ	P,DAEPRB	;PRINT PROBLEM WITH DAEMON
	MOVEI	T1,JS.DPM	;JOB STATUS BIT - NEED DAEMON PROB MESS.
	PJRST	OPRPJN		;TELL OPR WHICH JOBS ARE STUCK

;SUBROUTINE TO PRINT PROBLEM WITH DAEMON
;CALL:	MOVE	U,LINE DATA BLOCK ADR
;	PUSHJ	P,DAEPRB

DAEPRB:	PJSP	T1,CONMES##	;PRINT MESSAGE AND RETURN
	ASCIZ	/
%Problem with DAEMON/
>				;END DAEMON FEATURE
APRPDL:	TRNN	S,AP.POV	;PUSHDOWN OVERFLOW?
	STOPCD	CPOPJ##,DEBUG,SAC,	;++STRANGE APR CONDITION
	TLNE	T1,USRMOD	;IS PUSHDOWN LIST OVERFLOW IN EXEC UUO?
	JRST	PRTPOV		;NO - PRINT USER ERROR MESSAGE
IFE FTVM,<
	SKIPN	R,JOBDAT##	;DOES USER HAVE CORE ASSIGNED?
	MOVEI	R,NU0DAT##	;NO - HIS ACS ARE SAVED IN NULL JOB DATA AREA
	HRRZ	T1,JOBDPD##(R)	;GET PD POINTER AT TIME OF OVERFLOW
	CAMG	T1,SYSSIZ##	;IS PD LIST IN EXEC ALREADY?
				; (PI PD LIST, NULPDL, ERRPDL, OR EXTENDED LIST)
>	;END IFE FTVM
IFE FTHALT,<
	JRST	PRTPV1		;YES, PRINT OVERFLOW IN EXEC
>
IFN FTHALT,<
	STOPCD	PRTPV1,DEBUG,EPO,	;++EXEC PDL OV
>
IFE FTVM,<
	HRRZ	T2,USREPL##	;ADR. IN EXEC CORE OF EXTENDED PD LIST, IF ANY
	JUMPN	T2,MOVEP1	;NO - DOES THIS JOB ALREADY HAVE AN EPL?
	MOVEI	T2,EPL4WD##	;NO - TRY TO ASSIGN ENOUGH CONSECUTIVE 4 WORD BLOCKS
	PUSHJ	P,GET4WD##	;IS THERE ENOUGH?
	  JRST	PRTPV1		;NO - PRINT ERROR IN JOB & STOP IT
	MOVEM	T1,USREPL##	;YES - STORE STARTING ADR. OF EXEC CORE
				; (IE. FIRST DESTINATION ADDRESS)
	AOSA	EPOREC##	;INCREASE COUNT OF # RECOVERED EXEC PDL OVF
MOVEP1:	HRRZ	T1,USREPL##	;SET START ADR OF EXEC CORE
MOVEPL:
	HRRZ	T2,JOBDPD##(R)	;OVERFLOWED P(IE. LAST LOC TO MOVE)
	HRLI	T1,MMXPDL##+1(T2)	;LH=FIRST ADR. OF LONGEST PDL LIST IN MONITOR
				; (IE. FIRST SOURCE ADR.)
	MOVEI	T2,MAXPDL##-1(T1)	;STOP ADR.=MAX PD LIST BEFORE EXTENSION
	BLT	T1,(T2)		;MOVE OVERFLOWED LIST TO EXEC CORE
	MOVEM	T2,JOBDPD##(R)	;AND UPDATE PUSHDOWN POINTER(RH)
	MOVEI	T2,MEPLEN##	;-# OF WORDS IN EPL
	ADDI	T2,MAXPDL##	;+LENGTH OF OVERFLOWED LIST=-# WORDS LEFT IN EPL
	HRLM	T2,JOBDPD##(R)	;STORE -# OF WORDS LEFT IN NEW PDL POINTER(LH)
	JRST	CPOPJ1##	;RETURN SO THIS JOB CAN CONTINUE
>	;END IFE FTVM

PRTPV1:	AOS	EPOCNT##	;NO OF NON-RECOVERABLE MONITOR PDL OVFS
	MOVE	J,JOB##		;ZAPUSR REQUIRES J SET UP
	PUSHJ	P,ZAPUS1	;CLEAR ALL DDB'S, CHANS
	JRST	PRTPV2
PRTPOV:	MOVEM	T1,JOBPD1##(R)
IFN FTPI,<
	SIGNAL	C$PLOV		;SEE IF USER CARES
	  POPJ	P,		;HE DOES
>
PRTPV2:	JSP	T1,ERRPTU	;PRINT ERROR MESSAGE
PDLMES::ASCIZ	/Pdl ov/
APRSCD:	MOVE	T2,.C0APC##	;PRINT APR PC 
	JRST	PCPNT		;AS:
				; 1)"AT USER LOC XXX" OR
				; 2)"AT EXEC LOC XXX; EXEC CALLED FROM
				; EXEC/USER LOC YYY
;ADDRESS CHECK ERROR AT ANY LEVEL
;F MUST BE SET UP TO POINT TO OFFENDING DEVICE


ADRERR::
IFN FTMS,<
	PUSHJ	P,ONCPU0##
>
IFN FTPI,<
	LDB	J,PJOBN##	;OFFENDING JOB'S JOB NUMBER
	SIGNAL	C$ADCK		;SEE IF USER ENABLED FOR ADDRESS CHECK
	JRST	ERRGOU		;GO TO USER
>
	JSP	T1,ERRDEV	;GET JOB NO. FROM DEVICE DATA BLOCK
	ASCIZ	/Address check for /
	JRST	DEVEXC		;PRINT "DEVICE XXX; EXEC CALLED FROM
				; EXEC/USER LOC YYY"
				; THEN STOP JOB
;SUBROUTINE TO CLEAR ALL DDB'S, IO CHARS
;CALL WITH JOB NUMBER IN J
ZAPUSR::
IFN FTDISK,<
	PUSHJ	P,SWPCLN##	;CLEAN UP DISK CORE DATA BASE SO FILES
				; WILL NO LONGER BE FLAGGED AS BEING MODIFIED
>
ZAPUS1:	PUSHJ	P,GIVRSC	;GIVE UP ANY RESOURCES JOB MAY HAVE
	CAMN	J,JOB##		;CURRENT JOB?
	POPJ	P,		;YES, GIVE UP INITED DDB'S ON RESET
				; (ALL SHARED RESOURCES ALREADY GIVEN UP)
	HLRZ	F,DEVLST##	;LOC OF FIRST DDB
ZAPUS2:	LDB	T1,PJOBN##	;OWNER OF DDB
	MOVEI	T2,DEPMSG	;IS THIS DDB CONTROLLED BY MPX
	TDNN	T2,DEVMSG(F)	;IF SO, GIVE IT UP WHEN WE ZAP MPX
	CAME	T1,J		;RIGHT GUY OWN IT
	SKIPA			;NO, DON'T RELEASE IT
	PUSHJ	P,RELEA9##	;YES, RELEASE IT
	HLRZ	F,DEVSER(F)	;NEXT DDB
	JUMPN	F,ZAPUS2	;GO TEST IT
	POPJ	P,		;DONE - RETURN

;SUBROUTINE TO RETURN ALL RESOURCES
;CALL WITH J=JOB#
GIVRES::CAMN	J,.C0JOB##	;NO DEVICES ACTIVE IF NOT CURRENT JOB
	PUSHJ	P,IOWAIT##	;WAIT FOR ANY ACTIVE DEVICES TO FINISH
IFN FTMS,<
	PUSHJ	P,ONCPU0##	;COULD GET RESCHEDULED TO CPU1
>
GIVRSC:	MOVEI	F,DSKDDB##	;START AT FIRST DSK
GIVRS0:	MOVE	T1,DEVMOD(F)	;IS THIS A DISK?
	TLNN	T1,DVDSK
	JRST	GIVRS1		;NO
	MOVE	S,DEVIOS(F)
	LDB	T1,PJOBN##	;YES, THIS JOB OWN IT?
	CAMN	T1,J
	PUSHJ	P,RETRES##	;YES, RETURN ANY RESOURCES IT OWNS
	HLRZ	F,DEVSER(F)	;AND TRY NEXT DDB
	JUMPN	F,GIVRS0	
GIVRS1:	SETZB	T1,MQUSER##	;START WITH FIRST RESOURCE, MAKE
				; SURE THAT MON-BUF ISN'T RETURNED
	DPB	T1,PJBSTS##	;MAKE SURE THAT JOB DOESN'T APPEAR
				; TO HAVE ACTIVE DISK I/O
GIVRS2:	CAMN	J,USRTAB##(T1)	;OWNED BY JOB?
	PUSHJ	P,DVFREE##(T1)	;YES--FREE IT UP
	CAIGE	T1,AVLNUM##	;DONE YET?
	AOJA	T1,GIVRS2	;NO--CONTINUE
	PUSHJ	P,TPFREE##	;FREE UP TAPE KONTROLLERS
IFN FTKL10,<
	MOVEI	P4,.C0CDB##	;P4=CPU0S CDB
	PUSHJ	P,HAVPMR##	;DOES THIS JOB HAVE THE PERFORMANCE METER?
	  CAIA			;NO, SO DON'T GIVE IT UP.
	PUSHJ	P,RELPMR##	;YES, GIVE IT BACK SO OTHERS MAY MEASURE
>;END IFN FTKL10
	POPJ	P,		;YES--RETURN
NPDUFL::STOPCD	.,STOP,NPU,	;++NULL PUSH-DOWN-LIST UNDERFLOW

;JSR TO HERE FROM INTRPT LOC
	$LOW
PIERR::0
	EXCH	P,PIEPDL
	STOPCD	.,STOP,PIE,	;++PRIORITY INTERRUPT ERROR
PIEPDL::XWD	0,.
	BLOCK	1
	$HIGH
;ROUTINE TO RECOVER/RELOAD AFTER AN INTERNAL
; SYSTEM ERROR.  CALLED ONLY BY STOPCD MACRO
; (SEE S.MAC) WITH:
;	PUSHJ	P,DIE
;	CAI	TYPE,NAME (CONT)
;
;	-OR-
;
;	PUSHJ	P,DIE
;	CAIA	TYPE,NAME (17)
;	JRST	CONT
;
DIE::
IFN FTMS,<			;DUAL SYSTEM?
	SKPCPU	(0)		;CPU 0?
	PJRST	CP1DIE##
>	;END FTMS
	AOSE	DIEWRD		;INTERLOCK STOPCD CODE
	STOPCD	.,HALT,REH,	;RECURSION IN ERROR HANDLER
	CONI	PI,.C0CPI##	;SAVE STATE OF MACHINE
	CONO	PI,1177		; ..
	MOVEM	17,.C0CAC##+17	; ..
	MOVEI	17,.C0CAC##	; ..
	BLT	17,.C0CAC##+16	; ..
	MOVEI	P4,.C0CDB##
	MOVE	T1,MPTRAP##
	MOVEM	T1,.C0TRP##
DIETYP::MOVE	M,@(P)		;M=FLAG WORD
	POP	P,%SYSPC##	;SAVE PC
	MOVE	P,[ERRPLL##,,ERRPDL##]
IFN FTKL10,<
	PUSHJ	P,DIE1		;GO TO STOPCODE
	JRST	RESTORE		; AND RETURN

DIE1:	PUSHJ	P,SVPPC##	;SAVE PROTOCOL, ENTER SECONDARY
>
	PUSH	P,COMTOA##	;SAVE ADDRESS OF TYPEOUT
				; ROUTINE.
	MOVEI	T1,CTYWAT##	;REPLACE IT WITH ONE THAT
				; DOES NOT USE PI SYSTEM
	MOVEM	T1,COMTOA##	;MODIFY SCNSER
	HRRZ	U,CTYLDB##	;POINT TO CTY
	MOVEI	T2,^D10		;SEND 10 BELLS
	PUSHJ	P,BELLS		;..
	PUSHJ	P,INLMES##	;PRINT MESSAGE
	ASCIZ	/
?/
	MOVE	T2,.CPLOG##(P4)
	PUSHJ	P,PRNAME
	PUSHJ	P,INLMES##
	ASCIZ	/ monitor error. stopcode name /

	HRLZ	T2,M		;GET CODE
	HLLM	T2,%SYSPC##	;SAVE NAME
	PUSHJ	P,PRNAME	;PRINT IT OUT
	PUSHJ	P,CRLF##	;ADD A CRLF
	MOVE	J,.CPJOB##(P4)
	MOVEI	S,PI.IPA	;GET PI ON MASK
	AND	S,.CPCPI##(P4)	;MASK OUT ALL ELSE
	SKIPN	S		;INTERRUPT LEVEL?
	PUSHJ	P,WHATJB	;NO--GIVE INFO
	TLZ	F,-1		;CLEAR LH BITS
	CAMGE	F,SYSSIZ##
	CAIG	F,1000		;IS THIS A DDB?
	JRST	NODDB		;NO
	LDB	T1,PJOBN##	;GET JOB #
	CAILE	T1,JOBMAX##	;TOO BIG?
	JRST	NODDB		;YES--NOT A DDB
	JUMPE	T1,NODDB	;WANT REAL JOB #
	PUSHJ	P,INLMES##
	ASCIZ	/FILE /
	PUSHJ	P,PRTDDB##	;PRINT DDB STUFF
	PUSHJ	P,CRLF##	;ADD CRLF
	JUMPE	S,NODDB		;UUO LEVEL-SAID THIS
	LDB	J,PJOBN##	;GET JOB #
	PUSHJ	P,WHATJB	;PRINT IT
NODDB:	SKIPGE	DEBUGF##	;WANT DDT?
	JRST	DIERS0		;YES
	LDB	T1,PUUOAC##	;GET ERROR TYPE
	CAIL	T1,1		;BE SURE IT'S IN RANGE
	CAILE	T1,3		;JUST SUPER CAUTIOUS
	JRST	RELOAD		;BAD. DON'T MAKE IT WORSE
	JRST	@[EXP RELOAD,ZAPJOB,BUGCHK]-1(T1)
;HERE ON A DEBUG STOPCD
BUGCHK:	MOVSI	T1,(DF.RDC)	;DO WE WANT TO
	TDNE	T1,DEBUGF##	; RELOAD?
	JRST	RELOAD		;YES--GO RELOAD
	JUMPE	S,ZAPJB1
	AOS	%SYNDS##	;COUNT BUG
	PUSHJ	P,INLMES##	;NO--CONTINUE
	ASCIZ	/Continuing system
/
	MOVE	T1,.CPCAC##+P(P4)  ;GET OLD STACK POINTER
	LDB	T2,[POINT 4,M,17] ;GET RETURN TYPE
	XCT	CONTAB(T2)	;FIX UP PDP
	MOVEM	T1,.CPCAC##+P(P4)  ;SAVE BACK
	JRST	DIERS0		;RESTORE STATE OF MACHINE

;HERE ON A JOB ERROR STOPCD

ZAPJOB:	MOVSI	T1,(DF.RJE)	;IS RELOAD ON JOB ERROR
	TDNN	T1,DEBUGF##	; REQUESTED?
	SKIPE	S		; OR PI LEVEL?
	JRST	RELOAD		;YES--GO RELOAD
ZAPJB1:	AOS	%SYNJS##	;COUNT BUG
	PUSHJ	P,INLMES##	;NO--ZAP JOB
	ASCIZ	/?Aborting job/
	PUSHJ	P,CRLF##	; ..
	MOVEI	T1,BUGSTP	;ADJUST SAVED STACK
	MOVE	T2,.CPCAC##+P(P4)	;SO THIS JOB GETS
	MOVEM	T1,(T2)		;KILLED
	JRST	DIERS0		;RESTORE STATE OF SYSTEM

;HERE TO RELOAD
IFN FTKL10,<
DIERS0:	POP	P,COMTOA##
	POPJ	P,
>
RELOAD:
IFN FTMS,<
	MOVEI	T1,CPUN##	;DO WE HAVE MULTIPLE CPU'S?
	CAIN	T1,1		;IF NOT
	JRST	NOTCP1		;SKIP THIS STUFF
	SKIPLE	CP1HLT##
	JRST	CP1SBP##
	SKIPL	CP1HLT##	;WERE WE DOING A CPU1 STOPCD?
	JRST	NOTCP1		;NO
IFN FTKI10,<			;YES, RESTORE CPU0 PAGING
	MOVE	T1,CP0EUB##
	TLO	T1,(PG.LUB)
	DATAO	PAG,T1		;SINCE THE MASQUERADE IS OVER
>
IFN FTKL10,<			;RESTORE KL CPU0
	MOVE	T1,CP0UPT##
	TDC	T1,[LG.LAB!LG.LPC!LG.IAM]	;SET TO RESTORE UBR
	DATAO	PAG,T1
>
NOTCP1::
>	;END FTMS
	HRRZM	M,CRSWHY##	;SAVE REASON FOR ONCE ATER RELOAD
	PUSHJ	P,INLMES##
	ASCIZ	/Reload monitor
/
	MOVEI	T2,^D20		;20 BELLS
	PUSHJ	P,BELLS		;..
	MOVE	P,.CPCAC##+P(P4)  ;RESTORE PDP
	POP	P,CRSHWD##	;SAVE PC
	SOS	CRSHWD##	;FOR SYSTAT/X
	PJRST	REBOOT##

;HERE TO RESTORE STATE OF MACHINE

IFE FTKL10,<
DIERS0:	POP	P,COMTOA##
>
RESTOR:	MOVEI	T1,177		;ALL PI BITS
	AND	T1,.C0CPI##	;TURN ON ONLY
	IORI	T1,PI.TNP	;ONES WHICH WERE ON
	MOVEM	T1,.C0CPI##	;SAVE FOR CONO
IFN FTMS,<
	MOVEI	T1,CPUN##	;DO WE HAVE MULTIPLE CPU'S?
	CAIN	T1,1		;IF NOT
	JRST	N2TCP1		;SKIP THIS STUFF
	SKIPL	CP1HLT##	;WERE WE DOING A CPU1 STOPCD?
	JRST	N2TCP1		;NO
IFN FTKI10,<			;YES, RESTORE CPU0 PAGING
	MOVE	T1,CP0EUB##
	TLO	T1,(PG.LUB)
	DATAO	PAG,T1		;SINCE THE MASQUERADE IS OVER
>
IFN FTKL10,<			;RESTORE KL CPU0
	MOVE	T1,CP0UPT##
	TDC	T1,[LG.LAB!LG.LPC!LG.IAM]	;SET TO RESTORE UBR
	DATAO	PAG,T1
>
N2TCP1::
> ;END FTMS
	MOVSI	17,CRSHAC##	;RESTORE AC'S
	BLT	17,17		; ..
	CONO	PI,@.C0CPI##	;TURN ON PI SYSTEM
	SKIPGE	DEBUGF##	;WANT DDT?
	XCT	SYSDDT##	;YES
DIECON::SETOM	DIEWRD		;ALLOW STOPCD'S
IFN FTMS,<
	SETZM	CP1HLT##
>
	POPJ	P,

;HERE TO STOP AN ILL FATED USER

BUGSTP:
IFN FTMS,<
	PUSHJ	P,ONCPU0
>
	MOVE	J,.C0JOB##	;JOB NUMBER
	PUSHJ	P,ZAPUS1	;GIVE UP LOCKS AND DEVICES
IFN FTPI,<
	PUSHJ	P,EXTEIJ##	;SIGNAL EXTERNAL ERROR IN JOB
>
	JSP	T1,ERRPTU	;PRINT MESSAGE
	ASCIZ	/Monitor error/
	PJRST	UUOPCP			;PRINT SOME PC'S
;SUBROUTINE TO SEND C(T2) BELLS
;CLOBBERS T1, T2, T3, T4
BELLS::	MOVEI	T3,"G"-100	;BELL
BELOOP:	PUSHJ	P,COMTYO##	;DING
	MOVEI	T1,200000
	LSH	T1,-2*FTKL10-FTKI10
	SOJG	T1,.
	SOJG	T2,BELOOP	;LOOP FOR ALL
	POPJ	P,		;RETURN
;CONTINUE TABLE. T1 IS STACK POINTER FOR PROCESS WHICH DID STOPCD.
;CALLED BY XCT CONTAB(CONT)
CONTAB:	JFCL			;(0) .
	JFCL			;(1) .+1
	POP	T1,(T1)		;(2) CPOPJ
	PUSHJ	P,[POP T1,(T1)
		AOS (T1)
		POPJ P,]	;(3) CPOPJ1
	JFCL			;(4)
	JFCL			;(5)
	JFCL			;(6)
	JFCL			;(7)
	JFCL			;(10)
	JFCL			;(11)
	JFCL			;(12)
	JFCL			;(13)
	JFCL			;(14)
	JFCL			;(15)
	JFCL			;(16)
	AOS	(T1)		;(17) SPECIAL RETURN




	$LOW
DIEWRD::EXP	-1		;INTERLOCK
	$HIGH
WHATJB:	JUMPLE	J,CPOPJ##	;GET JOB NUMBER
	CAILE	J,JOBMAX##	;RANGE CHECK IT.
	POPJ	P,			;IGNORE IF FUNNY.
	PUSHJ	P,INLMES##	;GIVE THE JOB NUMBER
	ASCIZ	/JOB /		; ..
	MOVE	T1,J			; ..
	MOVEM	T1,%SYSJN##
	PUSHJ	P,RADX10	;IN DECIMAL
	PUSHJ	P,INLMES##	;PRINT OUT THE
	ASCIZ	/ ON /		; TTY NAME
	MOVE	T2,@TTYTAB##(J)	;GET TTY NAME
	MOVEM	T2,%SYSTN##
	PUSHJ	P,PRNAME	; AND PRINT IT.
	PUSHJ	P,INLMES##	;PRINT OUT
	ASCIZ	/ RUNNING /	; THE CUSP NAME
	MOVE	T2,JBTPRG##(J)	; SO OPERATOR
	MOVEM	T2,%SYSPN##
	PUSHJ	P,PRNAME	; CAN FIND HIS JOBS
	MOVE	T2,JBTPPN##(J)	;GET USER'S PPN
	MOVEM	T2,%SYSPP##	;AND SAVE FOR DAEMON
	JUMPN	S,CRLF##
	PUSHJ	P,INLMES##	;NEW LINE
	ASCIZ	/
UUO is /
	MOVE	T1,.CPTRP##(P4)	;PICK UP UUO
	PUSHJ	P,PRTDI8	;PRINT IN OCTAL
	MOVE	T1,JBTADR##(J)	;GET PC FROM
	MOVE	T2,JOBPD1##(T1)	; PUSH DOWN IN LIST
	MOVEM	T2,%SYSUP##
	PUSHJ	P,PCP		;LIST THE LOCATION
	PJRST	CRLF##		;RETURN ON A NEW LINE
;INPUT UUO FOR OUTPUT DEVICE
;CALLED AT UUO LEVEL ONLY


ILLINP::JSP	T1,ERRPTU
	ASCIZ	/output /
	PUSHJ	P,ERNAM		;PRINT "DEVICE XXX"
	JSP	T1,UUOMES	;PRINT MESSAGE,UUOPC,STOP JOB
	ASCIZ	/ cannot do input/
;OUTPUT UUO FOR INPUT DEVICE
;CALLED AT UUO LEVEL ONLY


ILLOUT::JSP	T1,ERRPTU
	ASCIZ	/input /
	PUSHJ	P,ERNAM		;PRINT "DEVICE XXX"
	JSP	T1,UUOMES	;PRINT MESSAGE,UUOPC,STOP JOB
	ASCIZ	/ cannot do output/

;ILLEGAL DEVICE DATA MODE (INIT, OPEN, OR SETSTS UUOS)
;CALLED AT UUO LEVEL ONLY


ILLMOD::
IFN FTMS,<
	PUSHJ	P,ONCPU0##
>
	JSP	T1,ERRPTU
	ASCIZ	/Illegal data mode for /
	JRST	DEVEXC		;PRINT "DEVICE XXX",UUO PC

	IFN	FTTYPE,<
;DWND44 CALLED WHEN A USER ACCESSES A DEVICE ON A
;NOT RUNNING DB44 FRONT END

DWND44::JSP	T1,ERRPTU	;TELL THE USER
	ASCIZ	/DC44 is not running
/
	JRST	DEVEXC
;CALLED WHEN AN ILLEGAL BYTE SIZE FOR A DEVICE INITED IN PIM
;MODE WAS USED
ILLBYT::JSP	T1,ERRPTU
	ASCIZ	/Illegal byte size in pim mode for/
	JRST	DEVEXC		;PRINT DEVICE XXX ,UUO PC

;INIERR CALLED WHEN THE PDP-11 BOOKKEEPING DOES NOT ALLOW
;THE SUCCESFULL INITIALIZATION OF A LINE.

CMTERR::JSP	T1,ERRPTU
	ASCIZ	/Init failure for DC44 /
	JRST	DEVEXC	;PRINT DEVICE XXX ,UUO PC

;UNAVLT IS CALLED TO TELL THAT A CONFIGURED
;DC44 DEVICE DID NOT EXIST

UNAVLT::JSP	T1,ERRPTU	;PRINT TEXT
	ASCIZ	/DC44 /
	PUSHJ	P,ERNAM	;TYPE DEVICE NAME
	JSP	T1,ERRPTU	;PRINT INLINE TEXT
	ASCIZ	/is unavailable /
	JRST	EXCALP

;ILLBCH IS CALLED WHEN A USER CHANGES THE BYTE SIZE FOR A PIM MODE
;DEVICE BEFORE A CLOSE IS DONE!!!

ILLBCH::PUSHJ	P,ERNAM	;PRINT THE DEVICE NAME
	JSP	T1,ERRPTU		;AND TELL PROBLEM
	ASCIZ	/Byte size was changed for device before doing a close/
	JRST	EXCALP		;LEAVE


;FAILRL IS CALLED ON INTERRUPT LEVEL WHEN PDP-11 FLAGS AN
;RELEASE ERROR

FAILRL::IFN	FTKI10!FTKL10,<
	PUSHJ	P,SVEUF##		;MAKE SURE JDA IS AVAILABLE
>
	JSP	T1,ERRDEV		;PRINT NAME
	ASCIZ	/Release failed for /
	JSP	T1,ERNAM		;PRINT DEVICE NAME
	POPJ	P,
>
;IO UUO TO USER CHANNEL WITH NO PREVIOUS INIT OR OPEN
;CALLED AT UUO LEVEL ONLY


IOIERR::
IFN FTMS,<
	PUSHJ	P,ONCPU0##	;MAKE SURE JOB IS ON CPU0
>
	JSP	T1,ERRPTU
	ASCIZ	/IO to unassigned channel/
	JRST	UUOPCP		;PRINT UUO PC
;ILLEGAL UUO
;CALLED AT UUO LEVEL ONLY
;SERVES TWO PURPOSES - A) TO WARN WHEN MOVING FROM A LOCATION WITH SPECIAL INSTALLATION
;UUOS TO ONE WITH LACKS THEM
;B) TO WARN OF OLD UUO'S WITH NONSKIP "GOOD" RETURNS WHICH 
;HAVE BEEN "DE-IMPLEMENTED"

UUOERR::

IFN FTMS,<
	PUSHJ	P,ONCPU0##	;INSURE THAT IS ON CPU0
>
	EXCH	T1,UUO0##	;GET UUO PC
	TLNN	T1,USRMOD	;FROM EXEC?
	JRST	EMUERR		;YES
	EXCH	T1,UUO0##	;PUT THINGS BACK
ILLUUO:	PUSH	P,UUO0##	;NOW PUSH USER PC ON STACK JUST LIKE UUO
				; (LEAVE STACK UNTOUCHED BEFORE HALT)
				; (START PRESERVES PC FLAGS IN LH)
	PUSHJ	P,GIVRES	;GIVE UP INTERLOCKS
IFN FTPI,<
	SIGNAL	C$IUUO		;SIGNAL ILLEGAL UUO
	  JRST	ERRGOU		;INTERCEPT THE UUO
>	;END FTPI
	JSP	T1,ERRPTU
	ASCIZ	/Illegal UUO/
	MOVE	T2,UUO0##	;GET UUO PC
	SOJA	T2,PCPNT	;AND PRINT, PRINT USER UUO PC IF DIFF.
;UUO ERROR-MONITOR ERROR AT UUO LEVEL
;CALLED AT UUO LEVEL ONLY

UUOER1::JSP	T1,ERRPTU
	ASCIZ	/UUO error/
	JRST	UUOPCP

;HERE ON AN EXEC MODE UUO ERROR

EMUERR:	EXCH	T1,UUO0##
	CONSZ	PI,PI.IPA	;AT UUO LEVEL?
	STOPCD	.,STOP,UIL,	;++UUO AT INTERRUPT LEVEL
	STOPCD	.+1,DEBUG,EUE,	;++EXEC UUO ERROR
	MOVE	J,.C0JOB##	;GET JOB NUMBER
	JRST	ILLUUO		;PRINT ERROR MESSAGE
;HERE IF THE USER DIES IN GETWRD OR PUTWRD

UADERR::
IFN FTMS,<
	PUSHJ	P,ONCPU0##	;MAKE SURE WE'RE ON CPU0
>
	PUSHJ	P,GIVRES	;RETURN INTERLOCKS
	JSP	T1,ERRPTU
	ASCIZ	/Illegal address in UUO/
	JRST	UUOPCP
;ILLEGAL INSTRUCTION
;HALT INSTRUCTION IS A SPECIAL CASE WHICH STOPS JOB BUT
;THE USER MAY CONTINUE FROM IT(EFFECTIVE ADR.)
;CALLED AT UUO LEVEL WITH A JRST


ILLINS::
	SIGNAL	C$IUUO		;SIGNAL ILL UUO
	  JRST	ERRGOU		;GO TO THE USER
IFN FTMS,<
	PUSHJ	P,ONCPU0##	;BE ON CPU0
>
IFN FTKL10,<
	LDB	T1,[POINT 9,M,8] ;OPCODE
	CAIL	T1,130		;WITHIN FLOATING POINT RANGE?
	CAILE	T1,177
	JRST	ILLIN1		;NO, ILLEGAL INSTRUCTION
	JSP	T1,ERRPTU
	ASCIZ	/KA10 floating point instruction/
	JRST	UUOPCP
ILLIN1:>
	HLRZ	T1,M		;ILLEGAL OPCODE
	CAIN	T1,254200+R	;IS IT A HALT?
	JRST	HALTI		;YES, PRINT DIFFERENT MESSAGE
IFN FTKA10!FTKI10,<
KIIBEG==105
KIIEND==127
	LSH	T1,-9		;MAKE T1=OPCODE
IFN FTKA10,<
	MOVE	T2,[237777,,600000] ;MASK FOR KI10 AND KL10 INST.
				; 1B1 = 105
> ;END FTKA10
IFN FTKI10,<
	MOVSI	T2,201704	;MASK FOR KL10 INST.
>
	CAIG	T1,KIIEND	;IF TOO LARGE, DON'T SHIFT
	LSH	T2,-KIIBEG+1(T1) ;SHIFT MASK BY OPCODE
	JUMPGE	T2,ILLKAI	;KA10 ILL INST IF SIGN NOT 1
IFN FTKA10,<
	MOVSI	T2,201704	;IS THIS ONLY ON THE KL10?
	LSH	T2,-KIIBEG+1(T1) ; ??
	JUMPL	T2,KLONLY	;YES IF T2 HAS 1B0=1
	JSP	T1,ERRPTU
	ASCIZ	/KI10 or KL10 instruction/
	JRST	UUOPCP
> 	;END CONDITIONAL ON FTKA10
KLONLY:	JSP	T1,ERRPTU
	ASCIZ	/KL10 only instruction/
	JRST	UUOPCP
> ;END FTKA10!FTKI10
ILLKAI:	JSP	T1,ERRPTU
	ASCIZ	/Illegal instruction/
	JRST	UUOPCP		;PRINT UUO PC AND STOP JOB

HALTI:	JSP	T1,ERRPTU
	ASCIZ	/HALT/
	SOS	T2,JOBPD1##(R)	;UUOPC=LOC OF HALT+1
	PUSHJ	P,PCP		;PRINT "USER LOC XXX"
	HRR	M,MPTRAP##	;CHKINT CLOBBERS M
	HRRM	M,JOBPD1##(R)	;SAVE EFFECTIVE ADDRESS OF HALT
	PUSH	P,U
	PUSHJ	P,TTYSRC	;GETTTY
	STOPCD	.,STOP,LNT,	;NONE?!
	JUMPE	U,HALTI2	;JUMP IF JOB DETACHED
	POP	P,U
	PUSHJ	P,TSETBI##	;CLEAR TYPE-AHEAD
	PUSHJ	P,HOLDW##	;START TTY WITH STANDARD RESPONSE,, STOP
				;JOB, LEAVE TTY IN MONITOR MODE
				;DO NOT SET ERROR BIT SO CAN CONTINUE
HALTI1:	PUSH	P,JOBPD1##(R)	;PUT USER RETURN ON END OF PD LIST
	JRST	USRXIT##	;RETURN TO USER IN CASE HE TYPES CONT COMMAND
HALTI2:	POP	P,U
	PUSHJ	P,CRLF##	;HERE TO HANDLE HALT IN DET'D JOB
	PUSHJ	P,ESTOP3##	;STOP JOB WITH CONTINUABILITY
	PUSHJ	P,WSCHED##	;WAIT FOR USER
	JRST	HALTI1		;RESUME NORMAL FLOW
;ROUTINE FOR HUNG IO DEVICE
;CALL	MOVE F,ADDRESS OF DEVICE DATA BLOCK
;	PUSHJ P,DEVHNG


DEVHNG::
IFN FTKI10!FTKL10,<
	PUSHJ	P,SVEUF##	;MAKE SURE JOB DATA AREA IS ADDRESSABLE
>
	PUSHJ	P,CLRACT##	;TURN OFF IO DEVICE ACTIVE BIT IN
				;MEMORY AND S
	LDB	J,PJOBN##	;JOB NUMBER
	PUSH	P,F		;GIVRSC CLOBBERS F
	PUSHJ	P,GIVRSC	;RETURN RESOURCES, COULD HAVE SOME, IF STR YANKED
	POP	P,F
IFN FTPI,<
	PUSHJ	P,EXTEIJ##	;SIGNAL EXTERNAL ERROR IN JOB
>
	JSP	T1,ERRDEV
	ASCIZ	/Hung /
	JRST	DEVEXC

;BAD DECTAPE DIRECTORY
;CALLED AT INTERRUPT AND UUO LEVELS WITH F AND J SETUP

BADDIR::
IFN FTKI10!FTKL10,<
	PUSHJ	P,SVEUF##	;MAKE JOB DATA AREA ADDRESSABLE
>
IFN FTPI,<
	PUSHJ	P,EXTEIJ##	;SIGNAL EXTERNAL ERROR IN JOB
>
	JSP	T1,ERRPNT
	ASCIZ	/Bad directory for /
	
;ROUTINE TO PRINT "DEVICE XXX; EXEC CALLED FOR EXEC/USER YYY"
;THEN STOP JOB
;TO BE USED BY DEVICE DEPENDENT ERROR MESSAGES AFTER JSP T1,DEVERR


DEVEXC::PUSHJ	P,ERNAM		;PRINT "DEVICE XXX"
	SKIPE	JBTADR##(J)	;CHECK FOR JOB IN CORE
	JRST	EXCALP		;PRINT "EXEC CALLED FROM EXEC/USER LOC YYY"
	JRST	PCSTOP		;JUST STOP THE JOB

;ROUTINE TO HALT A JOB WHEN A DEVICE IS NOT READY FOR I/O
;CALLED FROM XXXSER AT UUO LEVEL
;CALL	MOVE F,ADDR. OF DEV. DDB
;	MOVE R,JOB RELOCATION
;	PUSHJ P,HNGSTP
;WILL DISPATCH TO USER'S AREA IF JOBINT IS NON-0


HNGSTP::PUSH	P,M
	PUSHJ	P,HNGSTX
	PJRST	MPOPJ##
HNGSTX:	PUSHJ	P,SAVE3##	;SAVE P1-P3	
IFN FTKI10!FTKL10,<
	SKIPE	P3,DEVEVM(F)	;DOES DEVICE HAVE EVM?
	SETO	P3,		;NO
	PUSHJ	P,RTNEVM##	;RETURN ANY EVM DEVICE HAS FOR I/O
				; P3=-1 IF DEVICE HAD NO EVM, 0 IF IT DID
>				;END CONDITIONAL ON FTKI10
IFN	FTOPRERR,<
	SOS	JOBPD1##(R)	;BACK UP PC
IFN FTPI,<
	TLO	M,(1B0)
	PUSHJ	P,PSIHNG##	;CALL PSISER
	  PJSP	P1,HNGST1	;P1 NON-ZERO TO INDICATE INTERCEPTING
	TLZ	M,(1B0)
>
	MOVEI	T4,.ERIDV	;DEV OR INTERCEPT
	SETO	T2,		;MAKE T2 NON-ZERO SO LATER CHECKS WILL WORK
	LDB	T3,PJOBN##
	SKIPE	T3,JBTSTS##(T3)
	TRNN	T3,JS.ASA
	PUSHJ	P,CHKINT	;SEE IF SET UP
	  SETZB	T2,T3		;NO
	MOVE	P1,T2		;SAVE LOCATION
	PUSHJ	P,DOINT		;PREPARE INTERCEPT
	JUMPN	T2,HNGST1	;IF NOT INTERCEPTING
IFE FTVM,<
	AOS	JOBPD1##(R)	;RESET JOBPD1
>
IFN	FTVM,<
	PUSHJ	P,INCPD1##
>
HNGST1:	JUMPL	T3,HNGST3	;YES, DOES HE WANT THE ERROR MESSAGE?
>
	PUSH	P,J		;YES
	PUSH	P,W
	PUSH	P,S
	PUSH	P,U
	PUSH	P,F		;SAVE DEV'S S WORD & DDB
IFE	FTOPRERR,<		;(MUST BE LAST ON STACK FOR ERNAM)
	PUSHJ	P,TTYFUW##	;FIND USERS TERMINAL
	PUSHJ	P,PRQM##	;PRINT QUESTION MARK FOR BATCH
	PUSHJ	P,ERNAM		;PRINT "DEVICE XXX" (USING -1(P))
				; (ALSO USED BELOW)
	PUSHJ	P,INLMES##	;AND MSG.
	ASCIZ	/ action requested
./
>	;END CONDITIONAL ON FTOPRERR
IFN	FTOPRERR,<

	LDB	J,PJOBN##	;GET JOB NUMBER
	PUSHJ	P,FNDPDS##	;FIND PDB AND PUT IT'S ADDRESS IN W
				; IF NONE HALT.
	LDB	T1,PDVSTA##	;GET JOB'S LOCATION
	MOVEM	T1,SADVST	;ALSO SAVE FOR MSG TO USER
	JUMPE	T1,HNGST2	;CENTRAL SITE IF 0 (DISK)
IFN FTNET,<
	PUSHJ	P,STBOPR##	;GET OPR LINE
>
IFE FTNET,<
	MOVE	U,OPRLDB##
	LDB	T1,LDPLNO##
>
	SKIPA	U,LINTAB##(T1)	;GET LDB ADDR
HNGST2:	MOVE	U,OPRLDB##	;CENTRAL STA OPR
	PUSHJ	P,INLMES##	;OUTPUT START OF MESSAGE
	ASCIZ	/
%Problem on /
	PUSHJ	P,ERNAM		;PRINT PHYSICAL DEVICE NAME (USING -1(P))
	PUSHJ	P,INLMES##	;LOGICAL DEVICE OPR
	ASCIZ	/ for job /
	PUSHJ	P,PJOB##
	PUSHJ	P,CRLF##

	PUSHJ	P,TTYFUW##	;FIND CURRENT JOB'S TTY
	PUSHJ	P,CRLF##	;START A NEW LINE
	PUSHJ	P,ERNAM		;PRINT "DEVICE XXX"
	PUSHJ	P,INLMES##	;AND MSG.
	ASCIZ	/ OPR/
IFN FTNET,<
	HRRZ	T1,SADVST	;GET DEVICE'S LOCATION
	PUSHJ	P,CVTSBT##	;CONVERT TO SIXBIT
	MOVE	T2,T1		;GET SIXBIT FOR PRNAME
	PUSHJ	P,PRNAME	;AND PRINT IT
>
	PUSHJ	P,INLMES##
	ASCIZ	/ action requested/

	MOVEI	T1,TTYSTR##	;UNLESS ERROR INTERCEPTING
	SKIPN	P1		;CALL HOLD0 (STOP JOB,START TTY)
HNGST8:	MOVEI	T1,HNGST4	;SET UP ROUTINE TO CALL
	PUSHJ	P,(T1)		;START TTY TYPING ERR MESSAGE
				; LEAVE IN COMMAND MODE
				;DO NOT SET JOB ERROR SO CAN CONTINUE
>	;END CONDITIONAL ON FTOPRERR
IFE	FTOPRERR,<
HNGST8:	PUSHJ	P,HNGST4
>
	POP	P,F		;BRING BACK DEV DDB & S WORD
	POP	P,U
	POP	P,S
	POP	P,W
	POP	P,J
IFN FTKA10,<
IFN	FTOPRERR,<
	JUMPE	P1,WSCHED##	;RESCHEDULE IF NO ERROR INTERCEPT
>
IFE	FTOPRERR,<
	JRST	WSCHED##
>
>
IFN FTKI10!FTKL10,<
IFN FTOPRERR,<
	JUMPN	P1,HNGST3	;DO INTERCEPT IF WANTED
>
	PUSHJ	P,WSCHED##	;RESCHEDULE
	AOJN	P3,CPOPJ##	;DEVICE HAVE EVM WHEN THE ERROR OCCURRED?
	MOVE	M,-5(P)		;RESTORE M FOR ADDRESS CHECK
	PJRST	RSTEVM##	;YES, RESTORM EVM FOR I/O
>
IFN	FTOPRERR,<
HNGST3:	MOVEI	T1,DEPOND!DEPIND  ;NON-BLOCKING I/O NOT DONE BITS
	ANDCAM	T1,DEVAIO(F)	;CLEAR THEM SO THAT IN/OUT UUOS WILL WIN
	MOVEI	P1,1(M)		;SAVE 1(INTERCEPT LOC)
	LDB	T1,PIOMOD##	;MODE
	MOVE	T4,DEVADV(F)
	TLNN	T4,DEPADV
	CAIL	T1,SD		;DUMP?
	JRST	HNGST7		;YES, NO BUFFERS TO FIX
	HRR	M,DEVBUF(F)	;BUFFERED, FIX UP BUFFER HDR
	TLNE	S,IO		; SO REPEATING THE UUO WILL WIN
	HLR	M,DEVBUF(F)	; (THEY WERE ALREADY ADVANCED)
	HRRZ	T4,M		;SAVE LOCATION OF THE HDR
	JUMPE	T4,HNGST7	;JUMP IF NO BUFFERS YET SET UP
	PUSHJ	P,GETWRD##	;GET LOCATION OF FIRST BUFFER
	JRST	HNGST7		;ADDRESS CHECK - CAN'T FIX THE RING
	MOVE	P2,T1		;P2=ADDRESS OF FIRST BUFFER
	MOVEI	T3,10000	;END OF LOOP INSURANCE
HNGST5:	HRR	M,T1		;M=ADDRESS OF THIS BUFFER
	PUSHJ	P,GETWRD##	;GET THE ADDRESS OF THE NEXT ONE
	  JRST	HNGST7		;ADDRESS CHECK, FORGET IT
	CAIE	P2,(T1)		;THE ONE WE WANT?
	SOJGE	T3,HNGST5	;NO, STEP TO NEXT
	JUMPL	T3,HNGST7	;YES, JUMP IF RING WAS NOT CLOSED
	HRR	P2,M		;P2=POINTER TO NEXT BUFFER
	TLO	T1,IOUSE	;INDICATE "FULL" FOR TEST AT INPUT
	PUSHJ	P,PUTWDU##	;STORE THAT
	HRR	M,T4		;RESTORE HEADER ADDRESS
	MOVE	T1,P2		;T1=DEADVANCED BUFFER POINTER
	PUSHJ	P,PUTWDU##	;STORE THAT IN THE HDR
HNGST7:	HRRI	M,(P1)		;M=ADDRESS OF THIRD WORD OF INT. BLOCK
	PUSHJ	P,GETWDU##	;FETCH IT
	LDB	T2,PUUOAC##	;GET USER CHANNEL NO.
	HRR	T1,T2
	SKIPL	M		;SKIP IF PSISER TRAP
	PUSHJ	P,PUTWDU##	;STORE FOR INTERRUPT ROUTINE
>
QKUSXT::
ERRGOU::HRRI	P,JOBPD1##(R)	;SET P FOR NORMAL EXIT
				;(POP P,UUO0 ; JRST @UUO0)
	PJRST	USRXIT##	;LET UUOCON RETURN TO USER
IFN	FTOPRERR+FTDAEM,<
	$LOW
SADVST:	0
	$HIGH
>	;END CONDITIONAL ON FTOPRERR
HNGST4:	IFN	FTJCON,<
	MOVEI	T1,JDCON	;NO ERROR INTERCEPT
	IORM	T1,JBTSTS##(J)	; SO SET DEV CONT BIT
>
	PUSHJ	P,CRLF##	;PRINT A CRLF
	PUSH	P,TTYTAB##(J)	;MAKE THIS JOB LOOK DETACHED
	SETZM	TTYTAB##(J)	; SO IT'S TERMINAL IS NOT PUT
				; AT COMMAND LEVEL.
	PUSHJ	P,STOP1C##	;STOP JOB-SETUP TO RESCHEDULE
				; BUT DO NOT CALL WSYNC
	POP	P,TTYTAB##(J)	;ALL TTYSRC TO WIN AGAIN
	POPJ	P,0		;RETURN
;CHKINT -- ROUTINE TO SETUP FOR JOBINT USAGE
;CALL:	MOVEI	T4,ERROR TYPE (CLASS)
;	PUSHJ	P,,CHKINT
;SKIP RETURNS	M = RELATIVE BLOCK ADDRESS+2 (WHERE OLD PC IS STORED)
;		T1 = NEW PC
;		T3 = CONTENTS OF BITS,,CLASS
;STORES ERROR TYPE IN BLOCK+3.

IFN FTCCIN!FTDAEM!FTOPRERR,<


CHKINT::MOVE	T1,JBTSTS##(J)	;JOB STATUS
	TLNN	T1,SWP		;IS JOB SWAPPED OR
	TRNE	T1,JS.ASA	;EXEC MODE UUO IN PROGRESS
	POPJ	P,		;YES, DON'T TRAP
	HRR	M,JOBINT##(R)	;GET ERROR LOCATION
				; SET M FOR GETWRD/PUTWRD
IFN FTVM,<
	HRRZ	T1,M		;CHECK FIRST WORD OF INTERRUPT VECTOR
	PUSHJ	P,FLTST##	;IN-CORE?
	  POPJ	P,		;NO
	ADDI	T1,3		;LAST WORD OF VECTOR
	PUSHJ	P,FLTST##	;IN-CORE?
	  POPJ	P,		;NO
>
	TRNE	M,-1		;NO INTERRUPT IF JOBINT NOT SET
	PUSHJ	P,GETWRD##	;GET NEW PC
	  POPJ	P,		;ADDRESS CHECK - GIVE UP
	HRL	T4,T1		;SAVE NEW PC
	PUSHJ	P,GETWR1##	;GET BITS,,CLASS
	  POPJ	P,		;OUT OF BOUNDS
	MOVE	T3,T1		;SAVE THOSE
	PUSHJ	P,GETWR1##	;GET OLD PC
	  POPJ	P,		;ADDRESS CHECK - GIVE UP
	TRNE	T4,-1		;IF SPECIAL,
	TRNE	T3,(T4)		;  SEE IF USER OMITTED IT
	SKIPE	T1		;SEE IF IN USE ALREADY
	POPJ	P,		;YES - GIVE UP
	PUSHJ	P,GETWR1##	;GET THE OLD WORD
	  POPJ	P,0		; ADDRESS CHECK
	TLO	T1,(T4)		;TURN ON THE NEW BIT
	PUSHJ	P,PUTWRD##	;  STORE ERROR BITS
	  POPJ	P,		;ADDRESS CHECK - GIVE UP
	HLRZ	T1,T4		;GET NEW PC
	JUMPE	T1,CPOPJ##	;GIVE UP IF JUNK
	SOJA	M,CPOPJ1##	;OK RETURN

;DOINT -- ROUTINE TO PERFORM THE JOBINT
;CALL:	MOVE	T1,NEW PC
;	MOVEI	M,USER VIRTUAL ADDRESS OF INTERRUPT BLOCK + 2
;RETURN WITH JOBPD1 UPDATED


DOINT::	JUMPE	T2,CPOPJ##	;IF NO BLOCKS, GIVE UP
	EXCH	T1,JOBPD1##(R)	;STORE NEW PC
	TLO	T1,(XC.USR)	;MAKE SURE USER MODE IS ON
	HLLM	T1,JOBPD1##(R)	;STORE FLAGS
	PJRST	PUTWDU##	;STORE OLD PC AND RETURN
>	;END OF FTCCIN!FTDAEM!FTOPRERR
IFN FTSWAP,<
;ROUTINE TO PRINT "SWAP READ ERROR"
;CALLED FROM SWAPPER AT CLOCK LEVEL (USUALLY)
;CALL:	MOVE J,JOB NUMBER
;	PUSHJ P,ERRSWP
;	ALWAYS RETURN TO SWAPPER


ERRSWP::IFN	FTKI10!FTKL10,<
	PUSHJ	P,SVEUB##	;LOAD UBR
>;END FTKI,0
	MOVSI	T1,JERR		;SET JERR SO WE DO NOT
	IORM	T1,JBTSTS##(J)	;TRY TO INTERCEPT
	JSP	T1,ERRPNT	;PRINT MESSAGE
	ASCIZ	/Swap read error/
	PJRST	PCSTOP		;START TTY AND SET JERR BIT SO
				; JOB CANNOT CONTINUE. PI 7 WILL NOT
				; BE REQUESTED SINCE SWAPPING JOB CANNOT
				; BE CURRENT JOB.
				;ERRPNT PUSHED TWO AC'S. PCSTOP REMOVES THEM
>

;COMMON ERROR MESSAGE SETUP ROUTINES
;CALL:	JSP T1,ERRPTU, ERRDEV, OR ERRPNT
;	ASCIZ /message/
;	RETURNS HERE WITH F SAVED 0(P)
;	C(F)=TTYDDB, U TO TTY OUTPUT BUFFER POINTER
;	J=JOB NUMBER, W=ADDR OF PDB

;USE ERRPTU IF AT UUO LEVEL FOR SURE
;ERRDEV IF ERROR FOR AN ASSIGNED DEVICE AT ANY LEVEL
;ERRPNT WITH J ALREADY SET TO OFFENDING JOB NUMBER
;THE JSP CALL IS USED IN CASE PUSHDOWN SPACE BECOMES CRITICAL
;AGAIN AND ERRPNT HAS TO WIPE EXISTING LIST OUT


ERRPTU::SKIPA	J,JOB##		;BLAME CURRENT JOB IF NOT 0.
ERRDEV::LDB	J,PJOBN##		;JOB NO. FROM DEVICE DATA BLOCK
ERRPNT::PUSHJ	P,FNDPDB##	;FIND PDB FOR THIS JOB
IFN FTPDBS,<
	  MOVEI W,PDBPRO##	;MAY BE A SWAP READ ERROR ON PDB
>
IFE FTPDBS,<
	  HRRZ	W,JBTPDB##	;USE NULL JOB'S PDB
>
	SKIPN	J		;ERROR IN NULL JOB?
	SETOM	.C0NJE##	;YES, SET FLAG FOR ERROR IN NULL JOB
				; SO STATE OF NULL JOB WILL BE REESTABLISHED
				; WHEN IS IT RUN AGAIN(SEE CLOCK1)

IFN FTRCHK,<
	CAILE	J,JBTMAX##	;JOB NUMBER OR SEGMENT NUMBER
	STOPCD	.,STOP,SOR,	;++SEG OUT OF RANGE
>

	PUSH	P,U		;SAVE CALL TO ERROR(JSP U,ERROR)
	PUSH	P,F		;SAVE ADR. OF DEV. DATA BLOCK
	PUSH	P,T1		;SAVE RETURN FROM ERRPNT
	MOVE	R,JBTDAT##(J)	;EVEN NULL JOB HAS JOB DATA AREA
	MOVE	T1,JBTSTS##(J)
	TDNE	T1,[JERR,,JS.ASA]
	JRST	ERRPT1
IFN FTPI,<
	PUSHJ	P,USREIJ##	;SIGNAL USER ERROR
	JRST	ERRGOU
>
IFN FTCCIN!FTDAEM!FTOPRERR,<
	MOVEI	T4,.EREIJ	;DOES THIS JOB WANT
	PUSHJ	P,CHKINT	; TRAP ALL ERRORS?
	  JRST	ERRPT1		;NO--BOMB HIM OUT
	JUMPGE	T3,ERRPT1	;JUMP IF HE WANTS MESSAGE
	MOVE	T2,M		;NO MESSAGE
	PUSHJ	P,DOINT		;PREPARE INTERCEPT
;***NEED TO STORE ERROR CODE***
	PJRST	QKUSXT		;BACK TO USER
>
ERRPT1:	PUSHJ	P,TTYERP##	;FIND TTY FOR THIS ERROR (VIA J)
IFN FTOPRERR,<
	  PUSHJ	P,ERINDJ	;ERROR IN DETACHED JOB
>
	PUSHJ	P,INLMES##
	ASCIZ	/?
/
	PUSHJ	P,PRQM##	;PRINT QUESTION MARK ON NEXT LINE
				; FOR BATCH AND SCRIPT
	PJRST	INLMES##	;PRINT MESSAGE SPECIFIED BY CALLER
				; AND RETURN TO LOC. AFTER MESSAGE


IFN FTOPRERR,<
ERINDJ::JUMPE	J,ERINNJ	;JUMP IF NULL JOB
	PUSHJ	P,INLMES##	;PRINT ERROR MESSAGE
	ASCIZ	/?Error in detached job/
	PUSHJ	P,PRJBNM	;PRINT JOB # AND PROGRAM NAME
	PJRST	CRLF##		;PRINT <CRLF> AND RETURN
ERINNJ:	PUSHJ	P,INLMESS##	;PRINT ERROR MESSAGE
	ASCIZ	/?Error in job 0
/
	POPJ	P,
>
;ROUTINE TO PRINT UUO PC AND STOP JOB
;IF IN USER MODE PC WILL PRINT AS "AT USER LOC XXX"
;IF IN EXEC MODE "AT EXEC LOC XXX; EXEC CALLED FORM EXEC/USER/ LOC YYY


UUOMES::PUSHJ	P,CONMES##	;PRINT MESSAGE POINTED TO BY T1
UUOPCP::
	MOVE	T2,JOBPD1##(R)	;UUO PC STORED IN JOB DATA AREA
				; FIRST LOC ON PD LIST
	SOJA	T2,PCPNT	;DECREMENT TO POINT TO UUO IN USER AREA

;ROUTINE TO PRINT ONE OF THREE MESSAGES AND STOP JOB
;1) "AT EXEC LOC XXX; EXEC CALLED FROM EXEC LOC YYY"
;2) "AT EXEC LOC XXX; EXEC CALLED FORM USER LOC YYY"
;3) "AT USER LOC YYY"

;CALL:	MOVE T2, XXX		;WITH PC FLAGS IN LH
;	PUSHJ P,PCPNT
;	NEVER RETURN IF AT UUO LEVEL


PCPNT::	IFN FTWATCH,<
	TLNE	T2,USRMOD	;MAKE SURE CONTROL-T
	HRRM	T2,JBTPC##(J)	; GIVES CORRECT ANSWER
>
	PUSHJ	P,PCP		;PRINT " AT EXEC XXX" OR " AT USER "
	TLNE	T2,USRMOD	;WAS PC IN USER MODE?
	JRST	PCSTOP		;YES, ENOUGH INFO.

;ROUTINE TO PRINT EITHER:
;1) "; EXEC CALLED FROM EXEC LOC YYY"
;2) "; EXEC CALLED FROM USER LOC YYY"
;AND STOP JOB
;CALL:	PUSHJ P,EXCALP
;	NEVER RETURNS IF AT UUO LEVEL


EXCALP::PUSHJ	P,INLMES##
	ASCIZ	/; UUO/
	MOVE	T2,JOBPD1##(R)	;UUO PC IN JOB DATA AREA
	SUBI	T2,1		;BACK IT UP TO POINT TO UUO
	PUSHJ	P,PCP		;PRINT "EXEC LOC " OF USER LOC
PCSTOP::PUSH	P,U
	PUSHJ	P,TTYSRC##	;SET TTY
	STOPCD	.,STOP,LN1,	;NONE?!
	JUMPE	U,PCSTP2	;IS IT DETACHED?
	SKIPE	T1,F		;SKIP IF NO DDB
	LDB	T1,PJOBN##	;GET JOB #
	CAMN	T1,J		;IS THIS THE TTY OF THE LOOSER
	PUSHJ	P,TSETBI##	;CLEAR TYPE-AHEAD
PCSTP2:
IFN FTPI!FTCCIN!FTDAEM!FTOPRERR,<
	MOVE	T1,JBTSTS##(J)	;GET JOB STATUS
	TDNE	T1,[JERR,,JS.ASA]  ;CAN WE INTERCEPT
	JRST	PCSTP1		;NO--STOP JOB
>
IFN FTPI,<
	PUSHJ	P,PSIERR##
	  JRST	PCSTP4		;AT CLOCK LEVEL, CATCH IT AT CIPXIT
	  JRST	ERRGOU		;AT UUO LEVEL, CATCH IT AT USRXIT
>
IFN FTCCIN!FTDAEM!FTOPRERR,<
	MOVEI	T4,.EREIJ	;DOES THIS JOB WANT
	CAMN	J,.C0JOB##	;CANT INTERCEPT IF ON CLOCK LEVEL
	PUSHJ	P,CHKINT	; TRAP ALL ERRORS?
	  JRST	PCSTP1
	PUSHJ	P,DOINT		;PREPARE INTERCEPT
	PJRST	QKUSXT		;BACK TO USER
>
PCSTP1:	JUMPN	U,PCSTP3	;IS JOB DET'D
	POP	P,U
	PUSHJ	P,CRLF##	;YES,
	PUSHJ	P,ESTOP##	;STOP JOB
	JRST	ECONT		;RESUME FLOW
PCSTP3:	PUSHJ	P,HOLD##	;STOP JOB SET ERROR BIT
PCSTP4:	POP	P,U
;HERE TO CONTINUE AFTER ERROR (IF AT PI LEVEL OR USER TYPES CONT)
ECONT:	POP	P,F		;RETURN ONLY IF AT INTERRUPT LEVEL
	JRST	TPOPJ##		;REMOVE ERROR CALL AND RETURN
				;ALTHOUGH U WAS PUSHED, POP INTO T1, PERSERVE LINE NUMBER

;ROUTINE TO PRINT PC AS:
;1) "EXEC PC XXX" OR "USER PC XXX"
;CALL:	MOVE T2,PC TO PRINT(LH=PC FLAGS)
;	PUSHJ P,PCP


XMODE:	ASCIZ	/ at exec PC /
UMODE:	ASCIZ	/ at user PC /

PCP::	MOVEI	T1,XMODE	;ASSUME PC IN EXEC MODE
	TLNE	T2,USRMOD	;IS IT?
PCPU::	MOVEI	T1,UMODE	;NO, USER MODE
	PUSHJ	P,CONMES##	;PRINT ONE OR OTHER
	HRRZ	T1,T2		;PRINT RIGHT HALF IN OCTAL
				; FALL INTO OCTPNT



;ROUTINE TO PRINT 6 DIGIT OCTAL NUMBER
;CALL:	MOVEI LINE,LINE DATA BLOCK ADDRESS FOR TTY
;	HRR T1, OCTAL NUMBER
;	PUSHJ P,OCTPNT
;	RETURN T2,PRESERVED,T1 DESTROYED

OCTPNT::HRLZ	T1,T1		;MOVE TO LH FOR ROTATING
	TRO	T1,700000	;SETUP AN END FLAG

OCTP1:	ROT	T1,3		;GET NEXT OCTAL DIGIT
	TLNN	T1,777777	;WAS THAT FLAG?
	POPJ	P,		;YES, DO NOT PRINT IT
	PUSH	P,T1		;SAVE T1 OVER I/O ROUTINE
	PUSHJ	P,PRTNUM	;NO, PRINT OCTAL DIGIT
	POP	P,T1		;RESTORE T1
	HRRI	T1,0		;CLEAR RH
	JRST	OCTP1		;GET NEXT OCTAL DIGIT
;ROUTINE TO ADD 1 TO T1 AND PRINT DECIMAL
;SAME CALL AS OCTPNT


DECP1::	AOJA	T1,RADX10	;ADD 1 AND GO PRINT

;ROUTINE TO PRINT DECIMAL
;CALL:	SAME AS OCTPNT
;T2:	PRESERVED


RADX10::PUSH	P,T2		;SAVE T2
	PUSHJ	P,PRTDIG	;PRINT DECIMAL DIGITS
	PJRST	T2POPJ##	;RESTORE T2 AND RETURN

;RECURSIVE DECIMAL PRINT ROUTINE
;CALL:	MOVE T1,DECIMAL NO.
;	PUSHJ P,PRTDIG


PRTDIG::IDIVI	T1,12		;DIVIDE BY 10
	HRLM	T2,(P)		;RT ON PD LIST
	JUMPE	T1,.+2		;FINISHED?
	PUSHJ	P,PRTDIG	;NO, CALL S OR F 
PRTNMM:	HLRZ	T1,(P)		;YES, GET LAST NUMBER
PRTNUM:	MOVEI	T3,"0"(T1)	;CONVERT TO ASCII
	PJRST	COMTYO##	;AND TYPE IT OUT

;RECURSIVE OCTAL PRINT ROUTINE
;CALL:	SAME AS PRTDIG


PRTDI8::IDIVI	T1,10		;DIVIDE BY 8
	HRLM	T2,(P)		;PUT ON STACK
	JUMPE	T1,PRTNMM	;FINISHED?
	PUSHJ	P,PRTDI8	;NO - LOOP
	PJRST	PRTNMM		;OUTPUT
;ROUTINE TO PRINT "DEVICE XXX"
;CALL	MOVE U,ASCII OUTPUT BYTE POINTER
;	PUSH P,F
;	PUSHJ P,ERNAM


ERNAM::	PUSHJ	P,INLMES##
	ASCIZ	/device /
	SKIPN	T2,-1(P)	;IS F = 0?
	PJRST	PRNAM1		;YES, MESSAGE WITHOUT NAME
	MOVSI	T1,DVDSK	;DEVICE IS DISK BIT
	TDNN	T1,DEVMOD(T2)	;SKIP IF DISK
	JRST	ERNAM1		;NOT DISK, GET PHYSICAL DEVICE NAME
	SKIPN	T1,DEVUNI##(T2)	;GET CURRENT UNIT DATA BLOCK ADDRESS
	SKIPE	T1,DEVFUN##(T2)	;IF UNIT REMOVED, GET SAVED ADDRESS
	SKIPA	T2,UNINAM##(T1)	;GET PHYSICAL UNIT NAME AND SKIP TO PRNAM1
ERNAM1:	MOVE	T2,DEVNAM(T2)	;NO, GET DEVICE NAME


;ROUTINE TO PRINT SIXBIT NAME
;CALL	MOVE U,ASCII OUTPUT BYTE POINTER
;	MOVE T2,NAME
;	PUSHJ P,PRNAME


PRNAM1:	MOVEI	T1,0
	LSHC	T1,6		;SHIFT IN NEXT CHAR.
	MOVEI	T3,40(T1)	;ASCII VERSION INTO CHREC FOR OUTCHS
	PUSHJ	P,COMTYO##	;OUTPUT CHARACTER
PRNAME::JUMPE	T2,CPOPJ##
	JRST	PRNAM1


	LIT

ERREND:	END