home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
ddkx86v5.zip
/
DDKX86
/
SRC
/
PEN
/
PENTKT
/
PENBASE
/
TRACE.ASM
< prev
next >
Wrap
Assembly Source File
|
1995-04-14
|
16KB
|
545 lines
;*DDK*************************************************************************/
;
; COPYRIGHT Copyright (C) 1995 IBM Corporation
;
; The following IBM OS/2 WARP source code is provided to you solely for
; the purpose of assisting you in your development of OS/2 WARP device
; drivers. You may use this code in accordance with the IBM License
; Agreement provided in the IBM Device Driver Source Kit for OS/2. This
; Copyright statement may not be removed.;
;*****************************************************************************/
; /*****************************************************************/
; /* */
; /* */
; /*****************************************************************/
; /******************* START OF SPECIFICATIONS *********************/
; /* */
; /* SOURCE FILE NAME: TRACE.ASM */
; /* */
; /* DESCRIPTIVE NAME: Trace support */
; /* */
; /* */
; /* STATUS: Version 1.0 */
; /* */
; /* NOTES: This module provides tracing support which can be */
; /* used for debugging. Macros are defined in PEN.INC */
; /* to add trace data. The trace is extracted and */
; /* formatted by the pen device driver tool (PENTL.EXE). */
; /* */
; /* The trace table must be allocated before tracing. */
; /* This can be done throught the pen tool or can be */
; /* allocated during driver initialization with by: */
; /* */
; /* device=c:\penpm\pendd.sys trace=1000 */
; /* */
; /* 1000 can be any value trace table size. */
; /* */
; /* ENTRY POINTS: */
; /* See public statements */
; /* EXTERNAL REFERENCES: */
; /* See extrn statements */
; /* */
; /******************* END OF SPECIFICATIONS *********************/
.xlist
include pensegs.inc
include pen.inc
include penei.inc
include penioctl.inc
include devsym.inc
include devhlp.inc
include struc.inc
.list
.386p
;------------------------------------------------------------------------------
;declare external routines
;------------------------------------------------------------------------------
extrn skip_to_white : near
extrn skip_white : near
extrn str_i_cmp : near
extrn get_dec_num : near
;------------------------------------------------------------------------------
;declare external variables
;------------------------------------------------------------------------------
extrn Device_Help : dword
;------------------------------------------------------------------------------
; local equates
;------------------------------------------------------------------------------
fUSE_DEKKO equ 0 ; 1= use dekko trace 0= don't
CR equ 0Dh
LF equ 0Ah
;------------------------------------------------------------------------------
; local data that is device instance independent
;------------------------------------------------------------------------------
DSEG SEGMENT
; share same trace buffer for all devcies
public trcNext
trcSize dw 0 ; count of DWORD entries
trcWrap db 0
trcDS dw 0
trcPhys_h dw 0
trcPhys_l dw 0
trcNext dw 0
trcStart dw 0
DSEG ends
DSEGI segment
opt_trace db 'TRACE=',0
cnf_trace dw 0 ; size of trace to allocate at init time
DSEGI ends
CSEG SEGMENT
ASSUME CS:CGROUP, SS:nothing, ES:nothing, DS:DGROUP
;--- TRACE ROUTINES -----------------------------------------------------------
;
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
; Trace ABSOLUTE packet
; di = event packet
; returns
; maintains all regs and indicators
;------------------------------------------------------------------------------
Public Trc_ABS
Trc_ABS Proc Near
pushf
DISABLE
mov ax,[di].cev_devicebits
mov cx,TRACE_ABS_EH
call doTrc
mov eax,[di].lev_dev_x
mov cx,TRACE_ABS_XH
call doTrc
mov eax,[di].lev_dev_y
mov cx,TRACE_ABS_YH
call doTrc
mov ax,[di].lev_dev_z
mov cx,TRACE_ABS_ZH
call doTrc
popf
ret
Trc_ABS EndP
;------------------------------------------------------------------------------
; Trace a byte
; al = byte to trace
; returns
; maintains all regs and indicators
;------------------------------------------------------------------------------
Public Trc_Byte
Trc_Byte Proc Near
pushf
DISABLE
push ax
push cx
mov cx,TRACE_DATA_H
mov ah,0
call doTrc
pop cx
pop ax
popf
ret
Trc_Byte EndP
;------------------------------------------------------------------------------
; Trace a byte (first byte of packet)
; al = byte to trace
; returns
; maintains all regs and indicators
;------------------------------------------------------------------------------
Public Trc_Byte1
Trc_Byte1 Proc Near
pushf
DISABLE
push ax
push cx
mov cx,TRACE_DATA_1H
mov ah,0
call doTrc
pop cx
pop ax
popf
ret
Trc_Byte1 EndP
;------------------------------------------------------------------------------
; Trace a device dependent word
; ax = word to trace
; cl = index
; returns
; maintains all regs and indicators
;------------------------------------------------------------------------------
Public Trc_DD
Trc_DD Proc Near
pushf
DISABLE
push ax
push cx
xor ch,ch
or cx,TRACE_DD_H
call doTrc
pop cx
pop ax
popf
ret
Trc_DD EndP
;------------------------------------------------------------------------------
; Trace an interrupt (put a special mark in trace)
;
; returns
; maintains all regs and indicators
;------------------------------------------------------------------------------
Public Trc_INT
Trc_INT Proc Near
pushf
DISABLE
push ax
push cx
mov cx, TRACE_INT_H
mov ax,0
call doTrc
pop cx
pop ax
popf
ret
Trc_INT EndP
;------------------------------------------------------------------------------
; Trace a timer tick (put a special mark in trace)
;
; returns
; maintains all regs and indicators
; note: Does not fill up trace with ticks, instead, increment trace entry
; as the number of ticks since the last trace event.
;------------------------------------------------------------------------------
Public Trc_Tick
Trc_Tick Proc Near
.if <trcSize ne 0> ; check for trace table
pushf
DISABLE
push ax
push cx
push si
mov si, trcNext
push ds
mov ds, trcDS
.if <<word ptr [si+6]> eq TRACE_TICK_H>
inc word ptr [si+4]
pop ds
.else
pop ds
mov cx, TRACE_TICK_H
mov ax,1
call doTrc
.endif
pop si
pop cx
pop ax
popf
.endif
ret
Trc_Tick EndP
;------------------------------------------------------------------------------
; Actually do the trace entry
; ax = low order
; cx = high order
;------------------------------------------------------------------------------
Public doTrc
doTrc Proc
.if <trcSize ne 0>
push di
mov di,trcNext
push ds
mov ds, trcDS
mov word ptr [di],ax
mov word ptr [di+2],cx
pop ds
sub di,4
.if c ; do the wrap around
mov trcWrap, 1
mov di, trcStart
.endif
mov trcNext,di
pop di
.endif
xor ax,ax
ret
doTrc EndP
;--- IOCTL ROUTINES ---------------------------------------------------------
;
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
; Return the size of the trace table
;
; The returned size includes one for the first entry which is used to return
; the number of valid entries on the query trace table command.
;
; We waste one entry to make tracing ticks easiler. Tick trace looks ahead one
; entry to see if its a tick trace. We would need a special check not to look
; past the end of the table, instead we just waste one entry at the end.
;
; So, if 10 entries are requested on the Set Trace Table Size IOCTL, we alloc
; storage for 10 entries, then waste one. We return 10 on Query Trace table
; to include the first LONG which contains the number of valid entries. If the
; table is full or has wrapped, a 9 would be in this first location.
;------------------------------------------------------------------------------
public Gio_qtts
Gio_qtts proc ; query trace table size
mov ax, trcSize
mov word ptr gs:[si].dqtts_size,ax
mov word ptr gs:[si].dqtts_size+2,0
xor ax,ax
ret
Gio_qtts endp
;------------------------------------------------------------------------------
; Reset the trace back to start
;
; note: this is not really needed as the trace is a wrap trace, but the Trace
; program dumps starting at trcStart as a simification.
;------------------------------------------------------------------------------
public Gio_rtb
Gio_rtb proc ; reset trace buffer
push di
mov di, trcStart
mov trcNext, di
mov trcWrap, 0
pop di
xor ax,ax
ret
Gio_rtb endp
;------------------------------------------------------------------------------
; Copy the trace table to the Trace application's buffer
; gs:si = data packet
; note: handle generic IOCTL dump command
;------------------------------------------------------------------------------
public Gio_qtt
Gio_qtt proc ; query trace table
push gs
pop es
mov di,si
.if <trcSize eq 0> ; check for trace table
mov word ptr es:[di],0
mov word ptr es:[di+2],0
.else
DISABLE
mov cx, trcStart ; ax = addr of last entry in trace table
sub cx, trcNext ; calculate trace byte count
shr cx,2 ; convert to dword count
.if <trcWrap ne 0>
mov ax, trcSize
dec ax ; one is wasted
mov dx, ax
sub dx, cx
.else
mov ax, cx
.endif
mov word ptr es:[di],ax
add di,2
mov word ptr es:[di],0
add di,2
sal cx, 1 ; convert to word count
mov si, trcNext ; calculate trace byte count
add si,4 ; adv to first entry (not the next available)
push ds
mov ds, trcDS
rep movsw ; move it
pop ds
.if <trcWrap ne 0>
mov cx, dx
sal cx, 1
mov si, 0
push ds
mov ds, trcDS
rep movsw ; move it
pop ds
.endif
ENABLE
.endif
xor ax,ax
ret
Gio_qtt endp
;------------------------------------------------------------------------------
; Allocate or re-size trace table
; fs:di = PSTTS packet
;------------------------------------------------------------------------------
public Gio_stts ; Set Trace Table Size
Gio_stts proc
entryCount equ bp-4
traceSize equ bp-2
mov bx, word ptr fs:[di].pstts_size
; free the old one
initentry:
enter 4,0
push bx
.if <trcSize ne 0> ; free old buffer
mov trcSize, 0 ; stop traceing
mov ax, trcPhys_h
mov bx, trcPhys_l
mov dl, DevHlp_FreePhys
call Device_Help
.endif
pop bx
; allocate new size
; bx = size in dwords
.if <zero bx>
xor ax,ax ; stop tracing
.else
.if <bx a 4000>
mov bx, 4000 ; limit how big
.endif
.if <bx lt 10>
mov bx, 10 ; limit how small
.endif
mov [entryCount],bx
mov ax, 0
sal bx, 2 ; convert to byte count
mov [traceSize],bx
mov dh, 0 ; above 1 meg
mov dl, DevHlp_AllocPhys
call Device_Help
.if nc
mov trcPhys_h,ax
mov trcPhys_l,bx
mov cx, [traceSize]
mov si, trcDS
mov dl, DevHlp_PhysToGDTSelector
call Device_Help
.if nc
mov ax, [traceSize]
sub ax, 8 ; back up and waste one entry
mov trcNext , ax
mov trcStart, ax
mov trcWrap, 0
mov ax, [entryCount]
mov trcSize, ax
xor ax, ax
.endif
.endif
.if c
mov ax,STERR+STECODE
.endif
.endif
leave
ret
Gio_stts endp
CSEG ends
;-- INITIALIZATION ROUTINE ----------------------------------------------------
;
;------------------------------------------------------------------------------
CSEGI SEGMENT
ASSUME CS:CGROUP, SS:nothing, ES:nothing, DS:DGROUP
;------------------------------------------------------------------------------
; prepare for trace
;------------------------------------------------------------------------------
public Trc_Init
Trc_Init Proc Near
push es ; save parmline
push di
; allocate a selector to be used for the trace buffer
push ds
pop es
mov di, offset trcDS
mov cx, 1
mov dl, DevHlp_AllocGDTSelector
call Device_Help
pop di ; restore parmline
pop es
; see if trace= is specified
call skip_to_white ; Skip driver name
pcl_loop:
call skip_white ; Skip any/all blanks til 1st char
mov al, es:[di] ; Get 1st parameter/keyword char
cmp al, CR ; Scan remaining line chars for
jz pcl_loop_exit ; Keywords and parameters
cmp al, LF ; until end of line condition
jz pcl_loop_exit ; reached
cmp al, 0
jz pcl_loop_exit
cld
call DParse
jmp pcl_loop
pcl_loop_exit:
; allocate a trace table at init time if requested
mov bx, cnf_trace
.if <nonzero bx>
call initentry
.endif
ret
Trc_Init EndP
;----------------------------------------------------------------------------
; Parses command line options given on CONFIG.SYS's DEVICE= line
; Look for trace parameter, ignore others.
; es:[di] => possible command line option
;----------------------------------------------------------------------------
temp_di equ [bp]-2
public Dparse
Dparse proc near
enter 2,0
call skip_white
mov temp_di, di
; look for TRACE= parm
mov si, offset opt_trace
call str_i_cmp
.if <zero ax> ; found TRACE=, get type number
mov temp_di,di
call get_dec_num
.if <di ne temp_di>
mov cnf_trace, ax
.endif
.endif
parse_exit:
call skip_to_white
leave
ret
Dparse endp
CSEGI ENDS
end