	model	large,pascal
	locals	@@

Offs	equ	(word ptr 0)
Segm	equ	(word ptr 2)

acTraceInto	equ	0
acStepOver	equ	1
acRun		equ	2
acGoToCursor	equ	3

scNorm	equ	0
scRet	equ	1
scJmp	equ	2
scJcc	equ	3
scCall	equ	4
scInt	equ	5
scDS	equ	6
scES	equ	7
scBoth	equ	8
scInd	equ	80h

bpDS	equ	0
bpES	equ	1
bpBoth	equ	2
bpCall	equ	3
bpInt	equ	4
bpRet	equ	5
bpStop	equ	6
bpIJmp	equ	7
bpICall	equ	8

cbFirst		equ	1
cbAccepted	equ	2
cbSecond	equ	80h

Regs	struc
	rAX	dw	?
	rBX	dw	?
	rCX	dw	?
	rDX	dw	?
	rBP	dw	?
	rSI	dw	?
	rDI	dw	?
	rDS	dw	?
	rES	dw	?
	rCSIP	label	dword
	rIP	dw	?
	rCS	dw	?
	rFL	dw	?
	rSP	dw	?
	rSS	dw	?
	ends

DBpt	struc
	Adr	dd	?
	OldB	db	?
	Typ	db	?
	ends

	extrn	FindCode:far
	extrn	FindSrcLine:far
	extrn	FindUnit:far
	extrn	FindStubSeg:far
	extrn	ScreenSwap:far

	.data

	extrn	SaveInt1B:dword,SaveInt21:dword,SaveInt23:dword
	extrn	Rg:Regs

Work1		db	256 dup(0)
Work2		db	256 dup(0)
DebugPID	dw	0
SavedPID	dw	0
SavedInts	dd	256 dup(0)
OvrBptByte	dw	0
OvrBptPtr	dd	0
OvrBptFlag	dw	0
UserBptCnt	dw	0
UserBpts	dd	0
SrcLine		dd	0
LineBeg		dd	0
LineLen		dw	0
LineEnd		dw	0
		dw	0,0,0
FirstSet	dw	0
FinBptByte	dd	0
Dummy		dd	0
InitBP		dw	0
InitSSSP	dd	0
CurCS		dw	0
SavedStack	dd	0
		dd	0
PrevCSIP	dd	0

	.code

	db	'$*$*$*',0,10,0,1,'DEBUG',0

DSeg		dw	seg _Data

IntTable	equ	$
	irp	I,<01,03,09,10,13>
	dw	4*I&H
Old&I	dd	0
	dw	Int&I&_Entry
	endm

IntCount	dw	($-IntTable)/8
DOS1B		dd	0
DOS21		dd	0
ExpectInt	dw	0
DontTrace	dw	0
CBrkFlag	db	0
CBrkPressed	db	0
		dd	0,0

	public	Step
Step	proc	far UserBptCount:word,UserBptBuf:dword,Action:word
	uses	si,di
	cld
	mov	ax,DSeg
	mov	ds,ax
	mov	es,ax
	mov	InitSSSP.Segm,ss
	mov	InitSSSP.Offs,sp
	mov	InitBP,bp
	mov	ax,CurCS
	cmp	ax,-1
	jne	@@1
	mov	ax,Rg.rCS
@@1:	push	ax Rg.rIP ds
	lea	ax,Dummy
	push	ax
	call	FindSrcLine
	mov	SrcLine.Offs,ax
	mov	SrcLine.Segm,dx
	or	ax,dx
	jnz	@@3
	call	SetUserBpts
	mov	Action,acRun
@@2:	call	ScreenSwap
	jmp	@@6
@@3:	call	GetLineInfo
	call	SetUserBpts
@@4:	mov	ax,ds
	mov	es,ax
	lea	di,Work1
	mov	cx,256
	mov	ax,ds
	lea	bx,Work2
	mov	dx,256
	call	InitAnalyse
	cmp	Action,acRun
	je	@@2
	mov	ax,LineBeg.Offs
	add	ax,LineLen
	mov	LineEnd,ax
	les	bx,LineBeg
	mov	dx,CurCS
	mov	cx,LineLen
	mov	si,Rg.rIP
	mov	ax,Action
	call	Analyse
	jnc	@@5
StkOv:	mov	sp,InitSSSP.Offs
	mov	bp,InitBP
	xor	ax,ax
	mov	dx,-1
	jmp	DExit
@@5:	mov	di,LineEnd
	mov	es,CurCS
	mov	al,bpStop
	nop
	call	SetBpt
@@6:	cmp	FirstSet,0
	je	@@7
	les	di,LineBeg
	cmp	byte ptr es:[di],0cch
	je	@@7
	call	OneStep
	call	RemoveFinBpt
@@7:	mov	DontTrace,0
	mov	CBrkFlag,0
	mov	cs:Nested,0
	mov	ax,Rg.rIP
	mov	PrevCSIP.Offs,ax
	mov	ax,Rg.rCS
	mov	PrevCSIP.Segm,ax
	call	SwitchToDebug
	call	Glop
	call	SwitchToTurbo
	mov	ax,Rg.rIP
	mov	dx,Rg.rCS
	mov	cx,UserBptCount
	jcxz	@@10
	les	di,UserBptBuf
@@8:	cmp	es:[di].Typ,0
	je	@@9
	cmp	ax,es:[di].Adr.Offs
	jne	@@9
	push	es
	mov	es,es:[di].Adr.Segm
	mov	BptSeg,es
	call	GetRealSeg
	mov	bx,es
	pop	es
	jc	@@15
	cmp	dx,bx
	je	@@15
@@9:	add	di,size DBpt
	loop	@@8
@@10:	call	ProcessBpt
	jnc	@@13
	mov	cx,1
	mov	ax,Rg.rIP
	cmp	ax,PrevCSIP.Offs
	jne	@@11
	mov	ax,Rg.rCS
	cmp	ax,PrevCSIP.Segm
	jne	@@11
	mov	PrevCSIP.Offs,-1
	inc	Rg.rIP
	dec	cx
	cmp	Action,acRun
	je	@@14
@@11:	mov	PrevCSIP.Offs,-1
	push	cx
	push	Rg.rCSIP ds
	lea	ax,Dummy
	push	ax
	call	FindSrcLine
	pop	cx
	mov	bx,ax
	or	bx,dx
	jz	@@12
	push	cx
	mov	SrcLine.Offs,ax
	mov	SrcLine.Segm,dx
	call	GetLineInfo
	pop	cx
	mov	ax,LineBeg.Offs
	cmp	ax,Rg.rIP
	jne	@@12
	mov	ax,LineBeg.Segm
	cmp	ax,Rg.rCS
	je	@@18
@@12:	add	Rg.rIP,cx
	jmp	@@7
@@13:	jnz	@@16
@@14:	jmp	@@7
@@15:	push	BptSeg Rg.rIP ds
	lea	ax,Dummy
	push	ax
	call	FindSrcLine
@@16:	mov	SrcLine.Offs,ax
	mov	SrcLine.Segm,dx
	call	GetLineInfo
	mov	ax,LineBeg.Offs
	cmp	ax,Rg.rIP
	jne	@@17
	mov	ax,LineBeg.Segm
	cmp	ax,Rg.rCS
	je	@@18
@@17:	jmp	@@4
@@18:	call	RemoveUserBpts
	call	RemoveBpts
CBrkE:	mov	ax,SrcLine.Offs
	mov	dx,SrcLine.Segm
DExit:	ret

RemoveFinBpt	proc	near
	les	di,LineBeg
	mov	al,es:[di]
	mov	byte ptr es:[di],0cch
	les	di,FinBptByte
	stosb
	mov	FirstSet,0
	ret
RemoveFinBpt	endp

	include	debanalz.inc

	public	DoneDebug
DoneDebug	proc far
	push	bp
	mov	bp,sp
	push	si di
	mov	dx,Action
	cli
	mov	ss,InitSSSP.Segm
	mov	sp,InitSSSP.Offs
	sti
	mov	bp,InitBP
	mov	ds,DSeg
	push	dx
	call	RemoveHandlers
	call	SwapAllVectors
	call	RemoveUserBpts
	call	RemoveBpts
	xor	ax,ax
	pop	dx
	xor	dh,dh
	cmp	CBrkFlag,0
	je	@@1
	mov	dx,ax
	dec	ax
@@1:	jmp	DExit
DoneDebug	endp

	public	InitDebug
InitDebug	proc	far PID:word
	uses	si,di
	cld
	push	ds
	mov	ds,DSeg
	mov	ax,PID
	mov	ax,Rg.rDS
	mov	DebugPID,ax
	or	Rg.rFL,200h
	mov	es,ax
	mov	es,es:[16h]
	les	si,es:[2eh]
	mov	SavedStack.Offs,si
	mov	SavedStack.Segm,es
	mov	CurCS,-1
	mov	OvrBptFlag,0
	mov	es,DSeg
	xor	ax,ax
	mov	ds,ax
	xor	si,si
	lea	di,SavedInts
	mov	cx,256*2
	rep	movsw
	mov	ds,DSeg
	lea	si,SaveInt1B
	lea	di,SavedInts+1bh*4
	lodsw
	stosw
	mov	DOS1B.Offs,ax
	lodsw
	stosw
	mov	DOS1B.Segm,ax
	lea	si,SaveInt21
	lodsw
	mov	DOS21.Offs,ax
	lodsw
	mov	DOS21.Segm,ax
	lea	di,SavedInts+21h*4
	lea	ax,Int21_Entry
	stosw
	mov	ax,cs
	stosw
	lea	si,SaveInt23
	lea	di,SavedInts+23h*4
	movsw
	movsw
	movsw
	movsw
	pop	ds
	ret
InitDebug	endp

	public	OvrDebugHook
OvrDebugHook	proc	far
	test	CBrkFlag,80h
	jz	@@1
	ret
@@1:	push	ds
	mov	ds,DSeg
	mov	BptSeg,es
	mov	dx,es
	call	GetRealSeg
	or	ax,ax
	jz	@@7
	mov	cx,UserBptCnt
	jcxz	@@4
	push	ds
	lds	si,UserBpts
@@2:	cmp	dx,[si].Adr.Segm
	jne	@@3
	mov	di,[si].Adr.Offs
	mov	al,es:[di]
	mov	[si].OldB,al
	mov	byte ptr es:[di],0cch
@@3:	add	si,size DBpt
	loop	@@2
	pop	ds
@@4:	mov	cx,BptCount
	jcxz	@@7
	push	ds
	lds	si,BptBuf
@@5:	cmp	dx,[si].Adr.Segm
	jne	@@6
	mov	di,[si].Adr.Offs
	mov	al,es:[di]
	mov	[si].Oldb,al
	mov	byte ptr es:[di],0cch
@@6:	add	si,size DBpt
	loop	@@5
	pop	ds
@@7:	cmp	OvrBptFlag,0
	je	@@8
	mov	di,bx
	mov	bl,es:[di]
	xor	bh,bh
	mov	byte ptr es:[di],0cch
	mov	OvrBptPtr.Offs,di
	mov	OvrBptPtr.Segm,es
@@8:	mov	OvrBptByte,bx
	pop	ds
	ret
OvrDebugHook	endp

GetLineInfo	proc	near
	push	SrcLine ds
	lea	ax,LineBeg
	push	ax ds
	lea	ax,LineLen
	push	ax
	call	FindCode
	or	ax,ax
	jz	@@1
	mov	es,LineBeg.Segm
	mov	CurCS,es
	call	GetRealSeg
	jc	@@1
	mov	LineBeg.Segm,es
@@1:	or	ax,ax
	ret
GetLineInfo	endp

Finish		dd	0

SetUserBpts	proc	near
	mov	FirstSet,0
	mov	cx,UserBptCount
	mov	UserBptCnt,cx
	jcxz	@@2
	les	bx,UserBptBuf
	mov	UserBpts.Offs,bx
	mov	UserBpts.Segm,es
@@1:	push	cx
	push	bx es
	mov	ax,es:[bx].Adr.Offs
	mov	Finish.Offs,ax
	mov	ax,es:[bx].Adr.Segm
	mov	Finish.Segm,ax
	mov	ax,Finish.Offs
	cmp	ax,Rg.rIP
	jne	@@3
	push	es
	mov	es,Finish.Segm
	call	GetRealSeg
	mov	ax,es
	pop	es
	jc	@@3
	cmp	ax,Rg.rCS
	jne	@@3
	xor	al,al
	cmp	Action,acRun
	jne	@@6
	cmp	FirstSet,0
	jne	@@6
	pop	es bx
	push	bx es
	mov	FirstSet,1
	lea	ax,[bx].Oldb
	mov	FinBptByte.Offs,ax
	mov	FinBptByte.Segm,es
	les	di,Finish
	jmp	short @@5
@@2:	jmp	short @@7
@@3:	les	di,Finish
	push	es
	call	GetRealSeg
	jc	@@4
	mov	ah,es:[di]
	mov	byte ptr es:[di],0cch
@@4:	pop	es
@@5:	mov	al,1
	mov	dx,es
@@6:	pop	es bx
	mov	es:[bx].Typ,al
	mov	es:[bx].Oldb,ah
	pop	cx
	add	bx,size DBpt
	dec	cx
	jz	@@7
	jmp	@@1
@@7:	ret
SetUserBpts	endp

RemoveUserBpts	proc	near
	mov	cx,UserBptCount
	jcxz	@@3
	push	ds
	lds	si,UserBptBuf
@@1:	cmp	[si].Typ,0
	je	@@2
	mov	di,[si].Adr.Offs
	mov	es,[si].Adr.Segm
	call	GetRealSeg
	cmp	byte ptr es:[di],0cch
	jne	@@2
	mov	al,[si].Oldb
	mov	es:[di],al
@@2:	add	si,size DBpt
	loop	@@1
	pop	ds
@@3:	ret
RemoveUserBpts	endp

	include	debopcod.inc

	include	debemul.inc

Step	endp

	end
