Google
 

Trailing-Edge - PDP-10 Archives - SRI_NIC_PERM_SRC_1_19910112 - 6-sources/watdat.mac
There are 13 other files named watdat.mac in the archive. Click here to see a list.
; UPD ID= 310, SNARK:<6.UTILITIES>WATDAT.MAC.2,   6-Jul-83 15:38:15 by TGRADY
; Fix dummy record size in ODAGAN, just like 5.1

	TITLE WATDAT - PROGRAM TO OUTPUT "WATCH" DATA

	SEARCH MONSYM,MACSYM
	.REQUIRE SYS:MACREL
	SALL

	EXTERN WATCH,INTRVL,NQUEUE,MAXCLS,STRING,SUMJOB
	INTERN .PQMAX



;DEFINE ACCUMULATORS
	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


	JOBSMF==1B0		;JOB SUMMARY FLAG
	STATF==1B1		;MONITOR STATISTICS FLAG
	TUNEMF==1B3		;TUNE MODE FLAG
	ALLF==1B4		;ALL MODE (INCLUDING SNOOP DATA)
	ODATFL==1B5		;OUTPUT RECORDS TO DATA FILE
	SUPOUF==1B18		;SUPPRESS OUTPUT
	NCLR==2777B10		;MASK TO CLEAR LEFT CONTROL BITS OF NOUT FORMAT
				;  CONTROL WORD
	.PQMAX==^D10		;MAXIMUM NUMBER OF ENTRIES FOR QUEUE
				;  DISTRIBUTION PERCENTAGES
	.DEMAX==^D15		;MAXIMUM NUMBER OF ENTRIS FOR DISK I/O
	COMMENT \

   WATDAT, written  by  Kevin  G.   Wallace,  is  a  program
containing several  subroutines,  that are  used  to  output
WATCH data (data from running  the WATCH program) to a  data
file.  The data  is output in  the form of  data records  of
fixed lengths.   The  objective of  WATDAT  is to  add  this
capability of  outputting  data records  to  WATCH,  without
making many changes  to the existing  WATCH programs,  WATCH
and WATMAI.  Therefore, where possible, only tests and calls
are used (i. e. test if using the data file and if so,  call
a subroutine to  do the  outputting of the  data).  In  some
ways the  object was  to design  the best  subroutines  that
would be called in  the most optimum  places, such that  the
existing WATCH programs do most of the work.  Thus the  flow
of  control,  of  the   existing  WATCH  programs,   remains
unaltered.
   The following is a  brief description of the  subroutines
used or implemented in WATDAT.  This was written as a  guide
for  persons  who  maintain  WATDAT  and  the  entire  WATCH
program.   For  further  information   on  WATDAT  and   its
objectives, read RECORD-TYPES.MEM.


	SETHD - SET THE HEADER INFORMATION

   SETHD is the subroutine that outputs the initial data for
every record  output  by WATCH.   The  data that  is  output
consists of  the  Record  Entry Type,  the  Record  Sequence
Number, the date and time,  the length of the interval,  and
the number of jobs.   It is also to  be noted that PTR,  the
output data  record  byte  pointer is  initialized  in  this
routine, to point to the beginning of the block reserved for
all data records.  Thus when  a routine outputs data to  the
record block  or  buffer,  it  must  first  get  the  record
pointer, PTR, use the pointer  to output its data, and  then
restore an updated record pointer to PTR.


	ODATM - OUTPUT DATE AND TIME

   ODATM is the  subroutine that outputs  the date and  time
into a  buffer, such  that a  time stamp,  along with  other
data, may be  output at  the beginning of  each WATDAT  data
record.  The format  used is MM/DD/YY<BLANK>HH:MM:SS.   Note
that this format is readable with the IDTIM JSYS.  The  only
hack in this routine  is that ODTIM  outputs a single  digit
month number, with  a leading  space.  Before  the date  and
time can  be output  to a  record, this  space or  blank  is
changed to an ASCII zero.


	GETFIL - GET THE DATA FILE

   GETFIL is  the  subroutine  used  to  get  all  necessary
information about the output data file.  First ask the  user
if he/she is outputting data records.  If the person is not,
then just  return.  If  the  person is,  then set  the  flag
(ODATFL) that  states that  the  person is  outputting  data
records.  Open the file and  get the file handle.  If  there
are any errors, get the  file information again.  Return  if
all goes well.


	CLSOPN - CLOSE AND OPEN THE DATA FILE

   CLSOPN is the  subroutine used to  momentarily close  and
open the data file,  so as to write  out all changes to  it,
and update all pertinent tables.



	PRIREC - PRINT THE DATA RECORD

   PRIREC is the subroutine that outputs all data records to
the  data  file.   First  append  the  carriage-return   and
line-feed.  Then  SOUT   the  record  to   the  data   file,
terminating on a line-feed.   ORP is a  byte pointer to  the
beginning of the block that buffers the data records.


	OUSER - OUTPUT USER NAME

   OUSER is the subroutine that outputs the user name in the
Normal Per Job and Expanded Per Job data records.  Given the
user number,  it outputs  the  user name  and pads  it  with
blanks, such that the entire field is of length 20.


	OPGM - OUTPUT PROGRAM NAME

   OPGM is the subroutine that outputs the program name  for
a particular user.   STRING is the  data block where  WATMAI
conveniently leaves  the program  name.   All OPGM  does  is
output the first  six ASCII  bytes of  STRING, which  should
contain the program name.


	DETJOB - OUTPUT DETACHED JOB


   DETJOB is the subroutine that outputs the value 777 octal
for a detached terminal, when  outputting Normal Per Job  or
Expanded Per Job records to the data file.


	SYSHED - OUTPUT SYSTEM HEADER

   SYSHED is the subroutine that outputs the header for  the
Expanded Per Job Record totals.  The existing WATCH  program
outputs totals of all the Expanded Per Job entries, under  a
heading  of  System  Summary.   WATDAT  simply  takes   this
information and  forces it  into  another Expanded  Per  Job
record, with a  user name of  SYSTEM.  Specifically,  SYSHED
calls SETHD  to set  the header  that goes  on every  record
output.  Then 999 is  output as a dummy  job number, 777  is
output as a  detached terminal number,  SYSTEM is output  as
the user name, blanks  are output as  the program name,  and
zero is outuput as the %RT variable.


	CACBUF - BUFFER CACHE STATISTICS

   CACBUF is the subroutine that outputs the directory cache
statistics to the  a data block,  so that this  data may  be
output at a later time.  It merely accepts the three  values
and outputs them to the buffer area.


	OCACHE - OUTPUT CACHE STATISTICS

   OCACHE is the subroutine that outputs the directory cache
statistics to  the data  record block.   OCACHE outputs  the
string in the  CACSTS block,  the block used  to buffer  the
directory cache statistics.


	ODSKNM - OUTPUT DISK NAME

   ODSKNM is the subroutine that outputs the name string for
a particular disk structure.  The address of the name string
block is passed to ODSKNM, as  an argument.  A test is  made
at the beginning of the subroutine  to see if there is  data
at the address passed to ODSKNM.  If there is no data,  then
ten blanks  are output  in  place of  the name  string.   In
either case, the name string  is padded, with blanks, to  at
least ten characters,  and a  maximum of  ten characters  is
output by ODSKNM.


	ODFIL - OUTPUT FILLER DISK I/O ENTRIES

   ODFIL is  the subroutine  that  outputs filler  or  dummy
entries for the DISK I/O statistics.  The number of  entries
already output is  passed in P1.   Enough dummy entries  are
output to  make a  total of  fifteen entries  output.   Each
dummy entry consists of zeroes  for the Channel, zeroes  for
the Unit, zeroes  for the  number of Seeks,  zeroes for  the
number Reads, zero for the number of Writes, blanks for  the
Name, and zeroes  for the  Number.  Once  the dummy  entries
have been  output,  the  total number  of  good  entries  is
output.


	PQFIL - OUTPUT DUMMY ENTRIES FOR QUEUE
		DISTRIBUTION PERCENTAGES

   PQFIL is the  subroutine that outputs  dummy entries  for
the queue distribution entries.  NQUEUE contains the  number
of queue entries already output.  PQFIL outputs a maximum of
.PQMAX total entries.  User is alerted if there are too many
values to output.  Each  dummy entry output contains  zeros.
After all  necessary dummy  entries  are output,  the  total
number, of good entries, is output.



	DCFIL - OUTPUT DUMMY CLASS LOAD AVERAGES


   DCFIL is the  subroutine that outputs  dummy entries  for
the Class  Load Averages.   The  number of  entries  already
output is  passed in  P2.  The  total number  of entries  to
output (including dummy entries)  is in MAXCLS.  Each  dummy
entry contains zeroes for the  Class Number, zeroes for  the
Share, zeroes for the Utilization, and zeroes for the  three
Load Averages values.  After  all entries have been  output,
the total  number of  good Class  Load Averages  entries  is
output.


	OFLT - OUTPUT A FLOATING POINT NUMBER

   OFLT is  the subroutine  used  to output  floating  point
numbers to  the  data  record.  OFLT  tests  whether  output
should be  suppressed or  the  output JFN  is the  NULL  I/O
device, in which case OFLT  just returns.  OFLT accepts  the
number to be output in T2, and the lengths of the first  and
second fields in T3.   In outputting floating point  number,
OFLT  outputs  leading  zeroes  and  the  point.   If  field
overflow occurs, asterisks  are output to  the data  record.
If any other  errors occur,  the field is  just filled  with
zeroes.


	ONUM - OUTPUT AN INTEGER

   ONUM is the  subroutine used  to output  integers to  the
data record.  ONUM tests whether output should be suppressed
or the output JFN is the NULL I/O device, in which case ONUM
just returns.  ONUM accepts the  number to be output in  T2,
and the number of columns and the radix of the number in T3.
In outputting  the integer,  leading zeroes  are output.  If
column overflow  occurs, asterisks  are output  to the  data
record.  If any other errors occur, the field is just filled
with zeroes.


	OPCT - OUTPUT A PERCENTAGE

   OPCT  is  the  subroutine  used  to  output  percentages.
Percentages are  those  quantities  as  defined  in  WATMAI.
Specifically a percentage is a  floating point number to  be
output to the data  record, with four as  the length of  the
first field, and two as the length of the second field.  The
value, to be output, times ten, is passed in T1.


	ORAT - OUTPUT A RATE

   ORAT is the subroutine used  to output rates.  Rates  are
those quantities as defined  in WATMAI.  Specifcally a  rate
is floating point number  to be output  to the data  record,
with four as the length of  the first field, and two as  the
length of the second field.  The value, to be output,  times
one hundred, is passed in T1.


	NULJFN - OUTPUT TO NULL DEVICE

   NULJFN is the subroutine  used to set  the output JFN  to
NULL I/O.  DJFN is  the block where the  JFN, of the  output
data file, is stored.


	RSTJFN - RESET THE OUTPUT JFN

   RSTJFN is the subroutine used to reset the output JFN  to
its original value.   SAVJFN contains the  value of the  JFN
for the data  file.  SAVJFN is  set in the  initial call  to
GETFIL.


	CHECK - CHECK THE RECORD

   CHECK is the  subroutine that checks  the consistency  of
the data records, as they are output.  WATCH is halted if  a
bad data  record  is  output.   This  routine  is  merely  a
debugging tool.  At the present  time, the only test is  the
length of the record.

		To be continued ....
\
	SUBTTL SETHD - SET HEADER OF RECORD
;SETHD - SET THE HEADER INFORMATION OF THE RECORD TO BE
;	 OUTPUT (I.E. RECORD ENTRY TYPE, RECORD SEQUENCE NUMBER,
;	 DATE & TIME, INTERVAL, AND NUMBER OF JOBS.
; T1/ RECORD ENTRY TYPE
;	SETHD
; RETURN +1: ALWAYS


SETHD::	SAVEAC <T2,T3,T4>	;SAVE ACCUMULATORS
	TXNN F,TUNEMF		;IF IN TUNE MODE, THEN ALWAYS RESET SEQ COUNTER
	CAME T1,LASTYP		;IF THE LAST RECORD OUTPUT WAS OF A DIFFERENT
	SETZM SEQNO		;  TYPE THAN THIS ONE, THEN RESET THE SEQUENCE
				;  NUMBER COUNTER
	MOVEM T1,LASTYP		;UPDATE LAST RECORD TYPE
	MOVE T4,ORP		;GET POINTER TO BEGINNING OF OUTPUT RECORD
	MOVEM T4,PTR		;INITIALIZE DATA RECORD POINTER

;OUTPUT RECORD ENTRY TYPE
	MOVE T2,T1		;GET ENTRY TYPE
	MOVX T3,<FLD(2,NO%COL)!FLD(^D10,NO%RDX)>	;TWO COLUMNS
	CALL ONUM		;OUTPUT THE ENTRY RECORD TYPE

;OUTPUT RECORD SEQUENCE NUMBER
	AOS T2,SEQNO		;INCREMENT THE SEQUENCE NUMBER AND LOAD IT
	MOVX T3,<FLD(3,NO%COL)!FLD(^D10,NO%RDX)>	;THREE COLUMNS
	CALL ONUM		;OUTPUT THE RECORD SEQUENCE NUMBER

;OUTPUT THE DATE AND TIME
	MOVE T1,PTR		;GET OUTPUT DATA RECORD POINTER
	HRROI T2,DATM		;POINTER TO DATE AND TIME STRING
	SETZ T3,		;TERMINATE ON A NULL BYTE
	SOUT			;OUTPUT THE DATE AND TIME STRING
	MOVEM T1,PTR		;UPDATE RECORD POINTER

;OUTPUT TIME INTERVAL
	FLTR T2,INTRVL		;CONVERT TIME INTERVAL TO FLOATING POINT
	FDV T2,[1000.0]		;CONVERT TO SECONDS
	MOVX T3,<FLD(5,FL%FST)!FLD(1,FL%SND)>	;OUTPUT IN FORMAT 99999.9
	CALL OFLT		;OUTPUT THE INTERVAL

;OUTPUT NUMBER OF JOBS
	CALL SUMJOB		;SUM THE NUMBER OF JOBS
	MOVE T2,T1		;NUMBER OF JOBS IS RETURNED IN T1
	MOVX T3,<FLD(3,NO%COL)!FLD(^D10,NO%RDX)>	;OUTPUT IN 3 COLS
	CALL ONUM		;OUTPUT THE NUMBER OF JOBS

	RET			;RETURN
	SUBTTL ODATM -OUTPUT THE DATE AND TIME
;ODATM - OUTPUT THE DATE AND TIME TO THE OUTPUT BUFFER IN
;	THE FORMAT MM/DD/YY HH:MM:SS.
;	ODATM
; RETURNS +1: ALWAYS


ODATM::	SAVEAC <T1,T2,T3,T4>	;SAVE ACCUMULATORS
	HRROI T1,DATM		;BLOCK TO BUFFER DATE AND TIME STRING
	SETO T2,		;OUTPUT CURRENT DATE AND TIME
	MOVX T3,<OT%NMN!OT%DAM!OT%SLA>	;NUMERIC MONTH, DAY AFTER MONTH,
					;  WITH SLASHES
	ODTIM			;OUTPUT DATE AND TIME TO BUFFER
	MOVE T1,[POINT 7,DATM]	;POINTER TO BEGINNING OF DATE AND TIME STRING
	ILDB T2,T1		;GET FIRST BY OF DATE AND TIME (I. E. FIRST
				;  DIGIT OF THE MONTH
	MOVEI T3,"0"		;LOAD AN ASCII ZERO
	CAIN T2," "		;IF FIRST DIGIT IS A BLANK
	DPB T3,T1		;  THEN CHANGE IT TO AN ASCII ZERO
	RET			;RETURN
	SUBTTL GETFIL - GET THE DATA FILE
;GETFIL - ASK IF USER WANTS DATA FILE, GET DATA FILE
;	GETFIL
; RETURN +1: ALWAYS


;SAVE ACCUMULATORS
GETFIL::SAVEAC <T1,T2,T3,T4>


;ASK IF DATA FILE WANTED
	HRROI T1,[ASCIZ !Would you like to output data records?  (Y/N): !]
				;INITIAL PROMPT
	PSOUT

AGAIN:	HRROI T1,ISTRNG		;POINTER TO STRING BUFFER
	MOVX T2,<RD%TOP!RD%RAI!FLD(^D80,.RHALF)>;BREAK ON TOP, RAISE LOWERS,
						;  INPUT MAX OF 80 BYTES
	HRROI T3,[ASCIZ !Would you like to output data records?  (Y/N): !]
				;^R PROMPT
	RDTTY
	 JFCL			;HOPEFULLY NO ERROR

;EXAMINE ANSWER
	LDB T1,[POINT 7,ISTRNG,6]	;GET FIRST BYTE
	CAIN T1,"Y"		;TEST FOR YES
	JRST GTYES
	CAIN T1,"N"		;IF NO THEN RETURN
	RET			;RETURN


;ELSE GARBAGE WAS ENTERED
	HRROI T1,[ASCIZ !Please answer yes or no. (Y/N): !]
	PSOUT
	JRST AGAIN


GTYES:	TXO F,ODATFL	;SET FLAG TO OUTPUT DATA RECORDS TO FILE

;PROMPT USER FOR DATA FILE NAME
	HRROI T1,[ASCIZ /Output file for data records: /];ENTER FILE NAME
	PSOUT

;GET THE JFN
	MOVX T1,<GJ%MSG!GJ%CFM!GJ%FNS!GJ%SHT>	;SHORT FORM, TYPE MESSAGE, GIVE
						;  CONFIRMATION, IN ,, OUT JFN
	MOVE T2,[.PRIIN,,.PRIOU];READ FILE NAME FROM TERMINAL
	GTJFN
	 ERJMP GTFERR		;JUMP TO ROUTINE TO HANDLE GETFIL ERROR

	MOVEM T1,DJFN		;SAVE DATA FILE JFN
	MOVEM T1,SAVJFN		;PERMANENT COPY OF THE DATA JFN


;OPEN DATA FILE
				;JFN ALREADY IN T1
	MOVX T2,<FLD(7,OF%BSZ)!OF%WR!OF%APP!OF%THW>	;7 BIT BYTES, WRITE,
							;  APPEND, THAWED
	OPENF
	 ERJMP GTFERR		;JUMP TO ROUTINE TO HANDLE GETFIL ERROR


	RET			;RETURN IF EVERYTHING OK


;ROUTINE TO HANDLE GETFIL ERROR
GTFERR:	JSERR			;OUTPUT THE ERROR STRING
	JRST GTYES		;TRY TO GET FILE HANDLE AGAIN
	SUBTTL CLSOPN - CLOSE AND OPEN THE DATA FILE
;CLSOPN - CLOSE AND OPEN THE DATA FILE SO THAT DATA WILL NOT
;	BE LOST IF PROGRAM OR SYSTEM FAILURE
;	CLSOPN
; RETURN +1: ALWAYS

CLSOPN::SAVEAC <T1,T2,T3,T4>	;SAVE ACCUMULATORS
	MOVX T1,CO%NRJ		;DO NOT RELEASE JFN
	HRR T1,DJFN		;GET DATA FILE JFN
	CLOSF			;CLOSE THE DATA FILE
	 JFCL			;NO CLOSE ERRORS
	HRRZ T1,DJFN		;GET DATA FILE JFN
	MOVX T2,<FLD(7,OF%BSZ)!OF%WR!OF%APP!OF%THW>	;7 BIT BYTES, WRITE,
							;  APPEND, THAWED
	OPENF			;OPEN THE DATA FILE
	 JRST	[JSERR			;OUTPUT ERROR STRING
		HALTF			;STOP PROGRAM
		JRST WATCH]		;IF CONTINUED, JUST START AGAIN
	RET			;RETURN
	SUBTTL PRIREC - OUTPUT PRESENT RECORD
;PRIREC - OUTPUT PRESENT RECORD TO THE DATA FILE
;	PRIREC
; RETURN +1: ALWAYS


PRIREC::SAVEAC <T1,T2,T3,T4>	;SAVE ACCUMULATORS


;APPEND <CARRAIGE-RETURN><LINE-FEED>
PRINT:	MOVE T1,PTR		;RECORD POINTER
	HRROI T2,CRLF		;BYTE POINTER TO CRLF
	SETZ T3,		;ASCIZ STRING
	SOUT


;OUTPUT THE ENTIRE RECORD
	MOVE T1,DJFN		;JFN OF OUTPUT FILE
	MOVE T2,ORP		;POINTER TO BEGINNING OF RECORD
	MOVEM T2,PTR		;RESET DATA RECORD POINTER
	MOVX T3,.INFIN		;LARGEST POSSIBLE POSITIVE VALUE
	MOVEI T4,.CHLFD		;TERMINATE ON <LINE-FEED>
	SOUT
	RET			;RETURN
	SUBTTL OUSER - OUTPUT USER NAME
;OUSER - OUTPUT THE NAME STRING FOR A GIVEN USER NUMBER
; T2/ USER NUMBER
;	OUSER
; RETURN +1: ALWAYS

OUSER::	SAVEAC <T1,T2,T3,T4>	;SAVE ACCUMULATORS
	HRROI T1,USER		;POINTER TO BLOCK FOR USER NAME
	DIRST			;OUTPUT THE USER NAME TO THE BUFFER
	 JFCL			;ERRORS ARE TAKEN CARE OF BY THE BLANKS
	HRROI T2,[ASCIZ/                    /]	;PAD BUFFER WITH 20 BLANKS
	SETZ T3,		;TERMINATE ON A NULL BYTE
	SOUT			;OUTPUT BLANKS THAT PAD BUFFER
	MOVE T1,PTR		;GET OUTPUT DATA RECORD POINTER
	HRROI T2,USER		;POINTER TO USER NAME BUFFER
	MOVEI T3,^D20		;OUTPUT A MAX. OF 20 CHARACTERS
	SETZ T4,		;TERMINATE ON A NULL BYTE
	SOUT			;OUTPUT THE USER NAME TO THE DATA RECORD
	MOVEM T1,PTR		;UPDATE RECORD POINTER
	RET			;RETURN
	SUBTTL OPGM - OUTPUT PROGRAM NAME
;OPGM - OUTPUT THE PROGRAM NAME STRING
;	OPGM
; RETURN +1: ALWAYS

OPGM::	SAVEAC <T1,T2,T3,T4>	;SAVE ACCUMULATORS
	MOVE T1,PTR		;GET OUTPUT DATA RECORD POINTER
	HRROI T2,STRING		;POINTER TO PROGRAM NAME STRING
	MOVEI T3,6		;SIX SINCE PGM NAMES ARE SIXBIT
	SETZ T4,		;TERMINATE ON A NULL BYTE
	SOUT			;OUTPUT PROGRAM NAME STRING TO DATA RECORD
	MOVEM T1,PTR		;UPDATE RECORD POINTER
	RET			;RETURN
	SUBTTL DETJOB - OUTPUT DETACHED JOB TTY NUMBER
;DETJOB - OUTPUT NUMBER THAT REPRESENTS THE TTY OF A
;	DETACHED JOB
;	DETJOB
; RETURN +1: ALWAYS

DETJOB::SAVEAC <T1,T2,T3,T4>	;SAVE ACCUMULATORS
	MOVEI T2,777		;777 REPRESENTS A DETACHED JOB TTY
	MOVX T3,<FLD(3,NO%COL)!FLD(^D8,NO%RDX)>	;3 COLUMNS IN OCTAL
	CALL ONUM		;OUTPUT THE NUMBER TO THE RECORD
	RET			;RETURN
	SUBTTL SYSHED - OUTPUT SYSTEM HEADER
;SYSHED - OUTPUT THE DUMMY JOB NUMBER, DUMMY TERMINAL NUMBER, DUMMY
;	USER NAME, DUMMY PROGRAM NAME, AND DUMMY %RT FOR THE SYSTEM
;	TOTALS FOR THE EXPANDED JOB RECORDS.
;	SYSHED
; RETURN +1: ALWAYS

SYSHED::SAVEAC <T1,T2,T3,T4>	;SAVE ACCUMULATORS
	MOVEI T1,3		;ENTRY TYPE FOR EXPANDED JOB RECORD
	CALL SETHD		;SET THE ENTRY RECORD TYPE
	MOVE T1,PTR		;GET RECORD POINTER
	HRROI T2,[ASCIZ /999777SYSTEM                    00.0/]	;DUMMY HEADER
	SETZ T3,		;END ON A NULL BYTE
	SOUT			;OUTPUT THE DUMMY HEADER
	MOVEM T1,PTR		;UPDATE RECORD POINTER
	RET			;RETURN
	SUBTTL CACBUF - BUFFER CACHE STATISTICS
;CACBUF - OUTPUT THE DIRECTORY CACHE STATISTICS TO A BUFFER
;	DATA BLOCK SO THAT THESE STATS MAY BE OUTPUT TO THE
;	RECORD AT THE APPROPRIATE TIME
; T1/ NUMBER OF HITS
; T2/ NUMBER OF MISSES
; T3/ NUMBER OF MISSES OF BOTH TYPES
;	CACBUF
; RETURN +1: ALWAYS


CACBUF::ASUBR <HITS,MISS,BMISS>	;NAME AND SAVE ARGUMENTS ON THE STACK
	MOVE T1,[POINT 7,CACSTS];POINTER TO CACHE STATS BUFFER BLOCK
	MOVX T3,<NO%LFL!NO%ZRO!NO%AST!FLD(6,NO%COL)!FLD(^D10,NO%RDX)>
				;LEADING FILLER WITH 0'S, OUTPUT *'S ON OVER-
				;  FLOW, IN 6 COLUMNS
	MOVE T2,HITS		;GET NUMBER OF HITS
	NOUT
	 JFCL			;DO NOTHING ON ERROR
	MOVE T2,MISS		;GET NUMBER OF MISSES
	NOUT
	 JFCL			;DO NOTHING ON ERROR
	MOVE T2,BMISS		;GET NUMBER OF BOTH TYPES
	NOUT
	 JFCL			;DO NOTHING ON ERROR
	RET			;RETURN
	SUBTTL OCACHE - OUTPUT CACHE STATISTICS
;OCACHE - OUTPUT CACHE STATISTICS
;	OCACHE
; RETURN +1: ALWAYS


OCACHE::SAVEAC <T1,T2,T3,T4>	;SAVE ACCUMULATORS
	MOVE T1,PTR		;GET DATA RECORD POINTER
	HRROI T2,CACSTS		;POINTER TO CACHE STATISTICS BUFFER
	SETZ T3,		;TERMINATE ON NULL BYTE
	SOUT
	MOVEM T1,PTR		;UPDATE DATA RECORD POINTER
	RET			;RETURN
	SUBTTL ODSKNM - OUTPUT THE NAME STRING FOR A DISK
;ODSKNM - OUTPUT THE NAME STRING FOR A DISK
; T2/ ADDRESS OF NAME STRING BLOCK
;	ODSKNM
; RETURN +1: ALWAYS

ODSKNM::SAVEAC <T1,T2,T3,T4,P1>	;SAVE ACCUMULATORS
	SKIPN @T2		;IF NO DATA IS PRESENT THEN
	 JRST ODBLNK		;  OUTPUT BLANKS
	HRROI T1,ISTRNG		;OUTPUT TO STRING DATA BUFFER AREA
	HRRO T2,T2		;POINT TO NAME STRING
	SETZ T3,		;TERMINATE ON NULL BYTE
	SOUT			;OUTPUT THE DEFAULT STRING
	HRROI T2,[ASCIZ /          /]	;OUTPUT TEN BLANKS TO PAD THE STRING
	SETZ T3,		;TERMINATE ON A NULL BYTE
	SOUT			;OUTPUT THE NAME STRING
	MOVE T1,PTR		;GET RECORD POINTER
	HRROI T2,ISTRNG		;POINTER TO GOOD STRING
	MOVEI T3,^D10		;OUTPUT ONLY TEN CHARACTERS
	SETZ T4,		;DO NOT OUTPUT A NULL BYTE
	SOUT
	MOVEM T1,PTR		;UPDATE RECORD POINTER
	RET

ODBLNK:	MOVE T1,PTR		;GET RECORD POINTER
	HRROI T2,[ASCIZ /          /]	;OUTPUT DUMMY STRING
	SETZ T3,		;TERMINATE ON NULL BYTE
	SOUT			;OUTPUT THE DUMMY STRING
	MOVEM T1,PTR		;UPDATE RECORD POINTER
	RET
	SUBTTL ODFIL - FILL OUT DISK I/O ENTRIES
;ODFIL - OUTPUT FILLER ENTRIES TO DISK I/O STATS
; P1/ NUMBER OF ENTRIES ALREADY OUTPUT
;	ODFIL
; RETURN +1: ALWAYS

ODFIL::SAVEAC <T1,T2,T3,T4>
	MOVEI P2,.DEMAX		;GET MAXIMUM NUMBER OF ENTRIES ALLOWED
	SUB P2,P1		;FIND DIFFERENCE, I. E. NUMBER OF DUMMY ENTRIES
				;  TO OUTPUT
	MOVE T1,PTR		;GET POINTER TO DATA RECORD
	SETZ T3,		;TERMINATE ON A NULL BYTE
ODAGAN:	SOJL P2,ODEXT		;TEST IF ENOUGH ENTRIES OUTPUT
	HRROI T2,[ASCIZ /0000000000000000000000000          00/]	;DUMMY ENTRY
	SOUT			;OUTPUT THE DUMMY ENTRY
	JRST ODAGAN		;LOOP TO OUTPUT ENOUGH ENTRIES

ODEXT:	MOVEM T1,PTR		;UPDATE RECORD POINTER
	MOVE T2,P1		;GET NUMBER OF GOOD ENTRIES
	MOVX T3,<FLD(2,NO%COL)!FLD(^D10,NO%RDX)>	;OUTPUT IN TWO COLUMNS
	CALL ONUM		;OUTPUT THE NUMBER
	RET
	SUBTTL PQFIL - FILL QUEUE SUM ITEMS
;PQFIL - ZERO ALL UNUSED ENTRIES FOR PRINTING QUEUE 
;	DISTRIBUTION PERCENTAGES (MAX OF .PQMAX TOTAL ENTRIES),
;	AND OUTPUT THE NUMBER OF GOOD ENTRIES OUTPUT.
;	PQFIL
; RETURN +1: ALWAYS


;OUTPUT ALL NECESSARY ZERO ENTRIES
PQFIL::	MOVE T1,NQUEUE		;GET THE NEGATIVE OF THE NUMBER OF VALUES
				;  ALREADY OUTPUT
	CAMGE T1,[-.PQMAX]	;IF TO MANY VALUE ALREADY OUTPUT
	JRST PQOVFL		;JUMP TO ERROR ROUTINE
	ADDI T1,.PQMAX		;COMPUTE NUMBER OF ZERO FIELDS TO OUTPUT
	SETZ T2,		;OUTPUT 0'S
	MOVX T3,<FLD(4,FL%FST)!FLD(2,FL%SND)>	;IN FORMAT 9999.99
PQAGAN:	SOJL T1,PQNUM		;OUTPUT NUMBER OF ENTRIES WHEN FINISHED
				;  OUTPUTTING ZERO ENTRIES
	CALL OFLT		;OUTPUT THE FLOATING POINT NUMBER
	JRST PQAGAN		;TRY AGAIN

;ALERT USER THAT THERE WERE TO MANY VALUES TO OUTPUT
PQOVFL:	HRROI T1,[ASCIZ /Too many Queue Distribution values to output.
Only the first ten values have been output.
/]				;ALERT USER OF OVERFLOW
	PSOUT			;SEND THE MESSAGE

;OUTPUT THE NUMBER OF GOOD ENTRIES OUTPUT
PQNUM:	MOVN T2,NQUEUE		;GET NUMBER OF QUEUES
	CAILE T2,.PQMAX		;IF NUMBER OF QUEUES IS GREATER THAN THE MAX
				;  ALLOWED, THEN ONLY THE MAX SHOULD BE OUTPUT
	MOVEI T2,.PQMAX		;MAXIMUM NUMBER OF QUEUES OUTPUT
	MOVX T3,<FLD(2,NO%COL)!FLD(^D10,NO%RDX)>	;2 COLUMNS
	CALL ONUM		;OUTPUT THE NUMBER
	RET			;RETURN
	SUBTTL DCFIL - FILL CLASS LOAD AVERAGES ITEMS
;DCFIL - ZERO ALL UNUSED ENTRIES FOR PRINTING CLASS LOAD AVERAGES
;	(MAX OF MAXCLS TOTAL ENTRIES), AND OUTPUT NUMBER ENTRIES OUTPUT
; P2/ NUMBER OF ENTRIES OUTPUT
;	DCFIL
; RETURN +1: ALWAYS


DCFIL::	SAVEAC <T1,T2,T3,T4,P1>	;SAVE ACCUMULATORS
	CAILE P2,MAXCLS		;IF TO MANY ITEMS WERE OUTPUT THEN
	JRST DCOVFL		;  JUMP TO OVERFLOW ROUTINE
	MOVEI P1,MAXCLS		;GET MAXIMUM NUMBER OF ENTRIES TO OUTPUT
	SUB P1,P2		;GET NUMBER OF ZERO ENTRIES TO OUTPUT
DCAGAN:	SOJL P1,DCNUM		;OUTPUT NUMBER OF ENTRIES OUTPUT WHEN
				;  FINISHED OUTPUTTING ZERO ENTRIES
	MOVE T1,PTR		;GET POINTER TO DATA RECORD
	HRROI T2,[ASCIZ /000000000.000000.000000.000000.000000.00/];DUMMY ENTRY
	SETZ T3,		;TERMINATE ON A NULL BYTE (ASCIZ)
	SOUT			;OUTPUT THE DUMMY ENTRY
	MOVEM T1,PTR		;UPDATE RECORD POINTER
	JRST DCAGAN		;OUTPUT NEXT SET OF ENTRIES

;ALERT USER OF OVERFLOW ERROR
DCOVFL:	HRROI T1,[ASCIZ /Too many Class Load Average values to output.
Extra entries have been output.
/]				;ALERT USER OF OVERFLOW
	PSOUT			;OUTPUT ERROR MESSAGE


;OUTPUT NUMBER OF ENTRIES OUTPUT
DCNUM:	MOVE T2,P2		;GET NUMBER OF ENTRIES OUTPUT
	MOVX T3,<FLD(2,NO%COL)!FLD(^D10,NO%RDX)>	;2 COLUMNS
	CALL ONUM		;OUTPUT THE NUMBER
	RET			;RETURN
	SUBTTL NOSNP - OUTPUT DUMMY SNOOP STRING
;NOSNP - OUTPUT DUMMY SNOOP STRING BECAUSE NO SNOOP EVENTS THIS TIME
;	NOSNP
; RETURN +1: ALWAYS


NOSNP::	SAVEAC <T1,T2,T3,T4>	;SAVE ACCUMLATORS
	MOVE T1,PTR		;GET DATA RECORD POINTER
	HRROI T1,[ASCIZ /0000.0000.0000.0000.0000.0000.0000.0000.0000.00000.0000000000000.0000000000.000000.0000000000000000000/]	;DUMMY STRING
	SETZ T3,		;DUMMY STRING IS ASCIZ
	SOUT			;OUTPUT THE DUMMY SNOOP STRING
	MOVEM T1,PTR		;UPDATE RECORD POINTER
	RET			;RETURN
	SUBTTL OFLT - OUTPUT A FLOATING POINT NUMBER
;OFLT - OUTPUT A FLOATING POINTING NUMBER TO THE OUTPUT
;	DATA BUFFER.
; T2/ FLOATING NUMBER TO BE OUTPUT
; T3/ <FIRST FIELD>B23!<SECOND FIELD>B29!<THIRD FIELD>B35
;	OFLT
; RETURN +1: ALWAYS

OFLT::	SAVEAC <T1,T2,T3,T4>	;SAVE ACCUMULATORS
	MOVE T1,DJFN		;GET OUTPUT DATA JFN
	CAIN T1,.NULIO		;IF OUTPUTTING TO NULL I/O
	RET			;  THEN JUST RETURN
	JXN F,SUPOUF,R		;RETURN IF OUTPUT IS TO BE SUPPRESSED
	MOVE T1,PTR		;OUTPUT TO DATA BUFFER
	TXZ T3,.LHALF		;CLEAR LEFT HALF OF FLOUT FORMAT CONTROL WORD
	TXO T3,<FLD(.FLLZR,FL%JUS)!FL%ONE!FL%PNT>	;FILL WITH LEADING 0'S,
							;  & OUTPUT A POINT
	STKVAR <FORMAT>		;TEMPORARY FOR FLOUT FORMAT CONTROL WORD
	MOVEM T3,FORMAT		;SAVE FORMAT CONTROL WORD
	FLOUT
	 JFCL			;FLOUT ERROR RETURNS DO NOT SEEM TO BE WORKING
	CAME T3,FORMAT		;TEST IF THERE WAS AN ERROR BY CHECKING IF T3
	JRST OFLERR		;  CHANGED.  IF IT DID CALL ERROR ROUTINE.
	MOVEM T1,PTR		;UPDATE RECORD POINTER
	RET			;RETURN


;ERROR ROUTINES FOR OFLT
OFLERR:	CAIN T3,FLOTX1		;IF ERROR WAS OVERFLOW IN FIELD 1 OR FIELD 2
	JRST ASTFLT		;  THEN OUTPUT ASTERISKS IN THE FIELD
	JRST ZROFLT		;  ELSE JUST OUTPUT A ZERO


;OUTPUT A ZERO FOR THE FLOATING POINT NUMBER

ZROFLT:	MOVE T1,PTR		;OUTPUT TO DATA BUFFER
	SETZ T2,		;DATA IS FLOATING POINT ZERO
	MOVE T3,FORMAT		;RESTORE FORMAT CONTROL WORD SAVED WHEN
				;  WHEN OFLT WAS CALLED
	FLOUT
	 JFCL			;HOPEFULLY NO ERRORS
	MOVEM T1,PTR		;UPDATE RECORD POINTER
	RET			;RETURN



;OUTPUT ASTERISKS FOR THE FLOATING POINT NUMBER

;OUTPUT ASTERISKS FOR FIRST FIELD
ASTFLT:	MOVE T1,PTR		;OUTPUT TO DATA RECORD
	MOVEI T2,"*"		;ASTERISK TO BE OUTPUT
	LOAD T3,FL%FST,FORMAT	;GET SIZE OF FIRST FIELD
FST:	SOJL T3,PNT		;ALL ASTERISKS OUTPUT FOR FIRST FIELD
	BOUT			;OUTPUT ASTERISKS
	JRST FST		;TRY AGAIN

;OUTPUT DECIMAL POINT
PNT:	MOVEI T2,"."		;LOAD POINT
	BOUT

;OUTPUT ASTERISKS FOR SECOND FIELD
	MOVEI T2,"*"		;ASTERISK TO BE OUTPUT
	LOAD T3,FL%SND,FORMAT	;GET SIZE OF SECOND FIELD
SND:	SOJL T3,ZROEXT		;EXIT WHEN SECOND FIELD COMPLETE
	BOUT			;OUTPUT ASTERISKS
	JRST SND		;TRY AGAIN
ZROEXT:	MOVEM T1,PTR		;UPDATE RECORD POINTER
	RET			;RETURN
	SUBTTL ONUM - OUTPUT AN INTEGER
;ONUM - OUTPUT AN INTEGER TO THE OUTPUT DATA BUFFER
; T2/ NUMBER TO BE OUTPUT
; T3/ <NUMBER OF COLUNMS>B17,,RADIX
;	ONUM
; RETURN +1: ALWAYS

ONUM::	SAVEAC <T1,T2,T3,T4>	;SAVE ACCUMULATORS
	MOVE T1,DJFN		;GET OUTPUT DATA JFN
	CAIN T1,.NULIO		;IF OUTPUTTING TO NULL I/O
	RET			;  THEN JUST RETURN
	JXN F,SUPOUF,R		;RETURN IF OUTPUT IS TO BE SUPPRESSED
	MOVE T1,PTR		;OUTPUT TO DATA BUFFER
	TXZ T3,NCLR		;CLEAR LEFT PART OF NOUT FORMAT CONTROL WORD
	TXO T3,<NO%LFL!NO%ZRO!NO%OOV!NO%AST>	;OUTPUT WITH 0'S AS LEAD FILLER
						;  & ON OVERFLOW , OUTPUT *'S
	STKVAR <FORMAT>		;TEMPORARY FOR THE NOUT FORMAT CONTROL WORD
	MOVEM T3,FORMAT		;SAVE NOUT FORMAT CONTROL WORD
	NOUT
	 ERCAL ONUERR		;CALL TO ERROR ROUTINE
	MOVEM T1,PTR		;UPDATE RECORD POINTER
	RET			;RETURN


;ERROR ROUTINE FOR ONUM WHICH SIMPLY OUTPUTS ZERO THIS TIME
ONUERR:	CAIN T3,NOUTX2		;IF ERROR IS COLUMN OVERFLOW THEN
	RET			;  ASTERISKS HAVE ALREADY BEEN OUTPUT
				;  THEREFORE RETURN
	MOVE T1,PTR		;OUTPUT TO DATA BUFFER
	SETZ T2,		;DATA IS INTEGER ZERO
	MOVE T3,FORMAT		;RESTORE THE NOUT FLAGS
	NOUT
	 JFCL			;HOPEFULLY NO ERRORS
	RET			;RETURN
	SUBTTL OPCT - OUTPUT A PERCENTAGE
;OPCT - OUTPUT A PERCENTAGE
; T1/ PERCENTAGE TIMES 10
;	OPCT
; RETURN +1: ALWAYS

OPCT::	SAVEAC <T1,T2,T3>	;SAVE ACCUMULATORS
	FLTR T2,T1		;CONVERT PERCENTAGE*10 TO FLOATING PT.
	FDV T2,[10.0]		;DIVIDE BY TEN TO GET PERCENTAGE
	MOVX T3,<FLD(4,FL%FST)!FLD(2,FL%SND)>	;IN FORM 9999.99
	CALL OFLT		;OUTPUT FLOATING POINT NUMBER
	RET			;RETURN
	SUBTTL ORAT - OUTPUT A RATE
;ORAT - OUTPUT A RATE
; T1/ RATE TIMES 100
;	ORAT
; RETURN +1: ALWAYS

ORAT::	SAVEAC <T1,T2,T3>	;SAVE ACCUMULATORS
	FLTR T2,T1		;CONVERT RATE*100 TO FLOATING PT.
	FDV T2,[100.0]		;DIVIDE BY 100
	MOVX T3,<FLD(4,FL%FST)!FLD(2,FL%SND)>	;IN FORM 9999.99
	CALL OFLT		;OUTPUT FLOATING POINT NUMBER
	RET			;RET
	SUBTTL NULJFN - OUTPUT TO NULL DEVICE
;NULJFN - SET THE OUTPUT JFN TO NULL I/O
;	NULJFN
; RETURN +1: ALWAYS

NULJFN::SAVEAC <T1>		;SAVE ACCUMULATOR
	MOVEI T1,.NULIO		;GET NULL I/O
	MOVEM T1,DJFN		;SET OUTPUT DATA JFN TO NULL I/O
	RET			;RETURN
	SUBTTL RSTJFN - RESET OUTPUT DATA JFN
;RSTJFN - RESET THE OUTPUT DATA JFN TO ITS ORIGINAL VALUE
;	RSTJFN
; RETURN +1: ALWAYS

RSTJFN::SAVEAC <T1>		;SAVE ACCUMULATOR
	MOVE T1,SAVJFN		;GET ORIGINAL JFN
	MOVEM T1,DJFN		;RESTORE ORIGINAL JFN
	RET			;RETURN
	SUBTTL CHECK - CHECK THE RECORD SIZE
;CHECK - CHECK THE RECORD SIZE.  THIS IS AN INTERNAL SUBROUTINE
;	USED FOR DEBUGGING WATDAT.
;	CHECK
; RETURN +1: ALWAYS

CHECK:	SAVEAC <T1,T2,T3,T4,I>	;SAVE ACCUMULATORS
	MOVE T1,DJFN		;GET OUTPUT DATA JFN
	CAIN T1,.NULIO		;IF OUTPUTTING TO NULL I/O
	RET			;  THEN JUST RETURN
	JXN F,SUPOUF,R		;RETURN IF OUTPUT IS TO BE SUPPRESSED
	MOVE T1,ORP		;INPUT FROM DATA RECORD
	MOVEI T2,.NULIO		;OUTPUT TO NULL I/O
	MOVEI T3,^D5000		;INPUT A MAXIMUM OF 5000 CHARACTERS
	MOVEI T4,.CHLFD		;LAST BYTE TO READ IS A LINE-FEED
	SIN			;READ THE RECORD
	MOVEI T1,^D5000		;GET MAX NUMBER CHARACTERS INPUT
	SUB T1,T3		;COMPUTE THE NUMBER OF CHARACTERS READ
	SUBI T1,2		;SUBTRACT 2 SO AS NOT COUNT THE CRLF
	MOVE I,LASTYP		;GET THE PRESENT RECORD TYPE
	SOS I			;SUBTRACT ONE BECAUSE TABLE IS OFFSET BY ONE
	CAME T1,RECSIZ(I)	;COMPARE SIZE READ TO PROPER SIZE AND IF
	HALTF			;  DIFFERENT, HALT
	RET			;RETURN
	SUBTTL DATA AREA FOR WATDAT
;DATA AREA
OREC:	BLOCK ^D3000		;BLOCK FOR DATA RECORD
DATM:	BLOCK 10		;BLOCK FOR DATE AND TIME STRING
ISTRNG:	BLOCK 20		;BLOCK FOR ALL INPUT STRINGS
DJFN:	BLOCK 1			;JFN FOR OUTPUT DATA FILE
SAVJFN:	BLOCK 1			;SPACE TO SAVE THE ORIGINAL DATA FILE JFN
SEQNO:	BLOCK 1			;RECORD SEQUENCE NUMBER
LASTYP:	BLOCK 1			;LAST ENTRY RECORD TYPE OUTPUT
USER:	BLOCK 20		;BLOCK FOR USER NAME STRING
PGM:	BLOCK 2			;BLOCK FOR PROGRAM NAME STRING
CACSTS:	BLOCK 5			;BLOCK FOR DIRECTORY CACHE STATISTICS
RECSIZ:	EXP ^D361		;SIZE OF SYSTEM STATISTICS RECORD
	EXP ^D1377		;SIZE OF LOAD AVERAGES RECORD
	EXP ^D170		;SIZE OF EXPANDED PER JOB RECORD
	EXP ^D89		;SIZE OF NORMAL PER JOB RECORD
	EXP ^D667		;SIZE OF EXPANDED STATISTICS RECORD
	EXP ^D159		;SIZE OF TUNE MODE RECORD





;POINTERS AND CONSTANT DATA
ORP:	POINT 7,OREC		;BYTE POINTER TO BEGINNING OF RECORD
PTR:	BLOCK 1			;RECORD BUFFER POINTER FOR OUTPUT OF ALL DATA
CRLF:	ASCIZ /
/				;<CARRAIGE-RETURN><LINE-FEED>


	END