Trailing-Edge
-
PDP-10 Archives
-
bb-jr93h-bb
-
7,6/ap021/comcon.x21
There are 3 other files named comcon.x21 in the archive. Click here to see a list.
TITLE COMCON - COMMAND DECODER AND SAVEGET ROUTINES - V1741
SUBTTL /PFC/RCC/DAL/JBS 15-NOV-88
SEARCH F,S,DEVPRM
$RELOC
$HIGH
SALL
.DIRECT FLBLST
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED
; OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION
; 1973,1974,1975,1976,1977,1978,1979,1980,1982,1984,1986,1988.
;ALL RIGHTS RESERVED.
.CPYRT<1973,1988>
XP VCOMCN,1741 ;THIS MACRO PUTS VERSION NO. IN STORAGE MAP AND GLOB
COMCON::ENTRY COMCON ;ALWAYS LOAD COMCON IF LIBRARY SEARCH
;CALLED FROM CLOCK ROUTINE WHEN 'COMCNT' IS GREATER THAN 0
;AS SET BY TTY SERVICE ROUTINE
;ALL AC'S HAVE BEEN SAVED BY CLOCK CHANNEL
;THE COMMAND DECODER CALLS TTYCOM WHICH SCANS FOR TTY WHICH TYPED
SUBTTL TABLE OF CONTENTS
; TABLE OF CONTENTS FOR COMCON
;
;
; SECTION PAGE
; 1. TABLE OF CONTENTS......................................... 1
; 2. INTRODUCTION.............................................. 3
; 3. COMMAND SETUP AND DISPATCH................................ 5
; 4. COMMAND RETURN AND CLEANUP................................ 12
; 5. COMMAND TABLE............................................. 14
; 6. CORE 0 COMMAND............................................ 20
; 7. PJOB & KJOB COMMANDS...................................... 21
; 8. START GROUP (START,CSTART,REE,DDT)........................ 23
; 9. DUMP & DCORE COMMANDS..................................... 25
; 10. CONTROL-C PROCESSING...................................... 26
; 11. SET COMMAND AND UUO
; 11.1 DISPATCH.......................................... 29
; 11.2 JBSET............................................. 30
; 11.3 PRIVILEGE TESTS................................... 31
; 11.4 CORMAX AND CORMIN................................. 35
; 11.5 DAYTIME AND SCHED................................. 40
; 11.6 OPR, LOGMIN&MAX BATMIN&MAX........................ 41
; 11.7 WATCH............................................. 42
; 11.8 DATE.............................................. 44
; 11.9 SPOOL............................................. 45
; 11.10 DEFER/NODEFER..................................... 47
; 11.11 CDR............................................... 48
; 11.12 DISK STUFF........................................ 49
; 11.13 ROUTINE TO READ DATE.............................. 51
; 11.14 ROUTINES TO PRINT WATCH INFO...................... 53
; 12. CONTINUE, CCONT AND JCONT................................. 57
; 13. CORE COMMAND.............................................. 60
; 14. CONTROL-T PRINTOUT........................................ 65
; 15. SAVE, SSAVE AND GET - COMMAND SETUP....................... 70
; 16. COMMANDS WHICH RUN PROGRAMS............................... 72
; 17. ASSIGN, DEASSIGN AND REASSIGN COMMANDS.................... 75
; 18. ATTACH AND DETACH COMMANDS................................ 92
; 19. DATASET CONNECT & SYSTEM START............................ 99
; 20. DAYTIME COMMAND........................................... 100
; 21. RUNTIME ROUTINE (TIME COMMAND)............................ 101
; 22. SEND COMMAND.............................................. 102
; 23. VERSION COMMAND & PRVERS SUBROUTINE....................... 107
; 24. EXAMINE AND DEPOSIT COMMAND............................... 109
;CONTINUED ON NEXT PAGE
; 25. TTY COMMAND AND SET TTY COMMAND........................... 113
; 26. FINISH AND CLOSE COMMANDS................................. 123
; 27. SUBROUTINES
; 27.1 COMMAND SETUP..................................... 126
; 27.2 GET A WORD........................................ 127
; 27.3 GET CHARACTER..................................... 129
; 27.4 TYPE OUT ROUTINES................................. 130
; 28. SAVGET
; 28.1 PARAMETERS........................................ 143
; 28.2 COMMAND SCAN...................................... 144
; 28.3 RUN AND GETSEG UUO'S.............................. 147
; 28.4 SAVE A JOB........................................ 148
; 28.5 "EXE" SAVE FILES.................................. 151
; 28.6 GET AND RUN COMMANDS.............................. 177
; 28.7 RUN UUO........................................... 179
; 28.8 GETSEG UUO........................................ 182
; 28.9 COMMON CODE....................................... 183
; 28.10 GET FILE FROM DEVICE (R,RUN,GET,GETSEG)........... 186
; 28.11 IO ROUTINES....................................... 192
; 28.12 EXPAND COMPRESSED FILES........................... 195
; 28.13 SUBROUTINES....................................... 201
SUBTTL INTRODUCTION
;THE COMMAND AND THEN DISPATCHES(PUSHJ) TO APPROPRIATE
;COMMAND SETUP ROUTINE WITH AC'S SET AS:
;J = JOB NUMBER
;F = ADDRESS OF DEVICE DATA BLOCK TYPING COMMAND, IF ANY
;R = ADDRESS OF JOB'S CORE AREA, = 0 IF NO CORE
;S IS SET TO 0, USED FOR ADDRESS OF SUBSEQUENT CALLS
;U = ADDRESS OF LINE DATA BLOCK OF TTY TYPING COMMAND
;W = ADDRESS OF JOB'S PDB
;P4 = JOB STATUS WORD (C(JBTSTS(J)))
;P1 = 0 (USED FOR SAVGET FLAGS)
;P2 = COMMAND NAME (2ND NAME IF SET)
;THE PUSHDOWN LIST CONTAINS:
;LH(M) = 1B0=1B1= 1 (FLAG FOR COMMAND AT COMMAND LEVEL)
; = 1B8-17= COMMAND TABLE ENTRY
;-1 (P) = U = ADDRESS OF LDB
;THE FOLLOWING GLOBAL USAGE PREVAILS:
;T3 LAST INPUT CHARACTER
; ALSO TYPE OUT CHARACTER
;IN GENERAL, T1 - T4 AND P2 - 4 ARE SCRATCH
;AT COMMAND RETURN, IF J = 0 AND A
; JOB WAS REQUIRED, AN ERROR IS ASSUMED.
; ALL OTHER ACS CAN HAVE BEEN CHANGED
;UPON RETURN FROM COMMAND SETUP ROUTINE, A CR-LF IS ADDED TO
;MESSAGE AND TTY IS STARTED ON TTY SPECIFIED BY -1(P)
;SEVERAL COMMAND FLAGS ARE CHECKED BEFORE DISPATCHING TO
;COMMAND SETUP ROUTINES TO SEE IF COMMAND IS LEGAL AT THIS TIME
;SEVERAL MORE FLAGS ARE CHECKED UPON RETURN FROM COMMAND SETUP
;ROUTINES(UNLESS AN ERROR HAS OCCURRED) FOR STANDARD
;COMMAND RESPONSE
;IF AN ERROR OCCURS, THE JOB NO.(J) SHOULD BE 0 ON RETURN
;SO THAT JOB WILL NOT BE INITIALIZED IF FIRST COMMAND.
;ERRMES ROUTINE WILL SET J TO 0
;SINCE THE COMMAND DECODER IS CALLED FROM THE CLOCK ROUTINE
;COMMAND SETUP ROUTINE MUST RUN TO COMPLETION QUICKLY
;IF A COMMAND FUNCTION CANNOT DO THIS, IT MUST JUST SET
;THE JOB TO RUNABLE STATUS AND RETURN IMMEDIATELY
;OR DELAY THE COMMAND FOR LATER EXECUTION
;THE FOLLOWING AC USAGE PREVAILS FOR TTY IN/OUT:
;
;INPUT: U=LDB, T3=CHARACTER CLOBBERS T1
;
; CTEXT CLOBBERS W, RETURNS T2=NAME
; SKIPS RETURNS T2=0
; DEC/OCT IN CLOBBERS P4, RETURNS T2=NUMBER
; PJPGNO CLOBBERS T2,P4, RETURNS P2=USER
;
;
;OUTPUT:U=LDB, T3=CHARACTER CLOBBERS T1,S
;
; CONMES POINTER IN T1
; OCTPNT/PRTDI8/RADX10 NUMBER IN T1
; (PRTDI8 CLOBBERS T2)
; PRNAME NAME IN T2
;P1 ASSIGNMENTS:
;
;PHONLY==1B0 ;PHYSICAL ONLY
;INCREMENT==777777 ;STARTING ADDRESS OFFSET
SUBTTL COMMAND SETUP AND DISPATCH
COMMAN::SE1ENT ;ENTER SECTION 1
PUSHJ P,TTYCOM## ;SETUP F,U,J, AND W
; FOR ANY TTY WHICH HAS TYPED A COMMAND
JRST [AOS CMNOTF## ;NONE FOUND, COUNT THE BUG
SOS COMCNT## ;ADJUST COUNT
POPJ P,] ;RETURN
IFN FTMP,<MOVEM J,COMJOB##> ;TO AVOID JOBSTS UUO RACE
PUSHJ P,SVEUB## ;SAVE EBR AND UBR AND SETUP UBR FOR
; THE JOB THE COMMAND IS BEING EXECUTED FOR
PUSH P,U ;SAVE TTY LINE DATA BLOCK ADDRESS
LDB T1,LDPCMX## ;GET FORCED COMMAND INDEX, IF ANY
MOVEM T1,.CPLFC## ;SAVE IT FOR COMPARISON
MOVSI T2,LDBCMF## ;IS COMMAND FORCED?
TDNN T2,LDBCOM##(U) ; ..
JRST COM1 ;NO, TRY USER COMMANDS
MOVE T2,TTFCOM##(T1) ;YES. GET SIXBIT NAME OF COMMAND
JRST COM1S ;GO FIND IT
COM1: PUSHJ P,CTEXT ;SCAN COMMAND NAME, RETURN IT IN T2
COM1Z: CAIE T3,"C"-100 ;BREAK ON CONTROL-C?
JRST COM10 ;NO, TRY LOGICAL NAMES
MOVE T2,HALTXT## ;YES--TURN COMMAND INTO HALT
MOVEI T1,HALTXT##-COMTAB## ;CALCULATE OFFSET IMMEDIATELY
MOVE P3,[XWD UNQTAB##,DISP##] ;SET P3=UNIQNESS BITS, DISPATCH TABLE
MOVE P4,[XWD -DISPL##,COMTAB##] ;SET P4=-LENGTH,TABLE LOC
JRST COM1E ;GO JOIN COMMON CODE
COM10: CAMN P4,[XWD -DISPL2##,COMTB2##] ;IN THE MIDDLE OF A SET COMMAND?
JRST COM1A ;YES, DON'T SEARCH LOGICAL NAMES
JUMPE T2,COM1S ;BLANK COMMAND CANNOT BE REDEFINED
JUMPE W,COM1S ;NO USER DEFINED COMMANDS IF NO PDB
SKIPN .PDCMN##(W) ;ANY USER DEFINED COMMANDS TO SEARCH THROUGH?
JRST COM1S ;THEN USE SYSTEM TABLES
MOVE T3,JBTSTS##(J) ;NEED TO SEARCH PATHOLOGICAL NAMES
TLNN T3,SWP!SHF ;IS JOB ON DISK OR ON ITS WAY?
JRST COM11 ;NO, PROCEED
HRRI M,DLYCM ;YES, SET TO SWAP JOB IN
PUSH P,(P) ;KEEP THE STACK RIGHT
JRST COMDIS ;WAIT FOR IT TO COME IN
COM11: CAMN T2,[SIXBIT \R\] ;USER TYPED R COMMAND?
JRST COM1S ;YES, THIS CAN'T BE REDEFINED
MOVE P4,.PDCMN##(W) ;GET AOBJN POINTER TO COMMAND NAMES
MOVE P3,.PDUNQ##(W) ;GET POINTER TO UNIQNESS BITS
MOVSI T1,1 ;FLAG INDICATING THIS IS USER-COMMAND SEARCH
PUSHJ P,FNDABV ;SEE IF WE CAN FIND A MATCH
JRST COM1S ;NO, DEFAULT TO MONITOR'S COMMANDS
;HERE WE SEARCH MONITOR TABLE TO MAKE SURE NO UNIQUENESS CONFLICTS RESULT.
TRNE T3,CEXACT!CUNIQ ;DID WE MATCH EXACTLY OR UNIQUELY?
JRST COM11C ;YES, DON'T BOTHER WITH MONITOR COMMANDS
PUSH P,T1 ;SAVE THE FLAGS,,DISPATCH
PUSHJ P,FNDCOM ;GO FIND THE COMMAND IN TABLES
JRST COM11A ;ERROR, TAKE USER'S COMMAND
POP P,(P) ;ADJUST THE STACK
JRST COM1B ;GO JOIN COMMON CODE
;HERE FOR USER COMMAND
COM11A: POP P,T1 ;RESTORE THE DISPATCH AND FLAGS
TRNE T3,CAMBIG ;WAS THE COMMAND AMBIGUOUS?
JRST COM1A0 ;YES, IT STILL IS
COM11C: HLRZ T3,T1 ;SAVE BITS
ADD T1,.PDUNQ##(W) ;POINT TO DISPATCH FOR THIS COMMAND
HRRZS T1 ;CLEAR SECTION CRUD
HRL P3,(T1) ;AND SAVE THE DISPATCH IN LH P3
HRRI P3,DISP## ;FOR LATER USE
MOVEI T1,PLNTXT##-COMTAB## ;SET UP FOR PATHOLOGICAL RUN COMMAND
MOVE P4,[XWD -DISPL##,COMTAB##] ;POINT BACK TO MAIN TABLES
MOVE P2,PLNTXT## ;GET SIXBIT COMMAND NAME
JRST COM1E ;GO JOIN COMMON CODE
;HERE TO SEARCH MAIN COMMAND TABLES
; WITH T2/ COMMAND
COM1S: PUSHJ P,FNDCOM ;FIND THE COMMAND IN THE TABLES
JRST COM1A0 ;NOT FOUND, SEE IF ON FRCLIN
JRST COM1B ;GO IF NO ERROR
;ENTRY POINT FOR "SET" COMMAND
COM1A: SETZ T1, ;NO FLAGS FOR FULL WORD LDB POINTER
PUSHJ P,FNDABV ;LOOK IT UP
TRNA ;ERROR
JRST COM1B ;GO IF NO ERROR
COM1A0: MOVE P2,LINTAB##+FRCLIN## ;GET LDB ADDRESS OF FRCLIN
CAME P2,U ;UNKNOWN COMMAND TYPED ON FRCLIN?
JRST NOSUCH ;USER MISTYPED
MOVEI T1,.RNTXT##-COMTAB## ;GET OFFSET OF .RUN COMMAND
MOVE P2,T2 ;GET SIXBIT PROG NAME
COM1E: HRL M,UNQTAB##(T1) ;GET PREDISPATCH BITS
HRR M,DISP##(T1) ;AND GET THE DISPATCH ADDRESS
MOVE T2,UNQTAB##(T1) ;GET THE UNIQUENESS BITS
CAME P2,PLNTXT## ;USER-DEFINED COMMAND?
JRST COM1C ;NO, JOIN COMMON CODE
TRZE T3,CM.SAC## ;AUTO-PUSH FLAG LIT?
TLO T2,SACFLG ;YES, PROPAGATE
JRST COM1C ;AND RE-JOIN COMMON CODE
COM1B: CAIL T1,COMPIL##-COMTAB## ;COMPIL-CLASS COMMAND
CAILE T1,LASCCL##-COMTAB##
TRNA ;NO
MOVEI T1,COMPIL##-COMTAB## ;FUDGE DISPATCH OFFSET FOR COMPIL
MOVE P2,T1 ;CALCULATE THE OFFSET
ADDI P2,(P4) ; INTO THE COMMAND TABLE
MOVE P2,(P2) ;AND GET THE SIXBIT PROG NAME OR COMMAND
HRRZ M,P3 ;GET DISPATCH
ADDI M,(T1)
HRR M,(M)
HLRZ T2,P3 ;NOW POINT TO UNIQUENESS TABLE
ADDI T2,(T1) ;POINT TO THE COMMAND ENTRY
HRL M,(T2) ;GET THE BITS
MOVE T2,(T2) ;GET THE DISPATCH BITS
COM1C: EXCH T2,(P) ;SAVE TABLE OFFSET ON THE STACK
PUSH P,T2 ; BUT KEEP U ON TOP
ADDI P3,(T1) ;POINT P3 TO DISPATCH ENTRY
SKIPGE T1 ;SEE IF ERROR
MOVEI P3,COMERD## ;YES--SET DISPATCH
HRRZ P4,P3 ;CLEAR LEFT HALF JUNK
HRR M,(P4) ;GET DISPATCH TABLE ENTRY
MOVE P4,JBTSTS##(J) ;JOB STATUS WORD FOR THIS JOB
;THE FOLLOWING CODE IS THE LAST NOSTALGIC VESTIGE OF FT2741
TLNE P4,JLOG ; WHILE NOT LOGGED IN?
JRST NT2741 ;NO--LEAVE ALONE
JUMPGE T1,NT2741 ;JUMP IF NOT COMMAND ERROR
CAMN T2,[SIXBIT .YQAOS.] ;DID HE TYPE LOGIN WITH WRONG BALL?
HRRI M,SET987 ;YES--SET TTY ELEMENT 987
CAMN T2,[SIXBIT .VI.] ;MAYBE THE LEFT ONE?
HRRI M,SET988 ;YES--SET TTY ELEMENT 988
SET987==CPOPJ1##
SET988==CPOPJ1##
NT2741: TRNE P4,JS.DEP ;IS JOB BEING STOPPED ON ERROR SO DAEMON CAN LOG?
JRST CHKDLY ;YES, DELAY COMMAND UNTIL DAEMON IS FINISHED LOGGING
TLNE P4,JLOG ;IS JOB LOGGED IN?
JRST CHKNO ;YES, PROCEED
TLNN M,NOLOGIN ;NO, CAN COMMAND PROCEED WITH NO LOGIN?
JRST LOGPLE ;NO, TYPE "LOGIN PLEASE"
SKIPE [M.RCMP##] ;MAYBE. ARE WE BEING PERMISSIVE?
TLNE M,NORCMP ;OR IS THIS COMMAND ALLOWED ANYWAY?
JRST CHKNO ;YES, PROCEED
MOVEI T1,LDRRMT## ;REMOTE BIT
TDNN T1,LDBDCH##(U) ;SEE IF DONE ON A LOCAL TERMINAL
JRST CHKNO ;YES, IT'S LEGAL
LOGPLE: JSP T1,COMER ;NO, TYPE "LOGIN PLEASE"
LOGPLM::ASCIZ /LOGIN please
/
CHKNO: SETZB P1,R ;CLEAR PHYSICAL I/O FLAG, AND CORE LOCATION
JUMPN J,CHKRUN ;JOB NUMBER ALREADY ASSIGNED?
TLNE M,NOJOBN ;NO, DOES THIS COMMAND NEED A JOB NUMBER?
JRST COMGO ;NO
MOVEI J,1 ;YES, SCAN FOR ONE STARTING WITH 1
NUMLOP: HLLZ P4,JBTST2##(J) ;FOR JS.SIP
HLR P4,JBTSTS##(J) ;FOR OTHER BITS
TDNN P4,[JS.SIP+JNA+JRQ+CMWB] ;OR ONE OF THESE?
IFN FTMP,<
PUSHJ P,ANYRUN## ;RUNNABLE ANYWHERE?
JRST NUMLO1 ;YES, JOB ISN'T REALLY AVAILABLE
MOVE P4,JBTSTS(J) ;KEEP REST OF CODE HAPPY
>
IFE FTMP,<
SKIPA P4,JBTSTS(J) ;KEEP OTHER CODE HAPPY
JRST NUMLO1 ;JOB ISN'T AVAILABLE
>
JRST NEWJOB
NUMLO1: CAIGE J,JOBMAX## ;YES, IS THE MAX. JOB NO.?
AOJA J,NUMLOP ;NO, KEEP LOOKING
SKIPG ARFLAG## ;SYSTEM STARTING UP?
JRST CHKDLY ;YES--DELAY IT
IFN FTNET,<
MOVSI T1,LDBCMF## ;WAS THIS COMMAND FORCED?
TDNN T1,LDBCOM##(U)
JRST NEWJER ;NO, OKAY TO COMPLAIN
SKIPGE LDBTTW##(U) ;IF ANF THEN PROBABLY .HELLO/.NETLD
JRST CHKDLY ;SO DELAY IT
>
NEWJER: JSP T1,COMER ;YES, NONE LEFT, PRINT "JOB CAPACITY EXCEEDED"
ASCIZ /Job capacity exceeded
/
NEWJED: JSP T1,COMER ;PRINT "NO FREE DDBs"
ASCIZ /Job capacity exceeded (No free TTY DDBs)
/
NEWJEP: JSP T1,COMER ;Not enough core
ASCIZ /Job capacity exceeded (No core for a PDB)
/
;EVEN THOUGH THIS IS A NEW JOB NUMBER
;IT MAY HAVE CORE ASSIGNED NOW BECAUSE IT WAS DELAYED
;UNTIL IT COULD BE SWAPPED IN(LOGIN WITH CORE FULL)
NEWJOB: SKIPE F,TTYTAB##(J) ;ANY TTY DDB?
PUSHJ P,TTYKIL## ;YES--KILL IT OFF
SETZB F,TTYTAB##(J) ;KEEP TTYATI HAPPY
MOVE U,(P) ;RESTORE U
PUSHJ P,TTYATI## ;TRY TO ATTACH TTY TO THIS JOB NUMBER
JRST NEWJED ;IF CAN'T, NO DDB'S. SAY NO FREE DDBs
PUSHJ P,CREPDB## ;CREATE A PDB FOR THIS JOB
JRST [PUSHJ P,TTYKIL## ;KILL TTY DDB OBTAINED ABOVE
JRST NEWJEP] ;CAN'T GET A PDB, SAY SO
SETZM JBTPRG##(J)
PUSHJ P,CLRJBT## ;GO CLEAR ALL THE JOB TABLES AND PDB
PUSHJ P,ASICPT## ;ASSIGN INITIAL IN CORE PROTECT
MOVE T2,DATE##
MOVEM T2,JBTJLT##(J)
IFN FTMDA,<
MOVEM T2,.PDSTM##(W) ;INITIAL SETTING OF LAST RESET
> ;IFN FTMDA
SKIPE JBTADR##(J) ;CONTACT BOUNCE ON DLYCM?
PUSHJ P,MKADD## ;YES, MAKE SURE JOB IS ADDRESSABLE
IFN FTMP,<
MOVEM J,COMJOB## ;FOR PTYSER
>
PUSHJ P,CTLJBU## ;GET PTY DDB IF THERE IS ONE
JUMPL T1,NEWJB1 ;JUMP IF NOT PTY CONTROLLED
MOVSI T1,DVDIBP ;GET BATCH PTY BIT
MOVSI T2,(JB.LBT) ;GET A BATCH JOB BIT
TDNE T1,DEVCHR(F) ;IS IT A BATCH PTY ?
IORM T2,JBTLIM##(J) ;YES, THEN ITS A BATCH JOB
NEWJB1: HRRZ F,LDBDDB##(U) ;RESTORE TTY DDB
MOVEI T1,BPTBIT## ;GET INITIAL VALUE OF JS.BPT
DPB T1,BPTPTR ;SET IT
MOVE T1,TIME## ;INITIALIZE TO TIME OF DAY
TLO T1,M.WCH## ;OR IN INITIAL SET WATCH BITS
; (IN CASE THIS JOB GETS AUTOMATIC LOGIN)
MOVEM T1,JBTWCH##(J) ;STORE FOR THIS JOB
CAMLE J,HIGHJB## ;HIGHEST JOB NUMBER ASSIGNED?
MOVEM J,HIGHJB## ;YES,SAVE IT FOR SCHEDULER SCAN OF JOBS
IFN FTNET,<
PUSHJ P,FNDSTA## ;WHERE IS HE?
DPB T1,PDVSTA## ;THAT IS WHERE HIS TTY IS NOW
HRRZM T1,JBTLOC##(J) ;AND LOCATE HIM THERE
>
CHKRUN:
IFN FTMP,<
TLNE M,NORUN ;CAN COMMAND BE EXECUTED WHILE RUNNING?
TLNE P4,RUN ;YES, IS IT
JRST CHKRU1 ;YES
PUSHJ P,ANYRUN## ;RUN BIT COULD BE OFF BUT THE JOB
JRST CHKDLY ; COULD STILL BE THE CURRENT JOB ON ANOTHER CPU
>
CHKRU1: TLNE P4,RUN ;RUN BIT ON IN JOB STATUS?
TLNN M,NORUN ;YES, DOES THIS COMMAND REQUIRE A JOB?
JRST CHKBAT ;NO
JSP T1,COMER ;YES.
RUNERR::ASCIZ /Please type ^C first
/
CHKBAT: MOVE T1,JBTLIM##(J) ;GET BATCH BIT
TLNE T1,(JB.LBT) ;SEE IF BATCH JOB
TLNN M,NBATCH ;YES--SEE IF ILLEGAL COMMAND
JRST CHKXO ;NO--OK TO PROCEED
JSP T1,COMER ;YES--BOMB USER
BATMSG: ASCIZ /Illegal in batch job
/
CHKXO: TRNE P4,JS.XO!JS.RUU ;SEE IF EXECUTE ONLY JOB
TLNN M,NXONLY ;YES--SEE IF ILLEGAL COMMAND
JRST CHKACT ;NO--OK TO PROCEED
JSP T1,COMER ;YES--BOMB USER
ILLXOM: ASCIZ /Illegal when execute only
/
CHKACT: MOVE R,JBTADR##(J) ;XWD PROTECTION,RELOCATION
TLNE M,INCORE ;MUST JOB NOT BE SWAPPING OR
; IF JOB HAS CORE ASSIGNED, MUST IT BE
; IN PHYSICAL CORE (RATHER THAN DISK OR ON ITS WAY)
TLNN P4,SWP!SHF ;YES, IS JOB ON DISK OR ON ITS WAY?
JRST CHKCO2 ;NO
HRRI M,DLYCM ;ASSUME JOB MUST BE IN PHY CORE
; SO SET TO SWAP JOB IN
JRST COMDIS ;WAIT FOR JOB
CHKDLY: HRRI M,DLYCM1 ;NO, JUST DELAY COMMAND UNTIL SWAP OUT OR IN IS FINISHED
JRST COMDIS ;AND DISPATCH TO DELAY COMMAND
CHKCO2: TLNE M,NOACT ;CAN COMMAND BE PERFORMED WITH ACTIVE DEVICES?
PUSHJ P,RUNCHK ;NO, RETURN IF JOB STOPPED AND NO ACTIVE DEVICES
TLNE M,NOCORE ;DOES THIS COMMAND NEED CORE?
JRST COMGO ;NO. GO DISPATCH
JUMPN R,CHKXPN ;YES, IS CORE IN MEMORY?
JSP T1,COMER ;NO, PRINT "NO CORE ASSIGNED"
ASCIZ /No core assigned
/
CHKXPN: TLNN M,INCORE ;DOES THIS COMMAND NEED CORE TO BE EXPANDED?
JRST COMGO ;NO
HLRE S,USRHCU## ;YES, IS CORE STILL COMPRESSED(SAVE DID NOT GO
; TO COMPLETION)
JUMPGE S,COMGO ;LH=-2 DURING SAVE, WHEN CORE COMPRESSED
;LH=-1 DURING SAVE OF HIGH SEG, OR GET OF LOW
; OR HIGH SEG
CAME P2,FCOTXT## ;IS THIS A FORCED CONTINUE?
CAMN P2,CONTXT## ; OR CONTINUE COMMAND?
JRST COMGO ;YES, DON'T EXPAND (LET SAVE FINISH)
PUSHJ P,CLRASA ;CLEAR EXEC MODE UUO FLAG
AOJGE S,COMGO ;JUMP IF DON'T NEED TO EXPAND
S0PSHJ EXPAND ;NO, EXPAND CORE FIRST
JFCL ;IGNORE ADDRESS CHECK ERROR, WE TRIED
MOVSI T1,JERR ;SET JERR SO CONT WON'T WIN
IORM T1,JBTSTS##(J) ; (WOULD GET ADR CHK IF ATTEMPTED)
JRST CHKDLY ;DELAY COMMAND BECAUSE COMMAND DECODER ACS ARE
; ALL GONE, NEXT TIME JOBHCU WILL BE 0
NOSUCH: PUSH P,(P) ;SO COMDIS DOESN'T SCREW UP THE STACK
SKIPA M,[NOCOM] ;GET THE ERROR ROUTINE
COMER:: HRRI M,ERRMES ;CALL ERROR MESSAGE ROUTINE
HRLI M,NOINCK!CMDERR ;SET APPROOPRIATE BITS
COMGO: TLNN P4,CMWB ; WAS JOB IN COMM WAIT
TLZ M,CMWRQ ;NO, CLEAR REQUEUE BIT IN DISP. FLAGS
MOVSI S,CMWB ;CLEAR CMWB
ANDCAM S,JBTSTS##(J)
TLNE P4,CMWB ;IF NOT IN COMMAND WAIT,
SKIPN .PDCMN##(W) ;OR NO USER-DEFINED COMMANDS,
JRST COMDIS ;THEN DON'T NEED THIS
MOVSI T2,LDBCMF## ;COMMAND FORCED BIT
TDNN T2,LDBCOM##(U) ;SEE IF ON
TLO M,CMWRQ ;NO, DEMAND A REQUEUE TO FIX UP AFTER DLYCOM
COMDIS: POP P,T2 ;GET BACK THE OFFSET FROM THE STACK
EXCH T2,(P) ;KEEPING U THERE
TLNE M,CMDERR ;COMING IN FROM AN ERROR?
JRST COMDS1 ;YES, JUST DISPATCH
TLNN M,CMWRQ ;CMWRQ ON IN PREDISPATCH? (SEE COMGO)
TLZA T2,CMWRQ ;NO, CLEAR IT IN POST DISPATCH FLAGS
TLO T2,CMWRQ ;YES, SET IT IN POST DISPATCH FLAGS
HLL M,T2 ;NO, GET THE REAL FLAGS
COMDS1: MOVEI S,0 ;CLEAR S FOR SETTING DISPATCH ADDRESSES
TLO M,FLMCOM!FLMCLV ;SET COMMAND AT COMMAND LEVEL FLAGS
MOVEM P,.CPISF## ;SAVE PDL FOR DLYCOM & ABORTC
S0PSHJ <(M)> ;DISPATCH TO COMMAND IN SECTION 0
JFCL ;IGNORE ERROR RETURN
SUBTTL COMMAND RETURN AND CLEANUP
;RETURN FROM COMMAND SETUP ROUTINE
COMRET: NTDBUG NO,EITHER ;STOP IF NETWORK INTERLOCK NOT RELEASED
MOVE T1,.CPLFC## ;GET FORCED COMMAND INDEX BACK
POP P,U ;RESTORE TTY LDB ADDRESS
HRRZ F,LDBDDB##(U) ;RESTORE TTY DDB IF ANY
PUSHJ P,TTYCMR## ;TELL SCNSER COMMAND IS COMPLETED
SOS COMCNT##
AOS COMTOT## ;KEEP COUNT OF TOTAL COMMANDS PROCESSED
; (DO NOT COUNT DELAYED COMMANDS UNTIL PROCESSED)
MOVSI T1,1 ;ALSO KEEP COUNT OF COMMANDS PROCESSED
ADDM T1,LDBBCT##(U) ;ON A PER-TERMINAL BASIS FOR ACCOUNT PURPOSES
TLNN M,ERRFLG ;ERROR?
JRST COMRT1 ;NO, PROCEED
SETZM J ;YES, CLEAR J
TLZ M,NOFLM!NOCRLF!NOPER!TTYRNU!TTYRNC!TTYRNW!NOMESS ;ERROR--CLEAR PROBLEM BITS
TLO M,NOINCK+CMWRQ ;YES, JOB NUMBER REQUIRED, BUT NONE IN J.
; PRINT ERROR MESSAGE ONLY, AND
; REQUEUE JOB IF NECESSARY.
COMRT1: MOVSI P4,JNA ;JOB STATUS WORD
TLNN M,NOINCK ;SUPPRESS JOB INIT. CHECK?
TDOE P4,JBTSTS##(J) ;NO, IS JOB INIT BIT ALREADY SET?
JRST PCRLFA ;YES.
MOVSI P4,JNA ;GET JNA BIT AGAIN
IORB P4,JBTSTS##(J) ;NO, SO SET IT THIS COMMAND
PUSHJ P,TTYATI## ;ATTACH TTY TO JOB
JFCL ;IGNORE IF CAN NOT(SHOULD NEVER HAPPEN)
PCRLFA: MOVEI T1,JDCON ;CLEAR JDCON SO THAT A RUNNING JOB
TLNE M,TTYRNU!TTYRNC!TTYRNW ;WILL NOT BE THE "JCONT INVABLE" FROM
ANDCAM T1,JBTSTS##(J) ;ANOTHER TTY
TLNE M,NOMESS ;SEE IF MESSAGE SUPPRESSED
JRST PCRLF0 ;YES--SKIP WATCH
TLNE M,TTYRNU!TTYRNC!TTYRNW ;COMMAND START JOB UP (TTY IN EITHER MODE)?
S0PSHJ WCHBEG ;YES, PRINT [HH:MM:SS] STARTED TO WAIT FOR RESPONSE
PCRLF0: TLNN M,NOFLM!NOCRLF ;SUPRESS CRLF?
PUSHJ P,CRLF ;NO
TLNE M,NOPER ;SUPRESS PRINTING PERIOD?
JRST PCRLF2 ;YES
PUSHJ P,PRDOTM ;NO, GIVE A "."
PUSHJ P,CLRPCT## ;RESET STOP COUNTER
PUSHJ P,STRTDL## ;ALLOW A DEFERRED LINE TO ECHO IF NEEDED
PCRLF2: JUMPE J,PCRLF1 ;JOB DOES NOT RUN IF ERROR OR NO JOB NO. ASSIGNED
TLNE M,TTYRNU ;JOB TO RUN WHEN TTY FINISHED TYPING?
; COMMAND RESPONSE (TTY TO USER MODE)?
PUSHJ P,TTYUSR## ;YES, CALL SCANNER AND SCHEDULER ROUTINES
TLNE M,TTYRNW ;COMMAND RESTART TTY RESPECTING IO WAIT?
PUSHJ P,TTYUSW## ;YES. CALL SCANNER ROUTINE AND SCHEDULER
TLNE M,TTYRNC ;NO, JOB TO RUN AND REMAIN IN MONITOR MODE?
PUSHJ P,SETRUN## ;YES, CALL SCHEDULER ROUTINE
PCRLF1: TLNN M,NOMESS ;IS THERE A MESSAGE?
PUSHJ P,TTYSTR## ;YES, START TTY TYPING IT OUT
TLNE M,ERRFLG ;WAS AN ERROR?
PUSHJ P,TSETBI## ;YES--CLEAR TYPE-AHEAD
JUMPE F,PCRLF5 ;DON'T KILL NON-EXISTENT DDBS
TLNN M,NOJOBN ;WAS NO JOB NUMBER NEEDED?
TLNE M,ERRFLG ;OR DID AN ERROR OCCUR?
CAIA
JRST PCRLF5
MOVSI T1,JNA ;GET JNA
LDB T2,PJOBN## ;AND JOB NUMBER
SKIPE T2 ;HAVE A JOB?
TDNE T1,JBTSTS##(T2) ;AND IS JOB NUMBER ASSIGNED?
JRST PCRLF4 ;KILL OFF TTY IF IDLE
MOVEI J,(T2) ;COPY JOB NUMBER
SETZM TTYTAB##(J) ;ZAP TTY DDB POINTER
PUSHJ P,TTYKIL## ;RETURN TTY DDB TO FREE POOL
PUSHJ P,KILPDB## ;GIVE BACK PDB CORE
TDZA J,J ;DON'T CONFUSE THINGS
PCRLF4: PUSHJ P,TTYKLQ## ;KILL OFF TTY IF IDLE
PCRLF5: PUSHJ P,DECHJB## ;DECREMENT HIGHJB IF APPROPRIATE
IFN FTMP,<
SETOM COMJOB## ;NO JOB IN COMCON NOW
>
JUMPE F,CPOPJ## ;IF NO JOB, QUIT
MOVSI T1,LDBDET## ;SHOULD LINE BE DETACHED?
TDNN T1,LDBCOM##(U) ;DELAYED BECAUSE OF CMW
JRST PCRLF3
ANDCAM T1,LDBCOM##(U)
PUSHJ P,PTYDET## ;YES, DO IT NOW
PCRLF3: LDB J,PJOBN## ;GET ATTACHED JOB # FROM TTY DDB
JUMPE J,CPOPJ##
CAME J,.CPJOB## ;NEVER SET JRQ FOR CURRENT JOB!
TLNN M,CMWRQ ;REQUEUE JOB AFTER COMMAND WAIT OR ERROR?
POPJ P,
JRST REQUE## ;YES
SUBTTL CORE 0 COMMAND
COR0: JUMPE R,CPOPJ## ;RETURN IF JOB DOES NOT HAVE CORE
IFN FTFDAE,<
PUSHJ P,CHKXTM ;SEE IF AN "EXIT" MESSAGE SHOULD
; BE SENT TO THE FILE DAEMON AND IF
; SO, SEND IT.
>
JSP T2,MONJOB## ;SET TO RUN MONITOR JOB(PC IN EXEC MODE)
; RETURN HERE AT UUO LEVEL(NO ACS SET UP)
MOVEI T2,ESTOP## ;PUT ERROR STOP ON END OF PDL
JSP T1,MONSTR## ;START MONITOR JOB BY SETTING UP ACS AND
JOB1:: MOVSI T1,JERR ;TURN OFF JERR
ANDCAM T1,JBTSTS##(J) ;..
PUSHJ P,RESET## ;RELEASE ALL IO DEVICES ASSIGNED TO THIS JOB
IFN FTFDAE,<
PUSHJ P,CALLF ;NEED TO CALL FILDAE FOR THIS JOB?
PUSHJ P,SNDFXM ;YES, SEND FILDAE AN EXIT MESSAGE
>
JOB1A:: MOVSI T1,JERR ;TURN OFF JERR
ANDCAM T1,JBTSTS##(J) ;..
PUSHJ P,TTYFNU## ;FIND TTY FOR THIS JOB(SETUP J WITH JOB NO.)
IFN FTMP,<
PUSHJ P,UPMM## ;MUST HAVE THE MM RESOURCE
JRST ZAPPG1 ;ZAP THE PROGRAM (UUO LEVEL STYLE)
>
ZAPPGM::
IFN FTMP,<
PUSHJ P,GETMM## ;GET MEMORY MANAGEMENT RESOURCE
JRST .-1 ;MUST WAIT IF NOT AVAILABLE
>
ZAPPG1: PUSHJ P,KILHGA## ;HIGH SEG FOR THIS USER, RETURN CORE
; REMOVE HIGH SEG FROM THIS USER
; LOGICAL ADDRESSING SPACE
; IF NO OTHER USERS IN CORE ARE USING IT
; RETURN DISK SPACE IF NO LONGER SHARABLE HIGH SEG
PUSHJ P,INTLVL## ;AT CLOCK LEVEL?
PUSHJ P,DSKFLS## ;NO, UUO, CLOBBER ANY POSSIBLE DISK PAGES
PUSHJ P,NOCORQ## ;PUT JOB IN NO CORE Q
PUSHJ P,CLRTAB ;CLEAR BITS AND TABLE ENTRIES
MOVSI T1,(PD.LGO) ;IF A LOGOUT UUO IS IN PROGRESS,
TDNE T1,.PDDFL##(W) ; ..
JRST JOB2 ; ALWAYS DELETE ALL CORE
MOVSI T1,JLOG ;IF NOT LOGGED IN
SKIPN .CPISF## ; OR COMING FROM ERRCON
TDNN T1,JBTSTS##(J)
JRST JOB2 ;ALWAYS DELETE FUNNY PAGES
LDB T1,NFYPGS## ;ANY MONITOR FREE CORE PAGES?
CAIN T1,UPMPSZ##+1
JRST JOB2 ;NO, RETURN CORE
MOVE T1,[.JDAT,,.JDAT+1] ;ZERO JOB DATA AREA
SETZM .JDAT ;JOBSA, JOBDDT, ETC.
SETZM USRDDT## ;AND REMEMBERED COPY
BLT T1,.JDAT+PG.BDY ; AND THE REST OF PAGE 0 IN CASE XO
IFE FTMP,<
POPJ P, ;YES, JUST RETURN
>
IFN FTMP,<
PJRST GIVMM##
>
JOB2: SKIPE T1,JBTADR##(J) ;SKIP THIS IF NO CORE
PUSHJ P,VMSIZE## ;VIRTUAL SIZE OF THE JOB
LDB T2,NFYPGS## ;NUMBER OF FUNNY PAGES
ADDI T1,-UPMPSZ##(T2) ;VMSIZE ADDED UPMP SIZE
ADDM T1,VIRTAL## ;VIRTUAL CORE RETURNED
PUSHJ P,ZERSWP## ;RETURNED SWAPPING SPACE
PUSHJ P,FNDPDS## ;MAKE SURE W POINTS TO PDB
SETZM .PDCMN##(W) ;CLEAR POINTER TO COMMAND NAMES
SETZM .PDUNQ##(W) ;CLEAR POINTER TO UNIQNESS BITS
PUSHJ P,UUOLVL## ;AT UUO LEVEL?
JRST JOB3 ;NO
MOVE T1,(P) ;YES, CAN'T USE STACK IN THE
MOVE P,.CPNPD## ; UPMP AFTER GIVING THE
PUSH P,T1 ; UPMP BACK TO FREE CORE
JOB3: PUSHJ P,KCORE1##
SETZM .CPADR##
SETZM JBTIMI##(J) ;NO VIRTUAL CORE
SETZM JBTIMO##(J) ;...
SETZM JBTSWP##(J)
IFN FTMP,<
PJRST GIVMM## ;RETURN THE MM RESOURCE
>
IFE FTMP,<
POPJ P,
>
SUBTTL PJOB & KJOB COMMANDS
; "PJOB" PRINT JOB NUMBER OF JOB TTY IS ATTACHED TO
PJOB:: MOVE T1,J ;JOB NO.
DECLF:: PUSHJ P,RADX10 ;PRINT T1 AS DEC. THEN CRLF
JRST CRLF
;THIS PRINTS OUT:
;
; JOB N USER NAME [P,PN] TTY#
;
PJOBX:: PUSHJ P,SAVJW## ;SAVE J(W GETS A RIDE)
PUSHJ P,GETJOB ;GET JOB NUMBER TO DO PJOB ON
SKIPA ;NO JOB NUMBER SO USE CURRENT JOB
MOVE J,T2 ;PUT REQUESTED JOB NUMBER IN AC(J)
JUMPE J,ATT4 ;ERROR IF NO JOB ASSIGNED
PUSHJ P,INLMES ;GIVE FOLLOWING MESSAGE
ASCIZ \Job \ ;
MOVE T1,J ;PRINT THE
PUSHJ P,RADX10 ; JOB NUMBER
PUSHJ P,INLMES ;GIVE FOLLOWING MESSAGE
ASCIZ \ User \ ;
PUSHJ P,FNDPDB## ;SEE IF A PDB AND POINT AC(W) TO IT
JRST PJOBX2 ;NO PDB, SO CAN'T PRINT USERS NAME
MOVE T2,.PDNM1##(W) ;GET FIRST PART OF USERS NAME
SKIPN .PDNM2##(W) ;PRINT IT
JRST PJOBX1 ;GET USERS NAME
PUSHJ P,PRSIXB ;IF LAST PART IS NULL WE'RE DONE
; WITH THE NAME PRINTOUT
MOVE T2,.PDNM2##(W) ;DOES FIRST NAME END WITH A SPACE?
PJOBX1: PUSHJ P,PRNAME
PJOBX2: PUSHJ P,PR3SPC ;GIVE A SPACE
MOVE T2,JBTPPN##(J) ;GET PPN
PUSHJ P,PRTPPN ;PRINT PPN
PUSHJ P,PR3SPC
MOVE T2,@TTYTAB##(J) ;GET TTY NAME
TLNN T2,-1 ;DETACHED?
HRLI T2,'DET' ;YES
PUSHJ P,PRNAME ;PRINT THE TTY NAME
PJRST CRLF ;END WITH A CRLF
; "KJOB" KILL ATTACHED JOB
KJOB:: SKIPE J ;WAS JOB INITIALIZED?
TLNN P4,JNA ;JOB ASSIGNED?
SKIPA ;NO
JRST KJOB3 ;GO RUN LOGOUT
SE1ENT ;ENTER SECTION ONE
IFN FTNET,<
SKIPGE LDBREM##(U) ;IF SET HOST IN PROGRESS,
JRST KJOB2 ;JUST BE QUIET ABOUT IT
> ;END IFN FTNET
PUSHJ P,SKIPS1 ;EAT LEADING SPACES AND TABS
JRST KJOB1 ;EOL
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,[-1,,[SIXBIT/DISCON/]] ;TABLE POINTER
PUSHJ P,FNDNAM ;AND SEARCH IT
JRST COMERA ;AMBIGUOUS OR UNKNOWN
KJOB1: PUSHJ P,TOPDSF## ;HANG UP THE DATASET
JFCL ;CAN'T
IFN FTNET,<
PUSHJ P,TOPDNT## ;DO A NETWORK DISCONNECT
JFCL ;CAN'T
SKIPGE LDBREM##(U) ;IF SET HOST,
KJOB2: TLOA M,NOCRLP!NOFLM ;BE SILENT
> ;END IFN FTNET
TLO M,ERRFLG ;EXIT COMMAND PROCESSING CLEANLY
MOVEI J,0 ;DITTO
POPJ P, ;DONE
KJOB3: TLNN P4,JLOG ;TEST JLOG ALSO IN CASE JOB NOT LOGGED IN
JRST KJOB4 ;IF JOB NOT LOGGED IN
PUSHJ P,TTYATI## ;ATTACH TTY
JFCL
TLO M,TTYRNU ;SET TTYRNU FOR COMRET
MOVSI P1,PHONLY ;SET PHYSICAL I/O FORCE SYSTEM KJOB
MOVSI T1,(JS.BPR) ;SET BYPASS PROGRAM TO RUN
IORM T1,JBTST2##(J) ;TO INSURE KJOB REALLY RUNS
IFN FTMP,<
PUSHJ P,ALLJSP## ;SET CPU SPECIFICATION TO MAKE JOB RUNNABLE
; ON ALL CPU'S. THIS ALSO LEAVES A REASONABLE
; SPECIFICATION FOR THE NEXT USER WHO GETS
; THIS JOB NUMBER
> ;END IFN FTMP
HRRZ T1,.PDCVL##(W) ;GET PHYSICAL LIMIT
TRZ T1,400000 ;IGNORE LIMIT/GUIDELINE
SKIPN T1 ;IF NO LIMIT HERE,
HRRZ T1,.PDMVL##(W) ;GET MPPL
SKIPN T1 ;IF NOT LIMITED,
MOVEI T1,LOGSIZ## ;FIX THE COMPARE BELOW
MOVEI T2,LOGSIZ## ;GET SIZE TO RUN LOGIN
CAIGE T1,(T2) ;IF NOT ENOUGH,
HRRM T2,.PDCVL##(W) ;MAKE IT ENOUGH
MOVE P2,LGINAM## ;GET 'LOGIN'
JRST RUNAME ;GO RUN CUSP
KJOB4: PUSHJ P,GETCIC ;GET MINIMAL JOB AREA ON DISK OR CORE
IFN FTNET,<
SE1ENT
SKIPGE LDBREM##(U) ;IF SET HOST IN PROGRESS,
TLO M,NOCRLP!NOFLM ;DON'T DO TYPEOUT
> ;END IFN FTNET
JSP T2,MONJOB## ;SCHEDULE MONITOR JOB (PC IN EXEC MODE)
; RETURN HERE AT UUO LEVEL WHEN SCHEDULED
JOBKL::
IFN FTXMON,<JRST @[0,,.+1]> ;MUST RUN IN SECTION 0
MOVEI T2,ESTOP## ;PUT ESTOP ON END OF PDL
JSP T1,MONSTR## ;GO SETUP ACS AND PD LIST AT UUO LEVEL
;RETURN HERE AT UUO LEVEL AFTER BEING SCHEDULED
MOVSI T1,JERR ;TURN OFF JERR
ANDCAM T1,JBTSTS##(J) ;..
SETZM .JDAT+.JBINT## ;NO OLD-STYLE TRAPPING EITHER
PUSHJ P,RESET## ;ZAP PSI, IPCF STUFF, ETC. HANDLE ^C CORRECTLY
IFN FTMP,< ;IF SMP
PUSHJ P,ONCPU0## ;MAKE SURE WE CAN'T MESS UP COMMAND PROCESSING
>; END IFN FTMP
PUSHJ P,CTXLGO## ;DELETE ALL IDLE CONTEXTS
IFN FTSCA,<
PUSHJ P,SCSLGO## ;TELL SCSUUO JOB IS GONE
>; END IFN FTSCA
PUSHJ P,ENQLGO## ;TELL QUESER THAT ETERNAL LOCKS GO AWAY NOW
IFN FTDECNET,<
IFE FTXMON,<DNCALL (SCULGO##)> ;TELL SCMUUO THAT JOB IS GOING AWAY
IFN FTXMON,<SNCALL (SCULGO##,MS.HGH)> ;TELL SCMUUO THAT JOB IS GOING AWAY
>; END IFN FTDECNET
PUSHJ P,DSKKJB## ;CLEAR UP CORE BLOCKS ON A KJOB COMMAND
; MAY GO INTO WAIT, SO DO BEFORE GIVING UP USER CORE
JUMPE W,JOBKL1 ;IF THIS JOB HAS A PDB,
IFN FTKL10,<
PUSHJ P,BRKDEC ;MAKE SURE ADDRESS BREAK COUNT IS DECREMENTED,
; IF NEED BE.
>
PUSHJ P,KILJSL## ;DESTROY THE JSL (GET MOUNT COUNTS RIGHT)
JOBKL1: PUSHJ P,DEASTY ;DEASSIGN ALL BUT TTY
PUSHJ P,IPCLGO## ;TELL [SYSTEM] INFO THAT JOB IS GONE
PUSHJ P,JOB1 ;FLUSH CORE AFTER RELEASING DEVICES
PUSHJ P,FNDPDS## ;TAPUUO COULD USE W
PUSHJ P,TTYSRC## ;FIND THE TTY FOR THIS JOB
SETZ F, ;NONE?
SKIPE F ;IF THERE'S A TTY DDB,
PUSHJ P,TTYKIL## ;RETURN TTY TO VIRGIN STATE
JRST KSTOP## ;CLEAR JOB STATUS WORD AND STOP JOB
SUBTTL START GROUP (START,CSTART,REE,DDT)
; "START L" OR "START" - START AT LOC. L OR STARTING ADDRESS
START:: ;SAME AS CSTART, DIFF BY COMTAB BITS
; WHICH PUT TTY IN MONITOR OR USER MODE
; "CSTART L" OR "CSTART" - START AT LOC. L(TTY IN COMMAND MODE)
STARTC::MOVE P3,P4 ;SAVE STATUS
PUSHJ P,OCTPAR ;READ A NUMBER IF PRESENT
JRST SNOARG ;NO ARG SPECIFIED RETURN
TLNN P3,JLOG ;IS IT LOGGED IN?
JRST STARTE ;NO--ERROR
TRNE P3,JS.XO!JS.RUU ;SEE IF EXECUTE ONLY
JRST ILLXO ;YES -- BOMB USER
PUSHJ P,CHKMED## ;CHECK TO SEE IF HIGH SEG WHICH IS SHARABLE
; IF YES, TURN ON USER MODE WRITE PROTECT
; FOR THIS USER, AND SET MEDDLE BIT SO HE CANNOT
; TURN UWP OFF.
JRST STARTN ;START IN USER MODE
STARTE: MOVEI T1,LOGPLM ;SETUP ERROR MESSAGE
PJRST ERRMES ;GO ISSUE IT
ILLXO: MOVEI T1,ILLXOM ;GET ERROR MESSAGE
PJRST ERRMES ;GO ISSUE IT
;"REENTER" - REENTER USER PROGRAM
REENTE::SKIPN T2,JBTADR##(J)
JRST CHKPCM ;NO ADDRESS IF NO CORE
HRRZ T2,.JDAT+.JBREN## ;GET ADDRESS FROM JOBDAT
SKIPN T1,.USUSA ;ANY SORT OF ENTRY VECTOR?
JRST CHKPCM ;NO, GO CHECK FOR /USE SECTION
JUMPE J,STARTE ;YES, BUT MUSTN'T ALLOW THIS IF NOT A JOB
HLL T2,T1 ;HAVE ONE, MERGE IN ITS SECTION
TLNN T2,370000 ;IS THIS JUST A START ADDRESS?
JRST STARTN ;YES, ONLY WANT ITS SECTION NUMBER
AOS T2,T1 ;NO, OFFSET TO REENTRY ADDRESS IN ENTRY VECTOR
TLNN T2,360000 ;IS THE VECTOR LONG ENOUGH?
TDZA T2,T2 ;NO, CLEAR THE ADDRESS
TLZ T2,770000 ;YES, ISOLATE THE ADDRESS FROM ITS BITS
JUMPE T2,CHKSTR ;BOMB USER IF NO ADDRESS
PJRST SNOAR2 ;GET ADDRESS AT UUO LEVEL AND START THE USER
; "DDT" - START EXECUTION AT DDT IN USER AREA
DDTGO:: JUMPE R,STARTE ;ERROR IF NO CORE (NOT A JOB)
HRRZ T2,.JDAT+JOBDDT## ;DDT STARTING ADR. IN JOB DATA AREA
IFN FTXMON,<
HLLZ T1,.USUSA ;GET ENTRY VECTOR SECTION
TLZ T1,770000 ;CLEAR OUT BITS
SKIPE T2 ;PRESERVE ZERO
ADD T2,T1 ;OFFSET DDT TO THAT SECTION
> ;END IFN FTXMON
SKIPN .USUSA ;IF THERE IS NO ENTRY VECTOR,
JUMPN T2,CHKPCM ;OK IF WE HAVE DDT
JUMPN T2,STARTN ;IGNORE /USE SECTION IF ENTRY VECTOR
TLNN P4,JLOG ;MAKE SURE LOGGED IN
JRST CHKPCM ;NOT BOMB HIM
TRNN P4,JS.XO!JS.RUU ;SKIP IF EXECUTE ONLY
PJRST GETDDT## ;MERGE IN DDT
CHKPCM: JUMPE J,STARTE ;ERROR IF NOT A JOB (DDT,REENTER)
JUMPE T2,CHKSTR ;IS A START ADR SPECIFIED? (ERROR IF 0)
IFN FTXMON,<
MOVE T1,.USUSN ;GET SECTION #
LSH T1,P2WLSH ;POSITION
ADD T2,T1 ;MAKE FULL WORD ADDRESS
> ;END IFN FTXMON
STARTN: MOVE T1,USRPC## ;YES, GET JOB'S PC
HLR T1,JBTSTS##(J) ;AND JOB STATUS BITS
TDNE T1,[XWD USRMOD,JERR] ;IS JOB IN USER MODE, OR STOPPED ON AN ERROR?
JRST USTART## ;YES, START HIM UP NOW
MOVE T1,T2 ;GET START ADDRESS
PUSHJ P,SETUTP## ;SETUP UUO TRAP
JRST USTART## ;START USER
JRST RSTART## ;CLEAR STATUS FLAGS AND START JOB
; IN MIDDLE OF MONITOR WHERE IT STOPPED
;HERE TO START USER WHEN NO START ADR TYPED IN
SNOARG: SKIPN T2,JBTADR##(J)
JRST CHKSTR ;NO START ADDR IF NOT IN CORE
SKIPE T2,.USUSA ;START ADDR SPECIFIED ON GET/RUN COMMAND?
JRST SNOAR1 ;YES, SEE ABOUT USING IT
HRRZ T2,.JDAT+JOBSA## ;START ADR. SPECIFIED BY LINKING LOADER
; FROM END STATEMENT
JUMPE T2,CHKSTR ;IF ZERO, FORGET IT
IFN FTXMON,<
MOVE T1,.USUSN ;SECTION NUMBER USER SPECIFIED
LSH T1,P2WLSH ;WHERE IT BELONGS
ADD T2,T1 ;30 BIT START ADDRESS
TLZ T2,770000 ;CLEAR POSSIBLE BITS
> ;END IFN FTXMON
HLLZM T2,.USUSA ;SAVE FOR NEXT TIME
;FALL INTO CHKSTR
;HERE TO CHECK TO SEE IF STARTING ADDRESS IS NON-ZERO, AND START USER IF OK
CHKSTR: JUMPE J,STARTE ;ERROR IF NOT A JOB
TLZ T2,770000 ;CLEAR SPECIFIED BY COMMAND BIT
JUMPN T2,USTART## ;IS IT NON-ZERO?, IF YES
; STORE OLD PC IN JOBOPC IN JOB DATA AREA
; THEN START WITH PC IN USER MODE
JSP T1,ERRMES ;NO, PRINT "NO START ADR"
MESNSA: ASCIZ /No start address
/
SNOAR1: CAIN T2,1 ;IS THIS SPECIAL S0 JOBDAT
HRRZ T2,.JDAT+.JBSA## ;YES, FIX IT
TRNE T2,-1 ;IS THIS A FAKE JOBDAT ENTRY?
TLNE T2,370000 ;OR A REAL ENTRY VECTOR?
TRNA ;YES OR YES, NEED SAVCTX
JRST CHKSTR ;NO, JUST A START ADDRESS, SO TRY IT
SNOAR2: MOVE S,T2 ;YES, SAVE ACROSS SAVCTX
JSP T2,SAVCTX## ;GET TO UUO LEVEL
MOVE T2,S ;RESTORE ENTRY VECTOR ADDRESS
PUSHJ P,GSADDR ;GET THE RIGHT START ADDRESS
;PJRST STARTV
STARTV: SETZ F, ;FOR USRXIT (AVOID IME)
TRNE T2,777700 ;REASONABLE ADDRESS?
JRST STARTU ;YES, USE IT
PUSHJ P,PPQCRL ;NO, START UP AN ERROR MESSAGE
PJRST URUNSB ;COMPLAIN OF 'NO START ADDRESS'
GSADDR::PUSH P,M ;SAVE FOR SAVCTX RETURN
MOVE M,T2 ;PUT WHERE FETCH ROUTINES EXPECT IT
TLZ M,770000 ;CLEAR OUT JUNK
JUMPE M,GSADD0 ;DON'T FETCH IF JUNK
CAIN T2,1 ;IF S0 JOBDAT,
SETZ T2, ;FIX IT UP
TDNN T2,[BYTE (6)37(12)(18)-1] ;IF NO LENGTH AND NO IN-SECTION ADDRESS,
HRRI M,.JBSA## ;FIX UP THE REFERENCE ADDRESS
PUSHJ P,PFHMWD## ;READ A WORD FROM THE USER'S ADDRESS SPACE
SETZB T1,M ;INVALID ADDRESS
TDNN T2,[BYTE (6)37(12)(18)-1] ;IF SPECIAL JOBDAT REFERENCE,
HLL T1,M ;FIX UP SECTION NOW
SKIPL T1 ;POSSIBLE IFIW?
TLNE T1,^-<(SECMSK)> ;NO, IS IT A VALID ADDRESS?
TLNN T1,377777 ;IFIW, IS IT PURE?
SKIPA T2,T1 ;YES, USE INDIRECTED ADDRESS
MOVE T2,M ;NO, USE ORIGINAL ADDRESS
SKIPGE T2 ;IS IT AN IFIW?
HLL T2,M ;YES, UPDATE THE SECTION NUMBER
TRNN T2,^-17 ;TRYING TO START IN THE ACS?
GSADD0: SETZ T2, ;YES, DON'T ALLOW THAT
JRST MPOPJ## ;RETURN THE DESIRED ADDRESS TO THE CALLER
SUBTTL .BPT (CONTROL-D) COMMAND
;HERE WHEN THE USER TYPES A ^D TO FORCE AN "UNSOLICITED" DDT BREAKPOINT.
;
;THE EFFECT IS TO "EXECUTE" A "JSR @.JBBPT" ON BEHALF OF THE CURRENTLY
;RUNNING USER PROGRAM; THE USER WILL THEN BE IN DDT, AND CAN "$P" TO
;RESUME THE USER PROGRAM WHERE IT WAS INTERRUPTED BY THE BREAKPOINT.
CDBPT:: JUMPE J,ATT4 ;BOMB COMMAND IF NO JOB
JUMPGE P4,BPTER2 ; OR IF THE JOB IS ^C'ED
IFN FTMP,< ;IF MORE THAN ONE PROCESSOR,
PUSHJ P,SPSTOP## ;MAKE SURE NOT RUNNING ANYWHERE ELSE
JRST DLYCM ;OOPS, WE WERE, WAIT TILL OTHER CPU LETS GO
IFN FTKL10,< ;IF NON-WRITE-THROUGH CACHES EXIST,
PUSHJ P,SBCCSH## ;NOT RUNNING, BUT MIGHT BE IN OTHER CPU'S CACHE
CAIA ;OK WRT CACHE
JRST DLYCM ;STUCK IN OTHER CPU'S CACHE, WAIT
> ;END IFN FTKL10
> ;END IFN FTMP
PUSHJ P,SIMCHK## ;SEE IF JOB IN GOOD STATE TO BE STOPPED
CAIA ;CAN STOP JOB NOW
JRST DLYCM ;CAN'T STOP JOB (EXEC PC), WAIT
SKIPG T2,.JDAT+JOBBPT## ;ADDRESS OF BREAKPOINT TRAP ENTRY
JRST BPTER3 ;NO BREAKPOINT TRAP ADDRESS
PUSHJ P,FLTTC## ;CHECK VALIDITY OF ADDRESS
JRST BPTER5 ;ERROR: OUT OF BOUNDS
JRST BPTER6 ;ERROR: PAGED OUT/INACCESSIBLE
MOVE T1,.JDAT+JOBBPT## ;ADDRESS AGAIN
PUSHJ P,IADCKL## ;I/O-LEGAL ADDRESS?
JRST BPTER7 ;NO
JRST BPTER6 ;PAGED OUT
PUSHJ P,CDBRK## ;ALL SET, LET CLOCK1 PLAY WITH THE USER'S PC
JFCL ;FAILED???
IFN FTMP,< ;IF WE CALLED SPSTOP ABOVE,
PUSHJ P,CLRCCB## ;THEN UNDO THE CALL TO SPSTOP HERE
> ;END IFN FTMP
TLO M,NOPER ;NO DOT PLEASE
POPJ P, ;.BPT COMMAND COMPLETED
;.BPT COMMAND ERRORS
BPTER1: JSP T1,BPTERM
ASCIZ \Breakpoint trapping is illegal when execute-only\
BPTER2: JSP T1,BPTERM
ASCIZ \Program is not running\
BPTER3: SKIPE .JDAT+JOBDDT##
JRST BPTER4
JSP T1,BPTERM
ASCIZ \DDT is not loaded\
BPTER4: JSP T1,BPTERM
ASCIZ \No breakpoint trap address\
BPTER5: JSP T1,BPTERM
ASCIZ \Breakpoint trap address out of bounds\
BPTER6: JSP T1,BPTERM
ASCIZ \Breakpoint trap address paged out\
BPTER7: JSP T1,BPTERM
ASCIZ \Invalid breakpoint trap address\
;COMMON BPT COMMAND ERROR MESSAGE PROCESSOR
BPTERM: PUSH P,T1 ;SAVE ERROR MESSAGE ADDRESS
PUSHJ P,CRLF ;TYPE A CRLF
POP P,T1 ;GET ADDR BACK
PUSHJ P,ERRMES ;PRINT THE ERROR MESSAGE
TLZ M,ERRFLG ;DEFEAT ERRMES
SE1XCT <MOVE T1,LDBDCH##(U)> ;GET TTY CHARACTERISTICS WORD
TLNE T1,LDLCOM## ;AT COMMAND LEVEL?
TLOA M,ERRFLG ;YES
TLO M,NOPER ;ELSE SUPPRESS THE DOT
POPJ P, ;"ERROR" RETURN
; PROCESS A "SET EDDT BREAKPOINT" COMMAND
;
SETEBP::SE1XCT <LDB T1,LDPLNO> ;GET LINE NUMBER
IFE FTMP,<CAIE T1,TCONLN##>
IFN FTMP,<
CAILE T1,FRCLIN## ;IS IT A CTY?
CAILE T1,TCONLN## ;...
>
JRST COMERA1 ;NO
PUSHJ P,SAVE1## ;SAVE P1
MOVEI P1,0 ;JOB 0
JRST SETBP1 ;ENTER COMMON CODE
; PROCESS A "SET DDT BREAKPOINT" COMMAND
;
SETBPT::PUSHJ P,SAVE1## ;SAVE P1
MOVE P1,J ;GET OUR JOB NUMBER
SETBP1: PUSHJ P,CTEXT ;GET A KEYWORD
JUMPE T2,SETBP3 ;IF NO ARGUMENT, JUST TYPE CURRENT SETTING
MOVE T1,[-3,,BPTTAB] ;POINT TO TABLE
PUSHJ P,FNDNAM ;AND SEARCH IT
JRST COMERA ;AMBIGUOUS OR UNKNOWN KEYWORD
SKIPE T1 ;USER INCLUDE "BREAKPOINT" CHATTER?
SOJA T1,SETBP2 ;NO--JUST STORE ON/OFF VALUE
PUSHJ P,CTEXT ;GET "ON" OR "OFF"
JUMPE T2,SETBP3 ;INFORM CONFUSED USER OF .BPT STATE
MOVE T1,[-2,,BPTTB1] ;POINT TO ON/OFF TABLE
PUSHJ P,FNDNAM ;SCAN IT
JRST COMERA ;AMBIGUOUS OR UNKNOWN KEYWORD
SETBP2: DPB T1,BPTPT1 ;TURN .BPT ON OR OFF
SETBP3: MOVEI T1,[ASCIZ |[Control-D breakpoint facility is turned |]
PUSHJ P,CONMES ;TYPE TEXT
LDB T1,BPTPT1 ;GET THE BIT
MOVEI T1,[ASCIZ |off|
ASCIZ |on|](T1)
PUSHJ P,CONMES ;TYPE ON OR OFF
MOVEI T1,[ASCIZ | for exec mode debugging|] ;INCASE "SET EXEC CTRLD"
SKIPN P1 ;JOB 0?
PUSHJ P,CONMES ;YES
MOVEI T3,"]" ;GET MESSAGE TERMINATOR
PJRST COMTYO ;TYPE IT AND RETURN
; PROCESS SETUUO FUNCTIONS .STEBP AND .STBPT
;
SETEBU: MOVEI J,0 ;SET EDDT SETUUO FUNCTION
SETUBU: ANDI T2,1 ;SET DDT SETUUO FUNCTION (FOR USERS)
DPB T2,BPTPTR ;TURN .BPT ON OR OFF
MOVE J,.CPJOB## ;RELOAD OUR JOB NUMBER
JRST CPOPJ1## ;AND RETURN
BPTPTR: POINT 1,JBTSTS##(J),^L<JS.BPT>
BPTPT1: POINT 1,JBTSTS##(P1),^L<JS.BPT>
BPTTAB: SIXBIT /BREAKP/
BPTTB1: SIXBIT /OFF/
SIXBIT /ON/
SUBTTL DUMP & DCORE COMMANDS
DAECOM: HRLI M,NOCORE!NOACT!NORUN!NOCRLF!NOPER!TTYRNW!INCORE!NXONLY
GETPC T1,USRPC##
TLNE T1,USRMOD
JRST DCORE1
GETPC T1,.JDAT+JOBPD1##
HRRI T1,-2(T1)
MOVSI T2,(JS.HIB)
TDNN T2,JBTST2##(J)
HRRI T1,1(T1)
DCORE1: MOVEM T1,.JDAT+JOBOPC##
PUSHJ P,STDAEM##
JRST NODAEM
MOVEI T1,JDC
ORM T1,JBTSTS##(J)
PJRST REQUE##
NODAEM: JSP T1,ERRMES
ASCIZ /DAEMON not running
/
SNDTXS: MOVE P3,[POINT 7,(T4)] ;TO COPY THE STRING
MOVEI T3,7 ;GET A BELL
IDPB T3,P3 ;STORE IN MESSAGE
SUBI P1,1 ;ADJUST CHAR COUNT
SNDTX1: PUSHJ P,COMTYI## ;NEXT CHARACTER
IDPB T3,P3 ;STORE IT FOR THE ACTDAE
CAIE T3,12 ;END OF LINE?
CAIN T3,3
TDZA P1,P1
SOJG P1,SNDTX1 ;OR USED ALL THE SPACE?
IDPB P1,P3 ;ASCIZIZE
MOVE T1,P4 ;ACTDAE
MOVE T4,P2 ;LENGTH,,ADDRESS
PJRST SNDFFC## ;SEND IT
SUBTTL CONTROL-C PROCESSING
; "HALT" OR "<CONTROL>C"
;SCANNER ROUTINES DUMMY UP HALT WHEN CONTROL C TYPED IN
;STOP MUST BE DELAYED IF THIS JOB IS SYSTEM TAPE USER
;AND SYSTEM TAPE IS ACTIVE. OTHERWISE, THE JOB WILL NOT BE
;STOPPED WHEN DONE USING THE SYSTEM TAPE.
;IF JOB IS IN MONITOR MODE AND NOT IN TTY WAIT THIS JOB CANNOT BE STOPPED YET
;IN THIS CASE SET A BIT IN JOB STATUS WORD (CNTRLC) WHICH WILL BE CHECKED
;WHEN JOB RETURNS TO USER MODE
STOP:: MOVE P2,HALTXT##
STOPF::
IFN FTNET,<
SE1XCT <SKIPGE LDBREM##(U)> ;IF SET HOST IN PROGRESS,
TLO M,NOCRLP!NOFLM ;DON'T TYPE OUT
> ;END IFN FTNET
JUMPE J,STOPB
TLNE P4,JACCT ;JACCT AND WAITING
TRNN P4,JDCON ;..
JRST STOPD ;NO--PROCEED
JUMPL P4,STOPD ;JUMP IF RUN BIT IS SET
TLO M,NOCRLP ;KILL THE DOT
POPJ P,0 ;PUNT THE COMMAND
STOPD: MOVEI T1,JDCON!JDC ;CLEAR JCONT.ABLE (DEV OK?) AND DAEMON BIT
ANDCAM T1,JBTSTS##(J) ; SO USER CAN STOP ONCE-A-MINUTE STUFF
IFN FTMP,<
PUSHJ P,SPSTOP## ;TEST IF JOB ON SLAVE, IF SO SIGNAL TO STOP IT,
JRST DLYCM1 ; AND DELAY COMMAND
>
PUSHJ P,SIMCHK## ;OK TO "STOP IN MONITOR"?
JRST STOPA ;YES, STOP JOB
MOVSI T1,CNTRLC ;NO, FLAG THAT USER MUST BE STOPPED WHEN
IORB T1,JBTSTS##(J) ; RETURNING TO USER MODE IN UUO HANDLER
TLNE M,CMWRQ ;IS JOB IN COMMAND WAIT?
PUSHJ P,REQUE## ;YES. PUT HIM BACK IN RUNNABLE QUEUE
JRST DLYCM1 ;THEN DELAY COMMAND (IE ECHO CR-LF, DOT)
;UNTIL SWAPPED IN
STOPA: MOVSI T1,SWP!SHF ;IS THE JOB SWAPPED?
TDNE T1,JBTSTS##(J) ;IF SO, DELAY THE CONTROL C SINCE
PJRST DLYCM ; THE JOB DATA AREA MUST BE IN CORE
; TO SEE IF THE JOB IS INTERCEPTING
; CONTROL C'S
MOVSI T1,CNTRLC+CMWB ;DELAYED CONTROL C+ COMMAND WAIT
ANDCAM T1,JBTSTS##(J) ;CLEAR THEM
SKIPL JBTSTS##(J) ;IS RUN BIT ALREADY OFF?
JRST STOPAA ;IF YES, DO NOT PRINT [XXXX] AGAIN
PUSHJ P,STOPX ;STOP JOB
TLNN M,NOPER ;IF NO PERIOD, SKIP [XXX]
PUSHJ P,WCHEND ;PRINT [XXXX] CRLF IF USER IS WATCHING RESPONSES
JRST STOPAB ;GO FINISH
STOPAA: PUSHJ P,STOPX ;STOP JOB
STOPAB: SKIPGE T1,JBTSTS##(J) ;GET JOB STATUS
JRST STOPB ;IF NOT STOPPED, DON'T KJOB
TLNN T1,JLOG ;IS JOB LOGGED IN?
PUSHJ P,TTKJOB##
STOPB: SKIPL JBTSTS##(J) ;RUNNING?
PUSHJ P,FNDPDB## ;FIND PDB
POPJ P,
MOVEI T1,TTFCXI## ;FORCE .INITIA
MOVEI T2,JS.RPC ;IF JS.RPC = 1
SKIPE .PDPGM##(W) ;AND PROGRAM TO RUN
TDNN T2,JBTST2##(J) ; ..
POPJ P,0
PUSHJ P,TTFORC##
PJRST DLYCM
STOPX: MOVSI T1,(JS.SAC) ;BIT TO TEST
TDNE T1,JBTST2##(J) ;DOING AN AUTO-RESTORE ON PROGRAM EXIT?
TLO M,NOCRLP ;YES, DON'T TYPE CRUFT
PJUMPL P2,STOP1C## ;IF "HALT", STOP REGARDLESS
PJRST STOP1## ;IF "^C^C", STOP IF POSSIBLE
;MONITOR COMMAND LEVEL RESPONSE ROUTINES
;FIVE MULTIPLE ENTRY SUBROUTINES TO PRINT SYSTEM RESPONSE DATA FOR A JOB
;CONTROL REACHES ONE OF THESE ROUTINES ON ANY OF THE FOLLOWING:
;1. USER TYPES CONTROL C
;2. PROGRAM HALTS
;3. PROGRAM CALLS EXIT, OR CALL N,EXIT
;4. DEVICE BECOMES UNREADY DEVICE XXX OK?
;5. ERROR IN JOB MESSAGE
;PRRSP1 - PRINT CRLF CRLF
;PRRSP3 - PRINT [XXXX] CRLF IF USER WATCHING SYSTEM DATA RESPONSE
;PRRSP4 - PRINT CRLF
;PRRSP5 - PRINT PERIOD
PRRSP1::PUSHJ P,CRLF ;PRINT CR-LF
PRRSP3::PUSHJ P,WCHEND ;PRINT SYSTEM RESPONSE DATA IF USER IS WATCHING
PRRSP4::PUSHJ P,CRLF ;PRINT CR-LF
PRRSP5::PUSHJ P,FNDPDB## ;ENSURE W IS SETUP
PJRST PRDOTC ;?
MOVEI T1,JS.RPC ;RUN PROGRAM BIT
SKIPE .PDPGM##(W) ;ANY TO RUN?
TDNN T1,JBTST2##(J) ;DOES HE WANT IT RUN
PJRST PRDOTC ;NO, PRINT DOT
POPJ P, ;YES, DONT PRINT DOT
SUBTTL SET COMMAND AND UUO -- DISPATCH
;SET COMMAND/UUO
SET:: MOVE P3,[XWD UNQTB2##,DISP2##] ;UNIQUENESS PLUS START OF SET-TABLE
MOVE P4,[XWD -DISPL2##,COMTB2##] ;LENGTH, NAME
MOVE P,.CPISF## ;RESTORE P TO VALUE AT COMGO
XJRST [MCSEC1+COM1] ;GO INTERPRET 2ND PART OF THE COMMAND (IN SECTION 1)
;SUBROUTINE TO SEE IF A SYSTEM-WIDE SET COMMAND IS LEGAL
;SKIP RETURN IF LEGAL, ELSE NON-SKIP
SETLGF==FUPOPJ##
SETLGK==FUPOJ1##
SETLGL::MOVE T3,LINTAB##+FRCLIN##
CAMN T3,U
JRST CPOPJ1##
PUSHJ P,OPRLGL ;OPR?
SKIPA T2,JBTPPN##(T1) ;NO, CHECK FURTHER
JRST CPOPJ1## ;YES, OK
CAMN T2,FFAPPN## ;1,2?
AOS (P) ;YES, OK
POPJ P, ;RETURN
OPRLGL: PUSH P,U ;PRESERVE LINE
PUSH P,F ;AND F
MOVE T1,J
MOVE T3,OPRLDB## ;SEE IF OPR
CAMN T3,U ;ALSO OPR
JRST SETLGK ;WE WIN
MOVE T2,JBTSTS##(J) ;GET JOB STATUS
TLNE T2,JLOG ;A JOB ON THE TTY?
JRST SETLGF ;YES. COMMAND LOSES
SE1XCT <LDB T2,LDPLNO##> ;GET LINE NUMBER
PUSHJ P,CTLJB## ;LOSE -- SEE IF PTY
JUMPLE T1,SETLGF ;NO --- GIVE UP
HRRZ U,TTYTAB##(T1) ;OK -- GET DDB
MOVE U,DDBLDB##(U) ;THEN GET LDB
JUMPE U,SETLGF ;IF CONTROL JOB DETACHED STOP SCAN AND FAIL
MOVSI T2,DVDIBP ;GET BATCH JOB BITS
TDNE T2,DEVCHR(F)
JRST SETLGF ;YES. COMMAND LOSES
CAMN T3,U ;OR HIS TTY?
JRST SETLGK ;YES. COMMAND WINS
JRST SETLGF ;LOSE
SUBTTL SET COMMAND AND UUO -- JBSET.
;HERE FROM UUOCON ON JBSET. UUO
;CALL: MOVE AC,[+N,,BLK]
; CALLI AC,JBSET.
; ERROR RETURN AC=0
; NORMAL RETURN
;BLK: JOB NUMBER
; XWD FUNCTION,VALUE
UJBSET::PUSHJ P,PRVJ ;ARE WE A GOOD GUY
JRST JBSET1 ;YES--GO DO THE SET
JRST RTZER## ;NO--RETURN 0
JBSET1: PUSH P,M ;SAVE M
HRRI M,(T1) ;GET ADDRESS OF BLK
PUSHJ P,GETWDU## ;PICK UP JOB#
MOVE J,T1 ;PUT JOB NUMBER IN J
PUSHJ P,LGLPRC## ;SKIP IF LEGAL JOB NUMBER
JRST JBSET2 ;NO, GIVE UP
MOVSI T1,JNA ;SEE IF JOB EXISTS
TDNN T1,JBTSTS##(J) ; AND EXISTENT
JRST JBSET2 ; YES--GIVE UP
MOVE T4,J ;SAVE NEW JOB
PUSHJ P,GETWD1## ;GET NEXT WORD(XWD) PUT IT IN T1
MOVE J,T4 ;RESTORE NEW JOB
NOSCHED
PUSH P,JBTPPN##(J) ;SAVE PPN
MOVE T2,FFAPPN## ;GET A GOOD PPN
MOVEM T2,JBTPPN##(J) ;FAKE OUT PRIVJ AND PRVBIT
PUSH P,J
PUSH P,W ;PRESERVE W
PUSHJ P,FNDPDS## ;GET THE PDB FOR THE TARGET JOB
PUSHJ P,SETUUO ;DO IT
TDZA T1,T1 ;NOTE BAD RETURN
SETO T1, ;GOOD RETURN
POP P,W ;RESTORE W
POP P,J
POP P,JBTPPN##(J) ;RESTORE PPN
SCHEDULE
POP P,M
JUMPN T1,CPOPJ1## ;PASS THE GOOD WORD ON
JRST STOTAC## ;ELSE RETURN ZERO
JBSET2: POP P,M ;RESTORE AC
JRST RTZER## ;GIVE ERROR
SUBTTL SET COMMAND AND UUO -- PRIVILEGE TESTS
;DISPATCH HERE (FROM UUOCON) ON A SETUUO
;CALL: MOVE AC,[XWD FUNCTION,ARGUMENT]
; CALLI AC,SETUUO
NEDPRV==1 ;BIT ON IN DISPATCH TABLE IF PRIVS NEEDED
NLOGOK==2 ;BIT ON IS DISPATCH IF OK WHEN NOT LOGGED IN
SETUUO::HRRZ T2,T1 ;ARGUMENT
HLRES T1 ;FUNCTION
CAML T1,[SETTBC-SETTBL] ;A LEGAL CUSTOMER FUNCTION?
CAILE T1,SETLEN ;A LEGAL FUNCTION?
POPJ P, ;NO, RETURN DOING NOTHING
MOVE T1,SETTBL(T1) ;YES, GET TABLE WORD
TLNE T1,NEDPRV ;NEED SPECIAL PRIVS TO DO IT?
PUSHJ P,PRVJ ;YES, JOB HAVE PRIVS?
PJRST (T1) ;YES, DISPATCH
TLNE T1,NLOGOK ;NO PRIVS, IS IT OK IF NOT LOGGED IN?
TLNE T3,JLOG ;YES, IS JOB LOGGED IN?
JRST ECOD0## ;LOGGED IN OR NO PRIVS, ERROR RETURN
PJRST (T1) ;DISPATCH FUNCTION
;SUBROUTINE TO SEE IF A JOB HAS PRIVILEGE:
;CALL: MOVE T1,BIT TO BE TESTED IN PRIVILEGE WORD
; MOVE J,JOB NUMBER
; PUSHJ P,PRVBIT
; RETURN IF PRIVILEGED BY BIT, [1,2], OR JACCT
; RETURN IF NOT PRIVILEGED
;RESPECTS T2
PRVBIT::TDNE T1,JBTPRV##(J) ;IS REQUESTED BIT ON IN TABLE?
POPJ P, ;YES. OK RETURN
; PJRST PRVJ ;NO. CHECK FOR JACCT OR FSFPPN
;SUBROUTINE TO TEST FOR [1,2] OR JACCT PRIVILEGES.
;NEEDED IF A SETUUO FOR A SYSTEM-PARAMETER IS DONE.
;RETURNS CPOPJ IF HAVE PRIVS, CPOPJ1 IF DON'T.
;RESPECTS T2
PRVJ:: MOVE T3,JBTSTS##(J) ;JBTSTS WORD
SKIPGE M ;COMMAND LEVEL?
TLZA T3,JACCT ;YES--CLEAR JACCT
PRVJC:: MOVE T3,JBTSTS##(J) ;IF AT UUO LEVEL AND THE SIGN BIT OF M COULD BE ON
MOVE T4,JBTPPN##(J) ;JOB'S PRJ-PRG
CAME T4,FFAPPN## ;=1,2?
TLNE T3,JACCT ;NO, JACCT ON?
POPJ P, ;YES, OK
PJRST CPOPJ1## ;NO, ERROR RETURN
;TABLE FOR SETUUO. NEGATIVE FUNCTIONS ARE CUSTOMER DEFINED.
;POSITIVE FUNCTIONS ARE RESERVED FOR DEC.
SETTBC: ;MINIMUM CUSTOMER DEFINED FUCTION
IFN FTPATT,<
EXP CPOPJ## ;ROOM FOR PATCHING
>; END IFN FTPATT
SETTBL: XWD NEDPRV,SETMX1 ;(0) - SET CORMAX
XWD NEDPRV,SETMN1 ;(1) - SET CORMIN
XWD NEDPRV,SETDA1 ;(2) - SET DAYTIME
XWD NEDPRV,SETSC1 ;(3) - SET SCHED
EXP SETSPI ;(4) - SET CDR
EXP SETSPB ;(5) - SET SPOOL
EXP SETWTU ;(6) - SET WATCH
XWD NEDPRV,SETDT1 ;(7) - SET DATE
XWD NEDPRV,SETOP1 ;(10) - SET OPR (INDIRECT)
XWD NEDPRV,SETKSY ;(11) - SET KSYS
XWD NEDPRV,CORELM##
EXP SETIM1 ;(13) - SET TIME LIMIT
EXP SETCPU## ;(14) - SET USER CPU SPECIFICATION
XWD NEDPRV,SETCRN## ;(15) - SET CPU RUNABILITY
XWD NEDPRV,SETLMX ;(16) - SET LOGMAX
XWD NEDPRV,SETBMX ;(17) - SET BATMAX
XWD NEDPRV,SETBMN ;(20) - SET BATMIN
EXP DSKFUL ;(21) - SET DSKFUL- PAUSE OR ERROR
XWD NEDPRV,SETVM1## ;(22) - SET VMMAX (SYSTEM-WIDE)
XWD NEDPRV,CPOPJ1## ;(23) - HISTORICAL
XWD NEDPRV+NLOGOK,SETUVL## ;(24) - SET VM MAXIMA (USER)
EXP SETUV1## ;(25) - SET CURRENT VM MAXIMA (USER)
EXP SETVTM## ;(26) - SET TIME FOR VIRTUAL TIME INTERRUPTS
EXP SETABR ;(27)-SET ADDRESS BREAK
EXP SETPGM ;(30)-SET PROGRAM TO RUN
EXP SETDFU ;(31)-SET DEFERED SPOOLERS
IFN FTNET,<
XWD NEDPRV,HOST.U## ;(32)-SET HOST
>
IFE FTNET,<
EXP CPOPJ## ;(32)-SET HOST - NOT DEFINED
>
EXP SETDLU ;(33)-SET DEFAULTS
EXP SETPRV ;(34)-SET PRIVILEGES
XWD NEDPRV,SETBSN ;(35) SET BATCH STREAM NUMBER
XWD NEDPRV,SETWTO ;(36) SET WTO CAPABALITIES
XWD NEDPRV,SETCDN## ;(37) SET CPU UP/DOWN STATUS
IFN FTKL10,<
IFN FTMP,<
XWD NEDPRV,SETCSB## ;(40) SET/CLEAR CACHE BITS
>
IFE FTMP,<
EXP CPOPJ## ;(40) SET/CLEAR CACHE BITS - NOT DEFINED
>
> ;END IFN FTKL10
IFN FTKS10,<
EXP CPOPJ## ;(40) SET/CLEAR CACHE BITS - NOT DEFINED
>; END IFN FTKS10
EXP SETFPS## ;(41) SET/CLEAR FLOATING POINT SIMULATION
XWD NEDPRV+NLOGOK,SETOPP ;(42) SET OPERATOR PRIVS
XWD NEDPRV,SETQST ;(43) SET QUEUE STRUCTURE
XWD NEDPRV,CSHSIZ## ;(44) SET DISK BLOCK CACHE SIZE
XWD NEDPRV,SETEBU ;(45) SET EDDT BREAKPOINT ON/OFF
EXP SETUBU ;(46) SET DDT BREAKPOINT ON/OFF
XWD NEDPRV,SETDA0 ;(47) SET TIME OF DAY IN SECONDS
XWD NEDPRV,SETMXP ;(50) SET CORMAX IN PAGES
XWD NEDPRV,SETMNP ;(51) SET CORMIN IN PAGES
IFN FTMP,<
EXP SETPCP## ;(52) SET POLICY CPU
>; END IFN FTMP
IFE FTMP,<
EXP CPOPJ## ;(52) SET POLICY - UNDEFINED IF NOT FTMP
>; END IFE FTMP
IFN FTPATT,<
EXP CPOPJ## ;ROOM FOR PATCHING
>; END IFN FTPATT
SETLEN==.-SETTBL-1
IFE FTLOCK,<
SETMN1==CPOPJ##
SETMNP==CPOPJ##
>; END IFE FTLOCK
SUBTTL SET COMMAND AND UUO -- CORMAX AND CORMIN
SETMXP: AOS T3,T2 ;COMPUTE HIGHEST ADDRESS
ANDI T3,400000 ;PRESERVE SOFT CORMAX FLAG
TRZ T2,400000 ;KEEP ONLY NUMBER OF PAGES
LSH T2,P2WLSH ;CHANGE TO WORDS
SOSA T2 ;CONTINUE
SETMX1: SETZ T3, ;HARD CORMAX FOR OLD FUNCTION CODE
IFN FTLOCK,<
SKIPE LOCK## ;JOB BEING LOCKED?
JRST ECOD0## ;YES - CAN'T CHANGE CORMAX
>
JRST SETMX2 ;ENTER COMMON CODE
SETMAX::PUSHJ P,CORLGL ;GET DECIMAL ARG IF LEGAL
IFN FTLOCK,<
SKIPE LOCK## ;IF A JOB IS BEING LOCKED,
JRST DLYCM1 ;WAIT TILL LATER
>
SETZ T3, ;FORCE HARD CORMAX FOR COMMAND
SETMX2: PUSH P,T3 ;SAVE HARD/SOFT CORMAX FLAG
MOVE T1,RMCMAX## ;REAL MAXIMUM CORMAX, INCLUDING FUNNY SPACE
CAMG T2,T1 ;TRY TO SET IT TOO HIGH?
JRST SETAOK ;NO
JUMPGE M,SETMXE ;RETURN ERROR IF UUO
PUSHJ P,INLMES
ASCIZ /
%Exceeds physical maximum-/
MOVE T1,RMCMAX## ;GET REAL MAXIMUM
LSH T1,W2PLSH ;SET UP FOR P OR K
PUSHJ P,PRCORE ;TELL WHAT IT IS
MOVE T2,RMCMAX## ;REDUCE PHYSICAL LIMIT
SETAOK: CAIL T2,MINMAX## ;TOO SMALL?
JRST SETIOK ;NO
JUMPGE M,SETMXE ;RETURN ERROR IF UUO
PUSHJ P,INLMES
ASCIZ /
%Below minimum-/
MOVEI T1,MINMAX## ;GET MINIMUM
LSH T1,W2PLSH
PUSHJ P,PRCORE ;REPORT IT
MOVEI T2,MINMAX##
SETIOK: POP P,T3 ;GET FLAG BACK
JUMPN T3,SETMXF ;CONTINUE IF SOFT CORMAX
CAMGE T2,CORMAX## ;DECREASING?
PUSHJ P,CHKMAX ;YES. CHECK JOB SIZES
SETMXF: MOVEM T2,CORMAX## ;SAVE NEW VALUE
LSH T2,W2PLSH ;REDUCE TO N
HRRM T2,CORLIM## ;SAVE IN RH(CORLIM)
JRST CPOPJ1## ;AND SKIP RETURN
SETMXE: POP P,(P) ;PHASE STACK
JRST ECOD0## ;RETURN ERROR CODE 0 (BAD ARGUMENT)
CHKMAX: PUSHJ P,SAVE3## ;SEE IF NEW CORMAX
SETZ P1,0 ;IS TOO SMALL FOR
PUSH P,J ;JOBS NOW RUNNING
MOVE P2,T2 ;SAVE DESIRED NEW VALUE
MOVEI J,1 ;SCAN ALL JOBS
CHKMX1: MOVE T2,JBTSTS##(J) ;DON'T COUNT LOCKED JOBS
TLNE T2,NSHF!NSWP
TDZA T2,T2 ;THIS JOB IS LOCKED
PUSHJ P,SEGSIZ ;GET LOW SEG SIZE
PUSH P,J ;SAVE JOB #
HRRZ T3,JBTSGN##(J) ;SEE IF USER HAS ANY HIGH SEGS
JUMPE T3,CHKMX2 ;NO
CHKM1A: SKIPLE J,.HBSGN(T3) ;IS THIS HIGH SEG REAL?
TLNE J,NSWP!NSHF ;AND NOT LOCKED?
JRST CHKM1B ;LOCKED OR SPY
MOVE P3,T2 ;SAVE CURRENT SUM
PUSHJ P,SEGSIZ ;GET HISEG SIZE
ADDI T2,(P3) ;TOTAL
CHKM1B: HRRZ T3,.HBLNK(T3) ;POINT TO NEXT HIGH SEG
JUMPN T3,CHKM1A
CHKMX2: LSH T2,P2WLSH ;TOTAL WORDS
CAMLE T2,P1 ;BIGGEST SO FAR?
MOVE P1,T2 ;YES
POP P,J ;GET BACK JOB #
CAMGE J,HIGHJB## ;ALL JOBS SCANNED?
AOJA J,CHKMX1 ;NO
CAMG P1,P2 ;BIGGEST JOB FIT NEW CORMAX?
JRST CHKMX3 ;YES. OK AS IS
MOVE P2,P1 ;NO. ADJUST REQUEST
JUMPGE M,CHKMX3
PUSHJ P,INLMES
ASCIZ /
%Too small for current job(s)-/
MOVE T1,P2 ;GET SIZE OF LARGEST JOB
LSH T1,W2PLSH
PUSHJ P,PRCORE ;REPORT IT
CHKMX3: MOVE T2,P2
POP P,J ;BALANCE STACK
JRST ECOD0## ;RETURN ERROR
IFN FTLOCK,<
SETMNP: LSH T2,P2WLSH ;CONVERT TO WORDS
TROA T2,PG.BDY ;CONVERT TO HIGHEST LEGAL ADDRESS
SETMIN::PUSHJ P,CORLGL ;GET DECIMAL ARG IF LEGAL
SETMN1: CAMLE T2,CORMAX## ;CORMIN CAN'T
MOVE T2,CORMAX## ;EXCEED CORMAX
MOVEM T2,CORMIN## ;SET NEW VALUE IN CORMIN
JRST CPOPJ1## ;AND SKIP RETURN
>
;SUBROUTINE TO GET CORE ARGUMENT AND CHECK FOR LEGALITY
; DOES NOT RETURN IF NOT LEGAL
CORLGL::PUSHJ P,SETLGL ;TEST FOR LEGALITY
JRST COMERP ;NOT LEGAL
PUSHJ P,CORARG ;GET THE CORE ARGUMENT
JRST NOTENP ;NOT ENOUGH ARGUMENTS
AOS T2,T1 ;CONVERT TO NUMBER OF WORDS
POPJ P, ;RETURN
;SUBROUTINE TO TEST FOR LEGALITY, RETURN NEXT TYPED ARGUMENT IF LEGAL
;DOES NOT RETURN IF NOT LEGAL
DECLGL::PUSHJ P,SETLGL ;TEST FOR LEGALITY
JRST COMERP ;NOT LEGAL
PUSHJ P,DECIN1 ;LEGAL - GET DECIMAL NUMBER
PJRST NOTENP ;NOT ENOUGH ARGS
PJRST COMERP ;NOT A NUMBER
POPJ P, ;OK - RETURN
;HERE TO SET MEMORY ON OR OFF LINE
SETMEM::PUSHJ P,SETLGL ;MUST BE PRIVILEGED
JRST COMERA ;NOT PRIVLEGED, LOSE
; PUSHJ P,SAVE2##
PUSHJ P,CTEXT ;GET MODIFIER
JUMPE T2,NOTENF ;MUST BE ONE
MOVE T1,[-2,,[SIXBIT /ON/
SIXBIT /OFF/]]
PUSHJ P,FNDNAM ;LOOK FOR EITHER "ON" OR "OFF"
JRST COMERA ;IF NEITHER, LOSE
MOVE P1,T1 ;REMEMBER WHETHER HE SAID ON OR OFF
PUSHJ P,SKIPS1 ;SKIP SPACES, TABS, ETC.
JFCL ;IGNORE NON-SKIP RETURN
CAIN T3,"-" ;ALLOW "-LINE"
PUSHJ P,COMTYS ;IF A MINUS SIGN WAS TYPED, SKIP IT
MOVE T1,[-2,,[SIXBIT /LINE/
SIXBIT /FROM/]]
PUSHJ P,TXTARG ;ALLOW NOISE WORDS
JRST SETME0 ;NONE WAS TYPED
JUMPN T1,SETME0 ;SKIP ON IF "FROM" WAS TYPED
HRROI T1,[SIXBIT/FROM/]
PUSHJ P,TXTARG ;"LINE" WAS TYPED, EAT "FROM" IF ITS THERE
JFCL ;DON'T CARE WHETHER IT WAS ON NOT
SETME0: PUSHJ P,DECIN1 ;READ AN ARGUMENT (DEFAULT IS DECIMAL)
JRST NOTENF ;THERE MUST BE ONE
PUSHJ P,[CAIE T3,"K" ;NUMBER ENDED WITH A NON-DIGIT,
CAIN T3,"P" ; WAS IT "P" OR "K"?
CAIA ;YES
JRST COMERP ;NO, COMPLAIN
MOVEI T1,P2WLSH
CAIE T3,"P" ;ARGUMENT SPECIFIED IN PAGES?
MOVEI T1,K2WLSH
LSH T2,(T1) ;CONVERT TO WORDS
JRST COMTYS] ;AND EAT THE "P" OR "K"
MOVE P2,T2 ;SAVE THE LOWER BOUND
HRROI T1,[SIXBIT/TO/]
PUSHJ P,TXTARG ;ALLOW THE NOISE WORD "TO"
JFCL ;DON'T CARE IF IT ISN'T THERE
PUSHJ P,DECIN1 ;READ THE SECOND ARGUMENT
JRST NOTENF ;THERE MUST BE ONE
PUSHJ P,[PUSHJ P,[CAIE T3,"K"
CAIN T3,"P" ;ONCE AGAIN, ALLOW ARGUMENT TO BE
CAIA ; QUALIFIED BY "P" OR "K"
JRST COMERP ;HOWEVER, NOTHING ELSE WILL DO
MOVEI T1,P2WLSH
CAIE T3,"P" ;PAGES?
MOVEI T1,K2WLSH
LSH T2,(T1) ;CONVERT TO WORDS
JRST COMTYS] ;AND THROW AWAY THE CHARACTER
SOJA T2,CPOPJ##]
CAMG P2,T2 ;FIRST ARGUMENT MUST BE .LT. THE SECOND
CAIE T3,12 ;AND THE LINE MUST BE PROPERLY TERMINATED
JRST COMERA ;GRUMBLE
MOVE T1,P2 ;RESTORE FROM ARGUMENT
TRZ T1,PG.BDY ;ROUND TO A PAGE BOUNDARY
TRZ T2,PG.BDY ; ..
ADDI T2,PAGSIZ ;ROUND UP
LSHC T1,W2PLSH ;CONVERT FROM WORDS TO PAGES
;HERE T1 = LOWEST PAGE NUMBER (K NUMBER) OPR TYPED
; T2 = HIGHEST PAGE NUMBER (K NUMBER) + 1 OPR TYPED
;P1 = 0 IF SET MEMORY ON LINE
;P1 = 1 IF SET MEMORY OFF LINE
;DISPATCH TO ROUTINE TO SET MEMORY ON OR OFF LINE
JUMPN P1,SETME1
;HERE TO SET MEMORY ON LINE, T1 = FIRST PAGE TO SET ON LINE, T2 = LAST
; PAGE + 1
MEMONL::HRLZ S,T1 ;STARTING PAGE TO SET ON LINE
HRR S,T2 ;HIGHEST PAGE TO SET ON LINE
JSP T2,SAVCTX## ;SAVE THE JOB'S CONTEXT AND RETURN AT UUO LEVEL
; (THE JOB'S CONTEXT MUST BE SAVED BECAUSE
; IF SETTING THE MEMORY ON LINE CAUSES
; A NXM, THE JOB'S CONTEXT WILL BE DESTROYED)
HLRZ T1,S ;RESTORE THE STARTING PAGE TO SET ON LINE
HRRZ T2,S ;AND THE HIGHEST PAGE TO SET ON LINE
;JOIN HERE FOR RECON. UUO TO SET MEMORY ON LINE
MEMONU::SE1ENT ;ENTER SECTION 1, TO LOOK AT PAGTAB.
MOVE T3,MEMSIZ## ;CURRENT HIGHEST ADDRESS IN THE MACHINE
MOVE T4,NWCORE## ;HIGHEST ADDRESS THAT CAN BE SET ON LINE
; (CANNOT MAKE PAGTAB AND MEMTAB BIGGER)
LSHC T3,W2PLSH ;CONVERT TO PAGES
CAMG T3,T4 ;PICK THE BIGGER OF THE TWO AS THE
MOVE T3,T4 ; HIGHEST ADDRESS THAT CAN BE SET ON LINE
TRZE T3,PG.BDY ;ROUND UP TO A 256K BOUNDARY (IF NOT
ADDI T3,PAGSIZ ; ALREADY ON A 256K BOUNDARY
CAMG T3,T2 ;IF ASKING FOR MEMORY ON LINE ABOVE THE
; HIGHEST WHICH CAN BE DONE,
MOVE T2,T3 ; SET ON UP TO THE HIGHEST THAT CAN BE DONE
CAML T1,T2 ;LOWEST PAGE ABOVE THE HIGHEST PAGE?
POPJ P, ;YES, NOTHING TO SET ON LINE
MOVE P1,T1 ;LOWEST PAGE TO SET ON LINE
IDIVI P1,^D36 ;COMPUTE BIT POSITION AND WORD NUMBER WITHIN NXMTAB
MOVNI P2,-^D35(P2) ;BIT POSITION BYTE POINTER STYLE
HRLI P1,(POINT 1,0,0);FORM A 1 BIT BYTE POINTER TO NXMTAB
DPB P2,[POINT 6,P1,5]
ADDI P1,NXMTAB## ;BYTE POINTER TO BIT CORRESPONDING TO FIRST PAGE TO SET ON
SETZB T4,P2 ;INITIALIZE FIRST AND HIGHEST NON-EXISTANT PAGES SEEN
MOVEI P3,PAGSIZ ;TO UPDATE MAXMAX ON EACH PAGE SET ON LINE
IFN FTMP,<
PUSHJ P,UPMM## ;GET THE MM RESOURCE
>
MEMON6: MOVE T3,@[IW MS.MEM,PAGTAB(T1)] ;PAGE DESCRIPTOR BITS
TLNE T3,NXMBIT ;IS THIS PAGE NON-EXISTANT?
TLNE T3,MONTRB ;IF AN UNMAPPED MONITOR PAGE SKIP IT TOO
JRST MEMON8 ;NO, ITS ALREADY ON LINE
DPB P3,P1 ;INDICATE THIS PAGE EXISTS IN NXMTAB
PUSHJ P,MEMOZR ;ZERO OUT THE PAGE AND CHECK FOR NXM
JRST MEMON8 ;GOT AN NXM
ADDM P3,MAXMAX## ;INCREASE THE MAXIMUM VALUE FOR CORMAX
ADDM P3,RMCMAX## ;INCREASE REAL MAX VALUE FOR CORMAX
SKIPN P2 ;SKIP IF NOT THE FIRST PAGE SET ON LINE
MOVE P2,T1 ;REMEMBER THE FIRST PAGE SET ON LINE
JUMPE T4,MEMON7 ;JUMP IF FIRST PAGE
HRRZM T1,@[IW MS.MEM,PAGTAB(T4)] ;LINK PAGES BEING SET ON LINE TOGETHER
MEMON7: MOVE T4,T1 ;REMEMBER LAST PAGE
MEMON8: IBP P1 ;BUMP BYTE POINTER TO NEXT PAGE IN NXMTAB
CAIE T1,-1(T2) ;LOOKED AT THE ENTIRE RANGE OF PAGES TO SET ON LINE?
AOJA T1,MEMON6 ;NO, LOOK AT THE NEXT PAGE
IFE FTMP,<
JUMPE P2,CPOPJ## ;RETURN DOING NOTHING IF ALL PAGES WERE ALREADY
> ; ON LINE
IFN FTMP,<
PJUMPE P2,DWNMM## ;GIVE UP THE MM
>
SETZM @[IW MS.MEM,PAGTAB(T4)] ;INDICATE END OF THE LIST OF PAGES SET ON LINE
;HERE WHEN MEMORY HAS BEEN MARKED ON LINE AND CHECKED FOR NXM.
;ADD ALL PAGES WHICH WERE OFF LINE TO THE FREE CORE LIST.
MOVE T1,P2 ;FIRST PAGE IN THE LIST OF PAGES SET ON LINE
MOVE P1,T4 ;LAST PAGE FREED
LSH T4,P2WLSH ;HIGHEST ADDRESS SET ON LINE
ADDI T4,PAGSIZ ;ADDRESS OF PAGE FOLLOWING HIGHEST SET ON LINE
CAMLE T4,MEMSIZ## ;IS THAT GREATER THAN CURRENT MEMORY SIZE?
MOVEM T4,MEMSIZ## ;YES, SAVE NEW HIGHEST ADDRESS IN MEMORY + 1
MOVE T4,MEMSIZ## ;HIGHEST ADDRESS IN MEMORY + 1
LSH T4,W2PLSH ;CONVERT TO HIGHEST PAGE
MOVE T2,T4 ;NEW HIGHEST PAGE
TRZE T2,PG.BDY ;ROUND UP
ADDI T2,PP256K## ;TO A 256K BOUNDARY
IDIVI T2,^D36 ;BITS/WORD
MOVNI T2,1(T2) ;NEGATIVE LENGTH OF NXMTAB
HRLM T2,NXMPTR## ;UPDATE NXMPTR TO REFLECT ADDITIONAL MEMORY
MOVEI T4,PAGTAB-1(T4) ;BYTE POINTER TO HIGHEST PAGE IN MEMORY
SSX T4,MS.MEM ;GIVE IT A SECTION NUMBER
MOVEM T4,CORLST## ;STORE THAT FOR CHKTAL
SSX T1,MS.MEM ;CLEAR BACK POINTER SO
HLLZS PT2TAB(T1) ;GVPAGS DOESN'T GET CONFUSED
PUSHJ P,GVPAGS## ;ADD THE PAGES SET ON LINE TO THE FREE CORE LIST
;FINISH UP
PUSHJ P,CPINXF## ;FIX CORE ALLOCATION VARIABLES
JFCL ;CORMAX MAY HAVE CHANGED, BUT ALL JOBS WILL STILL FIT
IFN FTMP,<
PUSHJ P,DWNMM## ;GIVE UP THE MM
>; END IFN FTMP
MOVE T1,[.CSCMO,,.ERCSC]
PJRST DAEEIM## ;TELL DAEMON CONFIGURATION HAS CHANGED AND RETURN
;ROUTINE TO ZERO THE PAGE BEING SET ON-LINE AND CHECK FOR NXM.
;CALL WITH T1=PAGE NUMBER, P1=BYTE POINTER TO NXMTAB
;RETURNS CPOPJ IF NXM, CPOPJ1 IF PAGE OK.
;MUST BE CALLED WITH MM, RETURNS WITH MM.
;PRESERVES T1-T4.
MEMOZR: PUSHJ P,SAVT## ;SAVE T1-T4
HRRZ T3,T1 ;GET PAGE NUMBER
MOVE T4,.CPMAP## ;GET ADDRESS OF EXEC MAP
HRLI T3,(<PM.DCD>B2+PM.WRT) ;ACCESSIBLE AND WRITABLE
MOVEM T3,.EUPMP/PAGSIZ(T4) ;SET NEW MAPPING FOR PAGE
CLRPT .EUPMP ;FLUSH PAGE TABLE SO NEW MAPPING IS IN EFFECT
IFN FTMP,<
PUSHJ P,DWNMM## ;GIVE UP THE MM IN CASE NXM HAPPENS
>; END IFN FTMP
MOVEI T4,1000 ;TIME TO WAIT FOR NXM TO CAUSE AN INTERRUPT
MOVEM J,MOFLPG## ;FLAG WE ARE SETTING MEMORY OFF-LINE
SETZM .EUPMP ;ZERO FIRST WORD OF PAGE
SOJG T4,. ;WAIT LONG ENOUGH FOR NXM INTERRUPT TO HAPPEN
LDB T3,P1 ;GET BIT FROM NXMTAB
JUMPN T3,MEMOZ1 ;JUMP IF NXM HAPPENED
MOVE T3,[XWD .EUPMP,.EUPMP+1] ;SET TO CLEAR REMAINDER OF PAGE
MOVEI T4,1000 ;TIME TO WAIT FOR NXM TO CAUSE AN INTERRUPT
BLT T3,.EUPMP+PG.BDY ;ZERO THE REMAINDER OF THE PAGE
SOJG T4,. ;WAIT LONG ENOUGH FOR NXM INTERRUPT TO HAPPEN
LDB T3,P1 ;GET BIT FROM NXMTAB
SKIPN T3 ;DID NXM HAPPEN?
AOS (P) ;NO, SET UP SKIP RETURN
MEMOZ1: SETZM MOFLPG## ;NO LONGER CHECKING FOR OFFLINE PAGE
IFN FTMP,<
PUSHJ P,UPMM## ;GET BACK THE MM
>; END IFN FTMP
POPJ P, ;RETURN
SETME1: SKIPN [M.LOK##] ;MUST HAVE THE LOCK UUO TO SET MEMORY OFF
JRST COMERA ;ERROR IF LOKCON NOT LOADED
PUSHJ P,CKMOL## ;CHECK THAT RANGE DOESN'T OVERLAP THE MONITOR
JRST SETME6 ;IT DOES SO WE CAN'T DO IT
LDB T3,[POINT 14,NWCORE##,26] ;GET TOTAL SIZE (ON OR OFF)
CAIL T1,(T3) ;LOWER BOUND BEYOND END?
POPJ P, ;YES, IT'S ALREADY OFF
CAIL T2,(T3) ;UPPER BOUND BEYOND END?
MOVE T2,T3 ;YES,CHANGE UPPER BOUND
PUSH P,T1 ;SAVE LOWER BOUND
PUSH P,T2 ;AND UPPER BOUND
MOVEI P1,[ASCIZ /?Job(s) too big to continue to run/]
PUSHJ P,NEWCMX## ;SEE IF ALL JOBS CAN CONTINUE TO RUN
JUMPLE T1,[POP P,(P) ;IF .LE. 0, TRYING TO SET MONITOR MEMORY OFF LINE
POP P,(P)
JRST SETME6];GO EXPLAIN THE PROBLEM
PUSH P,J ;SAVE J FOR COMRET
MOVEI J,0 ;STARTING WITH JOB 0,
SETME3: PUSHJ P,JBSTBG## ;MAKE SURE ALL JOBS CAN STILL RUN (I.E., NONE IS TOO BIG)
JRST SETME4 ;NONE ARE
PUSHJ P,MOLMS ;TELL THE OPR ABOUT THIS JOB
JRST SETME3 ;AND LOOK FOR MORE THAT ARE TOO BIG
SETME4: JUMPE P1,SETME7 ;EXIT IF SOME JOBS WERE TO BIG
MOVEI P1,[ASCIZ /?Attempt to set memory containing locked jobs off-line/]
MOVEI J,0 ;STARTING WITH JOB 0,
MOVE T1,-2(P) ;LOWER BOUND,
SETME5: MOVE T2,-1(P) ;UPPER BOUND,
PUSHJ P,CKLJB## ;SEE IF RANGE OVERLAPS SOME LOCKED JOB
JRST SETME7 ;IT DOESN'T SO ALL IS WELL
PUSHJ P,MOLMS ;TELL THE OPR ABOUT THIS JOB
JRST SETME5 ;AND LOOP TO SEE IF THERE ARE ANY MORE IN THE WAY
SETME6: JSP T1,ERRMES ;PRINT THE ERROR MESSAGE
ASCIZ /Attempt to set monitor memory off-line/
SETME7: POP P,J ;RESTORE J FOR COMRET
POP P,T2 ;RESTORE UPPER BOUND
POP P,T1 ;AND LOWER BOUND
JUMPE P1,PCRLF ;EXIT IF THERE WAS AN ERROR
PJRST MEMOFL## ;GO SET THE MEMORY OFF-LINE
MOLMS: PUSH P,T1 ;SAVE T1
SKIPE T1,P1 ;SKIP IF ERROR MESSAGE WAS ALREADY TYPED
PUSHJ P,CONMES ;TYPE THE ERROR MESSAGE
MOVEI T1,[ASCIZ/
?Problem with job(s)/]
SKIPE P1 ;SAY PROBLEM WITH JOBS ONCE
PUSHJ P,CONMES ;TYPE THAT
MOVEI P1,0 ;FLAG AN ERROR AND DON'T PRINT ERROR HEADING TWICE
TLO M,ERRFLG ;TELL COMRET THAT THERE WAS AN ERROR
PUSHJ P,PRJBNM## ;DISPLAY INFO. ABOUT THE PROBLEM JOB
JRST TPOPJ## ;RESTORE T1, AND RETURN
SUBTTL SET COMMAND AND UUO -- DAYTIME AND SCHED
SETDAY::PUSHJ P,SETLGL
JRST COMERA
PUSHJ P,RDTIM ;GET TIME OF DAY
PJRST ERRCRL ;ISSUE CRLF/ERROR MESSAGE AND RETURN
JRST SETDA3 ;SKIP AROUND SETUUO CHECK
SETDA0:
IFN FTMP,< ;IF SMP
PUSHJ P,ONCPU0## ;RUN ON POLICY CPU
>; END IFN FTMP
CAIL T2,<^D24*^D60*^D60> ;RANGE CHECK IT
JRST ECOD3## ;ILLEGAL TIME (GREATER THAN 23:59:59)
MOVE T1,T2 ;SHUFFLE TIME TO SAME AC RDTIM USES
SETDA3::MOVE T4,T1 ;SAVE RESULT
IDIVI T1,^D60*^D60 ;T1:= HOURS
IDIVI T2,^D60 ;T2:= MINUTES, T3:= SECONDS
MOVEM T1,LOCHOR## ;SAVE HOURS
MOVEM T2,LOCMIN## ;SAVE MINUTES
MOVEM T3,LOCSEC## ;SAVE SECONDS
IMUL T4,TICSEC## ;CONVERT TO JIFFIES
MOVEM T4,TIME## ;SAVE IT
MOVEM T4,.CPTML## ;SAVE TIME AT THE LAST CLOCK TIC
MOVEI T1,.C0CDB## ;POINT AT FIRST CDB
MOVN T2,T3 ;GET -SECONDS
ADDI T2,^D60 ;GET SECONDS 'TIL NEXT MINUTE
MOVE T3,TICSEC## ;TIME TO NEXT SECOND
JRST SETDA2 ;ENTER COMMON CODE
SETDA1:
IFN FTMP,< ;IF SMP
PUSHJ P,ONCPU0## ;RUN ON POLICY CPU
>;END IFN FTMP
IDIVI T2,^D100 ;HOURS INTO T2
MOVEM T3,LOCMIN##
MOVEM T2,LOCHOR##
SETZM LOCSEC## ;ZERO SECOND COUNTER
IMULI T2,^D60 ;CONVERT HOURS TO MINS
ADD T2,T3 ;+ORIGINAL MINS
IMUL T2,TICMIN## ;CONVERT TO JIFFIES
MOVEM T2,TIME## ;SAVE AS NEW TIME
MOVEM T2,.CPTML##
MOVEI T1,.C0CDB## ;POINT AT FIRST CDB
MOVEI T2,^D60 ;TIME TO NEXT MINUTE
MOVE T3,TICSEC## ;TIME TO NEXT SECOND
SETDA2: MOVEM T2,.CPSEC##-.CPCDB##(T1) ;STORE IN THIS CDB
MOVEM T3,.CPHTM##-.CPCDB##(T1) ;TIME TO NEXT SECOND
HLRZ T1,.CPCDB##-.CPCDB##(T1) ;STEP TO NEXT
JUMPN T1,SETDA2 ;LOOP FOR ALL
PUSHJ P,OMSTIM## ;RECOMPUTE OPR MESSAGE TIME
PJRST SETDT2 ;FIXUP 'DATE' & SKIP RETURN
SETSCD::PUSHJ P,SETLGL ;CHECK FOR LEGALITY
JRST COMERA ;NOT LEGAL
PUSHJ P,OCTIN1 ;OK - GET OCTAL NUMBER
PJRST NOTENF ;NOT ENOUGH ARGS
PJRST COMERA ;ILLEGAL NUMBER
SETSC1: HRRZ T1,STATES## ;GET OLD SCHEDULE
HRRM T2,STATES## ;SET NEW SCHEDULE
CAIE T1,(T2) ;OLD AND NEW THE SAME?
PUSHJ P,SNDSCM## ;NO, TELL QUASAR IT CHANGED
JFCL
JRST CPOPJ1## ;AND SKIP RETURN
SETIM1: IMUL T2,TICSEC## ;CONVERT TO JIFFIES
MOVSI T3,(JB.LBT) ;GET BATCH BIT
TDNN T3,JBTLIM##(J) ;BATCH JOB?
JRST SETIM2 ;NO, GO STORE
LDB T3,JBYLTM## ;YES, LAST CHANCE
JUMPE T3,SETIM2 ;CAN ALWAYS ADD RESTRICTIONS
PUSHJ P,PRVJC ;IS HE [1,2] OR JACCT?
JRST SETIM2 ;LET HIM THROUGH
PJRST RTZER## ;NO, BOMB HIM
SETRTM::PUSHJ P,DECIN1 ;GET DECIMAL NO OF SECS
PJRST NOTENF ;NOT ENOUGH ARGS
PJRST COMERA ;NOTA NUMBER
IMUL T2,TICSEC## ;CONVERT TO JIFFIES
TLNE T2,(-JB.LTM-1) ;SEE IF TOO BIG
PJRST COMERA ;YES. ERROR
MOVEI T1,BATMSG
LDB T3,JBYLTM##
JUMPE T3,SETIM2
MOVE T3,JBTLIM##(J)
TLNE T3,(JB.LBT)
JRST ERRMES
SETIM2: DPB T2,JBYLTM##
JRST CPOPJ1## ;AND RETURN
SUBTTL SET COMMAND AND UUO -- OPR, LOGMIN&MAX BATMIN##&MAX
SETOPR::PUSHJ P,SETLGL ;SEE IF SET OPR LEGAL
JRST COMERA ;NOT LEGAL
PUSHJ P,CTEXT1 ;GET NAME OF DEVICE
MOVE T1,T2 ;MOVE FOR STDOPR
PUSHJ P,STDOPR## ;SET IT
PJRST COMERA ;NO GOOD
POPJ P,0 ;GOOD
SETOP1: HRR M,T2 ;UUO, GET ADDRESS
PUSHJ P,GETWDU## ;GET CONTENTS IF LEGAL
PUSHJ P,STDOPR## ;CHANGE DEVICE
JRST ECOD0## ;ERROR RETURN
JRST CPOPJ1## ;GOOD RETURN
;LOGIN CONTROL PARAMETERS
SETLMX: CAIL T2,1 ;LOGMAX MUST BE .GE. 1
CAILE T2,M.JOB## ; AND .LE. M.JOB
JRST ECOD0##
MOVEM T2,LOGMAX##
JRST CPOPJ1##
SETBMX: CAIL T2,0 ;BATMAX MUST BE .GE. 0
CAILE T2,M.JOB## ; AND .LE. M.JOB
JRST ECOD0##
MOVEM T2,BATMAX##
JRST CPOPJ1##
SETBMN: CAIL T2,0 ;BATMIN MUST BE .GE. 0
CAMLE T2,BATMAX## ; AND .LE. BATMAX
JRST ECOD0##
MOVEM T2,BATMIN##
JRST CPOPJ1##
;SET QUEUE STRUCTURE
SETQST: HRR M,T2 ;GET ADDR OF USER'S ARG
PUSHJ P,GETWDU## ;GET THE ARGUMENT
SKIPE T1 ;WEED OUT JUNK
PUSHJ P,SRSTR## ;MAKE SURE ITS A KNOWN STR
PJRST ECOD2## ;LOSE - ILLEGAL STRUCTURE
MOVEM T1,QUESTR## ;SAVE FOR % LDQUS GETTAB
JRST CPOPJ1## ;RETURN
SUBTTL SET COMMAND AND UUO -- WATCH
SETWAT::PUSHJ P,SAVE1## ;SAVE P1
MOVE P1,[IORM T2,JBTWCH##(J)] ;WE'RE CHANGING JBTWCH(J)
PUSHJ P,CTEXT ;GET 1ST ARG
JUMPE T2,WATLP1 ;ERROR IF MISSING
SKIPA T1,[-WATLEN-NOTLEN,,WATTAB] ;SCAN BOTH TABLES 1ST TIME
WATLOP: MOVE T1,[-WATLEN,,WATTAB] ;POINT TO TABLE
PUSHJ P,FNDNAM ;LOOK FOR ABBREV.
JRST WATLP1 ;ERROR
CAIL T1,NOTTAB-WATTAB ;SEE IF IN NOTTAB
JRST WATCH2 ;YES, MUST BE NO, ALL, NONE
MOVNI T1,(T1) ;-NO. OF ENTRY IN TABLE
MOVSI T2,JW.WCX ;FIRST BIT
ROT T2,(T1) ;ROTATE RIGHT TO PROPER POSITION
WATCH1: XCT P1 ;ANDCAM OR IORM T2,JBTWCH(J)
PUSHJ P,CTEXT ;GET NEXT ARG
JUMPE T2,CPOPJ## ;0 IF FINISHED OR NONE
JRST WATLOP ;AND SET A BIT FOR IT
WATCH2: SUBI T1,WATLEN ;RELATIVE TO NOTTAB
TRNN T1,1 ;NO OR NONE?
HRLI P1,(ANDCAM T2,(J)) ;YES
MOVSI T2,WCHALL ;READY FOR ALL,NONE
JUMPN T1,WATCH1 ;YES IT IS
PUSHJ P,CTEXT ;GET ARG OF NO
JUMPN T2,WATLOP ;SEE IF VALID
WATLP1: JSP T1,ERRMES ;NO, TELL USER THE LEGAL ONES
ASCIZ /Args are: contexts,day,run,wait,read,write,version,mta,files,all,none/
$LOW
WATTAB::<SIXBIT /CONTEXTS/>
<SIXBIT /DAY/>
<SIXBIT /RUN/>
<SIXBIT /WAIT/>
<SIXBIT /READS/>
<SIXBIT /WRITES/>
<SIXBIT /VERSION/>
<SIXBIT /MTA/>
<SIXBIT /FILES/>
;ADD NEW ITEMS HERE AND IN ERROR COMMENT AND IN S.MAC
WATLEN==.-WATTAB
WTCMXL==:<WATLEN-1>B26
;THIS TABLE MUST BE IN ORDER NO, ALL, NONE
;AND MUST FOLLOW WATTAB
NOTTAB: <SIXBIT /NO/>
<SIXBIT /ALL/>
<SIXBIT /NONE/>
NOTLEN==.-NOTTAB
$HIGH
SUBTTL SET COMMAND AND UUO -- DATE
SETDAT::PUSHJ P,SETLGL ;TEST FOR LEGALITY
JRST COMERA ;NOT PRIVILEGED
PUSHJ P,SAVE3## ;FRE UP SOME ACS
MOVE P1,LOCYER## ;SAVE THE OLD DATE
MOVE P2,LOCMON##
MOVE P3,LOCDAY##
MOVEI T1,LOCYER##
PUSHJ P,GTDATE ;ACCEPT E.G. 3-JAN-72
JRST [MOVEM P1,LOCYER## ;RESTORE OLD DATE
MOVEM P2,LOCMON##
MOVEM P3,LOCDAY##
JRST COMERR] ;BAD DATA
SETDT2: AOS (P) ;SKIP RETURN
PUSH P,DATE## ;SAVE OLDDAE
PUSHJ P,SUDATE## ;RECOMPUTE UNIV. DATE
POP P,T1 ;GET OLD DATE BACK
SUB T1,DATE## ;SUBTRACT NEW FROM OLD
MOVNS T1 ;MAKE IT ADDITIVE
MOVE T2,HIGHJB## ;GET HIGHEST JOB ASSIGNED
SETDT3: SKIPE JBTJLT##(T2) ;ANYTHING THERE?
ADDM T1,JBTJLT##(T2) ;YES, ADJUST IT
HRRZ T3,JBTPDB##(T2) ;GET PDB ADDR
CAIE T3,0 ;SEE IF THERE
ADDM T1,.PDSTM##(T3) ;YES ADJUST IT
SOJG T2,SETDT3 ; AND LOOP
SKIPE RSDTTM## ;LAST CPU ROLE SWITCH?
ADDM T1,RSDTTM## ;YES--UPDATE IT
IFN FTNSCHED,<
SKIPE SCDSTS## ;LAST SETTING OF SCHEDULER PARAMETERS?
ADDM T1,SCDSTS## ;YES--UPDATE IT
>;END IFN FTNSCHED
SKIPE SCDSET## ;..
ADDM T1,SCDSET## ;YES
PUSHJ P,FILSDT## ;TELL FILSER TO FIX THINGS UP
PUSHJ P,ENQSDT## ;AND QUESER
PUSHJ P,PSISDT## ;SIGNAL USERS TOO
PUSH P,F ;SAVE F AROUND CALL TO DAEMON
HRRZ U,T1 ;TIME PART
HLRZ F,T1 ;DATE PART
MOVE T1,[.CSCTC,,.ERCSC] ;DATE OR TIME CHANGE
PUSHJ P,DAERPT## ;TELL DAEMON
POP P,F ;RESTORE F
IFN FTKL10,<
PUSHJ P,THSDA## ;RECOMPUTE 12 BIT DATE
PJRST COMSDT## ;TELL ANY FRONT ENDS THAT NEED TELLING
; ABOUT NEW DATE. COUNT ON SET DAYTIME
; GETTING HERE WITH NEW TIME ALSO.
>;END IFN FTKL10
IFN FTKS10,<
PJRST THSDA## ;RECOMPUTE 12 BIT DATE AND RETURN
>;END IFN FTKI10!FTKS10
SETDT1:
IFN FTMP,< ;IF SMP
PUSHJ P,ONCPU0## ;RUN ON POLICY CPU
>;END IFN FTMP
IDIVI T2,^D31 ;DECOMPOSE 12 BIT DATE INTO LOCYER...
AOS T3
MOVEM T3,LOCDAY##
IDIVI T2,^D12
AOS T3
MOVEM T3,LOCMON##
ADDI T2,^D1964
MOVEM T2,LOCYER##
JRST SETDT2 ;GO MAKE & STORE THSDAT & DATE
SETKSY::
IFN FTMP,< ;IF SMP
PUSHJ P,ONCPU0## ;RUN ON POLICY CPU
>; END IFN FTMP
CAIN T2,-1 ;KSYS NOW?
SETOM T2 ;YES
MOVEM T2,SYSKTM## ;STORE VALUE FOR CLOCK1
PUSHJ P,PSIKSY## ;TELL EVERYONE OF CHANGE
JRST CPOPJ1## ;RETURN
SUBTTL SET COMMAND AND UUO -- SPOOL
SETSPL::PUSHJ P,SAVE2## ;SAVE P1
MOVE P1,[IORM T2,JBTSPL##(J)] ;WE'RE CHANGING JBTSPL
PUSHJ P,CTXDEV ;GET 1ST ARG
JUMPE T2,NOTENF ;NOT ENOUGH ARGS
MOVE T1,[-NOTLEN,,NOTTAB]
PUSHJ P,FNDNAM ;SEE IF NO. ALL, NONE
JRST SETSP0 ;NO, SEE IF DEVICE
TRNN T1,1 ;IS IF NO OR NONE
HRLI P1,(ANDCAM T2,(J)) ;YES, TURN OFF BIT
JUMPN T1,SETSP3 ;ALL OR NONE?
PUSHJ P,CTXDEV ;NO, GET ARG FOR NO
JUMPE T2,NOTENF ;NOT ENOUGH ARGS
SETSP0: MOVEI F,SPLTAB## ;POINT TO SPOOL TABLE
TRNN T2,-1 ;DID HE SPEC A PHYS DEV?
JRST SETSP1 ;NO ALL IS OK
JSP T1,ERRMES ;YES, GIVE A MESSAGE
ASCIZ /Cannot spool a physical device
/
SETSP1: CAMN T2,SPLNAM##(F) ;HATCH?
JRST SETSP2 ;YES!
ADDI F,SPLLEN## ;BUMP TO NEXT CARRY
CAIGE F,SPLTOP## ;DONE?
JRST SETSP1 ;NO, LOOP
JSP T1,ERRMES ;YES, NOT FOUND
ASCIZ /Not a spoolable device
/
SETSP2: HRRZ T2,SPLBIT##(F) ;GET THE SPOOL BIT
SKIPA ;SKIP ALTERNATE ENTRY
SETSP3: MOVEI T2,.SPALL ;ALL OR NONE
TLNE P1,20000 ;P1 AN ANDCAM?
JRST SETSP4 ;NO - ALWAYS ALLOWED TO SET SPOOLING
MOVSI T1,PVNSPL ;PRIV?
TSNN T1,STATES## ;OR SCHED BIT?
PUSHJ P,PRVBIT ;90 SEC.
;NOTE THIS CODE DEPENDS ON PVNSPL=ST.NSP
IFN PVNSPL-ST.NSP,<PRINTX ST.NSP DOESN'T=PVNSPL>
JRST SETSP4 ;YES - OK
JSP T1,ERRMES ;NO - TYPE THE MESSAGE:
ASCIZ /No privs to unspool
/
SETSP4: XCT P1 ;TURN ON/OFF SPOOL BIT(S)
MOVE F,LDBDDB##(U) ; AND F
PUSHJ P,CTXDEV ;GET NEXT DEV
JUMPE T2,CPOPJ## ;RETURN IF NOTHING
JRST SETSP0 ;AND SET ITS BIT
SUBTTL SET COMMAND AND UUO -- DEFER/NODEFER - BATCH STREAM - WTO - OPER PRIV
;ENTER HERE ON SETUUO FOR DEFER/NODEFER
SETDFU: JUMPE T2,SETNDC ;ZERO MEANS NO-DEFERED
; ELSE FALL INTO DEFER
;ENTER HERE ON SET DEFER COMMAND
SETDFC::MOVEI T2,JB.DFR ;GET DEFER BIT
IORM T2,JBTSPL##(J) ;SET IT
JRST CPOPJ1## ;RETURN
;ENTER HERE ON SET NODEFER COMMAND
SETNDC::MOVEI T2,JB.DFR ;GET DEFER BIT
ANDCAM T2,JBTSPL##(J) ;CLEAR IT
JRST CPOPJ1## ;RETURN
;ENTER HERE ON SETUUO FOR BATCH-STREAM-NUMBER
SETBSN: MOVSI T1,(JB.BSS) ;LOAD "ALREADY SET" BIT
TDNE T1,.PDOBI##(W) ;TEST IT
JRST ECOD0## ;SET ALREADY!
DPB T2,PDYBSN## ;STORE VALUE
IORM T1,.PDOBI##(W) ;SET BIT
JRST CPOPJ1## ;RETURN
;ENTER HERE ON SETUUO FOR WTO CAPABILITIES
SETWTO: DPB T2,PDYWTO## ;STORE VALUE
JRST CPOPJ1## ;AND RETURN
;ENTER HERE ON SET OPER PRIVILEGE
SETOPP: DPB T2,PDYOPP##
JRST CPOPJ1##
SUBTTL SET COMMAND AND UUO -- DEFAULTS
SETDFL::PUSHJ P,CTEXT ;GET DEFAULT ARGUMENT MODIFIER
JUMPE T2,NOTENF ;MUST BE ONE
MOVE T1,[-DFLTTL,,DFLTTB] ;ARGUMENT FOR FNDNAM
PUSHJ P,FNDNAM ;SEE IF A LEGAL MODIFIER WAS SPECIFIED
JRST COMERA ;BAD ARGUMENT
TLNN P4,JLOG
SKIPGE DFLCTB(T1)
JRST @DFLCTB(T1) ;DISPATCH TO SET THE DEFAULT
JRST STARTE
;HERE ON SET DEFAULT UUO
SETDLU: HRR M,T2 ;ADDRESS OF FUNCTION CODE
PUSHJ P,GETWDU## ;GET THE FUNCTION CODE
HLRZ T2,T1 ;NUMBER OF ARGUMENTS
HRRZS T1 ;FUNCTION CODE
CAILE T1,DFLUTL ;IS IT A DEFINED FUNCTION CODE?
JRST ECOD0## ;NO, ERROR RETURN
JRST @DFLUTB(T1) ;DISPATCH TO SET THE DEFAULT
DEFINE NAMES<
C PROTECTION,DFLPRT,0
C BUFFERS,DFLBFN,0
C ACCOUNT,DFLACS,400000
C BIGBUF,DFLBBC,0
>
DEFINE C(A,B,D,E)<
IFNB<E>,<E:>
<SIXBIT /A/>
>
XALL
DFLTTB::NAMES
DFLTTL==.-DFLTTB
DFLMXL==:<DFLTTL-1>B26
DEFINE C(A,B,D,E)<
XWD D,B
>
DFLCTB: NAMES
DFLUTB: EXP DFLPRU
EXP DFLBFU
EXP DFLDAU
EXP DFLBBU
DFLUTL==.-DFLUTB-1
SALL
;HERE ON SET DEFAULT PROTECTION COMMAND
DFLPRT: MOVE T1,[-2,,[SIXBIT /ON/
SIXBIT /OFF/]]
PUSHJ P,TXTARG ;WAS "ON OR OFF" TYPED?
JRST DFLPR0 ;NO
JUMPE T1,DFLPR1 ;JUMP IF ON WAS TYPED
MOVSI T1,(PD.DPS) ;YES, CLEAR THE BIT WHICH SAYS
ANDCAM T1,.PDDFL##(W) ; DEFAULT PROTECTION WAS SET
POPJ P, ;AND RETURN
DFLPR0: PUSHJ P,SKIPS1 ;SKIP BLANKS, TABS, ETC.
JFCL ;IGNORE
CAIN T3,074 ;WAS A BRACKET TYPED ?
PUSHJ P,COMTYS ;YES, FLUSH IT.
PUSHJ P,OCTIN1 ;READ THE PROTECTION VALUE
JRST NOTENF ;IT MUST BE THERE
JRST COMERA ;ILLEGAL CHARACTER
TDNE T2,[-1,,777000] ;LEGAL PROTECTION VALUE ?
JRST COMERA ;NO, COMPLAIN
DPB T2,PDYDPT## ;STORE DEFAULT PROTECTION
JRST DFLPR1 ;AND INDICATE A DEFAULT WAS SPECIFIED
;HERE ON SET DEFAULT PROTECTION UUO
DFLPRU: PUSHJ P,GETWD1## ;GET THE PROTECTION VALUE
TDNE T1,[-1,,777000] ;LEGAL ?
JRST ECOD0## ;NO, ERROR RETURN
DPB T1,PDYDPT## ;STORE DEFAULT PROTECTION
DFLPR1: MOVSI T1,(PD.DPS) ;DEFAULT PROTECTION SPECIFIED BIT
IORM T1,.PDDFL##(W) ;LITE THAT
JRST CPOPJ1## ;AND GIVE GOOD RETURN
;HERE ON SET DEFAULT NUMBER OF BUFFERS COMMAND
DFLBFN: PUSHJ P,DECIN ;READ NUMBER
JRST NOTENF ;NOT THERE
JRST COMERA ;NOT A NUMBER
TDNE T2,[-1,,777000] ;IN RANGE?
JRST COMERA ;NO, ERROR
SKIPA T1,T2 ;YES, STORE DEFAULT NUMBER
;HERE ON SET DEFAULT BUFFERS UUO
DFLBFU: PUSHJ P,GETWD1## ;GET ARGUMENT
TDNE T1,[-1,777000] ;IN RANGE?
JRST ECOD0## ;NO, ERROR
DPB T1,PDYBFN## ;STORE DEFAULT NUMBER OF DISK BUFFERS
JRST CPOPJ1## ;AND GIVE GOOD RETURN
;HERE ON SET DEFAULT DON'T ASK ABOUT DETACHED JOBS UUO
DFLDAU: PUSHJ P,GETWD1## ;GET ARGUMENT
MOVE T2,.PDDFL##(W) ;DEFAULT WORD
SKIPN T1 ;SET?
TLZA T2,(PD.DAD) ;NO, CLEAR
TLO T2,(PD.DAD) ;YES
MOVEM T2,.PDDFL##(W) ;STORE ANSWER
JRST CPOPJ1## ;AND GIVE GOOD RETURN
;HERE TO SET DEFAULT ACCOUNT STRING (USED FOR JOBS LOGGED IN ON FRCLIN)
DFLACS: PUSHJ P,SETLGL ;MUST BE OPR
JRST COMERA ;NOT, COMPLAIN
PUSHJ P,SAVE2## ;WORKING ACS
HRRZ P1,JBTPDB##+0 ;NULL JOB'S PDB
ADD P1,[POINT 7,.PDACS##] ;WHERE TO STORE DEFAULT
HRREI P2,5*ACTSTL##-1 ;LENGTH OF ACCOUNT STRING
JUMPLE P2,COMERA ;FORGET IT IF ZERO LENGTH
DFLAC1: PUSHJ P,COMTYI## ;NEXT CHARACTER
CAIE T3,12 ;LINEFEED?
CAIN T3,3 ;OR CONTROL C
JRST DFLAC2 ;YES, THAT'S ALL FOLKS
IDPB T3,P1 ;NO, STORE THE CHARACTER
SOJG P2,DFLAC1 ;LOOP FOR MORE
DFLAC2: MOVEI T1,0 ;ASCIZIZE
IDPB T1,P1
POPJ P, ;RETURN
;HERE ON SET DEFAULT BIGBUF COMMAND
DFLBBC: PUSHJ P,DECIN ;GET THE NUMBER OF BLOCKS PER BUFFER
JRST NOTENF ;NOT THERE
JRST COMERA ;NOT A NUMBER
MOVE T1,T2
CAILE T1,LIMBBF ;IN RANGE?
JRST COMERA ;NO, ERROR
TLO M,400000 ;SET THAT IT GETS SET PERMANENTLY
JRST DFLBB2
;HERE ON SET DEFAULT BIGBUF UUO
DFLBBU: PUSHJ P,GETWD1##
TLNN T1,-1 ;SET JOB-WIDE DEFAULT?
JRST DFLBB1 ;NO, CONTINUE
HLRZS T1 ;YES, MAKE IT AN RH QUANTITY
TLO M,400000 ;PRETEND WE HAVE A COMMAND
DFLBB1: CAILE T1,LIMBBF## ;IN RANGE?
JRST ECOD0## ;NO, ERROR
DFLBB2: LSH T1,BLKLSH## ;YES, CONVERT TO NUMBER OF WORDS
SKIPE T1 ;CLEAR IT IF ARGUMENT IS 0
ADDI T1,1
SKIPL M ;UUO?
HRLM T1,.PDLBS##(W) ; SAVE IN PDB
SKIPGE M ;COMMAND?
HRRM T1,.PDLBS##(W) ; SAVE IN PBD
JRST CPOPJ1## ;AND TAKE GOOD RETURN
SUBTTL SET COMMAND AND UUO -- BREAK
IFN FTKS10,<
;NO ADDRESS BREAK
XP SETBRK,COMERA
XP SETABR,CPOPJ##
XP CLRBRK,CPOPJ##
>
IFN FTKL10,<
;HERE IF THE USER TYPED SET BREAK
SETBRK::PUSHJ P,SAVE2## ;SAVE P1,P2
PUSHJ P,FNDPDS## ;FIND THE PDB FOR THIS USER
MOVSI P1,400000 ;NO NUMBER SEEN YET
PUSHJ P,OCTPRG ;SEE IF FIRST ARGUMENT IS A NUMBER
JRST SETBR2 ;NOT A NUMBER, LOOK FOR LEGAL TEXT
SETBR1: MOVE P1,T2 ;NUMBER TO P1
CAIG P1,17 ;WEED OUT REFERENCES
CAIGE P1,1 ; TO THE ACS
CAMLE P1,[MXSECN,,-1] ;REPORT THIS AS AN ERROR RATHER THAN CONFUSING USER
JRST COMERA ;COMPLAIN
DPB P1,[POINT 23,.PDABS##(W),35] ;STORE BREAK ADDRESS
PUSHJ P,SGSEND ;SEE IF EOL
JRST SETBR2 ;NO, READ NEXT ARGUMENT
SKIPN P2,P1 ;BREAK ADDRESS ZERO?
JRST SETB10 ;YES, TREAT SET BREAK 0 WITH NO CONDITION LIKE NONE
HLLZ P2,.PDABS##(W) ;GET PREVIOUS CONDITIONS IF ANY
TLZ P2,(OC.BSU) ;CLEAR SET BY UUO
SETB1A: TLNN P2,(OC.BCI+OC.BCD+OC.BCW+OC.BCM) ;WERE THERE ANY PREVIOUSLY?
TLO P2,(OC.BCI+OC.BCD+OC.BCW) ;NO, ASSUME ALL
JRST SETBR8 ;ENABLE BREAK, STORE CONDITIONS, AND GO AWAY
SETBR2: MOVE T1,[-4,,BRKLS1] ;TABLE LENGTH,,ADDRESS OF THE TABLE
PUSHJ P,TXTARG ;RECOGNIZABLE TEXT ARGUMENT?
JRST SETBR5 ;NO, POSSIBLY IN ANOTHER CONTEXT
MOVE P2,T1 ;INDEX INTO BRKTBL
JUMPN T1,SETBR3 ;JUMP IF THE USER DIDN'T TYPE 'NONE'
;HERE WHEN THE USER TYPED 'NONE'
JUMPGE P1,COMERA ;IF A NUMBER WAS TYPED WE SHOULDN'T BE HERE
JRST SETB10 ;GO CLEAR BREAK CONDITIONS
SETBR3: PUSHJ P,SGSEND ;AT END OF LINE?
CAIA ;NO
JRST NOTENF ;IF WE'RE HERE THERE HAS TO BE ONE
JRST .(P2) ;DISPATCH TO THE APPROPRIATE PROCESSOR
JRST SETBR4 ;USER TYPED 'AT'
JRST SETBR5 ;USER TYPED 'ON'
JRST SETBR6 ;USER TYPED 'NO'
;HERE WHEN THE USER TYPED 'AT'
SETBR4: JUMPGE P1,COMERA ;NO PREVIOUS NUMBERS ALLOWED IF WE GET HERE
PUSHJ P,OCTPRG ;READ A NUMBER
JRST COMERA ;IT MUST BE A NUMBER BUT ISN'T SO COMPLAIN
JRST SETBR1 ;LOOK FOR THE NEXT TEXT ARGUMENT
;HERE WHEN THE USER TYPED 'ON'
SETBR5: SKIPA P1,[TDO P2,BRKTBL-1(T1)]
;HERE WHEN THE USER TYPED 'NO'
SETBR6: MOVE P1,[TDZ P2,BRKTBL-1(T1)]
HLLZ P2,.PDABS##(W) ;GET CURRENT BREAK CONDITIONS
TLZ P2,(OC.BSU) ;CLEAR SET BY UUO
SETBR7: MOVE T1,[-7,,BRKLS2] ;TABLE LENGTH,,TABLE ADDRESS
PUSHJ P,TXTARG ;GET A BREAK CONDITION
JRST COMERA ;IT CAN'T BE ANYTHING ELSE
JUMPE T1,SETB11 ;JUMP IF 'USERS'
CAIN T1,AFTERX
JRST SETB12
XCT P1 ;SET OR CLEAR THE CONDITION
PUSHJ P,SGSEND ;LAST ARGUMENT?
JRST SETBR7 ;NO, CHECK NEXT ARGUMENT
TLZ P2,(OC.ABE+OC.FUP) ;ASSUME NO CONDITIONS
TLNN P2,(OC.BCI+OC.BCD+OC.BCW+OC.BCM) ;ANY CONDITIONS DESIRED?
JRST SETB10 ;NO, DECREMENT NUMBER OF USERS USING ADDRESS BREAK
SETBR8: PUSHJ P,BRKAV ;SEE IF ADDRESS BREAK IS AVAILABLE AND INCREMENT
; THE COUNT OF USERS USING IT IF SO
JRST NOBRAK ;NOT AVAILABLE, COMPLAIN
SETBR9: TLOA P2,(OC.ABE+OC.FUP) ;ENABLE THE USER FOR ADDRESS BREAK
SETB10: PUSHJ P,BRKDEC ;DECREMENT THE COUNT OF USERS USING ADDRESS BREAK
LSH P2,-^D23 ;POSITION BITS
DPB P2,[POINT 13,.PDABS##(W),12] ;STORE NEW CONDITIONS
POPJ P, ;AND RETURN TO COMCON
;HERE WHEN THE USER TYPED 'USERS', MUST BE PRIVILEGED
SETB11: PUSHJ P,SETLGL ;USER SUFFICIENTLY PRIVILEGED TO MONOPOLIZE
; ADDRESS BREAK?
JRST COMERA ;NO, COMPLAIN
PUSHJ P,FDNJP ;FIND THE NULL JOB'S PDB
MOVSI T2,400000 ;SET TO TURN ON OR OFF ADDRESS BREAK
CAME P1,[TDZ P2,BRKTBL-1(T1)] ;WAS 'USERS' WITHOUT A 'NO' TYPED?
JRST [ANDCAM T2,.PDABS##(T1) ;YES, ALLOW USERS TO USE ADDRESS BREAK
POPJ P,] ;RETURN
;HERE WHEN THE USER TYPED 'NO USERS'
SKIPLE .PDABS##(T1) ;IS ADDRESS BREAK CURRENTLY BEING USED?
JRST NOBRAK ;DON'T ALLOW HIM TO YANK IT OUT FROM UNDER THEM
IORM T2,.PDABS##(T1) ;DON'T ALLOW USERS TO USE ADDRESS BRAEK
POPJ P, ;RETURN TO COMCON
;HERE WHEN THE USER TYPED 'AFTER'
SETB12: PUSHJ P,DECIN ;GET THE NEXT ARGUMENT
PJRST NOTENF ;THERE MUST BE ONE
JRST COMERA ;NOTHING BUT A NUMBER IS LEGAL
CAILE T2,^D510 ;IS IT TOO BIG?
JRST COMERA ;YES
ADDI T2,1
DPB T2,[POINT 9,.PDTMI##(W),17] ;SAVE THE REPEAT COUNT
JRST SETB1A ;STORE IT AND GO AWAY
;HERE ON A SET ADDRESS BREAK UUO
SETABR::PUSHJ P,SAVE2## ;SAVE P1,P2
HRR M,T2 ;ADDRESS OF USER'S ARGUMENT
PUSHJ P,GETWDU## ;GET THE ARGUMENT
LDB P1,[POINT 9,T1,17] ;GET PROCEED COUNT
DPB P1,[POINT 9,.PDTMI##(W),17] ;STORE IT
LDB P1,[POINT 5,T1,8];GET SECTION NUMBER
DPB P1,[POINT 14,T1,17] ;STORE THAT
DPB T1,[POINT 23,.PDABS##(W),35] ;STORE BREAK ADDRESS
MOVE P2,T1 ;P2 = BREAK CONDITIONS
TLO P2,(OC.BSU) ;INDICATE SET BY UUO
AOS (P) ;PREPARE TO GIVE GOOD RETURN
TLNN P2,(OC.BCI+OC.BCD+OC.BCW+OC.BCM)
JRST [PUSHJ P,SETB10 ;TURNING OFF BREAK
PJRST SETRL1##]
PUSHJ P,BRKAV ;IS ADDRESS BREAK AVAILABLE?
SOSA (P) ;NO, ERROR RETURN
JRST [PUSHJ P,SETBR9 ;YES, SETUP BREAK CONDITIONS
PJRST SETRL1##]
JRST ECOD0## ;GIVE ERROR RETURN
;HERE ON RESET TO CLEAR BREAK ADDRESS AND CONDITIONS
; IF SET BY UUO
CLRBRK::SKIPE T1,.PDABS##(W) ;BREAK IN USE AT ALL?
TLNN T1,(OC.BSU) ;AND SET BY UUO?
POPJ P, ;NO
PUSHJ P,BRKDEC ;YES, DECREMENT COUNT OF USERS
SETZM .PDABS##(W) ;CLEAR ADDRESS AND CONDITIONS
POPJ P, ;AND RETURN
;THE ORDER OF AND THE NUMBER OF ENTRIES
; IN THE FOLLOWING TABLES CANNOT BE CHANGED
; WITHOUT CHANGING THE CODE IN SETBRK
BRKLS1: SIXBIT /NONE/
SIXBIT /AT/
SIXBIT /ON/
SIXBIT /NO/
BRKLS2: SIXBIT /USERS/
SIXBIT /EXECUT/
SIXBIT /READ/
SIXBIT /WRITE/
SIXBIT /MUUO/
SIXBIT /ALL/
BRKLS3: SIXBIT /AFTER/
AFTERX==BRKLS3-BRKLS2
;THE ENTRIES IN THIS TABLE CORRESPOND IN ORDER
; TO THE ENTRIES IN THE ABOVE TABLE
BRKTBL: EXP OC.BCI
EXP OC.BCD
EXP OC.BCW
EXP OC.BCM
EXP OC.BCI+OC.BCD+OC.BCW
;SUBROUTINE TO DETERMINE WHETHER ADDRESS BREAK IS AVAILABLE TO USERS
;CALLING SEQUENCE:
; PUSHJ P,BRKAV
;NON-SKIP RETURN IF NOT AVAILABLE BECAUSE MEMORY
; INDICATORS ARE DISABLED OR ADDRESS BREAK IS BEING
; USED BY SYSTEM PROGRAMMERS FOR MONITOR DEBUGGING
;SKIP RETURN IF ADDRESS BREAK IS AVAILABLE TO USERS, COUNT OF THE NUMBER
;OF USERS USING ADDRESS BREAK HAS BEEN UPDATED
;PRESERVES T2
BRKAV: PUSHJ P,FDNJP ;FIND THE NULL JOB'S PDB
IFN FTMP,<
PUSHJ P,CP0RC## ;SEE IF THE JOB IS RUNNABLE ON CPU0
TLNN P2,(OC.BCM) ;ITS NOT, BUT IF HE IS ENABLED FOR UUOS, SOME
>
; MUST HAPPEN ON CPU0
SKIPGE .PDABS##(T1) ;HAS ADDRESS BREAK BEEN DISABLED BY THE OPR?
POPJ P, ;YES, LOSE
MOVE T3,.PDABS##(W) ;GET HIS CURRENT ADDRESS BREAK SETTINGS
TLNN T3,(OC.ABE) ;IS HE ALREADY BREAKING?
AOS .PDABS##(T1) ;NO, COUNT UP THE NUMBER OF USERS USING ADDRESS BREAK
JRST CPOPJ1## ;AND GIVE THE HAPPY RETURN
;SUBROUTINE TO DECREMENT THE COUNT OF THE NUMBER
; OF USERS USING ADDRESS BREAK
BRKDEC: MOVE T1,.PDABS##(W) ;GET HIS CURRENT BREAK SETTINGS
TLNN T1,(OC.ABE) ;IS HE ENABLED FOR ADDRESS BREAK?
POPJ P, ;NO, NOTHING TO DO
PUSHJ P,FDNJP ;FIND THE PDB FOR THE NULL JOB
SOS .PDABS##(T1) ;DECREMENT THE COUNT OF USERS USING ADDRESS BREAK
POPJ P, ;AND RETURN
NOBRAK: PJSP T1,CONMES ;SORRY FOLKS!
ASCIZ /?Not available
/
;SUBROUTINE TO RETURN THE ADDRESS OF THE NULL JOB'S PDB IN T1
;PRESERVES T2-T4
FDNJP:: MOVEI T1,0 ;NULL JOB'S JOB NUMBER
PUSHJ P,FPDBT1## ;FIND THE NULL JOB'S PDB, RETURN ITS ADDRESS IN T1
JFCL ;IT MUST HAVE ONE
POPJ P, ;RETURN TO THE CALLER
>;END IFN FTKI10!FTKL10
SUBTTL SET COMMAND AND UUO -- PRIVILEGE WORDS
;HERE FOR UUO TO CHANGE PRIVILEGES
SETPRV: HRRI M,(T2) ;POINT TO FIRST ARGUMENT
PUSH P,J ;SAVE JOB NUMBER
PUSHJ P,GETWDU## ;PICK UP FUNCTION CODE
SKIPL T2,T1 ;SEE IF NEGATIVE
CAILE T2,SPRVMX ;OR TOO LARGE
JRST [POP P,J ;BALANCE THE STACK
JRST ECOD0##] ;YES, ERROR RETURN
ADDI M,1
PUSHJ P,GTWST2## ;GET ARGUMENT INTO T1
POP P,J ;RESTORE JOB NUMBER
JRST @SPRVTB(T2) ;DISPATCH
SPRVTB: EXP SPRVWD ;(0) SET PRIVILEGE WORD
EXP SPRVON ;(1) SET BITS IN PRIV WORD
EXP SPRVOF ;(2) CLEAR BITS IN PRIV WORD
EXP SCAPWD ;(3) SET CAPABILITY WORD
EXP SCAPON ;(4) SET BITS IN CAPABILITY WORD
EXP SCAPOF ;(5) CLEAR BITS IN CAPABILITY WORD
SPRVMX==.-SPRVTB-1 ;HIGHEST FUNCTION
SPRVOF: ANDCAB T1,JBTPRV##(J) ;CLEAR REQUESTED BITS
JRST STOTC1## ;AND STORE RESULT
SPRVON: IOR T1,JBTPRV##(J) ;INCLUDE BITS HE ALREADY HAS
SPRVWD: MOVE T2,.PDCAP##(W) ;GET CAPABILITIES
ANDCB T2,JBTPRV##(J) ;GET BITS HE CAN'T GET
TDNE T1,T2 ;TRYING TO SET BITS HE CAN'T HAVE?
PUSHJ P,PRVJ ;YES, BUT SEE IF PRIVILEGED
SKIPA ;OK TO SET BITS
JRST ECOD0## ;LOSE, ERROR RETURN
MOVEM T1,JBTPRV##(J) ;SET NEW PRIVILEGE WORD
JRST STOTC1## ;AND STORE FOR USER TO SEE
SCAPOF: ANDCAB T1,.PDCAP##(W) ;CLEAR REQUESTED BITS
JRST STOTC1## ;AND RETURN RESULT
SCAPON: IOR T1,.PDCAP##(W) ;INCLUDE BITS ALREADY OWNED
SCAPWD: SETCM T2,.PDCAP##(W) ;GET BITS HE CAN'T SET
TDNE T1,T2 ;NOT SETTING ANY NEW BITS?
PUSHJ P,PRVJ ;OR IS PRIVILEGED USER?
SKIPA ;YES, OK
JRST ECOD0## ;NO, LOSES
MOVEM T1,.PDCAP##(W) ;SET NEW CAPABILITY WORD
JRST STOTC1## ;AND GIVE TO USER
;HERE FOR COMMANDS TO ENABLE OR DISABLE PRIVILEGES.
;ONLY THE WHOLE WORD CAN BE MODIFIED NOW.
DISABL::SETZM JBTPRV##(J) ;CLEAR WORD
POPJ P, ;AND RETURN.
ENABLE::MOVE T1,.PDCAP##(W) ;GET CAPABILITIES
IORM T1,JBTPRV##(J) ;ADD TO PRIVILEGE WORD
POPJ P, ;DONE
SUBTTL SET COMMAND AND UUO -- CDR
;ENTER HERE ON SET CDR UUO
SETSPI: HRLOS T2 ;GET NAME, -1
AOS (P) ;AND SKIP COMMAND ENTRY AND FORCE SUCCESS RETURN
JRST SETCD2
;SET CDR COMMAND
SETCDR::PUSHJ P,CTEXT1 ;GET FILE NAME
JUMPE T2,NOTENF ;NONE SPECIFIED
TRNE T2,-1 ;MORE THAN 3 CHARACTERS?
JRST COMERA ;YES. NO GOOD.
SETCD2: HLLM T2,JBTSPL##(J) ;SAVE NAME
POPJ P, ;AND RETURN
;HERE TO SET SPOOL BITS BY UUO
SETSPB: SETCM T3,T2 ;-BITS HE WANTS ON
ANDI T3,.SPALL
TDNN T3,JBTSPL##(J) ;CLEARING SOME BITS FROM JBTSPL?
JRST SETSPC ;NO - OK
MOVSI T1,PVNSPL ;PRIV?
TSNN T1,STATES## ;OR SCHED BIT?
PUSHJ P,PRVBIT ;GO SEE
;NOTE THIS CODE DEPENDS ON PVNSPL=ST.NSP
IFN PVNSPL-ST.NSP,<PRINTX ST.NSP DOESN'T=PVNSPL>
JRST SETSPC ;YES. GO DO IT.
JRST ECOD0## ;NO. FAILURE RETURN
SETSPC: DPB T2,[POINT 5,JBTSPL##(J),35] ;YES, DO IT
JRST CPOPJ1## ;SUCCESS RETURN
DSKSIL::PUSHJ P,SETLGL ;LEGAL?
JRST COMERA ;NO
PUSHJ P,CTEXT1 ;YES, GET DRIVE NAME
MOVE T1,T2 ;INTO T1
CAMN T2,[SIXBIT 'PDP11'] ;DOES HE WANT TO STOP PDP-11 MESSAGE?
PJRST D76SIL## ;YES--GO SHUT HIM UP
IFN FTKS10,<
CAMN T2,[SIXBIT 'MEMORY'] ;DOES HE WANT TO STOP MEMORY ERROR MESSAGES?
PJRST MEMSIL## ;YES--GO SHUT HIM UP
>; END IFN FTKS10
PUSHJ P,TPMSIL## ;SEE IF A TAPE KONTROLLER
PJRST CPOPJ1## ;YES - EXIT
PUSHJ P,DSKQUI## ;STOP MESSAGES FOR THIS DRIVE
JRST COMERA ; NO SUCH UNIT, OR WRONG STATUS
PJRST CPOPJ1## ;OK
SUBTTL SET COMMAND AND UUO -- DISK STUFF
;SET DSKPRI N
DSKPRI::TLZA P4,-1 ;CLEAR LH(P4)
DSKPR2: TLO P4,-1 ;MINUS, SET LH(P4)=-1
PUSHJ P,SKIPS ;GET FIRST CHAR
JRST NOTENF
CAIN T3,"-" ;-?
JUMPE T2,DSKPR2 ;YES, SET LH(P4), TRY AGAIN
PUSHJ P,DECIN1 ;NO, GET THE NUMBER
JRST NOTENF
JRST COMERA
SKIPGE P4 ;- SEEN?
MOVNS T2 ;YES
PUSHJ P,PRICOM## ;CALL FILSER TO CHECK PRIUS
SKIPA
POPJ P,
PRIERR::JSP T1,ERRMES
ASCIZ /No privileges to set priority that high
/
;SET DSKFUL PAUSE (ERROR)
FULSTP::PUSHJ P,CTEXT
MOVE T1,[-2,,STPNST] ;LOOK AT ARGUMENT
PUSHJ P,FNDNAM
PJRST COMERA
STPSET: MOVEI T2,JS.SFL
XCT STPXCT(T1) ;TURN THE PAUSE-BIT ON OR OFF
PJRST CPOPJ1##
STPNST: SIXBIT /PAUSE/
SIXBIT /ERROR/
STPXCT: IORM T2,JBTSTS##(J)
ANDCAM T2,JBTSTS##(J)
;SET DSKFUL UUO (0=PAUSE, 1=ERROR, OTHER=READ)
DSKFUL: CAILE T2,1 ;SETTING?
JRST DSKFU1 ;NO
MOVE T1,T2 ;YES, T1=FUNCTION
JRST STPSET ;GO SET OR CLEAR THE BIT
DSKFU1: MOVEI T2,JS.SFL ;READING THE BIT
TDNE T2,JBTSTS##(J) ;IS HE SET TO PAUSE?
TDZA T1,T1 ;NO - 0
MOVEI T1,1 ;YES - 1
PJRST STOTC1## ;STOTAC, THEN CPOPJ1
;UUO TO SET PROGRAM TO RUN
SETPGM: PUSHJ P,PRVJ ;PRIV'D JOB?
JRST SETPG1 ;YES, ALLOW IT
MOVE T3,JBTLIM##(J)
TLNN T3,(JB.LBT) ; IN A BATCH JOB?
TLNN T3,(JB.LSY) ;FROM SYS: ?
JRST ECOD0## ;NO, ERROR
SETPG1: HRR M,T2 ;COPY ADDRESS
PUSH P,J
PUSHJ P,GETWDU## ;GET THE WORD
MOVE J,(P)
MOVEI T2,JS.RPC ;CLEAR BIT
ANDCAM T2,JBTST2##(J) ; ..
SKIPGE T1 ;WANT IT SET?
IORM T2,JBTST2##(J) ;YES
PUSHJ P,GETWD1## ;GET NAME
POP P,J
PUSHJ P,FNDPDS##
MOVEM T1,.PDPGM##(W)
JRST CPOPJ1##
SUBTTL SET COMMAND AND UUO -- ROUTINE TO READ DATE
;GTDATE-ACCEPTS DATE IN FORM 21-JAN-72 OR
; JAN-21-72 OR 5-JAN OR JAN-5 GIVING
; CREATION YEAR AS DEFAULT
; STORES YEAR (E.G. 1972), MONTH (1-12), DAY (1-31) IN 3 WORD
; VALVE BLOCK POINTED TO BY T1.
;
;CALL T1:=ADDRESS
; PUSHJ P,GTDATE
; ERROR, RETURN
; SUCCESS RETURN
GTDATE::PUSHJ P,SAVE2## ;SAVE POINTER
MOVEI P1,2 ;SET LOOP COUNT
MOVE P2,T1
SETZM 1(P2) ;NO MONTH TYPED YET
DATE01: PUSHJ P,CTEXT ;READ NEXT ARGUMENT
MOVE T1,[-MLEN,,MONTHS]
PUSHJ P,FNDNAM ;SCAN FOR A MONTH
JRST GTDAY
ADDI T1,1 ;FORM MONTH INDEX
MOVEM T1,1(P2) ;STORE MONTH
SOJG P1,DATE01 ;LOOP IF DAY NEXT
JRST GTYEAR
GTDAY: JUMPN T1,CPOPJ## ;ERROR, AMBIGOUS MONTH
SETZM T3 ;CLEAR FOR SUM
DATE02: SETZ T1,
LSHC T1,6 ;GET NEXT DIGIT
JUMPE T1,DATE03 ;DONE, IT 0
TRC T1,20 ;FORM OCTAL REPRESENTATION
CAILE T1,^D9
POPJ P, ;NOT A DIGIT
IMULI T3,^D10
ADDI T3,(T1) ;FORM SUM
JRST DATE02
DATE03: SKIPN 1(P2) ;IF NO MONTH WAS TYPED,
MOVEM T3,1(P2) ; STORE IT AS MONTH ALSO SO OLD FORMAT WILL WIN
MOVEM T3,2(P2) ;STORE DAY
SOJG P1,DATE01 ;LOOP IF MONTH NEEDED
GTYEAR: PUSHJ P,DECIN ;GET YEAR (IF TYPED)
SKIPA T2,MONYER ;CREATION YEAR IF MONITOR
POPJ P, ;BAD TERMINATOR
CAIGE T2,^D100 ;IF JUST 2 CHAR'S TYPED
ADDI T2,^D1900 ; ADD 1900
MOVEM T2,(P2) ;STORE YEAR
JRST CPOPJ1## ;SUCCESS
DEFINE .MONTH (A),
<IRP A
<SIXBIT/A/>>
MONTHS: .MONTH<JANUAR,FEBRUA,MARCH,APRIL,MAY,JUNE,JULY,AUGUST,SEPTEM,OCTOBE,NOVEMB,DECEMB>
MLEN==.-MONTHS
MONYER: M.YEAR## ;YEAR OF MONITOR CREATION
SUBTTL SET COMMAND AND UUO -- ROUTINES TO PRINT WATCH INFO
;SUBROUTINE TO PRINT TIME OF DAY USER STARTS TO WAIT FOR RESPONSE
; IF HE HAS ENABLED IT WITH "WATCH DAY"
;CALL: MOVE J,JOB NO.
; PUSHJ P,WCHBEG
; ALWAYS RETURN HERE
;THIS SUBROUTINE IS ALWAYS CALLED FROM THE COMMAND DECODER
;WHEN USER IS ABOUT TO WAIT FOR A RESPONSE
WCHBEG: MOVE T2,JBTWCH##(J)
MOVE T1,TIME## ;TIME OF DAY IN JIFFIES
TLNE T2,JW.WWT
DPB T1,JBYWCH## ;STORE FOR JOB
TLNN T2,JW.WDY ;DOES USER WANT TO SEE THIS?
POPJ P, ;NO.
PUSHJ P,PRLBK ;YES, PRINT LEFT BRACKET
MOVE T1,TIME## ;TIME OF DAY IN JIFFIES
PUSHJ P,PRTIM ;PRINT HH:MM:SS(NO CRLF)
;FALL INTO PRRBKC
;SUBROUTINE TO PRINT RIGHT BRACKET,CRLF
PRRBKC::PJSP T1,CONMES
ASCIZ /]
/
;SUBROUTINE TO PRINT LEFT BRACKET
PRLBK:: PJSP T1,CONMES
ASCIZ /[/
;SUBROUTINE TO PRINT RIGHT BRACKET
PRRBK:: PJSP T1,CONMES ;PRINT AND RETURN
ASCIZ /]/
;SUBROUTINE TO PRINT SYSTEM RESPONSE STATISTICS EACH TIME
;USER FINISHES WAITING FOR SYSTEM
;PRINT INCREMENTAL RUN TIME, WAIT TIME, # DISK BLKS READ, #DISK BLKS WRITTEN
;CALL: MOVE J,JOB NUMBER
; PUSHJ P,WCHEND
; ALWAYS RETURN HERE
WCHEND::MOVSI T1,JW.WRN!JW.WWT!JW.WDR!JW.WDW ;USER WANT ANY RESPONSE DATA?
TDNN T1,JBTWCH##(J) ; ..
POPJ P, ;NO.
PUSHJ P,SAVE1## ;SAVE P1
PUSHJ P,PRLBK ;YES, PRINT LEFT BRACKET
PUSHJ P,FNDPDS## ;FIND PDB ADDRESS. HALT IF NONE
MOVSI P1,-WCHLEN ;LOOP THRU ALL RESPONSE DATA ITEMS
WCHLOP: HLLZ T1,WCHTAB(P1) ;GET BIT ASSOCIATED WITH THIS FIELD
HRRZ T2,WCHTAB(P1) ;GET DISPATCH ADDRESS
TDZE T1,JBTWCH##(J) ;DOES USER WANT TO WATCH IT?
PUSHJ P,(T2) ;YES, PRINT IT OUT
AOBJP P1,WCH1 ;FINISHED ALL FIELDS?
PUSHJ P,PRSPC ;NO, PRINT A SPACE
WCH1: JUMPL P1,WCHLOP ;LOOP IF MORE BITS TO CONSIDER
PJRST PRRBKC ;APPEND RIGHT BRACKET, CRLF, AND RETURN
;TABLE OF ROUTINES TO PRINT RESPONSE DATA
WCHTAB: XWD JW.WRN,PRTWRN ;PRINT RUN TIME
XWD JW.WWT,PRTWWT ;PRINT WAIT TIME
XWD JW.WDR,PRTWDR## ;PRINT # DISK BLOCKS READ
XWD JW.WDW,PRTWDW## ;PRINT # DISK BLOCKS WRITTEN
;ADD NEW DATA HERE
WCHLEN==.-WCHTAB
;ROUTINE TO PRINT INCREMENTAL RUNTIME(NO CRLF)
;CALL: MOVEI T1,0
; PUSHJ P,PRTWRN
PRTWRN: EXCH T1,.PDRTM##(W) ;CLEAR INCREMENTAL RUN TIME
PJRST PRTIM ;PRINT AS HH:MM:SS, MM::SS OR SS.HH (NO CRLF)
;ROUTINE TO PRINT WAIT TIME (NO CRLF)
;CALL: PUSHJ P,PRTWWT
PRTWWT: LDB T1,JBYWCH## ;TIME OF DAY USER STARTED TO WAIT
SUB T1,TIME## ;-CURRENT TIME OF DAY = -WAIT TIME
SKIPLE T1 ;IS IT REALLY MINUS?
SUB T1,MIDNIT## ;NO. MUST HAVE BEEN WAITING ACROSS MIDNIGHT
; SO SUBTRACT A DAY TO GET IT NEGATIVE
MOVNS T1 ;NOW MAKE IT PLUS WAIT TIME
PJRST PRTIM ;TYPE OUT TIME (NO CRLF)
SETWTU: HLRZ T1,JBTWCH##(J) ;GET CLOCK OVERFLOW
ANDI T1,77 ;(ENOUGH FOR 24.*60.*60.*60.)
TRZ T2,77 ;CLEAR REQUEST JUNK
IOR T2,T1 ;INCLUDE OVERFLOW
HRLM T2,JBTWCH##(J) ;SAVE WATCH BITS
JRST CPOPJ1## ;AND RETURN
SUBTTL CONTINUE, CCONT AND JCONT
; "CONTC" - CONTINUE EXECUTION(TTY REMAINS IN COMMAND MODE)
CONTC:: ;SAME AS CONT
; "CONT" - CONTINUE EXECUTION FROM WHERE LEFT OFF
CONT:: JUMPE J,STARTE ;COMPLAIN IF NO JOB
LDB T1,JBYDEB## ;DEFERRED ECHO BITS
SE1XCT <DPB T1,LDPDEB##> ;RESTORE FOR CONTINUE
TLNN P4,JERR ;IS JOB ERROR BIT SET?
JRST CONT1 ;COMMAND DECODER WILL DO THE REST
JSP T1,ERRMES ;YES, PRINT CANT CONTINUE
ASCIZ /Can't continue
/
CONT1:
IFN FTMP,<
MOVE T1,USRPC## ;PC
TLNE T1,(XC.USR) ;USER MODE?
PJRST DPXST## ;YES, MAKE RUNNABLE ON ALL CPUS
>
POPJ P, ;*** NO
;JOB CONTINUE COMMAND
;FORCES A CONTINUE COMMAND FOR JOB Y
JCONT:: PUSHJ P,GETJOB ;GET JOB TO CONTINUE
JRST NOTENF ;MUST HAVE ARGUMENT
TRNN T3,JDCON ;JOB WAITING FOR CONT?
JRST JCERR2 ;NO
CAMN T2,J ;SEE IF FOR US
PJRST FCONT ;YES, GO DO IT
MOVE T1,T2 ;GET JOB # IN CORRECT AC FOR FCONRQ
PUSHJ P,FCONRQ ;GO REQUEST CONT BE FORCED FOR JOB
POPJ P, ;RETURN - SUCCESSFUL
PJRST SNDBSI ;NOT ENTERED - GO TYPE "BUSY"
;CALLED TO SET UP FORCED COMMAND FOR JOB CONTINUE
;JOB NUMBER IN T1
;SKIP RETURN IF COMMAND WAS NOT ENTERED BECAUSE ALREADY A
;FORCED COMMAND PENDING
FCONRQ::MOVEI T2,TTFCXJ## ;INDEX FOR FORCED CONTINUE
;SUBROUTINE TO FORCE COMMAND
;ARGS T1=JOB NUMBER
; T2=INDEX OF FORCED COMMAND
COMFRC::SE1ENT ;ENTER SECTION 1
PUSH P,U ;SAVE THIS AC
PUSH P,J ;SAVE THIS JOB NUMBER
MOVE J,T1 ;GET HIS JOB NUMBER
PUSHJ P,TTYSRC## ;SET UP LINE (LDB)
JRST JCONDM ;SEE IF ATTACHED
JRST COMFR2
COMFRL::SE1ENT ;ENTER SECTION 1
PUSH P,U ;SAVE ACS
PUSH P,J
COMFR2: JUMPE U,JCONDM ;CAN'T FORCE TO DETACHED LINE.
MOVSI T1,LDBCMF## ;ANY FORCED COMMAND
SCNOFF
TDNE T1,LDBCOM##(U) ;FOR THIS JOB ALREADY
JRST JCONDL ;YES
DPB T2,LDPCMX## ;STORE COMMAND INDEX
MOVSI T1,LDBCMR##+LDBCMF## ;BITS FOR FORCE
PUSHJ P,COMSTF## ;WAKE COMCON (RETURNS WITH SCAN ON)
POP P,J ;RESTORE JOB
PJRST LPOPJ## ;RETURN
;HERE IF JOB ALREADY HAS FORCED COMMAND PENDING, DELAY THIS COMMAND
JCONDL: SCNON
JCONDM: POP P,J ;RESTORE JOB NUMER
JRST LPOPJ1## ;CAN'T ENTER - SKIP RETURN
;HERE IF JOB NOT WAITING FOR CONTINUE
JCERR2: JSP T1,ERRMES
ASCIZ /Job not waiting/
;FORCED CONTINUE COMMAND
;NO TTY OUTPUT UNLESS COMMAND IS REALLY EXECUTED - IT WILL NOT BE
; IF USER HAS TYPED A COMMAND IN THE MEAN TIME.
FCONT:: MOVE P4,JBTSTS##(J) ;GET JOB STATUS
TLNN P4,JERR ;CAN WE CONTINUE
TRNN P4,JDCON ;IS JOB WAITING
POPJ P,
TLO M,TTYRNW ;SET FOR RESCHEDULE
TLZ M,NOCRLF!NOMESS ;RESET NOMESS
PUSHJ P,INLMES ;TELL USER HE'S CONT
ASCIZ /Continued by OPR/
POPJ P,
SUBTTL CORE COMMAND
; "CORE #" - ASSIGNS #*1024 WORDS OF CORE TO JOB
; "CORE" WITH NO ARG. WILL PRINT NO OF FREE BLOCKS LEFT
; WITHOUT AFFECTING CURRENT ASSIGNMENT OF CORE
; JOB NOT IN MIDDLE OF SWAPPING
; EITHER ON DISK OR CORE OR NEITHER PLACE
CORE:: PUSHJ P,CORARG ;GET HIGHEST RELATIVE ADDRESS USER SPECIFIED
JRST COR5 ;NO ARG. SPECIFIED, JUST TYPE FREE BLOCK LEFT
TLNE T1,-1 ;NO ARG GREATER THAN A SECTION ALLOWED
JRST COR4
JUMPL P4,[MOVEI T1,RUNERR ;RUNNING?
JRST ERRMES] ;YES, LOSE
JUMPE T1,COR1 ;RELEASE DEVICES IF USER ASKING FOR 0 CORE
TRNE P4,JS.XO!JS.RUU ;SEE IF EXECUTE ONLY
PJRST ILLXO ;YES -- GO GIVE ERROR
HRRZ T2,JBTSGN##(J) ;CLEAR JUNK IN LH
JUMPE T2,COR1 ;THERE REALLY ISN'T A HIGH SEG
COR3: SKIPG T3,.HBSGN(T2) ;IS THIS A REAL SEGMENT?
TLOA T3,-1 ;NO, FLAG SUCH
HLLZ T3,JBTADR##(T3) ;GET SIZE OF SEGMENT
HLRES T3 ;IN THE CORRECT HALF
SUBI T1,1(T3) ;ROUND UP AND SUBTRACT OUT
JUMPL T1,COR3D ;IF WENT NEGATIVE, ARG IS TOO SMALL
HRRZ T2,.HBLNK(T2) ;NEXT SEGMENT
JUMPN T2,COR3 ;CHECK IT OUT
COR1: SKIPE T1
SKIPN JBTADR##(J)
PUSHJ P,COR15 ;CALL UNLOCK, GETMIN, ET ALL
JUMPE T1,COR0
SKIPE JBTADR##(J) ;IF DIDN'T GET CORE IN CORE.
JRST COR2
LDB T2,IMGOUT## ;DID WE GET CORE ON DSK?
JUMPE T2,COR4 ;ERROR IF NONE
JRST DLYCM
COR2:
IFN FTMP,<
PUSHJ P,GETMM## ;GET THE MM
JRST DLYCM ;NOT AVAILABLE, DELAY
>
SKIPE PAGIPC## ;PAGING IN PROGRESS?
IFN FTMP,<
JRST [PUSHJ P,GIVMM##
JRST DLYCM ] ;YES, DELAY
>
IFE FTMP,<
JRST DLYCM
>
PUSHJ P,CORE0## ;GET CORE
IFN FTMP,<
JRST [PUSHJ P,GIVMM## ;NONE AVAILABLE
JRST COR4]
PUSHJ P,GIVMM## ;GIVE UP THE MM.
>
IFE FTMP,<
JRST COR4 ;CORE NOT AVAILABLE, GO PRINT MESSAGE
>
LDB T1,PJBSTS##
CAIE T1,NULQ## ;IN THE NO CORE Q?
POPJ P, ;NO
MOVEI T1,STOPQ## ;YES, OK RETURN, CORE ASSIGNED ON DISK OR MEMORY
DPB T1,PJBSTS## ;PUT JOB IN THE STOP Q SINCE IT NOW HAS CORE
PJRST REQUE##
COR3D: PUSHJ P,INLMES ;TOO SMALL AN ARG.
ASCIZ /?Try larger arg.
/
COR4: PUSHJ P,TTYFND## ;RE-FIND TTY LINE
JUMPE U,CPOPJ## ;GIVE UP IF GOT DETACHED
PUSHJ P,PRQM ;TYPE ? FOR BATCH
PUSHJ P,COR11 ;PRINT USAGE/LIMIT SUMMARY
TLO M,ERRFLG ;SET ERROR FLAG
POPJ P,
;HERE TO GIVE CURRENT CORE SIZE FOR VM USER
COR5: PUSHJ P,FNDPDS## ;FIND PDB FOR JOB
SKIPN JBTADR##(J) ;DON'T BOTHER IF NO CORE
JRST COR11 ;JUST SHOW LIMITS
JSP T2,SAVCTX## ;WE COULD HAVE A LOT OF OUTPUT
PUSHJ P,SAVE4## ;SAVE WORKING ACS
PUSHJ P,INLMES ;PRINT HEADER
ASCIZ /Page number Page status Origin
/
MOVEI P1,1 ;START WITH PAGE 1, PAGE 0 ALWAYS EXISTS
PUSH P,U ;GTPACC CLOBBERS U
MOVEI T1,0 ;PAGE 0
PUSHJ P,GTPACC## ;GET PAGE 0 ACCESSABILITY
POP P,U ;RESTORE LDB
TDZ T1,[<(PA.CPO+PA.OUT+PA.AA+PA.VSP)>,,-1] ;CLEAR DON'T CARE
MOVE P2,T1 ;FOR THE LOOP
MOVEI P3,0 ;END OF REGION
MOVEI P4,1 ;COUNT OF PAGES
COR6: MOVE T1,P1 ;CURRENT PAGE NUMBER
LSH T1,P2SLSH ;JUST SECTION NUMBER
SKIPN T2,.UPMP+SECTAB(T1) ;SECTION EXIST?
JRST COR9 ;NEXT SECTION
LDB T1,[POINT 3,T2,2] ;GET POINTER TYPE
CAIE T1,PM.ICD ;INDIRECT?
JRST COR8 ;NO
MOVEI T1,[ASCIZ /Section /]
PUSHJ P,CONMES ;PRINT THAT
MOVE T1,P1 ;PAGE NUMBER
LSH T1,P2SLSH ;SECTION NUMBER
PUSH P,T2 ;PRTDI8 CLOBBERS T2
PUSHJ P,PRTDI8 ;PRINT SECTION NUMBER
MOVEI T1,[ASCIZ / @section /]
PUSHJ P,CONMES ;INDIRECT
POP P,T2 ;RESTORE POINTER
HLRZ T1,T2 ;RIGHT HALF
ANDI T1,MXSECN ;ISOLATE SECTION NUMBER
PUSHJ P,PRTDI8 ;PRINT INDIRECT SECTION NUMBER
PUSHJ P,CRLF ;CRLF
COR7: TRO P1,PG.BDY ;NEXT SECTION
JRST COR10 ;CONTINUE
COR8: MOVE T1,P1 ;PAGE NUMBER
PUSH P,U ;GETPAC CLOBBERS U
PUSHJ P,GTPACC## ;GET PAGE ACCESSIBILITY
POP P,U ;RESTORE LDB
TDZ T1,[<(PA.OUT+PA.CPO+PA.AA+PA.VSP)>,,-1] ;DON'T CARE ABOUT IN, OUT, OR TARGET
TLNN T1,(PA.GSP) ;A SPY PAGE?
SKIPGE T1 ;DOES PAGE EXIST?
CAIA ;DON'T COUNT NON-EXISTANT OR SPY PAGES IN TOTAL
AOS P4 ;UPDATE TOTAL PAGE COUNT
CAMN T1,P2 ;SAME AS PREVIOUS PAGE?
JRST COR10 ;YES, LOOK AT NEXT PAGE
COR9: PUSH P,T1 ;SAVE NEW ACCESSIBILITY BITS
SKIPL P2 ;PREVIOUS PAGES NON-EXISTANT?
PUSHJ P,PRTACC ;NO, REPORT THEM
POP P,P2 ;NEW ACCESSIBILITY BITS
MOVE P3,P1 ;START OF RANGE
MOVE T1,P1 ;PAGE NUMBER
LSH T1,P2SLSH ;CURRENT SECTION NUMBER
SKIPE .UPMP+SECTAB(T1);DOES IT EXIST?
JRST COR10 ;YES, LOOK AT IT
TLO P2,400000 ;NO, PREVIOUS PAGE NON-EXISTANT
JRST COR7 ;NEXT SECTION
COR10: CAIGE P1,HLGPGS ;LOOKED AT ALL SECTIONS?
AOJA P1,COR6 ;NO, LOOP ON
SKIPL P2 ;PREVIOUS PAGES NON-EXISTANT?
PUSHJ P,[AOJA P1,PRTACC] ;NO, REPORT THEM
MOVEI T1,[ASCIZ /
Total of /]
PUSHJ P,CONMES ;SUMMARY
MOVE T1,P4 ;TOTAL NUMBER OF "REAL" PAGES SEEN
PUSHJ P,RADX10 ;OUTPUT THAT
MOVEI T1,[ASCIZ / page/]
PUSHJ P,CONMES ;FINISH UP
CAIN P4,1 ;SINGULAR?
SKIPA T1,[[ASCIZ /
/]]
MOVEI T1,[ASCIZ /s
/] ;NOTE THAT THIS IS <LF><CRLF> SO FITS IN 1 WORD
PUSHJ P,CONMES ;OUTPUT
;CONTINUED ON NEXT PAGE
COR11: HLRZ T1,.PDMVL##(W) ;GET MVPL
JUMPE T1,COR13 ;SKIP FIRST LINE IF ZERO
MOVEI T1,[ASCIZ "Virt. mem. assigned "]
PUSHJ P,CONMES ;PRINT TITLE
PUSHJ P,VMSIZE## ;GET SIZE OF JOB
JUMPE T2,[PUSHJ P,PRCORE ;IF JUST A LOWSEG
JRST COR12]; PRINT ONLY 1 NUMBER
PUSH P,T2 ;SAVE SIZE OF HISEG
PUSHJ P,RADX10 ;PRINT SIZE OF LOWSEG
PUSHJ P,PRTPLS
POP P,T1 ;SIZE OF HISEG
PUSHJ P,PRCORE ;PRINT THAT
COR12: HLRZ T4,.PDCVL##(W) ;GET CVPL
PUSHJ P,PRCXPL ;PRINT THAT
HLRZ T4,.PDMVL##(W) ;GET MVPL
SKIPN T4
MOVEI T4,1000
PUSHJ P,PRMXPL ;PRINT THAT
PUSHJ P,INLMES ;ADD ) CRLF
ASCIZ /)
/
COR13: PUSHJ P,INLMES
ASCIZ /Phys. mem. assigned /
PUSHJ P,PRTSEG ;PRINT LOWSEG SIZE
MOVEI T1,JBTSGN##-.HBLNK(J) ;START OF CHAIN
COR13A: SKIPN T1,.HBLNK(T1) ;NEXT SEGMENT DATA BLOCK
JRST COR13B ;NO MORE
SKIPG T2,.HBSGN(T1) ;SPY SEG?
JRST COR13A
PUSHJ P,PRTHGH## ;PRINT SIZE OF HISEG
COR13B: PUSHJ P,PRPORK ;PRINT P OR K
HRRZ T4,.PDCVL##(W) ;GET CPPL
TRZN T4,400000
JRST [PUSHJ P,PRCPGL
JRST .+2]
PUSHJ P,PRCXPL ;PRINT IT
MOVEI T4,0
MOVSI P1,PHONLY
PUSH P,.PDCVL##(W)
MOVEI T1,400000
ANDCAM T1,.PDCVL##(W)
PUSHJ P,PRMXPL ;PRINT IT
POP P,.PDCVL##(W)
;CONTINUED ON NEXT PAGE
PUSHJ P,INLMES ;ADD NOISE WORDS
ASCIZ /)
Swap space left: /
MOVE T1,VIRTAL## ;GET THAT NUMBER
PUSHJ P,PRCORE ;PRINT IN RADIX 10
PJRST CRLF ;ADD IN A CRLF AND RETURN
COR15: PUSH P,T1 ;SAVE T1
PUSHJ P,UNLOCK## ;SO CALLING GETMIN DOES SOMETHING
JFCL ;OOPS
PUSHJ P,CLRLPG## ;CLEAR LOCKED PAGES
PUSHJ P,GETMIN
PJRST TPOPJ## ;AND RETURN
;ROUTINE TO PRINT CURRENT AND MAX LIMITS
PRCPGL: MOVEI T1,[ASCIZ " (Guideline: "]
JRST PRXXPL
PRCXPL: SKIPA T1,[[ASCIZ " (Current limit: "]]
PRMXPL: MOVEI T1,[ASCIZ " Max limit: "]
PRXXPL: PUSH P,T4
PUSHJ P,CONMES ;PRINT THE TITLE
PUSHJ P,CORBND## ;GET MAX CORE
LSH T1,W2PLSH ;IN PAGES
SKIPN (P) ;ANYTHING GIVEN?
MOVEM T1,(P) ;CHOOSE GOOD MAX
POP P,T1 ;RESTORE NUMBER
PRCORE: PUSHJ P,RADX10 ;PRINT IN DECIMAL
PJRST PRPORK ;GIVE UNITS
;ROUTINE TO PRINT PAGE ACCESSIBILITY. CALL WITH P1=HIGHEST PAGE NUMBER IN REGION,
; P2=BITS RETURNED FROM GETPAC (ALTERED!), P3=FIRST PAGE NUMBER IN REGION
PRTACC: MOVE T1,P3 ;FIRST PAGE IN REGION
PUSHJ P,PRTDI8 ;PRINT THAT
CAIN P1,1(P3) ;EXACTLY 1 PAGE?
JRST PRTAC1 ;YES, SKIP NEXT
PUSHJ P,INLMES ;PRINT A MINUS SIGN
ASCIZ /-/
MOVEI T1,-1(P1) ;HIGHEST PAGE IN REGION
PUSHJ P,PRTDI8 ;PRINT THAT
PRTAC1: MOVEI T1,[ASCIZ / /]
PUSHJ P,CONMES ;LINE THINGS UP
MOVEI T2,-1(P1) ;FIX OFF BY ONE ABOVE
CAIE T2,(P3) ;ALWAYS TAB IF NO RANGE
TRNN T2,777000 ;SEVEN OR MORE CHARACTERS ALREADY BEEN OUTPUT?
PUSHJ P,CONMES ;NO, NEED ANOTHER TAB
MOVEI T2,0 ;COUNT CHARACTERS
MOVEI T1,[ASCIZ /EX /];IF ITS NOT A SPY PAGE, ITS EXECUTABLE
TLNN P2,(PA.GSP) ;A SPY PAGE?
PUSHJ P,[AOJA T2,CONMES] ;NO, OUTPUT
MOVEI T1,[ASCIZ /RD /];ASSUME IT CAN BE READ
TLNE P2,(PA.RED) ;CAN IT BE
PUSHJ P,[AOJA T2,CONMES] ;YES, OUTPUT THAT
MOVEI T1,[ASCIZ /WR /];ASSUME IT CAN BE WRITTEN
TLNE P2,(PA.WRT) ;CAN IT BE
PUSHJ P,[AOJA T2,CONMES] ;YES, OUTPUT THAT
MOVEI T1,[ASCIZ /AZ /];ASSUME ABZ
TLNE P2,(PA.ZER) ;IS IT?
PUSHJ P,[AOJA T2,CONMES] ;YES, OUTPUT THAT
MOVEI T1,[ASCIZ /SH /];ASSUME ITS SHARABLE
TLNN P2,(PA.GSP) ;WOULD YOU BELIEVE THAT SPY PAGES ARE SHARABLE?
TLNN P2,(PA.GSH) ;IS IT?
CAIA ;NO
PUSHJ P,[AOJA T2,CONMES] ;YES, OUTPUT THAT
MOVEI T1,[ASCIZ /LK /] ;ASSUME LOCKED
TLNE P2,(PA.LCK) ;IS IT?
PUSHJ P,[AOJA T2,CONMES] ;YES, OUTPUT THAT
MOVEI T1,[ASCIZ / /]
TLNN P2,(PA.GSH) ;NEED A TAB IF SHARABLE
CAIG T2,2 ;ALSO IF LESS THAT 2 ATTRIBUTES
PUSHJ P,CONMES ;LINE THINGS UP
TLNN P2,(PA.GSP) ;SPY PAGES?
PRTA1A: SKIPA T1,[[ASCIZ / Private/]] ;NO, ASSUME IT'S PRIVATE
MOVEI T1,[ASCIZ / Spy/] ;SPY
TLZE P2,(PA.GSH) ;PRIVATE
TLNE P2,(PA.GSP) ;OR SPY?
JRST PRTAC4 ;YES, WE HAVE AN ATTRIBUTE
PUSHJ P,SAVE1## ;SAVE P1
PUSHJ P,SAVJW## ;AND J (W ALONG FOR THE RIDE)
MOVE P1,P3 ;GET PAGE # OF FIRST PAGE
LSH P1,P2SLSH ;GET SECTION
SETZ T1, ;FIRST SEG THAT SECTION
PRTA1B: PUSHJ P,NXSSP1## ;GET NEXT SEGMENT IN THAT SECTION
JRST PRTA1A ;HUH (BITS ZEROED ABOVE)
SKIPG J,.HBSGN(T1) ;GET SEGMENT NUMBER
JRST PRTA1B ;SPY
HRRZS J ;CLEAR JUNK
LDB T2,JBYHSO## ;GET ORIGIN OF THAT HIGH SEG
XOR T2,P3 ;SEE IF IT'S THIS PAGE
TRNE T2,HLGPNO ;?
JRST PRTA1B ;NO, CHECK NEXT SEGMENT
MOVE T2,JBTDEV##(J) ;DEVICE NAME
PUSHJ P,PRNAME ;PRINT THAT
MOVEI T1,[ASCIZ /:/] ;DEVICE DELIMITER
PUSHJ P,CONMES ;PRINT THAT
MOVE T2,JBTNAM##(J) ;GET HIGH SEGMENT NAME
PUSHJ P,PRNAME ;PRINT THAT
MOVE J,JBTPPN##(J) ;GET PPN
TLNE J,-1 ;PATH OR PPN?
SKIPA T2,J ;PPN
MOVE T2,(J) ;PATH, PPN IS STORE HERE
PUSHJ P,PRTPP1 ;PRINT THE LEFT BRACKET, P,PN
TLNE J,-1 ;IF ONLY A PPN, DONE
JRST PRTAC3 ;GO PRINT THE RIGHT BRACKET
PRTAC2: SKIPN T2,1(J) ;NEXT SFD
JRST PRTAC3 ;NO MORE, DONE
PUSHJ P,PRCOM ;PRINT A COMMA
PUSHJ P,PRNAME ;PRINT THE SFD NAME
AOJA J,PRTAC2 ;NEXT SFD
PRTAC3: PUSHJ P,PRTRBK ;PRINT RIGHT BRACKET
PJRST CRLF ;PRINT A CRLF AND RETURN
PRTAC4: PUSHJ P,CONMES ;OUTPUT WHAT WE HAVE
CAIN P1,1(P3) ;EXACTLY ONE PAGE?
SKIPA T1,[[ASCIZ / page
/]]
MOVEI T1,[ASCIZ / pages
/]
PJRST CONMES
;ROUTINE TO PRINT ACCOUNT STRING
CACCT:: MOVEI T1,.PDACS##(W) ;ADDRESS OF USER'S ACCOUNT STRING
PUSHJ P,CONMES ;TYPE IT
PJRST PCRLF ;<CRLF>
SUBTTL CONTROL-T PRINTOUT
;SUBROUTINE TO PRINT A 1 TO 3 LINE USE STATUS REPORT
;CALLED FROM USESTAT COMMAND IT PRINTS A 1 LINE
; STATUS REPORT OF THE FORM:
; INCREMENTAL DAY TIME
; INCREMENTAL RUN TIME
; INCREMENTAL DISK READS
; INCREMENTAL DISK WRITES
; PROGRAM NAME
; CORE SIZE
; JOB STATE
; PC
;
USECOM::TLNN P4,JNA ;IS THIS A JOB?
PJRST ATT4 ;NO--SAY "NOT A JOB"
MOVEI T1,[ASCIZ 'Day: ']
PUSHJ P,CONMES
PUSHJ P,PRTWWT ;INCREMENTAL DAYTIME
MOVE T1,TIME## ;RESET THE TIMER FOR
DPB T1,JBYWCH## ; THE NEXT TIME
PUSHJ P,UDCPUT## ;UPDATE RUN TIME IF NECESSARY
MOVEI T1,[ASCIZ ' Run: ']
PUSHJ P,CONMES
MOVEI T1,0 ;CLEAR INCREMENTAL RUNTIME
EXCH T1,.PDRTM##(W) ; AND PICK UP OLD RUN TIME
PUSHJ P,PRTIM ;PRINT THAT
MOVEI T1,[ASCIZ ' Rd:']
PUSHJ P,CONMES
PUSHJ P,PRTWDR## ;DISK READS
MOVEI T1,[ASCIZ ' Wr:']
PUSHJ P,CONMES
PUSHJ P,PRTWDW## ;DISK WRITES
PUSHJ P,PRSPC ;ANOTHER SPACE
MOVE T2,JBTPRG##(J) ;PROGRAM NAME
PUSHJ P,PRNAME ;PRINT THE NAME
PUSHJ P,USEHSG ;PRINT JOB'S HIGH SEGMENTS
PUSHJ P,PRSPC ;ANOTHER SPACE
PUSHJ P,PRTSEG ;LOW SEG SIZE
PUSHJ P,PRTHGH## ;HIGH SEG SIZE
PUSHJ P,PRPORK ;PRINT P OR K
PUSHJ P,CTXPRT## ;PRINT CURRENT CONTEXT NUMBER
PUSHJ P,PRSPC ;ANOTHER SPACE
MOVSI T2,'^C' ;ASSUME CONTROL-C STATE
JUMPG P4,USECM1 ;JUMP IF TRUE
LDB T1,PJBSTS## ;PICK UP JOB STATE
IDIVI T1,3 ;DIVIDE BY 3 TO GET WORD NUMBER
IMULI T2,^D12 ;MULTIPLY REMAINDER BY 12 TO GET POSITION
MOVE T3,STSTBL##(T1) ;PICK UP ENTRY
ROT T3,(T2) ;GET CORRECT THIRD
MOVSI T2,777700 ;ONLY LOOK AT TOP 12 BITS
AND T2,T3 ;COPY STATE
USECM1: PUSHJ P,PRNAME ;PRINT THAT
IFN FTLOCK,<
MOVEI T3,"&" ;ASSUME LOCKED
TLNE P4,NSWP ;SEE IF LOCKED
PUSHJ P,PRCHR ;YES, LOCKED
>;END IFN FTLOCK
MOVEI T3,"*" ;ASSUME CURRENT JOB
PUSHJ P,ANYCPU## ;ARE WE THE CURRENT JOB?
PUSHJ P,PRCHR ;YES--PRINT *
PUSHJ P,PRSPC ;ANOTHER SPACE
MOVSI T2,'SW ' ;ASSUME SWAPPED
TLNE P4,SWP!SHF ;IS JOB IN CORE?
PUSHJ P,[SKIPE JBTADR##(J) ;ANY PHYS MEM?
MOVSI T2,'SW*' ;YES--ADD * TO MEAN SWAPPING
PJRST PRNAME] ;PRINT SW OR SW*
MOVEI T1,[ASCIZ ' PC:']
PUSHJ P,CONMES
MOVE T2,JBTPC##(J) ;GET CURRENT PC
PUSHJ P,UDPCP## ;PRINT PC IN OCTAL
USECPU:
IFN FTMP,<
SKIPE T2,[M.CPU##-1] ;SKIP IF FTMP ON BUT SINGLE CPU MONITOR
HRRZ T2,JBTST3##(J) ;GET CDB OF LAST CPU WE RAN ON
JUMPE T2,USECP1 ;SKIP THIS IF A SINGLE CPU OR NO CORE FOR JOB
PUSHJ P,PRSPC ;SPACE OVER
MOVE T2,.CPLOG##-.CPCDB##(T2) ;GET CPU NAME
PUSHJ P,PRNAME ;PRINT IT
USECP1:
> ;END IFN FTMP
SKIPN JBTADR##(J)
JRST USECM3
MOVSI T1,SWP!SHF ;BIT INDICATING SWAPPED OR BEING SWAPPED
SKIPE .USVRT ;VIRTUAL?
TDNE T1,JBTSTS##(J) ;AND IN CORE?
JRST USECM3 ;NO, SKIP THIS
MOVEI T1,[ASCIZ /
Faults - IW: /]
PUSHJ P,CONMES ;PRINT THE TEXT
MOVE T1,.USVCT ;REPORT INCREMEMTAL IN WORKING SET FAULTS
SUB T1,.USICT
HRRZS T1
PUSHJ P,RADX10
MOVEI T1,[ASCIZ / NIW: /]
PUSHJ P,CONMES ;PRINT TEXT
MOVE T1,.USVCT ;REPORT INCREMENTAL NOT IN WORKING SET FAULTS
SUB T1,.USICT
HLRZS T1
PUSHJ P,RADX10
MOVE T1,.USVCT ;UPDATE INCREMENTAL STATISTICS
MOVEM T1,.USICT
MOVEI T1,[ASCIZ / Virt core: /]
PUSHJ P,CONMES ;PRINT TEXT
LDB T1,LOVSIZ## ;LOW SEGMENT VIRTUAL CORE
PUSHJ P,RADX10 ;REPORT LOW SEGMENT VIRTUAL CORE
PUSHJ P,PRTPLS ;PRINT A PLUS SIGN
LDB T1,HIVSIZ## ;HIGH SEG
PUSHJ P,PRCORE ;REPORT HIGH SEGMENT VIRTUAL CORE
MOVEI T1,[ASCIZ / Page rate: /]
PUSHJ P,CONMES ;PRINT TEXT
MOVE T1,J
PUSHJ P,FPDBT1##
TDZA T3,T3
HLRZ T3,.PDVRT##(T1) ;GET PAGING RATE
SETZB T1,T2 ;ASSUME A RATE OF ZERO
JUMPE T3,USECM2 ;JUMP IF THE RATE IS ZERO
MOVEI T1,RTUPS## ;COMPUTE THE JOBS PAGING RATE
IDIVI T1,(T3)
IMULI T2,^D100
IDIVI T2,(T3)
USECM2: PUSH P,T2 ;SAVE THE REMAINDER
PUSHJ P,RADX10 ;PRINT THE RATE
PUSHJ P,PRPER ;AND A DOT
POP P,T1 ;RESTORE THE REMAINDER
MOVEI T3,"0" ;ASSUME THE REMAINDER IS IN HUNDREDTHS
CAIG T1,^D9 ;IS IT?
PUSHJ P,PRCHR ;YES, PRINT A LEADING ZERO
PUSHJ P,RADX10 ;AND PRINT DIGITS FOLLOWING THE DECIMAL PLACE
USECM3: HRRZ F,JBTDDB##(J) ;GET DDB ADDRESS
JUMPE F,USECM5 ;ALL DONE IF NO DDB
IFN FTMP,<
DDBSRL ;LOCK DDB SEARCH
MAP T1,(F) ;MAP DDB ADDRESS
PUSHJ P,FLTCHK## ;STILL AROUND?
JRST USECM4 ;NO
>
MOVE T1,JBTSTS##(J) ;GET STATUS
CAMLE F,SYSSIZ## ;DDB IN THE MONITOR?
TLNN T1,SWP!SHF ;NO, IS THE JOB IN CORE?
TRNA ;YES, PROCEED
JRST USECM4 ;NO, DON'T TRY TO REPORT DEVICE INFO
MOVE T3,DEVMOD(F) ;GET DEVICE TYPE FOR TEST
TRNE T1,JS.XO ;EXECUTE ONLY?
TLNN T3,DVDSK!DVDTA ;AND DISK OR DECTAPE?
SKIPA T2,DEVIOS(F) ;NO, TYPE DDB INFO
JRST USECM4 ;YES TO BOTH, SKIP DDB PRINTOUT
MOVEI T1,[ASCIZ "
Input"]
TLNE T3,DVTTY ;IS IT A TTY?
TLNE T3,DVDSK ;AND NOT NUL:?
JRST USECMA ;NO, GO DO NORMAL DEVICE
TLNE T2,TTYOUW## ;OUTPUT DIRECTION?
MOVEI T1,[ASCIZ "
Output"]
JRST USECMB ;TYPE THE MESSAGE
USECMA: TLNE T2,IO ;OUTPUT DIRECTION?
MOVEI T1,[ASCIZ "
Output"]
USECMB: PUSHJ P,CONMES ;PRINT THE TEXT
MOVEI T1,[ASCIZ " wait for "]
PUSHJ P,CONMES
PUSHJ P,PRTDDB ;PRINT FILE SPEC
MOVE T1,DEVMOD(F) ;GET DEVICE BITS
TLNE T1,DVDSK ;IS THIS A DISK?
PUSHJ P,DSKCTT## ;YES -- PRINT GOOD STUFF
MOVE T1,DEVMOD(F) ;IS THIS A
TLNE T1,DVMTA ; TAPE?
PUSHJ P,TPMCTT## ;YES--PRINT FILE & RECORD
USECM4:
IFN FTMP,<
DDBSRU ;UNLOCK DDB
>
USECM5: SE1ENT ;LDB'S ARE IN SECTION MUMBLE.
HRRZ F,LDBDDB##(U) ;GET DDB ADDRESS
MOVE T1,LDBDCH##(U) ;GET DEVICE BITS FOR TTY
TLNE T1,LDLCOM## ;COMMAND LEVEL?
TLZ M,NOPER ;YES--PRINT A PERIOD
MOVSI T2,LDBCMF## ;ALWAYS CALL TTYSTR IF
TDNE T2,LDBCOM##(U) ;USESTAT COMMAND (NOT ^T)
TRNN T1,LDROSU## ;CONTROL-O IN EFFECT
TLZ M,NOMESS ;NO--CLEAR NOMESS
POPJ P,0 ;RETURN
;SUBROUTINE TO PRINT JOB'S HIGH SEGMENT(S) FOR CONTROL-T COMMAND
;CALL WITH:
; J/ JOB NUMBER
USEHSG: ;WRAPS THE LINE AND TOO LATE FOR DOCUMENTATION
POPJ P, ;PATCH TO JFCL TO ENABLE THIS NIFTY FEATURE
PUSHJ P,SAVE2## ;FREE UP A FEW ACS
SETZ P1, ;START WITH FIRST HIGH SEGMENT
USEHS1: MOVE T1,P1 ;COPY HSB ADDRESS
PUSHJ P,GNXHSB## ;GET NEXT HSB
POPJ P, ;NONE, RETURN
MOVE P1,T1 ;REMEMBER FOR POSTERITY
SKIPG P2,.HBSGN(P1) ;IS THERE A REAL SEGMENT THERE?
JRST USEHS1 ;NO, SKIP THIS HSB
PUSHJ P,PRTPLS ;PRINT A "+"
MOVE T2,JBTPRG##(P2) ;GET NAME OF HIGH SEGMENT
CAME T2,JBTPRG##(J) ;UNLESS LOW AND HIGH SEG ARE SAME NAME,
PUSHJ P,PRNAME ; PRINT NAME OF HIGH SEGMENT
JRST USEHS1 ;KEEP LOOPING
;SUBROUTINE TO PRINT A FILESPEC FOR A DDB
;CALL WITH:
; F = DDB ADDRESS
; U = LDB ADDRESS (OR FIX COMTOA)
; PUSHJ P,PRTDDB
; RETURN HERE
;
PGMMRG: SKIPA T1,[[ASCIZ/Merged /]]
PGMFIL: MOVEI T1,[ASCIZ/ from /]
SKIPE F,USRJDA##+0 ;SEE IF DDB AND GET ADDRESS
TLNN F,INPB ;WAS AN INPUT DONE?
POPJ P, ;NO
PUSHJ P,CONMES
PRTDDB::PUSHJ P,SAVE1## ;SAVE P1
MOVE P1,DEVMOD(F) ;GET DEVICE TYPE BITS
MOVE T2,DEVNAM(F) ;GET DEVICE NAME
HRRZ T3,DEVUNI##(F) ;UDB POINTER
JUMPE T3,PRTDD1 ;NO UNIT IF A KNOWN SEGMENT
TLNN P1,DVDSK ;IS THIS A DISK?
JRST PRTDD1 ;NO
SKIPN T2,UNILOG(T3) ;YES, PART OF STR?
MOVE T2,UDBNAM(T3) ;NO
PRTDD1: PUSHJ P,PRNAME ;PRINT IT
MOVEI T3,":" ;ADD A COLON
PUSHJ P,PRCHR ; ..
TLNN P1,DVDSK!DVDTA ;FILE AND EXT?
JRST PRTDD2 ;NO
MOVE T2,DEVFIL(F) ;GET FILE NAME
JUMPE T2,CPOPJ## ;PUNT IF NO NAME
HLRZ T3,DEVEXT(F) ;IS THIS A UFD
TLNE P1,DVDSK ;ON DISK
CAIE T3,'UFD'
JRST PRTDD3 ;NO
PUSHJ P,PRTPPN ;YES -- PRINT FILE NAME AS [M,N]
JRST PRTDD4 ;AND NOT SIXBIT
PRTDD2:
IFE FTTLAB,<POPJ P,> ;RETURN
IFN FTTLAB,<
TLNE P1,DVMTA ;IS THIS A MAGTAPE?
SKIPN %SITLP## ;AND IS TAPE LABELER RUNNING?
POPJ P, ;NO TO EITHER--RETURN
PUSH P,U ;SAVE U
MOVE U,TDVUDB##(F) ;UDB ADDRESS
LDB T1,TUYLTP## ;GET LABEL TYPE
POP P,U ;RESTORE U
JUMPE T1,CPOPJ## ;RETURN IF NOT A LABELED TAPE
SKIPN T2,DEVFIL(F) ;ELSE GET FILE NAME
POPJ P, ;UNLESS THERE ISN'T ONE
> ;END IFN FTTLAB
PRTDD3: PUSHJ P,PRNAME ;PRINT IT
PRTDD4: PUSHJ P,PRPER ;ADD IN A DOT
HLLZ T2,DEVEXT(F) ;GET EXTENSION
PUSHJ P,PRNAME ;PRINT IT
TLNE P1,DVDSK ;IS THIS THE DISK?
SKIPN T2,DEVPPN(F) ;FALL INTO PRTPPN IF PPN
POPJ P, ;ELSE RETURN
; PJRST PRTPTH ;PRINT PATH (NEXT PAGE)
;ROUTINE TO TYPE A PATH WITH SFD'S IF NEEDED
PRTPTH: PUSHJ P,PRTPP1 ;PROJ, PROG PART OF PATH
HRRZ P1,DEVSFD##(F) ;PATH POINTER
JUMPE P1,PRTRBK ;IF NO SFD'S
PUSH P,[0] ;MARK END OF PATH
PRTPT1: PUSH P,NMBNAM##(P1) ;SAVE THE SFD NAME
PRTPT2: HLRZ P1,NMBPPB##(P1) ;BACK ONE LEVEL
TRZN P1,NMPUPT## ;NAME SHOULD BE OUTPUT?
JUMPN P1,PRTPT2 ;NO, GET NEXT LEVEL IF NOT AT END
JUMPN P1,PRTPT1 ;YES, SAVE NAME AND GET NEXT LEVEL
PRTPT3: POP P,T2 ;RESTORE SFD NAME
JUMPE T2,PRTRBK ;IF END, TYPE RIGHT BRACKET AND RETURN
PUSHJ P,PRCOM ;PRINT COMMA
PUSHJ P,PRNAME ;PRINT THIS SFD NAME
JRST PRTPT3 ;LOOP OVER WHOLE PATH
PRTPPN::PUSHJ P,PRTPP1
PJRST PRTRBK
PRTPP1: PUSH P,T2 ;SAVE PPN
MOVEI T3,"[" ;PRINT [
PUSHJ P,PRCHR
HLRE T1,(P)
JUMPGE T1,PRTPP2 ;WILDCARD?
MOVEI T3,"*" ;YES
PUSHJ P,COMTYO
SKIPA
PRTPP2: PUSHJ P,PRTDI8 ;PROJECT
PUSHJ P,PRCOM ;COMMA
HRRE T1,(P)
AOJN T1,PRTPP3 ;WILDCARD?
MOVEI T3,"*" ;YES
PUSHJ P,COMTYO
JRST T2POPJ##
PRTPP3: HRRZ T1,(P) ;GET PROGRAMMER HALFWORD AGAIN
PUSHJ P,PRTDI8 ;PRINT IT
JRST T2POPJ##
PRTRBK: MOVEI T3,"]"
PJRST P,PRCHR
SUBTTL NETWORK COMMANDS -- LOCATE
CLOCAT::JSP T2,SAVCTX ;MUST SCHEDULE THIS COMMAND
SE1ENT ;ENTER SECTION ONE
PUSHJ P,CTEXT1 ;GET THE ARGUMENT IN SIXBIT
NETDBJ ;INTERLOCK THIS CODE WITH NETSER
SKIPN T1,T2 ;COPY TO T1
SKIPA T2,JBTLOC## ;USE LOCAL STATION
PUSHJ P,CVTOCT## ;TRY TO CONVERT TO OCTAL
MOVE T1,T2 ;CAN'T-GET THE NAME BACK
PUSH P,T1 ;SAVE THE ARG
IFN FTNET,<
SKIPE [M.ANF##] ;ANF-10 SOFTWARE?
PUSHJ P,SRCNDB## ;SEARCH FOR THE NODE BLOCK
JRST LOCERR ;DOES NOT EXIST
HLRZ T2,NDBNNM##(W) ;YES, GET THE NODE NUMBER
MOVEI T1,[ASCIZ/Node number out of range/]
CAILE T2,77 ;KEEP IT REASONABLE FOR BATCH
JRST [POP P,(P) ;CLEAN STACK
JRST ERRMES] ;GIVE ERROR
MOVEM T2,JBTLOC##(J) ;LOCATE HIM WHERE HE WANTS
POP P,(P) ;RESTORE THE STACK
PUSHJ P,TYPNDB## ;TYPE THE NODE NAME
JSP T1,CONMES ;AND FINISH UP
ASCIZ / located
/
> ;END IFN FTNET
LOCERR: POP P,T2 ;GET NUMBER BACK
CAIG T2,77 ;IS IT A NUMBER
JUMPG T2,LOCER1 ;YES, WILL ALLOW THE LOCATE TO HAPPEN
IFN FTNET,<PJRST UNDERR> ;UNDEFINED NETWORK NODE
IFE FTNET,<
MOVEI T1,[ASCIZ \Invalid station address\] ;NO.
PJRST ERRMES ;TYPE IT
> ;END IFE FTNET
LOCER1: MOVEM T2,JBTLOC##(J) ;STORE THE LOCATION
IFN FTNET,<
MOVEI T1,[ASCIZ /%Node (/]
SKIPN [M.ANF##] ;ANF-10 SOFTWARE?
> ;END IFN FTNET
MOVEI T1,[ASCIZ /Station /]
PUSHJ P,CONMES ;PRINT TEXT
HRRZ T1,JBTLOC##(J) ;GET THE NUMBER
PUSHJ P,PRTDI8 ;PRINT THE NUMBER
IFN FTNET,<
MOVEI T1,[ASCIZ /) located but offline/]
SKIPN [M.ANF##] ;ANF-10 SOFTWARE?
> ;END IFN FTNET
MOVEI T1,[ASCIZ / located/]
PUSHJ P,CONMES ;PRINT TEXT
PJRST PCRLF ;END LINE WITH A CRLF
SUBTTL NETWORK COMMANDS -- WHERE
CWHERE::SE1ENT ;ENTER SECTION ONE
IFE FTNET!FTKL10!FTDECNET!FTENET,<
MOVSI T1,JLOG ;IF NOT
TDNN T1,JBTSTS##(J) ;LOGGED IN
DPB T1,PJOBN## ;DON'T LEAVE GHOST JOB
JSP T1,ERRMES ;CAN'T DO THESE IF NO NETWORK
ASCIZ /No network, DAS78, or DN60 software
/
> ;END IFN FTNET!FTKL10!FTDECNET!FTENET
IFN FTNET!FTKL10!FTDECNET!FTENET,<
JSP T2,SAVCTX## ;SAVE THE CONTEXT OF THE JOB
PUSHJ P,CTEXT1 ;GET FIRST ARG = SIXBIT DEV NAME
IFN FTNET,<
NETDBJ ;INTERLOCK WITH NETSER
PUSHJ P,NETASG## ;TRY TO ASSIGN "NODE_DEVICE"
POPJ P, ;ERROR IN ARGUMENTS (MESSAGE PRINTED)
>;END IFN FTNET
PUSH P,T2 ;SAVE 6 BIT
PUSHJ P,FNDSTA## ;GET OUR STATION
POP P,T2 ;GET 6 BIT NAME
MOVE T1,T2 ;INTO T1
PUSH P,U ;SAVE U
PUSHJ P,DVCNSG## ;SEARCH FOR PHYSICAL DEV NAME
PJRST NOTDV1 ;PRINT "NO SUCH DEVICE"
PUSHJ P,FNDDEV## ;FIND LOCATION
LDB T2,PDVTYP## ;GET DEVICE TYPE
IFN FTKL10,<
CAIN T2,.TYD78 ;IS IT A DAS78?
PJRST CWHD78## ;LET D78INT HANDLE IT
> ;END IFN FTKL10
IFN FTNET,<
CAIE T2,.TYTTY ;IS IT A TTY?
PJRST CWHANF## ;LET NETSER HANDLE NON-TTY DEVICES
> ;END IFN FTNET
MOVE U,DDBLDB##(F) ;GET TARGET TTY'S LDB
MOVE T4,LDBTTW##(U) ;GET THE TTY USE FLAGS
TLNN T4,LTLUSE## ;IS TTY IN USE?
JRST CWHNCN ;NO, JUST SAY "NOT CONNECTED"
IFN FTNET,<
TLNE T4,LTLANF## ;IF ANF-10,
PJRST CWHANF## ;LET NETSER TYPE IT OUT
> ;END IFN FTNET
IFN FTDECNET,< ;IF DECNET,
TLNE T4,LTLNRT## ;IF NRT/CTERM
JRST CWHNRT## ;LET NRTSER TYPE IT OUT
> ;END IFN FTDECNET
IFN FTENET,< ;IF ETHERNET/LAT
TLNE T4,LTLLAT## ;IF LAT TERMINAL
PJRST CWHLAT## ;LET LATSER TYPE IT OUT
> ;END IFN FTENET
TLNE T4,LTLREM## ;REMOTE?
PJRST CWHNCN ;YES, BUT DON'T KNOW WHAT FLAVOR
IFE FTNET,<JRST UPOPJ##> ;GIVE UP
IFN FTNET,<PJRST CWHANF##> ;SAY LOCAL STATION
CWHNCN::PUSHJ P,INLMES ;DEVICE IS NOT CONNECTED . . .
ASCIZ \Device \
MOVE T2,DEVNAM(F) ;GRAB THE DEVICE NAME
PUSHJ P,PRNAME ;AND TYPE IT OUT
PUSHJ P,INLMES ;NOT CONNECTED
ASCIZ / not connected
/
PUSHJ P,TTYKLQ## ;ZAP THE USELESS DDB
POP P,U
POPJ P, ;RETURN
> ;END IFN FTNET!FTKL10!FTDECNET!FTENET
SUBTTL NETWORK COMMANDS -- NODE
CNODE:: SE1ENT ;ENTER SECTION ONE
JSP T2,SAVCTX## ;SAVE CONTEXT, RUN AT UUO LEVEL
IFE FTNET!FTDECNET,<
MOVEI T1,[ASCIZ /No network support/]
PJRST ERRMES ;REPORT ERROR AND RETURN
> ;END IFE FTNET!FTDECNET
IFN FTNET!FTDECNET,<
SKIPN [M.NET##] ;NETWORK SUPPORT IN MONITOR?
JRST [MOVEI T1,[ASCIZ /No network support/] ;NO
PJRST ERRMES] ;REPORT ERROR AND RETURN
PUSHJ P,CTEXT1 ;GET THE ARGUMENT
IFN FTNET,<
PUSHJ P,NODE.A## ;ANF-10 NODE?
SKIPA ;NO
POPJ P, ;DONE
> ;END IFN FTNET
IFN FTDECNET,<
PUSHJ P,NODE.D## ;DECNET NODE?
SKIPA ;NO
POPJ P, ;DONE
>; END IFN FTDECNET
UNDERR::MOVEI T1,[ASCIZ /Undefined network node/]
PJRST ERRMES ;PRINT ERROR MESSAGE AND RETURN
> ;END IFN FTNET!FTDECNET
SUBTTL SAVE, SSAVE AND GET - COMMAND SETUP
; "SSAVE DEVICE:FILNAM.EXT [PROJ,R] CORE"
;WORKS LIKE SAVE, EXCEPT THAT HIGH SEG IS SAVED AS SHARABLE(EXT=SHR)
;INSTEAD OF NON-SHARABLE(EXT=HGH)
; "SAVE DEVICE:FILE-NAME[PROJ.,PROG.] CORE" - SAVES JOB AREA ON RETRIEVABLE DEVICE
;ONLY A SAVE OR A GET IN PROGRESS FOR EACH JOB
;NO ATTEMPT IS MADE TO SAVE DEVICE ASSIGNMENTS, AC'S, OR PC
NSAVE:: TLO S,NSRBIT ;SET FLAG FOR SAVE
NSSAVE::MOVSI T1,(JS.EXE) ;GET EXE BIT
IORM T1,JBTST2##(J) ;SET IT IN JOB STATUS WORD
JRST SSAVE2 ; AND CONTINUE AS BEFORE
SAVEO:: TLO S,NSRBIT ;OLD SAVE
JRST SSAVE1
CSAVE:: TLO S,NSRBIT ;SET FLAG FOR NON-SHARABLE EXT(HGH)
SSAVE:: MOVE T1,CNFST2## ;CHECK CONFIG BIT FOR EXE FILE SAVES
TRNE T1,ST%EXE ;IF ON,...
JRST NSSAVE ;... PROCEED AS IN "NSAVE"
SSAVE1::MOVSI T1,(JS.EXE) ;GET EXE BIT
ANDCAM T1,JBTST2##(J) ;CLEAR IT JUST FOR SAFETY
SSAVE2: TLO P1,GTSAV ;FLAG THAT DOING A SAVE
HRRI S,SAVJOB ;SETUP TO RUN SAVJOB (S CLEARED BEFORE CALL)
JRST SGSETD
; SAVE UUO - CALLED LIKE RUN AND GETSEG UUOS
USAVE:: MOVE T2,JBTSTS##(J) ;GET JOB STATUS
TLNE T2,JLOG ;LOGGED IN?
JRST USAVE1 ;YES, OK
MOVEI T1,NLIERR ;NOT LOGGED IN ERROR
PUSHJ P,SGRELE ;TRY TO TELL USER
MOVEI T1,LOGPLM ;ADDRESS OF ERROR TEXT
JRST PHOLD## ;START TTY AND STOP JOB
USAVE1: MOVSI T2,(JS.EXE) ;EXE-STYLE SAVE BIT
IORM T2,JBTST2##(J) ;SET FOR THIS USER
TLO P1,GTSAV ;DON'T KILL HISEG IF GETARG ABORTS
MOVEM P1,.JDAT+SGAEND ;A SAFER PLACE TO BE
PUSHJ P,GETARG ;GET USER'S ARGUMENTS
SKIPGE .JDAT+SGANEW ;EXTENDED CORE ARG GIVEN?
JRST IUUAGL## ;YES, MUSN'T DO THAT FOR SAVE (YET)
MOVE T1,DEVMOD(F) ;GET DEVICE TYPE
TLNN T1,DVDSK ;IS IT A DISK?
JRST [MOVEI T1,ILUERR ;GET ERROR CODE
PUSHJ P,SGRELE ;TRY TO TELL USER
PJSP T1,PHOLD## ;GIVE UP
ASCIZ\SAVE. UUO only valid for disks\]
TLNE T1,DVTTY ;IS IT NUL?
JRST [POP P,(P) ;POP OFF JUNK
JRST CPOPJ1] ;AND GIVE GOOD RETURN
GETPC T1,.JDAT+JOBPD1## ;GET UUO RETURN ADDR
TRNN T1,^-17 ;FROM THE ACS?
HRRZS .JDAT+JOBPD1## ;YES, SAY NOT FROM USER
IFN FTMP,<
PUSHJ P,CLRJSP## ;ENSURE MONITOR RUNS ON MASTER CPU
>
OPEN 0,SGAMOD ;OPEN THE SPECIFIED DEVICE
JRST SGERRU ;DEVICE WENT AWAY
SKIPL .JDAT+JOBPD3##+1 ;DID USER SPECIFY SHARABLE?
TLO S,NSRBIT ;NO, MAKE IT NONSHARABLE
MOVEI T2, 'EXE' ;GET THE LEGAL EXTENSION
HRLM T2,.JDAT+SGAEXT ;STORE IN ENTER BLOCK
PUSHJ P,SETEXT## ;AND SET UP SGALOW AND SGAHGH
MOVE T1,['SAVUUO'] ;WHAT WE'RE DOING
MOVEM T1,.USUAC+4 ;FOR THOSE WHO CARE
GETPC T1,.JDAT+JOBPD1## ;OUR NOMINAL RETURN ADDR
MOVEM T1,.USUAC+6 ;SALT IT AWAY
TLNN T1,USRMOD ;WILL WE EVER RETURN?
JRST USAVE2 ;NO, SO SKIP THIS
PUSH P,.PDTMI##(W) ;SAVE SOME VM LOCS
PUSH P,.PDTMC##(W)
USAVE2: HLRZ T1,JBTADR##(J) ;GET HIGHEST ADDRESS IN LOW SEG
HRRZS T2,.JDAT+SGANEW ;CLEAR JUNK FROM LH (FOR COMPATABILITY)
CAMGE T1,T2 ;COMPARE WITH USER STORED CORE ARG
MOVE T1,T2 ;USER'S WAS LARGER, USE IT
HRRM T1,.JDAT+JOBCOR## ;AND SET UP JOBCOR.
PUSHJ P,RMVPFH## ;GET RID OF PFH
PUSHJ P,ADJCOR## ;SET UP GOOD CORE ARG
PJRST SAVEXE ;GO SAVE A FILE
SUBTTL SEGOP. UUO
;
;CALL: XMOVEI AC,ARGLIS
; SEGOP. AC,
; ERROR CODE IN AC
; SUCCESS, AC UNCHANGED
;
;
SEGOP:: PUSHJ P,SXPCS## ;VALIDATE THE ARG BLOCK POINTER
JRST SOPADC ;ADDRESS ERROR
MOVE M,T1 ;COPY FOR FETCHING
PUSHJ P,GETEWD## ;GET LENGTH,,FCN
JRST SOPADC ;ADDRESS ERROR
MOVE T4,T1 ;SAVE IT
HLRZ T2,T1 ;GET LENGTH OF ARG BLOCK
HRRES T1 ;ISOLATE FUNCTION CODE
CAML T1,[SEGCMX] ;LEGAL CUSTOMER FUNCTION?
CAILE T1,SEGFMX ;LEGAL FUNCTION CODE?
JRST SOPILF ;NOPE
CAMGE T2,SEGMLN(T1) ;ARGUMENT LIST LONG ENOUGH?
JRST SOPATS ;NO, ARGUMENT LIST TOO SHORT
MOVE T1,M ;GET ADDRESS OF ARG LIST
PUSHJ P,ARNGE## ;ADDRESS CHECK THE ARG BLOCK ITSELF
JRST SOPADC ;NOT ALL ADDRESSABLE
JRST SOPADC ;CAN'T STORE RESULTS
HRRE T1,T4 ;GET FCN CODE AGAIN
PJRST @SEGJMP(T1) ;AND GO FOR IT
DEFINE SOPFNS,<
SOPFUN (4,SOPINF) ;(0) GET SEGMENT INFO
SOPFUN (7,SOPGET) ;(1) GET A SEGMENT
SOPFUN (3,SOPREL) ;(2) RELEASE SEGMENT(S)
SOPFUN (6,SOPRMP) ;(3) REMAP
SOPFUN (3,SOPSWP) ;(4) SETUWP
SOPFUN (6,SOPCOR) ;(5) CORE
SOPFUN (3,SOPDMP) ;(6) RETURN A LIST OF SEGMENTS IN SOME ADR SPACE
>
DEFINE SOPFUN(LENGTH,DISPATCH),<IFIW DISPATCH>
;DISPATCH TABLE OF SEGOP.
;CUSTOMER FUNCTIONS GO HERE
CSEGJM:
SEGJMP: SOPFNS
SEGFMX==.-SEGJMP-1
SEGCMX==SEGJMP-CSEGJM
DEFINE SOPFUN(LENGTH,DISPATCH),<EXP LENGTH>
;TABLE OF MINIMUM LEGAL LENGTHS OF ARGUMENT LIST FOR VARIOUS FUNCTIONS
SEGMLN: SOPFNS ;TABLE OF MINIMUM LENGTHS
;ERROR RETURNS
SOPNSS: MOVEI T1,FNFERR ;NO SUCH SEGMENT
JRST STOTAC## ;STORE ERROR CODE
SOPNCA: MOVEI T1,NECERR ;NOT ENOUGH CORE AVAILABLE
JRST STOTAC## ;STORE ERROR CODE
SOPILF: MOVEI T1,ILUERR ;ILLEGAL FUNCTION
JRST STOTAC## ;STORE ERROR CODE
SOPCCW: MOVEI T1,WLKERR ;CAN'T WRITE ENABLE SEGMENT
JRST STOTAC## ;STORE ERROR CODE
SOPADC: MOVEI T1,ACRERR ;ADDRESS CHECK READING ARGUMENTS
JRST STOTAC## ;STORE ERROR CODE
SOPACS: MOVEI T1,ACSERR ;ADDRESS CHECK STORING ARGUMENTS
JRST STOTAC## ;STORE ERROR CODE
SOPATS: MOVEI T1,ATSERR ;ARGUMENT LIST TOO SHORT
JRST STOTAC## ;STORE ERROR CODE
SOPIAL: MOVEI T1,NZAERR ;ILLEGAL ARGUMENT LIST
JRST STOTAC ;STORE ERROR CODE
SOPNSA: MOVEI T1,NFSERR ;NO FREE SECTION
JRST STOTAC## ;STORE ERROR CODE
SOPSII: MOVEI T1,SIIERR ;SEG INFO INCONSISTANT (NAME AND NUMBER DON'T AGREE)
JRST STOTAC## ;STORE ERROR CODE
;FUNCTION 0 - GET SEGMENT INFORMATION
SOPINF: PUSHJ P,SAVE4## ;SAVE SOME WORKING ACS
PUSHJ P,GETEW1## ;GET FLAGS AND CONTEXT NUMBER
JRST SOPADC ;ADDRESS CHECK
TRNN T1,-1 ;ALLOW 0 TO MEAN CURRENT CONTEXT
HRR T1,.CPJCH## ;GET CURRENT CONTEXT NUMBER
PUSHJ P,PUTEWD## ;STORE BACK POSSIBLY UPDATED JCH
JRST SOPACS ;ADDRESS CHECK
MOVE P1,T1 ;SAVE FLAGS AND CONTEXT NUMBER
HRRZS T1 ;JUST CONTEXT NUMBER
PUSHJ P,CTXSGN## ;GET JBTSGN ENTRY FOR CURRENT CONTEXT
JRST SOPNSS ;NO SUCH SEGMENT
JUMPE T1,SOPNSS ;NO SEGMENTS BELONG TO CONTEXT IF JBTSGN = 0
;HERE WITH T1 = JBTSGN FOR SPECIFIED CONTEXT
MOVE P2,T1 ;SAVE JBTSGN
PUSHJ P,GETEW1## ;GET SEGMENT NUMBER
JRST SOPADC ;ADDRESS CHECK
MOVE P3,T1 ;SAVE THAT
PUSHJ P,GETEW1## ;GET SEGMENT NAME
JRST SOPADC ;ADDRESS CHECK
HRRI M,-1(M) ;BACK M UP TO SEGMENT NUMBER IN CASE OF STORING
MOVE P4,T1 ;SAVE NAME
JUMPE P3,SOPIN1 ;JUMPE IF SEGMENT NUMBER = 0
HRRZ J,P1 ;CONTEXT NUMBER
HRRZ T1,P3 ;SEGMENT NUMBER
PUSHJ P,CFNDHB## ;FIND THE HIGH SEGMENT BLOCK FOR THIS SEGMENT
JRST SOPNSS ;NO SUCH SEGMENT
MOVE J,.CPJOB## ;RESTORE JOB NUMBER
MOVE P2,T1 ;HIGH SEGMENT BLOCK ADDRESS
JUMPE P4,SOPIN4 ;GO IF NO NAME SPECIFIED
CAME P4,.HBHNM(P2) ;NAME SPECIFIED, MUCH MATCH
JRST SOPSII ;SEGMENT INFORMATION INCONSISTANT
JRST SOPIN4 ;COPY SEGMENT INFO AND RETURN
;HERE TO SEARCH FOR A NAME IF GIVEN
SOPIN1: JUMPE P4,SOPIN4 ;GO IF NO NAME
SOPIN2: CAMN P4,.HBHNM(P2) ;NAME MATCH?
JRST SOPIN3 ;YES, WE HAVE A WINNER
SKIPE P2,.HBLNK(P2) ;NEXT SEGMENT BLOCK
JRST SOPIN2 ;SEE IF IT MATCHES
JRST SOPNSS ;NO SUCH SEGMENT
SOPIN3: MOVE P3,.HBSGN(P2) ;INDICATE WE HAVE A SEGMENT NUMBER
MOVE T1,P3 ;ARGUMENT FOR PUTEWD
PUSHJ P,PUTEWD## ;STORE SEGMENT NUMBER BACK IN USER'S ARG BLOCK
JRST SOPACS ;ADDRESS CHECK
;HERE TO CHECK FOR STEP FLAG. P1=FLAGS, P2=SEGMENT BLOCK, P3=SEGMENT NUMBER
SOPIN4: TLNN P1,(1B0) ;STEP FLAG? (SG.STP)
JRST SOPIN6 ;NO, RETURN INFO FOR CURRENT SEGMENT
SKIPE P3 ;IF AT START OF CHAIN, GET FIRST SEGMENT NUMBER
SKIPE P2,.HBLNK(P2) ;YES, GET NEXT SEGMENT BLOCK
JRST SOPIN5 ;GO IF NOT THE LAST
MOVEI T1,0 ;SIGNIFY END WITH 0 FOR SEGMENT NUMBER AND NAME
PUSHJ P,PUTEWD## ;STORE SEGMENT NUMBER
JRST SOPACS ;ADDRESS CHECK
PUSHJ P,PUTEW1## ;AND NAME
JRST SOPACS ;ADDRESS CHECK
JRST CPOPJ1## ;GOOD RETURN TO THE USER
SOPIN5: SKIPGE P3,.HBSGN(P2) ;GET SEGMENT NUMBER (INDICATE ONE FOUND)
JRST SOPIN4 ;FIND A REAL (NOT SPY) SEGMENT
MOVE T1,P3 ;FOR PUTEWD
PUSHJ P,PUTEWD## ;STORE IT FOR THE USER
JRST SOPACS ;ADDRESS CHECK
SOPIN6: JUMPE P3,SOPNSS ;NUMBER AND NAME WERE 0 AND SG.STP WAS OFF
HRRI M,-2(M) ;POSITION M FOR COPSGN
PUSHJ P,COPSGN ;COPY SEGMENT DATA TO USER'S ARGUMENT BLOCK
JRST STOTAC## ;SOMETHING WENT WRONG
JRST CPOPJ1## ;GOOD RETURN
;FUNCTION 1 - GET A SEGMENT
SOPGET: MOVE P2,USRJDA## ;THIS IS VERY SENSITVE TO STACK ORDER
;SEE SGRELE!!!
PUSHJ P,SAVE2## ;MAKE AC SPECIFIED IN THE SEGOP. BE AT
; JOBPD1+3. SGRELE EXPECTS TO FIND IT THERE
MOVEI T1,.USUAC ;SPEC SAYS USER'S ACS SURVIVE THIS
EXCTUX <BLT T1,.USUAC+17> ;SO SAVE THEM
PUSHJ P,GETEW1## ;GET FLAGS WORD
JRST SOPADC ;ADDRESS CHECK
MOVE P1,T1 ;SAVE FLAGS
LDB T1,[POINT 5,P1,17] ;GET SECTION NUMBER FIELD
TLNN P1,(1B2) ;SG.FFS? (FIND FREE SECTION)
JRST SOPGE2 ;NO, SEE IF SECTION NUMBER SPECIFIED
MOVEI T1,1 ;START AT SECTION 1
SOPGE1: SKIPN .UPMP+SECTAB(T1);THIS SECTION FREE?
JRST SOPGE3 ;YES, USE IT
CAIGE T1,MXSECN ;LOOKED AT ALL SECTIONS?
AOJA T1,SOPGE1 ;NO, LOOK AT NEXT
JRST SOPNSA ;NO AVAILABLE SECTIONS
SOPGE2: TLNN P1,(1B1) ;SG.USN? (USE SECTION NUMBER)
JRST SOPGE4 ;NO, USE PCS SECTION
SOPGE3: EXCH P1,T1 ;SECTION NUMBER TO P1, FLAGS TO T1
DPB P1,[POINT 5,T1,17] ;SECTION NUMBER TO RETURNED ARGUMENT
TLZ T1,(1B2) ;CLEAR FFS
TLO T1,(1B1) ;SET USN
PUSHJ P,PUTEWD## ;STORE THAT FOR THE USER
JRST SOPACS ;ADDRESS CHECK
LSH P1,S2PLSH ;POSITION SECTION NUMBER FOR .USUSN
MOVEM P1,.USUSN ;STORE THAT FOR THE GETSEG
SOPGE4: UMOVE T1,5(M) ;GET POINTER TO FILE SPEC
MOVEI T2,11 ;LENGTH OF FILE SPEC
PUSHJ P,ARNGE## ;CHECK IT
JRST SOPADC ;ADDRESS CHECK
JFCL ;NOT LEGAL FOR I/O, DON'T CARE SINCE ONLY READING
MOVE M,T1 ;SETUP M FOR FETCHING FILE SPEC
PUSHJ P,GETEWD## ;GET FIRST ARG FROM USER AREA
JRST GETADC ;ADDRESS CHECK (SHOULDN'T HAPPEN)
MOVEM T1,.JDAT+SGADEV ;STORE DEVICE NAME
PUSHJ P,GETEW1## ;GET NEXT ARG FROM USER AREA
JRST GETADC ;ADDRESS CHECK (SHOULDN'T HAPPEN)
MOVEM T1,.JDAT+SGANAM ;STORE FILE NAME FOR LOOKUP (DO NOT STORE FOR LOWSEG)
PUSHJ P,GETEW1## ;GET THIRD ARG(EXTENSION WORD E+1)
JRST GETADC ;ADDRESS CHECK (SHOULDN'T HAPPEN)
MOVEM T1,.JDAT+SGAEXT ;STORE EXTENSION AND RH FROM USER
PUSHJ P,GETEW1## ;GET FOURTH USER ARG FROM USER AREA
JRST GETADC ;ADDRESS CHECK (SHOULDN'T HAPPEN)
MOVEM T1,.JDAT+JOBUAL##+2 ;STORE PROJECT PROGRAMER NO. OR 0 IN PATH
SKIPE T1 ;IF PPN = 0, MAKE E+3 = 0
MOVEI T1,JOBUAL## ;ADDRESS OF PATH BLOCK
MOVEM T1,.JDAT+SGAPPN ;POINT AT PATH BLOCK
HLRZ T2,.JDAT+SGAEXT ;PUT ARG IN T2, SO SAME AS SGSET RETURN FROM CTEXT
CAIE T2,'SHR' ;SEE IF THE USER
CAIN T2,'HGH' ; GAVE A BAD EXT
MOVEI T2,0 ;YES--IGNORE IT
PUSHJ P,SETEX1## ;SAVE EXT AGAIN IN SGALOW
; SETUP EXT FOR HIGH SEG(SGAHGH="SHR")
; SETUP EXTENSION FOR LOW SEG(SGALOW="SAV")
SKIPN .JDAT+SGAPPN ;IF PPN = 0,
JRST SOPGE6 ; DON'T BOTHER WITH SFD'S
MOVSI P1,-MAXLVL## ;NUMBER OF SFDS
SOPGE5: PUSHJ P,GETEW1## ;GET NEXT SFD
JRST GETADC ;ADDRESS CHECK (SHOULDN'T HAPPEN)
MOVEM T1,.JDAT+JOBUAL##+3(P1) ;STORE NEXT SFD
SKIPE T1 ;DONE IF A ZERO
AOBJN P1,SOPGE5 ;LOOP FOR ALL SFD'S
SETZM .JDAT+JOBUAL##+3(P1) ;TERMINATE LIST (IN CASE MAXLVL SFDS)
SOPGE6: MOVE P1,.JDAT+JOBPD3##+1 ;PHONLY
PUSHJ P,SG2A ;GO SET UP LOWER CORE
; DO NOT DO A RESET
SETZM USRJDA## ;SO OPEN WON'T RELEASE IT
MOVSI T1,GTHGH+GTSGO ;GET ONLY HIGH SEGMENT BEING DONE FROM SEGOP.
PUSHJ P,[PUSH P,(P) ;SO SGETHI WILL HAVE SOMETHING TO POP OFF THE
JRST SGETHI##] ; SINCE THERE ISN'T A CALL TO GETARG HERE
STOPCD (GETNSS,DEBUG,GDS) ;++GETSEG DIDN'T SKIP
MOVE T1,.CPJOB## ;CURRENT JOB'S JOB NUMBER
PUSHJ P,CTXJCH## ;GET CURRENT JCH
MOVE T1,.CPJOB## ;NONE, USE CURRENT JOB NUMBER
HRRZ M,.JDAT+JOBPD3##+1 ;AC USER SPECIFIED IN THE SEGOP.
MOVE M,.USUAC(M) ;ADDRESS OF SEGOP. ARGUMENT BLOCK
MOVE J,T1 ;FOR FNDFSN AND A CONVENIENT PLACE TO SAVE T1
PUSHJ P,GETEW1## ;GET FLAGS WORD
JRST GETADC ;ADDRESS CHECK
HRR T1,J ;CURRENT JCH
PUSHJ P,PUTEWD## ;STORE THAT (NEEDED FOR COPSGN)
JRST GETADC ;ADDRESS CHECK
PUSHJ P,FNDFSN ;FIND SEGMENT NUMBER OF SEGMENT JUST GOTTEN
JRST GETNSS ;REALLY CAN'T HAPPEN
PUSHJ P,PUTEW1## ;STORE THAT BACK
JRST GETADC ;ADDRESS CHECK
SUBI M,2 ;BACK UP TO BEGINNING OF THE BLOCK
PUSHJ P,COPSGN ;NOW COPY SEGMENT INFO FOR SEGMENT JUST GOTTEN
JRST GETSEC ;BAD NEWS
MOVSI T1,.USUAC ;RESTORE USER'S AC
EXCTXU <BLT T1,17> ; ..
MOVE T1,.JDAT+JOBPD3##+2 ;USER'S STORED CHANNEL 0
MOVEM T1,USRJDA## ;RESTORE THAT
JRST CPOPJ1## ;AND GIVE GOOD RETURN
;ERRORS
GETADC: SKIPA T1,[ACSERR]
GETNSS: MOVEI T1,[FNFERR]
GETSEC: MOVSI T2,.USUAC ;RESTORE USER'S ACS
EXCTXU <BLT T2,17> ; ..
MOVE T2,.JDAT+JOBPD3##+2 ;USER'S STORED CHANNEL 0
MOVEM T2,USRJDA## ;RESTORE THAT
HRRZ M,.JDAT+JOBPD3##+1 ;USERS AC
PJRST PUTWDU## ;STORE ERROR CODE AND RETURN (CAN'T ADDRESS
; CHECK STORING IN AN AC)
;FUNCTION 2 - RELEASE A SEGMENT OR SEGMENTS
SOPREL: PUSHJ P,SAVE1## ;SAVE AN AC
PUSHJ P,GETEW1## ;GET THE FLAGS WORD
JRST SOPADC ;ADDRESS CHECK
MOVE P1,T1 ;SAVE FLAGS
PUSHJ P,GETEW1## ;FIRST SEGMENT NUMBER
JRST SOPADC ;ADDRESS CHECK
TLNE P1,(1B1) ;SG.USN?
JRST SOPRL1 ;YES
;HERE TO REMOVE ALL SEGMENTS OR A LIST OF SEGMENTS
JUMPN T1,SOPRL2 ;JUMP IF A LIST
;REMOVE ALL SEGMENTS
AOS (P) ;SKIP RETURN
PJRST KILHGA## ;REMOVE ALL SEGMENTS
SOPRL1: LDB T1,[POINT 5,P1,17]
PUSHJ P,SVPCS## ;SETUP PCS FOR THE SECTION IN QUESTION
SETZ T1, ;KILL ALL SEGMENTS IN PCS SECTION
PUSHJ P,KILHGC## ;DO THE WORK
SOPRL2: SOS M ;SO CAN CALL GETEW1
SOPRL3: PUSHJ P,GETEW1## ;NEXT SEGMENT NUMBER
JRST SOPADC ;ADDRESS CHECK
JUMPE T1,CPOPJ1## ;EXIT IF LAST SEGMENT
PUSHJ P,FNDHSB## ;FIND THE HIGH SEGMENT BLOCK ADDRESS
JRST SOPRL3 ;OK IF THERE ISN'T ONE
PUSHJ P,KILHGH## ;KILL OF THIS SEGMENT
JRST SOPRL3 ;LOOP FOR NEXT SEGMENT NUMBER
;FUNCTION 3 - MAKE A SEGMENT FROM "LOW SEGMENT PAGES" (REMAP)
SOPRMP: PUSHJ P,SAVE1## ;SAVE AN AC
MOVE P1,M ;THE HARDEST PART OF THIS IS KEEPING TRACK OF M
HRRI M,3(M) ;POINT AT NAME WORD
PUSHJ P,GETEWD## ;GET NAME
JRST SOPADC ;ADDRESS CHECK
MOVEM T1,.JDAT+SGANAM ;STORE IT FOR REMAP
PUSHJ P,GETEW1## ;GET CURRENT AND NEW ORIGIN
JRST SOPADC ;ADDRESS CHECK
HRRZM T1,.JDAT+JOBUAL##+1 ;CURRENT ORIGIN
HLRZM T1,.JDAT+JOBUAL##+2 ;NEW ORIGIN
PUSHJ P,GETEW1## ;GET NUMBER OF PAGES TO BE REMAPPED
JRST SOPADC ;ADDRESS CHECK
MOVEM T1,.JDAT+JOBUAL## ;NUMBER OF PAGES
MOVSI T1,GTSGO ;INDICATE SEGOP
MOVEM T1,.JDAT+SGAEND ;WHERE FLAGS ARE STORED
MOVE T1,[3,,JOBUAL##];THREE ARGUMENTS AT JOBUAL
PUSHJ P,SREMAP## ;DO THE WORK
POPJ P, ;ERROR CODE STORED (SHOULD IT BE REMAPPED?)
PUSHJ P,FNDFSN ;GET THE SEGMENT NUMBER OF SEGMENT JUST CREATED
JRST SOPNSS ;NO SUCH SEGMENT - SHOULDN'T HAPPEN
AOS M,P1 ;POINT M AT FLAGS WORD
MOVE P1,T2 ;PARINOIA (PUTEWD PROBABLY DOESN'T SMASH T2, BUT ...)
PUSHJ P,PUTEW1## ;BUMP M TO SEGMENT NUMBER WORD AND STORE ANSWER
JRST SOPACS ;ADDRESS CHECK
MOVE T1,P1 ;GET SEGMENT NAME BACK
PUSHJ P,PUTEW1## ;STORE THAT FOR THE USER (PROBABLY SAME AS SUPPLIED)
JRST SOPACS ;ADDRESS CHECK
JRST CPOPJ1## ;USER DID GOOD
;FUNCTION 4 - SETUWP (ON/OFF) FOR A SEGMENT
SOPSWP: PUSHJ P,SAVE2## ;SAVE SOME ACS
PUSHJ P,GETEW1## ;GET FLAGS WORD
JRST SOPADC ;ADDRESS CHECK
MOVE P1,T1 ;SAVE UWP ON/OFF FLAG
PUSHJ P,GETEW1## ;GET SEGMENT NUMBER
JRST SOPADC ;ADDRESS CHECK
PUSHJ P,FNDHSB## ;FIND HIGH SEGMENT BLOCK FOR THIS SEGMENT
JRST SOPNSS ;NO SUCH SEGMENT
MOVE T2,T1 ;HIGH SEGMENT BLOCK ADDRESS TO T2
MOVS M,.USMUO ;MAKE GETTAC WORK
PUSHJ P,GETTAC## ;GET CONTENTS OF USER'S AC
PUSH P,T1 ;SAVE THAT (SOSUWP STORES THERE)
PUSH P,T1 ;SAVE AS ADDRESS TO WRITE TO AS WELL
PUSHJ P,SOSUWP## ;DO THE WORK
JRST [MOVEI T1,WLKERR;FAILED, CAN'T SET UWP OFF FOR THE SEGMENT
MOVEM T1,-1(P) ;ERROR CODE FOR THE USER
SOS -2(P) ;SET FOR ERROR RETURN
JRST .+1] ;CONTINUE
PUSHJ P,GETTAC## ;GET WHAT SOSUWP STORED AS CURRENT VALUE OF UWP
POP P,M ;BACK UP TO FLAGS WORD
PUSHJ P,PUTEW1## ;STORE PREVIOUS (CURRENT IF ERROR) VALUE OF UWP
JRST SOPACS ;ADDRESS CHECK
POP P,T1 ;CONTENTS OF USER'S AC OR ERROR CODE
JRST STOTC1## ;STORE THAT AND RETURN
;FUNCTION 5 - DO A CORE UUO FOR A SEGMENT
SOPCOR: PUSHJ P,SAVE2## ;SAVE SOME ACS
HRRI M,2(M) ;POINT AT SEGMENT NUMBER
PUSHJ P,GETEWD## ;GET SEGMENT NUMBER
JRST SOPADC ;ADDRESS CHECK
SKIPE P1,T1 ;SAVE SEGMENT NUMBER
PUSHJ P,FNDHSB## ;VALIDATE HIGH SEGMENT NUMBER
JRST SOPNSS ;NO SUCH SEGMENT
MOVE P2,T1 ;SAVE ADDRESS OF HIGH SEGMENT BLOCK
LDB T1,[PSG2LH+.HBSG2(T1)] ;SECTION CONTAINING THE SEGMENT
PUSHJ P,SVPCS## ;SET PCS TO THAT
HRRI M,3(M) ;POINT AT SEGMENT SIZE FIELD
PUSHJ P,GETEWD## ;GET SIZE (CORE UUO ARGUMENT)
JRST SOPADC ;ADDRESS CHECK
JUMPLE T1,SOPIAL ;ZERO OR A NEGATIVE ARGUMENT IS ILLEGAL
HRRZ J,.HBSGN(P2) ;GET SEGMENT NUMBER
LDB P2,JBYHSO## ;SEGMENT ORIGIN WITHIN SECTION
LSH P2,P2WLSH ;CONVERT TO ADDRESS
LSH T1,P2WLSH ;SIZE OF SEGMENT IN WORDS AFTER CORE IS DONE
ADDI T1,-1(P2) ;HIGHEST RELATIVE ADDRESS IN SEGMENT
TLNE T1,-1 ;TRYING TO GROW OUTSIDE THE SECTION?
JRST SOPIAL ;YES, ILLEGAL ARGUMENT
HRLZS T1 ;WHERE CHGCOR WANTS THE ARGUMENT
MOVE J,P1 ;SEGMENT NUMBER TO J
PUSHJ P,CHGCOR## ;DO THE CORE UUO
JRST SOPNCA ;NOT ENOUGH CORE
JRST CPOPJ1## ;SUCCESS
;FUNCTION 6 - RETURN A LIST OF THE SEGMENTS IN THE SPECIFIED ADDRESS SPACE
SOPDMP: PUSHJ P,SAVE4## ;SAVE AN AC
PUSHJ P,GETEWD## ;GET THE LENGTH OF THE ARGUMENT BLOCK
JRST SOPADC ;ADDRESS CHECK
HLRZ P1,T1 ;LENGTH OF THE ARGUMENT BLOCK
MOVNI P1,-2(P1) ;MAKE AN AOBJN POINTER
HRLZS P1 ;TO COUNT ARGUMENTS THAT COULD HAVE BEEN STORED
PUSHJ P,GETEW1## ;GET FLAGS WORD
JRST SOPADC ;ADDRESS CHECK
TRNN T1,-1 ;IF CONTEXT IS ZERO,
HRR T1,.CPJCH## ; DEFAULT TO CURRENT CONTEXT
MOVE P3,M ;SAVE M
MOVE P4,T1 ;SAVE FLAGS
HRRZS J,T1 ;CONTEXT HANDLE TO J AND T1
PUSHJ P,CTXSGN## ;GET JBTSGN FOR SPECIFIED CONTEXT
JRST SOPNSS ;NON-EXISTANT
MOVE P2,T1 ;SAVE JBTSGN
JUMPE P2,SOPDM5 ;JUMP IF THERE AREN'T
PUSHJ P,GETEW1## ;GET STARTING SEGMENT NUMBER
JRST SOPADC ;ADDRESS CHECK
JUMPE T1,[TLNN P4,(1B0) ;ST.STP?
JRST SOPNSS ;NO, STARTING SEGMENT NUMBER = 0, ST.STP OFF
JRST SOPDM1];YES, START AT THE BEGINNING
HRRZS T1 ;ARGUMENTS FOR FNDHSB
PUSHJ P,CFNDHB## ;GET THE HIGH SEGMENT BLOCK FOR THIS CONTEXT
JRST SOPNSS ;NO SUCH SEGMENT
TLNE P4,(1B0) ;SG.STP? (STEP FLAG)
SKIPN P2,.HBLNK(T1) ;ADVANCE TO NEXT BLOCK IF THERE IS ONE
SOJA M,SOPDM5 ;THERE IS, RETURN SEGMENT NUMBER FROM IT
SOPDM1: HRRI M,-1(M) ;BACK UP TO SEGMENT WORD
SOPDM2: SKIPG T1,.HBSGN(P2) ;GET A SEGMENT NUMBER
JRST SOPDM3 ;SPY SEGMENT
PUSHJ P,PUTEW1## ;STORE SEGMENT NUMBER
JRST SOPACS ;ADDRESS CHECK
AOBJP P1,SOPDM4 ;GO IF ALL THE USER ASKED FOR HAVE BEEN STORED
SOPDM3: SKIPE P2,.HBLNK(P2) ;NEXT HIGH SEGMENT BLOCK
JRST SOPDM2 ;STORE THE NXEXT HIGH SEGMENT NUMBER
JRST SOPDM5 ;ALL DONE
SOPDM4: SKIPN P2,.HBLNK(P2) ;COUNT NUMBER THAT COULD HAVE BEEN STORED
JRST SOPDM5 ;NO MORE
SKIPG .HBSGN(P2) ;A REAL HIGH SEGMENT? (NOT SPY)
JRST SOPDM4 ;NO, DON'T COUNT IT
AOJA P1,SOPDM4 ;YES, COUNT ANOTHER SEGMENT
SOPDM5: JUMPGE P1,SOPDM6 ;IF THERE IS STILL SPACE LEFT,
MOVEI T1,0 ; TERMINATE SEGMENT NUMBER LIST WITH A 0
PUSHJ P,PUTEW1## ;STORE THAT
JRST SOPACS ;ADDRESS CHECK
SOPDM6: MOVE M,P3 ;RESTORE M
MOVE T1,P4 ;RESTORE FLAGS
DPB P1,[POINT 12,T1,17] ;RETURN NUMBER OF SEGMENTS WHICH
PUSHJ P,PUTEWD## ; COULD HAVE BEEN OR WERE RETURNED
JRST SOPACS ;ADDRESS CHECK
JRST CPOPJ1## ;SKIP RETURN TO THE USER
;SUBROUTINE TO COPY SEGMENT DATA TO USER ARGUMENT BLOCK.
;CALLING SEQUENCE:
; MOVEI M,ADDRESS OF USER ARGUMENT BLOCK
; PUSHJ P,COPSGN
; ERROR RETURN (ERROR CODE IN T1)
; GOOD RETURN
;
COPSGN: PUSHJ P,SAVE2## ;SAVE SOME WORKING ACS
PUSHJ P,GETEWD## ;GET LENGTH,,FUNCTION
JRST COPADC ;ADDRESS CHECK
HLRZ P2,T1 ;LENGTH OF THE ARGUMENT BLOCK
SUBI P2,3 ;ACCOUNT FOR MANDATORY RETURNED VALUES
PUSHJ P,GETEW1## ;GET FLAGS WORD
JRST COPADC ;ADDRESS CHECK
MOVEI J,(T1) ;CONTEXT HANDLE TO J
PUSHJ P,GETEW1## ;GET SEGMENT NUMBER WORD
JRST COPADC ;ADDRESS CHECK
PUSHJ P,CFNDHB## ;FIND THE HIGH SEGMENT BLOCK FOR THIS SEGMENT
; IN THE GIVEN CONTEXT
JRST COPNSS ;NO SUCH
MOVE P1,T1 ;P1 GET ADDRESS OF HIGH SEGMENT BLOCK
MOVE T1,.HBSGN(P1) ;GET SEGMENT NUMBER + BITS FROM HSB
HRRZ J,T1 ;J GETS HIGH SEGMENT NUMBER
PUSHJ P,PUTEWD## ;STORE SEGMNET NUMBER + BITS
JRST COPACS ;ADDRESS CHECK
MOVE T1,.HBHNM(P1) ;SEGMENT NAME
PUSHJ P,PUTEW1## ;STORE THAT
JRST COPACS ;ADDRESS CHECK
SOJE P2,CPOPJ1## ;RETURN IF ALL THE USER ASKED FOR HAS BEEN STORED
MOVE T1,P1 ;ADDRESS OF THE HSB TO T1
PUSHJ P,GETHSA ;GET HIGH SEGMENT ADDRESS
LSH T1,W2PLSH ;HIGH SEGMENT ORIGIN PAGE NUMBER
HRLS T1 ;COPY TO THE LEFT HALF
LDB T2,[PSG2LH+.HBSG2(P1)] ;SEGMENT ORIGIN SECTION
LSH T2,S2PLSH ;MAKE PAGE OFFSET
SUB T1,T2 ;LOCAL SEGMENT ORIGIN,,SEMENT ORIGIN IF GETSEG
MOVSS T1 ;PER THE SPEC
PUSHJ P,PUTEW1## ;STORE THAT
JRST COPACS ;ADDRESS CHECK
SOJE P2,CPOPJ1## ;RETURN IF ALL THE USER ASKED FOR HAS BEEN STORED
LDB T1,[PHSSLH+.HBHSZ(P1)] ;SIZE OF THE SEGMENT IN PAGES
PUSHJ P,PUTEW1## ;STORE THAT
JRST COPACS ;ADDRESS CHECK
SOJE P2,CPOPJ1## ;RETURN IF ALL THE USER ASKED FOR HAS BEEN STORED
PUSHJ P,GETEW1## ;GET POINTER TO FILE SPEC
JRST COPADC ;ADDRESS CHECK
JUMPE T1,CPOPJ1## ;ALL DONE IF ZERO
MOVE M,T1 ;FOR STORING THE FILE SPEC
MOVE T1,JBTDEV##(J) ;DEVICE SEGMENT CAME FROM
PUSHJ P,PUTEWD## ;STORE THAT
JRST COPACS ;ADDRESS CHECK
MOVE T1,JBTNAM##(J) ;FILE NAME OF FILE SEGMENT CAME FROM
PUSHJ P,PUTEW1## ;STORE THAT
JRST COPACS ;ADDRESS CHECK
MOVE T1,JBTSTS##(J) ;HIGH SEGMENT STATUS
TRNE T1,JS.SFE ;SEGMENT COME FROM AN EXE FILE?
JRST COPSG1 ;YES, EXTENSION IS 'EXE'
TLNN T1,SHRSEG ;NOT FROM AN EXE FILE, IS IT SHARABLE?
SKIPA T1,[SIXBIT/HGH/];NO, EXTENSION WAS 'HGH'
MOVSI T1,(SIXBIT/SHR/);YES, EXTENSION WAS 'SHR'
JRST COPSG2 ;STORE EXTENSION
COPSG1: MOVSI T1,(SIXBIT/EXE/);EXE EXTENSION
COPSG2: PUSHJ P,PUTEW1## ;STORE EXTENSION
JRST COPACS ;ADDRESS CHECK
SETO P1, ;ASSUME ONLY A PPN
MOVE T1,JBTPPN##(J) ;GET PPN OR PATH POINTER
TLNE T1,-1 ;PATH POINTER?
JRST COPSG4 ;NO, ONLY A PPN. GO STORE THAT
MOVSI P1,-MAXLVL##-1 ;NUMBER OF ELEMENTS TO COPY
HRR P1,T1 ;POINT AT THE PATH
COPSG3: MOVE T1,(P1) ;NEXT PATH ELEMENT
COPSG4: PUSHJ P,PUTEW1## ;STORE THAT
JRST COPACS ;ADDRESS CHECK
AOBJN P1,COPSG3 ;COPY ALL PATH ELEMENTS
JUMPN P1,CPOPJ1## ;EXIT IF PATH COPIED (TERMINATED BY 0 OR 5 SFDS)
SETZ T1, ;IF ONLY A PPN,
PUSHJ P,PUTEW1## ; TERMINATE PATH WITH A ZERO
JRST COPACS ;ADDRESS CHECK
JRST CPOPJ1## ;GOOD RETURN
;ERROR RETURNS
COPADC: MOVEI T1,ACRERR ;ADDRESS CHECK
POPJ P, ;NON-SKIP RETURN
COPACS: MOVEI T1,ACSERR ;ADDRESS CHECK STORING ARGUMENT
POPJ P, ;NON-SKIP RETURN
COPNSS: MOVEI T1,FNFERR ;NO SUCH SEGMENT
POPJ P, ;NON-SKIP RETURN
;SUBROUTINE TO FIND SEGMENT NUMBER OF FIRST SEGMENT IN .HBLNK CHAIN (LAST
; SEGMENT CREATED, REMAPPED, OR GOT)
;CALL WITH J=CONTEXT NUMBER, RETURNS CPOPJ IF NO SUCH SEGMENT, CPOPJ1, T1 =
; SEGMENT NUMBER, T2 = SEGMENT NAME (.HBHNM)
FNDFSN: MOVE T1,J ;FOR CTXSGN
PUSHJ P,CTXSGN ;GET JBTSGN FOR THIS CONTEXT
POPJ P, ;NO SUCH CONTEXT
JUMPE T1,CPOPJ## ;CONTEXT HAS NO SEGMENTS
MOVE T2,.HBHNM(T1) ;GET SEGMENT NAME
MOVE T1,.HBSGN(T1) ;SEGMENT NUMBER OF FIRST SEGMENT IN THE CHAIN
JRST CPOPJ1## ;OK RETURN
; "GET DEVICE:FILE-NAME[PROJ.,PROG.] CORE" - SETS UP JOB AREA FROM RETREIVABLE
;DEVICE AND ASSIGNS CORE.
GET:: HLLZ T2,SYSTAP## ;SETUP DEFAULT DEVICE
MOVEI S,GJOB ;SETUP TO RUN GETJOB
JRST RUNCM
; JOB DATA AREA FOR MONITOR JOB
LOGREF: PUSHJ P,ISOPCT ;SKIP IF OPR OR CTY
JRST CLOG2A ;NO, REGULAR LOGIN
SETZM REFLAG## ;ONLY ONCE
TDZA T2,T2
LOGRF1: MOVE T2,[SIXBIT/SYSJOB/]
MOVEM T1,JBTPPN##(J) ;PRJ,PRG NRS. IN REFLAG
MOVEM T2,.PDNM1##(W)
PUSHJ P,SETLOG## ;TURN ON JLOG
MOVE T1,CNFPRV## ;GET PRIVS WE WANT TO USE
MOVEM T1,JBTPRV##(J) ;GIVE OPERATOR ALL DEC PRIVILEGES
MOVEM T1,.PDCAP##(W) ;...
TLZ M,-1 ;CLEAR ALL FLAGS FOR COMRET
MOVEI T1,ACTSTL## ;LENGTH OF THE ACCOUNT STRING
JUMPE T1,LOGRF2 ;ALL DONE, IF NONE
HRRZ T2,JBTPDB##+0 ;NULL JOBS PDB
MOVSI T2,.PDACS##(T2) ;ADDRESS OF THE DEFAULT A.S.
HRRI T2,.PDACS##(W) ;ADDRESS OF JOBS A.S.
BLT T2,.PDACS##+ACTSTL##-1(W) ;FILL IN THE DEFAULT
LOGRF2: MOVE T1,[1000,,1000] ;MVPL,,MPPL
PJRST SETVLM## ;SET THEM
;SUBROUTINE TO CHECK IF LINE POINTS TO OPR OR CTY
;SAVES T1, USES T2
;RETURNS NONSKIP IF NOT OPR OR CTY, SKIP IF EITHER OPR OR CTY
ISOPCT: MOVE T2,U ;T2=ADDR OF LINE DATA BLOCK
CAMN T2,OPRLDB## ;SKIP IF NOT OPR
JRST CPOPJ1## ;YES, IT IS OPR
SE1XCT <MOVE T2,LDBDCH##(T2)> ;T2=LINE CHARACTERISTICS
TRNN T2,LDRCTY## ;SKIP IF CTY
POPJ P, ;NO, NEITHER OPR NOR CTY
JRST CPOPJ1## ;YES, IT IS CTY
SUBTTL COMMANDS WHICH RUN PROGRAMS
MNTCOM::
IFN FTMDA,<
SKIPN %SIDOL## ;MDA RUNNING?
JRST RECAL1 ;NO. RUN UMOUNT
RUNMDA::MOVE T1,[SIXBIT/QUEUE/]
JRST ARCOM
>
;FOR REMOTE USAGE OF FILE STORAGE SYSTEM
RECALL::SKIPN [M.TD10##] ;HAVE DECTAPES?
JRST COMERR ;NO
RECAL1: SKIPA T1,[SIXBIT .UMOUNT.] ;RUN UMOUNT
CCLRUN::MOVE T1,COMPIL## ;CUSP NAME
JRST ARCOM ;RUN IT
;"LOGIN" - LOGIN COMMAND
LOGDET: JSP T1,ERRMES
ASCIZ /Please KJOB or DETACH
/
CLOGIN::TLNE P4,JLOG ;FORCE USER TO LOGOUT BEFORE
JRST LOGDET ; LOGGING IN ANEW.
MOVE T1,VIRTAL## ;AMOUNT OF FREE VIRTUAL CORE LEFT
CAIGE T1,LOGSIZ## ;IS THERE AT LEAST ENOUGH FOR LOGIN?
; CUSTOMER CAN REDEFINE TO BE BIGGER THAN 2
; WITH MONGEN DIALOG
JRST COR4 ;NO--GO TELL USER AMOUNT OF CORE LEFT
SE1ENT ;NEED TO ACCESS LDB
MOVE T1,FFAPPN## ;1,2 IF LOGGING IN
LDB T2,LDPLNO## ;FRCLIN?
CAIN T2,FRCLIN##
JRST LOGRF1 ;YES, LOG IN THE JOB WITHOUT RUNNING LOGIN
SKIPE T1,REFLAG## ;REFLAG SET NON-ZERO FOR AUTOMATIC LOGIN?
JRST LOGREF ;YES, LOG USER IN WITHOUT RUNNING CUSP
CLOG2A: MOVE T1,JBTLIM##(J) ;GET OUR BATCH/LIMIT WORD
TLNE T1,(JB.LBT) ;DOING THIS FOR BATCON?
S0JRST RUNAME ;YES, DON'T CLEAR ECHO
MOVSI T1,LDLNEC## ;GO TO LOGIN, CLEAR ECHO
IORM T1,LDBDCH##(U)
MOVEI T1,IOSNEC## ;ALSO IN DDB
IORM T1,DEVIOS(F)
S0JRST RUNAME
RUNQUE::MOVE P2,QUEUE## ;SET CUSP NAME
JRST RUNAME ;GO RUN IT
IFN FTMIC,<
;HERE TO PROCESS PLEASE COMMAND (SEE IF USER IS RUNNING MIC)
RUNPLS::SE1XCT <SKIPE LDBMIC##(U)> ;IS HE RUNNING UNDER MIC?
RUNMIC::MOVSI P2,'MIC' ;YES - ITS A MIC PLEASE
JRST RUNAME ;NO - ITS A NORMAL ONE
>
IFN FTNET,<
RUNNET::MOVE P2,[SIXBIT/NETLDR/]
PUSH P,[DLYCM2]
PUSH P,T2
PUSHJ P,RUNAMC ;RUN NETLDR
JFCL
AOS (P) ;SKIP RTURN
POP P,(P)
POP P,(P)
SE1ENT ;'CAUSE WE PLAY WITH LDBS
HRRZ F,LDBDDB##(U) ;GET THE TTY'S DDB
SKIPE F
PUSHJ P,PTYDET## ;DETACH NETLDR
PJRST DETLDB## ;FREE THE LDB
;*** KROCK *** NEED TO USE FRCLIN ***
>;END FTNET
RUNMAI::MOVE P2,[M.MAIL##] ;RUN MAIL
JRST RUNAME
RUNLGN::SKIPA P2,LOGTXT## ;RUN LOGIN
RUNNFT::MOVSI P2,'NFT' ;RUN NFT
JRST RUNAME ;AT NORMAL START ADDRESS
RUNPIC::MOVSI P2,'PIP'
RUNAMC::MOVEI P1,1 ;SET CCL START
;RUNAME--COMMAND WHICH RUNS CUSP OF SAME NAME
RUNAME::TLNE P4,JLOG ;SEE IF LOGGED IN
JRST RUNAM1 ;YES--PROCEED
MOVE T1,HLPPPN## ;GET P,PN FOR JOB
MOVEM T1,JBTPPN##(J)
MOVSI P4,JLOG!JNA ;CLEAR JLOG&JNA SO COMRET DOES ALL GOOD THINGS
ANDCAB P4,JBTSTS##(J)
RUNAM1: PUSHJ P,TTYATI## ;REATTACH TTY
JFCL
MOVE T1,P2 ;GET CUSP NAME
JRST ARCOM ;FALL INTO ARCOM
; HERE ON USER DEFINED COMMANDS
PLNCOM::
; JRST ARCOM ;HANDLE LIKE OTHER SPECIAL RUN COMMANDS
; "R CUSPNAME CORE" - DOES "RUN SYS:CUSPNAME"
ARCOM: MOVEI T3,12 ;MAKE SURE NO MORE ARGS SCANNED
PUSHJ P,CTISLC## ; BY MAKING LAST CHAR READ A BREAK
MOVSI T2,JLOG ;BIT TO TEST
TDNN T2,JBTSTS##(J) ;ARE WE LOGGED IN?
JRST ARCOM1 ;NO--BYPASS AUTO-SAVE STUFF
TLZE M,SACFLG## ;NEED AN ALTERNATE CONTEXT FOR THIS COMMAND?
PUSHJ P,CTXATO## ;YES--HANDLE DIFFERENTLY (NEVER RETURNS)
ARCOM1: CAME P2,PLNTXT## ;UNLESS USER-DEFINED COMMAND,
MOVEM T1,JBTPRG##(J) ;STORE FILE NAME
RCOM:: MOVSI T2,(SIXBIT /SYS/) ;READ FROM SYS DEVICE
JRST RUNCO2
; "RUN DEVICE:FILE[PROJ.,PROG.] (CORE)"
;DOES A CORE,GET,START ALL IN ONE
;IF CORE ARG IS MISSING, SIZE IN DIRECTORY IS USED
;JOB ON DISK OR IN CORE OR NO CORE, BUT NOT IN MIDDLE OF SWAP
RUNCOM::HLLZ T2,SYSTAP## ;SET DEFAULT DEVICE DISK (DTA IN 10/40)
RUNCO2: MOVEI S,RUNJOB
RUNCM: TLZ M,ERRFLG ;ZAP ERROR FLAG TO START
IFN FTFDAE,<
PUSHJ P,CHKXTM ;SEE IF AN "EXIT" MESSAGE SHOULD BE SENT
; TO THE FILE DAEMON AND IF SO, SEND IT
>
MOVSI T1,JERR ;DON'T ALLOW CONTINUE
IORM T1,JBTSTS##(J) ; AFTER THE CORE IMAGE HAS BEEN WIPED OUT
SETZM JBTPC##(J) ;THIS IS MEANINGLESS NOW, ALSO
SKIPN R,JBTADR##(J) ;ONLY IF JOB HAS NO CORE AT ALL,
PUSHJ P,GETMIN ;GET MINIMAL JOB AREA IN CORE OR DISK
PUSHJ P,FNDPDB## ;SETUP W
JRST RUNCM1 ;NO PDB
MOVSI T1,(PD.LGO) ;CLEAR LOGOUT UUO IN PROGRESS IN CASE
ANDCAM T1,.PDDFL##(W) ; JOB BOMBED OUT DURING LOGOUT
MOVSI T1,(JS.BPR) ;ALLOWED DESPITE FORCED PGM TO RUN ?
TDNE T1,JBTST2##(J)
JRST [ANDCAM T1,JBTST2##(J) ;YES, CLEAR FLAG
JRST RUNCM1] ; AND RUN WHAT HE ASKED FOR
SKIPN T1,.PDPGM##(W) ;PROGRAM FORCED?
JRST RUNCM1 ;NO--CHARGE ON
MOVEM T1,JBTPRG##(J)
MOVSI T2,(PD.PGR) ;.STPGM RUN IN PROGRESS
IORM T2,.PDDFL##(W) ;FLAG FOR LATER USE.
MOVEI T2,12 ;STOP READING THE COMMAND
PUSHJ P,CTISLC## ; BY SAYING LAST CHAR WAS A <LF>
MOVSI T2,'SYS'
MOVSI P1,PHONLY ;INHIBIT LOG NAMES
RUNCM1: JUMPN R,SGSET ;WAS CORE ASSIGNED IN MEMORY? IF YES, GO SCANARGS
LDB T1,IMGIN## ;NO CORE IN CORE, CORE ON DISK?
JUMPE T1,COR4 ;COMPLAIN IF NONE
SKIPLE VIRTAL## ;NO, CORE LEFT ON DISK?
JRST DLYCM ;YES, DELAY COMMAND UNTIL IN CORE
JRST COR4 ;NO, PRINT "0K CORE LEFT"
SUBTTL ASSIGN, DEASSIGN AND REASSIGN COMMANDS
; "ASSIGN DEV:NAME" - ASSIGN DEVICE TO JOB AND GIVE IT LOGICAL NAME
ASSIGN::JSP T2,SAVCTX## ;SAVE THE CONTEXT OF THE JOB
PUSHJ P,CTXDEV ;GET FIRST ARGUMENT TO T2 "DEV"
JUMPE T2,NOTENF ;NO ARGUMENT TYPED IF 0
IFN FTNET,<
PUSHJ P,NETASG## ;SEE IF IT'S A "NODE_DEV" FORM
; AND IF IT IS TRANSLATE IT TO "GGGNNU"
POPJ P, ;BAD DEVICE NAME (ERROR MSG ALREADY PRINTED)
>;END IFN FTNET
MOVE P4,T2 ;SAVE DEVICE NAME
PUSHJ P,SKIPS1 ;FLUSH SPACES AND TABS
JRST ASSG1 ;END-OF-LINE IS OK
PUSHJ P,CTEX ;NEXT CHAR MUST BE ALPHANUMERIC
JRST COMERA ;NOT, THAT'S AN ERROR
ASSG1: PUSH P,U ;SAVE TTY LDB
MOVE T1,P4 ;DEVICE NAME IN T1
PUSHJ P,DEVSRC## ;LOOK FOR THE DEVICE (ALSO LOGICAL NAME)
JRST ASSG3 ;NOT A PHYSICAL NAME
JRST ASSG4 ;A SPECIFIC PHYSICAL NAME
ASSG3: SETZ T3, ;ANY DEVICE EXIST
PUSHJ P,DVSRSP##
JRST ASSFAL ;NO - ERROR
LDB T3,DEYSPL## ;YES. SPOOL BIT
SKIPE DEVCHR(F)
TDNE T3,JBTSPL##(J) ;THIS DEV SPOOLED?
JRST ASSG3A ;YES, GO FAKE UP A DDB
PUSH P,F
MOVEI T3,ASSCON+ASSPRG;FLAG ASSIGNED DEV AS UNACCEPTEABLE
PUSHJ P,DVASRC## ;SEARCH FOR GENERIC NAME
JRST ASSG3B
POP P,(P)
ASSG3A: MOVEI T2,ASSCON ;SET ASSIGNED BY CONSOLE BIT
PUSHJ P,ASSASG## ;GO ASSIGN DEVICE
JRST ASSER8 ;DEVICE NOT AVAILABLE
JRST ASSFIN ;SUCCESS ON ASSIGN
;HERE IF SOME DEVICE OF THIS FLAVOR EXISTS
ASSG3B: POP P,F ;F POINTS TO THE DDB IF "DEVX"
TRNE T1,770000 ;IS IT DEVX:
TRNE T1,7700
TRZA T1,-1 ;NO, CLEAR RIGHT HALF GO TO ASSFAL
JRST ASSG4 ;YES, TREAT AS PHYSICAL DEVICE
;HERE WHEN A GENERIC ASSIGN FAILS
;USES 3 FLAGS IN LH OF P3
ASF.SP==1B0 ;SOMETHING HAS BEEN PRINTED
ASF.MJ==1B1 ;AT LEAST 1 ASSIGNED TO MY JOB
ASF.RD==1B2 ;RESTRICTED DEVICE
ASSFAL: POP P,U ;RESTORE TTY LDB
JUMPGE T4,NOTDEV ;NO DEVICES FOUND - GO PRINT
;NO-SUCH-DEVICE
IFN FTNET,<MOVE P2,T2> ;COPY NODE NUMBER
PUSHJ P,CHKGEN## ;IS IT A VALID GENERIC NAME?
JFCL ;START AT DEVLST
;(A BAD GENERIC DEVICE SHOULD BE...
;...FOUND ABOVE AT ASSFAL+1!!!)
PUSHJ P,FXSNAM## ;FIX NAME IF 2-CHAR
MOVEI P3,-1 ;NO FLAGS AND ILL JOB NUMBER
ASSFA1: HLLZ T4,DEVNAM(F) ;GET GENERIC PHYSICAL NAME
CAMN T1,T4 ;SEE IF MATCH
PUSHJ P,ASSFA3 ;YES--DO REST OF CHECKS
PUSHJ P,NXDDB## ;NO--GET NEXT DEVICE
SKIPE F ;CONTINUE IF END OF CHAIN
JRST ASSFA1 ;NOT END, CHECK NEXT
TLO M,ERRFLG ;FLAG ERROR
JUMPL P3,ASSFA2 ;DONE CHECK IF ANY RESTRICTED DEVICES SEEN
MOVEI T1,[ASCIZ "Owned by your job, rest must be mounted"]
TLNN P3,(ASF.MJ) ;ANY OWNED?
MOVEI T1,[ASCIZ "Must be mounted"] ;NO
TLNN P3,(ASF.RD) ;ANY RESTRICTED?
MOVEI T1,[ASCIZ "Owned by your job"] ;NO
TLNN P3,(ASF.RD!ASF.MJ) ;ANYTHING FOUND?
JRST NOTDEV ;NO
JRST ASSER6 ;PRINT MESSAGE AND RETURN
ASSFA2: TLNN P3,(ASF.MJ) ;ANYTHING FOR ME?
JRST ASFA2A ;NO, CHECK RESTRICTED
MOVEI T1,[ASCIZ /, your job/]
PUSHJ P,CONMES ;NOTE YOU OWN SOME
ASFA2A: TLNN P3,(ASF.RD) ;ANY RESTRICTED DEVICES SEEN?
JRST CRLF ;NO
MOVEI T1,[ASCIZ/, rest of devices must be mounted/]
PUSHJ P,CONMES ;PRINT THE MESSAGE
PJRST CRLF ; CR AND RETURN
;HERE WITH F POINTING TO A DDB WE MAY WANT TO LIST
ASSFA3: PUSH P,T1 ;SAVE DEVICE NAME
LDB T1,PJOBN## ;GET JOB NUMBER
IFN FTNET,<
LDB T2,PDVSTA## ;GET STATION
CAME T2,P2 ;CHECK MATCH
JRST TPOPJ##
>
CAMN T1,J ;ASSIGNED TO US?
TLO P3,(ASF.MJ) ;YES--SET FLAG
CAME T1,J ;YES--IS IT OTHER JOB?
CAIN T1,(P3) ;SEE IF SAME
JRST TPOPJ## ; AS PREVIOUS
JUMPE T1,ASSFA5 ;CHECK IF THIS IS FREE, RESTRICTED DEVICE
HRR P3,T1 ; NO-PRINT
;HERE WHEN T1= JOB NUMBER TO TYPE
TLOE P3,(ASF.SP) ;PRINTED ANYTHING YET?
JRST ASFA3A ;YES--JUST ADD A COMMA
PUSH P,T1 ;SAVE GENERIC DEVICE
IFN FTNET,<PUSH P,P2> ;AND STATION
PUSHJ P,INLMES ;PRINT MESSAGE
ASCIZ /?Assigned to job /
IFN FTNET,<POP P,P2> ;RESTORE STATION
POP P,T1 ;RESTORE GENERIC NAME
JRST ASSFA4 ;SKIP COMMA
ASFA3A: PUSHJ P,PRCOM ;ISSUE COMMA
ASSFA4: PUSHJ P,RADX10 ;ISSUE JOB NUMBER
JRST TPOPJ## ;AND LOOP
ASSFA5: MOVSI T1,DEPRAS## ;GET RESTRICTED BIT ASSIGNMENT
TDNE T1,DEVSTA(F) ;DEVICE RESTRICTED?
TLO P3,(ASF.RD) ;YES -- SET BIT SAYING SO
JRST TPOPJ## ;RETURN
;PHYSICAL NAME MATCHES IF HERE
ASSG4: MOVE T2,DEVMOD(F) ;DEVMOD WORD
TLNN T2,DVDSK ;IS THIS A DISK?
JRST ASSG5 ;NO.
POP P,U ;RESTORE TTY LDB ADDRESS
PUSH P,F ;AND SAVE DEVICE'S DDB
PUSH P,T1 ;SAVE PHYSICAL NAME
PUSHJ P,CTEXT1 ;GET LOGICAL NAME ARGUMENT OF "ASSIGN DEV:NAME"
MOVE T1,T2 ;COPY TO T1 FOR DEVLG
JUMPE T1,ASSG8 ;NO LOGICAL NAME SPECIFIED, IF 0
PUSHJ P,LNMTST##
CAIA
JRST ASSER7
PUSH P,T2 ;SAVE LOG. NAME
PUSHJ P,DEVLG## ;SEE IF LOGICAL NAME IN USE
JRST ASSG4A ;NO
CAME F,-2(P) ;ASS LOGNAME LOGNAME?
PUSHJ P,ASSCHK ;YES, SEE IF WE CAN RECLAIM SPACE
MOVEI T1,LOGERR
PUSHJ P,CONMES
ASSG4A: POP P,T2 ;RESTORE LOG. NAME
POP P,T1 ;GET PHYSICAL NAME BACK
POP P,F ;RESTORE DDB ADDRESS
PUSH P,T2 ;SAVE LOGICAL NAME
MOVEI T2,ASSCON
PUSHJ P,ASSASG## ;ASSIGN BY CONSOLE
JRST ASSER4 ;NO MORE CORE FOR DISK DDB'S
POP P,T1 ;RESTORE LOGICAL NAME
JRST ASSF2 ;FINISH LOGICAL ASSIGNMENT
ASSG5: MOVEI T2,ASSCON
PUSHJ P,ASSASG## ;TRY TO ASSIGN DEVICE
JRST ASSER5 ;ALREADY ASSIGNED TO ANOTHER JOB
JRST ASSFIN ;SUCCESSFULLY ASSIGNED
ASSG8: POP P,T2 ;REMOVE GARBAGE FROM PD LIST
POP P,F ;RESTORE POINTER TO PROTOTYPE DSK DDB
JRST ASSF6
;ALREADY ASSIGNED TO ANOTHER JOB
ASSER2: LDB T1,PJOBN## ;GET JOB NUMBER DEVICE ASSIGNED TO
PUSH P,T1 ;SAVE JOB NO.
MOVEI T1,ASSMS2 ;TYPE ERROR MESSAGE
PUSHJ P,CONMES
TLO M,ERRFLG ;INDICATE ERROR
POP P,T1 ;GET JOB NO. BACK
JRST DECLF ;AND TYPE IT
ASSER8: TLOA T2,(1B0) ;GOVE NOT ASSIGNABLE
ASSER4: MOVEM U,0(P) ;DISCARD LOGICAL NAME VIA NEXT POP INSTR.
ASSER5: POP P,U ;GET LDB ADDRESS
JUMPGE T2,ASSER2 ;JUMP IF NOT RESTRICTED DEVICE
MOVEI T1,ASSMS3 ;TYPE ERROR MESSAGE
ASSER6: PUSHJ P,ERRMES ;Y
JRST CRLF
ASSMS2: ASCIZ /?Already assigned to job /
ASSMS3: ASCIZ /Device not assignable/
ASSER7: POP P,(P) ;CLEAN UP STACK
POP P,(P)
MOVEI T1,ASSMS4
PJRST ASSER6 ;TYPE ERROR MESSAGE
ASSMS4: ASCIZ /Disk logical name already exists/
;DEVICE ASSIGNED, GIVE IT A LOGICAL NAME
ASSFIN: SETZM DEVLOG(F) ;CLEAR LOGICAL NAME
POP P,U ;RESTORE TTY LDB ADDR
PUSHJ P,CTEXT1 ;GET SECOND ARG, LOGICAL DEVICE NAME
SKIPGE DEVSPL(F) ;IF A SPOOLING DDB,
JUMPE T2,[PUSH P,DEVNAM(F) ;SAVE DEVICE NAME BEFORE GIVING BACK DDB
PUSHJ P,CLRDDB## ;GIVE DDB BACK TO FREE STORAGE
; SINCE NO LOGICAL NAME
JRST ASSF4] ;GO PRINT "SPOOLED"
PUSH P,F ;SAVE DEVICE'S DDB
PUSH P,T2 ;SAVE LOGICAL NAME
SKIPE T1,T2 ;IS THERE A LOGICAL NAME SPECIFIED?
PUSHJ P,DEVLG## ;YES, SEE IF IT IS ALREADY IN USE BY THIS USER
JRST ASSF3 ;NO
PUSHJ P,ASSCHK ;YES, SEE IF WE CAN RECLAIM SPACE
MOVEI T1,LOGERR ;YES, PRINT ERROR
PUSHJ P,CONMES
ASSF3: POP P,T1 ;RESTORE LOGICAL NAME FOR THIS DEVICE
POP P,F ;DDB OF THE NEWLY ASSIGNED DEVICE
ASSF2: MOVEM T1,DEVLOG(F) ;STORE IN DEVICE DATA BLOCK
MOVSI T2,DVDIRIN ;CLEAR DIRECTORY IN CORE BIT
ANDCAB T2,DEVMOD(F) ;SETUP T2 WITH DEV CHARACTERISTICS FOR ASGHGH
PUSHJ P,ASGHGH## ;GO CHECK IF THIS DEVICE HAS
; INITIALIZED ANY SHARED SEGMENTS
; IF YES, CLEAR SEG NAMES SO NO
; NEW SHARING (DTA,MTA ONLY)
ASSF6: PUSH P,DEVNAM(F) ;SAVE PHYSICAL DEVICE NAME
SKIPL DEVSPL(F) ;IS THIS A SPOOLED DEVICE
JRST ASSF5 ;NO
;HERE TO TELL USER HE HAS ASSIGNED A SPOOLED DEVICE
ASSF4: PUSHJ P,INLMES ;YES, TELL HIM (IN CASE HE DOESN'T KNOW)
ASCIZ /Spooled /
ASSF5: POP P,T2 ;RESTORE PHYSICAL NAME
PUSHJ P,PRNAME ;PRINT PHYSICAL NAME IT
PJSP T1,CONMES ;AND RETURN
ASCIZ / assigned
/
LOGERR: ASCIZ /%Logical name was in use, /
;SUBROUTINE TO CLEAR THE LOGICAL NAME OF A DEVICE
;ENTER WITH F SET UP
;ZEROES DEVLOG, THEN CHECKS FOR DSK/SPOOL TYPE
;IF INIT'ED, CLEAR ASSCON
;IF NOT INIT'ED, CLEAR DDB
;ENTER AT ASSCK1 TO NOT ZERO DEVLOG
;CLOBBERS T2
ASSCHK: SETZM DEVLOG(F) ;CLEAR OLD NAME
ASSCK1::MOVE T2,DEVMOD(F) ;GET MOD WORD
TLNN T2,DVDSK ;DISK?
SKIPGE DEVSPL(F) ;OR SPOOL?
SKIPA ;YES, SKIP ALONG
POPJ P, ;NO, JUST RETURN
TRNN T2,ASSPRG ;INIT'ED?
PJRST [PUSHJ P,CLRDVL## ;NO, CLEAR LOGICAL NAME TABLE ENTRY
JRST CLRDDB##] ; CLEAR DDB AND RETURN
MOVEI T2,ASSCON ;YES, TURN OFF ASSCON
ANDCAM T2,DEVMOD(F) ;...
POPJ P, ;AND RETURN
;"DEASSIGN DEV" - DEASSIGNS DEVICE FROM CONSOLE
DEASSI::JSP T2,SAVCTX## ;SAVE THE CONTEXT OF THE JOB
PUSHJ P,CTXDEV ;GET DEVICE NAME
JUMPE T2,DEASTY ;NO ARG. IF 0, DEASSIGN ALL BUT TTY
MOVE T1,T2 ;DEVICE NAME
PUSHJ P,DEVSRD## ;SEARCH FOR DEVICE
JRST DEAER1 ;NOT FOUND
DEASI1: PUSHJ P, DEASG ;FOUND, DEASSIGN IT
JRST DEAER2 ;NOT PREVIOUSLY ASSIGNED
PJRST TTYKLQ## ;KILL TTY DDB IF NOT NEEDED
;DEVICE DEASSIGNED
NOTDEV::
DEAER1: SKIPE J ;IF NOT LOGGED IN (ATTACH FOO)
PUSHJ P,TTYFND##
SKIPA ;RESTORE TTY LINE DATA BLOCK
NOTDV1: POP P,U ;RESTORE U
JSP T1,ERRMES ;PRINT NO SUCH DEVICE
ASCIZ /No such device
/
DEAER2: PUSH P,F
PUSHJ P,TTYFND## ;RESTORE TTY LDB
POP P,F
MOVE T2,DEVNAM(F) ;PRINT PHYSICAL DEVICE NAME
PUSHJ P,PRNAMQ
PUSHJ P,TTYKLQ## ;REMOVE DDB
JSP T1,ERRMSN
ASCIZ / wasn't assigned
/
;REASSIGN UUO
;CALL MOVE AC,JOB NUMBER OR -1(SELF) OR 0(DEASSIGN)
; MOVE AC+1,SIXBIT /DEVICE/
; CALL AC,[SIXBIT /REASSIGN/]
;IF C(AC)=0, JOB HAS NOT BEEN INITIALIZED
;IF C(AC+1)=0, DEVICE NOT ASSIGNED TO THIS JOB OR DEVICE IS A TTY
REASSI::SKIPGE T1 ;SEE IF OUR JOB (-1)
MOVE T1,.CPJOB## ;YES--GET NUMBER
PUSH P,T1 ;STACK JOB NUMBER TO BE REASSIGNED TO
PUSHJ P,GETWD1##
MOVE T2,T1 ;DEVICE NAME
JRST REASS1
;"REASSIGN DEV:JOB" - REASSIGN DEVICE "DEV" TO JOB "JOB"
REASS:: PUSHJ P,CTXDEV ;GET DEVICE NAME
JUMPE T2,NOTENF ;NULL NAME?
MOVE F,T2 ;SAVE IT
PUSHJ P,GETJOB ;GET NEW JOB NUMBER
MOVE T2,J ;NONE SPECIFIED. ASSUME SELF
PUSH P,T2 ;PUT JOB NUMBER ON STACK, DEVICE
MOVE T2,F ;NAME IN T2
;ROUTINE COMMON TO REASSIGN UUO AND COMMAND
;HERE WITH T2=DEVICE AND (P)=NEW JOB (0=DEASSIGN)
REASS1: EXCH P1,(P) ;SAVE P1 IN STACK, P1= NEW JOB NUMBER
PUSH P,U ;SAVE U
MOVE T1,P1 ;T1 = NEW JOB NUMBER
PUSH P,T1
PUSHJ P,LGLPR1## ;IS JOB NUMBER OUT OF RANGE?
JRST REASE1 ;YES, DO NOT REASSIGN
JUMPE T1,REAS1A ;JUMP IF DEASSIGN
MOVE T1,JBTSTS##(T1) ;NEW JOB STATUS
TLNN T1,JNA ;DOES NEW JOB EXIST?
JRST REASE1 ;NO.
REAS1A: MOVE T1,T2
HLL P1,-2(P) ;GET PH ONLY BIT FROM ORIGINAL P1
PUSHJ P,DVCNSG## ;SEARCH FOR DEV
JRST REASE2 ;NOT FOUND
NOSCHEDULE
TLZ F,-1 ;CLEAR SYSDEV
CAIE F,SWPDDB##
CAIN F,DSKDDB## ;TRYING TO REASSIGN DSK?
JRST REASE7 ;YES, ERROR
LDB T2,PJOBN##
CAME T2,J ;ASSIGNED TO THIS JOB
JRST REASE9 ;NO, ERROR IF SOME OTHER
REAS1B: MOVE T1,DEVMOD(F)
LDB T3,DEYSPL## ;SPOOL BIT
TDNN T3,JBTSPL##(J) ;THIS JOB SPOOL THESE?
JRST REAS1X ;NO. NO PROBLEM
LDB T3,PJOBN## ;YES. HE DOES
CAME T3,J ;TO THIS JOB?
JRST REASE7 ;NO. CAN'T GET IT
REAS1X: TLNE T1,TTYATC ;IS IT THE CONSOLE TTY?
JRST REASE7 ;YES. CAN'T BE REASSIGNED.
;CONTINUED ON NEXT PAGE
IFN FTMDA,<
SKIPN 0(P) ;DEASSIGN?
JRST REAS1C ;YES
SKIPE %SIMDA## ;IS MDA RUNNING?
CAMN J,MDAJOB## ;YES, IS HE DOING THIS?
JRST REAS1C ;DON'T CHECK
MOVSI T1,DVCMDA ;CONTROLLED BIT
TDNE T1,DEVCHR(F) ;CONTROLLED?
JRST REASE7 ;NO CAN'T REASSIGN IT
>;END IFN FTMDA
REAS1C: SKIPE (P) ;DEASSIGN,
CAMN J,(P) ;OR REASSIGN TO SELF?
JRST REAS1D ;YES--OK
HRRZ T1,F ;GET DDB ADDRESS
CAIL T1,.FPMC ;OUT OF FUNNY
CAIL T1,.LPMC ;SPACE RANGE?
JRST REAS1D ;YES--GO AHEAD
JRST REASE7 ;NO--CAN'T DO REASSIGN
REAS1D: MOVE S,DEVMOD(F) ;SAVE DEVMOD WORD
MOVEI T1,ASSCON ;ASSIGN IT BY
TDNE T1,DEVMOD(F) ;SEE IF ASSIGNED
JUMPE T2,REASE3 ;YES--IF TO 0, ERROR
DPB J,PJOBN## ;PUT IN OUR NUMBER
SCHEDULE
SKIPN (P) ;SEE IF DEASSIGN
JRST REASS7 ;YES--GO DO IT
IORB T1,DEVMOD(F)
CAME J,(P) ;IS IT TO SAME JOB?
TRNN T1,ASSPRG ;NO. IS DEVICE INITED?
JRST REASS3 ;NO.
JUMPG M,REASS4 ;YES. COMMAND LEVEL?
HRL F,(P) ;YES. SCHEDULE RELEASE
MOVEM F,.JDAT+JOBFDV##
POP P,T2
POP P,U
POP P,P1
TLO M,TTYRNC ;SET TTYRNC SO JOB WILL RUN
PJSP T2,MSTART## ;SET UP MONITOR JOB, RETURNS AT PC C(T2)
JSP T1,MONSTR## ;START MONITOR JOBS, RETURNS AT UUO LEVEL
PUSH P,P1
PUSH P,U
MOVE J,.CPJOB##
HLRZ T1,.JDAT+JOBFDV##
PUSH P,T1
HRRZ F,.JDAT+JOBFDV##
REASS4:
IFN FTMPXSER,<
PUSHJ P,MPXDIS##
SKIPA
JRST REASS3
>
HRRZ T4,DEVSER(F)
HRRZM F,.JDAT+JOBFDV##
MOVEI P1,0
PUSH P,M ;SAVE M
REASS2: PUSHJ P,NXTCH##
JRST REAS2A
HRRZ F,.JDAT+JOBFDV##
CAIE F,(T1)
JRST REASS2
SOS P1
HRLM P1,.USCTA
PUSHJ P,JDAADP##
MOVE F,(T1)
PUSHJ P,URELEA##
AOJA P1,REASS2 ;INCREMENT CHANNEL AND LOOP
REAS2A: POP P,M ;RESTORE M
MOVE F,.JDAT+JOBFDV##
MOVE J,.CPJOB## ;CURRENT JOB NUMBER
REASS3: MOVSI T1,DVDIRIN ;CLEAR DIRECTORY IN CORE BIT
ANDCAM T1,DEVMOD(F) ;..
EXCH J,(P)
CAMN J,(P) ;IS IT TO US?
JRST REASS6 ;YES--JUST CLEAN UP
NOSCHEDULE
PUSH P,F ;PRESERVE F
TLZ P1,PHONLY ;ENABLE LOGICAL SEARCH
SKIPN T1,DEVLOG(F) ;SEE IF LOGICAL NAME
;INUSE BY THAT JOB
JRST REASS5 ;NO (OR NO LOG. NAME)
PUSHJ P,DEVCHN## ;DOES JOB HAVE THIS LOGICAL NAME INUSE?
SKIPA T1,-1(P) ;NO, PHYSICAL--GET CALLER'S JOB
JRST REASE8 ;YES--ILLEGAL
MOVE T2,JBTPPN##(T1) ;GET HIS P,PN
CAME T2,FFAPPN## ;SEE IF PRIV.
CAMN T2,JBTPPN##(J) ;OR SAME GUY
JRST REASS5 ;YES--IT'S OK
JUMPL M,REASE8 ;IF COMMAND, THAT IS ONLY WAY
MOVE T2,JBTSTS##(T1) ;ELSE, SEE IF
TLNE T2,JACCT ;PRIV. PROGRAM
JRST REASS5 ;YES--IT'S OK
REASE8: POP P,F ;RESTORE F
SCHEDULE
MOVEI T2,ASSCON ;WAS IT ASSIGNED
TDNN T2,S ;BEFORE WE STARTED
XORM T2,DEVMOD(F) ;NO, MAKE SURE IT IS NOT ASSIGNED
SETZ T1, ;0 JOB #
TDNN T2,S ;AGAIN, WAS IT ASSIGNED?
DPB T1,PJOBN ;NO CLEAR OWNER
JRST REASE6 ;GIVE ERROR
REASS5: POP P,F ;RESTORE F
DPB J,PJCHN## ;STORE NEW JOB NUMBER IN DDB
PUSHJ P,TPMREA## ;RESET MAGTAPE DDB PARAMETERS
REASS6: POP P,J
POP P,U ;RESTORE ADDR OF TTY LDB
POP P,P1 ;RESTORE P1
TLNN M,FLMCLV ;SEE IF UUO OR COMMAND LEVEL
PJUMPL M,ESTOP## ;UUO--STOP JOB
POPJ P,
REASS7: PUSHJ P,DEASG1 ;DEASSIGN
JFCL ;IGNORE ERROR
JRST REASS6 ;GO FINISH
REASE1: POP P,T1
POP P,U ;RESTORE ADDR OF TTY LDB
POP P,P1 ;RESTORE P1
TLNE M,FLMCLV ;SEE IF UUO OR COMMAND LEVEL
JRST ATT4 ;COMMAND--ISSUE MESSAGE
PJRST RTZER## ;RETURN 0 IN AC
REASE2: MOVEI T1,NOTDEV ;NO SUCH DEVICE
REASE5: POP P,T2
POP P,U ;RESTORE ADDR OF TTY LDB
POP P,P1 ;RESTORE P1
JUMPL M,(T1) ;JUMP IF COMMAND
PJRST RTM1## ;GIVE ERROR CODE OF -1 IN AC
REASE9: JUMPN T2,REASE3
IFN FTMDA,<
SKIPN %SIMDA## ;MDA RUNNING
JRST REAS9E ;CHECK RESTRICTED BIT
CAMN J,MDAJOB## ;YES, IS MDA DOING THIS?
JRST REAS1B ;YES
MOVSI T1,DVCMDA ;CONTROL BIT
TDNE T1,DEVCHR(F) ;CONTROLLED?
JRST REASE3 ;YES, LOSE
>;END IFN FTMDA
REAS9E: MOVSI T1,DEPRAS ;IS DEVICE
TDNN T1,DEVSTA(F) ; RESTRICTED?
JRST REAS1B ;NO
REASE3: SCHEDULE
MOVEI T1,DEAER2 ;WASN'T ASSIGNED
JRST REASE5
REASE7: SCHEDULE
EXCH J,(P) ;FUDGE CORRECT JOB ON STACK
REASE6: PJSP T1,REASE5 ;RETURN TO USER IF UUO
MOVE J,T2 ;RESTORE J IF COMMAND
MOVE T2,DEVNAM(F) ;GET DEVICE NAME
PUSHJ P,TTYFND## ;RESTORE TTY LDB
PUSHJ P,PRNAMQ
PUSHJ P,TSETBI## ;CLEAR TYPE AHEAD
MOVEI T1,REAS6M ;PICK UP MESSAGE
TLNN M,FLMCLV ;SEE IF UUO OR COMMAND LEVEL
PJRST PHOLD## ;UUO--GO HOLD JOB
JRST ERRMSN ;TYPE MESSAGE IF NOT
REAS6M: ASCIZ / can't be reassigned
/
SUBTTL ATTACH AND DETACH COMMANDS
;"ATTACH DEVNAM" -ATTACHES A PREVIOUSLY PARTITIONED DEVICE
; NOTE-MUST BE LOGGED IN UNDER [1,2] TO DO THIS
; "ATTACH N [PROJ.,PROG.]" - ATTACH CONSOLE TO JOB N
;CHANGES ADDRESS OF TTY DEVICE DATA BLOCK STORED IN -2(P)
;BY THE COMMAND DECODER
ATTACH::PUSHJ P,DECIN1 ;GET JOB NO.
JRST ATTLGN ;NOT A NUMBER--GO RUN LOGIN
JRST DEVATT ;WANTS TO ATTACH A DEVICE
PUSHJ P,GETJB1 ;VALIDATE
MOVE T1,JBTPPN##(J) ;GET PPN OF CURRENT JOB
TRNE T3,JDC ;TARGET JOB WAITING FOR DAEMON?
CAMN T1,FFAPPN## ;YES, ATTACHING JOB [1,2]?
CAIA ;YES, CONTINUE
JRST ATT3 ;NO, DON'T ALLOW ATTACH
MOVE S,T2 ;SAVE JOB NO.
PUSHJ P,PJPGNO ;GET PROJ.-PROG. NOS. ARG(IF ERROR, POP SUB LEVEL
; OFF 1, PRINT ERROR, AND DO NOT RETURN HERE)
MOVE P2,T2 ;DID USER TYPE IN A PROJ,PROG # IN []'S?
MOVEM S,T2 ;RESTORE
CAME P2,JBTPPN##(T2) ;IS THIS THE SAME PERSON WHO DETACHED FROM
; THIS JOB NUMBER?
JUMPN P2,ATT3 ;NO-ERROR
PUSH P,U
MOVE S,F ;SAVE DDB ADDRESS
MOVE T3,T2 ;SAVE TARGET JOB #
MOVEI T4,JOBMAX## ;UPPER LIMIT ON ITERATIONS
SE1XCT <LDB T2,LDPLNO##> ;UNIT # ON WHICH COMMAND APPEARED
PUSHJ P,CTLJB## ;IF UNIT IS A PTY, RETURN CONTROLLING JOB #
ATLCHK: JUMPL T1,ATTOK ;NOT A PTY, ITS COOL
CAIN T1,(T3) ;IS CONTROLLING JOB SAME AS TARGET JOB?
JRST ATT5 ;YES, DISALLOW
HRRZ F,TTYTAB##(T1)
PUSHJ P,CTLJBD## ;NO, LOOK AT HIS CONTROLLER, IF ANY.
SOJG T4,ATLCHK ;ITERATE FOR ALL JOBS, IF NEED BE
JRST ATT5 ;SHOULDN'T EVER GET HERE
ATTOK: MOVE T2,T3 ;RESTORE TARGET JOB
MOVE F,S ;RESTORE DDB POINTER
POP P,U
PUSH P,J
MOVE J,T2 ;CAN NEW TTY ATTACH TO NEW JOB?
PUSHJ P,TTYISA##
JRST ATT2A ;NO, NO DDB OR ANOTHER DDB ATTACHED AND NOT OPR
JUMPN T1,ATTNL ;IF THERE IS SOMEONE THERE MUST BE OPR TO BE OK
;HENCE NO LOGIN REQUIRED
MOVE T1,(P) ;OLD JOB NUMBER IN CASE NOT CTY OR OPR
MOVE T1,JBTPPN##(T1) ;PPN IF OLD JOB
CAMN T1,FFAPPN## ;NO SKIP IF [1,2]
JRST ATTNL ;[1,2] DOESN'T NEED LOGIN
PUSHJ P,ISOPCT
CAMN P2,T1 ;SKIP IF CURRENT JOB NOT SAME PPN AS OBJECT JOB
JUMPN T1,ATTNL ;YES, CURRENT JOB DOESN'T REQUIRE LOGIN
JUMPN P2,ATTLG1 ;MUST RUN LOGIN IF TARGET PPN SPECIFIED
MOVE P2,JBTPPN##(J) ;GET TARGET PPN
CAMN P2,T1 ;IS IT A MATCH?
JRST ATTNL ;YES, IT'S A WIN
ATTLG1: POP P,J ;NO, RESTORE OLD JOB #
ATTLGN: TLNN P4,JLOG
JRST ATTDET ;ALREADY DETACHED
SKIPN [EXP M.CTX##] ;CONTEXT SERVICE LOADED?
JRST [PUSHJ P,DETAC1;NO--DETACH JOB
JRST ATTDET]
TLO M,SACFLG## ;CAUSE AN AUTO-SAVE TO HAPPEN
PJRST RUNLGN ;GO RUN LOGIN
ATTDET: SETZ J, ;CLEAR SO WILL GET A NEW JOB #
MOVE T2,LOGTXT## ;MAKE IT LOOK LIKE A LOGIN COMMAND
MOVE P3,[XWD UNQTAB,DISP##] ;P3=UNIQUENESS INFO PLUS LOC OF DISPATCH TABLE
MOVE P4,[XWD-DISPL##,COMTAB##] ;P4=LENGTH, LOC
MOVE P,.CPISF## ;RESTORE P TO VALUE AT COMGO
XJRST [MCSEC1+COM1A] ;*** CALL LOGIN TO VALIDATE THE ATTACH
ATTNL: JUMPN P2,ATTNL1 ;ALWAYS OK IF PPN WAS TYPED
MOVE P2,JBTPPN##(J) ;GET TARGET'S PPN
MOVE T1,(P) ;GET STARTING JOB NUMBER
CAMN P2,JBTPPN##(T1) ;DO THEY MATCH?
JRST ATTNL1 ;YES, IT'S LEGAL AFTER ALL
PUSHJ P,SKIPS1 ;SEE IF AT EOL
JRST NOTENP ;NOT ENOUGH TYPED IF NO PPN
JRST COMERP ;INVALID PPN TYPED
ATTNL1: PUSHJ P,TTYATT## ;NO, ATTACH TTY
JRST ATT2A ;ERROR CAN'T ATTACH
EXCH J,0(P) ;GET OLD JOB #
MOVSI T1,JNA ;IS JOB NUMBER
TDNE T1,JBTSTS##(J) ; ASSIGNED?
PUSHJ P,DETMSG ;NO. TYPE MESSAGE
POP P,J ;RESTORE J
JRST TTYFND## ;ATTACHED. GO SET UP OUTP. BYTE PTR.
DEVATT: PUSHJ P,SETLGL ;SEE IF OPR OR [1,2]
JRST ATTLGN ;NOT PRIV'ED--GO RUN LOGIN
PUSHJ P,CTXDEV ;GET DEVICE ARGUMENT
IFN FTMP,<
PUSHJ P,CPUFND## ;IS THE ARGUMENT A CPU NAME?
CAIA ;NO, DEVICE OR ERROR
JRST CPUATT## ;YES, ATTACH THE CPU
>
MOVE S,T2 ;SAVE DEVICE NAME ACROSS CALL TO SAVCTX
JSP T2,SAVCTD## ;THIS MAY CALL NETSER, MUST BE A JOB.
MOVE T1,S ;YES-SET UP DEVICE NAME
PUSHJ P,DEVSRG## ;SEARCH FOR DEVICE
JRST ATT7 ;SEE IF DUAL-PORTED DISK OR IN SYSDET CHAIN
MOVE T2,DEVMOD(F)
TLNE T2,DVDSK ;DISK?
JRST ATT7 ;YES, DO IT DIFFERENTLY
SKIPN DEVCHR(F) ;IS IT A "FAKE" DDB?
PJRST DTATSP ;YES, CAN'T ATTACH SPOOLED DEVICE
TRNN T2,ASSCON ;WAS DEVICE DETACHED?
PJRST ATT6 ;NO ERROR
LDB T1,PJOBN## ;GET JOB NUMBER
JUMPN T1,ATT6 ;IS IT = 0?
SETZM DEVLOG(F)
DPB J,PJOBN## ;SET JOB NUMBER
PJRST TPMRES## ;RESET MAGTAPE DDB PARAMETERS
ATT2A: POP P,J ;REMOVE JUNK FROM STACK
MOVE T2,DEVNAM(F) ;PRINT PHYSICAL NAME
PUSHJ P,PRNAMQ
JSP T1,ERRMSN
ASCIZ / already attached
/
ATT5: MOVE F,S ;RESTORE DDB POINTER
POP P,U
ATT3: JSP T1,ERRMES
ASCIZ /Can't attach to job
/
ATT6: JSP T1,ERRMES
ASCIZ /Wasn't detached
/
;HERE TO ATTACH A DISK UNIT
ATT7: PUSHJ P,ATTDSK## ;TRY TO PUT IT ON-LINE
JRST ATT8 ;NOT DOWN OR NO SUCH UNIT
JFCL ;DOESN'T RETURN HERE WHEN CALLED AT UUO LEVEL
POPJ P, ;UNITS IS NOW UP
ATT8: TLZE U,400000 ;IS IT A DSK?
JRST NOTDEV ;NO, "NOT A DEVICE"
JRST COMERA ;YES, "ATTACH DEV?"
;GETJOB--ROUTINE TO SCAN COMMAND FOR JOB NUMBER
;RETURNS: CPOPJ IF NULL WITH T2=THIS JOB (IF ANY) OR 0.
; CPOPJ1 IF OK WITH T2=JOB SPECIFIED, T3=JOBSTS
;GIVES ERROR (NO RETURN) IF DECIMAL IMPROPER OR NOT A JOB.
GETJOB::PUSHJ P,DECIN1 ;READ DECIMAL
POPJ P, ;NULL--RETURN
JRST COMERP ;NOT DECIMAL--ERROR
AOS (P) ;GOOD--ADVANCE RETURN
GETJB1: MOVE T1,T2 ;T1=JOB NUMBER
PUSHJ P,LGLPRC## ;SKIP IF LEGAL JOB NUMBER
JRST ATT1P ;NO - FAIL
MOVE T3,JBTSTS##(T2) ;GET TARGET JOB STATUS
TLNE T3,JNA ;SEE IF JOB NUMBER
POPJ P, ;YES--RETURN
POP P,T1 ;NO--CLEAN UP STACK
ATT4: JSP T1,ERRMES
ASCIZ /Not a job
/
ATT1P: POP P,T1 ;CLEAN UP STACK
ATT1: JSP T1,ERRMES
ASCIZ /Illegal job number
/
;"DETACH" - DETACH CONSOLE FROM JOB
;"DETACH CPUNAM" - DETACHES CPU FROM THE SYSTEM SOFTWAREWISE
;"DETACH DEVNAM" - DETACHES DEVICE FROM THE SYSTEM SOFTWAREWISE
DETACH::PUSHJ P,CTXDEV ;GET ARGUMENT
JUMPE T2,DETAC1 ;ONLY "DET" TYPED
MOVE S,T2
PUSHJ P,SETLGL ;SEE IF OPR OR [1,2]
JRST COMERA ;NOT LEGAL
PUSHJ P,SAVE1## ;SAVE P1
IFN FTMP,<
MOVE T2,S ;RESTORE ARGUMENT
PUSHJ P,CPUFND## ;SEE IF ARGUMENT IS A CPU NAME
CAIA ;NOT, A DEVICE OR AN ERROR
JRST CPUDET## ;A CPU, DETACH IT
>
JSP T2,SAVCTD## ;AMAY CALL NETSER
MOVE T1,S ;YES-SET UP DEVICE NAME
PUSH P,U ;SAVE ADDR OF TTY LDB
PUSHJ P,DEVPHY## ;SEARCH FOR DEVICE
IFE FTDUAL,<
JRST NOTDV1 ;DEVICE NOT FOUND
>
IFN FTDUAL,<
JRST DETAC3
>
MOVE T2,DEVMOD(F) ;CHECK TO SEE IF THIS IS DSK
TRNE T2,ASSPRG ;ASSIGNED BY PROGRAM?
JRST NOTDT1
TLNE T2,DVDSK ;TRYING TO TAKE DOWN A DISK?
JRST DETAC3 ;YES, DO IT DIFFERENTLY
TLNE T2,DVDSK!DVTTY ;IS IT THE DSK OR A TTY?
JRST NOTDV1 ;YES-PRINT ERROR MSG.
MOVEI T2,ASSCON ;FOUND-SET UP ASSIGNED BY CONSOLE
PUSHJ P,ASSASG## ;TRY TO ASSIGN
JRST ASSER5 ;CAN'T ASSIGN
SKIPGE DEVSPL(F) ;SPOOLED?
JRST DETAC2 ;YES
TLNE F,SYSDEV ;IS THIS SYSTEM DEVICE?
JRST NOTDV1 ;YES-PRINT ERROR MSG.
MOVEI T1,0 ;NO. SET JOB NUMBER TO ZERO
DPB T1,PJOBN## ; ..
JRST UPOPJ## ;RESTORE U AND RETURN SUCCESSFUL
DETAC1: TLNN P4,JLOG ;CAN'T DETACH
JRST ATT4 ;IF NOT LOGGED IN
PUSHJ P,DETMSG
DETBYE: SE1XCT <HRRZ F,LDBDDB##(U)> ;IS THERE A JOB ATTACHED?
JUMPE F,CPOPJ## ;IF NONE, DONE NOW
JRST TTYDET## ;YES. GO DETACH IT FROM LINE
DETMSG: PUSHJ P,INLMES ;TELL USER WHERE HE WAS
ASCIZ /From job /
PJRST PJOB
DETAC2: PUSHJ P,DTATSP ;SAY DEVICE IS SPOOLED
PUSHJ P,CLRDDB## ;DEASSIGN THE DEVICE
PJRST UPOPJ## ;POP U AND RETURN
DTATSP: PUSHJ P,PRQM ;CAN'T DETACH/ATTACH A SPOOLED DEVICE
MOVE T2,DEVNAM(F) ;GET DEV NAME
PUSHJ P,PRNAME ;TYPE IT
PUSHJ P,INLMES
ASCIZ / is spooled/
POPJ P,
;HERE TO DETACH A DSK
DETAC3: POP P,U
PUSHJ P,DETDSK## ;TRY TO DETACH
JRST NOTDEV ;NOT A DSK
JRST COMERA ;CANT DETACH
POPJ P, ;WIN
NOTDT1: POP P,U ;RESTORE U
PJSP T1,ERRMES ;TYPE MESSAGE
ASCIZ /Device in use
/
SUBTTL DATASET CONNECT & SYSTEM START
;DATAPHONE RESPONSE COMMANDS PHONIED UP BY SCNSER ON DATAPHONE INTERRUPTS
BYECOM::TLNN P4,JLOG ;LOGGED IN?
JRST BYECM1 ;NO-LEAVE ALONE
LDB T1,JBYLTM## ;GET JOBS TIME LIMIT
JUMPN T1,BYECM1 ;JUMP IF ALREADY SET
MOVEI T1,M.DTLS## ;GET DEFAULT DETACH TIME LIMIT
IMUL T1,TICSEC## ;INTO JIFFIES
DPB T1,JBYLTM## ;STORE NEW LIMIT
MOVSI T1,(JB.LTL) ;GET DETACHED LIMIT SET
IORM T1,JBTLIM##(J) ;REMEMBER FOR LATER
BYECM1: PJRST DETBYE ;THEN DETACH IT
HELLO:: MOVE P2,INITIA## ;GO RUN THE
PJRST RUNAME ;HELLO PROGRAM
;SYSTEM RESTARTED MESSAGE - COMMAND PHONIED UP BY SCNSER WHEN
; CALLED FROM IOGO
RESTRT::PUSHJ P,CRLF ;START A NEW LINE, AND
MOVEI T1,CONFIG## ;TYPE OUT CONFIGURATION NAME
PUSHJ P,CONMES ;"
PUSHJ P,PRSPC ;A SPACE
; PJRST DAYTIM ;FALL INTO DAYTIME
SUBTTL DAYTIME COMMAND
;DAYTIME - PRINT DAY, DATE, TIME, CRLF
DAYTIM::SKIPE .UONCE## ;IF USER-MODE MONITOR,
PUSHJ P,USRDTM## ;SETUP THE VALUES WE NEED
PUSHJ P,PRDOFW ;PRINT DAY OF WEEK
PUSHJ P,PRSPC ;SPACE
PUSHJ P,DATIME ;TYPE DATE AND TIME
PJRST CRLF ;ADD CRLF
;DATIME - PRINT DATE AND TIME (NO CRLF)
DATIME::SKIPE .UONCE## ;IF USER-MODE MONITOR,
PUSHJ P,USRDTM## ;SETUP THE VALUES WE NEED
PUSHJ P,PRDAYD ;PRINT DAY AND DATE
PUSHJ P,PRSPC ;SPACE
PJRST PRNOW ;FINISH OFF WITH TIME
;PRDAYD - PRINT DATE, TIME (NO CRLF)
PRDAYD::MOVE T1,LOCDAY## ;PRINT DAY
PUSHJ P,RADX10
MOVE T1,LOCMON##
MOVE T1,MONTAB##-1(T1) ;MONTH
DPB T1,[POINT 21,DAMESS##,27]
MOVEI T1,DAMESS##
PUSHJ P,CONMES ;PRINT DAY
MOVE T1,LOCYER##
SUBI T1,^D1900
PJRST RADX10 ;PRINT YEAR
;SUBROUTINE TO PRINT TIME OF DAY, CRLF
PRDTIM::MOVE T1,TIME## ;PRINT TIME OF DAY
PRTIME::PUSHJ P,PRTIM ;PRINT TIME AS HH:MM:SS(NO CRLF)
PJRST CRLF ;AND ADD CRLF
;SUBROUTINE TO PRINT DAY OF WEEK
PRDOFW::HLRZ T1,DATE## ;GET NBS DATE
IDIVI T1,^D7 ;GET DAY OF WEEK
MOVE T1,DAYTAB##(T2) ;GET THE NAME OF THAT DAY
PJRST CONMES ;PRINT THAT
;SUBROUTINE TO PRINT TIME WITH AM/PM
PRAMPM::MOVE T2,TICMIN## ;GET TICKS/MINUTE
IMULI T2,^D60*^D12 ;COMPUTE PER HOUR
CAMGE T1,T2 ;PM?
JRST PRAM.1 ;NO--AM
MOVE T3,TICMIN## ;GET TICKS/MINUTE AGAIN
IMULI T3,^D60*^D13 ;COMPUTE FOR 13 HOURS
CAML T1,T3 ;SEE IF 12:00 TO 12:59:59
SUB T1,T2 ;NO--MAKE 1:00 TO 11:59:59
PUSHJ P,PRTIMS ;PRINT TIME
MOVEI T1,[ASCIZ/ PM/] ;GET SUFFIX
PJRST CONMES ;TYPE AND RETURN
PRAM.1: PUSHJ P,PRTIMS ;PRINT THE TIME
MOVEI T1,[ASCIZ/ AM/] ;GET SUFFIX
PJRST CONMES ;TYPE AND RETURN
;This routine is like PRTIM except it always types time as
;HH:MM:SS with leading zeros.
PRTIMS::MOVE T2,TICSEC## ;ADD 1/2 TICKS/SEC FOR ROUNDING
LSH T2,-1
ADD T1,T2
IDIV T1,TICMIN## ;FORM MINUTES
PUSH P,T2 ;SAVE REMAINDER IN JIFFIES
IDIVI T1,^D60 ;HOURS, MINUTES IN T1,T2
PUSHJ P,RADX10
JRST PR0 ;ENTER PRTIM
SUBTTL BIG BEN
;ROUTINE TO PRINT THE MONITOR NAME, SYSTEM UPTIME AND CURRENT
;DATE/TIME
;CALL: MOVEI U,LDB ADDRESS
; PUSHJ P,BIGBEN
; <RETURN HERE ALWAYS>
BIGBEN::SKIPGE DEBUGF## ;DEBUGGING?
POPJ P, ;KEEP QUIET
PUSHJ P,INLMES
ASCIZ/
Monitor /
MOVEI T1,CONFIG##
PUSHJ P,CONMES ;PRINT MONITOR NAME
PUSHJ P,CRLF ;END THE LINE
PUSHJ P,INLMES
ASCIZ/System uptime /
MOVE T1,SYSUPT## ;GET SYSTEM UPTIME
PUSHJ P,PRTIME ;PRINT IT
PUSHJ P,INLMES
ASCIZ .Current date/time .
PUSHJ P,DAYTIM ;PRINT DATE TIME
PJRST CRLF ;END LINE AND RETURN
SUBTTL RUNTIME ROUTINE (TIME## COMMAND)
;"TIME (JOB NO.)" - PRINT TOTAL AND INCREMENTAL RUNNING TIME FOR A JOB
;FOLLOWED BY KILO-CORE TICKS
;"TIME 0" IMPLIES RUNTIME FOR NULL JOB
; IF NO JOB NO. GIVEN-TIME WILL BE FOR CURRENTLY LOGGEN IN JOB NO.
RUNTIM::PUSHJ P,SAVJW## ;SAVE J (W GETS A RIDE)
PUSHJ P,GETJOB ;GET JOB NO. ARG.
JRST RUN1 ;NO ARG. GIVEN - LOGGED IN?
MOVE J,T2 ;SETUP DESIRED JOB NUMBER
JRST PRTTIM ;PRINT TOTAL RUN TIME+KIL-CORE-SEC
; BUT DO NOT PRINT INCREMENTAL
RUN1: MOVSI T1,JLOG ;IS JOB LOGGED IN?
TDZN T1,JBTSTS##(J) ;TEST JOB STATUS BITS AND CLEAR T1 ALWAYS
JRST NOTENF ;NO, NEED MORE ARGUMENTS
EXCH T1,.PDRTM##(W) ;CLEAR INCREMENTAL TIME
PUSHJ P,PRTIME ;PRINT TIME SINCE LAST TIME COMMAND PLUS CRLF
PRTTIM: PUSHJ P,FNDPDB## ;ADDRESS OF PDB FOR JOB
TDZA T1,T1 ;NO PDB -- GIVE 0
MOVE T1,.PDTTM##(W) ;GET TOTAL ACCUMULATED TIME
JUMPE W,PRTIME ;EXIT IF NO PDB
PUSHJ P,PRTIME
PUSHJ P,INLMES ;PRINT "J*CPUSEG=
ASCIZ /kilo-core-sec=/
MOVE T1,.PDKCT##(W) ;PRODUCT OF NO. OF J CORE* NO. OF JIFFIES RUN
;SUBROUTINE TO PRINT SECONDS, CRLF
IDIV T1,TICSEC## ;CONVERT TO SECONDS FROM JIFFIES
PJRST DECLF ;PRINT IN DECIMAL, ADD CRLF
SUBTTL SEND COMMAND
;ROUTINE TO SEND A LINE OF INFORMATION TO ANOTHER TTY, OR
; TO BROADCAST IT TO ALL TTY'S
SEND:: PUSHJ P,SAVE2##
PUSHJ P,CTEXT1 ;GET ARGUMENT DEVICE OF SEND
JUMPE T2,NOTENF ;MUST BE ONE
IFN FTNET,<
SETZ W, ;CLEAR NODE POINTER
CAIE T3,"_" ;TERMINATED BY _
JRST SEND0 ;NO, CONTINUE NORMAL
NETDBJ ;INTERLOCK THIS PART
MOVE T1,T2 ;COPY THE NODE NAME
PUSHJ P,CVTOCT## ;CHECK FOR A NUMBER
MOVE T1,T2 ;MUST BE A NODE NAME
SKIPE T1 ;NOT ZERO
PUSHJ P,SRCNDB## ;FIND THE NODE DATA BLOCK
JRST [JSP T1,ERRMES ;NODE DOES NOT EXIST
ASCIZ /Node does not exist
/]
HLRZ W,(W)
SE1ENT
JRST SENDA ;DO A PSEUDO SEND ALL
SEND0:> ;END IFN FTNET
SE1ENT ;ENTER SECTION 1
MOVE S,T1 ;SAVE WHAT USER TYPED
MOVS T1,T2 ;GET IT SWAPPED FOR COMPARES
CAIN T1,(SIXBIT /JOB/) ;PARTICULAR JOB NUMBER?
JRST SENDJ ;YES. GO FIND IT
CAIN T1,(SIXBIT /ALL/) ;BROADCAST TO ALL TTY'S?
JRST SENDA ;YES.
HRRZ P1,T1 ;SAVE WHAT WAS TYPED
PUSH P,U ;SAVE LINE ADDRESS OF SENDER
MOVE T1,T2 ;GET DEVICE NAME TO SEARCH FOR
PUSHJ P,DEVNFS## ;TRY TO MAKE SENSE OF DEVICE NAME
JRST SEND03 ;NOT A DEVICE, TRY OCTAL LINE NUMBER
MOVE T2,DEVMOD(F) ;GET THE BITS WORDS
TLNE T2,DVTTY ;IS IT A TTY?
TLNE T2,DVDSK ;WATCH OUT FOR NUL:
JRST SENDE2 ;TSK TSK NOT A TTY AT ALL
MOVE U,DDBLDB##(F) ;GET ADDRESS OF LDB
PUSHJ P,TTYKLQ## ;STOMP AN DDB IF NEED BE
JUMPN U,SENDT ;TO DO THE SEND
JRST SENDE2 ;DUH? ON SECOND THOUGHT, DON'T DO THE SEND
;UNRECOGNIZABLE DEVICE, TRY FOR A STRAIGHT OCTAL LINE NUMBER
SEND03: TRNE T1,-1 ;IF MORE THAN 3 CHARACTERS
JRST SENDE1 ;THEN IT'S NO TTY THAT WE KNOW OF
HLRZ T1,T1 ;POSITION "UNIT" NUMBER IN RH
HRLI T1,'TTY' ;GENERIC DEVICE TYPE
PUSHJ P,TTYALL## ;SEE IF IT MAKES ANY SENSE NOW
JRST SENDE1 ;USER MAKES NO SENSE WHATEVER
; JRST SENDT ;AH HA! WE HAVE A VALID TTY
;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE
SENDT:
IFN FTNET,<
SKIPGE LDBREM##(U) ;IF VTM+ HOSTED AWAY
JRST SENDE1 ;DON'T SEND
>;END IFN FTNET
MOVE T1,0(P) ;SEE IF EITHER GUY IS THE OPR
CAME U,OPRLDB## ; ..
CAMN T1,OPRLDB## ; ..
JRST SENDT1 ;YES. DONT BUSY CHECK
MOVE T1,LDBDCH##(U) ;NO. SEE IF DEST IS AT COMMAND LEVEL
HLR T1,LDBBY2##(U) ;OR HAS ALLOWED SENDS
TDNE T1,[LDLCOM##,,L2LSND##] ;OK TO SEND?
JRST SENDT1 ;YES. OK TO SEND
EXCH U,(P) ;RESTORE U
PUSHJ P,SETLGL ;DOESN'T WANT A SEND. OVERRIDE?
JRST SNDBSY ;NO. HE'S BUSY.
EXCH U,(P) ;POINT TOGETHER
SENDT1: SKIPN %SIOPR## ;YES, IS ORION RUNNING?
JRST SENDT3 ;NO, SEND TO OPR THE OLD WAY
CAIE P1,'OPR' ;SENDING TO OPERATOR?
JRST SENDT3 ;NO, NORMAL SEND
POP P,U ;SAVE U
JSP T2,SAVCTD## ;AND SOME CONTEXT
PUSHJ P,SAVE4## ;AND SOME REGS
MOVE T2,LDBTIC##(U) ;GET NUMBER OF CHARS IN THE USER'S MESSAGE
ADDI T2,4+1 ;ROUND OFF (PLUS 1 FOR BELL IN SNOTXS)
IDIVI T2,5 ; TO # WORDS
MOVSI P4,1(T2) ;FIGURE TEXT BLOCK LENGTH
MOVE P1,T2 ;GET # OF WORDS
IMULI P1,5 ;FIGURE # OF CHARS THAT CAN FIT IN THOSE WORDS
SOS P1 ;LEAVE ROOM FOR THE ASCIZ IN SNDTXS
ADDI T2,5+1+<1+1>+<1+1>+<1+2> ;5 - GALAXY HEADER, 1 - TEXT BLOCK HEADER
; 2 - FUNCTION BLOCK, 2 - NODE BLOCK
; 3 - TTY NAME BLOCK
HRLZ P2,T2 ;SIZE OF THE BLOCK
PUSHJ P,GTFWDC## ;GET SOME FUNNY SPACE
JRST [PUSH P,U ;CAN'T, SO SEND IT THE OLD WAY
JRST SENDT3]
PUSHJ P,SSEC0## ;DO THIS IN SECTION 0
HRR P2,T1 ;SAVE ADDRS OF SPACE GOTTEN
MOVSI T2,(T1) ;FROM FIRST WORD OF SPACE
HRRI T2,1(T1) ;TO NEXT WORD OF SPACE
HLRZ T3,P2 ;LENGTH OF THE SPACE
ADDI T3,(T1) ;WORD JUST PAST END OF SPACE
SETZM (T1) ;CLEAR THE FIRST WORD
BLT T2,-1(T3) ;AND CLEAR THE WHOLE MESSAGE
HLLZ T2,P2 ;COPY THE MESSAGE LENGTH
HRRI T2,.IPCGM## ;SETUP THE MESSAGE TYPE
MOVEM T2,(T1) ;.MSTYP - LEN,,TYPE
MOVSI T2,(WT.SND) ;INDICATE SEND OPR
CAMN U,OPRLDB##
IORM T2,3(T1) ;IN MESSAGE TO ORION
MOVEI P3,5(T1) ;AIM P3 AT THE 'CURRENT' BLOCK
;
; P2/ LEN,,ADRS OF THE MESSAGE
; P3/ ADRS OF 'CURRENT' BLOCK
;
DMOVE T1,[XWD 2,.WTUFC ;GET THE FIRST DATA BLOCK HEADER
EXP %QWTO##-.GTQFT##] ;A FUNCTION BLOCK - WTO FUNCTION
DMOVEM T1,0(P3) ;STORE 'EM
ADDI P3,2 ;STEP TO NEXT BLOCK
AOS 4(P2) ;COUNT THE ARGUMENT BLOCKS
IFN FTNET,<
HLLZ T1,S ;NODE NUMBER
SKIPE T1
PUSHJ P,CVTOCT## ;CONVERT
MOVE T1,JBTLOC##(J) ;USE WHERE LOCATED
PUSHJ P,[NETDBJ
JRST NODE.S##]
JRST SENDT2 ;NO NODE, DON'T INCLUDE A NODE BLOCK!
HLRZ T1,NDBSNM##(W)
MOVE T2,(T1) ;GET THE DESIRED NODE NAME
MOVE T1,[2,,.WTDES] ;AND THE ARGUMENT BLOCK HEADER WORD
DMOVEM T1,0(P3) ;MAKE THIS BLOCK
ADDI P3,2
AOS 4(P2) ;ONE MORE ARG BLOCK
>
SENDT2: PUSH P,U ;SAVE U
PUSHJ P,SENDH0 ;GO GENERATE SENDER'S TTY NAME
MOVE T1,[3,,.WTTTY] ;GET THE ARGUMENT BLOCK HEADER WORD
DMOVEM T1,0(P3) ;BUILD PART OF THE BLOCK
PUSHJ P,GTNTS0## ;GET [NODE #,,LINE #] IN T1
SETOM T1 ;TTY NOT CONNECTED
MOVEM T1,2(P3) ;FINISH .WTTTY ARG BLOCK
POP P,U ;GET ORIGINAL U BACK
ADDI P3,3 ;POINT TO NEXT BLOCK
AOS 4(P2) ;COUNT THIS ARG BLOCK
;BUILD THE TEXT BLOCK
HRRI P4,.WTTXT
MOVEM P4,0(P3)
MOVEI P4,%SIOPR ;WHO GETS THE MESSAGE
MOVEI T4,1(P3)
AOS 4(P2) ;ONE MORE ARG BLOCK
JRST SNDTXS
;HERE TO DO THE 'OLD STYLE' SEND OPR COMMAND
SENDT3: S0PSHJ SENDHD ;SEND HEADER (CRLF, SEMI, TTY NAME)
SEND1: PUSHJ P,SNDTYI ;GET CHARACTER TO SEND OUT
JRST SEND2 ;END OF LINE
PUSHJ P,COMTYO## ;SEND IT (DEST IN LINE)
JUMPN T3,SEND1 ;LOOP FOR MORE
SEND2: PUSHJ P,SNDEOL ;SEND CRLF, MAYBE DOT TO DEST
;RESTORE STACK, GET SENDER LDB
PJRST UPOPJ## ;AND RETURN FROM SEND COMMAND
;MORE OF SEND COMMAND
SENDJ: PUSHJ P,GETJOB ;GET DESIRED JOB NUMBER
JRST NOTENF ;MUST HAVE AN ARG
PUSH P,U ;OK. SAVE SENDER'S LDB
HRRZ F,TTYTAB##(T2) ;GET TTY DDB OF DEST JOB
JUMPE F,SENDE1 ;MUST BE ONE
MOVE U,DDBLDB##(F) ;GET LDB ADDRESS
JUMPN U,SENDT ;AND GO SEND IT (IF NOT DETACHED)
SENDE1: POP P,U ;OOPS. NO SUCH GUY. GET SENDER
JSP T1,ERRMES ;AND GIVE HIM THE BAD NEWS
ASCIZ /No such tty
/
SENDE2: POP P,U
JSP T1,ERRMES ;RESTORE THE STACK
; AND GRIPE AT THE USER
ASCIZ /Not a tty
/
SENDA: PUSHJ P,SETLGL ;LEGAL? (OPR OR [1,2])
JRST COMERA ;NOT LEGAL
SKIPE SNDCTR ;SKIP IF SEND BUFFER IS FREE
JRST DLYCM1 ;NOT FREE, DELAY THE COMMAND
PUSH P,U ;YES. STACK LDB ADR OF OPR
MOVE T1,SNDPTR ;PICK UP POINTER
MOVEM T1,SNDTMP ;SAVE IN TEMP
MOVEI T1,SNDTYO ;INTERCEPT TYPEOUT
MOVEM T1,.CPTOA## ;..
MOVEI T1,^D85 ;PRESET QUOTA
MOVEM T1,SNDCNT ; SO WE DON'T WIPE
; COMCON
S0PSHJ SENDHD ;SEND THE HEADER
MOVEI T1,CCTYO## ;RESTORE
MOVEM T1,.CPTOA## ;.CPTOA
MOVEI P1,^D85
SENDA3: PUSHJ P,SNDTYI ;GET A CHAR FROM SENDER
JRST SENDAX ;NO MORE.
MOVE T1,T3 ;COPY CHAR
SOSL P1
PUSHJ P,SNDTYO ;SEND TO ALL LINES
JRST SENDA3 ;LOOP TILL END OF LINE
SENDAX: MOVEI T1,FLLFLG## ;MARK SPOT FOR
IDPB T1,SNDTMP ;CRLF
MOVSI T1,LOLSAP## ;SEND ALL PENDING
IDPB T1,SNDTMP ;MAKE ASCIZ
AOS SNDCTR ;ALLOW A LITTLE SLOP TIME
AOS SNDCTR ;TO BE SURE THE MESSAGE GETS OUT
MOVNI U,1 ;LOOP OVER ALL LINES
JRST SENDX1 ;..
SENDX2: LDB U,LDPLNO## ;GET NEXT LINE
CAIL U,TTPLEN##-1 ;DONE?
JRST UPOPJ## ;YES.
SENDX1: MOVE U,LINTAB##+1(U) ;NO--GET NEXT LDB
MOVE T1,LDBDCH##(U) ;GET BITS
PUSHJ P,SHDSND ;SHOULD WE DO A SEND?
SKIPA T2,SNDPTR ;YES, SET UP POINTER
JRST SENDX2 ;NO--TRY NEXT LINE
MOVSI T1,LOLSAP## ;SET UP FLAG
SCNOFF ;NO INTERRUPTS HERE
IORM T1,LDBOST##(U) ;YES--SET FLAG
AOS SNDCTR
SCNON
SENDX3: PUSHJ P,TOPOKE## ;START TTY
JRST SENDX2 ;LOOP FOR MORE
;MORE OF SEND COMMAND
;SUBROUTINE TO GET CHARACTER FROM SENDER, WHOSE LDB IS ON STACK
SNDTYI: EXCH U,-1(P) ;GET SENDER'S LDB
PUSHJ P,COMTYI## ;GET HIS CHARACTER AND ITS BITS
EXCH U,-1(P) ;RESTORE LINE OF SENDEE
TLNE T1,CHBRK## ;IS THIS AN END OF LINE?
POPJ P,0 ;YES. NON-SKIP RETURN FROM SNDTYI
CAIE T3,"H"-100 ;FILTER ^H
TLNE T1,CHUAE## ;NO. IS IT A LOSING CONTROL CHAR?
JRST SNDTYI ;YES. FILTER IT OUT
JRST CPOPJ1## ;NORMAL CHAR. SKIP RETURN
SENDHD: PUSHJ P,INLMES ;SEND START OF SEND MESSAGE
BYTE(7)15,12,7,";",";",0 ;CR,LF,BELL
EXCH U,-1+IFN FTXMON,<-1>(P) ;GET SENDER'S LDB ADR
PUSHJ P,SENDH0 ;GENERATE A TTY NAME
CAMN U,OPRLDB## ;IS IT THE OPR?
MOVSI T2,(SIXBIT /OPR/) ;YES. SAY OPR INSTEAD
CAMN U,LINTAB##+FRCLIN## ;IS IT FROM FRCLIN
MOVE T2,[SIXBIT/SYSTEM/] ;YES, USE SYSTEM
MOVE U,-1+IFN FTXMON<-1>(P) ;RESTORE RECIPIENT
MOVEM T3,-1+IFN FTXMON,<-1>(P) ;PUT PTY POINTER ON STACK
PUSHJ P,PRNAME ;OUTPUT THE NAME TO SENDEE
PUSHJ P,INLMES ;AND SPACER
ASCIZ /: - / ; ..
POPJ P,0 ;RETURN FROM SENDHD
SENDH0: MOVE T1,J ;SET UP T1 FOR FIRST TIME THROUGH
MOVE T3,U ;SAVE U IN CASE OF ERROR
MOVEI T4,^D20 ;MAX DEPTH
SENDH1: MOVE T2,JBTLIM##(T1) ;IS SENDER A
TLNE T2,(JB.LBT) ;BATCH SUBJOB?
JRST SENDH3 ;YES, NEVER SAY OPR
PUSHJ P,CTLJBU## ;FIND CONTROL JOB
JUMPE U,SENDH2 ;DETACHED JOB
JUMPL T1,SENDH3 ;FOUND A TTY
MOVE F,TTYTAB##(T1) ;CONTROLLING TTY
MOVE U,DDBLDB##(F) ;HIS LINE
SOJG T4,SENDH1 ;LOOK FOR NEXT PTY
SENDH2: MOVE U,T3 ;RESTORE U
SENDH3: PUSH P,T3 ;SAVE POINTER TO PTY LDB
PUSHJ P,TTYNAM## ;CONVERT TO REAL NAME IN SIXBIT
POP P,T3
POPJ P,
SNDEOL: PUSHJ P,CRLF ;SEND CR LF TO LINE IN U
MOVE T1,LDBDCH##(U) ;SEE IF DEST IS AT COM LEVEL
TLNE T1,LDLCOM## ; ..
PUSHJ P,PRDOTC ;YES. SEND A DOT TOO
POPJ P,0 ;RETURN FROM SNDEOL
SHDSND: SKIPL LDBOFL##(U) ;SKIP IF OFF LINE?
TRNE T1,LDRPTY## ;DON'T SEND TO A PTY
JRST CPOPJ1## ;WHICH THIS IS
IFN FTNET,<
JUMPE W,SHDND2 ;ANY PARTICULAR NODE SPECIFIED
CAME W,JBTLOC## ;CHECK FOR THE LOCAL NODE
JRST SHDND0 ;REMOTE LINE
SKIPL LDBTTW##(U) ;LOCAL NODE IS THIS A LOCAL LINE?
JRST SHDND1 ;YES, CONTINUE
SHDND0: LDB T4,LDPRNN## ;GET THE NODE NUMBER OF THE REMOTE LINE
JUMPE T4,CPOPJ1## ;UNASSIGNED LINE
CAIE T4,(W) ;IS THIS LINE ON THAT NODE
JRST CPOPJ1## ;NO, RETURN
JRST SHDND1 ;YES CONTINUE
SHDND2: MOVSI T4,LRLCON## ;TTY
TDNE T4,LDBREM##(U) ; CONNECTED?
JRST SHDND1 ;YES CONTINUE
SKIPGE LDBTTW##(U) ;NO IS IT A REMOTE LINE
JRST CPOPJ1## ;YES, GO AWAY
SHDND1: SKIPGE LDBREM##(U) ;IF VTM + HOSTED AWAY
JRST CPOPJ1## ;YES, GO AWAY
>;END IFN FTNET
IFN FTMP,<
LDB T4,LDPCPU## ;CPU OWNING THE TERMINAL
CAIN T4,7 ;GENERIC BOOT CPU
MOVE T4,BOOTCP## ;YES, GET CPU NUMBER
IMULI T4,.CPLEN## ;TO CDB OFFSET
SKIPL .C0OK##(T4) ;CPU RUNNING
JRST CPOPJ1## ;NO, DON'T SEND
>
PUSH P,T1 ;SAVE T1
LDB T1,LDPLNO## ;GET LINE # INTO T1
IFN FTKS10,<
CAIE T1,KLILIN## ;KLINIK LINE?
JRST SHSND0 ;NO
MOVEI T4,KLIINI ;KLINIK INITED?
TDNN T4,KLIIWD
JRST TPOPJ1## ;NO,DON'T SEND
SHSND0:>
PUSHJ P,XTCTTY## ;CHECK ON DA-28 LINE
PJRST TPOPJ1## ;INACTIVE LINE - SKIP RETURN
JFCL ;ACTIVE LINE - OK
POP P,T1 ;NORMAL RETURN - RESTORE T1
HRRZ T4,LDBDDB##(U) ;GET DDB ADDRESS
JUMPE T4,SHSND1 ;JUMP IF NO DDB
MOVE T4,DEVIOS(T4) ;GET INIT MODE
TRNE T4,I!PIMMOD ;IMAGE MODE OR PACKED IMAGE MODE?
JRST CPOPJ1## ;YES--DO NOT SEND
SHSND1: MOVE T4,LDBBY2##(U) ;GET GAG FLAG
TLNE T1,LDLSLV## ;IF NOT SLAVE
TLNE T4,L2LSND## ;OR NOT GAGGED
SKIPA T4,LDBTTW##(U) ;OK, MAYBE, IF IN USE
JRST CPOPJ1## ;DON'T SEND TO GAGGED SLAVE
TLNN T4,LTLUSE## ;LINE IN USE?
AOS (P) ;NO, DON'T SEND
POPJ P, ;YES, SEND
SNDTYO: ;PUSHJ P,PEVEN8## ;ADD PARITY
SOSL SNDCNT ;SKIP IF NO ROOM
IDPB T3,SNDTMP ;STORE BYTE
POPJ P, ;RETURN
$LOW
SNDCNT::EXP ^D85
SNDCTR::EXP 0
SNDTMP::POINT 9,SNDTXT ;ACTIVE POINTER
SNDPTR::POINT 9,SNDTXT ;VIRGIN POINTER
SNDTXT: BLOCK ^D85/4+1 ;BUFFER
SNDMXL==:<.-SNDTMP-1>B26
$HIGH
SNDBSY: POP P,T1 ;REMOVE SENDEE FROM STACK
SNDBSI: JSP T1,ERRMES ;TYPE ERROR AND RETURN
ASCIZ /Busy
/
SUBTTL VERSION COMMAND & PRVERS SUBROUTINE
;"VERSION" -- COMMAND TO PRINT LOW+HISEG NAME+VERSION
;FORMAT IS: LOWNAM LOWVER[+[HINAM HIVER]]
;HISEG STUFF ONLY IF VERSION DIFFERENT OR NAME NON-ZERO
; AND DIFFERENT
;IF HISEG NAME ZERO, HINAM IS OMITTED
;IF NO HISEG, "+" IS OMITTED
;VERSION IS ALWAYS IN FORM VER LET(EDIT)-CUST.
VERCOM::PUSHJ P,INTLVL## ;AT UUO LEVEL ALREADY?
JRST VERBTH ;YES
MOVE S,P2 ;SAVE COMMAND NAME AS DATA ITEM
JSP T2,SAVCTX## ;SET UP TO RUN AT UUO LEVEL
MOVE P2,S ;RESTORE COMMAND NAME
PUSHJ P,TTYFUW##
VERBTH::MOVE T2,JBTNAM##(J) ;GET LOW NAME
PUSHJ P,PRNAME ;PRINT IT
PUSHJ P,PRSPC ;AND SPACE
MOVE T1,.JDAT+.JBVER## ;GET LOW VERSION
PUSHJ P,PRVERS ;PRINT IT
VERHGH::PUSHJ P,SAVE3##
PUSHJ P,INTLVL## ;AT UUO LEVEL ALREADY?
JRST VERHG0 ;YES
MOVE S,P2 ;SAVE COMMAND NAME AS DATA ITEM
JSP T2,SAVCTX## ;SET UP TO RUN AT UUO LEVEL
MOVE P2,S ;RESTORE COMMAND NAME
PUSHJ P,TTYFUW##
VERHG0: TDZA T1,T1 ;CLEAR T1
VERHLP: MOVE T1,P3 ;RESTORE LAST BLOCK LOOKED AT
VERHL1: PUSHJ P,GNXHSB## ;GET NEXT HIGH SEG BLOCK
POPJ P, ;DONE
SKIPG P1,.HBSGN(T1) ;GET SEGMENT DATA
JRST VERHL1 ;SPY SEG
MOVE P3,T1 ;SAVE HIGH SEG DATA BLOCK ADDR
PUSHJ P,INLMES ;INDICATE HI-SEG
ASCIZ / + /
MOVE T1,P3 ;GET HIGH SEG BLOCK AGAIN
PUSHJ P,GETHSA ;GET STARTING ADDRESS OF HI SEG
MOVE T2,T1 ;SAVE IT A BIT
HLRZS T1 ;SET PCS TO THIS
PUSHJ P,SVPCS## ;SAVE CURRENT PCS, SETUP NEW FOR FLTST
MOVE T1,T2 ;RESTORE ADDRESS
PUSHJ P,FLTST## ;IN CORE?
JRST VERNAA ;NOT IN CORE
VERAOK: MOVE T1,P3 ;HSB ADDR
PUSHJ P,MAPVJD## ;SET .VJDT TO CORRECT LOCATION
SKIPN T2,JBTNAM##(P1) ;GET HI NAME
MOVE T2,.VJDT+.JBHNM## ;BLANK--USE SAVE
SKIPE T1,.VJDT+.JBHVR## ;GET HIGH VERSION
CAMN T1,.JDAT+.JBVER## ; COMPARE TO LOW IF PRESENT
CAME T2,JBTNAM##(J) ;COMPARE TO LOW NAME
CAIA ;DIFFERENT, PRINT
JRST VERHG2
VERHG1: PUSHJ P,PRNAME ;PRINT HI HAME
PUSHJ P,PRSPC ;AND SPACE
MOVE T1,.VJDT+.JBHVR## ;GET HI VERSION
PUSHJ P,PRVERS ;PRINT VERSION #
VERHG2: MOVE T1,JBTSTS##(P1) ;GET HISEG FLAGS
TLNE T1,SHRSEG ;SHARE SEG?
JRST VERHG3 ;CONTINUE
PUSHJ P,INLMES ;NO--WARN USER
ASCIZ " Not sharable "
VERHG3: CAME P2,VERTXT## ;IF THIS IS VERSION COMMAND
AOSE P2 ;OR NOT FIRST TIME
JRST VERHLP ;LOOP
PUSHJ P,PGMFIL ;ELSE SEE IF WE DID I/O
JRST VERHLP
VERNAA: LSH T1,W2PLSH ;COULD BE ALLOCATED BUT ZERO
S1PSHJ GTPME## ;GET MAP CONTENTS
TLZ T2,(PM.NAD)
CAME T2,[PM.ZER]
CAME P2,VERTXT## ;ONLY ON A VERSION COMMAND
JRST VERHLP
MOVE T1,P3 ;HIGH SEG DATA BLOCK ADDR
PUSHJ P,GETHSA ;GET HI SEG ADDRESS AGAIN
LSH T1,W2PLSH ;CONVERT TO PAGE NUMBER
PUSHJ P,[PUSHJ P,SETASA ;GET THE PAGE INTO CORE AND ACCESSIBLE
PUSHJ P,PAGIA
CAIA
AOS (P)
PUSHJ P,TTYFUW##
JRST CLRASA]
JRST VERHLP ;AND AFTER ALL THAT WORK
JRST VERAOK
;PRINT VERSION FROM T1
PRVERS::PUSHJ P,SAVE1##
PUSH P,T1 ;SAVE FOR LATER
LSH T1,-^D24 ;POSITION MAJOR VERSION
ANDI T1,777 ;CLEAR JUNK
SKIPE T1 ;IF NON-ZERO,
PUSHJ P,PRTDI8 ; PRINT IN OCTAL
HLRZ T1,(P) ;GET MINOR VERSION
ANDI T1,77 ;CLEAR JUNK
JUMPE T1,PRVER2 ;IF NON-ZERO,
SUBI T1,1 ;
IDIVI T1,^D26 ; PRINT IN ALPHA
JUMPE T1,PRVER1 ; ONE OR TWO
PUSH P,T2 ; CHARACTERS
MOVEI T3,"A"-1(T1) ; ..
PUSHJ P,COMTYO## ; ..
POP P,T2 ; ..
PRVER1: MOVEI T3,"A"(T2) ; ALSO, SECOND ONE
PUSHJ P,COMTYO## ; ..
PRVER2: HRRZ T1,(P) ;GET EDIT NUMBER
JUMPE T1,PRVER3 ;IF NON-ZERO,
PUSHJ P,INLMES ; PRINT (
ASCIZ /(/
HRRZ T1,(P) ; GET EDIT NUMBER
PUSHJ P,PRTDI8 ; PRINT IN OCTAL
PUSHJ P,INLMES ; PRINT )
ASCIZ /)/
PRVER3: POP P,P1 ;GET CUST. NUMBER
LSH P1,-^D33 ;POSITION
JUMPE P1,CPOPJ## ;IF NON-ZERO,
PUSHJ P,INLMES ; PRINT -
ASCIZ /-/
MOVEI T3,"0"(P1) ; GET DIGIT
PJRST COMTYO## ;PRINT AND RETURN
;SUBROUTINE TO GET HI SEG ADDRESS, CALL WITH T1=HIGH SEG DATA BLOCK,
;RETURNS T1=ADDRESS
GETHSA::PUSH P,J ;SAVE JOB NUMBER
SKIPG J,.HBSGN(T1) ;IS THERE A REAL HIGH SEG?
JRST JPOPJ## ;NO
HRRZS J ;CLEAR CRUFT
LDB J,JBYHSO## ;ORGIN WITHIN SEGMENT
LDB T1,[PSG2LH+.HBSG2(T1)] ;SECTION HI SEG IS IN
LSH T1,S2PLSH ;CONVERT TO PAGE
IORI T1,(J) ;ADD IN RELATIVE ORIGIN PAGE #
LSH T1,P2WLSH ;CONVERT TO VIRTUAL ADDRESS
JRST JPOPJ## ;AND RETURN
SUBTTL EXAMINE AND DEPOSIT COMMAND
;"EXAMINE LOC" - LOOKS AT CONTENTS OF LOC AND PRINTS IN OCTAL
;IF LOC IS MISSING, NEXT LOC IS PRINTED
;IF PREVIOUS WAS E COMMAND, SAME LOC IF PREVIOUS WAS D COMMAND
;TAB. IS PRINTED INSTEAD OF CRLF(LIKE DDT)
ECOM:: SKIPGE T2,.JDAT+JOBEXM## ;WAS PREVIOUS D OR E COMMAND, A D COMMAND?
AOS T2,.JDAT+JOBEXM## ;NO, IT WAS AN E, INCREMENT IN CASE HE TYPES NO ARG
TLO T2,400000 ;SET E FLAG
MOVEM T2,.JDAT+JOBEXM## ;YES, FLAG THAT E HAPPENED LAST(LH=-1)
PUSHJ P,OCTPAR ;GET OCTAL LOCATION
MOVE T2,.JDAT+JOBEXM## ;NONE SPECIFIED, USE LAST LOC OF D OR NEXT OF E
PUSHJ P,DEAT ;CHECK FOR AC REFERENCE AND STORE JOBEXM
PUSHJ P,FLTTC## ;WILL DOING AN EXAMINE CAUSE A PAGE FAULT?
JRST ECOMA ;NO, BUT OUT OF BOUNDS
PUSHJ P,DEGETP ;OUT, GET IT IN
MOVE M,T2 ;SET EXAMINE ADDRESS
MOVEI T1,0 ;ASSUME ALLOCATED BUT ZERO PAGE
TLZ T4,(PM.NAD)
CAMN T4,[PM.ZER] ;PAGE ABZ?
JRST ECOM1 ;YES, PRINT 0
IFN FTXMON,<
PUSHJ P,[PUSHJ P,SSPCS## ;SAVE PCS
MOVE T1,M ;SXPCS WANTS THIS IN T1
PUSHJ P,SXPCS## ;SETUP PCS THE WAY GETEWD WANTS IT
POPJ P, ;OUT OF BOUNDS
PJRST GETEWD##] ;GET WORD FROM LOW OR HIGH SEG
>
IFE FTXMON,<
PUSHJ P,GETWRD## ;GET WORD FROM HIGH OR LOW SEG
>
JRST ECOMA ;ERROR, OUT OF BOUNDS
ECOM1: PUSH P,T1 ;SAVE CONTENTS OF LOC TO BE PRINTED
MOVE T1,.JDAT+JOBEXM## ;PRINT LOC BEING EXAMINED
TLZ T1,400000 ;CLEAR EXAMINE LAST FLAG
PUSHJ P,UDPCP##
PUSHJ P,INLMES ;PRINT SLASH TAB
ASCIZ */ *
HLRZ T1,(P) ;PRINT LEFT HALF
PUSHJ P,OCTPNT
PUSHJ P,INLMES ;PRINT SPACE
ASCIZ / /
HRRZ T1,(P) ;PRINT RIGHT HALF
PUSHJ P,OCTPNT
PUSHJ P,INLMES ;PRINT FINAL TAB
ASCIZ / /
PUSHJ P,CLRASA ;CLEAR AC'S IN SHADOW AREA FLAG
HRLI M,NOFLM ;AVOID LEFT MARGIN
JRST TPOPJ## ;POP P,T1,POPJ P,
;"DEPOSIT LH RH LOC" - DEPOSITS XWD LH,RH IN LOCATION LOC
;IF LOC IS MISSING, ASSUME NEXT LOC IF PREVIOUS D, SAME LOC IF PREVIOUS E
DCOM:: PUSHJ P,SAVE2##
PUSHJ P,OCTPRR ;READ A WORD TO DEPOSIT, MUST BE 36 BITS
JRST NOTENF ;NOT ENOUGH ARGUMENTS
MOVE P2,T2 ;SAVE NUMBER TO DEPOSIT
SKIPL P1,.JDAT+JOBEXM## ;WAS PREVIOUS D OR E AN E COMMAND?
; NEGATIVE IF E, POSITIVE IF D
AOS P1,.JDAT+JOBEXM## ;NO, INCREMENT IN CASE USER TYPED NO THIRD ARG
; FOR SUCCESSIVE D'S
MOVSI T1,400000 ;FLAG THAT A D WAS DONE LAST
ANDCAM T1,.JDAT+JOBEXM## ; JOBEXM POSITIVE
PUSHJ P,OCTPAR ;GET LOC
MOVE T2,P1 ;NOT SPECIFIED, USE LAST OF E OR NEXT OF D
MOVE S,P2 ;NUMBER TO BE DEPOSITED INTO S
PUSHJ P,CHKMED## ;CHECK TO SEE IF HIGH SEG IS SHARABLE
; IF YES, SET USER-MODE WRITE PROTECT (UWP) ON
; FOR THIS USER, AND SET MEDDLE FOR THIS USER
; SO HE CANNOT TURN UWP OFF
PUSHJ P,DEAT ;CHECK FOR AC REFERENCE
PUSHJ P,FLTTC## ;WILL DOING A DEPOSIT CAUSE A PAGE FAULT?
JRST ECOMA ;NO, BUT OUT OF BOUNDS
PUSHJ P,DEGETP ;OUT, GET IT IN
MOVE M,T2 ;DEPOSIT ADDRESS TO M
TLZ T4,(PM.NAD) ;CLEAR BITS
CAMN T4,[PM.ZER]
PJRST CREPAG## ;YES, MAKE IT COME TO LIFE
IFN FTXMON,<
PUSHJ P,[PUSHJ P,SSPCS## ;SAVE PCS
MOVE T1,M ;SXPCS WANTS THIS IN T1
PUSHJ P,SXPCS## ;SETUP PCS THE WAY GETEWD WANTS IT
POPJ P, ;OUT OF BOUNDS
MOVE T1,S ;WHERE PUTEWD WANTS IT
PJRST PUTEWD##] ;PUT WORD INTO LOW OR HIGH SEG
>
IFE FTXMON,<
PUSHJ P,PUTWRD## ;TRY TO STORE THE WORD IN THE USER'S AREA
>
JRST ECOMA ;OUT OF BOUNDS
PJRST CLRASA ;CLEAR AC'S IN SHADOW AREA FLAG
DEAT: TLZ T2,400000 ;CLEAR LH IN CASE THIS IS A SUCCESSIVE E WITH NO ARG
DPB T2,[POINT 23,.JDAT+JOBEXM##,35] ;STORE FOR NEXT TIME, DO NOT TOUCH LH(D OR E LAST)
; YES, WAS JOB STOPPED IN USER MODE?
PUSH P,T2 ;SAVE ARG
TLZ T2,1 ;1,,0-1,,17 ARE ACS
CAIL T2,20 ;IS IT AN AC?
JRST T2POPJ## ;NO
CAME J,.CPJOB## ;CURRENT JOB?
PUSHJ P,SETASA ;NO, INDICATE AC'S ARE IN THE SHADOW AREA
JRST T2POPJ## ;RETURN
ECOMA: PUSHJ P,CLRASA ;CLEAR AC'S IN SHADOW AREA FLAG
JSP T1,ERRMES ;OUT OF BOUNDS
OUTBMS::ASCIZ /Out of bounds
/
;ROUTINE TO GET A PAGE IN AND MAKE IT ACCESSIBLE FOR D/E COMMANDS
DEGETP: MOVEM S,.JDAT+JOBFDV##;SAVE S FOR THE CALLER
POP P,S ;CALLER'S PC
JSP T2,SAVCTX## ;GET TO UUO LEVEL
PUSH P,S ;SAVE CALLER'S PC FOR RETURN
MOVE T1,.JDAT+JOBEXM## ;ADDRESS IN QUESTION
TLZ T1,400000 ;CLEAR E/D LAST FLAG
LSH T1,W2PLSH ;PAGE IN QUESTION
PUSHJ P,SETASA ;SO UUO ARGUMENTS ARE FETCHED CORRECTLY
PUSHJ P,PAGIA ;PAGE IT IN, TURN ON ACCESS ALLOWED
JRST [POP P,(P) ;SHOULDN'T HAPPEN BUT PRETEND OUT OF BOUNDS
PUSHJ P,TTYFUW## ;PAGIA CLOBBERED U
JRST ECOMA]
PUSHJ P,TTYFUW## ;FIND THE TTY
MOVE S,.JDAT+JOBFDV##;RESTORE CALLER'S S
MOVE T2,.JDAT+JOBEXM## ;WHERE TO GET/PUT WORD
TLZ T2,400000 ;CLEAR E/D LAST FLAG
SETZ T4, ;SO DOESN'T LOOK LIKE AN ABZ PAGE
POPJ P, ;RETURN
;"SCHEDULE" TYPES OUT RH OF STATES, LEGAL FOR ALL.
SKEDUL::HRRZ T1,STATES## ;SCHEDULE WITH NO ARGUMENTS.
PUSHJ P,OCTPNT ;PRINT RH OF STATES.
JRST CRLF ;AND RETURN WITH A CRLF
;"BLANK" OR NO ALPHA NUMERIC BEFORE BREAK CHAR COMMAND
;DISPATCHED TO LIKE ANY OTHER COMMAND(0 IN COMMAND TABLE)
CBLANK::SE1ENT ;GET TO A DECENT SECTION
PUSHJ P,CTIGLC## ;GET LAST CHARACTER SCANNED
CAIN T3,12 ;WAS BREAK A LINE-FEED?
POPJ P, ;YES--NULL COMMAND
CAIL T3,40 ;RANGE CHECK FOR SIXBIT
CAILE T3,137
JRST COMERA ;OUT OF RANGE IS ERROR
SUBI T3,40 ;CONVERT TO SIXBIT
LSHC T2,^D<72-6> ;MAKE A SIXBIT TOKEN
PUSHJ P,COMTYS ;READ ANOTHER CHARACTER SO OTHER ROUTINES WORK
SETZB P3,P4 ;SO DON'T CONFUSE US WITH SET COMMAND
MOVE P,.CPISF## ;RESTORE STACK TO VALUE AT COMGO
JRST COM1Z ;TRY AGAIN WITH VALUE IN T2
SUBTTL TTY COMMAND AND SET TTY COMMAND
;TTY [DEV[:]] [NO] WORD ;SETS OR CLEARS BITS IN LDBDCH FOR TTY LINE
;DEV ARGUMENT LEGAL ONLY IF ASSIGNED TO YOU OR YOU ARE OPR
TTYCMD::SE1ENT ;ENTER SCETION 1
PUSHJ P,SAVE2## ;SAVE P1
PUSH P,U ;SAVE TYPING TTY'S LDB
MOVE P1,U ;ASSUME HIS WILL BE OBJECT
PUSHJ P,CTEXT1 ;GET AN ARGUMENT
IFN FTNET,<
CAIE T3,"_" ;START OF NODE_LINE?
JRST TTYC0 ;NO, CHECK IF DEVICE
POP P,U ;FIX STACK FOR CO-ROUTINING
NETDBJ ;INTERLOCK THIS PART
MOVE T1,T2 ;PUT IN RIGHT PLACE FOR NETSER
PUSH P,U ;SAVE OUR LINE AGAIN
PUSHJ P,SRCNDB## ;FIND THE NODE BY NAME
JRST [JSP T1,TTYCF ;NODE DOES NOT EXIST
ASCIZ /Node does not exist
/]
MOVE P1,T1 ;SAVE THE STATION NAME
PUSHJ P,CTEXT ;GET THE DEVICE NAME
JUMPE T2,NOTENP ;ILLEGAL ARG LIST
MOVE P2,T2 ;SAVE THE DEVICE NAME
TRNE T2,505050 ;MUST BE NUMERIC GGGU
JRST NOTDV1 ;ERROR RETURN
TLNE P2,505050 ;IS LH A NUMBER?
JRST TTYC0B ;NO, CONTINUE NORMALLY
MOVSS P2 ;FLIP HALVES OF ARGUMENT
TTYC0A: TRNE P2,77 ;IS RIGHTMOST DIGIT ZERO?
JRST TTYC0C ;NO, DONE
LSH P2,-6 ;SHIFT RIGHT ONE DIGIT
JRST TTYC0A ; AND TRY AGAIN
TTYC0C: TRO P2,202020 ;MAKE IT ALL DIGITS
HRLI P2,(SIXBIT/TTY/); AND MAKE LH SAY TTY
TTYC0B: MOVE T2,P2 ;RESTORE DEVICE NAME
HLRZ P1,NDBNNM##(W) ;GET NODE #
CAMN P1,JBTLOC## ;LOCAL NODE?
JRST TTYC0D ;YES, JUST RETURN
MOVEI P1,(W) ;SAVE THE NDB POINTER
HLRZ T1,P2 ;GENERIC NAME ONLY FROM THE LEFT HALF
CAIE T1,'TTY' ;IS IT A TTY?
JRST [JSP T1,TTYCF ;NO. COMPLAIN.
ASCIZ /Not a TTY/]
HRLZ T1,P2 ;GET THE REMOTE LINE NUMBER
PUSHJ P,CVTOCT## ;CONVERT IT TO OCTAL
JRST NOTDV1 ;NON NUMERIC LINE NUMBER
HLL T1,NDBNNM(W) ;GET THE NODE NUMBER
PUSHJ P,GTXTN## ;AND TRY TO CONVERT THE PAIR TO "TTYNNN"
JRST [JSP T1,TTYCF ;NOT IMMEDIATELY AVAILABLE
ASCIZ /Not connected/]
MOVE T2,T1 ;COPY THE DEVICE NAME
JRST TTYC0D ;WE SUCCEDED. T2 := DEVICE NAME
TTYC0:
> ;END IFN FTNET
CAIE T3,":" ;DEVICE?
JRST TTYC1 ;NO. A WORD.
MOVE T1,T2 ;GET THE DEVICE.
TTYC0D: PUSHJ P,DEVNFS## ;FIND THE DEVICE
JRST TTYCE ;NO SUCH DEVICE
MOVE T2,DEVMOD(F) ;GET DEVICE TYPE BITS
TLNE T2,DVTTY ;IS IT A TTY?
TLNE T2,DVDSK ; AND NOT NUL?
JRST TTYCE ;NO, ERROR
MOVE U,DDBLDB##(F) ;GET LDB ADDRESS
PUSHJ P,TTYKLQ## ;GIVE BACK TTY DDB IF NECESSARY
JUMPE U,TTYCE ;MAKE SURE WE GOT AN LDB ADDRESS
MOVE P1,U ;STORE AS OBJECT OF COMMAND
MOVE U,0(P) ;RESTORE LDB FOR TYPER
PUSHJ P,SKIPS ;DISCARD THE COLON
JRST TTYCE ;SHOULDNT BE END OF LINE
MOVE P2,U ;SEE IF THIS IS OPR
PUSHJ P,SETLGL ;SKIP IF OPR
CAMN P2,P1 ;HIS OWN TTY?
JRST TTYCL ;YES. OK.
LDB T2,PJOBN## ;NO. WHO OWNS THE TTY IN QUESTION
JUMPE T2,TTYCE ;LOSE IF NOBODY
CAIE T2,(J) ;OK IF US
JRST TTYCE ;OTHERWISE FAIL
;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE
TTYCL: MOVE U,0(P) ;RESET LINE TO TYPER
PUSHJ P,SKIPS1 ;SEE IF ANY MORE ON LINE.
JRST [MOVE U,P1 ;POINT TO TARGET
TLZ U,400000
PUSHJ P,SETCHP##
JRST UPOPJ##];RESTORE U AND RETURN
PUSHJ P,CTEXT1 ;YES. SEE WHAT IT IS
TTYC1: MOVE T1,[-TTCWDN,,TTCWDT] ;POINT TO NAMES
PUSHJ P,FNDNAM ;FIND ABBREV.
JRST TTYC4 ;ERROR
HRRZ T2,TTCWDD(T1) ;GET RESULT
HRRZ T3,TTCDAT(T1) ;GET FLAGS FOR COMMAND
TTYC2: MOVE T4,P1 ;TARGET LDB
TLZ T4,400000 ;CLEAR "NO" BIT
CAMN T4,LINTAB##+FRCLIN## ;IS TARGET FRCLIN?
TRNN T3,TT.CIF ;YES, IS THIS FUNCTION ILLEGAL?
PUSHJ P,(T2) ;DISPATCH TO ROUTINE
JRST TTYCE ;ERROR
JRST TTYCL ;LOOK FOR MORE
TTYC4: MOVE T1,[-TTTWDN,,CTTWDT] ;AOBJN POINTER TO TYPES TABLE
PUSHJ P,FNDNAM ;SEE IF RECOGNIZED TERMINAL TYPE
JRST TTYCE ;NO, CALL AN ERROR
MOVEI T2,TTUTYX ;DISPATCH ADDRESS TO PROCESS TERMINAL TYPE
MOVEI T3,TT.CIF ;THIS FUNCTION IS ILLEGAL ON FRCLIN
MOVE U,P1 ;SETUP TARGET LDB
TLZ U,400000 ;CLEAR POSSIBLE 'NO' BIT
JRST TTYC2 ;GO DISPATCH
TTYCE: POP P,U ;RESTORE LINE FROM STACK
JRST COMERR ;AND GO COMPLAIN.
TTYCF: POP P,U ;RESTORE LINE FROM STACK
PJRST ERRMES ;AND GIVE OUR MESSAGE
;TABLE FOR SET TTY COMMAND
;MACRO HAS 5 ARGUMENTS:
; NAME - WORD USED IN TTY COMMAND
; DISP - DISPATCH LOCATION TO PROCESS WORD
; OFST - OFFSET WITHIN LDB WHERE ANSWER IS STORED
; DATA - 18 BITS OF DATA USED BY PROCESSING ROUTINE
; BITS - FLAGS FOR THIS COMMAND
TT.CIF==1B18 ;THIS COMMAND IS ILLEGAL ON FRCLIN
DEFINE TTNAME,<
TT ALTMODE,TTCCLR,LDBPAG##,LPLALT##,0
TT BLANKS,TTCCLR,LDBPAG##,LPLBLK##,0
TT COPY,TTCESC,"_","^",TT.CIF
TT CRLF,TTCCLR,LDBDCH##,LDLNFC##,0
TT DEFER,TTCDFR,LDBBYT##,L1RDEM##,0
TT DISPLAY,TTCSET,LDBATR##,LALDIS##,0
TT ECHO,TTCCLR,LDBDCH##,LDLCNE##!LDLNEC##,TT.CIF
TT .EDIT,TTCEDT,LDBEDT##,0,TT.CIF
TT ESCAPE,TTCMAP,LDPESC##,33,TT.CIF
TT EIGHTBIT,TTC8BT,LDBATR##,LAL8BT##,0
; TT FFHOME,TTCSET,LDBPAG##,LPLFFH##,TT.CIF
; TT FFSIMU,TTCSET,LDBPAG##,LPLFFF##,TT.CIF
; TT FFSTOP,TTCSET,LDBPAG##,LPLFFS##,TT.CIF
TT FILL,TTCNUM,LDPFLC##,3,0
TT FORM,TTCSET,LDBDCH##,LDLFRM##,0
TT GAG,TTCCLR,LDBBY2##,L2LSND##,0
TT HOLD,TTCESC,"\",<"[">,TT.CIF
TT IGNORE,TTCIGN,0,0,TT.CIF
TT IGNORE,TTCIGN,0,0,TT.CIF ;MAKE SURE USER WANTS IGNORE
TT ISO,TTCSET,LDBATR##,LALISO##,TT.CIF
TT LC,TTCCLR,LDBDCH##,LDLLCT##,TT.CIF
TT LENGTH,TTCNUM,LDPLNB##,^D255,TT.CIF
TT LOCALCOPY,TTCSET,LDBDCH##,LDLLCP##,TT.CIF
TT NO,TTCNO,0,0,0
TT OVERSTRIKE,TTCSET,LDBATR##,LALCOS##,TT.CIF
TT PAGE,TTCPAG,LDPSTB##,^D255,TT.CIF
TT QUOTE,TTCSET,LDBBYT##,L1LQOT##,TT.CIF
TT RTCOMP,TTCSET,LDBISB##,LILRTC##,0
TT REMOTE,TTCREM,LDBDCH##,LDRRMT##,TT.CIF
TT SBELL,TTCSET,LDBPAG##,LPLSBL##,TT.CIF
TT SLAVE,TTCSLV,LDBDCH##,LDLSLV##,TT.CIF
TT SPEED,TTCSPD,0,0,TT.CIF
TT SSTOP,TTCSST,LDPSTB##,^D255,TT.CIF
TT STOP,TTCSTP,LDPSTB##,^D255,TT.CIF
TT TABS,TTCSET,LDBDCH##,LDLTAB##,0
TT TAPE,TTCTAP,LDBBY2##,L2LTAP##,TT.CIF
TT TYPE,TTCTYP,0,0,TT.CIF
TT UC,TTCSET,LDBDCH##,LDLLCT##,TT.CIF
TT UNPAUSE,TTCMAP,LDPUNP##,21,TT.CIF
TT WIDTH,TTCNUM,LDPWID##,<^D17*^O1000+^D255>,0
TT XONXOF,TTCSET,LDBPAG##,LPLXNF##,0
IFN FTPATT,<
TT .PATCH,TTYCL,0,0
> ;END FTPATT
> ;END TTNAME MACRO
XALL
DEFINE TT(NAME,DISP,OFST,DATA,BITS),<
<SIXBIT /NAME/>
>
$LOW
TTCWDT::TTNAME
TTCWDN==.-TTCWDT
TTCMXL==:<TTCWDN-1>B26
$HIGH
DEFINE TT(WORD,DISP,OFST,DATA,BITS)<
XWD OFST,DISP
>
TTCWDD: TTNAME
DEFINE TT(WORD,DISP,OFST,DATA,BITS)<
XWD DATA,BITS
>
TTCDAT: TTNAME
SALL
;HERE TO PROCESS 'TTY SPEED'
TTCSPD: PUSHJ P,NUMARG ;GO GET A NUMBER
POPJ P, ;MUST BE ONE
PUSHJ P,TTCSP1 ;FIND SPEED IN TABLE
POPJ P, ;NOT THERE
PUSH P,P2 ;SAVE RECEIVE SPEED
CAIN T3,"," ;ENDED WITH A COMMA?
PUSHJ P,COMTYS ;YES, SKIP IT
PUSHJ P,NUMARG ;GO GET NEXT NUMBER
JRST [MOVE P2,0(P) ;NONE, USE RECEIVE SPEED
JRST TTCSP0] ;AND SKIP TABLE LOOKUP
PUSHJ P,TTCSP1 ;CHECK TRANSMIT SPEED IN TABLE
JRST TPOPJ ;NOT THERE, ERROR
TTCSP0: MOVE U,P1 ;SETUP TARGET LDB
TLZ U,400000 ;CLEAR POSSIBLE "NO" BIT
DPB P2,LDPTSP## ;SAVE XMIT SPEED
POP P,P2 ;RESTORE RECEIVE SPEED
DPB P2,LDPRSP## ;SAVE RECEIVE SPEED
JRST CPOPJ1## ;GIVE GOOD RETURN
TTCSP1::MOVSI P2,-LSPLEN ;LENGTH OF TABLE
CAME T2,LSPTAB(P2) ;IS THIS IT?
AOBJN P2,.-1 ;NO--KEEP LOOKING
JUMPL P2,CPOPJ1## ;FOUND
POPJ P,0 ;LOST
LSPTAB:: DEC 0,50,75,110,134,150,200,300,600,1200,1800,2400,4800,9600,1,2
LSPLEN==:.-LSPTAB
;HERE TO PROCESS TTY ESCAPE AND TTY UNPAUSE
TTCMAP: HLRZ T2,TTCDAT(T1) ;GET OUR DEFAULT VALUE IF 'NO' FLAVOR
JUMPL P1,TTCMA1 ;JUMP IF NEGATING
PUSH P,T1 ;NO, SAVE INDEX
S0PSHJ OCTARG ;READ AN OCTAL NUMBER
JRST TTCMA2 ;NO, TRY FOR "<CHAR>"
JRST TTCMA3 ;YES, GO SET IT
TTCMA2: PUSHJ P,SKIPS1 ;SKIP BLANKS
JRST TPOPJ## ;MUST NOT HAVE EOL HERE
CAIE T3,"""" ;QUOTING A CHARACTER?
JRST TPOPJ## ;NO, I DON'T UNDERSTAND THIS
PUSHJ P,COMTYI## ;GET THE QUOTED CHARACTER
CAIN T3,12 ;IS IT LINEFEED?
JRST TPOPJ## ;YES, ABORT SINCE DON'T KNOW WHAT IT REALLY WAS
CAIE T3,"""" ;IS THIS ANOTHER QUOTE?
JRST TTCMA5 ;NO, CHECK FOR ^V
PUSHJ P,COMTYI## ;YES, GET NEXT CHARACTER
CAIE T3,"""" ;IS THIS ALSO QUOTE?
JRST TPOPJ## ;NO, BUT IT SHOULD BE
JRST TTCMA4 ;YES, DON'T TEST FOR ^V
TTCMA5: LDB T2,LDPQOT## ;GET TTY QUOTE ENABLED BIT
SKIPE T2 ;IS IT ENABLED?
CAIE T3,"V"-100 ;AND IS THIS THE MAGIC CHARACTER?
JRST TTCMA4 ;NO, DON'T EAT ANOTHER
PUSHJ P,COMTYI## ;YES, GET ANOTHER
TTCMA4: PUSH P,T3 ;NO, SAVE IT
PUSHJ P,COMTYI## ;ATTEMPT TO GET THE CLOSING QUOTE
CAIE T3,"""" ;IS IT HERE?
CAIN T3,12 ;OR EOL?
TRNA ;YES, WE'RE GOLDEN
JRST TTPOPJ## ;NO, GIVE UP
PUSHJ P,COMTYS ;EAT ONE TOO FAR FOR NEXT SKIPS1
POP P,T2 ;YES, RESTORE VALUE
TTCMA3: CAIL T2,0 ;IS IT IN RANGE?
CAILE T2,CK.CHR ;EITHER WAY?
JRST TPOPJ## ;NO, FORGET IT
POP P,T1 ;YES, RESTORE TABLE INDEX
TTCMA1: HLRZ T1,TTCWDD(T1) ;GET THE STORAGE POINTER
TLZ P1,400000 ;CLEAR THE 'NO' FLAG
EXCH P1,U ;SET TO AFFECT REQUESTED TARGET LINE
DPB T2,(T1) ;STORE THE VALUE
PUSHJ P,TOPNDS## ;SET THE LMLNDS FLAG FOR NETDEV
EXCH P1,U ;RESTORE THE LINE POINTERS
JRST CPOPJ1## ;SUCCESS
;HERE TO PROCESS TTY IGNORE
TTCIGN: MOVE U,P1 ;COPY LDB ADDRESS
TLZ U,400000 ;CLEAR "NO" BIT
LDB T1,LDPTSP## ;GET TRANSMIT SPEED
SKIPL P1 ;SKIP IF 'NO'
SETZM T1 ;NO--CLEAR T1
DPB T1,LDPRSP## ;SET TO RECEIVE SPEED
TLZ P1,400000 ;CLEAR YES/NO FLAG
JRST CPOPJ1## ;RETURN
;HERE TO PROCESS 'TTY REMOTE'
TTCREM: JUMPGE P1,TTCRM1 ;ANYONE CAN THROW AWAY GOODNESS
; (AND ONLY GOOD GUYS CAN GET GOOD TTY'S)
PUSHJ P,PRVJ ;BUT SETTING GOODNESS REQUIRES GOODNESS
JRST TTRSET ;TYPER IS ADEQUATELY PRIVILEGED
POPJ P, ;PRIVILEGED COMMAND BUT NO PRIVILEGES
TTCRM1: EXCH U,P1 ;GET ACS WHERE WE WANT THEM
LDB T2,LDPLNO## ;GET OUR LINE NUMBER
EXCH U,P1 ;RESTORE LDB ADDRESSES
CAIL T2,FRCLIN## ;MAKE SURE THAT FRCLIN AND THE CTYS
CAILE T2,TCONLN## ;STAY LOCAL
JRST TTRSET ;WIMP TERMINAL
POPJ P, ;FRCLIN & CTY0-N MUST REMAIN LOCAL
;HERE TO DO 'TTY EIGHTBIT'
TTC8BT: JUMPL P1,TTCSET ;ANYONE CAN SET 7-BIT
MOVSI T2,LIL7BT## ;DUMB FE BIT
TDNN T2,LDBISB##(U) ;SEE IF THIS FE CAN HANDLE 8-BIT
JRST TTCSET ;YES--GO DO IT
POPJ P, ;NO--WIMP OUT
;HERE TO DO 'TTY PAGE'
TTCPAG: PUSH P,T1 ;SAVE INDEX
MOVE T1,P1 ;ADDRESS OF LDB
ADDI T1,LDBPAG## ;ADDRESS OF WORD
MOVSI P2,LPLXNF##+LPLSTP## ;PAGE BIT
PUSHJ P,TTCST1 ;GO SET OR CLEAR IT
JFCL ;CAN NOT MISS
PUSHJ P,NUMARG ;GO READ IN ANY NUMERIC ARGUMENT
JRST TPOPJ1## ;NO CHANGE IN PAGE SIZE
POP P,T1 ;RESTORE INDEX
PUSHJ P,TTCNUP ;PROCESS THE NUMBER
POPJ P, ;OUT OF RANGE
EXCH U,P1 ;POINT U TO THE LDB
DPB T2,LDPLNB## ;ALSO SET TERMINAL LENGTH
EXCH P1,U ;RESTORE U
JRST CPOPJ1## ;SUCCESSFUL RETURN
;HERE TO DO 'TTY STOP'
TTCSTP: PUSH P,T1 ;SAVE INDEX
MOVE T1,P1 ;LDB ADDRESS
ADDI T1,LDBPAG## ;ADDRESS OF PAGING CONTROL
MOVSI P2,LPLSTP## ;AUTO STOP BIT
JRST TTCSS2 ;COMMON CODE
;HERE TO DO 'TTY 'SSTOP'
TTCSST: PUSH P,T1 ;SAVE INDEX
MOVE T1,P1 ;LDB ADDRESS
ADDI T1,LDBPAG## ;ADDRESS OF PAGING CONTROL
MOVSI P2,LPLSTP##+LPLSST## ;AUTO STOP BITS
TTCSS2: PUSHJ P,TTCST1 ;GO SET/CLEAR BITS
JFCL ;DUH?
PUSHJ P,NUMARG ;SEE IF ANY NUMERIC ARGUMENT
JRST TTCSS5 ;NO, SEE IF NEED TO DEFAULT STOP SIZE
POP P,T1 ;RESTORE INDEX
PUSHJ P,TTCNUP ;YES, PROCESS IT
POPJ P, ;OUT OF RANGE
JRST CPOPJ1## ;SUCCESSFUL RETURN
TTCSS5: POP P,T1 ;RESTORE INDEX
EXCH U,P1 ;POINT U TO THE LDB
TLZ U,400000 ;CLEAR "NO" BIT
LDB P2,LDPSTB ;GET SIZE OF STOP BASE
JUMPN P2,TTCSS6 ;IF SET THEN DON'T DEFAULT IT
LDB P2,LDPLNB ;PICK UP TTY LENGTH
DPB P2,LDPSTB ;AND USE IT FOR THE TTY STOP VALUE
TTCSS6: EXCH P1,U ;RESTORE U
JRST CPOPJ1## ;SUCCESSFUL RETURN
;HERE TO DO 'TTY DEFER'
TTCDFR: MOVE U,P1 ;SET UP FOR OUR TARGET
TLZE U,400000 ;CLEARING?
TDZA P2,P2 ;YES,
MOVEI P2,1 ;OR SETTING
LDB T2,LDPDEM## ;GET THE CURRENT VALUE
CAMN T2,P2 ;ARE WE CHANGING IT?
JRST CPOPJ1## ;NO, DON'T BOTHER SCNSER
DPB P2,LDPDEM## ;YES, SET THE NEW VALUE
MOVSI T2,L3LDMC## ;GET THE CHANGE BIT
IORM T2,LDBBY3##(U) ;LIGHT IT FOR RECINT
JRST CPOPJ1## ;NOW RETURN SUCCESS
;HERE TO DO 'TTY SLAVE'
TTCSLV: PUSH P,T1 ;SLAVE INDEX
JUMPL P1,TTCSL1 ;ALWAYS LEGAL TO CLEAR
MOVE T1,P1 ;COPY TARGET'S LINE POINTER
MOVE T1,LDBDCH##(T1) ;GET ITS BITS
TRNE T1,LDRPTY## ;IS IT A PTY?
JRST TPOPJ## ;YES, GIVE FAIL RETURN (ILLEGAL)
TTCSL1: PUSH P,U ;NO, CLEAR
MOVE U,P1 ;TARGET'S INPUT
TLZ U,400000 ;CLEAR POSSIBLE "NO" BIT
PUSHJ P,TSETBI## ;CLEAR INPUT BUFFER
POP P,U
POP P,T1 ;RESTORE INDEX
TLZN P1,400000 ;WANT TO CLEAR?
JRST TTCSET ;NO--LEAVE LDLCOM ALONE
MOVSI P2,LDLCOM## ;YES--SET LINE INTO
IORM P2,LDBDCH##(P1) ; COMMAND MODE
PJRST TTCCLR ;GO CLEAR SLAVE BIT
;HERE TO SET A RIGHT HALF WORD BIT
TTRSET: HLRZ P2,TTCDAT(T1)
JRST TTCST2
;HERE TO SET/CLEAR BITS IN THE LDB
TTCCLR: TLC P1,400000 ;COMPLEMENT THE SENSE
TTCSET: HLLZ P2,TTCDAT(T1) ;PICK UP FLAG
TTCST2: HLRZ T1,TTCWDD(T1) ;PICK UP OFFSET
ADD T1,P1 ;GET ACTUAL ADDRESS
TTCST1: TLZN P1,400000 ;WANT TO CLEAR?
SKIPA T2,[IORM P2,(T1)] ;NO--GO SET
MOVSI T2,(ANDCAM P2,(T1)) ;YES--CLEAR
TLZ T1,400000 ;CLEAR POSSIBLE "NO" BIT
XCT T2
PJRST CPOPJ1## ;SKIP RETURN
;HERE ON THE WORD NO
TTCNO: TLC P1,400000 ;COMPLEMENT FLAG
JRST CPOPJ1## ;SKIP RETURN
;HERE TO SEND AN ESCAPE SEQUENCE
TTCESC: PUSH P,T1 ;SAVE T1
MOVE U,P1 ;COPY LDB ADDRESS
TLZ U,400000 ;CLEAR POSSIBLE "NO" BIT
MOVEI T3,33 ;SEND OUT AN
PUSHJ P,COMTYO## ; ESCAPE
POP P,T1 ;RESTORE INDEX
HLRZ T3,TTCDAT(T1) ;ASSUME NORMAL COMMAND
SKIPGE P1 ;DID HE SAY NO?
HLRZ T3,TTCWDD(T1) ;YES--GET ALTERNATE BYTE
PUSHJ P,COMTYO## ;SEND TO TTY
JRST CPOPJ1## ;GOOD RETURN
;HERE TO PROCESS A NUMBER
TTCNUM: PUSH P,T1 ;SAVE INDEX
PUSHJ P,NUMARG ;GO READ A NUMBER
MOVEI T2,0 ;NONE THERE DO DEFAULT
POP P,T1 ;RESTORE INDEX
TTCNUP: LDB P2,[POINT 9,TTCDAT(T1),8] ;IS NUMBER BELOW
CAMGE T2,P2 ;THE MIN VALUE
POPJ P,0 ;YES
LDB P2,[POINT 9,TTCDAT(T1),17] ;IS NUMBER ABOVE
CAMLE T2,P2 ;THE MAX
POPJ P,0 ;YES -- ERROR
HLRZ T1,TTCWDD(T1) ;ADDRESS OF BYTE POINTER
TLZ P1,400000 ;CLEAR THE "CLEAR" FLAG
EXCH U,P1
DPB T2,(T1) ;STORE
EXCH U,P1
JRST CPOPJ1## ;SKIP RETURN
;HERE TO PROCESS SET TTY (NO) TAPE COMMAND
;ROUTINE REMEMBERS TO CLEAR L2RXON
TTCTAP: MOVEI T2,L2RXON## ;GET REAL STATUS BIT
MOVE T4,P1 ;COPY ADDRESS
TLZ T4,400000 ;CLEAR BIT
SKIPGE P1 ;IS THIS NO TAPE?
ANDCAM T2,LDBBY2##(T4) ;YES, CLEAR BIT
PJRST TTCSET ;THEN GO DO L2LTAP
;HERE TO PROCESS TTY TYPE COMMAND
TTCTYP: PUSHJ P,CTEXT1 ;GET TERMINAL TYPE
MOVE U,P1 ;GET LDB ADDRESS
TLZ U,400000 ;CLEAR POSSIBLE "NO" BIT
TTUTYP::MOVE T1,[-TTTWDN##,,CTTWDT##] ;AOBJN POINTER TO TYPES TABLE
PUSHJ P,FNDNAM ;FIND THE TERMINAL TYPE
POPJ P, ;FAT FINGERS
TTUTYX: AOS (P) ;SUCCESS
JRST SETTTC## ;SET DEFAULT CHARACTERSITICS
;HERE TO PROCESS A TTY EDITOR COMMAND
TTCEDT:
IFN FTMP,<
PUSHJ P,GETMM## ;MUST HAVE MM TO GET NZS CORE
JRST DLYCM1 ;DEFER TO NEXT CLOCK TICK IF CAN'T GET IT
> ;END FTMP
MOVE U,P1 ;GET THE TARGET LDB
PUSH P,P2 ;SAVE THE FUNCTION REGISTER
TLZE U,400000 ;DID HE TYPE 'NO'
TDZA P2,P2 ;YES, DON'T WANT IT THEN
MOVEI P2,1 ;ELSE WE WANT A BUFFER
PUSHJ P,SCNEDT## ;GO SET THE EDITOR
JRST TTCED1 ;RAN OUT OF MEMORY??
AOS -1(P) ;SUCCESS,,REMEMBER TO GIVE A SKIP RETURN
POP P,P2 ;ELSE RESTORE PROPER REGISTERS
IFE FTMP,<POPJ P,> ;RETURN
IFN FTMP,<PJRST GIVMM##> ;GIVE UP MM AND RETURN
TTCED1:
IFN FTMP,<PUSHJ P,GIVMM##> ;RETURN THE MM
JSP T1,COMER ;TYPE AN ERROR MESSAGE
ASCIZ /No buffer memory available/
SUBTTL FINISH AND CLOSE COMMANDS
; "FINISH DEVICE" - CLOSES,RELEASE AND DEASSIGNS DEVICE
;JOB MUST HAVE CORE
CFINI:: TDZA T1,T1 ;FINISH - SET T1=0
CLSCOM::SETO T1, ;CLOSE - T1=-1
MOVEM T1,.JDAT+JOBFDV## ;SAVE WHICH COMMAND IN JOBDAT
PUSHJ P,SETASA ;SET JS.ASA
PUSHJ P,CTXDEV ;GET DEVICE NAME
JUMPE T2,FINALL ;ALL DEVICES IF NO OTHER ARG
MOVE T1,T2 ;PUT NAME IN RIGHT AC
PUSH P,U ;SAVE ADDR OF TTY LDB
PUSHJ P,DEVSRG##
JRST NOTDV1 ;PRINT NOT A DEVICE
HRRM F,.JDAT+JOBFDV## ;STORE DDB ADR. IN JOB DATA AREA
POP P,U ;RESTORE ADDR OF TTY LDB
MOVEI T1,[ASCIZ /Not legal for disk-like devices
/]
MOVE T2,DEVMOD(F) ;IS IT A DISK?
TLNE T2,DVDSK
JRST ERRMES ;YES,MIGHT BE SEVERAL DDBS,DON'T TRY
PJSP T2,MSTART## ;SETUP MONITOR JOB AND RETURN
; RETURN HERE AT UUO LEVEL WHEN SCHEDULED
JSP T1,MONSTR## ;SETUP ACS,R,P
HRRZ F,.JDAT+JOBFDV## ; AND R
MOVEI T1,ASSPRG ;SEE IF
TDNN T1,DEVMOD(F) ; OPEN
JRST [SKIPGE .JDAT+JOBFDV## ;SEE IF FIN
JRST .+1 ;NO -- DO IT ANYWAY
TLZ M,NOPER!NOCRLF!TTYRNU
TLO M,CMWRQ ;FIX FLAGS FOR DEASSIGN
PUSHJ P,DEASI1 ;DEASSIGN
JRST CFINIX] ;STOP JOB
PUSHJ P,CFIN ;DO THE ACTUAL FIN (OR CLOSE)
JRST CFINIX ;STOP JOB SO HE CANNOT CONTINUE
;SUBROUTINE TO DO ACTUAL FIN
CFIN: PUSHJ P,SAVE1## ;SAVE P1
MOVEI P1,0 ;START AT CHANNEL 0
FDVI: PUSHJ P,NXTCH## ;GET NEXT DEVICE
JRST FDV3
HRRZ F,.JDAT+JOBFDV## ;GET DEV TO RELEASE
CAIE F,(T1) ;IS THIS WHAT WE WANT TO CLOSE?
JRST FDVI ;NO, CONTINUE
PUSHJ P,WAIT1## ;WAIT FOR INACTIVE DEVICE
MOVSI T2,DVTTY ;SET UP TTY BIT
SKIPN .USVRT ;IF VIRTUAL JOB
TDNE T2,DEVMOD(F) ;OR IF I/O TO A TTY
SETZM DEVBUF(F) ;THEN FORGET BUFFERS
SKIPN .USVRT ;IF VIRTUAL JOB
JRST FDV2 ;NOT THE CASE
MOVSI T3,0 ;SET UP
PUSHJ P,RTIEVM## ;TELL MONITOR ABOUT BUFFERS
MOVSI T3,0
PUSHJ P,RTOEVM##
FDV2: PUSH P,DEVMOD(F)
PUSH P,.JDAT+SGANEW
PUSH P,.JDAT+SGAHGH
MOVE T1,[1,,SGAHGH]
MOVSI T2,-1(P1)
HRRI T2,7
SKIPL .JDAT+JOBFDV##
HRRI T2,23
DMOVEM T1,.JDAT+SGANEW
FILOP. SGANEW,
JFCL
POP P,.JDAT+SGAHGH
POP P,.JDAT+SGANEW
POP P,T1
TRNN T1,ASSCON
POPJ P,
FDV3: MOVE J,.CPJOB## ;GET JOB NUMBER
SKIPL F,.JDAT+JOBFDV## ;RESET F, SKIP IF NOT FIN
PUSHJ P,DEASG ;DEASSIGN DEVICE IF FIN
POPJ P, ;IGNORE IF NOT ASSIGNED BY CONSOLE
POPJ P,
;HERE TO FIN ALL DEVICES JOB OWNS
FINALL: PJSP T2,MSTART## ;SETUP MONITOR JOB, RETURN AT UUO LEVEL
JSP T1,MONSTR## ;SETUP R, R,P
HLRZ F,DEVLST## ;START OF DDB CHAIN
FINAL1: LDB T1,PJOBN## ;JOB WHICH OWNS DEVICE
HRRM F,.JDAT+JOBFDV## ;SAVE DDB ADDR IN CASE CFIN IS CALLED
CAMN T1,.CPJOB## ;THIS JOB OWN DEVICE?
PUSHJ P,CFIN ;YES, FIN (OR CLOSE) IT
PUSHJ P,NXDDB## ;STEP TO NEXT DDB
SKIPE F ;DONE IF 0
JRST FINAL1 ;TEST NEXT
CFINIX: HLLZS JBTDDB##(J) ;NOT IN ANY I/O WAIT ANYMORE
PUSHJ P,CLRASA ;CLEAR JS.ASA
PUSHJ P,TTYFNU## ;DONE. FIND TTY LINE FOR JOB
PJRST HOLD## ;STOP JOB
;"RESOURCES" - PRINT OUT AVAILABLE DEVICES AND FREE BLOCKS ON THE DISK
FREDEV::PUSHJ P,SAVE2## ;SAVE P1=P2
PUSHJ P,DSKRES## ;PRINT DISK INFO
HLRZ P1,DEVLST## ;GET DDB POINTER
MOVEI P2,0 ;SET DEVICE NAME 0 FOR FIRST COMPARE
LOP01: MOVE T1,DEVMOD(P1) ;DEVICE CHARACTERISTICS
TRNN T1,ASSCON!ASSPRG ;DEVICE ASSIGNED BY CONSOLE OR PROGRAM?
TLNE T1,DVTTY!DVDSK ;NO, IS IT A TTY OR DSK?
JRST LOP02 ;YES DO NOT PRINT
HLRZ T1,DEVNAM(P1) ;GET NAME OF NEXT DEVICE IN CHAIN
SKIPE DEVNAM(P1) ;DON'T PRINT COMMA IF NO NAME
CAIN T1,(SIXBIT /PTY/) ;A PSEUDO TELETYPE?
JRST LOP02 ;YES. DONT MENTION IT.
JUMPE P2,LOP01B ;SUPPRESS LEADING COMMA
PUSHJ P,PRCOM ;PRINT COMMA
LOP01B: MOVS P3,DEVNAM(P1) ;GET DEVICE NAME
HLLZ T2,P3 ;ASSUME SAME TYPE AS LAST ONE, PRINT
; ONLY RH OF NAME (UNIT NUMBER)
CAIN P2,0(P3) ;IS IT REALLY THE SAME?
JRST LOP01A ;YES. PRINT THE UNIT NUMBER.
MOVS T2,P3 ;NO. MUST PRINT WHOLE NAME,
HRRZ P2,P3 ; AND GET THE NEW DEVICE IN FLAG AC.
LOP01A: PUSHJ P,PRNAME ;AS BEING FREE
LOP02: HLRZ P1,DEVSER(P1) ;GET NEXT DEVICE IN CHAIN
JUMPN P1,LOP01 ;IS THERE ONE?
MOVEI P1,.C0CDB## ;POINT AT THE FIRST ONE
SETO P2, ;INDICATE FIRST CPU
LOP03: SKIPGE .CPRUN##-.CPCDB##(P1) ;CAN THIS CPU RUN JOBS?
JRST LOP04 ;NO, DON'T PRINT IT
PUSHJ P,PRCOM ;PRINT A COMMA
MOVE T2,.CPLOG##-.CPCDB##(P1) ;GET CPU NAME
AOSE P2 ;UNLESS FIRST TIME,
HRLZS T2 ; LEAVE OFF THE "CPU" PART
PUSHJ P,PRNAME ;PRINT IT
LOP04: HLRZ P1,.CPCDB##-.CPCDB##(P1) ;GET LINK TO NEXT CDB
JUMPN P1,LOP03 ;LOOP BACK IF MORE
JRST CRLF ;NO. DONE. PRINT CR, LF AND THEN POPJ
SUBTTL SUBROUTINES -- COMMAND SETUP
;ROUTINE TO CHECK FOR ACTIVE DEVICES
;NEVER GET HERE DURING SWAP IN OR OUT
;SINCE COMMAND TABLE SHOULD HAVE NOTRAN BIT ON
RUNCHK: JUMPE R,RUNCH1 ;DOES JOB HAVE CORE IN MEMORY?
IFN FTMP&FTKL10,<
PUSHJ P,SBCCSH## ;MAKE SURE CPU1'S CACHE HAS BEEN
; SWEPT FOR THIS JOB
>
S0PSHJ ANYACT## ;YES, ARE DEVICES ACTIVE?
JRST RUNCK2 ;YES, DELAY COMMAND.
RUNCH1: HRRZ F,LDBDDB##(U) ;RESTORE F
POPJ P,
RUNCK2: POP P,(P) ;POP OFF RETURN ADDRESS (WE AREN'T GOING TO RETURN)
JRST CHKDLY ; AND DELAY THE COMMAND
;ROUTINE TO DELAY A COMMAND
;DELAYS COMMAND TO BE EXECUTED WHEN JOB IN CORE MEMORY
;AND CAUSES JOB TO BE SWAPPED IN(COMMAND WAIT BIT IS SET IN JBTSTS)
;AND POPS LEVEL UP ONE.
DLYCM:: PUSHJ P,DLYCOM## ;SET COMMAND WAIT BIT IN JOB STATUS AND PUT
; JOB IN COMMAND WAIT QUEUE
; SO JOB IS NOT RUNNABLE ANY MORE
;ROUTINE TO DELAY A COMMAND IF A SWAP OUT OR IN IS IN PROGRESS
;DIFFERS FROM DLYCM IN THAT JOB IS NOT MADE TO BE SWAPPED IN
;REQUIRED FOR DELAYING COMMAND IF SYSTEM
;TAPE USER TYPES ^C (HALT COMMAND)
DLYCM1::AOS LINSAV## ;INCR. COMMAND POINTER SO NEXT CALL
; BY COMMAND DECODER CALL START SCANNING
; WITH LINE AFTER DELAYED COMMAND.
DLYCM2: MOVE P,.CPISF## ;GET INITIAL PDL POINTER BACK
IFN FTRSP,<
TLNE M,TTYRNC!TTYRNU ;WILL THIS COMMAND CAUSE JOB TO BE RUN?
PUSHJ P,SETRSP## ; RESPONSE, IF NOT ALREADY SET
>
NTGIVE ;GIVE UP THE INTERLOCK IF IT WAS A NETWORK COMMAND
JRST T2POPJ## ;TTY LINE #
;THEN EXIT FROM COMMAND DECODER.
ABORTC::SKIPN .CPISF## ;AT UUO LEVEL?
POPJ P, ;YES, JUST RETURN
MOVE P,.CPISF## ;HERE TO GET OUT OF A COMMAND (CLEAN'S UP THE STACK)
XJRST [MCSEC1+COMRET] ;GO TELL SCNSER THE COMMAND IS DONE
SUBTTL SUBROUTINES -- GET A WORD
;ROUTINE TO RETURN NEXT ALPHANUMERIC STRING
; IN COMMAND LINE (SIXBIT)
;CALL: PUSHJ P, CTEXT
; SIXBIT STRING RETURN LEFT JUSTIFIED IN AC T2
CTEXT:: PUSHJ P,COMTYS ;SKIP CHAR
CTEXT1::PUSHJ P,SKIPS1 ;SKIP LEAD SPACES,TABS,NULLS AND CLEAR T2
POPJ P,0 ;NOTHING THERE.
PUSHJ P,SAVE1## ;SAVE P1
SKIPA P1,[POINT 6,T2]
CTEX0: PUSHJ P,COMTYS ;ROUTINE IN SCNSER TO PICK UP CHAR.
PUSHJ P,CTEX ;IS IT ALPHANUMERIC
POPJ P,0 ;NO
TRC T3,40 ;CONVERT TO SIXBIT
TLNE P1,770000 ;SIX CHARS YET?
IDPB T3,P1 ;NO. BUILD WORD
JRST CTEX0 ;LOOP FOR MORE
;SCAN FOR ALPHANUMERIC CHAR IN T3
CTEX: CAIL T3, "0"
CAILE T3, "Z" ;LETTERS ARE LARGER THAN NOS.
POPJ P,0 ;NEITHER
CAILE T3, "9"
CAIL T3, "A"
AOS (P) ;LETTER OR NUMBER RETURN
POPJ P,0 ;NOT-LETTER/NUMBER RETURN
CTXDEV::PUSHJ P,CTEXT1 ;GET A WORD
CAIN T3,":" ;AND IF TERM IS A COLON,
PUSHJ P,COMTYS ;DISCARD IT
POPJ P,0 ;RETURN FROM CTXDEV
SUBTTL SUBROUTINES -- GET CHARACTER
;ROUTINE TO IGNORE LEADING SPACES, TABS,
;ALSO CLEARS T2
;CALL: PUSHJ P,SKIPS1 ;TO CONSIDER CURRENT CHARACTER
; PUSHJ P,SKIPS ;TO DISCARD CURRENT CHARACTER
;NON-SKIP RETURN MEANS END OF LINE
;SKIP RETURN MEANS SOMETHING THERE, IN T3 AND .CPMCH
;ROUTINE TO IGNORE LEADING SPACES AND TABS. ALSO, CLEARS T2
;FOR USE BY ANYRIN AND CTEXT
SKIPS:: PUSHJ P,COMTYS ;DISCARD CURRENT CHARACTER
SKIPS1::MOVEI T2,0 ;CLEAR ANSWER FOR NUMERIC AND TEXT INPUTS
PUSHJ P,CTIGLC## ;GET LAST CHAR SCANNED
CAIE T3,11 ;TAB?
CAIN T3,40 ;OR SPACE?
JRST SKIPS ;YES. DISCARD IT
CAIL T3,40 ;BREAK CHARACTER?
AOS 0(P) ;NO. SKIP RETURN
POPJ P,0 ;RETURN.
;COMTYS - ROUTINE TO READ COMMAND AND STOP ON COMMENT
;CALL: PUSHJ P,COMTYS
;RETURN WITH CHARACTER IN T3 (12 IF ; OR !)
COMTYS::PUSHJ P,COMTYI## ;GET CHARACTER
CAIL T3,"A"+40 ;LOWER CASE?
CAILE T3,"Z"+40
SKIPA
TRZ T3,40 ;YES, CONVERT TO UPPER CASE
CAIE T3,"!" ;SEE IF EXCLAMATION
CAIN T3,";" ;SEE IF SEMI-COLON
MOVEI T3,12 ;YES, CHANGE TO LINEFEED
PUSHJ P,CTISLC## ;SAVE AS LAST CHAR SCANNED
POPJ P,
SUBTTL SUBROUTINES -- COMMAND DECODER TYPE OUT ROUTINES
;ROUTINE TO APPEND A "?" TO INPUT STRING AND SET AS OUTPUT
;CALLED FROM OCTIN, RETURNS TO SECOND LEVEL ON PDL
;CALL: MOVE T1, BYTE POINTER TO LAST CHAR. IN INPUT STRING
; PUSHJ P, COMERA
COMERP::POP P,0(P) ;REMOVE SUB. RETURN BEFORE CALLING COMERA
COMERA::PUSHJ P,COMTYI## ;SKIP ONE MORE CHARACTER
;ROUTINE TO TYPE ALL OF A COMMAND ACCEPTED, FOLLOWED BY
;A QUESTION MARK
;CALL: PUSHJ P, COMERR
;COMMAND NOT IN COMMAND DIRECTORY
NOCOM::
COMERR::PUSH P,T2
PUSHJ P,CTIGBP## ;GET THE INPUT BYTE POINTER
PUSH P,T1 ;SAVE ERROR POSITION ON THE STACK
PUSHJ P,TRESCN## ;BACK UP TO START OF COMMAND
PUSHJ P,PRQM ;TYPE ? FOR BATCH
COMERL: PUSHJ P,COMTYI## ;GET A CHAR FROM COMMAND
CAIN T3,3 ;^C?
JRST COMER1 ;BETTER LEAVE OR KAF
PUSHJ P,CTIGBP## ;GET THE BYTE POINTER
SKIPE T1 ; IF IT'S NULL, WE'RE DONE
CAMN T1,0(P) ; ..
JRST COMER1 ;YES
PUSHJ P,USEARO## ;NO. TYPE CHAR, IN ARROW MODE
CAIE T3,12
JRST COMERL ;LOOP FOR MORE
COMER1: POP P,T1 ;REMOVE OLD POSITION FROM STACK
POP P,T2
PUSHJ P,PRQM ;APPEND ? TO ERRONEOUS WORD
TLO M,ERRFLG ;SET ERROR FLAG
PUSHJ P,CRLF ;ADD CRLF
PJRST ABORTC ;TERMINATE COMMAND
;ROUTINE TO PRINT ?DEVICE NAME
PRNAMQ: PUSHJ P,PRQM
TLO M,ERRFLG ;SET ERROR FLAG
PJRST PRNAME
; ROUTINE TO PRINT A CRLF, THEN AN ERROR MESSAGE
ERRCRL::PUSH P,T1 ;SAVE ADDRESS OF TEXT
PUSHJ P,CRLF ;TYPE A CRLF
POP P,T1 ;RESTORE TEXT
; PJRST ERRMES ;TYPE "?ERROR-TEXT" AND RETURN
;ROUTINE TO PRINT A COMMAND ERROR MESSAGE
;SAME CALL AS CONMES
ERRMES::PUSHJ P,PRQM
ERRMSN: TLO M,ERRFLG ;INDICATE AN ERROR
PUSHJ P,CONMES ;PRINT MESSAGE
MOVEI J,0 ;CLEAR JOB NUMBER TO INDICATE ERROR
PJRST CRLF ;FALL INTO CRLF
;ROUTINE TO PRINT "TOO FEW ARGUMENTS"
;CALL: MOVE U,BYTE POINTER
; PUSHJ P,NOTENF
NOTENP::POP P,(P) ;REMOVE SUBROUTINE CALL BEFORE CALLING NOTENF
NOTENF::MOVEI T1,[ASCIZ /Too few arguments
/]
PUSHJ P,ERRMES ;REPORT THE ERROR
PJRST ABORTC ;DIE
;ROUTINE TO PRINT A MONITOR DOT AT LEFT MARGIN
;CALL: PUSHJ P,PRDOTC
PRDOTM::
IFN FTNET,<
SE1ENT ;NEED TO ACCESS THE LDB
SKIPGE LDBREM##(U) ;IF SET HOST IN PROGRESS,
POPJ P, ;PUNT THE TYPEOUT
> ;END IFN FTNET
TLNN M,NOFLM ;UNLESS REQUESTED OTHERWISE,
PRDOTC::PUSHJ P,COMFLM## ;FORCE LEFT MARGIN IN SCNSER
PJRST PRPER ;FALL INTO PRPER
SUBTTL SUBROUTINES -- GENERAL TYPE OUT ROUTINES
;ROUTINE TO PRINT CARRIAGE RETURN-LINE-FEED
;CALL: MOVE U,LDB ADDRESS OF TTY
; PUSHJ P,CRLF
PCRLF::! ;A ROSE BY ANOTHER NAME ...
CRLF:: MOVEI T1,[ASCIZ /
/]
; PJRST CONMES ;FALL INTO CONMES
;ROUTINE TO MOVE ASCIZ CHAR. STRING TO CONSOLE OUTPUT BUFFER
; CALL: MOVE U,LDB ADDRESS OF TTY
; MOVEI T1,ADDRESS OF ASCIZ MESSAGE
; PUSHJ P,CONMES
;STRING TERMINATED BY NULL
CONMES::HRLI T1,(POINT 7) ;FORM ASCIZ BYTE POINTER
PUSH P,T1 ;SAVE BYTE POINTER
CON0: ILDB T3,(P) ;GET NEXT CHAR.
JUMPE T3,TPOPJ## ;IS IT NULL?(IF YES, DO POP T1, POPJ)
PUSHJ P,COMTYO## ;NO, STORE TTY OUTPUT BUFFER
JRST CON0 ;KEEP GOING
;ROUTINE TO PRINT INLINE ASCIZ MESSAGE
;CALL: PUSHJ P,INLMES
; ASCIZ /THE MESSAGE/
;RETURN TO NEXT LOC AFTER MESSAGE
INLMES::POP P,T1 ;SETUP PRINT ADRESS FOR CONMES
PUSHJ P,CONMES
SSX T1,IFIW ;RETURN IN RIGHT SECTION
JRST 1(T1) ;RETURN TO NEXT LOC AFTER MESSAGE
;ROUTINE TO TYPE COMMA
;PRESERVES T1
PRCOM:: MOVEI T3,","
PJRST PRCHR
;SUBROUTINE TO PRINT 3 SPACES
PR3SPC::PJSP T1,CONMES
ASCIZ / /
;SUBROUTINE TO PRINT A SPACE
PRSPC:: PJSP T1,CONMES
ASCIZ / /
;SUBROUTINE TO PRINT A PLUS
PRTPLS::PJSP T1,CONMES
ASCIZ /+/
;ROUTINE TO PRINT A PERIOD
;CALL: PUSHJ P,PRPER
PRPER:: JSP T1,CONMES
ASCIZ /./
;ROUTINE TO PRINT A SLASH
PRSLSH::JSP T1,CONMES
ASCIZ ./.
;ROUTINE TO APPEND ? TO ERROR MESSAGE
;CALL PUSHJ P,PRQM
; RETURN
PRQM:: MOVEI T3,"?"
PRCHR:: PUSH P,T1
PUSHJ P,COMTYO##
PJRST TPOPJ##
;ROUTINE TO TYPE A NUMBER AS HALFWORDS SEPARATED BY COMMAS.
;CALL: MOVE T1,NUMBER
; PUSHJ P,HWDPNT
; RETURN
HWDPNT::PUSH P,T1 ;SAVE T1 FOR RH
HLRZS T1 ;KEEP JUST LH
PUSHJ P,OCTPNT ;PRINT AS 6 OCTAL DIGITS
PUSHJ P,INLMES ;PRINT THE TWO COMMAS
ASCIZ /,,/ ;...
POP P,T1 ;RESTORE T1 FOR RH
PJRST OCTPNT ;PRINT RH AND RETURN
;ROUTINE TO TYPE A NUMBER AS HALFWORDS SEPARATED BY COMMAS.
;DIFFERES FROM HWDPNT IN THAT THE NUMBERS ARE NOT ZERO FILLED.
;CALL: MOVE T1,NUMBER
; PUSHJ P,PRTXWD
; RETURN
PRTXWD::TLNN T1,-1 ;ANYTHING IN LH?
PJRST PRTDI8 ;NO, THEN JUST LET PRTDI8 DO ITS THING
PUSH P,T1 ;SAVE T1
HLRZS T1 ;GET LEFT HALF
PUSHJ P,PRTDI8 ;PRINT IT
PUSHJ P,INLMES ;ADD SOME NOISE
ASCIZ /,,/ ;...
POP P,T1 ;RESTORE T1
HRRZS T1 ;KEEP JUST RH
PJRST PRTDI8 ;PRINT RH AND RETURN
;ROUTINE TO PRINT 6 DIGIT OCTAL NUMBER
;CALL: MOVEI LINE,LINE DATA BLOCK ADDRESS FOR TTY
; HRR T1, OCTAL NUMBER
; PUSHJ P,OCTPNT
; RETURN T2,PRESERVED,T1 DESTROYED
OCTPNT::HRLZ T1,T1 ;MOVE TO LH FOR ROTATING
TRO T1,700000 ;SETUP AN END FLAG
OCTP1: ROT T1,3 ;GET NEXT OCTAL DIGIT
TLNN T1,777777 ;WAS THAT FLAG?
POPJ P, ;YES, DO NOT PRINT IT
PUSH P,T1 ;SAVE T1 OVER I/O ROUTINE
PUSHJ P,PRTNUM ;NO, PRINT OCTAL DIGIT
POP P,T1 ;RESTORE T1
HRRI T1,0 ;CLEAR RH
JRST OCTP1 ;GET NEXT OCTAL DIGIT
;ROUTINE TO ADD 1 TO T1 AND PRINT DECIMAL
;SAME CALL AS OCTPNT
DECP1:: AOJA T1,RADX10 ;ADD 1 AND GO PRINT
;ROUTINE TO PRINT DECIMAL
;CALL: SAME AS OCTPNT
;T2: PRESERVED
RADX10::PUSH P,T2 ;SAVE T2
PUSHJ P,PRTDIG ;PRINT DECIMAL DIGITS
PJRST T2POPJ## ;RESTORE T2 AND RETURN
;RECURSIVE DECIMAL PRINT ROUTINE
;CALL: MOVE T1,DECIMAL NO.
; PUSHJ P,PRTDIG
PRTDIG::
IFN FTXMON,<
PUSHJ P,SSEC0## ;RUN IN SECTION 0
>
PRTDGX: IDIVI T1,12 ;DIVIDE BY 10
HRLM T2,(P) ;RT ON PD LIST
JUMPE T1,.+2 ;FINISHED?
PUSHJ P,PRTDGX ;NO, CALL S OR F
PRTNMM: HLRZ T1,(P) ;YES, GET LAST NUMBER
PRTNUM: MOVEI T3,"0"(T1) ;CONVERT TO ASCII
PJRST COMTYO## ;AND TYPE IT OUT
;RECURSIVE OCTAL PRINT ROUTINE
;CALL: SAME AS PRTDIG
PRTDI8::
IFN FTXMON,<
PUSHJ P,SSEC0## ;RUN IN SECTION 0
>
PRTD8X: IDIVI T1,10 ;DIVIDE BY 8
HRLM T2,(P) ;PUT ON STACK
JUMPE T1,PRTNMM ;FINISHED?
PUSHJ P,PRTD8X ;NO - LOOP
PJRST PRTNMM ;OUTPUT
;SUBROUTINE TO PRINT 22 BIT OCTAL ADDRESS
;CALL: MOVE T1,22 BIT ADDRESS
; PUSHJ P,PRT22A
; ALWAYS RETURN
PRT22A::PUSH P,T1 ;SAVE 22 BIT ADDRESS
HLRZ T1,(P) ;GET HIGH ORDER HALF
JUMPE T1,PRT22B ;IS IT 0 (USUALLY EXCEPT BIG SYSTEMS)
PUSHJ P,PRTDI8 ;NO, PRINT AS LEADING 0 SUPPRESSED OCTAL
PRT22B: POP P,T1 ;GET LOW ORDER HALF
PJRST OCTPNT ;PRINT AS NON ZERO SUPPRESSED OCTAL (RH ONLY)
;ROUTINE TO PRINT SIXBIT NAME
;CALL MOVE U,ASCII OUTPUT BYTE POINTER
; MOVE T2,NAME
; PUSHJ P,PRNAME
PRNAM1::MOVEI T1,0
LSHC T1,6 ;SHIFT IN NEXT CHAR.
MOVEI T3," "-' '(T1) ;ASCII VERSION INTO CHREC FOR OUTCHS
PUSHJ P,COMTYO## ;OUTPUT CHARACTER
PRNAME::JUMPE T2,CPOPJ##
JRST PRNAM1
;ROUTINE TO PRINT SIXBIT WORD WITH TRAILING SPACES
;CALL: SAME AS PRNAME.
PRSIXB::MOVEI T3,6 ;NUMBER OF CHARACTERS
PUSH P,T3 ;SAVE T3
PRSIX0: SETZ T3, ;CLEAR RECIPIENT
ROTC T2,6 ;SHIFT IN NEXT CHARACTER
ADDI T3," "-' ' ;CONVERT TO ASCII
PUSHJ P,COMTYO## ;TYPE IT OUT
SOSLE (P) ;MORE TO DO?
JRST PRSIX0 ;YES, LOOP
JRST T3POPJ## ;RESTORE T3 AND RETURN
SUBTTL SUBROUTINES -- COMMAND INPUT
;ROUTINE TO RETURN HIGHEST RELATIVE ADDRESS SPECIFIED BY
; THE USER'S CORE ARGEMENT
;CALLING SEQUENCE:
; PUSHJ P,CORARG
; RETURN HERE IF NO ARGUMENT WAS SPECIFIED
; RETURN HERE - T1=HIGHEST RELATIVE ADDRESS REQUESTED
;NEVER RETURNS IF ARGUMENT IS ILLEGAL
CORARG::PUSHJ P,SKIPS1 ;SKIP LEADING BLANKS, ETC.
CORAR1: POPJ P,K2WLSH ;NO ARGUMENT SPECIFIED
CAIE T3,"K" ;DON'T ALLOW "P" OR "K"
CAIN T3,"P" ; WITHOUT A PRECEEDING #
JRST COMERP ; SINCE AMBIGUOUS
PUSHJ P,DECIN1 ;GET THE ARGUMENT
POPJ P, ;NULL RETURN
JRST CORAR2 ;SEE IF "P" OR "K"
PUSHJ P,SGSEND ;EOL?
CAIN T3,"/" ;NO, IS WHAT IS LEFT SWITCHES?
TDZA T3,T3 ;YES TO EITHER IS OK, SET E.O. LINE
JRST COMERP ;NO, BAD DELIMITER
LSH T2,K2WLSH
CAILE T3,40 ;AN ARG. WAS TYPED, DELIMITER OKAY?
JRST COMERP ;BAD DELIMITER
JRST CORAR3
CORAR2: CAIE T3,"K" ;CORE ARGUMENT IN # OF K?
CAIN T3,"P" ; OR NUMBER OR PAGES
SKIPA T1,CORAR1
JRST COMERP ;NO, DON'T ALLOW A,B,C, ETC.
CAIN T3,"P" ;DID USER TYPE "P"?
SOS T1 ;YES
LSH T2,(T1) ;CONVERT TO WORDS
PUSHJ P,COMTYS ;DISCARD "P"OR"K"
CORAR3: SOSL T1,T2 ;CONVERT TO HIGHEST RELATIVE ADDR.
JRST CPOPJ1## ;GIVE ARG FOUND RETURN
AOJA T1,CPOPJ1## ;MAKE ZERO BACK INTO ZERO
;SUBROUTINE TO PRINT "P" OR "K" AFTER A CORE TYPE OUT
;CALLING SEQUENCE:
; PUSHJ P,PRPORK
; ALWAYS RETURN HERE
PRPORK: MOVEI T3,"P" ;TELL NUMBER OF PAGES
PJRST PRCHR ;PRINT "P"
;SUBROUTINE TO READ A NUMBER IN THE FORM X,,Y. RETURNS CPOPJ IF NO NUMBER
; WAS TYPED, 0 IN T2, CPOPJ1 IF A NUMBER WITH SEVEN OR MORE DIGITS (IGNORING
; LEADING ZEROS) WAS TYPED, A NUMBER OF THE FORM X,,Y WAS TYPED, OR A NUMBER
; X <BLANK> Y WAS TYPED. CALL OCTPAR IF AN 18 BIT NUMBER WILL DO. CALL OCTPRR
; IF A 36 BIT NUMBER IS REQUIRED. DOESN'T RETURN IF REQUIREMENTS NOT MET OR
; INVALID NUMBER WAS TYPED.
OCTPAR: PUSHJ P,OCTPA0 ;DO REAL WORK
POPJ P, ;NOTHING FOUND
JRST COMERP ;ERROR
JRST CPOPJ1## ;GOOD RETURN
OCTPRR: PUSHJ P,OCTPA0 ;DO REAL WORK
POPJ P, ;NOTHING FOUND
JRST COMERP ;ERROR
JRST CPOPJ1## ;GOOD RETURN
OCTPA0: TDZA S,S ;18 BIT NUMBER IS OK
OCTPR0: MOVEI S,1 ;INDICATE 36 BIT QUANITY REQUIRED
PUSHJ P,OCTIN1 ;READ A NUMBER
POPJ P, ;NONE THERE, MAY BE OK
JRST CPOPJ1## ;ILLEGAL CHARACTER
TLNE T2,-1 ;IF 7 OR MORE DIGITS, ITS A 36 BIT NUMBER
JRST CPOPJ2## ;GO USE THE NUMBER
HRL S,T2 ;SAVE HIGH 18 BITS OF NUMBER
CAIE T3,"," ;A COMMA TYPED? X,,Y IS A LEGAL CONSTRUCT
JRST OCTPA1 ;NO, SPACE IS ALSO LEGAL
PUSHJ P,SKIPS ;SKIP THE COMMA AND GET THE NEXT CHARACTER
JRST CPOPJ1## ;END OF LINE IS ILLEGAL
CAIE T3,"," ;IF THERE WAS ONE, THERE MUST BE TWO
JRST CPOPJ1## ;NOPE
PUSHJ P,COMTYS ;SKIP OVER THE COMMA
HRRI S,2 ;ALLOW X,,<CRLF> TO MEAN X,,0
OCTPA1: PUSHJ P,OCTARG ;READ ANOTHER NUMBER
JRST [TRZE S,2 ;SEEN ,,?
JRST OCTPA2 ;YES, TREAT ,, <CRLF> AS 0
TRZE S,1 ;A FULL WORD REQUIRED?
JRST CPOPJ1## ;YES, LESS THAN A FULL WORD IS ILLEGAL
HLRZS S ;18 BIT NUMBER, PUT IT IN THE RIGHT HALF
JRST OCTPA2] ;AND RETURN THAT
TLNE T2,-1 ;MORE THAN A HALFWORD IS ILLEGAL HERE
JRST CPOPJ1## ;TELL THE USER THE ERROR OF HIS WAYS
HRR S,T2 ;36 BIT NUMBER
OCTPA2: MOVE T2,S ;WHERE THE CALLER WANTS THE ANSWER
JRST CPOPJ2## ;NUMBER READ RETURN
;ROUTINE TO DEASSIGN A DEVICE EXCEPT CONTROLLING TTY
;CALL: MOVE F, DEVICE DATA BLOCK
; MOVE J, JOB NUMBER
; PUSHJ P, DEASG
; ERROR NOT PREVIOUSLY ASSIGNED
; OK RETURN WITH DEVICE DEASSIGNED, EXCEPT CONTROLLING TELETYPE (LOGICAL NAME CLEARED)
DEASG: SKIPN DEVCHR(F) ;PROTOTYPE SPOOL DDB?
JRST CPOPJ1## ;YES
LDB T1,PJOBN## ;WAS DEVICE ASSIGNED TO THIS JOB?
CAME T1,J
POPJ P, ;NO, RETURN
DEASG1::PUSH P,J ;SAVE JOB NUMBER
MOVSI T2,DVDIRI ;CLEAR DIRECTORY IN CORE BIT
ANDCAB T2,DEVMOD(F) ;SET DEVICE CHARACTERISTICS FOR TEST
; AND ASGHGH
SETZM DEVLOG(F) ;CLEAR LOGICAL NAME
TLNE T2,TTYATC ;CONTROLLING TTY?
JRST IPOPJ1## ;YES, CAN'T DEASSIGN THAT!
TRNE T2,ASSCON ;IS DEVICE ASSIGNED BY CONSOLE?
AOS -1(P) ;YES, DO OK RETURN
PUSHJ P,ASGHGH## ;IF DTA OR MTA, CLEAR ANY HIGH SEGMENT NAMES
; FROM THIS DEVICE SO NO NEW SHARING
; DEVMOD SETUP IN T2 ON CALL
MOVEI T2,ASSCON ;SETUP ASSIGNED BY CONSOLE BIT FOR RELEA6
PUSHJ P,RELEA6## ;CLEAR JOB NO. IN DDB IF DDB NOT NEEDED
PUSHJ P,TTYKLQ## ;BE SURE TO CLEAN UP ASSIGNED TTY'S
JRST IPOPJ## ;RESTORE JOB NUMBER AND RETURN
;DEASTY--ROUTINE TO DEASSIGN ALL DEVICES EXCEPT CONTROLLING (ATTACHED) TTY
;CALL: MOVE J, JOB NUMBER
; PUSHJ P, DEASTY
DEASTY: PUSH P,F ;SAVE TTY DDB ADDRESS
HLRZ F,DEVLST## ;SEARCH ALL DDB'S
DEA1: PUSHJ P,DEASG ;TRY TO DEASSIGN IT
JFCL ;IGNORE IF CAN'T
PUSHJ P,NXDDB##
JUMPE F,FPOPJ## ;RESTORE TTY DDB AND EXIT
JRST DEA1 ;TRY NEXT
;SUBROUTINE TO READ A DECIMAL NUMBER. THIS ROUTINE DIFFERS FROM
; DECIN IN THAT IF THERE IS NO NUMBER TO READ THE CURSOR
; IS NOT MOVED.
;CALL WITH:
; PUSHJ P,NUMARG
; RETURN HERE IF NO NUMBER (NOTHING CHANGED)
; RETURN HERE NUMBER IN T2
;
NUMARG: PUSHJ P,CTIGBP## ;GET THE BYTE POINTER
PUSH P,T1 ; AND SAVE THAT
PUSHJ P,CTIGLC## ;GET THE "LAST CHAR"
PUSH P,T3 ; AND SAVE THAT TOO.
PUSHJ P,DECIN1 ;READ THE NUMBER
JRST NUMAR1 ;NO ARGUMENT
JRST NUMAR1 ;ILLEGAL CHARACTER
NUMAR0: SUB P,[2,,2] ;REMOVE JUNK FROM STACK
JRST CPOPJ1## ;GOOD RETURN
NUMAR1: POP P,T3 ;GET CHAR TO RETURN
EXCH T1,(P) ;SAVE T1, GET BYTE POINTER
PUSHJ P,CTISBP## ;STORE THE BYTE POINTER
PUSHJ P,CTISLC## ; AND THE "LAST CHAR READ"
JRST TPOPJ## ;RESTORE T1 AND RETURN
;SUBROUTINE TO READ A OCTAL NUMBER. THIS ROUTINE DIFFERS FROM
; NUMARG ONLY IN THE INPUT RADIX.
;CALL WITH:
; PUSHJ P,OCTARG
; RETURN HERE IF NO NUMBER (NOTHING CHANGED)
; RETURN HERE NUMBER IN T2
;
OCTARG: PUSHJ P,CTIGBP## ;GET THE BYTE POINTER
PUSH P,T1 ; AND SAVE THAT
PUSHJ P,CTIGLC## ;GET THE "LAST CHAR"
PUSH P,T3 ; AND SAVE THAT TOO.
PUSHJ P,OCTIN1 ;READ THE NUMBER
JRST NUMAR1 ;NO ARGUMENT
JRST NUMAR1 ;ILLEGAL CHARACTER
JRST NUMAR0 ;GOT IT
;SUBROUTINE TO READ A POTENTIALLY 30 BIT OCTAL ADDRESS
;CALL WITH:
; PUSHJ P,OCTPRG
; RETURN HERE IF NO NUMBER WAS TYPED (NOTHING CHANGED)
; RETURNS HERE WITH NUMBER IN T2
;
OCTPRG: PUSHJ P,CTIGBP## ;GET THE BYTE POINTER
PUSH P,T1 ; AND SAVE THAT
PUSHJ P,CTIGLC## ;GET THE "LAST CHAR"
PUSH P,T3 ; AND SAVE THAT TOO.
PUSHJ P,OCTPA0 ;READ THE NUMBER
JRST NUMAR1 ;NO ARGUMENT
JRST NUMAR1 ;ILLEGAL CHARACTER
JRST NUMAR0 ;GOT IT
;SUBROUTINE TO READ AN ARGUMENT, CALL FNDNAM
;IF NOT FOUND BY FNDNAM CURSOR IS NOT MOVED
;CALL WITH T1=AOBJN WORD FOR TABLE
;RETURNS SKIP IF FOUND BY FNDNAM, T1=INDEX
;RETURNS NON-SKIP IF NOT FOUND (NOTHING CHANGED)
TXTARG::PUSH P,T1 ;SAVE T1
PUSHJ P,CTIGBP## ;GET THE BYTE POINTER IN T1
PUSHJ P,CTIGLC## ; THE LAST CHAR IN T3
EXCH T1,(P) ;SAVE BYTE POINTER, RESTORE T1
PUSH P,T3 ;SAVE THE LAST CHAR.
PUSH P,T1 ;SAVE AOBJN WORD
PUSHJ P,CTEXT1 ;GET THE ARGUMENT
POP P,T1
JUMPE T2,NUMAR1
PUSHJ P,FNDNAM ;IN TABLE?
JRST NUMAR1 ;NO
JRST NUMAR0 ;YES, CLEAN UP STACK AND GIVE FOUND RETURN
;ROUTINES TO READ NUMBERS FROM COMMAND STRING
;CALL: MOVE P1,DESIRED INPUT RADIX
; PUSHJ P, ANYRIN
; NO ARG. TYPED RETURN, T2=0
; ILLEGAL CHARACTER RETURN
; NORMAL EXIT ;AC T2 CONTAINS NUMBER
;SCAN STOPS ON FIRST CR,DASH,SPACE,OR TAB OR ILLEGAL CHAR.
;SKIPS LEADING SPACES AND TABS
DECIN:: PUSHJ P,COMTYS ;SKIP CHAR
DECIN1::PUSHJ P,SAVE2## ;PRESERVE P1
MOVEI P1,12 ;DECIMAL INPUT
JRST ANYRIN
OCTIN:: PUSHJ P,COMTYS ;SKIP CHAR
OCTIN1::PUSHJ P,SAVE2## ;PRESERVE P1 ;;WARNING -- SEE AOS -3(P) BELOW
MOVEI P1,10 ;OCTAL INPUT
ANYRIN: PUSHJ P,SKIPS1 ;SKIP LEADING SPACES, TABS, NULLS
POPJ P,0 ;NOTHING LEFT. RETURN.
MOVEI P2,0 ;CLEAR DECIMAL ACCUMULATOR
CAIE T3,"#" ;SEE IF OCTAL FORCED
JRST ANYRI1 ;NO--PROCEED
MOVEI P1,10 ;YES--SET OCTAL RADIX
TLO P1,400000
PUSHJ P,COMTYS ;GET NEXT CHARACTER
ANYRI1: PUSHJ P,ANYR2 ;SEE IF NULL FIELD
JRST .+2 ;NOT END, SEE IF DIGIT
POPJ P, ;END--RETURN NULL
OCT0: CAIL T3,"0" ;IS CHARACTER .GE. A ZERO?
CAIL T3,"0"(P1) ;AND WITHIN RADIX BOUNDS?
JRST [CAIL T3,"0" ;NO. NOT A LEGAL DIGIT
CAILE T3,"9"
JRST ANYR1
JUMPL P1,ANYR1
TLO P1,200000
JRST .+1]
JFCL 17,.+1
IMULI T2,(P1) ;YES. SCALE INPUT SO FAR
ADDI T2,-"0"(T3) ;AND ADD IN THIS DIGIT
IMULI P2,^D10 ;MULTIPLY DECIMAL INPUT
JOV ANYR1 ;ON OVERFLOW, GIVE ILLEGAL CHARACTER RET
ADDI P2,-"0"(T3) ;INCLUDE THIS DIGIT
PUSHJ P,COMTYS ;GET ANOTHER CHARACTER
CAIE T3,"." ;SEE IF FORCING DECIMAL
JRST OCT0 ;AND LOOP FOR MORE.
MOVE T2,P2 ;YES--GET DECIMAL VALUE
JUMPL P1,ANYR1
PUSHJ P,COMTYS ;GET SEPARATOR
TLZ P1,200000
ANYR1: AOS -3(P) ;POINT TO ILLEGAL CHARACTER RETURN
TLNE P1,200000
POPJ P,
CAILE T3,40 ;CHECK FOR LEGAL TERMINATORS
ANYR2: CAIN T3,"," ;USED IN VARIOUS ROUTINES
JRST CPOPJ1## ;OK
CAIE T3,"[" ;MORE
CAIN T3,"]" ; ..
JRST CPOPJ1## ;OK.
CAIE T3,"<" ;MORE
CAIN T3,">" ; ''
JRST CPOPJ1## ;OK.
CAIE T3,"(" ;L. PAREN?
CAIN T3,"-" ;HYPHEN?
JRST CPOPJ1## ;OK.
CAIN T3,"/" ;SWITCHES?
JRST CPOPJ1## ;OK.
POPJ P,CPOPJ1## ;NO GOOD. GIVE "BAD CHARACTER RETURN"
; ROUTINE TO INPUT TIME SINCE MIDNIGHT
; LEGAL FORMATS ARE HH:MM[AM,PM] OR HH:MM:SS[AM,PM]
; THE COLONS, "AM", OR "PM" ARE ALL OPTIONAL
; CALL: PUSHJ P,RDTIM
; <ERROR> ;T1 POINTS TO ERROR TEXT
; <NORMAL> ;T1 CONTAINS TIME IN SECONDS SINCE MIDNIGHT
;
; AC USAGE: T1 - T4
;
RDTIM:: PUSHJ P,SAVE2## ;SAVE P1 AND P2
SETZB P1,T4 ;INIT INTERMEDIATE RESULT AND COUNTER
SETZ P2, ;CLEAR A FLAG
RDTIM0: IMULI P1,^D100 ;ADVANCE TO NEXT RESULT
PUSHJ P,DECIN ;GET NEXT SUPER-DIGIT
TDZA T2,T2 ;MAY HAVE TYPED HH::SS WHICH IS OK
JUMPL T2,RDTIM7 ;ERROR IF NEGATIVE
CAIL T2,^D60 ;RANGE CHECK
JUMPN T4,RDTIM6 ;TOO BIG FOR MINUTES OR SECONDS
ADD P1,T2 ;ADD TO ACCUMULATOR
CAIE T3,":" ;SEE IF MORE TO COME
JRST RDTIM1 ;NO--GO CONVERT RESULT
CAIGE T4,2 ;TOO MAY FIELDS?
AOJA T4,RDTIM0 ;NO--LOOP BACK FOR MORE
JRST RDTIM7 ;ILLEGAL FORMAT
RDTIM1: JUMPN T4,RDTIM2 ;JUMP IF NORE THAN ONE ARGUMENT
CAILE P1,^D2359 ;A REASONABLE NUMBER FOR HH:MM?
MOVEI T4,2 ;NO
RDTIM2: CAIGE T4,2 ;TWO OR LESS ARGUMENTS?
IMULI P1,^D100 ;YES--HAKE IT HH:MM:00
CAILE P1,^D235959 ;STILL REASONABLE?
JRST RDTIM6 ;HH GREATER THAN 23
PUSHJ P,RDTIM3 ;CONVERT TO TIME IN SECONDS
JUMPL P1,CPOPJ## ;RETURN IF FAILURE
SETZ P2, ;INIT FLAG
PUSHJ P,AMPM ;CHECK FOR AM OR PM
JRST RDTIM8 ;NO GOOD--ILLEGAL FORMAT
MOVE T1,P1 ;GET RESULT
JRST CPOPJ1## ;AND RETURN
RDTIM3: MOVE T2,P1 ;GET RESULT SO FAR
MOVEI P1,0 ;CLEAR RESULT
MOVEI T1,3 ;INITIALIZE TO ALLOW THREE FIELDS
MOVE P2,P ;SAVE P INCASE OF ERRORS
RDTIM4: IDIVI T2,^D100 ;SEPARATE TYPEIN
PUSH P,T3 ;STORE LEAST DIGIT AWAY
JUMPE T2,RDTIM5 ;JUMP IF ALL DONE
SOJLE T1,RDTIM7 ;GIVE AN ERROR IF TOO MANY FIELDS
PUSHJ P,RDTIM4 ;IF NOT, DO SOME MORE
RDTIM5: POP P,T1 ;GET BACK HIGHEST DIGIT
IMULI P1,^D60 ;MAKE ROOM IN RESULT
ADD P1,T1 ;INCLUDE RESULT
CAILE T1,^D60 ;SEE IF ERROR
JRST RDTIM6 ;COMPLAIN IF COMPONENT TOO BIG
POPJ P, ;RETURN
RDTIM6: JSP T2,RDTIM9 ;TIME COMPONENT TOO LARGE
RDTIM7: JSP T2,RDTIM9 ;ILLEGAL FORMAT IN TIME SPECIFICATION
RDTIM8: JSP T2,RDTIM9 ;ILLEGAL USE OF AM/PM CONSTRUCT
RDTIM9: SUBI T2,RDTIM6 ;GET ERROR CODE
TLZ T2,777777 ;STRIP OFF PC FLAGS OR SECTION NUMBER
MOVE T1,RDTIMM-1(T2) ;GET ADDRESS OF ERROR TEXT
MOVNI P1,1 ;SET P1 NEGATIVE TO INDICATE FAILURE
SKIPE P2 ;CALLED FROM WITHIN RDTIM3?
MOVE P,P2 ;YES--FIX UP STACK TO AVOID STOPCODES
POPJ P, ;AND RETURN
RDTIMM: [ASCIZ |Time component too large|]
[ASCIZ |Illegal format in time specification|]
[ASCIZ |Illegal use of AM/PM construct|]
; CHECK FOR AM OR PM APPENDED TO TIME
AMPM: MOVE T1,[-AMPMLN,,AMPMTB] ;AOBJN POINTER TO LEGAL ARGS
PUSHJ P,TXTARG ;SEE WHAT WE'VE GOT
JRST CPOPJ1## ;NOTHING
CAILE P1,^D12*^D60*^D60 ;GREATER THAN 12:00:00
POPJ P, ;YES--ILLEGAL FORMAT
SKIPE T1 ;SKIP IF AM
ADDI P1,^D12*^D60*^D60 ;OFFSET FOR PM
JRST CPOPJ1## ;AND RETURN
AMPMTB: SIXBIT /AM/
SIXBIT /PM/
AMPMLN==.-AMPMTB
;GET PROJECT-PROGRAMMER NUMBERS
;CALL: MOVE T1,INPUT BYTE POINTER
; PUSHJ P,PJPGNO
;
;(T2)LH _ PROJECT NUMBER
;(T2)RH _ PROGRAMMER NUMBER
;(T2) = 0 IF NO [ ]'S TYPED
;THE TERMINAL ] IS OPTIONAL
PJPGNO: PUSH P,P1
MOVEI P1,0 ;PRESET A 0 JUST IN CASE
PUSHJ P,SKIPS1
JRST PP2 ;NOTHING ON LINE
CAIE T3,"[" ;IS IT A "[" ?
CAIN T3,"<" ;OR 2741 EQUIV.
SKIPA ;YES
JRST PP2 ;EXIT.......
PUSHJ P,OCTIN ;GET FIRST ARG.-PROJ. NO.
JRST [CAIN T3,"-" ;SEE IF [-]
JRST [PUSHJ P,SKIPS ;YES -- SKIP -
JRST COMERP ;NOTHING LEFT
CAIE T3,"]" ;MINUS SIGN MUST BE FOLLOWED
CAIN T3,">" ; BY A LEGAL BRACKET
JRST PP1A ;THEN RETURN 0
JRST PP3] ;ELSE ERROR
HLRZ T2,JBTPPN##(J) ;NO ARG, DEFAULT TO LOGGED IN
JRST .+2] ;AND CONTINUE
JRST PP3 ;ILLEGAL OCTAL CHARACTER GIVEN
TLZ T2,-1
JUMPE T2,PP3 ;BOMB IF 0
HRL P1,T2 ;ENTER
CAIE T3,","
JRST PP3 ;PPN MUST HAVE COMMA
PUSHJ P,OCTIN ;GET SECOND ARG.-PROG. NO.
JRST [HRRZ T2,JBTPPN##(J) ;NO ARG, DEFAULT TO LOGGED IN
JRST .+2] ;AND CONTINUE
JRST PP3 ;
TLZ T2,-1
JUMPE T2,PP3 ;BOMB IF 0
HRR P1,T2 ;ENTER
PP1A: JUMPL P1,PP3 ;BOMB USER IF INVALID
PP2: MOVE T2,P1 ;RESULT IN T2
JRST P1POPJ## ;RETURN TO CALLER
PP3: POP P,P1
PJRST COMERP ;LOSE
;ROUTINE TO PRINT TIME AS HOURS,MINUTES,SECONDS, AND HUNDRETHS (NO CRLF)
;FORMAT IS HHMM:SS.HH, MM:SS, OR SS.HH IF HH AND MM ARE 0
;CALL: MOVE T1,TIME IN JIFFIES(60THS,50THS OR MILLISECONDS)
; PUSHJ P,PRTIM
; ;CALL PRTIME (ABOVE) TO GET CRLF AFTER TIME
;SCALEING IS DONE USING THE FOLLOWING GLOBAL SYMBOLS DEFINED IN COMMON
;THUS ANY INSTALLATION MAY HAVE ANY RATE CLOCK
;JIFMIN=NO. OF JIFFIES(CLOCK TICKS) PER MINUTE
;JIFSEC=NO. OF JIFFIES PER SECOND
;JIFSC2=1/2*JIFSEC(USED FOR ROUNDING)
PRNOW: MOVE T1,TIME## ;GET CURRENT TIME OF DAY
PRTIM:: CAMGE T1,TICMIN## ;IF LESS THAN A MINUTE
JRST PR1 ;IN USE DIFFERENT FORMAT
MOVE T2,TICSEC## ;ADD 1/2 TICKS/SEC FOR ROUNDING
LSH T2,-1
ADD T1,T2
IDIV T1,TICMIN## ;FORM MINUTES
PUSH P,T2 ;SAVE REMAINDER IN JIFFIES
IDIVI T1,^D60 ;HOURS, MINUTES IN T1,T2
JUMPE T1,PR0 ;SUPPRESS 0 HOURS
PUSHJ P,RADX10
PR0: PUSHJ P,INLMES ;PRINT "HH:" OR "H:"
ASCIZ /:/
MOVE T1,T2 ;GET MINUTES
PUSHJ P,PRT2 ;PRINT "MM:"
PUSHJ P,INLMES
ASCIZ /:/
POP P,T1 ;RESTORE SECONDS (IN JIFFIES)
PJRST PR2 ;PRINT AND RETURN (NO CRLF)
PR1: IDIV T1,TICSEC## ;JIFFIES PER SECOND
PUSHJ P,RADX10 ;PRINT SECONDS
PUSHJ P,PRPER ;PRINT PERIOD
MOVE T1,T2 ;NO OF JIFFIES(HUNDRETHS)
IMULI T1,^D100 ;CONVERT TO HUNDRETHS
PR2: IDIV T1,TICSEC##
PRT2: MOVEI T3,"0"
PUSH P,T1 ;SAVE T1 OVER I/O
CAIGE T1,^D10
PUSHJ P,COMTYO## ;PUT LEADING 0 IF LESS THAN 10
POP P,T1 ;RESTORE T1
JRST RADX10 ;PRINT REST OF NUMBER
;ROUTINE TO PRINT SIZE OF LOGICAL SEGMENT (LOW OR HIGH)
;CALL: MOVE J, HIGH OR LOW SEG NUMBER
; PUSHJ P,PRT SEG
; RETURN
;CALLED AT CLOCK LEVEL FROM CORE (UUO ARG) COMMAND AND SEGCON
PRTSEG: PUSHJ P,SEGSIZ ;T2=SIZE OF HIGH OR LOW SEG
MOVE T1,T2 ;RADX10 WANT DEC. NO. IN T1
JRST RADX10 ;PRINT DECIMAL
;ROUTINE TO RETURN SIZE OF HIGH OR LOW SEG
;CALL: MOVE J,LOW OR HIGH SEG NUMBER
; PUSHJ P,SEGSIZ
; RETURN WITH SIZE IN K IN T2
SEGSIZ::PUSHJ P,SAVE1## ;SAVE A COUPLE OF ACS
PUSH P,J ;SAVE J
HRRZS J ;SO CAN CLEAR JUNK
LDB T2,IMGIN## ;SEGMENT SIZE
CAILE J,JOBMAX## ;LOW SEGMENT?
JRST SEGSZ1 ;NO, GET HI SEG SIZE
MOVEI P1,JBTSGN##-.HBLNK(J) ;START OF SEGMENT DATA BLOCK CHAIN
SEGSZ0: HRRZ P1,.HBLNK(P1) ;NEXT SEGMENT DATA BLOCK
JUMPE P1,SEGSZ2 ;NO MORE
SKIPLE J,.HBSGN(P1) ;SPY SEG?
TLNE J,SHRSEG ;NON-SHARABLE?
JRST SEGSZ0 ;NO, CHECK NEXT
HRRZS J ;CLEAR JUNK
HLRZ J,JBTSWP##(J) ;GET SIZE OF THIS NON-SHARABLE
SUBI T2,(J) ;SUBTRACT OUT OF LOW SEG SIZE
JRST SEGSZ0 ;CONTINUE
SEGSZ1: JUMPG T2,JPOPJ## ;GO IF NON-ZERO
HLRZ T2,JBTSWP##(J) ;MAYBE A NON-SHARABLE HI SEG
JRST JPOPJ## ;RETURN
SEGSZ2: JUMPE J,JPOPJ## ;RETURN IF NO CORE
ADDI T2,UPMPSZ## ;YES, ACCOUNT FOR UPMP SIZE
JRST JPOPJ## ;RESTORE J AND RETURN
;ROUTINE TO ASSIGN A MINIMAL CORE AREA (2000 WORDS)
;CALLED FROM CORE, KJOB, AND RUN COMMANDS
;CALL: PUSHJ P,GETMIN
; RETURN R=0 IF UNSUCCESSFUL OR CORE ASSIGNED ON DISK
GETMIN::
IFN FTMP,<
PUSHJ P,GETMM## ;TRY TO GET THE MEMORY MANAGEMENT RESOURCE
JRST DLYCM1 ;FAILED, TRY AGAIN NEXT TIME
>
SKIPE PAGIPC## ;PAGING IN PROGRESS?
SKIPN JBTADR##(J) ;YES, PROCEED ONLY IF INCREASING CORE
JRST GETMI2 ;ENTER COMMON CODE
IFN FTMP,<
PUSHJ P,GIVMM## ;GIVE UP THE MM
>
JRST DLYCM1 ;AND TRY AGAIN NEXT TIME
GETMI1::
IFN FTMP,<
PUSHJ P,UPMM## ;GET MM (ALREADY AT UUO LEVEL)
>
GETMI2: PUSHJ P,ZAPEPL## ;CLEAR ANY EXTENDED PDL NOW
PUSH P,U ;SAVE TTY LDB ADDRESS
PUSH P,T2 ;SAVE DEVICE NAME(GET)
PUSH P,S ;SAVE DISPATCH ADDRESS(ANYACT USES S)
PUSHJ P,KILHGA## ;KILL HIGH SEG
IFN FTKL10&FTMP,<
PUSHJ P,CLCSN## ;CLEAR SWEEP SERIAL NUMBER FOR JOB
; SO WE DON'T SWEEP FOR NOTHING
>;END IFN FTKL10&FTMP
IFN FTPEEKSPY,<
PUSHJ P,CLRSPG## ;GET RID OF SPY PAGES
>
PUSHJ P,KILNZS## ;KILL NON-ZERO SECTIONS
JRST GMIDLY ;GIVE UP A WHILE
MOVEI T1,PG.BDY ;BASIC UNIT OF CORE MEMORY
PUSHJ P,CORE0## ;ASSIGN 2000 WORDS ON DISK OR MEMORY
JFCL ;IGNORE IF CANT(R=0)
IFN FTMP,<
PUSHJ P,GIVMM## ;RETURN MM RESOURCE
>
POP P,S
POP P,T2 ;RESTORE PUSHED ACS
PJRST UPOPJ## ;RESTORE U AND RETURN
GMIDLY: POP P,S
POP P,T2
POP P,U
IFN FTMP,<
PUSHJ P,GIVMM## ;RETURN MM RESOURCE
>
JRST DLYCM1
;SUBROUTINE TO GET A MINIMAL AMOUNT OF CORE IN CORE
GETCIC::PUSHJ P,GETMIN ;TRY TO GET CORE IN CORE
SKIPN JBTADR##(J) ;DID WE SUCCEED?
PJRST DLYCM ;NO
POPJ P, ;YES, RETURN TO CALLER
;FNDNAM--ROUTINE TO SEARCH FOR ABBREV. NAME IN TABLE
;CALL MOVE T1,AOBJN POINTER TO LIST OF NAMES
; MOVE T2,SIXBIT ABBREVIATION
; PUSHJ P,FNDNAM
;NON-SKIP IF UNKNOWN (T1=0) OR DUPLICATE (T1 .NE. 0)
;SKIP RETURN IF FOUND WITH T1=INDEX IN TABLE
FNDNAM::PUSHJ P,SAVE3## ;SAVE P1,P2,P3
MOVN P1,T2 ;FIND THE RIGHTMOST
AND P1,T2 ;NON-ZERO BIT IN COMMAND
JFFO P1,.+1 ;AND ITS CARDINALITY
IDIVI P2,6 ;FIND W HERE IN SIXBIT BYTE THE BIT IS
LSH P1,-5(P3) ;RIGHT-JUSTIFY THE BIT WITHIN THE BYTE
SOJ P1, ;MAKE MASK OF TRAILING BLANKS
SETZB T4,P2 ;INITIALIZE MATCH POINTER AND COUNT
MOVE P3,T1 ;SAVE POINTER
FNDNM2: MOVE T3,(T1) ;GET NEXT CANDIDATE
XOR T3,T2 ;COMPARE
JUMPE T3,FNDNMW ;WIN
ANDCM T3,P1 ;MASK IT
JUMPN T3,FNDNM3 ;LOOSE
MOVE T4,T1 ;WIN--SAVE POINTER
ADDI P2,1 ;COUNT SUCCESS
FNDNM3: AOBJN T1,FNDNM2 ;LOOP FOR ALL ENTRIES
FNDNM4: MOVE T1,T4 ;RESTORE POSSIBLE WINNER
SOJN P2,CPOPJ## ;JUMP IF UNSUCCESSFUL
FNDNMW: SUB T1,P3 ;COMPUTE INDEX
TLZ T1,-1 ;REMOVE JUNK
JRST CPOPJ1## ;SKIP RETURN
;FNDCOM--ROUTINE TO FIND A COMMAND
;FINDS COMMAND FROM EITHER CUSTOMER TABLE, OR NORMAL TABLE
;CALL MOVE T2,SIXBIT ABBREVIATION
; PUSHJ P,FNDCOM
; DIDN'T FIND IT OR DUPLICATE
; FOUND IT, T1/ FLAGS,,OFFSET
; T3/TYPE OF MATCH FLAGS
;T2 PRESERVED
;USES P3,P4,T1
;NON-SKIP IF UNKNOWN (T1.EQ.0) OR DUPLICATE (T1.NE.0)
FNDCOM: MOVE P3,[XWD UNQTBC##,DISPC##] ;CUSTOMER UNIQUENESS BITS,,DISPATCH
MOVE P4,[XWD -DISPLC##,CSTTAB##] ;CUSTOMER -LENGHT,,COMMAND TABLE
TLNN P4,777777 ;ANY CUSTOMER DEFINED COMMANDS?
JRST FNDCO1 ;NO, DON'T CHECK FOR THEM THEN
SETZ T1, ;NO FLAGS FOR FULL WORD LDB POINTER
PUSHJ P,FNDABV ;LOOK IT UP
JRST FNDCO1 ;ERROR, TRY REGULAR COMMANDS
TRNE T3,CEXACT ;EXACT MATCH?
JRST CPOPJ1## ;FOUND, RETURN NOW
PUSH P,T1 ;SAVE THE RESULT ACS IN CASE
PUSH P,T3 ; THEY MUST BE RETURNED TO THE CALLER
PUSH P,P3 ;LIKEWISE,
PUSH P,P4 ;SAVE THE TABLE ACS
PUSHJ P,FNDCO1 ;GO SEARCH THE MAIN TABLE
JRST FNDCO2 ;NOT FOUND, RETURN WHAT WE HAVE
TRNE T3,CEXACT ;EXACT MATCH?
JRST FNDCO3 ;EXACT MATCH, RETURN GOOD
MOVE T4,-2(P) ;GET CUSTOMER RESULT BITS
TRNN T4,CUNIQ ;IF UNIQUE HERE,
TRNN T3,CUNIQ ;OR NOT SO HERE,
JRST FNDCO2 ;RETURN CUSTOMER COMMAND
JRST FNDCO3 ;ELSE, RETURN DEC COMMAND
FNDCO2: POP P,P4 ;RESTORE TABLE ACS
POP P,P3 ; ...
POP P,T3 ;RESTORE THE STACK
POP P,T1 ; FOR RETURN OF CUSTOMER COMMANDS
JRST CPOPJ1 ;RETURN GOOD
FNDCO3: ADJSP P,-4 ;DESTROY THE RETURNED CUSTOMER RESULTS
JRST CPOPJ1 ;AND RETURN GOOD
FNDCO1: MOVE P3,[XWD UNQTAB##,DISP##] ;SET P3=UNIQNESS BITS, DISPATCH TABLE
MOVE P4,[XWD -DISPL##,COMTAB##] ;SET P4=-LENGTH,TABLE LOC
SETZ T1, ;NO FLAGS FOR FULL WORD LDB POINTER
PUSHJ P,FNDABV ;LOOK IT UP
POPJ P, ;RETURN ERROR
JRST CPOPJ1## ;FOUND, RETURN GOOD
;FNDABV--ROUTINE TO SEARCH FOR ABBREV. NAME IN LIST
;CALL MOVE T1,FLAGS
; MOVE T2,SIXBIT ABBREVIATION
; MOVSI P3,UNQTAB ;POINTER TO UNIQNESS BITS COMPRESSED TABLE
; MOVE P4,AOBJN POINTER TO NAMES
; PUSHJ P,FNDABV
; DIDN'T FIND IT OR DUPLICATE
; FOUND IT, T1/ FLAGS,,OFFSET
; T3/ TYPE OF MATCH FLAGS
;T2 AND P ACS ARE PRESERVED
;NON-SKIP IF UNKNOWN (T1=0) OR DUPLICATE (T1.NE.0)
;
CEXACT==1B18 ;COMMAND WAS EXACT MATCH
CUNIQ==1B19 ;COMMAND MATCHED ON UNIQUENESS
CAMBIG==1B20 ;COMMAND WAS AMBIGUOUS
CMONSB==1B21 ;COMMAND IS A SUBSTITUTE MONITOR COMMAND
FNDABV::PUSHJ P,SAVE4## ;SAVE P1-P4
PUSHJ P,SAVR## ;NEED YET ANOTHER AC
PUSH P,T2 ;SAVE FOR A MOMENT
MOVNS T2 ;NEGATE NAME
AND T2,(P) ;FIND RIGHTMOST NON-ZERO BIT
JFFO T2,.+1 ;IN THE COMMAND
IDIVI T3,6 ;FIND WHERE IN THE SIXBIT BYTE IT IS
LSH T2,-5(T4) ;RIGHT JUSTIFY THE BIT WITHIN THE BYTE
SOS T3,T2 ;MAKE MASK OF TRAILING BITS
POP P,T2 ;AND RESTORE THE COMMAND NAME
HLRZ P2,P3 ;RIGHT HALF POINTER TO UNQTAB
HRLI P2,(POINT ^D36,) ;ASSUME SYSTEM COMMAND
TLNE T1,1 ;IS IT?
HRLI P2,(POINT 6,) ;NO, THEN IT IS USER UNIQTAB
SETZB P1,P3 ;NO MATCHES FOUND YET (WE HAVEN'T LOOKED!)
MOVE R,P4 ;COPY THE STARTING AOBJN POINTER
FNDAB2: MOVE T4,(P4) ;GET NEXT CANDIDATE
XOR T4,T2 ;COMPARE
JUMPE T4,FNDEXC ;WIN ON EXACTNESS
ANDCM T4,T3 ;MASK IT
JUMPN T4,FNDAB4 ;LOSE
ILDB T4,P2 ;GET UNIQUENESS INFO
TRNN T4,<UNIQ.1!UNIQ.2!UNIQ.3!UNIQ.4> ;ANY UNIQNESS BITS
JRST FNDAB3 ;NO UNIQUENESS INFO
TRNE T4,UNIQ.1 ;UNIQUE AT 1 CHAR?
CAME T3,[7777,,-1] ;AND ONLY ONE CHAR SEEN?
CAIA ;NO
JRST FNDAWN ;YES, THEN WE HAVE IT
TRNE T4,UNIQ.2 ;UNIQUE AT 2 CHARS?
CAME T3,[77,,-1] ;AND TWO CHARS SEEN?
CAIA ;NO
JRST FNDAWN ;YES, SO WE HAVE IT
TRNE T4,UNIQ.3 ;UNIQUE AT 3 CHARS
CAME T3,[0,,-1] ;AND THREE CHARS SEEN?
CAIA ;NO
JRST FNDAWN ;YES
TRNE T4,UNIQ.4 ;UNIQUE AT 4 CHARS?
CAME T3,[0,,7777] ;AND FOUR CHARS TYPED?
CAIA ;NO
JRST FNDAWN ;YES
FNDAB3: HRR P3,P4 ;POSSIBLE WIN--SAVE POINTER
HRL P3,T4 ;AND BITS (IN CASE USER COMMAND)
AOSA P1 ;COUNT SUCCESS
FNDAB4: IBP P2 ;ADVANCE
AOBJN P4,FNDAB2 ;LOOP FOR ALL ENTRIES
SETZ T3, ;CLEAR ANY STRAY FLAGS
JUMPE P1,CPOPJ## ;NOTHING FOUND, RETURN NOW
SOJN P1,FNDAB6 ;MAKE SURE WE ONLY GOT A SINGLE COMMAND.
TLZ P4,-1 ;CLEAR THE LEFT HALF
SUBI P3,(R) ;CALCULATE THE OFFSET
TLNN T1,1 ;SYSTEM TABLE?
TLZ P3,-1 ;YES, CLEAR FLAGS
MOVE T1,P3 ;LEAVE WHERE CALLERS CAN FIND IT
JRST CPOPJ1## ;AND RETURN SUCCESS
;WIN ON EXACTNESS.
FNDEXC: ILDB T4,P2 ;GET UNIQUENESS (IN CASE USER COMMAND)
SKIPA T3,[CEXACT] ;TELL OF AN EXACT MATCH
;WIN BY VIRTUE OF UNIQNESS BITS. SEARCH NO MORE.
FNDAWN: MOVEI T3,CUNIQ ;REMEMBER WE WON UNIQUELY
SUBI P4,(R) ;COMPUTE INDEX TO RETURN
HRR T1,P4 ;COPY OFFSET
TLNE T1,1 ;SYSTEM TABLE?
HRLI T1,(T4) ;NO, COPY FLAGS FOR USER TABLE
JRST CPOPJ1## ;AND RETURN SUCCESS
;LOSE THROUGH AMBIGUITY.
FNDAB6: MOVEI T3,CAMBIG ;GET THE AMBIGUOUS BIT
POPJ P,
SUBTTL SAVGET -- PARAMETERS
;SAVGET LOWER CORE LOCATIONS USED FOR UUOS TO MONITOR
;USED IN SAVGET IN APRSER AND SAVGET IN SEGCON
;THESE LOCATIONS ARE DEFINED TO BE IN THE USERS UUO ACS
;FOR LOOKUP,ENTER UUOS:
XP SGANAM,0
;FILE NAME
XP SGAEXT,SGANAM+1
;FILE EXTENSION
XP SGADAT,SGANAM+2
;FILE CREATION DATE+TIME
XP SGALEN,SGANAM+3
;LH=-LENGTH,RH=FIRST LOC-1 DUMPED
; OR PROJECT-PROGRAMMER NUMBER(DISK)
XP SGAEND,SGALEN+1
;LAST WORD OF DUMP COMMAND LIST=0(SAVE AND GET)
XP SGAREN,SGAEND
; ALSO FIRST WORD FOR RENAME USED AS DELETE
XP SGAPPN,SGAREN+3
;FOURTH WORD-PLACE TO SAVE PROJECT-PROGRAMMER
; NUMBER USER TYPED
;FOR OPEN UUOS:
XP SGAMOD,10
;S MODE WORD FOR OPEN UUO
XP SGADEV,SGAMOD+1
;DEVICE NAME
XP SGAHED,SGAMOD+2
;INPUT-OUTPUT BUFFER HEADER ADDRESSES=0
;MISC. DATA LOCATIONS:
XP SGACOR,13
;AC FOR CORE UUO'S(HIGHEST USER LOC DESIRED)
XP SGADMP,14
;DUMP COMMAND IOWD
SGASAV==:SGADMP
XP SGANEW,15
;NEW CORE ASSIGNMENT AS SPECIFIED BY THIRD ARG
XP SGAHGH,16
;LH=EXT TO USE FOR SAVING HIGH SEG
; RH=EXT TO DELETE(IE SHRHGH OR HGHSHR)
XP SGALOW,17
;LH=EXT WHICH USER TYPED FOR SAVE OR GET COMMAND
; OR .SAV IF HE DIDN'T TYPE AN ARG WITH LEADING PERIOD
; RH=0
SUBTTL SAVGET -- COMMAND SCAN
;ROUTINE TO SCAN COMMAND STRING ARGUMENTS FOR SAVE,GET,MERGE,RUN AND R
;COMMANDS AND STORE THEM IN JOB DATA AREA WHICH MUST BE IN CORE
;WHEN SGSET IS CALLED FROM COMMAND DECODER
;CALL: MOVE T2,SIXBIT DEVICE NAME
; MOVE J,JOB #
; MOVE U,LDB ADDRESS
; MOVE S,ADR. OF MONITOR JOB(SAVJOB,GETJOB,MRGJOB,RUNJOB)
; MOVE R, ADR. OF JOB AREA
; PUSHJ P,SGSET
SGSETD: HLLZ T2,SYSTAP## ;SET DEFAULT DEVICE OF DISK
SGSET: MOVEM P1,.USUAC+6
MOVEM P2,.USUAC+4 ;SAVE COMMAND FOR GET
PUSHJ P,SETASA ;TURN ON THE EXEC MODE UUO FLAG
MOVEM T2,.JDAT+SGADEV ;STORE DEFAULT DEVICE NAME
MOVEM P1,.JDAT+SGAMOD ;SAVE PHYSICAL/LOGICAL BIT FOR LATER
SETZM .JDAT+SGAPPN ;INDICATE NO DEFAULTING DONE
SETZM .USUSN ;ALSO, NO /USE VALUE
SETZM .USUSA ;NO USER SUPPLIED START ADDRESS
CAMN P2,PLNTXT## ;USER-DEFINED COMMAND?
JRST SGSETC ;YES, COPY STUFF FROM BLOCK RATHER THAN COMMAND
HRRZ P3,S ;COMMAND
CAIN P3,MRGJOB ;MERGE COMMAND?
JRST SGSET1 ;YES
CAME T2,[SIXBIT/SYS/];R COMMAND?
CAIN P3,SAVJOB ;OR SAVE COMMAND?
JRST SGSET1 ;YES, USE OLD DEFAULTS
MOVSI T1,(PD.UDS) ;WAS A SAVE COMMAND THE LAST
TDNE T1,.PDDFL##(W) ; COMMAND DONE?
PUSHJ P,SGSEND ;OR WERE ARGUMENTS TYPED?
JRST SGSET1 ;YES, OLD STYLE DEFAULTING
SKIPN T1,.PDNAM##(W) ;NAME FROM PREVIOUS GET OR RUN
JRST SGSET1 ;USE JBTPRG
MOVEM T1,.JDAT+SGANAM ;STORE NAME
MOVEM T1,JBTPRG##(J)
MOVE T1,.PDSTR##(W) ;FILE STRUCTURE
MOVEM T1,.JDAT+SGADEV
MOVE T1,.PDDIR##(W) ;DIRECTORY
MOVEM T1,.JDAT+SGAPPN
MOVSI T1,.PDSFD##(W) ;AND SFD'S
HRRI T1,.JDAT+JOBUAL##+3
BLT T1,.JDAT+JOBUAL##+MAXLVL##+2
JRST SGSET4 ;GO PROCESS GET OR RUN
SGSET1: PUSHJ P,CTEXT1 ;GET DEVICE OR NAME
CAIE T3,":" ;SEE IF DEVICE
JRST SGSET2 ;NO--SET FILE NAME
MOVEM T2,.JDAT+SGADEV ;YES--SAVE IT
PUSHJ P,CTEXT ;AND GET FILE NAME
SGSET2: SETZM .JDAT+JOBUAL##+3;ASSUME USER DID NOT SPECIFY SFD'S
CAIE T3,"[" ;PPN HERE A POSSIBILITY?
CAIN T3,"<" ;TO CLOSE ANGLE BRACKET>, OR 2741 STYLE?
PUSHJ P,[PUSH P,T2 ;SAVE POSSIBLE FILE NAME
PUSHJ P,GETPPN ;SEE IF THERE IS A PPN
JRST T2POPJ## ;NO, TRY LATER IN THE MORE TRADITIONAL PLACE
POP P,T2 ;RESTORE POSSIBLE FILE NAME
JUMPN T2,CPOPJ## ;GO IF ONE WAS ALREADY TYPED
PJRST CTEXT1];HAVEN'T SEEN ONE, GO READ IT NOW
CAIN P3,MRGJOB ;MERGE COMMAND?
JRST SGSET3 ;YES, A FILE NAME IS REQUIRED
SKIPN T2 ;SEE IF FILE TYPED IN
MOVE T2,JBTPRG##(J) ;NO--GET DEFAULT IF ANY
MOVEM T2,JBTPRG##(J) ;SAVE FILE NAME FOR SYSTAT COMMAND
SGSET3: MOVEM T2,.JDAT+SGANAM ;STORE FILE NAME
SETZ T2, ;ASSUME USER DID NO SPECIFY AN EXTENSION
; 0 WILL BE TURNED INTO SAV OR DMP
CAIN T3,"." ;IS AN EXTENSION SPECIFIED
PUSHJ P,CTEXT ;YES. GET EXTENSION
HLRZS T2 ;SEE IF THE USER
CAIE T2,(SIXBIT /SHR/) ;HAS SPECIFIED AN
CAIN T2,(SIXBIT /HGH/) ;IMPROPER LOW EXTENSION
SGSET4: MOVEI T2,0 ;YES--IGNORE IT
HRLZM T2,.JDAT+SGAEXT ;STORE IT FOR LOOKUP
MOVSI T1,(JS.EXE)
CAIN T2,(SIXBIT /SAV/)
ANDCAM T1,JBTST2##(J)
PUSHJ P,SETEXT## ;SET HIGH EXTENSION(SGAHGH) TO .SHR IF SSAVE OR GET
; ,HGH IF SAVE(LH S=NSRBIT).
SETZM .JDAT+SGADAT ;SET DATE(E+2) TO 0, SO MONITOR WILL USE TODAYS
SKIPN .JDAT+SGAPPN ;ALREADY READ A PPN?
PUSHJ P,GETPPN ;NO, SEE IF THERE IS ONE
JFCL ;NOT HERE ANYWAY, SEE IF TYPED EARILER
SKIPN .JDAT+JOBUAL##+3 ;A PATH TYPED OR DEFAULTED?
JRST SGSET5 ;NO
MOVEI T1,JOBUAL## ;ADDRESS OF THE PATH
EXCH T1,SGAPPN+.JDAT ;STORE PATH AND GET THE PPN
MOVEM T1,JOBUAL##+.JDAT+2 ;STORE THE PPN
SETZM .JDAT+JOBUAL##+1 ;SO FILSER WILL SCAN IF THE SCAN SWITCH IS ON
SGSET5: PUSHJ P,CORARG ;AMOUNT OF CORE (OPTIONAL THIRD ARG.)
JRST SGSET6 ;RETURN HERE IF NO ARG.
TLNE T2,-1 ;USER ARG EXCEED MAX. SIZE OF CORE?
JRST SGERRP ;YES, PRINT COMMAND ERROR
SGSET6: HRRZM T2,.JDAT+SGANEW ;STORE FOR RUN AND SAVE
PUSHJ P,SGSEND ;END OF LINE?
CAIA ;READ THE REST
JRST SGSET7 ;NOTHING MORE TO READ OR IF THERE IS, ITS ILLEGAL
CAIE T3,"/" ;SWITCH TYPED?
JRST SGSET7 ;NO, SKIP ON
SGSE6A: PUSHJ P,CTEXT ;READ SWITCH VALUE
MOVE T1,[-2,,[SIXBIT /USE/
SIXBIT /START/]]
CAIN T3,":" ;NEED A ":" BEFORE THE VALUE
PUSHJ P,FNDNAM ;SEE IF LEGAL SWITCH VALUE
JRST SGERRP ;NO, PRINT COMMAND ERROR
CAIN T1,0 ;USE SWITCH?
CAIE T1,SAVJOB ;YES, SAVE COMMAND?
CAIA ;NO TO EITHER
JRST SGERRP ;USE SWITCH ON A SAVE COMMAND IS ILLEGAL
CAIE T1,1 ;START SWITCH?
JRST SGSE6B ;NO, GO PROCESS USE SWITCH
PUSHJ P,SKIPS ;DISCARD ":"
JRST SGERRP ;EOL IS ILLEGAL HERE
PUSHJ P,OCTPAR ;READ VALUE OF START SWITCH
JRST SGEENF ;THERE MUST BE ONE
CAIE P3,SAVJOB ;IF NOT A SAVE,
TLO T2,400000 ;LITE START ADDRESS SPECIFIED BY COMMAND
MOVEM T2,.USUSA ;STORE VALUE FOR SAVE OR RUN
MOVE S,P3 ;OCTPAR CLOBBERED S
JRST SGSET7 ;CONTINUE
SGSE6B: PUSHJ P,OCTIN ;READ VALUE
JRST SGEENF ;NULL VALUE ILLEGAL
JRST SGERRE ;ILLEGAL CHARACTER
LSH T2,S2PLSH ;PUT IN SECTION NUMBER FIELD
MOVEM T2,.USUSN ;SAVE FOR GET/R/RUN/MERGE PROCESSING
SGSET7: PUSHJ P,SGSEND
JRST [CAIE T3,"/" ;ANOTHER SWITCH?
JRST SGERRP ;NO, ANYTHING ELSE IS ILLEGAL
JRST SGSE6A] ;YES, PROCESS NEXT SWITCH
HRRZS T2,S ;SCHEDULE MONITOR JOB
; GUARRANTEE LH OF PC WORD IS 0, SINCE IT WILL
; BE ADDED TO STARTING ADDRESS(IF RUN COM)
SUBI S,SAVJOB
MOVSI T1,(PD.UDS) ;ASSUME RUN,GET COMMAND (REMEMBER DEFAULTS)
IORM T1,.PDDFL##(W)
SKIPN S ;IS IT?
ANDCAM T1,.PDDFL##(W) ;NO, FORGET DEFAULTS
PUSHJ P,CHKEXE ;IS THIS AN EXE SAVE?
JRST SGSET8 ;YES, MAKE AN EXE FILE
;NO, FALL THRU TO REGULAR SAVES
SKIPN .USREL ;IF NON-CONTIGUOUS CORE IMAGE
SKIPE .USVRT ;OR VIRTUAL (1+I SEA)
SGSET8: JUMPE S,SGSE10 ;GO ELSEWHERE IF SAVE
SGSET9:
IFN FTMP,<
PUSHJ P,CLRJSP## ;CLEAR JBTSPS TO ENSURE MONITOR JOB RUNS ON MASTER
>
PJRST MSTART## ;START JOB WITH PC IN MONITOR MODE
SGSE10: HLRZ T1,JBTADR##(J) ;GET HIGHEST ADDRESS IN LOW SEG
CAMGE T1,.JDAT+SGANEW ;COMPARE WITH USER STORED CORE ARG
MOVE T1,.JDAT+SGANEW ;USER'S WAS LARGER, USE IT
HRRM T1,.JDAT+JOBCOR## ;AND SET UP JOBCOR.
PUSHJ P,CHKEXE ;NSAVE OR NSSAVE?
JRST SGSET9 ;YES, SAVE AN EXE FILE
;LOSE SINCE MONITOR CAN'T DO IT ANYWAY
SGERRE: PUSHJ P,COMTYI## ;EAT ONE MORE CHARACTER
SGERRP: PUSHJ P,CLRASA ;CLEAR SHADOW ACS FLAG
JRST COMERR ;GO GIVE ERROR MESSAGE
SGEENF: PUSHJ P,CLRASA ;CLEAR SHADOW ACS FLAG
JRST NOTENF ;GO REPORT NOT ENOUGH CORE
;SUBROUTINE TO TEST FOR EOL. RETURNS CPOPJ IF NOT, CPOPJ1 IF IT IS
SGSEND: PUSH P,T2
PUSHJ P,SKIPS1 ;SKIP SPACES
JRST T2POJ1## ;EOL
CAIE T3,"(" ;SEE IF USER ARGUMENTS
CAIN T3,"-" ;DITTO (THE OLD WAY)
JRST T2POJ1## ;YES, END OF COMMAND LINE
JRST T2POPJ## ;NO, MORE TO PROCESS
;SUBROUTINE TO READ A PPN. RETURNS CPOPJ IF NONE FOUND, CPOPJ1 IF FOUND,
; [P,PN,PATH] STORED
GETPPN: SKIPN T2,.JDAT+SGAPPN ;PPN DEFAULTED?
PUSHJ P,PJPGNO ;GET PROJ. PROG. NO.
MOVEM T2,.JDAT+SGAPPN ;STORE 0 IF NO []'S TYPED BY USER
SETO P1,
CAIE T3,"," ;COMMA TYPED?
JRST [JUMPE T2,CPOPJ## ;(N0) IF NO PPN, ALL IS OK
JRST GETPP1]
JUMPE T2,COMERA ;(YES) ERROR IF SFD WITHOUT PPN
SETZ P1, ;SET SFD FLAG
GETPP1: MOVSI T1,(SIXBIT/SYS/)
CAME T1,.JDAT+SGADEV ;DID HE ASK FOR "SYS" BY MISTAKE?
JRST GETPP3 ;NO, ALL IS OK
PUSH P,T3 ;SAVE PUNCTUATION
PUSHJ P,DEVLG## ;IS "SYS" A LOGICAL NAME?
SKIPA ;NO, CHANGE IT TO "DSK"
JRST GETPP2 ;YES, NO CHANGES (HE KNOWS
; WHAT HE IS DOING)
MOVSI T1,(SIXBIT /DSK/)
MOVEM T1,.JDAT+SGADEV ;HE TYPED .R FOO[N,N]
;SO CHANGE "SYS" TO "DSK"
GETPP2: POP P,T3 ;RESTORE PUNCTUATION
GETPP3: JUMPN P1,GETPP5 ;JUMP IF NO PATH SPECIFIED
MOVEI P2,JOBUAL##+.JDAT+3 ;WHERE TO STORE SFD'S
GETPP4: PUSHJ P,CTEXT ;GET NEXT SFD
JUMPE T2,NOTENF
MOVEM T2,(P2) ;STORE SFD IN LOOKUP/ENTER BLOCK
AOS P2 ;NEXT SFD SLOT
SETZM (P2)
CAIE T3,"," ;WAS ANOTHER SFD TYPED?
JRST GETPP5 ;NO
CAIGE P1,MAXLVL##-1 ;EXCEED MAXIMUM NUMBER OF SFD'S?
AOJA P1,GETPP4 ;NO, GO READ THE NEXT SFD
JRST COMERA ;TO MANY SFD'S
;< SO ANGLE BRACKETS MATCH
GETPP5: CAIE T3,">" ;IS 2741 ENDING
CAIN T3,"]" ;OR USUAL "]"?
PUSHJ P,COMTYS ;YES, DISCARD CHARACTER
JRST CPOPJ1## ;AND GIVE [P,PN,PATH] FOUND RETURN
;COPY USER-DEFINED COMMAND INFORMATION TO SGAXXX.
SGSETC: SE1ENT ;DO THIS IN SECTION 1 (IN CASE GFWNZS)
SETZM .JDAT ;CLEAN OUT THE ACS.
MOVE T1,[.JDAT,,.JDAT+1] ;BLT POINTER
BLT T1,.JDAT+17 ;SINCE WE AREN'T TOO CAREFULL.
HLRZ T4,P3 ;GET POINTER TO OUR BLOCK
;MAYBE SSX T4,MS.MEM ;POINT TO PROPER SECTION
MOVE T1,(T4) ;GET NUMBER OF WORDS IN OUR BLOCK
SOJLE T1,SGSCER ;IF THIS BLOWS UP, WE HAVE A PROBLEM.
MOVE T2,1(T4) ;GET DEVICE NAME
MOVEM T2,.JDAT+SGADEV ;SAVE AS DEVICE NAME FOR RUN UUO
SOSG T1 ;HAVE FILE NAME?
TDZA T2,T2 ;NO, USE BLANK NAME (ASSUME PATHOLOGICAL DEVICE)
MOVE T2,2(T4) ;YES, GET NAME OF PROGRAM TO RUN
MOVEM T2,.JDAT+SGANAM ;SAVE AS FILENAME FOR RUN UUO
SOSG T1 ;HAVE EXTENSION WORD?
TDZA T2,T2 ;NO, DEFAULT IT
HLRZ T2,3(T4) ;YES, GET EXTENSION
CAIE T2,'SHR' ;IF INVALID LOW EXTENSION,
CAIN T2,'HGH' ;OF EITHER TYPE,
SETZ T2, ;IGNORE IT
MOVSM T2,.JDAT+SGAEXT
PUSHJ P,SETEXT## ;SETUP EXTENSION
SOJLE T1,[SETZM .JDAT+SGAPPN ;NO PPN
JRST SGSCEX] ;AND FALL INTO COMMON CODE
;PPN AND SFDS
MOVEI T2,JOBUAL## ;WHERE WE ARE GOING TO PUT A PATH BLOCK
MOVEM T2,.JDAT+SGAPPN ;POINTER TO PATH BLOCK
SETZM .JDAT+JOBUAL##+1 ;ZERO PATH FLAGS
XMOVEI T2,4(T4) ;POINTER TO START OF BLOCK TO COPY
XMOVEI T3,.JDAT+JOBUAL##+2 ;WHERE TO.
CAILE T1,MAXLVL+1 ;MAKE SURE WE WILL FIT
SGSCER: STOPCD CPOPJ,DEBUG,CBB, ;++COMMAND BLOCK BAD
PUSHJ P,XBLTAT## ;COPY THE DATA
SETZM (T3) ;ADD IN A TERMINATING ZERO
SGSCEX: SETZM .JDAT+SGAMOD ;ALLOW LOGICAL NAMES
HRRZ T2,S ;GET ADDRESS TO DISPATCH TO
TLO M,NOCRLF ;DO IT LIKE REAL COMMANDS
PJRST MSTART## ;AND GET THE MONITOR TO RUN AT UUO LEVEL
SUBTTL SAVGET -- RUN AND GETSEG UUO'S
;ROUTINE TO PICKUP ARGUMENTS FOR RUN AND GETSEG UUOS
;THIS ROUTINE DOES SAME THING AS SGSET, EXCEPT THAT ARGUMENTS ARE
;OBTAINED FROM USER UUO ARGUMENTS INSTEAD OF FROM CONSOLE COMMAND
;THE USERS ARG ARE MOVED TO USER ACS(SGA...), THEREBY CLOBBERING HIS ACS
;USER AC FIELD AND START PC OFFSET(RUN UUO) ARE SAVED ON PD LIST AT JOBPD3
;THEN LOWER CORE IS SET UP(SG2 CALLED) RESET IS NOT DONE (FOR GETSEGUUO)
;JBTPRG NOT SET FOR LOW SEG, SINCE GETSEGUUO SHOULD NOT
;CALL: MOVE T1,CONTENTS OF USER AC(ADR. OF 3 WORD ARG LIST)
; MOVE R,JOB RELOCATION
; PUSHJ P,GETARG
; RETURN
GETARG::HRR M,T1 ;MOVE ADR. OF ARG LIST TO UUO
EXCH T1,(P) ;AND PUT ON PD LIST
PUSH P,T1 ;MOVE RETURN PC UP ONE IN PD LIST
LDB T1,PUUOAC## ;USER AC FIELD IN RUN OR GETSEG UUO
HRRM T1,-1(P) ;SAVE IN CASE OF ERROR RETURN
PUSHJ P,GETWDU## ;GET FIRST ARG FROM USER AREA
MOVEM T1,.JDAT+SGADEV ;STORE DEVICE NAME
PUSHJ P,GETWD1## ;GET NEXT ARG FROM USER AREA
MOVEM T1,.JDAT+SGANAM ;STORE FILE NAME FOR LOOKUP (DO NOT STORE FOR LOWSEG)
PUSHJ P,GETWD1## ;GET THIRD ARG(EXTENSION WORD E+1)
MOVEM T1,.JDAT+SGAEXT ;STORE EXTENSION AND RH FROM USER
PUSHJ P,GETWD1## ;GET FOURTH ARG(DATE WORD)
MOVEM T1,.JDAT+SGADAT
PUSHJ P,GETWD1## ;GET FIFTH USER ARG FROM USER AREA
MOVEM T1,.JDAT+SGAPPN ;STORE PROJECT,PROGRAMMER NO. OR 0
PUSHJ P,GETWD1## ;SIXTH ARG FROM USER
MOVEM T1,.JDAT+SGANEW ;STORE CORE ARG, PAGE RANGE, OR 0(HIGHEST LOC DESIRED)
HLRZ T2,.JDAT+SGAEXT ;PUT ARG IN T2, SO SAME AS SGSET RETURN FROM CTEXT
CAIE T2,'SHR' ;SEE IF THE USER
CAIN T2,'HGH' ; GAVE A BAD EXT
MOVEI T2,0 ;YES--IGNORE IT
PUSHJ P,SETEX1## ;SAVE EXT AGAIN IN SGALOW
; SETUP EXT FOR HIGH SEG(SGAHGH="SHR")
; SETUP EXTENSION FOR LOW SEG(SGALOW="SAV")
JRST SG2A ;GO SET UP LOWER CORE AND RETURN
; DO NOT DO A RESET
;HERE TO GET THE EXTENDED CORE/SECTION ARGUMENT (IF GIVEN) FOR SAVEGET UUOS.
;CALL ONLY AFTER CALLING GETARG.
;USES ONLY T1
UGTSSL::HLRZ T1,.USUPF ;GET (REAL) PCS
ANDI T1,(SECMSK) ;KEEP ONLY SECTION NUMBER
LSH T1,S2PLSH ;MAKE INTO A PAGE NUMBER
MOVEM T1,.USUSN ;SAVE AS DEFAULT IF EXTENDED ARG NOT GIVEN
;PJRST UGTSSN ;FALL INTO UGTSSN
UGTSSN::SKIPL T1,.JDAT+SGANEW ;SEE IF ARG IS NEGATIVE
POPJ P, ;NO, WE'RE DONE HERE
PUSH P,M ;MAY NOT BE NECESSARY, BUT ...
HRRI M,(T1) ;POINT AT ARGUMENT LIST EXTENSION
PUSHJ P,CLRASA ;ALLOW FOR THE POSSIBILITY THAT ARG IS IN ACS
PUSHJ P,GETMWD## ;GET THE SECTION NUMBER (USE GETMWD SINCE SETASA ZEROED PCS)
JRST UADERR## ;ADDRESS CHECK
PUSH P,T1 ;SAVE T1
HLRE T1,.JDAT+SGANEW ;GET LENGTH OF ARGUMENT LIST
CAML T1,[-1] ;MORE THAN 1 WORD LONG? (MERGE SPECIFYING A RANGE)
JRST UGTSS1 ;NO, NO MORE ARGUMENTS TO FETCH
HRRI M,1(M) ;POINT AT NEXT ARGUMENT
PUSHJ P,GETMWD## ;FETCH IT
JRST UADERR## ;ADDRESS CHECK
MOVEM T1,.JDAT+SGANEW ;STORE SECOND ARGUMENT HERE
UGTSS1: PUSHJ P,SETASA ;RESTORE JS.ASA
POP P,T1 ;RESTORE SECTION NUMBER
POP P,M ;RESTORE M
SKIPL T1 ;NEGATIVE SECTION NUMBERS ARE ILLEGAL
CAILE T1,MXSECN ;LESS THAN THE HIGHEST LEGAL SECTION NUMBER?
JRST IUUAGL## ;NO, ILLEGAL UUO ARGUMENT LIST
LSH T1,S2PLSH ;CONVERT TO EXTENDED PAGE NUMBER
REPEAT 0,<
TLO T1,400000 ;INDICATE UUO RATHER THAN COMMAND
>
MOVEM T1,.USUSN ;STORE 0 OR SECTION NUMBER FOR GETSEG
POPJ P, ;RETURN WITH .USUSN SET UP
SUBTTL SAVGET -- SAVE A JOB
;THIS JOB SAVES A JOB AREA ON RETRIEVABLE STORAGE
;THIS JOB RUNS IN EXEC MODE AND CALLS IO ROUTINES USING REGULAR UUOS
;NO ATTEMPT IS MADE TO SAVE STATUS OF IO DEVICES, JOBPDP, OR AC'S
;IN FACT THE ONLY USEFUL THING WHICH MAY BE DONE WITH A JOB AREA
;AFTER IT HAS BEEN SAVED IS TO START EXECUTION OVER AT THE STARTING
;ADDRESS
SAVJOB::JSP T2,SG1 ;SET UP ACS R,P,J, RESET DEVICES
PUSHJ P,CLRBTS ;CLEAR BITS
PUSH P,[0] ;STORE ZERO IN JOBPD1
; SO THAT SGRELE CAN
; TELL SAVE IS IN PROGRESS
PUSHJ P,RMVPFH##
PUSHJ P,ADJCOR## ;COMPUTE AMOUNT OF CORE FOR BOTH LO+HI SEGS
; FROM USER'S CORE ARG(IF ANY)
HLRE T2,.JDAT+SGADMP ;-NO. OF WORDS TO WRITE
PUSHJ P,CKIOWD ;CHECK USER'S CORE ARG(IF ANY) WITH AMOUNT TO WRITE
; RETURN ONLY IF 0 OR NOT SMALLER
HRRM T1,.JDAT+JOBCOR## ;STORE MAX OF SIZE OF FILE OR CORE ARG
; FOR ASSIGNING INITIAL CORE WHEN FILE GOTTEN
PUSHJ P,SGOPEN## ;OPEN THE DEVICE
MOVE T1,DEVMOD(F) ;DEVICE BITS
TLNE T1,DVTTY ;IF DVTTY IS ON, IT IS NUL:
PJRST SAVFIN ; SO WE'RE DONE
MOVSI T2,(JS.EXE) ;BIT WHICH SAYS SAVE IN EXE FORMAT
TLNE T1,DVDTA ;A DECTAPE ?
ANDCAM T2,JBTST2##(J) ;YES, SAVE IN THE OLD OFRMAT
PUSHJ P,CHKEXE ;EXE FILE SAVE?
JRST SAVEXE ;YES, GO TO SPECIAL CODE
PUSHJ P,SAVHGH## ;INIT DEV,SAVE HIGH SEG, IF ANY, RETURN IF OK
JRST SAVFIN ;HIGH SAVED, BUT NO DATA IN LOW SEG, SO DO
; NOT WRITE LOW FILE
; SKIP RETURN IF LOW SEG TO BE WRITTEN
; SGALEN, AND SGAEXT RESTORED
OPEN 0,SGAMOD ;RE INIT DEVICE, SO UGETF WILL SET FIRST FREE
; BLOCK BECAUSE NO LOOKUP OR ENTER DONE
JRST SGERRA ;DEVICE NOT AVAILABLE
SETZM .JDAT+SGADAT ;CLEAR DATE, SO GET TODAY FOR CREATION
UGETF 0,SGAHED ;TELL DECTAPE SERVICE TO START AT FRONT
MOVEI T1,-2 ;FLAG THAT CORE HAS BEEN COMPRESSED
HRLM T1,USRHCU## ;KEEP LH NEG. COMMAND DECODER WILL EXPAND
; CORE ON START ,DDT,SAVE, REENTER,SSAVE IN CASE
; THIS SAVE IO DOES NOT GO TO COMPLETION. (CONTROL C
; OR DEVICE FULL, SO THAT CORE DOES NOT GET EXPANDED)
ENTER 0,SGANAM ;ENTER FILE NAME IN DIRECTORY
JRST SAVERR ;DIRECTORY FULL OR PROTECTION FAILURE
MOVE T1,.JDAT+JOB41## ;SAVE USER UUO HANDLING JSR
MOVEM T1,.JDAT+JOBS41## ;IN UPPER PART OF JOB DATA AREA
SETZM .JDAT+JOBEXM## ;CLEAR MEMORY OF EXAMINE
SETZM .JDAT+JOBFDV## ;CLEAR MEMORY OF FIN
MOVE T1,.JDAT+JOBDDT## ;SAVE DDT STARTING ADDRESS HIGHER UP IN JOB DATA AREA
MOVEM T1,.JDAT+JOBSDD## ;SO COMPRESS ALWAYS MOVES CODE DOWN
HRRZ T3,.JDAT+JOBSA## ;SAV START ADDRESS FOR 10DMP
MOVEI T1,JOBSV## ;POINT TO 1ST DATA WORD
MOVEI T2,JOBSDD## ;IT STARTS AT JOBSDD
HLRE J,.JDAT+SGADMP ;IOWD FOR THIS SIZE CORE(-LENGTH TO WRITE)
MOVNS J ;POSITIVE LENGTH
ADDI J,JOBSVM## ;ADD IN FIRST LOC-1 TO WRITE=HIGHEST LOC TO WRITE
; TO MAKE END TEST
HLL J,T2 ;USE R FOR RELOCATION IF KA
CMPLP1: MOVEM T1,U ;SAVE 1ST LOC FOR IOWD
CAMLE T2,J ;SEARCH FOR 1ST NON-0 WORD
AOJA T1,CMPTHR ;THROUGH
EXCTUX <SKIPN @T2> ;THIS A DATA WORD?
AOJA T2,.-3 ;NO. KEEP LOOKING
MOVNI P1,1 ;YES. P1 WILL BE AN IOWD
HRLI P1,-1(T2) ;1ST LOCATION - 1
CMPLP2: EXCTUU <PUSH T1,@T2> ;SAVE A DATA WORD
AOS T2
CAMGE T2,J ;AT TOP?
EXCTUX <SKIPN @T2> ;NO. NEXT WORD NON-0?
JRST .+2 ;NO. THROUGH THIS BLOCK
SOJA P1,CMPLP2 ;COUNT THE WORD AND CHECK NEXT
EXCTUU <MOVSM P1,(U)> ;SAVE IOWD IN FRONT OF BLOCK
AOJA T1,CMPLP1 ;LOOK FOR NEXT NON-0 BLOCK
;HERE WHEN THE CORE IMAGE IS ZERO COMPRESSED
CMPTHR: HRLI T3,254000 ;SET A JRST C(JOBSA)
EXCTXU <MOVEM T3,-1(T1)> ;AT END OF FILE
SUBI T1,JOBSV## ;COMPUTE WORD COUNT
MOVNS T1 ;MAKE AN IOWD
HRL T1,.JDAT+SGADMP ;START ADDRESS
MOVSM T1,.JDAT+SGALEN ;IOWD FOR THE OUTPUT UUO
; ENTER USES NEGATIVE USRCHU TO SET RIBVER
PUSHJ P,SGDOA ;DO OUTPUT,RELEASE,FIND TTY
OUTPUT 0,SGALEN ;OUTPUT UUO EXECUTED BY SGDO
; RETURN HERE ONLY IF NO ERRORS
SAVFIN: MOVE J,.CPJOB## ;GET JOB NUMBER
MOVSI T1,(JS.EXE) ;GET EXE FILE STATUS BIT
ANDCAM T1,JBTST2##(J) ;CLEAR BIT IN JOB STATUS WORD
MOVSI T1,USRMOD ;USER-MODE BIT
TDNE T1,.JDAT+JOBPD1## ;WAS THIS A UUO?
JRST USVFIN ;YES, GO HANDLE
PUSHJ P,FNDPDS## ;FIND PDB
MOVE T1,.JDAT+SGANAM ;NAME WHICH WAS ENTERED
MOVEM T1,.PDNAM##(W) ;STORE
SETZM .PDSFD##(W) ;ZERO SFD INFO
MOVSI T1,.PDSFD##(W) ;SET UP A BLT TO CLEAR SFD STUFF
HRRI T1,.PDSFD##+1(W)
BLT T1,.PDSFD##+MAXLVL##-1(W)
MOVEI T1,JOBUAL##
MOVEM T1,.JDAT+SGAPPN
PUSHJ P,PTHFIL## ;GET PATH WHERE FILE WAS WRITTEN
PUSHJ P,NAMSTR## ;STR NAME
SKIPA T1,DEVNAM(F) ;NOT A DSK, DEVICE NAME
SKIPA T2,DEVPPN(F) ;GET DIRECTORY
MOVEI T2,0 ;NO DIRECTORY
MOVEM T1,.PDSTR##(W) ;STORE STR OR DEVICE NAME
MOVEM T2,.PDDIR##(W) ;DIRECTORY
MOVSI T1,.JDAT+JOBUAL##+3 ;WHRE THE SFD'S ARE STORED
HRRI T1,.PDSFD##(W) ;WHERE TO STORE PATH
BLT T1,.PDSFD##+MAXLVL##-1(W) ;STORE PATH
PUSHJ P,SGREL ;RELEASE DEVICE AND FIND TTY
MOVE T2,.JDAT+SGANAM ;GET JOB NAME
PUSHJ P,PRNAME ;PRINT IT
JSP T1,PHOLD## ;PRINT MESSAGE AND STOP JOB
ASCIZ / saved/
USVFIN: POP P,.PDTMC##(W) ;RESTORE VM LOCS
POP P,.PDTMI##(W)
PUSH P,.JDAT+JOBPD1## ;DUPLICATE RETURN ADDRESS
PUSH P,.JDAT+JOBPD1##+1 ;DITTO
AOS (P) ;INCREMENT
PUSHJ P,SGREL ;RELEASE DDB
MOVSI T1,.JDAT ;RESTORE USER ACS
EXCTXU <BLT T1,17> ;FROM SHADOW AREA
IFN FTMP,<
PUSHJ P,DPXST## ;SET UP PROPER RUNNABLE BITS FOR THIS JOB IN JBTSPS
>
JRST USRXIT## ;GIVE SKIP RETURN FOR UUO
SAVERR::MOVE J,.CPJOB## ;GET JOB NUMBER
PUSHJ P,CLRTAB ;CLEAR BITS AND TABLES
MOVSI T1,(JS.EXE) ;GET EXE FILE STATUS BIT
ANDCAM T1,JBTST2##(J) ;CLEAR BIT IN JOB STATUS WORD
TLO P1,GTSAV ;DON'T KILL HISEG IF GETARG ABORTS
MOVEM P1,.JDAT+SGAEND ;A SAFER PLACE TO BE
HRRZS USRHCU## ;CLEAR SAVE IN PROGRESS FLAG
MOVEI T1,PRTERR ;ERROR CODE IN CASE RUN UUO(PROTECTION ERROR)
PUSHJ P,SGRELL ;CHANGE TO DISK ENTER ERROR CODE IF DSK
; RELEASE DEVICE AND RETURN TO USER(IF RUN UUO)
; OR FIND TTY+PRINT ?CRLF
PJSP T1,LKENFL ;PRINT MESSAGE AND STOP JOB
ASCIZ /Enter error /
SUBTTL SAVGET -- "EXE" SAVE FILES
;THIS ROUTINE DOES A "SAVE" FOR USERS RUNNING
; UNDER A VIRTUAL MEMORY SYSTEM. THE SAVE FILE IS IN THE NEW FORMAT
; (I.E. A VARIABLE-LENGTH DIRECTORY AND A VARIABLE NUMBER OF
; FILE PAGES FOLLOWING IT).
;FLAG BITS USED IN THE LEFT HALF OF P1
SV%SAV==NSRBIT ;USER ISSUED AN "SAVE" COMMAND
;SV%SHR==(1B1) ;THIS BIT MEANS WE SAW A SHARABLE HIGH SEG.
;IT IS DEFINED IN S AND MUST NOT CHANGE
SV%FUL==:(1B2) ;USER HAD MAX ALLOWABLE CORE, PAGE WAS WRITTEN OUT
SV%PGO==(1B3) ;PHYSICAL LIMIT REACHED, PAGE WAS PAGED OUT
SV%DWO==:(1B4) ;DON'T WRITE OUT DIRECTORY (USED FOR 1ST PASS THRU DIR)
GT%DAF==:(1B5) ;DIRECTORY ALREADY FLUSHED (OCCURS IF
; THE LAST PAGE TO BE READ IN OVERWRITES THE
; DIRECTORY PAGE.)
GT%PLE==:(1B6) ;PHYSICAL LIMIT WAS EXCEEDED ON A GET
GTHGH==:(1B7) ;GET HIGH SEGMENT (PARAMETER TO GETNEW)
GTLOW==:(1B8) ;GET LOW SEGMENT (PARAMETER TO GETNEW)
GTBTH==:GTHGH+GTLOW ;GET BOTH HIGH AND LOW SEGMENTS
GT%GTH==:(1B9) ;A HIGH SEGMENT WAS FOUND AND READ IN (FOR VEST.
; JOB DATA AREA SET-UP)
GT%S1S==:(1B10) ;SAW A SHARABLE PAGE IN THE COURSE OF THIS GET
GT%DW1==:GT%S1S+SV%DWO+GT%GTH ;THESE BITS ARE CLEARED WHEN ROTATING DIRECTORIES
GTMRG==:(1B11) ;MERGE EXE FILE WITH CURRENT CORE IMAGE
GTSAV==:(1B12) ;DOING A SAVE (AS OPPOSED TO RUN, MERGE, OR GETSEG)
SV%DSK==:(1B13) ;PAGE REMOVED (SV%FUL) WAS ON DISK
GTSGO==:(1B14) ;DOING A SEGOP.
;IN SAVEXE, P1-P4 ARE USED FOR SCRATCH AC'S. THEIR CONTENTS ARE:
;
;P1 - LH=FLAGS
; RH=MOVING POINTER TO DIRECTORY PAGE
;
;P2 - LH=COUNTER OF # OF DIRECTORY PAGES
; RH=CURRENT FILE PAGE # FOR DIRECTORY ENTRY
;
;P3 - USED TO HOLD CURRENT PAGE #'S WHEN PASSING OVER THE PAGE MAP
;
;P4 - LH=ACCESS BITS OF THE PAGE (IF ANY) WHICH HAD
; TO BE WRITTEN OUT TO THE DISK TO MAKE ROOM FOR
; THE DIRECTORY PAGE. THESE BITS ARE SAVED BECAUSE
; THEY ARE NEEDED FOR THE DIRECTORY, BUT AT THAT TIME,
; THE PAGE WHICH THEY REPRESENT IS WRITTEN OUT
; AND CAN'T BE BROUGHT BACK IN UNTIL THE DIRECTORY IS
; RELEASED.
; RH = DISK ADDRESS OF PAGE WHICH WAS WRITTEN OUT, OR
; THE PAGE NUMBER OF A PAGE WHICH HAD TO BE PAGED OUT
; BECAUSE THE CREATION OF THE DIRECTORY CAUSED THE USER'S
; PHYSICAL LIMIT TO BE EXCEEDED.
;
;P4 (NON-VM ONLY) - SCRATCH AC
;
;
REPEAT 0,<
***** EXPLANATION OF THE NSAVE PROCESSING *****
The NSAVE processing is fairly straightforward with a couple
of exceptions. First, a free page is acquired and the
directory is created in it. Next, the directory is written
out and its core is released. Finally, the core image is
written out, one page at a time for the low seg, and in one
fell swoop for the high seg.
The only minor problem involved in the use of the directory
is that before the 1st entry is created, the length of the
entire directory must be known (in order to set the file
page # field). This is accomplished by creating the
directory as if it were one page long, but not actually
writing it out as it is being created. The end result of
this operation is a valid directory if it is one page long,
or the last page of the directory if it is more than one
page long. In the latter case, the current file page number
is adjusted to be one more than the length of the directory,
and the whole process is repeated with each directory page
being written out as it is created. This technique
penalizes only those wierdos with extremely long
directories.
Another problem occurs in VM systems when the user's core
image is sufficiently large that there are no available
pages to use as a directory. In this case a random page is
written to disk and deleted from the page map. The disk
address of the page is saved so the page can be read back in
later. Also, the directory access bits for the page are
computed and stored before the page is written out so that
it won't have to be read back in at the point when its
directory entry is being created.
The last problem in VM systems occurs when the user's
physical core limit will not allow the directory page to be
actually created. In such a case, a random page is
paged-out (as distinguished from the previous case) and the
directory is then created. If the second attempt to create
the directory page fails, a STOPCD results. This page is
then later paged back in so that user's may not go "virtual"
inadvertantly.
For all systems, zeroes are compressed on a page-by-page
basis. However, on non-VM systems, if the user's core image
is equal to CORMAX##, (i.e. there is no place to put a
directory), then the directory is created in the user's AC's
and zero-compression is not done. This implies that under
certain extreme conditions, an EXE file may vary greatly in
size depending upon the value of CORMAX.
>;END OF REPEAT 0
;
;COME HERE TO BEGIN THE SAVE OF A VM SYSTEM CORE IMAGE..
;WE MUST FIRST INIT THE DEVICE AND ENTER THE
; .EXE FILE IN THE USER'S DIRECTORY
;
SAVEXE: SKIPN T1,.JDAT+SGALOW ;GET USER EXTENSION, IF ANY
MOVSI T1,'EXE' ;SET UP EXTENSION OF "EXE"
MOVEM T1,.JDAT+SGAEXT ;STORE IN USER'S AREA
HRROS USRHCU## ;SET SAVE IN PROGRESS FLAG IN MONITOR
ENTER 0,SGANAM ;ENTER THE FILE-NAME IN THE DIRECTORY
JRST SAVERR ;ERROR, ABORT WITH ERROR MESSAGE
MOVSI P1,GTSAV ;SET UP TO GET FLAGS
HLRZ T1,.JDAT+SGAHGH ;GET EXTENSION SET UP BY SG3
CAIE T1,'SHR' ;WAS THIS A NSSAVE?
TLO P1,SV%SAV ;NO, SET NON-SHARABLE BIT
MOVEI T1,JBTSGN##-.HBLNK(J) ;SEARCH FOR SOME HIGH SEG
SAVEX1: HRRZ T1,.HBLNK(T1) ;NEXT SEGMENT
JUMPE T1,SAVEX3 ;NONE, FORGET CALL TO COPVJD
SKIPG J,.HBSGN(T1) ;IS THIS NOT A SPY SEG?
JRST SAVEX1 ;NO
PUSHJ P,COPVJD## ;COPY NUMBERS FROM JOBDAT TO VESTIGIAL JOBDAT
; (ONLY NECESSARY FOR GETSEG OF UNKNOWN SEGMENTS)
SAVEX3: SETZM .JDAT+SGAEXT ;NO PREVIOUS PAGE PAGED OUT
;FALL THRU TO NEXT PAGE.....
;WE MUST NOW SEARCH THRU THE USER'S PAGE MAP TO FIND A FREE
; PAGE THAT WE CAN USE AS THE DIRECTORY PAGE. IF WE FIND
; ONE, THEN THERE'S NO PROBLEM. HOWEVER, IF THE USER'S MAP
; IS FULL, WE MUST TEMPORARILY WRITE ONE OF THE USER'S
; PAGES OUT TO SECONDARY STORAGE AND USE THAT PAGE AS THE
; SCRATCH PAGE. EVEN IF WE FIND A FREE PAGE, WE MAY EXCEED
; THE USER'S PHYSICAL LIMIT BY ATTEMPTING TO CREATE IT, SO WE
; MAY HAVE TO PAGE OUT SOME OTHER PAGE IN ORDER TO CREATE
; THE DIRECTORY PAGE.
PUSHJ P,GETDRP ;GET DIRECTORY PAGE
JRST SVABRT ;CAN'T
;COME HERE WHEN WE HAVE FOUND A FREE PAGE TO USE AS THE DIRECTORY
PAGFRE: MOVE J,.CPJOB## ;JOB NUMBER
MOVSI T1,NSWP!NSHF ;GET LOCKED BITS
TDNN T1,JBTSTS##(J) ;JOB LOCKED?
JRST PAGFR1 ;NO
MOVEI T1,SNSERR ;GET LOCKED ERROR CODE
PUSHJ P,SGRELE ;RELEASE DEV, RETURN ERROR CODE IF UUO
PUSHJ P,EXONLY ;PRESERVE XO BIT
JSP T1,PHOLD## ;PRINT MESSAGE AND STOP JOB
ASCIZ / Illegal to save a locked core image/
PAGFR1: MOVE T1,CORMAX## ;GET MAX PHYSICAL LIMIT FOR SYSTEM
LSH T1,W2PLSH ;MAKE CORMAX INTO PAGE NUMBER
HRLI T1,EXESIZ*<MXSECN+1> ;MAKE HIM HAVE A VERY HIGH VIRTUAL LIMIT
PUSH P,.PDCVL##(W) ;REPLACE HIS NEW VIRTUAL LIMIT
PUSH P,.PDMVL##(W) ;AND SAVE HIS OLD ONE
MOVEM T1,.PDCVL##(W)
MOVEM T1,.PDMVL##(W)
MOVEI T1,EXESIZ*<MXSECN+1>
PUSH P,JBTCLM##(J)
DPB T1,JBYLCR##
PGFRE2: MOVE T1,P3 ;GET SAVED PAGE NUMBER
PUSHJ P,CRPAGE ;CREATE THE PAGE
SKIPA T1,[1] ;PHYS LIM EXCEEDED, START LOOKING
; FOR PAGE TO PAGE OUT AT PAGE 1.
JRST GOTDIR ;SUCCESS, WE HAVE OUR DIRECTORY
PGFRE3: PUSHJ P,PAGOUT ;TRY TO PAGE IT OUT
AOSA T1 ;BUMP PAGE #
JRST PGFRE4 ;OK
CAIE T1,EXESIZ*<MXSECN+1> ;THRU UPMP?
JRST PGFRE3 ;NO, KEEP GOING
STOPCD .,STOP,PGL, ;++PAGES GOT LOST
PGFRE4: TLOE P1,SV%PGO ;REMEMBER WE DID IT (DONE IT BEFORE?)
STOPCD .,STOP,PAO, ;++PAGE ALREADY OUT
DPB T1,[POINT PM.SAD,P4,<^L<PM.ADR>+PM.SAD-1>]
;SAVE PAGE # THAT WAS SENT OUT
JRST PGFRE2 ;TRY TO CREATE DIRECTORY AGAIN
;COME HERE WHEN WE HAVE CREATED THE DIRECTORY PAGE
GOTDIR: LSH P3,P2WLSH ;CONVERT TO ADDRESS
HRRI P1,1(P3) ;P1 POINTS TO 2ND WORD OF THE DIRECTORY
MOVEI P2,1 ;P2=DIR PAGE COUNT,,FILE PAGE #
TLO P1,SV%DWO ;DON'T ACTUALLY WRITE DIRECTORY, JUST COMPUTE IT
SETZ P3, ;START LOOKING AT PAGE 0 FOR USER'S PAGES
GOTDR2: PUSHJ P,MKNTRY ;MAKE A DIRECTORY ENTRY FOR THIS PAGE
JRST THRUDR ;DIRECTORY IS OVER, GO CHECK ITS LENGTH
AOJA P3,GOTDR2 ;MORE TO GO, GET NEXT PAGE #
;COME HERE WHEN THE DIRECTORY IS FINISHED
;IF THE DIRECTORY IS ONE PAGE LONG, THEN THE FULL DIRECTORY
; IS ALREADY SET UP AND READY TO BE OUTPUT. IF IT'S MORE THAN
; ONE PAGE LONG, ONLY THE LAST PAGE IS SET UP (WHICH OBVIOUSLY
; IS WORTHLESS NOW) AND NO PREVIOUS PAGES HAVE BEEN OUTPUT.
; IN THAT CASE, WE MUST GO THRU THE WHOLE PROCEDURE AGAIN,
; EXCEPT THIS TIME, WE WILL ACTUALLY WRITE OUT EACH PAGE
; AS WE GO.
THRUDR: MOVNI T1,EXESIZ
HRLM T1,.JDAT+SGALEN ;SET UP LENGTH
PUSHJ P,PUTSAB ;OUTPUT ENTRY VECTOR IF USER SPECIFIED A START ADDRESS
MOVE T1,[SV.END,,LN.END] ;STORE END BLOCK
PUSHJ P,PTDIRW ;..
TLZ P1,SV%DWO ;CLEAR "DON'T WRITE OUT" FLAG
HRRZ T1,P1 ;GET DIRECTORY POINTER
ANDI T1,EXESIZ-1 ;FIND OFFSET INTO LAST PAGE
HLRZ T2,P2 ;GET # OF DIR PAGES-1
LSH T2,P2WLSH ;FIND LENGTH OF PREVIOUS PAGES
ADD T1,T2 ;=TOTAL LENGTH OF DIRECTORY
SUBI T1,LN.END ;SUBTRACT LENGTH OF END-BLOCK
;**NOTE**IF NEW BLOCKS ARE ADDED TO
; THE FILE DIRECTORY, THEIR LENGTHS
; SHOULD BE SUBTRACTED HERE
SKIPE .USUSA ;A START ADDRESS SPECIFIED BY THE USER?
SUBI T1,LN.STA ;YES, ACCOUNT FOR THAT
HRLI T1,SV.DIR ;SET UP 1ST WORD OF DIRECTORY
TRZ P1,EXESIZ-1 ;SET POINTER TO TOP OF DIR PAGE
PUSHJ P,PTDIRW ;STORE IT AND BUMP POINTER
TLNN P2,-1 ;WERE THERE MORE THAN 1 DIR PAGE?
JRST RELDIR ;NO (HOORAY!), WE CAN JUST OUTPUT PAGE
HLRS P2 ;YES, SET FILE PAGE # TO BE THE
; 1ST PAGE AFTER THE DIRECTORY PAGES
AOS P2 ;MAKE IT ONE MORE THAN LAST DIR PAGE
TDZA P3,P3 ;START OVER AGAIN AT PAGE 0
THRU2: AOS P3 ;BUMP PAGE #
PUSHJ P,MKNTRY ;FORM A DIRECTORY ENTRY
CAIA ;THROUGH, OUTPUT DIRECTORY END BLOCK
JRST THRU2 ;LOOP UNTIL PAGE 777
PUSHJ P,PUTSAB ;OUTPUT ENTRY VECTOR IF USER SPECIFIED A START ADDRESS
MOVE T1,[SV.END,,LN.END] ;PUT OUT END BLOCK
PUSHJ P,PTDIRW ;STORE IN DIRECTORY
;FALL THRU TO NEXT PAGE...
;WE HAVE NOW FINISHED CREATING THE DIRECTORY.
;WE MUST GET RID OF THE DIRECTORY PAGE, RESTORE ANY
; PAGES THAT HAD TO BE WRITTEN OUT EARLIER,
; AND CREATE THE REST OF THE FILE.
RELDIR: TRZE P1,EXESIZ-1 ;IS THERE A PARTIAL PAGE LEFT TO OUTPUT?
PUSHJ P,PUTDIR ;YES, SEND IT OUT
HRRZ T1,P1 ;GET PAGE ADDRESS OF DIRECTORY
MOVE T2,DEVMOD(F) ;DEVICE CHARACTERISTICS
TLNE T2,DVDSK ;RANDOM ACCESS POSSIBLE?
TLNE P2,777776 ;DIRECTORY NO LONGER THAN ONE PAGE?
JRST RELDR6 ;MUST WRITE ONE PAGE AT A TIME
TLNE P1,SV%FUL ;A PAGE REMOVED FROM THE IMAGE TO MAKE ROOM FOR DIR?
TLNE P4,SV%ABZ ;YES, WAS IT JUST AN ABZ PAGE?
JRST RELDRX ;YES, CAN DO MULTIPLE PAGE WRITES
RELDR6: TLNN P4,SV%ABZ ;READ DIRECTORY INTO AN ABZ PAGE
JRST RELDR7 ;NO, JUST ZAP THE DIRECTORY PAGE
PUSHJ P,MAKABZ ;MAKE IT BACK INTO AN ABZ PAGE
JRST RELDR1 ;WRITE THE DATA TO THE FILE
RELDR7: HRRZ T1,P1 ;PAGE ADDRESS
PUSHJ P,ZAPPAG ;DESTROY IT
STOPCD RELDR9,DEBUG,DPN, ;++DIRECTORY PAGE NON-EXISTENT
TLNE P1,SV%FUL ;DID WE WRITE OUT A PAGE?
PUSHJ P,GTSAVP ;YES, GET IT BACK AGAIN
TLNN P1,SV%PGO ;DID WE HAVE TO PAGE OUT A PAGE?
; (WAS PHYS LIMIT EXCEEDED?)
JRST RELDR1 ;NO
LDB T1,[POINT PM.SAD,P4,<^L<PM.ADR>+PM.SAD-1>]
;YES, GET ITS PAGE #
PUSHJ P,PAGIN ;BRING IT IN
CAIA ;ERROR
JRST RELDR1 ;OK
RELDR9: POP P,JBTCLM##(J) ;
POP P,.PDMVL##(W)
POP P,.PDCVL##(W) ;RESTORE VIR,PHY LIMITS
JRST SVABRT ;I/O ERROR--ABORT
;SUBROUTINE TO OUTPUT AN ENTRY VECTOR BLOCK IF A START ADDRESS WAS SPECIFIED
; BY THE USER.
PUTSAB: SKIPN .USUSA ;A START ADDRESS SPECIFIED?
POPJ P, ;NO, NOTHING TO DO
MOVE T1,[SV.STA,,LN.STA] ;INDICATE ENTRY VECTOR BLOCK
PUSHJ P,PTDIRW ;STORE THAT
SKIPGE T1,.USUSA ;USER SPECIFY THE ADDRESS OF THE ENTRY VECTOR?
JRST PUTSA1 ;YES, USE THAT INSTEAD
MOVEI T1,(JRST) ;TRADITION
PUSHJ P,PTDIRW ;STORE THAT
MOVE T1,.USUSA ;STARTING ADDRESS
CAIN T1,1 ;IS IT S0 JOBDAT?
HRRZ T1,.JDAT+.JBSA## ;YES, FIX IT
PJRST PTDIRW ;END OF BLOCK
PUTSA1: LDB T1,[POINT 5,T1,5] ;GET LENGTH OF THE ENTRY VECTOR
PUSHJ P,PTDIRW ;STORE THAT
LDB T1,[POINT 30,.USUSA,35] ;GET ADDRESS OF ENTRY VECTOR
PJRST PTDIRW ;AND THAT TOO
;THIS IS THE MAIN LOOP FOR AN EXE FILE SAVE
;EACH PAGE IS WRITTEN OUT INDIVIDUALLY TO INSURE DEVICE AND
; SYSTEM COMPATABILITY
RELDR1: POP P,JBTCLM##(J)
POP P,.PDMVL##(W)
POP P,.PDCVL##(W) ;RESTORE VIR,PHY LIMITS
SETO P3, ;WE WILL START LOOKING AT PAGE 0
HRRZ J,JBTSGN##(J) ;NEWEST SEGMENT
JUMPE J,RELD1A ;?
SKIPLE J,.HBSGN(J) ;SKIP IF SPY SEG
PUSHJ P,SETHRL## ;YES, SET LH(JOBHRL)
RELD1A: MOVE J,.CPJOB## ;RESET J
RELDR2: AOS T1,P3 ;BUMP PAGE #
CAIL T1,EXESIZ*<MXSECN+1> ;TOP OF CORE IMAGE?
JRST [HRRZS USRHCU## ;YES, CLEAR SAVE IN PROGRESS FLAG
JRST SAVFIN] ; WE'RE FINALLY THRU!!!
PUSHJ P,CMPBIT ;COMPUTE DIRECTORY BITS
JRST RELDR2 ;NON-EXISTENT PAGE
TLNE T1,SV%ABZ ;ALLOCATED-BIT-ZERO?
JRST RELDR2 ;YES, DON'T SAVE IT
MOVE T1,P3 ;GET PAGE #
PUSHJ P,YANKIT ;BRING PAGE IN, IF IT'S OUT
JFCL ;SHOULDN'T BE ABZ
MOVE T1,P3 ;GET PAGE #
TLNN T2,(PA.AA) ;ACCESS ALLOWED?
PUSHJ P,SETAA ;NO, SET IT
MOVE T1,P3 ;GET PAGE NUMBER
LSH T1,P2WLSH ;CONVERT TO ADDRESS
HRRI T1,-1(T1) ;=START OF PAGE-1
HRRM T1,.JDAT+SGALEN ;STORE IN IOWD
PUSH P,P1 ;SAVE P1
IFN FTXMON,<
PUSH P,DEVISN(F) ;SAVE SECTION NUMBER FOR I/O
HLRZM T1,DEVISN(F) ;SET IT UP FOR THE OUTPUT
>
OUTPUT SGALEN ;WRITE OUT THIS PAGE
IFN FTXMON,<
POP P,DEVISN(F) ;RESTORE DEVISN
>
POP P,P1 ;RESTORE IT
PUSHJ P,SGIOCK ;CHECK FOR ERRORS
JRST RELDR2 ;NO, GO BACK FOR MORE
;HERE IF PAGES CAN BE WRITTEN A DIRECTORY ENTRIES WORTH AT A TIME
; I.E., NOT A MAGTAPE, NOT A MULTIPLE PAGE DIRECTORY, A PAGE DIDN'T
; HAVE TO BE DELETED FROM THE ADDRESS SPACE TO CREATE THE DIRECTORY
RELDRX: POP P,JBTCLM##(J) ;RESTORE LIMITS
POP P,.PDMVL##(W) ; ..
POP P,.PDCVL##(W) ; ..
HRRZ J,JBTSGN##(J) ;POINT TO NEWEST SEGMENT
JUMPE J,RELDX0
SKIPE J,.HBSGN(J) ;SEGMENT WORD
PUSHJ P,SETHRL## ;YES, INSURE JOBHRL IS CORRECT
RELDX0: MOVE J,.CPJOB## ;GET JOB NUMBER BACK
PUSHJ P,GTDIRW## ;GET DIRECTORY HEADER WORD
MOVEI P2,-1(T1) ;LENGTH OF DIRECTORY ENTRIES
RELDX1: PUSHJ P,GTDIRE## ;GET NEXT DIRECTORY ENTRY
JRST RELDX2 ;DONE
TRNN P3,-1 ;THIS ENTRY DESCRIBE ABZ PAGES?
JRST RELDX1 ;YES, DON'T WRITE THEM
HRRZ T1,P4 ;STARTING PAGE NUMBER
LSH T1,P2WLSH ;STARTING ADDRESS
LDB T2,[POINT 9,P4,8] ;REPEAT COUNT
ADDI T2,1 ;ACTUAL NUMBER OF PAGES
LSH T2,P2WLSH ;NUMBER OF WORDS TO WRITE
PUSHJ P,FSIOWD## ;MAKE AND STORE THE IOWD
PUSHJ P,WRSTUF## ;WRITE OUT THE PAGE(S)
JRST RELDX1 ;DO THE ENTIRE CORE IMAGE
RELDX2: HRRZS USRHCU## ;SAVE NO LONGER IN PROGRESS
HRRZ T1,P1 ;PAGE ADDRESS OF DIRECTORY
TLNE P1,SV%FUL ;WAS AN ABZ PAGE USED FOR THE DIRECTORY?
JRST RELDX3 ;YES, GO MAKE IT ONE AGAIN
PUSHJ P,ZAPPAG ;NO, JUST MAKE THE DIRECTORY PAGE GO AWAY
JFCL ;A STOPCD WOULDN'T REALLY HELP
JRST SAVFIN ;FINISH UP
RELDX3: LSH T1,W2PLSH ;PAGE NUMBER
S1PSHJ ZERPAG## ;MAKE IT BACK INTO AN "ABZ" PAGE
JRST SAVFIN ;AND FINISH UP
;SUBROUTINE TO GET A FREE PAGE FOR THE DIRECTORY
GETDRP::SKIPN VIRTAL## ;MUST BE ENOUGH VIRTUAL CORE TO CREATE 1 PAGE
JRST NEED1P## ;GIVE UP NOW
PUSHJ P,GTFREP ;TRY TO FIND A FREE PAGE
SKIPA P3,[XWD 0,PG.BDY] ;COULDN'T, START AT PAGE 777
SKIPA P3,T1 ;GOT ONE, PUT NUMBER IN P3
SKIPA J,.CPJOB## ;SET UP JOB NUMBER
JRST CPOPJ1## ;GIVE GOOD RETURN
SAV2: MOVE T1,P3 ;GET THE PAGE #
JUMPE P3,NEED1P## ;IF IT'S PAGE 0, WE LOSE
PUSHJ P,CMPBIT ;COMPUTE THE SAVE-FILE BITS FOR THIS PAGE
PUSHJ P,BRCSTP ;ISSUE FATAL STOPCD IF NON-EXISTENT
TLNE T1,SV%HIS ;DON'T USE A HIGH SEGMENT PAGE
SOJA P3,SAV2 ;DECREMENT PAGE #
HLLZ P4,T1 ;SAVE THESE BITS FOR LATER
HRRZ T1,P3 ;GET THE PAGE #
PUSH P,P3 ;SAVE P3
SETZ P3, ;FLAG NOT REALLY IPCF
MOVE R,JBTADR##(J) ;FOR DCUPR (THE ENTER ABOVE CLOBBERED R AND J)
PUSHJ P,IPCRMV## ;REMOVE PAGE FROM LOG. ADR. SPACE
JRST P3POPJ## ;RESTORE P3 AND RETURN
TLNE T2,IP.DSK##_-^D18 ;DISK PAGE?
TLO P1,SV%DSK ;YES
POP P,P3 ;RESTORE P3
TLNE P4,SV%ABZ ;PAGE ALLOCATED BUT ZERO?
JRST [PUSHJ P,IPCDLX## ;YES, JUST DELETE IT (REAPPEAR IT LATER)
JRST SAV3] ;AND PROCEED
PUSHJ P,IPCPAG## ;WRITE PAGE OUT (RETURN WITH T2=PAGE #
; OR DISK ADDRESS)
POPJ P, ;ERROR
SAV3: DPB T2,[POINT PM.SAD,P4,<^L<PM.ADR>+PM.SAD-1>]
;SAVE ADDRESS WHERE WE PUT IT ON DISK
TLO P1,SV%FUL ;REMEMBER THAT WE DID THIS
JRST CPOPJ1## ;RETURN
;SUBROUTINE TO PERFORM A PAGE. UUO
;CALL:
; MOVE T1,[FUNCTION CODE,,0]
; MOVE T2,PAGE #
; PUSHJ P,PAGUUO
; RETURN HERE IF ERROR RETURN FROM PAGE. UUO
; GOOD RETURN
;
;
;ON EXIT, T1 CONTAINS THE PAGE NUMBER
PAGUUO::MOVEI T3,1 ;LENGTH OF THE ARGUMENT BLOCK
PAGUUN::PUSHJ P,SAVE4## ;SAVE P1-P4
PUSH P,T2 ;SAVE PAGE # TO RETURN TO CALLER
HRRI T1,SGASAV+1 ;POINT TO ARGUMENT BLOCK
PUSH P,.JDAT+SGAHGH ;SAVE SGAHGH
PUSH P,.JDAT+SGANEW ; AND SGANEW
MOVEM T2,.JDAT+SGAHGH ;STORE PAGE NUMBER FOR UUO
MOVEM T1,.JDAT+SGASAV ;STORE IN USER AREA
MOVEM T3,.JDAT+SGANEW ;STORE LENGTH OF ARGUMENT BLOCK
PAGE. SGASAV, ;DO THE UUO
SOS -3(P) ;ERROR
POP P,.JDAT+SGANEW
POP P,.JDAT+SGAHGH
MOVE F,USRJDA##+0 ;IOWAIT CLOBBERS F
JRST TPOPJ1## ;RESTORE PAGE # AND RETURN
;SUBROUTINE TO SET ACCESS ALLOWED BIT FOR PAGE
; (BIT MUST BE OFF)
;CALL:
; MOVE T1,PAGE#
; PUSHJ P,SETAA
; HERE ALWAYS
SETAA: HRRZ T2,T1 ;MOVE PAGE #
MOVSI T1,.PAGAA ;GET FUNCTION CODE
PUSHJ P,PAGUUO ;DO THE PAGE UUO
STOPCD CPOPJ##,DEBUG,CSA, ;++CAN'T SET ACCESS ALLOWED
POPJ P,
;SUBROUTINE TO PAGE OUT THE USER'S LOW SEGMENT ON A GETSEG
;THIS IS ONLY CALLED IF THE CURRENT USER IS "VIRTUAL".
;
;CALL:
; PUSHJ P,PAGLOW
; HERE ALWAYS
;
PAGLOW::MOVEI T1,1 ;START AT PAGE 0
PUSH P,F ;PAGOUT CLOBBERS F
PGLOW2: TRNE T1,HLGPNO ;WRAP A SECTION BOUNDARY?
JRST PGLOW4 ;YES
LSH T1,P2SLSH ;CONVERT TO SECTION #
PGLOW5: CAILE T1,MXSECN ;OVER THE TOP?
JRST FPOPJ##
SKIPE T4,.UPMP+SECTAB(T1) ;GET SECTION POINTER
TLNE T4,(<<PM.DCD^!PM.ACD>B2>) ;IS THIS AN INDEPENDENT SECTION?
AOJA T1,PGLOW5 ;NO, TRY NEXT SECTION
LSH T1,S2PLSH ;SECTION OK, PROCEED
PUSHJ P,SCDCHK## ;GIVE OTHER PEOPLE A CHANCE
PGLOW4: S1PSHJ GTPME## ;GET THE MAP ENTRY
JUMPE T2,PGLOW3 ;IF NON-EXISTENT, JUMP
PUSHJ P,CKDIRP ;IS THIS A DIR PAGE?
AOJA T1,PGLOW2 ;YES, DON'T PAGE IT OUT
PUSHJ P,PAGOUT ;TRY TO PAGE THIS PAGE OUT
JFCL ;COULDN'T
AOJA T1,PGLOW2 ;GET NEXT PAGE
PGLOW3: SKIPN .USREL ;DOES HE HAVE A NON-CONTIGUOUS CORE IMAGE?
PJRST FPOPJ## ;NO, WE MUST HAVE COME TO END OF LOW SEG
AOJA T1,PGLOW2 ;NO
;SUBROUTINE TO MAKE A SINGLE DIRECTORY ENTRY FOR A GIVEN PAGE
;CALL:
; MOVE P1,DIRECTORY POINTER
; MOVE P2,CURRENT FILE PAGE #
; MOVE P3,PAGE #
; PUSHJ P,MKNTRY
; RETURN HERE IF PAGE # IS TOO HIGH (.GTE. PAGSIZ)
; RETURN HERE OTHERWISE
;
;THIS ROUTINE EXPECTS THE "LAST" DIRECTORY ENTRY TO BE IN
; T3 AND T4. IT COMPUTES THE DIRECTORY FOR THE PAGE # IN P3,
; AND DETERMINES IF THIS NEW PAGE CAN BE INCLUDED IN THE
; DIRECTORY ENTRY FOR THE LAST GROUP OF PAGES. IF SO,
; THE REPEAT COUNT (IN T4) IS BUMPED AND CONTROL IS RETURNED.
; IF THIS PAGE NEEDS A NEW ENTRY, THE "OLD" ENTRY IS OUTPUT
; TO THE DIRECTORY, THE CURRENT FILE PAGE NUMBER IS UPDATED,
; AND THE NEW DIRECTORY ENTRY REPLACES THE OLD ONE IN T3,T4
;
;
MKNTRY: CAIL P3,EXESIZ*<MXSECN+1> ;TOO HIGH?
JRST NEWENT ;YES, OUTPUT LAST ENTRY AND EXIT
PUSHJ P,CMPBIT ;COMPUTE FLAG BITS FOR THIS PAGE
JRST CPOPJ1## ;NON-EXISTENT PAGE, EXIT AND IGNORE
JUMPE P3,[MOVE T3,T1 ;IF THIS IS THE 1ST PAGE,..
SETZ T4, ;MAKE IT THE LAST PAGE
JRST CPOPJ1##]
;PLEASE NOTE---THIS LAST CHECK ASSUMES
;THAT PAGE ZERO IS THE 1ST PAGE CHECKED.
;IF THIS IS NOT TRUE (I.E. IF THE DIRECTORY
; IS FORMED BY STARTING WITH PAGE 777
; AND PROCEDING BACKWARDS), THEN THIS
; ALGORITHM MUST BE CHANGED.
LDB T2,[POINT 9,T4,8] ;GET LAST REPEAT COUNT
CAIE T2,777 ;END OF REPEAT COUNT?
CAME T1,T3 ;ARE THE FLAG BITS THE SAME AS THE LAST PAGE
JRST NEWENT ;NO, FORM A NEW DIR ENTRY
ADDI T2,1(T4) ;FIND # OF NEXT CONTIGUOUS PAGE
CAME T2,P3 ;IS THIS IT?
JRST NEWENT ;NO, FORM A NEW ENTRY FOR THIS PAGE
ADD T4,[1000,,0] ;YES, BUMP LAST REPEAT COUNT
JRST CPOPJ1## ;RETURN
;COME HERE TO FORM A NEW DIRECTORY ENTRY
NEWENT: TLZE T3,SV%ABZ ;ALLOCATED BUT ZERO PAGE?
JRST NWENT2 ;YES
HRR T3,P2 ;NO, GET CURRENT FILE PAGE #
LDB T2,[POINT 9,T4,8] ;GET LAST REPEAT COUNT
ADDI P2,1(T2) ;COMPUTE NEW FILE PAGE #
NWENT2: HRRZ T2,P3 ;GET THIS PAGE #
EXCH T1,T3 ;GET 1ST WORD OF LAST ENTRY
EXCH T2,T4 ;GET 2ND WORD
PUSHJ P,PTNTRY ;STORE IT IN DIRECTORY
CAIGE P3,EXESIZ*<MXSECN+1> ;LAST PAGE?
AOS (P) ;NO, SKIP RETURN
POPJ P, ;YES, GIVE NON-SKIP RETURN
;SUBROUTINE TO PAGE OUT A PAGE
;CALL:
; MOVE T1,PAGE #
; PUSHJ P,PAGOUT
; HERE IF CAN'T PAGE IT OUT
; HERE IF CAN AND DID
;
;T1 IS PRESERVED
PAGOUT::MOVE J,.CPJOB## ;JUST FOR SAFETY
LDB T2,[POINT 9,.JDAT+.JBPFH##,26] ;GET STARTING PAGE OF PFH
SKIPE .JDAT+.JBPFH ;IF NO PFH, OR
CAIGE T1,(T2) ;THIS PAGE IS BELOW PFH'S STARTING PAGE
JRST PAGOU0 ;WE'RE SAFE, PAGE THIS ONE OUT
LDB T2,[POINT 9,.JDAT+.JBPFH##,26] ;GET ENDING PAGE OF PFH
CAIG T1,(T2) ;IS PAGE WE WANT PAST PFH?
POPJ P, ;NOPE - THIS PAGE HAS PFH, ERROR RETURN
PAGOU0: PUSH P,T1 ;SAVE PAGE #
HRRZ T1,.JDAT+JOBINT##;GET ADDRESS OF JOBINT BLOCK
HRRZI T2,3(T1) ;END ADDRESS OF JOBINT BLOCK
TRZ T1,PG.BDY ;MAKE START ADDRESS A PAGE BOUNDARY
LSHC T1,W2PLSH ;CONVERT BOTH TO PAGE NUMBERS
CAME T1,(P) ;IS START PAGE OF JBINT BLOCK IN THIS PAGE?
CAMN T2,(P) ;IS END OF JBINT BLOCK IN PAGE?
JRST TPOPJ## ;ERROR RETURN
MOVE T1,(P) ;GET PAGE WE WANT TO PAGE OUT
PUSHJ P,PSIIVR## ;FIND RANGE OF PAGES FOR PSI VECTOR
HLRZ T2,T1 ;GET ENDING PAGE
TLZ T1,-1 ;MAKE IT STARTING PAGE ONLY
CAML T1,0(P) ;ARE WE BELOW RANGE OF PSI VECTOR
CAMLE T2,0(P) ;OR ABOVE IT?
SKIPA T1,0(P) ;WE ARE GOLDEN, GET PAGE FOR GETPAG
JRST TPOPJ## ;PAGE CONTAINS PSI VECTOR, LEAVE IT ALONE
PUSHJ P,GETPAC## ;GET PAGE ACCESSABILITY
TLNE T1,(PA.CPO!PA.NXP!PA.OUT) ;CAN IT BE PAGED OUT?
JRST TPOPJ## ;NO, RESTORE T1 AND EXIT
MOVE T2,(P) ;GET PAGE #
TLO T2,(1B0) ;SET DESTORY BIT
MOVSI T1,.PAGIO ;GET FUNCTION CODE
PUSHJ P,PAGUUO ;DO THE UUO
JRST TPOPJ## ;I/O ERROR
JRST TPOPJ1## ;IT'S OUT
;SUBROUTINE TO PAGE IN A PAGE
;CALL:
; MOVE T1,PAGE #
; PUSHJ P,PAGIN
; ERROR RETURN
; OK RETURN
PAGIN:: PUSH P,T1 ;SAVE PAGE #
HRRZ T1,.PDCVL##(W) ;GET USER'S PHYSICAL LIMIT/GUIDELINE
LDB T2,IMGIN## ;AND HOW MANY PAGES ARE IN CORE
TRZ T1,400000 ;CLEAR LIMIT BIT
SKIPN .JDAT+SGAEXT ;PAGE PREVIOUSLY PAGED OUT?
CAML T2,T1 ;EXCEEDING LIMIT?
JRST PAGIN2 ;YES. GO PAGE OUT A PAGE
PAGIN1: POP P,T2 ;GET PAGE #
MOVSI T1,.PAGIO ;GET FUNCTION CODE
PUSHJ P,PAGUUO ;PAGE. UUO
SKIPA T2,.JDAT+SGASAV ;SOMETHING HAPPENED, GET THE ERROR
; CODE WHICH WAS RETURNED IN USER AC'S
JRST [MOVEM T1,.JDAT+SGAEXT ;SAVE LAST PAGE PAGED OUT FOR NEXT TIME
JRST CPOPJ1##] ;AND INDICATE SUCCESS
CAIE T2,PAGLE% ;LIMIT EXCEEDED IS OK
POPJ P, ;ANYTHING ELSE IS FATAL
PUSH P,T1 ;SAVE PAGE-IN PAGE #
PAGIN2: SKIPN T1,.JDAT+SGAEXT ;GET LAST PAGE PAGED OUT IF ONE HAS BEEN
MOVEI T1,1 ;TRY TO PAGE OUT SOME PAGES
PAGIN3: PUSHJ P,CKDIRP ;A DIRECTORY PAGE?
CAIA ;YES, CAN'T PAGE IT OUT
PUSHJ P,PAGOUT ;TRY TO PAGE IT OUT
JRST [CAIE T1,EXESIZ*<MXSECN+1>-1 ;THRU ALL PAGES?
AOJA T1,PAGIN3 ;NO, TRY AGAIN
SETZM .JDAT+SGAEXT ;NO PREVIOUS PAGE PAGED OUT
JRST PAGIN1] ;YES, FATAL ERROR
POP P,T1 ;GET PAGE BACK
SETZM .JDAT+SGAEXT ;LOOK AT ALL PAGES AS CANDIDATES
JRST PAGIN ;TRY AGAIN TO PAGE IT IN
;ROUTINE TO READ IN A PAGE THAT HAD TO BE OUTPUT EARLIER
;CALL:
; MOVE P4,DISK-ADDRESS-OF-PAGE
; MOVE P1,PAGE-ADDRESS
; PUSHJ P,GTSAVP
; RETURN HERE ALWAYS IF OK
GTSAVP::HRRZ T1,P1 ;GET PAGE ADDRESS
LSH T1,W2PLSH ;MAKE INTO A PAGE NUMBER
LDB T2,[POINT PM.SAD,P4,<^L<PM.ADR>+PM.SAD-1>]
TLNE P1,SV%DSK ;WAS IT A DISK ADR?
TLO T2,IP.DSK##_-^D18 ;YES
PUSHJ P,IPCINS## ;CREATE PAGE
CAIA ;ERROR OF SOME SORT
POPJ P,
CAIE T1,IPCUP%## ;DUPLICATE PAGE?
STOPCD CPOPJ##,DEBUG,DPL ;++DIRECTORY PAGE LOST
TLZN T2,IP.DSK##_-^D18 ;DISK PAGE?
PJRST DLTPGC## ;NO, JUST DELETE PAGE IN CORE
PUSHJ P,ONPOQ## ;ON OUT QUEUE (CAN'T BE ON IP QUEUE)?
PJRST DLTPGD## ;NO, JUST RETURN DISK SPACE
SSX T4,MS.MEM ;CLEAR MEMTAB
SE1XCT <SETZM MEMTAB(T4)>
PJRST DLTPGD##
;SUBROUTINE TO GET A FREE PAGE FROM USER'S PAGE MAP
;CALL:
; PUSHJ P,GTFREP
; HERE IF COULDN'T
; HERE IF DID, PAGE # IN T1
;
;IF THIS ROUTINE IS ENTERED AT GTFREP, IT WILL START SEARCHING
; AT PAGE 777.
;IF ENTERED AT GTFRE2, IT WILL START SEARCHING AT THE PAGE # IN T1.
;
GTFREP::MOVEI T1,PG.BDY ;START AT PAGE 777
SE1ENT
GTFRE1: PUSHJ P,GTPME## ;GET MAP ENTRY
JUMPE T2,CPOPJ1## ;IF NON-EXISTENT, ITS OK
SOJG T1,GTFRE1 ;DECREMENT PAGE # AND TRY AGAIN
POPJ P, ;COULDN'T
;SUBROUTINE TO CHECK IF A GIVEN PAGE IS A DIRECTORY PAGE
;CALL:
; MOVE T1,PAGE #
; PUSHJ P,CKDIRP
; HERE IF THIS PAGE IS A DIRECTORY
; HERE IF NOT
;
;ON RETURN, T3 POINTS TO WHERE THE DIRECTORY PAGE
; POINTER IS BEING KEPT (P1, SGANAM, OR SGAEXT)
;T1,T4 PRESERVED
;T2 DESTROYED
CKDIRP::JUMPE P1,CPOPJ1## ;NOT A DIRECTORY PAGE IF FROM PAGIA
PUSH P,T1 ;SAVE PAGE NUMBER
LSH T1,P2WLSH ;MAKE INTO AN ADDRESS
HRRZ T2,P1 ;GET CURRENT DIRECTORY POINTER
TRZ T2,PG.BDY ;CLEAR OFFSET
MOVEI T3,P1 ;ASSUME ITS' THERE
CAMN T1,T2 ;IS THIS A DIR PAGE?
JRST TPOPJ## ;YES, RESTORE PAGE # AND EXIT
JRST TPOPJ1## ;NOT A DIRECTORY PAGE
;SUBROUTINE TO PAGE IN A PAGE, IF IT'S OUT
;CALL:
; MOVE T1,PAGE #
; PUSHJ P,YANKIT
; RETURN HERE IF PAGE ALLOCATED BUT ZERO (T1=PAGE NUMBER)
; RETURN HERE WITH PAGE BITS IN T2
YANKIZ::SETZM .JDAT+SGAEXT ;NO PREVIOUS PAGE PAGED OUT
YANKIT::PUSH P,T1 ;SAVE PAGE BITS
PUSHJ P,GETPAC## ;GET PAGE BITS
MOVE T2,T1 ;MOVE BITS
POP P,T1 ;GET PAGE # BACK
TLNE T2,(PA.ZER)
POPJ P,
PUSH P,T2 ;SAVE BITS
TLNE T2,(PA.OUT) ;IS IT OUT?
PUSHJ P,PAGIN ;YES, BRING IT IN
JFCL ;NOT OUT
JRST T2POJ1## ;RESTORE PAGE BITS
;SUBROUTINE TO GET A PAGE INTO CORE AND MAKE IT ACCESSIBLE
;CALL:
; MOVE T1,PAGE #
; PUSHJ P,PAGIA
; HERE ON FAILURE
; HERE ON SUCCESS, PAGE IS IN CORE WITH ACCESS ALLOWED ON
;SETS WS SCRAMBLED BIT IF IT DOES ANYTHING, WORRYS ABOUT LIMITS
PAGIA:: PUSHJ P,SAVE2## ;SAVE WORKING ACS
MOVEI P1,.USUAC ;SAVE USER ACS SINCE
EXCTUX <BLT P1,.USUAC+17> ; PAGE UUO WILL CLOBBER THEM
HRRZ P2,T1 ;PAGE TO DOITTOIT
PUSHJ P,GETPAC## ;GET PAGE ACCESSIBILITY
TLNN T1,(PA.OUT) ;PAGE OUT?
JRST PAGIA1 ;NO, THEN THIS IS SIMPLIER
SETZB P1,.JDAT+SGAEXT ;FOR CKDIRP, ALSO NO PREVIOUS PAGE PAGED OUT
HRRZ T1,P2 ;PAGE NUMBER
PUSHJ P,PAGIN ;GO PAGE IT IN
JRST [SOS (P) ;SIGH, SET FOR FAIL RETURN
SETZ P2, ;SINCE WORKING SET HAS NOT CHANGED
JRST PAGIA2] ;RESTORE USER ACS AND RETURN
TLO P2,400000 ;REMEMBER THAT THE WORKING SET HAS BEEN DIDDLED
PUSHJ P,GETPAC## ;GET CURRENT ACCESSIBILITY
PAGIA1: TLNE T1,(PA.AA) ;ACCESS ALLOWED ON?
JRST PAGIA2 ;YES, THEN ESSENTIALLY DONE
HRRZ T1,P2 ;NO, GET PAGE NUMBER AGAIN
PUSHJ P,SETAA ;TURN ON AA
TLO P2,400000 ;AND INDICATE WS HAS CHANGED
PAGIA2: MOVSI T1,.USUAC ;RESTORE USER ACS
EXCTXU <BLT T1,17>
JUMPGE P2,CPOPJ1## ;JUMP IF LENGTHY NOOP
MOVSI T1,(UP.WHC!UP.WSS) ;NOTE CHANGE IN WORKING SET FOR PFH
IORM T1,.USBTS ;SO IT DOESN'T GET CONFUSED
JRST CPOPJ1## ;GOOD RETURN
;SUBROUTINE TO CREATE A SECTION
;CALLING SEQUENCE:
; PUSHJ P,CRESSN
; ...ERROR RETURN
; SECTION CREATED
CRESSN::MOVE T2,.USUSN ;SECTION TO CREATE
LSH T2,P2SLSH ; ..
REPEAT 0,<
CAIG T2,1 ;*** HACK
JRST CPOPJ1## ;SECTION ZERO OR SECTION 1 HACK
TRZ T2,400000_-P2WLSH ;CLEAR SET BY UUO BIT
>
JUMPE T2,CPOPJ1##
MOVSI T1,.PAGCS ;***
PJRST PAGUUO ;DO IT
;ROUTINE TO COMPUTE THE FLAG BITS FOR THE DIRECTORY ENTRY
;CALL:
; MOVE P3,PAGE #
; PUSHJ P,CMPBIT
; RETURN HERE IF PAGE WAS NON-EXISTENT
; RETURN HERE OTHERWISE
;
;ON RETURN, T1 WILL HAVE THE FLAG BITS SET UP PRECISELY AS THEY
; SHOULD APPEAR IN THE DIRECTORY ENTRY (I.E. IN THE LEFT-MOST BITS)
;IF THE PAGE IS ALLOCATED-BUT-ZERO, THE "SV%ABZ"
; BIT WILL BE SET ALSO.
; THIS BIT IS LATER TRANSFORMED INTO A FILE PAGE NUMBER OF ZERO.
;
;NOTE THAT THE DIRECTORY PAGE IS TREATED AS BEING
; NON-EXISTENT, EXCEPT IN NON-VM SYSTEMS WHEN
; WE ARE NOT ZERO-COMPRESSING (THE DIRECTORY IS USER AC'S).
CMPBIT: PUSH P,T3 ;SAVE T3 (T3 AND T4 ARE CURRENT DIRECTORY ENTRY)
PUSH P,T4 ;SAVE T4
MOVE T1,P3 ;GET PAGE #
PUSHJ P,GETPAC## ;GET PAGE MAP ACCESSABILITY BITS
MOVE T2,T1 ;SAVE BITS
POP P,T4 ;RESTORE OLD DIR ENTRY
POP P,T3
IFN FTXMON,<
TRNN P3,PG.BDY ;FIRST PAGE OF A NEW SECTION?
TLNN T2,(PA.NXS+PA.IND) ;YES, PAGE IN A NON-EXISTANT SECTION?
CAIA ;NO TO EITHER
JRST [ADDI P3,PG.BDY ;YES, SKIP THIS SECTION
POPJ P,] ;RETURN SAYING NON-EXISTANT PAGE
>
IFN FTPEEKSPY,<
TLNN T2,(PA.GSP) ;A SPY PAGE? IF SO TREAT AS NON EX
>
TLNE T2,(PA.NXP) ;PAGE EXIST?
POPJ P, ;NO, EXIT
SETZ T1, ;CLEAR BITS FOR ENTRY
TLNE T2,(PA.WRT) ;CAN IT BE WRITTEN?
TLO T1,SV%WRT ;YES, SET BIT
TLNE T2,(PA.ZER) ;ALLOCATED BUT ZERO?
TLO T1,SV%ABZ ;YES, SET THAT BIT IN FLAGS
TLNN T2,(PA.GHI) ;PAGE IN A HIGH SEGMENT?
JRST CMP2 ;ITS NOT IN THE HIGH SEG
TLO T1,SV%HIS ;SET HISEG BIT
TLNN P1,SV%SAV ;WAS THIS AN "SAVE" COMMAND?
TLO T1,SV%SHR ;NO, SET SHARABLE BIT TOO
MOVEI T2,JS.XO ; AND EXECUTE ONLY BIT
TDNE T2,JBTSTS##(J) ;IS IT SET?
TLO T1,SV%CON ;YES, MUST BE CONCEALED
JRST CPOPJ1## ;RETURN SINCE DIR CAN'T BE IN HIGH SEG
CMP2: TLNN T1,SV%ABZ ;SKIP CALL IF WE ALREADY KNOW THIS
PUSHJ P,CHKABZ ;IS THIS PAGE ALL ZEROES?
TLO T1,SV%ABZ ;YES, SET BIT
HRRZ T2,P1 ;GET ADDRESS OF DIRECTORY PAGE
LSH T2,W2PLSH ;CONVERT TO PAGE #
CAIE T2,(P3) ;IS THIS THE DIRECTORY PAGE?
JRST CPOPJ1## ;NO, RETURN TO CALL+2
TLNN P1,SV%FUL ;YES, DID WE HAVE TO WRITE OUT
POPJ P, ; A PAGE EARLIER?..EXIT IF NO
; AND TREAT THE DIRECTORY PAGE AS NON-EXISTENT
HLLZ T1,P4 ;YES, GET SAVED BITS FOR WRITTEN-OUT
JRST CPOPJ1## ; AND EXIT AS IF THIS WERE THAT PAGE
;COME HERE FOR A VARIETY OF USER SINS
GTABRT::
SVABRT: MOVE J,.CPJOB## ;GET JOB NUMBER
MOVSI T1,(JS.EXE) ;GET EXE SAVE FILE BIT
ANDCAM T1,JBTST2##(J) ;CLEAR IT
MOVSI T1,USRMOD ;GET USER-MODE BIT
TDNN T1,.JDAT+JOBPD1## ;UUO?
JRST SVABRU ;NO, DON'T RESTORE
POP P,.PDTMC##(W) ;YES, RESTORE VM LOCS
POP P,.PDTMI##(W)
SVABRU: HRRZS USRHCU## ;CLEAR SAVE IN PROGRESS FLAG
MOVEI T1,TRNERR ;GET APPROPRIATE ERROR CODE
PUSHJ P,SGRELE
JSP T1,PHOLD##
ASCIZ .I/O error for EXE file.
;COME HERE IF A BAD RETURN FROM "CMPBIT" OCCURED:
BRCSTP: STOPCD SAVERR,DEBUG,BRC, ;++BAD RETURN FROM CMPBIT
;ROUTINE TO CHECK IF THIS USER IS TRYING TO SAVE A NEW-STYLE (.EXE)
; SAVE FILE
;
;CALL:
; MOVE J,JOB-NUMBER
; PUSHJ P,CHKEXE
; HERE IF YES
; HERE IF NO
;
;ALL AC'S PRESERVED
;
CHKEXE::PUSH P,T1 ;SAVDDL NEEDS T1 SAVED
MOVE T1,JBTST2##(J) ;GET JOB STATUS WORD
TLNE T1,(JS.EXE) ;IS THE "EXE" BIT SET? (WHICH
; MEANS THAT WE ARE DOING A
; SAVE OF AN EXE FILE)
JRST TPOPJ## ;YES, RESTORE T1 AND EXIT
JRST TPOPJ1## ;NO, EXIT AT CALL+2
;SUBROUTINE TO CHECK IF A PAGE IS ALL ZEROES TO ENABLE IT
; TO BE COMPRESSED
;CALL:
; MOVE P3,PAGE # TO CHECK
; PUSHJ P,CHKABZ
; RETURN HERE IF PAGE IS ALL ZEROES
; HERE OTHERWISE
;
; T2 IS DESTROYED
;
CHKABZ: PUSH P,T1 ;SAVE T1
PUSH P,T3 ;PRESERVE
PUSH P,T4 ;OLD ENTRY
MOVE T1,P3 ;SET PAGE #
PUSHJ P,YANKIT ;IF OUT, BRING IT IN
JRST [POP P,T4 ;RESTORE OLD ENTRY
POP P,T3
JRST TPOPJ##] ;ABZ
TLNN T2,(PA.AA)
PUSHJ P,SETAA
POP P,T4 ;RESTORE OLD ENTRY
POP P,T3
POP P,T2 ;GET T1 BACK, CAN'T CALL CO-ROUTINES WITH IN ON THE STACK
IFN FTXMON,<
MOVE T1,P3 ;PAGE NUMBER
LSH T1,P2SLSH ;SECTION NUMBER
JUMPE T1,ABZ1 ;DON'T BOTHER WITH THIS FOR SECTION 0
PUSHJ P,SVPCS## ;SAVE PCS, SET IT TO SECTION CURRENTLY BEING SAVED
SE1ENT ;ENTER SECTION 1
>
ABZ1: MOVE T1,T2 ;RESTORE SAVED T1
MOVE T2,P3 ;FETCH PAGE #
LSH T2,P2WLSH ;MAKE INTO AN ADDRESS
HRLI T2,-EXESIZ ;FORM AOBJ WORD
ABZ2: EXCTUU <SKIPE (T2)> ;IS THIS LOCATION ZERO?
AOSA (P) ;NO, SKIP RETURN
AOBJN T2,ABZ2 ;LOOP THRU ENTIRE PAGE
POPJ P, ;PAGE MUST BE ALL ZERO, NON-SKIP RETURN
;SUBROUTINE TO PUT OUT 1 DIRECTORY ENTRY
;CALL:
; MOVE T1,1ST WORD OF DIRECTORY ENTRY
; MOVE T2,2ND " "
; PUSHJ P,PTNTRY
; RETURN HERE
;
;
PTNTRY: PUSH P,T2 ;SAVE T2 IN CASE PAGE MUST BE WRITTEN OUT
PUSHJ P,PTDIRW ;OUTPUT THIS WORD
POP P,T1 ;RESTORE 2ND WORD TO ENTRY AND
; PJRST PTDIRW ; STORE IT
;SUBROUTINE TO STORE A WORD IN THE DIRECTORY
;CALL:
; MOVE P1,ADDRESS-TO-PUT-WORD
; MOVE T1,WORD-TO-PUT
; PUSHJ P,PTDIRW
; RETURN HERE
;
PTDIRW: HRR M,P1 ;GET CURRENT DIRECTORY POINTER
PUSHJ P,PUTWDU## ;STORE WORD IN USER AREA
AOS P1 ;BUMP POINTER
TRNE P1,EXESIZ-1 ;DID WE OVERLAP ONTO A NEW PAGE?
POPJ P, ;NO
SUBI P1,EXESIZ ;YES, BUMP POINTER BACK TO LAST PAGE
; PJRST PUTDIR ;OUTPUT DIRECTORY (MAYBE)
;SUBROUTINE TO OUTPUT THE CURRENT DIRECTORY PAGE
;CALL:
; HRLI P2,DIRECTORY-PAGE-COUNTER
; MOVE P1,ADDRESS-OF-THIS-PAGE
; PUSHJ P,PUTDIR
; RETURN HERE ALWAYS
PUTDIR: PUSHJ P,SAVT## ;AT LEAST T3 AND T4 ARE IMPORTANT
ADD P2,[1,,0] ;BUMP # OF DIRECTORY PAGES
MOVEI T1,-1(P1) ;GET ADDRESS-1 OF I/O
MOVEI T2,SGALEN ;SAVE ADDR OF IOWD
HRRM T1,.JDAT+SGALEN ;STORE IN IOWD
PUSH P,P1 ;SAVE P1 (OUTPUT KILLS IT)
PUSH P,P4 ;SAVE P4 TOO
TLNN P1,SV%DWO ;DO WE REALLY WANT TO WRITE IT OUT?
OUTPUT (T2) ;YES, DO SO
POP P,P4 ;GET P4 BACK
JRST P1POPJ## ;RESTORE P1 AND RETURN
;ROUTINE TO REPLACE A REAL PAGE WITH AN ABZ PAGE
;
;CALL:
; MOVE T1,PAGE-ADDRESS
; PUSHJ P,MAKABZ
; HERE IF ERROR
; HERE IF OK
MAKABZ::PUSHJ P,ZAPPAG ;GET RID OF CURRENT PAGE
JFCL ;TOUGH NUGGIES
HRLI T1,(PG.DSK) ;MAKE AN ABZ PAGE
PJRST CRPAGE ;CREATE THAT
;SUBROUTINE TO DESTROY A PAGE
;CALL:
; MOVE T1,PAGE-ADDRESS
; PUSHJ P,ZAPPAG
; HERE IF ERROR
; HERE IF OK
ZAPPAG::LSH T1,W2PLSH ;CONVERT TO PAGE #
TLO T1,(1B0) ;SET DESTORY BIT
; PJRST CRPAGE ;DO THE PAGE. UUO
;ROUTINE TO CREATE A PAGE
;
;CALL:
; MOVE T1,PAGE #
; PUSHJ P,CREPAG
; COULDN'T
; COULD AND DID
;
;T1 IS PRESERVED
CRPAGE::MOVE T2,T1 ;MOVE IT INTO ANOTHER AC
MOVSI T1,.PAGCD ;SET UP FUNCTION CODE FOR PAGE.
PUSHJ P,PAGUUO ;DO THE PAGE. UUO
SKIPA T2,.JDAT+SGASAV ;ERROR--GET THE ERROR CODE
JRST CPOPJ1## ;SUCCESSFUL..GIVE SKIP RETURN
CAIE T2,PAGNV% ;DID WE TRY TO CREATE AN ALLOCATED-BUT-ZERO
; PAGE BUT WE WEREN'T VIRTUAL?
POPJ P, ;NO, GIVE FATAL ERROR RETURN
HRRZS T1 ;YES, SO GET JUST PAGE # AGAIN
; (WITHOUT "CREATE ON DISK" BIT) AND
JRST CRPAGE ; TRY TO CREATE IT AGAIN.
SUBTTL SAVGET -- GET AND RUN COMMANDS
;THIS JOB GETS A JOB AREA FROM A RETRIEVABLE DEVICE
;THIS JOB RUNS IN EXEC. MODE AND CALLS IO ROUTINES DIRECTLY
;NO ATTEMPT IS MADE TO RESTORE STATUS OF IO DEVICES, PC, OR AC'S
;JOBPC IS SET TO STARTING ADDRESS OF JOB
;CORE MUST ALREADY HAVE BEEN ASSIGNED AND THE FOLLOWING LOC. SETUP IN
;JOB DATA AREA:
;JOBPDP, JOBREL
GJOB: JSP T2,SG1 ;SETUP ACS, SETUP LOWER CORE(SGALEN,SGADMP)
PUSHJ P,CLRTAB ;CLEAR OUT LAST PROGRAM FROM PDB
PUSHJ P,RMVPFH##
PUSH P,[0] ;CLEAR PC FLAGS SINCE THEY ARE MEANINGLESS
MOVEI T1,JS.RUU ;BIT TO SET
IORM T1,JBTSTS##(J) ;SO CAN READ XONLY FILES
PUSHJ P,GJOBX ;GET THE JOB
MOVEI T1,JS.RUU ;GET THE BIT
ANDCAM T1,JBTSTS##(J) ;BACK TO NORMAL PROTECTION CHECKING
JSP T1,PHOLD## ;RETURN ONLY IF EVERYTING OK
ASCIZ /Job setup/
;THIS JOB GETS A JOB AREA FROM A RETRIEVAL DEVICE AND STARTS IT UP
;JOB HAS JUST A JOB DATA AREA ASSIGNED WHEN CONTROL GETS HERE
;THIS MONITOR JOB GETS A JOB AREA FROM A RETREIVABLE DEVICE
;ASSIGNS CORE AND START
RUNJOB: JSP T2,SG1 ;SETUP ACS, SETUP LOWER CORE(SGALEN,SGADMP)
PUSHJ P,CLRTAB ;CLEAR OUT LAST PROGRAM NAME
PUSH P,P1 ;PUSH A FAKE WORD SO GETBTB CAN CLEAR LH JOBPD1
PUSHJ P,RMVPFH##
HRLZ T1,P1 ;RH P1 = STARTING ADDRESS INCREMENT
PUSH P,T1 ;FAKE UP BEGINNING OF RUN UUO PD LIST
JRST URUN1 ;GO FINISH UP AS IF RUN UUO
UMERGE::PUSHJ P,GETARG
PUSHJ P,UGTSSL ;GET OR FAKE EXTENDED CORE ARG
SKIPL T1,.JDAT+SGANEW ;EXTENDED CORE ARG GIVEN?
JRST [TDNE T1,[777000,,777000] ;SPECIFYING SECTION NUMBERS IN RANGE IS ILLEGAL
JRST IUUAGL## ;ILLEGAL ARGUMENT LIST
JRST .+2] ;SGANEW SPECIFIES THE RANGE
SETZM .JDAT+SGANEW ;YES, CAN'T ALSO GIVE RANGES (YET)
PUSHJ P,MERGE
JRST TPOPJ1##
CMERGE::SETZB P1,P2
JSP S,SGSETD
MRGJOB: JSP T1,MONSTR##
PUSHJ P,RMVPFH##
PUSHJ P,SG2A
PUSH P,.JDAT+SGANAM
PUSHJ P,MERGE
POP P,T2
PUSHJ P,PRNAME
JSP T1,PHOLD##
ASCIZ / merged/
MERGE: MOVSI T1,'EXE'
MOVEM T1,.JDAT+SGAEXT
PUSHJ P,SGOPEN##
MOVEI T1,JS.XOR!JS.XO ;XONLY RUN
AND T1,JBTSTS##(J) ;ARE ANY SET IN JBTSTS##?
ANDCAM T1,JBTSTS##(J) ;WELL, CLEAR THEM IF SO
PUSH P,T1 ;SAVE THE BITS
LOOKUP 0,SGANAM ;LOOKUP AND SET JS.XOR IF EXEC ONLY FILE
JRST MERBAD
MOVEI T1,JS.XOR!JS.XO
TDNE T1,JBTSTS##(J) ;DID XONLY GET SET WITH THIS LOOKUP?
JRST [ MOVEI T1,PRTERR ;YES, DON'T ALLOW MERGE OF XONLY FILE
HRRM T1,.JDAT+SGAEXT ;INDICATE PROTECTION FAILURE
JRST MERBAD] ;AND MAKE THE MERGE FAIL
POP P,T1 ;GET BACK PREVIOUS XOR BIT
IORM T1,JBTSTS##(J) ;SET XOR IF IT WAS SET BEFORE
MOVSI T1,(UP.MPF) ;MERGING PFH?
TDNE T1,.USBTS ;ARE WE?
TLNE F,SYSDEV ;AND DID THIS PFH COME FROM SYS:?
TRNA ;KOSHER
PUSHJ P,CHKMED## ;MERGING PFH FROM USER AREA, MEDDLE.
MOVSI P1,GTLOW+GTMRG
PUSHJ P,GETEXE## ;GET FILE
MOVE J,.CPJOB##
PUSHJ P,VERWAT ;SEE IF WATCHING
JRST MERGE1 ;NO -SKIP IT
PUSHJ P,PGMMRG ;YES--PRINT FILESPEC
PUSHJ P,PRRBKC ;PRINT RIGHT BRACKET
MERGE1: PJRST SGREL
MERBAD: MOVEI T1,JS.XOR!JS.XO ;XONLY FLAGS
ANDCAM T1,JBTSTS##(J) ;CLEAR 'EM
POP P,T1 ;RESTORE ORIGINAL XONLY FLAGS
IORM T1,JBTSTS##(J) ;AND RESTORE THEM TO JBTSTS
MOVSI P1,GTMRG ;FLAG MERGE BEING DONE
MOVEM P1,.JDAT+SGAEND ;FOR SGRELE
JRST NOFILE ;AND RETURN ERROR CODE
SUBTTL SAVGET -- RUN UUO
;CALL: MOVE AC,[XWD N,D]
; CALL AC,[SIXBIT /RUN/]
; ERROR RETURN ;UNLESS LH=HALT(PRINT CONSOLE MESS. IF YES)
; IK OK, TRANSFER TO C(JOBSA)+N FOR NEW PROGRAM
; USERS ACS CLOBBERED SO CANNOT PASS DATA TO NEW PROGRAM
;WHERE: D/ DEVICE NAME
; D+1/ FILE NAME
; D+2/ FILE EXT OR 0 (LH SIXBIT)
; D+3/ DATE ETC
; D+4/ PROJECT,PROGRAMMER NO OR 0(CURRENT UFD OR DTA,MTA)
; D+5/ HIGHEST LOC DESIRED(OR 0) ANALOGOUS TO RUN COMMAND
; LH IS IGNORED(RATHER THAN ASSIGNING CORE TO HIGH SEG)
URUN:: MOVSI T1,JLOG ;IS THIS JOB
TDNE T1,JBTSTS##(J) ;LOGGED IN?
JRST URUN1A ;YES, OK
MOVEI T1,NLIERR ;NO, GIVE HIM
PUSHJ P,SGRELE ;AN ERROR
MOVEI T1,LOGPLM ;SET UP ERROR MESSAGE
JRST PHOLD## ;START TTY + STOP JOB
; HERE WHEN RUN UUO CALLED VIA CONTEXT UUO
URUN1A::
IFN FTFDAE,<
PUSHJ P,CALLF
PUSHJ P,SNDFXM
>
PUSHJ P,RESET## ;RELEASE DEVICES
; WARNING! THIS GOES VERY DEEP IN
; PUSHDOWN. SEE MCO 518
; (AC M PRESERVED IN RESET)
PUSHJ P,SAVE1## ;SAVE P1,P2
PUSHJ P,GETWDU## ;RESTORE CONTENTS OF USER'S CALLING AC
PUSHJ P,GETARG ;GET 6 ARGS FROM USER AND STORE
; SAVE STARTING ADDRESS INCREMENT(LH OF T1)
; AND USER AC NUMBER(IN CASE OF ERROR RETURN)
; SETUP ACS,F TO U
SETZM .USUSN ;ASSUME /USE:0
PUSHJ P,UGTSSN ;SET UP FROM USER ARG IF GIVEN
SETZM .USUSA ;CLEAR MEMORY OF ENTRY VECTOR
REPEAT 0,<
MOVSI T1,400000 ;SET-BY-UUO BIT
ANDCAM T1,.USUSN ;IS NOT FOR RUN
>
SKIPGE .JDAT+SGANEW ;IF EXTENDED ARG GIVEN,
SETZM .JDAT+SGANEW ;CAN'T (YET) ALSO GIVE CORE SIZE
HRRZS .JDAT+SGANEW ;CLEAR JUNK(FOR COMPATABILITY)
MOVEI P1,0 ;CLEAR FLAGS
MOVE T1,['RUNUUO'] ;NEED TO KNOW IF WE RUN GET
MOVEM T1,.USUAC+4
MOVS T1,(P)
MOVEM T1,.USUAC+6
;HERE ON R OR RUN COMMAND
URUN1: MOVEI T1,JS.RUU ;BIT TO SET
IORM T1,JBTSTS##(J) ;SO CAN READ XONLY FILES
PUSHJ P,GJOBX ;GET BOTH LOW AND HIGH SEGMENTS
;RETURN FILE NAME IF FROM REAL SYS, ELSE 0 IN T1
HLRZ T2,(P) ;GET STARTING ADDRESS INCREMENT
; SUPPLIED BY USER (0 IF RUN COM.)
CAILE T2,1 ;IS IT GREATER THAN 1 (REGULAR OR CCL
JRST URUN2 ; ENTRY POINT?)
;YES, DO NOT CHECK FOR SPECIAL CUSP FROM SYS
; SINCE IT WILL NOT BE ENTERED PROPERLY
MOVSI T2,(JB.LSY) ;PREPARE TO SET FLAG
JUMPE T1,URUN3 ; IF IT CAME FROM SYS:
IORM T2,JBTLIM##(J) ; FOR BATCON
PUSHJ P,PRVPG
JRST URUN3
CAME T1,LGONAM## ;IS THIS THE LOGOUT CUSP?
CAMN T1,LGINAM## ;OR THE LOGOUT CUSP IN DRAG?
SETZM .PDCVL##(W) ;YES, MAKE SURE IT HAS ENOUGH CORE TO RUN
CAMN T1,LGONAM## ;IS THIS THE LOGOUT CUSP?
PUSHJ P,CLRJLG## ;YES, CLEAR JLOG
MOVSI T2,JACCT ;SET PRIVILEGED PROG. BIT
MOVE T3,JBTPPN##(J)
CAME T3,FFAPPN## ;OPR IS NEVER XCT ONLY
HRRI T2,JS.XO
;*** MPB HACQUE
CAME T1,QUEUE## ;IS IT QUEUE?
JRST URUN4 ;NO, SKIP CHECK
SKIPE %SIQSR## ;YES, QUASAR RUNNING?
SETZ T2, ;YES, NO JACCT
;*** END MPB HACQUE
URUN4: IORM T2,JBTSTS##(J) ;SO NO CONTROL C AND ALL ACCESS TO FILES
JRST URUN2A ;GO START IT UP
URUN2: PUSHJ P,CHKMED## ;SET MEDDLE IF SHARABLE
MOVEI T1,JS.XO ;SEE IF EXECUTE ONLY
TDNN T1,JBTSTS##(J) ; IF SO, CLEAR OFFSET
JRST URUN3 ;NO, GO RUN IT
SETZM (P) ; TO PROTECT JOB
URUN2A: SKIPGE T1,.USUSA ;ALSO CLEAR .USUSA IF SET
TLNE T1,370000 ; BY A COMMAND RATHER THAN FROM THE EXE FILE
JRST URUN3 ;NOT SET BY COMMAND
SETZM .USUSA ;SET BY COMMAND, ZAP IT
URUN3: MOVSI T1,(PD.PGR) ;THE .STPGM RUN IN PROGRESS BIT
ANDCAM T1,.PDDFL##(W) ;CLEAR IT, SINCE WE MANAGED TO FINISH THE RUN.
HLRZ T2,(P) ;GET STARTING ADDRESS INCREMENT(0 IF RUN COM)
ADD T2,.JDAT+JOBSA## ;NOW ADD STARTING ADDRESS
TLZ T2,-1 ;CLEAR JUNK
SKIPN .USUSA ;ENTRY VECTOR OR /START:ADDR SEEN?
JRST STRTDD ;NO, JUST CHECK FOR /USE:N
MOVE T2,.USUSA ;YES, NEED THIS ADDRESS
TLZ T2,400000 ;IGNORE COMMAND-MODE BIT
PUSHJ P,GSADDR ;DEAL WITH POSSIBLE INDIRECTED START ADDR
HLRZ T1,(P) ;GET START ADDRESS OFFSET AGAIN
ADD T2,T1 ;OFFSET IT
JRST STARTU ;AND SKIP /USE:N NONSENSE
;HERE FROM VMSER TO START DDT AFTER GETTING DDT
STRTDD:
STARTD::MOVE T1,.USUSN ;SECTION NUMBER FROM USE SWITCH
LSH T1,P2WLSH ;CONVERT TO ADDRESS
HLL T2,T1 ;SECTION NUMBER,,START ADDRESS WITHIN SECTION
SKIPN .USUSA ;WAS THERE AN ENTRY VECTOR?
JRST STARTU ;NO, WE HAVE OUR ADDRESS
LDB T1,[POINT 6,.USUSA,5] ;MAYBE, GET ITS LENGTH AND FLAG
CAIN T1,40 ;CHECK HARDER
JRST STARTU ;DON'T OFFSET FOR /START:ADDR
HLL T2,.USUSA ;USE SECTION OF ENTRY VECTOR
TLZ T2,770000 ;CLEAR POSSIBLE JUNK
STARTU: TRNN T2,777700 ;SEE IF LEGITIMATE START ADDRESS
JRST URUNSA ;NO--GIVE THE USER AN ERROR
PUSH P,[XC.USR+IFN FTKL10,<XC.PUB>]
PUSH P,T2
IFN FTMP,<
PUSHJ P,DPXST## ;SET UP PROPER RUNNABLE BITS FOR THIS JOB IN JBTSPS
>
MOVE T1,[JERR,,JS.RUU] ;BITS TO CLEAR FOR FILSER
ANDCAM T1,JBTSTS##(J) ; AND FOR CTRL-C TRAPPING
JRST USRXIT## ;AND GO TO RETURN TO USER AS IF FROM UUO
URUNSA: PUSHJ P,SGRLE2 ;RELEASE DEVICE, GET TTY, TYPE ?
URUNSB::MOVEI T1,MESNSA ;SETUP MESSAGE
PJRST PHOLD## ;TYPE MESSAGE
;SUBROUTINE TO DETERMINE IF THE CUSP BEING RUN IS PRIVILEGED
; ENTER WITH T1=NAME OF THE CUSP BEING RUN
; EXIT CPOPJ IF NOT PRIVILEGED, CPOPJ1 IF IT IS
;PRESERVES T4
PRVPG:: MOVSI T2,-PRVTBL## ;NO. OF PRIVILEGED CUSPS
CAME T1,PRVTAB##(T2) ;MATCH?
AOBJN T2,.-1 ;NO, KEEP LOOKING, FINISHED?
JUMPL T2,CPOPJ1## ;JUMP IF FOUND
POPJ P, ;NO MATCH
IFN FTFDAE,<
;SUBROUTINE TO CALL FILE DAEMON ON EXIT
;CALLING SEQUENCE:
; MOVE J,JOB NUMBER
; PUSHJ P,SNDFXM
;RETURNS CPOPJ ALWAYS
SNDFRM::MOVEI T1,.FDPOP ;POP CODE
JRST SNDFX1 ;JOIN COMMON CODE
SNDFPM::SKIPA T1,[.FDPSH] ;PUSH CODE
SNDFXM: MOVEI T1,.FDXIT ;EXIT CODE
SNDFX1: PUSH P,T1 ;PRESERVE FOR A WHILE
MOVEI T2,1+4+MAXLVL## ;SPACE FOR CODE, STR, NAME, EXT, PPN, & SFDS
PUSHJ P,GTFWDC## ;GET FROM FUNNY SPACE
JRST TPOPJ## ;CAN'T
POP P,0(T1) ;RESTORE CODE INTO MESSAGE
MOVE T2,.PDSTR##(W) ;STR
MOVEM T2,1(T1)
MOVE T2,.PDNAM##(W) ;NAME
MOVEM T2,2(T1)
MOVSI T2,.PDDIR##(W) ;PPN/PATH
HRRI T2,4(T1)
BLT T2,MAXLVL##+3(T1)
MOVE T4,JBTPPN##(J) ;SENDER'S PPN
PUSHJ P,SENDFD## ;SEND TO FILDAE
JFCL ;COULDN'T
POPJ P, ;RETURN
;SUBROUTINE TO SEE IF FILE DAEMON SHOULD BE CALLED ON EXIT
;CALLING SEQUENCE:
; MOVE J,JOB NUMBER
; PUSHJ P,CALLF
;RETURNS CPOPJ IF FILE DAEMON SHOULD BE CALLED CPOPJ1 IF NOT
;PRESERVES T3,T4
CALLF: MOVSI T1,(JS.CFX) ;GET THE BIT
TDNN T1,JBTST2##(J) ;WAS IT SET?
AOSA (P) ;NO, SET FOR SKIP RETURN AND SKIP
ANDCAM T1,JBTST2##(J) ;YES, CLEAR IT NOW
POPJ P, ;RETURN
;SUBROUTINE TO SEE IF AN EXIT MESSAGE SHOULD BE SENT TO THE FILE DAEMON
; IF SO, DELAY THE COMMAND UNTIL THE MESSAGE IS SENT
CHKXTM: POP P,T4 ;RETURN ADDRESS
PUSHJ P,CALLF ;NO, SHOULD FILE DAEMON BE CALLED ?
CAIA ;YES
JRST (T4) ;NO, JUST DO THE COMMAND
MOVSI T1,LDBFDX## ;INDICATE PROCESSING FILDAE EXIT MESSAGE
SE1XCT <IORM T1,LDBCOM##(U)> ;SO COMRET WILL LEAVE LDBCMF ALONE JUST
; CLEARING LDBCMR
TLO M,LHRUNF!NOMESS ;SO COMRET WILL LET US RUN (SUPPRESS WATCH STATS)
PJSP T2,MSTART## ;START THE MONITOR JOB
JSP T1,MONSTR## ;SETUP ACS
PUSHJ P,SNDFXM ;SEND THE "EXIT" MESSAGE TO THE FD
PUSHJ P,TTYFUW## ;FIND THE TTY
MOVSI T1,LDBFDX## ;CLEAR
SE1XCT <ANDCAM T1,LDBCOM##(U)> ;SO FORCED COMMANDS IF ANY GET DONE NOW
PUSHJ P,CNCMOD## ;TTY TO MONITOR MODE
PUSHJ P,COMSET## ;MAKE THE ORIGINAL COMMAND VISABLE
PJRST ESTOP## ;STOP THE JOB
> ;END IFN FTFDAE
SUBTTL SAVGET -- GETSEG## UUO
;UUO TO GET JUST HIGH SEG AND RETURN TO USER
;CALL IS THE SAME AS FOR RUN UUO EXCEPT THAT OK RETURN IS SKIP RETURN
;IF ERROR RETURN HAS HALT IN LH, STANDARD CONSOLE MESSAGE IS PRINTED AND JOB STOPPED
UGTSEG::MOVE T2,['GETSEG']
MOVEM T2,.USUAC+4
MOVE T2,.JDAT+JOBPD1##
MOVEM T2,.USUAC+6
MOVE T2,JBTSTS##(J) ;GET JOB STATUS
TLNE T2,JACCT ;IS JACCT ON
TLO P1,PHONLY ;YES, GETSEG MUST BE PHYSICAL ONLY
JRST UGETHI## ;IN SEGCON
UGTERR::MOVEI T1,ILUERR ;ILLEGAL UUO ERROR CODE
PUSHJ P,SGRELE ;SEE IF USER WANTS ERROR
JRST UUOERR## ;NO, PRINT ILLEGAL UUO
SUBTTL SAVGET -- COMMON CODE
;ROUTINE TO SETUP ACS, RESET IO, AND SETUP LOWER CORE LOCATIONS
;FOR SAVE AND GET(SGALEN SET TO IOWD OR PP IF DTA OR DSK)
;SGADMP SET TO IOWD FOR THIS SIZE CORE
;CALL: JSP T2,SG1
; ALWAYS RETURN HERE, UNLESS DEVICE NOT FOUND
; F SETUP TO DEVICE DATA BLOCK(BUT NOT INITED)
; SO THAT INIT NOT NECESSARY IF SEG ALREADY KNOWN(NO DTA QUEUEING)
; DEVICE CHARACTERISTICS WORD(DEVMOD) RETURNED IN AC T2
; IF DISK SYSTEM
SG1: JSP T1,MONSTR## ;SETUP R,P,R,J=JOB NUMBER
; PUT T2 ON END OF PD LIST(EXEC MODE PC,
; SO ERROR MESSAGES WILL ALWAYS PRINT(SEE SGRELE)
PUSHJ P,RESET## ;RELEASE ALL DEVICES
MOVE P1,.JDAT+SGAMOD ;RESTORE PHYSICAL/LOGICAL BIT
SG2A: MOVEI T1,DR ;DUMP MODE 16(DUMP BY RECORDS
; IN CASE THIS IS MAGTAPE)
PUSHJ P,CHKEXE ;SAVING AN EXE FILE?
MOVEI T1,D ;YES, ALWAYS USE REGULAR DUMP MODE (WRITE PAGES
; TO MAGTAPE)
TLNE P1,PHONLY ;SEE IF PHYSICAL DEVICE
TLO T1,(1B0) ;YES -- SET FOR PHYSICAL OPEN
MOVEM T1,.JDAT+SGAMOD ;STORE FOR OPEN UUO
SETZM .JDAT+SGAREN+1 ;FOR DELETE
SETZM .JDAT+SGAREN+2 ;FOR DELETE
HLLZS .JDAT+JOBCOR## ;0 THIRD ARG IN JOBDATA AREA(SO CHKARG WILL
; WORK ON FIRST CALL(SAVE AND GET)
SETZM .JDAT+SGAHED ;CLEAR BUFFER HEADER ARG. FOR OPEN UUO
MOVE T1,.JDAT+SGADEV ;PHYSICAL OR LOGICAL DEVICE NAME
PUSHJ P,DEVSRG## ;FIND DEVICE AND SETUP F TO DDB
; DO NOT INIT DEV SINCE IO MAY NOT BE NECESSARY
; DO NOT WANT TO WAIT IN DTA SYSTEM
; TAPE QUEUE IN 10/40 SYS
JRST SGERRA ;NOT AVAILABLE
;DEVICE INITED(OR FOUND)
SETZM .JDAT+SGAEND ;0 END OF DUMPE MODE COMMAND LIST
;COMMON EXIT FROM SAVHGH AND GETHGH ROUTINES(HIGH SEG SAVE AND GET)
;SO THAT SGA... LOCATIONS ARE RESTORED TO ORIGINAL VALUES FOR LOW SEG
SG3:: SKIPN T1,.JDAT+SGAEXT ;DID USER SPECIFY AN EXTENSION ?
MOVSI T1,'SAV' ;NO, USE .SAV
MOVEM T1,.JDAT+SGAEXT ;AND STORE FOR LOOK UP OR ENTER
MOVE T1,.JDAT+JOBFF## ;FIRST FREE LOC IN JOB(SET FROM LH OF
; JOBSA WHICH IS SET BY LOADER
MOVEI T1,-1(T1) ;MAKE LAST LOC TO SAVE OR GET(MAKE 0=777777)
SKIPN USRDDT## ;USER DDT IN USE(IF YES, SAVE ALL OF CORE
; SO HIS SYMBOLS WILL BE INCLUDED
PUSHJ P,IADRCK## ;NO, ADDRESS TOO SMALL OR TOO LARGE?
JFCL
MOVE T1,.JDAT+.JBREL## ;YES, DUMP ALL OF CORE RATHER THAN GIVE
; ADDRESS CHECK MESSAGE-HIGHEST REL.ADR.
MOVNS T1 ;-HIGHEST ADR TO SAVE OR GET
ADDI T1,JOBSVM## ;LOWER CORE NOT DUMPED
HRLI T1,JOBSVM## ;IE FIRST LOC-1 TO BE DUMPED
MOVSM T1,.JDAT+SGADMP ;STORE IOWD WORD OF THIS SIZE CORE
;ROUTINE TO SET-UP E+3 FOR ENTER
;ENTER: MOVS T1,DTA IOWD.
;USES T2
SG4:: PUSHJ P,SETASJ ;SET EXEC MODE UUO FLAG
MOVE T2,DEVMOD(F) ;RETURN DEVICE CHARACTERISTICS(IF DISK SYS)
TLNE T2,DVDSK ;IS THIS DEVICE A DISK?
MOVS T1,.JDAT+SGAPPN ;YES, MAKE SURE FOURTH WORD IS PROJ,R NO.
MOVSM T1,.JDAT+SGALEN ;NO, MAKE SURE FOURTH WORD IS IOWD FOR DECTAPE
; SINCE DECTAPE USES RH TO COMPUTE LENGTH IN K
; FOR BOTH SAVE AND GET
POPJ P,
;ERROR ON INIT OR DEVICE SEARCH
SGERRU: TLO P1,GTSAV ;FLAG TO KEEP HISEG
PUSHJ P,SGRELE ;RETURN TO USER IF UUO (WITH ERROR IN T1)
MOVE T1,.JDAT+SGADEV ;GET DEVICE AGAIN
PUSHJ P,DEVSRG## ;SEE IF EXISTS
JFCL ;IGNORE NON-SKIP (SHOULD GIVE ERROR RET)
SGERRA::JUMPE F,SGERR1 ;WAS DEVICE FOUND, BUT JUST UNAVAILABLE?
MOVEM F,(P) ;YES, SAVE DDB ADDRESS FOR MESSAGE(ERNAM)
MOVEI T1,DNAERR ;ERROR CODE IN CASE RUN UUO(DEVICE NOT AVAILABLE)
PUSHJ P,SGRELE ;RETURN TO USER IF RUN UUO
; OR FIND TTY AND PRINT ?CRLF
PUSHJ P,ERNAM## ;PRINT DEVICE NAME USING (P)
JSP T1,PHOLD## ;START TTY AND STOP JOB
ASCIZ / not available/
SGERR1: MOVEI T1,NSDERR ;ERROR CODE IN CASE RUN UUO(NO SUCH DEVICE)
PUSHJ P,SGRELE ;RETURN TO USER IF RUN UUO
; OR FIND TTY AND PRINT ?CRLF
JSP T1,PHOLD## ;START TTY AND STOP JOB
ASCIZ /No such device/
SUBTTL SAVGET -- GET FILE FROM DEVICE (R,RUN,GET,GETSEG)
;ROUTINE TO GET FILE FROM DEVICE(LOW AND/OR HIGH)
;CALL: ACS R,P,F SETUP
; MOVE J,JOB NUMBER
; MOVE T2,DEVMOD(F) ;DEVICE CHAR.
; PUSHJ P,GETJB
; RETURN ONLY IF ALL OK
; VALUE IN T1 = FILE NAME IF FROM REAL SYS, ELSO0., J PRESERVED
;
GJOBX: MOVE T1,J
PUSHJ P,FPDBT1## ;FIND PDB
CAIA ;OH WELL
SETZM .PDVRT##(T1)
PUSHJ P,SETASA ;SET EXEC MODE UUO FLAG
MOVSI T1,(JB.LSY) ;CLEAR GOTTEN FROM SYS: FLAG
ANDCAM T1,JBTLIM##(J) ; ..
MOVEI T1,JS.XOR ;CLEAR XO-STATUS
HRLI T1,JACCT ; AND JACCT
ANDCAM T1,JBTSTS##(J) ; ..
MOVSI T1,(UP.CXO)
ANDCAM T1,.USBTS ;AND XO CORE IMAGE
IFN FTFDAE,<
MOVSI T1,(JS.FXO)
ANDCAM T1,JBTST2##(J)
>
PUSHJ P,GETHGH## ;SEE IF HIGH SEG ALREADY EXISTS AND BEING SHARED
; IF NOT, TRY TO LOOKUP AND READ IN HIGH FILE
; IF .SHR DOESN'T EXIST, TRY .HGH,
; IF NEITHER-SKIP RETURN
; T2=DEVMOD(F) IF DISK(DEV CHAR.)
JRST GJOB1 ;HIGH SEG NOW IN CORE AND NO LOW FILE NEEDED
SKIPA T1,.JDAT+SGAPPN ;LOW FILE NEEDED
; EITHER BECAUSE NO HIGH SEG OR HIGH SEG ALSO
; NEEDS LOW FILE
JRST GJOB5B ;RETURN HERE IF ENTIRE FILE
; (HIGH AND LOW SEGS) HAVE BEEN
; INPUT AND ARE READY TO GO.
CAIE T1,JOBUAL## ;DON'T WIPE OUT THE PPN RETURNED BY PATH
MOVEM T1,.JDAT+JOBUAL##+2 ;IN CASE MUST GET GET
PUSHJ P,LUKFIL ;LOOKUP LOW FILE
JRST NOFILE ;GO PRINT FILE.EXT NOT FOUND
HLRE T2,.JDAT+SGALEN ;-NO. OF WORDS IN FILE
JUMPE T2,GETERR ;IF 0, GIVE ERROR MESSAGE
JUMPL T2,GJOB5 ;GO IF NUMBER OF WORDS
LSH T2,BLKLSH## ;NO. OF BLOCKS, CONVERT TO WORDS
MOVNS T2 ;MINUS NO. OF WORDS
HRLM T2,.JDAT+SGALEN
GJOB5: PUSHJ P,CKIOWD ;CHECK USER'S SUPPLIED CORE ARG TO MAKE SURE NOT
; TOO SMALL, RETURN LARGER OF FILE SIZE OR CORE ARG
PUSH P,T1 ;SAVE CORE REQUIRED
PUSHJ P,MINGET ;REDUCE TO ONE PAGE IF VIRTUAL
POP P,T1 ;RESTORE CORE ARG
PUSHJ P,GETCOR ;OK, TRY TO GET CORE
MOVE T2,DEVMOD(F) ;DEVICE CHARACTERISTICS
MOVNS T1
ADDI T1,JOBSVM## ;-WORD COUNT FOR ALL USERS CORE
TLNE T2,DVMTA ;MAG TAPE?
HRLM T1,.JDAT+SGALEN ;YES, USE USER-SPECIFIED CORE ARGUMENT
HRRZS .JDAT+JOBPD1## ;TURN OFF USER MODE PC FLAG IN CASE THIS
; IS A RUN UUO,SO ERRORS WILL NOT TRY TO RETURN TO USER
PUSHJ P,SGDO ;READ IN FILE INTO LOW SEGMENT
INPUT 0,SGALEN ;EXECUTED FROM SGDO
HLRZ T1,.JDAT+JOBSVM##-3 ;GET 1ST WORD OF FILE
CAIN T1,SV.DIR ;IS THIS AN EXE FILE?
JRST EXESAV## ;YES, GIVE ERROR MESSAGE
MOVE T1,.JDAT+JOBS41## ;RESTORE USER UUO JSR LOC
MOVEM T1,.JDAT+JOB41## ;SAVED BY SAVE
GJOB5B: PUSH P,F ;SAVE SYSDEV BIT
SKIPN .USREL ;NO LOWFIN IF NON-CONTIGUOUS
PUSHJ P,LOWFIN ;MAKE SURE GOT ALL REQUESTED CORE
POP P,F ;NOW RESTORE F
JRST GJOB2 ;GO RELEASE DEVICES AND RETURN
;HERE IF HIGH SEG SAYS NO LOW SEG(AND USER DID NOT TYPE AN EXT)
GJOB1: SETZM .JDAT+JOBBPT
PUSH P,F ;SAVE F SINCE IF NO LOOKUP WAS DONE IT IS
; NOT STORED IN USRJDA
PUSHJ P,MINGET
PUSH P,.CPREL## ;MAX WHICH MUST BE CLEARED
PUSHJ P,LOWFIN ;INCREASE OR DECREASE SIZE
POP P,T1 ;RESTORE PREVIOUS SIZE
POP P,F ;RESTORE F
CAMLE T1,.CPREL## ;SMALLER YET?
MOVE T1,.CPREL## ;
MOVEI T2,MJOBDA##(T1) ;NO. OF WORDS TO CLEAR(-JOB DATA AREA)
ADDM T2,CLRWRD## ;INCREASE TOT. NO. WORDS CLEARED BY SYSTEM
MOVEI T2,JOBDA##+1 ;FIRST ABSOLUTE LOC+1 TO CLEAR(JOB DATA
; AREA+2)=BLT DESTINATION ADR.
EXCTUU <SETZM -1(T2)> ;CLEAR THE FIRST WORD
HRLI T2,-1(T2) ;SET UP FIRST BLT SOURCE ADR(JOB DATA
; AREA+1)
EXCTUU <BLT T2,(T1)> ;CLEAR FROM 140 TO TOP OF LOW SEG
GJOB2: HRRZ T1,JBTSGN##(J) ;GET ADDRESS OF SEGMENT DATA BLOCK IF ANY
SKIPE T1 ;ONLY IF THERE IS ONE (FIRST IS NEWEST)
PUSHJ P,HSVAD## ;GET HIGHEST RELATIVE ADDRESS IN THE HI SEG
HRRM T1,.JDAT+JOBHRL## ;SET HIGHEST RELATIVE LOC FOR USER
MOVE T1,.JDAT+SGANAM ;FILE NAME OF FILE OR SEGMENT
PUSH P,T1 ;SAVE POSSIBLE RETURN AS VALUE
TLNN F,SYSDEV ;IS DEVICE THE REAL SYS(AS OPPOSED TO LOGICAL)
SETZM (P) ;NO, SET FILE NAME TO 0 FOR RETURN
MOVEM T1,JBTPRG##(J) ;LOW SEG NAME FOR SYSTAT
PUSHJ P,EXONLY ;IF EXECUTE ONLY, PROTECT THE CORE IMAGE
MOVSI T1,(UP.CXO)
TDNE T2,JBTSTS##(J) ;IF XO HERE,
IORM T1,.USBTS ; MARK THE ENTIRE CORE IMAGE AS XO
TDNE T2,JBTSTS##(J) ;IS IT EXECUTE ONLY?
PUSHJ P,MAPHGH## ;YES, MAKE SURE THE MAP REFLECTS THAT
PUSHJ P,FNDPDS## ;FIND THE PDB OR STOP
MOVE T1,JBTNAM##(J) ;STORE THE NAME OF THE PROGRAM
MOVEM T1,.PDNAM##(W) ; SINCE IT CAN BE CHANGED WITHOUT
; CHANGING THE CONTENTS OF THE CORE IMAGE
SETZM .JDAT+JOBUAL##+3 ;ZERO FIRST SFD WORD (IN CASE OF JUNK FROM LOWFIN)
HRRZ T1,F ;IF (F)
CAIE T1,DSKDDB## ;=DSKDDB, NO LOOKUP DONE
JRST GJOB6 ;LOOKUP WAS DONE
MOVE J,.CPJOB## ;JOB NUMBER
HRRZ T1,JBTSGN##(J) ;HIGH SEGMENT BLOCK
MOVE T1,.HBSGN(T1) ;SEGMENT WORD (NEWEST SEGMENT)
MOVE T2,JBTPPN##(T1) ;DIRECTORY AND
MOVE T1,JBTDEV##(T1) ;STR WHERE PROGRAM CAME FROM
TLNE T2,-1 ;A PATH TO THE HIGH SEGMENT?
JRST GJOB6A ;NO, STORE A ZERO AS FIRST SFD
MOVSI T3,1(T2) ;WHERE SFD'S ARE STORED
MOVE T2,(T2) ; AND THE PPN
JRST GJOB7 ;STORE THEM
GJOB6: CAIN T1,SWPDDB## ;VIRTUAL PROGRAM?
MOVE F,USRJDA ;YES, INSURE F IS SETUP
MOVEI T1,JOBUAL##
MOVEM T1,.JDAT+SGAPPN
PUSHJ P,PTHFIL## ;GET PATH BACK (CLOBBERED BUT BY VIRCHK)
PUSHJ P,NAMSTR## ;STR
SKIPA T1,DEVNAM(F) ;NOT A DSK, DEVICE NAME
SKIPA T2,DEVPPN(F) ;YES, GET DIRECTORY
MOVEI T2,0 ;NO, NO DIRECTORY
GJOB6A: MOVSI T3,.JDAT+JOBUAL##+3 ;WHERE THE SFD'S ARE STORED
GJOB7: MOVEM T1,.PDSTR##(W) ;STORE STR OR DEVICE NAME
MOVEM T2,.PDDIR##(W) ;AND DIRECTORY
HRRI T3,.PDSFD##(W) ;WHERE TO STORE PATH
BLT T3,.PDSFD##+MAXLVL##-1(W) ;STORE PATH
PUSHJ P,VERWAT ;SEE IF VERSION WATCHING
JRST GJOB8 ;NO
MOVSI T2,'S: ' ;YES -- PRESET SYS FLAG
SKIPE (P) ;SEE IF FROM SYS:
PUSHJ P,PRNAME ;YES -- TYPE IT
PUSH P,P2 ;NOT A VERSION COMMAND
SETO P2, ;CALL PGMFIL FOR FIRST SEGMENT
PUSHJ P,VERBTH ;PRINT BOTH SEGMENTS
POP P,P2
PUSHJ P,PRRBKC ;PRINT RIGHT BRACKET <CRLF>
GJOB8: PUSHJ P,SGREL ;RELEASE DDB
MOVSI T1,.JDAT
EXCTXU <BLT T1,17> ;SETUP USER'S ACS FROM SG AREA
JRST TPOPJ## ;RETURN WITH T1 = FILE NAME ONLY
; IF FROM REAL SYS,ELSE 0
;ROUTINE TO LOOKUP A LOW-SEGMENT FILE
;
;CALL:
; PUSHJ P,LUKFIL
; HERE IF NOT FOUND
; HERE IF FOUND
;
LUKFIL::MOVE T1,DEVMOD(F) ;DEVICE CHARACTERISTICS
SKIPN T2,JBTSGN##(J) ;MIGHT THERE HAVE BEEN A HIGH SEGMENT?
TLNN T1,DVDSK ;YES, AND DID IT COME FROM THE DISK
JRST LUKFI3 ;NO, JUST DO THE LOOKUP
MOVE T1,.JDAT+SGANAM ;GET NAME HIGH SEG SHOULD HAVE COME FROM
SKIPLE T2,.HBSGN(T2) ;REALLY WAS A HIGH SEG?
CAME T1,JBTPRG##(T2) ;SAME NAME?
JRST LUKFI3 ;NO
SKIPN T1,DEVPPN(F) ;PPN FROM WHENCE THE HIGH SEGMENT CAME
MOVE T1,JBTPPN##(T2) ;NO LOOKUP WAS DONE FOR THE HI SEG
TLNE T1,-1 ;PATH TO THE HI SEG STORED?
JRST [SKIPE DEVPPN(F) ;NO, USE PPN OR PATH FROM HI SEG LOOKUP
JRST LUKFI1
JRST LUKFI2]
HRLI T1,.JDAT+JOBUAL##+2 ;YES, USE PATH TO THE HI SEG
MOVSS T1 ; TO LOOKUP THE LOW SEG
BLT T1,.JDAT+JOBUAL##+MAXLVL##+2
LUKFI1: MOVEI T1,JOBUAL## ;ADDRESS OF THE PATH
LUKFI2: MOVEM T1,.JDAT+SGALEN ;STORE IT FOR THE LOOKUP
LUKFI3: LOOKUP 0,SGANAM ;LOOKUP LOW SEG FILE(EXT=SAV.DMP OR LOW(IF HIGH SEG
; REQUIRES LOW SEG AND USER DID NOT TYPE EXT)
; MODE=SAVMOD SO DECTAPE SERVICE WILL RETURN
; IOWD IN E+3(TEMPORARY)
POPJ P, ;NOT FOUND
JRST CPOPJ1## ;FOUND, SKIP RETURN
;ROUTINE TO CHECK VIRTUAL LIMITS ON A GET.
;
;CALL:
; MOVE T1,WORDS-NEEDED
; PUSHJ P,CKVLIM
; HERE IF NO ROOM
; HERE IF OK
;
CKVLIM: LSH T1,W2PLSH ;PAGE #
HLRZ T2,.PDCVL##(W) ;GET VIRTUAL LIMIT
MOVSI T3,(UP.GET) ;CHECK GET BIT
TDNN T3,.USBTS
CAIL T1,(T2) ;WANT MORE THAN THAT?
POPJ P, ;YES
JRST CPOPJ1## ;NO
;VERWAT -- START VERSION WATCH IF ON
;RETURN CPOPJ IF NOT OR DETACHED
;SKIP IF SO WITH U SETUP AND LEFT BRACKET TYPED
VERWAT::MOVSI T1,JW.WVR ;SEE IF WATCHING
TDNN T1,JBTWCH##(J) ; ..
POPJ P, ;NO
PUSHJ P,TTYFND## ;GET LDB
JUMPE U,CPOPJ## ;NONE
PUSHJ P,PRLBK ;PRINT LEFT BRACKET
JRST CPOPJ1## ;SKIP RETURN
;SUBROUTINE TO DETERMINE IF JOB OR SEGMENT WAS READ FROM AN EXECUTE
; ONLY FILE. IF SO PROTECT THE CORE IMAGE BY SETTING THE EXECUTE
; ONLY BIT. IF NOT CLEAR EXECUTE ONLY.
EXONLY::MOVE J,.CPJOB## ;GET THIS JOB NUMBER
MOVE T1,[JACCT,,JS.XOR]
MOVEI T2,JS.XO
MOVE T3,[IORM T2,JBTSTS##(J)]
IFN FTFDAE,<
MOVSI T4,(JS.FXO)
TDNE T4,JBTST2##(J)
JRST EXONL1
>
MOVE T4,JBTPPN##(J)
CAME T4,FFAPPN## ;DONT SET EXEC.ONLY FOR [1,2]
TDNN T1,JBTSTS##(J) ;EXEC.ONLY FILE?
HRLI T3,(ANDCAM T2,(J))
EXONL1: MOVEI T1,JS.RUU
TDNN T1,JBTSTS##(J)
CAME T3,[ANDCAM T2,JBTSTS##(J)]
XCT T3 ;SET OR CLEAR EXECUTE ONLY CORE IMAGE
POPJ P, ;RETURN
;SUBROUTINE TO REDUCE LOW SEGMENT SIZE TO ONE PAGE
; IF THE PROGRAM IS VIRTUAL. THIS IS NECESSARY
; (ONLY IN THE CASE OF A RUN UUO - RUN COMMAND
; CALLED GETMIN) TO MAKE SURE THAT THE MAP
; CONTAINS NO DISK ADDRESSES AND TO REMOVE PFH
; IF IT IS CONTAINED IN THE CORE IMAGE
MINGET: SKIPN .USVRT ;VIRTUAL?
SKIPE .USMEM ;OR NON-CONTIGUOUS
SKIPA T1,MINCOR ;YES
IFN FTPEEKSPY,<
PJRST CLRSPG## ;ZAP SPY PAGES
>
IFE FTPEEKSPY,<
POPJ P, ;RETURN
>
GET1PG::
IFN FTMP,<
PUSHJ P,[PUSHJ P,GGVMM## ;NEED MM
PJRST KILNZS##]
>
IFE FTMP,<
PUSHJ P,KILNZS##
>
JFCL ;ALWAYS SKIPS AT UUO LEVEL
HRRZM T1,.JDAT+SGACOR ;ONE PAGE
CALLI SGACOR,200011 ;REDUCE LOW SEG IMAGE TO PAGE ZERO
JFCL ;CAN'T FAIL
PUSHJ P,ZAPEPL## ;CLEAR EXTENDED PDL
HRRZ T1,.JDAT+JOBPD1## ;ADDRESS OF UUO
CAML T1,.CPREL## ;IN CASE THE USER DID THE UUO IN PAGE 0
HRRZS .JDAT+JOBPD1## ;CLEAR USER MODE SINCE CAN'T RETURN TO USER
IFN FTPEEKSPY,<
PJRST CLRSPG## ;ZAP SPY PAGES IF ANY
>
IFE FTPEEKSPY,<
POPJ P, ;AND RETURN
>
;SUBROUTINE TO CLEAR VARIOUS ITEMS WHEN THE CONTENTS OF A CORE
; IMAGE IS CHANGED OR RENAMED (SAVE)
CLRTAB: PUSHJ P,CLRBTS ;CLEAR BITS IN JOB TABLES
PUSHJ P,FNDPDS## ;POINT TO PDB
SETZM .PDNAM##(W) ;ZERO NAME
SETZM .PDSTR##(W) ; AND STR
SETZM .PDDIR##(W) ; AND PPN
MINCOR: POPJ P,PG.BDY ;RETURN
CLRBTS: MOVE T1,[JACCT,,JS.XO!JS.XOR] ;CLEAR EXECUTE ONLY SO
ANDCAM T1,JBTSTS##(J) ; USER WILL NOT BE RESTRICTED
MOVSI T1,(UP.CXO)
ANDCAM T1,.USBTS ;CLEAR XO CORE IMAGE
MOVSI T1,(JB.LSY) ;NO LONGER A PROGRAM
ANDCAM T1,JBTLIM##(J) ; FROM SYS
POPJ P, ;RETURN
SUBTTL SAVGET -- IO ROUTINES
;ROUTINE TO RELEASE DEVICE AND FIND TTY
SGREL:: SKIPN F,USRJDA## ;HAS CHANNEL BEEN RELEASED ALREADY?
JRST SGREL2 ;YES, FIND TTY AND WAIT FOR OUTPUT TO FINISH
PUSH P,S ;NO,
MOVE T1,DEVMOD(F)
TLNE T1,DVDSK ;DISK?
CLOSE 0,CLSNMB ;YES, KEEP THE ACCESS TABLES
TLNE T1,DVMTA ;MAGTAPE?
TLNN F,INPB ;YES, WAS AN INPUT DONE?
JRST SGREL1 ;NO
SETZM DEVBUF(F) ;INSURE NO PAGE FAULTS
CLOSE 0,CLSOUT ;YES, CLOSE MTA INPUT
STATO 0,IOTEND+IODEND ;AT END OF TAPE?
MTAPE 0,16 ;NO SKIP TO EOF
SGREL1: RELEASE 0, ;NO RELEASE DEVICE
POP P,S
SGREL2: PUSHJ P,TTYFNU## ;FIND TTY FOR CURRENT USER SET J TO CURRENT JOB
MOVSI T1,(UP.CTX) ;RUN UUO ERROR BIT FOR CTXSER
ANDCAM T1,.USBTS ;CLEAR IT
PJRST CLRASA ;CLEAR EXEC MODE UUO FLAG
;SUBROUTINE TO ADJUST LOW SEG CORE ACCORDING TO ARG
; ON GET OR PREVIOUS SAVE
;CALL: PUSHJ P,LOWFIN
; ALWAYS RETURN
LOWFIN: HRRZ T1,.JDAT+JOBCOR## ;CORE ARG FROM PREVIOUS SAVE(THIS MONITOR
; ALWAYS STORES SOMETHING)
SKIPN T1 ;IS THIS AN OLD FORMAT FILE WITH NO CORE ARG TO SAVE?
MOVE T1,.CPREL## ;YES, USE ASSIGNMENT MADE WHEN LOW FILE READ IN
PUSHJ P,CKSARG ;RETURN ONLY IF USER'S SUPPLIED ARG IS 0 OR NOT
; SMALLER THAN SAVE CORE ARG, RETURN LARGER
HRRZM T1,.JDAT+SGACOR ;STORE CORE ARGUMENT
PUSH P,T1 ;SAVE IN CASE OF AN ERROR
PUSHJ P,GETSSN## ;SECTION 0 OR SECTION 1 PROGRAM?
JUMPN T1,LOWFI1 ;NO, DO THINGS DIFFERENTLY
MOVE T1,(P) ;CORE ARG
CAMG T1,.CPREL## ;IF GREATER, EXE FILE DICTATES
JRST TPOPJ## ;ALL DONE
MOVE T1,.JDAT+SGANAM ;NAME OF PROGRAM
TLNE F,SYSDEV ;IS PROGRAM FROM SYS ?
PUSHJ P,PRVPG ;YES, SHOULD IT BE NON-VIRTUAL?
TDZA T1,T1 ;NO
MOVEI T1,UPHNLY ;YES, LIGHT PHYSICAL-ONLY BIT
CALLI SGACOR,11(T1) ;TRY TO GET THE CORE (VIRTUAL OR PHYSICAL)
JRST NOROOM ;NOT AVAILABLE
MOVE T1,.CPREL## ;HIGHEST LOC ASSIGNED TO LOW SEG
HRRM T1,.JDAT+JOBCOR## ;SET INITIAL CORE ASSIGNMENT IN JOB DATA AREA FOR
; USER TO USE TO RESET CORE TO INITIAL SETTING WHEN
; PROGRAM IS RESTARTED
REPEAT 0,<
SKIPG .USUSN ;MAP SECTION 0 AND 1 TOGETHER?
>
JRST TPOPJ## ;NO, ALL DONE
REPEAT 0,<
MOVSI T1,.PAGCS ;SET TO MAP SECTION 0 AND 1 TOGETHER
MOVE T2,[PG.SLO+1] ;ARGUMENT TO PAGE UUO
PUSHJ P,PAGUUO ;DO IT
JRST OVRERR## ;MUST OVERLAP
JRST TPOPJ## ;OK, RETURN
>
LOWFI1: POP P,T2 ;HIGHEST ADDRESS WITHIN THE SECTION TO ALLOCATE
CAIN T2,PG.BDY ;NOT CHANGING ANYTHING?
POPJ P, ;YES, JUST EXIT
PUSHJ P,SVPCS## ;SAVE PCS, SET IT TO (.USUSN)
PUSHJ P,CLRASA ;ALCORE WORKS WITH JS.ASA OFF
MOVEI T1,PAGSIZ ;START ALLOCATING AT PAGE 1
PUSHJ P,ALCORE## ;ALLOCATE THE NEEDED NZS CORE
PJRST SETASA ;TURN JS.ASA BACK ON AND RETURN
;ROUTINE TO EXECUTE DUMP MODE COMMAND LIST SETUP IN SGALEN(R)
;AND CHECK FOR ERRORS. USED ONLY TO READ LOW FILE.
;CALL: PUSHJ P,SGDO
; INPUT 0,SGALEN OR OUTPUT 0,SGALEN
; OK RETURN(NO ERRORS)
;SGDOA CALLED FROM SAVE, IT HAS ALREADY SET LH OF USRHCU=-2
;TO INDICATE CORE IS COMPRESSED
SGDO: HRROS USRHCU## ;SET LH OF USRCHU-1 AS A FLAG TO INDICATE SAVE GET
; LOW FILE IO IN PROGRESS, SO MONITOR WILL
; NOT STORE HIGH SEG PROTECTION IN JOBHRL WHICH
; HAS IOWD FOR ZERO COMPRESSION
SGDOA: SETZM .JDAT+SGAEND
XCT @(P) ;EXECUTE INPUT OR OUTPUT UUO
MOVE J,.CPJOB## ;READ INTO PROTECTED PART OF JOB DATA AREA
PUSHJ P,EXPAND ;EXPAND CORE IMAGE
JRST ADRERR## ;ADDRESS CHECK, PRINT MESSAGE AND STOP JOB
MOVE T1,.JDAT+JOBDDT## ;COPY DDT STARTING ADR
MOVEM T1,USRDDT## ;INTO MONITOR PROTECTED AREA(IN CASE THIS IS GET)
SETZM USRHCU## ;FLAG THAT SAVE-GET IO FINISHED AND CORE EXPANDED
AOS (P) ;SKIP OVER UUO IN CALLING SEQUENCE
;ROUTINE TO CHECK FOR IO ERRORS(CALLED FROM SEGCON)
;CALL: MOVE F,DEVICE DATA BLOCK ADDRESS
; PUSHJ P,SGIOCK
; RETURN ONLY IF NO ERRORS
SGIOCK::MOVE S,DEVIOS(F) ;IO STATUS WORD FOR THIS DEVICE
TRNN S,IOBKTL!IODTER!IODERR!IOIMPM ;ANY ERRORS ON SAVE-GET DEVICE?
POPJ P, ;NO, GIVE OK RETURN
MOVSI T1,USRMOD ;USER-MODE BIT
TDNN T1,.JDAT+JOBPD1## ;FROM A UUO?
JRST SGIO2 ;NO, SKIP THIS
POP P,.PDTMC##(W) ;RESTORE VM LOCS
POP P,.PDTMI##(W)
SGIO2:: MOVEI T1,TRNERR ;YES, ERROR CODE IN CASE THIS IS RUN UUO
; (TRANSMISSION ERROR)
PUSHJ P,SGRELE ;RELEASE DEVICE AND ERROR RETURN TO USER IF RUN UUO
; OR FIND TTY AND PRINT ?CRLF
JSP T1,PHOLD## ;START TTY AND STOP JOB
ASCIZ /Transmission error/
SUBTTL SAVGET -- EXPAND COMPRESSED FILES
;ROUTINE TO EXPAND CORE AFTER A SAVE(LOW SEG ONLY)
;CALL: MOVE F,DEVICE ADR.
; MOVE R,JOBADR.
; MOVE J,JOB NUMBER
; PUSHJ P,EXPAND
; ERROR RETURN, ADR. CHECK, OR NEED CORE BUT NOT CURRENT USER(COMMAND
; DECODER EXPANDING AFTER USER HAS REDUCE CORE)
; OK RETURN, CORE EXPANDED
;CALLED FROM SAVE AND COMMAND DECODER
;START,CSTART,DDT,REENTER,SAVE,SSAVE COMMANDS IF CORE STILL COMPRESSED
EXPAND: HLRE P3,.JDAT+SGALEN ;-LENGTH OF FILE
MOVNS P3 ;+LENGTH OF FILE
ADDI P3,JOBSVM## ;ADD FIRST LOC-1 TO FORM HIGHEST LEGAL ADR.
SKIPL T1,.JDAT+JOBSV## ;IF FIRST LOC IS POSITIVE
JRST SGDO1 ;OLD FORMAT, SO DONT EXPAND
AOJE T1,SGDO2 ;DO NOT EXPAND IF NOT COMPRESSED
PUSHJ P,SAVE1## ;SAVE P1
HRRZ T1,.JDAT+JOBSV## ;LOOK AT 1ST WORD OF FILE
CAILE T1,JOBDDT## ;IS IT BELOW JOBJDA?
JRST EXPND1 ;NO. NEW COMPRESSED FORMAT
CAIE T1,JOBSAV## ;IS JOBDDT THE DATA WORD?
JRST EXPND1 ;NO. EXPAND
SKIPN .JDAT+JOBSV3## ;IS THE SAVE FILE FROM CONVERT?
; CONVERT DOES NOT ZERO COMPESS
; IT JUST WRITES ENTIRE FILE WITH 1 IOWD IN FRONT
SOJA P3,SGDO1 ;YES, GO BLT DATA DOWN AS IF OLD DISK SAVE FILE
; (NON-COMPRESSED)
HRROI T1,JOBSD1## ;YES. CHANGE TO IOWD 1,JOBSDD
EXCH T1,.JDAT+JOBSV## ;ZAP. THE IOWD IS FIXED
HLRES T1 ;WORD COUNT OF IOWD
AOJE T1,EXPND1 ;JUST 1 DATA WORD - THROUGH
MOVSI T1,1(T1) ;MAKE IOWD N-2,JOBSAV
JUMPE T1,EXPZ
HRRI T1,JOBSAV## ;SO NEXT DATA WDS WILL BE SKIPPED
MOVEI T2,.JDAT+JOBSV##
MOVEM T1,2(T2) ;STORE IN COMPRESSED DATA
JRST EXPND1
EXPZ: MOVSI T1,-2
HLLM T1,.JDAT+JOBSV##
;COME HERE TO DO THE ACTUAL EXPANSION OF A FILE
EXPND1: MOVEI T1,JOBSV## ;IT WAS READ INTO JOBSV
EXCTUX <MOVE T2,@T1> ;GET FIRST IOWD
EXPLP1: HRRZ P1,T2 ;ADDRESS OF IOWD
CAIGE P1,JOBSD1## ;LEGAL?
AOJA P1,TOOLOW ;NO. DELETE DATA WHICH IS TOO LOW
HLRE P1,T2 ;YES. GET WORDCOUNT
MOVNS P1 ;+N
HRLM P1,T2 ;CONVERT IOWD TO +N IN LH
ADDI T1,1(P1) ;ADDRESS OF NEXT IOWD
CAMLE T1,P3 ;IN BOUNDS?
JRST GETERR ;NO. COMPLAIN
ADDI T2,(P1) ;YES. CHANGE RH OF IOWD
EXCTUU <EXCH T2,@T1> ;MAKE IT XWD +N,A+N-1 AFTER DATA BLOCK
JUMPL T2,EXPLP1 ;CONTINUE IF NEXT THING IS AN IOWD
HLRZ P1,T2 ;GET LH OF SUSPECTED STARTING
CAIE P1,(JRST) ;IS IT JRST?
CAIN P1,(HALT) ;OR HALT?
SKIPA ;YES,
JRST EXPLP1 ;NO, LOOP BACK AND ASSUME JUST
; A COUNT OF GREATER THAN 128K
; GET ADDRESS CHECK MESSAGE IF FILE
; WAS NOT THAT BIG
PUSH P,T1 ;SAVE DATA LOCATION
EXCTUX <HRRZ T1,@T1> ;TOP REAL LOCATION NEEDED
TRO T1,PG.BDY ;MAKE IT NK-1
HLRZ T2,R ;PRESENT SIZ OF LOW SEG
CAMG T1,T2 ;IS THERE ENOUGH?
JRST EXPCOR ;YES,
CAME J,.CPJOB## ;NO, IS TIS THE CURENT JOB?
JRST SGDOER ;NO, GIVE ERROR RETURN, MUST BE COMMAND DECODER
; DOING EXPAND AFTER USER HAS REDUECED CORE
PUSH P,.JDAT+JOBUAL##+6 ;DEFEND AGAINST PAGE UUO
PUSHJ P,GETCOR ;YES. GET IT
POP P,.JDAT+JOBUAL##+6
EXPCOR: POP P,T2
MOVEI P1,@T2 ;TOP DATA LOC
HRLI P1,1(P1) ;SET TO ZERO TO TOP OF CORE
HRRI P1,2(P1)
EXCTXU <SETZM -1(P1)> ;ZERO FIRST LOC
EXCTUU <BLT P1,@T1> ;CLEAR CORE
MOVEI T4,JOBSV## ;SET UP END-OF-LOOP WORD
HLL T4,T2 ;R IN LH(T4) IF KA10
HRROI T1,@T2 ;FROM DATA POINTER
EXPLP2: EXCTUX <HRRZ P1,(T1)> ;TO DATA POINTER
MOVSS R ;CHECK ADR OF, IOWD
CAILE P1,(R) ;IN BOUNDS?
JRST GETER0 ;NO-ERROR
MOVSS R ;YES. OK
CAIGE P1,(T1) ;MAKE SURE WE DO NOT GO BACKWARDS
JRST GETERR ; CAN HAPPEN IF TOO MANY IOWDS W/O 0'S.
EXCTUX <HLRZ P2,(T1)> ;WORD COUNT
SUBI T2,1(P2) ;POINT T2 TO PREVIOUS IOWD
JUMPE P2,EXPLP5 ;FORGET IT IF ZERO WORD-COUNT
EXCTXU <SETZM (T1)>
SOSA T1 ;POINT TO DATA
EXPLP3: SOS P1
CAIGE P1,JOBSDD##
JRST EXPLP5
JRST EXPLP6
EXPLP5: SOSA T1
EXPLP6: EXCTUU <POP T1,(P1)> ;MOVE A DATA WORD
EXCTUU <SETZM 1(T1)> ;ZERO WHERE IT CAME FROM
SOJG P2,EXPLP3 ;LOOP IF MORE DATA
CAMLE T2,T4 ;THROUGH?
JRST EXPLP2 ;NO. DO NEXT BLOCK
EXCH P2,.JDAT+JOBSDD## ;YES. ZERO JOBSDD
MOVEM P2,.JDAT+JOBDDT## ;SET USER DDT STR ADR
JRST SGDO2 ;AND SETUP USRDDT IN MONITOR PROTECTED
; FROM THIS USER
;THIS ROUTINE WILL DELETE ALL DATA FROM A COMPRESSED FILE
;WHICH IS BELOW JOBSDD (PROBABLY WRITTEN BY TENDUMP)
TOOLOW: EXCTUX <HLRE P2,@T1> ;WORDCOUNT OF OFFENDING IOWD
JUMPGE P2,GETERR ;PROHIBIT AGAINST UNFORMATTED SAVE FILES
SUB P1,P2 ;ADDRESS+N
HLRZ T2,R ;PROTECTION
CAILE P1,(T2) ;ADR TOO HIGH?
JRST GETERR ;YES, COMPLAIN
CAIG P1,JOBSDD## ;IS ANY DATA IN IT LEGAL?
AOJA T1,NXIOWD ;NO, TEST NEXT IOWD
SUBI P1,JOBSDD## ;YES, NUMBER OF WORDS TO KEEP
MOVNS P2 ;TOTAL NUMBER OF WORDS
SUBB P2,P1 ;NUMBER OF WORDS TO DROP
HRLS P2 ;INTO BOTH HALVES
EXCTUX <ADD P2,@T1> ;NEW IOWD FOR ONLY GOOD DATA
ADDI T1,(P1) ;POINT T1 TO LAST BAD DATA LOC
EXCTXU <MOVEM P2,@T1> ;STORE UPDATED IOWD OVER IT
JRST IOWBLT ;GO BLT OVER BAD DATA
NXIOWD: SUB T1,P2 ;POINT T1 TO NEXT IOWD
CAMLE T1,P3 ;PROTECTION
JRST SGDOR2
EXCTUX <HRRZ P1,@T1> ;GET ADDRESS
CAIGE P1,JOBSD1## ;LEGAL?
AOJA P1,TOOLOW ;NO, AT LEAST PART OF THE DATA IS LOW
IOWBLT: EXCTUX <MOVSI T2,@T1> ;YES. KEEP THE ENTIRE IOWD DATA
HRRI T2,JOBSV## ;T2 IS A BLT POINTER
SUBI T1,JOBSV## ;RH OF T1 IS AMOUNT BEING DELETED
SUBI P3,(T1) ;P3 POINTS TO TOP OF DATA READ IN-(N)
EXCTUU <BLT T2,@P3> ;MOVE ONLY GOOD DATA DOWN
JRST EXPND1 ;GO EXPAND THE GOOD DATA
SGDO1: MOVEI T1,JOBDDT## ;MOVE EVERYTHING DOWN )MUST BE NON-COMPRESSED DSK FILE
HRLI T1,JOBSVD##(T1) ;OR CONVERT SAVE FILE
SKIPGE .JDAT+JOBSV## ;IS THIS CONVERT FILE(FIRST WORD IS IOWD)?
HRLI T1,JOBSDP##(T1) ;YES, ALSO SKIP OVER IOWD
SUBI P3,JOBSVD##
EXCTUU <BLT T1,(P3)>
SGDO2: AOSA (P) ;SET FOR OK RETURN
SGDOER: POP P,T1
SGDOR2: SETZM USRHCU## ;CLEAR LH AND SET HIGHEST USER CHAN. IN
; USE TO 0(WHERE IT SHOULD BE ANYWAY)
POPJ P, ;ERROR RETURN OR OK RETURN
;ROUTINE TO CHECK USER SUPPLIED CORE ARG AND CHECK TO SEE IF 0
;OR GREATER THAN OR EQUAL TO IOWD USED TO SAVE OR GET FILE
;CALL: HLRE T2,-NO. OF WORDS IN FILE
; PUSHJ P,CKIOWD
; RETURN WITH LARGER OF 2 POSITIVE NOS. IN T1(1777 ORED IN)
; DO NOT RETURN IF CORE ARG SUPLLIED BY USER IS TOO SMALL
;CALLED FROM SAVE AND GET
CKIOWD: MOVEI T1,JOBSVM## ;FIRST LOC-1 READ OR WRITTEN IN USER AREA
HRRM T1,.JDAT+SGALEN ;RESTORE RH TO JOBSAV AFTER LOOKUP
SUB T1,T2 ;HIGHEST LOC=FIRST LOC-1+LENGTH OF FILE
; FALL INTO CHSARG
;ROUTINE TO CHECK USER SUPPLIED CORE ARG AND CHECK IF 0
;OR GREATER THAN OR EQUAL TO CORE ARG FOR PREVIOUS SAVE
;CALL: HRRZ T1,JOBCOR(R) ;WRITTEN WHEN FILE SAVED
; PUSHJ P,CKSARG
; RETURN WITH LARGER OF 2 IN AC T1, ONLY IF USER ARG NOT TOO SMALL
;CALLED ONLY FROM GET AFTER JOB DATA AREA LOADED FROM FILE(JOBCOR) OR HIGH SEG
CKSARG: IORI T1,PG.BDY ;MAKE SURE 1K-1
CAMLE T1,.JDAT+SGANEW ;IS USER SUPPLIED ARG BIGGER?
JRST CKSAR1 ;NO
MOVE T1,.JDAT+SGANEW ;YES, RETURN IT
POPJ P,
CKSAR1: PUSH P,T1 ;IN CASE OF ERROR
SKIPN .JDAT+SGANEW ;DID USER SUPPLY ONE?
PJRST TPOPJ## ;NO, RETURN LARGER OF TWO
;ROUTINE TO PRINT #K OF CORE NEEDED
;CALL: PUSH P,HIGHEST REL. USER ADR.
; JRST NROOM
; NEVER RETURN
NOROOM::MOVEI T1,NECERR ;NOT ENOUGH CORE ERROR CODE
NROOM:: PUSHJ P,SGRELE ;RELEASE DEVICE AND ERROR RETURN TO USER IF RUN UUO
; OR FIND TTY AND PRINT ?CRLF
PUSHJ P,EXONLY ;SET JS.XO AS APPROPRIATE
HRRZ T1,(P) ;GET AMOUNT OF CORE REQUESTED
LSH T1,W2PLSH ;CONVERT TO NO. OF 1K BLOCKS-1
PUSHJ P,DECP1 ;ADD 1 TO T1 AND PRINT DECIMAL
PUSHJ P,PRPORK ;PRINT "P" OR "K"
JSP T1,PHOLD## ;START TTY ADN STOP JOB
ASCIZ / of core needed/
SUBTTL SAVGET -- SUBROUTINES
;ROUTINE TO ASSIGN CORE FOR LOW AND HIGH SEG
;CALL: MOVE R,LOW SEG RELOCATION
; HRR T1,HIGHEST LOC DESIRED
; PUSHJ P,GETCOR
; RETURN ONLY IF ASSIGNED
GETCOR::PUSHJ P,SAVE1## ;SAVE P1 FOR EXE FILES
HRRZM T1,.JDAT+SGACOR ;SOTRE CORE ARG FOR CORE UUO IN USER AC
PUSH P,T1 ;SAVE IN CASE OF ERROR
MOVE J,.CPJOB##
REPEAT 0,<
MOVE T4,T1
SKIPN T2,.USREL
HLRZ T2,R
IORI T4,PG.BDY
SUB T4,T2
LSH T4,W2PLSH
PUSHJ P,GSIZT##
JRST GETGET
SKIPA T2,.USBTS
JRST GETCR1
TLNN T2,(UP.GET)
JRST GETGET
>
GETCR1: CALLI SGACOR,200011 ;DO PHYSICAL-ONLY CORE UUO
JRST NOROOM ;NOT AVAILABLE, PRINT ERROR AND AMOUNT TRYING FOR
JRST TPOPJ## ;OK, REMOVE T1 FROM PD LIST AND RETURN
SETASJ::PUSH P,J ;SAVE J
MOVE J,.CPJOB## ;J=JOB NUMBER OF CURRENT JOB
PUSHJ P,SETASA ;MAKE AC REFERENCES BE TO THE SHADOW AREA
JRST JPOPJ## ;RESTORE J AND RETURN
SETASA::PUSH P,T1 ;SAVE T1
IFN FTXMON,<
MOVEI T1,0 ;SET PCS TO 0 SO REFERENCES TO JOBUAL WORK
PUSHJ P,STPCS## ;CORRECTLY (DON'T IME)
>
MOVEI T1,JS.ASA ;LITE THE BIT WHICH INDICATES REFERENCES TO
IORM T1,JBTSTS##(J) ; LOCATIONS 0-17 IN THE USER'S AREA ARE TO SHADOW ACS
JRST TPOPJ## ;RETURN
CLRASA::PUSHJ P,SAVE1## ;SAVE P1
MOVEI P1,JS.ASA ;CLEAR THE BIT WHICH INDICATES REFERENCES TO
ANDCAM P1,JBTSTS##(J) ; USER LOCATIONS 0-17 ARE TO SHADOW ACS
POPJ P, ;AND RETURN
;ROUTINE TO PRINT NOT A SAVE FILE IF WRONG FORMAT FILE DETECTED
GETER0: MOVSS R ;"SAVE" FILE ISN'T RIGHT
GETERR::MOVEI T1,NSFERR ;ERROR CODE IN CASE THIS IS RUN UUO(NOT SAVE FILE)
PUSHJ P,SGRELE ;RELEASE DEVICE AND ERROR RETURN TO USER IF RUN UUO
; OR FIND TTY AND PRINT ?CRLF
JSP T1,PHOLD## ;START TTY AND STOP JOB
ASCIZ /Not a save file/
;ROUTINE TO PRINT FILE NOT FOUND OR NEEDS 2 RELOC REG
NOFILE::MOVEI T1,FNFERR ;ERROR CODE IN CASE THIS IS RUN UUO(FILE NOT FOUND)
; CHANGE ERROR CODE TO DISK ERROR CODE IF DEV IS DSK
PUSHJ P,SGRELL ;RETURN DISK LOOKUP OR ENTER ERROR CODE IF DSK
; RELEASE DEVICE AND ERROR RETURN TO USER IF HE WANTED
; OR FIND TTY AND PRINT ?CRLF
HRRZ T1,.JDAT+SGAEXT ;SEE WHICH ERROR
JUMPN T1,LOOKFL ;NOT NOT FOUND
SKIPN T2,.JDAT+SGANAM ;PRINT FILE NAME
JRST NOLKFL ;NO FILE PROVIDED
PUSHJ P,PRNAME
PUSHJ P,PRPER ;PRINT PERIOD
HLLZ T2,.JDAT+SGAEXT ;PRINT EXTENSION
PUSHJ P,PRNAME
JSP T1,PHOLD## ;START TTY AND STOP JOB
ASCIZ / not found/
NOLKFL: JSP T1,PHOLD## ;START TTY AND STOP JOB
ASCIZ /No file specified /
LOOKFL: PJSP T1,LKENFL ;LOOKUP ERROR - PRINT MESSAGE
ASCIZ /Lookup error /
LKENFL: PUSHJ P,CONMES ;ISSUE MESSAGE
HRRZ T1,.JDAT+SGAEXT ;GET ERROR
SKIPE T1 ;SEE IF = 0
PUSHJ P,PRTDI8 ;NO - PRINT IN OCTAL
PJRST HOLD## ;STOP JOB
;ROUTINE TO RELEASE DEVICE ON AN ERROR AND CHECK TO SEE
;IF THIS IS A MONITOR COMMAND OR USER UUO
;IF USER UUO, GIVE ERROR RETURN TO USER UNLESS THERE IS A HALT
;IN LH OF EROR RETURN WORD, IN WHICH CASE FIND TTY, PRINT ?CRLF
;AND RETURN TO CALLER SO CAN ADD MORE INFO TO ERROR MESSAGE AND STOP JOB
;CALL: MOVEI T1,ERROR CODE(DEFINED IN S.MAC)
; PUSHJ P,SGRELE
;DO NOT RETURN TO CALLER IF USER WANTS ERROR RETURN ON RUN AND GETSEG UUOS
SGRELL: ;LOOKUP OR ENTER FAILURE
MOVE T2,DEVMOD(F) ;IS THIS DEVICE A DISK?
TLNE T2,DVDSK
HRRZ T1,.JDAT+SGAEXT ;YES, RETURN DISK SERVICE ERROR CODE
SGRELE::PUSH P,T1 ;SAVE T1
MOVE J,.CPJOB## ;GET JOB #
CAMN J,CAUSER## ;DO WE OWN THE CA?
PUSHJ P,CAFREE## ;YES, FREE IT
MOVE P1,.JDAT+SGAEND ;GET FLAGS
TLNN P1,GTMRG!GTSAV!GTSGO ;DON'T RELEASE HI-SEG IF MERGING OR SEGOPING
SKIPN .JDAT+JOBPD1## ;SKIP IF SAVE IS IN PROGRESS
; IF IT IS NOT WE WANT TO KILL ANY
; HISEG WE MAY HAVE GOTTEN. THIS
; PREVENTS US FROM LEAVING AN EXECUTE
; ONLY HISEG ADDRESSABLE WHEN A RUN UUO
; FAILS.
JRST SEGRLX ;MERGING OR SAVING, KEEP HIGH SEG
HRRZ T1,JBTSGN##(J) ;RELEASE SEGMENT JUST GOTTEN
IFE FTMP,<
PUSHJ P,KILHSH## ;KILL THE HISEG IF NOT SAVE
>
IFN FTMP,<
PUSHJ P,[PUSHJ P,GGVMM## ;MUST OWN THE MM RESOURCE
PJRST KILHSH##] ;REMOVE THE HI SEG
>
SEGRLX: MOVEI T2,JS.RUU ;CLEAR RUN FLAG
ANDCAM T2,JBTSTS##(J) ; SO FILSER STOPS ITS CHECKS
GETPC T2,.JDAT+JOBPD1## ;GET FIRST PC ON PD LIST
MOVSI T1,(UP.CTX) ;IF RUN UUO FAILED WHILE BEING
TDNE T1,.USBTS ; CALLED BY THE CONTEXT UUO, THEN
JRST SGRLE1 ; THE UUO PC ISN'T IN ORIGINAL USER CORE
TLNN T2,USRMOD ;IS IT IN USER MODE(IE USER UUO)?
JRST SGRLE1 ;NO, MUST BE MONITOR COMMAND OR CALLER OVERLAYED
; RELEASE DEVICE, FIND TTY, AND RETURN TO CALLER
HRR M,T2 ;ADDRESS OF RETURN AFTER RUN OR GETSEG UUO
TRNN M,777760 ;FROM AC'S?
JRST SGRLE1 ;YES - TYPE MESSAGE
PUSHJ P,GETWRD## ;GET ERROR RETURN WORD FROM RUN OR GETSEG UUO
MOVSI T1,(HALT)
LSH T1,-^D23 ;ISOLATE OP CODE
CAIN T1,<HALT>B58 ;IS IT HALT?
JRST SGRLE1 ;YES, RELEASE DEVICE,FIND TTY, AND RETURN TO CALLER
SGRLE0: SKIPE USRJDA## ;DO NOT RELEASE CHANNEL 0 IF NOT INITED YET
; UUO HANDLER DOES NOT ALLOW THIS FROM EXEC MODE
RELEAS 0, ;RELEASE DEVICE(IF INITED)
PUSHJ P,CLRASA ;CLEAR EXEC MODE UUO FLAG
HRR M,.JDAT+JOBPD3##+1 ;NO, AC NUMBER OF RUN OR GETSEG UUO
POP P,T1 ;RESTORE ERROR CODE
TLNE P1,GTSGO ;SEGOP?
JRST [MOVSI T2,.USUAC;YES, DO THAT DIFFERENTLY
EXCTXU <BLT T2,17> ;RESTORE THE USER'S ACS
MOVE T2,.JDAT+JOBPD3##+2 ;STORED USRJDA FOR USER CHANNEL 0
MOVEM T2,USRJDA## ;RESTORE THAT AS WELL
JRST .+1] ;STORE ERROR CODE AND RETURN TO THE USER
PUSHJ P,PUTWDU## ;STORE ERROR NUMBER IN USER AC
JRST ERRGOU## ;PUT RETURN ON END OF PDLIST
; AND RETURN TO USER TO HANDLE ERROR
SGRLE1: POP P,T1 ;REMOVE ERROR CODE FROM LIST
MOVSI T2,(UP.CTX) ;IF CALLED BY THE CONTEXT UUO
TDNE T2,.USBTS ; THEN NO MORE CAN BE DONE HERE AND
PJRST CTXRUE## ; CTXSER MUST FINISH ERROR RECOVERY
MOVSI T1,.JDAT ;SAVUAC WILL STORE OVER
EXCTXU <BLT T1,17> ; SHADOW ACS, SO SET USERS ACS
SGRLE2: PUSHJ P,SGREL ;RELEASE DEVICE AND FIND TTY
PUSHJ P,TTYFUW## ;MAKE SURE ATTACHED FOR ERROR MESSAGES
PUSHJ P,TSETBI## ;CLEAR TYPE AHEAD
SETZM JBTPRG##(J) ;CLEAR NAME SINCE LOST
MOVSI T1,(PD.PGR) ;WAS THIS A .STPGM RUN?
TDNN T1,.PDDFL##(W)
JRST PPQCRL ;NO, BYPASS CODE
ANDCAM T1,.PDDFL##(W) ;CLEAR BIT (JUST PARANOIA)
MOVE T1,LGINAM## ;GET NAME OF LOGOUT CUSP
MOVEM T1,.PDPGM##(W) ;AND STORE AS CUSP-TO-RUN.
PUSHJ P,INLMES ;AND TELL THE USER WHAT HAPPENED TO HIM
ASCIZ \
%.STPGM run failed, logging job out.
\
PPQCRL::PJSP T1,CONMES ;PRINT ? ON SAME LINE AS ERROR MSG,
;FOR BATCH AND SCRIPT, RETURN TO CALLER
; WHO WILL PRINT REST OF ERROR MESSAGE AND STOP JOB
ASCIZ /
?/
$LIT
COMEND: END ;END OF COMCON