home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
ddkx86v5.zip
/
DDKX86
/
SRC
/
PEN
/
PENTKT
/
PENBASE
/
INIT.ASM
< prev
next >
Wrap
Assembly Source File
|
1995-04-14
|
20KB
|
648 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: INIT.ASM */
; /* */
; /* DESCRIPTIVE NAME: Initialization routine */
; /* */
; /* */
; /* STATUS: Version 1.0 */
; /* */
; /* NOTES: Perform all functions needed to initialize the */
; /* driver. Routines are provided to parse the config.sys */
; /* line and to modify the driver name and driver device */
; /* name. */
; /* */
; /* Unit 0 variables are provided as follows: */
; /* index 0 = device error count */
; /* index 1 = panic codes */
; /* */
; /* These variables can be queried with the pen device */
; /* driver tool. Panic codes are defined in PEN.INC and */
; /* provide problem determination if the driver is not */
; /* functional. */
; /* */
; /* ENTRY POINTS: */
; /* See public statements */
; /* EXTERNAL REFERENCES: */
; /* See extrn statements */
; /* */
; /******************* END OF SPECIFICATIONS *********************/
.xlist
include pensegs.inc
include pen.inc
include penei.inc
include penidc.inc
include penioctl.inc
include devsym.inc
include devhlp.inc
include struc.inc
.list
.286p
;------------------------------------------------------------------------------
; external data references
;------------------------------------------------------------------------------
extrn DDHdr1 : byte
extrn Dev_ErrorCount : dword
extrn Dev_Lev_Major : byte
extrn Dev_Lev_Minor : byte
;------------------------------------------------------------------------------
; external routines
;------------------------------------------------------------------------------
extrn Dev_Init : near
extrn Loc_Init : near
extrn But_Init : near
extrn Dsp_Init : near
extrn Tim_Init : near
extrn Trc_Init : near
extrn Vmc_Init : near
extrn Idc_DriverEntryPoint : near
extrn Gio_AddDCB : near
extrn Dsp_callback :near
;------------------------------------------------------------------------------
; local equates
;------------------------------------------------------------------------------
GDTINFOINDEX equ 1
;------------------------------------------------------------------------------
; global data declarations
;------------------------------------------------------------------------------
public Device_Help,RegCaps0
DSEG segment
Device_Help dd 0 ; Dev helper entry point
public dcb0
dcb0 DCB_DRV <> ; driver dcb
public RegCaps0
RegCaps0 DDCAP <> ; device driver registration packet
; define unit 0 unit variables, accessable via query|set unit variable IOCTL
public DDPanic
UVAR_COUNT equ 2
numUVars DD UVAR_COUNT
UVarss DD 0 ; 0= error count
DDPanic DD PANIC_DDS ; 1= panic numbers (init to DDS not contact us)
Public GDTInfoSeg
GDTInfoSeg dw 0 ; Save GDT Selector to info seg
DSEG ends
;------------------------------------------------------------------------------
; local init data declarations
;------------------------------------------------------------------------------
DSEGI SEGMENT
public ENDDATA
ENDDATA label byte ; used to figure end of init data to free
deviceName db 'DRIVER ' ; device name
public ParmLine
ParmLine dd 0 ; pointer to config.sys line
public InitPkt
InitPkt dd 0
DSEGI ends
CSEGI SEGMENT
ASSUME CS:CSEGI, SS:nothing, ES:nothing, DS:DGROUP
public ENDCODE
ENDCODE label near ; used to know where to truncate after INIT command
;------------------------------------------------------------------------------
; OS/2 initialization routine entry point
; es:bx = request packet
;------------------------------------------------------------------------------
public Init_Init
Init_Init Proc Near
; Get the address to the DevHelp router and save in our DS.
mov word ptr InitPkt, bx
mov word ptr InitPkt+2, es
push es
push bx
.386p
mov edx,dword ptr es:[bx.InitpBPB] ; get config.sys statement pointer
mov ParmLine, edx
mov edx,dword ptr es:[bx].InitDevHlp
mov Device_Help, edx
.286p
; get the info seg
push es
push bx
mov al, GDTINFOINDEX ; Request GDT InfoSeg value = 1
mov dl, DevHlp_GetDOSVar ; DevHelp function number
call Device_Help ; Invoke GetDOSVar Function
.if c
PANIC PANIC_DEVHLP1
.else
mov es, ax ; Get the GDT level 0 selector and
mov ax, word ptr es:[bx] ; Overwrite the level 3 Selector
mov GDTInfoSeg, ax ; Save GDT Selector
.endif
pop bx
pop es
; add a dcb for the driver to list as unit 0
lea bx, dcb0
call Gio_AddDCB
call initDCB0
call Tim_Init
; Set up all devices and add all DCBs
les di,ParmLine ; Set ES:DI -> to config.sys
call Dev_Init
.if <zero ax>
; register with penPM device services
mov si, offset DDHdr1 + 10 ; driver name
mov ax, cs
mov bx, offset Idc_DriverEntryPoint
mov cx, 2
mov di, REG_EXT_IF
mov dl, DevHlp_RegisterDeviceClass
call Device_Help
.if c
PANIC PANIC_DEVHLP2
.endif
; do device type initializations
CALL_TYPE Loc_Init,DT_LOCATOR
CALL_TYPE But_Init,DT_BUTTON
CALL_TYPE Dsp_Init,DT_DISPLAY
CALL_ALL Int_ChkNames
; do driver initialazations
les di,ParmLine ; Set ES:DI -> to config.sys line
call Trc_Init
les di,ParmLine ; Set ES:DI -> to config.sys line
call Vmc_Init
xor ax,ax
.endif
; free the init code and data segments
pop bx
pop es
mov byte ptr es:[bx].InitcUnit, 0
.if <zero ax>
mov word ptr es:[bx].InitpEnd, offset ENDCODE
mov word ptr es:[bx].InitpEnd+2, offset ENDDATA
.else
mov es:[bx].PktStatus, ax ; set error return code
mov word ptr es:[bx].InitpEnd, 0
mov word ptr es:[bx].InitpEnd+2, 0
PANIC PANIC_DEVINIT ; This won't show up since the dd will terminate
.endif
ret
Init_Init EndP
;------------------------------------------------------------------------------
; Set up the driver device DCB
;------------------------------------------------------------------------------
public initDCB0
initDCB0 proc
mov dcb0.dcb_@RegCaps, offset RegCaps0
mov al, dcb0.dcb_Unit
mov bx, dcb0.dcb_@regCaps
mov [bx].ccap_unit, al
mov [bx].ccap_device_type,DT_DRIVER
mov [bx].ccap_length, size DDCAP
mov al, Dev_Lev_Major
mov [bx].ddcap_rev_major,al
mov al, Dev_Lev_Minor
mov [bx].ddcap_rev_minor,al
mov [bx].ddcap_ioc_major,PEN_IOCTL_LEV_MAJOR
mov [bx].ddcap_ioc_minor,PEN_IOCTL_LEV_MINOR
mov [bx].ddcap_eif_major,PEN_EI_LEV_MAJOR
mov [bx].ddcap_eif_minor,PEN_EI_LEV_MINOR
mov [bx].ddcap_idc_major,PEN_DDS_LEV_MAJOR
mov [bx].ddcap_idc_minor,PEN_DDS_LEV_MINOR
mov si, offset DDHdr1 + 10 ; driver name
lea di, [bx].ccap_driver_name
cld
push ds
pop es
mov cx,SIZEOF_DRIVER_NAME
rep movsb
mov si, offset deviceName ; device name
lea di, [bx].ccap_device_name
mov cx, SIZEOF_DRIVER_NAME
rep movsb
mov dcb0.dcb_@UVars, offset numUVars
mov dcb0.dcb_@Dev_quv, offset unit0_quv
mov dcb0.dcb_@Dev_suv, offset unit0_suv
mov dcb0.dcb_@Dev_Start, offset Null_rtn
mov dcb0.dcb_@Dev_CallBack,offset Dsp_callback
ret
initDCB0 endp
;------------------------------------------------------------------------------
; make sure all names are null terminated
;------------------------------------------------------------------------------
public Int_ChkNames
Int_ChkNames proc
mov di,[bx].dcb_@RegCaps
mov [di].ccap_device_name+SIZEOF_DEVICE_NAME-1,0
stc ;do all
ret
Int_ChkNames endp
CSEGI ENDS
;-- ROUTINES FOR DRIVER DEVICE ------------------------------------------------
;
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
; Query unit variable, variable 0 is used to return the number of device errors
;------------------------------------------------------------------------------
CSEG segment
ASSUME CS:CGROUP, SS:nothing, ES:nothing, DS:DGROUP
public unit0_quv
unit0_quv proc
.if <ax eq 0>
.386p
mov edx,Dev_ErrorCount
.286p
.endif
ret
unit0_quv endp
;------------------------------------------------------------------------------
; Query unit variable, variable 0 can be reset to 0
;------------------------------------------------------------------------------
public unit0_suv
unit0_suv proc
.if <ax eq 0>
.386p
mov Dev_ErrorCount,edx
.286p
.endif
ret
unit0_suv endp
;------------------------------------------------------------------------------
; Avaiable for use
;------------------------------------------------------------------------------
public Null_rtn
Null_rtn proc
xor ax,ax
ret
Null_rtn endp
public Null_rtn_far
Null_rtn_far proc far
stc
ret
Null_rtn_far endp
CSEG ENDS
;-- SOME UTILITY ROUTINES FOR INIT TIME ---------------------------------------
;
;------------------------------------------------------------------------------
CSEGI SEGMENT
ASSUME CS:CSEGI, SS:nothing, ES:nothing, DS:DGROUP
;------------------------------------------------------------------------------
; Set Driver Name
; si = driver name (8 characters)
;------------------------------------------------------------------------------
public SetDriverName
SetDriverName proc
cld
push ds
pop es
push si ;fix up device header
mov di, offset DDHdr1 + 10
mov cx,SIZEOF_DRIVER_NAME
rep movsb
pop si
lea di,RegCaps0.ccap_driver_name ;fix up dcb 0
mov cx,SIZEOF_DRIVER_NAME
rep movsb
ret
SetDriverName endp
;------------------------------------------------------------------------------
; Set Device Name
; si = device name (SIZEOF_DEVICE_NAME characters,null terminated)
;------------------------------------------------------------------------------
public SetDeviceName
SetDeviceName proc
cld
push ds
pop es
lea di,RegCaps0.ccap_device_name ;fix up dcb 0
mov cx,SIZEOF_DEVICE_NAME
.repeat
movsb
.leave <<byte ptr [si]> eq 0>
.loop
ret
SetDeviceName endp
;------------------------------------------------------------------------------
; Set IDC Entry point
; di = device dependent IDC entry point
;------------------------------------------------------------------------------
public SetIDCEntry
SetIDCEntry proc
mov word ptr DDHdr1 + 8,di
ret
SetIDCEntry endp
CR equ 0dh
LF equ 0ah
;*********************** String Compare w/o Case ****************************
;* ENTRY:
;* ds:si => ASCIIZ string 1 ( master )
;* es:di => ASCII string 2 ( to compare )
;* EXIT:
;* ax == 0 strings equal for length of master
;* ax == -1 (FFFF) string 1 less than string 2
;* ax == 1 string 1 greater than string 2
;* es:[di] => next character after match string if ax == 0
;* USES:
;* si, di
;* Direction Flag Cleared
;* DESCRIPTION:
;* Will compare string 2 to string 1. Strings must macth over the whole
;* length of string 1. If string 2 has characters past the end of string
;* 1, then that is still a match
;****************************************************************************
public str_i_cmp
str_i_cmp proc near
; test for end of string 1
sic_loop:
cmp byte ptr [si], 0
jnz sic_not_end
mov ax, 0
jmp sic_done
; compare the current two characters ( after converting to upper case )
sic_not_end:
mov al, es:[di]
inc di
call to_upper
mov ah, al
mov al, [si]
inc si
call to_upper
sub al, ah
je sic_loop
; getting here means string are diffrent
mov ax, 1 ; assume str1 > str2
jnc sic_done ; actually test
mov ax, 0FFFFh ; fix assumtion as it was wrong
sic_done:
ret
str_i_cmp endp
;**************************** Skip Over Whitespace **************************
;* Function: Advance to next non-whitespace character
;* Entry: es:[di] => ascii text
;* Exit: es:[di] => next non-whitespace or end of string
;* Preserves: all except di
;****************************************************************************
public skip_white
skip_white proc near
dec di
sw_loop:
inc di
call is_white
jz sw_loop
; not white space, return
ret
skip_white endp
;************************** Skip To Next Whitespace *************************
;* Function: Advance to next whitespace character
;* Entry: es:[di] => ascii text
;* Exit: es:[di] => next whitespace or end of string
;* Preserves: all except di
;****************************************************************************
public skip_to_white
skip_to_white proc near
push ax
stw_loop:
mov al, es:[di]
cmp al, ' '
jz stw_done
cmp al, CR
jz stw_done
cmp al, LF
jz stw_done
cmp al, 0
jz stw_done
cmp al, 09h ; tab
jz stw_done
; not white space, advance
inc di
jmp stw_loop
stw_done:
pop ax
ret
skip_to_white endp
;************************** Is Whitespace? *************************
;* Function: Test character for whitespace
;* Entry: es:[di] => ascii text
;* Exit: zero flag set if whitespace
;* Preserves: all
;****************************************************************************
public is_white
is_white proc near
push ax
mov al, es:[di]
cmp al, ' '
jz iw_done
cmp al, ','
jz iw_done
cmp al, 09h ; tab
jz iw_done
iw_done:
pop ax
ret
is_white endp
;************************** Is End of Line? *************************
;* Function: Test character for end of line character (CR,LF,0)
;* Entry: es:[di] => ascii text
;* Exit: zero flag set if end of line
;* Preserves: all
;****************************************************************************
public is_endln
is_endln proc near
push ax
mov al, es:[di]
cmp al, CR
jz ie_done
cmp al, LF
jz ie_done
cmp al, 0
jz ie_done
ie_done:
pop ax
ret
is_endln endp
;********************** Convert Character to Upper Case *********************
;* ENTRY:
;* al = char to convert
;* EXIT:
;* al = converted ( if needed) char
;* USES:
;* none
;****************************************************************************
public to_upper
to_upper proc near
cmp al, 'a'
jb tu_done
cmp al, 'z'
ja tu_done
sub al, 'a'-'A'
tu_done:
ret
to_upper endp
;***************************** Get Hex Number *******************************
;* Function: Parse a hex number from an ascii string
;* Entry: es:[di] => ascii text
;* Exit: es:[di] => first non hex character
;* ax value of number
;* Preserves: std C
;****************************************************************************
public get_hex_num
get_hex_num proc near
mov ax, 0
ghn_loop:
mov bl, es:[di]
cmp bl, '0'
jb ghn_exit
cmp bl, '9'
ja ghn_tst_let
sub bl, '0'
jmp ghn_add
ghn_tst_let:
and bl, not ('A' xor 'a') ; convert letter to uppercase
cmp bl, 'A'
jb ghn_exit
cmp bl, 'F'
ja ghn_exit
sub bl, 'A' - 10 ; bl = ( bl - 'A') + 10
ghn_add:
mov cl, 4
shl ax, cl
add al, bl
jmp ghn_adv
ghn_adv:
inc di
jmp ghn_loop
ghn_exit:
ret
get_hex_num endp
;***************************** Get Hex Number *******************************
;* Function: Parse a deciaml number from an ascii string
;* Entry: es:[di] => ascii text
;* Exit: es:[di] => first non hex character
;* ax value of number
;* Preserves: std C
;****************************************************************************
temp equ bp-2
public get_dec_num
get_dec_num proc near
enter 2,0
xor ax,ax
xor bx,bx
mov word ptr [temp],10
gdn_loop:
mov bl, es:[di]
cmp bl, '0'
jb gdn_exit
cmp bl, '9'
ja gdn_exit
sub bl, '0'
gdn_add:
imul word ptr [temp]
add ax, bx
inc di
jmp gdn_loop
gdn_exit:
leave
ret
get_dec_num endp
CSEGI ENDS
END