home *** CD-ROM | disk | FTP | other *** search
/ Beijing Paradise BBS Backup / PARADISE.ISO / software / BBSDOORW / SHSUCD11.ZIP / SHSUDRVX.ASM < prev    next >
Encoding:
Assembly Source File  |  1995-12-07  |  46.3 KB  |  1,350 lines

  1. ;************************************************************************
  2. ;
  3. ;  SHSUDRVX.ASM  v1.0
  4. ;
  5. ;    An installable dummy CD driver for testing purposes.  Emulates
  6. ;       2 CD drives with ISO9660 format CD roms.
  7. ;
  8. ;    Updated to handle multi-block reads.
  9. ;
  10. ;    UsageMsg:
  11. ;      SHSUDRVX [/?][/D:DriverName][/U]
  12. ;      default driver name is CD001
  13. ;
  14. ;  Assemble using MASM 6.0 and link as an .exe file.
  15. ;
  16. ;  SHSUDRVX is a copyright-reserved, free use program.  Use at your own risk.
  17. ;  (c)John H. McCoy, 1993, 1995, Sam Houston St. Univ., TX 77341-2206
  18. ;************************************************************************
  19.  
  20. .model small, os_dos
  21.  
  22. option nokeyword:<length name>
  23. option expr16
  24.  
  25. fptr  typedef  far ptr word
  26. nptr  typedef  near ptr word
  27.  
  28. ; DOS FileFlags -- not CDrom dir entry flags
  29. _A_NORMAL       equ   00h
  30. _A_RDONLY       equ   01h       ; all cdrom files
  31. _A_HIDDEN       equ   02h
  32. _A_SYSTEM       equ   04h
  33. _A_VOLID        equ   08h
  34. _A_SUBDIR       equ   10h
  35. _A_ARCH         equ   20h
  36.  
  37. ; CD flags
  38. _CD_NORMAL      equ   00h
  39. _CD_HIDDEN      equ   01h
  40. _CD_SUBDIR      equ   02h
  41.  
  42. rh    struc
  43.    Length      byte ?          ; header size in bytes
  44.    SubUnit     byte ?          ; cd drive number
  45.    Command     byte ?          ; device command code
  46.    Status      word ?          ; device command status
  47.    Reserved    byte 8 dup(?)
  48. rh    ends
  49.  
  50. rhIOCTL   struc
  51.                      byte size rh dup(?) ;rh common
  52.    MediaDesc         byte ?
  53.    CBPtr             fptr ?
  54.    BytesToTransfer   word ?
  55.    StartSector       word ?
  56.    VolIdPtr          fptr ?
  57. rhIOCTL   ends
  58.  
  59. IOCtl_RDHACmd          equ  0
  60. IOCtl_ReadDriveBytes   equ  5
  61. IOCtl_DevStatCmd       equ  6
  62. IOCtl_ReturnSectorSize equ  7
  63. IOCtl_ReturnVolumeSize equ  8        ;   total sectors on disk
  64. IOCtl_MediaChangedCmd  equ  9
  65.  
  66. IoCB_RDHA     struc
  67.    IoctlCommand           byte IOCtl_RDHACmd
  68.    DeviceHeaderAddress    fptr ?
  69. IoCB_RDHA ends
  70.  
  71. rhTransfer  struc
  72.                      byte size rh dup(?) ;rh common
  73.                      byte   ?
  74.    DtaPtr            fptr   ?
  75.    SectorCount       word   ?
  76.    StartSector       Dword  ?
  77.    ReadMode          byte   ?     ; we support cooked mode only
  78.                      byte   ?
  79.                      byte   ?
  80. rhTransfer ends
  81.  
  82.  
  83. DeviceError            equ  8000h
  84. DeviceDone             equ  0100h
  85. DE_UnknownUnit         equ    01h   ; OR with DeviceError
  86. DE_DeviceNotReady      equ    02h
  87. DE_UnknownCommand      equ    03h
  88. DE_SectorNoFound       equ    08h
  89. DE_ReadError           equ    0Bh
  90. DE_GeneralFailure      equ    0Ch
  91.  
  92. AsciiNul                equ     0
  93. cr                      equ     13
  94. lf                      equ     10
  95. ht                      equ     09
  96. QMark                   equ     '?'
  97.  
  98. Display   MACRO  msg
  99.          mov     dx,offset msg
  100.          mov     ah,9
  101.          int     21h
  102. ENDM
  103. ToHex             proto near C Num:word
  104.  
  105. .code
  106.  
  107.    assume cs:@code,  ds:@code
  108.  
  109. ;  dos device header with CDROM extension fields
  110.  
  111. DevHeader  label word
  112.   NextDriver     dword     -1
  113.   Attributes     word      0C800h
  114.                  nptr      Strategy
  115.                  nptr      Interrupt
  116.   DeviceName     byte      'CD001   '
  117.                  word      0                     ; CDROM reserved
  118.                  byte      0                     ; 1st CDROM drive letter
  119.   SubUnits       byte      2                     ; number of drives
  120.  
  121. ;  strategy call saves req hdr addr here for use by interrupt call
  122.  
  123. rhAddr        label far ptr
  124.   rhOffset      word       ?
  125.   rhSegment     word       ?
  126.  
  127.  
  128. DriverName       byte       'CD001   '
  129.                  byte       "$"
  130.  
  131. Author           byte       "John H. McCoy"
  132.  
  133. DeviceUnit       byte       ?
  134. DrvDoorOpen      equ        01h             ; bit is zero if closed
  135. DrvDoorUnlocked  equ        02h             ; bit is zero if locked
  136. DriveStatus      dword      0000h           ; drive 0
  137.                  dword      0000h           ; drive 1
  138. dta              label      fptr
  139. dta_off          word       ?
  140. dta_seg          word       ?
  141.  
  142. ;--- ISO9660 Drive 0 --------------------
  143.  
  144. iso0PVD            label byte                            ; block 10h
  145. CDType            byte     1                             ; 1
  146. ID                byte     "CD001"                       ; 2-6
  147. Version           byte     1                             ; 7
  148.                   byte     0                             ; 8
  149. SysID             byte     32 dup (0)                    ; 9-40   a-chars
  150. VolID             byte     "SHSU_ISO00", 22 dup(0)       ; 41-72  d-chars
  151.                   byte     8 dup (0)                     ; 73-80
  152. VolSizeLSB        dword    15h                           ; 81-84
  153. VolSizeMSB        dword    ?                             ; 85-88
  154.                   byte     32 dup (0)                    ; 89-120
  155. SetSizeLSB        word     1
  156. SetSizeMSB        word     ?
  157. SetSeqLSB         word     0
  158. SetSeqMSB         word     ?
  159. BlkSizeLSB        word     2048
  160. BlkSizeMSB        word     ?
  161. PathTabSizeLSB    dword    iso013Len-iso0PathTable
  162. PathTabSizeMSB    dword    ?
  163. PathTabLocLSB     dword    13h                           ; 141-144
  164. PathTabOptLocLSB  dword    ?                             ; 145-148
  165. PathTabLocMSB     dword    ?                             ; 149-152
  166. PathTabOptLocMSB  dword    ?                             ; 152-156
  167. RootDirEnt        label    byte                          ; 157-190
  168.    RDELen_Dr        byte      34
  169.    RDEEAttrRecLen   byte      0
  170.    RDEExtLocLSB     dword     12h
  171.    RDEExtLocMSB     dword     0
  172.    RDEDataLenLSB    dword     iso012Len-iso0RootDir
  173.    RDEDataLenMSB    dword     0
  174.    RDEDate          byte      93,7,10,0,0,0,0
  175.    RDEFlags         byte      _CD_SUBDIR
  176.    RDEFileUnitSize  byte      0
  177.    RDEInterLeave    byte      0
  178.    RDEVolSeqNoLSB   word      0
  179.    RDEVolSeqNoMSB   word      0
  180.    RDEFIDLen        byte      1
  181.    RDEFileID        byte      0
  182. VolSetID          byte     128 dup (0)                   ; 191-318 d-chars
  183. PubID             byte     "SAM HOUSTON STATE UNIVERSITY",100 dup (' ') ;a-chars
  184. PrepID            byte     128 dup (' ')                 ; a-chars
  185. AppID             byte     128 dup (' ')                 ; a-chars
  186. CopyRightFileID   byte     37 dup (' ')                  ; d-chars
  187. AbstractFileID    byte     "README.TXT",27 dup (0)       ; d-chars
  188. BibloFileID       byte     37 dup (' ')                  ; d-chars
  189. CreateDate        byte     "1993071100160000",0          ; 814-830
  190. ModDate           byte     16 dup ('0'),0                ; 831-847
  191. ExpDate           byte     16 dup ('0'),0
  192. EffDate           byte     16 dup ('0'),0
  193. StdVer            byte     1                             ; 882
  194.                   byte     0                             ; 883 (373h)
  195.                   byte     (2048-($-iso0PVD)) dup (0)
  196. iso010Len          word     $-iso0PVD           ; details only assemble to 373h
  197.  
  198. iso0VDSTerm        label    byte                         ; block 011h
  199.                   byte     255                           ; type
  200.                   byte     "CD001"                       ; id
  201.                   byte     1                             ; version
  202.                   byte     0
  203. iso011Len          word     $-iso0VDSTerm
  204.  
  205. iso0RootDir        label    byte                         ; block 012h
  206. RDDot             label    byte
  207.   RDDotRecLen         byte        RDDotEnd-RDDot
  208.   RDDotEAttribLen     byte        0
  209.   RDDotExtLocLSB      dword       12h
  210.   RDDotExtLocMSB      dword       0
  211.   RDDotDataLenLSB     dword       iso012Len-iso0RootDir
  212.   RDDotDataLenMSB     dword       0
  213.   RDDotDate           byte        93,7,10,0,0,0,0
  214.   RDDotFlags          byte        _CD_SUBDIR
  215.   RDDotFileUnitSize   byte        0
  216.   RDDotInterLeave     byte        0
  217.   RDDotVolSeqNoLSB    word        0
  218.   RDDotVolSeqNoMSB    word        0
  219.   RDDotFIDLen         byte        1
  220.   RDDotFileID         byte        0
  221.   RDDotEnd            label byte
  222. RDDDot            label    byte
  223.   RDDDotRecLen        byte        RDDDotEnd-RDDDot
  224.   RDDDotEAttribLen    byte        0
  225.   RDDDotExtLocLSB     dword       12h
  226.   RDDDotExtLocMSB     dword       0
  227.   RDDDotDataLenLSB    dword       iso012Len-iso0RootDir
  228.   RDDDotDataLenMSB    dword       0
  229.   RDDDotDate          byte        93,7,10,0,0,0,0
  230.   RDDDotFlags         byte        _CD_SUBDIR
  231.   RDDDotFileUnitSize  byte        0
  232.   RDDDotInterLeave    byte        0
  233.   RDDDotVolSeqNoLSB   word        0
  234.   RDDDotVolSeqNoMSB   word        0
  235.   RDDDotFIDLen        byte        1
  236.   RDDDotFileID        byte        1
  237.   RDDDotEnd           label byte
  238. RDF1              label    byte
  239.   RDF1RecLen           byte        RDF1End-RDF1
  240.   RDF1EAttribLen       byte        0
  241.   RDF1ExtLocLSB        dword       14h
  242.   RDF1ExtLocMSB        dword       0
  243.   RDF1DataLenLSB       dword       iso014Len-iso0F1
  244.   RDF1DataLenMSB       dword       0
  245.   RDF1Date             byte        93,7,11,0,0,0,0
  246.   RDF1Flags            byte        _CD_NORMAL
  247.   RDF1FileUnitSize     byte        0
  248.   RDF1InterLeave       byte        0
  249.   RDF1VolSeqNoLSB      word        0
  250.   RDF1VolSeqNoMSB      word        0
  251.   RDF1FIDLen           byte        12
  252.   RDF1FileID           byte        "README.TXT"
  253.                        byte        0                        ; pad to even
  254.   RDF1End              byte        0
  255. iso012Len          word     $-iso0RootDir
  256.  
  257. iso0PathTable      label    byte                            ; block 013h
  258.   RootDirPath     label    byte
  259.     RDPLen             byte         1         ; len of DirID
  260.     RDPEAttrib         byte         0
  261.     RDPExtLoc          dword        12h
  262.     RDPParent          word         1
  263.     RDPDirID           byte         0
  264.                        byte         0
  265. iso013Len          word     $-iso0PathTable
  266.  
  267. iso0F1             label    byte                           ; block 014h
  268.    byte  "SHSUDRVX emulates a CD driver/controller with 2 CD drives",cr,lf
  269.    byte  "loaded with ISO ROMS.  Drive 0 has a single text file in",cr,lf
  270.    byte  "the root directory.  This file is also listed in the Abstract",cr,lf
  271.    byte  "field of the primary volume descriptor(PVD).",cr,lf,lf
  272.    byte  "In the root directory of Drive 1 there is a copyright file",cr,lf
  273.    byte  "and a sub-directory.  The copyright file is a text file and is",cr,lf
  274.    byte  "listed in the PVD copyright field.  The HELLO.EXE in the HELLO",cr,lf
  275.    byte  "sub-directory is executable.",cr,lf,lf
  276.    byte  "IOCTL input functions supported:",cr,lf
  277.    byte  "   Return address of Device Header",cr,lf
  278.    byte  "   Read drive bytes",cr,lf
  279.    byte  "   Device status",cr,lf
  280.    byte  "   Return sector size",cr,lf
  281.    byte  "   Return volume size",cr,lf
  282.    byte  "   Media changed",cr,lf
  283.    byte  "      reports -- not changed if drive door is closed and locked",cr,lf
  284.    byte  "              -- don't know if door closed and unlocked",cr,lf
  285.    byte  "              -- changed if door is open",cr,lf
  286.    byte  "IOCTL output functions supported:",cr,lf
  287.    byte  "   Eject disk  -- don't unless you can close it!!!",cr,lf
  288.    byte  "   Lock/Unlock door",cr,lf
  289.    byte  "   Reset drive",cr,lf
  290.    byte  "   Close door",cr,lf,lf
  291.    byte  "SHSUDRVX is a copyright reserved, free use program.",cr,lf
  292.    byte  "(c) John H. McCoy  "
  293.    byte  "August 1993,  Sam Houston State University, TX 77341-2206.",cr,lf
  294.  
  295. iso014Len          word     $-iso0F1
  296.  
  297. ;--- ISO9660 Drive 1 --------------------
  298.  
  299. iso1PVD            label byte                             ; lbn 10h
  300. CDType1            byte     1                             ; 1
  301. ID1                byte     "CD001"                       ; 2-6
  302. Version1           byte     1                             ; 7
  303.                    byte     0                             ; 8
  304. SysID1             byte     32 dup (0)                    ; 9-40   a-chars
  305. VolID1             byte     "SHSU_ISO01", 22 dup(0)       ; 41-72  d-chars
  306.                    byte     8 dup (0)                     ; 73-80
  307. VolSizeLSB1        dword    18h                           ; 81-84
  308. VolSizeMSB1        dword    ?                             ; 85-88
  309.                    byte     32 dup (0)                    ; 89-120
  310. SetSizeLSB1        word     1
  311. SetSizeMSB1        word     ?
  312. SetSeqLSB1         word     1
  313. SetSeqMSB1         word     ?
  314. BlkSizeLSB1        word     2048
  315. BlkSizeMSB1        word     ?
  316. PathTabSizeLSB1    dword    iso113Len-iso1PathTable
  317. PathTabSizeMSB1    dword    ?
  318. PathTabLocLSB1     dword    13h                           ; 141-144
  319. PathTabOptLocLSB1  dword    ?                             ; 145-148
  320. PathTabLocMSB1     dword    ?                             ; 149-152
  321. PathTabOptLocMSB1  dword    ?                             ; 152-156
  322. RootDirEnt1        label    byte                          ; 157-190
  323.    RDELen_Dr1        byte      34
  324.    RDEEAttrRecLen1   byte      0
  325.    RDEExtLocLSB1     dword     12h
  326.    RDEExtLocMSB1     dword     0
  327.    RDEDataLenLSB1    dword     iso112Len-iso1RootDir
  328.    RDEDataLenMSB1    dword     0
  329.    RDEDate1          byte      93,7,10,0,0,0,0
  330.    RDEFlags1         byte      _CD_SUBDIR OR _CD_HIDDEN
  331.    RDEFileUnitSize1  byte      0
  332.    RDEInterLeave1    byte      0
  333.    RDEVolSeqNoLSB1   word      1
  334.    RDEVolSeqNoMSB1   word      0
  335.    RDEFIDLen1        byte      1
  336.    RDEFileID1        byte      0
  337. VolSetID1          byte     128 dup (0)                   ; 191-318 d-chars
  338. PubID1             byte     "SAM HOUSTON STATE UNIVERSITY",100 dup (' ') ;a-chars
  339. PrepID1            byte     128 dup (' ')                 ; a-chars
  340. AppID1             byte     128 dup (' ')                 ; a-chars
  341. CopyRightFileID1   byte     "COPYRITE.TXT",25 dup (0)     ; d-chars
  342. AbstractFileID1    byte     37 dup (' ')                  ; d-chars
  343. BibloFileID1       byte     37 dup (' ')                  ; d-chars
  344. CreateDate1        byte     "1993072900160000",0          ; 814-830
  345. ModDate1           byte     16 dup ('0'),0                ; 831-847
  346. ExpDate1           byte     16 dup ('0'),0
  347. EffDate1           byte     16 dup ('0'),0
  348. StdVer1            byte     1                             ; 882
  349.                    byte     0
  350.                    byte     (2048-($-iso1PVD)) dup (0)
  351. iso110Len          word     $-iso1PVD           ; details only assemble to 373h
  352.  
  353. iso1VDSTerm        label    byte                               ; lbn 11h
  354.                   byte     255                           ; type
  355.                   byte     "CD001"                       ; id
  356.                   byte     1                             ; version
  357.                   byte     0
  358. iso111Len          word     $-iso1VDSTerm
  359.  
  360. iso1RootDir        label    byte                               ; lbn 12h
  361. RDDot1             label    byte
  362.   RDDotRecLen1         byte        RDDotEnd1-RDDot1
  363.   RDDotEAttribLen1     byte        0
  364.   RDDotExtLocLSB1      dword       12h
  365.   RDDotExtLocMSB1      dword       0
  366.   RDDotDataLenLSB1     dword       iso112Len-iso1RootDir
  367.   RDDotDataLenMSB1     dword       0
  368.   RDDotDate1           byte        93,7,10,0,0,0,0
  369.   RDDotFlags1          byte        _CD_SUBDIR OR _CD_HIDDEN
  370.   RDDotFileUnitSize1   byte        0
  371.   RDDotInterLeave1     byte        0
  372.   RDDotVolSeqNoLSB1    word        1
  373.   RDDotVolSeqNoMSB1    word        0
  374.   RDDotFIDLen1         byte        1
  375.   RDDotFileID1         byte        0
  376.   RDDotEnd1            label byte
  377. RDDDot1            label    byte
  378.   RDDDotRecLen1        byte        RDDDotEnd1-RDDDot1
  379.   RDDDotEAttribLen1    byte        0
  380.   RDDDotExtLocLSB1     dword       12h
  381.   RDDDotExtLocMSB1     dword       0
  382.   RDDDotDataLenLSB1    dword       iso112Len-iso1RootDir
  383.   RDDDotDataLenMSB1    dword       0
  384.   RDDDotDate1          byte        93,7,29,0,0,0,0
  385.   RDDDotFlags1         byte        _CD_SUBDIR OR _CD_HIDDEN
  386.   RDDDotFileUnitSize1  byte        0
  387.   RDDDotInterLeave1    byte        0
  388.   RDDDotVolSeqNoLSB1   word        1
  389.   RDDDotVolSeqNoMSB1   word        0
  390.   RDDDotFIDLen1        byte        1
  391.   RDDDotFileID1        byte        1
  392.   RDDDotEnd1           label byte
  393. RDF11          label    byte
  394.   RDF1RecLen1           byte        RDF11End-RDF11
  395.   RDF1EAttribLen1       byte        0
  396.   RDF1ExtLocLSB1        dword       14h
  397.   RDF1ExtLocMSB1        dword       0
  398.   RDF1DataLenLSB1       dword       iso114Len-iso1F1
  399.   RDF1DataLenMSB1       dword       0
  400.   RDF1Date1             byte        93,7,29,0,0,0,0
  401.   RDF1Flags1            byte        _CD_NORMAL
  402.   RDF1FileUnitSize1     byte        0
  403.   RDF1InterLeave1       byte        0
  404.   RDF1VolSeqNoLSB1      word        1
  405.   RDF1VolSeqNoMSB1      word        0
  406.   RDF1FIDLen1           byte        12
  407.   RDF1FileID1           byte        "COPYRITE.TXT"
  408.                         byte        0                        ; pad to even
  409.   RDF11End     label    byte
  410. RDSub10          label    byte
  411.   RDS1RecLen1           byte        RDS10End-RDSub10
  412.   RDS1EAttribLen1       byte        0
  413.   RDS1ExtLocLSB1        dword       15h
  414.   RDS1ExtLocMSB1        dword       0
  415.   RDS1DataLenLSB1       dword       iso115Len-iso1SubDir1
  416.   RDS1DataLenMSB1       dword       0
  417.   RDS1Date1             byte        93,8,07,0,0,0,0
  418.   RDS1Flags1            byte        _CD_SUBDIR
  419.   RDS1FileUnitSize1     byte        0
  420.   RDS1InterLeave1       byte        0
  421.   RDS1VolSeqNoLSB1      word        1
  422.   RDS1VolSeqNoMSB1      word        0
  423.   RDS1FIDLen1           byte        5
  424.   RDS1FileID1           byte        "HELLO"
  425.   RDS10End     label    byte
  426.                         byte        0
  427. iso112Len          word     $-iso1RootDir
  428.  
  429. iso1PathTable      label    byte                              ; lbn 13h
  430.   RootDirPath1     label    byte
  431.     RDPLen1             byte         1
  432.     RDPEAttrib1         byte         0
  433.     RDPExtLoc1          dword        12h
  434.     RDPParent1          word         1
  435.     RDPDirID1           byte         0
  436.                         byte         0
  437.     SDPLen1             byte         5       ; len of dirid field
  438.     SDPEAttrib1         byte         0
  439.     SDPExtLoc1          dword        15h
  440.     SDPParent1          word         1
  441.     SDPDirID1           byte         "HELLO"
  442.                         byte         0
  443. iso113Len          word     $-iso1PathTable
  444.  
  445. iso1F1             label    byte                              ; lbn 14h
  446.    byte "Copyright file for device 1 of John's CD Drive Emulator.",cr,lf,lf
  447.    byte  "SHSUDRVX is a copyright reserved, free use program.",cr,lf
  448.    byte  "(c) John H. McCoy  "
  449.    byte  "August 1993,  Sam Houston State University, TX 77341-2206.",cr,lf
  450. iso114Len          word     $-iso1F1
  451.  
  452. iso1SubDir1        label    byte                               ; lbn 15h
  453. SDDot1             label    byte
  454.   SDDotRecLen1         byte        SDDotEnd1-SDDot1
  455.   SDDotEAttribLen1     byte        0
  456.   SDDotExtLocLSB1      dword       15h
  457.   SDDotExtLocMSB1      dword       0
  458.   SDDotDataLenLSB1     dword       iso115Len-iso1SubDir1
  459.   SDDotDataLenMSB1     dword       0
  460.   SDDotDate1           byte        93,8,8,0,0,0,0
  461.   SDDotFlags1          byte        _CD_SUBDIR
  462.   SDDotFileUnitSize1   byte        0
  463.   SDDotInterLeave1     byte        0
  464.   SDDotVolSeqNoLSB1    word        1
  465.   SDDotVolSeqNoMSB1    word        0
  466.   SDDotFIDLen1         byte        1
  467.   SDDotFileID1         byte        0
  468.   SDDotEnd1            label byte
  469. SDDDot1            label    byte
  470.   SDDDotRecLen1        byte        SDDDotEnd1-SDDDot1
  471.   SDDDotEAttribLen1    byte        0
  472.   SDDDotExtLocLSB1     dword       15h
  473.   SDDDotExtLocMSB1     dword       0
  474.   SDDDotDataLenLSB1    dword       iso112Len-iso1RootDir
  475.   SDDDotDataLenMSB1    dword       0
  476.   SDDDotDate1          byte        93,7,29,0,0,0,0
  477.   SDDDotFlags1         byte        _CD_SUBDIR
  478.   SDDDotFileUnitSize1  byte        0
  479.   SDDDotInterLeave1    byte        0
  480.   SDDDotVolSeqNoLSB1   word        1
  481.   SDDDotVolSeqNoMSB1   word        0
  482.   SDDDotFIDLen1        byte        1
  483.   SDDDotFileID1        byte        1
  484.   SDDDotEnd1           label byte
  485. SDF12          label    byte
  486.   SDF2RecLen1           byte        SDF12End-SDF12
  487.   SDF2EAttribLen1       byte        0
  488.   SDF2ExtLocLSB1        dword       16h
  489.   SDF2ExtLocMSB1        dword       0
  490.   SDF2DataLenLSB1       dword       iso116Len-iso1F2
  491.   SDF2DataLenMSB1       dword       0
  492.   SDF2Date1             byte        93,8,8,0,0,0,0
  493.   SDF2Flags1            byte        _CD_NORMAL
  494.   SDF2FileUnitSize1     byte        0
  495.   SDF2InterLeave1       byte        0
  496.   SDF2VolSeqNoLSB1      word        1
  497.   SDF2VolSeqNoMSB1      word        0
  498.   SDF2FIDLen1           byte        9
  499.   SDF2FileID1           byte        "HELLO.ASM"
  500.   SDF12End     label    byte
  501. SDF13          label    byte
  502.   SDF3RecLen1           byte        SDF13End-SDF13
  503.   SDF3EAttribLen1       byte        0
  504.   SDF3ExtLocLSB1        dword       17h
  505.   SDF3ExtLocMSB1        dword       0
  506.   SDF3DataLenLSB1       dword       iso117Len-iso1F3
  507.   SDF3DataLenMSB1       dword       0
  508.   SDF3Date1             byte        93,8,8,0,0,0,0
  509.   SDF3Flags1            byte        _CD_NORMAL
  510.   SDF3FileUnitSize1     byte        0
  511.   SDF3InterLeave1       byte        0
  512.   SDF3VolSeqNoLSB1      word        1
  513.   SDF3VolSeqNoMSB1      word        0
  514.   SDF3FIDLen1           byte        9
  515.   SDF3FileID1           byte        "HELLO.EXE"
  516.   SDF13End     label    byte
  517.                         byte        0
  518. iso115Len          word     $-iso1SubDir1
  519.  
  520. iso1F2            label    byte                                ; lbn 16h
  521.  
  522.  byte ";",cr,lf
  523.  byte ";        hello.asm",cr,lf
  524.  byte ";",cr,lf
  525.  byte cr,lf
  526.  byte ".model small, os_dos",cr,lf
  527.  byte cr,lf
  528.  byte "option nokeyword:<length name>",cr,lf
  529.  byte "option expr16",cr,lf
  530.  byte cr,lf
  531.  byte "cr                      equ     13",cr,lf
  532.  byte "lf                      equ     10",cr,lf
  533.  byte cr,lf
  534.  byte "Display   MACRO  msg",cr,lf
  535.  byte "         mov     dx,offset msg",cr,lf
  536.  byte "         mov     ah,9",cr,lf
  537.  byte "         int     21h",cr,lf
  538.  byte "ENDM",cr,lf
  539.  byte cr,lf
  540.  byte ".data",cr,lf
  541.  byte cr,lf
  542.  byte "HelloMsg byte cr,lf",cr,lf
  543.  byte 'byte "Greetings from Sam Houston State University in '
  544.  byte 'Huntsville, TX.",cr,lf,lf',cr,lf
  545.  byte 'byte "Sam Houston State has an enrollment of some 12,000'
  546.  byte ' students.  It",cr,lf',cr,lf
  547.  byte 'byte "is located 68 miles North of Houston in the scenic pine'
  548.  byte ' forests of",cr,lf',cr,lf
  549.  byte 'byte "East Texas.",cr, lf,lf,''$''',cr,lf
  550.  byte cr,lf
  551.  byte ".code",cr,lf
  552.  byte cr,lf
  553.  byte "   .startup",cr,lf
  554.  byte "   Display HelloMsg",cr,lf
  555.  byte "   .exit",cr,lf
  556.  byte "END",cr,lf
  557. iso116Len          word     $-iso1F2
  558. ; ------------------------------------------------------------------------
  559. ;  Warning!!! Don't mess with the following code.
  560. ;  It is the machine code for HELLO.EXE.
  561. ; ------------------------------------------------------------------------
  562. iso1F3            label    byte                                ; lbn 17h
  563.  byte "MZ·   D "
  564.  byte ""
  565.  byte ""
  566.  byte ""
  567.  byte ""
  568.  byte ""
  569.  byte ""
  570.  byte ""
  571.  byte ""
  572.  byte ""
  573.  byte "║Ä┌î╙+┌╤π╤π╤π╤π·Ä╥π√║┤"
  574.  byte ht,"═!┤L═!",cr,lf
  575.  byte "Greetings from Sam Houston State University in Huntsville, TX.",cr,lf,lf
  576.  byte "Sam Houston State has an enrollment of some 12,000 students.  It",cr,lf
  577.  byte "is located 68 miles North of Houston in the scenic pine forests of",cr,lf
  578.  byte "East Texas.",cr,lf,lf,'$'
  579. iso117Len          word     $-iso1F3
  580.  
  581.  
  582. ;************************************************************************
  583. ;  Driver Strategy routine
  584. ;************************************************************************
  585.  
  586. Strategy    proc     far
  587.  
  588.    ;  es:bx contains request header pointer.  save it.
  589.       mov    cs:rhOffset, bx
  590.       mov    cs:rhSegment, es
  591.       ret
  592.  
  593. Strategy    endp
  594.  
  595. ;************************************************************************
  596. ;  Driver Interrupt routine
  597. ;************************************************************************
  598.  
  599. Interrupt    proc  far uses ax bx cx dx si di ds es
  600.  
  601.    ;  setup ds addressing
  602.       push   cs
  603.       pop    ds
  604.  
  605.    ;  process command
  606.       les      bx, rhAddr                ; make sure we have rh addr
  607.       mov      al, es:[bx].rh.SubUnit
  608.       .if   al >= SubUnits
  609.             mov   ax,(DeviceDone OR DeviceError OR DE_UnknownUnit)
  610.             jmp    ExitWithStatus
  611.       .endif
  612.       mov      DeviceUnit, al
  613.       mov      al, es:[bx].rh.command
  614.       xor      ah, ah
  615.       .if      (al ==128)
  616.           jmp  ReadLong
  617.       .elseif  (al == 3)
  618.           jmp IoctlInput
  619.       .elseif  (al == 12)
  620.           jmp IoctlOutput
  621.       .elseif  (al == 13)
  622.           ;Open  Just drop on through.
  623.       .elseif  (al == 14 )
  624.           ;Close Just drop on through.
  625.       .elseif  (al ==131 )
  626.           ;seek  Just drop on through
  627.       .else
  628.           jmp   UnknownCommand
  629.       .endif
  630.  
  631.        mov   ax, (DeviceDone)
  632.        jmp   ExitWithStatus
  633.  
  634.  
  635. IoctlInput:
  636.       les      bx, es:[bx].rhIOCTL.CBPtr
  637.       mov      al, byte ptr es:[bx]           ; 1st byte of dta is subcommand
  638.       .if      al == IOCtl_RDHACmd
  639.          lea   ax, DevHeader
  640.          mov   word ptr es:[bx].IoCB_RDHA.DeviceHeaderAddress, ax
  641.          mov   ax, ds
  642.          mov   word ptr es:[bx].IoCB_RDHA.DeviceHeaderAddress+2, ax
  643.          mov   ax, DeviceDone
  644.          jmp   ExitRestoreRH
  645.       .elseif   al == IOCtl_ReadDriveBytes
  646.          mov   ax, 0
  647.          mov   word ptr es:[bx+1], ax
  648.          mov   ax, DeviceDone
  649.          jmp   ExitRestoreRH
  650.       .elseif   al == IOCtl_DevStatCmd
  651.          mov   al, DeviceUnit
  652.          .if   al == 1
  653.             mov    al, 4
  654.          .endif
  655.          cbw
  656.          mov   si, ax
  657.          mov   ax, word ptr [si+DriveStatus]
  658.          mov   word ptr es:[bx+1], ax
  659.          mov   ax, 0
  660.          mov   word ptr es:[bx+3], ax
  661.          mov   ax, DeviceDone
  662.          jmp   ExitRestoreRH
  663.       .elseif   al == IOCtl_ReturnSectorSize
  664.          mov   ax, 0
  665.          mov   word ptr es:[bx+1], ax
  666.          mov   ax, 2048
  667.          mov   word ptr es:[bx+2], ax
  668.          mov   ax, DeviceDone
  669.          jmp   ExitRestoreRH
  670.       .elseif   al == IOCtl_ReturnVolumeSize
  671.          .if  DeviceUnit == 0
  672.                mov   ax, word ptr VolSizeLSB
  673.                mov   word ptr es:[bx+1], ax
  674.                mov   ax, word ptr VolSizeLSB+2
  675.                mov   word ptr es:[bx+3], ax
  676.          .else
  677.                mov   ax, word ptr VolSizeLSB1
  678.                mov   word ptr es:[bx+1], ax
  679.                mov   ax, word ptr VolSizeLSB1+2
  680.                mov   word ptr es:[bx+3], ax
  681.          .endif
  682.          mov   ax, DeviceDone
  683.          jmp   ExitRestoreRH
  684.       .elseif   al == IOCtl_MediaChangedCmd
  685.          mov   al, DeviceUnit
  686.          .if   al == 1
  687.             mov    al, 4
  688.          .endif
  689.          cbw
  690.          mov   si, ax
  691.          mov   ax, word ptr [si+DriveStatus]
  692.          and   ax, DrvDoorUnlocked
  693.          .if    ax == 0                         ; door is locked
  694.             mov   byte ptr es:[bx+1], 01h       ; report media hasn't changed
  695.          .else
  696.             mov   ax, word ptr [si+DriveStatus]
  697.             and   ax, DrvDoorOpen
  698.             .if   ax == 0
  699.                mov   byte ptr es:[bx+1], 0h    ; closed, report don't know
  700.             .else
  701.                mov   byte ptr es:[bx+1], 0ffh    ; open, report media change
  702.             .endif
  703.          .endif
  704.          mov   ax, DeviceDone
  705.          jmp   ExitRestoreRH
  706.       .endif
  707.       jmp      UnknownCommand
  708.  
  709. IoctlOutput:
  710.       les      bx, es:[bx].rhIOCTL.CBPtr
  711.       mov      al, byte ptr es:[bx]             ; 1st byte of dta is subcommand
  712.       .if      al == 0                          ; eject disk
  713.          mov   al, DeviceUnit
  714.          .if   al == 1
  715.             mov  al, 4
  716.          .endif
  717.          cbw
  718.          mov   si, ax
  719.          mov   ax, DrvDoorUnlocked OR DrvDoorOpen
  720.          mov   word ptr [si+DriveStatus], ax
  721.          mov   ax, DeviceDone
  722.          jmp   ExitRestoreRH
  723.       .elseif  al == 1              ; lock/unlock door
  724.          mov   al, DeviceUnit
  725.          .if   al == 1
  726.             mov   al, 4
  727.          .endif
  728.          cbw
  729.          mov   si, ax
  730.          cmp   byte ptr es:[bx+1], 0
  731.          jne    @F
  732.                mov   ax, word ptr [si+DriveStatus]
  733.                or    ax, DrvDoorUnlocked        ; unlock door
  734.                mov   word ptr [si+DriveStatus], ax
  735.                mov   ax, DeviceDone
  736.                jmp   ExitRestoreRH
  737.      @@:
  738.          mov   word ptr [si+DriveStatus], 0     ; closed and locked
  739.          mov   ax, DeviceDone
  740.          jmp   ExitRestoreRH
  741.       .elseif al == 2              ; reset drive
  742.          mov   al, DeviceUnit
  743.          .if   al == 1
  744.             mov    al, 4
  745.          .endif
  746.          cbw
  747.          mov   si, ax
  748.          xor    ax, ax
  749.          mov   word ptr [si+DriveStatus], ax
  750.          mov   ax, DeviceDone
  751.          jmp   ExitRestoreRH
  752.       .elseif al == 5              ; close door
  753.          mov   al, DeviceUnit
  754.          .if   al == 1
  755.             mov    al, 4
  756.          .endif
  757.          cbw
  758.          mov   si, ax
  759.          mov   ax, word ptr [si+DriveStatus]
  760.          or    ax, DrvDoorUnlocked
  761.          and   ax, NOT(DrvDoorOpen)
  762.          mov   word ptr [si+DriveStatus], ax
  763.          mov   ax, DeviceDone
  764.          jmp   ExitRestoreRH
  765.       .endif
  766.       jmp      UnknownCommand
  767.  
  768.  
  769. ReadLong:
  770.  
  771.     mov   al, DeviceUnit
  772.     .if   al == 1
  773.        mov al, 4
  774.     .endif
  775.     cbw
  776.     mov   si, ax
  777.     mov   ax, word ptr [si+DriveStatus]
  778.     and    ax, DrvDoorOpen
  779.  
  780.     .if  ax != 0
  781.        mov   ax,(DeviceDone OR DeviceError OR DE_DeviceNotReady)
  782.        jmp   ExitWithStatus
  783.     .endif
  784.  
  785.     .if word ptr es:[bx+2].rhTransfer.StartSector != 0
  786.        mov   ax,(DeviceDone OR DeviceError OR DE_SectorNoFound)
  787.        jmp   ExitWithStatus
  788.     .endif
  789.  
  790.     mov    ax, word ptr es:[bx].rhTransfer.DtaPtr
  791.     mov    dta_off, ax
  792.     mov    ax, word ptr es:[bx+2].rhTransfer.DtaPtr
  793.     mov    dta_seg, ax
  794.  
  795.     mov   ax, word ptr es:[bx].rhTransfer.StartSector
  796.  
  797.     .if es:[bx].rh.SubUnit == 0
  798.       .if (ax < 010h) || (ax > word ptr VolSizeLSB)
  799.         mov   ax,(DeviceDone OR DeviceError OR DE_SectorNoFound)
  800.         jmp   ExitWithStatus
  801.       .endif
  802.       mov   ah, byte ptr VolSizeLSB
  803.       sub   ah, al
  804.       .if  ah > byte ptr es:[bx].rhTransfer.SectorCount
  805.           mov  ah, byte ptr es:[bx].rhTransfer.SectorCount
  806.       .endif
  807.       .if al == 010h         ; PVD
  808.         mov   si, offset iso0PVD
  809.         mov   cx, iso010Len
  810.         les   di, dta
  811.         cld
  812.         rep   movsb
  813.         .if  ah > 1
  814.            dec  ah
  815.            inc  al
  816.            add  dta_off, 2048
  817.         .endif
  818.       .endif
  819.       .if al == 011h     ; VDSTerm
  820.         mov   si, offset iso0VDSTerm
  821.         mov   cx, iso011Len
  822.         les   di, dta
  823.         cld
  824.         rep   movsb
  825.         .if  ah > 1
  826.            dec  ah
  827.            inc  al
  828.            add  dta_off, 2048
  829.         .endif
  830.       .endif
  831.       .if al == 012h     ; RootDir
  832.         mov   si, offset iso0RootDir
  833.         mov   cx, iso012Len
  834.         les   di, dta
  835.         cld
  836.         rep   movsb
  837.         .if  ah > 1
  838.            dec  ah
  839.            inc  al
  840.            add  dta_off, 2048
  841.         .endif
  842.       .endif
  843.       .if al == 013h     ; Path
  844.         mov   si, offset iso0PathTable
  845.         mov   cx, iso013Len
  846.         les   di, dta
  847.         cld
  848.         rep   movsb
  849.         .if  ah > 1
  850.            dec  ah
  851.            inc  al
  852.            add  dta_off, 2048
  853.         .endif
  854.       .endif
  855.       .if al == 014h     ; F1
  856.         mov   si, offset iso0F1
  857.         mov   cx, iso014Len
  858.         les   di, dta
  859.         cld
  860.         rep   movsb
  861.         .if  ah > 1
  862.            dec  ah
  863.            inc  al
  864.            add  dta_off, 2048
  865.         .endif
  866.       .endif
  867.        mov   ax, (DeviceDone)
  868.        jmp   ExitRestoreRH
  869.    .elseif es:[bx].rh.SubUnit == 1
  870.       .if (ax < 10h) || (ax >= word ptr VolSizeLSB1)
  871.         mov   ax,(DeviceDone OR DeviceError OR DE_SectorNoFound)
  872.         jmp   ExitWithStatus
  873.       .endif
  874.       mov   ah, byte ptr VolSizeLSB1
  875.       sub   ah, al
  876.       .if  ah > byte ptr es:[bx].rhTransfer.SectorCount
  877.           mov  ah, byte ptr es:[bx].rhTransfer.SectorCount
  878.       .endif
  879.       .if al == 010h         ; PVD
  880.         mov   si, offset iso1PVD
  881.         mov   cx, iso110Len
  882.         les   di, dta
  883.         cld
  884.         rep   movsb
  885.         .if  ah > 1
  886.            dec  ah
  887.            inc  al
  888.            add  dta_off, 2048
  889.         .endif
  890.       .endif
  891.       .if al == 011h     ; VDSTerm
  892.         mov   si, offset iso1VDSTerm
  893.         mov   cx, iso111Len
  894.         les   di, dta
  895.         cld
  896.         rep   movsb
  897.         .if  ah > 1
  898.            dec  ah
  899.            inc  al
  900.            add  dta_off, 2048
  901.         .endif
  902.       .endif
  903.       .if al == 012h     ; RootDir
  904.         mov   si, offset iso1RootDir
  905.         mov   cx, iso112Len
  906.         les   di, dta
  907.         cld
  908.         rep   movsb
  909.         .if  ah > 1
  910.            dec  ah
  911.            inc  al
  912.            add  dta_off, 2048
  913.         .endif
  914.       .endif
  915.       .if al == 013h     ; Path
  916.         mov   si, offset iso1PathTable
  917.         mov   cx, iso113Len
  918.         les   di, dta
  919.         cld
  920.         rep   movsb
  921.         .if  ah > 1
  922.            dec  ah
  923.            inc  al
  924.            add  dta_off, 2048
  925.         .endif
  926.       .endif
  927.       .if al == 014h     ; F1
  928.         mov   si, offset iso1F1
  929.         mov   cx, iso114Len
  930.         les   di, dta
  931.         cld
  932.         rep   movsb
  933.         .if  ah > 1
  934.            dec  ah
  935.            inc  al
  936.            add  dta_off, 2048
  937.         .endif
  938.       .endif
  939.       .if al == 015h     ; SubDir1
  940.         mov   si, offset iso1SubDir1
  941.         mov   cx, iso115Len
  942.         les   di, dta
  943.         cld
  944.         rep   movsb
  945.         .if  ah > 1
  946.            dec  ah
  947.            inc  al
  948.            add  dta_off, 2048
  949.         .endif
  950.       .endif
  951.       .if al == 016h     ; F2
  952.         mov   si, offset iso1F2
  953.         mov   cx, iso116Len
  954.         les   di, dta
  955.         cld
  956.         rep   movsb
  957.         .if  ah > 1
  958.            dec  ah
  959.            inc  al
  960.            add  dta_off, 2048
  961.         .endif
  962.       .endif
  963.       .if al == 017h     ; F3
  964.         mov   si, offset iso1F3
  965.         mov   cx, iso117Len
  966.         les   di, dta
  967.         cld
  968.         rep   movsb
  969.         .if  ah > 1
  970.            dec  ah
  971.            inc  al
  972.            add  dta_off, 2048
  973.         .endif
  974.       .endif
  975.        mov   ax, (DeviceDone)
  976.        jmp   ExitRestoreRH
  977.    .endif
  978.    mov   ax,(DeviceDone OR DeviceError OR DE_UnknownUnit)
  979.    jmp    ExitWithStatus
  980.  
  981. UnknownCommand:
  982.  
  983.       mov      ax, (DeviceDone OR DeviceError OR DE_UnknownCommand)
  984.  
  985.  
  986. ExitRestoreRH:
  987.  
  988.       les      bx, rhAddr                ; restore rh ptr
  989.  
  990. ExitWithStatus:
  991.  
  992.       mov   es:[bx].rh.Status, ax
  993.  
  994. Exit0:
  995.       ret
  996.  
  997. Interrupt   endp
  998.  
  999. ToHex proc near C public uses ax bx cx dx, Num:word
  1000.       mov   cl, 4
  1001.       mov   ch, 4
  1002.       mov   ah, 02h
  1003.       mov   dx, Num
  1004.       .while ch > 0
  1005.           rol   dx, cl
  1006.           mov   bx, dx
  1007.           and   dx, 0fh
  1008.           .if dl < 0Ah
  1009.               add  dl, '0'
  1010.           .else
  1011.               add  dl, 'A' - 0Ah
  1012.           .endif
  1013.           int   21h
  1014.           mov   dx, bx
  1015.           dec   ch
  1016.       .endw
  1017.       ret
  1018. ToHex    endp
  1019.  
  1020.  
  1021.      byte "End of DRVX"
  1022.  
  1023. LastByte               label byte
  1024. ;============================================================================
  1025. ;  everything below this line is discarded after installing the driver
  1026.  
  1027. DriverParm              equ     'D'     ; command line parms /D:, etc
  1028. ArgumentNotFound        EQU     2       ; Unrecognized argument
  1029. NoArgumentsFound        EQU     1       ; No argument in command line
  1030. ArgumentFound           EQU     0       ; Ok argument in command line
  1031.  
  1032. UnInstall               equ     2
  1033. DontInstall             equ     1
  1034. Install                 equ     0
  1035.  
  1036. InstallFlag             byte    0
  1037.  
  1038. _SS    word ?
  1039. _SP    word ?
  1040.  
  1041.  
  1042. Init  proc far
  1043.                                  ; fix regs for Install/uninstall
  1044.       push     ds                ; point to psp so we can access command line
  1045.       pop      es                ; using es or for uninstall
  1046.       push     cs                ; now set DS to CS
  1047.       pop      ds
  1048.  
  1049.       call ParseCommandLine
  1050.  
  1051.       .if InstallFlag == Install
  1052.           .if InstallFlag == Install
  1053.               call Link
  1054.               .if (InstallFlag == Install)
  1055.                   Display  InstallMsg
  1056.                   Display  DriverMsg
  1057.                   Display  DriverName
  1058.               .endif
  1059.               push   es                     ; reset ds to psp
  1060.               pop    ds
  1061.  
  1062.               mov    ax, ds:[2Ch]           ; find environment and release it
  1063.               mov    es, ax
  1064.               mov    ah, 49h
  1065.               int    21h
  1066.               sub    ax, ax
  1067.               mov    ds:[2Ch], ax           ; zero the evironment ptr
  1068.  
  1069.               if  (LastByte-DevHeader+1) mod 16
  1070.                   roundup = 1
  1071.               else
  1072.                   roundup = 0
  1073.               endif
  1074.  
  1075.               mov     dx,((LastByte-DevHeader)+1+100h)/16+roundup; para to keep
  1076.               mov     ah,31h        ; stay resident and
  1077.               int     21h             ; exit
  1078.  
  1079.           .endif
  1080.       .elseif InstallFlag == UnInstall
  1081.           call UnInstallDriver              ; es points to our psp
  1082.  
  1083.       .endif
  1084.  
  1085.       .exit
  1086.  
  1087. Init endp
  1088.  
  1089. Link   proc near uses es
  1090.       mov      ax, 5200h               ; get list of list
  1091.       int      21h                     ; we assume DOS 3.1 or later
  1092.       add      bx, 22h                 ; es:bx[22] is NUL device header
  1093.       mov      ax, es:[bx]               ; put NUL.next in our header
  1094.       mov      word ptr NextDriver, ax
  1095.       mov      ax, es:[bx+2]
  1096.       mov      word ptr NextDriver+2, ax
  1097.       mov      ax, 0                   ; then point NUL header at us
  1098.       mov      es:[bx], ax
  1099.       mov      es:[bx+2], cs
  1100.       ret
  1101. Link   endp
  1102.  
  1103. UnInstallDriver proc near
  1104.  
  1105.    local _bx,_es:word
  1106.  
  1107.       push     es                      ; save our psp address
  1108.       mov      ax, 5200h               ; get list of list
  1109.       int      21h                     ; we assume DOS 3.1 or later
  1110.       add      bx, 22h                 ; es:bx[22] is NUL (1st) device header
  1111.                                        ; es:bx now pointing at NUL header
  1112.    TryNext:
  1113.       cld
  1114.       mov      _bx, bx                 ; save current header addr
  1115.       mov      _es, es
  1116.       les      bx, es:[bx]             ; load next header addr into es:bx
  1117.       mov      ax, es
  1118.       cmp      bx, 0FFFFh              ; end of drivers?
  1119.       je       DriverNotInstalled
  1120.       mov      cx, 8
  1121.       lea      di, DeviceName[bx]      ; es:di is chained device name
  1122.       mov      si, offset DeviceName   ; ds:si is our device name
  1123.       repe     cmpsb                   ; if equ its the one we are looking for
  1124.       jne      TryNext
  1125.       push     ds
  1126.       mov      ax, es                  ; es:bx is addr of driver being removed
  1127.       mov      ds, ax                  ; put it into ds:si
  1128.       mov      si, bx                  ;
  1129.       mov      cx, 4                   ;
  1130.       mov      es, _es                 ;
  1131.       mov      di, _bx                 ; previous header now in es:di
  1132.       rep      movsb                   ; move address ds:si -> es:di
  1133.       mov      es, ax                  ; es now points at unlinked driver
  1134.       pop      ds                      ; cs=ds=@code -- need this for net
  1135.       mov      ax, es                   ; locate the
  1136.       sub      ax, 10h                  ; psp of installed driver
  1137.       mov      es, ax                   ;
  1138.       mov      bx, 16h                  ; installed drivers parent psp pointer
  1139.       pop      ax                       ; our psp address(pushed es above)
  1140.       mov      es:[bx],ax               ; make us parent of TSR
  1141.       lea      ax, UnInstallExit        ; set TSRs
  1142.       mov      bx, 0Ah                  ; terminate address
  1143.       mov      es:[bx], ax              ; to come back to
  1144.       mov      ax, cs
  1145.       mov      es:[bx]+2, ax            ; us
  1146.       mov      bx, es                   ; now make TSRs psp the
  1147.       mov      ah, 50h                  ; current psp
  1148.       int      21h
  1149.  
  1150.       push     bp
  1151.       mov      _SS, ss                  ; save stack info
  1152.       mov      _SP, sp
  1153.       mov      ah, 4Ch                  ; terminate TSR and
  1154.       int      21h                      ; come back to next
  1155.  
  1156.     UnInstallExit:
  1157.       mov      ax, cs
  1158.       mov      ds, ax                   ; reestablish addressing
  1159.       mov      sp, _SP                  ; and stack info
  1160.       mov      ss, _SS
  1161.       pop      bp
  1162.  
  1163.       display DriverMsg
  1164.       display DriverName                ; tell the world we did it
  1165.       display UnInstallMsg
  1166.       ret
  1167.  
  1168.   DriverNotInstalled:
  1169.       Display  CouldNotRemoveMsg
  1170.       display DriverMsg
  1171.       display  DriverName
  1172.       ret
  1173.  
  1174. UnInstallDriver endp
  1175.  
  1176. ParseCommandLine       proc near  uses es
  1177.  
  1178.       ;* If driver is loaded from config.sys using device=drivername parms
  1179.       ;* then rhINIT points to the first character following the drivername
  1180.       ;* and a CR follows the last parm.  When loaded by executing, the
  1181.       ;* command line is available in the PSP.(len +80h, 1st ch +81h, no CR)
  1182.  
  1183.       sub      ch, ch
  1184.       mov      di, 80h            ; command line length @ +80h
  1185.       mov      cl, es:[di]
  1186.  
  1187.       mov      al, '?'
  1188.       call     GetParm
  1189.       .if       ax == NoArgumentsFound
  1190.          jmp   CopyDeviceName
  1191.       .elseif   ax == ArgumentFound       ; /?  user needs help on usage
  1192.          Display  UsageMsg
  1193.          mov   al,DontInstall
  1194.          mov   InstallFlag, al
  1195.          jmp   exit
  1196.       .endif
  1197.  
  1198.       sub      ch, ch
  1199.       mov      di, 80h            ; command line length @ +80h
  1200.       mov      cl, es:[di]
  1201.       mov      al, 'U'            ; /U unInstall driver
  1202.       call     GetParm
  1203.       .if ax == ArgumentFound
  1204.           mov      InstallFlag, UnInstall
  1205.       .endif
  1206.  
  1207.       mov      al, DriverParm
  1208.       call     FindParm
  1209.      .if   ax == ArgumentFound
  1210.          mov      dx, sizeof DeviceName
  1211.          lea      si, DeviceName
  1212.          call     MoveName
  1213.       .endif
  1214.  
  1215.   CopyDeviceName:                               ; so we can display it
  1216.  
  1217.       mov   cx, 8
  1218.       push  ds
  1219.       pop   es
  1220.       lea   si, DeviceName
  1221.       lea   di, DriverName
  1222.       cld
  1223.       rep    movsb
  1224.  
  1225.  
  1226. Exit: ret
  1227.  
  1228. ParseCommandLine       endp
  1229.  
  1230. UsageMsg    db cr, lf,"Usage:  SHSUDRVX"
  1231.             db " [/?] [/D:DriverName] [/U]",cr,lf,"$"
  1232.  
  1233. InstallMsg  db cr,lf,"SHSUDRVX V1.0 CD Driver Installed.",cr,lf
  1234.             db "Copyright 1993, 1995, John H. McCoy.",cr, lf
  1235.             db "Sam Houston State University","$"
  1236. DriverMsg   db cr,lf,"Driver Name:  ","$"
  1237. UnInstallMsg       db " Uninstalled and memory freed",cr,lf,"$"
  1238. CouldNotRemoveMsg  db "Could not remove SHSUDRVX with ","$"
  1239.  
  1240. MoveName proc near
  1241.       sub   bx, bx                                 ; es:di points to 1st char
  1242.       .repeat                                      ; cx chars left on cmd line
  1243.           mov al, es:[di]
  1244.           .if (al == '/' || al == ' '|| cx <= 0)
  1245.               mov    byte ptr [si+bx], ' '
  1246.               inc    bx
  1247.           .else
  1248.              .if (al >= 'a' && al <= 'z')
  1249.                  and    al, 11011111y           ; upper case it
  1250.               .endif
  1251.               mov    byte ptr [si+bx], al
  1252.               inc    bx
  1253.               inc    di
  1254.               dec    cx
  1255.           .endif
  1256.       .until bx == dx
  1257.  
  1258. MoveName endp
  1259.  
  1260. FindParm proc near
  1261.  
  1262.    ; al has parm code we are to find       /X: or -X:
  1263.  
  1264.       mov      di, 80h                ; command line length @ +80h
  1265.       sub      ch, ch
  1266.       mov      cl, es:[di]
  1267.  
  1268.  GetNext:                             ; this code allows us to handle names
  1269.       call     GetParm                ; like   -C:NET-CD
  1270.       cmp      ax, ArgumentFound
  1271.       jne      NotFound
  1272.       inc      di                     ; found /X or -X, is next char a ':' ?
  1273.       dec      cl
  1274.       mov      al, es:[di]
  1275.       cmp      al, ':'
  1276.       je       FoundIt
  1277.       loop     GetNext
  1278.       mov      ax, ArgumentNotFound
  1279.       ret
  1280.  
  1281.   FoundIt:
  1282.       inc   di                           ; /X:name  make di point @ name
  1283.       dec   cl
  1284.       mov   ax, ArgumentFound
  1285.   NotFound: ret
  1286.  
  1287. FindParm endp
  1288.  
  1289. ;* GetParm - Scans command line for argument of form /X or -X  where
  1290. ;* X = specified ASCII character. Presumes that argument is preceded
  1291. ;* by a '/' or a '-'. Comparisons are case insensitive.
  1292. ;*
  1293. ;* Params: ES:DI = Address of CommandLine -1
  1294. ;*         AL    = Paramater character to scan for
  1295. ;*         CX    = command line length
  1296. ;*
  1297. ;* Return: AX    = One of the following codes:
  1298. ;*                 NoArgumentsFound  if empty command line
  1299. ;*                 ArgumentFound  if argument found
  1300. ;*                 ArgumentNotFound if argument not as specified
  1301. ;*         ES:DI = Pointer to found argument
  1302. ;*         CX    = chars left on command line including arg or 0
  1303.  
  1304. GetParm PROC NEAR
  1305.  
  1306.         mov     ah, NoArgumentsFound    ; assume no /X style arguments
  1307.         jcxz    exit
  1308.         .if (al >= 'a' && al <= 'z')
  1309.             and    al, 11011111y           ; Make character upper case
  1310.         .endif
  1311.  
  1312. ; Find start of argument
  1313.  
  1314. loop1:
  1315.         inc     di                      ;
  1316.         mov     dl, es:[di]             ; Get character from argument list
  1317.         cmp     dl, '/'                 ; Find option prefix '/'
  1318.         je      analyze
  1319.         cmp     dl, '-'                 ;   or option prefix '-'
  1320.         je      analyze
  1321.  
  1322.         loop    loop1
  1323.  
  1324.         jmp     exit
  1325.  
  1326. ; '/' or '-' prefix found. Compare command-line character
  1327. ; with character specified in AL.
  1328. analyze:
  1329.         mov     ah, ArgumentFound         ; Assume argument is okay
  1330.         inc     di
  1331.         dec     cl
  1332.         mov     dl, es:[di]
  1333.         .if (dl >= 'a' && dl <= 'z')
  1334.             and    dl, 11011111y           ; Make character upper case
  1335.         .endif
  1336.         cmp     dl, al
  1337.         je      exit                    ; specified char
  1338.         mov     ah, ArgumentNotFound    ; Else signal bad argument,
  1339.         inc     bx
  1340.         loop    loop1             ;   continue scan
  1341.  
  1342. exit:
  1343.         mov     al, ah
  1344.         cbw                             ; AX = return code
  1345.         ret
  1346.  
  1347. GetParm ENDP
  1348.  
  1349. .stack
  1350.             end  Init