home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
icat.zip
/
icatos2.zip
/
icatos2
/
sample
/
SAMPLEDD.ASM
< prev
next >
Wrap
Assembly Source File
|
1996-07-22
|
14KB
|
402 lines
page ,132
title Sample Device Driver for OS/2 2.0
subttl Copyright (C) 1996 by the IBM Corporation
; This file contains the code for a sample device driver. The purpose
; of the device driver is to illustrate the usage of ASDT32.
;
; The original code was written 3/92 by Jim Christensen and modified for
; ASDT32 purposes 4/92 by Dave Evans. This code modified again in 4/96 for
; ICAT purposes.
.386p
.lall
include debequ.inc
include debmac.inc
DEBUG_HOOK macro
int 3 ; Debug hook for ASDT32
endm
; The following hard-coded constants are a kludge. They give the address
; of the BIOS data area that holds the number of columns on the screen. Note
; that this area is of little use to protect-mode OS/2 2.0 screen handling,
; but I know that it is always accessible.
COLUMNS_SEL equ 0040h ; 16-bit seglector to BIOS data area
COLUMNS_OFF equ 004Ah ; 16-bit offset to screen column count
; This device driver must be installed at system boot time as an OS/2 device
; driver. To use this device driver, an OS/2 program must do the following:
;
; 1. DosOpen( "$SAMPDD" )
;
; 2. DosDevIOCtl( NULL, &parms, 0xF0, 0xE0, openHandle )
;
; 3. DosClose( openHandle )
;
; Handle is the 16-bit number returned by DosOpen.
; Device Header
DEVATTR equ 1000100010000000b
; | | |||
; | | Level (DOS 5.0)
; | Accepts Open/Close/Removable Media
; Device is a character device
DevHeader struc
dh_next dd ?
dh_attr dw DEVATTR
dh_strategy dw ?
dh_1 dw 0
dh_name db " "
dh_2 db 8 dup(0)
DevHeader ends
; Request Packet
RPMAXLEN equ 18 ; Maximum size of packet data
ReqPacket struc
rp_len db ? ; Length in bytes of packet
rp_unit db ? ; Subunit number of block device
rp_cmd db ? ; Command code
rp_status dw ? ; Status word
rp_doslink dd ? ; Reserved
rp_devlink dd ? ; Device multiple-request link
rp_data db RPMAXLEN dup (?)
; Data pertaining to specific packet
ReqPacket ends
; Values for the rp_status field
PSTAT_ERROR equ 8000h ; Error status
PSTST_BUSY equ 0200h ; Busy status
PSTAT_DONE equ 0100h ; Command complete
PSTAT_UNKCMD equ 0003h ; Unknown command
PSTAT_GFAIL equ 000Ch ; General failure
PSTAT_BADPARM equ 0013h ; Invalid parameter
; Subfields of the rp_data field
InitDevHlp equ dword ptr rp_data+1 ; Pointer to DevHlp commands
InitEndCode equ word ptr rp_data+1 ; Code segment size
InitEndData equ word ptr rp_data+3 ; Data segment size
IOaddr equ dword ptr rp_data+1 ; Transfer address (32 bits)
IOaddrLow equ word ptr rp_data+1 ; Transfer address (low 16 bits)
IOaddrHigh equ word ptr rp_data+3 ; Transfer address (high 16 bits)
IOcount equ word ptr rp_data+5 ; Count of bytes/sectors
IoctlFcat equ byte ptr rp_data+0 ; Function category
IoctlFcode equ byte ptr rp_data+1 ; Function code
IoctlParmAddr equ dword ptr rp_data+2 ; Parameter buffer address
IoctlDataAddr equ dword ptr rp_data+6 ; Data buffer address
; The values expected by this device driver for an ioctl call are:
IOCTL_CATEGORY equ 0E0h
IOCTL_FUNCTION_INIT equ 0F0h
DDioctl_Request struc
DDioctl_ptr dd ? ; Returned address of BIOS screen column count
DDioctl_Request ends
; Command Code for DevHelp Functions
DevHlp_SemRequest equ 6 ; Claim a semaphore
DevHlp_SemClear equ 7 ; Release a semaphore
DevHlp_QueueInit equ 15 ; Init/Clear char queue
DevHlp_QueueFlush equ 16 ; Flush queue
DevHlp_QueueWrite equ 17 ; Put a char in the queue
DevHlp_QueueRead equ 18 ; Get a char from the queue
DevHlp_Lock equ 19 ; Lock segment into storage
DevHlp_Unlock equ 20 ; Unlock segment in storage
DevHlp_PhysToVirt equ 21 ; Convert physical address to virtual
DevHlp_VirtToPhys equ 22 ; Convert virtual address to physical
DevHlp_PhysToUVirt equ 23 ; Convert physical to user virtual
DevHlp_AllocPhys equ 24 ; Allocate physical memory
DevHlp_SetIRQ equ 27 ; Set a hardware interrupt vector
DevHlp_SetTimer equ 29 ; Set timer request handler
DevHlp_MonitorCreate equ 31 ; Create a monitor
DevHlp_Register equ 32 ; Install a monitor
DevHlp_DeRegister equ 33 ; Remove a monitor
DevHlp_MonWrite equ 34 ; Pass data records to monitor
DevHlp_MonFlush equ 35 ; Remove all data from stream
DevHlp_GetDOSVar equ 36 ; Return pointer to DOS variable
DevHlp_VerifyAccess equ 39 ; Verify access to virtual memory
DevHlp_AllocGDTSelector equ 45 ; Allocate GDT Descriptors
DevHlp_EOI equ 49 ; Issue an End-of-Interrupt
DevHlp_UnPhysToVirt equ 50 ; Done with PhysToVirt address
;------------------------------------------------------------------------------
; Data Segment
;------------------------------------------------------------------------------
data segment use16 public 'DATA'
DevHeader <-1,, code:Strategy,, "$SAMPDD">
router_table label word
dw Init ; Command code 0: init
dw Unsupported ; Command code 1: media check
dw Unsupported ; Command code 2: build BPB
dw Unsupported ; Command code 3: reserved
dw Unsupported ; Command code 4: read (input)
dw Unsupported ; Command code 5: nondestructive read no wait
dw Unsupported ; Command code 6: input status
dw Unsupported ; Command code 7: input flush
dw Unsupported ; Command code 8: write (output)
dw Unsupported ; Command code 9: write with verify
dw Unsupported ; Command code 10: output status
dw Unsupported ; Command code 11: output flush
dw Unsupported ; Command code 12: reserved
dw Open ; Command code 13: device open
dw Close ; Command code 14: device close
dw Unsupported ; Command code 15: removable media
dw Control ; Command code 16: generic ioctl
dw Unsupported ; Command code 17: reset media
dw Unsupported ; Command code 18: get logical drive map
dw Unsupported ; Command code 19: set logical drive map
dw Unsupported ; Command code 20: deinstall
dw Unsupported ; Command code 21: reserved
dw Unsupported ; Command code 22: partitionable fixed disks
dw Unsupported ; Command code 23: get fixed disk/log.unit map
dw Unsupported ; Command code 24: reserved
dw Unsupported ; Command code 25: reserved
dw Unsupported ; Command code 26: reserved
RTABLE_SIZE equ ($ - router_table) / 2
;------------------------------------------------------------------------------
; Variables
;------------------------------------------------------------------------------
public DevHlp
DevHlp dd 0 ; Entry point for DevHlp routines
public rp
rp dd 0 ; Request packet address
public physDS
physDS dd 0
EndOfData equ $ ; Rest of data released after initialization
public InitMsg
InitMsg equ $
db 13,10
db "SAMPLEDD.SYS installed (v.42) -- IBM Internal Use Only",13,10
db " Copyright (C) 1996 by the IBM Corporation",13,10
InitMsgLen equ $-InitMsg
InitWord dw 0
data ends
;------------------------------------------------------------------------------
extrn DosWrite:far
code segment use16 public 'CODE'
assume cs:code, ds:data
public Strategy
Strategy proc far
push bp ; establish frame for call stack
mov bp,sp ; unwinds w/ ICAT
mov word ptr ds:rp+0, bx
mov word ptr ds:rp+2, es
mov al, es:[bx].rp_cmd
cmp al, RTABLE_SIZE
ja BadCmd
xor ah, ah
shl ax, 1
xchg ax, di
xor ax, ax
call router_table [di]
les bx, ds:rp
or ax, PSTAT_DONE
mov es:[bx].rp_status, ax
leave
ret
BadCmd:
mov es:[bx].rp_status, PSTAT_DONE + PSTAT_ERROR + PSTAT_UNKCMD
leave
ret
Strategy endp
public Unsupported
Unsupported proc
push bp
mov bp,sp
mov ax, PSTAT_ERROR + PSTAT_UNKCMD
leave
ret
Unsupported endp
CantDoThat proc
mov ax, PSTAT_ERROR + PSTAT_GFAIL
leave
ret
CantDoThat endp
DefProc subrWFrame, NEAR, PUBLIC, C
ArgVar arg1, WORD
ArgVar arg2, WORD
ArgVar arg3, WORD
BeginProc
SaveReg <eax,ecx,edx>
mov ax, arg1
mov cx, arg2
mov dx, arg3
RestoreReg <edx,ecx,eax>
EndProc
public Open
Open proc
push bp
mov bp,sp
Ccall subrWFrame,<ax,bx,cx> ; call to establish a stack frame
xor ax, ax
leave
ret
Open endp
public Close
Close proc
push bp
mov bp,sp
xor ax, ax
leave
ret
Close endp
;------------------------------------------------------------------------------
; This routine processes the IOCTL request
;------------------------------------------------------------------------------
public BadArg
BadArg proc
mov ax, PSTAT_ERROR + PSTAT_BADPARM
leave
ret
BadArg endp
public Control
Control proc
push bp
mov bp,sp
cmp es:[bx].IoctlFcat, IOCTL_CATEGORY
jne BadArg
cmp es:[bx].IoctlFcode, IOCTL_FUNCTION_INIT
jne BadArg
; Make sure the caller has read/write access to the IOCTL parameter area.
les bx, ds:rp
mov di, word ptr es:[bx].IoctlParmAddr + 0
mov ax, word ptr es:[bx].IoctlParmAddr + 2
mov cx, size DDioctl_Request
mov dh, 01 ; Read/write access
mov dl, DevHlp_VerifyAccess
call [DevHlp]
jc BadArg
; Map the BIOS data area for column count into a user segment
push ds
push ds
pop es
mov ax, COLUMNS_SEL
mov ds, ax
mov si, COLUMNS_OFF
mov dl, DevHlp_VirtToPhys
call es:[DevHlp]
pop ds
jc CantDoThat
mov word ptr physDS+0, bx
mov word ptr physDS+2, ax
les bx, ds:rp
push bp ;preserve due to stack frame
les bp, es:[bx].IoctlParmAddr ;es:bp -> IOCTL parm area
push es
mov bx, word ptr physDS+0
mov ax, word ptr physDS+2
mov cx, 2
mov dh, 0 ; Read-only access
mov dl, DevHlp_PhysToUVirt
call [DevHlp]
mov ax, es ; ax:bx = virt addr
pop es ; es:bp -> IOCTL parm area
jnc ok ; carry bit on => error
pop bp ; restore due to stack frame
jmp CantDoThat
ok: mov word ptr es:[bp].DDioctl_ptr+0, bx
mov word ptr es:[bp].DDioctl_ptr+2, ax
pop bp ; restore due to stack frame
xor ax, ax
leave
ret
Control endp
EndOfCode equ $ ; Rest of code released after initialization
;------------------------------------------------------------------------------
; This initialization code is called just once during system boot.
;------------------------------------------------------------------------------
public Init
Init proc
push bp
mov bp,sp
mov ax, word ptr es:[bx].InitDevHlp + 0
mov word ptr DevHlp + 0, ax
mov ax, word ptr es:[bx].InitDevHlp + 2
mov word ptr DevHlp + 2, ax
push 1 ; Standard output device
push ds
push offset InitMsg
push InitMsgLen
push ds
push offset InitWord
call DosWrite
les bx, ds:rp
mov es:[bx].InitEndCode, offset code:EndOfCode
mov es:[bx].InitEndData, offset data:EndOfData
xor ax, ax
leave
ret
Init endp
code ends
end