; ************** PMEDEBUG "DEBUGGER" TO START AND STOP PME *******************
;
;
; This module serves as a "user-written debugger" (from the linker's point of
; view) which in actuality initiates program counter sampling before calling
; the user's main program and terminates such sampling after the user's prog-
; ram returns or otherwise terminates.  This module is concatenated with the
; PMECLOCK object file to produce the PME object module.  This allows program
; counter sampling to be specified by linking the user program like this:
;
;		$ LINK/DEBUG=PME  userprogram
;
; This specifies this module as a "user-written debugger" which is to receive
; control before and after the user's program.
;
; The module can be concatenated with PMETRACE if trace sampling is preferred.
;
;
;		Written by Bert Beander, July, 1979.



	.TITLE	PMEDEBUG Performance Measurement and Evaluation
	.IDENT	/V01-01/


; Exit handler control block and other data areas.
;
	.PSECT	PME_DATA,NOEXE,LONG

HANDLER:				; Exit handler control block
	.LONG	0			; Forward link, filled in by system
	.LONG	EXIT			; The handler start address
	.LONG	1			; Number of arguments to handler
	.LONG	STATUS			; Address of status code longword
STATUS:	.LONG	0			; Status code is filled in here
FLAG:	.LONG	0			; PME_EXIT already done flag


	.PSECT	PME_CODE,EXE,NOWRT,LONG,PIC


; When we first get control, declare an exit handler in case the user program
; does not exit normally with a return instruction.  Call PME_INIT to start
; program counter sampling and then call the user program itself.
;
START:	.WORD	^M<>			; Entry mask
	$DCLEXH_S  HANDLER		; Declare the exit handler
	BLBS	R0,1$			; Check for good status
	RET				; If bad, return to CLI with code in R0
1$:	CALLS	#0,PME_INIT		; Initiate program counter sampling
	ADDL2	#4,4(AP)		; Step to next initialization list entry
	MOVL	@4(AP),R0		; R0 = address of user program entry pt.
	CALLG	(AP),(R0)		; Call the user's main program


; When the user program returns, set the PME_EXIT done flag, call PME_EXIT to
; close out program counter sampling, and return with the proper status code.
;
CLOSE:	INCL	FLAG			; Set the PME_EXIT already called flag
	PUSHL	R0			; Save the user program's status code
	CALLS	#0,PME_EXIT		; Terminate program counter sampling
	MOVL	(SP)+,R0		; Restore R0, the exit status code
	RET				; Return to the CLI


; This is the exit handler which is called when the user program terminates for
; any reason, including abnormally.  If the program terminated normally, we come
; here after we already called PME_EXIT.  For this reason we test FLAG to see if
; the program counter sampling has already been terminated.
;
EXIT:	.WORD	^M<>			; Entry mask
	TSTL	FLAG			; Have we already terminated PME?
	BEQL	CLOSE			; No--do so now
	RET				; Yes--there is no more to do

	.END	START			; Define start address
