; 
;   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
;
	;MASM MODE
	.386
	.model use32 small

include  prints.ase 
include  mtrap.ase 
include  input.ase 

	PUBLIC	SetBreak, breaks, EnableBreaks, DisableBreaks, enableOneBreak
	extrn hdwebreakcommand : PROC, hdwebreakenable : PROC
	extrn hdwebreakdisable : PROC

	.data
breaklist dd 16 DUP (?)		; List of breakpoints
breakhold db 16 dup (?)		; List of values where 'int 3' has covered
				; the opcode
breakenum dw	0		; Flags telling which breakpoints are set
	
	.code
;
; Command to set a breakpoint comes here
;
SetBreak	PROC	
	and	eax,0fh		; Set the breakpoint set bit
	bts	[breakenum],ax	;
	mov	[eax*4+breaklist],ebx	;
	ret
SetBreak	ENDP	
;
; Command to clear a breakpoint comes here
;
clearbreak	PROC	
	and	ax,0fh		; Reset the flag bit
	btr	[breakenum],ax	;
	ret
clearbreak	ENDP	
;
; Command to display a breakpoint comes here
;
displaybreak	PROC	
	and	eax,0fh		; See if set
	bt	[breakenum],ax	;
	jnc	short nodisplay	; Quit with no disp if no breakpoint set
	push	eax		; CR/LF
	call	crlf
	pop	eax		;
	push	eax		;
	call	PrintByte	; Print breakpoint #
	mov	dl,':'		; Print ':'
	call	PutChar
	call	PrintSpace
	pop	ebx		;
	mov	eax,DWORD PTR [ebx*4+breaklist]	; Print segment
	call	PrintDword	;
nodisplay:
	ret
displaybreak	ENDP	
enableOneBreak PROC
	mov	esi,dword ptr [ecx*4 + breaklist]
	mov	al,[esi]	; Get the byte at that location
	mov	BYTE PTR [esi],0cch	; Put an int 3
	mov	[ecx + breakhold],al	; Save it for restore
	ret
enableOneBreak ENDP
;
; When GO or TRAP or PROCEED commands execute, they call this to
; enable breakpoints
;
EnableBreaks	PROC	
	mov	ecx,15		; For each breakpoint
eblp:
	bt	[breakenum],cx	; If not set
	jnc	short ebnn	; Don't do anything
	call	enableOneBreak;
ebnn:
	dec	ecx		; Next breakpoint
	jns	eblp		;
	mov	eax,ecx		;
	call	hdwebreakenable
	ret	
EnableBreaks	ENDP	
;
; Int 3 or int 1 call this to disable breakpoints and restore the
; values covered by the int 3
;
DisableBreaks	PROC	
	mov	ecx,15		; For each breakpoint
dblp:
	bt	[breakenum],cx	; If not set
	jnc	short dbnn	; Go nothing
	mov	al,[ecx + breakhold]
	
	mov	esi,[ecx*4 + breaklist]	;
	mov	[esi],al	;
dbnn:
	dec	ecx
	jns	dblp		; Next breakpoint
	btr	[breakenum],0   ; Reset breakpoint 0 (the automatic breakpoint)
	call	hdwebreakdisable
	ret
DisableBreaks	ENDP	
;
; Handle breakpoint-related commands
;
breaks	PROC	
	call	WadeSpace	; Wade through spaces
	jz	showall	; Show all breakpoints
	cmp	al,'d'
	jz	hdwebreakcommand
	cmp	al,'-'		; Else check for '-'
	pushfd			;
	jnz	noinc		;
	inc	esi		; Skip to next arg
	call	WadeSpace	;
noinc:
	cmp	al,'*'
	jz	clearall
	call    ReadNumber	; Read break number
	jc	badbreak2	; Exit if error
	cmp	eax,16		; Make sure in range
	jnc	badbreak2	; Exit if error
	or	eax,eax		; Can't do anything with break #0, it's automatic
	jz	badbreak2	;
	popfd			;
	push	eax		;
	jz	short unmake	; If was '-', clear break
	call	WadeSpace	; Else wade to next arg
	jz	badbreak2
	call	ReadAddress	; Read the bp address
	pop	eax		;
	jc	short badbreak	; Quit if error
	call	SetBreak	; Set breakpoint at this address
	jmp	short breakdone	; Get out
unmake:
	call	WadeSpace	; Wade to end
	pop	eax		;
	jnz	short badbreak	; If there is more we have an error
	call	clearbreak	; Clear breakpoint
	jmp	short breakdone	; Get out
clearall:
	popf
	jnz	short badbreak
	inc	esi
	call	WadeSpace
	jnz	short	badbreak
	mov	[breakenum],0
	jmp	breakdone
showall:
	test	[breakenum],0ffffh
	jnz	doshow
	Msg	<13,10,"No breakpoints enabled">
	clc
	ret

doshow:
	mov	ecx,15		; For each breakpoint
salp:
	mov	eax,ecx		; Display it if set
	call	displaybreak	;
	loop	salp		;
breakdone:
	clc			; Exit, no errors
	ret
badbreak2:
	pop	eax		;
badbreak:
	stc			; Exit, errors
	ret
breaks	ENDP	
END
