; 
;   Copyright 1994-2003 Free Software Foundation, Inc.
;
;   This library is free software; you can redistribute it and/or
;   modify it under the terms of the GNU Lesser General Public
;   License as published by the Free Software Foundation; either
;   version 2.1 of the License, or (at your option) any later version.
;
;   This library is distributed in the hope that it will be useful,
;   but WITHOUT ANY WARRANTY; without even the implied warranty of
;   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
;   Lesser General Public License for more details.
;
;   You should have received a copy of the GNU Lesser General Public
;   License along with this library; if not, write to the Free Software
;   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 
;   USA
;
;   You may contact the author at:
;
;   mailto::camille@bluegrass.net
;
;   or by snail mail at:
;
;   David Lindauer
;   850 Washburn Ave Apt 99
;   Louisville, KY 40222
;
	.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
include asm.asi
include asm.ase

	PUBLIC	reflags,dreax,drebx,drecx,dredx
	PUBLIC	dresi,dredi,drebp
	PUBLIC	dresp,dreip
	PUBLIC	monitor_init, rtoss, dres,drds,sysds, entry1, entry3, entry13
	public  drcs, drss, drfs, drgs
	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, join
ifb <error>
        
cwentry&num:
        push    ds
        mov     ds,cs:[sysds]
        mov     [_winxcept], 0
        pop     ds
        jmp     join
endif
; 
entry&num:
	call	___clearxcept
join:
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
if num EQ 1
	mov	[tracing],1
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
drfs	dw	0
drgs	dw	0
drss	dw	0
drcs	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 [drss],ss
	mov [drcs],cs
	mov	[drds],ax
	mov	[dres],es
	mov [drfs],fs
	mov [drgs],gs
	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
;
;extrn adjusteip : PROC

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
	jz		dbreak	;
	test	[reflags], TRAPFLAG; See if trap is set in flags
	jnz	short istracing	; No, not tracing
dbreak:	
	call	DisableBreaks	; Disable breakpoints if not
istracing:
	mov	[tracing],0	; Clear tracing flag
	and	[reflags],NOT TRAPFLAG
	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
nostats:
    test    [slashcmd],-1
    jz      notslashcmd
    call    slashcont
notslashcmd:
	call	DisplayRegisters; Display registers
	cmp	[trapnum],1
	jnz	noretrap
	test	[TrapCount],-1	; in case a number specified on T command
	jz	noretrap
    call    ScanKey         ; if they pressed a key stop
    jnz     noreproceed
	dec	TrapCount
	jmp	ReTrap
noretrap:
    test    [proceedCount],-1
    jz      noreproceed
    call    ScanKey         ; if they pressed a key stop
    jnz     noreproceed
    dec     [proceedCount]
    jmp     proceedone
noreproceed:
    mov     [proceedCount],0
	mov	[TrapCount],0
	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
        ;
        ; support for causeway
        ;
        mov     ax,205h
        mov     ebx,3
        mov     edx,offset cwentry3
        mov     ecx,cs
        int     31h
        mov     ax,205h
        mov     ebx,0
        mov     edx,offset cwentry0
        mov     ecx,cs
        int     31h
	call	floatcheck
	Call	Message
	db	'Debug/386 Version '
	db	30h + VERID/10,'.',30h + VERID MOD 10
	db	' (DPMI) Copyright (c) 1997, 2006 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