mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1007 lines
25 KiB
1007 lines
25 KiB
PAGE ,132
|
|
TITLE DXBUG.ASM -- Dos Extender Debug Services
|
|
|
|
; Copyright (c) Microsoft Corporation 1989-1991. All Rights Reserved.
|
|
|
|
;****************************************************************
|
|
;* *
|
|
;* DXBUG.ASM - Dos Extender Debug Services *
|
|
;* *
|
|
;****************************************************************
|
|
;* *
|
|
;* Module Description: *
|
|
;* *
|
|
;* This module contains protect mode debug services for the *
|
|
;* DOS extender. *
|
|
;* *
|
|
;****************************************************************
|
|
;* Revision History: *
|
|
;* *
|
|
;* 11/17/89 Jimmat Added TraceBug stuff for debugging on *
|
|
;* 286 machines. *
|
|
;* 03/09/89 JimMat Initial version. *
|
|
;* *
|
|
;****************************************************************
|
|
|
|
.286p
|
|
.287
|
|
|
|
ifndef DEBUG
|
|
DEBUG = 0
|
|
endif
|
|
|
|
|
|
; -------------------------------------------------------
|
|
; INCLUDE FILE DEFINITIONS
|
|
; -------------------------------------------------------
|
|
|
|
include segdefs.inc
|
|
include gendefs.inc
|
|
include pmdefs.inc
|
|
|
|
if DEBUG ;********** ENTIRE FILE IS DEBUG CODE ***********
|
|
; -------------------------------------------------------
|
|
; GENERAL SYMBOL DEFINITIONS
|
|
; -------------------------------------------------------
|
|
|
|
Debug_Serv_Int equ 41h ;WDEB386 service codes
|
|
DS_Out_Char equ 0
|
|
DS_Out_Symbol equ 0fh
|
|
|
|
|
|
; -------------------------------------------------------
|
|
; DATA SEGMENT DEFINITIONS
|
|
; -------------------------------------------------------
|
|
|
|
DXDATA segment
|
|
|
|
extrn fDebug:BYTE
|
|
extrn fTraceBug:WORD
|
|
extrn idCpuType:WORD
|
|
|
|
DXDATA ends
|
|
|
|
; -------------------------------------------------------
|
|
page
|
|
|
|
DXCODE segment
|
|
assume cs:DXCODE
|
|
|
|
; -------------------------------------------------------
|
|
; PMDebugInt -- Process (display) the pMode debugger interrupt calls
|
|
;
|
|
|
|
public PMDebugInt
|
|
assume ds:NOTHING,es:NOTHING,ss:NOTHING
|
|
|
|
PMDebugInt proc near
|
|
|
|
cmp al,4Fh ;debugger installation check?
|
|
jnz notInsChk
|
|
mov ax,0F386h ;say we're here...
|
|
jmp DebugIntExit
|
|
|
|
notInsChk:
|
|
cmp al,50h ;load segment call?
|
|
jnz notLoadSeg
|
|
|
|
push ax
|
|
mov ax,es
|
|
Trace_Out "Int 41h Load code ->@AX:DI<- ",x
|
|
pop ax
|
|
test si,1
|
|
jz LoadCode
|
|
Trace_Out "data ",x
|
|
jmp short @f
|
|
LoadCode:
|
|
Trace_Out "code ",x
|
|
@@:
|
|
Trace_Out "seg #BX sel #CX inst #DX"
|
|
jmp short DebugIntExit
|
|
notLoadSeg:
|
|
|
|
DebugIntExit:
|
|
|
|
iret
|
|
|
|
PMDebugInt endp
|
|
|
|
|
|
; -------------------------------------------------------
|
|
; DXTestDebugIns -- Returns with Z flag set if running
|
|
; under the debugger, NZ means not
|
|
; under debugger.
|
|
;
|
|
; Input: none
|
|
; Output: Z - no debugger, NZ - under debugger
|
|
; Uses: Flags
|
|
|
|
public DXTestDebugIns
|
|
|
|
DXTestDebugIns proc far
|
|
assume ds:NOTHING,es:NOTHING,ss:NOTHING
|
|
|
|
push ds
|
|
|
|
push SEL_DXDATA ;address our data seg
|
|
pop ds
|
|
assume ds:DGROUP
|
|
|
|
cmp fDebug,0
|
|
|
|
pop ds
|
|
ret
|
|
|
|
DXTestDebugIns endp
|
|
|
|
DXCODE ends
|
|
|
|
|
|
;******************************************************************************
|
|
;
|
|
; DXOutputDebugStr
|
|
;
|
|
; Basically stolen from Windows/386 code by Ralph Lipe -- hacked up for
|
|
; 286 instead of 386. Here in RalphL's own words is the description:
|
|
;
|
|
; DESCRIPTION:
|
|
; The following code is not pretty but it does what it needs to. It will
|
|
; only be included in DEBUG versions of Win386. It accepts an ASCIIZ
|
|
; string which it will output to the COM1 serial port. If the string
|
|
; contains #(Register) (for example #AX) then the value of that register
|
|
; will be output. It will not work for segment registers.
|
|
;
|
|
; If the string contains ?(Register)[:(Register)] (for example ?AX or
|
|
; ?AX:BX) then the value of the register(s) is passed to the debugger
|
|
; to display the label nearest to the given address. (It, also, will
|
|
; not work with segment registers. If ?AX is given, then the segment is
|
|
; assumed to be the DX code segment.
|
|
;
|
|
; ENTRY:
|
|
; DS:SI -> ASCIIZ string
|
|
;
|
|
; EXIT:
|
|
; All registers and flags trashed
|
|
;
|
|
; ASSUMES:
|
|
; This procedure was called by the Trace_Out macro. It assumes that
|
|
; the stack is a pushad followed by a FAR call to this procedure.
|
|
;
|
|
;------------------------------------------------------------------------------
|
|
|
|
DXDATA segment
|
|
|
|
Reg_Offset_Table LABEL WORD ; Order of PUSHA
|
|
dw "DI"
|
|
dw "SI"
|
|
dw "BP"
|
|
dw "SP"
|
|
dw "BX"
|
|
dw "DX"
|
|
dw "CX"
|
|
dw "AX"
|
|
|
|
DXDATA ends
|
|
|
|
DXCODE segment
|
|
assume cs:DXCODE
|
|
|
|
public DXOutDebugStr
|
|
|
|
DXOutDebugStr proc far
|
|
|
|
push bp
|
|
mov bp, sp ; Assumes BP+6 = Pusha
|
|
pushf
|
|
push es
|
|
|
|
push SEL_DXDATA ; Address our own data seg
|
|
pop es
|
|
assume ds:NOTHING,es:DGROUP
|
|
|
|
cld
|
|
cli
|
|
|
|
OSC1_Loop:
|
|
lodsb ; Get the next character
|
|
test al, al ; Q: End of string?
|
|
jz short OSC1_Done ; Y: Return
|
|
cmp al, "#" ; N: Q: Special register out?
|
|
je SHORT OSC1_Hex ; Y: Find out which one
|
|
cmp al, "?" ; Q: special lable out?
|
|
je short OSC1_Label ; Y: find out which one
|
|
cmp al, "@" ; Q: special string out?
|
|
je short OSC1_Str
|
|
OSC1_out:
|
|
xor ah, ah ; N: Send char to COM
|
|
call Out_Debug_Chr
|
|
jmp OSC1_Loop ; Loop until done
|
|
|
|
OSC1_Hex:
|
|
call Get_Register
|
|
jnc short OSC1_not_special
|
|
|
|
cmp bl, 2 ; Q: Word output?
|
|
jb SHORT OSC1_Out_Byte ; N: display byte
|
|
OSC1_Out_Word:
|
|
call Out_Hex_Word ; Display AX in hex
|
|
jmp OSC1_Loop ; Output next char
|
|
|
|
OSC1_Out_Byte:
|
|
xchg al, ah ; swap bytes to print just
|
|
call Out_Hex_Byte ; the low one!
|
|
jmp OSC1_Loop ; Output next char
|
|
|
|
OSC1_Label:
|
|
call Get_Register
|
|
jc short show_label
|
|
OSC1_not_special:
|
|
lodsb ; Get special char again
|
|
jmp OSC1_out ; display it, and continue
|
|
|
|
show_label:
|
|
mov cx, ax ; save first value
|
|
cmp byte ptr [si], ':' ;Q: selector separator?
|
|
jne short flat_offset ; N:
|
|
lodsb ; Y: eat the ':'
|
|
call Get_Register ; and attempt to get the selector
|
|
jc short sel_offset
|
|
flat_offset:
|
|
mov ax, cs ; default selector value
|
|
sel_offset:
|
|
call Show_Near_Label
|
|
jmp OSC1_Loop
|
|
|
|
OSC1_Str:
|
|
call Get_Register
|
|
jnc short OSC1_not_special
|
|
mov cx,ax
|
|
cmp byte ptr [si],':'
|
|
jne short no_selector
|
|
lodsb
|
|
push cx
|
|
call Get_Register
|
|
pop cx
|
|
xchg ax,cx
|
|
jc short got_sel_off
|
|
mov cx,ax
|
|
no_selector:
|
|
mov ax,ds ; default selector for strings
|
|
got_sel_off:
|
|
call Show_String
|
|
jmp OSC1_Loop
|
|
|
|
OSC1_Done: ; The end
|
|
|
|
pop es
|
|
npopf
|
|
pop bp
|
|
ret 10h
|
|
|
|
DXOutDebugStr endp
|
|
|
|
|
|
;******************************************************************************
|
|
;
|
|
; Get_Register
|
|
;
|
|
; DESCRIPTION:
|
|
;
|
|
; ENTRY:
|
|
;
|
|
; EXIT: Carry set if register value found
|
|
; AX = register value
|
|
; BL = value size (1, 2, 4)
|
|
;
|
|
; USES:
|
|
;
|
|
;==============================================================================
|
|
|
|
|
|
Get_Register proc near
|
|
|
|
push si ; Save string pointer
|
|
xor ax, ax ; Zero AX
|
|
mov bl, 2 ; BL = 2 (assume word output)
|
|
call Load_Up_Char ; Get 1st char
|
|
mov ah, al ; Move 1st char to AH
|
|
call Load_Up_Char ; Get second char
|
|
cmp al, 'L' ; Q: "L" (ie AL, BL, etc)?
|
|
jne short OSC1_WORD ; N: word reg
|
|
mov al, 'X' ; Y: change to X for pos match
|
|
mov bl, 1 ; BL = 1 -- byte output
|
|
OSC1_WORD:
|
|
xor di, di ; DI = 0
|
|
mov cx, 8 ; Size of a pusha
|
|
OSC1_Special_Loop:
|
|
push di
|
|
shl di,1
|
|
cmp ax, Reg_Offset_Table[di] ; Q: Is this the register?
|
|
pop di
|
|
je SHORT OSC1_Out_Reg ; Y: Output it
|
|
inc di ; N: Try the next one
|
|
loop OSC1_Special_Loop ; until CX = 0
|
|
|
|
OSC1_Ignore_Special: ; OOPS! backup and ignore special
|
|
pop si ; Restore original string ptr
|
|
dec si ; back up to special char
|
|
clc
|
|
jmp short gr_exit
|
|
|
|
OSC1_Out_Reg:
|
|
push di
|
|
shl di,1
|
|
mov ax, SS:[bp.6][di] ; AX = Value to output
|
|
pop di
|
|
add sp, 2 ; Trash pushed SI
|
|
cmp bl, 2 ;Q: byte or word value?
|
|
je short value_fnd ; jump if word value
|
|
xor ah, ah ; clear ah, if byte value
|
|
value_fnd:
|
|
stc
|
|
|
|
gr_exit:
|
|
ret
|
|
|
|
Get_Register endp
|
|
|
|
|
|
;******************************************************************************
|
|
;
|
|
; Load_Up_Char
|
|
;
|
|
; Moves the character at DS:SI into AL and converts it to an upper case
|
|
; character. SI is incremented.
|
|
;
|
|
;------------------------------------------------------------------------------
|
|
|
|
Load_Up_Char proc near
|
|
|
|
lodsb
|
|
cmp al, "Z"
|
|
jb SHORT LUC_Done
|
|
sub al, "a" - "A"
|
|
LUC_Done:
|
|
ret
|
|
|
|
Load_Up_Char endp
|
|
|
|
|
|
;******************************************************************************
|
|
;
|
|
; Out_Hex_Word
|
|
;
|
|
; Outputs the value in AX to the COM port in hexadecimal.
|
|
;
|
|
;------------------------------------------------------------------------------
|
|
|
|
Out_Hex_Word proc near
|
|
|
|
rol ax, 4
|
|
call Out_Hex_Char
|
|
rol ax, 4
|
|
call Out_Hex_Char
|
|
Out_Hex_Byte:
|
|
rol ax, 4
|
|
call Out_Hex_Char
|
|
rol ax, 4
|
|
call Out_Hex_Char
|
|
|
|
ret
|
|
|
|
Out_Hex_Word endp
|
|
|
|
|
|
;******************************************************************************
|
|
;
|
|
; Out_Hex_Char
|
|
;
|
|
; Outputs the low nibble in AL to the COM port.
|
|
;
|
|
;------------------------------------------------------------------------------
|
|
|
|
DXDATA segment
|
|
|
|
Hex_Char_Tab LABEL BYTE
|
|
db "0123456789ABCDEF"
|
|
|
|
DXDATA ends
|
|
|
|
Out_Hex_Char proc near
|
|
|
|
push ax
|
|
push bx
|
|
mov bx, ax
|
|
and bx, 1111b
|
|
mov al, Hex_Char_Tab[bx]
|
|
call Out_Debug_Chr
|
|
pop bx
|
|
pop ax
|
|
ret
|
|
|
|
Out_Hex_Char endp
|
|
|
|
|
|
;******************************************************************************
|
|
;
|
|
; Out_Debug_Chr
|
|
;
|
|
; DESCRIPTION:
|
|
;
|
|
; ENTRY:
|
|
; AL contains character to output
|
|
;
|
|
; EXIT:
|
|
;
|
|
; USES:
|
|
; Nothing
|
|
;
|
|
;==============================================================================
|
|
|
|
Out_Debug_Chr proc near
|
|
assume ds:nothing,es:DGROUP
|
|
|
|
push ax
|
|
mov ax,cs
|
|
cmp ax,SEL_DXCODE0 ; Are we in real mode?
|
|
pop ax
|
|
jne out_com
|
|
|
|
cmp fDebug,0 ; debugger installed?
|
|
je out_com ; N: go output it ourselves
|
|
|
|
push ax
|
|
push dx
|
|
mov dl, al
|
|
mov ax, DS_Out_Char
|
|
int Debug_Serv_Int
|
|
pop dx
|
|
pop ax
|
|
ret
|
|
|
|
Out_Debug_Chr endp
|
|
|
|
|
|
;******************************************************************************
|
|
;
|
|
; out_com
|
|
;
|
|
; DESCRIPTION: Reprograms COM and outputs a character (stolen from DEB386).
|
|
;
|
|
; ENTRY: AL character to output
|
|
;
|
|
; EXIT:
|
|
;
|
|
; USES:
|
|
;
|
|
;==============================================================================
|
|
|
|
|
|
UR_DAT equ 0000h ; Data port
|
|
UR_IEN equ 0001h ; Interrupt enable
|
|
UR_IER equ 0002h ; interrupt ID
|
|
UR_LCR equ 0003h ; line control registers
|
|
UR_MCR equ 0004h ; modem control register
|
|
UR_LSR equ 0005h ; line status register
|
|
UR_MSR equ 0006h ; modem status regiser
|
|
UR_DLL equ 0000h ; divisor latch least sig
|
|
UR_DLM equ 0001h ; divisor latch most sig
|
|
|
|
public out_com
|
|
|
|
out_com proc near
|
|
|
|
push dx
|
|
push ax
|
|
|
|
push ds ;get first com port address from BIOS area
|
|
mov ax,40h
|
|
mov ds,ax
|
|
mov dx,ds:[0]
|
|
pop ds
|
|
|
|
or dx,dx ;forget it if no comm port
|
|
jnz @f
|
|
|
|
pop ax
|
|
pop dx
|
|
ret
|
|
@@:
|
|
|
|
;
|
|
; Initialize the port on EVERY CHARACTER just to make sure
|
|
;
|
|
add dx, UR_LCR
|
|
mov al, 80h
|
|
out dx, al
|
|
IO_Delay
|
|
sub al, al
|
|
add dx, UR_DLM - UR_LCR
|
|
out dx, al
|
|
IO_Delay
|
|
add dx, UR_DLL - UR_DLM
|
|
mov al, 12
|
|
out dx, al
|
|
IO_Delay
|
|
mov al, 3
|
|
add dx, UR_LCR - UR_DLL
|
|
out dx, al
|
|
IO_Delay
|
|
add dx, UR_LSR - UR_LCR
|
|
|
|
Wait_Til_Ready:
|
|
in al, dx
|
|
IO_Delay
|
|
test al, 020h
|
|
jz Wait_Til_Ready
|
|
;
|
|
; Crank it out!
|
|
;
|
|
add dx, UR_DAT - UR_LSR
|
|
pop ax
|
|
out dx, al
|
|
IO_Delay
|
|
pop dx
|
|
|
|
ret
|
|
|
|
out_com endp
|
|
|
|
|
|
;******************************************************************************
|
|
;
|
|
; Show_Near_Label
|
|
;
|
|
; DESCRIPTION: call the debugger to display a label less than or equal
|
|
; to the given address
|
|
;
|
|
; ENTRY: AX is selector, CX is offset of address to try to find
|
|
; a symbol for
|
|
; ES selector to DOSX data segment
|
|
; EXIT:
|
|
;
|
|
; USES:
|
|
;
|
|
;==============================================================================
|
|
|
|
Show_Near_Label proc near
|
|
|
|
push ax
|
|
mov ax,cs
|
|
cmp ax,SEL_DXCODE0 ; Are we in real mode?
|
|
pop ax
|
|
jne Show_Near_Label_ret
|
|
|
|
cmp es:idCpuType,3 ;use 32 bit regs?
|
|
jae debug_386
|
|
|
|
push ax ;on a 286, use 16 bit regs
|
|
push bx
|
|
push cx
|
|
mov bx,cx
|
|
mov cx,ax
|
|
mov ax,DS_Out_Symbol
|
|
int Debug_Serv_Int
|
|
pop cx
|
|
pop bx
|
|
pop ax
|
|
ret
|
|
|
|
debug_386:
|
|
.386p
|
|
push eax
|
|
push ebx
|
|
push ecx
|
|
|
|
mov bx, cx
|
|
|
|
movzx ecx, ax ;WDEB386 wants a 32 bit offset
|
|
|
|
mov ax, DS_Out_Symbol
|
|
int Debug_Serv_Int
|
|
|
|
pop ecx
|
|
pop ebx
|
|
pop eax
|
|
ret
|
|
|
|
.286p
|
|
|
|
Show_Near_Label_ret:
|
|
|
|
Show_Near_Label endp
|
|
|
|
|
|
;******************************************************************************
|
|
;
|
|
; Show_String
|
|
;
|
|
; DESCRIPTION: Display an asciiz string
|
|
;
|
|
; ENTRY: AX is selector, CX is offset of address to find string
|
|
;
|
|
; EXIT:
|
|
;
|
|
; USES:
|
|
;
|
|
;==============================================================================
|
|
|
|
Show_String proc near
|
|
|
|
push ax
|
|
push ds
|
|
push si
|
|
|
|
mov ds,ax
|
|
mov si,cx
|
|
xor ax,ax
|
|
@@:
|
|
lodsb
|
|
or al,al
|
|
jz @f
|
|
call Out_Debug_Chr
|
|
jmp short @b
|
|
@@:
|
|
pop si
|
|
pop ds
|
|
pop ax
|
|
|
|
ret
|
|
|
|
Show_String endp
|
|
|
|
|
|
DXCODE ends
|
|
|
|
endif ; DEBUG
|
|
|
|
|
|
if NTDEBUG
|
|
;******************************************************************************
|
|
;
|
|
; The following macros and routines implement DOSX's internal trace tables.
|
|
;
|
|
;==============================================================================
|
|
|
|
ifdef WOW_x86
|
|
|
|
SAVE_STATE_PM MACRO
|
|
push ebp
|
|
mov ebp, esp
|
|
pushfd
|
|
pushad
|
|
push ss
|
|
push es
|
|
push ds
|
|
push cs
|
|
|
|
mov ax, ss
|
|
lar eax,eax
|
|
test eax,(AB_BIG SHL 8)
|
|
jnz @f
|
|
movzx ebp,bp
|
|
@@:
|
|
ENDM
|
|
RESTORE_STATE_PM MACRO
|
|
add esp, 2
|
|
pop ds
|
|
pop es
|
|
pop ss
|
|
popad
|
|
popfd
|
|
pop ebp
|
|
ENDM
|
|
|
|
SAVE_STATE_V86 MACRO
|
|
push ebp
|
|
mov ebp, esp
|
|
pushfd
|
|
pushad
|
|
push ss
|
|
push es
|
|
push ds
|
|
push cs
|
|
ENDM
|
|
RESTORE_STATE_V86 MACRO
|
|
add esp, 2
|
|
pop ds
|
|
pop es
|
|
pop ss
|
|
popad
|
|
popfd
|
|
pop ebp
|
|
ENDM
|
|
|
|
TRACEDS_PM MACRO
|
|
mov ax,SEL_DXDATA or STD_RING
|
|
mov ds, ax
|
|
ENDM
|
|
|
|
TRACEDS_V86 MACRO
|
|
mov ds,selDgroup
|
|
ENDM
|
|
|
|
DEBUG_TRACE_PROC MACRO mode
|
|
local dbgtr_exit
|
|
|
|
.386p
|
|
SAVE_STATE_&mode
|
|
|
|
TRACEDS_&mode
|
|
assume ds:DGROUP
|
|
|
|
test fDebugTrace, 0ffh
|
|
jnz short @f
|
|
jmp dbgtr_exit ;just return
|
|
@@:
|
|
;------------------------------------------------------------------------------
|
|
; Update DebugTraceBuffer
|
|
;------------------------------------------------------------------------------
|
|
mov di, DebugTracePointer
|
|
add di, TRACE_ENTRY_SIZE
|
|
cmp di, OFFSET DebugTraceBuffer + TRACE_ENTRY_SIZE*(NUM_TRACE_ENTRIES-1)
|
|
jbe short @f
|
|
mov di, OFFSET DebugTraceBuffer
|
|
@@:
|
|
mov DebugTracePointer, di
|
|
movzx edi, di
|
|
|
|
push edi
|
|
push ds
|
|
|
|
push ds
|
|
pop es
|
|
push ss
|
|
pop ds
|
|
mov ecx, 8 ;four parameters on stack
|
|
mov esi, ebp ;point to input parameters
|
|
add esi, 6
|
|
cld
|
|
rep movsb ;move them to debugtracebuffer
|
|
pop ds
|
|
pop edi
|
|
|
|
mov ax, DebugTraceCounter
|
|
mov word ptr es:[di+8], ax
|
|
inc DebugTraceCounter
|
|
|
|
push ds
|
|
mov ax, SEL_VDMTIB or STD_RING
|
|
mov ds, ax
|
|
mov ax, word ptr ds:[0]
|
|
mov word ptr es:[di+10], ax
|
|
pop ds
|
|
|
|
mov ax, word ptr ss:[ebp+4]
|
|
mov word ptr es:[di+12], ax
|
|
|
|
;------------------------------------------------------------------------------
|
|
; Update RegisterTraceBuffer
|
|
;------------------------------------------------------------------------------
|
|
mov ax, RegisterTracePointer
|
|
add ax, REGTRACE_ENTRY_SIZE
|
|
cmp ax, OFFSET RegisterTraceBuffer + REGTRACE_ENTRY_SIZE*(NUM_TRACE_ENTRIES-1)
|
|
jbe short @f
|
|
mov ax, OFFSET RegisterTraceBuffer
|
|
@@:
|
|
mov RegisterTracePointer, ax
|
|
mov word ptr es:[di+14], ax ;save pointer to register buff
|
|
mov di, ax
|
|
|
|
|
|
push ds
|
|
pop es
|
|
push ss
|
|
pop ds
|
|
mov ecx, REGTRACE_ENTRY_SIZE
|
|
mov esi, ebp
|
|
sub esi, 44 ;point to saved register values
|
|
cld
|
|
rep movsb
|
|
|
|
dbgtr_exit:
|
|
RESTORE_STATE_&mode
|
|
ENDM
|
|
|
|
else
|
|
|
|
SAVE_STATE_PM MACRO
|
|
push bp
|
|
mov bp, sp
|
|
pushf
|
|
pusha
|
|
push ss
|
|
push es
|
|
push ds
|
|
push cs
|
|
ENDM
|
|
RESTORE_STATE_PM MACRO
|
|
add sp, 2
|
|
pop ds
|
|
pop es
|
|
pop ss
|
|
popa
|
|
popf
|
|
pop bp
|
|
ENDM
|
|
|
|
SAVE_STATE_V86 MACRO
|
|
push bp
|
|
mov bp, sp
|
|
pushf
|
|
pusha
|
|
push ss
|
|
push es
|
|
push ds
|
|
push cs
|
|
ENDM
|
|
RESTORE_STATE_V86 MACRO
|
|
add sp, 2
|
|
pop ds
|
|
pop es
|
|
pop ss
|
|
popa
|
|
popf
|
|
pop bp
|
|
ENDM
|
|
|
|
DEBUG_TRACE_PROC MACRO mode
|
|
local dbgtr_exit
|
|
|
|
.286p
|
|
|
|
SAVE_STATE_&mode
|
|
|
|
mov ax,SEL_DXDATA or STD_RING
|
|
mov ds, ax
|
|
assume ds:DXDATA
|
|
|
|
test fDebugTrace, 0ffh
|
|
jnz short @f
|
|
jmp dbgtr_exit ;just return
|
|
@@:
|
|
;------------------------------------------------------------------------------
|
|
; Update DebugTraceBuffer
|
|
;------------------------------------------------------------------------------
|
|
mov di, DebugTracePointer
|
|
add di, TRACE_ENTRY_SIZE
|
|
cmp di, OFFSET DebugTraceBuffer + TRACE_ENTRY_SIZE*(NUM_TRACE_ENTRIES-1)
|
|
jbe short @f
|
|
mov di, OFFSET DebugTraceBuffer
|
|
@@:
|
|
mov DebugTracePointer, di
|
|
|
|
push di
|
|
push ds
|
|
|
|
push ds
|
|
pop es
|
|
push ss
|
|
pop ds
|
|
mov cx, 8 ;four parameters on stack
|
|
mov si, bp ;point to input parameters
|
|
add si, 6
|
|
cld
|
|
rep movsb ;move them to debugtracebuffer
|
|
pop ds
|
|
pop di
|
|
|
|
mov ax, DebugTraceCounter
|
|
mov word ptr es:[di+8], ax
|
|
inc DebugTraceCounter
|
|
|
|
mov word ptr es:[di+10], 0
|
|
mov ax, word ptr ss:[bp+4]
|
|
mov word ptr es:[di+12], ax
|
|
|
|
;------------------------------------------------------------------------------
|
|
; Update RegisterTraceBuffer
|
|
;------------------------------------------------------------------------------
|
|
mov ax, RegisterTracePointer
|
|
add ax, REGTRACE_ENTRY_SIZE
|
|
cmp ax, OFFSET RegisterTraceBuffer + REGTRACE_ENTRY_SIZE*(NUM_TRACE_ENTRIES-1)
|
|
jbe short @f
|
|
mov ax, OFFSET RegisterTraceBuffer
|
|
@@:
|
|
mov RegisterTracePointer, ax
|
|
mov word ptr es:[di+14], ax ;save pointer to register buff
|
|
mov di, ax
|
|
|
|
|
|
push ds
|
|
pop es
|
|
push ss
|
|
pop ds
|
|
mov cx, REGTRACE_ENTRY_SIZE
|
|
mov si, bp
|
|
sub si, 44 ;point to saved register values
|
|
cld
|
|
rep movsb
|
|
|
|
dbgtr_exit:
|
|
RESTORE_STATE_&mode
|
|
ENDM
|
|
|
|
endif ; WOW_x86
|
|
|
|
DXDATA segment
|
|
|
|
NUM_TRACE_PARAMETERS equ 4 ;# of pass parameters to proc
|
|
NUM_TRACE_ENTRIES equ 256
|
|
TRACE_ENTRY_SIZE equ 2*8
|
|
REGTRACE_ENTRY_SIZE equ 12*4
|
|
|
|
public DebugTraceBuffer, DebugTracePointer
|
|
public RegisterTraceBuffer, RegisterTracePointer
|
|
ALIGN 16
|
|
DebugTraceBuffer db TRACE_ENTRY_SIZE*NUM_TRACE_ENTRIES dup (?)
|
|
RegisterTraceBuffer db REGTRACE_ENTRY_SIZE*NUM_TRACE_ENTRIES dup (?)
|
|
|
|
DebugTracePointer dw OFFSET DebugTraceBuffer
|
|
DebugTraceCounter dw 0
|
|
RegisterTracePointer dw OFFSET RegisterTraceBuffer
|
|
DXDATA ends
|
|
|
|
extrn pbReflStack:WORD
|
|
extrn fDebugTrace:BYTE
|
|
|
|
|
|
DXPMCODE segment
|
|
assume cs:DXPMCODE
|
|
;******************************************************************************
|
|
;
|
|
; DebugTrace
|
|
;
|
|
; DESCRIPTION:
|
|
;
|
|
; ENTRY:
|
|
;
|
|
; EXIT:
|
|
;
|
|
; USES:
|
|
;
|
|
;==============================================================================
|
|
|
|
public DebugTrace
|
|
DebugTrace proc near
|
|
|
|
DEBUG_TRACE_PROC PM
|
|
ret 2*NUM_TRACE_PARAMETERS
|
|
|
|
DebugTrace endp
|
|
|
|
DXPMCODE ends
|
|
|
|
DXCODE segment
|
|
|
|
IFNDEF ROM
|
|
extrn selDgroup:WORD
|
|
ENDIF
|
|
|
|
assume cs:DXCODE
|
|
;******************************************************************************
|
|
;
|
|
; Stack_Trace
|
|
;
|
|
; DESCRIPTION:
|
|
;
|
|
; ENTRY:
|
|
;
|
|
; EXIT:
|
|
;
|
|
; USES:
|
|
;
|
|
;==============================================================================
|
|
|
|
public DebugTraceRm
|
|
DebugTraceRm proc near
|
|
|
|
DEBUG_TRACE_PROC V86
|
|
ret 2*NUM_TRACE_PARAMETERS
|
|
|
|
DebugTraceRm endp
|
|
|
|
DXCODE ends
|
|
|
|
endif ; NTDEBUG
|
|
end
|