	.TITLE	STAT -- IAS V3.1 STATS DISPLAY
	.IDENT	"V3.1"

;	*** STAT -- TASK TO DISPLAY IAS V3.0 SYSTEM STATISTICS
;
;        COPYRIGHT (c) 1979,1978 BY
;        DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS,  U.S.A
;
;
;        This software is furnished under a licence  and  may
;        BE USED AND COPIED ONLY IN ACCORDANCE WITH THE TERMS
;        OF  SUCH LICENCE 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 TRANSFERED.
;
;
;        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.
;
;        THIS SOFTWARE IS SUPPLIED UNSUPPORTED BY DIGITAL AND
;        NO LIABILITY, SUPPORT, OR APPROVAL OF THIS  SOFTWARE
;        EITHER EXPRESS OR IMPLIED, WILL  BE  UNDERTAKEN   BY
;        DIGITAL UNDER ANY CIRCUMSTANCES.
;
;		AUTHOR:  P. G. VISCAROLA
;			 DEC, EDUCATIONAL SERVICES
;		DATE:    10-NOV-78
;
; Modifications:
;
; 001	??-???-????  Henry R. Tumblin	Added Real Time display
; 002	02-May-1981  Bruce C. Wright	Added support for general
;					screen package, minor bug
;					fixes.
; 003	19-Oct-1981  Bruce C. Wright	Modified to use line drawing
;					character set for those
;					terminals which have it
;					(HP-2648, VT-100, VT-52, etc).
;

	.SBTTL FUNCTIONAL DESCRIPTION

;	*** STAT  -- FUNCTIONAL DESCRIPTION
;
; THIS PROGRAM COLLECTS AND DISPLAYS STATISTICS FROM AN IAS V3.0 SYSTEM.
; THE PROGRAM COLLECTS DATA AT TWO POINTS.  AT INITIALIZATION TIME THE
; PROGRAM COLLECTS AND DISPLAYS THE FOLLOWING DATA:
;
;	MACHINE TYPE
;	SYSGEN'D MEMORY SIZE
;	TIMESHARING SCHEDULER PRIORITY
;	NUMBER OF TIMESHARING LEVELS
;	SYSTEM MAXIMUM TIMESLICE
;	TICKS TO SCHEDULER PROMOTIONS
;	TICKS BETWEEN BATCH SCHEDULES
;	BATCH QUANTUM
;
; THE PROGRAM DISPLAYS THIS DATA ONCE.  THE PROGRAM THEN CYCLES AT A
; VARIABLE INTERVAL.  ON EACH CYCLE, SYSTEM STATISTICS ARE COLLECTED
; AND DISPLAYED AS PERCENTAGE BAR GRAPHS.
;
; CERTAIN COMMANDS ARE LEGAL WHILE THE DISPLAY IS CYCLING.  THEY ARE:
;
;	^Z 		EXIT THE PROGRAM
;	X		EXIT THE PROGRAM
;	IN		SET THE CYCLE INTERVAL TO N CLOCK TICKS (<= 2 DIGITS)
;	C		CLEAR SCREEN AND REDISPLAY
;
;	RESTRICTIONS/CAVEATS
;
; 1) THIS PROGRAM USES THE FLOATING POINT PROCESSOR.
; 2) DUE TO ROUNDING ERROR PERCENTAGES DISPLAYED MAY NOT SUM TO 100%
; 3) DUE TO SYSTEM DESIGN (IAS, THAT IS) PERCENTAGES DISPLAYED MAY
;    SUM TO OVER 100%.
;

	.SBTTL	GENERAL DATA AREAS
; GENERAL DATA AREA
;
	.MCALL	EXIT$S,MRKT$S,QIOW$S,QIOW$C,QIO$C,ASTX$S,WTSE$C
	.MCALL	IHAR$C,ENAR$C
 
	.macro	.inh
	mov	@#ps.exp,-(sp)
	bis	#340,@#ps.exp
	.endm	.inh
 
	.macro	.enb
	mov	(sp)+,@#ps.exp
	.endm	.enb
 
	.ENABLE	LC
	.NLIST	BEX

; DEFINITIONS FOR FLOATING POINT ACCUMULATORS
	AC0 == %0
	AC1 == %1
	AC2 == %2
	AC3 == %3

; MISCELLANEOUS DATA AND DEFINITIONS

	CLKTIK	== 60.		; CLOCK FREQUENCY

; "COMMAND REQUESTED" FLAG WORD AND BIT DEFINITIONS

CYCTIM:	.WORD	5.		; "CYCLE TIME"-- TIME BETWEEN DISPLAYS

FLAG:	.WORD	0		; COMMAND REQUEST FLAG (SET IN AST)

	EXTBIT = 1.		; EXIT REQUESTED
	CLRBIT = 2		; CLEAR SCREEN REQUESTED
	INTBIT = 4		; CHANGE OF INTERVAL REQUESTED

USIBUF:	.BLKW	4.		; UNSOLICITED INPUT BUFFER
IOSB:	.BLKW	2		; I/O STATUS BLOCK FOR UNSOLICITED INPUT

OUTPUT:	.BLKW	180.		; $EDMSG OUTPUT BUFFER
badtyp:	.ascii	<15><12>/Unsupported terminal type/<15>
badlen	=	.-badtyp
FORM:	.ASCIZ	/(%D%)  /	; Percentage message
				; (plus two blanks in case there
				; used to be parentheses there).
FORM1:	.ASCII/ Active timesharing jobs: %D    Uptime: %D:%2Z/
	.ASCIZ/  Stats time: %D:%2Z/
	.EVEN
bartbl:	.word	t.vt50,10$	;++003 Bar codes for VT-50
	.word	t.vt52,10$	;++003 Bar codes for VT-52
	.word	t.vt55,10$	;++003 Bar codes for VT-55
	.word	t.vt61,10$	;++003 Bar codes for VT-61
	.word	t.v100,10$	;++003 Bar codes for VT-100
	.word	t.hp48,20$	;++003 Bar codes for HP-2648
	.word	0,30$		;++003 Default bar codes.
10$:	.ascii	"lkmjwvtuxqn"<141> ;++003 VT-100 line drawing characters.
	.asciz	<33>"F"		;++003 Enter graphics mode
	.asciz	<33>"G"		;++003 Exit graphics mode
20$:	.ascii	"rtfg7856.,/C"	;++003 HP-2648 line drawing characters.
	.asciz	<33>")B"<16>	;++003 Enter graphics mode
	.asciz	""		;++003 Exit graphics mode
				;++003 (leaves automatically at the
				;++003 end of every line).
30$:	.ascii	"++++++++!-+*"	;++003 Default line drawing characters.
	.asciz	""
	.asciz	""
	.even
li.ulc:	.word	0		;++003 Upper left corner
li.urc:	.word	0		;++003 Upper right corner
li.blc:	.word	0		;++003 Bottom left corner
li.brc:	.word	0		;++003 Bottom right corner
li.ut:	.word	0		;++003 Upper "T"
li.bt:	.word	0		;++003 Bottom "T"
li.lt:	.word	0		;++003 Left "T"
li.rt:	.word	0		;++003 Right "T"
li.ver:	.word	0		;++003 Vertical line
li.hor:	.word	0		;++003 Horizontal line
li.crs:	.word	0		;++003 Crossing lines
li.qua::.word	0		;++003 Quad character.
li.beg::.word	0		;++003 Begin graphics sequence
li.end::.word	0		;++003 End graphics sequence

; BUFFERS FOR STATISTICS:
;
; FIRST, THE BUFFER FOR STATISTICS THAT ARE RETRIEVED AND STORED ONLY ONCE

NUPDAT:
nupdt1:	.WORD	0		; "PDP11" TYPE
	.word	0		; Length of node name
	.word	0		; Address of string for node name.
	.WORD	0		; MEMORY SIZE IN WORDS
nupdt2:	.WORD	0		; TSS1'S PRIORITY
	.WORD	0		; NUMBER OF TIMESHARING LEVELS
	.WORD	0		; SYSTEM MAXIMUM TIMESLICE
nupdt3:	.WORD	0		; TICKS TO SCHEDULER PROMOTIONS
	.WORD	0		; TICKS BETWEEN BATCH SCHEDULES
	.WORD	0		; BATCH QUANTUM
;
; THE FOLLOWING DATA IS RETRIEVED AND STORED ON EVERY DISPLAY CYCLE

UPDAT:
STTIM:	.WORD	0,0		; TIME SINCE LAST SCHEDULER STARTUP
UPTIM:	.WORD	0,0		; TIME SCHEDULER RUNNING SINCE SYSTEM BOOT
SNTIM:	.WORD	0,0		; Null job time.
SPTIM:	.WORD	0,0		; Time in swap state
SBTIM:	.WORD	0,0		; Time in batch
SUTIM:	.WORD	0,0		; Time in user mode

; ARGUMENT LIST FOR "CYCLIC" TEXT DISPLAYED BY $EDMSG

ARGLIS:	.WORD	0		; Percentage of time taken by Real Time
       	.WORD	0		; PERCENTAGE OF TIME TAKEN BY NULL JOB
	.WORD	0		; PERCENT OF TIME TAKEN BY SWAPPING
	.WORD	0		; PERCENT OF TIME TAKEN BY BATCH
	.WORD	0		; PERCENTGE OF TIME TAKEN BY INTERACTIVE USERS
	.WORD	0		; NUMBER OF CURRENTLY ACTIVE TIMEHSARING JOBS

TB1:	.WORD	0		; HOURS SINCE SCHEDULER STARTUP
	.WORD	0		; MINUTES
	.WORD	0		; SECONDS

TB2:	.WORD	0		; HOURS SINCE STATISTICS STARTED
	.WORD	0		; MINUTES
TIMBUF:	.WORD	0		; SECONDS


	.SBTTL	DISPLAY CONTROL TABLES

; DISPLAY TABLES
;
; THE FIRST TABLE INDICATES THE STARTING LINE NUMBER OF EACH
; LINE OF THE GRAPH

BASEX::	.WORD	6		; INTERACTIVE TIME PERCENTAGE
	.WORD	11		; BATCH TIME PERCENTAGE
	.WORD	14		; SWAPPING TIME PERCENTAGE
	.WORD	17		; NULL JOB RUNNING PERCENTAGE
	.WORD	22		; Real time running percentage

; THE SECOND TABLE INDICATES THE STARTING COLUMN NUMBER OF EACH
; LINE OF THE GRAPH

BASEY::	.WORD	24		; INTERACTIVE TIME
	.WORD	24		; BATCH TIME
	.WORD	24		; SWAPPING TIME
	.WORD	24		; NULL JOB
	.WORD	24		; Real Time

; THE THIRD TABLE INDICATES THE CURRENT LENGTH OF EACH LINE IN THE GRAPH
; LENGTH IS STORED IN "NUMBER OF QUADS" OUTPUT

DISTAB::.WORD	0		; THESE ALL START AS ZERO IN LENGTH
	.WORD 	0
	.WORD	0
	.WORD	0
	.WORD	0
 
SAVBUF:	.BLKW	10.		; Save area for system times

	.SBTTL	"ONCE ONLY" INITIALIZATION

STAT:
	mov	#5,r0		; Get the LUN
	call	$sctyp		; Get the terminal type.
	tst	r2		; A supported type?
	bne	stat1		; J if so.
	qiow$c	io.wvb,5,1,,,,<badtyp,badlen,0,0,0,0>
	exit$s			; And exit.
 
stat1:	mov	#bartbl,r0	;++003 Point to table of graphics chars.
1$:	tst	(r0)+		;++003 To end of table yet?
	beq	2$		;++003 J if so.
	cmp	-2(r0),r1	;++003 Found our type?
	bne	1$		;++003 J if not.
2$:	mov	(r0),r0		;++003 Pick up address of graphics characters.
	movb	(r0)+,li.ulc	;++003 Upper left corner
	movb	(r0)+,li.urc	;++003 Upper right corner
	movb	(r0)+,li.blc	;++003 Bottom left corner
	movb	(r0)+,li.brc	;++003 Bottom right corner
	movb	(r0)+,li.ut	;++003 Upper "T"
	movb	(r0)+,li.bt	;++003 Bottom "T"
	movb	(r0)+,li.lt	;++003 Left "T"
	movb	(r0)+,li.rt	;++003 Right "T"
	movb	(r0)+,li.ver	;++003 Vertical line
	movb	(r0)+,li.hor	;++003 Horizontal line
	movb	(r0)+,li.crs	;++003 Crossing lines
	movb	(r0)+,li.qua	;++003 Quad character.
	mov	r0,li.beg	;++003 Point to begin graphics sequence
3$:	tstb	(r0)+		;++003 Find end of sequence
	bne	3$		;++003 Not found yet
	mov	r0,li.end	;++003 Point to end graphics sequence
	mov	#1,r1		; Show buffering in effect.
	call	$scbuf		; ...

; COLLECT THE "ONCE ONLY" DATA

	MOV	#SAVBUF,R5	; Initialize system times
	.inh			; Inhibit interrupts to prevent changing.
	MOV	.SSTIM,(R5)+	; Save elapsed time
	MOV	.SSTIM+2,(R5)+	;  ...
	MOV	.SNTIM,(R5)+	; Save null time
	MOV	.SNTIM+2,(R5)+	;  ...
	MOV	.SPTIM,(R5)+	; Save swap time
	MOV	.SPTIM+2,(R5)+	;  ...
	MOV	.SBTIM,(R5)+	; Save batch time
	MOV	.SBTIM+2,(R5)+	;  ...
	MOV	.SUTIM,(R5)+	; Save user time
	MOV	.SUTIM+2,(R5)+	;  ...
	.enb			; Enable interrupts.

	MOV	#NUPDAT,R0	; GET THE ADDRESS OF THE BUFFER TO STORE DATA
	MOV	.PDP11,(R0)+	; STORE THE PROCESSOR MODEL
	mov	r0,-(sp)	; Save r0
	call	$mtype		; Pick up machine type.
	mov	r0,r1		; Remember the address of the buffer.
	mov	(sp)+,r0	; Get the output address again.
	mov	r1,r2		; Remember address again.
10$:	tstb	(r1)+		; Find end of string.
	bne	10$		; ...
	dec	r1		; Decrement to null byte.
	sub	r2,r1		; Compute length of string.
	mov	r1,(r0)+	; Output the length
	mov	r2,(r0)+	; Output the address.
	MOV	.MSIZE,R4	; GET THE MEMORY SIZE IN 32. WORD BLOCKS
	ASH	#-5,R4		; +J01 TURN IT INTO WORDS
	MOV	R4,(R0)+	; AND STORE IT
	MOV	.T1PRI,(R0)+	; STORE TSS1'S RUNNING PRIORITY
	MOV	.UTLNO,(R0)+	; NUMBER OF TIMEHSARING SCHEDULING LEVELS
	MOV	.SYSQT,(R0)+	; SYSTEM MAXIMUM TIMESLICE
	MOV	.SCHPR,(R0)+	; TICKS TO SCHEDULER PROMOTION
	MOV	.BATSD,(R0)+	; TICKS BETWEEN BATCH SCHEDULES
	MOV	.BATQT,(R0)+	; BATCH QUANTUM

; NOW, CLEAR THE SCREEN AND OUTPUT THE DISPLAY MASK

	QIOW$C	IO.ATA,5,1,,,,<,UNSOLI> ; ATTACH THE TERMINAL FOR UNSOLICITED
					; INPUT (AST ENTRY ADDRESS = UNSOLIC)
CLEAR:	CALL	MASK		; AND PUT OUT THE DISPLAY


	.SBTTL	DISPLAY CYCLE CODE

; "ONCE PER CYCLE" CODE.  THE FOLLOWING ROUTINE IS ENTERED ON EVERY
; CYCLE OF THE PROGRAM.

CYCLE:	IHAR$C			; INHIBIT AST RECOGNITION WHILE CYCLING
	TST	FLAG		; ANY "RUNNING" COMMANDS GIVEN?
	BEQ	CMDDUN		; NOPE, ONWARD
	JMP	DOCMD		; GO DO THE COMMAND PROCESSING

; COLLECT, INTERPRET, COMPUTE AND DISPLAY THE "ONCE PER CYCLE" DATA.

CMDDUN:	MOV	#STTIM,R5	; GET THE ADDRESS OF THE STORAGE AREA
	SETF			; SET FLOATING POINT MODE
	SETL			; SET LONG INTEGER MODE
 
;	Get statistics

	.inh			; Inhibit context switching & interrupts.
	MOV	.SETIM,(R5)+	; SYSTEM ELAPSED TIME
	MOV	.SETIM+2,(R5)+	;
	MOV	.SSTIM,(R5)+	; SYSTEM STATISTICS TIME
	MOV	.SSTIM+2,(R5)+	;
	mov	.sntim,(r5)+	; null job time
	mov	.sntim+2,(r5)+	; ...
	mov	.sptim,(r5)+	; swap time
	mov	.sptim+2,(r5)+	; ...
	mov	.sbtim,(r5)+	; batch time
	mov	.sbtim+2,(r5)+	; ...
	mov	.sutim,(r5)+	; user time
	mov	.sutim+2,(r5)+	; ...
	.enb			; Re-enable interrupts.
 
	LDCLF	STTIM+4,AC1	; +J02LOAD AND CONVERT THE SYSTEM ELAPSED TIME
	LDCLF	SAVBUF,AC0	; Get original elapsed time
	STCFL	AC1,SAVBUF	; Update to new time
	SUBF	AC0,AC1		; Get mean elapsed time -> AC1

	LDCLF	SNTIM,AC3	; load and convert the null time
	LDCLF	SAVBUF+4,AC0	; Get last null time
	STCFL	AC3,SAVBUF+4	; Update to new null time
	SUBF	AC0,AC3		; Get mean null time
	
	LDCLF	SPTIM,AC2	; LOAD AND CONVERT SWAP TIME
	LDCLF	SAVBUF+10,AC0	; Get original swap time
	STCFL	AC2,SAVBUF+10	; Update to new swap time
	SUBF	AC0,AC2		; Get mean swap time
 
	SETI
	STCFI	AC1,-(SP)	; Get elapsed time -> (SP)
	STCFI	AC2,R0		; Get swap time -> R0
	STCFI	AC3,R1		; Get null time -> R1
	ADD	R1,R0		; Total it up
	MOV	R0,-(SP)	; Save on stack
	SETL


;	Get null time and display it

	SUBF	AC2,AC3		; TRUE NULL TIME = NULL TIME - SWAP TIME
	DIVF	AC1,AC3		; GET PERCENT OF TIME THAT NULL TIME
	SETI
	LDCIF	#5,AC0		; Round off the number
	DIVF	#1000.,AC0	; make it .5
	ADDF	AC0,AC3		; Add .5
	MULF	#100.,AC3	;  IS OF STATISTICS TIME
	MOV	#ARGLIS,R2	; GET POINTER TO ARGUMENT LIST TO STORE %'S
	CLR	(R2)+		; Store dummy real time
	STCFI	AC3,R1		; AND PUT IT BACK IN A GPR
	MOV	R1,(R2)+	; STORE THE PERCENTAGE AWAY FOR FUTURE DISPLAY
	MOV	#6,R0		; LOAD OFFSET IN DISPLAY TABLES
	CALL	DIS		; AND DISPLAY THE BOTTOM BAR OF THE GRAPH
 
;	Get SWAP time

	DIVF	AC1,AC2		; PERCENTAGE OF TIME THAT SWAP TIME
	SETI
	LDCIF	#5,AC0		; Round off the number
	DIVF	#1000.,AC0	; make it .5
	ADDF	AC0,AC2		; Add .5
	MULF	#100.,AC2	;  IS OF STATISTICS TIME
	STCFI	AC2,R1		; PUT IT IN REG1 FOR DISPLAY
	MOV	R1,(R2)+	; STORE AWAY THE PERCENTAGE
	MOV	#4,R0		; OFFSET FOR BAR 3 INTO DISPLAY TABLES
	CALL	DIS		; PUT OUT THE GRAPH
;
;	Get BATCH time

	SETL
	LDCLF	SBTIM,AC2	; LOAD AND CONVERT THE BATCH TIME
	LDCLF	SAVBUF+14,AC0	; Get original batch time
	STCFL	AC2,SAVBUF+14	; Update original batch time
	SUBF	AC0,AC2		; Get mean batch time

	SETI
	STCFI	AC2,R1		; Get batch time
	ADD	R1,(SP)		; Add to total
	DIVF	AC1,AC2		; GET THE PERCENTAGE
	LDCIF	#5,AC0		; Round off the number
	DIVF	#1000.,AC0	; make it .5
	ADDF	AC0,AC2		; Add .5
	MULF	#100.,AC2	; BATCH IS OF STAT TIME
	STCFI	AC2,R1		; AND STORE THE RESULT IN R1
	MOV	R1,(R2)+	; STORE AWAY THE PERCENTAGE
	MOV	#2,R0		; OFFSET TO BATCH BAR GRAPH
	CALL	DIS		; OUTPUT THE BAR

;
;	Get User time

	SETL
	LDCLF	SUTIM,AC2	; LOAD AND CONVERT TO FLOATING THE USER TIME
	LDCLF	SAVBUF+20,AC0	; Get original user time
	STCFL	AC2,SAVBUF+20	; Update original user time
	SUBF	AC0,AC2		; Get mean user time

	SETI
	STCFI	AC2,R1		; Get user time -> R1
	ADD	R1,(SP)		; Accumulate -> (SP)
	DIVF	AC1,AC2		; FIND THE PERCENTAGE
	SETI
	LDCIF	#5,AC0		; Round off the number
	DIVF	#1000.,AC0	; make it .5
	ADDF	AC0,AC2		; Add .5
	MULF	#100.,AC2	;
	STCFI	AC2,R1		; AND STORE IT IN R1
	MOV	R1,(R2)+	; STORE AWAY THE PERCENTAGE
	CLR	R0		; THIS IS THE FIRST LINE IN THE DISPLAY TABLES
	CALL	DIS		; AND DISPLAY THE LINE OF THE GRAPH
;
;	Display the real time
;
	MOV	(SP)+,R0	; Get the total time used by timesharing
	MOV	(SP),R1		; Get the elapsed time
	SUB	R0,R1		; Get the difference
	bge	10$		; J if >= 0
	clr	r1		; Make it 0 if < 0.
10$:	LDCIF	R1,AC0		; Get the time spent not timesharing
	LDCIF	(SP)+,AC1	; Get the elapsed time
	DIVF	AC1,AC0		; Find percent of time
	SETI			;
	LDCIF	#5,AC1		; Round off the number.
	DIVF	#1000.,AC1	; make it .5
	ADDF	AC1,AC0		; Add in .5
	MULF	#100.,AC0	; And normalize
	STCFI	AC0,R1		; Place onto argument list
	MOV	R1,ARGLIS	; Store real time
	MOV	#10,R0		; Get index into table
	CALL	DIS		; And display this line of the graph

	MOV	.JBCUR,(R2)+	; CURRENT NUMBER OF TIMESHARING JOBS
	MOV	#TB1,R4		; GET THE ADDRESS OF THE TIME BUFFER
 
;+J03	Get actual system Uptime

	MOV	.TKPS,R0	;; +J03 Get ticks/Second -> R0
	MOV	.SETIM,R1	;; +J03 Get elapsed time in tics
	MOV	.SETIM+2,R2	;; +J03 ...
	CALL	$DDIV		;; +J03 Convert to seconds
	MOV	#60.,R0		;; +J03 Set up for minutes
	CALL	$DDIV		;; +J03 Convert to minutes
	MOV	R0,4(R4)	;; +J03 Store seconds
	MOV	#60.,R0		;; +J03 Set up for hours
	CALL	$DDIV		;; +J03 Convert to hours
	MOV	R0,2(R4)	;; +J03 Store minutes
	MOV	R2,(R4)		;; +J03 Store Hours

;	Get time statistics were running

	MOV	#STTIM+4,R3	; POINT TO THE STATISTICS AREA
	MOV	#TB2,R4		; POINT TO ARGUMENT LIST
	MOV	.TKPS,R0	;; +J03 Get ticks/Second -> R0
	MOV	(R3)+,R1	;; +J03 Get elapsed time in tics
	MOV	(R3)+,R2	;; +J03 ...
	CALL	$DDIV		;; +J03 Convert to seconds
	MOV	#60.,R0		;; +J03 Set up for minutes
	CALL	$DDIV		;; +J03 Convert to minutes
	MOV	R0,4(R4)	;; +J03 Store seconds
	MOV	#60.,R0		;; +J03 Set up for hours
	CALL	$DDIV		;; +J03 Convert to hours
	MOV	R0,2(R4)	;; +J03 Store minutes
	MOV	R2,(R4)		;; +J03 Store Hours

; FORMAT AND WRITE OUT THE TEXT LINE OF THE DISPLAY

	mov	#output,r0	; Address of output buffer for text
	mov	#form,r1	; Address of format specifier
	mov	#arglis,r2	; Argument list
	call	$edmsg		; Edit the message.
	mov	r1,-(sp)	; Save r1
	mov	#5,r0		; Get LUN
	mov	#7,r1		; Get X coordinate
	mov	#23,r2		; Get Y coordinate
	call	$scadr		; Address the screen (first line)
	mov	(sp)+,r2	; Get length of buffer
	mov	#output,r1	; Get address of buffer.
	call	$scout		; Output the buffer.
;
	mov	#output,r0	; Address of output buffer for text
	mov	#form,r1	; Address of format specifier
	mov	#arglis+2,r2	; Argument list
	call	$edmsg		; Edit the message.
	mov	r1,-(sp)	; Save r1
	mov	#5,r0		; Get LUN
	mov	#7,r1		; Get X coordinate
	mov	#20,r2		; Get Y coordinate
	call	$scadr		; Address the screen (first line)
	mov	(sp)+,r2	; Get length of buffer
	mov	#output,r1	; Get address of buffer.
	call	$scout		; Output the buffer.
;
	mov	#output,r0	; Address of output buffer for text
	mov	#form,r1	; Address of format specifier
	mov	#arglis+4,r2	; Argument list
	call	$edmsg		; Edit the message.
	mov	r1,-(sp)	; Save r1
	mov	#5,r0		; Get LUN
	mov	#7,r1		; Get X coordinate
	mov	#15,r2		; Get Y coordinate
	call	$scadr		; Address the screen (first line)
	mov	(sp)+,r2	; Get length of buffer
	mov	#output,r1	; Get address of buffer.
	call	$scout		; Output the buffer.
;
	mov	#output,r0	; Address of output buffer for text
	mov	#form,r1	; Address of format specifier
	mov	#arglis+6,r2	; Argument list
	call	$edmsg		; Edit the message.
	mov	r1,-(sp)	; Save r1
	mov	#5,r0		; Get LUN
	mov	#7,r1		; Get X coordinate
	mov	#12,r2		; Get Y coordinate
	call	$scadr		; Address the screen (first line)
	mov	(sp)+,r2	; Get length of buffer
	mov	#output,r1	; Get address of buffer.
	call	$scout		; Output the buffer.
;
	mov	#output,r0	; Address of output buffer for text
	mov	#form,r1	; Address of format specifier
	mov	#arglis+10,r2	; Argument list
	call	$edmsg		; Edit the message.
	mov	r1,-(sp)	; Save r1
	mov	#5,r0		; Get LUN
	mov	#7,r1		; Get X coordinate
	mov	#7,r2		; Get Y coordinate
	call	$scadr		; Address the screen (first line)
	mov	(sp)+,r2	; Get length of buffer
	mov	#output,r1	; Get address of buffer.
	call	$scout		; Output the buffer.
;
	mov	#output,r0	; Address of output buffer for text
	mov	#form1,r1	; Address of format specifier
	mov	#arglis+12,r2	; Argument list
	call	$edmsg		; Edit the message.
	mov	r1,-(sp)	; Save r1
	mov	#5,r0		; Get LUN
	clr	r1		; Get X coordinate
	mov	#27,r2		; Get Y coordinate
	call	$scadr		; Address the screen (first line)
	mov	(sp)+,r2	; Get length of buffer
	mov	#output,r1	; Get address of buffer.
	call	$scout		; Output the buffer.
	call	$scflu		; Flush the output buffer if necessary.
;

; NOW, WAIT FOR THE NEXT CYCLE TO BEGIN

	ENAR$C			; ENABLE AST RECOGNITION
	MRKT$S	#10.,CYCTIM,#2	; MARK-TIME FOR "CYCTIM" SECONDS
	WTSE$C	10.		; WAIT FOR EVENT FLAG ONE TO BE SET
	JMP	CYCLE		; AND RECYCLE THE DISPLAY


	.SBTTL	UNSOLICITED INPUT AST ROUTINE
;
; UNSOLICITED INPUT AST ROUTINE. 
; THIS ROUTINE IS ENTERED WHEN ANY LINE OF INPUT IS TYPED ON THE TERMINAL.
; WE USE THIS ROUTINE TO GET "RUNNING" CLASS COMMANDS TO STAT. COMMANDS
; IN THIS GROUP ARE:
;
;		C 	CLEAR DISPLAY
;		X OR ^Z CLEAR SCREEN AND EXIT PROGRAM
;		IN	SET INTERVAL (TIME BETWEEN SCREEN UPDATES) TO N 
;			SECONDS
;
; ANY VALUE OTHER THAN ONE OF THOSE LISTED ABOVE IS ILLEGAL AND IGNORED.
;
UNSOLI:	CLR	USIBUF			; CLEAR BUFFER
       	CLR	USIBUF+2		; CLEAR OUT ANY EXTRANEOUS CHRS
	CLR	USIBUF+4		;  ...
	CLR	USIBUF+6		;  ...
	CLR	USIBUF+10
	QIOW$C	IO.RNE,5,1,,IOSB,,<USIBUF,6,0> ; GET THE INPUT
	QIOW$C	IO.ATA,5,1,,,,<,UNSOLI>	; ATTACH FOR ANY MORE INPUT
	cmpb	usibuf,#140	; Is it lower case?
	blo	5$		; J if not.
	bicb	#40,usibuf	; Make it upper case if so.
5$:	CMPB	#IE.EOF,IOSB	; ^Z TYPED??
	BEQ	10$		; BRANCH IF SO
	CMPB	#'X,USIBUF	; WAS THE COMMAND AN "X"??
	BNE	20$		; BRANCH IF NOT
10$:	BIS	#EXTBIT,FLAG	; SET THE "EXIT REQUESTED" FLAG
	BR	ASTEX		; EXIT THE AST
20$:	CMPB	#'I,USIBUF	; HOW ABOUT AN "I" COMMAND???
	BNE	30$		; IF NOT, GO TO 30$
	BIS	#INTBIT,FLAG	; SET THE "CHANGE INTERVAL" BIT
	BR	ASTEX		; AND BACK TO THE PROGRAM
30$:	CMPB	#'C,USIBUF	; MUST HAVE BEEN A "C" THEN??
	BNE	ASTEX		; NOPE, IGNORE IT
	BIS	#CLRBIT,FLAG	; SET THE "CLEAR SCREEN" BIT
ASTEX:	;	TST	(SP)+		; CLEAN UP THE STACK
	ASTX$S			; EXIT THE AST

	.SBTTL	"RUNNING COMMAND" PROCESSING

	.ENABL	LSB

DOCMD:	MOV	R0,-(SP)
	MOV	R1,-(SP)
	MOV	R2,-(SP)

      	BIT	#INTBIT,FLAG	; REQUEST TO CHANGE INTERVAL
	BEQ	10$		; IF EQ, NO
	MOV	#USIBUF,R0	; Point to input buffer
	MOV	#5,R1		; Set counter
2$:	CMPB	(R0)+,#40	; IN_n ?
	BEQ	3$
	SOB	R1,2$
	BR	30$		; Else leave
3$:	CALL	$CDTB		; Convert ascii to binary
	MOV	R1,CYCTIM	; Store cycle time	

10$:	BIT	#CLRBIT,FLAG	; CLEAR SCREEN AND RE-OUTPUT?
	BEQ	20$		; IF EQ, KEEP LOOKING FOR COMMAND
	CALL	MASK		; PROCESS THE REQUEST
20$:	BIT	#EXTBIT,FLAG	; EXIT NOW?
	BEQ	30$		; IF EQ, NO
	mov	#5,r0		; Get the LUN to output to.
	call	$scclr		; Clear the display.
	call	$scflu		; Flush out buffer if necessary.
	QIOW$C	IO.KIL,5,1	; KILL I/O ON THE LUN
	EXIT$S
30$:	CLR	FLAG		; CLEAR OUT THE FLAG
	MOV	(SP)+,R2	; Restore regs.
	MOV	(SP)+,R1	;  ...
	MOV	(SP)+,R0	;  ...
	JMP	CMDDUN		; RETURN TO THE DISPLAY



	.DSABL	LSB
	.SBTTL	MASK	-- SUBROUTINE TO OUTPUT DISPLAY MASK
 
	.macro	move	x,y
	.word	move
	.byte	x,y
	.endm
 
	.macro	text	arg
	.word	text
	.nchr	$$$,<arg>
	.word	$$$
	.ascii	/arg/
	.even
	.endm
 
;++003	.MACRO	CHART	y
;++003	move	23,y
;++003	text	<+---------!---------!---------!---------!---------+>
;++003	.ENDM

;++003	.MACRO	FILL	Y
;++003	move	23,y
;++003	text	<!         !         !         !         !         !>
;++003	.ENDM

; HEADER LINE STORAGE BUFFER

	.even
HEDLIN:	.BLKW	80.
BARLIN:	.BLKB	60.
FILLIN:	.BLKB	60.

; HEADER LINE FORMAT STRING FOR $EDMSG

HFMT1:	.ASCIZ	\IAS V3.1   PDP 11/%D  %VA  %DK(word) System\
HFMT2:	.ASCII	\T/S Scheduler priority: %D   T/S levels: %D\
	.ASCIZ	\  Sys max. timeslice: %D ticks\
HFMT3:	.ASCII	\Promotion time: %D ticks  Batch scheduled every %D ticks\
	.ASCIZ	\ for %D ticks\
	.even

;  MASK OUTPUT BUFFER

mob:	move	0,6
	text	<Interactive jobs>
	move	0,11
	text	<Batch jobs>
	move	0,14
	text	<Swapping time>
	move	0,17
	text	<Null job>
	move	0,22
	text	<Real time>
	move	23,4
	text	<0        20%       40%       60%       80%       100%>
;++003	CHART	5
;++003	FILL	6
;++003	FILL	7
;++003	CHART	10
;++003	FILL	11
;++003	FILL	12
;++003	CHART	13
;++003	FILL	14
;++003	FILL	15
;++003	CHART	16
;++003	FILL	17
;++003	FILL	20
;++003	CHART	21
;++003	FILL	22
;++003	FILL	23
;++003	CHART	24
	.word	0		; End of list

MASK::
	mov	r5,-(sp)	; Save r5
	mov	#5,r0		; Get LUN to output to.
	call	$scclr		; Clear the screen.
	mov	#mob,r5		; Point to output buffer.
10$:	call	@(r5)+		; Call next setup routine.
	tst	(r5)		; Anything left?
	bne	10$		; J if so.
;
; Set up the chart portion of the display.
;
	mov	#barlin,r1	;++003 Point to the output line.
	mov	#51.,r2		;++003 Get size of line.
20$:	movb	li.hor,(r1)+	;++003 Move in horizontal lines.
	sob	r2,20$		;++003 And loop.
	mov	#fillin,r1	;++003 Point to the other output line.
	mov	#51.,r2		;++003 Get size of line.
30$:	movb	#' ,(r1)+	;++003 Move in blanks.
	sob	r2,30$		;++003
	movb	li.ulc,barlin+0	;++003 Set up bar line for top line.
	movb	li.ut,barlin+10. ;++003 ...
	movb	li.ut,barlin+20. ;++003 ...
	movb	li.ut,barlin+30. ;++003 ...
	movb	li.ut,barlin+40. ;++003 ...
	movb	li.urc,barlin+50. ;++003 ...
	movb	li.ver,fillin+0	;++003 Set up the fill line.
	movb	li.ver,fillin+10. ;++003 ...
	movb	li.ver,fillin+20. ;++003 ...
	movb	li.ver,fillin+30. ;++003 ...
	movb	li.ver,fillin+40. ;++003 ...
	movb	li.ver,fillin+50. ;++003 ...
	mov	#5,r4		;++003 Get Y coordinate
50$:	call	barout		;++003 Output the bar line.
	inc	r4		;++003 Get to the next line.
	call	filout		;++003 Output fill line.
	inc	r4		;++003 Get to next line.
	call	filout		;++003 Output fill line.
	inc	r4		;++003 Get to next line.
	movb	li.lt,barlin+0.	;++003 Set up new bar line.
	movb	li.crs,barlin+10. ;++003 ...
	movb	li.crs,barlin+20. ;++003 ...
	movb	li.crs,barlin+30. ;++003 ...
	movb	li.crs,barlin+40. ;++003 ...
	movb	li.rt,barlin+50. ;++003 ...
	cmp	r4,#24		;++003 At end of list?
	blt	50$		;++003 J if so.
	movb	li.blc,barlin+0. ;++003 Set up last bar line.
	movb	li.bt,barlin+10. ;++003 ...
	movb	li.bt,barlin+20. ;++003 ...
	movb	li.bt,barlin+30. ;++003 ...
	movb	li.bt,barlin+40. ;++003 ...
	movb	li.brc,barlin+50. ;++003 ...
	call	barout		;++003 Output the bar buffer.
	mov	li.end,r1	;++003 Get end of graphics sequence.
	clr	r2		;++003 0-trailed.
	call	$scout		;++003 Output it.
;
;
	mov	#16,r1		; Get X coordinate
	clr	r2		; Get Y coordinate
	call	$scadr		; Address to screen.
;
	mov	#hedlin,r0	; Output buffer
	mov	#hfmt1,r1	; First format string
	mov	#nupdt1,r2	; Argument list.
	call	$edmsg		; Edit the message.
;
	mov	#5,r0		; Get LUN to output ti.
	mov	r1,r2		; Get the length of the message.
	mov	#hedlin,r1	; Get message.
	call	$scout		; Output first line.
;
	clr	r1		; Get X coordinate.
	mov	#1,r2		; Get Y coordinate.
	call	$scadr		; Address the screen.
;
	mov	#hedlin,r0	; Point to output string.
	mov	#hfmt2,r1	; Second format string
	mov	#nupdt2,r2	; Argument list.
	call	$edmsg		; Edit the message.
;
	mov	#5,r0		; Get LUN to output.
	mov	r1,r2		; Get the length of the message.
	mov	#hedlin,r1	; Get message.
	call	$scout		; Output second line.
;
	clr	r1		; Get X coordinate.
	mov	#2,r2		; Get Y coordinate.
	call	$scadr		; Address the screen.
;
	mov	#hedlin,r0	; Get output buffer.
	mov	#hfmt3,r1	; Third format string
	mov	#nupdt3,r2	; Argument list.
	call	$edmsg		; Edit the message.
;
	mov	#5,r0		; Get LUN to output.
	mov	r1,r2		; Get length of the message.
	mov	#hedlin,r1	; Get the message.
	call	$scout		; Output the message.
;
	CLR	DISTAB		; INITILIZE THE DISPLAY TABLE
	CLR	DISTAB+2
	CLR	DISTAB+4
	CLR	DISTAB+6	;  NO BARS DISPLAYED IN GRAPH
	CLR	DISTAB+10	;   ...
	mov	(sp)+,r5	; Recover r5
	RETURN
;
move:	movb	(r5)+,r1	; Get X coordinate.
	movb	(r5)+,r2	; Get Y coordinate.
	call	$scadr		; Address the screen.
	return			; And return.
;
text:	mov	(r5)+,r2	; Get the length of the buffer.
	mov	r5,r1		; Get the address of the buffer.
	call	$scout		; Output the buffer.
	add	r2,r5		; Adjust the pointer.
	inc	r5		; Round up if necessary.
	bic	#1,r5		; ...
	return			; And return to the caller.
filout:	mov	r4,r2		;++003 Get the Y coordinate into R2
	mov	#23,r1		;++003 Get the X coordinate into R1
	call	$scadr		;++003 Address the cursor.
	mov	li.beg,r1	;++003 Get the graphics mode sequence.
	clr	r2		;++003 0-trailed.
	call	$scout		;++003 Output it.
	mov	#fillin,r1	;++003 Point to buffer.
	mov	#51.,r2		;++003 Get size of buffer.
	call	$scout		;++003 Output it.
	return
barout:	mov	r4,r2		;++003 Get the Y coordinate into R2
	mov	#23,r1		;++003 Get the X coordinate into R1
	call	$scadr		;++003 Address the cursor.
	mov	li.beg,r1	;++003 Get the graphics mode sequence.
	clr	r2		;++003 0-trailed.
	call	$scout		;++003 Output it.
	mov	#barlin,r1	;++003 Point to buffer.
	mov	#51.,r2		;++003 Get size of buffer.
	call	$scout		;++003 Output it.
	return
	.END	STAT

