	.title	sys_peek
	.ident	/X1-002/

;+
; Version:	X1-002
;
; Facility:	General system routines.
;
; Abstract:	Return the contents of a given virtual memory address.
;
; Environment:	Kernel mode.  This routine creates an environment where both
;		the current and previous modes are kernel.  Probe instructions
;		are used on both arguments but it is still possible to cause
;		bugchecks and other nasties.
;
; History:
;
;	28-Sep-1990, DBS, Version X1-001
; 001 -	Original version.
;	19-Jan-1996, FBS, Version X1-002
; 002 -	Added code for alpha.
;-

;++
; Functional Description:
;	Examines the location specified and returns the contents into a
;	longword as supplied by the caller.
;
; Calling Sequence:
;	status = sys_peek (%val(location), %ref(contents)) ! from fortran
;		-or-
;	pushal	contents
;	pushl	address
;	calls	#2, g^sys_peek
;	blbc	r0, error
;
; Formal Argument(s):
;	address.rl.v	Virtual address of the location to be read.
;	value.wl.r	Address of the longword to contain the returned
;			contents.
;
; Implicit Inputs:
;	None
;
; Implicit Outputs:
;	None
;
; Completion Codes:
;	ss$_accvio	Caller did not have read access to the address or
;			write access to the return value location.
;	ss$_insfarg	Insufficient arguments specified in the call.
;	ss$_normal	Successful completion.
;	ss$_ovrmaxarg	Too many arguments specified in the call.
;
; Side Effects:
;	It is possible to cause BUGCHECKS or system hangs if this routine
;	is not used carefully.
;--

	.library 	"SYS$LIBRARY:STARLET.MLB"
	.library 	"DBSLIBRARY:SYS_MACROS.MLB"

	.iif defined, alpha, .disable flagging
	.iif defined, ia64, .disable flagging

	.disable global

	$ssdef

arg_count=2				; to see if we have two arguments
p1=4					; offset to location address
p2=8					; offset to value address

	def_psect _sys_code, type=CODE, alignment=LONG

	set_psect _sys_code

        .entry -
sys_peek, ^m<>
	clrl	@p2(ap)			; should fault the result into memory
	$cmkrnl_s -
		routin=sys___peek_1, -
		arglst=(ap)
	ret

	.entry -
sys___peek_1, ^m<>
	$cmkrnl_s -
		routin=sys___peek_2, -
		arglst=(ap)
	ret

	.entry -
sys___peek_2, ^m<r2,r3>
	cmpw	(ap), #arg_count	; do we have two arguments ?
	bgtr	10$			; too many, bail out
	bneq	20$			; nope, not enough, bail out
	movl	p1(ap), r2		; get the address to peek
	prober	#0, #4, (r2)		; check read access
	beql	30$			; no access, get out
	movl	p2(ap), r3		; that's the address of the result
	probew	#0, #4, (r3)		; check access to result
	beql	30$			; no good, get out
	movl	(r2), (r3)		; simple, wasn't it
	movl	#ss$_normal, r0
	brb	40$
10$:	movl	#ss$_ovrmaxarg, r0
	brb	40$
20$:	movl	#ss$_insfarg, r0
	brb	40$
30$:	movl	#ss$_accvio, r0
40$:	ret

sys_peek_end::
.iif defined, alpha, .jsb_entry
.iif defined, ia64, .jsb_entry

	.end
