[Back to DOS SWAG index] [Back to Main SWAG index] [Original]

    (*
    > Is there someone who can tell me how I can CREATED my own .SYS files ?

    Try "Advanced MSDOS Programming", by Ray Duncan (Microsoft Press) for details
    about device driver writing.

    A device driver is a binary image whose origin is at zero.  The first two
    words in the header are always $FFFF.  Device attribute varies per device!
    { start of device driver header }
       ORG  0
    dd -1          { Next device : longint = -1; }
    dw $8800       { Device attribute word, "generic" driver for DOS 3 or later }
    dw strategy    { Strategy routine offset (request header pointer entry) }
    dw intrupt     { Interrupt routine offset (request entry point) }
    db 'EXAMPLE '  { Eight character device name }
    { Global variables }
    request_ptr LABEL dword
    request_off  DW  ?
    request_seg  DW  ?
    { end of device driver header }

    { "dos_func_table" is used by "intrupt" to call the routine that handles
      the requested function.  Example table with four command entries: }
    max_cmd EQU 4
    dos_func_table:  DW dosfunc0, nopcmd, nopcmd, badcmd
    { Typical table has 24 entries including nopcmd's and badcmd's.  dosfunc0
     initializes device driver interrupts and buffers, then gives ending address
     of the device driver (header + body) to DOS.
      MediaCheck       ; not used for character devices -- return done
      BuildBPB         ; not used for character devices -- return done
      IOCTLRead        ; disabled in table word
          Read           ; implemented for character device
          NdRead         ; implemented "   "         "
          InpStatus      ; implemented "   "         "
          InpFlush       ; implemented "   "         "
          Write          ; implemented "   "         "
          WriteVerify    ; implemented "   "         "
          OutStatus      ; implemented "   "         "
          OutFlush       ; not used in this example -- always success
      IOCTLWrite       ; disabled in table word
      DevOpen          ; disabled in table word
      DevClose         ; disabled in table word
      RemMedia         ; disabled in table word
      OutBusy          ; disabled in table word
      GenIOCTL         ; disabled in table word
      GetLogDev        ; not used for character devices -- return done
      SetLogDev        ; not used for character devices -- return done }

    { "Strategy" routine called by DOS with a request.  This implementation just
      saves the request. }
    strategy proc far
       MOV  CS:request_off, BX
       MOV  CS:request_seq, ES
       RET
    strategy endp
    { "Intrupt" routine handles request queued by "strategy".  Calls one of the
      subroutines in the function table depending upon the request number.  Each
      subroutine returns with exit status in AX.  Partial example: }
    intrupt proc far
       STI
       PUSHA             { Preserve all registers except stack }
       PUSH DS
       PUSH ES
       { Read requested function information into registers }
       LDS  BX, CS:request_ptr
       XOR  AH, AH
       MOV  AL, DS:[BX+02h]       { AL = function code }
       CMP  AL, max_cmd  { Check range for expected table entry }
       JA   unknown_command
       XCHG BX, AX
       SHL  BX, 1        { Calculate index to function table of words }
       MOV  AX, CS
       MOV  DS, AX
       CALL word ptr dos_func_table[BX]
    done:
       LDS  BX, CS:request_ptr       { Report status }
       OR   AX, 100h                 { Always set done bit before exit }
       MOV  [BX+03], AX
       POP  ES
       POP  DS
       POPA              { Restore all registers }
       RET               { Return to DOS }
    unknown_command:
       CALL badcmd       { Your error routine for invalid codes }
       JMP  done
    intrupt endp
    { Invalid function request by DOS }
    badcmd proc near
       MOV  AX, 813h     { Return "Error: invalid command" }
       RET
    badcmd endp
    { Unimplemented function request by DOS will return 0=SUCCESS }
    nopcmd proc near
       XOR  AX, AX       { No error, not busy }
       RET
    nopcmd endp
    dosfunc0 proc near .. endp
    *)

[Back to DOS SWAG index] [Back to Main SWAG index] [Original]