Google
 

Trailing-Edge - PDP-10 Archives - decuslib10-01 - 43,50035/clock1.mun
There are no other files named clock1.mun in the archive.
TITLE	CLOCK1 - CLOCK, CONTEXT SWITCHING, AND JOB STARTUP AND STOP ROUTINES - V412
SUBTTL	APRINT TH/TH/CHW  TS  20 MAY 69
XP VCLOCK1,412
		; PUT VERSION NUMBER IN GLOB LISTING AND LOADER STORAGE MAP

	ENTRY CLOCK1	;ALWAYS LOAD CLOCK1 IF LIBRARY SEARCH
CLOCK1:

;THIS SERVICE ROUTINE RUNS ON A HIGH PRIORITY CHANNEL
;AND REQUESTS INTERRUPTS ON LOWER CLK CHANNEL
;FOR SCHEDULING JOBS AND ERROR HANDLING THAT THE USER
;IS NOT ENABLED TO HANDLE HIMSELF


EXTERNAL TIME,TIMEF,CLKFLG,REQCLK,APRCHL,APRPC,UPTIME
EXTERNAL JOBDAT,JOBTPC,JOBCNI,JOBAPR,APRERR,SCHEDF

EXTERNAL APRILM,COMMAN,CONMES,DEVCHK,DEVSRC,ERROR,INLMES
EXTERNAL RELEA9,CRSHWD,CRASHX

INTERNAL	FTTTYSER	;THIS ROUTINE MAY BE ASSEMBLED TO WORK WITH  EITHER
				; THE OLD SCNSER OR THE NEW TTYSER.

IFNDEF FTPDP8,<FTPDP8==1>	;NORMALLY PDP-8'S ATTACHED TO SYSTEM

INTERNAL FTCHECK,FTMONP

IFN FTCHECK+FTMONP,<
EXTERNAL DATA,APRCON,APRIN1,CLKS17,DAMESS,UUO0,CLOCK
INTERNAL UUO1
>
IFE FTCHECK+FTMONP,<
	INTERN CLOCK,DAMESS
	EXTERN CIPWTM
APRCON:	231000		;MONITOR ENABLED CPU FLAGS
APRIN1:	0		;USER ENABLED CPU FLAGS
CLKS17:	0		;PLACE TO SAVE AC17 ON CLOCK INTERRUPT
DAMESS:	ASCIZ /-JAN-/
CLOCK:	POINT 36,CIPWTM,35	;BYTE POINTER TO CLOCK REQ QUEUE
>
	INTERN APRINT

APRINT:	JRST APRPAR		;ALWAYS CHECK APR AND PI DEVICES
	JRST .			;CHECK OTHER DEVICES

APRPCL:	CONO PI,240000		;TURN OFF MEM PAR. ERR, AND
				; ENABLE FOR MEM PAR AND TRY AGAIN
				; (DO NOT TURN OFF POWR FAIL AS THAT PERMANENTLY
				; DISABLES POWR FAIL INTERRUPT)
APRPAR:	CONSZ PI,600000		;MEM PARITY ERROR OR POWER FAILURE?
	HALT APRPCL		;YES, HALT MACHINE, CLEAR FLAGS AND TRY AGAIN
				; ON CONTINUE
	CONSO APR,@APRCON	;INTERRUPT FOR APR?
				; ALWAYS AT LEAST FOR CLOCK,ILM,NXM,PD OVF
				; RH MODIFIED EACH TIME USER RUNS IN CASE HE IS
				; ENABLED FOR PC CHANGE OR AR OVF
	JRST APRINT+1		;NO,CHECK OTHER DEVICES ON THIS PI CHANNEL
	SKIPE CRSHWD		;IS LOC. 30 CLOBBERED?
	JRST CRASHX		;YES - GO SAVE AC'S & STATE OF ALL DEVS.
	CONSO APR,001000	;YES, IS IT CLOCK?
	JRST APRER		;NO, GO CHECK ERROR FLAGS
	AOS TIME		;YES, INCREMENT TIME OF DAY
	AOS UPTIME		;UPTIME IS LOADED AS ZERO,AND IS NEVER CLEARED
	SETOM TIMEF		;FLAG THAT APR CLOCK HAS TICKED
	SETOM CLKFLG		;SET FLAG FOR CLK FORCED INTERRUPT
	CONO PI,REQCLK		;REQUEST INTERRUPT ON CLK CHANNEL
	CONSZ APR,@APRIN1	;IS USER ENABLE FOR ANY FLAGS(INCLUDING CLOCK)
				; RH ALSO MODIFIED EACH TIME A USER RUNS
	JRST APRER1		;YES, GO PROCESS TRAP
	CONO APR,1000+APRCHN	;NO, CLEAR ONLY THE CLOCK FLAG
	JEN @APRCHL		;DISMISS INTERRUPT

;HERE ON CLOCK FLAG AND IT OR SOME OTHER FLAG IS ON WHICH USERS WANTS

APRER1:	CONO APR,1000+APRCHN	;NOW CLEAR CLOCK FLAG
	EXCH TAC,APRCHL		;SAVE TAC, GET PC
	TLNE TAC,USRMOD		;IS PC FROM USER MODE?
	JRST APRER4		;YES, GO TRAP TO HIM
	JRST APRER2		;NO, GO CHECK IN CASE ALSO A SERIOUS ERROR
;OTHER APR INTERRUPTS BESIDES CLOCK

APRER:	EXCH TAC,APRCHL		;SAVE TAC, GET PC
	TLNE TAC,USRMOD		;IS PC IN USER MODE?
	CONSO APR,@APRIN1	;YES, IS USER ENABLED FOR THIS ERROR
	JRST APRER2		;NO, PRINT ERROR MESSAGE AND STOP JOB
APRER4:	EXCH JDAT,JOBDAT	;YES, SAVE JDAT, GET CURRENT JOB DATA AREA ADR.
	MOVEM TAC,JOBTPC(JDAT)	;STORE PC IN JOB DATA AREA

	CONI APR,JOBCNI(JDAT)	;STORE APR IN JOB DATA AREA
	HLLZS JOBENB(JDAT)	;CLEAR SOFTWARE FLAGS SO THAT USER MUST DO
				; ANOTHER APRENB UUO IN ORDER TO ENABLE TRAPS
	SETZM APRIN1		;ALSO CLEAR USER APR CONSO FLAGS
	HRRI TAC,231000		;AND SET MONITOR TO LOOK ONLY FOR
	HRRM TAC,APRCON		;PD OVF,ILM,NXM, AND CLOCK
	HRR TAC,JOBAPR(JDAT)	;GET USER LOC TO TRAP TO
	EXCH JDAT,JOBDAT	;RESTORE JDAT,JOBDAT
	CONO APR,440+APRCHN	;DISABLE FOV, AROVF IN CASE ON
				;SO USER MUST REENABLE WITH SETAPR UUO
APRER3:	TLZ	TAC,440000	;CLEAR FOV (PC CHANGE ON PDP-6) AND AR OVF FLAGS
				; SO INTERRUPT MAY BE DISMISSED
	EXCH	TAC,APRCHL	;RESTORE TAC & APRCHL
	CONO APR,430110+APRCHN	;CLEAR ALL ERROR FLAGS WHICH CAN CAUSE INTERRUPTS
				; EXCEPT CLOCK FLAG(ELSE LOSE TIME OF DAY)
	JEN @APRCHL		;DISMISS INTERRUPT
APRER2:	CONSO	APR,NXM!ILM!POV	;DOES EXEC CARE?
	JRST	APRER3		;NO. IGNORE EXEC OVERFLOW (MUST BE FOV OR AROVF)
	MOVEM	TAC,APRPC	;STORE ERROR PC FOR CLK CHANNEL
	CONI APR,APRERR		;STORE ERROR FLAGS
				; (ALSO USED AS ERROR FLAG)
	SETOM CLKFLG		;SET FLAG FOR CLK INTERRUPT
	SETOM SCHEDF		;FLAG THAT RESCHEDULING IS NEEDED
				; (EVEN THOUGH PC MAY BE IN EXEC MODE)
	CONO PI,REQCLK		;REQUEST INTERRUPT IN CLK CHANNEL
	CONSZ	APR,ILM		;WAS ERROR ILLEGAL MEMORY(FROM USER)?
	HRRI	TAC,0		;YES,CLEAR RH OF PC,SO A SECOND ILM INTERRUPT
				; WILL NOT OCCUR IF THIS IS A WILD PC(AND A PDP-10)
IFN FTHALT,<
	CONSZ	PI,003400	;ARE ANY PI'S IN PROGRESS OF LOWER PRIORITY THAN APR?
				; (PDP-10 BITS ONLY)
	HALT .+1		;YES, HALT SO CONTINUE WILL TRY TO RECOVER
>
	JRST	APRER3		;NO,MUST BE UUO LEVEL(OR USER MODE AND
				; MEMORY DROPPED OUT)
SUBTTL	CLOCK - LOW PRIORITY CLOCK SERVICE(CLK)

;THIS ROUTINE RUNS ON THE LOWEST PRIORITY PI CHANNEL AND AT UUO LEVEL
;TO CAUSE AN INTERRUPT ON CLK CHANNEL:
;	SETOM CLKFLG	;FLAG THAT INTERRUPT HAS BEEN REQUESTED
;	CONO PI,CLKREQ	;REQUEST PI INTERUPT ON LOWEST PI CHANNEL
;THE FOLLOWING OTHER FLAGS MUST ALSO BE SET
;APRERR-APR DETECTED ERROR IN CURRENT JOB
;SCHEDF-RESCHEDULING MUST TAKE PLACE(EVEN THOUGH PC IN EXEC MODE)
;TIMEF-APR CLOCK HAS TICKED ON HIGH PRIORITY CHANNEL
;SEE APRSER AND RUNCSS TO SEE HOW THIS ROUTINE IS CALLED

;CLK SERVICE PERFORMS THE FOLLOWING ON A REGULAR BASIS:
;PROCESSES CLOCK QUEUE REQUESTS
;CALLS CONSOLE MONITOR COMMAND DECODER
;CALLS CORE SHUFFLER
;THEN CALLS SCHEDULER
;IF THE CURRENT JOB IS IN EXEC MODE THE ABOVE 4 TASKS ARE
;DELAYED UNTIL THE CURRENT JOB ENTERS A STOPPABLE STATE: I.E., UNTIL
;	1. JOB STARTS TO WAIT FOR A BUSY SHARABLE DEVICE
;	2. JOB STARTS TO WAIT FOR IO TO COMPLETE
;	3. CONTROL ABOUT TO RETURN TO USER MODE
;THEN CLK SERVICE IS ENTERED AT THE UUO LEVEL

STOR=DAT
T=TAC
T1=TAC1
JA=JDAT

;THE CLOCK REQUEST QUEUE PROVIDES THE REST OF THE MONITOR
;WITH THE ABILITY TO BE TRAPPED TO AFTER A NUMBER OF CLOCK TICKS
;HAVE OCCURRED

;TO MAKE A REQUEST:
;	CONO PI,PIOFF
;	IDPB AC,CLOCK	;STORE CLOCK REQUEST IN QUEUE
;	CONO PI,PION	;TURN PI BACK ON
;C(AC)=XWD ADDRESS,NO. OF CLOCK TICKS+DATA*10000
;WHERE DATA IS 6 BITS OF INFO NEEDED WHEN TIME RUNS OUT
;CLK SERVICE WILL PUSHJ PDP,ADR
;WHEN TIME RUNS OUT WITH DATA RIGHT JUSTIFIED IN AC TAC
;ALL ACS ARE FREE TO USE WHEN CALL IS MADE

INTERNAL CLKINI
EXTERNAL CIPWTM1,PION,PIOFF

CLKINI:	MOVEI TAC,CIPWTM1	;SETUP CLOCK QUEUE BYTE POINTER
	HRRM TAC,CLOCK		;LH NEVER CHANGES(36 BIT BYTE)
	POPJ PDP,
;HERE AT UUO LEVEL WHEN JOB GOES INTO IO WAIT OR SHARABLE DEVICE WAIT
;CALL:	PUSHJ PDP,WSCHED
;	RETURN HERE WHEN RUNABLE AGAIN

INTERNAL WSCHED
EXTERNAL JOBD14,JOBDAC,USRPC,JOBD16,NULPDL

WSCHED:	POP PDP,USRPC		;SAVE PC IN PROTECTED PART OF SYSTEM DATA
	MOVEI AC3,JOBDAC(JDAT)	;SAVE ACS 0-16 IN DUMP ACS
	BLT AC3,JOBD16(JDAT)	;IN CURRENT JOB DATA AREA
	MOVEI PDP,NULPDL	;NULL JOB PD LIST
	HRLI PDP,MJOBP1		;USED TO CALL SCHEDULER AND COMMAND DECODER
				; OTHERWISE GET PD OUF

	JRST RSCHED		;GO RESCHEDULE


;HERE AT UUO LEVEL WHEN CURRENT JOB RETURNS TO USER MODE
;FROM A UUO CALL AND EITHER:
;	1. CURRENT JOB TYPED CONTROL C WHILE IN EXEC MODE
;	2. CLOCK FLAG WENT OFF WHILE CURRENT JOB WAS
;		IN EXEC MODE

;CALL:	PUSHJ PDP,USCHED	;FROM UUOCON(UUO HANDLER RETURN TO USER)
;	RETURN HERE WHEN RUNABLE

INTERNAL USCHED
EXTERNAL JOBDPG,JOBDPD,USRPC

USCHED:	POP PDP,USRPC		;SAVE PC IN PROTECTED PART OF SYSTEM DATA
	MOVEM PROG,JOBDPG(PROG)	;SAVE PROG IN DUMP AC AREA
	MOVEM PDP,JOBDPD(PROG)	;SAVE PDP
	JRST RSCHED		;GO RESCHEDULE
;HERE AT CLK INTERRUPT LEVEL

INTERNAL CLKINT
INTERNAL FTTIME
EXTERNAL CLKFLG,JOBD17,CLKCHL,SCHEDF,JOBADR,JOBD16,JOBDAC
EXTERNAL JOBD15,JOBPD1,MJOBP1,APRERR,NULDAT,NULPDL

CLKINT:	SKIPN CLKFLG		;CLK INTERRUPT REQUEST?
	JRST CLKINT			;NO, CHECK OTHER DEVICES
	MOVEM 17,CLKS17		;SAVE AC 17
	MOVE 17,CLKCHL		;IS CURRENT JOB IN USER MODE?
	TLNN 17,USRMOD
	SKIPE SCHEDF		;NO, IS THIS A FORSCED RESCHEDULING INTERRUPT?
	JRST SAVPC		;YES, IT IS OK TO RESCHEDULE NOW
	MOVE 17,CLKS17		;NO, LEAVE TIMEF SET AND DISMISS INT.
	JEN @CLKCHL

SAVPC:	MOVEM 17,USRPC		;SAVE PC IN PROTECTED PART OF SYSTEM DATA
				; STORAGE FOR CURRENT JOB
CLKERR:	SKIPN 17,JOBDAT		;CURRENT JOB DATA AREA, IS THERE ONE?
	MOVEI 17,NULDAT		;NO, MUST BE NULL JOB OR CORE 0
				; RUNS AT UUO LEVEL,REQUESTS CLK INT. TO STOP
	MOVEM 16,JOBD16(17)	;SAVE AC 16 IN DUMP AC PART OF JOB DATA AREA
	MOVEI 16,JOBDAC(17)	;SOURCE=0,DESTINATION=DUMP AC 0
	BLT 16,JOBD15(17)	;SAVE ACS 0-15 JUST BELOW AC 16
	MOVE TAC,CLKS17		;NOW SAVE 17 IN JOB DATA AREA
	MOVEM TAC,JOBD17(17)	;ALONG WITH OTHER ACS
	MOVEI PDP,NULPDL	;SET UP PUSH DOWN LIST IN NULL JOB DATA
				; AREA IN LOWER CORE
	HRLI PDP,MJOBP1		;-LENGTH+1(LEAVE ROOM FOR UUO PC)
	SKIPE TAC,APRERR	;IT THIS AN ERROR INTERRUPT?
	PUSHJ PDP,APRILM	;YES, GO PROCESS ERROR,APRILM WILL CLEAR APRERR
				; FLAG IMMEDIATELY 
EXTERNAL COMCNT,NXTJOB,HNGTIM,POTLST,LSTWRD
EXTERNAL TIMEF,APRERR,CLKFLG,SCHEDF,JOB,PMONTB

RSCHED:	SKIPN TIMEF	;HAS CLOCK GONE OFF SINCE LAST CALL?
	JRST CIP6	;NO, JUST RESCHEDULE

;TIME ACCOUNTING

EXTERNAL TIME,MIDNIT,THSDAT,MONTAB

IFN FTTIME,<
	EXTERNAL RTIME,TTIME,JOB
	SKIPN	ITEM,JOB	;WAS LAST JOB NULL JOB?
	SKIPN	POTLST		;YES-WAS IT A LOST TICK?
	JRST	INCTIM		;NO-PROCEED NORMALLY
	AOS	LSTWRD		;YES-INCREMENT LOST TIME COUNT
	SETZM	POTLST		;AND CLEAR LOST TICK INDICATION
INCTIM:	AOS RTIME(ITEM)		;INCR. CURRENT JOB INCREMENTAL RUN TIME
	AOS TTIME(ITEM)		;INCR. CURRENT JOB TOTAL RUN TIME
>
IFN FTKCT,<
	EXTERN USRREL,JBTKCT
	LDB TAC,[POINT 8,USRREL,25]	;GET NO. OF 1K BLOCKS-1FOR CURRENT USER
	ADDI TAC,1			;MAKE IT NO. OF 1K BLOCKS
	ADDM TAC,JBTKCT(ITEM)		;ADD IN ACCUMULATED CORE RUNNING TIME PRODUCT
				; (KILO-CORE TICKS)
IFN FT2REL,<
	EXTERN CHGHGH
	PUSHJ PDP,CHGHGH	;CHARGE USER FOR HIGH SEGMENT IF HE HAS ONE
>
>
;MIDNITE CHECK

	MOVE TAC1,TIME
	CAMGE TAC1,MIDNIT	;GONE PAST MIDNITE?
	JRST CIP2		;NO
CIP3:	SETZB IOS,TIME		;YES. RESET TIME OF DAY
	AOS TAC,THSDAT		;UPDATE DAY
	IDIVI TAC,^D31
	DIVI IOS,^D12		;NO.
	LDB TAC,PMONTB
	CAMGE TAC,TAC1		;END OF MONTH?
	JRST CIP3		;YES.
;PROCESS TIMING REQUESTS STORED IN QUEUE

CIP2:	HRRZ STOR,CLOCK		;GET END OF LIST
CIP4:	CAIN STOR,CIPWTM1	;END YET?
	JRST CIP5		;YES
	SOS TAC1, (STOR)	;DECREMENT TIMING REQUEST
	TRNE TAC1, 7777		;TIME EXPIRED YET
	SOJA STOR, CIP4		;NO, CONTINUE SCAN
	CONO PI, PIOFF		;YES, MOVE LAST ITEM IN LIST TO THIS
	MOVE TAC, @CLOCK
	SOS CLOCK
	MOVEM TAC, (STOR)
	CONO PI,PION
	LDB TAC, [POINT 6, TAC1, 23]	;GET 6 BIT DATA ITEM
	MOVSS TAC1		;SETUP DISPATCH ADDRESS
	PUSH PDP, STOR		;SAVE ONLY VALUABLE AC
	PUSHJ PDP, (TAC1)	;AND DISPATCH TO TIMING REQUEST ROUTINE
	POP PDP, STOR
	SOJA STOR, CIP4		;GO BACK FOR MORE REQUESTS

CIP5:	SOSG HNGTIM		;DECREMENT HUNG IO DEVICE 
	PUSHJ PDP,DEVCHK	;GO CHECK FOR HUNG IO DEVICES
	SKIPE COMCNT		;ANY COMMANDS TO PROCESS?
	PUSHJ PDP,COMMAND	;YES, CALL COMMAND DECODER
IFN FTPDP8,<
EXTERN TIMSKP,TRPFLG,UUOTRA,DEVIPC,DEVTRP
	SKIPN SCHEDF		;NEVER OVERRIDE FORCED RESCHEDULE
	SKIPN ITEM,TIMSKP	;DON'T SCHED THIS CLOCK-TICK,FORCE CURRENT JOB
>
CIP6:	PUSHJ PDP,NXTJOB	;CALL SCHEDULER
IFN FTPDP8,<
	SETZM TIMSKP	;SCHEDULER SKIPS THIS INSTRUCTION ON HIGH PRIORITY RETURN
	SETZM UUOTRA	;ALWAYS CLEAR UUO EXIT RESCHEDULE FLAG
>
	SETZM CLKFLG		;CLEAR CLK INTERRUPT FLAG
				; SET ON ALL FORCED CLK INTERRUPTS
	SETZM TIMEF		;CLEAR TIMED (1 JIFFY) INTERRUPT FLAG.
	SETZM SCHEDF		;CLEAR FORCED SCHEDULING FLAG
	CAMN ITEM,JOB		;IS NEXT JOB SAME AS LAST ONE?
	JRST CIP8		;YES, JUST RESTORE ACS AND DISMISS
;DIFFERENT JOB, SAVE SOFTWARE STATE(HARDWARE ALREADY SAVED)

EXTERNAL JOB,JOBDAT,JOBPRT,USRPRT,USRHCU,JOBJDA

	SKIPN JA,JOBDAT		;NULL JOB OR CORE 0 ON OLD JOB?
	JRST CIP7		;YES, DO NO SAVE SOFTWARE STATE
	MOVEI T,JOBPRT(JA)	;DEST.=FIRST LOC PROTECTED FROM USER
	HRLI T,USRPRT		;SOUR.=SYSTEM DATA STORAGE FOR CURRETN JOB
	SKIPL T1,USRHCU		;MOVE NO. OF OLD USER IO CHAN. IN USE
	CAILE T1,17		;MUST BE 17 OR LESS(IO MIGHT
				; CLOBBER IF ADDRESS CHECKING MISSES)
	MOVEI T1,0		;MOVE ONLY CHN 0 IF NEG, OR GR 17
				; SAVGET SETS LH NEGATIVE DURING IO AS A FLAG
				; SINCE IT DOES IO INTO AND OUT OF
				; CHANNEL LOCATIONS (JOBJDA+1...JOBJDA+17).
	ADD JA,T1		;RELOCATE TO USER AREA
	BLT T,JOBJDA(JA)	;MOVE TO USER JOB DATA AREA
				; STOP WITH USER CHANNEL 0-1+C(USRHCU)
;RESTORE SOFTWARE STATE OF NEW JOB,THEN HARDWARE STATE

INTERNAL NULJOB,NULADR
EXTERNAL JOB,JBTDAT,JOBDAT,USRPRT,JOBPRT
EXTERNAL JOBHCU,USRJDA,JOBENB,APRCHN,APRNUL,NULDAT,NULERR

NULJOB:				;TRANSFER HERE FROM SYSINI WITH ITEM=0
CIP7:	MOVEM ITEM,JOB		;STORE NEW CURRENT JOB NUMBER
NULADR:	PUSHJ PDP,SETRL1	;GO SETUP HARDWARE AND SOFTWARE RELOCATION
				; INFORMATION FOR NEW CURRENT USER
	JUMPE ITEM,NULJB	;IS NEW JOB THE NULL JOB?

IFN FTHALT,<
	SKIPN JA		;DOES JOB HAVE CORE ASSIGNED?
	HALT .			;NO -ELSE CLOBBER MONITOR
>
	MOVEI T,USRPRT		;NO, DEST.=PROTECTED AREA IN MONITOR
	HRLI T,JOBPRT(JA)	;SOURCE=FIRST PROTECTED LOC. IN JB  DATA AREA
	SKIPL T1,JOBHCU(JA)	;MOVE NO. OF USER IO CHAN. IN USE
	CAILE T1,17		;MUST BE 17 OR LESS(IO MIGHT CLOBBER
				; IF ADRRESS CHECKING MISSES
	MOVEI T1,0		;MOVEJUST CHAN 0 IF NEG. OR GREATER THAN 17
				; SAVEGET SETS NEG.DURING IO
	BLT T,USRJDA(T1)	;AND MOVE INTO MONITOR

;RESTORE HARDWARE STATE OF CURRENT JOB

CIP8:	SKIPN JA,JBTDAT(ITEM)	;JOB DATA AREA(IS THERE ONE?)
	MOVEI JA,NULDAT		;NO, MUST BE NULL JOB
IFN FTPDP8,<
	SKIPN DEVDAT,TRPFLG	;DOES JOB NEED TO BE TRAPPED
	JRST CIP9		;NO, CONTINUE
	MOVE T,USRPC		;YES, GET IT'S CURRENT PC
	MOVE T1,DEVTRP(DEVDAT)	;ALSO GET TRAP PC
	TLNN T,USRMOD		;IS JOB GOING BACK INTO USER MODE ?
	SKIPA T,JOBPD1(JA)	;NO, GET IT'S USER MODE PC
	MOVEM T1,USRPC		;YES, TRAP IMMEDIATELY
	MOVEM T1,JOBPD1(JA)	;TRAP LATER UPON RETURN FROM SYSTEM
		;IF PREVIOUS INSTRUCTION EXECUTED, THIS ONE DOESN'T MATTER
	MOVEM T,DEVIPC(DEVDAT)	;SAVE USER'S INTERRUPT PC IN DATA BLOCK
	SETZM TRPFLG		;CLEAR TRAP REQUEST FLAG
CIP9:
>
	MOVSI 17,JOBDAC(JA)	;RESTORE DUMP ACS
	BLT 17,17
	SKIPE APRERR		;DID AN ERROR OCCUR WHILE CLKPI IN PROGRESS
				; (ON CLK PI OR HIGHER)
	JRST CLKERR		;YES, GO PROCESS ERROR
	SKIPN JOB		;IS THIS JOB THE NULL JOB?
	SKIPN NULERR		;YES, HAS AN ERROR OCCURRED WHILE NULL JOB
				; WAS RUNNING? IF YES, RESTORE ACS
				; ILL UUO LOSED ACS
	JEN @USRPC		;DISMISS CHANNEL(IF INTERRUPT IN PROGRESS)

;THE NULL JOB
;RUNS IN USER MODE WITH PC=1 AND COUNTS IN AC 0

EXTERNAL APRNUL,TIME,THSDAT,MIDNIT,NULERR

NULJB:
IFN FTCHECK,<EXTERNAL MONPTR,MONSUM,CHECK
	MOVE TAC,MONPTR
	PUSHJ PDP,CHECK
	CAME TAC1,MONSUM
	HALT .+1
>
	SETZB 0,NULERR	;CLEAR AC 0 USED FOR USUAL MONITORING
				; CLEAR FLAG SAYING ERROR IN NULL JOB
				; OF NULL TIME INTERVAL
				; LOC JOBDAT (LOCATION OF NULL JOB DATA AREA) TO 0
				; AS A FLAG (ONLY DUMP ACS USED IN NULL JOB DATA AREA)
				; IF ANY ERRORS (APRERR NON-ZERO) OCCURRED
				; WHILE CLK IN PROGRESS
				; CATCH THEM NEXT CLK INTERRUPT
 	MOVE 1,[AOJA 0,1]	;INSTR. TO AC1
	JRST 11,1		;DISMISS IF INTERUPT IN PROGRESS
;ROUTINE TO SET HARDWARE AND SOFTWARE RELOCATION INFORMATION FOR CURRENT USER
;CALLED FROM:
;	CLOCK ROUTINE WHEN NEW USER IS DIRRERENT FROM OLD USER
;	CORE ROUTINE WHEN CORE REASSIGNED FOR CURRENT USER
;	CORE UUO
;	REMAP UUO
;	CALL RESET UUO
;	CALL SETUWP UUO

;CALL:	STORE RELOCATION AND PROTECTION FOR LOW SEG IN JOBADR(JOB NUMBER)
;	STORE LENGTH-1 AND ABS ORIGIN FOR HIGH SEG IN JBTADR(HIGH SEG NO)
;	(MOVE ITEM,JOB NUMBER - IF CALLING SETRL1)
;	PUSHJ PDP,SETREL OR SETRL1
;	ALWAYS RETURN, C(ITEM)=JOB NUMBER, C(PROG)=XWD PROT,RELOC, FOR LOW SEG

	INTERN SETREL
	EXTERN JOB,JBTADR,JOBADR,USRREL,JBTDAT,JOBDAT,JOBREL,KT10A

SETREL:	MOVE ITEM,JOB		;CURRENT JOB NUMBER
SETRL1:	MOVE PROG,JBTADR(ITEM)	;XWD PROTECTION,RELOCATION FOR LOW SEG
	MOVEM PROG,JOBADR	;SAVE TO MAKE UUO HANDLER FASTER
	HLRZM PROG,USRREL	;SAVE PROTECTION FOR ADDRESS CHECKING
				; (HIGHEST LEGAL REL ADDRES FOR CURRENT USER IN LOW SEG)
IFN JDAT-PROG,<
	MOVE JA,JBTDAT(ITEM)	;LOC OF JOB DATA AREA
	MOVEM JA,JOBDAT		;SAVE IT TOO FOR UUO HANDLER
>
	JUMPE PROG,SETHRD	;IF 0 (NULL JOB OR JOB DOING CORE 0 OR KJOB)
				; DO NOT STORE IN JOB DATA AREA (SINCE IT WILL BE
				; IN EXEC LOWER CORE.  ALSO DO NOT STORE
				; IN LOC 33, SO CAN SEE LAST REAL USER TO RUN

	HLRZM PROG,JOBREL(JA)	;SET PROTECTION IN USER JOB DATA AREA
				; FOR HIM TO LOOK AT
IFN FT2REL,<
	EXTERN SETHGH
	PUSHJ PDP,SETHGH	;SET UP FOR HIGH SEG, IF USER HAS ONE
				; PROG SETUP FOR DATAO
>
IFE FT2REL,<
	TLZ PROG,1777		;CLEAR OUT PROTECTION FOR HIGH SEG 
				; JUST IN CASE THIS IS A 2 REG. MACHINE(EVEN THOGH
				; SOFTWARE CANNOT HANDLE 2 SEGS)
>
	MOVEM PROG,KT10A	;STORE IN LOWER CORE SO IT CAN BE FOUND OUT
				; USING SWITCHES WHAT IS IN SECOND REGISTER
				; OPTION DOES NOT COME WITH PANEL LIGHTS
				; SO NOT STORE 0 FOR NULL JOB SO CAN SEE
				; LAST JOB TO RUN IN LOC 33
SETHRD:	DATAO APR,PROG		;SET APR HARDWARE FOR RELOCATION AND PROTECTION
				; FOR LOW(AND HIGH SEGS)
	SKIPN PROG,JOBADR	;RESTORE PROG TO XWD PROT,RELOC FOR JUST LOW SEG
				; (IS THERE ONE)?
	TDZA TAC,TAC		;NO, MUST BE NULL JOB OR CORE0 OR KJOB
				; SET FOR NO SPECIAL INTERRUPTS TO USER
	MOVE TAC,JOBENB(JA)	;USER APR CONSO FLAGS (THE ONES HE WANTS TO HANDLE
				; FALL INTO SETAPR ROUTINE


;ROUTINE TO ENABLE/DISABLE APR FOR TRAPPING TO USER AND EXEC
;CALL:	MOVEI TAC, APR CONSO FLAGS FOR USER TRAPPING
;	PUSHJ POP,SETAPR
;	RETURN WITH APR RESET AND INTERRUPT LOCATION CONSO'S SET

	INTERN SETAPR
	EXTERN APRFOV

SETAPR:	ANDI TAC,231010+APRFOV		;MASK OUT ALL BUT PD OVF, ILL MEM, NXM,
				; CLOCK, FOV(ONLY PDP-10), AND AROVF CONSO FLAGS
				; FOV=PC CHANGE ON PDP-6 WHICH IS NEVER ALLOWED
				; UNDER TIME SHARING BECAUSE IT TRAPS MONITOR TOO
	HRLS TAC		;PRESERVE USER BITS IN LH
	TRO TAC,231000		;MAKE SURE MONITOR ALWAYS LOOKING FOR
				; PD OVF, ILM, NXM, CLOCK FLAGS
	MOVE TAC1,TAC		;DUPLICATE BITS IN TAC1 FOR CONO TO APR.
	XORI TAC1,110		;COMPLEMENT FOV(PDP-10 ONLY) AND AROV FLAGS
	ADDI TAC1, 330		;SET DISABLE OR ENABLE FOR EACH
	ANDI TAC1,660		;MASK OUT ALL BUT DISABLE/ENABLE
				; BITS FOR FOV(PDP-10 ONLY) AND AROVF
	CONO PI,PIOFF		;DISABLE PI'S SO NO INTS. MAY OCCUR WHILE
				;CHANGING HARDWARE & SOFTWARE STATE FOR
				;APR TRAPPING
	HLRM TAC,APRIN1		;STORE USER BITS
	HRRM TAC,APRCON		;STORE EXEC BITS
	CONO APR,APRCHN(TAC1)	;ENABLE OR DISABLE APR FOR
				; FOV(PDP-10 ONLY) AND AR OVF SEPARATELY
	CONO PI,PION		;ENABLE PI'S AGAIN
	POPJ PDP,
SUBTTL	RUNCSS - RUN CONTROL(STARTING AND STOPPING OF JOBS)

;RUN CONTROL IS A COLLECTION OF ROUTINES WHICH
;SET AND CLEAR BITS IN THE JOB STATUS WORDS OF
;ALL JOBS SO THAT THE SCHEDULER WILL START AND STOP
;THEM ACCORDINGLY

;COMMON ERROR STOPPING ROUTINES
;CALLED AT ANY LEVEL(UUO,CLK, OR INTERRUPT)
;CALL:	MOVE ITEM,JOB CAUSING ERROR OR BEING STOPPED
;	MOVE DEVDAT,ADRRESS OF THAT JOB TTY DEVICE DATA BLOCK
;	MOVE DAT,BYTE POINTER TO LAST CHAR. ALREADY MOVED
;			;TO TTY OUTPUT BUFFER
;	PUSHJ PDP,KSTOP,PHOLD,HOLD,OR ESTOP
;	NEVER RETURN IF CALLED AT UUO LEVEL

;ROUTINE TO STOP JOB AFTER KJOB COMMAND
;CALLED AT UUO LEVEL IF JOB HAD CORE,CLK LEVEL IF NOT

INTERNAL KSTOP
EXTERNAL HIGHJB

KSTOP:	MOVSI TAC,JNA+JLOG+JACCT	;CLEAR JOB NUMBER ASSIGNED AND LOGGED IN BITS
	ANDCAM TAC,JBTSTS(ITEM)
IFN FTLOGIN,<
EXTERN PRJPRG

	SETZM PRJPRG(ITEM)	;CLEAR PROJECT-PROGRAMMER NUMBER WHEN JOB LOGS OUT
>
			; IF THIS IS THE LARGEST JOB IN USE,FIND NEXT
			; HIGHEST AND SET HIGHJB
	CAMGE	ITEM,HIGHJB	;IS THIS THE BIGGEST JOB NUMBER ASSIGNED?
	JRST	ESTOP		;NO, LEAVE HOLE
	MOVSI	TAC1,JNA	;YES,JOB NUMBER ASSIGNED BIT
	HRRZ	TAC,ITEM	;SCAN DOWNWARD
	TDNN	TAC1,JBTSTS(TAC)	;IS JNA BIT SET FOR THIS JOB?
	SOJG	TAC,.-1		;NO,KEEP LOOKING,FINISHED(TRUE IF THIS THE ONLY JOB
	MOVEM	TAC,HIGHJB	;YES,STORE NEW HIGHEST JOB NUMBER ASSIGNED
	JRST	ESTOP		;GO SET ERROR BIT
;ROUTINE TO STOP JOB, SET ERROR BIT AND PRINT MESSAGE
;THEN ADD ^C<CRLF><CRLF><PERIOD>
;CALL:	MOVEI TAC,ADR. OF MESSAGE
;	PUSHJ PDP,PHOLD

	INTERN PHOLD

PHOLD:	PUSHJ PDP,CONMES	;MOVE MESSAGE TO TTY OUTPUT BUFFER
				; FALL INTO HOLD
;ROUTINE TO STOP JOB, SET ERROR BIT,
;AND ADD "^C<CRLF><CRLF><PERIOD>

INTERNAL HOLD,HOLD1
EXTERNAL TTYSTC

HOLD:	PUSHJ PDP,INLMES
	ASCIZ /
^C

./

HOLD1:	PUSHJ PDP,TTYSTC	;MAKE SURE TTY STAYS IN MONITOR MODE
				; AND START TTY TYPING OUT MESSAGE
				; FALL INTO ESTOP
;ROUTINE TO STOP USER AND FLAG AS ERROR STOP


INTERNAL ESTOP,ESTOP1
EXTERNAL JBTSTS,STUSER,STREQ,STAVAL
EXTERNAL SCHEDF,JOB,CPOPJ

ESTOP:	JUMPE ITEM,CPOPJ	;IS THIS ERROR IN JOB 0?
	MOVSI TAC,JACCT		;NO, CLEAR ACCOUNTING BIT(IN CASE LOGGING
	ANDCAM TAC,JBTSTS(ITEM)	;IN OR OUT) SO USER CAN USE CONTROL C
				; TO RECOVER
ESTOP1:	MOVSI TAC,JERR		;SET ERROR BIT IN JOB STATUS WORD
	IORM TAC,JBTSTS(ITEM)	;SO JOB CAN NOT CONTINUE(CONT COM.)
	CAME ITEM,STUSER	;SYSTEM TAPE USER?
	JRST STOP1		;NO
	MOVSI TAC,637163	;FIND SYS DDB
	PUSHJ PDP,DEVSRC	;SYSTEM ERROR IF NOT FOUND
	JSP DAT,ERROR
	PUSHJ PDP,RELEA9	;YES, RELEASE SYSTEM TAPE WITHOUT WAITING
;ROUTINE TO STOP ANY JOB FROM BEING SCHEDULED
;CALL:
;	MOVE ITEM, JOB NUMBER
;	PUSHJ PDP, STOP1
;	EXIT	;RETURN HERE IMMEDIATELY, IF CALLED FROM HIGHER
;PRIORITY PI CHANNEL THAN CLK(LOWEST), OTHERWISE WHEN JOB IS RUNABLE
;CALLED FROM COMMAND DECODER WHEN <CONTROL>C TYPED IN BY USER
;OR ON ANY ERROR MESSAGE(SEE PREVIOUS PAGE)

INTERNAL STOP1
EXTERNAL JBTSTS,PJBSTS,REQTAB,JOB,STUSER,MAXQ,AVALTB

STOP1:	MOVSI TAC, RUN
	CONO PI, PIOFF		;DONE AT INTERUPT LEVEL HIGHER THAN DT LEVEL
	CAME ITEM,STUSER	;IS THIS JOB CURRENTLY USING THE SYSTEM TAPE?
	TDNN TAC,JBTSTS(ITEM)	;NO, IS RUN BIT OFF IN JOB STATUS WORD
	JRST STOP1A		;YES
	ANDCAM TAC,JBTSTS(ITEM)	;NO, SO CLEAR IT
	CONO PI, PION
	LDB TAC,PJBSTS		;GET JOB WAIT QUEUE CODE(IF ANY)
	CAIG TAC,MAXQ		;DOES STATE HAVE Q ?
	SOSL REQTAB(TAC)	;YES. REDUCE IT.
	JRST STOP1A		;NO
	SOSGE AVALTB(TAC)	;YES REDUCE  COUNT
	SETZM AVALTB(TAC)	;CLEAR AVAL FLAG IF NO ONE WAITING
STOP1A:	CONO PI, PION		;MAKE SURE PI ON
	CAME ITEM, JOB		;NO, IS THIS JOB CURRENT USER

INTERNAL FTSWAP

IFE FTSWAP,<
	POPJ PDP,		;NO
>
IFN FTSWAP,<
	JRST REQUE		;SET REQUE JOB FLAG
>

	SKIPL TAC,JBTSTS(ITEM)	;RUN FLAG OFF?
	TLNN	TAC,JERR	;YES. ERROR FLAG ON?
	JRST	STOP2		;NO
	SETOM	SCHEDF		;YES, FORCE RESCHEDULING EVEN IF JOB IN EXEC MODE
	JRST STOP2		;YES, MAKE CLK RESCHEDULE ANOTHER JOB
;ROUTINE TO REQUE JOB WHICH HAS HAD A COMMAND TYPED
;WHICH NEEDS CORE AND THE CORE IMAGE IS ON THE DISK.
;OR IS IN CORE AND HAS ACTIVE DEVICES.
;CALLED FROM COMMAND DECODER
;CALL:	MOVE ITEM,JOB NO.
;	PUSHJ PDP,DLYCOM

INTERNAL DLYCOM

DLYCOM:	MOVSI TAC,CMWB		;SET COMMAND WAIT BIT
IFN FTSWAP,<
	EXCH	TAC,JBTSTS(ITEM)
>
	IORM TAC,JBTSTS(ITEM)	;IN JOB STATUS WORD

INTERNAL FTSWAP
IFN FTSWAP,<
	TLNN	TAC,CMWB
	PUSHJ	PDP,REQUE
>
		POPJ PDP,

;ROUTINE TO PUT JOB IN NO CORE QUEUE


INTERNAL FTSWAP
IFN FTSWAP,<INTERNAL NOCORQ
	EXTERNAL NULQ

NOCORQ:	MOVEI TAC,NULQ		;NO JOB NO. OR NO CORE QUEUE
	DPB TAC,PJBSTS
	JRST REQUE
>
;ROUTINE TO SETUP MONITOR JOB TO RUN LATER AT UUO LEVEL
;CALLED BY COMMANDS WHICH MAY OR MAY NOT NEED TO
;RUN MONITOR JOB DEPENDING ON WHETHER JOB HAS CORE(KJOB,IJOB)
;TTY WILL REMAIN IN MONITOR MODE
;JOB MUST HAVE CORE ASSIGNED
;CALL:	MOVE ITEM, JOB NUMBER
;	MOVEI TAC1,ADDR. OF MONITOR JOB TO BE RUN
;	PUSHJ PDP,MONJOB
;WHEN SCHEDULED TO RUN, MONITOR JOB MUST SET UP ITS OWN ACS

INTERNAL MONJOB

MONJOB:	PUSHJ PDP,MSTART	;START WITH PC IN MONITOR
	JRST SETRUN		;SET TTY TO START JOB WHEN COMMAND RESPONSE
				; IS FINISHED AND KEEP TTY IN MONITOR MODE


;ROUTINE TO SETUP ACS FOR MONITOR JOB STARTING AT UUO LEVEL
;SETS UP ITEM, WITH JOB NO.; PROG WITH RELOCATION, AND PDP
;WITH PUSH DOWN LIST ADR. IN JOB DATA AREA
;USED BY KJOB,CORE 0,SAVE,GET,RUN,R,REASSIGN AND FINISH COMMANDS
;CALL:	MOVEI TAC1,MONITOR JOB STOP ADDRESS
;	JSP TAC,MONSTR
;	RETURN WITH ACS PDP,PROG,JDAT, AND ITEM SETUP

INTERNAL MONSTR
EXTERNAL JOB,JBTADR,MJOBPD,JOBPDL,TTYFNU,JBTDAT

MONSTR:	MOVE ITEM,JOB		;CURRENT JOB NUMBER
	MOVE JDAT,JBTDAT(ITEM)	;ADR. OF JOB DATA AREA
IFN JDAT-PROG,<
	MOVE PROG,JBTADR(ITEM)	;JOB RELOCATION
>
	MOVSI PDP,MJOBPD	;MINUS LENGTH OF SYSTEM PD LIST
	HRRI PDP,JOBPDL(JDAT)	;FIRST LOC.-1 OF PD LIST
	PUSH PDP,TAC1		;SAVE STOP ADRRESS
	JRST (TAC)		;RETURN AND DO MONITOR JOB
				; WITH TTY DDB,OUTPUT BYTE POINTER, AND JOB NO.
;ROUTINE TO SET JOB STATE TO BE SCHEDULED TO RUN
;WITH SPECIFIED STARTING ADDRESS INCLUDING PC FLAGS
;CALLED ONLY WHEN JOB IN CORE AND AFTER JOB HAS BEEN
;SAFELY STOPPED IN ONE OF 3 STATES:
;1) PC IN USER MODE
;2) JOB IN A WAIT FOR SHARABLE DEVICE, OR IO WAIT
;3) JOB JUST ABOUT TO RETURN TO USER MODE FROM A UUO CALL
;CALL:	MOVE TAC1,STARTING PC
;	MOVE ITEM, JOB NUMBER
;	MOVE JDAT,ADR. OF JOB DATA AREA WHICH MUST BE IN CORE
;	PUSHJ PDP,USTART(PC TO USER MODE),MSTART(PC TO MONITOR MODE)
;	RETURN HERE IMMEDIATELY

INTERNAL MSTART,USTART
EXTERNAL JOBPC,JOBDAC,JOBD17,TTYSET,JOBOPC,JOBPD1

USTART:	MOVE TAC,JOBPC(JDAT)	;GET OLD PC
	TLNE TAC,USRMOD		;IS IT IN USER MODE TOO?
	JRST USTRT1		;YES, DUMP ACS AND PC FLAGS ARE ALREADY HIS
	MOVEI TAC,JOBDAC(JDAT)	;NO, MOVE USERS(UUO) ACS TO DUMP ACS
	HRL TAC,JDAT		;SOURCE=REL. 0,DEST.=JOBDAC IN JOB DATA AREA
	BLT TAC,JOBD17(JDAT)	;MOVE ALL ACS
	MOVE TAC,JOBPD1(JDAT)	;UUO PC HAS LAST PC
	HRRI TAC,-1(TAC)	;SUBTRACT 1 FROM RIGHT HALF AND
				; PRESERVE LH PC FLAGS.
				; (RH=0 ON HALT 0 OR FIRST START)
USTRT1:	MOVEM TAC,JOBOPC(JDAT)	;STORE OLD PC FOR USER TO LOOK AT
	HLL TAC1,TAC		;PRESERVE USER APR FLAGS
	TLO TAC1,USRMOD		;MAKE SURE NEW PC IN USER MODE
	TLZ TAC1,37		;MAKE SURE NO INDIRECT BITS OR INDEX FIELD

MSTART:	MOVEM TAC1,JOBPC(JDAT)	;STORE NEW PC
	MOVSI TAC,JERR+WTMASK
	ANDCAM TAC,JBTSTS(ITEM)	;CLEAR ERROR AND WAIT STATUS BITS
	JRST TTYSET		;SET TTY STATE TO INITIAL COND.
				; TTYUSR OR TTYURC SHOULD BE CALLED
				; TO INDICATE WHETHER TTY TO USER OR EXEC MODE
				; AND THAT JOB IS TO RUN(RUN BIT =1) WHEN
				; MONITOR COMMAND RESPONSE FINISHES.
				; SEE SETRUN BELOW

;ROUTINE TO SET JOB STATUS RUN BIT(RUN)
;CALLED BY SCANNER SERVICE WHEN TTY MONITOR COMMAND
;RESPONSE FINISHES.  THIS ACTION IS ENABLED BY CALLING
;TTYUSR, OR TTYURC IN SCNSER
;CALL:	MOVE ITEM,JOB NUMBER
;	PUSHJ PDP,SETRUN

INTERNAL SETRUN
EXTERNAL JBTSTS,PJBSTS,REQTAB,AVALTB,RNQUNT
EXTERNAL MAXQ

SETRUN:	LDB TAC,PJBSTS		;GET JOB STATUS WAIT QUEUE CODE
	CAILE TAC,MAXQ		;DOES JOB STATUS CODE HAVE A QUEUE?
	JRST SETR1		;NO
	AOSLE REQTAB(TAC)	;ADD TO REQUEST COUNT
	JRST SETR1		;OTHERS WAITING?
	AOSG AVALTB(TAC)	;MAKE AVAILABLE
	SETOM AVALTB(TAC)	;FLAG AS JUST AVAILABLE, BECAUSE
				; NO JOB WAS USING DEVICE. SCHEDULER
				; WILL SCAN THIS QUEUE
SETR1:	MOVSI TAC,RUN		;SET RUN BIT IN JOB STATUS WORD
	IORM TAC,JBTSTS(ITEM)
SETR2:	MOVE TAC,RNQUNT		;SET QUANTUM TIME TO RUN QUEUE QUANTUM
	HRRM TAC,JBTSTS(ITEM)	;RUN QUEUE QUANTUM

INTERNAL FTSWAP
IFE FTSWAP,<
		JRST NULTST	;GO SEE IF NULL JOB IS RUNNING
>
IFN FTSWAP,<
	INTERNAL REQUE
	EXTERNAL QJOB,JBTSTS

REQUE:	MOVSI TAC,JRQ		;MARK JOB TO BE REQUEUED WITH JRQ BIT
	TDNN TAC,JBTSTS(ITEM)	;INCREMENT COUNT ONLY ONCE FOR EACH JOB
	AOS QJOB		;INCREMENT COUNT OF NO. OF JOBS WAITING TO BE REQUEUED
	IORM TAC,JBTSTS(ITEM)	;SET REQUE BIT FOR SCHEDULER
	POPJ PDP,

>
;ROUTINE TO PUT A JOB TO SLEEP AND WAKE UP AGAIN LATER
;CALLED AFTER CLOCK QUEUE REQUEST PUT IN BY UUO ROUTINE

INTERNAL FTSLEEP

IFN FTSLEEP,<
INTERNAL SETSLP
EXTERNAL JBTSTS,SLPQ

SETSLP:	MOVSI TAC,CLKR		;FLAG THAT A CLOCK REQUEST HAS BEEN PUT IN
	IORM TAC,JBTSTS(ITEM)	;SO ONLY ONE PER JOB
	MOVEI AC1,SLPQ		;SLEEP STATE CODE
	JRST SETSTT		;SET STATUS AND RESCHEDULE

;HERE AT CLOCK LEVEL WHEN CLOCK REQUEST TIMES OUT FOR SLEEP
;JOB NO. IN AC TAC

INTERNAL WAKE
EXTERNAL PJBSTS,RNQ,SLPQ

WAKE:	MOVEI TAC1,RNQ		;RUN QUEUE CODE
	MOVE ITEM,TAC		;JOB NO.
	MOVSI TAC,CLKR		;CLEAR CLOCK REQUEST BIT FOR THIS JOB
	ANDCAM TAC,JBTSTS(ITEM)	;SO IT CAN PUT ANOTHER ONE IN
	LDB TAC,PJBSTS		;GET QUEUE CODE
	CAIE TAC,SLPQ		;IS JOB STILL SLEEPING?
	POPJ PDP,		;NO. RETURN TO CLOCK ROUTINE
	DPB TAC1,PJBSTS		;YES, STORE RUN QUEUE CODE
				; (CONTROL C, START CAN GET JOB OUT OF SLEEP)
	JRST SETR2
>
;ROUTINE TO GET DATA CONTROL AND ANOTHER SHARABLE DEVICE
;JOB NEVER GETS ONE DEVICE AND WAITS FOR SECOND, SINCE TYPING
;CONTROL C WOULD NEVER FINISH WITH FIRST DEVICE
;CALL	PUSHJ PDP,GETDCXX
;	AOSE XXREQ	;REQUEST COUNT FOR OTHER DEVICE
;	RETURN WHEN BOTH AVAILABLE

INTERNAL GETDCDT,GETDCMT
EXTERNAL DCREQ,REQTAB,AVALTB,DCAVAL,CPOPJ1

GETDCDT:GETDCMT:
	XCT @(PDP)		;INCREASE SHARABLE DEVICE REQ. COUNT
GETWT:	PUSHJ PDP,DVWAT1	;NOT AVAIL., GO WAIT FOR IT
	AOSN DCREQ		;IS DATA CONTROL AVAILABLE?
	JRST CPOPJ1		;YES, RETURN BOTH AVAILABLE
	MOVE AC1,@(PDP)		;DATA CONTROL NOT AVAILABLE
	SUBI AC1,REQTAB
	SOSL REQTAB(AC1)	;REDUCE REQ. COUNT FOR OTHER
				; SHARABLE DEVICE.
	SETOM AVALTB(AC1)	;SET AVAILABLE IF OTHER JOBS WAITING
	JFCL DCREQ		;ARGUMENT FOR DCWAIT
	PUSHJ PDP,DCWAIT	;WAIT FOR DATA CONTROL FREE
	MOVE AC1,@(PDP)		;INCREMENT REQ. COUNT
	AOSN @AC1		;NOW IS SHARABLE DEVICE FREE?
	JRST CPOPJ1		;YES
	SOSL DCREQ		;NO, REDUCE DATA CONTROL REQUEST
	SETOM DCAVAL		;SET AVAIL., SOME OTHER JOB WAITING FOR IT
	JRST GETWT		;TRY AGAIN
;ROUTINE TO WAIT FOR A SHARABLE DEVICE
;CALLED AT UUO LEVEL ONLY BY DEVICE SERVICE ROUTINES
;CALL:	AOSLE XXREQ		;ADD 1 TO SHARABLE DEVICE REQUEST COUNT
;				;IS DEVICE AVAILABLE?
;	PUSHJ PDP,XXWAIT	;NO, PUT JOB IN WAIT QUEUE
;	RETURN WHEN DEVICE AVAILABLE

;INITIALLY THE REQUEST COUNT IS -N, WHERE N IS THE
;NUMBER OF JOBS WHICH CAN USE THE SHARABLE DEVICE AT THE SAME TIME
;A REQUEST COUNT OF 0 MEANS THE MAXIMUM NO. OF JOBS ARE
;USING THE DEVICE, A POSITIVE NUMBER IS THE
;NUMBER OF JOBS WAITING IN THE SHARABLE DEVICE WAIT QUEUE

INTERNAL DVWAIT
INTERNAL MTWAIT,STWAIT,DTWAIT,DCWAIT,DAWAIT,MQWAIT,AUWAIT
EXTERNAL JOB,REQTAB

MTWAIT:DTWAIT:DCWAIT:STWAIT:DAWAIT:MQWAIT:AUWAIT:
DVWAIT:	MOVE AC1,(PDP)		;GET ADR. OF CALLER
	MOVE AC1,-2(AC1)	;GET AOSLE XXREQ INSTRUCTION
	JRST .+2
DVWAT1:	MOVE AC1,@-1(PDP)	;GET ADR. OF CALLER OF THIS ROUTINE
	SUBI AC1,REQTAB		;COMPUTE WAIT-STATE QUEUE CODE
SETSTT:	MOVE AC3,JOB		;CURRENT JOB NO.
	DPB AC1,PJBS1		;STORE IN JOB STATUS WORD
	JRST WSCHED		;GO SCHEDULE ANOTHER AND RETURN TO CALLER
				; WHEN SHARABLE DEVICE BECOMES AVAILABLE
				; SEE CLOCK AND CLKCSS

PJBS1:	POINT JWSIZ,JBTSTS(AC3),JWPOS	;BYTE POINTER TO JOB STATUS
				; WORD WAIT QUEUE CODE
;ROUTINE TO SET JOB TO RUN AFTER IT HAS BEEN STOPPED
;BECAUSE IT HAD TO WAIT FOR IO TO COMPLETE FOR SOME DEVICE
;EACH SERVICE ROUTINE AT INTERRUPT LEVEL
;CHECK EACH TIME IT FINISHED A TASK(BUFFERFUL)
;TO SEE IF THE JOB USING THE DEVICE HAS
;PREVIOUSLY CAUGHT UP WITH DEVICE AND HAS BEEN STOPPED
;CALL:	MOVE DEVDAT,ADR. OF DEVICE DATA BLOCK
;	MOVE IOS,DEVIOS(DEVDAT)	;GET DEVICE IO STATUS WORD FROM DDB
;	TLZE IOS,IOW	;IS JOB IN AN IO WAIT FOR THIS DEVICE?
;	PUSHJ PDP,SETIOD	;YES, GO FLAG JOB TO START UP AGAIN
;	RETURN
;SETS THE JOB QUEUE WAIT CODE TO WSQ IN JOB STATUS WORD.
;THE SCHEDULER THEN SEES THAT THIS JOB HAS ITS
;IO WAIT SATISFIED AND IS WAITING TO BE RUN AGAIN

INTERNAL SETIOD,STTIOD
EXTERNAL WSQ,WSAVAL,TSQ,TSAVAL,JOB,PJOBN

PJBS2:	POINT JWSIZ,JBTSTS(TAC),JWPOS	;BYTE POINTER TO JOB STATUS
				; WORD QUEUE CODE

STTIOD:	MOVEI TAC1,TSQ		;SET TTY IO WAIT SATISFIED QUEUE CODE
	AOS TSAVAL
	JRST SETID1
SETIOD:	MOVEI TAC1,WSQ		;REQUE TO WAIT SATISFIED Q
	AOS WSAVAL		;INCR. NO. OF JOBS WITH IO WAIT
				; SATISFIED. NON-ZERO WSAVAL WILL
				; CAUSE SCHED. TO SCAN FOR IO
				; SATISFIED JOB.
SETID1:	LDB TAC,PJOBN
	DPB TAC1,PJBS2		;IN JOB STATUS WORD

INTERNAL FTSWAP
IFN FTSWAP,<
	EXTERN QJOB,JBTSTS
	MOVSI TAC1,JRQ		;SET JOB TO BE REQUEUED AT NEXT CLOCK TICK
	TDNN TAC1,JBTSTS(TAC)	;IS REQUE BIT ALREADY ON?
	AOS QJOB		;NO, INCREMENT COUNT ONCE FOR EACH JOB
	IORM TAC1,JBTSTS(TAC)	;SET REQUEUEING BIT FOR SCHEDULER
>
NULTST:	SKIPE JOB		;IS NULL JOB RUNNING?
	POPJ PDP,		;NO LET OTHER JOB RUN TILL SCHEDULER IS TRAPPPED TO
;ROUTINE TO CAUSE CLK ROUTINE TO RESCHEDULE
;CALLED AT ANY LEVEL
;CALL:	PUSHJ PDP,STOP2	
;	RETURN IMMEDIATELY EXCEPT IF AT UUO LEVEL
;	IF AT UUO LEVEL, RETURN WHEN JOB IS RUNABLE AGAIN

INTERNAL STOP2
EXTERNAL PICLK,CLKFLG

STOP2:	CONO PI,PIOFF	;PREVENT CLOCK INTERRUPT DURING STOP2 CODE
	SETOM CLKFLG	;SET FLAG TO INDICATE CLK INTERRUPT
			; EVEN THOUGH CLK INTERRUPT IS NOT A TIME INTERRUPT
	CONO PI,PICLK	;TURN PI BACK ON AND REQUEST INTERRUPT TO
			; CLK PI CHANNEL(LOWEST PRIORITY CHANNEL)
	POPJ PDP,	;INTERRUPT IMMEDIATELY IF AT UUO LEVEL
;ROUTINE TO WAIT TILL DEVICE CATCHES UP WITH USER AND BECOMES INACTIVE
,CALLING SEQUENCE
,     PUSHJ PDP, WAIT1
,     EXIT	  ALWAYS RETURNS HERE
 
,IF THE DEVICE IS INACTIVE (IOACT=0), RETURNS TO EXIT. OTHERWISE, SETS
,IOW:=1 AND ENTERS WAIT UNLESS IOACT BECOMES ZERO BEFORE THE
,JUMP IS MADE, IN WHICH CASE IT SETS IOW:=0 AND RETURNS TO EXIT.
,ON LEAVING THE WAIT STATE, RETURNS TO EXIT.
,THIS ROUTINE PREVENTS THE STATE IOACT=0 AND IOW=1 FROM OCCURING
,CALLING SEQUENCE
,     PUSHJ PDP, WSYNC
,     EXIT             ALWAYS RETURNS HERE
,SETS IOW:=1 AND ENTERS WAIT ROUTINE. RETURNS TO EXIT WHEN IOACT=0.

INTERNAL WAIT1

WAIT1:	MOVE IOS,DEVIOS(DEVDAT)
	TRNN IOS, IOACT		;IS DEVICE ACTIVE? (IOACT=1?)
	POPJ PDP,		;RETURN
	PUSHJ PDP,WSYNC		;WAIT
	JRST WAIT1
;WSYNC IS CALLED TO WAIT UNTIL SETIOD IS CALLED BY INTERRUPT SERVICE ROUTINE
;IE  UNTIL CURRENT BUFFER ACTIVITY IS COMPLETED
;CALLED ONLY FROM UUO LEVEL
;CALL:	MOVE DEVDAT,ADR. OF DEVICE DATA BLOCK
;	PUSHJ PDP,WSYNC
;	RETURN IMMEDIATELY IF DEVICE IS INACTIVE
;	RETURN WHEN DEVICE FINISHES NEXT BUFFER IF IT IS ACTIVE


INTERNAL WSYNC
EXTERNAL IOWQ,TIOWQ,PION,PIOFF

WSYNC:	MOVSI IOS,IOW		;SETUP DEVICE IO WAIT BIT
	MOVEI AC1,IOWQ		;IO WAIT STATE CODE
	MOVE AC3,DEVMOD(DEVDAT)	;DEVICE CHARACTERISTICS
	TLNE AC3,DVTTY		;IS THIS DEVICE A TTY?
	MOVEI AC1,TIOWQ		;YES, SET TTY WAIT STATE CODE
	MOVE AC3,JOB		;CURRENT JOB NO.
	MOVEI AC2,IOACT		;DEVICE ACTIVE BIT
	CONO PI, PIOFF		;TURN PI OFF
	TDNN AC2,DEVIOS(DEVDAT)	;IS THE DEVICE ACTIVE?
	JRST WSYNC1		;NO
	IORM IOS,DEVIOS(DEVDAT)	;YES, SET DEVICE IO-WAIT BIT
				; AND SETUP IOS FOR RETURN WHEN WAIT SATISFIED
	DPB AC1,PJBS1		;SET JOB WAIT STATE CODE
				; IN JOB STATUS WORD
	CONO PI, PION		;TURN PI ON
	PUSHJ PDP,WSCHED	;CALL SCHEDULER TO FIN ANOTHER JOB TO RUN
				; RETURN WHEN NEXT BUFFERFUL IS FINISHED
				; WITH ACS 0-14 OCTAL RESTORED
				; RETURN WHEN IO-WAIT FINISHED
WSYNC1:	CONO PI, PION
	ANDCAB IOS, DEVIOS(DEVDAT)	;CLEAR DEVICE IO-WAIT BIT
	POPJ PDP,


CLKEND:	END