home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / pc / source / st01driv.lzh / st01.2 < prev   
Encoding:
Text File  |  1990-10-12  |  28.1 KB  |  1,206 lines

  1.  
  2. #!/bin/sh
  3. # This is part 02 of ST01SCSI.12
  4. # ============= struct.inc ==============
  5. if test -f 'struct.inc' -a X"$1" != X"-c"; then
  6.     echo 'x - skipping struct.inc (File already exists)'
  7. else
  8. echo 'x - extracting struct.inc (Text)'
  9. sed 's/^X//' << 'SHAR_EOF' > 'struct.inc' &&
  10. X;
  11. X; Structures for SCSI commands
  12. X;
  13. Xio_cmd        struc
  14. Xio_cmd_op    db    ?        ;Opcode
  15. X        if extended_io
  16. Xio_cmd_lun    db    ?
  17. Xio_cmd_lba_b3    db    ?        ;Logical Block Address
  18. Xio_cmd_lba_b2    db    ?
  19. Xio_cmd_lba_b1    db    ?
  20. Xio_cmd_lba_b0    db    ?
  21. Xio_cmd_dummy1    db    ?
  22. Xio_cmd_cnt_b1    db    ?        ;Block Count
  23. Xio_cmd_cnt_b0    db    ?
  24. Xio_cmd_dummy2    db    ?
  25. X        else
  26. Xio_cmd_lba_b2    db    ?        ;Logical Block Address / Lun
  27. Xio_cmd_lba_b1    db    ?
  28. Xio_cmd_lba_b0    db    ?
  29. Xio_cmd_cnt_b0    db    ?        ;Block Count
  30. Xio_cmd_dummy1    db    ?
  31. X        endif
  32. Xio_cmd        ends
  33. X
  34. Xtio_cmd        struc
  35. Xtio_cmd_op    db    ?        ;Opcode
  36. Xtio_cmd_lun    db    ?        ;Lun
  37. Xtio_cmd_cnt_b2    db    ?        ;Block Count
  38. Xtio_cmd_cnt_b1    db    ?
  39. Xtio_cmd_cnt_b0    db    ?
  40. Xtio_cmd_dummy1    db    ?
  41. Xtio_cmd        ends
  42. X
  43. X;
  44. X; Format the Unit
  45. X;
  46. Xfmt_cmd        struc
  47. Xfmt_cmd_op    db    ?        ;Opcode
  48. Xfmt_cmd_type    db    ?        ;Format Type
  49. Xfmt_cmd_dummy1    db    ?
  50. Xfmt_cmd_il_b1    db    ?        ;Interleave (MSB)
  51. Xfmt_cmd_il_b0    db    ?        ;Interleave (LSB)
  52. Xfmt_cmd_dummy3    db    ?
  53. Xfmt_cmd        ends
  54. X
  55. X;
  56. X; Verify Sectors
  57. X;
  58. Xver_cmd        struc
  59. Xver_cmd_op    db    ?        ;Opcode
  60. Xver_cmd_lun    db    ?        ;Lun
  61. Xver_cmd_lba_b3    db    ?        ;Logical Block Address MSB
  62. Xver_cmd_lba_b2    db    ?
  63. Xver_cmd_lba_b1    db    ?
  64. Xver_cmd_lba_b0    db    ?        ;Logical Block Address LSB
  65. Xver_cmd_dummy1    db    ?
  66. Xver_cmd_len_b1    db    ?        ;Length MSB
  67. Xver_cmd_len_b0    db    ?        ;Length LSB
  68. Xver_cmd_dummy2    db    ?
  69. Xver_cmd        ends
  70. X
  71. X;
  72. X; Load / Unload a Tape
  73. X;
  74. Xload_cmd    struc
  75. Xload_cmd_op    db    ?        ;Opcode
  76. Xload_cmd_lun    db    ?        ;Lun
  77. Xload_cmd_dummy1    db    2 dup (?)
  78. Xload_cmd_type    db    ?        ;Load / Unload
  79. Xload_cmd_dummy2    db    ?
  80. Xload_cmd    ends
  81. X
  82. X;
  83. X; Write Filemarks on a Tape
  84. X;
  85. Xfm_cmd        struc
  86. Xfm_cmd_op    db    ?        ;Opcode
  87. Xfm_cmd_lun    db    ?        ;Lun
  88. Xfm_cmd_cnt_b2    db    ?        ;Filemark MSB
  89. Xfm_cmd_cnt_b1    db    ?
  90. Xfm_cmd_cnt_b0    db    ?        ;Filemark LSB
  91. Xfm_cmd_dummy    db    ?
  92. Xfm_cmd        ends
  93. X
  94. X;
  95. X; Space a Tape
  96. X;
  97. Xspace_cmd    struc
  98. Xspace_cmd_op    db    ?        ;Opcode
  99. Xspace_cmd_code    db    ?
  100. Xspace_cmd_cnt2    db    ?        ;Count
  101. Xspace_cmd_cnt1    db    ?
  102. Xspace_cmd_cnt0    db    ?
  103. Xspace_cmd_dummy    db    ?
  104. Xspace_cmd    ends
  105. X
  106. X;
  107. X; Structure returned by the sense command
  108. X;
  109. Xsense        struc
  110. X        if extended_sense
  111. Xsense_ccs    db    ?        ;0x70 for Extended Sense
  112. Xsense_dummy1    db    ?
  113. Xsense_sense    db    ?        ;Sense (Error) Group
  114. Xsense_lba_b3    db    ?        ;Failed Block Address
  115. Xsense_lba_b2    db    ?
  116. Xsense_lba_b1    db    ?
  117. Xsense_lba_b0    db    ?
  118. X        else
  119. Xsense_sense    db    ?        ;Sense (Error) code
  120. Xsense_lba_b2    db    ?        ;Failed Block Address
  121. Xsense_lba_b1    db    ?
  122. Xsense_lba_b0    db    ?
  123. X        endif
  124. Xsense        ends
  125. X
  126. X;
  127. X; Structure returned by the unit inquiry command
  128. X;
  129. Xinq        struc
  130. Xinq_dev_type    db    ?        ;Device Type
  131. Xinq_dev_qual    db    ?        ;Device Qualifier
  132. Xinq_stand_rev    db    ?        ;Standard Revision Level
  133. Xinq_format    db    ?        ;Response Format
  134. Xinq_length    db    ?        ;Length of Extra Data
  135. Xinq_reserv1    db    ?
  136. Xinq_reserv2    db    ?
  137. Xinq_reserv3    db    ?
  138. Xinq_manufact    db    8 dup (?)    ;Manufacture
  139. Xinq_product    db    16 dup (?)    ;Product
  140. Xinq        ends
  141. X
  142. X;
  143. X; Structure returned by the read drive capacity command
  144. X;
  145. Xcap        struc
  146. Xcap_sectors_b3    db    ?        ;MSB of sector count
  147. Xcap_sectors_b2    db    ?
  148. Xcap_sectors_b1    db    ?
  149. Xcap_sectors_b0    db    ?        ;LSB of sector count
  150. Xcap_size_b3    db    ?        ;MSB of sector size
  151. Xcap_size_b2    db    ?
  152. Xcap_size_b1    db    ?
  153. Xcap_size_b0    db    ?        ;LSB of sector size
  154. Xcap        ends
  155. X
  156. X;
  157. X; Structure Definitions For Our Device Driver
  158. X;
  159. Xbpb        struc
  160. Xbpb_ss        dw    ?        ;Sector Size
  161. Xbpb_au        db    ?        ;Cluster Size in Sectors
  162. Xbpb_rs        dw    ?        ;Reserved Sectors
  163. Xbpb_nf        db    ?        ;Number of Fats
  164. Xbpb_de        dw    ?        ;Number of Root Directory Entries
  165. Xbpb_ts        dw    ?        ;Total Number Of Sectors
  166. Xbpb_md        db    ?        ;Media Descriptor
  167. Xbpb_fs        dw    ?        ;Number of Sectors in each Fat
  168. Xbpb_st        dw    ?        ;Number of Sectors per Track
  169. Xbpb_nh        dw    ?        ;Number of Heads
  170. Xbpb_hs_lsw    dw    ?        ;Hidden Sectors (Least Sig Word)
  171. Xbpb_hs_msw    dw    ?        ;Hidden Sectors (Most Sig Word)
  172. Xbpb_ts_large    dd    ?        ;Large Total Sector Count
  173. Xbpb_res        db    6 dup (?)    ;Reserved
  174. Xbpb        ends
  175. X
  176. X;
  177. X; ioctl function 42h
  178. X;
  179. Xioctl_fmt    struc
  180. Xioctl_fmt_spec    db    ?        ;Special Flags
  181. Xioctl_fmt_head    dw    ?        ;Head to Format
  182. Xioctl_fmt_cyl    dw    ?        ;Cylinder to Format
  183. Xioctl_fmt    ends
  184. X
  185. X;
  186. X; ioctl function 60h
  187. X;
  188. Xdpb        struc
  189. Xdpb_special    db    ?        ;Special Flags
  190. Xdpb_type    db    ?        ;Device Type
  191. Xdpb_attr    dw    ?        ;Device Attributes
  192. Xdpb_cyl        dw    ?        ;Device Cylinder Count
  193. Xdpb_media    db    ?        ;Device Media Type if Diskette
  194. Xdpb_bpb        db    size bpb dup (?)
  195. Xdpb_sectors    dw    ?        ;Sectors in Track
  196. Xdpb_track    dd    SECT_TRACK dup (?)
  197. Xdpb        ends
  198. X
  199. X;
  200. X; The internal control structure for a SCSI device
  201. X;
  202. Xunit        struc
  203. Xunit_1st_drv    db    ?        ;DOS Drive Numbers
  204. Xunit_num_drv    db    ?        ;DOS Drive Count
  205. Xunit_select    db    ?        ;SCSI Select Bit
  206. Xunit_mcheck    db    ?        ;Media Check Byte
  207. Xunit_inq_buf    db    size inq dup (?)
  208. Xunit_inq_term    db    ?
  209. Xunit_cap_buf    db    size cap dup (?)
  210. Xunit_sense_buf    db    size sense dup (?)
  211. Xunit        ends
  212. X
  213. X;
  214. X; Ioctl Commands
  215. X;
  216. Xioc        struc
  217. Xioc_command    dw    ?        ;Command
  218. Xioc_param1    dw    ?        ;Command Dependent Data
  219. Xioc_param2    dw    ?        ;Command Dependent Data
  220. Xioc        ends
  221. X
  222. X;
  223. X; DOS requests
  224. X;
  225. Xrh        struc
  226. Xrh_len        db    ?        ;Length of Packet
  227. Xrh_unit        db    ?        ;Unit Code (Block Only)
  228. Xrh_cmd        db    ?        ;Command Code
  229. Xrh_status    dw    ?        ;Returned Status
  230. Xrh_res        db    8 dup (?)    ;Reserved
  231. Xrh        ends
  232. X
  233. Xrh0        struc            ;INITIALIZATION
  234. Xrh0_rh        db    size rh dup (?)    ;Fixed Portion
  235. Xrh0_nunits    db    ?        ;Number of units (Block Only)
  236. Xrh0_brk_ofs    dw    ?        ;Break Address (Offset)
  237. Xrh0_brk_seg    dw    ?        ;Break Address (Segment)
  238. Xrh0_bpb_tbo    dw    ?        ;Pointer to BPB Array (Offset)
  239. Xrh0_bpb_tbs    dw    ?        ;Pointer to BPB Array (Segment)
  240. Xrh0_drv_ltr    db    ?        ;First Available Drive (DOS 3+, Block Only)
  241. Xrh0        ends
  242. X
  243. Xrh1        struc            ;MEDIA CHECK
  244. Xrh1_rh        db    size rh dup (?)    ;Fixed Portion
  245. Xrh1_media    db    ?        ;Media Descriptor from DPB
  246. Xrh1_md_stat    db    ?        ;Media Status returned by Device Driver
  247. Xrh1_volid_ofs    dw    ?        ;Offset of Volume ID String (DOS 3+)
  248. Xrh1_volid_seg    dw    ?        ;Segment of Volume ID String (DOS 3+)
  249. Xrh1        ends
  250. X
  251. Xrh2        struc            ;GET BPB
  252. Xrh2_rh        db    size rh dup (?)    ;Fixed Portion
  253. Xrh2_media    db    ?        ;Media Descriptor from DPB
  254. Xrh2_buf_ofs    dw    ?        ;Offset of Data Transfer Area
  255. Xrh2_buf_seg    dw    ?        ;Segment of Data Transfer Area
  256. Xrh2_pbpbo    dw    ?        ;Offset of Pointer to BPB
  257. Xrh2_pbpbs    dw    ?        ;Segment of Pointer to BPB
  258. Xrh2        ends
  259. X
  260. Xrh4        struc            ;INPUT
  261. Xrh4_rh        db    size rh dup (?)    ;Fixed Portion
  262. Xrh4_media    db    ?        ;Media Descriptor from DPB
  263. Xrh4_buf_ofs    dw    ?        ;Offset of Data Transfer Area
  264. Xrh4_buf_seg    dw    ?        ;Segment of Data Transfer Area
  265. Xrh4_count    dw    ?        ;Transfer Count (Sectors)
  266. Xrh4_start    dw    ?        ;Start Sector Number
  267. Xrh4        ends
  268. X
  269. Xrh8        struc            ;OUTPUT
  270. Xrh8_rh        db    size rh dup (?)    ;Fixed Portion
  271. Xrh8_media    db    ?        ;Media Descriptor from DPB
  272. Xrh8_buf_ofs    dw    ?        ;Offset of Data Transfer Area
  273. Xrh8_buf_seg    dw    ?        ;Segment of Data Transfer Area
  274. Xrh8_count    dw    ?        ;Transfer Count (Sectors)
  275. Xrh8_start    dw    ?        ;Start Sector Number
  276. Xrh8        ends
  277. X
  278. Xrh9        struc            ;OUTPUT VERIFY
  279. Xrh9_rh        db    size rh dup (?)    ;Fixed Portion
  280. Xrh9_media    db    ?        ;Media Descriptor from DPB
  281. Xrh9_buf_ofs    dw    ?        ;Offset of Data Transfer Area
  282. Xrh9_buf_seg    dw    ?        ;Segment of Data Transfer Area
  283. Xrh9_count    dw    ?        ;Transfer Count (Sectors)
  284. Xrh9_start    dw    ?        ;Start Sector Number
  285. Xrh9        ends
  286. X
  287. Xrh12        struc            ;OUTPUT IOCTL
  288. Xrh12_rh        db    size rh dup (?)    ;Fixed Portion
  289. Xrh12_media    db    ?        ;Media Descriptor from DPB
  290. Xrh12_buf_ofs    dw    ?        ;Offset of Data Transfer Area
  291. Xrh12_buf_seg    dw    ?        ;Segment of Data Transfer Area
  292. Xrh12_count    dw    ?        ;Transfer Count (Sectors)
  293. Xrh12_start    dw    ?        ;Start Sector Number
  294. Xrh12        ends
  295. X
  296. Xrh19        struc            ;IOCTL
  297. Xrh19_rh        db    size rh dup (?)    ;Fixed Portion
  298. Xrh19_major    db    ?        ;Major Code
  299. Xrh19_minor    db    ?        ;Minor Code
  300. Xrh19_si        dw    ?        ;Caller SI Register
  301. Xrh19_di        dw    ?        ;Caller DI Register
  302. Xrh19_buf_ofs    dw    ?        ;Caller Buffer Offset
  303. Xrh19_buf_seg    dw    ?        ;Caller Buffer Segment
  304. Xrh19        ends
  305. SHAR_EOF
  306. chmod 0644 struct.inc ||
  307. echo 'restore of struct.inc failed'
  308. Wc_c="`wc -c < 'struct.inc'`"
  309. test 7166 -eq "$Wc_c" ||
  310.     echo 'struct.inc: original size 7166, current size' "$Wc_c"
  311. fi
  312. # ============= subs.asm ==============
  313. if test -f 'subs.asm' -a X"$1" != X"-c"; then
  314.     echo 'x - skipping subs.asm (File already exists)'
  315. else
  316. echo 'x - extracting subs.asm (Text)'
  317. sed 's/^X//' << 'SHAR_EOF' > 'subs.asm' &&
  318. X;
  319. X; Data storage for local subroutines
  320. X;
  321. Xcmd_ready    db    SCSI_TESTREADY,0,0,0,0,0
  322. Xcmd_rewind    db    SCSI_REWIND,0,0,0,0,0
  323. Xcmd_sense    db    SCSI_REQSENSE,0,0,0,size sense,0
  324. Xcmd_format    db    SCSI_FORMATUNIT,0,0,0,0,0
  325. Xcmd_space    db    SCSI_SPACE,1,0,0,0,0
  326. X        if extended_io
  327. Xcmd_read    db    SCSI_READBLK,0,0,0,0,0,0,0,1,0
  328. Xcmd_write    db    SCSI_WRITEBLK,0,0,0,0,0,0,0,1,0
  329. X        else
  330. Xcmd_read    db    SCSI_READBLK,0,0,0,1,0
  331. Xcmd_write    db    SCSI_WRITEBLK,0,0,0,1,0
  332. X        endif
  333. Xcmd_tread    db    SCSI_READBLK,1,0,0,0,0
  334. Xcmd_twrite    db    SCSI_WRITEBLK,1,0,0,0,0
  335. Xcmd_twritefm    db    SCSI_WRITEFM,0,0,0,1,0
  336. Xcmd_inquire    db    SCSI_INQUIRY,0,0,0,size inq,0
  337. Xcmd_erase    db    SCSI_ERASE,1,0,0,0,0
  338. Xcmd_load    db    SCSI_LOAD,0,0,0,0,0
  339. Xcmd_capacity    db    SCSI_READSIZE,0,0,0,0,0,0,0,0,0
  340. Xcmd_verify    db    SCSI_VERIFYBLK,0,0,0,0,0,0,0,SECT_TRACK,0
  341. X
  342. X        even
  343. Xdocmd_cmd    dw    ?
  344. Xdocmd_buf    dw    ?
  345. Xdocmd_buf_seg    dw    ?
  346. Xdocmd_len    dw    ?
  347. Xdocmd_status    db    ?
  348. Xdocmd_tempb    db    ?
  349. X
  350. X        if dump_sense
  351. Xsense_msg    db    0dh,07h,'SCSI Unit: 0x'
  352. Xsense_unit    db    'xx, Sense Status: 0x'
  353. Xsense_code    db    'xx, Block Address: 0x'
  354. X        if extended_sense
  355. Xsense_addr3    db    'xx'
  356. X        endif
  357. Xsense_addr2    db    'xx'
  358. Xsense_addr1    db    'xx'
  359. Xsense_addr0    db    'xx',0dh,0ah,'$'
  360. X        endif
  361. X
  362. X;
  363. X; Reset the SCSI Bus
  364. X;
  365. Xscsi_reset    proc    near
  366. X        pusha
  367. X
  368. X        mov    ax,SCSI_CARD_SEG    ;Point at the command port
  369. X        mov    es,ax
  370. X        mov    si,SCSI_CMD_PORT
  371. X
  372. X        mov    al,CMDBASE or CMDENABLE or CMDRST
  373. X        mov    es:[si],al        ;Reset the bus
  374. X        call    wait1ms
  375. X        mov    al,CMDBASE
  376. X        mov    es:[si],al        ;All done
  377. X        mov    cx,250            ;Wait 250ms
  378. Xreset_loop:    call    wait1ms
  379. X        loop    reset_loop
  380. X
  381. X        popa
  382. X        ret
  383. Xscsi_reset    endp
  384. X
  385. X;
  386. X; Test the Ready Status of a unit
  387. X;
  388. X; al = return code, 'C' error
  389. X;
  390. Xscsi_ready    proc    near
  391. X        lea    di,cmd_ready            ;Command
  392. X        call    docmd
  393. X        ret
  394. Xscsi_ready    endp
  395. X
  396. X;
  397. X; Request Sense data from a unit and display the result
  398. X; Called after every SCSI command with the exit code in 'al'
  399. X;
  400. Xscsi_sense    proc    near
  401. X        pushf
  402. X        pusha
  403. X        mov    di,cur_unit            ;Unit
  404. X        lea    bx,[di].unit_sense_buf        ;Buffer Offset
  405. X        push    ds                ;Buffer Segment
  406. X        pop    es
  407. X        mov    cx,size sense            ;Buffer Size
  408. X        lea    di,cmd_sense            ;Command
  409. X        call    docmd
  410. X        if dump_sense
  411. X        jc    sense_exit
  412. X        mov    di,cur_unit
  413. X        mov    dl,[di].unit_select
  414. X        if reserve_addr
  415. X        and    dl,07Fh            ;Remove Cards Bit
  416. X        endif
  417. X        lea    bx,sense_unit        ;Unit
  418. X        call    hex2asc2
  419. X        mov    dl,[di].unit_sense_buf.sense_sense
  420. X        lea    bx,sense_code        ;Sense
  421. X        call    hex2asc2
  422. X        if extended_sense
  423. X        mov    dl,[di].unit_sense_buf.sense_lba_b3
  424. X        lea    bx,sense_addr3        ;Address
  425. X        call    hex2asc2
  426. X        endif
  427. X        mov    dl,[di].unit_sense_buf.sense_lba_b2
  428. X        lea    bx,sense_addr2
  429. X        call    hex2asc2
  430. X        mov    dl,[di].unit_sense_buf.sense_lba_b1
  431. X        lea    bx,sense_addr1
  432. X        call    hex2asc2
  433. X        mov    dl,[di].unit_sense_buf.sense_lba_b0
  434. X        lea    bx,sense_addr0
  435. X        call    hex2asc2
  436. X        lea    dx,sense_msg
  437. X        call    puts
  438. X        endif
  439. Xsense_exit:    popa
  440. X        popf
  441. X        ret
  442. Xscsi_sense    endp
  443. X
  444. X;
  445. X; Inquire about the type of a unit
  446. X;
  447. X; al = return code, 'C' error indicates an error
  448. X;
  449. Xscsi_inquire    proc    near
  450. X        push    cx
  451. X        mov    di,cur_unit            ;Unit
  452. X        lea    bx,[di].unit_sense_buf        ;Buffer Offset
  453. X        push    ds                ;Buffer Segment
  454. X        pop    es
  455. X        mov    cx,size sense            ;Buffer Size
  456. X        lea    di,cmd_sense            ;Command
  457. X        call    docmd                ;Always ask first
  458. X        jc    inquire_exit
  459. X        mov    di,cur_unit            ;Unit
  460. X        lea    bx,[di].unit_inq_buf        ;Buffer Offset
  461. X        push    ds                ;Buffer Segment
  462. X        pop    es
  463. X        mov    cx,size inq            ;Buffer Size
  464. X        lea    di,cmd_inquire            ;Command
  465. X        call    docmd
  466. X        jnc    inquire_exit
  467. X        call    scsi_sense
  468. Xinquire_exit:    pop    cx
  469. X        ret
  470. Xscsi_inquire    endp
  471. X
  472. X;
  473. X; Determine the size of a disk
  474. X;
  475. X; al = return code, 'C' error indicates an error
  476. X;
  477. Xscsi_capacity    proc    near
  478. X        push    cx
  479. X        mov    di,cur_unit            ;Unit
  480. X        lea    bx,[di].unit_cap_buf        ;Buffer Offset
  481. X        push    ds                ;Buffer Segment
  482. X        pop    es
  483. X        mov    cx,size cap            ;Buffer Size
  484. X        lea    di,cmd_capacity            ;Command
  485. X        call    docmd
  486. X        jnc    capacity_exit
  487. X        call    scsi_sense
  488. Xcapacity_exit:    pop    cx
  489. X        ret
  490. Xscsi_capacity    endp
  491. X
  492. X;
  493. X; Verify the Track given in an IOCTL Request
  494. X;
  495. X; al = return code, 'C' indicates an error
  496. X;
  497. Xscsi_verify    proc    near
  498. X        mov    di,es:[bx].rh19_buf_ofs        ;Command Offset
  499. X        mov    ax,es:[bx].rh19_buf_seg        ;Command Segment
  500. X        mov    es,ax
  501. X        mov    ax,es:[di].ioctl_fmt_cyl    ;Track
  502. X        shl    ax,SECT_2_CYL            ;Convert to Sector
  503. X
  504. X        mov    di,cur_bpb            ;Add to Drive Offset
  505. X        mov    dx,[di].bpb_hs_msw
  506. X
  507. X        lea    di,cmd_verify            ;Command
  508. X        mov    [di].ver_cmd_lba_b3,dh        ;Insert Sector
  509. X        mov    [di].ver_cmd_lba_b2,dl        ; into Command
  510. X        mov    [di].ver_cmd_lba_b1,ah        ;Insert Sector
  511. X        mov    [di].ver_cmd_lba_b0,al        ; into Command
  512. X        call    docmd
  513. X        jnc    verify_exit
  514. X        call    scsi_sense
  515. Xverify_exit:    ret
  516. Xscsi_verify    endp
  517. X
  518. X;
  519. X; Read Some Blocks from the disk given
  520. X; the request header in es:bx
  521. X;
  522. X; al = return code, 'C' indicates an error
  523. X;
  524. Xdisk_read    proc    near
  525. X        mov    di,bx
  526. X        mov    cx,es:[di].rh4_count        ;Sector Count
  527. X        mov    dx,es:[di].rh4_start        ;Starting Sector
  528. X        mov    bx,es:[di].rh4_buf_ofs        ;Buffer Offset
  529. X        mov    ax,es:[di].rh4_buf_seg        ;Buffer Segment
  530. X        mov    es,ax
  531. X
  532. X        mov    si,cur_bpb
  533. X        lea    di,cmd_read            ;Command
  534. X        mov    ax,[si].bpb_hs_msw        ;Drive Sector Offset
  535. X        if extended_io
  536. X        mov    [di].io_cmd_lba_b3,ah        ;Insert Sector
  537. X        endif
  538. X        mov    [di].io_cmd_lba_b2,al        ;Into the Command
  539. X
  540. X        if multi_sector
  541. X        mov    ax,cx                ;Get Sector Count
  542. X        and    ax,CHUNK_MAX-1            ;Mask Off the I/O Chunk
  543. X        jnz    disk_r_cok1            ;Check for Boundary
  544. X        mov    ax,CHUNK_MAX
  545. Xdisk_r_cok1:    shl    ax,9                ;Convert to Buffer Size
  546. X        add    ax,bx                ;Check for Wrap
  547. X        else
  548. X        mov    ax,bx                ;Check for Wrap
  549. X        add    ax,P_SECT            ;The First Time
  550. X        endif
  551. Xdisk_r_loop:    jnc    disk_r_nowrap
  552. X        mov    ax,bx                ;Normalize the
  553. X        shr    ax,4                ;Segment and
  554. X        mov    si,es                ;Offset so that
  555. X        add    si,ax                ;It dosn't Wrap
  556. X        mov    es,si
  557. X        and    bx,000Fh
  558. Xdisk_r_nowrap:    push    cx
  559. X        mov    [di].io_cmd_lba_b1,dh        ;Insert Sector
  560. X        mov    [di].io_cmd_lba_b0,dl        ;Into the Command
  561. X        if multi_sector
  562. X        and    cx,CHUNK_MAX-1            ;Mask Off the I/O Chunk
  563. X        jnz    disk_r_cok2            ;Check for Boundary
  564. X        mov    cx,CHUNK_MAX
  565. Xdisk_r_cok2:
  566. X        if extended_io
  567. X        mov    [di].io_cmd_cnt_b1,ch        ;Insert Sector Count
  568. X        endif
  569. X        mov    [di].io_cmd_cnt_b0,cl        ;Into the Command
  570. X        shl    cx,9                ;Convert to Buffer Size
  571. X        else
  572. X        mov    cx,P_SECT            ;Buffer Size
  573. X        endif
  574. X        call    docmd
  575. X        pop    cx
  576. X        jc    disk_r_exit
  577. X        if multi_sector
  578. X        mov    ax,cx                ;Get Sector Count
  579. X        and    ax,CHUNK_MAX-1            ;Mask Off the I/O Chunk
  580. X        jnz    disk_r_cok3            ;Check for Boundary
  581. X        mov    ax,CHUNK_MAX
  582. Xdisk_r_cok3:    sub    cx,ax                ;Dec Sector Count
  583. X        jz    disk_r_exit
  584. X        add    dx,ax                ;Bump to next Sector
  585. X        shl    ax,9                ;Convert to Buffer Size
  586. X        add    bx,ax
  587. X        jmp    short disk_r_loop
  588. X        else
  589. X        inc    dx                ;Bump to next Sector
  590. X        add    bx,P_SECT
  591. X        loop    disk_r_loop
  592. X        clc
  593. X        endif
  594. Xdisk_r_exit:    jnc    disk_r_exit2            ;If no error occured
  595. X        call    scsi_sense            ;Display Sense Status
  596. Xdisk_r_exit2:    mov    es,rh_seg
  597. X        mov    bx,rh_off
  598. X        pushf
  599. X        mov    ax,es:[bx].rh4_count        ;Update the Count
  600. X        sub    ax,cx
  601. X        mov    es:[bx].rh4_count,ax
  602. X        popf
  603. X        ret
  604. Xdisk_read    endp
  605. X
  606. X;
  607. X; Write Some Blocks to the disk given
  608. X; the request header in es:bx
  609. X;
  610. X; al = return code, 'C' indicates an error
  611. X;
  612. Xdisk_write    proc    near
  613. X        mov    di,bx
  614. X        mov    cx,es:[di].rh8_count        ;Sector Count
  615. X        mov    dx,es:[di].rh8_start        ;Starting Sector
  616. X        mov    bx,es:[di].rh8_buf_ofs        ;Buffer Offset
  617. X        mov    ax,es:[di].rh8_buf_seg        ;Buffer Segment
  618. X        mov    es,ax
  619. X
  620. X        mov    si,cur_bpb
  621. X        lea    di,cmd_write            ;Command
  622. X        mov    ax,[si].bpb_hs_msw        ;Drive Sector Offset
  623. X        if extended_io
  624. X        mov    [di].io_cmd_lba_b3,ah        ;Insert Sector
  625. X        endif
  626. X        mov    [di].io_cmd_lba_b2,al        ;Into the Command
  627. X
  628. X        if multi_sector
  629. X        mov    ax,cx                ;Get Sector Count
  630. X        and    ax,CHUNK_MAX-1            ;Mask Off the I/O Chunk
  631. X        jnz    disk_w_cok1            ;Check for Boundary
  632. X        mov    ax,CHUNK_MAX
  633. Xdisk_w_cok1:    shl    ax,9                ;Convert to Buffer Size
  634. X        add    ax,bx                ;Check for Wrap
  635. X        else
  636. X        mov    ax,bx                ;Check for Wrap
  637. X        add    ax,P_SECT            ;The First Time
  638. X        endif
  639. Xdisk_w_loop:    jnc    disk_w_nowrap
  640. X        mov    ax,bx                ;Normalize the
  641. X        shr    ax,4                ;Segment and
  642. X        mov    si,es                ;Offset so that
  643. X        add    si,ax                ;It dosn't Wrap
  644. X        mov    es,si
  645. X        and    bx,000Fh
  646. Xdisk_w_nowrap:    push    cx
  647. X        mov    [di].io_cmd_lba_b1,dh        ;Insert Sector
  648. X        mov    [di].io_cmd_lba_b0,dl        ;Into the Command
  649. X        if multi_sector
  650. X        and    cx,CHUNK_MAX-1            ;Mask Off the I/O Chunk
  651. X        jnz    disk_w_cok2            ;Check for Boundary
  652. X        mov    cx,CHUNK_MAX
  653. Xdisk_w_cok2:
  654. X        if extended_io
  655. X        mov    [di].io_cmd_cnt_b1,ch        ;Insert Sector Count
  656. X        endif
  657. X        mov    [di].io_cmd_cnt_b0,cl        ;Into the Command
  658. X        shl    cx,9                ;Convert to Buffer Size
  659. X        else
  660. X        mov    cx,P_SECT            ;Buffer Size
  661. X        endif
  662. X        call    docmd
  663. X        pop    cx
  664. X        jc    disk_w_exit
  665. X        if multi_sector
  666. X        mov    ax,cx                ;Get Sector Count
  667. X        and    ax,CHUNK_MAX-1            ;Mask Off the I/O Chunk
  668. X        jnz    disk_w_cok3            ;Check for Boundary
  669. X        mov    ax,CHUNK_MAX
  670. Xdisk_w_cok3:    sub    cx,ax                ;Dec Sector Count
  671. X        jz    disk_w_exit
  672. X        add    dx,ax                ;Bump to next Sector
  673. X        shl    ax,9                ;Convert to Buffer Size
  674. X        add    bx,ax
  675. X        jmp    short disk_w_loop
  676. X        else
  677. X        inc    dx                ;Bump to next Sector
  678. X        add    bx,P_SECT
  679. X        loop    disk_w_loop
  680. X        clc
  681. X        endif
  682. Xdisk_w_exit:    jnc    disk_w_exit2            ;If no error occured
  683. X        call    scsi_sense            ;Display Sense Status
  684. Xdisk_w_exit2:    mov    es,rh_seg
  685. X        mov    bx,rh_off
  686. X        pushf
  687. X        mov    ax,es:[bx].rh8_count        ;Update the Count
  688. X        sub    ax,cx
  689. X        mov    es:[bx].rh8_count,ax
  690. X        popf
  691. X        ret
  692. Xdisk_write    endp
  693. X
  694. X;
  695. X; Read Some Blocks from the Tape
  696. X;
  697. Xtape_read    proc    near
  698. X        mov    write_flag,FALSE        ;Cancel if READ seen
  699. X        mov    di,bx
  700. X        mov    cx,es:[di].rh4_count        ;Byte Count
  701. X        mov    ax,cx                ;Test for invalid
  702. X        and    ax,P_SECT-1            ;Byte Count
  703. X        jz    tape_r_ok
  704. X        mov    es:[di].rh4_count,0        ;Nothing Read
  705. X        stc                    ;Oops
  706. X        ret
  707. Xtape_r_ok:    mov    bx,es:[di].rh4_buf_ofs        ;Buffer Offset
  708. X        mov    ax,es:[di].rh4_buf_seg        ;Buffer Segment
  709. X        mov    es,ax
  710. X        mov    ax,bx                ;Normalize the
  711. X        shr    ax,4                ;Segment and
  712. X        mov    si,es                ;Offset so that
  713. X        add    si,ax                ;It dosn't Wrap
  714. X        mov    es,si
  715. X        and    bx,000Fh
  716. X        lea    di,cmd_tread
  717. X        mov    ax,cx                ;Convert Bytes
  718. X        shr    ax,9                ;to Blocks
  719. X        mov    [di].tio_cmd_cnt_b1,ah        ;Insert into Command
  720. X        mov    [di].tio_cmd_cnt_b0,al
  721. X        call    docmd
  722. X        jnc    tape_r_exit
  723. X        call    scsi_sense
  724. Xtape_r_exit:    ret
  725. Xtape_read    endp
  726. X
  727. X;
  728. X; Write Some Blocks to the Tape
  729. X;
  730. Xtape_write    proc    near
  731. X        mov    write_flag,TRUE            ;Write Done
  732. X        mov    di,bx
  733. X        mov    cx,es:[di].rh8_count        ;Byte Count
  734. X        mov    ax,cx                ;Test for invalid
  735. X        and    ax,P_SECT-1            ;Byte Count
  736. X        jz    tape_w_ok
  737. X        mov    es:[di].rh8_count,0        ;Nothing Write
  738. X        mov    write_flag,FALSE        ;Cancel if ERROR!
  739. X        stc                    ;Oops
  740. X        ret
  741. Xtape_w_ok:    mov    cx,es:[di].rh8_count        ;Byte Count
  742. X        mov    bx,es:[di].rh8_buf_ofs        ;Buffer Offset
  743. X        mov    ax,es:[di].rh8_buf_seg        ;Buffer Segment
  744. X        mov    es,ax
  745. X        mov    ax,bx                ;Normalize the
  746. X        shr    ax,4                ;Segment and
  747. X        mov    si,es                ;Offset so that
  748. X        add    si,ax                ;It dosn't Wrap
  749. X        mov    es,si
  750. X        and    bx,000Fh
  751. X        lea    di,cmd_twrite
  752. X        mov    ax,cx                ;Convert Bytes
  753. X        shr    ax,9                ;to Blocks
  754. X        mov    [di].tio_cmd_cnt_b1,ah        ;Insert into Command
  755. X        mov    [di].tio_cmd_cnt_b0,al
  756. X        call    docmd
  757. X        jnc    tape_w_exit
  758. X        mov    write_flag,FALSE        ;Cancel if ERROR!
  759. X        call    scsi_sense
  760. Xtape_w_exit:    ret
  761. Xtape_write    endp
  762. X
  763. X;
  764. X; Do a command
  765. X;
  766. X; bx => buffer for returned information
  767. X; cx = buffer len
  768. X; di => command string
  769. X; es = buffer segment for returned information
  770. X;
  771. X; al = return code, 'C' indicates an error
  772. X;
  773. Xdocmd        proc    near
  774. X        pusha
  775. X        push    es
  776. X
  777. X        mov    docmd_buf,bx        ;Save our arguments
  778. X        mov    docmd_buf_seg,es
  779. X        mov    docmd_len,cx
  780. X        mov    docmd_cmd,di
  781. X
  782. X        mov    ax,SCSI_CARD_SEG    ;Point at the Card
  783. X        mov    es,ax
  784. X        mov    si,SCSI_CMD_PORT    ;Command Port
  785. X
  786. X;
  787. X; Wait for the Bus to become free
  788. X;
  789. X        mov    cx,65535
  790. Xidle_loop:    mov    al,es:[si]        ;Get the Status
  791. X        and    al,FREE_MASK
  792. X        jz    try_sel
  793. X        loop    idle_loop
  794. X
  795. X        call    scsi_reset
  796. X        mov    al,CBUSBUSY        ;Bus still BUSY?
  797. X        jmp    docmd_exit
  798. X
  799. Xtry_sel:    mov    al,CMDBASE        ;Try to select target
  800. X        mov    es:[si],al
  801. X
  802. X        mov    di,cur_unit
  803. X        mov    al,[di].unit_select    ;Get our Select Bit
  804. X        mov    di,SCSI_DATA_PORT    ;Data Port
  805. X        mov    es:[di],al
  806. X
  807. X        call    wait100us        ;Spec says wait 90us here
  808. X        mov    al,CMDBASE or CMDENABLE or CMDSEL
  809. X        mov    es:[si],al
  810. X
  811. X;
  812. X; Wait 250 ms for the Target to be SELected
  813. X;
  814. X        mov    cx,2500
  815. Xsel_loop:    test    byte ptr es:[si],STBSY    ;Look for BSY bit
  816. X        jnz    cmd_xfer
  817. X        call    wait100us
  818. X        loop    sel_loop
  819. X
  820. X        mov    al,CMDBASE or CMDSEL    ;Release the data BUS
  821. X        mov    es:[si],al
  822. X        call    wait100us        ;Spec says wait 290us
  823. X        call    wait100us        ;to abort selection phase
  824. X        call    wait100us
  825. X        test    byte ptr es:[si],STBSY    ;Look one final time
  826. X        jnz    cmd_xfer        ;Device did answer
  827. X        mov    al,CNOCONNECT        ;Nothing Answered
  828. X        jmp    docmd_exit
  829. X
  830. X;
  831. X; Start the Command
  832. X;
  833. Xcmd_xfer:    call    wait100us        ;Spec say wait 90us here
  834. X        mov    al,CMDBASE or CMDENABLE    ;Drop SEL and begin talking
  835. X        mov    es:[si],al
  836. Xxfer_loop:    mov    al,es:[si]
  837. X        test    al,STBSY        ;Look for BSY bit
  838. X        jz    xfer_error
  839. X        test    al,STREQ        ;And REQ bit
  840. X        jz    xfer_loop
  841. X
  842. X        and    al,REQ_MASK        ;Look at REQ type
  843. X
  844. X        cmp    al,REQ_DATAOUT        ;Is it Data Out?
  845. X        jnz    try_datain
  846. X        call    send_data
  847. X        jmp    short xfer_loop
  848. X
  849. Xtry_datain:    cmp    al,REQ_DATAIN        ;Is it Data In?
  850. X        jnz    try_cmdout
  851. X        call    receive_data
  852. X        jmp    short xfer_loop
  853. X
  854. Xtry_cmdout:    cmp    al,REQ_CMDOUT        ;Is it Command Out?
  855. X        jnz    try_statin
  856. X        call    send_cmd
  857. X        jmp    short xfer_loop
  858. X
  859. Xtry_statin:    cmp    al,REQ_STATIN        ;Is it Status In?
  860. X        jnz    try_msgout
  861. X        mov    al,es:[di]        ;Get the Status Byte
  862. X        mov    docmd_status,al
  863. X        jmp    short xfer_loop
  864. X
  865. Xtry_msgout:    cmp    al,REQ_MSGOUT        ;Is it Message Out?
  866. X        jnz    try_msgin
  867. X        call    send_nop
  868. X        jmp    short xfer_loop
  869. X
  870. Xtry_msgin:    cmp    al,REQ_MSGIN        ;Is it Message In?
  871. X        jnz    xfer_error
  872. X
  873. X        mov    al,es:[di]        ;Get Message Byte
  874. X        cmp    al,MSG_COMPLETE        ;Are We All Done?
  875. X        jnz    short xfer_loop
  876. X        mov    al,docmd_status
  877. X        or    al,al            ;Did we have an error?
  878. X        mov    al,COK            ;Preload OK code
  879. X        jz    docmd_exit
  880. X
  881. Xxfer_error:    mov    al,CERROR        ;Command Failed Somehow
  882. X
  883. Xdocmd_exit:    mov    docmd_tempb,al
  884. X        mov    al,CMDBASE        ;Release the BUS
  885. X        mov    es:[si],al
  886. X        pop    es
  887. X        popa
  888. X        mov    al,docmd_tempb
  889. X        cmp    al,COK
  890. X        jz    docmd_exit_ok
  891. X        stc
  892. Xdocmd_exit_ok:    ret
  893. Xdocmd        endp
  894. X
  895. X;
  896. X; Receive a Data Stream from the card
  897. X; On entry es:[di] points at the data port
  898. X;          es:[si] points at the command port
  899. X;
  900. Xreceive_data    proc    near
  901. X        mov    dx,es            ;Save ES
  902. X
  903. X        mov    bx,si
  904. X        mov    ax,es
  905. X        mov    cx,docmd_len        ;Length
  906. X        mov    di,docmd_buf        ;Dest Offset
  907. X        mov    es,docmd_buf_seg    ;Dest Segment
  908. X        mov    si,SCSI_DATA_PORT    ;Source Offset
  909. X        mov    ds,ax            ;Source Segment
  910. X        mov    al,STREQ
  911. X        mov    ah,STBSY
  912. X        cld
  913. X
  914. Xreceive_loop:    movsb
  915. X        if multi_sector
  916. X        dec    si            ;Don't blow the card buffer
  917. X        endif
  918. X        dec    cx
  919. X        jz    receive_exit
  920. Xreceive_wait:    test    byte ptr [bx],al    ;Ready?
  921. X        jnz    receive_loop
  922. X        test    byte ptr [bx],ah    ;Busy?
  923. X        jz    receive_exit
  924. X        jmp    short receive_wait
  925. X
  926. Xreceive_exit:    mov    si,SCSI_CMD_PORT    ;Restore the Environment
  927. X        mov    di,SCSI_DATA_PORT
  928. X        mov    ax,cs
  929. X        mov    ds,ax
  930. X        mov    es,dx
  931. X        ret
  932. Xreceive_data    endp
  933. X
  934. X;
  935. X; Send a Command to the card
  936. X; On entry es:[di] points at the data port
  937. X;          es:[si] points at the command port
  938. X;
  939. Xsend_cmd    proc    near
  940. X        mov    bx,docmd_cmd        ;Get Command Pointer
  941. X        mov    al,[bx]            ;Get a Command Byte
  942. X        mov    es:[di],al        ;Send it to Card
  943. X        inc    bx            ;Bump for Next Time
  944. X        mov    docmd_cmd,bx
  945. X        ret
  946. Xsend_cmd    endp
  947. X
  948. X;
  949. X; Send a Data Stream to the card
  950. X; On entry es:[di] points at the data port
  951. X;          es:[si] points at the command port
  952. X;
  953. Xsend_data    proc    near
  954. X        mov    bx,si
  955. X        mov    cx,docmd_len        ;Get the Data Count
  956. X        mov    si,docmd_buf        ;Source Offset
  957. X        mov    ds,docmd_buf_seg    ;Source Segment
  958. X        mov    al,STREQ
  959. X        mov    ah,STBSY
  960. X        cld
  961. X
  962. Xsend_loop:    movsb
  963. X        if multi_sector
  964. X        dec    di            ;Don't blow the card buffer
  965. X        endif
  966. X        dec    cx
  967. X        jz    send_exit
  968. Xsend_wait:    test    byte ptr es:[bx],al    ;Ready?
  969. X        jnz    send_loop
  970. X        test    byte ptr es:[bx],ah    ;Busy?
  971. X        jz    send_exit
  972. X        jmp    short send_wait
  973. X
  974. Xsend_exit:    mov    si,SCSI_CMD_PORT    ;Restore the Environment
  975. X        mov    di,SCSI_DATA_PORT
  976. X        mov    ax,cs
  977. X        mov    ds,ax
  978. X        ret
  979. Xsend_data    endp
  980. X
  981. X;
  982. X; Send a NOP Message
  983. X;
  984. Xsend_nop    proc    near
  985. X        mov    al,MSG_NOP        ;Oops, send a nop
  986. X        mov    es:[di],al
  987. X        mov    al,CMDBASE or CMDENABLE
  988. X        mov    es:[si],al
  989. X        ret
  990. Xsend_nop    endp
  991. X
  992. X;
  993. X; Wait One Milli second
  994. X;
  995. X; The value of 'cx' is computed for an 8 Mhz Clock
  996. X;
  997. Xwait1ms        proc    near
  998. X        push    cx        ;   (3) = 375ns
  999. X        mov    cx,798        ;   (2) = 250ns
  1000. Xwait_m_loop:    loop    wait_m_loop    ;  (10) = 1250ns * X
  1001. X        pop    cx        ;   (5) = 625ns
  1002. X        ret            ; (11+) = 1375ns
  1003. Xwait1ms        endp
  1004. X
  1005. X;
  1006. X; Wait One Hundred Micros Seconds
  1007. X;
  1008. X; The value of 'cx' is computed for an 8 Mhz Clock
  1009. X;
  1010. Xwait100us    proc    near
  1011. X        push    cx        ;   (3) = 375ns
  1012. X        mov    cx,78        ;   (2) = 250ns
  1013. Xwait_u_loop:    loop    wait_u_loop    ;  (10) = 1250ns * X
  1014. X        pop    cx        ;   (5) = 625ns
  1015. X        ret            ; (11+) = 1375ns
  1016. Xwait100us    endp
  1017. SHAR_EOF
  1018. chmod 0644 subs.asm ||
  1019. echo 'restore of subs.asm failed'
  1020. Wc_c="`wc -c < 'subs.asm'`"
  1021. test 15830 -eq "$Wc_c" ||
  1022.     echo 'subs.asm: original size 15830, current size' "$Wc_c"
  1023. fi
  1024. # ============= units.asm ==============
  1025. if test -f 'units.asm' -a X"$1" != X"-c"; then
  1026.     echo 'x - skipping units.asm (File already exists)'
  1027. else
  1028. echo 'x - extracting units.asm (Text)'
  1029. sed 's/^X//' << 'SHAR_EOF' > 'units.asm' &&
  1030. X;
  1031. X; target information/control structures
  1032. X;
  1033. X        even
  1034. Xunit0        db    size unit dup (-1)
  1035. X        even
  1036. Xunit1        db    size unit dup (-1)
  1037. X        even
  1038. Xunit2        db    size unit dup (-1)
  1039. X        even
  1040. Xunit3        db    size unit dup (-1)
  1041. X        even
  1042. Xunit4        db    size unit dup (-1)
  1043. X        even
  1044. Xunit5        db    size unit dup (-1)
  1045. X        even
  1046. Xunit6        db    size unit dup (-1)
  1047. X        ife reserve_addr
  1048. X        even
  1049. Xunit7        db    size unit dup (-1)
  1050. X        endif
  1051. X
  1052. X        even
  1053. Xbpb0        db    size bpb dup (-1)
  1054. X        even
  1055. Xbpb1        db    size bpb dup (-1)
  1056. X        even
  1057. Xbpb2        db    size bpb dup (-1)
  1058. X        even
  1059. Xbpb3        db    size bpb dup (-1)
  1060. X        even
  1061. Xbpb4        db    size bpb dup (-1)
  1062. X        even
  1063. Xbpb5        db    size bpb dup (-1)
  1064. X        even
  1065. Xbpb6        db    size bpb dup (-1)
  1066. X        even
  1067. Xbpb7        db    size bpb dup (-1)
  1068. X        even
  1069. Xbpb8        db    size bpb dup (-1)
  1070. X        even
  1071. Xbpb9        db    size bpb dup (-1)
  1072. X        even
  1073. XbpbA        db    size bpb dup (-1)
  1074. X        even
  1075. XbpbB        db    size bpb dup (-1)
  1076. X        even
  1077. XbpbC        db    size bpb dup (-1)
  1078. X        even
  1079. XbpbD        db    size bpb dup (-1)
  1080. X        even
  1081. XbpbE        db    size bpb dup (-1)
  1082. X        even
  1083. XbpbF        db    size bpb dup (-1)
  1084. X
  1085. X        even
  1086. Xunit_array    dw    unit0
  1087. X        dw    unit1
  1088. X        dw    unit2
  1089. X        dw    unit3
  1090. X        dw    unit4
  1091. X        dw    unit5
  1092. X        dw    unit6
  1093. X        ife reserve_addr
  1094. X        dw    unit7
  1095. X        endif
  1096. X
  1097. X        even
  1098. Xbpb_array    dw    bpb0        ;BPB Array for DOS
  1099. X        dw    bpb1
  1100. X        dw    bpb2
  1101. X        dw    bpb3
  1102. X        dw    bpb4
  1103. X        dw    bpb5
  1104. X        dw    bpb6
  1105. X        dw    bpb7
  1106. X        dw    bpb8
  1107. X        dw    bpb9
  1108. X        dw    bpbA
  1109. X        dw    bpbB
  1110. X        dw    bpbC
  1111. X        dw    bpbD
  1112. X        dw    bpbE
  1113. X        dw    bpbF
  1114. Xbpb_hw_mark    dw    bpb_array
  1115. X
  1116. Xtape_unit    dw    -1
  1117. Xcur_unit    dw    unit0
  1118. Xcur_bpb        dw    bpb0
  1119. X
  1120. X;
  1121. X; Given the request header in es:bx
  1122. X; Return a pointer in ds:di to the unit entry
  1123. X; or 'C' if no such unit exists.
  1124. X;
  1125. X; Do not destroy es:bx !!!
  1126. X;
  1127. Xfind_unit    proc    near
  1128. X        pusha
  1129. X        mov    ah,es:[bx].rh_unit    ;What drive did they want
  1130. X        lea    di,unit_array
  1131. X        lea    si,bpb_array
  1132. X        mov    cx,MAXUNIT        ;How many to search
  1133. Xfind_loop:    mov    bx,[di]            ;Point at a unit    
  1134. X        mov    al,[bx].unit_num_drv    ;Does this SCSI device
  1135. X        or    al,al            ;Have any Drives Defined?
  1136. X        jz    find_next
  1137. X        mov    dh,[bx].unit_1st_drv    ;Get First Drive Number
  1138. Xfind_unit_loop:    cmp    ah,dh            ;Is this the correct drive?
  1139. X        jz    find_match
  1140. X        inc    si            ;Bump to next BPB
  1141. X        inc    si
  1142. X        inc    dh            ;Bump Drive Number
  1143. X        dec    al            ;Dec Drive count
  1144. X        jnz    find_unit_loop        ;Try next Drive
  1145. X        jmp    short find_next        ;Try next SCSI device
  1146. Xfind_match:    mov    cur_unit,bx        ;Found a match
  1147. X        mov    ax,[si]
  1148. X        mov    cur_bpb,ax
  1149. X        clc
  1150. X        jmp    find_exit
  1151. Xfind_next:    inc    di
  1152. X        inc    di
  1153. X        loop    find_loop
  1154. X        stc                ;No More units, Error
  1155. Xfind_exit:    popa
  1156. X        ret
  1157. Xfind_unit    endp
  1158. X
  1159. X;
  1160. X; Given the data in a unit entry,
  1161. X; create the bpb for the unit.
  1162. X;
  1163. Xmake_bpb    proc    near
  1164. X        mov    di,cur_bpb        ;Get the current BPB
  1165. X        mov    bx,cur_unit        ;Get the current Unit
  1166. X        mov    [di].bpb_ss,P_SECT
  1167. X        mov    [di].bpb_au,CLUSTSIZE
  1168. X        mov    [di].bpb_rs,1
  1169. X        mov    [di].bpb_nf,2
  1170. X        mov    [di].bpb_de,512
  1171. X        mov    ah,[bx].unit_cap_buf.cap_sectors_b3
  1172. X        mov    al,[bx].unit_cap_buf.cap_sectors_b2
  1173. X        or    ax,ax
  1174. X        jz    make_bpb_last        ;Use up the last few sectors
  1175. X        dec    ax            ;Use up 65536 Sectors
  1176. X        mov    [bx].unit_cap_buf.cap_sectors_b3,ah
  1177. X        mov    [bx].unit_cap_buf.cap_sectors_b2,al
  1178. X        mov    dx,65535        ;Max of 32 Meg
  1179. X        jmp    short make_bpb_ts
  1180. Xmake_bpb_last:    mov    dh,[bx].unit_cap_buf.cap_sectors_b1
  1181. X        mov    [bx].unit_cap_buf.cap_sectors_b1,0
  1182. X        mov    dl,0            ;Round to nearest Cyl
  1183. X        mov    [bx].unit_cap_buf.cap_sectors_b0,0
  1184. X        dec    dx            ;Make it zero relative
  1185. Xmake_bpb_ts:    mov    [di].bpb_ts,dx
  1186. X        mov    [di].bpb_md,0F8h
  1187. X        shr    dx,SECT_2_FS
  1188. X        inc    dx            ;Allow for round-off
  1189. X        mov    [di].bpb_fs,dx
  1190. X        mov    [di].bpb_st,SECT_TRACK
  1191. X        mov    [di].bpb_nh,1
  1192. X        mov    [di].bpb_hs_lsw,0
  1193. X        mov    [di].bpb_hs_msw,0
  1194. X        ret
  1195. Xmake_bpb    endp
  1196. SHAR_EOF
  1197. chmod 0644 units.asm ||
  1198. echo 'restore of units.asm failed'
  1199. Wc_c="`wc -c < 'units.asm'`"
  1200. test 3322 -eq "$Wc_c" ||
  1201.     echo 'units.asm: original size 3322, current size' "$Wc_c"
  1202. fi
  1203. exit 0
  1204.  
  1205.  
  1206.