Google
 

Trailing-Edge - PDP-10 Archives - custsupcuspmar86_bb-x130b-sb - kiser.mac
There are 6 other files named kiser.mac in the archive. Click here to see a list.
TITLE	KISER - KI10 PROCESSOR DEPENDENT CODE - V375
SUBTTL	J.M. FLEMMING/JMF/DAL  TS   10 SEP 85
	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.
;
.CPYRT<1973,1986>
;COPYRIGHT (C) 1973,1974,1975,1976,1977,1978,1979,1980,1982,1984,1986
;BY DIGITAL EQUIPMENT CORP., MAYNARD, MASS.
;ALL RIGHTS RESERVED.
;
;
;DATE		LOAD	EDIT
;
;
;

XP VKISER,375
		; PUT VERSION NUMBER IN GLOB LISTING AND LOADER STORAGE MAP

	ENTRY	KISER		;LOAD KISER IF LIBRARY SEARCH
KISER::

SUBTTL	CLOCK1 - INTERFACE TO JOB STARTUP, STOP, AND CONTEXT SWITCHING ROUTINES
SUBTTL	TRAP HANDLING AND CONTEXT SWITCHING

;HERE TO PROCESS USER ARITHMETIC OVERFLOW TRAPS
SAROVF::MOVE	T1,.UPMP+.UPMUP	;GET PC
	MOVE	T3,.JDAT+JOBENB## ;GET USER'S ENABLE BITS
	TRNN	T3,AP.AOV	;OVERFLOW - IS THE USER ENABLED?
	TLNE	T1,(XC.FOV)	;TRAP CAUSED BY FOV?
	CAIA			;YES,
	JRST	SAROV6		;NOT ENABLED, IGNORE IT
	HRRI	T3,AP.AOV+AP.FOV;ASSUME FLOATING OVERFLOW
	TLNN	T1,(XC.FOV)	;WAS IT A FLOATING OVERFLOW TRAP?
	TRZ	T3,AP.FOV	;NO, INTEGER OVERFLOW
;HERE WITH T1=PC, T3=APRENB BITS
SAROV3:	TLZ	T1,637		;CLEAR BITS FOR COMPATABILITY
	MOVEM	T1,.JDAT+JOBTPC## ;SAVE OLD PC
	MOVEM	T3,.JDAT+JOBCNI## ;LIKE CONI ON THE KA-10
	MOVE	T3,.JDAT+JOBENB## ;GET USER'S ENABLE BITS
	TRNE	T3,XP.DDU	;USER WANT TRAPS REENABLED?
	JRST	SAROV5		;YES, LEAVE AS IS
	HLLZS	.JDAT+JOBENB##	;CLEAR USER'S ENABLE BITS SO MUST DO APRENB AGAIN
	MOVEI	T3,UP.PFT
	MOVEM	T3,.UPMP+.UPPFT	;EXEC WILL FIELD ILM
	MOVSI	T3,(JFCL)	;NOP
	MOVEM	T3,.UPMP+.UPAOT	;IGNORE ARITHMETIC TRAPS
	MOVEI	T3,UP.PDT
	MOVEM	T3,.UPMP+.UPPDT	;EXEC WILL FIELD PDL OVERFLOWS
	SETZM	.CPCN1##	;CLEAR POSSIBLE NXM OR CLOCK ENABLES
SAROV5:	MOVEI	T3,XP.CLK	;ALWAYS DISABLE CLOCK
	ANDCAM	T3,.CPCN1##
	HRRZ	T3,.JDAT+JOBAPR## ;PC IN TRAP ROUTINE?
	CAIE	T3,0(T1)
	CAIN	T3,-1(T1)
	JRST	SAROV7		;YES
	HRR	T1,.JDAT+JOBAPR## ;GET USER'S TRAP ADDRESS
	TLZ	T1,(XC.OVF+XC.FOV+XC.FUF+XC.NDV+IC.BIS+IC.AFI)
	TLO	T1,(XC.PUB!XC.USR) ;INSURE PUBLIC AND USER MODE IS SET
SAROV6:	MOVEM	T1,.UPMP+.UPMUO	;NEW PC WITH TRAP CAUSING BITS CLEARED
	MOVE	P,[XWD MJOBPD##,.JDAT+JOBPDL##] ;SET UP A STACK
	PUSHJ	P,SCDCHK##	;CHECK IF WE SHOULD RESCHEDULE
	JEN	@.UPMP+.UPMUO	;EXIT TO THE USER'S TRAP HANDLER
SAROV7:	HLLZM	T1,.CPAPC##	;SAVE OLD PC FOR THE ERROR MESSAGE
	HRRZM	T1,.CPAPC##+1
	MOVEI	T1,XP.LTH	;STUCK IN LOOP BIT
	HRRM	T1,.CPAEF##
	JRST	SEPDL3
SEPDLO::EXCH	T1,.UPMP+.UPMUP	;GET THE PC
	HLLZM	T1,.CPAPC##	;SET AS ERROR PC FOR ERRCON
	HRRZM	T1,.CPAPC##+1	; ..
	HRRI	T1,AP.POV	;SET PUSH DOWN OVERFLOW FLAG
SEPDL1:	HRRM	T1,.CPAEF##	;IN .CPAEF SO ERRCON WILL GET CALLED
	MOVE	T1,.UPMP+.UPMUP	;RESTORE T1
SEPDL3:	SETOM	.CPSCF##	;SET FORCED RESCHEDULING FLAG
	SETOM	.CPCKF##	;AND CLOCK FLAG
	CONO	PI,CLKBIT##+PI.IIO  ;REQUEST A CLOCK INTERRUPT AND TURN THE PI SYSTEM ON
	CONSO	PI,II.IPA	;ANY PIS IN PROGRESS?
	JRST	.		;WAIT UNTIL CLOCK LEVEL HAPPENS AND THE JOB
				; IS STOPPED IF IN USER MODE.  IF THE PC IS IN
				 ;EXEC MODE, ERRCON WILL CONTINUE AT
				; (.CPAPC) INSTEAD OF HERE
	MOVEM	P,PIPPDL	;SAVE OLD STACK POINTER
	MOVEI	P,PIPPDL	;AND GET NEW ONE
	STOPCD	.,STOP,PIP,	;++PI IN PROGRESS
	$LOW
PIPPDL:	EXP	0
	BLOCK	1
	$HIGH
SEILM::	SKIPN	.CPEJ1##	;ALREADY BEEN HERE (T1 AND T2 SAVED)?
	DMOVEM	T1,.CPST1##	;NO, SAVE T1 AND T2 HERE
	MOVE	T1,.UPMP+.UPMUP	;GET THE PC
	HLLZM	T1,.CPAPC##	;STORE IT AS POTENTIAL ERROR PC
	HRRZM	T1,.CPAPC##+1	; ..
	MOVE	T2,.UPMP+.UPUPF	;GET THE USER PAGE FAIL WORD
	TLNN	T1,(XC.USR)	;DID THE PAGE FAULT OCCUR IN USER MODE?
	SKIPA	T2,.UPMP+.UPEPF	;NO, GET THE EXEC PAGE FAIL WORD
	MOVE	T3,T2		;USER PAGE FAULT, SAVE PC FOR POSSIBLE CALL TO USRFLT
	MOVEM	T2,.CPPFW##	;STORE PAGE FAULT WORD
	JUMPL	T2,SEILM4	;INSURE AGAINST HARDWARE STORING A -1 P.F. WORD
	ANDI	T2,37		;CLEAR ALL BUT THE PAGE FAIL CODE
	TLNE	T1,(XC.USR)	;PAGE FAULT IN EXEC MODE?
	JRST	SEILM0		;NO, PROCEED
	CAIN	T2,PF.ABF	;WAS THE PAGE FAULT AN ADDRESS BREAK?
	JRST	SEILM1		;YES, REMEMBER IT AND GO AWAY
	JRST	SEILM7		;NO, EXEC ILL MEM REF, LOOK FOR ERJMP

SEILM0:	MOVE	P,[XWD MJOBPD##,.JDAT+JOBPDL##]	;SETUP A PUSH DOWN LIST
	SKIPN	.UPMP+.UPJOB
	STOPCD	.,CPU,PFN	;++PAGE FAULT IN NULL JOB
	PUSH	P,T1		;SAVE USER'S PC
	CAIN	T2,PF.ABF	;ADDRESS BREAK?
	JRST	SEILM1		;YES, GO PROCESS
	MOVE	T4,T1		;PC WORD INTO T4 FOR USRFLT
	HRRI	T1,AP.ILM	;ILLEGAL MEMORY REFERENCE
	CAIN	T2,PF.PRV	;WAS IT A PROPRIETARY VIOLATION?
	TROA	T1,AP.PPV	;INDICATE PROPRIETARY VIOLATION (AVOID CALL TO USRFLT)
	PUSHJ	P,USRFLT##	;SEE IF PAGE FAULT FOR A VM USER
				; WILL NOT RETURN IF SO (DISPATCH TO USER)
	MOVE	T2,.CPST2##	;RESTORE T2
	JRST	SEPDL1		;GO SAY "ILL. MEM. REF."
SEILM1:	TLO	T1,(IC.AFI)	;INHIBIT ADDRESS BREAK WHEN INSTRUCTION IS
				; EXECUTED AGAIN
	EXCH	J,.CPJOB##	;GET JOB
	PUSH	P,W		;SAVE W IN CASE IN EXEC MODE
	PUSHJ	P,FNDPDS##	;FIND THE PDB
	LDB	T2,[POINT 9,.PDABS##(W),17]	;GET THE PROCEED COUNT
	SOSL	T2		;DECREMENT
	DPB	T2,[POINT 9,.PDABS##(W),17]	;STORE IT BACK IF POSITIVE
	POP	P,W		;RESTORE W
	JUMPG	T2,SEILM3	;DON'T BREAK IF PROCEED COUNT .GT. 0
	MOVE	T2,JBTSTS##(J)	;IS THIS A JACCT
	TLNN	T2,JACCT	;JOB
	JRST	SEILM6		;NOT JACCT
	MOVE	T2,JBTPPN##(J)	;YES, BUT IS
	CAME	T2,FFAPPN##	; HE GOD?
	JRST	SEILM3		;NO-IGNORE BREAK
SEILM6:	EXCH	J,.CPJOB##	;UNDO LAST EXCH
	TLNN	T1,(XC.USR)	;PC IN USER MODE?
	JRST	SEILM2		;NO, REMEMBER BREAK AND GO AWAY
	MOVEM	T1,.CPPC##	;STORE THE PC WITH IFA ON
IFN FTPI,<
	MOVE	J,.CPJOB##	;JOB NUMBER FOR PSISER
	SIGNAL	C$ADRB		;SIGNAL THAT AN ADDRESS BREAK HAS OCCURED
	  SKIPA			;USER DOESN'T WANT TRAP
	JRSTF	@.CPPC##	;THE USER IS ENABLED, INTERRUPT HIM
>	;END FTPI
	PUSH	P,.CPPC##	;SAVE PC ON STACK
	PUSHJ	P,TTYFUW##	;FIND THE USER'S TTY
	PUSHJ	P,INLMES##	;REPORT THE ADDRESS BREAK
	ASCIZ	/
%Address break at user PC /
	HRRZ	T1,(P)		;GET THE USER'S PC
	PUSHJ	P,OCTPNT##	;TELL HIM WHERE THE BREAK OCCURED
IFN FTPI,<
	PUSHJ	P,PSIERR##	;PENDING INTERRUPT?
	  JFCL
	  PJRST	ERRGOU##	;YES, GIVE IT TO THE USER
>
	PJRST	HOLDW##		;STOP THE JOB IN A CONTINUABLE STATE
SEILM2:	MOVEI	T2,JS.ASA	;AC'S ARE IN THE SHADOW AREA BIT
	EXCH	J,.CPJOB##	;JOB NUMBER
	TDNE	T2,JBTSTS##(J)	;SAVE/GET IN PROGRESS?
	JRST	SEILM3		;YES, DON'T BOTHER THE USER WITH BREAKS ON THAT
	MOVEI	T2,JS.ABP	;ADDRESS BREAK HAPPENED DURING UUO PROCESSING BIT
	IORM	T2,JBTST2##(J)	;REMEMBER THAT THE BREAK HAPPENED
SEILM3:	EXCH	J,.CPJOB##	;RESTORE J
SEILM4:	MOVEM	T1,.UPMP+.UPMUP	;STORE PC WITH IC.AFI ON
	DMOVE	T1,.CPST1##	;RESTORE T1 AND T2
	JRSTF	@.UPMP+.UPMUP	;GO AWAY AND TELL THE USER ABOUT THE BREAK
				; AT UUO EXIT
;HERE IF AN ILL MEM REF OCCURED IN EXEC MODE, CHECK FOR ERJMP OR
;ERCAL BEFORE CALLING IT AN IME

SEILM7:	CONSO	PI,PI.IPA	;AT INTERRUPT LEVEL?
	JRST	SEJLM2		;NO, UUO LEVEL, OK
	CONSO	PI,PI.IPA-PI.IP7 ;YES - LEVEL 7?
	SKIPN	.CPISF##	;YES, FROM SCHEDULER?
	JRST	SEILME		;PI1 - PI6 OR NON-SCHEDULER PI7

SEJLM2:	SKIPE	.CPEJ1##	;NESTING?
	JRST	SEILM8		;YES, IT'S AN IME
	MOVE	T2,.CPPFW##	;NO, GET PAGE FAULT WORD
IFN FTPEEKSPY,<
	TLNE	T2,(PF.USR)	;USER REFERENCE
	PUSHJ	P,[PUSHJ P,SAVT## ;YES, SAVE ACS
		   LDB T1,[POINT 9, T2,17] ;VIRTUAL PAGE NUMBER
		   PUSHJ P,TSSPT## ;A SPY PAGE?
		     POPJ P,	;NO
		   PJRST UADERR##] ;YES,BLAME THE USER
>
	DMOVEM	T1,.CPEJ1##	;"TOP LEVEL", REMEMBER IN CASE WE NEST
	MOVEM	T1,.CPEJ3##	;ALSO SAVE HERE FOR PSYCHOPATHIC CASES
	SKIP	(T1)		;TOUCH PAGE FAULT PC LOCATION AND
	LDB	T2,[POINT 13,1(T1),12]  ;GET INSTRUCTION FOLLOWING
				; IF THE PC JUMPED OFF INTO THE BOONIES
				; THEN THIS WILL PAGE FAULT AND WE WILL
				; KNOW WE HAVE A REAL IME
	CAIE	T2,<ERJMP>_-^D23	;IS IT AN ERJMP?
	JRST	SEILM8		;NO, THEN WE HAVE AN IME
	MOVE	T2,1(T1)	;GET ENTIRE ERJMP EXPRESSION
	MOVEM	T2,.CPEJ4##	;AND SAVE IT WHERE WE CAN FIND IT
	DMOVE	T1,.CPST1##	;RESTORE FULL AC SET
	MOVEI	T1,@.CPEJ4##	;GET "E" OF ERJMP
				; IF THIS IME'S (NOTE .CPEJ1 STILL
				; NON-ZERO) THEN .CPEJ3 HAS ORIGINAL
				; TRAP PC WHICH STARTED THIS MESS.
	HRRM	T1,.CPAPC##	;SET FROM WHENCE TO CONTINUE
	MOVE	T1,.CPST1##	;RESTORE T1 AGAIN
	SETZM	.CPEJ1##	;CLEAR NESTING FLAG
	JRSTF	@.CPAPC##	;AND GO PROCESS THE ERROR

;HERE ON NESTED IME, "RESTORE" THE FIRST IME AND STOPCD

SEILM8:	DMOVE	T1,.CPEJ1##	;PAGE FAULT PC AND REASON WORDS
	MOVEM	T1,.CPAPC##	;SET TRUE ERROR PC
	MOVEM	T1,.UPMP+.UPMUP	;ALSO MAKE UPMP LOOK RIGHT
	MOVEM	T2,.CPPFW##	;SET TRUE PAGE FAULT WORD
	MOVEM	T2,.UPMP+.UPEPF	;ALSO MAKE UPMP LOOK RIGHT
SEILME:	SETZM	.CPEJ1##	;CLEAR NESTING FLAG
	STOPCD	.+1,JOB,IME,	;++ILL MEM REF FROM EXEC
	JRST	SEILM4		;AND DISMISS THE TRAP
EXCABK::ANDCAM	T1,JBTST2##(J)	;CLEAR BREAK HAPPENED IN EXEC MODE BIT
	PUSHJ	P,FNDPDS##	;FIND THIS JOB'S PDB
	MOVSI	T1,(OC.BCM)	;BREAK ON MUUO REFERENCES BIT
	TDNN	T1,.PDABS##(W)	;IS THE USER INTERESTED?
	 POPJ	P,		;NO, GO AWAY
IFN FTPI,<
	MOVE	T2,.JDAT+JOBPD1##	;GET UUO PC
	MOVEM	T2,.CPPC##	;STORE IT WHERE PSISER EXPECTS IT
	SIGNAL	C$ADRB		;SIGNAL THAT AN ADDRESS BREAK OCCURED
	  SKIPA			;USER DOESN'T WANT TRAP
	POPJ	P,		;USER IS ENABLED, UUO EXIT WILL INTERRUPT TO HIM
>
IFN FTMP,<
	PUSHJ	P,ONCPU0##	;MUST BE ON CPU0 TO WRITE A MESSAGE
>
	PUSHJ	P,TTYFUW##	;FIND THE USER'S TTY
	PUSHJ	P,INLMES##	;REPORT THE ADDRESS BREAK
	ASCIZ	/
%Address break at exec PC /
	HRRZ	T1,.UPMP+.UPMUP	;GET THE PC WHERE THE LAST BREAK OCCURED
	PUSHJ	P,OCTPNT##	;TELL HIM THAT
	MOVEI	T1,[ASCIZ/; UUO/]
	PUSHJ	P,CONMES##
	MOVE	T2,.JDAT+JOBPD1##	;GET THE UUO PC
	PUSHJ	P,PCP##		;REPORT IT SO HE WILL KNOW WHAT UUO BROKE
IFN FTPI,<
	PUSHJ	P,PSIERR##	;PENDING INTERRUPT?
	  JFCL
	POPJ	P,		;YES
>
	POP	P,(P)		;POP OFF THE PUSHJ TO EXCABK
	PJRST	HOLDW##		;AND STOP THE JOB IN A CONTINUABLE STATE
SUILM::MOVEM	T1,.UPMP+.UPMUO	;SAVE A TEMPORARY
	MOVE	T1,.UPMP+.UPMUP	;GET ILM PC
	MOVE	T2,.UPMP+.UPUPF	;GET THE PAGE FAIL WORD
	ANDI	T2,37		;PAGE FAIL CODE
	CAIN	T2,PF.ABF	;ADDRESS BREAK?
	JRST	SEILM0		;YES, GO PROCESS IT
	MOVE	T3,.UPMP+.UPUPF	;GET THE USER PAGE FAIL WORD
	MOVE	T4,T1		;MOVE THE PC TO T4 FOR USRFLT
	MOVE	P,[XWD MJOBPD##,.JDAT+JOBPDL##]	;SETUP A PUSH DOWN LIST
	PUSHJ	P,USRFLT##	;SEE IF PAGE FAULT FOR VM USER
				; WILL NOT RETURN IF SO (DISPATCH TO PFH)

	MOVEI	T3,AP.ILM	;SET ILM BIT FOR USER
	JRST	SAROV3		;FINISH UP
SUPDLO::MOVE	T1,.UPMP+.UPMUP	;GET ERROR PC
	MOVEI	T3,AP.POV	;SET POV BIT FOR USER
	JRST	SAROV3		;FINISH UP
;ROUTINE TO SET HARDWARE AND SOFTWARE RELOCATION INFORMATION FOR CURRENT USER
;CALLING SEQUENCE:
;	PUSHJ	P,SETREL
;	...	RETURN HERE
;J = CURRENT JOB NUMBER

SETRLH::MOVE	J,.CPJOB##	;J=CURRENT JOB NUMBER
	MOVEI	T1,0
	DPB	T1,JBYHSS##	;FORCE MAP TO BE REDONE
SETREL::MOVE	J,.CPJOB##	;J = CURRENT JOB NUMBER
SETRL1::MOVE	T1,JBTADR##(J)	;T1 = PROT,,EVA
				; OF THE FIRST PAGE OF THE LOW SEGMENT
	MOVEM	T1,.CPADR##	;SET .CPADR FOR QUICK ACCESS AT APR LEVEL
	HLRZM	T1,.CPREL##	;SET .CPREL FOR ADDR CHECKING
IFN FTTRPSET,<
	SKIPE	T2,.CPSTS##	;HAS TIMESHARING BEEN STOPPED VIA TRPSET?
	CAIE	T2,(J)		;YES, IS IT THIS JOB?
	JUMPN	T2,SETRLZ	;NO, DON'T CHANGE THE UBR
>
	SKIPE	J		;NULL JOB ALWAYS HAS A UPMP
	JUMPE	T1,SETRLZ	;THERE IS NO UPMP IF THE JOB HAS NO CORE
	PUSHJ	P,STEUB		;NO, SET THE USER BASE REGISTER
	JUMPE	T1,SETRLZ	;IF NULL JOB OR CORE 0, DON'T STORE IN
				; NON-EXISTANT JOB DATA AREA
	HLRZM	T1,.UPMP+.UPHVA	;SET .UPHVA FOR ADDRESS CHECKING AT IRP LEVEL
	LDB	T2,[POINT 9,T1,8];GET THE CURRENT SIZE
	LDB	T1,JBYLSS##	;GET THE PREVIOUS SIZE OF THE LOW SEGMENT
	CAIE	T1,(T2)		;IS IT THE SAME SIZE AS IT WAS THE LAST
				; TIME THIS JOB WAS RUN?
	PUSHJ	P,MAPLOW##	;NO, REDO THE MAP
	SKIPN	T1,.UPMP+.UPREL	;HOLEY PROGRAM?
	HLR	T1,JBTADR##(J)
	HRRZM	T1,.JDAT+JOBREL##	;STORE HIGHEST CORE-UUO ADDRESS IN JOBREL

	SKIPL	T1,JBTSGN##(J)	;JOB HAVE A REAL HIGH SEGMENT?
	SKIPA	T1,JBTADR##(T1)	;YES
	HRLZS	T1		;SIZE OF SPY SEGMENT OR ZERO IF NOT SPY SEGMENT
	LDB	T2,[POINT 9,T1,8];CURRENT SIZE -1 OF THE HIGH SEGMENT
	SKIPE	T1		;IS THERE A SPY OR HIGH SEGEMNT?
	ADDI	T2,1		;YES, ITS ACTUALLY ONE PAGE BIGGER
	LDB	T1,JBYHSS##
	MOVSI	T3,REDOMP!SEGMB
	TDNN	T3,JBTSGN(J)
	CAIE	T1,(T2)		;HAS THE HIGH SEGMENT SIZE CHANGED SINCE THE
				; LAST TIME THIS JOB WAS RUN?
	PUSHJ	P,MAPHGH##	;YES, REDO THE HIGH SEGMENT PART OF THE MAP
	MOVSI	T1,REDOMP!SEGMB
	ANDCAM	T1,JBTSGN(J)

SETRLZ:
	PUSHJ	P,FDNJP##	;FIND THE NULL JOB'S PDB
	MOVE	T3,T1		;SAVE THE ADDRESS OF THE NULL JOB'S PDB
	PUSHJ	P,FNDPDS##	;FIND THE CURRENT JOB'S PDB

	HRRZ	T1,JBTUPM##(J)	;PAGE NUMBER OF THE CURRENT JOB'S UPMP
	JUMPE	T1,SETRL2	;DON'T CHANGE ANYTHING IF THERE ISN'T ONE
	MOVSI	T1,<(PG.LUB)>(T1)
IFN FTRTTRP,<
	MOVEM	T1,.CPDTO##	;SAVE FOR RTTRP INTERRUPT LEVEL USE
>
	TLO	T1,(PG.ACE+PG.AC1)	;USER ADDRESS COMPARE ENABLE AND USER AC SET 1
	.SKIPE	T2,.PDABS##(W)	;DOES THE USER HAVE ADDRESS BREAK SETTINGS?
	TLNN	T2,(OC.ABE)	;YES, IS HE ENABLED FOR BREAKS
	MOVE	T2,[EXP OC.FEP+CURJOB##]	;NO, DISPLAY JOB NUMBERS

	DATAO	PAG,T1		;SETUP THE UBR
	TLZ	T2,777(OC.BSU)	;CLEAR PROCEED COUNTER AND SET BY UUO
	.SKIPL	.PDABS##(T3)	;CAN USERS USE ADDRESS BREAK?
	DATAO	PTR,T2		;YES, SETUP BREAK CONDITIONS AND BREAK ADDRESS

SETRL2:	SKIPN	JBTADR##(J)	;JOB HAVE CORE IN CORE?
	TDZA	T1,T1		;NO, MUST BE THE NULL JOB OR CORE 0
	MOVE	T1,.JDAT+JOBENB##	;JOB'S APR ENABLE BITS
	PJRST	SETCNA##	;SETUP APR ENABLE BITS FOR USER
				; NO ENABLES IF NULL JOB OR NO CORE IN CORE
;ROUTINE TO SETUP USER AND EXEC BASE REGISTERS FOR A JOB
;CALLING SEQUENCE:
;	MOVE	J,JOB NUMBER
;	PUSHJ	P,STEUB

MKADD::	CAME	J,.USJOB	;JOB ALREADY ADDRESSABLE?
STEUB::	CAILE	J,JOBMAX##	;IS THIS A LOW SEGMENT?
	POPJ	P,		;NO, THE UBR MUST ALREADY BE SETUP
				; OR DOESN'T NEED TO BE (ADDRESSES WILL BE
				; MAPPED THROUGH THE EXEC MAP)
	PUSH	P,T1		;SAVE A TEMPORARY
	HRRZ	T1,JBTUPM##(J)	;T1 = THE PAGE NUMBER OF THE USER PAGE MAP PAGE
	TRNN	T1,17777	;IS THERE A UPMP
	JRST	TPOPJ##		;NO, DON'T CLOBBER UBR
	MOVSI	T1,<(PG.LUB+PG.AC1)>(T1)
	DATAO	PAG,T1		;SET FOR CURRENT USER AND CLEAR THE AM
	JRST	TPOPJ##		;RESTORE T1 AND RETURN
SUBTTL	IOCSS - I/O SERVICE SUBROUTINES (UUOCON AND DEVICE ROUTINES)

;ROUTINE TO SAVE AND OPTIONALLY SET UP THE USER BASE REGISTER
; AND RESTORE IT ON A CPOPJ OR CPOPJ1 RETURN
;CALLING SEQUENCE:
;	PUSHJ	P,SVEUB		;TO SAVE USER BASE REGISTER
;OR
;	PUSHJ	P,SVEUB		;TO SAVE USER BASE REGISTER AND SETUP
;				;USER BASE REGISTER FOR JOB IN J
;ALWAYS RETURN HERE

SVEUF::	PUSH	P,T1		;SAVE A TEMPORARY
	DATAI	PAG,T1		;GET THE USER AND EXEC BASE REGISTERS
	PUSH	P,J		;SAVE J
	LDB	J,PJOBN##	;GET THE JOB NUMBER OF JOB CURRENTLY USING
				; THIS DEVICE
	PUSHJ	P,STEUB		;SETUP THE UBR SO CURRENT JOB IS ADDRESSABLE
	POP	P,J		;RESTORE J
	JRST	SSEU1		;SAVE THE PREVIOUS CONTENTS OF THE UBR AND EBR
SVEUB::	PUSH	P,T1		;SAVE A TEMPORARY
	DATAI	PAG,T1		;GET THE CONTENTS OF THE USER AND EXEC BASE REGISTERS
	PUSHJ	P,STEUB		;SETUP THE UBR FOR THE JOB WHOSE JOB NUMBER
				; IS IN J
	JRST	SSEU1		;SAVE THE PREVIOUS CONTENTS OF THE UBR AND THE EBR
SSEUB::	PUSH	P,T1		;SAVE A TEMPORARY
	DATAI	PAG,T1		;GET THE CONTENTS OF THE USER AND EXEC BASE REGISTERS
SSEU1:	EXCH	T1,-1(P)	;GET THE CALLER'S PC AND SAVE THE CONTENTS
				; OF THE UBR AND EBR
	MOVEM	T1,1(P)		;SAVE THE CALLER'S PC IN A TEMPORARY LOCATION
				; ON THE STACK
	POP	P,T1		;RESTORE T1 TO ITS CONTENTS ON ENTRY
	PUSHJ	P,@2(P)		;RETURN TO THE CALLER LEAVING .+1 ON THE
				; STACK SO WHEN THE CALLER DOES A POPJ OR
				; A CPOPJ1, CAN RESTORE THE PREVIOUS CONTENTS
				; OF THE UBR AND THE EBR
	  CAIA			;CPOPJ RETURN
	AOS	-1(P)		;CPOPJ1 RETURN - BUMP RETURN PC
	EXCH	T1,(P)		;GET THE PREVIOUS CONTENTS OF THE UBR
	TDO	T1,[EXP PG.LUB+PG.LEB]
	DATAO	PAG,T1		;RESTORE THE UBR AND THE EBR
	JRST	TPOPJ##		;RESTORE T1 AND RETURN
;ROUTINE TO CONVERT AN IOWD TO ABSOLUTE IOWDS
;FOLLOWING THE PAGING OF A JOB
;CALLING SEQUENCE:
;	MOVE	T2,IOWD
;	MOVEI	P1,0		;FIRST CALL
;	MOVE	P3,LOC OF CHANNEL DATA BLOCK
;	LH(P3)=1 IF STORE EXPECTED CHAN TERM WORD
;	MOVE	P4,FRAME-COUNT,,CHARS/WD IF DX10 CHL
;	PUSHJ	P,MAPIOW
;	RETURN HERE IF NOT ENOUGH MONITOR FREE CORE
;	RETURN HERE - P2=ADDRESS OF FIRST IOWD
;	P1=WHERE NEXT IOWD WILL BE STORED
;	LH(P2)=LOC WHERE IOWD WAS STORED, IF A DX10

MAPIO::	TLNN	T2,-1		;0 OR CHANNEL JUMPS ARE ILLEGAL
	STOPCD	CPOPJ##,DEBUG,IEZ,	;++IOWD EQUALS ZERO
	PUSHJ	P,SVEUB		;SAVE AND SETUP UBR
	PUSH	P,U		;SAVE U
	LDB	U,[POINT 2,CHB22B##(P3),1]
				;GET CHL TYPE INFO
	HLL	U,P4		;PRESERVE FRAME-COUNT

	PUSH	P,T1		;SAVE ALL ACS THAT ARE USED SINCE THEY
	PUSH	P,P4		; ARE PROBABLY IMPORTANT TO THE CALLERS
	PUSH	P,P3		; OF MAPIOW
	PUSH	P,T2		; ..
	PUSH	P,T3		; ..
	PUSH	P,T4		; ..
	JUMPN	P1,MAPIO1	;P1 IS NON-ZERO IF NOT THE FIRST CALL
	PUSHJ	P,GCH4WD	; ..
	  JRST	MAPIO9		;NONE AVAILABLE
	MOVE	P1,T1		;ADDRESS OF THE FOUR WORD BLOCK
	MOVE	P2,T1		;ADDRESS OF THE IOWD LIST
	HRLI	P1,-3		;THE NUMBER OF WORDS LEFT IN THIS BLOCK
	SETZM	3(P1)		;ZERO THE LAST WORD OF THE BLOCK
MAPIO1:	PUSHJ	P,CHKMOR	;GET ANOTHER FOUR WORD BLOCK AND LINK IT
				; TO THE CURRENT BLOCK IF ABOUT TO USE
				; THE LAST WORD OF THE CURRENT BLOCK
	  JRST	MAPIO8		;NO MORE FOUR WORD BLOCKS
	MOVE	P4,-2(P)	;RESTORE THE IOWD TO P4
	HRRZ	T2,P4		;ADDRESS-1 WHERE I/O WILL START
	MOVE	T3,DEVMOD(F)
IFE FTSPL,<
	TLNN	T3,DVDSK	;IF A DSK
>
IFN FTSPL,<
	SKIPL	DEVSPL(F)	;SPOOLED DDBS ARE ALWAYS A DSK
	TLNE	T3,DVDSK	;IS A DSK
	CAIA
>
	JUMPN	T3,MAPI1B
	JUMPGE	S,MAPI1B
	SKIPN	DINITF##
	CAIE	T2,@.UPMP+.UPMBF	;WE KNOW BITS 13-17 ARE ZERO
	JRST	MAPIO6
	ADDI	T2,<.MCFV-.FPMC>+1
	JRST	MAPI1D
MAPI1B:
	MOVEI	T2,1(P4)	;STARTING ADDRESS
MAPI1D:	LSH	T2,W2PLSH##	;CONVERT TO PAGE NUMBER
	ROT	T2,-1		;SET UP A BYTE POINTER TO THE PAGE IN THE UPMP
	ADDI	T2,.UPMP
	TLZE	T2,400000
	TLOA	T2,(<POINT 18,0,35>)
	TLO	T2,(<POINT 18,0,17>)
	MOVE	P3,T2		;SAVE POINTER IN P3
	MOVE	T2,P4		;T2 AND P4 = IOWD
	HLROS	P4		;P4 = -WORD COUNT
	ADDI	T2,1		;POINT AT REAL ADR
MAPIO2:	LDB	T3,P3		;T3 = CURRENT ABSOLUTE PAGE NUMBER
	TRNN	T3,PM.ACC
	SKIPGE	USRHCU##	;IF A SAVE IS IN PROGRESS,
	SKIPA			; THEN, THIS IS OK
	JRST	S..AAO		;ACCESS ALLOWED OFF
				; IOWD HAS BEEN ADDRESS CHECKED)
	MOVEI	T1,0		;T1 = AMOUNT ACCUMULATED SO FAR
	LSH	T3,P2WLSH##	;MOVE PAGE NUMBER TO THE HIGH ORDER THIRTEEN
				; BITS OF THE ADDRESS
	ANDI	T2,PG.BDY##	;GET THE STARTING WORD ADDDESS WITHIN THE PAGE
	ADD	T2,T3		;T2 = ABSOLUTE ADDRESS (IOWD STYLE)
	SUBI	T2,1		;MAKE AN IOWD
	PUSH	P,T2		;SAVE THE ADDRESS
	ANDI	T2,PG.BDY##	;EXTRACT THE WORD NUMBER
	SUBI	T2,PAGSIZ##-1	;CALCULATE THE NUMBER OF WORDS TO DO INTO THIS PAGE
	SKIPN	T2		;IF ITS ZERO DO A WHOLE PAGE WORTH
MAPIO3:	MOVNI	T2,PAGSIZ##	; ..
	SUB	P4,T2		;ADD -NUMBER OF WORDS ON THIS PAGE TO 
				; IOWD WORD COUNT
	ADD	T1,T2		;ACCUMULATE IN TOTAL WORD COUNT
	JUMPGE	P4,MAPIO4	;JUMP IF THE ORIGIONAL WORD COUNT IS EXHAUSTED
	SETZ	T3,		;SET T3 SO TEST WILL FAIL IF 22-BIT CHAN AND
	SKIPE	U		; NO ROOM FOR ANOTHER PAGE IN IOWD
	CAML	T1,[EXP -37777+PAGSIZ##]	;OTHERWISE SET T3=CURRENT PAGE

	LDB	T3,P3		;T3 = CURRENT PAGE NUMBER WITHIN SEGMENT
	ILDB	T4,P3		;T4 = NEXT PAGE NUMBER WITHIN SEGMENT
	TRNN	T4,PM.ACC	;ACCESS ALLOWED ON?
	STOPCD	.,JOB,AAO,	;++ACCESS ALLOWED IS OFF
	TRZ	T3,760000	;CLEAR ACCESS BITS
	TRZ	T4,760000	;CLEAR OUT THE ACCESS BITS
	CAIN	T4,1(T3)	;ARE THE TWO PAGES ADJACENT IN PHYSICAL MEMORY?
	JRST	MAPIO3		;YES, CONTINUE ON CURRENT IOWD
	MOVEI	T2,0		;T2 = FIRST ADDRESS
	POP	P,(P1)		;STORE THE IOWD ABSOLUTE ADDRESS
	PUSHJ	P,DXFIX		;ADJUST IOWD IF A DX10
	  JRST	MAPIO8		;NO SPACE
	JUMPL	U,MAPIO7	;GO IF FRAMECOUNT EXHAUSTED

	AOBJN	P1,MAPIO2	;CONTINUE IF THERE IS ROOM IN THE FOUR WORD BLOCK
	PUSHJ	P,GETMOR	;GET ANOTHER FOUR WORD BLOCK
	  JRST	MAPIO8		;WHOOPS! NONE AVAILABLE
	MOVEI	T2,0		;START AT WORD NUMBER ZERO ON THIS PAGE
	JRST	MAPIO2		;MAP THE REST OF THE IOWD
MAPIO4:	POP	P,(P1)		;STORE THE IOWD ABSOLUTE ADDRESS
	ADD	P4,T1		;ADD THE RESIDUAL WORD COUNT TO THE ACCUMULATED
				; WORD COUNT
	MOVE	T1,P4		;PUT WD CNT INTO T1
	PUSHJ	P,DXFIX		;PERFORM FIXUPS FOR DX10
	  JRST	MAPIO8		;OUT OF SPACE

	JRST	MAPIO7		;AND GIVE THE WIN RETURN
MAPIO6:
	MOVEM	T2,0(P1)	;STORE ADDRESS
	HLRE	T1,P4		;GET WORD COUNT
	PUSHJ	P,DXFIX		;FIDDLE WITH DX10 IOWDS
	  JRST	MAPIO8		;NO ROOM

				; THE ALREADY ABSOLUTE IOWD AND RETURN
				;AND FALL INTO MAPIO7
				;MAPIO6 FALLS INTO HERE
MAPIO7:	AOBJN	P1,.+1		;BUMP THE POINTER TO THE NEXT FREE WORD
	SETZM	(P1)		;ZERO IT SO THE LIST IS TERMINATED
	AOS	-7(P)		;SET FOR SKIP (WIN) RETURN
MAPIO8:
	SKIPGE	-3(P)		;IF WE WANT IT STORED,
	TRNE	U,1		;TYPE 0 OR 2 CONTROLLER?
	JRST	MAPIO9		;NO, DON'T DO NEXT
	HRRZS	U		;CLEAR POSSIBLE FRAMECOUNT
	LSH	U,-1
	MOVE	T3,P1		;GET ADDR OF LAST IOWD FOR BYTE PTR'S
	LDB	T1,ADRPT2##(U)	;GET ADDR FIELD FROM LAST IOWD
	HLRO	P4,-1(T3)	;WORD COUNT
	ASH	P4,@ASH22B##(U)	;4 BITS DON'T COUNT IF 22-BIT
	SUB	T1,P4		;DETERMINE ENDING DATA ADDRESS
	DPB	P1,ADRPT4##(U)	;PUT ADDR OF END OF IOWD LIST

	MOVE	P3,-3(P)
	MOVEM	T1,CHNTCW##(P3)
MAPIO9:	POP	P,T4		;RESTORE ACS
	POP	P,T3		; ..
	POP	P,T2		; ..
	POP	P,P3		; ..
	POP	P,P4		; ..
	POP	P,T1		; ..
	PJRST	UPOPJ##		;GIVE WIN OR LOSE RETURN
;SUBROUTINE TO CHECK TO SEE IF THE CURRENT FOUR WORD BLOCK IS EXHAUSTED
; AND IF SO GET ANOTHER ONE IF ANY ARE AVAILABLE.  IF THE NEXT FOUR WORD
; BLOCK IT OBTAINS IS ADJACENT TO THE CURRENT ONE, IT SIMPLY RETURNS.  IF
; IT IS NOT, A LINK WORD LINKING THE CURRENT FOUR WORD BLOCK TO THE
; NEW FOUR WORD BLOCK IS SETUP IN THE FOURTH WORD OF THE CURRENT BLOCK
;CALLING SEQUENCE:
;	MOVE	P1,AOBJN POINTER TO CURRENT BLOCK
;	PUSHJ	P,CHKMOR
;	...	RETURN HERE IF NO MORE FOUR WORD BLOCKS
;	...	RETURN HERE IF CURRENT FOUR WORD BLOCK NOT FILLED OR
;		NEXT FOUR WORD BLOCK OBTAINED 
;P1 = AOBJN POINTER TO CURRENT OR NEW BLOCK

CHKMOR::JUMPL	P1,CPOPJ1##	;CONTINUE IF ANY WORDS LEFT IN THIS BLOCK
GETMOR::PUSHJ	P,GCH4WD	;GET 1 CORE BLOCK
	  POPJ	P,		;NO MORE AVAILABLE
	CAIE	T1,1(P1)	;IS THIS BLOCK ADJACENT TO THE LAST BLOCK?
	JRST	GETMR1		;NO, ADD A LINK
	HRLI	P1,-4		;YES, FOUR WORDS LEFT TO GO (LAST WORD IN
				; THE LAST BLOCK AND THREE WORDS IN NEW BLOCK)
	JRST	CPOPJ1##	;RESTORE T2 AND GIVE OK RETURN
GETMR1:
	TRC	U,3
	TRCN	U,3		;CHECK CHL TYPE
	HRLI	T1,CCHJGO##	;DX10 STYLE CHL JUMP

	MOVEM	T1,0(P1)	;LINK TO THE NEW BLOCK
	MOVE	P1,T1		;P1 = POINTER TO NEW BLOCK
	HRLI	P1,-3		;NUMBER OF WORDS LEFT TO GO IN THE CURRENT BLOCK
	JRST	CPOPJ1##	;AND SKIP RETURN
;ROUTINE USED TO HANDLE 22-BIT CHNLS AND PERFORM IOWD TRANSFORMATIONS
;FOR THE DX10 TAPE CHL. CALLING SEQUENCE:
;	MOVE T1,-WDS TO XFER
;	MOVE P1,ADDRS OF CURRENT IOWD
;	CHARS/WD WAS FOUND IN THE ORIGINAL CALL TO MAPIO
;	PUSHJ P,DXFIX
;	  ...		;RETURN HERE IF NO MORE FREE SPACE
;	  ...		;RETURN HERE IF OK

DXFIX:	HRRZ	T4,U
	CAIE	T4,3		;CHECK CHL TYPE
	JRST	[DPB T1,WDCPNT##(U)
		 JRST CPOPJ1##]	;HANDLE NON-DX10 CHLS
	MOVE	T4,-5(P)	;RESTORE CHAR/WD
	IMULI	T1,0(T4)	;CONVERT TO BYTE COUNT
	AOS	0(P1)		;DX10 LIKES ADDRS RATHER THAN ADDRS-1
	HLRZ	T3,U		;FRAME-COUNT USER SET
	JUMPE	T3,DXFIX0	;NONE
	MOVNS	T3
	CAML	T3,T1		;MORE THAN HE WANTS?
	MOVE	T1,T3		;YES, GET WHAT WAS REQUESTED
	HRLZ	T3,T1		;FRAMECOUNT
	ADDB	T3,U		;UPDATE MAX LEFT
	TLNN	T3,-1		;ANY LEFT?
	HRROS	U		;NO, INDICATE WE'RE DONE
DXFIX0:	CAML	T1,[-17777]	;ROOM FOR THIS
	JRST	DXFIX2		;YES - JUST STORE AND EXIT
	MOVE	T3,MCHTAB(T4)	;MAX CHARS / XFER CMD
	SUB	T1,T3		;SUBTRACT MAX FOR THIS ONE
	DPB	T3,WDCPNT##(U)	;STORE IN IOWD
	PUSH	P,0(P1)		;SAVE PNTR
	AOBJN	P1,DXFIX1	;SEE IF ROOM FOR MORE
	PUSH	P,T1		;NO -SAVE COUNT
	PUSHJ	P,GETMOR	;GET MORE SPACE
	  JRST	DXFIX3		;RAN OUT OF SPACE
	MOVEI	T2,0		;RESTORE T2
	POP	P,T1		;RESTORE COUNT
DXFIX1:	POP	P,T3		;GET LAST POINTER
	MOVE	T4,-5(P)	;RESTORE T4 (CHARS/WD)
	ADD	T3,MWDTAB(T4)	;ADD MAX WORDS OFFSER
	MOVEM	T3,0(P1)	;NEW PARTIAL PNTR
	JRST	DXFIX0		;PROCEED

DXFIX2:	DPB	T1,WDCPNT##(U)	;STORE RESIDUE
	HRL	P2,P1		;LOCATION OF IOWD
	JRST	CPOPJ1##	;SUCCESS RETURN

DXFIX3:	POP	P,T1		;PRUNE PDL
	JRST	TPOPJ##		;PRUNE & EXIT (FAIL)
;THE BYTE PACKING MODES OF THE DX10 WILL ALLOW 4,5 & 6 BYTES / WORD
;THESE TABLES ARE USED TO TRANSLATE THIS INFO INTO 1) THE MAX CHARS
;THAT WILL EXACTLY FILL THE 2) MAX NO. OF WDS PER IOWD
;ALLOWING 2^13-1 BYTES / IOWD.
MCHTAB=.-4
	-<17777/4>*4		;4 BYTE/WD = 8188 BYTES
	-<17777/5>*5		;5 BYTE/WD = 8190 BYTES
	-<17777/6>*6		;6 BYTE/WD = 8190 BYTES

MWDTAB=.-4
	17777/4			;4 BYTE/WD = 2047 WDS
	17777/5			;5 BYTE/WD = 1638 WDS
	17777/6			;6 BYTE/WD = 1365 WDS

;ROUTINE TO RETURN FREE CORE USED FOR MAPPING IOWDS.
;CALLING SEQUENCE:
;	MOVE	T1,ADDRESS OF IOWD LIST
;	PUSHJ	P,RTNIOW
;	ALWAYS RETURN HERE

RTNIOW::PUSHJ	P,SAVE1##	;SAVE P1
	HRRZ	P1,T1		;P1 = ADDRESS OF THE IOWD LIST
RTNIO1:	MOVEI	T1,1		;GIVE BACK ONE FOUR WORD BLOCK
	HRRZ	T2,P1		;ADDRESS OF THE BLOCK
	MOVE	T3,3(P1)	;LAST WORD OF BLOCK
	TLNN	T3,-1		;AN IOWD?
	SKIPA	P1,T3		;NO, THEN THIS IS THE LAST BLOCK
				; OR A LINK TO THE NEXT BLOCK
	ADDI	P1,4		;ADDRESS OF THE NEXT BLOCK
				; (ITS ADJACENT TO THE CURRENT BLOCK)
	PUSHJ	P,RCH4WD	;RETURN BLOCK TO MONITOR FREE CORE
	JUMPE	P1,CPOPJ##	;JUMP IF THIS IS THE LAST BLOCK
	JRST	RTNIO1		;GIVE UP ALL THE BLOCKS


;ROUTINE TO OBTAIN A LOWER-CORE 4-WORD BLOCK
GCH4WD::MOVE	T1,NOIOWD##	;IF WE DON'T HAVE MUCH IOWD SPACE
	CAMGE	T1,NUMKON##	; ONLY GIVE AN IOWD
	JUMPN	P1,CPOPJ##	; FOR THE INITIAL IOWD
	MOVEI	T1,1		;JUST WANT 1 BLOCK
	MOVEI	T2,LOWPTR##	;POINT TO LOWER-CORE FREE-CORE TABLE
	PUSHJ	P,GETBIT##	;GET, SET THE BIT
	  POPJ	P,		;NONE AVAILABLE, LOSE
	SOS	NOIOWD##	;1 LESS IOWD BLOCK
	LSH	T1,2		;CONVERT TO 4-WORD STYLE
	ADD	T1,LOWLOC##	;CONVERT TO ACTUAL ADDRESS
	SETZM	3(T1)		;ZERO THE LAST WORD OF THE CURRENT BLOCK
	PJRST	CPOPJ1##	;AND TAKE GOOD RETURN


;ROUTINE TO RETURN LOWER-CORE 4-WORD BLOCKS
RCH4WD::SUB	T2,LOWLOC##	;CONVERT TO RELATIVE ADDRESS
	LSH	T2,-2		;/4 TO CONVERT TO BITS
	IDIVI	T2,^D36		;COMPUTE WORD ADR, POSITION IN WORD
	HRLS	T2
	ADD	T2,LOWPTR##	;SET AOBJN POINTER FOR SETZRS
	ADDM	T1,NOIOWD##	;1 MORE IOWD BLOCK
	PJRST	SETZRS##	;CLEAR THE BITS AND RETURN
SUBTTL	ERRCON - ERROR HANDLING MODULE

;SUBROUTINE TO SWEEP MEMORY TO FIND ADDRESS AND CONTENTS OF BAD WORDS
;IT CALLS CPU INDEPENDENT SUB.(PARERR) TO RECORD DATA ON EACH BAD WORD
;CALL:	PUSHJ	P,@.CPMPS##
;	ALWAYS RETURN WHEN SWEEP OVER (EVEN IF SERIOUS ERROR)
;SWEEP CORE IN ASCENDING ADDRESSES EVEN THOUGH SLOWER, SO DATA STORED ASCENDING
; FOR ERROR REPORTING WITH DAEMON

CPIMPS::PUSHJ	P,MAPLOC##	;GET EXEC MAP SLOT
	MOVE	W,T1		;SAVE BYTE POINTER TO EXEC MAP SLOT
	MOVEI	P3,PM.ACC+PM.WRT;START AT PAGE 0, ACCESSIBLE AND WRITEABLE
	LDB	T4,[POINT 14,MEMSIZ##,26] ;T4=NUMBER OF PAGES TO SCAN
	SKIPA	P4,[POINT 1,NXMTAB##] ;BYTE POINTER TO NXM TABLE
MPSLP1:	AOS	P3		;STEP TO NEXT PAGE
	SOJL	T4,MPSLP5	;RESTORE T1 AND RETURN IF SCANNED ALL OF MEMORY
	ILDB	T1,P4		;DOES THIS PAGE EXIST?
	JUMPN	T1,MPSLP1	;IF NOT, GO BACK FOR NEXT
	DPB	P3,W		;MAP THE CURRENT PAGE
	MOVE	P1,T3		;EVA FOR BEGINNING OF PAGE
	CLRPGT	(0)		;CLEAR ASSOCIATIVE MEMORY FOR NEW MAPPING
	MOVEI	T2,PAGSIZ##	;NO. OF WORDS/PAGE TO SCAN
	SETOM	.CPPSP##	;SET SWEEPING FLAG
MPSL1A:	MOVEI	T1,5		;NO. OF SOJG'S TO WAIT FOR INTERRUPT TO HAPPEN
	MOVE	P2,(P1)		;TEST NEXT LOCATION
CPIMPI::SOJG	T1,.		;DELAY HERE SO INTERRUPT PC POINTS HERE
MPSLP2:	SOJLE	T2,MPSLP1	;IF CURRENT PAGE DONE, MAP NEXT
	AOJA	P1,MPSL1A	;GO TEST NEXT WORD IN PAGE

;HERE ON BAD WORD FOUND (NXM OR PARITY) - INTERRUPT HAPPENED AND ADDED 3 TO PC
	MAP	T1,(P1)		;GET THE PHYSICAL PAGE THAT BAD WORD IS IN
	PUSH	P,P1		;SAVE THE EVA
	PUSH	P,T2		;SAVE THE WORD NUMBER IN CURRENT PAGE
	PUSH	P,T3		;SAVE THE POSITION IN THE MAP
	PUSH	P,T4		;SAVE # OF PAGES TO SCAN
	DPB	T1,[POINT 13,P1,26] ;FORM PHYS. ADDRESS OF BAD WORD
	PUSHJ	P,CPIASN##	;CONVERT TO SEG NUMBER IN J
	  TDZA	T1,T1		;INDICATE NO ERROR IN MONITOR OR A JOB
	SETO	T1,		;INDICATE AN ERROR IN MONITOR OR A JOB
	MOVE	P2,.CPTBD##	;GET BAD DATA WORD STORED BY THE TRAP ROUTINE
	PUSHJ	P,PARRBD##	;RECORD BAD DATA
	POP	P,T4		;RESTORE T4
	POP	P,T3		; AND T3
	POP	P,T2		; AND T2
	POP	P,P1		; AND P1
	JRST	MPSLP2		;GO CONTINUE THE SWEEP

MPSLP5:	SETZM	.CPPSP##	;CLEAR SWEEPING FLAG
	PUSHJ	P,UNMAP##	;RESTORE EXEC MAP SLOT
	POPJ	P,		;AND RETURN

	$LIT
KIEND:	END