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

CMS
	LEA	SCMS,A1		;Find command in table
	BRA	SRCHCMND

;SM [$X+]XXXXXX - Substitutes memory starting at arg 1

CMSM:
	BSR	CNVTADDR	;Decode first argument
	BNE	CMNDERRA	;Error in command
				;Error - # not legal for 1st arg
	BRA.S	$1
	
;Print memory

$05
	BSR	TERMBELL
$1
	MOVE.L	A1,D4		;Address
	MOVEA.L A2,A4		;Location counter index
	MOVE.L	D4,D5		;Last address
	ADDQ.L	#2,D5		;Print word
	BSR	DISPMEM
	BSR	TERMCOLN	;Print delimiter
	
;Edit memory
	
	LEA	CMNDLINE,A0	;Get new data
	MOVE.L	#CLINELEN,D2
	BSR	READLINE
	CLR.L	D1		;Set no period match
	MOVE.B	(A0),D0		;Any thing read
	BEQ.S	$5
	MOVE.L	#0FFFFH,D1	;Get data byte (max size: 0FFH)
	BSR	GETDATA
	BMI	$05		;Error: Illegal number
	BGT.S	$6		; Period = done
	MOVE.B	D0,1(A1)	;Store new data
	ASR.L	#8,D0		;Store new high byte
	MOVE.B	D0,(A1)
$5
	ADDQ.L	#2,A1		;Move to next address
$6
	CMPI.B	#PERIOD,D1	; Period = done
	BNE	$1		; Else no change
	RTS

;S$X - Substitute data in base register(s)

CMSB
	LEA	BASEADDR,A1	;Substitute base registers
	MOVE.W	#" $",D1
	MOVEQ	#MAXBASE,D2	;Set max base register
	MOVEQ	#1,D5		;Minimum alterable register
	BRA.S	CMSDDX

;SAX - Substiture data in A register(s)

CMSA
	LEA	REGA,A1	       ;Substitute A registers
	MOVE.W	#REGNA,D1
	BRA.S	CMSDD
	
;SDX - Substitutes data in D register(s)

CMSD
	LEA	REGD,A1		;Substitute D registers
	MOVE.W	#REGND,D1
CMSDD
	MOVEQ	#8,D2		;Maxmimum register
	CLR.L	D5		;Minimum register is 0
CMSDDX
	BSR	GETCHAR		;Get register to display (if any)
	BEQ.S	CMSAA		;No register - Alter all registers
	SUB.B	#ZERO,D0	;Convert to binary
	BMI	CMNDERRA	;Number to small
	CMP.B	D5,D0		;Register < min register?
	BMI	CMNDERRA	;Yes
	CMP.B	D2,D0		;> Max register
	BGE	CMNDERRA
	CLR.L	D2		;Set single register update flag
	BSR.S	SUBSREG
	RTS
	
;Display all registers of same type 

CMSAA
	MOVE.L	D5,D0		;Print all registers
$1
	BSR.S	SUBSREG		;Substitute register
	ADDQ.L	#1,D0		;Move to next register
	CMP.B	D2,D0		;Done
	BLT	$1		;Repeat until done
	RTS
	
;Substitute data in a given register

SUBSREG
	CLR.L	D3		;Enable print register number
SUBSREGC
	MOVE.L	D2,-(A7)	;Save last register
	MOVE.W	D1,D5		;Save output register type
	MOVE.L	D0,D4		;Save register offset
	MOVE.L	D0,D6		;Convert base reg to offset
	ASL.L	#2,D6
	TST.L	D2		;Printing just 1 register
	BNE.S	$05		;No - Must display before alteration
	BSR	SKIPSPAC	;Move to next nonspace
	TST.B	(A0)		;Any data characters on command line?
	BNE.S	$30		;Yes - assume new register value
	BRA.S	$05
$04
	BSR	TERMBELL	;Error
$05
	MOVE.W	D5,D1		;Output register type
	BSR	TERMCRLF
	BSR	DISPREGC
	BSR	TERMCOLN
	MOVEQ	#CLINELEN,D2	;Get new register value
	LEA	CMNDLINE,A0
	BSR	READLINE
	MOVE.B	(A0),D0		;Any data in buffer?
	BEQ.S	$2		;No - skip location
$30
	CLR.L	D1		;Get new value
	BSR	GETDATA
	BMI	$04		;Error - Retry
	BNE	$2
	ANDI.L	#0FFH,D6	;Assure size
	OR.L	D3,D3		;16 or 32 bits
	BPL.S	$17		;32 bits
	MOVE.W	D0,0(A1,D6)	;Store 16 bit result
	BRA.S	$2
$17
	MOVE.L	D0,0(A1,D6)	;Set new value
$2
	MOVE.W	D5,D1		;Restore output register type
	MOVE.B	D4,D0		;Restore register #
	MOVE.L	(A7)+,D2	;Restore ending register
	RTS
	
;SR - Substitute data in all registers

CMSR
	BSR	GETCHAR		;No more characters allowed
	BNE	CMNDERRA
	BSR	CMSA		;Substitute A registers
	BSR	CMSD		;Substitute D registers
	BSR.S	CMSPC		;Substitute Program Counter
	BSR.S	CMSUS		;Substitute User Stack
	BSR.S	CMSSR		;Substitute Status Register
	RTS
	
;SP - Substitute Program Counter

CMSPC
	LEA	REGPC,A1
	MOVE.W	#"PC",D1
	BRA	CMSREG
	
;SS - Substitute Program status register

CMSSR
	LEA	REGSR,A1
	MOVE.W	#"SR",D1
	MOVEQ	#-1,D3		;Set 16 bit register
	BRA	CMSREGA
	
;SU - Substitute User stack

CMSUS
	LEA	REGUS,A1
	MOVE.W	#"US",D1

;Substitute command register

CMSREG
	MOVEQ	#1,D3		;Disable display register number
CMSREGA
	CLR.L	D2		;Set single register update
	CLR.L	D0		;Only register 1 exist
	BSR	SUBSREGC	;Display register
	RTS
	
;SB - Substitute breakpoint registers

CMSBR
	MOVEQ	#-1,D6		;Assume multiple break points
PRCBRKPT
	MOVEQ	#MAXBRKP-1,D5	;Assume process all (user) registers
	CLR.L	D0		;Clear register
	BSR	GETCHAR		;Get register to alter (if any)
	BEQ.S	$02		;No chars - process all registers
	NEG.L	D6		;Set positive or zero
	SUB.B	#ZERO,D0	;Convert to binary
	BMI	CMNDERRA	;Too small - error
	CMP.B	#MAXBRKP-1,D0	;Greater than max user register
	BGT	CMNDERRA	;Too large - error
	MOVE.W	D0,D5		;Set stoping address
$02
	MOVE.W	D0,D3		;Substitute starting at highest BP
	BRA.S	$1
$05
	BSR	TERMBELL
$1
	MOVEA.W D3,A3		;Compute offset
	ADDA.L	A3,A3
	MOVEA.L A3,A4		;Compute count register offset
	ADDA.L	A3,A3
	TST.L	D6		;Request type?
	BMI.S	$15		;Mult register - read update line
	BEQ.S	$4		;Display only - print CR & continue
				;Single register - check for cmnd line update
	BSR	SKIPSPAC	;Search for more data on command line
	TST.B	(A0)		;Any data left on line
	BNE.S	$19		;Yes - process it
$15
	BSR.S	DISPBRK		;Display breakpoint address
	BSR	TERMCOLN
	MOVEQ	#CLINELEN,D2	;Get new value
	LEA	CMNDLINE,A0
	BSR	READLINE
	BSR	SKIPSPAC	;Any result
$19
	MOVE.B	(A0),D0		;Period entered
	BEQ.S	$3		;Empty line - skip update
	CMPI.B	#PERIOD,D0
	BNE.S	$2		;No
	BCLR	D3,BMODE	;Disable breakpoint register
	BRA.S	$3
$2
	BSR	CNVTADDR	;Get new address
	BMI	$05		;Error detected - retry
	BSR	SKIPSPAC	;Skip to next field
	MOVE.L	#0FFFFH,D2	;Max count 
	BSR	GETNUM		;Get prebreak count
	BMI	$05		;Error detected
	CLR.W	BRKCOUNT(A4)	;Clear break count
	MOVE.W	D0,BRKEND(A4)	;Set max pass
	BSET	D3,BMODE	;Enable breakpoint
	MOVE.L	A1,BRKPOINT(A3) ;Set new breakpoint value
$3
	ADDQ.W	#1,D3		;Move to next breakpoint
	CMP.W	D5,D3		;Completed last breakpt
	BLE	$1		;Repeat until done
	RTS
$4
	BSR.S	DISPBRK		;Display break point register
	BRA.S	$3		;Skip update

;Display breakpoint register

BRKNAME .ASCII	"Breakpoint "
	.BYTE	0
BRKINAC .ASCII	"Inactive"
	.WORD	0
DISPBRK
	BSR	TERMCRLF
	LEA	BRKNAME,A0	;Print "Breakpoint "
	BSR	TERMTEXT
	MOVE.B	D3,D0		;Print register number
	BSR	TERMDIGT
	BSR	TERMCOLN
	BTST	D3,BMODE	;Breakpoint reg in use?
	BNE.S	$1		;Yes
	LEA	BRKINAC,A0	;Print inactive
	BSR	TERMTEXT
	RTS
$1
	MOVE.L	BRKPOINT(A3),D0 ;Print break point address
	BSR	TERMHEXL
	BSR	TERMSPAC	;Skip space
	MOVEQ	#"(",D0		;Print (
	BSR	TERMCHAR
	MOVE.W	BRKEND(A4),D0	;Print max pass count
	BSR	TERMHEXW
	BSR	TERMCOMA	;Delineate them
	MOVE.W	BRKCOUNT(A4),D0 ;Print count of register
	BSR	TERMHEXW
	MOVEQ	#")",D0		;Print )
	BSR	TERMCHAR
	RTS

;ST - Substitute TRAP-tracing status

CMST
	MOVEQ	#0,D3		;First TRAP to set
	MOVEQ	#16.,D4		;Last TRAP (+1)
	TST.B	(A0)		;Any more characters?
	BEQ.S	$1		;No, set all TRAPs
	BSR	GETNUM		;Find out which TRAP to set
	BMI	CMNDERRA
	MOVE.B	D0,D3		;Make it the first and last to set
	MOVE.B	D0,D4
	BSR	SKIPSPAC	;Did user already specify setting?
	CMPI.B	#"T",D0
	BEQ.S	$4		;Set to Trace status
	CMPI.B	#"N",D0
	BEQ.S	$3		;Set to Notrace status
	
$1
	BSR	TERMCRLF	;Tell user how to set status
	LEA	STMSG,A0
	BSR	TERMTEXT
	
$2
	MOVE.B	D3,D0		;Display current TRAP-tracing status
	BSR	DISPTRAP
	BSR	TERMCOLN	;Prompt for new status
	MOVEQ	#CLINELEN,D2	;Read new status
	LEA	CMNDLINE,A0
	BSR	READLINE
	BSR	SKIPSPAC
	BEQ.S	$6		;No new status, go to next TRAP
	CMPI.B	#"T",D0
	BEQ.S	$4		;Set Trace status
	CMPI.B	#"N",D0
	BEQ.S	$3		;Set Notrace status
	BSR	TERMBELL	;Illegal status, try again
	BRA	$1
	
$3	MOVE.W	TTARRAY,D1	;Set Notrace status
	BCLR	D3,D1
	BRA.S	$5
	
$4	MOVE.W	TTARRAY,D1	;Set Trace status
	BSET	D3,D1
	
$5	MOVE.W	D1,TTARRAY

$6
	ADDQ.B	#1,D3		;Advance to next TRAP
	CMP.B	D4,D3		;Done yet?
	BLT	$2
	RTS
	
STMSG
	.ASCII	"(T)race or (N)o trace"
	.BYTE	0
	.ALIGN	2

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        