home *** CD-ROM | disk | FTP | other *** search
- ; devhlp.asm -- to produce DEVHLP.SYS
- ; cf. template in MSJ, March 1988
- ; Andrew Schulman, December 1988
-
- ; DEF file:
- ; LIBRARY DEVHLP
- ; DESCRIPTION 'DEVHLP.SYS (c) Andrew Schulman 1988'
- ; PROTMODE
-
- ; masm devhlp && link devhlp,devhlp.sys,,\msc\lib\doscalls,devhlp.def
-
- ; put in config.sys:
- ; device=devhlp.sys
-
- ; access with DosOpen ("DEVHLPXX"), DosDevIOCTL (category 128)
-
- ; make sure this works in real mode -- possibly use as bridge for OS/2
- ; programs to call real-mode code?
-
- ; make sure can be used by multiple apps at same time
-
- .286p
-
- maxcmd equ 26
- stdout equ 1
- cr equ 0dh
- lf equ 0ah
-
- ; the only specific DevHlp that DEVHLP.SYS should know about
- VerifyAccess equ 27h
-
- ioctlpkt struc
- db 13 dup(?) ; header
- cat db ? ; category
- fun db ? ; function
- param dd ? ; param area
- dataptr dd ? ; data area
- ioctlpkt ends
-
- ; typedef struct {
- ; USHORT ax,bx,cx,dx,si,di,ds,es;
- ; FLAGS flags;
- ; } REGS;
-
- regs struc
- regs_ax dw ?
- regs_bx dw ?
- regs_cx dw ?
- regs_dx dw ?
- regs_si dw ?
- regs_di dw ?
- regs_ds dw ?
- regs_es dw ?
- regs_flags dw ?
- regs ends
-
- regs_size equ 18
-
- dgroup group _DATA
-
- _DATA segment word public 'DATA'
-
- header dd -1
- dw 8880h
- dw Strat
- dw 0
- db 'DEVHLPXX'
- db 8 dup (0)
-
- DevHlp dd 0
-
- dispch dw Init ; 0 -- Init
- dw Error ; 1
- dw Error ; 2
- dw Error ; 3
- dw Error ; 4
- dw Error ; 5
- dw Error ; 6
- dw Error ; 7
- dw Error ; 8
- dw Error ; 9
- dw Error ; 10
- dw Error ; 11
- dw Error ; 12
- dw DevOp ; 13 -- DevOpen
- dw DevOp ; 14 -- DevClose
- dw Error ; 15
- dw GenIOCtl ; 16 -- DevIOCtl
- dw Error ; 17
- dw Error ; 18
- dw Error ; 19
- dw Error ; 20
- dw Error ; 21
- dw Error ; 22
- dw Error ; 23
- dw Error ; 24
- dw Error ; 25
- dw Error ; 26
-
- Ident db ? ; ?????
-
- _DATA ends
-
- _TEXT segment word public 'CODE'
-
- assume cs:_TEXT,ds:DGROUP,es:NOTHING
-
- Strat proc far
- mov di,es:[bx+2]
- and di,0ffh
- cmp di,maxcmd
- jle Strat1
- call Error
- jmp short Strat2
- Strat1: add di,di
- call word ptr [di+dispch]
- Strat2: mov word ptr es:[bx+3],ax ; set request header status
- ret
- Strat endp
-
- ; used by DevOpen and DevClose
- DevOp proc near
- mov ax,0100h
- ret
- DevOp endp
-
- ;; use category #128, function 0x60 (bitmapped function codes!)
- ;; entry point for app access to DevHlp
- ;; INPUT: regs struct (using only ax,bx,cx,dx,di)
- ;; OUTPUT: regs struct (using only ax,bx,es,ds,si,di,flags)
- ;; GenIOCtl is a completely ignorant data pass-through. Knows nothing
- ;; about any specific DevHlp (except VerifyAccess, which it should use
- ;; for its own purposes). Just passes along registers (including DX,
- ;; which includes the DevHlp number).
- ;; The calling app must piece together output, just as in int86() function
- ;; in C for MS-DOS. Note that GenIOCtl doesn't even look at flags --
- ;; just passes them back for the app to inspect.
- ;; essentially, this is Remote Procedure Call via packets
-
- GenIOCtl proc near
-
- push es
- push bx
-
- mov ax,8101h ; assume error
-
- cmp es:[bx].cat,128
- jne done
- mov ch,es:[bx].fun
- cmp ch,60h
- je Op_DevHlp
- ; other functions could go here
- jmp short done
-
- Op_DevHlp:
- ; verify user's access:
- ; VerifyAccess will shut down user's app in the event of error,
- ; We could use VERR, VERW, and LSL, but these won't work
- ; in real-mode, and the device driver must work in real mode too!
- mov ax,word ptr es:[bx+17] ; selector
- mov di,word ptr es:[bx+15] ; offset
- mov cx,regs_size ; length to be read
- mov dh,0 ; read
- mov dl,VerifyAccess
- call DevHlp
- jc fini ; if carry flag set
-
- mov ax,word ptr es:[bx+21] ; selector
- mov di,word ptr es:[bx+19] ; offset
- mov cx,regs_size ; length to be written
- mov dh,1 ; read/write
- mov dl,VerifyAccess
- call DevHlp
- jc fini
-
- push es ; going to be bashed!
- push bx
-
- ; get the parameters for DevHlp from regs
- ; need some way to possibly pass in ds and es??
- push ds ; NB!!!!
- lds di,es:[bx].param
- mov ax,ds:[di].regs_ax
- mov bx,ds:[di].regs_bx
- mov cx,ds:[di].regs_cx
- mov dx,ds:[di].regs_dx
- mov di,ds:[di].regs_di
- pop ds
-
- ; here it is, the whole point of this exercise!
- call DevHlp
-
- ; save ES:BX to put in out-regs
- mov cx,es
- mov dx,bx
-
- ; get back old ES:BX
- pop bx
- pop es
-
- ; save FLAGS, SI, DS on stack
- pushf
- push si
- push ds
-
- ; set up regs to return to the app
- lds si,es:[bx].dataptr
- mov ds:[si].regs_ax,ax
- pop ds:[si].regs_ds
- pop ds:[si].regs_si
- pop ds:[si].regs_flags
- mov ds:[si].regs_bx,dx
- mov ds:[si].regs_es,cx
- mov ds:[si].regs_di,di
-
- fini:
- mov ax,0100h ; no error
- done:
- pop bx
- pop es
- ret
- GenIOCtl endp
-
- Error proc near
- mov ax,8103h
- ret
- Error endp
-
- Init proc near
- mov ax,es:[bx+14]
- mov word ptr DevHlp,ax
- mov ax,es:[bx+16]
- mov word ptr DevHlp+2,ax
-
- mov word ptr es:[bx+14],offset _TEXT:Init
- mov word ptr es:[bx+16],offset DGROUP:Ident
-
- mov ax,0100h
- ret
- Init endp
-
- _TEXT ends
-
- end
-