; ; GRDP ; ; Copyright(c) LADsoft ; ; David Lindauer, gclind01@starbase.spd.louisville.edu ; ; ; breaks.asm ; ; handle breakpoint setting, resetting, enabling, commands ; ;MASM MODE .model small .386 include prints.ase include mtrap.ase include input.ase PUBLIC setbreak, breaks, enableBreaks, disableBreaks .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 push bx or edx,edx ; Null segment defaults to CS jnz hasbreak ; mov dx,[drcs] ; hasbreak: and ax,0fh ; Set the breakpoint set bit bts [breakenum],ax ; shl ax,2 add ax,offset dgroup:breaklist xchg ax,bx mov [bx],ax ; mov [bx + 2],dx ; pop bx 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 ax,0fh ; See if set bt [breakenum],ax ; jnc short nodisplay ; Quit with no disp if no breakpoint set push ax ; CR/LF call crlf pop ax ; push ax ; call printbyte ; Print breakpoint # mov dl,':' ; Print ':' call PutChar call printspace pop bx ; shl bx,2 add bx,offset dgroup:breaklist mov ax,WORD PTR [bx + 2] ; Print segment call printword ; mov dl,':' ; Print ':' call PutChar mov ax,[bx] ; Print offset call printword ; nodisplay: ret displaybreak ENDP ; ; When GO or TRAP or PROCEED commands execute, they call this to ; enable breakpoints ; enableBreaks PROC mov cx,15 ; For each breakpoint eblp: bt [breakenum],cx ; If not set jnc short ebnn ; Don't do anything mov bx,cx shl bx,2 mov fs,WORD PTR [bx + breaklist + 2] mov si,word ptr [bx + breaklist] mov al,fs:[si] ; Get the byte at that location mov BYTE PTR fs:[si],0cch ; Put an int 3 mov bx,cx mov [bx + breakhold],al ; Save it for restore ebnn: dec cx ; Next breakpoint jns eblp ; mov eax,ecx ; 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 cx,15 ; For each breakpoint dblp: bt [breakenum],cx ; If not set jnc short dbnn ; Go nothing mov bx,cx mov al,[bx + breakhold] shl bx,2 mov si,word ptr [bx + breaklist] ; mov fs,WORD PTR [bx + breaklist + 2] ; mov fs:[si],al ; dbnn: dec cx jns dblp ; Next breakpoint btr [breakenum],0 ; Reset breakpoint 0 (the automatic breakpoint) ret disableBreaks ENDP ; ; Handle breakpoint-related commands ; breaks PROC call WadeSpace ; Wade through spaces jz short showall ; Show all breakpoints cmp al,'-' ; Else check for '-' pushf ; jnz noinc ; inc si ; Skip to next arg call WadeSpace ; noinc: cmp al,'*' jz clearall call ReadNumber ; Read break number jc short badbreak2 ; Exit if error cmp ax,16 ; Make sure in range jnc short badbreak2 ; Exit if error or ax,ax ; Can't do anything with break #0, it's automatic jz short badbreak2 ; popf ; push ax ; jz short unmake ; If was '-', clear break call WadeSpace ; Else wade to next arg jz badbreak2 call ReadAddress ; Read the bp address pop ax ; 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 ax ; 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 si 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 cx,15 ; For each breakpoint salp: mov ax,cx ; Display it if set call displaybreak ; loop salp ; breakdone: clc ; Exit, no errors ret badbreak2: pop ax ; badbreak: stc ; Exit, errors ret breaks ENDP END