	.data

	extrn	CBrkTrace:byte

SavedSP	dd	0
SavedBP	dw	0

	.code

OneStep	proc	near
	call	SetInt1
	call	DoOneStep
	call	ResetInt1
	ret
OneStep	endp

DoOneStep	proc	near
	les	di,Rg.rCSIP
	mov	al,es:[di]
	cmp	al,0cch
	je	@@2
	cmp	al,0cfh
	je	@@3
	cmp	al,9ch
	je	@@4
	cmp	al,9dh
	je	@@5
	cmp	al,0cdh
	je	@@1
	or	Rg.rFL,100h
	push	ExpectInt
	mov	ExpectInt,1
	call	Glop
	pop	ExpectInt
	inc	Rg.rIP
	jmp	@@8
@@1:	jmp	short @@6
@@2:	inc	Rg.rIP
	ret
@@3:	mov	es,Rg.rSS
	mov	bx,Rg.rSP
	mov	ax,es:[bx]
	mov	cx,es:[bx+2]
	mov	dx,es:[bx+4]
	mov	Rg.rIP,ax
	mov	Rg.rCS,cx
	mov	Rg.rFL,dx
	add	Rg.rSP,6
	jmp	short @@8
@@4:	sub	Rg.rSP,2
	mov	bx,Rg.rSP
	mov	es,Rg.rSS
	mov	ax,Rg.rFL
	mov	es:[bx],ax
	inc	Rg.rIP
	ret
@@5:	mov	bx,Rg.rSP
	mov	es,Rg.rSS
	mov	ax,es:[bx]
	and	ax,not 100h
	mov	Rg.rFL,ax
	add	Rg.rSP,2
	inc	Rg.rIP
	ret
@@6:	mov	bl,es:[di+1]
	xor	bh,bh
	shl	bx,1
	shl	bx,1
	add	Rg.rIP,2
	sub	Rg.rSP,6
	mov	di,Rg.rSP
	mov	es,Rg.rSS
	mov	ax,Rg.rIP
	stosw
	mov	ax,Rg.rCS
	stosw
	mov	ax,Rg.rFL
	stosw
	push	ds
	add	bx,offset SavedInts
	test	CBrkFlag,cbSecond
	jz	@@7
	xor	ax,ax
	mov	ds,ax
	sub	bx,offset SavedInts
@@7:	mov	ax,[bx]
	mov	dx,[bx+2]
	pop	ds
	mov	Rg.rIP,ax
	mov	Rg.rCS,dx
@@8:	les	di,Rg.rCSIP
	cmp	word ptr es:[0],3fcdh
	je	@@9
	push	es
	call	FindStubSeg
	mov	BptSeg,ax
	ret
@@9:	test	CBrkFlag,cbSecond
	jnz	@@11
	cmp	word ptr es:[di],3fcdh
	je	@@10
	cmp	byte ptr es:[di],0eah
	jne	@@11
	mov	BptSeg,es
	les	ax,es:[di+1]
	mov	Rg.rIP,ax
	mov	Rg.rCS,es
	ret
@@10:	call	ResetInt1
	call	SwitchToDebug
	call	Glop
	call	SwitchToTurbo
	call	SetInt1
	cmp	OvrBptByte,-1
	je	@@11
	les	di,OvrBptPtr
	cmp	byte ptr es:[di],0cch
	jne	@@11
	mov	al,byte ptr OvrBptByte
	stosb
@@11:	ret
DoOneStep	endp

SwitchToDebug	proc	near
	mov	ah,51h
	int	21h
	mov	SavedPID,bx
	mov	es,bx
	mov	ax,SavedStack.Offs
	mov	es:[2eh].Offs,ax
	mov	ax,SavedStack.Segm
	mov	es:[2eh].Segm,ax
	mov	bx,DebugPid
	mov	ah,50h
	int	21h
	cli
	call	SwapAllVectors
	call	SetHandlers
	mov	ExpectInt,3
	ret
SwitchToDebug	endp

SwitchToTurbo	proc	near
	call	RemoveHandlers
	call	SwapAllVectors
	mov	ExpectInt,0
	sti
	mov	ah,51h
	int	21h
	mov	DebugPid,bx
	mov	bx,SavedPID
	mov	ah,50h
	int	21h
	ret
SwitchToTurbo	endp

SwapAllVectors	proc	near
	xor	ax,ax
	mov	bx,sp
	sub	sp,256*4+1
	and	sp,0fffeh
	mov	ds,ax
	mov	si,ax
	push	ss
	pop	es
	mov	di,sp
	mov	cx,256*2
	rep	movsw
	nop
	mov	ds,DSeg
	lea	si,SavedInts
	mov	es,ax
	mov	di,ax
	mov	cx,256*2
	rep	movsw
	mov	si,sp
	push	ss
	pop	ds
	lea	di,SavedInts
	mov	es,DSeg
	mov	cx,256*2
	rep	movsw
	mov	ds,DSeg
	mov	es,DSeg
	mov	sp,bx
	ret
SwapAllVectors	endp

SetHandlers	proc	near
	push	ds
	push	cs
	pop	ds
	xor	ax,ax
	mov	es,ax
	lea	si,IntTable
	mov	cx,IntCount
@@1:	lodsw
	mov	di,ax
	mov	ax,es:[di]
	mov	[si],ax
	mov	ax,es:[di+2]
	mov	[si+2],ax
	add	si,4
	movsw
	mov	ax,cs
	stosw
	loop	@@1
	pop	ds
	ret
SetHandlers	endp

RemoveHandlers	proc	near
	mov	bx,DebugPid
	push	ds
	mov	dx,cs
	mov	ds,dx
	xor	ax,ax
	mov	es,ax
	lea	si,IntTable
	mov	cx,IntCount
@@1:	lodsw
	mov	di,ax
	cmp	dx,es:[di+2]
	jne	@@3
	mov	ax,[si+4]
	cmp	ax,es:[di]
	jne	@@3
@@2:	movsw
	movsw
	inc	si
	inc	si
	loop	@@1
	pop	ds
	ret
@@3:	cmp	es:[di+2],bx
	jb	@@2
	mov	ds,dx
	add	si,6
	loop	@@1
	pop	ds
	ret
RemoveHandlers	endp

Glop	proc	near
	mov	SavedSP.Offs,sp
	mov	SavedSP.Segm,ss
	mov	SavedBP,bp
	lea	bx,Rg
	mov	ax,[bx].rAX
	mov	cx,[bx].rCX
	mov	dx,[bx].rDX
	mov	si,[bx].rSI
	mov	di,[bx].rDI
	mov	bp,[bx].rBP
	mov	es,[bx].rES
	cli
	mov	ss,[bx].rSS
	mov	sp,[bx].rSP
	push	[bx].rFL
	push	[bx].rCSIP
	mov	bx,[bx].rBX
	mov	ds,Rg.rDS
	iret

Int01_Entry	proc	far
	cmp	ExpectInt,1
	je	@Int
	iret
Int01_Entry	endp

Int03_Entry	proc	far
	cmp	ExpectInt,3
	je	@Int
	iret
Int03_Entry	endp

@Int:	push	ds
	push	bx
	mov	ds,DSeg
	lea	bx,Rg
	mov	[bx].rAX,ax
	pop	[bx].rBX
	mov	[bx].rCX,cx
	mov	[bx].rDX,dx
	mov	[bx].rSI,si
	mov	[bx].rDI,di
	mov	[bx].rBP,bp
	pop	[bx].rDS
	mov	[bx].rES,es
	pop	[bx].rCSIP
	pop	[bx].rFL
	mov	[bx].rSS,ss
	mov	[bx].rSP,sp
	cli
	mov	ss,SavedSP.Segm
	mov	sp,SavedSP.Offs
	sti
	mov	bp,SavedBP
	and	[bx].rFL,not 100h
	dec	Rg.rIP
	cld
	ret

	db	'TDI9'

Int09_Entry	proc	far
	push	ds di
	xor	di,di
	mov	ds,di
	mov	di,6ch
	push	[di].Offs
	push	[di].Segm
	cli
	mov	[di].Offs,offset Int1B_Entry
	mov	[di].Segm,cs
	pushf
	call	Old09
	cli
	pop	[di].Segm
	pop	[di].Offs
	cmp	CBrkPressed,0
	je	@@1
	and	byte ptr ds:[471h],7fh
	mov	CBrkPressed,0
	push	ax bx si
	xor	ah,ah
	int	16h
	pop	si bx ax
@@1:	pop	di ds
	test	CBrkFlag,cbFirst
	jnz	Break
@Iret:	iret
Int09_Entry	endp

Int1B_Entry	proc	far
	or	CBrkFlag,1
	test	CBrkFlag,82h
	jnz	@@1
	mov	CBrkPressed,1
	push	ds
	mov	ds,DSeg
	mov	SrcLine.Offs,1
	mov	SrcLine.Segm,0
	pop	ds
	iret
@@1:	or	CBrkFlag,80h
	jmp	Dos1B
Int1B_Entry	endp

Break:	or	CBrkFlag,cbAccepted
	cmp	DontTrace,0
	jne	@Iret
	push	ds bx
	test	CBrkFlag,80h
	jnz	@@1
	mov	bx,seg _Data
	mov	ds,bx
	cmp	CBrkTrace,0
	je	@@1
	mov	CBrkFlag,cbAccepted+cbSecond
	pop	bx ds
	jmp	@Iret
@@1:	mov	ds,DSeg
	lea	bx,Rg
	mov	[bx].rAX,ax
	pop	[bx].rBX
	mov	[bx].rCX,cx
	mov	[bx].rDX,dx
	mov	[bx].rSI,si
	mov	[bx].rDI,di
	mov	[bx].rBP,bp
	pop	[bx].rDS
	mov	[bx].rES,es
	pop	[bx].rCSIP
	pop	[bx].rFL
	mov	[bx].rSS,ss
	mov	[bx].rSP,sp
	cli
	mov	ss,InitSSSP.Segm
	mov	sp,InitSSSP.Offs
	sti
	mov	bp,InitBP
	test	CBrkFlag,cbSecond
	jnz	@@6
	mov	CBrkFlag,cbAccepted+cbSecond
	sti
	call	RemoveUserBpts
	call	DisableBpts
	mov	SrcLine.Offs,1
	mov	SrcLine.Segm,0
@@2:	push	Rg.rCS
	call	FindStubSeg
	mov	CurCS,ax
	push	ax
	call	FindUnit
	or	ax,ax
	jnz	@@4
	mov	ax,Rg.rCS
@@3:	push	ax
	call	SmartStep
	pop	ax
	jnz	@@6
	cmp	ax,Rg.rCS
	je	@@3
	jmp	@@2
@@4:	push	CurCS Rg.rIP ds
	lea	ax,Dummy
	push	ax
	call	FindSrcLine
	mov	bx,ax
	or	bx,dx
	jnz	@@7
@@5:	mov	ax,Rg.rCS
	push	ax
	call	SmartStep
	pop	ax
	jnz	@@6
	cmp	ax,Rg.rCS
	je	@@4
	jmp	@@2
@@6:	neg	SrcLine.Segm
	mov	CBrkFlag,0
	jmp	short @@8
@@7:	mov	SrcLine.Offs,ax
	mov	SrcLine.Segm,dx
	call	GetLineInfo
	mov	ax,LineBeg.Offs
	cmp	ax,Rg.rIP
	jne	@@5
	mov	ax,LineBeg.Segm
	cmp	ax,Rg.rCS
	jne	@@5
@@8:	mov	ah,51h
	int	21h
	mov	DebugPid,bx
	mov	bx,SavedPID
	mov	ah,50h
	int	21h
	call	RemoveHandlers
	call	SwapAllVectors
	sti
	neg	SrcLine.Offs
	jmp	CBrkE

SmartStep	proc	near
	mov	di,Rg.rIP
	mov	es,Rg.rCS
	cmp	word ptr es:[di],21cdh
	je	@@3
	cmp	word ptr es:[di],13cdh
	je	@@3
	cmp	word ptr es:[di],10cdh
	je	@@3
	push	ExpectInt
	mov	ExpectInt,1
	call	DoOneStep
	pop	ExpectInt
	cmp	Rg.rIP,offset Int09_Entry
	je	@@2
@@1:	test	CBrkFlag,1
	ret
@@2:	mov	bx,cs
	cmp	bx,Rg.rCS
	jne	@@1
	push	ExpectInt
	mov	ExpectInt,1
	call	Glop
	pop	ExpectInt
	jmp	@@1
@@3:	mov	DontTrace,1
	inc	di
	inc	di
	mov	al,es:[di]
	mov	byte ptr es:[di],0cch
	push	ax
@@4:	push	es di ExpectInt
	mov	ExpectInt,3
	call	Glop
	pop	ExpectInt di es
	mov	dx,es
	cmp	dx,Rg.rCS
	jne	@@4
	cmp	di,Rg.rIP
	jne	@@4
	pop	ax
	mov	es:[di],al
	mov	DontTrace,0
	test	CBrkFlag,1
	ret
SmartStep	endp

Int13_Entry	proc	far
	inc	DontTrace
	pushf
	call	Old13
	jmp	short @Check
Int13_Entry	endp

Int10_Entry	proc	far
	inc	DontTrace
	pushf
	call	Old10
	jmp	short @Check
Int10_Entry	endp

Nested	db	0

Int21_Entry	proc	far
	cmp	Nested,0
	jne	@@1
	inc	DontTrace
	cmp	ah,4bh
	je	@@2
	clc
	pushf
	call	Dos21
@Check:	push	bp
	mov	bp,sp
	push	ax
	lahf
	mov	[bp+6],ah
	pop	ax bp
	dec	DontTrace
	test	CBrkFlag,cbFirst
	jnz	@Break
	iret
@@1:	jmp	Dos21
@@2:	inc	Nested
	pushf
	call	Dos21
	pushf
	dec	Nested
	popf
	jmp	@Check
@Break:	jmp	Break
Int21_Entry	endp

Glop	endp

SetInt1	proc	near
	mov	si,1*4
	lea	di,Old01
	lea	ax,Int01_Entry
	push	ds
	xor	bx,bx
	mov	ds,bx
	push	cs
	pop	es
	movsw
	movsw
	pop	ds
	mov	es,bx
	lea	di,[si-4]
	cli
	stosw
	mov	ax,cs
	stosw
	sti
	push	ds
	pop	es
	ret
SetInt1	endp

ResetInt1	proc	near
	mov	di,1*4
	lea	si,Old01
	lea	ax,Int01_Entry
	push	ds
	xor	bx,bx
	mov	es,bx
	cmp	ax,es:[di]
	jne	@@1
	push	cs
	pop	ds
	cli
	movsw
	movsw
	sti
@@1:	pop	ds
	push	ds
	pop	es
	ret
ResetInt1	endp
