Trailing-Edge
-
PDP-10 Archives
-
BB-J710A-BM
-
tools/sysdpy/sysdpy.mac
There are 31 other files named sysdpy.mac in the archive. Click here to see a list.
;<4.1.UTILITIES>SYSDPY.MAC.6, 20-Jan-80 11:57:21, EDIT BY DBELL
;501 - SET UP FR.END AS INITIAL FLAGS SO SPACE IN RSCAN LINE DOESN'T SCROLL
;<4.1.UTILITIES>SYSDPY.MAC.5, 16-Jan-80 21:29:38, EDIT BY DBELL
;500 - ADD RP20 DATA AND CODE TO HANDLE CONTROLLERS IN DISK DISPLAY
;<4.1.UTILITIES>SYSDPY.MAC.3, 14-Jan-80 19:34:03, EDIT BY DBELL
;477 - HAVE SPACE CHARACTER SCROLL THE SCREEN WITHOUT CARRIAGE RETURN NEEDED
;476 - MAKE DECNET CORE IN RESOURCE DISPLAY SHOW RIGHT VALUE
;<4.UTILITIES>SYSDPY.MAC.69, 28-Oct-79 12:16:19, EDIT BY DBELL
;475 - SPLIT UP ARPANET DISPLAY INTO TWO SEPARATE DISPLAYS
;474 - FIX SOME XLISTS SINCE NEW MACRO MAKES CREFS LOOK BAD NOW
;<4.UTILITIES>SYSDPY.MAC.68, 27-Oct-79 22:27:43, EDIT BY DBELL
;473 - SET UP AN INTERRUPT FOR FORK TERMINATIONS
;<4.UTILITIES>SYSDPY.MAC.67, 27-Oct-79 21:08:06, EDIT BY DBELL
;472 - DON'T KILL EXEC WHEN IT POPS BACK, ADD "KE" COMMAND TO KILL IT
;<4.UTILITIES>SYSDPY.MAC.65, 24-Oct-79 20:15:45, EDIT BY DBELL
;471 - CHANGE POPJ P, TO RET AND JRST CPOPJ1 TO RETSKP
;470 - TYPE +INFINITY FOR DISK QUOTAS IF INFINITE
;<4.UTILITIES>SYSDPY.MAC.64, 3-Sep-79 20:19:07, EDIT BY DBELL
;467 - DON'T SHOW AN OFN FOR A JFN WHICH IS NOT OPEN
;<4.UTILITIES>SYSDPY.MAC.63, 31-Jul-79 13:29:30, EDIT BY DBELL
;466 - SET FAILURE FLAG PROPERLY FOR UNKNOWN SYMBOLS AT UNKSYM+1
;<4.UTILITIES>SYSDPY.MAC.62, 30-Jun-79 14:38:48, EDIT BY DBELL
;465 - MAKE THE ENQ DISPLAY SCROLL AS IT SHOULD
;<4.UTILITIES>SYSDPY.MAC.61, 28-Jun-79 21:35:59, EDIT BY DBELL
;464 - DON'T DO A RLJFN AFTER A GET JSYS
;<4.UTILITIES>SYSDPY.MAC.60, 10-Jun-79 16:57:05, EDIT BY DBELL
;463 - CHANGE BUFSIZ TO BUFLEN SO DEFINITION IN ORNMAC ISN'T FOUND
;<4.UTILITIES>SYSDPY.MAC.59, 3-Jun-79 16:48:36, EDIT BY DBELL
;462 - DON'T DO A RLJFN AFTER A CLOSF IN NEWDPY
;<4.UTILITIES>SYSDPY.MAC.58, 2-Jun-79 14:15:54, EDIT BY DBELL
;461 - START USING STANDARD TOPS-20 EDIT HISTORY CONVENTIONS, AND
; REMOVE OLD EDIT HISTORY.
TITLE SYSDPY PROGRAM TO WATCH EVERYTHING
SUBTTL DEFINITIONS/DAVID I. BELL
;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 BY DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
;PROGRAM TO DISPLAY VARIOUS SORTS OF INFORMATION ABOUT THE SYSTEM
;SUCH AS GENERAL JOB STATUS, SPECIFIC JOB STATUS, THE QUEUES,
;DECNET INFORMATION, ETC.
SEARCH DPYDEF ;SEARCH DPY DEFINITIONS
SEARCH MACSYM,MONSYM,JOBDAT ;AND MONITOR DEFINITIONS
SEARCH GLXMAC,QSRMAC,ORNMAC ;AND GALAXY DEFINITIONS TOO
.REQUES DPY ;ASK TO LOAD DPY
SALL ;MAKE FOR NICE MACROS
VERSION==4 ;VERSION NUMBER
EDIT==501 ;EDIT NUMBER
;ACCUMULATORS:
F=0 ;FLAGS
T1=1 ;TEMPORARY AC'S
T2=2
T3=3
T4=4
C=5 ;CHARACTER HOLDING
J=6 ;JOB NUMBER CURRENTLY WORKING ON
R=7 ;ROUTINE TO CALL FOR DPYING
I=10 ;INDEX INTO RUNTIME TABLES
P=17 ;STACK
FX==7 ;MONITOR AC - MUST MATCH MONITOR!!
P1==10 ;ANOTHER ONE
P2==11 ;ANOTHER MONITOR AC
P3==12 ;ANOTHER ONE
CX==16 ;AND ANOTHER MONITOR AC
;FLAGS:
FR.JSY==1B0 ;WE CAN USE THE "MONRD% JSYS"
FR.TAC==1B1 ;ONLY SHOW ACTIVE TERMINALS
FR.MOR==1B2 ;MORE COLUMNS ARE AFTER THIS ONE
FR.CPR==1B3 ;THE CPU PERCENTAGE TABLE IS READY
FR.RSN==1B4 ;INPUT CHARACTER NEEDS REREADING
FR.NEG==1B5 ;NEXT COMMAND'S ACTION IS NEGATED
FR.TMP==1B6 ;TEMPORARY USE INSIDE VARIOUS LOOPS
FR.NOC==1B7 ;DON'T CONVERT THE LABEL CHARACTER
FR.ACT==1B8 ;SHOW ONLY ACTIVE DECNET LINKS
FR.CMP==1B9 ;REMOVE HEADER LINES TO COMPRESS OUTPUT
FR.HDR==1B10 ;HEADER LINE HAS BEEN GIVEN
FR.OPR==1B11 ;SHOW OPERATOR JOBS IN DISPLAY
FR.EAT==1B12 ;SET UP EATING AFTER HEADER TYPEOUT
FR.END==1B13 ;PREVIOUS SCREEN WAS LAST ONE OF DISPLAY
FR.NDC==1B14 ;CRLF IS NEEDED BEFORE NEXT DISPLAY
FR.UDB==1B15 ;UDB IS VALID TO LOOK AT
FR.UDS==1B16 ;SYMBOLS FOR UDB HAVE BEEN OBTAINED
FR.INS==1B17 ;WE ONLY WANT TO INSERT THE MONRD% JSYS
FR.REF==1B18 ;REFRESH THE SCREEN
FR.RFC==1B19 ;CLEAR THE SCREEN WHEN REFRESHING
;COLUMN DEFINITIONS:
CL.TYP==0 ;TYPE OF COLUMN THIS IS
CL.VAL==1 ;VALUE FOR ORDERING OUTPUT
CL.DSP==2 ;ROUTINE TO TYPE DATA FOR COLUMN
CL.SIZ==3 ;WIDTH OF COLUMN
CL.TXT==4 ;ASCIZ TEXT FOR HEADER TO COLUMN
;THE FOLLOWING SYMBOLS ARE DEFINED IN THE MONITOR IN SUCH A WAY THAT
;ONE CANNOT OBTAIN THEM BY SNOOPING OR LOOKING IN A TABLE (THEY ARE
;ONLY DEFINED IN A DEFSTR MACRO). NONE OF THESE VALUES CHANGING WILL
;EVER CRASH THE MONITOR. INCORRECT VALUES WILL ONLY MAKE THE DATA
;RETURNED BY THE MONRD% JSYS BE INCORRECT.
;FIELDS DEFINED IN HEADER BLOCKS OF IPCF MESSAGES:
PD.CNT==POINT 9,0,35 ;NUMBER OF OUTSTANDING MESSAGES
PD.FLG==POINT 12,1,11 ;FLAG BITS
PD.FKW==POINT 18,1,35 ;FORK WAITING FOR MESSAGE
PD.FKO==POINT 18,2,35 ;FORK WHICH OWNS THIS PID
;FLAG BITS IN THE IPCF HEADER:
PD%DIS==4 ;PID IS DISABLED
;FLAGS IN THE SYSFK TABLE:
SFEXO==1B1 ;FORK IS EXECUTE-ONLY
SFNVG==1B2 ;FORK IS NOT A VIRGIN
SFGXO==1B3 ;FORK IS DOING GET OF EXECUTE-ONLY PROG
;MACROS:
DEFINE $$(SYM,MOD),< ;;PRODUCES SYMBOL DATA FOR SNOOPING
ADDR==.-1 ;;GET LOCATION OF THIS INSTRUCTION
XLIST ;;SUPPRESS LISTING
RELOC ;;RETURN TO NORMAL RELOCATION
EXP ADDR ;;DUMP THE ADDRESS OF THE INSTRUCTION
RADIX50 0,SYM ;;AND THE SYMBOL NAME
RADIX50 0,MOD ;;AND THE MODULE NAME
EXP .FAIL. ;;AND ADDRESS TO SET IF SYMBOL LOOKUP FAILS
LOC ;;RETURN TO ABSOLUTE CODE
LIST ;;ALLOW LISTING AGAIN
>
.FAIL.==0 ;INITIALIZE FAILURE ADDRESS
DEFINE ND(SYM,VAL),< ;;DEFINES DEFAULT VALUES FOR SYMBOLS
IFNDEF SYM,<SYM==VAL> ;;IF NOT DEFINED YET, DO SO NOW
>
DEFINE STS(BIT,TEXT),< ;;GENERATES FORK STATUS INFORMATION
<BIT>B0+[ASCIZ"TEXT"]
>
DEFINE IERR(TEXT),< ;;FOR ERRORS WHEN STARTING "MONRD%" JSYS
JRST [HRROI T1,[ASCIZ/
? TEXT
/] ;;GET STRING
JRST IERRTP] ;;THEN GO TYPE IT
>
;MACROS TO GENERATE MASKS AND OFFSETS FROM A BYTE POINTER:
DEFINE PW(PTR),<<<PTR>&^O777777>>
DEFINE PM(PTR),<<<<1_<<<PTR>_-^D24>&^O77>>-1>_<<PTR>_-^D30>>>
DEFINE SERR(TEXT),< ;;FOR ERRORS WHEN DOING SNOOPS
JRST [HRROI T1,[ASCIZ/
? TEXT: /] ;;GET STRING
JRST SERRTP] ;;THEN GO TYPE IT
>
DEFINE UU(ARGS),< ;;GENERATE TABLE OF UUOS
XLIST
IRP ARGS,<
SIXBIT /ARGS/
>
LIST
>
DEFINE NOSKED,< ;;PREVENT SCHEDULING
JSP CX,$$(NOSKD0,SCHED)
>
DEFINE OKSKED,< ;;ALLOW SCHEDULING AGAIN
JSP CX,$$(OKSKD0,SCHED)
>
DEFINE NOINT,< ;;PREVENT CONTROL-C'S
AOS $$(INTDF,STG)
>
DEFINE OKINT,< ;;ALLOW THEM AGAIN
XCT $$(INTDFF,STG)
>
DEFINE RESCAN,<
TXO F,FR.RSN ;;SET THE REREAD FLAG
>
;DEFAULT PARAMETERS:
ND FTPRIV,-1 ;-1 IF MONRD% JSYS IS TO BE PRIVILEGED
ND .MSR20,24 ;**TEMPORARY UNTIL IN MONSYM** RP20 UNIT TYPE
ND NWFKPT,2433 ;MONITOR VERSION FOR NEW FKPT FORMAT
ND JSYNUM,717 ;SPECIAL SYSTAT JSYS NUMBER
ND TAKMAX,5 ;MAXIMUM DEPTH OF NESTED TAKE COMMANDS
ND LBLCHR,":" ;CHARACTER IN INDIRECT FILE FOR LABELS
ND ACTTIM,1 ;MINUTES TO CONTINUE SHOWING ACTIVE TERMINALS
ND PERCOL,2 ;COMPRESSION FACTOR FOR HISTOGRAM
ND DFTLBL,'SYSDPY' ;DEFAULT LABEL TO LOOK FOR IN SYSDPY.INI
ND DATLOC,274000 ;PAGES FOR COLLECTION OF DATA
ND DATSIZ,3000 ;SIZE OF THE BLOCK
ND ERRNUM,^D30 ;NUMBER OF ERROR STRINGS TO KNOW ABOUT
ND ERRSIZ,^D15 ;WORDS TO HOLD EACH ERROR STRING
ND ENQSAF,^D55 ;SAFETY MARGIN FOR BUFFER OVERFLOW
ND IPCSIZ,^D100 ;STORAGE FOR PIDS OF A JOB
ND LCKMAX,^D100 ;NUMBER OF ENQ LOCKS WE CAN SHOW
ND SNPLOC,277000 ;LOCATION OF CODE FOR SNOOP JSYS
ND UDBSIZ,^D50 ;SIZE OF BLOCK TO READ UDB INTO
ND PDLSIZ,40 ;STACK SIZE
ND TMPSIZ,^D50 ;SIZE OF TEMPORARY USE BUFFER
ND USRSIZ,^D200 ;STORAGE FOR USER NAME STRINGS
ND PRGMAX,^D10 ;MAXIMUM NUMBER OF PROGRAM NAMES TO SPECIFY
ND PSHSLP,^D30000 ;SLEEP TIME DURING A PUSH
ND MAXJOB,^D150 ;MAXIMUM JOBS WE CAN HANDLE
ND MAXTTY,300 ;MAXIMUM TERMINAL KNOWN
ND MAXSYM,^D50 ;MAXIMUM NUMBER OF MONITOR SYMBOLS KNOWN
ND MAXSEP,^D10 ;MAXIMUM COLUMN SEPARATION ALLOWED
ND MAXCLS,^D20 ;MAXIMUM CLASS FOR SCHEDULER
ND TTYCHN,0 ;TERMINAL INTERRUPT CHANNEL
ND CPUINT,^D20 ;SECONDS BETWEEN CPU COMPUTATIONS
ND CPUAVG,3 ;NUMBER OF INTERVALS TO AVERAGE
ND DFTLAP,1 ;DEFAULT NUMBER OF LINES SCREENS OVERLAP BY
ND DFTSLP,^D10000 ;DEFAULT SLEEP TIME BETWEEN UPDATES
ND DFTPAG,0 ;DEFAULT SECONDS BETWEEN SCROLLING
ND DFTIDL,.INFIN ;DEFAULT CUTOFF TIME FOR IDLE JOBS
ND DFTREF,.INFIN ;DEFAULT MINUTES BETWEEN REFRESHINGS
ND MAXID,6 ;MAXIMUM NUMBER OF ID'S TYPED FOR FORK
ND BUFLEN,^D20 ;NUMBER OF WORDS IN TTY BUFFERS
ND BUFNUM,^D10 ;NUMBER OF BUFFERS
ND TXTLEN,^D8 ;WORDS TO HOLD TEXT STRINGS
;OPDEFS:
OPDEF TAB [CHI$ 11] ;TAB CHARACTER
OPDEF SPACE [CHI$ 40] ;SPACE CHARACTER
OPDEF CRLF [CHI$ 12] ;CRLF CHARACTER
OPDEF CALL [PUSHJ P,] ;SUBROUTINE CALL
OPDEF RET [POPJ P,] ;RETURN
OPDEF RETSKP [JRST CPOPJ1] ;GO SKIP RETURN
OPDEF PJRST [JRST] ;STANDARD
OPDEF GETCHR [CALL RUNCHR] ;GET NEXT INPUT CHARACTER IN C
OPDEF MONRD% [JSYS JSYNUM] ;SPECIAL "CUSTOM" SYSTAT JSYS
OPDEF XCTU [XCT 4,] ;PREVIOUS CONTEXT EXECUTE
OPDEF IFIW [1B0] ;FOR EXTENDED INDIRECT WORDS
.NODDT IFIW ;SUPPRESS OUTPUT TOO
SUBTTL INITIALIZATION
;THIS PROGRAM SHOWS A CONSTANTLY UPDATING DISPLAY OF ALL OF THE JOBS ON
;THE SYSTEM, A PARTICULAR JOB IN DETAIL, OR THE GENERAL STATUS OF THE
;MONITOR. NO PRIVILEGES ARE REQUIRED IN GENERAL TO RUN THIS PROGRAM.
ENTRY: JRST SYSDPY ;START ADDRESS
JRST SYSDPY ;REENTER ADDRESS
BYTE (3)0(9)VERSION(6)0(18)EDIT ;VERSION
SYSDPY: RESET ;RESET EVERYTHING
MOVE P,[IOWD PDLSIZ,PDL] ;INITIALIZE STACK
MOVX F,FR.END ;SET UP INITIAL FLAGS
MOVE T1,[CALL DPYUUO] ;GET LUUO INSTRUCTION
MOVEM T1,.JB41 ;SET IT
SETZM ERRCNT ;NO ERRORS ARE STORED
SETZM MYPID ;WE HAVE NO PID
SETZM QSRPID ;AND DON'T KNOW QUASARS
SETZM INFPID ;OR PID OF SYSTEM INFO
SETZM HLPJFN ;CLEAR HELP FILE JFN
SETZM TAKJFN ;CLEAR ANY INDIRECT FILE JFN
SETZM TAKLVL ;AND RESET DEPTH OF TAKE FILES
SETZM HANDLE ;NO FORK HANDLE EXISTS
SETZM REFLST ;CLEAR LAST TIME OF REFRESH
SETZM HLPDSP ;CLEAR OUT ANY HELP DISPATCH
SETZM PAGE ;CLEAR PAGE COUNTER
CALL GETARG ;GO CHECK FOR SPECIAL ACTIONS
GTAD ;READ TIME AND DATE
MOVEM T1,NTIME ;INITIALIZE IT
TIME ;GET THE UPTIME OF THE SYSTEM
MUL T1,[1,,0] ;CONVERT FROM MILLISECONDS
DIV T1,[^D<24*60*60*1000>] ;TO UNIVERSAL TIME
SUB T1,NTIME ;COMPUTE THE TIME THE SYSTEM STARTED
MOVNM T1,BEGTIM ;SAVE FOR LATER
CALL DEFALT ;SET UP ALL DEFAULT PARAMETERS
MOVEI R,DPYALL ;SET UP DEFAULT DISPLAY ROUTINE
HRROI T1,.JOBRT ;GET READY
GETAB ;FIND NUMBER OF JOBS ON SYSTEM
ERJMP DIE ;FAIL
ADDI T1,1 ;ACCOUNT FOR JOB 0
MOVMM T1,HGHJOB ;SAVE MAXIMUM JOB NUMBER ON SYSTEM
MOVEI T1,MAXJOB ;GET NUMBER OF JOBS WE CAN HANDLE
CAMG T1,HGHJOB ;MAKE SURE SYSTEM DOESN'T HAVE MORE
JRST TOOMNY ;YEP, GO COMPLAIN
HRROI T1,.TTYJO ;GET READY
GETAB ;FIND THE NUMBER OF TTYS ON THE SYSTEM
ERJMP DIE ;FAILED
ADDI T1,1 ;ADJUST FOR TTY0
MOVMM T1,HGHTTY ;SAVE MAXIMUM TTY NUMBER
MOVEI T1,.PTYPA ;GET READY
GETAB ;READ PTY DATA
ERJMP DIE ;CAN'T
MOVEI T1,-1(T1) ;MAKE TTY NUMBER OF THE CTY
MOVEM T1,CTYNUM ;SAVE IT
GJINF ;GET INFORMATION ABOUT MY JOB
MOVEM T1,MYUSER ;SAVE MY USER NUMBER
MOVEM T3,MYJOB ;AND MY JOB NUMBER
GETNM ;READ MY PROGRAM NAME
MOVEM T1,MYNAME ;SAVE IT
MOVX T1,RC%EMO ;MATCH STRING EXACTLY
HRROI T2,[ASCIZ/OPERATOR/] ;THE OPERATOR
RCUSR ;GET THE USER NUMBER FOR HIM
TXNE T1,RC%NOM+RC%AMB ;NO MATCH?
SETO T3, ;YES, CLEAR USER NUMBER
MOVEM T3,OPRUSR ;SAVE THE OPERATOR'S USER NUMBER
CALL TBLINI ;INITIALIZE TABLES
CALL BUFINI ;GO INITIALIZE TTY BUFFERS
CALL RDSTAT ;READ MONITOR STATISTICS
CALL STATCP ;THEN COPY AS OLD INFO
CALL ECHOOF ;TURN OFF ECHOING
CALL TAKINI ;GO SET UP TO READ SYSDPY.INI COMMANDS
CALL JSYTST ;SEE IF WE CAN USE "MONRD% JSYS"
CALL CMDINI ;DO RESCANNING OF COMMAND LINE
SETOM TTYFLG ;INITIALIZE INTERRUPT FLAGS
SETOM FRKFLG ;TO NICE STATES
MOVEI T1,.FHSLF ;GET SET
MOVE T2,[LEVTAB,,CHTAB] ;GET TABLE ADDRESSES
SIR ;TELL MONITOR WHERE INTERRUPT TABLES ARE
ERJMP DIE ;FAILED
MOVX T2,1B<TTYCHN> ;GET BIT FOR CHANNEL
AIC ;ACTIVATE THE CHANNEL
ERJMP DIE ;FAILED
EIR ;ENABLE THE INTERRUPTS
ERJMP DIE ;FAILED
MOVE T1,[.TICTI,,TTYCHN] ;SET UP FOR TYPEIN INTERRUPT
ATI ;ACTIVATE INTERRUPT
ERJMP DIE ;FAILED
MOVEI T1,.FHSLF ;GET READY TO INTERRUPT MY FORK
IIC ;GO TAKE CARE OF TYPE-AHEAD
INI$ ;NOW INITIALIZE DPY AND CLEAR SCREEN
SETOM TTYFLG ;ACT LIKE SLEEPING IS OK NOW
SUBTTL MAIN LOOP FOR SHOWING SCREEN DATA
;THIS IS THE MAIN LOOP OF THE PROGRAM. WE CHECK FOR COMMANDS, THEN
;COMPUTE THE SCREEN OF DATA, SHOW IT TO THE USER, SLEEP FOR A WHILE,
;AND LOOP FOREVER.
LOOP: GTAD ;READ CURRENT TIME OF DAY
MOVEM T1,NTIME ;SAVE IT
CALL RUNCMD ;SEE IF ANY COMMANDS TO DO
CALL CHKDRM ;CHECK IDLE TIME OF JOBS
CALL CPUCMP ;COMPUTE CPU PERCENTAGES IF NEEDED
TXZ F,FR.EAT!FR.HDR!FR.NDC ;REINITIALIZE THE DISPLAY FLAGS
SET$ [$SEEAT,,0] ;EAT NO LINES AT FIRST
CALL PAGCHK ;DO SCROLLING OF SCREEN
CALL (R) ;CALL THE PROPER DISPLAY ROUTINE
CALL FULL ;NOW SEE IF THIS WAS LAST SCREEN
TXZA F,FR.END ;NO, CLEAR FLAG FOR NEXT LOOP
TXO F,FR.END ;YES, SET FLAG TO SAY THAT
SET$ [$SEEAT,,0] ;CLEAR EATING SO CAN SEE DASHES
STR$ [ASCIZ/---/] ;FINISH THE DISPLAY
MOVE T1,NTIME ;GET CURRENT TIME
SKIPN REFLST ;SEE IF WE REFRESHED BEFORE
MOVEM T1,REFLST ;NO, THEN SET THE TIME
SUB T1,REFLST ;GET TIME SINCE LAST REFRESH
MULI T1,^D<60*24> ;CONVERT FROM UNIVERSAL TIME
ASHC T1,^D17 ;INTO MINUTES
CAML T1,REFTIM ;REACHED TIME YET?
TXO F,FR.REF ;YES, REMEMBER TO DO IT
TXNN F,FR.REF ;WANTS TO REFRESH SCREEN?
DPY$ DP$NOH ;NO, JUST SHOW CHANGES
TXZN F,FR.REF ;WELL?
JRST DOSLP ;NO, JUST GO SLEEP
MOVE T1,[REF$ RE$NOH] ;GET REFRESH INSTRUCTION
TXZE F,FR.RFC ;WANT TO CLEAR THE SCREEN?
IORI T1,RE$CLR ;YES, SET THE FLAG
XCT T1 ;DO THE REFRESH
MOVE T1,NTIME ;GET CURRENT TIME
MOVEM T1,REFLST ;SET IT AS TIME WE REFRESHED LAST
DOSLP: SKIPN T1,SLPTIM ;GET SLEEP TIME READY
JRST LOOP ;NONE, LOOP
AOSN TTYFLG ;CHECK AND SET SLEEP FLAG
DISMS ;WAIT A WHILE
SLPINT: SETOM TTYFLG ;FLAG NO LONGER SLEEPING
JRST LOOP ;LOOP
SUBTTL ROUTINE TO SHOW ALL JOBS IN A "SYSTAT" DISPLAY
;THIS DISPLAY MODE SHOWS ALL JOBS IN A TYPE OF "SYSTAT" DISPLAY.
;IT WILL GIVE THE GENERAL STATUS OF THE JOBS. NO EXTRANEOUS DATA
;IS GIVEN, SUCH AS SYSTEM DATA. THIS MODE IS THE DEFAULT MODE
;WHEN THE PROGRAM IS STARTED.
DPYALL: MOVEI T1,TP.JOB ;THIS IS JOB OUTPUT
CALL HDRSET ;SO SET UP HEADER FOR IT
TXO F,FR.EAT ;SET UP EATING WHEN HEADER IS TYPED
SETO J, ;INITIALIZE FOR LOOP
JOBLOP: ADDI J,1 ;MOVE TO NEXT JOB
CAMG J,HGHJOB ;DID ALL JOBS YET?
CALL FULL ;OR IS SCREEN FULL?
RET ;YES, DONE
CALL GETDAT ;READ DATA ON THIS JOB
JRST JOBLOP ;NO SUCH JOB, GO ON
CALL SUPPRS ;SEE IF THIS JOB IS TO BE SHOWN
JRST JOBLOP ;NO, GO TO NEXT ONE
CALL DOCOLS ;TYPE ALL REQUIRED COLUMNS
JRST JOBLOP ;LOOP
;HERE TO READ INFO ON A JOB, TO SEE IF IT IS TO BE SHOWN:
GETDAT: MOVE T1,J ;GET JOB NUMBER
MOVE T2,[-<.JISTM+1>,,BLK] ;AND PLACE TO PUT DATA
SETZ T3, ;START AT FIRST WORD
GETJI ;READ INFORMATION ABOUT THE JOB
JRST [CAIE T1,GTJIX1 ;FAIL BECAUSE OF INVALID INDEX?
JRST NOTJOB ;NO, NO SUCH JOB
JRST .+1] ;YES, PROCEED WITH WHAT WE GOT
MOVE T1,BLK+.JIRT ;GET NEW RUNTIME OF JOB
CALL UPDORM ;COMPUTE IDLE TIME FOR THIS JOB
MOVEM T1,IDLE(J) ;THEN SAVE IT
RETSKP ;GOOD RETURN
;FOLLOWING ARE THE ROUTINES TO OUTPUT THE VARIOUS COLUMNS.
XXJOB: MOVE T1,J ;GET JOB NUMBER
CALL DECSP2 ;OUTPUT IT
CAMN J,MYJOB ;IS THIS MY OWN JOB?
CHI$ "*" ;YES, MARK IT WITH A STAR
RET ;DONE
XXTERM: MOVE T1,BLK+.JITNO ;GET TERMINAL NUMBER
JRST TTYOUT ;OUTPUT IT
XXPROG: SKIPN T1,BLK+.JIPNM ;GET PROGRAM NAME
MOVE T1,BLK+.JISNM ;IF NONE, USE SUBSYSTEM NAME
JRST SIXOUT ;GO OUTPUT IT
XXJSTA: MOVE T1,BLK+.JITNO ;GET TERMINAL NUMBER
CALL STATE ;USE IT TO RETURN THE STATE OF THE JOB
STR$ T1 ;THEN OUTPUT IT
RET ;DONE
XXJRUN: MOVE T1,BLK+.JIRT ;GET RUN TIME
IDIVI T1,^D1000 ;CONVERT TO SECONDS
JRST TIMSPC ;OUTPUT IT JUSTIFIED
XXCPU: TXNN F,FR.CPR ;IS THE CPU DATA READY YET?
RET ;NO, DO NOTHING
MOVE T1,RUNDIF(J) ;GET RUNTIME JOB HAD IN LAST INTERVAL
MOVE T2,TIMDIF ;AND TIME DIFFERENCE
JRST CENOUT ;GO OUTPUT IT
XXCDIR: MOVE T1,BLK+.JIDNO ;GET CONNECTED DIRECTORY
MOVEI T2,4 ;ALLOW 4 WORDS OF OUTPUT
JRST USROUT ;GO OUTPUT IT
XXIDLE: MOVE T1,IDLE(J) ;GET BACK DORMANT TIME
CAIGE T1,^D60 ;AN HOUR?
STR$ [ASCIZ/ /] ;NO, SPACE OVER
CALL TMHSPS ;OUTPUT DORMANCY TIME
SKIPGE TIMRUN(J) ;HAS JOB NOT RUN SINCE WE STARTED?
CHI$ "+" ;YES, APPEND A PLUS THEN
RET ;DONE
XXUSER: MOVE T1,BLK+.JIUNO ;GET THE USER'S NUMBER
MOVEI T2,3 ;GET WORDS OF OUTPUT WE WANT
JRST USROUT ;OUTPUT IT AND RETURN
XXCTIM: SKIPN T2,BLK+.JISTM ;GET TIME USER LOGGED IN
RET ;CAN'T GET IT, FAIL
SPACE ;SPACE OVER ONE TO LOOK NICE
SKIPGE T2 ;KNOWN TIME?
MOVE T2,BEGTIM ;NO, USE SYSTEM STARTUP THEN
MOVE T1,NTIME ;GET TIME RIGHT NOW
SUB T1,T2 ;SUBTRACT TO GET CONNECT TIME
MULI T1,^D<24*60> ;CONVERT FROM UNIVERSAL TIME
ASHC T1,^D17 ;TO MINUTES
JRST TMHSPC ;OUTPUT IT AND RETURN
XXACCT: MOVE T1,J ;GET JOB NUMBER
HRROI T2,TEMP ;POINT TO STORAGE
GACCT ;READ ACCOUNT STRING FOR JOB
ERJMP CPOPJ ;FAILED, HE LOSES
TXNE F,FR.MOR ;MORE COLUMNS AFTER THIS ONE?
SETZM TEMP+3 ;YES, THEN CUT OFF THE OUTPUT SOME
STR$ TEMP ;OUTPUT IT
RET ;DONE
XXLINK: SKIPGE T4,BLK+.JITNO ;GET TERMINAL NUMBER
RET ;DETACHED, FAIL
MOVEI T1,.RDTTY ;FUNCTION TO GET TTY DATA
MOVE T2,['TTLINK'] ;WANT THE LINK WORD
SETZ T3, ;NO OFFSET
MONRD% ;READ THE DATA
ERJMP CPOPJ ;FAILED
JUMPL T1,CPOPJ ;ALSO FAILED
JRST TELLNK ;GO OUTPUT THE DATA
XXJCLS: MOVEI T1,3 ;WANT THREE ARGUMENTS
MOVE T2,J ;GET JOB NUMBER
DMOVEM T1,TEMP ;STORE IN ARGUMENT BLOCK
MOVEI T1,.SKRJP ;GET FUNCTION
MOVEI T2,TEMP ;AND ADDRESS OF BLOCK
SKED% ;READ INFO ON JOB
ERJMP CPOPJ ;FAILED
MOVE T1,TEMP+.SAJCL ;GET THE CLASS
JRST DECSP3 ;OUTPUT IT
XXFKS: MOVE T1,['FKCNT '] ;GET WORD
CALL GETJS0 ;READ NUMBER OF FORKS IN THE JOB
RET ;CAN'T GET IT
AOJA T1,DECSP3 ;ADD 1 FOR TOP FORK AND OUTPUT NUMBER
SUBTTL ROUTINE TO SEE IF A JOB IS TO BE SHOWN
;CALLED FOR EACH JOB TO SELECT WHETHER OR NOT WE WANT TO DISPLAY THE
;JOB. THIS DOES NOT PREVENT ANY DATA COLLECTION FOR CPU TIMES. CALLED
;AFTER READING THE JOB INFO BY GETJI. SKIP RETURN IF JOB IS TO BE SHOWN.
SUPPRS: MOVE T1,IDLE(J) ;GET IDLE TIME FOR THIS JOB
MOVE T2,MAXIDF ;GET FLAG FOR WHICH CHECK TO MAKE
XCT [CAMLE T1,MAXIDL
CAMG T1,MAXIDL](T2) ;CORRECT SIDE OF THE CUTOFF VALUE?
RET ;NO, RETURN
MOVE T1,J ;GET COPY OF JOB NUMBER
ADJBP T1,[POINT 1,BITS,0] ;CREATE PROPER BYTE POINTER
LDB T1,T1 ;GET BIT FOR THIS JOB
JUMPN T1,CPOPJ ;RETURN FAILURE IF BIT WAS SET
MOVE T2,BLK+.JIUNO ;GET USER NUMBER
CAMN T2,OPRUSR ;IS THIS NOT THE OPERATOR?
TXNE F,FR.OPR ;OR WE WANT TO SHOW THEM ANYWAY?
SKIPA ;YES
RET ;NO, RETURN
SKIPN T1,BLK+.JIPNM ;GET PROGRAM NAME
MOVE T1,BLK+.JISNM ;OR SYSTEM NAME IF NONE
CALL PRGCMP ;SEE IF THE PROGRAM NAME MATCHES
RET ;NO, RETURN
MOVE T1,BLK+.JIUNO ;GET THE JOB'S USER NUMBER
JRST USRCMP ;SEE IF HE MATCHES WHO WE WANT TO SEE
SUBTTL ROUTINE TO DO DISPLAY OF A SINGLE JOB
;THIS DISPLAY WILL SHOW THE STATUS OF A PARTICULAR JOB IN DETAIL,
;INCLUDING THE OPEN JFNS AND THE FORKS.
DPYONE: MOVEI T1,TP.JOB ;THIS IS JOB OUTPUT
CALL HDRSET ;SET UP TAB STOPS AND HEADER
TXO F,FR.HDR ;BUT STOP HEADER FROM TYPING
SKIPN T1,THETTY ;SEE IF A PARTICULAR TTY IS TO BE SHOWN
JRST ONEHAV ;NO, THEN ALREADY HAVE THE JOB
HRROI T2,THEJOB ;ONE WORD STORED AT GIVEN LOCATION
MOVEI T3,.JIJNO ;WANT TO READ THE JOB NUMBER
GETJI ;READ THE JOB NUMBER
ERJMP LOSE ;FAILED
SKIPGE THEJOB ;IS A JOB ON THE TERMINAL?
JRST DPYONT ;NO, GO COMPLAIN
ONEHAV: MOVE J,THEJOB ;GET JOB TO DO
CALL GETDAT ;READ DATA ON THE JOB
JRST DPYONN ;ISN'T THERE
CALL DOCOLS ;OK, SHOW DATA ON THE JOB
CRLF ;THEN DO A CRLF
CALL SETEAT ;SET UP TO EAT LINES NOW
TXZ F,FR.NDC ;DON'T NEED A CRLF NOW
CALL DOFORK ;SHOW THE FORK STATUS
CALL DOJFN ;AND THE JFN STATUS
JRST JOBSUM ;OUTPUT SUMMARY STUFF AND RETURN
DPYONN: STR$ [ASCIZ/Job /] ;TYPE SOME
MOVE T1,J ;GET JOB NUMBER
CALL DECOUT ;OUTPUT IT
STR$ [ASCIZ/ is not in use
/]
RET ;DONE
DPYONT: STR$ [ASCIZ/No job is on line /] ;TYPE SOME
MOVE T1,THETTY ;GET THE TTY NUMBER
SUBI T1,.TTDES ;REMOVE OFFSET
CALL OCTOUT ;OUTPUT IT
JRST DOCRLF ;THEN FINISH WITH A CRLF
SUBTTL SUBROUTINE TO OUTPUT GENERAL INFORMATION ON A JOB
;THIS OUTPUTS STUFF AT THE END OF THE SINGLE JOB DISPLAY SUCH AS
;THE CONNECTED DIRECTORY, TIME LIMIT, DISK SPACE USED, ETC.
JOBSUM: TXOE F,FR.NDC ;CRLF NECESSARY?
CRLF ;YES, TYPE ONE
STR$ [ASCIZ/Job started: /] ;TYPE SOME TEXT
SKIPN T2,BLK+.JISTM ;GET JOB STARTUP TIME IF THERE
MOVE T2,BLK+.JILLN ;OTHERWISE GET LAST LOGIN TIME
SKIPGE T2 ;IS THE TIME KNOWN?
MOVE T2,BEGTIM ;NO, USE SYSTEM STARTUP TIME
HRROI T1,TEMP ;POINT TO BUFFER
SETZ T3, ;NORMAL OUTPUT
ODTIM ;CONVERT TO ASCIZ
STR$ TEMP ;THEN OUTPUT IT
STR$ [ASCIZ/ Time limit: /] ;MORE
SKIPN T1,BLK+.JIRTL ;ANY RUN TIME LIMIT?
STR$ [ASCIZ/None/] ;NO, SAY SO
IDIVI T1,^D1000 ;CONVERT TO SECONDS
SKIPN T1 ;ANY TIME?
SKIPE T2 ;OR EVEN REMAINDER?
CALL TIMOUT ;YES, OUTPUT IT
CALL DOCRLF ;TYPE A CRLF
CALL TYPRSC ;TYPE THE RSCAN BUFFER FOR THE JOB
STR$ [ASCIZ/Connected directory: /] ;MORE OUTPUT
MOVE T1,BLK+.JIDNO ;GET CONNECTED DIRECTORY
SETZ T2, ;WANT ALL OF OUTPUT
CALL USROUT ;OUTPUT IT
MOVE T1,BLK+.JIDNO ;GET READY
GTDAL ;READ DIRECTORY DATA
ERJMP DOCRLF ;FAILED
MOVEM T1,TEMP ;SAVE WORKING QUOTA
MOVEM T3,TEMP+1 ;AND PERMANENT QUOTA
STR$ [ASCIZ/
Used pages: /] ;TYPE MORE
MOVE T1,T2 ;GET CURRENT ALLOCATION
CALL DECOUT ;OUTPUT IT
STR$ [ASCIZ/ Working quota: /] ;MORE
MOVE T1,TEMP ;GET QUOTA
CALL INFOUT ;OUTPUT IT
STR$ [ASCIZ/ Permanent quota: /] ;MORE
MOVE T1,TEMP+1 ;GET QUOTA
CALL INFOUT ;OUTPUT IT
JRST DOCRLF ;TYPE A CRLF
SUBTTL ROUTINE TO SHOW FORK STATUS
;THIS ROUTINE IS CALLED WITH A JOB NUMBER IN AC J, TO FIND THE
;FORKS IN THE JOB AND GIVE A STATUS OF EACH ONE. THIS REQUIRES
;THAT THE MONRD% JSYS BE WORKING.
DOFORK: TXNN F,FR.JSY ;IS THE JSYS THERE?
RET ;NO, RETURN
MOVEI T1,TP.FRK ;THIS IS FORK OUTPUT
CALL HDRSET ;SO SET UP HEADER AND TAB STOPS
MOVE T1,SKPFRK ;GET NUMBER OF FORKS TO SKIP
MOVEM T1,EATNUM ;REMEMBER NUMBER
SETOM JOBFRK ;INITIALIZE JOB FORK INDEX
FRKLOP: AOS T2,JOBFRK ;GET NEXT JOB FORK NUMBER
CAMGE T2,NUFKS ;DID THEM ALL?
CALL FULL ;OR IS SCREEN FULL?
RET ;YES, RETURN
MOVE T1,['SYSFK '] ;WANT TO READ SYSTEM FORK TABLE
CALL GETJSB ;READ WORD
JRST FRKLOP ;FAILED, DO NEXT ONE
JUMPL T2,FRKLOP ;IF NEGATIVE, FORK NOT IN USE
MOVEM T2,SYSFK ;SAVE BITS FOR LATER USE
HRRZ T1,T2 ;KEEP ONLY RIGHT HALF
CAIE T1,-1 ;IS THIS FORK ASSIGNED?
SOSL EATNUM ;AND WE HAVE NO LINES TO EAT?
JRST FRKLOP ;NO, DO NEXT ONE
MOVEM T1,FORK ;SAVE SYSTEM FORK NUMBER
SETZM HAVPC ;WE NEED NEW PC'S FOR THE FORK
SETZM HAVID ;AND NEW ID'S FOR THE FORK
CALL DOCOLS ;DO ALL OF THE COLUMNS
JRST FRKLOP ;THEN DO NEXT FORK
;THE ROUTINES TO HANDLE THE VARIOUS COLUMN OUTPUTS:
XXFORK: MOVE T1,FORK ;GET FORK NUMBER
JRST OCTOUT ;OUTPUT IT AND RETURN
XXSUP: MOVE T1,JOBFRK ;GET JOB FORK NUMBER
CALL GETSUP ;FIND THE SUPERIOR
RET ;FAILED
CAMN T1,FORK ;IS OUR SUPERIOR US?
STR$ [ASCIZ/--/] ;YES, INDICATE THAT
CAME T1,FORK ;WELL?
JRST OCTOUT ;NO, THEN OUTPUT THE FORK WHICH IS
RET ;DONE
XXUPC: CALL GETPC ;READ ALL PC INFORMATION
RET ;FAILED
MOVE T1,USERPC ;GET THE USER PC
JRST PCOUT ;AND OUTPUT IT
XXMPC: CALL GETPC ;READ THE PC INFORMATION
RET ;FAILED
MOVE T1,PC ;GET THE PROCESS PC
MOVE T2,PCFLAG ;AND THE CORRESPONDING FLAGS
TLNN T2,(1B5) ;IS THE FORK IN MONITOR MODE?
JRST PCOUT ;YES, OUTPUT THE MONITOR PC
STR$ [ASCIZ/ --/] ;OTHERWISE TYPE DASHES
RET ;AND RETURN
XXSCHD: MOVEI T1,.RDFST ;GET FUNCTION FOR SCHEDULER TEST
MOVE T2,FORK ;AND FORK NUMBER
MONRD% ;GET THE SCHEDULER TEST
ERJMP CPOPJ ;FAILED
JUMPL T1,CPOPJ ;ALSO FAILED
HRRZM T2,TEMP ;SAVE THE ADDRESS
HLRZ T1,T2 ;GET THE DATA
CALL OCTSP6 ;OUTPUT IN A FIELD OF 6
STR$ [ASCIZ/,,/] ;THEN SOME COMMAS
MOVE T1,TEMP ;GET BACK ADDRESS
JRST SYMOUT ;OUTPUT AS MONITOR SYMBOL
XXCORE: CALL GETID ;GO READ ALL PAGE IDENTIES
RET ;FAILED
JRST TYPID ;THEN TYPE IT OUT AND RETURN
XXPRIV: JRST GETPRV ;GO TYPE PRIVILEGES
XXCALL: CALL GETPC ;OBTAIN ALL PC INFO
RET ;FAILED
MOVE T1,PCFLAG ;GET THE PC FLAGS
TLNN T1,(1B5) ;WAS HE IN USER MODE?
CHI$ "*" ;NO, TYPE A STAR
TLNE T1,(1B5) ;WELL?
SPACE ;YES, TYPE A SPACE
MOVE T1,['KIMUU1'] ;GET READY
CALL GETPS0 ;READ FIRST PART OF MUUO
RET ;CAN'T
MOVEM T1,TEMP ;SAVE THE OPCODE PART
MOVE T1,['KIMUU1'] ;GET READY AGAIN
MOVEI T2,1 ;OFFSET OF 1
CALL GETPSB ;GET OTHER PART
RET ;FAILED
HRL T1,TEMP ;GET BACK OTHER PART OF MUUO
JRST UUOOUT ;OUTPUT IT AND RETURN
XXFFLG: SPACE ;SPACE OVER FIRST
MOVE T1,SYSFK ;GET FORK FLAGS
TXNN T1,SFNVG ;VIRGIN FORK?
CHI$ "V" ;YES, SAY SO
TXNE T1,SFEXO ;EXECUTE ONLY?
CHI$ "E" ;YES, SAY SO
TXNE T1,SFGXO ;DOING A GET OF EXECUTE ONLY PROG?
CHI$ "G" ;YES, SAY SO
RET ;DONE
XXINTD: MOVE T1,['INTDF '] ;GET READY
CALL GETPS0 ;READ THE INTERRUPT DEFER COUNTER
RET ;CAN'T
JRST DECSP3 ;OUTPUT IT
XXTRPC: MOVE T1,['TRAPPC'] ;GET READY
CALL GETPS0 ;READ THE PC OF THE PAGE FAULT
RET ;FAILED
MOVEM T1,TEMP ;SAVE FOR AWHILE
MOVE T1,['TRAPPC'] ;NOW GET READY TO READ FLAGS
SETO T2, ;WHICH ARE IN PREVIOUS WORD
CALL GETPSB ;GET THEM
RET ;FAILED
TXNE T1,1B5 ;WAS THIS IN USER OR EXEC MODE?
SPACE ;USER MODE, JUST SPACE
TXNN T1,1B5 ;WELL?
CHI$ "*" ;EXEC MODE, SAY SO
MOVE T1,TEMP ;GET BACK THE PC
JRST PCOUT ;AND OUTPUT IT
XXSTAT: MOVEI T1,.RDSTS ;GET READY
MOVE T2,FORK ;TO READ STATUS OF FORK
MONRD% ;DO IT
ERJMP CPOPJ ;FAILED
JUMPN T1,CPOPJ ;AS I SAID
MOVE T1,T2 ;PUT RESULT IN RIGHT AC
JRST FRKSTS ;OUTPUT IT
XXTRAP: MOVE T1,['UTRPCT'] ;GET READY
CALL GETPS0 ;READ NUMBER OF PAGE TRAPS
RET ;CAN'T
JRST DECSP4 ;OUTPUT THEM
XXRUN: MOVE T1,['FKRT '] ;GET READY
CALL GETPS0 ;READ FORK'S RUN TIME
RET ;FAILED
IDIVI T1,^D1000 ;CONVERT TO SECONDS
PUSH P,T2 ;SAVE REMAINDER
CALL TIMSPC ;OUTPUT IT
POP P,T1 ;RESTORE REMAINDER
IDIVI T1,^D100 ;GET TENTHS OF A SECOND
CHI$ "." ;TYPE A DOT
CHI$ "0"(T1) ;THEN GIVE TENTHS
RET ;DONE
XXLERR: MOVE T1,['LSTERR'] ;GET THE SYMBOL NAME READY
CALL GETPS0 ;READ IT
RET ;FAILED
JRST ERROUT ;OUTPUT IT AND RETURN
XXWSIZ: MOVEI T1,.RDWSP ;GET FUNCTION CODE
MOVE T2,FORK ;AND FORK NUMBER
MONRD% ;READ THE DATA
ERJMP CPOPJ ;FAILED
JUMPL T1,CPOPJ ;ALSO FAILED
HRRZ T1,T2 ;MOVE TO RIGHT AC
CALL DECSP3 ;OUTPUT IT
CALL GETID ;THEN READ THE IDS OF THE FORK
RET ;CAN'T GET THEM
CHI$ "/" ;TYPE A SLASH TO SEPARATE NUMBERS
MOVE T1,IDPGS ;GET TOTAL PAGES IN USE BY FORK
JRST DECOUT ;AND OUTPUT IT
SUBTTL SUBROUTINES TO READ JSB OR PSB WORDS OF OTHER JOBS
;SUBROUTINE TO READ A WORD FROM THE PSB OF A FORK. CALLED WITH THE
;SIXBIT NAME OF THE WORD IN T1, THE OFFSET IN T2, AND THE FORK
;NUMBER IN FORK. SKIP RETURN IF SUCCESSFUL, WITH VALUE RETURNED IN T1.
;CALL AT GETPS0 IF OFFSET IS ZERO.
GETPS0: SETZ T2, ;CLEAR OFFSET
GETPSB: MOVE T3,T2 ;MOVE OFFSET TO RIGHT AC
MOVE T2,T1 ;MOVE SIXBIT WORD TO RIGHT AC
MOVEI T1,.RDPSB ;SET UP FUNCTION CODE FOR PSB
MOVE T4,FORK ;GET FORK NUMBER
DOMONR: MONRD% ;ASK MONITOR TO READ DATA
ERJMP CPOPJ ;NO SUCH JSYS, FAIL RETURN
SKIPN T1 ;DID IT WORK?
AOS (P) ;YES, SET FOR SKIP RETURN
MOVE T1,T2 ;COPY DATA TO T1
RET ;DONE
;SUBROUTINE TO READ WORDS FROM JSB. SIXBIT NAME OF WORD GOES
;IN T1, THE OFFSET IN T2, AND THE JOB NUMBER IN J. SKIP RETURN IF
;SUCCESSFUL, WITH VALUE RETURNED IN T1. CALLED AT GETJS0 IF THE
;OFFSET IS ZERO.
GETJS0: SETZ T2, ;SET OFFSET TO ZERO
GETJSB: MOVE T3,T2 ;MOVE TO RIGHT AC
MOVE T2,T1 ;AND SYMBOL
MOVEI T1,.RDJSB ;READ JSB FUNCTION
MOVE T4,J ;JOB NUMBER TO READ
JRST DOMONR ;GO READ DATA
SUBTTL SUBROUTINE TO OBTAIN THE USER AND EXEC PC OF A FORK
;CALLED WITH THE FORK NUMBER IN LOCATION FORK, TO FIND THE
;USER MODE AND EXEC MODE PC OF A FORK. SINCE THIS IS CALLED SEVERAL
;TIMES, WE DO NOT RECOMPUTE THE PC IF THE FLAG HAVPC IS SET. SO
;THIS MUST BE CLEARED WHENEVER A NEW PC IS TO BE OBTAINED.
;VALUES RETURNED ARE:
;
;PC THE CURRENT PROCESS PC WITHOUT FLAGS (CAN BE EITHER USER OR EXEC MODE)
;PCFLAG THE FLAGS CORRESPONDING TO PC. USER MODE SET IF THIS IS A USER PC.
;USERPC THE CURRENT USER MODE PC. SAME AS PC UNLESS DOING A MONITOR CALL.
GETPC: SKIPE HAVPC ;DO WE ALREADY HAVE THE PC INFO?
RETSKP ;YES, SKIP RETURN
MOVSI T1,'PPC' ;GET READY TO READ PROCESS PC
CALL GETPS0 ;DO IT
RET ;FAILED
MOVEM T1,PC ;SAVE THE PC
MOVEM T1,USERPC ;HERE TOO UNTIL PROVED WRONG
MOVSI T1,'PPC' ;NOW GET SET TO READ THE PC FLAGS
SETO T2, ;WHICH ARE JUST BEFORE THE PC
CALL GETPSB ;GET THEM
RET ;FAILED
MOVEM T1,PCFLAG ;SAVE THEM
TLNE T1,(1B5) ;IS THE PROCESS PC IN USER MODE?
JRST GETPCY ;YES, ALL DONE
MOVE T1,['UPDL '] ;NO, THEN USER PC IS ON THE STACK
CALL GETPS0 ;READ THE REAL USER PC
RET ;FAILED
MOVEM T1,USERPC ;SAVE IT
GETPCY: SETOM HAVPC ;ALL PC INFO OK NOW
RETSKP ;GOOD RETURN
SUBTTL ROUTINE TO TYPE OUT A FORK'S CAPABILITIES
;CALLED WITH THE FORK INDEX IN FORK, TO TYPE OUT THE CAPABILITIES OF
;A FORK, WHETHER OR NOT THEY ARE ENABLED. SKIP RETURN IF SUCCESSFUL.
GETPRV: MOVE T1,['CAPMSK'] ;GET READY
CALL GETPS0 ;READ POSSIBLE CAPABILITIES
RET ;ERROR
HRRZM T1,TEMP ;SAVE FOR LATER
MOVE T1,['CAPENB'] ;GET READY
CALL GETPS0 ;READ ENABLED CAPABILITIES
RET ;FAILED
ANDCAM T1,TEMP ;ZAP POSSIBLE CAPABILITES WHICH ARE ENABLED
CALL TYPPRV ;TYPE OUT ENABLED PRIVILEGES
SKIPN T1,TEMP ;NOW GET BACK POSSIBLE CAPABILITIES
RET ;NONE, DONE
CHI$ "/" ;SEPARATE WITH A SLASH
;FALL INTO TYPEOUT ROUTINE
;TRIVIAL ROUTINE TO TYPE OUT LETTERS INDICATING WHICH PRIVS ARE THERE.
;ONLY THE MOST IMPORTANT PRIVILEGES ARE TYPED OUT HERE.
TYPPRV: TRNE T1,SC%WHL ;WHEEL?
CHI$ "W" ;YES
TRNE T1,SC%OPR ;OPERATOR?
CHI$ "O" ;YES
TRNE T1,SC%MNT ;MAINTAINANCE PRIVILEGES?
CHI$ "M" ;YES
TRNE T1,-1-<SC%WHL!SC%OPR!SC%MNT> ;ANY OTHERS?
CHI$ "+" ;YES, SAY SO
RET ;DONE
SUBTTL SUBROUTINE TO FIND THE SUPERIOR OF A FORK
;CALLED WITH THE JOB NUMBER IN J, AND THE JOB FORK NUMBER IN T1, TO
;FIND OUT WHAT THE SUPERIOR OF THE FORK IS. SKIP RETURN IF SUCCESSFUL,
;WITH SYSTEM FORK IN T1. CALL AT FNDFRK TO CONVERT JOB FORK NUMBER
;TO SYSTEM FORK NUMBER.
GETSUP: MOVE T2,T1 ;COPY TO RIGHT AC
MOVE T1,['FKPTRS'] ;THE FORK STRUCTURE TABLE
CALL GETJSB ;READ WORD FROM JSB
RET ;FAILED
LDB T2,[POINT 12,T2,11] ;GET FORK NUMBER OF SUPERIOR
FNDFRK: CAML T2,NUFKS ;MAKE SURE IT IS LEGAL
RET ;NO, ERROR
MOVE T1,['SYSFK '] ;WANT TO GET SYSTEM FORK NUMBER
CALL GETJSB ;READ IT
RET ;FAILED
HRRZ T1,T2 ;KEEP ONLY RIGHT HALF
CAIE T1,-1 ;A REAL FORK?
AOS (P) ;YES, GOOD RETURN
RET ;DONE
SUBTTL SUBROUTINE TO FIND THE JOB NUMBER A FORK BELONGS TO
;CALLED WITH A FORK NUMBER IN T1, TO RETURN THE JOB NUMBER THAT FORK
;BELONGS TO. TO SPEED UP SUCCESSIVE CALLS WITH THE SAME FORK NUMBER,
;WE ONLY DO THE WORK IF LOCATION KWNJOB IS NONNEGATIVE. SKIP
;RETURN IF SUCCESSFUL.
FRKJOB: SKIPL KWNJOB ;DO WE ALREADY KNOW THE JOB NUMBER?
JRST FRKJBY ;YES, GO GET IT
MOVEM T1,FORK ;SAVE THE FORK NUMBER
MOVE T1,['JOBNO '] ;WORD CONTAINING THE JOB NUMBER
CALL GETPS0 ;READ IT
RET ;FAILED
MOVEM T1,KWNJOB ;SAVE JOB FOR LATER USE
RETSKP ;GOOD RETURN
FRKJBY: MOVE T1,KWNJOB ;GET THE JOB NUMBER
RETSKP ;GOOD RETURN
SUBTTL SUBROUTINE TO COMPUTE WHAT A FORK'S PAGES ARE
;CALLED WITH FORK NUMBER IN LOCATION FORK, TO CONSTRUCT A TABLE AT
;IDTVAL WHICH CONTAINS THE IDENTITIES OF THE PAGES OF THE FORK. THE
;TABLE WILL CONTAIN EITHER FORK NUMBERS OR NEGATIVE OFNS. SKIP
;RETURN IF SUCCESSFUL, WITH NUMBER OF IDENTITIES IN IDNUM. SINCE THIS IS
;CALLED SEVERAL TIMES, WE SAVE TIME IF WE HAVE BEEN CALLED BEFORE.
GETID: SKIPE HAVID ;ALREADY COLLECTED THE ID'S?
RETSKP ;YES, ALL DONE
SETOM IDPAG ;INITIALIZE CURRENT PAGE
SETZM IDNUM ;AND NUMBER OF DIFFERENT IDENTITIES
SETZM IDPGS ;AND TOTAL NUMBER OF PAGES
IDLOP: AOS T2,IDPAG ;INCREMENT TO NEXT PAGE
TRNE T2,777000 ;WENT OFF OF END?
JRST IDDONE ;YES, HAVE ALL IDS THEN
MOVEI T1,.RDMAP ;FUNCTION TO READ MAP WORD OF FORK
MOVE T3,FORK ;GET FORK HANDLE
MONRD% ;READ THE POINTER FOR THAT PAGE
ERJMP CPOPJ ;FAILED
JUMPL T1,CPOPJ ;ALSO FAILED
TLNN T2,-1 ;IS THIS PAGE NONEXISTANT?
JRST IDNONX ;YES, SEE WHAT TO DO
TLC T2,300000 ;GET READY FOR CHECK
TLCN T2,300000 ;IS THIS A PRIVATE OR SHARED PAGE?
TRNE T2,400000 ;OR INDIRECT TO A FILE?
AOS IDPGS ;YES, COUNT UP TOTAL PAGES FOR FORK
TLNN T2,200000 ;IS THIS A PRIVATE PAGE?
SKIPA T1,[1B0] ;YES, REMEMBER THAT
HRREI T1,(T2) ;NO, GET FORK OR -OFN BY ITSELF
HRLZ T2,IDNUM ;GET CURRENT NUMBER OF TABLE ENTRIES
JUMPE T2,IDNEW ;IF NONE, INSERT THIS ONE
MOVN T2,T2 ;TURN INTO AOBJN POINTER
CAME T1,IDVALS(T2) ;FOUND THIS IDENTITY?
AOBJN T2,.-1 ;NOT YET, KEEP LOOKING
JUMPGE T2,IDNEW ;NOT IN TABLE, GO INSERT IT
AOS IDCNTS(T2) ;FOUND IT, INCREMENT COUNTER
JRST IDLOP ;AND GO BACK TO LOOP
;HERE WHEN THE CURRENT PAGE IS NONEXISTANT:
IDNONX: SUBI T2,1 ;DECREMENT PAGE SINCE AOS'D ABOVE
MOVEM T2,IDPAG ;SAVE NEW PAGE TO START LOOP AT
JUMPGE T2,IDLOP ;GO BACK TO LOOP IF NOT YET DONE
IDDONE: SETOM HAVID ;SAY WE HAVE THE ID'S
RETSKP ;GOOD RETURN
;HERE WHEN THE IDENTITY WASN'T IN THE TABLE PREVIOUSLY, TO INSERT IT:
IDNEW: MOVEM T1,IDVALS(T2) ;SAVE THIS NEW IDENTITY
MOVEI T1,1 ;GET AN INITIAL COUNT
MOVEM T1,IDCNTS(T2) ;AND SET IT
AOS IDNUM ;INCREMENT NUMBER OF IDENTITIES IN TABLE
JRST IDLOP ;AND LOOP
SUBTTL SUBROUTINE TO TYPE OUT THE PAGE ID'S OF A FORK
;CALLED AFTER COLLECTION OF THE PAGE IDENTITIES OF A FORK, TO SCAN
;THEM AND TYPE OUT THE MOST COMMON ONES. THE TYPEOUT SHOWS WHICH
;FORKS WE ARE MAPPED INTO, AND WHICH OFNS WE ARE MAPPED TO.
TYPID: MOVEI T1,MAXID ;GET MAXIMUM NUMBER OF ID'S ALLOWED
CAMGE T1,IDNUM ;ACTUAL NUMBER LESS THAN THIS?
TXNN F,FR.MOR ;OR NO MORE COLUMNS COMING?
MOVE T1,IDNUM ;YES, GET ACTUAL NUMBER THEN
JUMPE T1,CPOPJ ;IF NONE THERE RETURN
MOVEM T1,IDYNM ;SAVE NUMBER TO BE TYPED
TXZ F,FR.TMP ;CLEAR FLAG
IDTYPL: SETZB T1,T2 ;INITIALIZE INDEX AND MAXIMUM COUNT
SOSL IDYNM ;SEE IF TYPED ALL INDENTITIES YET
JRST IDSRCL ;NO, GO GET NEXT ONE
TXNN F,FR.MOR ;MORE COLUMNS COMING?
RET ;NO, THEN WE TYPED EVERYTHING
MOVE T1,IDNUM ;GET TOTAL NUMBER OF ENTRIES
CAILE T1,MAXID ;MORE THAN WE TYPED?
CHI$ "+" ;YES, SAY THERE ARE EVEN MORE
RET ;DONE
IDSRCL: CAML T2,IDCNTS(T1) ;FOUND AN ENTRY WITH HIGHER COUNT?
JRST IDSRCN ;NO, KEEP LOOKING
MOVE T2,IDCNTS(T1) ;YES, REMEMBER NEW MAXIMUM
MOVE T3,T1 ;AND INDEX OF THE ENTRY
IDSRCN: ADDI T1,1 ;ADVANCE TO NEXT ENTRY
CAMGE T1,IDNUM ;LOOKED AT ALL ENTRIES?
JRST IDSRCL ;NO, KEEP LOOPING
SETZM IDCNTS(T3) ;CLEAR COUNT SO WON'T SEE THIS AGAIN
TXOE F,FR.TMP ;ALREADY TYPED ONE IDENTITY?
CHI$ "+" ;YES, TYPE A COMMA FIRST
SKIPL T1,IDVALS(T3) ;GET THE IDENTITY AND SEE IF IT IS A FORK
CHI$ "F" ;YES, THEN TYPE PRECEEDING LETTER
CAMN T1,[1B0] ;IS IT A PRIVATE PAGE?
JRST [CHI$ "P" ;YES, SAY IT IS PRIVATE
JRST IDTYPL] ;CONTINUE LOOPING
MOVM T1,T1 ;MAKE IT POSITIVE
CALL OCTOUT ;THEN OUTPUT EITHER FORK OR OFN NUMBER
JRST IDTYPL ;AND LOOP
SUBTTL ROUTINE TO SHOW JFN STATUS
;THIS ROUTINE IS CALLED WITH A JOB NUMBER IN AC J, TO FIND
;THE JFNS WHICH ARE IN USE BY THE JOB. THIS ROUTINE REQUIRES THAT
;THE MONRD% JSYS BE WORKING.
DOJFN: TXNN F,FR.JSY ;DOES THE JSYS EXIST?
RET ;NO, RETURN
MOVEI T1,TP.FIL ;THIS IS FILE TYPE OUTPUT
CALL HDRSET ;SO SET UP THE HEADER AND TAB STOPS
SETZM JFN ;INITIALIZE JFN NUMBER
MOVE T1,['MAXJFN'] ;GET READY
CALL GETJS0 ;READ HIGHEST JFN TO LOOK AT
RET ;CAN'T
MOVEM T1,MAXJFN ;SAVE IT
MOVE T1,SKPJFN ;GET NUMBER OF JFNS TO SKIP
MOVEM T1,EATNUM ;AND SAVE IT
JFNLOP: AOS T2,JFN ;ADVANCE TO NEXT JFN
CAMG T2,MAXJFN ;DONE WITH ALL JFNS YET?
CALL FULL ;OR IS SCREEN FULL?
RET ;YES, RETURN
MOVE T1,['FILSTS'] ;GET READY TO READ STATUS OF JFN
IMUL T2,MLJFN ;MULTIPLY JFN BY LENGTH OF JFN BLOCK
MOVEM T2,JFNOFF ;SAVE OFFSET FOR LATER USE
CALL GETJSB ;READ JFN STATUS
JRST JFNLOP ;FAILED, LOOK AT NEXT ONE
TXNE T1,GS%NAM!GS%ASG ;IS THIS JFN VALID?
SOSL EATNUM ;AND ARE WE DONE EATING LINES?
JRST JFNLOP ;NO, LOOK AT NEXT ONE
MOVEM T1,FILSTS ;YES, SAVE STATUS FOR LATER USE
CALL DOCOLS ;TYPE OUT LINE ABOUT JFN
JRST JFNLOP ;AND LOOP FOR NEXT ONE
;ROUTINES TO TYPE VARIOUS THINGS ABOUT FILES:
XXJFN: MOVE T1,JFN ;GET JFN
JRST OCTSP2 ;OUTPUT IT AND RETURN
XXOFN: MOVE T1,FILSTS ;GET FILE STATUS BITS
TXNN T1,GS%OPN ;IS THE FILE OPEN?
JRST OFNDSH ;NO, TYPE DASHES
MOVE T1,['FILDEV'] ;GET READY
MOVE T2,JFNOFF ;GET OFFSET TOO
CALL GETJSB ;READ DISPATCH ADDRESS FOR JFN
RET ;FAILED
HRRZ T1,T1 ;KEEP ONLY THE ADDRESS
CAME T1,DSKDTB ;IS THIS A DISK?
JRST OFNDSH ;NO, GO TYPE DASHES
MOVE T1,['FILOFN'] ;GET READY
MOVE T2,JFNOFF ;GET OFFSET
CALL GETJSB ;READ OFNS OF FILE
RET ;FAILED
HRRZ T4,T1 ;REMEMBER THE SUPER INDEX BLOCK OFN
HLRZ T1,T1 ;KEEP THE LOCAL OFN
JUMPE T1,OFNDSH ;IF ZERO, TYPE DASHES
CALL OCTSP3 ;OUTPUT THE OFN
JUMPE T4,CPOPJ ;DONE IF WASN'T A LONG FILE
CHI$ "/" ;SEPARATE THE OFNS
MOVE T1,T4 ;GET OTHER OFN
JRST OCTOUT ;OUTPUT THE SUPER INDEX BLOCK'S OFN
OFNDSH: STR$ [ASCIZ/ --/] ;SAY NO VALID OFN EXISTS
RET ;DONE
XXINIF: MOVE T1,['FILVER'] ;GET READY
MOVE T2,JFNOFF ;GET OFFSET
CALL GETJSB ;READ CREATOR OF JFN
RET ;FAILED
HLRZ T2,T1 ;GET FORK WHICH STARTED JFN
CALL FNDFRK ;CONVERT TO SYSTEM FORK NUMBER
STR$ [ASCIZ/--/] ;IF FORK NOT THERE, INDICATE THAT
CAIE T1,-1 ;WAS THERE A FORK?
JRST OCTOUT ;YES, OUTPUT IT
RET ;OTHERWISE DONE
XXBYTE: MOVE T1,['FILBYN'] ;GET READY
MOVE T2,JFNOFF ;GET OFFSET
CALL GETJSB ;READ BYTE NUMBER
RET ;FAILED
CALL DECOUT ;OUTPUT THE NUMBER
MOVE T1,['FILBYT'] ;GET READY
MOVE T2,JFNOFF ;SAME OFFSET
CALL GETJSB ;READ BYTE POINTER
RET ;FAILED
CHI$ "(" ;OUTPUT STARTING PARENTHESIS
LDB T1,[POINT 6,T1,11] ;GET SIZE OF BYTES
CALL DECOUT ;OUTPUT IT
CHI$ ")" ;THEN GIVE CLOSING PARENTHESIS
RET ;DONE
XXFSTA: MOVE T1,FILSTS ;GET BACK STATUS BITS
JRST TYPSTS ;THEN OUTPUT THEM
XXFILE: JRST TYPFIL ;OUTPUT THE FILE SPEC
SUBTTL SUBROUTINE TO TYPE OUT A FILE SPEC FOR A JFN
;ROUTINE TO TRACE THE DATA IN A JSB DOWN FOR A PARTICULAR JFN, AND
;TO TYPE OUT THE FULL FILE SPEC ASSOCIATED WITH THE JFN. CALLED WITH
;JFN OFFSET IN LOCATION JFNOFF.
TYPFIL: MOVE T1,['FILDDN'] ;POINTER TO DEVICE STRING
MOVE T2,JFNOFF ;OFFSET FOR THIS JFN
CALL GETJSB ;READ THE POINTER
RET ;CAN'T
HLRZ T1,T1 ;KEEP JUST THE POINTER
JUMPE T1,TYPFL1 ;IF NO DEVICE, SKIP ON
CALL TYPPTR ;TYPE OUT DEVICE
RET ;FAILED
CHI$ ":" ;TYPE COLON FOR THE DEVICE
TYPFL1: MOVE T1,['FILDNM'] ;GET READY TO READ DIRECTORY
MOVE T2,JFNOFF ;SAME OFFSET
CALL GETJSB ;READ POINTER
RET ;FAILED
HLRZ T1,T1 ;GET POINTER IN RIGHT HALF
JUMPE T1,TYPFL2 ;IF NO DIRECTORY, JUMP ON
CHI$ "<" ;TYPE STARTING BRACKET
CALL TYPPTR ;TYPE OUT THE DIRECTORY NUMBER
RET ;FAILED
CHI$ ">" ;FINISH DIRECTORY
TYPFL2: MOVE T1,['FILNEN'] ;GET READY
MOVE T2,JFNOFF ;AGAIN SAME OFFSET
CALL GETJSB ;READ THE POINTER WORD
RET ;FAILED
MOVEM T1,TXTTMP ;SAVE IT
HLRZ T1,T1 ;GET POINTER TO FILE NAME
CALL TYPPTR ;TYPE FILE NAME STRING
RET ;FAILED
MOVE T1,['FILVER'] ;GET READY
MOVE T2,JFNOFF ;SAME OFFSET
CALL GETJSB ;READ GENERATION NUMBER
RET ;FAILED
HRLM T1,TXTTMP ;SAVE GENERATION NUMBER
SKIPN T1,TXTTMP ;GET POINTER TO EXTENSION
RET ;IF NO EXTENSION OR GENERATION, DONE
CHI$ "." ;TYPE A DOT
CALL TYPPTR ;TYPE EXTENSION
RET ;FAILED
CHI$ "." ;ONE MORE DOT
HLRZ T1,TXTTMP ;GET GENERATION NUMBER BACK
CALL DECOUT ;OUTPUT THE VERSION
RETSKP ;GOOD RETURN
SUBTTL SUBROUTINE TO OUTPUT FILE STATUS INFORMATION
;CALLED WITH A JFN'S FILE STATUS BITS IN T1, TO OUTPUT INFORMATION
;ABOUT THE FILE. THE STATUS BITS IN THE MONITOR'S STATUS WORD ARE
;THE SAME AS RETURNED BY THE GTSTS JSYS.
TYPSTS: TXNN T1,GS%OPN ;IS FILE OPENED?
TXZ T1,GS%RDF+GS%WRF+GS%XCF+GS%RND ;NO, CLEAR THESE BITS
TXNE T1,GS%RDF ;OPEN FOR READ?
TXZ T1,GS%XCF ;YES, CLEAR EXECUTE ACCESS
TXNN T1,GS%OPN+GS%AST ;CAN FILE BE OPENED BUT ISN'T?
STR$ [ASCIZ/Nopen /] ;YES, SAY NOT OPENED
TXNE T1,GS%AST ;IS THE JFN PARSE ONLY?
STR$ [ASCIZ/Parse /] ;YES, SAY SO
TXNE T1,GS%RDF ;OPEN FOR READ?
STR$ [ASCIZ/Rd /] ;YES, SAY SO
MOVEI T2,[ASCIZ/Wrt /] ;GET STRING
TXNN T1,GS%RND ;APPEND ONLY?
MOVEI T2,[ASCIZ/App /] ;YES, GET OTHER TEXT
TXNE T1,GS%WRF ;OPEN FOR WRITE?
STR$ (T2) ;SAY, SAY SO
TXNE T1,GS%XCF ;OPEN FOR EXECUTE?
STR$ [ASCIZ/Xct /] ;YES, INDICATE THAT
TXNE T1,GS%FRK ;RESTRICTED JFN?
STR$ [ASCIZ/Res /] ;YES, SAY SO
TXNE T1,GS%EOF ;AT END OF FILE?
STR$ [ASCIZ/Eof /] ;SAY, INDICATE IT
TXNE T1,GS%ERR ;ANY ERRORS IN FILE?
STR$ [ASCIZ/Err /] ;YES, SAY SO
TXNN T1,GS%NAM ;ANY FILE FOUND FOR JFN?
STR$ [ASCIZ/Inv/] ;NO, SAY SPEC IS INVALID
RET ;DONE
SUBTTL DISPLAY FOR QUEUES
;THIS DISPLAY ROUTINE LISTS THE QUEUES. SET BY THE "Q" COMMAND.
;IPCF PACKETS ARE SENT TO QUASAR, AND THE RETURN MESSAGES ARE OUTPUT
;TO THE SCREEN. THUS THE FORMAT OF THE OUTPUT IS TOTALLY UP TO
;QUASAR.
DPYQUE: SETOM HDRTYP ;CLEAR HEADER TYPE
TAB$ ;USE DEFAULT TAB STOPS
TXNE F,FR.CMP ;WANT COMPRESSED OUTPUT?
JRST QUENOC ;YES, SKIP THIS
STR$ [ASCIZ/Queues as of /] ;TYPE SOME
HRROI T1,TEMP ;POINT TO TEMPORARY DATA
SETOB T2,T3 ;CURRENT TIME, VERBOSE OUTPUT
ODTIM ;COMPUTE AND STORE IT
STR$ TEMP ;THEN OUTPUT IT
STR$ [ASCIZ/
/] ;SPACE DOWN SOME
QUENOC: CALL GETPID ;GO OBTAIN PIDS FOR MYSELF AND QUASAR
JRST LOSE ;FAILED, GO COMPLAIN
CALL SETEAT ;GO SET UP HOW MANY LINES TO EAT
MOVEI T1,MBLK-1 ;POINT AT DATA BLOCK
PUSH T1,[0] ;NO FLAGS
PUSH T1,MYPID ;STORE SENDER
PUSH T1,QSRPID ;AND RECEIVER
PUSH T1,[XWD QSRLEN,QSRMSG] ;AND POINTER TO DATA
MOVEI T1,4 ;SIZE OF PACKET DESCRIPTER BLOCK
MOVEI T2,MBLK ;ADDRESS OF BLOCK
MSEND ;SEND THE PACKET TO QUASAR
ERJMP [SETZM QSRPID ;FAILED, CLEAR PID IN CASE NOT VALID
JRST LOSE] ;AND GO COMPLAIN
TXZ F,FR.TMP ;INITIALIZE FIRST TIME FLAG
;NOW READ THE REPLY FROM QUASAR AND TYPE IT:
RECLOP: MOVEI T1,MBLK-1 ;POINT AT DATA BLOCK
PUSH T1,[IP%CFV] ;SET UP FLAGS
PUSH T1,QSRPID ;INTENDED SENDER (IGNORED)
PUSH T1,MYPID ;AND RECEIVER
PUSH T1,[1000,,DATLOC/1000] ;AND POINTER TO DATA
MOVEI T1,4 ;LENGTH OF BLOCK
MOVEI T2,MBLK ;ADDRESS OF BLOCK
MRECV ;BLOCK UNTIL A MESSAGE IS RETURNED
ERJMP [SETZM QSRPID ;FAILED, CLEAR PID IN CASE NO LONGER VALID
JRST LOSE] ;AND SAY WHAT HAPPENED
MOVE T1,MBLK+.IPCFS ;GET PID WHO SENT TO US
CAME T1,QSRPID ;FROM QUASAR?
JRST RECLOP ;NO, IGNORE THE PACKET
MOVEI T1,DATLOC+.OHDRS ;POINT AT FIRST BLOCK
HLRZ T2,(T1) ;GET SIZE OF THE BLOCK
TXOE F,FR.TMP ;FIRST PAGE OF DATA?
JRST QUETYP ;NO, JUST TYPE THE STRING
ADDB T1,T2 ;MOVE TO BLOCK WE WANT
MOVEI T3,177 ;YES, GET SET TO EAT LEADING CRLFS
TLOA T2,(POINT 7,0,34) ;MAKE A BYTE POINTER
RUBSTR: DPB T3,T2 ;STORE A RUBOUT
ILDB T4,T2 ;GET NEXT CHARACTER
CAIE T4,15 ;CARRIAGE RETURN?
CAIN T4,12 ;OR LINE FEED?
JRST RUBSTR ;YES, GO REPLACE WITH RUBOUT
QUETYP: STR$ 1(T1) ;OUTPUT THE TEXT
MOVE T1,DATLOC+.OFLAG ;GET FLAGS
TXNE T1,WT.MOR ;MORE MESSAGES COMING?
JRST RECLOP ;YES, LOOP
RET ;NO, ALL DONE
SUBTTL ROUTINE TO OBTAIN ALL NECESSARY PIDS
;CALLED TO OBTAIN PIDS FOR SYSTEM INFO, QUASAR, AND MYSELF.
;SKIP RETURN IF SUCCESSFUL, NON-SKIP IF FAILED.
GETPID: SKIPE INFPID ;HAVE A PID FOR SYSTEM INFO?
JRST GETQSP ;YES, GO SEE ABOUT QUASAR
MOVEI T1,3 ;SIZE OF BLOCK
MOVEI T2,MBLK ;ADDRESS OF IT TOO
MOVEI T3,.MURSP ;FUNCTION TO READ SYSTEM PIDS
MOVEM T3,MBLK ;SET IT UP
MOVEI T3,.SPINF ;WANT TO GET SYSTEM INFO
MOVEM T3,MBLK+1 ;STORE IT
MUTIL ;DO THE WORK
ERJMP CPOPJ ;FAILED
MOVE T1,MBLK+2 ;GET THE PID
MOVEM T1,INFPID ;SAVE FOR LATER
GETQSP: SKIPE QSRPID ;DO WE HAVE QUASAR'S PID?
JRST GETMYP ;YES, GO SEE ABOUT MY OWN PID
MOVEI T1,3 ;SIZE OF ARGUMENT BLOCK
MOVEI T2,MBLK ;AND ADDRESS OF ARGUMENT BLOCK
MOVEI T3,.MURSP ;FUNCTION TO RETURN A PID
MOVEM T3,MBLK ;SET IT
MOVEI T3,.SPQSR ;CODE FOR QUASAR
MOVEM T3,MBLK+1 ;SET IT
MUTIL ;ASK MONITOR FOR THE PID
ERJMP CPOPJ ;FAILED, ERROR RETURN
MOVE T1,MBLK+2 ;GET THE PID
MOVEM T1,QSRPID ;AND REMEMBER IT FOR LATER
GETMYP: SKIPE MYPID ;SEE IF ALREADY HAVE OUR PID
RETSKP ;YES, GOOD RETURN
MOVEI T1,3 ;A FEW ARGUMENTS
MOVEI T2,MBLK ;NORMAL ARGUMENT BLOCK
MOVEI T3,.MUCRE ;FUNCTION TO CREATE A PID
MOVEM T3,MBLK ;SET IT UP
MOVEI T3,.FHSLF ;WANT A PID FOR MY PROCESS
MOVEM T3,MBLK+1 ;STORE THE ARGUMENT
MUTIL ;ASK TO HAVE A PID CREATED FOR US
ERJMP CPOPJ ;FAILED
MOVE T1,MBLK+2 ;GET THE PID THAT WAS OBTAINED
MOVEM T1,MYPID ;REMEMBER IT
RETSKP ;GOOD RETURN
SUBTTL DISPLAY ROUTINE TO TYPE PIDS ON THE SYSTEM
;CALLED TO DISPLAY INFORMATION ABOUT IPCF DATA SYSTEM-WIDE.
;MOST THINGS CAN BE OBTAINED BY THE MUTIL JSYS, BUT SOME THINGS
;NEED THE MONRD% JSYS TO DO.
DPYIPC: MOVEI T1,TP.IPC ;THIS IS IPCF DATA
CALL HDRSET ;SO SET UP THE HEADER
TXO F,FR.EAT ;DO EATING OF LINES AFTER HEADER
SETOM PIDJOB ;CLEAR JOB NUMBER FOR LOOP
SETOM OLDJOB ;CLEAR OLD JOB NUMBER TOO
IPCLOP: AOS T2,PIDJOB ;MOVE TO NEXT JOB
CAMG T2,HGHJOB ;DID ALL JOBS?
CALL FULL ;OR IS SCREEN FULL?
RET ;YES, DONE
MOVEM T2,PIDTAB+1 ;NO, SET JOB NUMBER IN BLOCK
MOVEI T1,IPCSIZ ;GET SIZE OF BLOCK
MOVEI T2,PIDTAB ;AND ADDRESS OF BLOCK
MOVEI T3,.MUFJP ;GET FUNCTION CODE
MOVEM T3,PIDTAB ;AND SET IT
MUTIL ;ASK MONITOR TO READ INFO
ERJMP IPCLOP ;FAILED, ASK ABOUT NEXT JOB
MOVEI J,PIDTAB ;POINT AT START OF PID LIST
PIDLOP: ADDI J,2 ;MOVE TO NEXT PID PAIR
SKIPN (J) ;ANOTHER PID TO SHOW?
JRST IPCLOP ;NO, GO DO NEXT JOB
CALL DOCOLS ;YES, SHOW INFO ON THIS PID
JRST PIDLOP ;THEN GO DO ANOTHER ONE
;HERE TO OUTPUT THE VARIOUS THINGS ABOUT EACH PID FOUND.
XXPIDJ: MOVE T1,PIDJOB ;GET JOB NUMBER THIS PID IS FROM
CAMN T1,OLDJOB ;SAME AS LAST TIME?
RET ;YES, RETURN
MOVEM T1,OLDJOB ;NO, SET IT
JRST DECSP2 ;AND OUTPUT IT
XXPID: HLRZ T1,0(J) ;GET LEFT HALF OF PID
CALL OCTSP6 ;OUTPUT IN FIELD OF 6
STR$ [ASCIZ/,,/] ;THEN COMMAS
HRRZ T1,0(J) ;GET RIGHT HALF OF PID
JRST OCTOUT ;OUTPUT IT AND RETURN
XXPIDF: MOVE T1,1(J) ;GET WORD OF FLAGS
TXNE T1,IP%JWP ;IS THIS A JOB-WIDE PID?
STR$ [ASCIZ/Job /] ;YES, SAY SO
TXNE T1,IP%NOA ;ACCESSIBLE BY OTHER PROCESSES?
STR$ [ASCIZ/Res /] ;NO, SAY SO
MOVE T1,[PD.FLG] ;GET BYTE POINTER
CALL PIDMON ;ASK MONITOR FOR DATA
RET ;FAILED
TXNE T1,PD%DIS ;IS THE PID DISABLED?
STR$ [ASCIZ/Dis/] ;YES, SAY SO
RET ;DONE
XXPQTA: MOVEI T1,3 ;THREE WORDS
MOVEI T2,MBLK ;POINT TO ARGUMENT BLOCK
MOVEI T3,.MUFSQ ;GET FUNCTION CODE
MOVEM T3,MBLK ;SET IT
MOVE T3,0(J) ;GET THE PID TO ASK ABOUT
MOVEM T3,MBLK+1 ;STORE AS ARGUMENT
MUTIL ;ASK MONITOR ABOUT THE PID
ERJMP CPOPJ ;FAILED
LDB T1,[POINT 9,MBLK+2,26] ;GET SEND QUOTA
CALL DECSP4 ;OUTPUT IT
CHI$ "/" ;TYPE A SLASH
LDB T1,[POINT 9,MBLK+2,35] ;GET RECEIVE QUOTA
JRST DECOUT ;OUTPUT IT AND RETURN
XXSYSP: CALL SYSPID ;READ ALL OF THE SYSTEM PIDS
MOVE T1,0(J) ;GET THE PID
MOVSI T2,-PIDNUM ;AND A COUNTER FOR LOOPING
CAME T1,PIDSYS(T2) ;FOUND THE PID YET?
AOBJN T2,.-1 ;NO, KEEP SEARCHING
JUMPGE T2,CPOPJ ;RETURN IF NOT A SYSTEM PID
STR$ [ASCIZ/ /] ;SPACE OVER SOME
STR$ @PIDNAM(T2) ;OUTPUT THE NAME OF THIS PID
RET ;DONE
;TABLE OF SYSTEM PID NAMES:
PIDNAM: EXP [ASCIZ/IPCC/] ;(0) SYSTEM IPCC
EXP [ASCIZ/INFO/] ;(1) <SYSTEM>INFO
EXP [ASCIZ/QUASAR/] ;(2) QUEUEING SYSTEM CONTROLLER
EXP [ASCIZ/QSRMDA/] ;(3) MOUNTABLE DEVICE ALLOCATOR
EXP [ASCIZ/ORION/] ;(4) OPERATOR SERVICE PROGRAM
EXP [ASCIZ/NETCON/] ;(5) DECNET CONTROLLER
PIDNUM==.-PIDNAM ;NUMBER OF ENTRIES
XXPPRG: HRLZ T1,PIDJOB ;GET JOB NUMBER
HRRI T1,.JOBPN ;INDEX FOR PROGRAM NAME
GETAB ;GET IT
ERJMP CPOPJ ;FAILED
JRST SIXOUT ;OUTPUT IN SIXBIT
XXRECC: MOVE T1,[PD.CNT] ;GET POINTER TO OUTSTANDING PACKETS
CALL PIDMON ;ASK MONITOR FOR DATA
RET ;FAILED
JRST OCTSP4 ;OUTPUT AND RETURN
XXPOWN: MOVE T1,[PD.FKO] ;GET OWNER FORK POINTER
CALL PIDMON ;ASK MONITOR FOR DATA
RET ;FAILED
JRST OCTSP3 ;OUTPUT IT
XXPDWT: MOVE T1,[PD.FKW] ;GET FORK WAIT FIELD
CALL PIDMON ;ASK MONITOR FOR DATA
RET ;FAILED
CAIN T1,-1 ;NO FORK IN A WAIT?
STR$ [ASCIZ/--/] ;YES, SAY SO
CAIE T1,-1 ;WELL?
JRST OCTOUT ;YES, GO OUTPUT IT
RET ;DONE
;LOCAL SUBROUTINE TO READ DATA ABOUT A PID BY USE OF MONRD% JSYS.
;BYTE POINTER TO DATA IS IN T1. RETURNS VALUE IN T1 IF SUCCESSFUL.
;NON-SKIP IF FAIL.
PIDMON: HRRZ T3,T1 ;PUT OFFSET IN RIGHT PLACE
HLLZ T4,T1 ;SAVE BYTE POINTER
MOVEI T1,.RDPID ;FUNCTION CODE
MOVE T2,0(J) ;GET PID TO READ DATA OF
MONRD% ;DO THE WORK
ERJMP CPOPJ ;FAILED
JUMPL T1,CPOPJ ;ALSO FAILED
HRRI T4,T2 ;MAKE BYTE POINTER POINT TO DATA
LDB T1,T4 ;GET THE DATA
RETSKP ;GOOD RETURN
XXPNAM: CALL GETPID ;OBTAIN A PID FOR MYSELF
RET ;FAILED, CAN'T FIND NAME
MOVEI T1,MBLK-1 ;POINT AT ARGUMENT BLOCK
PUSH T1,[0] ;NO FLAGS
PUSH T1,MYPID ;SET MY PID AS THE SENDER
PUSH T1,[0] ;RECEIVER IS SYSTEM INFO
PUSH T1,[3,,INFMSG] ;POINT AT DATA TO SEND
MOVE T1,0(J) ;GET THE PID TO ASK ABOUT
MOVEM T1,INFDAT ;SET AS DATA FOR SYSTEM INFO
MOVEI T1,4 ;LENGTH OF ARGUMENT BLOCK
MOVEI T2,MBLK ;ADDRESS
MSEND ;SEND THE PACKET
ERJMP LOSE ;FAILED
INFREC: MOVE T1,[TEMP,,TEMP+1] ;GET SET
SETZM TEMP ;TO CLEAR SOME WORDS
BLT T1,TEMP+TMPSIZ-1 ;DO IT
MOVEI T1,MBLK-1 ;POINT AT DATA BLOCK
PUSH T1,[0] ;NO FLAGS
PUSH T1,[0] ;SENDER IS IGNORED
PUSH T1,MYPID ;MY PID IS THE RECEIVER
PUSH T1,[TMPSIZ,,TEMP] ;PLACE TO STORE ANSWER
MOVEI T1,4 ;GET LENGTH
MOVEI T2,MBLK ;AND ADDRESS OF BLOCK
MRECV ;RECEIVE THE ANSWER
ERJMP LOSE ;FAILED
MOVE T1,MBLK+.IPCFS ;GET SENDER
CAME T1,INFPID ;IS IT FROM SYSTEM INFO?
JRST INFREC ;NO, IGNORE IT
TXNE F,FR.MOR ;ANY MORE COLUMNS COMING?
SETZM TEMP+5 ;YES, THEN RESTRICT THE NAME
STR$ TEMP+1 ;OUTPUT THE NAME
RET ;DONE
SUBTTL SUBROUTINE TO READ ALL SYSTEM PIDS
;CALLED TO OBTAIN THE SYSTEM PIDS AND STORE THEM IN A TABLE FOR
;LATER USE. ANY PID WHICH DOES NOT EXIST WILL BE ZERO.
SYSPID: MOVEI T1,.MURSP ;FUNCTION TO READ SYSTEM PID TABLE
MOVEM T1,MBLK ;SET IT
SETOM MBLK+1 ;AND INITIALIZE OFFSET
SYSPIL: AOS T1,MBLK+1 ;ADVANCE TO THE NEXT OFFSET
CAIL T1,PIDNUM ;DID ALL KNOWN SYSTEM PIDS?
RET ;YES, DONE
SETZM PIDSYS(T1) ;CLEAR WORD IN CASE MUTIL FAILS
MOVEI T1,3 ;SIZE OF ARGUMENT BLOCK
MOVEI T2,MBLK ;ADDRESS OF THE BLOCK
MUTIL ;READ THE PID VALUE
ERJMP SYSPIL ;FAILED, TRY NEXT ONE
DMOVE T1,MBLK+1 ;GET THE OFFSET AND THE PID
MOVEM T2,PIDSYS(T1) ;REMEMBER THE PID
JRST SYSPIL ;LOOP
SUBTTL DISPLAY FOR DISK STATUS
;THIS DISPLAY TYPES OUT THE STATUS OF ALL THE DISK DRIVES ON THE
;SYSTEM. UNFORTUNATELY, THIS CURRENTLY REQUIRES WHEEL PRIVILEGES
;TO WORK. ONLY USES THE MSTR JSYS.
DPYDSK: CALL DOSTR ;GO TYPE THE STATUS OF ALL STRUCTURES
MOVEI T1,TP.DSK ;THIS IS THE DISK OUTPUT DISPLAY
CALL HDRSET ;SO SET UP HEADERS AND TAB STOPS
TXO F,FR.EAT ;REMEMBER TO SET UP EATING LATER
SETOM SBLK+.MSRCH ;INITIALIZE CHANNEL NUMBER
SETOM SBLK+.MSRCT ;CONTROLLER NUMBER
SETOM SBLK+.MSRUN ;AND UNIT NUMBER
DSKLOP: HRROI T1,STRUC ;GET POINTER TO STRUCTURE NAME
MOVEM T1,SBLK+.MSRSN ;SET IN ARGUMENT BLOCK
HRROI T1,ALIAS ;GET POINTER TO ALIAS NAME
MOVEM T1,SBLK+.MSRSA ;PUT IN ARGUMENT BLOCK
SETZM STRUC ;CLEAR NAMES IN CASE NOT FILLED IN
SETZM ALIAS ;SO WON'T BE CONFUSED
MOVE T1,[.MSRBT+1,,.MSRNU] ;GET LENGTH AND FUNCTION
MOVEI T2,SBLK ;AND ADDRESS OF ARGUMENT BLOCK
MSTR ;DO THE WORK
ERJMP DSKDON ;FAILED, GO SEE WHY
MOVE T1,SBLK+.MSRCH ;GET CHANNEL
MOVE T2,SBLK+.MSRCT ;AND CONTROLLER NUMBER
MOVE T3,SBLK+.MSRUN ;AND UNIT NUMBER
CALL GETUDB ;GO READ IN THE UDB FOR THIS DISK
TXZA F,FR.UDB ;UDB IS INVALID
TXO F,FR.UDB ;UDB IS OK
CALL DOCOLS ;SHOW DATA ABOUT THIS UNIT
JRST DSKLOP ;DO NEXT UNIT
DSKDON: MOVEI T1,.FHSLF ;GET READY
GETER ;READ LAST ERROR IN MY JOB
ANDI T2,-1 ;REMOVE THE FORK HANDLE
CAIE T2,MSTX18 ;NO MORE UNITS?
JRST LOSE ;NO, SOME OTHER ERROR
RET ;YES, DONE
;ROUTINES CALLED TO OUTPUT THE COLUMNS ABOUT THE DISK UNITS:
XXCHAN: MOVE T1,SBLK+.MSRCH ;GET CHANNEL NUMBER
JRST OCTSP2 ;OUTPUT IT AND RETURN
XXUNIT: MOVE T1,SBLK+.MSRUN ;GET UNIT NUMBER
JRST OCTSP3 ;OUTPUT IT AND RETURN
XXCTRL: SKIPL T1,SBLK+.MSRCT ;GET CONTROLLER NUMBER
JRST OCTSP2 ;IF ONE, TYPE IT
STR$ [ASCIZ/ -/] ;OTHERWISE SAY THERE IS NONE
RET ;DONE
XXSTR: STR$ STRUC ;OUTPUT THE STRUCTURE NAME
RET ;DONE
XXALIS: STR$ ALIAS ;OUTPUT THE ALIAS NAME
RET ;DONE
XXLUNT: MOVE T1,SBLK+.MSRST ;GET STATUS
TXNE T1,MS%OFL ;IS DISK OFF LINE?
RET ;YES, CAN'T KNOW THIS THEN
HLRZ T1,SBLK+.MSRNS ;GET LOGICAL UNIT NUMBER
ADDI T1,1 ;INCREMENT BY 1
CALL OCTOUT ;OUTPUT IT
CHI$ "/" ;THEN A SLASH
HRRZ T1,SBLK+.MSRNS ;GET TOTAL UNITS IN STRUCTURE
JRST OCTOUT ;OUTPUT IT
XXSWAP: MOVE T1,SBLK+.MSRST ;GET STATUS BITS
TXNE T1,MS%OFL ;OFF LINE?
RET ;YES, THEN NO INFORMATION AVAILABLE
MOVE T1,SBLK+.MSRSW ;GET NUMBER OF SWAPPING SECTORS
IDIV T1,SBLK+.MSRSP ;CONVERT FROM SECTORS TO PAGES
JRST DECSP6 ;OUTPUT IT AND RETURN
XXUSTS: MOVE T1,SBLK+.MSRST ;GET STATUS BITS
TXNE T1,MS%MNT ;MOUNTED?
STR$ [ASCIZ/Mount /] ;YES, SAY SO
TXNE T1,MS%DIA ;DOING DIAGNOSTICS?
STR$ [ASCIZ/Diag /] ;YES, SAY SO
TXNE T1,MS%OFL ;IS IT OFF-LINE?
STR$ [ASCIZ/Offline /] ;YES, SAY SO
TXNN T1,MS%MNT!MS%DIA!MS%OFL ;READY BUT NOT IN USE?
STR$ [ASCIZ/Free /] ;YES, SAY ITS FREE
TXNE T1,MS%ERR ;ERROR DURING READING?
STR$ [ASCIZ/Err /] ;YES, SAY SO
TXNE T1,MS%BBB ;BAD BAT BLOCKS?
STR$ [ASCIZ/BadBAT /] ;YES, SAY SO
TXNE T1,MS%HBB ;BAD HOME BLOCK?
STR$ [ASCIZ/BadHOM /] ;YES, SAY SO
TXNE T1,MS%WLK ;WRITE LOCKED?
STR$ [ASCIZ/Wrtlck/] ;YES, SAY SO
RET ;DONE
XXTYPE: LDB T1,[POINT 9,SBLK+.MSRST,17] ;GET TYPE FIELD
MOVSI T2,-TYPNUM ;GET SET FOR SEARCH
HLRZ T3,TYPTAB(T2) ;GET NEXT POSSIBLE MATCH
CAME T1,T3 ;FOUND IT?
AOBJN T2,.-2 ;NO, KEEP SEARCHING
JUMPGE T2,OCTSP3 ;IF NOT FOUND, TYPE IN OCTAL
HRRZ T1,TYPTAB(T2) ;GET ADDRESS OF STRING
STR$ (T1) ;TYPE IT
RET ;DONE
TYPTAB: XWD .MSRP4,[ASCIZ/RP04/] ;RP04 DISK
XWD .MSRP5,[ASCIZ/RP05/] ;RP05 DISK
XWD .MSRP6,[ASCIZ/RP06/] ;RP06 DISK
XWD .MSRP7,[ASCIZ/RP07/] ;RP07 DISK
XWD .MSRM3,[ASCIZ/RM03/] ;RM03 DISK
XWD .MSR20,[ASCIZ/RP20/] ;RP20 DISK
TYPNUM==.-TYPTAB ;NUMBER OF ENTRIES
XXSEEK: TXNN F,FR.UDB ;IS THE UDB VALID?
RET ;NO, TYPE NOTHING
MOVE T1,UDBSEK ;GET OFFSET
MOVE T1,UDB(T1) ;GET THE DATA TO TYPE
JRST DECSP6 ;GO OUTPUT IT
XXREAD: SKIPA T1,UDBRED ;GET OFFSET FOR READS
XXWRIT: MOVE T1,UDBWRT ;OR OFFSET FOR WRITES
TXNN F,FR.UDB ;IS THE UDB VALID?
RET ;NO, QUIT
MOVE T1,UDB(T1) ;GET THE NUMBER OF READS OR WRITES
IDIV T1,SBLK+.MSRSP ;DIVIDE TO GET PAGES
JRST DECSP6 ;GO OUTPUT IT
XXRDER: MOVE T1,UDBSRE ;SOFT READ ERRORS
MOVE T4,UDBHRE ;AND HARD READ ERROS
TYPERR: TXNN F,FR.UDB ;IS THE UDB VALID?
RET ;NO
MOVE T1,UDB(T1) ;GET NUMBER OF SOFT ERRORS
MOVE T4,UDB(T4) ;AND NUMBER OF HARD ERRORS
JUMPN T1,TYPERY ;GO ON IF HAVE ANY ERRORS
JUMPN T4,TYPERY ;OF EITHER TYPE
STR$ [ASCIZ/ -- --/] ;NONE, SAY SO
RET ;DONE
TYPERY: CALL DECSP3 ;OUTPUT NUMBER OF SOFT ERRORS
STR$ [ASCIZ/S /] ;MARK THEM AS SOFT AND SPACE OVER
MOVE T1,T4 ;GET ERROR COUNT
CALL DECSP3 ;OUTPUT NUMBER OF HARD ERRORS
CHI$ "H" ;MARK THEM AS HARD
RET ;DONE
XXWTER: MOVE T1,UDBSWE ;SOFT WRITE ERROR
MOVE T4,UDBHWE ;AND HARD WRITE ERROR
JRST TYPERR ;GO OUTPUT THEM
XXPSER: MOVE T1,UDBSPE ;SOFT POSITIONING ERROR
MOVE T4,UDBHPE ;HARD POSITIONING ERROR
JRST TYPERR ;GO OUTPUT THEM
SUBTTL SUBROUTINE TO READ THE UDB OF A DISK OR MAGTAPE UNIT
;CALLED WITH CHANNEL NUMBER IN T1, CONTROLLER ON THAT CHANNEL IN T2, AND
;UNIT ON THE CONTROLLER IN T3, TO RETURN STARTING IN LOCATION UDB THE
;UNIT DATA BLOCK FOR THAT DEVICE. THIS ROUTINE REQUIRES PRIVILEGES AS
;PEEKS ARE USED TO OBTAIN THE INFORMATION. SKIP RETURN IF SUCCESSFUL.
GETUDB: SKIPL T1 ;RANGE CHECK CHANNEL NUMBER
CAILE T1,7 ;WHICH CAN ONLY BE FROM 0 TO 7
RET ;BAD, GIVE ERROR
CAML T2,[-1] ;RANGE CHECK THE CONTROLLER NUMBER
CAILE T2,7 ;WHICH CAN ONLY BE FROM -1 TO 7
RET ;BAD, GIVE ERROR
JUMPL T3,CPOPJ ;NEGATIVE UNIT NUMBER IS ILLEGAL
SKIPGE T2 ;ANY CONTROLLER?
CAIG T3,7 ;NO, THEN UNIT HAS TO BE FROM 0 TO 7
CAILE T3,377 ;YES, THEN UNIT CAN BE FROM 0 TO 377
RET ;NOPE, FAIL
MOVEM T1,CHAN ;SAVE CHANNEL
MOVEM T2,CTRL ;CONTROLLER
MOVEM T3,UNIT ;AND UNIT TOO
CALL UDBSYM ;GO OBTAIN ALL UDB SYMBOLS NEEDED
RET ;FAILED
MOVE T1,CHAN ;GET BACK CHANNEL NUMBER
ADD T1,CHNTAB ;CREATE ADDRESS OF CHANNEL POINTER
CALL DOPEEK ;OBTAIN THE CDB ADDRESS
RET ;FAILED
JUMPE T1,CPOPJ ;IF ZERO, NO SUCH CHANNEL
ADD T1,CDBUDB ;ADD IN ADDRESS OF THE UDB/KDB POINTERS
SKIPGE T2,CTRL ;ANY CONTROLLER?
MOVE T2,UNIT ;NO, THEN GET UNIT INSTEAD
ADD T1,T2 ;ADD IN CONTROLLER/UNIT NUMBER
CALL DOPEEK ;OBTAIN THE UDB/KDB ADDRESS
RET ;FAILED
JUMPE T1,CPOPJ ;IF ZERO, NO SUCH UNIT
SKIPGE CTRL ;ANY CONTROLLER?
JRST HAVUDB ;NO, THEN WE HAVE THE UDB ADDRESS NOW
ADD T1,KDBIUN ;ADD OFFSET OF UDB POINTERS
CALL DOPEEK ;READ AOBJN WORD TO UNITS OF CONTROLLER
RET ;FAILED
JUMPGE T1,CPOPJ ;IF NO UNITS, FAIL
MOVE T4,T1 ;MOVE TO SAFE AC
UDBSRC: HRRZ T1,T4 ;GET ADDRESS OF NEXT UDB POINTER
CALL DOPEEK ;READ THE POINTER
RET ;FAILED
JUMPE T1,UDBSRN ;IF NONE, TRY NEXT UNIT
MOVEM T1,TEMP ;REMEMBER UDB ADDRESS FOR LATER
ADD T1,UDBSLV ;ADD IN OFFSET TO GET SLAVE NUMBER
CALL DOPEEK ;READ THE SLAVE NUMBER
RET ;FAILED
ANDI T1,-1 ;KEEP ONLY THE RIGHT HALF
CAME T1,UNIT ;IS THIS THE REQUIRED UNIT?
UDBSRN: AOBJN T4,UDBSRC ;NO, SEARCH SOME MORE
JUMPGE T4,CPOPJ ;FAIL IF NOT FOUND
MOVE T1,TEMP ;RESTORE THE UDB ADDRESS
HAVUDB: MOVE T2,UDBDDP ;GET SIZE OF UDB
CAIL T2,UDBSIZ ;MAKE SURE BLOCK IS LARGE ENOUGH
RET ;NO, THEN FAIL
HRL T1,T2 ;PUT SIZE IN LEFT HALF
MOVEI T2,UDB ;SET UP ADDRESS WHERE DATA GOES
DOPEEK: TLNN T1,-1 ;WANT A SINGLE WORD OF DATA?
MOVEI T2,T3 ;YES, POINT TO AC TO RECEIVE ANSWER
TLNN T1,-1 ;WELL?
HRLI T1,1 ;YES, WANT ONLY ONE WORD
PEEK ;ASK MONITOR FOR DATA
ERJMP CPOPJ ;FAILED
MOVE T1,T3 ;PUT ANSWER IN RIGHT AC
RETSKP ;GOOD RETURN
SUBTTL SUBROUTINE TO OBTAIN UDB SYMBOLS BY SNOOPING
;HERE TO FILL IN THE TABLE OF OFFSETS AND SUCH SO WE CAN DO PEEKS
;WITH THE DATA.
UDBSYM: TXNE F,FR.UDS ;DO WE ALREADY HAVE THE SYMBOLS?
RETSKP ;YES, GOOD RETURN
MOVSI T4,-NUMUDB ;GET READY FOR LOOP
UDBSYL: MOVEI T1,.SNPSY ;GET FUNCTION CODE
MOVE T2,TBSUDB(T4) ;GET WORD OF DATA
MOVE T3,TBMUDB(T4) ;AND PROGRAM NAME
SNOOP ;GET THE VALUE
ERJMP CPOPJ ;FAILED
MOVEM T2,TBVUDB(T4) ;SAVE THE VALUE
AOBJN T4,UDBSYL ;LOOP OVER ALL WORDS
TXO F,FR.UDS ;SYMBOLS ARE NOW GOTTEN
RETSKP ;GOOD RETURN
;TABLE OF SYMBOLS WE WANT TO SNOOP. THIS MACRO IS EXPANDED LATER ON
;IN THE PROGRAM.
DEFINE USYMS,< ;SYMBOLS WE WANT TO KNOW ABOUT
XX CHNTAB,STG ;;TABLE OF CHANNEL ADDRESSES
XX CDBUDB ;;OFFSET IN CDB TO START OF UDBS
XX KDBIUN,PHYSIO ;;POINTER TO UDB ADDRESSES
XX UDBDDP,PHYP4 ;;FIRST WORD OF DEVICE DEPENDENT PART
XX UDBSEK ;;NUMBER OF SEEKS
XX UDBRED ;;READS
XX UDBWRT ;;WRITES
XX UDBSRE ;;SOFT READ ERRORS
XX UDBSWE ;;SOFT WRITE ERRORS
XX UDBHRE ;;HARD READ ERRORS
XX UDBHWE ;;HARD WRITE ERRORS
XX UDBSPE,PHYP4 ;;SOFT POSITIONING ERROR
XX UDBHPE,PHYP4 ;;HARD POSITIONING ERROR
XX UDBSLV,PHYSIO ;;UNIT NUMBER ON CONTROLLER
>
SUBTTL SUBROUTINE TO TYPE STRUCTURE STATUS
;CALLED TO OUTPUT THE STATUS OF EACH MOUNTED STRUCTURE ON THE SYSTEM,
;SUCH AS THE AMOUNT OF SPACE USED ON EACH ONE, AND THE MOUNT COUNTS.
;NO PRIVILEGES REQUIRED FOR THIS OUTPUT.
DOSTR: MOVEI T1,TP.STR ;THIS IS THE STRUCTURE DISPLAY
CALL HDRSET ;SO SET IT UP
TXO F,FR.EAT ;REMEMBER TO EAT LINES AFTERWARD
SETO J, ;GET READY FOR LOOP
STRSTL: ADDI J,1 ;MOVE TO NEXT POSSIBLE DEVICE
MOVSI T1,(J) ;GET READY
IORI T1,.DEVCH ;TO GET DATA ON THIS DEVICE
GETAB ;GET IT
ERJMP CPOPJ ;FAILED, ASSUME NO MORE
LDB T1,[POINTR T1,DV%TYP] ;GET DEVICE TYPE
CAIE T1,.DVDSK ;IS THIS A DISK?
JRST STRSTL ;NO, TRY NEXT DEVICE
MOVSI T1,(J) ;GET READY
IORI T1,.DEVNA ;TO OBTAIN THE DEVICE NAME
GETAB ;GET IT
ERJMP CPOPJ ;FAILED
CAMN T1,['DSK '] ;IS THIS THE GENERIC DISK?
JRST STRSTL ;YES, DON'T USE IT
CALL SIXASC ;CONVERT FROM SIXBIT TO ASCIZ
DMOVE T1,TEMP ;GET THE NAME
DMOVEM T1,DEVNAM ;SAVE IT AWAY
HRROI T1,DEVNAM ;GET A POINTER
MOVEM T1,MBLK+.MSGSN ;AND SET IN ARGUMENT BLOCK
MOVE T1,[.MSGFC+1,,.MSGSS] ;GET READY
MOVEI T2,MBLK ;POINT TO DATA AREA
MSTR ;ASK ABOUT THIS STRUCTURE
ERJMP STRSTL ;FAILED, LOOP
SETZM HAVALC ;CLEAR FLAG SAYING HAVE ALLOCATION INFO
CALL DOCOLS ;NOW SHOW THE DATA
JRST STRSTL ;LOOP
;ROUTINES TO OUTPUT DATA ABOUT EACH STRUCTURE:
XXSTNM: SPACE ;SPACE OVER FIRST
STR$ DEVNAM ;OUTPUT THE NAME OF THE STRUCTURE
RET ;DONE
XXSTST: MOVE T1,MBLK+.MSGST ;GET THE STATUS BITS
TXNE T1,MS%PS ;IS THIS PUBLIC?
STR$ [ASCIZ/Public /] ;YES, SAY SO
TXNE T1,MS%DIS ;IS IT BEING DISMOUNTED?
STR$ [ASCIZ/Dismount /] ;YES, SAY SO
TXNE T1,MS%DOM ;IS IT DOMESTIC?
STR$ [ASCIZ/Domestic /] ;YES
TXNN T1,MS%DOM ;IS IT FOREIGN?
STR$ [ASCIZ/Foreign /] ;YES, SAY SO
TXNE T1,MS%LIM ;IS STRUCTURE LIMITED?
STR$ [ASCIZ/Limit /] ;YES, SAY SO
TXNN T1,MS%NRS ;IS STRUCTURE REGULATED?
STR$ [ASCIZ/Regulated /] ;YES, SAY SO
TXNE T1,MS%INI ;IS IT BEING INITIALIZED?
STR$ [ASCIZ/Init/] ;YES, SAY SO
RET ;DONE
XXSTMC: MOVE T1,MBLK+.MSGMC ;GET THE MOUNT COUNT
JRST DECSP3 ;OUTPUT IT
XXSTOF: MOVE T1,MBLK+.MSGFC ;GET OPEN FILE COUNT
JRST DECSP3 ;OUTPUT IT
XXSTPG: CALL GETALC ;OBTAIN ALLOCATION DATA FOR STRUCTURE
RET ;FAILED
MOVE T1,T2 ;GET FREE PAGES
JRST DECSP5 ;OUTPUT IT
XXSTSZ: CALL GETALC ;GET ALLOCATION INFORMATION
RET ;FAILED
ADD T1,T2 ;ADD TOGETHER TO GET SIZE
JRST DECSP6 ;OUTPUT IT
SUBTTL ROUTINE TO GET ALLOCATION INFO
;CALLED TO GET THE ALLOCATION DATA FOR A STRUCTURE WHOSE NAME IS
;IN LOCATION STRNAM. SKIP RETURN IF SUCCESSFUL. TO SAVE TIME,
;WE DON'T RECOMPUTE THE DATA IF THE FLAG HAVALC IS SET.
GETALC: DMOVE T1,STRALC ;GET ALLOCATION INFORMATION
SKIPE HAVALC ;IS IT CORRECT?
RETSKP ;YES, GOOD RETURN
HRROI T1,DEVNAM ;GET READY
STDEV ;CONVERT NAME TO DESIGNATOR
ERJMP CPOPJ ;FAILED, CAN'T DO THIS
MOVE T1,T2 ;MOVE TO RIGHT AC
GDSKC ;READ DISK ALLOCATION INFO
ERJMP CPOPJ ;FAILED
DMOVEM T1,STRALC ;SAVE FOR LATER
SETOM HAVALC ;SAY HAVE THE DATA
RETSKP ;GOOD RETURN
SUBTTL DISPLAY FOR ENQ/DEQ STATUS
;THIS DISPLAY TYPES ALL OF THE ENQ LOCKS AND THE QUEUES FOR THOSE
;LOCKS. WHEEL PRIVILEGES ARE REQUIRED FOR THIS DISPLAY, SINCE WE
;USE THE ENQC JSYS TO COLLECT THE DATA.
DPYENQ: MOVEI T1,.ENQCD ;FUNCTION TO DUMP THE QUEUES
MOVEI T2,DATLOC ;ADDRESS OF WHERE TO DUMP THEM
MOVEI T3,DATSIZ ;GET SIZE OF AREA
MOVEM T3,DATLOC ;SET FOR MONITOR
ENQC ;READ ALL OF THE DATA
ERJMP LOSE ;FAILED, GO EXPLAIN TO USER
MOVEI T1,TP.EQL ;TYPE OF HEADER IS ENQ-LOCKS
CALL HDRSET ;SET UP TAB STOPS AND TITLE
TXO F,FR.EAT ;EAT LINES AFTER THE TITLE
SETZM LOKNUM ;CLEAR NUMBER OF LOCKS FOUND
MOVEI J,DATLOC+1 ;SET UP POINTER
LOKLUP: CALL FULL ;IS SCREEN FULL?
RET ;YES, RETURN NOW
CAIL J,DATLOC+DATSIZ-ENQSAF ;RAN OFF OF END?
JRST ENQOVF ;YES, GO SAY WE OVERFLOWED
MOVE T1,.ENQDF(J) ;GET FLAG WORD
CAMN T1,[-1] ;REACHED END?
JRST ENQQUE ;YES, GO DO QUEUES NOW
TXNN T1,EN%QCL ;IS THIS A LOCK BLOCK?
JRST ISQUE ;NO, IS A QUEUE BLOCK
AOS T1,LOKNUM ;COUNT ANOTHER LOCK BLOCK
CAIL T1,LCKMAX ;OVERFLOWED TABLE OF LOCKS?
JRST ENQOVF ;YES, SAY WE OVERFLOWED
HRLZM J,LOKTAB(T1) ;REMEMBER WHERE THE LOCK BLOCK IS
CALL DOCOLS ;DO ALL COLUMNS ABOUT THE LOCK
MOVE T1,.ENQDF(J) ;GET FLAGS AGAIN
ADDI J,.ENQDC ;MOVE TO LAST WORD OF BLOCK, MAYBE
TXNN T1,EN%QCT ;IS LAST WORD A USER CODE?
AOJA J,LOKLUP ;YES, MOVE TO NEXT BLOCK AND CONTINUE
HRLI J,(POINT 7,) ;NO, IS A STRING, SET UP
ILDB T1,J ;GET NEXT BYTE
JUMPN T1,.-1 ;KEEP GOING UNTIL FIND A NULL
MOVEI J,1(J) ;THEN MOVE TO NEXT WORD
JRST LOKLUP ;PROCEED WITH NEXT BLOCK (HOPEFULLY!)
ISQUE: MOVE T1,LOKNUM ;GET THE NUMBER OF THE LOCK
MOVEI T2,-1 ;GET A MASK TOO
TDNN T2,LOKTAB(T1) ;FIRST QUEUE BLOCK FOR THIS LOCK?
HRRM J,LOKTAB(T1) ;YES, REMEMBER WHERE IT IS
ADDI J,2 ;MOVE BEYOND THE BLOCK
JRST LOKLUP ;AND GO BACK TO LOOP
;NOW LOOP OVER THE QUEUE BLOCKS. TYPING DATA ON THEM. THE ADDRESSES
;OF THE FIRST QUEUE BLOCK FOR EACH LOCK WAS REMEMBERED IN THE FIRST
;PASS IN THE TABLE LOKTAB.
ENQOVF: STR$ [ASCIZ/ [Table overflow, further entries not reported]
/] ;SAY WE OVERFLOWED
ENQQUE: MOVEI T1,TP.EQQ ;TYPE OF DISPLAY IS THE ENQ QUEUES
CALL HDRSET ;SET UP TAB STOPS AND TITLE LINE
SETZM ENQNUM ;CLEAR COUNTER
SETOM LSTNUM ;CLEAR LAST NUMBER
ENQQLP: AOS T2,ENQNUM ;GET NEXT NUMBER TO LOOK FOR
CAMG T2,LOKNUM ;DONE WITH ALL LOCKS?
CALL FULL ;OR IS SCREEN FULL?
RET ;YES, RETURN
HRRZ J,LOKTAB(T2) ;GET FIRST QUEUE BLOCK FOR THIS LOCK IF ANY
JUMPE J,ENQQLP ;NONE, GO TO NEXT BLOCK
DMPQUE: MOVE T1,.ENQDF(J) ;GET FLAG WORD
CAIGE J,DATLOC+DATSIZ-ENQSAF ;OVERFLOWED?
TXNE T1,EN%QCL ;OR REACHED A LOCK BLOCK?
JRST ENQQLP ;YES, GO LOOK AT NEXT ONE
CALL DOCOLS ;SHOW DATA ON THIS QUEUE BLOCK
ADDI J,2 ;MOVE OUT OF BLOCK
JRST DMPQUE ;AND DO NEXT QUEUE BLOCK TOO
;FOLLOWING ARE THE ROUTINES FOR TYPING THE FIELDS OF THE LOCK BLOCKS
;AND OF THE QUEUE BLOCKS.
XXLLCK: MOVE T1,LOKNUM ;GET THE NUMBER OF THIS LOCK
JRST DECSP2 ;OUTPUT IT
XXLLVL: LDB T1,[POINT 9,.ENQDF(J),17] ;GET LEVEL NUMBER
JRST DECSP3 ;OUTPUT IT
XXLTYP: HRRZ T1,.ENQDF(J) ;GET THE TYPE OF THIS ENTRY
CAIN T1,-2 ;RANDOM ENQ PRIVILEGES NEEDED?
STR$ [ASCIZ/ENQ jobs/] ;YES, SAY THAT
CAIN T1,-3 ;WHEEL PRIVILEGES NEEDED?
STR$ [ASCIZ/WHEEL jobs/] ;YES, SAY THAT
CAIE T1,-2 ;ONE OF THE ABOVE?
CAIN T1,-3 ;WELL?
RET ;YES, DONE
CAIL T1,400000 ;A JOB NUMBER OR AN OFN
JRST XXLTYJ ;JOB
STR$ [ASCIZ/OFN /] ;TYPE SOME
JRST OCTOUT ;OUTPUT THE OFN
XXLTYJ: STR$ [ASCIZ/Job /] ;TYPE TEXT
SUBI T1,400000 ;REMOVE OFFSET
JRST DECOUT ;OUTPUT IT
XXLRES: MOVE T1,.ENQDR(J) ;GET RESOURCE WORD
TLZN T1,-1 ;IS THIS A GROUP?
JRST XXLREG ;YES
CALL DECOUT ;OUTPUT REMAINING RESOURCES
CHI$ "/" ;THEN A SLASH
HLRZ T1,.ENQDR(J) ;GET TOTAL RESOURCES IN POOL
JRST DECOUT ;OUTPUT IT AND RETURN
XXLREG: SKIPE .ENQDT(J) ;IS THE ONE LOCK FREE?
TDZA T1,T1 ;NO, GET ZERO
MOVEI T1,1 ;OTHERWISE ONE
CHI$ "0"(T1) ;SAY IF IT IS FREE OR NOT
CHI$ "/" ;THEN TYPE A SLASH
SKIPN T1,.ENQDR(J) ;GROUP NUMBER OF ZERO?
AOJA T1,DECOUT ;YES, OUTPUT AVAILABILITY OF 1
STR$ [ASCIZ/Group /] ;OTHERWISE SAY WHAT GROUP THIS IS
JRST DECOUT ;AND OUTPUT GROUP NUMBER
XXLTIM: SKIPN T4,.ENQDT(J) ;GET TIME STAMP IF ANY
STR$ [ASCIZ/ --/] ;NONE, SAY SO
JUMPE T4,CPOPJ ;RETURN IF NO DATE
SKIPGE T4 ;WAS TIME SET BACK THEN?
MOVE T4,BEGTIM ;NO, USE SYSTEM STARTUP TIME THEN
HRROI T1,TEMP ;POINT TO BUFFER
MOVE T2,T4 ;GET TIME
MOVX T3,OT%NDA ;DON'T OUTPUT THE DATE
ODTIM ;OUTPUT TO CORE
STR$ TEMP ;THEN GIVE TO DPY
MOVE T1,NTIME ;GET NOW'S TIME
SUB T1,T4 ;GET DIFFERENCE BETWEEN NOW AND THEN
HLRZ T1,T1 ;KEEP JUST DAYS OF DIFFERENCE
JUMPE T1,CPOPJ ;LESS THAN A DAY, NO OUTPUT
STR$ [ASCIZ/ -/] ;START OUTPUT
CALL DECOUT ;OUTPUT NUMBER OF DAYS
CHI$ "D" ;SAY IT IS DAYS
RET ;DONE
XXLCOD: MOVE T1,.ENQDC(J) ;GET CODE OR USER STRING
MOVE T2,.ENQDF(J) ;AND GET FLAGS
TXNN T2,EN%QCT ;IS THIS A TEXT STRING?
JRST XXLCOO ;NO, IS OCTAL NUMBER
MOVEI T1,.ENQDC(J) ;GET ADDRESS OF THE STRING
HRLI T1,(POINT 7,) ;MAKE BYTE POINTER TO IT
MOVE T2,[POINT 7,TEMP] ;POINT TO TEMP AREA TOO
MOVEI T3,TMPSIZ*5-1 ;GET A COUNT TOO
XXLCLP: ILDB T4,T1 ;GET NEXT CHAR
JUMPE T4,XXLCTP ;DONE WHEN GET A NULL
CAIL T4," " ;SEE IF A NORMAL CHAR
CAILE T4,176 ;WELL?
MOVEI T4,"?" ;NO, TURN TO SOMETHING VISIBLE
IDPB T4,T2 ;STORE THE CHAR
SOJG T3,XXLCLP ;LOOP UNLESS TOO MANY CHARS
SETZ T4, ;MAKE A NULL
XXLCTP: IDPB T4,T2 ;MAKE STRING ASCIZ
SPACE ;SPACE OVER FIRST
TXNE F,FR.MOR ;MORE OUTPUT COMING?
SETZM TEMP+3 ;YES, CUT OFF THE NAME
STR$ TEMP ;OUTPUT IT
RET ;DONE
XXLCOO: CHI$ "#" ;SAY THIS IS A NUMBER
TLZ T1,700000 ;CLEAR OUT THE 5B2
JRST OCTOUT ;GO OUTPUT IT
XXQLCK: MOVE T1,ENQNUM ;GET NUMBER OF LOCK THIS IS FOR
CAMN T1,LSTNUM ;SAME AS LAST TIME?
RET ;YES, RETURN
MOVEM T1,LSTNUM ;NO, SAVE NEW NUMBER
JRST DECSP2 ;OUTPUT IT
XXQJOB: HRRZ T1,.ENQDF(J) ;GET JOB NUMBER OF ORIGINATOR
JRST DECSP2 ;OUTPUT IT
XXQPRG: HRLZ T1,.ENQDF(J) ;GET JOB NUMBER
HRRI T1,.JOBPN ;AND INDEX
GETAB ;READ PROGRAM NAME
ERJMP CPOPJ ;FAILED
JRST SIXOUT ;OUTPUT IT
XXQREQ: HLRZ T1,.ENQDI(J) ;GET REQUEST DATA
MOVE T2,ENQNUM ;GET INDEX INTO LOKTAB
HLRZ T2,LOKTAB(T2) ;THEN ADDRESS OF LOCK BLOCK
MOVE T2,.ENQDR(T2) ;FINALLY GET RESOURCES WORD
TLNN T2,-1 ;GROUP NUMBER?
STR$ [ASCIZ/Group /] ;YES, SAY SO
JRST DECOUT ;OUTPUT GROUP OR REQUESTS WANTED
XXQID: HRRZ T1,.ENQDI(J) ;GET REQUEST ID
JRST OCTSP6 ;OUTPUT IT
XXQFLG: MOVE T1,.ENQDF(J) ;GET FLAGS
TXNE T1,EN%QCO ;DOES THIS GUY OWN THE LOCK?
STR$ [ASCIZ/Owner /] ;YES, SAY SO
TXNE T1,EN%QCB ;BLOCKED WAITING FOR EXCLUSIVE ACCESS?
STR$ [ASCIZ/Blocked/] ;YES, SAY SO
RET ;DONE
SUBTTL DISPLAY FOR TERMINAL INFORMATION
;THIS MODE OF OUTPUT TELLS THINGS ABOUT THE ACTIVE TERMINALS ON
;THE SYSTEM. THIS IS SET BY THE "TT" COMMAND.
DPYTTY: MOVEI T1,TP.TTY ;THIS IS TERMINAL DISPLAY
CALL HDRSET ;SO SET UP HEADERS FOR IT
TXO F,FR.EAT ;REMEMBER TO EAT AFTER HEADER IS TYPED
SETO J, ;INITIALIZE FOR LOOP
TTYLOP: ADDI J,1 ;MOVE TO NEXT TERMINAL
CAMG J,HGHTTY ;DID ALL TERMINALS?
CALL FULL ;OR IS SCREEN FULL?
RET ;YES, DONE
MOVE T1,['TTFLG1'] ;WANT THE STATUS WORD
CALL GETTT0 ;READ THE DATA
JRST TTYLOP ;TERMINAL NOT IN USE, GO LOOP
MOVEM T1,TTYSTS ;SAVE FOR LATER
CALL TTYACT ;SEE IF TERMINAL IS ACTIVE ENOUGH
JRST TTYLOP ;NO, DON'T SHOW IT
SETOM TTJBVL ;SAY WE NEED NEW JOB FROM TTY DATA
CALL DOCOLS ;TYPE DATA ABOUT THIS TERMINAL
JRST TTYLOP ;AND LOOP
;FOLLOWING ARE THE ROUTINES TO TYPE THINGS ABOUT EACH TERMINAL.
XXTNUM: MOVE T1,J ;GET TERMINAL NUMBER
JRST OCTSP3 ;OUTPUT AND RETURN
XXTTYP: MOVEI T1,.TTDES(J) ;GET DEVICE DESIGNATOR
GTTYP ;ASK MONITOR TO GET TERMINAL TYPE
ERJMP CPOPJ ;CAN'T GET IT, RETURN
MOVE T1,T2 ;MOVE TO RIGHT AC
MOVSI T2,-TTTNUM ;GET READY FOR SEARCH
HLRZ T3,TTTTAB(T2) ;GET NEXT POSSIBLE TERMINAL
CAME T1,T3 ;FOUND IT?
AOBJN T2,.-2 ;NO, KEEP SEARCHING
JUMPGE T2,OCTTEL ;CAN'T FIND IT, GIVE IN OCTAL
HRRZ T1,TTTTAB(T2) ;GET THE STRING ADDRESS
STR$ (T1) ;OUTPUT TYPE
RET ;DONE
DEFINE NT(CODE,TEXT),<
XWD CODE,[ASCIZ/TEXT/] ;;TERMINAL TYPES
>
TTTTAB: NT .TT33,<Model 33>
NT .TT35,<Model 35>
NT .TT37,<Model 37>
NT .TTEXE,Execuport
NT .TTDEF,Default
NT .TTIDL,Ideal
NT .TTV05,VT05
NT .TTV50,VT50
NT .TTL30,LA30
NT .TTG40,GT40
NT .TTL36,LA36
NT .TTV52,VT52
NT .TT100,VT100
NT .TTL38,LA38
NT .TT120,LA120
TTTNUM==.-TTTTAB ;NUMBER OF TERMINALS IN TABLE
XXTINC: SKIPA T1,['TTICT '] ;GET WORD
XXTOUC: MOVE T1,['TTOCT '] ;OR GET OTHER WORD
SKIPL TTYSTS ;FAIL IF THIS IS A SHORT BLOCK
CALL GETTT0 ;NORMAL BLOCK, READ WORD
RET ;CAN'T GET IT
JRST DECSP3 ;OUTPUT IT
XXTSPD: MOVEI T1,.TTDES(J) ;GET TERMINAL DESIGNATOR
MOVEI T2,.MORSP ;FUNCTION TO READ LINE SPEEDS
MTOPR ;READ IT
ERJMP CPOPJ ;FAILED
SKIPGE T4,T3 ;SAVE SPEED AND SEE IF UNKNOWN
JRST NOSPED ;ISN'T VALID
HLRZ T1,T4 ;GET INPUT SPEED
CALL DECSP5 ;OUTPUT IT
HRRZ T1,T4 ;GET OUTPUT SPEED
JRST DECSP6 ;OUTPUT IT AND RETURN
NOSPED: STR$ [ASCIZ/ -- --/] ;SAY SPEED IS IRREVELANT
RET ;DONE
XXTJOB: CALL TTYJOB ;GET JOB DATA FOR THIS TERMINAL
RET ;FAILED
HLRZ T1,T1 ;KEEP ONLY THE JOB NUMBER
CAIN T1,-1 ;NOT ASSIGNED?
JRST TTYNTA ;YES, GO SAY THAT
CAIE T1,-2 ;BECOMING ASSIGNED?
JRST DECSP2 ;NO, TELL JOB NUMBER
STR$ [ASCIZ/Ass/] ;SAY BECOMING ASSIGNED
RET ;DONE
TTYNTA: STR$ [ASCIZ/--/] ;SAY UNASSIGNED
RET ;DONE
XXTLNK: MOVE T1,['TTLINK'] ;GET WORD
CALL GETTT0 ;READ THE DATA
RET ;FAILED
TELLNK: MOVEM T2,TEMP ;SAVE AWAY THE LINK DATA
MOVE T4,[POINT 9,TEMP] ;GET BYTE POINTER
TXZ F,FR.TMP ;INITIALIZE FLAG
LNKLOP: TXNN T4,77B5 ;DID ALL FOUR BYTES?
RET ;YES, DONE
ILDB T1,T4 ;GET NEXT BYTE
CAIN T1,777 ;REAL TERMINAL LINKED HERE?
JRST LNKLOP ;NO, TRY NEXT BYTE
TXOE F,FR.TMP ;ANY PREVIOUS OUTPUT?
SPACE ;YES, SPACE OVER
CALL OCTSP3 ;OUTPUT THE TERMINAL NUMBER
JRST LNKLOP ;LOOP
XXTUSR: CALL TTYJOB ;FIND THE JOB INFO FOR THIS TERMINAL
RET ;CAN'T GET IT
HLRZ T1,T1 ;KEEP ONLY THE JOB NUMBER
CAIGE T1,-2 ;IS TERMINAL ASSIGNED TO A JOB?
JRST JOBUSR ;YES, GO SAY WHO IT IS
STR$ [ASCIZ/None/] ;NO, SAY NOBODY IS THERE
RET ;DONE
TT%SAL==1B0 ;SEND-ALL BEING DONE
TT%SHT==1B1 ;THIS IS A SHORT BLOCK
TT%MES==1B2 ;THIS IS A SYSTEM MESSAGE BLOCK
TT%OTP==1B3 ;OUTPUT ON ROUTE
TT%SFG==1B5 ;CONTROL-S WAS TYPED
TT%PRM==1B8 ;DON'T DEALLOCATE BLOCK
TT%FEM==1B0 ;LINE IS REMOTE
TT%CON==1B3 ;CARRIER IS ON
TT%AUT==1B7 ;LINE IS AUTO-SPEED
XXTFLG: MOVE T1,TTYSTS ;GET THE STATUS WORD
TXNE T1,TT%PRM ;IS THIS A PERMANENT BLOCK?
STR$ [ASCIZ/Prm /] ;YES, SAY SO
TXNE T1,TT%SHT ;IS THIS A SHORT BLOCK?
STR$ [ASCIZ/Sht /] ;YES, SAY SO
TXNE T1,TT%MES ;IS THIS A SYSTEM MESSAGE BLOCK?
STR$ [ASCIZ/Msg /] ;YES, SAY SO
TXNE T1,TT%SAL ;SEND-ALL BEING DONE?
STR$ [ASCIZ/Sndal /] ;YES, SAY SO
TXNE T1,TT%SFG ;CONTROL-S TYPED?
STR$ [ASCIZ/Pag /] ;YES, SAY SO
TXNE T1,TT%OTP ;OUTPUT ON ROUTE?
STR$ [ASCIZ/Out /] ;YES, SAY SO
CALL TTYJOB ;GET JOB DATA FOR THIS TTY
MOVEI T1,-1 ;FAILED, DEFAULT IT
ANDI T1,-1 ;KEEP ONLY THE FORK NUMBER
CAIE T1,-1 ;ANY FORK IN INPUT WAIT?
STR$ [ASCIZ/In /] ;YES, SAY SO
MOVEI T1,.RDTTS ;GET FUNCTION
MOVE T2,J ;AND TERMINAL NUMBER
MONRD% ;GET THE TTSTAT WORD
ERJMP CPOPJ ;FAILED
JUMPL T1,CPOPJ ;ALSO FAILED
TXNE T2,TT%FEM ;IS THIS A REMOTE LINE?
STR$ [ASCIZ/Rmt /] ;YES, SAY SO
TXNE T2,TT%CON ;IS CARRIER ON?
STR$ [ASCIZ/Car /] ;YES, SAY SO
TXNE T2,TT%AUT ;IS LINE AUTO-BAUD?
STR$ [ASCIZ/Auto /] ;YES, SAY SO
CAMN J,CTYNUM ;IS THIS THE CTY?
STR$ [ASCIZ/Cty /] ;YES, SAY SO
CAMLE J,CTYNUM ;IS THIS A PTY?
STR$ [ASCIZ/Pty /] ;YES, SAY SO
RET ;DONE
SUBTTL SUBROUTINE TO CHECK FOR AN ACTIVE TERMINAL
;CALLED FOR EACH TERMINAL TO SEE IF THAT TERMINAL IS ACTIVE. TERMINAL
;NUMBER IS SPECIFIED IN AC J. SKIP RETURN IF TERMINAL SHOULD BE SHOWN
;BECAUSE OF SOMETHING INTERESTING. ACTIVE TERMINALS STAY THAT WAY FOR
;ABOUT A MINUTE BEFORE THEY WILL DISAPPEAR FROM THE DISPLAY.
TTYACT: CAILE J,MAXTTY ;SEE IF NUMBER LARGER THAN OUR TABLE
RETSKP ;YES, ACT LIKE ACTIVE THEN
MOVE T1,TTYSTS ;GET THE STATUS
TXNE T1,TT%SHT+TT%MES+TT%OTP ;ANYTHING HAPPENING?
JRST NEWACT ;YES, NOW ACTIVE
MOVE T1,['TTOCT '] ;GET READY
CALL GETTT0 ;READ NUMBER OF OUTPUT CHARS
SETZ T1, ;FAILED, ASSUME NONE
JUMPN T1,NEWACT ;IF ANY, IS ACTIVE
MOVE T1,['TTICT '] ;GET READY
CALL GETTT0 ;READ NUMBER IF INPUT CHARACTERS
SETZ T1, ;FAILED
JUMPN T1,NEWACT ;IF ANY THERE, IT'S ACTIVE
SKIPE T1,ACTTAB(J) ;SEE IF TERMINAL HAS BEEN ACTIVE
CAMGE T1,NTIME ;AND SEE IF RECENT ENOUGH TO WANT IT
TXNN F,FR.TAC ;OR SEE IF WANT ALL TERMINALS ANYWAY
RETSKP ;YES, SHOW IT
RET ;NO, FORGET IT
NEWACT: MOVX T1,<<ACTTIM,,0>/^D<60*24>> ;GET TIME INTERVAL
ADD T1,NTIME ;ADD CURRENT TIME
MOVEM T1,ACTTAB(J) ;REMEMBER WHEN WILL NO LONGER BE ACTIVE
RETSKP ;GOOD RETURN
SUBTTL SUBROUTINES USED FOR TERMINAL DISPLAY
;CALLED TO USE THE MONRD% JSYS TO RETURN A WORD FROM THE TTACTL BLOCK
;OF A TERMINAL. CALL WITH SIXBIT NAME IN T1, AND OFFSET FROM THAT NAME
;IN T2, AND TERMINAL NUMBER IN AC J. SKIP RETURN WITH DATA IN T1 IF
;SUCCESSFUL. CALL AT GETTT0 IF OFFSET IS ZERO.
GETTT0: SETZ T2, ;MAKE OFFSET ZERO
GETTTY: MOVE T3,T2 ;MOVE OFFSET TO RIGHT AC
MOVE T2,T1 ;MOVE SYMBOL TO RIGHT AC
MOVEI T1,.RDTTY ;SET UP FUNCTION CODE
MOVE T4,J ;GET TERMINAL NUMBER
JRST DOMONR ;GO DO THE JSYS
;SUBROUTINE TO READ THE GETAB ENTRY WHICH CONVERTS TERMINAL NUMBER TO
;JOB NUMBER. TO SAVE TIME, LOCATION TTJBVL IS NONNEGATIVE IF WE ALREADY
;HAVE COLLECTED THE INFORMATION. SKIP RETURN IF SUCCESSFUL WITH WORD
;IN T1. TERMINAL NUMBER GIVEN IN AC J.
TTYJOB: SKIPL T1,TTJBVL ;GET DATA IF ALREADY KNOWN
RETSKP ;YES, GOOD RETURN
MOVSI T1,(J) ;SET UP INDEX
IORI T1,.TTYJO ;AND TABLE NUMBER
GETAB ;READ THE WORDD
ERJMP CPOPJ ;FAILED
MOVEM T1,TTJBVL ;REMEMBER FOR NEXT TIME
RETSKP ;GOOD RETURN
SUBTTL ROUTINE TO GIVE MONITOR STATISTICS
;THIS MODE OF OUTPUT IS USED TO OUTPUT MONITOR DATA, ON THE SYSTEM
;PERFORMANCE AS A WHOLE. THIS MODE IS SET BY THE "M" COMMAND.
DPYMON: SETOM HDRTYP ;NO HEADERS ARE VALID ANYMORE
TAB$ ;SET UP DEFAULT TABS
SETZB T2,T3 ;INITIALIZE FOR LOOP
VERLOP: MOVSI T1,(T3) ;GET READY
IORI T1,.SYSVE ;TO READ MONITOR VERSION
GETAB ;READ A WORD OF IT
JRST VERDON ;IF FAILED, ALL DONE
JUMPE T1,VERDON ;PROCEED IF DONE
STR$ T1 ;OUTPUT PART OF NAME
AOJA T3,VERLOP ;LOOP OVER ALL PARTS
VERDON: CRLF ;TYPE A CRLF
HRROI T1,TEMP ;POINT TO TEMPORY AREA
SETO T2, ;WANT CURRENT TIME
MOVX T3,OT%DAY+OT%FDY+OT%FMN+OT%4YR+OT%DAM+OT%SPA+OT%SCL+OT%TMZ
ODTIM ;STORE TIME WITH TIME ZONE
STR$ TEMP ;THEN OUTPUT IT
STR$ [ASCIZ/ Uptime: /] ;TYPE MORE
TIME ;READ TIME
IDIVI T1,^D1000 ;TURN MILLISECONDS TO SECONDS
CALL TIMOUT ;OUTPUT IT
CRLF ;THEN A CRLF
CALL SETEAT ;SET UP HOW MANY LINES TO BE EATEN
CALL DOSTAT ;GO TYPE OUT THE STATUS INFORMATION
CALL DOCLAS ;TYPE OUT CLASS INFORMATION
CALL DOLOAD ;TYPE OUT THE LOAD AVERAGES
PJRST DOACT ;FINISH WITH ACTIVE JOB INFO
SUBTTL ROUTINE TO TYPE OUT "WATCH" INTO
;THE FOLLOWING CODE TYPES OUT MONITOR STATISTICS IN A MANNER SIMILAR
;TO WHAT WATCH TYPES. THE COLUMNS ARE ARRANGED FOUR TO A LINE.
DOSTAT: CALL RDSTAT ;GO READ NEW VALUES
TAB$ [$TABS<14,29,41,51,62,63,64,65,66,67>] ;SET UP NICE TAB STOPS
STR$ [ASCIZ/
Statistics for an interval of /] ;TYPE SOME HEADER
MOVE T1,STADIF ;GET INTERVAL
IDIVI T1,^D100 ;CONVERT TO TENTHS OF A SECOND
CAIL T2,^D50 ;SHOULD WE ROUND UP?
ADDI T1,1 ;YES
MOVEI T4,DECOUT ;SET UP ROUTINE TO CALL
CALL FIXOUT ;OUTPUT AS FIXED POINT NUMBER
STR$ [ASCIZ/ seconds:
/] ;FINISH HEADER
MOVSI J,-STATNM ;GET NUMBER OF ENTRIES TO TYPE
STATLP: TRNE J,3 ;TIME FOR A TAB?
TAB ;YES, TYPE ONE
TRNN J,3 ;TIME FOR A CRLF INSTEAD?
CRLF ;YES, GIVE ONE
HRRZ T1,STATTB(J) ;GET THE NAME OF THE ENTRY
STR$ (T1) ;OUTPUT IT
STR$ [ASCIZ/: /] ;FOLLOW WITH COLON AND SPACE
CALL @STATCD(J) ;GO TYPE OUT THE VALUE
AOBJN J,STATLP ;LOOP OVER ALL ENTRIES
CRLF ;END WITH A CRLF
STATCP: MOVE T1,[NEWSTA,,OLDSTA] ;GET READY
BLT T1,OLDTIM ;COPY NEW STATISTICS AS OLD ONES
RET ;ALL DONE
;FOLLOWING ARE THE ROUTINES CALLED TO OUTPUT THE VARIOUS VALUES.
;THE DATA FOR EACH ROUTINE IS IN THE TABLES NEWSTA AND OLDSTA.
;ROUTINE TO OUTPUT THE DIFFERENCE BETWEEN NEW AND OLD VALUES, AND
;ALSO TYPE THE TOTAL VALUE:
DODIF: MOVE T1,NEWSTA(J) ;GET NEW VALUE
SUB T1,OLDSTA(J) ;SUBTRACT OLD VALUE
CALL DECOUT ;OUTPUT IT
TAB ;TAB OVER
;THEN OUTPUT TOTAL VALUE
;ROUTINE TO OUTPUT THE NEW VALUE ITSELF:
DONUM: MOVE T1,NEWSTA(J) ;GET THE NEW VALUE
PJRST DECOUT ;OUTPUT IT AND RETURN
;ROUTINE TO COMPUTE AN AVERAGE OVER THE TIME INTERVAL:
DOAVG: MOVE T1,NEWSTA(J) ;GET THE NEW TIME
SUB T1,OLDSTA(J) ;SUBTRACT THE OLD TIME
IMULI T1,^D10 ;SINCE HAVE ONE PLACE AFTER DECIMAL POINT
MOVEI T4,DECSP3 ;GET READY
JRST DOPCT1 ;JOIN OTHER CODE
;ROUTINE TO OUTPUT THE PERCENTAGE OF TIME TAKEN IN THE LAST INTERVAL:
DOPCT: MOVE T1,NEWSTA(J) ;GET THE NEW TIME
SUB T1,OLDSTA(J) ;SUBTRACT THE OLD TIME
IMULI T1,^D1000 ;GET READY TO GET TENTHS OF PERCENT
MOVEI T4,DECSP2 ;GET READY
DOPCT1: IDIV T1,STADIF ;DIVIDE BY TIME INTERVAL
LSH T2,1 ;DOUBLE REMAINDER
CAML T2,STADIF ;SHOULD WE ROUND UP?
ADDI T1,1 ;YES, DO IT
PJRST FIXOUT ;OUTPUT AS FIXED POINT NUMBER
SUBTTL ROUTINE TO COLLECT DATA FOR WATCH TYPE OUTPUT
;CALLED TO FILL IN THE TABLE NEWSTA WITH THE RESULTS OF GETABS ON
;THE ENTRIES GIVEN IN THE STATTB TABLE. LATER ON THE DATA IS OUTPUT
;TO THE USER.
RDSTAT: TIME ;READ TIME SINCE SYSTEM STARTED
MOVEM T1,NEWTIM ;SAVE IT
SUB T1,OLDTIM ;GET DIFFERENCE FROM OLD TIME
MOVEM T1,STADIF ;SAVE IT
MOVSI J,-STATNM ;GET READY FOR A LOOP
RDSTAL: MOVE T1,STATTB(J) ;GET THE TABLE INDEX
HRRI T1,.SYSTA ;AND THE TABLE NUMBER
GETAB ;READ THE INFORMATION
SETZ T1, ;FAILED, MAKE IT ZERO
MOVEM T1,NEWSTA(J) ;SAVE THE VALUE
AOBJN J,RDSTAL ;LOOP OVER ALL ENTRIES
RET ;DONE
SUBTTL SUBROUTINE TO OUTPUT LOAD AVERAGES
;THIS IS CALLED TO TYPE THE LOAD AVERAGES OUT. THE LOAD AVERAGES
;KEPT AS FLOATING POINT NUMBERS.
DOLOAD: STR$ [ASCIZ/
Load averages:/] ;START OUT TYPEOUT
MOVSI T1,14 ;GET INDEX OF 1 MINUTE AVERAGE
CALL LOADTP ;TYPE IT OUT
MOVSI T1,15 ;GET INDEX OF 5 MINUTE AVERAGE
CALL LOADTP ;TYPE IT OUT
MOVSI T1,16 ;GET INDEX OF 15 MINUTE AVERAGE
CALL LOADTP ;TYPE IT
JRST DOCRLF ;FINISH WITH A CRLF
LOADTP: HRRI T1,.SYSTA ;DATA IS IN THE SYSTAT TABLE
GETAB ;READ IT
SETZ T1, ;FAILED, MAKE ZERO
MOVE T2,T1 ;PUT INTO RIGHT AC
HRROI T1,TEMP ;POINT TO STORAGE AREA
MOVX T3,1B1!1B4!1B6!37B17!4B23!2B29 ;GET BITS
FLOUT ;OUTPUT THE NUMBER
JFCL ;SHOULD NOT FAIL
STR$ TEMP ;NOW OUTPUT THE NUMBER
RET ;DONE
SUBTTL SUBROUTINE TO OUTPUT NUMBER OF JOBS ON SYSTEM
;CALLED TO OUTPUT THE NUMBER OF JOBS ON THE SYSTEM, AND HOW MANY OF
;THEM ARE ACTIVE. (THEIR IDLE TIME IS 1 MINUTE OR LESS).
DOACT: STR$ [ASCIZ/Jobs: /] ;TYPE SOME
SETZB T1,T4 ;CLEAR COUNTERS
MOVE J,HGHJOB ;GET HIGHEST JOB
DOACTL: SKIPN CURRUN(J) ;DOES THIS JOB HAVE RUNTIME?
JRST DOACTN ;NO, LOOK AT NEXT ONE
ADDI T1,1 ;YES, COUNT IT
SKIPN IDLE(J) ;IS THE JOB ACTIVE?
ADDI T4,1 ;YES, COUNT IT
DOACTN: SOJGE J,DOACTL ;LOOP OVER ALL JOBS
CALL DECOUT ;OUTPUT TOTAL NUMBER
CHI$ "/" ;THEN A SLASH
MOVE T1,HGHJOB ;GET HIGHEST JOB NUMBER
ADDI T1,1 ;ADD SINCE WE COUNT JOB 0
CALL DECOUT ;OUTPUT TOTAL JOBS POSSIBLE
STR$ [ASCIZ/ Active: /] ;GET READY
MOVE T1,T4 ;GET NUMBER OF ACTIVE JOBS
CALL DECOUT ;OUTPUT THEM
JRST DOCRLF ;END IN CRLF
SUBTTL SUBROUTINE TO TYPE OUT SCHEDULAR CLASSES
;CALLED AS PART OF THE MONITOR STATISTICS, TO OUTPUT THE SCHEDULER CLASSES
;CURRENTLY IN USE. USES THE SKED% JSYS TO COLLECT THE DATA.
DOCLAS: MOVEI T1,.SKRBC ;FUNCTION TO READ BIAS KNOB
MOVEI T2,T3 ;ADDRESS OF BLOCK
MOVEI T3,2 ;TWO ARGUMENTS
SKED% ;READ THE KNOB
ERJMP CPOPJ ;FAILED, ASSUME NO JSYS EXISTS
MOVE T1,T4 ;GET VALUE OF KNOB
STR$ [ASCIZ/
Bias knob: /] ;START OUTPUT
CALL DECOUT ;OUTPUT THE VALUE
MOVEI T1,.SKRCV ;FUNCTION
MOVEI T2,T3 ;LOCATION FOR BLOCK
MOVEI T3,2 ;TWO ARGUMENTS AGAIN
SKED% ;READ THE CLASS PARAMETERS
ERJMP DOCRLF ;FAILED
STR$ [ASCIZ/ Class scheduler is /] ;TYPE SOME
TXNE T4,SK%STP ;IS IT ON?
STR$ [ASCIZ/off/] ;NO, SAY SO
TXNN T4,SK%STP ;WELL?
STR$ [ASCIZ/on/] ;YES
CRLF ;THEN A CRLF
CALL GETCLS ;READ CLASSES FOR ALL JOBS
TAB$ [$TABS<6,12,18,25,32,40>] ;SET NEW TAB STOPS
TXZ F,FR.HDR ;CLEAR HEADER FLAG
SETO J, ;INITIALIZE CLASS FOR LOOP
CLSLOP: MOVEI T1,.SA15L+1 ;NUMBER OF ARGUMENTS
AOS T2,J ;GET NEXT CLASS
DMOVEM T1,KBLK ;STORE AWAY
MOVEI T1,.SKRCS ;FUNCTION CODE
MOVEI T2,KBLK ;ADDRESS OF ARGUMENT BLOCK
SKED% ;READ THE INFORMATION
ERJMP CPOPJ ;FAILED, RETURN
SKIPN KBLK+.SASHR ;ANY SHARE?
SKIPE KBLK+.SAUSE ;OR UTILIZATION?
JRST SHWCLS ;YES, THEN SHOW THIS CLASS
CAIG J,MAXCLS ;GREATER THAN OUR HIGHEST CLASS?
SKIPN CLSNUM(J) ;OR NO JOBS IN THE CLASS?
JRST CLSLOP ;YES, DON'T SHOW IT
SHWCLS: TXON F,FR.HDR ;ALREADY OUTPUT THE HEADER?
STR$ [ASCIZ/Class Share Use 1-Load 5-Load 15-Load Jobs in class
/] ;NO, THEN OUTPUT IT
MOVE T1,J ;GET CLASS
CALL DECSP3 ;OUTPUT IT
TAB ;THEN TAB OVER
MOVE T1,KBLK+.SASHR ;GET THE SHARE
CALL FLTOUT ;OUTPUT A FLOATING POINT NUMBER
TAB ;THEN TAB AGAIN
MOVE T1,KBLK+.SAUSE ;GET THE UTILIZATION
CALL FLTOUT ;OUTPUT IT AS FLOATING POINT TOO
TAB ;THEN TAB AGAIN
MOVE T1,KBLK+.SA1ML ;GET ONE MINUTE LOAD AVERAGE
CALL FLTOUT ;OUTPUT IT
TAB ;THEN TAB
MOVE T1,KBLK+.SA5ML ;GET FIVE MINUTE LOAD AVERAGE
CALL FLTOUT ;OUTPUT IT
TAB ;THEN TAB
MOVE T1,KBLK+.SA15L ;GET FIFTEEN MINUTE LOAD AVERAGE
CALL FLTOUT ;OUTPUT IT
TAB ;ANOTHER TAB
CALL TYPCLS ;AND LIST ALL JOBS IN THAT CLASS
CRLF ;THEN DO A CRLF
JRST CLSLOP ;LOOP
SUBTTL SUBROUTINES TO COLLECT AND LIST JOBS IN A CLASS
;HERE TO CREATE A TABLE OF CLASSES FOR ALL THE JOBS. USED LATER
;TO LIST THOSE JOBS IN EACH SCHEDULER CLASS.
GETCLS: MOVE T1,[CLSTAB,,CLSTAB+1] ;GET READY
SETOM CLSTAB ;TO CLEAR INFO IN TABLE
BLT T1,CLSTAB+MAXJOB-1 ;DO IT
MOVE T1,[CLSNUM,,CLSNUM+1] ;GET READY
SETZM CLSNUM ;CLEAR NUMBER OF JOBS IN CLASSES
BLT T1,CLSNUM+MAXCLS ;DO IT
SETO J, ;GET READY FOR LOOP
GETCLL: ADDI J,1 ;MOVE TO NEXT JOB
CAMLE J,HGHJOB ;DID THEM ALL?
RET ;YES, RETURN
MOVEM J,KBLK+.SAJOB ;SET IN ARGUMENT BLOCK
MOVEI T1,3 ;GET NUMBER OF WORDS
MOVEM T1,KBLK ;PUT IN ARGUMENT BLOCK TOO
MOVEI T1,.SKRJP ;GET FUNCTION CODE
MOVEI T2,KBLK ;POINT TO FUNCTION BLOCK
SKED% ;READ THE INFO
ERJMP GETCLL ;FAILED, DO NEXT JOB
MOVE T1,KBLK+.SAJCL ;GET THE SCHEDULER CLASS
MOVEM T1,CLSTAB(J) ;REMEMBER FOR LATER
SKIPL T1 ;SEE IF IN RANGE OF OUR TABLE
CAILE T1,MAXCLS ;WELL?
JRST GETCLL ;NO, IGNORE INCREMENTING COUNT
AOS CLSNUM(T1) ;YES, INCREMENT COUNT
JRST GETCLL ;LOOP
;HERE TO TYPE ALL OF THE JOBS WHICH BELONG TO A PARTICULAR SCHEDULER
;CLASS. THE DATA HAD PREVIOUSLY BEEN COLLECTED BY THE GETCLS ROUTINE.
;SCHEDULER CLASS TO BE LISTED IN IN AC J.
TYPCLS: SKIPN CLSNUM(J) ;ANY JOBS IN THIS CLASS?
STR$ [ASCIZ/None/] ;NO, SAY SO
SKIPN CLSNUM(J) ;WELL?
RET ;NO, SO QUIT NOW
SETOB T4,TEMP ;GET READY FOR THE LOOP
TYPCLL: AOS T4 ;ADVANCE TO NEXT JOB
CAMG T4,HGHJOB ;DONE WITH ALL JOBS?
CAME J,CLSTAB(T4) ;OR DONE WITH A RANGE?
JRST TYPCLR ;YES, GO TYPE IT
SKIPGE TEMP ;SEE IF HAVE TO INITIALIZE THE RANGE
MOVEM T4,TEMP ;YES, SAVE JOB NUMBER
JRST TYPCLL ;GO BACK TO THE LOOP
TYPCLR: SKIPGE TEMP ;HAVE A RANGE TO TYPE?
JRST TYPCLE ;NO, GO SEE IF DONE
CALL LEFT ;GET AMOUNT OF SPACE LEFT ON LINE
CAIGE T1,^D6 ;ENOUGH FOR ANOTHER RANGE?
STR$ [BYTE(7)12,11,11,11,11,11,11] ;NO, MOVE TO NEXT LINE
MOVE T1,TEMP ;GET FIRST JOB NUMBER
CALL DECOUT ;OUTPUT IT
MOVEI T1,-1(T4) ;GET LAST JOB OF RANGE
CAME T1,TEMP ;SAME AS FIRST JOB?
CHI$ "-" ;NO, SEPARATE WITH DASH
CAME T1,TEMP ;WELL?
CALL DECOUT ;NO, TYPE LAST JOB OF RANGE
SPACE ;THEN TYPE A SPACE
SETOM TEMP ;REINITIALIZE FIRST JOB OF RANGE
TYPCLE: CAMGE T4,HGHJOB ;LOOKED AT ALL JOBS?
JRST TYPCLL ;NO, TRY NEXT ONE
RET ;YES, DONE
SUBTTL DISPLAY TO SHOW STATUS OF SYSTEM RESOURCES
;THIS DISPLAY SHOWS THE AMOUNT OF RESOURCES USED, SUCH AS SPT SLOTS,
;FREE CORE, SWAPPING SPACE, ETC. A BAR GRAPH IS SHOWN AS PART OF THE
;DISPLAY TO MAKE THESE NUMBERS OBVIOUS.
DPYRES: TAB$ [$TABS <0,16,27>] ;SET NICE TAB STOPS
SETOM HDRTYP ;NO SPECIAL HEADERS FOR THIS DISPLAY
TXNN F,FR.CMP ;SKIP HEADER IF COMPRESSING
STR$ [ASCIZ"Resource Used/Total Percentage used
"]
SETZM RESDAT ;INITIALIZE TOTAL IN CASE FAIL TOTALLY
SETO J, ;GET READY FOR LOOP
RESLOP: MOVEI T1,.RDRES ;GET FUNCTION CODE
TLNN J,-1 ;NOT A RESIDENT SUBFIELD?
CAML J,RESQTL ;OR NO MORE SUBFIELDS?
IORI J,-1 ;YES, SET TO DO NEXT FIELD
AOS T2,J ;ADVANCE TO NEXT ENTRY
MONRD% ;READ THE DATA
ERJMP RESDON ;FAILED
JUMPL T1,RESDON ;ALSO
CALL RESTYP ;TYPE DATA ON THIS POOL
JRST RESLOP ;LOOP
RESDON: STR$ [ASCIZ/ 0% 20% 40% 60% 80% 100%
/] ;TYPE OUT PERCENTAGE LINE
RET ;RETURN
;HERE TO TYPE A LINE ABOUT EACH FREE POOL:
RESTYP: HLRZ T4,J ;GET TYPE OF FIELD THIS IS
TRNE J,-1 ;ACTUALLY A SUBFIELD OF RESIDENT SPACE?
MOVEI T4,RESPOL-RESFLD-1(J) ;YES, FIX UP TO POINT TO OTHER TABLE
STR$ @RESFLD(T4) ;OUTPUT PROPER TEXT
TAB ;THEN TAB
MOVE T1,T2 ;COPY TOTAL
SKIPGE RESFLD(T4) ;WANTS THE VALUE ITSELF?
SKIPA T1,T3 ;YES, GET IT
SUB T1,T3 ;NO, THEN GET DIFFERENCE
DMOVEM T1,TEMP ;SAVE VALUES
CALL DECSP4 ;OUTPUT CURRENT VALUE
SPACE ;THEN SPACE ONE
MOVE T1,TEMP+1 ;GET ORIGINAL VALUE
CALL DECOUT ;OUTPUT IT TOO
TAB ;TAB OVER MORE
DMOVE T1,TEMP ;GET BACK VALUES
CALL DOHIST ;OUTPUT HISTOGRAM
JRST DOCRLF ;END IN A CRLF
;EACH INDIVIDUAL RESOURCE:
RESFLD: EXP [ASCIZ/Res free core/] ;(0) TOTAL FREE RESIDENT BLOCKS
EXP [ASCIZ/Swap free core/] ;(1) SWAPPABLE STORAGE
EXP [ASCIZ/ ENQ blocks/] ;(2) ENQ USAGE
EXP 1B0+[ASCIZ/ DECnet core/] ;(3) SWAPPABLE NETWORK
EXP 1B0+[ASCIZ/Open files/] ;(4) NUMBER OF OFNS
EXP 1B0+[ASCIZ/SPT slots/] ;(5) SPT SLOTS
EXP [ASCIZ/Swapping pages/] ;(6) PAGES OF SWAPPING
EXP [ASCIZ/User core/] ;(7) PAGES OF USER CORE USED
EXP 1B0+[ASCIZ/Forks/] ;(10) NUMBER OF FORKS USED
MAXRES==.-RESFLD-1 ;HIGHEST RESOURCE
;SUBFIELDS OF THE RESIDENT STORAGE FIELD:
RESPOL: EXP [ASCIZ/ General pool/] ;(1) GENERAL
EXP [ASCIZ/ Terminals/] ;(2) TERMINAL DATA
EXP [ASCIZ/ DECnet core/] ;(3) NETWORK
EXP [ASCIZ/ Timer blocks/] ;(4) TIMER BLOCKS
MAXPOL==.-RESPOL ;HIGHEST KNOWN TYPE
SUBTTL SUBROUTINE TO TYPE OUT HISTOGRAM DATA
;CALLED WITH A FRACTION GIVEN BY THE NUMBERS IN ACS T1 AND T2, TO
;OUTPUT A BAR GRAPH WHICH GIVES THE PERCENTAGE OF THE FRACTION.
;ILLEGAL VALUES ARE TAMED BEFORE TRYING TO USE THEM. THE PATTERN
;IS SEVERAL PERCENTAGE POINTS TO A COLUMN.
DOHIST: SKIPL T3,T1 ;MOVE AND CHECK SIGN OF NUMBER
SKIPG T2 ;AND OF DENOMINATOR
SETZB T2,T3 ;BAD, CLEAR THEM
CAMLE T3,T2 ;SEE IF HAVE AN IMPROPER FRACTION
MOVE T3,T2 ;YES, REDUCE TO UNITY
MULI T3,^D100 ;TURN INTO A PERCENTAGE
DIV T3,T2 ;FROM THE FRACTION
IDIVI T3,PERCOL ;CONVERT PERCENTAGE
IMULI T3,PERCOL ;TO A MULTIPLE OF THE COMPRESSION
SETZ T1, ;START WITH ZERO
STARLP: ADDI T1,PERCOL ;ADVANCE TO NEXT PERCENTAGE
CHI$ "*" ;TYPE A STAR
CAMG T1,T3 ;DONE?
JRST STARLP ;NO
HSTLOP: ADDI T3,PERCOL ;INCREMENT TO NEXT NUMBER
CAILE T3,^D100 ;REACHED THE END?
RET ;YES, DONE
MOVE T1,T3 ;COPY NUMBER
IDIVI T1,^D10 ;SEE IF AT A MULTIPLE OF 10
SKIPN T2 ;AT A MULTIPLE?
CHI$ "!" ;YES, THEN TYPE MARKER
SKIPE T2 ;WELL?
SPACE ;NO, JUST SPACE OVER
JRST HSTLOP ;LOOP
SUBTTL DISPLAY WHICH SHOWS BUSY DEVICES
;THIS DISPLAY SHOWS WHO OWNS THE DEVICES ON THE SYSTEM. ALL
;DEVICES WHICH ARE NOT DISKS AND CONTROLLING TERMINALS ARE DISPLAYED.
DPYDEV: MOVEI T1,TP.DEV ;THIS IS THE DEVICE DISPLAY
CALL HDRSET ;SO SET UP HEADERS FOR IT
TXO F,FR.EAT ;REMEMBER TO EAT LINES LATER
SETO J, ;SET UP FOR LOOP
DEVLOP: ADDI J,1 ;MOVE TO NEXT INDEX
MOVSI T1,(J) ;SET UP INDEX
IORI T1,.DEVUN ;TABLE OF OWNERS AND UNITS
GETAB ;READ IT
ERJMP CPOPJ ;FAILED, ALL DONE
HLRZ T2,T1 ;GET JOB NUMBER
CAIE T2,-1 ;NOT ASSIGNED TO ANY JOB?
CAIN T2,-2 ;OR ASSIGNED TO RESOURCE ALLOCATOR?
JRST DEVLOP ;YES, TRY NEXT ONE
MOVEM T1,DEVUNT ;SAVE WORD FOR LATER
MOVSI T1,(J) ;SET UP INDEX AGAIN
IORI T1,.DEVCH ;TABLE OF DEVICE CHARACTERISTICS
GETAB ;READ IT
ERJMP DEVLOP ;CAN'T, GO TO NEXT ONE
LDB T2,[POINT 9,T1,17] ;GET DEVICE TYPE
CAIN T2,.DVDSK ;IS IT A DISK?
JRST DEVLOP ;YES, DON'T SHOW IT
CAIE T2,.DVTTY ;IS IT A TTY?
JRST DEVSHW ;NO, GO SHOW IT
HLLZ T1,DEVUNT ;GET BACK JOB NUMBER
IORI T1,.JOBTT ;INDEX FOR JOB TO TERMINAL
GETAB ;GET IT
ERJMP DIE ;FAILED
TSC T1,DEVUNT ;GET DIFFERENCES WITH SAVED UNIT
TLNN T1,-1 ;CONTROLLING TERMINAL?
JRST DEVLOP ;YES, DON'T SHOW IT
DEVSHW: MOVSI T1,(J) ;GET INDEX
IORI T1,.DEVNA ;WANT NAME
GETAB ;READ IT
SETZ T1, ;CAN'T, USE ZERO
MOVEM T1,DEVNAM ;SAVE FOR LATER
CALL DOCOLS ;DO THE COLUMNS
JRST DEVLOP ;THEN LOOP
;FOLLOWING ARE THE ROUTINES TO OUTPUT THINGS ABOUT DEVICES:
XXDEVN: MOVE T1,DEVNAM ;GET THE DEVICE NAME
JRST SIXOUT ;OUTPUT IT
XXDEVC: MOVE T1,DEVNAM ;GET DEVICE NAME
CALL SIXASC ;CONVERT IT TO ASCIZ
HRROI T1,TEMP ;POINT TO NAME
STDEV ;CONVERT TO DESIGNATOR
ERJMP CPOPJ ;FAILED
MOVE T1,T2 ;MOVE TO RIGHT AC
JRST OCTFUL ;OUTPUT IT
XXDEVJ: HLRZ T1,DEVUNT ;GET THE JOB NUMBER
JRST DECSP3 ;THEN OUTPUT IT
XXDEVU: HLRZ T1,DEVUNT ;GET THE JOB NUMBER AGAIN
JRST JOBUSR ;AND OUTPUT THE USER
SUBTTL DISPLAY FOR DECNET STATUS
;THIS MODE IS ENTERED BY THE "DN" COMMAND. THE STATUS OF ALL NODES
;ON THE NETWORK IS GIVEN, AND THE STATUS OF ALL LOGICAL LINK
;BLOCKS IS ALSO GIVEN.
DPYDEC: MOVEI T1,.NDGLN ;FUNCTION TO READ LOCAL NODE NAME
MOVEI T2,T3 ;ARGUMENT BLOCK ADDRESS
HRROI T3,LCLNOD ;POINT TO STORAGE
NODE ;GET THE INFORMATION
ERJMP LOSE ;FAILED
TXNE F,FR.CMP ;DON'T WANT TO SEE TITLES?
JRST DECNOH ;YEP, SKIP IT
STR$ [ASCIZ/This is node /] ;TYPE SOME
STR$ LCLNOD ;THEN GIVE THE NODE NAME
MOVEI T1,2 ;WANT TWO VERSIONS RETURNED
MOVEM T1,TEMP ;STORE
MOVEI T1,DATLOC ;GET ADDRESS OF FIRST BLOCK
MOVEM T1,TEMP+1 ;STORE
MOVEI T1,DATLOC+10 ;GET ADDRESS OF SECOND BLOCK
MOVEM T1,TEMP+2 ;STORE THAT TOO
MOVEI T1,.NDGVR ;FUNCTION CODE
MOVEI T2,TEMP ;POINT TO ARGUMENTS
NODE ;READ THE DATA
ERJMP LOSE ;FAILED
STR$ [ASCIZ/ NSP version /] ;TYPE SOME MORE
MOVEI T1,DATLOC ;POINT TO VERSION STUFF
CALL VEROUT ;OUTPUT STRANGE VERSION STYLE
STR$ [ASCIZ/ Routing version /] ;TYPE MORE
MOVEI T1,DATLOC+10 ;POINT TO DATA
CALL VEROUT ;OUTPUT THAT TOO
CRLF ;DO A CRLF
DECNOH: CALL DONODE ;SHOW THE AVAILABLE NODES
CRLF ;THEN DO ANOTHER CRLF
CALL SETEAT ;SET UP TO EAT LINES NOW
JRST DOLLNK ;GO SHOW LOGICAL LINKS
SUBTTL ROUTINE TO TYPE OUT AVAILABLE NODES
;THIS ROUTINE OUTPUTS THE LIST OF AVAILABLE NODES.
DONODE: MOVEI T1,.NDGNT ;FUNCTION TO READ DECNET STRUCTURE
MOVEI T2,DATLOC ;POINT TO STORAGE AREA
MOVEI T3,DATSIZ ;GET SIZE OF AREA
MOVEM T3,DATLOC+.NDNND ;SET IN ARGUMENT BLOCK
NODE ;READ THE DATA
ERJMP LOSE ;FAILED, GO SAY WHY
HLRZ T4,DATLOC+.NDNND ;GET NUMBER OF NODES RETURNED
MOVEI T3,DATLOC+.NDBK1 ;GET ADDRESS OF FIRST POINTER
TXZ F,FR.TMP ;CLEAR TEMP FLAG
STR$ [ASCIZ/Available nodes: /] ;TYPE SOME
NODLOP: SOJL T4,DOCRLF ;IF NO MORE NODES, DO CRLF AND RETURN
TXOE F,FR.TMP ;TIME FOR A COMMA?
STR$ [ASCIZ/, /] ;YES, SEPARATE THE NODES
CALL LEFT ;GET ROOM LEFT ON THIS LINE
CAIGE T1,^D8 ;ENOUGH FOR ANOTHER NODE NAME?
STR$ [ASCIZ/
/] ;NO, MOVE TO NEW LINE
MOVE T1,(T3) ;GET ADDRESS OF THIS BLOCK
MOVE T1,.NDNAM(T1) ;GET POINTER TO NODE NAME
STR$ (T1) ;TYPE IT
AOJA T3,NODLOP ;DO NEXT ONE
SUBTTL SUBROUTINE TO DUMP INFORMATION ABOUT LOGICAL LINKS
;CALLED TO TYPE OUT ALL OF THE LOGICAL LINKS ON THIS NODE, AND THEIR
;STATUS, ETC. THIS CURRENTLY REQUIRES THE MONRD% JSYS TO COLLECT THE
;DATA.
DOLLNK: TXNN F,FR.JSY ;IS THE MONRD% JSYS IN?
RET ;NO, CAN'T GET THIS
MOVEI T1,TP.DLL ;TYPE OF DISPLAY
CALL HDRSET ;SET UP HEADERS
MOVEI T1,.RDDLL ;GET FUNCTION CODE
MOVE T2,[-DATSIZ,,DATLOC] ;POINT TO BUFFER AREA
MONRD% ;READ THE DATA
ERJMP CPOPJ ;FAILED, CAN'T GET IT
JUMPL T1,CPOPJ ;ALSO CAN'T GET IT
HRRZM T2,LNKNUM ;SAVE NUMBER OF LINKS WE GOT
MOVEI J,DATLOC ;POINT TO THE DATA
JBLNKL: SOSL LNKNUM ;ANY MORE LOGICAL LINKS TO SHOW?
CALL FULL ;OR IS SCREEN FULL?
RET ;YES, RETURN
SETOM KWNJOB ;CLEAR ANY KNOWN JOB FOR A FORK
LDB T1,[POINT 4,DL.2(J),5] ;GET STATE OF LINK
CAIN T1,1 ;ACTIVE?
TXNN F,FR.ACT ;OR WANT ALL LINKS ANYWAY?
CALL DOCOLS ;YES, SHOW DATA ABOUT THIS LINK
ADDI J,DLLNUM ;ADVANCE TO NEXT LINK
JRST JBLNKL ;AND SHOW IT
;BITS AND FIELDS IN THE LOGICAL LINK BLOCKS. REFER TO NSPPAR.MAC FOR
;THE ORIGINAL DEFINITIONS.
LLSTA==POINT 4,DL.2(J),5 ;STATE CODE
LLFLG==POINT 12,DL.2(J),17 ;FLAGS FOR THIS LL BLOCK
LLSDE==POINT 1,DL.2(J),7 ;LL BLOCK IS DISASSOCIATED FROM FORK
LLFOB==POINT 1,DL.2(J),17 ;THIS IS A SRV
LLINT==POINT 1,DL.2(J),6 ;THIS IS AN INTERNAL LINK
LLLNK==POINT 18,DL.2(J),35 ;LINK ID
LLFRK==POINT 18,DL.3(J),17 ;FORK WHICH OWNS LL BLOCK
LLFNM==POINT 8,DL.4(J),19 ;REMOTE OBJECT NUMBER
LLHLK==POINT 16,DL.4(J),35 ;LINK ID ON REMOTE HOST
LLBRP==POINT 1,DL.7(J),0 ;TRANSBIT BACK-PRESSURE BIT
LLBRL==POINT 1,DL.7(J),1 ;RECEIVE BACK-PRESSURE BIT
LLMFC==POINT 2,DL.7(J),3 ;FLOW CONTROL CODE
LLMSM==POINT 8,DL.7(J),27 ;MAXIMUM MESSAGES ALLOWED
LLDSN==POINT 12,DL.11(J),11 ;TRANSMIT COUNTER
LLIDN==POINT 12,DL.11(J),35 ;RECEIVE COUNTER
LLTSK==POINT 30,DL.13(J),35 ;POINTER TO TASK NAME
LLHST==POINT 36,DL.14(J),35 ;POINTER TO REMOTE HOST NAME
LLBPCT==POINT 36,DL.17(J),35 ;CURRENT BYTE COUNT
LLBSZ==POINT 6,DL.20(J),5 ;BYTE SIZE FOR IO
LLRSN==POINT 16,DL.20(J),35 ;REASON CODE FOR ABORT
LLSOB==POINT 18,DL.24(J),17 ;OBJECT CODE FOR A SRV
;THE FOLLOWING MACRO DEFINES WHICH WORDS WE WANT TO KNOW ABOUT,
;AND IS USED TO RETURN THEM IN THE MONRD% JSYS.
DEFINE LLNUMS,<
LLLIST <2,3,4,7,10,11,13,14,17,20,24>
>
;ROUTINES TO TYPE OUT VARIOUS THINGS ABOUT THE LINKS.
XXLKFK: LDB T1,[LLSDE] ;GET FLAG FOR DISASSOCIATED LL BLOCK
JUMPN T1,LNKDIS ;JUMP IF IT IS DISASSOCIATED
LDB T1,[LLFRK] ;GET FORK WHICH OWNS THIS LINK
JRST OCTSP3 ;OUTPUT IT
LNKDIS: STR$ [ASCIZ/--/] ;SAY NO FORK
RET ;DONE
XXLKJB: LDB T1,[LLSDE] ;SEE IF THIS BLOCK IS DISACCOCIATED
JUMPN T1,LNKDIS ;YES, GO TYPE DASHES
LDB T1,[LLFRK] ;GET THE FORK OWNINT IT
CALL FRKJOB ;FIND WHICH JOB HAS THAT FORK
RET ;FAILED
JRST DECSP2 ;OK, GO OUTPUT JOB NUMBER
XXLPRG: LDB T1,[LLSDE] ;SEE IF THIS IS A DISASSOCIATED BLOCK
JUMPN T1,CPOPJ ;IF SO, TYPE NOTHING
LDB T1,[LLFRK] ;GET THE FORK WHICH OWNS IT
CALL FRKJOB ;FIND OUT THE JOB NUMBER
RET ;FAILED
MOVSI T1,(T1) ;PUT INTO LEFT HALF
IORI T1,.JOBPN ;INDEX
GETAB ;READ PROGRAM NAME
ERJMP CPOPJ ;FAILED
JRST SIXOUT ;GO OUTPUT IT
XXLBYC: LDB T1,[LLBPCT] ;GET THE CURRENT BYTE COUNT
JRST DECSP6 ;OUTPUT IT
XXLKID: LDB T1,[LLLNK] ;GET THIS LINK ID
JRST OCTSP6 ;OUTPUT IT AND RETURN
XXLKIR: LDB T1,[LLHLK] ;GET LINK ID ON REMOTE HOST
JRST OCTSP6 ;OUTPUT IT AND RETURN
XXLSEG: LDB T1,[LLDSN] ;GET TRANSMIT COUNTER
CALL OCTSP4 ;OUTPUT IT
LDB T1,[LLIDN] ;GET RECEIVE COUNTER
JRST OCTSP6 ;OUTPUT AND RETURN
XXLOBJ: LDB T2,[LLFOB] ;GET FLAG DISTINGUSHING DCN FROM A SRV
LDB T1,[LLSOB] ;GET OBJECT CODE ASSUMING THIS IS A SRV
SKIPN T2 ;IS THIS ACTUALLY A DCN?
LDB T1,[LLFNM] ;YES, GET REMOTE OBJECT
MOVSI T2,-OBJNUM ;GET READY FOR SEARCH
HLRZ T3,OBJTAB(T2) ;GET NEXT OBJECT NUMBER
CAME T1,T3 ;FOUND IT?
AOBJN T2,.-2 ;NO, CONTINUE LOOKING
JUMPGE T2,DECOUT ;IF NOT FOUND, OUTPUT IN DECIMAL
MOVE T1,OBJTAB(T2) ;GET POINTER TO NAME
STR$ (T1) ;TYPE IT
RET ;DONE
;TABLE OF OBJECT NAMES:
DEFINE NT(CODE,TEXT),<
XWD <CODE>,[ASCIZ/TEXT/] ;;CODE AND NAME
>
OBJTAB: NT 0,TASK
NT 1,FAL1
NT 2,URDS
NT 3,ATS
NT 4,CTS
NT 5,TCL1
NT 6,OSI
NT 7,NRM
NT 10,3270
NT 11,2780
NT 12,3790
NT 13,TPS
NT 17,TCL
NT 20,TLK
NT 21,FAL
NT 22,RTL
NT 23,NCU
NT ^D47,POSI
NT ^D200,NVT
NT ^D201,MAIL
OBJNUM==.-OBJTAB ;NUMBER OF ENTRIES
XXLKTP: MOVE T1,<PW(LLFLG)>(J) ;GET WORD CONTAINING FLAGS
TXNE T1,<PM(LLFOB)> ;IS THIS A SRV OR A DCN?
TDZA T2,T2 ;A SRV, MAYBE
MOVEI T2,1 ;A DCN, MAYBE
TXNE T1,<PM(LLINT)> ;IS THIS REALLY INTERNAL?
MOVEI T2,2 ;YES, GET THAT OFFSET
STR$ [ASCII/SRV /
ASCII/DCN /
ASCII/Int /](T2) ;OUTPUT PROPER NAME
CHI$ "(" ;TYPE OPENING PARENTHESIS
LDB T1,[LLBSZ] ;GET BYTE SIZE
CALL DECOUT ;OUTPUT BYTE SIZE
CHI$ ")" ;FINISH THE PARANTHESIS
RET ;DONE
XXLHST: LDB T1,[LLHST] ;GET POINTER TO HOST NAME
JUMPE T1,NOREM ;IF NONE, WE ARE LOCAL
TLNE T1,-1 ;CAN ONLY USE SECTION 0
RET ;NO, FAIL
HRLI T1,^D20 ;ASK FOR SOME WORDS
MOVEI T2,TEMP ;PLACE TO READ TO
PEEK ;READ DATA
ERJMP CPOPJ ;FAILED
SKIPE TEMP ;ANY REMOTE HOST NAME?
JRST TELHST ;YES, GO OUTPUT IT
NOREM: STR$ LCLNOD ;OUTPUT OUR OWN NODE
RET ;DONE
XXLUSR: LDB T1,[LLSDE] ;SEE IF LL BLOCK IS DISACCIATED
JUMPN T1,CPOPJ ;IF SO, TYPE NOTHING
LDB T1,[LLFRK] ;GET FORK OWNING THE LINK
CALL FRKJOB ;CONVERT TO JOB NUMBER
RET ;CAN'T DO IT
JOBUSR: HRROI T2,T4 ;WANT ONE WORD RETURNED IN T4
MOVEI T3,.JIUNO ;JOB'S USER NUMBER
GETJI ;READ IT
ERJMP CPOPJ ;CAN'T
MOVE T1,T4 ;MOVE TO RIGHT AC
MOVEI T2,3 ;WANT THREE WORDS
JRST USROUT ;GO OUTPUT IT
XXLTSK: LDB T1,[LLTSK] ;GET POINTER TO TASK NAME
JUMPE T1,CPOPJ ;RETURN IF NULL
TLNE T1,-1 ;BETTER NOT BE OUT OF SECTION
RET ;YES, CAN'T GET IT
HRLI T1,^D20 ;ASK FOR SOME WORDS
MOVEI T2,TEMP ;POINT TO STORAGE
PEEK ;READ TEXT
ERJMP CPOPJ ;NO PRIVILEGES
TELHST: SETZM TEMP+^D20 ;MAKE SURE TEXT ENDS
MOVX T1,177B13 ;GET MASK FOR SECOND CHARACTER IN WORD
TXNE F,FR.MOR ;ANY MORE COLUMNS?
ANDCAM T1,TEMP+1 ;YES, CUT OFF TEXT AFTER SIX CHARS
STR$ TEMP ;OUTPUT NAME
RET ;DONE
XXFLOW: LDB T1,[LLBRP] ;GET BACK PRESSURE BIT
CHR$ [EXP " ","T"](T1) ;SAY IF TRANSMITS ARE BLOCKED
LDB T1,[LLBRL] ;GET OTHER BACK PRESSURE BIT
CHR$ [EXP " ","R"](T1) ;SAY IF RECEIVES ARE BLOCKED
SPACE ;SPACE OVER SOME
LDB T1,[LLMFC] ;GET TYPE OF FLOW CONTROL
CAILE T1,MAXFLW ;LEGAL VALUE?
SETO T1, ;NO, SAY UNKNOWN
STR$ @FLOWTB(T1) ;OUTPUT THE TYPE
JUMPE T1,CPOPJ ;IF NONE, ALL DONE
STR$ [ASCIZ/: /] ;TYPE MORE
LDB T1,[LLMSM] ;GET REMAINING MESSAGES TO SEND
JRST DECOUT ;OUTPUT AND RETURN
[ASCIZ/???/] ;UNKNOWN CODE
FLOWTB: [ASCIZ/None/] ;(0) NO FLOW CONTROL
[ASCIZ/Seg/] ;(1) CONTROL IS BY SEGMENT
[ASCIZ/Msg/] ;(2) CONTROL IS BY MESSAGES
MAXFLW==.-FLOWTB-1 ;HIGHEST KNOWN FLOW CONTROL CODE
XXLSTA: LDB T1,[LLSTA] ;GET STATE CODE
CAILE T1,LLSMAX ;GREATER THAN KNOWN STATE?
JRST OCTOUT ;YES, OUTPUT IN OCTAL
STR$ @LLSTAB(T1) ;NO, OUTPUT THE STATE
RET ;DONE
LLSTAB: [ASCIZ/Transient/] ;(0) NON-EXISTANT
[ASCIZ/CI wait/] ;(1) OBJECT IS LISTENING
[ASCIZ/CI sent/] ;(2) CONNECT-INITIALIZE SENT
[ASCIZ/CI read/] ;(3) CONNECT-INITIALIZE RECEIVED
[ASCIZ/Active/] ;(4) LINK IS ACTIVE
[ASCIZ/DI sent/] ;(5) DI SENT
[ASCIZ/DI queued/] ;(6) DI QUEUED
[ASCIZ/DI read/] ;(7) DI REVEIVED
ABTCOD: [ASCIZ/Aborted/] ;(10) CONNECTION ABORTED
LLSMAX==.-LLSTAB-1 ;HIGHEST KNOWN STATE
XXLABT: LDB T1,[LLSTA] ;GET STATE CODE
CAIE T1,ABTCOD-LLSTAB ;IS IT CONNECTION BROKEN?
RET ;NO, TYPE NOTHING
LDB T1,[LLRSN] ;YES, GET REASON
MOVSI T2,-DINUM ;GET READY FOR SEARCH
HLRZ T3,DITAB(T2) ;GET NEXT POSSIBILITY
CAME T1,T3 ;IS THIS IT?
AOBJN T2,.-2 ;NO, KEEP SEARCHING
JUMPGE T2,DECOUT ;CAN'T FIND, GO GIVE NUMBER
HRLZ T1,DITAB(T2) ;GET ADDRESS OF STRING
HRRI T1,TEMP ;POINT TO STORAGE
BLT T1,TEMP+^D20 ;COPY THE STRING
TXNE F,FR.MOR ;MORE COLUMNS COMING?
SETZM TEMP+3 ;YES, CUT OFF OUTPUT
STR$ TEMP ;OUTPUT REASON
RET ;DONE
;TABLE OF DISCONNECT REASONS:
DEFINE NT(CODE,TEXT),<
XWD <CODE>,[ASCIZ/TEXT/] ;;CODE AND TEXT FOR ERRORS
>
DITAB: NT .DCX0,No special error
NT .DCX1,Resource allocation failure
NT .DCX2,Unknown destination node
NT .DCX3,Node shutting down
NT .DCX4,Unknown destination process
NT .DCX5,Invalid name field
NT .DCX11,User abort
NT .DCX32,Too many node connections
NT .DCX33,Too many process connections
NT .DCX34,Access not permitted
NT .DCX35,Logical link mismatch
NT .DCX36,Invalid account
NT .DCX37,Segment size too small
NT .DCX38,Process aborted
NT .DCX39,No path to destination node
NT .DCX40,Aborted due to data loss
NT .DCX41,Unknown destination process
NT .DCX42,Disconnect confirmation
NT .DCX43,Image data field too long
DINUM==.-DITAB ;SIZE OF TABLE
SUBTTL DISPLAY FOR ARPANET STATUS
;THIS DISPLAY MODE IS SET BY THE "ANH" COMMAND. THE STATUS OF ALL
;ARPANET SITES IS GIVEN. THIS DOES NOT NEED THE MONRD% JSYS.
DPYARH: MOVX T1,.GTHSZ ;WANT TO READ NUMBER OF HOSTS
GTHST% ;READ IT
ERJMP NOARPA ;FAILED, GO SEE WHY
SKIPN J,T2 ;PUT NUMBER OF HOSTS IN RIGHT AC
RET ;NO HOSTS, RETURN
MOVEI T1,TP.ANH ;THIS IS DISPLAY FOR HOST STATUS
CALL HDRSET ;SET UP HEADERS
TXO F,FR.EAT ;REMEMBER TO EAT OUTPUT LATER
APALOP: CALL FULL ;SEE IF SCREEN IS FULL YET
RET ;YES, DONE
MOVX T1,.GTHHI ;GET FUNCTION
MOVEI T3,(J) ;AND HOST INDEX
GTHST% ;READ HOST NUMBER AND STATUS
ERJMP APALPL ;FAILED
DMOVEM T3,APANUM ;SAVE NUMBER AND STATUS
TXNE T4,HS%VAL ;VALID STATUS?
CALL DOCOLS ;YES, SHOW THIS HOST
APALPL: AOBJN J,APALOP ;LOOP UNTIL LOOKED AT THEM ALL
RET ;DONE
NOARPA: MOVEI T1,.FHSLF ;GET READY
GETER ;READ ERROR REASON
HRRZ T1,T2 ;GET ERROR CODE
CAIE T1,ILINS2 ;IS THE JSYS UNDEFINED?
JRST LOSE ;NO, SOME OTHER ERROR
STR$ [ASCIZ/
? No ARPANET code exists in this monitor
/] ;YES, SAY WHAT'S WRONG
RET ;AND RETURN
;ROUTINES TO TYPE DATA ABOUT HOSTS:
XXAHST: MOVE T1,APANUM ;GET HOST NUMBER
JRST OCTOUT ;OUTPUT IT
XXANAM: MOVEI T1,.GTHNS ;WANT TO GET NAME
HRROI T2,TEMP ;POINT TO STORAGE
MOVE T3,APANUM ;GET HOST NUMBER
GTHST% ;READ THE NAME STRING
ERJMP CPOPJ ;NONE EXISTS
TXNE F,FR.MOR ;ANY MORE COLUMNS?
SETZM TEMP+3 ;YES, THEN RESTRICT THE NAME
STR$ TEMP ;OUTPUT THE NAME
RET ;DONE
XXATYP: LDB T1,[POINTR APASTS,HS%STY] ;GET TYPE CODE
CAILE T1,APATPX ;HIGHER THAN WE KNOW?
JRST OCTTEL ;YES, GIVE THE NUMBER
STR$ @APATPT(T1) ;NO, TYPE THE SYSTEM
MOVE T1,APASTS ;GET STATUS AGAIN
TXNE T1,HS%USR ;IS THIS A USER?
STR$ [ASCIZ/ (user)/] ;YES, SAY SO
RET ;DONE
APATPT: [ASCIZ /# 0/] ;(0)
[ASCIZ /TENEX/] ;(1)
[ASCIZ /ITS/] ;(2)
[ASCIZ /TOPS-10/] ;(3)
[ASCIZ /TIP/] ;(4)
[ASCIZ /MTIP/] ;(5)
[ASCIZ /ELF/] ;(6)
[ASCIZ /ANTS/] ;(7)
[ASCIZ /MULTICS/] ;(10)
[ASCIZ /TOPS-20/] ;(11)
[ASCIZ /UNIX/] ;(12)
APATPX==.-APATPT-1 ;HIGHEST KNOWN SYSTEM TYPE
XXASTS: MOVE T1,APASTS ;GET THE STATUS OF THIS HOST
TXNE T1,HS%UP ;IS HOST UP?
STR$ [ASCIZ/Up/] ;YES, SAY SO
TXNE T1,HS%UP ;WELL?
RET ;YES, DONE
STR$ [ASCIZ/Down/] ;SAY IT IS DOWN
TXCE T1,HS%DAY+HS%HR+HS%MIN+HS%RSN ;NO TIME GIVEN?
TXCN T1,HS%DAY+HS%HR+HS%MIN+HS%RSN ;OR UNKNOWN?
RET ;YES, SAY NOTHING
STR$ [ASCIZ/, up at /] ;MORE OUTPUT
LDB T1,[POINTR T1,HS%DAY] ;GET DAY OF WEEK
STR$ DAYTAB(T1) ;TYPE IT
LDB T1,[POINTR APASTS,HS%HR] ;GET HOUR
CALL DECOUT ;OUTPUT IT
CHI$ ":" ;THEN THE COLON
LDB T1,[POINTR APASTS,HS%MIN] ;GET MINUTE
IMULI T1,5 ;FIVE MINUTE EXPANSION
JRST DECOUT ;OUTPUT AND RETURN
DAYTAB: ASCII /Mon / ;(0) MONDAY
ASCII /Tue / ;(1) TUESDAY
ASCII /Wed / ;(2) WEDNESDAY
ASCII /Thu / ;(3) THURSDAY
ASCII /Fri / ;(4) FRIDAY
ASCII /Sat / ;(5) SATURDAY
ASCII /Sun / ;(6) SUNDAY
SUBTTL DISPLAY ROUTINE TO SHOW ARPANET CONNECTIONS
;ROUTINE TO TYPE OUT ALL OF THE ARPANET CONNECTIONS IN USE ON THIS
;SYSTEM. THIS IS THE "ANC" COMMAND.
DPYARC: MOVEI T1,TP.ANC ;GET CODE FOR ARPANET CONNECTION DISPLAY
CALL HDRSET ;AND SET UP HEADERS FOR IT
TXO F,FR.EAT ;REMEMBER TO DO EATING LATER
MOVEI T1,.GTNSZ ;GET FUNCTION
GTNCP% ;READ NUMBER OF NETWORK CONNECTIONS
ERJMP NOARPA ;FAILED, COMPLAIN
SKIPN J,T2 ;COPY TO GOOD AC
RET ;NONE, RETURN
ARPCLP: CALL FULL ;SEE IF SCREEN IS OVERFLOWED YET
RET ;YES, DONE
MOVX T1,.GTNIX ;GET FUNCTION TO RETURN DATA
MOVEI T2,(J) ;USES CONNECTION INDEX
MOVEI T3,ABLK ;POINT TO BLOCK
MOVSI T4,-<.NCSTS+1> ;GET NUMBER OF WORDS
GTNCP% ;READ THE STATUS
ERJMP ARPCLL ;FAILED
MOVE T1,ABLK+.NCFSM ;GET THE STATE OF THE CONNECTION
CAIE T1,DEADCD ;IS IT DEAD?
CAIN T1,FREECD ;OR FREE?
JRST ARPCLL ;YES, DON'T SHOW IT
CALL DOCOLS ;SHOW DATA ON THIS CONNECTION
ARPCLL: AOBJN J,ARPCLP ;LOOP OVER ALL OF THEM
RET ;DONE
;ROUTINES TO TYPE VARIOUS DATA ABOUT ARPANET CONNECTIONS:
XXACFH: MOVX T1,.GTHNS ;WANT TO GET HOST STRING
HRROI T2,TEMP ;POINT TO STORAGE
MOVE T3,ABLK+.NCFHS ;GET HOST NUMBER
GTHST% ;READ HOST NAME
ERJMP ACFHNU ;FAILED, GO GIVE NUMBER
TXNE F,FR.MOR ;LAST COLUMN?
SETZM TEMP+3 ;NO, THEN CUT OFF OUTPUT
STR$ TEMP ;OUTPUT NAME
RET ;DONE
ACFHNU: MOVE T1,ABLK+.NCFHS ;GET NUMBER
JRST OCTTEL ;OUTPUT NUMBER
XXACLS: SKIPA T1,ABLK+.NCLSK ;GET LOCAL SOCKET NUMBER
XXACFS: MOVE T1,ABLK+.NCFSK ;OR FOREIGN SOCKET NUMBER
JRST OCTOUT ;OUTPUT IT
XXACVT: MOVE T1,ABLK+.NCNVT ;GET VIRTUAL TERMINAL NUMBER
CAME T1,[-1] ;REALLY ONE HERE?
JRST OCTSP3 ;YES, SAY WHICH ONE IT IS
STR$ [ASCIZ/---/] ;NO, TYPE DASHES
RET ;DONE
XXACBT: MOVE T1,ABLK+.NCBTC ;GET NUMBER OF BITS TRANSMITTED OR RECEIVED
JRST DECOUT ;TYPE AND RETURN
XXABTA: SKIPA T1,ABLK+.NCBAL ;GET BIT ALLOCATION
XXAMSA: MOVE T1,ABLK+.NCMSG ;OR MESSAGE ALLOCATION
JRST DECOUT ;OUTPUT IT
XXAPRS: MOVE T4,[POINT 4,ABLK+.NCSTS,19] ;POINT TO PREVIOUS STATES
APRSLP: ILDB T1,T4 ;GET NEXT STATE
CALL APASTE ;OUTPUT IT
TLNN T4,770000 ;FINISHED OFF WORD YET?
RET ;YES, RETURN
STR$ [ASCIZ/, /] ;NO, SPACE OVER SOME
JRST APRSLP ;AND CONTINUE
XXASTE: MOVE T1,ABLK+.NCFSM ;GET THE STATE OF THE CONNECTION
APASTE: SKIPL T1 ;MAKE SURE IT IS REASONABLE
CAILE T1,APASTM ;SO WE CAN OUTPUT IT
JRST OCTOUT ;NO, THEN GIVE IN OCTAL
STR$ APASTT(T1) ;TYPE THE STATE CODE
RET ;DONE
;TABLE OF CONNECTIONS STATES:
DEADCD==0 ;STATE OF A DEAD CONNECTION
FREECD==16 ;STATE OF A FREE CONNECTION
APASTT: ASCII /DEAD/ ;(0) DEAD
ASCII /CLZD/ ;(1) CLOSED
ASCII /PNDG/ ;(2) PENDING
ASCII /LSNG/ ;(3) LISTENING
ASCII /RFCR/ ;(4) RFC RECEIVED
ASCII /CLW1/ ;(5) CLOSE WAIT SUB1
ASCII /RFCS/ ;(6) RFC SENT
ASCII /OPND/ ;(7) OPENED
ASCII /CLSW/ ;(10) CLOSE WAIT
ASCII /DATW/ ;(11) FINAL DATA WAIT
ASCII /RFN1/ ;(12) RFN1 FINAL WAIT
ASCII /CLZW/ ;(13) PROGRAM CLOSE WAIT
ASCII /RFN2/ ;(14) RFN2 SUB2 WAIT
ASCII /NUSE/ ;(15) NOT IN USE
ASCII /FREE/ ;(16) FREE
APASTM==.-APASTT-1 ;HIGHEST LEGAL STATE
SUBTTL ROUTINE TO GIVE HELP MESSAGE
;THIS MODE IS ENTERED BY THE "H" COMMAND. THERE ARE SEVERAL
;SUB-DISPLAYS, SUCH AS HELP FILE TYPEOUT, COLUMN TYPEOUT. THE NORMAL
;HELP DISPLAY SIMPLY TYPES OUT THE HELP FILE FOR SYSDPY.
DPYHLP: SETOM HDRTYP ;CLEAR ANY HEADER STUFF
TAB$ ;SET DEFAULT TABS
TXNE F,FR.CMP ;WANT COMPRESSED OUTPUT?
JRST HLPCMP ;YES, SKIP TIME OUTPUT
HRROI T1,TEMP ;POINT TO TEMPORARY DATA
SETOB T2,T3 ;CURRENT TIME, VERBOSE OUTPUT
ODTIM ;COMPUTE AND STORE IT
STR$ TEMP ;THEN OUTPUT IT
STR$ [ASCIZ/ Page /] ;TYPE SOME
MOVE T1,PAGE ;GET PAGE NUMBER
ADDI T1,1 ;CORRECT TO MATCH "S" COMMAND
CALL DECOUT ;OUTPUT IT
STR$ [BYTE (7)12,12] ;THEN SKIP A LINE
HLPCMP: SKIPE T1,HLPDSP ;ANY SPECIAL HELP DISPLAY?
JRST (T1) ;YES, GO DO IT
CALL SETEAT ;GO SET UP HOW MANY LINES TO EAT
SKIPE T1,HLPJFN ;HAVE HELP FILE OPEN YET?
JRST HLPTYP ;YES, GO TYPE IT OUT
MOVX T1,GJ%SHT+GJ%OLD ;GET READY
HRROI T2,[ASCIZ/HLP:SYSDPY.HLP/] ;GET STRING
GTJFN ;OPEN THE HELP FILE
ERJMP LOSE ;FAILED, GO EXPLAIN THINGS
HRRZM T1,HLPJFN ;REMEMBER THE JFN
MOVX T2,OF%RD+7B5 ;GET SET TO OPEN THE FILE
OPENF ;OPEN IT
ERJMP [MOVE T1,HLPJFN ;FAILED, GET JFN
SETZM HLPJFN ;CLEAR IT
RLJFN ;RELEASE IT
ERJMP LOSE ;FAILED
JRST LOSE] ;SUCCEEDED, GO COMPLAIN
HLPTYP: SETZ T2, ;WANT TO BE AT FRONT OF FILE
SFPTR ;SET US THERE
ERJMP LOSE ;FAILED
HLPLOP: CALL FULL ;OVERFLOWED THE SCREEN?
RET ;YES, RETURN NOW
MOVE T1,HLPJFN ;GET INPUT JFN
MOVE T2,[POINT 7,TEMP] ;GET POINTER TO BUFFER
MOVNI T3,TMPSIZ*5-5 ;GET NUMBER OF BYTES TO READ
SIN ;READ THEM
ERJMP HLPDON ;FAILED, GO SEE WHY
IDPB T3,T2 ;END STRING WITH A NULL
STR$ TEMP ;OUTPUT THIS PART
JRST HLPLOP ;LOOP UNTIL END OF FILE REACHED
HLPDON: SETZ T1, ;GET A NULL
IDPB T1,T2 ;STORE IT TO MAKE ASCIZ STRING
STR$ TEMP ;OUTPUT REMAINING PART OF TEXT
MOVEI T1,.FHSLF ;GET READY
GETER ;FIND OUT WHY WE STOPPED
ANDI T2,-1 ;KEEP ONLY THE ERROR CODE
CAIE T2,IOX4 ;END OF FILE?
JRST LOSE ;NO, GO COMPLAIN
RET ;DONE
SUBTTL SUBROUTINE TO TYPE OUT COLUMN NAMES
;CALLED AS PART OF THE HELP COMMAND, TO CREATE A LIST OF THE COLUMN
;NAMES, TELLING WHICH ONES ARE BEING SHOWN. THE OUTPUT IS ORDERED
;SO HE CAN TELL WHICH DISPLAYS THE COLUMNS ARE FOR.
HLPCOL: TAB$ [$TABS <15,40>] ;SET NICE TAB STOPS
TXNN F,FR.CMP ;SUPPRESS IF COMPRESSING
STR$ [ASCIZ/Display Displayed columns Suppressed columns
/] ;TYPE SOME
CALL SETEAT ;SET UP TO EAT LINES
SETOM LSTTYP ;CLEAR LAST TYPE SEEN
MOVE J,COLHLC ;GET AOBJN POINTER TO DISPLAY TYPES
HLPCLL: AOBJP J,CPOPJ ;RETURN IF DID ALL DISPLAY TYPES
HRRZM J,COLTYP ;REMEMBER THIS COLUMN TYPE
TXOE F,FR.NDC ;ANY PREVIOUS TYPES OUTPUT?
CRLF ;YES, SEPARATE FROM THEM
SETZM COLDIS ;INITIALIZE INDEX INTO DISPLAYED COLUMNS
SETZM COLSUP ;AND INDEX INTO SUPPRESSED COLUMNS
TYPCNX: SETZ T4, ;CLEAR RESULT AC
CALL FNDDIS ;FIND THE NEXT DISPLAYED COLUMN
MOVE T4,T1 ;REMEMBER THE TEXT ADDRESS
CALL FNDSUP ;THEN FIND THE NEXT SUPPRESSED COLUMN
HRL T4,T1 ;SAVE THAT ADDRESS TOO
JUMPE T4,HLPCLL ;IF NO MORE COLUMNS, DO NEXT TYPE
SKIPLE @DPYTAB+$DPEAT ;STILL HAVE LINES TO EAT?
JRST TYPCNC ;YES, JUST DO A CRLF
MOVE T2,COLTYP ;GET CURRENT COLUMN TYPE
HLRZ T3,DISTAB(T2) ;GET NAME OF DISPLAY
CAME T2,LSTTYP ;SAME AS PREVIOUS ONE?
STR$ (T3) ;NO, SAY WHICH DISPLAY THIS IS
MOVEM T2,LSTTYP ;AND REMEMBER THE NEW TYPE
TAB ;SPACE OVER
TRNE T4,-1 ;ANY DISPLAYED COLUMN?
STR$ (T4) ;YES, OUTPUT IT
TAB ;THEN TAB AGAIN
TLNE T4,-1 ;ANY SUPPRESSED COLUMN?
STR$ (T1) ;YES, OUTPUT IT
TYPCNC: CRLF ;END IN A CRLF
JRST TYPCNX ;LOOP OVER SOME MORE COLUMNS
;SUBROUTINES TO SEARCH FOR ANOTHER DISPLAYED COLUMN OR SUPPRESSED
;COLUMN. SKIP RETURNS IF NOT FOUND, NON-SKIP WITH TEXT OF COLUMN IN
;T1 IF FOUND.
FNDDIS: MOVE T1,COLDIS ;GET NEXT POSSIBLE COLUMN
SKIPN T2,COLDSP(T1) ;ANY MORE DISPLAYED COLUMNS?
RETSKP ;NOT FOUND, SKIP RETURN
AOS COLDIS ;INCREMENT COUNTER
MOVE T3,CL.TYP(T2) ;GET THE TYPE OF COLUMN
CAME T3,COLTYP ;THE ONE CURRENTLY LOOKING FOR?
JRST FNDDIS ;NO, LOOP FOR ANOTHER ONE
MOVSI T1,-COLNUM ;GET READY FOR SEARCH
FNDDIL: HRRZ T3,COLTAB+1(T1) ;FIND ADDRESS FOR NEXT POSSIBLE COLUMN
CAME T2,T3 ;FOUND THIS ONE?
AOBJN T1,FNDDIL ;NO, KEEP GOING
JUMPGE T1,FNDDIS ;SHOULD NEVER FAIL, BUT ...
HAVSUP: HLRZ T1,COLTAB+1(T1) ;GET THE STRING FOR THIS COLUMN
RET ;RETURN IT
FNDSUP: MOVE T1,COLSUP ;GET NEXT POSSIBLE INDEX
CAIL T1,COLNUM ;ALL DONE?
RETSKP ;YES, SKIP RETURN
AOS COLSUP ;INCREMENT COUNTER
HRRZ T2,COLTAB+1(T1) ;GET ADDRESS OF DATA FOR COLUMN
MOVE T3,CL.TYP(T2) ;THEN GET TYPE OF COLUMN
CAME T3,COLTYP ;THE ONE WE ARE INTERESTED IN?
JRST FNDSUP ;NO, KEEP LOOKING
SETZ T3, ;GET READY FOR A LOOP
FNDSUL: SKIPN COLDSP(T3) ;RAN OUT OF COLUMNS?
JRST HAVSUP ;YES, THIS IS A SUPPRESSED COLUMN
CAME T2,COLDSP(T3) ;FOUND THE COLUMN?
AOJA T3,FNDSUL ;NO, KEEP SEARCHING
JRST FNDSUP ;YES, LOOK AT NEXT COLUMN
SUBTTL FORK TERMINATION INTERRUPT HANDLING
;HERE WHEN WE ARE WAITING FOR AN INFERIOR TO TERMINATE, TO BREAK
;OUT OF THE SLEEP WE WERE DOING FOR IT.
FRKINT: PUSH P,T1 ;SAVE AN AC
MOVEI T1,PSHINT ;GET PC TO GO TO
SKIPN FRKFLG ;IN THE SLEEP?
MOVEM T1,CHNPC1 ;YES, CHANGE THE PC
MOVEI T1,1 ;GET POSITIVE NUMBER
MOVEM T1,FRKFLG ;STOP THE NEXT SLEEP
POP P,T1 ;RESTORE THE AC
DEBRK ;RETURN WHERE INTERRUPTED
SUBTTL CHARACTER INTERRUPT HANDLING
;HERE TO HANDLE AN INTERRUPT DUE TO CHARACTER TYPE IN. THE
;CHARACTER IS STORED IN ONE OF SEVERAL BUFFERS, AND WHEN A LINE FEED
;IS SEEN THE BUFFER IS MADE AVAILABLE TO THE COMMAND PROCESSOR.
TTYINT: PUSH P,T1 ;SAVE AN AC
PUSH P,T2 ;AND ANOTHER
CHRCHK: MOVEI T1,.PRIIN ;GET READY
SIBE ;IS INPUT BUFFER NONEMPTY?
JRST CHRGET ;YES, GO HANDLE A CHAR
POP P,T2 ;NO, RESTORE ACS
POP P,T1 ;BOTH
DEBRK ;AND DISMISS THE INTERRUPT
CHRGET: PUSH P,[CHRCHK] ;SET TO CHECK ANOTHER CHAR WHEN DONE
PBIN ;GET THE CHARACTER
SKIPL @INTBUF ;SEE IF HAVE NOPLACE TO PUT THE CHAR
CAIN T1,33 ;OR SEE IF IT IS AN ALTMODE
JRST CHRALT ;YES, RING BELL
CAIN T1,"U"-100 ;CONTROL-U?
JRST CHRINI ;YES, GO REINITIALIZE
CAIN T1,177 ;RUBOUT?
JRST CHRRUB ;YES, GO UNDO A CHAR
CAIN T1,12 ;LINE FEED?
JRST CHRLIN ;YES, HAVE A LINE
AOS T2,INTCNT ;ADD 1 TO INPUT CHARS
CAILE T2,BUFLEN*5-1 ;ROOM FOR NEW CHAR?
JRST CHRFUL ;NO, COMPLAIN
IDPB T1,INTPTR ;PUT IT IN THE BUFFER
CAIN T2,1 ;FIRST CHARACTER ON THIS LINE?
CAIE T1," " ;AND IT IS A SPACE?
RET ;NO, JUST RETURN
MOVEI T1,"S" ;YES, GET SCROLL COMMAND LETTER
DPB T1,INTPTR ;REPLACE SPACE WITH IT
MOVEI T1,12 ;GET A LINE FEED
JRST CHRLIN ;AND PRETEND IT WAS TYPED IN
;HERE ON AN ALTMODE. WE DON'T DO ANY RECOGNITION, SO WARN THE
;USER BY BEEPING AT HIM.
CHRALT: MOVEI T1,7 ;GET A BELL CHAR
PBOUT ;OUTPUT IT
RET ;RETURN
;HERE ON A RUBOUT. WE REMOVE THE LATEST CHARACTER FROM THE
;INPUT BUFFER. WE BEEP AT HIM IF THERE ARE NO MORE CHARS.
CHRRUB: SKIPG INTCNT ;ANY CHARS STORED?
JRST CHRALT ;NO, GO BEEP AT HIM
SOS INTCNT ;YES, DECREMENT COUNT
SETO T1, ;SET COUNT OF -1
ADJBP T1,INTPTR ;BACK UP BYTE POINTER BY A CHAR
MOVEM T1,INTPTR ;AND STORE BACK
RET ;RETURN
;HERE ON A CONTROL-U. WE DELETE ALL INPUT WE HAVE ACCUMULATED
;SO FAR. THIS ROUTINE IS ALSO CALLED TO INITIALIZE THE INPUT BUFFER.
CHRINI: MOVE T1,@INTBUF ;GET BUFFER WE ARE USING
HRLI T1,(POINT 7,) ;MAKE A POINTER TO IT
MOVEM T1,INTPTR ;SAVE POINTER
SETZM INTCNT ;CLEAR COUNT OF SAVED CHARS
RET ;RETURN
;HERE WHEN HE HAS TYPED TOO MANY CHARACTERS, AND OUR BUFFER HAS
;FILLED UP. WE WIPE OUT THE BUFFER AND BEEP AT HIM.
CHRFUL: MOVEI T1,7 ;GET A BELL
PBOUT ;OUTPUT IT
JRST CHRINI ;GO INITIALIZE AGAIN
;HERE WHEN A LINE FEED HAS BEEN TYPED. WE MAKE THIS BUFFER AVAILABLE
;TO THE PROGRAM, ADVANCE TO THE NEXT BUFFER, AND GET THE MAIN CODE OUT
;OF THE DISMS IF IT WAS IN IT.
CHRLIN: IDPB T1,INTPTR ;FIRST STORE THE LINE FEED
MOVSI T1,(1B0) ;GET SIGN BIT
IORM T1,@INTBUF ;MAKE BUFFER AVAILABLE TO MAIN CODE
AOS T1,INTBUF ;ADVANCE TO NEXT BUFFER
CAILE T1,BUFFS+BUFNUM-1 ;WENT OFF OF END?
MOVEI T1,BUFFS ;YES, RESET TO FIRST ONE
MOVEM T1,INTBUF ;SAVE POINTER
CALL CHRINI ;INITIALIZE POINTER AND COUNTER
MOVEI T1,SLPINT ;GET PC TO GO TO
SKIPN TTYFLG ;IN THE SLEEP?
MOVEM T1,CHNPC1 ;YES, STOP IT
MOVEI T1,1 ;GET POSITIVE
MOVEM T1,TTYFLG ;STOP THE NEXT SLEEP
RET ;RETURN
SUBTTL ROUTINE TO INITIALIZE TTY BUFFERS
;CALLED AT START OF PROGRAM TO BUILD ALL THE BUFFERS. THEY ARE
;INITIALLY SET SO THEY ARE AVAILBLE TO THE INTERRUPT CODE, AND NOT
;TO THE MAIN CODE. THE POINTERS TO THE CURRENT BUFFERS ARE
;ALSO INITIALIZED.
BUFINI: MOVEI T1,BUFFS ;GET ADDRESS OF FIRST BUFFER HEADER
MOVEM T1,INTBUF ;SET AS INTERRUPT CODE'S CURRENT BUFFER
MOVEM T1,RUNBUF ;AND AS COMMAND CODE'S CURRENT BUFFER
MOVEI T1,BUFNUM-1 ;GET NUMBER OF BUFFERS TO INITIALIZE
MOVEI T2,BUFFER ;AND ADDRESS OF WHERE BUFFERS POINT
MOVEM T2,BUFFS(T1) ;POINT NEXT BUFFER AT ITS LOCATION
ADDI T2,BUFLEN ;MOVE TO NEXT ONE
SOJGE T1,.-2 ;LOOP OVER ALL BUFFER HEADERS
PJRST CHRINI ;THEN GO INITIALIZE INTERRUPT DATA
SUBTTL ROUTINE TO DO SPECIAL ACTIONS AT STARTUP
;CALLED RIGHT AFTER PROGRAM IS STARTED, TO SEE IF ANY SPECIAL ACTIONS
;ARE TO BE PERFORMED. IF SO, WE SET UP TO DO THEM. ARGUMENTS ARE
;OBTAINED FROM THE PRARG BLOCK OF THIS PROCESS.
GETARG: MOVE T1,[.PRARD,,.FHSLF] ;GET FUNCTION
MOVEI T2,TEMP ;POINT TO STORAGE
MOVEI T3,1 ;WANT ONLY ONE WORD
PRARG ;READ THE ARGS
ERJMP DIE ;FAILED, COMPLAIN
JUMPLE T3,CPOPJ ;RETURN OK IF NO WORDS READ
SKIPN TEMP ;ANY SPECIAL ACTIONS DESIRED?
RET ;NO, RETURN
MOVE T1,[.PRAST,,.FHSLF] ;GET FUNCTION
MOVEI T2,T4 ;POINT TO AC
MOVEI T3,1 ;ONE ARGUMENT
SETZ T4, ;WANT TO CLEAR THE BLOCK
PRARG ;CLEAR IT
ERJMP DIE ;FAILED
SKIPL T1,TEMP ;GET THE FUNCTION CODE
CAILE T1,ARGMAX ;AND VERIFY ITS VALIDITY
JRST ARGBAD ;IT'S BAD, GO COMPLAIN
PJRST @ARGTAB-1(T1) ;DISPATCH TO ROUTINE
ARGTAB: EXP ARGINS ;(1) JUST INSERT THE MONRD% JSYS
ARGMAX==.-ARGTAB ;HIGHEST LEGAL FUNCTION
ARGINS: TXO F,FR.INS ;SET FLAG SAYING INSERT JSYS ONLY
CALL JSYTST ;GO INSERT THE JSYS IF NECESSARY
HALTF ;QUIT
JRST .-1 ;AND STAY THAT WAY
ARGBAD: HRROI T1,[ASCIZ/
? Illegal function code given in PRARG block
/] ;GET STRING
PSOUT ;TYPE IT
HALTF ;STOP
JRST .-1 ;FOREVER
SUBTTL SUBROUTINE TO SET UP TO READ INITIAL INDIRECT FILE
;HERE TO FIND THE SYSDPY.INI FILE IF IT EXISTS, AND SET IT UP
;SO THAT COMMANDS WILL BE READ FIRST FROM THAT FILE.
TAKINI: HRROI T1,TEMP ;POINT AT BUFFER
HRROI T2,[ASCIZ/PS:</] ;GET READY
SETZ T3, ;TO START STRING
SOUT ;STORE IT
MOVE T2,MYUSER ;GET MY USER NUMBER
DIRST ;CONVERT IT TO STRING
ERJMP DIE ;SHOULDN'T FAIL
HRROI T2,[ASCIZ/>SYSDPY.INI/] ;GET REST OF STRING
SOUT ;BUILD REST OF FILE SPEC
MOVX T1,GJ%SHT+GJ%OLD+GJ%ACC ;SET UP
HRROI T2,TEMP ;POINT AT FILE SPEC
GTJFN ;TRY TO FIND THE FILE
ERJMP NOINIG ;FAILED, GO SEE WHY
MOVX T2,7B5+OF%RD ;WANT TO READ THE FILE
OPENF ;DO THE OPEN
ERJMP DIE ;FAILED, GO COMPLAIN
HRRZM T1,TAKJFN ;SAVE THE JFN AWAY
SETZ T1, ;USE DEFAULT LABEL
CALL TAKFIL ;GO SET UP TO READ COMMANDS FROM IT
JFCL ;DON'T CARE IF IT FAILS
RET ;RETURN
;HERE IF FAILED TO FIND THE FILE:
NOINIG: MOVSI T2,-NOFNUM ;GET READY FOR SEARCH
CAME T1,NOFTAB(T2) ;FOUND THE ERROR?
AOBJN T2,.-1 ;NO, KEEP SEARCHING
JUMPGE T2,DIE ;IF NOT FOUND, GIVE ERROR
RET ;OTHERWISE ITS OK
NOFTAB: EXP GJFX16,GJFX17,GJFX18,GJFX19
EXP GJFX20,GJFX24,GJFX32
NOFNUM==.-NOFTAB ;NUMBER OF ERRORS IN TABLE
;HERE TO PUSH A LEVEL OF INDIRECT COMMANDS. WE SAVE THE CURRENT
;FILE POINTER, SAVED CHARACTER AND RESCAN FLAG, AND SET UP TO READ
;THE COMMAND FILE AGAIN. SKIP RETURN IF SUCCESSFUL.
TAKPSH: MOVE T4,TAKLVL ;GET THE CURRENT LEVEL
CAIL T4,TAKMAX ;CAN WE GO ANOTHER LEVEL DEEPER?
RET ;NO, ERROR RETURN
MOVE T1,TAKJFN ;GET INDIRECT FILE JFN
SKIPE T2,T4 ;AT TTY INPUT LEVEL?
RFPTR ;NO, READ THE CURRENT FILE POSITION
ERJMP CPOPJ ;FAILED, ERROR RETURN
MOVEM T2,TAKPTR(T4) ;SAVE THE OLD FILE POSITION
SETZ T2, ;GET SET
SFPTR ;SET INPUT TO BEGINNING OF FILE
ERJMP CPOPJ ;FAILED
HRRZ T1,SAVCHR ;GET THE SAVED CHARACTER
TXNE F,FR.RSN ;IS THE RESCAN FLAG SET?
TLO T1,-1 ;YES, REMEMBER THAT
MOVEM T1,TAKSVC(T4) ;SAVE THEM
TXZ F,FR.RSN ;CLEAR THE RESCAN FLAG
AOS TAKLVL ;INCREMENT DEPTH COUNTER
RETSKP ;GOOD RETURN
;HERE TO POP UP A LEVEL OF INDIRECT COMMANDS. WE HAVE TO RESTORE THE
;CURRENT FILE POSITION, THE SAVED CHARACTER, AND THE RESCAN FLAG.
TAKPOP: SOS T4,TAKLVL ;DECREMENT THE DEPTH COUNTER
MOVE T1,TAKJFN ;GET THE JFN OF THE TAKE FILE
MOVE T2,TAKPTR(T4) ;AND THE OLD FILE POINTER
SKIPE T4 ;RETURNING TO TTY COMMANDS?
SFPTR ;NO, THEN SET THE FILE POINTER
ERJMP DIE ;FAILED, GO LOSE
SKIPL T1,TAKSVC(T4) ;GET SAVED CHAR AND SEE IF WE SHOULD RESCAN
TXZA F,FR.RSN ;NO, CLEAR FLAG
TXO F,FR.RSN ;YES, SET IT
HRRZM T1,SAVCHR ;RESTORE THE CHARACTER
RET ;DONE
SUBTTL COMMAND PROCESSOR
;HERE WHEN A LINE OF INPUT HAS BEEN READ IN, TO HANDLE THE COMMANDS.
;COMMANDS ARE SINGLE LETTERS, FOLLOWED BY ARGUMENTS WHICH MAY BE
;OMITTED.
RUNCMD: TXZ F,FR.RSN ;NO CHARACTERS TO BE REREAD
SKIPL T1,@RUNBUF ;SEE IF A BUFFER IS READY TO READ
TDZA T1,T1 ;NO, CLEAR AC
HRLI T1,(POINT 7,) ;YES, MAKE A BYTE POINTER TO IT
MOVEM T1,RUNPTR ;SAVE THE BYTE POINTER
SKIPN TAKLVL ;DO COMMANDS IF READING FROM FILE
JUMPE T1,CPOPJ ;OR IF TTY LINE IS READY
NXTCMD: TXZ F,FR.NEG ;RESET NEGATE FLAG FOR NEW COMMAND
NXTCNG: CALL EATSPS ;EAT ANY LEADING SPACES
GETCHR ;THEN READ NEXT CHARACTER
CAIN C,12 ;IS THIS THE LINE FEED?
JRST RUNFIN ;YES, COMMAND LINE IS DONE
MOVSI T1,-CMDNUM ;NO, GET READY FOR LOOP
CMDSRC: HLRZ T2,CMDTAB(T1) ;GET NEXT COMMAND
CAME T2,C ;MATCH OUR LETTER?
AOBJN T1,CMDSRC ;NO, KEEP SEARCHING
JUMPL T1,CMDHAV ;GO IF FOUND IT
RESCAN ;PUT BACK THE CHARACTER
CALL JOBIN ;LOOK FOR A JOB NUMBER
JUMPGE T2,RUNBAD ;IF NOT THERE, THEN BAD COMMAND
SKIPA T2,[CMDJOB] ;SET UP ROUTINE TO CALL
CMDHAV: HRRZ T2,CMDTAB(T1) ;GET ADDRESS
CALL (T2) ;CALL ROUTINE FOR COMMAND
JRST RUNBAD ;IF BAD, GO TYPE BELL
JRST NXTCMD ;LOOK FOR NEXT COMMAND
JRST NXTCNG ;FOR "N" COMMAND, GO BACK DIFFERENTLY
;HERE WHEN DONE WITH A COMMAND. IF WE WERE READING FROM AN
;INDIRECT COMMAND, WE POP UP TO THE NEXT HIGHER COMMAND LEVEL. IF
;WE WERE READING FROM THE TTY, WE HAVE TO ADVANCE THE BUFFER.
RUNBAD: CALL CHRALT ;BAD INPUT, RING THE BELL
RUNFIN: SKIPE TAKLVL ;WERE WE READING FROM A COMMAND FILE?
JRST TAKCDN ;YES, GO POP UP A LEVEL
HRRZS @RUNBUF ;MAKE BUFFER AVAILABLE TO INTERRUPT CODE
AOS T1,RUNBUF ;ADVANCE TO NEXT BUFFER
CAILE T1,BUFFS+BUFNUM-1 ;WENT OFF OF END?
MOVEI T1,BUFFS ;YES, RESET TO TOP
MOVEM T1,RUNBUF ;SAVE NEW POINTER
JRST RUNCMD ;SEE IF ANOTHER COMMAND IS READY
TAKCDN: CALL TAKPOP ;POP BACK TO OLD LEVEL
SKIPE RUNPTR ;WERE WE READING TTY COMMANDS?
JRST NXTCMD ;YES, GO CONTINUE DOING THAT
JRST RUNCMD ;NO, THEN SEE IF HAVE ANY NOW
;COMMAND TABLE. CHARACTERS ARE IN LEFT HALF, ADDRESSES OF ROUTINES
;ARE IN RIGHT HALF.
CMDTAB: XWD ",",CPOPJ1 ;COMMA, GOOD RETURN
XWD "T",CMDT ;SHOW TITLES OR DO TTY DISPLAY
XWD "G",CMDGET ;GET COMMANDS FROM SPECIFIED OPTION
XWD "C",CMDCOL ;COLUMN FORMAT COMMAND
XWD "A",CMDA ;ADVANCE, ACTIVE, ARPANET COMMANDS
XWD "K",CMDK ;KILL OFF A JOB OR THE EXEC
XWD "B",CMDBLK ;SET NUMBER OF BLANKS BETWEEN COLUMNS
XWD "U",CMDUSR ;SHOW JOBS OF GIVEN USER
XWD "R",CMDREF ;REFRESH COMMAND
XWD "W",CMDSLP ;WAIT TIME COMMAND
XWD "L",CMDLIN ;SET NUMBER OF LINES OF OVERLAP
XWD "E",CMDE ;EXIT OR DO ENQ/DEQ STATUS
XWD "I",CMDI ;SET IDLE TIME OR SHOW IPCF DATA
XWD "N",CMDNEG ;NEGATE NEXT COMMAND
XWD "O",CMDOPR ;OPERATOR JOBS
XWD "D",CMDD ;DO DEFAULTS OR DECNET STATUS
XWD "H",CMDHLP ;HELP COMMAND
XWD "M",CMDMON ;DO MONITOR STATUS DISPLAY
XWD "J",CMDONE ;DO ALL JOBS DISPLAY
XWD "P",CMDP ;PUSH OR SHOW PARTICULAR PROGRAM
XWD "S",CMDS ;SKIP NUMBER OF JFNS OR FORKS
XWD "Q",CMDQUE ;SHOW THE QUEUES
CMDNUM==.-CMDTAB ;NUMBER OF COMMANDS
;ROUTINES TO HANDLE EACH COMMAND:
CMDT: GETCHR ;READ NEXT CHARACTER
CAIN C,"T" ;WANTS TTY DISPLAY?
JRST SETTTY ;YES, GO SET IT UP
RESCAN ;NO, RESTORE THE CHAR
TXNN F,FR.NEG ;WANT TO SHOW TITLE LINES?
TXZA F,FR.CMP ;NO, CLEAR FLAG
TXO F,FR.CMP ;YES, SET FLAG
SETOM HDRTYP ;CLEAR ANY KNOWN HEADER
RETSKP ;GOOD RETURN
CMDI: GETCHR ;GET NEXT CHARACTER
CAIE C,"P" ;IS IT A P?
JRST SHWIDL ;NO, GO DO IDLE COMMAND
MOVEI R,DPYIPC ;SET UP TO SHOW IPCF STUFF
NEWDPY: SETZM PAGE ;RESET TO FIRST PAGE
TXZ F,FR.END ;ACT LIKE MORE PAGES TO GO
CALL PAGSET ;RESET SCROLLING TIMER
SKIPN T1,HLPJFN ;ANY HELP FILE OPEN?
RETSKP ;NO, ALL DONE
CLOSF ;YES, CLOSE THE FILE
ERJMP .+1 ;IGNORE ERROR
SETZM HLPJFN ;CLEAR THE JFN
RETSKP ;DONE
SHWIDL: RESCAN ;REREAD THE CHARACTER
TXNN F,FR.NEG ;WANT OPPOSITE ACTION?
TDZA T1,T1 ;NO, CLEAR FOR DEFAULT CHECK
MOVEI T1,1 ;YES, SET FOR OTHER CHECK
MOVEM T1,MAXIDF ;SAVE THE FLAG
CALL DECINZ ;READ NUMBER OF MINUTES
SKIPL T2 ;NO ARGUMENT GIVEN?
MOVX T1,DFTIDL ;YES, THEN GET DEFAULT
MOVEM T1,MAXIDL ;SET VALUE
RETSKP ;GOOD RETURN
CMDSLP: CALL DECINZ ;READ NUMBER OF SECONDS TO WAIT
IMULI T1,^D1000 ;CONVERT TO MILLISECONDS
SKIPN T2 ;WAS ANY NUMBER TYPED AT ALL?
MOVEI T1,DFTSLP ;NO, THEN SUPPLY THE DEFAULT
MOVEM T1,SLPTIM ;SAVE SLEEP TIME
RETSKP ;GOOD RETURN
CMDLIN: CALL DECIN ;READ FOLLOWING NUMBER
SKIPL T2 ;ANY NUMBER TYPED?
MOVX T1,DFTLAP ;NO, SET UP DEFAULT OVERLAP
MOVEM T1,OVRLAP ;SET THE NEW OVERLAP
RETSKP ;GOOD RETURN
CMDE: GETCHR ;READ NEXT CHARACTER
CAIN C,"Q" ;WANT ENQ/DEQ STATUS?
JRST SETENQ ;YES, GO SET UP FOR THAT
CAIN C,"N" ;WANT TO ENABLE PRIVILEGES?
JRST ENABLE ;YES, GO DO IT
RESCAN ;REREAD THE CHARACTER
TTY$ $TTCLR ;CLEAR SCREEN AND HOME UP
HALTF ;EXIT NICELY
TXO F,FR.REF!FR.RFC ;SET TO REFRESH SCREEN
RETSKP ;AND SKIP RETURN
ENABLE: GETCHR ;READ NEXT CHARACTER
CAIE C,"!" ;BETTER BE EXCLAIMATION MARK
RET ;NO, ERROR
MOVEI T1,.FHSLF ;GET READY
RPCAP ;READ MY PRIVILEGES
TRNN T2,SC%WHL!SC%OPR ;CAN I DO PRIVILEGED STUFF?
RET ;NO, ERROR
MOVE T3,T2 ;YES, COPY THE PRIVILEGES OVER
EPCAP ;TURN ON ALL OUR PRIVILEGES
ERJMP CPOPJ ;FAILED SOMEHOW
TXNE F,FR.JSY ;COULD WE DO THE JSYS BEFORE?
RETSKP ;YES, GOOD RETURN
TTY$ $TTCLR ;ERASE THE SCREEN SO ERRORS CAN BE SEEN
CALL JSYTST ;TRY TO INSERT THE JSYS NOW
TXO F,FR.REF!FR.RFC ;REMEMBER TO REFRESH THE SCREEN
RETSKP ;GOOD RETURN
SETARP: GETCHR ;GET NEXT CHARACTER
SETZ T1, ;CLEAR IN CASE NO MATCH
CAIN C,"H" ;WANT HOSTS?
MOVEI T1,DPYARH ;YES
CAIN C,"C" ;WANTS CONNECTIONS?
MOVEI T1,DPYARC ;YES
JUMPE T1,CPOPJ ;FAIL IF NOT EITHER OF THEM
MOVE R,T1 ;SET UP DISPATCH
JRST NEWDPY ;GO FINISH
SETDEC: MOVEI R,DPYDEC ;SET TO DO DECNET DISPLAY
TXZA F,FR.ACT ;ALL LINKS TOO
SETENQ: MOVEI R,DPYENQ ;DO ENQ/DEQ DISPLAY
JRST NEWDPY ;GO FINISH
SETTTY: MOVEI R,DPYTTY ;DO THE TTY DISPLAY
TXZA F,FR.TAC ;SHOW ALL TERMINALS
SETSTR: MOVEI R,DPYDSK ;OR STRUCTURE DISPLAY
JRST NEWDPY ;GO SET IT UP
SETRES: SKIPA R,[DPYRES] ;DO RESOURCES DISPLAY
SETDEV: MOVEI R,DPYDEV ;DO DEVICE DISPLAY
JRST NEWDPY ;FINISH
CMDNEG: TXO F,FR.NEG ;SET THE NEGATE FLAG FOR NEXT COMMAND
AOS (P) ;DOUBLE SKIP RETURN
RETSKP ;DONE
CMDOPR: TXNE F,FR.NEG ;WANT OPERATOR JOBS SHOWN?
TXZA F,FR.OPR ;NO, CLEAR BIT
TXO F,FR.OPR ;YES, SET BIT
JRST NEWDPY ;RESET SCREEN
;COMMAND TO GET COMMANDS FROM THE INDIRECT FILE. COMMANDS ARE
;GOTTEN FROM THE STATEMENTS FOLLOWING THE SPECIFIED LABEL.
CMDGET: SKIPN TAKJFN ;SEE IF OUR COMMAND FILE IS OPEN
RET ;NO, THEN GIVE AN ERROR
CALL SIXIN ;GET WHAT LABEL TO LOOK FOR
TAKFIL: SKIPN T1 ;WAS THERE ONE?
MOVX T1,DFTLBL ;NO, USE THE DEFAULT
MOVEM T1,TAKLBL ;SAVE THE LABEL
CALL TAKPSH ;NEST TO NEXT LEVEL OF INDIRECTION
RET ;FAILED
LBLSRC: TXO F,FR.NOC ;DON'T CONVERT THE LABEL CHAR TO LF
GETCHR ;READ NEXT CHARACTER
CAIN C,12 ;END OF THE FILE?
JRST [TXZ F,FR.NOC ;YES, CLEAR SPECIAL FLAG
JRST TAKPOP] ;RETURN TO PREVIOUS LEVEL WITH ERROR
CAIE C,LBLCHR ;FOUND THE LABEL CHARACTER?
JRST LBLSRC ;NO, KEEP SEARCHING
CALL SIXIN ;READ THE LABEL NAME
CAME T1,TAKLBL ;THE ONE WE ARE LOOKING FOR?
JRST LBLSRC ;NO, LOOK FOR ANOTHER LABEL
TXZ F,FR.NOC ;CLEAR SPECIAL FLAG
RETSKP ;YES, RETURN TO GET COMMANDS FROM IT
;COMMAND TO KILL THE EXEC WE HAD PUSHED INTO, OR SOME JOB NUMBER. IF
;KILLING A JOB, THE COMMAND MUST END IN A "!" TO PREVENT ACCIDENTS.
CMDK: GETCHR ;READ NEXT CHARACTER
CAIE C,"E" ;WANTS THE EXEC TO DISAPPEAR?
JRST KILJOB ;NO, GO SEE ABOUT A JOB
SKIPN T1,HANDLE ;GET FORK HANDLE IF ANY
RETSKP ;NONE, SUCCEED
KFORK ;TRASH THE POOR EXEC
ERJMP CPOPJ ;FAILED
SETZM HANDLE ;OK, IT IS NO LONGER HERE
RETSKP ;GOOD RETURN
KILJOB: RESCAN ;RESTORE CHARACTER
CALL JOBIN ;READ JOB NUMBER IF ANY
MOVE T4,C ;REMEMBER IF TYPED "." OR NOT
GETCHR ;THEN GET TERMINATING CHAR
CAIE C,"!" ;COMMAND PROPERLY TYPED?
RET ;NO, ERROR
CAIN T4,"." ;WANT TO KILL MYSELF?
JRST KILSLF ;YES, DO DO IT
JUMPL T2,KILHVJ ;JUMP ON IF SUPPLIED A JOB NUMBER
CAIE R,DPYONE ;WANTS DEFAULT, LOOKING AT A JOB?
RET ;NO, THEN FAIL
MOVE T1,THEJOB ;YES, GET THE JOB NUMBER
KILHVJ: JUMPLE T1,CPOPJ ;CAN'T LOG OUT JOB 0
CAME T1,MYJOB ;MY OWN JOB?
CAMLE T1,HGHJOB ;OR ILLEGAL JOB?
RET ;YES, ERROR
LGOUT ;TRY TO LOG JOB OUT
ERJMP CPOPJ ;FAILED
RETSKP ;GOOD RETURN
KILSLF: TTY$ $TTCLR ;FIRST CLEAR THE SCREEN
SETO T1, ;WANT TO KILL THIS JOB
LGOUT ;GO AWAY
ERJMP .+1 ;FAILED
TXO F,FR.REF!FR.RFC ;SCREEN NEEDS REFRESHING NOW
RET ;AND ERROR RETURN
;HERE TO SELECT WHAT PART OF THE QUEUES ARE TO BE SHOWN.
CMDQUE: SETZB T3,T4 ;INITIALIZE FLAGS
CMDQLP: GETCHR ;READ NEXT CHARACTER
MOVSI T1,-QUENUM ;GET READY FOR SEARCH
HLRZ T2,QUETAB(T1) ;GET NEXT LETTER
CAME T2,C ;MATCH?
AOBJN T1,.-2 ;NO, KEEP SEARCHING
JUMPGE T1,CMDQDN ;JUMP IF NO MATCH
HRRZ T1,QUETAB(T1) ;GET ADDRESS OF INSTRUCTION
XCT (T1) ;SET SOME BITS
JRST CMDQLP ;LOOP FOR NEXT LETTER
CMDQDN: CAIL C,"A" ;SEE IF TERMINATED ON A LETTER
CAILE C,"Z" ;WELL?
SKIPA ;NO
RET ;YES, ERROR RETURN
RESCAN ;PUT BACK THE CHARACTER
SKIPN T4 ;SPECIFIED ANY QUEUES?
TXO T4,LIQALL ;NO, THEN DO ALL AS DEFAULT
MOVEM T4,QSRFL1 ;SET THE FLAG BITS
MOVEM T3,QSRFL2 ;IN BOTH LOCATIONS
MOVEI R,DPYQUE ;SET UP TO SHOW THE QUEUES
JRST NEWDPY ;GO FINISH
QUETAB: XWD "A",[TXO T4,LIQALL] ;ALL QUEUES
XWD "O",[TXO T4,LIQOUT] ;OUTPUT QUEUES
XWD "B",[TXO T4,LIQBAT] ;BATCH QUEUE
XWD "L",[TXO T4,LIQLPT] ;LINE PRINTER QUEUE
XWD "M",[TXO T4,LIQMNT] ;MOUNT REQUESTS
XWD "R",[TXO T4,LIQRET] ;RETRIEVAL REQUESTS
XWD "F",[TXO T3,LS.FST] ;WANTS FAST LISTING
XWD "D",[TXO T3,LS.ALL] ;WANTS DETAILED LISTING
QUENUM==.-QUETAB ;NUMBER OF COMMANDS
CMDREF: GETCHR ;READ FOLLOWING CHAR
CAIN C,"E" ;WANTS TO SEE AVAILABLE RESOURCES?
JRST SETRES ;YES
RESCAN ;NO, PUT BACK THE CHAR
CALL DECINZ ;INPUT A NUMBER
SKIPN T1 ;NONZERO VALUE GIVEN?
MOVX T1,DFTREF ;NO, THEN GET DEFAULT
SKIPL T2 ;WAS ONE INPUT?
TXOA F,FR.REF ;NO, THEN SET UP REFRESH
MOVEM T1,REFTIM ;YES, SAVE THE NUMBER
CPOPJ1: AOS (P) ;SET FOR SKIP RETURN
RET ;RETURN
CMDJOB: CAMLE T1,HGHJOB ;IS IT TOO LARGE?
RET ;NO, ERROR
MOVE T4,T1 ;SAVE A COPY
CAIE C,"-" ;FOLLOWED BY A DASH?
JRST CMDRAN ;NO, GO DO ONE JOB
MOVE T4,T1 ;YES, SAVE THIS ONE
GETCHR ;GOBBLE THE DASH
CALL JOBIN ;INPUT ANOTHER JOB NUMBER
JUMPGE T2,CPOPJ ;ERROR IF NONE THERE
CAMLE T1,HGHJOB ;SEE IF LEGAL AGAIN
RET ;NO, ERROR
CMDRAN: CAMGE T1,T4 ;SEE IF ORDER IS RIGHT
EXCH T1,T4 ;NO, SWITCH THEM THEN
SUB T1,T4 ;GET NUMBER OF JOBS DIFFERENCE
SUBI T4,1 ;BACK OFF A JOB
ADJBP T4,[POINT 1,BITS,0] ;GET A BYTE POINTER
TXNN F,FR.NEG ;ADDING JOBS?
TDZA T2,T2 ;YES, CLEAR AC
MOVEI T2,1 ;NO, SET AC NONZERO
IDPB T2,T4 ;DEPOSIT THE BIT
SOJGE T1,.-1 ;LOOP OVER REQUIRED NUMBER OF JOBS
RETSKP ;GOOD RETURN
CMDD: GETCHR ;GET THE NEXT CHARACTER
CAIN C,"N" ;WANTS TO SHOW DECNET STATUS?
JRST SETDEC ;YES, GO DO IT
CAIN C,"V" ;WANTS TO SHOW DEVICES
JRST SETDEV ;YES, GO DO IT
RESCAN ;NO, RESTORE THE CHAR
CALL DEFALT ;CALL ROUTINE TO DEFAULT EVERYTHING
RETSKP ;GOOD RETURN
;COMMAND TO SHOW OR REMOVE HELP DISPLAY. WE TRY TO PRESERVE THE STATE
;OF THE PREVIOUS DISPLAY, SO THAT GETTING HELP DOESN'T RIP YOU OFF.
CMDHLP: TXNE F,FR.NEG ;WANT TO SEE HELP TEXT?
JRST HLPNO ;NO, GO REMOVE IT
GETCHR ;READ NEXT CHAR
CAIE C,"C" ;WANTS HELP ON COLUMN COMMANDS?
JRST HLPNRM ;NO, GO DO NORMAL HELP
CALL DISNAM ;READ IN THE NAME OF THE DISPLAY
RET ;BAD INPUT
SUB T4,[1,,DISTAB+1] ;MAKE AOBJN POINTER OVER TYPES
MOVEM T4,COLHLC ;AND SAVE IT
MOVEI T1,HLPCOL ;GET SPECIAL HELP ROUTINE
MOVEM T1,HLPDSP ;REMEMBER IT
JRST HLPNRD ;AND FINISH UP
HLPNRM: RESCAN ;PUT BACK THE NEXT CHARACTER
SETZM HLPDSP ;SET NO SPECIAL HELP ROUTINE
HLPNRD: TXZ F,FR.END ;ACT LIKE MORE PAGES COMING
SETZ T1, ;GET A ZERO
EXCH T1,PAGE ;GET OLD PAGE COUNTER AND CLEAR IT
TLNE R,-1 ;ALREADY SET UP FOR HELP?
RETSKP ;YES, GOOD RETURN
MOVSI R,(R) ;NO, SAVE CURRENT ROUTINE
HRRI R,DPYHLP ;SET UP HELP MODE
MOVEM T1,OLDPAG ;SAVE IT FOR LATER RESTORATION
RETSKP ;AND SKIP RETURN
HLPNO: TLNN R,-1 ;WERE WE IN THE HELP DISPLAY?
RET ;NO, ERROR
HLRZ R,R ;YES, RESTORE OLD DISPLAY
MOVE T1,OLDPAG ;GET OLD PAGE VALUE
MOVEM T1,PAGE ;AND RESTORE IT
RETSKP ;GOOD RETURN
;COMMAND TO SET THE NUMBER OF BLANK SPACES BETWEEN COLUMNS IN A DISPLAY.
CMDBLK: CALL DISNAM ;READ IN A DISPLAY NAME
RET ;ERROR
GETCHR ;READ NEXT CHAR
CAIE C,"/" ;SECOND ARGUMENT FOLLOWING?
JRST DEFBLK ;NO, WANTS DEFAULT SEPARATION USED
CALL DECIN ;READ SEPARATION
CAIG T1,MAXSEP ;MAKE SURE NOT TOO LARGE
JUMPG T1,DEFBLL ;AND MAKE SURE POSITIVE
RET ;NO, ERROR
DEFBLK: RESCAN ;REREAD THE CHAR
SETZ T1, ;INDICATE TO USE DEFAULTS
DEFBLL: SKIPN T2,T1 ;GET SPECIFIED SEPARATION
HRRZ T2,(T4) ;WANTS DEFAULT, GET IT
MOVEM T2,COLSEP-DISTAB(T4) ;STORE NEW SEPARATION
AOBJN T4,DEFBLL ;LOOP FOR NECESSARY DISPLAYS
SETOM HDRTYP ;INVALIDATE ANY OLD HEADER
RETSKP ;GOOD RETURN
;USEFUL SUBROUTINE TO READ IN A DISPLAY NAME, AND RETURN AN AOBJN
;POINTER IN T4 WHICH POINTS TO THE SELECTED COLUMNS. SKIP RETURN
;IF SUCCESSFUL.
DISNAM: CALL CPYTXT ;COPY THE NAME OF THE DISPLAY
JUMPN T1,CPOPJ ;ERROR IF BUFFER OVERFLOWED
MOVE T4,[-DISNUM,,DISTAB+1] ;ASSUME WANT ALL COLUMNS SET
JUMPE T1,CPOPJ1 ;RETURN IF CORRECT
MOVEI T1,DISTAB ;GET ADDRESS OF THE TABLE
HRROI T2,TXTBUF ;AND POINTER TO USER'S STRING
TBLUK ;SEARCH FOR DISPLAY NAME
TXNN T2,TL%ABR+TL%EXM ;FIND A MATCH?
RET ;NO, FAIL
HRRO T4,T1 ;MAKE AOBJN POINTER TO PARTICULAR COLUMN
RETSKP ;AND GIVE GOOD RETURN
CMDONE: GETCHR ;GET FOLLOWING CHAR
CAIN C,"T" ;WANTS TO SPECIFY A TERMINAL?
JRST ONETTY ;YES, GO DO THAT
RESCAN ;NO, REREAD THE CHAR
CALL JOBINZ ;READ JOB NUMBER IF THERE
JUMPGE T2,CMDALL ;IF NONE, DO ALL JOBS
CAMLE T1,HGHJOB ;SEE IF LEGAL JOB NUMBER
RET ;NO, ERROR RETURN
MOVEM T1,THEJOB ;YES, SAVE NUMBER
SETZM THETTY ;AND CLEAR TERMINAL TO SHOW
MOVEI R,DPYONE ;GET ROUTINE TO DO
JRST NEWDPY ;GO FINISH
ONETTY: CALL OCTIN ;READ THE TTY NUMBER
JUMPGE T2,CPOPJ ;MUST HAVE ONE SPECIFIED
CAMLE T1,HGHTTY ;MAKE SURE IT IS LEGAL
RET ;NO, ERROR
ADDI T1,.TTDES ;TURN INTO TERMINAL DESIGNATOR
MOVEM T1,THETTY ;THEN SAVE IT
MOVEI R,DPYONE ;GET ROUTINE TO DO
JRST NEWDPY ;AND FINISH
CMDMON: SKIPA R,[DPYMON] ;SET UP ROUTINE
CMDALL: MOVEI R,DPYALL ;OR OTHER ROUTINE
JRST NEWDPY ;GO FINISH
CMDS: GETCHR ;READ FOLLOWING CHAR
MOVSI T1,-SDPNUM ;GET READY FOR SEARCH
HLRZ T2,CMDSDP(T1) ;GRAB NEXT COMMAND LETTER
CAME C,T2 ;FOUND MATCH?
AOBJN T1,.-2 ;NO, KEEP LOOKING
HRRZ T1,CMDSDP(T1) ;GET DISPATCH ADDRESS
JRST (T1) ;GO TO IT
CMDSDP: XWD "T",SETSTR ;SET UP STRUCTURE DISPLAY
XWD "J",CMDSKJ ;SKIP SOME JFNS
XWD "F",CMDSKF ;SKIP SOME FORKS
XWD "B",SETBIA ;SET BIAS CONTROL KNOB
XWD "+",SCRREL ;SCROLL AHEAD SOME PAGES
XWD "-",SCRREL ;SCROLL BACKWARDS SOME PAGES
XWD "I",SCRINT ;SET SCROLLING INTERVAL
XWD -1,SCRPHY ;IF NO MATCH, SCROLL TO PARTICULAR PAGE
SDPNUM==.-CMDSDP-1 ;NUMBER OF REAL COMMANDS
CMDSKF: CALL DECINZ ;READ ARGUMENT
MOVEM T1,SKPFRK ;SAVE NUMBER OF FORKS TO SKIP
RETSKP ;SKIP RETURN
CMDSKJ: CALL DECINZ ;READ ARGUMENT
MOVEM T1,SKPJFN ;SAVE NUMBER OF JFNS TO SKIP
RETSKP ;SKIP RETURN
SETBIA: CALL DECIN ;READ THE FOLLOWING NUMBER
JUMPGE T2,CPOPJ ;IF TYPED NONE, ERROR
GETCHR ;GET THE NEXT CHARACTER
CAIE C,"!" ;MUST BE EXCLAIMATION POINT
RET ;NO, ERROR
MOVE T4,T1 ;MOVE VALUE TO RIGHT AC
MOVEI T1,.SKSBC ;FUNCTION TO SET BIAS KNOB
MOVEI T2,T3 ;ADDRESS OF BLOCK
MOVEI T3,2 ;TWO ARGUMENTS
SKED% ;SET IT
ERJMP CPOPJ ;FAILED, GIVE ERROR
RETSKP ;GOOD RETURN
;HERE FOR THOSE VARIATIONS OF THE "S" COMMAND WHICH AFFECT SCROLLING.
;THE CURRENT SCREEN PAGE NUMBER CAN BE SET TO A PARTICULAR VALUE,
;OR CHANGED RELATIVE TO THE CURRENT PAGE.
SCRPHY: RESCAN ;REREAD LAST CHAR
CALL DECIN ;THEN GET PAGE NUMBER
SUBI T1,1 ;COMPENSATE FOR PAGE NUMBERING
JUMPL T2,SCRSAV ;IF ONE GIVEN, SET TO THAT PAGE
CALL PAGDO ;OTHERWISE JUST ADVANCE TO NEXT SCREEN
RETSKP ;GOOD RETURN
SCRREL: MOVE T4,C ;SAVE WHICH COMMAND THIS IS
CALL DECIN ;READ FOLLOWING NUMBER
SKIPL T2 ;WAS ONE TYPED?
MOVEI T1,1 ;NO, THEN DEFAULT TO ONE
CAIN T4,"-" ;WANTS TO BACK UP?
MOVN T1,T1 ;YES, NEGATE THE NUMBER
ADD T1,PAGE ;ADD CURRENT PAGE NUMBER IN
SCRSAV: SKIPGE T1 ;TRYING TO GO NEGATIVE?
SETZ T1, ;YES, TAME IT
MOVEM T1,PAGE ;SET NEW PAGE NUMBER
TXZ F,FR.END ;ACT LIKE MORE PAGES TO GO
CALL PAGSET ;RESET SCROLLING INTERVAL
RETSKP ;GOOD RETURN
SCRINT: CALL DECIN ;GET INTERVAL FOR SCROLLING
MOVEM T1,PAGINT ;SAVE IT
CALL PAGSET ;RESET PAGING TIMER
RETSKP ;GOOD RETURN
;COMMAND TO ADVANCE THE SINGLE-JOB DISPLAY TO THE NEXT SUITABLE
;JOB NUMBER. THESE ARE THE JOBS SHOWN ON THE NORMAL DISPLAY.
;ALSO USED TO DETERMINE WHETHER OR NOT TO SHOW ACTIVE LOGICAL
;LINK NODES.
CMDA: GETCHR ;READ NEXT CHARACTER
CAIN C,"N" ;WANTS TO SEE ARPANET STATUS?
JRST SETARP ;YES, GO DO THAT
RESCAN ;NO, PUT BACK CHARACTER
CAIE R,DPYONE ;CURRENTLY DOING ONE-JOB DISPLAY?
JRST CMDACT ;NO, GO CHECK FOR DECNET DISPLAY
MOVE J,THEJOB ;GET THE JOB WE WERE SHOWING
ADVSRC: ADDI J,1 ;MOVE TO NEXT JOB
CAMLE J,HGHJOB ;OFF OF END?
SETZ J, ;YES, START OVER
CAMN J,THEJOB ;WENT ALL THE WAY AROUND?
JRST NEWDPY ;YES, STAY WITH THIS JOB
CALL GETDAT ;READ INFORMATION ON THIS JOB
JRST ADVSRC ;NO SUCH JOB, CONTINUE LOOKING
CALL SUPPRS ;WANT TO SEE THIS JOB?
JRST ADVSRC ;NO, LOOK AT NEXT ONE
MOVEM J,THEJOB ;YES, SET NEW JOB TO WATCH
JRST NEWDPY ;RESET PAGING AND RETURN
CMDACT: SETZ T1, ;CLEAR
CAIN R,DPYDEC ;DECNET DISPLAY?
MOVX T1,FR.ACT ;YES, GET FLAG
CAIN R,DPYTTY ;TERMINAL DISPLAY?
MOVX T1,FR.TAC ;YES, GET DIFFERENT FLAG
JUMPE T1,CPOPJ ;FAIL IF NOT THEM
TXNN F,FR.NEG ;WANT TO SEE ACTIVE LINES ONLY?
TDOA F,T1 ;YES, SET THE FLAG
TDZ F,T1 ;NO, CLEAR THE FLAG
RETSKP ;GOOD RETURN
;COMMAND TO READ USER NAMES TO BE SHOWN EXCLUSIVELY.
CMDUSR: SETZM USRLST ;CLEAR LIST OF USERS TO SHOW
MOVEI T1,USERS ;GET FIRST FREE WORD
MOVEM T1,USRFRE ;AND SET IT
CMDUSL: AOS T1,USRFRE ;MOVE TO NEXT FREE WORD
MOVEI T2,USERS+USRSIZ-2 ;GET WORD NEAR END OF AREA
SUB T2,T1 ;PRODUCE NUMBER OF WORDS LEFT
JUMPLE T2,CPOPJ ;ERROR IF NO MORE ROOM
IMULI T2,5 ;MULTIPLY BY CHARS TO A WORD
CALL CPYTX1 ;STORE USER NAME IN SPACE GIVEN
JUMPN T1,CPOPJ ;IF OVERFLOW, ERROR
EXCH T2,USRFRE ;SAVE NEW FREE LOCATION AND GET OLD ONE
SOS T1,T2 ;BACK UP TO LINK WORD
EXCH T1,USRLST ;SET US AS FIRST NAME IN LIST
MOVEM T1,(T2) ;AND SET OLD FIRST NAME AFTER US
GETCHR ;READ NEXT CHARACTER
CAIN C,"/" ;MORE NAMES COMING UP?
JRST CMDUSL ;YES, READ ANOTHER ONE
RESCAN ;NO, PUT BACK THIS CHAR
TXNE F,FR.NEG ;THESE USERS NOT WANTED TO BE SHOWN?
HRROS USRLST ;YES, SET HEADER WORD NEGATIVE
JRST NEWDPY ;RESET SCREEN SO USER ISN'T CONFUSED
;HERE TO EITHER REMOVE A COLUMN OF OUTPUT, OR TO ADD A COLUMN OF
;OUTPUT TO THE END OF THE DISPLAY.
CMDCOL: CALL CPYTXT ;COPY THE COLUMN NAME
RET ;HAS TO BE ONE
MOVEI T1,COLTAB ;GET ADDRESS OF COLUMN NAME TABLE
HRROI T2,TXTBUF ;AND POINTER TO USER'S STRING
TBLUK ;SEARCH FOR THE NAME
TXNN T2,TL%ABR+TL%EXM ;FIND A MATCH?
RET ;NO, ERROR
HRRZ T1,(T1) ;GET ADDRESS OF COLUMN DATA
AOS (P) ;GOOD RETURN NOW
TXNE F,FR.NEG ;WANT TO ADD THIS ENTRY?
JRST COLREM ;NO, GO REMOVE IT
MOVE T3,T1 ;SAVE COLUMN
MOVEI T1,-1 ;GET A LARGE NUMBER
GETCHR ;GET THE NEXT CHARACTER
CAIE C,"/" ;SECOND ARGUMENT COMING?
RESCAN ;NO, PUT BACK THE CHAR
CAIN C,"/" ;WELL?
CALL DECIN ;YES, READ THE ARGUMENT
MOVE T2,T1 ;PUT NUMBER IN RIGHT AC
MOVE T1,T3 ;AND COLUMN ADDRESS IN RIGHT AC
JRST COLADD ;GO ADD AT DESIRED COLUMN NUMBER
;HERE TO REMOVE A COLUMN FROM THE DISPLAY. ENTRY TO REMOVE IS IN
;AC T1, WHICH IS NOT CHANGED.
COLREM: SETOM HDRTYP ;HEADER ISN'T VALID ANYMORE
SETZ T2, ;SET UP FOR LOOP
COLREL: SKIPN T3,COLDSP(T2) ;RAN OUT OF COLUMNS?
RET ;YES, IT WAN'T THERE TO REMOVE
CAME T1,T3 ;IS THIS THE ONE TO REMOVE?
AOJA T2,COLREL ;NO, KEEP SEARCHING
COLRLL: MOVE T3,COLDSP+1(T2) ;GET NEXT WORD
MOVEM T3,COLDSP(T2) ;MOVE IT UP OVER OLD ONE
JUMPE T3,CPOPJ ;DONE WHEN MOVED THE NULL WORD
AOJA T2,COLRLL ;LOOP UNTIL DONE
;HERE TO ADD A COLUMN TO THE DISPLAY. ENTRY TO BE ADDED IS IN T1,
;AND COLUMN NUMBER TO INSERT IT AT IS IN T2.
COLADD: MOVEM T2,TEMP ;SAVE AWAY THE COLUMN NUMBER
CALL COLREM ;FIRST REMOVE THE ENTRY
MOVE T2,CL.TYP(T1) ;GET THE TYPE OF COLUMN THIS IS
SETZ T3, ;INITIALIZE INDEX
COLADS: SKIPN T4,COLDSP(T3) ;GET NEXT COLUMN
JRST COLADF ;NO MORE, INSERT AT END THEN
CAMN T2,CL.TYP(T4) ;WRONG COLUMN TYPE?
SOSLE TEMP ;OR NOT TO SPECIFIED COLUMN NUMBER?
AOJA T3,COLADS ;YES, KEEP SEARCHING
COLADF: EXCH T1,COLDSP(T3) ;PUT NEW ENTRY HERE AND GET OLD ENTRY
SKIPE T1 ;REACHED THE END?
AOJA T3,COLADF ;NO, KEEP SWITCHING THEM
SETZM COLDSP+1(T3) ;MAKE SURE NEXT ENTRY IS ZERO
RET ;DONE
CMDP: GETCHR ;READ THE NEXT CHARACTER
CAIE C,"R" ;COMMAND TO SHOW A PROGRAM?
JRST DOPUSH ;NO, GO PUSH TO ANOTHER EXEC
SETZM PRGNUM ;CLEAR NUMBER OF PROGRAM NAMES STORED
CMDPRL: MOVE T1,PRGNUM ;GET NUMBER OF PROGRAM NAMES STORED
CAILE T1,PRGMAX ;OVERFLOWED?
RET ;YES, ERROR RETURN
IMULI T1,2 ;MULTIPLY BY TWO WORDS PER PROGRAM NAME
ADDI T1,PRGWLD ;POINT TO STORAGE AREA
MOVEI T2,6 ;ALLOW SIX CHARACTERS
CALL CPYTX1 ;READ IN THE STRING
JUMPN T1,CPOPJ ;ERROR RETURN IF OVERFLOWED AREA
AOS PRGNUM ;INCREMENT NUMBER OF PROGRAM NAMES
GETCHR ;READ NEXT CHARACTER
CAIN C,"/" ;MORE NAMES COMING?
JRST CMDPRL ;YES, GET ANOTHER ONE
RESCAN ;NO, PUT BACK THE CHAR
TXNE F,FR.NEG ;DOES HE WANT THESE NAMES SUPPRESSED?
MOVNS PRGNUM ;YES, NEGATE THE NUMBER
JRST NEWDPY ;RESET SCREEN SO HE ISN'T CONFUSED
;COMMAND TO DO A PUSH TO A NEW EXEC. WHILE THE EXEC IS RUNNING,
;WE STILL COMPUTE THE CPU PERCENTAGES AND IDLE TIME. WHEN THE EXEC
;TERMINATES, WE REFRESH THE SCREEN AND RETURN. IF AN EXEC HAD
;PREVIOUSLY BEEN USED, WE JUST CONTINUE IT.
DOPUSH: RESCAN ;RESTORE UNWANTED CHARACTER
MOVEI T1,.FHSLF ;GET READY
MOVX T2,1B<TTYCHN> ;TO DISABLE TERMINAL INTERRUPT
DIC ;DO IT
CALL ECHOON ;TURN ON ECHOING NOW
SKIPE T1,HANDLE ;ALREADY HAVE AN EXEC AROUND?
JRST PSHCON ;YES, JUST CONTINUE IT
SETZ T4, ;REMEMBER NO JFN AND NO FORK YET
MOVX T1,CR%CAP ;GET READY TO CREATE ONE
CFORK ;MAKE AN INFERIOR FORK
ERJMP PSHFAI ;FAILED
HRLZ T4,T1 ;REMEMBER THE FORK HANDLE
MOVX T1,GJ%OLD+GJ%PHY+GJ%SHT ;GET FLAGS
HRROI T2,[ASCIZ/SYSTEM:EXEC.EXE/] ;AND FILE SPEC
GTJFN ;GET A JFN ON THE FILE
ERJMP PSHFAI ;FAILED
IORB T1,T4 ;COMBINE JFN AND HANDLE
GET ;READ EXEC INTO FORK
ERJMP PSHFAI ;FAILED
TRZ T4,-1 ;THE JFN NOW BELONGS TO THE INFERIOR
TTY$ $TTCLR ;CLEAR SCREEN AND HOME UP
TXO F,FR.REF!FR.RFC ;REMEMBER TO REFRESH SCREEN LATER
HLRZ T1,T4 ;GET HANDLE BACK
SETZ T2, ;NORMAL START ADDRESS
SFRKV ;START THE FORK
ERJMP PSHFAI ;FAILED
HLRZM T4,HANDLE ;OK, REMEMBER HANDLE FOR NEXT PUSH
JRST PSHCHK ;JOIN MAIN LOOP
PSHCON: TTY$ $TTCLR ;CLEAR SCREEN AND HOME UP
TXO F,FR.REF!FR.RFC ;REMEMBER TO REFRESH SCREEN LATER
TXO T1,SF%CON ;SET FLAG TO SAY CONTINUE FORK
SFORK ;CONTINUE IT
ERJMP PSHFIN ;FAILED, GIVE ERROR
JRST PSHCHK ;OK, GO TO MAIN LOOP
;NOW WAIT FOR THE EXEC TO FINISH UP:
PSHCHK: SETOM FRKFLG ;SAY NOT YET IN SLEEP
MOVEI T1,.FHSLF ;GET HANDLE
MOVX T2,1B<.ICIFT> ;THEN CHANNEL
AIC ;ACTIVATE FORK TERMINATION CHANNEL
PSHLOP: MOVEI T1,PSHSLP ;GET SLEEP TIME
AOSN FRKFLG ;SET FLAG AND CHECK IT
DISMS ;WAIT A LITTLE BIT IF NECESSARY
PSHINT: SETOM FRKFLG ;NO LONGER SLEEPING
GTAD ;READ TIME AND DATE
MOVEM T1,NTIME ;SAVE IT
CALL CPUCMP ;COMPUTE NEW CPU DATA
CALL CHKDRM ;AND COMPUTE NEW DORMANCY DATA
MOVE T1,HANDLE ;GET HANDLE
RFSTS ;GET STATUS
LDB T1,[POINT 17,T1,17] ;GET STATUS CODE
CAIN T1,.RFHLT ;DID IT HALT?
JRST PSHFIS ;YES, DONE
CAIE T1,.RFFPT ;FORCED HALT?
JRST PSHLOP ;NO, BACK TO LOOP
HRROI T1,[ASCIZ/
? EXEC terminated abnormally at PC /] ;GET STRING
PSOUT ;TYPE IT
MOVEI T1,.PRIOU ;TO TERMINAL
ANDI T2,-1 ;TRASH BITS
MOVEI T3,^D8 ;OCTAL
NOUT ;SAY WHAT THE PC IS
JFCL ;IGNORE ERROR
HRROI T2,[ASCIZ/ - /] ;GET STRING
SETZ T3, ;TERMINATE ON NULL
SOUT ;TYPE SEPARATOR
HRLO T2,HANDLE ;GET HANDLE, LAST ERROR
ERSTR ;SAY WHY THE EXEC DIED
JFCL ;CAN'T KNOW
JFCL ;EITHER ERROR
HRROI T2,[ASCIZ/
/] ;GET FINAL CRLF
SOUT ;TYPE IT
DOBE ;WAIT UNTIL DONE
MOVEI T1,^D5000 ;GET TIME
DISMS ;WAIT UNTIL HE CAN SEE IT
JRST PSHFIS ;AND RETURN
;HERE TO TERMINATE THE PUSH IF WE COULD NOT START IT UP:
PSHFAI: HRRZ T1,T4 ;GET POSSIBLE JFN WE CREATED
SKIPE T1 ;WAS THERE ONE?
RLJFN ;YES, RELEASE IT
ERJMP .+1 ;IGNORE ERROR
HLRZ T1,T4 ;GET POSSIBLE FORK HANDLE
SKIPE T1 ;WAS THERE ONE?
KFORK ;YES, RELEASE IT
ERJMP .+1 ;IGNORE FAILURE
JRST PSHFIN ;GO FINISH UP NOW
;HERE TO FINISH A PUSH WHEN THE EXEC HAS TERMINATED:
PSHFIS: AOS (P) ;SKIP RETURN
PSHFIN: MOVEI T1,.FHSLF ;MY FORK
MOVX T2,1B<.ICIFT> ;CHANNEL FOR TERMINATION
DIC ;DISABLE INTERRUPT
MOVE T1,MYNAME ;GET MY NAME
SETNM ;CHANGE BACK TO IT
CALL ECHOOF ;TURN ECHOING OFF AGAIN
MOVEI T1,.FHSLF ;GET READY
MOVX T2,1B<TTYCHN> ;TO REACTIVATE TERMINAL INTERRUPT
AIC ;DO IT
RET ;RETURN
SUBTTL SIMPLE INPUT ROUTINES
;OCTAL AND DECIMAL NUMBER INPUT ROUTINES. AC T2 IS NEGATIVE IF A
;NUMBER WAS FOUND, NONNEGATIVE OTHERWISE. AC T1 WILL BE ZERO IF
;NO NUMBER WAS FOUND. AC T3 IS UNCHANGED.
DECINZ: CALL EATSPS ;READ SPACES FIRST
DECIN: SETZB T1,T2 ;CLEAR AC'S
NUMINL: GETCHR ;READ NEXT CHARACTER
CAIL C,"0" ;VALID DIGIT?
CAILE C,"9" ;WELL?
JRST NUMHAV ;NO, GO FINISH UP
TLOE T2,400000 ;YES, SET FLAG TO SAY FOUND A NUMBER
IMULI T1,^D10 ;MAKE ROOM FOR NEXT DIGIT
ADDI T1,-"0"(C) ;ADD NEW DIGIT IN
JRST NUMINL ;LOOP OVER WHOLE NUMBER
NUMHAV: SKIPGE T1 ;SEE IF OVERFLOWED?
MOVX T1,.INFIN ;YES, THEN GET POSITIVE INFINITY
JRST REREAD ;GO REREAD LAST CHAR
OCTIN: SETZB T1,T2 ;CLEAR AC'S
OCTINL: GETCHR ;READ NEXT CHAR
CAIL C,"0" ;OCTAL DIGIT?
CAILE C,"7" ;WELL?
JRST NUMHAV ;NO, GO FINISH UP
TLOE T2,400000 ;SET FLAG SAYING HAVE NUMBER
LSH T1,3 ;SHIFT OVER A DIGIT
IORI T1,-"0"(C) ;ADD IN NEW ONE
JRST OCTINL ;LOOP
;ROUTINE TO INPUT A JOB NUMBER, WHICH COULD BE MY OWN DUE TO A PERIOD.
;RETURNS SAME AS DECINZ OR DECIN.
JOBINZ: CALL EATSPS ;EAT LEADING SPACES
JOBIN: CALL DECIN ;LOOK FOR A NUMBER
JUMPL T2,CPOPJ ;RETURN IF GOT ONE
CAIE C,"." ;NO, THEN SEE IF A PERIOD IS THERE
RET ;NO, RETURN
GETCHR ;YES, EAT THE PERIOD
MOVE T1,MYJOB ;GET MY JOB NUMBER
SETO T2, ;SAY WE HAVE A NUMBER
RET ;RETURN
;SIXBIT INPUT ROUTINE. ALPHANUMERICS ARE ALLOWED ONLY. RETURNS
;QUANTITY IN AC T1.
SIXIN: SETZ T1, ;CLEAR RESULT
MOVE T2,[POINT 6,T1] ;AND SET UP BYTE POINTER
SIXINL: GETCHR ;READ NEXT CHARACTER
CAIL C,"0" ;POSSIBLY ALPHANUMERIC?
CAILE C,"Z" ;WELL?
JRST REREAD ;NO, RESCAN THE CHAR AND RETURN
CAILE C,"9" ;WELL?
CAIL C,"A" ;IS IT?
SKIPA ;YES
JRST REREAD ;NO, RESCAN IT AND RETURN
TRNE T1,77 ;ROOM FOR ANOTHER CHARACTER?
JRST SIXINL ;NO, IGNORE THIS ONE
SUBI C," " ;CONVERT FROM ASCII TO SIXBIT
IDPB C,T2 ;STORE THE CHARACTER
JRST SIXINL ;AND LOOP
;ROUTINE TO SKIP OVER SPACES AND TABS:
EATSPS: GETCHR ;GET NEXT CHARACTER
CAIE C," " ;A SPACE?
CAIN C," " ;OR TAB?
JRST EATSPS ;YES, KEEP EATING
REREAD: RESCAN ;NO, SET TO RESCAN THIS CHAR
RET ;AND RETURN
SUBTTL SUBROUTINE TO READ COMMAND CHARACTERS
;CHARACTER INPUT ROUTINE. CHARACTERS ARE READ EITHER FROM AN
;INDIRECT FILE, OR FROM THE INPUT BUFFERS. THIS ROUTINE PROVIDES
;FOR THE RESCANNING OF A SINGLE CHARACTER. CHAR READ IS RETURNED
;IN AC C.
RUNCHR: MOVE C,SAVCHR ;GET OLD CHARACTER
TXZE F,FR.RSN ;WANT A NEW CHARACTER INSTEAD?
RET ;NO, RETURN THIS ONE
SKIPE TAKLVL ;READING FROM AN INDIRECT FILE?
JRST TAKCHR ;YES, HANDLE SPECIAL
ILDB C,RUNPTR ;NO, GET NEW CHAR FROM OUR BUFFER
CHRHAV: CAIN C,15 ;CARRIAGE RETURN?
JRST RUNCHR ;YES, IGNORE IT
JUMPE C,RUNCHR ;ALSO EAT NULLS
CAIL C,"A"+40 ;IS THIS A LOWER CASE CHAR?
CAILE C,"Z"+40 ;WELL?
SKIPA ;NO
SUBI C,40 ;YES, CONVERT TO UPPER CASE
MOVEM C,SAVCHR ;REMEMBER IN CASE HAVE TO REREAD IT
CAIN C,12 ;HAVE A LINE FEED?
RESCAN ;YES, MAKE SURE IT STAYS AROUND
RET ;RETURN
TAKCHR: PUSH P,T1 ;SAVE SOME AC'S
PUSH P,T2 ;THAT WE NEED
MOVE T1,TAKJFN ;GET JFN
BIN ;READ THE NEXT CHARACTER
ERJMP TAKERR ;FAILED, GO ANALYSE
CAIN T2,12 ;FOUND A LINE FEED IN FILE?
MOVEI T2," " ;YES, MAKE IT A SPACE
TXNN F,FR.NOC ;SEE IF WE SHOULD CONVERT THE CHAR
CAIE T2,LBLCHR ;IS THIS THE START OF A LABEL?
SKIPA C,T2 ;NO, MOVE CHAR TO RIGHT AC
TAKDON: MOVEI C,12 ;GET A LINEFEED TO SAY WE'RE DONE
POP P,T2 ;RESTORE AC'S
POP P,T1 ;THAT WERE USED
JRST CHRHAV ;GO FINISH CHARACTER HANDLING
TAKERR: MOVEI T1,.FHSLF ;GET SET
GETER ;FIND OUT WHY WE LOST
ANDI T2,-1 ;KEEP ONLY THE ERROR REASON
CAIN T2,IOX4 ;END OF FILE?
JRST TAKDON ;YES, GO RETURN A LINE FEED
JRST DIE ;NO, THEN LOSE
SUBTTL ROUTINE TO SET UP ALL DEFAULT PARAMETERS
;THIS ROUTINE IS CALLED AT SYSTEM STARTUP, OR BY THE "D" COMMAND.
;ALL THE PARAMETERS ARE SET TO THEIR INITIAL VALUE.
DEFALT: TXZ F,FR.TAC!FR.OPR!FR.CMP!FR.ACT ;RESET SOME FLAGS
SETZM SKPFRK ;CLEAR NUMBER OF FORKS TO SKIP
SETZM SKPJFN ;AND NUMBER OF JFNS TO SKIP
SETZM USRLST ;CLEAR LIST OF USERS TO SHOW
MOVX T1,LIQALL ;GET FLAGS FOR ALL QUEUES
MOVEM T1,QSRFL1 ;SET THEM
SETZM QSRFL2 ;CLEAR OTHER QUEUE FLAGS
MOVX T1,DFTPAG ;GET DEFAULT PAGE INTERVAL
MOVEM T1,PAGINT ;SET IT
CALL PAGSET ;AND RECOMPUTE SCROLLING TIME
MOVX T1,DFTLAP ;GET DEFAULT LINES TO OVERLAP
MOVEM T1,OVRLAP ;SET IT
MOVX T1,DFTSLP ;GET DEFAULT SLEEP TIME
MOVEM T1,SLPTIM ;SET IT
MOVX T1,DFTREF ;GET DEFAULT TIME BETWEEN REFRESHES
MOVEM T1,REFTIM ;SET IT
MOVX T1,DFTIDL ;GET DEFAULT IDLE TIME
MOVEM T1,MAXIDL ;AND SET IT
SETZM MAXIDF ;SET FLAG TO NORMAL CHECK
SETZM PRGNUM ;CLEAR ANY PROGRAM NAMES STORED
MOVE T1,[BITS,,BITS+1] ;GET READY
SETZM BITS ;CLEAR FIRST WORD OF BITS
BLT T1,BITS+<MAXJOB/^D36> ;THEN THE REST
JRST COLINI ;THEN GO INITIALIZE THE COLUMNS
SUBTTL SUBROUTINE TO SET UP HEADER AND TAB STOPS
;CALLED WITH THE HEADER TYPE IN T1, TO BUILD THE HEADER STRING AND
;SET THE PROPER TAB STOPS FOR FOLLOWING OUTPUT. STRING IS STORED
;IN LOCATION HDRTXT. IF FR.NDC IS SET, WE MAKE THE TITLE HAVE A CRLF
;FIRST, TO SEPARATE US FROM THE PREVIOUS OUTPUT.
HDRSET: TXZ F,FR.HDR ;CLEAR THE HEADER FLAG
CAMN T1,HDRTYP ;SEE IF ALREADY SET PROPER HEADER AND TABS
RET ;YES, JUST RETURN
MOVEM T1,HDRTYP ;NO, REMEMBER WHAT WE ARE BUILDING
MOVE T2,[COLTBS,,COLTBS+1] ;GET READY
SETZM COLTBS ;TO CLEAR TAB STOP WORDS
BLT T2,COLTBS+3 ;DO IT
MOVE T2,[POINT 7,HDRTXT] ;GET POINTER TO HEADER STORAGE
MOVEM T2,HDRPTR ;SAVE IT
MOVEI T2,12 ;GET CRLF READY
TXNE F,FR.NDC ;WANT A PRELIMINARY CRLF?
IDPB T2,HDRPTR ;YES, START STRING WITH ONE THEN
SETO T2, ;INITIALIZE COLUMN COUNTER
SETZM HDRPOS ;INITIALIZE COLUMN POSITION
HDRLOP: ADDI T2,1 ;MOVE TO NEXT HEADER
SKIPN T3,COLDSP(T2) ;ANY MORE COLUMNS TO LOOK AT?
JRST HDRDON ;NO, GO FINISH UP
HRRZ T4,CL.TYP(T3) ;GET TYPE
CAME T1,T4 ;THE TYPE WE WANT?
JRST HDRLOP ;NO, LOOK SOME MORE
MOVE T4,CL.SIZ(T3) ;GET WIDTH OF THIS COLUMN
ADD T4,COLSEP(T1) ;ADD IN SEPARATION BETWEEN COLUMNS
ADDB T4,HDRPOS ;ADD INTO TOTAL WIDTH SO FAR
CAIL T4,^D36*4-1 ;CHECK TO SEE IF TOO LARGE
SETZ T4, ;YES, MAKE NICER
ADJBP T4,[POINT 1,COLTBS,0] ;MAKE PROPER BYTE POINTER
MOVEM T4,TEMP ;SAVE AWAY
MOVEI T4,1 ;GET A BIT
DPB T4,TEMP ;SET THE TAB STOP
TXNE F,FR.CMP ;COMPRESSING HEADERS?
JRST HDRLOP ;YES, JUST GO TO NEXT COLUMN
MOVEI T4,11 ;GET A TAB
TXOE F,FR.HDR ;FIRST COLUMN?
IDPB T4,HDRPTR ;NO, THEN SEPARATE THE COLUMNS
ADDI T3,CL.TXT ;POINT TO THE TEXT STRING
CALL HDRSTR ;STORE IT AWAY
JRST HDRLOP ;AND LOOP
;HERE WHEN DONE PROCESSING ALL COLUMNS, TO FINISH UP.
HDRDON: MOVEI T3,[BYTE (7)12,12] ;GET A COUPLE OF END OF LINES
TXNN F,FR.CMP ;COMPRESSING OUTPUT?
CALL HDRSTR ;NO, STORE THESE
SETZ T1, ;GET A NULL
IDPB T1,HDRPTR ;MAKE STORED STRING ASCIZ
TAB$ COLTBS ;SET THE PROPER TAB STOPS
TXZ F,FR.HDR ;CLEAR THE HEADER BIT AGAIN
RET ;DONE
;LOCAL SUBROUTINE TO STORE AN ASCIZ STRING AWAY AS PART OF THE HEADER.
;ADDRESS OF STRING IS IN T3.
HDRSTR: HRLI T3,(POINT 7,) ;MAKE A BYTE POINTER
HDRSTL: ILDB T4,T3 ;GET NEXT CHARACTER
JUMPE T4,CPOPJ ;DONE WHEN GET A NULL
IDPB T4,HDRPTR ;STORE THIS CHAR
JRST HDRSTL ;LOOP FOR NEXT CHAR
SUBTTL SUBROUTINE TO OUTPUT ALL COLUMNS OF A LINE
;CALLED TO LOOP OVER ALL COLUMNS FOR THE CURRENT OUTPUT, CALLING
;THE VARIOUS SUBROUTINES TO OUTPUT THINGS. IT IS ASSUMED THAT
;THE HDRSET ROUTINE WAS PREVIOUSLY CALLED. RETURNS WHEN ALL
;COLUMNS HAVE BEEN PRINTED. CRLF IS TYPED WHEN THE LINE IS DONE.
DOCOLS: CALL HEADER ;TYPE HEADER IF NECESSARY
TXZE F,FR.EAT ;EATING NEEDED?
CALL SETEAT ;YES, GO SET IT UP
SKIPLE @DPYTAB+$DPEAT ;STILL EATING LINES?
JRST DOCRLF ;YES, DON'T DO ANY WORK YET THEN
SETOM NXTCOL ;INITIALIZE NEXT COLUMN FOR LOOP
DOCOLL: MOVE T1,NXTCOL ;GET THE OLD NEXT COLUMN
MOVEM T1,CURCOL ;SET AS THE CURRENT COLUMN
DOCOLF: AOS T1,NXTCOL ;GET NEXT COLUMN
SKIPN T1,COLDSP(T1) ;OUT OF COLUMNS?
JRST COLNOM ;YES, GO CLEAR FLAG
HRRZ T2,CL.TYP(T1) ;GET THE TYPE OF COLUMN
CAME T2,HDRTYP ;SAME TYPE AS THE HEADER IS SET UP FOR?
JRST DOCOLF ;NO, KEEP SEARCHING
TXOA F,FR.MOR ;THERE ARE MORE COLUMNS
COLNOM: TXZ F,FR.MOR ;NO MORE COLUMNS COMING
SKIPGE T1,CURCOL ;GET CURRENT COLUMN TO SHOW
JRST CHKMOR ;ISN'T ONE, GO LOOK SOME MORE
MOVE T1,COLDSP(T1) ;GET ADDRESS OF DATA BLOCK
CALL @CL.DSP(T1) ;PRINT DATA FOR THIS COLUMN
TAB ;APPEND A TAB AFTER THE COLUMN
CHKMOR: TXNN F,FR.MOR ;ANY MORE COLUMNS COMING?
JRST DOCRLF ;NO, END LINE WITH A CRLF
JRST DOCOLL ;YES, GO DO NEXT COLUMN
SUBTTL SUBROUTINE TO SCROLL THE SCREEN IF NECESSARY
;CALLED AFTER A SCREEN HAS BEEN OUTPUT, TO SEE IF THE NEXT SCREEN
;SHOULD BE SCROLLED OR NOT, AND TO DO IT IF NECESSARY. CALL AT
;PAGSET TO JUST SET UP THE NEXT SCROLLING TIME.
PAGCHK: MOVE T1,NTIME ;GET CURRENT TIME
CAMGE T1,PAGTIM ;IS IT TIME TO SCROLL SCREEN?
RET ;NO, RETURN
PAGDO: TXZN F,FR.END ;DID PREVIOUS SCREEN END THE DISPLAY?
AOSA PAGE ;NO, MOVE TO NEXT PAGE
SETZM PAGE ;YES, RESET TO FIRST PAGE
PAGSET: MOVE T1,PAGINT ;GET INTERVAL BETWEEN SCROLLS
MUL T1,[1,,0] ;CONVERT FROM SECONDS
DIVI T1,^D<60*60*24> ;TO UNIVERSAL TIME
ADD T1,NTIME ;COMPUTE TIME FROM NOW
SKIPN PAGINT ;ANY INTERVAL AT ALL?
MOVX T1,.INFIN ;NOPE, SET SO WILL NEVER SCROLL
MOVEM T1,PAGTIM ;REMEMBER TIME OF NEXT SCROLLING
RET ;DONE
SUBTTL SUBROUTINE TO SET UP INITIAL COLUMNS
;HERE TO BUILD THE LIST OF DEFAULT COLUMNS FOR OUTPUT. THE
;ORDER OF COLUMNS DEPENDS ON THE VALUE DEFINED FOR THAT COLUMN
;IN THE COLS MACRO. LOWER NUMBERED COLUMNS WILL APPEAR BEFORE
;HIGHER NUMBERED COLUMNS. COLUMNS WITH A ZERO NUMBER WILL NOT
;BE INSERTED AT ALL.
COLINI: SETOM HDRTYP ;HEADER IS UNKNOWN AFTER THIS
MOVEI T1,DISNUM ;GET READY FOR LOOP
HRRZ T2,DISTAB(T1) ;GET DEFAULT SEPARATION BETWEEN COLUMNS
MOVEM T2,COLSEP(T1) ;INITIALIZE VALUE FOR THIS DISPLAY
SOJG T1,.-2 ;LOOP OVER ALL DISPLAYS
SETZM COLDSP ;CLEAR OUR CURRENT COLUMNS
SETZM ORDVAL ;INITIALIZE LOOP
COLINL: AOS T1,ORDVAL ;MOVE TO NEXT VALUE
MOVEM T1,ORDMIN ;SET AS THE MINIMUM ALLOWABLE VALUE
HRLOI T1,377777 ;GET INFINITY
MOVEM T1,ORDVAL ;SET AS INITIAL VALUE
SETZM ORDHAV ;CLEAR COLUMN WHICH IS PICKED
MOVEI T1,COLNUM+2 ;GET HIGHEST COLUMN+1
MOVEM T1,ORDIDX ;INITIALIZE INDEX
COLINS: SOSG T1,ORDIDX ;GET NEXT POSSIBLE COLUMN
JRST COLINH ;NO MORE, GO PROCESS SELECTED COLUMN
HRRZ T1,COLTAB(T1) ;GET ADDRESS OF THIS COLUMN
MOVE T2,CL.VAL(T1) ;THEN GET THE VALUE FOR THIS COLUMN
CAML T2,ORDMIN ;AT LEAST AS LARGE AS OUR MINIMUM?
CAML T2,ORDVAL ;AND LESS THAN PREVIOUS SMALLEST?
JRST COLINS ;NO, KEEP LOOKING
MOVEM T2,ORDVAL ;YES, SAVE THIS VALUE
MOVEM T1,ORDHAV ;AND THE ADDRESS
JRST COLINS ;LOOK FOR A BETTER COLUMN
COLINH: SKIPN T1,ORDHAV ;SEE IF FOUND A COLUMN
RET ;NO, ALL COLUMNS ARE DONE
MOVEI T2,-1 ;INDICATE COLUMN GOES AT END
CALL COLADD ;ADD THIS COLUMN TO ONES BEING SHOWN
JRST COLINL ;LOOP AGAIN
SUBTTL SUBROUTINE TO INITIALIZE RUNTIME TABLES
;HERE AT START OF PROGRAM, TO SET THE INITIAL RUNTIME VARIABLES
;FOR ALL THE JOBS.
TBLINI: MOVEI I,CPUAVG-1 ;SET INITIAL VALUE
GTAD ;READ TIME OF DAY
MOVEM T1,OTIME ;SET OLD TIME OF DAY
MOVEM T1,NTIME ;AND NEW TIME OF DAY
MOVEI T2,CPUAVG-1 ;GET READY FOR LOOP
MOVEM T1,TIMES(T2) ;SAVE TIMES THAT TABLES WERE MADE
SOJGE T2,.-1 ;LOOP OVER ALL TABLES
MOVNM T1,TIMRUN ;SAVE NEGATIVE TIME IN TIME TABLE
MOVE T1,[TIMRUN,,TIMRUN+1] ;GET SET
BLT T1,TIMRUN+MAXJOB-1 ;STORE TIMES IN ALL WORDS
MOVE T1,[BITS,,BITS+1] ;GET READY
SETZM BITS ;CLEAR FIRST WORD OF BITS
BLT T1,BITS+<MAXJOB/^D36> ;AND THE REST ALSO
MOVE J,HGHJOB ;START WITH HIGHEST JOB
TBLINL: MOVSI T1,(J) ;GET READY
IORI T1,.JOBRT ;TO READ JOB'S RUN TIME
GETAB ;READ IT
ERJMP DIE ;FAILED
SKIPGE T1 ;JOB EXIST?
SETZ T1, ;NO, THEN SET RUNTIME TO ZERO
MOVEM T1,CURRUN(J) ;SAVE AS CURRENT RUNTIME
MOVEI T2,CPUAVG-1 ;GET READY
MOVEM T1,@OLDRUN(T2) ;SAVE IN OTHER TABLES ALSO
SOJGE T2,.-1 ;LOOP OVER THEM ALL
SOJGE J,TBLINL ;LOOP OVER ALL JOBS
RET ;RETURN
SUBTTL SUBROUTINE TO RECALCULATE PERCENTAGES OF CPU TIME
;HERE TO TAKE THE TABLES OF RUNTIM AND ORUNTM, AND TO COMPUTE THE
;PERCENTAGE OF ALL JOB'S CPU TIME, AND STORE THEM BACK INTO THE
;TABLE RUNDIF. CALLED OCCASSIONALLY.
CPUCMP: MOVE T1,NTIME ;GET CURRENT TIME
SUB T1,OTIME ;SEE HOW LONG SINCE LAST CALCULATION
CAIGE T1,<<CPUINT_^D18>/^D<24*60*60>> ;TIME TO GET NEW DATA?
RET ;NO, JUST RETURN
SOJGE I,CPUCMI ;DECREMENT TO NEXT TABLE
MOVEI I,CPUAVG-1 ;TIME TO RESET TO TOP
TXO F,FR.CPR ;SET THAT THE DATA IS READY
CPUCMI: MOVE J,HGHJOB ;GET HIGHEST POSSIBLE JOB
CPUCML: MOVE T1,CURRUN(J) ;GET LATEST RUNTIME OF JOB
SUB T1,@OLDRUN(I) ;SUBTRACT RUNTIME FROM BEFORE
SKIPGE T1 ;IS IT REASONABLE?
SETZ T1, ;NO, CLEAR IT
MOVEM T1,RUNDIF(J) ;SAVE FOR OUTPUT LATER
SOJGE J,CPUCML ;LOOP OVER ALL JOBS
HRRZ T1,OLDRUN(I) ;GET ADDRESS OF PROPER TABLE
HRLI T1,CURRUN ;AND ADDRESS OF CURRENT RUNTIMES
MOVE T2,T1 ;COPY ADDRESS
BLT T1,MAXJOB-1(T2) ;SET NEW RUNTIMES FOR TABLE
MOVE T1,NTIME ;GET CURRENT TIME AGAIN
MOVEM T1,OTIME ;SAVE AS OLD TIME
MOVE T2,TIMES(I) ;GET TIME THAT CURRENT DATA WAS MADE
MOVEM T1,TIMES(I) ;SET CURRENT TIME FOR NEW DATA
SUB T1,T2 ;GET DIFFERENCE IN TIMES
MUL T1,[^D<1000*60*60*24>] ;CONVERT TO MILLISECONDS
ASHC T1,^D17 ;FROM UNIVERSAL FORMAT
MOVEM T1,TIMDIF ;SAVE DIFFERENCE
RET ;RETURN
SUBTTL ROUTINE TO UPDATE IDLE TIMES FOR ALL JOBS
;ROUTINE TO UPDATE THE IDLE TIMES FOR ALL JOBS.
;CALL AT UPDORM IF UPDATING A SINGLE JOB.
CHKDRM: MOVE J,HGHJOB ;GET HIGHEST JOB
CHKDRL: MOVSI T1,(J) ;GET INDEX READY
IORI T1,.JOBRT ;AND RUNTIME TABLE
GETAB ;READ VALUE
ERJMP DIE ;FAILED
CALL UPDORM ;UPDATE DORMANCY FOR JOB
MOVEM T1,IDLE(J) ;SAVE THE RESULT
SOJGE J,CHKDRL ;LOOP OVER ALL JOBS
RET ;DONE
;HERE TO CHECK THE IDLE TIME OF A SINGLE JOB:
UPDORM: JUMPL T1,NOTJOB ;IF NOT A JOB, CLEAR STUFF
CAMN T1,CURRUN(J) ;SAME RUNTIME AS LAST TIME?
JRST GETIDL ;YES, SKIP ONWARD
MOVEM T1,CURRUN(J) ;NO, SAVE NEW RUNTIME
MOVE T1,NTIME ;GET CURRENT TIME
MOVEM T1,TIMRUN(J) ;AND SAVE AS TIME RUNTIME CHANGED
SETZ T1, ;IDLE TIME IS NOW ZERO
RET ;RETURN
GETIDL: MOVE T1,NTIME ;GET CURRENT TIME
MOVM T2,TIMRUN(J) ;AND ABSOLUTE VALUE OF TIME JOB LAST RAN
SUB T1,T2 ;GET THE DIFFERENCE
SKIPGE T1 ;SEE IF NEGATIVE
SETZ T1, ;YES??? THEN SET TO ZERO
MULI T1,^D<60*24> ;CONVERT UNIVERSAL TIME TO MINUTES
ASHC T1,^D17 ;BY MULTIPLYING BY CORRECT CONSTANT
RET ;AND RETURN
;HERE WHEN THE JOB IS NONEXISTANT, TO CLEAR THE TABLES FOR IT.
NOTJOB: SETZM CURRUN(J) ;CLEAR CURRENT RUNTIME
MOVEI T1,CPUAVG-1 ;GET SET FOR LOOP
SETZM @OLDRUN(T1) ;CLEAR ALL RUNTIME TABLES
SOJGE T1,.-1 ;KEEP LOOPING UNTIL DONE
MOVE T1,NTIME ;GET CURRENT TIME
MOVEM T1,TIMRUN(J) ;AND SET IN TIME TABLE
SETZ T1, ;GET A ZERO
MOVE T2,J ;GET COPY OF JOB
ADJBP T2,[POINT 1,BITS,0] ;GET BYTE POINTER TO RIGHT BIT
DPB T1,T2 ;LET JOB BE SEEN LATER
RET ;THEN RETURN
SUBTTL ROUTINE TO RETURN STATE OF A JOB
;CALLED WITH JOB NUMBER IN J, AND TERMINAL NUMBER IN T1, TO RETURN
;THE STATE OF A JOB AS AN ASCII STRING IN T1.
STATE: JUMPL T1,STATRN ;IF NOT ON A TERMINAL, ASSUME RUNNING
MOVSI T1,(T1) ;TERMINAL NUMBER IS INDEX
IORI T1,.TTYJO ;TABLE OF TERMINALS
GETAB ;READ DATA
ERJMP DIE ;FAILED
ANDI T1,-1 ;KEEP ONLY THE RIGHT HALF
CAIN T1,-1 ;IS ANY FORK IN JOB WAITING FOR TTY?
STATRN: SKIPA T1,[ASCIZ/ RUN/] ;NO, THEN STATE IS RUNNING
MOVE T1,[ASCIZ/ TI/] ;YES, THEN STATE IS TI
RET ;RETURN
SUBTTL ROUTINE TO TYPE STATUS OF A FORK
;CALLED WITH THE FORK STATUS WORD IN T1, TO TYPE OUT THE PROPER
;STATUS OF THE FORK.
FRKSTS: HLRZ T2,T1 ;GET CODE
ANDI T2,(RF%STS) ;KEEP ONLY THE CODE
CAILE T2,STSMAX ;LEGAL CODE?
IORI T2,-1 ;NO, SET TO UNKNOWN
TXNE T1,RF%FRZ ;WAS PROCESS FROZEN?
SKIPL STSTAB(T2) ;AND IN A STATE WHERE IT MAKES SENSE?
SKIPA ;NO
MOVEI T2,-2 ;YES, SAY WAS FROZEN
STR$ @STSTAB(T2) ;OUTPUT THE STATUS NOW
RET ;AND RETURN
STS 1,frozen
STS 1,unknown
STSTAB: STS 1,running
STS 1,IO wait
STS 0,halt
STS 0,error halt
STS 1,fork wait
STS 1,sleep
STS 0,JSYS trap
STS 0,addr break
STSMAX==.-STSTAB-1 ;HIGHEST KNOWN CODE
SUBTTL SUBROUTINE TO TYPE OUT THE RSCAN BUFFER
;CALLED TO TYPE THE RSCAN BUFFER FOR A JOB. THIS IS USUALLY THE
;LAST COMMAND PROCESSED WHICH RAN A PROGRAM.
TYPRSC: TXNN F,FR.JSY ;CAN WE DO THE MONRD% JSYS?
RET ;NO, TYPE NOTHING
STR$ [ASCIZ/RSCAN buffer: /] ;START THE OUTPUT
MOVE T1,['RSCNBP'] ;GET THE SYMBOL
CALL GETJS0 ;READ THE POINTER
JRST DOCRLF ;FAILED, JUST TYPE A CRLF
JUMPE T1,RSCNON ;NULL POINTER, SAY SO
MOVEI T2,^D20 ;ALLOW A LONG STRING
CALL TYPPTM ;TYPE IT OUT
JFCL ;DON'T CARE IT IT FAILS
JRST DOCRLF ;THEN FINISH WITH A CRLF
RSCNON: STR$ [ASCIZ/(none)
/] ;SAY THERE IS NONE
RET ;RETURN
SUBTTL SUBROUTINE TO TYPE OUT ASCIZ STRING FROM A JSB
;CALLED WITH AN ADDRESS INTO A JSB IN AC T1, TO READ AND OUTPUT THE
;ASCIZ STRING THAT THE POINTER IS POINTING TO. USED FOR OUTPUT OF
;FILE NAMES. SKIP RETURN IF SUCCESSFUL. CALL AT TYPPTM WITH LENGTH
;IN T2 IF STRING CAN BE LONGER THAN A NORMAL FILE SPEC.
TYPPTR: MOVEI T2,^D8 ;SET UP NORMAL SIZE LIMIT
TYPPTM: ANDI T1,-1 ;KEEP ONLY RIGHT HALF
JUMPE T1,CPOPJ1 ;IF NO POINTER, GOOD RETURN
SUB T1,JSVAR ;REMOVE JSB OFFSET
MOVEM T1,TXTPTR ;SAVE THE OFFSET
SETZM TXTCTR ;CLEAR COUNTER ALSO
SETZM TEMP(T2) ;CLEAR THE WORD AFTER THE MAXIMUM
MOVEM T2,TXTMAX ;SAVE THE MAXIMUM OFFSET
TYPPTL: MOVE T1,['JSVAR '] ;BASE ADDRESS OF WORD
AOS T2,TXTPTR ;INCREMENT TO NEXT WORD
CALL GETJSB ;READ THE WORD
RET ;FAILED
AOS T2,TXTCTR ;INCREMENT WORD COUNTER TOO
MOVEM T1,TEMP-1(T2) ;SAVE THIS WORD
CAML T2,TXTMAX ;MORE WORDS TO BE READ MAYBE?
JRST TYPPTT ;NO, GO TYPE RESULT
TXNE T1,177B34 ;SEE IF THIS WORD ENDS IN A NULL
TXNN T1,177B27 ;SOMPLACE IN THE WORD
JRST TYPPTT ;YES, TYPE RESULT
TXNE T1,177B20 ;KEEP LOOKING FOR A NULL
TXNN T1,177B13 ;WELL?
JRST TYPPTT ;FOUND IT, ALL DONE
TXNE T1,177B6 ;LAST CHECK
JRST TYPPTL ;WORD IS FULL, GET NEXT ONE
;NOW SEARCH THE STRING AND REPLACE ALL BAD CHARACTERS WITH NICE
;ONES SO THAT THE OUTPUT ISN'T MESSED UP BY STRANGE FILENAMES.
TYPPTT: MOVE T1,[POINT 7,TEMP] ;GET A BYTE POINTER
TYPPFL: ILDB T2,T1 ;GET NEXT CHARACTER
JUMPE T2,TYPPFO ;DONE WHEN HAVE A NULL
CAIL T2," " ;IS IT A CONTROL CHARACTER?
JRST TYPPFL ;NO, LEAVE IT ALONE
CAIE T2,15 ;CARRIAGE RETURN?
CAIN T2,12 ;OR LINE FEED?
SKIPA T2,[" "] ;YES, TURN THEM INTO HARMLESS SPACES
MOVEI T2,"?" ;OTHER CONTROL CHARS BECOME THIS
DPB T2,T1 ;STORE THE NEW CHARACTER
JRST TYPPFL ;LOOP UNTIL DONE
TYPPFO: STR$ TEMP ;OUTPUT THE STRING WE COLLECTED
RETSKP ;GOOD RETURN
SUBTTL ROUTINE TO OUTPUT AN ERROR STRING
;CALLED WITH AN ERROR CODE IN T1, TO CONVERT IT TO A STRING AND
;OUTPUT IT TO THE SCREEN. TO BE FAST, WE KEEP A TABLE OF THE MOST
;RECENT ERRORS WE KNOW ABOUT.
ERROUT: CAIN T1,LSTRX1 ;NO ERRORS ENCOUNTERED YET?
RET ;YES, TYPE NOTHING
TXNE F,FR.MOR ;ANY MORE COLUMNS?
JRST ERRJUS ;YES, JUST TYPE THE STRING
MOVEM T1,TEMP ;SAVE THE ERROR CODE
MOVEI T2,OCTSP6 ;ASSUME WANT OCTAL OUTPUT AT FIRST
CAIL T1,.ERBAS ;IN RANGE OF OUR TABLE?
CAILE T1,.ERBAS+MAXERR ;WELL?
JRST ERROCT ;NO, WE GUESSED RIGHT
SKIPN T1,ERRS-.ERBAS(T1) ;IS THERE A MNEMONIC THERE?
SKIPA T1,TEMP ;NO, RESTORE NUMBER
MOVEI T2,SIXRHT ;YES, GET ROUTINE FOR SIXBIT OUTPUT
ERROCT: CALL (T2) ;OUTPUT EITHER SIXBIT OR OCTAL
STR$ [ASCIZ/ - /] ;SPACE OVER SOME
MOVE T1,TEMP ;RESTORE CODE
ERRJUS: HRLZ T4,ERRCNT ;GET NUMBER OF ERRORS ALREADY STORED
JUMPE T4,NEWERR ;IF NONE, HAVE A NEW ERROR
MOVN T4,T4 ;TURN INTO AOBJN POINTER
MOVX T2,.INFIN ;INITIALIZE AGE FOR LOOP
ERRSRC: CAMN T1,ERRCOD(T4) ;IS THIS THE ERROR CODE WE WANT?
JRST HAVERR ;YES, JUST GO TYPE IT
CAMGE T2,ERRAGE(T4) ;IS THIS ERROR OLDER THAN PREVIOUS ONES?
JRST ERRSRN ;NO, GO TRY NEXT ERROR
MOVE T2,ERRAGE(T4) ;YES, GET ITS AGE
HRRZ T3,T4 ;AND REMEMBER WHICH ERROR THIS WAS
ERRSRN: AOBJN T4,ERRSRC ;LOOK AT ALL KNOWN ERRORS
CAIL T4,ERRNUM ;IS THE TABLE FULL?
SKIPA T4,T3 ;YES, THEN USE THE OLDEST SLOT
NEWERR: AOS ERRCNT ;INCREMENT NUMBER OF STORED ERRORS
MOVEM T1,ERRCOD(T4) ;REMEMBER THIS ERROR CODE FOR LATER
HRRZ T1,T4 ;GET READY
IMULI T1,ERRSIZ ;MAKE OFFSET INTO ERROR STRINGS
ADD T1,[POINT 7,ERRTAB] ;MAKE BYTE POINTER TO STORAGE
MOVE T2,ERRCOD(T4) ;GET ERROR CODE
HRLI T2,.FHSLF ;AND A VALID PROCESS HANDLE
MOVEI T3,ERRSIZ*5-1 ;SET UP MAXIMUM SIZE OF STRING
ERSTR ;CONVERT CODE TO STRING
JFCL ;FAILED
SKIPA T1,T4 ;FAILED, GET WHICH ENTRY WE FAILED ON
JRST HAVERR ;SUCCESSFUL, GO ON
IMULI T1,ERRSIZ ;MAKE OFFSET
SETZM ERRTAB(T1) ;ZERO THE STRING SINCE DON'T KNOW ERROR
;HERE WHEN WE HAVE FOUND THE ERROR CODE, TO TYPE THE STORED STRING:
HAVERR: AOS T1,ERRTOT ;INCREMENT AGE COUNTER
MOVEM T1,ERRAGE(T4) ;AND SET THIS ERROR AS BEING NEWEST
MOVE T1,T4 ;GET WHICH ENTRY THIS IS
IMULI T1,ERRSIZ ;MAKE OFFSET INTO THE BUFFER
SKIPN ERRTAB(T1) ;IS THIS AN UNKNOWN ERROR?
JRST UNKERR ;YES, GO SAY SO
PUSH P,ERRTAB+5(T1) ;SAVE A WORD OF THE STRING
TXNE F,FR.MOR ;ARE THERE MORE COLUMNS AFTER THIS ONE?
SETZM ERRTAB+5(T1) ;YES, RESTRICT SIZE OF MESSAGE
STR$ ERRTAB(T1) ;OUTPUT THE ERROR TEXT
POP P,ERRTAB+5(T1) ;RESTORE THE WORD OF THE TEXT
RET ;DONE
UNKERR: STR$ [ASCIZ/Unknown error /] ;SAY WE DON'T KNOW WHAT IT IS
TXNN F,FR.MOR ;MORE COLUMNS?
RET ;NO, THEN WE ALREADY GAVE THE NUMBER
MOVE T1,ERRCOD(T4) ;GET THE NUMBER
JRST OCTOUT ;OUTPUT IT
SUBTTL SUBROUTINE TO TYPE OUT A JSYS VALUE
;CALLED WITH AN MUUO IN AC T1, TO OUTPUT IT NICELY. IF IT IS A KNOWN
;JSYS, THE NAME WILL BE OUTPUT, OTHERWISE JUST JSYS NNN. IF IT
;IS A UUO, THE OPCODE WILL BE TYPED.
UUOOUT: HLRZ T2,T1 ;GET OPCODE AND STUFF
JUMPE T2,CPOPJ ;DONE IF NO INSTRUCTION
CAIE T2,(JSYS) ;IS THIS A JSYS?
JRST TYPUUO ;NO, TYPE OUT A UUO
CAMN T1,[MONRD%] ;IS IT OUR JSYS?
JRST OURJSY ;YES, TYPE SPECIAL
HRRZ T2,T1 ;GET THE JSYS NUMBER
CAIG T2,JSYSMX ;IS THIS A KNOWN JSYS?
SKIPN T1,JSTABL(T2) ;AND DOES IT HAVE A NAME?
SKIPA T1,T2 ;NO, HAVE TO OUTPUT AS JSYS NNN
JRST SIXOUT ;YES, GO OUTPUT IT
STR$ [ASCIZ/JSYS /] ;BEGIN OUTPUT
PJRST OCTOUT ;OUTPUT NUMBER
OURJSY: STR$ [ASCIZ/MONRD/] ;OUTPUT SPECIAL NAME
RET ;DONE
;HERE TO TYPE OUT A UUO. THIS IS NECESSARY FOR THOSE PROGRAMS WHICH
;RUN UNDER THE COMPATABILITY PACKAGE.
TYPUUO: LDB T2,[POINT 9,T1,8] ;GET OPCODE
CAIN T2,047 ;IS THIS A CALLI?
JRST TYPCAL ;YES, HANDLE SPECIAL
CAIN T2,051 ;IS THIS A TTCALL?
JRST TYPTTC ;YES, HANDLE SPECIAL
CAILE T2,100 ;A NORMAL UUO?
JRST TYPOPC ;NO, TYPE OUT THE OPCODE
MOVE T1,UUOTAB-40(T2) ;YES, GET NAME
PJRST SIXOUT ;OUTPUT AND RETURN
TYPCAL: STR$ [ASCIZ/CALLI /] ;TYPE START OF TEXT
TRNE T1,400000 ;IS THIS A NEGATIVE CALLI?
TDOA T1,[-1,,200000] ;YES, EXTEND IT AND CLEAR PHYSICAL BIT
TDZA T1,[-1,,200000] ;NO, CLEAR LEFT HALF AND PHYSICAL BIT
CHI$ "-" ;IF NEGATIVE CALLI, TYPE MINUS SIGN
MOVM T1,T1 ;GET POSITIVE NUMBER
PJRST OCTOUT ;THEN OUTPUT THE NUMBER
TYPTTC: LDB T2,[POINT 4,T1,12] ;GET TTCALL TYPE
MOVE T1,TTCTAB(T2) ;GET NAME
PJRST SIXOUT ;OUTPUT IT
TYPOPC: STR$ [ASCIZ/OPCODE /] ;TYPE OPCODE TEXT
MOVE T1,T2 ;GET OPCODE
PJRST OCTOUT ;OUTPUT IT
SUBTTL SIMPLE DATA OUTPUT ROUTINES
;HERE WITH A TERMINAL NUMBER IN AC T1, TO OUTPUT THE PROPER THING,
;ONE OF NUMBER, OR "DET", OR NUMBER FOLLOWED BY CONTROLLING JOB.
;ASSUMES JOB INFORMATION IS READ INTO AREA AT BLK.
TTYOUT: JUMPL T1,TTYDET ;JUMP IF HE IS DETACHED
MOVEI T2," " ;GET A SPACE
CAMN T1,CTYNUM ;IS THIS THE CTY?
MOVEI T2,"*" ;YES, GET AN ASTERISK INSTEAD
CHI$ (T2) ;OUTPUT SPACE OR STAR
CALL OCTOUT ;OUTPUT NUMBER
SKIPGE T1,BLK+.JICPJ ;CONTROLLED ON A PTY?
RET ;NO, ALL DONE
CHI$ "J" ;YES, OUTPUT LETTER TO INDICATE IT
JRST DECOUT ;THEN PRINT THE JOB NUMBER
TTYDET: STR$ [ASCIZ/ Det/] ;GET DETACHED STRING
RET ;AND RETURN
;HERE WITH A USER NUMBER IN T1, TO OUTPUT THE USER NAME. IF ZERO,
;THE USER IS NOT LOGGED IN. AC T2 HAS THE NUMBER OF WORDS TO
;RESTRICT THE OUTPUT TO IF MORE COLUMNS FOLLOW.
USROUT: MOVE T3,T2 ;SAVE CUTOFF AMOUNT
SKIPN T2,T1 ;MOVE NUMBER INTO RIGHT AC
JRST USRNLI ;SKIP ON IF NOT LOGGED IN
CAMN T1,OPRUSR ;IS THIS THE OPERATOR'S NUMBER?
JRST USRIOP ;YES, SKIP THE JSYS THEN
HRROI T1,TEMP ;POINT TO TEMPORARY STORAGE
DIRST ;CONVERT NUMBER TO STRING
RET ;IF ERROR, RETURN NOW
JUMPLE T3,USRFUL ;OUTPUT WHOLE THING IF GIVEN ZERO
CAIL T3,TMPSIZ ;MAKE SURE NOT GIVEN JUNK
JRST USRFUL ;YES, ALLOW ALL OUTPUT THEN
TXNE F,FR.MOR ;MORE COLUMNS TO COME?
SETZM TEMP(T3) ;YES, RESTRICT LENGTH OF OUTPUT
USRFUL: STR$ TEMP ;OUTPUT THE STRING
RET ;AND RETURN
USRNLI: STR$ [ASCIZ/Not logged in/] ;OUTPUT THIS STRING
RET ;THEN RETURN
USRIOP: STR$ [ASCIZ/OPERATOR/] ;GIVE OPERATOR
RET ;AND RETURN
;HERE TO OUTPUT A PERCENTAGE IN THE FORM NN.NN, WHERE T1 HAS THE VALUE
;OF A NUMERATOR, AND T2 THE VALUE OF A DENOMINATOR.
CENOUT: MOVE T4,T2 ;SAVE THE DENOMINATOR
MULI T1,^D10000 ;MULTIPLY BY HUNDREDS OF A PERCENT
DIV T1,T4 ;THEN DIVIDE BY DENOMINATOR
ADD T2,T2 ;DOUBLE THE REMAINDER
CAMLE T2,T4 ;SHOULD WE ROUND UP?
ADDI T1,1 ;YES, ADD TO HUNDREDS OF A PERCENT
IDIVI T1,^D100 ;GET PERCENTAGE AND FRACTION
MOVE T4,T2 ;SAVE FRACTION
SKIPN T1 ;IS THERE A NUMBER THERE?
STR$ [ASCIZ/ /] ;NO, THEN TYPE SPACES
SKIPE T1 ;WELL?
CALL DECSP2 ;YES, OUTPUT IN A FIELD OF 3
CHI$ "." ;THEN OUTPUT A DOT
MOVE T1,T4 ;GET BACK FRACTIONAL PART
IDIVI T1,^D10 ;SPLIT INTO SEPARATE DIGITS
CHI$ "0"(T1) ;OUTPUT FIRST ONE
CHI$ "0"(T2) ;AND SECOND ONE
RET ;DONE
;HERE TO OUTPUT A HEADER LINE IF NECESSARY. THE TEXT HAD PREVIOUSLY BEEN
;STORED IN HDRTXT. THE HEADER HAS BEEN SET UP BY A PREVIOUS CALL TO
;THE HDRSET ROUTINE.
HEADER: TXON F,FR.HDR ;HAVE WE TYPED THE HEADER YET?
STR$ HDRTXT ;NO, DO SO NOW
TXO F,FR.NDC ;CRLF WILL BE NEEDED IN NEXT DISPLAY
RET ;DONE
SUBTTL SIMPLE OUTPUT SUBROUTINES
;THE FOLLOWING ROUTINES TAKE THEIR ARGUMENTS IN AC T1. THEY GIVE
;ALL THEIR OUTPUT TO THE DPY ROUTINES. THESE ROUTINES DO NOT USE
;JSYSES SO THAT THE PROGRAM CAN RUN AS FAST AS POSSIBLE.
TMHSPC: CAIGE T1,^D60 ;AY LEAST ONE HOUR?
STR$ [ASCIZ/ /] ;NO, SPACE OVER
TMHSPS: CAIGE T1,^D60 ;ONLY MINUTES TO OUTPUT?
JRST DECSP2 ;YES, GO DO IT
MOVEI T4,TIMTST ;GET READY
JRST TMHOUT ;JOIN OTHER CODE
TIMSPC: CAIGE T1,^D<60*60> ;AT LEAST ONE HOUR?
STR$ [ASCIZ/ /] ;NO, SPACE OVER
CAIGE T1,^D60 ;AT LEAST ONE MINUTE?
STR$ [ASCIZ/ /] ;NO, SPACE OVER MORE
;THEN FALL INTO TIME OUTPUT
TIMOUT: CAIGE T1,^D60 ;LESS THAN ONE MINUTE?
JRST DECSP2 ;YES, OUTPUT SIMPLY
MOVEI T4,TIMTST ;GET OUTPUT ROUTINE READY
IDIVI T1,^D<60*60> ;GET HOURS INTO T1 AND MINUTES IN T2
HRLI T4,(T2) ;SAVE MINUTES
CALL (T4) ;OUTPUT HOURS
HLRZ T1,T4 ;GET BACK MINUTES
TMHOUT: IDIVI T1,^D60 ;GET MINUTES IN T1 AND SECONDS IN T2
HRLI T4,(T2) ;SAVE SECONDS
CALL (T4) ;OUTPUT MINUTES
HLRZ T1,T4 ;GET BACK SECONDS
;AND FALL INTO OUTPUT ROUTINE
TIMYES: CHI$ ":" ;FIRST OUTPUT A COLON
IDIVI T1,^D10 ;SPLIT INTO TWO DIGITS
CHI$ "0"(T1) ;OUTPUT FIRST ONE
CHI$ "0"(T2) ;THEN SECOND ONE
RET ;AND RETURN
TIMTST: JUMPE T1,CPOPJ ;IF NOTHING THERE, RETURN
HRRI T4,TIMYES ;SOMETHING, SET UP OTHER ROUTINE
JRST DECSP2 ;AND GO INTO TWO DIGIT OUTPUT
DECSP6: CAIGE T1,^D100000 ;IS THIS A FIVE OR LESS DIGIT NUMBER?
SPACE ;YES, SPACE OVER
DECSP5: CAIGE T1,^D10000 ;IS THIS A FOUR OR LESS DIGIT NUMBER?
SPACE ;YES, SPACE OVER
DECSP4: CAIGE T1,^D1000 ;IS THIS A THREE OR LESS DIGIT NUMBER?
SPACE ;YES, TYPE A SPACE
DECSP3: CAIGE T1,^D100 ;IS THIS A TWO OR LESS DIGIT NUMBER?
SPACE ;YES, TYPE A SPACE
DECSP2: CAIGE T1,^D10 ;IS THIS ONE DIGIT NUMBER?
SPACE ;YES
JRST DECOUT ;JOIN DECOUT ROUTINE
OCTSP6: CAIGE T1,100000 ;FIVE OR LESS DIGITS?
SPACE ;YES, TYPE SPACE
OCTSP5: CAIGE T1,10000 ;FOUR OR LESS DIGITS?
SPACE ;YES, DO A SPACE
OCTSP4: CAIGE T1,1000 ;IS THIS A THREE OR LESS DIGIT NUMBER?
SPACE ;YES, TYPE A SPACE
OCTSP3: CAIGE T1,100 ;IS THIS TWO OR LESS DIGITS?
SPACE ;YES
OCTSP2: CAIGE T1,10 ;ONE DIGIT NUMBER?
SPACE ;YES
JRST OCTOUT ;JOIN OCTAL OUTPUT CODE
FIXOUT: IDIVI T1,^D10 ;SPLIT OFF TENTHS
EXCH T2,T4 ;GET ROUTINE TO CALL AND SAVE DIGIT
CALL (T2) ;OUTPUT THE INTEGRAL PART
CHI$ "." ;PRINT A DOT
CHI$ "0"(T4) ;THEN PRINT THE FRACTIONAL PART
RET ;DONE
INFOUT: CAME T1,[377777,,-1] ;INFINITE?
JRST DECOUT ;NO, TYPE THE NUMBER
STR$ [ASCIZ/+Inf/] ;YES, SAY SO
RET ;DONE
OCTTEL: CHI$ "#" ;SAY THIS IS AN OCTAL NUMBER
OCTOUT: SKIPA T3,[^D8] ;SET UP FOR OCTAL
DECOUT: MOVEI T3,^D10 ;SET UP FOR DECIMAL
JUMPGE T1,NUMOUT ;OUTPUT IF NONNEGATIVE
CHI$ "-" ;TYPE MINUS SIGN
MOVM T1,T1 ;MAKE POSITIVE
NUMOUT: IDIVI T1,(T3) ;GET A DIGIT
JUMPE T1,NUMFIN ;IF ZERO, FINISH UP
HRLM T2,(P) ;SAVE THIS DIGIT
CALL NUMOUT ;LOOP
HLRZ T2,(P) ;DONE, GET BACK DIGIT
NUMFIN: CHI$ "0"(T2) ;OUTPUT IT
CPOPJ: RET ;AND RETURN
OCTFUL: MOVEI T3,^D12 ;GET A COUNT
OCTFLL: SETZ T2, ;ZERO AC
ROTC T1,3 ;GET NEXT CHAR
CHI$ "0"(T2) ;OUTPUT IT
SOJG T3,OCTFLL ;LOOP UNTIL DONE
RET ;DONE
;SUBROUTINE TO OUTPUT A VALUE AS A SYMBOL PLUS OFFSET.
SYMOUT: CALL CVTSYM ;CONVERT TO SYMBOL AND OFFSETS
MOVEM T2,TEMP ;SAVE OFFSET FOR AWHILE
JUMPE T1,SYMOUN ;IF NO SYMBOL, JUST OUTPUT OCTAL
CALL R50OUT ;OUTPUT RADIX50 NAME
SKIPN TEMP ;ANY OFFSET?
RET ;NO, DONE
CHI$ "+" ;YES, TYPE PLUS SIGN
SYMOUN: MOVE T1,TEMP ;GET BACK OCTAL
PJRST OCTOUT ;OUTPUT IT AND RETURN
R50OTT: SKIPA T3,[PBOUT] ;SET UP INSTRUCTION
R50OUT: MOVE T3,[CHI$ (T1)] ;OR OTHER ONE
TLZ T1,740000 ;CLEAR JUNK IN HIGH ORDER BITS
R50OUL: IDIVI T1,50 ;GET A DIGIT
JUMPE T1,R50FIN ;IF ZERO, HAVE ALL DIGITS
HRLM T2,(P) ;MORE, SAVE THIS ONE
CALL R50OUL ;LOOP
HLRZ T2,(P) ;GET BACK A DIGIT
R50FIN: SETZ T1, ;START WITH A NULL
CAIL T2,1 ;IN RANGE OF A DIGIT?
CAILE T2,12 ;WELL?
SKIPA ;NO
MOVEI T1,"0"-1(T2) ;YES, GET ASCII CHAR
CAIL T2,13 ;IN RANGE OF A LETTER?
CAILE T2,44 ;WELL?
SKIPA ;NO
MOVEI T1,"A"-13(T2) ;YES, GET ASCII CHAR
CAIN T2,45 ;PERIOD?
MOVEI T1,"." ;YES
CAIN T2,46 ;DOLLAR SIGN?
MOVEI T1,"$" ;YES
CAIN T2,47 ;PERCENT SIGN?
MOVEI T1,"%" ;YES
XCT T3 ;OUTPUT THE CHAR
RET ;DONE
FLTOUT: MOVE T2,T1 ;MOVE TO RIGHT AC
HRROI T1,TEMP ;POINT TO STORAGE
MOVX T3,FL%ONE+FL%PNT+FL%OVL+2B23+2B29 ;GET BITS
FLOUT ;OUTPUT NUMBER
ERJMP CPOPJ ;FAILED
STR$ TEMP ;TYPE IT
RET ;DONE
VEROUT: MOVE T4,T1 ;SAVE ADDRESS OF VERSION
MOVE T1,.NDVER(T4) ;GET VERSION
CALL OCTOUT ;OUTPUT IT
CHI$ "." ;TYPE A DOT
MOVE T1,.NDECO(T4) ;GET ECO NUMBER
CALL OCTOUT ;OUTPUT IT TOO
CHI$ "." ;ANOTHER DOT
MOVE T1,.NDCST(T4) ;GET CUSTOMER LEVEL
JRST OCTOUT ;FINISH WITH IT
PCOUT: MOVE T4,T1 ;SAVE RIGHT HALF OF PC
HLRZ T1,T1 ;AND GET LEFT HALF
ANDI T1,7777 ;KEEP ONLY SECTION NUMBER
SKIPN T1 ;NONZERO SECTION?
STR$ [ASCIZ/ /] ;NO, SPACE OVER SOME
SKIPE T1 ;WELL?
CALL OCTSP4 ;YES, OUTPUT IT
MOVS T1,T4 ;GET RIGHT HALF PC READY
;FALL INTO OUTPUT CODE
OCTSIX: MOVEI T3,6 ;GET A COUNT
OCTSIL: SETZ T2, ;CLEAR NEXT AC
ROTC T1,3 ;SHIFT NEXT DIGIT IN
CHI$ "0"(T2) ;OUTPUT IT
SOJG T3,OCTSIL ;LOOP OVER ALL DIGITS
RET ;DONE
SIXRHT: TRNE T1,77 ;RIGHT JUSTIFIED YET?
JRST SIXOUT ;YES, OUTPUT IT
LSH T1,-6 ;NO, SHIFT OVER
JUMPN T1,SIXRHT ;LOOP UNTIL DONE
SIXOUT: SKIPA T4,[CHI$ (T1)] ;GET INSTRUCTION TO TYPE TO DPY
SIXOTT: MOVE T4,[PBOUT] ;OR INSTRUCTION TO TYPE TO TTY
MOVE T2,T1 ;MOVE WORD TO BETTER AC
SIXOUL: JUMPE T2,CPOPJ ;DONE IF GET A NULL
SETZ T3, ;CLEAR NEXT AC
ROTC T2,6 ;SHIFT IN NEXT CHARACTER
MOVEI T1," "(T3) ;CONVERT IT TO ASCII
XCT T4 ;OUTPUT IT
JRST SIXOUL ;LOOP UNTIL DONE
DOCRLF: CRLF ;TYPE THE CRLF
RET ;RETURN
SUBTTL ROUTINES TO NOECHO AND ECHO THE TERMINAL
;ROUTINES TO TURN OFF OR ON ECHOING FOR THE TERMINAL.
ECHOON: SKIPA T3,[TXO T2,TT%ECO] ;GET INSTRUCTION
ECHOOF: MOVE T3,[TXZ T2,TT%ECO] ;OR OTHER ONE
MOVEI T1,.PRIIN ;PRIMARY INPUT
RFMOD ;READ STATUS OF TERMINAL
XCT T3 ;TURN ON OR OFF ECHO BIT
SFMOD ;SET TERMINAL TO NEW STATUS
RET ;RETURN
SUBTTL SUBROUTINE TO DO RESCANNING OF COMMAND LINE
;CALLED AT START OF PROGRAM, TO RESCAN THE INPUT BUFFER AND SEE
;IF WE WERE PROPERLY STARTED. IF SO, THE REST OF THE BUFFER IS
;LEFT AS THE FIRST INPUT TO BE READ BY THE PROGRAM.
CMDINI: MOVEI T1,.RSINI ;GET FUNCTION
RSCAN ;MAKE THE RESCAN BUFFER AVAILABLE
ERJMP DIE ;FAILED
MOVEM T1,TEMP ;SAVE NUMBER OF CHARS AVAILABLE
MOVE T2,[POINT 6,MYNAME] ;GET A POINTER READY
MOVEI T3,6 ;WANT TO READ SIX CHARACTERS
NAMCHK: SOJL T3,CPOPJ ;IF FINISHED WITH NAME, ALL DONE
ILDB T4,T2 ;READ NEXT CHARACTER OF NAME
JUMPE T4,CPOPJ ;DONE IF NO MORE TO NAME
SOSGE TEMP ;DECREMENT COUNT OF CHARS LEFT
RET ;NO MORE, THEN NO COMMANDS TO RESCAN
PBIN ;READ NEXT CHARACTER
CAIL T1,"A"+40 ;LOWER CASE?
CAILE T1,"Z"+40 ;WELL?
SKIPA ;NO
SUBI T1,40 ;YES, MAKE UPPER CASE
CAIN T1," "(T4) ;MATCH HIS TYPEIN?
JRST NAMCHK ;YES, CONTINUE LOOKING
LINEAT: SOSGE TEMP ;BAD COMMAND, DECREMENT COUNT
RET ;ALL OF LINE DONE, RETURN
PBIN ;READ NEXT CHAR
JRST LINEAT ;LOOP UNTIL DONE
SUBTTL SUBROUTINES TO HANDLE EATING OF LINES
;THIS ROUTINE IS CALLED AFTER THE MAIN HEADER OF A DISPLAY IS TYPED
;OUT, TO TELL DPY HOW MANY LINES OF FOLLOWING OUTPUT ARE TO BE
;THROWN AWAY. THIS IS DONE TO IMPLEMENT SCROLLING OF THE SCREEN VERY
;EASILY. NUMBER OF SCREENFULLS TO EAT IS IN LOCATION PAGE.
SETEAT: LOC$ T1 ;READ CURRENT OUTPUT POSITION
JUMPL T1,CPOPJ ;IF ALREADY OVERFLOWED, IGNORE IT
HLRZ T1,T1 ;GET LINE NUMBER FOR NEXT OUTPUT
MOVE T2,@DPYTAB+$DPLEN ;GET SIZE OF TERMINAL
SUB T2,T1 ;COMPUTE LINES REMAINING
AOS T1,T2 ;ADJUST FOR ONE OFF EFFECT
SUB T1,OVRLAP ;DIDDLE BY AMOUNT OF DESIRED OVERLAP
IMUL T1,PAGE ;MULTIPLY BY PAGE NUMBER
SKIPGE T1 ;NEGATIVE?
SETZ T1, ;YES, RAISE TO ZERO
TLNE T1,-1 ;OVERFLOWED?
MOVEI T1,-1 ;YES, MAKE LARGEST VALUE
HRLI T1,$SEEAT ;SET UP FUNCTION CODE
SET$ T1 ;TELL DPY HOW MUCH TO IGNORE
RET ;DONE
;ROUTINE TO SEE IF THE SCREEN IS FULL. USED TO TERMINATE LISTING OF
;DATA WHEN IT WOULD NEVER SHOW TO THE SCREEN. SKIP RETURN IF SCREEN
;IS NOT YET FULL. USES AC T1.
FULL: LOC$ T1 ;READ CURRENT POSITION
JUMPGE T1,CPOPJ1 ;SKIP RETURN IF STILL MORE LINES LEFT
RET ;ALL FULL, ERROR RETURN
;ROUTINE TO SEE HOW MUCH ROOM IS LEFT ON THE CURRENT LINE. USED TO
;DETERMINE WHEN A CRLF IS NEEDED BEFORE FURTHER OUTPUT. COLUMNS LEFT
;IS RETURNED IN AC T1.
LEFT: LOC$ T1 ;READ CURRENT POSITION
ANDI T1,-1 ;ONLY KEEP THE COLUMN NUMBER
SUB T1,@DPYTAB+$DPWID ;SUBTRACT FROM SIZE OF LINE
MOVN T1,T1 ;GET POSITIVE NUMBER
RET ;DONE
SUBTTL ROUTINE WHICH CHECKS A PROGRAM NAME AGAINST A WILDCARD
;ROUTINE TO CHECK A JOB'S PROGRAM NAME AGAINST ONES SPECIFIED BY THE
;USER TO DECIDE IF THIS USER SHOULD BE SHOWN. CALLED WITH THE USER'S
;SIXBIT PROGRAM NAME IN T1. SKIP RETURN IF JOB IS SELECTED.
PRGCMP: SKIPN T4,PRGNUM ;ANY PROGRAM NAMES STORED?
RETSKP ;NO, THEN SHOW EVERYTHING
MOVM T4,T4 ;MAKE OFFSET POSITIVE ALWAYS
IMULI T4,2 ;THERE ARE TWO WORDS FOR EACH NAME
CALL SIXASC ;CONVERT THE SIXBIT NAME TO ASCIZ
HRROI T3,TEMP ;SET UP POINTER TO TEST NAME
PRCMPL: SUBI T4,2 ;BACK DOWN BY A PROGRAM NAME
JUMPL T4,PRGNO ;IF NEGATIVE, NO MORE TO CHECK
MOVS T1,PRGWLD(T4) ;GET FIRST WORD OF NAME
CAIN T1,(ASCII/*/) ;IS IT THE FULL WILDCARD?
JRST PRGYES ;YES, PROGRAM NAME MATCHES
MOVEI T1,.WLSTR ;GET FUNCTION FOR JSYS
HRROI T2,PRGWLD(T4) ;POINT AT WILD STRING
WILD% ;SEE IF WE HAVE A MATCH
ERJMP CPOPJ1 ;FAILED, SHOW THE JOB
TXNE T1,WL%NOM ;MATCHED?
JRST PRCMPL ;NO, KEEP CHECKING
PRGYES: TDZA T1,T1 ;MATCHED, GET ZERO
PRGNO: MOVEI T1,1 ;NO MATCH, GET NONZERO VALUE
SKIPG PRGNUM ;WANT THIS PROGRAM NAME?
XORI T1,1 ;NO, COMPLEMENT THE CHECK
JUMPE T1,CPOPJ1 ;SKIP IF WE SHOULD SHOW THE JOB
RET ;OTHERWISE NON-SKIP
SUBTTL ROUTINE WHICH CHECKS USER NAME AGAINST LIST
;ROUTINE TO CHECK A USER NAME AGAINST A LIST OF WILDCARD USER NAMES,
;AND DECIDE WHETHER OR NOT THIS USER IS DESIRED. CALLED WITH THE
;USER NUMBER IN T1. SKIP RETURN IF THIS USER IS SELECTED.
USRCMP: SKIPN USRLST ;IS ANY LIST SET UP?
RETSKP ;NO, THEN SHOW ALL JOBS
MOVEI T4,USRLST ;GET ADDRESS OF LIST OF STRINGS
JUMPE T1,NLICHK ;HANDLE NOT LOGGED IN JOBS SPECIALLY
MOVE T2,T1 ;MOVE DIRECTORY NUMBER
HRROI T1,TEMP ;POINT TO TEMPORARY STORAGE
DIRST ;CONVERT TO STRING
ERJMP CPOPJ1 ;FAILED, SHOW JOB ANYWAY
HRROI T3,TEMP ;POINT TO NAME STRING
USRCML: SKIPN T4,(T4) ;GET THE NEXT USER NAME TO CHECK
JRST NINLST ;NO MORE, HE IS NOT IN LIST
MOVS T1,1(T4) ;GET FIRST WORD OF NAME STRING
JUMPE T1,USRCML ;CHECK NEXT NAME IF THIS ONE IS NULL
CAIN T1,(ASCII/*/) ;WANTS ALL LOGGED IN JOBS?
JRST INLST ;YES, HE IS IN THE LIST
MOVEI T1,.WLSTR ;MUST DO JSYS, GET FUNCTION CODE
MOVE T2,T4 ;COPY ADDRESS OF WILD STRING
HRLI T2,(POINT 7,0,34) ;AND MAKE INTO BYTE POINTER
WILD% ;SEE IF THEY MATCH
ERJMP OLDCMP ;FAILURE, GO TRY OLD METHOD
TXNE T1,WL%NOM ;MATCH?
JRST USRCML ;NO, KEEP SEARCHING
INLST: TDZA T1,T1 ;IN THE LIST, GET ZERO READY
NINLST: MOVEI T1,1 ;NOT IN LIST, GET NONZERO
SKIPGE USRLST ;WANT TO COMPLEMENT THE CHECKS?
XORI T1,1 ;YES, DO SO
JUMPE T1,CPOPJ1 ;SKIP RETURN IF SHOULD SHOW THE JOB
RET ;OTHERWISE NON-SKIP
OLDCMP: MOVE T1,T3 ;GET POINTER TO USER NAME
STCMP ;COMPARE WITHOUT WILDCARDS
JUMPE T1,INLST ;FOUND A MATCH
JRST USRCML ;NO MATCH, TRY NEXT NAME
;HERE IF USER BEING CHECKED IS NOT LOGGED IN:
NLICHK: SKIPN T4,(T4) ;GET NEXT POSSIBLE NAME
JRST NINLST ;NO MORE, NOT IN LIST
SKIPN 1(T4) ;IS THE TEST STRING NULL?
JRST INLST ;YES, HE IS IN THE LIST
JRST NLICHK ;NO, KEEP SEARCHING
SUBTTL SUBROUTINE TO COPY TEXT INTO SEPARATE BUFFER
;ROUTINE TO COPY TEXT FROM THE COMMAND BUFFER TO THE TXTBUF BUFFER.
;BUFFER MUST BE AT LEAST TXTLEN WORDS IN LENGTH. ALL TEXT IS COPIED
;UNTIL THE FIRST SPACE, TAB, SLASH, COMMA, OR LINE FEED. CALL IS:
;
; CALL CPYTXT ;COPY STRING
; (ERROR RETURN) ;FAILED
; (GOOD RETURN) ;SUCCEEDED
;
;ON ERROR RETURN, T1 = 0 IF NO TEXT WAS GIVEN, OR NONZERO IF THE
;TEXT BUFFER WAS OVERFLOWED. ON GOOD RETURN, T1 CONTAINS THE
;FIRST WORD OF THE BUFFER, AND T2 CONTAINS FIRST FREE WORD.
;CALL AT CPYTX1 IF SIZE AND ADDRESS IS NOT THE NORMAL ONE.
CPYTXT: MOVEI T2,TXTLEN*5-1 ;SET UP SIZE OF AREA
MOVEI T1,TXTBUF ;POINT TO NORMAL TEXT BUFFER
CPYTX1: HRLI T1,(POINT 7,) ;MAKE A BYTE POINTER
HRRZ T3,T1 ;REMEMBER ADDRESS OF BUFFER
SETZM (T3) ;AND CLEAR FIRST WORD
CPYTXL: GETCHR ;READ NEXT CHARACTER
CAIN C,12 ;END OF LINE?
JRST CPYTXD ;YES, DONE
CAIE C," " ;SPACE?
CAIN C," " ;OR TAB?
JRST CPYTXD ;YES, DONE
CAIE C,"/" ;SLASH?
CAIN C,"," ;OR COMMA?
JRST CPYTXD ;YES, DONE
IDPB C,T1 ;STORE THIS CHAR
SOJGE T2,CPYTXL ;IF MORE ROOM, GET ANOTHER CHAR
RET ;OTHERWISE RETURN ERROR
CPYTXD: RESCAN ;REREAD TERMINATING CHARACTER
SETZ T2, ;GET A NULL
IDPB T2,T1 ;MAKE THE STRING ASCIZ
MOVEI T2,1(T1) ;REMEMBER FIRST FREE WORD
SKIPE T1,(T3) ;ANY TEXT STORED?
AOS (P) ;YES, GOOD RETURN
RET ;DONE
SUBTTL SUBROUTINE TO CONVERT SIXBIT WORD INTO ASCIZ
;CALLED WITH A SIXBIT QUANTITY IN AC1, TO STORE IN LOCATION TEMP AND
;TEMP+1 THE ASCIZ TEXT FOR THAT WORD. USES ALL TEMP AC'S.
;ON RETURN, AC T1 IS READY TO APPEND MORE CHARACTERS TO THE STRING.
SIXASC: SETZM TEMP ;CLEAR WORDS FIRST
SETZM TEMP+1 ;TO GUARANTEE A NULL EXISTS
MOVE T2,T1 ;MOVE WORD TO BETTER AC
MOVE T1,[POINT 7,TEMP] ;GET READY
SIXASL: JUMPE T2,CPOPJ ;DONE IF WORD IS ZERO
SETZ T3, ;CLEAR NEXT AC
ROTC T2,6 ;GET NEXT CHARACTER
ADDI T3," " ;CONVERT TO ASCII
IDPB T3,T1 ;STORE AWAY
JRST SIXASL ;LOOP UNTIL DONE
SUBTTL SUBROUTINE TO CONVERT OCTAL VALUE TO SYMBOLS
;CALLED WITH AN OCTAL VALUE IN AC T1, TO OBTAIN THE RADIX50 SYMBOL
;AND OFFSET FOR THE VALUE. THIS REQUIRES PRIVILEGES TO WORK.
;TO SAVE TIME, WE FIRST TRY TO FIND THE SYMBOL IN OUR OWN LOCAL
;SYMBOL TABLE. RETURNS SYMBOL IN T1 AND OFFSET IN T2.
CVTSYM: HRLZ T4,MONSYC ;GET CURRENT COUNT OF SYMBOLS
JUMPE T4,SYMSNP ;IF NONE, GO SNOOP
MOVN T4,T4 ;GET READY FOR A SEARCH
CAME T1,MONSYV(T4) ;FOUND THE VALUE IN TABLE?
AOBJN T4,.-1 ;NO, KEEP LOOKING
JUMPGE T4,SYMSNP ;NOT IN TABLE, GO SNOOP IT
MOVE T1,MONSYS(T4) ;FOUND IT, GET THE SYMBOL NAME
MOVE T2,MONSYO(T4) ;AND THE OFFSET
RET ;DONE
SYMSNP: MOVEM T1,TEMP ;SAVE FOR AWHILE
CAIL T4,MAXSYM ;IS THE SYMBOL TABLE FULL?
JRST SYMLOS ;YES, JUST RETURN OCTAL
MOVEI T1,.SNPAD ;FUNCTION TO FIND A SYMBOL
MOVE T2,TEMP ;VALUE TO FIND
SETZ T3, ;GLOBAL SEARCH
SNOOP ;LOOK FOR IT
ERJMP SYMLOS ;FAILED, RETURN OCTAL
MOVE T1,T2 ;MOVE SYMBOL TO RIGHT AC
MOVE T2,T3 ;AND OFFSET
MOVEM T1,MONSYS(T4) ;STORE THE SYMBOL NAME
MOVEM T2,MONSYO(T4) ;AND THE OFFSET
MOVE T3,TEMP ;GET VALUE WE FOUND
MOVEM T3,MONSYV(T4) ;SAVE IT
AOS MONSYC ;INCREMENT NUMBER OF SYMBOLS IN TABLE
RET ;DONE
SYMLOS: SETZ T1, ;SAY NO SYMBOL KNOWN
MOVE T2,TEMP ;GET ORIGINAL VALUE
RET ;DONE
SUBTTL ERROR TYPEOUT
;HERE TO TYPE ERRORS. THE DIE ROUTINE STOPS PERMANENTLY.
;THE LOSE ROUTINE OUTPUTS THE ERROR MESSAGE TO DPY, AND DOESN'T
;STOP THE PROGRAM.
TOOMNY: HRROI T1,[ASCIZ/
? Tables too small for jobs on system, reassemble with larger MAXJOB
/] ;GET STRING
PSOUT ;OUTPUT IT
HALTF ;QUIT
JRST .-1 ;STAY THAT WAY
DIE: MOVEI T1,.PRIOU ;OUTPUT STRAIGHT TO TERMINAL
CALL GIVERR ;TYPE THE LAST ERROR
HALTF ;QUIT
JRST .-1 ;STAY THAT WAY
LOSE: HRROI T1,TEMP ;POINT TO BUFFER
CALL GIVERR ;STORE THE ERROR MESSAGE
STR$ TEMP ;OUTPUT IT
RET ;DONE
GIVERR: HRROI T2,[ASCIZ/
? /] ;GET START OF ERROR
SETZ T3, ;CLEAR
SOUT ;START STRING
HRLOI T2,.FHSLF ;LAST ERROR IN MY PROCESS
MOVEI T3,TMPSIZ*5-12 ;GET MAXIMUM NUMBER OF CHARS
ERSTR ;TYPE ERROR
JFCL ;IGNORE ERRORS
JFCL
HRROI T2,[ASCIZ/
/] ;GET A FINAL CRLF
SETZ T3, ;WHOLE STRING
SOUT ;OUTPUT IT
RET ;DONE
SUBTTL SUBROUTINE TO SEE IF MONRD% JSYS EXISTS
;THIS SUBROUTINE IS CALLED TO TRY OUT THE MONRD% JSYS TO SEE IF IT
;WORKS. IF IT DOES NOT, WE TRY TO PUT IT INTO THE RUNNING MONITOR.
;THEN WE TRY IT AGAIN. FLAG FR.JSY IS SET IF IT WORKS CORRECTLY.
;ALWAYS RETURNS RIGHT AFTER CALL.
JSYTST: MOVEI T1,.RDTST ;GET TEST FUNCTION
SETZ T2, ;CLEAR AC
MONRD% ;TRY THE JSYS OUT
ERJMP JSYINI ;FAILED, GO TRY TO PUT IT IN
CAIN T2,.TSTNY ;ABLE TO USE THE JSYS?
JRST SYMRED ;YES, GO COLLECT SYMBOLS
CAIN T2,.TSTNN ;TOLD WE AREN'T GOOD ENOUGH?
RET ;YES, RETURN GRACEFULLY
IERR Wrong value returned from test function of "MONRD%" JSYS
;HERE WHEN THE MONRD% JSYS FAILS, TRY TO INSERT IT:
JSYINI: CALL MKJSYS ;TRY TO IMPLEMENT THE JSYS NOW
RET ;FAILED, ERROR MESSAGE ALREADY GIVEN
MOVEI T1,.RDTST ;GET TEST FUNCTION AGAIN
SETZ T2, ;CLEAR OTHER AC
MONRD% ;TRY IT AGAIN NOW
ERJMP [IERR "MONRD%" JSYS not inserted (not enough free core)]
CAIE T2,.TSTNY ;GET THE PROPER NUMBER?
IERR "MONRD%" JSYS inserted but test function returns wrong value
SYMRED: MOVSI T4,-SYMCNT ;GET NUMBER OF SYMBOLS TO FIND OUT
SYMRDL: MOVEI T1,.RDSYM ;FUNCTION TO READ A SYMBOL VALUE
MOVE T2,SYMTAB(T4) ;GET SYMBOL TO FIND OUT
MONRD% ;GET THE VALUE
ERJMP NOMONS ;FAILED, GO SAY WHY
JUMPN T1,NOMONS ;ALSO FAILED
MOVEM T2,SYMVAL(T4) ;SAVE THE VALUE FOR LATER
AOBJN T4,SYMRDL ;LOOP OVER ALL SYMBOLS
TXO F,FR.JSY ;CAN USE JSYS NOW
RET ;RETURN
;HERE FOR ERRORS IN SNOOPING OR USING MONRD%. THESE ROUTINES ARE
;CALLED BY THE IERR AND SERR MACROS. AN ERROR MESSAGE IS TYPED, AND
;THEN WE SLEEP FOR A FEW SECONDS TO GIVE TIME FOR THE TEXT TO BE READ.
NOMONS: HRROI T1,[ASCIZ/
? "MONRD%" JSYS failed to find the value of /]
PSOUT ;START OFF ERROR MESSAGE
MOVE T1,SYMTAB(T4) ;GET THE SYMBOL NAME IN SIXBIT
CALL SIXOTT ;OUTPUT IT TO THE TERMINAL
HRROI T1,[ASCIZ/
/] ;GET A FINAL CRLF
JRST IERRTP ;AND FINISH THE OUTPUT
SERRTP: PSOUT ;OUTPUT STRING
MOVEI T1,.PRIOU ;PRIMARY OUTPUT
HRLOI T2,.FHSLF ;LAST ERROR IN MY FORK
SETZ T3, ;INFINITE OUTPUT
ERSTR ;DO IT
JFCL ;IGNORE ERRORS
JFCL
SKIPA ;SKIP
IERRTP: PSOUT ;OUTPUT THE ERROR MESSAGE
MOVEI T1,^D5000 ;GET A TIME
TXNN F,FR.INS ;JUST INSERTING JSYS?
DISMS ;NO, SLEEP SOME SO HE CAN READ ERROR
RET ;THEN RETURN
SUBTTL ROUTINE TO "IMPLEMENT" USEFUL JSYS FOR SYSDPY
;ROUTINE TO IMPLEMENT THE MONRD% JSYS BY SNOOPING. IT IS ONLY
;NECESSARY TO HAVE A PRIVILEGED USER DO THIS ONCE, THEREAFTER ANYONE
;CAN USE THE JSYS TO READ INFORMATION. SKIP RETURN IF SUCCESSFUL.
MKJSYS: MOVEI T1,.FHSLF ;GET READY
RPCAP ;READ MY CAPABILITIES
TXNN T3,SC%WHL!SC%OPR ;SEE IF I CAN SNOOP
RET ;NO, RETURN WITHOUT COMPLAINING
AOS T1,VIRGIN ;BUMP COUNT OF TIMES WE GOT HERE
CAIE T1,1 ;BETTER BE FIRST TIME
IERR Initialization code is runnable only once
HRROI T1,[ASCIZ/
Attempting to insert "MONRD%" JSYS by snooping.../]
TXNN F,FR.INS ;SKIP MESSAGE IF SPECIAL ENTRY
PSOUT ;SAY WE ARE DOING THE WORK
MOVEI T1,.SNPSY ;FUNCTION TO GET A SYMBOL
MOVE T2,[RADIX50 0,.SNOOP] ;GET SYMBOL WE WANT
MOVE T3,[RADIX50 0,JSYSA] ;PROGRAM NAME
SNOOP ;FIND ITS VALUE
SERR SNOOP failed to get .SNOOP value
MOVEM T2,SNPVAL ;SAVE THE VALUE
CALL GETSYM ;FIX UP ALL CODE WITH SYMBOLS
RET ;ERROR, MESSAGE ALREADY GIVEN
MOVEI T1,.SNPLC ;GET FUNCTION TO LOCK PAGES
MOVEI T2,1 ;ONE PAGE
MOVEI T3,SNPLOC/1000 ;PAGE NUMBER TO BE LOCKED
SNOOP ;DO IT
SERR SNOOP failed to lock page
IMULI T2,1000 ;TURN MONITOR PAGE INTO ADDRESS
MOVEM T2,MONADR ;SAVE IT
MOVEI T1,.SNPDB ;GET READY TO DEFINE A BREAKPOINT
MOVEI T2,0 ;BREAKPOINT NUMBER 0
MOVE T3,SNPVAL ;GET ADDRESS TO BE PATCHED
MOVSI T4,(<CALL>) ;GET INSTRUCTION TO CALL US BY
HRR T4,MONADR ;INSERT ADDRESS
SNOOP ;DEFINE THE BREAKPOINT
JRST [CALL SNPFIN ;FAILED, UNDO SNOOP
SERR SNOOP failed to define breakpoint]
MOVEI T1,.SNPIB ;FUNCTION TO PUT IN BREAKPOINT
SNOOP ;PUT IT IN
JRST [CALL SNPFIN ;FAILED, UNDO SNOOP
SERR SNOOP failed to insert breakpoint]
AOS (P) ;INSERTED PROPERLY, SET UP FOR SKIP
SNPFIN: MOVEI T1,.SNPUL ;FUNCTION TO UNDO EVERYTHING
SNOOP ;UNDO SNOOPING (AND INSTALL JSYS!!)
JFCL ;OH WELL
RET ;ALL DONE
SUBTTL SUBROUTINE TO FILL IN SYMBOL VALUES
;SUBROUTINE TO FILL IN THE VALUES OF ALL MONITOR SYMBOLS REFERENCED
;BY THE $$ MACRO. THIS IS DONE BY SCANNING THE SYMS TABLE, WHICH HAS
;BLOCKS OF DATA IN THE FOLLOWING FORMAT:
;
; WORD 0 THE ADDRESS WHERE THE SYMBOL VALUE IS NEEDED.
; WORD 1 THE SYMBOL NAME IN RADIX50.
; WORD 2 THE PROGRAM MODULE NAME IN RADIX50.
; WORD 3 ADDRESS TO SET NONZERO IF SYMBOL ISN'T FOUND.
;
;SKIP RETURN IF SUCCESSFULLY FOUND ALL SYMBOLS.
GETSYM: MOVSI J,-SYMNUM ;SET UP AOBJN LOOP OVER SYMBOL TABLE
GETSYL: SKIPN T2,SYMS+1(J) ;IS THIS A NEW SYMBOL TO FIND?
JRST GETSYX ;NO, LOOK AT NEXT ONE
MOVE T3,SYMS+2(J) ;GET PROGRAM NAME
MOVEI T1,.SNPSY ;FUNCTION TO LOOKUP A SYMBOL
SNOOP ;ASK MONITOR FOR VALUE
JRST UNKSYM ;FAILED, GO HANDLE IT
MOVE T1,SYMS+1(J) ;GET SYMBOL NAME AGAIN
MOVE T3,J ;COPY AOBJN POINTER FOR SEARCH
GETSIL: CAME T1,SYMS+1(T3) ;IS THIS SYMBOL THE DESIRED ONE?
JRST GETSIX ;NO, KEEP SEARCHING
MOVE T4,@SYMS(T3) ;YES, GET INSTRUCTION THERE
ADD T4,T2 ;ADD IN THE SYMBOL VALUE
TLNN T4,-1 ;IS LEFT HALF ZERO?
MOVEM T4,@SYMS(T3) ;YES, REPLACE WHOLE VALUE
TLNE T4,-1 ;IS IT NONZERO?
HRRM T4,@SYMS(T3) ;YES, ONLY REPLACE RIGHT HALF
SETZM SYMS+1(T3) ;DONE WITH THIS USE OF THIS SYMBOL
GETSIX: ADDI T3,3 ;MOVE TO NEXT FOUR-WORD BLOCK
AOBJN T3,GETSIL ;SEARCH ALL OF REST OF TABLE
GETSYX: ADDI J,3 ;MOVE TO NEXT SYMBOL BLOCK
AOBJN J,GETSYL ;CONTINUE SEARCH FOR MORE NEW SYMBOLS
RETSKP ;HAVE THEM ALL
;HERE IF WE FAILED TO FIND A SYMBOL VALUE, TO TYPE OUT THE NAME
;OF THE SYMBOL SO THAT THE PROBLEM CAN EASILY BE FIXED. IF THIS
;SYMBOL IS ALLOWED TO BE UNKNOWN, WE JUST REMEMBER THAT.
UNKSYM: SKIPE T1,SYMS+3(J) ;ARE WE ALLOWED TO NOT KNOW THIS SYMBOL?
JRST [SETOM (T1) ;YES, SET FLAG SAYING WE FAILED
JRST GETSYX] ;AND GO BACK TO THE LOOP
HRROI T1,[ASCIZ/
? SNOOP failed to find value of /] ;GET READY
PSOUT ;TYPE THE INITIAL STRING
MOVE T1,SYMS+1(J) ;GET THE SYMBOL
CALL R50OTT ;OUTPUT TO TERMINAL
SKIPN SYMS+2(J) ;ANY PROGRAM NAME?
JRST UNKSYF ;NO, SKIP ON
HRROI T1,[ASCIZ/ in module /] ;YES, SAY SO
PSOUT ;OUTPUT IT
MOVE T1,SYMS+2(J) ;GET PROGRAM NAME
CALL R50OTT ;OUTPUT THAT TOO
UNKSYF: HRROI T1,[ASCIZ/:
/] ;GET THE REST OF THE STRING
JRST SERRTP ;GO OUTPUT IT AND THE ERROR REASON
SUBTTL SNOOP CODE
;THE FOLLOWING INSTRUCTIONS ARE EXECUTED BY THE MONITOR TO IMPLEMENT
;A JSYS WHICH WILL READ ANOTHER JOB'S JSB OR PSB. THIS CODE IS
;SELF-RELOCATABLE. THIS IS CALLED FROM THE BEGINNING OF A SNOOP JSYS.
XLIST ;DUMP ANY LITERALS FIRST
LIT
LIST
SYMS: ;SYMBOLS GET DUMPED HERE
LOC SNPLOC ;ACTUAL CODE GOES IN HIGH CORE
SNOPCD: MOVSI P2,(<JRST (P1)>) ;PUT INSTRUCTION IN P2
JSP P1,P2 ;JUMP TO IT AND PUT PC INTO P1
SUBI P1,. ;RELOCATE THE CODE
JSP CX,$$(SAVT,APRSRV) ;SAVE AC'S SNOOP WANTS TO USE
NOINT ;DON'T ALLOW US TO BE STOPPED
MOVEI T1,$$(JSTAB,LDINIT) ;GET ADDRESS OF JSYS TABLE
HRRZ T1,JSYNUM(T1) ;GET INSTRUCTION FOR OUR JSYS
CAIN T1,$$(UJSYS0,SCHED) ;ALREADY BEEN DIDDLED?
AOSE ONCE(P1) ;OR ALREADY ENTERED THIS CODE?
JRST INSDON(P1) ;YES, DO NOTHING
CALL $$(LGTAD,TIMER) ;GET CURRENT TIME
MOVEM T1,POKTIM(P1) ;SAVE IT
MOVE T1,$$(JOBNO,STG) ;GET MY JOB NUMBER
<HRL T1,(T1)>+$$(JOBDIR,STG) ;AND MY USER NUMBER
MOVEM T1,POKWHO(P1) ;SAVE IT
MOVEI T1,JSYLEN+1 ;GET NUMBER OF WORDS WANTED
CALL $$(ASGSWP,FREE) ;ALLOCATE FREE CORE
JRST INSDON(P1) ;CAN'T GET IT
AOS P2,T1 ;OK, SAVE ADDRESS OF WHERE JSYS BEGINS
HRLI T1,.MONRD(P1) ;GET ADDRESS OF CODE TO COPY
MOVEI T2,JSYLEN-1(T1) ;GET ADDRESS OF LAST LOC TO COPY TO
BLT T1,(T2) ;COPY CODE INTO FREE CORE
MOVEI T1,$$(JSTAB,LDINIT) ;GET ADDRESS OF START OF JSYS TABLE
HRRM P2,JSYNUM(T1) ;SETUP DISPATCH ADDRESS
INSDON: OKINT ;ALLOW INTERRUPTS AGAIN
RET ;RETURN
ONCE: EXP -1 ;ONCE-ONLY FLAG
LIT ;DUMP LITERALS NOW
SUBTTL THE MONRD% JSYS
;THE FOLLOWING CODE IS THE JSYS INSTALLED INTO THE RUNNING MONITOR.
;ITS FUNCTION IS TO RETURN INFORMATION NEEDED BY THIS PROGRAM.
;THE CALL IS:
;
; MOVEI T1,FUNCTION ;GET FUNCTION CODE
; (ARGUMENTS IN T2-T4) ;AND POSSIBLE ARGUMENTS
; MONRD% ;DO THE JSYS
; ERJMP LOSE ;FAIL IF NOT IMPLEMENTED
; JUMPN T1,ERROR ;AC IS NONZERO IF FUNCTION FAILED
; ;DONE, ANY VALUE RETURNED IN T2
;FUNCTIONS AND CONSTANTS:
.RDTST==0 ;TEST FUNCTION
.RDSYM==1 ;READ SYMBOL FUNCTION
.RDJSB==2 ;READ FROM JSB
.RDPSB==3 ;READ FROM PSB
.RDSTS==4 ;READ FORK STATUS
.RDMAP==5 ;READ WORDS FROM FORK PAGE MAP
.RDFST==6 ;READ FKSTAT WORD
.RDPID==7 ;READ WORD FROM IPCF HEADER
.RDDLL==10 ;READ DECNET LOGICAL LINK DATA
.RDTTY==11 ;READ WORD FROM TERMINAL DATABASE
.RDTTS==12 ;READ TTSTAT WORD FOR TERMINAL
.RDWSP==13 ;READ FKWSP WORD
.RDRES==14 ;READ STATUS OF SYSTEM RESOURCES
.TSTNY==123456 ;VALUE RETURNED FROM TEST FUNCTION
.TSTNN==654321 ;VALUE RETURNED IF NOT ALLOWED TO DO IT
;THE ACTUAL JSYS CODE:
.MONRD: MOVSI P2,(<JRST (P1)>) ;SETUP RETURN INSTRUCTION
JSP P1,P2 ;PUT PC IN P1 AND RETURN
SUBI P1,. ;RELOCATE IT
NOINT ;DISALLOW INTERRUPTS
IFN FTPRIV,<
MOVE P2,$$(CAPENB,STG) ;GET HIS CAPABILITIES
TXNN P2,SC%WHL!SC%OPR ;ALLOWED TO DO THIS JSYS?
JUMPN T1,ERROR(P1) ;NO, ERROR UNLESS FUNCTION 0
>
SKIPL T1 ;SEE IF HAVE LEGAL FUNCTION
CAILE T1,.RDMAX ;WELL?
JRST ERROR(P1) ;NO, GO LOSE
ADD T1,P1 ;RELOCATE THE ADDRESS
CALL @MONRDT(T1) ;CALL THE SUBROUTINE
JRST ERROR(P1) ;FAILED
XCTU [MOVEM P2,2](P1) ;STORE RETURNED VALUE
TDZA T1,T1 ;CLEAR AC
ERROR: SETO T1, ;OR SET AC NONZERO
XCTU [MOVEM T1,1](P1) ;STORE SUCCESS FLAG
OKINT ;ALLOW INTERRUPTS AGAIN
JRST $$(MRETN,SCHED) ;RETURN FROM JSYS
MONRDT: IFIW TSTFNC(P1) ;TEST EXISTANCE OF JSYS
IFIW SYMFNC(P1) ;READ VALUE OF SYMBOL
IFIW JSBFNC(P1) ;READ WORD FROM JSB
IFIW PSBFNC(P1) ;READ WORD FROM PSB
IFIW STSFNC(P1) ;GET FORK STATUS
IFIW MAPFNC(P1) ;READ ACCESS OF CORE PAGE
IFIW FSTFNC(P1) ;RETURN FKSTAT WORD
IFIW IPCFNC(P1) ;RETURN WORD FROM PID HEADER
IFIW DLLFNC(P1) ;DUMP LL BLOCKS FOR DECNET
IFIW TTYFNC(P1) ;RETURN WORD FROM TERMINAL BLOCKS
IFIW TTSFNC(P1) ;RETURN THE TTSTAT WORD
IFIW WSPFNC(P1) ;RETURN FKWSP WORD
IFIW RESFNC(P1) ;RETURN RESOURCE INFORMATION
.RDMAX==.-MONRDT-1 ;HIGHEST LEGAL FUNCTION
POKTIM: EXP 0 ;TIME AT WHICH JSYS WAS INSTALLED
POKWHO: EXP 0 ;USER NUMBER AND JOB NUMBER WHICH DID IT
;TEST FUNCTION. USED TO SEE IF JSYS IS IMPLEMENTED. NO ARGUMENTS.
;RETURNS IN T2 THE NUMBER .TSTN?, IN T3 THE TIME THE JSYS WAS PUT IN,
;AND IN T4 THE USER NUMBER AND JOB NUMBER WHICH DID IT.
TSTFNC: DMOVE T1,POKTIM(P1) ;GET THE TIME AND WHO PUT IN JSYS
XCTU [DMOVEM T1,3](P1) ;STORE IN USER'S AC
MOVEI P2,.TSTNY ;GET TEST NUMBER TO BE RETURNED
IFN FTPRIV,<
MOVE T1,$$(CAPENB,STG) ;GET PRIVILEGES
TXNN T1,SC%WHL!SC%OPR ;ABLE TO DO THE OTHER FUNCTIONS?
MOVEI P2,.TSTNN ;NO, GET FAILURE CODE
>
SKP: AOS (P) ;SET UP FOR SKIP RETURN
RET: RET ;DO IT
;LOOKUP SYMBOL VALUE FUNCTION. T2 = SIXBIT OF SYMBOL TO LOOK UP.
;RETURNS VALUE IN T2.
SYMFNC: CALL SYMSR0(P1) ;LOOK FOR THE SYMBOL
RET ;FAILED
JRST SKP(P1) ;GOOD RETURN
;GET STATUS OF FORK FUNCTION. T2 = SYSTEM FORK NUMBER.
;RETURNS STATUS WORD (SAME AS .RFSTS) IN T2.
STSFNC: MOVE T1,T2 ;PUT FORK NUMBER IN RIGHT AC
MOVE FX,T2 ;AND IN OTHER AC
CALL CHKFRK(P1) ;SEE IF THE FORK IS THERE
RET ;NO, ERROR RETURN
CALL $$(MRFSTS,FORK) ;OK, READ FORK STATUS
OKSKED ;ALLOW SCHEDULING NOW
MOVE P2,T1 ;COPY STATUS
JRST SKP(P1) ;GOOD RETURN
;GET FKSTAT OR FKWSP WORD FOR FORK. T2 = SYSTEM FORK NUMBER. RETURNS
;WORD IN T2.
WSPFNC: SKIPA P2,WSPLOC(P1) ;GET ADDRESS OF WORKING SET TABLE
FSTFNC: MOVEI P2,$$(FKSTAT,STG) ;OR ADDRESS OF SCHEDULER TEST TABLE
SKIPL T2 ;VERIFY FORK NUMBER
CAIL T2,$$(NFKS,STG) ;SOME MORE
RET ;BAD
ADD P2,T2 ;ADD IN OFFSET INTO TABLE
MOVE P2,(P2) ;GET WORD
JRST SKP(P1) ;GOOD RETURN
WSPLOC: EXP $$(FKWSP,STG) ;ADDRESS OF WORKING SET TABLE
;GET WORD FROM TTACTL DATA FOR TERMINALS. T2 = SYMBOL IN BLOCK,
;T3 = OFFSET FROM SYMBOL, T4 = TERMINAL NUMBER. RETURNS WORD IN T2.
TTYFNC: MOVEI T1,$$(TTDDLN,TTYSRV) ;GET LENGTH OF TERMINAL BLOCKS
SUBI T1,1 ;BACK OFF ONE
CALL SYMSRC(P1) ;LOOK FOR THE SYMBOL
RET ;UNKNOWN SYMBOL
XCTU [SKIPL T1,4](P1) ;GET TERMINAL NUMBER
CAIL T1,$$(NLINES,STG) ;AND RANGE CHECK IT
RET ;OUT OF RANGE
<SKIPG T1,(T1)>+$$(TTACTL,STG) ;GET POINTER TO DATA BLOCK
RET ;NOT ASSIGNED
ADD P2,T1 ;ADD ADDRESS INTO OFFSET
MOVE P2,(P2) ;GET THE REQUIRED WORD
JRST SKP(P1) ;DONE
;GET THE WORD FROM TTSTAT FOR A TTY LINE. AC T2 HAS THE LINE NUMBER.
;RETURNS THE WORD IN T2.
TTSFNC: SKIPL T2 ;RANGE CHECK THE DATA
CAIL T2,$$(NLINES,STG) ;SOME MORE
RET ;ITS BAD
<MOVE P2,(T2)>+$$(TTSTAT,STG) ;GET THE WORD
JRST SKP(P1) ;GOOD RETURN
;GET WORD FROM JSB FUNCTION. T2 = SYMBOL IN JSB, T3 = OFFSET FROM SYMBOL,
;T4 = JOB NUMBER. RETURNS WORD FROM JSB IN AC T2.
;THE JSB AREA STARTS AT LOCATION JSB, AND EXTENDS UP TO THE PAGE PPMPG.
JSBFNC: MOVEI T1,$$(JSVARZ,POSTLD) ;GET LAST ADDRESS IN JSB
HRLI T1,$$(JSVAR,JOBDAT) ;AND PUT IN LOWEST JSB ADDRESS
CALL SYMSRC(P1) ;LOOK FOR THE SYMBOL
RET ;FAILED, RETURN
XCTU [SKIPL T1,4](P1) ;GET JOB AND SEE IF NONNEGATIVE
CAIL T1,$$(NJOBS,STG) ;AND SEE IF NOT TOO LARGE
RET ;NO, ERROR RETURN
NOSKED ;STOP SCHEDULING NOW
<SKIPGE 0(T1)>+$$(JOBRT,STG) ;IS THIS JOB NUMBER ASSIGNED?
JRST SKDRET(P1) ;NO, GO ERROR RETURN
<HRRZ T1,0(T1)>+$$(JOBPT,STG) ;GET TOP FORK OF THE JOB
<HRLZ T1,0(T1)>+$$(FKJOB,STG) ;THEN GET SPT INDEX OF JSB
MOVE T2,P2 ;GET ADDRESS
SUBI T2,$$(JSVAR,JOBDAT) ;SUBTRACT BASE ADDRESS
LSH T2,-^D9 ;GET PAGE NUMBER INTO JSB
HRR T1,T2 ;PUT THAT INTO T1
PUSH P,T1 ;SAVE PAGE IDENT FOR LATER
CALL $$(MRPACS,PAGEM) ;READ ACCESSIBILITY OF PAGE
JUMPE T1,JSBZER(P1) ;NO PAGE, GO RETURN ZERO
POP P,T1 ;PAGE IS THERE, RESTORE IDENT
MOVEI T2,$$(FPG1A,STG) ;GET ADDRESS OF TEMPORARY PAGE
CALL $$(SETMPG,PAGEM) ;MAP THE PAGE OF THE JSB
NOINT ;MATCH OKINT DONE BY CLRJSB
ANDI P2,777 ;ONLY KEEP OFFSET INTO PAGE NOW
<MOVE P2,0(P2)>+$$(FPG1A,STG) ;GET THE WORD FROM THE JSB
OKSKP: CALL $$(CLRJSB,FORK) ;UNMAP THE TEMPORARY PAGE
OKSKED ;CAN SCHEDULE AGAIN NOW
JRST SKP(P1) ;GOOD RETURN
JSBZER: OKSKED ;ALLOW SCHEDULING
POP P,T1 ;POP OFF AC
SETZ P2, ;MAKE A ZERO RESULT
JRST SKP(P1) ;GOOD RETURN
;READ WORD OF PSB FUNCTION. T2 = SYMBOL NAME, T3 = OFFSET FROM SYMBOL,
;T4 = SYSTEM FORK NUMBER. RETURNS WORD OF PSB IN T2.
;WE ONLY PROVIDE FOR THE READING OF THE TWO IMPORTANT PAGES.
PSBFNC: MOVEI T1,$$(PSBPGA,STG) ;GET LOWER BOUND ON SYMBOL
HRLI T1,1777(T1) ;CREATE UPPER BOUND
MOVS T1,T1 ;AND REVERSE TO MAKE CORRECT
CALL SYMSRC(P1) ;LOOK FOR HIS SYMBOL
RET ;NOT FOUND
XCTU [MOVE T1,4](P1) ;GET THE FORK NUMBER
CALL CHKFRK(P1) ;SEE IF FORK IS OK TO LOOK AT
RET ;NO, ERROR
CALL $$(SETLF3,FORK) ;FORK IS THERE, MAP THE PSB
OKSKED ;THEN ALLOW SCHEDULING
ADD P2,T1 ;RELOCATE WORD TO BE READ
MOVE P2,(P2) ;GET THE WORD
CALL $$(CLRJSB,FORK) ;UNMAP THE JSB OR PSB NOW
JRST SKP(P1) ;GOOD RETURN
;READ A WORD FROM THE HEADER BLOCK OF A PID. T2 = PID TO READ,
;T3 = OFFSET INTO HEADER. RETURNS WORD IN T2.
IPCFNC: SKIPL P2,T3 ;VALIDATE THE HEADER OFFSET
CAIL P2,$$(PIDHDS,STG) ;AND SAVE IN GOOD AC
RET ;BAD OFFSET
MOVE T1,T2 ;MOVE PID TO RIGHT AC
CALL $$(VALPID,IPCF) ;VALIDATE THE PID NUMBER
RET ;BAD, RETURN
ADD P2,T2 ;ADD ADDRESS OF HEADER TO OFFSET
MOVE P2,(P2) ;GET THE WORD
JRST SKP(P1) ;GOOD RETURN
;READ ACCESS OF A USER CORE PAGE. T2 = PAGE NUMBER TO BE EXAMINED,
;T3 = SYSTEM FORK NUMBER. RETURNS PAGE POINTER IN T2, IN THE FOLLOWING
;FORMAT:
;
; 0 THIS PAGE AND ALL FURTHER PAGES ARE NONEXISTANT
; 0,,N THIS PAGE NONEXISTANT, NEXT EXISTANT PAGE IS N
; 1XXXXX,,XXXXXX PRIVATE PAGE
; 2XXXXX,,FORK SHARED PAGE WITH GIVEN SYSTEM FORK INDEX
; 2XXXXX,,-OFN SHARED PAGE WITH GIVEN FILE OFN
; 3XXXXX,,FORK INDIRECT PAGE WITH GIVEN FORK INDEX
; 3XXXXX,,-OFN INDIRECT PAGE WITH GIVEN FILE OFN
MAPFNC: MOVE P2,T2 ;SAVE PAGE NUMBER IN SAFE PLACE
MOVE T1,T3 ;GET SYSTEM FORK NUMBER IN RIGHT AC
TDNN P2,[-1,,777000](P1) ;VALIDATE PAGE NUMBER
CALL CHKFRK(P1) ;AND VALIDATE FORK NUMBER
RET ;BAD, ERROR RETURN
<HLRZ T1,(T1)>+$$(FKPGS,STG) ;GET SPT INDEX OF PAGE TABLE
MOVEI T2,$$(FPG1A,STG) ;AND ADDRESS OF TEMP PAGE
CALL $$(SETMPG,PAGEM) ;MAP IN THE PAGE TABLE
NOINT ;MATCH OKINT DONE BY CLRJSB
<SKIPN T1,(P2)>+$$(FPG1A,STG) ;IS PAGE POINTER IN USE?
AOJA P2,MAPZER(P1) ;NO, GO HUNT FOR NEXT USED ONE
MOVE P2,T1 ;PUT POINTER IN SAFE PLACE
CALL $$(CLRJSB,FORK) ;REMOVE THE MAPPING
OKSKED ;ALLOW SCHEDULING NOW
TLNN P2,200000 ;IS THIS A DIRECT POINTER?
JRST SKP(P1) ;YES, RETURN IT AS IS
HRRZ T1,P2 ;GET SPT INDEX FROM POINTER
CAIL T1,$$(NOFN,STG) ;IS THIS AN OFN?
<SKIPA T1,(T1)>+$$(SPTH,STG) ;NO, GET PAGE'S ORIGIN
HRLZ T1,T1 ;YES, SET UP
HLRZ T2,T1 ;GET OFN IF ANY
SKIPE T2 ;IS THIS OFN,,PAGE OR 0,,FORK?
MOVN T1,T2 ;IS OFN, NEGATE IT
HRR P2,T1 ;REPLACE RIGHT HALF WITH OFN OR FORK
JRST SKP(P1) ;GOOD RETURN
MAPZER: TRZN P2,777000 ;WENT OFF END OF THE PAGE MAP?
<SKIPE (P2)>+$$(FPG1A,STG) ;OR FOUND A NONZERO ENTRY?
JRST OKSKP(P1) ;YES, DO UNMAP, OKSKED, AND SKIP RETURN
AOJA P2,MAPZER(P1) ;OTHERWISE KEEP SEARCHING
;FUNCTION TO DUMP OUT THE LL BLOCKS INTO CORE. T2 = <-LEN,,ADDR>
;OF BLOCK TO STORE DATA. RETURNS IN T2 SIZE OF EACH BLOCK IN LEFT
;HALF, AND NUMBER OF BLOCKS RETURNED IN RIGHT HALF.
OKDLL: BLOCK 1 ;NONZERO IF NOT ABLE TO DO THIS FUNCTION
.FAIL.==OKDLL ;DEFINE LOC IN CASE SYMBOLS AREN'T FOUND
DLLFNC: SKIPE OKDLL(P1) ;SEE IF WE CAN DO THIS STUFF
RET ;NO, RETURN
MOVE P3,T2 ;SAVE IOWD POINTER
SUB P3,[1,,1](P1) ;FIX UP POINTER
MOVSI P2,DLLNUM ;GET SIZE OF EACH BLOCK AND CLEAR COUNTER
CALL $$(LOKLL,NSPSRV) ;LOCK UP THE NETWORK STRUCTURE
MOVEI T1,DLLSUB(P1) ;GET CO-ROUTINE ADDRESS
SETO T2, ;WE WANT ALL LOGICAL LINK BLOCKS
CALL $$(OBJSRC,NSPSRV) ;CALL CO-ROUTINE TO PROCESS THEM
CALL $$(ULOKLL,NSPSRV) ;UNLOCK THE DATA STRUCTURE
JRST SKP(P1) ;GOOD RETURN
;SUBROUTINE CALLED FOR EACH LOGICAL LINK BLOCK. AC T1 HAS
;THE ADDRESS OF THE NEW LL BLOCK.
DLLSUB: JSP CX,$$(SAVT,APRSRV) ;HAVE TO SAVE ALL TEMPORARIES
MOVSI T2,-DLLNUM ;GET READY FOR A LOOP
HRR T2,P1 ;RELOCATE AOBJN POINTER
MOVSI T3,(<MOVEM T4,>) ;SET UP AN INSTRUCTION
DLLSTL: AOBJP P3,RET(P1) ;RETURN IF NO MORE ROOM
MOVE T4,T1 ;COPY ADDRESS OF LL BLOCK
ADD T4,DLLTAB(T2) ;ADD OFFSET DESIRED
MOVE T4,(T4) ;GET THE DATA
HRR T3,P3 ;POINT TO NEXT WORD
XCTU T3 ;STORE THE WORD
ERJMP RET(P1) ;FAILED
AOBJN T2,DLLSTL(P1) ;STORE ALL DESIRED WORDS
AOJA P2,RET(P1) ;COUNT BLOCKS STORED AND RETURN
;TABLE OF WORDS TO BE RETURNED BACK TO USER. THIS TABLE IS BUILT
;BY EXPANDING THE LLNUMS MACRO DEFINED EARLIER.
DEFINE LLLIST(ARGS),<
IRP ARGS,< ;;LOOP OVER ALL ARGS
DL.'ARGS==.-DLLTAB ;;ASSIGN OFFSET
EXP ARGS ;;MAKE OFFSET TABLE
>
>
DLLTAB: LLNUMS ;EXPAND THE MACRO
DLLNUM==.-DLLTAB ;NUMBER OF WORDS
.FAIL.==0 ;NO MORE SYMBOL FAILURES ALLOWED NOW
;FUNCTION TO RETURN VARIOUS SYSTEM RESOURCE INFORMATION IN THE MONITOR.
;CALLED WITH TYPE OF RESOURCE IN T2. RETURNS T2 = CURRENT VALUE,
;AND T3 = INITIAL VALUE.
RESFNC: TRNN T2,-1 ;WANTS A SUB FIELD OF RESIDENT SPACE?
JRST RESSUB(P1) ;NO, GO DO OTHER FIELDS
SUBI T2,1 ;DECREMENT OFFSET
TLNN T2,-1 ;SEE IF NONZERO LEFT HALF
CAIL T2,$$(RESQTL,STG) ;OR IF FUNCTION IS TOO BIG
RET ;YES, BAD
<MOVE P2,(T2)>+$$(RESQTB,FREE) ;GET INITIAL COUNT
<MOVE T2,(T2)>+$$(RESUTB,STG) ;AND CURRENT FREE COUNT
XCTU [MOVEM T2,3](P1) ;GIVE TO USER
JRST SKP(P1) ;AND RETURN FINAL RESULT TOO
RESSUB: HLRZ T2,T2 ;GET FIELD OFFSET
CAILE T2,MAXRES ;RANGE CHECK THE INDEX
RET ;BAD
ADD T2,P1 ;RELOCATE ADDRESS
SKIPGE P2,RESTB1(T2) ;GET VALUE OR POINTER
MOVE P2,(P2) ;WAS A POINTER, GET DATA
SKIPL T2,RESTB2(T2) ;HAVE TO COMPUTE CURRENT VALUE?
TLOA T2,(IFIW) ;YES, SET BIT FIRST
SKIPA T2,@T2 ;NO, JUST GET IT
CALL @T2 ;YES, COMPUTE DATA
XCTU [MOVEM T2,3](P1) ;GIVE TO USER
JRST SKP(P1) ;DONE
RESTB1: EXP $$(NRESFB,STG) ;(0) NUMBER OF RESIDENT BLOCKS
EXP $$(SWFREL,STG) ;(1) AMOUNT OF SWAPABLE SPACE
EXP $$(ENQMXF,STG) ;(2) MAXIMUM ENQ USAGE
EXP $$(MAXBLK,STG) ;(3) MAXIMUM NETWORK STORAGE
EXP $$(NOFN,STG) ;(4) SIZE OF OFN TABLE
EXP $$(SSPT,STG) ;(5) SIZE OF SPT TABLE
IFIW $$(DRMTPG,STG) ;(6) NUMBER OF SWAPPING PAGES
IFIW $$(TOTRC,STG) ;(7) TOTAL USER CORE AVAILABLE
EXP $$(NFKS,STG) ;(10) NUMBER OF FORKS
MAXRES==.-RESTB1 ;HIGHEST VALUE
RESTB2: IFIW $$(RESFRE,STG) ;FREE RESIDENT BLOCKS
IFIW 2+$$(SWPFRE,STG) ;NONRESIDENT STORAGE
IFIW $$(ENQSPC,STG) ;ENQ SPACE LEFT
IFIW $$(BLKASG,STG) ;NETWORK SPACE ASSIGNED
IFIW $$(NOF,PAGEM) ;CURRENT OFNS ASSIGNED
IFIW $$(SPTC,PAGEM) ;CURRENT SPT SLOTS ASSIGNED
IFIW $$(DRMFRE,STG) ;FREE SWAPPING PAGES
IFIW $$(NRPLQ,STG) ;PAGES ON THE REPLACEABLE QUEUE
Z FRKCNT(P1) ;ROUTINE TO COUNT USED FORKS
;ROUTINE TO COMPUTE NUMBER OF USED FORKS ON THE SYSTEM.
FRKCNT: SETZ T2, ;START WITH ZERO
MOVNI T3,$$(NFKS,STG) ;GET NUMBER OF FORKS TOTAL
MOVSI T3,(T3) ;MAKE AOBJN POINTER
FRKCN1: <SKIPL (T3)>+$$(FKPT,STG) ;THIS FORK ASSIGNED?
ADDI T2,1 ;YES, COUNT IT
AOBJN T3,FRKCN1(P1) ;LOOP UNTIL LOOKED AT THEM ALL
RET ;DONE
;SUBROUTINE TO CHECK A SYSTEM WIDE FORK NUMBER, AND VERIFY THAT THE
;FORK IS LEGAL AND EXISTS. CALL:
;
; MOVE T1,FORK ;GET SYSTEM FORK NUMBER
; CALL CHKFRK(P1) ;VERIFY THAT IT IS THERE
; (ERROR) ;ILLEGAL FORK, OR NOT EXISTANT
; (GOOD RETURN) ;IS LEGAL, WE ARE NOSKED
;
;ON A SUCCESSFUL RETURN, WE ARE RUNNING NOSKED SO THE CALLER MUST
;DO AN OKSKED SOMETIME. DOES NOT CHANGE T1.
CHKFRK: SKIPL T1 ;SEE IF FORK NUMBER IS LEGAL
CAIL T1,$$(NFKS,STG) ;WELL?
RET ;NO, ERROR
NOSKED ;NO RACES NOW
HRRZ T2,.JBVER ;GET MONITOR VERSION
CAIGE T2,NWFKPT ;NEW STYLE SCHEDULAR CODE?
JRST CHKFRO(P1) ;NO, GO DO OLD WAY
<SKIPL 0(T1)>+$$(FKPT,STG) ;IS FORK ASSIGNED?
JRST SKP(P1) ;YES, GOOD RETURN
JRST SKDRET(P1) ;NO, GIVE ERROR RETURN
CHKFRO: <HLRZ T2,0(T1)>+$$(FKPT,STG) ;GET QUEUE FORK IS ON
CAIE T2,$$(WTLST,STG) ;IS FORK IN A WAIT?
CAIN T2,$$(GOLST,STG) ;OR RUNNABLE?
JRST SKP(P1) ;YES, SUCCESSFUL RETURN
SKDRET: OKSKED ;NO, THEN FORK IS NONEXISTANT
RET ;SO ERROR RETURN
;SUBROUTINE TO SEARCH FOR A MONITOR SYMBOL IN OUR LITTLE TABLE, AND
;RANGE CHECK IT AGAINST THE LIMITS OF THE PSB OR JSB. CALL:
;
; MOVE T1,[LOWADR,,HGHADR] ;GET BOUNDS ON THE ADDRESS
; MOVE T2,SYMBOL ;GET SIXBIT SYMBOL
; CALL SYMSRC(P1) ;LOOK FOR IT
; (ERROR) ;NOT FOUND, OR OUT OF LEGAL RANGE
; (GOOD RETURN) ;VALUE IN AC P2
;
;A SYMBOL NAME OF ZERO IMPLIES A VALUE OF ZERO, SO THAT THE OFFSET
;GIVEN IS THE ACTUAL ADDRESS WANTED. CALL AT SYMSR0 IF NO OFFSET
;IS TO BE USED, AND NO RANGE CHECKING IS WANTED.
SYMSR0: SETZ T1, ;NO BOUNDS CHECKING
SYMSRC: SKIPN P2,T2 ;ANY SYMBOL NAME SPECIFIED?
JRST SYMSRV(P1) ;NO, WANTS THE PARTICULAR VALUE
MOVSI T3,-SYMCNT ;GET NUMBER OF SYMBOLS TO LOOK AT
HRR T3,P1 ;RELOCATE THE ADDRESS
SYMLOP: CAME T2,SYMTAB(T3) ;FOUND THE SYMBOL YET?
AOBJN T3,SYMLOP(P1) ;NO, KEEP LOOKING
JUMPGE T3,RET(P1) ;NOT FOUND, ERROR
MOVE P2,SYMVAL(T3) ;OK, GET THE VALUE
SYMSRV: JUMPE T1,SKP(P1) ;IF NO BOUNDS CHECKING, ARE DONE
XCTU [ADD P2,3](P1) ;ADD IN OFFSET SPECIFIED BY USER
HLRZ T2,T1 ;GET LOWER BOUND
CAML P2,T2 ;ADDRESS LESS THAN LOWER BOUND?
CAILE P2,(T1) ;OR HIGHER THAN UPPER BOUND?
RET ;YES, ERROR
JRST SKP(P1) ;NO, THEN SKIP RETURN
;TABLE OF KNOWN SYMBOLS WE CAN BE TOLD TO USE:
DEFINE SS,< ;;DEFINE SYMBOLS WE WILL KNOW ABOUT
XX JSVAR,JOBDAT ;BEGINNING OF JOB STORAGE BLOCK
XX JSVARZ,POSTLD ;END OF JOB STORAGE BLOCK
XX RSCNBP ;POINTER TO JOB'S RSCAN BUFFER
XX MAXJFN ;HIGHEST JFN IN USE
XX FILSTS ;STATUS BITS FOR JFN
XX FILBYT ;BYTE POINTER INTO WINDOW
XX FILBYN ;BYTE NUMBER INTO FILE
XX FILDDN ;POINTER TO DEVICE STRING IN JFN BLOCK
XX FILDNM ;POINTER TO DIRECTORY STRING
XX FILNEN ;POINTER TO NAME AND EXTENSION STRINGS
XX FILVER ;GENERATION NUMBER
XX FILOFN ;OFN FOR THIS FILE
XX FILDEV ;DEVICE DISPATCH
XX DSKDTB,DISC ;ADDRESS FOR DISKS
XX SYSFK ;JOB FORK TO SYSTEM FORK TABLE
XX FKPTRS ;STRUCTURE OF FORKS
XX NUFKS ;NUMBER OF USER FORKS
XX FKCNT ;NUMBER OF FORKS IN THE JOB
XX MLJFN ;LENGTH OF EACH JFN BLOCK
XX PSVAR,JOBDAT ;BEGINNING OF PROCESS STORAGE BLOCK
XX PSVARZ,POSTLD ;END OF PROCESS STORAGE BLOCK
XX JOBNO ;JOB NUMBER FORK BELONGS TO
XX UPDL ;BEGINNING OF JSYS STACK
XX FKRT ;FORK RUN TIME
XX PPC ;PROCESS PC
XX KIMUU1 ;LAST USER UUO
XX CAPMSK ;POSSIBLE CAPABILITIES
XX CAPENB ;ENABLED CAPABILITIES
XX UTRPCT ;NUMBER OF PAGE TRAPS
XX LSTERR ;LAST ERROR IN FORK
XX INTDF ;NO INTERRUPTIONS COUNTER
XX TRAPPC ;THE PC OF THE LAST PAGE FAULT
XX TTFLG1,TTYSRV ;FLAGS
XX TTOCT,TTYSRV ;CHARACTERS IN OUTPUT BUFFER
XX TTICT,TTYSRV ;CHARACTERS IN INPUT BUFFER
XX TTLINK,TTYSRV ;LINES LINKED TO THIS TTY
XX TTFLGS,TTYSRV ;MORE FLAGS
XX RESQTL ;NUMBER OF RESIDENT FREE POOLS
>
DEFINE XX(SYMBOL,MODULE<STG>),<
EXP SIXBIT /SYMBOL/ ;SIXBIT NAME
>
XALL ;ALLOW LISTING
SYMTAB: SS
SYMCNT==.-SYMTAB ;NUMBER OF SYMBOLS
DEFINE XX(SYMBOL,MODULE<STG>),<
SYMBOL: Z $$(SYMBOL,MODULE) ;VALUE OF NAME
>
SYMVAL: SS
SALL ;RETURN TO NORMAL LISTING
LIT ;DUMP LITERALS
JSYLEN==.-.MONRD ;NUMBER OF WORDS FOR JSYS
IFG <.-SNPLOC-1000>,< ;MAKE SURE STILL ON ONE PAGE
PRINTX ? SNOOP code is larger than a page. Do not attempt to run program!
>
RELOC ;RETURN TO NORMAL CODE
SYMNUM==<.-SYMS>/4 ;NUMBER OF SYMBOLS TO FILL IN
SUBTTL MACRO TO DEFINE THE DISPLAY TYPES
;THE FOLLOWING MACRO DEFINES THE TYPES OF DISPLAYS WHICH CAN
;BE OUTPUT, AND WHICH HAVE DEFINABLE COLUMNS. (THUS THINGS LIKE
;THE QUEUE DISPLAY WON'T APPEAR HERE, SINCE NO COLUMNS CAN BE
;CHANGED). THE ARGUMENTS ARE:
;
; XX SEPARATION, TYPE, TEXT
;
;WHERE SEPARATION IS THE DEFAULT NUMBER OF BLANKS BETWEEN COLUMNS,
;TYPE IS THE MNEMONIC FOR THIS DISPLAY USED IN THE COLUMN MACRO LATER,
;AND TEXT IS THE NAME OF THIS COLUMN FOR TBLUK PURPOSES. THIS
;TABLE MUST BE IN ALPHABETICAL ORDER.
DEFINE TYPES,< ;;DEFINE THE TYPES
XX 3,ANH,ARPANET-HOSTS ;;HOSTS ON THE ARPANET
XX 3,ANC,ARPANET-LINKS ;;ARPANET CONNECTIONS
XX 2,DLL,DECNET-STATUS ;;DECNET DISPLAY
XX 4,DEV,DEVICES ;;SYSTEM DEVICES
XX 1,DSK,DISK-UNITS ;;UNITS IN THE SYSTEM
XX 3,EQL,ENQ-LOCKS ;;LOCKS FOR ENQ/DEQ
XX 3,EQQ,ENQ-QUEUES ;;QUEUES FOR THE LOCKS
XX 2,FIL,FILES ;;FILES OF A JOB
XX 2,FRK,FORKS ;;FORKS IN A JOB
XX 2,IPC,IPCF-STATUS ;;THE PIDS ON THE SYSTEM
XX 2,JOB,JOBS ;;ALL OF THE JOBS
XX 2,STR,STRUCTURES ;;DISK STRUCTURES
XX 2,TTY,TERMINALS ;;THE TERMINALS
>
DEFINE XX(SEP,TYPE,TEXT),<
TP.'TYPE==.-DISTAB ;;DEFINE HEADER CODE
XWD [ASCIZ/TEXT/],SEP ;;DUMP NAME AND SEPARATION
>
DISTAB: XWD DISNUM,DISNUM ;NUMBER OF ENTRIES
TYPES ;EXPAND THE TABLE
DISNUM==.-DISTAB-1 ;NUMBER OF ENTRIES
SUBTTL MACRO TO DEFINE THE COLUMNS
;THE FOLLOWING MACRO DEFINES THE COLUMNS WHICH CAN BE OUTPUT FOR
;A FORK. THE ARGUMENTS ARE:
;
; XX ORDER, TYPE, SIZE, ROUTINE, NAME, HEADER
;
;ORDER GIVES THE DEFAULT ORDERING OF THE COLUMNS.
;TYPE IS THE TYPE OF COLUMN THIS IS, WITHOUT THE "TP."
;SIZE IS THE NUMBER OF SPACES THIS COLUMN NEEDS IN WORST CASE.
;ROUTINE IS THE DISPATCH ADDRESS FOR THIS COLUMN, WITHOUT THE "XX"
;NAME IS THE KEYWORD NAME FOR THIS COLUMN.
;HEADER IS THE TEXT OUTPUT AS THE HEADER FOR THIS COLUMN.
DEFINE COLS,<
XX 0,DLL,15,LABT,ABORT-REASON,<Abort reason> ;;ABORT REASON
XX 0,JOB,15,ACCT,ACCOUNT,< Account> ;;ACCOUNT STRING
XX 30,DSK,6,ALIS,ALIAS,<Alias> ;;DISK ALIAS
XX 0,DLL,10,LBYC,BYTE-COUNT-IN-SEGMENT,<Byte count> ;;BYTES
XX 10,DSK,4,CHAN,CHANNEL,<Chan> ;;DISK CHANNEL
XX 60,EQL,15,LCOD,CODE-FOR-LOCK,<Lock code> ;;LOCK CODE
XX 0,JOB,7,CTIM,CONNECT-TIME,<Connect> ;;CONNECT TIME OF JOB
XX 15,DSK,4,CTRL,CONTROLLER,<Ctrl> ;;DISK CONTROLLER
XX 60,JOB,5,CPU,CPU-PERCENTAGE,< %CPU> ;;PERCENTAGE OF THE CPU
XX 10,DEV,6,DEVN,DEVICE,<Device> ;;DEVICE
XX 30,DEV,12,DEVC,DEVICE-DESIGNATOR,< Designator> ;;DESIGNATOR
XX 20,DEV,5,DEVJ,DEVICE-OWNER,<Owner> ;;OWNER OF DEVICE
XX 40,DEV,15,DEVU,DEVICE-USER,< User> ;;USER OF DEVICE
XX 0,JOB,20,CDIR,DIRECTORY,<Connected directory> ;;DIRECTORY
XX 90,DSK,25,USTS,DISK-STATUS,<Disk status> ;;STATUS
XX 20,EQQ,3,QJOB,ENQ-BLOCK-CREATOR,<Job> ;;JOB WHICH MADE BLOCK
XX 25,EQQ,6,QPRG,ENQ-PROGRAM,< Prog> ;;PROGRAM NAME
XX 30,EQQ,7,QFLG,ENQ-STATUS,<Status> ;;QUEUE BLOCK STATUS
XX 60,FIL,140,FILE,FILE-NAME,< File name> ;;FILE NAME OF JFN
XX 40,FIL,10,BYTE,FILE-POINTER,<Pointer> ;;CURRENT FILE POINTER
XX 50,FIL,14,FSTA,FILE-STATUS,<Status> ;;STATUS OF JFN
XX 30,IPC,10,PIDF,FLAGS-FOR-PID,<Flags> ;;FLAGS
XX 80,TTY,25,TFLG,FLAGS-FOR-TERMINAL,<Flags> ;;TERMINAL FLAGS
XX 0,DLL,11,FLOW,FLOW-STATUS,<Flow status> ;;FLOW CONTROL
XX 15,ANC,11,ACFS,FOREIGN-SOCKET,<Foreign soc> ;;FOREIGN SOCKET
XX 10,FRK,3,FORK,FORK,<Frk> ;;THE FORK NUMBER
XX 0,FRK,5,FFLG,FORK-FLAGS,<Flags> ;;FORK FLAGS
XX 80,FRK,10,RUN,FORK-RUNTIME,< Runtime> ;;RUNTIME OF FORK
XX 50,FRK,10,STAT,FORK-STATUS,<Status> ;;THE STATUS OF THE FORK
XX 0,JOB,5,FKS,FORKS-IN-JOB,<Forks> ;;NUMBER OF FORKS
XX 30,EQL,10,LRES,FREE-LOCKS,<Free locks> ;;FREE LOCKS LEFT
XX 40,STR,6,STPG,FREE-PAGES,< Free> ;;NUMBER OF FREE PAGES
XX 20,ANH,15,ANAM,HOST-NAME,<Host name> ;;NAME OF HOST
XX 10,ANH,11,AHST,HOST-NUMBER,<Host number> ;;HOST NUMBER
XX 50,ANH,30,ASTS,HOST-STATUS,<Status> ;;HOST STATUS
XX 40,ANH,14,ATYP,HOST-TYPE,<System type> ;;TYPE OF HOST
XX 70,JOB,6,IDLE,IDLE-TIME,< Idle> ;;IDLE TIME
XX 30,FIL,3,INIF,INITIALIZING-FORK,<Frk> ;;FORK WHICH STARTED JFN
XX 40,TTY,3,TINC,INPUT-CHARACTERS,< In> ;;CHARS IN INPUT
XX 0,FRK,5,INTD,INTERRUPT-DEFER-COUNT,<INTDF> ;;INTERRUPT DEFER
XX 10,FIL,3,JFN,JFN,<JFN> ;;JFN OF FILE
XX 10,JOB,3,JOB,JOB,<Job> ;;JOB NUMBER
XX 40,FRK,9,CALL,LAST-CALL,<Last call> ;;THE LAST JSYS DONE
XX 0,FRK,25,LERR,LAST-ERROR,< Last error> ;;LAST ERROR IN FORK
XX 40,EQL,6,LLVL,LEVEL-OF-LOCK,<Level> ;;LOCK LEVEL
XX 0,DLL,4,LKFK,LINK-FORK-OWNER,<Fork> ;;FORK OWNER OF LINK
XX 0,DLL,7,LKID,LINK-ID,<Link ID> ;;LINK ID
XX 10,DLL,3,LKJB,LINK-JOB-OWNER,<Job> ;;OWNER OF LINK
XX 20,DLL,7,LPRG,LINK-PROGRAM,<Program> ;;PROGRAM NAME FOR LINK
XX 70,DLL,9,LSTA,LINK-STATE,<State> ;;STATE
XX 30,DLL,7,LKTP,LINK-TYPE,< Type> ;;TYPE OF I/O
XX 90,DLL,15,LUSR,LINK-USER,< User> ;;USER
XX 0,JOB,15,LINK,LINKED-TERMINALS,<Links to TTY> ;;TERMINAL LINKS
XX 10,ANC,11,ACLS,LOCAL-SOCKET,<Local soc> ;;SOCKET NUMBER
XX 10,EQL,4,LLCK,LOCK-NUMBER,<Lock> ;;ENQ LOCK NUMBER
XX 0,FRK,24,CORE,MAPPED-PAGES,<Mapped pages> ;;PAGE MAP
XX 0,FRK,10,MPC,MONITOR-PC,<Monitor PC> ;;THE MONITOR PC
XX 20,STR,5,STMC,MOUNT-COUNT,<Mount> ;;NUMBER OF MOUNTS
XX 0,ANC,9,ABTA,NCP-BIT-ALLOCATION,<Bit alloc> ;;ALLOCATION OF BITS
XX 30,ANC,10,ACBT,NCP-BITS-TRANSFERED,<Bits trans> ;;BITS SENT
XX 40,ANC,15,ACFH,NCP-FOREIGN-HOST,<Foreign host> ;;HOST
XX 0,ANC,9,AMSA,NCP-MESSAGE-ALLOC,<Msg alloc> ;;ALLOCATION OF MSGS
XX 20,ANC,3,ACVT,NCP-NVT,<NVT> ;;NETWORK VIRTUAL TERMINAL
XX 50,ANC,5,ASTE,NCP-STATE,<State> ;;STATE OF NCP CONNECTION
XX 50,DSK,4,LUNT,NUMBER-OF-PACK,<Pack> ;;PACK NUMBER
XX 10,TTY,3,TNUM,NUMBER-OF-TERMINAL,<TTY> ;;TERMINAL
XX 40,DLL,6,LOBJ,OBJECT-NAME,<Object> ;;OBJECT NAME
XX 20,FIL,7,OFN,OFN,< OFN> ;;THE OFNS OF THE FILE
XX 0,ANC,22,APRS,OLD-NSP-STATES,<Previous states> ;;OLD STATES
XX 30,STR,5,STOF,OPEN-FILE-COUNT,<Files> ;;NUMBER OF FILES OPEN
XX 50,TTY,3,TOUC,OUTPUT-CHARACTERS,<Out> ;;CHARS IN OUTPUT
XX 10,IPC,3,PIDJ,OWNER-OF-PID,<Job> ;;JOB WHICH OWNS PID
XX 20,TTY,3,TJOB,OWNER-OF-TERMINAL,<Job> ;;JOB OWNING TTY
XX 10,EQQ,4,QLCK,OWNING-LOCK,<Lock> ;;LOCK WHICH OWNS QUEUE
XX 0,IPC,7,RECC,PACKETS-TO-READ,<Packets> ;;NUMBER OF PACKETS
XX 0,FRK,12,TRPC,PAGE-TRAP-PC,<Page trap PC> ;;PC OF PAGE TRAPS
XX 60,FRK,6,TRAP,PAGE-TRAPS,<Ptraps> ;;NUMBER OF PAGE TRAPS
XX 30,FRK,10,UPC,PC,< User PC> ;;THE CURRENT USER PC
XX 20,IPC,13,PID,PID,< PID> ;;THE PID
XX 15,IPC,4,POWN,PID-FORK,<Fork> ;;FORK WHICH CREATED PID
XX 50,IPC,20,PNAM,PID-NAME,< Name> ;;NAME OF PID
XX 17,IPC,6,PPRG,PID-PROGRAM,< Prog> ;;PROGRAM RUNNING
XX 0,FRK,5,PRIV,PRIVILEGES,<Privs> ;;PRIVILEGES OF FORK
XX 30,JOB,7,PROG,PROGRAM,<Program> ;;PROGRAM NAME
XX 0,IPC,9,PQTA,QUOTAS,< Quotas> ;;SEND, RECEIVE QUOTAS
XX 0,DSK,12,RDER,READ-ERRORS,<Read errors> ;;NUMBER OF READ ERRORS
XX 70,DSK,8,READ,READS,< Reads> ;;DISK READS
XX 60,DLL,6,LHST,REMOTE-HOST-NAME,<Host> ;;REMOTE HOST
XX 0,DLL,9,LKIR,REMOTE-ID,<Remote ID> ;;REMOTE ID
XX 50,EQQ,10,QID,REQUEST-ID,<Request ID> ;;REQUEST ID
XX 50,JOB,9,JRUN,RUNTIME,< Runtime> ;;RUNTIME OF JOB
XX 0,JOB,5,JCLS,SCHEDULER-CLASS,<Class> ;;SCHEDULER CLASS
XX 0,FRK,16,SCHD,SCHEDULER-TEST,<Scheduler test> ;;FKSTAT WORD
XX 0,DSK,12,PSER,SEEK-ERRORS,<Seek errors> ;;NUMBER OF SEEK ERRORS
XX 60,DSK,8,SEEK,SEEKS,< Seeks> ;;DISK SEEKS
XX 45,STR,6,STSZ,SIZE-OF-STRUCTURE,< Size> ;;SIZE
XX 0,TTY,11,TSPD,SPEEDS,<Line speeds> ;;SPEED OF LINE
XX 40,JOB,5,JSTA,STATE,<State> ;;STATE JOB IS IN
XX 10,STR,9,STNM,STRUCTURE,<Structure> ;;STRUCTURE NAME
XX 50,STR,40,STST,STRUCTURE-STATUS,<Structure status> ;;STATUS
XX 20,FRK,3,SUP,SUPERIOR,<Sup> ;;THE SUPERIOR OF THE FORK
XX 0,DSK,8,SWAP,SWAPPING-SPACE,<Swapping> ;;SWAPPING SPACE
XX 40,IPC,10,SYSP,SYSTEM-PID,<System PID> ;;THE SYSTEM PID
XX 0,DLL,6,LTSK,TASK-NAME,<Task> ;;NAME OF TASK
XX 20,JOB,8,TERM,TERMINAL,<Terminal> ;;TERMINAL JOB IS ON
XX 50,EQL,13,LTIM,TIME-LOCK-OBTAINED,<Time locked> ;;TIME
XX 80,DLL,10,LSEG,TRANSMIT-RECEIVE-SEGMENT,<Trans Recv> ;COUNTERS
XX 70,TTY,15,TLNK,TTY-LINKS,<Links to TTY> ;;LINKS
XX 25,TTY,15,TUSR,TTY-USER,< User> ;;USER ON A TERMINAL
XX 0,DSK,4,TYPE,TYPE-OF-DISK,<Type> ;;TYPE OF DISK
XX 20,EQL,11,LTYP,TYPE-OF-LOCK,<Restriction> ;;TYPE OF ENQ LOCK
XX 30,TTY,9,TTYP,TYPE-OF-TERMINAL,<Type> ;;TERMINAL TYPE
XX 20,DSK,4,UNIT,UNIT,<Unit> ;;DISK UNIT
XX 80,JOB,15,USER,USER-NAME,< User> ;;USER NAME
XX 40,DSK,6,STR,VOLUME-ID,<Vol ID> ;;THE VOLUME NAME
XX 70,FRK,7,WSIZ,WORKING-SET-SIZE,<WS size> ;;WORKING SET SIZE
XX 0,DSK,12,WTER,WRITE-ERRORS,<Write errors> ;;WRITE ERRORS
XX 80,DSK,8,WRIT,WRITES,< Writes> ;;DISK WRITES
>
DEFINE XX(ORD,TYP,SIZE,DISP,NAME,HEAD),<
XWD [ASCIZ/NAME/],[ EXP TP.'TYP ;TYPE OF COLUMN
IFE <^D<ORD>>,< EXP 0> ;ORDERING DATA
IFN <^D<ORD>>,< XWD TP.'TYP,^D<ORD>>
EXP XX'DISP ;DISPATCH ADDRESS
EXP ^D<SIZE> ;WIDTH OF COLUMN
ASCIZ "HEAD"] ;HEADER TEXT
>
COLTAB: XWD COLNUM,COLNUM ;NUMBER OF ENTRIES
COLS ;EXPAND THE TABLE
COLNUM==.-COLTAB-1 ;NUMBER OF COLUMNS
SUBTTL DEFINITIONS OF THE STATISTICS
;TABLE OF ENTRIES TO BE TYPED. THE IMBEDDED XX MACRO HAS THE FOLLOWING
;ARGUMENTS:
;
; XX NAME,ROUTINE,INDEX
;
;WHERE NAME IS THE NAME OF THIS DATA (4 OR LESS LETTERS TO LOOK GOOD),
;ROUTINE IS THE CODE TO TYPE OUT THE DATA, AND INDEX IS THE INDEX INTO
;THE GETAB TABLE CONTAINING THE DATA.
DEFINE STATS,<
XX USED,DOPCT,32 ;;USED TIME AS PERCENTAGE
XX NRUN,DOAVG,13 ;;AVERAGE NUMBER OF RUNNABLE FORKS
XX DMRD,DODIF,4 ;;NUMBER OF DRUM READS
XX TTIN,DODIF,21 ;;NUMBER OF TERMINAL INPUT CHARACTERS
XX IDLE,DOPCT,0 ;;IDLE TIME AS PERCENTAGE
XX NBAL,DOAVG,12 ;;AVERAGE NUMBER OF FORKS IN BALANCE SET
XX DMWR,DODIF,5 ;;NUMBER OF DRUM WRITES
XX TTOU,DODIF,22 ;;NUMBER OF TERMINAL OUTPUT CHARACTERS
XX SWPW,DOPCT,1 ;;SWAP-WAIT TIME AS PERCENTAGE
XX BSWT,DOAVG,26 ;;AVERAGE NUMBER OF FORKS WAITING
XX DKRD,DODIF,6 ;;NUMBER OF DISK READS
XX WAKE,DODIF,10 ;;NUMBER OF PROCESS WAKEUPS
XX SKED,DOPCT,2 ;;SCHEDULAT OVERHEAD TIME AS PERCENTAGE
XX UPGS,DOAVG,37 ;;AVERAGE NUMBER OF PAGES IN BALANCE SET
XX DKWR,DODIF,7 ;;NUMBER OF DISK WRITES
XX TTCC,DODIF,11 ;;NUMBER OF TERMINAL INTERRUPTS
>
;NOW EXPAND THE TABLE PROPERLY:
DEFINE XX(NAME,ROUTINE,INDEX),<
XWD INDEX,[ASCIZ/NAME/]
>
XALL ;LET EXPANSION SHOW
STATTB: STATS ;GENERATE THE TABLE
STATNM==.-STATTB ;NUMBER OF ENTRIES
;NOW PRODUCE THE TABLE OF ROUTINES:
DEFINE XX(NAME,ROUTINE,INDEX),<
EXP ROUTINE ;CODE TO HANDLE NAME
>
STATCD: STATS ;GENERATE THE TABLE
SALL ;RETURN TO NORMAL LISTING
SUBTTL TABLE OF JSYSES AND UUOS
;THE FOLLOWING TABLE OF JSYSES IS PRODUCED BY EXPANDING THE
;MACRO DEFJS DEFINED IN UUOSYM. UNUSED JSYSES JUST STAY ZERO.
JSTABL: ;TABLE OF JSYS NAMES
IF1,< DEFINE DEFJS(NAME,NUMBER,FLAGS,EXTRA1,EXTRA2),<
JSYSMX==NUMBER ;;JUST FIND LAST DEFINED JSYS
>
JSLIST ;DO THE WORK
BLOCK JSYSMX+1 ;ALLOCATE SPACE FOR THE TABLE
>
IF2,< DEFINE DEFJS(NAME,NUMBER,FLAGS,EXTRA1,EXTRA2),<
XLIST ;;TURN OFF LISTING
IFG <NUMBER-JSYSMX>,<
BLOCK NUMBER-JSYSMX
> ;;LEAVE ROOM FOR GAPS
EXP SIXBIT/NAME/ ;;GENERATE THIS JSYS NAME
JSYSMX==NUMBER+1 ;;MOVE UP TO NEXT JSYS VALUE
LIST ;;RESUME LISTING
>
JSYSMX==0 ;INITIALIZE JSYS NUMBER
JSLIST ;GENERATE THE TABLE
>
UUOTAB: ;TABLE OF UUO NAMES
UU <CALL,INIT,UUO42,UUO43,UUO44,UUO45,UUO46,CALLI >
UU <OPEN,TTCALL,UUO52,UUO53,UUO54,RENAME,IN,OUT>
UU <SETSTS,STATO,GETSTS,STATZ,INBUF,OUTBUF,INPUT,OUTPUT>
UU <CLOSE,RELEAS,MTAPE,UGETF,USETI,USETO,LOOKUP,ENTER>
UU <UJEN>
TTCTAB: UU <INCHRW,OUTCHR,INCHRS,OUTSTR,INCHWL,INCHSL,GETLCH,SETLCH>
UU <RESCAN,CLRBFI,CLRBFO,SKPINC,SKPINL,TTCALL,TTCALL>
SUBTTL SYMBOLS TO BE SNOOPED FOR DISK STATISTICS
XALL ;LET EXPANSIONS SHOW
DEFINE XX(SYM,MOD<PHYSIO>),<
RADIX50 0,SYM ;;DEFINE RADIX50 VALUE OF SYMBOL
>
TBSUDB: USYMS ;TABLE OF SYMBOLS
NUMUDB==.-TBSUDB ;NUMBER OF SYMBOLS
DEFINE XX(SYM,MOD<PHYSIO>),<
RADIX50 0,MOD ;;PROGRAM NAME TO FIND SYMBOL IN
>
TBMUDB: USYMS ;TABLE OF PROGRAM NAMES
DEFINE XX(SYM,MOD<PHYSIO>),<
SYM: EXP 0 ;;DEFINE LOCATION FOR VALUE TO GO
>
TBVUDB: USYMS ;TABLE OF VALUES TO FILL IN
SALL ;RETURN TO NORMAL
SUBTTL ERROR CODE MNEMONICS
;THE FOLLOWING TABLE IS GENERATED BY EXPANDING THE .ERCOD MACRO
;IN MONSYM. IN PASS1, WE SIMPLY LOOK FOR THE HIGHEST ERROR CODE.
;IN PASS2, WE GENERATE THE TABLE.
IF1,<
DEFINE .ERR(NUMBER,NAME,TEXT),<
IFG <NUMBER-MAXERR>,<MAXERR==NUMBER>
>
MAXERR==0 ;START OFF HIGHEST ERROR NUMBER
.ERCOD ;EXPAND ERROR MACRO
ERRS: BLOCK MAXERR+1 ;LEAVE ROOM FOR THE ERRORS
>
IF2,<
DEFINE .ERR(NUMBER,NAME,TEXT),<
XLIST
RELOC ERRS+NUMBER
SIXBIT /NAME/
LIST
>
ERRS: .ERCOD ;GENERATE THE ERROR TABLE
RELOC ERRS+MAXERR+1 ;THEN RELOCATE TO PROPER PLACE
>
SUBTTL DATA STORAGE
LEVTAB: EXP CHNPC1 ;PLACE TO STORE PC
BLOCK 2 ;OTHER LEVELS UNUSED
CHTAB: XWD 1,TTYINT ;LEVEL 1, INTERRUPT ROUTINE
BLOCK .ICIFT-1 ;UNUSED CHANNELS
XWD 1,FRKINT ;LEVEL 1, INTERRUPT ROUTINE
BLOCK ^D36-.ICIFT ;OTHER CHANNELS UNUSED
;POINTERS TO THE RUNTIMES
XX==0 ;START OFF COUNTER AT ZERO
OLDRUN: REPEAT CPUAVG,<
Z RUNTIM+<XX*MAXJOB>(J)
XX==XX+1
>
;MESSAGE TO BE SENT TO QUASAR FOR QUEUE LISTING:
QSRMSG: XWD QSRLEN,.QOLIS ;TYPE OF FUNCTION AND LENGTH
XWD 0,'SYS' ;FLAGS AND 3 LETTER MNENOMIC
EXP 0 ;ACKNOWLEDGE WORD
QSRFL2: EXP 0 ;FLAGS FILLED IN LATER
EXP 1 ;ONE ARGUMENT BLOCK FOLLOWING
XWD 2,.LSQUE ;QUEUE BLOCK
QSRFL1: EXP 0 ;WHICH QUEUES TO LIST, FILLED IN LATER
QSRLEN==.-QSRMSG ;SIZE OF PACKET
;MESSAGE SENT TO SYSTEM INFO TO OBTAIN NAME OF A PID:
INFMSG: EXP .IPCIG ;FUNCTION TO RETURN NAME OF A PID
EXP 0 ;NO COPIES OF THE RESPONSE
INFDAT: EXP 0 ;FILLED IN LATER
PDL: BLOCK PDLSIZ ;STACK AREA
KWNJOB: BLOCK 1 ;JOB NUMBER A FORK BELONGS TO
LCLNOD: BLOCK 5 ;LOCAL NODE NAME
PCFLAG: BLOCK 1 ;THE PC FLAGS OF A FORK
PC: BLOCK 1 ;THE CURRENT PC OF A FORK
USERPC: BLOCK 1 ;THE USER MODE PC OF A FORK
HAVPC: BLOCK 1 ;SET IF PC STUFF IS AVAILABLE
HAVID: BLOCK 1 ;SET IF ID INFORMATION IS KNOWN
HAVALC: BLOCK 1 ;SET IF HAVE ALLOCATION INFO
STRALC: BLOCK 2 ;ALLOCATION INFORMATION
TTJBVL: BLOCK 1 ;TERMINAL TO JOB WORD IF NONNEGATIVE
JOBFRK: BLOCK 1 ;JOB FORK NUMBER WE ARE ON
FORK: BLOCK 1 ;SYSTEM FORK NUMBER WE ARE ON
THETTY: BLOCK 1 ;TERMINAL NUMBER DOING SINGLE DISPLAY ON
THEJOB: BLOCK 1 ;JOB NUMBER DOING SINGLE DISPLAY ON
TXTPTR: BLOCK 1 ;ADDRESS IN JSB OF ASCII TEXT
TXTMAX: BLOCK 1 ;MAXIMUM NUMBER OF WORDS IN STRING
TXTCTR: BLOCK 1 ;COUNTER INTO WHICH WORD OF TEXT WE ARE ON
JFNOFF: BLOCK 1 ;OFFSET INTO JSB OF A JFN BLOCK
JFN: BLOCK 1 ;JFN WE ARE TYPING OUT
TXTTMP: BLOCK 1 ;TEMPORARY WORD
SNPVAL: BLOCK 1 ;VALUE OF .SNOOP SYMBOL
MONADR: BLOCK 1 ;ADDRESS IN MONITOR OF SNOOP PAGE
TIMES: BLOCK CPUAVG ;TIMES DATA IN EACH TABLE WAS COMPUTED
RUNTIM: BLOCK MAXJOB*CPUAVG ;TABLE OF COLLECTED RUNTIMES
CURRUN: BLOCK MAXJOB ;CURRENT RUNTIMES OF THE JOBS
CLSTAB: BLOCK MAXJOB ;SCHEDULER CLASS EACH JOB IS IN
CLSNUM: BLOCK MAXCLS+1 ;NUMBER OF JOBS IN EACH CLASS
HANDLE: BLOCK 1 ;FORK HANDLE OF INFERIOR FORK
DEVUNT: BLOCK 1 ;JOB AND UNIT NUMBERS FOR A DEVICE
COLUMN: BLOCK 1 ;COLUMN COUNTER
REFLST: BLOCK 1 ;TIME OF LAST REFRESH
REFTIM: BLOCK 1 ;NUMBER OF MINUTES BETWEEN REFRESHES
SKPJFN: BLOCK 1 ;NUMBER OF JFNS TO BE SKIPPED
SKPFRK: BLOCK 1 ;NUMBER OF FORKS TO BE SKIPPED
CHNPC1: BLOCK 1 ;PC ON AN INTERRUPT
TTYFLG: BLOCK 1 ;USED TO STOP SLEEPS WHEN TTY COMMANDS TYPED
FRKFLG: BLOCK 1 ;USED TO STOP SLEEPS WHILE WAITING FOR EXEC
MAXIDL: BLOCK 1 ;MAXIMUM IDLE TIME FOR SHOWN JOBS
MAXIDF: BLOCK 1 ;FLAG FOR WHICH IDLE CUTOFF IS DONE
INTCNT: BLOCK 1 ;NUMBER OF CHARS IN INTERRUPT BUFFER
INTPTR: BLOCK 1 ;BYTE POINTER INTO BUFFER FOR INTERRUPT CODE
HLPJFN: BLOCK 1 ;JFN FOR HELP FILE
SBLK: BLOCK .MSRBT+1 ;ARGUMENT BLOCK FOR MSTR
STRUC: BLOCK 2 ;STRUCTURE NAME
ALIAS: BLOCK 2 ;ALIAS NAME
UDB: BLOCK UDBSIZ ;BLOCK FOR READING UDB INTO
CHAN: BLOCK 1 ;CHANNEL NUMBER UDB IS OF
CTRL: BLOCK 1 ;CONTROLLER NUMBER UDB IS OF
UNIT: BLOCK 1 ;UNIT NUMBER UDB IS OF
COLTYP: BLOCK 1 ;FOR HELP OUTPUT
COLDIS: BLOCK 1 ;FOR LOOPING THROUGH DISPLAYED COLUMNS
COLSUP: BLOCK 1 ;FOR LOOPING THROUGH SUPPRESSED COLUMNS
LSTTYP: BLOCK 1 ;LAST TYPE OF COLUMN TYPED OUT
HLPDSP: BLOCK 1 ;DISPATCH FOR SPECIAL HELP
COLHLC: BLOCK 1 ;AOBJN POINTER TO DISPLAYS TO GIVE HELP ON
PAGTIM: BLOCK 1 ;TIME AT WHICH NEXT SCROLLING IS DONE
PAGINT: BLOCK 1 ;AUTOMATIC SCROLLING INTERVAL
LNKNUM: BLOCK 1 ;NUMBER OF LOGICAL LINKS TO TYPE OUT
BEGTIM: BLOCK 1 ;UNIVERSAL TIME SYSTEM STARTED
INTBUF: BLOCK 1 ;BUFFER IN USE BY INTERRUPT CODE
RUNPTR: BLOCK 1 ;BYTE POINTER INTO BUFFER FOR RUNTIME CODE
SAVCHR: BLOCK 1 ;LAST CHARACTER READ OF A COMMAND
TAKJFN: BLOCK 1 ;JFN OF INDIRECT FILE
TAKLVL: BLOCK 1 ;DEPTH OF NESTED TAKE COMMANDS
TAKLBL: BLOCK 1 ;LABEL IN TAKE FILE WE'RE LOOKING FOR
TAKPTR: BLOCK TAKMAX+1 ;FILE POINTERS FOR EACH LEVEL OF TAKE FILES
TAKSVC: BLOCK TAKMAX+1 ;SAVED CHARACTERS AND RESCAN FLAG
RUNBUF: BLOCK 1 ;BUFFER IN USE BY RUNTIME CODE
BUFFS: BLOCK BUFNUM ;POINTERS TO TTY BUFFERS
BUFFER: BLOCK BUFNUM*BUFLEN ;BUFFER AREA FOR TTY INPUT
CTYNUM: BLOCK 1 ;TERMINAL NUMBER OF THE CTY
MYJOB: BLOCK 1 ;MY JOB NUMBER
MYUSER: BLOCK 1 ;MY USER NUMBER
MYNAME: BLOCK 1 ;MY PROGRAM NAME
OPRUSR: BLOCK 1 ;THE OPERATOR'S USER NUMBER
VIRGIN: BLOCK 1 ;COUNT OF TRIES TO GET MONITOR SYMBOLS
SLPTIM: BLOCK 1 ;TIME TO SLEEP BETWEEN UPDATES
HGHJOB: BLOCK 1 ;HIGHEST JOB SYSTEM HAS
HGHTTY: BLOCK 1 ;HIGHEST TERMINAL NUMBER SYSTEM HAS
TTYSTS: BLOCK 1 ;STATUS WORD OF A TERMINAL
LOKNUM: BLOCK 1 ;NUMBER OF CURRENT ENQ LOCK BEING DONE
ENQNUM: BLOCK 1 ;NUMBER OF CURRENT ENQ QUEUE BLOCK
LSTNUM: BLOCK 1 ;LAST LOCK NUMBER OUTPUT
PIDTAB: BLOCK IPCSIZ ;STORAGE FOR PIDS OF A JOB
PIDJOB: BLOCK 1 ;JOB NUMBER READING PIDS OF
OLDJOB: BLOCK 1 ;PREVIOUS JOB WE PROCESSED
LOKTAB: BLOCK LCKMAX ;STORAGE FOR ENQ BLOCK POINTERS
BLK: BLOCK .JISTM+1 ;DATA FROM GETJI JSYS
TEMP: BLOCK TMPSIZ ;TEMPORARY STRING STORAGE
USERS: BLOCK USRSIZ ;LINKED LIST OF USERS TO SHOW
USRLST: BLOCK 1 ;ADDRESS OF FIRST USER TO SHOW
USRFRE: BLOCK 1 ;FIRST FREE WORD IN USERS ARRAY
BITS: BLOCK <MAXJOB/^D36>+1 ;BITS TO SUPPRESS SHOWING OF JOBS
NTIME: BLOCK 1 ;CURRENT UNIVERSAL FORMAT TIME
ACTTAB: BLOCK MAXTTY+1 ;TABLE OF ACTIVE TIMES FOR TERMINALS
IDLE: BLOCK MAXJOB ;NUMBER OF MINUTES OF IDLE TIME
ORUNTM: BLOCK MAXJOB ;OLD RUNTIMES OF JOBS
RUNDIF: BLOCK MAXJOB ;PERCENTAGE OF CPU TIME A JOB HAS USED
TIMDIF: BLOCK 1 ;TIME INTERVAL CPU TABLE USES
OTIME: BLOCK 1 ;TIME THAT OLD RUNTIMES WERE COMPUTED
TIMRUN: BLOCK MAXJOB ;TIMES THAT RUNTIMES CHANGED
OLDSTA: BLOCK STATNM ;OLD VALUES OF STATISTICS
OLDTIM: BLOCK 1 ;UPTIME THEY WERE COMPUTED
PAGE: BLOCK 1 ;PAGE NUMBER OF OUTPUT WE ARE ON
OLDPAG: BLOCK 1 ;SAVED VALUE OF PAGE WHILE SHOWING HELP
OVRLAP: BLOCK 1 ;NUMBER OF LINES OF OVERLAP WANTED
DEVNAM: BLOCK 2 ;DEVICE NAME BEING GRUNGED ON
NEWSTA: BLOCK STATNM ;NEW VALUES OF STATISTICS
NEWTIM: BLOCK 1 ;UPTIME THEY WERE COMPUTED
STADIF: BLOCK 1 ;DIFFERENCE BETWEEN OLDTIM AND NEWTIM
KBLK: BLOCK 10 ;BLOCK FOR CLASS SCHEDULER DATA
HDRTXT: BLOCK ^D50 ;TEXT OUTPUT AS HEADER
HDRPTR: BLOCK 1 ;BYTE POINTER INTO HEADER TEXT
HDRPOS: BLOCK 1 ;COLUMN POSITION WE ARE AT
HDRTYP: BLOCK 1 ;CURRENT TYPE OF HEADER
COLSEP: BLOCK DISNUM+1 ;SEPARATION TO USE BETWEEN COLUMNS
COLTBS: BLOCK 4 ;TAB STOPS FOR THIS OUTPUT
EATNUM: BLOCK 1 ;NUMBER OF LINES TO EAT
IDPGS: BLOCK 1 ;TOTAL PAGES IN USE BY A FORK
IDPAG: BLOCK 1 ;CURRENT PAGE OF FORK WE ARE LOOKING AT
IDNUM: BLOCK 1 ;NUMBER OF IDENTITIES IN TABLE
IDYNM: BLOCK 1 ;NUMBER OF IDENTITIES LEFT TO TYPE
TXTBUF: BLOCK TXTLEN ;STORAGE FOR CPYTXT ROUTINE
CURCOL: BLOCK 1 ;CURRENT COLUMN BEING OUTPUT
NXTCOL: BLOCK 1 ;NEXT COLUMN TO BE OUTPUT
COLDSP: BLOCK COLNUM+1 ;COLUMN OUTPUT DISPATCHES
ORDMIN: BLOCK 1 ;MINIMUM COLUMN NUMBER TO ALLOW
ORDVAL: BLOCK 1 ;CURRENT BEST VALUE FOR COLUMN
ORDHAV: BLOCK 1 ;WHICH COLUMN IS CURRENTLY BEST
ORDIDX: BLOCK 1 ;COUNTER THROUGH COLUMNS
QSRPID: BLOCK 1 ;PID OF QUASAR
MYPID: BLOCK 1 ;MY PID
INFPID: BLOCK 1 ;PID OF SYSTEM INFO
APANUM: BLOCK 1 ;ARPANET HOST NUMBER
APASTS: BLOCK 1 ;HOST STATUS. MUST FOLLOW APANUM!
PIDSYS: BLOCK PIDNUM ;TABLE OF SYSTEM PIDS
PRGWLD: BLOCK PRGMAX*2 ;STORAGE FOR PROGRAM NAMES TO SHOW
PRGNUM: BLOCK 1 ;NUMBER OF PROGRAM NAMES TO CHECK
MBLK: BLOCK 10 ;ARGUMENT BLOCK FOR IPCF JSYSES
ABLK: BLOCK .NCSTS+1 ;ARGUMENT BLOCK FOR ARPANET CONNECTIONS
MONSYV: BLOCK MAXSYM ;TABLE OF VALUES OF SYMBOLS
MONSYS: BLOCK MAXSYM ;TABLE OF SYMBOLS
MONSYO: BLOCK MAXSYM ;TABLE OF OFFSETS
MONSYC: BLOCK 1 ;NUMBER OF SYMBOLS IN TABLE
IDVALS: BLOCK 1000 ;TABLE OF IDENTITES OF FORK PAGES
IDCNTS: BLOCK 1000 ;NUMBER OF TIMES EACH IDENTITY WAS USED
RESDAT: BLOCK 2 ;DATA RETURNED ABOUT RESIDENT SPACE
ERRTOT: BLOCK 1 ;COUNTER FOR AGING ERROR CODES
ERRCNT: BLOCK 1 ;NUMBER OF ERROR CODES KNOWN
ERRCOD: BLOCK ERRNUM ;THE ERROR CODES WHICH ARE KNOWN
ERRAGE: BLOCK ERRNUM ;THE AGES OF EACH ERROR CODE
ERRTAB: BLOCK ERRNUM*ERRSIZ ;STRING STORAGE FOR THE ERRORS
END 3,,ENTRY ;ENTRY VECTOR