; JINIT - Job Initiation and Termination for VTAM ; ; Copyright [c] Noel Alaska Systems Technology, 1983. SEARCH SYS ; AMOSL libraries SEARCH SYSSYM SEARCH TRM SEARCH VTAMEQ ; VTAM library INTERN DRAINO,JAUTO,JINIT,JTERM,JTXXXX,JTOG,JATT,JDET AUTOEXTERN ; routine to try to acquire any available job JAUTO: SAVE A0-A5,D0-D5 ; save regs BISL #AUTO,JSTAT(A4) ; attempt auto-acquire MOV JCUR(A4),A5 ; if there is a current job PUSH A5 ; make it un-current MOV A5,D7 BEQ 0$ BICL #CUR,JSTAT(A5) CLR JCUR(A4) 0$: MOV @A4,A5 ; prime chain (and dissallow job #1) 1$: MOV @A5,D7 ; next job MOV D7,A5 BEQ JAUTO3 ; end of chain BITL #VALLOC,JSTAT(A5) ; available for auto-acquire? BEQ 1$ ; NO CALL JINIT ; YES - try to get it TST JCUR(A4) ; did we get it? BEQ 1$ ; NO JAUTO3: BICL #AUTO,JSTAT(A4) ; reset auto-acquire flag POP A3 ; recover old current pointer TST JCUR(A4) ; did we get a job? BNE 1$ ; YES - return MOV A3,D7 ; was there a current before? BEQ 0$ ; NO - show problem MOV A3,JCUR(A4) ; YES - make it current again BISL #CUR,JSTAT(A3) 0$: JMP HELP6 ; show unable to get one... 1$: REST A0-A5,D0-D5 RTN ; routine to acquire a job based on the name pointed to by A2 JINIT: SAVE A0-A5,D0-D5 ; save regs BITL #AUTO,JSTAT(A4) ; is this auto-acquire? BNE JIA ; YES MOVB #3,JDDB+D.FLG(A4) ; FIXUP DDB FSPEC JDDB(A4),M68 ; get job name CALL JOBSRH ; find it MOV A5,D7 ; found? JEQ HELP0 ; NO JIA: CMP A5,JME(A4) ; is he trying to talk to himself? JEQ HELP1 ; YES - pretend not found BITL #VACT,JSTAT(A5) ; this job in use by me already? BEQ JIA2 ; NO - drive on CMP JJNM(A5),#1 ; is he trying to get job #1 ? JEQ HELP7 ; YES - blow him away BITL #AUTO,JSTAT(A4) ; this an auto-acquire? JEQ JINIT2 ; NO - just make current JMP HELP99 ; YES - bypass this job in search JIA2: VLOK ; freeze out other guys MOV JJCB(A5),A3 ; get JCB addr MOV JOBTRM(A3),A3 ; get TRMDEF addr MOV A3,D7 JEQ HELP2 ; quit if none MOV A3,JTRM(A5) ; else save it MOV T.TDV(A3),JTDV(A5) ; save TDV addr too MOV T.IDV(A3),A2 MOV A2,JIDV(A5) ; save IDV address ; CMP A2,VIDV(A4) ; is it the one he'll get anyway? ; BEQ 0$ ; YES - always ok ; TST @A2 ; is this interrupt-driven IDV? ; JEQ HELP8 ; NO - blow him away 0$: MOV QBAS(A4),A3 ; point to HPO queue 1$: MOV @A3,D7 ; get next on it BEQ 6$ ; quit if end found MOV D7,A3 BITL #QBCTLD,QBFLG(A3) ; is this a controlled job? BEQ 2$ ; NO - check for VGUARD CMM QBJCB(A3),JJCB(A5) ; YES - correct job? JEQ HELP3 ; YES - abort BR 1$ 2$: BITL #QBGARD,QBFLG(A3) ; is this a VGUARD? BEQ 1$ ; NO - continue thru CMM QBJCB(A3),JJCB(A5) ; YES - correct job? BNE 1$ ; NO - continue thru CMM QBCJCB(A3),JJCB(A4) ; YES - for me perhaps? JNE HELP5 ; NO - abort BR 7$ ; YES - use that one 6$: MOV QBAS(A4),A3 ; point back to queue start QADD A3 ; put another block on chain SUB #4,A3 ; adjust pointer 7$: MOV A3,JQUE(A5) ; save pointer MOV JJCB(A5),QBJCB(A3) ; store jobs JCB addr MOV JJCB(A4),QBCJCB(A3) ; store my JCB addr MOV JTRM(A5),A2 MOV A2,QBTRM(A3) ; store jobs TRM addr MOV VTDV(A4),T.TDV(A2) ; he gets VTAM.TDV (new fmt) MOV VIDV(A4),T.IDV(A2) ; he gets PSEUDO.IDV MOV #QBCTLD,QBFLG(A3) ; note controlled job entry CLR JDDB(A5) ; say no LOG file open CLR VSCR(A5) ; say no virtual screen BISL #VACT,JSTAT(A5) ; make him known as active CLR JVCNT(A5) ; zero count of pending ctl chars PUSH A5 ; save A5 MOV A2,A5 ; set "offical" TRMDEF pointer CALL DRAINO ; clean out the TRMDEF POP A5 ; restore A5 VUNLK CALL FORUPD ; force intensity change BISL #RUNON,JSTAT(A5) ; he gets RUNON option MOV RMAX(A4),D6 ; figure out how much storage MOV CMAX(A4),D7 ; a virtual crt will get MUL D6,D7 ADD CMAX(A4),D6 ADD D6,D6 ADD #1000.,D6 ; that plus 1000 bytes CMP D6,DFMEM(A4) ; is there more than that? BHI JINIT2 ; NO - don't try for VCRT CALL ALLCON ; YES - get VCRT for him JINIT2: VUNLK MOV JCUR(A4),D7 ; see who is current job BEQ 1$ ; NONE MOV D7,A3 BICL #CUR,JSTAT(A3) ; make old job not current 1$: BISL #CUR,JSTAT(A5) ; make this job current MOV A5,JCUR(A4) REST A0-A5,D0-D5 RTN ; routine to un-acquire a job whose name is pointed to by A2 JTERM: SAVE A0-A5,D0-D5 ; save regs MOVB #3,JDDB+D.FLG(A4) ; FIXUP DDB FSPEC JDDB(A4),M68 ; get job name CALL JOBSRH ; find it MOV A5,D7 ; found? JEQ HELP0 ; NO BR JTX ; YES JTXXXX: SAVE A0-A5,D0-D5 ; ENTRY POINT FOR 'QUIT' COMMAND JTX: CMP A5,JME(A4) ; is he trying to term himself? JEQ HELP1 ; YES - pretend not found BITL #VACT,JSTAT(A5) ; this job in use by me? JEQ HELP4 ; NO CALL CLOLOG ; close log (if open CALL RELCON ; release virtual screen (if alloc. VLOK ; clean out pending I/O PUSH A5 MOV JTRM(A5),A5 CALL DRAINO POP A5 MOV JTRM(A5),A2 ; get TRMDEF pointer MOV JTDV(A5),T.TDV(A2) ; restore TDV addr MOV JIDV(A5),T.IDV(A2) ; IDV addr 1$: MOV JQUE(A5),A3 BICL #QBCTLD,QBFLG(A3) ; say not in use BITL #QBGARD,QBFLG(A3) ; is it vguarded? BNE JTERM3 ; YES - do not free block MOV QBAS(A4),A0 ; NO - release queue block CALL QDEL QRET A3 MOV QBAS(A4),A3 ; now try to tell BATRUN job avail 2$: MOV @A3,A3 ; point to next queue block MOV A3,D7 BEQ JTERM3 ; no biggy if not found BITL #QBBAT,QBFLG(A3) ; is this BATRUN? BEQ 2$ ; NO BISL #QBSUBW,QBFLG(A3) ; YES - say SUBMIT update BICL #QBSUPR,QBFLG(A3) ; - let next tick kick off COM QBUPDT(A3) JTERM3: VUNLK ; unfreeze BICL #VACT,JSTAT(A5) ; make him inactive... CMP A5,JCUR(A4) ; was this job the current one? BNE 1$ ; NO CALL JTOG ; YES - try for new current 1$: CALL FORUPD ; force status screen update REST A0-A5,D0-D5 RTN ; routine to toggle 'current' job JTOG: SAVE A0-A5,D0-D5 ; save regs MOV JCUR(A4),A5 ; start with current 'current' MOV A5,D7 BEQ 2$ ; (unless none) BICL #CUR,JSTAT(A5) ; make not 'current' 0$: MOV @A5,A5 ; chain to next job MOV A5,D7 BEQ 2$ ; (unless end) BITL #VACT,JSTAT(A5) ; this job active? BEQ 0$ ; NO 1$: MOV A5,JCUR(A4) ; make this job new 'current' BISL #CUR,JSTAT(A5) REST A0-A5,D0-D5 RTN ; restore regs and return 2$: MOV A4,A5 ; try looking at top of chain 3$: MOV @A5,A5 ; chain to next job MOV A5,D7 BEQ 4$ ; (unless end) BITL #VACT,JSTAT(A5) ; this job active? BEQ 3$ ; NO BR 1$ ; YES - make new 'current' 4$: CLR JCUR(A4) ; no eligible job found... REST A0-A5,D0-D5 RTN ; routine to re-attach VTAM to real terminal... JATT: SAVE A0-A5,D0-D5 ; save regs MOV JJCB(A4),A0 ; index my JCB MOV JOBTRM(A0),JTRM(A4) ; index my TRMDEF BNE 1$ REST A0-A5,D0-D5 RTN 1$: BICL #DETACH,JSTAT(A4) ; reset 'detached' bit MOV JTRM(A4),A5 ; index my TRMDEF w/A5 VLOK ; lock out interrupts BISW #T$IMI!T$DAT!T$ECS!T$ILC,@A5 ; set DATA MODE CALL DRAINO ; sanitize termianl MOV JQUE(A4),A3 ; point to hpo entry MOV JTRM(A4),QBTRM(A3) ; attach' terminal VUNLK ; allow interrupts again BISL #CTLMOD,JSTAT(A4) ; go to control mode BICL #INHELP,JSTAT(A4) ; not in help REST A0-A5,D0-D5 CALL VSTATI ; put up status screen CALL VCMD0 ; init command line RTN ; routine to detach VTAM from real terminal... JDET: SAVE A0-A5,D0-D5 ; save regs MOVB #3,JDDB+D.FLG(A4) ; FIXUP DDB FSPEC JDDB(A4),M68 ; get job name CALL JOBSRH ; find it MOV A5,D7 ; found? JEQ HELP0 ; NO - msg VLOK ; no interrupts now CMP A5,JME(A4) ; is he trying to attach to himself? JEQ HELP1 ; YES - msg MOV QBAS(A4),A3 ; point to HPO queue 1$: MOV @A3,D7 ; get next on it BEQ 2$ ; quit if end found MOV D7,A3 BITL #QBCTLD,QBFLG(A3) ; is this a controlled job? BEQ 1$ ; NO - continue thru CMM QBJCB(A3),JJCB(A5) ; YES - correct job? JEQ HELP3 ; YES - abort BR 1$ 2$: MOV JJCB(A5),A3 ; get JCB addr MOV JOBTRM(A3),A3 ; get TRMDEF addr MOV A3,D7 BEQ 3$ ; ok if none CLR T.JLK(A3) ; detach that terminal MOV JJCB(A5),A3 CLR JOBTRM(A3) 3$: VUNLK ; allow interrupts CRT 255.,0 ; clear screen CRT 255.,12. ; hi intensity MOV JTRM(A4),A0 ; wait for output to finish 4$: SLEEP #2 BITW #T$OIP,@A0 BNE 4$ TST T.OQX(A0) BNE 4$ VLOK ; no interrupts again PUSH A5 ; save pointer MOV A0,A5 ; index trmdef w/A5 CALL DRAINO ; sanitize terminal POP A5 ; recover pointer MOV JJCB(A5),A1 ; get JCB pointer MOV A0,JOBTRM(A1) ; attach terminal MOV A1,T.JLK(A0) BICW #177,@A0 ; reset wierd status bits MOV JJCB(A4),A1 ; VTAM has no terminal CLR JOBTRM(A1) CLR JTRM(A4) MOV JQUE(A4),A3 ; point to HPO entry CLR QBTRM(A3) ; YES - 'detach' terminal VUNLK ; allow interrupts again ; CALL VCLKOF BISL #DETACH,JSTAT(A4) BICL #CTLMOD!INHELP,JSTAT(A4) REST A0-A5,D0-D5 RTN HELP0: VUNLK CRT 23.,1 TYPE JMP HELP99 HELP1: VUNLK BITL #AUTO,JSTAT(A4) JNE HELP99 CRT 23.,1 TYPE JMP HELP99 HELP2: VUNLK BITL #AUTO,JSTAT(A4) JNE HELP99 CRT 23.,1 TYPE JMP HELP99 HELP3: VUNLK BITL #AUTO,JSTAT(A4) JNE HELP99 CRT 23.,1 MOV QBCJCB(A3),A0 LEA A1,JOBNAM(A0) LEA A2,JWRK(A4) UNPACK UNPACK CLRB @A2 TYPE TTYL JWRK(A4) JMP HELP99 HELP4: VUNLK CRT 23.,1 TYPE JMP HELP99 HELP5: VUNLK BITL #AUTO,JSTAT(A4) JNE HELP99 CRT 23.,1 TYPE JMP HELP99 HELP6: VUNLK CRT 23.,1 TYPE JMP HELP99 HELP7: VUNLK BITL #AUTO,JSTAT(A4) JNE HELP99 CRT 23.,1 TYPE JMP HELP99 HELP8: VUNLK BITL #AUTO,JSTAT(A4) JNE HELP99 CRT 23.,1 TYPE TYPE HELP99: BITL #AUTO,JSTAT(A4) BNE 0$ CRT 255.,9. 0$: REST A0-A5,D0-D5 RTN ; routine to locate job area from packed jobname in JDDB(A4) JOBSRH: MOV @A4,A5 1$: MOV JJCB(A5),A0 CMM JOBNAM(A0),JDDB+D.FIL(A4) BNE 2$ ; check jobname RTN 2$: MOV @A5,A5 ; else advance to next MOV A5,D7 BNE 1$ ; unless end of chain RTN ; routine to clean out a TRMDEF, input and output ; A5 --> TRMDEF (must be LOCKed on entry) DRAINO: SAVE A3,D1 BISW #T$OIP,@A5 ; turn on output in progress MOV T.OQX(A5),D7 ; any output queued? MOV D7,A3 BEQ 2$ ; NO ADD #4,A3 ; skip to command word CMP (A3)+,#10 ; is this ^S block? BNE 2$ ; NO BICW #1,@A3 ; reset ^S suspend 2$: TRMOCP ; get output TST D1 ; end yet? BPL 2$ ; NO BICW #T$OIP,@A5 ; YES - reset OIP CLR T.ICC(A5) ; clear input system also... CLR T.ECC(A5) CLR T.BCC(A5) REST A3,D1 RTN ; routine to remove a queue block from linked list (prior to QRET) ; A3 --> queue block to unchain, A0 --> base of chain it's on QDEL: CMP A3,@A0 ; is this the right one? BEQ 1$ ; YES - go free/rechain MOV @A0,A0 ; save fwd pointer MOV A0,D7 ; make sure not zero BNE QDEL ; if not zero, loop RTN 1$: MOV @A3,@A0 ; rechain rest RTN ; routine to force intensity change for a job line FORUPD: SETL DJOB(A5) SETL DTRM(A5) SETW DDVC(A5) SETW DDRV(A5) SETW DUSR(A5) SETL DMEM(A5) SETW DSTA(A5) SETL DPRG(A5) SETL DFLG(A5) RTN EVEN END