home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PROGRAMS / UTILS / DOS_HELP / ADVMSDOS.ZIP / ASYNCH.ASM < prev    next >
Encoding:
Assembly Source File  |  1986-06-19  |  22.4 KB  |  878 lines

  1.         name    asynch 
  2.         page    55,132
  3.         title   'ASYNCH --- asynchronous driver' 
  4.     .lfcond    
  5.  
  6. ;
  7. ; Asynchronous Port Driver  (COM1 or COM2)
  8. ; version 1.0  April 16, 1985
  9. ; Copyright (C) 1985 Ray Duncan
  10. ;
  11. ; To assemble, link, and convert this program into 
  12. ; a BIN file, follow these steps:
  13. ;
  14. ;    C>MASM ASYNCH;
  15. ;     C>LINK ASYNCH;
  16. ;    C>EXE2BIN ASYNCH.EXE ASYNCH.BIN
  17. ;    C>DEL ASYNCH.EXE
  18. ;
  19. ; Ignore the message "Warning: no stack segment" from the Linker.
  20. ;
  21. ; Then add the line:  
  22. ;
  23. ;     DEVICE=ASYNCH.BIN
  24. ;
  25. ; to your CONFIG.SYS file.
  26. ;
  27.     
  28. code    segment public 'CODE'
  29.  
  30. driver  proc    far
  31.  
  32.         assume  cs:code,ds:code,es:code
  33.  
  34.         org     0
  35.  
  36. comm_port equ    0             ;0=COM1, <>0=COM2
  37.  
  38.     if     comm_port    ;define physical port assignments
  39.  
  40.                 ; COM2 port assignments
  41. comm_irqm equ   08h             ; Mask for IRQ3
  42. comm_int  equ    0bh
  43. comm_data equ    02f8h
  44. comm_ier  equ    02f9h
  45. comm_lcr  equ      02fbh 
  46. comm_mcr  equ   02fch
  47. comm_stat equ   02fdh
  48.     else
  49.                 ; COM1 port assignments
  50. comm_irqm equ   10h        ; Mask for IRQ4
  51. comm_int  equ   0ch
  52. comm_data equ    03f8h
  53. comm_ier  equ    03f9h
  54. comm_lcr  equ    03fbh
  55. comm_mcr  equ   03fch
  56. comm_stat equ   03fdh
  57.     endif
  58.  
  59. Max_Cmd equ     15                ; MS-DOS command code maximum
  60.  
  61. In_Len  equ    2048        ; length of ring buffer for reads
  62. Out_Len    equ    2048        ; length of ring buffer for writes
  63.  
  64. cr    equ    0dh        ; ASCII carriage return
  65. lf    equ    0ah        ; ASCII line feed
  66. eom    equ    '$'        ; end of message signal
  67.  
  68.      page
  69. ;
  70. ; Device Driver Header
  71. ;
  72. Header  dd      -1              ;link to next device,-1= end of list
  73.  
  74.         dw      8000h           ;attribute word
  75.                 ;bit 15=1 for character devices
  76.  
  77.         dw      Strat            ;device "Strategy" entry point
  78.  
  79.         dw      Intr           ;device "Intrrupt" entry point
  80.  
  81.         db      'ASYNCH1 '      ;char device name, 8 char, or
  82.                 ;if block device, no. of units
  83.                 ;in first byte followed by 
  84.                 ;7 don't care bytes    
  85.  
  86. ;
  87. ; local variables for use by driver
  88. ;
  89. Rq_Ptr  dd      ?               ; pointer to request header
  90.                 ; passed to Strat by BDOS
  91.  
  92. Ident    db    cr,lf,lf
  93.     db    'LMI Asynchronous Port Driver 1.0'
  94.     db    cr,lf
  95.     db    'Copyright (c) 1985 '
  96.     db    'Laboratory Microsystems Inc.' 
  97.     db    cr,lf,lf,eom
  98.  
  99. rcv_in    dw    0        ; input ptr to read ring buffer
  100. rcv_out    dw    0        ; output ptr to read ring buffer
  101.  
  102. xmt_in    dw    0        ; input ptr to write ring buffer
  103. xmt_out    dw    0        ; output ptr to write ring buffer
  104.  
  105.         page
  106.  
  107. ;
  108. ; MS-DOS Command Codes dispatch table
  109.  
  110. ; The "Intr" routine uses this table and the Command Code
  111. ; supplied in the Request Header to transfer to the
  112. ; appropriate driver subroutine.
  113.  
  114. Dispatch:
  115.  
  116.         dw      Init        ;  0 = init driver into system
  117.         dw      Media_Chk       ;  1 = media check on blk dev
  118.         dw      Build_Bpb       ;  2 = build BIOS param block
  119.         dw      Ioctl_Inp       ;  3 = I/O ctrl read from dev
  120.         dw      Input           ;  4 = normal destructive read
  121.         dw      Nd_Input        ;  5 = non-destructive read,no wait
  122.         dw      Inp_Stat        ;  6 = return current input status
  123.         dw      Inp_Flush       ;  7 = flush device input buffers
  124.         dw      Output          ;  8 = normal output to device
  125.         dw      Outp_Vfy    ;  9 = output with verify
  126.         dw      Outp_Stat       ; 10 = return current output status
  127.         dw      Outp_Flush      ; 11 = flush output buffers
  128.         dw      Ioctl_Outp      ; 12 = I/O control output
  129.     dw    Dev_Open    ; 13 = device open      (MS-DOS 3.x)
  130.     dw    Dev_Close    ; 14 = device close     (MS-DOS 3.x)
  131.     dw    Rem_Media    ; 15 = removeable media (MS-DOS 3.x)
  132.  
  133.         page
  134. ; MS-DOS Request Header structure definition
  135. ;
  136. Request struc                   ; request header template structure
  137.         
  138. Rlength db      ?               ; length of request header
  139. Unit    db      ?               ; unit number for this request
  140. Command db      ?               ; request header's command code
  141. Status  dw      ?               ; driver's return status word
  142. Reserve db      8 dup (?)       ; reserved area
  143. Media   db      ?               ; media descriptor byte
  144. Address dd      ?               ; memory address for transfer
  145. Count   dw      ?               ; byte/sector count value
  146. Sector  dw      ?               ; starting sector value
  147.  
  148. Request ends                    ; end of request header template
  149.  
  150. ;
  151. ; Status word is interpreted as follows:
  152. ;
  153. ;  Bit(s)   Significance
  154. ;   15       Error
  155. ;   10-14    Reserved
  156. ;   9        Busy
  157. ;   8        Done
  158. ;   0-7      Error code if bit 15=1
  159.  
  160. ; Predefined BDOS error codes are:
  161. ;   0        Write protect violation
  162. ;   1       Unknown unit
  163. ;   2       Drive not ready
  164. ;   3       Unknown command
  165. ;   4       CRC error
  166. ;   5       Bad drive request structure length
  167. ;   6       Seek error
  168. ;   7       Unknown media
  169. ;   8       Sector not found
  170. ;   9       Printer out of paper
  171. ;   10      Write fault
  172. ;   11      Read fault
  173. ;   12      General failure       
  174. ;   13-14   Reserved
  175. ;   15      Invalid disk change  (MS-DOS 3.x)
  176.     page
  177.  
  178. ;
  179. ; Media descriptor byte is interpreted as follows
  180. ; if Non-IBM-Format bit is zero
  181. ;  Bit(s)   Significance
  182. ;   3-7      always set 
  183. ;   2        1=removeable 0=not removeable
  184. ;   1        1=8 sector   0=not 8 sector
  185. ;   0        1=2 sided    0=not 2 sided
  186. ;
  187. ; Current valid DOS descriptor bytes, 5 1/4" disks
  188. ;   0F9H     2 sided 15 sector
  189. ;   0FCH     1 sided  9 sector
  190. ;   0FDH     2 sided  9 sector
  191. ;   0FEH     1 sided  8 sector
  192. ;   0FFH     2 sided  8 sector
  193. ;
  194. ;   0F8H     (fixed disk)
  195.  
  196.     page
  197.  
  198. ;
  199. ; this is the hardware interrupt handler for 
  200. ; Asynch Communications Adaptor
  201. ;
  202.  
  203. Svc_Int    proc    far        ;interrupt service routine
  204.                 ;for asynch controller
  205.  
  206.     sti            ;turn interrupts back on
  207.     push    ax        ;save all necessary registers
  208.     push    bx
  209.     push    dx
  210.     push    ds
  211.     mov    ax,cs        ;make local data addressable
  212.     mov    ds,ax
  213.     call    Recv        ;receive a character
  214.     cli            ;disable interrupts
  215.                 ;for clean exit
  216.     mov    al,20h        ;send EOI to 8259
  217.     out    20h,al
  218.     pop    ds        ;restore all registers
  219.     pop    dx
  220.     pop    bx
  221.     pop    ax
  222.     iret            ;and exit handler
  223.  
  224. Svc_Int    endp
  225.  
  226.     page
  227. ;
  228. ; This is the input interrupt driver.
  229. ; Check for RDA status on interrupt, 
  230. ; if RDA = True then input character
  231. ; Called on each interrupt. 
  232. ;
  233. Recv    proc    near        ;assumes CS = DS
  234.  
  235.     mov    dx,comm_stat    ;read status
  236.     in    al,dx
  237.     and    al,1        ;RDA ?
  238.     jz    Recv2        ;no, jump
  239.     mov    dx,comm_data
  240.     in    al,dx        ;read this character
  241.     cli            ;clear interrupts for
  242.                 ;pointer manipulation    
  243.     mov    bx,rcv_in    ;get buffer pointer
  244.                 ;store this character
  245.     mov    byte ptr [In_Buf+bx],al 
  246.     inc    bx        ;bump pointer
  247.     cmp    bx,In_Len    ;time for wrap?
  248.     jne    Recv1        ;no,jump
  249.     xor    bx,bx        ;yes,reset pointer
  250. Recv1:  mov    rcv_in,bx    ;store back updated pointer
  251.     sti            ;unmask interrupts
  252. Recv2:    ret
  253.  
  254. Recv    endp
  255.  
  256.     page
  257. ;
  258. ; This is the interrupt output driver.
  259. ; Check for TBE status on interrupt, if TBE = True 
  260. ; then transmit another character if any waiting.
  261. ; Called by Command Codes 8 & 9 to start I/O,
  262. ; and will be called on interrupt in final version.
  263. ;
  264. Xmit    proc    near        ;assumes CS = DS
  265.  
  266.     mov    dx,comm_stat    ;read status
  267.     in    al,dx
  268.     and    al,20h        ;TBE?
  269.     jz    Xmit9        ;no, jump
  270.     mov    bx,xmt_out    ;any characters waiting
  271.     cmp    bx,xmt_in    ;in output buffer?
  272.     je    Xmit9        ;no, jump
  273.     mov    al,[bx+Out_Buf]    ;yes, get next char
  274.     inc    bx
  275.     cmp    bx,Out_Len    ;time to wrap?
  276.     jne    Xmit1        ;no
  277.     xor    bx,bx        ;yes,reset ring buffer ptr
  278. Xmit1:
  279.     mov    xmt_out,bx    ;store updated pointer
  280.     mov    dx,comm_data    ;transmit this char.
  281.     out    dx,al
  282. Xmit9:    ret
  283.  
  284. Xmit    endp
  285.  
  286.         page
  287.  
  288. ; Device Driver "Strategy Routine"
  289.  
  290. ; Each time a request is made for this device, the BDOS
  291. ; first calls "Strategy routine",  then immediately calls
  292. ; the "Interrupt routine".  
  293.  
  294. ; The Strategy routine is passed the address of the
  295. ; Request Header in ES:BX, which it saves in a local
  296. ; variable and then returns to BDOS.
  297.  
  298. Strat     proc     far    
  299.                 ; save address of Request Header
  300.         mov     word ptr cs:[Rq_Ptr],bx
  301.         mov     word ptr cs:[Rq_Ptr+2],es
  302.  
  303.         ret            ; back to BDOS
  304.  
  305. Strat     endp
  306.  
  307.         page
  308.  
  309.  
  310. ; Device Driver "Interrupt Routine"
  311.  
  312. ; This entry point is called by the BDOS immediately after 
  313. ; the call to the "Strategy Routine", which saved the long
  314. ; address of the Request Header in the local variable "Rq_Ptr".
  315.  
  316. ; The "Interrupt Routine" uses the Command Code passed in
  317. ; the Request Header to transfer to the appropriate device
  318. ; handling routine.  Each command code routine is responsible
  319. ; for any necessary return information into the Request Header,
  320. ; then transfers to Error or Exit to set the Return Status code.
  321.  
  322. Intr     proc  far
  323.  
  324.         push    ax              ; save general registers 
  325.         push    bx
  326.         push    cx
  327.         push    dx
  328.         push    ds
  329.         push    es
  330.         push    di
  331.         push    si
  332.         push    bp
  333.  
  334.     push    cs        ; make local data addressable
  335.     pop    ds
  336.  
  337.     les    di,[Rq_Ptr]    ; ES:DI = Request Header
  338.  
  339.                 ; get BX = Command Code
  340.     mov    bl,es:[di.Command]
  341.     xor    bh,bh
  342.     cmp    bx,Max_Cmd    ; make sure its legal
  343.     jg    Unk_Command    ; too big, exit with error code
  344.     shl    bx,1        ; form index to Dispatch table
  345.                 ; and branch to driver routine
  346.     jmp    word ptr [bx+Dispatch]
  347.  
  348.         page
  349.  
  350.  
  351. ; General collection of exit points for the driver routines.
  352.  
  353.  
  354. Unk_Command:            ; Come here if Command Code > 12
  355.         mov     al,3            ; Sets "Unknown Command" error 
  356.                 ; code and "Done" bit.
  357.  
  358. Error:                ; Transfer here with AL = error code.
  359.         mov     ah,81h        ; Sets "Error" and "Done" bits.
  360.         jmp     Exit
  361.  
  362. Done:    mov    ah,1        ; Come here if I/O complete and
  363.                 ; no error, sets "Done" bit only.
  364.  
  365.  
  366. Exit:                ; General purpose exit point.
  367.                 ; Transfer here with AX = 
  368.                 ; Return Status word to be
  369.                 ; placed into Request Header.
  370.  
  371.         lds     bx,cs:[Rq_Ptr]      ; set status
  372.         mov     ds:[bx.Status],ax
  373.  
  374.         pop     bp              ;restore general registers
  375.         pop     si
  376.         pop     di
  377.         pop     es
  378.         pop     ds
  379.         pop     dx
  380.         pop     cx
  381.         pop     bx
  382.         pop     ax
  383.         ret            ; back to BDOS
  384.  
  385.         page
  386.  
  387.  
  388. ; MS-DOS Command Code # 1  Media Check
  389.  
  390. ; Block devices only.  Should be a NOP for character devices.
  391. ;
  392. ; This routine is called first by BDOS for a block device transfer,
  393. ; passing current media descriptor byte at Request Header + 
  394. ;
  395. ; Media Check routine sets status word and in addition passes back 
  396. ; return byte at Request Header + 14  as follows:
  397.  
  398. ;    -1  Media has been changed
  399. ;     0  Don't know if media changed
  400. ;     1  Media has not been changed
  401. ;
  402. ; If driver can return 1 or -1, performance is improved because
  403. ; MS-DOS does not need to reread the FAT for each directory access.
  404.  
  405.  
  406. Media_Chk:
  407.  
  408.         jmp     Done
  409.  
  410.         page
  411.  
  412. ;
  413. ; MS-DOS Command Code # 2  Build BIOS Parameter Block
  414. ; Block devices only.  Should be a NOP for character devices.
  415. ;
  416. ; This routine is called by MS-DOS when Media-Changed code is
  417. ; returned by Media Check routine, or if Not Sure code is returned
  418. ; and there are no dirty buffers.
  419. ; Build BPB call receives pointer to one-sector buffer in Address
  420. ; Field of Request Header (offset 14).  If "Non-IBM-Format" bit 
  421. ; in attribute word is zero, the buffer contains the first sector
  422. ; of the FAT including the media identification byte and should not 
  423. ; be altered by the driver.   If the "Non-IBM-Format" bit is set, 
  424. ; the buffer may be used as scratch space.
  425. ;
  426. ; The Build BPB routine sets status and returns a DWORD pointer to 
  427. ; the new Bios Parameter Block at Request Header + 18.
  428. ;
  429.  
  430. Build_Bpb:
  431.  
  432.         jmp     Done
  433.  
  434.         page
  435.  
  436. ;
  437. ; MS-DOS Command Code # 3  I/O Control Read from device
  438. ; Only called if IOCTL bit set in Device Header Attribute word.
  439. ;
  440. ; Called with:
  441. ;
  442. ; Request Header + 13  BYTE   Media descriptor byte from DPB
  443. ; Request Header + 14  DWORD  Transfer address
  444. ; Request Header + 18  WORD   byte/sector count
  445. ; Request Header + 20  WORD   starting sector no. (block dev.)
  446. ;
  447. ; Returns the Return Status word set appropriately, and
  448. ; Request Header + 18  WORD   actual bytes or sectors transferred
  449. ; No error check is performed on IOCTL I/O calls.
  450.  
  451. Ioctl_Inp:
  452.  
  453.         jmp     Done
  454.  
  455.         page
  456.  
  457. ;
  458. ; MS-DOS Command Code # 4  Read from device
  459. ;
  460. ; Called with
  461. ;
  462. ; Request Header + 13  BYTE   Media descriptor byte from DPB
  463. ; Request Header + 14  DWORD  Transfer address
  464. ; Request Header + 18  WORD   byte/sector count
  465. ; Request Header + 20  WORD   starting sector no. (block dev.)
  466. ;
  467. ; Returns the Return Status word set appropriately, and
  468. ; Request Header + 18  WORD   actual bytes or sectors transferred
  469.  
  470. Input: 
  471.  
  472.     mov    si,rcv_out    ;receive buffer output pointer
  473.     cmp    si,rcv_in    ;compare to buffer input ptr
  474.     jne    Input1        ;something is in buffer
  475.                 ;set characters xfer'd = 0
  476.     mov    word ptr es:[di.Count],0 
  477.     jmp    Done        ;go set Done flag
  478.  
  479. Input1:
  480.     xor    dx,dx        ;set chars xferd count=0
  481.                 ;get requested transfer count
  482.     mov    cx,word ptr es:[di.Count]
  483.                 ;given DS:SI = addr input buffer
  484.                 ;set ES:DI = addr user's buffer
  485.     push    word ptr es:[di.Address]
  486.     push    word ptr es:[di.Address+2]
  487.     pop    es
  488.     pop    di
  489.         
  490. Input2:                ;transfer one character
  491.     mov    al,byte ptr ds:[si+In_Buf]
  492.     mov    byte ptr es:[di],al
  493.     inc    si
  494.     inc    di
  495.     inc    dx        ;count characters given to user
  496.     cmp    si,In_Len    ;buffer pointer wrap? 
  497.     jne    Input3        ;no
  498.     xor    si,si        ;yes
  499.  
  500. Input3:    cmp    si,rcv_in    ;input buffer exhausted?
  501.     je    Input4        ;yes, user got all he can get
  502.     cmp    dx,cx        ;user got max requested?
  503.     jne    Input2        ;not yet
  504.  
  505. Input4:    mov    rcv_out,si    ;update buffer out pointer
  506.     les    di,cs:[Rq_Ptr]    ;let ES:DI = Request Header
  507.                 ;store length actually transferred
  508.     mov    word ptr es:[di.Count],dx
  509.         jmp     Done        ;go set Done & No Error flags
  510.  
  511.         page
  512.  
  513. ;
  514. ; MS-DOS Command Code # 5  Non-destructive Read from Device
  515. ; Character devices only.
  516. ;
  517. ; If Input Status request returns Busy bit=0 (characters 
  518. ; waiting), the next character that would be read is returned 
  519. ; at Request Header + 13.  This character is not removed from
  520. ; the Input Buffer.  This basically provides the capability to 
  521. ; "look-ahead" by one character.
  522.  
  523. Nd_Input:
  524.  
  525.     mov    bx,rcv_out
  526.     cmp    bx,rcv_in
  527.     je    Nd_Input1        ;jump, nothing in buffer
  528.  
  529.                     ;something in read buffer,
  530.                     ;fetch first waiting char 
  531.     mov    al,byte ptr [bx+In_Buf]
  532.     jmp    Nd_Input2
  533.  
  534. Nd_Input1:                ;nothing in read buffer,
  535.     mov    al,0            ;return a null character
  536.  
  537. Nd_Input2:                ;put char into Request Header
  538.     mov    byte ptr es:[di+13],al
  539.     jmp    done            ;set Done status, no error
  540.  
  541.         page
  542.  
  543. ;
  544. ; MS-DOS Command Code # 6  Return current device input status
  545. ; Character devices only.
  546. ;
  547. ; Sets the Returned Status word:
  548. ; Done bit = 1
  549. ; Busy bit = 1 read request would go to physical device
  550. ;          = 0 characters already in device buffer, read request
  551. ;              would return quickly.
  552. ;
  553. ; MS-DOS assumes all character devices have type-ahead buffer.
  554. ; If device does not have type-ahead buffer, should always
  555. ; return Busy bit=0 so MS-DOS will not hang.
  556.  
  557. Inp_Stat:
  558.  
  559.     mov    ax,rcv_in        ;anything in read buffer?
  560.     cmp    ax,rcv_out
  561.     je    Inp_Stat1        ;no,jump
  562.     jmp    Done            ;yes, let busy bit=0
  563.  
  564. Inp_Stat1:
  565.     mov    ax,300h            ;request goes to device
  566.     jmp    Exit            ;so let busy bit=1
  567.  
  568.         page
  569.  
  570. ;
  571. ; MS-DOS Command Code # 7  Flush device input buffers
  572. ; Character devices only.
  573. ;
  574. ; Terminate all pending requests, i.e. the Input buffer is
  575. ; emptied.
  576.  
  577. Inp_Flush:
  578.  
  579.     cli            ; block interrupts
  580.     mov    rcv_in,0    ; reset buffer pointers
  581.     mov    rcv_out,0
  582.     sti            ; restore interrupts
  583.         jmp     Done
  584.  
  585.         page
  586.  
  587. ;
  588. ; MS-DOS Command Code # 8  Write to device
  589. ; Called with
  590. ;
  591. ; Request Header + 13  BYTE   Media descriptor byte from DPB
  592. ; Request Header + 14  DWORD  Transfer address
  593. ; Request Header + 18  WORD   byte/sector count
  594. ; Request Header + 20  WORD   starting sector no. (block dev.)
  595. ;
  596. ; Returns the Return Status word set appropriately, and
  597. ; Request Header + 18  WORD   actual bytes or sectors transferred
  598.  
  599. Output: 
  600.  
  601.                 ;DS:SI = user's data address
  602.     mov    si,word ptr es:[di.Address]
  603.     mov    ds,word ptr es:[di.Address+2]
  604.                 ;CX = length of user's data
  605.     mov    cx,word ptr es:[di.Count]
  606.     jcxz    Output3        ;exit if length=0 
  607.  
  608.     mov    di,cs:xmt_in    ;ES:DI = output buffer address
  609.     push    cs
  610.     pop    es
  611.  
  612. Output1:
  613.     mov    al,byte ptr ds:[si]
  614.     mov    byte ptr es:[di+Out_Buf],al
  615.     inc    si
  616.     inc    di
  617.     cmp    di,Out_Len    ;buffer pointer wrap? 
  618.     jne    Output2        ;no
  619.     xor    di,di        ;reset output buffer pointer
  620.  
  621. Output2:
  622.     loop    Output1        ;loop until all string moved 
  623.     mov    cs:xmt_in,di    ;store updated buffer input ptr
  624.  
  625. Output3:
  626.     mov    ax,cs        ;make buffers addressable for
  627.     mov    ds,ax        ;XMIT routine, 
  628. Output4:
  629.     mov    ax,xmt_in
  630.     cmp    ax,xmt_out
  631.     je    Output5
  632.     call    Xmit        ;transmit one character 
  633.     jmp    Output4
  634. Output5:
  635.         jmp     Done        ;go set Done & No Error flags
  636.  
  637.         page
  638.  
  639. ;
  640. ; MS-DOS Command Code # 9  Write with verify to device
  641. ; Called with
  642. ;
  643. ; Request Header + 13  BYTE   Media descriptor byte from DPB
  644. ; Request Header + 14  DWORD  Transfer address
  645. ; Request Header + 18  WORD   byte/sector count
  646. ; Request Header + 20  WORD   starting sector no. (block dev.)
  647. ;
  648. ; Returns the Return Status word set appropriately, and
  649. ; Request Header + 18  WORD   actual bytes or sectors transferred
  650.  
  651. Outp_Vfy: 
  652.  
  653.         jmp     Output    
  654.  
  655.         page
  656.  
  657. ;
  658. ; MS-DOS Command Code # 10  Return device output status
  659. ;
  660. ; Character devices only.
  661. ;
  662. ; Sets the Returned Status word:
  663. ; Done bit = 1
  664. ; Busy bit = 1 write request would wait for completion of
  665. ;              current request
  666. ;          = 0 device idle, write request would start immediately.
  667. ;
  668.  
  669. Outp_Stat:
  670.  
  671.                 ; always return Not Busy for now
  672.                 ; *** later should return Busy if
  673.                 ;     transmit buffer is full ***
  674.         jmp     Done
  675.  
  676.         page
  677.  
  678. ;
  679. ; MS-DOS Command Code # 11  Flush output buffers
  680. ; Character devices only.
  681. ;
  682. ; Terminate pending requests.  The output buffer is emptied. 
  683.  
  684. Outp_Flush:
  685.  
  686.     cli            ; block interrupts
  687.     mov    xmt_in,0    ; reset buffer pointers
  688.     mov    xmt_out,0
  689.     sti            ; re-enable interrupts
  690.         jmp     Done
  691.  
  692.         page
  693.  
  694. ;
  695. ; MS-DOS Command Code # 12  I/O Control write to device
  696. ; Only called if IOCTL bit in Device Header Attribute word is set.
  697. ;
  698. ; Called with
  699. ;
  700. ; Request Header + 13  BYTE   Media descriptor byte from DPB
  701. ; Request Header + 14  DWORD  Transfer address
  702. ; Request Header + 18  WORD   byte/sector count
  703. ; Request Header + 20  WORD   starting sector no. (block dev.)
  704. ;
  705. ; Returns the Return Status word set appropriately, and
  706. ; Request Header + 18  WORD   actual bytes or sectors transferred
  707. ;
  708. ; No error check is performed on IOCTL calls.
  709.  
  710. Ioctl_Outp:
  711.  
  712.         jmp     Done
  713.  
  714.         page
  715.  
  716. ;
  717. ; MS-DOS Command Code # 13  Device Open
  718. ;
  719. ; MS-DOS version 3.0 and above only.
  720. ; Only called if OPEN/CLOSE/RM bit set in Attribute word.
  721. ; May be used to manage local buffering.  Reference count
  722. ; is incremented keeping track of number of open files on
  723. ; the device.  On character devices can be used to send
  724. ; device initialization string, which can be set by IOCTL 
  725. ; Write.  Note that CON AUX and PRN devices are always open.
  726. ;
  727. ; Returns the Return Status word set to "Done.
  728. ;
  729. Dev_Open:
  730.  
  731.         jmp     Done
  732.  
  733.         page
  734.  
  735. ;
  736. ; MS-DOS Command Code # 14  Device Close
  737. ;
  738. ; MS-DOS version 3.0 and above only.
  739. ; Only called if OPEN/CLOSE/RM bit set in Attribute word.
  740. ; May be used to manage local buffering.  Reference count
  741. ; is decremented keeping track of number of open files on
  742. ; the device; when count reaches zero all files have been closed 
  743. ; and the driver should flush buffers as user may change disks.
  744. ; On character devices can be used to send device post-I/O
  745. ; string such as a form feed, which can be set by IOCTL 
  746. ; Write.  Note that CON AUX and PRN devices are never closed.
  747. ;
  748. ; Returns the Return Status word set to "Done".
  749. ;
  750. Dev_Close:
  751.  
  752.         jmp     Done
  753.  
  754.         page
  755.  
  756. ;
  757. ; MS-DOS Command Code # 15  Removeable Media
  758. ;
  759. ; MS-DOS version 3.0 and above only.
  760. ; Only called if OPEN/CLOSE/RM bit set in Attribute word
  761. ;    and device type is block.
  762. ;
  763. ; Returns the Return Status word set to "Done" and 
  764. ; Busy bit = 1 if media is non-removable.  
  765. ;          = 0 if media is removable.
  766. ;
  767. Rem_Media:
  768.  
  769.         jmp     Error
  770.  
  771.     page
  772.  
  773. ; This initialization code for the driver is called only
  774. ; once when the driver is loaded.  It returns its own
  775. ; address to the DOS as the start of free memory after the
  776. ; driver, so that the memory occupied by INIT will be
  777. ; reclaimed after it is finished with its work.  If it 
  778. ; is a block device driver it must also return the address of
  779. ; the Bios Parameter Block pointer array; if all units are the
  780. ; same all pointers can point to the same BPB.
  781. ;
  782. ; Only MS-DOS services 01-0CH and 30H can be called
  783. ; by the INIT code.
  784. ;
  785. ; Called with:
  786. ;
  787. ; Request Header + 18  DWORD pointer to the character after the "="
  788. ;                            on the CONFIG.SYS line that loaded 
  789. ;                            driver; this information is read only.
  790. ;                  22  BYTE  drive letter for first unit of a 
  791. ;                            block driver (0=A 1=B etc)
  792. ; Returns:
  793. ; Request Header + 13  BYTE  Number of units (block devices only)
  794. ;                + 14  DWORD address of first free memory above driver
  795. ;         + 18  DWORD BPB pointer array (block devices only)    
  796. ;
  797.  
  798. Init:                           ; MS-DOS Command Code # 0
  799.                                 ; initialize device driver
  800.  
  801.     push    es        ; push Request Header addr
  802.     push    di
  803.  
  804.     mov    ah,9        ; print sign-on message
  805.     mov    dx,offset Ident
  806.     int    21h
  807.  
  808.     pop    di        ; restore Request Header addr
  809.     pop    es
  810.  
  811.                 ; set addr of interrupt handler
  812.     push    ds
  813.     xor    ax,ax
  814.     mov    ds,ax
  815.     mov    bx,comm_int*4
  816.     mov    word ptr [bx],offset Svc_Int 
  817.     mov    word ptr [bx+2],cs
  818.     pop    ds
  819.  
  820.     mov    dx,comm_lcr    ;make sure DLAB is off
  821.     in    al,dx
  822.     and    al,07fh
  823.     out    dx,al
  824.     
  825.     mov    dx,comm_mcr    ;modem controller DTR, RTS, 
  826.     mov    al,0bh        ;and OUT2 to enable interrupts.
  827.     out    dx,al
  828.  
  829.     mov    dx,comm_ier    ;enable interrupts for TBE
  830.     mov    al,1        ;and RDA on asynch controller.
  831.     out    dx,al 
  832.  
  833.     in    al,21h        ;8259 int mask register
  834.                 ;Reset IRQ3 or IRQ4 mask 
  835.     and    al,not comm_irqm
  836.     out    21h,al
  837.  
  838.                 ; set first usable memory addr.
  839.         mov     word ptr es:[di.Address],offset End_Buf 
  840.         mov     word ptr es:[di.Address+2],cs
  841.  
  842.         jmp     Done
  843.  
  844.  
  845. Intr     endp
  846.  
  847.  
  848. Driver    endp
  849.  
  850.  
  851. In_Buf    db    In_Len dup (?)
  852.  
  853. Out_Buf db    Out_Len dup (?)
  854.  
  855. End_Buf    equ    $
  856.  
  857.  
  858. code    ends
  859.         
  860.         end     
  861.