	.TITLE	DBGAID
	.IDENT	"V1.6"
	.NLIST	BEX,CND
;
;   Author:	D. Mischler	25-OCT-87
;
;   This module implements a debugging aid which must be
;   linked with the target task for DBG to be used.
;
;   WARNING: this code "knows" the format of command and response packets.
;
; V1.1	D. Mischler  05-JAN-88	Major redesign.
; V1.2	D. Mischler  18-JAN-88	Make MCR DEBUG handling work right.
; V1.3	D. Mischler  06-FEB-88	Operate on separate debugging stack.
; V1.4	D. Mischler  13-NOV-88	Generate 2nd task name word via TNWTBL.
; V1.5	D. Mischler  22-NOV-88	Include region ID in RT.WIN message.
; V1.6	D. Mischler  30-NOV-88	Make sure window access sent is always OK.
;
	.MCALL	ALUN$,DIR$,DSAR$S,ENAR$S,EXST$S,GLUN$
	.MCALL	GMCX$,RCVD$,SREF$S,SVDB$,WSIG$S,WDBDF$

	WDBDF$					; Define WDB offsets, etc.
WS.ACC	=	WS.DEL!WS.EXT!WS.RED!WS.WRT	; Declare WDB access mask.
	.PAGE
	.PSECT	$DBG$D,D,RW,GBL,SAV
;
;   Data definitions needed only during startup.
;
ASNLUN:	ALUN$	1,TI,0		; Assign LUN DPB.
DBGVEC:	SVDB$	$DBG$V,VECLEN	; Set debugging aid SST vectors DPB.
GETLUN:	GLUN$	1,LUNBUF	; Get LUN information DPB.
LUNBUF:	.BLKW	6		; LUN information buffer.
;   Table of second task name words, indexed by terminal number.
TNWTBL:	.RAD50	"T0 T1 T2 T3 T4 T5 T6 T7 "
	.RAD50	"T10T11T12T13T14T15T16T17"
	.RAD50	"T20T21T22T23T24T25T26T27"
	.RAD50	"T30T31T32T33T34T35T36T37"
	.RAD50	"T40T41T42T43T44T45T46T47"
	.RAD50	"T50T51T52T53T54T55T56T57"
	.RAD50	"T60T61T62T63T64T65T66T67"
	.RAD50	"T70T71T72T73T74T75T76T77"

;
;   Uninitialized data needed during operation.
;
	.=ASNLUN
ASTSTS:	.BLKW	1		; AST recognition status to restore.
	.IF DF	M$PLUS
MAPCTX:	.BLKW	24.*8.+1	; Mapping context buffer.
	.IFF	; DF M$PLUS
MAPCTX:	.BLKW	8.*8.+1		; Mapping context buffer.
	.ENDC	; DF M$PLUS
	.BLKW	20.		; Debugging stack.
DBGSTK:
RCVBUF:	.BLKW	15.		; Receive data message buffer.
CMDBUF	=	RCVBUF+4	; Command packet buffer.
TSKCTX:	.BLKB	TC.LEN		; Task context buffer.
;
;   Initialized data needed during operation.
;
CTXAPR:	.BYTE	0		; Starting APR of context window.
CTXSPC:	.BYTE	AS.UIS		; Address space of context window.
CTXWDB:	.WORD	MAPCTX		; Context window descriptor block.
GMAPCX:	GMCX$	MAPCTX		; Get mapping context DPB.
RCVMSG:	RCVD$	DBGT,RCVBUF	; Receive data DPB.
$DBG$T	==	RCVMSG+R.VDTN	; DBG task name in RAD50.
SNDBUF:	.BLKW	6		; Send by reference data buffer.
	.WORD	MAPCTX,TSKCTX	; Fixed SREF$ buffer fields.
;
;   Debugging aid SST vectors.
;
$DBG$V::.WORD	ODTRAP		; Odd address or other trap 4.
	.WORD	MPTRAP		; Memory protection violation.
	.WORD	BPTRAP		; BPT or trace trap.
	.WORD	IOTRAP		; IOT instruction.
	.WORD	ILTRAP		; Reserved instruction.
	.WORD	EMTRAP		; Non-RSX EMT instruction.
	.WORD	TRTRAP		; TRAP instruction.
	.WORD	FPTRAP		; 11/40 FP exception.
VECLEN	=	<.-$DBG$V>/2
	.PAGE
	.PSECT	$DBG$I,I,RO,GBL,SAV
;
;   Catch attempts to fall into DBGAID.
;
	HALT			; Abort task execution.
	HALT
;
;   Fatal errors during startup lead here.
;
FATAL:	BPT			; I Have No Mouth, But I Must Scream (H.E.)
;
;   DBGAID startup code. Determine the name of the
;   debugger and initiate communications.
;
DBGAID:	MOV	#PS.INI,-(SP)		; Build SST frame: push initial PS,
	MOV	R0,-(SP)		;  and initial PC.
	DIR$	#GETLUN			; Get info on LUN 1, OK?
	BCS	FATAL			; No, give it up.
	MOV	#ASNLUN,R5		; Point to assign LUN DPB.
	DIR$	R5			; Assign LUN 1 to TI0:, OK?
	BCS	FATAL			; No, forget the whole thing.
	MOV	#LUNBUF,R0		; Point to LUN information buffer.
	MOV	(R0)+,A.LUNA(R5)	; Save original LUN 1 device mnemonic,
	MOVB	(R0),A.LUNU(R5) 	;  and device unit number in ALUN$ DPB.
	DIR$	#GETLUN			; Get LUN info for TI0:
	MOVB	(R0),R0			; Get TI0: device unit number.
	ASL	R0			; Make it a word index.
	MOV	TNWTBL(R0),$DBG$T+2	; Set second word of debugger task name.
	DIR$	R5			; Restore original LUN 1 assignment, OK?
	BCS	FATAL			; No, give up (in disgust).
	DIR$	#DBGVEC			; Set debugging aid SST vectors.
	DIR$	#GMAPCX			; Get initial mapping context.
	MOV	#MAPCTX,R0		; Point to mapping context buffer.
	.IF DF	M$PLUS
	TST	W.NLGH(R0)		; Is there only one address window?
	BMI	10$			; Yes, can't be I/D space.
	BIT	#WS.UDS,W.NSTS+W.NLGH(R0) ; Is window 1 in user data space?
	BEQ	10$			; No, use window 0 (I space only).
	ADD	#W.NLGH,R0		; Point to context WDB.
	CLRB	CTXSPC			; Set up context address space type.
	.ENDC	; DF M$PLUS
10$:	MOV	R0,CTXWDB		; Save context window WDB address.
	MOVB	W.NAPR(R0),CTXAPR	; Save context window base APR number.
;
;   Patch this word to an RTI (000002) to start execution immediately.
;
$DBG$S::
	CLR	-(SP)			; No data words are present.
	MOV	#RT.STU,-(SP)		; Get start packet ID.
	BR	DBGCTX			; Send startup message.
	.PAGE
;
;   Odd address or other trap 4.
;
ODTRAP:	CLR	-(SP)		; No data words are present.
	MOV	#RT.ODD,-(SP)	; Get odd address SST packet ID.
	BR	DBGCTX		; Send odd address SST message.
;
;   Memory protection violation.
;
MPTRAP:	MOV	#3,-(SP)	; Three data words are present.
	MOV	#RT.MPV,-(SP)	; Set up memory protect violation ID.
	BR	DBGCTX		; Send memory protection violation SST message.
;
;   IOT instruction trap.
;
IOTRAP:	CLR	-(SP)		; No data words are present.
	MOV	#RT.IOT,-(SP)	; Set up IOT instruction SST packet ID.
	BR	DBGCTX		; Send SST message.
;
;   Illegal instruction trap.
;
ILTRAP:	CLR	-(SP)		; No data words are present.
	MOV	#RT.ILL,-(SP)	; Set up illegal instruction SST ID.
	BR	DBGCTX		; Send SST message.
;
;   Non-RSX EMT instruction trap.
;
EMTRAP:	MOV	#1,-(SP)	; There is one data word.
	MOV	#RT.EMT,-(SP)	; Set up Non-RSX EMT SST ID.
	BR	DBGCTX		; Send SST message.
;
;   TRAP instruction execution.
;
TRTRAP:	MOV	#1,-(SP)	; There is one data word.
	MOV	#RT.TRP,-(SP)	; Set up TRAP instruction SST ID.
	BR	DBGCTX		; Send SST message.
;
;   PDP-11/40 floating point exception.
;
FPTRAP:	CLR	-(SP)		; No data words are present.
	MOV	#RT.FPX,-(SP)	; Set up 11/40 FP exception SST ID.
	BR	DBGCTX		; Send SST message.
	.PAGE
;
;   Break point trap or trace trap.
;
BPTRAP:	BIT	#PS.TRC,2(SP)		; Was trace trap enabled?
	BEQ	20$			; No, assume break point trap.
	CMP	(SP),#DBGAID		; Is return PC below DBGAID?
	BLO	30$			; Yes, it's a regular trace trap.
	CMP	(SP),#DBAEND		; Is return PC at or above DBAEND?
	BHIS	30$			; Yes, it's a regular trace trap.
;
;   Trap was caused by the MCR DEBUG command.
;
	MOV	@#$DSW,-(SP)		; Preserve directive status.
	MOV	SNDBUF,-(SP)		; Save last response packet type.
	MOV	#RT.DEB,SNDBUF		; Set up new response packet type.
	SREF$S	#$DBG$T,CTXWDB		; Send MCR DEBUG packet.
	MOV	(SP)+,SNDBUF		; Recover last response packet type.
	MOV	(SP)+,@#$DSW		; Restore directive status.
	BIC	#PS.TRC,2(SP)		; Clear trace bit in return PS.
	RTT				; Return into DBGAID.
;
;   Indicate a break point trap occurred.
;
20$:	CLR	-(SP)			; No data words are present.
	MOV	#RT.BPT,-(SP)		; Set up BPT SST packet ID.
	BR	DBGCTX			; Send SST message.
;
;   Indicate a trace trap occurred.
;
30$:	CLR	-(SP)			; No data words are present.
	MOV	#RT.TRC,-(SP)		; Set up trace trap SST packet ID.
;   Fall into DBGCTX to save context and send trace trap SST message.
	.PAGE
;
;   Save task context and send an appropriate message.
;
DBGCTX:	MOV	@#$DSW,-(SP)		; Protect directive status.
	DSAR$S				; Disable AST recognition.
	MOV	@#$DSW,ASTSTS		; Save AST recognition status.
	DIR$	#GMAPCX			; Get mapping context.
	MOV	(SP)+,TSKCTX+TC.DSW	; Save task-level directive status.
	MOV	R0,TSKCTX+TC.R0		; Save R0.
	MOV	#TSKCTX+TC.R1,R0	; Point into task context buffer.
	MOV	R1,(R0)+		; Save R1.
	MOV	R2,(R0)+		; Save R2.
	MOV	R3,(R0)+		; Save R3.
	MOV	R4,(R0)+		; Save R4.
	MOV	R5,(R0)+		; Save R5.
	MOV	#SNDBUF,R1		; Point to response packet buffer.
	MOV	R1,R2			; Copy pointer.
	MOV	(SP)+,(R2)+		; Set up response packet type.
	MOV	CTXAPR,(R2)+		; Set up context window data.
	MOV	CTXWDB,(R2)+		; Set up address of WDB.
	MOV	(SP)+,R3		; Get number of extra data words, zero?
	BEQ	20$			; Yes, finish saving context.
10$:	MOV	(SP)+,(R2)+		; Copy a word into response packet.
	SOB	R3,10$			; Copy 'em all.
;   Finish saving task context.
20$:	TST	(R0)+			; Skip over SP for now.
	MOV	(SP)+,(R0)+		; Save PC.
	MOV	(SP)+,(R0)		; Save PS.
	MOV	SP,TSKCTX+TC.SP		; Save SP.
	MOV	#DBGSTK,SP		; Load debug stack.
	MOV	#CMDBUF,R4		; Point to command buffer.
	MOV	CTXWDB,R5		; Point to context WDB.
;   Fall into DBGSND to send the context window by reference.
	.PAGE
;
;   Send an address window by reference.
;   On arrival:	R0 -> TSKCTX+TC.PS
;		R1 -> SNDBUF
;		R4 -> CMDBUF
;		R5 -> WDB to be sent
;
DBGSND:
	MOV	R1,W.NSRB(R5)		; Save send buffer address in WDB.
	BIC	#WS.ACC,W.NSTS(R5)	; Default region access rights.
10$:	SREF$S	#$DBG$T,R5		; Attempt message transmission, OK?
	BCC	20$			; Yes, wait for a reply.
	WSIG$S				; Wait for a significant event.
	BR	10$			; Try again.
;   Message has been sent: wait for a reply.
20$:	DIR$	#RCVMSG			; Attempt message reception, OK?
	BCC	30$			; Yes, analyze the command packet.
	WSIG$S				; Wait for a significant event.
	BR	20$			; Try again.
;   A command packet has been received: take a look at it.
30$:	CMP	#CT.PRO,(R4)		; Proceed with task execution?
	BEQ	PROCED			; Yes, do so.
	CMP	#CT.SWR,(R4)		; Send window by reference?
	BEQ	SWNDOW			; Yes, hear and obey.
	MOV	#RT.AFU,(R1)		; Set possible response type.
	CMP	#CT.XIT,(R4)		; Exit command?
	BNE	DBGSND			; No, complain about invalid command.
;
;   Obey the EXIT command.
;
EXIT:	EXST$S	#EX$SEV		; Terminate execution with severe error.
	.PAGE
;
;   Proceed with program execution.
;
PROCED:	MOV	TSKCTX+TC.SP,SP		; Get task stack pointer.
	MOV	(R0),-(SP)		; Set up task PS.
	MOV	-(R0),-(SP)		; Set up task PC.
	TST	-(R0)			; Skip over SP.
	MOV	-(R0),R5		; Restore R5.
	MOV	-(R0),R4		; Restore R4.
	MOV	-(R0),R3		; Restore R3.
	MOV	-(R0),R2		; Restore R2.
	MOV	-(R0),R1		; Restore R1.
	MOV	-(R0),R0		; Restore R0.
	MOV	TSKCTX+TC.DSW,-(SP)	; Stack task-level DSW.
	TST	ASTSTS			; Should AST recognition be reenabled?
	BMI	10$			; No, skip it.
	ENAR$S				; Enable AST recognition.
10$:	MOV	(SP)+,@#$DSW		; Restore directive status.
	RTT				; Continue task execution.

;
;   Send the requested address window by reference.
;
SWNDOW:	MOV	R1,R2			; Copy SNDBUF address.
	MOV	C.WADR(R4),R5		; Get address of specified WDB.
	MOV	#RT.WIN,(R2)+		; Set up response type.
	MOVB	W.NAPR(R5),(R2)+	; Put APR in response packet.
	MOVB	#AS.UIS,(R2)		; Assume window is in user I space.
	.IF DF	M$PLUS
	BIT	#WS.UDS,W.NSTS(R5)	; Is window actually in D space?
	BEQ	10$			; No, check super I space.
	CLRB	(R2)			; Set up window address space.
	BR	20$			; Finish up.
;   Check WDB for supervisor I space window.
10$:	BIT	#WS.SIS,W.NSTS(R5)	; Is window in super I space?
	BEQ	20$			; No, send user I space window.
	MOVB	#AS.SIS,(R2)		; Set window address space.
	.ENDC	; DF M$PLUS
;   Save WDB address in response packet.
20$:	INC	R2			; Point to WDB address field.
	MOV	R5,(R2)+		; Stuff WDB address into place.
	MOV	W.NRID(R5),(R2)+	; Send region ID as variable data.
	BR	DBGSND			; Send response packet.

DBAEND:					; End of debugging aid code.
	.END	DBGAID
