1
0
mirror of https://github.com/PDP-10/stacken.git synced 2026-02-16 20:51:02 +00:00
Files
PDP-10.stacken/files/stacken-tape-backup/dskb:10_7/mon/ctxser.mac
Lars Brinkhoff 6e18f5ebef Extract files from tape images.
Some tapes could not be extracted.
2021-01-29 10:47:33 +01:00

3387 lines
114 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
TITLE CTXSER - TOPS10 CONTEXT SERVICE - V110
SUBTTL D. MASTROVITO/DPM/JMF/NT/RCB 2-AUGUST-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,110 ;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?
CAME 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