home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk1.iso / altsrc / articles / 1000-1999 / 1752 < prev    next >
Internet Message Format  |  1990-12-27  |  47KB

  1. From: briana@tau-ceti.isc-br.com (Brian Who?)
  2. Newsgroups: alt.sources
  3. Subject: SCSI Device Driver for the Seagate ST-01
  4. Message-ID: <660@tau-ceti.isc-br.com>
  5. Date: 30 Aug 90 02:03:34 GMT
  6.  
  7.  
  8.      Here is a very simple minded device driver using the ST-01 SCSI
  9. interface card.  It is none to fast, and the code is probably not what
  10. it could be, but for my first assembler project on a PC it does work.
  11. Enjoy!
  12.  
  13. #
  14. # This is a Shell Archive.
  15. # Remove everything above and including the cut line.
  16. # Then run the rest of the file through #! /bin/sh.
  17. # -----cut here-----cut here-----cut here-----cut here-----
  18. #! /bin/sh
  19. # Execute the file with #! /bin/sh (not csh) to create the files:
  20. #    Makefile
  21. #    Readme.10
  22. #    dump.asm
  23. #    equ.inc
  24. #    ioctl.asm
  25. #    scsi.asm
  26. #    sformat.c
  27. #    struct.inc
  28. #    subs.asm
  29. #    units.asm
  30. # This Archive created: Wed Aug 29 19:00:19 1990
  31. # By: Brian Who? at I Saute Cats - Barbecue Rats, Spokane, WA
  32. #
  33. export PATH; PATH=/bin:$PATH
  34. echo shar: extracting "'Makefile'" '(388 characters)'
  35. if test -f 'Makefile'
  36. then
  37. echo shar: will not over-write existing file "'Makefile'"
  38. else
  39. sed 's/^XX//' > 'Makefile' << \SHAR_EOF
  40. XX#
  41. XX# SCSI Stuff
  42. XX#
  43. XXall: scsi.sys sformat.exe
  44. XX
  45. XX#
  46. XX# SCSI Disk Device Driver
  47. XX#
  48. XXscsi.sys: scsi.obj
  49. XX    link +scsi.obj, scsi ;
  50. XX    exe2bin scsi.exe scsi.sys
  51. XX
  52. XXscsi.obj: scsi.asm subs.asm ioctl.asm dump.asm units.asm equ.inc struct.inc
  53. XX    masm scsi.asm scsi.obj scsi.lst ;
  54. XX
  55. XX#
  56. XX# SCSI Disk Formatter
  57. XX#
  58. XXsformat.exe: sformat.c
  59. XX    cl -G2 -Ox -o sformat.exe sformat.c
  60. XX
  61. XX#
  62. XX# clean
  63. XX#
  64. XXclean:
  65. XX    rm -f *.exe *.obj *.lst
  66. SHAR_EOF
  67. if test 388 -ne "`wc -c < 'Makefile'`"
  68. then
  69. echo shar: error transmitting "'Makefile'" '(should have been 388 characters)'
  70. fi
  71. fi # end of overwriting check
  72. echo shar: extracting "'Readme.10'" '(2706 characters)'
  73. if test -f 'Readme.10'
  74. then
  75. echo shar: will not over-write existing file "'Readme.10'"
  76. else
  77. sed 's/^XX//' > 'Readme.10' << \SHAR_EOF
  78. XXScsi Version 1.0
  79. XX
  80. XX     The code you received with this file is a very simple SCSI device
  81. XXdriver that uses the Seagate ST-01 interface card.  As this driver is
  82. XXmy first PC assembler project other then "hello world", please don't
  83. XXsnicker to loudly.
  84. XX
  85. XX     The package includes the source for a device driver that will scan
  86. XXthe SCSI bus for disk drives and partition any drives found into chunks
  87. XXof 32Meg plus any leftovers.  As soon as I discover a way to get DOS to
  88. XXlet me use > 512 byte sectors, It will just allocate the entire disk to
  89. XXa single logical drive.  It also includes a utility to access the low
  90. XXlevel SCSI format function for any disk found.  You may specify the
  91. XXinterleave when the low level format is done and the version of the
  92. XXdriver here seems to work fine at 1:1 with my 8Mhz NEC.
  93. XX
  94. XX     Some of the things to look out for are:
  95. XX
  96. XX#1 The receive_data and send_data functions in subs.asm use polled I/O
  97. XX   to transfer data to/from the card.  I would have loved to just use
  98. XX   the I/O Channel Ready line that the card is suppose to support, but
  99. XX   my NEC does not seem to use that line.  Hence the polling of the REQ
  100. XX   bit in the status port.
  101. XX
  102. XX#2 I did not know how to do clock speed independent timing loops, so there
  103. XX   is a wait100us function in subs.asm that is very processor speed
  104. XX   dependent :-(
  105. XX
  106. XX#3 In ioctl.asm there is a commented out call to scsi_verify.  This is
  107. XX   used by the DOS format utility to scan for errors.  You may want to
  108. XX   enable the call after you get everything setup.  I shut it off while
  109. XX   I was testing as I didn't want to wait for the verify everytime I
  110. XX   changed the interleave.
  111. XX
  112. XX     To bring up the driver.  Assemble and link scsi.sys and add it to
  113. XXyour config.sys file.  After rebooting, you may optionaly do a low level
  114. XXformat of each disk found using sformat.exe.  You then use the DOS format
  115. XXutility on each logical drive.  I did figure out just what format needed
  116. XXin the way of ioctl support to get it to do the high level format for me.
  117. XXAt this point you should have fully functional DOS drives.  In testing
  118. XXI found that with multi_sector support (subs.asm) enabled, the SCSI drives
  119. XXwere just about as fast as the ST-412 C: that came with the machine.  I
  120. XXam sure that the speed problem is basic to the inner loop of the data
  121. XXtransfer routines, but I'm at a loss to figure out how to speed it up.
  122. XX
  123. XX     Anyway, maybe someone can find some use for the code.  I got the
  124. XXcard for free, so I can't really complain about the speed or cost too
  125. XXmuch :-)
  126. XX
  127. XX     Also thanks to the people that sent me samples of other device drivers
  128. XXfor the PC.  I lost the names to a disk crash, but here is the result of
  129. XXyour help and my thanks.
  130. XX
  131. XXBrian Antoine
  132. XXAug 29, 1990
  133. SHAR_EOF
  134. if test 2706 -ne "`wc -c < 'Readme.10'`"
  135. then
  136. echo shar: error transmitting "'Readme.10'" '(should have been 2706 characters)'
  137. fi
  138. fi # end of overwriting check
  139. echo shar: extracting "'dump.asm'" '(973 characters)'
  140. if test -f 'dump.asm'
  141. then
  142. echo shar: will not over-write existing file "'dump.asm'"
  143. else
  144. sed 's/^XX//' > 'dump.asm' << \SHAR_EOF
  145. XX;
  146. XX; Convert bin (ax) to ascii (dx => buffer)
  147. XX;
  148. XXbin_ascii    proc    near
  149. XX        pusha
  150. XX        push    ax
  151. XX        mov    bx,dx
  152. XX        mov    cx,6
  153. XXfill_buff:    mov    byte ptr [bx],' '
  154. XX        inc    bx
  155. XX        loop    fill_buff
  156. XX        mov    si,10
  157. XX        or    ax,ax
  158. XX        jns    clr_dvd
  159. XX        neg    ax
  160. XXclr_dvd:    sub    dx,dx
  161. XX        div    si
  162. XX        add    dx,'0'
  163. XX        dec    bx
  164. XX        mov    [bx],dl
  165. XX        inc    cx
  166. XX        or    ax,ax
  167. XX        jnz    clr_dvd
  168. XX        pop    ax
  169. XX        or    ax,ax
  170. XX        jns    no_more
  171. XX        dec    bx
  172. XX        mov    byte ptr [bx],'-'
  173. XXno_more:    popa
  174. XX        ret
  175. XXbin_ascii    endp
  176. XX
  177. XX;
  178. XX; Convert Hex to Ascii
  179. XX;
  180. XX; dx = value
  181. XX; di => buffer
  182. XX;
  183. XXhex2asc        proc    near
  184. XX        push    cx
  185. XX        push    ax
  186. XX        mov    cx,4        ;Do Four Digits
  187. XXh1:        push    cx
  188. XX        mov    cl,4
  189. XX        rol    dx,cl
  190. XX        mov    al,dl        ;Get the Current Digit
  191. XX        and    al,0Fh
  192. XX        cmp    al,0Ah        ;Is It Hex?
  193. XX        jge    h2
  194. XX        add    al,30h        ;Normal Digit
  195. XX        jmp    h3
  196. XXh2:        add    al,37h        ;Hex Digit
  197. XXh3:        mov    cs:[di],al    ;Insert in Buffer
  198. XX        inc    di
  199. XX        pop    cx        ;Go Do Another
  200. XX        loop    h1
  201. XX        pop    ax
  202. XX        pop    cx
  203. XX        ret
  204. XXhex2asc        endp
  205. XX
  206. XX;
  207. XX; Print a string
  208. XX;
  209. XX; ds:dx => string
  210. XX;
  211. XXputs        proc    near
  212. XX        pusha
  213. XX        mov    ah,9        ;DOS print string
  214. XX        int    21h
  215. XX        popa
  216. XX        ret
  217. XXputs        endp
  218. SHAR_EOF
  219. if test 973 -ne "`wc -c < 'dump.asm'`"
  220. then
  221. echo shar: error transmitting "'dump.asm'" '(should have been 973 characters)'
  222. fi
  223. fi # end of overwriting check
  224. echo shar: extracting "'equ.inc'" '(3049 characters)'
  225. if test -f 'equ.inc'
  226. then
  227. echo shar: will not over-write existing file "'equ.inc'"
  228. else
  229. sed 's/^XX//' > 'equ.inc' << \SHAR_EOF
  230. XX;
  231. XX; Equates
  232. XX;
  233. XXSCSI_CARD_SEG    EQU    0DE00h        ;Base Segment of Card
  234. XXSCSI_CMD_PORT    EQU    01A00h        ;Offset to Command Port
  235. XXSCSI_DATA_PORT    EQU    01C00h        ;Offset to Data Port
  236. XX
  237. XXSTACK_SIZE    EQU    512        ;Our Local Stack
  238. XX
  239. XX;
  240. XX; How the 16 bit sector number is broken down
  241. XX; into a sector and cylinder number.
  242. XX;
  243. XX; x = Cylinder, y = track, always have only 1 head
  244. XX;
  245. XX; xxxx xxxx xxxx yyyy
  246. XX;
  247. XX; SECT_2_FS is computed as: ((unit_bpb.bpb_ts / CLUSTSIZE) * 2) / P_SECT)
  248. XX;
  249. XXSECT_TRACK    EQU    16        ;Logical Sectors in a Track
  250. XXSECT_MASK    EQU    0000Fh        ;Mask for Sector
  251. XXCYL_MASK    EQU    0FFF0h        ;Mask for Cylinder
  252. XXSECT_2_CYL    EQU    4        ;How far to shift to convert
  253. XX                    ;Sector to Cylinder Number
  254. XXSECT_2_FS    EQU    10        ;How far to shift for
  255. XX                    ;Total Sectors to Fat Sectors
  256. XX
  257. XXMAXUNIT        EQU    3        ;Maximum Unit Number
  258. XX
  259. XXP_SECT        EQU    512        ;Physical Sector Size
  260. XXCLUSTSIZE    EQU    4        ;Number of Sectors to a Cluster
  261. XX
  262. XX;
  263. XX; For multi_sector reads and writes,
  264. XX; set the following to '1'
  265. XX;
  266. XX; CHUNK_MASK is the maximum number of sectors to access in one
  267. XX; SCSI request.  It MUST be a power of two, and CHUNK_MASK * P_SECT
  268. XX; MUST be <= 64K to prevent segment wrap problems.
  269. XX;
  270. XXmulti_sector    =    1        ;1 = multi sector, 0 = single sector
  271. XXCHUNK_MAX    EQU    32
  272. XX
  273. XXCMDENABLE    EQU    080h        ;Enable the output drivers
  274. XXCMDENINTR    EQU    040h        ;Enable Interrupt
  275. XXCMDPARITY    EQU    020h        ;Enable Parity
  276. XXCMDSTARB    EQU    010h        ;Start Bus Arbitration
  277. XXCMDATTN        EQU    008h        ;Assert ATTN
  278. XXCMDBSY        EQU    004h        ;Assert BSY
  279. XXCMDSEL        EQU    002h        ;Assert SEL
  280. XXCMDRST        EQU    001h        ;Assert RST
  281. XX
  282. XXCMDBASE        EQU    CMDPARITY    ;Base value of all commands
  283. XX
  284. XXSTARBCOMPL    EQU    080h        ;Arbitration Complete
  285. XXSTPARERR    EQU    040h        ;Parity Error
  286. XXSTSEL        EQU    020h        ;SEL Asserted
  287. XXSTREQ        EQU    010h        ;REQ Asserted
  288. XXSTCD        EQU    008h        ;C/D Asserted
  289. XXSTIO        EQU    004h        ;I/O Asserted
  290. XXSTMSG        EQU    002h        ;MSG Asserted
  291. XXSTBSY        EQU    001h        ;BSY Asserted
  292. XX
  293. XXFREE_MASK    EQU    03Fh
  294. XX
  295. XXREQ_MASK    EQU    STMSG or STCD or STIO
  296. XXREQ_DATAOUT    EQU    000h        ;Data Out Phase
  297. XXREQ_DATAIN    EQU    STIO        ;Data In Phase
  298. XXREQ_CMDOUT    EQU    STCD        ;Command Out Phase
  299. XXREQ_STATIN    EQU    STCD or STIO    ;Status In Phase
  300. XXREQ_MSGOUT    EQU    STMSG or STCD    ;Msg Out Phase
  301. XXREQ_MSGIN    EQU    STMSG or STCD or STIO    ;Msg In Phase
  302. XX
  303. XXCOK        EQU    0        ;Command Completed OK
  304. XXCNOCONNECT    EQU    1        ;Unable to Connect to Target
  305. XXCBUSBUSY    EQU    2        ;Bus Busy
  306. XXCTIMEOUT    EQU    3        ;Timeout waiting for Response
  307. XXCERROR        EQU    4        ;Target Return Error
  308. XXCBUSY        EQU    5        ;Target was Busy
  309. XXCDISCONNECT    EQU    6        ;Target Disconnected
  310. XX
  311. XXSCSI_TESTREADY    EQU    000h        ;Test Unit Ready (6 byte)
  312. XXSCSI_REQSENSE    EQU    003h        ;Request Sense (6 byte)
  313. XXSCSI_FORMATUNIT    EQU    004h        ;Format Disk (6 byte)
  314. XXSCSI_INQUIRY    EQU    012h        ;Inquire (6 byte)
  315. XXSCSI_READSIZE    EQU    025h        ;Read Drive Capacity (10 byte)
  316. XXSCSI_READBLK    EQU    028h        ;Read Sectors (10 byte)
  317. XXSCSI_WRITEBLK    EQU    02Ah        ;Write Sectors (10 byte)
  318. XXSCSI_VERIFYBLK    EQU    02Fh        ;Verify Blocks (10 byte)
  319. XX
  320. XXMSG_COMPLETE    EQU    000h        ;Command is Complete
  321. XXMSG_SAVE    EQU    002h        ;Save Data Pointers
  322. XXMSG_RESTORE    EQU    003h        ;Restore Data Pointers
  323. XXMSG_ERROR    EQU    005h        ;Error Detected
  324. XXMSG_ABORT    EQU    006h        ;Abort the Command
  325. XXMSG_REJECT    EQU    007h        ;Reject the Command
  326. XXMSG_NOP        EQU    008h        ;No Operation
  327. XXMSG_IDENTIFY    EQU    080h        ;Identify Yourself
  328. SHAR_EOF
  329. if test 3049 -ne "`wc -c < 'equ.inc'`"
  330. then
  331. echo shar: error transmitting "'equ.inc'" '(should have been 3049 characters)'
  332. fi
  333. fi # end of overwriting check
  334. echo shar: extracting "'ioctl.asm'" '(1824 characters)'
  335. if test -f 'ioctl.asm'
  336. then
  337. echo shar: will not over-write existing file "'ioctl.asm'"
  338. else
  339. sed 's/^XX//' > 'ioctl.asm' << \SHAR_EOF
  340. XX;
  341. XX; Process an ioctl request for the current unit
  342. XX;
  343. XX; return 'C' on error
  344. XX;
  345. XXscsi_ioctl    proc
  346. XX        mov    al,es:[bx].rh19_minor        ;Get the minor number
  347. XX
  348. XX        cmp    al,40h                ;Set Device Params?
  349. XX        jnz    scsi_i_42h
  350. XX        clc
  351. XX        jmp    scsi_i_exit
  352. XX
  353. XXscsi_i_42h:    cmp    al,42h                ;Format and Verify?
  354. XX        jnz    scsi_i_60h
  355. XX;        call    scsi_verify
  356. XX        jmp    scsi_i_exit
  357. XX
  358. XXscsi_i_60h:    cmp    al,60h                ;Get Device Params?
  359. XX        jnz    scsi_i_62h
  360. XX        mov    si,cur_bpb            ;Get the Current BPB
  361. XX        mov    di,es:[bx].rh19_buf_ofs        ;Get the Param Buffer
  362. XX        mov    ax,es:[bx].rh19_buf_seg
  363. XX        mov    es,ax
  364. XX        mov    es:[di].dpb_special,05h        ;Sect Same/Use Cur BPB
  365. XX        mov    es:[di].dpb_type,05h        ;Fixed Disk
  366. XX        mov    es:[di].dpb_attr,0001h        ;Not Removable
  367. XX        mov    ax,[si].bpb_ts
  368. XX        shr    ax,SECT_2_CYL            ;Convert Sect to Cyl
  369. XX        mov    es:[di].dpb_cyl,ax
  370. XX        mov    es:[di].dpb_media,0        ;????
  371. XX        mov    es:[di].dpb_sectors,SECT_TRACK    ;Sectors per Track
  372. XX
  373. XX        push    di
  374. XX        lea    di,es:[di].dpb_bpb        ;Copy the bpb into
  375. XX        mov    cx,size bpb            ;the requestors buffer
  376. XX        cld
  377. XX    rep    movsb
  378. XX        pop    di
  379. XX
  380. XX        lea    di,es:[di].dpb_track        ;Build the Track List
  381. XX        mov    cx,SECT_TRACK
  382. XX        mov    ax,0                ;Start with Sector 0
  383. XXscsi_i_t_loop:    mov    es:[di],ax            ;Sector Number
  384. XX        inc    ax
  385. XX        inc    di
  386. XX        inc    di
  387. XX        mov    word ptr es:[di],P_SECT        ;Sector Size
  388. XX        inc    di
  389. XX        inc    di
  390. XX        loop    scsi_i_t_loop
  391. XX        clc
  392. XX        jmp    scsi_i_exit
  393. XX
  394. XXscsi_i_62h:    cmp    al,62h                ;Verify?
  395. XX        jnz    scsi_i_error
  396. XX        call    scsi_verify
  397. XX        jmp    scsi_i_exit
  398. XX
  399. XXscsi_i_error:    stc
  400. XXscsi_i_exit:    ret
  401. XXscsi_ioctl    endp
  402. XX
  403. XXscsi_ioctl_write proc
  404. XX        mov    di,es:[bx].rh12_buf_ofs
  405. XX        mov    ax,es:[bx].rh12_buf_seg
  406. XX        mov    es,ax
  407. XX        mov    ax,es:[di].ioc_command        ;What Command
  408. XX        cmp    al,'F'                ;Format?
  409. XX        jnz    scsi_i_w_error
  410. XX
  411. XX        mov    ax,es:[di].ioc_data        ;Get Interleave
  412. XX        lea    di,cmd_format            ;Insert into Command
  413. XX        mov    [di].fmt_cmd_il_b0,al
  414. XX        mov    [di].fmt_cmd_il_b1,ah
  415. XX        call    docmd
  416. XX        jmp    short scsi_i_w_exit
  417. XX
  418. XXscsi_i_w_error:    stc
  419. XXscsi_i_w_exit:    ret
  420. XXscsi_ioctl_write endp
  421. SHAR_EOF
  422. if test 1824 -ne "`wc -c < 'ioctl.asm'`"
  423. then
  424. echo shar: error transmitting "'ioctl.asm'" '(should have been 1824 characters)'
  425. fi
  426. fi # end of overwriting check
  427. echo shar: extracting "'scsi.asm'" '(8104 characters)'
  428. if test -f 'scsi.asm'
  429. then
  430. echo shar: will not over-write existing file "'scsi.asm'"
  431. else
  432. sed 's/^XX//' > 'scsi.asm' << \SHAR_EOF
  433. XX;
  434. XX; Simple SCSI Device Driver
  435. XX;
  436. XX        .286
  437. XX        PAGE    76,132
  438. XX
  439. XX        INCLUDE    equ.inc
  440. XX        INCLUDE    struct.inc
  441. XX;
  442. XX; Start of Code and Data
  443. XX;
  444. XX_TEXT        segment    word public 'CODE'
  445. XX        assume    cs:_TEXT, ds:_TEXT, es:_TEXT
  446. XX
  447. XX        org    0
  448. XX
  449. XX;
  450. XX; Device Header Required By DOS
  451. XX;
  452. XXscsi:
  453. XXnext_dev    dd    -1        ;No other Device Drivers
  454. XXattribute    dw    6040h        ;Ioctl R/W, Block Device, Non-IBM, Get/Set
  455. XXstrategy    dw    dev_strategy    ;Address of 1st DOS Call
  456. XXinterrupt    dw    dev_interrupt    ;Address of 2nd DOS Call
  457. XXdisk_count    db    0        ;Number of Disks Present
  458. XX        db    7 dup(?)
  459. XX
  460. XX;
  461. XX; Work Space For Our Device Driver
  462. XX;
  463. XXrh_off        dw    ?        ;Request Header Offset
  464. XXrh_seg        dw    ?        ;Request Header Segment
  465. XX
  466. XXcur_drive    db    -1
  467. XXvol_id        db    'NO NAME    ',0
  468. XX
  469. XX;
  470. XX; Define our own personal Stack
  471. XX;
  472. XX        even
  473. XXnew_stack    db    STACK_SIZE-2 dup (?)    ;Our Local Stack
  474. XXnew_stack_top    dw    ?
  475. XX
  476. XXstack_ptr    dw    ?            ;Old Stack Pointer
  477. XXstack_seg    dw    ?            ;Old Stack Segment
  478. XX
  479. XX;
  480. XX; Command Table
  481. XX;
  482. XXcmdtab        label    byte        ;* = Char Only Devices
  483. XX        dw    INITIALIZATION    ;Initialization
  484. XX        dw    MEDIA_CHECK    ;Media Check (Block Only)
  485. XX        dw    GET_BPB        ;Build BPB
  486. XX        dw    unknown        ;IOCTL Read
  487. XX        dw    READ        ;Read Data
  488. XX        dw    done        ;*Non Destructive Read
  489. XX        dw    done        ;*Read Status
  490. XX        dw    done        ;*Flush Read Buffer
  491. XX        dw    WRITE        ;Write Data
  492. XX        dw    WRITE_VERIFY    ;Write With Verify
  493. XX        dw    done        ;*Write Status
  494. XX        dw    done        ;*Flush Write Buffer
  495. XX        dw    WRITE_IOCTL    ;IOCTL Write
  496. XX        dw    done        ;Device Open
  497. XX        dw    done        ;Device Close
  498. XX        dw    busy        ;Removable Check
  499. XX        dw    unknown        ;*Write Until Busy
  500. XX        dw    unknown        ;Unknown Call
  501. XX        dw    unknown        ;Unknown Call
  502. XX        dw    IOCTL        ;Generic Ioctl
  503. XX        dw    unknown        ;Unknown Call
  504. XX        dw    unknown        ;Unknown Call
  505. XX        dw    unknown        ;Unknown Call
  506. XX        dw    GET_DEV        ;Get Device
  507. XX        dw    SET_DEV        ;Set Device
  508. XX
  509. XX;
  510. XX; Strategy Procedure
  511. XX;
  512. XXdev_strategy    proc    far
  513. XX        mov    cs:rh_seg,es        ;Save Request Header Ptr Segment
  514. XX        mov    cs:rh_off,bx        ;Save Request Header Ptr Offset
  515. XX        ret
  516. XXdev_strategy    endp
  517. XX
  518. XX;
  519. XX; Interrupt Procedure
  520. XX;
  521. XXdev_interrupt    proc    far
  522. XX        cli                ;Save Machine State On Entry
  523. XX        push    ds
  524. XX        push    es
  525. XX        push    ax
  526. XX        push    bx
  527. XX        push    cx
  528. XX        push    dx
  529. XX        push    si
  530. XX        push    di
  531. XX        push    bp
  532. XX        pushf
  533. XX
  534. XX        mov    cs:stack_seg,ss        ;Save Old Stack
  535. XX        mov    cs:stack_ptr,sp
  536. XX
  537. XX        mov    ax,cs            ;Save us the Segment Override Crap
  538. XX        mov    ds,ax
  539. XX        mov    es,ax
  540. XX
  541. XX        mov    ss,ax            ;Setup Our Local Stack
  542. XX        lea    ax,new_stack_top
  543. XX        mov    sp,ax
  544. XX        sti                ;We're Safe Now
  545. XX
  546. XX;
  547. XX; Perform branch based on the command passed in the Request Header
  548. XX;
  549. XX        mov    es,rh_seg        ;Point us at the Request Header
  550. XX        mov    bx,rh_off
  551. XX
  552. XX        mov    al,es:[bx].rh_cmd    ;Get Command Code
  553. XX        rol    al,1            ;Get offset into table
  554. XX        lea    di,cmdtab        ;Get address of command table
  555. XX        mov    ah,0            ;Clear hi order byte
  556. XX        add    di,ax            ;Add offset
  557. XX        jmp    word ptr [di]        ;Jump Indirect
  558. XX
  559. XX;
  560. XX; Command Procedures
  561. XX;
  562. XXINITIALIZATION:    mov    al,es:[bx].rh0_drv_ltr    ;Save the starting Drive
  563. XX        add    al,041h
  564. XX        mov    cur_drive,al
  565. XX        call    initial            ;Setup
  566. XX        mov    bx,rh_off
  567. XX        mov    es,rh_seg
  568. XX        lea    ax,initial        ;Set The Break Address
  569. XX        mov    es:[bx].rh0_brk_ofs,ax
  570. XX        mov    es:[bx].rh0_brk_seg,cs
  571. XX        mov    al,disk_count        ;Number of Disk Devices Supported
  572. XX        mov    es:[bx].rh0_nunits,al
  573. XX        lea    dx,bpb_array        ;BPB Array
  574. XX        mov    es:[bx].rh0_bpb_tbo,dx
  575. XX        mov    es:[bx].rh0_bpb_tbs,cs
  576. XX        jmp    done
  577. XX
  578. XXMEDIA_CHECK:    call    find_unit
  579. XX        jc    bad_unit
  580. XX        mov    di,cur_unit
  581. XX        mov    al,[di].unit_mcheck    ;Get Initial Status
  582. XX        mov    [di].unit_mcheck,1    ;Always OK from then on
  583. XX        mov    es:[bx].rh1_md_stat,al
  584. XX        lea    dx,vol_id        ;Address of Volume ID
  585. XX        mov    es:[bx].rh1_volid_ofs,dx
  586. XX        mov    es:[bx].rh1_volid_seg,cs
  587. XX        jmp    done
  588. XX
  589. XXGET_BPB:    call    find_unit
  590. XX        jc    bad_unit
  591. XX        mov    dx,cur_bpb        ;Address of BPB
  592. XX        mov    es:[bx].rh2_pbpbo,dx
  593. XX        mov    es:[bx].rh2_pbpbs,cs
  594. XX        jmp    done
  595. XX
  596. XX;
  597. XX; Read some data from the disk
  598. XX;
  599. XXREAD:        call    find_unit
  600. XX        jc    bad_unit
  601. XX        call    scsi_read
  602. XX        jc    bad_read
  603. XX        jmp    done
  604. XX
  605. XX;
  606. XX; Write some data to the disk
  607. XX;
  608. XXWRITE        equ    $
  609. XXWRITE_VERIFY:    call    find_unit
  610. XX        jc    bad_unit
  611. XX        call    scsi_write
  612. XX        jc    bad_write
  613. XX        jmp    done
  614. XX
  615. XX;
  616. XX; Write Ioctl Packet
  617. XX;
  618. XXWRITE_IOCTL:    call    find_unit
  619. XX        jc    bad_unit
  620. XX        call    scsi_ioctl_write
  621. XX        jc    unknown
  622. XX        jmp    done
  623. XX
  624. XX;
  625. XX; Special Control Functions
  626. XX;
  627. XXIOCTL:        call    find_unit
  628. XX        jc    bad_unit
  629. XX        call    scsi_ioctl
  630. XX        jc    unknown
  631. XX        jmp    done
  632. XX
  633. XXGET_DEV:    mov    es:[bx].rh_unit,0
  634. XX        jmp    done
  635. XX
  636. XXSET_DEV:    jmp    done
  637. XX
  638. XXbad_unit:    mov    es,rh_seg        ;Point us at the Request Header
  639. XX        mov    bx,rh_off
  640. XX        or    es:[bx].rh_status,8001h
  641. XX        jmp    short done
  642. XX
  643. XXunknown:    mov    es,rh_seg        ;Point us at the Request Header
  644. XX        mov    bx,rh_off
  645. XX        or    es:[bx].rh_status,8003h
  646. XX        jmp    short done
  647. XX
  648. XXbad_write:    mov    es,rh_seg        ;Point us at the Request Header
  649. XX        mov    bx,rh_off
  650. XX        or    es:[bx].rh_status,800Ah
  651. XX        jmp    short done
  652. XX
  653. XXbad_read:    mov    es,rh_seg        ;Point us at the Request Header
  654. XX        mov    bx,rh_off
  655. XX        or    es:[bx].rh_status,800Bh
  656. XX        jmp    short done
  657. XX
  658. XXbusy:        mov    es,rh_seg        ;Point us at the Request Header
  659. XX        mov    bx,rh_off
  660. XX        or    es:[bx].rh_status,0200h
  661. XX
  662. XXdone:        mov    es,rh_seg        ;Point us at the Request Header
  663. XX        mov    bx,rh_off
  664. XX        or    es:[bx].rh_status,0100h
  665. XX
  666. XX        cli                ;Make sure we're left alone
  667. XX        mov    ax,cs:stack_seg        ;Restore DOS Stack
  668. XX        mov    ss,ax
  669. XX        mov    ax,cs:stack_ptr
  670. XX        mov    sp,ax
  671. XX
  672. XX        popf                ;Restore All Registers
  673. XX        pop    bp
  674. XX        pop    di
  675. XX        pop    si
  676. XX        pop    dx
  677. XX        pop    cx
  678. XX        pop    bx
  679. XX        pop    ax
  680. XX        pop    es
  681. XX        pop    ds
  682. XX        sti                ;We're Safe Now
  683. XX        ret
  684. XX
  685. XX        INCLUDE    units.asm
  686. XX        INCLUDE    subs.asm
  687. XX        INCLUDE    ioctl.asm
  688. XX        INCLUDE    dump.asm
  689. XX;
  690. XX; End of Program
  691. XX; Stuff Placed Here Gets Handed Back To DOS For Re-use
  692. XX;
  693. XXinitial        proc    near
  694. XX        lea    dx,hello_msg        ;Tell them the driver version
  695. XX        call    puts
  696. XX        push    cs
  697. XX        pop    dx
  698. XX        lea    di,seg_msg_value
  699. XX        call    hex2asc
  700. XX        lea    dx,seg_msg        ;And Were We Loaded
  701. XX        call    puts
  702. XX
  703. XX        call    scsi_reset        ;Reset the bus
  704. XX
  705. XX        mov    cx,0            ;Scan for devices
  706. XXscan:        mov    ax,cx
  707. XX        add    al,030h
  708. XX        mov    scan_dev,al
  709. XX        mov    ax,1            ;Create Select Bit
  710. XX        shl    ax,cl
  711. XX        mov    di,cur_unit
  712. XX        mov    [di].unit_select,al
  713. XX        mov    [di].unit_num_drv,0    ;No Drives to start with
  714. XX        mov    al,disk_count        ;We will start with
  715. XX        mov    [di].unit_1st_drv,al    ;Drive Number if any
  716. XX
  717. XX        lea    dx,scan_dev        ;Print the device number
  718. XX        call    puts
  719. XX        call    scsi_inquire        ;Inquire as to its type
  720. XX        jnc    scan_inq_ok
  721. XX        jmp    scan_err
  722. XX
  723. XXscan_inq_ok:    mov    di,cur_unit
  724. XX        lea    dx,[di].unit_inq_buf.inq_manufact
  725. XX        mov    [di].unit_inq_term,'$'
  726. XX        mov    al,[di].unit_inq_buf.inq_dev_type
  727. XX        or    al,al            ;Look at device type
  728. XX        jz    scan_is_drv
  729. XX        jmp    scan_puts        ;Must be a Tape Drive
  730. XX
  731. XXscan_is_drv:    call    puts            ;Output the Device String
  732. XX        call    scsi_capacity        ;Inquire as to its size
  733. XX        lea    dx,err_size
  734. XX        jc    scan_puts        ;Do not use unknown drives
  735. XX        lea    dx,crlf
  736. XX        call    puts
  737. XX
  738. XXscan_next_drv:    mov    di,cur_unit
  739. XX        mov    al,disk_count        ;Number Of Drives Found
  740. XX        inc    al
  741. XX        mov    disk_count,al
  742. XX        mov    al,[di].unit_num_drv    ;We have a valid Drive
  743. XX        inc    al
  744. XX        mov    [di].unit_num_drv,al
  745. XX        mov    al,cur_drive        ;Get Current Drive Letter
  746. XX        mov    drv_msg_let,al        ;Insert it in message
  747. XX        inc    al            ;Bump Drive Letter
  748. XX        mov    cur_drive,al
  749. XX        call    make_bpb        ;Setup the BPB for this drive
  750. XX        mov    di,cur_bpb        ;Current Working BPB
  751. XX        mov    ax,[di].bpb_ts
  752. XX        shr    ax,11
  753. XX        inc    ax
  754. XX        lea    dx,drv_msg_size
  755. XX        call    bin_ascii
  756. XX        mov    bx,bpb_hw_mark        ;Get the BPB High Water Mark
  757. XX        inc    bx            ;Bump HW Mark for next time
  758. XX        inc    bx
  759. XX        mov    ax,[bx]            ;Get the BPB
  760. XX        mov    cur_bpb,ax        ;Make it the current BPB
  761. XX        mov    bpb_hw_mark,bx
  762. XX        lea    dx,drv_msg
  763. XX        call    puts
  764. XX        mov    bx,cur_unit
  765. XX        mov    ah,0
  766. XX        mov    al,[bx].unit_num_drv    ;Insert Drive Offset
  767. XX        dec    al            ;Into BPB for this Drive
  768. XX        mov    [di].bpb_hs_msw,ax
  769. XX        mov    al,[bx].unit_cap_buf.cap_sectors_b3
  770. XX        or    al,[bx].unit_cap_buf.cap_sectors_b2
  771. XX        or    al,[bx].unit_cap_buf.cap_sectors_b1
  772. XX        or    al,[bx].unit_cap_buf.cap_sectors_b0
  773. XX        jnz    scan_next_drv        ;Room left for another Drive
  774. XX        jmp    short scan_next
  775. XX
  776. XXscan_err:    lea    dx,no_dev
  777. XX        cmp    al,CNOCONNECT
  778. XX        jz    scan_puts
  779. XX        lea    dx,err_dev
  780. XXscan_puts:    call    puts
  781. XX        lea    dx,crlf
  782. XX        call    puts
  783. XX
  784. XXscan_next:    inc    cx
  785. XX        cmp    cx,MAXUNIT    ;End of devices?
  786. XX        jg    scan_exit
  787. XX        mov    bx,cx        ;Bump to next unit
  788. XX        shl    bx,1
  789. XX        mov    ax,word ptr unit_array[bx]
  790. XX        mov    cur_unit,ax
  791. XX        jmp    scan
  792. XX
  793. XXscan_exit:    ret
  794. XXinitial        endp
  795. XX
  796. XX;
  797. XX; Data Area Used Only During Initialization
  798. XX;
  799. XXhello_msg    db    0dh,0ah,'SCSI Device Driver Version 1.0',0Dh,0Ah,'$'
  800. XXseg_msg        db    'Driver Loaded At Segment '
  801. XXseg_msg_value    db    '0000',0dh,0ah,'$'
  802. XXscan_dev    db    'X - ','$'
  803. XXno_dev        db    '(No Installed Device)$'
  804. XXerr_dev        db    '(Error On Device)$'
  805. XXerr_size    db    'unknown size$'
  806. XXdrv_msg        db    '  - Drive '
  807. XXdrv_msg_let    db    'X: '
  808. XXdrv_msg_size    db    'XXXXXX Meg',0dh,0ah,'$'
  809. XXcrlf        db    0dh,0ah,'$'
  810. XX
  811. XXdev_interrupt    endp
  812. XX_TEXT        ends
  813. XX        end    scsi
  814. SHAR_EOF
  815. if test 8104 -ne "`wc -c < 'scsi.asm'`"
  816. then
  817. echo shar: error transmitting "'scsi.asm'" '(should have been 8104 characters)'
  818. fi
  819. fi # end of overwriting check
  820. echo shar: extracting "'sformat.c'" '(1842 characters)'
  821. if test -f 'sformat.c'
  822. then
  823. echo shar: will not over-write existing file "'sformat.c'"
  824. else
  825. sed 's/^XX//' > 'sformat.c' << \SHAR_EOF
  826. XX/*
  827. XX** SCSI Disk Formatter (Low Level)
  828. XX**
  829. XX** usage: sformat drive: [interleave]
  830. XX**
  831. XX** Revision History:
  832. XX**
  833. XX** Version 1.0  08/03/90 Initial Release
  834. XX**
  835. XX** Version 1.1  08/20/90 Add verification message.
  836. XX*/
  837. XX#include <stdio.h>
  838. XX#include <dos.h>
  839. XX
  840. XX#define TRUE (1)
  841. XX#define FALSE (0)
  842. XX#define VERSION "sformat Version 1.1 BWA"
  843. XX
  844. XXextern int _doserrno;
  845. XX
  846. XXstruct cmd {
  847. XX    short command;        /* command type */
  848. XX    short args;            /* command args */
  849. XX} ioctl_data;
  850. XXunion REGS inregs, outregs;
  851. XXstruct SREGS segregs;
  852. XXunsigned short interleave = 0;
  853. XXunsigned char drive;
  854. XXchar far *cp;
  855. XX
  856. XXmain(argc, argv)
  857. XXint argc;
  858. XXchar *argv[];
  859. XX{
  860. XX    /*
  861. XX    ** say hello
  862. XX    */
  863. XX    puts(VERSION);
  864. XX
  865. XX    /*
  866. XX    ** figure out who to format
  867. XX    */
  868. XX    switch (argc)
  869. XX    {
  870. XX        case 3:
  871. XX        interleave = atoi(argv[2]);
  872. XX        case 2:
  873. XX        if (argv[1][1] != ':') usage();
  874. XX        drive = argv[1][0];
  875. XX        drive = toupper(drive);
  876. XX        drive -= '@';
  877. XX        break;
  878. XX
  879. XX        default:
  880. XX        usage();
  881. XX        break;
  882. XX    }
  883. XX
  884. XX    /*
  885. XX    ** verify that this is what the user really wants to do
  886. XX    */
  887. XX    printf("Do you really wish to format the SCSI\n");
  888. XX    printf("device that contains drive %c: (y,n)? ", argv[1][0]);
  889. XX    fflush(stdout);
  890. XX    if ( getchar() != 'y' )
  891. XX    {
  892. XX        puts("Aborting low level format ....");
  893. XX        exit(1);
  894. XX    }
  895. XX
  896. XX    /*
  897. XX    ** put together the command
  898. XX    */
  899. XX    inregs.h.ah = 0x44;            /* ioctl */
  900. XX    inregs.h.al = 0x05;            /* write */
  901. XX    inregs.h.bl = drive;        /* unit */
  902. XX    inregs.x.cx = sizeof(struct cmd);
  903. XX    cp = (char *) &ioctl_data;
  904. XX    inregs.x.dx = FP_OFF(cp);
  905. XX    segregs.ds = FP_SEG(cp);
  906. XX    ioctl_data.command = 'F';
  907. XX    ioctl_data.args = interleave;
  908. XX
  909. XX    /*
  910. XX    ** start the format
  911. XX    */
  912. XX    puts("Now formating ....");
  913. XX    puts("Please wait ....");
  914. XX    intdosx(&inregs, &outregs, &segregs);
  915. XX
  916. XX    /*
  917. XX    ** see what happened
  918. XX    */
  919. XX    if ( outregs.x.cflag )
  920. XX        printf("DOS error %d occured during format.\n", _doserrno);
  921. XX    else
  922. XX        puts("Formating complete.");
  923. XX    exit(0);
  924. XX}
  925. XX
  926. XXusage()
  927. XX{
  928. XX    puts("usage: sformat drive: [interleave]");
  929. XX    exit(1);
  930. XX}
  931. SHAR_EOF
  932. if test 1842 -ne "`wc -c < 'sformat.c'`"
  933. then
  934. echo shar: error transmitting "'sformat.c'" '(should have been 1842 characters)'
  935. fi
  936. fi # end of overwriting check
  937. echo shar: extracting "'struct.inc'" '(5738 characters)'
  938. if test -f 'struct.inc'
  939. then
  940. echo shar: will not over-write existing file "'struct.inc'"
  941. else
  942. sed 's/^XX//' > 'struct.inc' << \SHAR_EOF
  943. XX;
  944. XX; Structures for SCSI commands
  945. XX;
  946. XXio_cmd        struc
  947. XXio_cmd_op    db    ?        ;Opcode
  948. XXio_cmd_lun    db    ?
  949. XXio_cmd_lba_b3    db    ?        ;Logical Block Address
  950. XXio_cmd_lba_b2    db    ?
  951. XXio_cmd_lba_b1    db    ?
  952. XXio_cmd_lba_b0    db    ?
  953. XXio_cmd_dummy1    db    ?
  954. XXio_cmd_cnt_b1    db    ?        ;Block Count
  955. XXio_cmd_cnt_b0    db    ?
  956. XXio_cmd_dummy2    db    ?
  957. XXio_cmd        ends
  958. XX
  959. XX;
  960. XX; Format the Unit
  961. XX;
  962. XXfmt_cmd        struc
  963. XXfmt_cmd_op    db    ?        ;Opcode
  964. XXfmt_cmd_type    db    ?        ;Format Type
  965. XXfmt_cmd_dummy1    db    ?
  966. XXfmt_cmd_il_b1    db    ?        ;Interleave (MSB)
  967. XXfmt_cmd_il_b0    db    ?        ;Interleave (LSB)
  968. XXfmt_cmd_dummy3    db    ?
  969. XXfmt_cmd        ends
  970. XX
  971. XX;
  972. XX; Verify Sectors
  973. XX;
  974. XXver_cmd        struc
  975. XXver_cmd_op    db    ?        ;Opcode
  976. XXver_cmd_lun    db    ?        ;Lun
  977. XXver_cmd_lba_b3    db    ?        ;Logical Block Address MSB
  978. XXver_cmd_lba_b2    db    ?
  979. XXver_cmd_lba_b1    db    ?
  980. XXver_cmd_lba_b0    db    ?        ;Logical Block Address LSB
  981. XXver_cmd_dummy1    db    ?
  982. XXver_cmd_len_b1    db    ?        ;Length MSB
  983. XXver_cmd_len_b0    db    ?        ;Length LSB
  984. XXver_cmd_dummy2    db    ?
  985. XXver_cmd        ends
  986. XX
  987. XX;
  988. XX; Structure returned by the unit inquiry command
  989. XX;
  990. XXinq        struc
  991. XXinq_dev_type    db    ?        ;Device Type
  992. XXinq_dev_qual    db    ?        ;Device Qualifier
  993. XXinq_stand_rev    db    ?        ;Standard Revision Level
  994. XXinq_format    db    ?        ;Response Format
  995. XXinq_length    db    ?        ;Length of Extra Data
  996. XXinq_reserv1    db    ?
  997. XXinq_reserv2    db    ?
  998. XXinq_reserv3    db    ?
  999. XXinq_manufact    db    8 dup (?)    ;Manufacture
  1000. XXinq_product    db    16 dup (?)    ;Product
  1001. XXinq        ends
  1002. XX
  1003. XX;
  1004. XX; Structure returned by the read drive capacity command
  1005. XX;
  1006. XXcap        struc
  1007. XXcap_sectors_b3    db    ?        ;MSB of sector count
  1008. XXcap_sectors_b2    db    ?
  1009. XXcap_sectors_b1    db    ?
  1010. XXcap_sectors_b0    db    ?        ;LSB of sector count
  1011. XXcap_size_b3    db    ?        ;MSB of sector size
  1012. XXcap_size_b2    db    ?
  1013. XXcap_size_b1    db    ?
  1014. XXcap_size_b0    db    ?        ;LSB of sector size
  1015. XXcap        ends
  1016. XX
  1017. XX;
  1018. XX; Structure Definitions For Our Device Driver
  1019. XX;
  1020. XXbpb        struc
  1021. XXbpb_ss        dw    ?        ;Sector Size
  1022. XXbpb_au        db    ?        ;Cluster Size in Sectors
  1023. XXbpb_rs        dw    ?        ;Reserved Sectors
  1024. XXbpb_nf        db    ?        ;Number of Fats
  1025. XXbpb_de        dw    ?        ;Number of Root Directory Entries
  1026. XXbpb_ts        dw    ?        ;Total Number Of Sectors
  1027. XXbpb_md        db    ?        ;Media Descriptor
  1028. XXbpb_fs        dw    ?        ;Number of Sectors in each Fat
  1029. XXbpb_st        dw    ?        ;Number of Sectors per Track
  1030. XXbpb_nh        dw    ?        ;Number of Heads
  1031. XXbpb_hs_lsw    dw    ?        ;Hidden Sectors (Least Sig Word)
  1032. XXbpb_hs_msw    dw    ?        ;Hidden Sectors (Most Sig Word)
  1033. XXbpb_ts_large    dd    ?        ;Large Total Sector Count
  1034. XXbpb_res        db    6 dup (?)    ;Reserved
  1035. XXbpb        ends
  1036. XX
  1037. XX;
  1038. XX; ioctl function 42h
  1039. XX;
  1040. XXioctl_fmt    struc
  1041. XXioctl_fmt_spec    db    ?        ;Special Flags
  1042. XXioctl_fmt_head    dw    ?        ;Head to Format
  1043. XXioctl_fmt_cyl    dw    ?        ;Cylinder to Format
  1044. XXioctl_fmt    ends
  1045. XX
  1046. XX;
  1047. XX; ioctl function 60h
  1048. XX;
  1049. XXdpb        struc
  1050. XXdpb_special    db    ?        ;Special Flags
  1051. XXdpb_type    db    ?        ;Device Type
  1052. XXdpb_attr    dw    ?        ;Device Attributes
  1053. XXdpb_cyl        dw    ?        ;Device Cylinder Count
  1054. XXdpb_media    db    ?        ;Device Media Type if Diskette
  1055. XXdpb_bpb        db    size bpb dup (?)
  1056. XXdpb_sectors    dw    ?        ;Sectors in Track
  1057. XXdpb_track    dd    SECT_TRACK dup (?)
  1058. XXdpb        ends
  1059. XX
  1060. XX;
  1061. XX; The internal control structure for a SCSI device
  1062. XX;
  1063. XXunit        struc
  1064. XXunit_1st_drv    db    ?        ;DOS Drive Numbers
  1065. XXunit_num_drv    db    ?        ;DOS Drive Count
  1066. XXunit_select    db    ?        ;SCSI Select Bit
  1067. XXunit_mcheck    db    ?        ;Media Check Byte
  1068. XXunit_inq_buf    db    size inq dup (?)
  1069. XXunit_inq_term    db    ?
  1070. XXunit_cap_buf    db    size cap dup (?)
  1071. XXunit        ends
  1072. XX
  1073. XX;
  1074. XX; Ioctl Commands
  1075. XX;
  1076. XXioc        struc
  1077. XXioc_command    dw    ?        ;Command
  1078. XXioc_data    dw    ?        ;Command Dependent Data
  1079. XXioc        ends
  1080. XX
  1081. XX;
  1082. XX; DOS requests
  1083. XX;
  1084. XXrh        struc
  1085. XXrh_len        db    ?        ;Length of Packet
  1086. XXrh_unit        db    ?        ;Unit Code (Block Only)
  1087. XXrh_cmd        db    ?        ;Command Code
  1088. XXrh_status    dw    ?        ;Returned Status
  1089. XXrh_res        db    8 dup (?)    ;Reserved
  1090. XXrh        ends
  1091. XX
  1092. XXrh0        struc            ;INITIALIZATION
  1093. XXrh0_rh        db    size rh dup (?)    ;Fixed Portion
  1094. XXrh0_nunits    db    ?        ;Number of units (Block Only)
  1095. XXrh0_brk_ofs    dw    ?        ;Break Address (Offset)
  1096. XXrh0_brk_seg    dw    ?        ;Break Address (Segment)
  1097. XXrh0_bpb_tbo    dw    ?        ;Pointer to BPB Array (Offset)
  1098. XXrh0_bpb_tbs    dw    ?        ;Pointer to BPB Array (Segment)
  1099. XXrh0_drv_ltr    db    ?        ;First Available Drive (DOS 3+, Block Only)
  1100. XXrh0        ends
  1101. XX
  1102. XXrh1        struc            ;MEDIA CHECK
  1103. XXrh1_rh        db    size rh dup (?)    ;Fixed Portion
  1104. XXrh1_media    db    ?        ;Media Descriptor from DPB
  1105. XXrh1_md_stat    db    ?        ;Media Status returned by Device Driver
  1106. XXrh1_volid_ofs    dw    ?        ;Offset of Volume ID String (DOS 3+)
  1107. XXrh1_volid_seg    dw    ?        ;Segment of Volume ID String (DOS 3+)
  1108. XXrh1        ends
  1109. XX
  1110. XXrh2        struc            ;GET BPB
  1111. XXrh2_rh        db    size rh dup (?)    ;Fixed Portion
  1112. XXrh2_media    db    ?        ;Media Descriptor from DPB
  1113. XXrh2_buf_ofs    dw    ?        ;Offset of Data Transfer Area
  1114. XXrh2_buf_seg    dw    ?        ;Segment of Data Transfer Area
  1115. XXrh2_pbpbo    dw    ?        ;Offset of Pointer to BPB
  1116. XXrh2_pbpbs    dw    ?        ;Segment of Pointer to BPB
  1117. XXrh2        ends
  1118. XX
  1119. XXrh4        struc            ;INPUT
  1120. XXrh4_rh        db    size rh dup (?)    ;Fixed Portion
  1121. XXrh4_media    db    ?        ;Media Descriptor from DPB
  1122. XXrh4_buf_ofs    dw    ?        ;Offset of Data Transfer Area
  1123. XXrh4_buf_seg    dw    ?        ;Segment of Data Transfer Area
  1124. XXrh4_count    dw    ?        ;Transfer Count (Sectors)
  1125. XXrh4_start    dw    ?        ;Start Sector Number
  1126. XXrh4        ends
  1127. XX
  1128. XXrh8        struc            ;OUTPUT
  1129. XXrh8_rh        db    size rh dup (?)    ;Fixed Portion
  1130. XXrh8_media    db    ?        ;Media Descriptor from DPB
  1131. XXrh8_buf_ofs    dw    ?        ;Offset of Data Transfer Area
  1132. XXrh8_buf_seg    dw    ?        ;Segment of Data Transfer Area
  1133. XXrh8_count    dw    ?        ;Transfer Count (Sectors)
  1134. XXrh8_start    dw    ?        ;Start Sector Number
  1135. XXrh8        ends
  1136. XX
  1137. XXrh9        struc            ;OUTPUT VERIFY
  1138. XXrh9_rh        db    size rh dup (?)    ;Fixed Portion
  1139. XXrh9_media    db    ?        ;Media Descriptor from DPB
  1140. XXrh9_buf_ofs    dw    ?        ;Offset of Data Transfer Area
  1141. XXrh9_buf_seg    dw    ?        ;Segment of Data Transfer Area
  1142. XXrh9_count    dw    ?        ;Transfer Count (Sectors)
  1143. XXrh9_start    dw    ?        ;Start Sector Number
  1144. XXrh9        ends
  1145. XX
  1146. XXrh12        struc            ;OUTPUT IOCTL
  1147. XXrh12_rh        db    size rh dup (?)    ;Fixed Portion
  1148. XXrh12_media    db    ?        ;Media Descriptor from DPB
  1149. XXrh12_buf_ofs    dw    ?        ;Offset of Data Transfer Area
  1150. XXrh12_buf_seg    dw    ?        ;Segment of Data Transfer Area
  1151. XXrh12_count    dw    ?        ;Transfer Count (Sectors)
  1152. XXrh12_start    dw    ?        ;Start Sector Number
  1153. XXrh12        ends
  1154. XX
  1155. XXrh19        struc            ;IOCTL
  1156. XXrh19_rh        db    size rh dup (?)    ;Fixed Portion
  1157. XXrh19_major    db    ?        ;Major Code
  1158. XXrh19_minor    db    ?        ;Minor Code
  1159. XXrh19_si        dw    ?        ;Caller SI Register
  1160. XXrh19_di        dw    ?        ;Caller DI Register
  1161. XXrh19_buf_ofs    dw    ?        ;Caller Buffer Offset
  1162. XXrh19_buf_seg    dw    ?        ;Caller Buffer Segment
  1163. XXrh19        ends
  1164. SHAR_EOF
  1165. if test 5738 -ne "`wc -c < 'struct.inc'`"
  1166. then
  1167. echo shar: error transmitting "'struct.inc'" '(should have been 5738 characters)'
  1168. fi
  1169. fi # end of overwriting check
  1170. echo shar: extracting "'subs.asm'" '(11083 characters)'
  1171. if test -f 'subs.asm'
  1172. then
  1173. echo shar: will not over-write existing file "'subs.asm'"
  1174. else
  1175. sed 's/^XX//' > 'subs.asm' << \SHAR_EOF
  1176. XX;
  1177. XX; Data storage for local subroutines
  1178. XX;
  1179. XXcmd_ready    db    SCSI_TESTREADY,0,0,0,0,0
  1180. XXcmd_format    db    SCSI_FORMATUNIT,0,0,0,0,0
  1181. XXcmd_read    db    SCSI_READBLK,0,0,0,0,0,0,0,1,0
  1182. XXcmd_write    db    SCSI_WRITEBLK,0,0,0,0,0,0,0,1,0
  1183. XXcmd_inquire    db    SCSI_INQUIRY,0,0,0,size inq,0
  1184. XXcmd_capacity    db    SCSI_READSIZE,0,0,0,0,0,0,0,0,0
  1185. XXcmd_verify    db    SCSI_VERIFYBLK,0,0,0,0,0,0,0,SECT_TRACK,0
  1186. XX
  1187. XX        even
  1188. XXdocmd_cmd    dw    ?
  1189. XXdocmd_buf    dw    ?
  1190. XXdocmd_buf_seg    dw    ?
  1191. XXdocmd_len    dw    ?
  1192. XXdocmd_unit_sel    db    ?
  1193. XXdocmd_status    db    ?
  1194. XX
  1195. XX;
  1196. XX; Reset the SCSI Bus
  1197. XX;
  1198. XXscsi_reset    proc    near
  1199. XX        pusha
  1200. XX
  1201. XX        mov    ax,SCSI_CARD_SEG    ;Point at the command port
  1202. XX        mov    es,ax
  1203. XX        mov    si,SCSI_CMD_PORT
  1204. XX
  1205. XX        mov    al,CMDBASE or CMDENABLE or CMDRST
  1206. XX        mov    es:[si],al        ;Reset the bus
  1207. XX        call    wait1ms
  1208. XX        mov    al,CMDBASE
  1209. XX        mov    es:[si],al        ;All done
  1210. XX        mov    cx,250            ;Wait 250ms
  1211. XXreset_loop:    call    wait1ms
  1212. XX        loop    reset_loop
  1213. XX
  1214. XX        popa
  1215. XX        ret
  1216. XXscsi_reset    endp
  1217. XX
  1218. XX;
  1219. XX; Test the Ready Status of a unit
  1220. XX;
  1221. XX; al = return code, 'C' error
  1222. XX;
  1223. XXscsi_ready    proc    near
  1224. XX        lea    di,cmd_ready            ;Command
  1225. XX        call    docmd
  1226. XX        ret
  1227. XXscsi_ready    endp
  1228. XX
  1229. XX;
  1230. XX; Inquire about the type of a unit
  1231. XX;
  1232. XX; 'C' error indicates an error
  1233. XX;
  1234. XXscsi_inquire    proc    near
  1235. XX        push    cx
  1236. XX        mov    di,cur_unit            ;Unit
  1237. XX        lea    bx,[di].unit_inq_buf        ;Buffer Offset
  1238. XX        push    ds                ;Buffer Segment
  1239. XX        pop    es
  1240. XX        mov    cx,size inq            ;Buffer Size
  1241. XX        lea    di,cmd_inquire            ;Command
  1242. XX        call    docmd
  1243. XX        pop    cx
  1244. XX        ret
  1245. XXscsi_inquire    endp
  1246. XX
  1247. XX;
  1248. XX; Determine the size of a disk
  1249. XX;
  1250. XX; 'C' error indicates an error
  1251. XX;
  1252. XXscsi_capacity    proc    near
  1253. XX        push    cx
  1254. XX        mov    di,cur_unit            ;Unit
  1255. XX        lea    bx,[di].unit_cap_buf        ;Buffer Offset
  1256. XX        push    ds                ;Buffer Segment
  1257. XX        pop    es
  1258. XX        mov    cx,size cap            ;Buffer Size
  1259. XX        lea    di,cmd_capacity            ;Command
  1260. XX        call    docmd
  1261. XX        pop    cx
  1262. XX        ret
  1263. XXscsi_capacity    endp
  1264. XX
  1265. XX;
  1266. XX; Verify the Track given in an IOCTL Request
  1267. XX;
  1268. XX; 'C' indicates an error
  1269. XX;
  1270. XXscsi_verify    proc    near
  1271. XX        mov    di,es:[bx].rh19_buf_ofs        ;Command Offset
  1272. XX        mov    ax,es:[bx].rh19_buf_seg        ;Command Segment
  1273. XX        mov    es,ax
  1274. XX        mov    ax,es:[di].ioctl_fmt_cyl    ;Track
  1275. XX        shl    ax,SECT_2_CYL            ;Convert to Sector
  1276. XX
  1277. XX        mov    di,cur_bpb            ;Add to Drive Offset
  1278. XX        mov    dx,[di].bpb_hs_msw
  1279. XX
  1280. XX        lea    di,cmd_verify            ;Command
  1281. XX        mov    [di].ver_cmd_lba_b3,dh        ;Insert Sector
  1282. XX        mov    [di].ver_cmd_lba_b2,dl        ; into Command
  1283. XX        mov    [di].ver_cmd_lba_b1,ah        ;Insert Sector
  1284. XX        mov    [di].ver_cmd_lba_b0,al        ; into Command
  1285. XX        call    docmd
  1286. XX        ret
  1287. XXscsi_verify    endp
  1288. XX
  1289. XX;
  1290. XX; Read Some Blocks from the disk given
  1291. XX; the request header in es:bx
  1292. XX;
  1293. XX; al = return code, 'C' indicates an error
  1294. XX;
  1295. XXscsi_read    proc    near
  1296. XX        mov    di,bx
  1297. XX        mov    cx,es:[di].rh4_count        ;Sector Count
  1298. XX        mov    dx,es:[di].rh4_start        ;Starting Sector
  1299. XX        mov    bx,es:[di].rh4_buf_ofs        ;Buffer Offset
  1300. XX        mov    ax,es:[di].rh4_buf_seg        ;Buffer Segment
  1301. XX        mov    es,ax
  1302. XX
  1303. XX        mov    si,cur_bpb
  1304. XX        lea    di,cmd_read            ;Command
  1305. XX        mov    ax,[si].bpb_hs_msw        ;Drive Sector Offset
  1306. XX        mov    [di].io_cmd_lba_b3,ah        ;Insert Sector
  1307. XX        mov    [di].io_cmd_lba_b2,al        ;Into the Command
  1308. XX
  1309. XX        if multi_sector
  1310. XX        mov    ax,cx                ;Get Sector Count
  1311. XX        and    ax,CHUNK_MAX-1            ;Mask Off the I/O Chunk
  1312. XX        jnz    scsi_r_cok1            ;Check for Boundary
  1313. XX        mov    ax,CHUNK_MAX
  1314. XXscsi_r_cok1:    shl    ax,9                ;Convert to Buffer Size
  1315. XX        add    ax,bx                ;Check for Wrap
  1316. XX        else
  1317. XX        mov    ax,bx                ;Check for Wrap
  1318. XX        add    ax,P_SECT            ;The First Time
  1319. XX        endif
  1320. XXscsi_r_loop:    jnc    scsi_r_nowrap
  1321. XX        mov    ax,bx                ;Normalize the
  1322. XX        shr    ax,4                ;Segment and
  1323. XX        mov    si,es                ;Offset so that
  1324. XX        add    si,ax                ;It dosn't Wrap
  1325. XX        mov    es,si
  1326. XX        and    bx,000Fh
  1327. XXscsi_r_nowrap:    push    cx
  1328. XX        mov    [di].io_cmd_lba_b1,dh        ;Insert Sector
  1329. XX        mov    [di].io_cmd_lba_b0,dl        ;Into the Command
  1330. XX        if multi_sector
  1331. XX        and    cx,CHUNK_MAX-1            ;Mask Off the I/O Chunk
  1332. XX        jnz    scsi_r_cok2            ;Check for Boundary
  1333. XX        mov    cx,CHUNK_MAX
  1334. XXscsi_r_cok2:    mov    [di].io_cmd_cnt_b1,ch        ;Insert Sector Count
  1335. XX        mov    [di].io_cmd_cnt_b0,cl        ;Into the Command
  1336. XX        shl    cx,9                ;Convert to Buffer Size
  1337. XX        else
  1338. XX        mov    cx,P_SECT            ;Buffer Size
  1339. XX        endif
  1340. XX        call    docmd
  1341. XX        pop    cx
  1342. XX        jc    scsi_r_exit
  1343. XX        if multi_sector
  1344. XX        mov    ax,cx                ;Get Sector Count
  1345. XX        and    ax,CHUNK_MAX-1            ;Mask Off the I/O Chunk
  1346. XX        jnz    scsi_r_cok3            ;Check for Boundary
  1347. XX        mov    ax,CHUNK_MAX
  1348. XXscsi_r_cok3:    sub    cx,ax                ;Dec Sector Count
  1349. XX        jz    scsi_r_exit
  1350. XX        add    dx,ax                ;Bump to next Sector
  1351. XX        shl    ax,9                ;Convert to Buffer Size
  1352. XX        add    bx,ax
  1353. XX        jmp    short scsi_r_loop
  1354. XX        else
  1355. XX        inc    dx                ;Bump to next Sector
  1356. XX        add    bx,P_SECT
  1357. XX        loop    scsi_r_loop
  1358. XX        clc
  1359. XX        endif
  1360. XXscsi_r_exit:    mov    es,rh_seg
  1361. XX        mov    bx,rh_off
  1362. XX        pushf
  1363. XX        mov    ax,es:[bx].rh4_count        ;Update the Count
  1364. XX        sub    ax,cx
  1365. XX        mov    es:[bx].rh4_count,ax
  1366. XX        popf
  1367. XX        ret
  1368. XXscsi_read    endp
  1369. XX
  1370. XX;
  1371. XX; Write Some Blocks from the disk given
  1372. XX; the request header in es:bx
  1373. XX;
  1374. XX; al = return code, 'C' indicates an error
  1375. XX;
  1376. XXscsi_write    proc    near
  1377. XX        mov    di,bx
  1378. XX        mov    cx,es:[di].rh8_count        ;Sector Count
  1379. XX        mov    dx,es:[di].rh8_start        ;Starting Sector
  1380. XX        mov    bx,es:[di].rh8_buf_ofs        ;Buffer Offset
  1381. XX        mov    ax,es:[di].rh8_buf_seg        ;Buffer Segment
  1382. XX        mov    es,ax
  1383. XX
  1384. XX        mov    si,cur_bpb
  1385. XX        lea    di,cmd_write            ;Command
  1386. XX        mov    ax,[si].bpb_hs_msw        ;Drive Sector Offset
  1387. XX        mov    [di].io_cmd_lba_b3,ah        ;Insert Sector
  1388. XX        mov    [di].io_cmd_lba_b2,al        ;Into the Command
  1389. XX
  1390. XX        if multi_sector
  1391. XX        mov    ax,cx                ;Get Sector Count
  1392. XX        and    ax,CHUNK_MAX-1            ;Mask Off the I/O Chunk
  1393. XX        jnz    scsi_w_cok1            ;Check for Boundary
  1394. XX        mov    ax,CHUNK_MAX
  1395. XXscsi_w_cok1:    shl    ax,9                ;Convert to Buffer Size
  1396. XX        add    ax,bx                ;Check for Wrap
  1397. XX        else
  1398. XX        mov    ax,bx                ;Check for Wrap
  1399. XX        add    ax,P_SECT            ;The First Time
  1400. XX        endif
  1401. XXscsi_w_loop:    jnc    scsi_w_nowrap
  1402. XX        mov    ax,bx                ;Normalize the
  1403. XX        shr    ax,4                ;Segment and
  1404. XX        mov    si,es                ;Offset so that
  1405. XX        add    si,ax                ;It dosn't Wrap
  1406. XX        mov    es,si
  1407. XX        and    bx,000Fh
  1408. XXscsi_w_nowrap:    push    cx
  1409. XX        mov    [di].io_cmd_lba_b1,dh        ;Insert Sector
  1410. XX        mov    [di].io_cmd_lba_b0,dl        ;Into the Command
  1411. XX        if multi_sector
  1412. XX        and    cx,CHUNK_MAX-1            ;Mask Off the I/O Chunk
  1413. XX        jnz    scsi_w_cok2            ;Check for Boundary
  1414. XX        mov    cx,CHUNK_MAX
  1415. XXscsi_w_cok2:    mov    [di].io_cmd_cnt_b1,ch        ;Insert Sector Count
  1416. XX        mov    [di].io_cmd_cnt_b0,cl        ;Into the Command
  1417. XX        shl    cx,9                ;Convert to Buffer Size
  1418. XX        else
  1419. XX        mov    cx,P_SECT            ;Buffer Size
  1420. XX        endif
  1421. XX        call    docmd
  1422. XX        pop    cx
  1423. XX        jc    scsi_w_exit
  1424. XX        if multi_sector
  1425. XX        mov    ax,cx                ;Get Sector Count
  1426. XX        and    ax,CHUNK_MAX-1            ;Mask Off the I/O Chunk
  1427. XX        jnz    scsi_w_cok3            ;Check for Boundary
  1428. XX        mov    ax,CHUNK_MAX
  1429. XXscsi_w_cok3:    sub    cx,ax                ;Dec Sector Count
  1430. XX        jz    scsi_w_exit
  1431. XX        add    dx,ax                ;Bump to next Sector
  1432. XX        shl    ax,9                ;Convert to Buffer Size
  1433. XX        add    bx,ax
  1434. XX        jmp    short scsi_w_loop
  1435. XX        else
  1436. XX        inc    dx                ;Bump to next Sector
  1437. XX        add    bx,P_SECT
  1438. XX        loop    scsi_w_loop
  1439. XX        clc
  1440. XX        endif
  1441. XXscsi_w_exit:    mov    es,rh_seg
  1442. XX        mov    bx,rh_off
  1443. XX        pushf
  1444. XX        mov    ax,es:[bx].rh8_count        ;Update the Count
  1445. XX        sub    ax,cx
  1446. XX        mov    es:[bx].rh8_count,ax
  1447. XX        popf
  1448. XX        ret
  1449. XXscsi_write    endp
  1450. XX
  1451. XX;
  1452. XX; Do a command
  1453. XX;
  1454. XX; bx => buffer for returned information
  1455. XX; cx = buffer len
  1456. XX; di => command string
  1457. XX; es = buffer segment for returned information
  1458. XX;
  1459. XX; al = return code, 'C' indicates an error
  1460. XX;
  1461. XXdocmd        proc    near
  1462. XX        pusha
  1463. XX        push    es
  1464. XX
  1465. XX        mov    docmd_buf,bx        ;Save our arguments
  1466. XX        mov    docmd_buf_seg,es
  1467. XX        mov    docmd_len,cx
  1468. XX        mov    docmd_cmd,di
  1469. XX
  1470. XX        mov    ax,SCSI_CARD_SEG    ;Point at the Card
  1471. XX        mov    es,ax
  1472. XX        mov    si,SCSI_CMD_PORT    ;Command Port
  1473. XX
  1474. XX;
  1475. XX; Wait for the Bus to become free
  1476. XX;
  1477. XX        mov    cx,65535
  1478. XXidle_loop:    mov    al,es:[si]        ;Get the Status
  1479. XX        and    al,FREE_MASK
  1480. XX        jz    try_sel
  1481. XX        loop    idle_loop
  1482. XX
  1483. XX        call    scsi_reset
  1484. XX        mov    al,CBUSBUSY        ;Bus still BUSY?
  1485. XX        stc
  1486. XX        jmp    docmd_exit
  1487. XX
  1488. XXtry_sel:    mov    al,CMDBASE        ;Try to select target
  1489. XX        mov    es:[si],al
  1490. XX
  1491. XX        mov    di,cur_unit
  1492. XX        mov    al,[di].unit_select    ;Get our Select Bit
  1493. XX        mov    di,SCSI_DATA_PORT    ;Data Port
  1494. XX        mov    es:[di],al
  1495. XX
  1496. XX        mov    al,CMDBASE or CMDENABLE or CMDSEL
  1497. XX        mov    es:[si],al
  1498. XX
  1499. XX;
  1500. XX; Wait 250 ms for the Target to be SELected
  1501. XX;
  1502. XX        mov    cx,2500
  1503. XXsel_loop:    test    byte ptr es:[si],STBSY    ;Look for BSY bit
  1504. XX        jnz    cmd_xfer
  1505. XX        call    wait100us
  1506. XX        loop    sel_loop
  1507. XX
  1508. XX        mov    al,CNOCONNECT        ;Nothing Answered
  1509. XX        stc
  1510. XX        jmp    docmd_exit
  1511. XX
  1512. XX;
  1513. XX; Start the Command
  1514. XX;
  1515. XXcmd_xfer:    mov    al,CMDBASE or CMDENABLE
  1516. XX        mov    es:[si],al
  1517. XXxfer_loop:    mov    al,es:[si]
  1518. XX        test    al,STBSY        ;Look for BSY bit
  1519. XX        jz    xfer_error
  1520. XX        test    al,STREQ        ;And REQ bit
  1521. XX        jz    xfer_loop
  1522. XX
  1523. XX        and    al,REQ_MASK        ;Look at REQ type
  1524. XX
  1525. XX        cmp    al,REQ_DATAOUT        ;Is it Data Out?
  1526. XX        jnz    try_datain
  1527. XX        call    send_data
  1528. XX        jmp    short xfer_loop
  1529. XX
  1530. XXtry_datain:    cmp    al,REQ_DATAIN        ;Is it Data In?
  1531. XX        jnz    try_cmdout
  1532. XX        call    receive_data
  1533. XX        jmp    short xfer_loop
  1534. XX
  1535. XXtry_cmdout:    cmp    al,REQ_CMDOUT        ;Is it Command Out?
  1536. XX        jnz    try_statin
  1537. XX        call    send_cmd
  1538. XX        jmp    short xfer_loop
  1539. XX
  1540. XXtry_statin:    cmp    al,REQ_STATIN        ;Is it Status In?
  1541. XX        jnz    try_msgout
  1542. XX        mov    al,es:[di]        ;Get the Status Byte
  1543. XX        mov    docmd_status,al
  1544. XX        jmp    short xfer_loop
  1545. XX
  1546. XXtry_msgout:    cmp    al,REQ_MSGOUT        ;Is it Message Out?
  1547. XX        jnz    try_msgin
  1548. XX        call    send_nop
  1549. XX        jmp    short xfer_loop
  1550. XX
  1551. XXtry_msgin:    cmp    al,REQ_MSGIN        ;Is it Message In?
  1552. XX        jnz    xfer_error
  1553. XX
  1554. XX        mov    al,es:[di]        ;Get Message Byte
  1555. XX        cmp    al,MSG_COMPLETE        ;Are We All Done?
  1556. XX        jnz    short xfer_loop
  1557. XX        mov    al,docmd_status
  1558. XX        cmp    al,0
  1559. XX        jnz    xfer_error
  1560. XX        mov    al,COK
  1561. XX        clc
  1562. XX        jmp    docmd_exit
  1563. XX
  1564. XXxfer_error:    call    scsi_reset
  1565. XX        mov    al,CERROR
  1566. XX        stc
  1567. XX
  1568. XXdocmd_exit:    mov    docmd_status,al
  1569. XX        mov    al,CMDBASE
  1570. XX        mov    es:[si],al
  1571. XX        pop    es
  1572. XX        popa
  1573. XX        mov    al,docmd_status
  1574. XX        ret
  1575. XXdocmd        endp
  1576. XX
  1577. XX;
  1578. XX; Receive a Data Stream from the card
  1579. XX; On entry es:[di] points at the data port
  1580. XX;          es:[si] points at the command port
  1581. XX;
  1582. XXreceive_data    proc    near
  1583. XX        mov    dx,es            ;Save ES
  1584. XX
  1585. XX        mov    bx,si
  1586. XX        mov    ax,es
  1587. XX        mov    cx,docmd_len        ;Length
  1588. XX        mov    di,docmd_buf        ;Dest Offset
  1589. XX        mov    es,docmd_buf_seg    ;Dest Segment
  1590. XX        mov    si,SCSI_DATA_PORT    ;Source Offset
  1591. XX        mov    ds,ax            ;Source Segment
  1592. XX        mov    al,STREQ
  1593. XX        cld
  1594. XX
  1595. XXreceive_loop:    movsb
  1596. XX        dec    si            ;Don't blow the card buffer
  1597. XX        dec    cx
  1598. XX        jz    receive_exit
  1599. XXreceive_wait:    test    byte ptr [bx],al    ;Ready?
  1600. XX        jnz    receive_loop
  1601. XX        jmp    short receive_wait
  1602. XX
  1603. XXreceive_exit:    mov    si,SCSI_CMD_PORT    ;Restore the Environment
  1604. XX        mov    di,SCSI_DATA_PORT
  1605. XX        mov    ax,cs
  1606. XX        mov    ds,ax
  1607. XX        mov    es,dx
  1608. XX        ret
  1609. XXreceive_data    endp
  1610. XX
  1611. XX;
  1612. XX; Send a Command to the card
  1613. XX; On entry es:[di] points at the data port
  1614. XX;          es:[si] points at the command port
  1615. XX;
  1616. XXsend_cmd    proc    near
  1617. XX        mov    bx,docmd_cmd        ;Get Command Pointer
  1618. XX        mov    al,[bx]            ;Get a Command Byte
  1619. XX        mov    es:[di],al        ;Send it to Card
  1620. XX        inc    bx            ;Bump for Next Time
  1621. XX        mov    docmd_cmd,bx
  1622. XX        ret
  1623. XXsend_cmd    endp
  1624. XX
  1625. XX;
  1626. XX; Send a Data Stream to the card
  1627. XX; On entry es:[di] points at the data port
  1628. XX;          es:[si] points at the command port
  1629. XX;
  1630. XXsend_data    proc    near
  1631. XX        mov    bx,si
  1632. XX        mov    cx,docmd_len        ;Get the Data Count
  1633. XX        mov    si,docmd_buf        ;Source Offset
  1634. XX        mov    ds,docmd_buf_seg    ;Source Segment
  1635. XX        mov    al,STREQ
  1636. XX        cld
  1637. XX
  1638. XXsend_loop:    movsb
  1639. XX        dec    di            ;Don't blow the card buffer
  1640. XX        dec    cx
  1641. XX        jz    send_exit
  1642. XXsend_wait:    test    byte ptr es:[bx],al    ;Ready?
  1643. XX        jnz    send_loop
  1644. XX        jmp    short send_wait
  1645. XX
  1646. XXsend_exit:    mov    si,SCSI_CMD_PORT    ;Restore the Environment
  1647. XX        mov    di,SCSI_DATA_PORT
  1648. XX        mov    ax,cs
  1649. XX        mov    ds,ax
  1650. XX        ret
  1651. XXsend_data    endp
  1652. XX
  1653. XX;
  1654. XX; Send a NOP Message
  1655. XX;
  1656. XXsend_nop    proc    near
  1657. XX        mov    al,MSG_NOP        ;Oops, send a nop
  1658. XX        mov    es:[di],al
  1659. XX        mov    al,CMDBASE or CMDENABLE
  1660. XX        mov    es:[si],al
  1661. XX        ret
  1662. XXsend_nop    endp
  1663. XX
  1664. XX;
  1665. XX; Wait One Milli second
  1666. XX;
  1667. XX; The value of 'cx' is computed for an 8 Mhz Clock
  1668. XX;
  1669. XXwait1ms        proc    near
  1670. XX        push    cx        ;   (3) = 375ns
  1671. XX        mov    cx,798        ;   (2) = 250ns
  1672. XXwait_m_loop:    loop    wait_m_loop    ;  (10) = 1250ns * X
  1673. XX        pop    cx        ;   (5) = 625ns
  1674. XX        ret            ; (11+) = 1375ns
  1675. XXwait1ms        endp
  1676. XX
  1677. XX;
  1678. XX; Wait One Hundred Micros Seconds
  1679. XX;
  1680. XX; The value of 'cx' is computed for an 8 Mhz Clock
  1681. XX;
  1682. XXwait100us    proc    near
  1683. XX        push    cx        ;   (3) = 375ns
  1684. XX        mov    cx,78        ;   (2) = 250ns
  1685. XXwait_u_loop:    loop    wait_u_loop    ;  (10) = 1250ns * X
  1686. XX        pop    cx        ;   (5) = 625ns
  1687. XX        ret            ; (11+) = 1375ns
  1688. XXwait100us    endp
  1689. SHAR_EOF
  1690. if test 11083 -ne "`wc -c < 'subs.asm'`"
  1691. then
  1692. echo shar: error transmitting "'subs.asm'" '(should have been 11083 characters)'
  1693. fi
  1694. fi # end of overwriting check
  1695. echo shar: extracting "'units.asm'" '(3252 characters)'
  1696. if test -f 'units.asm'
  1697. then
  1698. echo shar: will not over-write existing file "'units.asm'"
  1699. else
  1700. sed 's/^XX//' > 'units.asm' << \SHAR_EOF
  1701. XX;
  1702. XX; target information/control structures
  1703. XX;
  1704. XX        even
  1705. XXunit0        db    size unit dup (-1)
  1706. XX        even
  1707. XXunit1        db    size unit dup (-1)
  1708. XX        even
  1709. XXunit2        db    size unit dup (-1)
  1710. XX        even
  1711. XXunit3        db    size unit dup (-1)
  1712. XX        even
  1713. XXunit4        db    size unit dup (-1)
  1714. XX        even
  1715. XXunit5        db    size unit dup (-1)
  1716. XX        even
  1717. XXunit6        db    size unit dup (-1)
  1718. XX        even
  1719. XXunit7        db    size unit dup (-1)
  1720. XX
  1721. XX        even
  1722. XXbpb0        db    size bpb dup (-1)
  1723. XX        even
  1724. XXbpb1        db    size bpb dup (-1)
  1725. XX        even
  1726. XXbpb2        db    size bpb dup (-1)
  1727. XX        even
  1728. XXbpb3        db    size bpb dup (-1)
  1729. XX        even
  1730. XXbpb4        db    size bpb dup (-1)
  1731. XX        even
  1732. XXbpb5        db    size bpb dup (-1)
  1733. XX        even
  1734. XXbpb6        db    size bpb dup (-1)
  1735. XX        even
  1736. XXbpb7        db    size bpb dup (-1)
  1737. XX        even
  1738. XXbpb8        db    size bpb dup (-1)
  1739. XX        even
  1740. XXbpb9        db    size bpb dup (-1)
  1741. XX        even
  1742. XXbpbA        db    size bpb dup (-1)
  1743. XX        even
  1744. XXbpbB        db    size bpb dup (-1)
  1745. XX        even
  1746. XXbpbC        db    size bpb dup (-1)
  1747. XX        even
  1748. XXbpbD        db    size bpb dup (-1)
  1749. XX        even
  1750. XXbpbE        db    size bpb dup (-1)
  1751. XX        even
  1752. XXbpbF        db    size bpb dup (-1)
  1753. XX
  1754. XX        even
  1755. XXunit_array    dw    unit0
  1756. XX        dw    unit1
  1757. XX        dw    unit2
  1758. XX        dw    unit3
  1759. XX        dw    unit4
  1760. XX        dw    unit5
  1761. XX        dw    unit6
  1762. XX        dw    unit7
  1763. XX
  1764. XX        even
  1765. XXbpb_array    dw    bpb0        ;BPB Array for DOS
  1766. XX        dw    bpb1
  1767. XX        dw    bpb2
  1768. XX        dw    bpb3
  1769. XX        dw    bpb4
  1770. XX        dw    bpb5
  1771. XX        dw    bpb6
  1772. XX        dw    bpb7
  1773. XX        dw    bpb8
  1774. XX        dw    bpb9
  1775. XX        dw    bpbA
  1776. XX        dw    bpbB
  1777. XX        dw    bpbC
  1778. XX        dw    bpbD
  1779. XX        dw    bpbE
  1780. XX        dw    bpbF
  1781. XXbpb_hw_mark    dw    bpb_array
  1782. XX
  1783. XXcur_unit    dw    unit0
  1784. XXcur_bpb        dw    bpb0
  1785. XX
  1786. XX;
  1787. XX; Given the request header in es:bx
  1788. XX; Return a pointer in ds:di to the unit entry
  1789. XX; or 'C' if no such unit exists.
  1790. XX;
  1791. XX; Do not destroy es:bx !!!
  1792. XX;
  1793. XXfind_unit    proc    near
  1794. XX        pusha
  1795. XX        mov    ah,es:[bx].rh_unit    ;What drive did they want
  1796. XX        lea    di,unit_array
  1797. XX        lea    si,bpb_array
  1798. XX        mov    cx,MAXUNIT        ;How many to search
  1799. XXfind_loop:    mov    bx,[di]            ;Point at a unit    
  1800. XX        mov    al,[bx].unit_num_drv    ;Does this SCSI device
  1801. XX        or    al,al            ;Have any Drives Defined?
  1802. XX        jz    find_next
  1803. XX        mov    dh,[bx].unit_1st_drv    ;Get First Drive Number
  1804. XXfind_unit_loop:    cmp    ah,dh            ;Is this the correct drive?
  1805. XX        jz    find_match
  1806. XX        inc    si            ;Bump to next BPB
  1807. XX        inc    si
  1808. XX        inc    dh            ;Bump Drive Number
  1809. XX        dec    al            ;Dec Drive count
  1810. XX        jnz    find_unit_loop        ;Try next Drive
  1811. XX        jmp    short find_next        ;Try next SCSI device
  1812. XXfind_match:    mov    cur_unit,bx        ;Found a match
  1813. XX        mov    ax,[si]
  1814. XX        mov    cur_bpb,ax
  1815. XX        clc
  1816. XX        jmp    find_exit
  1817. XXfind_next:    inc    di
  1818. XX        inc    di
  1819. XX        loop    find_loop
  1820. XX        stc                ;No More units, Error
  1821. XXfind_exit:    popa
  1822. XX        ret
  1823. XXfind_unit    endp
  1824. XX
  1825. XX;
  1826. XX; Given the data in a unit entry,
  1827. XX; create the bpb for the unit.
  1828. XX;
  1829. XXmake_bpb    proc    near
  1830. XX        mov    di,cur_bpb        ;Get the current BPB
  1831. XX        mov    bx,cur_unit        ;Get the current Unit
  1832. XX        mov    [di].bpb_ss,P_SECT
  1833. XX        mov    [di].bpb_au,CLUSTSIZE
  1834. XX        mov    [di].bpb_rs,1
  1835. XX        mov    [di].bpb_nf,2
  1836. XX        mov    [di].bpb_de,512
  1837. XX        mov    ah,[bx].unit_cap_buf.cap_sectors_b3
  1838. XX        mov    al,[bx].unit_cap_buf.cap_sectors_b2
  1839. XX        or    ax,ax
  1840. XX        jz    make_bpb_last        ;Use up the last few sectors
  1841. XX        dec    ax            ;Use up 65536 Sectors
  1842. XX        mov    [bx].unit_cap_buf.cap_sectors_b3,ah
  1843. XX        mov    [bx].unit_cap_buf.cap_sectors_b2,al
  1844. XX        mov    dx,65535        ;Max of 32 Meg
  1845. XX        jmp    short make_bpb_ts
  1846. XXmake_bpb_last:    mov    dh,[bx].unit_cap_buf.cap_sectors_b1
  1847. XX        mov    [bx].unit_cap_buf.cap_sectors_b1,0
  1848. XX        mov    dl,0            ;Round to nearest Cyl
  1849. XX        mov    [bx].unit_cap_buf.cap_sectors_b0,0
  1850. XX        dec    dx            ;Make it zero relative
  1851. XXmake_bpb_ts:    mov    [di].bpb_ts,dx
  1852. XX        mov    [di].bpb_md,0F8h
  1853. XX        shr    dx,SECT_2_FS
  1854. XX        inc    dx            ;Allow for round-off
  1855. XX        mov    [di].bpb_fs,dx
  1856. XX        mov    [di].bpb_st,SECT_TRACK
  1857. XX        mov    [di].bpb_nh,1
  1858. XX        mov    [di].bpb_hs_lsw,0
  1859. XX        mov    [di].bpb_hs_msw,0
  1860. XX        ret
  1861. XXmake_bpb    endp
  1862. SHAR_EOF
  1863. if test 3252 -ne "`wc -c < 'units.asm'`"
  1864. then
  1865. echo shar: error transmitting "'units.asm'" '(should have been 3252 characters)'
  1866. fi
  1867. fi # end of overwriting check
  1868. #
  1869. # End of shell archive
  1870. #
  1871. exit 0
  1872.