home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-10-12 | 28.1 KB | 1,206 lines |
-
- #!/bin/sh
- # This is part 02 of ST01SCSI.12
- # ============= struct.inc ==============
- if test -f 'struct.inc' -a X"$1" != X"-c"; then
- echo 'x - skipping struct.inc (File already exists)'
- else
- echo 'x - extracting struct.inc (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'struct.inc' &&
- X;
- X; Structures for SCSI commands
- X;
- Xio_cmd struc
- Xio_cmd_op db ? ;Opcode
- X if extended_io
- Xio_cmd_lun db ?
- Xio_cmd_lba_b3 db ? ;Logical Block Address
- Xio_cmd_lba_b2 db ?
- Xio_cmd_lba_b1 db ?
- Xio_cmd_lba_b0 db ?
- Xio_cmd_dummy1 db ?
- Xio_cmd_cnt_b1 db ? ;Block Count
- Xio_cmd_cnt_b0 db ?
- Xio_cmd_dummy2 db ?
- X else
- Xio_cmd_lba_b2 db ? ;Logical Block Address / Lun
- Xio_cmd_lba_b1 db ?
- Xio_cmd_lba_b0 db ?
- Xio_cmd_cnt_b0 db ? ;Block Count
- Xio_cmd_dummy1 db ?
- X endif
- Xio_cmd ends
- X
- Xtio_cmd struc
- Xtio_cmd_op db ? ;Opcode
- Xtio_cmd_lun db ? ;Lun
- Xtio_cmd_cnt_b2 db ? ;Block Count
- Xtio_cmd_cnt_b1 db ?
- Xtio_cmd_cnt_b0 db ?
- Xtio_cmd_dummy1 db ?
- Xtio_cmd ends
- X
- X;
- X; Format the Unit
- X;
- Xfmt_cmd struc
- Xfmt_cmd_op db ? ;Opcode
- Xfmt_cmd_type db ? ;Format Type
- Xfmt_cmd_dummy1 db ?
- Xfmt_cmd_il_b1 db ? ;Interleave (MSB)
- Xfmt_cmd_il_b0 db ? ;Interleave (LSB)
- Xfmt_cmd_dummy3 db ?
- Xfmt_cmd ends
- X
- X;
- X; Verify Sectors
- X;
- Xver_cmd struc
- Xver_cmd_op db ? ;Opcode
- Xver_cmd_lun db ? ;Lun
- Xver_cmd_lba_b3 db ? ;Logical Block Address MSB
- Xver_cmd_lba_b2 db ?
- Xver_cmd_lba_b1 db ?
- Xver_cmd_lba_b0 db ? ;Logical Block Address LSB
- Xver_cmd_dummy1 db ?
- Xver_cmd_len_b1 db ? ;Length MSB
- Xver_cmd_len_b0 db ? ;Length LSB
- Xver_cmd_dummy2 db ?
- Xver_cmd ends
- X
- X;
- X; Load / Unload a Tape
- X;
- Xload_cmd struc
- Xload_cmd_op db ? ;Opcode
- Xload_cmd_lun db ? ;Lun
- Xload_cmd_dummy1 db 2 dup (?)
- Xload_cmd_type db ? ;Load / Unload
- Xload_cmd_dummy2 db ?
- Xload_cmd ends
- X
- X;
- X; Write Filemarks on a Tape
- X;
- Xfm_cmd struc
- Xfm_cmd_op db ? ;Opcode
- Xfm_cmd_lun db ? ;Lun
- Xfm_cmd_cnt_b2 db ? ;Filemark MSB
- Xfm_cmd_cnt_b1 db ?
- Xfm_cmd_cnt_b0 db ? ;Filemark LSB
- Xfm_cmd_dummy db ?
- Xfm_cmd ends
- X
- X;
- X; Space a Tape
- X;
- Xspace_cmd struc
- Xspace_cmd_op db ? ;Opcode
- Xspace_cmd_code db ?
- Xspace_cmd_cnt2 db ? ;Count
- Xspace_cmd_cnt1 db ?
- Xspace_cmd_cnt0 db ?
- Xspace_cmd_dummy db ?
- Xspace_cmd ends
- X
- X;
- X; Structure returned by the sense command
- X;
- Xsense struc
- X if extended_sense
- Xsense_ccs db ? ;0x70 for Extended Sense
- Xsense_dummy1 db ?
- Xsense_sense db ? ;Sense (Error) Group
- Xsense_lba_b3 db ? ;Failed Block Address
- Xsense_lba_b2 db ?
- Xsense_lba_b1 db ?
- Xsense_lba_b0 db ?
- X else
- Xsense_sense db ? ;Sense (Error) code
- Xsense_lba_b2 db ? ;Failed Block Address
- Xsense_lba_b1 db ?
- Xsense_lba_b0 db ?
- X endif
- Xsense ends
- X
- X;
- X; Structure returned by the unit inquiry command
- X;
- Xinq struc
- Xinq_dev_type db ? ;Device Type
- Xinq_dev_qual db ? ;Device Qualifier
- Xinq_stand_rev db ? ;Standard Revision Level
- Xinq_format db ? ;Response Format
- Xinq_length db ? ;Length of Extra Data
- Xinq_reserv1 db ?
- Xinq_reserv2 db ?
- Xinq_reserv3 db ?
- Xinq_manufact db 8 dup (?) ;Manufacture
- Xinq_product db 16 dup (?) ;Product
- Xinq ends
- X
- X;
- X; Structure returned by the read drive capacity command
- X;
- Xcap struc
- Xcap_sectors_b3 db ? ;MSB of sector count
- Xcap_sectors_b2 db ?
- Xcap_sectors_b1 db ?
- Xcap_sectors_b0 db ? ;LSB of sector count
- Xcap_size_b3 db ? ;MSB of sector size
- Xcap_size_b2 db ?
- Xcap_size_b1 db ?
- Xcap_size_b0 db ? ;LSB of sector size
- Xcap ends
- X
- X;
- X; Structure Definitions For Our Device Driver
- X;
- Xbpb struc
- Xbpb_ss dw ? ;Sector Size
- Xbpb_au db ? ;Cluster Size in Sectors
- Xbpb_rs dw ? ;Reserved Sectors
- Xbpb_nf db ? ;Number of Fats
- Xbpb_de dw ? ;Number of Root Directory Entries
- Xbpb_ts dw ? ;Total Number Of Sectors
- Xbpb_md db ? ;Media Descriptor
- Xbpb_fs dw ? ;Number of Sectors in each Fat
- Xbpb_st dw ? ;Number of Sectors per Track
- Xbpb_nh dw ? ;Number of Heads
- Xbpb_hs_lsw dw ? ;Hidden Sectors (Least Sig Word)
- Xbpb_hs_msw dw ? ;Hidden Sectors (Most Sig Word)
- Xbpb_ts_large dd ? ;Large Total Sector Count
- Xbpb_res db 6 dup (?) ;Reserved
- Xbpb ends
- X
- X;
- X; ioctl function 42h
- X;
- Xioctl_fmt struc
- Xioctl_fmt_spec db ? ;Special Flags
- Xioctl_fmt_head dw ? ;Head to Format
- Xioctl_fmt_cyl dw ? ;Cylinder to Format
- Xioctl_fmt ends
- X
- X;
- X; ioctl function 60h
- X;
- Xdpb struc
- Xdpb_special db ? ;Special Flags
- Xdpb_type db ? ;Device Type
- Xdpb_attr dw ? ;Device Attributes
- Xdpb_cyl dw ? ;Device Cylinder Count
- Xdpb_media db ? ;Device Media Type if Diskette
- Xdpb_bpb db size bpb dup (?)
- Xdpb_sectors dw ? ;Sectors in Track
- Xdpb_track dd SECT_TRACK dup (?)
- Xdpb ends
- X
- X;
- X; The internal control structure for a SCSI device
- X;
- Xunit struc
- Xunit_1st_drv db ? ;DOS Drive Numbers
- Xunit_num_drv db ? ;DOS Drive Count
- Xunit_select db ? ;SCSI Select Bit
- Xunit_mcheck db ? ;Media Check Byte
- Xunit_inq_buf db size inq dup (?)
- Xunit_inq_term db ?
- Xunit_cap_buf db size cap dup (?)
- Xunit_sense_buf db size sense dup (?)
- Xunit ends
- X
- X;
- X; Ioctl Commands
- X;
- Xioc struc
- Xioc_command dw ? ;Command
- Xioc_param1 dw ? ;Command Dependent Data
- Xioc_param2 dw ? ;Command Dependent Data
- Xioc ends
- X
- X;
- X; DOS requests
- X;
- Xrh struc
- Xrh_len db ? ;Length of Packet
- Xrh_unit db ? ;Unit Code (Block Only)
- Xrh_cmd db ? ;Command Code
- Xrh_status dw ? ;Returned Status
- Xrh_res db 8 dup (?) ;Reserved
- Xrh ends
- X
- Xrh0 struc ;INITIALIZATION
- Xrh0_rh db size rh dup (?) ;Fixed Portion
- Xrh0_nunits db ? ;Number of units (Block Only)
- Xrh0_brk_ofs dw ? ;Break Address (Offset)
- Xrh0_brk_seg dw ? ;Break Address (Segment)
- Xrh0_bpb_tbo dw ? ;Pointer to BPB Array (Offset)
- Xrh0_bpb_tbs dw ? ;Pointer to BPB Array (Segment)
- Xrh0_drv_ltr db ? ;First Available Drive (DOS 3+, Block Only)
- Xrh0 ends
- X
- Xrh1 struc ;MEDIA CHECK
- Xrh1_rh db size rh dup (?) ;Fixed Portion
- Xrh1_media db ? ;Media Descriptor from DPB
- Xrh1_md_stat db ? ;Media Status returned by Device Driver
- Xrh1_volid_ofs dw ? ;Offset of Volume ID String (DOS 3+)
- Xrh1_volid_seg dw ? ;Segment of Volume ID String (DOS 3+)
- Xrh1 ends
- X
- Xrh2 struc ;GET BPB
- Xrh2_rh db size rh dup (?) ;Fixed Portion
- Xrh2_media db ? ;Media Descriptor from DPB
- Xrh2_buf_ofs dw ? ;Offset of Data Transfer Area
- Xrh2_buf_seg dw ? ;Segment of Data Transfer Area
- Xrh2_pbpbo dw ? ;Offset of Pointer to BPB
- Xrh2_pbpbs dw ? ;Segment of Pointer to BPB
- Xrh2 ends
- X
- Xrh4 struc ;INPUT
- Xrh4_rh db size rh dup (?) ;Fixed Portion
- Xrh4_media db ? ;Media Descriptor from DPB
- Xrh4_buf_ofs dw ? ;Offset of Data Transfer Area
- Xrh4_buf_seg dw ? ;Segment of Data Transfer Area
- Xrh4_count dw ? ;Transfer Count (Sectors)
- Xrh4_start dw ? ;Start Sector Number
- Xrh4 ends
- X
- Xrh8 struc ;OUTPUT
- Xrh8_rh db size rh dup (?) ;Fixed Portion
- Xrh8_media db ? ;Media Descriptor from DPB
- Xrh8_buf_ofs dw ? ;Offset of Data Transfer Area
- Xrh8_buf_seg dw ? ;Segment of Data Transfer Area
- Xrh8_count dw ? ;Transfer Count (Sectors)
- Xrh8_start dw ? ;Start Sector Number
- Xrh8 ends
- X
- Xrh9 struc ;OUTPUT VERIFY
- Xrh9_rh db size rh dup (?) ;Fixed Portion
- Xrh9_media db ? ;Media Descriptor from DPB
- Xrh9_buf_ofs dw ? ;Offset of Data Transfer Area
- Xrh9_buf_seg dw ? ;Segment of Data Transfer Area
- Xrh9_count dw ? ;Transfer Count (Sectors)
- Xrh9_start dw ? ;Start Sector Number
- Xrh9 ends
- X
- Xrh12 struc ;OUTPUT IOCTL
- Xrh12_rh db size rh dup (?) ;Fixed Portion
- Xrh12_media db ? ;Media Descriptor from DPB
- Xrh12_buf_ofs dw ? ;Offset of Data Transfer Area
- Xrh12_buf_seg dw ? ;Segment of Data Transfer Area
- Xrh12_count dw ? ;Transfer Count (Sectors)
- Xrh12_start dw ? ;Start Sector Number
- Xrh12 ends
- X
- Xrh19 struc ;IOCTL
- Xrh19_rh db size rh dup (?) ;Fixed Portion
- Xrh19_major db ? ;Major Code
- Xrh19_minor db ? ;Minor Code
- Xrh19_si dw ? ;Caller SI Register
- Xrh19_di dw ? ;Caller DI Register
- Xrh19_buf_ofs dw ? ;Caller Buffer Offset
- Xrh19_buf_seg dw ? ;Caller Buffer Segment
- Xrh19 ends
- SHAR_EOF
- chmod 0644 struct.inc ||
- echo 'restore of struct.inc failed'
- Wc_c="`wc -c < 'struct.inc'`"
- test 7166 -eq "$Wc_c" ||
- echo 'struct.inc: original size 7166, current size' "$Wc_c"
- fi
- # ============= subs.asm ==============
- if test -f 'subs.asm' -a X"$1" != X"-c"; then
- echo 'x - skipping subs.asm (File already exists)'
- else
- echo 'x - extracting subs.asm (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'subs.asm' &&
- X;
- X; Data storage for local subroutines
- X;
- Xcmd_ready db SCSI_TESTREADY,0,0,0,0,0
- Xcmd_rewind db SCSI_REWIND,0,0,0,0,0
- Xcmd_sense db SCSI_REQSENSE,0,0,0,size sense,0
- Xcmd_format db SCSI_FORMATUNIT,0,0,0,0,0
- Xcmd_space db SCSI_SPACE,1,0,0,0,0
- X if extended_io
- Xcmd_read db SCSI_READBLK,0,0,0,0,0,0,0,1,0
- Xcmd_write db SCSI_WRITEBLK,0,0,0,0,0,0,0,1,0
- X else
- Xcmd_read db SCSI_READBLK,0,0,0,1,0
- Xcmd_write db SCSI_WRITEBLK,0,0,0,1,0
- X endif
- Xcmd_tread db SCSI_READBLK,1,0,0,0,0
- Xcmd_twrite db SCSI_WRITEBLK,1,0,0,0,0
- Xcmd_twritefm db SCSI_WRITEFM,0,0,0,1,0
- Xcmd_inquire db SCSI_INQUIRY,0,0,0,size inq,0
- Xcmd_erase db SCSI_ERASE,1,0,0,0,0
- Xcmd_load db SCSI_LOAD,0,0,0,0,0
- Xcmd_capacity db SCSI_READSIZE,0,0,0,0,0,0,0,0,0
- Xcmd_verify db SCSI_VERIFYBLK,0,0,0,0,0,0,0,SECT_TRACK,0
- X
- X even
- Xdocmd_cmd dw ?
- Xdocmd_buf dw ?
- Xdocmd_buf_seg dw ?
- Xdocmd_len dw ?
- Xdocmd_status db ?
- Xdocmd_tempb db ?
- X
- X if dump_sense
- Xsense_msg db 0dh,07h,'SCSI Unit: 0x'
- Xsense_unit db 'xx, Sense Status: 0x'
- Xsense_code db 'xx, Block Address: 0x'
- X if extended_sense
- Xsense_addr3 db 'xx'
- X endif
- Xsense_addr2 db 'xx'
- Xsense_addr1 db 'xx'
- Xsense_addr0 db 'xx',0dh,0ah,'$'
- X endif
- X
- X;
- X; Reset the SCSI Bus
- X;
- Xscsi_reset proc near
- X pusha
- X
- X mov ax,SCSI_CARD_SEG ;Point at the command port
- X mov es,ax
- X mov si,SCSI_CMD_PORT
- X
- X mov al,CMDBASE or CMDENABLE or CMDRST
- X mov es:[si],al ;Reset the bus
- X call wait1ms
- X mov al,CMDBASE
- X mov es:[si],al ;All done
- X mov cx,250 ;Wait 250ms
- Xreset_loop: call wait1ms
- X loop reset_loop
- X
- X popa
- X ret
- Xscsi_reset endp
- X
- X;
- X; Test the Ready Status of a unit
- X;
- X; al = return code, 'C' error
- X;
- Xscsi_ready proc near
- X lea di,cmd_ready ;Command
- X call docmd
- X ret
- Xscsi_ready endp
- X
- X;
- X; Request Sense data from a unit and display the result
- X; Called after every SCSI command with the exit code in 'al'
- X;
- Xscsi_sense proc near
- X pushf
- X pusha
- X mov di,cur_unit ;Unit
- X lea bx,[di].unit_sense_buf ;Buffer Offset
- X push ds ;Buffer Segment
- X pop es
- X mov cx,size sense ;Buffer Size
- X lea di,cmd_sense ;Command
- X call docmd
- X if dump_sense
- X jc sense_exit
- X mov di,cur_unit
- X mov dl,[di].unit_select
- X if reserve_addr
- X and dl,07Fh ;Remove Cards Bit
- X endif
- X lea bx,sense_unit ;Unit
- X call hex2asc2
- X mov dl,[di].unit_sense_buf.sense_sense
- X lea bx,sense_code ;Sense
- X call hex2asc2
- X if extended_sense
- X mov dl,[di].unit_sense_buf.sense_lba_b3
- X lea bx,sense_addr3 ;Address
- X call hex2asc2
- X endif
- X mov dl,[di].unit_sense_buf.sense_lba_b2
- X lea bx,sense_addr2
- X call hex2asc2
- X mov dl,[di].unit_sense_buf.sense_lba_b1
- X lea bx,sense_addr1
- X call hex2asc2
- X mov dl,[di].unit_sense_buf.sense_lba_b0
- X lea bx,sense_addr0
- X call hex2asc2
- X lea dx,sense_msg
- X call puts
- X endif
- Xsense_exit: popa
- X popf
- X ret
- Xscsi_sense endp
- X
- X;
- X; Inquire about the type of a unit
- X;
- X; al = return code, 'C' error indicates an error
- X;
- Xscsi_inquire proc near
- X push cx
- X mov di,cur_unit ;Unit
- X lea bx,[di].unit_sense_buf ;Buffer Offset
- X push ds ;Buffer Segment
- X pop es
- X mov cx,size sense ;Buffer Size
- X lea di,cmd_sense ;Command
- X call docmd ;Always ask first
- X jc inquire_exit
- X mov di,cur_unit ;Unit
- X lea bx,[di].unit_inq_buf ;Buffer Offset
- X push ds ;Buffer Segment
- X pop es
- X mov cx,size inq ;Buffer Size
- X lea di,cmd_inquire ;Command
- X call docmd
- X jnc inquire_exit
- X call scsi_sense
- Xinquire_exit: pop cx
- X ret
- Xscsi_inquire endp
- X
- X;
- X; Determine the size of a disk
- X;
- X; al = return code, 'C' error indicates an error
- X;
- Xscsi_capacity proc near
- X push cx
- X mov di,cur_unit ;Unit
- X lea bx,[di].unit_cap_buf ;Buffer Offset
- X push ds ;Buffer Segment
- X pop es
- X mov cx,size cap ;Buffer Size
- X lea di,cmd_capacity ;Command
- X call docmd
- X jnc capacity_exit
- X call scsi_sense
- Xcapacity_exit: pop cx
- X ret
- Xscsi_capacity endp
- X
- X;
- X; Verify the Track given in an IOCTL Request
- X;
- X; al = return code, 'C' indicates an error
- X;
- Xscsi_verify proc near
- X mov di,es:[bx].rh19_buf_ofs ;Command Offset
- X mov ax,es:[bx].rh19_buf_seg ;Command Segment
- X mov es,ax
- X mov ax,es:[di].ioctl_fmt_cyl ;Track
- X shl ax,SECT_2_CYL ;Convert to Sector
- X
- X mov di,cur_bpb ;Add to Drive Offset
- X mov dx,[di].bpb_hs_msw
- X
- X lea di,cmd_verify ;Command
- X mov [di].ver_cmd_lba_b3,dh ;Insert Sector
- X mov [di].ver_cmd_lba_b2,dl ; into Command
- X mov [di].ver_cmd_lba_b1,ah ;Insert Sector
- X mov [di].ver_cmd_lba_b0,al ; into Command
- X call docmd
- X jnc verify_exit
- X call scsi_sense
- Xverify_exit: ret
- Xscsi_verify endp
- X
- X;
- X; Read Some Blocks from the disk given
- X; the request header in es:bx
- X;
- X; al = return code, 'C' indicates an error
- X;
- Xdisk_read proc near
- X mov di,bx
- X mov cx,es:[di].rh4_count ;Sector Count
- X mov dx,es:[di].rh4_start ;Starting Sector
- X mov bx,es:[di].rh4_buf_ofs ;Buffer Offset
- X mov ax,es:[di].rh4_buf_seg ;Buffer Segment
- X mov es,ax
- X
- X mov si,cur_bpb
- X lea di,cmd_read ;Command
- X mov ax,[si].bpb_hs_msw ;Drive Sector Offset
- X if extended_io
- X mov [di].io_cmd_lba_b3,ah ;Insert Sector
- X endif
- X mov [di].io_cmd_lba_b2,al ;Into the Command
- X
- X if multi_sector
- X mov ax,cx ;Get Sector Count
- X and ax,CHUNK_MAX-1 ;Mask Off the I/O Chunk
- X jnz disk_r_cok1 ;Check for Boundary
- X mov ax,CHUNK_MAX
- Xdisk_r_cok1: shl ax,9 ;Convert to Buffer Size
- X add ax,bx ;Check for Wrap
- X else
- X mov ax,bx ;Check for Wrap
- X add ax,P_SECT ;The First Time
- X endif
- Xdisk_r_loop: jnc disk_r_nowrap
- X mov ax,bx ;Normalize the
- X shr ax,4 ;Segment and
- X mov si,es ;Offset so that
- X add si,ax ;It dosn't Wrap
- X mov es,si
- X and bx,000Fh
- Xdisk_r_nowrap: push cx
- X mov [di].io_cmd_lba_b1,dh ;Insert Sector
- X mov [di].io_cmd_lba_b0,dl ;Into the Command
- X if multi_sector
- X and cx,CHUNK_MAX-1 ;Mask Off the I/O Chunk
- X jnz disk_r_cok2 ;Check for Boundary
- X mov cx,CHUNK_MAX
- Xdisk_r_cok2:
- X if extended_io
- X mov [di].io_cmd_cnt_b1,ch ;Insert Sector Count
- X endif
- X mov [di].io_cmd_cnt_b0,cl ;Into the Command
- X shl cx,9 ;Convert to Buffer Size
- X else
- X mov cx,P_SECT ;Buffer Size
- X endif
- X call docmd
- X pop cx
- X jc disk_r_exit
- X if multi_sector
- X mov ax,cx ;Get Sector Count
- X and ax,CHUNK_MAX-1 ;Mask Off the I/O Chunk
- X jnz disk_r_cok3 ;Check for Boundary
- X mov ax,CHUNK_MAX
- Xdisk_r_cok3: sub cx,ax ;Dec Sector Count
- X jz disk_r_exit
- X add dx,ax ;Bump to next Sector
- X shl ax,9 ;Convert to Buffer Size
- X add bx,ax
- X jmp short disk_r_loop
- X else
- X inc dx ;Bump to next Sector
- X add bx,P_SECT
- X loop disk_r_loop
- X clc
- X endif
- Xdisk_r_exit: jnc disk_r_exit2 ;If no error occured
- X call scsi_sense ;Display Sense Status
- Xdisk_r_exit2: mov es,rh_seg
- X mov bx,rh_off
- X pushf
- X mov ax,es:[bx].rh4_count ;Update the Count
- X sub ax,cx
- X mov es:[bx].rh4_count,ax
- X popf
- X ret
- Xdisk_read endp
- X
- X;
- X; Write Some Blocks to the disk given
- X; the request header in es:bx
- X;
- X; al = return code, 'C' indicates an error
- X;
- Xdisk_write proc near
- X mov di,bx
- X mov cx,es:[di].rh8_count ;Sector Count
- X mov dx,es:[di].rh8_start ;Starting Sector
- X mov bx,es:[di].rh8_buf_ofs ;Buffer Offset
- X mov ax,es:[di].rh8_buf_seg ;Buffer Segment
- X mov es,ax
- X
- X mov si,cur_bpb
- X lea di,cmd_write ;Command
- X mov ax,[si].bpb_hs_msw ;Drive Sector Offset
- X if extended_io
- X mov [di].io_cmd_lba_b3,ah ;Insert Sector
- X endif
- X mov [di].io_cmd_lba_b2,al ;Into the Command
- X
- X if multi_sector
- X mov ax,cx ;Get Sector Count
- X and ax,CHUNK_MAX-1 ;Mask Off the I/O Chunk
- X jnz disk_w_cok1 ;Check for Boundary
- X mov ax,CHUNK_MAX
- Xdisk_w_cok1: shl ax,9 ;Convert to Buffer Size
- X add ax,bx ;Check for Wrap
- X else
- X mov ax,bx ;Check for Wrap
- X add ax,P_SECT ;The First Time
- X endif
- Xdisk_w_loop: jnc disk_w_nowrap
- X mov ax,bx ;Normalize the
- X shr ax,4 ;Segment and
- X mov si,es ;Offset so that
- X add si,ax ;It dosn't Wrap
- X mov es,si
- X and bx,000Fh
- Xdisk_w_nowrap: push cx
- X mov [di].io_cmd_lba_b1,dh ;Insert Sector
- X mov [di].io_cmd_lba_b0,dl ;Into the Command
- X if multi_sector
- X and cx,CHUNK_MAX-1 ;Mask Off the I/O Chunk
- X jnz disk_w_cok2 ;Check for Boundary
- X mov cx,CHUNK_MAX
- Xdisk_w_cok2:
- X if extended_io
- X mov [di].io_cmd_cnt_b1,ch ;Insert Sector Count
- X endif
- X mov [di].io_cmd_cnt_b0,cl ;Into the Command
- X shl cx,9 ;Convert to Buffer Size
- X else
- X mov cx,P_SECT ;Buffer Size
- X endif
- X call docmd
- X pop cx
- X jc disk_w_exit
- X if multi_sector
- X mov ax,cx ;Get Sector Count
- X and ax,CHUNK_MAX-1 ;Mask Off the I/O Chunk
- X jnz disk_w_cok3 ;Check for Boundary
- X mov ax,CHUNK_MAX
- Xdisk_w_cok3: sub cx,ax ;Dec Sector Count
- X jz disk_w_exit
- X add dx,ax ;Bump to next Sector
- X shl ax,9 ;Convert to Buffer Size
- X add bx,ax
- X jmp short disk_w_loop
- X else
- X inc dx ;Bump to next Sector
- X add bx,P_SECT
- X loop disk_w_loop
- X clc
- X endif
- Xdisk_w_exit: jnc disk_w_exit2 ;If no error occured
- X call scsi_sense ;Display Sense Status
- Xdisk_w_exit2: mov es,rh_seg
- X mov bx,rh_off
- X pushf
- X mov ax,es:[bx].rh8_count ;Update the Count
- X sub ax,cx
- X mov es:[bx].rh8_count,ax
- X popf
- X ret
- Xdisk_write endp
- X
- X;
- X; Read Some Blocks from the Tape
- X;
- Xtape_read proc near
- X mov write_flag,FALSE ;Cancel if READ seen
- X mov di,bx
- X mov cx,es:[di].rh4_count ;Byte Count
- X mov ax,cx ;Test for invalid
- X and ax,P_SECT-1 ;Byte Count
- X jz tape_r_ok
- X mov es:[di].rh4_count,0 ;Nothing Read
- X stc ;Oops
- X ret
- Xtape_r_ok: mov bx,es:[di].rh4_buf_ofs ;Buffer Offset
- X mov ax,es:[di].rh4_buf_seg ;Buffer Segment
- X mov es,ax
- X mov ax,bx ;Normalize the
- X shr ax,4 ;Segment and
- X mov si,es ;Offset so that
- X add si,ax ;It dosn't Wrap
- X mov es,si
- X and bx,000Fh
- X lea di,cmd_tread
- X mov ax,cx ;Convert Bytes
- X shr ax,9 ;to Blocks
- X mov [di].tio_cmd_cnt_b1,ah ;Insert into Command
- X mov [di].tio_cmd_cnt_b0,al
- X call docmd
- X jnc tape_r_exit
- X call scsi_sense
- Xtape_r_exit: ret
- Xtape_read endp
- X
- X;
- X; Write Some Blocks to the Tape
- X;
- Xtape_write proc near
- X mov write_flag,TRUE ;Write Done
- X mov di,bx
- X mov cx,es:[di].rh8_count ;Byte Count
- X mov ax,cx ;Test for invalid
- X and ax,P_SECT-1 ;Byte Count
- X jz tape_w_ok
- X mov es:[di].rh8_count,0 ;Nothing Write
- X mov write_flag,FALSE ;Cancel if ERROR!
- X stc ;Oops
- X ret
- Xtape_w_ok: mov cx,es:[di].rh8_count ;Byte Count
- X mov bx,es:[di].rh8_buf_ofs ;Buffer Offset
- X mov ax,es:[di].rh8_buf_seg ;Buffer Segment
- X mov es,ax
- X mov ax,bx ;Normalize the
- X shr ax,4 ;Segment and
- X mov si,es ;Offset so that
- X add si,ax ;It dosn't Wrap
- X mov es,si
- X and bx,000Fh
- X lea di,cmd_twrite
- X mov ax,cx ;Convert Bytes
- X shr ax,9 ;to Blocks
- X mov [di].tio_cmd_cnt_b1,ah ;Insert into Command
- X mov [di].tio_cmd_cnt_b0,al
- X call docmd
- X jnc tape_w_exit
- X mov write_flag,FALSE ;Cancel if ERROR!
- X call scsi_sense
- Xtape_w_exit: ret
- Xtape_write endp
- X
- X;
- X; Do a command
- X;
- X; bx => buffer for returned information
- X; cx = buffer len
- X; di => command string
- X; es = buffer segment for returned information
- X;
- X; al = return code, 'C' indicates an error
- X;
- Xdocmd proc near
- X pusha
- X push es
- X
- X mov docmd_buf,bx ;Save our arguments
- X mov docmd_buf_seg,es
- X mov docmd_len,cx
- X mov docmd_cmd,di
- X
- X mov ax,SCSI_CARD_SEG ;Point at the Card
- X mov es,ax
- X mov si,SCSI_CMD_PORT ;Command Port
- X
- X;
- X; Wait for the Bus to become free
- X;
- X mov cx,65535
- Xidle_loop: mov al,es:[si] ;Get the Status
- X and al,FREE_MASK
- X jz try_sel
- X loop idle_loop
- X
- X call scsi_reset
- X mov al,CBUSBUSY ;Bus still BUSY?
- X jmp docmd_exit
- X
- Xtry_sel: mov al,CMDBASE ;Try to select target
- X mov es:[si],al
- X
- X mov di,cur_unit
- X mov al,[di].unit_select ;Get our Select Bit
- X mov di,SCSI_DATA_PORT ;Data Port
- X mov es:[di],al
- X
- X call wait100us ;Spec says wait 90us here
- X mov al,CMDBASE or CMDENABLE or CMDSEL
- X mov es:[si],al
- X
- X;
- X; Wait 250 ms for the Target to be SELected
- X;
- X mov cx,2500
- Xsel_loop: test byte ptr es:[si],STBSY ;Look for BSY bit
- X jnz cmd_xfer
- X call wait100us
- X loop sel_loop
- X
- X mov al,CMDBASE or CMDSEL ;Release the data BUS
- X mov es:[si],al
- X call wait100us ;Spec says wait 290us
- X call wait100us ;to abort selection phase
- X call wait100us
- X test byte ptr es:[si],STBSY ;Look one final time
- X jnz cmd_xfer ;Device did answer
- X mov al,CNOCONNECT ;Nothing Answered
- X jmp docmd_exit
- X
- X;
- X; Start the Command
- X;
- Xcmd_xfer: call wait100us ;Spec say wait 90us here
- X mov al,CMDBASE or CMDENABLE ;Drop SEL and begin talking
- X mov es:[si],al
- Xxfer_loop: mov al,es:[si]
- X test al,STBSY ;Look for BSY bit
- X jz xfer_error
- X test al,STREQ ;And REQ bit
- X jz xfer_loop
- X
- X and al,REQ_MASK ;Look at REQ type
- X
- X cmp al,REQ_DATAOUT ;Is it Data Out?
- X jnz try_datain
- X call send_data
- X jmp short xfer_loop
- X
- Xtry_datain: cmp al,REQ_DATAIN ;Is it Data In?
- X jnz try_cmdout
- X call receive_data
- X jmp short xfer_loop
- X
- Xtry_cmdout: cmp al,REQ_CMDOUT ;Is it Command Out?
- X jnz try_statin
- X call send_cmd
- X jmp short xfer_loop
- X
- Xtry_statin: cmp al,REQ_STATIN ;Is it Status In?
- X jnz try_msgout
- X mov al,es:[di] ;Get the Status Byte
- X mov docmd_status,al
- X jmp short xfer_loop
- X
- Xtry_msgout: cmp al,REQ_MSGOUT ;Is it Message Out?
- X jnz try_msgin
- X call send_nop
- X jmp short xfer_loop
- X
- Xtry_msgin: cmp al,REQ_MSGIN ;Is it Message In?
- X jnz xfer_error
- X
- X mov al,es:[di] ;Get Message Byte
- X cmp al,MSG_COMPLETE ;Are We All Done?
- X jnz short xfer_loop
- X mov al,docmd_status
- X or al,al ;Did we have an error?
- X mov al,COK ;Preload OK code
- X jz docmd_exit
- X
- Xxfer_error: mov al,CERROR ;Command Failed Somehow
- X
- Xdocmd_exit: mov docmd_tempb,al
- X mov al,CMDBASE ;Release the BUS
- X mov es:[si],al
- X pop es
- X popa
- X mov al,docmd_tempb
- X cmp al,COK
- X jz docmd_exit_ok
- X stc
- Xdocmd_exit_ok: ret
- Xdocmd endp
- X
- X;
- X; Receive a Data Stream from the card
- X; On entry es:[di] points at the data port
- X; es:[si] points at the command port
- X;
- Xreceive_data proc near
- X mov dx,es ;Save ES
- X
- X mov bx,si
- X mov ax,es
- X mov cx,docmd_len ;Length
- X mov di,docmd_buf ;Dest Offset
- X mov es,docmd_buf_seg ;Dest Segment
- X mov si,SCSI_DATA_PORT ;Source Offset
- X mov ds,ax ;Source Segment
- X mov al,STREQ
- X mov ah,STBSY
- X cld
- X
- Xreceive_loop: movsb
- X if multi_sector
- X dec si ;Don't blow the card buffer
- X endif
- X dec cx
- X jz receive_exit
- Xreceive_wait: test byte ptr [bx],al ;Ready?
- X jnz receive_loop
- X test byte ptr [bx],ah ;Busy?
- X jz receive_exit
- X jmp short receive_wait
- X
- Xreceive_exit: mov si,SCSI_CMD_PORT ;Restore the Environment
- X mov di,SCSI_DATA_PORT
- X mov ax,cs
- X mov ds,ax
- X mov es,dx
- X ret
- Xreceive_data endp
- X
- X;
- X; Send a Command to the card
- X; On entry es:[di] points at the data port
- X; es:[si] points at the command port
- X;
- Xsend_cmd proc near
- X mov bx,docmd_cmd ;Get Command Pointer
- X mov al,[bx] ;Get a Command Byte
- X mov es:[di],al ;Send it to Card
- X inc bx ;Bump for Next Time
- X mov docmd_cmd,bx
- X ret
- Xsend_cmd endp
- X
- X;
- X; Send a Data Stream to the card
- X; On entry es:[di] points at the data port
- X; es:[si] points at the command port
- X;
- Xsend_data proc near
- X mov bx,si
- X mov cx,docmd_len ;Get the Data Count
- X mov si,docmd_buf ;Source Offset
- X mov ds,docmd_buf_seg ;Source Segment
- X mov al,STREQ
- X mov ah,STBSY
- X cld
- X
- Xsend_loop: movsb
- X if multi_sector
- X dec di ;Don't blow the card buffer
- X endif
- X dec cx
- X jz send_exit
- Xsend_wait: test byte ptr es:[bx],al ;Ready?
- X jnz send_loop
- X test byte ptr es:[bx],ah ;Busy?
- X jz send_exit
- X jmp short send_wait
- X
- Xsend_exit: mov si,SCSI_CMD_PORT ;Restore the Environment
- X mov di,SCSI_DATA_PORT
- X mov ax,cs
- X mov ds,ax
- X ret
- Xsend_data endp
- X
- X;
- X; Send a NOP Message
- X;
- Xsend_nop proc near
- X mov al,MSG_NOP ;Oops, send a nop
- X mov es:[di],al
- X mov al,CMDBASE or CMDENABLE
- X mov es:[si],al
- X ret
- Xsend_nop endp
- X
- X;
- X; Wait One Milli second
- X;
- X; The value of 'cx' is computed for an 8 Mhz Clock
- X;
- Xwait1ms proc near
- X push cx ; (3) = 375ns
- X mov cx,798 ; (2) = 250ns
- Xwait_m_loop: loop wait_m_loop ; (10) = 1250ns * X
- X pop cx ; (5) = 625ns
- X ret ; (11+) = 1375ns
- Xwait1ms endp
- X
- X;
- X; Wait One Hundred Micros Seconds
- X;
- X; The value of 'cx' is computed for an 8 Mhz Clock
- X;
- Xwait100us proc near
- X push cx ; (3) = 375ns
- X mov cx,78 ; (2) = 250ns
- Xwait_u_loop: loop wait_u_loop ; (10) = 1250ns * X
- X pop cx ; (5) = 625ns
- X ret ; (11+) = 1375ns
- Xwait100us endp
- SHAR_EOF
- chmod 0644 subs.asm ||
- echo 'restore of subs.asm failed'
- Wc_c="`wc -c < 'subs.asm'`"
- test 15830 -eq "$Wc_c" ||
- echo 'subs.asm: original size 15830, current size' "$Wc_c"
- fi
- # ============= units.asm ==============
- if test -f 'units.asm' -a X"$1" != X"-c"; then
- echo 'x - skipping units.asm (File already exists)'
- else
- echo 'x - extracting units.asm (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'units.asm' &&
- X;
- X; target information/control structures
- X;
- X even
- Xunit0 db size unit dup (-1)
- X even
- Xunit1 db size unit dup (-1)
- X even
- Xunit2 db size unit dup (-1)
- X even
- Xunit3 db size unit dup (-1)
- X even
- Xunit4 db size unit dup (-1)
- X even
- Xunit5 db size unit dup (-1)
- X even
- Xunit6 db size unit dup (-1)
- X ife reserve_addr
- X even
- Xunit7 db size unit dup (-1)
- X endif
- X
- X even
- Xbpb0 db size bpb dup (-1)
- X even
- Xbpb1 db size bpb dup (-1)
- X even
- Xbpb2 db size bpb dup (-1)
- X even
- Xbpb3 db size bpb dup (-1)
- X even
- Xbpb4 db size bpb dup (-1)
- X even
- Xbpb5 db size bpb dup (-1)
- X even
- Xbpb6 db size bpb dup (-1)
- X even
- Xbpb7 db size bpb dup (-1)
- X even
- Xbpb8 db size bpb dup (-1)
- X even
- Xbpb9 db size bpb dup (-1)
- X even
- XbpbA db size bpb dup (-1)
- X even
- XbpbB db size bpb dup (-1)
- X even
- XbpbC db size bpb dup (-1)
- X even
- XbpbD db size bpb dup (-1)
- X even
- XbpbE db size bpb dup (-1)
- X even
- XbpbF db size bpb dup (-1)
- X
- X even
- Xunit_array dw unit0
- X dw unit1
- X dw unit2
- X dw unit3
- X dw unit4
- X dw unit5
- X dw unit6
- X ife reserve_addr
- X dw unit7
- X endif
- X
- X even
- Xbpb_array dw bpb0 ;BPB Array for DOS
- X dw bpb1
- X dw bpb2
- X dw bpb3
- X dw bpb4
- X dw bpb5
- X dw bpb6
- X dw bpb7
- X dw bpb8
- X dw bpb9
- X dw bpbA
- X dw bpbB
- X dw bpbC
- X dw bpbD
- X dw bpbE
- X dw bpbF
- Xbpb_hw_mark dw bpb_array
- X
- Xtape_unit dw -1
- Xcur_unit dw unit0
- Xcur_bpb dw bpb0
- X
- X;
- X; Given the request header in es:bx
- X; Return a pointer in ds:di to the unit entry
- X; or 'C' if no such unit exists.
- X;
- X; Do not destroy es:bx !!!
- X;
- Xfind_unit proc near
- X pusha
- X mov ah,es:[bx].rh_unit ;What drive did they want
- X lea di,unit_array
- X lea si,bpb_array
- X mov cx,MAXUNIT ;How many to search
- Xfind_loop: mov bx,[di] ;Point at a unit
- X mov al,[bx].unit_num_drv ;Does this SCSI device
- X or al,al ;Have any Drives Defined?
- X jz find_next
- X mov dh,[bx].unit_1st_drv ;Get First Drive Number
- Xfind_unit_loop: cmp ah,dh ;Is this the correct drive?
- X jz find_match
- X inc si ;Bump to next BPB
- X inc si
- X inc dh ;Bump Drive Number
- X dec al ;Dec Drive count
- X jnz find_unit_loop ;Try next Drive
- X jmp short find_next ;Try next SCSI device
- Xfind_match: mov cur_unit,bx ;Found a match
- X mov ax,[si]
- X mov cur_bpb,ax
- X clc
- X jmp find_exit
- Xfind_next: inc di
- X inc di
- X loop find_loop
- X stc ;No More units, Error
- Xfind_exit: popa
- X ret
- Xfind_unit endp
- X
- X;
- X; Given the data in a unit entry,
- X; create the bpb for the unit.
- X;
- Xmake_bpb proc near
- X mov di,cur_bpb ;Get the current BPB
- X mov bx,cur_unit ;Get the current Unit
- X mov [di].bpb_ss,P_SECT
- X mov [di].bpb_au,CLUSTSIZE
- X mov [di].bpb_rs,1
- X mov [di].bpb_nf,2
- X mov [di].bpb_de,512
- X mov ah,[bx].unit_cap_buf.cap_sectors_b3
- X mov al,[bx].unit_cap_buf.cap_sectors_b2
- X or ax,ax
- X jz make_bpb_last ;Use up the last few sectors
- X dec ax ;Use up 65536 Sectors
- X mov [bx].unit_cap_buf.cap_sectors_b3,ah
- X mov [bx].unit_cap_buf.cap_sectors_b2,al
- X mov dx,65535 ;Max of 32 Meg
- X jmp short make_bpb_ts
- Xmake_bpb_last: mov dh,[bx].unit_cap_buf.cap_sectors_b1
- X mov [bx].unit_cap_buf.cap_sectors_b1,0
- X mov dl,0 ;Round to nearest Cyl
- X mov [bx].unit_cap_buf.cap_sectors_b0,0
- X dec dx ;Make it zero relative
- Xmake_bpb_ts: mov [di].bpb_ts,dx
- X mov [di].bpb_md,0F8h
- X shr dx,SECT_2_FS
- X inc dx ;Allow for round-off
- X mov [di].bpb_fs,dx
- X mov [di].bpb_st,SECT_TRACK
- X mov [di].bpb_nh,1
- X mov [di].bpb_hs_lsw,0
- X mov [di].bpb_hs_msw,0
- X ret
- Xmake_bpb endp
- SHAR_EOF
- chmod 0644 units.asm ||
- echo 'restore of units.asm failed'
- Wc_c="`wc -c < 'units.asm'`"
- test 3322 -eq "$Wc_c" ||
- echo 'units.asm: original size 3322, current size' "$Wc_c"
- fi
- exit 0
-
-
-