.PAGE
;******************************************************
;*						      *
;*		  GO COMMAND			      *
;*						      *
;*  COPYRIGHT (c) 1982, 1983 SAGE Computer Technology *
;*  All Rights Reserved				      *
;*						      *
;******************************************************

CMG
	LEA	SCMG,A1		;Jump to GO subcommand
	BRA	SRCHCMND
	
;GS [[$X+]XXXXXX] - Go setting break following BRA,BSR,BCC,JMP,JSR,DBCC,TRAP

CMGS
	BSR	SETSTART	;Set starting address if needed
	LEA	TRANLEN-2,A1	;Address of table
$1
	ADDQ.L	#2,A1		;Move to next table entry
	TST.W	(A1)		;Any more entries left in table?
	BEQ	CMNDERRA	;Report illegal instruction
	MOVE.W	(A4),D0		;Get instruction
	AND.W	(A1)+,D0	;Mask instruction
	CMP.W	(A1)+,D0	; Proper instruction?
	BNE	$1		; No try again
	ADDA.W	(A1),A4		;Compute address for break
	MOVE.L	A4,BRKPNT2	;Set breakpoint
	BSET	#BK2,BMODE	;Enable break point 2
	BSET	#GSBRK,BMODE	;Enable Subroutine break point
	BRA.S	CMGO1		;Clear breakpoint counts
	
;GO [[$X+]XXXXXX] - Execute program / reseting breakpoints 

CMGO
	BSR.S	SETSTART	;Set starting address if needed
CMGO1
	MOVEQ	#MAXBRKP-1,D2	;Reset breakpoint count
$1
	BSR	NEXTBRK
	CLR.W	BRKCOUNT(A2)	;Clear breakpoint
	DBF	D2,$1		;Repeat for all breakpoints
	BRA.S	CMG1
	
;GC [[$X+]XXXXXX] - Execute program / breakpoint unchanged

CMGC
	BSR.S	SETSTART	;Set starting address if needed
CMG1
	BCLR	#DSPREGS,BMODE	;Dont display register at completion
CMG2
	BSET	#TRACE,BMODE	;Assume tracing
	BSET	#BRKPT,BMODE	;Set breakpoint flag
	MOVE.B	BMODE,D0	;Any breakpoints set
	ANDI.B	#7.,D0
	BNE.S	$1		;Breakpoints set
	BCLR	#TRACE,BMODE	;If no breakpoints then no need to trace
$1
	BRA	EXECUTE		;Set up to start program


;Set starting address for Go and Trace commands
;			A0 : Command buffer
;	BSR	SETSTART
;			A0 : Following address of address (if any)
;			A1 : ?
;			A2 : ?
;			A4 : REGPC
;			D0 : ?
;			D1 : ?
;			D2 : ?
;			D6 : REGPC
; THIS ROUTINE DOES NOT RETURN IF ADDRESS ERROR DETECTED. IT GOES DIRECTLY
; BACK TO DEBUGGER AFTER ERROR ISSUED.

SETSTART
	BSR	SKIPSPAC
	MOVE.B	(A0),D0		;Any starting address given
	BEQ.S	$1		;No - start at address in PC
	BSR	CNVTADDR	;Get starting address
	BNE	CMNDERRA	;Error - Illegal address
	MOVE.L	A1,REGPC	;Set starting address
$1
	BSR.S	CHKADDR		;Check for legal address (ok if it returns)
	BSR	TERMCRLF
	RTS
	
;Check REGPC for legal address
CHKADDR
	MOVE.L	REGPC,D6
	MOVEA.L D6,A4		;Set starting address
	BTST	#0,D6		;Starting on word boundry
	BEQ.S	$1		;Yes
	LEA	BADADDR,A0	;Print starting at bad address
	BSR	TERMTEXT
	MOVE.L	D6,D0		;Print bad address
	BSR	PRNTADDR
	BRA	DEBUG
$1
	MOVEA.L A4,A1		;Starting address good?
	BSR	CHKMEM
	BNE	CMNDERRA	;No - return to debugger
	RTS

BADADDR
	.ASCII	"Illegal program start address: "
	.BYTE	0
	.ALIGN	2
.PAGE
;****************************************
;*					*
;*	      TRACE COMMAND		*
;*					*
;****************************************

CMT
	BSR	TERMCRLF
	LEA	SCMT,A1		;Find command in table
	BRA	SRCHCMND
	
;<Blank line> - Trace next instruction

CMTC
	BTST	#TRACE,BMODE	;In tracing mode?
	BEQ.S	$1		;No
	BSR	CHKADDR		;Check for valid address
	BRA.S	RTRACE		;Execute next instruction
$1
	RTS			;Get next command
	
;TR [[$X+]XXXXXX] - Trace program / displaying registers

CMTR
	BSET	#DSPREGS,BMODE	;Display registers on return
	BRA.S	CMTB1		;Continue trace processing
	
;TN XX - Trace next group of instructions
;TNI XX - Trace next group of instructions (interruptible)

CMTN
	BSR	CHKADDR		;Make sure we're starting at a legal address
	BCLR	#UTRACE,BMODE	;Disable trace breaking
	CMPI.B	#"I",(A0)	;Interuptable tracing requested?
	BNE.S	$05		;No
	BSET	#UTRACE,BMODE	;Set interuptable tracing
	ADDQ.L	#1,A0		;Step over request
$05	
	MOVEQ	#5,D0		;Assume tracing screen full with reg display
	BTST	#DSPREGS,BMODE	;Displaying registers
	BNE.S	$1		;Yes guessed right!
	MOVEQ	#16.,D0		;Trace 16 instructions
$1
	TST.B	(A0)		;Number of instructions specified
	BEQ.S	$2		;No
	MOVEQ	#127.,D2	;Maximum of 127 instructions
	BSR	SKIPSPAC
	BSR	GETNUM		;Get number of instructions
	BMI	CMNDERRA	;Bad results
$2
	BSR	TERMCRLF
	BRA.S	RTRACE1		;Continue processing
	
;TB [[$X+]XXXXXX] - Trace program / without displaying registers

CMTB
	BCLR	#DSPREGS,BMODE	;Dont display registers on return
CMTB1
	BSR	SETSTART	;Get starting address if needed

RTRACE
	MOVEQ	#1,D0		;Trace 1 instruction
RTRACE1
	MOVE.B	D0,TRACECNT	;Set number of instructions to trace
RTRACE2
	BSET	#TRACE,BMODE	;Set trace flag
	BCLR	#BRKPT,BMODE	;Clear breakpoint flag
	MOVE.W	(A4),D0		;Is this instr. a TRAP?
	ANDI.W	#0FFF0H,D0
	CMPI.W	#4E40H,D0
	BNE.S	EXECUTE		;No, trace normally
	
;Special routine to decide whether to trace this TRAP instruction or not.
TT
	MOVE.W	(A4)+,D0	;Recover TRAP instruction
	ANDI.W	#0FH,D0		;Find out which one it is
	MOVE.W	TTARRAY,D6	;Boolean array tells whether to trace or not
	LEA	TTMSG1,A0	;Assume we're going to trace it
	BTST	D0,D6
	BNE.S	$1		;Trace the TRAP
	MOVE.L	A4,BRKPNT2	;Set up breakpoint 2 so we can skip tracing
	BSET	#BRKPT,BMODE
	BSET	#BK2,BMODE	;Activate breakpoint 2
	BCLR	#GSBRK,BMODE	;Terminate GS command if active, because we
	BEQ.S	EXECUTE		;  need the breakpoint 2 register
	LEA	TTMSG2,A0	;Inform user of GS termination
$1
	BSR	TERMTEXT	;Inform user of TRAP tracing or GS termination
	BSR	TERMCRLF
	BRA.S	EXECUTE
	
TTMSG1
	.ASCII	"*** Tracing TRAP ***"
	.BYTE	0
TTMSG2
	.ASCII	"*** GS terminated ***"
	.BYTE	0
	.ALIGN	2


;Set up for execution

EXECUTE
	MOVEA.L REGPC,A4	;Get current execution address
	MOVE.W	REGSR,D6	;Get status register
	BTST	#TRACE,BMODE	;Tracing program?
	BNE.S	$10
	BCLR	#15.,D6		;Disable tracing
	BRA.S	$30
;Set trace bit
$10	BSET	#15.,D6		;Request trace in status register

;Restore all registers and start execution of program

$30
	MOVEA.L REGUS,A0	;Restore user stack pointer
	MOVE	A0,USP
	MOVEA.L REGA7,A7	;Set up system stack
	MOVE.L	A4,-(A7)	;Put program counter on stack
	MOVE.W	D6,-(A7)	;Put status register on stack
	MOVEM.L REGTRAP,D0-D7/A0-A6
	RTE


;TE - End trace mode

CMTE
	BCLR	#TRACE,BMODE	;Clear trace mode bit
	RTS

;Set move to next breakpoint and test memory for valid address
;			D2 : Breakpoint register
;	BSR	NEXTBRK
;			D0 : ?
;			D2 : Breakpoint register
;			A1 : Breakpoint address
;			A2 : Breakpoint contents index
;			EQ : Breakpoint register not in use
;			GT : All OK
;			MI : Memory error detected at breakpoint address

NEXTBRK
	CLR.L	D0		;Clear result status registe
	MOVEA.W D2,A1		;Convert register number to offset
	ADDA.L	A1,A1
	MOVEA.L A1,A2		;Set breakpoint contents index
	ADDA.L	A1,A1
	BTST	D2,BMODE	;Breakpoint set?
	BEQ.S	$1		;No
	MOVEA.L BRKPOINT(A1),A1 ;Set breakpoint address
	BSR	CHKMEM		;Verify breakpoint memory exist
	BNE	$2		;Memory error
	ADDQ.L	#1,D0		;Set all Ok
$1
	RTS
$2
	SUBQ.L	#1,D0		;Set error
	RTS

;Print physical and relative address at current cursor position
;			D0 : Physical address
;	BSR	PRNTADDR
;			D0 : Relative address
;			A0 : Base register offset

PRNTADDR
	BSR	TERMHEXL	;Print physical address
	MOVEA.W LOCCNTR,A0	;Form base register offset
	ADDA.W	A0,A0
	ADDA.W	A0,A0
	TST.W	LOCCNTR		;Do we need any relative stuff?
	BEQ.S	$1		;No, base register is zero
	BSR	TERMSPAC
	MOVE.L	D0,-(A7)	;Save physical address
	MOVEQ	#"(",D0		;Print "("
	BSR	TERMCHAR
	MOVEQ	#"$",D0		;Print "$"
	BSR	TERMCHAR
	MOVE.W	LOCCNTR,D0	;Print base register
	BSR	TERMDIGT
	BSR	TERMCOLN
	MOVE.L	(A7)+,D0	;Print relative address
	SUB.L	BASEADDR(A0),D0
	BSR	TERMHEXL
	MOVEQ	#")",D0		;Print ")"
	BSR	TERMCHAR
$1	RTS

;Trap entry point

GDTRACE
	.ASCII	"Trace: "
	.BYTE	0
	.ALIGN	2
	
TRCTRAP
	BTST	#TRACE,BMODE	;Legal trace condition
	BEQ	EXECUTE		;Yes - Assume RTE initiated tracing
$1
	BTST	#BRKPT,BMODE	;Break point running?
	BEQ.S	$2		;No
	
;Go command processing 
	BCLR	#TRACE,BMODE	;Clear tracing
	MOVEQ	#0,D2		;Set breakpoints
$11
	BSR	NEXTBRK		;Get breakpoint
	BMI	CMNDERRA	;Breakpoint address does not exist
	BEQ.S	$12		;No breakpoint for register
	MOVE.W	(A1),BRKCONT(A2);Save original contents
	MOVE.W	#4E4FH,(A1)	;Put back breakpoint TRAP (#15)
$12
	ADDQ.W	#1,D2		;Move to next breakpoint
	CMPI.W	#MAXBRKP+1,D2	;Reached end?
	BNE	$11		;Repeat until done
	BRA	EXECUTE		;Continue execution

;Trace command processing
$2
	LEA	GDTRACE,A0	;Print trace break
$3
	MOVE.L	REGPC,D0	;Set addr of inst just traced
INTADDR
	MOVE.L	D0,LASTMEM	;Initialize register for "AD" and "DM" commands
	BSR	TERMTEXT
	MOVEA.L D0,A4		;Save interupt address
	BSR	PRNTADDR
	ADDA.W	#BASEADDR,A0	;Set up base for display
	MOVE.W	A0,LASTBASE
	BSR	TERMCOLN	;Print a colon
	MOVEA.L A4,A1		;Get word at address
	BSR	CHKMEM		;Legal memory?
	BNE.S	$1		;No memory
	MOVE.W	(A1),D0		;Print word
	BSR	TERMHEXW
	BSR	TERMSPAC	;Print instruction at address
	BSR	TERMSPAC
	MOVEA.L A1,A6
	BSR	DISASM
$1
	BTST	#DSPREGS,BMODE	;Print registers?
	BEQ.S	$2		;No - skip print
	LEA	CMNDLINE,A0	;Fake buffer
	CLR.B	(A0)
	BSR	CMDR		;Print all registers
$2
	SUBQ.B	#1,TRACECNT	;Any more instructions to trace
	BLE.S	$5		;Enter debugger
	BTST	#UTRACE,BMODE	;Interuptable tracing?
	BEQ.S	$6		;No
	BSR	TESTTERM	;Any characters waiting?
	BEQ.S	$6		;No - continue
$4
	BSR	KEYBCH		;Get character
	CMPI.B	#CNTRLS,D0	;Break character?
	BEQ	$4		;Yes - Wait for continue character
	CMPI.B	#CNTRLC,D0	;Break character
	BNE.S	$6
$5
	BRA	DEBUG
$6
	BSR	TERMCRLF	;Set to new line
	BRA	RTRACE2		;Trace next instruction

;Debugger break exception entry point

BADBREAK
	.BYTE	CR,LF
	.ASCII	"Unexpected break point: "
	.WORD	0
GDBREAK
	.BYTE	CR,LF
	.ASCII	"Break: "
	.BYTE	0

BRKTRAP
	CLR.L	D5		;Set breakcount to interupt
	CLR.L	D6
	MOVE.L	REGPC,D4	;Get break address + 2
	SUBQ.L	#2,D4		;Convert to break address
	MOVEQ	#0,D3		;Restart execution at next instuction
	LEA	BADBREAK,A0	;Assume unexpected brkpt until proven otherwise
	MOVEQ	#MAXBRKP,D2	;Clear break points

$2
	BSR	NEXTBRK		;Get next breakpoint
	BLE.S	$3		;Not in use or error detected
	CMPA.L	D4,A1		;Reached set breakpoint
	BNE.S	$25		;No
	LEA	GDBREAK,A0	;Expected this breakpoint
	MOVEQ	#2,D3		;Set to reexecute instruction
	CMPI.B	#MAXBRKP,D2	;Don't mess with counts for BK2, it doesn't
	BEQ.S	$25		;  have any
	MOVE.W	BRKCOUNT(A2),D5 ;Get break count
	MOVE.W	BRKEND(A2),D6	;Max break count before interupt
	CMP.W	D5,D6		;Any passes left?
	BEQ.S	$25		;No
	ADDQ.W	#1,D5		;Lower passes
	MOVE.W	D5,BRKCOUNT(A2) ;Set new break count
$25
	CMPI.W	#4E4FH,(A1)	;Is this a breakpoint instruction?
	BEQ.S	$27		;Yes, restore original instruction
	BCLR	D2,BMODE	;This breakpoint reg. is bogus - disable it
	BRA.S	$3
$27	MOVE.W	BRKCONT(A2),(A1) ;Restore original instuction

$3
	DBF	D2,$2
	BTST	#BK2,BMODE	;Is breakpoint 2 active?
	BEQ.S	$4		;No
	CMP.L	BRKPNT2,D4	;Did we hit it?
	BNE.S	$4		;No
	BCLR	#BK2,BMODE	;Disable it
	BCLR	#GSBRK,BMODE	;Terminate GS
	BNE.S	$4
	MOVE.L	D4,REGPC	;Fake continuation of tracing
	BSET	#TRACE,BMODE
	BCLR	#BRKPT,BMODE
	BRA	TRCTRAP
	
$4
	MOVE.L	REGPC,D0	;Get break point address
	SUB.L	D3,D0
	MOVE.L	D0,REGPC	;Set PC to breakpoint address
	CMP.W	D5,D6		;Breakcount set to interupt
	BNE	CMG2		;No restart command
	TST.W	D3		;Is this unexpected break?
	BNE	INTADDR		;No
	MOVEA.L D4,A4		;Recover instruction we broke on
	CMPI.W	#4E4FH,(A4)	;Was it a TRAP 15?
	BNE	INTADDR		;No, user must have typed BREAK key
	MOVE.L	D4,D0		;We broke on a TRAP 15 - display it
	BRA	INTADDR
	
                                                                                              