home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume25 / st01scsi / part02 < prev    next >
Text File  |  1991-11-04  |  59KB  |  2,505 lines

  1. Newsgroups: comp.sources.misc
  2. From: briana@tau-ceti.isc-br.com (Brian W. Antoine)
  3. Subject:  v25i019:  st01scsi - DOS SCSI Driver for the Seagate ST-01, v2.0, Part02/02
  4. Message-ID: <1991Nov5.033452.4414@sparky.imd.sterling.com>
  5. X-Md4-Signature: db7f3dda25e39475703534e67a7028f3
  6. Date: Tue, 5 Nov 1991 03:34:52 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: briana@tau-ceti.isc-br.com (Brian W. Antoine)
  10. Posting-number: Volume 25, Issue 19
  11. Archive-name: st01scsi/part02
  12. Environment: DOS, ST-01
  13. Supersedes: ST01SCSI.12: Volume 15, Issue 2-3
  14.  
  15. #
  16. # This is a Shell Archive.
  17. # Remove everything above and including the cut line.
  18. # Then run the rest of the file through #! /bin/sh.
  19. # -----cut here-----cut here-----cut here-----cut here-----
  20. #! /bin/sh
  21. # Execute the file with #! /bin/sh (not csh) to create the files:
  22. #    dump.asm
  23. #    ioctl.asm
  24. #    kludge.asm
  25. #    scsi.asm
  26. #    subs.asm
  27. #    units.asm
  28. # This Archive created: Fri Oct 18 22:46:09 1991
  29. # By: Brian W. Antoine at ISC - Bunker Ramo, Spokane, WA
  30. #
  31. export PATH; PATH=/bin:$PATH
  32. echo shar: extracting "'dump.asm'" '(1362 characters)'
  33. if test -f 'dump.asm'
  34. then
  35. echo shar: will not over-write existing file "'dump.asm'"
  36. else
  37. sed 's/^XX//' > 'dump.asm' << \SHAR_EOF
  38. XX;
  39. XX; Convert bin (ax) to ascii (bx => buffer)
  40. XX;
  41. XXbin_ascii    proc    near
  42. XX        pusha
  43. XX        push    ax
  44. XX        mov    cx,6
  45. XXfill_buff:    mov    byte ptr [bx],' '
  46. XX        inc    bx
  47. XX        loop    fill_buff
  48. XX        mov    si,10
  49. XX        or    ax,ax
  50. XX        jns    clr_dvd
  51. XX        neg    ax
  52. XXclr_dvd:    sub    dx,dx
  53. XX        div    si
  54. XX        add    dx,'0'
  55. XX        dec    bx
  56. XX        mov    [bx],dl
  57. XX        inc    cx
  58. XX        or    ax,ax
  59. XX        jnz    clr_dvd
  60. XX        pop    ax
  61. XX        or    ax,ax
  62. XX        jns    no_more
  63. XX        dec    bx
  64. XX        mov    byte ptr [bx],'-'
  65. XXno_more:    popa
  66. XX        ret
  67. XXbin_ascii    endp
  68. XX
  69. XX;
  70. XX; Convert Hex (dx) to Ascii (bx => buffer)
  71. XX;
  72. XXhex2asc4    proc    near
  73. XX        push    cx
  74. XX        push    ax
  75. XX        mov    cx,4        ;Do Four Digits
  76. XXh241:        rol    dx,1
  77. XX        rol    dx,1
  78. XX        rol    dx,1
  79. XX        rol    dx,1
  80. XX        mov    al,dl        ;Get the Current Digit
  81. XX        and    al,0Fh
  82. XX        cmp    al,0Ah        ;Is It Hex?
  83. XX        jge    h242
  84. XX        add    al,30h        ;Normal Digit
  85. XX        jmp    h243
  86. XXh242:        add    al,37h        ;Hex Digit
  87. XXh243:        mov    [bx],al        ;Insert in Buffer
  88. XX        inc    bx
  89. XX        loop    h241
  90. XX        pop    ax
  91. XX        pop    cx
  92. XX        ret
  93. XXhex2asc4    endp
  94. XX
  95. XX;
  96. XX; Convert Hex (dl) to Ascii (bx => buffer)
  97. XX;
  98. XXhex2asc2    proc    near
  99. XX        push    cx
  100. XX        push    ax
  101. XX        mov    cx,2        ;Do Two Digits
  102. XXh221:        rol    dl,1
  103. XX        rol    dl,1
  104. XX        rol    dl,1
  105. XX        rol    dl,1
  106. XX        mov    al,dl        ;Get the Current Digit
  107. XX        and    al,0Fh
  108. XX        cmp    al,0Ah        ;Is It Hex?
  109. XX        jge    h222
  110. XX        add    al,30h        ;Normal Digit
  111. XX        jmp    h223
  112. XXh222:        add    al,37h        ;Hex Digit
  113. XXh223:        mov    [bx],al        ;Insert in Buffer
  114. XX        inc    bx
  115. XX        loop    h221
  116. XX        pop    ax
  117. XX        pop    cx
  118. XX        ret
  119. XXhex2asc2    endp
  120. XX
  121. XX;
  122. XX; Print a string
  123. XX;
  124. XX; ds:dx => string
  125. XX;
  126. XXputs        proc    near
  127. XX        pusha
  128. XX        mov    ah,9        ;DOS print string
  129. XX        int    21h
  130. XX        popa
  131. XX        ret
  132. XXputs        endp
  133. SHAR_EOF
  134. if test 1362 -ne "`wc -c < 'dump.asm'`"
  135. then
  136. echo shar: error transmitting "'dump.asm'" '(should have been 1362 characters)'
  137. fi
  138. fi # end of overwriting check
  139. echo shar: extracting "'ioctl.asm'" '(5778 characters)'
  140. if test -f 'ioctl.asm'
  141. then
  142. echo shar: will not over-write existing file "'ioctl.asm'"
  143. else
  144. sed 's/^XX//' > 'ioctl.asm' << \SHAR_EOF
  145. XX;
  146. XX; Process an ioctl request for the current unit
  147. XX;
  148. XX; return 'C' on error
  149. XX;
  150. XXscsi_ioctl    proc
  151. XX        mov    al,es:[bx].rh19_minor        ;Get the minor number
  152. XX        cmp    al,40h                ;Set Device Params?
  153. XX        jnz    scsi_i_42h
  154. XX        clc
  155. XX        jmp    scsi_i_exit
  156. XX
  157. XXscsi_i_42h:    cmp    al,42h                ;Format and Verify?
  158. XX        jnz    scsi_i_60h
  159. XX        mov    di,es:[bx].rh19_buf_ofs        ;Get the Param Buffer
  160. XX        mov    ax,es:[bx].rh19_buf_seg
  161. XX        mov    es,ax
  162. XX        mov    ax,es:[di].ioctl_fmt_cyl    ;Cylinder
  163. XX        mov    bx,SECT_TRACK
  164. XX        mul    bx                ;Convert to Sector
  165. XX        mov    cx,es:[di].ioctl_fmt_head    ;Head
  166. XX        or    cx,cx
  167. XX        jz    head0_42h
  168. XXhead_loop_42h:    add    ax,SECT_TRACK            ;Add Head Tracks
  169. XX        adc    dx,0
  170. XX        loop    head_loop_42h
  171. XXhead0_42h:    mov    bx,0
  172. XX        mov    cx,es:[di].ioctl_fmt_len    ;How Many Tracks
  173. XXlen_loop_42h:    add    bx,SECT_TRACK            ;Convert to Sectors
  174. XX        loop    len_loop_42h
  175. XX        mov    cx,bx
  176. XX
  177. XX        ife large_drives
  178. XX        mov    di,cur_bpb            ;Add Drive Offset
  179. XX        mov    dx,[di].bpb_hs_msw
  180. XX        endif
  181. XX
  182. XX        call    scsi_verify
  183. XX        jmp    scsi_i_exit
  184. XX
  185. XXscsi_i_60h:    cmp    al,60h                ;Get Device Params?
  186. XX        jnz    scsi_i_61h
  187. XXbuild_bpb:    mov    si,cur_bpb            ;Get the Current BPB
  188. XX        mov    di,es:[bx].rh19_buf_ofs        ;Get the Param Buffer
  189. XX        mov    ax,es:[bx].rh19_buf_seg
  190. XX        mov    es,ax
  191. XX        mov    es:[di].dpb_special,05h        ;Sect Same/Use Cur BPB
  192. XX        mov    es:[di].dpb_type,05h        ;Fixed Disk
  193. XX        mov    es:[di].dpb_attr,0001h        ;Not Removable
  194. XX        if large_drives
  195. XX        mov    dx,[si].bpb_ts_msw
  196. XX        mov    ax,[si].bpb_ts_lsw
  197. XX        else
  198. XX        mov    dx,0
  199. XX        mov    ax,[si].bpb_ts
  200. XX        endif
  201. XX        add    ax,1                ;Sectors (1-n)
  202. XX        adc    dx,0
  203. XX        mov    bx,SECT_TRACK
  204. XX        div    bx
  205. XX        mov    es:[di].dpb_cyl,ax
  206. XX        mov    es:[di].dpb_media,0        ;????
  207. XX        mov    es:[di].dpb_sectors,SECT_TRACK    ;Sectors per Track
  208. XX
  209. XX        push    di
  210. XX        lea    di,es:[di].dpb_bpb        ;Copy the bpb into
  211. XX        mov    cx,size bpb            ;the requestors buffer
  212. XX        cld
  213. XX    rep    movsb
  214. XX        pop    di
  215. XX
  216. XX        lea    di,es:[di].dpb_track        ;Build the Track List
  217. XX        mov    cx,SECT_TRACK
  218. XX        mov    ax,0                ;Start with Sector 0
  219. XXscsi_i_t_loop:    mov    es:[di],ax            ;Sector Number
  220. XX        inc    ax
  221. XX        inc    di
  222. XX        inc    di
  223. XX        mov    word ptr es:[di],P_SECT        ;Sector Size
  224. XX        inc    di
  225. XX        inc    di
  226. XX        loop    scsi_i_t_loop
  227. XX        clc
  228. XX        jmp    short scsi_i_exit
  229. XX
  230. XXscsi_i_61h:    cmp    al,61h                ;Read Track?
  231. XX        jnz    scsi_i_62h
  232. XX        mov    di,es:[bx].rh19_buf_ofs        ;Get the Param Buffer
  233. XX        mov    ax,es:[bx].rh19_buf_seg
  234. XX        mov    es,ax
  235. XX        mov    ax,es:[di].ioctl_read_cyl    ;Cylinder
  236. XX        mov    bx,SECT_TRACK
  237. XX        mul    bx                ;Convert to Sector
  238. XX        mov    cx,es:[di].ioctl_read_head    ;Head
  239. XX        or    cx,cx
  240. XX        jz    head0_61h
  241. XXhead_loop_61h:    add    ax,SECT_TRACK            ;Add Head Tracks
  242. XX        adc    dx,0
  243. XX        loop    head_loop_61h
  244. XXhead0_61h:    add    ax,es:[di].ioctl_read_sect    ;Offset into the Track
  245. XX        adc    dx,0
  246. XX        mov    cx,es:[di].ioctl_read_len    ;How Many Sectors
  247. XX
  248. XX        ife large_drives
  249. XX        mov    di,cur_bpb            ;Add Drive Offset
  250. XX        mov    dx,[di].bpb_hs_msw
  251. XX        endif
  252. XX
  253. XX        call    scsi_verify
  254. XX        jc    scsi_i_error
  255. XX        mov    es,rh_seg
  256. XX        mov    bx,rh_off
  257. XX        jmp    build_bpb
  258. XX
  259. XXscsi_i_62h:    cmp    al,62h                ;Verify?
  260. XX        jnz    scsi_i_error
  261. XX        mov    di,es:[bx].rh19_buf_ofs        ;Get the Param Buffer
  262. XX        mov    ax,es:[bx].rh19_buf_seg
  263. XX        mov    es,ax
  264. XX        mov    ax,es:[di].ioctl_fmt_cyl    ;Cylinder
  265. XX        mov    bx,SECT_TRACK
  266. XX        mul    bx                ;Convert to Sector
  267. XX        mov    cx,es:[di].ioctl_fmt_head    ;Head
  268. XX        or    cx,cx
  269. XX        jz    head0_62h
  270. XXhead_loop_62h:    add    ax,SECT_TRACK            ;Add Head Tracks
  271. XX        adc    dx,0
  272. XX        loop    head_loop_62h
  273. XXhead0_62h:    mov    bx,0
  274. XX        mov    cx,es:[di].ioctl_fmt_len    ;How Many Tracks
  275. XXlen_loop_62h:    add    bx,SECT_TRACK            ;Convert to Sectors
  276. XX        loop    len_loop_62h
  277. XX        mov    cx,bx
  278. XX
  279. XX        ife large_drives
  280. XX        mov    di,cur_bpb            ;Add Drive Offset
  281. XX        mov    dx,[di].bpb_hs_msw
  282. XX        endif
  283. XX
  284. XX        call    scsi_verify
  285. XX        jmp    short scsi_i_exit
  286. XX
  287. XXscsi_i_error:    stc
  288. XXscsi_i_exit:    ret
  289. XXscsi_ioctl    endp
  290. XX
  291. XX;
  292. XX; Process an ioctl_write request
  293. XX;
  294. XXscsi_ioctl_write proc
  295. XX        mov    di,es:[bx].rh12_buf_ofs        ;Get The Command
  296. XX        mov    ax,es:[bx].rh12_buf_seg        ;Buffer
  297. XX        mov    es,ax
  298. XX        mov    ax,es:[di].ioc_command        ;What Command
  299. XX
  300. XX;
  301. XX; Format Disk Unit
  302. XX;
  303. XX        cmp    al,'F'                ;Format?
  304. XX        jnz    try_erase
  305. XX        mov    ax,es:[di].ioc_param1        ;Get Interleave
  306. XX        mov    bx,es:[di].ioc_buf_ofs        ;Get Buffer Offset
  307. XX        mov    cx,es:[di].ioc_buf_len        ;Get Buffer Length
  308. XX        mov    dx,es:[di].ioc_param2        ;Get Format Type
  309. XX        mov    es,es:[di].ioc_buf_seg        ;Get Buffer Seg
  310. XX        lea    di,cmd_format            ;Insert into Command
  311. XX        mov    [di].fmt_cmd_il_b1,ah
  312. XX        mov    [di].fmt_cmd_il_b0,al
  313. XX        mov    [di].fmt_cmd_type,dl
  314. XX        call    docmd
  315. XX        jnc    format_exit
  316. XX        call    scsi_sense
  317. XXformat_exit:    jmp    scsi_i_w_exit
  318. XX
  319. XX;
  320. XX; Erase Tape Unit
  321. XX;
  322. XXtry_erase:    cmp    al,'E'                ;Erase?
  323. XX        jnz    try_rewind
  324. XX        lea    di,cmd_erase            ;Now Erase Tape
  325. XX        call    docmd
  326. XX        jnc    erase_exit
  327. XX        call    scsi_sense
  328. XXerase_exit:    jmp    scsi_i_w_exit
  329. XX
  330. XX;
  331. XX; Rewind Tape Unit
  332. XX;
  333. XXtry_rewind:    cmp    al,'R'                ;Rewind?
  334. XX        jnz    try_load
  335. XX        lea    di,cmd_rewind            ;Now Rewind Tape
  336. XX        call    docmd
  337. XX        jnc    rewind_exit
  338. XX        call    scsi_sense
  339. XXrewind_exit:    jmp    scsi_i_w_exit
  340. XX
  341. XX;
  342. XX; Load Tape on Open
  343. XX;
  344. XXtry_load:    cmp    al,'L'                ;Load?
  345. XX        jnz    try_noload
  346. XX        mov    load_flag,TRUE
  347. XX        jmp    scsi_i_w_exit
  348. XX
  349. XX;
  350. XX; No Load Tape on Open
  351. XX;
  352. XXtry_noload:    cmp    al,'N'                ;No Load?
  353. XX        jnz    try_space
  354. XX        mov    load_flag,FALSE
  355. XX        jmp    scsi_i_w_exit
  356. XX
  357. XX;
  358. XX; Space Tape
  359. XX;
  360. XXtry_space:    cmp    al,'S'                ;Space?
  361. XX        jnz    try_filemark
  362. XX        mov    ax,es:[di].ioc_param1        ;Get Count
  363. XX        mov    bx,es:[di].ioc_param2        ;Get Type
  364. XX        lea    di,cmd_space            ;Insert into Command
  365. XX        mov    [di].space_cmd_code,bl
  366. XX        mov    [di].space_cmd_cnt2,ah        ;Dup of ah
  367. XX        mov    [di].space_cmd_cnt1,ah
  368. XX        mov    [di].space_cmd_cnt0,al
  369. XX        call    docmd
  370. XX        jnc    scsi_i_w_exit
  371. XX        call    scsi_sense
  372. XX        jmp    scsi_i_w_exit
  373. XX
  374. XX;
  375. XX; Write Filemarks
  376. XX;
  377. XXtry_filemark:    cmp    al,'M'                ;Mark?
  378. XX        jnz    try_remap
  379. XX        mov    ax,es:[di].ioc_param1        ;Get Count
  380. XX        lea    di,cmd_twritefm            ;Insert into Command
  381. XX        mov    [di].fm_cmd_cnt_b1,ah
  382. XX        mov    [di].fm_cmd_cnt_b0,al
  383. XX        call    docmd
  384. XX        jnc    scsi_i_w_exit
  385. XX        call    scsi_sense
  386. XX        jmp    scsi_i_w_exit
  387. XX
  388. XX;
  389. XX; Reassign Block
  390. XX;
  391. XXtry_remap:    cmp    al,'A'                ;ReAssign?
  392. XX        jnz    scsi_i_w_error
  393. XX        mov    bx,es:[di].ioc_buf_ofs        ;Get Buffer Offset
  394. XX        mov    cx,es:[di].ioc_buf_len        ;Get Buffer Length
  395. XX        mov    es,es:[di].ioc_buf_seg        ;Get Buffer Seg
  396. XX        lea    di,cmd_remap            ;Command
  397. XX        call    docmd
  398. XX        jnc    scsi_i_w_exit
  399. XX        call    scsi_sense
  400. XX        jmp    scsi_i_w_exit
  401. XX
  402. XXscsi_i_w_error:    stc
  403. XXscsi_i_w_exit:    ret
  404. XXscsi_ioctl_write endp
  405. SHAR_EOF
  406. if test 5778 -ne "`wc -c < 'ioctl.asm'`"
  407. then
  408. echo shar: error transmitting "'ioctl.asm'" '(should have been 5778 characters)'
  409. fi
  410. fi # end of overwriting check
  411. echo shar: extracting "'kludge.asm'" '(2417 characters)'
  412. if test -f 'kludge.asm'
  413. then
  414. echo shar: will not over-write existing file "'kludge.asm'"
  415. else
  416. sed 's/^XX//' > 'kludge.asm' << \SHAR_EOF
  417. XX;
  418. XX; This code is needed because DOS insists on opening a char device
  419. XX; in cooked mode.  The problem is that without adding code to every
  420. XX; application that would ever use us, we have no way to alter this
  421. XX; because the use of O_BINARY or setmode() do not affect char devices.
  422. XX;
  423. XX; The solution (kludge) is to watch open requests issued thru the
  424. XX; INT 21 vector.  If we see a open request followed by a OPEN_DEV
  425. XX; call to us, it must have been an open for us.  So during the return,
  426. XX; force a call to the ioctl facility that will switch to raw mode.
  427. XX;
  428. XX
  429. XX;
  430. XX; The Original INT 21 Vector
  431. XX;
  432. XXvect_int_21    equ    word ptr 4 * 21h
  433. XXorig_int_21    dd    ?            ;Original INT 21 Vector
  434. XX
  435. XX;
  436. XX; OPEN_DEV flag is TRUE when we are opened
  437. XX;
  438. XXopened_flag    db    FALSE
  439. XX
  440. XXpatch_us_in    proc    near
  441. XX        push    es
  442. XX        push    ax
  443. XX        mov    ax,0            ;Patch Ourselves into
  444. XX        mov    es,ax            ;the INT 21 Vector
  445. XX        mov    ax,es:[vect_int_21]    ;Offset
  446. XX        mov    word ptr orig_int_21,ax
  447. XX        lea    ax,our_int_21
  448. XX        mov    es:[vect_int_21],ax
  449. XX        mov    ax,es:[vect_int_21+2]    ;Segment
  450. XX        mov    word ptr orig_int_21+2,ax
  451. XX        mov    ax,cs
  452. XX        mov    es:[vect_int_21+2],ax
  453. XX        pop    ax
  454. XX        pop    es
  455. XX        ret
  456. XXpatch_us_in    endp
  457. XX
  458. XXour_int_21    proc    far
  459. XX        pushf                ;Save entry flags
  460. XX        cmp    ah,3Dh            ;Is it an open request?
  461. XX        jnz    not_open_req
  462. XX        popf                ;Restore entry flags
  463. XX;
  464. XX; We need to set things up so the 'iret' done by the INT 21
  465. XX; code will have some the right stuff on the stack.
  466. XX; #1 Flags with interrupts enabled
  467. XX; #2 Return Address
  468. XX;
  469. XX        sti                ;Allow interrupts
  470. XX        pushf                ;After the iret
  471. XX        cli                ;Shut interrupts off
  472. XX        call    cs:orig_int_21        ;While we Pass the request on
  473. XX;
  474. XX; Upon return, interrupts are enabled, so shut them off while we work
  475. XX;
  476. XX        pushf
  477. XX        cli
  478. XX        cmp    cs:opened_flag,FALSE    ;Was it an open for us?
  479. XX        jz    not_our_open
  480. XX        mov    cs:opened_flag,FALSE    ;Clear for next time
  481. XX;
  482. XX; We need to forge a call to the ioctl interface
  483. XX; to switch DOS to raw mode when it talks to us
  484. XX;
  485. XX        pusha
  486. XX        mov    bx,ax            ;Save the Handle
  487. XX        mov    ax,4400h        ;Get Device Information
  488. XX        pushf
  489. XX        call    cs:orig_int_21
  490. XX        mov    dh,0            ;Setup
  491. XX        or    dl,20h            ;for RAW Mode
  492. XX        mov    ax,4401h        ;Set Device Information
  493. XX        pushf
  494. XX        call    cs:orig_int_21
  495. XX        popa
  496. XX
  497. XXnot_our_open:    popf                ;The Original Flags to return
  498. XX;
  499. XX; When we return, we need to pop the flags that the original INT 21
  500. XX; call left on the stack, and return the flags we got back
  501. XX;
  502. XX        ret    2            ;Return and discard flags
  503. XX
  504. XXnot_open_req:    popf                ;Pop the saved flags
  505. XX        jmp    cs:orig_int_21        ;Continue with original code
  506. XXour_int_21    endp
  507. SHAR_EOF
  508. if test 2417 -ne "`wc -c < 'kludge.asm'`"
  509. then
  510. echo shar: error transmitting "'kludge.asm'" '(should have been 2417 characters)'
  511. fi
  512. fi # end of overwriting check
  513. echo shar: extracting "'scsi.asm'" '(14291 characters)'
  514. if test -f 'scsi.asm'
  515. then
  516. echo shar: will not over-write existing file "'scsi.asm'"
  517. else
  518. sed 's/^XX//' > 'scsi.asm' << \SHAR_EOF
  519. XX;
  520. XX; Simple SCSI Device Driver
  521. XX;
  522. XX        PAGE    76,132
  523. XX
  524. XX        INCLUDE    options.inc
  525. XX        INCLUDE    equ.inc
  526. XX        INCLUDE    struct.inc
  527. XX
  528. XX        ife oldcode
  529. XX        .286
  530. XX        else
  531. XX        .8086
  532. XXpusha        macro
  533. XX        push    ax
  534. XX        push    bx
  535. XX        push    cx
  536. XX        push    dx
  537. XX        push    si
  538. XX        push    di
  539. XX        endm
  540. XX
  541. XXpopa        macro
  542. XX        pop    di
  543. XX        pop    si
  544. XX        pop    dx
  545. XX        pop    cx
  546. XX        pop    bx
  547. XX        pop    ax
  548. XX        endm
  549. XX        endif
  550. XX
  551. XX;
  552. XX; Start of Code and Data
  553. XX;
  554. XX_TEXT        segment    word public 'CODE'
  555. XX        assume    cs:_TEXT, ds:_TEXT, es:_TEXT
  556. XX
  557. XX        org    0
  558. XX
  559. XX;
  560. XX; Device Header Required By DOS
  561. XX;
  562. XXscsi:
  563. XXtape_link_ofs    dw    disk_link_ofs    ;Forward Link
  564. XXtape_link_seg    dw    -1
  565. XX        dw    0C800h        ;Char Device
  566. XX        dw    tape_strategy    ;Address of 1st DOS Call
  567. XX        dw    dev_interrupt    ;Address of 2nd DOS Call
  568. XX        db    'SCSITAPE'    ;Device Name
  569. XX
  570. XXdisk_link_ofs    dw    -1        ;Forward Link
  571. XXdisk_link_seg    dw    -1
  572. XX        if large_drives
  573. XX        dw    06042h        ;Ioctl R/W, Block Device, Non-IBM, Get/Set, 32 bit
  574. XX        else
  575. XX        dw    06040h        ;Ioctl R/W, Block Device, Non-IBM, Get/Set
  576. XX        endif
  577. XX        dw    disk_strategy    ;Address of 1st DOS Call
  578. XX        dw    dev_interrupt    ;Address of 2nd DOS Call
  579. XXdisk_count    db    0        ;Number of Disks Present
  580. XX        db    7 dup(?)
  581. XX
  582. XX;
  583. XX; Work Space For Our Device Driver
  584. XX;
  585. XX        even
  586. XXrh_off        dw    ?        ;Request Header Offset
  587. XXrh_seg        dw    ?        ;Request Header Segment
  588. XXrh_type        db    ?        ;Request Type
  589. XX
  590. XXwrite_flag    db    FALSE        ;TRUE When Tape Write Seen
  591. XXread_flag    db    FALSE        ;TRUE When Tape Read Seen
  592. XXerror_flag    db    FALSE        ;TRUE When Tape Error Seen
  593. XXload_flag    db    TRUE        ;TRUE When Tape should Load/Unload
  594. XXcur_drive    db    -1
  595. XXvol_id        db    'NO NAME    ',0
  596. XX
  597. XX;
  598. XX; The Original INT 24 Vector
  599. XX;
  600. XXvect_int_24    equ    word ptr 4 * 24h
  601. XXorig_int_24    dd    ?            ;Original INT 24 Vector
  602. XX
  603. XX;
  604. XX; Define our own personal Stack
  605. XX;
  606. XX        even
  607. XXnew_stack    db    STACK_SIZE-2 dup (?)    ;Our Local Stack
  608. XXnew_stack_top    dw    ?
  609. XX
  610. XXstack_ptr    dw    ?            ;Old Stack Pointer
  611. XXstack_seg    dw    ?            ;Old Stack Segment
  612. XX
  613. XX;
  614. XX; Command Table
  615. XX;
  616. XXcmdtab        label    byte        ;* = Char Only Devices
  617. XX        dw    INITIALIZATION    ;Initialization
  618. XX        dw    MEDIA_CHECK    ;Media Check (Block Only)
  619. XX        dw    GET_BPB        ;Build BPB (Block Only)
  620. XX        dw    unknown        ;IOCTL Read
  621. XX        dw    READ        ;Read Data
  622. XX        dw    done        ;*Non Destructive Read
  623. XX        dw    done        ;*Read Status
  624. XX        dw    done        ;*Flush Read Buffer
  625. XX        dw    WRITE        ;Write Data
  626. XX        dw    WRITE_VERIFY    ;Write With Verify
  627. XX        dw    done        ;*Write Status
  628. XX        dw    done        ;*Flush Write Buffer
  629. XX        dw    WRITE_IOCTL    ;IOCTL Write
  630. XX        dw    OPEN_DEV    ;Device Open
  631. XX        dw    CLOSE_DEV    ;Device Close
  632. XX        dw    done        ;Removable Check
  633. XX        dw    unknown        ;*Write Until Busy
  634. XX        dw    unknown        ;Unknown Call
  635. XX        dw    unknown        ;Unknown Call
  636. XX        dw    IOCTL        ;Generic Ioctl
  637. XX        dw    unknown        ;Unknown Call
  638. XX        dw    unknown        ;Unknown Call
  639. XX        dw    unknown        ;Unknown Call
  640. XX        dw    GET_DEV        ;Get Device
  641. XX        dw    SET_DEV        ;Set Device
  642. XX
  643. XX;
  644. XX; Int 24 (Fatal Error Handler)
  645. XX;
  646. XX; The test for our tape device only works because the
  647. XX; device header for the tape is located at the start
  648. XX; of the driver binary.
  649. XX;
  650. XXour_int_24    proc    far
  651. XX        push    ax
  652. XX        mov    ax,cs        ;Is it our Segment
  653. XX        cmp    bp,ax
  654. XX        jnz    not_our_tape
  655. XX        cmp    si,0        ;Is it the Tape Device
  656. XX        jnz    not_our_tape
  657. XX        pop    ax
  658. XX        mov    al,3        ;Fail the System Call
  659. XX        iret
  660. XXnot_our_tape:    pop    ax
  661. XX        jmp    cs:orig_int_24    ;Pass the Request On
  662. XXour_int_24    endp
  663. XX
  664. XX;
  665. XX; Strategy Procedure
  666. XX;
  667. XXdisk_strategy    proc    far
  668. XX        mov    cs:rh_seg,es        ;Save Request Header Ptr Segment
  669. XX        mov    cs:rh_off,bx        ;Save Request Header Ptr Offset
  670. XX        mov    cs:rh_type,DISK_REQUEST
  671. XX        ret
  672. XXdisk_strategy    endp
  673. XX
  674. XXtape_strategy    proc    far
  675. XX        mov    cs:rh_seg,es        ;Save Request Header Ptr Segment
  676. XX        mov    cs:rh_off,bx        ;Save Request Header Ptr Offset
  677. XX        mov    cs:rh_type,TAPE_REQUEST
  678. XX        ret
  679. XXtape_strategy    endp
  680. XX
  681. XX;
  682. XX; Interrupt Procedure
  683. XX;
  684. XXdev_interrupt    proc    far
  685. XX        pushf                ;Save Machine State On Entry
  686. XX        cli
  687. XX        push    ds
  688. XX        push    es
  689. XX        push    ax
  690. XX        push    bx
  691. XX        push    cx
  692. XX        push    dx
  693. XX        push    si
  694. XX        push    di
  695. XX        push    bp
  696. XX
  697. XX        mov    cs:stack_seg,ss        ;Save Old Stack
  698. XX        mov    cs:stack_ptr,sp
  699. XX
  700. XX        mov    ax,cs            ;Save us the Segment Override Crap
  701. XX        mov    ds,ax
  702. XX        mov    es,ax
  703. XX
  704. XX        mov    ss,ax            ;Setup Our Local Stack
  705. XX        lea    ax,new_stack_top
  706. XX        mov    sp,ax
  707. XX        sti                ;We're Safe Now
  708. XX
  709. XX;
  710. XX; Perform branch based on the command passed in the Request Header
  711. XX;
  712. XX        mov    es,rh_seg        ;Point us at the Request Header
  713. XX        mov    bx,rh_off
  714. XX
  715. XX        mov    al,es:[bx].rh_cmd    ;Get Command Code
  716. XX        rol    al,1            ;Get offset into table
  717. XX        lea    di,cmdtab        ;Get address of command table
  718. XX        mov    ah,0            ;Clear hi order byte
  719. XX        add    di,ax            ;Add offset
  720. XX        jmp    word ptr [di]        ;Jump Indirect
  721. XX
  722. XX;
  723. XX; Command Procedures
  724. XX;
  725. XXINITIALIZATION:    cmp    rh_type,TAPE_REQUEST    ;Is this SCSITAPE: Init?
  726. XX        jz    init_skip
  727. XX        mov    al,es:[bx].rh0_drv_ltr    ;Save the starting Drive
  728. XX        add    al,041h
  729. XX        mov    cur_drive,al
  730. XX        call    initial            ;Setup
  731. XX        if use_kludge
  732. XX        call    patch_us_in
  733. XX        endif
  734. XX        mov    bx,rh_off
  735. XX        mov    es,rh_seg
  736. XXinit_skip:    lea    ax,initial        ;Set The Break Address
  737. XX        mov    es:[bx].rh0_brk_ofs,ax
  738. XX        mov    es:[bx].rh0_brk_seg,cs
  739. XX        mov    al,disk_count        ;Number of Disk Devices Supported
  740. XX        mov    es:[bx].rh0_nunits,al
  741. XX        lea    dx,bpb_array        ;BPB Array
  742. XX        mov    es:[bx].rh0_bpb_tbo,dx
  743. XX        mov    es:[bx].rh0_bpb_tbs,cs
  744. XX        jmp    done
  745. XX
  746. XX;
  747. XX; Has the Media Changed
  748. XX;
  749. XXMEDIA_CHECK:    call    find_unit
  750. XX        jc    mc_jmp_err
  751. XX        mov    di,cur_unit
  752. XX        mov    al,[di].unit_mcheck    ;Get Initial Status
  753. XX        mov    [di].unit_mcheck,1    ;Always OK from then on
  754. XX        mov    es:[bx].rh1_md_stat,al
  755. XX        lea    dx,vol_id        ;Address of Volume ID
  756. XX        mov    es:[bx].rh1_volid_ofs,dx
  757. XX        mov    es:[bx].rh1_volid_seg,cs
  758. XX        jmp    done
  759. XXmc_jmp_err:    jmp    bad_unit
  760. XX
  761. XX;
  762. XX; Get Disk Parameter Block
  763. XX;
  764. XXGET_BPB:    call    find_unit
  765. XX        jc    get_jmp_err
  766. XX        mov    dx,cur_bpb        ;Address of BPB
  767. XX        mov    es:[bx].rh2_pbpbo,dx
  768. XX        mov    es:[bx].rh2_pbpbs,cs
  769. XX        jmp    done
  770. XXget_jmp_err:    jmp    bad_unit
  771. XX
  772. XX;
  773. XX; Read some data from the disk/tape
  774. XX;
  775. XXREAD:        cmp    rh_type,DISK_REQUEST
  776. XX        jz    read_a_disk
  777. XX        mov    ax,tape_unit        ;Do We Have a Tape?
  778. XX        cmp    ax,-1
  779. XX        jz    read_jmp_err1
  780. XX        mov    cur_unit,ax
  781. XX        call    tape_read
  782. XX        jc    read_jmp_err2
  783. XX        jmp    done
  784. XXread_a_disk:    call    find_unit
  785. XX        jc    read_jmp_err1
  786. XX        call    disk_read
  787. XX        jc    read_jmp_err2
  788. XX        jmp    done
  789. XXread_jmp_err1:    jmp    bad_unit
  790. XXread_jmp_err2:    jmp    bad_read
  791. XX
  792. XX;
  793. XX; Write some data to the disk/tape
  794. XX;
  795. XXWRITE        equ    $
  796. XXWRITE_VERIFY:    cmp    rh_type,DISK_REQUEST
  797. XX        jz    write_a_disk
  798. XX        mov    ax,tape_unit        ;Do We Have a Tape?
  799. XX        cmp    ax,-1
  800. XX        jz    write_jmp_err1
  801. XX        mov    cur_unit,ax
  802. XX        call    tape_write
  803. XX        jc    write_jmp_err2
  804. XX        jmp    done
  805. XXwrite_a_disk:    call    find_unit
  806. XX        jc    write_jmp_err1
  807. XX        call    disk_write
  808. XX        jc    write_jmp_err2
  809. XX        jmp    done
  810. XXwrite_jmp_err1:    jmp    bad_unit
  811. XXwrite_jmp_err2:    jmp    bad_write
  812. XXwrite_jmp_err3:    jmp    unknown
  813. XX
  814. XX;
  815. XX; Write Ioctl Packet
  816. XX;
  817. XXWRITE_IOCTL:    cmp    rh_type,DISK_REQUEST
  818. XX        jz    ioctl_a_disk
  819. XX        mov    ax,tape_unit            ;Do we have a SCSITAPE?
  820. XX        cmp    ax,-1
  821. XX        jz    write_jmp_err1
  822. XX        mov    cur_unit,ax
  823. XX        jmp    short ioctl_do
  824. XXioctl_a_disk:    call    find_unit
  825. XX        jc    write_jmp_err1
  826. XXioctl_do:    call    scsi_ioctl_write
  827. XX        jc    write_jmp_err3
  828. XX        jmp    done
  829. XX
  830. XX;
  831. XX; Special Control Functions
  832. XX;
  833. XXIOCTL:        call    find_unit
  834. XX        jc    ioctl_jmp_err1
  835. XX        call    scsi_ioctl
  836. XX        jc    ioctl_jmp_err2        ;Must have been a Verify error
  837. XX        jmp    done
  838. XXioctl_jmp_err1:    jmp    bad_unit
  839. XXioctl_jmp_err2:    jmp    bad_read
  840. XX
  841. XX;
  842. XX; Open Tape Device
  843. XX;
  844. XXOPEN_DEV:    mov    di,tape_unit
  845. XX        cmp    di,-1            ;Do We have a SCSITAPE: Unit?
  846. XX        jnz    open_tape
  847. XX        jmp    bad_unit
  848. XXopen_tape:    mov    cur_unit,di            ;New Current Unit
  849. XX        lea    bx,[di].unit_sense        ;Buffer Offset
  850. XX        push    ds                ;Buffer Segment
  851. XX        pop    es
  852. XX        mov    cx,size sense            ;Buffer Size
  853. XX        lea    di,cmd_sense            ;Command
  854. XX        call    docmd
  855. XX        jc    open_err
  856. XX        cmp    load_flag,TRUE            ;Should we LOAD?
  857. XX        jnz    open_ok
  858. XX        ife mini_inquire
  859. XX        mov    di,cur_unit            ;Check Unit Type
  860. XX        mov    ax,word ptr [di].unit_inq_buf.inq_manufact
  861. XX        lea    di,cmd_rewind            ;Default to Rewind
  862. XX        cmp    ax,'ET'                ;If this is a TEAC Unit
  863. XX        jz    open_rewind
  864. XX        endif
  865. XX        lea    di,cmd_load            ;Now Load Tape
  866. XX        mov    [di].load_cmd_type,LOAD_TAPE
  867. XXopen_rewind:    call    docmd
  868. XX        jnc    open_ok
  869. XX        call    scsi_sense
  870. XXopen_err:    jmp    general
  871. XXopen_ok:    mov    write_flag,FALSE        ;No Writes Seen
  872. XX        mov    read_flag,FALSE            ;No Reads Seen
  873. XX        mov    error_flag,FALSE        ;No Error Yet
  874. XX        if use_kludge
  875. XX        mov    opened_flag,TRUE        ;We are Open
  876. XX        endif
  877. XX        mov    ax,0                ;Patch Ourselves into
  878. XX        mov    es,ax                ;the INT 24 Vector
  879. XX        mov    ax,es:[vect_int_24]        ;Offset
  880. XX        mov    word ptr orig_int_24,ax
  881. XX        lea    ax,our_int_24
  882. XX        mov    es:[vect_int_24],ax
  883. XX        mov    ax,es:[vect_int_24+2]        ;Segment
  884. XX        mov    word ptr orig_int_24+2,ax
  885. XX        mov    ax,cs
  886. XX        mov    es:[vect_int_24+2],ax
  887. XX        jmp    done
  888. XX
  889. XX;
  890. XX; Close Tape Device
  891. XX;
  892. XXCLOSE_DEV:    mov    di,tape_unit
  893. XX        cmp    di,-1        ;Do We have a SCSITAPE: Unit?
  894. XX        jnz    close_tape
  895. XX        jmp    bad_unit
  896. XXclose_tape:    mov    ax,0                ;Restore
  897. XX        mov    es,ax                ;the INT 24 Vector
  898. XX        mov    word ptr orig_int_24,ax
  899. XX        mov    es:[vect_int_24],ax        ;Offset
  900. XX        mov    word ptr orig_int_24+2,ax
  901. XX        mov    es:[vect_int_24+2],ax        ;Segment
  902. XX        mov    cur_unit,di            ;New Current Unit
  903. XX        cmp    error_flag,TRUE            ;Any Tape Errors
  904. XX        jz    skip_extras
  905. XX        cmp    write_flag,TRUE            ;Were We Writing?
  906. XX        jnz    not_writing
  907. XX        lea    di,cmd_twritefm            ;End Tape with FM(s)
  908. XX        mov    [di].fm_cmd_cnt_b0,CLOSE_FM_CNT
  909. XX        call    docmd
  910. XX        jnc    skip_extras
  911. XX        call    get_sense
  912. XX        jmp    short skip_extras
  913. XXnot_writing:    cmp    read_flag,TRUE            ;Were We Reading?
  914. XX        jnz    skip_extras
  915. XX        cmp    load_flag,TRUE            ;No Rewind?
  916. XX        jz    skip_extras
  917. XX        lea    di,cmd_space            ;Space Forward
  918. XX        mov    [di].space_cmd_code,1        ;By FileMark
  919. XX        mov    [di].space_cmd_cnt2,0
  920. XX        mov    [di].space_cmd_cnt1,0
  921. XX        mov    [di].space_cmd_cnt0,1
  922. XX        call    docmd
  923. XX        jnc    skip_extras
  924. XX        call    get_sense
  925. XXskip_extras:    cmp    load_flag,TRUE            ;Should we Unload?
  926. XX        jnz    close_ok    
  927. XX        ife mini_inquire
  928. XX        mov    di,cur_unit            ;Check Unit Type
  929. XX        mov    ax,word ptr [di].unit_inq_buf.inq_manufact
  930. XX        lea    di,cmd_rewind
  931. XX        cmp    ax,'ET'                ;Rewind instead of
  932. XX        jz    close_rewind            ;Unload TEAC Unit
  933. XX        endif
  934. XX        lea    di,cmd_load            ;Now Unload Tape
  935. XX        mov    [di].load_cmd_type,UNLOAD_TAPE
  936. XXclose_rewind:    call    docmd
  937. XX        jnc    close_ok
  938. XX        call    scsi_sense
  939. XX        jmp    general
  940. XXclose_ok:    jmp    done
  941. XX
  942. XX;
  943. XX; Get Device Assignment
  944. XX;
  945. XXGET_DEV:    mov    es:[bx].rh_unit,0
  946. XX        jmp    done
  947. XX
  948. XX;
  949. XX; Set Device Assignment
  950. XX;
  951. XXSET_DEV:    jmp    done
  952. XX
  953. XXbad_unit:    mov    es,rh_seg        ;Point us at the Request Header
  954. XX        mov    bx,rh_off
  955. XX        or    es:[bx].rh_status,8001h
  956. XX        jmp    short done
  957. XX
  958. XXunknown:    mov    es,rh_seg        ;Point us at the Request Header
  959. XX        mov    bx,rh_off
  960. XX        or    es:[bx].rh_status,8003h
  961. XX        jmp    short done
  962. XX
  963. XXbad_write:    mov    es,rh_seg        ;Point us at the Request Header
  964. XX        mov    bx,rh_off
  965. XX        or    es:[bx].rh_status,800Ah
  966. XX        jmp    short done
  967. XX
  968. XXbad_read:    mov    es,rh_seg        ;Point us at the Request Header
  969. XX        mov    bx,rh_off
  970. XX        or    es:[bx].rh_status,800Bh
  971. XX        jmp    short done
  972. XX
  973. XXgeneral:    mov    es,rh_seg        ;Point us at the Request Header
  974. XX        mov    bx,rh_off
  975. XX        or    es:[bx].rh_status,800Ch
  976. XX        jmp    short done
  977. XX
  978. XXbusy:        mov    es,rh_seg        ;Point us at the Request Header
  979. XX        mov    bx,rh_off
  980. XX        or    es:[bx].rh_status,0200h
  981. XX
  982. XXdone:        mov    es,rh_seg        ;Point us at the Request Header
  983. XX        mov    bx,rh_off
  984. XX        or    es:[bx].rh_status,0100h
  985. XX
  986. XX        cli                ;Make sure we're left alone
  987. XX        mov    ax,cs:stack_seg        ;Restore DOS Stack
  988. XX        mov    ss,ax
  989. XX        mov    ax,cs:stack_ptr
  990. XX        mov    sp,ax
  991. XX
  992. XX        pop    bp            ;Restore All Registers
  993. XX        pop    di
  994. XX        pop    si
  995. XX        pop    dx
  996. XX        pop    cx
  997. XX        pop    bx
  998. XX        pop    ax
  999. XX        pop    es
  1000. XX        pop    ds
  1001. XX        popf
  1002. XX        ret
  1003. XX
  1004. XX        INCLUDE    units.asm
  1005. XX        INCLUDE    subs.asm
  1006. XX        INCLUDE    ioctl.asm
  1007. XX        INCLUDE    dump.asm
  1008. XX        if use_kludge
  1009. XX        INCLUDE    kludge.asm
  1010. XX        endif
  1011. XX
  1012. XX;
  1013. XX; End of Program
  1014. XX; Stuff Placed Here Gets Handed Back To DOS For Re-use
  1015. XX;
  1016. XXinitial        proc    near
  1017. XX        lea    dx,hello_msg        ;Tell them the driver version
  1018. XX        call    puts
  1019. XX        push    cs
  1020. XX        pop    dx
  1021. XX        lea    bx,seg_msg_value
  1022. XX        call    hex2asc4
  1023. XX        lea    dx,seg_msg        ;And Were We Loaded
  1024. XX        call    puts
  1025. XX
  1026. XX        call    scsi_reset        ;Reset the bus
  1027. XX
  1028. XX        mov    cx,0            ;Scan for devices
  1029. XXscan:        mov    ax,cx
  1030. XX        add    al,030h
  1031. XX        mov    scan_dev,al
  1032. XX        mov    ax,1            ;Create Select Bit
  1033. XX        shl    ax,cl
  1034. XX        mov    di,cur_unit
  1035. XX        mov    [di].unit_select,al
  1036. XX        mov    [di].unit_num_drv,0    ;No Drives to start with
  1037. XX        mov    al,disk_count        ;We will start with
  1038. XX        mov    [di].unit_1st_drv,al    ;Drive Number if any
  1039. XX
  1040. XX        lea    dx,scan_dev        ;Print the device number
  1041. XX        call    puts
  1042. XX        call    scsi_inquire        ;Inquire as to its type
  1043. XX        jnc    scan_inq_ok
  1044. XX
  1045. XX        lea    dx,no_dev        ;If the error was
  1046. XX        cmp    al,CNOCONNECT        ;'No Such Device'
  1047. XX        jz    puts_jmp
  1048. XX
  1049. XX        lea    dx,dumb_disk_msg    ;Assume it is a 'SCSI I'
  1050. XX        jmp    short scan_is_drv    ;Old style disk
  1051. XX
  1052. XXscan_inq_ok:    mov    di,cur_unit
  1053. XX        if mini_inquire
  1054. XX        lea    dx,disk_dev_msg
  1055. XX        else
  1056. XX        lea    dx,[di].unit_inq_buf.inq_manufact
  1057. XX        mov    [di].unit_inq_term,'$'
  1058. XX        endif
  1059. XX        mov    al,[di].unit_inq_buf.inq_dev_type
  1060. XX        or    al,al            ;Look at device type
  1061. XX        jz    scan_is_drv
  1062. XX        if mini_inquire
  1063. XX        lea    dx,tape_dev_msg
  1064. XX        endif
  1065. XX        cmp    tape_unit,-1        ;Do We Already Have A Tape?
  1066. XX        jnz    puts_jmp
  1067. XX        call    puts            ;Make this our SCSITAPE: Unit
  1068. XX        mov    tape_unit,di
  1069. XX        lea    dx,tape_msg
  1070. XXputs_jmp:    jmp    scan_puts
  1071. XX
  1072. XXscan_is_drv:    call    puts            ;Output the Device String
  1073. XX        call    scsi_capacity        ;Inquire as to its size
  1074. XX        lea    dx,err_size
  1075. XX        jc    scan_puts        ;Do not use unknown drives
  1076. XX        lea    dx,crlf
  1077. XX        call    puts
  1078. XX
  1079. XXscan_next_drv:    mov    di,cur_unit
  1080. XX        mov    al,disk_count        ;Number Of Drives Found
  1081. XX        inc    al
  1082. XX        mov    disk_count,al
  1083. XX        mov    al,[di].unit_num_drv    ;We have a valid Drive
  1084. XX        inc    al
  1085. XX        mov    [di].unit_num_drv,al
  1086. XX        mov    al,cur_drive        ;Get Current Drive Letter
  1087. XX        mov    drv_msg_let,al        ;Insert it in message
  1088. XX        inc    al            ;Bump Drive Letter
  1089. XX        mov    cur_drive,al
  1090. XX        call    make_bpb        ;Setup the BPB for this drive
  1091. XX        mov    di,cur_bpb        ;Current Working BPB
  1092. XX        if large_drives
  1093. XX        mov    dx,[di].bpb_ts_msw
  1094. XX        mov    ax,[di].bpb_ts_lsw
  1095. XX        else
  1096. XX        mov    dx,0
  1097. XX        mov    ax,[di].bpb_ts
  1098. XX        endif
  1099. XX        mov    bx,2048
  1100. XX        div    bx
  1101. XX        inc    ax
  1102. XX        lea    bx,drv_msg_size
  1103. XX        call    bin_ascii
  1104. XX        mov    bx,bpb_hw_mark        ;Get the BPB High Water Mark
  1105. XX        inc    bx            ;Bump HW Mark for next time
  1106. XX        inc    bx
  1107. XX        mov    ax,[bx]            ;Get the BPB
  1108. XX        mov    cur_bpb,ax        ;Make it the current BPB
  1109. XX        mov    bpb_hw_mark,bx
  1110. XX        lea    dx,drv_msg
  1111. XX        call    puts
  1112. XX        ife large_drives
  1113. XX        mov    bx,cur_unit
  1114. XX        mov    ah,0
  1115. XX        mov    al,[bx].unit_num_drv    ;Insert Drive Offset
  1116. XX        dec    al            ;Into BPB for this Drive
  1117. XX        mov    [di].bpb_hs_msw,ax
  1118. XX        mov    al,[bx].unit_cap_buf.cap_sectors_b3
  1119. XX        or    al,[bx].unit_cap_buf.cap_sectors_b2
  1120. XX        or    al,[bx].unit_cap_buf.cap_sectors_b1
  1121. XX        or    al,[bx].unit_cap_buf.cap_sectors_b0
  1122. XX        jnz    scan_next_drv        ;Room left for another Drive
  1123. XX        endif
  1124. XX        jmp    short scan_next
  1125. XX
  1126. XXscan_puts:    call    puts
  1127. XX        lea    dx,crlf
  1128. XX        call    puts
  1129. XX
  1130. XXscan_next:    inc    cx
  1131. XX        cmp    cx,MAXUNIT    ;End of devices?
  1132. XX        jg    scan_exit
  1133. XX        mov    bx,cx        ;Bump to next unit
  1134. XX        shl    bx,1
  1135. XX        mov    ax,word ptr unit_array[bx]
  1136. XX        mov    cur_unit,ax
  1137. XX        jmp    scan
  1138. XX
  1139. XXscan_exit:    lea    dx,crlf
  1140. XX        call    puts
  1141. XX        ret
  1142. XXinitial        endp
  1143. XX
  1144. XX;
  1145. XX; Data Area Used Only During Initialization
  1146. XX;
  1147. XXhello_msg    db    0dh,0ah,'SCSI Device Driver Version 2.0, '
  1148. XX        if oldcode
  1149. XX        db    '8086 Flavor',0Dh,0Ah,'$'
  1150. XX        else
  1151. XX        db    '80286 Flavor',0Dh,0Ah,'$'
  1152. XX        endif
  1153. XXseg_msg        db    'Driver Loaded At Segment '
  1154. XXseg_msg_value    db    '0000',0dh,0ah,'$'
  1155. XXscan_dev    db    'X - ','$'
  1156. XXno_dev        db    '(No Installed Device)$'
  1157. XXerr_size    db    '(Unknown Size)$'
  1158. XXdrv_msg        db    '  - Drive '
  1159. XXdrv_msg_let    db    'X: '
  1160. XXdrv_msg_size    db    'XXXXXX Meg',0dh,0ah,'$'
  1161. XXtape_msg    db    0dh,0ah,'  - Is The SCSITAPE: Device$'
  1162. XXdumb_disk_msg    db    'UNKNOWN DUMB DISK $'
  1163. XXcrlf        db    0dh,0ah,'$'
  1164. XX        if mini_inquire
  1165. XXdisk_dev_msg    db    'Disk Device $'
  1166. XXtape_dev_msg    db    'Tape Device $'
  1167. XX        endif
  1168. XX
  1169. XX
  1170. XXdev_interrupt    endp
  1171. XX_TEXT        ends
  1172. XX        end
  1173. SHAR_EOF
  1174. if test 14291 -ne "`wc -c < 'scsi.asm'`"
  1175. then
  1176. echo shar: error transmitting "'scsi.asm'" '(should have been 14291 characters)'
  1177. fi
  1178. fi # end of overwriting check
  1179. echo shar: extracting "'subs.asm'" '(22277 characters)'
  1180. if test -f 'subs.asm'
  1181. then
  1182. echo shar: will not over-write existing file "'subs.asm'"
  1183. else
  1184. sed 's/^XX//' > 'subs.asm' << \SHAR_EOF
  1185. XX;
  1186. XX; Data storage for local subroutines
  1187. XX;
  1188. XXcmd_ready    db    SCSI_TESTREADY,0,0,0,0,0
  1189. XXcmd_rewind    db    SCSI_REWIND,0,0,0,0,0
  1190. XXcmd_sense    db    SCSI_REQSENSE,0,0,0,size sense,0
  1191. XXcmd_e_sense    db    SCSI_REQSENSE,0,0,0,size e_sense,0
  1192. XXcmd_format    db    SCSI_FORMATUNIT,FORMAT_NORMAL,0,0,0,0
  1193. XXcmd_remap    db    SCSI_REASSIGN,0,0,0,0,0
  1194. XXcmd_space    db    SCSI_SPACE,1,0,0,0,0
  1195. XX        if extended_io
  1196. XXcmd_read    db    SCSI_READBLK,0,0,0,0,0,0,0,1,0
  1197. XXcmd_write    db    SCSI_WRITEBLK,0,0,0,0,0,0,0,1,0
  1198. XX        else
  1199. XXcmd_read    db    SCSI_READBLK,0,0,0,1,0
  1200. XXcmd_write    db    SCSI_WRITEBLK,0,0,0,1,0
  1201. XX        endif
  1202. XXcmd_tread    db    SCSI_READBLK,1,0,0,0,0
  1203. XXcmd_twrite    db    SCSI_WRITEBLK,1,0,0,0,0
  1204. XXcmd_twritefm    db    SCSI_WRITEFM,0,0,0,CLOSE_FM_CNT,0
  1205. XXcmd_inquire    db    SCSI_INQUIRY,0,0,0,size inq,0
  1206. XXcmd_erase    db    SCSI_ERASE,1,0,0,0,0
  1207. XXcmd_load    db    SCSI_LOAD,0,0,0,0,0
  1208. XXcmd_capacity    db    SCSI_READSIZE,0,0,0,0,0,0,0,0,0
  1209. XXcmd_verify    db    SCSI_VERIFYBLK,0,0,0,0,0,0,0,SECT_TRACK,0
  1210. XX
  1211. XX        if large_drives
  1212. XX        even
  1213. XXlsect_lsw    dw    ?
  1214. XXlsect_msw    dw    ?
  1215. XX        endif
  1216. XX
  1217. XX        even
  1218. XXdocmd_cmd    dw    ?
  1219. XXdocmd_buf    dw    ?
  1220. XXdocmd_buf_seg    dw    ?
  1221. XXdocmd_len    dw    ?
  1222. XXdocmd_ustatus    db    ?
  1223. XXdocmd_estatus    db    ?
  1224. XXdocmd_message    db    ?
  1225. XX
  1226. XXsense_ustatus    db    ?
  1227. XXsense_estatus    db    ?
  1228. XXsense_message    db    ?
  1229. XX
  1230. XXretry_cnt    db    ?
  1231. XX
  1232. XX        if dump_sense
  1233. XXsense_msg1    db    0dh,07h,'Unit '
  1234. XXsense_unit    db    'xxh, Err '
  1235. XXsense_err    db    'xxh, Stat '
  1236. XXsense_ustat    db    'xxh, Msg '
  1237. XXsense_msg    db    'xxh, Retry '
  1238. XXsense_retry    db    'xxh$'
  1239. XXsense_msg2    db    ', Sense '
  1240. XXsense_code    db    'xxh, Addr '
  1241. XXsense_addr3    db    'xx'
  1242. XXsense_addr2    db    'xx'
  1243. XXsense_addr1    db    'xx'
  1244. XXsense_addr0    db    'xxh$'
  1245. XX        ife monitor
  1246. XXsense_msg3    db    0dh,0ah,'$'
  1247. XX        endif
  1248. XX        endif
  1249. XX
  1250. XX;
  1251. XX; Reset the SCSI Bus
  1252. XX;
  1253. XXscsi_reset    proc    near
  1254. XX        pusha
  1255. XX
  1256. XX        mov    ax,SCSI_CARD_SEG    ;Point at the command port
  1257. XX        mov    es,ax
  1258. XX        mov    si,SCSI_CMD_PORT
  1259. XX
  1260. XX        mov    byte ptr es:[si],CMDBASE or CMDRST
  1261. XX        call    wait100us
  1262. XX        mov    byte ptr es:[si],CMDBASE
  1263. XX        call    wait100us
  1264. XX
  1265. XX        popa
  1266. XX        ret
  1267. XXscsi_reset    endp
  1268. XX
  1269. XX;
  1270. XX; Request Sense data from a unit and display the result
  1271. XX; Called after every SCSI command with the exit code in 'al'
  1272. XX;
  1273. XXscsi_sense    proc    near
  1274. XX        pushf
  1275. XX        pusha
  1276. XX        push    es
  1277. XX
  1278. XX        if dump_sense
  1279. XX;
  1280. XX; Print out the first part even if we can't retrieve any sense status
  1281. XX;
  1282. XX        mov    al,docmd_estatus    ;Save for printing
  1283. XX        mov    sense_estatus,al
  1284. XX        mov    al,docmd_ustatus
  1285. XX        mov    sense_ustatus,al
  1286. XX        mov    al,docmd_message
  1287. XX        mov    sense_message,al
  1288. XX        mov    di,cur_unit
  1289. XX        mov    dl,[di].unit_select
  1290. XX        lea    bx,sense_unit        ;Unit
  1291. XX        call    hex2asc2
  1292. XX        mov    dl,sense_estatus    ;Error (from docmd)
  1293. XX        lea    bx,sense_err
  1294. XX        call    hex2asc2
  1295. XX        mov    dl,sense_ustatus    ;Status (from unit)
  1296. XX        lea    bx,sense_ustat
  1297. XX        call    hex2asc2
  1298. XX        mov    dl,sense_message    ;Msg (from unit)
  1299. XX        lea    bx,sense_msg
  1300. XX        call    hex2asc2
  1301. XX        mov    dl,retry_cnt        ;Retry
  1302. XX        lea    bx,sense_retry
  1303. XX        call    hex2asc2
  1304. XX        lea    dx,sense_msg1
  1305. XX        call    puts
  1306. XX        endif
  1307. XX
  1308. XX;
  1309. XX; Try to retrieve sense status
  1310. XX;
  1311. XX        mov    di,cur_unit            ;Unit
  1312. XX        lea    bx,[di].unit_sense        ;Buffer Offset
  1313. XX        mov    cx,size sense            ;Buffer Size
  1314. XX        lea    dx,cmd_sense            ;Command
  1315. XX        cmp    [di].unit_sense.sense_sense,SENSE_CCS
  1316. XX        jnz    no_e_sense
  1317. XX        lea    bx,[di].unit_e_sense        ;Buffer Offset
  1318. XX        mov    cx,size e_sense            ;Buffer Size
  1319. XX        lea    dx,cmd_e_sense            ;Command
  1320. XXno_e_sense:    push    ds                ;Buffer Segment
  1321. XX        pop    es
  1322. XX        mov    di,dx
  1323. XX        call    docmd
  1324. XX
  1325. XX        if dump_sense
  1326. XX;
  1327. XX; If we got something, print it
  1328. XX;
  1329. XX        jnc    sense_dump
  1330. XX        jmp    sense_exit
  1331. XX
  1332. XXsense_dump:    mov    di,cur_unit
  1333. XX        cmp    [di].unit_sense.sense_sense,SENSE_CCS
  1334. XX        jz    dump_e_sense
  1335. XX
  1336. XX        mov    dl,[di].unit_sense.sense_sense
  1337. XX        lea    bx,sense_code        ;Sense
  1338. XX        call    hex2asc2
  1339. XX        mov    dl,0
  1340. XX        lea    bx,sense_addr3
  1341. XX        call    hex2asc2
  1342. XX        mov    dl,[di].unit_sense.sense_lba_b2
  1343. XX        lea    bx,sense_addr2
  1344. XX        call    hex2asc2
  1345. XX        mov    dl,[di].unit_sense.sense_lba_b1
  1346. XX        lea    bx,sense_addr1
  1347. XX        call    hex2asc2
  1348. XX        mov    dl,[di].unit_sense.sense_lba_b0
  1349. XX        lea    bx,sense_addr0
  1350. XX        call    hex2asc2
  1351. XX        jmp    short sense_print
  1352. XX
  1353. XXdump_e_sense:    mov    dl,[di].unit_e_sense.e_sense_sense
  1354. XX        lea    bx,sense_code        ;Sense
  1355. XX        call    hex2asc2
  1356. XX        mov    dl,[di].unit_e_sense.e_sense_lba_b3
  1357. XX        lea    bx,sense_addr3        ;Address
  1358. XX        call    hex2asc2
  1359. XX        mov    dl,[di].unit_e_sense.e_sense_lba_b2
  1360. XX        lea    bx,sense_addr2
  1361. XX        call    hex2asc2
  1362. XX        mov    dl,[di].unit_e_sense.e_sense_lba_b1
  1363. XX        lea    bx,sense_addr1
  1364. XX        call    hex2asc2
  1365. XX        mov    dl,[di].unit_e_sense.e_sense_lba_b0
  1366. XX        lea    bx,sense_addr0
  1367. XX        call    hex2asc2
  1368. XX
  1369. XXsense_print:    lea    dx,sense_msg2
  1370. XX        call    puts
  1371. XX        endif
  1372. XX
  1373. XXsense_exit:    if dump_sense
  1374. XX        if monitor
  1375. XX        mov    cx,20000
  1376. XXsense_wait:    call    wait100us
  1377. XX        loop    sense_wait
  1378. XX        else
  1379. XX        lea    dx,sense_msg3        ;Terminate the Message
  1380. XX        call    puts
  1381. XX        endif
  1382. XX        endif
  1383. XX
  1384. XX        pop    es
  1385. XX        popa
  1386. XX        popf
  1387. XX        ret
  1388. XXscsi_sense    endp
  1389. XX
  1390. XX;
  1391. XX; Get the Extended Sense Status from the current Unit
  1392. XX;
  1393. XXget_sense    proc    near
  1394. XX        mov    di,cur_unit            ;Unit
  1395. XX        lea    bx,[di].unit_e_sense        ;Buffer Offset
  1396. XX        push    ds                ;Buffer Segment
  1397. XX        pop    es
  1398. XX        mov    cx,size e_sense            ;Buffer Size
  1399. XX        lea    di,cmd_e_sense            ;Command
  1400. XX        call    docmd                ;Always ask first
  1401. XX        ret
  1402. XXget_sense    endp
  1403. XX
  1404. XX;
  1405. XX; Inquire about the type of a unit
  1406. XX;
  1407. XX; This MUST be the first call to a unit after the reset is done!
  1408. XX;
  1409. XX; al = return code, 'C' error indicates an error
  1410. XX;
  1411. XXscsi_inquire    proc    near
  1412. XX        push    cx
  1413. XX
  1414. XX;
  1415. XX; First thing we should do is wait for the unit to be ready
  1416. XX; as it takes some drives a while to spin up.
  1417. XX;
  1418. XX        mov    retry_cnt,READY_RETRY
  1419. XXready_loop1:    lea    di,cmd_ready        ;Command
  1420. XX        call    docmd
  1421. XX        jnc    unit_is_ready
  1422. XX        cmp    al,CNOCONNECT        ;No such unit?
  1423. XX        jz    ready_error
  1424. XX        push    cx
  1425. XX        mov    cx,10000        ;Wait 1 Second
  1426. XXready_loop2:    call    wait100us
  1427. XX        loop    ready_loop2
  1428. XX        pop    cx
  1429. XX        dec    retry_cnt        ;RETRY Times
  1430. XX        jns    ready_loop1
  1431. XX        jmp    short unit_is_ready    ;Still Try the Inquire
  1432. XXready_error:    stc
  1433. XX        jmp    short inquire_exit
  1434. XX
  1435. XX;
  1436. XX; Then requests its sense status.
  1437. XX; This gives us a chance to find out if the
  1438. XX; device supports the Command Command Set (CCS)
  1439. XX;
  1440. XXunit_is_ready:    call    get_sense
  1441. XX        jc    inquire_exit
  1442. XX
  1443. XX;
  1444. XX; Ok, Now find out what kind of device it is
  1445. XX;
  1446. XX        mov    di,cur_unit            ;Unit
  1447. XX        lea    bx,[di].unit_inq_buf        ;Buffer Offset
  1448. XX        push    ds                ;Buffer Segment
  1449. XX        pop    es
  1450. XX        mov    cx,size inq            ;Buffer Size
  1451. XX        lea    di,cmd_inquire            ;Command
  1452. XX        call    docmd
  1453. XX
  1454. XXinquire_exit:    pop    cx
  1455. XX        ret
  1456. XXscsi_inquire    endp
  1457. XX
  1458. XX;
  1459. XX; Determine the size of a disk
  1460. XX;
  1461. XX; al = return code, 'C' error indicates an error
  1462. XX;
  1463. XXscsi_capacity    proc    near
  1464. XX        push    cx
  1465. XX        mov    retry_cnt,MAX_RETRY
  1466. XX
  1467. XXcapacity_retry:    mov    di,cur_unit            ;Unit
  1468. XX        lea    bx,[di].unit_cap_buf        ;Buffer Offset
  1469. XX        push    ds                ;Buffer Segment
  1470. XX        pop    es
  1471. XX        mov    cx,size cap            ;Buffer Size
  1472. XX        lea    di,cmd_capacity            ;Command
  1473. XX        call    docmd
  1474. XX        jnc    capacity_exit
  1475. XX        call    scsi_sense
  1476. XX        dec    retry_cnt
  1477. XX        jns    capacity_retry
  1478. XX        stc
  1479. XX
  1480. XXcapacity_exit:    pop    cx
  1481. XX        ret
  1482. XXscsi_capacity    endp
  1483. XX
  1484. XX;
  1485. XX; Verify (cx) Sectors starting with (dx:ax)
  1486. XX;
  1487. XX; al = return code, 'C' indicates an error
  1488. XX;
  1489. XX
  1490. XXscsi_verify    proc    near
  1491. XX        mov    retry_cnt,0        ;Don't do retrys
  1492. XX        lea    di,cmd_verify            ;Command
  1493. XX        mov    [di].ver_cmd_lba_b3,dh        ;Insert Sector
  1494. XX        mov    [di].ver_cmd_lba_b2,dl        ; into Command
  1495. XX        mov    [di].ver_cmd_lba_b1,ah        ;Insert Sector
  1496. XX        mov    [di].ver_cmd_lba_b0,al        ; into Command
  1497. XX        mov    [di].ver_cmd_len_b1,ch        ;Insert Length
  1498. XX        mov    [di].ver_cmd_len_b0,cl        ; into Command
  1499. XX        call    docmd
  1500. XX        jnc    verify_exit
  1501. XX        call    scsi_sense
  1502. XX
  1503. XXverify_exit:    ret
  1504. XXscsi_verify    endp
  1505. XX
  1506. XX;
  1507. XX; Read Some Blocks from the disk given
  1508. XX; the request header in es:bx
  1509. XX;
  1510. XX; al = return code, 'C' indicates an error
  1511. XX;
  1512. XXdisk_read    proc    near
  1513. XX        mov    retry_cnt,MAX_RETRY
  1514. XX
  1515. XX        mov    di,bx
  1516. XX        mov    cx,es:[di].rh4_count        ;Sector Count
  1517. XX        if large_drives
  1518. XX        mov    dx,es:[di].rh4_lsect_lsw    ;Starting Sector
  1519. XX        mov    lsect_lsw,dx
  1520. XX        mov    dx,es:[di].rh4_lsect_msw
  1521. XX        mov    lsect_msw,dx
  1522. XX        else
  1523. XX        mov    dx,es:[di].rh4_sector        ;Starting Sector
  1524. XX        endif
  1525. XX        mov    bx,es:[di].rh4_buf_ofs        ;Buffer Offset
  1526. XX        mov    ax,es:[di].rh4_buf_seg        ;Buffer Segment
  1527. XX        mov    es,ax
  1528. XX
  1529. XX        mov    si,cur_bpb
  1530. XX        lea    di,cmd_read            ;Command
  1531. XX        ife large_drives
  1532. XX        mov    ax,[si].bpb_hs_msw        ;Drive Sector Offset
  1533. XX        if extended_io
  1534. XX        mov    [di].io_cmd_lba_b3,ah        ;Insert Sector
  1535. XX        endif
  1536. XX        mov    [di].io_cmd_lba_b2,al        ;Into the Command
  1537. XX        endif
  1538. XX
  1539. XX        if multi_sector
  1540. XX        mov    ax,cx                ;Get Sector Count
  1541. XX        and    ax,CHUNK_MAX-1            ;Mask Off the I/O Chunk
  1542. XX        jnz    disk_r_cok1            ;Check for Boundary
  1543. XX        mov    ax,CHUNK_MAX
  1544. XX        if oldcode
  1545. XXdisk_r_cok1:    shl    ax,1                ;Convert to Buffer Size
  1546. XX        shl    ax,1
  1547. XX        shl    ax,1
  1548. XX        shl    ax,1
  1549. XX        shl    ax,1
  1550. XX        shl    ax,1
  1551. XX        shl    ax,1
  1552. XX        shl    ax,1
  1553. XX        shl    ax,1
  1554. XX        else
  1555. XXdisk_r_cok1:    shl    ax,9                ;Convert to Buffer Size
  1556. XX        endif
  1557. XX        add    ax,bx                ;Check for Wrap
  1558. XX        else
  1559. XX        mov    ax,bx                ;Check for Wrap
  1560. XX        add    ax,P_SECT            ;The First Time
  1561. XX        endif
  1562. XXdisk_r_loop:    jnc    disk_r_nowrap
  1563. XX        mov    ax,bx                ;Normalize the
  1564. XX        if oldcode
  1565. XX        shr    ax,1                ;Segment and
  1566. XX        shr    ax,1
  1567. XX        shr    ax,1
  1568. XX        shr    ax,1
  1569. XX        else
  1570. XX        shr    ax,4                ;Segment and
  1571. XX        endif
  1572. XX        mov    si,es                ;Offset so that
  1573. XX        add    si,ax                ;It dosn't Wrap
  1574. XX        mov    es,si
  1575. XX        and    bx,000Fh
  1576. XXdisk_r_nowrap:    push    cx
  1577. XX        if large_drives
  1578. XX        mov    dx,lsect_msw
  1579. XX        if extended_io
  1580. XX        mov    [di].io_cmd_lba_b3,dh
  1581. XX        mov    [di].io_cmd_lba_b2,dl
  1582. XX        else
  1583. XX        and    dl,01Fh
  1584. XX        mov    [di].io_cmd_lba_b2,dl
  1585. XX        endif
  1586. XX        mov    dx,lsect_lsw
  1587. XX        endif
  1588. XX        mov    [di].io_cmd_lba_b1,dh        ;Insert Sector
  1589. XX        mov    [di].io_cmd_lba_b0,dl        ;Into the Command
  1590. XX        if multi_sector
  1591. XX        and    cx,CHUNK_MAX-1            ;Mask Off the I/O Chunk
  1592. XX        jnz    disk_r_cok2            ;Check for Boundary
  1593. XX        mov    cx,CHUNK_MAX
  1594. XXdisk_r_cok2:
  1595. XX        if extended_io
  1596. XX        mov    [di].io_cmd_cnt_b1,ch        ;Insert Sector Count
  1597. XX        endif
  1598. XX        mov    [di].io_cmd_cnt_b0,cl        ;Into the Command
  1599. XX        if oldcode
  1600. XX        shl    cx,1                ;Convert to Buffer Size
  1601. XX        shl    cx,1
  1602. XX        shl    cx,1
  1603. XX        shl    cx,1
  1604. XX        shl    cx,1
  1605. XX        shl    cx,1
  1606. XX        shl    cx,1
  1607. XX        shl    cx,1
  1608. XX        shl    cx,1
  1609. XX        else
  1610. XX        shl    cx,9                ;Convert to Buffer Size
  1611. XX        endif
  1612. XX        else
  1613. XX        mov    cx,P_SECT            ;Buffer Size
  1614. XX        endif
  1615. XXdisk_r_retry:    call    docmd
  1616. XX        jnc    disk_r_cok3
  1617. XX        call    scsi_sense
  1618. XX        dec    retry_cnt
  1619. XX        jns    disk_r_retry            ;Already Setup
  1620. XX        pop    cx
  1621. XX        stc
  1622. XX        jmp    short disk_r_exit
  1623. XX        if multi_sector
  1624. XXdisk_r_cok3:    pop    cx
  1625. XX        mov    ax,cx                ;Get Sector Count
  1626. XX        and    ax,CHUNK_MAX-1            ;Mask Off the I/O Chunk
  1627. XX        jnz    disk_r_cok4            ;Check for Boundary
  1628. XX        mov    ax,CHUNK_MAX
  1629. XXdisk_r_cok4:    sub    cx,ax                ;Dec Sector Count
  1630. XX        jz    disk_r_exit
  1631. XX        if large_drives
  1632. XX        add    lsect_lsw,ax            ;Bump to next Sector
  1633. XX        adc    lsect_msw,0
  1634. XX        else
  1635. XX        add    dx,ax                ;Bump to next Sector
  1636. XX        endif
  1637. XX        if oldcode
  1638. XX        shl    ax,1                ;Convert to Buffer Size
  1639. XX        shl    ax,1
  1640. XX        shl    ax,1
  1641. XX        shl    ax,1
  1642. XX        shl    ax,1
  1643. XX        shl    ax,1
  1644. XX        shl    ax,1
  1645. XX        shl    ax,1
  1646. XX        shl    ax,1
  1647. XX        else
  1648. XX        shl    ax,9                ;Convert to Buffer Size
  1649. XX        endif
  1650. XX        add    bx,ax
  1651. XX        jmp    disk_r_loop
  1652. XX        else
  1653. XXdisk_r_cok3:    pop    cx
  1654. XX        if large_drives
  1655. XX        add    lsect_lsw,1            ;Bump to next Sector
  1656. XX        adc    lsect_msw,0
  1657. XX        else
  1658. XX        inc    dx                ;Bump to next Sector
  1659. XX        endif
  1660. XX        add    bx,P_SECT
  1661. XX        loop    disk_r_loop
  1662. XX        clc
  1663. XX        endif
  1664. XX
  1665. XXdisk_r_exit:    mov    es,rh_seg
  1666. XX        mov    bx,rh_off
  1667. XX        pushf
  1668. XX        mov    ax,es:[bx].rh4_count        ;Update the Count
  1669. XX        sub    ax,cx
  1670. XX        mov    es:[bx].rh4_count,ax
  1671. XX        popf
  1672. XX        ret
  1673. XXdisk_read    endp
  1674. XX
  1675. XX;
  1676. XX; Write Some Blocks to the disk given
  1677. XX; the request header in es:bx
  1678. XX;
  1679. XX; al = return code, 'C' indicates an error
  1680. XX;
  1681. XXdisk_write    proc    near
  1682. XX        mov    retry_cnt,MAX_RETRY
  1683. XX
  1684. XX        mov    di,bx
  1685. XX        mov    cx,es:[di].rh8_count        ;Sector Count
  1686. XX        if large_drives
  1687. XX        mov    dx,es:[di].rh8_lsect_lsw    ;Starting Sector
  1688. XX        mov    lsect_lsw,dx
  1689. XX        mov    dx,es:[di].rh8_lsect_msw
  1690. XX        mov    lsect_msw,dx
  1691. XX        else
  1692. XX        mov    dx,es:[di].rh8_sector        ;Starting Sector
  1693. XX        endif
  1694. XX        mov    bx,es:[di].rh8_buf_ofs        ;Buffer Offset
  1695. XX        mov    ax,es:[di].rh8_buf_seg        ;Buffer Segment
  1696. XX        mov    es,ax
  1697. XX
  1698. XX        mov    si,cur_bpb
  1699. XX        lea    di,cmd_write            ;Command
  1700. XX        ife large_drives
  1701. XX        mov    ax,[si].bpb_hs_msw        ;Drive Sector Offset
  1702. XX        if extended_io
  1703. XX        mov    [di].io_cmd_lba_b3,ah        ;Insert Sector
  1704. XX        endif
  1705. XX        mov    [di].io_cmd_lba_b2,al        ;Into the Command
  1706. XX        endif
  1707. XX
  1708. XX        if multi_sector
  1709. XX        mov    ax,cx                ;Get Sector Count
  1710. XX        and    ax,CHUNK_MAX-1            ;Mask Off the I/O Chunk
  1711. XX        jnz    disk_w_cok1            ;Check for Boundary
  1712. XX        mov    ax,CHUNK_MAX
  1713. XX        if oldcode
  1714. XXdisk_w_cok1:    shl    ax,1                ;Convert to Buffer Size
  1715. XX        shl    ax,1
  1716. XX        shl    ax,1
  1717. XX        shl    ax,1
  1718. XX        shl    ax,1
  1719. XX        shl    ax,1
  1720. XX        shl    ax,1
  1721. XX        shl    ax,1
  1722. XX        shl    ax,1
  1723. XX        else
  1724. XXdisk_w_cok1:    shl    ax,9                ;Convert to Buffer Size
  1725. XX        endif
  1726. XX        add    ax,bx                ;Check for Wrap
  1727. XX        else
  1728. XX        mov    ax,bx                ;Check for Wrap
  1729. XX        add    ax,P_SECT            ;The First Time
  1730. XX        endif
  1731. XXdisk_w_loop:    jnc    disk_w_nowrap
  1732. XX        mov    ax,bx                ;Normalize the
  1733. XX        if oldcode
  1734. XX        shr    ax,1                ;Segment and
  1735. XX        shr    ax,1
  1736. XX        shr    ax,1
  1737. XX        shr    ax,1
  1738. XX        else
  1739. XX        shr    ax,4                ;Segment and
  1740. XX        endif
  1741. XX        mov    si,es                ;Offset so that
  1742. XX        add    si,ax                ;It dosn't Wrap
  1743. XX        mov    es,si
  1744. XX        and    bx,000Fh
  1745. XXdisk_w_nowrap:    push    cx
  1746. XX        if large_drives
  1747. XX        mov    dx,lsect_msw
  1748. XX        if extended_io
  1749. XX        mov    [di].io_cmd_lba_b3,dh
  1750. XX        mov    [di].io_cmd_lba_b2,dl
  1751. XX        else
  1752. XX        and    dl,01Fh
  1753. XX        mov    [di].io_cmd_lba_b2,dl
  1754. XX        endif
  1755. XX        mov    dx,lsect_lsw
  1756. XX        endif
  1757. XX        mov    [di].io_cmd_lba_b1,dh        ;Insert Sector
  1758. XX        mov    [di].io_cmd_lba_b0,dl        ;Into the Command
  1759. XX        if multi_sector
  1760. XX        and    cx,CHUNK_MAX-1            ;Mask Off the I/O Chunk
  1761. XX        jnz    disk_w_cok2            ;Check for Boundary
  1762. XX        mov    cx,CHUNK_MAX
  1763. XXdisk_w_cok2:
  1764. XX        if extended_io
  1765. XX        mov    [di].io_cmd_cnt_b1,ch        ;Insert Sector Count
  1766. XX        endif
  1767. XX        mov    [di].io_cmd_cnt_b0,cl        ;Into the Command
  1768. XX        if oldcode
  1769. XX        shl    cx,1                ;Convert to Buffer Size
  1770. XX        shl    cx,1
  1771. XX        shl    cx,1
  1772. XX        shl    cx,1
  1773. XX        shl    cx,1
  1774. XX        shl    cx,1
  1775. XX        shl    cx,1
  1776. XX        shl    cx,1
  1777. XX        shl    cx,1
  1778. XX        else
  1779. XX        shl    cx,9                ;Convert to Buffer Size
  1780. XX        endif
  1781. XX        else
  1782. XX        mov    cx,P_SECT            ;Buffer Size
  1783. XX        endif
  1784. XXdisk_w_retry:    call    docmd
  1785. XX        jnc    disk_w_cok3
  1786. XX        call    scsi_sense
  1787. XX        dec    retry_cnt
  1788. XX        jns    disk_w_retry            ;Already Setup
  1789. XX        pop    cx
  1790. XX        stc
  1791. XX        jmp    short disk_w_exit
  1792. XX        if multi_sector
  1793. XXdisk_w_cok3:    pop    cx
  1794. XX        mov    ax,cx                ;Get Sector Count
  1795. XX        and    ax,CHUNK_MAX-1            ;Mask Off the I/O Chunk
  1796. XX        jnz    disk_w_cok4            ;Check for Boundary
  1797. XX        mov    ax,CHUNK_MAX
  1798. XXdisk_w_cok4:    sub    cx,ax                ;Dec Sector Count
  1799. XX        jz    disk_w_exit
  1800. XX        if large_drives
  1801. XX        add    lsect_lsw,ax            ;Bump to next Sector
  1802. XX        adc    lsect_msw,0
  1803. XX        else
  1804. XX        add    dx,ax                ;Bump to next Sector
  1805. XX        endif
  1806. XX        if oldcode
  1807. XX        shl    ax,1                ;Convert to Buffer Size
  1808. XX        shl    ax,1
  1809. XX        shl    ax,1
  1810. XX        shl    ax,1
  1811. XX        shl    ax,1
  1812. XX        shl    ax,1
  1813. XX        shl    ax,1
  1814. XX        shl    ax,1
  1815. XX        shl    ax,1
  1816. XX        else
  1817. XX        shl    ax,9                ;Convert to Buffer Size
  1818. XX        endif
  1819. XX        add    bx,ax
  1820. XX        jmp    disk_w_loop
  1821. XX        else
  1822. XXdisk_w_cok3:    pop    cx
  1823. XX        if large_drives
  1824. XX        add    lsect_lsw,1            ;Bump to next Sector
  1825. XX        adc    lsect_msw,0
  1826. XX        else
  1827. XX        inc    dx                ;Bump to next Sector
  1828. XX        endif
  1829. XX        add    bx,P_SECT
  1830. XX        loop    disk_w_loop
  1831. XX        clc
  1832. XX        endif
  1833. XX
  1834. XXdisk_w_exit:    mov    es,rh_seg
  1835. XX        mov    bx,rh_off
  1836. XX        pushf
  1837. XX        mov    ax,es:[bx].rh8_count        ;Update the Count
  1838. XX        sub    ax,cx
  1839. XX        mov    es:[bx].rh8_count,ax
  1840. XX        popf
  1841. XX        ret
  1842. XXdisk_write    endp
  1843. XX
  1844. XX;
  1845. XX; Read Some Blocks from the Tape
  1846. XX;
  1847. XXtape_read    proc    near
  1848. XX        mov    read_flag,TRUE            ;Data Read from Tape
  1849. XX        mov    di,bx
  1850. XX        mov    cx,es:[di].rh4_count        ;Byte Count
  1851. XX        mov    ax,cx                ;Test for invalid
  1852. XX        and    ax,P_SECT-1            ;Byte Count
  1853. XX        jz    tape_r_valid
  1854. XX        mov    error_flag,TRUE
  1855. XX        mov    es:[di].rh4_count,0        ;Nothing Read
  1856. XX        stc                    ;Oops
  1857. XX        ret
  1858. XXtape_r_valid:    mov    bx,es:[di].rh4_buf_ofs        ;Buffer Offset
  1859. XX        mov    ax,es:[di].rh4_buf_seg        ;Buffer Segment
  1860. XX        mov    es,ax
  1861. XX        mov    ax,bx                ;Normalize the
  1862. XX        if oldcode
  1863. XX        shr    ax,1                ;Segment and
  1864. XX        shr    ax,1
  1865. XX        shr    ax,1
  1866. XX        shr    ax,1
  1867. XX        else
  1868. XX        shr    ax,4                ;Segment and
  1869. XX        endif
  1870. XX        mov    si,es                ;Offset so that
  1871. XX        add    si,ax                ;It dosn't Wrap
  1872. XX        mov    es,si
  1873. XX        and    bx,000Fh
  1874. XX        lea    di,cmd_tread
  1875. XX        mov    ax,cx                ;Convert Bytes
  1876. XX        if oldcode
  1877. XX        shr    ax,1                ;to Blocks
  1878. XX        shr    ax,1
  1879. XX        shr    ax,1
  1880. XX        shr    ax,1
  1881. XX        shr    ax,1
  1882. XX        shr    ax,1
  1883. XX        shr    ax,1
  1884. XX        shr    ax,1
  1885. XX        shr    ax,1
  1886. XX        else
  1887. XX        shr    ax,9                ;to Blocks
  1888. XX        endif
  1889. XX        mov    [di].tio_cmd_cnt_b1,ah        ;Insert into Command
  1890. XX        mov    [di].tio_cmd_cnt_b0,al
  1891. XX        call    docmd
  1892. XX        jnc    tape_r_ok
  1893. XX;
  1894. XX; Get the Extended Sense Status to check for reading FileMark
  1895. XX;
  1896. XX        call    get_sense            ;Get Extended Sense
  1897. XX        jc    tape_r_kaboom
  1898. XX        mov    di,cur_unit            ;Unit
  1899. XX        cmp    [di].unit_e_sense.e_sense_sense,80h
  1900. XX        jnz    tape_r_eom
  1901. XXtape_r_kaboom:    mov    error_flag,TRUE            ;Real Error Occured
  1902. XX        stc
  1903. XX        ret
  1904. XXtape_r_eom:    mov    es,rh_seg
  1905. XX        mov    bx,rh_off
  1906. XX        mov    es:[bx].rh4_count,0        ;Nothing Read
  1907. XX        clc
  1908. XXtape_r_ok:    ret
  1909. XXtape_read    endp
  1910. XX
  1911. XX;
  1912. XX; Write Some Blocks to the Tape
  1913. XX;
  1914. XXtape_write    proc    near
  1915. XX        mov    write_flag,TRUE            ;Data Written to Tape
  1916. XX        mov    di,bx
  1917. XX        mov    cx,es:[di].rh8_count        ;Byte Count
  1918. XX        mov    ax,cx                ;Test for invalid
  1919. XX        and    ax,P_SECT-1            ;Byte Count
  1920. XX        jz    tape_w_valid
  1921. XX        mov    es:[di].rh8_count,0        ;Nothing Written
  1922. XX        mov    error_flag,TRUE            ;ERROR!
  1923. XX        stc                    ;Oops
  1924. XX        ret
  1925. XXtape_w_valid:    mov    cx,es:[di].rh8_count        ;Byte Count
  1926. XX        mov    bx,es:[di].rh8_buf_ofs        ;Buffer Offset
  1927. XX        mov    ax,es:[di].rh8_buf_seg        ;Buffer Segment
  1928. XX        mov    es,ax
  1929. XX        mov    ax,bx                ;Normalize the
  1930. XX        if oldcode
  1931. XX        shr    ax,1                ;Segment and
  1932. XX        shr    ax,1
  1933. XX        shr    ax,1
  1934. XX        shr    ax,1
  1935. XX        else
  1936. XX        shr    ax,4                ;Segment and
  1937. XX        endif
  1938. XX        mov    si,es                ;Offset so that
  1939. XX        add    si,ax                ;It dosn't Wrap
  1940. XX        mov    es,si
  1941. XX        and    bx,000Fh
  1942. XX        lea    di,cmd_twrite
  1943. XX        mov    ax,cx                ;Convert Bytes
  1944. XX        if oldcode
  1945. XX        shr    ax,1                ;to Blocks
  1946. XX        shr    ax,1
  1947. XX        shr    ax,1
  1948. XX        shr    ax,1
  1949. XX        shr    ax,1
  1950. XX        shr    ax,1
  1951. XX        shr    ax,1
  1952. XX        shr    ax,1
  1953. XX        shr    ax,1
  1954. XX        else
  1955. XX        shr    ax,9                ;to Blocks
  1956. XX        endif
  1957. XX        mov    [di].tio_cmd_cnt_b1,ah        ;Insert into Command
  1958. XX        mov    [di].tio_cmd_cnt_b0,al
  1959. XX        call    docmd
  1960. XX        jnc    tape_w_ok
  1961. XX;
  1962. XX; Get the Sense Status and see if we hit EOM.
  1963. XX; This is to allow the FileMark to still be written
  1964. XX; during the close processing.
  1965. XX;
  1966. XX        call    get_sense            ;Get Extended Sense
  1967. XX        jc    tape_w_kaboom
  1968. XX        mov    di,cur_unit            ;Unit
  1969. XX        cmp    [di].unit_e_sense.e_sense_sense,40h
  1970. XX        jz    tape_w_eom
  1971. XXtape_w_kaboom:    mov    error_flag,TRUE            ;Real Error Occured
  1972. XX        mov    es,rh_seg
  1973. XX        mov    bx,rh_off
  1974. XX        mov    es:[bx].rh8_count,0        ;Nothing Written
  1975. XXtape_w_eom:    stc
  1976. XXtape_w_ok:    ret
  1977. XXtape_write    endp
  1978. XX
  1979. XX;
  1980. XX; Do a command
  1981. XX;
  1982. XX; bx = buffer offset
  1983. XX; es = buffer segment
  1984. XX; cx = buffer len
  1985. XX; di => command string
  1986. XX;
  1987. XX; al = return code, 'C' indicates an error
  1988. XX;
  1989. XXdocmd        proc    near
  1990. XX        pusha
  1991. XX        push    es
  1992. XX
  1993. XX        mov    docmd_buf,bx        ;Save our arguments
  1994. XX        mov    docmd_buf_seg,es
  1995. XX        mov    docmd_len,cx
  1996. XX        mov    docmd_cmd,di
  1997. XX        mov    docmd_ustatus,0FFh
  1998. XX
  1999. XX        if monitor
  2000. XX        mov    ax,'F'            ;Arbitrate for Bus
  2001. XX        call    show_phase
  2002. XX        endif
  2003. XX
  2004. XX        mov    ax,SCSI_CARD_SEG    ;Point at the Card
  2005. XX        mov    es,ax
  2006. XX        mov    si,SCSI_CMD_PORT    ;Command Port
  2007. XX        mov    di,SCSI_DATA_PORT    ;Data Port
  2008. XX        mov    bx,cur_unit
  2009. XX        mov    al,[bx].unit_select    ;Get our Select Bit
  2010. XX
  2011. XX        if reserve_addr
  2012. XX;
  2013. XX; Get us control of the BUS by starting Arbitration
  2014. XX; Wait a maximum of 250ms for Control of the Bus
  2015. XX;
  2016. XX        or    al,080h            ;Add our Address
  2017. XX        mov    byte ptr es:[si],CMDBASE
  2018. XX        nop
  2019. XX        mov    byte ptr es:[di],080h    ;Our Address
  2020. XX        nop
  2021. XX        mov    byte ptr es:[si],CMDBASE or CMDSTARB
  2022. XX        mov    cx,2500
  2023. XXarb_loop:    test    byte ptr es:[si],STARBCOMPL
  2024. XX        jnz    try_sel
  2025. XX        call    wait100us
  2026. XX        loop    arb_loop
  2027. XX        else
  2028. XX;
  2029. XX; Wait 250ms for the Bus to become free
  2030. XX;
  2031. XX        mov    cx,2500
  2032. XXidle_loop:    test    byte ptr es:[si],STBSY    ;Busy?
  2033. XX        jz    try_sel
  2034. XX        call    wait100us
  2035. XX        loop    idle_loop
  2036. XX        endif
  2037. XX
  2038. XX        call    scsi_reset
  2039. XX        mov    al,CBUSBUSY        ;Bus still BUSY?
  2040. XX        jmp    docmd_exit
  2041. XX
  2042. XXtry_sel:    mov    byte ptr es:[di],al    ;Select Bit
  2043. XX        nop
  2044. XX        mov    byte ptr es:[si],CMDBASE or CMDENABLE or CMDSEL
  2045. XX
  2046. XX        if monitor
  2047. XX        mov    ax,'S'            ;Select Target
  2048. XX        call    show_phase
  2049. XX        endif
  2050. XX
  2051. XX;
  2052. XX; Wait 250 ms for the Target to be SELected
  2053. XX;
  2054. XX        mov    cx,2500
  2055. XXsel_loop:    test    byte ptr es:[si],STBSY    ;Wait for BSY
  2056. XX        jnz    cmd_xfer
  2057. XX        call    wait100us
  2058. XX        loop    sel_loop
  2059. XX
  2060. XX        if monitor
  2061. XX        mov    ax,'A'            ;Abort Selection
  2062. XX        call    show_phase
  2063. XX        endif
  2064. XX
  2065. XX        mov    byte ptr es:[si],CMDBASE or CMDSEL
  2066. XX        call    wait100us        ;Spec says wait 200us
  2067. XX        call    wait100us        ;to abort selection phase
  2068. XX        test    byte ptr es:[si],STBSY    ;Look one final time
  2069. XX        jnz    cmd_xfer        ;Device did answer
  2070. XX        mov    al,CNOCONNECT        ;Nothing Answered
  2071. XX        jmp    docmd_exit
  2072. XX
  2073. XX;
  2074. XX; Start the Command, (al) contains last known status
  2075. XX;
  2076. XXcmd_xfer:    mov    byte ptr es:[si],CMDBASE or CMDENABLE
  2077. XX        nop
  2078. XXxfer_loop:    mov    al,es:[si]        ;Get Status Byte
  2079. XX        test    al,STBSY        ;Look for BSY bit
  2080. XX        jnz    still_busy
  2081. XX        jmp    xfer_offline
  2082. XX        if scsi_parity
  2083. XXstill_busy:    test    al,STPARERR        ;Parity Error?
  2084. XX        jz    still_good
  2085. XX        jmp    xfer_parerr
  2086. XXstill_good:    test    al,STREQ        ;Request?
  2087. XX        jz    xfer_loop
  2088. XX        else
  2089. XXstill_busy:    test    al,STREQ        ;Request?
  2090. XX        jz    xfer_loop
  2091. XX        endif
  2092. XX
  2093. XX;
  2094. XX; Figure out what type of request it is
  2095. XX;
  2096. XX        and    al,REQ_MASK
  2097. XX        cmp    al,REQ_CMDOUT        ;Is it Command Out?
  2098. XX        jnz    try_dataout
  2099. XX
  2100. XX        if monitor
  2101. XX        mov    ax,'C'            ;Command
  2102. XX        call    show_phase
  2103. XX        endif
  2104. XX
  2105. XX        mov    si,docmd_cmd        ;Get Command Pointer
  2106. XX        movsb                ;Send Byte to Card
  2107. XX        mov    docmd_cmd,si
  2108. XX        mov    si,SCSI_CMD_PORT    ;Restore Command Port
  2109. XX        mov    di,SCSI_DATA_PORT    ;Restore Data Port
  2110. XX        jmp    xfer_loop
  2111. XX
  2112. XXtry_dataout:    cmp    al,REQ_DATAOUT        ;Is it Data Out?
  2113. XX        jnz    try_datain
  2114. XX
  2115. XX        if monitor
  2116. XX        mov    ax,'W'            ;Write
  2117. XX        call    show_phase
  2118. XX        endif
  2119. XX
  2120. XX        mov    bx,si
  2121. XX        mov    cx,docmd_len        ;Get the Data Count
  2122. XX        mov    si,docmd_buf        ;Source Offset
  2123. XX        mov    ds,docmd_buf_seg    ;Source Segment
  2124. XX        cld
  2125. XX
  2126. XXdataout_loop:    test    byte ptr es:[bx],STBSY    ;Must be BUSY
  2127. XX        jz    dataout_exit
  2128. XX        test    byte ptr es:[bx],STREQ    ;Wait for REQ
  2129. XX        jz    dataout_loop
  2130. XX        movsb                ;Transfer a Byte
  2131. XX        dec    di            ;Keep in Valid
  2132. XX        loop    dataout_loop        ;Done Yet?
  2133. XX
  2134. XXdataout_exit:    mov    si,bx            ;Restore the Environment
  2135. XX        mov    ax,cs
  2136. XX        mov    ds,ax
  2137. XX        jmp    xfer_loop
  2138. XX
  2139. XXtry_datain:    cmp    al,REQ_DATAIN        ;Is it Data In?
  2140. XX        jnz    try_statin
  2141. XX
  2142. XX        if monitor
  2143. XX        mov    ax,'R'            ;Read
  2144. XX        call    show_phase
  2145. XX        endif
  2146. XX
  2147. XX        mov    bx,si
  2148. XX        mov    si,di            ;Source Offset
  2149. XX        mov    ax,es
  2150. XX        mov    cx,docmd_len        ;Length
  2151. XX        mov    di,docmd_buf        ;Dest Offset
  2152. XX        mov    es,docmd_buf_seg    ;Dest Segment
  2153. XX        mov    ds,ax            ;Source Segment
  2154. XX        cld
  2155. XX
  2156. XXdatain_loop:    test    byte ptr [bx],STBSY    ;Must be BUSY
  2157. XX        jz    datain_exit
  2158. XX        test    byte ptr [bx],STREQ    ;Wait for REQ
  2159. XX        jz    datain_loop
  2160. XX        movsb                ;Transfer a Byte
  2161. XX        dec    si            ;Keep in Valid
  2162. XX        loop    datain_loop        ;Done Yet?
  2163. XX
  2164. XXdatain_exit:    mov    ax,ds            ;Restore the Environment
  2165. XX        mov    es,ax
  2166. XX        mov    ax,cs
  2167. XX        mov    ds,ax
  2168. XX        mov    di,si
  2169. XX        mov    si,bx
  2170. XX        jmp    xfer_loop
  2171. XX
  2172. XXtry_statin:    cmp    al,REQ_STATIN        ;Is it Status In?
  2173. XX        jnz    try_msgout
  2174. XX
  2175. XX        if monitor
  2176. XX        mov    ax,'s'            ;Status
  2177. XX        call    show_phase
  2178. XX        endif
  2179. XX
  2180. XX        mov    al,es:[di]        ;Get the Status Byte
  2181. XX        mov    docmd_ustatus,al
  2182. XX        jmp    xfer_loop
  2183. XX
  2184. XXtry_msgout:    cmp    al,REQ_MSGOUT        ;Is it Message Out?
  2185. XX        jnz    try_msgin
  2186. XX
  2187. XX        if monitor
  2188. XX        mov    ax,'M'            ;Message Out
  2189. XX        call    show_phase
  2190. XX        endif
  2191. XX
  2192. XX        mov    byte ptr es:[di],MSG_REJECT
  2193. XX        jmp    xfer_loop
  2194. XX
  2195. XXtry_msgin:    cmp    al,REQ_MSGIN        ;Is it Message In?
  2196. XX        jnz    kaboom
  2197. XX
  2198. XX        if monitor
  2199. XX        mov    ax,'m'            ;Message In
  2200. XX        call    show_phase
  2201. XX        endif
  2202. XX
  2203. XX        mov    al,es:[di]        ;Get the MSG Byte
  2204. XX        mov    docmd_message,al    ;And Save it
  2205. XX        cmp    al,MSG_COMPLETE        ;Are We All Done?
  2206. XX        jnz    xfer_error
  2207. XX        cmp    docmd_ustatus,0        ;Did we have an error?
  2208. XX        mov    al,COK            ;Preload OK code
  2209. XX        jz    docmd_exit
  2210. XX        jmp    xfer_error        ;Oops
  2211. XX
  2212. XXkaboom:        call    scsi_reset        ;Reset the BUS
  2213. XX
  2214. XX        if monitor
  2215. XX        mov    ax,'?'            ;Message In
  2216. XX        call    show_phase
  2217. XX        endif
  2218. XX        
  2219. XXxfer_error:    mov    al,CERROR        ;Command Failed with Bad Status
  2220. XX        jmp    short docmd_exit
  2221. XXxfer_offline:    mov    al,COFFLINE        ;Unit went OffLine
  2222. XX        jmp    short docmd_exit
  2223. XXxfer_parerr:    mov    al,CPARERR        ;Parity Error Detected
  2224. XX        jmp    short docmd_exit
  2225. XXxfer_selerr:    mov    al,CSELERR        ;Re-Select?
  2226. XX
  2227. XXdocmd_exit:    mov    docmd_estatus,al
  2228. XX        mov    byte ptr es:[si],CMDBASE
  2229. XX        pop    es
  2230. XX        popa
  2231. XX        mov    al,docmd_estatus
  2232. XX        cmp    al,COK
  2233. XX        jz    docmd_exit_ok
  2234. XX        stc
  2235. XXdocmd_exit_ok:    ret
  2236. XXdocmd        endp
  2237. XX
  2238. XX;
  2239. XX; Wait One Hundred Micros Seconds
  2240. XX;
  2241. XX; The value of 'cx' is computed for an 8 Mhz Clock
  2242. XX;
  2243. XXwait100us    proc    near
  2244. XX        push    cx        ;   (3) = 375ns
  2245. XX        mov    cx,79        ;   (2) = 250ns
  2246. XXwait_u_loop:    loop    wait_u_loop    ;  (10) = 1250ns * X
  2247. XX        pop    cx        ;   (5) = 625ns
  2248. XX        ret            ; (11+) = 1375ns
  2249. XXwait100us    endp
  2250. XX
  2251. XX;
  2252. XX; Monitor the Bus Phase on the Video Screen
  2253. XX;
  2254. XX        if monitor
  2255. XXshow_phase    proc
  2256. XX        push    es
  2257. XX        push    di
  2258. XX        or    ax,VIDEO_COLOR
  2259. XX        mov    di,VIDEO_SEG
  2260. XX        mov    es,di
  2261. XX        mov    di,VIDEO_OFS
  2262. XX        stosw
  2263. XX        pop    di
  2264. XX        pop    es
  2265. XX        ret
  2266. XXshow_phase    endp
  2267. XX        endif
  2268. SHAR_EOF
  2269. if test 22277 -ne "`wc -c < 'subs.asm'`"
  2270. then
  2271. echo shar: error transmitting "'subs.asm'" '(should have been 22277 characters)'
  2272. fi
  2273. fi # end of overwriting check
  2274. echo shar: extracting "'units.asm'" '(3996 characters)'
  2275. if test -f 'units.asm'
  2276. then
  2277. echo shar: will not over-write existing file "'units.asm'"
  2278. else
  2279. sed 's/^XX//' > 'units.asm' << \SHAR_EOF
  2280. XX;
  2281. XX; target information/control structures
  2282. XX;
  2283. XX        even
  2284. XXunit0        db    size unit dup (-1)
  2285. XX        even
  2286. XXunit1        db    size unit dup (-1)
  2287. XX        even
  2288. XXunit2        db    size unit dup (-1)
  2289. XX        even
  2290. XXunit3        db    size unit dup (-1)
  2291. XX        even
  2292. XXunit4        db    size unit dup (-1)
  2293. XX        even
  2294. XXunit5        db    size unit dup (-1)
  2295. XX        even
  2296. XXunit6        db    size unit dup (-1)
  2297. XX        ife reserve_addr
  2298. XX        even
  2299. XXunit7        db    size unit dup (-1)
  2300. XX        endif
  2301. XX
  2302. XX;
  2303. XX; basic BPB array
  2304. XX;
  2305. XX        even
  2306. XXbpb0        db    size bpb dup (-1)
  2307. XX        even
  2308. XXbpb1        db    size bpb dup (-1)
  2309. XX        even
  2310. XXbpb2        db    size bpb dup (-1)
  2311. XX        even
  2312. XXbpb3        db    size bpb dup (-1)
  2313. XX        even
  2314. XXbpb4        db    size bpb dup (-1)
  2315. XX        even
  2316. XXbpb5        db    size bpb dup (-1)
  2317. XX        even
  2318. XXbpb6        db    size bpb dup (-1)
  2319. XX        even
  2320. XXbpb7        db    size bpb dup (-1)
  2321. XX
  2322. XX;
  2323. XX; Additional entries if needed
  2324. XX;
  2325. XX        ife large_drives
  2326. XX        even
  2327. XXbpb8        db    size bpb dup (-1)
  2328. XX        even
  2329. XXbpb9        db    size bpb dup (-1)
  2330. XX        even
  2331. XXbpbA        db    size bpb dup (-1)
  2332. XX        even
  2333. XXbpbB        db    size bpb dup (-1)
  2334. XX        even
  2335. XXbpbC        db    size bpb dup (-1)
  2336. XX        even
  2337. XXbpbD        db    size bpb dup (-1)
  2338. XX        even
  2339. XXbpbE        db    size bpb dup (-1)
  2340. XX        even
  2341. XXbpbF        db    size bpb dup (-1)
  2342. XX        endif
  2343. XX
  2344. XX        even
  2345. XXunit_array    dw    unit0
  2346. XX        dw    unit1
  2347. XX        dw    unit2
  2348. XX        dw    unit3
  2349. XX        dw    unit4
  2350. XX        dw    unit5
  2351. XX        dw    unit6
  2352. XX        ife reserve_addr
  2353. XX        dw    unit7
  2354. XX        endif
  2355. XX
  2356. XX        even
  2357. XXbpb_array    dw    bpb0        ;BPB Array for DOS
  2358. XX        dw    bpb1
  2359. XX        dw    bpb2
  2360. XX        dw    bpb3
  2361. XX        dw    bpb4
  2362. XX        dw    bpb5
  2363. XX        dw    bpb6
  2364. XX        dw    bpb7
  2365. XX        ife large_drives
  2366. XX        dw    bpb8
  2367. XX        dw    bpb9
  2368. XX        dw    bpbA
  2369. XX        dw    bpbB
  2370. XX        dw    bpbC
  2371. XX        dw    bpbD
  2372. XX        dw    bpbE
  2373. XX        dw    bpbF
  2374. XX        endif
  2375. XXbpb_hw_mark    dw    bpb_array
  2376. XX
  2377. XXtape_unit    dw    -1
  2378. XXcur_unit    dw    unit0
  2379. XXcur_bpb        dw    bpb0
  2380. XX
  2381. XX;
  2382. XX; Given the request header in es:bx
  2383. XX; Return a pointer in ds:di to the unit entry
  2384. XX; or 'C' if no such unit exists.
  2385. XX;
  2386. XX; Do not destroy es:bx !!!
  2387. XX;
  2388. XXfind_unit    proc    near
  2389. XX        pusha
  2390. XX        mov    ah,es:[bx].rh_unit    ;What drive did they want
  2391. XX        lea    di,unit_array
  2392. XX        lea    si,bpb_array
  2393. XX        mov    cx,MAXUNIT        ;How many to search
  2394. XXfind_loop:    mov    bx,[di]            ;Point at a unit    
  2395. XX        mov    al,[bx].unit_num_drv    ;Does this SCSI device
  2396. XX        or    al,al            ;Have any Drives Defined?
  2397. XX        jz    find_next
  2398. XX        mov    dh,[bx].unit_1st_drv    ;Get First Drive Number
  2399. XXfind_unit_loop:    cmp    ah,dh            ;Is this the correct drive?
  2400. XX        jz    find_match
  2401. XX        inc    si            ;Bump to next BPB
  2402. XX        inc    si
  2403. XX        ife large_drives
  2404. XX        inc    dh            ;Bump Drive Number
  2405. XX        dec    al            ;Dec Drive count
  2406. XX        jnz    find_unit_loop        ;Try next Drive
  2407. XX        endif
  2408. XX        jmp    short find_next        ;Try next SCSI device
  2409. XXfind_match:    mov    cur_unit,bx        ;Found a match
  2410. XX        mov    ax,[si]
  2411. XX        mov    cur_bpb,ax
  2412. XX        clc
  2413. XX        jmp    find_exit
  2414. XXfind_next:    inc    di
  2415. XX        inc    di
  2416. XX        loop    find_loop
  2417. XX        stc                ;No More units, Error
  2418. XXfind_exit:    popa
  2419. XX        ret
  2420. XXfind_unit    endp
  2421. XX
  2422. XX;
  2423. XX; Given the data in a unit entry,
  2424. XX; create the bpb for the unit.
  2425. XX;
  2426. XXmake_bpb    proc    near
  2427. XX        mov    di,cur_bpb        ;Get the current BPB
  2428. XX        mov    bx,cur_unit        ;Get the current Unit
  2429. XX;
  2430. XX; First the basic stuff
  2431. XX;
  2432. XX        mov    [di].bpb_ss,P_SECT
  2433. XX        mov    [di].bpb_au,CLUSTSIZE
  2434. XX        mov    [di].bpb_rs,1
  2435. XX        mov    [di].bpb_nf,2
  2436. XX        mov    [di].bpb_de,512
  2437. XX        mov    [di].bpb_st,SECT_TRACK
  2438. XX        mov    [di].bpb_nh,1
  2439. XX        mov    [di].bpb_hs_lsw,0
  2440. XX        mov    [di].bpb_hs_msw,0
  2441. XX        mov    [di].bpb_md,0F8h
  2442. XX;
  2443. XX; then the size and fat sectors
  2444. XX;
  2445. XX        mov    dh,[bx].unit_cap_buf.cap_sectors_b3
  2446. XX        mov    dl,[bx].unit_cap_buf.cap_sectors_b2
  2447. XX        mov    ah,[bx].unit_cap_buf.cap_sectors_b1
  2448. XX        mov    al,[bx].unit_cap_buf.cap_sectors_b0
  2449. XX        if large_drives
  2450. XX        mov    [di].bpb_ts,0        ;(32 bit size)
  2451. XX        and    ax,ROUND_CYL        ;Round to nearest Cyl
  2452. XX        mov    [di].bpb_ts_lsw,ax
  2453. XX        mov    [di].bpb_ts_msw,dx
  2454. XX        sub    [di].bpb_ts_lsw,1    ;Make it zero relative
  2455. XX        sbb    [di].bpb_ts_msw,0
  2456. XX        mov    bx,P_SECT        ;Figure out how many
  2457. XX        div    bx            ;sectors it will take
  2458. XX        mov    dx,0            ;to hold the FAT for
  2459. XX        mov    bx,CLUSTSIZE        ;this drive.
  2460. XX        div    bx
  2461. XX        mov    dx,0
  2462. XX        mov    bx,2
  2463. XX        mul    bx
  2464. XX        else
  2465. XX        or    dx,dx
  2466. XX        jz    make_bpb_last        ;Use up the last few sectors
  2467. XX        dec    dx            ;Use up 65536 Sectors
  2468. XX        mov    [bx].unit_cap_buf.cap_sectors_b3,dh
  2469. XX        mov    [bx].unit_cap_buf.cap_sectors_b2,dl
  2470. XX        mov    dx,0            ;Max of 32 Meg
  2471. XX        mov    ax,65535
  2472. XX        jmp    short make_bpb_ts
  2473. XXmake_bpb_last:    mov    [bx].unit_cap_buf.cap_sectors_b1,0
  2474. XX        mov    [bx].unit_cap_buf.cap_sectors_b0,0
  2475. XX        and    ax,ROUND_CYL        ;Round to nearest Cyl
  2476. XX        dec    ax            ;Make it zero relative
  2477. XXmake_bpb_ts:    mov    [di].bpb_ts,ax
  2478. XX        shr    ax,SECT_2_FS
  2479. XX        endif
  2480. XX        inc    ax            ;Allow for round-off
  2481. XX        mov    [di].bpb_fs,ax
  2482. XX        ret
  2483. XXmake_bpb    endp
  2484. SHAR_EOF
  2485. if test 3996 -ne "`wc -c < 'units.asm'`"
  2486. then
  2487. echo shar: error transmitting "'units.asm'" '(should have been 3996 characters)'
  2488. fi
  2489. fi # end of overwriting check
  2490. #
  2491. # End of shell archive
  2492. #
  2493. exit 0
  2494. -- 
  2495. Brian Antoine                   |
  2496. ISC-Bunker Ramo                 |  ...uunet!isc-br!tau-ceti!briana
  2497. Spokane, WA                     |     briana@tau-ceti.isc-br.com
  2498.  
  2499. exit 0 # Just in case...
  2500. -- 
  2501. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  2502. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  2503. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  2504. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  2505.