home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / UTILITY / SYSTEM / MMCLK12.ZIP / DRIVER.ASM < prev    next >
Encoding:
Assembly Source File  |  1990-07-28  |  5.5 KB  |  208 lines

  1.     include    mmclock.mac
  2.     title    MM58167A clock/calendar driver -- Copyright 1990 Wales
  3.  
  4. ; ======================================================================
  5. ;
  6. ; MM58167A clock/calendar driver.
  7. ; (C) Copyright 1990 Richard B. Wales.  All Rights Reserved.
  8. ;
  9.  
  10. ; ======================================================================
  11. ;
  12. ; Format of a DOS I/O request header structure.
  13.  
  14. Request    struc
  15.     db    ?            ; length of header
  16.     db    ?            ; unit number
  17. Command    db    ?            ; command code
  18. Status    dw    ?            ; return status
  19.     db    8 dup (?)        ; reserved
  20.     db    ?            ; media descriptor
  21. Address    dw    ?, ?            ; memory address for transfer
  22. Args    dw    ?, ?            ; command-line argument string
  23. Request    ends
  24.  
  25. ; ======================================================================
  26. ;
  27. ; Bit values for return status word in request header.
  28.  
  29. IOERR    equ    8000h            ; error flag
  30. IOBUSY    equ    0200h            ; busy
  31. IODONE    equ    0100h            ; done
  32. IOUNK    equ    0003h            ; unknown command
  33.  
  34. ; ======================================================================
  35. ;
  36. ; Driver header.
  37.  
  38.     org    0            ; drivers start at offset zero
  39. Header    dd    -1            ; link to next device
  40.     dw    8008h            ; attribute word (clock device)
  41.     dw    Strat            ; entry point (strategy)
  42.     dw    Intr            ; entry point (interrupt)
  43.     db    'MM$CLOCK'        ; device name
  44. RHptr    dw    ?, ?            ; pointer to request header
  45.  
  46. ; ======================================================================
  47. ;
  48. ; Dispatch table for driver command codes -- used by interrupt routine
  49.  
  50. Dispatch:
  51.     dw    Init            ;  0 = initialize
  52.     dw    Done            ;  1 = media check
  53.     dw    Done            ;  2 = build parameter block
  54.     dw    NoSuchOp        ;  3 = I/O control read
  55.     dw    Read            ;  4 = read
  56.     dw    Busy            ;  5 = non-destructive read
  57.     dw    Done            ;  6 = current input status
  58.     dw    Done            ;  7 = flush input buffers
  59.     dw    Write            ;  8 = write
  60.     dw    Write            ;  9 = write and verify
  61.     dw    Done            ; 10 = current output status
  62.     dw    Done            ; 11 = flush output buffers
  63.     dw    NoSuchOp        ; 12 = I/O control write
  64.     dw    Done            ; 13 = open
  65.     dw    Done            ; 14 = close
  66.     dw    NoSuchOp        ; 15 = removable media check
  67.     dw    NoSuchOp        ; 16 = output until busy
  68. MaxCmd    equ    (($-Dispatch)/2)-1
  69.  
  70. ; ======================================================================
  71. ;
  72. ; I/O port for clock.
  73.  
  74. ClkPort    dw    0
  75.  
  76. ; ======================================================================
  77. ;
  78. ; External routines called directly from the driver.
  79.  
  80.     extrn    DriverInit:proc, ClkToBuf:proc, BufToClk:proc
  81.  
  82. ; ======================================================================
  83. ;
  84. ; Strategy routine (saves request header pointer).
  85.  
  86. Strat    proc    far
  87.  
  88.     mov    cs:[RHptr], bx
  89.     mov    cs:[RHptr+2], es
  90.     ret
  91.  
  92. Strat    endp
  93.  
  94. ; ======================================================================
  95. ;
  96. ; Interrupt routine (jumps to service routine through dispatch table).
  97. ;
  98. ; The interrupt routine saves all registers on entry (including flags),
  99. ; and restores them all on exit.  Any procedure called from the inter-
  100. ; rupt routine is presumed to destroy all registers; hence, anything to
  101. ; be saved in a register across a procedure call must be pushed before
  102. ; the CALL and popped afterwards.  In particular, ES and DI are used by
  103. ; the "Done" cleanup processing and must be saved prior to any CALL.
  104.  
  105. Intr    proc    far
  106.  
  107.     ; Save registers.
  108.     PUSHM    ax, bx, cx, dx, bp, ds, es, si, di, flags
  109.  
  110.     ; Make sure string operations work in ascending memory order.
  111.     cld
  112.  
  113.     ; Make data addressable via DS.  This is required in order to
  114.     ; get the service routine address via "mod-reg-r/m" addressing,
  115.     ; so we might as well take advantage of it.
  116.     INIT_DS
  117.  
  118.     ; Get the request header (ES:DI).
  119.     les    di, dword ptr [RHptr]
  120.  
  121.     ; Get the command code.
  122.     mov    al, es:[di.Command]
  123.     cmp    al, MaxCmd        ; command code too big?
  124.     ja    NoSuchOp
  125.  
  126.     ; Get the address of the service routine.
  127.     xor    ah, ah
  128.     shl    ax, 1
  129.     mov    bx, offset Dispatch
  130.     add    bx, ax
  131.  
  132.     ; Jump to the service routine.
  133.     ; Note that the service routine must preserve ES and DI --
  134.     ; but all other registers are fair game and cannot be assumed
  135.     ; to contain anything meaningful later on.
  136.     jmp    [bx]
  137.     assume    ds:nothing        ; service routine may zap DS
  138.  
  139. Success:
  140.     ; Successful completion of the service routine.
  141.     xor    ax, ax
  142.     ; (fall through to "Done")
  143.  
  144. Done:
  145.     ; Store the status code, restore registers, and return.
  146.     or    ax, IODONE
  147.     mov    es:[di.Status], ax
  148.     POPM    flags, di, si, es, ds, bp, dx, cx, bx, ax
  149.     ret
  150.  
  151. NoSuchOp:
  152.     ; Unimplemented driver command.
  153.     mov    ax, IOERR + IOUNK
  154.     jmp    short Done
  155.  
  156. Busy:
  157.     ; Driver is busy.  (Response to a non-destructive read request.)
  158.     mov     ax, IOERR + IOBUSY
  159.     jmp    short Done
  160.  
  161. Intr    endp
  162.  
  163. ; ======================================================================
  164. ;
  165. ; Initialization routine.
  166.  
  167. Init:
  168.     assume    ds:nothing
  169.     lds    si, dword ptr es:[di.Args]
  170.     PUSHM    es, di
  171.     call    DriverInit
  172.     POPM    di, es
  173.     mov    cs:[ClkPort], dx    ; save clock port for Read/Write
  174.     mov    es:[di.Address], cx    ; first mem loc after driver
  175.     mov    es:[di.Address+2], cs
  176.     jmp    short Success
  177.  
  178. ; ======================================================================
  179. ;
  180. ; Read routine.
  181.  
  182. Read:
  183.     assume    ds:code
  184.     mov    dx, [ClkPort]        ; DS still set from "Intr"
  185.     assume    ds:nothing
  186.     PUSHM    es, di
  187.     les    di, dword ptr es:[di.Address]
  188.     call    ClkToBuf
  189.     POPM    di, es
  190.     jmp    short Success
  191.  
  192. ; ======================================================================
  193. ;
  194. ; Write routine.
  195.  
  196. Write:
  197.     assume    ds:code
  198.     mov    dx, [ClkPort]        ; DS still set from "Intr"
  199.     assume    ds:nothing
  200.     PUSHM    es, di
  201.     lds    si, dword ptr es:[di.Address]
  202.     call    BufToClk
  203.     POPM    di, es
  204.     jmp    short Success
  205.  
  206. code    ends
  207.  
  208.     end