1
0
mirror of https://github.com/PDP-10/stacken.git synced 2026-03-09 03:59:45 +00:00
Files
Lars Brinkhoff 6e18f5ebef Extract files from tape images.
Some tapes could not be extracted.
2021-01-29 10:47:33 +01:00

3592 lines
122 KiB
Plaintext
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
TITLE BATCON - GALAXY-10 Batch controller
SUBTTL C.D.O'Toole, D.P.Mastrovito /CDO/DPM 12-SEP-85
;
;
; COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION
; 1974,1975,1976,1977,1978,1979,1980,1981,1982,1983,1984,1986,1987.
; ALL RIGHTS RESERVED.
;
;
; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED
; AND COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE
; AND WITH THE INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS
; SOFTWARE OR ANY OTHER COPIES THEREOF MAY NOT BE PROVIDED OR
; OTHERWISE MADE AVAILABLE TO ANY OTHER PERSON. NO TITLE TO
; AND OWNERSHIP OF THE SOFTWARE IS HEREBY TRANSFERRED.
;
; THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE
; WITHOUT NOTICE AND SHOULD NOT BE CONSTRUED AS A COMMITMENT
; BY DIGITAL EQUIPMENT CORPORATION.
;
; DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY
; OF ITS SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY
; DIGITAL.
SEARCH BATMAC ;BATCON SYMBOLS
SEARCH GLXMAC ;GALAXY SYMBOLS
SEARCH QSRMAC ;QUASAR SYMBOLS
SEARCH ORNMAC ;ORION SYMBOLS
PROLOG (BATCON) ;SET UP
%%.BAT==:%%.BAT ;FORCE VERSION INTO SYMBOL TABLE
TOPS10 <IF1,<PRINTX [Assembling GALAXY-10 BATCON]>>
TOPS20 <IF1,<PRINTX [Assembling GALAXY-20 BATCON]>>
GLOB <LOGERR>
LOC <.JBVER==:137>
EXP %%.BAT ;BATCON VERSION NUMBER
RELOC 0
COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1971,1987. ALL RIGHTS RESERVED.
\;END COPYRIGHT MACRO
SUBTTL Table of contents
; TABLE OF CONTENTS FOR BATCON
;
;
; SECTION PAGE
; 1. Table of contents......................................... 2
; 2. BATCON Data Base.......................................... 3
; 3. Popular ITEXT blocks...................................... 4
; 4. Program initialization and reentry........................ 5
; 5. Job scheduler
; 5.1 Toplevel.......................................... 6
; 5.2 Fast batch shutdown............................... 8
; 5.3 Clock queue control............................... 9
; 5.4 Checkpoint........................................ 12
; 5.5 Message processing................................ 14
; 6. IPCF/Operator/QUASAR interface
; 6.1 IPCF interrupts................................... 15
; 6.2 Hello and goodbye................................. 16
; 6.3 IPCF message processing........................... 17
; 6.4 Message tables.................................... 18
; 6.5 Validate messages................................. 20
; 6.6 Initialize stream block........................... 21
; 6.7 Message block processing.......................... 22
; 6.8 QUASAR communication.............................. 23
; 6.9 Ask for operator response......................... 25
; 6.10 Unknown message................................... 26
; 6.11 QUASAR message #5 (NEXTJOB)....................... 27
; 6.12 QUASAR message #6 (ABORT)......................... 29
; 6.13 QUASAR message #22 (SETUP)........................ 30
; 6.14 QUASAR message #60 (ALLOCATION)................... 33
; 6.15 ORION message #200004 (PAUSE)..................... 34
; 6.16 ORION message #200005 (CONTINUE).................. 35
; 6.17 ORION message #200012 (RESPONSE).................. 36
; 6.18 ORION message #200025 (REQUEUE)................... 37
; 6.19 ORION message #200026 (CANCEL).................... 38
; 6.20 ORION message #200035 (SEND)...................... 40
; 6.21 ORION message #200036 (EXAMINE)................... 41
; 6.22 ACK message #700000............................... 42
; 7. STPPRC - Batch step processor............................. 44
; 8. JOBPRC - Process a Batch stream........................... 45
; 9. BATCON initialization
; 9.1 System independant code........................... 46
; 9.2 TOPS-10 code...................................... 47
; 9.3 TOPS-20 code...................................... 48
; 10. Batch generated commands
; 10.1 Buffer management................................. 49
; 10.2 TOPS-10 Login..................................... 51
; 10.3 TOPS-20 Login..................................... 54
; 10.4 Kill a job........................................ 56
; 10.5 CLOSE/DUMP........................................ 58
; 11. Batch WTO/WTOR
; 11.1 Initialization and character storage.............. 59
; 11.2 IPCF page setup................................... 60
; 11.3 Write To OPR (WTO)................................ 61
; 11.4 Write To OPR with a Response (WTOR)............... 62
; 11.5 Get operator response to a WTOR................... 63
; 12. Response buffer support................................... 64
; 13. Batch error handling
; 13.1 Error, operator, dialogue, or quote checking...... 65
; 13.2 LOGIN error analysis.............................. 66
; 14. MDA interface............................................. 67
; 15. MODIFY interface.......................................... 68
; 16. End of job processing..................................... 69
; 17. JOBINI - Initialize job processing........................ 70
; 18. TIMERR - Time limit exceeded.............................. 71
; 19. Stream termination
; 19.1 Dismiss job....................................... 73
; 19.2 Build release message............................. 74
; 19.3 Data base cleanup................................. 75
; 20. IOWAIT - Wait for I/O completion.......................... 76
; 21. Random Little Routines.................................... 77
; 22. DELSPL - Delete spooled input files....................... 78
; 23. Get job status............................................ 79
; 24. LUUO handler.............................................. 80
; 25. PTY interrupt handler..................................... 81
; 26. ERRTAB EXPAND ERROR TABLE VALUES......................... 82
; 27. Literals.................................................. 83
; 28. End....................................................... 84
SUBTTL BATCON Data Base
; Global data
;
LOWDAT:! ;BEGINING OF BLOCK TO CLEAR ON START UP
G$PDL:: BLOCK TPSIZE ;TOP LEVEL PUSH DOWN LIST
G$IB:: BLOCK IB.SZ ;GLXLIB INITIALIZATION BLOCK
G$PIB:: BLOCK PB.MNS ;GLXLIB PID BLOCK
G$SAB:: BLOCK SAB.SZ ;GLXLIB IPCF SEND ARGUMENT BLOCK
G$MDA:: BLOCK 1 ;MDA FLAG
G$UDT:: BLOCK 1 ;DATE/TIME OF LAST SCHEDULER PASS
G$CPU:: BLOCK 1 ;CPU TYPE CODE
G$MADR:: BLOCK 1 ;MESSAGE ADDRESS
G$MIDX:: BLOCK 1 ;INDEX INTO MESSAGE TABLES
G$MBLK:: BLOCK 1 ;MESSAGE BLOCK POINTER
G$MARG:: BLOCK 1 ;MESSAGE ARGUMENT COUNT
G$CORE:: BLOCK 1 ;FLAG WORD FOR CORE CHECKING
G$NODE:: BLOCK 1 ;BATCON'S NODE
G$SPLD:: BLOCK 1 ;SPOOLED PPN OR DIRECTORY NUMBER
G$PTYF:: BLOCK 1 ;FIRST PTY IN THE SYSTEM
G$PTYN:: BLOCK 1 ;NUMBER OF PTYS IN THE SYSTEM
G$TIME:: BLOCK 2 ;ASCIZ TIME FOR TIME STAMPS
G$STRM:: BLOCK JOBMAX ;STREAM INDEX BLOCK
G$BASE:: BLOCK JOBMAX ;STREAM DATA BASE POINTERS
G$FAIR:: BLOCK 1 ;FAIRNESS COUNT
G$FFLG:: BLOCK 1 ;FAIRNESS COUNT EXPIRED FLAG
G$KILL:: BLOCK 1 ;KILL ALL JOBS FLAG
G$PSCN:: BLOCK 1 ;PRESCAN FLAG
G$HACT:: BLOCK 1 ;HIGHEST STREAM NUMBER ACTIVE
G$SACT:: BLOCK 1 ;NUMBER OF ACTIVE STREAMS
G$TMTX:: BLOCK 2 ;ASCIZ TIME TEXT BUFFER
G$TPTR:: BLOCK 1 ;TEMPORARY BYTE POINTER
G$TCTR:: BLOCK 1 ;TEMPORARY BYTE COUNT
G$KSYS:: BLOCK 1 ;NON-ZERO IF KSYS IN PROGRESS
G$BUDT:: BLOCK 1 ;UDT WHEN TO SAY GOODBYE IF IDLE
G$SSET:: BLOCK 1 ;NUMBER OF STREAMS SETUP
; Local data
;
WTOCNT: BLOCK 1 ;WTO BYTE COUNTER
WTOPTR: BLOCK 1 ;WTO BYTE POINTER
MAX <RSU.SZ!REL.BL!STU.SZ!REQ.SZ!CHE.SZ>
MSGADR: BLOCK MAXSIZ ;MESSAGE DATA AREA
SLPTIM: BLOCK 1 ;TIME TO SLEEP
CLKQUE: BLOCK 1 ;CLOCK REQUEST QUEUE ID
CLKEID: BLOCK 1 ;CLOCK QUEUE ENTRY ID COUNTER
TOPS10 < ;TOPS-10 ONLY
VECTOR:! ;BEGINING OF INTERRUPT VECTOR BLOCKS
VECIPC: BLOCK 4 ;IPCF INTERRUPT BLOCK
ENDVEC==.-1 ;END OF INTERRUPT VECTORS
OPRPPN: BLOCK 1 ;OPERATOR PPN
KSYZBG:! ;START OF KSYS DATA TO ZERO
KSYCNT: BLOCK 1 ;COUNT OF JOBS TO KILL
KSYSSC: BLOCK 1 ;COUNT OF KSYS STREAMS SETUP
KSYUSE: BLOCK 1 ;COUNT OF KSYS STREAMS IN USE
KSYREQ: BLOCK 1 ;FAKE REQUEST-ID
KSYNAM: BLOCK 1 ;LAST LOG FILE NAME
KSYJLO: BLOCK 1 ;COUNT OF JOBS LOGGED OFF
KSYJLE: BLOCK 1 ;COUNT OF JOBS LOGGED OFF WITH ERRORS
KSYMAP: BLOCK <^D512/^D36> ;KSYS BIT MAP
KSYLEN==.-KSYMAP ;LENGTH OF BIT MAP
KSYZND:! ;END OF KSYS DATA TO ZERO
> ;END OF TOPS-10 CONDITIONAL
TOPS20 < ;TOPS-20 ONLY
LEVTAB: BLOCK 3 ;INTERRUPT LEVEL PCS
CHNTAB: BLOCK ^D36 ;INTERRUPT CHANNEL TABLE
INTRP1: BLOCK 1 ;INTERRUPT LEVEL 1 PC
INTRP2: BLOCK 1 ;INTERRUPT LEVEL 2 PC
INTRP3: BLOCK 1 ;INTERRUPT LEVEL 3 PC
JSTBLK: BLOCK .JIMAX ;GETJI JSYS JOB STATUS BLOCK
> ;END OF TOPS-20 CONDITIONAL
LASLOW:! ;END OF BLOCK TO CLEAR ON START UP
SUBTTL Popular ITEXT blocks
; Output job information contained in .JQJBB(R)
;
JIBTXT:: ITEXT (<^R/.JQJBB(R)/^M^J>)
; Output <number> for WTOR messages
;
NUMBER:: ITEXT (<^7/[.CHLAB]/number^7/[.CHRAB]/>)
SUBTTL Program initialization and reentry
BATCON: JFCL ;NO CCL ENTRY
RESET ;STOP I/O
MOVE P,[IOWD TPSIZE,G$PDL] ;SET UP THE PDL
SETZM LOWDAT ;CLEAR THE FIRST DATA WORD
MOVE S1,[LOWDAT,,LOWDAT+1] ;SET UP BLT
BLT S1,LASLOW-1 ;CLEAR THE REST OF THE DATA SECTION
; Build the IB
;
MOVE S1,['BATCON'] ;OUR NAME
MOVEM S1,G$IB+IB.PRG ;STORE IT
MOVX S1,IP.STP ;SEND STOPCODES TO ORION
SKIPE DEBUGW ;DEBUGGING?
MOVX S1,IB.NPF ;YES - NO STOPCODES TO ORION, NO PFH
MOVEM S1,G$IB+IB.FLG ;STORE IN FLAG WORD
MOVEI S1,G$PIB ;POINT TO PID BLOCK
MOVEM S1,G$IB+IB.PIB ;STORE IT
TOPS10 <MOVEI S1,VECTOR> ;TOPS-10 PSI INTERRUPT VECTOR ADDRESS
TOPS20 <MOVE S1,[LEVTAB,,CHNTAB]> ;TOPS-20 PSI INTERRUPT TABLES
MOVEM S1,G$IB+IB.INT ;STORE IT
; Build the PIB
;
MOVX S1,INSVL.(PB.MNS,PB.LEN) ;GET BLOCK LENGTH
MOVEM S1,G$PIB+PB.HDR ;STORE IT
MOVX S1,IP.PSI ;ENABLE FOR IPCF PSI
MOVEM S1,G$PIB+PB.FLG ;SET FLAGS
MOVX S1,<INSVL.(SNDMAX,IP.SQT)!INSVL.(RCVMAX,IP.RQT)> ;IPCF QUOTAS
MOVEM S1,G$PIB+PB.SYS ;STORE THEM
TOPS10 <MOVX S1,INSVL.(VECIPC-VECTOR,IP.CHN)> ;TOPS-10 IPCF PSI VECTOR
TOPS20 <MOVX S1,INSVL.(IPCCHN,IP.CHN)> ;TOPS-20 IPCF INTERRUPT CHANNEL
MOVEM S1,G$PIB+PB.INT ;STORE IT
MOVEI S1,IB.SZ ;GET LENGTH OF BLOCK
MOVEI S2,G$IB ;GET ADDRESS OF BLOCK
PUSHJ P,I%INIT## ;INITIALIZE GLXLIB
PUSHJ P,B$INIT ;INITIALIZE BATCON
PUSHJ P,U$INIT## ;INITIALIZE CUSTOMER CODE
JRST TOPLVL ;ENTER JOB SCHEDULER
REENTER:SETOM G$KILL ;SHUTDOWN BATCH SYSTEM
TOPS10 <JRSTF @.JBOPC##> ;RETURN
TOPS20 <JRST TOPLVL> ;HOPE WE WERE STOPPED IN A SAFE PLACE
SUBTTL Job scheduler -- Toplevel
TOPLVL: PUSHJ P,KILCHK ;SEE IF WE MUST KILL ALL JOBS
PUSHJ P,U$SCHD## ;PROCESS CUSTOMER SCHEDULER STUFF
PUSHJ P,IPCF ;PROCESS IPCF MESSAGES
TOPL.1: SETZM G$FFLG ;CLEAR FAIRNESS EXPIRED FLAG
SKIPLE KSYCNT ;KSYS IN PROGRESS?
PUSHJ P,KSYSCD ;YES--SCHEDULE SOME JOBS
MOVX S,.INFIN ;A LARGE NUMBER INCASE NONE ACTIVE
SKIPN G$SACT ;ANY STREAMS ACTIVE?
JRST STEXIT ;NO - WAIT A WHILE
PUSHJ P,CLKCHK ;COUNTDOWN THE CLOCK REQUEST QUEUE
SETZ S, ;START WITH STREAM 0
TOPL.2: SKIPL R,G$BASE(S) ;GET DATA BASE ADDRESS AND STREAM FLAGS
JRST STEXIT ;STREAM NOT ACTIVE
MOVE F,.JREGS+F(R) ;LOAD STREAM FLAGS
PUSHJ P,JOBCHK ;CHECK FOR JOB'S EXISTANCE
PUSHJ P,CHKPNT ;DO CHECKPOINT IF NEEDED
PUSHJ P,PROMES ;PROCESS ANY OPERATION MESSAGES
MOVEM F,.JREGS+F(R) ;UPDATE FLAG WORD
MOVEM R,G$BASE(S) ;FLAGS HERE TOO
TXZE R,RL.MSP ;MESSAGE TO PROCESS?
JRST TOPL.3 ;YES - THEN PROCESS IT NOW
TXNE R,RL.STP!RL.OPR!RL.NSC!RL.ACK ;STOPPED, OPR/ACK WAIT, NO SCHED?
JRST STEXIT ;YES TO EITHER - IGNORE STREAM
MOVEM R,G$BASE(S) ;UPDATE RELOCATION
TOPL.3: HRLZI 0,.JREGS+1(R) ;SET UP BLT
HRRI 0,1 ;START WITH AC 1
BLT 0,14 ;LOAD ACS 1 - 14
MOVE 0,.JREGS(R) ;LOAD AC 0
MOVE 17,.JREGS+17(R) ;RELOAD AC 17
POPJ P, ;RETURN TO INTERRUPTED PROCESS
; Return from process (switch to BATCON's context).
;
QTS:: MOVEM R,G$BASE(S) ;STORE STREAM RELOCATION
MOVEM 0,.JREGS(R) ;SAVE AC 0
HRLZI 0,1 ;START WITH AC 1
HRRI 0,.JREGS+1(R) ;SET UP BLT
BLT 0,.JREGS+17(R) ;SAVE THE ACS
MOVE P,[IOWD TPSIZE,G$PDL] ;RESET BATCON'S PDL
; Here to exit from the stream
; *** Note ***
; STEXIT must be called by JRST STEXIT after CLRSTR is called since the
; stream stack (and data base) has been destroyed.
;
STEXIT: CAMGE S,G$HACT ;CHECKED ALL STREAMS YET?
AOJA S,TOPL.2 ;NO - TRY THE NEXT
AOSG G$PSCN ;DONE WITH A PRESCAN?
JRST TOPLVL ;YES - THEN NO TIME TO REST
SETZM G$PSCN ;INSURE WE DON'T ATTEMPT A PRESCAN
SKIPG G$FFLG ;FAIRNESS COUNT EXPIRE DURING JOB SCAN?
PUSHJ P,TSLEEP ;ZZZZZZ
JRST TOPLVL ;BACK TO TOP LEVEL
SUBTTL Job scheduler -- Fast batch shutdown
; Set up to kill all jobs if necessary (G$KILL non-zero).
; This routine will set the fast KJOB bit (RL.FKJ) and cause BATCON to
; kill the stream on the next pass. No attempt is made to send release
; messages to QUASAR, nor is any attempt made to recover from batch errors
; such as a job not in monitor mode or not logging out.
;
KILCHK: SKIPN G$KILL ;WANT TO KILL ALL JOBS?
POPJ P, ;NO - JUST RETURN
MOVEI S,0 ;START WITH STREAM 0
KILC.1: SKIPGE R,G$BASE(S) ;GET DATA BASE ADDRESS AND STREAM FLAGS
TXOE R,RL.FKJ ;NEED TO DO ANYTHING?
JRST KILC.2 ;NO - ON TO THE NEXT ONE
HRLI T1,-.JPSIZ ;RESET THE STREAM PDL
HRRI T1,.JPLST-1(R) ;...
PUSH T1,[B$CLOS] ;POINT TO THE CLOSE JOB ROUTINE
MOVEM T1,.JREGS+P(R) ;SAVE AS STREAM AC 'P'
TXZ R,RL.OPR!RL.STP!RL.JIE!RL.DIA ;CLEAR BATCH STREAM FLAGS
MOVX T1,FL.NER ;GET NOERROR BIT
IORM T1,.JREGS+F(R) ;SET IT
TXZ R,RL.OPR!RL.STP!RL.JIE!RL.DIA!RL.NLG ;CLEAR LOTS OF FLAGS
MOVEM R,G$BASE(S) ;UPDATE STATUS
KILC.2: CAMGE S,G$HACT ;CHECKED ALL STREAMS YET?
AOJA S,KILC.1 ;NO - LOOP
SETZM G$PSCN ;FORGET ANY PRESCAN REQUESTS
POPJ P, ;RETURN
SUBTTL Job scheduler -- Clock queue control
; Create a clock request
; Call: MOVE T1,event code,,time in seconds
; MOVE T2,dispatch address
; MOVE T3,context
; PUSHJ P,B$CLKR
; PUSHJ P,B$CLKB ;AUTOMATICALLY SET UP T3 WITH -1 (BATCON)
; PUSHJ P,B$CLKS ;AUTOMATICALLY SET UP T3 WITH C(S) (STREAM)
;
; On return, .JBCLK(R):= event code,,clock queue entry ID
;
B$CLKS::SKIPA T3,S ;INDICATE STREAM CONTEXT
B$CLKB::HRLOI T3,-1 ;INDICATE BATCON'S CONTEXT
B$CLKR::MOVE T4,T1 ;GET EVENT CODE AND SLEEP TIME
LOAD S1,T1,CQ.TIM ;GET TIME IN SECONDS
ASHC S1,-21 ;POSITION FRACTION
DIV S1,[^D24*^D60*^D60] ;DIVIDE BY SECONDS PER DAY
CAILE S2,<^D24*^D60*^D60>/2 ;OVER HALF TO THE NEXT?
AOS S1 ;YES - INCREMENT THE UDT
MOVE T1,S1 ;SAVE UDT IN A SAFE PLACE
$CALL I%NOW ;GET CURRENT DATE/TIME
ADD T1,S1 ;MAKE IT THE WAKEUP DATE/TIME
MOVE S1,CLKQUE ;GET THE CLOCK QUEUE ID
$CALL L%FIRST ;GET THE FIRST ENTRY
JRST CLKR.2 ;JUMP THE FIRST TIME THROUGH
CLKR.1: MOVE S1,CLKQUE ;GET THE CLOCK QUEUE ID
$CALL L%NEXT ;GET THE NEXT ENTRY
CLKR.2: JUMPT CLKR.3 ;ONWARD IF NO ERRORS
MOVE S1,CLKQUE ;GET THE CLOCK QUEUE ID
MOVEI S2,.CQLEN ;GET CLOCK QUEUE ENTRY LENGTH
$CALL L%CENT ;CREATE AN ENTRY AFTER THE CURRENT ONE
JRST CLKR.4 ;CONTINUE
CLKR.3: CAML T1,.CQTIM(S2) ;LESS THAN THE CURRENT ENTRY?
JRST CLKR.1 ;YES - TRY THE NEXT ENTRY
MOVE S1,CLKQUE ;GET THE CLOCK QUEUE ID
MOVEI S2,.CQLEN ;GET CLOCK QUEUE ENTRY LENGTH
$CALL L%CBFR ;CREATE AN ENTRY BEFORE THE CURRENT ONE
CLKR.4: MOVEM T1,.CQTIM(S2) ;SAVE UDT WAKEUP TIME
MOVEM T2,.CQADR(S2) ;SAVE DISPATCH ADDRESS
MOVEM T3,.CQCTX(S2) ;SAVE CONTEXT AFTER WAKEUP
MOVEM T4,.CQEVN(S2) ;SAVE EVENT CODE AND SLEEP TIME
AOS S1,CLKEID ;GET A NEW CLOCK QUEUE ENTRY ID
HRRZM S1,.CQEID(S2) ;SAVE IT
JUMPL T3,CLKR.5 ;CHECK FOR BATCON'S CONTEXT
MOVE S1,T4 ;GET THE EVENT CODE
HRR S1,.CQEID(S2) ;GET THE ENTRY ID
SKIPGE T4,G$BASE(T3) ;GET STREAM RELOCATION
MOVEM S1,.JBCLK(T4) ;SET UP CLOCK QUEUE DATA WORD
TXNN S1,CQ.NSC ;TURN OFF SCHEDULING FOR THIS STREAM?
JRST CLKR.5 ;NO
MOVX S1,RL.NSC ;GET NO SCHEDULE FLAG
IORM S1,G$BASE(T3) ;UPDATE RELOCATION WORD
CAMN T3,S ;CURRENT STREAM?
TXO R,RL.NSC ;YES
CLKR.5: PUSHJ P,CLKTIM ;COMPUTE NEW SLEEP TIME
POPJ P, ;RETURN
; Kill a clock request
; Call: MOVE T1,clock queue entry ID
; PUSHJ P,B$CLKK
;
B$CLKK::HRRZS T1 ;MAKE SURE IT'S ONLY THE ENTRY ID
MOVE S1,CLKQUE ;GET THE CLOCK QUEUE ID
$CALL L%FIRST ;GET THE FIRST ENTRY
JRST CLKK.2 ;JUMP THE FIRST TIME THROUGH
CLKK.1: MOVE S1,CLKQUE ;GET THE CLOCK QUEUE ID
$CALL L%NEXT ;GET THE NEXT ENTRY
CLKK.2: JUMPF .POPJ ;RETURN OF END OF LINKED LIST
CAME T1,.CQEID(S2) ;FOUND THE ENTRY?
JRST CLKK.1 ;NO - TRY ANOTHER ONE
CLKDEL: SKIPGE S1,.CQCTX(S2) ;STREAM CONTEXT?
JRST CLKK.3 ;NO
SKIPGE S2,G$BASE(S1) ;GET STREAM RELOCATION
SETZM .JBCLK(S2) ;CLEAR CLOCK QUEUE DATA WORD
TXZ S2,RL.NSC ;CLEAR NO SCHEDULE FLAG
MOVEM S2,G$BASE(S1) ;UPDATE RELOCATION WORD
CLKK.3: MOVE S1,CLKQUE ;GET THE CLOCK QUEUE ID
$CALL L%DENT ;DELETE THE ENTRY
POPJ P, ;RETURN
CLKCHK: SETZM SLPTIM ;CLEAR SLEEP TIME
$CALL I%NOW ;GET CURRENT UDT
MOVEM S1,G$UDT ;SAVE IT
$TEXT (<-1,,G$TIME>,<^C/G$UDT/^0>) ;CREATE ASCIZ TIME STAMP
MOVE S1,CLKQUE ;GET THE CLOCK QUEUE ID
$CALL L%FIRST ;GET THE FIRST ENTRY
JRST CLKC.2 ;ONWARD
CLKC.1: MOVE S1,CLKQUE ;GET THE CLOCK QUEUE ID
$CALL L%NEXT ;GET THE NEXT ENTRY
CLKC.2: JUMPF .POPJ ;END OF LINKED LIST
MOVE S1,.CQTIM(S2) ;GET UDT FOR THIS ENTRY
CAMG S1,G$UDT ;TIME TO PROCESS THIS REQUEST?
HRRZS .CQEVN(S2) ;YES - CLEAR PENDING EVENT CODE
LOAD S1,.CQEVN(S2),CQ.EVN ;GET THE PENDING EVENT CODE
CAIL S1,.CQMIN ;RANGE CHECK
CAILE S1,.CQMAX ; THE EVENT TYPE
JRST CLKC.6 ;ILLEGAL - DON'T DO EVENT CHECKING
SKIPGE S,.CQCTX(S2) ;NEED TO SETUP STREAM STATUS?
JRST CLKC.3 ;NO
SKIPL R,G$BASE(S) ;SET UP STREAM RELOCATION
JRST CLKC.5 ;NOT ACTIVE
PUSHJ P,P$STAT## ;UPDATE JOB STATUS
MOVEM J,.JREGS+J(R) ;SAVE FOR LATER
CLKC.3: PUSHJ P,@CLKTAB(S1) ;CHECK IT OUT
JRST CLKC.6 ;EVENT NOT SATISFIED YET
JUMPL S,CLKC.4 ;CHECK FOR BATCON'S CONTEXT
MOVE S1,.JREGS+P(R) ;GET STREAM'S STACK
SKIPE .CQADR(S2) ;NEED TO PUSH A DISPATCH ADDRESS?
PUSH S1,.CQADR(S2) ;YES - DO IT
MOVEM S1,.JREGS+P(R) ;UPDATE STREAM'S STACK POINTER
JRST CLKC.5 ;ONWARD
CLKC.4: PUSH P,S2 ;SAVE FROM DESTRUCTION
PUSHJ P,@.CQADR(S2) ;DISPATCH IN BATCON'S CONTEXT
POP P,S2 ;RESTORE CLOCK QUEUE ENTRY ADDRESS
CLKC.5: PUSHJ P,CLKDEL ;DELETE THE ENTRY
JRST CLKC.1 ;TRY THE NEXT ONE
CLKC.6: SKIPN SLPTIM ;COMPUTED A SLEEP TIME YET?
PUSHJ P,CLKTIM ;NO - DO IT NOW
JRST CLKC.1 ;YES
; Clock queue event dispatch table
;
CLKTAB: EXP EVNHNG ;(00) HUNG TIMER
EXP EVNLGI ;(01) LOGIN
EXP EVNLGO ;(02) LOGOUT
EXP EVNHLT ;(03) HALT
EVNHNG: MOVE S1,.CQTIM(S2) ;GET UDT FOR THIS ENTRY
CAMG S1,G$UDT ;TIME TO PROCESS IT?
AOS (P) ;YES
POPJ P, ;RETURN
EVNLGI: TXNE J,JL.ULI ;IS A JOB LOGGED IN?
EVNHLT: TXNN J,JL.UML ;IN MONITOR MODE?
AOS (P) ;YES
POPJ P, ;RETURN
EVNLGO: TXNN R,RL.FKJ ;FAST KJOB?
TXNN J,JL.ULI ;LOGGED OUT?
AOS (P) ;YES
POPJ P, ;RETURN
; Compute the time to sleep
; Call: MOVE S2, clock queue entry address
; PUSHJ P,CLKTIM
;
; On return, SLPTIM:= updated sleep time
;
CLKTIM: PUSH P,S2 ;SAVE FROM DESTRUCTION
MOVE S1,.CQTIM(S2) ;GET WAKEUP UDT
SUB S1,G$UDT ;GET OFFSET FROM NOW
MULI S1,<^D24*^D60*^D60> ;MULTIPLY BY NUMBER OF SECS/DAY
ASHC S1,21 ;POSITION RESULT
SKIPE SLPTIM ;ZERO?
CAMG S1,SLPTIM ;GREATER THAN THE CURRENT ONE?
MOVEM S1,SLPTIM ;SAVE IT
POP P,S2 ;RESTORE S2
POPJ P, ;RETURN
SUBTTL Job scheduler -- Timed sleep
TSLEEP: SKIPLE S1,G$BUDT ;CARE ABOUT ACTVIITY?
SKIPE G$SACT ;ANY ACTIVE STREAMS?
JRST [SOJL S1,TSLP.2 ;JUMP IF DON'T CARE
MOVEI S1,1 ;WE CARE, BUT THERE'S ACTIVITIY
MOVEM S1,G$BUDT ;RESET G$BUDT
JRST TSLP.2]
SOJE S1,TSLP.1 ;JUMP IF TIME NEEDS TO BE SET
$CALL I%NOW ;GET CURRENT TIME
CAMGE S1,G$BUDT ;TIME TO SAY GOODBYE?
JRST TSLP.2 ;NOT YET
PJRST IDLBYE ;YES, GO SAY GOODBYE AND LOGOUT
TSLP.1: $CALL I%NOW ;GET CURRENT TIME
ADD S1,[EXP IDLMIN*^D60*^D3];COMPUTE TIME TO SAY GOODBYE
MOVEM S1,G$BUDT ;SAVE IT FOR CHECKING LATER
TSLP.2: MOVEI S1,IZTIME ;GET INACTIVE TIME MAXIMUM
SKIPE G$SACT ;STREAMS ACTIVE?
MOVEI S1,AZTIME ;NO, GET ACTIVE SLEEP TIME MAXIMUM
SKIPN S2,SLPTIM ;GET COMPUTED SLEEP TIME
MOVE S2,S1 ;NO CLOCK REQUESTS
CAMLE S1,S2 ;WHICH IS SMALLER?
MOVE S1,S2 ;USE THE COMPUTED VALUE
TOPS10 <TXO S1,HB.RPT> ;WAKE ON PTY ACTIVITY
$CALL I%SLP ;ZZZZZZ
POPJ P, ;RETURN
SUBTTL Job scheduler -- Job check
JOBCHK: TXNN R,RL.LGI!RL.KJB ;LOGGING IN OR OUT?
TXNE F,FL.UKJ ;USER REQUEST KJOB?
POPJ P, ;MAYBE THERE ISN'T A JOB (THATS OK)
PUSHJ P,P$STAT## ;GET JOB STATUS
TXNE J,JL.ULI!JL.UJA ;JOB STILL THERE?
POPJ P, ;ALL'S WELL
TXZ R,RL.STP!RL.OPR!RL.NSC!RL.ACK ;MAKE JOB RUNABLE
MOVE S1,.JREGS+P(R) ;GET STREAM'S STACK
PUSH S1,[B$GONE] ;START STREAM HERE
MOVEM S1,.JREGS+P(R) ;REPLACE STACK
POPJ P, ;RETURN
SUBTTL Job scheduler -- Checkpoint
CHKPNT: TXNE F,FL.KST ;KSYS STREAM?
POPJ P, ;YES--DON'T TALK TO QUASAR
SKIPN .JBSPS(R) ;IGNORE IF STEP HEADER SCAN
TXNE R,RL.KJB!RL.ACK!RL.OPR ;LOGGING OUT OR ACKS PENDING?
POPJ P, ;THEN DO NOTHING
SKIPL S1,.JBCHK(R) ;STREAM REQUEST CHECKPOINTING?
CAML S1,G$UDT ;BATCON REQUEST CHECKPOINTING?
POPJ P, ;NO TO EITHER - RETURN
PUSHJ P,L$CHKP## ;CHECKPOINT THE LOG
PUSHJ P,CHKINI ;INITIALIZE CHECKPOINT MESSAGE
PUSHJ P,CHKJOB ;CHECK JOB STATUS
JRST CHKP.S ;NO NEED TO GO ON
MOVE S1,.JBJNO(R) ;GET THE JOB NUMBER
MOVX S2,JI.PRG ;GET PROGRAM NAME
PUSHJ P,I%JINF ;GET JOB INFO
SKIPE S2 ;NO NAME..IGNORE THIS STATUS
$TEXT (CHKTYO,< Running ^W/S2/^A>)
SKIPE S1,.JLLBL(R) ;CHECK IF HAD LABEL
TLNN S1,770000 ;WAS IT A LABEL
SKIPA ;NO..IGNORE LABEL
$TEXT (CHKTYO,< Last label: ^W/S1/^A>)
MOVE S1,.JBJNO(R) ;GET JOB NUMBER
MOVX S2,JI.RTM ;GET THE RUNTIME
PUSHJ P,I%JINF ;GET THE JOB INFO
MOVE S1,S2 ;PLACE VALUE IN S1
PUSHJ P,B$MTIM ;CONVERT TO READABLE TEXT
$TEXT (CHKTYO,< Runtime ^T/G$TMTX/^A>)
CHKP.S: MOVX S1,.CHNUL ;GET A <NUL>
PUSHJ P,CHKTYO ;STORE IT
HRRZ S1,.JBSPW(R) ;GET LAST ADDRESS
SUBI S1,-1(P1) ;COMPUTE THE LENGTH
STORE S1,.MSTYP(P1),MS.CNT ;SAVE THE MESSAGE COUNT
PJRST B$SEND ;SEND MESSAGE TO QUASAR AND RETURN
; INITIALIZE CHECKPOINT MESSAGE AND TEXT POINTERS
;
CHKINI: MOVEI S1,CHE.SZ ;GET MESSAGE SIZE
PUSHJ P,B$SQSR ;SET UP MESSAGE
MOVE P1,S2 ;PLACE MESSAGE ADDRESS IN P1
MOVX S1,.QOCHE ;MESSAGE TYPE
STORE S1,.MSTYP(P1),MS.TYP ;SAVE TYPE IN MESSAGE
TXNN F,FL.CHK ;STREAM REQUEST CHECKPOINTING?
JRST CHKI.1 ;NO
MOVE S1,.JQITN(R) ;GET STREAM'S ITN
MOVEM S1,.JOACK(R) ;USE IT AS THE ACK CODE
MOVEM S1,.MSCOD(P1) ;SAVE IN MESSAGE TO QUASAR TOO
MOVX S1,MF.ACK ;GET THE ACK BIT
MOVEM S1,.MSFLG(P1) ;STORE IN FLAG WORD
TXO R,RL.ACK ;REMEMBER TO WAIT FOR AN ACK
CHKI.1: XMOVEI S1,CHE.ST(P1) ;POINT TO STATUS AREA
TXO S1,<POINT 7,0> ;MAKE A BYTE POINTER
MOVEM S1,.JBSPW(R) ;STORE FOR LATER
MOVX S1,CH.FST ;SEND STATUS CODE
TXZE F,FL.CHK ;WANT CHECKPOINT UPDATED ON DISK?
TXO S1,CH.FCH ;YES - TELL QUASAR
MOVEM S1,CHE.FL(P1) ;UPDATE FLAG WORD
MOVE S1,.JQITN(R) ;THE TASK NAME
MOVEM S1,CHE.IT(P1) ;STORE
HRLI S1,.JBCRQ(R) ;CHECKPOINT/REQUEUE INFORMATION
HRRI S1,CHE.IN(P1) ;INTO THE MESSAGE
BLT S1,CHE.IN+<EQCKSZ-1>(P1) ;MOVE ALL THE WORDS
MOVE S1,G$UDT ;GET CURRENT TIME
ADDI S1,CKTIME*3 ;GET NEXT TIME TO CHECKPOINT
MOVEM S1,.JBCHK(R) ;REMEMBER IT
POPJ P, ;RETURN
; CHECK JOB STATUS
;
CHKJOB: MOVEI S1,[ITEXT (<Job ^D/.JBJNO(R)/>)] ;DEFAULT
SKIPG S2,.JBJNO(R) ;GET JOB NUMBER (IF ANY)
MOVEI S1,[ITEXT (<Job being set up by BATCON>)]
STORE S2,CHE.FL(P1),CH.JBN ;STORE IT
$TEXT (CHKTYO,< ^I/(S1)/^A>) ;DISPLAY SOMETHING
SKIPLE .JBJNO(R) ;HAVE A JOB?
AOS (P) ;YES
POPJ P, ;RETURN
; STORE AN ASCII CHARACTER IN THE CHECKPOINT MESSAGE
;
CHKTYO: IDPB S1,.JBSPW(R) ;STORE CHARACTER
$RETT ;RETURN
SUBTTL Job scheduler -- Message processing
; Process operator action messages
;
PROMES: SKIPE .JOVAL(R) ;HAVE AN OPERATOR/QUASAR MESSAGE?
TXNE R,RL.KJB!RL.MIP ;LOGGING OUT OR MESSAGE IN PROGRESS?
POPJ P, ;YES - THEN ALL DONE
TXO R,RL.MIP ;FLAG MESSAGE IN PROGRESS
PROM.1: MOVE S1,.JOFLG(R) ;GET FLAGS
TXNE S1,B.STCN ;STOP OR CONTINUE?
JRST PROM.4 ;YES - SPECIAL CASE OF DEFER REQUEST
TXNE S1,B.DEFR ;DEFER FOR STREAM CONTEXT?
JRST PROM.3 ;YES
PROM.2: PUSHJ P,@.JOPRC(R) ;PROCESS MESSAGE
TXZ R,RL.MIP ;CLEAR MESSAGE IN PROGRESS
SETZM .JOVAL(R) ;INDICATE MESSAGE PROCESSED
POPJ P, ;RETURN
PROM.3: TXZ R,RL.OPR!RL.STP!RL.JIE!RL.DIA ;CLEAR LOTS OF FLAGS
TXZ F,FL.NER!FL.SIL ;CLEAR MORE FLAGS
PROM.4: TXO R,RL.MIP!RL.MSP ;SET MESSAGE IN PROGRESS
MOVEM F,.JREGS+F(R) ;RESTORE FLAG AC
MOVEM R,G$BASE(S) ;RESTORE DATA BASE AC
MOVE S1,.JREGS+P(R) ;GET PROCESS STACK AC
PUSH S1,.JOPRC(R) ;PLACE ROUTINE ADDR ON STACK
MOVEM S1,.JREGS+P(R) ;SAVE STACK FOR PROCESS
POPJ P, ;RETURN
SUBTTL Job scheduler -- KSYS routines
TOPS10 <
; Schedule jobs for KSYS
; Call: PUSHJ P,KSYSCD
KSYSCD: SKIPG KSYCNT ;COUNT EXPIRED?
POPJ P, ;YES--NOTHING TO DO
$SAVE <P1,P2,P3,P4> ;SAVE SOME ACS
MOVSI P1,-KSYLEN ;START WITH FIRST WORD IN BIT MAP
KSYSC1: SKIPN P2,KSYMAP(P1) ;GET A MAP ENTRY
JRST KSYSC4 ;EMPTY
JFFO P2,.+1 ;FIND FIRST
MOVN P4,P3 ;NEGATE
MOVSI P2,400000 ;GET A BIT
LSH P2,(P4) ;POSITION
HRRZ S1,P1 ;GET MAP INDEX
IMULI S1,^D36 ;COMPUTE STARTING JOB NUMBER IN WORD
ADDI S1,(P3) ;PLUS REMAINDER GETS JOB NUMBER
MOVE S,[-JOBMAX+KSYSTR,,KSYSTR] ;POINTER TO START OF KSYS STREAMS
KSYSC2: SKIPLE R,G$BASE(S) ;ACTIVE?
JRST KSYSC3 ;NO--USE THIS ONE
AOBJN S,KSYSC2 ;KEEP SEARCHING
POPJ P, ;NONE AVAILABLE RIGHT NOW
KSYSC3: HRRZS S ;KEEP ONLY STREAM NUMBER
MOVEM S1,.JBJNO(R) ;SAVE
ANDCAM P2,KSYMAP(P1) ;CLEAR BIT IN MAP FOR THIS JOB
SOS KSYCNT ;COUNT DOWN NUMBER OF JOBS TO KILL
AOS KSYUSE ;COUNT THE KSYS STREAM IN USE
PUSHJ P,KSYFIR ;FIREUP THE STREAM
POPJ P, ;RETURN
KSYSC4: AOBJN P1,KSYSC1 ;LOOP
POPJ P, ;RETURN
; Fireup a KSYS stream
KSYFIR: $SAVE <P1> ;SAVE P1
MOVE T1,.JQOBJ+OBJ.TY(R) ;SAVE OBJECT TYPE
MOVE T2,.JQOBJ+OBJ.UN(R) ;SAVE UNIT/STREAM NUMBER
MOVE T3,.JQOBJ+OBJ.ND(R) ;SAVE NODE NUMBER OR NAME
MOVE T4,.JBJNO(R) ;SAVE JOB NUMBER
HRLZ S1,R ;GET START ADDRESS OF DATA BASE
HRRI S1,1(R) ;MAKE A BLT POINTER
SETZM (R) ;CLEAR THE FIRST WORD
BLT S1,.JSIZE-1(R) ;CLEAR THE DATA BASE
MOVEM T1,.JQOBJ+OBJ.TY(R) ;RESTORE OBJECT TYPE
MOVEM T2,.JQOBJ+OBJ.UN(R) ;RESTORE UNIT/STREAM NUMBER
MOVEM T3,.JQOBJ+OBJ.ND(R) ;RESTORE NODE NUMBER OR NAME
MOVEM T4,.JBJNO(R) ;RESTORE JOB NUMBER
$CALL M%GPAG ;GET A PAGE
MOVEM S1,.JSCMD(R) ;STORE FOR COMMAND PARSING
; Internal job name
MOVE S1,G$UDT ;A GOOR RANDOM NUMBER
MOVEM S1,.JQITN(R) ;SAVE
; Job information block
MOVE S1,['KSYS '] ;JOB NAME
MOVEM S1,.JQJBB+JIB.JN(R) ;SAVE
MOVE S1,.JQITN(R) ;GET ITN
ADDI S1,1 ;DON'T ALLOW ZERO
ANDI S1,7777 ;MASK DOWN INTO LEGAL RANGE
STORE S1,.JQJBB+JIB.SQ(R),EQ.SEQ ;SET SEQUENCE NUMBER
MOVE S1,.JBJNO(R) ;GET JOB NUMBER
MOVEI S2,JI.USR ;WANT THE PPN
$CALL I%JINF ;ASK THE GLXLIB
JUMPF KSYJ.X ;JOB GONE AWAY
MOVEM S2,.JQJBB+JIB.US(R) ;SAVE PPN
AOS S1,KSYREQ ;GET FAKE REQUEST-ID
MOVEM S1,.JQJBB+JIB.ID(R) ;SAVE
HRLZ S1,.JBJNO(R) ;GET JOB NUMBER
HRRI S1,.GTNM1 ;WANT FIRST HALF OF NAME
GETTAB S1, ;ASK MONITOR
SETZ S1, ;???
MOVEM S1,.JQJBB+JIB.NM+0(R) ;SAVE WORD 1
HRLZ S1,.JBJNO(R) ;GET JOB NUMBER
HRRI S1,.GTNM2 ;WANT SECOND HALF OF NAME
GETTAB S1, ;ASK MONITOR
SETZ S1, ;???
MOVEM S1,.JQJBB+JIB.NM+1(R) ;SAVE WORD 2
; Limit words
MOVEI S1,%EQUNO ;/UNIQUE:NO
STOLIM S1,.JQLIM(R),UNIQ
MOVEI S1,%EQRNO ;/RESTART:NO
STOLIM S1,.JQLIM(R),REST
MOVEI S1,1 ;/OPRINT:YES
STOLIM S1,.JQLIM(R),OINT
MOVEI S1,%EQOLE ;/OUTPUT:ERROR
STOLIM S1,.JQLIM(R),OUTP
MOVEI S1,0 ;/DEPEND:0
STOLIM S1,.JQLIM(R),DEPN
MOVX S1,INPCOR ;/CORE
STOLIM S1,.JQLIM(R),CORE
MOVEI S1,<^D5*^D60> ;/TIME
STOLIM S1,.JQLIM(R),TIME
MOVE S1,G$NODE ;/DESTINATION
STOLIM S1,.JQLIM(R),ONOD
MOVEI S1,%BSPOL ;/BATLOG:SPOOL
STOLIM S1,.JQLIM(R),BLOG
; Output location
MOVE S1,G$NODE ;USE BATCON'S NODE
MOVEM S1,.JQLOC(R) ;SAVE IT
; Checkpoint information
MOVSI S1,.JBCRQ(R) ;START ADDRESS
HRRI S1,.JBCRQ+1(R) ;BUILD BLT AC
SETZM .JBCRQ(R) ;CLEAR FIRST WORD
BLT S1,.JBCRQ+EQCKSZ-1(R) ;CLEAR ENTIRE BLOCK
; Account string
MOVE S1,[.ACTRD,,T1] ;SET UP UUO AC
MOVEI T1,2 ;TWO WORDS FOLLOWING
MOVE T2,.JBJNO(R) ;COPY JOB NUMBER
MOVEI T3,.JQACT(R) ;WHERE TO PUT IT
ACCT. S1, ;READ ACCOUNT STRING
SETZM .JQACT(R) ;IGNORE ERRORS
; PPN
MOVE S1,.JQJBB+JIB.US(R) ;GET FROM JIB BLOCK
MOVEM S1,.JQPPN(R) ;COPY IT
; Path
MOVEM S1,.JQPAT+0(R) ;SAVE PPN AS PATH
; Control file
; Log file
MOVSI S1,KSYLFP ;POINT TO PROTOTYPE FP
HRRI S1,.JQLFP(R) ;WHERE TO PUT IT
BLT S1,.JQLFP+FPXSIZ-1(R) ;COPY
KSYF.1: PUSHJ P,L$GENL## ;GENERATE A LOG FILE NAME
MOVE S1,.JQLFD+.FDNAM(R) ;GET LOG FILE NAME
CAMN S1,KSYNAM ;SAME AS LAST (NOT UNIQUE)?
JRST KSYF.1 ;TRY AGAIN
MOVEM S1,KSYNAM ;SAVE FOR NEXT TIME
; Miscellaneous
MOVX F,FL.INI+FL.KST ;SET INITIAL F FLAGS
PUSHJ P,U$FIRE## ;DO CUSTOMER STUFF
HRRZS R ;MAKE SURE NO JUNK IN LH
IORX R,RL.INI ;SET INITIAL BATCH STREAM FLAGS
MOVEM R,G$BASE(S) ;STORE JOB RELOCATION AC
MOVEM F,.JREGS+F(R) ;STORE IT
PUSHJ P,P$OPEN## ;OPEN A PTY
JUMPF KSYF.2 ;DID WE DO IT?
CAMLE S,G$HACT ;IS THIS NOW THE HIGHEST ACTIVE STREAM
MOVEM S,G$HACT ;YES, SET NEW VALUE
HRLI T1,-.JPSIZ ;BUILD PDL FOR THE STREAM
HRRI T1,.JPLST-1(R)
PUSH T1,[JOBPRC] ;START STREAM AT THE JOB PROCESSOR
MOVEM T1,.JREGS+P(R) ;SAVE AS PROCESSOR REGISTER P
AOS G$SACT ;ADD ANOTHER JOB
POPJ P, ;RETURN TO DISPATCHER
KSYF.2: $WTO (<Batch error>,<No PTYs available>,.JQOBJ(R),<$WTNOD(.JQLOC(R))>)
MOVX T1,%RSUNA ;SET UP 'STREAM UNAVAILABLE'
MOVEI T2,E.NJOB ;NO JOBS AVAILABLE CODE
MOVX T3,%SFULL ;SYSTEM FULL
TXO R,RL.SHT ;LITE THE SHUTDOWN AT EOJ BIT
PUSHJ P,SETUPR ;SEND RESPONSE TO QUASAR
JRST B$CLOS ;DISMISS JOB
; Prototype KSYS log file FP
KSYLFP: $BUILD (FPXSIZ) ;SIZE OF BLOCK
$SET (.FPLEN,FPMSIZ) ;LENGTH
$SET (.FPINF,FP.FFF,.FPFAS) ;/FILE:ASCII
$SET (.FPINF,FP.FPF,%FPLAS) ;/PRINT:ASCII
$SET (.FPINF,FP.FSP,1) ;/SPACING:1
$SET (.FPINF,FP.DEL,1) ;/DISPOSE:DELETE
$SET (.FPINF,FP.SPL,1) ;SPOOLED FILE
$SET (.FPONM,,0) ;ORIGINAL FILE NAME
$SET (.FPOXT,,0) ;ORIGINAL EXTENSION
$EOB ;END OF BLOCK
KSYFIN: MOVEI T1,KSYFT1 ;POINT TO NORMAL COMPLETION TEXT
MOVEI T2,[ASCIZ |jobs|] ;ASSUME MORE THAN ONE
MOVE S1,KSYJLO ;GET COUNT
CAIN S1,1 ;JUST ONE?
MOVEI T2,[ASCIZ |job|] ;YES
MOVEI T3,[ASCIZ |errors|] ;ASSUME MORE THAN ONE
MOVE S2,KSYJLE ;GET COUNT
CAIN T3,1 ;JUST ONE?
MOVEI T2,[ASCIZ |error|] ;YES
SKIPE T3 ;ANY ERRORS?
MOVEI T1,KSYFT2 ;YES--USE DIFFERENT TEXT
$WTO (<KSYS processing completed>,,,<$WTFLG(WT.SJI)>)
SETZM G$KSYS ;CLEAR KSYS IN PROGRESS
POPJ P, ;RETURN
KSYFT1: ITEXT (<^D/KSYJLO/ ^T/(T2)/ logged off>)
KSYFT2: ITEXT (<^D/KSYJLO/ ^T/(T2)/ logged off; ^D/KSYJLE/ ^T/(T3)/ had errors>)
> ;END TOPS-10 CONDITIONAL
SUBTTL IPCF/Operator/QUASAR interface -- IPCF interrupts
; IPCF interrupt level handler
;
IPCINT: $BGINT IPCLVL ;SWITCH TO IPCF INTERRUPT LEVEL
$CALL C%INTR ;NOTIFY THE LIBRARY WE HAVE A MESSAGE
$DEBRK ;RETURN FROM INTERRUPT
SUBTTL IPCF/Operator/QUASAR interface -- Hello and goodbye
; Send GOODBYE message and LOGOUT
;
IDLBYE: MOVX T3,IDLMIN ;GET MINUTES OF IDLENESS
SKIPA T2,[EXP IDLTXT] ;GET ADDRESS OF ITEXT FOR WTO
SHTBYE: MOVEI T2,SHTTXT
PUSHJ P,GOODBY ;SAY GOODBYE TO QUASAR
$WTO (<BATCON logging out>,<^I/(T2)/>,,$WTFLG(WT.SJI))
$CALL I%KJOB ;GO LOGOUT
STOPCD (CNL,HALT,,<Could not logout. Call to I%KJOB failed>)
IDLTXT: ITEXT (<All streams have been idle for ^D/T3/ minutes>)
SHTTXT: ITEXT (<All streams have been shut down>)
; Send GOODBYE message to QUASAR
;
GOODBY: TDZA T1,T1 ;INDICATE SIGNING OFF
; Send HELLO message to QUASAR
;
HELLO: SETO T1, ;INDICATE SIGNING ON
MOVEI S1,HEL.SZ ;GET MESSAGE SIZE
PUSHJ P,B$SQSR ;SETUP QUASAR MESSAGE
MOVX S1,<INSVL.(.QOHEL,MS.TYP)!INSVL.(HEL.SZ,MS.CNT)>
MOVEM S1,.MSTYP(S2) ;STORE MESSAGE TYPE AND SIZE
MOVE S1,['BATCON'] ;GET OUR NAME
MOVEM S1,HEL.NM(S2) ;STORE IT
MOVX S1,<INSVL.(%%.QSR,HEFVER)> ;GET QUASAR VERSION NUMBER
SKIPN T1 ;WHAT ARE WE DOING?
TXO S1,HEFBYE ;SIGNING OFF
MOVEM S1,HEL.FL(S2) ;STORE IT
MOVX S1,<INSVL.(1,HENNOT)!INSVL.(DEFMJB,HENMAX)>
MOVEM S1,HEL.NO(S2) ;STORE # OBJECT TYPES AND UNITS/STREAMS
MOVX S1,.OTBAT ;GET BATCH OBJECT TYPE
MOVEM S1,HEL.OB(S2) ;STORE IT
PUSHJ P,B$SEND ;GREET QUASAR
POPJ P, ;AND RETURN
SUBTTL IPCF/Operator/QUASAR interface -- IPCF message processing
IPCF: $CALL C%RECV ;TRY TO RECEIVE A MESSAGE
JUMPF .POPJ ;NONE THERE - RETURN
LOAD S2,MDB.SI(S1) ;GET SYSTEM PID INFO
TXZN S2,SI.FLG ;FROM SYSTEM PID
JRST IPCF.X ;NOT FROM SYSTEM PID - IGNORE IT
LOAD T1,S2,SI.IDX ;GET SYSTEM PID INDEX
CAIE T1,SP.QSR ;IS IT FROM QUASAR
CAIN T1,SP.OPR ;IS IT FROM ORION
SKIPA ;YES
JRST IPCF.X ;NOT FROM QUASAR OR ORION - IGNORE IT
LOAD S1,MDB.MS(S1),MD.ADR ;GET MESSAGE ADDRESS
PUSHJ P,B$SBLK ;SET UP FOR MESSAGE BLOCK PROCESSING
LOAD T1,.MSTYP(S1),MS.TYP ;GET MESSAGE TYPE
MOVSI S1,-NUMMSG ;NUMBER OF MESSAGES
IPCF.1: CAMN T1,MSGTAB(S1) ;A MATCH?
JRST IPCF.2 ;YES
AOBJN S1,IPCF.1 ;LOOP AND TRY ANOTHER
MOVEI S1,0 ;NO MATCH - MAYBE AN ACK
IPCF.2: HRRZM S1,G$MIDX ;SAVE INDEX FOR LATER
PUSHJ P,U$IPCF## ;CALL CUSTOMER USER EXIT ROUTINES
JRST IPCF.X ;FAILED - ABORT PROCESSING
PUSHJ P,VALMSG ;VALIDATE MESSAGE
JRST IPCF.X ;BAD MESSAGE
MOVE S1,G$MIDX ;GET INDEX INTO MESSAGE TABLES
PUSHJ P,@MSGPRC(S1) ;PROCESS THE MESSAGE
IPCF.X: $CALL C%REL ;RELEASE THE MESSAGE
SKIPN G$PSCN ;NEED TO PROCESS PRESCAN STREAM?
JRST IPCF ;NO - GET ANOTHER MESSAGE
POPJ P, ;RETURN
SUBTTL IPCF/Operator/QUASAR interface -- Message tables
; Macros to build the paralell message tables
; The arguments to the $ macro are used in the following ways:
; TYPE message type
; SUBR subroutine to process the message
; OBJ index into the message of the object block (-1 means no check)
;
DEFINE $MSG,<
$ ( 0, UNKMSG, -1) ;?????? UNKNOWN MESSAGES
$ (.QONEX, NEXTJB, .EQROB) ;QUASAR NEXTJOB
$ (.QOABO, ABORT , ABO.TY) ;QUASAR USER CANCEL
$ (.QOSUP, SETUP , -1) ;QUASAR SETUP JOB
$ (.QOALC, ALLOC , -1) ;QUASAR PRE-ALLOCATION
TOPS10 <
$ (.QOKSY, KSYS , -1) ;QUASAR KSYS
>
$ (.OMPAU, PAUSE , .OROBJ) ;ORION STOP
$ (.OMCON, CONTIN, .OROBJ) ;ORION CONTINUE
$ (.OMRSP, RESPON, -1) ;ORION RESPONSE TO WTOR
$ (.OMREQ, REQUE , .OROBJ) ;ORION REQUEUE
$ (.OMCAN, CANCEL, .OROBJ) ;ORION CANCEL
$ (.OMSND, SEND , .OROBJ) ;ORION SEND
$ (.OMSHC, EXAMIN, .OROBJ) ;ORION EXAMINE
$ (MT.TXT, ACK , -1) ;ACKS
>
DEFINE $ (TYPE,SUBR,OBJ),<EXP TYPE>
MSGTAB::$MSG
NUMMSG==.-MSGTAB
DEFINE $ (TYPE,SUBR,OBJ),<EXP SUBR>
MSGPRC::$MSG
DEFINE $ (TYPE,SUBR,OBJ),<EXP OBJ>
MSGOBJ::$MSG
SUBTTL IPCF/Operator/QUASAR interface -- Validate messages
; Validate IPCF messages
; Call: PUSHJ P,VALMSG
; <NON-SKIP> ;ILLEGAL MESSAGE
; <SKIP> ;MESSAGE OK
;
; On sucessful return, S:= stream index and R:= stream relocation
;
VALMSG: MOVE S1,G$MIDX ;GET MESSAGE INDEX
SKIPGE MSGOBJ(S1) ;NEED TO VALIDATE MESSAGE?
JRST .POPJ1 ;NO
MOVE S2,MSGTAB(S1) ;GET MESSAGE TYPE
CAIGE S2,.OMTXT ;RANGE CHECK
CAIGE S2,.OMOFF ;FOR ORION MESSAGE TYPE
JRST VALM.2 ;NO
VALM.1: PUSHJ P,B$GBLK ;GET A MESSAGE BLOCK
JRST VALM.E ;NO MORE - ERROR
CAIE T1,.OROBJ ;IS THIS THE OBJECT BLOCK???
JRST VALM.1 ;NO - GET THE NEXT MSG BLOCK
MOVE S2,T3 ;GET THE BLOCK DATA ADDRESS IN S1.
JRST VALM.3 ;GO FIND THE OBJECT BLOCK
VALM.2: MOVE S2,MSGOBJ(S1) ;GET OBJECT BLOCK OFFSET
ADD S2,G$MADR ;ADD MESSAGE ADDRESS
VALM.3: MOVE T1,.ROBTY(S2) ;GET OBJECT TYPE
MOVE T2,.ROBAT(S2) ;GET UNIT NUMBER
MOVE T3,.ROBND(S2) ;AND NODE NUMBER
MOVEI S,0 ;CLEAR STREAM INDEX
VALM.4: SKIPN R,G$BASE(S) ;GET STREAM RELOCATION
JRST VALM.5 ;NOT SETUP
CAMN T1,.JQOBJ+.ROBTY(R) ;COMPARE OBJECT TYPE
CAME T2,.JQOBJ+.ROBAT(R) ;COMPARE UNIT NUMBER
JRST VALM.5 ;NO MATCH
CAMN T3,.JQOBJ+.ROBND(R) ;COMPARE NODE NUMBER
JRST .POPJ1 ;MESSAGE SEEMS OK - RETURN
VALM.5: CAIGE S,DEFMJB ;CHECKED ALL STREAMS YET?
AOJA S,VALM.4 ;NO - LOOP
VALM.E: $WTO (<BATCON Error>,<Invalid object block: type = ^O/T1/, unit/stream = ^O/T2/, node = ^N/T3/>)
POPJ P, ;TAKE ERROR RETURN
SUBTTL IPCF/Operator/QUASAR interface -- Initialize stream block
; Initialize operator/QUASAR message block in stream data base
; Call: MOVEI S1,[ASCIZ |message text|]
; MOVE S2,processor address
; PUSHJ P,B$IMSG
; <NON-SKIP> ;MESSAGE PENDING
; <SKIP> ;MESSAGE BLOCK SETUP
;
B$IMSG::SKIPN .JOVAL(R) ;HAVE A VALID MESSAGE?
JRST IMSG.1 ;NO
$WTO (<^T/@.JONAM(R)/ pending; ^T/(S1)/ ignored>,,.JQOBJ(R))
POPJ P, ;RETURN
IMSG.1: SETOM .JOVAL(R) ;INDICATE A VALID MESSAGE
SETZM .JOFLG(R) ;CLEAR FLAG WORD
MOVEM S1,.JONAM(R) ;STORE TEXT ADDRESS
MOVEM S2,.JOPRC(R) ;STORE PROCESSOR ADDRESS
MOVSI S1,.JOMSG(R) ;START OF MESSAGE BUFFER
HRRI S1,.JOMSG+1(R) ;MAKE A BLT POINTER
SETZM .JOMSG(R) ;CLEAR FIRST WORD
BLT S1,.JOMSG+IPCSIZ-1(R) ;CLEAR ENTIRE BUFFER
MOVE S1,G$MADR ;GET MESSAGE ADDRESS
LOAD S2,.MSTYP(S1),MS.CNT ;GET MESSAGE LENGTH
CAILE S2,IPCSIZ-1 ;OVERFLOW?
MOVEI S2,IPCSIZ-1 ;YES
STORE S2,.MSTYP(S1),MS.CNT ;UPDATE
HRLZ S1,G$MADR ;GET MESSAGE ADDRESS
HRRI S1,.JOMSG(R) ;PUT IT THERE
ADDI S2,.JOMSG(R) ;COMPUTE END ADDRESS
BLT S1,-1(S2) ;COPY MESSAGE
JRST .POPJ1 ;RETURN
SUBTTL IPCF/Operator/QUASAR interface -- Message block processing
; Set up message block processing
; Call: MOVE S1,message address
; PUSHJ P,B$SETM
;
; On return, G$MADR and G$MBLK will be set up and B$GBLK may be called.
;
; All ACs preserved
;
B$SBLK::$SAVE <P1> ;SAVE P1
MOVEM S1,G$MADR ;REMEMBER MESSAGE ADDRESS FOR LATER
MOVEI P1,.OHDRS+ARG.HD(S1) ;POINT TO FIRST BLOCK ADDRESS
MOVEM P1,G$MBLK ;REMEMBER IT TOO
MOVE P1,.OARGC(S1) ;GET ARGUMENT COUNT
MOVEM P1,G$MARG ;STORE IT
POPJ P, ;RETURN
; Get the next block of a message
; Call: PUSHJ P,B$GBLK
; <NON-SKIP> ;END OF MESSAGE
; <SKIP> ;NEXT BLOCK FOUND
;
; On error return, T1, T2 and T3 left unchanged
; On sucessful return, T1:= type, T2:= length, T3:= data address
;
; AC usage: Destroys S1
;
B$GBLK::MOVE S1,G$MADR ;GET MESSAGE ADDRESS
SOSGE G$MARG ;SUBTRACT 1 FROM THE BLOCK COUNT
POPJ P, ;ERROR RETURN IF NO MORE
MOVE S1,G$MBLK ;GET THE PREVIOUS BLOCK ADDRESS
LOAD T1,ARG.HD(S1),AR.TYP ;GET THE BLOCK TYPE
LOAD T2,ARG.HD(S1),AR.LEN ;GET THE BLOCK LENGTH
MOVEI T3,ARG.DA(S1) ;GET THE BLOCK DATA ADDRESS
ADD S1,T2 ;POINT TO THE NEXT MESSAGE BLOCK
MOVEM S1,G$MBLK ;SAVE IT FOR THE NEXT CALL
JRST .POPJ1 ;RETURN SUCESSFUL
SUBTTL IPCF/Operator/QUASAR interface -- QUASAR communication
; Setup message to QUASAR
; Call: MOVE S1,# words
; PUSHJ P,B$SQSR
;
; On return, S2:= message address
;
B$SQSR::MOVE S2,[MSGADR,,MSGADR+1] ;SET UP BLT
SETZM MSGADR ;CLEAR THE FIRST WORD
BLT S2,MSGADR-1(S1) ;CLEAR THE ENTIRE BLOCK
MOVEI S2,MSGADR ;GET MESSAGE ADDRESS AGAIN
STORE S2,G$SAB+SAB.MS ;STORE THE MESSAGE ADDRESS IN SAB
POPJ P, ;RETURN
; Send an IPCF message to QUASAR
; Call: PUSHJ P,B$SEND
;
B$SEND::SETZM G$SAB+SAB.PD ;NO PID
LOAD S1,@G$SAB+SAB.MS,MS.CNT ;GET THE MESSAGE COUNT
STORE S1,G$SAB+SAB.LN ;STORE IT
MOVX S1,<SI.FLG+<INSVL.(SI.IDX,SP.QSR)>> ;USE SPECIAL PID INDEX
MOVEM S1,G$SAB+SAB.SI ;STORE IT
MOVEI S1,SAB.SZ ;SIZE OF BLOCK IN S1
MOVEI S2,G$SAB ;ADDRESS OF BLOCK
$CALL C%SEND ;SEND TO QUASAR
SKIPT ;CHECK FOR ERRORS
SKIPN G$KILL ;KILLING ALL JOBS?
POPJ P, ;RETURN
STOPCD (SQF,HALT,,<Send failure to QUASAR>)
; Update stream status in QUASAR
; Call: MOVE T1,status code
; PUSHJ P,B$UPDA
;
B$UPDA::MOVEI S1,STU.SZ ;GET STATUS SIZE
PUSHJ P,B$SQSR ;SETUP MESSAGE TO QUASAR
MOVEM T1,STU.CD(S2) ;SAVE THE CODE
MOVE S1,[STU.SZ,,.QOSTU] ;GET HEADER WORD
MOVEM S1,.MSTYP(S2) ;STORE IN MESSAGE
MOVSI S1,.JQOBJ(R) ;GET SOURCE TYPE FROM STREAM
HRRI S1,STU.RB(S2) ;DESTINATION,,RESPONSE TYPE
BLT S1,STU.RB+OBJ.SZ-1(S2) ;MOVE TYPE,UNIT,NUMBER
PJRST B$SEND ;SEND TO QUASAR AND RETURN
SUBTTL IPCF/Operator/QUASAR interface -- Ask for operator response
; Ask for operator response
; Call: MOVE S1,address of type ITEXT block
; MOVE S2,address of main ITEXT block
; MOVE T1,address of table of responses
; PUSHJ P,B$OPER
;
; On return, S1:= index into response table
;
B$OPER::MOVEM S1,.JOTYP(R) ;STORE TYPE ITEXT BLOCK ADDRESS
MOVEM S2,.JOTXT(R) ;STORE MAIN ITEXT BLOCK ADDRESS
MOVEM T1,.JOTBL(R) ;STORE RESPONSE TABLE POINTER
MOVEI T1,%OREWT ;GET OPERATOR RESPONSE WAIT CODE
PUSHJ P,B$UPDA ;UPDATE QUASAR
OPER.1: MOVE S1,.JQITN(R) ;GET THE REQUEST ITN
MOVEM S1,.JOACK(R) ;SAVE AS THE ACK CODE
$WTOR (<^I/@.JOTYP(R)/>,<^I/JIBTXT/^I/@.JOTXT(R)/>,.JQOBJ(R),.JOACK(R),<$WTNOD(.JQLOC(R))>)
TXO R,RL.OPR ;MARK AS WAITING FOR OPERATOR RESPONSE
PUSHJ P,QTS ;WAIT FOR OEPRATOR TO ANSWER
SKIPN S1,.JOTBL(R) ;POINT TO RESPONSE TABLE (IF ONE GIVEN)
POPJ P, ;WILL ACCEPT ANY TEXT - RETURN
HRROI S2,.JORSP(R) ;POINT TO RESPONSE FROM OPERATOR
$CALL S%TBLK ;SCAN THE TABLE FOR A MATCH
TXNE S2,TL%NOM ;GOT ONE?
JRST OPER.1 ;NO - TRY AGAIN
PUSH P,S1 ;SAVE INDEX
MOVX T1,%RESET ;GET NORMAL OPERATION CODE
PUSHJ P,B$UPDA ;UPDATE QUASAR
POP P,S1 ;RESTORE S1
POPJ P, ;RETURN WITH TABLE INDEX IN S1
SUBTTL IPCF/Operator/QUASAR interface -- Unknown message
UNKMSG: MOVE S1,G$MADR ;GET MESSAGE ADDRESS
$WTO (<BATCON Error>,<^I/UNKTXT/>)
POPJ P, ;RETURN
UNKTXT: ITEXT (< Unknown IPCF message
Message header: ^O12R0/.MSTYP(S1)/, ^O12R0/.MSFLG(S1)/, ^O12R0/.MSCOD(S1)/>)
SUBTTL IPCF/Operator/QUASAR interface -- QUASAR message #5 (NEXTJOB)
NEXTJB: TXNN R,RL.ACT ;STREAM ALREADY ACTIVE?
JRST NEXT.1 ;GOT IT
MOVX T1,%RSUNA ;NOT SETUP..TRY AGAIN
MOVEI T2,E.STRA ;STREAM ALREADY ACTIVE
SETZM T3 ;CLEAR STATUS CODE AC
PJRST SETUPF ;NOTIFY QUASAR OF THE SETUP FAILURE
NEXT.1: MOVE P1,G$MADR ;GET MESSAGE ADDRESS
PUSHJ P,FIREUP ;FIREUP STREAM
POPJ P, ;RETURN
; Fireup a job for processing
;
FIREUP: MOVE T1,.JQOBJ+OBJ.TY(R) ;SAVE OBJECT TYPE
MOVE T2,.JQOBJ+OBJ.UN(R) ;SAVE UNIT/STREAM NUMBER
MOVE T3,.JQOBJ+OBJ.ND(R) ;SAVE NODE NUMBER OR NAME
HRLZ S1,R ;GET START ADDRESS OF DATA BASE
HRRI S1,1(R) ;MAKE A BLT POINTER
SETZM (R) ;CLEAR THE FIRST WORD
BLT S1,.JSIZE-1(R) ;CLEAR THE DATA BASE
MOVEM T1,.JQOBJ+OBJ.TY(R) ;RESTORE OBJECT TYPE
MOVEM T2,.JQOBJ+OBJ.UN(R) ;RESTORE UNIT/STREAM NUMBER
MOVEM T3,.JQOBJ+OBJ.ND(R) ;RESTORE NODE NUMBER OR NAME
$CALL M%GPAG ;GET A PAGE
MOVEM S1,.JSCMD(R) ;STORE FOR COMMAND PARSING
; Internal job name
MOVE S1,.EQITN(P1) ;GET THE ITN FOR THE JOB
MOVEM S1,.JQITN(R) ;PLACE IN DATA BASE
; Job information block
HRLI S1,.EQJBB(P1) ;START OF JOB INFO BLOCK
HRRI S1,.JQJBB(R) ;END OF JOB INFO BLOCK
BLT S1,.JQJBB+JIBSIZ-1(R) ;MOVE THE BLOCK
; Limit words
HRLI S1,.EQLIM(P1) ;GET START OF LIMIT WORDS
HRRI S1,.JQLIM(R) ;GET DESTINATION OF LIMIT WORDS
BLT S1,.JQLIM+EQLMSZ-1(R) ;MOVE THE LIMIT WORDS
; Output location
GETLIM S1,.JQLIM(R),ONOD ;GET THE OUTPUT/LOCATION NODE
MOVEM S1,.JQLOC(R) ;SAVE AS THE LOCATION
; Checkpoint information
HRLI S1,.EQCHK(P1) ;GET ADDRESS OF CHECKPOINT WORDS
HRRI S1,.JBCRQ(R) ;GET DESTINATION FOR WORDS
BLT S1,.JBCRQ+EQCKSZ-1(R) ;SAVE THEM IN DATA BASE
; Account string
HRLI S1,.EQACT(P1) ;GET ADDRESS OF ACCOUNT STRING
HRRI S1,.JQACT(R) ;GET DESTINATION FOR STRING
BLT S1,.JQACT+10-1(R) ;SAVE ACCOUNT STRING
LOAD T2,.EQLEN(P1),EQ.LOH ;GET LENGTH OF THE REQUEST HEADER
TOPS20 < ;TOPS-20 ONLY
; SPRINT input set handle
MOVE S1,.EQSIS(P1) ;GET SPRINT SPOOL WORD
MOVEM S1,.JQSIS(R) ;SAVE WORD
; User name
HRLI S1,.EQOWN(P1) ;GET USER NAME
HRRI S1,.JQNAM(R) ;DESTINATION FOR USER NAME
BLT S1,.JQNAM+10-1(R) ;MOVE THE NAME
; Connected directory
HRLI S1,.EQCON(P1) ;GET CONNECTED DIRECTORY
HRRI S1,.JQCON(R) ;DESTINATION FOR CONN. DIR
BLT S1,.JQCON+12-1(R) ;SAVE CONNECTED DIRECTORY
> ;END OF TOPS-20 CONDITIONAL
TOPS10 < ;TOPS-10 ONLY
; User PPN
MOVE S1,.EQOID(P1) ;GET PPN INFO
MOVEM S1,.JQPPN(R) ;SAVE PPN
; Path
CAIGE T2,.EQPSZ ;ENOUGH ROOM FOR THE PATH SPEC
JRST FIRE.0 ;NO, DON'T BOTHER COPYING IT
HRLI S1,.EQPAT(P1) ;WHERE IT IS IF PRESENT
HRRI S1,.JQPAT(R) ;INTO INTERNAL BLOCK
BLT S1,.JQPAT+5(R) ;MOVE IT ALL
> ;END OF TOPS-10 CONDITIONAL
; Control file
FIRE.0: ADDI T2,(P1) ;FIND FILE PARAMETERS FOR THE CTL FILE
HRLZ S1,T2 ;GET FP ADDRESS IN THE EQ
HRRI S1,.JQCFP(R) ;GET FP ADDRESS IN THE JOB DATA BASE
LOAD S2,.FPLEN(T2),FP.LEN ;GET LENGTH OF FP IN THE EQ
ADDI S2,.JQCFP(R) ;COMPUTE END ADDRESS TO BLT
BLT S1,-1(S2) ;COPY THE CONTROL FILE FP
LOAD T3,.FPLEN(T2),FP.LEN ;FIND THE FILE DESCRIPTOR
ADDI T3,(T2) ;AS MESSAGE+LENGTH OF HEADER+LENGTH OF PARMS
LOAD T4,.FDLEN(T3),FD.LEN ;SIZE OF THE DESCRIPTOR
ADDI T4,.JQCFD-1(R) ;END OF THE BLT
HRLI T1,0(T3) ;THE CTL FILE STRUCTURE
HRRI T1,.JQCFD(R) ;WHERE FNDCTL WANTS IT
BLT T1,0(T4) ;COPY ALL AND SFD'S IF THERE
LOAD T4,.FDLEN(T3),FD.LEN ;GET FD SIZE AGAIN
ADDI T3,(T4) ;C = LOG FILE PARAMETERS
; Log file
HRLZ S1,T3 ;GET FP ADDRESS IN THE EQ
HRRI S1,.JQLFP(R) ;GET FP ADDRESS IN THE JOB DATA BASE
LOAD S2,.FPLEN(T3),FP.LEN ;GET LENGTH OF FP IN THE EQ
ADDI S2,.JQLFP(R) ;COMPUTE END ADDRESS TO BLT
BLT S1,-1(S2) ;COPY THE CONTROL FILE FP
LOAD T4,.FPLEN(T3),FP.LEN ;SIZE OF LOG FILE PARM HEADER
ADDI T4,(T3) ;POINT TO LOG FILE DESCRIPTOR
LOAD T3,.FDLEN(T4),FD.LEN ;SIZE OF LOG FILE FD
ADDI T3,.JQLFD-1(R) ;LAST LOCATION TO MOVE TO
HRLI T1,0(T4) ;THE LOG FILE NOW
HRRI T1,.JQLFD(R) ;WHERE THE ROUTINES WANT IT
BLT T1,0(T3) ;MOVE THE FULL SPEC
; Miscellaneous
PUSHJ P,U$FIRE## ;DO CUSTOMER STUFF
HRRZS R ;MAKE SURE NO JUNK IN LH
IORX R,RL.INI ;SET INITIAL BATCH STREAM FLAGS
MOVEM R,G$BASE(S) ;STORE JOB RELOCATION AC
MOVX F,FL.INI ;SET INITIAL F FLAGS
MOVEM F,.JREGS+F(R) ;STORE IT
SETOM .JBJNO(R) ;MARK NO JOB YET
MOVE S1,G$STRM(S) ;GET THE STREAM NUMBER
CAIN S1,PSCSTR ;IS IT THE PRESCAN STREAM?
POPJ P, ;YES - JUST RETURN
FIRE.1: AOS G$SACT ;ANOTHER STREAM IN USE
PUSHJ P,P$OPEN## ;OPEN A PTY
JUMPF FIRE.2 ;DID WE DO IT?
CAMLE S,G$HACT ;IS THIS NOW THE HIGHEST ACTIVE STREAM
MOVEM S,G$HACT ;YES, SET NEW VALUE
HRLI T1,-.JPSIZ ;BUILD PDL FOR THE STREAM
HRRI T1,.JPLST-1(R)
PUSH T1,[JOBPRC] ;START STREAM AT THE JOB PROCESSOR
MOVEM T1,.JREGS+P(R) ;SAVE AS PROCESSOR REGISTER P
POPJ P, ;RETURN TO DISPATCHER
FIRE.2: $WTO (<Batch error>,<No PTYs available - job requeued>,.JQOBJ(R),<$WTNOD(.JQLOC(R))>)
MOVX T1,%RSUNA ;SET UP 'STREAM UNAVAILABLE'
MOVEI T2,E.NJOB ;NO JOBS AVAILABLE CODE
MOVX T3,%SFULL ;SYSTEM FULL
TXO R,RL.SHT ;LITE THE SHUTDOWN AT EOJ BIT
PUSHJ P,SETUPR ;SEND RESPONSE TO QUASAR
SETOM .JBCHK(R) ;NO CHECKPOINT NEEDED
JRST B$CLOS ;DISMISS JOB
SUBTTL IPCF/Operator/QUASAR interface -- QUASAR message #6 (ABORT)
ABORT: MOVE P1,G$MADR ;GET MESSAGE ADDRESS
MOVE S1,ABO.IT(P1) ;GET ITN FOR STREAM
CAME S1,.JQITN(R) ;IS IT SAME JOB
POPJ P, ;NO,,IGNORE IT
MOVEI S1,[ASCIZ |CANCEL|] ;MESSAGE NAME
MOVEI S2,ABOJOB ;PROCESSOR ADDRESS
PUSHJ P,B$IMSG ;SET UP OPERATOR/QUASAR MESSAGE
POPJ P, ;ONE ALREADY THERE - RETURN
MOVX S1,B.DEFR ;GET DEFERRED FLAG
IORM S1,.JOFLG(R) ;STORE IT
MOVX T1,%CNCLG ;GET CANCEL CODE
PUSHJ P,B$UPDA ;UPDATE QUASAR
$WTOJ (<Cancel request queued by user ^P/ABO.ID(P1)/>,<^R/.JQJBB(R)/>,.JQOBJ(R))
POPJ P, ;RETURN
; Routine executed in stream context to abort the job.
;
ABOJOB: PUSHJ P,P$STOP## ;STOP THE PTY
MOVEI S1,.JOMSG(R) ;GET MESSAGE ADDRESS
$IDENT (CANCEL,<? Job canceled by user ^P/ABO.ID(S1)/>)
PUSHJ P,B$RTYO ;ECHO THE RESPONSE BUFFER
TXZ R,RL.JIE ;AVOID THE CLOSE/DUMP
TXO F,FL.UHE!FL.TXT ;AN UNEXPECTED CONDITION, TEXT AVAIL
$TEXT (<-1,,.JWTOP(R)>,<Job canceled by user ^P/ABO.ID(S1)/^0>)
JRST CLOSJB ;DISMISS THE JOB
SUBTTL IPCF/Operator/QUASAR interface -- QUASAR message #22 (SETUP)
SETUP: MOVE P1,G$MADR ;GET MESSAGE ADDRESS
LOAD S1,SUP.FL(P1) ;GET FLAGS
TXNE S1,SUFSHT ;SHUTTING DOWN STREAM?
JRST SHUTDN ;YES
MOVX S1,-1 ;-1 MEANS WE WANT A FREE STREAM
PUSHJ P,FSTREA ;SEE IF CAN FIND ONE
JUMPF SETE.1 ;NONE AVAILABLE
MOVE S,S1 ;GET STREAM
LOAD S1,SUP.UN(P1),RO.UNI ;GET UNIT/STREAM NUMBER
MOVEM S1,G$STRM(S) ;SAVE STREAM NUMBER IN TABLE
MOVEI S1,.JPAGS ;# PAGES NEEDED FOR THE DATA BASE
$CALL M%AQNP ;GET A PAGE FOR THE DATA BASE
MOVEI R,(S1) ;PUT THE PAGE NUMBER IN R
PG2ADR R ;CONVERT PAGE TO ADDRESS
HRRZM R,G$BASE(S) ;SAVE FOR THE DISPATCHER
MOVSI S1,SUP.TY(P1) ;BATCH OBJECT TYPE
HRRI S1,.JQOBJ(R) ;PLACE IN DATA BASE
BLT S1,.JQOBJ+OBJ.SZ-1(R) ;MOVE THE BLOCK
MOVX T1,%RSUOK ;GOOD RETURN FOR SETUP
SETZB T2,T3 ;CLEAR MESSAGE AND STATUS CODE
PUSHJ P,SETUPS ;SEND SUCESSFUL SETUP MESSAGE TO QUASAR
AOS G$SSET ;BUMP SETUP COUNTER
POPJ P, ;RETURN
SETE.1: MOVX T1,%RSUDE ;CAN NOT SETUP,,DO NOT TRY AGAIN
MOVEI T2,E.NSTR ;NO FREE STREAMS
SETZM T3 ;CLEAR STATUS CODE AC
PJRST SETUPF ;NOTIFY QUASAR OF THE SETUP FAILURE
; Shutdown message
;
SHUTDN: LOAD S1,SUP.UN(P1),RO.UNI ;GET STREAM NUMBER
PUSHJ P,FSTREA ;FIND THE STREAM
JUMPF .POPJ ;EH?
MOVE S,S1 ;GET STREAM INDEX
SHUT.1: SETOM G$STRM(S) ;MARK STREAM AVAILABLE
HRRZ S2,G$BASE(S) ;GET STREAM RELOCATION ADDRESS
SETZM G$BASE(S) ;CLEAR STREAM ENTRY
ADR2PG S2 ;CONVERT TO PAGE NUMBER
MOVEI S1,.JPAGS ;NUMBER TO RELEASE
$CALL M%RLNP ;RELEASE IT
TXNE F,FL.KST ;KSYS STREAM?
SOS KSYSSC ;YES--COUNT DOWN # STREAMS SETUP
SOSG G$SSET ;DECREMENT SETUP STREAM COUNT
SKIPE G$BUDT ;NO MORE. ARE WE A %STCMD PROCESSOR?
POPJ P, ;NO, RETURN
PJRST SHTBYE ;YES, GO SAY GOODBYE AND LOGOUT
; Here on SETUP failure
;
SETUPF: $WTO (<BATCON error>,<^I/JIBTXT/^I/@ERRTAB(T2)/>,.JQOBJ(R))
TXO R,RL.SHT ;LITE THE SHUTDOWN AT EOJ BIT
JRST SETUPR ;SEND RESPONSE TO QUASAR
; Here on sucessful SETUP
;
SETUPS: $WTO (<Started>,,.JQOBJ(R))
SETUPR: TXNE F,FL.KST ;KSYS STREAM
POPJ P, ;YES--DON'T TALK TO QUASAR
MOVEI S1,RSU.SZ ;GET THE MESSAGE SIZE
PUSHJ P,B$SQSR ;SETUP MESSAGE TO QUASAR
MOVEM T3,RSU.CD(S2) ;SAVE THE CODE
MOVEM T1,RSU.CO(S2) ;STORE IN MESSAGE
MOVE S1,[RSU.SZ,,.QORSU] ;GET HEADER WORD
MOVEM S1,.MSTYP(S2) ;STORE IN MESSAGE
MOVSI S1,.JQOBJ(R) ;GET SOURCE TYPE FROM STREAM
HRRI S1,RSU.TY(S2) ;DESTINATION,,RESPONSE TYPE
BLT S1,RSU.NO(S2) ;MOVE TYPE,UNIT,NUMBER
PUSHJ P,B$SEND ;SEND TO QUASAR
POPJ P, ;RETURN
;FIND A STREAM ROUTINE
;CALLED WITH S1 STREAM TO LOCATE ....-1...FREE STREAM
FSTREA: MOVSI S2,-JOBMAX ;GET MAX NUMBER OF JOBS
FSTR.1: MOVE T1,G$STRM(S2) ;GET FIRST STREAM VALUE
CAMN T1,S1 ;CHECK IF MATCH
JRST FSTR.2 ;YES ,,,MATCH
AOBJN S2,FSTR.1 ;TRY NEXT ENTRY
$RETF ;CAN'T FIND ENTRY
FSTR.2: HRRZ S1,S2 ;RELATIVE STREAM INDEX
$RETT ;RETURN TRUE
POPJ P, ;RETURN
SUBTTL IPCF/Operator/QUASAR interface -- QUASAR message #60 (ALLOCATION)
ALLOC: MOVE P1,G$MADR ;GET MESSAGE ADDRESS
MOVEI S,PSCSTR ;GET PRESCAN STREAM NUMBER
SKIPL G$STRM(S) ;DATA BASE ALLOCATED YET?
JRST ALLO.1 ;YES
MOVX S1,.JPAGS ;NUMBER OF PAGES IN A JOB'S DATA BASE
$CALL M%AQNP ;GET SOME PAGES
MOVEI R,(S1) ;PUT THE PAGE NUMBER IN R
PG2ADR R ;CONVERT TO ADDRESS
HRRZM R,G$BASE(S) ;STORE PAGE POINTER
MOVE S1,.EQROB+.ROBTY(P1) ;GET OBJECT TYPE
MOVEM S1,.JQOBJ+OBJ.TY(R) ;STORE IT
MOVEI S1,PSCSTR ;PRESCAN STREAM NUMBER
MOVEM S1,G$STRM(S) ;STORE IT
MOVE S1,.EQROB+.ROBND(P1) ;GET NODE
MOVEM S1,.JQOBJ+OBJ.ND(R) ;STORE IT
JRST ALLO.2 ;ONWARD
ALLO.1: HRRZ R,G$BASE(S) ;GET RELOCATION
ALLO.2: MOVE P1,G$MADR ;GET MESSAGE ADDRESS
MOVE S1,.EQROB+.ROBTY(P1) ;GET OBJECT TYPE
MOVEI S,PSCSTR ;GET PRESCAN STREAM NUMBER
HRRZ R,G$BASE(S) ;GET RELOCATION FOR STREAM
PUSHJ P,FIREUP ;FIRE UP A BATCH STREAM
HRLI S1,-.JPSIZ ;BUILD THE PDL FOR THE STREAM
HRRI S1,.JPLST-1(R) ;STACK STARTS HERE
PUSH S1,[STPPRC] ;BEGIN AT THE STEP PROCESSOR
MOVEM S1,.JREGS+P(R) ;STORE STREAM'S AC 'P'
SETOM .JBSPS(R) ;INDICATE STEP HEADER SCAN ONLY
AOS G$SACT ;ADD ANOTHER JOB
CAMLE S,G$HACT ;COULD THIS STREAM BE THE NEW G$HACT?
MOVEM S,G$HACT ;YES - STORE STREAM INDEX
SETOM G$PSCN ;INDICATE PRESCAN SETUP
POPJ P, ;RETURN
SUBTTL IPCF/Operator/QUASAR interface -- QUASAR message #66 (KSYS)
TOPS10 <
KSYS: MOVE S1,[KSYZBG,,KSYZBG+1] ;SET UP BLT
SETZM KSYZBG ;CLEAR FIRST WORD
BLT S1,KSYZND ;CLEAR ALL KSYS DATA
MOVEI S1,777777-^D512 ;STARTING FAKE REQUEST-ID
MOVEM S1,KSYREQ ;SAVE
SETOM G$KSYS ;FLAG KSYS IN PROGRESS
PUSHJ P,KSYJOB ;FIND ALL THE JOBS TO KILL
SKIPN KSYCNT ;ANY JOBS?
PJRST KSYFIN ;NO--TYPE COMPLETION TEXT AND RETURN
PUSHJ P,KSYSET ;SETUP ALL KSYS STREAMS
POPJ P, ;LET THE SCHEDULER DO THE REST
; Here to find all the jobs to kill
; Call: PUSHJ P,KSYJOB
;
; On return all jobs to be killed will be marked in the bit map
; (KSYMAP) and the number of jobs marked will be set in KSYCNT.
KSYJOB: $SAVE <P1,P2> ;SAVE SOME ACS
MOVE T1,[KSYMAP,,KSYMAP+1] ;SET UP BLT
SETZM KSYMAP ;CLEAR FIRST WORD
BLT T1,KSYMAP+KSYLEN-1 ;CLEAR OUT BIT MAP
SETZM KSYCNT ;INIT COUNT OF JOBS TO KILL
SETZM KSYJLO ;CLEAR COUNT OF JOBS LOGGED OFF
MOVE P1,[%NSHJB] ;START WITH THE HIGHEST
GETTAB P1, ; LOGGED IN JOB
MOVEI P1,^D511 ;ASSUME THE MAX
KSYJ.1:
; CHECK THE PPN
MOVEI S1,(P1) ;GET JOB NUMBER
MOVEI S2,JI.USR ;WANT THE PPN
$CALL I%JINF ;ASK THE GLXLIB
JUMPF KSYJ.X ;JOB GONE AWAY
CAMN S2,OPRPPN ;OPERATOR?
JRST KSYJ.X ;YES--LEAVE HIM ALONE
; CHECK THE LINE
MOVEI S1,(P1) ;GET JOB NUMBER
MOVEI S2,JI.TNO ;WANT LINE NUMBER
$CALL I%JINF ;ASK THE GLXLIB
JUMPF KSYJ.X ;JOB GONE AWAY
JUMPL S2,KSYJ.3 ;ALREADY DETACHED
TRO S2,.UXTRM ;ADD UDX OFFSET
GETLCH S2 ;GET LINE CHARACTERISTICS
TXNN S2,GL.ITY ;PTY?
JRST KSYJ.2 ;NO
; CHECK FOR BATCON OR MIC CONTROLLED PTYS
MOVEI S1,.GTLIM ;BATCH LIMIT TABLE
HRL S1,P ;INCLUDE JOB NUMBER
GETTAB S1, ;GET BAT LIMIT WORD
MOVEI S1,0 ;SHOULDNT FAIL
TXNE S1,JB.LBT ;BATCH (BATCON OR MIC)?
JRST KSYJ.X ;YES--LEAVE THEM ALONE
KSYJ.2: TXNN S2,GL.DSL!GL.REM ;DATASET OR REMOTE?
JRST KSYJ.X ;NO--TRY SOMEONE ELSE
ANDI S2,UX.UNT ;KEEP ONLY THE LINE NUMBER
HRLZS S2 ;MAKE IT LINE#,,JOB 0
ATTACH S2, ;DETACH JOB
JRST KSYJ.X ;??
KSYJ.3: MOVSI T1,400000 ;GET A BIT
MOVEI T2,(P1) ;AND THE JOB IN QUESTION
IDIVI T2,^D36 ;COMPUTE BIT MAP WORD
MOVNS T3 ;NEGATE
LSH T1,(T3) ;POSITION BIT
IORM T1,KSYMAP(T2) ;SAVE IT AWAY
AOS KSYCNT ;COUNT THE JOB
KSYJ.X: SOJG P1,KSYJ.1 ;LOOP FOR ALL JOBS
POPJ P, ;AND RETURN
; Routine to do a special KSYS stream setup
; Call: PUSHJ P,KSYSET
; <NON-SKIP> ;NONE AVAILABLE RIGHT NOW
; <SKIP> ;STREAM SETUP
KSYSET: $SAVE <P1,P2> ;SAVE P1 AND P2
MOVE P1,[-JOBMAX+KSYSTR,,KSYSTR] ;POINTER TO START OF KSYS STREAMS
MOVE P2,KSYCNT ;GET NUMBER IF JOBS TO KILL
KSYSE1: SKIPL G$STRM(P1) ;STREAM IN USE?
JRST KSYSE2 ;YES--KEEP LOOKING
HRRZ S,P1 ;GET STREAM NUMBER IN S
MOVEM S,G$STRM(S) ;SAVE IN TABLE
MOVEI S1,.JPAGS ;# PAGES NEEDED FOR THE DATA BASE
$CALL M%AQNP ;GET A PAGE FOR THE DATA BASE
MOVEI R,(S1) ;PUT THE PAGE NUMBER IN R
PG2ADR R ;CONVERT PAGE TO ADDRESS
HRRZM R,G$BASE(S) ;SAVE FOR THE DISPATCHER
MOVEI S1,.OTBAT ;OBJECT TYPE = BATCH STREAM
MOVEM S1,.JQOBJ+OBJ.TY(R) ;SAVE
MOVE S1,G$STRM(S) ;GET STREAM NUMBER
MOVEM S1,.JQOBJ+OBJ.UN(R) ;SAVE
MOVE S1,G$NODE ;GET BATCON'S NODE
MOVEM S1,.JQOBJ+OBJ.ND(R) ;SAVE
AOS KSYSSC ;COUNT THE STREAM SETUP
$WTO (<KSYS stream started>,,.JQOBJ(R))
; MOVX T1,%RSUOK ;GOOD RETURN FOR SETUP
; SETZB T2,T3 ;CLEAR MESSAGE AND STATUS CODE
; PUSHJ P,SETUPR ;SEND SUCESSFUL SETUP MESSAGE TO QUASAR
SOSLE P2 ;COUNT DOWN
KSYSE2: AOBJN P1,KSYSE1 ;LOOP UNTIL ALL KSYS STREAMS SETUP
POPJ P, ;RETURN
; Routine to simply queue up the log file
KSYQUE: $SAVE <P1,P2> ;SAVE P1 AND P2
$CALL M%GPAG ;GET A PAGE FOR MESSAGE
MOVE P1,S1 ;COPY TO A SAFE PLACE
MOVEI S1,.QOCQE ;MESSAGE TYPE IS SHORT CREATE
STORE S1,.MSTYP(P1),MS.TYP ;STORE IT
MOVEI P2,.OHDRS(P1) ;POINT TO EMPTY SLOT
; Queue type
MOVE S1,[2,,.QCQUE] ;LENGTH,,BLOCK TYPE
MOVEM S1,ARG.HD(P2) ;SAVE
MOVEI S1,.OTLPT ;OBJECT TYPE LPT
MOVEM S1,ARG.DA(P2) ;SAVE
ADDI P2,2 ;ADVANCE
AOS .OARGC(P1) ;COUNT ARGUMENTS
; Filespec
MOVSI S1,.JQLFD+ARG.DA(R) ;ADDRESS OF FD
HRRI S1,ARG.DA(P2) ;WHERE TO PUT IT
BLT S1,FDXSIZ-ARG.DA-1(P2) ;COPY FD
MOVE S1,[FDXSIZ-ARG.DA,,.QCFIL] ;LENGTH,,BLOCK TYPE
MOVEM S1,ARG.HD(P2) ;SAVE
HLRZS S1 ;GET BLOCK LENGTH
ADDI P2,(S1) ;ADVANCE
AOS .OARGC(P1) ;COUNT ARGUMENTS
; File format
MOVE S1,[2,,.QCPTP] ;LENGTH,,BLOCK TYPE
MOVEM S1,ARG.HD(P2) ;SAVE
MOVEI S1,.FPFAS ;ASCII
MOVEM S1,ARG.DA(P2) ;SAVE
ADDI P2,2 ;ADVANCE
AOS .OARGC(P1) ;COUNT ARGUMENTS
; Output disposition
MOVE S1,[2,,.QCODP] ;LENGTH,,BLOCK TYPE
MOVEM S1,ARG.HD(P2) ;SAVE
MOVEI S1,%DELETE ;DELETE AFTER PRINTING
MOVEM S1,ARG.DA(P2) ;SAVE
ADDI P2,2 ;ADVANCE
AOS .OARGC(P1) ;COUNT ARGUMENTS
; Account string
MOVE S1,[10,,.QCACT] ;LENGTH,,BLOCK TYPE
MOVEM S1,ARG.HD(P2) ;SAVE
MOVSI S1,.JQACT(R) ;POINT TO ACCT STRING
HRRI S1,ARG.DA(P2) ;WHERE TO PUT IT
BLT S1,ARG.DA+10-1(P2) ;COPY
ADDI P2,10 ;ADVANCE
AOS .OARGC(P1) ;COUNT ARGUMENTS
; User name
MOVE S1,[3,,.QCNAM] ;LENGTH,,BLOCK TYPE
MOVEM S1,ARG.HD(P2) ;SAVE
DMOVE S1,.JQJBB+JIB.NM(R) ;GET TWO WORDS
DMOVEM S1,ARG.DA(P2) ;SAVE
ADDI P2,3 ;ADVANCE
AOS .OARGC(P1) ;COUNT ARGUMENTS
; PPN
MOVE S1,[2,,.QCOID] ;LENGTH,,BLOCK TYPE
MOVEM S1,ARG.HD(P2) ;SAVE
MOVE S1,.JQPPN(R) ;GET THE PPN
MOVEM S1,ARG.DA(P2) ;SAVE
ADDI P2,2 ;ADVANCE
AOS .OARGC(P1) ;COUNT ARGUMENTS
; Job name
MOVE S1,[2,,.QCJBN] ;LENGTH,,BLOCK TYPE
MOVEM S1,ARG.HD(P2) ;SAVE
MOVE S1,['KSYS '] ;GET OBVIOUS NAME
MOVEM S1,ARG.DA(P2) ;SAVE
ADDI P2,2 ;ADVANCE
AOS .OARGC(P1) ;COUNT ARGUMENTS
; Note
MOVE S1,[3,,.QCNTE] ;LENGTH,,BLOCK TYPE
MOVEM S1,ARG.HD(P2) ;SAVE
MOVE S1,['LOGOUT'] ;WORD 1
MOVE S2,[' ERROR'] ;WORD 2
DMOVEM S1,ARG.DA(P2) ;SAVE
ADDI P2,3 ;ADVANCE
AOS .OARGC(P1) ;COUNT ARGUMENTS
; Finish up
MOVEI S1,(P2) ;GET LAST FREE ADDR IN MESSAGE
SUBI S1,(P1) ;COMPUTE LENGTH
STORE S1,.MSTYP(P1),MS.CNT ;STORE IN MESSAGE
MOVEM P1,G$SAB+SAB.MS ;STORE PAGE ADDRESS
MOVEI S1,PAGSIZ ;GET THE MESSAGE SIZE
STORE S1,G$SAB+SAB.LN ;STORE IT
MOVEI S1,SAB.SZ ;GET SAB SIZE
MOVEI S2,G$SAB ;GET SAB ADDRESS
$CALL C%SEND ;SEND MESSAGE TO QUASAR
JUMPT .POPJ ;RETURN IF NO ERRORS
MOVE S1,G$SAB+SAB.MS ;ELSE GET BACK PAGE ADDRESS
$CALL M%RPAG ;DESTROY THE PAGE
$WTO (<BATCON error>,<^I/KSYQTX/>,.JQOBJ(R),<$WTNOD(.JQLOC(R))>)
POPJ P, ;AND RETURN
KSYQTX: ITEXT (<Can't spool KSYS log file: ^F/.JQLFD(R)/>)
> ;END TOPS-10 CONDITIONAL
SUBTTL IPCF/Operator/QUASAR interface -- ORION message #200004 (PAUSE)
PAUSE: MOVE P1,G$MADR ;GET MESSAGE ADDRESS
SETZ S1, ;CLEAR AC
TXNE R,RL.STP ;ALREADY STOPPED?
MOVEI S1,[ASCIZ |Already stopped|] ;YES
TXNE R,RL.LGI ;LOGGING IN
MOVEI S1,[ASCIZ |Logging in|] ;YES
TXNE R,RL.KJB ;LOGGING OUT?
MOVEI S1,[ASCIZ |Logging out|] ;YES
JUMPE S1,PAUS.1 ;CHECK FOR ERRORS
$ACK (<^T/(S1)/>,,<.JQOBJ(R)>,<.MSCOD(P1)>) ;COMPLAIN
POPJ P, ;RETURN
PAUS.1: MOVEI S1,[ASCIZ |STOP|] ;MESSAGE NAME
MOVEI S2,STOPJB ;PROCESSOR ADDRESS
PUSHJ P,B$IMSG ;SET UP OPERATOR/QUASAR MESSAGE
POPJ P, ;ONE ALREADY THERE - RETURN
MOVX S1,B.STCN!B.DEFR ;GET SOME FLAGS
IORM S1,.JOFLG(R) ;STORE IT
$ACK (<Stop request queued>,,<.JQOBJ(R)>,.MSCOD(P1))
POPJ P, ;RETURN
; Routine executed in stream context to stop the job.
;
STOPJB: TXO F,FL.SCC ;SEND ^C TO STOP THE JOB
PUSHJ P,P$STOP## ;PUT AT MONITOR LEVEL
$IDENT (OPERAT,<[Job stopped by the operator]>)
SETOM .JLTIM(R) ;MARK TIME STAMP NEEDED
MOVX T1,%STOPD ;GET STOPPED CODE
PUSHJ P,B$UPDA ;UPDATE QUASAR
$WTOJ (<Stopped>,<^R/.JQJBB(R)/>,.JQOBJ(R),<$WTNOD(.JQLOC(R))>)
TXO R,RL.STP ;STREAM STOPPED
TXZ R,RL.MIP ;CLEAR MESSAGE IN PROGRESS
SETZM .JOVAL(R) ;CLEAR VALID MESSAGE FLAG
JRST QTS ;WAIT FOR CONTINUE
SUBTTL IPCF/Operator/QUASAR interface -- ORION message #200005 (CONTINUE)
CONTIN: MOVE P1,G$MADR ;GET MESSAGE ADDRESS
TXNE R,RL.STP ;JOB STOPPED?
JRST CONT.1 ;YES
$ACK (<Not stopped>,,<.JQOBJ(R)>,<.MSCOD(P1)>) ;COMPLAIN
POPJ P, ;RETURN
CONT.1: MOVEI S1,[ASCIZ |CONTINUE|] ;MESSAGE NAME
MOVEI S2,CONTJB ;PROCESSOR ADDRESS
PUSHJ P,B$IMSG ;SET UP OPERATOR/QUASAR MESSAGE
POPJ P, ;ONE ALREADY THERE - RETURN
MOVX S1,B.STCN!B.DEFR ;GET SOME FLAGS
IORM S1,.JOFLG(R) ;STORE IT
POPJ P, ;RETURN
; Routine executed in stream context to continue the job.
;
CONTJB: TXZE R,RL.STP ;SHOULE WE CONTINUE JOB?
TXNN F,FL.SCC ;SENT ^C TO JOB?
JRST CONTJ1 ;NO TO EITHER
$IDENT (OPERAT,<[Job continued by the operator]>)
PUSHJ P,L$LSTP## ;PUT A TIME STAMP IN THE LOG FILE
MOVX S1,MONCHR ;GET THE MONITOR PROMPT CHARACTER
PUSHJ P,L$OUTC## ;LOG IT
PUSHJ P,B$CINI ;SET UP THE COMMAND BUFFER
$TEXT (B$CPUT,<CONTINUE^M>) ;CONTINUE THE JOB
PUSHJ P,B$SETB ;RESET THE BYTE POINTER
PUSHJ P,B$XFER ;TRANSFER THE LINE TO THE PTY
CONTJ1: MOVX T1,%RESET ;GET NORMAL OPERATION CODE
PUSHJ P,B$UPDA ;UPDATE QUASAR
$ACK (<Continued>,,<.JQOBJ(R)>,<.JOMSG+.MSCOD(R)>)
TXZ R,RL.MIP ;CLEAR MESSAGE IN PROGRESS
SETZM .JOVAL(R) ;CLEAR VALID MESSAGE FLAG
JRST QTS ;CONTEXT SWITCH INCASE IN OPERATOR WAIT
SUBTTL IPCF/Operator/QUASAR interface -- ORION message #200012 (RESPONSE)
RESPON: MOVE P1,G$MADR ;GET MESSAGE ADDRESS
MOVE S1,.MSCOD(P1) ;GET ACK CODE (STREAM ITN)
MOVEI S,0 ;CLEAR STREAM INDEX
RESP.1: SKIPL R,G$BASE(S) ;GET STREAM RELOCATION
JRST RESP.2 ;NOT SETUP
CAMN S1,.JOACK(R) ;CHECK THE ACK CODE
JRST RESP.3 ;FOUND IT
RESP.2: CAMGE S,G$HACT ;CHECKED ALL STREAMS YET?
AOJA S,RESP.1 ;NO - LOOP
POPJ P, ;RETURN
RESP.3: SETZM .JOACK(R) ;CLEAR ACK CODE
TXZN R,RL.OPR!RL.DIA ;CLEAR OPR RESPONSE WAIT, DIALOGUE MODE
POPJ P, ;NOT WAITING
MOVE S1,P1 ;POINT TO MESSAGE
PUSHJ P,B$SBLK ;SETUP FOR BLOCK PARSING
RESP.4: PUSHJ P,B$GBLK ;GET A BLOCK
POPJ P, ;CAN'T
CAIE T1,.CMTXT ;LOOKING FOR TEXT
JRST RESP.4 ;TRY ANOTHER
HRLZ S1,T3 ;GET ADDRESS OF TEXT
HRRI S1,.JORSP(R) ;WANT IT TO GO HERE
MOVE S2,T2 ;GET SIZE OF BLOCK
CAILE S2,<RSPSIZ/5>+1 ;WILL IT FIT IN THE BUFFER?
MOVEI S2,<RSPSIZ/5>+1 ;NO - TAKE ONLY WHAT WE CAN HANDLE
ADDI S2,.JORSP(R) ;COMPUTE END ADDRESS
BLT S1,-1(S2) ;COPY TEXT
MOVEM R,G$BASE(S) ;RESTORE R
POPJ P, ;RETURN
SUBTTL IPCF/Operator/QUASAR interface -- ORION message #200025 (REQUEUE)
REQUE: MOVE P1,G$MADR ;GET MESSAGE ADDRESS
MOVEI S1,[ASCIZ |REQUEUE|] ;MESSAGE NAME
MOVEI S2,REQJOB ;PROCESSOR ADDRESS
PUSHJ P,B$IMSG ;SET UP OPERATOR/QUASAR MESSAGE
POPJ P, ;ONE ALREADY THERE - RETURN
MOVX S1,B.DEFR ;GET DEFERRED FLAG
IORM S1,.JOFLG(R) ;STORE IT
MOVX T1,%REQUE ;GET REQUEUE CODE
PUSHJ P,B$UPDA ;UPDATE QUASAR
$ACK (<Requeue request queued>,,<.JQOBJ(R)>,.MSCOD(P1))
POPJ P, ;RETURN
; Routine executed in stream context to requeue the job.
;
REQJOB: TXO R,RL.REQ ;MARK JOB AS REQUEUED
MOVEI P1,[ASCIZ |No reason given|] ;DEFAULT REASON
MOVEI S1,.JOMSG(R) ;GET MESSAGE ADDRESS
PUSHJ P,B$SBLK ;SET UP BLOCK STUFF
REQJ.1: PUSHJ P,B$GBLK ;GET A BLOCK
JRST REQJ.2 ;NO MORE
CAIE T1,.ORREA ;REASON FIELD
JRST REQJ.1 ;NO - KEEP LOOKING
MOVE P1,T3 ;GET ADDRESS OF REASON
JRST REQJ.1 ;CHECK NEXT ARGUMENT
REQJ.2: $IDENT (OPERAT,<[Job requeued by the operator]>)
MOVE S1,[$IDENT (OPERAT,<; ^A>)] ;GET INSTRUCTION TO STAMP LINE
MOVE S2,P1 ;GET BYTE POINTER
PUSHJ P,L$COPY## ;COPY TEXT INTO THE LOG FILE
PUSHJ P,L$CRLF## ;ADD A CRLF
MOVX S1,RQ.HBO ;HELD BY OPERATOR FOR REQUEUE
MOVEM S1,.JBRQF(R) ;SAVE REQUEUE FLAG WORD
MOVX S1,<BA.ORQ!BA.JOB> ;OPERATOR REQUEUE
IORM S1,.JBCRQ(R) ;SAVE IN CHECKPOINT WORDS
PJRST B$CLOS ;DISMISS JOB
SUBTTL IPCF/Operator/QUASAR interface -- ORION message #200026 (CANCEL)
CANCEL: MOVE P1,G$MADR ;GET MESSAGE ADDRESS
MOVEI S1,[ASCIZ |ABORT|] ;MESSAGE NAME
MOVEI S2,CANJOB ;PROCESSOR ADDRESS
PUSHJ P,B$IMSG ;SET UP OPERATOR/QUASAR MESSAGE
POPJ P, ;ONE ALREADY THERE - RETURN
MOVX S1,B.DEFR ;GET DEFERRED FLAG
IORM S1,.JOFLG(R) ;STORE IT
MOVX T1,%CNCLG ;GET CANCEL CODE
PUSHJ P,B$UPDA ;UPDATE QUASAR
$ACK (<Abort request queued>,,<.JQOBJ(R)>,.MSCOD(P1))
POPJ P, ;RETURN
; Routine executed in stream context to cancel the job.
;
CANJOB: PUSHJ P,P$STOP## ;^C THE PTY
MOVX P1,.CNERR ;DEFAULT TO ERROR PROCESSING
MOVEI P2,[ASCIZ |No reason given|] ;DEFAULT REASON
MOVEI S1,.JOMSG(R) ;GET MESSAGE ADDRESS
PUSHJ P,B$SBLK ;SET UP BLOCK STUFF
CANJ.1: PUSHJ P,B$GBLK ;GET A BLOCK
JRST CANJ.2 ;NO MORE
CAIN T1,.CANTY ;TYPE FIELD
JRST CANJ.5 ;YES..PROCESS TYPE
CAIN T1,.ORREA ;REASON FIELD
JRST CANJ.6 ;YES..SETUP POINTER
JRST CANJ.1 ;KEEP LOOKING
CANJ.2: HRRZ S1,CANCTB-1(P1) ;GET THE TEXT FOR ERROR TYPE
$IDENT (OPERAT,<? Job aborted by the operator (^T/(S1)/)>)
MOVE S1,[$IDENT (OPERAT,<; ^A>)] ;GET INSTRUCTION TO STAMP LINE
MOVE S2,P2 ;GET BYTE POINTER
PUSHJ P,L$COPY## ;COPY TEXT INTO THE LOG FILE
PUSHJ P,L$CRLF## ;ADD A CRLF
TXO F,FL.TXT ;MESSAGE TEXT AVAILABLE
$TEXT (<-1,,.JWTOP(R)>,<Job aborted by the operator; ^T/(P2)/^0>)
TXZ R,RL.JIE!RL.FLS ;CLEAR JOB IN ERROR AND FLUSH JOB
CAIE P1,.CNERR ;/ERROR?
JRST CANJ.3 ;NO
TXZ R,RL.MSP!RL.MIP ;CLEAR MESSAGE FLAGS
SETZM .JOVAL(R) ;CLEAR VALID MESSAGE INDICATOR
TXO R,RL.JIE ;SET JOB IN ERROR
MOVX T1,%RESET ;GET NEW STATUS
PUSHJ P,B$UPDA ;TELL QUASAR
POPJ P, ;AND RETURN TO NORMAL JOB LOOP
CANJ.3: CAIE P1,.CNNER ;/NOERROR?
JRST CANJ.4 ;NO
TXO R,RL.FLS ;SET FLUSH JOB BIT
TXZA F,FL.UHE ;CLEAR UNHANDLED ERROR CONDITION
CANJ.4: TXO F,FL.UHE ;/PURGE - SET UNHANDLED ERROR CONDITION
JRST B$CLOS ;DISMISS THE JOB
; Process disposition type
;
CANJ.5: SKIPLE P1,(T3) ;GET DISPOSITION TYPE
CAILE P1,.CNPRG ;IS IT WITHIN RANGE?
MOVEI P1,.CNERR ;ASSUME ERROR PROCESSING
JRST CANJ.1 ;CHECK NEXT ARGUMENT
; Process /REASON
;
CANJ.6: MOVE P2,T3 ;GET ADDRESS OF REASON
JRST CANJ.1 ;CHECK NEXT ARGUMENT
; Table of cancel options and flags
;
CANCTB: EXP [ASCIZ/with error processing/]
EXP [ASCIZ/with no error processing/]
EXP [ASCIZ/purged/]
SUBTTL IPCF/Operator/QUASAR interface -- ORION message #200035 (SEND)
SEND: MOVE P1,G$MADR ;GET MESSAGE ADDRESS
PUSHJ P,B$GBLK ;FIND A BLOCK
JRST SEND.1 ;CAN'T
CAIE T1,.CMTXT ;IS IT TEXT?
JRST SEND.1 ;NO
MOVE P2,T3 ;COPY TO A SAFER PLACE
HRLI P2,(POINT 7,) ;MAKE A BYTE POINTER
SEND.1: ILDB S1,P2 ;GET A CHARACTER, < (MATCH BRACKETS)
JUMPE S1,SEND.E ;END OF TEXT - BAD MESSAGE
CAIE S1,">" ;END OF JUNK?
JRST SEND.1 ;NO - KEEP LOOKING
$IDENT (OPERAT,<[Message from operator]>) ;IDENTIFY LINE
MOVE S1,[$IDENT (OPERAT,<; ^A>)] ;GET INSTRUCTION TO STAMP LINE
MOVE S2,P2 ;GET BYTE POINTER
PUSHJ P,L$COPY## ;COPY TEXT INTO THE LOG FILE
MOVE S1,[$IDENT (OPERAT,<[End of operator message]>)]
MOVE S2,[POINT 7,[BYTE (7) .CHCRT,.CHLFD,0,0,0]]
PUSHJ P,L$COPY ;PUT IN LOG FILE
SETOM .JLTIM(R) ;SAY WE NEED TIME STAMP
$ACK (<Send completed>,,<.JQOBJ(R)>,.MSCOD(P1))
POPJ P, ;RETURN
SEND.E: $ACK (<BATCON error>,<Invalid SEND message from ORION>,<.JQOBJ(R)>,.MSCOD(P1))
POPJ P, ;RETURN
SUBTTL IPCF/Operator/QUASAR interface -- ORION message #200036 (EXAMINE)
EXAMIN: MOVE P1,G$MADR ;GET MESSAGE ADDRESS
$CALL M%GPAG ;GET A PAGE
MOVE P2,S1 ;SAVE THE PAGE ADDRESS
MOVEI S1,WTOSIZ ;GET MESSAGE SPACE LEAVING ROOM FOR ACK
MOVEM S1,WTOCNT ;SAVE THE COUNT
HRRI S1,(P2) ;POINT TO THE PAGE
HRLI S1,(POINT 7,) ;MAKE BYTE POINTER
MOVEM S1,WTOPTR ;SAVE THE POINTER
SKIPN .JCIFN(R) ;IS THE CONTROL FILE OPEN?
JRST EXAME1 ;NO,,EXIT WITH ERROR
PUSHJ P,B$GBLK ;FIND A BLOCK
JRST EXAME4 ;CAN'T
CAIE T1,.SHCLN ;IS IT /LINES?
JRST EXAME4 ;NO
MOVE P3,(T3) ;GET /LINES VALUE
SUBI P3,1 ;ACCOUNT FOR THE IN-CORE COMMAND LINE
PUSHJ P,C$SPOS## ;SAVE POSITION OF CTL FILE
$TEXT (WTODAT,<*** Input from ^F/.JQCFD(R)/ ***^M^J^T/.JSCTL(R)/^A>)
EXAM.1: MOVE S1,.JCIFN(R) ;GET IFN
$CALL F%IBYT ;GET A BYTE
JUMPF EXAME2 ;EXIT EXAMIN ERROR
JUMPE S2,EXAM.1 ;SKIP NULLS
MOVE S1,S2 ;PLACE NUMBER IN S1
PUSHJ P,WTODAT ;OUTPUT BYTE TO MESSAGE
JUMPF EXAME3 ;ERROR ..TERMINATES MESSAGE
CAIG S2,.CHFFD ;CHECK IF GREATER THAN FF
CAIGE S2,.CHLFD ;CHECK IF LINE FEED
JRST EXAM.1 ;NO GET NEXT CHARACTER
SOJG P3,EXAM.1 ;WANT MORE...GO TO EXAM.1
EXAM.2: PUSHJ P,EXAMAC ;SEND AC AND MESSAGE TO ORION
EXAM.3: PUSHJ P,C$RPOS## ;REPOSITION THE CTL FILE
$RETIT ;ALL DONE IF IT WORKED
MOVE S1,.JREGS+P(R) ;GET THE STREAM STACK
PUSH S1,[B$ABORT] ;WHERE TO RESUME EXECUTION
MOVEM S1,.JREGS+P(R) ;SAVE UPDATED STACK POINTER
TXZ R,RL.STP!RL.OPR!RL.NSC!RL.ACK ;CLEAR FLAGS WHICH WOULD PREVENT
MOVEM R,.JREGS+R(R) ; RUNNING THIS STREAM AT TOPLVL
POPJ P, ;RETURN, WILL ABORT IN STREAM CONTEXT
EXAME1: $TEXT (WTODAT,<Control file ^F/.JQCFD(R)/ not open^A>)
PJRST EXAMAC ;SEND AC TO ORION
EXAME2: $TEXT (WTODAT,<^M^J *** End of File ***^A>)
JRST EXAM.2 ;FINISH OUT EXAMIN COMMAND
EXAME3: MOVEI S1,^D15*5 ;GET EXTRA ROOM
MOVEM S1,WTOCNT ;SAVE THE COUNT
$TEXT (WTODAT,< *** End of Show Data Page ***^A>)
JRST EXAM.2 ;SEND AND REPOSITION
EXAME4: $TEXT (WTODAT,<Invalid Show Control-File command>)
JRST EXAM.2 ;FINISH OFF THE COMMAND
EXAMAC: $ACK (<Show control file>,<^I/JIBTXT/^T/(P2)/>,.JQOBJ(R),.MSCOD(P1),<$WTJBN(.JBJNO(R))>)
MOVE S1,P2 ;GET THE PAGE
$CALL M%RPAG ;RELEASE THE PAGE
POPJ P, ;RETURN
WTODAT: SOSG WTOCNT ;DECREMENT COUNT
$RETF ;ABORT AND RETURN
IDPB S1,WTOPTR ;DEPOSIT BYTE
$RETT ;RETURN
SUBTTL IPCF/Operator/QUASAR interface -- ACK message #700000
ACK: MOVE P1,G$MADR ;GET MESSAGE ADDRESS
MOVX S2,MF.NOM ;GET THE 'NO MESSAGE' BIT
SKIPE S1,.MSCOD(P1) ;GET ACK CODE (IF ANY)
TDNN S2,.MSFLG(P1) ;ALL GOOD ACKS HAVE THIS BIT SET
JRST ACKTXT ;MUST BE SOME JUNK TEXT ACK
MOVEI S,0 ;CLEAR STREAM INDEX
ACK.1: SKIPL R,G$BASE(S) ;GET STREAM RELOCATION
JRST ACK.2 ;NOT SETUP
CAMN S1,.JOACK(R) ;CHECK THE ACK CODE
JRST ACK.3 ;FOUND IT
ACK.2: CAMGE S,G$HACT ;CHECKED ALL STREAMS YET?
AOJA S,ACK.1 ;NO - LOOP
POPJ P, ;RETURN
ACK.3: SETZM .JOACK(R) ;CLEAR ACK CODE
TXZ R,RL.ACK ;CLEAR WAITING FOR ACK BIT
MOVEM R,G$BASE(S) ;UPDATE STREAM FLAGS
POPJ P, ;RETURN
; Text ACKs
;
ACKTXT: MOVE S1,G$MADR ;GET MESSAGE ADDRESS
SKIPE .OARGC(S1) ;QUASAR SNIFFING AROUND?
$WTO(<BATCON Error>,<Unexpected text message - ^T/.OHDRS+ARG.DA(S1)/>)
POPJ P, ;RETURN
; Find new G$HACT stream
;
FHIACT: PUSH P,S ;SAVE THE CURRENT STREAM NUMBER
SKIPL G$BASE(S) ;IS STREAM ACTIVE?
SOJG S,.-1 ;NO - TRY ANOTHER
MOVEM S,G$HACT ;STORE STREAM NUMBER OR -1
POP P,S ;RESTORE CURRENT STREAM NUMBER
$RETT ;RETURN
SUBTTL STPPRC - Batch step processor
STPPRC::SETZM .JSSTP(R) ;CLEAR STEP LINE COUNTER
SKIPN .JBSPS(R) ;DOING ONLY A STEP HEADER SCAN?
JRST STPP.4 ;NO - CALLED FROM JOB PROCESSOR
PUSHJ P,C$OPEN## ;OPEN THE CONTROL FILE
PUSHJ P,C$READ## ;READ THE FIRST LINE
JUMPF CLOSJB ;EOF
CAXN S1,STPCHR ;IS IT THE MAGIC STEP HEADER CHARACTER?
JRST STPP.4 ;YES
STPP.1: PUSHJ P,B$EOJ ;FORCE END OF HEADER PROCESSING
JRST CLOSJB ;DISMISS JOB
STPP.2: TXNE R,RL.JIE ;JOB IN ERROR?
JRST HDRERR ;YES - ABORT IT
SKIPGE .JSSTP(R) ;END OF STEP?
JRST HDRXIT ;YES
STPP.3: PUSHJ P,C$READ## ;READ A LINE FROM THE CONTROL FILE
JUMPF CLOSJB ;END OF FILE
CAIN S1,.CHCRT ;BLANK LINE?
JRST STPP.3 ;YES - IGNORE IT
CAIE S1,";" ;OLD STYLE COMMENT?
CAIN S1,"!" ;NEW STYLE COMMENT?
JRST STPP.4 ;YES
CAXE S1,STPCHR ;STEP DELIMITER CHARACTER?
JRST HDRSSE ;ERROR - GO FINISH UP
STPP.4: PUSHJ P,C$STEP## ;PARSE PARAMETER LINES
JUMPF HDRERR ;PARSE ERRORS
JRST STPP.2 ;BACK FOR ANOTHER COMMAND
; Header syntax error
;
HDRSSE: $IDENT (HEADER,<^T/.JSCTL(R)/^A>) ;ECHO THE LINE IN ERROR
$IDENT (BATSSE,<? Step header syntax error>)
; Common header scan error code
;
HDRERR: TXO F,FL.UHE ;CALL IT AN UNHANDLED ERROR CONDITION
TXO R,RL.JIE ;JOB IN ERROR IF IT GOT THIS FAR
PUSHJ P,B$EOJ ;FORCE END OF HEADER PROCESSING
MOVE S1,.JLSTP(R) ;GET $STEP LABEL
CAMN S1,[-1] ;WAS IT A SPECIAL $STEP ERROR?
SETZM .JLSTP(R) ;YES
SKIPN S1 ;WAS $STEP LINE MISSING?
$IDENT (BATMSL,<? Missing $STEP line in header>)
SOSLE .JSSTP(R) ;ADJUST COUNT OF LINES PROCESSED
$IDENT (HEADER,<[^D/.JSSTP(R)/ lines processed in step ^W/.JLSTP(R)/ header]>)
$IDENT (BATBJC,<[Batch job canceled]>)
; Header scan exit
;
HDRXIT: TXNN R,RL.JIE ;JOB IN ERROR?
SKIPE .JBSPS(R) ;OR DOING ONLY A STEP HEADER SCAN?
JRST CLOSJB ;YES - DISMISS THE JOB
POPJ P, ;NO - RETURN TO JOB PROCESSOR
SUBTTL JOBPRC - Process a Batch stream
; JOBPRC will do the following:
; a) Open the control file
; b) Open the log file
; c) Put a header on the log file
; d) LOGIN a job
; e) Perform post LOGIN job setup
; f) Initialize job processing
; g) Enter job processor loop
;
JOBPRC: PUSHJ P,U$STJB## ;HANDLE SPECIAL STARTUP PROCESSING
PUSHJ P,C$FILE## ;FIX UP THE CTL FILESPEC
MOVEI T1,FILTX1 ;ASSUME NORMAL BATCH JOB
TXNE F,FL.KST ;KSYS STREAM?
MOVEI T1,FILTX2 ;YES
$WTOJ (<Begin>,<^I/JIBTXT/^I/(T1)/>,.JQOBJ(R),<$WTNOD(.JQLOC(R))>)
PUSHJ P,L$HEAD## ;PREPARE A LOG FILE HEADER
PUSHJ P,L$OPEN## ;OPEN THE LOG FILE
PUSHJ P,C$OPEN## ;OPEN THE CONTROL FILE
PUSHJ P,CHKPNT ;CHECKPOINT JOB
PUSHJ P,LOGINJ ;LOGIN THE JOB
PUSHJ P,JOBINI ;INITIALIZE JOB PROCESSING
TXNE F,FL.KST ;KSYS STREAM?
PJRST B$CLOS ;YES--TERMINATE NOW
TXNE R,RL.ACK ;MUST WE WAIT FOR INITIAL ACK?
PUSHJ P,QTS ;YES, MUST BE NORESTARTABLE
JRST HONORJ ;ENTER JOB PROCESSING LOOP
FILTX1: ITEXT (<Control file: ^F/.JQCFD(R)/^M^JLog file: ^F/.JQLFD(R)/>)
FILTX2: ITEXT (<Log file: ^F/.JQLFD(R)/>)
; Here to honor a job's input request
;
HONORJ: PUSHJ P,IOWAIT ;WAIT FOR I/O COMPLETION
TXNN J,JL.UJA ;IS THE JOB STILL THERE?
PJRST B$GONE ;NO
TXNE R,RL.NLG ;LOG FILE OUTPUT ERROR?
PUSHJ P,L$IOER## ;YES
TXNE F,FL.TLE ;WAS TIME LIMIT EXCEEDED?
PUSHJ P,TIMERR ;YES - TRY TO GIVE MORE TIME
TXNE R,RL.DIA ;JOB IN DIALOGUE MODE?
PUSHJ P,REDOPR ;YES
PUSHJ P,U$HNRJ## ;PROCESS SPECIAL CUSTOMER CHECKING
JRST B$CLOS ;DISMISS JOB IF ERROR OCCURS
TXZE F,FL.RCL ;RE-EAT COMMAND LINE?
JRST HONOR1 ;YES
PUSHJ P,C$READ## ;NO - READ A LINE FROM THE CONTROL FILE
JUMPF CLOSJB ;END OF FILE?
HONOR1: PUSHJ P,C$SCAN## ;SCAN AND PROCESS A COMMAND
JRST HONORJ ;LOOP
SUBTTL BATCON initialization -- System independant code
B$INIT: MOVE S1,[PUSHJ P,UUOCON] ;LOCAL UUO HANDLER
MOVEM S1,.JB41## ;SET IT UP
SETOM G$STRM ;SET UP STREAM INDEX BLOCK
MOVX S1,<G$STRM,,G$STRM+1> ; BY PUTTING -1 IN EACH WORD
BLT S1,G$STRM+JOBMAX-1 ; TO INDICATE STREAM NOT IN USE
MOVX S1,INPCOR ;GET CORE FLAG
MOVEM S1,G$CORE ;REMEMBER FOR LATER
SETZM G$MDA ;ASSUME NO MDA SUPPORT
$CALL L%CLST ;CREATE A LINKED LIST
MOVEM S1,CLKQUE ; FOR THE CLOCK REQUEST QUEUE
$CALL .CPUTY ;GET CPU TYPE
MOVEM S1,G$CPU ;SAVE IT
; Get our node number
SETO S1, ;-1 MEANS US
MOVX S2,JI.LOC ;FUNCTION CODE
$CALL I%JINF ;GET OUR NODE NUMBER
MOVEM S2,G$NODE ;STORE IT
PUSHJ P,SYSINI ;DO SYSTEM DEPENDANT INITIALIZATION
; Greet QUASAR
PUSHJ P,HELLO ;GREET QUASAR
MOVEI S1,REENTER ;GET REENTER ADDRESS
MOVEM S1,.JBREN## ;SET IT UP
POPJ P, ;RETURN
SUBTTL BATCON initialization -- TOPS-10 code
; TOPS-10 initialization
;
TOPS10 < ;TOPS-10 ONLY
SYSINI: MOVX S1,OPTYP% ;GET OUR OBJECT PROCESSOR TYPE
SETOM G$BUDT ;ASSUME %ONCE (SHOULDN'T BE, BUT..)
SKIPE DEBUGW ;DEBUGGING?
JRST SYSI.0 ;YES
CAXN S1,%DEMND ;"FIRED UP" WHEN JOB TO DO?
AOSA G$BUDT ;YES, MAKE G$BUDT +1
CAXN S1,%STCMD ;NO, "FIRED UP" ON START COMMAND?
AOS G$BUDT ;YES, MAKE G$BUDT 0
SYSI.0: SETO S1, ;-1 MEANS US
WAKE S1, ;THIS GUARANTEES US A OUR FIRST WAKE UP
JFCL ;WON'T FAIL
MOVE S1,[%LDFFA] ;GET OPERATOR PPN
GETTAB S1, ;FROM THE MONITOR
MOVE S1,[1,,2] ;DEFAULT
MOVEM S1,OPRPPN ;SAVE
MOVE S1,[%LDQUE] ;GET QUEUE PPN
GETTAB S1, ;FROM THE MONITOR
MOVE S1,[3,,3] ;DEFAULT TO THE USUAL
MOVEM S1,G$SPLD ;STORE IT
MOVE S1,[%CNPTY] ;GET SYSTEM PTY CONFIGURATION
GETTAB S1, ;FROM THE MONITOR
SETZ S1, ;CAN'T
HLRZM S1,G$PTYF ;STORE FIRST PTY
HRRZM S1,G$PTYN ;STORE NUMBER OF PTYS
; Set up the interrupt system
MOVX S1,<VECTOR,,VECTOR+1> ;SET UP A BLT POINTER
SETZM VECTOR ;CLEAR THE FIRST WORD
BLT S1,ENDVEC ;CLEAR THE INTERRUPT DATA
MOVEI S1,IPCINT ;GET ADDRESS OF IPCF INTERRUPT ROUTINE
MOVEM S1,VECIPC+.PSVNP ;STORE IN VECTOR
HRREI T1,.PCIPC ;IPCF CONDITION CODE
MOVSI T2,<VECIPC-VECTOR> ;VECTOR OFFSET
MOVSI T3,IPCLVL ;GET IPCF PRIORITY LEVEL
MOVX S1,PS.FAC+T1 ;FUNCTION CODE TO ADD THE CONDITION
PISYS. S1, ;ADD IT
STOPCD (CEI,HALT,,<Can't enable interrupts>) ;++ CAN'T CONTINUE
$CALL I%ION ;TURN ON THE INTERRUPT SYSTEM
MOVE S1,[%CNST2] ;GET SECOND MONITOR STATES WORD
GETTAB S1, ;READ IT
SETZ S1, ;CAN'T
TXNE S1,ST%MDA ;MONITOR SUPPORT MDA?
SETOM G$MDA ;YES
HRROI S1,.GTPPN ;GET OUR PPN
GETTAB S1, ;GET OUR PPN
JFCL ;CAN'T
CAME S1,[1,,2] ;ARE WE GODLY?
SETZM G$MDA ;NO - THEN NO MDA
SKIPN G$MDA ;ARE WE GONNA SUPPORT MDA?
POPJ P, ;NO - ALL DONE
SYSI.1: MOVX S1,SP.MDA ;GET SPECIAL PID INDEX
$CALL C%RPRM ;ASK THE LIBRARY FOR THE MDA PID
JUMPT .POPJ ;GOT IT
MOVEI S1,5 ;5 SECONDS
$CALL I%SLP ;ZZZZZZ
JRST SYSI.1 ;TRY AGAIN
> ;END OF TOPS-10 CONDITIONAL
SUBTTL BATCON initialization -- TOPS-20 code
; TOPS-10 initialization
;
TOPS20 < ;TOPS-20 ONLY
SYSINI: MOVX S1,RC%EMO ;EXACT MATCH ONLY
HRROI S2,[ASCIZ |PS:[SPOOL]|] ;DIRECTORY NAME
RCDIR ;GET THE DIRECTORY NUMBER
MOVEM T1,G$SPLD ;STORE IT
MOVX S1,'PTYPAR' ;GET SOME PTY PARAMETERS
SYSGT ;FROM THE MONITOR
HRRZM S1,G$PTYF ;SAVE FIRST PTY NUMBER
HLRZM S1,G$PTYN ;SAVE THE NUMBER OF PTYS IN THE SYSTEM
MOVX S1,.MSIIC ;BYPASS MOUNT COUNTS
MSTR ;DO THE FUNCTION
ERJMP .+1 ;IGNODE ERRORS
MOVX S1,.FHSLF ;GET OUR PROCESS HANDLE
MOVEI S2,104 ;GET THE DESIRED QUEUE
SPRIW ;SET PRIORITY WORD FOR OUR JOB
ERJMP .+1 ;IGNORE ERRORS
; Set up the interrupt system
MOVEI S1,INTRP1 ;GET INTERRUPT LEVEL 1 PC
MOVEM S1,LEVTAB ;STORE IT
MOVEI S1,INTRP2 ;GET INTERRUPT LEVEL 2 PC
MOVEM S1,LEVTAB+1 ;STORE IT
MOVEI S1,INTRP3 ;GET INTERRUPT LEVEL 3 PC
MOVEM S1,LEVTAB+2 ;STORE IT
MOVX S1,<IPCLVL,,IPCINT> ;GET INTERRUPT LEVEL FOR IPCF
MOVEM S1,CHNTAB+IPCCHN ;SET UP CHANNEL
MOVX S1,<PTYLVL,,PTYINT> ;GET INTERRUPT LEVEL FOR PTYS
MOVEM S1,CHNTAB+PTYCHN ;SET UP CHANNEL
MOVEM S1,CHNTAB+PTYCHN+1 ;PTYS NEED TWO
CIS ;CLEAR INTERRUPT SYSTEM
$CALL I%ION ;TURN IT ON
MOVX S1,.FHSLF ;GET OUR PROCESS HANDLE
MOVX S2,INTMSK ;GET MASK OF CHANNELS TO ACTIVATE
AIC ;ACTIVATE THOSE CHANNELS
POPJ P, ;RETURN
> ;END OF TOPS-20 CONDITIONAL
SUBTTL Batch generated commands -- Buffer management
; Set up the byte pointer and byte count for Batch generated commands
;
B$CINI::MOVX S1,CTLSIZ ;GET THE NUMBER OF CHARACTERS ALLOWED
MOVEM S1,.JSCTC(R) ;STORE IT
HRLI S1,.JSCTL(R) ;BUILD A BLT POINTER
HRRI S1,.JSCTL+1(R) ;TO CLEAR THE COMMAND BUFFER
SETZM .JSCTL(R) ;CLEAR THE FIRST WORD
BLT S1,.JSCTL+<CTLSIZ/5>(R) ;ZAP THE REMAINDER
; SET UP THE BYTE POINTER TO THE IN-CORE COMMAND BUFFER
;
B$SETB::MOVEM S1,.JSCTB(R) ;SAVE S1
MOVE S1,[POINT 7,.JSCTL(R)] ;GET BYTE POINTER TO TEXT BUFFER
EXCH S1,.JSCTB(R) ;STORE IT AND RESTORE S1
POPJ P, ;RETURN SUCESSFUL
; Put a quoted character into the command buffer
;
B$CQUO::CAIN S1,"""" ;IS IT A DOUBLE QUOTE?
PUSHJ P,B$CPUT ;OUTPUT AN EXTRA - FALL INTO B$CPUT
; Put a character into the command buffer
;
B$CPUT::SOSG .JSCTC(R) ;COUNT CHARACTERS
$RETF ;BUFFER FULL
IDPB S1,.JSCTB(R) ;STORE CHARACTER
$RETT ;RETURN SUCESSFUL
; Transfer the contents of the command buffer pointed to by .JSCTB(R)
; to the PTY
;
B$XFER::ILDB S1,.JSCTB(R) ;GET A CHARACTER
JUMPE S1,XFER.3 ;DONE IF WE ENCOUNTER A <NUL>
CAXE S1,.CHCRT ;A CARRIAGE RETURN?
JRST XFER.1 ;NOPE
TXO F,FL.CTP ;REMEMBER A <CR> SEEN
TXZN F,FL.SUP ;SUPRESS EOL CHARACTERS?
JRST XFER.1 ;NO TO EITHER
ILDB S1,.JSCTB(R) ;EAT THE LINE FEED FOLLOWING <CR>
XFER.1: CAXE S1,.CHLFD ;END OF LINE?
JRST XFER.2 ;YES - IGNORE <LF> AND FINISH UP
TXZE F,FL.CTP ;CARRIAGE RETURN PRECEED THE LINE FEED?
JRST XFER.3 ;YES - IGNORE THE LINE FEED
XFER.2: PUSHJ P,P$OCHR## ;SEND CHARACTER TO THE PTY
JRST B$XFER ;LOOP UNTIL END OF LINE
XFER.3: SETOM .JPEOL(R) ;REMEMBER END OF LINE SENT
TXO F,FL.ECH ;GET READY FOR ECHO LINE
PJRST P$OBUF## ;FORCE OUT PTY BUFFERS AND RETURN
SUBTTL Batch generated commands -- TOPS-10 Login
TOPS10 < ;TOPS-10 ONLY
; TOPS-10 Login
;
LOGINJ: SETOM .JLTIM(R) ;FORCE A TIME STAMP
PUSHJ P,P$CTLC## ;SEND A CONTROL-C
PUSHJ P,IOWAIT ;WAIT FOR I/O COMPLETION
PUSHJ P,P$TERM## ;SET UP PTY'S TERMINAL CHARACTERISTICS
TXNE F,FL.KST ;KSYS STREAM?
JRST ATTJOB ;YES--DO AN ATTACH INSTEAD
PUSHJ P,B$CINI ;SET UP THE COMMAND BUFFER
$TEXT (B$CPUT,<LOGIN ^A>) ;SEND LOGIN COMMAND
MOVE S1,.JQPPN(R) ;GET THE PPN
SKIPN .JQPAT(R) ;IS THERE ONE IN THE PATH SPEC?
MOVEM S1,.JQPAT(R) ;NO - PUT ONE THERE
CAME S1,.JQPAT(R) ;ARE THE PPNS THE SAME?
$TEXT (B$CPUT,<^O/.JQPPN(R),LHMASK/,^O/.JQPPN(R),RHMASK/ ^A>)
$TEXT (B$CPUT,<[^O/.JQPAT(R),LHMASK/,^O/.JQPAT(R),RHMASK/^A>)
MOVEI T1,.JQPAT+1(R) ;GET STARTING ADDRESS OF PATH
HRLI T1,-5 ;SFD COUNTER
LGN1: SKIPN (T1) ;HAVE AN SFD?
TDZA T1,T1 ;NO - END OF PATH
$TEXT (B$CPUT,<,^W/(T1)/^A>) ;SEND THE SFD
AOBJN T1,LGN1 ;LOOP FOR ENTIRE PATH
$TEXT (B$CPUT,<] -^M^A>) ;TERMINATE PPN OR PATH
PUSHJ P,B$SETB ;RESET THE BYTE POINTER
PUSHJ P,B$XFER ;TRANSFER THE LINE TO THE PTY
PUSHJ P,IOWAIT ;WAIT FOR I/O COMPLETION AND RETURN
PUSHJ P,B$CINI ;SET UP THE COMMAND BUFFER
; Batch parameters
$TEXT (LGNCHR,</BATCH:(^A>) ;START BATCH SWITCHES
GETLIM T1,.JQLIM(R),OINT ;GET OPRINT VALUE
CAIN T1,.OPINN ;NO INTERVENTION?
SKIPA T1,['NO '] ;YES - HE SAID NO
HRLZI T1,'YES' ;NO - HE SAID YES
$TEXT (LGNCHR,<INTERVENTION:^W/T1/,NAME:"^A>)
$TEXT (LGNQUO,<^W/.JQJBB+JIB.JN(R)/^A>)
$TEXT (LGNCHR,<",SEQUENCE:^D/.JQJBB+JIB.SQ(R),JB.SEQ/^A>)
$TEXT (LGNCHR,<,STREAM:^O/.JQOBJ+OBJ.UN(R)/^A>)
$TEXT (LGNCHR,<,REQUESTID:^D/.JQJBB+JIB.ID(R)/)^A>)
; Accounting parameters
$TEXT (LGNCHR,</ACCOUNT:"^A>)
$TEXT (LGNQUO,<^T/.JQACT(R)/^A>)
$TEXT (LGNCHR,<"/NAME:"^A>)
$TEXT (LGNQUO,<^W6/.JQJBB+JIB.NM(R)/^W/.JQJBB+JIB.NM+1(R)/^A>)
MOVEI S1,"""" ;TERMINATE NAME STRING
PUSHJ P,LGNCHR ;TERMINATE COMMAND
; Job parameters
LGN2: GETLIM T1,.JQLIM(R),OPTN ;GET BATCH OPTION NAME
SKIPE T1 ;HAVE ONE?
$TEXT (LGNCHR,</OPTION:^W/T1/^A>)
GETLIM T1,.JQLIM(R),CORE ;GET CORE LIMIT
SKIPE G$CORE ;CHECKING CORE LIMITS?
$TEXT (LGNCHR,</CORE:^D/T1/P^A>)
GETLIM T1,.JQLIM(R),TIME ;GET TIME LIMIT
$TEXT (LGNCHR,</DEFER/LOCATE:^O/.JQLOC(R)//SPOOL:ALL/TIME:^D/T1/^A>)
PUSHJ P,U$LOGI## ;APPEND SPECIAL CUSTOMER SWITCHES
MOVEI S1,.CHCRT ;GET A CARRIAGE RETURN
PUSHJ P,LGNCHR ;TERMINATE COMMAND
PUSHJ P,B$SETB ;RESET THE BYTE POINTER
PUSHJ P,B$XFER ;TRANSFER THE LINE TO THE PTY
PUSHJ P,IOWAIT ;WAIT FOR I/O COMPLETION AND RETURN
JRST LOGSET ;GO DO POST LOGIN SETUP
; Here to attach to the job
ATTJOB: MOVE S1,.JPTTY(R) ;GET PTY'S UDX
ANDI S1,UX.UNT ;KEEP JUST THE LINE NUMBER
HRLZS S1 ;PUT IN LH
HRR S1,.JBJNO(R) ;GET JOB NUMBER
TXO S1,AT.UMM ;PUT IN MONITOR MODE
ATTACH S1, ;DO IT
PJRST B$GONE ;TOO BAD
$IDENT (BATCH,<^7/[MONCHR]/ATTACH ^D/.JBJNO(R)/ ^P/.JQPPN(R)/>)
MOVE T1,['HALT '] ;BE MEAN
MOVE T2,.JBJNO(R) ;GET JOB NUMBER
MOVE S1,[2,,T1] ;SET UP UUO AC
FRCUUO S1, ;STOP JOB
PUSHJ P,P$CTLC## ;SEND A SINGLE CONTROL-C TO HALT JOB
PUSHJ P,IOWAIT ;EAT OUTPUT
POPJ P, ;RETURN
; TOPS-10 post LOGIN setup
;
LOGSET: TXNE J,JL.ULI ;IS A JOB LOGGED IN?
TXNE R,RL.JIE ;DID LOGIN FAIL?
PUSHJ P,ANALYZ ;NOT LOGGED IN - ANALYZE THE ERROR
PUSHJ P,CHKPNT ;CHECKPOINT JOB
PUSHJ P,P$TERM## ;SET UP PTY'S TERMINAL CHARACTERISTICS
PUSHJ P,U$PLGN## ;DO SPECIAL POST-LOGIN PROCESSING
JRST B$CLOS ;SOMETHING WRONG - DISMISS JOB
POPJ P, ;RETURN
; Special character sticker routines for LOGIN command line processing.
; These must be used instead of B$CPUT/B$CQUO to cause continuation line
; processing to happen.
LGNQUO: CAIN S1,"""" ;DOUBLE QUOTE?
PUSHJ P,LGNCHR ;YES--OUTPUT TWO
LGNCHR: PUSH P,S1 ;SAVE CHARACTER
PUSH P,S2 ;SAVE JUNK
MOVEI S1,CTLSIZ+2 ;BUFFER SIZE + "-" AND <CR>
SUB S1,.JSCTC(R) ;COMPUTE CHARACTERS STORED
IDIVI S1,^D80 ;SEE HOW MANY CHARACTER ON LINE
JUMPN S2,LGNC.1 ;TIME FOR A CONTINUATION LINE?
MOVEI S1,"-" ;CHARACTER
PUSHJ P,LGNC.2 ;STORE
MOVEI S1,.CHCRT ;CARRIAGE RETURN
PUSHJ P,LGNC.2 ;STORE
LGNC.1: POP P,S2 ;RESTORE JUNK
POP P,S1 ;RESTORE CHARACTER
LGNC.2: SOSG .JSCTC(R) ;COUNT CHARACTERS
$RETF ;BUFFER FULL
IDPB S1,.JSCTB(R) ;STORE CHARACTER
$RETT ;RETURN SUCESSFUL
> ;END OF TOPS-10 CONDITIONAL
SUBTTL Batch generated commands -- TOPS-20 Login
TOPS20 < ;TOPS-20 ONLY
; TOPS-20 Login
;
LOGINJ: SETOM .JPEOL(R) ;FAKE OUT IN CASE OF PROBLEMS
PUSHJ P,P$CTLC## ;SEND A CONTROL-C
PUSHJ P,IOWAIT ;WAIT FOR I/O COMPLETION
PUSHJ P,P$TERM## ;SET UP PTY'S TERMINAL CHARACTERISTICS
TXNE R,RL.JIE ;JOB IN ERROR (? FULL)
PJRST ANLY.2 ;YES - REQUEUE THE JOB
LGN: PUSHJ P,B$CINI ;SET UP THE COMMAND BUFFER
GETLIM T1,.JQLIM(R),TIME ;GET TIME LIMIT
$TEXT (B$CPUT,<SET TIME-LIMIT ^D/T1/^M^A>)
PUSHJ P,B$SETB ;RESET THE BYTE POINTER
PUSHJ P,B$XFER ;TRANSFER THE LINE TO THE PTY
PUSHJ P,IOWAIT ;WAIT FOR I/O COMPLETION
TXNE R,RL.JIE ;JOB IN ERROR?
PUSHJ P,ANALYZ ;YES..ANALYZE THE ERROR
PUSHJ P,SETLOC ;SETUP LOCATION
MOVE S1,[POINT 7,.JQACT(R)] ;GET BYTE POINTER TO ACCT STRING
LGN1: ILDB S2,S1 ;GET A CHARACTER
JUMPE S2,LGN2 ;END OF STRING?
CAIGE S2,176 ;RANGE CHECK
CAIGE S2," " ; IT FOR LEGALITY
JRST LGNERR ;NO GOOD
JRST LGN1 ;LOOP
LGN2: PUSHJ P,B$CINI ;SET UP THE COMMAND BUFFER
$TEXT (B$CPUT,<LOGIN ^T/.JQNAM(R)/ FOO ^T/.JQACT(R)/^A>)
PUSHJ P,U$LOGI## ;APPEND SPECIAL CUSTOMER SWITCHES
MOVX S1,.CHCRT ;GET A CARRIAGE RETURN
PUSHJ P,B$CPUT ;TERMINATE COMMAND
PUSHJ P,B$SETB ;RESET THE BYTE POINTER
PUSHJ P,B$XFER ;TRANSFER THE LINE TO THE PTY
PUSHJ P,IOWAIT ;WAIT FOR I/O COMPLETION AND RETURN
JRST LOGSET ;DO POST LOGIN PROCESSING
LGNERR: ANDI S2,37 ;MAKE SURE NO JUNK (SORRY RUBOUT)
ADDI S2,"@" ;MAKE IT READABLE
$IDENT (BATICA,<? ^I/LGNTXT/>)
$WTOJ (<Batch error>,<^R/.JQJBB(R)/^I/LGNTXT/>,.JQOBJ(R),<$WTNOD(.JQLOC(R))>)
JRST B$ABORT ;DISMISS THE JOB
LGNTXT: ITEXT (<Illegal character "^^^7/S2/" in account string; job canceled>)
; TOPS-20 post LOGIN setup
; The following job parameters are set:
; a) Mount count on connected directory's structure
; b) CONNECT to requested directory
; c) Batch stream number
;
LOGSET: TXNE J,JL.ULI ;IS A JOB LOGGED IN?
TXNE R,RL.JIE ;DID LOGIN FAIL?
PUSHJ P,ANALYZ ;NOT LOGGED IN - ANALYZE THE ERROR
PUSHJ P,P$TERM## ;SET UP PTY'S TERMINAL CHARACTERISTICS
TXO R,RL.DRT ;DELAY THE RESPONSE BUFFER OUTPUT
MOVX S1,.MSIMC ;FUNCTION CODE TO INCREMENT MOUNT COUNT
HRLI S1,2 ;2 WORD BLOCK
MOVEI S2,T1 ;POINT TO BLOCK
HRROI T1,.JQCON(R) ;POINT TO THE CONNECTED DIRECTORY
MOVE T2,.JBJNO(R) ;GET THE JOB NUMBER
MSTR ;CHANGE MOUNT COUNT
ERJMP .+1 ;IGNORE FOR NOW
MOVX S1,AC%CON+3 ;FLAGS,,LENGTH IN 1
MOVEI S2,T1 ;ADR IN 2
HRROI T1,.JQCON(R) ;ADR POINTS TO STR-DIR STRING
HRROI T2,[ASCIZ / /] ;ADR+1 POINTS TO PSW (DUMMY)
HRRZ T3,.JBJNO(R) ;ADR+2 POINTS TO JOB NUMBER
ACCES ;CONNECT THE JOB
ERJMP .+2 ;DON'T WAIT IF IT FAILED
PUSHJ P,IOWAIT ;GET RESPONSE FROM ACCES JSYS
HRRZ S1,.JBJNO(R) ;GET THE JOB NUMBER
MOVEI S2,.SJDFS ;SET DEFAULT SPOOLING
MOVEI T1,.SJSPD ;A = S2 + 1, SET DEFERRED
SETJB ;SET IT FOR THE JOB
ERJMP .+1 ;IGNORE THE ERROR..
HRRZ S1,.JBJNO(R) ;GET THE JOB NUMBER
MOVEI S2,.SJBAT ;SET BATCH INFO
SETZM T1 ;CLEAR DATA WORD
MOVE T2,.JQOBJ+OBJ.UN(R) ;GET STREAM NUMBER
STORE T2,T1,OB%BSN ;SAVE BATCH STREAM NUMBER IN WORD
TXO T1,OB%BSS ;SET THE STREAM SET FLAG
GETLIM T2,.JQLIM(R),OINT ;GET THE OPERATOR INTERVENTION VALUE
CAXE T2,.OPINN ;WAS NO INTERVENTION SPECIFIED?
JRST LOGS.1 ;NO - IGNORE THIS FUNCTION
MOVX T2,.OBNWR ;TURN OFF THE CAPABILITY
STORE T2,T1,OB%WTO ;STORE IN ARGUMENT BLOCK
LOGS.1: SETJB ;SET BATCH PARAMETERS
ERJMP .+1 ;IGNORE ERRORS
PUSHJ P,U$PLGN## ;DO SPECIAL POST-LOGIN PROCESSING
JRST B$CLOS ;SOMETHING WRONG - DISMISS JOB
POPJ P, ;RETURN
> ;END OF TOPS-20 CONDITIONAL
SUBTTL Batch generated commands -- Kill a job
B$KJOB::TXNE R,RL.DRT ;RESPONSE BUFFER OUTPUT DELAYED?
PUSHJ P,B$RTYO ;YES - DUMP IT NOW
PUSHJ P,P$STAT## ;GET JOB'S STATUS
TXNN J,JL.ULI ;IS JOB LOGGED IN?
$RETT ;NO - RETURN
TXNE R,RL.FKJ ;FAST KJOB REQUESTED?
$IDENT (ABORT,<? Job aborted due to batch system shutdown>)
TXZ F,FL.SIL ;CLEAR SILENCE SO LOG FILE SHOWS ALL
PUSHJ P,P$STOP## ;PUT THE JOB IN MONITOR MODE
PUSHJ P,U$KJOB## ;DO ANY SPECIAL PRE-KJOB PROCESSING
KJOB.1: PUSHJ P,P$STOP## ;PUT THE JOB IN MONITOR MODE
TXNN J,JL.ULI ;IS THE JOB STILL THERE?
$RETT ;NO - RETURN
TXO R,RL.KJB ;MARK ON THE WAY OUT
TOPS10 < ;TOPS-10 ONLY
MOVEI S1,"""" ;GET A QUOTE
MOVEM S1,.JBOCH(R) ;SET AS DIALOGUE MODE SIGNAL
MOVEI S1,"?" ;GET A QUESTION MARK
MOVEM S1,.JBECH(R) ;SET AS ERROR CHARACTER
PUSHJ P,B$CINI ;SET UP THE COMMAND BUFFER
$IDENT (BATCH,<^7/[MONCHR]/KJOB/BATCH>) ;FAKE KJOB COMMAND IN THE LOG
MOVE TF,[2,,S1] ;SET UP UUO
MOVE S1,[SIXBIT/KJOB/] ;COMMAND TO FORCE
MOVE S2,.JBJNO(R) ;GET JOB NUMBER
FRCUUO TF, ;FORCE THE KJOB COMMAND
JFCL ;CAN'T
> ;END OF TOPS-10 CONDITIONAL
TOPS20 < ;TOPS-20 ONLY
$IDENT (BATCH,<^7/[MONCHR]/LOGOUT>) ;FAKE LOGOUT COMMAND IN THE LOG
SETOM .JLTIM(R) ;FORCE A TIME STAMP
MOVE S1,.JBJNO(R) ;GET THE JOB NUMBER
LGOUT ;KILL THE JOB
JFCL ;IGNORE ERRORS FOR NOW
> ;END OF TOPS-20 CONDITIONAL
MOVE S1,G$CPU ;GET CPU TYPE
MOVEI T1,KJTIME ;GET KJOB TIME
CAIN S1,%KS10 ;A SLOW MACHING?
LSH T1,1 ;YES - MULTIPLY BY 2
HRLI T1,.CQLGO ;EVENT CODE IS LOGOUT
MOVEI T2,0 ;NO DISPATCH
PUSHJ P,B$CLKS ;MAKE A CLOCK REQUEST
PUSHJ P,QTS ;WAIT A WHILE CUZ THE -20 IS SO SLOW
KJOB.2: PUSHJ P,IOWAIT ;WAIT FOR I/O COMPLETION
TXNN R,RL.FKJ ;FAST KJOB?
TXNN J,JL.ULI ;DID THE JOB GO AWAY?
POPJ P, ;YES TO EITHER - RETURN
MOVEI S1,LGOTYP ;GET ADDRESS OF TYPE ITEXT BLOCK
MOVEI S2,LGOTXT ;GET ADDRESS OF MAIN ITEXT BLOCK
MOVEI T1,LGOTAB ;GET ADDRESS OF RESPONSE TABLE
PUSHJ P,B$OPER ;ASK THE OPERATOR FOR HELP
JRST KJOB.1 ;SEE IF THE JOB IS STILL THERE
LGOTYP: ITEXT (<Batch error>)
LGOTXT: ITEXT (<Unable to log out job ^D/.JBJNO(R)/.
Type 'RESPOND ^I/NUMBER/ PROCEED' to try again or kill the job>)
LGOTAB: $STAB
KEYTAB (0,<PROCEED>)
$ETAB
SUBTTL Batch generated commands -- CLOSE/DUMP
; Check to see if CLOSE/DUMP commands are necessary
; *** Note ***
; This routine will not use B$CINI/B$XFER routines for sending the CLOSE/DUMP
; commands since this will destroy the contents of .JSCTL(R). .JSCTL(R) must
; be preserced for DUMP output.
;
B$DUMP::TXNN R,RL.JIE ;JOB IN ERROR?
POPJ P, ;NO - JUST RETURN
TXO F,FL.UHE ;SET AN UNEXPECTED ERROR CONDITION
TXNN J,JL.ULI ;JOB LOGGED IN?
POPJ P, ;NO
$IDENT (BATCH,<^7/[MONCHR]/DUMP^A>) ;FAKE DUMP COMMAND IN THE LOG FILE
PUSHJ P,.DUMP## ;FORCE A DUMP BATCH COMMAND
JFCL ;IGNORE ERRORS
PUSHJ P,B$RTYO ;ECHO THE RESPONSE BUFFER
PUSHJ P,P$STOP## ;STOP THE JOB
TOPS10 < ;TOPS-10 ONLY
PUSHJ P,B$RTYO ;ECHO THE RESPONSE BUFFER
$TEXT (P$OCHR##,<CLOSE^M^A>) ;SEND THE CLOSE COMMAND
PUSHJ P,P$OBUF## ;FORCE OUT PTY BUFFERS
PUSHJ P,IOWAIT ;WAIT FOR I/O COMPLETION
PUSHJ P,P$STOP## ;MAKE SURE THE JOB IS STOPPED
> ;END OF TOPS-10 CONDITIONAL
POPJ P, ;RETURN
SUBTTL Batch WTO/WTOR -- Initialization and character storage
; Initialize the WTO/WTOR buffer
;
B$WINI::MOVE S1,[POINT 7,.JWTOP(R)] ;GET BYTE POINTER
MOVEM S1,.JWPTR(R) ;STORE IT
MOVX S1,CTLSIZ ;GET THE MAXIMUM NUMBER OF CHARACTERS
MOVEM S1,.JWCNT(R) ;STORE IT
POPJ P, ;RETURN
; Store a character in the WTO/WTOR buffer
;
B$WPUT::SOSLE .JWCNT(R) ;COUNT CHARACTERS
IDPB S1,.JWPTR(R) ;DEPOSIT CHARACTER IF ROOM IN BUFFER
POPJ P, ;RETURN
; End WTO/WTOR buffer
;
B$WEOL::PUSH P,S1 ;SAVE S1
MOVX S1,.CHNUL ;GET A <NUL>
IDPB S1,.JWPTR(R) ;END THE LINE
SETOM .JWCNT(R) ;NO MORE ROOM IN BUFFER
POP P,S1 ;RESTORE S1
POPJ P, ;RETURN
SUBTTL Batch WTO/WTOR -- Write To OPR
; Write To OPR (WTO)
;
B$WTO:: PUSHJ P,B$WEOL ;TERMINATE THE BUFFER
$WTO (<Message from batch user>,<^I/JIBTXT/^T/.JWTOP(R)/>,.JQOBJ(R),<$WTJBN(.JBJNO(R)),$WTNOD(.JQLOC(R))>)
POPJ P, ;RETURN
; Write To OPR with a Response (WTOR)
;
B$WTOR::PUSHJ P,B$WEOL ;TERMINATE THE BUFFER
MOVE S1,.JQITN(R) ;GET OUR ITN
MOVEM S1,.JOACK(R) ;USE IT AS THE ACK CODE
$WTOR (<Message from batch user>,<^I/JIBTXT/^T/.JWTOP(R)/>,.JQOBJ(R),.JOACK(R),<$WTJBN(.JBJNO(R)),$WTNOD(.JQLOC(R))>)
POPJ P, ;RETURN
SUBTTL Batch WTO/WTOR -- Get operator response to a WTOR
; Put job in operator wait and get response
;
B$WRSP::TXO R,RL.OPR ;MARK WAITING FOR THE OPERATOR
MOVX T1,%OREWT ;STATUE CODE
PUSHJ P,B$UPDA ;UPDATE QUASAR
PUSHJ P,QTS ;WAIT FOR OPERATOR RESPONSE
MOVX T1,%RESET ;RESET STATUS
PUSHJ P,B$UPDA ;UPDATE QUASAR
SETZM .JBCHK(R) ;FORCE A CHECKPOINT
PUSHJ P,P$STAT## ;GET THE JOB STATUS
MOVE T1,[POINT 7,.JORSP(R)] ;POINT TO RESPONSE BUFFER
MOVE S2,[POINT 7,.JWFOP(R)] ;BYTE POINTER TO DESTINATION
WRSP.1: ILDB S1,T1 ;GET A CHARACTER
IDPB S1,S2 ;PUT A CHARACTER
CAME S2,[POINT 7,.JWFOP+<CTLSIZ/5>(R),27] ;BUFFER FULL?
JUMPN S1,WRSP.1 ;NO - LOOP UNLESS END OF TEXT
WRSP.2: MOVEI S1,.CHNUL ;END THE STRING
IDPB S1,S2 ;STORE <NUL>
POPJ P, ;RETURN
SUBTTL Response buffer support
; Store a character in the response buffer
;
B$RPUT::MOVE S2,.JBRBP(R) ;GET BYTE POINTER
CAME S2,[POINT 7,.JBRSP+PTYBLK-3-1(R),27] ;BUFFER OVERFLOW?
IDPB S1,.JBRBP(R) ;NO - STORE CHARACTER
POPJ P, ;RETURN
; Mark EOL in response buffer
;
B$REOL::MOVEI S1,.CHNUL ;GET A <NUL>
IDPB S1,.JBRBP(R) ;END RESPONSE BUFFER
; Reset response buffer byte pointer
;
B$RINI::MOVE S1,[POINT 7,.JBRSP(R)] ;GET POINTER TO START OF BUFFER
MOVEM S1,.JBRBP(R) ;RESET BYTE POINTER
POPJ P, ;RETURN
; Output the response buffer to the log file
;
B$RTYO::TXNN F,FL.SIL ;DON'T ECHO BUFFER IF SILENCE IN EFFECT
$IDENT (BATCH,<^T/.JBRSP(R)/^A>) ;IDENTITY AND ECHO RESPONSE BUFFER
POPJ P, ;RETURN
SUBTTL Batch error handling -- Error, operator, dialogue, or quote checking
; This routine is called only when the first character in a line has been input.
; It will check for an error condition (either "?" or as set by the last ERROR
; command) or an operator signal (either a double quote or as set by the last
; OPERATOR command). In the case of an error, if (nnn) immediately follows the
; error character, nnn is stored in .JBECD(R) for later analysis.
;
B$ECHK::TXNE J,JL.UNE ;IS THE PTY SET TO A NO ECHO STATE?
TXZ F,FL.ECH ;YES - READ WHAT WE THOUGHT WAS ECHO
TXZE F,FL.ECH ;IS THIS CHARACTER ECHO?
POPJ P, ;YES - THEN DON'T DO ANY CHECKING
CAIE S1,"?" ;IS IT THE STANDARD ERROR FLAG?
JRST ECHK.1 ;NO - LOOK FURTHER
TXO R,RL.JIE ;SET JOB IN ERROR BIT
TXNN R,RL.LGI ;LOGGING IN?
TXNE F,FL.UKJ ; OR USER REQUESTED KJOB?
JRST ECHK.1 ;YES - SKIP TIME LIMIT EXCEEDED CHECK
PUSHJ P,GJTIML ;GET THE JOB'S REMAINING TIME LIMIT
JUMPG S2,ECHK.2 ;TIME LIMIT EXCEEDED?
TXOA F,FL.TLE ;YES
ECHK.1: TXNE F,FL.NER ;IS NOERROR IN EFFECT?
JRST ECHK.2 ;YES - CHECK FOR OPERATOR CHARACTER
CAMN S1,.JBECH(R) ;OR USER ERROR CHARACTER ENCOUNTERED
TXO R,RL.JIE ;YES TO EITHER - MARK JOB IN ERROR
ECHK.2: CAMN S1,.JBOCH(R) ;WAS THE OPERATOR CHARACTER SEEN?
TXO R,RL.DIA ;YES - MARK DIALOGUE MODE
CAIN S1,"""" ;Was a quote seen?
TXO R,RL.QTS ;YES - REMEMBER IT
TXNE F,FL.TLE ;WAS TIME LIMIT EXCEEDED?
POPJ P, ;YES - RETURN NOW
TXNE F,FL.NER ;IS NOERROR IN EFFECT?
TXZ R,RL.JIE ;YES - MAKE SURE JOB IN ERROR CLEARED
TXNE R,RL.JIE ;JOB IN ERROR?
TXNN R,RL.LGI ;AND WAS JOB LOGGING IN?
POPJ P, ;NO - JUST RETURN
SKIPE .JBECD(R) ;BEEN HERE BEFORE?
POPJ P, ;YES - THEN JUST RETURN
ECHK.3: PUSHJ P,L$PLOG## ;LOG THE ERROR CHARACTER
PUSHJ P,P$NXTC## ;GET THE NEXT CHARACTER
CAIE S1,"(" ;START OF SPECIAL ERROR CODE?
POPJ P, ;NO - JUST RETURN
ECHK.4: PUSHJ P,L$PLOG## ;LOG THE CHARACTER
PUSHJ P,P$NXTC## ;GET THE NEXT CHARACTER
CAIG S1,"9" ;RANGE CHECK THE DIGIT
CAIGE S1,"0" ;0 THROUGH 9 ALLOWED
POPJ P, ;NOT A DIGIT - EXIT LOOP
MOVE S2,.JBECD(R) ;GET THE ERROR CODE
IMULI S2,^D10 ;SHIFT NUMBER
ADDI S2,-"0"(S1) ;ADD IN THIS DIGIT
MOVEM S2,.JBECD(R) ;REPLACE CODE
JRST ECHK.4 ;LOOP FOR ANOTHER
SUBTTL Batch error handling -- LOGIN error analysis
ANALYZ: TXNE J,JL.ULI ;IS THIS JOB LOGGED IN NOW?
$RETT ;YES - THATS INCONSISTANT
TOPS10 < ;TOPS-10 ONLY
SKIPLE S1,.JBECD(R) ;GET THE ERROR CODE FROM LOGIN
CAILE S1,5 ;WE ONLY KNOW ABOUT 1-5
MOVEI S1,5 ;ASSUME RANDOM ERROR AND REQUEUE JOB
JRST @[ANLY.1 ;(1) CANCEL JOB
ANLY.1 ;(2) CANCEL JOB
ANLY.1 ;(3) CANCEL JOB
ANLY.2 ;(4) REQUEUE JOB AND SHUTDOWN STREAM
ANLY.3]-1(S1) ;(5) REQUEUE JOB
> ;END OF TOPS-10 CONDITIONAL
TOPS20 < ;TOPS-20 ONLY
MOVX S1,EQ.IAS ;GET THE INVALID ACCOUNT BIT
TDNE S1,.JQJBB+JIB.SQ(R) ;DID QUASAR SET IT?
JRST ANLY.1 ;YES - CANCEL THE JOB
JRST ANLY.2 ;NO - REQUEUE THE JOB
> ;END OF TOPS-20 CONDITIONAL
; Cancel job
;
ANLY.1: $IDENT (BATBJC,<? Batch job has been canceled - LOGIN failure>)
$WTO (<Batch error>,<LOGIN failed - job canceled>,.JQOBJ(R),<$WTNOD(.JQLOC(R))>)
TXO F,FL.UHE!FL.TXT ;CALL IT AN UNHANDLED ERROR CONDITION
$TEXT (<-1,,.JWTOP(R)>,<LOGIN failure^0>)
JRST B$ABOR ;ABORT THE JOB
; Requeue job and shutdown stream
;
ANLY.2: $IDENT (BATJRQ,<[Job requeued by BATCON]>)
$WTO (<Batch error>,<Cannot LOGIN jobs - job requeued>,.JQOBJ(R),<$WTNOD(.JQLOC(R))>)
MOVX T1,%RSUNA ;SET UP 'STREAM UNAVAILABLE'
MOVEI T2,E.NJOB ;NO JOBS AVAILABLE CODE
MOVX T3,%SFULL ;SYSTEM FULL
TXO R,RL.SHT ;LITE THE SHUTDOWN AT EOJ BIT
PUSHJ P,SETUPR ;SEND RESPONSE TO QUASAR
JRST B$CLOS ;DISMISS JOB
; Requeue job
;
ANLY.3: $IDENT (BATJRQ,<[Job requeued by BATCON]>)
$WTO (<Batch error>,<Requeue requested by LOGIN>,.JQOBJ(R),<$WTNOD(.JQLOC(R))>)
TXO R,RL.REQ ;MARK JOB AS BEING REQUEUED
MOVEI S1,REQTIM ;GET DEFAULT REQUEUE TIME
STORE S1,.JBRQF(R),RQ.TIM ;SAVE IT
MOVEI T1,%REQUE ;GET REQUEUE CODE
PUSHJ P,B$UPDA ;UPDATE QUASAR
JRST B$CLOS ;DISMISS JOB
SUBTTL MDA interface
; Get an MDA page if we don't already have one (S1:= page address)
;
B$MDAP::SKIPE S1,.JMDAP(R) ;ALREADY HAVE A PAGE?
POPJ P, ;YES - JUST RETURN
$CALL M%GPAG ;GET A PAGE FOR MESSAGE
MOVEM S1,.JMDAP(R) ;STORE PAGE ADDRESS
MOVX S2,.QOPRM ;MESSAGE TYPE IS PRE-MOUNT
STORE S2,.MSTYP(S1),MS.TYP ;STORE IT
MOVX S2,.MMHSZ ;MESSAGE SIZE
STORE S2,.MSTYP(S1),MS.CNT ;STORE IT
LOAD S2,.JQJBB+JIB.ID(R) ;GET REQUEST ID
STORE S2,.OFLAG(S1),PR.RID ;STORE IT
MOVEI S2,.MMHSZ(S1) ;POINT TO EMPTY SLOT
MOVEM S2,.JMDAF(R) ;STORE FIRST FREE POINTER
POPJ P, ;RETURN
; Send any ALLOCATE/MOUNT requests to QUASAR
;
B$MDAR::PUSHJ P,B$MDAP ;GET MDA PAGE IF NECESSADY
MOVX S2,PR.NON ;GET NOTHING IN MESSAGE BIT
SKIPN .MMARC(S1) ;ANYTHING ADDED TO THE BLOCK?
IORM S2,.OFLAG(S1) ;STORE BIT
MOVEM S1,G$SAB+SAB.MS ;STORE PAGE ADDRESS
MOVX S1,PAGSIZ ;GET THE MESSAGE SIZE
STORE S1,G$SAB+SAB.LN ;STORE IT
MOVX S1,SAB.SZ ;GET SAB SIZE
MOVEI S2,G$SAB ;GET SAB ADDRESS
$CALL C%SEND ;SEND MESSAGE TO QUASAR
SKIPT ;MESSAGE SENT OK?
$CALL M%RPAG ;NO - DESTROY THE PAGE
SETZM .JMDAP(R) ;CLEAR PAGE NUMBER
POPJ P, ;RETURN SUCESSFUL
SUBTTL MODIFY interface
; Get a MODIFY page if we don't already have one (S1:= page address)
;
B$MODP::SKIPE S1,.JMODP(R) ;HAVE A MODIFY PAGE YET?
POPJ P, ;YES - RETURN WITH S1 SET UP
$CALL M%GPAG ;GET A PAGE FOR MESSAGE
MOVEM S1,.JMODP(R) ;STORE PAGE ADDRESS
MOVX S2,.QOMOD ;MESSAGE TYPE IS MODIFY QUEUE ENTRY
STORE S2,.MSTYP(S1),MS.TYP ;STORE IT
MOVEI S2,NMAJPM+NINPPM+MOD.SZ ;GET BLOCK LENGTH
STORE S2,.MSTYP(S1),MS.CNT ;STORE IT
MOVX S2,.OTBAT ;OBJECT TYPE
MOVEM S2,MOD.OT(S1) ;STORE IT
LOAD S2,.JQJBB+JIB.ID(R) ;GET REQUEST ID
STORE S2,MOD.RQ+.RDBRQ(S1) ;STORE IT
MOVEI S1,MOD.FG(S1) ;POINT TO FIRST FREE WORD
MOVE S2,[.GPMAJ,,NMAJPM] ;SET UP GROUP MODIFY BLOCK
MOVEM S2,MOD.GN(S1) ;STORE MAJOR MODIFY HEADER
SETOM MOD.GE(S1) ;DEFAULT THE FIRST ENTRY
HRLZI S2,MOD.GE(S1) ;GET SOURCE ADDRESS
HRRI S2,MOD.GE+1(S1) ;GET DESTINATION ADDRESS
BLT S2,MOD.GE+NMAJPM(S1) ;SET THE WHOLE MESS TO -1
ADDI S1,NMAJPM ;POINT TO START OF NEXT BLOCK
MOVE S2,[.GPQUE,,NINPPM] ;SET UP GROUP MODIFY BLOCK
MOVEM S2,MOD.GN(S1) ;STORE QUEUE DEPENDANT MODIFY HEADER
SETOM MOD.GE(S1) ;DEFAULT THE FIRST ENTRY
HRLZI S2,MOD.GE(S1) ;GET SOURCE ADDRESS
HRRI S2,MOD.GE+1(S1) ;GET DESTINATION ADDRESS
BLT S2,MOD.GN+NINPPM-1(S1) ;SET TO -1
MOVE S1,.JMODP(R) ;RELOAD PAGE ADDRESS
POPJ P, ;RETURN
; Send MODIFY request to QUASAR
;
B$MODR::SKIPN S1,.JMODP(R) ;GET MDA REQUEST PAGE
$RETT ;NO MODIFY TO SEND
SKIPN .JMODC(R) ;ANY MODIFIES IN THIS REQUEST?
JRST MODR.1 ;NO
MOVEM S1,G$SAB+SAB.MS ;STORE PAGE ADDRESS
MOVX S1,PAGSIZ ;GET THE MESSAGE SIZE
STORE S1,G$SAB+SAB.LN ;STORE IT
MOVX S1,SAB.SZ ;GET SAB SIZE
MOVEI S2,G$SAB ;GET SAB ADDRESS
$CALL C%SEND ;SEND MESSAGE TO QUASAR
JUMPT MODR.2 ;ANY ERRORS?
$WTO(<BATCON Error>,<MODIFY failed for request ^D/.JQJBB+JIB.ID(R)/>)
MODR.1: MOVE S1,.JMODP(R) ;GET PAGE NUMBER
$CALL M%RPAG ;DESTROY THE PAGE
MODR.2: SETZM .JMODP(R) ;CLEAR SO WE DON'T HAVE PROBLEMS LATER
POPJ P, ;AND RETURN
SUBTTL End of job processing
; Here on end of job (step) header
;
B$EOJ:: TXOE F,FL.EOJ ;PROCESS EOJ STUFF ALREADY?
POPJ P, ;YES - THEN JUST RETURN
TXNN R,RL.JIE ;IS THE JOB IN ERROR?
SETOM .JSSTP(R) ;NO - INDICATE END OF STEP
SKIPN .JBSPS(R) ;DOING ONLY STEP HEADER SCAN?
POPJ P, ;NO - RETURN
PUSHJ P,B$MODR ;PROCESS ANY MODIFY REQUESTS
SKIPE G$MDA ;MDA TURNED ON?
PUSHJ P,B$MDAR ;YES - SEND ANY MDA REQUESTS
POPJ P, ;RETURN
SUBTTL JOBINI - Initialize job processing
JOBINI: TXNE F,FL.KST ;KSYS STREAM?
JRST JOBI.K ;YES
SETOM .JSSPP(R) ;ALLOW US TO PROCESS ONLY 1 STEP
TXZ R,RL.LGI ;CLEAR LOGIN SEQUENCE NOW
SKIPN S1,.JBCRQ(R) ;IS THERE CHKPNT/REQUEUE INFORMATION?
JRST JOBI.1 ;NO - SEE IF RESTARTABLE
TXNN S1,BA.JOB ;BETTER BE SET
JRST JOBI.E ;ELSE WE'RE IN TROUBLE
TXNE S1,BA.ORQ!BA.URQ!BA.CHK ;ANY REQ OR CHKPNT
JRST JOBI.2 ;YES,,CHECK FOR CHECKPOINT RESTART
GETLIM S2,.JQLIM(R),REST ;GET RESTART DATA
CAIE S2,%EQRNO ;IS IT RESTARTABLE
JRST JOBI.2 ;TREAT IT AS RESTARTABLE
;USER MODIFIED AFTER CRASH
; BUT BEFORE RESTART
$IDENT (BATJNR,<? Job canceled after a restart - it is not restartable^A>)
$WTO (<Batch error>,<Job canceled after a restart; it is not restartable>,.JQOBJ(R),<$WTNOD(.JQLOC(R))>)
SETZM .JBCHK(R) ;FORCE A CHECKPOINT
TXO F,FL.LSL ;LIST SKIPPED LINES
PJRST LABFIN## ;FIND %FIN AND CONTINUE FROM THERE
JOBI.1: MOVX S1,<BA.JOB> ;GET SEEN JOB FLAG
IORM S1,.JBCRQ(R) ;UPDATE FLAG WORD
TXO F,FL.CHK ;UPDATE CHECKPOINT
JOBI.2: SETZM .JBCHK(R) ;FORCE A CHECKPOINT
PUSHJ P,C$READ## ;READ A LINE FROM THE CONTROL FILE
JUMPF CLOSJB ;END OF FILE?
CAXE S1,STPCHR ;START OF A STEP?
JRST JOBI.3 ;NO - RESET TO BEGING OF FILE
PUSHJ P,STPPRC ;YES - CALL THE STEP HEADER PROCESSOR
JUMPF CLOSJB ;ERRORS DURING SCAN?
JRST JOBI.4 ;GO SEARCH FOR STARTING POINT
JOBI.3: TXO F,FL.RCL ;RE-EAT THE COMMAND LINE
JOBI.4: PUSHJ P,C$STRT## ;SEARCH FOR STARTING POINT IN CTL FILE
POPJ P, ;RETURN
JOBI.K: $IDENT (BATKSY,<[Beginning KSYS processing]^A>)
POPJ P, ;RETURN
JOBI.E: $IDENT (BATUJR,<? ^I/JOBTXT/>)
$WTOJ (<BATCON error>,<^R/.JQJBB(R)/^I/JOBTXT/>,.JQOBJ(R),<$WTNOD(.JQLOC(R))>)
JRST B$ABORT ;DISMISS THE JOB
JOBTXT: ITEXT (<Unrecognized job restart type ^O/S1/; job canceled>)
SUBTTL TIMERR - Time limit exceeded
; Here on time limit exceeded errors
;
TIMERR::TXON F,FL.%XT ;EXTRA TIME ALREADY GIVEN?
JRST TIME.1 ;NO
$WTO (<Batch error>,<^I/JIBTXT/^I/TIMTX0/>,.JQOBJ(R),<$WTNOD(.JQLOC(R))>)
$IDENT (BATTLE,<? ^I/TIMTX0/>) ;MAKE A LOG ENTRY
TXO F,FL.TXT ;MESSAGE TEXT AVAILABLE
$TEXT (<-1,,.JWTOP(R)>,<Time limit exceeded^0>)
JRST B$ABOR ;ABORT THE JOB
TIME.1: PUSHJ P,C$READ## ;ADVANCE BEYOND LINE CAUSING THE ERROR
PUSHJ P,LABTER## ;SEARCH FOR LABEL %TERR
PUSHJ P,P$STOP## ;YES - PUT JOB IN MONITOR MODE
TXZ R,RL.JIE ;CLEAR ERROR CONDITION
GETLIM S2,.JQLIM(R),TIME ;GET TIME LIMIT
IMULI S2,%EXTRA ;COMPUTE EXTRA TIME TO BE GIVEN
IDIVI S2,^D100 ;AS A PERCENTAGE OF THE ORIGINAL LIMIT
CAIGE S2,%EXTRA ;TOO MUCH?
MOVX S2,%EXTRA ;YES - ADJUST IT
PUSH P,S2 ;SAVE TIME
MOVE S1,S2 ;COPY IT
PUSHJ P,B$STIM ;TRANSLATE TO READABLE TEXT
POP P,S2 ;RESTORE TIME TO SET
TOPS10 < ;TOPS-10 ONLY
MOVX T1,<2,,S1> ;SET UP AC
HRRZ S1,J ;GET THE JOB NUMBER
HRLI S2,.STTLM ;FUNCTION TO SET TIME LIMIT
JBSET. T1, ;SET NEW TIME LIMIT
JRST TIME.E ;CAN'T
JRST TIME.2 ;NO ERRORS
> ;END OF TOPS-10 CONDITIONAL
TOPS20 < ;TOPS-20 ONLY
PUSH P,S2 ;SAVE TIME IN SECONDS
PUSHJ P,B$CINI ;SET UP THE COMMAND BUFFER
$TEXT (B$CPUT,<SET TIME-LIMIT ^D/S2/>) ;ISSUE COMMAND
PUSHJ P,B$SETB ;RESET THE BYTE POINTER
PUSHJ P,B$XFER ;TRANSFER THE LINE TO THE PTY
PUSHJ P,IOWAIT ;WAIT FOR I/O COMPLETION
POP P,S2 ;RESTORE TIME
TXNE R,RL.JIE ;JOB IN ERROR?
JRST TIME.E ;YES
> ;END OF TOPS-20 CONDITIONAL
TIME.2: $WTO (<Batch error>,<^I/JIBTXT/^I/TIMTX2/>,.JQOBJ(R),<$WTNOD(.JQLOC(R))>)
$IDENT (BATAXT,<[^I/TIMTX2/]>) ;MAKE A LOG ENTRY
TXZ F,FL.TLE ;CLEAR TIME LIMIT EXCEEDED CONDITION
TXO F,FL.RCL ;RE-EAT COMMAND LINE
POPJ P, ;RETURN
TIME.E: $WTO (<BATCON error>,<^I/JIBTXT/^T/TIMTX1/>,.JQOBJ(R),<$WTNOD(.JQLOC(R))>)
$IDENT (BATCST,<? ^I/TIMTX1/>) ;MAKE LOG ENTRY
JRST B$ABOR ;ABORT JOB
TIMTX0: ITEXT (<Time limit exceeded after allowing extra time; job canceled>)
TIMTX1: ITEXT (<Cannot set time limit; job canceled>)
TIMTX2: ITEXT (<Time limit exceeded; allowing ^T/G$TMTX/ extra time>)
;HERE WHEN DIALOGUE MODE IS IN EFFECT, READ FROM THE OPERATOR
REDOPR: PUSHJ P,B$WTOR ;WRITE TO OPR AND WAIT FOR RESPONSE
PUSHJ P,B$WRSP ;GET THE OPERATOR RESPONSE
TXNN J,JL.UJA ;IS THE JOB STILL THERE?
JRST B$GONE ;NO
TXNE R,RL.DIA ;JOB STILL WAITING?
JRST REDOPR ;YES - TRY AGAIN
PUSH P,F ;SAVE FLAGS IN CASE THE JOB IS SILENCED
TXZ F,FL.SIL ;CLEAR SILENCE SO LINES WILL GO TO LOG
$IDENT (OPERAT,<Operator response:^A>)
PUSHJ P,B$RTYO ;DUMP THE RESPONSE BUFFER
MOVE S2,[POINT 7,.JWFOP(R)] ;BYTE POINTER TO STRING
SETZ T1, ;CLEAR PREVIOUS CHARACTER SAVER
RDOPR1: ILDB S1,S2 ;GET A CHARACTER
JUMPE S1,RDOPR2 ;DONE IF ENCOUNTER A <NUL>
CAXN S1,.CHLFD ;A LINE FEED?
CAXE T1,.CHCRT ;PREVIOUS CHARACTER A CARRIAGE RETURN?
PUSHJ P,P$OCHR## ;SEND CHARACTER TO THE PTY
MOVE T1,S1 ;SAVE AS PREVIOUS CHARACTER
JRST RDOPR1 ;LOOP FOR ANOTHER
RDOPR2: MOVX S1,.CHCRT ;LOAD A CARRIAGE RETURN
SKIPL .JPEOL(R) ;END OF LINE YET?
PUSHJ P,P$OCHR## ;NO - FORCE ONE
PUSHJ P,P$OBUF## ;SEND THE TEXT TO THE PTY
POP P,S1 ;RESTORE OLD F
TXNE S1,FL.SIL ;WAS SILENCE IN EFFECT?
TXO F,FL.SIL ;YES - SET IT AGAIN
PUSHJ P,P$OBUF## ;OUTPUT THE PTY BUFFER
SETOM .JPEOL(R) ;MARK EOL SENT
TXO F,FL.RCL ;RE-EAT THE COMMAND LINE
POPJ P, ;RETURN
SUBTTL Stream termination -- Dismiss job
; Here to abort the job and update QUASAR
;
B$ABOR::SKIPE .JBSPS(R) ;STEP HEADER SCAN PROCESSING ONLY?
JRST B$CLOS ;YES
MOVEI T1,%CNCLG ;GET CANCEL CODE
PUSHJ P,B$UPDA ;UPDATE QUASAR
JRST B$CLOS ;DISMISS THE JOB
; Here when the job disappears (probably some ATTACHed to it)
;
B$GONE::SKIPN .JBSPS(R) ;STEP HEADER SCAN PROCESSING ONLY?
TXNE R,RL.LGI!RL.KJB ;LOGGING IN OR OUT?
JRST B$CLOS ;THEN IT COULD DISAPPEAR UNEXPECTEDLY
TXNE F,FL.UKJ ;USER REQUEST KJOB?
JRST B$CLOS ;YES
$WTO (<Batch error>,<^I/JIBTXT/^I/GONTXT/>,.JQOBJ(R),<$WTNOD(.JQLOC(R))>)
$IDENT (BATNBC,<% ^I/GONTXT/>) ;LOG IT
JRST B$CLOS ;TERMINATE JOB
GONTXT: ITEXT (<Job ^D/.JBJNO(R)/ no longer under BATCON's control; job canceled>)
; Here to dismiss a job (release or requeue)
;
B$CLOS::
CLOSJB::PUSHJ P,CHKPNT ;CHECKPOINT IF NECESSARY
TXNE R,RL.FKJ ;FAST KJOB?
JRST CLOS.0 ;YES - DON'T TALK TO ANYONE
SKIPE .JOACK(R) ;A PENDING WTOR?
$KWTOR (.JOACK(R)) ;KILL IT
PUSHJ P,B$EOJ ;PROCESS END OF JOB (STEP) HEADER
CLOS.0: TXNN J,JL.UJA ;IS A JOB REALLY THERE?
JRST CLOS.1 ;NO
TXNE R,RL.KJB ;WHAT ARE WE DOING HERE?
JRST CLOS.2 ;DON'T DO ANOTHER KJOB
TXNN R,RL.FKJ ;FAST KJOB?
PUSHJ P,B$DUMP ;NO - SEE IF A CLOSE/DUMP IS NEEDED
PUSHJ P,B$KJOB ;KILL THE JOB
TXNE F,FL.KST ;KSYS STREAM?
TXNN R,RL.JIE ;AND JOB IN ERROR?
SKIPA ;NO TO EITHER
AOS KSYJLE ;COUNT THE ERROR
CLOS.1: TXNE R,RL.REQ ;JOB BEING REQUEUED?
JRST CLOS.2 ;YES - DON'T DELETE CTL FILE
SKIPE .JBSPS(R) ;DOING ONLY STEP HEADER PROCESSING?
JRST CLOS.S ;YES
TXNN R,RL.FLS ;FLUSHING THE JOB?
PUSHJ P,C$DISP## ;DISPOSE OF THE CONTROL FILE (MAYBE)
CLOS.2: PUSHJ P,P$CLOS## ;CLOSE THE PTY
PUSHJ P,C$CLOS## ;CLOSE THE CONTROL FILE
PUSHJ P,L$CLOS## ;CLOSE THE LOG FILE
PUSHJ P,U$CLOS## ;DO ANY SPECIAL POST-KJOB PROCESSING
TXNE R,RL.FKJ ;FAST KJOB?
JRST CLOS.F ;YES - SKIP ALL OTHER STUFF
TXNE R,RL.REQ ;JOB BEING REQUEUED?
JRST CLOS.R ;YES - SEND REQUEUE MESSAGE
PUSHJ P,DELSPL ;DELETE SPOOLED FILES (TOPS-20 ONLY)
PUSHJ P,RELMSG ;BUILD RELEASE MESSAGE
CLOS.5: $WTOJ (<End>,<^R/.JQJBB(R)/>,.JQOBJ(R),<$WTNOD(.JQLOC(R))>)
PUSHJ P,CLRSTR ;CLEAN UP STREAM
TXNE F,FL.KST ;KSYS STREAM?
JRST STEXIT ;YES--DONE
TXNN R,RL.SHT ;SHUTTING DOWN STREAM?
PUSHJ P,B$SEND ;NO - SEND RELEASE MESSAGE TO QUASAR
JRST STEXIT ;EXIT FROM STREAM
CLOS.S: PUSHJ P,C$CLOS## ;CLOSE THE CONTROL FILE
CLOS.F: PUSHJ P,CLRSTR ;CLEAN UP STREAM DATA BASE
JRST STEXIT ;EXIT FROM STREAM
CLOS.R: MOVX S1,REQ.SZ ;REQUEUE MESSAGE SIZE
PUSHJ P,B$SQSR ;SET UP MESSAGE TO QUASAR
MOVE S1,[REQ.SZ,,.QOREQ] ;HEADER WORD
MOVEM S1,.MSTYP(S2) ;SAVE IN MESSAGE
MOVE S1,.JBRQF(R) ;GET REQUEUE FLAG WORD
TXNE S1,RQ.TIM ;SAVE A TIME SET?
TXZA S1,RQ.HBO ;YES - MAKE SURE HOLD BIT OFF
TXO S1,RQ.HBO ;ELSE LITE THE HOLD BIT
MOVEM S1,REQ.FL(S2) ;SAVE IN REQUEUE FLAG WORD
MOVE S1,.JQITN(R) ;THE TASK NAME
MOVEM S1,REQ.IT(S2) ;STORE
HRLI S1,.JBCRQ(R) ;CHECKPOINT/REQUEUE INFORMATION
HRRI S1,REQ.IN(S2) ;INTO THE MESSAGE
BLT S1,REQ.IN+<EQCKSZ-1>(S2) ;MOVE ALL THE WORDS
PUSHJ P,B$SEND ;SEND IT TO QUASAR
$WTOJ (<Requeue>,<^R/.JQJBB(R)/>,.JQOBJ(R),<$WTNOD(.JQLOC(R))>)
PUSHJ P,CLRSTR ;CLEAN UP STREAM
PJRST STEXIT ;EXIT FROM STREAM
SUBTTL Stream termination -- Build release message
; Build release message
;
RELMSG: TXNE F,FL.KST ;KSYS STREAM?
JRST RELM.6 ;YES--SKIP NORMAL RELEASE STUFF
MOVEI S1,REL.FD ;GET MINIMUM RELEASE MESSAGE
PUSHJ P,B$SQSR ;SET UP MESSAGE TO QUASAR
MOVX S1,<INSVL.(REL.FD,MS.CNT)!INSVL.(.QOREL,MS.TYP)>
MOVEM S1,.MSTYP(S2) ;STORE LENGTH AND TYPE
MOVE S1,.JQITN(R) ;GET ITN
MOVEM S1,REL.IT(S2) ;STORE IT
MOVEI S1,0 ;CLEAR FLAG BITS
TXNE F,FL.UHE ;UNHANDLED ERROR?
TXO S1,RF.ABO ;YES--LIGHT ABORTED BIT
MOVEM S1,REL.FL(S2) ;STORE FLAGS
TXNN F,FL.TXT ;COPY .JWTOP TEXT?
JRST RELM.3 ;NO
MOVE S1,[POINT 7,.JWTOP(R)] ;YES--SETUP INITIAL POINTER
MOVE T1,[POINT 7,REL.TX(S2)] ;AND DESTINATION
REML.1: ILDB T2,S1 ;GET A CHAR
CAIE T2,.CHLFD ;STOP ON <LF>
CAIN T2,.CHCRT ;STOP ON <CR>
JRST RELM.2 ;YES
JUMPE T2,RELM.2 ;OR NULL
IDPB T2,T1 ;STORE
JRST REML.1 ;LOOP FOR ALL
RELM.2: MOVEI T2,.CHNUL ;GET A NULL
IDPB T2,T1 ;STORE
RELM.3: SKIPG S1,.JBJNO(R) ;GET THE JOB NUMBER
MOVEI S1,0 ;JOB WAS NEVER LOGGED IN
MOVE T1,.JQLFP+.FPINF(R) ;GET THE LOG FILE BITS
TXNE T1,FP.DEL ;DELETE IT?
TXO S1,RL.DLG ;YES
TXNE T1,FP.SPL ;WAS IT SPOOLED?
TXO S1,RL.SPL!RL.DLG ;YES
MOVEM S1,REL.BJ(S2) ;STORE FLAGS AND JOB NUMBER
RELM.4: GETLIM S1,.JQLIM(R),OUTP ;GET /OUTPUT VALUE
TXNN R,RL.FLS ;FLUSHING THE JOB?
CAIN S1,%EQONL ;OR WAS IT /OUTPUT:NOLOG
JRST RELM.7 ;YES TO EITHER - DON'T QUEUE LOG
TXNE F,FL.UHE ;WAS THERE AN UNHANDLED ERROR?
CAIE S1,%EQOLE ;AND /OUTPUT:ERROR SPECIFIED?
CAIN S1,%EQOLG ;NO TO ERROR STUFF, WAS IT /OUTPUT:LOG?
JRST RELM.5 ;YES TO ONE OF THOSE - QUEUE LOG FILE
JRST RELM.7 ;DON'T QUEUE LOG IF WE GET THIS FAR
RELM.5: TXNE F,FL.NUL ;LOG FILE WRITTEN TO NUL:?
POPJ P, ;YES - THEN ALL DONE
HRLI S1,.JQLFD(R) ;GET LOG FILE FD ADDRESS
HRRI S1,REL.FD(S2) ;GET DESTINATION ADDRESS
LOAD T1,.JQLFD+.FDLEN(R),FD.LEN ;GET FD LENGTH
LOAD T2,.MSTYP(S2),MS.CNT ;GET MESSAGE LENGTH
ADD T2,T1 ;COMPUTE NEW LENGTH
STORE T2,.MSTYP(S2),MS.CNT ;STORE IT
ADDI T1,-1(S1) ;COMPUTE END ADDRESS OF BLT
BLT S1,0(T1) ;COPY LOG FILE FD
POPJ P, ;RETURN
RELM.6: TXNE R,RL.JIE ;JOB IN ERROR?
PJRST KSYQUE ;YES--QUEUE UP LOG FILE /DISP:DEL
JRST RELM.8 ;ELSE DELETE IT
RELM.7: MOVX S1,RL.SPL!RL.DLG ;GET SPOOLED AND DELETE LOG FILE BIT
TDNE S1,REL.BJ(S2) ;DID WE SET IT?
RELM.8: PUSHJ P,L$DLET## ;YES - DELETE THE LOG FILE
POPJ P, ;RETURN
SUBTTL Stream termination -- Data base cleanup
; This routine is called only from CLOSJB
;
CLRSTR: TXNN F,FL.KST ;KSYS STREAM?
JRST CLRS.1 ;NO
MOVE S1,KSYSSC ;GET COUNT OF STREAMS SETUP
SOS S2,KSYUSE ;COUNT DOWN KSYS STREAMS IN USE
SUBI S1,(S2) ;COMPUTE STREAMS FREE NOW
CAMLE S1,KSYCNT ;ENOUGH LEFT TO HANDLE THE OVERFLOW?
TXO R,RL.SHT ;YES--SHUT DOWN THIS STREAM
JUMPN S2,CLRS.1 ;SHUTTING DOWN LAST KSYS STREAM?
PUSHJ P,KSYFIN ;YES--TELL THE OPERATOR WE'VE FINISHED
CLRS.1: MOVE S1,[IOWD TPSIZE,G$PDL] ;GET TOP LEVEL PDL FIRST
PUSH S1,(P) ;PLACE RETURN ADDRESS ON STACK
MOVE P,S1 ;GET NEW STACK POINTER
SOS G$SACT ;DECREMENT THE STREAM COUNT
CAMN S,G$HACT ;WAS STREAM THE HIGHEST ACTIVE
PUSHJ P,FHIACT ;YES, FIND NEW G$HACT
SKIPE S1,.JMDAP(R) ;GET MDA PAGE (IF ANY)
$CALL M%RPAG ;RELEASE IT
SKIPE S1,.JMODP(R) ;GET MODIFY PAGE (IF ANY)
$CALL M%RPAG ;RELEASE IT
MOVEI S1,1 ;1 PAGE
MOVE S2,.JSCMD(R) ;GET ADDRESS OF COMMAND PARSE PAGE
ADR2PG S2 ;CONVERT TO PAGE NUMBER
SKIPE S2 ;MAKE SURE WE REALLY HAD IT
$CALL M%RLNP ;RELEASE IT
TXNE R,RL.SHT ;SHUTTING DOWN STREAM?
PJRST SHUT.1 ;YES - DO IT NOW
TLZ R,777777 ;CLEAR INITIAL SETTINGS
MOVEM R,G$BASE(S) ;UPDATE STREAM RELOCATION AND FLAGS
POPJ P, ;RETURN
SUBTTL Time text generation
; Convert time to ASCIZ text
; Call: MOVE S1, time
; PUSHJ P,B$MTIM ;TIME IN MILLISECONDS
; PUSHJ P,B$STIM ;TIME IN SECONDS
;
; On return, G$TMTX:= contains the ASCIZ time text
;
B$MTIM::IDIVI S1,^D1000 ;CONVERT TO SECONDS
B$STIM::$SAVE <P1,P2,P3> ;SAVE SOME ACS
MOVE P1,S1 ;GET TIME IN MILLISECONDS
IDIVI P1,^D3600 ;P1:= HOURS
IDIVI P2,^D60 ;P2:= MINUTES, P3:= SECONDS
$TEXT (<-1,,G$TMTX>,<^D/P1/:^D2R0/P2/:^D2R0/P3/^0>) ;HH:MM:SS
POPJ P, ;RETURN
SUBTTL IOWAIT - Wait for I/O completion
IOWAIT::PUSHJ P,P$STAT## ;GET THE JOB STATUS
TXNE J,JL.UOA ;OUTPUT AVAILABLE?
JRST IOWA.2 ;YES
TXNE J,JL.UDI!JL.UHI ;PTY READY FOR MORE INPUT?
JRST IOWA.3 ;YES
IOWA.1: PUSHJ P,QTS ;WAIT FOR SOME PTY ACTIVITY
JRST IOWAIT ;TRY AGAIN
IOWA.2: PUSHJ P,P$READ## ;READ A LINE FROM THE PTY
JRST IOWAIT ;GO CHECK STATUS
IOWA.3: TXNE F,FL.SIL ;BATCH JOB SILENCED?
SETOM .JLTIM(R) ;YES - KEEP OUTPUT ALIGNED
SKIPE .JBCLK(R) ;CLOCK/EVENT REQUEST PENDING?
JRST IOWA.1 ;YES - WAIT A WHILE
POPJ P, ;RETURN
SUBTTL Random Little Routines
; Get job's remaining time limit
;
GJTIML:
TOPS10 < ;TOPS-10 ONLY
HRLZ S2,.JBJNO(R) ;GET THE JOB NUMBER
HRRI S2,.GTLIM ;AND THE BATCH LIMIT TABLE
GETTAB S2, ;READ THE JOB'S LIMIT WORD
MOVX S2,-1 ;CAN'T - GIVE THE GUY A BREAK
ANDX S2,JB.LTM ;KEEP ONLY THE TIME LIMIT
POPJ P, ;RETURN
> ;END OF TOPS-10 CONDITIONAL
TOPS20 < ;TOPS-20 ONLY
PUSH P,S1 ;SAVE S1
PUSH P,T1 ;AND T1
MOVE S1,.JBJNO(R) ;GET THE JOB NUMBER
MOVX S2,<-1,,T1> ;RETURN 1 WORD IN S2
MOVX T1,.JIRTL ;FUNCTION CODE
GETJI ;READ THE JOB'S TIME LIMIT
MOVX S2,-1 ;GIVE THE GUY A BREAK
MOVE S2,T1 ;GET TIME LIMIT
POP P,T1 ;RESTORE T1
POP P,S1 ;AND S1
POPJ P, ;RETURN
> ;END OF TOPS-20 CONDITIONAL
; Set job location on TOPS-20
;
TOPS20 <
SETLOC: MOVE S1,.JQLOC(R) ;GET THE OUTPUT NODE
CAMN S1,G$NODE ;IS IT SAME AS MINE?
POPJ P, ;YES..JUST RETURN
SETZB T3,T4 ;CLEAR T3 AND T4
MOVE T1,[POINT 6,.JQLOC(R)] ;GET THE LOCATION
MOVE T2,[POINT 7,T3] ;PLACE TO STORE STRING
MOVEI P1,6 ;MAXIMUM LENGTH
SETL.1: ILDB S2,T1 ;GET A BYTE
JUMPE S2,SETL.2 ;O.K. SET THE LOCATION
ADDI S2,40 ;CONVERT TO ASCII CHARACTER
IDPB S2,T2 ;SAVE THE BYTE
SOJG P1,SETL.1 ;CHECK NUMBER OF CHARACTERS
SETL.2: MOVE S1,.JBJNO(R) ;GET THE JOB NUMBER
MOVX S2,.SJLLO ;SETUP LOCATION
HRROI T1,T3 ;GET STRING
SETJB ;SET IT UP
ERJMP .+1 ;IGNORE ERROR FOR NOW
POPJ P, ;RETURN
>;END TOPS20
SUBTTL DELSPL - Delete spooled input files
; This routine is not needed for TOPS-10. For TOPS-20, files named
; DSK:<SPOOL>CDR-xxx.CDyyy.* are deleted. "xxx" is the user's directory
; and "yyyy" is a string maje of the job name concatenated with 4 random
; characters currently passed by SPRINT in .JQSIS(R).
;
; *** Note ***
; The call to DELSPL must follow the call to C$CLOS in CLOSJB since it uses
; .JQCFD(R) for deleting spooled files.
;
DELSPL:
TOPS10 <POPJ P,> ;NOT NEEDED FOR TOPS-10
TOPS20 < ;TOPS-20 ONLY
SKIPN .JQSIS(R) ;IS THERE A SPOOLED INPUT NAME?
POPJ P, ;NO, JUST RETURN
$TEXT (<-1,,.JQCFD(R)>,<PS:[SPOOL]CDR-^O/.JQJBB+JIB.US(R),RHMASK/.^W/.JQSIS(R)/.*^0>)
MOVX S1,GJ%OLD!GJ%IFG!GJ%SHT ;LOAD GTJFN BITS
HRROI S2,.JQCFD(R) ;POINT TO FILE-NAME
GTJFN ;GET A JFN
POPJ P, ;FAILED, RETURN
MOVE T1,S1 ;SAVE THE JFN
JRST DELS.2 ;JUMP INTO THE LOOP
DELS.1: GNJFN ;GET THE NEXT FILE
JRST DELS.3 ;DONE EXPUNGE THE AREA
DELS.2: TLZ S1,-1 ;CLEAR LEFT HALF OF JFN WORD
TXO S1,DF%NRJ ;DONT RELEASE THE JFN
DELF ;DELETE THE FILE
JFCL ;IGNORE THE ERROR
MOVE S1,T1 ;RELOAD INDEXABLE JFN
JRST DELS.1 ;GET THE NEXT ONE
DELS.3: MOVEI S1,0 ;NO SPECIAL FLAGS
MOVE S2,G$SPLD ;GET DIRECTORY NUMBER OF PS:[SPOOL]
DELDF ;EXPUNGE IT
ERJMP .+1 ;IGNORE ERROR..
POPJ P, ;AND RETURN
> ;END OF TOPS-20 CONDITIONAL
SUBTTL LUUO handler
UUOCON: PUSH P,S1 ;SAVE S1
LDB S1,[POINT 9,.JBUUO##,8] ;GET OPCODE
CAXLE S1,UUOMAX ;RANGE CHECK IT
STOPCD (IBU,HALT,,<Illegal BATCON UUO>)
PUSHJ P,@UUOTAB-1(S1) ;DISPATCH
POP P,S1 ;RESTORE S1
POPJ P, ;RETURN
; UUO dispatch table
;
UUOTAB: IDENTX ;IDENTIFY A LOG FILE LINE
IDHDRX ;IDENTIFY A LOG FILE HEADER LINE
UUOMAX==.-UUOTAB ;NUMBER OF KNOWN UUOS
; Identify a log file line
;
IDENTX: SKIPN .JLTIM(R) ;NEED TO END THE PREVIOUS LINE?
PUSHJ P,L$CRLF## ;YES - SEND A CRLF TO THE LOG
SETZM .JLTIM(R) ;CLEAR TIME STAMP NEEDED FLAG
MOVE S1,-1(P) ;GET SAVED AC CONTENTS
$TEXT (L$PLOG##,<^T/G$TIME/^I/@.JBUUO/>) ;OUTPUT LINE IDENTIFIER
POPJ P, ;RETURN
; Identify a log file header line
;
IDHDRX: MOVE S1,-1(P) ;GET SAVED AC CONTENTS
$TEXT (L$PHDR##,<^T/G$TIME/^I/@.JBUUO/>) ;OUTPUT LINE IDENTIFIER
POPJ P, ;RETURN
SUBTTL PTY interrupt handler
; This seemingly useless routine will actually make the TOPS-20 DISMS JSYS
; act in a reasonable manor when a PTY interrupt is received during the sleep.
; The problem is that the DISMS JSYS doesn't get terminated when an interrupt
; is received.
;
TOPS20 < ;TOPS-20 ONLY
PTYINT: $BGINT PTYLVL ;SWITCH TO PTY INTERRUPT LEVEL
$DEBRK ;RETURN FROM INTERRUPT
> ;END OF TOPS-20 CONDITIONAL
SUBTTL ERRTAB EXPAND ERROR TABLE VALUES
DEFINE X(A,B),< EXP [ITEXT (<B>)]>
ERRTAB: MSGBLD ;BUILD MESSAGE TABLE
SUBTTL Literals
LIT
SUBTTL End
END BATCON ;A GOOD PLACE TO START