	page	78,132
	title	Trace and Register commands

	include	DOS.INC

BPMAX		=	10		;Maximum number of breakpoints

StepVect	equ	word ptr ds:[1*4]
BreakPtVect	equ	word ptr ds:[3*4]

	.model	small
	.code
	.data

DGroup	group	_TEXT,_DATA

	.data

	public	TCount

	extrn	AxSave:word,BxSave:word,SpSave:word
	extrn	CsSave:word,IpSave:word,FlSave:word,TestPSP:word

BRKCNT	dw	?			;Number of breakpoints
TCOUNT	dw	?			;Number of steps to trace
BPTAB	db	5*BpMax dup(?)		;Breakpoint table

	.code
	assume	cs:DGroup,ds:DGroup,es:DGroup,ss:DGroup

	public	Go,Reg,Trace,ReEnter

	extrn	CrLf:near, Blank:near, ScanP:near, GetEol:near, OutCh:near
	extrn	InBuf:near, ScanB:near, GetHex:near, GetHex1:near, Out16:near
	extrn	PrintAbort:near, HexIn:near, Address:near, Command:near
	extrn	ErrMes:byte, DisLine:near

;Flags are ordered to correspond with the bits of the flag
;register, most significant bit first, zero if bit is not
;a flag. First 16 entries are for bit set, second 16 for
;bit reset.

FLAGTAB	label	byte
	DW	0
	DW	0
	DW	0
	DW	0
	DB	"OV"
	DB	"DN"
	DB	"EI"
	DW	0
	DB	"NG"
	DB	"ZR"
	DW	0
	DB	"AC"
	DW	0
	DB	"PE"
	DW	0
	DB	"CY"
	DW	0
	DW	0
	DW	0
	DW	0
	DB	"NV"
	DB	"UP"
	DB	"DI"
	DW	0
	DB	"PL"
	DB	"NZ"
	DW	0
	DB	"NA"
	DW	0
	DB	"PO"
	DW	0
	DB	"NC"

REGTAB		DB	"AXBXCXDXSPBPSIDIDSESSSCSIPPC"
REGTABLEN	=	($-RegTab)/2	;Number of registers

;************************************************************
; "R" command
;Perform register dump if no parameters or set register if a
;register designation is a parameter.

DISPREG:
	MOV	SI,offset DGroup:REGTAB
	MOV	BX,offset DGroup:AXSave
	MOV	CX,8
	CALL	DISPREGLINE
	CALL	CRLF
	MOV	CX,5
	CALL	DISPREGLINE
	CALL	BLANK
	CALL	DISPFLAGS
	call	CrLf
	mov	si,[IpSave]
	mov	ds,[CsSave]
	call	DisLine			;Disassemble current line
	push	cs
	pop	ds
	ret

REG:
	CALL	SCANP
	JZ	DISPREG
	LODSW
	CMP	AH,13
	JZ	FLAG
	XCHG	DX,AX		;Get flag letters in DX
	CALL	GETEOL
	CMP	DH," "
	JZ	FLAG
	MOV	DI,offset DGroup:REGTAB
	XCHG	AX,DX
	PUSH	CS
	POP	ES
	MOV	CX,REGTABLEN
REPNZ	SCASW
	JNZ	BADREG
	OR	CX,CX
	JNZ	NOTPC
	DEC	DI
	DEC	DI
	MOV	AX,CS:[DI-2]
NOTPC:
	PUSH	DS
	POP	ES
	CALL	OutCh
	MOV	AL,AH
	CALL	OutCh
	CALL	BLANK
	sub	di,offset DGroup:RegTab
	LEA	BX,[DI+AxSave-2]
	MOV	DX,[BX]
	CALL	OUT16
	CALL	CRLF
	MOV	AL,":"
	CALL	OutCh
	CALL	INBUF
	CALL	SCANB
	JZ	RET4
	MOV	CX,4
	CALL	GETHEX1
	CALL	GETEOL
	MOV	[BX],DX
Ret4:	RET

BADREG:
	MOV	AX,"RB"		;BR ERROR
	JMP	ERR

FLAG:
	CMP	AL,"F"
	JNZ	BADREG
	CALL	DISPFLAGS
	MOV	AL,"-"
	CALL	OutCh
	CALL	INBUF
	CALL	SCANB
	XOR	BX,BX
	MOV	DX,[FlSave]
GETFLG:
	LODSW
	CMP	AL,13
	JZ	SAVCHG
	CMP	AH,13
	JZ	FLGERR
	MOV	DI,offset DGroup:FLAGTAB
	MOV	CX,32
	PUSH	CS
	POP	ES
REPNE	SCASW
	JNZ	FLGERR
	MOV	CH,CL
	AND	CL,0FH
	MOV	AX,1
	ROL	AX,CL
	TEST	AX,BX
	JNZ	REPFLG
	OR	BX,AX
	OR	DX,AX
	TEST	CH,16
	JNZ	NEXFLG
	XOR	DX,AX
NEXFLG:
	PUSH	DS
	POP	ES
	CALL	SCANP
	jmp	GETFLG

DISPREGLINE:
	lods	word ptr cs:[si]
	CALL	OutCh
	MOV	AL,AH
	CALL	OutCh
	MOV	AL,"="
	CALL	OutCh
	MOV	DX,[BX]
	INC	BX
	INC	BX
	CALL	OUT16
	CALL	BLANK
	CALL	BLANK
	LOOP	DISPREGLINE
	RET

REPFLG:
	MOV	AX,"FD"		;DF ERROR
FERR:
	CALL	SAVCHG
ERR:
	CALL	OutCh
	MOV	AL,AH
	CALL	OutCh
	MOV	SI,offset DGroup:ERRMES
	JMP	PrintAbort

SAVCHG:
	MOV	[FlSave],DX
	RET

FLGERR:
	MOV	AX,"FB"		;BF ERROR
	jmp	FERR

DISPFLAGS:
	MOV	SI,offset DGroup:FLAGTAB
	MOV	CX,16
	MOV	DX,[FlSave]
DFLAGS:
	lods	word ptr cs:[si]
	SHL	DX,1
	JC	FLAGSET
	MOV	AX,CS:[SI+30]
FLAGSET:
	OR	AX,AX
	JZ	NEXTFLG
	CALL	OutCh
	MOV	AL,AH
	CALL	OutCh
	CALL	BLANK
NEXTFLG:
	LOOP	DFLAGS
	RET


;************************************************************
; "T" command
;Trace 1 instruction or the number of instruction specified
;by the parameter using 8086 trace mode. Registers are all
;set according to values in save area

TRACE:
	CALL	SETADD
	CALL	SCANP
	CALL	HEXIN
	MOV	DX,1
	JC	STOCNT
	MOV	CX,4
	CALL	GETHEX
STOCNT:
	MOV	[TCOUNT],DX
	CALL	GETEOL
STEP:
	MOV	[BRKCNT],0
	OR	byte ptr [FlSave+1],1
EXIT:
	mov	bx,[TestPSP]		;If no child, our own PSP
	DOS	SetPSP			;Switch over to child PSP
	xor	ax,ax
	mov	ds,ax

assume	ds:nothing,ss:nothing,es:nothing

	MOV	BreakPtVect,offset DGroup:BREAKFIX	;Breakpoint interrupt
	MOV	BreakPtVect+2,CS
	MOV	StepVect,offset DGroup:REENTER	;Single step interrupt
	MOV	StepVect+2,CS
	cli
	MOV	SP,offset DGroup:AxSave
	POP	AX
	POP	BX
	POP	CX
	POP	DX
	POP	BP
	POP	BP
	POP	SI
	POP	DI
	POP	DS
	POP	ES
	POP	SS
	MOV	SP,[SPSave]
	PUSH	[FlSave]
	PUSH	[CSSave]
	PUSH	[IPSave]
	IRET

STEP1:	JMP	STEP

;Re-entry point from breakpoint. Need to decrement instruction
;pointer so it points to location where breakpoint actually
;occured.

BREAKFIX:
	PUSH	BP
	MOV	BP,SP
	DEC	word ptr [BP+2]
	POP	BP

;Re-entry point from trace mode or interrupt during
;execution. All registers are saved so they can be
;displayed or modified.

REENTER:
	PUSH	AX
	PUSH	BX
	MOV	AX,SS
	MOV	BX,SP		;Save stack pointer in AX,BX
	push	cs
	pop	ss
	mov	sp,offset DGroup:CsSave
	PUSH	AX		;Save SS
	PUSH	ES
	PUSH	DS
	PUSH	DI
	PUSH	SI
	PUSH	BP
	PUSH	BX		;Save SP
	PUSH	DX
	PUSH	CX
	PUSH	SS
	POP	DS

assume	ds:DGroup

	MOV	SS,AX		;Restore user stack pointer
	MOV	SP,BX
	POP	[BXSave]
	POP	[AXSave]
	POP	[IPSave]
	POP	[CSSave]
	POP	AX
	AND	AH,0FEH
	MOV	[FlSave],AX
	MOV	[SPSave],SP
	PUSH	DS
	POP	ES
	PUSH	DS
	POP	SS
	MOV	SP,offset DGroup:AxSave
	sti
	cld
	mov	bx,cs			;Change back to our PSP
	DOS	SetPSP
	MOV	SI,offset DGroup:BPTAB
	MOV	CX,[BRKCNT]
	JCXZ	SHOREG
CLEARBP:
	LODSW
	XCHG	DI,AX
	LODSW
	MOV	ES,AX		;ES:DI point to a breakpoint location
	MOVSB			;Restore original value
	LOOP	CLEARBP
	PUSH	DS
	POP	ES
SHOREG:
	CALL	DISPREG
	DEC	[TCOUNT]
	JNZ	STEP1
	JMP	COMMAND


;************************************************************
; "G" command
;Jump to program, setting up registers according to the
;save area. Up to 10 breakpoint addresses may be specified.

GO:
	CALL	SETADD
	MOV	DI,offset DGroup:BPTAB
	XOR	BX,BX
GO1:
	CALL	SCANP
	JZ	DoExec
	MOV	BP,[CSSave]
	CALL	ADDRESS
	XCHG	AX,DX
	STOSW			;Save offset of breakpoint
	XCHG	AX,DX
	STOSW
	INC	DI		;Save room for present value
	INC	BX
	CMP	BX,BPMAX+1
	JNZ	GO1
	MOV	AX,"PB"		;BP ERROR
	JMP	ERR

DoExec:
	MOV	[BRKCNT],BX
	CALL	GETEOL
	MOV	CX,BX
	JCXZ	NOBP
	MOV	DI,offset DGroup:BPTAB
SETBP:
	LDS	SI,[DI]
	ADD	DI,4
	MOVSB			;Copy present value
	MOV	byte ptr [SI-1],0CCH	;Set breakpoint
	PUSH	ES
	POP	DS
	LOOP	SETBP
NOBP:
	MOV	[TCOUNT],1
	JMP	EXIT

SETADD:
;Set GO address if specified
	CALL	SCANP
	CMP	AL,"="
	JNZ	RET5
	INC	SI
	MOV	BP,[CSSave]	;Default to CS
	CALL	ADDRESS
	MOV	[CSSave],AX
	MOV	[IPSave],DX
Ret5:	RET

end
