Trailing-Edge
-
PDP-10 Archives
-
BB-5255D-BM
-
4-sources/sysjob.mac
There are 32 other files named sysjob.mac in the archive. Click here to see a list.
;<4.UTILITIES>SYSJOB.MAC.16, 3-Jan-80 15:27:29, EDIT BY R.ACE
;UPDATE COPYRIGHT DATE
;<4.UTILITIES>SYSJOB.MAC.15, 13-Nov-79 15:58:43, EDIT BY MURPHY
;<4.UTILITIES>SYSJOB.MAC.14, 13-Nov-79 15:50:43, EDIT BY MURPHY
;ADD ERJMP AFTER BOUT TO PTY
;<4.UTILITIES>SYSJOB.MAC.13, 1-Oct-79 07:24:39, EDIT BY R.ACE
;<4.UTILITIES>SYSJOB.MAC.12, 1-Oct-79 07:22:44, EDIT BY R.ACE
;TCO 4.2502 - ADD ERJMP AFTER JFNS JSYS
;<4.UTILITIES>SYSJOB.MAC.11, 21-Jun-79 16:39:25, EDIT BY KIRSCHEN
;REMOVE SUPERFLUOUS MESSAGE IF CANNOT GET JOB LOCATION;<4.UTILITIES>SYSJOB.MAC.10, 11-Apr-79 10:25:03, EDIT BY KIRSCHEN
;<4.UTILITIES>SYSJOB.MAC.9, 11-Apr-79 09:59:11, EDIT BY KIRSCHEN
;SET JOB 0 LOCATION TO LOCAL NODE
;<4.UTILITIES>SYSJOB.MAC.8, 15-Mar-79 10:38:47, EDIT BY KIRSCHEN
;make fork status output be octal to agree with purge command
;<4.UTILITIES>SYSJOB.MAC.7, 12-Mar-79 14:23:25, EDIT BY KONEN
;UPDATE COPYRIGHT FOR RELEASE 4
;<4.UTILITIES>SYSJOB.MAC.6, 1-Feb-79 12:08:21, EDIT BY KIRSCHEN
;TCO 4.2180 - Add the PURGE command to kill a specific fork.
;<4.UTILITIES>SYSJOB.MAC.5, 23-Jan-79 16:21:27, Edit by KONEN
;UPDATE VERSION NUMBER FOR RELEASE 4
;<4.UTILITIES>SYSJOB.MAC.4, 13-Dec-78 14:15:56, EDIT BY DBELL
;MOVE TESTSW SO IT ISN'T CLEARED ON STARTUP
;<4.UTILITIES>SYSJOB.MAC.3, 13-Dec-78 11:24:02, EDIT BY DBELL
;TCO 4.2120 - IMPROVE HANDLING OF JOB CREATION ON PTYS
;<4.UTILITIES>SYSJOB.MAC.2, 29-Jul-78 13:18:00, EDIT BY MILLER
;MORE FIXES
;<4.UTILITIES>SYSJOB.MAC.1, 28-Jul-78 15:28:05, EDIT BY MILLER
;MAKE SYSJOB IMPERVIOUS TO FILE ERRORS
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) 1976,1977,1978,1979,1980 BY DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
;EXECUTIVE TO CONTROL 'DETACHED' SYSTEM JOBS - D. MURPHY
TITLE SYSJOB
SEARCH MONSYM,MACSYM
SALL
IFNDEF .PSECT,<
.DIRECT .XTABM>
; VERSION NUMBER DEFINITIONS
VMAJOR==4 ;MAJOR VERSION OF SYSJOB
VMINOR==0 ;MINOR VERSION NUMBER
VEDIT==11 ;EDIT NUMBER
VWHO==0 ;GROUP WHO LAST EDITED PROGRAM (0=DEC DEVELOPMENT)
VSYSJB== <VWHO>B2+<VMAJOR>B11+<VMINOR>B17+VEDIT
P=17
F=0
A=1
B=2
C=3
D=4
Q1=5
Q2=6
Q3=7
P1=10
P2=11
P3=12
P4=13
P5=14
NX=15 ;NAME INDEX
NPDL==40
NJOBS==20 ;MAX NUMBER OF SIMULTANEOUS JOBS
NAJOBS==100 ;MAX NUMBER ADVANCE JOBS
NAJCW==10 ;NUMBER WORDS FOR COMMAND STRING FOR EACH AJOB
NLINES==20 ;MAX NUMBER PTY LINES ACTIVE
NWSBUF==^D40 ;NUMBER OF WORDS PER STRING BUFFER
NLCLBF==100 ;SIZE OF LOCAL TERMINAL INPUT BUFFER
OPDEF CALL [PUSHJ P,0]
OPDEF RET [POPJ P,0]
DEFINE RETSKP <
JRST RSKP>
DEFINE PMSG (MSG)<
HRROI 1,[ASCIZ \MSG\]
PSOUT>
;GENERAL JSYS ERROR HANDLER
DEFINE JERR <
CALL JERR0>
;CHARACTERS USED
ESCC=="^" ;ESCAPE CHARACTER IN PTY INPUT
ESC==33 ;'ESC'
INTCCD==3 ;^C IS INTERRUPT CHAR, FORCES RESTART
RSTCCD==2 ;^B IS INTERRUPT CHAR, FORCES RELOAD
PTCHN==2 ;CHANNELS (2 AND 3) USED BY PTYS
.TTDPI==24 ;FUNCTION CODE - DECLARE PTY INTERRUPTS
.TTTIH==25 ; "" - TEST INPUT HUNGRY
FRKTMF=1B1 ;FORK TERMINATION NOTED BY INTERRUPT
AJCMF=1B2 ;COMMAND COMING FROM AJOB STRING BUFFER
EVEC: JRST START ;REGULAR START
JRST DSTRT ;DETACH AND START
VSYSJB ;VERSION NUMBER
RSKP: AOS 0(P)
R: RET
;THE W,X,Y,Z ARE CALCULATED BY THE MACRO LIKE THIS:
;W - THE NUMBERICAL VALUE OF VMAJOR
;
;X - THE LETTER CORRESPONDING TO THE VALUE OF VMINOR. @=0, A=1...
;
;Y - THE NUMERICAL VALUE OF VEDIT
;
;Z - THE NUMERICAL VALUE OF VWHO
DEFINE .CLNAM<
DEFINE .CLNM(LETTER,WHO)<
IRPC LETTER,<
IFE "A"-"'LETTER'"+VMINOR-1,<
STOPI
IFIDN <LETTER><@>,<
IFE VWHO,< .NAME(\VMAJOR,,\VEDIT,)>
IFN VWHO,< .NAME(\VMAJOR,,\VEDIT,-WHO)>>
IFDIF <LETTER><@>,<
IFE VWHO,< .NAME(\VMAJOR,LETTER,\VEDIT,)>
IFN VWHO,< .NAME(\VMAJOR,LETTER,\VEDIT,-WHO)>>>>>
IFGE VMINOR-^D26,< VMINOR==0
PRINTX %MINOR VERSION TOO LARGE - IGNORED>
IFGE VWHO-7,< VMINOR==
PRINTX %VWHO IS TOO LARGE - IGNORED>
.CLNM(@ABCDEFGHIJKLMNOPQRSTUVWXYZ,\VWHO)
>
;DEFINE A .NAME MACRO TO GEN THE TEXT STRING
DEFINE .NAME(V,M,E,W)<
ASCIZ /V'M'('E')'W/>
;ENTRY POINTS
;DETACH AND START - MAKE PRIMARY OUTPUT FOR THIS JOB
;BE JOB 0'S LOGGING TTY
DSTRT: DTACH
MOVE 1,[SIXBIT /LOGDES/]
SYSGT ;GET TABLE NUMBER FOR JOB 0 TTY
JUMPE 2,DSTRT1 ;JUMP IF NO SUCH TABLE
HRLI 1,1 ;GET ENTRY 1
GETAB
DSTRT1: MOVEI 1,377777 ;IF CAN'T GET JOB 0 TTY, USE NUL
HRLI 1,-1 ;SHOULD NEVER DO PRIMARY INPUT
MOVE 2,1
MOVEI 1,.FHSLF
SPJFN ;MAKE PRIMARY OUTPUT TO JOB 0 TTY
;NORMAL START
;INITIALIZE STORAGE AREA; ENABLE ALL AVAILABLE CAPABILITIES
;PRINT STARTING MESSAGE; GET DBUGSW FROM SYSTEM
START: RESET
MOVE P,[IOWD NPDL,PDL]
MOVE A,[STGBGN,,STGBGN+1]
SETZM -1(A)
BLT A,STGEND-1 ;CLEAR ALL STORAGE
SETZ F,
CALL SETLOC ;SET JOB LOCATION IF UNDER JOB 0
GTAD ;TRY TO GET TAD
JUMPL 1,[MOVEI 1,^D5000 ;IF NOT SET YET, WAIT AWHILE
DISMS
JRST START] ;THEN TRY AGAIN
MOVEI 1,400000
RPCAP
MOVE 3,2
EPCAP ;ENABLE ALL POSSIBLE CAPS
PMSG <
SYSJOB >
HRROI A,VTXT
PSOUT
PMSG < started at >
MOVEI 1,101
SETO B,
MOVSI C,240
ODTIM ;TIMESTAMP THE RESTART
PMSG <
>
MOVE 1,[SIXBIT /DBUGSW/]
SYSGT ;GET DBUGSW FROM SYSTEM
CAIN 2,0
SETZ 1, ;ASSUME 0 IF NO DBUGSW TABLE
MOVEM 1,DBUGSW
; ..
;SET UP THE INTERRUPT SYSTEM
MOVEI 1,400000 ;INIT PSI SYSTEM, THIS FORK
MOVE 2,[XWD LEVT,CHNT]
SIR
MOVE 2,CHNMSK
AIC
EIR
GJINF ;GET OUR JOB NUMBER
JUMPN 3,ST1 ;NO INTERRUPT CHAR NEED IF NOT JOB 0
MOVE 1,[XWD INTCCD,0] ;PUT THE INTERRUPT CHAR ON 0
ATI
MOVE 1,[RSTCCD,,1] ;ASSIGN RELOAD CHAR TO 1
ATI
;STORE INFORMATION ABOUT SYSTEM TABLES
ST1: MOVE 1,[SIXBIT /PTYPAR/]
SYSGT ;GET NUMBER OF FIRST PTY
HRRZM 1,FIRPTY
MOVE 1,[SIXBIT /TTYJOB/]
SYSGT ;GET NUMBER OF TTYJOB TABLE
HRRZM 2,TTYJOB
MOVE 1,[SIXBIT /JOBNAM/]
SYSGT ;GET NUMBER OF JOBNAM TABLE
HRRZM 2,JOBNAM
MOVE 1,[SIXBIT /SNAMES/]
SYSGT ;GET NUMBER OF SYSTEM PROGRAM TABLE
HRRZM 2,SNAMES
;GET COMMAND FILE FOR STARTUP AND EXECUTE COMMANDS. IF SYSTEM IS BEING
;DEBUGGED (DBUGSW IS 2 OR TESTSW IS NON-ZERO) USE A SPECIAL FILE
;EXECUTE ALL COMMANDS IN THE FILE AND CLOSE IT
MOVEI A,.SFCDE ;SEE IF OK TO START
TMON
JUMPN B,[PMSG <SYSJOB startup deferred due to file system errors.
>
JRST ST3]
MOVSI 1,(1B2+1B17) ;SETUP TO DO INITIAL COMMANDS
HRROI 2,[ASCIZ /SYSTEM:SYSJOB.RUN/]
MOVE 3,DBUGSW
CAIL 3,2 ;DEBUGGING?
HRROI 2,[ASCIZ /SYSTEM:SYSJOB.DEBUG/] ;YES, USE OTHER FILE
SKIPE TESTSW ;TESTING SYSJOB?
HRROI 2,[ASCIZ /SYSJOB.TEST0/] ;YES, USE LOCAL FILE
GTJFN ;GET JFN FOR DESIRED FILE
JRST [ PMSG <SYSJOB command file not found.
>
JRST ST3]
MOVEM 1,INJFN ;SAVE THE JFN
MOVE 2,[7B5+1B19];; ;7-BIT BYTES, READ
OPENF ;OPEN THE FILE
JRST [ JERR
MOVE 1,INJFN
RLJFN
JFCL
JRST ST3]
CALL DOCMND ;READ AND PROCESS ALL COMMANDS IN THE FILE
MOVE 1,INJFN ;1/JFN FOR INITIAL COMMAND FILE
CLOSF ;CLOSE THE FILE
JFCL
; ..
;ALL INITIAL COMMANDS HAVE BEEN PROCESSED
;IF THIS JOB IS ATTACHED TO A TERMINAL, START A FORK TO READ COMMANDS
;FROM THE TERMINAL.
ST3: MOVEI 1,.FHSLF ;1/FORK HANDLE FOR THIS FORK
GPJFN ;GET PRIMARY INPUT AND OUTPUT JFNS
HLRZ 2,2 ;GET PRIMARY INPUT
CAIE 2,-1 ;CONTROLLING TTY?
JRST ST2 ;NO
GJINF ;YES. GET INFO ON CURRENT JOB
CAMN 4,[-1] ;IS IT ATTACHED TO A TERMINAL?
JRST ST2 ;NO, DETACHED
;JOB IS ATTACHED TO A TTY. CREATE A FORK AND MAP PART OF SYSJOB
;INTO IT. START IT AT FRKBGN (BELOW).
MOVSI 1,(1B1) ;YES, START FORK TO GATHER INPUT
CFORK ;CREATE FORK WITH SAME CAPABILITIES
JERR
MOVEM 1,LFORK ;SAVE FORK HANDLE
MOVSI 1,.FHSLF ;MAKE FIRST 100 PAGES COMMON
HRLZ 2,LFORK
MOVE 3,[1B0+3B4+100]
PMAP
MOVE 1,LFORK ;1/FORK HANDLE OF LOWER FORK
MOVEI 2,FRKBGN ;2/STARTING ADDRESS FOR LOWER FORK
SFORK ;START FORK TO READ FIRST LINE
;CHECK FOR INPUT AND OUTPUT FOR ALL PTY'S
ST2: CALL CHKPTY ;DO INITIAL PTY IO
JRST WAITI ;GO TO THE MAIN LOOP
;FORK TO GATHER INPUT FROM LOCAL TTY
;NOTE: THE CODE AT ST3 CREATES A FORK AND MAPS THIS ROUTINE INTO IT.
;THIS ROUTINE IS RUN ONLY IN THE LOWER FORK. IT READS ONE LINE OF
;INPUT FROM THE PRIMARY INPUT DEVICE AND STORES IT IN LCLBF. WHEN
;DONE, IT SETS A FLAG (LCLIC) AND HALTS. IT IS RESTARTED WHEN THE MAIN
;PROGRAM HAS COPIED THE TEXT FROM THE BUFFER
FRKBGN: MOVE 1,[100,,101] ;PRIMARY IO
HRROI 2,LCLBF ;INPUT TO LOCAL BUFFER
MOVE 3,[RD%BRK+RD%CRF+RD%JFN+NLCLBF*5]
RDTXT
JFCL
MOVEI 1,.CHLFD
DPB 1,2 ;MAKE SURE AT LEAST ONE EOL IN STRING
AOS LCLIC
HALTF ;WILL BE RESTARTED FOR NEXT COMMAND
;SETLOC - ROUTINE TO SET JOB LOCATION TO LOCAL NODE IF UNDER JOB 0
;
; DONE BECAUSE JOB 0 IS CREATED BEFORE THE LOCAL NODE NAME IS KNOWN
SETLOC: GJINF ;GET OUR JOB NUMBER
SKIPE C ;RUNNING UNDER JOB 0 ?
RET ;NO, ALL DONE
MOVX A,.NDGLN ;GET LOCAL NODE NAME FUNCTION
MOVEI B,C ;ARGUMENT BLOCK STARTS IN C
HRROI C,LOCAL ;POINT TO WHERE LOCAL NAME GOES
NODE ;GET LOCAL NODE NAME
ERJMP R ;FAILED, MUST NOT BE A DECNET SYSTEM
SETOM A ;THIS JOB
MOVX B,.SJLLO ;SET LOCATION FUNCTION
HRROI C,LOCAL ;POINTER TO NAME
SETJB ;SET OUR LOCATION
ERJMP [ PMSG (
% SYSJOB: Cannot set job location
)
RET] ;DONE
RET ;DONE
;THIS IS THE BEGINNING OF THE MAIN LOOP. IT MAKES REGULAR CHECKS
;FOR I/O NEEDS OF ITS SUBJOBS AND SUBFORKS
WAITI: MOVE 1,[SIXBIT /SYSJOB/]
SETNM
MOVEI 1,^D15
TLZE F,(FRKTMF) ;IF FORK TERMINATED, DON'T DISMS
JRST WAIT8
WAITPC: THIBR ;WAIT UNTIL SIGNAL FROM 'SPEAK'
JFCL
WAIT8: SKIPE LCLIC ;ANY LOCAL INPUT (SET BY LOWER FORK)
JRST [ MOVE 1,[POINT 7,LCLBF] ;YES, DO IT
MOVEM 1,AJCMP ;SETUP PTR TO INPUT STRING
TLO F,(AJCMF) ;SAY COMMAND FROM STRING
CALL CMND0 ;DO THE COMMAND
TLZ F,(AJCMF)
SETZM LCLIC
MOVE 1,LFORK ;RESTART THE FORK FOR MORE INPUT
MOVEI 2,FRKBGN
SFORK
JRST .+1]
;SEE IF ANYONE HAS WRITTEN COMMANDS VIA ^ESPEAK. CHOOSE THE CORRECT FILE BASED
;ON TESTSW. PROCESS THE COMMANDS, CLOSE THE FILE, AND DELETE IT.
;THE NEXT TIME SOMEONE DOES A ^SPEAK, A NEW FILE WILL BE CREATED.
MOVSI 1,(1B2+1B17)
HRROI 2,[ASCIZ /SYSTEM:SYSJOB.COMMANDS/]
SKIPE TESTSW ;TESTING SYSJOB?
HRROI 2,[ASCIZ /SYSJOB.TEST1/] ;YES, USE LOCAL FILE
GTJFN ;MORE COMMANDS?
JRST WAIT1 ;NO
MOVEM 1,INJFN
MOVE 2,[7B5+1B19]
OPENF
JRST WAIT2 ;FILE WON'T OPEN
CALL DOCMND ;GO READ AND PROCESS ALL COMMANDS IN THE FILE
MOVE 1,INJFN ;1/JFN FOR CURRENT FIE
HRLI 1,400000
CLOSF ;CLOSE BUT KEEP JFN
JFCL
WAIT2: HRROI 1,DIRNAM ;1/DESTINATION POINTER
MOVE 2,INJFN ;2/JFN FOR FILE
MOVX 3,<FLD(.JSAOF,JS%DIR)>+JS%PAF ;3/OUTPUT DIRECTORY ONLY
JFNS ;GET DIRECTORY FOR CURRENT FILE
ERJMP WAIT1 ;UNEXPECTED FAILURE. DON'T DELETE FILES
MOVE 1,INJFN ;1/JFN FOR CURRENT FILE
SETZ 2, ;2/VERSIONS TO BE SAVED
DELNF ;DELETE ALL VERSIONS OF THIS FILE
JFCL
MOVE A,INJFN ;1/ JFN OF FILE
RLJFN ;RELEASE IT
JFCL
MOVX A,RC%EMO ;1/ USE EXACT MATCH ONLY
HRROI B,DIRNAM ;2/POINTER TO DIRECTORY NAME
RCDIR ;CONVERT NAME TO NUMBER
ERJMP WAIT1 ;CAN'T DO EXPUNGE
MOVE B,C ;DIRECTORY NUMBER
SETZ A, ;NOTHING SPECIAL
DELDF ;EXPUNGE THE DIRECTORY
;SEE IF FORKS THAT WERE STARTED VIA 'RUN' COMMANDS ARE ALIVE. IF ONE
;HAS DIED, PRINT A MESSAGE
WAIT1: MOVSI NX,-NJOBS ;CHECK STATE OF ALL JOBS
SKIPN 1,FORKN(NX) ;JOB EXISTS?
WAIT4: AOBJN NX,.-1 ;NO, GO ON TO NEXT
JUMPGE NX,WAIT5 ;DONE WHEN ALL JOBS CHECKED
RFSTS
HLRZ 1,1
TRZ 1,400000 ;FLUSH FREEZE BIT IF ANY
CAIE 1,2 ;HALTED?
CAIN 1,3
JRST .+2 ;YES
JRST WAIT4 ;NO, OK
PMSG <** SYSJOB: subjob crashed, data follows: **
>
CALL PSTAT ;PRINT ITS STATE
CALL PMORT ;PRINT A POST-MORTEM
MOVE 1,FORKN(NX)
KFORK ;FLUSH IT
SETZM FORKN(NX)
SETZM NAME(NX)
JRST WAIT4
;EXAMINE ALL ADVANCE SCHEDULED JOBS TO SEE IF NOW TIME TO RUN
WAIT5: GTAD ;GET TIME NOW
MOVSI 5,-NAJOBS
SKIPN TIMES(5) ;JOB QUEUED HERE?
WAIT6: AOBJN 5,.-1 ;NO
JUMPGE 5,WAIT7 ;DONE WHEN ALL ENTRIES EXAMINED
CAMGE 1,TIMES(5) ;IS NOW .GE. DESIRED TIME?
JRST WAIT6 ;NO, LEAVE JOB IN QUEUE
SETZM TIMES(5) ;YES, REMOVE JOB FROM QUEUE
MOVEI 5,0(5) ;COMPUTE POINTER TO STORED COMMAND
IMULI 5,NAJCW
ADD 5,[XWD 440700,AJCMD]
MOVEM 5,AJCMP ;LEAVE POINTER FOR GCIN
TLO F,(AJCMF) ;NOTE COMMAND FROM STORED STRING
CALL CMND0 ;DO COMMAND
TLZ F,(AJCMF)
JRST WAIT5
;SEE IF PTY'S HAVE INPUT OR OUTPUT WAITING
WAIT7: CALL CHKPTY ;CHECK FOR PTY SERVICE
JRST WAITI ;MAIN LOOP
;DO COMMANDS FROM OPEN FILE
DOCMND: MOVE 1,INJFN
GTSTS
TXNE 2,GS%NAM ;IS THERE A NAME FOR THIS JFN?
TXNE 2,GS%EOF!GS%ERR ;YES. CAN READ MORE?
RET ;NO NAME OR EOF
;HERE WHEN INPUT FROM LOCAL TTY OR FILE IS WAITING. COPY ALL CHARACTERS TO CMDBUF
CMND0: MOVE 7,CMDPT0 ;POINT TO START OF CMDBUF INITIALLY
MOVEM P,CMNDP ;SAVE STACK FOR COMMAND ABORTS
CMND4: CALL GCIN ;READ ONE CHARACTER AND ECHO IT
CAIE 1,.CHLFD ;CHECK FOR COMMAND WORD TERMINATOR
CAIN 1," "
JRST CMND1 ;LINE FEED OR SPACE.
IDPB 1,7 ;COPY CHARACTER INTO CMDBUF
JRST CMND4 ;GO GET NEXT CHARACTER
;LINE FEED OR SPACE FOUND.
CMND1: MOVEM 1,TERMCH ;SAVE TERMINATOR
CAMN 7,CMDPT0 ;NULL COMMAND?
JRST [ CAIE 1,.CHLFD ;YES, BLANK LINE?
JRST CMND4 ;NO, TRY AGAIN
JRST CMDEND] ;YES
SETZ 1,
IDPB 1,7 ;PUT NULL ON STRING
;SEARCH FOR COMMAND IN TABLE AND DISPATCH TO ROUTINE TO PROCESS IT
MOVSI 5,-LCMTB ;SET TO SEARCH COMMAND TABLE
CMND2: MOVE 1,CMDPT0
HRRZ 2,CMNDTB(5) ;POINTER TO KNOWN COMMAND NAME
HRLI 2,440700
CALL STCOMP ;SKIP IF STRINGS NEQ
JRST [ HLRZ 1,CMNDTB(5) ;FOUND, DISPATCH TO IT
JRST 0(1)]
AOBJN 5,CMND2
;NOT FOUND. PRINT COMMAND AND ERROR MESSAGE
MOVE 1,TERMCH ;NOT FOUND, SCAN TO END OF LINE
CMND3: CAIN 1,.CHLFD
JRST [ PMSG < - unrecognized command.
>
JRST CMDEND]
CALL GCIN
JRST CMND3
;HERE TO IGNORE REST OF LINE
CMDFLS: SKIPA 1,TERMCH ;FLUSH REMAINDER OF LINE
CALL GCIN
CAIE 1,.CHLFD ;GOT TO EOL?
JRST .-2 ;NO, KEEP LOOKING
;HERE WHEN ENTIRE LINE PROCESSED
CMDEND: MOVE P,CMNDP ;RESTORE STACK
TLZE F,(AJCMF) ;WERE DOING STORED COMMAND?
RET ;YES, RETURN NOW
JRST DOCMND ;NO. GO GET NEXT ONE
;RUN COMMAND - 'RUN filespec'
;CREATES A FORK AND RUNS THE FILE 'FILESPEC' IN IT
.RUN: MOVE 1,TERMCH
CAIE 1," " ;PROPER TERMINATOR?
JRST CMDFLS ;NO
;COPY FILESPEC INTO CMDBUF
MOVE 7,CMDPT0 ;GATHER FILE NAME
RUN1: CALL GCIN ;READ AND ECHO A CHARACTER
CAIN 1,.CHLFD ;TERMINATES WITH EOL
JRST RUN2
IDPB 1,7 ;COPY CHARACTER INTO CMDBUF
JRST RUN1 ;GO GET NEXT CHARACTER
;LINE FEED FOUND. HAVE NAME OF FILE. GET A JFN ON THE FILE.
RUN2: SETZ 1,
IDPB 1,7 ;ADD NULL TO STRING
CALL IJFNT ;INIT THE JFN TABLE
MOVSI 1,(1B2)
MOVEM 1,JFNTAB
MOVEI 1,JFNTAB
MOVE 2,CMDPT0 ;FILENAME STRING
GTJFN
JRST [ JERR
JRST CMDEND] ;NOT FOUND, ETC.
PUSH P,1 ;SAVE THE JFN
;STORE THE FILENAME PORTION OF THE FILESPEC IN NAMBUF
HRROI 1,NAMBUF
HRRZ 2,0(P)
MOVSI 3,(1B8)
JFNS ;GET STRING CONTAINING NAME FIELD ONLY
;CREATE AN INFERIOR FORK AND GET THE FILE INTO IT.
MOVSI 1,(1B1) ;GIVE NEW FORK THIS FORK'S CAPABILITIES
CFORK ;CREATE THE FORK
JRST [ JERR
JRST CMDEND]
EXCH 1,0(P) ;1/JFN, STACK/FORK HANDLE
HRL 1,0(P) ;XWD FORK,JFN
GET ;GET THE FILE INTO THE NEW FORK
;STORE INFORMATION ABOUT THIS FORK IN NEXT SLOT IN TABLES
MOVSI NX,-NJOBS ;FORK READY TO GO, MAKE TABLE ENTRY
SKIPE FORKN(NX) ;AVAILABLE SLOT?
AOBJN NX,.-1 ;NO
JUMPGE NX,[PMSG <Tables full.
>
POP P,1 ;1/FORK HANDLE
KFORK ;KILL THE FORK
JRST CMDEND]
POP P,FORKN(NX) ;PUT FORK HANDLE IN TABLES
SETZM NAME(NX) ;SETUP TO PUT SIXBIT NAME IN TABLES
;CONVERT FIRST 6 CHARACTERS OF FILENAME TO SIXBIT AND STORE IN NAME TABLE
MOVEI 4,NAME(NX)
HRLI 4,440600
MOVE 3,[POINT 7,NAMBUF,-1]
MOVEI 2,6 ;MAX 6 CHARS
RUN4: ILDB 1,3
JUMPE 1,RUN3 ;END OF STRING
SUBI 1,40 ;CONVERT TO SIXBIT
IDPB 1,4
SOJG 2,RUN4
;START THE PROGRAM IN THE NEW FORK
RUN3: MOVE 1,FORKN(NX) ;NOW START THE JOB
SETZ 2, ;AT MAIN START LOC
SFRKV
JRST CMDEND
; PURGE COMMAND - 'PURGE fork-number'
;
; KILLS THE FORK WITH THE INDICATED NUMBER (NUMBERS DISPLAYED ON STATUS COMMAND)
.PURGE: CALL GETNUM ;GET FORK NUMBER
JRST KTASK ;KILL THE FORK
;KILL COMMAND - 'KILL name'
;KILLS THE FORK THAT IS RUNNING THE PROGRAM 'NAME'
.KILL: CALL GETNAM ;GET NAME FROM COMMAND STRING AND FIND FORK
; THAT IS RUNNING IT
JRST KTASK ;GO KILL THE FORK
;KTASK - ROUTINE TO KILL A SYSJOB FORK
;
;ACCEPTS IN NX/ FORK TABLE INDEX
;
; KILL AND PURGE COMMANDS BRANCH HERE
KTASK: MOVE 1,FORKN(NX)
KFORK ;KILL THE FORK
SETZM FORKN(NX) ;RELEASE SLOT
SETZM NAME(NX)
JRST CMDEND
;STOP COMMAND - 'STOP name'
;FREEZES THE FORK THAT IS RUNNING THE PROGRAM 'NAME'
.STOP: CALL GETNAM
MOVE 1,FORKN(NX)
FFORK
JRST CMDEND
;START COMMAND - 'START name'
;STARTS THE FORK THAT IS RUNNING THE PROGRAM 'NAME' (UNDOES STOP)
.START: CALL GETNAM
MOVE 1,FORKN(NX)
RFORK
JRST CMDEND
;STATUS COMMAND - 'STATUS'
.STAT: PMSG <SYSJOB status at >
MOVEI A,.PRIOU
SETO B,
MOVSI C,240
ODTIM ;DO TIMESTAMP
PMSG <
>
;SEARCH TABLE OF FORKS STARTED VIA RUN COMMANDS
MOVSI NX,-NJOBS ;SCAN ALL JOBS, PRINTING FORK STATUS
SKIPN FORKN(NX) ;SLOT IN USE?
STAT1: AOBJN NX,.-1 ;NO
JUMPGE NX,STAT2
CALL PSTAT ;PRINT THE STATUS
JRST STAT1
;SEARCH TABLE OF JOBS STARTED VIA JOB COMMANDS
STAT2: MOVSI NX,-NLINES ;SETUP TO CHECK ALL PTY LINES
STAT3: SKIPE JOBPTY(NX) ;EXISTS?
CALL PJSTAT ;YES, PRINT STATUS
AOBJN NX,STAT3
JRST CMDFLS
;PRINT STATUS FOR ONE PTY JOB
; ##: JOB ##, TTY ##, PROGRAM
PJSTAT: MOVEI 1,101
HRRZ 2,NX ;PRINT SYSJOB NUMBER
MOVE 3,[1B2+3B17+^D10] ;USING 3 COLUMNS
NOUT
JERR
MOVE 1,TTYJOB ;GET MONITOR JOB NUMBER FROM TTY
HLL 1,JOBPTY(NX)
TLZ 1,400000
GETAB
JERR
HLRZ 2,1
TRNE 2,1B18 ;JOB NUMBER EXISTS?
JRST [ PMSG <: No job
>
RET] ;NO FURTHER INFO
PMSG <: Job >
PUSH P,2 ;SAVE JOB NUMBER
MOVEI 1,101
MOVEI 3,^D10 ;PRINT JOB NUMBER IN DECIMAL
NOUT
JERR
PMSG <, TTY>
MOVEI 1,101
HLRZ 2,JOBPTY(NX) ;GET TTY NUMBER
TRZ 2,400000
MOVEI 3,^D8
NOUT
JERR
PMSG <, >
POP P,2 ;RECOVER JOB NUMBER
MOVE 1,JOBNAM ;GET NAME INDEX FOR JOB
HRL 1,2
GETAB
JERR
HRLZ 1,1
HRR 1,SNAMES ;GET SIXBIT NAME OF JOB
GETAB
JERR
MOVEM 1,2
MOVEI 4,6 ;SET TO PRINT 6 CHARS
PJS1: SETZ 1,
LSHC 1,6 ;SHIFT IN A CHAR
ADDI 1,40 ;CONVERT TO ASCII
PBOUT
PJS2: SOJG 4,PJS1
PMSG <
>
RET
;PRINT STATUS FOR 1 FORK
PSTAT: MOVEI 2,0(NX)
MOVEI 1,101
MOVE 3,[1B2+3B17+10]
NOUT ;PRINT LOCAL INDEX IN 3 CHAR FIELD
JFCL
MOVEI 2," "
BOUT
MOVEI 4,NAME(NX)
HRLI 4,440600
MOVEI 3,6 ;PRINT THE NAME, I.E. FIRST 6 CHARS
ILDB 2,4 ;OF FILE NAME
ADDI 2,40
BOUT
SOJG 3,.-3
MOVEI 2," "
BOUT
MOVE 1,FORKN(NX)
RFSTS ;GET FORK STATUS
PUSH P,2 ;SAVE PC
HLRZ 1,1
TRZE 1,400000 ;FROZEN?
JRST [ PUSH P,1 ;YES
PMSG <stopped, >
POP P,1
JRST .+1]
HRRO 1,FSTAB(1) ;MESSAGE FOR STATE OF FORK
PSOUT
PMSG < at >
POP P,2 ;PC
MOVEI 2,0(2)
MOVEI 1,101
MOVEI 3,10
NOUT
JFCL
PMSG < >
MOVEI 1,101 ;TIMESTAMP THE STATUS
SETO 2,
MOVSI 3,240
ODTIM
PMSG <
>
RET
;POST MORTEM FOR DEAD FORK
PMORT: PMSG < JSYS error: >
MOVEI 1,101
HRLO 2,FORKN(NX)
MOVEI 3,0
ERSTR ;DO MSG FOR MOST RECENT ERROR TO TTY
JFCL
JRST [ MOVE 1,FORKN(NX) ;FAILED TO FIND MSG, PRINT NUMBER
PUSH P,NX ;TEMP - UNTIL GETER FIXED
GETER ;GET ERROR CODE FOR FORK
POP P,NX ;TEMP - UNTIL GETER FIXED
MOVEI 1,101
HRRZ 2,2 ;PRINT ONLY ERROR CODE
MOVEI 3,10 ;IN OCTAL
NOUT
JFCL
JRST .+1]
MOVE 1,FORKN(NX) ;GET ACS FROM FORK
MOVEI 2,FRKACS
RFACS
PMSG <
Fork acs:>
MOVSI Q1,-4 ;TYPE ACS 1-4
CRASHL: PMSG < >
MOVE B,FRKACS+1(Q1)
MOVEI A,101
MOVEI C,10
NOUT ;PRINT AC IN OCTAL
JFCL
AOBJN Q1,CRASHL
PMSG <
>
SKIPN DBUGSW ;DEBUG MODE?
JRST NOFSTA ;NO, DON'T DO FILSTAT
PMSG < Fork 0 FILSTAT:
>
MOVEI Q1,77 ;SETUP TO SCAN ALL JFNS
FSTATL: HRRZ A,Q1
GTSTS ;GET STATUS OF JFN
TLNN B,(1B10) ;FILE HERE?
JRST FSTATN ;NO
PUSH P,B ;SAVE BITS
HRRZ B,Q1
MOVEI A,101
MOVE C,[3,,10] ;TYPE JFN NUMBER IN 3 PLACES
NOUT
JFCL
MOVEI B," "
BOUT
HRRZ B,Q1
MOVEI C,0
JFNS ;TYPE FILENAME
ERJMP [MOVEI B,"?" ;FAILED (CAN'T IMAGINE WHY)
BOUT
JRST .+1]
MOVEI B," "
BOUT
POP P,D ;RECOVER BITS
DEFINE BITMSG(N,XMSG)<
HRROI A,[ASCIZ \XMSG\]
TLNE D,(1B'N)
PSOUT>
JUMPL D,FSTAT1
PMSG <Not open >
FSTAT1: BITMSG (1,<READ>)
BITMSG (2,<WRITE >)
BITMSG (3,<XCT >)
BITMSG (9,<ERROR >)
PMSG <
>
FSTATN: SOJGE Q1,FSTATL
NOFSTA: RET
;ATTIME DATE TIME; COMMAND
;SEMICOLON DELIMITS TIME
.ATTM: MOVE 1,TERMCH
CAIE 1," " ;PROPER TERMINATOR?
JRST CMDFLS ;NO
MOVE 7,CMDPT0 ;SET TO READ DATIME STRING
ATTM1: CALL GCIN
CAIN 1,.CHLFD
JRST CMDEND ;EOL, SOMEBODY GOOFED
CAIN 1,";"
JRST ATTM2 ;END OF DATIME STRING
IDPB 1,7
JRST ATTM1
ATTM2: SETZ 1,
IDPB 1,7 ;STRING TERMINATOR
MOVE 1,CMDPT0
SETZ 2,
IDTIM ;CONVERT STRING TO INTERNAL FORMAT
JRST [ JERR ;DIDN'T WORK
JRST CMDFLS]
MOVSI 5,-NAJOBS ;FIND A FREE QUEUE SLOT
SKIPE TIMES(5)
AOBJN 5,.-1
JUMPGE 5,[PMSG <
No queue slots left.
>
JRST CMDFLS]
MOVEM 2,TIMES(5)
MOVEI 4,0(5) ;COMPUTE STRING PTR FOR COMMAND
IMULI 4,NAJCW
ADD 4,[XWD 440700,AJCMD]
MOVEI 3,NAJCW*5 ;MAX NUMBER CHARS IN STORED COMMAND
CALL GCIN
IDPB 1,4
CAIE 1,.CHLFD ;STORE TO EOL
SOJG 3,.-3 ;OR UNTIL STRING FULL
JUMPLE 3,[PMSG <
Command too long to be stored.
>
SETZM TIMES(5) ;REMOVE FROM QUEUE
JRST CMDFLS]
JRST CMDEND
;JOB COMMAND - 'JOB n /text/'
;TRANSMIT TEXT TO JOB IDENTIFIED BY N. FIRST OCCURRENCE CREATES A NEW
;JOB ON A PTY. DELIMITIERS CAN BE ANYTHING NOT IN TEXT
;THIS ROUTINE COPIES THE TEXT TO A BUFFER TO BE TRANSMITTED LATER BY
;CHKPIN
;THE CLEARING OF THE TTY INPUT BUFFER WAS ADDED AS A QUICK FIX FOR A
;BUG. IF THE USER TYPED A 'JOB' COMMAND AND FAILED TO TERMINATE IT
;WITH THE EXPECTED DELIMITER, THE COMMAND WAS WRITTEN OVER THE
;LAST 'JOB' COMMAND FOR THE SAME JOB. THUS THE REMAINDER OF THE
;PREVIOUS COMMAND WAS APPENDED TO THE NEW COMMAND.
;THIS BLT CLEARS THE BUFFER. IDEALLY WE WOULD CORRECTLY
;HANDLE THE OCCURRENCE OF AN END OF FILE WITHOUT FINDING THE DESIRED
;DELIMITER. PRESENTLY GCIN ASSUMES THE COMMAND HAS BEEN TERMINATED CORRECTLY
;WHEN END OF FILE IS DETECTED.
.JOB: CALL GJOBN ;GET JOB NUMBER
JRST CMDFLS ;FAILED
SKIPN JOBPTY(NX) ;HAVE A PTY HERE?
JRST [ CALL GETPTY ;NO, GET ONE
JRST CMDFLS ;NONE AVAILABLE
JRST .+1]
MOVE 1,TERMCH ;FIRST NON-DIGIT READ BY GJOBN (END OF NUMBER)
JOB4: CAIE 1," " ;VALID DELIMITER (NON-BLANK)?
JRST JOB3 ;YES.
CALL GCIN ;NO. GET NEXT CHARACTER
JRST JOB4 ;GO CHECK IT FOR DELIMITER
JOB3: MOVEM 1,TERMCH ;SAVE THE TERMINATOR
SKIPN JOBISP(NX) ;HAVE EXISTING INPUT?
JRST [ MOVEI 1,0(NX) ;NO. 1/JOB NUMBER IN COMMAND
CALL SETSP ;1/BYTE PTR TO START OF BUFFER FOR THIS JOB
MOVEM 1,2 ; SAVE PTR AND SET UP FOR TERMINATING BLT
SETZM 0(1) ;CLEAR FIRST WORD OF BUFFER
HRLS 1 ;BLT FROM FIRST WORD IN BUFFER
AOS 1 ; TO NEXT UNTIL END OF BUFFER
BLT 1,NWSBUF-1(2) ;CLEAR THE ENTIRE BUFFER
MOVEM 2,JOBISP(NX) ;START OF PTY INPUT
MOVEM 2,JOBISE(NX) ;END OF PTY INPUT
JRST .+1]
MOVEI P2,NWSBUF*5 ;SETUP TO COUNT CHARS IN STRING
JOB1: CALL GCIN ;GET CHARACTER FROM INPUT
CAME 1,TERMCH ;THE TERMINATOR?
JUMPN 1,[IDPB 1,JOBISE(NX) ;NO, APPEND IT TO STRING
SOJG P2,JOB1 ;LOOP UNLESS OUT OF STRING SPACE
JRST JOB2] ;FILLED UP STRING SPACE
SETZ 1, ;END OF STRING, APPEND NULL
MOVE 2,JOBISE(NX)
IDPB 1,2
JRST CMDFLS ;FLUSH UP TO NEXT EOL
JOB2: CALL GCIN ;FLUSH REST OF INPUT
CAME 1,TERMCH
JRST JOB2
PMSG <
Too much input for line.
>
JRST CMDFLS
;CCJOB COMMAND - 'CCJOB n'
;FORCES DOUBLE CONTROL-C TO JOB
.CCJOB: CALL GJOBN ;GET JOB NUMBER
JRST CMDFLS ;NO GOOD
SKIPN JOBPTY(NX) ;HAVE PTY HERE?
JRST CMDEND ;NO
HRRZ 1,JOBPTY(NX)
MOVEI 2,"C"-100 ;SEND CONTROL-C
BOUT
BOUT ;SEND TWO
JRST CMDEND
;KILLJOB COMMAND - 'KILLJOB n'
;CLOSES PTY AND RELEASES BUFFERS IF ANY
.KJOB: CALL GJOBN ;GET JOB NUMBER
JRST CMDFLS ;LOSER
SKIPN JOBPTY(NX) ;PTY HERE?
JRST CMDEND ;NO, NOTHING TO DO
HRRZ 1,JOBPTY(NX)
CLOSF ;CLOSE THE PTY - WILL DETACH JOB IF ANY
JERR ; STILL THERE
SETZM JOBPTY(NX) ;NOTE NO PTY HERE NOW
SETZM JOBISP(NX) ;NOTE GONE
SETZM JOBOSP(NX) ;NOTE GONE
JRST CMDEND
;SUBROUTINES FOR PTY LOGIC
;FIND A FREE PTY AND OPEN IT
GETPTY: PUSH P,P1
PUSH P,P2
PUSH P,P3
MOVEI P1,0 ;START WITH PTY0
GETPT1: HRROI 1,P2 ;CONSTRUCT A PTY IDENT STRING IN P2
HRROI 2,[ASCIZ /PTY/] ;START WITH NAME
SETZ 3,
SOUT
MOVE 2,P1
MOVEI 3,10
NOUT ;NUMBER (OCTAL) IS NEXT
JERR
HRROI 2,[ASCIZ /:/] ;THEN A COLON
SETZ 3,
SOUT
MOVSI 1,(1B2+1B17)
HRROI 2,P2 ;POINT GTJFN AT STRING JUST MADE
GTJFN ;TRY TO GET THIS PTY
JRST GETPT3 ;FAILED, PROBABLY ALREADY ASSIGNED
MOVEM 1,JOBPTY(NX) ;SO FAR SO GOOD, SAVE JFN
MOVE 2,[07B5+3B20] ;OPEN PTY FOR IN AND OUT
OPENF
JRST [ HRRZ 1,JOBPTY(NX) ;FAILED, CAN'T USE THIS ONE
RLJFN
JFCL
JRST GETPT3] ;GO TRY NEXT ONE
ADD P1,FIRPTY ;PTY OK, COMPUTE RELATED TTY NUMBER
TRO P1,400000 ;CONSTRUCT TTY DESIGNATOR
HRLM P1,JOBPTY(NX) ;SAVE IT FOR VARIOUS JSYSES
HLRZ 1,JOBPTY(NX) ;GET DESIGNATOR
MOVEI 2,.TTL36 ;SET TERMINAL TYPE TO LA36 SINCE
;OUTPUT GOES TO CTY
STTYP
HRRZ 1,JOBPTY(NX) ;ASSIGN INTERRUPT CHANNELS
MOVE 2,[1B0+1B1+<PTCHN>B17+.TTDPI]
MTOPR
HRRZ 1,JOBPTY(NX)
MOVEI 2,"C"-100 ;SEND A ^C TO STARTUP JOB
BOUT
ERJMP .+1 ;IGNORE FAILURE, PRESENCE OF JOB CHECKED LATER
GETPT4: POP P,P3
POP P,P2
POP P,P1
JUMPE 1,R ;RETURN BAD
RETSKP
GETPT3: CAIL P1,777 ;CHECK ALL POSSIBLE PTYS?
JRST [ PMSG <
No PTYs available.
>
SETZ 1, ;SIGNAL RETURN BAD
JRST GETPT4]
AOJA P1,GETPT1 ;GO CHECK NEXT PTY
;GET JOB NUMBER FROM COMMAND
GJOBN: MOVE 2,[POINT 7,3] ;COLLECT STRING BEFORE GIVING TO NIN
GJOBN2: CALL GCIN
CAIL 1,"0" ;IS A NUMBER?
CAILE 1,"9"
JRST GJOBN1 ;NO
IDPB 1,2 ;YES, APPEND TO STRING
TLNE 2,(7B2) ;TOO MANY DIGITS?
JRST GJOBN2 ;NO, KEEP GOING
PMSG <
Too many digits in job number.
>
RET
;FOUND NON-DIGIT
GJOBN1: MOVEM 1,TERMCH
SETZ 1,
IDPB 1,2 ;APPEND NULL
HRROI 1,1(P) ;SETUP PTR TO STACK
PUSH P,3
MOVEI 3,^D10
NIN ;READ JOB NUMBER IN DECIMAL
JERR
POP P,3 ;CLEAR STACK
CAIL 2,0 ;REASONABLE?
CAILE 2,NLINES
JRST [ PMSG <
Illegal job number.
>
RET]
MOVEM 2,NX ;RETURN IN USUAL INDEX
RETSKP
;ROUTINE TO CHECK EVERY PTY FOR INPUT OR OUTPUT NEEDED
CHKPTY: MOVSI NX,-NLINES ;SETUP TO CHECK ALL LINES
CHKPT1: SKIPE JOBPTY(NX) ;PTY HERE?
JRST [ CALL CHKPIN ;YES, CHECK INPUT
CALL CHKPOU ;CHECK OUTPUT
JRST .+1]
AOBJN NX,CHKPT1
RET
;CHKPIN - CHECK PTY FOR INPUT NEEDED
;ACCEPTS:
; NX/ JOB NUMBER (WITHIN SYSJOB, AS IN THE 'JOB' COMMAND)
; CALL CHKPIN
;RETURNS +1: ALWAYS
;THIS ROUTINE IS CALLED PERIODICALLY FOR EACH JOB THAT SYSJOB HAS
;CREATED ON A PTY. WHEN SYSJOB READS A 'JOB' COMMAND, IT STORES THE
;TEXT IN A BUFFER POINTED TO BY JOBISP(NX) (SEE .JOB). THIS ROUTINE WRITES
;THAT TEXT TO THE PTY IF THE CREATED JOB IS IN INPUT WAIT ON THE PTY
CHKPIN: CALL CHKPOU ;ALWAYS EMPTY THE OUTPUT BUFFER FIRST
SKIPN A,JOBISP(NX) ;INPUT WAITING?
RET ;NO
ILDB A,A ;MAYBE, GET FIRST CHAR
JUMPE A,[SETZM JOBISP(NX) ;NULL, CLEAR POINTER
RET] ;AND RETURN
HLRZ 1,JOBPTY(NX)
MOVEI 2,.TTTIH ;SETUP FUNCTION CODE
MTOPR ;GET INPUT HUNGRY STATUS
ERJMP R ;IF FAILS, ASSUME NOT HUNGRY
JUMPE 2,R ;JUMP IF NOT HUNGRY
CALL PTYINI ;SEE IF HAVE TO CREATE A JOB ON PTY
RET ;CAN'T MAKE A JOB, WAIT TILL LATER
HRRZ 1,JOBPTY(NX) ;PTY IS HUNGRY, GIVE IT A LINE
CHKPI1: ILDB 2,JOBISP(NX) ;GET NEXT CHARACTER OF INPUT
JUMPE 2,[SETZM JOBISP(NX) ;NOTE NO INPUT STRING
RET]
CAIN 2,ESCC ;OUR ESCAPE CHARACTER?
JRST DOESC ;YES
CAIN 2,.CHLFD ;EOL?
MOVEI 2,.CHCRT ;YES, CONVERT TO .CHCRT
CHKPI2: BOUT ;SEND THE CHAR
ERJMP [JERR ;REPORT FAILURE (PROBABLY INPUT BUFFER FULL)
JRST .+1]
CAIE 2,.CHCRT ;WAS END OF LINE?
JRST CHKPI1 ;NO, KEEP SENDING
JRST CHKPIN ;YES, SEE IF STILL HUNGRY
DOESC: ILDB 2,JOBISP(NX) ;GET CHAR AFTER THE ESCAPE
CAIN 2,ESCC ;ANOTHER ESCAPE?
JRST CHKPI2 ;YES, MEANS SINGLE ESCAPE
CAIN 2,"$" ;A $ ?
JRST [ MOVEI 2,ESC ;YES MEANS ESC (ALTMODE)
JRST CHKPI2]
CAIL 2,100 ;DOES CHAR HAVE CONTROL EQUIV?
CAIL 2,140
JRST CHKPI1 ;NO, SEND DIRECTLY
SUBI 2,100 ;YES, CONVERT TO CONTROL
BOUT ;SEND IT
ERJMP [JERR ;REPORT FAILURE
JRST .+1]
JRST CHKPIN ;SEE IF STILL HUNGRY
;ROUTINE TO CREATE A JOB ON A PTY IF NECESSARY. SKIP RETURN IF
;A JOB IS NOW ON THE PTY, NON-SKIP RETURN IF WE FAILED TO CREATE
;ANY JOB.
PTYINI: CALL PTYJBC ;SEE IF A JOB IS ALREADY ON THE PTY
JRST RSKP ;YES, GOOD RETURN
SKIPN C,PDELAY ;GET DELAY TIME
JRST PTYING ;PROCEED IF NO DELAY
TIME ;GET CURRENT TIME
CAMGE A,C ;TIME FOR ANOTHER ATTEMPT?
RET ;NO
SETZM PDELAY ;YES, CLEAR DELAY
PTYING: HRRZ A,JOBPTY(NX) ;GET JFN
MOVEI B,3 ;AND A CONTROL-C
BOUT ;SEND TO PTY TO CREATE A JOB
ERJMP .+1 ;IGNORE FAILURE, CHECKED BELOW
CALL PTYJBC ;SEE IF JOB WAS CREATED
JRST RSKP ;YES, RETURN OK
TIME ;GET CURRENT TIME
ADDI A,^D30000 ;ADD 30 SECONDS TO IT
MOVEM A,PDELAY ;SAVE AS NEXT ALLOWABLE TIME
RET ;RETURN BAD FOR NOW
;ROUTINE TO SEE IF A JOB EXISTS ON A PTY. IF THE JOB IS IN THE
;PROCESS OF BEING INITIALIZED, WE WAIT FOR IT TO COMPLETE.
;SKIP RETURN IF NO JOB IS ON THE PTY, NON-SKIP IF A JOB IS THERE.
PTYJBC: HLL A,JOBPTY(NX) ;GET TTY DESIGNATOR
TLZ A,400000 ;TURN IT INTO A TTY NUMBER
HRR A,TTYJOB ;GET TABLE NUMBER FOR TTYJOB
GETAB ;SEE IF LOGGED IN
JRST RSKP ;FAILED, ASSUME NO JOB
JUMPGE A,R ;IF JOB NUMBER SET UP, THEN OK
HLRZ A,A ;GET LEFT HALF
CAIE A,-2 ;UNASSIGNED?
JRST RSKP ;YES
MOVEI A,^D250 ;NO, BEING ASSIGNED
DISMS ;GIVE IT A CHANCE TO FINISH
JRST PTYJBC ;AND CHECK AGAIN
;CHECK FOR OUTPUT AVAILABLE ON LINE
CHKPOU: HLRZ 1,JOBPTY(NX) ;GET TTY DESIG
SOBE ;ANYTHING IN OUTPUT BUFFER?
SKIPA ;YES, GET IT
RET
HRRZ 1,JOBPTY(NX) ;1/JFN OF PTY
BIN ;GET ONE OUTPUT CHARACTER
JUMPE 2,CHKPOU ;IGNORE NULL
SKIPN JOBOSP(NX) ;HAVE A BUFFER FOR OUTPUT?
JRST [ MOVEI 1,NLINES(NX) ;NO, SETUP OUTPUT BFR
CALL SETSP
MOVEM 1,JOBOSP(NX) ;SETUP POINTER
JRST .+1]
IDPB 2,JOBOSP(NX) ;PUT IN OUTPUT STRING
CAIE 2,.CHLFD ;END OF LINE?
JRST CHKPOU ;NO, TRY TO GET MORE
SETZ 2, ;YES, TERMINATE STRING
IDPB 2,JOBOSP(NX)
CHKPO2: MOVEI 1,101
RFPOS ;SEE WHERE CHARRIAGE IS NOW
HRRZ 2,2
JUMPE 2,CHKPO1 ;DO CRLF IF NOT AT LEFT MARGIN
PMSG <
>
CHKPO1: PMSG <SJ > ;BEGIN THE HEADER
MOVEI 1,101
HRRZ 2,NX
MOVE 3,[1B2+2B17+^D10]
NOUT ;PRINT JOB NUMBER NEXT
JERR
PMSG <: >
MOVEI 1,NLINES(NX)
CALL SETSP ;REINIT POINTER
MOVE 2,1
MOVEI 1,101
SETZ 3,
SOUT ;OUTPUT THE JOB'S LINE
SETZM JOBOSP(NX)
JRST CHKPOU
;NORMALIZE PTR TO BEGINNING OF BUFFER
NORMSP: HRRZ 1,1 ;REDUCE ADDRESS TO BUFFER NUMBER
SUBI 1,SBUF
IDIVI 1,NWSBUF
SETSP: IMULI 1,NWSBUF ;CONVERT TO STRING PTR FOR RELATED
ADDI 1,SBUF ; BUFFER
HRLI 1,(<POINT 7,0>)
RET
;GET CHAR FROM INPUT FILE, COPY TO PRIMARY OUTPUT FOR INFO
;IF F HAS AJCMF BIT SET, INPUT COMES FROM A BUFFER RATHER THAN A FILE
;AND AJCMP HAS POINTER TO BUFFER
GCIN: TLNE F,(AJCMF) ;FROM STORED COMMAND?
JRST [ ILDB 1,AJCMP ;YES
PBOUT ;REPORT IT
RET]
;INPUT IS VIA JFN
PUSH P,2
MOVE 1,INJFN ;1/JFN FOR INPUT
GCIN0: BIN ;READ A CHARACTER
ERJMP CMDEND ;IF ANY SORT OF ERROR, DONE
CAIN 2,.CHCRT
JRST GCIN0 ;YES. SKIP IT
JUMPE 2,CMDEND ;NULL - ASSUME EOF
CAIN 1,100 ;INPUT FROM PRIMARY?
JRST GCIN1 ;YES, ECHO ALREADY DONE
MOVEI 1,101
BOUT
GCIN1: CAIL 2,"A"+40 ;IF LOWERCASE A-Z CONVERT TO UPPER CASE
CAILE 2,"Z"+40
JRST GCIN2 ;NOT LOWER CASE
SUBI 2,40 ;CONVERT TO LOWER CASE
GCIN2: MOVE 1,2 ;RETURN CHARACTER IN 1
POP P,2
RET
;INITIALIZE JFN TABLE
IJFNT: MOVE 1,[XWD IJFNTT,JFNTAB]
BLT 1,JFNTAB+7
RET
IJFNTT: 0
XWD 377777,377777 ;NO FILE I/O
-1,,[ASCIZ /SYS/] ;DEFAULT TO SYS
0
0
XWD -1,[ASCIZ /EXE/] ;DEFAULT TO .EXE
0
0
;COMPARE STRINGS IN 1,2
;SKIP IF NOT EQUAL
STCOMP: PUSH P,1
PUSH P,2
STC1: ILDB 1,-1(P)
ILDB 2,0(P)
CAIN 1,0(2)
JUMPN 1,STC1 ;EQUAL SO FAR, END OF STRINGS?
CAIE 1,0(2) ;END OR NOT EQUAL, WHICH?
AOS -2(P) ;NOT EQUAL, SKIP RETURN
POP P,2
POP P,1
RET
;A COMMAND OF THE FORM 'KEYWORD name' HAS BEEN FOUND. GET THE NAME
;FROM THE COMMAND AND FIND THE FORK THAT IS RUNNING THAT PROGRAM
;RETURNS INDEX INTO FORK TABLES IN FX
GETNAM: MOVE 1,TERMCH
CAIE 1," " ;PROPER TERMINATOR?
JRST CMDFLS ;NO
MOVEI 6,6 ;LIMIT OF 6 CHARACTERS IN NAME
SETZ 7, ;INITIALIZE TO STORE NAME IN AC 7
MOVE 5,[POINT 6,7,-1]
GETN2: CALL GCIN ;READ AND ECHO A CHARACTER
CAIE 1,.CHLFD ;LINE FEED?
CAIN 1," " ; OR SPACE?
JRST GETN1 ;YES. END OF NAME
JUMPLE 6,GETN2 ;DON'T STORE CHAR IF ALREADY HAVE 6
SUBI 1,40 ;CONVERT TO SIXBIT
IDPB 1,5 ;ADD TO NAME IN AC 7
SOJA 6,GETN2 ;GO GET NEXT CHARACTER
;FIND THIS NAME IN TABLE OF PROGRAMS BEING RUN.
GETN1: MOVSI NX,-NJOBS
CAME 7,NAME(NX) ;NAME MATCH?
AOBJN NX,.-1 ;NO
JUMPGE NX,[PMSG <Name not found.
>
JRST CMDEND]
RET
;GETNUM - ROUTINE TO RETURN A FORK NUMBER FROM A COMMAND IN NX
GETNUM: MOVE 1,TERMCH
CAIE 1," " ;PROPER TERMINATOR?
JRST CMDFLS ;NO
MOVEI 6,4 ;LIMIT OF 4 CHARACTERS IN NUMBER
SETZ 7, ;INITIALIZE TO STORE NUMBER IN AC 7
MOVE 5,[POINT 7,7,-1] ;GET POINTER FOR STORING NUMBER
GETNU2: CALL GCIN ;READ AND ECHO A CHARACTER
CAIE 1,.CHLFD ;LINE FEED?
CAIN 1," " ; OR SPACE?
JRST GETNU1 ;YES. END OF NAME
JUMPLE 6,GETNU2 ;DON'T STORE CHAR IF ALREADY HAVE 6
IDPB 1,5 ;ADD TO NAME IN AC 7
SOJA 6,GETNU2 ;GO GET NEXT CHARACTER
; HERE WITH NUMBER IN ASCII IN AC 7
GETNU1: MOVEI 1,.CHNUL ;GET A NULL
IDPB 1,5 ;STORE IN NUMBER
HRROI 1,7 ;GET POINTER TO NUMBER
MOVEI 3,10 ;OCTAL
NIN ;INPUT THE NUMBER
JRST CMDFLS ;FLUSH COMMAND
MOVE NX,2 ;COPY THE FORK NUMBER
RET ;DONE, RETURN
;JSYS ERROR
JERR0: PMSG <
?JSYS error: >
ERMSG: MOVEI 1,101
HRLOI 2,.FHSLF
SETZ 3,
ERSTR
JFCL
JFCL
PMSG <
>
RET
;NUMBER PRINTERS
DECOUT: SKIPA C,[^D10]
OCTOUT: MOVEI C,^D8
MOVX A,.PRIOU
NOUT
JFCL
RET
;PSI STUFF
LEVT: PCL1
PCL2
PCL3
;PUTS CHANNEL NUMBER IN LOCATION IN CHNN CORRESPONDING TO LEVEL WITHOUT
;DISTURBING ANY AC'S; THEN GOES TO LOCATION TO PROCESS INTERRUPT
DEFINE CHNE (LVL,LOC)
< XWD LVL,[MOVEM 1,CHNN+LVL-1
MOVEI 1,.-CHNT
EXCH 1,CHNN+LVL-1
JRST LOC]
>
RADIX 10
CHNT: CHNE (2,INTCH) ;0 - INTERRUPT CH
CHNE (2,RSTCH) ;1 - INTERRUPT CH
CHNE (3,PTINI) ;PTY INPUT
CHNE (3,PTOUI) ;PTY OUTPUT
REPEAT 9-4,<CHNE (1,BADI)> ;4 - 8, NOT ENABLED
CHNE (1,BADI) ;9 - PDL OV
CHNE (1,BADI) ;10 - NOT ENABLED
CHNE (1,IGNOR) ;11 - FILE ERROR
REPEAT 15-12,<CHNE (1,BADI)> ;12-14 NOT ENABLED
CHNE (1,BADI) ;15 - ITRAP
CHNE (1,BADI) ;16 - MR TRAP
CHNE (1,BADI) ;17 - MW TRAP
CHNE (1,BADI) ;18 - MX TRAP
CHNE (3,FRKTRM) ;19 - FORK TERMINATED
CHNE (1,BADI) ;20 - MACH SIZE TRAP
REPEAT 36-21,<CHNE (1,BADI)> ;21-35, NOT ENABLED
RADIX 8
CHNMSK: 1B0+1B1+3B<PTCHN+1>+1B9+1B11+1B15+1B16+1B17+1B18+1B19+1B20
;INT CHAR, FRK TRM, ALL PANIC CHANS
;PSI HANDLERS
IGNOR: DEBRK
;^C
INTCH: JSP 4,LRSET
PMSG <
SYSJOB: ^C, restarting...
>
JRST START ;DO NORMAL START
;^B - RELOAD AND RESTART SYSJOB
RSTCH: MOVE 1,INJFN ;SEE IF HAVE INPUT FILE
CAIL 1,1
CAIL 1,100 ;IS A JFN?
JRST RSTC1 ;NO
GTSTS ;YES, GET STATUS
TLNN 2,(1B10) ;EXISTS?
JRST RSTC1 ;NO
HRLI 1,(1B0) ;YES, CLOSE AND DELETE IT
CLOSF
JFCL
HRLI 1,0
DELF ;DELETE AND RELEASE JFN
JFCL
RSTC1: JSP 4,LRSET ;RESET EVERYTHING
PMSG <
SYSJOB: reloading self...
>
MOVSI 1,(1B2+1B17)
HRROI 2,[ASCIZ /SYSTEM:SYSJOB.EXE/]
GTJFN
JRST [ JERR ;SUPER LOSSAGE...
JRST START] ;TRY TO KEEP RUNNING THIS ONE
HRLI 1,.FHSLF
MOVE 2,[GET] ;PUT PROGRAM IN ACS
MOVE 3,[MOVEI 1,.FHSLF] ;AFTER GET, CHECK ENTRY VECTOR
MOVE 4,[GEVEC]
MOVE 5,[JRST 0(2)] ;START NEW LOAD AT MAIN START
JRST 2
BADI: MOVX A,.FHSLF
CIS ;UNDO ALL INTERRUPTS
MOVE P,[IOWD NPDL,PDL] ;RESET STACK
PMSG <
** SYSJOB: unexpected interrupt on channel >
MOVE 2,CHNN ;CHANNEL NUMBER FOR LEV 1
CALL DECOUT
PMSG <, PC=>
MOVE B,PCL1 ;PC FOR LEVEL 1
CALL OCTOUT
PMSG < **
Last error message is:
>
CALL ERMSG
JRST WAITI ;RESTART MAIN LOOP
LRSET: MOVEI 1,400000
SETO 2,
DIC
DIR
MOVEI 1,-4
KFORK
CIS
JRST 0(4)
;FORK TERMINATED - WAKE UP RIGHT AWAY TO REPORT IT
FRKTRM: TLO F,(FRKTMF)
PUSH P,1
HRRZ 1,PCL3 ;PC AT INTERRUPT
CAIE 1,WAITPC+1 ;AT DISMS?
JRST FRKT1 ;NO, RUNNING, WILL NOTICE FLAG
MOVSI 1,010000 ;YES, SET USER FLAG TO RUN
HLLM 1,PCL3
FRKT1: POP P,1
DEBRK
;PTY ACTIVITY
;DO PTY SERVICE AT INTERRUPT LEVEL IF MAIN PRG IS IN HIBER.
;NOTE ACS (EXCEPT 1) ASSUMED CLOBBERABLE DURING HIBER.
PTINI:
PTOUI: PUSH P,1
HRRZ 1,PCL3 ;CHECK PC OF MAIN PRG
CAIE 1,WAITPC+1 ;AT HIBER?
JRST [ TLO F,(FRKTMF) ;NO, REQUEST ADDITIONAL CHECK
JRST PTI1]
CALL CHKPTY ;MAIN PRG IN HIBER, DO PTY NOW
PTI1: POP P,1
DEBRK
;COMMAND TABLE
DEFINE CM (LOC,NAME)
< XWD LOC,[ASCIZ /NAME/]
>
CMNDTB: CM (.RUN,RUN)
CM (.KILL,KILL)
CM (.PURGE,PURGE)
CM (.START,RESUME)
CM (.STOP,FREEZE)
CM (.STAT,STATUS)
CM (.ATTM,ATTIME)
CM (RSTCH,RELOAD)
CM (.JOB,JOB)
CM (.KJOB,KILLJOB)
CM (.CCJOB,CCJOB)
LCMTB==.-CMNDTB
CMDPT0: POINT 7,CMDBUF,-1 ;COMMAND BUFFER INITIAL PTR
;FORK STATE DESCRIPTION MESSAGES
FSTAB: Z [ASCIZ /Running/]
Z [ASCIZ /IO wait/]
Z [ASCIZ /Halted/]
Z [ASCIZ /Crashed/]
Z [ASCIZ /Fork wait/]
Z [ASCIZ /DISMS/]
NFSTAB==.-FSTAB
VTXT: .CLNAM ;CREATE VERSION TEXT
XLIST ;'LIT' FOLLOWS
LIT ;KEEP LITERALS WITH CODE
LIST ;END OF 'LIT'
;STORAGE
BLOCK 1000 ;PUT STORAGE IN SEPARATE PAGE FROM CODE
STGBGN: BLOCK 0 ;CLEAR FROM HERE TO STGEND ON STARTUP
PCL1: BLOCK 1
PCL2: BLOCK 1
PCL3: BLOCK 1
CHNN: BLOCK 3
CMNDP: BLOCK 1
PDL: BLOCK NPDL
LOCAL: BLOCK 2 ;LOCAL NODE NAME
PDELAY: BLOCK 1
CMDBUF: BLOCK 30
NAMBUF: BLOCK 11
TERMCH: BLOCK 1
INJFN: BLOCK 1
DBUGSW: BLOCK 1
JFNTAB: BLOCK 10
FRKACS: BLOCK 20 ;ACS FOR DEAD INFERIOR
JOBPTY: BLOCK NLINES ;TTY DESIG,,PTY JFN
JOBISP: BLOCK NLINES ;BYTE POINTER TO PTY INPUT
JOBISE: BLOCK NLINES ;BYTE PTR TO END OF PTY INPUT
JOBOSP: BLOCK NLINES ;BYTE POINTER TO PTY OUTPUT
SBUF: BLOCK NLINES*2*NWSBUF ;STRING BUFFERS
LCLIC: BLOCK 1 ;COUNT OF COMMANDS FROM LOCAL TTY
LCLBF: BLOCK NLCLBF ;BUFFER FOR LOCAL COMMANDS
LFORK: BLOCK 1 ;HANDLE FOR LOCAL INPUT FORK
FIRPTY: BLOCK 1 ;TTY NUMBER OF FIRST PTY
TTYJOB: BLOCK 1 ;TABLE NUMBER FOR TTYJOB
JOBNAM: BLOCK 1 ; " " JOBNAM
SNAMES: BLOCK 1 ; " " SNAMES
DIRNAM: BLOCK 10 ;BUFFER FOR NAME OF DIRECTORY (USED AT WAIT2)
;ATTIME TABLES
TIMES: BLOCK NAJOBS
AJCMD: BLOCK NAJOBS*NAJCW ;STORED COMMAND STRINGS
AJCMP: BLOCK 1
;JOB TABLES - DO NOT REORDER
;ONE ENTRY PER FORK STARTED VIA 'RUN' COMMAND
FORKN: BLOCK NJOBS ;FORK HANDLE
NAME: BLOCK NJOBS ;SIXBIT NAME
STGEND: BLOCK 0 ;CLEAR FROM STGBGN TO HER ON STARTUP
;LOCATIONS FROM HERE ON ARE NOT CLEARED ON STARTUP
TESTSW: BLOCK 1 ;NON-0 IF TESTING SYSJOB
END <3,,EVEC>