Trailing-Edge
-
PDP-10 Archives
-
bb-bt99o-bb
-
ctxser.x21
There are 3 other files named ctxser.x21 in the archive. Click here to see a list.
TITLE CTXSER - TOPS10 CONTEXT SERVICE - V111
SUBTTL D. MASTROVITO/DPM/JMF/NT/RCB 25-OCTOBER-88
SEARCH F,S
SALL ;FOR CLEAN LISTINGS
.DIRECTIVE FLBLST ;FOR CLEANER LISTINGS
$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 1981,1982,1983,1984,1986,1988.
;ALL RIGHTS RESERVED.
.CPYRT<1981,1988>
XP VCTXSER,111 ;PUT VERSION NUMBER IN STORAGE MAP AND GLOB
CTXSER::ENTRY CTXSER ;ALWAYS LOAD CTXSER IF LIBRARY SEARCH
REPEAT 0,<
LOOSE ENDS:
CTXSER:
INVENT INTERLOCK TO PREVENT RACES BETWEEN QUOTA CHECKS AND
THE ACTUAL SAVE PROCESS. THIS IS NEEDED TO KEEP THE SYSTEM
CONTEXT AND SAVED PAGE COUNTERS ACCURATE ON A MULTI-CPU SYSTEM.
FINISH CODING CX RESOURCE.
ERRCON/CTXSER:
ADD CTXZAP ROUTINE TO BE CALLED BY ZAPHIM/ZAPHER/ZAPJOB AND FRIENDS
>
SUBTTL CONTEXT PARAMETERS -- OFFSETS AND MACRO DEFINITIONS
; DEFINE ENTRIES IN CSRTAB
.CXNUM==0 ;;INIT COUNTER
DEFINE CTX (NAM,WDS,ARG),<
IFNDEF .CX'NAM,<.CX'NAM==.CXNUM>
.CXNUM==.CXNUM+WDS ;;COUNT WORDS SAVED IN CONTEXT BLOCK
EXP <ARG> ;;INSTRUCTION TO EXECUTE
> ;END CTX MACRO
;SPECIAL DUPLICATE DEFINITION FOR SPECIAL CHARACTER STATUS BYTES
LDBCSL==:<CK.CHR/<^D36/CC.WID>>+1 ;NUMBER OF WORDS REQUIRED TO STORE THE BYTES
MAXLVL==:5
DEFINE CTXSFD (ARG),<
ZZ==0
REPEAT ARG,<
CTX (SFD,1,EXP <.PDSFD##+ZZ(W)>)
ZZ==ZZ+1
> ;;END REPEAT
> ;END CTXSFD MACRO
SUBTTL CONTEXT PARAMETERS -- TABLE
; THE CTX MACRO DEFINES THE JOB PARAMETERS THAT GET SAVED AND
; RESTORED ON CONTEXT CALLS. THE SAVE AND RESTORE ROUTINES
; LOOP THROUGH THE TABLE PROCESSING EACH ENTRY. EACH EACH
; HAS ONE OF THREE FORMATS:
;
; EXP ADDR WHERE ADDR IS AN ADDRESS INCLUDING
; INDEXING AND INDIRECTION THAT WILL
; BE SAVED OR RESTORED
;
; 1B0+ADDR WHERE ADDR IS A SUBROUTINE TO EXECUTE
;
; 1B1+ADDR WHERE ADDR IS AN ADDRESS INCLUDING
; INDEXING AND INDIRECTION THAT WILL
; BE SAVED-AND-ZEROED OR RESTORED
CSRTAB: CTX (SYS,1,1B0+CSRSYS) ;FROM SYS BIT
CTX (MON,1,1B0+CSRMON) ;MONITOR MODE BIT, ETC.
CTX (SCX,1,1B1+.PDSCX##(W)) ;SAVCTX WORD (ALSO .PDNET)
EXTERN .PDNET
CTX (BKM,LDBCSL+3,1B0+CSRBKM) ;TTY BREAK MASK
CTX (PIA,1,1B1+JBTPIA##(J)) ;PSI DATA BASE (PIT)
CTX (IPC,11,1B0+CSRIPC) ;IPCF DATA BASE
CTX (ENQ,1,1B0+CSRENQ) ;ENQ/DEQ QUEUE CHAIN ADDRESS
CTX (TTY,13,1B0+CSRTTY) ;TTY DDB
CTX (STS,1,1B0+CSRSTS) ;JOB STATUS
IFE FTFDAE,<CTX (ST2,1,EXP <JBTST2##(J)>)> ;SECOND JOB STATUS WORD
IFN FTFDAE,<CTX (ST2,1,1B0+CSRST2)> ;SECOND JOB STATUS WORD
CTX (SWP,1,EXP <JBTSWP##(J)>) ;SWAPPED OUT DISK ADDRESS
CTX (IMI,1,EXP <JBTIMI##(J)>) ;SWAPPED IN IMAGE SIZE
CTX (IMO,1,EXP <JBTIMO##(J)>) ;SWAPPED OUT IMAGE SIZE
CTX (SGN,1,1B0+CSRSGN) ;HIGH SEGMENT DATA BASE POINTER
CTX (AD2,1,1B0+CSRAD2) ;JBTAD2
CTX (PDB,1,EXP <JBTPDB##(J)>) ;NUMBER OF FUNNY PAGES
CTX (CHK,1,EXP <JBTCHK##(J)>) ;SWAPPED OUT CHECKSUM
CTX (PRG,1,EXP <JBTNAM##(J)>) ;PROGRAM NAME
CTX (PC,1,EXP <JBTPC##(J)>) ;USER PC
CTX (DDB,1,EXP <JBTDDB##(J)>) ;I/O WAIT DDB
CTX (NAM,1,EXP <.PDNAM##(W)>) ;PROGRAM FILE NAME
CTX (STR,1,EXP <.PDSTR##(W)>) ;PROGRAM STRUCTURE
CTX (DIR,1,EXP <.PDDIR##(W)>) ;PROGRAM PPN
CTXSFD (MAXLVL) ;PROGRAM SFDS
CTX (STM,1,EXP <.PDSTM##(W)>) ;TIME OF LAST RESET
CTX (CMN,1,EXP <.PDCMN##(W)>) ;POINTER TO USER DEFINED COMMANDS
CTX (UNQ,1,EXP <.PDUNQ##(W)>) ;POINTER TO UNQTAB FOR USER COMMANDS
IFN FTDECNET,<CTX (SJB,1,1B1+.PDSJB##(W))> ;DECNET DATA BASE
IFN FTKL10,<CTX (ABS,1,EXP <.PDABS##(W)>)> ;ADDRESS BREAK SETTINGS
CTX (TMI,1,EXP 1B1+<.PDTMI##(W)>) ;VIRTUAL TIMER TRAP INTERVAL
CTX (TMC,1,EXP 1B1+<.PDTMC##(W)>) ;COUNTER FOR ABOVE
CTX (SPS,1,1B0+CSRSPS) ;SET RUN ONLY CPU7
CTX (VRT,1,EXP <JBTVIR##(J)>) ;PROGRAM SIZE FOR CONTROL-T
CTX (CVL,1,EXP <.PDCVL##(W)>) ;CVPL,,CPPL
CTX (PVT,1,EXP <.PDVRT##(W)>) ;FAULT RATE
CTX (LBS,1,1B0+CSRLBS) ;UUO-SET BIGBUF N
IFN FTHPQ,<CTX (RTD,1,1B0+CSRRTD)> ;HPQ AND HIBER SETTINGS
IFE FTHPQ,<CTX (RTD,1,EXP <JBTRTD##(J)>)> ;HIBER SETTINGS
IFN FTSCA,<CTX (SCS,1,EXP <.PDSCS##(W)>)> ;SCS. UUO
IFN FTENET,<CTX (EJB,1,1B1+<.PDEJB##(W)>)> ;ETHNT. UUO DATABASE
IFN FTPATT,<CTX (PAT,1,1B0+CSRPAT)> ;PATCH SPACE (CSRPAT SHOWS HOW TO USE)
CSRLEN==.-CSRTAB ;LENGTH OF TABLE
SUBTTL CONTEXT BLOCK DEFINITIONS
; OFFSETS INTO THE DATA BLOCK POINTED TO BY .PDSAC(W)
.CTFLG==0 ;CONTEXT BLOCK FLAGS
.CTJCH==.CTFLG+1 ;OWNER JOB/CONTEXT HANDLE AT CREATION TIME
.CTNXT==.CTJCH+1 ;NEXT CONTEXT BLOCK ADDRESS
.CTPRV==.CTNXT+1 ;PREVIOUS CONTEXT BLOCK ADDRESS
.CTSUP==.CTPRV+1 ;SUPERIOR CONTEXT BLOCK ADDRESS
.CTLAS==.CTSUP+1 ;LAST CONTEXT BLOCK ADDRESS CONTAINING ARGS
.CTNEW==.CTLAS+1 ;NEW CONTEXT ADDRESS
.CTRET==.CTNEW+1 ;CTX. UUO RETURN AC
.CTCBN==.CTRET+1 ;CONTXT BLOCK NAME IN SIXBIT
.CTNCN==.CTCBN+1 ;NEW CONTEXT NAME
.CTIDL==.CTNCN+1 ;UPTIME WHEN CONTEXT WENT IDLE
.CTPRG==.CTIDL+1 ;AUTO-SAVE COMMAND PROGRAM NAME
.CTDSP==.CTPRG+1 ;AUTO-SAVE COMMAND DISPATCH
.CTDTL==.CTDSP+1 ;DATA BLOCK LENGTH(S)
.CTDTU==.CTDTL+1 ;DATA BLOCK ADDRESS IN USER CORE
.CTDTE==.CTDTU+1 ;DATA BLOCK ADDRESS IN EXEC CORE
.CTDTT==.CTDTE+1 ;DATA BLOCK ADDRESS IN EXEC CORE (TEMPORARY)
.CTTCR==.CTDTT+1 ;TMPCOR FILE LENGTH,,NAME
.CTTCA==.CTTCR+1 ;TMPCOR FILE ADDRESS (USER)
.CTTCE==.CTTCA+1 ;TMPCOR FILE ADDRESS (EXEC)
.CTRUA==.CTTCE+1 ;RUN UUO AC (OFFSET,,SECTION #)
.CTRUB==.CTRUA+1 ;RUN UUO BLOCK
.CTPUB==.CTRUB+6 ;PATH UUO BLOCK (MUST BE ADJACENT TO .CTRUB)
.CTBPR==.CTPUB+2+MAXLVL+1 ;BEGINING OF SAVED PARAMETER AREA
.CTEPR==.CTBPR+.CXNUM-1 ;END OF SAVED PARAMETER AREA
.CTSIZ==.CTEPR+1 ;LENGTH OF SAVED CONTEXT BLOCK
; FLAGS AND FIELDS USED FOR CONTEXT CREATION AND BY THE SCHEDULER (.PDCTX).
; THE CONTEXT NUMBER FOR MIGRATION CONTROL OCCUPIES THE RIGHT-MOST BITS
; IN .PDCTX AND IS ONLY REFERENCED BY THE BYTE POINTER "PCTXMF".
CT.SCD==1B0 ;CALL FROM SCHEDULER TO SAVE CONTEXT
CT.ATO==1B1 ;AUTO-SAVE DONE
CT.TOP==1B2 ;CREATE A NEW TOP LEVEL CONTEXT
CT.SWT==1B3 ;SWITCH TO AN EXISTING CONTEXT
CT.HLT==1B5 ;SAVE CONTEXT AND HALT JOB
CT.UUO==1B6 ;SAVE CONTEXT VIA UUO
CT.PRN==1B7 ;PHYSICAL DEVICE SEARCH ON RUN UUO
CT.LGO==1B18 ;LOGGING OUT
CT.MTJ==1B19 ;MIGRATING THIS JOB
; FLAGS AND FIELDS RETAINED FOR EACH CONTEXT (.CTFLG). THE CONTEXT
; NUMBER OCCUPIES THE RIGHT-MOST BITS AND IS ONLY REFERENCED BY THE
; BYTE POINTER "PCTXNO".
CT.INF==1B9 ;CONTEXT HAS AT LEAST ONE INFERIOR
CT.UUE==1B10 ;UUO ERROR HAS OCCURRED
CT.DEL==1B11 ;DELETE A CONTEXT
CT.CON==1B12 ;CONTINUE PREVIOUS CONTEXT
CT.UAC==17B17 ;UUO AC
SUBTTL BYTE POINTERS
PCTXMF: <Z .PDCTX##(W)>+CTXCBP## ;MIGRATE'S FIRST CONTEXT NUMBER
PCTXPQ: <Z .PDCTQ##(W)>+CTXPBP## ;PAGE QUOTA
PCTXCQ: <Z .PDCTQ##(W)>+CTXCBP## ;CONTEXT QUOTA
PCTXPU: <Z .PDCTU##(W)>+CTXPBP## ;PAGES IN USE
PCTXCU: <Z .PDCTU##(W)>+CTXCBP## ;CONTEXTS IN USE
PCTXUA: POINT 4,.CTFLG(P1),17 ;UUO AC
PCTXNO: <Z .CTFLG(P1)>+CTXCBP## ;CONTEX NUMBER IN A CONTEXT BLOCK
PCTXDW: POINT 9,T1,26 ;RETURNED DATA BLOCK LENGTH
PCTXEC: POINT 9,T1,35 ;RETURNED ERROR CODE
SUBTTL DATA BASE INTERLOCK MACROS
; MACRO TO INTERLOCK REFERENCES TO THE CTXSER DATA BASE
DEFINE CTXLOK,<
IFN FTMP,<PUSHJ P,LOKCTX>
>
DEFINE CTXNLK,<
IFN FTMP,<PUSHJ P,NLKCTX>
>
SUBTTL ENTRY POINTS -- CTXINI - INITIALIZE
; CALLED FROM SYSINI TO SET SYSTEM QUOTAS BASED ON VIRTAL
; CALL: PUSHJ P,CTXINI
CTXINI::SE1ENT ;ENTER SECTION 1
MOVEI T1,JOBMAX## ;GET MAXIMUM NUMBER OF JOBS
IMUL T1,JOBCCQ ;TIMES THE NUMBER OF CONTEXTS PER JOB
MOVEM T1,SYSCCQ ;SAVE
MOVEI T1,JOBMAX## ;GET JOBMAX AGAIN
IMUL T1,JOBCPQ ;TIMES THE NUMBER OF PAGES PER JOB
CAMLE T1,VIRTAL## ;CAN THE SWAPPER HANDLE THIS MUCH?
MOVE T1,VIRTAL## ;NO
MOVEM T1,SYSCPQ ;SAVE
IFN FTXMON,<
SKIPN T2,RESMAX ;ANY RESERVED LIST ALLOWED?
POPJ P, ;NO, GIVE UP
IMULI T2,.CTSIZ ;YES, CALCULATE NUMBER OF WORDS TO POPULATE IT
PUSHJ P,GFWNZS## ;GET SOME NZS CORE
POPJ P, ;PUNT IF CAN'T DO IT
MOVEM T1,RESBLK ;SAVE THE START ADDRESS OF THE LIST
MOVEI T2,.CTSIZ-1 ;HOW MANY WORDS WE NEED TO CLEAR
MOVE T3,T1 ;COPY START ADDRESS OF THE TRANSFER
XMOVEI T4,1(T3) ;FORM DESTINATION ADDRESS
SETZM (T3) ;CLEAR THE FIRST WORD
EXTEND T2,[XBLT] ;SMEAR SOME ZEROS AROUND
MOVSI T2,'CTX' ;TAG FOR LOST CORE TRACERS
MOVEM T2,.CTJCH(T1) ;SAVE IN THE BLOCK
MOVE T2,RESMAX ;HOW MANY BLOCKS WE ALLOCATED
MOVEM T2,RESCNT ;SAVE FOR CREBLK/DELBLK
SUBI T2,1 ;ONE IS ALREADY INITIALIZED
IMULI T2,.CTSIZ ;HOW MANY WORDS TO TRANSFER
MOVE T3,T1 ;COPY START ADDRESS OF TRANSFER
XMOVEI T4,.CTSIZ(T3) ;AND DESTINATION ADDRESS
EXTEND T2,[XBLT] ;INITIALIZE THE REST OF THE BLOCKS
MOVE T2,RESMAX ;HOW MANY WE ALLOCATED
SOJE T2,CPOPJ## ;ONLY ONE?!?
CTXIN1: ADDI T1,.CTSIZ ;BUMP TO NEXT ADDRESS
MOVEM T1,.CTNXT-.CTSIZ(T1) ;POINT PREVIOUS TO THIS ONE
SOJG T2,CTXIN1 ;LOOP UNTIL ALL ARE LINKED
> ;END IFN FTXMON
POPJ P, ;RETURN
SUBTTL ENTRY POINTS -- CTXBLK - CREATE CONTEXT BLOCK FOR A NEW JOB
CTXBLK::JUMPE J,CPOPJ1## ;NO-OP FOR THE NULL JOB
SE1ENT ;ENTER SECTION 1
PUSHJ P,SAVE1## ;SAVE P1
PUSHJ P,CREBLK ;CREATE A CONTEXT BLOCK
POPJ P, ;NOT ENOUGH CORE
MOVEI T1,1 ;START WITH CONTEXT NUMBER ONE
DPB T1,PCTXCU ;SET IT
AOS SYSCCU ;COUNT UP SYSTEM-WIDE CONTEXTS IN USE
PUSHJ P,FREECT ;FIND AND ASSIGN A FREE CONTEXT NUMBER
SKIPN T1,JOBCCQ ;GET DEFAULT CONTEXT QUOTA
MOVEI T1,CTXMAX## ;MAKE IT ABSOLUTE MAXIMUM
DPB T1,PCTXCQ ;SET IT
MOVE T1,JOBCPQ ;GET DEFAULT SAVED PAGE QUOTA
DPB T1,PCTXPQ ;SET IT
JRST CPOPJ1## ;DONE
SUBTTL ENTRY POINTS -- CTXPRT - CONTROL-T TYPEOUT
CTXPRT::SE1ENT ;ENTER SECTION 1
PUSHJ P,SAVE1## ;SAVE P1
MOVEI T1,[ASCIZ | Ctx:|]
PUSHJ P,CONMES## ;TYPE TEXT
SKIPN P1,.PDCTC##(W) ;POINT TO CURRENT CONTEXT BLOCK
TDZA T1,T1 ;JOB BEING KILLED
LDB T1,PCTXNO ;GET CONTEXT NUMBER
PJRST PRTDIG## ;TYPE IT AND RETURN
SUBTTL ENTRY POINTS -- CTXKIL - ARBITRARILY DELETE CONTEXT BLOCKS
CTXKIL::SE1ENT ;ENTER SECTION 1
LDB T1,PCTXCU ;GET NUMBER OF CONTEXTS IN USE
JUMPE T1,CPOPJ## ;RETURN IF NONE
PUSHJ P,RELINK ;RELINK ALL BLOCKS
POPJ P, ;NONE LEFT??
KILL1: PUSHJ P,DELBLK ;DELETE A BLOCK
PUSHJ P,DNCTXN ;DECREMENT CONTEXT USE COUNT
SKIPE .PDCTC##(W) ;HAVE A NEW "CURRENT" CONTEXT BLOCK?
JRST KILL1 ;YES
POPJ P, ;ALL DONE
SUBTTL ENTRY POINTS -- CTXLGO - DELETE CONTEXTS WHEN KILLING A JOB
CTXLGO::SE1ENT ;ENTER SECTION 1
LDB T1,PCTXCU ;GET NUMBER OF CONTEXTS IN USE
JUMPE T1,CPOPJ## ;ALREADY BEEN THROUGH HERE ONCE
SOJE T1,LOGOU1 ;GO DELETE THE BLOCK AND RETURN IF ONLY ONE
PUSHJ P,RELINK ;RELINK ALL BLOCKS
POPJ P, ;NO CONTEXT BLOCKS??
PUSHJ P,SWTCTX ;SWITCH TO THE MOST INFERIOR CONTEXT
JFCL ;CAN'T FAIL
LOGOU1: PUSHJ P,DELBLK ;FINALLY DELETE THE CURRENT CONTEXT BLOCK
PJRST DNCTXN ;COUNT DOWN CONTEXT USE COUNT AND RETURN
SUBTTL ENTRY POINTS -- CTXNUM/CTXJCH - RETURN CURRENT CONTEXT NUMBER
; RETURN THE CURRENT CONTEXT NUMBER IN T1
; CALL: MOVE T1, JOB NUMBER
; PUSHJ P,CTXNUM
; <ERROR> ;ILLEGAL JOB NUMBER
; <SKIP> ;OK, CTX/JCH IN T1
CTXJCJ::SKIPA T1,J ;CTXJCH FOR CURRENT JOB
CTXNUM::TLOA T2,-1 ;FLAG CTX ENTRY
CTXJCH::TLZ T2,-1 ;FLAG JCH ENTRY POINT
JUMPLE T1,CPOPJ## ;CAN'T BE NEGATIVE OR ZERO
CAILE T1,JOBMAX## ;RANGE CHECK
POPJ P, ;LOSE
HRR T2,T1 ;COPY ARGUMENT
PUSHJ P,FPDBT1## ;FIND THE PDB
POPJ P, ;RETURN
SE1ENT ;ENTER SECTION 1
SKIPN .PDSAC##(T1) ;HAVE A CONTEXT BLOCK CHAIN?
POPJ P, ;NO, LOSE
PUSH P,P1 ;SAVE P1
MOVE P1,.PDCTC##(T1) ;POINT TO CURRENT CONTEXT BLOCK
LDB T1,PCTXNO ;GET ITS CONTEXT NUMBER
POP P,P1 ;RESTORE
JUMPL T2,CPOPJ1## ;RETURN IF ONLY CONTEXT NUMBER REQUESTED
LSH T1,CTXLSH## ;ELSE POSITION
IOR T1,T2 ;INCLUDE JOB NUMBER
JRST CPOPJ1## ;AND RETURN
; VALIDATE A JOB/CONTEXT HANDLE
; CALL: MOVE T1, JOB/CONTEXT HANDLE
; PUSHJ P,CTXVAL
; <NON-SKIP> ;NO SUCH JOB OR CONTEXT
; <SKIP 1> ;JCH IS FOR CURRENT CONTEXT OF JOB
; <SKIP 2> ;JCH OK BUT NOT CURRENT
CTXVAL::SE1ENT ;ENTER SECTION 1
PUSH P,P1 ;SAVE P1 FOR CALLERS
PUSHJ P,JBCHCT ;CHECK OUT JCH
JRST P1POPJ## ;NONESUCH
CAIA ;SKIP ONCE
AOS -1(P) ;SKIP TWICE
AOS -1(P) ;OR ONCE
JRST P1POPJ## ;NOW RESTORE AND RETURN
SUBTTL ENTRY POINTS -- CTXPSI - RETURN PIT FOR ANY CONTEXT
; RETURN THE PIT FOR A GIVEN JOB/CONTEXT HANDLE
; CALL: MOVE T1,JOB/CONTEXT HANDLE
; PUSHJ P,CTXPSI
; <NON-SKIP> ;NO SUCH JOB OR CONTEXT
; <SKIP> ;T1 = JOB/CONTEXT HANDLE NUMBER
; ;T2 = ADDRESS OF PIT
CTXPSI::SE1ENT ;ENTER SECTION 1
PUSHJ P,SAVE1## ;SAVE P1
PUSHJ P,JBCHCT ;FIND THE CONTEXT BLOCK
POPJ P, ;NO SUCH JOB OR CONTEXT
JRST PSICUR ;FOUND CURRENT CONTEXT FOR A JOB
MOVE T2,.CTBPR+.CXPIA(P1) ;GET JBTPIA
JRST CPOPJ1## ;RETURN
PSICUR: MOVE T2,T1 ;COPY JCH
ANDI T2,JOBMSK## ;ONLY WANT JOB NUMBER
MOVE T2,JBTPIA##(T2) ;GET PIT
JRST CPOPJ1## ;RETURN
SUBTTL ENTRY POINTS -- CTXIPC - RETURN IPCF DATA
; RETURN IPCF DATA FOR A GIVEN JOB/CONTEXT HANDLE
; CALL: MOVE T1,JOB/CONTEXT HANDLE
; PUSHJ P,CTXIPC
; <NON-SKIP> ;NO SUCH JOB OR CONTEXT
; <SKIP> ;J = JOB/CONTEXT HANDLE NUMBER
; ;W = ADDRESS OF IPCF DATA BLOCK
CTXIPC::TRNN T1,JOBMSK## ;ANY JOB #?
JRST IPCCUR ;NO, JUST NUL JOB THEN
PUSHJ P,SAVE1## ;SAVE P1
PUSHJ P,JBCHCT ;FIND THE CONTEXT BLOCK
POPJ P, ;NO SUCH JOB OR CONTEXT
JRST IPCCUR ;FOUND THE CURRENT ONE
MOVE J,T1 ;COPY UPDATED JOB/CONTEXT HANDLE
XMOVEI W,.CTBPR+.CXIPC(P1) ;POINT TO DATA BLOCK
JRST CPOPJ1## ;RETURN
IPCCUR: MOVE J,T1 ;COPY JCH
ANDI T1,JOBMSK## ;KEEP ONLY JOB NUMBER
HRRZ T1,JBTPDB##(T1) ;POINT TO PDB
MOVEI W,.PDIPC##(T1) ;POINT TO START OF IPCF DATA BLOCK
JRST CPOPJ1## ;AND RETURN
SUBTTL ENTRY POINTS -- CTXENQ - RETURN .PDEQJ FOR ANY CONTEXT
; RETURN THE START OF THE QUEUE CHAIN FOR A GIVEN JOB/CONTEXT HANDLE
; CALL: MOVE T1,JOB/CONTEXT HANDLE
; PUSHJ P,CTXENQ
; <NON-SKIP> ;NO SUCH JOB OR CONTEXT
; <SKIP> ;T1 = JOB/CONTEXT HANDLE NUMBER
; ;T2 = C(.PDEQJ)
CTXENQ::SE1ENT ;ENTER SECTION 1
PUSHJ P,SAVE1## ;SAVE P1
PUSHJ P,JBCHCT ;FIND THE CONTEXT BLOCK
POPJ P, ;NO SUCH JOB OR CONTEXT
SKIPA T2,.PDEQJ##(W) ;GET .PDEQJ FOR CURRENT CONTEXT
MOVE T2,.CTBPR+.CXENQ(P1) ;GET .PDEQJ
JRST CPOPJ1## ;RETURN
SUBTTL ENTRY POINTS -- CTXJPK - JOBPEK UUO SUPPORT
; RETURN JBTSWP FOR A GIVEN JOB/CONTEXT HANDLE
; CALL: MOVE T1,JOB/CONTEXT HANDLE
; PUSHJ P,CTXJPK
; <NON-SKIP> ;NO SUCH JOB OR CONTEXT
; <SKIP> ;T1 = JOB/CONTEXT HANDLE NUMBER
; ;T2 = C(JBTSWP)
CTXJPK::SE1ENT ;ENTER SECTION 1
PUSHJ P,SAVE1## ;SAVE P1
PUSHJ P,JBCHCT ;FIND THE CONTEXT BLOCK
POPJ P, ;NO SUCH JOB OR CONTEXT
JRST JPKCUR ;FOUND CURRENT CONTEXT FOR A JOB
MOVE T2,.CTBPR+.CXSWP(P1) ;GET JBTSWP
JRST CPOPJ1## ;RETURN
JPKCUR: MOVE T2,T1 ;COPY JCH
ANDI T2,JOBMSK## ;ONLY WANT JOB NUMBER
MOVE T2,JBTSWP##(T2) ;GET DISK ADDRESS
JRST CPOPJ1## ;RETURN
SUBTTL ENTRY POINTS -- CTXSGN - JOBPEK UUO SUPPORT
; RETURN JBTSGN FOR A GIVEN JOB/CONTEXT HANDLE
; CALL: MOVE T1,JOB/CONTEXT HANDLE
; PUSHJ P,CTXSGN
; <NON-SKIP> ;NO SUCH JOB OR CONTEXT
; <SKIP> ;T1 = JBTSGN ENTRY
CTXSGN::SE1ENT ;ENTER SECTION 1
PUSHJ P,SAVE1## ;SAVE P1
PUSHJ P,JBCHCT ;FIND THE CONTEXT BLOCK
POPJ P, ;NO SUCH JOB OR CONTEXT
JRST SGNCUR ;FOUND CURRENT CONTEXT FOR A JOB
HRRZ T1,.CTBPR+.CXSGN(P1) ;GET JBTSGN
JRST CPOPJ1## ;RETURN
SGNCUR: ANDI T1,JOBMSK## ;WANT ONLY JOB NUMBER FROM JCH
HRRZ T1,JBTSGN##(T1) ;GET JBTSGN
JRST CPOPJ1## ;RETURN
SUBTTL ENTRY POINTS -- CTXSTS - GET STATUS OF ANY CONTEXT
; GET THE STATUS INFORMATION FOR A GIVEN JOB/CONTEXT HANDLE
; CALL: MOVE T1,JOB/CONTEXT HANDLE
; PUSHJ P,CTXSTS
; <NON-SKIP> ;NO SUCH JOB OR CONTEXT
; <SKIP> ;STATUS RETRIEVED IN T1 & T2
;
; RETURNS:
; T1/ JBTSTS ENTRY FOR GIVEN JOB/CONTEXT HANDLE
; T2/ JBTST2 ENTRY CORRESPONDING
CTXSTS::SE1ENT ;DO IN RIGHT SECTION
PUSHJ P,SAVE1## ;PRESERVE FOR OUR CALLER
PUSHJ P,JBCHCT ;GET CONTEXT BLOCK
POPJ P, ;PROPAGATE FAILURE
JRST STSCUR ;CURRENT JCH
HRRZ T1,.CTBPR+.CXSCX(P1) ;POINT TO SAVCTX BLOCK
SKIPE T1 ;IF THERE,
SKIPA T1,2(T1) ;GET ITS SAVED JBTSTS
MOVE T1,.CTBPR+.CXSTS(P1) ;ELSE USE OURS
MOVE T2,.CTBPR+.CXST2(P1) ;GET OUR SAVED JBTST2
JRST CPOPJ1## ;RETURN GOODNESS
STSCUR: ANDI T1,JOBMSK## ;ONLY NEED THE JOB NUMBER
MOVE T2,JBTST2##(T1) ;GET JBTST2
MOVE T1,JBTSTS##(T1) ;AND JBTSTS
JRST CPOPJ1## ;RETURN AS ADVERTISED
SUBTTL ENTRY POINTS -- CTXEWK - EWAKE ANY CONTEXT
; BREAK ANY CONTEXT OUT OF EVENT WAIT FOR A GIVEN JOB/CONTEXT HANDLE
; CALL: MOVE T1,JOB/CONTEXT HANDLE
; PUSHJ P,CTXEWK
; <NON-SKIP> ;NO SUCH JOB OR CONTEXT
; <SKIP> ;JOB/CONTEXT CLEARED FROM EVENT WAIT
CTXEWK::SE1ENT ;DO THIS IN CORRECT SECTION
PUSHJ P,SAVE1## ;FOR OUR CALLER
PUSHJ P,JBCHCT ;FIND CONTEXT BLOCK
POPJ P, ;NOT THERE
JRST EWKCUR ;CURRENT CONTEXT
MOVEI T1,EWAKEB ;WAKE UP PENDING
IORM T1,.CTBPR+.CXST2(P1) ;LIGHT THE MAGIC BIT
JRST CPOPJ1## ;AND RETURN GOODNESS
EWKCUR: AOS (P) ;GOING TO SKIP-RETURN
ANDI T1,JOBMSK## ;FOR EWAKE
PJRST EWAKE## ;WAKE JOB AND RETURN
SUBTTL ENTRY POINTS -- CTXWAK - WAKE UP ANY CONTEXT
; WAKE UP ANY CONTEXT FOR A GIVEN JOB/CONTEXT HANDLE
; CALL: MOVE T1,JOB/CONTEXT HANDLE
; PUSHJ P,CTXWAK
; <NON-SKIP> ;NO SUCH JOB OR CONTEXT
; <SKIP> ;JOB/CONTEXT WOKEN UP
CTXWAK::SE1ENT ;ENTER SECTION 1
PUSHJ P,SAVE1## ;SAVE P1
PUSHJ P,JBCHCT ;FIND THE CONTEXT BLOCK
POPJ P, ;NO SUCH JOB OR CONTEXT
JRST WAKCUR ;CONTEXT IS CURRENT CONTEXT
XMOVEI T2,.CTBPR+.CXSTS(P1) ;POINT TO WHERE WE STORE JBTSTS
HRRZ T1,.CTBPR+.CXSCX(P1) ;GET SAVCTX BLOCK
SKIPE T1 ;IF THERE IS ONE,
XMOVEI T2,2(T1) ;POINT TO WHERE SAVCTX SAVED JBTSTS
SYSPIF ;GUARD AGAINST HIGHER PI ACTIVITY
LDB T1,[POINT JWSIZ,(T2),JWPOS] ;GET CURRENT QUEUE CODE
CAIN T1,SLPQ## ;IS THE JOB IN THE SLEEP QUEUE
JRST WAKSLP ;YES, THEN WAKE THE JOB UP
CAIN T1,NAPQ## ;NOT SLEEP, IS IT A NAP?
JRST WAKNAP ;YES, CLEAR WAIT STATE
MOVSI T1,WAKEB## ;NO, SET WAKEUP BIT INSTEAD
IORM T1,.CTBPR+.CXRTD(P1) ;SET WAKE UP BIT
JRST WAKDON ;RETURN
WAKSLP:
IFN FTPSCD,<
AOS REQWK## ;COUNT A WAKE
>
WAKNAP: MOVEI T1,RNQ## ;PREPARE TO PUT JOB IN THE RUN QUEUE
DPB T1,[POINT JWSIZ,(T2),JWPOS] ;PUT THE JOB IN THE RUN QUEUE
WAKDON: SYSPIN ;TURN THE PI BACK ON
JRST CPOPJ1## ;GIVE SKIP RETURN
WAKCUR: ANDI T1,JOBMSK## ;GET JUST THE JOB NUMBER
AOS (P) ;GIVE GOOD RETURN
S0JRST WAKJOB## ;WAKE UP THE JOB THE OLD WAY
SUBTTL ENTRY POINTS -- CTXWKJ - FINISH SLEEP/HIBER FOR ANY CONTEXT
; WAKE UP ANY CONTEXT FOR A GIVEN JOB/CONTEXT HANDLE AFTER SLEEP TIME EXPIRES
; CALL: MOVE T1,JOB/CONTEXT HANDLE
; PUSHJ P,CTXWKJ
; <NON-SKIP> ;ALWAYS
; CLOBBERS P1
; CALLED ONLY BY SLEEP AND HIBER UUO TIMER EXPIRATIONS
CTXWKJ::SE1ENT ;ENTER SECTION 1
PUSHJ P,JBCHCT ;FIND THE CONTEXT BLOCK
POPJ P, ;NO SUCH JOB OR CONTEXT
JRST WKJCUR ;CURRENT CONTEXT
XMOVEI T2,.CTBPR+.CXSTS(P1) ;POINT TO WHERE WE STORE JBTSTS
HRRZ T1,.CTBPR+.CXSCX(P1) ;GET SAVCTX BLOCK
SKIPE T1 ;IF THERE IS ONE,
XMOVEI T2,2(T1) ;POINT TO WHERE SAVCTX SAVED JBTSTS
MOVEI T1,CLKR## ;GET CLOCK-REQUEST BIT
ANDCAM T1,(T2) ;CLEAR IT FOR NEXT SLEEP/HIBER DONE
LDB T1,[POINT JWSIZ,(T2),JWPOS] ;GET JBTSTS VALUE OF IDLE CONTEXT
CAIE T1,SLPQ## ;IS IT ASLEEP?
CAIN T1,NAPQ## ;OR NAPPING?
TRNA ;YES, SKIP ON
POPJ P, ;NO, FORGET IT
IFN FTPSCD,<
CAIN T1,SLPQ## ;WAS IT SLEEP?
AOS REQSS## ;YES, COUNT UP A SLEEP SATISFIED
>
MOVEI T1,RNQ## ;YES, GET RUN QUEUE
DPB T1,[POINT JWSIZ,(T2),JWPOS] ;MAKE IT RUNNABLE WHEN NEXT CURRENT
POPJ P, ;RETURN TO CLOCK1
WKJCUR: ANDI T1,JOBMSK## ;KEEP ONLY JOB NUMBER PORTION
S0JRST WAKEJ## ;WAKE UP CURRENT CONTEXT THE OLD WAY
SUBTTL ENTRY POINTS -- CTXMIG/CTXMGN - RETURN DATA FOR MIGRATION
; RETURN DATA FOR MIGRATION
; CALL: MOVE J,JOB NUMBER
; PUSHJ P,CTXMIG
; <NON-SKIP> ;NO IDLE CONTEXTS TO MIGRATE
; <SKIP> ;THERE ARE IDLE CONTEXTS FOR THIS JOB
CTXMIG::PUSHJ P,FNDPDB## ;GET THE PDB
POPJ P, ;NO CONTEXTS IF NO PDB
MOVEI T1,CT.MTJ ;MIGRATING THIS JOB BIT
TDNE T1,.PDCTX##(W) ;TRYING TO RE-START THIS MIGRATION?
STOPCD .,STOP,CTXMCT, ;++CTXMIG CALLED TWICE
LDB T2,PCTXCU ;GET NUMBER OF CONTEXTS IN USE
SOJLE T2,CPOPJ## ;NONE IDLE IF 1 OR 0
PUSHJ P,SAVE1## ;PRESERVE P1
SKIPN P1,.PDCTC##(W) ;GET CURRENT POINTER
POPJ P, ;NONE IDLE IF NO CURRENT
IORM T1,.PDCTX##(W) ;LIGHT MIGRATION BIT
SE1ENT ;ENTER SECTION 1
LDB T1,PCTXNO ;GET CONTEXT NUMBER OF CURRENT CONTEXT
DPB T1,PCTXMF ;STORE AS START OF MIGRATE CHAIN
JRST CPOPJ1## ;GIVE IDLE CONTEXTS EXISTENCE RETURN
; ROUTINE TO ADVANCE TO NEXT CONTEXT FOR MIGRATE
; CALL: MOVE J,JOB NUMBER
; PUSHJ P,CTXMGN
; <NON-SKIP> ;NO MORE CONTEXTS TO MIGRATE (RESET TO INITIAL)
; <SKIP> ;SWITCHED TO NEXT CONTEXT IN JOB
;
; IT IS THE CALLER'S RESPONSIBILITY TO ENSURE THAT THE JOB IS SWAPPED OUT
; BEFORE CALLING US.
CTXMGN::SE1ENT ;ENTER SECTION 1
PUSHJ P,FNDPDS## ;GET THE PDB FOR THE JOB
MOVEI T1,CT.MTJ ;MIGRATE THIS JOB BIT
TDNN T1,.PDCTX##(W) ;CHECK
STOPCD .,STOP,CTXNIP, ;++CTX MIGRATION NOT IN PROGRESS
PUSHJ P,SAVE1## ;SAVE OUR FAVORITE REGISTER
MOVE P1,.PDCTC##(W) ;GET CURRENT POINTER
MOVSI T1,RUN ;THE 'RUNNABLE' BIT
LDB T2,PCTXMF ;NUMBER OF CONTEXT DONE BY MIGRATE
LDB T3,PCTXNO ;NUMBER OF CURRENT CONTEXT
CAME T2,T3 ;FIRST CALL TO CTXMGN?
IORM T1,JBTSTS##(J) ;NO, RESTORE RUN BIT (VALUE UNKNOWN FOR FIRST)
PUSHJ P,SAVECT ;SAVE THE TABLES FOR THIS CONTEXT
MOVE P1,.PDCTC##(W) ;RESTORE CURRENT POINTER (CLOBBERED BY SAVECT)
LDB T4,PCTXMF ;RETRIEVE NUMBER OF MIGRATE'S FIRST CONTEXT
LDB T1,PCTXNO ;GET NUMBER OF CURRENT CONTEXT
CAIE T1,(T4) ;SAME AS START?
SKIPA P1,.CTNXT(P1) ;NO, ADVANCE POINTER
MOVE P1,.PDSAC##(W) ;YES, GO FROM START OF CHAIN
JUMPE P1,CTXMG1 ;DONE IF END OF CHAIN
LDB T1,PCTXNO ;GET CONTEXT NUMBER
CAIN T1,(T4) ;THE ONE MIGRATE ALREADY DID?
MOVE P1,.CTNXT(P1) ;YES, ADVANCE PAST IT
JUMPE P1,CTXMG1 ;CHECK END AGAIN
MOVEM P1,.PDCTC##(W) ;MAKE IT CURRENT
PUSHJ P,RESTCT ;RESTORE ALL THE TABLES FOR MIGRATE TO LOOK AT
MOVSI T1,RUN ;THE 'RUNNABLE' BIT
ANDCAM T1,JBTSTS##(J) ;CLEAR IT TO BE SURE THERE'S NO MISTAKE
JRST CPOPJ1## ;TELL IT WE DID GOOD
CTXMG1: LDB T1,PCTXMF ;GET NUMBER OF FIRST MIGRATION CONTEXT
PUSHJ P,FINDCT ;POINT TO ITS BLOCK
STOPCD .,STOP,CTXFWA, ;++CTXMIG'S FIRST CONTEXT WENT AWAY
MOVEM P1,.PDCTC##(W) ;MAKE IT CURRENT
MOVEI T1,CT.MTJ ;BIT TO CLEAR
ANDCAM T1,.PDCTX##(W) ;CLEAR IT
DPB T1,PCTXMF ;AND THE STARTING POINT
PJRST RESTCT ;RESTORE OUR TABLES AND GIVE DONE RETURN
SUBTTL ENTRY POINTS -- CTXCMD - CONTEXT COMMAND
; CONTEXT COMMAND SYNTAX:
;
; .CONTEXT ;LISTS THE STATUS FOR ALL CONTEXTS
; .CONTEXT <NAME>=<NUMBER> ;NAMES A CONTEXT
; .CONTEXT <HANDLE> ;SWITCHED TO CONTEXT "HANDLE"
; .CONTEXT <HANDLE>= ;KEEP THE CURRRENT CONTEXT AND SPAWN ANOTHER
; .CONTEXT <HANDLE>/KILL ;DELETE THE SPECIFIED CONTEXT
; .CONTEXT <HANDLE>/LIST ;LIST THE STATUS FOR THE SPECIFIED CONTEXT
;
; WHERE <HANDLE> CAN BE EITHER A NAME, NUMBER, OR "."
CTXCMD::SE1ENT ;ENTER SECTION 1
MOVSI T1,(CT.UUO) ;FLAG TO CLEAR
ANDCAM T1,.PDCTX##(W) ;NOT DOING A UUO (FOR ERRXIT)
PUSHJ P,RDNAME ;GET CONTEXT NAME OR NUMBER
JRST COMERA## ;COMPLAIN
SKIPN P1,T1 ;SAVE CONTEXT BLOCK ADDRESS
JRST LISTER ;NONE GIVEN--LIST THEM ALL
MOVE P2,T2 ;GET NAME OR NUMBER
PUSHJ P,SKIPS1## ;EAT LEADING TABS AND SPACES
JRST CMD2 ;EOL--SWITCH TO SPECIFIED CONTEXT
CAIE T3,"=" ;NAME=NUMBER?
JRST CMD1 ;NO--MAYBE A KEYWORD
PUSHJ P,SKIPS## ;EAT THE EQUALS SIGN
JRST CMD3 ;USER WANTS A NEW CONTEXT
TLNN P2,-1 ;MUST BE A NAME, NOT A NUMBER
SKIPN P2 ;A BLANK NAME IS OK TOO
SKIPA ;NAME IS VALID
JRST CMDER2 ;NUMERIC NAMES DON'T MAKE IT
PUSHJ P,RDNAME ;TRY TO GET ANOTHER
JRST CMDER4 ;BAD COMMAND--NEED NAME OR NUMBER
JUMPL T1,CMDER3 ;NO SUCH CONTEXT
JUMPE T1,CMDER4 ;NEED A NAME OR NUMBER TO SET NEW NAME
MOVE P1,T1 ;SET CONTEXT BLOCK ADDRESS
MOVE T1,P2 ;GET NEW NAME
PUSHJ P,NAMECT ;ASSIGN THE NAME
TLZ M,NOPER+NOCRLF ;TERMINATE LIKE ANY NORMAL COMMAND
POPJ P, ;RETURN
CMD1: CAIE T3,"/" ;WE EXPECT A SWITCH AT THIS POINT
JRST COMERA## ;CONFUSED USER
PUSHJ P,CTEXT## ;GET A KEYWORD
JUMPE T2,COMERA## ;CONFUSED USER
MOVE T1,[-KEYSIZ,,KEYTAB] ;POINT TO TABLE
PUSHJ P,FNDNAM## ;AND SEARCH IT
JRST COMERA## ;AMBIGUOUS OR UNKNOWN KEYWORD
JRST @KEYDSP(T1) ;DISPATCH
CMD2: JUMPL P1,CMDER1 ;CONTEXT MUST BE KNOWN
MOVE T1,.PDCTC##(W) ;POINT TO CURRENT CONTEXT
MOVEM P1,.CTNEW(T1) ;SET NEW CONTEXT BLOCK ADDRESS
JSP T2,SAVCTX## ;RUN AT UUO LEVEL
SETZ P1, ;FLAG FOR ERRXIT
PUSHJ P,SWTCTX ;DO IT
JRST CMDETX ;GO TRANSLATE ERROR CODE TO TEXT AND HALT JOB
POPJ P, ;USER TYPED CONTUNUE, CONTEXT RESTORED
CMD3: SKIPE P2 ;IF BLANK NAME,
TLNE P2,-1 ;OR IF SIXBIT,
JRST CMD4 ;THEN USER WANTS A NEW CONTEXT
JUMPLE P1,CMDER1 ;CONTEXT MUST EXIST
SETZM .CTCBN(P1) ;CLEAR THE CONTEXT'S NAME
TLZ M,NOPER!NOCRLF ;TERMINATE LIKE A NORMAL COMMAND
POPJ P, ;RETURN
CMD4: MOVE P1,.PDCTC##(W) ;POINT TO CURRENT CONTEXT BLOCK
MOVEM P2,.CTNCN(P1) ;STORE NAME FOR NEW CONTEXT
JSP T2,SAVCTX## ;RUN AT UUO LEVEL
SETZ P1, ;FLAG FOR ERRXIT
MOVSI T1,(CT.TOP!CT.HLT) ;CREATE TOP LEVEL CONTEXT AND HALT JOB
PUSHJ P,CTXPSH ;DO IT
JRST CMDETX ;GO TRANSLATE ERROR CODE TO TEXT AND HALT JOB
POPJ P, ;USER TYPED CONTINUE, CONTEXT RESTORED
LISTER: JSP T2,SAVCTX## ;RUN AT UUO LEVEL
PUSHJ P,LSTQTA ;LIST QUOTAS, ETC.
MOVE P1,.PDSAC##(W) ;POINT TO START OF CONTEXT BLOCK CHAIN
SETZ P2, ;CLEAR A COUNTER
MOVEI T1,LSTHDR ;POINT TO HEADER
PUSHJ P,CONMES## ;TYPE IT
LISTE1: PUSHJ P,LSTBLK ;LIST CONTEXT BLOCK STATUS
SKIPE P1,.CTNXT(P1) ;POINT TO NEXT BLOCK
AOJA P2,LISTE1 ;COUNT THE CONTEXT AND LOOP
POPJ P, ;RETURN
LISTCT: JUMPLE P1,CMDER1 ;CONTEXT MUST BE KNOWN
TLZ M,NOPER!NOCRLF ;TERMINATE LIKE NORMAL COMMAND
MOVEI T1,LSTHDR ;POINT TO HEADER
PUSHJ P,CONMES## ;TYPE IT
PJRST LSTBLK ;LIST CONTEXT BLOCK STATUS AND RETURN
LSTHDR: ASCIZ |
Context Superior Prog Idle time
|
LSTQTA: PUSHJ P,PCRLF## ;START WITH A CRLF
MOVEI T1,[ASCIZ |Contexts used/quota = |]
LDB T2,PCTXCU ;GET CONTEXTS USED
SKIPN T2 ;HAVE A QUOTA?
MOVEI T2,777 ;NO--THIS IS THE ABSOLUTE LIMIT
LDB T3,PCTXCQ ;GET QUOTA
PUSHJ P,LSTQT1 ;DISPLAY
MOVEI T1,[ASCIZ |, pages used/quota = |]
LDB T2,PCTXPU ;GET PAGES USED
LDB T3,PCTXPQ ;GET QUOTA
LSTQT1: PUSH P,T3 ;SAVE QUOTA
PUSH P,T2 ;SAVE USED
PUSHJ P,CONMES## ;TYPE TEXT
POP P,T1 ;GET USED
PUSHJ P,PRTDIG## ;TYPE IT
MOVEI T3,"/" ;TYPE
PUSHJ P,PRCHR## ; SEPARATOR
POP P,T1 ;GET QUOTA BACK
SKIPE T1 ;IF NO QUOTA, SAY SO
PJRST PRTDIG## ;ELSE TYPE QUOTA AND RETURN
MOVEI T1,[ASCIZ |none|] ;LOTS
PJRST CONMES## ;TYPE TEXT AND RETURN
; CONTEXT COMMAND KEYWORD AND DISPATCH TABLES
KEYTAB: SIXBIT /KILL/
SIXBIT /LIST/
KEYSIZ==.-KEYTAB
KEYDSP: IFIW KILLCT
IFIW LISTCT
; COMMAND ERROR PROCESSING
CMDER1: JSP T1,CMDER0
ASCIZ |No such context|
CMDER2: JSP T1,CMDER0
ASCIZ |Context name cannot be numeric|
CMDER3: JSP T1,CMDER0
ASCIZ |Cannot find context to be named|
CMDER4: JSP T1,CMDER0
ASCIZ |No context to be named|
CMDETX: ANDI T1,CT.ERR ;NO JUNK
HRRZ T1,ERRTAB(T1) ;TRANSLATE ERROR CODE TO TEXT
TLO T1,(IFIW) ;EXTENDED ADDRESSING HACK
CMDER0: PUSH P,T1 ;SAVE STRING ADDRESS
PUSHJ P,PCRLF## ;TYPE A CRLF
POP P,T1 ;GET MESSAGE ADDRESS BACK
PJRST ERRMES## ;ISSUE ERROR MESSAGE AND HALT JOB
KILLCT: JUMPL P1,CMDER1 ;CONTEXT MUST BE KNOWN
MOVE T1,.PDCTC##(W) ;POINT TO CURRENT CONTEXT
MOVEM P1,.CTNEW(T1) ;SET NEW CONTEXT BLOCK ADDRESS
JSP T2,SAVCTX## ;RUN AT UUO LEVEL
SETZ P1, ;FLAG FOR ERRXIT
SETZ T1, ;NO FLAGS
PUSHJ P,DELCTX ;DELETE THE SPECIFIED CONTEXT
JRST CMDETX
POPJ P,
; READ A CONTEXT NAME OR NUMBER
; CALL: PUSHJ P,RDNAME
; <NON-SKIP>
; <SKIP>
;
; NON-SKIP: COMMAND ERROR, BAD ARGUMENTS GIVEN
; SKIP: T1 CONTAINS:
; -1 IF NO SUCH CONTEXT
; ZERO IF NO ARGUMENT GIVEN (LIST ALL)
; ADDR IF AN EXISTING CONTEXT FOUND
RDNAME: PUSHJ P,SKIPS1## ;EAT LEADING SPACES AND TABS
JRST RDNAM2 ;INDICATE NO ARGUMENT SEEN
MOVE T1,.PDCTC##(W) ;POINT TO THE CURRENT CONTEXT
CAIN T3,"." ;WANT THAT ONE?
JRST RDNAM1 ;GO RETURN THE CURRENT CONTEXT
CAIL T3,"0" ;RANGE CHECK
CAILE T3,"9" ; FOR A DIGIT
JRST RDNAM4 ;MUST BE A SIXBIT NAME
PUSHJ P,DECIN1## ;PARSE A NUMBER
POPJ P, ;NOT ENOUGH ARGUMENTS
JFCL ;END OF NUMBER
MOVE T1,.PDSAC##(W) ;POINT TO START OF CONTEXT BLOCK CHAIN
JRST RDNAM3 ;GO SEARCH FOR A MATCHING NUMBER
; HERE IF "." SEEN
RDNAM1: PUSHJ P,COMTYS## ;EAT THE DOT
SKIPA T1,.PDCTC##(W) ;POINT TO CURRENT CONTEXT
; HERE IF NO ARGUMENT
RDNAM2: SETZ T1, ;CLEAR CONTEXT BLOCK ADDRESS
JRST CPOPJ1## ;AND RETURN
; SEARCH FOR A MATCHING CONTEXT NUMBER
RDNAM3: HRRZ T3,.CTFLG(T1)
CAIN T2,(T3) ;MATCH?
JRST CPOPJ1## ;YES--RETURN
SKIPE T1,.CTNXT(T1) ;POINT TO NEXT BLOCK
JRST RDNAM3 ;LOOP
JRST RDNAM6 ;NO SUCH CONTEXT
; SEARCH FOR A MATCHING CONTEXT NAME
RDNAM4: PUSHJ P,CTEXT1## ;GET A NAME
MOVE T1,.PDSAC##(W) ;POINT TO START OF CONTEXT BLOCK CHAIN
RDNAM5: CAMN T2,.CTCBN(T1) ;MATCH?
JRST CPOPJ1## ;YES--RETURN
SKIPE T1,.CTNXT(T1) ;POINT TO NEXT BLOCK
JRST RDNAM5 ;LOOP
RDNAM6: MOVNI T1,1 ;NO SUCH CONTEXT
JRST CPOPJ1## ;RETURN
SUBTTL ENTRY POINTS -- PSHCMD/POPCMD - PUSH AND POP COMMANDS
PSHCMD::SE1ENT ;ENTER SECTION 1
JSP T2,SAVCTX## ;RUN AT UUO LEVEL
MOVSI T1,(CT.UUO) ;BIT TO CLEAR
ANDCAM T1,.PDCTX##(W) ;FLAG NOT IN UUO (FOR ERRXIT)
SETZ P1, ;FLAG FOR ERRXIT
MOVSI T1,(CT.HLT) ;SAVE CONTEXT AND HALT JOB
PUSHJ P,CTXPSH ;DO IT
JRST CMDETX ;GO TRANSLATE ERROR CODE TO TEXT AND HALT JOB
POPJ P, ;USER TYPED CONTINUE, CONTEXT RESTORED
POPCMD::SE1ENT ;ENTER SECTION 1
JSP T2,SAVCTX## ;RUN AT UUO LEVEL
MOVSI T1,(CT.UUO) ;BIT TO CLEAR
ANDCAM T1,.PDCTX##(W) ;FLAG NOT IN UUO (FOR ERRXIT)
PUSHJ P,CLRCOM ;CLEAR TTY INPUT BUFFER
PUSHJ P,CTXPOP ;RESTORE CONTEXT (SHOULD NEVER RETURN)
PJRST CMDETX ;GO TRANSLATE ERROR CODE TO TEXT AND HALT JOB
SUBTTL ENTRY POINTS -- CTXATO - AUTO-SAVE CONTEXT
CTXATO::MOVSI T1,(CT.UUO) ;BIT TO CLEAR
ANDCAM T1,.PDCTX##(W) ;FLAG NOT IN UUO (FOR ERRXIT)
POP P,(P) ;CPOPJ RETURNS ONLY IF NO CONTEXT SERVICE
SE1ENT ;ENTER SECTION 1
MOVE T1,.PDCTC##(W) ;POINT TO CURRENT BLOCK
HRLZM P1,.CTRUA(T1) ;SAVE RUN OFFSET
MOVEM P2,.CTPRG(T1) ;SAVE PROGRAM NAME
MOVEM P3,.CTDSP(T1) ;SAVE DISPATCH
JSP T2,SAVCTD## ;RUN AT UUO LEVEL
MOVE P1,.PDCTC##(W) ;POINT TO CURRENT JUST TO HAVE A VALID POINTER
MOVSI T1,(CT.ATO) ;THIS IS AN AUTO-SAVE
PUSHJ P,CTXPSH ;SAVE THE WORLD
SKIPA T1,.PDCTC##(W) ;FAILED--POINT TO CURRENT CONTEXT BLOCK
POPJ P, ;PROGRAM EXITED, CONTEXT RESTORED
MOVE T1,.CTRET(T1) ;GET WORD TO RETURN IN UUO AC
LDB T2,PCTXEC ;NOW GET THE ERROR CODE
EXCH T1,T2 ;SWAP
TLNN T2,(CT.RUN) ;RUN UUO ERROR?
PJRST CMDETX ;NO--CONTEXT ERROR
MOVEI T2,[ASCIZ |Run error |] ;POINT TO DEFAULT TEXT
PJRST SGETXT ;TYPE ERROR MESSAGE AND RETURN
SUBTTL ENTRY POINTS -- CTXSCD - SCHEDULER CALL TO SAVE CONTEXT
CTXSCD::SE1ENT ;ENTER SECTION 1
CAILE J,JOBMAX## ;HIGH SEGMENT?
JRST CTXSCH ;YES, CHECK IF IT'S OURS
JUMPE W,KCORE1## ;JUST GIVE BACK CORE IF NO PDB (CAN HAPPEN
; ON A WEIRD KJOB CASE)
SKIPL .PDCTX##(W) ;NO, EXPECTING THE SCHEDULAR TO CALL US?
JRST KCORE1## ;NO, JUST DELETE CORE IN CORE
PUSH P,P1 ;SAVE P1
PUSH P,P2 ;SAVE P2
MOVE P1,.PDCTC##(W) ;GET THE CURRENT CONTEXT BLOCK
MOVSI T1,(CT.SCD) ;GET BIT TO TEST
ANDCAM T1,.PDCTX##(W) ;CLEAR SO WE DON'T COME THROUGH HERE AGAIN
MOVSI T1,(CT.SWT) ;BIT TO TEST
TDNN T1,.PDCTX##(W) ;SWITCHING TO ANOTHER CONTEXT?
SKIPE P1,.CTLAS(P1) ;POINT TO PREVIOUS CONTEXT BLOCK
PUSHJ P,SAVECT ;SAVE CONTEXT
POP P,P2 ;RESTORE P2
POP P,P1 ;RESTORE P1
SETZM JBTIMO##(J) ;SWAPPED OUT SIZE IS 0P
SETZM JBTSWP##(J) ;CLEAR DISK ADDRESS AND COUNT OF SECTION MAPS
PJRST MAPBAK## ;CONVERT DISK ADDRESS BACK AND START JOB RUNNING
;HERE IF SWAPPING A HISEG TO DETERMINE IF IT'S OURS
CTXSCH: HRRZ T1,SWPOUT## ;GET ASSOCIATED LOWSEG (JOB)
PUSHJ P,FPDBT1## ;GET ITS PDB ADDRESS
JRST KCORE1## ;HOW CAN THIS FAIL? DELETE CORE IN CORE
SKIPL .PDCTX##(T1) ;IS JOB CHANGING CONTEXTS?
JRST KCORE1## ;NO, DELETE CORE IN CORE
POPJ P, ;ELSE RETURN WITHOUT DELETING CORE
SUBTTL SAVE CURRENT CONTEXT
CTXPSH::PUSHJ P,SAVE2## ;SAVE P1 AND P2
MOVE P2,T1 ;SAVE NEW CONTEXT FLAGS
PUSHJ P,LGLCHK ;PERFORM LEGALITY CHECKS
POPJ P, ;CAN'T SAVE CONTEXT--PROPAGATE ERROR BACK
MOVE P1,.PDCTC##(W) ;POINT TO CURRENT CONTEXT BLOCK
MOVE T1,SYSUPT## ;GET UPTIME NOW
MOVEM T1,.CTIDL(P1) ;MARK THIS CONTEXT IDLE AS OF NOW
PUSHJ P,CREBLK ;CREATE AND LINK A CONTEXT BLOCK
JRST ERRNCS ;NOT ENOUGH CORE TO SAVE CONTEXT
PUSHJ P,UPPAGE ;ACCOUNT FOR THE PAGES ABOUT TO BE USED
MOVE P1,.CTLAS(P1) ;POINT TO LAST BLOCK (THE ONE WE'RE SAVING)
HLLM P2,.PDCTX##(W) ;SET NEW FLAGS
MOVE T1,JBTNAM##(J) ;GET PROGRAM NAME
TLNN P2,(CT.ATO) ;AUTO-SAVE?
MOVEM T1,.CTPRG(P1) ;NO--SAVE FOR DISPLAY
PUSHJ P,CLRCOM ;CLEAR TTY INPUT BUFFER
PUSHJ P,GETRUA ;GET RUN UUO ARGS FROM USER ADDRESS SPACE
MOVSI T1,(CT.TOP) ;BIT TO TEST
TDNE T1,.PDCTX##(W) ;CREATING A NEW TOP LEVEL CONTEXT?
JRST CTXPS1 ;YES
MOVE T1,.PDCTC##(W) ;POINT TO CURRENT BLOCK
MOVEM P1,.CTSUP(T1) ;SET SUPERIOR CONTEXT BLOCK ADDRESS
MOVSI T1,(CT.INF) ;REMEMBER THE SUPERIOR
IORM T1,.CTFLG(P1) ; HAS INFERIOR CONTEXTS
CTXPS1: PUSH P,P1 ;SAVE SUPERIOR BLOCK ADDRESS
MOVE P1,.PDCTC##(W) ;GET NEW INFERIOR ADDRESS
PUSHJ P,UPCTXN ;COUNT UP THE CONTEXT LEVEL
PUSHJ P,FREECT ;FIND AND ASSIGN A FREE CONTEXT NUMBER
POP P,P1 ;RESTORE SUPERIOR
PUSHJ P,SWPCTX ;SWAP JOB AND SAVE CONTEXT
JRST CTXPS4 ;CONTEXT CONTINUED
SETZM JBTNAM##(J) ;ONLY FOR ^T
SETZM JBTPC##(J) ;DITTO
SETZM USRHCU## ;I/O CHANNELS NO LONGER OPENED
SETZM .USCTA ;NO EXTENDED CHANNEL TABLE
PUSHJ P,CORCTX ;GET MINIMAL JOB CORE FOR THIS CONTEXT
CTXPS2: PUSHJ P,WRTTCR ;WRITE TMPCOR IF REQUESTED
PUSHJ P,WCHCTX ;TYPE CONTEXT WATCH INFO
MOVSI T1,(JS.SAC) ;GET AUTO-RESTORE BIT
ANDCAM T1,JBTST2##(J) ;DON'T WANT TO DO THIS ON PUSH COMMANDS
MOVSI T1,(CT.HLT) ;GET HALT BIT
TDNN T1,.PDCTX##(W) ;SAVE CONTEXT AND HALT JOB?
JRST CTXPS3 ;NO--IT'S SAVE CONTEXT AND RUN
ANDCAM T1,.PDCTX##(W) ;CLEAR SO DON'T LEAVE AROUND
PUSHJ P,PRRSP3## ;PRINT [XXX], CRLF, DOT
PUSHJ P,TTYSTC## ;GET THE TTY TYPING
PJRST ESTOP## ;START TTY IN MONITOR MODE AND STOP JOB
CTXPS3: MOVE P1,.CTLAS(P1) ;POINT TO THE LAST (SAVED) CONTEXT BLOCK
PUSHJ P,PUTRUA ;PUT RUN UUO ARGS IN USER ADDRESS SPACE
MOVSI T1,(JS.SAC) ;GET THE AUTO-RESTORE BIT
IORM T1,JBTST2##(J) ;LITE SO PROGRAM EXIT WILL GO BACK TO CALLER
MOVSI T1,(UP.CTX) ;LITE SPECIAL CONTEXT BIT
IORM T1,.USBTS ; FOR SAVE/GET ERROR RECOVERY
MOVSI T1,(CT.PRN) ;BIT TO TEST
TDNN T1,.PDCTX##(W) ;WANT PHYSICAL ONLY?
TDZA P1,P1 ;NO
MOVSI P1,PHONLY ;LITE THE BIT
ANDCAM T1,.PDCTX##(W) ;CLEAR FOR FUTURE REFERENCE
IFN FTXMON,<JRST @[0,,.+1]> ;CAN'T USE SSEC0 HERE
PUSHJ P,URUN1A## ;DO A RUN UUO (NEVER RETURNS IF SUCESSFUL)
CTXRUE::
IFN FTXMON,<XJRST [MCSEC1+.+1]> ;BACK TO SECTION 1
MOVE P1,.PDCTC##(W) ;RELOAD CURRENT CONTEXT BLOCK ADDRESS
MOVE P1,.CTLAS(P1) ;POINT TO THE ONE WE CAME FROM
TLO T1,(CT.RUN) ;INDICATE RUN UUO ERROR
MOVEM T1,.CTRET(P1) ;STORE FOR RETURN
MOVSI T1,(CT.UUE) ;AN ERROR
IORM T1,.CTFLG(P1) ; HAS OCCURRED
MOVSI T1,(UP.CTX) ;CLEAR THE SPECIAL BIT USED
ANDCAM T1,.USBTS ; BY SAVE/GET ERROR RECOVERY
MOVE J,.CPJOB## ;IN CASE RUN UUO PUT KDB IN J
JRST MONRET## ;SET AUTO-RESTORE CLEAN UP
CTXPS4: MOVSI T1,(CT.DEL) ;GET DELETE FLAG
TDNE T1,.CTFLG(P1) ;KILLING OFF THIS CONTEXT?
PJRST CTXPOP ;YES
MOVE T1,.CTRET(P1) ;STUFF TO RETURN IN USER'S AC
PUSHJ P,PUTAC ;RETURN DATA
MOVSI T1,(CT.CON) ;CLEAR CONTINUE BIT TO
ANDCAM T1,.CTFLG(P1) ; PREVENT ETERNAL LOOPING
MOVSI T1,(CT.UUE) ;BIT TO TEST
TDNN T1,.CTFLG(P1) ;ERROR?
AOSA (P) ;SKIP
ANDCAM T1,.CTFLG(P1) ;CLEAR FOR NEXT TIME
POPJ P, ;RETURN
SUBTTL SWITCH CURRENT CONTEXT
SWTCTX: PUSHJ P,SAVE2## ;SAVE P1 AND P2
MOVSI P2,(CT.SWT) ;SWITCHING CONTEXTS
PUSHJ P,LGLCHK ;PERFORM LEGALITY CHECKS
POPJ P, ;CAN'T SAVE CONTEXT--PROPAGATE ERROR BACK
MOVE P1,.PDCTC##(W) ;POINT TO CURRENT CONTEXT BLOCK
MOVE T1,.CTNEW(P1) ;POINT TO THE NEW CONTEXT
CAME T1,P1 ;NEW SAME AS CURRENT?
JRST SWTCT1 ;NO
SETZM .CTNEW(P1) ;CLEAR FOR NEXT TIME
SETZM .CTLAS(P1) ;NO LAST CONTEXT
PUSHJ P,WCHCTX ;DISPLAY WATCH INFO
JRST CPOPJ1## ;AND RETURN
SWTCT1: MOVEI T2,CT.LGO ;BIT TO TEST
TDNE T2,.PDCTX##(W) ;LOGGING OUT?
JRST SWTCT2 ;YES
MOVSI T2,(CT.INF) ;BIT TO TEST
TDNE T2,.CTFLG(T1) ;NEW CONTEXT HAVE INFERIORS?
JRST ERRCSI ;CANNOT SWITCH TO AN INTERMEDIATE CONTEXT
SWTCT2: MOVE T1,SYSUPT## ;GET UPTIME NOW
MOVEM T1,.CTIDL(P1) ;MARK THIS CONTEXT IDLE AS OF NOW
SETZM .CTLAS(P1) ;NO LAST CONTEXT
HLLM P2,.PDCTX##(W) ;SET NEW FLAGS
MOVE T1,JBTNAM##(J) ;GET PROGRAM NAME
MOVEM T1,.CTPRG(P1) ;SAVE FOR DISPLAY
PUSHJ P,UPPAGE ;ACCOUNT FOR THE PAGES ABOUT TO BE USED
PUSHJ P,CLRCOM ;CLEAR TTY INPUT BUFFER
PUSHJ P,SWPCTX ;SWAP JOB AND SAVE CONTEXT
JRST CTXPS4 ;CONTEXT CONTINUED
SETZM JBTNAM##(J) ;ONLY FOR ^T
SETZM JBTPC##(J) ;DITTO
SETZM USRHCU## ;I/O CHANNELS NO LONGER OPENED
SETZM .USCTA ;NO EXTENDED CHANNEL TABLE
PUSHJ P,CORCTX ;GET MINIMAL JOB CORE FOR THIS CONTEXT
MOVSI T1,JLOG!JERR ;CLEAR JERR SO CAN'T ^C, JLOG SO
ANDCAM T1,JBTSTS##(J) ; ALL CORE GOES AWAY
MOVSI T1,JACCT ;SET JACCT SO
IORM T1,JBTSTS##(J) ; USER CAN'T CONTROL-C
SETZM .JDAT+.JBINT## ;ZAP TRAPPING
IFN FTXMON,<JRST @[0,,.+1]> ;CAN'T USE SSEC0 HERE
PUSHJ P,JOB1A## ;CLEAN UP
IFN FTXMON,<XJRST [MCSEC1+.+1]> ;BACK TO SECTION 1
MOVE P1,.PDCTC##(W) ;POINT TO CURRENT CONTEXT BLOCK
MOVE P1,.CTNEW(P1) ;NOW GET ADDRESS OF TARGET CONTEXT BLOCK
MOVEM P1,.PDCTC##(W) ;SET FOR POSTERITY
SETZM .CTNEW(P1) ;CLEAR FOR NEXT TIME
PUSHJ P,RESTCT ;RESTORE CONTEXT
PUSHJ P,DNPAGE ;ACCOUNT FOR THE PAGES ABOUT TO BE GIVEN BACK
PUSHJ P,WCHCTX ;TYPE CONTEXT WATCH INFO
JSP T1,XITCTX ;SET UP CONTEXT EXIT
PJRST RSCHED## ;CALL SCHEDULER
SUBTTL DELETE A CONTEXT
DELCTX: PUSHJ P,SAVE2## ;SAVE P1 AND P2
MOVE P2,T1 ;COPY FLAGS
TLO P2,(CT.SWT) ;DELETE CONTEXT INVOLVES SWITCHING
MOVE P1,.PDCTC##(W) ;POINT TO CURRENT CONTEXT BLOCK
MOVE T1,.CTNEW(P1) ;POINT TO THE NEW CONTEXT
CAMN T1,P1 ;NEW SAME AS CURRENT?
JRST ERRCDC ;CANNOT DELETE CURRENT CONTEXT
MOVSI T2,(CT.INF) ;BIT TO TEST
TDNE T2,.CTFLG(T1) ;NEW CONTEXT HAVE INFERIORS?
JRST ERRCDI ;CANNOT DELETE AN INTERMEDIATE CONTEXT
MOVE T3,.CTSUP(T1) ;GET TARGET'S SUPERIOR CONTEXT
ANDCAM T2,.CTFLG(T3) ;IT WON'T HAVE AN INFERIOR AFTER THE DELETE
MOVEM P1,.CTSUP(T1) ;MAKE CURRENT CONTEXT SUPERIOR TO TARGET
MOVSI T2,(CT.DEL) ;DELETING CONTEXTS
IORM T2,.CTFLG(T1) ;SET FOR TARGET CONTEXT
MOVE T1,SYSUPT## ;GET UPTIME NOW
MOVEM T1,.CTIDL(P1) ;MARK THIS CONTEXT IDLE AS OF NOW
SETZM .CTLAS(P1) ;NO LAST CONTEXT
HLLM P2,.PDCTX##(W) ;SET NEW FLAGS
MOVE T1,JBTNAM##(J) ;GET PROGRAM NAME
MOVEM T1,.CTPRG(P1) ;SAVE FOR DISPLAY
PUSHJ P,UPPAGE ;ACCOUNT FOR THE PAGES ABOUT TO BE USED
PUSHJ P,SWPCTX ;SWAP JOB AND SAVE CONTEXT
JRST CTXPS4 ;CONTEXT CONTINUED
SETZM USRHCU## ;I/O CHANNELS NO LONGER OPENED
SETZM .USCTA ;NO EXTENDED CHANNEL TABLE
PUSHJ P,CORCTX ;GET MINIMAL JOB CORE FOR THIS CONTEXT
MOVSI T1,JLOG ;CLEAR JLOG SO
ANDCAM T1,JBTSTS##(J) ; ALL CORE GOES AWAY
MOVSI T1,JACCT ;SET JACCT SO
IORM T1,JBTSTS##(J) ; USER CAN'T CONTROL-C
SETZM .JDAT+.JBINT## ;ZAP TRAPPING
IFN FTXMON,<JRST @[0,,.+1]> ;CAN'T USE SSEC0 HERE
PUSHJ P,JOB1## ;CLEAN UP
IFN FTXMON,<XJRST [MCSEC1+.+1]> ;BACK TO SECTION 1
MOVE P1,.PDCTC##(W) ;POINT TO CURRENT CONTEXT BLOCK
MOVE P1,.CTNEW(P1) ;NOW GET ADDRESS OF TARGET CONTEXT BLOCK
MOVEM P1,.PDCTC##(W) ;SET FOR POSTERITY
SETZM .CTNEW(P1) ;CLEAR FOR NEXT TIME
PUSHJ P,RESTCT ;RESTORE CONTEXT
PUSHJ P,DNPAGE ;ACCOUNT FOR THE PAGES ABOUT TO BE GIVEN BACK
JSP T1,XITCTX ;SET UP CONTEXT EXIT
PJRST RSCHED## ;CALL SCHEDULER
SUBTTL RESTORE PREVIOUS CONTEXT
CTXPOP::SE1ENT ;ENTER SECTION 1
PUSHJ P,FNDPDS## ;FIND THE PDB
MOVE P1,.PDCTC##(W) ;GET THE ADDRESS OF THE CURRENT CONTEXT BLOCK
SKIPN .CTSUP(P1) ;HAVE A SUPERIOR CONTEXT TO RESTORE?
JRST ERRNSC ;NO
MOVSI T1,RUN ;LIGHT OUR RUN BIT
IORM T1,JBTSTS##(J) ;SO THIS CALL RETURNS
S0PSHJ RESET## ;STOP THE WORLD
PUSHJ P,IPCPOP## ;TELL IPCSER WE'RE LEAVING
IFN FTSCA,<PUSHJ P,SCSPOP##> ;TELL SCSUUO WE'RE LEAVING
IFN FTDECNET,<
IFE FTXMON,<DNCALL (SCUPOP##)> ;TELL SCMUUO WE'RE LEAVING
IFN FTXMON,<SNCALL (SCUPOP##,MS.HGH)> ;TELL SCMUUO WE'RE LEAVING
>; END IFN FTDECNET
PUSHJ P,MDIECT ;COPY DATA FROM INFERIOR TO EXEC
MOVE P1,.CTSUP(P1) ;POINT TO SUPERIOR CONTEXT
MOVSI T1,JLOG ;CLEAR JLOG SO
ANDCAM T1,JBTSTS##(J) ; ALL CORE GOES AWAY
MOVSI T1,RUN+JACCT ;RUNNABLE BIT + JACCT TO PREVENT ^C
IORM T1,JBTSTS##(J) ;MAKE SURE IT'S ON
SETZM .JDAT+.JBINT## ;ZAP TRAPPING
IFN FTXMON,<JRST @[0,,.+1]> ;CAN'T USE SSEC0 HERE
PUSHJ P,JOB1## ;CLEAN UP
IFN FTXMON,<XJRST [MCSEC1+.+1]> ;BACK TO SECTION 1
LDB T1,PCTXNO ;GET SUPERIOR'S CTX NUMBER
LSH T1,CTXLSH## ;MOVE IT OVER
IOR T1,J ;MAKE FULL JCH
XMOVEI T2,.CTBPR+.CXENQ(P1) ;POINT TO QUESER DATA HEADER
PUSHJ P,ENQPOP## ;CALL QUESER FOR ETERNAL LOCKS
SKIPE U ;UNLESS DETACHED,
PUSHJ P,WCHEND## ;PRINT WATCH STATISTICS FOR NEATNESS'S SAKE
PUSHJ P,RESTCT ;RESTORE CONTEXT
PUSHJ P,DNCTXN ;COUNT DOWN THE CONTEXT LEVEL
PUSHJ P,DNPAGE ;ACCOUNT FOR THE PAGES ABOUT TO BE GIVEN BACK
PUSHJ P,DELBLK ;DELETE AND UNLINK CONTEXT BLOCK
PUSHJ P,WCHCTX ;TYPE WATCH INFO FOR THE NEW CONTEXT
SETZM .CTIDL(P1) ;NO LONGER IDLE
MOVSI T1,(CT.INF) ;THIS NEW CONTEXT NO
ANDCAM T1,.CTFLG(P1) ; LONGER HAS ANY INFERIORS
JSP T1,XITCTX ;SET UP CONTEXT EXIT
PJRST RSCHED## ;CALL SCHEDULER
SUBTTL SWAP JOB AND SAVE CONTEXT
; THIS ROUTINE WILL MARK THE CURRENT JOB TO HAVE ITS CURRENT
; CONTEXT SAVED AND SWAP THE JOB OUT.
;
; CALL: PUSHJ P,SWPCTX
; <NON-SKIP> ;CONTINUE AFTER CONTEXT RESTORE
; <SKIP> ;FINISH UP CONTEXT SAVE
SWPCTX: AOS TOTSAV ;COUNT THE CONTEXT ABOUT TO BE SAVED
MOVSI T1,(CT.UUO) ;BIT TO DIDDLE
ANDCAM T1,.CTFLG(P1) ;ASSUME FOR COMMAND
TDNE T1,.PDCTX##(W) ;THIS FOR A UUO?
IORM T1,.CTFLG(P1) ;YES, SET IN BLOCK
IFN FTFDAE,<
MOVSI T1,(JS.CFX) ;CALL FILDAE FOR EXIT MESSAGE
TDNE T1,JBTST2##(J) ;DO WE NEED TO DO SO?
PUSHJ P,SNDFPM## ;YES, SEND FILDAE A PUSH MESSAGE
>
SWPCT1: LDB T1,IMGIN## ;GET OUR IN-CORE SIZE
PUSHJ P,XPANDP## ;SET WHEELS IN MOTION TO SWAP US OUT
MOVSI T1,(CT.SCD) ;WAITING FOR SWAPOUT TO SAVE CONTEXT
IORM T1,.PDCTX##(W) ;REMEMBER WHEN THE SCHEDULER CALLS US
PUSHJ P,WSCHED## ;REQUEUE
CONTPC:
IFN FTXMON,<XJRST [MCSEC1+.+1]> ;SAVCTX (MAPBAK) PUTS US IN S0
MOVE P1,.PDCTC##(W) ;GET CURRENT CONTEXT BLOCK ADDRESS
MOVSI T1,(CT.CON) ;DID THE USER TYPE CONTINUE
TDNN T1,.CTFLG(P1) ; CAUSING A CONTEXT RESTORE?
JRST CPOPJ1## ;NO--ALL DONE
ANDCAM T1,.CTFLG(P1) ;CLEAR CONTINUE FLAG
MOVSI T1,(CT.UUO) ;BIT TO REMEMBER
ANDCAM T1,.PDCTX##(W) ;ASSUME BY COMMAND
TDNE T1,.CTFLG(P1) ;ON IN BLOCK?
IORM T1,.PDCTX##(W) ;YES, RESTORE
PUSHJ P,MDEUCT ;COPY DATA FROM EXEC TO USER
IFN FTFDAE,<
MOVSI T1,(JS.CFX) ;CALL FILDAE FOR EXIT MESSAGE
TDNE T1,JBTST2##(J) ;DO WE NEED TO DO SO?
PUSHJ P,SNDFRM## ;YES, SEND FILDAE A POP MESSAGE
>
POPJ P, ;AND RETURN
SUBTTL CORCTX - GET MINIMAL JOB DATA AREA
CORCTX: SKIPN JBTADR##(J) ;HAVE CORE?
JRST CORCT1 ;LEAVE COUNTERS ALONE
PUSHJ P,CORESZ ;COMPUTE CORE SIZE
MOVNS T1 ;NEED TO SUBTRACT
ADDM T1,VIRTAL## ;DO SO (SUBM GOES WRONG WAY)
CORCT1: MOVSI T1,(UP.CTX) ;LIGHT SPECIAL CONTEXT BIT
IORM T1,.USBTS ;SO DLTPAG WON'T DELETE OUR VIRTUAL PAGES
S0PSHJ GETMI1## ;GET MINIMAL JOB AREA IN CORE OR DISK
MOVSI T1,(UP.CTX) ;AND NOW CLEAR THE SPECIAL BIT
ANDCAM T1,.USBTS ;SO LATER PAGE DELETIONS WORK NORMALLY
PUSHJ P,CORESZ ;COMPUTE CORE SIZE NOW
MOVNS T1 ;NEED TO SUBTRACT
ADDM T1,VIRTAL## ;DO SO (SUBM GOES WRONG WAY)
MOVSI T1,SWP!SHF ;AND NOT
ANDCAM T1,JBTSTS##(J) ; SWAPPING NOW
SETZM .JDAT ;CLEAR FIRST WORD OF JOBDAT
IFE FTXMON,<
MOVE T1,[.JDAT,,.JDAT+1] ;SET UP BLT POINTER
BLT T1,.JDAT+PG.BDY ;CLEAR USER PAGE ZERO
> ;END IFE FTXMON
IFN FTXMON,<
MOVEI T1,PG.BDY ;CLEAR
MOVEI T2,.JDAT ; USER
MOVEI T3,.JDAT+1 ; PAGE
EXTEND T1,[XBLT] ; ZERO
> ;END IFN FTXMON
SETZM USRDDT## ;CLEAR SAVED COPY OF DDT
POPJ P, ;RETURN
SUBTTL EXIT FROM A CONTEXT
; CALL: JSP T1,XITCTX
XITCTX: MOVSI T2,(CT.CON) ;LITE CONTINUE CONTEXT SO IT
IORM T2,.CTFLG(P1) ; STARTS RUNNING AT LAST STOPPED PC
XSFM T2 ;GET PC FLAGS (PC STILL IN T3)
XMOVEI T3,CONTPC ;CONTINUE PC
DMOVEM T2,.CPPC## ;SET RETURN PC DOUBLE WORD
MOVE P,.CPNPD## ;SET UP SCHEDULER PDL
JRST (T1) ;RETURN
SUBTTL SAVE/RESTORE -- FREECT - FIND AND ASSIGN A FREE CONTEXT NUMBER
FREECT: PUSH P,P1 ;SAVE P1
MOVEI T1,1 ;START WITH CONTEXT NUMBER 1
FREEC1: MOVE P1,.PDSAC##(W) ;POINT TO THE START OF THE CHAIN
FREEC2: LDB T2,PCTXNO ;GET A CONTEXT NUMBER
CAIN T1,(T2) ;THIS NUMBER IN USE?
AOJA T1,FREEC1 ;YES--TRY ANOTHER
SKIPE P1,.CTNXT(P1) ;POINT TO NEXT BLOCK
JRST FREEC2 ;KEEP SEARCHING
FREEC3: POP P,P1 ;RESTORE CONTEXT BLOCK POINTER
DPB T1,PCTXNO ;SET THIS NUMBER IN THE CURRENT BLOCK
POPJ P, ;AND RETURN
SUBTTL SAVE/RESTORE -- FINDCT - FIND A CONTEXT GIVEN A NAME OR NUMBER
; CALL: MOVE T1, SIXBIT NAME OR NUMBER
; PUSHJ P,FINDCT
; <ERROR> ;NO SUCH CONTEXT
; <SKIP> ;FOUND, P1 CONTAINS BLOCK ADDRESS
FINDCT: TLNE T1,-1 ;SIXBIT NAME?
JRST FINDC1 ;YES
CAIE T1,0 ;CAN'T BE ZERO
CAILE T1,777 ;A REASONABLE NUMBER?
POPJ P, ;NOPE
FINDC1: MOVE P1,.PDSAC##(W) ;POINT TO START OF CONTEXT BLOCK CHAIN
FINDC2: TLNE T1,-1 ;NAME OR NUMBER?
SKIPA T2,.CTCBN(P1) ;NAME
LDB T2,PCTXNO ;NUMBER
CAMN T1,T2 ;MATCH?
JRST CPOPJ1## ;YES
SKIPE P1,.CTNXT(P1) ;GET NEXT BLOCK ADDRESS
JRST FINDC2 ;KEEP SEARCHING
MOVE P1,.PDCTC##(W) ;LEAVE P1 POINTING TO THE CURRENT
POPJ P, ;RETURN EMPTY HANDED
SUBTTL SAVE/RESTORE -- NAMECT - ASSIGN A NAME TO A CONTEXT
; CALL: MOVE P1, CONTEXT BLOCK
; MOVE T1, SIXBIT NAME
; PUSHJ P,NAMECT
NAMECT: JUMPE T1,NAMEC3 ;NULL NAME IS OK
CAMN T1,.CTCBN(P1) ;NAME ALREADY MATCH THE CURRENT ONE?
POPJ P, ;YES--NOTHING TO DO
MOVE T2,.PDSAC##(W) ;POINT TO START OF CONTEXT BLOCK CHAIN
NAMEC1: CAMN T1,.CTCBN(T2) ;MATCH?
JRST NAMEC2 ;YES
SKIPE T2,.CTNXT(T2) ;GET NEXT BLOCK ADDRESS
JRST NAMEC1 ;KEEP SEARCHING
MOVE T2,P1 ;NAME NOT A DUPLICATE
NAMEC2: SETZM .CTCBN(T2) ;DEASSIGN NAME FROM OLD CONTEXT BLOCK
NAMEC3: MOVEM T1,.CTCBN(P1) ;AND ASSIGN THIS NAME TO THE NEW BLOCK
POPJ P, ;RETURN
SUBTTL SAVE/RESTORE -- JBCHCT - FIND A CONTEXT GIVEN A JOB/CTX HANDLE
; FIND A CONTEXT GIVEN A JOB/CONTEXT HANDLE
; CALL: MOVE T1,JOB/CONTEXT HANDLE
; PUSHJ P,JBCHCT
; <NON-SKIP> ;NO SUCH JOB OR CONTEXT NUMBER
; <SKIP 1> ;FOUND THE CURRENT CONTEXT BLOCK
; <SKIP 2> ;FOUND A RANDOM CONTEXT BLOCK
;
; ON A SUCESSFUL RETURN, T1 WILL CONTAIN AN UPDATES JOB/CONTEXT
; HANDLE AND P1 WILL CONTAIN A CONTEXT BLOCK ADDRESS.
;
; NOTE: IF THE SIGN OF OF T1 IS ON, THEN THIS ROUTINE WILL RETURN
; THE NEXT CONTEXT FOR THE SPECIFIED JOB. IN ADDITION, IF
; REQUESTED CONTEXT NUMBER IS ZERO, THEN THE FIRST CONTEXT
; BLOCK ADDRESS WILL BE RETURNED. IN EITHER CASE, ON RETURN,
; T1 WILL CONTAIN THE NEW JOB/CONTEXT HANDLE NUMBER.
JBCHCT: PUSH P,J ;SAVE J
PUSH P,W ;SAVE W
PUSH P,T2 ;SAVE T2
PUSH P,T3 ;SAVE T3
MOVE J,T1 ;COPY ARGUMENT
ANDI J,JOBMSK## ;WANT ONLY JOB NUMBER
PUSHJ P,FNDPDB## ;FIND THE PDB
JRST JBCHC6 ;BAD JOB NUMBER
LDB T2,[POINT 9,T1,26] ;COPY TARGET CONTEXT NUMBER
TRZ T1,CTXMSK## ;CLEAR OLD CTXNUM
SKIPE P1,.PDSAC##(W) ;POINT TO START OF CONTEXT CHAIN
JRST JBCHC1 ;ONWARD
TRO T1,1000 ;CAN ONLY BE ONE
TLZN T1,400000 ;STEP?
SOJLE T2,JBCHC5 ;NO--MUST REQUEST FIRST OR ONLY CONTEXT
JUMPE T2,JBCHC5 ;STEP ON, IF JUST JOB # WANTS ONLY CONTEXT
JRST JBCHC6 ;REQUESTING CONTEXT OTHER THAN ONE
JBCHC1: JUMPN T2,JBCHC2 ;JUMP IF A SPECIFIC ONE WANTED
JUMPL T1,JBCHC4 ;IF ZERO REQUESTED AND NEXT, THEN GIVE FIRST
MOVE P1,.PDCTC##(W) ;ELSE POINT TO CURRENT
JRST JBCHC4 ;AND FINISH UP
JBCHC2: LDB T3,PCTXNO ;GET THIS BLOCK'S NUMBER
CAMN T2,T3 ;MATCH TARGET?
JRST JBCHC3 ;YES
SKIPE P1,.CTNXT(P1) ;POINT TO NEXT
JRST JBCHC2 ;KEEP SEARCHING
JRST JBCHC6 ;GIVE UP
JBCHC3: JUMPGE T1,JBCHC4 ;JUMP IF WANT THE CURRENT CONTEXT ONLY
SKIPN P1,.CTNXT(P1) ;YES--POINT TO IT
JRST JBCHC6 ;THERE ISN'T ANOTHER ONE
JBCHC4: LDB T2,PCTXNO ;GET THIS BLOCK'S NUMBER
MOVE T3,P1 ;SAVE BLOCK ADDRESS
MOVE P1,.PDCTC##(W) ;GET CURRENT
LDB P1,PCTXNO ;AND CURRENT CONTEXT NUMBER
EXCH T3,P1 ;SWAP
CAIE T2,(T3) ;SEARCH FOUND THE CURRENT CONTEXT?
AOS -4(P) ;NO--DOUBLE SKIP
LSH T2,CTXLSH## ;POSITION
IOR T1,T2 ;FORM JCH
ANDI T1,JCHMSK## ;STRIP OFF JUNK
JBCHC5: AOS -4(P) ;SKIP
JBCHC6: POP P,T3 ;RESTORE T3
POP P,T2 ;RESTORE T2
POP P,W ;RESTORE W
POP P,J ;RESTORE J
POPJ P, ;AND RETURN
SUBTTL SAVE/RESTORE -- SAVECT - SAVE CONTEXT
SAVECT: PUSHJ P,TTYFND## ;GET TTY DDB (F,S,U)
ADDI P1,.CTBPR-1 ;ACCOUNT FOR THE HEADER
TLNN P1,-1 ;NZS CONTEXT BLOCK?
HRLI P1,-.CXNUM-1 ;NO--AVOID PDL OVERFLOWS
MOVSI P2,-CSRLEN ;AOBJN POINTER
SAVEC1: SKIPG T1,CSRTAB(P2) ;GET AN ENTRY
JRST SAVEC2 ;MUST BE A SUBROUTINE TO EXECUTE
TLO T1,(IFIW) ;MAKE IT A LOCAL REFERENCE
TLZN T1,(1B1) ;WANT TO PUSH-AND-ZERO, OR JUST PUSH?
JRST [PUSH P1,@T1 ;SAVE IT
JRST SAVEC3] ;JOIN UP WITH COMMON CODE
PUSH P1,@T1 ;SAVE SOMETHING
SETZM @T1 ;YES, DO IT
JRST SAVEC3 ;REJOIN COMMON CODE
SAVEC2: PUSHJ P,0(T1) ;DISPATCH
JFCL ;IGNORE ERRORS FOR NOW
SAVEC3: AOBJN P2,SAVEC1 ;LOOP THROUGH TABLE
POPJ P, ;RETURN
SUBTTL SAVE/RESTORE -- RESTCT - SAVE CONTEXT
RESTCT: PUSHJ P,TTYFND## ;GET TTY DDB (F,S,U)
ADDI P1,.CTEPR ;POINT TO END OF SAVED DATA
TLNN P1,-1 ;NZS CONTEXT BLOCK?
TLO P1,-1 ;NO--AVOID PDL UNDERFLOW
MOVEI P2,CSRLEN-1 ;INIT TABLE INDEX
RESTC1: SKIPG T1,CSRTAB(P2) ;GET AN ENTRY
JRST RESTC2 ;MUST BE AN INSTRUCTION TO EXECUTE
TLO T1,(IFIW) ;MAKE IT A LOCAL REFERENCE
TLZ T1,(1B1) ;ILLEGAL FOR IW TO HAVE BOTH 1B0 & 1B1
POP P1,@T1 ;RESTORE SOMETHING
JRST RESTC3 ;REJOIN COMMON CODE
RESTC2: PUSHJ P,1(T1) ;DISPATCH
JFCL ;IGNORE ERRORS FOR NOW
RESTC3: SOJGE P2,RESTC1 ;LOOP THROUGH TABLE
MOVE P1,.PDCTC##(W) ;RESET CURRENT CONTEXT BLOCK ADDRESS
POPJ P, ;RETURN
SUBTTL SAVE/RESTORE -- LIGHT REDOMP FOR ALL HIGH SEGS AFTER RESTORING
CSRSGN: JRST SAVSGN
RSTSGN: POP P1,T2 ;GET THE ENTRY
MOVEM T2,JBTSGN##(J) ;RESTORE LEFT HALF AND CLEAR RIGHT
MOVSI T1,REDOMP ;GET THE BIT
TLZA T2,-1 ;CLEAR JUNK IN LEFT HALF
RSTSG1: HRRZ T2,.HBLNK(T2) ;POINT TO NEXT BLOCK
JUMPE T2,RSTSG2 ;NO MORE
IORM T1,.HBSGN(T2) ;SET REDOMP IN CASE HIGH SEG MAP MOVED
JRST RSTSG1 ;LOOP FOR NEXT SEGMENT
RSTSG2: HRRZ T2,JBTSGN##(J) ;IS THERE A JBTSGN ENTRY?
JUMPE T2,CPOPJ## ;NO IF RIGHT HALF IS ZERO
IORM T1,JBTSGN##(J) ;MAKE SURE REDOMP IS ON GLOBALLY
POPJ P,
SAVSGN: PUSH P1,JBTSGN##(J) ;SAVE JBTSGN
POPJ P,
SUBTTL SAVE/RESTORE -- FROM SYS BIT
CSRSYS: JRST SAVSYS ;SAVE
RSTSYS: MOVSI T1,(JB.LSY) ;GET THE "FROM SYS" BIT
ANDCAM T1,JBTLIM##(J) ;CLEAR IT INITIALLLY
POP P1,T1 ;GET THE SAVED BIT
IORM T1,JBTLIM##(J) ;SET AS APPROPRIATE
POPJ P, ;RETURN
SAVSYS: MOVSI T1,(JB.LSY) ;GET THE "FROM SYS" BIT
AND T1,JBTLIM##(J) ;KEEP ONLY THAT BIT
PUSH P1,T1 ;SAVE IT
POPJ P, ;RETURN
SUBTTL SAVE/RESTORE -- MONITOR MODE BIT
CSRMON: JRST SAVMON ;SAVE
RSTMON: SE1ENT
POP P1,T1 ;GET THE BIT
JUMPE U,CPOPJ## ;CAN'T RESTORE IF NOT ATTACHED
JUMPN T1,TTYSTC## ;FORCE MONITOR MODE IF WAS ON BEFORE
PJRST TTYUSW## ;AND USER MODE IF THAT WAS PREVIOUS
SAVMON: SE1ENT
MOVSI T1,LDLCOM## ;GET THE MONITOR MODE BIT
AND T1,LDBDCH##(U) ;KEEP ONLY THAT BIT
PUSH P1,T1 ;SAVE IT
POPJ P, ;RETURN
SUBTTL SAVE/RESTORE -- BREAK MASK ADDRESS
CSRBKM: JRST SAVBKM ;SAVE
RSTBKM: SE1ENT
JUMPE U,[ADJSP P1,-<LDBCSL+3> ;CLEAR STACK OF NOW USELESS VALUES
POPJ P,] ;AND RETURN
XMOVEI T2,-<LDBCSL+2>(P1) ;TABLE ADDRESS
IFN FTXMON,<
MOVEI T1,LDBCSL+2 ;LENGTH OF BLOCK
XMOVEI T3,LDBCSB##(U) ;WHERE TO RESTORE THE TABLE
EXTEND T1,[XBLT] ;MOVE THE WORDS
>
IFE FTXMON,<
MOVSI T1,(T2) ;SOURCE ADDRESS
HRRI T1,LDBCSB##(U) ;DESTINATION ADDRESS
BLT T1,LDBCSB##+LDBCSL+2-1(U) ;RESTORE THE TABLE
>
ADJSP P1,-<LDBCSL+2> ;TRIM THE BLOCK POINTER
POP P1,LDBBKB##(U) ;RESTORE BREAK MASK BLOCK
POPJ P, ;RETURN
SAVBKM: SE1ENT
PUSH P1,LDBBKB##(U) ;SAVE BREAK MASK BLOCK
XMOVEI T1,(P1) ;POINT TO START OF TABLE
ADJSP P1,LDBCSL+2 ;AND SKIP POINTER PAST IT
IFN FTXMON,<
MOVE T3,T1 ;DESTINATION
XMOVEI T2,LDBCSB##(U) ;SOURCE
MOVEI T1,LDBCSL+2 ;LENGTH
EXTEND T1,[XBLT] ;SAVE THE TABLE
>
IFE FTXMON,<
MOVE T2,T1 ;DESTINATION
HRLI T2,LDBCSB##(U) ;SOURCE
BLT T2,LDBCSL+2-1(T1) ;SAVE IT AWAY
>
SETZM LDBBKB##(U) ;CLEAR SO NO CONFUSION WITH NEW CONTEXT
POPJ P, ;RETURN
SUBTTL SAVE/RESTORE -- IPCF DATA
CSRIPC: JRST SAVIPC ;SAVE
RSTIPC: POP P1,.PDEPA##(W) ;(11) RESTORE EXEC PSEUDO-PROCESS PACKET ADDR
POP P1,.PDQSN##(W) ;(10) RESTORE SEQUENCE NUMBERS
POP P1,.PDIPN##(W) ;(07) RESTORE POINTER TO LAST PACKET IN QUEUE
POP P1,.PDIPI##(W) ;(06) RESTORE PID OF JOB'S [SYSTEM]INFO
POP P1,.PDPID##(W) ;(05) RESTORE PID FOR SPECIFIC RECEIVE WORD
POP P1,.PDIPL##(W) ;(04) RESTORE IPCF QUEUE INTERLOCK WORD
POP P1,.PDIPQ##(W) ;(03) RESTORE QUOTAS
POP P1,T1 ;(02) RESTORE INCREMENTAL SND AND RCV COUNT
ADDM T1,.PDIPA##(W) ; ACCUMULATE
POP P1,.PDIPC##(W) ;(01) RESTORE COUNTERS
POPJ P, ;RETURN
SAVIPC: SYSPIF ;AVOID IPCF QUEUEING RACE
MOVSI T1,-1 ;LINK HALFWORD
TDNN T1,.PDIPC##(W) ;IF EMPTY QUEUE,
SETZM .PDIPN##(W) ;MAKE SURE WE KNOW IT'S EMPTY
SYSPIN ;END OF RACE
PUSH P1,.PDIPC##(W) ;(01) SAVE COUNTERS
SETZM .PDIPC##(W) ; ZERO
PUSH P1,[EXP 0] ;(02) INIT INCREMENTAL STATISTICS (.PDIPA)
PUSH P1,.PDIPQ##(W) ;(03) SAVE QUOTAS
HRLOI T1,IP.CTX## ; SPECIAL FLAGS PRESERVED OVER CTX CALLS
ANDM T1,.PDIPQ##(W) ; CLEAR ALL OTHER BITS
PUSH P1,.PDIPL##(W) ;(04) SAVE IPCF QUEUE INTERLOCK WORD
PUSH P1,.PDPID##(W) ;(05) SAVE PID FOR SPECIFIC RECEIVE
SETZM .PDPID##(W) ; ZERO
PUSH P1,.PDIPI##(W) ;(06) SAVE PID OF JOB'S [SYSTEM]INFO
SETZM .PDIPI##(W) ; ZERO
PUSH P1,.PDIPN##(W) ;(07) SAVE POINTER TO LAST PACKET IN QUEUE
SETZM .PDIPN##(W) ; ZERO
PUSH P1,.PDQSN##(W) ;(10) SAVE SEQUENCE NUMBERS
SETZM .PDQSN##(W) ; ZERO
PUSH P1,.PDEPA##(W) ;(11) SAVE EXEC PSEUDO-PROCESS PACKET ADDRESS
SETZM .PDEPA##(W) ; ZERO
POPJ P, ;RETURN
SUBTTL SAVE/RESTORE -- .PDEQJ
CSRENQ: JRST SAVENQ ;SAVE
RSTENQ: POP P1,.PDEQJ##(W) ;RESTORE QUEUE CHAIN ADDRESS
POPJ P, ;RETURN
SAVENQ: PUSH P1,.PDEQJ##(W) ;SAVE QUEUE CHAIN ADDRESS
PUSHJ P,ENQJBI## ;RE-INIT QUEUE LIST HEADER
POPJ P, ;RETURN
SUBTTL SAVE/RESTORE -- JOB STATUS WORD
CSRSTS: JRST SAVSTS ;SAVE
RSTSTS:
IFN FTMP,<PUSHJ P,SBSCD##> ;INTERLOCK THE SCHEDULER
MOVSI T1,JRQ ;REQUE'D BIT
TDNE T1,JBTSTS##(J) ;IS IT ON?
IORM T1,(P1) ;YES, PROPAGATE (ELSE RSJ'S RESULT)
POP P1,JBTSTS##(J) ;RESTORE STATUS WORD
POPJ P, ;BACK FOR MORE OF RESTCT
SAVSTS: PUSH P1,JBTSTS##(J) ;SAVE IS SIMPLE
POPJ P, ;VOILA!
SUBTTL SAVE/RESTORE -- TTY DDB
CSRTTY: JRST SAVTTY ;SAVE
RSTTTY: JUMPN F,RSTTT1 ;HAVE A DDB?
ADJSP P1,-13 ;PHASE STACK
POPJ P, ;AND RETURN
RSTTT1: POP P1,T1 ;(13) GET ASSIGNED BITS AND JCH
HLRM T1,DEVMOD(F) ; RESTORE ASSPRG+ASSCON
DPB T1,PJCHN## ; RESTORE OWNING JCH
POP P1,DEVISN(F) ;(12) RESTORE SECTION NUMBER FOR I/O
POP P1,DEVXTR(F) ;(11) RESTORE MSGSER CONTROL WORD
POP P1,DEVESE(F) ;(10) RESTORE PSI LINKS
POP P1,DEVPSI(F) ;(07) RESTORE PSI CONDITIONS
POP P1,DEVOAD(F) ;(06) RESTORE OUTPUT BUFFER ADDRESS
POP P1,DEVIAD(F) ;(05) RESTORE INPUT BUFFER ADDRESS
POP P1,DEVBUF(F) ;(04) RESTORE BUFFER HEADER ADDRESSES
POP P1,DEVLOG(F) ;(03) RESTORE LOGICAL NAME
POP P1,DEVIOS(F) ;(02) RESTORE I/O STATUS
POP P1,DEVCHR(F) ;(01) RESTORE DEVICE CHARACTERISTICS
POPJ P, ;RETURN
SAVTTY: JUMPN F,SAVTT1 ;HAVE A DDB?
ADJSP P1,13 ;PHASE STACK
POPJ P, ;AND RETURN
SAVTT1: PUSH P1,DEVCHR(F) ;(01) SAVE DEVICE CHARACTERISTICS
PUSH P1,DEVIOS(F) ;(02) SAVE I/O STATUS
PUSH P1,DEVLOG(F) ;(03) SAVE LOGICAL NAME
PUSH P1,DEVBUF(F) ;(04) SAVE BUFFER HEADER ADDRESSES
PUSH P1,DEVIAD(F) ;(05) SAVE INPUT BUFFER ADDRESS
PUSH P1,DEVOAD(F) ;(06) SAVE OUTPUT BUFFER ADDRESS
PUSH P1,DEVPSI(F) ;(07) SAVE PSI CONDITIONS
SETZM DEVPSI(F) ; ZERO
PUSH P1,DEVESE(F) ;(10) SAVE PSI LINKS
SETZM DEVESE(F) ; ZERO
PUSH P1,DEVXTR(F) ;(11) SAVE MSGSER CONTROL WORD
PUSH P1,DEVISN(F) ;(12) SAVE SECTION NUMBER FOR I/O
LDB T1,PJCHN## ;(13) GET OWNING JCH
HRL T1,DEVMOD(F) ; GET ASSPRG+ASSCON
PUSH P1,T1 ; SAVE IT
ANDI T1,JOBMSK## ; KEEP ONLY JOB NUMBER
DPB T1,PJCHN## ; AS THE OWNER
MOVEI T1,ASSPRG ; INIT'ED BIT
ANDCAM T1,DEVMOD(F) ; NO MORE
POPJ P, ;RETURN
SUBTTL SAVE/RESTORE -- JBTST2
IFN FTFDAE,<
CSRST2: JRST SAVST2 ;SAVE ENTRY
RSTST2: POP P1,JBTST2##(J) ;RESTORE JBTST2
POPJ P, ;RETURN
SAVST2: PUSH P1,JBTST2##(J) ;SAVE JBTST2
MOVSI T1,(JS.CFX) ;FILDAE EXIT MESSAGE BIT
ANDCAM T1,JBTST2##(J) ;WE ALREADY DID THIS OUR WAY (.FDPSH)
POPJ P, ;RETURN
> ;END OF IFN FTFDAE
SUBTTL SAVE/RESTORE -- JBTAD2
CSRAD2: JRST SAVAD2 ;SAVE ENTRY
RSTAD2: POP P1,T1 ;GET OLD JBTAD2
TRZ T1,37777 ;CLEAR LOW SEG ADDRESS
MOVEM T1,JBTAD2##(J) ;UPDATE
POPJ P, ;RETURN
SAVAD2: PUSH P1,JBTAD2##(J) ;SAVE JBTAD2
POPJ P, ;RETURN
SUBTTL SAVE/RESTORE -- SET CPU (.STCPU) SETTING
CSRSPS: JRST SAVSPS ;SAVE ENTRY
RSTSPS: POP P1,T1 ;GET VALUE BACK
SKIPE [M.CPU##-1] ;ONLY IF REALLY SMP
DPB T1,[POINT 6,JBTSPS##(J),35] ;RESTORE IT TO CORRECT PLACE
POPJ P, ;DONE
SAVSPS: SKIPE T1,[M.CPU##-1] ;ONLY IF REALLY SMP
LDB T1,[POINT 6,JBTSPS##(J),35] ;GET VALUE WE CARE ABOUT
PUSH P1,T1 ;SAVE IT
POPJ P, ;DONE
SUBTTL SAVE/RESTORE -- UUO-LEVEL BIGBUF SIZE
CSRLBS: JRST SAVLBS ;SAVE ENTRY
RSTLBS: POP P1,T1 ;GET VALUE BACK
HRLM T1,.PDLBS##(W) ;RESTORE IT IN CORRECT PLACE
POPJ P, ;DONE
SAVLBS: HLRZ T1,.PDLBS##(W) ;GET VALUE WE CARE ABOUT
PUSH P1,T1 ;SAVE IT
POPJ P, ;DONE
SUBTTL SAVE/RESTORE -- HPQ AND HIBWAKE
IFN FTHPQ,<
CSRRTD: JRST SAVRTD ;SAVE ENTRY
RSTRTD: MOVSI T1,HPQMSK## ;SET HPQ COMMAND SETTING
ANDM T1,JBTRTD##(J) ;SAVE IT
ANDCAM T1,(P1) ;ELIMINATE FROM SAVED VALUES
POP P1,T1 ;RETRIEVE SAVED VALUES
IORM T1,JBTRTD##(J) ;RESTORE ALL OTHER VALUES
LDB T1,HPQPNT## ;GET UUO-LEVEL SETTING
PJRST HPQ## ;RE-PERFORM UUO, THEN BACK TO RESTCT
SAVRTD: PUSH P1,JBTRTD##(J) ;SAVE THE VALUE STRAIGHT AWAY
POPJ P, ;BACK TO SAVECT
> ;END OF IFN FTHPQ
SUBTTL SAVE/RESTORE -- PATCH SPACE
IFN FTPATT,<
CSRPAT: JRST SAVPAT ;SAVE ENTRY
RSTPAT: POP P1,T1 ;RETRIEVE DATA FROM CONTEXT STACK
JFCL ;MODIFY T1
JFCL ;PUT T1 SOMEWHERE
POPJ P, ;RETURN
SAVPAT: MOVEI T1,0 ;GET DATA INTO T1
JFCL ;MODIFY IT
PUSH P1,T1 ;SAVE DATA ON CONTEXT STACK
POPJ P, ;RETURN
> ;END OF IFN FTPATT
SUBTTL CTXUUO - CONTEXT UUO
; UUO TO MANIPULATE CONTEXTS
; CALL: MOVEI AC,ADR
; CTX. AC,
; <NON-SKIP>
; <SKIP>
; ARGUMENT BLOCK
.CTFNC==0 ;FUNCTION CODE WORD
CT.PHY==1B0 ;PHYSICAL ONLY RUN UUO
CT.LEN==777B17 ;LENGTH OF BLOCK INCLUDING THIS WORD
CT.FNC==777777B35 ;FUNCTION CODE
.CTSVH==0 ;SAVE CURRENT CONTEXT, HALT JOB
.CTSVR==1 ;SAVE CURRENT CONTEXT, RUN PROGRAM
.CTSVT==2 ;SAVE CURRENT CONTEXT, CREATE A TOP LEVEL
.CTSVS==3 ;SAVE CURRENT CONTEXT, SWITCH TO ANOTHER
.CTSVD==4 ;SAVE CURRENT CONTEXT, RUN PROGRAM
.CTRDB==5 ;READ DATA BUFFER
.CTWDB==6 ;WRITE DATA BUFFER
.CTRQT==7 ;READ QUOTAS INTO DATA BUFFER
.CTSQT==10 ;SET QUOTAS IN DATA BUFFER
.CTDIR==11 ;RETURN A DIRECTORY MAP OF ALL CONTEXTS
.CTINF==12 ;RETURN INFORMATION ABOUT A CONTEXT
.CTDBL==1 ;DATA BUFFER LENGTH
.CTDBA==2 ;DATA BUFFER ADDRESS
.CTNAM==3 ;SIXBIT CONTEXT NAME
.CTRNO==4 ;RUN UUO OFFSET (LH RESERVED)
.CTRNB==5 ;RUN UUO BLOCK ADDRESS
.CTTMN==6 ;TMPCOR LENGTH,,SIXBIT NAME
.CTTMB==7 ;TMPCOR BUFFER ADDRESS
.CTMAX==10 ;LENGTH OF ARGUMENT BLOCK
; DATA BUFFER OFFSETS FOR FUNCTIONS .CTRQT AND .CTSQT
.CTJOB==0 ;JOB NUMBER
.CTCTQ==1 ;CONTEXT QUOTA
.CTPGQ==2 ;SAVED PAGES QUOTA
; DATA BUFFER OFFSETS FOR FUNCTION .CTDIR
;.CTJOB==0 ;JOB NUMBER
.CTWCT==1 ;RETURNED WORD COUNT OF BYTE-STREAM DATA
.CTFDW==2 ;FIRST DATA WORD OF DIRECTORY BYTE-STREAM
; DATA BUFFER OFFSETS FOR FUNCTION .CTINF
;.CTJOB==0 ;JOB NUMBER
.CTCNO==1 ;THIS CONTEXT'S NUMBER
.CTCNM==2 ;THIS CONTEXT'S NAME
.CTSNO==3 ;SUPERIOR'S CONTEXT NUMBER
.CTSNM==4 ;SUPERIOR'S CONTEXT NAME
.CTPGM==5 ;PROGRAM NAME
.CTITM==6 ;IDLE TIME IN TICKS
; ON ANY RETURN, THE AC WILL CONTAIN THE FOLLOWING
CT.DAT==1B0 ;DATA WORDS RETURNED
CT.DBT==1B1 ;DATA BUFFER TRUNCATED
CT.ETX==1B2 ;UUO ERROR TEXT IN DATA BUFFER
CT.RUN==1B3 ;RUN UUO ERROR
CT.RDL==777B27 ;WORDS IN DATA BUFFER
CT.ERR==777B35 ;ERROR CODE
; CTX. UUO ERROR CODES AND ERROR DISPATCH ADDRESS GENERATION
DEFINE ERRS,<
XLIST
X (IFC,<Illegal function code>)
X (ACR,<Address check reading arguments>)
X (ACS,<Address check storing answers>)
X (NEA,<Not enough arguments>)
X (NLI,<Not logged in>)
X (LOK,<Locked in core>)
X (DET,<Detached>)
X (SCE,<System context quota exceeded>)
X (SPE,<System page quota exceeded>)
X (JCE,<Job context quota exceeded>)
X (JPE,<Job page quota exceeded>)
X (NCS,<Not enough core to save context>)
X (NCD,<Not enough core to return data block>)
X (ICN,<Illegal context number>)
X (NSC,<No superior context>)
X (NPV,<No privileges to set quotas>)
X (IJN,<Illegal job number>)
X (CSI,<Cannot switch to an intermediate context>)
X (CDI,<Cannot delete an intermediate context>)
X (CDC,<Cannot delete the current context>)
X (CNP,<Context not privileged>)
X (NDA,<No data block available>)
X (DTL,<Data block too long>)
X (CCC,<Cannot create context from a captive program>)
LIST
> ;END ERRS MACRO
DEFINE X (NAM,TEXT),<
CX'NAM'%==ZZ
ZZ==ZZ+1
ERR'NAM: JSP T1,ERRXIT
> ;END X MACRO
ZZ==0
ERRDSP:!
ERRS ;GENERATE ERROR CODES AND DISPATCH ADDRESSES
ERRXIT: HRRZS T1 ;KEEP ONLY RH
SUBI T1,ERRDSP+1 ;GET OFFSET
MOVSI T2,(CT.UUO) ;USER-MODE BIT
SKIPE P1 ;CONTEXT BLOCK SETUP YET?
TDNN T2,.PDCTX##(W) ;OR NOT USER LEVEL?
POPJ P, ;YES, JUST RETURN ERROR UP A LEVEL
SKIPN .CTDTU(P1) ;NO, USER SUPPLY A DATA BUFFER?
PJRST PUTAC ;STORE IN USER'S AC AND RETURN
MOVEM T1,.CTRET(P1) ;SAVE ERROR CODE
HLRZ T2,ERRTAB(T1) ;GET LENGTH OF MESSAGE
HLRZ T3,.CTDTL(P1) ;GET USER'S DATA BUFFER LENGTH
MOVSI T4,(CT.DBT) ;GET TRUNCATED BIT
CAMLE T2,T3 ;TEXT TOO LONG FOR BUFFER?
IORM T4,.CTRET(P1) ;YES--INDICATE SO
HRRM T2,.CTDTL(P1) ;STORE TEXT LENGTH
HRRZ T2,ERRTAB(T1) ;GET MESSAGE ADDRESS
MOVEM T2,.CTDTT(P1) ;SAVE EXEC ADDRESS
PUSHJ P,MDEUCT ;MOVE DATA FROM EXEC TO USER
MOVE T1,.CTRET(P1) ;GET STUFF TO RETURN IN USER'S AC
TLO T1,(CT.ETX) ;INDICATE RETURNING ERROR TEXT
PJRST PUTAC ;STORE IN USER'S AC AND RETURN
DEFINE X (NAM,TEXT),<
ZZ==0 ;;INIT COUNTER
IRPC TEXT,<ZZ==ZZ+1> ;;COUNT CHARACTERS
NAM'TXT: XWD <<ZZ/5>+1>,[ASCIZ |TEXT|]
>
ERRTAB: ERRS ;GENERATE ERROR TEXT TABLE
CTXUUO::MOVSI T2,(CT.UUO) ;IN UUO FLAG
IORM T2,.PDCTX##(W) ;SET FOR ERRXIT
MOVE P2,T1 ;SAVE ARG BLOCK ADDRESS
MOVE P3,P1 ;COPY PHYSICAL BIT
MOVE P1,.PDCTC##(W) ;POINT TO THE CURRENT CONTEXT BLOCK
LDB T1,PUUOAC## ;GET UUO AC
DPB T1,PCTXUA ;PRESERVE
MOVE M,P2 ;POINT M AT FIRST WORD OF USER ARG BLOCK
MOVE T1,M ;COPY ADDRESS
PUSHJ P,SXPCS## ;SET PCS
JRST ERRACR ;ADDRESS CHECK
PUSHJ P,GETEWD## ;GET FIRST WORD
JRST ERRACR ;ADDRESS CHECK READING ARGUMENTS
TLNE P3,PHONLY ;PHYSICAL ONLY?
TLO T1,(CT.PHY) ;YES
MOVE P3,T1 ;SAVE FUNCTION CODE, ETC.
LDB P4,[POINT 9,T1,17] ;GET ARG BLOCK LENGTH
PUSHJ P,UUODAT ;PROCESS DATA BLOCK ARGUMENTS
POPJ P, ;PROPAGATE ERROR
PUSHJ P,UUONAM ;PROCESS NEW CONTEXT NAME
POPJ P, ;PROPAGATE ERROR
PUSHJ P,UUOTMP ;PROCESS TMPCOR ARGUMENTS
POPJ P, ;PROPAGATE ERROR
PUSHJ P,UUORUN ;PROCESS RUN UUO BLOCK
POPJ P, ;PROPAGATE ERROR
JRST UUODSP
; PROCESS DATA BLOCK ARGUMENTS
UUODAT: PUSHJ P,ZERDAT ;CLEAR POINTERS TO STORAGE
CAIG P4,.CTDBL ;HAVE A DATA BLOCK WORD?
JRST CPOPJ1## ;NO
HRRI M,.CTDBL(P2) ;POINT M AT IT
PUSHJ P,GETEWD## ;GET LENGTH
JRST ERRACR ;ADDRESS CHECK READING ARGUMENTS
SKIPN T2,T1 ;PUT IN APPROPRIATE PLACE
JRST CPOPJ1## ;ZERO LENGTH DATA BLOCK
CAILE T2,^D510 ;MAXIMUM DATA BLOCK LENGTH
JRST ERRDTL ;DATA BLOCK TOO LONG
PUSHJ P,GETEW1## ;NOW GET ADDRESS WORD
JRST ERRACR ;ADDRESS CHECK READING ARGUMENTS
PUSHJ P,ARNGE## ;RANGE CHECK
JRST ERRACR ;ADDRESS CHECK
JFCL ;ADDRESS OK BUT ILLEGAL FOR I/O (IGNORED HERE)
MOVEM T1,.CTDTU(P1) ;SAVE ADDRESS
HRRM T2,.CTDTL(P1) ;SAVE REQUESTED LENGTH
JRST CPOPJ1## ;RETURN
; PROCESS NEW CONTEXT NAME
UUONAM: SETZM .CTNCN(P1) ;INIT NAME STORAGE
CAIG P4,.CTNAM ;HAVE A NAME?
JRST CPOPJ1## ;NO
HRRI M,.CTNAM(P2) ;POINT AT IT
PUSHJ P,GETEWD## ;GET SIXBIT NAME
JRST ERRACR ;ADDRESS CHECK
MOVEM T1,.CTNCN(P1) ;SAVE
JRST CPOPJ1## ;RETURN
; PROCESS TMPCOR ARGUMENTS
UUOTMP: CAIG P4,.CTTMN ;HAVE A TMPCOR BLOCK WORD?
JRST CPOPJ1## ;NO
HRRI M,.CTTMN(P2) ;POINT M AT IT
PUSHJ P,GETEWD## ;GET LENGTH,,NAME
JRST ERRACR ;ADDRESS CHECK READING ARGUMENTS
TLNE T1,-1 ;MUST BE A NON-ZERO LENGTH
SKIPN T3,T1 ;SAVE FOR A MINUTE
JRST CPOPJ1## ;SKIP TMPCOR STUFF
PUSHJ P,GETEW1## ;GET ADDRESS OF TMPCOR BLOCK
JRST ERRACR ;ADDRESS CHECK READING ARGUMENTS
HLRZ T2,T3 ;COPY LENGTH
PUSHJ P,ARNGE## ;RANGE CHECK
JRST ERRACR ;ADDRESS CHECK READING ARGUMENTS
JFCL ;ADDRESS OK BUT ILLEGAL FOR I/O (IGNORED HERE)
MOVEM T1,.CTTCA(P1) ;SAVE USER ADDRESS OF TMPCOR BUFFER
MOVEM T3,.CTTCR(P1) ;SAVE TMPCOR FILE LENGTH,,NAME
JRST CPOPJ1## ;RETURN
; PROCESS RUN UUO ARGUMENTS
UUORUN: PUSHJ P,CLRRUA ;CLEAR OUT RUN UUO STORAGE
CAIG P4,.CTRNO ;HAVE A RUN UUO BLOCK WORD?
JRST CPOPJ1## ;NO
IFN FTXMON,<PUSHJ P,SSPCS##> ;SAVE PCS
HRRI M,.CTRNO(P2) ;POINT M AT IT
PUSHJ P,GETEWD## ;GET RUN OFFSET WORD
JRST ERRACR ;ADDRESS CHECK READING ARGUMENTS
MOVE T3,T1 ;COPY FOR A MINUTE
PUSHJ P,GETEW1## ;GET RUN UUO BLOCK ADDRESS
JRST ERRACR ;ADDRESS CHECK READING ARGUMENTS
JUMPE T1,CPOPJ1## ;HAVE A RUN UUO BLOCK?
MOVEI T2,6 ;STANDARD LENGTH
PUSHJ P,ARNGE## ;RANGE CHECK
JRST ERRACR ;ADDRESS CHECK READING ARGUMENTS
JFCL ;OK IF NOT I/O LEGAL
HRLZM T3,.CTRUA(P1) ;STORE RUN UUO OFFSET IN TEMPORARY AC INCORE
SOS M,T1 ;COPY RUN UUO BLOCK ADDRESS -1
PUSHJ P,SXPCS## ;SET PCS ACCORDINGLY
JRST ERRACR ;ADDRESS CHECK
MOVSI T3,-6 ;LENGTH OF RUN UUO BLOCK
UUORU1: PUSHJ P,GETEW1## ;GET A WORD
JRST ERRACR ;ADDRESS CHECK READING ARGUMENTS
XMOVEI T2,.CTRUB(P1) ;POINT TO STARTING STORAGE ADDR
ADDI T2,(T3) ;INDEX
MOVEM T1,(T2) ;SAVE WORD
AOBJN T3,UUORU1 ;LOOP THROUGH BLOCK
SKIPE T1,.CTRUB+4(P1) ;GET PPN/PATH POINTER
TLNE T1,-1 ;A PATH?
JRST UUORU3 ;NO
HRRI M,-1(T1) ;POINT TO USER'S PATH BLOCK
MOVSI T3,-<2+1+MAXLVL> ;OVERHEAD WORDS + ONE PPN + MAXLVL SFDS
UUORU2: PUSHJ P,GETEW1## ;GET A WORD
JRST ERRACR ;ADDRESS CHECK READING ARGUMENTS
XMOVEI T2,.CTPUB(P1) ;POINT TO STARTING STORAGE ADDR
ADDI T2,(T3) ;INDEX
MOVEM T1,(T2) ;SAVE WORD
AOBJN T3,UUORU2 ;LOOP THROUGH PATH BLOCK
UUORU3: HLRE T1,.CTRUB+5(P1) ;GET LH
AOJN T1,CPOPJ1## ;RETURN IF NOTHING SPECIFIED
HRRZ T1,.CTRUB+5(P1) ;GET ADDRESS
HRRI M,-1(T1) ;POINT M AT IT
PUSHJ P,GETEW1## ;GET SECTION NUMBER
JRST ERRACR ;ADDRESS CHECK READING ARGUMENTS
HRRM T1,.CTRUA(P1) ;SAVE IN LH OF AC
JRST CPOPJ1## ;RETURN
UUODSP: HRRE T1,P3 ;GET FUNCTION CODE
CAML T1,[DSPCST-DSPTAB] ;RANGE
CAILE T1,DSPLEN ; CHECK
JRST ERRIFC ;ILLEGAL FUNCTION CODE
PJRST @DSPTAB(T1) ;DISPATCH
DSPCST==. ;END OF CUSTOMER DISPATCH TABLE
IFIW CPOPJ## ;(-1) FIRST CUSTOMER FUNCTION GOES HERE
DSPTAB: IFIW SAVHLT ;(00) SAVE CURRENT CONTEXT, HALT
IFIW SAVRUN ;(01) SAVE CURRENT CONTEXT, RUN PROGRAM
IFIW SAVTOP ;(02) SAVE CURRENT CONTEXT, CREATE A TOP LEVEL
IFIW SAVSWT ;(03) SAVE CURRENT CONTEXT, SWITCH TO ANOTHER
IFIW SAVDEL ;(04) SAVE CURRENT CONTEXT, DELETE ANOTHER
IFIW REDDAT ;(05) READ DATA BUFFER
IFIW WRTDAT ;(06) WRITE DATA BUFFER
IFIW REDQTA ;(07) READ QUOTAS INTO DATA BUFFER
IFIW SETQTA ;(10) SET QUOTAS IN DATA BUFFER
IFIW DIRECT ;(11) READ CONTEXT DIRECTORY MAP
IFIW INFORM ;(12) RETURN INFORMATION ABOUT A CONTEXT
DSPLEN==.-DSPTAB ;LENGTH OF TABLE
SAVRUN: MOVSI T1,(CT.PRN) ;PHYSICAL DEVICE SEARCH ON RUN UUO
ANDCAM T1,.PDCTX##(W) ;CLEAR BIT INITIALLY
TLNE P3,(CT.PHY) ;USER WANT PHYSICAL ONLY?
IORM T1,.PDCTX##(W) ;YES
TDZA T1,T1 ;DEFAULT IS TO RUN A PROGRAM
SAVHLT: MOVSI T1,(CT.HLT) ;LITE THE HALT BIT
TLO T1,(CT.UUO) ;REMEMBER SAVE CONTEXT VIA UUO
PUSH P,T1 ;SAVE FROM DESTRUCTION
PUSHJ P,MDUECT ;MOVE DATA FROM USER TO EXEC
JRST TPOPJ## ;FAILED
POP P,T1 ;GET FLAGS BACK
PUSHJ P,CTXPSH ;DO IT
POPJ P, ;FAILED--ERROR CODE IN T1
JRST CPOPJ1## ;RETURN AND CONTINUE PREVIOUS CONTEXT
SAVTOP: MOVSI T1,(CT.TOP!CT.HLT) ;CREATE TOP LEVEL CONTEXT AND HALT JOB
PUSHJ P,CTXPSH ;CREATE A NEW CONTEXT
POPJ P, ;FAILED--ERROR CODE IN T1
JRST CPOPJ1## ;RETURN AND CONTINUE PREVIOUS CONTEXT
SAVSWT: CAIG P4,.CTNAM ;HAVE A NAME ARGUMENT?
JRST ERRNEA ;NO, NOT ENOUGH ARGUMENTS
MOVE T1,.CTNCN(P1) ;GET NEW CONTEXT NAME
PUSHJ P,FINDCT ;FIND THE MATCHING NAME OR NUMBER
JRST ERRICN ;ILLEGAL CONTEXT NUMBER (OR NAME)
MOVE T1,.PDCTC##(W) ;POINT TO THE CURRENT CONTEXT
MOVEM P1,.CTNEW(T1) ;SET THE ONE WE'LL SWITCH TO
PUSHJ P,SWTCTX ;SWITCH TO ANOTHER CONTEXT
POPJ P, ;FAILED--ERROR CODE IN T1
JRST CPOPJ1## ;RETURN AND CONTINUE PREVIOUS CONTEXT
SAVDEL: CAIG P4,.CTNAM ;HAVE A NAME ARGUMENT?
JRST ERRNEA ;NO, NOT ENOUGH ARGUMENTS
MOVE T1,.CTNCN(P1) ;GET NEW CONTEXT NAME
PUSHJ P,FINDCT ;FIND THE MATCHING NAME OR NUMBER
JRST ERRICN ;ILLEGAL CONTEXT NUMBER (OR NAME)
MOVE T1,.PDCTC##(W) ;POINT TO THE CURRENT CONTEXT
MOVEM P1,.CTNEW(T1) ;SET THE ONE WE'LL SWITCH TO
MOVSI T1,(CT.UUO) ;UUO IN PROGRESS
PUSHJ P,DELCTX ;DELETE THE CONTEXT
POPJ P, ;FAILED--ERROR CODE IN T1
JRST CPOPJ1## ;RETURN AND CONTINUE PREVIOUS CONTEXT
REDDAT: PUSHJ P,INIDAT ;SET UP TO READ DATA BUFFER
POPJ P, ;PROPAGATE ERROR BACK
JUMPE T2,XITDAT ;ANY DATA TO MOVE?
REDDA1: MOVE T1,(T3) ;GET A WORD
PUSHJ P,PUTWD1## ;PUT A WORD
ADDI T3,1 ;POINT TO NEXT STORAGE LOCATION
AOBJN T2,REDDA1 ;LOOP
MOVSI T1,(CT.DBT) ;GET THE TRUNCATION BIT
ANDCAM T1,.CTRET(P1) ;CAN NEVER HAPPEN ON A READ
JRST XITDAT ;DONE
WRTDAT: PUSHJ P,INIDAT ;SET UP TO WRITE DATA BUFFER
POPJ P, ;PROPAGATE ERROR BACK
JUMPE T2,XITDAT ;ANY DATA TO MOVE?
WRTDA1: PUSHJ P,GETWD1## ;GET A WORD
MOVEM T1,(T3) ;PUT A WORD
ADDI T3,1 ;POINT TO NEXT STORAGE LOCATION
AOBJN T2,WRTDA1 ;LOPO
JRST XITDAT ;DONE
; COMMON INITIALIZATION CODE FOR READ AND WRITE DATA FUNCTIONS
INIDAT: SKIPN T4,.CTSUP(P1) ;HAVE A SUPERIOR CONTEXT?
JRST ERRNSC ;NO
CAIG P4,.CTDBA ;UUO BLOCK CONTAIN LENGTH AND ADDRESS WORDS?
JRST ERRNEA ;NO--NOT ENOUGH ARGUMENTS
MOVSI T1,(CT.DAT) ;WE'LL BE RETURNING DATA WORDS
HLRZ T2,.CTDTL(T4) ;GET ACTUAL LENGTH
HRRZ T3,.CTDTL(P1) ;GET REQUESTED LENGTH
CAMG T2,T3 ;REQUESTED GREATER THAN ACTUAL?
SKIPA T3,T2 ;NO--ONLY MOVE AS MUCH DATA AS IS AVAILABLE
TLO T1,(CT.DBT) ;DATA BLOCK TRUNCATED
MOVEM T1,.CTRET(P1) ;SAVE FOR UUO EXIT
MOVN T2,T3 ;USE THE SMALLER OF THE TWO LENGTHS
HRLZS T2 ;MAKE -LEN,,0
SKIPE T3,.CTDTE(T4) ;DO WE HAVE A BLOCK?
MOVE M,.CTDTU(P1) ;GET ADDRESS OF BLOCK IN USER CORE
SOJGE M,CPOPJ1## ;ADJUST BY ONE AND RETURN
JRST ERRNDA ;NO DATA BLOCK AVAILABLE
; COMMON EXIT CODE FOR READ AND WRITE DATA FUNCTIONS
XITDAT: MOVE T1,.CTRET(P1) ;GET RETURNED AC FLAGS, ETC.
DPB T2,PCTXDW ;STORE COUNT FOR USER
PJRST PUTAC1 ;PUT IN USER'S AC AND RETURN
; READ QUOTAS FOR SYSTEM OR ANY JOB
REDQTA: PUSHJ P,INIQTA ;SET UP FOR QUOTA READING
POPJ P, ;PROPAGATE ERROR BACK
SKIPN J ;JOB?
SKIPA T1,SYSCCQ ;SYSTEM
LDB T1,PCTXCQ ;GET CONTEXT QUOTA
PUSHJ P,PUTEW1## ;STORE IT
JRST ERRACS ;ADDRESS CHECK STORING ANSWERS
AOBJP T2,XITQTA ;BUFFER COUNT RUN OUT?
SKIPN J ;JOB?
SKIPA T1,SYSCPQ ;SYSTEM
LDB T1,PCTXPQ ;GET SAVED PAGE QUOTA
PUSHJ P,PUTEW1## ;STORE IT
JRST ERRACS ;ADDRESS CHECK STORING ANSWERS
AOJA T2,XITQTA ;FIX UP USER'S AC AND RETURN
; SET QUOTAS FOR SYSTEM OR ANY JOB
SETQTA: PUSHJ P,PRVJC## ;GODLY?
SKIPA ;LETTERRIP
JRST ERRNPV ;MUST BE [1,2] OR JACCT
PUSHJ P,INIQTA ;SET UP FOR QUOTA SETTING
POPJ P, ;PROPAGATE ERROR BACK
PUSHJ P,GETEW1## ;GET CONTEXT QUOTA
JRST ERRACR ;ADDRESS CHECK READING ARGUMENTS
SKIPE J ;JOB?
DPB T1,PCTXCQ ;SET JOB QUOTA
SKIPN J ;SYSTEM?
MOVEM T1,SYSCCQ ;SET SYSTEM-WIDE QUOTA
AOBJP T2,XITQTA ;BUFFER COUNT RUN OUT?
PUSHJ P,GETEW1## ;GET SAVED PAGES QUOTA
JRST ERRACR ;ADDRESS CHECK READING ARGUMENTS
SKIPE J ;JOB?
DPB T1,PCTXPQ ;SET JOB QUOTA
SKIPN J ;SYSTEM?
MOVEM T1,SYSCPQ ;SET SYSTEM-WIDE QUOTA
AOJA T2,XITQTA ;FIX UP USER'S AC AND RETURN
; COMMON SETUP CODE FOR SET AND READ QUOTA FUNCTIONS
INIQTA: CAIG P4,.CTDBA ;HAVE A DATA BUFFER LENGTH AND ADDRESS?
JRST ERRNEA ;NOT ENOUGH ARGUMENTS
IFN FTXMON,<PUSHJ P,SSPCS##> ;SAVE PCS
HRRI M,.CTDBL(P2) ;POINT TO DATA BUFFER LENGTH WORD
HLL M,P2 ;INCLUDE SECTION NUMBER
MOVE T1,M ;SET UP CALL
PUSHJ P,SXPCS## ;SET PCS ACCORDINGLY
JRST ERRACR ;ADDRESS CHECK
PUSHJ P,GETEWD## ;GET ADDRESS
JRST ERRACR ;ADDRESS CHECK READING ARGUMENTS
SKIPG T2,T1 ;SAVE LENGTH
JRST ERRNEA ;NOT ENOUGH ARGUMENTS
MOVNS T2 ;NEGATE
HRLZS T2 ;MAKE IT -COUNT,,0
PUSHJ P,GETEW1## ;GET ADDRESS
JRST ERRACR ;ADDRESS CHECK READING ARGUMENTS
MOVE M,T1 ;POINT M AT USER'S BUFFER
PUSHJ P,SXPCS## ;SET PCS ACCORDINGLY
JRST ERRACR ;ADDRESS CHECK
PUSHJ P,GETEWD## ;GET JOB NUMBER IN T1
JRST ERRACR ;ADDRESS CHECK READING ARGUMENTS
AOBJP T2,ERRNEA ;NEED AT LEAST TWO WORDS
JUMPE J,CPOPJ1## ;RETURN IF READING OR SETTING SYSTEM QUOTAS
CAMN T1,[EXP -1] ;EXCEPTION
MOVE T1,.CPJOB## ;-1 MEANS SELF
MOVE J,T1 ;LOAD JOB NUMBER
PUSHJ P,FNDPDB## ;SET UP W WITH THE TARGET PDB
JRST ERRIJN ;BAD JOB NUMBER
PUSHJ P,PUTWDU## ;ALWAYS RETURN JOB NUMBER (INCASE -1 GIVEN)
JUMPE J,CPOPJ1## ;NO INTERLOCKING NEEDED IF NULL JOB
CAME J,.CPJOB## ;DOING TO SELF?
PUSHJ P,UPCX## ;PREVENT RACES
JRST CPOPJ1## ;INDICATE JOB QUOTAS AND RETURN
; COMMON EXIT CODE FOR SET AND READ QUOTA FUNCTIONS
XITQTA: SKIPE J ;NULL JOB?
CAMN J,.CPJOB## ;DOING TO SELF?
SKIPA ;NO INTERLOCKING NEEDED
PUSHJ P,DWNCX## ;GIVE UP CX RESOURCE
MOVSI T1,(CT.DAT) ;INDICATE STUFF IN THE DATA BUFFER
DPB T2,PCTXDW ;STORE WORDS RETURNED
PJRST PUTAC1 ;STUFF INTO THE USER'S AC AND RETURN
; RETURN A DIRECTORY OF THE CONTEXT CHAINS FOR A JOB
; DATA IS STORED IN THE USER'S DATA BUFFER IN THE FOLLOWING
; FORMAT:
; BUFFER/ EXP JOB# ;SUPPLIED BY USER
; EXP WORDS RETURNED
; BYTE(9) CTX1, INF1, INF2, ..., NUL
; BYTE(9) CTX2, INF1, INF2, ..., NUL
; . .
; . .
; . .
DIRECT:
IFN FTXMON,<PUSHJ P,SSPCS##> ;SAVE PCS
PUSHJ P,DIRINI ;INIT DATA BUFFER STUFF
POPJ P, ;CAN'T
TLNN M,(IFIW) ;LOCAL REFERENCE?
AOSA M ;NO
HRRI M,1(M) ;ADVANCE BUT DON'T CROSS SECTION BOUNDRIES
SETZ P2, ;CLEAR MAP STORAGE ADDRESS
PUSHJ P,FNDPDB## ;FIND TARGET JOB'S PDB
JRST DIRIJN ;ILLEGAL JOB NUMBER
CAME J,.CPJOB## ;IS IT US?
PUSHJ P,UPCX## ;PDB ACCESS REQUIRES CX RESOURCE
MOVEI T2,2*CTXMAP## ;NUMBER OF WORDS FOR TWO MAPS
PUSHJ P,GTFWDC## ;GET FUNNY WORDS, CACHED
JRST DIRNCS ;NOT ENOUGH CORE
IFE FTXMON,<
HRLZ T3,T1 ;GET STARTING ADDRESS
HRRI T3,1(T1) ;MAKE A BLT POINTER
SETZM (T1) ;CLEAR FIRST WORD
BLT T3,<2*CTXMAP##>-1(T1) ;CLEAR BOTH MAPS
> ;END IFE FTXMON
IFN FTXMON,<
MOVEI T2,2*CTXMAP##-1 ;LENGTH MAY HAVE BEEN CLOBBERED
MOVE T3,T1 ;COPY STARTING ADDRESS
AOS T4,T1 ;MAKE A BLT POINTER
SETZM (T3) ;ZERO FIRST WORD
EXTEND T2,[XBLT] ;ZREO BOTH MAPS
> ;END IFN FTXMON
PUSH P,M ;SAVE DATA BUFFER ADDRESS FOR LATER
PUSH P,P3 ;SAVE DATA BUFFER LENGTH
PUSH P,P3 ;SAVE WORKING COPY
MOVE P1,.PDSAC##(W) ;POINT TO START OF CHAIN
SOS P2,T1 ;COPY CONTEXT INFERIOR MAP ADDRESS
IOR P2,DIRPTR ;MAKE A BYTE POINTER
MOVE P3,P2 ;ANOTHER COPY
ADDI P3,CTXMAP## ;POINT TO CONTEXT HEADER MAP
MOVNI T1,1 ;-1
EXCH T1,P3 ;SWAP SO ADJBP PUTS RESULT IN P3
ADJBP P3,T1 ;ACCOUNT FOR IDPB STORAGE
MOVNI U,1 ;FLAG HAVING MAP STORAGE NOW
; HERE TO SCAN CONTEXT CHAIN(S) AND BUILD TWO MAPS.
;
; P3 CONTAINS A BYTE POINTER TO THE "HEAD OF CHAIN" MAP. EACH SUCESSIVE
; BYTE WITHIN THE MAP HOLDS THE CONTEXT NUMBER OF ITS IMMEDIATE INFERIOR
; CONTEXT. A ZERO BYTE INDICATES THERE ARE NO MORE CHAINS.
;
; P2 CONTAINS A BYTE POINTER TO THE "INFERIOR" MAP. THIS MAP IS INDEXED
; BY THE CONTEXT NUMBERS. A ZERO BYTE INDICATES THE END OF THE CHAIN.
;
; TO FOLLOW A CONTEXT CHAIN FROM THE HEAD OF THE CHAIN TO THE MOST INFERIOR
; CONTEXT, FIRST PICK UP A CONTEXT NUMBER FROM THE "HEAD OF CHAIN" MAP.
; THEN INDEX INTO THE "INFERIOR" MAP USING SAID CONTEXT NUMBER. THIS BYTE
; WILL CONTAIN THE CONTEXT NUMBER OF THE NEXT INFERIOR, WHICH AGAIN MAY BE
; USED TO INDEX INTO THE "INFERIOR" MAP. EVENTUALLY, A CONTEXT NUMBER OF
; ZERO WILL BE FOUND, INDICATING THE END OF THE CHAIN.
DIREC1: MOVE T1,P1 ;SAVE STARTING BLOCK ADDRESS
LDB T3,PCTXNO ;GET CURRENT CONTEXT NUMBER
SKIPN T2,.CTSUP(P1) ;THIS BLOCK HAVE A SUPERIOR?
JRST DIREC2 ;NO
MOVE P1,T2 ;POINT TO SUPERIOR
LDB T4,PCTXNO ;GET SUPERIOR CONTEXT NUMBER
ADJBP T4,P2 ;POSITION IN INFERIOR MAP
DPB T3,T4 ;STORE INFERIOR CONTEXT NUMBER
JRST DIREC3 ;SEE IF MORE CONTEXT BLOCKS
DIREC2: IDPB T3,P3 ;STORE TOP LEVEL CONTEXT NUMBER
DIREC3: SKIPE P1,.CTNXT(T1) ;POINT TO NEXT BLOCK
JRST DIREC1 ;FOLLOW CHAINS
MOVNI P3,1 ;-1
ADJBP P3,P2 ;POINT TO START OF INFERIOR MAP
ADDI P3,CTXMAP## ;ADVANCE TO CONTEXT HEADER MAP
DIREC4: ILDB T1,P3 ;GET STARTING CONTEXT NUMBER OF A CHAIN
JUMPE T1,DIREC8 ;DONE?
PUSHJ P,DIRSET ;SET UP BYTE POINTER AND COUNT FOR STORAGE
IDPB T1,T2 ;STORE HEAD OF CHAIN
SOJA T3,DIREC6 ;ENTER LOOP
DIREC5: PUSHJ P,DIRSET ;SET UP BYTE POINTER AND COUNT FOR STORAGE
DIREC6: ADJBP T1,P2 ;INDEX INTO INFERIOR MAP
MOVE T4,T1 ;COPY UPDATED BYTE POINTER
LDB T1,T4 ;GET NEXT INFERIOR CONTEXT NUMBER
IDPB T1,T2 ;SAVE TEMPORARILY
JUMPE T1,DIREC7 ;END OF CHAIN?
SOJG T3,DIREC6 ;LOOP BACK FOR ANOTHER
DIREC7: EXCH T1,P4 ;SAVE T1, GET WORD OF BYTES
PUSHJ P,DIRPUT ;STORE IN DATA BUFFER
JRST DIRACP ;ADDRESS CHECK??
SKIPE T1,P4 ;RESTORE T1
JRST DIREC5 ;LOOP IF MORE INFERIORS
JRST DIREC4 ;ELSE SEE IF MORE CHAINS TO TRAVERSE
; HERE TO FINISH UP
DIREC8: POP P,T1 ;GET COUNT OF WORDS STORED (SORT OF)
POP P,T2 ;AND COUNT OF DATA WORDS AVAILABLE
SUBI T1,(T2) ;COMPUTE TOTAL WORDS NEEDED TO RETURN ALL DATA
POP P,M ;GET DATA BUFFER ADDRESS BACK
PUSHJ P,PUTEWD## ;STORE
JRST DIRACS ;ADDRESS CHECK STORING ANSWERS
PUSHJ P,DIRRST ;RESET THINGS
MOVSI T3,(CT.DAT) ;DATA BEING RETURNED
ADDI T1,2 ;ACCOUNT FOR OVERHEAD WORDS
SKIPGE T1 ;TRUNCATED?
TLO T3,(CT.DBT) ;YES
CAIL T1,(T2) ;TRIED TO RETURN MORE THAN DATA BUFFER LENGTH?
MOVE T1,T2 ;YES--GET LENGTH SUPPLIED BY USER
EXCH T1,T3 ;SWAP SO WE CAN USE APPROPRIATE BYTE POINTER
DPB T3,PCTXDW ;STORE WORDS RETURNED
PJRST PUTAC1 ;PUT C(T1) IN UUO AC AND RETURN
; INIT DATA BUFFER POINTERS
DIRINI: CAIG P4,.CTDBA ;HAVE A DATA BUFFER LENGTH AND ADDRESS?
JRST ERRNEA ;NOT ENOUGH ARGUMENTS
HRRI M,.CTDBL(P2) ;POINT TO DATA BUFFER LENGTH WORD
HLL M,P2 ;INCLUDE SECTION NUMBER
SOS T1,M ;SET UP CALL
PUSHJ P,SXPCS## ;SET PCS ACCORDINALY
JRST ERRACR ;ADDRESS CHECK
PUSHJ P,GETEW1## ;GET DATA BUFFER LENGTH
JRST ERRACR ;ADDRESS CHECK
SKIPLE P3,T1 ;COPY LENGTH
CAIGE P3,2 ;NEED AT LEAST TWO WORDS
JRST ERRNEA ;NOT ENOUGH ARGUMENTS
PUSHJ P,GETEW1## ;GET ADDRESS OF DATA BLOCK
JRST ERRACR ;ADDRESS CHECK
MOVE M,T1 ;COPY IT
PUSHJ P,SXPCS## ;SET INITIAL PCS
JRST ERRACR ;ILLEGAL ADDRESS
PUSHJ P,GETEWD## ;GET FIRST WORD (TARGET JOB NUMBER)
JRST ERRACR ;ADDRESS CHECK READING ARGUMENT
CAMN T1,[EXP -1] ;IS IT US?
MOVE T1,.CPJOB## ;YES
JUMPLE T1,ERRIJN ;CHECK FOR ILLEGAL JOB NUMBERS
PUSHJ P,PUTEWD## ;UPDATE DATA BUFFER INCASE -1 GIVEN
JRST ERRACS ;ADDRESS CHECK STORING ANSWER
MOVE J,T1 ;GET JOB IN QUESTION
JRST CPOPJ1## ;RETURN
; RETURN ADDRESS CHECK ERROR AFTER PHASING STACK
DIRACP: POP P,(P) ;PRUNE GARBAGE
POP P,(P) ; OFF THE
POP P,(P) ; STACK
; RETURN ADDRESS CHECK ERROR
DIRACS: PUSHJ P,DIRRST ;RESET THINGS
JRST ERRACS ;ADDRESS CHECK STORING ANSWERS
; RETURN ILLEGAL JOB NUMBER ERROR
DIRIJN: PUSHJ P,DIRRST ;RESET THINGS
JRST ERRIJN ;ILLEGAL JOB NUMBER
; RETURN NOT ENOUGH CORE ERROR
DIRNCS: PUSHJ P,DIRRST ;RESET THINGS
JRST ERRNCS ;NOT ENOUGH CORE
; HERE TO RESET THINGS ON ERRORS OR FINAL DIRECTORY FUNCTION EXIT
DIRRST: CAME J,.CPJOB## ;IS IT US?
PUSHJ P,DWNCX## ;PDB ACCESS REQUIRED CX RESOURCE
MOVE J,.CPJOB## ;RESET OUR JOB NUMBER
PUSHJ P,FNDPDS## ;POINT TO OUR PDB
MOVE P1,.PDCTC##(W) ;RESET P1 FOR ERROR RETURN
JUMPE P2,CPOPJ## ;RETURN IF NOT OWNING ANY MAPS
PUSH P,T1 ;SAVE T1
PUSH P,T2 ;SAVE T2
MOVEI T1,2*CTXMAP## ;NUMBER OF WORDS FOR TWO MAPS
HRRZ T2,P2 ;POINT TO MAPS
PUSHJ P,GVFWDS## ;GIVE UP FUNNY SPACE
JRST TTPOPJ## ;AND RETURN
; SET UP BYTE POINTER AND COUNT FOR STORAGE INTO USER'S DATA BUFFER
DIRSET: MOVNI T2,1 ;-1
MOVE T3,DIRPTR ;GET BYTE POINTER FOR STORAGE
HRRI T3,P4 ;TEMPORARY PLACE WHILE DOING IDPBS
ADJBP T2,T3 ;ACCOUNT FOR IDPB STORAGE
MOVEI T3,CTXBPW## ;BYTES PER WORD
SETZ P4, ;ZERO TEMPORARY STORAGE
POPJ P, ;AND RETURN
; ROUTINE TO STORE A WORD IN THE DATA BUFFER
DIRPUT: SOSGE -2(P) ;ROOM TO STORE?
JRST DIRPU1 ;NO--TRY TO PREVENT A KAF
PUSH P,J ;SAVE J
MOVE J,.CPJOB## ;INCASE LOOKING AT ANOTHER JOB
PUSHJ P,PUTEW1## ;PUT C(T1) INTO DATA BUFFER
JRST JPOPJ## ;ADDRESS CHECK??
POP P,J ;RESTORE JOB WE'RE LOOKING AT
; HERE TO PREVENT KAF STOPCODES. SCDCHK WILL BE CALLED EVERY
; CTXBPW*17 TIMES THROUGH THE CONTEXT NUMBER STORAGE LOOP.
DIRPU1: EXCH T1,-1(P) ;SAVE T1 AND GET COUNT
TRNN T1,17 ;TIME TO TAKE A REST?
PUSHJ P,SCDCHK## ;GIVE SOMEONE ELSE A CHANCE TO RUN
EXCH T1,-1(P) ;RESTORE T1 AND COUNT
JRST CPOPJ1## ;RETURN
; RETURN INFORMATION ABOUT A SINGLE CONTEXT
; DATA IS STORED IN THE USER'S DATA BUFFER IN THE FOLLOWING
; FORMAT:
; BUFFER/ EXP JOB# ;SUPPLIED BY THE USER
; EXP CONTEXT# ;SUPPLIED BY THE USR
; SIXBIT /CONTEXT-NAME/ ;TARGET CONTEXT'S NAME
; EXP SUP# ;SUPERIOR'S CONTEXT NUMBER
; SIXBIT /SUP-NAME/ ;SUPERIOR'S CONTEXT NAME
; SIXBIT /PROGRAM/ ;PROGRAM NAME
; EXP TIME ;IDLE TIME IN TICKS
;
; *** NOTE ***
; THE INTENT OF THIS FUNCTION IS TO PROVIDE THE SAME INFORMATION
; CURRENTLY AVAILABLE AT MONITOR LEVEL USING THE CONTEXT COMMAND.
; ALTHOUGH IT'S TEMPTING TO RETURN ADDITIONAL INFORMATION, A MORE
; GENERALIZED MECHANISM SHOULD BE EMPLOYED RATHER THAN EXPANDING
; THIS FUNCTION OF THE CONTEXT UUO. PERHAPS AN EXTENSION TO THE
; GETTAB UUO IS NEEDED. IN ANY CASE, WE'LL SAVE THIS FOR ANOTHER
; MONITOR RELEASE.
INFORM:
IFN FTXMON,<PUSHJ P,SSPCS##> ;SAVE PCS
PUSHJ P,DIRINI ;INIT DATA BUFFER POINTERS
POPJ P, ;PROPAGATE ERROR
SUBI P3,1 ;ACCOUNT FOR JOB NUMBER WORD ALREADY STORED
CAME J,.CPJOB## ;IS IT US?
PUSHJ P,UPCX## ;PDB ACCESS REQUIRES CX RESOURCE
PUSHJ P,FNDPDB## ;FIND TARGET JOB'S PDB
JRST INFIJN ;ILLEGAL JOB NUMBER
MOVE P1,.PDCTC##(W) ;POINT TO CURRENT BLOCK FOR TARGET JOB
PUSHJ P,GETEW1## ;GET NEXT WORD (CONTEXT NUMBER)
JRST INFACR ;ADDRESS CHECK READING ARGUMENTS
SUBI M,1 ;SET UP M FOR NEXT STORE
SKIPN T1 ;CONTEXT ZERO REQUESTED?
LDB T1,PCTXNO ;USER WANTS THE CURRENT ONE
CAIL T1,1 ;RANGE
CAILE T1,CTXMAX## ; CHECK
JRST INFICN ;PRELIMINARY CHECK SAYS NUMBER IS NO GOOD
LSH T1,CTXLSH## ;POSITION
IOR T1,J ;FORM JCH
PUSHJ P,JBCHCT ;FIND TARGET CONTEXT BLOCK
JRST INFICN ;ILLEGAL CONTEXT NUMBER
JFCL ;DON'T CARE IF IT'S THE CURRENT ONE
LSH T1,-CTXLSH## ;KEEP ONLY THE CONTEXT NUMBER
PUSHJ P,INFPUT ;STORE INCASE CONTEXT ZERO WAS SPECIFIED
JRST INFACS ;ADDRESS CHECK
MOVSI P2,-INFLEN ;AOBJN POINTER
INFOR1: XCT INFTAB(P2) ;GET A WORD OF DATA
PUSHJ P,INFPUT ;PUT A WORD OF DATA
JRST INFACS ;ADDRESS CHECK STORING ANSWERS
AOBJN P2,INFOR1 ;LOOP
PUSHJ P,INFRST ;RESET THINGS
JRST CPOPJ1## ;RETURN
INFTAB: MOVE T1,.CTCBN(P1) ;TARGET CONTEXT'S NAME
PUSHJ P,INFNUM ;SUPERIOR'S CONTEXT NUMBER
PUSHJ P,INFNAM ;SUPERIOR'S CONTEXT NAME
MOVE T1,.CTPRG(P1) ;PROGRAM NAME
PUSHJ P,INFIDL ;IDLE TIME IN TICKS
INFLEN==.-INFTAB ;LENGTH OF TABLE
; SUPERIOR'S CONTEXT NUMBER
INFNUM: SKIPN T1,.CTSUP(P1) ;GET SUPERIOR CONTEXT BLOCK ADDRESS
POPJ P, ;THERE IS NONE
MOVE T2,T1 ;COPY
EXCH T2,P1 ;SWAP WITH CURRENT
LDB T1,PCTXNO ;GET CONTEXT NUMBER
MOVE P1,T2 ;REPLACE
POPJ P, ;RETURN
; SUPERIOR'S CONTEXT NAME
INFNAM: SKIPE T1,.CTSUP(P1) ;GET SUPERIOR CONTEXT BLOCK ADDRESS
MOVE T1,.CTCBN(T1) ;GET NAME
POPJ P, ;RETURN
; IDLE TIME IN TICKS
INFIDL: MOVE T1,SYSUPT## ;GET SYSTEM UPTIME
SUB T1,.CTIDL(P1) ;COMPUTE IDLE TIME FOR THIS CONTEXT
POPJ P, ;RETURN
; RETURN ADDRESS CHECK ERROR
INFACR: PUSHJ P,INFRST ;RESET THINGS
JRST ERRACR ;ADDRESS CHECK READING ARGUMENTS
; RETURN ADDRESS CHECK ERROR
INFACS: PUSHJ P,INFRST ;RESET THINGS
JRST ERRACS ;ADDRESS CHECK STORING ANSWERS
; RETURN ILLEGAL JOB NUMBER ERROR
INFIJN: PUSHJ P,INFRST ;RESET THINGS
JRST ERRIJN ;ILLEGAL JOB NUMBER
; RETURN ILLEGAL CONTEXT NUMBER
INFICN: PUSHJ P,INFRST ;RESET THINGS
JRST ERRICN ;ILLEGAL CONTEXT NUMBER
; HERE TO RESET THINGS ON ERRORS OR FINAL INFORMATION FUNCTION EXIT
INFRST: CAME J,.CPJOB## ;IS IT US?
PUSHJ P,DWNCX## ;PDB ACCESS REQUIRED CX RESOURCE
MOVE J,.CPJOB## ;RESET OUR JOB NUMBER
PUSHJ P,FNDPDS## ;POINT TO OUR PDB
MOVE P1,.PDCTC##(W) ;RESET P1 FOR ERROR RETURN
POPJ P, ;RETURN
; ROUTINE TO STORE A WORD IN THE DATA BUFFER
INFPUT: SOJL P3,CPOPJ1## ;RETURN IF NO MORE ROOM
PUSH P,J ;SAVE J
MOVE J,.CPJOB## ;INCASE LOOKING AT ANOTHER JOB
PUSHJ P,PUTEW1## ;PUT C(T1) INTO DATA BUFFER
JRST JPOPJ## ;ADDRESS CHECK??
POP P,J ;RESTORE JOB WE'RE LOOKING AT
JRST CPOPJ1## ;RETURN
SUBTTL UTILITY ROUTINES -- CREBLK - CREATE A CONTEXT BLOCK
CREBLK:
IFN FTXMON,<
CTXLOK ;INTERLOCK SCANNING THE LIST
PUSHJ P,UUOLVL## ;SKIP IF AT UUO LEVEL (CAN BLOCK)
SKIPN T1,RESBLK ;HAVE ANY RESERVED CONTEXT BLOCKS?
JRST CREBL1 ;GO ALLOCATE CORE
MOVE T2,.CTNXT(T1) ;GET POINTER TO NEXT BLOCK (IF ANY)
MOVEM T2,RESBLK ;PUT AT HEAD OF CHAIN
SOS RESCNT ;COUNT DOWN
CTXNLK ;DONE CHANGING THE LIST
JRST CREBL2 ;SKIP CORE ALLOCATION STUFF
CREBL1: CTXNLK ;DONE SCANNING THE LIST
> ;END IFN FTXMON
MOVEI T2,.CTSIZ ;GET LENGTH OF CONTEXT SAVE BLOCK
PUSHJ P,GETCOR ;MAKE A BLOCK
POPJ P, ;NO AVAILABLE CORE
CREBL2: MOVE P1,T1 ;COPY NEW BLOCK ADDRESS
SETZM @P1 ;CLEAR FIRST WORD OF CONTEXT BLOCK
IFE FTXMON,<
MOVSI T1,(P1) ;GET START ADDRESS
HRRI T1,1(P1) ;MAKE A BLT POINTER
BLT T1,.CTSIZ-1(P1) ;CLEAR THE CONTEXT BLOCK
> ;END IFE FTXMON
IFN FTXMON,<
MOVEI T1,.CTSIZ-1 ;LENGTH OF TRANSFER
MOVE T2,P1 ;START ADDR
XMOVEI T3,1(P1) ;MAKE A BLT POINTER
EXTEND T1,[XBLT] ;ZAP BLOCK
> ;END IFN FTXMON
SKIPE T1,.PDSAC##(W) ;POINT TO START OF CHAIN
JRST CREBL3 ;ONWARD
MOVEM P1,.PDSAC##(W) ;FIRST BLOCK IN CHAIN
JRST CREBL5 ;GO FINISH UP
CREBL3: SKIPN T2,.CTNXT(T1) ;GET ADDRESS OF NEXT BLOCK
JRST CREBL4 ;END OF CHAIN
MOVE T1,T2 ;COPY ADDRESS
JRST CREBL3 ;SEARCH FOR END
CREBL4: MOVEM P1,.CTNXT(T1) ;LINK NEW BLOCK AT END OF CHAIN
MOVEM T1,.CTPRV(P1) ;LINK BACK TO PREVIOUS BLOCK
MOVE T2,.PDCTC##(W) ;GET CURRENT CONTEXT BLOCK ADDRESS
MOVEM T2,.CTLAS(P1) ;SAVE POINTER TO CONTEXT BLOCK WITH ARGS
MOVE T3,.CTTCR(T1) ;GET TMPCOR FILE LENGTH,,NAME
MOVEM T3,.CTTCR(P1) ;SAVE IN NEW CONTEXT BLOCK
MOVE T3,.CTTCE(T1) ;GET TMPCORE FILE ADDRESS (EXEC)
MOVEM T3,.CTTCE(P1) ;COPY TO NEW CONTEXT BLOCK
IFE FTXMON,<
MOVE T2,.CTLAS(P1) ;GET PREVIOUS BLOCK ADDRESS
MOVSI T1,.CTRUA(T2) ;POINT TO RUN UUO ARGUMENTS
HRRI T1,.CTRUA(P1) ;START OF RUN STORAGE
BLT T1,.CTRUA+1+6+2+MAXLVL-1(P1) ;COPY TO NEW BLOCK
> ;END IFE FTXMON
IFN FTXMON,<
MOVEI T1,1+6+2+MAXLVL-1 ;NUMBER OF WORDS TO COPY
MOVE T2,.CTLAS(P1) ;POINT TO PREVIOUS BLOCK
XMOVEI T2,.CTRUA(T2) ;FROM HERE
XMOVEI T3,.CTRUA(P1) ;INTO HERE
EXTEND T1,[XBLT] ;COPY TO NEW BLOCK
> ;END IFN FTXMON
MOVE T2,.CTLAS(P1) ;POINT TO PREVIOUS BLOCK
SETZ T1, ;CLEAR FOR NEXT TIME AND
EXCH T1,.CTNCN(T2) ; GET THE NEW CONTEXT NAME
PUSHJ P,NAMECT ;ASSIGN IT
CREBL5: PUSHJ P,INTLVL## ;RUNNING AT INTERRUPT LEVEL?
SKIPN T1,.CPJCH## ;NO--GET JCH (CREATOR OF THIS BLOCK)
MOVE T1,J ;MUST BE A NEW JOB
HRLI T1,'CTX' ;INCLUDE IDENTIFIER
MOVEM T1,.CTJCH(P1) ;SAVE IN BLOCK FOR TRACKING PURPOSES
MOVEM P1,.PDCTC##(W) ;SET NEW BLOCK AS CURRENT ONE
JRST CPOPJ1## ;AND RETURN
SUBTTL UTILITY ROUTINES -- DELBLK - DELETE A CONTEXT BLOCK
DELBLK: MOVE P1,.PDCTC##(W) ;GET CURRENT BLOCK ADDRESS
MOVE T1,.CTNXT(P1) ;GET LINK TO NEXT BLOCK
SKIPE T2,.CTPRV(P1) ;GET LINK TO PREVIOUS BLOCK
MOVEM T1,.CTNXT(T2) ;LINK PREVIOUS TO NEXT
SKIPE T1 ;CHECK FOR END OF CHAIN
MOVEM T2,.CTPRV(T1) ;LINK NEXT TO PREVIOUS
SKIPN T2 ;FIRST BLOCK GO AWAY?
MOVEM T1,.PDSAC##(W) ;YES--LINK THE NEXT ONE AT THE START
SKIPN T1,.CTSUP(P1) ;GET SUPERIOR CONTEXT FOR THE ONE TO BE DELETED
MOVE T1,.PDSAC##(W) ;ELSE POINT TO THE START OF THE CHAIN
MOVEM T1,.PDCTC##(W) ;MAKE IT THE NEW CURRENT CONTEXT
IFN FTXMON,<
CAMGE P1,SYSSIZ## ;BLOCK COME FROM LOW CORE?
JRST DELBL1 ;YES--ALWAYS RELEASE IT
CTXLOK ;INTERLOCK
MOVE T1,RESCNT ;GET COUNT RESERVED CONTEXT BLOCKS
IFN FTMP,<SKIPGE MMREQ##> ;CAN WE GET THE MM?
CAMGE T1,RESMAX ;HAVE ENOUGH?
AOJA T1,DELBL2 ;PUT ON RESERVED CHAIN
CTXNLK ;RELEASE INTERLOCK
DELBL1:
> ;END IFN FTXMON
MOVEI T1,.CTSIZ ;NUMBER OF WORDS
MOVE T2,P1 ;ADDRESS OF CONTEXT BLOCK
PUSHJ P,GIVCOR ;RETURN CORE
JRST DELBL5 ;AND FINISH UP
IFN FTXMON,<
DELBL2: MOVEM T1,RESCNT ;UPDATE COUNT
MOVEI T1,RESBLK-.CTNXT ;PRESET STORAGE
DELBL3: SKIPN T2,.CTNXT(T1) ;GET ADDRESS OF NEXT BLOCK
JRST DELBL4 ;END OF CHAIN
MOVE T1,T2 ;COPY ADDRESS
JRST DELBL3 ;SEARCH FOR END
DELBL4: MOVEM P1,.CTNXT(T1) ;LINK NEW BLOCK TO END OF CHAIN
SETZM .CTNXT(P1) ;CLEAR OLD LINK SINCE AT END OF CHAIN
CTXNLK ;RELEASE INTERLOCK
> ;END IFN FTXMON
DELBL5: MOVE P1,.PDCTC##(W) ;RESET CURRENT CONTEXT POINTER
POPJ P, ;AND RETURN
SUBTTL UTILITY ROUTINES -- LSTBLK - LIST CONTEXT BLOCK STATUS
LSTBLK: MOVEI T1,[ASCIZ | |] ;ASSUME NOT THE CURRENT ONE
CAMN P1,.PDCTC##(W) ;IS IT?
MOVEI T1,[ASCIZ |* |] ;YES
PUSHJ P,CONMES## ;TYPE JUNK
MOVE T4,.CTCBN(P1) ;GET CONTEXT NAME
PUSHJ P,LSTCNM ;TYPE IT
PUSHJ P,PRSPC## ;SPACE OVER
LDB T2,PCTXNO ;GET CONTEXT NUMBER
PUSHJ P,LSTCNO ;TYPE IT
PUSHJ P,LSTSPC ;SPACE OVER
SKIPN T1,.CTSUP(P1) ;GET SUPERIOR CONTEXT ADDRESS
JRST LSTBL1 ;THERE ISN'T ONE
MOVE T4,.CTCBN(T1) ;GET SUPERIOR CONTEXT NAME
PUSHJ P,LSTCNM ;TYPE IT
PUSHJ P,PRSPC## ;SPACE OVER
PUSH P,P1 ;SAVE SUPERIOR
MOVE P1,.CTSUP(P1) ;POINT TO SUPERIOR CONTEXT AGAIN
LDB T2,PCTXNO ;GET ITS CONTEXT NUMBER
PUSHJ P,LSTCNO ;TYPE IT
POP P,P1 ;RESTORE SUPERIOR
JRST LSTBL2 ;ONWARD
LSTBL1: MOVEI T1,[ASCIZ | |]
PUSHJ P,CONMES## ;FILL FIELD WITH SPACES
LSTBL2: PUSHJ P,LSTSPC ;SPACE OVER
CAMN P1,.PDCTC##(W) ;CURRENT CONTEXT?
SKIPA T4,JBTNAM##(J) ;YES--GET PROGRAM NAME FROM JOB TABLE
MOVE T4,.CTPRG(P1) ;ELSE USE SAVED PROGRAM NAME
PUSHJ P,LSTCNM ;TYPE IT
CAMN P1,.PDCTC##(W) ;IS THIS THE CURRENT CONTEXT?
JRST LSTBL3 ;YES--THEN IT'S NOT IDLE
PUSHJ P,LSTSPC ;SPACE OVER
MOVE T1,SYSUPT## ;GET SYSTEM UPTIME
SUB T1,.CTIDL(P1) ;COMPUTE IDLE TIME FOR THIS CONTEXT
PUSHJ P,PRTIM## ;TYPE IT
LSTBL3: PJRST PCRLF## ;TYPE A CRLF AND RETURN
; CONTEXT NAME
LSTCNM: MOVEI T2,6 ;SIX CHARACTERS
LSTCN1: LSHC T3,6 ;SHIFT IN A CHARACTER
ANDI T3,77 ;NO JUNK
ADDI T3,40 ;CONVERT TO ASCII
PUSH P,T4 ;SAVE THE REMAINDER OF THE NAME
PUSHJ P,PRCHR## ;TYPE CHARACTER
POP P,T4 ;RESTORE NAME
SOJG T2,LSTCN1 ;LOOP
POPJ P, ;RETURN
; CONTEXT NUMBER
LSTCNO: MOVEI T3," " ;GET A LEADING SPACE
CAIGE T2,^D10 ;000 - 009?
PUSHJ P,PRCHR## ;SPACE
CAIGE T2,^D100 ;010 - 099?
PUSHJ P,PRCHR## ;SPACE
MOVE T1,T2 ;GET NUMBER
PJRST PRTDIG## ;TYPE NUMBER AND RETURN
; SPACES
LSTSPC: MOVEI T1,[ASCIZ | |]
PJRST CONMES## ;TYPE SPACES AND RETURN
SUBTTL UTILITY ROUTINES -- MDUECT - MOVE DATA FROM USER TO EXEC
MDUECT: HRLS T2,.CTDTL(P1) ;GET REQUESTED LENGTH, MAKE ACTUAL LENGTH
JUMPE T2,MDUEC2 ;CHECK TMPCOR STUFF IF NO DATA BUFFER
HRRZS T2 ;KEEP REASONABLE
PUSHJ P,GTFWDC## ;GET FUNNY WORDS, CACHED
JRST MDUEC4 ;NOT ENOUGH CORE
MOVEM T1,.CTDTE(P1) ;SAVE ADDRESS
HRRZ T1,.CTDTL(P1) ;LENGTH
SUBI T1,1 ;MAKE TRANSFER LENGTH
MOVE T2,.CTDTE(P1) ;START ADDRESS
SETZM @T2 ;CLEAR FIRST WORD OF DATA BUFFER IN MONITOR
IFE FTXMON,<
ADDI T1,(T2) ;COMPUTE END ADDRESS
HRLS T2 ;PUT IN LH
HRRI T2,1(T2) ;MAKE A BLT POINTER
BLT T2,-1(T1) ;CLEAR ENTIRE BLOCK
> ;END IFE FTXMON
IFN FTXMON,<
XMOVEI T3,1(T2) ;MAKE A BLT POINTER
EXTEND T1,[XBLT] ;CLEAR ENTIRE BLOCK
PUSHJ P,SSPCS## ;SAVE PCS
> ;END IFN FTXMON
MOVE M,.CTDTU(P1) ;POINT M AT THE DATA
SOS T1,M ;-1 FOR DATMAN
PUSHJ P,SXPCS## ;SET PCS ACCORDINGLY
JRST MDUEC5 ;ADDRESS CHECK
HRRZ T2,.CTDTL(P1) ;GET LENGTH AGAIN
MOVE T3,.CTDTE(P1) ;AND IT WILL GO HERE
MDUEC1: PUSHJ P,GETEW1## ;GET A WORD
JRST MDUEC5 ;ADDRESS CHECK READING ARGUMENTS
MOVEM T1,(T3) ;PUT A WORD
ADDI T3,1 ;POINT TO NEXT STORAGE LOCATION
SOJG T2,MDUEC1 ;LOOP
MDUEC2: HLRZ T2,.CTTCR(P1) ;GET TMPCOR FILE LENGTH
JUMPE T2,CPOPJ1## ;NO--RETURN
ADDI T2,2 ;PLUS OVERHEAD WORDS
PUSHJ P,GTFWDC## ;GET FUNNY WORDS, CACHED
JRST MDUEC6 ;NOT ENOUGH CORE
MOVEM T1,.CTTCE(P1) ;SAVE ADDRESS
HLRZ T1,.CTTCR(P1) ;LENGTH
ADDI T1,2-1 ;PLUS OVERHEAD WORDS -1
MOVE T2,.CTTCE(P1) ;START ADDRESS
SETZM @T2 ;CLEAR FIRST WORD OF DATA BUFFER IN MONITOR
IFE FTXMON,<
ADDI T1,(T2) ;COMPUTE END ADDRESS
HRLS T2 ;PUT IN LH
HRRI T2,1(T2) ;MAKE A BLT POINTER
BLT T2,-1(T1) ;CLEAR ENTIRE BLOCK
> ;END IFE FTXMON
IFN FTXMON,<
XMOVEI T3,1(T2) ;MAKE A BLT POINTER
EXTEND T1,[XBLT] ;CLEAR ENTIRE BLOCK
PUSHJ P,SSPCS## ;SAVE PCS
> ;END IFN FTXMON
HRLZ T1,.CTTCR(P1) ;GET TMPCOR FILE NAME,,0
HLRZ T2,.CTTCR(P1) ;GET LENGTH
MOVNS T2 ;NEGATE
HRLZS T2 ;PUT IN LH
MOVE T3,.CTTCE(P1) ;GET LENGTH OF DATA BUFFER IN MONITOR
DMOVEM T1,(T3) ;STORE
ADDI T3,2 ;ACCOUNT FOR OVERHEAD WORDS
HLRZ T2,.CTTCR(P1) ;GET LENGTH OF TMPCOR FILE
MOVE T1,.CTTCA(P1) ;POINT M AT THE USER'S TMPCOR BUFFER
SOS M,T1 ;COPY ADDRESS
PUSHJ P,SXPCS## ;SET PCS ACCORDINGLY
JRST MDUEC5 ;ADDRESS CHECK
MDUEC3: PUSHJ P,GETEW1## ;GET A WORD
JRST MDUEC5 ;ADDRESS CHECK READING ARGUMENTS
MOVEM T1,(T3) ;PUT A WORD
ADDI T3,1 ;POINT TO NEXT STORAGE LOCATION
SOJG T2,MDUEC3 ;LOOP
JRST CPOPJ1## ;AND RETURN
MDUEC4: PUSHJ P,ZERDAT ;ZERO OUT DATA BLOCK POINTERS
JRST ERRNCS ;NOT ENOUGH CORE TO SAVE CONTEXT
MDUEC5: PUSHJ P,MDEUC2 ;RELEASE CORE, ZERO POINTERS
JRST ERRACR ;ADDRESS CHECK READING ARGUMENTS
MDUEC6: PUSHJ P,MDEUC2 ;RELEASE CORE, ZERO POINTERS
JRST ERRNCS ;NOT ENOUGH CORE TO SAVE CONTEXT
SUBTTL UTILITY ROUTINES -- MCEUCT - MOVE DATA FROM EXEC TO USER
MDEUCT: HRRZ T2,.CTDTL(P1) ;GET NUMBER OF WORDS RETURNED
SKIPE T3,.CTDTT(P1) ;HAVE A DATA BLOCK?
SOSG M,.CTDTU(P1) ;WHERE TO PUT IT IN USER CORE
JRST MDEUC2 ;JUST GET RID OF TMPCOR
IFN FTXMON,<PUSHJ P,SSPCS##> ;SAVE PCS
MOVE T1,M ;SET UP CALL
PUSHJ P,SXPCS## ;SET PCS ACCORDINGLY
POPJ P, ;GIVE UP
MOVNS T2 ;NEGATE
HRLZS T2 ;MAKE -LEN,,0
MDEUC1: MOVE T1,(T3) ;GET A WORD
PUSHJ P,PUTEW1## ;PUT A WORD
POPJ P, ;SHOULDN'T FAIL AT THIS POINT
ADDI T3,1 ;ADVANCE EXEC ADDRESS BY ONE
AOBJN T2,MDEUC1 ;LOOP
MOVE T1,.CTRET(P1) ;GET AC CONTENTS TO RETURN
TLO T1,(CT.DAT) ;RETURNING DATA WORDS
DPB T2,PCTXDW ;STORE NUMBER OF DATA WORDS
MOVEM T1,.CTRET(P1) ;UPDATE
MDEUC2: HLRZ T1,.CTDTL(P1) ;GET ACTUAL BUFFER LENGTH
SKIPE T2,.CTDTE(P1) ;GET STORAGE ADDRESS
PUSHJ P,GIVCOR ;RELEASE CORE
HLRZ T1,.CTTCR(P1) ;GET TMPCOR FILE LENGTH
ADDI T1,2 ;PLUS OVERHEAD WORDS
SKIPE T2,.CTTCE(P1) ;GET STORAGE ADDRESS
PUSHJ P,GIVCOR ;RELEASE CORE
HRRZ T1,.CTDTL(P1) ;GET LENGTH
SKIPN T2,.CTDTT(P1) ;GET TEMPORARY STORAGE ADDRESS
PJRST ZERDAT ;JUST ZAP DATA BLOCK POINTERS AND RETURN
CAIL T2,CTXSER ;IF THE ADDRESS IS
CAILE T2,CTXEND ; IN CTXSER, THEN IT
PUSHJ P,GIVCOR ; DIDN'T COME FROM FRECOR
PJRST ZERDAT ;ZERO OUT DATA BLOCK POINTERS AND RETURN
SUBTTL UTILITY ROUTINES -- MOVE DATA FROM INFERIOR TO EXEC
MDIECT: SKIPE P2,.CTSUP(P1) ;HAVE A SUPERIOR CONTEXT?
SKIPN .CTDTE(P2) ;HAVE A DATA BUFFER?
POPJ P, ;NO--JUST RETURN
HRRZ T2,.CTDTL(P2) ;GET NUMBER OF DATA WORDS WRITTEN
PUSHJ P,GETCOR ;GET CORE
JRST MDIEC1 ;NOT ENOUGH CORE TO RETURN DATA BUFFER
MOVEM T1,.CTDTT(P2) ;SAVE TEMPORARY BUFFER ADDRESS IN SUPERIOR
HRRZ T1,.CTDTL(P2) ;GET WORDS TO COPY
IFE FTXMON,<
HRLZ T2,.CTDTE(P2) ;WHERE THE BUFFER RESIDES NOW
HRR T2,.CTDTT(P2) ;AND WHERE IT'S BEING MOVED TO
ADD T1,.CTDTT(P2) ;COMPUTE END ADDRESS
BLT T2,-1(T1) ;COPY BUFFER
> ;END IFE FTXMON
IFN FTXMON,<
MOVE T2,.CTDTE(P2) ;WHERE THE BUFFER RESIDES NOW
MOVE T3,.CTDTT(P2) ;AND WHERE IT'S BEING MOVED TO
EXTEND T1,[XBLT] ;COPY BUFFER
> ;END IFN FTXMON
PJRST ZERDAT ;SKIP AROUND ERROR NONSENSE
MDIEC1: PUSHJ P,ERRNCD ;NOT ENOUGH CORE TO RETURN DATA BUFFER
MOVSI T1,(CT.UUE) ;FLAG A UUO ERROR
IORM T1,.CTFLG(P2) ;AND CAUSE AN ERROR RETURN TO SUPERIOR
; PJRST ZERDAT ;CLEAR POINTERS AND RETURN
ZERDAT: SETZM .CTDTL(P1) ;CLEAR BLOCK LENGTH(S)
SETZM .CTDTU(P1) ;CLEAR BLOCK ADDRESS IN USER CORE
SETZM .CTDTE(P1) ;CLEAR BLOCK ADDRESS IN EXEC CORE
SETZM .CTDTT(P1) ;CLEAR BLOCK ADDRESS IN EXEC CORE (TEMPORARY)
SETZM .CTTCR(P1) ;CLEAR TMPCOR FILE LENGTH,,NAME
SETZM .CTTCA(P1) ;CLEAR TMPFOR FILE ADDRESS (USER)
SETZM .CTTCE(P1) ;CLEAR TMPFOR FILE ADDRESS (EXEC)
POPJ P, ;RETURN
SUBTTL UTILITY ROUTINES -- LGLCHK - CHECK LEGALITY
LGLCHK: MOVEI T1,CT.LGO ;BIT TO TEST
MOVSI T2,JLOG ;ANOTHER BIT TO TEST
TDNN T1,.PDCTX##(W) ;CURRENTLY TRYING TO LOGOUT?
TDNE T2,JBTSTS##(J) ;LOGGED IN?
SKIPA T1,[NSHF!NSWP,,0];YES TO EITHER
JRST ERRNLI ;NO
MOVSI T2,LOKSEG ;OR A LOCKED HIGH SEG
TDNN T1,JBTSTS##(J) ;LOW LOCKED?
TDNE T2,JBTSGN##(J) ;HIGH SEG LOCKED?
JRST ERRLOK ;YES--CAN'T DO IT
PUSHJ P,TTYSRC## ;NEED A TTY
JRST ERRDET ;JOB IS DETACHED
PUSHJ P,SYSNUM ;CHECK SYSTEM-WIDE CONTEXT QUOTAS
JRST ERRSCE ;SYSTEM CONTEXT QUOTA EXCEEDED
PUSHJ P,SYSPAG ;CHECK SYSTEM-WIDE PAGES IN USE
JRST ERRSPE ;SYSTEM PAGE QUOTA EXCEEDED
PUSHJ P,QTANUM ;CHECK CONTEXTS IN USE
JRST ERRJCE ;JOB CONTEXT QUOTA EXCEEDED
PUSHJ P,QTAPAG ;CHECK PAGES IN USE
JRST ERRJPE ;JOB PAGE QUOTA EXCEEDED
PUSHJ P,SWPCHK ;CHECK FOR ENOUGH SWAPPING SPACE
JRST ERRNCS ;NOT ENOUGH VIRTUAL CORE TO SAVE CONTEXT
MOVEI T2,JS.RPC ;BIT TO TEST
SKIPE .PDPGM##(W) ;PROGRAM TO RUN?
TDNN T2,JBTST2##(J) ;AND NEVER RETURN TO MONITOR?
JRST CPOPJ1## ;NO--OK TO SAVE CONTEXT
TLNE P2,(CT.HLT) ;AUTO-SAVE?
JRST ERRCCC ;NO--CANNOT CREATE CONTEXT FROM CAPTIVE PROGRAM
JRST CPOPJ1## ;OK TO SAVE CONTEXT
; CHECK JOB CONTEXT QUOTA NUMBERS
QTANUM: LDB T1,PCTXCQ ;GET CONTEXT QUOTA
LDB T2,PCTXCU ;GET NUMBER OF CONTEXTS IN USE
ADDI T2,1 ;THIS WILL BE THE NEW NUMBER
SKIPN T1 ;HAVE A CONTEXT QUOTA?
MOVEI T1,CTXMAX## ;NO--CHECK AGAINST ABSOLUTE MAXIMUM
CAML T1,T2 ;EXCEED NUMBER OF CONTEXTS?
JRST CPOPJ1## ;NO--DONE CHECKING
PUSHJ P,JACCTP ;GODLY PROGRAM?
JRST QTANU1 ;YES--LET HIM THROUGH
TLNN P2,(CT.ATO!CT.SWT) ;NO--OK TO EXCEED QUOTA?
POPJ P, ;NO
AOSA NPQEXC ;NORMAL PROGRAM SAVE QUOTA EXCEEDED
QTANU1: AOS JPPEXC ;JACCT PROGRAM SAVE QUOTA EXCEEDED
JRST CPOPJ1## ;AND LET THE JOB CONTINUE
; CHECK CONTEXT PAGES
QTAPAG: PUSHJ P,CORESZ ;COMPUTE SIZE OF CORE IMAGE
LDB T2,PCTXPU ;GET PAGES IN USE
ADD T1,T2 ;THIS WILL BE THE NEW NUMBER
LDB T2,PCTXPQ ;GET PAGE QUOTA
SKIPN T2 ;HAVE A PAGE QUOTA?
SETZ T1, ;NO--THE SKY'S THE LIMIT
CAMG T1,T2 ;EXCEED THE NUMBER OF SAVED PAGES ALLOWED?
JRST CPOPJ1## ;OK TO PROCEED
PUSHJ P,JACCTP ;GODLY PROGRAM?
JRST QTAPA1 ;YES--LET HIM THROUGH
TLNN P2,(CT.ATO!CT.SWT) ;NO--OK TO EXCEED QUOTA?
POPJ P, ;NO
AOSA NPPEXC ;NORMAL PROGRAM PAGE QUOTA EXCEEDED
QTAPA1: AOS JPPEXC ;JACCT PROGRAM PAGE QUOTA EXCEEDED
JRST CPOPJ1## ;AND LET THE JOB CONTINUE
; CHECK SYSTEM-WIDE CONTEXT QUOTA NUMBERS
SYSNUM: SKIPN SYSCCQ ;HAVE A SYSTEM-WIDE QUOTA?
JRST CPOPJ1## ;NO QUOTA ENFORCEMENT
CTXLOK ;INTERLOCK DATA BASE
MOVE T1,SYSCCU ;GET SYSTEM-WIDE CONTEXTS IN USE
ADDI T1,1 ;THIS WILL BE THE NEW NUMBER
CAMG T1,SYSCCQ ;OVER THE LIMIT?
AOS (P) ;NO
CTXNLK ;GIVE UP INTERLOCK
POPJ P, ;RETURN
; CHECK SYSTEM-WIDE PAGE QUOTAS
SYSPAG: SKIPN SYSCPQ ;HAVE A SYSTEM-WIDE QUOTA?
JRST CPOPJ1## ;NO QUOTA ENFORCEMENT
PUSHJ P,CORESZ ;COMPUTE SIZE OF CORE IMAGE
CTXLOK ;INTERLOCK DATA BASE
MOVE T2,SYSCPU ;GET PAGES IN USE
ADD T1,T2 ;THIS WILL BE THE NEW NUMBER
CAMGE T1,SYSCPQ ;OVER THE LIMIT?
AOS (P) ;NO
CTXNLK ;GIVE UP INTERLOCK
POPJ P, ;RETURN
; CHECK VIRTAL
SWPCHK: PUSHJ P,CORESZ ;COMPUTE SIZE OF CORE IMAGE
MOVE T2,VIRTAL## ;GET TOTAL SWAPPING SPACE AVAILABLE
SUB T2,T1 ;SUBTRACT AMOUNT NEEDED
JUMPG T2,CPOPJ1## ;HAVE ENOUGH
POPJ P, ;TOO BAD
; CHECK IF A JACCT'ED PROGRAM
JACCTP: MOVSI T3,JACCT ;THE BIT TO TEST
TLNE P2,(CT.UUO) ;COMING FROM COMCON?
TDNN T3,JBTSTS##(J) ;NO, TEST FOR GODLINESS OF PROGRAM
AOS (P) ;NOT GODLY ENOUGH
POPJ P, ;RETURN APPROPRIATELY
SUBTTL UTILITY ROUTINES -- CORESZ - COMPUTE CORE IMAGE SIZE
; CALL: PUSHJ P,CORESZ
;
; ON RETURN T1 WILL CONTAIN THE SUM OF THE LOW AND HIGH SEG SIZES
CORESZ: PUSH P,J ;SAVE J
S0PSHJ SEGSIZ## ;GET LOW SEGMENT SIZE
PUSH P,T2 ;SAVE IT
SETZ T1, ;FIRST CALL
CORSZ0: PUSHJ P,GNXHSB## ;GET NEXT HIGH SEG BLOCK
JRST CORSZ1 ;DONE
SKIPLE J,.HBSGN(T1) ;SEGMENT WORD
TLNE J,SHRSEG ;SHARABLE?
JRST CORSZ0 ;CONTINUE WITH NEXT SEGMENT
S0PSHJ SEGSIZ## ;GET HISEG SIZE
ADDM T2,(P) ;ACCUMULATE TOTAL
TLNE J,UWPOFF
AOS (P)
JRST CORSZ0 ;CONTINUE WITH NEXT SEGMENT
CORSZ1: POP P,T1 ;RESTORE T1
POP P,J ;RESTORE JOB NUMBER
POPJ P, ;AND RETURN
SUBTTL UTILITY ROUTINES -- CONTEXT ACCOUNTING
; INCREMENT THE CONTEXT NUMBER
UPCTXN: LDB T1,PCTXCU ;GET CURRENT CONTEXT LEVEL
ADDI T1,1 ;COUNT UP
TDNE T1,[-1-CTXMAX##];FIELD OVERFLOW?
PUSHJ P,CTXSTP ;YES--DIE
DPB T1,PCTXCU ;UPDATE CONTEXT NUMBER
AOS SYSCCU ;COUNT UP SYSTEM-WIDE CONTEXTS IN USE
POPJ P, ;AND RETURN
; DECREMENT THE CONTEXT NUMBER
DNCTXN: LDB T1,PCTXCU ;GET CURRENT CONTEXT LEVEL
SUBI T1,1 ;COUNT DOWN
TDNE T1,[-1-CTXMAX##];FIELD UNDERFLOW?
PUSHJ P,CTXSTP ;YES--DIE
DPB T1,PCTXCU ;UPDATE CONTEXT NUMBER
CTXLOK ;INTERLOCK DATA BASE
SOSGE SYSCCU ;COUNT DOWN SYSTEM-WIDE CONTEXTS IN USE
PUSHJ P,CTXSTP ;WENT TOO FAR
CTXNLK ;RELEASE INTERLOCK
POPJ P, ;AND RETURN
CTXSTP: STOPCD .,INFO,CTX, ;++CONTEXT SKEW
; INCREMENT THE NUMBER OF SAVED CONTEXT PAGES
UPPAGE: PUSHJ P,CORESZ ;COMPUTE SIZE OF CORE IMAGE
CTXLOK ;INTERLOCK DATA BASE
ADDM T1,SYSCPU ;ADD TO SYSTEM SAVE PAGE TOTAL
CTXNLK ;RELEASE INTERLOCK
LDB T2,PCTXPU ;GET PAGES USED SO FAR
ADD T1,T2 ;ACCUMULATE
DPB T1,PCTXPU ;UPDATE TOTAL
POPJ P, ;AND RETURN
; DECREMENT THE NUMBER OF SAVED CONTEXT PAGES
DNPAGE: PUSHJ P,CORESZ ;COMPUTE SIZE OF CORE IMAGE
CTXLOK ;INTERLOCK DATA BASE
MOVE T2,SYSCPU ;GET SYSTEM SAVE PAGE TOTAL
SUB T2,T1 ;ADJUST
SKIPGE T2 ;SHOULD NEVER BE NEGATIVE
PUSHJ P,CTXSTP ;DIE
MOVEM T2,SYSCPU ;UPDATE
CTXNLK ;RELEASE INTERLOCK
LDB T2,PCTXPU ;GET TOTAL PAGES USED
SUB T2,T1 ;DECREMENT
SKIPGE T2 ;SHOULD NEVER BE NEGATIVE
PUSHJ P,CTXSTP ;DIE
DPB T2,PCTXPU ;UPDATE
POPJ P, ;AND RETURN
SUBTTL UTILITY ROUTINES -- CLRCOM - CLEAR COMCON INPUT BUFFER
CLRCOM: MOVSI T1,(CT.UUO) ;GET THE UUO FLAG
TDNN T1,.PDCTX##(W) ;UUO IN PROGRESS?
PUSHJ P,TTYCMR## ;NO, LIGHT COMMAND SYNCH BIT (END OF COMMAND)
MOVSI T1,(CT.ATO) ;BIT FOR TESTING
TDNN T1,.PDCTX##(W) ;IF NOT AUTO-SAVE
PUSHJ P,TYIEAT## ;THEN MAKE COMCON NOT REREAD COMMANDS
POPJ P, ;GO BACK
SUBTTL UTILITY ROUTINES -- CLRRUA - CLEAR RUN UUO ARGUMENT STORAGE
; CLEAR RUN UUO ARGUMENT STORAGE IN THE CONTEXT BLOCK
; CALL: PUSHJ P,CLRRUA
CLRRUA: SETZM .CTRUA(P1) ;CLEAR FIRST WORD OF RUN STORAGE
IFE FTXMON,<
MOVSI T1,.CTRUA(P1) ;START OF RUN STORAGE
HRRI T1,.CTRUA+1(P1) ;MAKE A BLT POINTER
BLT T1,.CTRUA+1+6+2+MAXLVL-1(P1) ;CLEAR OUT OUR BLOCKS
> ;END IFE FTXMON
IFN FTXMON,<
MOVEI T1,1+6+2+MAXLVL-1 ;NUMBER OF WORDS TO CLEAR
XMOVEI T2,.CTRUA(P1) ;FROM HERE
XMOVEI T3,.CTRUA+1(P1) ;INTO HERE
EXTEND T1,[XBLT] ;CLEAR OUT OUR BLOCKS
> ;END IFN FTXMON
POPJ P, ;RETURN
SUBTTL UTILITY ROUTINES -- GETRUA - GET RUN UUO ARGUMENTS FROM USER CORE
GETRUA: MOVSI T1,(CT.UUO) ;BIT TO TEST
TDNN T1,.PDCTX##(W) ;CALLED VIA UUO?
PUSHJ P,CLRRUA ;NO--CLEAR STORAGE SINCE NOT DONE YET
MOVSI T1,(CT.ATO) ;BIT TO TEST
TDNN T1,.PDCTX##(W) ;AUTO-SAVE AND RUN?
POPJ P, ;JUST RETURN
MOVE T1,.CTPRG(P1) ;GET INVOKING COMMAND NAME
CAMN T1,PLNTXT## ;USER DEFINED COMMAND?
JRST GETRU1 ;YES--MUST HANDLE DIFFERENTLY
MOVEM T1,.CTRUB+1(P1) ;SAVE PROGRAM NAME
MOVSI T1,'SYS' ;DEVICE
MOVEM T1,.CTRUB+0(P1) ;SAVE IT
POPJ P, ;DONE
GETRU1: MOVE T1,JBTNAM##(J) ;GET CORRECT NAME TO SAVE
MOVEM T1,.CTPRG(P1) ;AND DO SO
HLRZ P2,.CTDSP(P1) ;GET DISPATCH ADDRESS (USER COMMAND BLOCK)
MOVE T1,(P2) ;GET WORD COUNT
SUBI T1,1 ;ACCOUNT FOR WORD COUNT WORD
MOVE T2,1(P2) ;DEVICE
MOVEM T2,.CTRUB+0(P1)
SOJLE T1,CPOPJ1##
MOVE T2,2(P2) ;FILE NAME
MOVEM T2,.CTRUB+1(P1)
SOJLE T1,CPOPJ1##
MOVE T2,3(P2) ;EXTENSION
MOVEM T2,.CTRUB+2(P1)
SOJLE T1,CPOPJ1##
AOS .CTRUB+4(P1) ;REMEMBER THAT WE HAVE A PATH
IFE FTXMON,<
MOVSI T2,4(P2) ;START ADDRESS
HRRI T2,.CTPUB+2(P1) ;WHERE TO PUT IT
ADDI T1,.CTPUB+2(P1) ;COMPUTE END ADDRESS
BLT T2,-1(T1) ;COPY
> ;END IFE FTXMON
IFN FTXMON,<
XMOVEI T2,4(P2) ;FIRST WORD OF PATH
XMOVEI T3,.CTPUB+2(P1) ;WHERE TO PUT IT
EXTEND T1,[XBLT] ;COPY
> ;END IFN FTXMON
POPJ P, ;ALL DONE
SUBTTL UTILITY ROUTINES -- PUTRUA - PUT RUN UUO ARGUMENTS IN USER CORE
PUTRUA:
IFE FTXMON,<
MOVSI T1,.CTRUB(P1) ;POINT TO RUN UUO BLOCK
HRRI T1,.JDAT+.JBDA## ;WHERE TO PUT IT
BLT T1,.JDAT+.JBDA##+6-1 ;COPY IT
MOVSI T1,.CTPUB(P1) ;POINT TO PATH UUO BLOCK
HRRI T1,.JDAT+.JBDA##+7 ;WHERE TO PUT IT
BLT T1,.JDAT+.JBDA##+7+2+1+MAXLVL-1 ;COPY IT
> ;END IFE FTXMON
IFN FTXMON,<
MOVEI T1,6 ;LENGTH
XMOVEI T2,.CTRUB(P1) ;POINT TO RUN UUO BLOCK
MOVEI T3,.JDAT+.JBDA## ;WHERE TO PUT IT
EXTEND T1,[XBLT] ;COPY IT
HRRZ T1,.CTRUA(P1) ;GET /USE SECTION NUMBER
MOVEM T1,.JDAT+.JBDA##+6 ;STORE
HRROI T1,.JBDA##+6 ;WORD TO STUFF INTO BLOCK
SKIPE .CTRUB+5(P1) ;USER GIVE A POINTER?
MOVEM T1,.JDAT+.JBDA##+5 ;POINT TO SECTION NUMBER
MOVEI T1,2+1+MAXLVL ;LENGTH
XMOVEI T2,.CTPUB(P1) ;POINT TO PATH UUO BLOCK
MOVEI T3,.JDAT+.JBDA##+7 ;WHERE TO PUT IT
EXTEND T1,[XBLT] ;COPY IT
> ;END IFN FTXMON
MOVEI T1,.JBDA##+7 ;RELATIVE ADDRESS OF PATH BLOCK IN PAGE
SKIPE T2,.CTRUB+4(P1) ;HAVE A PPN/PATH POINTER?
TLNE T2,-1 ;PATH POINTER?
SKIPA ;NO
MOVEM T1,.JDAT+.JBDA##+4;SET IT UP
HLLZ T1,.CTRUA(P1) ;GET RUN UUO OFFSET
HRRI T1,.JBDA## ;ARGUMENTS LIVE HERE
EXCTXU <MOVEM T1,0> ;STORE IN USER AC 0
MOVEI M,0 ;SET UP AC 'M' FOR GETWRD CALLS
POPJ P, ;RETURN
SUBTTL UTILITY ROUTINES -- GETCOR/GIVCOR - CORE ALLOCATION
GETCOR:
IFN FTXMON,< ;IF MONITOR SUPPORTS EXTENDED ADDRESSING,
PUSHJ P,INTLVL## ;CAN WE BLOCK?
PJRST GFWNZS## ;YES, GET NON-ZERO SECTION FREE CORE
>
PJRST GETWDS## ;NO--GET SECTION ZERO FREE CORE
GIVCOR: CAMGE T2,SYSSIZ## ;SECTION ZERO FREE CORE?
PJRST GIVWDS## ;RETURN SECTION ZERO FREE CORE
IFE FTMP,<PJRST GVFWDS##> ;RETURN FUNNY OR NZS CORE
IFN FTMP,<
PUSHJ P,INTLVL## ;CAN WE BLOCK?
PJRST GVFWDS## ;YES--GIVE UP NZS CORE GRACEFULLY
PUSHJ P,GETMM## ;NEED THE MM RESOURCE
JRST .-1 ;I REALLY WANT IT NOW
PUSHJ P,GVFWDS## ;RETURN FUNNY OR NZS CORE
PJRST GIVMM## ;NOW GIVE UP THE MM RESOURCE AND RETURN
> ;END IFN FTMP
SUBTTL UTILITY ROUTINES -- GETAC/PUTAC - USER AC GET/PUT ROUTINES
; GET THE CONTENTS OF THE USER'S UUO AC
; CALL: PUSHJ P,GETAC
GETAC: LDB M,PCTXUA ;GET AC
PJRST GETWDU## ;FETCH CONTENTS AND RETURN
; RETURN DATA IN THE USER'S AC
; CALL: MOVE T1, DATA
; PUSHJ P,PUTAC/PUTAC1
PUTAC1: AOS (P) ;SKIP
PUTAC: PUSH P,M ;SAVE M
MOVSI M,(CT.UUO) ;USER-MODE BIT
TDNN M,.PDCTX##(W) ;DOING THIS FOR A USER?
JRST MPOPJ## ;NO, LEAVE USER'S ACS ALONE
LDB M,PCTXUA ;POINT M AT USER'S AC
PUSHJ P,PUTWDU## ;STORE CONTENTS OF T1
JRST MPOPJ## ;RESTORE M AND RETURN
SUBTTL UTILITY ROUTINES -- WCHCTX - TYPE CONTEXT WATCH INFORMATION
WCHCTX: MOVSI T1,JW.WCX ;SEE IF WATCHING
TDNN T1,JBTWCH##(J) ;YES--WANT TO SEE THIS CRUFT?
POPJ P, ;NO
PUSHJ P,SAVE1## ;SAVE P1
MOVE P1,.PDCTC##(W) ;POINT TO CURRENT CONTEXT BLOCK
PUSHJ P,CRLF## ;START WITH A NEW LINE
MOVEI T1,[ASCIZ |[Context |]
PUSHJ P,CONMES## ;TYPE TEXT
MOVE T2,.CTCBN(P1) ;GET NAME IF ANY
PUSH P,T2 ;SAVE NAME OR ZERO
JUMPE T2,WCHCT1 ;AVOID EXTRA WORK IF NO NAME
PUSHJ P,PRNAME## ;TYPE CONTEXT NAME
MOVEI T3,"(" ;PUT THE CONTEXT
PUSHJ P,PRCHR## ; NUMBER IN PARANTHESIS
WCHCT1: LDB T1,PCTXNO ;GET CURRENT CONTEXT NUMBER
PUSHJ P,PRTDIG## ;TYPE IT
MOVEI T3,")" ;CLOSE PARANTHESIS
SKIPE (P) ; UNLESS THERE WAS NO
PUSHJ P,PRCHR## ; NAME FOR THIS CONTEXT
POP P,(P) ;TRIM STACK
SKIPE JBTNAM##(J) ;HAVE A PROGRAM NAME?
PUSHJ P,PRSPC## ;YES--SPACE OVER
SKIPE T2,JBTNAM##(J) ;GET PROGRAM NAME
PUSHJ P,PRNAME## ;TYPE IT
MOVEI T3,"]" ;FINISH
PUSHJ P,PRCHR## ; DISPLAY
PJRST CRLF## ;TYPE CRLF AND RETURN
SUBTTL UTILITY ROUTINES -- WRTTCR - WRITE A TMPCOR FILE
WRTTCR: SKIPN .CTTCR(P1) ;TMPCOR FILE AVAILABLE?
POPJ P, ;NO
MOVE T1,.CTTCE(P1) ;POINT TO FILE ALREADY IN FUNNY SPACE
PUSHJ P,TMPCTX## ;CALL TMPUUO TO LINK INTO TMPCOR CHAIN
POPJ P, ;FOR NOW
SUBTTL UTILITY ROUTINES -- SGETXT - REPORT SAVE/GET ERRORS
; ROUTINE TO TRANSLATE SAVE/GET ERROR CODES INTO MEANINGFUL TEXT
; CALL: MOVE T1, ERROR CODE
; MOVE T2, DEFAULT TEXT
; PUSHJ P,SGETXT
SGETXT: HRL T2,T1 ;PUT ERROR CODE IN LH
TLO T2,400000 ;AND LIGHT THE ERROR BIT
PUSH P,T2 ;SAVE DEFAULT ERROR TEXT
MOVSI T2,-SGELEN ;MAKE AN AOBJN POINTER
SGETX1: HLRZ T3,SGETAB(T2) ;GET AN ERROR CODE
CAIE T3,(T1) ;A MATCH?
AOBJN T2,SGETX1 ;NO
MOVE T1,SGETAB(T2) ;GET ASSOCIATED TEXT
SKIPGE T2 ;FIND A MATCH?
MOVEM T1,(P) ;YES--OVERWRITE DEFAULT
PUSHJ P,PPQCRL## ;START WITH ?<CRLF>
HRRZ T1,(P) ;GET TEXT
PUSHJ P,CONMES## ;TYPE IT
POP P,T1 ;GET ERROR CODE BACK
JUMPGE T1,SGETX2 ;JUMP IF KNOWN ERROR CODE
TLZ T1,400000 ;CLEAR ERROR BIT
HLRZS T1 ;PUT IN RH
PUSHJ P,PRTDI8## ;TYPE OCTAL NUMBER
SGETX2: MOVEI J,0 ;CLEAR JOB # TO INDICATE COMCON ERROR
PJRST PCRLF## ;TYPE A CRLF AND RETURN
SGETAB: FNFERR,,[ASCIZ |File not found|]
IPPERR,,[ASCIZ |Incorrect PPN|]
PRTERR,,[ASCIZ |Protection failure|]
TRNERR,,[ASCIZ |Transmission error|]
NSFERR,,[ASCIZ |Not a save file|]
NECERR,,[ASCIZ |Not enough core|]
DNAERR,,[ASCIZ |Device not available|]
NSDERR,,[ASCIZ |No such device|]
SNFERR,,[ASCIZ |SFD not found|]
SLEERR,,[ASCIZ |Search list empty|]
SGELEN==.-SGETAB
SUBTTL UTILITY ROUTINES -- LOKCTX/NLKCTX - SYSTEM DATA BASE INTERLOCKS
IFN FTMP,<
; GET CTXSER DATA BASE INTERLOCK
; CALLED USING THE CTXLOK MACRO
LOKCTX: SKIPGE INTRCT ;INTERLOCK AVAILABLE?
AOSE INTRCT ;TRY TO GET IT
JRST LOKCTX ;SPIN
IFN FTKL10,<APRID INTOCT> ;STORE OWNING CPU SERIAL NUMBER
POPJ P, ;RETURN
; RELEASE CTXSER DATA BASE INTERLOCK
; CALLED USING THE CTXNLK MACRO
NLKCTX: SETOM INTOCT ;CLEAR OWING CPU
SETOM INTRCT ;CLEAR INTERLOCK
POPJ P, ;RETURN
> ;END IFN FTMP
SUBTTL UTILITY ROUTINES -- RELINK - RELINK A USER'S CONTEXT BLOCKS
; THIS ROUTINE IS CALLED TO RELINK ALL CONTEXT BLOCKS OWNED BY A
; JOB INTO A SINGLE "PUSH" CHAIN.
; CALL: PUSHJ P,RELINK
; <NON-SKIP> ;NO CONTEXT BLOCKS
; <SKIP> ;ONE OR MORE BLOCKS
RELINK: SKIPN P1,.PDSAC##(W) ;POINT TO THE START OF THE CHAIN
POPJ P, ;NO CONTEXT BLOCKS??
RELIN1: SKIPN T1,.CTNXT(P1) ;SEARCH FOR THE LAST ONE
JRST RELIN2 ;FOUND IT
CAMN T1,.PDCTC##(W) ;FOUND THE CURRENT CONTEXT?
MOVE T1,.CTNXT(T1) ;YES--LOOK BEYOND
JUMPE T1,RELIN2 ;END?
MOVE P1,T1 ;SET POINTER
JRST RELIN1 ;AND LOOP
RELIN2: MOVE P2,P1 ;COPY TO A SAFE PLACE
RELIN3: SKIPN T1,.CTPRV(P1) ;GET PREVIOUS
JRST RELIN5 ;CONTEXT BLOCKS ARE ALL LINKED
CAME T1,.PDCTC##(W) ;IS THE PREVIOUS THE CURRENT ONE?
JRST RELIN4 ;NO
SKIPN T1,.CTSUP(T1) ;IGNORE CURRENT BLOCK
JRST RELIN5 ;BEGINING OF CHAIN
RELIN4: MOVEM T1,.CTSUP(P1) ;MAKE IT OUR SUPERIOR
MOVSI T2,(CT.INF!CT.DEL) ;GET THE INFERIOR PLUS DELETE FLAGS
IORM T2,.CTFLG(T1) ;REMEMBER THE SUPERIOR OWNS THIS ONE
MOVSI T2,JLOG ;GET LOGGED IN BIT
ANDCAM T2,.CTBPR+.CXSTS(T1) ;CLEAR SO CONTEXT RESTORE WON'T LOG US IN
MOVE P1,T1 ;NOW POINT TO THE PREVIOUS
JRST RELIN3 ;AND LINK THAT BLOCK
RELIN5: MOVE T1,.PDCTC##(W) ;POINT TO THE CURRENT
MOVEM T1,.CTSUP(P1) ;PUT CURRENT AT THE TOP OF THE CHAIN
SETZM .CTSUP(T1) ;FIRST BLOCK IN CHAIN HAS NO SUPERIOR
MOVSI T2,(CT.INF) ;REMEMBER THE CURRENT
IORM T2,.CTFLG(T1) ; HAS AT LEAST ONE INFERIOR
MOVEM P2,.CTNEW(T1) ;WILL BE SWITCHING TO THE LAST BLOCK IN CHAIN
MOVSI T1,(CT.DEL) ;LAST CONTEXT IN CHAIN DIDN'T GET
IORM T1,.CTFLG(P2) ; THE DELETE BIT TURNED ON YET
MOVEI T1,CT.LGO ;LITE LOGGING OUT IN PROGRESS
IORM T1,.PDCTX##(W) ;SO THINGS PROCEED SMOOTHLY
JRST CPOPJ1## ;RETURN
SUBTTL LITERAL POOL
$LIT
SUBTTL IMPURE DATA
$LOW
INTRCT: EXP -1 ;INTERLOCK REFERENCE COUNT
IFN FTKL10,<INTOCT: EXP -1> ;INTERLOCK OWNER
IFN FTXMON,<
RESMAX: EXP M.CTXR## ;RESERVED CONTEXT BLOCK MAXIMUM
RESCNT: BLOCK 1 ;RESERVED CONTEXT BLOCK COUNT
RESBLK: BLOCK 1 ;RESERVED CONTEXT BLOCK CHAIN ADDRESS
> ;END IFN FTXMON
CTXTAB::! ;CONTEXT GETTAB TABLE
JOBCCQ: EXP M.CTXC## ;(00) DEFAULT JOB CONTEXT QUOTA
JOBCPQ: EXP M.CTXP## ;(01) DEFAULT JOB SAVED PAGE QUOTA
SYSCCQ: BLOCK 1 ;(02) SYSTEM-WIDE CONTEXT QUOTA
SYSCPQ: BLOCK 1 ;(03) SYSTEM-WIDE PAGE QUOTA
SYSCCU: BLOCK 1 ;(04) SYSTEM-WIDE CONTEXTS IN USE
SYSCPU: BLOCK 1 ;(05) SYSTEM-WIDE PAGES IN USE
TOTSAV: BLOCK 1 ;(06) TOTAL NUMBER OF CONTEXT SAVES
NPQEXC: BLOCK 1 ;(07) AUTO-SAVE SAVE QUOTA EXCEEDED COUNT
NPPEXC: BLOCK 1 ;(10) AUTO-SAVE PAGE QUOTA EXCEEDED COUNT
JPQEXC: BLOCK 1 ;(11) JACCT PROGRAM SAVE QUOTA EXCEEDED COUNT
JPPEXC: BLOCK 1 ;(12) JACCT PROGRAM PAGE QUOTA EXCEEDED COUNT
DIRPTR: EXP CTXDIR## ;(13) BYTE POINTER TO CONTEXT DIRECTORY MAP
CTXMXL==:<.-CTXTAB-1>B26 ;MAXIMUM ENTRY IN GETTAB
$HIGH
CTXEND::!END