home *** CD-ROM | disk | FTP | other *** search
- page ,132
- title Sample Device Driver for OS/2 2.0
- subttl Copyright (C) 1992 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.
-
- .386p
- .lall
-
- 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.2.6.307B) -- .....................",13,10
- db " Copyright (C) 1992 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
- DEBUG_HOOK ; Conditionally allow ASDT32 control
- 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
- ret
- BadCmd:
- mov es:[bx].rp_status, PSTAT_DONE + PSTAT_ERROR + PSTAT_UNKCMD
- ret
- Strategy endp
-
- Unsupported proc
- mov ax, PSTAT_ERROR + PSTAT_UNKCMD
- ret
- Unsupported endp
-
- CantDoThat proc
- mov ax, PSTAT_ERROR + PSTAT_GFAIL
- ret
- CantDoThat endp
-
- Open proc
- xor ax, ax
- ret
- Open endp
-
- Close proc
- xor ax, ax
- ret
- Close endp
-
- ;------------------------------------------------------------------------------
- ; This routine processes the IOCTL request
- ;------------------------------------------------------------------------------
-
- BadArg proc
- mov ax, PSTAT_ERROR + PSTAT_BADPARM
- ret
- BadArg endp
-
- public Control
- Control proc
- 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 interrupt 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
- 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
- jc CantDoThat
- mov word ptr es:[bp].DDioctl_ptr+0, bx
- mov word ptr es:[bp].DDioctl_ptr+2, ax
-
- xor ax, ax
- 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
- 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
- ret
- Init endp
-
- code ends
- end