perm filename SAIPRC.FAI[S,AIL] blob sn#217523 filedate 1976-05-31 generic text, type T, neo UTF8
SEARCH HDRFIL
COMPIL(PRC,,,,,,DUMMYFORGDSCISS)
DEFINE ENS1 < SPROUT,URSCHD,RESUME,SUSPEND,TERMINATE,JOIN,MAINPR,CALLER>
DEFINE ENS2 <%PSSGC,DDFINT,INTSET,CAUSE,ANSWER,INTERROGATE,SETCP>
DEFINE ENS3 <MKEVTT,SETIP,MYPROC,CLKMOD,DFR1IN,DFRINT,INTPRO>
DEFINE ENS4 <DFCPKT,PSTATUS,ASKNTC,CAUSE1,PRISET>
DEFINE EXT1 <LEAP,STKUWD,X44,GOGTAB,%ARSR1,SGINS,ALLPDP>
DEFINE EXT2 <CORGET,CORREL,INTRPT,INFTB,%SPGC,X22,%SPGC1,FP1DON,STACSV>
DEFINE EXT3 <X33,%ARRSR,DATM,SGLKBK,FP2DON,SGREM,STACRS,RUNNER,NOPOLL>
DEFINE EXT4 <X11,DEFSSS,DEFPSS,DEFPRI,DEFQNT,INTTBL,APPL$Y>
IFN APRISW <
DEFINE XJBCNI <JOBCNI>
DEFINE XJBTPC <JOBTPC>
DEFINE XJBAPR <JOBAPR>
DEFINE EXT5 <JOBCNI,JOBTPC,JOBAPR>
IFN ALWAYS <
EXTERN EXT5	;THESE ARE ALWAYS EXTERNAL
>;IFN ALWAYS
>;IFN APRISW
IFE APRISW <
DEFINE EXT5 <XJBCNI,XJBTPC,XJBAPR,JOBINT>
IFN ALWAYS <
EXTERNAL JOBINT ;THIS FELLOW IS ALWAYS EXTERNAL
>;IFN ALWAYS
>;IFE APRISW
COMPXX(PRC,<ENS1,ENS2,ENS3,ENS4>,<EXT1,EXT2,EXT3,EXT4,EXT5>
	,<MULTIPLE PROCESS STUFF>,<SPRPDA>,HIIFPOSSIB)
BEGIN PROCSS
KL	←D	;KILL LIST & SCRATCH
PB	←5	;PROCESS BASE
OPTS	←6	;HOLDS OPTIONS
PDA	←7	;HOLDS PDA
EVT	←10	;EVENT DATUM
NSP	←←10	;NEW SP
NP	←11	;NEW P
TMP	←LPSA	;TEMP AC
GLOB < 
TABL ←← 7	;NEEDED BY LIST CELL GETTER
>;GLOB
NOGLOB <
TABL ←← USER	;NEEDED BY LIST CELL GETTER
>;NOGLOB
FP ←← 6		;NEEDED BY LIST CELL GETTER
MAXPRI ←← 0	;MAXIMUM PRIORITY
MINPRI ←← NPRIS-1
PSPF←←0		;ONLY P, SP, F NEED BE RESTORED
SPNDR←←1	;SUSPENDED (FROM READY) BY SUSPEND
JOINR←←2	;SUSPENDED BECAUSE OF A JOIN
WAITNG←←3	;WAITING ON AN EVENT OR SO
STSMSK←	77 ⊗ =8	;MASK FOR P STACK SIZE FIELD
SSSMSK←	17 ⊗ =14;MASK FOR SP STACK SIZE FIELD OF OPTIONS WORD
PRIMSK←	17 ⊗ 4	;MASK FOR PRIORITY FIELD
QNTMSK←← 17	;MASK FOR QUANTUM
RUNME←←	1	;RUN THE SPROUTING PROCESS
SPNDME←←2	;SUSPEND THE SPROUTING PROCESS
SPNDNP←←10	;SUSPEND THE NEW PROCESS
TERM  ←← 1	;BIT (LH) IN DATUM OF TERMINATED PROCESS ITEM
STPSZ←	40	;DEFAULT P- STACK SIZE (MINUS THE PROCESS TABLE AREA)
STSPST ←20	;DEFAULT SP STACK SIZE
STDQNT ←← 4	;DEFAULT STD QUANTUM IS 4
STDPRI	←←7	;DEFAULT PRIORITY
MSTMSK←←14	;MASK FOR MY NEW STATUS FIELD
NOTNOW←←1	;SET IF RESUMED PROCESS IS MERELY TO GO READY
MSTBYT:	POINT	2,OPTS,33 ;MY NEW STATUS
SSSBYT:	POINT	4,OPTS,21	;STRING STACK FIELD (MOD 32)
STSBYT:	POINT	6,OPTS,27	;P - STACK FIELD (MOD 32)
PRIBYT:	POINT	4,OPTS,31	;PRIORITY FIELD
QNTBYT:	POINT	4,OPTS,17	;LOG2 (QUANTUM)
DEFINE NCELL(AC) <
	MOVE	FP,FP1(TABL)	;USE WHERE SURE THE LIST SPACE IS INITIALIZED
	HRRI	AC,(FP)
	SKIPN	FP,(FP)
	PUSHJ	P,FP1DON
	HRRM	FP,FP1(TABL)
>
DEFINE NNCELL(AC) <
	SKIPN	FP,FP1(TABL)	;USE WHERE LIST SPACE MAY NEED INITIALIZATION
	PUSHJ	P,FP1DON
	HRRI	AC,(FP)
	SKIPN	FP,(FP)
	PUSHJ	P,FP1DON
	HRRM	FP,FP1(TABL)
>
DEFINE NNCLL2(AC) <
	SKIPN	FP,FP2(TABL)	;USE WHERE LIST SPACE MAY NEED INITIALIZATION
	PUSHJ	P,FP2DON
	HRRI	AC,(FP)
	SKIPN	FP,(FP)
	PUSHJ	P,FP2DON
	HRRM	FP,FP2(TABL)
>
NOTENX<
OPDEF INTENS [CALLI 400030]
OPDEF IWAIT [CALLI 400040]
>;NOTENX
DEFINE PVAR (V,ATTRIB),
	<↑V ←← NPVARS
	NPVARS←← NPVARS+1
IFE ALWAYS,<
	IFDIF <ATTRIB>,<> < ATTRIB V >
>;IFE ALWAYS
	>
NPVARS←← 0
	PVAR	DYNL	;DYNAMIC LINK
	PVAR	STATL	;STATIC LINK
	PVAR	ISP	;REST OF MSCP
	PVAR	AC0	;AC SAVE AREA
	PVAR	AC1
	PVAR	AC2
	PVAR	AC3
	PVAR	AC4
	PVAR	AC5
	PVAR	AC6
	PVAR	AC7
	PVAR	AC10
	PVAR	AC11
	PVAR	AC12
	PVAR	AC13
	PVAR	AC14
	PVAR	AC15
	PVAR	AC16
	PVAR	AC17
INTERNAL ACF
↑ACF ←← AC12
↑ACP ←← AC17
↑ACSP ←← AC16
	PVAR	PCW	;PC WORD
	PVAR	QUANTM	;TIME QUANTUM
	PVAR	PRIOR	;PRIORITY
	PVAR	PRCITM	;PROCESS ITEM OF THIS PROCESS
	PVAR	KLOWNR	;THE OWNER OF MY KILL LIST
	PVAR 	STATUS	;-1 = RUNNING, 0 = SUSPEND, 1 = READY, 2 = TERMINATED
	PVAR	DADDY,INTERNAL	;PROCESS ITEM OF SPROUTING PROCESS
	PVAR	CAUSRA	;RETN ADDRESS FROM CAUSE
ZFIRST←←NPVARS
	PVAR	CURSCB,INTERNAL	;CURRENT SEARCH CONTROL BLOCK
	PVAR	REASON	;HOW GOT UNSCHEDULED (0 MEANS ONLY NEED ACS F,SP,P)
	PVAR	PLISTE,INTERNAL	;PRIORITY LIST ENTRY
	PVAR	RSMR	;THE GUY WHO RESUMED ME (%AG% ** INIT TO DADDY ** )
	PVAR	JOINCT	;HOW MANY PROCESSES NEED TO JOIN THIS ONE
	PVAR	JOINS	;WHO IS WAITING TO FOR ME TO JOIN (A SET OF ITEMS)
	PVAR	WAITES	;LIST OF ALL EVENT TYPES ON WHICH I AM WAITING
	PVAR	INTRGC	;THE CONTROL WORD FOR MY CURENT INTERROGATION
	PVAR	CAUSES	;COUNT OF CAUSES PENDING
	PVAR	CAUSEQ	;QUEUE OF CAUSES TO BE MADE
ZLAST←←NPVARS-1
↑NPVARS ← NPVARS
↑STKBAS ← NPVARS	;STACK BASE SIZE (= #PROCESS VARS FOR NOW)
NEVARS←←0
DEFINE EVAR(V) ,
	<↑↑V←←NEVARS
	NEVARS←←NEVARS+1
	>
	EVAR	NOTCLS		;LIST OF CURRENT NOTICES
	EVAR	WAITLS		;LIST OF CURRENTLY WAITING PROCESSES
	EVAR	CAUSEP		;USER SPEC CAUSE PROC
	EVAR	INTRGP		;USER SPEC INTERROGATE PROC
	EVAR	USER1		;AVAIL TO USER
	EVAR	USER2		;AVAIL TO USERR
DNTSAV ←← 1
TELLAL ←← 2
SCHDIT ←← 4
RETAIN ←← 1
WAIT   ←← 2
SAYWCH ←← 10
MULTIN ←← 200000
NOJOY  ←← 400000
FLXXX←←0
NOTENX<
UP <
FLXXX←←%FIRLOC-400000
>;UP
>;NOTENX
TENX<
UP <
FLXXX←←%FIRLOC-(SEGPAGE*1000)
>;UP
>;TENX
DEFINE PUTINLOC(LCN,V),< 
UP <
	SVPCXX ←← .
	DEPHASE
>;UP
	RELOC LCN+FLXXX
	V
	RELOC
UP <
	PHASE SVPCXX
>;UP
>
↑SPRPDA:
REPEAT PD.XXX+1, <0
>
DEFINE FPDE(IX,V),<PUTINLOC (SPRPDA+IX,V)>
	FPDE	(PD.,SPROUT)
	FPDE	(PD.ID1,6)
	FPDE	(PD.ID2,<<POINT 7,[ASCII/SPROUT/]>>)
	FPDE	(PD.DSW,STKBAS)
	FPDE	(PD.PDA,<<XWD SPRPDA,0>>)
	FPDE	(PD.LLW,<SPRPDA+PD.XXX>)
	FPDE	(PD.DLW,<SPRPDA+PD.XXX>)
IFN 0,<
NULPDA:	NULPRO			;PD OF NUL PROC
↑NULPRC: %NULPR			;NULL PROCESS
%NULPR:	BLOCK STKBAS+=32	;NULL PROCESS AREA
DEFINE NPE (IX,V), <PUTINLOC (%NULPR+IX,V)>
	NPE	(STATL,<<XWD SPRPDA,0>>)
	NPE	(ACF,STKBAS+%NULPR+1)
	NPE	(ACP,<<TPDL: XWD - =29,%NULPR+STKBAS+3>>)
	NPE	(STKBAS+1,%NULPR+DYNL)
	NPE	(STKBAS+2,<<XWD NULPDA,0>>)
↑NULPRO:
	ERR	<I SHOULD NEVER RUN>
>;IFN 0
HERE (SPROUT)
	MOVE	USER,RUNNER	;
	POP	P,PCW(USER)	;RETN ADDRESS
	POP	P,KL		;PICK UP KILLL LIST
	POP	P,OPTS		;OPTIONS
	POP	P,PDA		;FIND OUT WHO
	CAIN 	PDA,APPL$Y	;SPROUT APPLY IS A ROYAL PAIN
	SKIPA	TMP,-1(P)	;REAL PDA FOR SPROUT APPLY
	MOVE	TMP,PDA		;
	HRRZ	A,PD.PDB(TMP)	;THE DEFAULTS
	JUMPE	A,SALCS		;NO DEFAULTS -- SPROUT ALLOCATIONS NOW
	LSH	A,4		;INTO POSITION
	TRNE	OPTS,STSMSK	;P STACK
	TRZ	A,STSMSK
	TRNE	OPTS,SSSMSK	;SP STACK
	TRZ	A,SSSMSK
	TRNE	OPTS,PRIMSK	;PRIORITY
	TRZ	A,PRIMSK
	TLNE	OPTS,QNTMSK	;QUANTUM
	TLZ	A,QNTMSK	;
	IOR	OPTS,A		;OR IN THE BITS FOR DEFAULTS
SALCS:
	TRNE	OPTS,SSSMSK	;SPECIFIED SP STACK SIZE ?
	JRST	[ LDB C,SSSBYT	;YES, GET IT
		LSH   C,5	;TIMES 32
		JRST  .+2 ]
	MOVE	C,DEFSSS	;STANDARD SIZE
	PUSHJ	P,CORGET	;GET SPACE
	ERR	<SPROUT: No core>
	MOVN	C,C		;MAKE PDP
	HRLZI	NSP,-1(C)	
	HRRI	NSP,-1(B)
	TRNE	OPTS,STSMSK	;P - STACK
	JRST	[ LDB C,STSBYT	;YES, GET IT
		LSH	C,5	;TIMES 32
		JRST	.+2]
	MOVE	C,DEFPSS	;STANDARD AMOUNT TO GET
	ADDI	C,STKBAS	;SPACE FOR BASE
	PUSHJ	P,CORGET	;GET ROOM
	ERR	<SPROUT: No core>
	MOVE	PB,B		;PROCESS BASE
	MOVN	C,C
	HRLZI	NP,STKBAS(C)	;MAKE PDP
	HRRI	NP,STKBAS(PB)
	HRLZI	A,ZFIRST(PB)	;
	HRRI	A,ZFIRST+1(PB)
	SETZM	ZFIRST(PB)
	BLT	A,ZLAST(PB)
	MOVE	USER,RUNNER
	MOVE	A,PRCITM(USER)
	MOVEM	A,DADDY(PB)
	MOVEM	A,RSMR(PB)	;SO CALLER(MYPROC) STARTS OUT AS DADDY
	SETZM	DYNL(PB)	;NULL DYN LINK
	CAIN	PDA,APPL$Y	;IS IT A SPROUT APPLY?
	JRST	[		;YES
UP <
		MOVE	PDA,(PDA) ;SINCE APPL$Y IS HERED
>;UP
		POP	P,TMP	;ARG LIST
		POP	P,A	;PDA OF TARGET
		PUSH	NP,A	;PUT ON CALL STACK
		PUSH	NP,TMP	;PUT ON CALL STACK
		HRLZI	TMP,SPRPDA
		HLRZ	C,PD.DLW(A) ;LOOK FOR RIGHT LINK
		TLNN	A,-1	;ENVIRON SUPPLIED??
		CAIG	C,1	;GLOBAL??
		JRST	SSLON	;YES
		HRRZ	A,PD.PPD(A);
		SKIPA	TMP,RF
	SSLFLP:	HLRZ	TMP,C
		MOVS	C,1(TMP)
		CAIE	A,(C)
		JRST	SSLFLP
		HRLI	TMP,SPRPDA
	SSLON:	MOVEM	TMP,STATL(PB)
		MOVEM	NSP,ISP(PB)
		JRST	APSON	]
	HLRZ	A,PD.DLW(PDA)	;DISPLAY LEVEL
	HRLZI	TMP,SPRPDA	;IN CASE OUTER LEVEL
	CAIG	A,1		;OUTER BLOCK PROC?
	JRST	SLON		;YES -- NO LOOP
	HRRZ	A,PD.PPD(PDA)	;THE LEXICAL PARENT
	SKIPA	TMP,RF		;DYNL
SLFLP:	HLRZ	TMP,C		;BACK A STATL
	MOVS	C,1(TMP)	;SL,,PDA
	CAIE	A,(C)		;SAME AS DADDY?
	JRST	SLFLP		;NO
	HRLI	TMP,SPRPDA	;SPRPDA,,STATL
SLON:	MOVEM	TMP,STATL(PB)	;STATIC LINK WORD
	MOVEM	NSP,ISP(PB)	;SP WORD
	HLRZ	TMP,PD.NPW(PDA)	;#STRING PARAMS*2
	JUMPE	TMP,STPSON	;HAVE ANY ?
	HRL	TMP,TMP		;YES, DO A BLT
	HRRZI	A,1(NSP)	;DEST
	ADD	NSP,TMP		;BUMP NEW STACK
	JUMPL	NSP,.+2
	 ERR	<SPROUT: SP PDLOV>
	SUB	SP,TMP		;DECREMENT OLD STACK
	HRLI	A,1(SP)		;SOURCE
	BLT	A,(NSP)		;COPY THEM
STPSON:	HRRZ	TMP,PD.NPW(PDA)	;# ARITH PARMS +1
	SOJLE	TMP,APSON	;ANY TO BLT ?
	HRL	TMP,TMP		;MAKE XWD
	HRRZI	A,1(NP)		;DEST
	ADD	NP,TMP
	JUMPL	NP,.+2
	 ERR	<SPROUT: P PDLOV>
	SUB	P,TMP
	HRLI	A,1(P)
	BLT	A,(NP)		;DO IT
APSON:
	SETOM	STATUS(PB)		;ASSUME RUNNING
	TRNE	OPTS,SPNDNP		;UNLESS SUSPEND
	SETZM	STATUS(PB)		;0 MEANS SUSPENDED
	MOVE	TMP,DEFQNT		;STANDARD QUANTUM
	TLNN	OPTS,QNTMSK		;GET LOG2 QUANTUM
	JRST	SVQNT			;NO NEED
	LDB	A,QNTBYT
	MOVEI	TMP,1
	LSH	TMP,(A)
SVQNT:	MOVEM	TMP,QUANTM(PB)
	MOVE 	A,DEFPRI		;ASSUME STD PRIORITY
	TRNE	OPTS,PRIMSK		;SAID OTHERWISE?
	LDB	A,PRIBYT
	PUSHJ	P,SETPRI		;GO SET PRIORITY
	POP	P,C			;PICK UP ITEM #
	JUMPN	C,.+2
	 ERR	<SPROUT: Illegal process item >,7
	MOVEM	C,PRCITM(PB)		;REMEMBER IT
	MOVEI	A,PRCTYP		;SAY IS OF TYPE PROCESS
	MOVE	TABL,GOGTAB
	DPB	A,INFOTAB(TABL)		;SAY IS A PROCESS
	HRRZM	PB,@DATAB(TABL)		;SET DATUM VALUE
	MOVE	B,C			;ITEM NUMBER
	MOVEM	KL,KLOWNR(PB)		;REMEMBER KILL LIST OWNER
	JUMPE	KL,NEWSTT		;ONLY PUT ON KILL SET IF HAVE ONE
	PUSH	P,TABL			;NEED TO SAVE THESE
	PUSH	P,FP			;
	PUSHJ	P,INSRTS		;GO PUT ITEM IN KILL SET
	POP	P,FP
	POP	P,TABL
NEWSTT:	MOVE 	USER,RUNNER		;HOPE IT IS STILL HIM
	TRNE	OPTS,RUNME		; DOES SPROUTING PROCESS WANT TO RUN?
	JRST	RNSPRR			;YES
	MOVEM	P,ACP(USER)		;IF HERE, THEN WANT TO RUN NEW GUY
	MOVEM	SP,ACSP(USER)		;SAVE THE NECESSARY ACS
	MOVEM	RF,ACF(USER)		;
	MOVNS	STATUS(USER)		;RUNNING BECOMES READY
	TRNE	OPTS,SPNDME		;IF I WANTED SUSPENSION
	SETZM	STATUS(USER)		;DO IT
	SKIPL	STATUS(PB)		;DOES SPROUTED PROCESS WANT TO RUN
	JRST	NORFR			;NO
	MOVE	USER,GOGTAB
	MOVE	A,QUANTM(PB)
	MOVEM	A,TIMER(USER)
	MOVE	P,NP			;
	MOVE	SP,NSP			;GET READY
	MOVEI	RF,DYNL(PB)		;
	MOVEM	PB,RUNNER
CALLIT:	PUSHJ	P,@PD.(PDA)		;CALL THE SO AND SO
CALRET:	MOVE	PB,RUNNER		;I HOPE ITS ME
	MOVE	P,ALLPDP		;USE THIS PDL FOR KILLING CORE
	PUSHJ	P,KACTS			;DO EVERYTHING BUT SPACE FREEING
	HRRZ	B,ISP(PB)
	ADDI	B,1
	PUSHJ	P,CORREL
	HRRZI	B,(PB)
	PUSHJ	P,CORREL
	JRST	FOTR			;GO FIND SOMETHING TO DO
KACTS:	HRRZ	C,PRCITM(PB)
	MOVE	B,C			;
	MOVE	TABL,GOGTAB		;
	TLO	PB,TERM			;SET TERM BIT
	MOVEM	PB,@DATAB(TABL)		;TERMINATED
	SKIPE	KL,KLOWNR(PB)		;IF HAVE A KILL SET
	PUSHJ	P,DELTSE		;DELETE FROM SET
	SKIPN	A,JOINS(PB)
	JRST	REMPRI
	MOVE	KL,GOGTAB	;
KACT.1:	HLRZ	C,(A)		;THE ITEM
	MOVE	B,@DATAB(TABL)	;GET ADDRESS OF THE DATUM
	TLNE	B,TERM		;DEAD ALREADY??
	JRST	KACT.2		;YES
	SOSLE	JOINCT(B)	;READY TO ROLL ??
	JRST	KACT.2		;NO
	SKIPN	STATUS(B)	;CURRENT STATUS
	AOS	STATUS(B)	;READY
KACT.2:	HRRZ	B,(A)
	HRR	C,FP1(KL)	;RELEASE LIST CELL
	HRRM	C,(A)	
	HRRM	A,FP1(KL)	;NEW FREE LIST
	JUMPE	B,REMPRI	;END OF LIST
	MOVE	A,B		;
	JRST 	KACT.1
REMPRI:	MOVE	A,PRIOR(PB)
	ADD	A,GOGTAB
	HRRZ	B,PLISTE(PB)
	HLRZ	C,PLISTE(PB)
	JUMPN	C,.+3
	HRRM	B,PRILIS(A)		;HEAD OF LIST
	JRST	.+2
	HRRM	B,PLISTE(C)		;NEXT(C)←B
	JUMPN	B,.+3
	HRLM	C,PRILIS(A)		;NEW TAIL
	POPJ	P,
	HRLM	C,PLISTE(B)		;PREV(B)←C
	POPJ	P,
SETPRI:	MOVEM	A,PRIOR(PB)		;REMEMBER MY PRIORITY
	ADD	A,GOGTAB
	HLRZ	B,PRILIS(A)		;OLD LAST ELEMENT
	JUMPN	B,OLDLST		;HAVE ONE
	SETZM	PLISTE(PB)		;DONT HAVE ONE, BOTH LINKS ARE NULL
	HRRZM	PB,PRILIS(A)		;NEW FIRST ELEMENT SINCE WAS EMPTY
	JRST	SETP.X			;GO FINISH OUT
OLDLST:	HRRM	PB,PLISTE(B)		;LINK ONTO END OF LIST
	HRLZM	B,PLISTE(PB)
SETP.X:	HRLM	PB,PRILIS(A)		;MAKE NEW LAST ELEMENT
CPOPJ:	POPJ	P,
NORFR:	TROA	B,1			;FLAG
RNSPRR:	MOVEI	B,0
	MOVNS	STATUS(PB)		;IF NEW IS "RUNNING", THEN "READY"
	PUSH	NP,[CALRET]		;
	MOVEM	NP,ACP(PB)		;SET UP NEC. SAVES
	MOVEM	NSP,ACSP(PB)
	MOVEI	A,DYNL(PB)		
	MOVEM	A,ACF(PB)
	MOVE	A,PD.(PDA)		;WHERE HE STARTS
	MOVEM	A,PCW(PB)
	CAIN	B,			;SPROUTER RUNS??
	JRST	@PCW(USER)		;YES -- 
	JRST	FOTR			;NO -- FIND SOMEONE TO RUN
INSRTS:	MOVE	TABL,GOGTAB
	SKIPN	A,(KL)		;GET OWNER
	JRST	NEWINS		;IT WAS NULL BEFORE
	MOVE	C,(A)		;POINT AT FIRST
ISCH:	MOVS	C,(C)		;CONTENTS (SWAPPED) OF THIS
	CAILE	B,(C)		;ELIGIBLE
	JRST	NX1		;MUST GO FURTHER
	CAIL	B,(C)		;THERE ALREADY?
	POPJ	P,		;YES
NI:	HRL	B,(A)		;POINTER AT THIS
	NCELL	(C)		;GET A CELL FOR IT
	MOVSM	B,(C)		;SAVE CONTENTS OF CELL
	HRRM	C,(A)		;LINK TO NEW
	HRLZI	A,1
	ADDB	A,(KL)		;UPDATE COUNT -- POINT AT LAST,,FIRST
	TLNN	B,-1		;AT THE END???
	HRLM	C,(A)		;YES
	POPJ	P,
NX1:	HRRZ	A,(A)
	TLNN	C,-1		;END OF LIST
	JRST	NI		;YES -- PUT AT END
	MOVSS	C
	JRST	ISCH		;GO LOOK SOME MORE
NEWINS:	NNCELL	(A)
	SETZM	(A)
	HRRZM	A,(KL)		;IT USED TO BE NULL
	JRST	NI
IHEDLS:	MOVE	TABL,GOGTAB
	SKIPN	A,(KL)		;INSERT AT HEAD
	JRST	NEWINS
	JRST	NI		
ITAILS:	
	MOVE	TABL,GOGTAB	;
	SKIPN	A,(KL)		;INSERT AT TAIL
	JRST	NEWINS
	MOVS	A,(A)
	JRST	NI
DELTLE:
DELTSE:	SKIPN	A,(KL)		;GET SET DESCRIPTOR
	POPJ	P,		;NULL ALREADY
	MOVE	C,(A)
DSCH:	MOVE	C,(C)
	TLC	C,(B)
	TLNN	C,-1		;WAS IT THIS ONE???
	JRST	DIT		;YES
	TRNN	C,-1		;END OF SEARCH
	POPJ	P,		;YES
	MOVE	A,(A)		;LINK
	JRST	DSCH		;GO LOOK
DIT:	MOVE	TABL,GOGTAB
	MOVE	B,(A)		;B PTR TO THIS CELL
	HRRM	C,(A)		;LINK PREV TO NEXT
	HRL	C,FP1(TABL)	;OLD FREE LIST
	HLRM	C,(B)		;LINK CELL
	HRRM	B,FP1(TABL)	;
	HRLZI	B,-1		;ADJUST DESCRIPTOR
	ADDB	B,(KL)
	TLNE	B,-1		;LIST NULL NOW???
	JRST	CKEND		;NO
	SETZM	(KL)		;YES
	MOVSS	(B)		;LAST,,FIRST CELL 
	HRRM	B,FP1(TABL)	;NEW FREE LIST
	POPJ	P,
CKEND:	TRNN	C,-1		;WAS THIS THE END
	HRLM	A,(B)		;YES
	POPJ	P,
REMCAR:	SKIPN	A,(KL)
	POPJ	P,		;IF WAS NULL RETURN A 0
	MOVE	C,(A)
	MOVE	C,(C)		;FIRST REAL LIST CELL
	HLRZ	B,C		;FIRST ONE
	PUSH	P,B		;SAVE IT
	PUSHJ	P,DIT
	POP	P,A		;VALUE
	POPJ	P,
HERE(URSCHD)
	MOVE	PB,RUNNER
	SKIPL	STATUS(PB)		;
	JRST 	FOTR			;GO FIND ONE TO RUN
	MOVNS	STATUS(PB)		;SET TO READY
SPSRN1:	SETZM	REASON(PB)		;OTHER ACS NOT SAVED
SPSRN2:	POP	P,PCW(PB)		;DITTO -- BUT LEAVE REASON INTACT
	MOVEM	P,ACP(PB)
	MOVEM	SP,ACSP(PB)
	MOVEM	RF,ACF(PB)		
FOTR:	HRRZ	B,GOGTAB
	TLO	B,-NPRIS
	MOVEI	A,1			;READY
SCHLIS:	SKIPN	PB,PRILIS(B)		;SEARCH DOWN THIS LIST
	JRST	NXLIS			;LIST IS EMPTY
TRYTHS:	CAMN	A,STATUS(PB)		;IS THIS READY
	JRST	SCDTHS			;YES -- DO HIM
	HRRZ	PB,PLISTE(PB)		;LINK DOWN LIST
	JUMPN	PB,TRYTHS		;IF ANY LEFT AT THIS LEVEL,TRY
NXLIS:	AOBJN	B,SCHLIS		;SEARCH LIST
NOTENX<
IFE APRISW <
	IMSKCL	1,[-1]			;MASK OFF ALL INTERRUPTS
	SKIPE	INTRPT			; A RECENT INTERRUPT
	JRST	[INGOSC: SETZM INTRPT	;GO TRY AGAIN TO SCCHEDULE
			IMSKST 1,[-1]
			JRST	FOTR ]
	INTENS	B,			;GET INTERRUPT ENABLING
	TLNN	B,775204		;IS HE ENABLED FOR SOMETHING
	ERR <NO ONE TO RUN>,1,INGOSC	;NO
	IMSTW	[-1			;WAIT FOR AN INTERRUPT
		1]
	SETZM	INTRPT			;ZERO THE FLAG
>;IFE APRISW
IFN APRISW <
	SKIPN	INTRPT
	ERR <NO ONE TO RUN>,1
	SETZM	INTRPT
>;IFN APRISW
>;NOTENX
TENX<
	SKIPN	INTRPT
	  ERR <NO ONE TO RUN>,1
	SETZM	INTRPT
>;TENX
	JRST	FOTR			;FIND SOMEONE TO RUN
SCDTHS:	
	SKIPE	A,PLISTE(PB)		;ONLY ONE ON THE LIST?
	TRNN	A,-1			;ALREADY AT END?
	JRST	RDYTHS			;YES
	HLLM	A,PLISTE(A)		;PREV(NEXT(ME))←PREV(ME)
	MOVS	C,A			;NEXT(ME),,PREV(ME)
	TRNE	C,-1			;ANY PREV?
	HLRM	C,PLISTE(C)		;YES -- NEXT(PREV(ME))←NEXT(ME)
	TLNE	A,-1			;WAS I FIRST?
	HRR	A,PRILIS(B)		;NO -- FIRST WILL STAY FIRST
	HRL	A,PB			;NEW OWNER -- ME,,NEW FIRST
	EXCH	A,PRILIS(B)		;GET OLD LAST,,FIRST
	HLLZM	A,PLISTE(PB)		;MY NEW ENTRY IS OLD LAST,,0
	MOVS	A,A			;    XXX,,OLD LAST
	HRRM	PB,PLISTE(A)		;POINT AT ME
RDYTHS:	SETOM 	STATUS(PB)		;RUNNING
	HRRM 	PB,RUNNER		;SAY SO
	MOVE	USER,GOGTAB
	MOVE	A,QUANTM(PB)
	MOVEM	A,TIMER(USER)
	SKIPE	A,REASON(PB)
	JRST	@SPCASE(A)		;SOME SPECIAL CASE
RPSPF:	MOVE	P,ACP(PB)		;GET THE NEEDED REGISTERS
	MOVE	SP,ACSP(PB)
	MOVE	RF,ACF(PB)
	JRST	@PCW(PB)		;GO START RUNNING THE SO AND SO
SPCASE:	RPSPF				;0 THEN RESTORE P, SP, F
	RSTACS				;1 THEN RESTORE ALL ACS
	RPSPF				;2 THEN FROM JOINER
	RST1				;3 THEN FROM INTERROGATE
RSTACS:	MOVE	P,ACP(PB)		;PUT THE RETURN ADDRESS ON THE STACK
	PUSH	P,PCW(PB)
	MOVEM	P,ACP(PB)
	HRLZI	P,AC0(PB)
	BLT	P,P			;RESTORE THE OLD ACS
	POPJ	P,			;GO RUN
RST1:	MOVE	A,AC1(PB)		;RESTORE REG 1 , SP,P,F
	JRST	RPSPF
HERE(RESUME)
	MOVE	USER,RUNNER	;TAKE CARE OF RET ADDRS
	POP	P,PCW(USER)
	POP	P,OPTS		;OPTIONS
	POP	P,A		;RETURN VALUE
	POP	P,C		;WHO
	MOVE	TEMP,GOGTAB	;
	LDB	B,INFOTAB(TEMP)	;TEST THE TYPE
	CAIE	B,PRCTYP	;IS THE TYPE A PROCESS
	 JRST	[	MOVEI	LPSA,ER.NPI
		RESERR:	MOVSI	TEMP,[ASCIZ/RESUME/]
			PUSH	P,PCW(USER)	;ENTRY CONVENTION OF ER.ITN
			JRST	(LPSA)]
	MOVE	PB,@DATAB(TEMP)	;GET THE DATUM
	TLNE	PB,TERM		;WAS IT TERMINATED?
	 JRST	[MOVEI	LPSA,ER.TRP
		JRST	RESERR]
	MOVE	B,PRCITM(USER)	;MY NAME
	MOVEM	B,RSMR(PB)	;REMEMBER CALLER
	SKIPE	STATUS(PB)	;HIS STATUS BETTER BE 0
	 JRST	[MOVEI	LPSA,ER.SUS
		JRST	RESERR]
	JUMPN	OPTS,NS.RSM	;NONSTANDARD IF JUMP
	SETZM	STATUS(USER)
RSM.H:	SETOM	STATUS(PB)
	MOVEM	P,ACP(USER)	;SAVE NEEDFUL REGISTERS
	MOVEM	RF,ACF(USER)
	MOVEM	SP,ACSP(USER)
	SETZM	REASON(USER)	;ONTL P, SP, F IMPORTANT
	MOVEM	PB,RUNNER	;
	MOVE	C,REASON(PB)	;
	JRST	@SPCASE(C)	;GO FIRE HIM UP
NS.RSM:	TRNN	OPTS,MSTMSK	;FUNNYNESS IN MY NEW STATUS?
	JRST	RSM.4		;NO -- IT MUST BE NOTNOW
	LDB	D,MSTBYT	;GET INDEX
	JRST	@[ RSM.1	;I GO READY
		  RSM.3		;I DIE
		  RSM.4		;I WANT TO KEEP RUNNING
		]-1(D)		;SELECT
RSM.1:	TRNN	OPTS,NOTNOW	;HE RUNS?
	JRST	RSM.2		;YES
	AOS	STATUS(PB)	;MAKE HIM READY
	MOVE	B,REASON(PB)	;WERE ALL REGISTERS SAVED
	CAIN	B,1		;
	JRST	RSM.01		;YES
	MOVEM	A,AC1(PB)	;
	MOVEI	A,3
	MOVEM	A,REASON(PB)	;A IS IMPORTANT
RSM.01:	PUSH	P,PCW(USER)	;RET AD
	JRST	URSCHD		;RESCHEDULE
RSM.2:	MOVNS	STATUS(USER)	;
	JRST	RSM.H		;GO GET HIM GOING
RSM.3:	MOVE	B,REASON(PB)	;
	CAIN	B,1		;ALL ACS SAVED?
	JRST	RSM.3X		;YES
	MOVEM	A,AC1(PB)	;SAVE A
	MOVEI	A,3		;
	MOVEM	A,REASON(PB)	;
RSM.3X:	TRNE	OPTS,NOTNOW	;HE RUNS?
	JRST	RSM.03		;YES
	AOS	STATUS(PB)	;NO - I CAN COMMIT SUICIDE
	MOVE	PB,USER		;
	JRST	TERMPB		; I DIE
RSM.03:	MOVE	B,ACP(PB)	;
	MOVEI	C,RSM.T		;
	EXCH	C,PCW(PB)	;FIRST HE WILL KILL ME
	PUSH 	B,C		;
	PUSH	B,PB		;
	MOVEM	B,ACP(PB)	;THE TERMPB POPJ WILL CONTINUE HIM
	JRST	RSM.H		;GO FIRE THE DEAR BOY UP
RSM.4:	AOS	STATUS(PB)	;GET HIM READY
	MOVE	B,REASON(PB)	;SHOULD WE SAVE 1
	CAIE	B,1		;
	JRST	@PCW(USER)	;I GO ON MY WAY
	MOVEM	A,AC1(PB)	;SAVE IT
	MOVEI	A,3		;
	MOVEM	A,REASON(PB)	;
	JRST	@PCW(USER)	;
RSM.T:	MOVE	PB,(P)		;
	PUSHJ	P,TERMPB	;
	MOVE	PB,1(P)		;TERMPB BACKED UP THE STACK
	POP	P,PCW(PB)	;RET AD
	MOVE	C,REASON(PB)	;
	JRST	@SPCASE(C)	;GO DO RIGHT THING ABOUT ACS
ER.SUS:	HRRI	TEMP,[ASCIZ/Non-suspended process/]
	JRST	ER.ITN
ER.TRP:	TROA	TEMP,[ASCIZ/Terminated process/]
ER.NPI:	HRRI	TEMP,[ASCIZ/Non-process item/]
ER.ITN:
	MOVE	LPSA,RUNNER	;STORE STATE
	POP	P,PCW(LPSA)	;RETURN WORD
	MOVEM	P,ACP(LPSA)
	MOVEM	SP,ACSP(LPSA)
	MOVEM	RF,ACF(LPSA)
	MOVEI	LPSA,(C)	;ITEM NUMBER (ERRSPL USES FF THRU D)
	ERRSPL	1,[[ASCIZ/
@A: @A #@D/]
		PLEFT	TEMP	;routine
		PRIGHT	TEMP	;msg
		PRIGHT	LPSA]	;item number
	MOVE	PB,RUNNER	;TRY TO IGNORE THE CALL THAT GAVE THE ERROR
	SETZ	A,		;RETURN 0 (=ANY) IF IT MATTERS
	JRST	RPSPF		;RESTORE P, SP, F AND CONTINUE
HERE(SUSPEND)
	MOVE	C,-1(P)		;THE ITEM
	POP	P,-1(P)		;BACK UP RETN ADDR
	MOVSI	TEMP,[ASCIZ/SUSPEND/]
	MOVE	TABL,GOGTAB	;
	LDB	B,INFOTAB(TABL)
	CAIE	B,PRCTYP	;BE SURE A PROCESS ITEM
	 JRST	ER.NPI
	MOVE	PB,@DATAB(TABL)
        TLNE	PB,TERM		;IF TERMINATED , 
	 JRST	ER.TRP
	CAME	PB,RUNNER	;IS IT THE RUNNER
	JRST	OTHGUY		;NO
	SETZM	STATUS(PB)
	JRST	SPSRN1		;GO RESCHEDULE
OTHGUY:	MOVEI	A,SPNDR		;HE MUST HAVE BEEN READY
	SKIPE	STATUS(PB)	;IF HE WASNT SUSPENDED
	MOVEM	A,REASON(PB)	;THE REGISTERS MUST BE RESTORED
	SETZM	STATUS(PB)	;BE SURE
	MOVEI	A,ITMANY	;GET THE ITEM ANY
	POPJ	P,
HERE(TERMINATE)
	MOVE	C,-1(P)
	MOVE	TABL,GOGTAB	;
	LDB	B,INFOTAB(TABL)	;IS HE A PROCESS
	CAIE	B,PRCTYP
	 JRST	[	MOVSI	TEMP,[ASCIZ/TERMINATE/]
		NPIPOP:	POP	P,-1(P)	;MOVE RETURN WORD BACK
			JRST	ER.NPI]
	MOVE	PB,@DATAB(TABL)	;POINT AT PROCESS
	TLNE	PB,TERM		;ALREADY DEAD
	JRST	RET1		;YES
↑TERMPB:
	MOVE	USER,RUNNER	;COME HERE IF PB LOADED
	CAMN	PB,USER		;IS IT ME THAT IS TO DIE?
	JRST	KILLIT		;YES
	PUSH	P,PRIOR(USER)	;I AM ABOUT TO GET HIGH PRIORITY
	PUSHJ	P,REMPRI
	MOVEI	A,MAXPRI	;
	PUSHJ	P,SETPRI
	MOVEI	A,FIXPRI
	MOVEM	A,PCW(USER)
	MOVEM	P,ACP(USER)
	MOVEM	RF,ACF(USER)
	MOVEM	SP,ACSP(USER)
	MOVE	RF,ACF(PB)
	MOVE	P,ACP(PB)
	MOVE	SP,ACSP(PB)
	MOVEI	A,1		;NOW FIX STATUS
	MOVEM	A,STATUS(USER)	;
	MOVNM	A,STATUS(PB)
	MOVEM	PB,RUNNER	;THE NEW RUNNER
KILLIT:	MOVEI	LPSA,SPRPDA	;THE SPROUTER IS WHERE WE GO BACK TO
	PUSHJ	P,STKUWD	;UNWIND THE STACK
	JRST	CALRET		;GO DIE 
FIXPRI:	PUSHJ	P,REMPRI
	POP	P,A		;REAL PRIORITY
	PUSHJ	P,SETPRI
RET1:	SUB	P,[XWD 2,2]	;GET OFF THE PARAMETER
	JRST	@2(P)		;RETURN
HERE(JOIN)
	MOVE	PB,RUNNER
	MOVE	B,-1(P)		;THE SET 
	POP	P,-1(P)		;FOR LATER
	JUMPE	B,CPOPJ		;
	MOVE	TABL,GOGTAB	;GET READY FOR CELL GETTING
	HRRZ	A,(B)		;A NOW POINTS AT FIRST
	HRLZ	D,PRCITM(PB)	;THE PROCESS ITEM OF THE JOIN
JNST:	HLRZ	C,(A)		;THE ITEM NUMBER
	LDB	B,INFOTAB(TABL)	;GET TYPE
	CAIE	B,PRCTYP	;PROCESS?
	 JRST	[MOVSI	TEMP,[ASCIZ/JOIN/]
		JRST	ER.NPI]
	MOVE	B,@DATAB(TABL)	;GET DATUM
	TLNE	B,TERM		;DEAD ???
	JRST	NXTJNR		;YES
	AOS	JOINCT(PB)	;ONE MORE TO DIE
	NNCELL	(C)		;GET (POSSIBLY FIRST) NEW CELL
	HRR	D,JOINS(B)	;LINK TO OLD JOIN LIST
	MOVEM	D,(C)		;NEW CONTENTS OF THIS CELL
	HRRZM	C,JOINS(B)	;NEW JOIN LIST
NXTJNR:	HRRZ	A,(A)		;GET NEXT ENTRY
	JUMPN	A,JNST
	SKIPG	JOINCT(PB)	;DO WE NEED TO WAIT?
	POPJ	P,		;NO
	MOVEI	A,JOINR		;REASON IS A JOIN
	MOVEM	A,REASON(PB)	;
	SETZM	STATUS(PB)	;I AM SUSPENDED
	JRST	SPSRN2		;GO SAVE P,RF,SP & RUN SOMEONE
HERE(MAINPR)
	MOVE	USER,GOGTAB
	SKIPE	GGDAD(USER)	;INITIALIZED ALREADY
	POPJ	P,		;YES
	MOVEI	C,NPVARS+40	;HOW MUCH SPACE WE NEED
	PUSHJ	P,CORGET
	ERR	<NO ROOM FOR THE MAIN PROCESS>
	HRRZ	PB,B		;PROCESS BASE
	MOVE	A,SPDL(USER)	;STRING PDL
	MOVEM	A,ISP(PB)
	SETOM	DYNL(PB)
	HLROI	A,SPRPDA
	MOVEM	A,STATL(PB)
	MOVEM	PB,GGDAD(USER)
	MOVEM	PB,RUNNER	;SAY THIS IS THE RUNNER
	HRLZI	A,ZFIRST(PB)
	HRRI	A,ZFIRST+1(PB)
	SETZM	ZFIRST(PB)
	BLT	A,ZLAST(PB)
	MOVEI	C,MAINPI	;THE MAIN PROCESS ITEM NUMBER
	MOVEI	A,PRCTYP	;MAKE A PROCESS
	DPB	A,INFOTAB(USER)
	HRRZM	PB,@DATAB(USER)
	MOVEM	C,PRCITM(PB)
	SETZM	KLOWNR(PB)	;NASTY
	SETOM	STATUS(PB)	;I AM THE RUNNER
	MOVEI	A,STPSZ		;SET DEFAULTS
	MOVEM	A,DEFPSS	;P STACK
	MOVEI	A,STSPST	;
	MOVEM	A,DEFSSS	;SP STACK
	MOVEI	A,STDQNT	;
	MOVEM	A,DEFQNT	;QUANTUM
	MOVEM	A,QUANTM(PB)	;
	MOVEI	A,STDPRI	;STANDARD PRIORITY
	MOVEM	A,DEFPRI	;PRIORITY
	PUSHJ	P,SETPRI	;SET THE PRIORITY
	PUSH	P,[%SPGC]
	PUSHJ	P,SGREM
	PUSH	P,[%ARRSRT]
	PUSHJ	P,SGREM
	PUSH	P,[%PSSGC]
	PUSH	P,[SGLKBK+1]
	PUSHJ	P,SGINS
	POPJ	P,
HERE(CALLER)
	JSP	TEMP,PDG
	 JRST	[MOVSI	TEMP,[ASCIZ/CALLER/]
		JRST	NPIPOP]
	TLNE	A,TERM
	 JRST	[	MOVSI	TEMP,[ASCIZ/CALLER/]
		TRPPOP:	POP	P,-1(P)	;BACK UP RETURN WORD
			JRST	ER.TRP]
	MOVE	A,RSMR(A)
C.XIT1:	EXCH	C,-1(P)
C.XIT:	SUB	P,X22
	JRST	@2(P)
HERE(MYPROC)
	MOVE	USER,RUNNER
	MOVE	A,PRCITM(USER)
	POPJ	P,
HERE(PSTATUS)
	JSP	TEMP,PDG
	 JRST	[MOVSI	TEMP,[ASCIZ/PSTATUS/]
		JRST	NPIPOP]
	TLNN	A,TERM
	SKIPA	A,STATUS(A)
	MOVEI	A,2
	JRST	C.XIT1
PDG:	EXCH	C,-1(P)		;ITEM NUMBER
	MOVE	USER,GOGTAB
	LDB	A,INFOTAB(USER)
	CAIE	A,PRCTYP
	JRST	(TEMP)		;WAS NOT A PROC ITEM
	MOVE	A,@DATAB(USER)
	JRST	1(TEMP)		;RETURN
HERE(PRISET)
	MOVE	C,-2(P)		;ITEM
	MOVE	TABL,GOGTAB	;
	LDB	A,INFOTAB(TABL)
	CAIE	A,PRCTYP
	 JRST	[	MOVEI	LPSA,NPIPOP
		PRIERR:	MOVSI	TEMP,[ASCIZ/PRISET/]
			POP	P,-1(P)
			JRST	(LPSA)]
	MOVE	PB,@DATAB(TABL)	;GET DATUM
	TLNE	PB,TERM
	 JRST	[MOVEI	LPSA,TRPPOP
		JRST	PRIERR]
	PUSHJ	P,REMPRI	;TAKE OFF MY LIST
	MOVE	A,-1(P)
	CAIG	A,17		;CHECK BOUNDS
	CAIGE	A,0
	 JRST	[MOVEI	LPSA,ER.IPR
		JRST	PRIERR]
	PUSHJ	P,SETPRI
RET.3:	SUB	P,X33
	JRST	@3(P)
ER.IPR:	HRRI	TEMP,[ASCIZ/Illegal priority/]
	POP	P,-1(P)
	POP	P,-1(P)
	JRST	ER.ITN
HERE(%PSSGC)
	MOVE	TEMP,RUNNER
	MOVEM	SP,ACSP(TEMP)
	MOVEM	RF,ACF(TEMP)
	HRLZI	B,-NPRIS
	HRR	B,GOGTAB
SCHL1:	SKIPN	TEMP,PRILIS(B)
	JRST	NXLS
	PUSH	P,B
SCHL2:	MOVE	RF,ACF(TEMP)
	PUSH	P,TEMP
	PUSHJ	P,%ARSR1
	MOVE	TEMP,(P)
	HRRZ	A,ISP(TEMP)
	MOVE	SP,ACSP(TEMP)
	PUSHJ	P,%SPGC1
	POP	P,TEMP
	HRRZ	TEMP,PLISTE(TEMP)
	JUMPN	TEMP,SCHL2
	POP	P,B
NXLS:	AOBJN	B,SCHL1
	MOVE	TEMP,RUNNER
	MOVE	RF,ACF(TEMP)
	MOVE	SP,ACSP(TEMP)
	POPJ	P,
HERE(DDFINT)			;DO DEFERRED INTERRUPT
	SKIPE	NOPOLL		;IGNORING IT?
	POPJ	P,		;YES
	SETZM	INTRPT		;
	MOVE	USER,RUNNER	;NEED TO SAVE ACS
	POP	P,PCW(USER)	;SAVE PC WORD
	MOVNS	STATUS(USER)	;READY
	MOVEI	TEMP,AC0(USER)	;
	BLT	TEMP,ACP(USER)	;
	MOVEI	A,1		;NEED ALL ACS
	MOVEM	A,REASON(USER)	;
	JRST	FOTR		;SEE WHOM TO RUN
HERE(INTSET)
	MOVE	USER,GOGTAB	;
	SKIPE	DISPAT(USER)	;HAVE TABLES???
	JRST	.+3		;YES
	PUSH	P,[=128]	;DEFAULT BUFFER SIZE
	PUSHJ	P,INTTBL	;GO GET EM
	PUSH	P,-2(P)		;ITEM
	PUSH	P,[INTPDA]	;INTERRUPT PROCEDURE
	MOVE	A,-2(P)		;GET OPTIONS
	TRZ	A,SPNDME	;SET UP STATUS FIELD
	TRO	A,SPNDNP+RUNME	;
	PUSH	P,A		;
	PUSH	P,[0]		;NO KILL SET
	PUSHJ	P,SPROUT	;SPROUT IT
	MOVE	C,-2(P)		;THE ITEM
	MOVE	A,@DATM
	MOVE	USER,GOGTAB
	MOVEM	A,INTPRC(USER)	;REMEMBER INTERRUPT PROCESS BASE
	MOVE	A,-1(P)		;
	TRNE	A,PRIMSK	;DID HE SPEC A PRIORITY
	JRST	POK
	PUSH	P,C		;ITEM
	PUSH	P,[0]
	PUSHJ	P,PRISET	;SET THE PRIORITY
POK:
	SUB	P,X33
	JRST	@3(P)
HERE(CLKMOD)
	MOVE	USER,GOGTAB	;
	SOSG	TIMER(USER)	;IF COUNTDOWN COMPLETE THEN
	SETOM	INTRPT		;SIGNAL THE INTERRUPT
	POPJ	P,		;LET CALLER DISMIS
DEFINE QW(VALAC,WPAC,RPTR,WTOP,WBOT,OVINST) <
	MOVEM	VALAC,(WPAC)
	ADDI	WPAC,1
	CAMLE	WPAC,WTOP
	MOVE	WPAC,WBOT
	CAMN	WPAC,RPTR
	OVINST
	>
DEFINE QR(VALAC,WPTR,RPAC,WTOP,WBOT,OVINST) <
	CAMN	RPAC,WPTR
	OVINST
	MOVE	VALAC,(RPAC)
	ADDI	RPAC,1
	CAMLE	RPAC,WTOP
	MOVE	RPAC,WBOT
	>
DEFINE IQW(VAC) <
	QW(VAC,11,<INTQRP(USER)>,<INTQWT(USER)>,<INTQWB(USER)>,< JRST IQWOV >)
	>
HERE(DFR1IN)
	MOVE	USER,GOGTAB	;SO CAN CALL ANY TIME
	MOVE	11,INTQWP(USER)
	IQW	1
	IQW	6
NOTENX<
	MOVE	TEMP,XJBCNI
	IQW	TEMP
	MOVE	TEMP,XJBTPC
	IQW	TEMP
>;NOTENX
TENX<
	MOVE	TEMP,-5(P)
	IQW	TEMP
	MOVE	TEMP,-4(P)
	IQW 	TEMP
>;TENX
	MOVE	TEMP,RUNNER
	IQW	TEMP
	MOVE	1,-1(P)
VILOOP:	MOVE	TEMP,(1)
	IQW	TEMP
	AOBJN	1,VILOOP
	MOVEM	11,INTQWP(USER)
	SETOM	INTRPT
	SKIPN	7,INTPRC(USER)	;INTERRUPT PROCESS
	JRST	DF.X
	MOVEI	TEMP,1		;READY
	SKIPL	STATUS(7)
	MOVEM	TEMP,STATUS(7)
DF.X:	SUB	P,X22
	JRST	@2(P)
IQWOV:	ERR	<DRYROT IN INTMOD -- WRITER>
	JRST	DF.X
HERE(DFRINT)
	PUSH	P,@DFRINF(USER)
	PUSHJ	P,DFR1IN
	POPJ	P,
DEFINE IQR(AC) <
	QR	(AC,<INTQWP(USER)>,D,<INTQWT(USER)>,<INTQWB(USER)>,<JRST QRERR>)
	>
HERE(INTPRO)
	PUSH	P,RF
	PUSH	P,INPDA0
	PUSH	P,SP
	MOVE	USER,GOGTAB
DO1INT:	MOVE	D,INTQRP(USER)	;READER OF THE QUEUE
	QR	(1,<INTQWP(USER)>,D,<INTQWT(USER)>,<INTQWB(USER)>,< JRST ALDCIS >);
	IQR	6
	IQR	TEMP
	MOVEM	TEMP,IJBCNI(USER)
	IQR	TEMP
	MOVEM	TEMP,IJBTPC(USER)
	IQR	TEMP
	MOVEM	TEMP,IRUNNR(USER)
	IQR	B
	SOJLE	B,DISDFI
DO1I.1:	
	IQR	C
	MOVEM	D,INTQRP(USER)
	SOJLE	B,DO1I.2
	PUSH	P,C
	JRST	DO1I.1
DO1I.2:	HLRZ	D,C		
	CAIN	D,-1		;IS THIS A PDA
	JRST	DO1I.4		;NO -- JUST ISSUE THE CALL
	TLNN	C,-1		;WAS THERE A CONTEXT??
	JRST	DO1I.3		;NO
	MOVS	D,C		;PDA,,STATIC LINK
	HRRZ	TEMP,PD.PPD(C)	;PARENTS PDA
	PUSH	P,[ DO1INT]
	PUSH	P,RF
	HLRZ	LPSA,1(D)	;THE PDA IIN THE STACK
	CAIE	LPSA,TEMP	;BETTER BE THE SAME
	ERR	<ATTEMPT TO REFERENCE A NON-EX ENVIRONMENT IN INTPRO >
	PUSH	P,D		;STATIC LINK
	PUSH	P,SP		;SAVE SP
	HLRZ	C,PD.PPD	;END OF MKSEMT
	JRST	(C)
DO1I.3:	HRRZ	C,PD.(C)	;ENTRY ADDRESS
DO1I.4:	PUSHJ	P,(C)		;CALL THE PROCEDURE
	JRST	DO1INT
ALDCIS:	MOVE	PB,RUNNER	;ALL DONE CURRENT INTERRUPTS
	SETZM	STATUS(PB)	;SUSPEND SELF
	PUSHJ	P,SPSRN1
	JRST	DO1INT
QRERR: ERR	<DRYROT IN INTPRO -- READER>
	JRST 	ALDCIS
DISDFI:	ERR	<STRANGENESS IN DEFERRED INTERRUPT>,1
	JRST	DO1INT
DEFINE IPDE(X,V), < PUTINLOC(INTPDA+X,V) >
INTPDA: BLOCK PD.XXX+1
	IPDE	(PD.,INTPRO)
	IPDE	(PD.DSW,3)
	IPDE	(PD.PDA,<<INPDA0: XWD INTPDA,0>>)
	IPDE	(PD.LLW,<INTPDA+PD.XXX>)
	IPDE	(PD.DLW,<INTPDA+PD.XXX>)
HERE(DFCPKT)
	SKIPE	B,-4(P)		;DID USER GIVE ME A BLOCK
	JRST	DFC.1		;YES
	MOVEI	C,5
	PUSHJ	P,CORGET
	ERR	<NO CORE LEFT>
DFC.1:	HRLI	B,-5
	MOVE	A,B		;AOBJN PTR
	SUB	B,X11		;READY FOR PUSHES
	PUSH	B,[5]
	PUSH	B,-3(P)
	PUSH	B,-2(P)
	PUSH	B,-1(P)
	PUSH	B,[XWD -1,CAUSE]
	SUB	P,[XWD 5,5]
	JRST	@5(P)		;RETURN
HERE(CAUSE)
	MOVE	PB,RUNNER
	AOS	A,CAUSES(PB)
	CAIE	A,1		;FIRST CAUSE?
	JRST	DFRCS		;NO -DEFER IT
	POP	P,CAUSRA(PB)	;SAVE RETN ADDRESS
CSIT:	PUSHJ	P,CAUSE1	;DO THE WORK
	MOVE	PB,RUNNER
	SOSG	A,CAUSES(PB)	;DONE ONE
	JRST	CSE.X		;ALL ARE DONE -- CHECK FOR SCHED REQ
	MOVEI	KL,CAUSEQ(PB)	;GET NEXT FROM QUEUE
	PUSHJ	P,REMCAR
	HLRZ	B,(A)		;PICK UP TYPE
	PUSH	P,B
	HRRZ	B,(A)		;NOTICE
	PUSH	P,B
	PUSH	P,1(A)		;OPTIONS
	MOVE	TABL,GOGTAB
	HRR	B,FP2(TABL)	;RELEASE 2 WD BLOCK
	HRRM	B,(A)
	HRRM	A,FP2(TABL)
	JRST	CSIT		;GO WORK ON THIS
DFRCS:	MOVE	TABL,GOGTAB	;
	NNCLL2	(B)		;GET 2 WD CELL
	POP	P,TMP		;RETURN ADDRESS
	POP	P,1(B)		;OPTS
	POP	P,(B)		;NOTICE
	POP	P,A		;TYPE
	HRLM	A,(B)
	MOVEI	KL,CAUSEQ(KL)	;PUT ON CAUSE QUEUE
	PUSHJ	P,ITAILS	;PUT ON TAIL OF QUEUE
	JRST	(TMP)		;RETURN
CSE.X:	MOVE	USER,GOGTAB
	SKIPN	SCHDRQ(USER)	;SCHEDULING REQUEST
	JRST	@CAUSRA(PB) 	;NO
	SETZM	SCHDRQ(USER)	;YES
	PUSH	P,CAUSRA(PB)	;YES
	JRST	URSCHD		;RESCHEDULE
HERE(CAUSE1)
CSE1:	JSP	TMP,EVTCK3	;VERIFY THAT THIS IS AN EVENT ITEM
	SKIPE	PDA,CAUSEP(EVT)	;DID THE USER SAY SOMETHING???
	JRST	USPPRC		;USER SPEC PROCEDURE
	MOVE	FF,-1(P)	;OPTIONS
	SKIPN	TMP,WAITLS(EVT)	;WAS ANYONE WAITING?
	JRST	SCA.2		;NO
	MOVE	TEMP,B		;EV TYP NO
	MOVE	TMP,(TMP)	;LAST,,FIRST
	MOVE	D,-2(P)		;NOTICE NO
SCA.1:	MOVE	TMP,(TMP)	;WAIT ENTRY
	HLRZ	C,TMP		;PROCESS NO
	MOVE	TABL,GOGTAB	;SET TABL TO RIGHT THING
	PUSHJ	P,ANSWR1	;SPECIAL ENTRY POINT IN ANSWER
	TRNE	A,NOJOY		;DID WE SUCCEED??
	JRST	SCA.1A		;NO
	TRNN	A,RETAIN	;KEEP THE NOTICE??
	TRO	FF,DNTSAV	;YES
	TRNN	FF,TELLAL	;TELL THE WHOLE WORLD?
	JRST	SCA.2		;NO
SCA.1A:	TRNE	TMP,-1		;ANY LEFT
	JRST	SCA.1		;YES
SCA.2:	TRNE	FF,DNTSAV	;SAVE IT?
	JRST	SCA.3		;NO
	MOVE	B,-2(P)		;ITEM NO OF NOTICE
	MOVEI	KL,NOTCLS(EVT)	;
	PUSHJ	P,ITAILS	;PUT ON END OF NOTIICE LIST
SCA.3:
	MOVE	USER,GOGTAB
	TRNE	FF,SCHDIT	;WANT TO RESCHEDULE
	SETOM	SCHDRQ(USER)	;RESCHEDULE REQUEST
SCA.X:	SUB	P,X44		;RETURN
	JRST	@4(P)
USPPRC:	MOVE	B,PD.(PDA)	;HERE IF USER SPECIFIED A PROCEDURE
	TLNN	PDA,-1		;CONTEXT GIVEN
	JRST	(B)		;NO
	PUSH	P,RF		;SET UP CONTEXT
	HRRZ	C,PD.PPD	;PARENTS PDA
	MOVS	A,PDA		;
	HLRZ	D,1(A)
	CAME	D,C		;SAME?
	ERR 	<CONTEXT WRONG OR CLOBBERED IN INTERP CALL
USER SPEC EVENT PROC >
	PUSH	P,A		;STATL
	PUSH	P,SP
	HLRZ	B,PD.PPD(PDA)
	JRST	(B)		;GO TO INSTR AFTER THE MKSEMT
HERE(ANSWER)
	MOVE	TEMP,-3(P)	;EV TYPE
	POP	P,-3(P)		;RET ADRS
	POP	P,C		;PROCESS ITEM
	POP	P,D		;NOTICE
	MOVE	TABL,GOGTAB
	LDB	B,INFOTAB(TABL)
	CAIE	B,PRCTYP
	 JRST	[MOVSI	TEMP,[ASCIZ/ANSWER/]
		JRST	ER.NPI]
ANSWR1:	MOVE	PB,@DATAB(TABL)	;THE PROCESS BASE
	TLNN	PB,TERM		;TERMINATED?
	SKIPE	STATUS(PB)	;OR NOT SUSPENDED??
	JRST	NOANS		;YES
	AOS	STATUS(PB)	;MAKE READY
	MOVEM	D,AC1(PB)
ANSWR2:	PUSHJ	P,DELWRQ	;DELETE ALL WAIT REQUESTS
	MOVE	A,INTRGC(PB)	;THE INTERROG CONTROL WORD
	TRNN	A,SAYWCH	;ASKED FOR THE ASSOCIATION
	POPJ	P,		;NO
	PUSH	P,[EVTYPI]	;
	PUSH	P,D
	PUSH	P,TEMP
	PUSHJ	P,STACSV	;SAVE ALL ACS
	MOVEI	5,16		;MAKE
	PUSHJ	P,LEAP
	PUSHJ	P,STACRS	;GET ACS BACK
	POPJ	P,
NOANS:	TRO	A,NOJOY
	POPJ	P,		;RETURN
DELWRQ:	SKIPN	A,WAITES(PB)
	POPJ	P,
	PUSH	P,KL
	MOVE	A,(A)		;A IS LAST,,FIRST
DTHSRQ:	MOVE	A,(A)		;NEXT ENTRY
	HLRZ	C,A		;ITEM NUMBER OF TYPE
	PUSH	P,A		;FOR SAFE KEEPING
	MOVE	TABL,GOGTAB	;
GLOB <
	CAIL	C,GBRK		;GLOBAL ??
	MOVEI	TABL,GLUSER	;
>;GLOB
	MOVE	A,@DATAB(TABL)
	MOVEI	KL,WAITLS(A)
	MOVE	B,PRCITM(PB)
	PUSHJ	P,DELTLE	;DELETE ELEMENT
	POP	P,A		
	TRNE	A,-1		;ANY LEFT
	JRST	DTHSRQ		;YES
	MOVE	A,WAITES(PB)
	MOVE	TABL,GOGTAB
	HLRZ	B,(A)		;ADDRESS OF LAST
	HRRZ	C,FP1(TABL)
	HRRM	C,(B)		;RELEASE THE LOT
	HRRM	A,FP1(TABL)
	SETZM	WAITES(PB)	;NONE LEFT
	POP	P,KL
	POPJ	P,
HERE(INTERROGATE)
	SKIPN	B,-2(P)		;SET OR ITEM
	ERR	<NULL INTERROGATION???>
	TLNN	B,-1		;SET?
	JRST	ASK1.0		;NO
	MOVEI	FF,MULTIN
	IORM	FF,-1(P)	;SAY MULT REQUEST
	MOVE	TMP,(B)		;LAST,,FIRST
MPCI:	MOVE	TMP,(TMP)	;NEXT ENTRY
	HLRZ	B,TMP
	PUSH	P,TMP
	PUSH	P,B		;TYPE ITEM
	PUSH	P,-3(P)		;OPTIONS WORD
	PUSHJ	P,ASK1.0
	POP	P,TMP		;GET LIST BACK
	CAIE	A,NIC		;FIND ONE??
	JRST	ASK1.X		;YES
	TRNE	TMP,-1		;DONE LIST???
	JRST	MPCI		;NO
	MOVE	FF,-1(P)
	TRNN	FF,WAIT		;WAITING REQUESTED
	JRST	ASK1.X		;NO
	MOVE	PB,RUNNER	;SUSPEND SELF
	MOVE	B,-2(P)		;THE LIST
	MOVE	TMP,(B)		;LAST,,FIRST
BWL:	MOVEI	KL,WAITES(PB)
	MOVE	TMP,(TMP)	;NEXT
	HLRZ	B,TMP		;ITEM NO
	MOVE	C,B
	MOVE	EVT,@DATM
	PUSHJ	P,ITAILS	;ON TAIL
	MOVE	B,PRCITM(PB)	;
	MOVEI	KL,WAITLS(EVT)
	PUSHJ	P,ITAILS	;ON EVENT WAIL LIST
	TRNE	TMP,-1
	JRST	BWL		;CDR DOWN LIST
	JRST	DOWAIT		;GO WAIT
ASK1I:	MOVE	B,-2(P)
ASK1.0:	JSP	TMP,EVTCKB	;GET DATUM OF EVENT TYPE
	SKIPE	PDA,INTRGP(EVT)	;USER WAIT PROCESS??
	JRST	USPPRC		;YES
ASKN:	MOVE	FF,-1(P)	;CONTROL WORD
	SKIPN	A,NOTCLS(EVT)	;ANY READY TO GO
	JRST	ASK1.4		;NO
	TRNE	FF,RETAIN	;RETAIN THIS ONE??
	JRST 	ASK1.1		;YES
	MOVEI	KL,NOTCLS(EVT)
	PUSHJ	P,REMCAR	;GET THE FIRST
	JRST	ASK1.2		;TEST SAYWCH
ASK1.1:	MOVE	A,(A)
	HLRZ	A,(A)		;THI FIRST ITEM
ASK1.2:	TRNN	FF,SAYWCH	;WANT ASSOCIATION
	JRST	ASK1.3		;NO
	PUSH	P,[EVTYPI]	;EVENT TYPE
	PUSH	P,A		;NOTICE
	PUSH	P,-4(P)		;WHATEVER TYPE IT IS
	PUSHJ	P,STACSV	;SAVE REGS
	MOVEI	5,16		;MAKE
	PUSHJ	P,LEAP
	PUSHJ	P,STACRS	;GET ACS BACK
ASK1.3:
ASK1.X:	SUB	P,X33
	JRST	@3(P)		;RETURN
ASK1.4:	MOVEI	A,NIC
	TRNE	FF,WAIT		;IF NOT WAITING OR 
	TRNE	FF,MULTIN	;MUL REQ
	JRST	ASK1.X		;ALL DONE
	MOVE	PB,RUNNER
	MOVEI	KL,WAITES(PB)	;WAIT ON THIS ONE
	PUSHJ	P,ITAILS	;PUT ON TAIL
	MOVE	B,PRCITM(PB)
	MOVEI	KL,WAITLS(EVT)
	PUSHJ	P,ITAILS
DOWAIT:	SETZM	STATUS(PB)
	MOVEM	FF,INTRGC(PB)
	MOVEI	A,WAITNG
	MOVEM	A,REASON(PB)
	PUSHJ	P,SPSRN2	;WAIT
	JRST	ASK1.X		;RETURN
HERE(ASKNTC)
	JSP  	TMP,EVTCK3	;CHECK EVENT TYPE
	JRST	ASKN		;GO DO IT
EVTCK3:	SKIPA	B,-3(P)
EVTCK2:	MOVE	B,-2(P)
EVTCKB:	MOVE	TABL,GOGTAB
	MOVE	C,B
GLOB <
	CAIL	C,GBRK		;IS THE ITEM GLOBAL
	MOVEI	TABL,GLUSER	;YES, USE GLOBAL INFO STUFF
>;GLOB
	LDB	A,INFOTAB(TABL)
	CAIE	A,EVTTYP
	ERR	<THIS ITEM IS NOT AN EVENT TYPE>,6
	MOVE	EVT,@DATAB(TABL)
GLOB <
	MOVE	TABL,GOGTAB
>;GLOB
	JRST	(TMP)
HERE(SETCP)
	JSP	TMP,EVTCK2
	MOVE	A,-1(P)
	MOVEM	A,CAUSEP(EVT)
XIT3:	SUB	P,X33
	JRST	@3(P)
HERE(SETIP)
	JSP	TMP,EVTCK2
	MOVE	A,-1(P)
	MOVEM	A,INTRGP(EVT)
	JRST	XIT3
HERE(MKEVTT)	;MAKE EVENT TYPE
	MOVE	C,-1(P)
	MOVEI	A,EVTTYP
	MOVE	TABL,GOGTAB
GLOB <
	CAIL	C,GBRK
	JRST	[ SETOM USCOR2(TABL)	;BLOCK IN UPPER
		MOVEI TABL,GLUSER
		JRST	.+1 ]
>;GLOB
	DPB	A,INFOTAB(TABL)
	MOVEI	C,NEVARS
	PUSHJ	P,CORGET
	ERR	<MKEVT: No core>
	MOVE	C,-1(P)
	MOVE	TABL,GOGTAB
GLOB <
	CAIL	C,GBRK
	JRST	[ SETZM USCOR2(TABL)	;UNDO ABOVE
		MOVEI	TABL,GLUSER
		JRST	.+1 ]
>;GLOB
	MOVEM	B,@DATAB(TABL)
	HRLI	D,(B)
	HRRI	D,1(B)
	SETZM	(B)
	BLT	D,NEVARS-1(B)
	SUB	P,X22
	JRST	@2(P)
HERE(NWLD1)
HERE(NWLD2)
HERE(NWLD3)
HERE(NWLD4)
HERE(NWLD5)
	ERR <DRYROT IN NWORLD>
BEND PROCSS
ENDCOM(PRC)