home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / assemblr / mslang / as / driver.asm < prev    next >
Assembly Source File  |  1985-08-28  |  18KB  |  622 lines

  1.         name    driver
  2.         page    55,132
  3.         title   'DRIVER --- installable driver template'
  4.  
  5. ;
  6. ; This is a "template" for a MS-DOS installable device driver.
  7. ; The actual driver subroutines are stubs only and have
  8. ; no effect but to return a non-error "done" status.
  9. ; Ray Duncan
  10. ; Laboratory Microsystems Inc.
  11. ; April 1985
  12.  
  13. code    segment public 'CODE'
  14.  
  15. driver  proc    far
  16.  
  17.         assume  cs:code,ds:code,es:code
  18.  
  19.         org     0
  20.  
  21.  
  22. Max_Cmd equ     15              ; MS-DOS command code maximum
  23.                                 ; this is 15 for MS-DOS 3.x
  24.                                 ; and 12 for MS-DOS 2.x 
  25.  
  26.  
  27. cr      equ     0dh             ; ASCII carriage return
  28. lf      equ     0ah             ; ASCII line feed
  29. eom     equ     '$'             ; end of message signal
  30.  
  31.  
  32.         page
  33. ;
  34. ; Device Driver Header
  35. ;
  36. Header  dd      -1              ;link to next device,-1= end of list
  37.  
  38.         dw      8000h           ;attribute word
  39.                                 ;bit 15=1 for character devices
  40.  
  41.         dw      Strat           ;device "Strategy" entry point
  42.  
  43.         dw      Intr            ;device "Interrupt" entry point
  44.  
  45.         db      'DRIVER  '      ;char device name, 8 char, or
  46.                                 ;if block device, no. of units
  47.                                 ;in first byte followed by 
  48.                                 ;7 don't care bytes     
  49.  
  50.  
  51.  
  52. ; Interpretation of Attribute word:
  53. ; Bit           Significance
  54. ;
  55. ; 15            =1 for character drivers
  56. ; 14            =1 if driver can handle IOCTL
  57. ; 13            =1 if block device & non-IBM format
  58. ; 12            0
  59. ; 11            open/close/RM supported (DOS 3.x)
  60. ; 10            0
  61. ;  9            0
  62. ;  8            0
  63. ;  7            0
  64. ;  6            0
  65. ;  5            0
  66. ;  4            0
  67. ;  3            =1 if CLOCK device
  68. ;  2            =1 if NUL device
  69. ;  1            =1 if Standard Output
  70. ;  0            =1 if Standard Input
  71.  
  72.         page
  73. ;
  74. ; local variables for use by driver
  75. ;
  76. RH_Ptr  dd      ?               ; pointer to request header
  77.                                 ; passed to Strat by BDOS
  78.  
  79. Ident   db      cr,lf,lf
  80.         db      'LMI Example Device Driver 1.0'
  81.         db      cr,lf
  82.         db      'Copyright (c) 1985 '
  83.         db      'Laboratory Microsystems Inc.' 
  84.         db      cr,lf,lf,eom
  85. ;
  86. ; MS-DOS Command Codes dispatch table.
  87. ; The "Interrupt" routine uses this table and the 
  88. ; Command Code supplied in the Request Header to 
  89. ; transfer to the appropriate driver subroutine.
  90.  
  91. Dispatch:
  92.         dw      Init            ;  0 = init driver into system
  93.         dw      Media_Chk       ;  1 = media check on blk dev
  94.         dw      Build_Bpb       ;  2 = build BIOS param block
  95.         dw      Ioctl_Inp       ;  3 = I/O ctrl read from dev
  96.         dw      Input           ;  4 = normal destructive read
  97.         dw      Nd_Input        ;  5 = non-destructive read,no wait
  98.         dw      Inp_Stat        ;  6 = return current input status
  99.         dw      Inp_Flush       ;  7 = flush device input buffers
  100.         dw      Output          ;  8 = normal output to device
  101.         dw      Outp_Vfy        ;  9 = output with verify
  102.         dw      Outp_Stat       ; 10 = return current output status
  103.         dw      Outp_Flush      ; 11 = flush output buffers
  104.         dw      Ioctl_Outp      ; 12 = I/O control output
  105.         dw      Dev_Open        ; 13 = device open      (MS-DOS 3.x)
  106.         dw      Dev_Close       ; 14 = device close     (MS-DOS 3.x)
  107.         dw      Rem_Media       ; 15 = removeable media (MS-DOS 3.x)
  108.         page
  109. ; MS-DOS Request Header structure definition
  110. ;
  111. ; The first 13 bytes of all Request Headers are the same
  112. ; and are referred to as the "Static" part of the Header.
  113. ; The number and meaning of the following bytes varies.
  114. ; In this "Struc" definition we show the Request Header
  115. ; contents for Read and Write calls.
  116. ;
  117. Request struc                   ; request header template structure
  118.         
  119.                                 ; beginning of "Static" portion
  120. Rlength db      ?               ; length of request header
  121. Unit    db      ?               ; unit number for this request
  122. Command db      ?               ; request header's command code
  123. Status  dw      ?               ; driver's return status word
  124. Reserve db      8 dup (?)       ; reserved area
  125.                                 ; end of "Static" portion       
  126.  
  127. Media   db      ?               ; media descriptor byte
  128. Address dd      ?               ; memory address for transfer
  129. Count   dw      ?               ; byte/sector count value
  130. Sector  dw      ?               ; starting sector value
  131.  
  132. Request ends                    ; end of request header template
  133.  
  134. ;
  135. ; Status word is interpreted as follows:
  136. ;
  137. ;  Bit(s)   Significance
  138. ;   15       Error
  139. ;   10-14    Reserved
  140. ;   9        Busy
  141. ;   8        Done
  142. ;   0-7      Error code if bit 15=1
  143.  
  144. ; Predefined BDOS error codes are:
  145. ;   0       Write protect violation
  146. ;   1       Unknown unit
  147. ;   2       Drive not ready
  148. ;   3       Unknown command
  149. ;   4       CRC error
  150. ;   5       Bad drive request structure length
  151. ;   6       Seek error
  152. ;   7       Unknown media
  153. ;   8       Sector not found
  154. ;   9       Printer out of paper
  155. ;   10      Write fault
  156. ;   11      Read fault
  157. ;   12      General failure     
  158. ;   13-14   Reserved
  159. ;   15      Invalid disk change  (MS-DOS 3.x)
  160.  
  161.         page
  162.  
  163. ; Device Driver "Strategy Routine"
  164.  
  165. ; Each time a request is made for this device, the BDOS
  166. ; first calls "Strategy routine",  then immediately calls
  167. ; the "Interrupt routine".  
  168.  
  169. ; The Strategy routine is passed the address of the
  170. ; Request Header in ES:BX, which it saves in a local
  171. ; variable and then returns to the BDOS.
  172.  
  173. Strat   proc    far     
  174.                                 ; save address of Request Header
  175.         mov     word ptr cs:[RH_Ptr],bx
  176.         mov     word ptr cs:[RH_Ptr+2],es
  177.  
  178.         ret                     ; back to BDOS
  179.  
  180. Strat   endp
  181.  
  182.         page
  183.  
  184.  
  185. ; Device Driver "Interrupt Routine"
  186.  
  187. ; This entry point is called by the BDOS immediately after 
  188. ; the call to the "Strategy Routine", which saved the long
  189. ; address of the Request Header in the local variable "RH_Ptr".
  190.  
  191. ; The "Interrupt Routine" uses the Command Code passed in
  192. ; the Request Header to transfer to the appropriate device
  193. ; handling routine.  Each command code routine is responsible
  194. ; for any necessary return information into the Request Header,
  195. ; then transfers to Error or Exit to set the Return Status code.
  196.  
  197. Intr    proc  far
  198.  
  199.         push    ax              ; save general registers 
  200.         push    bx
  201.         push    cx
  202.         push    dx
  203.         push    ds
  204.         push    es
  205.         push    di
  206.         push    si
  207.         push    bp
  208.  
  209.         push    cs              ; make local data addressable
  210.         pop     ds
  211.  
  212.         les     di,[RH_Ptr]     ; ES:DI = Request Header
  213.  
  214.                                 ; get BX = Command Code
  215.         mov     bl,es:[di.Command]
  216.         xor     bh,bh
  217.         cmp     bx,Max_Cmd      ; make sure its legal
  218.         jg      Unk_Command     ; too big, exit with error code
  219.         shl     bx,1            ; form index to Dispatch table
  220.                                 ; and branch to driver routine
  221.         jmp     word ptr [bx+Dispatch]
  222.  
  223.         page
  224.  
  225.  
  226. ; General collection of exit points for the driver routines.
  227.  
  228.  
  229. Unk_Command:                    ; Come here if Command Code too big.
  230.         mov     al,3            ; Sets "Unknown Command" error 
  231.                                 ; code and "Done" bit.
  232.  
  233. Error:                          ; Transfer here with AL = error code.
  234.         mov     ah,81h          ; Sets "Error" and "Done" bits.
  235.         jmp     Exit
  236.  
  237. Done:   mov     ah,1            ; Come here if I/O complete and
  238.                                 ; no error, sets "Done" bit only.
  239.  
  240.  
  241. Exit:                           ; General purpose exit point.
  242.                                 ; Transfer here with AX = 
  243.                                 ; Return Status word to be
  244.                                 ; placed into Request Header.
  245.  
  246.         lds     bx,cs:[RH_Ptr]          ; set status
  247.         mov     ds:[bx.Status],ax
  248.  
  249.         pop     bp              ;restore general registers
  250.         pop     si
  251.         pop     di
  252.         pop     es
  253.         pop     ds
  254.         pop     dx
  255.         pop     cx
  256.         pop     bx
  257.         pop     ax
  258.         ret                     ; back to BDOS
  259.  
  260.         page
  261.  
  262.  
  263. ; Function 1  Media Check
  264.  
  265. ; Block devices only.  Should be a NOP for character devices.
  266. ;
  267. ; This routine is called first by BDOS for a block device transfer,
  268. ; passing current media descriptor byte at Request Header + 
  269. ;
  270. ; Media Check routine sets status word and in addition passes back 
  271. ; return byte at Request Header + 14  as follows:
  272.  
  273. ;    -1  Media has been changed
  274. ;     0  Don't know if media changed
  275. ;     1  Media has not been changed
  276. ;
  277. ; If driver can return 1 or -1, performance is improved because
  278. ; MS-DOS does not need to reread the FAT for each directory access.
  279.  
  280.  
  281. Media_Chk:
  282.  
  283.         jmp     Done
  284.  
  285.         page
  286.  
  287. ;
  288. ; Function 2  Build BIOS Parameter Block
  289. ; Block devices only.  Should be a NOP for character devices.
  290. ;
  291. ; This routine is called by MS-DOS when Media-Changed code is
  292. ; returned by Media Check routine, or if Not Sure code is returned
  293. ; and there are no dirty buffers.
  294. ; Build BPB call receives pointer to one-sector buffer in Address
  295. ; Field of Request Header (offset 14).  If "Non-IBM-Format" bit 
  296. ; in attribute word is zero, the buffer contains the first sector
  297. ; of the FAT including the media identification byte and should not 
  298. ; be altered by the driver.   If the "Non-IBM-Format" bit is set, 
  299. ; the buffer may be used as scratch space.
  300. ;
  301. ; The Build BPB routine sets status and returns a DWORD pointer to 
  302. ; the new Bios Parameter Block at Request Header + 18.
  303. ;
  304.  
  305. Build_Bpb:
  306.  
  307.         jmp     Done
  308.  
  309.         page
  310.  
  311. ;
  312. ; Function 3  I/O Control Read 
  313. ; Only called if IOCTL bit set in Device Header Attribute word.
  314. ;
  315. ; Called with:
  316. ;
  317. ; Request Header + 13  BYTE   Media descriptor byte from DPB
  318. ; Request Header + 14  DWORD  Transfer address
  319. ; Request Header + 18  WORD   byte/sector count
  320. ; Request Header + 20  WORD   starting sector no. (block dev.)
  321. ;
  322. ; Returns the Return Status word set appropriately, and
  323. ; Request Header + 18  WORD   actual bytes or sectors transferred
  324. ; No error check is performed on IOCTL I/O calls.
  325.  
  326. Ioctl_Inp:
  327.  
  328.         jmp     Done
  329.  
  330.         page
  331.  
  332. ;
  333. ; Function 4  Read from Device
  334. ;
  335. ; Called with
  336. ;
  337. ; Request Header + 13  BYTE   Media descriptor byte from DPB
  338. ; Request Header + 14  DWORD  Transfer address
  339. ; Request Header + 18  WORD   byte/sector count
  340. ; Request Header + 20  WORD   starting sector no. (block dev.)
  341. ;
  342. ; Returns the Return Status word set appropriately, and
  343. ; Request Header + 18  WORD   actual bytes or sectors transferred
  344.  
  345. Input: 
  346.  
  347.         jmp     Done
  348.  
  349.         page
  350.  
  351. ;
  352. ; Function 5  Non-destructive Read from Device
  353. ; Character devices only.
  354. ;
  355. ; If Input Status request returns Busy bit=0 (characters 
  356. ; waiting), ; the next character that would be read is returned 
  357. ; at Request Header + 13.  This character is not removed from
  358. ; the Input Buffer.  This basically provides the capability to 
  359. ; "look-ahead" by one character.
  360.  
  361. Nd_Input:
  362.  
  363.         jmp     Done
  364.  
  365.         page
  366.  
  367. ;
  368. ; Function 6  Input Status
  369. ; Character devices only.
  370. ;
  371. ; Sets the Returned Status word:
  372. ; Done bit = 1
  373. ; Busy bit = 1 read request would go to physical device
  374. ;          = 0 characters already in device buffer, read request
  375. ;              would return quickly.
  376. ;
  377. ; MS-DOS assumes all character devices have type-ahead buffer.
  378. ; If device does not have type-ahead buffer, should always
  379. ; return Busy bit=0 so MS-DOS will not hang.
  380.  
  381. Inp_Stat:
  382.  
  383.         jmp     Done
  384.  
  385.         page
  386.  
  387. ;
  388. ; Function 7  Flush Input Buffers
  389. ; Character devices only.
  390. ;
  391. ; Terminate all pending requests, i.e. the Input buffer is
  392. ; emptied.
  393.  
  394. Inp_Flush:
  395.  
  396.         jmp     Done
  397.  
  398.         page
  399.  
  400. ;
  401. ; Function 8  Write to Device
  402. ; Called with
  403. ;
  404. ; Request Header + 13  BYTE   Media descriptor byte from DPB
  405. ; Request Header + 14  DWORD  Transfer address
  406. ; Request Header + 18  WORD   byte/sector count
  407. ; Request Header + 20  WORD   starting sector no. (block dev.)
  408. ;
  409. ; Returns the Return Status word set appropriately, and
  410. ; Request Header + 18  WORD   actual bytes or sectors transferred
  411.  
  412. Output: 
  413.  
  414.         jmp     Done
  415.  
  416.         page
  417.  
  418. ;
  419. ; Function 9  Write with Verify to Device
  420. ; Called with
  421. ;
  422. ; Request Header + 13  BYTE   Media descriptor byte from DPB
  423. ; Request Header + 14  DWORD  Transfer address
  424. ; Request Header + 18  WORD   byte/sector count
  425. ; Request Header + 20  WORD   starting sector no. (block dev.)
  426. ;
  427. ; Returns the Return Status word set appropriately, and
  428. ; Request Header + 18  WORD   actual bytes or sectors transferred
  429.  
  430. Outp_Vfy: 
  431.  
  432.         jmp     Done
  433.  
  434.         page
  435.  
  436. ;
  437. ; Function 10  Output Status
  438. ;
  439. ; Character devices only.
  440. ;
  441. ; Sets the Returned Status word:
  442. ; Done bit = 1
  443. ; Busy bit = 1 write request would wait for completion of
  444. ;              current request
  445. ;          = 0 device idle, write request would start immediately.
  446. ;
  447.  
  448. Outp_Stat:
  449.  
  450.         jmp     Done
  451.  
  452.         page
  453.  
  454. ;
  455. ; Function 11  Flush Output Buffers
  456. ; Character devices only.
  457. ;
  458. ; Terminate pending requests.  The output buffer, if any,
  459. ; is emptied.
  460.  
  461. Outp_Flush:
  462.  
  463.         jmp     Done
  464.  
  465.         page
  466.  
  467. ;
  468. ; Function 12  I/O Control Write 
  469. ; Only called if IOCTL bit in Device Header Attribute word is set.
  470. ;
  471. ; Called with
  472. ;
  473. ; Request Header + 13  BYTE   Media descriptor byte from DPB
  474. ; Request Header + 14  DWORD  Transfer address
  475. ; Request Header + 18  WORD   byte/sector count
  476. ; Request Header + 20  WORD   starting sector no. (block dev.)
  477. ;
  478. ; Returns the Return Status word set appropriately, and
  479. ; Request Header + 18  WORD   actual bytes or sectors transferred
  480. ;
  481. ; No error check is performed on IOCTL calls.
  482.  
  483. Ioctl_Outp:
  484.  
  485.         jmp     Done
  486.  
  487.         page
  488.  
  489. ;
  490. ; Function 13  Device Open
  491. ;
  492. ; MS-DOS version 3.0 and above only.
  493. ; Only called if OPEN/CLOSE/RM bit set in Attribute word.
  494. ; May be used to manage local buffering.  Reference count
  495. ; is incremented keeping track of number of open files on
  496. ; the device.  On character devices can be used to send
  497. ; device initialization string, which can be set by IOCTL 
  498. ; Write.  Note that CON AUX and PRN devices are always open.
  499. ;
  500. ; Returns the Return Status word set to "Done".
  501. ;
  502. Dev_Open:
  503.  
  504.         jmp     Done
  505.  
  506.         page
  507.  
  508. ;
  509. ; Function 14  Device Close
  510. ;
  511. ; MS-DOS version 3.0 and above only.
  512. ; Only called if OPEN/CLOSE/RM bit set in Attribute word.
  513. ; May be used to manage local buffering.  Reference count
  514. ; is decremented keeping track of number of open files on
  515. ; the device; when count reaches zero all files have been closed 
  516. ; and the driver should flush buffers as user may change disks.
  517. ; On character devices can be used to send device post-I/O
  518. ; string such as a form feed, which can be set by IOCTL 
  519. ; Write.  Note that CON AUX and PRN devices are never closed.
  520. ;
  521. ; Returns the Return Status word set to "Done".
  522. ;
  523. Dev_Close:
  524.  
  525.         jmp     Done
  526.  
  527.         page
  528.  
  529. ;
  530. ; Function 15  Removeable Media
  531. ;
  532. ; MS-DOS version 3.0 and above only.
  533. ; Only called if OPEN/CLOSE/RM bit set in Attribute word
  534. ;    and device type is block.
  535. ;
  536. ; Returns the Return Status word set to "Done" and 
  537. ; Busy bit = 1 if media is non-removable.  
  538. ;          = 0 if media is removable.
  539. ;
  540. Rem_Media:
  541.  
  542.         jmp     Done
  543.  
  544.  
  545.         page
  546.  
  547. ; This Initialization code for the driver is called only
  548. ; once when the driver is loaded.  It is responsible for
  549. ; initializing the hardware, setting up any necessary 
  550. ; interrupt vectors, and it must return the address
  551. ; of the first free memory after the driver to the BDOS.
  552. ; If it is a block device driver, Init must also return the 
  553. ; address of the Bios Parameter Block pointer array; if all 
  554. ; units are the same, all pointers can point to the same BPB.
  555. ; Only MS-DOS services 01-0CH and 30H can be called by the 
  556. ; Initialization function. 
  557. ;
  558. ; In this example, Init returns its own address to the DOS as 
  559. ; the start of free memory after the driver, so that the memory 
  560. ; occupied by INIT will be reclaimed after it is finished 
  561. ; with its work.  
  562. ;
  563. ; Called with:
  564. ;
  565. ; Request Header + 18  DWORD pointer to the character after the "="
  566. ;                            on the CONFIG.SYS line that loaded 
  567. ;                            driver; this information is read only.
  568. ;                  22  BYTE  drive letter for first unit of a 
  569. ;                            block driver (0=A 1=B etc)
  570. ;                            (MS-DOS 3.x only)   
  571. ;
  572. ; Returns:
  573. ; Request Header + 13  BYTE  Number of units (block devices only)
  574. ;                + 14  DWORD address of first free memory above driver
  575. ;                + 18  DWORD BPB pointer array (block devices only)     
  576. ;
  577.  
  578. Init:                           ; Function 0
  579.                                 ; initialize device driver
  580.  
  581.         push    es              ; push Request Header addr
  582.         push    di
  583.  
  584.         mov     ah,9            ; print sign-on message
  585.         mov     dx,offset Ident
  586.         int     21h
  587.  
  588.         pop     di              ; restore Request Header addr
  589.         pop     es
  590.  
  591.                                 ; set first usable memory addr.
  592.         mov     word ptr es:[di.Address],offset Init
  593.         mov     word ptr es:[di.Address+2],cs
  594.  
  595.         jmp     Done
  596.  
  597.  
  598. Intr    endp
  599.  
  600.  
  601. Driver  endp
  602.  
  603. code    ends
  604.         
  605.         end     
  606.