home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 1 / 1793 < prev    next >
Internet Message Format  |  1990-12-28  |  70KB

  1. From: briana@tau-ceti.isc-br.com (Brian Who?)
  2. Newsgroups: alt.sources
  3. Subject: SCSI Version 1.1
  4. Message-ID: <681@tau-ceti.isc-br.com>
  5. Date: 8 Sep 90 19:15:46 GMT
  6.  
  7.  
  8.      Here is version 1.1 of my SCSI Device Driver for the Seagate ST-01
  9. interface card.  It add support for a single tape device and cleans up
  10. the code a little.
  11.  
  12. #
  13. # This is a Shell Archive.
  14. # Remove everything above and including the cut line.
  15. # Then run the rest of the file through #! /bin/sh.
  16. # -----cut here-----cut here-----cut here-----cut here-----
  17. #! /bin/sh
  18. # Execute the file with #! /bin/sh (not csh) to create the files:
  19. #    binmode.c
  20. #    dump.asm
  21. #    equ.inc
  22. #    ioctl.asm
  23. #    kludge.asm
  24. #    makefile
  25. #    options.inc
  26. #    readme.10
  27. #    readme.11
  28. #    scsi.asm
  29. #    serase.c
  30. #    sformat.c
  31. #    struct.inc
  32. #    subs.asm
  33. #    units.asm
  34. # This Archive created: Sat Sep  8 12:13:37 1990
  35. # By: Brian Who? at I Saute Cats - Barbecue Rats, Spokane, WA
  36. #
  37. export PATH; PATH=/bin:$PATH
  38. echo shar: extracting "'binmode.c'" '(497 characters)'
  39. if test -f 'binmode.c'
  40. then
  41. echo shar: will not over-write existing file "'binmode.c'"
  42. else
  43. sed 's/^XX//' > 'binmode.c' << \SHAR_EOF
  44. XX#ifdef MSDOS
  45. XX#include <dos.h>
  46. XX
  47. XXbinmode(fd)
  48. XXint fd;
  49. XX{
  50. XX    union REGS inregs, outregs;
  51. XX
  52. XX    /*
  53. XX    ** get the current mode
  54. XX    */
  55. XX    inregs.h.ah = 0x44;            /* ioctl */
  56. XX    inregs.h.al = 0x00;            /* get */
  57. XX    inregs.x.bx = fd;            /* unit */
  58. XX    intdos(&inregs, &outregs);
  59. XX
  60. XX    /*
  61. XX    ** set to BINARY mode (this works for char devices)
  62. XX    */
  63. XX    inregs.h.ah = 0x44;            /* ioctl */
  64. XX    inregs.h.al = 0x01;            /* set */
  65. XX    inregs.x.bx = fd;            /* unit */
  66. XX    inregs.h.dh = 0;
  67. XX    inregs.h.dl = outregs.h.dl | 0x20;
  68. XX    intdos(&inregs, &outregs);
  69. XX}
  70. XX#endif
  71. SHAR_EOF
  72. if test 497 -ne "`wc -c < 'binmode.c'`"
  73. then
  74. echo shar: error transmitting "'binmode.c'" '(should have been 497 characters)'
  75. fi
  76. fi # end of overwriting check
  77. echo shar: extracting "'dump.asm'" '(1296 characters)'
  78. if test -f 'dump.asm'
  79. then
  80. echo shar: will not over-write existing file "'dump.asm'"
  81. else
  82. sed 's/^XX//' > 'dump.asm' << \SHAR_EOF
  83. XX;
  84. XX; Convert bin (ax) to ascii (bx => buffer)
  85. XX;
  86. XXbin_ascii    proc    near
  87. XX        pusha
  88. XX        push    ax
  89. XX        mov    cx,6
  90. XXfill_buff:    mov    byte ptr [bx],' '
  91. XX        inc    bx
  92. XX        loop    fill_buff
  93. XX        mov    si,10
  94. XX        or    ax,ax
  95. XX        jns    clr_dvd
  96. XX        neg    ax
  97. XXclr_dvd:    sub    dx,dx
  98. XX        div    si
  99. XX        add    dx,'0'
  100. XX        dec    bx
  101. XX        mov    [bx],dl
  102. XX        inc    cx
  103. XX        or    ax,ax
  104. XX        jnz    clr_dvd
  105. XX        pop    ax
  106. XX        or    ax,ax
  107. XX        jns    no_more
  108. XX        dec    bx
  109. XX        mov    byte ptr [bx],'-'
  110. XXno_more:    popa
  111. XX        ret
  112. XXbin_ascii    endp
  113. XX
  114. XX;
  115. XX; Convert Hex (dx) to Ascii (bx => buffer)
  116. XX;
  117. XXhex2asc4    proc    near
  118. XX        push    cx
  119. XX        push    ax
  120. XX        mov    cx,4        ;Do Four Digits
  121. XXh241:        rol    dx,4
  122. XX        mov    al,dl        ;Get the Current Digit
  123. XX        and    al,0Fh
  124. XX        cmp    al,0Ah        ;Is It Hex?
  125. XX        jge    h242
  126. XX        add    al,30h        ;Normal Digit
  127. XX        jmp    h243
  128. XXh242:        add    al,37h        ;Hex Digit
  129. XXh243:        mov    [bx],al        ;Insert in Buffer
  130. XX        inc    bx
  131. XX        loop    h241
  132. XX        pop    ax
  133. XX        pop    cx
  134. XX        ret
  135. XXhex2asc4    endp
  136. XX
  137. XX;
  138. XX; Convert Hex (dl) to Ascii (bx => buffer)
  139. XX;
  140. XXhex2asc2    proc    near
  141. XX        push    cx
  142. XX        push    ax
  143. XX        mov    cx,2        ;Do Two Digits
  144. XXh221:        rol    dl,4
  145. XX        mov    al,dl        ;Get the Current Digit
  146. XX        and    al,0Fh
  147. XX        cmp    al,0Ah        ;Is It Hex?
  148. XX        jge    h222
  149. XX        add    al,30h        ;Normal Digit
  150. XX        jmp    h223
  151. XXh222:        add    al,37h        ;Hex Digit
  152. XXh223:        mov    [bx],al        ;Insert in Buffer
  153. XX        inc    bx
  154. XX        loop    h221
  155. XX        pop    ax
  156. XX        pop    cx
  157. XX        ret
  158. XXhex2asc2    endp
  159. XX
  160. XX;
  161. XX; Print a string
  162. XX;
  163. XX; ds:dx => string
  164. XX;
  165. XXputs        proc    near
  166. XX        pusha
  167. XX        mov    ah,9        ;DOS print string
  168. XX        int    21h
  169. XX        popa
  170. XX        ret
  171. XXputs        endp
  172. SHAR_EOF
  173. if test 1296 -ne "`wc -c < 'dump.asm'`"
  174. then
  175. echo shar: error transmitting "'dump.asm'" '(should have been 1296 characters)'
  176. fi
  177. fi # end of overwriting check
  178. echo shar: extracting "'equ.inc'" '(3726 characters)'
  179. if test -f 'equ.inc'
  180. then
  181. echo shar: will not over-write existing file "'equ.inc'"
  182. else
  183. sed 's/^XX//' > 'equ.inc' << \SHAR_EOF
  184. XX;
  185. XX; Equates
  186. XX;
  187. XXTRUE            EQU    001h
  188. XXFALSE            EQU    000h
  189. XX
  190. XXDISK_REQUEST    EQU    000h        ;Disk I/O Request
  191. XXTAPE_REQUEST    EQU    001h        ;Tape I/O Request
  192. XX
  193. XX;
  194. XX; ST-01 Card Registers
  195. XX;
  196. XXSCSI_CARD_SEG    EQU    0DE00h        ;Base Segment of Card
  197. XXSCSI_CMD_PORT    EQU    01A00h        ;Offset to Command Port
  198. XXSCSI_DATA_PORT    EQU    01C00h        ;Offset to Data Port
  199. XX
  200. XXSTACK_SIZE    EQU    512        ;Our Local Stack
  201. XX
  202. XX;
  203. XX; How the 16 bit sector number is broken down
  204. XX; into a sector and cylinder number.
  205. XX;
  206. XX; x = Cylinder, y = track, always have only 1 head
  207. XX;
  208. XX; xxxx xxxx xxxx yyyy
  209. XX;
  210. XX; SECT_2_FS is computed as: ((unit_bpb.bpb_ts / CLUSTSIZE) * 2) / P_SECT)
  211. XX;
  212. XXSECT_TRACK    EQU    16        ;Logical Sectors in a Track
  213. XXSECT_MASK    EQU    0000Fh        ;Mask for Sector
  214. XXCYL_MASK    EQU    0FFF0h        ;Mask for Cylinder
  215. XXSECT_2_CYL    EQU    4        ;How far to shift to convert
  216. XX                    ;Sector to Cylinder Number
  217. XXSECT_2_FS    EQU    10        ;How far to shift for
  218. XX                    ;Total Sectors to Fat Sectors
  219. XX
  220. XX;
  221. XX; The max target to check for (0-X).
  222. XX; If using 'reserve_addr', this should not execede 6!
  223. XX;
  224. XXMAXUNIT        EQU    6        ;Maximum Unit Number
  225. XX
  226. XXP_SECT        EQU    512        ;Physical Sector Size
  227. XXCLUSTSIZE    EQU    4        ;Number of Sectors to a Cluster
  228. XX
  229. XX;
  230. XX; For multi_sector reads and writes,
  231. XX; set the following to '1'
  232. XX;
  233. XX; CHUNK_MASK is the maximum number of sectors to access in one
  234. XX; SCSI request.  It MUST be a power of two, and CHUNK_MASK * P_SECT
  235. XX; MUST be <= 64K to prevent segment wrap problems.
  236. XX;
  237. XXCHUNK_MAX    EQU    32
  238. XX
  239. XXCMDENABLE    EQU    080h        ;Enable the output drivers
  240. XXCMDENINTR    EQU    040h        ;Enable Interrupt
  241. XXCMDPARITY    EQU    020h        ;Enable Parity
  242. XXCMDSTARB    EQU    010h        ;Start Bus Arbitration
  243. XXCMDATTN        EQU    008h        ;Assert ATTN
  244. XXCMDBSY        EQU    004h        ;Assert BSY
  245. XXCMDSEL        EQU    002h        ;Assert SEL
  246. XXCMDRST        EQU    001h        ;Assert RST
  247. XX
  248. XX        if scsi_parity
  249. XXCMDBASE        EQU    CMDPARITY    ;Base value of all commands
  250. XX        else
  251. XXCMDBASE        EQU    000h        ;Base value of all commands
  252. XX        endif
  253. XX
  254. XXSTARBCOMPL    EQU    080h        ;Arbitration Complete
  255. XXSTPARERR    EQU    040h        ;Parity Error
  256. XXSTSEL        EQU    020h        ;SEL Asserted
  257. XXSTREQ        EQU    010h        ;REQ Asserted
  258. XXSTCD        EQU    008h        ;C/D Asserted
  259. XXSTIO        EQU    004h        ;I/O Asserted
  260. XXSTMSG        EQU    002h        ;MSG Asserted
  261. XXSTBSY        EQU    001h        ;BSY Asserted
  262. XX
  263. XXFREE_MASK    EQU    03Fh
  264. XX
  265. XXREQ_MASK    EQU    STMSG or STCD or STIO
  266. XXREQ_DATAOUT    EQU    000h        ;Data Out Phase
  267. XXREQ_DATAIN    EQU    STIO        ;Data In Phase
  268. XXREQ_CMDOUT    EQU    STCD        ;Command Out Phase
  269. XXREQ_STATIN    EQU    STCD or STIO    ;Status In Phase
  270. XXREQ_MSGOUT    EQU    STMSG or STCD    ;Msg Out Phase
  271. XXREQ_MSGIN    EQU    STMSG or STCD or STIO    ;Msg In Phase
  272. XX
  273. XXCOK        EQU    0        ;Command Completed OK
  274. XXCNOCONNECT    EQU    1        ;Unable to Connect to Target
  275. XXCBUSBUSY    EQU    2        ;Bus Busy
  276. XXCTIMEOUT    EQU    3        ;Timeout waiting for Response
  277. XXCERROR        EQU    4        ;Target Return Error
  278. XXCBUSY        EQU    5        ;Target was Busy
  279. XXCDISCONNECT    EQU    6        ;Target Disconnected
  280. XX
  281. XXSCSI_TESTREADY    EQU    000h        ;Test Unit Ready (6 byte)
  282. XXSCSI_REQSENSE    EQU    003h        ;Request Sense (6 byte)
  283. XXSCSI_FORMATUNIT    EQU    004h        ;Format Disk (6 byte)
  284. XXSCSI_WRITEFM    EQU    010h        ;Write File Marks (6 byte)
  285. XXSCSI_INQUIRY    EQU    012h        ;Inquire (6 byte)
  286. XXSCSI_MODE_SET    EQU    015h        ;Mode Select (6 byte)
  287. XXSCSI_ERASE    EQU    019h        ;Erase Tape (6 byte)
  288. XXSCSI_MODE_GET    EQU    01Ah        ;Mode Sense (6 byte)
  289. XXSCSI_LOAD    EQU    01Bh        ;Load / Unload Tape (6 byte)
  290. XXSCSI_READSIZE    EQU    025h        ;Read Drive Capacity (10 byte)
  291. XX        if extended_io
  292. XXSCSI_READBLK    EQU    028h        ;Read Sectors (10 byte)
  293. XXSCSI_WRITEBLK    EQU    02Ah        ;Write Sectors (10 byte)
  294. XX        else
  295. XXSCSI_READBLK    EQU    008h        ;Read Sectors (6 byte)
  296. XXSCSI_WRITEBLK    EQU    00Ah        ;Write Sectors (6 byte)
  297. XX        endif
  298. XXSCSI_VERIFYBLK    EQU    02Fh        ;Verify Blocks (10 byte)
  299. XX
  300. XXMSG_COMPLETE    EQU    000h        ;Command is Complete
  301. XXMSG_SAVE    EQU    002h        ;Save Data Pointers
  302. XXMSG_RESTORE    EQU    003h        ;Restore Data Pointers
  303. XXMSG_ERROR    EQU    005h        ;Error Detected
  304. XXMSG_ABORT    EQU    006h        ;Abort the Command
  305. XXMSG_REJECT    EQU    007h        ;Reject the Command
  306. XXMSG_NOP        EQU    008h        ;No Operation
  307. XXMSG_IDENTIFY    EQU    080h        ;Identify Yourself
  308. XX
  309. XXLOAD_TAPE    EQU    001h        ;Load
  310. XXUNLOAD_TAPE    EQU    000h        ;Unload
  311. SHAR_EOF
  312. echo shar: a missing newline was added to "'equ.inc'"
  313. if test 3726 -ne "`wc -c < 'equ.inc'`"
  314. then
  315. echo shar: error transmitting "'equ.inc'" '(should have been 3726 characters)'
  316. fi
  317. fi # end of overwriting check
  318. echo shar: extracting "'ioctl.asm'" '(2148 characters)'
  319. if test -f 'ioctl.asm'
  320. then
  321. echo shar: will not over-write existing file "'ioctl.asm'"
  322. else
  323. sed 's/^XX//' > 'ioctl.asm' << \SHAR_EOF
  324. XX;
  325. XX; Process an ioctl request for the current unit
  326. XX;
  327. XX; return 'C' on error
  328. XX;
  329. XXscsi_ioctl    proc
  330. XX        mov    al,es:[bx].rh19_minor        ;Get the minor number
  331. XX
  332. XX        cmp    al,40h                ;Set Device Params?
  333. XX        jnz    scsi_i_42h
  334. XX        clc
  335. XX        jmp    short scsi_i_exit
  336. XX
  337. XXscsi_i_42h:    cmp    al,42h                ;Format and Verify?
  338. XX        jnz    scsi_i_60h
  339. XX        call    scsi_verify
  340. XX        jmp    short scsi_i_exit
  341. XX
  342. XXscsi_i_60h:    cmp    al,60h                ;Get Device Params?
  343. XX        jnz    scsi_i_62h
  344. XX        mov    si,cur_bpb            ;Get the Current BPB
  345. XX        mov    di,es:[bx].rh19_buf_ofs        ;Get the Param Buffer
  346. XX        mov    ax,es:[bx].rh19_buf_seg
  347. XX        mov    es,ax
  348. XX        mov    es:[di].dpb_special,05h        ;Sect Same/Use Cur BPB
  349. XX        mov    es:[di].dpb_type,05h        ;Fixed Disk
  350. XX        mov    es:[di].dpb_attr,0001h        ;Not Removable
  351. XX        mov    ax,[si].bpb_ts
  352. XX        shr    ax,SECT_2_CYL            ;Convert Sect to Cyl
  353. XX        mov    es:[di].dpb_cyl,ax
  354. XX        mov    es:[di].dpb_media,0        ;????
  355. XX        mov    es:[di].dpb_sectors,SECT_TRACK    ;Sectors per Track
  356. XX
  357. XX        push    di
  358. XX        lea    di,es:[di].dpb_bpb        ;Copy the bpb into
  359. XX        mov    cx,size bpb            ;the requestors buffer
  360. XX        cld
  361. XX    rep    movsb
  362. XX        pop    di
  363. XX
  364. XX        lea    di,es:[di].dpb_track        ;Build the Track List
  365. XX        mov    cx,SECT_TRACK
  366. XX        mov    ax,0                ;Start with Sector 0
  367. XXscsi_i_t_loop:    mov    es:[di],ax            ;Sector Number
  368. XX        inc    ax
  369. XX        inc    di
  370. XX        inc    di
  371. XX        mov    word ptr es:[di],P_SECT        ;Sector Size
  372. XX        inc    di
  373. XX        inc    di
  374. XX        loop    scsi_i_t_loop
  375. XX        clc
  376. XX        jmp    short scsi_i_exit
  377. XX
  378. XXscsi_i_62h:    cmp    al,62h                ;Verify?
  379. XX        jnz    scsi_i_error
  380. XX        call    scsi_verify
  381. XX        jmp    short scsi_i_exit
  382. XX
  383. XXscsi_i_error:    stc
  384. XXscsi_i_exit:    ret
  385. XXscsi_ioctl    endp
  386. XX
  387. XX;
  388. XX; Process an ioctl_write request
  389. XX;
  390. XXscsi_ioctl_write proc
  391. XX        mov    di,es:[bx].rh12_buf_ofs        ;Get The Command
  392. XX        mov    ax,es:[bx].rh12_buf_seg        ;Buffer
  393. XX        mov    es,ax
  394. XX        mov    ax,es:[di].ioc_command        ;What Command
  395. XX
  396. XX;
  397. XX; Format Disk Unit
  398. XX;
  399. XX        cmp    al,'F'                ;Format?
  400. XX        jnz    try_erase
  401. XX        mov    ax,es:[di].ioc_param        ;Get Interleave
  402. XX        lea    di,cmd_format            ;Insert into Command
  403. XX        mov    [di].fmt_cmd_il_b0,al
  404. XX        mov    [di].fmt_cmd_il_b1,ah
  405. XX        call    docmd
  406. XX        jnc    scsi_i_w_exit
  407. XX        call    scsi_sense
  408. XX        jmp    scsi_i_w_exit
  409. XX
  410. XX;
  411. XX; Erase Tape Unit
  412. XX;
  413. XXtry_erase:    cmp    al,'E'                ;Erase?
  414. XX        jnz    scsi_i_w_error
  415. XX        lea    di,cmd_erase            ;Now Erase Tape
  416. XX        call    docmd
  417. XX        jnc    scsi_i_w_exit
  418. XX        call    scsi_sense
  419. XX        jmp    scsi_i_w_error
  420. XX
  421. XXscsi_i_w_error:    stc
  422. XXscsi_i_w_exit:    ret
  423. XXscsi_ioctl_write endp
  424. SHAR_EOF
  425. if test 2148 -ne "`wc -c < 'ioctl.asm'`"
  426. then
  427. echo shar: error transmitting "'ioctl.asm'" '(should have been 2148 characters)'
  428. fi
  429. fi # end of overwriting check
  430. echo shar: extracting "'kludge.asm'" '(2417 characters)'
  431. if test -f 'kludge.asm'
  432. then
  433. echo shar: will not over-write existing file "'kludge.asm'"
  434. else
  435. sed 's/^XX//' > 'kludge.asm' << \SHAR_EOF
  436. XX;
  437. XX; This code is needed because DOS insists on opening a char device
  438. XX; in cooked mode.  The problem is that without adding code to every
  439. XX; application that would ever use us, we have no way to alter this
  440. XX; because the use of O_BINARY or setmode() do not affect char devices.
  441. XX;
  442. XX; The solution (kludge) is to watch open requests issued thru the
  443. XX; INT 21 vector.  If we see a open request followed by a OPEN_DEV
  444. XX; call to us, it must have been an open for us.  So during the return,
  445. XX; force a call to the ioctl facility that will switch to raw mode.
  446. XX;
  447. XX
  448. XX;
  449. XX; The Original INT 21 Vector
  450. XX;
  451. XXvect_int_21    equ    word ptr 4 * 21h
  452. XXorig_int_21    dd    ?            ;Original INT 21 Vector
  453. XX
  454. XX;
  455. XX; OPEN_DEV flag is TRUE when we are opened
  456. XX;
  457. XXopened_flag    db    FALSE
  458. XX
  459. XXpatch_us_in    proc    near
  460. XX        push    es
  461. XX        push    ax
  462. XX        mov    ax,0            ;Patch Ourselves into
  463. XX        mov    es,ax            ;the INT 21 Vector
  464. XX        mov    ax,es:[vect_int_21]    ;Offset
  465. XX        mov    word ptr orig_int_21,ax
  466. XX        lea    ax,our_int_21
  467. XX        mov    es:[vect_int_21],ax
  468. XX        mov    ax,es:[vect_int_21+2]    ;Segment
  469. XX        mov    word ptr orig_int_21+2,ax
  470. XX        mov    ax,cs
  471. XX        mov    es:[vect_int_21+2],ax
  472. XX        pop    ax
  473. XX        pop    es
  474. XX        ret
  475. XXpatch_us_in    endp
  476. XX
  477. XXour_int_21    proc    far
  478. XX        pushf                ;Save entry flags
  479. XX        cmp    ah,3Dh            ;Is it an open request?
  480. XX        jnz    not_open_req
  481. XX        popf                ;Restore entry flags
  482. XX;
  483. XX; We need to set things up so the 'iret' done by the INT 21
  484. XX; code will have some the right stuff on the stack.
  485. XX; #1 Flags with interrupts enabled
  486. XX; #2 Return Address
  487. XX;
  488. XX        sti                ;Allow interrupts
  489. XX        pushf                ;After the iret
  490. XX        cli                ;Shut interrupts off
  491. XX        call    cs:orig_int_21        ;While we Pass the request on
  492. XX;
  493. XX; Upon return, interrupts are enabled, so shut them off while we work
  494. XX;
  495. XX        pushf
  496. XX        cli
  497. XX        cmp    cs:opened_flag,FALSE    ;Was it an open for us?
  498. XX        jz    not_our_open
  499. XX        mov    cs:opened_flag,FALSE    ;Clear for next time
  500. XX;
  501. XX; We need to forge a call to the ioctl interface
  502. XX; to switch DOS to raw mode when it talks to us
  503. XX;
  504. XX        pusha
  505. XX        mov    bx,ax            ;Save the Handle
  506. XX        mov    ax,4400h        ;Get Device Information
  507. XX        pushf
  508. XX        call    cs:orig_int_21
  509. XX        mov    dh,0            ;Setup
  510. XX        or    dl,20h            ;for RAW Mode
  511. XX        mov    ax,4401h        ;Set Device Information
  512. XX        pushf
  513. XX        call    cs:orig_int_21
  514. XX        popa
  515. XX
  516. XXnot_our_open:    popf                ;The Original Flags to return
  517. XX;
  518. XX; When we return, we need to pop the flags that the original INT 21
  519. XX; call left on the stack, and return the flags we got back
  520. XX;
  521. XX        ret    2            ;Return and discard flags
  522. XX
  523. XXnot_open_req:    popf                ;Pop the saved flags
  524. XX        jmp    cs:orig_int_21        ;Continue with original code
  525. XXour_int_21    endp
  526. SHAR_EOF
  527. if test 2417 -ne "`wc -c < 'kludge.asm'`"
  528. then
  529. echo shar: error transmitting "'kludge.asm'" '(should have been 2417 characters)'
  530. fi
  531. fi # end of overwriting check
  532. echo shar: extracting "'makefile'" '(526 characters)'
  533. if test -f 'makefile'
  534. then
  535. echo shar: will not over-write existing file "'makefile'"
  536. else
  537. sed 's/^XX//' > 'makefile' << \SHAR_EOF
  538. XX#
  539. XX# SCSI Stuff
  540. XX#
  541. XXSRCS = scsi.asm subs.asm ioctl.asm dump.asm units.asm kludge.asm \
  542. XX       options.inc equ.inc struct.inc
  543. XX
  544. XXall: scsi.sys sformat.exe serase.exe
  545. XX
  546. XX#
  547. XX# SCSI Disk Device Driver
  548. XX#
  549. XXscsi.sys: scsi.obj
  550. XX    link +scsi.obj, scsi ;
  551. XX    exe2bin scsi.exe scsi.sys
  552. XX
  553. XXscsi.obj: $(SRCS)
  554. XX    masm scsi.asm scsi.obj scsi.lst ;
  555. XX
  556. XX#
  557. XX# SCSI Disk Formatter
  558. XX#
  559. XXsformat.exe: sformat.c
  560. XX    cl -G2 -Ox -o sformat.exe sformat.c
  561. XX
  562. XX#
  563. XX# SCSI Tape Erase
  564. XX#
  565. XXserase.exe: serase.c
  566. XX    cl -G2 -Ox -o serase.exe serase.c
  567. XX
  568. XX#
  569. XX# clean
  570. XX#
  571. XXclean:
  572. XX    rm -f *.exe *.obj *.lst
  573. SHAR_EOF
  574. if test 526 -ne "`wc -c < 'makefile'`"
  575. then
  576. echo shar: error transmitting "'makefile'" '(should have been 526 characters)'
  577. fi
  578. fi # end of overwriting check
  579. echo shar: extracting "'options.inc'" '(1165 characters)'
  580. if test -f 'options.inc'
  581. then
  582. echo shar: will not over-write existing file "'options.inc'"
  583. else
  584. sed 's/^XX//' > 'options.inc' << \SHAR_EOF
  585. XX;
  586. XX; Allow multi_sector reads and writes.
  587. XX;
  588. XX; This means that a read request of less then CHUNK_MAX
  589. XX; sectors will be done in one request to the drive rather
  590. XX; then multiple single sector requests.
  591. XX;
  592. XX; The disadvantage here is that the code in receive_data()
  593. XX; and send_data() must keep the transfer from exceding the
  594. XX; 512 byte buffer on the ST-01 card.
  595. XX;
  596. XXmulti_sector    =    1    ;Enable multi_sector support
  597. XX
  598. XX;
  599. XX; Use the extended SCSI commands for reads and writes.
  600. XX;
  601. XX; This means that we can access drives larger then 1Gb
  602. XX; and read/write more then 256 sectors per command.
  603. XX;
  604. XX; The disadvantage here is that not all devices support
  605. XX; the extended command set.
  606. XX;
  607. XXextended_io    =    0    ;Disable use of extended io commands
  608. XX
  609. XX;
  610. XX; Use parity on the SCSI bus
  611. XX;
  612. XXscsi_parity    =    1    ;Enable use of parity on the SCSI bus
  613. XX
  614. XX;
  615. XX; Reserve SCSI Address 7 for card
  616. XX;
  617. XXreserve_addr    =    1    ;Reserve Address for Card Use
  618. XX
  619. XX;
  620. XX; Dump Sense information to the screen
  621. XX;
  622. XXdump_sense    =    1    ;Dump Sense Message to the Screen
  623. XX
  624. XX;
  625. XX; Extended Sense or Normal Sense
  626. XX;
  627. XXextended_sense    =    1    ;Request Extended Sense
  628. XX
  629. XX;
  630. XX; Include the code to kludge the RAW ioctl call after an open
  631. XX;
  632. XXuse_kludge    =    1    ;Enable the ioctl kludge
  633. SHAR_EOF
  634. if test 1165 -ne "`wc -c < 'options.inc'`"
  635. then
  636. echo shar: error transmitting "'options.inc'" '(should have been 1165 characters)'
  637. fi
  638. fi # end of overwriting check
  639. echo shar: extracting "'readme.10'" '(2706 characters)'
  640. if test -f 'readme.10'
  641. then
  642. echo shar: will not over-write existing file "'readme.10'"
  643. else
  644. sed 's/^XX//' > 'readme.10' << \SHAR_EOF
  645. XXScsi Version 1.0
  646. XX
  647. XX     The code you received with this file is a very simple SCSI device
  648. XXdriver that uses the Seagate ST-01 interface card.  As this driver is
  649. XXmy first PC assembler project other then "hello world", please don't
  650. XXsnicker to loudly.
  651. XX
  652. XX     The package includes the source for a device driver that will scan
  653. XXthe SCSI bus for disk drives and partition any drives found into chunks
  654. XXof 32Meg plus any leftovers.  As soon as I discover a way to get DOS to
  655. XXlet me use > 512 byte sectors, It will just allocate the entire disk to
  656. XXa single logical drive.  It also includes a utility to access the low
  657. XXlevel SCSI format function for any disk found.  You may specify the
  658. XXinterleave when the low level format is done and the version of the
  659. XXdriver here seems to work fine at 1:1 with my 8Mhz NEC.
  660. XX
  661. XX     Some of the things to look out for are:
  662. XX
  663. XX#1 The receive_data and send_data functions in subs.asm use polled I/O
  664. XX   to transfer data to/from the card.  I would have loved to just use
  665. XX   the I/O Channel Ready line that the card is suppose to support, but
  666. XX   my NEC does not seem to use that line.  Hence the polling of the REQ
  667. XX   bit in the status port.
  668. XX
  669. XX#2 I did not know how to do clock speed independent timing loops, so there
  670. XX   is a wait100us function in subs.asm that is very processor speed
  671. XX   dependent :-(
  672. XX
  673. XX#3 In ioctl.asm there is a commented out call to scsi_verify.  This is
  674. XX   used by the DOS format utility to scan for errors.  You may want to
  675. XX   enable the call after you get everything setup.  I shut it off while
  676. XX   I was testing as I didn't want to wait for the verify everytime I
  677. XX   changed the interleave.
  678. XX
  679. XX     To bring up the driver.  Assemble and link scsi.sys and add it to
  680. XXyour config.sys file.  After rebooting, you may optionaly do a low level
  681. XXformat of each disk found using sformat.exe.  You then use the DOS format
  682. XXutility on each logical drive.  I did figure out just what format needed
  683. XXin the way of ioctl support to get it to do the high level format for me.
  684. XXAt this point you should have fully functional DOS drives.  In testing
  685. XXI found that with multi_sector support (subs.asm) enabled, the SCSI drives
  686. XXwere just about as fast as the ST-412 C: that came with the machine.  I
  687. XXam sure that the speed problem is basic to the inner loop of the data
  688. XXtransfer routines, but I'm at a loss to figure out how to speed it up.
  689. XX
  690. XX     Anyway, maybe someone can find some use for the code.  I got the
  691. XXcard for free, so I can't really complain about the speed or cost too
  692. XXmuch :-)
  693. XX
  694. XX     Also thanks to the people that sent me samples of other device drivers
  695. XXfor the PC.  I lost the names to a disk crash, but here is the result of
  696. XXyour help and my thanks.
  697. XX
  698. XXBrian Antoine
  699. XXAug 29, 1990
  700. SHAR_EOF
  701. if test 2706 -ne "`wc -c < 'readme.10'`"
  702. then
  703. echo shar: error transmitting "'readme.10'" '(should have been 2706 characters)'
  704. fi
  705. fi # end of overwriting check
  706. echo shar: extracting "'readme.11'" '(2983 characters)'
  707. if test -f 'readme.11'
  708. then
  709. echo shar: will not over-write existing file "'readme.11'"
  710. else
  711. sed 's/^XX//' > 'readme.11' << \SHAR_EOF
  712. XXScsi Version 1.1
  713. XX
  714. XX     This version of the driver add support for a single tape drive, and
  715. XXcleans up some of the code a little.  It also adds a file that has equates
  716. XXto customize some of the major areas of the driver.
  717. XX
  718. XX     When the driver is initialized it does a scan of the SCSI bus for
  719. XXdevices.  The FIRST tape device found is assigned to a char device with the
  720. XXname "SCSITAPE".  If no tape drive is found, the char device is still valid
  721. XXbut will generate a "bad unit" error when accessed.
  722. XX
  723. XX     The SCSITAPE device expects reads and writes to be done in some variation
  724. XXof 512 bytes.  I/O done where (size mod 512) is non-zero will generate an
  725. XXerror.  Tape access must be done in RAW mode, and this is where I had to
  726. XXsome code in the driver that I'm not sure is very pretty.  The problem is
  727. XXthat DOS insists on opening char devices in cooked mode.  It does give you
  728. XXthe ability to switch to RAW mode, but only by using 'intdos()' to access
  729. XXthe ioctl interface.  The MSC 'setmode()' call for binary will not effect
  730. XXchar devices, nor will opening the file with O_BINARY.  So I had two choices.
  731. XXI could modify every program that expected to talk to the tape so that it
  732. XXalso issued the ioctl stuff (see binmode.c), or I could kludge the driver
  733. XXto issue the required calls.
  734. XX
  735. XX     In the end, I punted and did both.  The code in binmode.c is the function
  736. XXthat along with 'setmode()', will make sure that ANYTHING you open is accessed
  737. XXin RAW mode.  Simply check for any call to 'setmode()' that is switching to
  738. XXO_BINARY, and add another call to 'binmode()'.  This assumes that you have
  739. XXthe source to the utility in question.  For those who are don't mind a little
  740. XXkludge amount friends.  The file options.inc has an equate called 'use_kludge'
  741. XXthat when enabled turns on some code in kludge.asm.  This code links into the
  742. XXINT 21h vector and waits for a DOS open request to go by.  When it sees an
  743. XXopen request, it 'calls' rather then 'jmps' to the normal vector.  This allows
  744. XXthe driver to get the 'handle' returned by DOS.  Because the SCSITAPE device
  745. XXenables the driver_open function, I can tell from the fact that an open is
  746. XXin progress and wether the driver just got an open request, wether any
  747. XXparticular open was for me.  When the open was in fact for the SCSITAPE device,
  748. XXI take the 'handle' returned by DOS and forge the required ioctl calls to
  749. XXswitch to RAW mode.
  750. XX
  751. XX     With the addition of tape support.  I now use GNU Tar to swap tapes with
  752. XXmy normal UN*X system at work.  The driver works well enough that I have yet
  753. XXto have a format problem with the different systems.  It is also a lot faster
  754. XXwhen doing backups on the PC.  Using 'fastback' I would get about 1 Meg a
  755. XXminute thruput on my 8 Mhz AT.  Using GNU Tar and the SCSITAPE device I get
  756. XX> 2.5 Meg a minute to the tape and don't have to swap disks quite so often :-)
  757. XX
  758. XX     Anyway, I hope that someone out there actually gets some use out of this
  759. XXcode.  It has been a real adventure for me.
  760. XX
  761. XXBrian Antoine
  762. XXSept 8, 1990
  763. SHAR_EOF
  764. if test 2983 -ne "`wc -c < 'readme.11'`"
  765. then
  766. echo shar: error transmitting "'readme.11'" '(should have been 2983 characters)'
  767. fi
  768. fi # end of overwriting check
  769. echo shar: extracting "'scsi.asm'" '(11664 characters)'
  770. if test -f 'scsi.asm'
  771. then
  772. echo shar: will not over-write existing file "'scsi.asm'"
  773. else
  774. sed 's/^XX//' > 'scsi.asm' << \SHAR_EOF
  775. XX;
  776. XX; Simple SCSI Device Driver
  777. XX;
  778. XX        .286
  779. XX        PAGE    76,132
  780. XX
  781. XX        INCLUDE    options.inc
  782. XX        INCLUDE    equ.inc
  783. XX        INCLUDE    struct.inc
  784. XX;
  785. XX; Start of Code and Data
  786. XX;
  787. XX_TEXT        segment    word public 'CODE'
  788. XX        assume    cs:_TEXT, ds:_TEXT, es:_TEXT
  789. XX
  790. XX        org    0
  791. XX
  792. XX;
  793. XX; Device Header Required By DOS
  794. XX;
  795. XXscsi:
  796. XXtape_link_ofs    dw    disk_link_ofs    ;Forward Link
  797. XXtape_link_seg    dw    -1
  798. XX        dw    0C800h        ;Char Device
  799. XX        dw    tape_strategy    ;Address of 1st DOS Call
  800. XX        dw    dev_interrupt    ;Address of 2nd DOS Call
  801. XX        db    'SCSITAPE'    ;Device Name
  802. XX
  803. XXdisk_link_ofs    dw    -1        ;Forward Link
  804. XXdisk_link_seg    dw    -1
  805. XX        dw    06040h        ;Ioctl R/W, Block Device, Non-IBM, Get/Set
  806. XX        dw    disk_strategy    ;Address of 1st DOS Call
  807. XX        dw    dev_interrupt    ;Address of 2nd DOS Call
  808. XXdisk_count    db    0        ;Number of Disks Present
  809. XX        db    7 dup(?)
  810. XX
  811. XX;
  812. XX; Work Space For Our Device Driver
  813. XX;
  814. XX        even
  815. XXrh_off        dw    ?        ;Request Header Offset
  816. XXrh_seg        dw    ?        ;Request Header Segment
  817. XXrh_type        db    ?        ;Request Type
  818. XX
  819. XXwrite_flag    db    FALSE        ;TRUE When Tape Write Seen
  820. XXcur_drive    db    -1
  821. XXvol_id        db    'NO NAME    ',0
  822. XX
  823. XX;
  824. XX; Define our own personal Stack
  825. XX;
  826. XX        even
  827. XXnew_stack    db    STACK_SIZE-2 dup (?)    ;Our Local Stack
  828. XXnew_stack_top    dw    ?
  829. XX
  830. XXstack_ptr    dw    ?            ;Old Stack Pointer
  831. XXstack_seg    dw    ?            ;Old Stack Segment
  832. XX
  833. XX;
  834. XX; Command Table
  835. XX;
  836. XXcmdtab        label    byte        ;* = Char Only Devices
  837. XX        dw    INITIALIZATION    ;Initialization
  838. XX        dw    MEDIA_CHECK    ;Media Check (Block Only)
  839. XX        dw    GET_BPB        ;Build BPB (Block Only)
  840. XX        dw    unknown        ;IOCTL Read
  841. XX        dw    READ        ;Read Data
  842. XX        dw    done        ;*Non Destructive Read
  843. XX        dw    done        ;*Read Status
  844. XX        dw    done        ;*Flush Read Buffer
  845. XX        dw    WRITE        ;Write Data
  846. XX        dw    WRITE_VERIFY    ;Write With Verify
  847. XX        dw    done        ;*Write Status
  848. XX        dw    done        ;*Flush Write Buffer
  849. XX        dw    WRITE_IOCTL    ;IOCTL Write
  850. XX        dw    OPEN_DEV    ;Device Open
  851. XX        dw    CLOSE_DEV    ;Device Close
  852. XX        dw    done        ;Removable Check
  853. XX        dw    unknown        ;*Write Until Busy
  854. XX        dw    unknown        ;Unknown Call
  855. XX        dw    unknown        ;Unknown Call
  856. XX        dw    IOCTL        ;Generic Ioctl
  857. XX        dw    unknown        ;Unknown Call
  858. XX        dw    unknown        ;Unknown Call
  859. XX        dw    unknown        ;Unknown Call
  860. XX        dw    GET_DEV        ;Get Device
  861. XX        dw    SET_DEV        ;Set Device
  862. XX
  863. XXreq_msg        db    0dh,'Request: '
  864. XXreq_msg_type    db    'xx, Count: '
  865. XXreq_msg_count    db    'xxxx, Start: '
  866. XXreq_msg_start    db    'xxxx',0dh,0ah,'$'
  867. XX
  868. XX;
  869. XX; Strategy Procedure
  870. XX;
  871. XXdisk_strategy    proc    far
  872. XX        mov    cs:rh_seg,es        ;Save Request Header Ptr Segment
  873. XX        mov    cs:rh_off,bx        ;Save Request Header Ptr Offset
  874. XX        mov    cs:rh_type,DISK_REQUEST
  875. XX        ret
  876. XXdisk_strategy    endp
  877. XX
  878. XXtape_strategy    proc    far
  879. XX        mov    cs:rh_seg,es        ;Save Request Header Ptr Segment
  880. XX        mov    cs:rh_off,bx        ;Save Request Header Ptr Offset
  881. XX        mov    cs:rh_type,TAPE_REQUEST
  882. XX        ret
  883. XXtape_strategy    endp
  884. XX
  885. XX;
  886. XX; Interrupt Procedure
  887. XX;
  888. XXdev_interrupt    proc    far
  889. XX        cli                ;Save Machine State On Entry
  890. XX        push    ds
  891. XX        push    es
  892. XX        push    ax
  893. XX        push    bx
  894. XX        push    cx
  895. XX        push    dx
  896. XX        push    si
  897. XX        push    di
  898. XX        push    bp
  899. XX        pushf
  900. XX
  901. XX        mov    cs:stack_seg,ss        ;Save Old Stack
  902. XX        mov    cs:stack_ptr,sp
  903. XX
  904. XX        mov    ax,cs            ;Save us the Segment Override Crap
  905. XX        mov    ds,ax
  906. XX        mov    es,ax
  907. XX
  908. XX        mov    ss,ax            ;Setup Our Local Stack
  909. XX        lea    ax,new_stack_top
  910. XX        mov    sp,ax
  911. XX        sti                ;We're Safe Now
  912. XX
  913. XX;
  914. XX; Perform branch based on the command passed in the Request Header
  915. XX;
  916. XX        mov    es,rh_seg        ;Point us at the Request Header
  917. XX        mov    bx,rh_off
  918. XX
  919. XX;        pusha
  920. XX;        mov    di,bx
  921. XX;        mov    dl,es:[di].rh_cmd    ;Get Command Code
  922. XX;        lea    bx,req_msg_type
  923. XX;        call    hex2asc2
  924. XX;        mov    dx,es:[di].rh4_count
  925. XX;        lea    bx,req_msg_count
  926. XX;        call    hex2asc4
  927. XX;        mov    dx,es:[di].rh4_start
  928. XX;        lea    bx,req_msg_start
  929. XX;        call    hex2asc4
  930. XX;        lea    dx,req_msg
  931. XX;        call    puts
  932. XX;        popa
  933. XX
  934. XX        mov    al,es:[bx].rh_cmd    ;Get Command Code
  935. XX        rol    al,1            ;Get offset into table
  936. XX        lea    di,cmdtab        ;Get address of command table
  937. XX        mov    ah,0            ;Clear hi order byte
  938. XX        add    di,ax            ;Add offset
  939. XX        jmp    word ptr [di]        ;Jump Indirect
  940. XX
  941. XX;
  942. XX; Command Procedures
  943. XX;
  944. XXINITIALIZATION:    cmp    rh_type,TAPE_REQUEST    ;Is this SCSITAPE: Init?
  945. XX        jz    init_skip
  946. XX        mov    al,es:[bx].rh0_drv_ltr    ;Save the starting Drive
  947. XX        add    al,041h
  948. XX        mov    cur_drive,al
  949. XX        call    initial            ;Setup
  950. XX        if use_kludge
  951. XX        call    patch_us_in
  952. XX        endif
  953. XX        mov    bx,rh_off
  954. XX        mov    es,rh_seg
  955. XXinit_skip:    lea    ax,initial        ;Set The Break Address
  956. XX        mov    es:[bx].rh0_brk_ofs,ax
  957. XX        mov    es:[bx].rh0_brk_seg,cs
  958. XX        mov    al,disk_count        ;Number of Disk Devices Supported
  959. XX        mov    es:[bx].rh0_nunits,al
  960. XX        lea    dx,bpb_array        ;BPB Array
  961. XX        mov    es:[bx].rh0_bpb_tbo,dx
  962. XX        mov    es:[bx].rh0_bpb_tbs,cs
  963. XX        jmp    done
  964. XX
  965. XX;
  966. XX; Has the Media Changed
  967. XX;
  968. XXMEDIA_CHECK:    call    find_unit
  969. XX        jc    mc_jmp_err
  970. XX        mov    di,cur_unit
  971. XX        mov    al,[di].unit_mcheck    ;Get Initial Status
  972. XX        mov    [di].unit_mcheck,1    ;Always OK from then on
  973. XX        mov    es:[bx].rh1_md_stat,al
  974. XX        lea    dx,vol_id        ;Address of Volume ID
  975. XX        mov    es:[bx].rh1_volid_ofs,dx
  976. XX        mov    es:[bx].rh1_volid_seg,cs
  977. XX        jmp    done
  978. XXmc_jmp_err:    jmp    bad_unit
  979. XX
  980. XX;
  981. XX; Get Disk Parameter Block
  982. XX;
  983. XXGET_BPB:    call    find_unit
  984. XX        jc    get_jmp_err
  985. XX        mov    dx,cur_bpb        ;Address of BPB
  986. XX        mov    es:[bx].rh2_pbpbo,dx
  987. XX        mov    es:[bx].rh2_pbpbs,cs
  988. XX        jmp    done
  989. XXget_jmp_err:    jmp    bad_unit
  990. XX
  991. XX;
  992. XX; Read some data from the disk/tape
  993. XX;
  994. XXREAD:        cmp    rh_type,DISK_REQUEST
  995. XX        jz    read_a_disk
  996. XX        mov    ax,tape_unit        ;Do We Have a Tape?
  997. XX        cmp    ax,-1
  998. XX        jz    read_jmp_err1
  999. XX        mov    cur_unit,ax
  1000. XX        call    tape_read
  1001. XX        jc    read_jmp_err2
  1002. XX        jmp    done
  1003. XXread_a_disk:    call    find_unit
  1004. XX        jc    read_jmp_err1
  1005. XX        call    disk_read
  1006. XX        jc    read_jmp_err2
  1007. XX        jmp    done
  1008. XXread_jmp_err1:    jmp    bad_unit
  1009. XXread_jmp_err2:    jmp    bad_read
  1010. XX
  1011. XX;
  1012. XX; Write some data to the disk/tape
  1013. XX;
  1014. XXWRITE        equ    $
  1015. XXWRITE_VERIFY:    cmp    rh_type,DISK_REQUEST
  1016. XX        jz    write_a_disk
  1017. XX        mov    ax,tape_unit        ;Do We Have a Tape?
  1018. XX        cmp    ax,-1
  1019. XX        jz    write_jmp_err1
  1020. XX        mov    cur_unit,ax
  1021. XX        call    tape_write
  1022. XX        jc    write_jmp_err2
  1023. XX        jmp    done
  1024. XXwrite_a_disk:    call    find_unit
  1025. XX        jc    write_jmp_err1
  1026. XX        call    disk_write
  1027. XX        jc    write_jmp_err2
  1028. XX        jmp    done
  1029. XXwrite_jmp_err1:    jmp    bad_unit
  1030. XXwrite_jmp_err2:    jmp    bad_write
  1031. XXwrite_jmp_err3:    jmp    unknown
  1032. XX
  1033. XX;
  1034. XX; Write Ioctl Packet
  1035. XX;
  1036. XXWRITE_IOCTL:    cmp    rh_type,DISK_REQUEST
  1037. XX        jz    ioctl_a_disk
  1038. XX        mov    ax,tape_unit            ;Do we have a SCSITAPE?
  1039. XX        cmp    ax,-1
  1040. XX        jz    write_jmp_err1
  1041. XX        mov    cur_unit,ax
  1042. XX        jmp    short ioctl_do
  1043. XXioctl_a_disk:    call    find_unit
  1044. XX        jc    write_jmp_err1
  1045. XXioctl_do:    call    scsi_ioctl_write
  1046. XX        jc    write_jmp_err3
  1047. XX        jmp    done
  1048. XX
  1049. XX;
  1050. XX; Special Control Functions
  1051. XX;
  1052. XXIOCTL:        call    find_unit
  1053. XX        jc    ioctl_jmp_err1
  1054. XX        call    scsi_ioctl
  1055. XX        jc    ioctl_jmp_err2
  1056. XX        jmp    done
  1057. XXioctl_jmp_err1:    jmp    bad_unit
  1058. XXioctl_jmp_err2:    jmp    unknown
  1059. XX
  1060. XX;
  1061. XX; Open Tape Device
  1062. XX;
  1063. XXOPEN_DEV:    mov    di,tape_unit
  1064. XX        cmp    di,-1        ;Do We have a SCSITAPE: Unit?
  1065. XX        jz    open_err1
  1066. XX        mov    cur_unit,di            ;New Current Unit
  1067. XX        lea    bx,[di].unit_sense_buf        ;Buffer Offset
  1068. XX        push    ds                ;Buffer Segment
  1069. XX        pop    es
  1070. XX        mov    cx,size sense            ;Buffer Size
  1071. XX        lea    di,cmd_sense            ;Command
  1072. XX        call    docmd
  1073. XX        jc    open_err2
  1074. XX        lea    di,cmd_load            ;Now Load Tape
  1075. XX        mov    [di].load_cmd_type,LOAD_TAPE
  1076. XX        call    docmd
  1077. XX        jnc    open_ok
  1078. XX        call    scsi_sense
  1079. XXopen_err2:    jmp    general
  1080. XXopen_err1:    jmp    bad_unit
  1081. XXopen_ok:    mov    opened_flag,TRUE        ;We are open
  1082. XX        mov    write_flag,FALSE        ;No Writes Seen
  1083. XX        jmp    done
  1084. XX
  1085. XX;
  1086. XX; Close Tape Device
  1087. XX;
  1088. XXCLOSE_DEV:    mov    di,tape_unit
  1089. XX        cmp    di,-1        ;Do We have a SCSITAPE: Unit?
  1090. XX        jz    close_err1
  1091. XX        mov    cur_unit,di            ;New Current Unit
  1092. XX        cmp    write_flag,TRUE            ;Were We Writing?
  1093. XX        jnz    tape_no_write
  1094. XX        lea    di,cmd_twritefm            ;End Tape with FM
  1095. XX        call    docmd
  1096. XX        jnc    tape_no_write
  1097. XX        call    scsi_sense
  1098. XXtape_no_write:    lea    di,cmd_load            ;Now Unload Tape
  1099. XX        mov    [di].load_cmd_type,UNLOAD_TAPE
  1100. XX        call    docmd
  1101. XX        jnc    close_jmp
  1102. XX        call    scsi_sense
  1103. XXclose_err2:    jmp    general
  1104. XXclose_err1:    jmp    bad_unit
  1105. XXclose_jmp:    jmp    done
  1106. XX
  1107. XX;
  1108. XX; Get Device Assignment
  1109. XX;
  1110. XXGET_DEV:    mov    es:[bx].rh_unit,0
  1111. XX        jmp    done
  1112. XX
  1113. XX;
  1114. XX; Set Device Assignment
  1115. XX;
  1116. XXSET_DEV:    jmp    done
  1117. XX
  1118. XXbad_unit:    mov    es,rh_seg        ;Point us at the Request Header
  1119. XX        mov    bx,rh_off
  1120. XX        or    es:[bx].rh_status,8001h
  1121. XX        jmp    short done
  1122. XX
  1123. XXunknown:    mov    es,rh_seg        ;Point us at the Request Header
  1124. XX        mov    bx,rh_off
  1125. XX        or    es:[bx].rh_status,8003h
  1126. XX        jmp    short done
  1127. XX
  1128. XXbad_write:    mov    es,rh_seg        ;Point us at the Request Header
  1129. XX        mov    bx,rh_off
  1130. XX        or    es:[bx].rh_status,800Ah
  1131. XX        jmp    short done
  1132. XX
  1133. XXbad_read:    mov    es,rh_seg        ;Point us at the Request Header
  1134. XX        mov    bx,rh_off
  1135. XX        or    es:[bx].rh_status,800Bh
  1136. XX        jmp    short done
  1137. XX
  1138. XXgeneral:    mov    es,rh_seg        ;Point us at the Request Header
  1139. XX        mov    bx,rh_off
  1140. XX        or    es:[bx].rh_status,800Ch
  1141. XX        jmp    short done
  1142. XX
  1143. XXbusy:        mov    es,rh_seg        ;Point us at the Request Header
  1144. XX        mov    bx,rh_off
  1145. XX        or    es:[bx].rh_status,0200h
  1146. XX
  1147. XXdone:        mov    es,rh_seg        ;Point us at the Request Header
  1148. XX        mov    bx,rh_off
  1149. XX        or    es:[bx].rh_status,0100h
  1150. XX
  1151. XX        cli                ;Make sure we're left alone
  1152. XX        mov    ax,cs:stack_seg        ;Restore DOS Stack
  1153. XX        mov    ss,ax
  1154. XX        mov    ax,cs:stack_ptr
  1155. XX        mov    sp,ax
  1156. XX
  1157. XX        popf                ;Restore All Registers
  1158. XX        pop    bp
  1159. XX        pop    di
  1160. XX        pop    si
  1161. XX        pop    dx
  1162. XX        pop    cx
  1163. XX        pop    bx
  1164. XX        pop    ax
  1165. XX        pop    es
  1166. XX        pop    ds
  1167. XX        sti                ;We're Safe Now
  1168. XX        ret
  1169. XX
  1170. XX        INCLUDE    units.asm
  1171. XX        INCLUDE    subs.asm
  1172. XX        INCLUDE    ioctl.asm
  1173. XX        INCLUDE    dump.asm
  1174. XX        if use_kludge
  1175. XX        INCLUDE    kludge.asm
  1176. XX        endif
  1177. XX
  1178. XX;
  1179. XX; End of Program
  1180. XX; Stuff Placed Here Gets Handed Back To DOS For Re-use
  1181. XX;
  1182. XXinitial        proc    near
  1183. XX        lea    dx,hello_msg        ;Tell them the driver version
  1184. XX        call    puts
  1185. XX        push    cs
  1186. XX        pop    dx
  1187. XX        lea    bx,seg_msg_value
  1188. XX        call    hex2asc4
  1189. XX        lea    dx,seg_msg        ;And Were We Loaded
  1190. XX        call    puts
  1191. XX
  1192. XX        call    scsi_reset        ;Reset the bus
  1193. XX
  1194. XX        mov    cx,0            ;Scan for devices
  1195. XXscan:        mov    ax,cx
  1196. XX        add    al,030h
  1197. XX        mov    scan_dev,al
  1198. XX        mov    ax,1            ;Create Select Bit
  1199. XX        shl    ax,cl
  1200. XX        if reserve_addr
  1201. XX        or    al,80h            ;Add Card Select Bit
  1202. XX        endif
  1203. XX        mov    di,cur_unit
  1204. XX        mov    [di].unit_select,al
  1205. XX        mov    [di].unit_num_drv,0    ;No Drives to start with
  1206. XX        mov    al,disk_count        ;We will start with
  1207. XX        mov    [di].unit_1st_drv,al    ;Drive Number if any
  1208. XX
  1209. XX        lea    dx,scan_dev        ;Print the device number
  1210. XX        call    puts
  1211. XX        call    scsi_inquire        ;Inquire as to its type
  1212. XX        jnc    scan_inq_ok
  1213. XX        jmp    scan_err
  1214. XX
  1215. XXscan_inq_ok:    mov    di,cur_unit
  1216. XX        lea    dx,[di].unit_inq_buf.inq_manufact
  1217. XX        mov    [di].unit_inq_term,'$'
  1218. XX        mov    al,[di].unit_inq_buf.inq_dev_type
  1219. XX        or    al,al            ;Look at device type
  1220. XX        jz    scan_is_drv
  1221. XX        cmp    tape_unit,-1        ;Do We Already Have A Tape?
  1222. XX        jnz    tape_jmp
  1223. XX        call    puts            ;Make this our SCSITAPE: Unit
  1224. XX        mov    tape_unit,di
  1225. XX        lea    dx,tape_msg
  1226. XXtape_jmp:    jmp    scan_puts
  1227. XX
  1228. XXscan_is_drv:    call    puts            ;Output the Device String
  1229. XX        call    scsi_capacity        ;Inquire as to its size
  1230. XX        lea    dx,err_size
  1231. XX        jc    scan_puts        ;Do not use unknown drives
  1232. XX        lea    dx,crlf
  1233. XX        call    puts
  1234. XX
  1235. XXscan_next_drv:    mov    di,cur_unit
  1236. XX        mov    al,disk_count        ;Number Of Drives Found
  1237. XX        inc    al
  1238. XX        mov    disk_count,al
  1239. XX        mov    al,[di].unit_num_drv    ;We have a valid Drive
  1240. XX        inc    al
  1241. XX        mov    [di].unit_num_drv,al
  1242. XX        mov    al,cur_drive        ;Get Current Drive Letter
  1243. XX        mov    drv_msg_let,al        ;Insert it in message
  1244. XX        inc    al            ;Bump Drive Letter
  1245. XX        mov    cur_drive,al
  1246. XX        call    make_bpb        ;Setup the BPB for this drive
  1247. XX        mov    di,cur_bpb        ;Current Working BPB
  1248. XX        mov    ax,[di].bpb_ts
  1249. XX        shr    ax,11
  1250. XX        inc    ax
  1251. XX        lea    bx,drv_msg_size
  1252. XX        call    bin_ascii
  1253. XX        mov    bx,bpb_hw_mark        ;Get the BPB High Water Mark
  1254. XX        inc    bx            ;Bump HW Mark for next time
  1255. XX        inc    bx
  1256. XX        mov    ax,[bx]            ;Get the BPB
  1257. XX        mov    cur_bpb,ax        ;Make it the current BPB
  1258. XX        mov    bpb_hw_mark,bx
  1259. XX        lea    dx,drv_msg
  1260. XX        call    puts
  1261. XX        mov    bx,cur_unit
  1262. XX        mov    ah,0
  1263. XX        mov    al,[bx].unit_num_drv    ;Insert Drive Offset
  1264. XX        dec    al            ;Into BPB for this Drive
  1265. XX        mov    [di].bpb_hs_msw,ax
  1266. XX        mov    al,[bx].unit_cap_buf.cap_sectors_b3
  1267. XX        or    al,[bx].unit_cap_buf.cap_sectors_b2
  1268. XX        or    al,[bx].unit_cap_buf.cap_sectors_b1
  1269. XX        or    al,[bx].unit_cap_buf.cap_sectors_b0
  1270. XX        jnz    scan_next_drv        ;Room left for another Drive
  1271. XX        jmp    short scan_next
  1272. XX
  1273. XXscan_err:    lea    dx,no_dev
  1274. XX        cmp    al,CNOCONNECT
  1275. XX        jz    scan_puts
  1276. XX        lea    dx,err_dev
  1277. XXscan_puts:    call    puts
  1278. XX        lea    dx,crlf
  1279. XX        call    puts
  1280. XX
  1281. XXscan_next:    inc    cx
  1282. XX        cmp    cx,MAXUNIT    ;End of devices?
  1283. XX        jg    scan_exit
  1284. XX        mov    bx,cx        ;Bump to next unit
  1285. XX        shl    bx,1
  1286. XX        mov    ax,word ptr unit_array[bx]
  1287. XX        mov    cur_unit,ax
  1288. XX        jmp    scan
  1289. XX
  1290. XXscan_exit:    ret
  1291. XXinitial        endp
  1292. XX
  1293. XX;
  1294. XX; Data Area Used Only During Initialization
  1295. XX;
  1296. XXhello_msg    db    0dh,0ah,'SCSI Device Driver Version 1.1',0Dh,0Ah,'$'
  1297. XXseg_msg        db    'Driver Loaded At Segment '
  1298. XXseg_msg_value    db    '0000',0dh,0ah,'$'
  1299. XXscan_dev    db    'X - ','$'
  1300. XXno_dev        db    '(No Installed Device)$'
  1301. XXerr_dev        db    '(Error On Device)$'
  1302. XXerr_size    db    'unknown size$'
  1303. XXdrv_msg        db    '  - Drive '
  1304. XXdrv_msg_let    db    'X: '
  1305. XXdrv_msg_size    db    'XXXXXX Meg',0dh,0ah,'$'
  1306. XXtape_msg    db    0dh,0ah,'  - Is The SCSITAPE: Device$'
  1307. XXcrlf        db    0dh,0ah,'$'
  1308. XX
  1309. XXdev_interrupt    endp
  1310. XX_TEXT        ends
  1311. XX        end
  1312. SHAR_EOF
  1313. if test 11664 -ne "`wc -c < 'scsi.asm'`"
  1314. then
  1315. echo shar: error transmitting "'scsi.asm'" '(should have been 11664 characters)'
  1316. fi
  1317. fi # end of overwriting check
  1318. echo shar: extracting "'serase.c'" '(1658 characters)'
  1319. if test -f 'serase.c'
  1320. then
  1321. echo shar: will not over-write existing file "'serase.c'"
  1322. else
  1323. sed 's/^XX//' > 'serase.c' << \SHAR_EOF
  1324. XX/*
  1325. XX** SCSI Tape Erase (Low Level)
  1326. XX**
  1327. XX** usage: serase
  1328. XX**
  1329. XX** Revision History:
  1330. XX**
  1331. XX** Version 1.0  09/03/90 Initial Release
  1332. XX**
  1333. XX*/
  1334. XX#include <stdio.h>
  1335. XX#include <fcntl.h>
  1336. XX#include <dos.h>
  1337. XX
  1338. XX#define TRUE (1)
  1339. XX#define FALSE (0)
  1340. XX#define VERSION "serase Version 1.0 BWA"
  1341. XX
  1342. XXextern int _doserrno;
  1343. XX
  1344. XXstruct cmd {
  1345. XX    short command;        /* command type */
  1346. XX    short args;            /* command args */
  1347. XX    short unit;            /* command unit */
  1348. XX    short buf_ofs;        /* buffer offset */
  1349. XX    short buf_seg;        /* buffer segment */
  1350. XX} ioctl_data;
  1351. XXunion REGS inregs, outregs;
  1352. XXstruct SREGS segregs;
  1353. XXint fd;
  1354. XXchar *device = "SCSITAPE";
  1355. XXchar far *cp;
  1356. XX
  1357. XXmain(argc, argv)
  1358. XXint argc;
  1359. XXchar *argv[];
  1360. XX{
  1361. XX    /*
  1362. XX    ** say hello
  1363. XX    */
  1364. XX    puts(VERSION);
  1365. XX    if (argc != 1) usage();
  1366. XX
  1367. XX    /*
  1368. XX    ** verify that this is what the user really wants to do
  1369. XX    */
  1370. XX    printf("Do you really wish to erase the tape\n");
  1371. XX    printf("contained in SCSITAPE unit (y,n)? ");
  1372. XX    fflush(stdout);
  1373. XX    if ( getchar() != 'y' )
  1374. XX    {
  1375. XX        puts("Aborting erase ....");
  1376. XX        exit(1);
  1377. XX    }
  1378. XX
  1379. XX    /*
  1380. XX    ** put together the command
  1381. XX    */
  1382. XX    fd = open(device, O_WRONLY);
  1383. XX    if ( fd < 0 )
  1384. XX    {
  1385. XX        perror(device);
  1386. XX        exit(1);
  1387. XX    }
  1388. XX    inregs.h.ah = 0x44;            /* ioctl */
  1389. XX    inregs.h.al = 0x03;            /* write */
  1390. XX    inregs.x.bx = fd;            /* unit */
  1391. XX    inregs.x.cx = sizeof(struct cmd);
  1392. XX    cp = (char *) &ioctl_data;
  1393. XX    inregs.x.dx = FP_OFF(cp);
  1394. XX    segregs.ds = FP_SEG(cp);
  1395. XX    ioctl_data.command = 'E';
  1396. XX
  1397. XX    /*
  1398. XX    ** start the format
  1399. XX    */
  1400. XX    puts("Now erasing ....");
  1401. XX    puts("Please wait ....");
  1402. XX    intdosx(&inregs, &outregs, &segregs);
  1403. XX
  1404. XX    /*
  1405. XX    ** see what happened
  1406. XX    */
  1407. XX    if ( outregs.x.cflag )
  1408. XX        printf("DOS error %d occured during erase.\n", _doserrno);
  1409. XX    else
  1410. XX        puts("Erasing complete.");
  1411. XX    close(fd);
  1412. XX    exit(0);
  1413. XX}
  1414. XX
  1415. XXusage()
  1416. XX{
  1417. XX    puts("usage: serase");
  1418. XX    exit(1);
  1419. XX}
  1420. SHAR_EOF
  1421. if test 1658 -ne "`wc -c < 'serase.c'`"
  1422. then
  1423. echo shar: error transmitting "'serase.c'" '(should have been 1658 characters)'
  1424. fi
  1425. fi # end of overwriting check
  1426. echo shar: extracting "'sformat.c'" '(1842 characters)'
  1427. if test -f 'sformat.c'
  1428. then
  1429. echo shar: will not over-write existing file "'sformat.c'"
  1430. else
  1431. sed 's/^XX//' > 'sformat.c' << \SHAR_EOF
  1432. XX/*
  1433. XX** SCSI Disk Formatter (Low Level)
  1434. XX**
  1435. XX** usage: sformat drive: [interleave]
  1436. XX**
  1437. XX** Revision History:
  1438. XX**
  1439. XX** Version 1.0  08/03/90 Initial Release
  1440. XX**
  1441. XX** Version 1.1  08/20/90 Add verification message.
  1442. XX*/
  1443. XX#include <stdio.h>
  1444. XX#include <dos.h>
  1445. XX
  1446. XX#define TRUE (1)
  1447. XX#define FALSE (0)
  1448. XX#define VERSION "sformat Version 1.1 BWA"
  1449. XX
  1450. XXextern int _doserrno;
  1451. XX
  1452. XXstruct cmd {
  1453. XX    short command;        /* command type */
  1454. XX    short args;            /* command args */
  1455. XX} ioctl_data;
  1456. XXunion REGS inregs, outregs;
  1457. XXstruct SREGS segregs;
  1458. XXunsigned short interleave = 0;
  1459. XXunsigned char drive;
  1460. XXchar far *cp;
  1461. XX
  1462. XXmain(argc, argv)
  1463. XXint argc;
  1464. XXchar *argv[];
  1465. XX{
  1466. XX    /*
  1467. XX    ** say hello
  1468. XX    */
  1469. XX    puts(VERSION);
  1470. XX
  1471. XX    /*
  1472. XX    ** figure out who to format
  1473. XX    */
  1474. XX    switch (argc)
  1475. XX    {
  1476. XX        case 3:
  1477. XX        interleave = atoi(argv[2]);
  1478. XX        case 2:
  1479. XX        if (argv[1][1] != ':') usage();
  1480. XX        drive = argv[1][0];
  1481. XX        drive = toupper(drive);
  1482. XX        drive -= '@';
  1483. XX        break;
  1484. XX
  1485. XX        default:
  1486. XX        usage();
  1487. XX        break;
  1488. XX    }
  1489. XX
  1490. XX    /*
  1491. XX    ** verify that this is what the user really wants to do
  1492. XX    */
  1493. XX    printf("Do you really wish to format the SCSI\n");
  1494. XX    printf("device that contains drive %c: (y,n)? ", argv[1][0]);
  1495. XX    fflush(stdout);
  1496. XX    if ( getchar() != 'y' )
  1497. XX    {
  1498. XX        puts("Aborting low level format ....");
  1499. XX        exit(1);
  1500. XX    }
  1501. XX
  1502. XX    /*
  1503. XX    ** put together the command
  1504. XX    */
  1505. XX    inregs.h.ah = 0x44;            /* ioctl */
  1506. XX    inregs.h.al = 0x05;            /* write */
  1507. XX    inregs.h.bl = drive;        /* unit */
  1508. XX    inregs.x.cx = sizeof(struct cmd);
  1509. XX    cp = (char *) &ioctl_data;
  1510. XX    inregs.x.dx = FP_OFF(cp);
  1511. XX    segregs.ds = FP_SEG(cp);
  1512. XX    ioctl_data.command = 'F';
  1513. XX    ioctl_data.args = interleave;
  1514. XX
  1515. XX    /*
  1516. XX    ** start the format
  1517. XX    */
  1518. XX    puts("Now formating ....");
  1519. XX    puts("Please wait ....");
  1520. XX    intdosx(&inregs, &outregs, &segregs);
  1521. XX
  1522. XX    /*
  1523. XX    ** see what happened
  1524. XX    */
  1525. XX    if ( outregs.x.cflag )
  1526. XX        printf("DOS error %d occured during format.\n", _doserrno);
  1527. XX    else
  1528. XX        puts("Formating complete.");
  1529. XX    exit(0);
  1530. XX}
  1531. XX
  1532. XXusage()
  1533. XX{
  1534. XX    puts("usage: sformat drive: [interleave]");
  1535. XX    exit(1);
  1536. XX}
  1537. SHAR_EOF
  1538. if test 1842 -ne "`wc -c < 'sformat.c'`"
  1539. then
  1540. echo shar: error transmitting "'sformat.c'" '(should have been 1842 characters)'
  1541. fi
  1542. fi # end of overwriting check
  1543. echo shar: extracting "'struct.inc'" '(6833 characters)'
  1544. if test -f 'struct.inc'
  1545. then
  1546. echo shar: will not over-write existing file "'struct.inc'"
  1547. else
  1548. sed 's/^XX//' > 'struct.inc' << \SHAR_EOF
  1549. XX;
  1550. XX; Structures for SCSI commands
  1551. XX;
  1552. XXio_cmd        struc
  1553. XXio_cmd_op    db    ?        ;Opcode
  1554. XX        if extended_io
  1555. XXio_cmd_lun    db    ?
  1556. XXio_cmd_lba_b3    db    ?        ;Logical Block Address
  1557. XXio_cmd_lba_b2    db    ?
  1558. XXio_cmd_lba_b1    db    ?
  1559. XXio_cmd_lba_b0    db    ?
  1560. XXio_cmd_dummy1    db    ?
  1561. XXio_cmd_cnt_b1    db    ?        ;Block Count
  1562. XXio_cmd_cnt_b0    db    ?
  1563. XXio_cmd_dummy2    db    ?
  1564. XX        else
  1565. XXio_cmd_lba_b2    db    ?        ;Logical Block Address / Lun
  1566. XXio_cmd_lba_b1    db    ?
  1567. XXio_cmd_lba_b0    db    ?
  1568. XXio_cmd_cnt_b0    db    ?        ;Block Count
  1569. XXio_cmd_dummy1    db    ?
  1570. XX        endif
  1571. XXio_cmd        ends
  1572. XX
  1573. XXtio_cmd        struc
  1574. XXtio_cmd_op    db    ?        ;Opcode
  1575. XXtio_cmd_lun    db    ?        ;Lun
  1576. XXtio_cmd_cnt_b2    db    ?        ;Block Count
  1577. XXtio_cmd_cnt_b1    db    ?
  1578. XXtio_cmd_cnt_b0    db    ?
  1579. XXtio_cmd_dummy1    db    ?
  1580. XXtio_cmd        ends
  1581. XX
  1582. XX;
  1583. XX; Format the Unit
  1584. XX;
  1585. XXfmt_cmd        struc
  1586. XXfmt_cmd_op    db    ?        ;Opcode
  1587. XXfmt_cmd_type    db    ?        ;Format Type
  1588. XXfmt_cmd_dummy1    db    ?
  1589. XXfmt_cmd_il_b1    db    ?        ;Interleave (MSB)
  1590. XXfmt_cmd_il_b0    db    ?        ;Interleave (LSB)
  1591. XXfmt_cmd_dummy3    db    ?
  1592. XXfmt_cmd        ends
  1593. XX
  1594. XX;
  1595. XX; Verify Sectors
  1596. XX;
  1597. XXver_cmd        struc
  1598. XXver_cmd_op    db    ?        ;Opcode
  1599. XXver_cmd_lun    db    ?        ;Lun
  1600. XXver_cmd_lba_b3    db    ?        ;Logical Block Address MSB
  1601. XXver_cmd_lba_b2    db    ?
  1602. XXver_cmd_lba_b1    db    ?
  1603. XXver_cmd_lba_b0    db    ?        ;Logical Block Address LSB
  1604. XXver_cmd_dummy1    db    ?
  1605. XXver_cmd_len_b1    db    ?        ;Length MSB
  1606. XXver_cmd_len_b0    db    ?        ;Length LSB
  1607. XXver_cmd_dummy2    db    ?
  1608. XXver_cmd        ends
  1609. XX
  1610. XX;
  1611. XX; Load / Unload a Tape
  1612. XX;
  1613. XXload_cmd    struc
  1614. XXload_cmd_op    db    ?        ;Opcode
  1615. XXload_cmd_lun    db    ?        ;Lun
  1616. XXload_cmd_dummy1    db    2 dup (?)
  1617. XXload_cmd_type    db    ?        ;Load / Unload
  1618. XXload_cmd_dummy2    db    ?
  1619. XXload_cmd    ends
  1620. XX
  1621. XX;
  1622. XX; Structure returned by the sense command
  1623. XX;
  1624. XXsense        struc
  1625. XX        if extended_sense
  1626. XXsense_ccs    db    ?        ;0x70 for Extended Sense
  1627. XXsense_dummy1    db    ?
  1628. XXsense_sense    db    ?        ;Sense (Error) Group
  1629. XXsense_lba_b3    db    ?        ;Failed Block Address
  1630. XXsense_lba_b2    db    ?
  1631. XXsense_lba_b1    db    ?
  1632. XXsense_lba_b0    db    ?
  1633. XX        else
  1634. XXsense_sense    db    ?        ;Sense (Error) code
  1635. XXsense_lba_b2    db    ?        ;Failed Block Address
  1636. XXsense_lba_b1    db    ?
  1637. XXsense_lba_b0    db    ?
  1638. XX        endif
  1639. XXsense        ends
  1640. XX
  1641. XX;
  1642. XX; Structure returned by the unit inquiry command
  1643. XX;
  1644. XXinq        struc
  1645. XXinq_dev_type    db    ?        ;Device Type
  1646. XXinq_dev_qual    db    ?        ;Device Qualifier
  1647. XXinq_stand_rev    db    ?        ;Standard Revision Level
  1648. XXinq_format    db    ?        ;Response Format
  1649. XXinq_length    db    ?        ;Length of Extra Data
  1650. XXinq_reserv1    db    ?
  1651. XXinq_reserv2    db    ?
  1652. XXinq_reserv3    db    ?
  1653. XXinq_manufact    db    8 dup (?)    ;Manufacture
  1654. XXinq_product    db    16 dup (?)    ;Product
  1655. XXinq        ends
  1656. XX
  1657. XX;
  1658. XX; Structure returned by the read drive capacity command
  1659. XX;
  1660. XXcap        struc
  1661. XXcap_sectors_b3    db    ?        ;MSB of sector count
  1662. XXcap_sectors_b2    db    ?
  1663. XXcap_sectors_b1    db    ?
  1664. XXcap_sectors_b0    db    ?        ;LSB of sector count
  1665. XXcap_size_b3    db    ?        ;MSB of sector size
  1666. XXcap_size_b2    db    ?
  1667. XXcap_size_b1    db    ?
  1668. XXcap_size_b0    db    ?        ;LSB of sector size
  1669. XXcap        ends
  1670. XX
  1671. XX;
  1672. XX; Structure Definitions For Our Device Driver
  1673. XX;
  1674. XXbpb        struc
  1675. XXbpb_ss        dw    ?        ;Sector Size
  1676. XXbpb_au        db    ?        ;Cluster Size in Sectors
  1677. XXbpb_rs        dw    ?        ;Reserved Sectors
  1678. XXbpb_nf        db    ?        ;Number of Fats
  1679. XXbpb_de        dw    ?        ;Number of Root Directory Entries
  1680. XXbpb_ts        dw    ?        ;Total Number Of Sectors
  1681. XXbpb_md        db    ?        ;Media Descriptor
  1682. XXbpb_fs        dw    ?        ;Number of Sectors in each Fat
  1683. XXbpb_st        dw    ?        ;Number of Sectors per Track
  1684. XXbpb_nh        dw    ?        ;Number of Heads
  1685. XXbpb_hs_lsw    dw    ?        ;Hidden Sectors (Least Sig Word)
  1686. XXbpb_hs_msw    dw    ?        ;Hidden Sectors (Most Sig Word)
  1687. XXbpb_ts_large    dd    ?        ;Large Total Sector Count
  1688. XXbpb_res        db    6 dup (?)    ;Reserved
  1689. XXbpb        ends
  1690. XX
  1691. XX;
  1692. XX; ioctl function 42h
  1693. XX;
  1694. XXioctl_fmt    struc
  1695. XXioctl_fmt_spec    db    ?        ;Special Flags
  1696. XXioctl_fmt_head    dw    ?        ;Head to Format
  1697. XXioctl_fmt_cyl    dw    ?        ;Cylinder to Format
  1698. XXioctl_fmt    ends
  1699. XX
  1700. XX;
  1701. XX; ioctl function 60h
  1702. XX;
  1703. XXdpb        struc
  1704. XXdpb_special    db    ?        ;Special Flags
  1705. XXdpb_type    db    ?        ;Device Type
  1706. XXdpb_attr    dw    ?        ;Device Attributes
  1707. XXdpb_cyl        dw    ?        ;Device Cylinder Count
  1708. XXdpb_media    db    ?        ;Device Media Type if Diskette
  1709. XXdpb_bpb        db    size bpb dup (?)
  1710. XXdpb_sectors    dw    ?        ;Sectors in Track
  1711. XXdpb_track    dd    SECT_TRACK dup (?)
  1712. XXdpb        ends
  1713. XX
  1714. XX;
  1715. XX; The internal control structure for a SCSI device
  1716. XX;
  1717. XXunit        struc
  1718. XXunit_1st_drv    db    ?        ;DOS Drive Numbers
  1719. XXunit_num_drv    db    ?        ;DOS Drive Count
  1720. XXunit_select    db    ?        ;SCSI Select Bit
  1721. XXunit_mcheck    db    ?        ;Media Check Byte
  1722. XXunit_inq_buf    db    size inq dup (?)
  1723. XXunit_inq_term    db    ?
  1724. XXunit_cap_buf    db    size cap dup (?)
  1725. XXunit_sense_buf    db    size sense dup (?)
  1726. XXunit        ends
  1727. XX
  1728. XX;
  1729. XX; Ioctl Commands
  1730. XX;
  1731. XXioc        struc
  1732. XXioc_command    dw    ?        ;Command
  1733. XXioc_param    dw    ?        ;Command Dependent Data
  1734. XXioc_unit    dw    ?        ;Forced SCSI Unit Number
  1735. XXioc_buf_ofs    dw    ?        ;Buffer Offset
  1736. XXioc_buf_seg    dw    ?        ;Buffer Segment
  1737. XXioc        ends
  1738. XX
  1739. XX;
  1740. XX; DOS requests
  1741. XX;
  1742. XXrh        struc
  1743. XXrh_len        db    ?        ;Length of Packet
  1744. XXrh_unit        db    ?        ;Unit Code (Block Only)
  1745. XXrh_cmd        db    ?        ;Command Code
  1746. XXrh_status    dw    ?        ;Returned Status
  1747. XXrh_res        db    8 dup (?)    ;Reserved
  1748. XXrh        ends
  1749. XX
  1750. XXrh0        struc            ;INITIALIZATION
  1751. XXrh0_rh        db    size rh dup (?)    ;Fixed Portion
  1752. XXrh0_nunits    db    ?        ;Number of units (Block Only)
  1753. XXrh0_brk_ofs    dw    ?        ;Break Address (Offset)
  1754. XXrh0_brk_seg    dw    ?        ;Break Address (Segment)
  1755. XXrh0_bpb_tbo    dw    ?        ;Pointer to BPB Array (Offset)
  1756. XXrh0_bpb_tbs    dw    ?        ;Pointer to BPB Array (Segment)
  1757. XXrh0_drv_ltr    db    ?        ;First Available Drive (DOS 3+, Block Only)
  1758. XXrh0        ends
  1759. XX
  1760. XXrh1        struc            ;MEDIA CHECK
  1761. XXrh1_rh        db    size rh dup (?)    ;Fixed Portion
  1762. XXrh1_media    db    ?        ;Media Descriptor from DPB
  1763. XXrh1_md_stat    db    ?        ;Media Status returned by Device Driver
  1764. XXrh1_volid_ofs    dw    ?        ;Offset of Volume ID String (DOS 3+)
  1765. XXrh1_volid_seg    dw    ?        ;Segment of Volume ID String (DOS 3+)
  1766. XXrh1        ends
  1767. XX
  1768. XXrh2        struc            ;GET BPB
  1769. XXrh2_rh        db    size rh dup (?)    ;Fixed Portion
  1770. XXrh2_media    db    ?        ;Media Descriptor from DPB
  1771. XXrh2_buf_ofs    dw    ?        ;Offset of Data Transfer Area
  1772. XXrh2_buf_seg    dw    ?        ;Segment of Data Transfer Area
  1773. XXrh2_pbpbo    dw    ?        ;Offset of Pointer to BPB
  1774. XXrh2_pbpbs    dw    ?        ;Segment of Pointer to BPB
  1775. XXrh2        ends
  1776. XX
  1777. XXrh4        struc            ;INPUT
  1778. XXrh4_rh        db    size rh dup (?)    ;Fixed Portion
  1779. XXrh4_media    db    ?        ;Media Descriptor from DPB
  1780. XXrh4_buf_ofs    dw    ?        ;Offset of Data Transfer Area
  1781. XXrh4_buf_seg    dw    ?        ;Segment of Data Transfer Area
  1782. XXrh4_count    dw    ?        ;Transfer Count (Sectors)
  1783. XXrh4_start    dw    ?        ;Start Sector Number
  1784. XXrh4        ends
  1785. XX
  1786. XXrh8        struc            ;OUTPUT
  1787. XXrh8_rh        db    size rh dup (?)    ;Fixed Portion
  1788. XXrh8_media    db    ?        ;Media Descriptor from DPB
  1789. XXrh8_buf_ofs    dw    ?        ;Offset of Data Transfer Area
  1790. XXrh8_buf_seg    dw    ?        ;Segment of Data Transfer Area
  1791. XXrh8_count    dw    ?        ;Transfer Count (Sectors)
  1792. XXrh8_start    dw    ?        ;Start Sector Number
  1793. XXrh8        ends
  1794. XX
  1795. XXrh9        struc            ;OUTPUT VERIFY
  1796. XXrh9_rh        db    size rh dup (?)    ;Fixed Portion
  1797. XXrh9_media    db    ?        ;Media Descriptor from DPB
  1798. XXrh9_buf_ofs    dw    ?        ;Offset of Data Transfer Area
  1799. XXrh9_buf_seg    dw    ?        ;Segment of Data Transfer Area
  1800. XXrh9_count    dw    ?        ;Transfer Count (Sectors)
  1801. XXrh9_start    dw    ?        ;Start Sector Number
  1802. XXrh9        ends
  1803. XX
  1804. XXrh12        struc            ;OUTPUT IOCTL
  1805. XXrh12_rh        db    size rh dup (?)    ;Fixed Portion
  1806. XXrh12_media    db    ?        ;Media Descriptor from DPB
  1807. XXrh12_buf_ofs    dw    ?        ;Offset of Data Transfer Area
  1808. XXrh12_buf_seg    dw    ?        ;Segment of Data Transfer Area
  1809. XXrh12_count    dw    ?        ;Transfer Count (Sectors)
  1810. XXrh12_start    dw    ?        ;Start Sector Number
  1811. XXrh12        ends
  1812. XX
  1813. XXrh19        struc            ;IOCTL
  1814. XXrh19_rh        db    size rh dup (?)    ;Fixed Portion
  1815. XXrh19_major    db    ?        ;Major Code
  1816. XXrh19_minor    db    ?        ;Minor Code
  1817. XXrh19_si        dw    ?        ;Caller SI Register
  1818. XXrh19_di        dw    ?        ;Caller DI Register
  1819. XXrh19_buf_ofs    dw    ?        ;Caller Buffer Offset
  1820. XXrh19_buf_seg    dw    ?        ;Caller Buffer Segment
  1821. XXrh19        ends
  1822. SHAR_EOF
  1823. if test 6833 -ne "`wc -c < 'struct.inc'`"
  1824. then
  1825. echo shar: error transmitting "'struct.inc'" '(should have been 6833 characters)'
  1826. fi
  1827. fi # end of overwriting check
  1828. echo shar: extracting "'subs.asm'" '(15406 characters)'
  1829. if test -f 'subs.asm'
  1830. then
  1831. echo shar: will not over-write existing file "'subs.asm'"
  1832. else
  1833. sed 's/^XX//' > 'subs.asm' << \SHAR_EOF
  1834. XX;
  1835. XX; Data storage for local subroutines
  1836. XX;
  1837. XXcmd_ready    db    SCSI_TESTREADY,0,0,0,0,0
  1838. XXcmd_sense    db    SCSI_REQSENSE,0,0,0,size sense,0
  1839. XXcmd_format    db    SCSI_FORMATUNIT,0,0,0,0,0
  1840. XX        if extended_io
  1841. XXcmd_read    db    SCSI_READBLK,0,0,0,0,0,0,0,1,0
  1842. XXcmd_write    db    SCSI_WRITEBLK,0,0,0,0,0,0,0,1,0
  1843. XX        else
  1844. XXcmd_read    db    SCSI_READBLK,0,0,0,1,0
  1845. XXcmd_write    db    SCSI_WRITEBLK,0,0,0,1,0
  1846. XX        endif
  1847. XXcmd_tread    db    SCSI_READBLK,1,0,0,0,0
  1848. XXcmd_twrite    db    SCSI_WRITEBLK,1,0,0,0,0
  1849. XXcmd_twritefm    db    SCSI_WRITEFM,0,0,0,1,0
  1850. XXcmd_inquire    db    SCSI_INQUIRY,0,0,0,size inq,0
  1851. XXcmd_erase    db    SCSI_ERASE,1,0,0,0,0
  1852. XXcmd_load    db    SCSI_LOAD,0,0,0,0,0
  1853. XXcmd_capacity    db    SCSI_READSIZE,0,0,0,0,0,0,0,0,0
  1854. XXcmd_verify    db    SCSI_VERIFYBLK,0,0,0,0,0,0,0,SECT_TRACK,0
  1855. XX
  1856. XX        even
  1857. XXdocmd_cmd    dw    ?
  1858. XXdocmd_buf    dw    ?
  1859. XXdocmd_buf_seg    dw    ?
  1860. XXdocmd_len    dw    ?
  1861. XXdocmd_status    db    ?
  1862. XXdocmd_tempb    db    ?
  1863. XX
  1864. XX        if dump_sense
  1865. XXsense_msg    db    0dh,07h,'SCSI Unit: 0x'
  1866. XXsense_unit    db    'xx, Sense Status: 0x'
  1867. XXsense_code    db    'xx, Block Address: 0x'
  1868. XX        if extended_sense
  1869. XXsense_addr3    db    'xx'
  1870. XX        endif
  1871. XXsense_addr2    db    'xx'
  1872. XXsense_addr1    db    'xx'
  1873. XXsense_addr0    db    'xx',0dh,0ah,'$'
  1874. XX        endif
  1875. XX
  1876. XX;
  1877. XX; Reset the SCSI Bus
  1878. XX;
  1879. XXscsi_reset    proc    near
  1880. XX        pusha
  1881. XX
  1882. XX        mov    ax,SCSI_CARD_SEG    ;Point at the command port
  1883. XX        mov    es,ax
  1884. XX        mov    si,SCSI_CMD_PORT
  1885. XX
  1886. XX        mov    al,CMDBASE or CMDENABLE or CMDRST
  1887. XX        mov    es:[si],al        ;Reset the bus
  1888. XX        call    wait1ms
  1889. XX        mov    al,CMDBASE
  1890. XX        mov    es:[si],al        ;All done
  1891. XX        mov    cx,250            ;Wait 250ms
  1892. XXreset_loop:    call    wait1ms
  1893. XX        loop    reset_loop
  1894. XX
  1895. XX        popa
  1896. XX        ret
  1897. XXscsi_reset    endp
  1898. XX
  1899. XX;
  1900. XX; Test the Ready Status of a unit
  1901. XX;
  1902. XX; al = return code, 'C' error
  1903. XX;
  1904. XXscsi_ready    proc    near
  1905. XX        lea    di,cmd_ready            ;Command
  1906. XX        call    docmd
  1907. XX        ret
  1908. XXscsi_ready    endp
  1909. XX
  1910. XX;
  1911. XX; Request Sense data from a unit and display the result
  1912. XX; Called after every SCSI command with the exit code in 'al'
  1913. XX;
  1914. XXscsi_sense    proc    near
  1915. XX        pushf
  1916. XX        pusha
  1917. XX        mov    di,cur_unit            ;Unit
  1918. XX        lea    bx,[di].unit_sense_buf        ;Buffer Offset
  1919. XX        push    ds                ;Buffer Segment
  1920. XX        pop    es
  1921. XX        mov    cx,size sense            ;Buffer Size
  1922. XX        lea    di,cmd_sense            ;Command
  1923. XX        call    docmd
  1924. XX        if dump_sense
  1925. XX        jc    sense_exit
  1926. XX        mov    di,cur_unit
  1927. XX        mov    dl,[di].unit_select
  1928. XX        if reserve_addr
  1929. XX        and    dl,07Fh            ;Remove Cards Bit
  1930. XX        endif
  1931. XX        lea    bx,sense_unit        ;Unit
  1932. XX        call    hex2asc2
  1933. XX        mov    dl,[di].unit_sense_buf.sense_sense
  1934. XX        lea    bx,sense_code        ;Sense
  1935. XX        call    hex2asc2
  1936. XX        if extended_sense
  1937. XX        mov    dl,[di].unit_sense_buf.sense_lba_b3
  1938. XX        lea    bx,sense_addr3        ;Address
  1939. XX        call    hex2asc2
  1940. XX        endif
  1941. XX        mov    dl,[di].unit_sense_buf.sense_lba_b2
  1942. XX        lea    bx,sense_addr2
  1943. XX        call    hex2asc2
  1944. XX        mov    dl,[di].unit_sense_buf.sense_lba_b1
  1945. XX        lea    bx,sense_addr1
  1946. XX        call    hex2asc2
  1947. XX        mov    dl,[di].unit_sense_buf.sense_lba_b0
  1948. XX        lea    bx,sense_addr0
  1949. XX        call    hex2asc2
  1950. XX        lea    dx,sense_msg
  1951. XX        call    puts
  1952. XX        endif
  1953. XXsense_exit:    popa
  1954. XX        popf
  1955. XX        ret
  1956. XXscsi_sense    endp
  1957. XX
  1958. XX;
  1959. XX; Inquire about the type of a unit
  1960. XX;
  1961. XX; al = return code, 'C' error indicates an error
  1962. XX;
  1963. XXscsi_inquire    proc    near
  1964. XX        push    cx
  1965. XX        mov    di,cur_unit            ;Unit
  1966. XX        lea    bx,[di].unit_inq_buf        ;Buffer Offset
  1967. XX        push    ds                ;Buffer Segment
  1968. XX        pop    es
  1969. XX        mov    cx,size inq            ;Buffer Size
  1970. XX        lea    di,cmd_inquire            ;Command
  1971. XX        call    docmd
  1972. XX        jnc    inquire_exit
  1973. XX        call    scsi_sense
  1974. XXinquire_exit:    pop    cx
  1975. XX        ret
  1976. XXscsi_inquire    endp
  1977. XX
  1978. XX;
  1979. XX; Determine the size of a disk
  1980. XX;
  1981. XX; al = return code, 'C' error indicates an error
  1982. XX;
  1983. XXscsi_capacity    proc    near
  1984. XX        push    cx
  1985. XX        mov    di,cur_unit            ;Unit
  1986. XX        lea    bx,[di].unit_cap_buf        ;Buffer Offset
  1987. XX        push    ds                ;Buffer Segment
  1988. XX        pop    es
  1989. XX        mov    cx,size cap            ;Buffer Size
  1990. XX        lea    di,cmd_capacity            ;Command
  1991. XX        call    docmd
  1992. XX        jnc    capacity_exit
  1993. XX        call    scsi_sense
  1994. XXcapacity_exit:    pop    cx
  1995. XX        ret
  1996. XXscsi_capacity    endp
  1997. XX
  1998. XX;
  1999. XX; Verify the Track given in an IOCTL Request
  2000. XX;
  2001. XX; al = return code, 'C' indicates an error
  2002. XX;
  2003. XXscsi_verify    proc    near
  2004. XX        mov    di,es:[bx].rh19_buf_ofs        ;Command Offset
  2005. XX        mov    ax,es:[bx].rh19_buf_seg        ;Command Segment
  2006. XX        mov    es,ax
  2007. XX        mov    ax,es:[di].ioctl_fmt_cyl    ;Track
  2008. XX        shl    ax,SECT_2_CYL            ;Convert to Sector
  2009. XX
  2010. XX        mov    di,cur_bpb            ;Add to Drive Offset
  2011. XX        mov    dx,[di].bpb_hs_msw
  2012. XX
  2013. XX        lea    di,cmd_verify            ;Command
  2014. XX        mov    [di].ver_cmd_lba_b3,dh        ;Insert Sector
  2015. XX        mov    [di].ver_cmd_lba_b2,dl        ; into Command
  2016. XX        mov    [di].ver_cmd_lba_b1,ah        ;Insert Sector
  2017. XX        mov    [di].ver_cmd_lba_b0,al        ; into Command
  2018. XX        call    docmd
  2019. XX        jnc    verify_exit
  2020. XX        call    scsi_sense
  2021. XXverify_exit:    ret
  2022. XXscsi_verify    endp
  2023. XX
  2024. XX;
  2025. XX; Read Some Blocks from the disk given
  2026. XX; the request header in es:bx
  2027. XX;
  2028. XX; al = return code, 'C' indicates an error
  2029. XX;
  2030. XXdisk_read    proc    near
  2031. XX        mov    di,bx
  2032. XX        mov    cx,es:[di].rh4_count        ;Sector Count
  2033. XX        mov    dx,es:[di].rh4_start        ;Starting Sector
  2034. XX        mov    bx,es:[di].rh4_buf_ofs        ;Buffer Offset
  2035. XX        mov    ax,es:[di].rh4_buf_seg        ;Buffer Segment
  2036. XX        mov    es,ax
  2037. XX
  2038. XX        mov    si,cur_bpb
  2039. XX        lea    di,cmd_read            ;Command
  2040. XX        mov    ax,[si].bpb_hs_msw        ;Drive Sector Offset
  2041. XX        if extended_io
  2042. XX        mov    [di].io_cmd_lba_b3,ah        ;Insert Sector
  2043. XX        endif
  2044. XX        mov    [di].io_cmd_lba_b2,al        ;Into the Command
  2045. XX
  2046. XX        if multi_sector
  2047. XX        mov    ax,cx                ;Get Sector Count
  2048. XX        and    ax,CHUNK_MAX-1            ;Mask Off the I/O Chunk
  2049. XX        jnz    disk_r_cok1            ;Check for Boundary
  2050. XX        mov    ax,CHUNK_MAX
  2051. XXdisk_r_cok1:    shl    ax,9                ;Convert to Buffer Size
  2052. XX        add    ax,bx                ;Check for Wrap
  2053. XX        else
  2054. XX        mov    ax,bx                ;Check for Wrap
  2055. XX        add    ax,P_SECT            ;The First Time
  2056. XX        endif
  2057. XXdisk_r_loop:    jnc    disk_r_nowrap
  2058. XX        mov    ax,bx                ;Normalize the
  2059. XX        shr    ax,4                ;Segment and
  2060. XX        mov    si,es                ;Offset so that
  2061. XX        add    si,ax                ;It dosn't Wrap
  2062. XX        mov    es,si
  2063. XX        and    bx,000Fh
  2064. XXdisk_r_nowrap:    push    cx
  2065. XX        mov    [di].io_cmd_lba_b1,dh        ;Insert Sector
  2066. XX        mov    [di].io_cmd_lba_b0,dl        ;Into the Command
  2067. XX        if multi_sector
  2068. XX        and    cx,CHUNK_MAX-1            ;Mask Off the I/O Chunk
  2069. XX        jnz    disk_r_cok2            ;Check for Boundary
  2070. XX        mov    cx,CHUNK_MAX
  2071. XXdisk_r_cok2:
  2072. XX        if extended_io
  2073. XX        mov    [di].io_cmd_cnt_b1,ch        ;Insert Sector Count
  2074. XX        endif
  2075. XX        mov    [di].io_cmd_cnt_b0,cl        ;Into the Command
  2076. XX        shl    cx,9                ;Convert to Buffer Size
  2077. XX        else
  2078. XX        mov    cx,P_SECT            ;Buffer Size
  2079. XX        endif
  2080. XX        call    docmd
  2081. XX        pop    cx
  2082. XX        jc    disk_r_exit
  2083. XX        if multi_sector
  2084. XX        mov    ax,cx                ;Get Sector Count
  2085. XX        and    ax,CHUNK_MAX-1            ;Mask Off the I/O Chunk
  2086. XX        jnz    disk_r_cok3            ;Check for Boundary
  2087. XX        mov    ax,CHUNK_MAX
  2088. XXdisk_r_cok3:    sub    cx,ax                ;Dec Sector Count
  2089. XX        jz    disk_r_exit
  2090. XX        add    dx,ax                ;Bump to next Sector
  2091. XX        shl    ax,9                ;Convert to Buffer Size
  2092. XX        add    bx,ax
  2093. XX        jmp    short disk_r_loop
  2094. XX        else
  2095. XX        inc    dx                ;Bump to next Sector
  2096. XX        add    bx,P_SECT
  2097. XX        loop    disk_r_loop
  2098. XX        clc
  2099. XX        endif
  2100. XXdisk_r_exit:    jnc    disk_r_exit2            ;If no error occured
  2101. XX        call    scsi_sense            ;Display Sense Status
  2102. XXdisk_r_exit2:    mov    es,rh_seg
  2103. XX        mov    bx,rh_off
  2104. XX        pushf
  2105. XX        mov    ax,es:[bx].rh4_count        ;Update the Count
  2106. XX        sub    ax,cx
  2107. XX        mov    es:[bx].rh4_count,ax
  2108. XX        popf
  2109. XX        ret
  2110. XXdisk_read    endp
  2111. XX
  2112. XX;
  2113. XX; Write Some Blocks to the disk given
  2114. XX; the request header in es:bx
  2115. XX;
  2116. XX; al = return code, 'C' indicates an error
  2117. XX;
  2118. XXdisk_write    proc    near
  2119. XX        mov    di,bx
  2120. XX        mov    cx,es:[di].rh8_count        ;Sector Count
  2121. XX        mov    dx,es:[di].rh8_start        ;Starting Sector
  2122. XX        mov    bx,es:[di].rh8_buf_ofs        ;Buffer Offset
  2123. XX        mov    ax,es:[di].rh8_buf_seg        ;Buffer Segment
  2124. XX        mov    es,ax
  2125. XX
  2126. XX        mov    si,cur_bpb
  2127. XX        lea    di,cmd_write            ;Command
  2128. XX        mov    ax,[si].bpb_hs_msw        ;Drive Sector Offset
  2129. XX        if extended_io
  2130. XX        mov    [di].io_cmd_lba_b3,ah        ;Insert Sector
  2131. XX        endif
  2132. XX        mov    [di].io_cmd_lba_b2,al        ;Into the Command
  2133. XX
  2134. XX        if multi_sector
  2135. XX        mov    ax,cx                ;Get Sector Count
  2136. XX        and    ax,CHUNK_MAX-1            ;Mask Off the I/O Chunk
  2137. XX        jnz    disk_w_cok1            ;Check for Boundary
  2138. XX        mov    ax,CHUNK_MAX
  2139. XXdisk_w_cok1:    shl    ax,9                ;Convert to Buffer Size
  2140. XX        add    ax,bx                ;Check for Wrap
  2141. XX        else
  2142. XX        mov    ax,bx                ;Check for Wrap
  2143. XX        add    ax,P_SECT            ;The First Time
  2144. XX        endif
  2145. XXdisk_w_loop:    jnc    disk_w_nowrap
  2146. XX        mov    ax,bx                ;Normalize the
  2147. XX        shr    ax,4                ;Segment and
  2148. XX        mov    si,es                ;Offset so that
  2149. XX        add    si,ax                ;It dosn't Wrap
  2150. XX        mov    es,si
  2151. XX        and    bx,000Fh
  2152. XXdisk_w_nowrap:    push    cx
  2153. XX        mov    [di].io_cmd_lba_b1,dh        ;Insert Sector
  2154. XX        mov    [di].io_cmd_lba_b0,dl        ;Into the Command
  2155. XX        if multi_sector
  2156. XX        and    cx,CHUNK_MAX-1            ;Mask Off the I/O Chunk
  2157. XX        jnz    disk_w_cok2            ;Check for Boundary
  2158. XX        mov    cx,CHUNK_MAX
  2159. XXdisk_w_cok2:
  2160. XX        if extended_io
  2161. XX        mov    [di].io_cmd_cnt_b1,ch        ;Insert Sector Count
  2162. XX        endif
  2163. XX        mov    [di].io_cmd_cnt_b0,cl        ;Into the Command
  2164. XX        shl    cx,9                ;Convert to Buffer Size
  2165. XX        else
  2166. XX        mov    cx,P_SECT            ;Buffer Size
  2167. XX        endif
  2168. XX        call    docmd
  2169. XX        pop    cx
  2170. XX        jc    disk_w_exit
  2171. XX        if multi_sector
  2172. XX        mov    ax,cx                ;Get Sector Count
  2173. XX        and    ax,CHUNK_MAX-1            ;Mask Off the I/O Chunk
  2174. XX        jnz    disk_w_cok3            ;Check for Boundary
  2175. XX        mov    ax,CHUNK_MAX
  2176. XXdisk_w_cok3:    sub    cx,ax                ;Dec Sector Count
  2177. XX        jz    disk_w_exit
  2178. XX        add    dx,ax                ;Bump to next Sector
  2179. XX        shl    ax,9                ;Convert to Buffer Size
  2180. XX        add    bx,ax
  2181. XX        jmp    short disk_w_loop
  2182. XX        else
  2183. XX        inc    dx                ;Bump to next Sector
  2184. XX        add    bx,P_SECT
  2185. XX        loop    disk_w_loop
  2186. XX        clc
  2187. XX        endif
  2188. XXdisk_w_exit:    jnc    disk_w_exit2            ;If no error occured
  2189. XX        call    scsi_sense            ;Display Sense Status
  2190. XXdisk_w_exit2:    mov    es,rh_seg
  2191. XX        mov    bx,rh_off
  2192. XX        pushf
  2193. XX        mov    ax,es:[bx].rh8_count        ;Update the Count
  2194. XX        sub    ax,cx
  2195. XX        mov    es:[bx].rh8_count,ax
  2196. XX        popf
  2197. XX        ret
  2198. XXdisk_write    endp
  2199. XX
  2200. XX;
  2201. XX; Read Some Blocks from the Tape
  2202. XX;
  2203. XXtape_read    proc    near
  2204. XX        mov    write_flag,FALSE        ;Cancel if READ seen
  2205. XX        mov    di,bx
  2206. XX        mov    cx,es:[di].rh4_count        ;Byte Count
  2207. XX        mov    ax,cx                ;Test for invalid
  2208. XX        and    ax,P_SECT-1            ;Byte Count
  2209. XX        jz    tape_r_ok
  2210. XX        mov    es:[di].rh4_count,0        ;Nothing Read
  2211. XX        stc                    ;Oops
  2212. XX        ret
  2213. XXtape_r_ok:    mov    bx,es:[di].rh4_buf_ofs        ;Buffer Offset
  2214. XX        mov    ax,es:[di].rh4_buf_seg        ;Buffer Segment
  2215. XX        mov    es,ax
  2216. XX        mov    ax,bx                ;Normalize the
  2217. XX        shr    ax,4                ;Segment and
  2218. XX        mov    si,es                ;Offset so that
  2219. XX        add    si,ax                ;It dosn't Wrap
  2220. XX        mov    es,si
  2221. XX        and    bx,000Fh
  2222. XX        lea    di,cmd_tread
  2223. XX        mov    ax,cx                ;Convert Bytes
  2224. XX        shr    ax,9                ;to Blocks
  2225. XX        mov    [di].tio_cmd_cnt_b1,ah        ;Insert into Command
  2226. XX        mov    [di].tio_cmd_cnt_b0,al
  2227. XX        call    docmd
  2228. XX        jnc    tape_r_exit
  2229. XX        call    scsi_sense
  2230. XXtape_r_exit:    ret
  2231. XXtape_read    endp
  2232. XX
  2233. XX;
  2234. XX; Write Some Blocks to the Tape
  2235. XX;
  2236. XXtape_write    proc    near
  2237. XX        mov    write_flag,TRUE            ;Write Done
  2238. XX        mov    di,bx
  2239. XX        mov    cx,es:[di].rh8_count        ;Byte Count
  2240. XX        mov    ax,cx                ;Test for invalid
  2241. XX        and    ax,P_SECT-1            ;Byte Count
  2242. XX        jz    tape_w_ok
  2243. XX        mov    es:[di].rh8_count,0        ;Nothing Write
  2244. XX        mov    write_flag,FALSE        ;Cancel if ERROR!
  2245. XX        stc                    ;Oops
  2246. XX        ret
  2247. XXtape_w_ok:    mov    cx,es:[di].rh8_count        ;Byte Count
  2248. XX        mov    bx,es:[di].rh8_buf_ofs        ;Buffer Offset
  2249. XX        mov    ax,es:[di].rh8_buf_seg        ;Buffer Segment
  2250. XX        mov    es,ax
  2251. XX        mov    ax,bx                ;Normalize the
  2252. XX        shr    ax,4                ;Segment and
  2253. XX        mov    si,es                ;Offset so that
  2254. XX        add    si,ax                ;It dosn't Wrap
  2255. XX        mov    es,si
  2256. XX        and    bx,000Fh
  2257. XX        lea    di,cmd_twrite
  2258. XX        mov    ax,cx                ;Convert Bytes
  2259. XX        shr    ax,9                ;to Blocks
  2260. XX        mov    [di].tio_cmd_cnt_b1,ah        ;Insert into Command
  2261. XX        mov    [di].tio_cmd_cnt_b0,al
  2262. XX        call    docmd
  2263. XX        jnc    tape_w_exit
  2264. XX        mov    write_flag,FALSE        ;Cancel if ERROR!
  2265. XX        call    scsi_sense
  2266. XXtape_w_exit:    ret
  2267. XXtape_write    endp
  2268. XX
  2269. XX;
  2270. XX; Do a command
  2271. XX;
  2272. XX; bx => buffer for returned information
  2273. XX; cx = buffer len
  2274. XX; di => command string
  2275. XX; es = buffer segment for returned information
  2276. XX;
  2277. XX; al = return code, 'C' indicates an error
  2278. XX;
  2279. XXdocmd        proc    near
  2280. XX        pusha
  2281. XX        push    es
  2282. XX
  2283. XX        mov    docmd_buf,bx        ;Save our arguments
  2284. XX        mov    docmd_buf_seg,es
  2285. XX        mov    docmd_len,cx
  2286. XX        mov    docmd_cmd,di
  2287. XX
  2288. XX        mov    ax,SCSI_CARD_SEG    ;Point at the Card
  2289. XX        mov    es,ax
  2290. XX        mov    si,SCSI_CMD_PORT    ;Command Port
  2291. XX
  2292. XX;
  2293. XX; Wait for the Bus to become free
  2294. XX;
  2295. XX        mov    cx,65535
  2296. XXidle_loop:    mov    al,es:[si]        ;Get the Status
  2297. XX        and    al,FREE_MASK
  2298. XX        jz    try_sel
  2299. XX        loop    idle_loop
  2300. XX
  2301. XX        call    scsi_reset
  2302. XX        mov    al,CBUSBUSY        ;Bus still BUSY?
  2303. XX        jmp    docmd_exit
  2304. XX
  2305. XXtry_sel:    mov    al,CMDBASE        ;Try to select target
  2306. XX        mov    es:[si],al
  2307. XX
  2308. XX        mov    di,cur_unit
  2309. XX        mov    al,[di].unit_select    ;Get our Select Bit
  2310. XX        mov    di,SCSI_DATA_PORT    ;Data Port
  2311. XX        mov    es:[di],al
  2312. XX
  2313. XX        call    wait100us        ;Spec says wait 90us here
  2314. XX        mov    al,CMDBASE or CMDENABLE or CMDSEL
  2315. XX        mov    es:[si],al
  2316. XX
  2317. XX;
  2318. XX; Wait 250 ms for the Target to be SELected
  2319. XX;
  2320. XX        mov    cx,2500
  2321. XXsel_loop:    test    byte ptr es:[si],STBSY    ;Look for BSY bit
  2322. XX        jnz    cmd_xfer
  2323. XX        call    wait100us
  2324. XX        loop    sel_loop
  2325. XX
  2326. XX        mov    al,CMDBASE or CMDSEL    ;Release the data BUS
  2327. XX        mov    es:[si],al
  2328. XX        call    wait100us        ;Spec says wait 290us
  2329. XX        call    wait100us        ;to abort selection phase
  2330. XX        call    wait100us
  2331. XX        test    byte ptr es:[si],STBSY    ;Look one final time
  2332. XX        jnz    cmd_xfer        ;Device did answer
  2333. XX        mov    al,CNOCONNECT        ;Nothing Answered
  2334. XX        jmp    docmd_exit
  2335. XX
  2336. XX;
  2337. XX; Start the Command
  2338. XX;
  2339. XXcmd_xfer:    call    wait100us        ;Spec say wait 90us here
  2340. XX        mov    al,CMDBASE or CMDENABLE    ;Drop SEL and begin talking
  2341. XX        mov    es:[si],al
  2342. XXxfer_loop:    mov    al,es:[si]
  2343. XX        test    al,STBSY        ;Look for BSY bit
  2344. XX        jz    xfer_error
  2345. XX        test    al,STREQ        ;And REQ bit
  2346. XX        jz    xfer_loop
  2347. XX
  2348. XX        and    al,REQ_MASK        ;Look at REQ type
  2349. XX
  2350. XX        cmp    al,REQ_DATAOUT        ;Is it Data Out?
  2351. XX        jnz    try_datain
  2352. XX        call    send_data
  2353. XX        jmp    short xfer_loop
  2354. XX
  2355. XXtry_datain:    cmp    al,REQ_DATAIN        ;Is it Data In?
  2356. XX        jnz    try_cmdout
  2357. XX        call    receive_data
  2358. XX        jmp    short xfer_loop
  2359. XX
  2360. XXtry_cmdout:    cmp    al,REQ_CMDOUT        ;Is it Command Out?
  2361. XX        jnz    try_statin
  2362. XX        call    send_cmd
  2363. XX        jmp    short xfer_loop
  2364. XX
  2365. XXtry_statin:    cmp    al,REQ_STATIN        ;Is it Status In?
  2366. XX        jnz    try_msgout
  2367. XX        mov    al,es:[di]        ;Get the Status Byte
  2368. XX        mov    docmd_status,al
  2369. XX        jmp    short xfer_loop
  2370. XX
  2371. XXtry_msgout:    cmp    al,REQ_MSGOUT        ;Is it Message Out?
  2372. XX        jnz    try_msgin
  2373. XX        call    send_nop
  2374. XX        jmp    short xfer_loop
  2375. XX
  2376. XXtry_msgin:    cmp    al,REQ_MSGIN        ;Is it Message In?
  2377. XX        jnz    xfer_error
  2378. XX
  2379. XX        mov    al,es:[di]        ;Get Message Byte
  2380. XX        cmp    al,MSG_COMPLETE        ;Are We All Done?
  2381. XX        jnz    short xfer_loop
  2382. XX        mov    al,docmd_status
  2383. XX        or    al,al            ;Did we have an error?
  2384. XX        mov    al,COK            ;Preload OK code
  2385. XX        jz    docmd_exit
  2386. XX
  2387. XXxfer_error:    mov    al,CERROR        ;Command Failed Somehow
  2388. XX
  2389. XXdocmd_exit:    mov    docmd_tempb,al
  2390. XX        mov    al,CMDBASE        ;Release the BUS
  2391. XX        mov    es:[si],al
  2392. XX        pop    es
  2393. XX        popa
  2394. XX        mov    al,docmd_tempb
  2395. XX        cmp    al,COK
  2396. XX        jz    docmd_exit_ok
  2397. XX        stc
  2398. XXdocmd_exit_ok:    ret
  2399. XXdocmd        endp
  2400. XX
  2401. XX;
  2402. XX; Receive a Data Stream from the card
  2403. XX; On entry es:[di] points at the data port
  2404. XX;          es:[si] points at the command port
  2405. XX;
  2406. XXreceive_data    proc    near
  2407. XX        mov    dx,es            ;Save ES
  2408. XX
  2409. XX        mov    bx,si
  2410. XX        mov    ax,es
  2411. XX        mov    cx,docmd_len        ;Length
  2412. XX        mov    di,docmd_buf        ;Dest Offset
  2413. XX        mov    es,docmd_buf_seg    ;Dest Segment
  2414. XX        mov    si,SCSI_DATA_PORT    ;Source Offset
  2415. XX        mov    ds,ax            ;Source Segment
  2416. XX        mov    al,STREQ
  2417. XX        cld
  2418. XX
  2419. XXreceive_loop:    movsb
  2420. XX        if multi_sector
  2421. XX        dec    si            ;Don't blow the card buffer
  2422. XX        endif
  2423. XX        dec    cx
  2424. XX        jz    receive_exit
  2425. XXreceive_wait:    test    byte ptr [bx],al    ;Ready?
  2426. XX        jnz    receive_loop
  2427. XX        jmp    short receive_wait
  2428. XX
  2429. XXreceive_exit:    mov    si,SCSI_CMD_PORT    ;Restore the Environment
  2430. XX        mov    di,SCSI_DATA_PORT
  2431. XX        mov    ax,cs
  2432. XX        mov    ds,ax
  2433. XX        mov    es,dx
  2434. XX        ret
  2435. XXreceive_data    endp
  2436. XX
  2437. XX;
  2438. XX; Send a Command to the card
  2439. XX; On entry es:[di] points at the data port
  2440. XX;          es:[si] points at the command port
  2441. XX;
  2442. XXsend_cmd    proc    near
  2443. XX        mov    bx,docmd_cmd        ;Get Command Pointer
  2444. XX        mov    al,[bx]            ;Get a Command Byte
  2445. XX        mov    es:[di],al        ;Send it to Card
  2446. XX        inc    bx            ;Bump for Next Time
  2447. XX        mov    docmd_cmd,bx
  2448. XX        ret
  2449. XXsend_cmd    endp
  2450. XX
  2451. XX;
  2452. XX; Send a Data Stream to the card
  2453. XX; On entry es:[di] points at the data port
  2454. XX;          es:[si] points at the command port
  2455. XX;
  2456. XXsend_data    proc    near
  2457. XX        mov    bx,si
  2458. XX        mov    cx,docmd_len        ;Get the Data Count
  2459. XX        mov    si,docmd_buf        ;Source Offset
  2460. XX        mov    ds,docmd_buf_seg    ;Source Segment
  2461. XX        mov    al,STREQ
  2462. XX        cld
  2463. XX
  2464. XXsend_loop:    movsb
  2465. XX        if multi_sector
  2466. XX        dec    di            ;Don't blow the card buffer
  2467. XX        endif
  2468. XX        dec    cx
  2469. XX        jz    send_exit
  2470. XXsend_wait:    test    byte ptr es:[bx],al    ;Ready?
  2471. XX        jnz    send_loop
  2472. XX        jmp    short send_wait
  2473. XX
  2474. XXsend_exit:    mov    si,SCSI_CMD_PORT    ;Restore the Environment
  2475. XX        mov    di,SCSI_DATA_PORT
  2476. XX        mov    ax,cs
  2477. XX        mov    ds,ax
  2478. XX        ret
  2479. XXsend_data    endp
  2480. XX
  2481. XX;
  2482. XX; Send a NOP Message
  2483. XX;
  2484. XXsend_nop    proc    near
  2485. XX        mov    al,MSG_NOP        ;Oops, send a nop
  2486. XX        mov    es:[di],al
  2487. XX        mov    al,CMDBASE or CMDENABLE
  2488. XX        mov    es:[si],al
  2489. XX        ret
  2490. XXsend_nop    endp
  2491. XX
  2492. XX;
  2493. XX; Wait One Milli second
  2494. XX;
  2495. XX; The value of 'cx' is computed for an 8 Mhz Clock
  2496. XX;
  2497. XXwait1ms        proc    near
  2498. XX        push    cx        ;   (3) = 375ns
  2499. XX        mov    cx,798        ;   (2) = 250ns
  2500. XXwait_m_loop:    loop    wait_m_loop    ;  (10) = 1250ns * X
  2501. XX        pop    cx        ;   (5) = 625ns
  2502. XX        ret            ; (11+) = 1375ns
  2503. XXwait1ms        endp
  2504. XX
  2505. XX;
  2506. XX; Wait One Hundred Micros Seconds
  2507. XX;
  2508. XX; The value of 'cx' is computed for an 8 Mhz Clock
  2509. XX;
  2510. XXwait100us    proc    near
  2511. XX        push    cx        ;   (3) = 375ns
  2512. XX        mov    cx,78        ;   (2) = 250ns
  2513. XXwait_u_loop:    loop    wait_u_loop    ;  (10) = 1250ns * X
  2514. XX        pop    cx        ;   (5) = 625ns
  2515. XX        ret            ; (11+) = 1375ns
  2516. XXwait100us    endp
  2517. SHAR_EOF
  2518. if test 15406 -ne "`wc -c < 'subs.asm'`"
  2519. then
  2520. echo shar: error transmitting "'subs.asm'" '(should have been 15406 characters)'
  2521. fi
  2522. fi # end of overwriting check
  2523. echo shar: extracting "'units.asm'" '(3322 characters)'
  2524. if test -f 'units.asm'
  2525. then
  2526. echo shar: will not over-write existing file "'units.asm'"
  2527. else
  2528. sed 's/^XX//' > 'units.asm' << \SHAR_EOF
  2529. XX;
  2530. XX; target information/control structures
  2531. XX;
  2532. XX        even
  2533. XXunit0        db    size unit dup (-1)
  2534. XX        even
  2535. XXunit1        db    size unit dup (-1)
  2536. XX        even
  2537. XXunit2        db    size unit dup (-1)
  2538. XX        even
  2539. XXunit3        db    size unit dup (-1)
  2540. XX        even
  2541. XXunit4        db    size unit dup (-1)
  2542. XX        even
  2543. XXunit5        db    size unit dup (-1)
  2544. XX        even
  2545. XXunit6        db    size unit dup (-1)
  2546. XX        ife reserve_addr
  2547. XX        even
  2548. XXunit7        db    size unit dup (-1)
  2549. XX        endif
  2550. XX
  2551. XX        even
  2552. XXbpb0        db    size bpb dup (-1)
  2553. XX        even
  2554. XXbpb1        db    size bpb dup (-1)
  2555. XX        even
  2556. XXbpb2        db    size bpb dup (-1)
  2557. XX        even
  2558. XXbpb3        db    size bpb dup (-1)
  2559. XX        even
  2560. XXbpb4        db    size bpb dup (-1)
  2561. XX        even
  2562. XXbpb5        db    size bpb dup (-1)
  2563. XX        even
  2564. XXbpb6        db    size bpb dup (-1)
  2565. XX        even
  2566. XXbpb7        db    size bpb dup (-1)
  2567. XX        even
  2568. XXbpb8        db    size bpb dup (-1)
  2569. XX        even
  2570. XXbpb9        db    size bpb dup (-1)
  2571. XX        even
  2572. XXbpbA        db    size bpb dup (-1)
  2573. XX        even
  2574. XXbpbB        db    size bpb dup (-1)
  2575. XX        even
  2576. XXbpbC        db    size bpb dup (-1)
  2577. XX        even
  2578. XXbpbD        db    size bpb dup (-1)
  2579. XX        even
  2580. XXbpbE        db    size bpb dup (-1)
  2581. XX        even
  2582. XXbpbF        db    size bpb dup (-1)
  2583. XX
  2584. XX        even
  2585. XXunit_array    dw    unit0
  2586. XX        dw    unit1
  2587. XX        dw    unit2
  2588. XX        dw    unit3
  2589. XX        dw    unit4
  2590. XX        dw    unit5
  2591. XX        dw    unit6
  2592. XX        ife reserve_addr
  2593. XX        dw    unit7
  2594. XX        endif
  2595. XX
  2596. XX        even
  2597. XXbpb_array    dw    bpb0        ;BPB Array for DOS
  2598. XX        dw    bpb1
  2599. XX        dw    bpb2
  2600. XX        dw    bpb3
  2601. XX        dw    bpb4
  2602. XX        dw    bpb5
  2603. XX        dw    bpb6
  2604. XX        dw    bpb7
  2605. XX        dw    bpb8
  2606. XX        dw    bpb9
  2607. XX        dw    bpbA
  2608. XX        dw    bpbB
  2609. XX        dw    bpbC
  2610. XX        dw    bpbD
  2611. XX        dw    bpbE
  2612. XX        dw    bpbF
  2613. XXbpb_hw_mark    dw    bpb_array
  2614. XX
  2615. XXtape_unit    dw    -1
  2616. XXcur_unit    dw    unit0
  2617. XXcur_bpb        dw    bpb0
  2618. XX
  2619. XX;
  2620. XX; Given the request header in es:bx
  2621. XX; Return a pointer in ds:di to the unit entry
  2622. XX; or 'C' if no such unit exists.
  2623. XX;
  2624. XX; Do not destroy es:bx !!!
  2625. XX;
  2626. XXfind_unit    proc    near
  2627. XX        pusha
  2628. XX        mov    ah,es:[bx].rh_unit    ;What drive did they want
  2629. XX        lea    di,unit_array
  2630. XX        lea    si,bpb_array
  2631. XX        mov    cx,MAXUNIT        ;How many to search
  2632. XXfind_loop:    mov    bx,[di]            ;Point at a unit    
  2633. XX        mov    al,[bx].unit_num_drv    ;Does this SCSI device
  2634. XX        or    al,al            ;Have any Drives Defined?
  2635. XX        jz    find_next
  2636. XX        mov    dh,[bx].unit_1st_drv    ;Get First Drive Number
  2637. XXfind_unit_loop:    cmp    ah,dh            ;Is this the correct drive?
  2638. XX        jz    find_match
  2639. XX        inc    si            ;Bump to next BPB
  2640. XX        inc    si
  2641. XX        inc    dh            ;Bump Drive Number
  2642. XX        dec    al            ;Dec Drive count
  2643. XX        jnz    find_unit_loop        ;Try next Drive
  2644. XX        jmp    short find_next        ;Try next SCSI device
  2645. XXfind_match:    mov    cur_unit,bx        ;Found a match
  2646. XX        mov    ax,[si]
  2647. XX        mov    cur_bpb,ax
  2648. XX        clc
  2649. XX        jmp    find_exit
  2650. XXfind_next:    inc    di
  2651. XX        inc    di
  2652. XX        loop    find_loop
  2653. XX        stc                ;No More units, Error
  2654. XXfind_exit:    popa
  2655. XX        ret
  2656. XXfind_unit    endp
  2657. XX
  2658. XX;
  2659. XX; Given the data in a unit entry,
  2660. XX; create the bpb for the unit.
  2661. XX;
  2662. XXmake_bpb    proc    near
  2663. XX        mov    di,cur_bpb        ;Get the current BPB
  2664. XX        mov    bx,cur_unit        ;Get the current Unit
  2665. XX        mov    [di].bpb_ss,P_SECT
  2666. XX        mov    [di].bpb_au,CLUSTSIZE
  2667. XX        mov    [di].bpb_rs,1
  2668. XX        mov    [di].bpb_nf,2
  2669. XX        mov    [di].bpb_de,512
  2670. XX        mov    ah,[bx].unit_cap_buf.cap_sectors_b3
  2671. XX        mov    al,[bx].unit_cap_buf.cap_sectors_b2
  2672. XX        or    ax,ax
  2673. XX        jz    make_bpb_last        ;Use up the last few sectors
  2674. XX        dec    ax            ;Use up 65536 Sectors
  2675. XX        mov    [bx].unit_cap_buf.cap_sectors_b3,ah
  2676. XX        mov    [bx].unit_cap_buf.cap_sectors_b2,al
  2677. XX        mov    dx,65535        ;Max of 32 Meg
  2678. XX        jmp    short make_bpb_ts
  2679. XXmake_bpb_last:    mov    dh,[bx].unit_cap_buf.cap_sectors_b1
  2680. XX        mov    [bx].unit_cap_buf.cap_sectors_b1,0
  2681. XX        mov    dl,0            ;Round to nearest Cyl
  2682. XX        mov    [bx].unit_cap_buf.cap_sectors_b0,0
  2683. XX        dec    dx            ;Make it zero relative
  2684. XXmake_bpb_ts:    mov    [di].bpb_ts,dx
  2685. XX        mov    [di].bpb_md,0F8h
  2686. XX        shr    dx,SECT_2_FS
  2687. XX        inc    dx            ;Allow for round-off
  2688. XX        mov    [di].bpb_fs,dx
  2689. XX        mov    [di].bpb_st,SECT_TRACK
  2690. XX        mov    [di].bpb_nh,1
  2691. XX        mov    [di].bpb_hs_lsw,0
  2692. XX        mov    [di].bpb_hs_msw,0
  2693. XX        ret
  2694. XXmake_bpb    endp
  2695. SHAR_EOF
  2696. if test 3322 -ne "`wc -c < 'units.asm'`"
  2697. then
  2698. echo shar: error transmitting "'units.asm'" '(should have been 3322 characters)'
  2699. fi
  2700. fi # end of overwriting check
  2701. #
  2702. # End of shell archive
  2703. #
  2704. exit 0
  2705.