	.386p
	;MASM MODE
	.model use32 small

include version.asi
include  prints.ase 
include  regs.ase 
include  input.ase 
include  breaks.ase 
include  exec.ase
include swift.ase
include fp.ase

	PUBLIC	reflags,dreax,drebx,drecx,dredx
	PUBLIC	dresi,dredi,drebp
	PUBLIC	dresp,dreip
	PUBLIC	monitor_init, rtoss, dres,drds,sysds, entry1, entry3, entry13
	extrn   hdwechk : PROC

	extrn _winxcept : word, ___clearxcept : PROC
	.data
;
; CPU instruction trap enable flag
;
TRAPFLAG = 100h
;
; Macro which sets things up to call the generic trap handler
;
TRAP	MACRO	num,error,clflag
	local	notrace, noswift
entry&num:
	call	___clearxcept
if num EQ 3
;	call	swiftrace
endif
if num EQ 1
	call	hdwechk
;	jc	noswift
;	call	swiftrace
noswift:
endif
	push	ds		; Switch to system data seg
	mov	ds,cs:[sysds]
	mov	[trapnum],num	; Save trapnu,
	ifnb	<error>		; If it has an error# on stack
	inc	[haserr]	; Set the error flag
	endif
	ifnb	<xclflag>	; If is int #1
	test	DWORD PTR [esp + 12], TRAPFLAG; See if trap is set in flags
	jz	short notrace	; No, not tracing
	or	[tracing],1	; Else set tracing flag
notrace:
	and	DWORD PTR [esp + 12], NOT TRAPFLAG ; Reset trap flag
	endif
	jmp	traphandler	; Jump to trap handler
	ENDM	

;
; List of all trap handlers
;
tsvects	dd	16		; Not allowing TRAP 16 because is video int
	dd	entry0,entry1,entry2,entry3,0,0
	dd	entry6,entry7,0,0,0,0
	dd	entry12,entry13,entry14,0,0
;
; Register image
;
reflags	dd	0
dreax	dd	0
drebx	dd	0
drecx	dd	0
dredx	dd	0
dresi	dd	0
dredi	dd	0
drebp	dd	0
dresp	dd	0
dreip	dd	0
drds	dw	0
dres	dw	0
rtoss	dd	0
sysds	dw	0
;
haserr	dw	0	; If there is an error# on stack
errnum	dw	0	; The error#
trapnum	dw	0	; The trap#
tracing	db	0	; True if tracing
	db	10,13,0

	.code
;
; Save an image of the regs
; This MUST BE the first thing the trap handler calls; it assumes
; there is ONE PUSH (return address) followed by the DS at the time
; of interrupt followed by the interrupt data
;
saveregs	PROC	
	mov	[dreax],eax	; Save GP regs
	mov	[drebx],ebx	;
	mov	[drecx],ecx	;
	mov	[dredx],edx	;
	mov	[dresi],esi	;
	mov	[dredi],edi	;
	mov	[drebp],ebp	;
	lea	ebp,[esp+4]	; Point BP at DS on stack
	mov	ebx,4		; Offset past DS on stack
	mov	eax,[ebp]
	mov	[drds],ax
	mov	[dres],es
	test	[_winxcept],1
	jnz	windowsxcept
	bt	[haserr],0	; See if an error
	jnc	short noerr	;
windowsxcept:
      	add	ebp,4		; Yes, point errno
	add	ebx,4		; Offset past errno
	mov	ax,[ebp]	; Get the error #
	mov	[errnum],ax	;
noerr:
	mov	eax,[ebp + 4]	; Get CS:eip
	mov	[dreip],eax	;
	mov	eax,[ebp + 12]	; Get flags
	mov	[reflags],eax	;
	add	ebx,12		; Offset past CS:eip & flags
	mov	eax,ebp		; things in the trap routine
	add	eax,16		;
	mov	[dresp],eax	;
	ret
saveregs	ENDP	
;
; Adjust EIP to the trap if it's not int 3
;
adjusteip	PROC	
	cmp	[trapnum],3	; See if int 3
	jnz	short noadj	; No, get out
	mov	esi,[dreip]	;
	cmp	BYTE PTR [esi-1],0cch ; See if is an INT 3
	jz	short noadj ; Get out if so
	cmp	word ptr [esi-2],03cdh ; long form
	jz	short noadj
	dec	[dreip]		; Else point at trap
noadj:
	ret
adjusteip	ENDP	
;
; Generic trap handler
;
traphandler	PROC	
	cld
	call	saveregs	; Save Regs
	push	ds
	pop	es
	add	esp,ebx		; Find usable top of stack
	mov	[rtoss],esp	;
	test	[tracing],1	; See if tracing
	jnz	istracing	;
	call	DisableBreaks	; Disable breakpoints if not
istracing:
	mov	[tracing],0	; Clear tracing flag
	and	[reflags],NOT 100h
	call	adjusteip	; Adjust the EIP to point to the breakpoint
	call	crlf
	cmp     [trapnum],3	; No stats if it is int 3
	jz	short nostats	;
	cmp	[trapnum],1	; Or int 1
	jz	short nostats	;
	Msg	<'Trap: '>
	mov	ax,[trapnum]	; Say which one
	call	PrintByte	;
	call	crlf
	btr	[haserr],0	; If has error 
	jnc	nostats		;
	Msg	<'Error: '>
	mov	ax,[errnum]	; Say which one
	call	PrintWord
	call	crlf
	cmp	[trapnum],1
	jnz	nostats
	test	[TrapCount],-1	; in case a number specified on T command
	jz	nostats
	dec	TrapCount
	jmp	ReTrap
nostats:
	mov	[TrapCount],0
	call	DisplayRegisters; Display registers
	jmp	InputHandler	; Go do input

traphandler	ENDP	
;
; Monitor init routine, point all traps to point to the monitor handler
;
monitor_init	PROC
	pushfd
	pop	[reflags]
	mov	[dreax],eax	; Save GP regs
	mov	[drebx],ebx	;
	mov	[drecx],ecx	;
	mov	[dredx],edx	;
	mov	[dresi],esi	;
	mov	[dredi],edi	;
	mov	[drebp],ebp	;
	pop	eax
	mov	[dreip],eax
	mov	[dresp],esp
	mov	[rtoss],esp
	mov	[sysds],ds
	mov	[drds],ds
	mov	[dres],es
	mov	ecx,[tsvects]		; Get the number of vectors
	mov	esi,offset DGROUP:tsvects + 4	; Get the offset to the vector handlers
	mov	edi,0			; Get the initial trap #
tilp:
	lodsd				; Read a trap handler
	or	eax,eax
	jz	noset
	push 	edi
	push 	ecx
	mov	edx,eax			;
	mov	ecx,cs			;
	mov	ebx,edi
	pushad
	mov	ax,203h			; try first as an except handler
	int 	31h
	popad
	jnc	mtok
overtake:
	mov	ax,205h			; if that fails (and it will in pmode307
	int 	31h			; try as an interrupt handler
mtok:
	pop	ecx
	pop	edi
noset:
	inc	edi			; Update trap#
	loop	tilp			; Loop till done
	Call	Message
	db	'Debug/386 Version '
	db	30h + VERID/10,'.',30h + VERID MOD 10
	db	' (DPMI) Copyright (c) 1997, LADsoft',13,10,0
	call	ReTrap			; get us to _main
	jmp	InputHandler
monitor_init	ENDP	
;
; Here are the individual trap handlers
;
TRAP	0
TRAP	1,,yes
TRAP	2
TRAP	3
TRAP	6
TRAP	7
TRAP	12,YES
TRAP	13,YES
TRAP	14,YES
 

END