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 >
Assembly Source File  |  1996-07-22  |  14KB  |  402 lines

  1.         page    ,132
  2.         title   Sample Device Driver for OS/2 2.0
  3.         subttl  Copyright (C) 1996 by the IBM Corporation
  4.  
  5. ; This file contains the code for a sample device driver.  The purpose
  6. ; of the device driver is to illustrate the usage of ASDT32.
  7. ;
  8. ; The original code was written 3/92 by Jim Christensen and modified for
  9. ; ASDT32 purposes 4/92 by Dave Evans.  This code modified again in 4/96 for
  10. ; ICAT purposes.
  11.  
  12.         .386p
  13.         .lall
  14.  
  15.         include debequ.inc
  16.         include debmac.inc
  17.  
  18. DEBUG_HOOK      macro
  19.                 int 3           ; Debug hook for ASDT32
  20. endm
  21.  
  22. ; The following hard-coded constants are a kludge.  They give the address
  23. ; of the BIOS data area that holds the number of columns on the screen.  Note
  24. ; that this area is of little use to protect-mode OS/2 2.0 screen handling,
  25. ; but I know that it is always accessible.
  26.  
  27. COLUMNS_SEL     equ 0040h       ; 16-bit seglector to BIOS data area
  28. COLUMNS_OFF     equ 004Ah       ; 16-bit offset to screen column count
  29.  
  30.  
  31. ; This device driver must be installed at system boot time as an OS/2 device
  32. ; driver.  To use this device driver, an OS/2 program must do the following:
  33. ;
  34. ; 1.  DosOpen( "$SAMPDD" )
  35. ;
  36. ; 2.  DosDevIOCtl( NULL, &parms, 0xF0, 0xE0, openHandle )
  37. ;
  38. ; 3.  DosClose( openHandle )
  39. ;
  40. ;     Handle is the 16-bit number returned by DosOpen.
  41.  
  42.  
  43. ; Device Header
  44.  
  45. DEVATTR         equ  1000100010000000b
  46. ;                    |   | |||
  47. ;                    |   | Level (DOS 5.0)
  48. ;                    |   Accepts Open/Close/Removable Media
  49. ;                    Device is a character device
  50.  
  51. DevHeader       struc
  52. dh_next         dd ?
  53. dh_attr         dw DEVATTR
  54. dh_strategy     dw ?
  55. dh_1            dw 0
  56. dh_name         db "        "
  57. dh_2            db 8 dup(0)
  58. DevHeader       ends
  59.  
  60.  
  61. ; Request Packet
  62.  
  63. RPMAXLEN        equ 18          ; Maximum size of packet data
  64.  
  65. ReqPacket       struc
  66. rp_len          db ?            ; Length in bytes of packet
  67. rp_unit         db ?            ; Subunit number of block device
  68. rp_cmd          db ?            ; Command code
  69. rp_status       dw ?            ; Status word
  70. rp_doslink      dd ?            ; Reserved
  71. rp_devlink      dd ?            ; Device multiple-request link
  72. rp_data         db RPMAXLEN dup (?)
  73.                                 ; Data pertaining to specific packet
  74. ReqPacket       ends
  75.  
  76. ; Values for the rp_status field
  77.  
  78. PSTAT_ERROR     equ   8000h     ; Error status
  79. PSTST_BUSY      equ   0200h     ; Busy status
  80. PSTAT_DONE      equ   0100h     ; Command complete
  81. PSTAT_UNKCMD    equ   0003h     ; Unknown command
  82. PSTAT_GFAIL     equ   000Ch     ; General failure
  83. PSTAT_BADPARM   equ   0013h     ; Invalid parameter
  84.  
  85. ; Subfields of the rp_data field
  86.  
  87. InitDevHlp      equ dword ptr rp_data+1 ; Pointer to DevHlp commands
  88. InitEndCode     equ  word ptr rp_data+1 ; Code segment size
  89. InitEndData     equ  word ptr rp_data+3 ; Data segment size
  90. IOaddr          equ dword ptr rp_data+1 ; Transfer address (32 bits)
  91. IOaddrLow       equ  word ptr rp_data+1 ; Transfer address (low 16 bits)
  92. IOaddrHigh      equ  word ptr rp_data+3 ; Transfer address (high 16 bits)
  93. IOcount         equ  word ptr rp_data+5 ; Count of bytes/sectors
  94.  
  95. IoctlFcat       equ  byte ptr rp_data+0 ; Function category
  96. IoctlFcode      equ  byte ptr rp_data+1 ; Function code
  97. IoctlParmAddr   equ dword ptr rp_data+2 ; Parameter buffer address
  98. IoctlDataAddr   equ dword ptr rp_data+6 ; Data buffer address
  99.  
  100. ; The values expected by this device driver for an ioctl call are:
  101. IOCTL_CATEGORY         equ 0E0h
  102. IOCTL_FUNCTION_INIT    equ 0F0h
  103.  
  104. DDioctl_Request  struc
  105. DDioctl_ptr      dd ?   ; Returned address of BIOS screen column count
  106. DDioctl_Request  ends
  107.  
  108.  
  109. ; Command Code for DevHelp Functions
  110.  
  111. DevHlp_SemRequest       equ  6  ; Claim a semaphore
  112. DevHlp_SemClear         equ  7  ; Release a semaphore
  113. DevHlp_QueueInit        equ 15  ; Init/Clear char queue
  114. DevHlp_QueueFlush       equ 16  ; Flush queue
  115. DevHlp_QueueWrite       equ 17  ; Put a char in the queue
  116. DevHlp_QueueRead        equ 18  ; Get a char from the queue
  117. DevHlp_Lock             equ 19  ; Lock segment into storage
  118. DevHlp_Unlock           equ 20  ; Unlock segment in storage
  119. DevHlp_PhysToVirt       equ 21  ; Convert physical address to virtual
  120. DevHlp_VirtToPhys       equ 22  ; Convert virtual address to physical
  121. DevHlp_PhysToUVirt      equ 23  ; Convert physical to user virtual
  122. DevHlp_AllocPhys        equ 24  ; Allocate physical memory
  123. DevHlp_SetIRQ           equ 27  ; Set a hardware interrupt vector
  124. DevHlp_SetTimer         equ 29  ; Set timer request handler
  125. DevHlp_MonitorCreate    equ 31  ; Create a monitor
  126. DevHlp_Register         equ 32  ; Install a monitor
  127. DevHlp_DeRegister       equ 33  ; Remove a monitor
  128. DevHlp_MonWrite         equ 34  ; Pass data records to monitor
  129. DevHlp_MonFlush         equ 35  ; Remove all data from stream
  130. DevHlp_GetDOSVar        equ 36  ; Return pointer to DOS variable
  131. DevHlp_VerifyAccess     equ 39  ; Verify access to virtual memory
  132. DevHlp_AllocGDTSelector equ 45  ; Allocate GDT Descriptors
  133. DevHlp_EOI              equ 49  ; Issue an End-of-Interrupt
  134. DevHlp_UnPhysToVirt     equ 50  ; Done with PhysToVirt address
  135.  
  136. ;------------------------------------------------------------------------------
  137. ; Data Segment
  138. ;------------------------------------------------------------------------------
  139.  
  140. data    segment use16 public 'DATA'
  141.  
  142.         DevHeader <-1,, code:Strategy,, "$SAMPDD">
  143.  
  144.  
  145. router_table    label word
  146.         dw      Init            ; Command code 0: init
  147.         dw      Unsupported     ; Command code 1: media check
  148.         dw      Unsupported     ; Command code 2: build BPB
  149.         dw      Unsupported     ; Command code 3: reserved
  150.         dw      Unsupported     ; Command code 4: read (input)
  151.         dw      Unsupported     ; Command code 5: nondestructive read no wait
  152.         dw      Unsupported     ; Command code 6: input status
  153.         dw      Unsupported     ; Command code 7: input flush
  154.         dw      Unsupported     ; Command code 8: write (output)
  155.         dw      Unsupported     ; Command code 9: write with verify
  156.         dw      Unsupported     ; Command code 10: output status
  157.         dw      Unsupported     ; Command code 11: output flush
  158.         dw      Unsupported     ; Command code 12: reserved
  159.         dw      Open            ; Command code 13: device open
  160.         dw      Close           ; Command code 14: device close
  161.         dw      Unsupported     ; Command code 15: removable media
  162.         dw      Control         ; Command code 16: generic ioctl
  163.         dw      Unsupported     ; Command code 17: reset media
  164.         dw      Unsupported     ; Command code 18: get logical drive map
  165.         dw      Unsupported     ; Command code 19: set logical drive map
  166.         dw      Unsupported     ; Command code 20: deinstall
  167.         dw      Unsupported     ; Command code 21: reserved
  168.         dw      Unsupported     ; Command code 22: partitionable fixed disks
  169.         dw      Unsupported     ; Command code 23: get fixed disk/log.unit map
  170.         dw      Unsupported     ; Command code 24: reserved
  171.         dw      Unsupported     ; Command code 25: reserved
  172.         dw      Unsupported     ; Command code 26: reserved
  173.  
  174. RTABLE_SIZE     equ ($ - router_table) / 2
  175.  
  176. ;------------------------------------------------------------------------------
  177. ; Variables
  178. ;------------------------------------------------------------------------------
  179.  
  180.         public  DevHlp
  181. DevHlp          dd 0            ; Entry point for DevHlp routines
  182.         public  rp
  183. rp              dd 0            ; Request packet address
  184.  
  185.         public  physDS
  186. physDS          dd 0
  187.  
  188. EndOfData       equ $           ; Rest of data released after initialization
  189.  
  190.  
  191.         public  InitMsg
  192. InitMsg         equ $
  193.  db 13,10
  194.  db "SAMPLEDD.SYS installed (v.42) -- IBM Internal Use Only",13,10
  195.  db "     Copyright (C) 1996 by the IBM Corporation",13,10
  196. InitMsgLen      equ $-InitMsg
  197.  
  198. InitWord        dw 0
  199.  
  200. data    ends
  201. ;------------------------------------------------------------------------------
  202.  
  203.         extrn   DosWrite:far
  204. code    segment use16 public 'CODE'
  205.         assume  cs:code, ds:data
  206.  
  207.         public  Strategy
  208. Strategy        proc far
  209.         push    bp                             ; establish frame for call stack
  210.         mov     bp,sp                          ;   unwinds w/ ICAT
  211.  
  212.         mov     word ptr ds:rp+0, bx
  213.         mov     word ptr ds:rp+2, es
  214.         mov     al, es:[bx].rp_cmd
  215.         cmp     al, RTABLE_SIZE
  216.         ja      BadCmd
  217.  
  218.         xor     ah, ah
  219.         shl     ax, 1
  220.         xchg    ax, di
  221.         xor     ax, ax
  222.         call    router_table [di]
  223.         les     bx, ds:rp
  224.         or      ax, PSTAT_DONE
  225.         mov     es:[bx].rp_status, ax
  226.  
  227.         leave
  228.         ret
  229. BadCmd:
  230.         mov     es:[bx].rp_status, PSTAT_DONE + PSTAT_ERROR + PSTAT_UNKCMD
  231.  
  232.         leave
  233.         ret
  234. Strategy        endp
  235.  
  236.         public  Unsupported
  237. Unsupported     proc
  238.         push    bp
  239.         mov     bp,sp
  240.  
  241.         mov     ax, PSTAT_ERROR + PSTAT_UNKCMD
  242.  
  243.         leave
  244.         ret
  245. Unsupported     endp
  246.  
  247. CantDoThat      proc
  248.         mov     ax, PSTAT_ERROR + PSTAT_GFAIL
  249.  
  250.         leave
  251.         ret
  252. CantDoThat      endp
  253.  
  254. DefProc subrWFrame, NEAR, PUBLIC, C
  255. ArgVar  arg1,      WORD
  256. ArgVar  arg2,      WORD
  257. ArgVar  arg3,      WORD
  258.  
  259.  
  260. BeginProc
  261.         SaveReg <eax,ecx,edx>
  262.  
  263.         mov  ax, arg1
  264.         mov  cx, arg2
  265.         mov  dx, arg3
  266.  
  267.         RestoreReg <edx,ecx,eax>
  268. EndProc
  269.  
  270.         public  Open
  271. Open            proc
  272.         push    bp
  273.         mov     bp,sp
  274.  
  275.         Ccall   subrWFrame,<ax,bx,cx>   ; call to establish a stack frame
  276.         xor     ax, ax
  277.  
  278.         leave
  279.         ret
  280. Open            endp
  281.  
  282.         public  Close
  283. Close           proc
  284.         push    bp
  285.         mov     bp,sp
  286.  
  287.         xor     ax, ax
  288.  
  289.         leave
  290.         ret
  291. Close           endp
  292.  
  293.  
  294. ;------------------------------------------------------------------------------
  295. ; This routine processes the IOCTL request
  296. ;------------------------------------------------------------------------------
  297.  
  298. public          BadArg
  299. BadArg          proc
  300.         mov     ax, PSTAT_ERROR + PSTAT_BADPARM
  301.  
  302.         leave
  303.         ret
  304. BadArg          endp
  305.  
  306.         public  Control
  307. Control         proc
  308.         push    bp
  309.         mov     bp,sp
  310.  
  311.         cmp     es:[bx].IoctlFcat, IOCTL_CATEGORY
  312.         jne     BadArg
  313.         cmp     es:[bx].IoctlFcode, IOCTL_FUNCTION_INIT
  314.         jne     BadArg
  315.  
  316. ; Make sure the caller has read/write access to the IOCTL parameter area.
  317.  
  318.         les     bx, ds:rp
  319.         mov     di, word ptr es:[bx].IoctlParmAddr + 0
  320.         mov     ax, word ptr es:[bx].IoctlParmAddr + 2
  321.         mov     cx, size DDioctl_Request
  322.         mov     dh, 01          ; Read/write access
  323.         mov     dl, DevHlp_VerifyAccess
  324.         call    [DevHlp]
  325.         jc      BadArg
  326.  
  327. ; Map the BIOS data area for column count into a user segment
  328.  
  329.         push    ds
  330.         push    ds
  331.         pop     es
  332.         mov     ax, COLUMNS_SEL
  333.         mov     ds, ax
  334.         mov     si, COLUMNS_OFF
  335.         mov     dl, DevHlp_VirtToPhys
  336.         call    es:[DevHlp]
  337.         pop     ds
  338.         jc      CantDoThat
  339.         mov     word ptr physDS+0, bx
  340.         mov     word ptr physDS+2, ax
  341.  
  342.         les     bx, ds:rp
  343.         push    bp                          ;preserve due to stack frame
  344.         les     bp, es:[bx].IoctlParmAddr   ;es:bp -> IOCTL parm area
  345.         push    es
  346.         mov     bx, word ptr physDS+0
  347.         mov     ax, word ptr physDS+2
  348.         mov     cx, 2
  349.         mov     dh, 0           ; Read-only access
  350.         mov     dl, DevHlp_PhysToUVirt
  351.         call    [DevHlp]
  352.         mov     ax, es          ; ax:bx = virt addr
  353.         pop     es              ; es:bp -> IOCTL parm area
  354.         jnc     ok              ; carry bit on => error
  355.         pop     bp              ; restore due to stack frame
  356.         jmp     CantDoThat
  357. ok:     mov     word ptr es:[bp].DDioctl_ptr+0, bx
  358.         mov     word ptr es:[bp].DDioctl_ptr+2, ax
  359.         pop     bp              ; restore due to stack frame
  360.  
  361.         xor     ax, ax
  362.  
  363.         leave
  364.         ret
  365. Control         endp
  366.  
  367. EndOfCode       equ $           ; Rest of code released after initialization
  368.  
  369. ;------------------------------------------------------------------------------
  370. ; This initialization code is called just once during system boot.
  371. ;------------------------------------------------------------------------------
  372.         public  Init
  373. Init            proc
  374.         push    bp
  375.         mov     bp,sp
  376.  
  377.         mov     ax, word ptr es:[bx].InitDevHlp + 0
  378.         mov     word ptr DevHlp + 0, ax
  379.         mov     ax, word ptr es:[bx].InitDevHlp + 2
  380.         mov     word ptr DevHlp + 2, ax
  381.  
  382.         push    1               ; Standard output device
  383.         push    ds
  384.         push    offset InitMsg
  385.         push    InitMsgLen
  386.         push    ds
  387.         push    offset InitWord
  388.         call    DosWrite
  389.  
  390.         les     bx, ds:rp
  391.         mov     es:[bx].InitEndCode, offset code:EndOfCode
  392.         mov     es:[bx].InitEndData, offset data:EndOfData
  393.  
  394.         xor     ax, ax
  395.  
  396.         leave
  397.         ret
  398. Init            endp
  399.  
  400. code    ends
  401.         end
  402.