1 ! P s e u d o K e y b o a r d C o m m a n d F i l e E x e c u t o r 2 ! PROGRAM : EXEC.BAS 3 ! PACKAGE : SYSTEMS UTILITIES 4 V$ = "V03-01" 5 ! DATE : 26-Jan-82 6 ! AUTHOR : Steven R. Gerber 7 ! 8 ! Copyright (C) 1982 By Steven R. Gerber 9 ! 10 EXTEND ! This is an Extend Mode Program 20 Y$=SYS(CHR$(6%)+CHR$(-7%)) ! Enable CTRL/C Trapping & \ ON ERROR GOTO 19000 95 ! & ! P R O G R A M D E S C R I P T I O N & ! & ! & ! The EXEC software package is designed to replace previous 'BATCH' & ! processing packages by taking up less core memory when running and by & ! being able to properly pass the escape character (CHR$(27%) or & ! CHR$(155%)). & ! & ! Naturally, the 'DATE' and 'TIME' invocation options are valid; 'KILL', & ! '-LOG', and 'DELETE' are also valid. 'KILL' deletes the .LOG file upon & ! completing EXECution. '-LOG' simply tells EXEC not to create a .LOG d & ! file. 'DELETE' kills the command file upon completing EXECution. & ! & ! The ...LOGIN and ...LOGOUT directives are no longer required; & ! EXEC automatically logs in the user's PPN at the beginning of & ! EXECution and kills the Pseudo-Keyboard job at the end of EXECution. & ! Three Directives are available: %%BURST, %%PRIOR, and %%DET. & ! The burst directive allows a privileged user to change his/her run & ! burst at virtually any time during EXECution. The priority directive & ! allows any user to lower his/her priority and privileged users to & ! raise their priorities. The detach directive allows privileged users & ! to detach their EXECuting job from the Pseudo-Keyboard. & ! & ! EXEC can only be started by START. & ! EXEC requires KBLOG to login the Pseudo-Keyboard. & ! PASS is required to send messages (containing Command file information) & ! to EXEC. & ! EXEC only can be properly shut down by DOWN. & ! REDUCE is used to make EXEC take up the minimum amount of memory, & ! while running. & ! & ! & ! Command file examples : & ! & ! Privileged ; & ! PIP [1,*]*.BAC/L:S/PRIOR/LOCK & ! PIP *.BAK,*.TMP/DE/ER/W/PRIOR/LOCK & ! %%BURST=10 & ! %%PRIOR=8 & ! SY/1,* & ! DIR/SU & ! %%DET & ! & ! Non-Privileged ; & ! %%PRIOR=-88 & ! PIP ALL.ALL=*.*/W & ! SYS & ! & ! Invocation examples : & ! & ! A.CMD/DE/K/DA:05-Mar-82/T:11:00 & ! ; Delete command file upon completing & ! ; Kill .LOG file upon completion & ! ; Start on or after 05-Mar-82 & ! ; Start at or after 11:00 in the morning & ! & ! A.CMD/-LOG/DA:05.03.82 & ! ; Do not create a .LOG file & ! ; Start on or after 05.03.82 & ! & ! Notes : & ! 1. Noon is specified as 12:00 and midnight is specified as & ! 00:00. & ! 2. Certain protection codes, for the six programs making up & ! the EXEC software package, are suggested : & ! & ! EXEC.BAC <124> & ! START.BAC <124> & ! PASS.BAC <232> & ! DOWN.BAC <124> & ! REDUCE.BAC <104> & ! & ! 3. The proper procedure for creating EXEC.BAC; & ! & ! RUN $PIP & ! TEMP.BAS=EXEC.BAS & ! ^Z & ! RUN REDUCE & ! TEMP.BAS & ! T2.BAS & ! YES & ! YES & ! NO & ! ^Z & ! OLD T2 & ! COMPILE EXEC & ! 295 ! & ! I / O C H A N N E L S & ! & ! #1% Buffer used to Receive Messages from PASS & ! #2% My Error Log & ! #3% Used to Input Command lines from the Command file & ! #4% Used to Print into the .LOG file & ! #5% Used as a Communications Channel to the Pseudo-Keyboard & ! #6% The .HLD Virtual Array & ! 395 ! & ! V A R I A B L E D E F I N I T I O N S & ! & ! ACCESS% Access Control Field for the Receive a Message SYS Call & ! BACKSLASH% Pointer to the Backslash character in a string & ! BUF.OFFSET% Offset to Message in Message Buffer & ! BURST% Requested Run-Burst & ! CALL$ User's Directive Request & ! CHAN% Message Buffer's Channel number & ! CLEAN% Loop Variable for Cleaning the .HLD Virtual Array & ! COMMA% Pointer to a Comma in certain strings & ! COMMAND$ User Command Line & ! COMMON.CORE$ Data from Common Core & ! D1$ Temporary storage for User's Requested Start Date & ! DAT$ User's Requested Start Date & ! DAT% Pointer to D1$ in SWITCH$ & ! DEV$ Device where user's Command file Resides & ! DEVOKB% 2%*(Number of Disks) & ! DEVPTR% DDB Pointer Table & ! DIR.LEN% Number of characters necessary to Specify a certain Directive & ! DIRECTIVE$ Proper Directive & ! EQUAL.SIGN% Pointer to the Equal Sign in a Directive Line & ! ERL System Variable for Line at which an Error occurred & ! ERR System Variable used to Specify the type of Error & ! EXTENSION.RADIX.50$ Command file Extension in RADIX-50 format & ! FILE$ Command file specification & ! HOLD$(64%) The .HLD Virtual Array & ! JDB2% Job Data Block 2 & ! JDB% Job Data Block 1 & ! JOB% Job Number of job Spawned & ! JOB.NAME$ Job Name of job Spawned & ! JOBTBL% Job Table & ! KB.BASE% Base Address of Keyboard DDB Pointers in DEVTBL & ! KB.DDB% Keyboard's Device Data Block & ! KB.UNIT% Keyboard Number of Pseudo-Keyboard & ! LOCAL% Local/No Local Senders & ! LOOP% Loop Variable used in Directives routine & ! M1$ Month, used to convert Numeric date to & ! Alphabetic date & ! MAX.LEN% Maximum number of Bytes to accept on a Receive & ! ME% My Job number & ! MES.LEN% Number of Bytes actually Copied to my Message Buffer & ! MONTH$ The first three letters of all twelve months & ! in the order of the year & ! MONTH% Number of month & ! MOVE% Loop Variable used shift the held messages & ! down one position & ! NAM$ My Name as a Receiver & ! NAME.RADIX.50$ Command file Name in RADIX-50 format & ! NETWORK% Network Logical Links/No Logical Links & ! NUM.CHR% Number of Bytes Copied to PK.DATA$ & ! OUT$ Filespec of .LOG file & ! P1$ String used to pass Virtual Array pointer to & ! DOWN & ! P1% Pointer to Messages in array MES$ & ! PARAM$ Parameter string from Receive & ! PARAM% Number of Bytes making up PPN in PARAM$ & ! PASS$ Message Buffer & ! PASS%(32) Ascii value of each and every character in PASS$ & ! PGR.PROGRAMMER% User's Programmer number & ! PJT.PROJECT% User's Project number & ! PK$ "PK"+NUM1$(PK.UNIT%)+":" & ! PK.DATA$ Buffer used to Retreive Data from the Pseudo-Keyboard & ! PK.DDB% Pseudo-Keyboard's Device Data Block & ! PK.OFFSET% Pseudo-Keyboard's Device Offset & ! PK.UNIT% Pseudo-Keyboard's Pseudo-Keyboard Number & ! PPN$ Sub-string of PARAM$ used to determine & ! PGR.PROGRAMMER% and PJT.PROJECT% & ! PPN% PPN information for Job SLAVE% & ! PRIOR% Requested Priority & ! PTR% Pointer used to extract target KB.UNIT% & ! to be passed to DOWN & & ! RECOUNT System Variable used to indicate NUM.CHR% & ! SG.SPAWN.PROGRAMMER$ CHR$(Programmer number of Program to Spawn) & ! SJ.SPAWN.PROJECT$ CHR$(Project number of Program to Spawn) & ! SLASH% Pointer to the Slash character in FILE$ & ! SLAVE% Job number of job Attached to the Pseudo-Keyboard & ! SLP% Sleep/No Sleep & ! SPAWN$ Filespec of Program to Spawn & ! SWITCH$ String user's specified options & ! SYS.23$ Data returned from Terminating Filename String Scan & ! T1$ Temporary storage for User's Requested Start Time & ! T1% Pointer to Time switch in SWITCH$ & ! T2% Pointer to the Slash character in SWITCH$ & ! following the Time switch & ! TEMP$ String used to make PASS% from PASS$ & ! TIM$ User's Requested Start Time & ! TRUNCATE% Truncate/No Truncate & ! V$ String indicating program Version and Edition & ! Y$ Used for SYS Calls & ! Y%(40%) Ascii value for each and every characer in Y$ & ! 595 ! & ! F U N C T I O N S & ! 795 ! & ! F U N C T I O N / S U B R O U T I N E D E F I N I T I O N S & ! & ! 10000 Convert 24hr time to 12hr time & ! 895 ! & ! D I M E N S I O N I N G A R E A & ! 900 DIM MES$(32%) ! Temporary Storage for Messages & \ DIM PASS%(32%) ! Comes From Message Buffer & \ DIM Y%(40%) ! Comes From Receive String 995 ! & ! S T A R T O F P R O G R A M & ! & ! Get and Chop up COMMON.CORE$ & ! 1000 COMMON.CORE$=SYS(CHR$(7%)) & \ BACKSLASH%=INSTR(1%,COMMON.CORE$,"\") & \ DEVPTR%=VAL(LEFT(COMMON.CORE$,BACKSLASH%-1%)) & \ COMMON.CORE$=RIGHT(COMMON.CORE$,BACKSLASH%+1%) & \ BACKSLASH%=INSTR(1%,COMMON.CORE$,"\") & \ PK.OFFSET%=VAL(LEFT(COMMON.CORE$,BACKSLASH%-1%)) & \ COMMON.CORE$=RIGHT(COMMON.CORE$,BACKSLASH%+1%) & \ BACKSLASH%=INSTR(1%,COMMON.CORE$,"\") & \ JOBTBL%=VAL(LEFT(COMMON.CORE$,BACKSLASH%-1%)) 1005 ! & ! Initialize Variables & ! 1010 BUF.OFFSET%=0% & \ CHAN%=1% & \ LOCAL%=0% & \ MAX.LEN%=32% & \ NETWORK%=0% & \ SLP%=1% & \ TIMER%=0% & \ TRUNCATE%=0% & \ MONTH$="JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC" & \ NAM$="EXEC " 1015 ! & ! Open a Buffer for Messages & ! 1020 OPEN "NL:" AS FILE 1%,RECORDSIZE 32% & \ FIELD #1%,32% AS PASS$ 1025 ! & ! Open the Error Log & ! 1030 OPEN "[210,2]EXEC.ERR" FOR OUTPUT AS FILE 2% 1035 ! & ! Receive a Message & ! 1040 ACCESS%=SLP%+TRUNCATE%+LOCAL%+NETWORK% & \ Y$=SYS(CHR$(6%)+CHR$(22%)+CHR$(2%)+CHR$(ACCESS%)+ & STRING$(6%,0%)+CHR$(CHAN%)+CHR$(0%)+ & CHR$(MAX.LEN%)+CHR$(SWAP%(MAX.LEN%))+ & CHR$(BUF.OFFSET%)+CHR$(SWAP%(BUF.OFFSET%))+ & STRING$(10%,0%)+CHR$(TIMER%)+CHR$(SWAP%(TIMER%))+CHR$(0%)) & \ GOTO 25000 IF LEFT(PASS$,11%)="EXEC\%%SHUT" & \ P1%=P1%+1% & \ PARAM$=RIGHT(Y$,21%) ! Contains PPN$ & \ PARAM%=VAL(LEFT(PARAM$,1%)) & \ PPN$=MID(PARAM$,2%,PARAM%) & \ COMMA%=INSTR(1%,PPN$,",") & \ PJT.PROJECT%=VAL(LEFT(PPN$,COMMA%-1%)) & \ PGR.PROGRAMMER%=VAL(RIGHT(PPN$,COMMA%+1%)) & \ CHANGE Y$ TO Y% & \ MES.LEN%=Y%(13%)+SWAP%(Y%(14%)) & \ MES$(P1%)=CHR$(PJT.PROJECT%)+CHR$(PGR.PROGRAMMER%)+LEFT(PASS$,MES.LEN%) & \ P1%=P1%+1% & \ GOTO 1045 IF (INSTR(1%,MES$(P1%-1%),"/:")<1% AND & INSTR(1%,MES$(P1%-1%),"/T")<1%) & \ P1%=P1%-1% & \ GOTO 1040 IF P1%<32% & \ P1%=P1%+1% 1045 P1%=P1%-1% & \ GOTO 1040 IF P1%<1% & \ PGR.PROGRAMMER%=ASCII(LEFT(MES$(P1%),1%)) & \ PJT.PROJECT%=ASCII(MID(MES$(P1%),2%,1%)) & \ LSET PASS$=RIGHT(MES$(P1%),3%) & \ DEV$=LEFT(PASS$,3%) & \ DEV$=DEV$+":" IF INSTR(1%,DEV$,":")<1% & \ PPN$="["+NUM1$(ASCII(MID(PASS$,5%,1%)))+","+ & NUM1$(ASCII(MID(PASS$,6%,1%)))+"]" & \ TEMP$=STRING$(32%,32%) ! Spaces & \ LSET TEMP$=PASS$ & \ CHANGE TEMP$ TO PASS% & \ FILE$=RAD$(PASS%(7%)+SWAP%(PASS%(8%)))+ & RAD$(PASS%(9%)+SWAP%(PASS%(10%)))+ & "."+ & RAD$(PASS%(11%)+SWAP%(PASS%(12%))) & \ START$=TEMP$ & \ SWITCH$="" & \ IF INSTR(1%,START$,"/")>0% THEN & SLASH%=INSTR(1%,START$,"/") & \ SWITCH$=RIGHT(START$,SLASH%) & \ FILE$=LEFT(START$,SLASH%-1%) & \ DAT$="" & \ IF INSTR(1%,SWITCH$,"/:")>0% THEN & DAT%=INSTR(1%,SWITCH$,"/:")+2% & \ D1$=MID(SWITCH$,DAT%,6%) & \ DAT$=LEFT(D1$,2%)+"."+MID(D1$,3%,2%)+"."+RIGHT(D1$,5%) & \ IF INSTR(1%,DATE$(0%),"-")>0% THEN ! Convert date to Alphabetic form & MONTH%=VAL(MID(DAT$,4%,2%)) & \ M1$=MID(MONTH$,3%^(MONTH%-1%)+1%,3%) & \ D1$=LEFT(DAT$,2%)+"-"+M1$+"-"+RIGHT(DAT$,7%) & \ DAT$=D1$ 1050 TIM$="" & \ T2%=0% & \ IF SWITCH$<>"" THEN & IF INSTR(1%,SWITCH$,"/T")>0% THEN & T1%=INSTR(1%,SWITCH$,"/T")+2% & \ T2%=INSTR(T1%,SWITCH$,"/") & \ T1$=RIGHT(SWITCH$,T1%) IF T2%<1% & \ T1$=MID(SWITCH$,T1%,T2%-T1%) IF T2%>0% & \ T%=LEN(T1$)-2% & \ TIM$=LEFT(T1$,T%-1%)+":"+RIGHT(T1$,T%) & \ IF INSTR(1%,TIME$(0%),"M")>0% THEN GOSUB 10000 ! 12hr Clock 1060 IF (DAT$<>"" AND DAT$"" AND TIM$0% THEN 1140 1115 ! & ! Set up the .LOG file & ! 1120 OUT$="["+NUM1$(PJT.PROJECT%)+","+NUM1$(PGR.PROGRAMMER%)+"]"+"EXEC"+NUM1$(JOB%)+".LOG" & \ OPEN OUT$ AS FILE 4%,RECORDSIZE 512% 1130 PRINT #4%,STRING$(80%,42%) ! *'s & \ PRINT #4% & \ PRINT #4%," EXECUTION BEGUN ON ";DATE$(0%);" AT ";TIME$(0%) & \ PRINT #4%," Job Name = ";FILE$;" Queued by User [";PJT.PROJECT%;",";PGR.PROGRAMMER%;"]" & \ PRINT #4%," JOB #";NUM1$(JOB%);" and ";PK$;" are being used" & \ PRINT #4% & \ PRINT #4%,STRING$(80%,42%) ! *'s & \ PRINT #4% 1135 ! & ! Open a Communications Channel to the PK & ! 1140 OPEN PK$ AS FILE 5%,RECORDSIZE 128% & \ FIELD #5%,128% AS PK.DATA$ 1145 ! & ! Loop While JOB.NAME$<>"NONAME" & ! 1150 JDB2%=PEEK(PEEK(JOBTBL%+(JOB%*2%))) & \ JOB.NAME$=RAD$(PEEK(JDB2%+12%))+RAD$(PEEK(JDB2%+14%)) & \ SLEEP (1%) & \ IF JOB.NAME$<>"NONAME" THEN 1150 1155 ! & ! Get PK.DATA$ & ! 1160 GET #5% & \ NUM.CHR%=RECOUNT & \ IF INSTR(1%,SWITCH$,"/-")<1% THEN & PRINT #4%,LEFT(PK.DATA$,NUM.CHR%); 1170 GOTO 1160 1180 PUT #5%,RECORD 6% 1185 ! & ! Get a Command Line & ! 1190 INPUT LINE #3%,COMMAND$ & \ IF LEFT(COMMAND$,2%)="%%" THEN & CALL$=CVT$$(RIGHT(COMMAND$,3%),38%) & \ GOTO 20000 1195 ! & ! Make Escapes Passable & ! 1200 IF RIGHT(COMMAND$,LEN(COMMAND$))=CHR$(27%) THEN & COMMAND$=LEFT(COMMAND$,LEN(COMMAND$)-1%)+CHR$(155%) 1205 ! & ! If Requested, Force a Control Character & ! 1210 IF CVT$$(COMMAND$,4%)="^C" THEN Y$=SYS(CHR$(6%)+CHR$(-4%)+CHR$(KB.UNIT%)+CHR$(3%)) & \ GOTO 1160 1220 IF CVT$$(COMMAND$,4%)="^O" THEN Y$=SYS(CHR$(6%)+CHR$(-4%)+CHR$(KB.UNIT%)+CHR$(115%)) & \ GOTO 1160 1230 IF CVT$$(COMMAND$,4%)="^Q" THEN Y$=SYS(CHR$(6%)+CHR$(-4%)+CHR$(KB.UNIT%)+CHR$(17%)) & \ GOTO 1160 1240 IF CVT$$(COMMAND$,4%)="^R" THEN Y$=SYS(CHR$(6%)+CHR$(-4%)+CHR$(KB.UNIT%)+CHR$(18%)) & \ GOTO 1160 1250 IF CVT$$(COMMAND$,4%)="^S" THEN Y$=SYS(CHR$(6%)+CHR$(-4%)+CHR$(KB.UNIT%)+CHR$(19%)) & \ GOTO 1160 1260 IF CVT$$(COMMAND$,4%)="^T" THEN Y$=SYS(CHR$(6%)+CHR$(-4%)+CHR$(KB.UNIT%)+CHR$(20%)) & \ GOTO 1160 1270 IF CVT$$(COMMAND$,4%)="^U" THEN Y$=SYS(CHR$(6%)+CHR$(-4%)+CHR$(KB.UNIT%)+CHR$(21%)) & \ GOTO 1160 1280 IF CVT$$(COMMAND$,4%)="^Z" THEN Y$=SYS(CHR$(6%)+CHR$(-4%)+CHR$(KB.UNIT%)+CHR$(26%)) & \ GOTO 1160 1290 PUT #5%,RECORD 6% & \ PRINT #5%,COMMAND$ & \ COMMAND$="" & \ LSET PK.DATA$="" & \ NUM.CHR%=0% & \ GOTO 1190 1300 IF INSTR(1%,SWITCH$,"/-")<1% THEN & PRINT #4% & \ PRINT #4%,STRING$(80%,42%) ! *'s & \ PRINT #4%," Physical End-of-File on Device EXECution assumed complete" & \ PRINT #4%,STRING$(80%,42%) ! *'s 1305 ! & ! Kill the Pseudo Keyboard Job & ! 1310 KB.BASE%=DEVPTR%+DEVOKB% & \ KB.DDB%=PEEK(PEEK(KB.BASE%)+(KB.UNIT%)*2%) & \ SLAVE%=(PEEK(KB.DDB%+2%) AND 126%)/2% ! The PK Job & \ Y$=SYS(CHR$(6%)+CHR$(8%)+CHR$(SLAVE%)+STRING$(24%,0%)+CHR$(255%)) 1315 ! & ! Close the 'Temporary' I/O Channels Used & ! 1320 CLOSE 3%,4%,5% 1325 ! & ! Deassign the Pseudo Keyboard & ! 1330 Y$=SYS(CHR$(6%)+CHR$(11%)+STRING$(20%,0%)+"PK"+CHR$(PK.UNIT%)) & \ KILL FILE$ IF INSTR(1%,SWITCH$,"/D")>0% ! Command file & \ KILL OUT$ IF INSTR(1%,SWITCH$,"/K")>0% ! .LOG file & \ PRINT #2%,STRING$(80%,42%) ! *'s & \ GOTO 1045 9995 ! & ! S U B R O U T I N E S & ! 10000 COLON%=INSTR(1%,TIM$,":") & \ IF VAL(LEFT(TIM$,COLON%-1%))>12% THEN & T1$=NUM1$(-12%+VAL(LEFT(TIM$,COLON%-1%))) & \ T2$=RIGHT(TIM$,COLON%) & \ TIM$=T1$+T2$+"PM" & \ GOTO 10020 10010 TIM$=TIM$+"AM" 10020 RETURN 18995 ! & ! S T A N D A R D E R R O R H A N D L I N G & ! 19000 IF ERL=1040 AND ERR=5 AND P1%>0% THEN RESUME 1045 19010 IF ERL=1040 AND ERR=5 THEN RESUME 1040 19020 IF ERL=1070 THEN RESUME 1040 19030 IF ERL=1090 AND (ERR=3 OR ERR=8) THEN RESUME 1090 19040 RESUME 19060 IF (ERL<>1090 AND ERL<>1120) & \ PRINT #2%,DATE$(0%);" ";TIME$(0%); & \ PRINT #2%," ?No Pseudo-Keyboards Available" IF ERL<>1120 & \ PRINT #2%," ?Can't Open .LOG file" IF ERL<>1090 & \ PRINT STRING$(80%,42%) ! *'s & \ Y$=SYS(CHR$(6%)+CHR$(22%)+CHR$(-1%)+CHR$(0%)+NAM$+ & CHR$(CHAN%)+CHR$(0%)+ & CHR$(MES.LEN%)+CHR$(SWAP%(MES.LEN%))+ & CHR$(BUF.OFFSET%)+CHR$(SWAP%(BUF.OFFSET%))+ & STRING$(4%,0%)+NUM1$(PARAM%)+PARAM$) & \ SLEEP (120%) & \ CLOSE 3%,4%,5% ! Close 'Temporary' I/O Channels & \ RESUME 1040 19060 IF ERL=1140 THEN SLEEP (5%) & \ RESUME 1140 19070 IF ERL=1160 THEN RESUME 1180 19080 IF ERL=1180 AND ERR=28 THEN & Y$=SYS(CHR$(6%)+CHR$(-7%)) & \ RESUME 1190 19090 IF ERL=1180 THEN RESUME 1160 19100 IF ERL=1190 AND ERR<>11 AND INSTR(1%,SWITCH$,"/-")<1% THEN & PRINT #4%,"?Command Input Error ... Stopping EXECution ...." & \ RESUME 1310 19110 IF ERL=1190 THEN RESUME 1300 19120 IF ERL=1290 AND ERR=28 THEN Y$=SYS(CHR$(6%)+CHR$(-7%)) 19130 IF ERL=1290 THEN RESUME 1160 19140 IF ERL=1310 THEN RESUME 1320 19150 IF ERL=22010 OR ERL=23010 OR ERL=24000 OR ERL=24010 THEN RESUME 1190 19160 PRINT #2% & \ PRINT #2%,DATE$(0%);" ";TIME$(0%); & " [";NUM1$(PJT.PROJECT%);",";NUM1$(PGR.PROGRAMMER%);"] "; & DEV$;PPN$;FILE$;SWITCH$;" "; & ERR;" ";ERL & \ PRINT #2%,STRING$(80%,42%) ! *'s & \ RESUME 25000 ! DOWN 19995 ! & ! L I B R A R Y R O U T I N E S & ! & ! Directives & ! 20000 KB.BASE%=DEVPTR%+DEVOKB% & \ KB.DDB%=PEEK(PEEK(KB.BASE%)+(KB.UNIT%)*2%) & \ SLAVE%=(PEEK(KB.DDB%+2%) AND 126%)/2% ! The PK Job & \ JDB%=PEEK(JOBTBL%+(SLAVE%*2%)) & \ PPN%=PEEK(PEEK(JDB%+8%)+24%) & \ PGR.PROGRAMMER%=PPN% AND 255% & \ PJT.PROJECT%=SWAP%(PPN%) AND 255% & \ LOOP%=0% & \ RESTORE 21000 LOOP%=LOOP%+1% & \ READ DIRECTIVE$,DIR.LEN% & \ IF LEFT(CALL$,DIR.LEN%)=LEFT(DIRECTIVE$,DIR.LEN%) THEN 21030 21010 IF DIRECTIVE$<>"^*@" THEN 21000 21020 GOTO 1190 21030 ON LOOP% GOTO 22000,23000,24000 21040 DATA "BURST",5%,"DET",3%,"PRI",3%,,"^*@",3% 22000 IF PJT.PROJECT%>1% THEN 1190 22005 ! & ! Change Job SLAVE%'s Burst to BURST% & ! 22010 EQUAL.SIGN%=INSTR(1%,CALL$,"=") & \ BURST%=VAL(RIGHT(CALL$,EQUAL.SIGN%+1%)) & \ Y$=SYS(CHR$(6%)+CHR$(-13%)+CHR$(SLAVE%)+STRING$(2%,0%)+CHR$(1%)+CHR$(BURST%)) & \ GOTO 1190 23000 IF PJT.PROJECT%>1% THEN 1190 23005 ! & ! Detach Job SLAVE% & ! 23010 Y$=SYS(CHR$(6%)+CHR$(7%)+CHR$(SLAVE%+128%)) & \ IF INSTR(1%,SWITCH$,"/-")>0% THEN & PRINT #4%,"Detaching ..." 23020 GOTO 1320 24000 EQUAL.SIGN%=INSTR(1%,CALL$,"=") & \ PRIOR%=VAL(RIGHT(CALL$,EQUAL.SIGN%+1%)) & \ IF PJT.PROJECT%>1% AND PRIOR%>0% THEN 1190 24005 ! & ! Change Job SLAVE%'s Priority to PRIOR% & ! 24010 Y$=SYS(CHR$(6%)+CHR$(-13%)+CHR$(SLAVE%)+CHR$(1%)+CHR$(PRIOR%)) & \ GOTO 1190 24995 ! & ! Shut Down & ! 25000 OPEN "[210,2]EXEC.HLD" AS FILE 6% & \ DIM #6%,HOLD$(64%) & \ HOLD$(CLEAN%)="" FOR CLEAN%=1% TO 64% & \ HOLD$(MES%)=MES$(MES%) FOR MES%=1% TO P1% & \ PTR%=ASCII(MID(PASS$,12%,1%)) & \ KB.UNIT%=VAL(MID(PASS$,13%,PTR%)) ! Keyboard to which I shall Broadcast & \ CLOSE 1%,2%,3%,4%,5%,6% ! Close all I/O Channels & \ P1$=CHR$(LEN(NUM1$(P1%+1%))) ! Virtual Array Pointer & \ Y$=SYS(CHR$(8%)+CHR$(PTR%)+NUM1$(KB.UNIT%)+P1$+NUM1$(P1%+1%)) ! Virtual Array Pointer & \ PRINT #2%,CHR$(7%);" Chaining to DOWN ...." & \ CHAIN "[210,2]DOWN.BAC" ! Chain to Actual Shutdown Program & \ GOTO 32767 29995 ! & ! C C L E N T R Y & ! 32700 ! & ! E X I T F R O M P R O G R A M C O D E & ! 32767 END