;*************************************************
;	Program:	show_proc_page
;	Author:		Billy Bitsenbites (Bruce Ellis)
;	Function:	This program will determine and
;			display the page and swap file
;			usage by page file number, per 
;			process
;	Date written:	6/2/90
;*************************************************
;Macro to check status
	.macro	check	?l
	blbs	r0,l
	$exit_s	r0
l:
	.endm	check
;Include system definitions
	.library	/sys$library:lib.mlb/
	.link		/sys$system:sys.stb/
	$pcbdef		;Process control block definitions
	$phddef		;Process header definitions
;Define offsets into information buffer structure
long_size=4
name_size=16
flags=0
prcpgfl=flags+long_size
pgflcnt=prcpgfl+long_size
wsswp=pgflcnt+long_size
epid=wsswp+long_size
prcnam=epid+long_size
align_skip=prcnam+long_size
buf_size=align_skip+name_size

;address range to lock for code
code_lock:
	.address	code_lock_start
	.address	code_lock_end
;P0 expand region and address range to lock for data
p0_exp:
	.address	512
	.address	512
;Argument list for SYS$CMKRNL
kargs:	.long	2
buffer_loc:
	.long	0
	.address	proc_cnt
proc_cnt:
	.long	0
disp_buffer:
	.long	80			;Display buffer
	.address	10$
10$:	.blkb	80
post_size=8
slot_desc:
	.long	post_size
	.address	post
swap_str:
	.long	pre_size+post_size	;total buffer size
	.address	prefix		;swap file prefix
prefix:	.ascii	/Swap slot: /
	pre_size=.-prefix
post:	.blkb	post_size		;storage for string or swap file #
none:	.ascii	/None/
none_size=.-none
pfl:	.ascii	/PFLMAPed/
pfl_size=.-pfl
prc_fmt:
	.ascid	$!/Process name: !15AC   Pid: !8XL$
pag_fmt:
	.ascid	/Number of page files: !2UB  Page file #s: !2UB,!2UB,!2UB,!2UB/
sys_pfl:	
	.blkl	1
sys_pfl_cnt:
	.blkl	1
sys_pfl_hdr:
	.ascid	<10><13>/System header/
page_size=512				;Avoid assumptions
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
;	Main program
;	Flow:
;	Allocate a buffer large enough to hold MAXPROCESSCNT
;		structures
;	Lock code and buffer accessed at ipl>2
;	Get into kernel mode and grab data
;	Spill the info
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
	.entry	show_proc_page,^m<r2,r3,r5,r6,r7,r8,r9,r10,r11>
	movzwl	g^sgn$gw_maxprcct,r3	;get MAXPROCESSCNT setting
	mull3	#buf_size,-		;size the buffer to hold
		r3,r2			;info on all possible processes
	divl2	#page_size,r2		;calculate number of pages for buffer
	incl	r2			;allow for truncation
;^^^^^^^^^^^^^^^^^
;allocate a buffer
;^^^^^^^^^^^^^^^^^
	$expreg_s	inadr=p0_exp,retadr=p0_exp,pagcnt=r2
	check
;^^^^^^^^^^^^^^^^^
;Lock code and data accessed at High IPL
;^^^^^^^^^^^^^^^^^
	$lkwset_s	inadr=p0_exp	;lock the buffer
	check
	$lkwset_s	inadr=code_lock	;lock the code
	check
	movl	p0_exp,buffer_loc	;set data buffer address
;^^^^^^^^^^^^^^^^^
;Get the info
;^^^^^^^^^^^^^^^^^
	$cmkrnl_s	routin=get_pfl_info,arglst=kargs
	check
	movl	p0_exp,r11		;Get address of data buffer
	movl	proc_cnt,r6		;Get process count
display:
	moval	prcnam(r11),r3		;get address of process name string
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
;Format and display Process name and Pid
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
	$fao_s	ctrstr=prc_fmt,outbuf=disp_buffer,outlen=disp_buffer,-
		p1=r3 ,p2=epid(r11)
	pushal	disp_buffer		;Spill the display buffer
	calls	#1,g^lib$put_output
	movl	#80,disp_buffer		;Reset buffer size
	movl	pgflcnt(r11),r5		;get count of page files
	movzbl	prcpgfl(r11),r7		;get 1st page file number
	movzbl	<prcpgfl+1>(r11),r8	;get 2nd page file number
	movzbl	<prcpgfl+2>(r11),r9	;get 3rd page file number
	movzbl	<prcpgfl+3>(r11),r10	;get 4th page file number
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
;Format and display page file info
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
	$fao_s	ctrstr=pag_fmt,outbuf=disp_buffer,outlen=disp_buffer,-
		p1=r5,p2=r7,p3=r8,p4=r9,p5=r10
	pushal	disp_buffer		;spill the display buffer
	calls	#1,g^lib$put_output
	movl	#80,disp_buffer		;reset buffer size
	tstb	wsswp(r11)		;check swap slot number
	beql	no_swapfile		;if=0, print none
	bgtr	swap_slot		;if high bit clear, process slot number
	movc5	#pfl_size,pfl,#^a/ /,-	;append 'PFLMAPed' on prefix
		#post_size,post
	brb	done_w_swap		;done with swap file string
no_swapfile:
	movc5	#none_size,none,#^a/ /,-	;append 'None' on prefix
		#post_size,post
	brb	done_w_swap		;done with swap file string
swap_slot:
	pushal	slot_desc		;format the slot number
	pushal	wsswp(r11)
	calls	#2,g^ots$cvt_l_ti	;format to decimal
	check
done_w_swap:
	pushal	swap_str		;Spill swap file info string
	calls	#1,g^lib$put_output
	addl	#buf_size,r11		;get next process structure
	sobgtr	r6,br_display		;Continue until out of processes
	brb	done_display
br_display:
	brw	display
done_display:
	pushal	sys_pfl_hdr		;Display header for system header
	calls	#1,g^lib$put_output
	movl	#80,disp_buffer		;Reset buffer size
	movl	sys_pfl_cnt,r5		;get count of page files
	movzbl	sys_pfl,r7		;get 1st page file number
	movzbl	sys_pfl+1,r8		;get 2nd page file number
	movzbl	sys_pfl+2,r9		;get 3rd page file number
	movzbl	sys_pfl+3,r10		;get 4th page file number
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
;Format and display page file info
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
	$fao_s	ctrstr=pag_fmt,outbuf=disp_buffer,outlen=disp_buffer,-
		p1=r5,p2=r7,p3=r8,p4=r9,p5=r10
	pushal	disp_buffer		;spill the display buffer
	calls	#1,g^lib$put_output

	ret

;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
;	Routine:	get_pfl_info
;	function:	Returns page file count, page file #s
;			swap file #s, process name, and epid for
;			each process on the system.
;	inputs:		4(ap) -> buffer of per process structures
;			whose format is described at the beginning of the 
;			program.
;			8(ap) -> address of longword to receive 
;			the count of actual process on the system
;	outputs:	buffer filled in.
;			process count returned in @8(ap)
;			r0 <- ss$_normal
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
buffer=4
prccnt=8
	.entry	get_pfl_info,^m<r6,r7,r8,r9,r10,r11>
	movl	buffer(ap),r6		;Get address of data buffer
	movl	g^sch$gl_pcbvec,r7	;get the address of PCB vector table
	movl	g^sch$gl_maxpix,r8	;get the maximum process index
code_lock_start:
	lock	lockname=SCHED,lockipl=#ipl$_sched	;lock the scheduling db
pixloop:
	movl	(r7)[r8],r9		;get the next pcb address
	decl	r8			;use next proces index
	cmpl	pcb$l_pid(r9),-		;If we are at the SWAPPER, we are done
		g^sch$gl_swppid
	bneq	process_process		;else process the process
	brw	done_with_procs		;if done, scram
process_process:
	cmpl	r9,g^sch$ar_nullpcb	;if the slot is empty, skip it
	beql	pixloop			;get next pcb
	movl	pcb$l_sts(r9),flags(r6)	;copy status flags
	bbc	#pcb$v_phdres,-		;if PHD swapped, skip it
		pcb$l_sts(r9),phd_swapped
	movl	pcb$l_phd(r9),r10	;get the PHD of this process
	movl	phd$b_prcpgfl(r10),-	;copy page file array
		prcpgfl(r6)
	movzbl	phd$b_pgflcnt(r10),-	;copy the count of page files
		pgflcnt(r6)
	bbs	#pcb$v_res,-		;if Process body res, skip swap file 
		pcb$l_sts(r9),body_res
phd_swapped:
	movzbl	<pcb$l_wsswp+3>(r9),-	;get swap slot info
		wsswp(r6)
body_res:
	movl	pcb$l_epid(r9),epid(r6) ;get process id (extended)
	movq	pcb$t_lname(r9),-	;copy the process name (1st half)
		prcnam(r6)
	movq	<pcb$t_lname+8>(r9),-	;copy the process name (2nd half)
		<prcnam+8>(r6)
	incl	@prccnt(ap)		;bump he count of processes
	addl	#buf_size,r6		;point to next buffer strucure
	brw	pixloop			;get next process
done_with_procs:
	unlock	lockname=SCHED,newipl=#0	;unlock sched db
code_lock_end:
	movl	g^mmg$gl_sysphd,r6	;locate the system header
	movl	phd$b_prcpgfl(r6),-	;get the page file array
		sys_pfl	
	movzbl	phd$b_pgflcnt(r6),-	;get count of page files
		sys_pfl_cnt
	movl	#ss$_normal,r0		;return success, no chance for failure
	ret
	.end	show_proc_page
