Google
 

Trailing-Edge - PDP-10 Archives - bb-jr93j-bb - 7,6/ap023/rttrp.x23
There is 1 other file named rttrp.x23 in the archive. Click here to see a list.
TITLE	RTTRP - REAL TIME TRAPPING ROUTINES - V151
SUBTTL P. HURLEY/PFC/JE/TS/JAD  28-FEB-89

	SEARCH	F,S
	$RELOC
	$HIGH


;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED
;  OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION
; 1973,1974,1975,1976,1977,1978,1979,1980,1982,1984,1986,1988.
;ALL RIGHTS RESERVED.

.CPYRT<1973,1988>


XP VRTTRP,151

		; PETER M HURLEY   MAY 13, 1970

		;RTTRP IS A COMPLETELY REENTRANT UUO CALLABLE
		;FROM ALL PI LEVELS TO CHAIN AND UNCHAIN DEVICES
		;ONTO THE MONITOR DEVICE CHAINS.
		;IT ALSO PROVIDES THE CAPABILITY OF ALLOWING AN
		;INTERRUPT FROM ANY DEVICE TO TRANSFER PROGRAM
		;CONTROL TO A USER PROGRAM AT INTERRUPT LEVEL
		;IN RESPONSE TO THAT INTERRUPT.
		;RTTRP TAKES CARE OF ALL CONTEXT SWITCHING WHICH
		;IS NECESSARY AND CHANGING THE  RELOCATION AND
		;PROTECTION REGISTER,  THUS PERMITTING MORE THAN
		;ONE JOB AT A TIME TO BE CONTROLING DEVICES ON THE
		;INTERRUPT LEVELS WITHOUT STOPPING TIME SHARING.

	ENTRY	RTTRP
; RIGHT HALF OF S - ERROR BIT DEFINITIONS

	E35==1B35	;PI CHANNEL NOT AVAILABLE, USED BY MONITOR FOR BLKI/O
	E34==1B34	;PI CHANNEL NOT CURRENTLY AVAILABLE FOR BLKI/O
	E33==1B33	;TRAP ADDRESS OUT OF BOUNDS
	E32==1B32	;ERROR ADDRESS OUT OF BOUNDS
	E31==1B31	;BLKADR OR POINTER WORD OUT OF BOUNDS
	E30==1B30	;SYNTAX ERROR IN FORMAT, NO CONSO OR BLKI/O INSTRUCTION
	E29==1B29	;NO MORE RT BLOCKS LEFT
	E28==1B28	;JOB NOT LOCKED IN CORE
	E27==1B27	;ILLEGAL AC USED AT INTERRUPT LEVEL CALL
	E26==1B26	;DEVICE ALREADY IN USE BY ANOTHER JOB
	E25==1B25	;JOB SET TO RUN ON CPU1 ONLY - TEMPORARILY NOT SUPPORTED
	E24==1B24	;JOB DOES NOT HAVE PRIVILEGES
	E23==1B23	;NON-EXISTANT CPU SPECIFIED
;LEFT HALF OF S BIT DEFINITIONS

	INDBIT==1	;INDIRECT BIT SET IN CONSO INSTRUCTION
	CNSO==2		;CONSO INSTRUCTION
	RTINT==4	;UUO ENTERED FROM INTERRUPT LEVEL
	BLKIO==10	;BLKI/O TO GO ON CHANNEL
	NOREM==20	;DO NOT REMOVE DEVICES FROM CHAINS BEFORE LINKING
			; ANOTHER DEVICE ONTO THE CHAIN
	NOSAV==40	;EXEC MODE TRAPPING, DON'T DO CONTEXT SWITCH
	VECTOR==100	;DEVICE INTERRUPTS BY EXECUTING AN INTERRUPT VECTOR
	EPTREL==200	;INTERRUPT INSTRUCTION IS TO BE STORED RELATIVE TO THE EPT

;.CPRCT LEFT HALF BIT DEFINITIONS

	BLKENB==1	;BLKI/O INSTRUCTIONS ALLOWED ON THIS CHANNEL
	BINUSE==2	;BLKI/O INSTRUCTION IN USE PRESENTLY ON THIS CHANNEL
	BLKSAV==4	;BLKI/O INSTRUCTION BEING REPLACED BY ANOTHER BLKI/O
	BLKAVL==400000	;CHANNEL CAN CURRENTLY BE USED FOR BLKI/O
			;*** MUST BE SIGN BIT

REPEAT 0,<
;AC DEFINITIONS - *** CHANGED TO STANDARD ON JUNE 1, 1971

	IWD=U		;BLKI/O IOWD
	BLK=F		;BLKI/O INSTRUCTION
	RTB=T4		;RT BLOCK BASE ADDRESS
	PIAC=P1		;PI CHANNEL NUMBER
	TRP=P2		;TRAP ADDRESS
	INS=W		;CONSO INSTRUCTION
	ENB=M		;ENABLE BITS

	RTUUO=17	;THESE TWO AC'S CANNOT BE USED IN CALLS FROM INTERRUPT LEVEL
	RTUUO1=16	;RTUUO CONTAINS USER PC, AND RTUUO1 IS A SCRATCH
>


;OTHER DEFINITIONS

	RTUUON==57	;UUO CALLI NUMBER
	RTUSE==1000	;REAL TIME BLOCK IS BEING USED
	VECUSE==2000	;RTBLK IN USE BY A VECTOR INTERRUPT DEVICE
			; NOT ON THE CONSO CHAIN
	WAKUUO==73	;WAKE UUO CALLI NUMBER
	JSRMOD==1	;DO JSR TO TRPADR WITH NO CONTEXT SWITCH
	VTRMOD==2	;IF DEVICE DOES VECTORED INTERRUPTS
	EPTMOD==4	;IF THE INTERRUPT JSR INSTRUCTION IS TO BE STORED RELATIVE
			; TO THE EPT
;REAL TIME BLOCK DEFINITIONS AND FORMAT

	$PHASE	(0)	;OFFSETS IN REAL TIME BLOCK

	BLOCK	3	;FOR XPCW
RTCNSO:!BLOCK	1	;CONSO DEV,BITS		;CHAIN INSTRUCTION
RTJRST:!BLOCK	1	;JRST NXTDEV		;CONTINUE ON IN CHAIN
RTBLKO:!BLOCK	1	;BLKO DEV,POINTR	;IF NO BLKI/O THEN JRST .+3
RJRST1:!BLOCK	1	;JRST .+2		;BLKI/O COUNTED OUT
RTJEN:!	BLOCK	1	;JEN @CHN		;DISMISS INTERRUPT
RTJSR:!	BLOCK	1	;JSR SAV'PI		;SAVE THE AC'S
RTJSP:!	BLOCK	1	;JSP J,TRPGO		;SAVE THE STATE OF THE MACHINE
TABST:!
ENBTAB:!BLOCK	1	;APR CONO BITS
RELTAB:!BLOCK	1	;RELOCATION-PROTECTION TABLE
UENBTB:!BLOCK	1	;USER APR INTERRUPT ENABLE BITS
TRPTAB:!BLOCK	1	;USER TRAP ADDRESS
JADRTB:!BLOCK	1	;JBTADR VALUE FOR THIS JOB
APRTAB:!BLOCK	1	;XWD R, APRTRP
JOBTB:!	BLOCK	1	;XWD DEV CODE, JOB #
PITAB:!	BLOCK	1	;XWD 0,PI CHANNEL
DISMTB:!BLOCK	1	;JRST CHAND'PI
RTBSIZ::!		;REAL TIME BLOCK SIZE

	$DEPHASE

	ENBTB1==:ENBTAB-TABST
	RELTB1==:RELTAB-TABST
	UENBT1==:UENBTB-TABST
	TRPTB1==:TRPTAB-TABST
	JADRT1==:JADRTB-TABST
	APRTB1==:APRTAB-TABST
	JOBTB1==:JOBTB-TABST
	PITB1==:PITAB-TABST
	DISMT1==:DISMTB-TABST

IFN ENBTB1,<PRINTX ENBTAB MUST BE THE FIRST ENTRY IN TABLE>

	MRELTB==:-RELTAB
;DESCRIPTION OF TABLES USED BY RTTRP

	;JBTRDT = COUNT OF REAL TIME DEVICES ON INTERRUPT SYSTEM FOR EACH JOB
		;JBTRTD IS INDEXED BY JOB NUMBER

	;.CPRCU = COUNT OF REAL TIME DEVICES ON EACH PI CHANNEL
		;.CPRCU IS INDEXED BY PI NUMBER MINUS 1

	;.CPRCT = XWD STATUS,CH'PI
		;STATUS DESCRIBES STATE OF CHANNEL  IE BEING USED BY BLKI INSTRUCTION
		;CH'PI IS THE ADDRESS OF THE CHANNEL ROUTINE FOR THAT LEVEL
		;.CPRCT IS INDEXED BY PI NUMBER MINUS 1

	;.CPRDT = XWD JSRADR,DISMIS ADR
		;JSR ADR = ADDRESS OF CHANNEL ROUTINE TO SAVE THE AC'S
		;DISMIS ADR IS THE ADDRESS OF CHANNEL DISMISS ROUTINE
		;.CPRDT IS INDEXED BY PI NUMBER MINUS 1

	;.CPRIT = C(CH'PI+1)
		;THIS IS USED TO RESTORE THE PI CHAINS TO ORIGINAL
		;STATE DURING A 140 OR A 143 RESTART
		;.CPRIT IS INDEXED BY PI NUMBER MINUS 1
	;RTTRP IS THE ENTRY POINT FROM UUOCON DURING A CALL
	;FROM A USER ON LEVEL 8 (I.E. NORMAL TIME SHARING).

	;RTTRP1 IS THE ENTRY POINT FROM A UUO GIVEN FROM
	;A PROGRAM RUNNING AT PRIORITY INTERRUPT LEVEL

	;J = JOB #
	;R = JBTADR(J)
	;T1  = CONTENTS OF UUO AC
	;RTUUO= RETURN ADDRESS IF ENTERED FROM INTERRUPT LEVEL

RTTRP::	PUSHJ	P,SAVE3##	;SAVE P1-P3
	PUSH	P,M		;SAVE THE UUO AC
	SETZ	S,		;INITIALIZE FLAG REGISTER
	MOVE	T2,JBTPRV##(J)	;GET USER PRIVILEGE BITS
	TLNN	T2,PVRTT	;DOES THE USER HAVE THE PROPER PRIVILEGES
	TRO	S,E24		;NO, SET THE ERROR BIT
IFN FTLOCK,<			;LOCK UUO FEATURE?
	PUSHJ	P,LOKCHK##	;JOB LOCKED IN CORE?
	  SKIPA			;YES, OK FOR THE MOMENT (CHECK EVM LATER)
>
	  TRO	S,E28		;NO, SET ERROR BIT
	PUSHJ	P,GETTAC##	;SET UP T1 AGAIN
;HERE AT INTERRUPT LEVEL TO DO RTTRP UUO
RTTRP1:	HRRZS	P2,T1		;ADDRESS OF ARG LIST & ZERO IDX & INDIRECT BITS
	MOVS	U,R		;GET LENGTH OF USER LOW SEGMENT
	CAILE	P2,JOBPFI##	;IS ADR ABOVE PROTECTED AREA
	CAILE	P2,(U)		;YES, IS ADR BELOW TOP OF USER AREA
	JRST	[CAIL P2,(P1)	;VALID AC?
		 JRST ERR30	;NO
		 JRST .+1]	;YES
	EXCTUX	<HLRE	P1,@T1>	;PICK UP PI CHANNEL #
	LDB	W,[POINT 3,P1,26];CPU NUMBER
	JUMPGE	P1,[TLO W,(1B0) ;IS THIS A REGULAR RTTRP CALL
		    JRST RTTRP2]
	TRNN	P1,(17B5)	;NEGATIVE PI LEVEL (OLD-STYLE CALL)?
	TRZA	P1,(577B8)	;NO, CLEAR CPU NUMBER FIELD/SIGN BIT AND SKIP
	TLOA	W,(1B0)		;REMEMBER THIS IS AN OLD-STYLE CALL AND SKIP
	TRZE	P1,(1B1)	;"NO REMOVE" FLAG OR -VE PI LEVEL?
	TLO	S,NOREM		;NOTE THAT NO DEVICES ARE TO BE REMOVED
	TRNE	P1,(17B5)	;NEGATIVE PI LEVEL?
	MOVMS	P1		;NO, GET POSITIVE PI LEVEL
	HRRZS	P1
	TLNE	S,NOREM
	JUMPE	P1,ERR30
RTTRP2:	CAIG	W,M.CPU##-1	;LEGAL CPU OR OLD STYLE CALL?
	JRST	RTTRP3		;YES
	TRO	S,E23		;NO, INDICATE NON-EXISTANT CPU
	JRST	ERROR		;AND DON'T TRY TO RESCHEDULE ONTO THAT CPU
RTTRP3:
IFN FTMP,<
	PUSH	P,T1		;SAVE ADDRESS OF ARG BLOCK
	JUMPGE	W,RTTR3A	;OK IF CPU SPECIFIED
	PUSHJ	P,CHKCPU##	;FOR OLD CALLS, USE ONLY 1 CPU
	  TRO	S,E25		;NOT "ONLY" ON A CPU
	MOVE	W,T1		;REMEMBER CPU WE ARE LOCKED ON
RTTR3A:	MOVE	T1,W		;CPU NUMBER WHERE DEVICE IS
	TLNN	S,RTINT		;AT INTERRUPT LEVEL?
	PUSHJ	P,ONCPUN##	;NO, GET ON THE PROPER CPU
	POP	P,T1		;RESTORE ARG POINTER
	CAMN	W,.CPCPN##	;ON THE PROPER CPU?
	JRST	RTTRP4		;YES
	TRO	S,E25		;NO, INDICATE ERROR IN CPU SPEC
	JRST	ERROR		;AND DON'T CONTINUE
RTTRP4:
>
	JUMPE	P1,REMOVE	;IF NO PI CHANNEL THEN REMOVE DEVICE
	CAIGE	P1,7		;IS PI OUT OF BOUNDS
	SKIPN	.CPRCT##-1(P1)	;IS CHANNEL LEGAL FOR RTTRP USE
	TRO	S,E35		;NO, SET ERROR BIT
	EXCTUX	<HRRZ	P2,@T1>	;GET TRAP ADDRESS
	CAILE	P2,JOBPFI##	;IS THIS ABOVE THE PROTECTED AREA?
	CAILE	P2,(U)		;IS THIS LESS THAN TOP OF CORE AREA?
	TRO	S,E33		;NO, SET PROPER ERROR BIT
	HRRI	T1,1(T1)	;MAKE T1 POINT TO NEXT ARGUMENT
	EXCTUX	<HRRZ	M,@T1>	;GET APR TRAP ADDRESS
	CAILE	M,JOBPFI##	;IS IT ABOVE PROTECTED AREA
	CAILE	M,(U)		;AND BELOW TOP OF CORE AREA?
	TRO	S,E32		;NO, SET ERROR BIT
	EXCTUX	<HLL	M,@T1>	;GET LEFT HALF OF SECOND WORD
	TLNE	M,JSRMOD	;IS THIS AN EXEC MODE TRAPPING REQUEST
	TLO	S,NOSAV		;YES, REMEMBER IT
	TLNE	M,VTRMOD	;WAS VECTORED INTERRUPT MODE SPECIFIED?
	TLO	S,VECTOR	;YES, REMEMBER THAT
	TLNE	M,EPTMOD	;INTERRUPT INSTRUCTION TO BE STORED RELATIVE TO THEE EPT?
	TLO	S,EPTREL	;YES, REMEMBER THAT
	HRRI	T1,1(T1)	;T1 NOW POINTS TO THIRD ARGUMENT
	EXCTUX	<HLRZ	T2,@T1>	;PICK UP INTERRUPT INSTRUCTION
	TRZ	T2,77400	;ZERO OUT DEVICE CODE
	TRZE	T2,17		;INDEX FIELD SHOULD ALSO BE ZERO
	TRO	S,E30		;IT ISN'T, SET ERROR BIT
	TRZE	T2,20		;IS THE INDIRECT BIT ON
	TLO	S,INDBIT	;YES, NOTE THAT FACT
	CAIE	T2,(CONSO)	;IS THIS A CONSO INSTRUCTION?
	JRST	BLKINS		;NO, TRY FOR BLKI/O INSTRUCTION
				;FALL THROUGH TO NEXT PAGE
	TLO	S,CNSO		;MARK THAT THIS IS A CONSO INSTRUCTION
	TLNN	S,INDBIT	;IS THIS AN INDIRECTION CALL
	JRST	RTTRP5		;NO
	EXCTUX	<HRRZ	T2,@T1>	;YES, PICK UP INSTRUCTION
	CAILE	T2,JOBPFI##	;CHECK IF IT IS IN BOUNDS
	CAILE	T2,(U)		;ABOVE LOWER LIMIT AND BELOW UPPER LIMIT?
	TRO	S,E30		;NO, SET ERROR BIT
RTTRP5:	EXCTUX	<MOVE	P3,@T1>	;PICK UP INSTRUCTION AGAIN
	TLNE	S,INDBIT	;IS THE INDIRECT BIT SET
	ADDI	P3,(R)		;YES, RELOCATE ONCE
	HRRI	T1,1(T1)	;MAKE T1 POINT TO NEXT ARGUMENT
	EXCTUX	<HLRZ	T2,@T1>	;GET INSTRUCTION PART OF ARG
	JUMPE	T2,BLKRET	;IF IT IS ZERO THEN FORGET IT
	TRZ	T2,77400	;ZERO OUT DEVICE CODE
	TRZE	T2,37		;INDEX OR INDIRECT BITS ON
	TRO	S,E30		;YES, ERROR
	JRST	BLKRET		;ONWARD
	;BLKI/O INSTRUCTION, CHECK BOUNDRY CONDITIONS

BLKINS:	TRZ	T2,100		;COMMON BIT TO BLKI AND BLKO
	TLNN	S,INDBIT	;INDIRECT BIT SET
	CAIE	T2,(BLKI)	;BLKI OR BLKO
	JRST	VECINS		;NO, MAYBE VECTORED INTERRUPT
	EXCTUX	<HRRZ	T2,@T1>	;GET BLKADR
	CAILE	T2,JOBPFI##	;CHECK BOUNDRY CONDITIONS
	CAILE	T2,(U)		;ABOVE LOWER BOUND AND BELOW UPPER BOUND?
	JRST	ERR31		;NO, GO SET ERROR BIT
	EXCTUX	<MOVE	T3,@T2>	;PICK UP BLOCK ADDRESS AND WORD COUNT
	HLRO	T4,T3		;GET NEGATIVE WORD COUNT
	MOVNS	T4		;MAKE IT POSITIVE
	ADDI	T4,(T3)		;CALCULATE END OF BLOCK
	CAILE	T4,JOBPFI##	;CHECK BOUNDS
	CAILE	T4,(U)		;UPPER AND LOWER BOUNDS OK?
	JRST	ERR31		;NO, GO SET ERROR BIT
	MOVEI	T4,1(T3)	;GET START OF BLOCK
	CAILE	T4,JOBPFI##	;IS IT IN BOUNDS
	CAILE	T4,(U)		;UPPER AND LOWER BOUNDS OK?
	JRST	ERR31		;NO,GO SET ERROR BIT
	EXCTUX	<MOVE	F,@T1>	;SAVE BLKI/O INSTRUCTION FOR LATER
	ADDI	F,(R)		;RELOCATE BLKI/O INSTRUCTION
	EXCTUX	<HRRZ	T2,@T1>	;GET ADDRESS OF WORD COUNT, START ADR
	ADDI	T2,(R)		;RELOCATE IT
	MOVE	U,(T2)		;LOAD U WITH THE IOWD FOR BLKI/O
	ADDI	U,(R)		;RELOCATE IT
	MOVEM	U,(T2)		;SET UP RELOCATED IOWD IN USER AREA
	TLO	S,BLKIO		;NOTE THAT A BLKI/O IS TO BE DONE
	JRST	BLKRET		;GO GET RT BLOCK

ERR31:	TROA	S,E31		;SET ERROR BIT 31
ERR30:	TRO	S,E30		;SET ERROR BIT 30
	JRST	ERROR		; GO RETURN TO USER

VECINS:	TLNN	S,INDBIT	;INDIRECT BIT SPECIFIED?
	TLNN	S,VECTOR	;AND WAS VECTOR TYPE INTERRUPT REQUESTED?
	JRST	ERR30		;ERROR
	EXCTUX	<MOVE	F,@T1>	;EXEC VIRTUAL ADDRESS OF THE INTERRUPT VECTOR
	TLNN	S,EPTREL	;IS ADDRESS RELATIVE TO THE EPT?
	JRST	BLKRET		;NO, USER SPECIFIED THE EVA OF IRP VECTOR
	TRNE	F,-PAGSIZ	;MUST BE LESS THAN PAGSIZ
	JRST	ERR31		;NOT, THE EPT IS ONLY A PAGE LONG
	ADD	F,.CPEPT##	;RELOCATE BY ADDRESS OF THE EPT
;FALL INTO BLKRET
	;ARRIVE HERE AFTER PROCESSING ARGUMENT LIST.
	;IF THERE ARE ANY ERRORS SO FAR, DON'T GO ON.
	;AT THIS POINT THERE ARE FOUR AC'S SET UP:
	;F=INTERRUPT INSTRUCTION(CONSO OR BLKI/O),
	;M=APR INFO (XWD ENABLE,APRTRP),
	;P1=PI CHANNEL NUMBER, AND P2=TRAP ADDRESS

BLKRET:	TLNN	S,INDBIT!NOSAV	;INDIRECT OR FAST MODE?
	JRST	BLKRT1		;NO, NO NEED TO TEST FOR EVM
IFN FTLOCK,<
	PUSHJ	P,LOKEVC##	;IF NON-PXCT REF TO USER, MUST BE LOCKED IN EVM
>; END IFN FTLOCK
	  TRO	S,E28		;GIVE ERROR
BLKRT1:	TLZ	S,INDBIT	;THIS CAN BE CLEARED NOW
	TRNE	S,-1		;ANY ERRORS YET?
	JRST	ERROR		;YES, DONT GO ANY FURTHER

	;AT THIS POINT THE ARGUMENT LIST HAS BEEN VERIFIED, NOW
	;TRY TO OBTAIN A FREE REAL TIME BLOCK.

	SYSPIF			;LOCK OUT HIGHER PRIORITY INTERRUPTS
	SKIPE	T4,RTLINK	;IS THE FREE LIST EMPTY?
	MOVE	T4,@RTLINK	;NO, GET FIRST FREE BLOCK
	EXCH	T4,RTLINK	;STORE NEW POINTER IN RTLINK
	SYSPIN
	JUMPE	T4,NORTBL	;ANY BLOCKS?
				;FALL THROUGH TO NEXT SECTION

	;THE RT BLOCK HAS BEEN OBTAINED.
	;NOW AN INTERRLOCK IS SET ( JOBTB(RTBLK) = XWD  DEV-CODE,0)
	;TO PREVENT THE SAME DEVICE FROM BEING PUT ON OR TAKEN OFF
	;OTHER CHANNELS DURING THE TIME IT TAKES TO COMPLETE THE
	;CHAINING OF THIS RT BLOCK.

	TLNN	S,CNSO		;IS THERE A CONSO INSTRUCTION
	MOVE	P3,F		;NO, SET P3 UP PROPERLY
	LDB	T3,[POINT 7,P3,9] ; GET DEV CODE
	IORI	T3,RTUSE	; MARK THAT RTBLOCK IS BEING USED
	HRLZM	T3,JOBTB(T4)	;STORE DEV CODE IN RT BLOCK FOR INTERLOCK
IFN FTMP,<
	DPB	W,[POINT 3,JOBTB(T4),2] ;STORE CPU NUMBER
>
	MOVE	T2,[XWD -M.RTD##,RTBLK##] ;SET UP COUNTER AC

	;CHKDEV MAKES SURE THAT THERE ARE NO OTHER OCCURENCES OF THIS DEVICE
	;ON ANY OTHER CHANNELS EXCEPT WHEN OWNED BY THIS JOB

CHKDEV:	LDB	T1,[POINT 10,JOBTB(T2),17] ;DEVICE CODE + USE BIT
	CAMN	T1,T3		;IS THIS THE SAME AS CURRENT DEVICE
	JRST	CHKDV2		;YES, GO SEE IF LEGAL
CHKDV1:	HRRI	T2,RTBSIZ-1(T2)	;LOOK AT NEXT BLOCK
	AOBJN	T2,CHKDEV	;LOOP BACK FOR REST OF CHECKS
	TLNE	S,VECTOR	;VECTOR INTERRUPT DEVICE?
	JRST	CHKDV4		;YES
	TLNN	S,CNSO		;CONSO INSTRUCTION?
	JRST	NOCNSO		;NO, GO SET UP BLKI/O INSTRUCTION
CHKDV4:	SYSPIF			;POSSIBLE RACE CONDITIONS HERE
	SKIPG	T1,.CPRCT##-1(P1) ;ENABLED FOR BLKI/O
	TLZA	T1,BLKAVL	;YES, CLEAR BLKI/O BIT
	TLNN	T1,BINUSE	;IS THERE A BLKI/O OPERATION IN USE
	AOSA	.CPRCU##-1(P1)	;NO, COUNT UP CONSO IN USE TABLE
	JRST	ERR35		;CHANNEL BEING USED, GIVE BACK RT F
	MOVEM	T1,.CPRCT##-1(P1);RESTORE NEW CHANNEL STATUS WORD
	SYSPIN			;TURN PI SYSTEM BACK ON
				;FALL THROUGH TO LOADRB
	;THE RT BLOCK HAS BEEN OBTAINED, AND THE CHANNEL HAS BEEN SECURED
	;NOW THE RT BLOCK CAN BE SET UP
	;T4 CONTAINS THE START ADDRESS OF THE RT BLOCK
	;P1 CONTAINS PI#

LOADRB:	TLZ	M,-1
	MOVEM	M,APRTAB(T4)	;STORE IN APRTRP TABLE
	MOVEM	R,JADRTB(T4)	;STORE JBTADR VALUE IN TABLE
	MOVEM	P1,PITAB(T4)	;SAVE PI NUMBER
	SKIPN	T1,.CPRTT##	;ARE WE AT INTERRUPT LEVEL
	SKIPA	T2,.CPCN1##	;NO, GET USER ENABLE BITS
	SKIPA	T2,UENBT1(T1)	;YES, GET USER ENABLE BITS FROM T4
	SKIPA	T1,.CPHRP##	;NO, USE KT10A VALUE
	MOVE	T1,RELTB1(T1)	;YES, USE CURRENT INTERRUPT LEVEL VALUE
	MOVEM	T1,RELTAB(T4)	;STORE FOR INTERRUPT LEVEL USE
IFN FTKL10,<TRO T2,LP.NXM!LP.IOF>;KL10 BITS FOR NXM AND PAGE FAIL
IFN FTKS10,<TRO T2,SP.NXM>	;KS10 BITS FOR NXM
	HRRZM	T2,UENBTB(T4)	;STORE FOR LATER USE
	MOVSI	T1,(JRST)	;SET UP JRST CHAND'PI
	HRR	T1,.CPRDT##-1(P1) ;FOR INTERRUPT LEVEL USE
	MOVEM	T1,DISMTB(T4)	;STORE IT IN TABLE
	HLRZ	T1,.CPRDT##-1(P1) ;GET JSR ADDRESS
	HRLI	T1,(JSR)	;SET UP INSTRUCTION PART
	MOVEM	T1,RTJSR(T4)	;STORE IN RTBLK
	MOVE	T1,[JSP J,TRPGO##]
	MOVEM	T1,RTJSP(T4)	;SET UP JSP INSTRUCTION IN RT BLOCK
	HRLI	P2,(XC.USR!XC.UIO) ;TURN ON USER MODE AND USER I/O MODE BITS
	MOVEM	P2,TRPTAB(T4)	;STORE TRAP ADDRESS
	HRRZ	T1,.CPRCT##-1(P1) ;GET CHANNEL ADDRESS
	ADDI	T1,4		;T1 = CHANX+4
	HRLI	T4,(JRST)	;SET UP JRST T4
	LDB	T2,[POINT 7,P3,9] ;GET DEVICE CODE
	TLNN	S,NOREM		;SHOULD WE REMOVE ANY DEVICES?
	PUSHJ	P,REMDEV	;GO REMOVE ALL DEVICES WITH THIS CODE FOR THIS JOB
	AOS	JBTRTD##(J)	;COUNT UP REAL TIME DEVICE COUNT
	MOVSI	T3,(JSR)	;SET UP JSR TO TRPADR
	HRR	T3,TRPTAB(T4)	;GET USER TRAP ADDRESS
	ADDI	T3,(R)		;RELOCATE IT
	TLNE	S,VECTOR	;VECTORED MODE TRAPPING?
	JRST	VECST1		;YES, SETUP RTBLK FOR THAT STYLE OF RTTRP
	MOVEM	T3,RJRST1(T4)	;STORE IT IN RT BLOCK
	MOVSI	T3,(XJEN)	;SET UP XJEN CHN
	HRR	T3,.CPRCT##-1(P1) ;GET CHANNEL RETURN ADDRESS
	MOVEM	T3,RTJEN(T4)	;STORE IN JEN ADDRESS
	TLNN	S,CNSO		;CONSO OR BLKI/O
	JRST	BLKSET		;BLKI/O, GO SET UP PI LOCATIONS
	MOVEM	P3,RTCNSO(T4)	;STORE THE CONSO INSTRUCTION
	MOVSI	T2,(JRST)	;SET UP JRST INSTRUCTION
	HRRI	T2,RTJSR(T4)	;GET ADDRESS OF JSR SAVCHN
	TLNE	S,NOSAV		;EXEC MODE TRAPPING
	HRRI	T2,RJRST1(T4)	;YES, GET ADR OF JSR TRPADR
	MOVEM	T2,RTBLKO(T4)	;STORE IT IN RT BLOCK
	TLNE	S,BLKIO		;IS THERE A BLKI/O TO GO ON
	JRST	BLKST1		;YES, GO DO IT
RTRET1:	SYSPIF			;PI MUST BE OFF NOW
	MOVE	T2,(T1)		;PICK UP FIRST JRST OF CHAIN
	MOVEM	T4,(T1)		;CHANGE IT TO JRST RTBLK
	MOVEM	T2,RTJRST(T4)	;SET UP JRST NXTDEV INSTRUCTION
	MOVEI	T2,3		;OFFSET
	ADDM	T2,(T1)		;SKIP SPACE RESURVED FOR XPCW

RTRET2:	HRRM	J,JOBTB(T4)	;COMPLETE RT BLOCK SET UP
	PUSHJ	P,ONIFO		;INTERLOCK REMOVED
RTRET:	TLNE	S,RTINT		;ARE WE AT INTERRUPT LEVEL
	AOSA	P4		;YES, ADD ONE TO RETURN
	AOSA	-1(P)		;NO, ADD ONE TO RETURN
	JRSTF	@P4		;RETURN
	MOVSI	T2,(XC.UIO)	;SET USER I/O BIT
	IORM	T2,.JDAT+JOBPD1## ;IN USER RETURN ADDRESS
	MOVEI	T1,.SWERT	;EVENT CODE (RTTRP)
	HLRZ	T2,JOBTB(T4)	;EVENT-SPECIFIC DATA WORD
	HRR	T2,PITAB(T4)	; (CPU & DEVICE CODE,,PI CHANNEL)
	PUSHJ	P,SWESEB##	;LOG EVENT
	SETZ 	F,		;AVOID IME
	JRST	MPOPJ##		;RESTORE M AND RETURN
;ODD PEICES AND ROUTINES

NOCNSO:	SYSPIF			;ROUTINE TO MARK A BLKI/O IN PROGRESS
	SKIPL	T1,.CPRCT##-1(P1);ARE BLKI/O INSTRUCTIONS ALLOWED
	JRST	NCNSO1		;NO, SEE IF ONLY RESETTING BLKI/O POINTR
	TLC	T1,BLKAVL!BINUSE ;MARK THAT BLKI/O IS IN USE
	MOVEM	T1,.CPRCT##-1(P1);STORE NEW CHANNEL STATUS WORD
	SYSPIN
	JRST	LOADRB		;GO SET UP RT BLOCK

NCNSO1:	TLNN	T1,BINUSE	;IS THERE ALREADY A BLOCK IN OR OUT GOING
	JRST	ERR34		;NO, THEN THIS IS AN ERROR
	TLO	T1,BLKSAV	;YES, THEN WE ARE ONLY CHANGING POINTER'S
	MOVEM	T1,.CPRCT##-1(P1) ;STORE NEW VALUE
	SYSPIN			;TURN ON PI SYSTEM
	JRST	LOADRB		;GO SET UP RT BLOCK

BLKST1:	MOVEM	F,RTBLKO(T4)	;STORE BLKI/O INSTRUCTION
	TLNN	S,NOSAV		;EXEC MODE TRAPPING?
	MOVEM	T2,RJRST1(T4)	;STORE JRST RTJSR
	JRST	RTRET1		;GO SET UP CONSO CHAIN

VECST1:	MOVSI	T1,VECUSE	;INDICATE VECTORED INTERRUPT DEVICE
	IORM	T1,JOBTB(T4)	; THEREFORE NO CONSO INSTRUCTION ON THE SKIP CHAIN
	SETZM	RTCNSO-1(T4)	;INTERRUPT FLAGS
	MOVEI	T1,RTCNSO+1(T4)	;INTERRUPT NEW PC
	MOVEM	T1,RTCNSO(T4)	;FOR XPCW
	MOVSI	T1,(EXCH T1,)	;"EXCH T1,RTCNSO-3", FLAGS STORED BY XPCW
	HRRI	T1,RTCNSO-3(T4)	; ..
	MOVEM	T1,RTJRST(T4)	;STORE THAT IN RTBLK
	ADD	T1,[1,1]	;"EXCH T2,RTCNSO-2", PC STORED BY XPCW
	MOVEM	T1,RTBLKO(T4)	;STORE THAT IN RTBLK
	MOVSI	T1,(DMOVEM T1,)	;"DMOVEM T1,CHN", SO CAN USE CHANNEL SAVE ROUTINES
	HRR	T1,.CPRCT##-1(P1) ; ..
	MOVEM	T1,RJRST1(T4)	;STORE THAT
	MOVSI	T1,(DMOVE T1,)	;"DMOVE T1,RTCNSO-3", TO RESTORE ACS
	HRRI	T1,RTCNSO-3(T4)	; ..
	MOVEM	T1,RTJEN(T4)	;STORE THAT IN RTBLK
	TLNN	S,NOSAV		;EXEC MODE TRAPING?
	JRST	VECST2		;NO, REST OF THE BLOCK IS SETUP
	MOVEM	T3,RTJEN(T4)	;STORE "JSR TRPADR"
	MOVSI	T1,(XJEN)	;"XJEN CHN"
	HRR	T1,.CPRCT##-1(P1) ; ..
	MOVEM	T1,RTJSR(T4)	;STORE THAT IN RTBLK
VECST2:	MOVSI	T1,(XPCW)	;"XPCW RTCNSO-3"
	HRRI	T1,RTCNSO-3(T4)	; ..
	MOVEM	T1,(F)		;STORE THAT AT THE VECTOR ADDRESS
	JRST	RTRET2		;COMPLETE RTBLK AND RETURN TO THE USER
CHKDV2:	CAIN	T4,(T2)		;IS THIS DEVICE CODE OK?
	JRST	CHKDV1		;YES, GO BACK AND LOOK AT THE REST
	HRRZ	T1,JOBTB(T2)	;CHECK TO SEE IF THIS IS OUR JOB
	CAIN	J,(T1)		;IS IT US?
	JRST	CHKDV1		;YES, THEN IT IS OK.
	TRO	S,E26		;NO, SET ERROR BIT
CHKDV3:	SETZM	JOBTB(T4)	;ZERO OUT DEVICE CODE
	MOVEI	T1,(T4)		;GET BLOCK START ADDRESS
	SYSPIF			;PUT IT BACK ON FREE LIST
	EXCH	T1,RTLINK	;GET NEXT ENTRY ON LIST
	MOVEM	T1,(T4)		;PUT IT IN FIRST WORD OF CURRENT BLOCK
	SYSPIN			;LET INTERRUPTS COME AGAIN
ERROR:	TLNN	S,RTINT		;ARE WE AT INTERRUPT LEVEL
	JRST	ERROR1		;NO, GO DISMISS PROPERLY
	ADDI	R,-1(P4)	;GET ADDR OF UUO IN USER AREA
	LDB	T1,[POINT 4,(R),12] ;GET USER AC NUMBER
	HRRZM	S,(T1)		;STORE THE ERROR BITS IN USER AC
	JRSTF	@P4		;RETURN
ERROR1:	POP	P,M		;RESTORE UUO AC
	MOVE	T1,S		;PUT ERROR CODE IN T1
	JRST	STOTAC##	;GO STORE T1 IN USER AC

ERR34:	TROA	S,E34		;SET ERROR BIT 34
ERR35:	TRO	S,E35		;SET ERROR BIT 35
	SYSPIN			;TURN PI SYSTEM BACK ON
	JRST	CHKDV3		;GO CLEAN UP AND RETURN

NORTBL:	TRO	S,E29		;SET THE ERROR BIT
	JRST	ERROR		;GO GIVE ERROR RETURN

BLKSET:	MOVSI	T1,(XPCW)
	HRR	T1,.CPRCT##-1(P1) ;GET CH'PI ADDRESS
	HRRZ	T2,P1		;GET CHANNEL NUMBER
	LSH	T2,1		;MULTIPLY IT BY 2
	ADD	T2,.CPEPT##
	MOVEM	T1,41(T2) 	;STORE JSR INSTRUCTION IN TRAP LOCATION
	MOVSI	T3,(JRST)	;SET UP JRST TO RT BLOCK
	HRRI	T3,RTJSR(T4)	;GET START OF RT BLOCK CODE
	TLNE	S,NOSAV		;EXEC MODE TRAPING
	HRRI	T3,RJRST1(T4)	;YES, GET ADR OF "JSR TRPADR" INSTRUCTION
	MOVEM	T3,4(T1)	;STORE INSTRUCTION IN CH'PI + 4
	SYSPIF
	MOVEM	F,40(T2)	;STORE BLKI/O INSTRUCTION IN TRAP LOC
	HRRM	J,JOBTB(T4)	;REMOVE INTERLOCK
	SYSPIN
	JRST	RTRET		;GO RETURN TO USER
	;ENTERED BY INTERRUPT LEVEL UUO FROM LOC 41 WITH JSP RTUUO,UUOHND

	;DECODE UUO, AND IF IT IS LEGAL GO EXECUTE IT
	;OTHERWISE DISMIS THE INTERRUPT
	;THE FASTEST METHOD OF DISMISSING IS TO EXECUTE AN INSTRUCTION
	;WHICH TRAPS TO LOC 60 (IE OPCODE 100). THIS BYPASSES THE UUO DECODING.

	;*** ACS 16 AND 17 SHOULD NOT BE SYMBOLIC IN THIS ROUTINE
	;***SINCE THEY ARE DOCUMENTED AS 16 AND CANNOT IF SYMBOLIC
	;***NAMES ARE CHANGED
IFE <J-16>*<J-17>*<T1-16>*<T1-17>*<P-16>*<P-17>,<PRINTX ?UUOHND AC ASSIGNMENTS WRONG>
UUOHND::LDB	16,RTMUAC##	;PICK UP UUO AC
	CAIE	16,16		;IS THIS AN ILLEGAL USER AC?
	CAIN	16,17
	JRST	UUOHD3		;YES, GO GIVE IMMMEDIATE ERROR RETURN
	SKIPL	J,.CPRTT##	;GET RT BLOCK INDEX REGISTER
	JRST	.CPDMI##	;IF RT BLOCK RELEASED GO DISMISS
	LDB	T1,RTMUOC##	;GET UUO OPCODE
	CAIE	T1,47		;CALLI UUO?
	JRST	.CPDMI##	;NO,DISMIS
	XCT	@.CPDMI##	;SET UP P (MOVE P,C'PI'RTP)
	PUSH	P,17		;SAVE MUUO FLAGS,,PC
	MOVE	T1,(16)		;LOAD T1 WITH USER'S AC
	MOVE	R,JADRT1(J)	;LOAD PROTECTION-RELOCATION
	HRRZ	J,JOBTB1(J)	;LOAD J WITH JOB NUMBER
	HRRZ	T2,RTMCAN##	;PICK UP CALLI #
	CAIE	T2,RTUUON	;IS IT A RTTRP UUO?
	JRST	UUOHD2		;TRY OTHER LEGAL UUOS
	MOVSI	S,RTINT		;SET INTERRUPT LEVEL UUO BIT
	POP	P,P4		;RTRET AND ERROR EXPECT TO RETURN THRU P4
	JRST	RTTRP1		;GO EXECUTE UUO


UUOHD3:	MOVE	T1,17		;SAVE CONTENTS OF RETURN AC
	MOVEI	17,E27		;SET ERROR BIT IN AC RTUUO
	MOVEM	17,(16)		;STORE ERROR CODE IN USER'S AC
	JRSTF	@T1		;GIVE ERROR RETURN

UUOHD2:	CAIE	T2,WAKUUO	;IS THIS A WAKE UUO ?
	JRST	.CPDMI##	;NO,DISMIS(OR CHECK FOR OTHER LEGAL UUOS)
	MOVEI	T2,WAKEUP##	;SET UP FOR UUO DISPATCH
UUODPT:	PUSHJ	P,(T2)		;DISPATCH TO UUO
	  SKIPA			;ERROR RETURN
	AOS	(P)		;NORMAL SKIP RETURN
	POP	P,17		;GET RETURN PC
	JRSTF	@17		;RETURN TO CALLER
REMOVE:	TRNE	S,E24+E25	;ANY ERRORS SO FAR?
	JRST	ERROR		;YES, DON'T CONTINUE
	HRRI	T1,2(T1)	;MAKE T1 POINT TO INSTRUCTION ARG
	EXCTUX	<LDB T2,[POINT 7,@T1,9]>	;PICK UP DEVICE CODE
	PUSHJ	P,REMDEV	;GO REMOVE ALL DEVICES WITH THIS CODE
	JRST	RTRET		;GO RETURN TO USER

;SUBROUTINE TO TURN ON PI IF OFF
;PRESERVES ALL ACS
ONIFO:	CONSZ	PI,CLKBIT##	;CHANNEL 7 DISABLED
	CONSO	PI,PI.ON	;OR PI TURNED OFF
	SYSPIN			;RELEASE INTERLOCK
	POPJ	P,		;RETURN
	;REMDEV REMOVES ALL INSTANCES OF A DEVICE WITH THE CORRECT
	;JOB NUMBER FROM THE CHAINS
	;CALLING SEQUENCE:
	;	MOVE T2,DEVCODE
	;	PUSHJ P,REMDEV
	;AC'S T1, W, U, AND T4 ARE PRESERVED

REMDEV:	MOVE	P2,[XWD -M.RTD##,RTBLK##]	;SET UP COUNTER AC
	SYSPIF			;PREVENT RACES
REMDV1:	LDB	M,[POINT 7,JOBTB(P2),17]	;GET DEVICE CODE
IFN FTMP,<
	LDB	T3,[POINT 3,JOBTB(P2),2] ;CPU NUMBER
	CAMN	T3,.CPCPN##	;DEVICE ON THIS CPU?
>
	CAME	M,T2		;IS IT A MATCH
	SKIPA			;NO
	JRST	REMDV3		;YES, GO REMOVE IT FROM CHAIN
REMDV2:	HRRI	P2,RTBSIZ-1(P2)	;GO ON TO NEXT BLOCK
	AOBJN	P2,REMDV1	;LOOP BACK FOR REST OF BLOCKS
	JRST	ONPOPJ##	;NO DEVICES, TURN INTS BACK ON AND RETURN

REMDV3:	MOVE	M,JOBTB(P2)	;GET JOB NUMBER
	CAIE	J,(M)		;IS THIS OUR JOB?
	JRST	REMDV2		;KEEP LOOKING
	PUSH	P,P1		;SAVE CHANNEL NUMBER
	PUSH	P,T2		;SAVE DEVICE CODE
	HRRZS	JOBTB(P2)	;SET INTERLOCK
	TLNE	M,VECUSE	;VECTORED INTERRUPT DEVICE?
	JRST	CHFND0		;YES, NO CONSO'S ON THE SKIP CHAIN
	SYSPIN			;FINISHED STICKY AREA
	HRRZ	P1,PITAB(P2)	;GET PI CHANNEL NUMBER
	MOVE	T2,.CPRCT##-1(P1);GET CHANNEL STATUS WORD
	TLNE	T2,BINUSE	;IS THIS A BLKI/O CASE
	JRST	BLKREM		;YES, GO REMOVE THAT
CHLPB:	MOVSI	T2,(JRST)	;SET UP CHAIN INSTRUCTION TO LOOK FOR
	HRRI	T2,3(P2)	;GET ADDRESS OF BLOCK
	HRRZ	M,.CPRCT##-1(P1) ;GET CHANNEL ADDRESS
	ADDI	M,3		;SKIP XPCW BLOCK
	SYSPIF			;PREVENT RACES

CHLOOP:	CAMN	T2,1(M)		;IS THIS THE RIGHT CHAIN ENTRY?
	JRST	CHFND		;YES, GO REMOVE IT
	HRRZ	M,1(M)		;POINT TO NEXT CONSO ELEMENT
	JRST	CHLOOP		;GO BACK FOR MORE
	;ENTERED AFTER FINDING THIS DEVICE
CHFND:	MOVE	T2,4(P2)	;GET NEXT CHAIN LINK
	MOVEM	T2,1(M)		;CUT THIS RT BLOCK OUT OF CHAIN
CHFND0:	SYSPIN			;ALLOW INTERRUPTS PENDING TO GO
	SYSPIF
	SOSE	.CPRCU##-1(P1)	;DECREMENT COUNT OF CONSO'S
	JRST	CHFND1		;STILL MORE CONSO'S ON CHAIN
	MOVE	T2,.CPRCT##-1(P1);GET CHANNEL STATUS WORD
	TLNE	T2,BLKENB	;BLKI/O ALLOWED
	TLO	T2,BLKAVL	;YES, MARK THAT THIS CHANNEL IS FREE
	MOVEM	T2,.CPRCT##-1(P1);STORE NEW STATUS WORD
CHFND1:	SYSPIN			;TURN ON PI SYSTEM AGAIN
CLRRTB:	HRRZ	T2,.CPRTT##	;GET RT BLOCK POINTER ADDRESS
	CAIE	T2,RTJSP+1(P2)	;IS THIS THE BLOCK THAT IS BEING REMOVED?
	JRST	CLRRT1		;NO
	HRRZ	M,.CPRDT##-1(P1) ;GET ADDRESS OF DISMISS ROUTINE
	HRRZI	M,RTOFST##(M)	;ADD IN RELTAB OFSET
	MOVE	T2,RELTAB(P2)	;GET RELOC/PROTECTION
	MOVEM	T2,RELTB1(M)	;STORE IN PI LEVEL AREA
	MOVE	T2,UENBTB(P2)	;GET ENABLE BITS
	MOVEM	T2,UENBT1(M)	;STORE IN PI LEVEL AREA
	MOVEM	M,.CPRTT##	;STORE NEW .CPRTT WORD
CLRRT1:	MOVEI	T2,(P2)		;PICK UP RT BLOCK ADDRESS
	SYSPIF
	SETZM	JOBTB(P2)	;CLEAR OUT DEV CODE
	EXCH	T2,RTLINK	;PUT THIS BLOCK BACK ON LIST
	MOVEM	T2,(P2)		;SET UP REST OF LINKS
	SYSPIN
	SOS	JBTRTD##(J)	;COUNT DOWN RT DEVICE COUNT
	POP	P,T2		;RESTORE DEVICE CODE
	POP	P,P1		;RESTORE CHANNEL NUMBER
	SYSPIF			;ENTER REMDV2 WITH PIS OFF
	JRST	REMDV2		;ALL FINISHED
	;ENTER HERE TO REMOVE A BLKI/O FROM A PI LOCATION
BLKREM:	TLNE	T2,BLKSAV	;ARE WE JUST RESETTING POINTER WORD
	JRST	BLKRM1		;YES, DON'T REMOVE BLKI/O
	MOVE	T2,.CPEPT##	;GET PROPER PI LOCATION
	ADDI	T2,40(P1)
	ADD	T2,P1		;40 + 2*N
	HRLI	M,(XPCW)	;SET UP XPCW CHAN
	HRR	M,.CPRCT##-1(P1) ;GET CHAN ADDRESS
	MOVEM	M,(T2)		;STORE IN 40+2*N
	HRLI	M,(XJEN)
	MOVEM	M,4(M)		;T4+4 = JEN @ T4
	SYSPIF			;TURN OFF PI
	MOVE	M,.CPRCT##-1(P1) ;GET STATUS WORD
	TLC	M,BLKAVL!BINUSE	;SET THAT CHANNEL IS FREE
	MOVEM	M,.CPRCT##-1(P1);STORE NEW STATUS WORD
	SYSPIN
	JRST	CLRRTB		;GO CLEAN UP RT BLOCK

BLKRM1:	MOVSI	T2,BLKSAV	;CLEAR OUT BIT
	ANDCAM	T2,.CPRCT##-1(P1)
	JRST	CLRRTB		;GO CLEAN UP
	;RTREL IS CALLED BY RESET TO REMOVE ALL DEVICES FROM
	;THE PI CHANNELS.
	;BEFORE REMOVING ANY DEVICE A CONO DEV,0 IS EXECUTED

RTREL::	MOVEI	T1,777		;ARE THERE ANY DEVICES ON PI LEVELS
	TDNN	T1,JBTRTD##(J)	;CHECK RIGHT HALF ONLY
	POPJ	P,		;NO, RETURN
	MOVEI	T1,M.RTD##	;SET UP COUNTER
	MOVEI	T2,RTBLK##	;SET UP TO LOOK FOR DEVICES
RTREL1:	SKIPE	T3,JOBTB(T2)	;ANY JOB USING THIS BLOCK
	JRST	RTREL3		;YES, GO SEE IF IT IS THIS JOB
RTREL2:	MOVEI	T2,RTBSIZ(T2)	;GET NEXT ENTRY
	SOJG	T1,RTREL1	;GO LOOK AT OTHER ENTRIES
	JRST	RTREL		;GO RETURN

RTREL3:	CAIE	J,(T3)		;IS THIS US?
	JRST	RTREL2		;NO, GO LOOK AT REST OF BLOCKS
IFN FTMP,<
	LDB	T1,[POINT 3,T3,2] ;CPU NUMBER
	PUSHJ	P,ONCPUN##	;GET TO THE CPU THAT OWNS THE DEVICE
>
	HLRZ	T2,T3		;GET DEVICE NUMBER
	ANDI	T2,177		;CLEAR RTUSE BIT
	MOVSI	T3,(CONO)	;SET UP TO DO A CONO DEV,0
	DPB	T2,[POINT 7,T3,9]
IFN FTKL10,<
	CAIN	T2,<TIM>_-2	;IF KL10 INTERVAL TIMER
	TRO	T3,TO.CIT!TO.CTD ;CLEAR TIMER AND THE DONE FLAG
>
	CAILE	T2,1		;DON'T CONO 0 TO PI OR APR
	XCT	T3		;CONO DEV,0
	PUSHJ	P,REMDEV	;REMOVE THE DEVICE FROM THE CHAIN
	JRST	RTREL		;GO LOOK AT REST OF BLOCKS
	SUBTTL	REAL TIME TRAPPING INITIALIZATION

	$INIT

;RTINI IS THE INITIALIZATION ROUTINE TO SET UP THE REAL TIME BLOCKS

RTINI::	MOVEI	T1,.C0CDB##	;POINT AT FIRST CDB
RTINI1:	HRLI	T1,-6		;NUMBER OF RT DEVICE SLOTS
RTINI2:	SKIPE	T2,.CPRCT##-.CPCDB##(T1) ;ANY DEVICES?
	MOVE	T2,1(T2)	;YES, GET COUNT
	MOVEM	T2,.CPRIT##-.CPCDB##(T1) ;RESET IT
	AOBJN	T1,RTINI2	;LOOP FOR ALL SLOTS
	HLRZ	T1,.CPCDB##-.CPCDB##-6(T1) ;GET LINK TO NEXT CDB
	JUMPN	T1,RTINI1	;LOOP IF MORE CPUS

RTINI3:	MOVEI	T1,.C0CDB##	;ADDRESS OF FIRST CDB
RTINI4:	HRLI	T1,-6		;NUMBER OF RT DEVICE SLOTS
RTINI5:	MOVE	T2,.CPRIT##-.CPCDB##(T1) ;GET TABLE ADDRESS
	SKIPE	T3,.CPRCT##-.CPCDB##(T1) ;ANY DEVICES?
	MOVEM	T2,1(T3)	;YES, SAVE COUNT IN TABLE
	AOBJN	T1,RTINI5	;LOOP FOR ALL SLOTS IN CDB
	HLRZ	T1,.CPCDB##-.CPCDB##-6(T1) ;GET LINK TO NEXT CDB
	JUMPN	T1,RTINI4	;LOOP IF ANY MORE

	SETZM	RTBLK##		;SET UP TO ZERO RTBLOCK AREA
	MOVE	T1,[XWD RTBLK##,RTBLK+1]
	MOVEI	T2,RTBSIZ*M.RTD## ;CALCULATE LENGTH OF RT BLOCK AREA
	BLT	T1,RTBLK##-1(T2) ;ZERO THE AREA
	MOVEI	T1,RTBLK##	;NOW LINK THE BLOCKS TOGETHER
	MOVEI	T2,M.RTD##	;GET NUMBER OF BLOCKS AVAILABLE
	MOVEM	T1,RTLINK	;SET UP FIRST ENTRY
RTINI6:	MOVEI	T3,RTBSIZ(T1)	;GET ADDRESS OF NEXT BLOCK
	MOVEM	T3,(T1)		;STORE IN CURRENT BLOCK
	EXCH	T3,T1		;GET NEXT BLOCKADR IN T1
	SOJG	T2,RTINI6	;GO FINISH LOOP
	SETZM	(T3)		;MAKE THE LAST BLOCK IN LIST HAVE 0 POINTER
	MOVEI	T1,.C0CDB##	;START WITH FIRST CDB
RTINI7:	SETZM	.CPRTT##-.CPCDB##(T1) ;CLEAR COUNT
	HRLI	T1,-6		;NUMBER OF RT DEVICE SLOTS
RTINI8:	SKIPE	T2,.CPRCT##-.CPCDB##(T1) ;ANY DEVICES?
	TLNN	T2,BLKENB	;YES, ENABLED?
	JRST	RTINI9		;NO
	HRLI	T2,BLKENB+400000 ;YES, FLAG IT
	MOVEM	T2,.CPRCT##-.CPCDB##(T1) ;STORE FLAGS
RTINI9:	AOBJN	T1,RTINI8	;LOOP FOR ALL SLOTS
	HLRZ	T1,.CPCDB##-.CPCDB##-6(T1) ;GET LINK TO NEXT CDB
	JUMPN	T1,RTINI7	;LOOP IF MORE CPUS

	MOVSI	T1,MJOBN##	;GET NEGATIVE JOB NUMBER
	SETZM	JBTRTD##(T1)	;CLEAR OUT TABLE
	AOBJN	T1,.-1		;DO REST OF TABLE
	POPJ	P,		;RETURN

	$HIGH
;VARIABLE STORAGE ALLOCATION
	$LOW
RTLINK::Z			;POINTER TO FIRST FREE BLOCK ON LIST
	$LIT
	END