Google
 

Trailing-Edge - PDP-10 Archives - BB-H138E-BM - 6-1-sources/watch.mac
There are 22 other files named watch.mac in the archive. Click here to see a list.
; UPD ID= 136, SNARK:<6.1.UTILITIES>WATCH.MAC.11,   5-Jun-85 15:55:01 by MCCOLLUM
;TCO 6.1.1406  - Update copyright notice.
; UPD ID= 133, SNARK:<6.1.UTILITIES>WATCH.MAC.10,   5-Jun-85 15:40:49 by MCCOLLUM
;TCO 6.1.1406  - Update copyright notice.
; UPD ID= 515, SNARK:<6.UTILITIES>WATCH.MAC.9,   4-Apr-84 11:28:10 by MOSER
;TCO 6.2003 - FIXES FOR GLOBAL JOB NUMBERS
; UPD ID= 377, SNARK:<6.UTILITIES>WATCH.MAC.8,  22-Nov-83 22:22:50 by TLITT
;TCO 6.1880 - Correct BP 2 to not double count wss and upg
; UPD ID= 166, SNARK:<6.UTILITIES>WATCH.MAC.7,   5-Nov-82 17:51:34 by MURPHY
;TCO 6.1350 - Merge release 5 edits.
; UPD ID= 147, SNARK:<6.UTILITIES>WATCH.MAC.6,  29-Sep-82 16:02:58 by LEACHE
;More TCO 6.1220 - use UDBRCT and UDBWCT
; UPD ID= 136, SNARK:<6.UTILITIES>WATCH.MAC.5,  23-Sep-82 16:14:50 by MURPHY
;TCO 6.1279 - Prevent "column overflow" error messages.
; UPD ID= 116, SNARK:<6.UTILITIES>WATCH.MAC.4,   9-Aug-82 16:54:08 by LEACHE
;TCO 6.1220 - Capture and display read-after-write counts
; UPD ID= 112, SNARK:<6.UTILITIES>WATCH.MAC.3,   6-Aug-82 12:16:09 by LEACHE
;TCO 6.1216 Make disk calculations happen correctly for RP20's
; UPD ID= 89, SNARK:<6.UTILITIES>WATCH.MAC.2,  22-Jun-82 15:20:39 by MURPHY
;Update for symbol changed in SCHED.
;Better error messages for symbol not found and not enough free pages.
; UPD ID= 12, FARK:<5-WORKING-SOURCES.UTILITIES>WATCH.MAC.2,   3-May-82 12:22:07 by MOSER
; EDIT 10 - DO NOT REPORT COLUMN OVERFLOW. JUST OUTPUT STARS.
; UPD ID= 72, SNARK:<5.UTILITIES>WATCH.MAC.8,  18-Jan-82 10:48:37 by TORREY
;TCO 5.1527 - Once again replace this TCO
; UPD ID= 43, SNARK:<5.UTILITIES>WATCH.MAC.7,   1-Oct-81 13:22:56 by PAETZOLD
;TCO 5.1555 - Remove TCO 5.1527
; UPD ID= 36, SNARK:<5.UTILITIES>WATCH.MAC.6,  22-Sep-81 17:27:58 by PAETZOLD
;TCO 5.1527 - Increase NJOBS to 128
;FIX LINE OVERFLOW, INCREASE NUMBER JOBS AND FORKS, CHECK FOR MONITOR TOO BIG
; UPD ID= 1772, SNARK:<5.UTILITIES>WATCH.MAC.2,  25-Mar-81 17:52:05 by GRANT
;Update Copyright
; UPD ID= 1231, SNARK:<4.RP20-UTILITIES>WATCH.MAC.4,   4-Nov-80 15:06:30 by UHLER
;TEACH WATCH ABOUT DISK KDB'S (RP20)
; UPD ID= 267, SNARK:<4.1.UTILITIES>WATCH.MAC.2,  18-Feb-80 09:53:13 by ENGEL
;FIX THE BAD JXE BEFORE DSK4
;<4.UTILITIES>WATCH.MAC.8,  3-Jan-80 15:27:59, EDIT BY R.ACE
;UPDATE COPYRIGHT DATE
;<4.UTILITIES>WATCH.MAC.6, 17-Apr-79 08:44:48, EDIT BY KIRSCHEN
;<4.UTILITIES>WATCH.MAC.5, 28-Mar-79 10:09:07, EDIT BY KIRSCHEN
;ADD DIRECTORY CACHE STATS
;<4.UTILITIES>WATCH.MAC.4, 12-Mar-79 14:33:31, Edit by KONEN
;UPDATE COPYRIGHT FOR RELEASE 4
;<4.UTILITIES>WATCH.MAC.3,  7-Mar-79 20:55:03, EDIT BY MURPHY

;COPYRIGHT  (C)  DIGITAL  EQUIPMENT  CORPORATION  1976, 1985.
;ALL RIGHTS RESERVED.
;
;
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
;ONLY  IN  ACCORDANCE  WITH  THE  TERMS  OF  SUCH LICENSE AND WITH THE
;INCLUSION OF THE ABOVE COPYRIGHT NOTICE.  THIS SOFTWARE OR ANY  OTHER
;COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
;OTHER PERSON.  NO TITLE TO AND OWNERSHIP OF THE  SOFTWARE  IS  HEREBY
;TRANSFERRED.
;
;THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT  NOTICE
;AND  SHOULD  NOT  BE  CONSTRUED  AS A COMMITMENT BY DIGITAL EQUIPMENT
;CORPORATION.
;
;DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY  OF  ITS
;SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.

	TITLE WATCH - PROGRAM TO REPORT JOB SCHEDULING DATA
	SEARCH MONSYM,MACSYM
	.CPYRT (1985)
	SEARCH PROLOG
	SALL
	.REQUIRE SYMSUB

	EXTERN ST2ADR,ADR2ST,SYM2ST
	EXTERN INTRVL,CRLF
	EXTERN OFLT,ONUM,PRIREC,SYSHED,CACBUF,OCACHE
	EXTERN ODSKNM,ODFIL,SETHD,NULJFN,RSTJFN,NOSNP

DEFINE NUMOUT (LOC,BASE)<
   IFNB <LOC>,<MOVE T2,LOC>
	MOVEI T3,^D'BASE
	NOUT
	 NOP>

DEFINE TABOUT <
	MOVEI T2,.CHTAB
	BOUT>

TUNEMF==:1B3			;TUNE MODE FLAG IN F
ODATFL==1B5			;OUTPUT TO DATA FILE

SUPOUF==1B18			;SUPPRESS OUTPUT

NJOBS==^D128
NFKS==4*NJOBS
MAXSNP==14000			;ASSUMED MAX LENGTH OF SNOOP DATA
NBPT==^D14			;NUMBER OF BREAKPOINTS
NDSKS==^D64			;MAXIMUM NUMBER OF DISKS
CCZCHN==0			;^Z CHANNEL
OPDEF IFIW [1B0]		;INSTRUCTION FORMAT INDIRECT WORD

F=:0
T1=:1
T2=:2
T3=:3
T4=:4
Q1=:5
Q2=:6
Q3=:7
P1=:10
P2=:11
P3=:12
P4=:13
P5=:14
I=15
CX=:16
P=:17

BPRPAG==100
BPRCOD==BPRPAG_11

DEFINE LFMSG ($MSG)<
	HRROI T2,[ASCIZ \$MSG\]
	CALL LFMSGX>
	COMMENT \

Some definitions and explanations...

The job working set size (column WSS) is obtained by integrating the instantaneous
fork working set size (FKNR) over all time that the fork is not blocked.  The average
size is then the integral divided by the accumulated time, i.e.

	JOB WSS = integral FKNR dt / T not blocked

The job used pages (column UPGS) is obtained by integrating the instantaneous
fork assigned pages (FKWSP) over all time that the fork is in the balance set.
The average used pages is then the integral divided by the accumulated time, i.e.

	JOB UPGS = integral FKWSP dt / T in balset

The system average memory demand is the sum of the NR integrals for all jobs
divided by the interval time, i.e.

	SYS MEM DMD = SUM all jobs (integral FKNR dt) / T interval

The system average used pages is the sum of the WSP integrals for all jobs
divided by the interval time, i.e.

	SYS UPGS = SUM all jobs (integral FKWSP dt) / T interval

The arithmetic sum of the working sets of all jobs active during the interval
is also computed and reported in the system summary WSS column.  This
represents the total number of pages used during the interval.

	SYS WSS = SUM all jobs (JOB WSS)

The Swap Ratio is the system WSS divided by the amount of available
main memory.  This represents the amount by which main memory would
have to be increased to avoid any swapping during the interval.

	SWAP RATIO = SYS WSS / AV CORE

The active swap ratio is the system average core demand divided by the
amount of available main memory.  The represents the amount by which
main memory would have to be increased to hold all jobs wanting
to run simultaneously.

	ACTIVE SWAP RATIO = SYS MEM DMD / AV CORE

The core utilization if the system used pages divided by the amount
of available main memory.  For active swap ratios greater than 1,
this indicates how well the monitor is doing in keeping core used.

	CORE UTILIZATION = SYS UPGS / AV CORE

The following variables are used herein

SNR = SUM all jobs (integral NR dt)
SNNR = SUM all jobs (time in balset)
SWSP = SUM all jobs (integral WSP dt)
SNWSP = SUM all jobs (time in balset); not presently used
SSWSS = SUM all jobs (JOB WSS)
SSBLKT = SUM all jobs (time blocked)
\
;TOP

	BLOCK 1000

TIMER:				;LOCATION OF START OF PROGRAM

SINIT::	SAVEAC <Q1,Q2,Q3,I>
	SKIPE ONCEF		;FIRST TIME?
	JRST [	TMSG <
?This program may not be restarted.
>
		HALTF
		JRST .]
	SETOM ONCEF		;PREVENT RESTART
	MOVEI I,BPRCOD
	MOVSI T1,SNPDAT(I)
	HRRI T1,SNPDAT+1(I)
	SETZM -1(T1)
	BLT T1,BPRCOD+BPRLEN-1
	XJRSTF [0
		REL3]
	ERJMP .+1
	TDZA T1,T1		;NO EXT ADR
REL3:	SETO T1,
	MOVEM T1,MONTYP(I)
      DO.
	MOVEI T1,.SNPLC
	MOVEI T2,<BPRLEN+777>/1000
	MOVEI T3,BPRPAG
	SNOOP
	 IFJER.
	  CAIE T1,SNOP15	;NOT ENOUGH PAGES?
	  JSHLT			;NO, SOMETHING ELSE
	  TMSG <?Not enought free pages for SNOOPing.
There is probably another job using the SNOOP facility.
CONTINUE to try again.
>
	  HALTF
	  LOOP.
	ENDIF.
      ENDDO.
	LSH T2,11
	MOVEM T2,INDEX(I)

;RELOCATE BREAKPOINT CODE

	; ..
	AOSE INIFLG		;NEED TO DO SYMBOL TABLE?
	JRST TIMER4		;NO. GO ON TO BREAKPOINTS
	MOVSI Q1,-INSTBL
TIMER1:	HLRZ T1,INSTAB(Q1)
	HRRZ T2,INSTAB(Q1)
	ADD T2,INDEX(I)
	HRRM T2,BPRCOD(T1)
	AOBJN Q1,TIMER1

;LOOK UP SYMBOLS

	MOVSI Q1,-SYMTBL
	JUMPE Q1,TIMER4
TIMER2:	MOVEI T1,.SNPSY
	MOVE T2,SYMTAB(Q1)
	MOVE T3,SYMTAB+1(Q1)
	SNOOP
	 IFJER.
	  TMSG <?Symbol not found: >
	  MOVE T1,[POINT 7,SYMBOL]
	  MOVE T2,SYMTAB(Q1)	;GET SYMBOL THAT FAILED
	  CALL SYM2ST		;CONVERT TO STRING
	  HRROI T1,SYMBOL
	  PSOUT			;PRINT IT
	  TMSG <
>
	  HALTF
	ELSE.
	  HLRE T3,SYMTAB+2(Q1)	;GET SYMBOL OFFSET
	  ADD T2,T3		;ADJUST VALUE BY OFFSET
	  HRRZ T3,SYMTAB+2(Q1)
	  CAIL T3,TIMER		;IN LOCAL CODE?
	  ADDM T2,0(T3)		;YES
	  CAIGE T3,TIMER	;IN BREAKPOINT CODE?
	  ADDM T2,BPRCOD(T3)
	ENDIF.
	ADD Q1,[2,,2]
	AOBJN Q1,TIMER2
	MOVEI T1,NJOBS		;SEE IF OUR TABLES BIG ENOUGH FOR MONITOR
	CAML T1,LNJOBS
	IFSKP.
	  TMSG <
?Monitor has too many jobs for this version of WATCH.
>
	  HALTF
	  JRST .-1
	ENDIF.
	MOVEI T1,NFKS
	CAML T1,LNFKS
	IFSKP.
	  TMSG <
?Monitor has too many forks for this version of WATCH.
>
	  HALTF
	  JRST .-1
	ENDIF.
	TXNN F,TUNEMF		;NO DISK STUFF IF TUNE MODE
	CALL GETUDB		;SET UP DISK UDBS

;SET BREAKPOINTS

TIMER4:	MOVSI Q1,-NBPT
SETBP1:	MOVEI T1,.SNPDB
	MOVEI T2,1(Q1)
	MOVE T3,BP1ADR(Q1)
	SKIPE MONTYP(I)
	JRST [	HLRZ T4,BPI(Q1)	;EXT ADR BP ROUTINE ENTRY
		HRLI T4,(XPCW)	;CONSTRUCT BP INSTRUCTION
		JRST SETBP2]
	HRRZ T4,BPI(Q1)
	HRLI T4,(JSR)		;CONSTRUCT BP INSTRUCTION
SETBP2:	ADD T4,INDEX(I)
	TLZ T4,37
	SNOOP
	 JSHLT
	AOBJN Q1,SETBP1

	MOVSI T4,-NFKS
	HRR T4,I
	TIME
	MOVEM T1,FKLEV(T4)		;INIT ALL TIMES
	AOBJN T4,.-1

;START SNOOPING

	MOVEI T1,.SNPIB
	SNOOP
	 JSHLT
	RET
;GET SNOOP DATA - CALLED AT START OF CYCLE TO GET NEW
;DATA AND SAVE PREVIOUS DATA

GSNPD::	SAVEAC <I>
	MOVEI I,BPRCOD
	TIME			;GET CURRENT TODCLK
	MOVEM T1,TODBIV(I)	;SAVE START OF INTERVAL
	MOVE T1,[JOBWSM,,JOBWSM+1]
	SETZM JOBWSM
	BLT T1,JOBWSM+NJOBS-1	;CLEAR JOB WSS TABLE
	SETZM SYSWSM
	MOVSI T4,-NFKS
	HRR T4,I
GSNPD1:	SKIPN T1,FKWSIZ(T4)	;RECORDED FORK WSS HERE?
	JRST GSNPD2		;NO
	HRRZ T3,FKJB(T4)	;YES, GET JOB INDEX
	ADDM T1,JOBWSM(T3)	;COMPUTE JOB TOTAL
	ADDM T1,SYSWSM		;COMPUTE SYS TOTAL
	SETZM FKWSIZ(T4)		;REINIT
GSNPD2:	SKIPN T1,FKMTIM(T4)	;WS IN MEM?
	JRST GSNPD3		;NO
	MOVE T2,TODBIV(I)	;CURRENT TIME
	MOVEM T2,FKMTIM(T4)	;RESET
	SUB T2,T1		;COMPUTE TIME IN MEM LAST INTERVL
	HRRZ T3,FKJB(T4)	;GET JOB INDEX
	ADD T3,I
	ADDM T2,JINMEM(T3)	;ACCUMULATE TOTAL
GSNPD3:	AOBJN T4,GSNPD1
	MOVE T1,[NEWDAT,,OLDDAT]
	BLT T1,OLDDAT+LJDAT-1	;SAVE PREVIOUS SET
	MOVSI T1,JDAT(I)
	HRRI T1,NEWDAT
	BLT T1,NEWDAT+LJDAT-1	;GET NEW DATA
	SETZM SBASET
	MOVE T1,[SBASET,,SBASET+1]
	BLT T1,SBASET+NSYSV-1	;CLEAR SYSTEM TOTALS
	MOVSI T1,XTOTRC(I)
	HRRI T1,TOTRC
	BLT T1,BALSHC		;COPY SYSTEM VARIABLES
	SETZM XMAXNG(I)		;REINIT MIN/MAX VALUES
	SETZM XMAXNB(I)
	SETZM XMAXRP(I)
	MOVX T1,1B1
	MOVEM T1,XMINNG(I)
	MOVEM T1,XMINNB(I)
	MOVEM T1,XMINRP(I)
	TXNN F,TUNEMF		;NO DISK STUFF IF TUNE MODE
	CALL GETDSK		;GET DISK DATA
	RET
;PRINT THE PART OF THE HEADING FOR SNOOP DATA
; T1/ OUTJFN

SNPHED:
ASCIZ /  DEMD USED GRDY BRDY SWPR DSKR DSKW RPQW OTHR  IMEM NLD NRSP  RESP SR    WSS   UPGS SWPR DSKR TPF IFA/

SNPHE2:
ASCIZ / USED GRDY BRDY SWPR DSKR DSKW RPQW OTHR  IMEM NLD NRSP  RESP SR/

DOSNPH::HRROI T2,SNPHED
	TXNE F,TUNEMF
	HRROI T2,SNPHE2
	SETZ T3,
	SOUT
	RET
;TEST FOR REPORT NEEDED FOR THIS JOB
; T1/ JOB NUMBER

TSTSNP::SAVEAC <Q1,Q2,Q3,I>
	CALL G2LJ
	 RET			;NO JOB RETURN A ZERO
	MOVEI Q2,NEWDAT-JDAT(T1)
	MOVEI Q3,OLDDAT-JDAT(T1)
	MOVSI T4,-NJVAL
TSTSN1:	MOVE T1,@JNEWT(T4)
	CAME T1,@JOLDT(T4)	;CHANGE HERE?
	RET			;YES, RETURN T1 NON-0
	AOBJN T4,TSTSN1
	SETZ T1,		;FOUND NO DIFFERENCES
	RET
;PRINT THE SNOOP DATA
; T1/ OUTJFN
; T2/ JOB NUMBER

DOSNPD::CAIN T1,.NULIO		;NULL OUTPUT?
	RET			;DO NOTHING
	SAVEAC <Q1,Q2,Q3,P1,I>
	MOVEM T1,OUTJFN
	EXCH T1,T2
	CALL G2LJ		;GET LOCAL INDEX
	 JRST DOSN8		;NONE JOB IS GONE
	EXCH T2,T1
	MOVEM T2,P1
	MOVEI I,BPRCOD
	TXZ F,SUPOUF
	TXNE F,TUNEMF		;IF TUNE MODE
	TXO F,SUPOUF		;  SUPPRESS PER JOB OUTPUT
	MOVEI Q2,NEWDAT-JDAT(T2) ;SETUP INDEXES TO NEW, OLD DATA
	MOVEI Q3,OLDDAT-JDAT(T2)
	MOVSI T4,-NJVAL		;SETUP TO SUM TIMES FOR THIS JOB
	SETZ T1,
DOSN0:	ADD T1,@JNEWT(T4)	;NEW-OLD
	SUB T1,@JOLDT(T4)
	AOBJN T4,DOSN0
DOSN8:	JXE F,ODATFL,DOSN1	;TEST IF USING THE DATA FILE
	JUMPN T1,DOSN1		;IF NOTHING HAPPENED
	CALL NOSNP		;  THEN OUTPUT DUMMY SNOOP STRING
DOSN1:	JUMPE T1,R		;JUMP IF NOTHING HAPPENED THIS TIME
	FLTR T1,T1		;FLOAT THE TIME BASE
	MOVEM T1,JBASET		;SAVE IT AS DENOMINATOR OF TIMES
	FADRM T1,SBASET		;ACCUMULATE SYSTEM TOTALS
	FLTR T3,INTRVL		;GET ACTUAL ELAPSED INTERVAL
	FDVR T1,T3		;COMPUTE DEMAND FRACTION
	FMPRI T1,(100.0)		;CONVERT TO PERCENT
	MOVE T2,T1
	CALL FLOUT6
	MOVSI Q1,-NJVAL
	MOVE T1,OUTJFN
DOSN2:	MOVE T2,@JNEWT(Q1)	;COMPUTE DELTA THIS QUANTITY
	SUB T2,@JOLDT(Q1)
	JUMPE T2,[LFMSG <     >	;BLANK IF NO TIME
		JXE F,ODATFL,DOSN5	;TEST IF USING DATA FILE
		SETZ T2,		;OUTPUT A ZERO
		MOVX T3,<FLD(3,FL%FST)!FLD(1,FL%SND)>	;OUTPUT IN 5 COLS
		CALL OFLT		;OUTPUT THE FLOATING NUMBER
		JRST DOSN5]
	FLTR T2,T2
	FADRM T2,@SSUMT(Q1)
	FDVR T2,JBASET		;COMPUTE FRACTION
	FMPRI T2,(100.0)	;CONVERT TO PERCENT
	MOVEI T3,3B23+1B29
	CALL LFLOUT		;OUTPUT IN 5 COLS
DOSN5:	AOBJN Q1,DOSN2
	MOVE T2,JINMEM(Q2)	;WS IN MEM INTEGRAL
	SUB T2,JINMEM(Q3)
	FLTR T2,T2
	FADRM T2,SMEMD		;SYSTEM SUM
	FLTR T3,INTRVL
	FDVR T2,T3		;COMPUTE AV TIME IN MEM
	FMPRI T2,(100.0)	;AS PCT
	CALL FLOUT6
	MOVE T2,JNWSL(Q2)	;COMPUTE NUMBER WS LOADS
	SUB T2,JNWSL(Q3)
	ADDM T2,SNWSL
	MOVX T3,4B17
	CALL LNOUT
	MOVE T4,JNINTR(Q2)	;COMPUTE NUMBER INTERACTIONS
	SUB T4,JNINTR(Q3)
	JUMPE T4,[LFMSG <              > ;BLANK IF NO CHANGE
		JXE F,ODATFL,DOSN3	;TEST IF USING DATA FILE
		SETZ T2,		;OUTPUT A ZERO FOR THE FIELD
		MOVX T3,<FLD(5,NO%COL)!FLD(^D10,NO%RDX)>;OUTPUT IN 5 COLS
		CALL ONUM		;OUTPUT NRSP
		MOVX T3,<FLD(3,FL%FST)!FLD(2,FL%SND)>	;OUTPUT IN 6 COLS
		CALL OFLT		;OUTPUT RESP
		MOVX T3,<FLD(3,NO%COL)!FLD(^D10,NO%RDX)>;OUTPUT IN 3 COLS
		CALL ONUM		;OUTPUT SR
		JRST DOSN3]
	MOVE T2,T4
	FLTR T4,T4
	FADRM T4,SNINTR		;SYSTEM TOTAL
	MOVSI T3,5
	CALL LNOUT		;PRINT NUMBER INTERACTIONS
	MOVE T2,JINTR(Q2)	;COMPUTE INTERACTIVE USED TIME
	SUB T2,JINTR(Q3)
	FLTR T2,T2
	MOVEM T2,JINTR(Q3)	;SAVE IT
	FADRM T2,SINTR		;SYSTEM TOTAL
	FDVR T2,T4		;COMPUTE MS PER INTERACTION
	FDVRI T2,(1000.0)	;CONVERT TO SECONDS
	MOVEI T3,3B23+2B29
	CALL LFLOUT
	MOVE T4,JINTIM(Q2)	;COMPUTE RUNTIME USED
	SUB T4,JINTIM(Q3)
	FLTR T4,T4
	FADRM T4,SINTIM		;SYSTEM TOTAL
	MOVE T2,JINTR(Q3)	;TOTAL NON-IDLE TIME
	FDVR T2,T4		;RATIO OF TOTAL TO USED - STRETCH FACTOR
	FIXR T2,T2
	MOVX T3,3B17
	CALL LNOUT
	FLTR T2,INTRVL
	FSBR T2,JINTR(Q3)		;COMPUTE BLOCKED TIME DURING INTERVAL
	FADRM T2,SSBLKT		;ACCUMULATE SYS TOTAL
DOSN3:	MOVE T4,JNNR(Q2)	;COMPUTE WS SIZE BASE
	SUB T4,JNNR(Q3)
	JUMPE T4,[LFMSG <      >
		JXE F,ODATFL,DOSN6	;TEST IF USING DATA FILE
		SETZ T2,		;OUTPUT ZERO FOR DATA
		MOVX T3,<FLD(4,FL%FST)!FLD(1,FL%SND)>	;OUTPUT IN 6 COLS
		CALL OFLT		;OUTPUT WSS
		JRST DOSN6]
	FLTR T4,T4
	FADRM T4,SNNR		;ACCUMULATE SYS TOTAL
	MOVE T2,JNR(Q2)		;COMPUTE WS SIZE INTEGRAL CHANGE
	SUB T2,JNR(Q3)
	FLTR T2,T2
	FADRM T2,SNR		;SYSTEM TOTAL
	FDVR T2,T4
	FADRM T2,SSWSS		;SYSTEM TOTAL WS SIZES
	FLTR T2,JOBWSM(P1)	;GET JOB MAX WSS
	MOVEI T3,5B23+1B29
	CALL LFLOUT
DOSN6:	MOVE T4,JNWSP(Q2)
	SUB T4,JNWSP(Q3)	;COMPUTE WSP BASE
	JUMPE T4,[LFMSG <      >
		JXE F,ODATFL,DOSN4	;TEST IF USING DATA FILE
		SETZ T2,		;OUTPUT ZERO FOR DATA
		MOVX T3,<FLD(5,FL%FST)!FLD(1,FL%SND)>	;OUTPUT IN 6 COLS
		CALL OFLT		;OUTPUT UPGS
		JRST DOSN4]
	FLTR T4,T4
	FADRM T4,SNWSP		;SYSTEM TOTAL
	MOVE T2,JWSP(Q2)
	SUB T2,JWSP(Q3)		;COMPUTE USED INTEGRAL CHANGE
	FLTR T2,T2
	FADRM T2,SWSP		;SYSTEM TOTAL
	FDVR T2,T4
	MOVX T3,<FLD(5,FL%FST)!FLD(1,FL%SND)>	;IN 6 COLS
	CALL LFLOUT
DOSN4:	MOVE T2,JNSWPR(Q2)		;GET NUMBER SWAP READS
	SUB T2,JNSWPR(Q3)
	MOVEM T2,T4		;SAVE FOR TOTAL NUMBER PAGE FAULTS
	ADDM T2,SNSWPR		;ACCUMULATE SYSTEM TOTAL
	MOVSI T3,5
	CALL LNOUT
	MOVE T2,JNDSKR(Q2)
	SUB T2,JNDSKR(Q3)
	ADDM T2,T4		;NUMBER DISK READS - ACCUMULATE TOTALS
	ADDM T2,SNDSKR
	CALL LNOUT
	JUMPE T4,[LFMSG <        >	;NO AVERAGE IF 0
		JXE F,ODATFL,DOSN7	;TEST IF USING DATA FILE
		SETZ T2,		;OUTPUT A ZERO FOR DATA
		MOVX T3,<FLD(4,NO%COL)!FLD(^D10,NO%RDX)>;OUTPUT IN 4 COLS
		CALL ONUM		;OUTPUT TPF
		CALL ONUM		;OUTPUT IFA
		JRST DOSN7]
	MOVE T2,JSWPR(Q2)	;GET TOTAL SWAP AND DISK LATENCIES
	SUB T2,JSWPR(Q3)
	ADD T2,JDSKR(Q2)
	SUB T2,JDSKR(Q3)
	ADDM T2,SPGF
	IDIV T2,T4		;COMPUTE AVERAGE FAULT WAIT TIME
	MOVSI T3,4
	CALL LNOUT
	MOVE T2,JUSED(Q2)	;COMPUTE USED CPU TIME
	SUB T2,JUSED(Q3)
	IDIV T2,T4		;USED TIME PER FAULT
	MOVX T3,4B17
	CALL LNOUT
DOSN7:	RET

;G2LJ - FIND LOCAL JOB INDEX FROM GLOBAL NUMBER
;
;ACCEPTS:
;	T1/ GLOBAL JOB NUMBER
;
;RETURNS:
;	+1 T1/ 0 FAILURE
;	+2 T2/ LOCAL JOB INDEX

G2LJ:	SAVEAC <T2,T3,I>
	MOVE T2,[-1,,T1]	;LENGTH 1 ADDRESS AC1
	MOVEI T3,.JILJI		;GET LOCAL INDEX
	GETJI
	 ERJMP [SETZ T1,
		RET]
	RETSKP
;DO SYSTEM TOTALS - CALLED ONCE AT END OF ALL JOBS
; T1/ OUTJFN

SNPSUM::CAIN T1,.NULIO		;NULL OUTPUT?
	RET			;DO NOTHING
	SAVEAC <Q1,Q2,Q3,I>
	MOVEM T1,OUTJFN
	TXZ F,SUPOUF
	JXE F,ODATFL,SNPSU0	;JUMP IF NOT USING DATA FILE
	TXNN F,TUNEMF		;SKIP IF IN TUNE MODE
	CALL SYSHED		;OUTPUT RECORD HEADER FOR SYSTEM TOTALS
SNPSU0:	MOVE T2,SBASET		;TOTAL DEMAND SUM
	FLTR T3,INTRVL		;ACTUAL INTERVAL
	FDVR T2,T3		;SYSTEM DEMAND RATIO
	FMPRI T2,(100.0)		;PERCENTAGE
	TXNN F,TUNEMF		;SKIP IF TUNE MODE
	CALL FLOUT6
	MOVSI Q1,-NJVAL
SNPSU1:	MOVE T2,@SSUMT(Q1)	;SYSTEM TOTAL THIS VARIABLE
	JUMPE T2,[LFMSG <     >	;BLANK IF NO EVENTS
		JXE F,ODATFL,SNPSU2	;TEST IF USING DATA FILE
		SETZ T2,		;OUTPUT A ZERO
		MOVX T3,<FLD(3,FL%FST)!FLD(1,FL%SND)>	;OUTPUT IN 5 COLS
		CALL OFLT		;OUTPUT THE FLOATING NUMBER
		JRST SNPSU2]
	FDVR T2,SBASET		;COMPUTE FRACTION
	FMPRI T2,(100.0)	;PERCENTAGE
	MOVEI T3,3B23+1B29
	CALL LFLOUT
SNPSU2:	AOBJN Q1,SNPSU1
	MOVE T2,SMEMD		;WS IN MEM SUM
	FLTR T3,INTRVL
	FDVR T2,T3		;COMPUTE TOTAL OF COLUMN
	FMPRI T2,(100.0)	;AS PCT
	CALL FLOUT6
	MOVE T2,SNWSL
	MOVX T3,4B17
	CALL LNOUT		;NUMBER WS LOADS
	MOVE T4,SNINTR		;TOTAL NUMBER INTERACTIONS
	JUMPE T4,[LFMSG <              >
		JXE F,ODATFL,SNPSU3	;TEST IF USING DATA FILE
		SETZ T2,		;OUTPUT A ZERO FOR THE FIELD
		MOVX T3,<FLD(5,NO%COL)!FLD(^D10,NO%RDX)>;OUTPUT IN 5 COLS
		CALL ONUM		;OUTPUT NRSP
		MOVX T3,<FLD(3,FL%FST)!FLD(2,FL%SND)>	;OUTPUT IN 6 COLS
		CALL OFLT		;OUTPUT RESP
		MOVX T3,<FLD(3,NO%COL)!FLD(^D10,NO%RDX)>;OUTPUT IN 3 COLS
		CALL ONUM		;OUTPUT SR
		JRST SNPSU3]
	FIXR T2,SNINTR
	MOVSI T3,5		;PRINT TOTAL NUMBER INTERACTIONS
	CALL LNOUT
	MOVE T2,SINTR		;TOTAL NON-IDLE TIME
	FDVR T2,T4
	FDVRI T2,(1000.0)	;CONVERT TO SECONDS
	MOVEI T3,3B23+2B29
	CALL LFLOUT
	MOVE T2,SINTR		;TOTAL NON-IDLE TIME
	FDVR T2,SINTIM		;TOTAL USED TIME
	FIXR T2,T2
	MOVX T3,3B17
	CALL LNOUT		;AVERAGE STRETCH FACTOR
SNPSU3:	TXNE F,TUNEMF		;TUNE MODE?
	RET			;YES, DONE
	FLTR T2,SYSWSM		;GET SYS TOTAL WS
	MOVEI T3,5B23+1B29	;PRINT AS INTEGER
	CALL LFLOUT
	FLTR T4,INTRVL		;ACTUAL TIME INTERVAL
	MOVE T2,SWSP		;USED PAGES TOTAL INTEGRAL
	FDVR T2,T4		;COMPUTE AV CORE USED
	MOVEM T2,SUPGS		;SAVE IT
	MOVEI T3,5B23+1B29
	CALL LFLOUT
SNPSU4:	MOVE T2,SNSWPR		;TOTAL SWAP READS
	MOVSI T3,5
	CALL LNOUT
	MOVE T2,SNDSKR		;TOTAL DISK READS
	CALL LNOUT
	ADD T2,SNSWPR		;DISK AND DRUM READS = PAGE FAULTS
	JUMPE T2,[LFMSG <        >	;LEAVE BLANK IF NONE
		JXE F,ODATFL,SNPSU5	;TEST IF USING DATA FILE
		SETZ T2,		;OUTPUT ZERO FOR DATA
		MOVX T3,<FLD(4,NO%COL)!FLD(^D10,NO%RDX)>	;IN 4 COLS
		CALL ONUM		;OUTPUT TPF
		CALL ONUM		;OUTPUT IFA
		JRST SNPSU5]
	MOVE T4,T2
	MOVE T2,SPGF		;TOTAL PAGE FAULT TIME
	IDIV T2,T4		;AVERAGE PAGE FAULT TIME
	MOVX T3,4B17
	CALL LNOUT
	FIXR T2,SUSED
	IDIV T2,T4		;AVERAGE INTERFAULT AV
	MOVX T3,4B17
	CALL LNOUT
SNPSU5:	JXE F,ODATFL,SNPSU6	;TEST IF USING DATA FILE
	CALL PRIREC		;PRINT THE RECORD
	MOVEI T1,5		;ENTRY RECORD TYPE FOR EXPANDED PER JOB RECORD
	CALL SETHD		;SET THE ENTRY RECORD HEADER
	CALL OCACHE		;OUTPUT THE CACHE STATICS
	MOVE T1,OUTJFN		;GET THE OUTPUT JFN
SNPSU6:	LFMSG <

TOTRC: >
	MOVE T2,TOTRC
	MOVX T3,5B17
	CALL LNOUT
	LFMSG <   LOKPGS: >
	MOVE T2,LOKPGS
	MOVX T3,5B17
	CALL LNOUT
	LFMSG <   SHR PGS: >
	MOVE T2,BALSHC
	SUB T2,LOKPGS
	MOVX T3,5B17
	CALL LNOUT
	LFMSG <   AVAIL MEM: >
	MOVE T2,TOTRC
	SUB T2,LOKPGS
	MOVX T3,5B17
	CALL LNOUT
	LFMSG <
NRUN MIN,MAX:	>
	MOVE T2,MINNG
	MOVX T3,5B17
	CALL LNOUT
	MOVE T2,MAXNG
	CALL LNOUT
	; ..
	; ..
	LFMSG <
SUMNR MIN,MAX:	>
	MOVE T2,MINNB
	MOVX T3,5B17
	CALL LNOUT
	MOVE T2,MAXNB
	CALL LNOUT
	LFMSG <
NRPLQ MIN,MAX:	>
	MOVE T2,MINRP
	MOVX T3,5B17
	CALL LNOUT
	MOVE T2,MAXRP
	CALL LNOUT
	LFMSG <
SYS MEM DMD =				>
	MOVE T2,SNR
	FLTR T4,INTRVL
	FDVR T2,T4
	MOVEM T2,SMDMD
	MOVEI T3,5B23+1B29
	CALL LFLOUT
	MOVE T4,TOTRC
	SUB T4,LOKPGS
	FLTR T4,T4
	LFMSG <
SWAP RATIO (SUM WSS / AV MEM) =		>
	FLTR T2,SYSWSM
	FDVR T2,T4
	MOVEI T3,5B23+2B29
	CALL LFLOUT
	LFMSG <
ACTIVE SWAP RATIO (DMD/AVMEM) =		>
	MOVE T2,SMDMD
	FDVR T2,T4
	MOVEI T3,5B23+2B29
	CALL LFLOUT
	LFMSG <
MEM UTILIZATION ((UPGS+SHRPGS)/AVMEM) =	>
	MOVE T2,BALSHC
	SUB T2,LOKPGS		;COMPUTE SHARED PAGES
	FLTR T2,T2
	FADR T2,SUPGS		;ADD SHARED AND USED
	FDVR T2,T4
	MOVEI T3,5B23+2B29
	CALL LFLOUT
	LFMSG <
AV WS SIZE = 				>
	MOVE T2,SNR
	FDVR T2,SNNR
	MOVEI T3,5B23+2B29
	CALL LFLOUT
	LFMSG <
AV CPU TIME (MS) PER INTERACTION =	>
	MOVE T2,SINTIM
	FDVR T2,SNINTR
	MOVEI T3,5B23+2B29
	CALL LFLOUT
	LFMSG <
THINK TIME (SEC) PER INTERACTION =	>
	MOVE T2,SSBLKT
	FDVRI T2,(1000.0)	;CONVERT TO SECONDS
	FDVR T2,SNINTR
	MOVEI T3,5B23+2B29
	CALL LFLOUT
	RET
;LOCAL FLOUT ROUTINES
; FLOUT6 - XXX.X IN 6 COLUMNS
; LFLOUT - <NUMBER DIGITS BEFORE POINT>B23 + <NUMBER DIGITS AFTER POINT>B29
; T2/ NUMBER

FLOUT6:	MOVEI T3,4B23+1B29
LFLOUT:	MOVE T1,OUTJFN
	TXNE F,SUPOUF		;SUPPRESS OUTPUT?
	RET			;YES
	TXO T3,FL%ONE!FL%PNT!FL%OVL
	TXNE F,ODATFL		;TEST IF USING DATA FILE
	CALL OFLT		;OUTPUT A FLOATING POINT NUMBER
	FLOUT
	 NOP
	MOVE T1,OUTJFN		;IN CASE ERROR
	RET

;LOCAL NOUT
; T3/ <NUMBER COLUMNS>B17, RADIX DEFAULTS TO 10 IF NOT SUPPLIED

LNOUT:	TRNN T3,-1		;RADIX GIVEN?
	HRRI T3,^D10		;NO, USE 10
	TXNE F,SUPOUF		;SUPPRESS OUTPUT?
	RET			;YES
	TXO T3,NO%LFL+NO%OOV+NO%AST
	TXNE F,ODATFL		;TEST IF USING DATA FILE
	CALL ONUM		;OUTPUT THE NUMBER
	NOUT
	 NOP			;DON'T CLUTTER UP OUTPUT WITH ERR MSGS
	MOVE T1,OUTJFN		;IN CASE ERROR
	RET

;LOCAL MSG OUT

LFMSGX:	TXNE F,SUPOUF		;SUPPRESS OUTPUT?
	RET			;YES
	SETZ T3,
	SOUT
	RET
;PRINT DISK STATISTICS

DSKOUT::ASUBR <THEJFN>
	FMSG<
			DISK I/O

CHN,KON,UNIT	SEEKS		READS		WRITES		READ-VERIFIES	STRUCTURE
>
	MOVSI T4,-NDSKS
	SETZ P1,		;INITIALIZE THE RECORD COUNTER
DSKOU0:	SKIPN UDBS(T4)		;THIS DISK EXIST?
	JRST DSKOU1		;NO. SKIP IT
	AOS P1			;INCREMENT THE RECORD COUNTER
	LOAD T2,DOP%C2,DSKCKU(T4) ;GET CHANNEL NUMBER
	MOVX T3,<FLD(2,NO%COL)!FLD(^D8,NO%RDX)>	;OUTPUT IN 2 COLS
	CALL LNOUT		;DO CHANNEL
	LFMSG <,>
	LOAD T2,DOP%K2,DSKCKU(T4) ;GET CONTROLLER NUMBER
	CAIN T2,<.RTJST(-1,DOP%K2)> ;NO CONTROLLER (-1)?
	SETOM T2		;YES, MAKE IT A FULL WORD
	MOVX T3,<FLD(2,NO%COL)!FLD(^D8,NO%RDX)>	;OUTPUT IN 2 COLS
	CALL LNOUT		;OUTPUT IT
	LFMSG <,>
	LOAD T2,DOP%U2,DSKCKU(T4) ;GET UNIT NUMBER
	MOVX T3,<FLD(3,NO%COL)!FLD(^D8,NO%RDX)>	;OUTPUT IN 3 COLS
	CALL LNOUT		;DO UNIT
	LFMSG <	>
	PUSH P,T4		;SAVE INDEX
	IMULI T4,UDBCNT		;INDEX TO NUMBERS
	MOVE T2,NEWIO+UDBSEK(T4)
	SUB T2,OLDIO+UDBSEK(T4)
	MOVX T3,<FLD(6,NO%COL)!FLD(^D10,NO%RDX)>	;OUTPUT IN 6 COLUMNS
	SKIPE T2		;IF NOT NULL
	CALL LNOUT		;DO SEEKS
	JUMPN T2,DSK1
	TXNE F,ODATFL		;TEST IF USING DATA FILE
	CALL ONUM		;OUTPUT THE NUMBER
DSK1:	LFMSG <		>
	MOVE T2,NEWIO+UDBRCT(T4) ;GET READS
	SUB T2,OLDIO+UDBRCT(T4)	;COMPUTE DIFFERENCE
	MOVX T3,<FLD(6,NO%COL)!FLD(^D10,NO%RDX)>	;OUTPUT IN 6 COLUMNS
	SKIPE T2
	CALL LNOUT
	JUMPN T2,DSK2
	TXNE F,ODATFL		;TEST IF USING DATA FILE
	CALL ONUM		;OUTPUT THE NUMBER
DSK2:	FMSG<		>
	MOVE T2,NEWIO+UDBWCT(T4)	;GET WRITES
	SUB T2,OLDIO+UDBWCT(T4)
	MOVX T3,<FLD(6,NO%COL)!FLD(^D10,NO%RDX)>	;OUTPUT IN 6 COLUMNS
	SKIPE T2
	CALL LNOUT
	JUMPN T2,DSK3
	TXNE F,ODATFL		;TEST IF USING DATA FILE
	CALL ONUM		;OUTPUT THE NUMBER
DSK3:	FMSG<		>
	MOVE T2,NEWIO+UDBRVC(T4)	;GET READ-AFTER-WRITES
	SUB T2,OLDIO+UDBRVC(T4)
	MOVX T3,<FLD(6,NO%COL)!FLD(^D10,NO%RDX)>	;OUTPUT IN 6 COLUMNS
	SKIPE T2
	CALL LNOUT
	JUMPN T2,DSK4
	TXNE F,ODATFL		;TEST IF USING DATA FILE
	CALL ONUM		;OUTPUT THE NUMBER
DSK4:	HRRZ T4,0(P)		;GET INDEX AGAIN
	LSH T4,1		;GET "NAMES" INDEX
	MOVEI T2,NAMES(T4)
	JXE F,ODATFL,DSK5	;TEST IF USING DATA FILE
	CALL ODSKNM		;OUTPUT THE DISK NAME
	SKIPE NAMES(T4)		;IF THERE IS NO DISK NAME
	JRST DSK5
	SETZ T2,		;  THEN OUTPUT A ZERO FOR A DISK NUMBER
	MOVX T3,<FLD(2,NO%COL)!FLD(^D10,NO%RDX)>	;OUTPUT IN 2 COLS
	CALL ONUM		;OUTPUT THE ZERO DISK NUMBER
DSK5:	SKIPN NAMES(T4)		;HAVE A NAME?
	JRST DSKOUX		;NO
	MOVE T1,THEJFN
	LFMSG <		>
	HRROI T2,NAMES(T4)	;YES. POINT TO IT
	SETZM T3
	SOUT			;TYPE IT
	LFMSG < #>
	HRRZ T2,NAMES+1(T4)	;GET UNIT NUMBER
	MOVX T3,2B17
	CALL LNOUT
DSKOUX:	LFMSG <
>
	POP P,T4		;GET BACK INDEX
DSKOU1:	AOBJN T4,DSKOU0		;DO THEM ALL
	TXNN F,ODATFL		;TEST IF USING DATA FILE
	RET			;AND RETURN IF NOT
	CALL ODFIL		;FILL OUT THE RECORD ENTRIES
	CALL PRIREC		;OUTPUT THE RECORD
	RET
; DOCACH - ROUTINE TO OUTPUT DIRECTORY CACHE STATISTICS
;
;ACCEPTS IN T1/	OUTPUT JFN

DOCACH::MOVEI D,BPRCOD		;GET BASE ADDRESS OF DATA
	HRROI B,[ASCIZ/
Directory Cache hits: /]
	SETZM C			;TERMINATE ON NULL
	SOUT			;OUTPUT HEADING
	MOVE B,NCHITS(D)	;GET NUMBER OF CACHE HITS
	MOVEI C,^D10		;USE DECIMAL
	NOUT			;OUTPUT NUMBER OF HITS
	 JFCL
	HRROI B,[ASCIZ/
Directory Cache Misses - Cache Full: /]
	SETZM C			;TERMINATE ON NULL
	SOUT			;OUTPUT NEXT HEADING
	MOVE B,NCFULL(D)	;GET NUMBER OF MISSES WITH CACHE FULL
	MOVEI C,^D10		;USE DECIMAL
	NOUT
	 JFCL
	HRROI B,[ASCIZ/
Directory Cache Misses - New Entry Added: /]
	SETZM C			;TERMINATE ON NULL
	SOUT			;OUTPUT FINAL HEADING
	MOVE B,NCADD(D)		;GET NUMBER OF NEW ENTRIES ADDED
	MOVEI C,^D10		;USE DECIMAL
	NOUT			;OUTPUT NUMBER OF "FULL MISSES"
	 JFCL
	CALL CRLF		;OUTPUT FINAL CRLF
	MOVE A,NCHITS(D)	;LOAD A WITH NUMBER OF HITS
	MOVE B,NCFULL(D)	;LOAD B WITH NUMBER OF MISSES
	MOVE C,NCADD(D)		;LOAD C WITH NUMBER OF BOTH TYPES
	SETZM NCHITS(D)		;RESET NUMBER OF HITS
	SETZM NCFULL(D)		;RESET NUMBER OF MISSES
	SETZM NCADD(D)		; OF BOTH TYPES
	TXNE F,ODATFL		;TEST IF USING DATA FILE
	CALL CACBUF		;DUMP CACHE STATS TO DATA BUFFER
	RET			;DONE, RETURN
;TABLE OF QUANTITIES TO PRINT AS PERCENTAGE OF TIME - NEW VALUES

JNEWT:	Z JUSED(Q2)
	Z JGRDY(Q2)
	Z JBRDY(Q2)
	Z JSWPR(Q2)
	Z JDSKR(Q2)
	Z JDSKW(Q2)
	Z JRPQ(Q2)
	Z JBSW(Q2)
NJVAL==.-JNEWT

; - OLD VALUES

JOLDT:	Z JUSED(Q3)
	Z JGRDY(Q3)
	Z JBRDY(Q3)
	Z JSWPR(Q3)
	Z JDSKR(Q3)
	Z JDSKW(Q3)
	Z JRPQ(Q3)
	Z JBSW(Q3)
IFN .-JOLDT-NJVAL,<PRINTX JOLDT SIZE INCONSISTENT>

; - SYSTEM TOTALS

SSUMT:	Z SUSED
	Z SGRDY
	Z SBRDY
	Z SSWPR
	Z SDSKR
	Z SDSKW
	Z SRPQ
	Z SBSW
IFN .-SSUMT-NJVAL,<PRINTX SSUMT SIZE INCONSISTENT>
PNTSYM:	STKVAR <OJFN,VAL>
	MOVEM T1,OJFN
	MOVEM T2,VAL
	HRROI T1,SYMBOL
	SETZ T3,
	CALL ADR2ST
	 JRST [	MOVE T1,OJFN
		MOVE T2,VAL
		MOVEI T3,^D8
		NOUT
		 NOP
		MOVEI T2,7	;ASSUMED MAX NUMBER CHARACTERS
		RET]
	MOVE T1,OJFN
	HRROI T2,SYMBOL
	SETZ T3,
	SOUT
	MOVE T1,T2
	MOVE T2,[POINT 7,SYMBOL]
	CALL SUBBP7		;COMPUTE NUMBER CHARACTERS OUT
	MOVEI T2,-1(T1)		;DON'T COUNT NULL
	MOVE T1,OJFN		;PRESERVE
	RET

;SUBTRACT 7-BIT BYTE PTRS, AC1-AC2

SUBBP7:	HRRZ T3,T1
	SUBI T3,0(T2)		;WORD DIFFERENCE
	IMULI T3,5
	LDB T1,[POINT 6,T1,5]	;GET BYTE POSITIONS
	LDB T2,[POINT 6,T2,5]
	SUBM T2,T1		;BIT DIFFERENCE
	IDIVI T1,7
	ADD T1,T3		;COMBINE WORD AND BIT DIFFERENCES
	RET
GETADR:	MOVE T1,[100,,101]
	HRROI T2,STRING
	MOVE T3,[RD%BRK!RD%TOP!RD%JFN+STRNGL]
	RDTXT
	 JSHLT
	HRROI T1,STRING
	MOVEI T3,10
	NIN
	 JSHLT
	POPJ P,


;BREAKPOINT INSTRUCTIONS

DEFINE BPTR (Q)<
	BPTR1(\Q)>

   DEFINE BPTR1 (Q)<
	XBP'Q'R,,BP'Q'R>

BPI:
   XX==1
   REPEAT NBPT,<
	BPTR XX
	XX=XX+1>

DEFINE XBP1 (Q)<
	XBP2 (\Q)>

   DEFINE XBP2 (Q)<
BP'Q'ADR: 0>

   XX==1
   REPEAT NBPT,<
	XBP1 XX
	XX=XX+1>

DEFINE SYM (NAME,PTR,MODUL,OFFSET)<
	RADIX50 0,NAME
   IFNB <MODUL>,<RADIX50 0,MODUL>
   IFB <MODUL>,<0>
   IFNDEF NAME,<
NAME:>
	XWD OFFSET,PTR>

;LITERALS XLISTED

	XLIST
	LIT
	LIST

ONCEF:	0			;NON-0 AFTER PROGRAM STARTED
LNJOBS:	0			;NJOBS OBTAINED FROM MONITOR SYMTAB
LNFKS:	0			;NFKS OBTAINED FROM MONITOR SYMTAB
OUTJFN:	0
JBASET:	0
PIPC1:	0
PIPC2:	0
PIPC3:	0
QUITF:	0
INTAC1:	0

;SYSTEM TOTALS

SBASET:	0
SMEMD:	0			;TOTAL WS IN MEM
SNWSL:	0			;NUMBER WS LOADS
SNINTR:	0
SINTR:	0
SINTIM:	0
SNNR:	0
SNR:	0
SNWSP:	0
SWSP:	0
SSWSS:	0			;SUM OF JOB WSS
SSBLKT:	0			;SUM OF JOB BLOCKED TIMES
SUPGS:	0
SUSED:	0
SGRDY:	0
SBRDY:	0
SSWPR:	0
SDSKR:	0
SDSKW:	0
SRPQ:	0
SBSW:	0
SPGF:	0
SNSWPR:	0
SNDSKR:	0
 NSYSV==.-SBASET		;NUMBER SYSTEM VARIABLES

TOTRC:	0
LOKPGS:	0
MINNG:	0
MAXNG:	0			;NGOJOB MIN, MAX
MINNB:	0
MAXNB:	0			;SUMNR MIN,MAX
MINRP:	0
MAXRP:	0
BALSHC:	0

SMDMD:	0			;SYS MEM DEMAND
SYSWSM:	0			;SYS WS MAX

JOBWSM:	BLOCK NJOBS		;JOB WS MAX

	STRNGL==20
STRING:	BLOCK STRNGL

SYMBOL:	BLOCK 10

	PRGNML==40
PRGNAM:	BLOCK PRGNML
;MACROS FOR GENERATING MONITOR AND LOCAL REFERENCES IN RELOCATED CODE

;MONITOR SYMBOL REFERENCE

DEFINE MONREF (INST,MSY,%TAG)<
%TAG:!	INST
	MONRR <SYM MSY,%TAG
>>

;SET OF REMOTE MACROS FOR ABOVE

DEFINE MONRR (..XXX)<
	MONRR2 <..XXX>,
>

DEFINE MONRR2 (..NEW,..OLD)<
   DEFINE MONRR (..XXX)<
	MONRR2 <..XXX>,<..OLD
	..NEW
>>>

DEFINE MONRH <
   DEFINE MONRR2 (..NEW,..OLD)<
	..OLD>
   MONRR ()>

;LOCAL SYMBOL REFERENCE

DEFINE LOCREF (INST,LSY,%TAG)<
%TAG:!	INST
	LOCRR < %TAG,,LSY
>>

;SET OF REMOTE MACROS FOR ABOVE

DEFINE LOCRR (..XXX)<
	LOCRR2 <..XXX>,
>

DEFINE LOCRR2 (..NEW,..OLD)<
   DEFINE LOCRR (..XXX)<
	LOCRR2 <..XXX>,<..OLD
	..NEW
>>>

DEFINE LOCRH <
   DEFINE LOCRR2 (..NEW,..OLD)<
	..OLD>
   LOCRR ()>
DEFINE BP (Q)<
 XBP'Q'R:0
	0
	0
	LOCREF <0>,XBP'Q'

 BP'Q'R: 0
 XBP'Q':
	LOCREF <MOVEM I,>,SAV1I
	LOCREF <MOVE I,>,INDEX
   >

DEFINE ENDBP (Q)<
	MOVE I,SAV1I(I)
	LOCREF <SKIPE>,MONTYP
	LOCREF <XJRSTF>,XBP'Q'R
	LOCREF <JRSTF @0>,BP'Q'R>

LOC BPRPAG_11
PHASE 0

BPR:

;COMMON CODE FOR THESE BPTS

DEFINE BBPT <
	DMOVEM T1,SAV1T1(I)	;SAVE T1-T4
	DMOVEM T3,SAV1T3(I)
	HRRZ T1,Q3		;GET FORK INDEX
	ADD T1,I		;OFFSET INTO DATA AREA
	MONREF <HLRZ T2,0(Q3)>,FKJOB ;GET JOB NUMBER
	ADD T2,I		;OFFSET INTO DATA AREA
	MONREF <MOVE T3,>,TODCLK ;GET CURRENT TIME
	SUBM T3,FKLEV(T1)	;COMPUTE TIME SINCE LAST EVENT
	EXCH T3,FKLEV(T1)	;SAVE CURRENT TIME, LEAVE DIFFERENCE
   >

DEFINE EBPT (NN)<
	DMOVE T1,SAV1T1(I)	;RESTORE ACS
	DMOVE T3,SAV1T3(I)
	ENDBP NN
   >

;UPDATE WORKING SET SIZE COMMON CODE

DEFINE UPDWSS <
	ADDM T3,JNNR(T2)	;ACCUMULATE TIME DIVISOR
	MONREF <HRRZ T4,0(Q3)>,FKNR ;GET CURRENT WS SIZE
	CAMLE T4,FKWSIZ(T1)	;KEEP MAX SIZE SEEN
	MOVEM T4,FKWSIZ(T1)
	IMUL T4,T3		;COMPUTE INTEGRAL SIZE.DT
	ADDM T4,JNR(T2)
	MONREF <HLRZ T4,0(Q3)>,FKJOB
	MOVEM T4,FKJB(T1)	;SAVE JOB INDEX
   >

;UPDATE USED PAGES COMMON CODE

DEFINE UPDUPG <
	MOVE T4,TODBIV(I)
	SKIPN FKMTIM(T1)		;ALREADY NOTED IN MEM?
	MOVEM T4,FKMTIM(T1)		;NO, DO IT
	ADDM T3,JNWSP(T2)
	MONREF <HRRZ T4,0(Q3)>,FKWSP ;GET CURRENT USAGE
	IMUL T4,T3
	ADDM T4,JWSP(T2)
   >

;UNBLOCK - SCHEDJ

BP 4
	BBPT
	JSR UNBLK(I)		;DO THE WORK
	EBPT 4

UNBLK:	0
	ADDM T3,JIDLE(T2)	;PREVIOUS STATE WAS IDLE
	SETZM FKUNBT(T1)	;CLEAR START OF INTERACTION
	MONREF <HRRZ T4,0(Q3)>,FKSTAT
	MONREF <CAIA T4,>,TCITST ;WAIEUP FROM TTY INPUT? (DISABLED)
	JRST BPT4(I)		;NO, DON'T COUNT INTERACTION
	MOVE T3,FKLEV(T1)	;SAVE CURRENT TIME FOR
	MOVEM T3,FKUNBT(T1)	; FULL CYCLE RESPONSE TIME
BPT4:	SETZM FKIRT(T1)		;CLEAR INCREMENTAL RUNTIME
	MONREF <MOVE T4,>,TOTRC	;SAVE CURRENT STATIC VARIABLES
	MOVEM T4,XTOTRC(I)
	MONREF <MOVE T4,>,LOKPGS
	MOVEM T4,XLOKPG(I)
	MONREF <MOVE T4,>,BALSHC
	MOVEM T4,XBALSH(I)
	MONREF <MOVE T4,>,NGOJOB
	CAMGE T4,XMINNG(I)	;NEW MIN?
	MOVEM T4,XMINNG(I)
	ADDI T4,1		;INCLUDE THIS FORK
	CAMLE T4,XMAXNG(I)	;NEW MAX?
	MOVEM T4,XMAXNG(I)
	JRST @UNBLK(I)

;UNBLOCK FROM HDISMS - BP1

BP 13
	BBPT
	JSR UNBLK(I)		;SAME AS REGULAR UNBLOCK
	EBPT 13

;WS ENTRY - LDJB3

BP 3
	BBPT
	UPDWSS
	ADDM T3,JGRDY(T2)	;PREVIOUS STATE WAS GOLIST READY
	MOVE T4,FKLEV(T1)	;GET CURRENT TIME
	MOVEM T4,FKMTIM(T1)	;INIT IN MEM TIME
	AOS JNWSL(T2)		;COUNT WS LOADS
	EBPT 3

;END BALANCE SET WAIT - FRIBP3

BP 5
	BBPT
	JSR BSW1(I)		;DO THE WORK
	EBPT 5

BSW1:	0
	UPDWSS			;UPDATE WS DATA
	UPDUPG
	MONREF <MOVE T4,>,SUMNR
	CAMGE T4,XMINNB(I)	;NEW MIN OR MAX?
	MOVEM T4,XMINNB(I)
	CAMLE T4,XMAXNB(I)
	MOVEM T4,XMAXNB(I)
	MONREF <MOVE T4,>,NRPLQ
	CAMGE T4,XMINRP(I)	;NEW MIN OR MAX?
	MOVEM T4,XMINRP(I)
	CAMLE T4,XMAXRP(I)
	MOVEM T4,XMAXRP(I)
	MONREF <HRRZ T4,0(Q3)>,FKPGST ;GET BS WAIT TEST
	MONREF <CAIN T4,>,SWPRT ;COUNT SWAP AND DISK READS
	AOS JNSWPR(T2)
	MONREF <CAIN T4,>,DSKRT
	AOS JNDSKR(T2)
	MOVEI T1,0
	MONREF <CAIN T4,>,SWPRT
	MOVEI T1,JSWPR(T2)
	MONREF <CAIN T4,>,DSKRT
	MOVEI T1,JDSKR(T2)
	MONREF <CAIN T4,>,DWRTST
	MOVEI T1,JDSKW(T2)
	MONREF <CAIN T4,>,SWPINT
	MOVEI T1,JSWPR(T2)
	MONREF <CAIN T4,>,UDWDON
	MOVEI T1,JDSKW(T2)
	MONREF <CAIN T4,>,TRP0CT
	MOVEI T1,JRPQ(T2)
	CAIN T1,0		;MATCH ONE OF THE ABOVE?
	MOVEI T1,JBSW(T2)		;NO - CATCHALL
	ADDM T3,0(T1)
	JRST @BSW1(I)

;RUN - SKDJ2

BP 6
	BBPT
	JSR BRDY1(I)		;DO THE WORK
	EBPT 6

BRDY1:	0
	UPDWSS			;UPDATE WS DATA
	UPDUPG
	ADDM T3,JBRDY(T2)	;PREVIOUS STATE WAS READY
	JRST @BRDY1(I)

;STOP RUNNING - DISMSJ

BP 1
	JSR ERUN(I)
	EBPT 1

ERUN:	0
	BBPT
	UPDWSS			;UPDATE WORKING SET DATA
	UPDUPG
	ADDM T3,JUSED(T2)	;PREVIOUS STATE WAS USING TIME
	ADDM T3,FKIRT(T1)	;INCREMENTAL RUNTIME
	JRST @ERUN(I)

;BALSET WAIT - SCHP3

BP 10
	JSR ERUN(I)		;SAME AS STOP
	EBPT 10

;BLOCK - DISMSH

BP 7
	BBPT
	UPDWSS			;UPDATE WS DATA
	UPDUPG
	ADDM T3,JUSED(T2)	;WAS USING TIME
	ADDM T3,FKIRT(T1)	;INCREMENTAL RUNTIME
	SKIPN FKUNBT(T1)	;HAVE TIME OF START OF INTERACTION?
	JRST BPT3(I)		;NO, DON'T COUNT IT
	MOVE T3,FKIRT(T1)	;RUNTIME THIS INTERACTION
	CAIL T3,^D2000		;LESS THAN 2 SECONDS RUNTIME?
	JRST BPT3(I)		;NO, DON'T COUNT AS INTERACTION
	ADDM T3,JINTIM(T2)	;SUM INTERACTIVE USED TIME
	MOVE T3,FKLEV(T1)	;COMPUTE TIME SINCE UNBLOCK
	SUB T3,FKUNBT(T1)
	ADDM T3,JINTR(T2)	;ACCUMULATE RESPONSE AVERAGE
	AOS JNINTR(T2)
BPT3:	EBPT 7

;WS REMOVAL - REMWS

BP 2
	BBPT
	MOVE T4,TODBIV(I)
	SKIPG FKMTIM(T1)	;TIME INITED?
	MOVEM T4,FKMTIM(T1)	;NO, USE START OF INTERVAL
	MOVE T4,FKLEV(T1)	;CURRENT TIME
	SUB T4,FKMTIM(T1)	;COMPUTE TIME IN MEM
	ADDM T4,JINMEM(T2)	;ACCUMULATE
	SETZM FKMTIM(T1)	;0 WHEN WS NOT IN MEM
	MONREF <MOVE T4,0(Q3)>,FKSWP ;GET SWAP FLAGS
	TXNE T4,FKBLK		;BLOCKED?
	JRST BPT1(I)		;YES, NO COUNT
	TXNE T4,BSWTB		;BALSET WAIT?
	JRST BPT2(I)		;WAITING, CHECK CAUSE
	JSR BRDY1(I)		;WAS READY
	JRST BPT1(I)

BPT2:	JSR BSW1(I)
BPT1:	EBPT 2

;AJBALS, FORK IN BALSET - FRIBP0

BP 11
	BBPT
	JSR BRDY1(I)		;STATE IS BRDY
	EBPT 11

;AJBALS, FORK NOT IN BALSET - AJBAL5

BP 12
	BBPT
	UPDWSS
	ADDM T3,JGRDY(T2)	;STATE IS GRDY
	EBPT 12


; DIRECTORY CACHE BREAKPOINTS

BP 14
	AOS NCHITS(I)
ENDBP 14



BP 15
	AOS NCFULL(I)
ENDBP 15


BP 16
	AOS NCADD(I)
ENDBP 16
;LITERALS XLISTED

	XLIST
	LIT
	LIST

SNPDAT:				;START OF AREA CLEARED ON STARTUP

SAV1T1:	0
SAV1T2:	0
SAV1T3:	0
SAV1T4:	0
SAV1Q1:	0
SAV1I:	0
MONTYP:	0

INDEX:	0

;FOLLOWING IN ORDER - NOTE

XTOTRC:	0
XLOKPG:	0
XMINNG:	0
XMAXNG:	0
XMINNB:	0
XMAXNB:	0
XMINRP:	0
XMAXRP:	0
XBALSH:	0

TODBIV:	0			;TOD AT START OF INTERVAL

;FORK AND JOB TABLES

FKLEV:	BLOCK NFKS		;TOD OF LAST EVENT
FKUNBT:	BLOCK NFKS		;TOD OF LAST UNBLOCK
FKIRT:	BLOCK NFKS		;INCREMENTAL RUNTIME
FKMTIM:	BLOCK NFKS		;LAST MOVE IN/OUT OF MEM

FKWSIZ:	BLOCK NFKS		;MAX WS SIZE SEEN DURING INTERVAL
FKJB:	BLOCK NFKS		;JOB INDEX

JDAT:				;BEGINNING OF JOB DATA AREA

JNNR:	BLOCK NJOBS		;TIME BASE OF NR 
JNR:	BLOCK NJOBS		;INTEGRAL NR
JNWSP:	BLOCK NJOBS		;WSP TIME BASE
JWSP:	BLOCK NJOBS		;INTEGRAL WSP

JGRDY:	BLOCK NJOBS
JNSWPR:	BLOCK NJOBS	;SWAP READ WAIT
JSWPR:	BLOCK NJOBS
JNDSKR:	BLOCK NJOBS	;DSK READ WAIT
JDSKR:	BLOCK NJOBS
JDSKW:	BLOCK NJOBS
JRPQ:	BLOCK NJOBS
JBSW:	BLOCK NJOBS
JBRDY:	BLOCK NJOBS
JUSED:	BLOCK NJOBS
JNINTR:	BLOCK NJOBS	;COMPLETE CYCLE INTERACTION
JINTR:	BLOCK NJOBS
JINTIM:	BLOCK NJOBS		;INTERACTIVE USED TIME
JIDLE:	BLOCK NJOBS
JINMEM:	BLOCK NJOBS		;TIME WS IN MEM
JNWSL:	BLOCK NJOBS		;NUMBER WS LOADS
LJDAT==.-JDAT			;SIZE OF JOB DATA AREA

; DIRECTORY CACHE COUNTERS

NCHITS:	0			;NUMBER OF CACHE HITS
NCFULL:	0			;NUMBER OF MISSES, CACHE FULL
NCADD:	0			;NUMBER OF MISSES, NEW ENTRY ADDED

BPRLEN==.-BPR

	BLOCK 1000
	-1			;FORCE SYMBOL TABLE BEYOND SNOOP DATA

DEPHASE
RELOC

IFG BPRLEN-MAXSNP,<PRINTX %DATA AREA TOO LARGE FOR SNOOP>

INSTAB:	LOCRH
INSTBL==.-INSTAB

INIFLG:	-1			;FLAG TO INDICATE IF RELOCATION NEEDED
NEWDAT:	BLOCK LJDAT		;WORKING NEW AND OLD COPIES OF JOB DATA
OLDDAT:	BLOCK LJDAT

;DATA FOR DISK STATISTICS

STRNAM:	BLOCK 2
STRSTR:	BLOCK 2
UNITS:	BLOCK .MSRLN		;GET THE WHOLE BLOCK ON MSTR .MSRNU
UDBS:	BLOCK NDSKS
DSKCKU:	BLOCK NDSKS		;CHANNEL, KONTROLLER, UNIT FOR UDB'S
	;DEFINTIONS FOR FOLLOWING 2 BLOCKS
	UDBSEK==0		;SEEKS
	UDBRED==1		;READS - SECTORS IF DISK, FRAMES IF TAPE
	UDBWRT==2		;WRITES - SECTORS IF DISK, FRAMES IF TAPE
	UDBRCT==3		;ACTUAL READ COUNT
	UDBWCT==4		;ACTUAL WRITE COUNT
	UDBRVC==5		;ACTUAL SKIP READ (READ VERIFY) COUNT
	  UDBCNT==6		;SIZE OF OUR CHUNK OF THE UDB
NEWIO:	BLOCK NDSKS*UDBCNT
OLDIO:	BLOCK NDSKS*UDBCNT
NAMES:	BLOCK NDSKS*2		;HOLD NAMES AND UNIT NUMBERS
LASUDB:	BLOCK 1			;TIME STAMP
DEVSPP:	BLOCK NDSKS		;SECTORS PER PAGE FOR ADJUSTMENT OF OUTPUT
;ROUTINES FOR DISK STATISTICS

;FIND UDB ADDRESSES

GETUDB:	TIME			;GET NOW
	SAVEAC <Q1,Q2>		;GET TWO AC'S TO USE
	MOVEM T1,LASUDB		;SAVE TIME WE DID THIS
	SETOM UNITS+.MSRCH	;INIT MSTR BLOCK
	SETOM UNITS+.MSRCT
	SETOM UNITS+.MSRUN

;MAIN LOOP

GETUD0:	HRROI T1,STRNAM		;WHERE TO PUT NAME
	MOVEM T1,UNITS+.MSRSN
	HRROI T1,STRSTR
	MOVEM T1,UNITS+.MSRSA
	MOVE T1,[.MSRLN,,.MSRNU] ;GET WHOLE BLOCK
	MOVEI T2,UNITS
	MSTR			;GET UNIT DATA
	 ERJMP GETUDX		;IF NO MORE, ALL DONE
	SETZM T1		;START OUT TO BUILD CKU
	MOVE T2,UNITS+.MSRCH	;GET CHANNEL NUMBER
	STOR T2,DOP%C2,T1	;STORE IN T1
	MOVE T2,UNITS+.MSRCT	;GET CONTROLLER NUMBER
	STOR T2,DOP%K2,T1	;STORE IN T1
	MOVE T2,UNITS+.MSRUN	;GET UNIT NUMBER
	STOR T2,DOP%U2,T1	;STORE IN T1
	MOVSI T2,-NDSKS		;SETUP AOBJN POINTER FOR TABLES
	SETOM T3		;PLUS FIRST FREE SLOT POINTER
GETUD1:	CAMN T1,DSKCKU(T2)	;ALREADY HAVE THIS ONE IN THE TABLES?
	JRST [	HRRZ T3,T2	;YES, MOVE INDEX TO T3
		JRST GETUD3]	;AND EXIT THE LOOP
	JUMPGE T3,GETUD2	;ALREADY FOUND THE FIRST HOLE?
	SKIPN UDBS(T2)		;NO, THIS ONE FREE?
	MOVEI T3,(T2)		;YES, REMEMBER THAT AS THE FIRST FREE
GETUD2:	AOBJN T2,GETUD1		;LOOP FOR ALL ENTRIES
GETUD3:	MOVEM T1,DSKCKU(T3)	;STORE CKU NUMBERS FOR THIS UNIT
	MOVE T4,T3		;COPY INDEX TO T4
	LSH T4,1		;COMPUTE DOUBLE WORD NAME INDEX
	MOVE T1,UNITS+.MSRST	;GET UNIT STATUS
	TXNN T1,MS%MNT		;A PART OF A MOUNTED STRUCTURE?
	JRST [	SETZM NAMES(T4)
		JRST GETUD4]	;AND PROCEED
	DMOVE T1,STRNAM		;GET ALIAS OF STRUCTURE
	DMOVEM T1,NAMES(T4)	;SAVE NAME OF UNIT
	HLRZ T1,.MSRNS+UNITS	;GET LOGICAL UNIT NUMBER
	HRRM T1,NAMES+1(T4)	;SAVE THIS
	MOVE T4,UNITS+.MSRSP	;LOAD + SAVE SECTORS PER PAGE COUNT
	MOVEM T4,DEVSPP(T3)	; ...
GETUD4:	SKIPE UDBS(T3)		;ALREADY KNOWN?
	JRST GETUD0		;YES
	MONREF <MOVEI T1,0>,CHNTAB ;NO. GET ADDRESS OF CHANNEL TABLE
	ADD T1,UNITS+.MSRCH	;ADD IN THIS CHANNEL
	HRLI T1,1		;ONE WORD OF "PEEK"
	MOVEI T2,T1
	PEEK			;GET DATA FROM CHNTAB
	 ERJMP GETUDX		;IF IT FAILS, GIVE UP
	MONREF <ADDI T1,0>,CDBUDB ;GET TO UDB DATA
	SKIPL UNITS+.MSRCT	;THIS DISK HAVE A KDB?
	JRST GETUD5		;YES, MUST DO IT DIFFERENTLY
	ADD T1,UNITS+.MSRUN	;GET DATA FOR THIS UNIT
	HRLI T1,1
	MOVEI T2,T1
	PEEK			;GET UDB ADDRESS
	 ERJMP GETUDX
	JRST GETUD8		;JOIN COMMON EXIT CODE
GETUD5:	ADD T1,UNITS+.MSRCT	;ADD IN CONTROLLER NUMBER
	HRLI T1,1		;NUMBER OF WORDS IS 1
	MOVEI T2,T1		;PUT DATA IN T1
	PEEK			;GET THE KDB ADDRESS
	 ERJMP GETUDX
	MONREF <ADDI T1,0>,KDBIUN ;ADD IN OFFSET OF AOBJN POINTER TO UDB TABLE
	HRLI T1,1		;GET ONE WORD
	MOVEI T2,Q1		;PUT DATA IN Q1
	PEEK			;GET AOBJN POINTER
	 ERJMP GETUDX
GETUD6: HRRZ T1,Q1		;GET ADDRESS OF NEXT SLOT IN UDB TABLE
	HRLI T1,1		;GET ONE WORD
	MOVEI T2,Q2		;PUT DATA IN Q2
	PEEK			;GET ADDRESS OF NEXT UDB TO CHECK
	 ERJMP GETUDX
	JUMPE Q2,GETUD7		;SKIP THIS ONE IF NO ADDRESS
	MOVE T1,Q2		;COPY ADDRESS TO T1
	MONREF <ADDI T1,0>,UDBSLV ;OFFSET TO SLAVE ADDRESS
	HRLI T1,1		;GET ONE WORD
	MOVEI T2,T1		;PUT DATA IN T1
	PEEK			;GET UDB+UDBSLV
	 ERJMP GETUDX
	CAME T1,UNITS+.MSRUN	;THIS UDB MATCH WITH THE ONE WE WANT?
GETUD7:	AOBJN Q1,GETUD6		;NO, LOOP FOR ALL UDB'S
	JUMPGE Q1,GETUDX	;GO IF NO MATCH FOUND
	MOVE T1,Q2		;COPY MATCHED UDB ADDRESS TO T1
GETUD8:	MOVEM T1,UDBS(T3)	;SAVE UDB ADDRESS
	JRST GETUD0		;DO ALL DRIVES
GETUDX:	RET			;DONE

;ROUTINE TO GATHER DISK I/O DATA AND SAVE PREVIOUS DATA

GETDSK:	TIME			;GET NOW
	SUB T1,[^D<1000*60*5>]	;TIME TO POLL UNITS?
	CAML T1,LASUDB
	CALL GETUDB		;YES. DO IT NOW
	MOVE T1,[NEWIO,,OLDIO]
	BLT T1,OLDIO+<10*10*UDBCNT-1> ;SAVE ALL DATA
	MOVSI T4,-<10*10>	;DO ALL UNITS
GETDS0:	SKIPN T1,UDBS(T4)	;THIS UNIT EXIST?
	JRST GETDSX		;NO. GO ON THEN
	MONREF <ADDI T1,0>,UDBSEK ;GET TO DATA PORTION OF UDB
	HRLI T1,UDBCNT		;GET ALL DATA
	MOVEI T2,0(T4)		;GET DISK UNIT
	IMULI T2,UDBCNT		;WORDS PER ENTRY
	ADDI T2,NEWIO		;BASE ADDRESS
	PEEK			;GET DATA
	ERJMP GETDSX		;UNKNOWN FAILURE
GETDSX:	AOBJN T4,GETDS0		;DO THEM ALL
	RET			;DONE

SYMTAB:
	SYM DISMSJ,BP1ADR,,2
	SYM REMWS,BP2ADR
	SYM LDJB3,BP3ADR
	SYM SCHEDJ,BP4ADR
	SYM FRIBP3,BP5ADR
	SYM SKDJ2,BP6ADR
	SYM DISMSH,BP7ADR,,6
	SYM SCHP3,BP10ADR
	SYM FRIBP0,BP11ADR
	SYM AJBAL5,BP12ADR
	SYM FRIBP1,BP13ADR
	SYM MAPDL,BP14ADR,,21	;DIRECTORY CACHE HIT
	SYM MAPELN,BP15ADR,,3	;DIRECTORY CACHE MISS - CACHE FULL
	SYM MAPFIN,BP16ADR	;DIRECTORY CACHE MISS - ENTRY ADDED
NSYM==<.-SYMTAB>/3
IFN NBPT-NSYM,<PRINTX **NBPT AND SYMTAB INCONSISTENT**>

	MONRH
	SYM NJOBS,LNJOBS
	SYM NFKS,LNFKS
SYMTBL==.-SYMTAB

	END