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. ; 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 > TOPS20 > GLOB LOC <.JBVER==:137> EXP %%.BAT ;BATCON VERSION NUMBER RELOC 0 COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1971,1986. 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 ; Local data ; WTOCNT: BLOCK 1 ;WTO BYTE COUNTER WTOPTR: BLOCK 1 ;WTO BYTE POINTER MAX 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 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 ;TOPS-10 PSI INTERRUPT VECTOR ADDRESS TOPS20 ;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, ;IPCF QUOTAS MOVEM S1,G$PIB+PB.SYS ;STORE THEM TOPS10 ;TOPS-10 IPCF PSI VECTOR TOPS20 ;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 ;RETURN TOPS20 ;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: MOVEI S1,IZTIME ;GET INACTIVE SLEEP TIME MAXIMUM SKIPE G$SACT ;ANY ACTIVE STREAMS? MOVEI S1,AZTIME ;USE 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 ;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 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, ;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+(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 ()] ;DEFAULT SKIPG S2,.JBJNO(R) ;GET JOB NUMBER (IF ANY) MOVEI S1,[ITEXT ()] 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 ;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 ;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 (,,.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 (,,,<$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 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, MOVEM S1,.MSTYP(S2) ;STORE MESSAGE TYPE AND SIZE MOVE S1,['BATCON'] ;GET OUR NAME MOVEM S1,HEL.NM(S2) ;STORE IT MOVX S1, ;GET QUASAR VERSION NUMBER SKIPN T1 ;WHAT ARE WE DOING? TXO S1,HEFBYE ;SIGNING OFF MOVEM S1,HEL.FL(S2) ;STORE IT MOVX S1, 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), MSGTAB::$MSG NUMMSG==.-MSGTAB DEFINE $ (TYPE,SUBR,OBJ), MSGPRC::$MSG DEFINE $ (TYPE,SUBR,OBJ), MSGOBJ::$MSG SUBTTL IPCF/Operator/QUASAR interface -- Validate messages ; Validate IPCF messages ; Call: PUSHJ P,VALMSG ; ;ILLEGAL MESSAGE ; ;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 (,) 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 ; ;MESSAGE PENDING ; ;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 HRLZ S1,G$MADR ;GET MESSAGE ADDRESS HRRI S1,.JOMSG(R) ;PUT IT THERE MOVE S2,G$MADR ;GET MESSAGE ADDRESS LOAD S2,.MSTYP(S2),MS.CNT ;GET MESSAGE LENGTH 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 ;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 ; ;END OF MESSAGE ; ;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,> ;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 $STOP (SQF,) ; 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 (,<^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 (,,.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 (,<^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,) 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)>,) 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 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 POPJ P, ;AND RETURN ; Here on SETUP failure ; SETUPF: $WTO (,<^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 (,,.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 ;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 ; ;NONE AVAILABLE RIGHT NOW ; ;STREAM SETUP KSYSET: $SAVE ;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 (,,.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 ;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 (,<^I/KSYQTX/>,.JQOBJ(R),<$WTNOD(.JQLOC(R))>) POPJ P, ;AND RETURN KSYQTX: ITEXT () > ;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 (,,<.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 (,<^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 (,,<.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 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 (,,<.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,+1 ;WILL IT FIT IN THE BUFFER? MOVEI S2,+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 (,,<.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, ;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 (,,<.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,) 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)>,) 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 (,,<.JQOBJ(R)>,.MSCOD(P1)) POPJ P, ;RETURN SEND.E: $ACK (,,<.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: PJRST C$RPOS## ;RESPOSITION THE CTL FILE EXAME1: $TEXT (WTODAT,) 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,) JRST EXAM.2 ;FINISH OFF THE COMMAND EXAMAC: $ACK (,<^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(,) 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,) ; 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,) 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 (,<^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 TXNN F,FL.KST ;KSYS STREAM? JRST HONORJ ;ENTER JOB PROCESSING LOOP PJRST B$CLOS ;YES--TERMINATE NOW FILTX1: ITEXT () FILTX2: ITEXT () ; 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, ; 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: 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, ;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, ;VECTOR OFFSET MOVSI T3,IPCLVL ;GET IPCF PRIORITY LEVEL MOVX S1,PS.FAC+T1 ;FUNCTION CODE TO ADD THE CONDITION PISYS. S1, ;ADD IT $STOP (CEI,) ;++ 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, ;GET INTERRUPT LEVEL FOR IPCF MOVEM S1,CHNTAB+IPCCHN ;SET UP CHANNEL MOVX S1, ;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+(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 CAXE S1,.CHCRT ;A CARRIAGE RETURN? JRST XFER.1 ;NOPE TXO F,FL.CTP ;REMEMBER A SEEN TXZN F,FL.SUP ;SUPRESS EOL CHARACTERS? JRST XFER.1 ;NO TO EITHER ILDB S1,.JSCTB(R) ;EAT THE LINE FEED FOLLOWING XFER.1: CAXE S1,.CHLFD ;END OF LINE? JRST XFER.2 ;YES - IGNORE 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,) ;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,) ;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,) $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,) $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,) GETLIM T1,.JQLIM(R),CORE ;GET CORE LIMIT SKIPE G$CORE ;CHECKING CORE LIMITS? $TEXT (LGNCHR,) GETLIM T1,.JQLIM(R),TIME ;GET TIME LIMIT $TEXT (LGNCHR,) 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 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,) 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,) 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,) $WTOJ (,<^R/.JQJBB(R)/^I/LGNTXT/>,.JQOBJ(R),<$WTNOD(.JQLOC(R))>) JRST B$ABORT ;DISMISS THE JOB LGNTXT: ITEXT () ; 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,) 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 () LGOTXT: ITEXT () LGOTAB: $STAB KEYTAB (0,) $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##,) ;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 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 (,<^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 (,<^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+(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 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 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,) $WTO (,,.JQOBJ(R),<$WTNOD(.JQLOC(R))>) TXO F,FL.UHE!FL.TXT ;CALL IT AN UNHANDLED ERROR CONDITION $TEXT (<-1,,.JWTOP(R)>,) JRST B$ABOR ;ABORT THE JOB ; Requeue job and shutdown stream ; ANLY.2: $IDENT (BATJRQ,<[Job requeued by BATCON]>) $WTO (,,.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 (,,.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(,) 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,) $WTO (,,.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, ;GET SEEN JOB FLAG IORM S1,.JBCRQ(R) ;UPDATE FLAG WORD GETLIM S2,.JQLIM(R),REST ;GET RESTART DATA CAIE S2,%EQRNO ;IS IT RESTARTABLE JRST JOBI.2 ;YES, GO GET STARTING POINT 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,) $WTOJ (,<^R/.JQJBB(R)/^I/JOBTXT/>,.JQOBJ(R),<$WTNOD(.JQLOC(R))>) JRST B$ABORT ;DISMISS THE JOB JOBTXT: ITEXT () 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 (,<^I/JIBTXT/^I/TIMTX0/>,.JQOBJ(R),<$WTNOD(.JQLOC(R))>) $IDENT (BATTLE,) ;MAKE A LOG ENTRY TXO F,FL.TXT ;MESSAGE TEXT AVAILABLE $TEXT (<-1,,.JWTOP(R)>,