;USR0:SYSDPY.MAC.3 27-Mar-86 FM+2D.18H.34M.24S., by BUDD ; merge in 6.1 SYSDPY ARPA/ARP displays ;SYSDPY.MAC.3 16-Nov-85 NM+4D.16H.36M.47S., by BUDD ; add sun, adm3a, glass ;<5-4-SUBSYS>SYSDPY.MAC.2 10-Oct-85 LQ+4D.9H.51M.26S., by BUDD ; Add new terminal types ;USR0:SYSDPYX.MAC.23 4-Feb-85 FM+4H.6M.32S., by BUDD ; Print out FORKs indented tastefully ;**************************************************************** ;SYSDPY.MAC.3, 3-Jan-83 23:29:24, Edit by PAETZOLD ;547 - Make this 5.3 ;SYSDPY.MAC.2, 19-Dec-82 13:04:14, Edit by PAETZOLD ;546 - Remove monitor edit number check from CHKFRK in MONRD ; UPD ID= 6, SNARK:<5.TOOLS-TAPE>SYSDPY.MAC.9, 31-Mar-82 14:57:33 by PURRETTA ;545 - TCO 5.1770 - Replace symbol references of UDBDDP with UDBDDD ; UPD ID= 2, SNARK:<5.TOOLS-TAPE>SYSDPY.MAC.6, 14-Oct-81 15:19:53 by PAETZOLD ;544 - Suppress available nodes (in DN display) if suppressing titles ; UPD ID= 1, SNARK:<5.TOOLS-TAPE>SYSDPY.MAC.5, 30-Sep-81 14:51:28 by GRANT ;543 - LL block ;SYSDPY.MAC.2, 21-Sep-81 10:52:43, EDIT BY GRANT ;542 - LL block growing again ;<5.TOOLS-TAPE>SYSDPY.MAC.2, 26-May-81 17:50:53, EDIT BY GRANT ;541 - LL block still growing, fix LLLIST ;SYSDPY.MAC.2, 24-Apr-81 13:23:22, EDIT BY GRANT ;540 - Add new LL state "CC sent" ;SYSDPY.MAC.20, 13-Apr-81 09:18:35, EDIT BY GRANT ;537 - Add new DECnet object types ; Rewrite XXLHST to reflect new DECnet information ; Change LLLIST to reflect new DECnet data structure ;SNARK:SYSDPY.MAC.2 12-Mar-81 11:10:50, Edit by LYONS ;536 - Fix some of the bugs in the "re" display ; Get rid if the "unused pool" line ; Expand the "used" field to 5 digits. Some people use more ; than 10000 pages of drum space. ;SNARK:<5.UTILITIES>SYSDPY.MAC.13 19-Feb-81 12:51:49, Edit by LYONS ;535 - Add a DECSW to control DEC only features ; Put slow down prohibit under this switch ;<5.UTILITIES>SYSDPY.MAC.12, 24-Dec-80 11:47:41, EDIT BY GRANT ;534 - DECnet logical link block has changed - LLSOB now word 25 ;SNARK:<5.UTILITIES>SYSDPY.MAC.9, 22-Dec-80 14:57:27 by GRANT ;533 - Fix the resident free space output in the RES command ;SYSDPY.MAC.5, 7-Oct-80 13:38:06, Edit by LYONS ;532 - Add the "RP" command for Run time Percentage ;SYSDPY.MAC.3, 8-Sep-80 12:43:07, Edit by LYONS ;531 - Increase max sleep time to 3 min, start after 1 min, and slow ; down faster. ; Also, slow down default display speed to 15 seconds ; Allow a refresh every 30 min by default ; Bump number of terminals to 300 from 178 ; Move data pages up some, get rid of overlaps ;SYSDPY.MAC.2, 27-Aug-80 11:55:23, Edit by LYONS ;530 - Report quotas as +INF if the are ;SYSDPY.MAC.2, 31-Jul-80 16:05:36, Edit by LYONS ;527 - SHIFT THE INDEX FOR FREE CORE BLOCKS AND FLAG TYPE 0 AS UNUSED ;<4.1.UTILITIES>SYSDPY.MAC.34, 24-May-80 22:22:48, EDIT BY DBELL ;526 - TELL ABOUT DOWNTIME IN INFORMATION LINE ;<4.1.UTILITIES>SYSDPY.MAC.30, 22-May-80 12:19:13, EDIT BY DBELL ;525 - DON'T SHOW SECONDS IN INFORMATION LINE ;524 - REMOVE TITLE LINE FOR HELP DISPLAY, ENFORCE INFO LINE FOR IT ;<4.1.UTILITIES>SYSDPY.MAC.29, 21-May-80 17:05:34, EDIT BY DBELL ;523 - DON'T DO AUTO-SCROLLING FOR HELP DISPLAY ;<4.1.UTILITIES>SYSDPY.MAC.28, 20-May-80 12:18:01, EDIT BY DBELL ;522 - USE FIXOUT ROUTINE INSTEAD OF FLOUT JSYS IN INFORMATION LINE ;<4.1.UTILITIES>SYSDPY.MAC.25, 18-May-80 20:37:16, EDIT BY DBELL ;521 - EAT LEADING SPACES IN HELP FILE TYPEOUT ;520 - ADD GENERAL INFORMATION LINE TO END OF DISPLAY IF DESIRED ;<4.1.UTILITIES>SYSDPY.MAC.23, 11-May-80 23:43:24, EDIT BY DBELL ;517 - MAKE CPYTXT ROUTINE ALLOW CONTROL-V FOR QUOTING ANY CHARACTER ;516 - MAKE "U" AND "PR" COMMANDS APPEND NAMES INSTEAD OF REPLACING THEM ;<4.1.UTILITIES>SYSDPY.MAC.21, 20-Apr-80 22:26:39, EDIT BY DBELL ;515 - MAKE VERSION OF "A" COMMAND SHOW ONLY ACTIVE ARPANET HOSTS ;514 - IF NO COMMANDS ARE BEING TYPED, SLOW DISPLAY RATE DOWN AFTER AWHILE ;<4.1.UTILITIES>SYSDPY.MAC.19, 12-Apr-80 17:05:18, EDIT BY DBELL ;513 - DON'T DO PHYSICAL ONLY GTJFN FOR DOING PUSH ;<4.1.UTILITIES>SYSDPY.MAC.18, 10-Apr-80 16:42:46, EDIT BY DBELL ;512 - TAKE CARE OF TYPE-AHEAD AFTER EXEC HAS TERMINATED ;<4.1.UTILITIES>SYSDPY.MAC.17, 6-Apr-80 15:08:13, EDIT BY DBELL ;511 - ADD TEMPORARY FEATURE TO SHOW FOREIGN HOST FOR DECNET NRTSRV PROGRAM ;510 - CHANGE IPCSIZ TO NOT CONFLICT WITH GALAXY DEFINITIONS ;<4.1.UTILITIES>SYSDPY.MAC.15, 23-Mar-80 22:45:38, EDIT BY DBELL ;507 - FIX UPTIME IN ARPANET DISPLAY, MAKE IDLE COLUMN LINE UP ;<4.1.UTILITIES>SYSDPY.MAC.12, 16-Mar-80 22:07:16, EDIT BY DBELL ;506 - ADD FOREIGN HOST COLUMN FOR JOB DISPLAY ;<4.1.UTILITIES>SYSDPY.MAC.10, 16-Mar-80 21:30:35, EDIT BY DBELL ;505 - IF CONTROLLED BY JOB ZERO JUST INSERT JSYS AND EXIT ;504 - FIX UP ARPANET DISPLAYS SOME ;<4.1.UTILITIES>SYSDPY.MAC.8, 14-Mar-80 14:15:46, EDIT BY DBELL ;503 - CALL SWPMWE AND SWPMWP WHEN CHANGING JSTAB ;<4.1.UTILITIES>SYSDPY.MAC.7, 15-Feb-80 17:01:22, EDIT BY DBELL ;502 - CHANGE NVT OBJECT TYPE FROM 200 TO 23 ;<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 SEARCH ANADPY ;ANAUNV WITH CONFLICTING MACROS REMOVED .REQUES DPY ;ASK TO LOAD DPY .require sys:macrel SALL ;MAKE FOR NICE MACROS VERSION==5 ;VERSION NUMBER VMINOR==3 EDIT==547 ;EDIT NUMBER VWHO==7 ;[BUDD] ;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 FR.NRT==1B20 ;NRTSRV DATA FILE IS MAPPED INTO CORE IFE DECSW,< FR.NOS==1B21 ;DON'T SLOW DOWN THE UPDATE RATE > FR.AAH==1B22 ;ONLY SHOW ACTIVE ARPANET HOSTS FR.INF==1B23 ;USER WANTS TO SEE INFORMATION LINE FR.ANA==1B26 ;[BUDD] SYMBOLS FOR INTERNET HAVE BEEN OBTAINED FR.HD1==1B27 ;[BUDD] TYPE ONE CRLF AFTER HEADER, NOT TWO ;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, ;;IF NOT DEFINED YET, DO SO NOW > DEFINE STS(BIT,TEXT),< ;;GENERATES FORK STATUS INFORMATION 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),<<&^O777777>> DEFINE PM(PTR),<<<<1_<<_-^D24>&^O77>>-1>_<_-^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 DECSW,-1 ;INCLUDE DEC ONLY FEATURES 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 NRTLOC,350000 ;PAGE WHERE NRTSRV DATA FILE GOES ND DATLOC,351000 ;PAGES FOR COLLECTION OF DATA ND DATSIZ,3000 ;SIZE OF THE BLOCK ND SNPLOC,354000 ;LOCATION OF CODE FOR SNOOP JSYS 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 PIDSIZ,^D100 ;STORAGE FOR PIDS OF A JOB ND LCKMAX,^D100 ;NUMBER OF ENQ LOCKS WE CAN SHOW ND UDBSIZ,^D50 ;SIZE OF BLOCK TO READ UDB INTO ND PDLSIZ,1000 ;[plb] STACK SIZE ND TMPSIZ,^D50 ;SIZE OF TEMPORARY USE BUFFER ND USRSIZ,^D500 ;STORAGE FOR USER NAME STRINGS ND PRGMAX,^D100 ;MAXIMUM NUMBER OF PROGRAM NAMES TO SPECIFY ND PSHSLP,^D30000 ;SLEEP TIME DURING A PUSH ND DWNTIM,^D60 ;MINUTES LEFT FOR SAYING SYSTEM GOING DOWN ND MAXJOB,^D150 ;MAXIMUM JOBS WE CAN HANDLE ND MAXTTY,^D300 ;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,^D15000 ;DEFAULT SLEEP TIME BETWEEN UPDATES ND MAXSLP,^D180000 ;MAXIMUM SLEEP TIME WHEN SLOWING DISPLAY DOWN ND SLWFAC,^D20 ;SECONDS OF ELAPSED TIME PER SECOND OF SLOWING ND SLWGRC,^D60000 ;TIME PERIOD BEFORE SLOWING DOWN DISPLAY ND DFTPAG,0 ;DEFAULT SECONDS BETWEEN SCROLLING ND DFTIDL,.INFIN ;DEFAULT CUTOFF TIME FOR IDLE JOBS ND DFTRPL,^D0 ;BY DEFAULT, SHOW JOBS WITH MORE THAN 0 % CPU USAGE ND DFTREF,^D30 ;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)VWHO(9)VERSION(6)VMINOR(18)EDIT ;[BUDD]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 SETZM DOTFLG ;[BUDD]ARPANET DISPLAY DEFAULT IS NOT DOTTED 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 ;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 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 WINSET ;SET UP WHERE WINDOW FOR DISPLAY IS 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 TLNN R,-1 ;SHOWING HELP DISPLAY? TXNE F,FR.INF ;OR SHOWING INFORMATION LINE? CALL INFO ;YES, SHOW THAT 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: CALL GETSLP ;GET THE SLEEP TIME JUMPLE T1,LOOP ;IF ZERO, DON'T SLEEP AT ALL 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 MOVE T1,RUNDIF(J) ;GET RUNTIME JOB HAD IN LAST INTERVAL MOVE T2,TIMDIF ;AND TIME DIFFERENCE 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 MOVEM T1,CPUPER(J) ;SAVE TO DECIEDE TO DROP THIS ONE 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,CPUPER(J) ;GET THE CPU PERCENTAGES IDIVI T1,^D100 ;GET PERCENTAGE AND FRACTION 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 XXFHST: SKIPL T1,BLK+.JICPJ ;ANY CONTROLLING JOB? JRST FHDECN ;YES, GO SEE IF THIS IS A "NRTSRV" LINK SKIPL T2,BLK+.JITNO ;GET TERMINAL NUMBER CAMG T2,CTYNUM ;TERMINAL NUMBER IN RANGE OF ARPANET NVT'S? RET ;NO, THEN NOT FROM FOREIGN HOST MOVEI T1,.GTNNI ;ARGUMENT IS INPUT SIDE OF NVT MOVEI T3,T3 ;LOCATION TO PUT RESULT HRROI T4,.NCFHS ;WANT TO READ FOREIGN HOST NUMBER GTNCP% ;READ IT ERJMP CPOPJ ;FAILED, RETURN MOVEI T1,.GTHNS ;NOW WANT TO CONVERT NUMBER TO STRING HRROI T2,TEMP ;POINT TO STORAGE GTHST% ;STORE THE SITE NAME ERJMP [MOVE T1,T3 ;FAILED, COPY HOST NUMBER JRST OCTTEL] ;AND OUTPUT IN OCTAL TXNE F,FR.MOR ;MORE COLUMNS AFTER THIS ONE? SETZM TEMP+3 ;YES, CUT OFF THE STRING STR$ TEMP ;TYPE THE NAME RET ;DONE FHDECN: MOVE T2,[-<.JIPNM+1>,,TEMP] ;WANT DATA ON CONTROLLING JOB SETZ T3, ;FROM OFFSET ZERO GETJI ;OBTAIN THE INFORMATION ERJMP CPOPJ ;FAILED MOVE T1,TEMP+.JIPNM ;GET PROGRAM NAME READY SKIPN TEMP+.JIUNO ;JOB LOGGED IN? CAME T1,['NRTSRV'] ;OR HAS THE WRONG NAME? RET ;YES, NOT THE REAL DECNET "NVT" HACK PROGRAM TXNE F,FR.NRT ;HAVE DATA FILE MAPPED ALREADY? JRST FHDECG ;YES, SKIP ONWARD MOVX T1,GJ%OLD!GJ%SHT!GJ%ACC ;NO, GET READY HRROI T2,[ASCIZ/SYSTEM:NRTSRV-CONNECTIONS.DATA/] ;FILE NAME GTJFN ;TRY TO GET IT ERJMP CPOPJ ;FAILED MOVE T4,T1 ;REMEMBER JFN IN CASE OF FAILURE MOVX T2,OF%RD ;WANT TO READ IT OPENF ;TRY TO DO SO ERJMP NODECV ;FAILED MOVSI T1,(T1) ;WANT TO READ PAGE ZERO OF FILE MOVE T2,[.FHSLF,,] ;WHERE TO MAP IT MOVX T3,PM%RD ;WANT READ ACCESS PMAP ;DO IT ERJMP DIE ;FAILED TXO F,FR.NRT ;WE NOW HAVE THE FILE MAPPED FHDECG: MOVE T1,BLK+.JITNO ;GET TERMINAL NUMBER SUB T1,CTYNUM ;REMOVE CTY OFFSET SOJL T1,CPOPJ ;CREATE PTY NUMBER AND CHECK TO MAKE SURE IMULI T1,2 ;DATA FILE HAS TWO WORDS PER PTY CAIGE T1,PAGSIZ ;VERIFY THE RANGE STR$ NRTLOC(T1) ;OK, TYPE THE FOREIGN HOST NAME RET ;DONE NODECV: MOVE T1,T4 ;GET BACK JFN RLJFN ;RELEASE IT ERJMP DIE ;FAILED RET ;RETURN 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 TXNN F,FR.CPR ;IS IT READY? JRST SUPPR1 ;NO, ALLOW TEH LINE IN ANY CASE MOVE T1,CPUPER(J) ;GET THE CPU PERCENTAGE USED MOVE T2,MAXRPF ;AND THE FLAG TO TEST XCT [CAMGE T1,MAXRPT CAML T1,MAXRPT](T2) ;TEST AGAINST CUTOFF RET ;IT FAILED THE TEST SUPPR1: 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 ifn 0,< 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 > ;ifn 0 Setzb t1,t2 Call DoFrk1 Ret PrFork: Movem t1,JOBFRK Movem t2,indent Call Full Ret ;No more room on screen Move t2,JOBFRK ;get jfi in t2 MOVE T1,['SYSFK '] ;WANT TO READ SYSTEM FORK TABLE CALL GETJSB ;READ WORD Ret JUMPL T2,R ;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? Ret ;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 Ret DoFrk1: Stkvar Movem t1,jfi ;save job fork index Movem t2,ind ;save indentation Call PrFork ;print me Move t1,jfi ;get my index back Call Getinf ;get my inferior list Ret ; none. Jumpe t2,Cpopj ;none? Movem t2,inf ;save Call FndFrk ;Check it. Ret Move t1,inf ;get fork index Aos t2,ind ;get colm bumped Pjrst DoFrk2 endsv. DoFrk2: stkvar Movem t1,jfi Movem t2,ind Call GetBro ;get my brother jrst frk2e jumpe t2, frk2e ;none? Movem t2, bro ;save bro jfi Call FndFrk ;Validate jrst frk2e ; no go Move t1,bro Move t2,ind Call DoFrk2 ;recurse to end of chain (oldest) Frk2e: Move t1,jfi ;none older than me Move t2,ind ;print me and my inferiors Pjrst DoFrk1 endsv. ;THE ROUTINES TO HANDLE THE VARIOUS COLUMN OUTPUTS: doind: Skipn t1,indent Ret SPACE sojg t1,.-1 Ret XXFORK: call doind 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- ;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. ; [plb] find inferior list -- returns job fork index GETinf: 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,35] ;GET FORK NUMBER OF inferior pjrst cpopj1 ; [plb] find brother list -- returns job fork index GETbro: 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,23] ;GET FORK NUMBER OF brother pjrst cpopj1 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!FR.INF ;COMPRESSED OUTPUT OR SHOWING INFO LINES? 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,PIDSIZ ;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) 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,UDBDDD ;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 UDBDDD,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, NT .TT35, NT .TT37, NT .TTEXE,Execuport NT .ttgla,GLASS ;;;[budd] NT .TTDM,DM2500 ;;;[budd] NT .ttsun,SUN ;;;[budd] NT .ttadm,ADM3A ;;;[budd] 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 NT .TT125,VT125 ;;;[budd] NT .TTK10,VK100 ;;;[budd] NT .TT102,VT102 ;;;[budd] NT .TTH19,H19 ;;;[budd] NT .TT131,VT131 ;;;[budd] NT .TT200,VT200 ;;;[budd] 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,</^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 MOVX T3,1B1!1B4!1B6!37B17!4B23!2B29 ;GET BITS 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 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,28>] ;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 CAIN T4,RESPOL-RESFLD;SUB FIELD 0? RET ;YES, FORGET IT 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 DECSP5 ;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/ Unused pool/] ;(0) CATCH22 POOL 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: TXNN F,FR.CMP ;SUPPRESING TITLES? CALL DONODE ;NO...SO 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 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 LLHSN==POINT 18,DL.22(J),17 ;REMOTE NODE NUMBER LLSOB==POINT 18,DL.33(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,17,20,22,33> > ;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 ,[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 26,MAIL NT 27,NVT NT 30,TCON NT 31,LOOP NT 32,EVENT NT 33,VMAIL ;[BUDD] NT 34,FTS NT 35,PHONE ;[BUDD] NT ^D47,POSI NT ^D63,DTR NT ^D65,TOPOL NT ^D117,FINGER ;[BUDD] NT ^D123,PMR NT ^D200,OLDNVT ;[BUDD] NT ^D201,MS NT ^D254,SWTSMT ;[BUDD] OBJNUM==.-OBJTAB ;NUMBER OF ENTRIES XXLKTP: MOVE T1,(J) ;GET WORD CONTAINING FLAGS TXNE T1, ;IS THIS A SRV OR A DCN? TDZA T2,T2 ;A SRV, MAYBE MOVEI T2,1 ;A DCN, MAYBE TXNE T1, ;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 T3,[LLHSN] ;GET THE REMOTE NODE NUMBER JUMPE T3,NOREM ;IF NONE, LOCAL MOVEI T1,16 ;MAGIC NODE JSYS FUNCTION MOVEI T2,T3 ;ADDRESS OF ARG BLOCK HRROI T4,TEMP ;BP TO NODE NAME NODE ERJMP CPOPJ SKIPE TEMP ;IF NONE, LOCAL JRST TELHST 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 [ASCIZ/CC sent/] ;(10) CC SENT ABTCOD: [ASCIZ/Aborted/] ;(11) 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 ,[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,.GTHIX ;GET HOST INFO FROM NAME INDEX HRROI T2,TEMP ;NAME INTO TEMP BUFFER MOVEI T3,(J) ;WITH HOST NAME INDEX GTHST% ;GET HOST NAME ERJMP APALPL ;FAILED TXNE T4,HS%SRV ;NOT A HOST? TXNE T4,HS%NCK ;OR A HOST NICKNAME? JRST APALPL ;YES, DON'T SHOW IT IFXN. F,FR.AAH ;WANT TO SHOW ONLY VALID HOSTS? TXNN T4,HS%VAL ;YES SO MAKE SURE STATUS IS VALID JRST APALPL ;NOT VALID, SKIP ON ENDIF. DMOVEM T3,APANUM ;WANT TO SHOW IT, SAVE NUMBER AND STATUS CALL DOCOLS ;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 PUSH P,DOTFLG ;SAVE CURRENT VAULUE OF DOTFLG SETOM DOTFLG ;ENSURE NUMERIC TYPEOUT CALL PNTHST ;PRINT HOST NAME POP P,DOTFLG ;RESTORE OLD DOTFLG RET ;RETURN TO CALLER 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 TXNN T1,HS%SRV ;IS THIS A USER? STR$ [ASCIZ/ (user)/] ;YES, SAY SO RET ;DONE APATPT: [ASCIZ /other/] ;(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) [ASCIZ /NETWORK/] ;(13) [ASCIZ /FUZZBALL/] ;(14) [ASCIZ /VMS/] ;(15) [ASCIZ /TAC/] ;(16) [ASCIZ /MSDOS/] ;(17) APATPX==.-APATPT-1 ;HIGHEST KNOWN SYSTEM TYPE XXASTS: MOVE T1,APASTS ;GET THE STATUS OF THIS HOST TXNN T1,HS%VAL ;INFORMATION VALID? (ONLY VALID FOR 1822 NETS) RET ;NO, PRINT NOTHING 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 LDB T1,[POINTR APASTS,HS%RSN] ;GET REASON FOR BEING DOWN STR$ @RSNTAB(T1) ;OUTPUT REASON LDB T1,[POINTR APASTS,] ;GET TIME JUMPE T1,CPOPJ ;DONE IF UNKNOWN CAIE T1,<.RTJST(-1,)> ;"-1" FORM OF UNKNOWN? CAIN T1,<.RTJST(-1,)>-1 ;OR "-2" FORM? RET ;YES, DONE LDB T1,[POINTR APASTS,HS%HR] ;RANGE CHECK FOR VALIDITY LDB T2,[POINTR APASTS,HS%MIN] CAIGE T1,^D24 CAIL T2,^D12 RET LDB T1,[POINTR APASTS,HS%DAY] CAIL T1,^D7 RET STR$ [ASCIZ/, up /] ;HAVE REAL TIME, START OUTPUT 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 RSNTAB: [ASCIZ/net err/] ;(0) REASONS WHY HOST IS DOWN [ASCIZ/sys dwn/] ;(1) [ASCIZ/frn NCP/] ;(2) [ASCIZ/nosuch/] ;(3) [ASCIZ/NCP ini/] ;(4) [ASCIZ/PM/] ;(5) [ASCIZ/hdw wrk/] ;(6) [ASCIZ/sfw wrk/] ;(7) [ASCIZ/restart/] ;(8) [ASCIZ/power/] ;(9) [ASCIZ/bpt/] ;(10) [ASCIZ/hdw err/] ;(11) [ASCIZ/sched/] ;(12) [ASCIZ/#13/] ;(13) [ASCIZ/#14/] ;(14) [ASCIZ/unknown/] ;(15) 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 Internet Status Commands ;Brief display of the state of all TCP connections invoked by the "ANC" ;command DPYARC: MOVX T1,TCP%NI ;GET THE AOBJN POINTER STAT% ; .... IFJER. TMSG RET ;JUST QUIT QUIETLY ENDIF. MOVE J,T2 ;SAVE AOBJN POINTER MOVEI T1,TP.ANC ;COLUMNS FOR ANC COMMAND CALL HDRSET ;SET THEM UP TXO F,FR.EAT ;PREVENT ANOREXIA DPYAC0: CALL FULL ;SCREEN OVERFLOWED? RET ;YES, RETURN TO CALLER HRRZ T1,J ;SET INDEX TXO T1,TCP%IX ;SET FLAG THAT INDICATES INDEXING MOVSI T2,-TCBSIZ ;-TCB LENGTH,,OFFSET MOVE T3,[XWD -TCBSIZ,TCB] ;-TCB LENGTH,,USER BUFFER STAT% ;COPY THE TCB INTO OUR ADDRESS SPACE ERJMP DPYAC2 ;IGNORE AN ERROR LOAD T1,TVTL,+TCB ;GET TVT NUMBER (MAY BE NONE) JUMPE T1,DPYAC1 ;THERE IS NONE, DESPITE THE FLAG. GET OWNER. MOVEI T1,.TTDES(T1) ;TURN INTO A TTY DESGINATOR JN TTVT,+TCB,DPYAC3 ;SKIP IF THERE REALLY IS A TVT HERE DPYAC1: CALL TCBJOB ;GETTHE JOB FOR THIS TCB JRST DPYAC2 ;HANDLE ERROR DPYAC3: ;HERE WHEN WE HAVE THE JOB OR TTY DESIGNATOR MOVE T2,[-<.JISTM+1>,,BLK] ;PUT DATA IN STANDARD LOCATION SETZ T3, ;START AT FIRST WORD GETJI% ;READ INFORMATION ABOUT THE JOB ERJMP DPYAC2 ;NO JOB? JUST SKIP THIS ONE, THEN. CALL DOCOLS ;PRINT A LINE DPYAC2: AOBJN J,DPYAC0 ;LOOP OVER ALL TCB'S RET ;RETURN TO CALLER ;Display error wait index for this TCB. This is a kludge to associate a ;small, unique number with the TCB. The (JOB,JCN) pair is not unique ;over the TCB's lifetime. XXANCI: LOAD T1,TERRF,+TCB ;LOAD ERROR WAIT BIT INDEX CALLRET DECSP3 ;PRINT IT XXANCJ: ;DISPLAY JOB ASSOCIATED WITH THIS TCB CALL TCBJOB ;GET THE JOB NUMBER FOR THIS TCB JRST XXANCE ;ON ERROR ASSUME JOB ZERO LOAD T2,TVTL,+TCB ;SKIP IF WE HAVE A TVT NUMBER JUMPE T2,DECSP3 ;PRINT JOB NUMBER IF NOT A TVT MOVEI T1,.TTDES(T2) ;GET TTY NUMBER OF TVT HRROI T2,T4 ;PUT ONE WORD IN T4 MOVEI T3,.JIJNO ;GET JOB NUMBER GETJI% ;DO SO. XXANCE: TDZA T1,T1 ;FAILED, SAY JOB ZERO IS OWNER MOVE T1,T4 ;GET JOB NUMBER INTO PLACE CALLRET DECSP3 ;AND PRINT IT XXANCT: ;DISPLAY TVT NUMBER OPSTR ,TTVT,+TCB ;SKIP IF THIS IS A TVT TCB RET ;ELSE RETURN HAVING DONE NOTHING LOAD T1,TVTL,+TCB ;GET TVT/TTY NUMBER CALLRET OCTSP3 ;ELSE PRINT OCTAL TTY NUMBER XXANCU: ;DISPLAY USERNAME HRROI T1,TEMP ;INTO TEMP BUFFER MOVE T2,BLK+.JIUNO ;GET USER NUMBER DIRST% ERJMP CPOPJ ;NO USER, LEAVE BLANK TXNE F,FR.MOR ;IS THIS THE LAST FIELD? SETZM TEMP+2 ;NO, CUT OFF STRING STR$ TEMP ;PRINT USERNAME RET ;RETURN TO CALLER XXANCN: ;DISPLAY JOBNAME SKIPN T1,BLK+.JIPNM ;GET PROGRAM NAME MOVE T1,BLK+.JISNM ;IF NONE, USE SUBSYSTEM NAME CALLRET SIXOUT ;GO OUTPUT IT XXANCS: ;STATUS OF CONNECTION (RCV.SND) LOAD T1,TRSYN,+TCB ;RECEIVE STATE LOAD T2,TSSYN,+TCB ;SEND STATE STR$ @TCPSTA(T1) ;PRINT RCV STATE CHI$ "." ;SEPARATING DOT STR$ @TCPSTA(T2) ;PRINT SND SATE RET ;RETURN TO CALLER TCPSTA: ;TABLE OF TCP STATES [ASCIZ/NOT/] ;NOTSYN [ASCIZ/-1-/] [ASCIZ/FIN/] ;FINSNT [ASCIZ/-3-/] [ASCIZ/PND/] ;SYNABL [ASCIZ/SYN/] ;SYNSNT [ASCIZ/-6-/] [ASCIZ/EST/] ;SYNCHED XXANCQ: ;LOCAL HOST LOAD T1,TLH,+TCB ;GET LOCAL HOST NUMBER PUSH P,DOTFLG ;SAVE SENSE OF DOT FLAG SETOM DOTFLG ;-1 TO PRINT DOTTED HOST NAME CALL PNTHST ;PRINT HOST NUMBER IN DOTTED FORM POP P,DOTFLG ;RESTORE DOTFLG RET ;RETURN TO CALLER XXANCH: ;FOREIGN HOST LOAD T1,TFH,+TCB ;GET FOREIGN HOST NUMBER CALLRET PNTHST ;PRINT HOST NUMBER XXANCL: ;LOCAL PORT LOAD T1,TLP,+TCB ;GET LOCAL PORT NUMBER CALLRET PNTPRT ;PRINT IT XXANCF: ;FOREIGN PORT LOAD T1,TFP,+TCB ;GET FOREIGN PORT NUMBER CALLRET PNTPRT ;PRINT IT ;Display the state of a particular TCB. Invoked by the "ANC" ;command. The cell ANCIDX is already set up at this point. DPYARJ: CALL FNDTCB ;LOOK FOR THE TCB IFNSK. STR$ [ASCIZ/There is no TCB for /] ; MOVE T1,ANCIDX ; CALL DECOUT ;PRINT INDEX NUMBER CRLF RET ENDIF. MOVEI T1,TP.ANC ;COLUMNS FOR ANC COMMAND CALL HDRSET ;SET THEM UP TXO F,FR.HDR ;BUT STOP HEADER FROM TYPING CALL DOCOLS ;PRINT LINE OF CONNECTION INFORMATION SETOM HDRTYP ;NO MORE COLUMNS TAB$ ;SET UP DEFAULT TABS CALL SETEAT ;SET UP PAGING CALL ANJFLG ;FLAG BITS CALL ANJDEC ;DEC INTERFACE FLAGS CALL ANJMSC ;RANDOM PIECES OF INFORMATION MOVEI T1,TP.ASR ;WANT SEND/RECV DISPLAY TXO F,FR.HD1 ;TYPE ONLY ONE CRLF AFTER HEADER CALL HDRSET ;SET UP TABS, ETC. SETZ J, ;DO SEND SIDE CALL DOCOLS ; ... SETO J, ;DO RECV SIDE CALL DOCOLS ; ... RET ;RETURN TO CALLER ;FNDTCB - Find TCB matching ANCIDX. ;RETURNS +1 FAILURE ; +2 SUCCESS, TCB AND BLK SET UP FNDTCB: MOVX T1,TCP%NI ;GET THE AOBJN POINTER STAT% ; .... ERJMP R ;NO CONNECTIONS, TAKE FAILURE RETURN MOVE J,T2 ;SAVE AOBJN POINTER FNDTC0: HRRZ T1,J ;SET INDEX TXO T1,TCP%IX ;SET FLAG THAT INDICATES INDEXING MOVSI T2,-TCBSIZ ;-TCB LENGTH,,OFFSET MOVE T3,[XWD -TCBSIZ,TCB] ;-TCB LENGTH,,USER BUFFER STAT% ;COPY THE TCB INTO OUR ADDRESS SPACE ERJMP FNDTC2 ;IGNORE AN ERROR LOAD T1,TERRF,+TCB ;GET ERROR WAIT BIT INDEX CAME T1,ANCIDX ;MATCH? JRST FNDTC2 ;NO, KEEP ON LOOKING LOAD T1,TVTL,+TCB ;GET TVT NUMBER (MAY BE NONE) JUMPE T1,FNDTC1 ;THERE IS NONE, DESPITE THE FLAG. GET OWNER. MOVEI T1,.TTDES(T1) ;TURN INTO A TTY DESGINATOR FNDTC1: CALL TCBJOB ;GET THE JOB FOR THIS TCB RET ;HANDLE ERROR MOVE T2,[-<.JISTM+1>,,BLK] ;PUT DATA IN STANDARD LOCATION SETZ T3, ;START AT FIRST WORD GETJI% ;READ INFORMATION ABOUT THE JOB ERJMP R ;NO JOB? TAKE ERROR RETURN. RETSKP ;RETURN TO CALLER WITH APPROPRIATE DATA FNDTC2: AOBJN J,FNDTC0 ;GO ON TO NEXT TCB RET ;LOOK AT ALL WITH NO LUCK, TAKE FAILURE RETURN TCBJOB: ;RETURN GLOBAL JOB NUMBER FOR CURRENT TCB LOAD T1,TOWNR,+TCB ;GET THE LOCAL JOB WHO OWNS THIS RETSKP ;NON ERROR RETURN ;NEWLIN - Print a crlf and if eos, exit to caller of caller's caller NEWLIN: CRLF ;PRINT A CRLF CALL FULL ;END OF SCREEN YET? TRNA ;YES, TAKE A FUNNY RETURN RET ;MORE TO GO, RETURN TO CALLER ADJSP P,-2 ;RETURN TWO DEEP INTO STACK RET ;RETURN TO CALLER OF CALLER ON EOP ;BITOUT - Pretty print a flag description if the flag is set ;Takes T1/ Sense of flag, 0 OR 1 ; T2/ Adress of description string ;Returns +1 always BITOUT: JUMPE T1,CPOPJ ;IGNORE CLEARED FLAGS PUSH P,T2 ;SAVE POINTER TO STRING SETZ T1, ;USE T1 TO ACCUMULATE STRING LENGTH MOVE T3,[POINT 7,(T2)] ;SET UP POINTER TO STRING BITOU0: ILDB T4,T3 ;GET A BYTE SKIPE T4 ;SKIP IF EOS AOJA T1,BITOU0 ;ELSE COUNT AND LOOP PUSH P,T1 ;SAVE BYTE COUNT CALL LEFT ;GET T1/ SPACES LEFT ON LINE POP P,T2 ;RESTORE BYTE COUNT ADDI T2,2 ;ACCOUNT FOR A POSSIBLE COMMA AND SPACE SUBI T1,(T2) ;SEE IF WE HAVE ROOM IFL. T1 ; CRLF ;NO ROOM, PRINT A CRLF CALL FULL ;ARE WE AT END OF PAGE? ANNSK. ADJSP P,-2 ;FUDGE STACK TO RETURN TWO DEEP RET ;RETURN TO CALLER OF OUR CALLER'S CALLER ELSE. LOC$ T1 ;GET OUR CURRENT LOCATION ANDI T1,-1 ;SAVE JUST COLUMN NUMBER SKIPE T1 ;SKIP IF ON THE SCREEN'S EDGE STR$ [ASCIZ/, /] ;ELSE PRINT A SEPARATING COMMA AND SPACE ENDIF. POP P,T2 ;RESTORE ADDRESS OF DESCRIPTION STR$ (T2) ;PRINT DESCRIPTION RET ;RETURN TO CALLER ;FLGOUT - Print a flag description DEFINE FLGOUT(OFFSET,DESC) < LOAD T1,OFFSET,+TCB MOVEI T2,[ASCIZ/DESC/] CALL BITOUT > ;FLGCMP - Same as FLGOUT, but prints only if 'over' field is not set DEFINE FLGOIF(OFFSET,OVER,DESC) < LOAD T1,OFFSET,+TCB MOVEI T2,[ASCIZ/DESC/] OPSTR ,OVER,+TCB CALL BITOUT > ANJFLG: CALL NEWLIN ;ANJFLG - PRINT OUT TCB FLAG BITS FLGOIF (TWLDN,TSOPN,) ;Show only if not open FLGOIF (TWLDT,TSOPN,) ; ... FLGOIF (TWLDP,TSOPN,) ; ... FLGOUT (TSCR,) FLGOUT (TTVT,) FLGOUT (TDEC,) FLGOUT (TSUOP,) FLGOIF (TSOPN,TSUOP,) ;Show only if not open FLGOUT (TSPRS,) FLGOUT (TSABT,) FLGOUT (TSSV,) FLGOUT (TSURG,) FLGOUT (TRURG,) FLGOUT (TSEP,) FLGOUT (TSFP,) FLGOUT (TRPP,) CALL NEWLIN RET ;RETURN TO CALLER ANJDEC: ;DEC INTERFACE FLAGS LOAD T1,TDEC,+TCB ;DEC TCB? JUMPE T1,CPOPJ ;NO, DON'T DO ANYTHING CALL NEWLIN STR$ [ASCIZ/JFN= /] LOAD T1,TJFN,+TCB ;GET JFN IDIV T1,MLJFN ;COMPUTE USER JFN CALL OCTOUT LOAD T1,TCDWT,+TCB ;GET SENSE OF WAIT FLAG MOVEI T2,[ASCIZ/, Wait/] ;ASSUME SET SKIPN T1 ;WELL? MOVEI T2,[ASCIZ/, Immediate/] ;NO IMMEDIATE ACTION WANTED STR$ (T2) ;PRINT FIRST PART OF OPEN MODE LOAD T1,TCDHT,+TCB ;GET SENSE OF HIGH THROUGHPUT FLAG MOVEI T2,[ASCIZ/ High-Throughput mode/] ;ASSUME SET SKIPN T1 ;WELL? MOVEI T2,[ASCIZ/ Interactive mode/] STR$ (T2) ;PRINT LAST PART OF MODE DESCRIPTION LOAD T1,TCDFS,+TCB ;GET ACTIVE/PASSIVE FLAG MOVEI T2,[ASCIZ/, Active/] ;ASSUME ACTIVE SKIPN T1 ;WELL? MOVEI T2,[ASCIZ/, Passive/] ;IT'S PASSIVE STR$ (T2) FLGOUT (TCDB8,<8-bit OPENF%>) FLGOIF (TCDOW,TSOPN,) FLGOIF (TCDGN,TSOPN,) FLGOIF (TCDGE,TSOPN,) FLGOUT (TCDPS,) FLGOUT (TCDOB,) FLGOUT (TCDIB,) FLGOUT (TCDCW,) FLGOUT (TCDOQ,) FLGOUT (TCDPU,) FLGOUT (TCDUR,) CALL NEWLIN RET ANJMSC: ;RANDOM VARIABLES CALL NEWLIN ;START OFF ON A NEW LINE MOVEI T1,[ASCIZ/TCB is locked/] LOAD T2,TCBLCK,+TCB ;GET TCB LOCK WORD SKIPL T2 ;SKIP IF UNLOCKED (-1) MOVEI T1,[ASCIZ/TCB is unlocked/] STR$ (T1) ;PRINT STATUS OF TCB LOCK LOAD T1,TOFRK,+TCB ;GET OWNING FORK CAIE T1,-1 ;IF -1, WE ARE A TVT TCB OWNED BY JOB ZERO IFSKP. STR$ [ASCIZ/, owned by TCP fork/] ELSE. STR$ [ASCIZ/, owning fork is /] CALL OCTOUT ;PRINT OWNING FORK NUMBER STR$ [ASCIZ/, job /] LOAD T1,TOWNR,+TCB ;GET JOB NUMBER CALL DECOUT ;AND PRINT IT ENDIF. LOAD T1,TABTFX,+TCB ;GET FORKX OF ABORTER IFN. T1 STR$ [ASCIZ/, aborting fork is /] CALL OCTOUT ;PRINT ABORTING FORK IF IT EXISTS ENDIF. LOAD T1,TERR,+TCB ;GET TCP ERROR CODE IFN. T1 STR$ [ASCIZ/, TCP error= /] ;ONLY IF THERE IS A CODE CALL OCTOUT ;DO WE PRINT ANYTHING ENDIF. CALL NEWLIN ;START A NEW LINE STR$ [ASCIZ/Send timeout= /] LOAD T1,TSTO,+TCB CALL DECOUT ;TIMEOUT INTERVAL STR$ [ASCIZ/ ms, Time to live= /] LOAD T1,TTTL,+TCB ;GET IP TIME TO LIVE CALL DECOUT STR$ [ASCIZ/ secs/] CALL NEWLIN STR$ [ASCIZ/SRT time= /] LOAD T1,TSMRT,+TCB CALL DECOUT ;SMOOTHED ROUND TRIP TIME STR$ [ASCIZ/ ms, MRT time= /] LOAD T1,TMXRT,+TCB CALL DECOUT ;MAX ROUND TRIP TIME STR$ [ASCIZ/ ms, RI time= /] LOAD T1,TRXI,+TCB CALL DECOUT ;RETRANSMIT INTERVAL STR$ [ASCIZ/ ms/] CALL NEWLIN ;START A NEW LINE STR$ [ASCIZ/IP fragmenting is /] ;LEAD IN LOAD T1,TIFDF,+TCB ;GET SENSE OF DON'T FRAGMENT FLAG MOVEI T2,[ASCIZ/allowed/] ;ASSUME ALLOWD SKIPE T1 ;USUALLY OFF MOVEI T2,[ASCIZ/not allowed/] ;(I DON'T THINK TOPS-20 EVEN LOOKS) STR$ (T2) ;PRINT IT STR$ [ASCIZ/, max pkt= /] LOAD T1,TSMXP,+TCB CALL DECOUT ;LARGEST SIZE BUFFER STR$ [ASCIZ/ bytes, Buffer misses= /] LOAD T1,TCTBS,+TCB CALL DECOUT ;NO. TIMES PACKETIZER WAITED FOR BUFFERS CALL NEWLIN ;START A NEW LINE LOAD T1,TTOS,+TCB ;GET TYPE OF SERVICE BYTE MOVEI T2,[A