home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-10-12 | 44.0 KB | 1,752 lines |
-
- #!/bin/sh
- # This is ST01SCSI.12, a shell archive (produced by shar 3.49)
- # To extract the files from this archive, save it to a file, remove
- # everything above the "!/bin/sh" line above, and type "sh file_name".
- #
- # made 09/25/1990 02:47 UTC by briana@tau-ceti.isc-br.com
- # Source directory /u/briana/scsi/scsi-1.2
- #
- # existing files will NOT be overwritten unless -c is specified
- #
- # This shar contains:
- # length mode name
- # ------ ---------- ------------------------------------------
- # 497 -rw-r--r-- binmode.c
- # 1296 -rw-r--r-- dump.asm
- # 3921 -rw-r--r-- equ.inc
- # 3256 -rw-r--r-- ioctl.asm
- # 2417 -rw-r--r-- kludge.asm
- # 506 -rw-r--r-- makefile
- # 2744 -rw-r--r-- mt.c
- # 1165 -rw-r--r-- options.inc
- # 2706 -rw-r--r-- readme.10
- # 2983 -rw-r--r-- readme.11
- # 1210 -rw-r--r-- readme.12
- # 11458 -rw-r--r-- scsi.asm
- # 2518 -rw-r--r-- scsi.sys
- # 1931 -rw-r--r-- sformat.c
- # 7166 -rw-r--r-- struct.inc
- # 15830 -rw-r--r-- subs.asm
- # 3322 -rw-r--r-- units.asm
- #
- # ============= binmode.c ==============
- if test -f 'binmode.c' -a X"$1" != X"-c"; then
- echo 'x - skipping binmode.c (File already exists)'
- else
- echo 'x - extracting binmode.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'binmode.c' &&
- X#ifdef MSDOS
- X#include <dos.h>
- X
- Xbinmode(fd)
- Xint fd;
- X{
- X union REGS inregs, outregs;
- X
- X /*
- X ** get the current mode
- X */
- X inregs.h.ah = 0x44; /* ioctl */
- X inregs.h.al = 0x00; /* get */
- X inregs.x.bx = fd; /* unit */
- X intdos(&inregs, &outregs);
- X
- X /*
- X ** set to BINARY mode (this works for char devices)
- X */
- X inregs.h.ah = 0x44; /* ioctl */
- X inregs.h.al = 0x01; /* set */
- X inregs.x.bx = fd; /* unit */
- X inregs.h.dh = 0;
- X inregs.h.dl = outregs.h.dl | 0x20;
- X intdos(&inregs, &outregs);
- X}
- X#endif
- SHAR_EOF
- chmod 0644 binmode.c ||
- echo 'restore of binmode.c failed'
- Wc_c="`wc -c < 'binmode.c'`"
- test 497 -eq "$Wc_c" ||
- echo 'binmode.c: original size 497, current size' "$Wc_c"
- fi
- # ============= dump.asm ==============
- if test -f 'dump.asm' -a X"$1" != X"-c"; then
- echo 'x - skipping dump.asm (File already exists)'
- else
- echo 'x - extracting dump.asm (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'dump.asm' &&
- X;
- X; Convert bin (ax) to ascii (bx => buffer)
- X;
- Xbin_ascii proc near
- X pusha
- X push ax
- X mov cx,6
- Xfill_buff: mov byte ptr [bx],' '
- X inc bx
- X loop fill_buff
- X mov si,10
- X or ax,ax
- X jns clr_dvd
- X neg ax
- Xclr_dvd: sub dx,dx
- X div si
- X add dx,'0'
- X dec bx
- X mov [bx],dl
- X inc cx
- X or ax,ax
- X jnz clr_dvd
- X pop ax
- X or ax,ax
- X jns no_more
- X dec bx
- X mov byte ptr [bx],'-'
- Xno_more: popa
- X ret
- Xbin_ascii endp
- X
- X;
- X; Convert Hex (dx) to Ascii (bx => buffer)
- X;
- Xhex2asc4 proc near
- X push cx
- X push ax
- X mov cx,4 ;Do Four Digits
- Xh241: rol dx,4
- X mov al,dl ;Get the Current Digit
- X and al,0Fh
- X cmp al,0Ah ;Is It Hex?
- X jge h242
- X add al,30h ;Normal Digit
- X jmp h243
- Xh242: add al,37h ;Hex Digit
- Xh243: mov [bx],al ;Insert in Buffer
- X inc bx
- X loop h241
- X pop ax
- X pop cx
- X ret
- Xhex2asc4 endp
- X
- X;
- X; Convert Hex (dl) to Ascii (bx => buffer)
- X;
- Xhex2asc2 proc near
- X push cx
- X push ax
- X mov cx,2 ;Do Two Digits
- Xh221: rol dl,4
- X mov al,dl ;Get the Current Digit
- X and al,0Fh
- X cmp al,0Ah ;Is It Hex?
- X jge h222
- X add al,30h ;Normal Digit
- X jmp h223
- Xh222: add al,37h ;Hex Digit
- Xh223: mov [bx],al ;Insert in Buffer
- X inc bx
- X loop h221
- X pop ax
- X pop cx
- X ret
- Xhex2asc2 endp
- X
- X;
- X; Print a string
- X;
- X; ds:dx => string
- X;
- Xputs proc near
- X pusha
- X mov ah,9 ;DOS print string
- X int 21h
- X popa
- X ret
- Xputs endp
- SHAR_EOF
- chmod 0644 dump.asm ||
- echo 'restore of dump.asm failed'
- Wc_c="`wc -c < 'dump.asm'`"
- test 1296 -eq "$Wc_c" ||
- echo 'dump.asm: original size 1296, current size' "$Wc_c"
- fi
- # ============= equ.inc ==============
- if test -f 'equ.inc' -a X"$1" != X"-c"; then
- echo 'x - skipping equ.inc (File already exists)'
- else
- echo 'x - extracting equ.inc (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'equ.inc' &&
- X;
- X; Equates
- X;
- XTRUE EQU 001h
- XFALSE EQU 000h
- X
- XDISK_REQUEST EQU 000h ;Disk I/O Request
- XTAPE_REQUEST EQU 001h ;Tape I/O Request
- X
- X;
- X; ST-01 Card Registers
- X;
- XSCSI_CARD_SEG EQU 0DE00h ;Base Segment of Card
- XSCSI_CMD_PORT EQU 01A00h ;Offset to Command Port
- XSCSI_DATA_PORT EQU 01C00h ;Offset to Data Port
- X
- XSTACK_SIZE EQU 512 ;Our Local Stack
- X
- X;
- X; How the 16 bit sector number is broken down
- X; into a sector and cylinder number.
- X;
- X; x = Cylinder, y = track, always have only 1 head
- X;
- X; xxxx xxxx xxxx yyyy
- X;
- X; SECT_2_FS is computed as: ((unit_bpb.bpb_ts / CLUSTSIZE) * 2) / P_SECT)
- X;
- XSECT_TRACK EQU 16 ;Logical Sectors in a Track
- XSECT_MASK EQU 0000Fh ;Mask for Sector
- XCYL_MASK EQU 0FFF0h ;Mask for Cylinder
- XSECT_2_CYL EQU 4 ;How far to shift to convert
- X ;Sector to Cylinder Number
- XSECT_2_FS EQU 10 ;How far to shift for
- X ;Total Sectors to Fat Sectors
- X
- X;
- X; The max target to check for (0-X).
- X; If using 'reserve_addr', this should not execede 6!
- X;
- XMAXUNIT EQU 6 ;Maximum Unit Number
- X
- XP_SECT EQU 512 ;Physical Sector Size
- XCLUSTSIZE EQU 4 ;Number of Sectors to a Cluster
- X
- X;
- X; For multi_sector reads and writes,
- X; set the following to '1'
- X;
- X; CHUNK_MASK is the maximum number of sectors to access in one
- X; SCSI request. It MUST be a power of two, and CHUNK_MASK * P_SECT
- X; MUST be <= 64K to prevent segment wrap problems.
- X;
- XCHUNK_MAX EQU 32
- X
- XCMDENABLE EQU 080h ;Enable the output drivers
- XCMDENINTR EQU 040h ;Enable Interrupt
- XCMDPARITY EQU 020h ;Enable Parity
- XCMDSTARB EQU 010h ;Start Bus Arbitration
- XCMDATTN EQU 008h ;Assert ATTN
- XCMDBSY EQU 004h ;Assert BSY
- XCMDSEL EQU 002h ;Assert SEL
- XCMDRST EQU 001h ;Assert RST
- X
- X if scsi_parity
- XCMDBASE EQU CMDPARITY ;Base value of all commands
- X else
- XCMDBASE EQU 000h ;Base value of all commands
- X endif
- X
- XSTARBCOMPL EQU 080h ;Arbitration Complete
- XSTPARERR EQU 040h ;Parity Error
- XSTSEL EQU 020h ;SEL Asserted
- XSTREQ EQU 010h ;REQ Asserted
- XSTCD EQU 008h ;C/D Asserted
- XSTIO EQU 004h ;I/O Asserted
- XSTMSG EQU 002h ;MSG Asserted
- XSTBSY EQU 001h ;BSY Asserted
- X
- XFREE_MASK EQU 03Fh
- X
- XREQ_MASK EQU STMSG or STCD or STIO
- XREQ_DATAOUT EQU 000h ;Data Out Phase
- XREQ_DATAIN EQU STIO ;Data In Phase
- XREQ_CMDOUT EQU STCD ;Command Out Phase
- XREQ_STATIN EQU STCD or STIO ;Status In Phase
- XREQ_MSGOUT EQU STMSG or STCD ;Msg Out Phase
- XREQ_MSGIN EQU STMSG or STCD or STIO ;Msg In Phase
- X
- XCOK EQU 0 ;Command Completed OK
- XCNOCONNECT EQU 1 ;Unable to Connect to Target
- XCBUSBUSY EQU 2 ;Bus Busy
- XCTIMEOUT EQU 3 ;Timeout waiting for Response
- XCERROR EQU 4 ;Target Return Error
- XCBUSY EQU 5 ;Target was Busy
- XCDISCONNECT EQU 6 ;Target Disconnected
- X
- XSCSI_TESTREADY EQU 000h ;Test Unit Ready (6 byte)
- XSCSI_REWIND EQU 001h ;Rewind (6 byte)
- XSCSI_REQSENSE EQU 003h ;Request Sense (6 byte)
- XSCSI_FORMATUNIT EQU 004h ;Format Disk (6 byte)
- XSCSI_WRITEFM EQU 010h ;Write File Marks (6 byte)
- XSCSI_SPACE EQU 011h ;Space Tape (6 byte)
- XSCSI_INQUIRY EQU 012h ;Inquire (6 byte)
- XSCSI_MODE_SET EQU 015h ;Mode Select (6 byte)
- XSCSI_ERASE EQU 019h ;Erase Tape (6 byte)
- XSCSI_MODE_GET EQU 01Ah ;Mode Sense (6 byte)
- XSCSI_LOAD EQU 01Bh ;Load / Unload Tape (6 byte)
- XSCSI_READSIZE EQU 025h ;Read Drive Capacity (10 byte)
- X if extended_io
- XSCSI_READBLK EQU 028h ;Read Sectors (10 byte)
- XSCSI_WRITEBLK EQU 02Ah ;Write Sectors (10 byte)
- X else
- XSCSI_READBLK EQU 008h ;Read Sectors (6 byte)
- XSCSI_WRITEBLK EQU 00Ah ;Write Sectors (6 byte)
- X endif
- XSCSI_VERIFYBLK EQU 02Fh ;Verify Blocks (10 byte)
- X
- XMSG_COMPLETE EQU 000h ;Command is Complete
- XMSG_SAVE EQU 002h ;Save Data Pointers
- XMSG_RESTORE EQU 003h ;Restore Data Pointers
- XMSG_ERROR EQU 005h ;Error Detected
- XMSG_ABORT EQU 006h ;Abort the Command
- XMSG_REJECT EQU 007h ;Reject the Command
- XMSG_NOP EQU 008h ;No Operation
- XMSG_IDENTIFY EQU 080h ;Identify Yourself
- X
- XLOAD_TAPE EQU 001h ;Load
- XUNLOAD_TAPE EQU 000h ;Unload
- X
- X;
- X; We write one filemark at the end of a tape
- X; so that we can space forward over stuff.
- X;
- XCLOSE_FM_CNT EQU 001h
- SHAR_EOF
- chmod 0644 equ.inc ||
- echo 'restore of equ.inc failed'
- Wc_c="`wc -c < 'equ.inc'`"
- test 3921 -eq "$Wc_c" ||
- echo 'equ.inc: original size 3921, current size' "$Wc_c"
- fi
- # ============= ioctl.asm ==============
- if test -f 'ioctl.asm' -a X"$1" != X"-c"; then
- echo 'x - skipping ioctl.asm (File already exists)'
- else
- echo 'x - extracting ioctl.asm (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'ioctl.asm' &&
- X;
- X; Process an ioctl request for the current unit
- X;
- X; return 'C' on error
- X;
- Xscsi_ioctl proc
- X mov al,es:[bx].rh19_minor ;Get the minor number
- X
- X cmp al,40h ;Set Device Params?
- X jnz scsi_i_42h
- X clc
- X jmp short scsi_i_exit
- X
- Xscsi_i_42h: cmp al,42h ;Format and Verify?
- X jnz scsi_i_60h
- X call scsi_verify
- X jmp short scsi_i_exit
- X
- Xscsi_i_60h: cmp al,60h ;Get Device Params?
- X jnz scsi_i_62h
- X mov si,cur_bpb ;Get the Current BPB
- X mov di,es:[bx].rh19_buf_ofs ;Get the Param Buffer
- X mov ax,es:[bx].rh19_buf_seg
- X mov es,ax
- X mov es:[di].dpb_special,05h ;Sect Same/Use Cur BPB
- X mov es:[di].dpb_type,05h ;Fixed Disk
- X mov es:[di].dpb_attr,0001h ;Not Removable
- X mov ax,[si].bpb_ts
- X shr ax,SECT_2_CYL ;Convert Sect to Cyl
- X mov es:[di].dpb_cyl,ax
- X mov es:[di].dpb_media,0 ;????
- X mov es:[di].dpb_sectors,SECT_TRACK ;Sectors per Track
- X
- X push di
- X lea di,es:[di].dpb_bpb ;Copy the bpb into
- X mov cx,size bpb ;the requestors buffer
- X cld
- X rep movsb
- X pop di
- X
- X lea di,es:[di].dpb_track ;Build the Track List
- X mov cx,SECT_TRACK
- X mov ax,0 ;Start with Sector 0
- Xscsi_i_t_loop: mov es:[di],ax ;Sector Number
- X inc ax
- X inc di
- X inc di
- X mov word ptr es:[di],P_SECT ;Sector Size
- X inc di
- X inc di
- X loop scsi_i_t_loop
- X clc
- X jmp short scsi_i_exit
- X
- Xscsi_i_62h: cmp al,62h ;Verify?
- X jnz scsi_i_error
- X call scsi_verify
- X jmp short scsi_i_exit
- X
- Xscsi_i_error: stc
- Xscsi_i_exit: ret
- Xscsi_ioctl endp
- X
- X;
- X; Process an ioctl_write request
- X;
- Xscsi_ioctl_write proc
- X mov di,es:[bx].rh12_buf_ofs ;Get The Command
- X mov ax,es:[bx].rh12_buf_seg ;Buffer
- X mov es,ax
- X mov ax,es:[di].ioc_command ;What Command
- X
- X;
- X; Format Disk Unit
- X;
- X cmp al,'F' ;Format?
- X jnz try_erase
- X mov ax,es:[di].ioc_param1 ;Get Interleave
- X lea di,cmd_format ;Insert into Command
- X mov [di].fmt_cmd_il_b1,ah
- X mov [di].fmt_cmd_il_b0,al
- X call docmd
- X jnc format_exit
- X call scsi_sense
- Xformat_exit: jmp scsi_i_w_exit
- X
- X;
- X; Erase Tape Unit
- X;
- Xtry_erase: cmp al,'E' ;Erase?
- X jnz try_rewind
- X lea di,cmd_erase ;Now Erase Tape
- X call docmd
- X jnc scsi_i_w_exit
- X call scsi_sense
- X jmp scsi_i_w_error
- X
- X;
- X; Rewind Tape Unit
- X;
- Xtry_rewind: cmp al,'R' ;Rewind?
- X jnz try_load
- X lea di,cmd_rewind ;Now Rewind Tape
- X call docmd
- X jnc scsi_i_w_exit
- X call scsi_sense
- X jmp scsi_i_w_error
- X
- X;
- X; Load Tape on Open
- X;
- Xtry_load: cmp al,'L' ;Load?
- X jnz try_noload
- X mov load_flag,TRUE
- X jmp scsi_i_w_exit
- X
- X;
- X; No Load Tape on Open
- X;
- Xtry_noload: cmp al,'N' ;No Load?
- X jnz try_space
- X mov load_flag,FALSE
- X jmp scsi_i_w_exit
- X
- X;
- X; Space Tape
- X;
- Xtry_space: cmp al,'S' ;Space?
- X jnz try_filemark
- X mov ax,es:[di].ioc_param1 ;Get Count
- X mov bx,es:[di].ioc_param2 ;Get Type
- X lea di,cmd_space ;Insert into Command
- X mov [di].space_cmd_code,bl
- X mov [di].space_cmd_cnt2,ah ;Dup of ah
- X mov [di].space_cmd_cnt1,ah
- X mov [di].space_cmd_cnt0,al
- X call docmd
- X jnc scsi_i_w_exit
- X call scsi_sense
- X jmp scsi_i_w_exit
- X
- X;
- X; Write Filemarks
- X;
- Xtry_filemark: cmp al,'M' ;Mark?
- X jnz scsi_i_w_error
- X mov ax,es:[di].ioc_param1 ;Get Count
- X lea di,cmd_twritefm ;Insert into Command
- X mov [di].fm_cmd_cnt_b1,ah
- X mov [di].fm_cmd_cnt_b0,al
- X call docmd
- X jnc scsi_i_w_exit
- X call scsi_sense
- X jmp scsi_i_w_exit
- X
- Xscsi_i_w_error: stc
- Xscsi_i_w_exit: ret
- Xscsi_ioctl_write endp
- SHAR_EOF
- chmod 0644 ioctl.asm ||
- echo 'restore of ioctl.asm failed'
- Wc_c="`wc -c < 'ioctl.asm'`"
- test 3256 -eq "$Wc_c" ||
- echo 'ioctl.asm: original size 3256, current size' "$Wc_c"
- fi
- # ============= kludge.asm ==============
- if test -f 'kludge.asm' -a X"$1" != X"-c"; then
- echo 'x - skipping kludge.asm (File already exists)'
- else
- echo 'x - extracting kludge.asm (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'kludge.asm' &&
- X;
- X; This code is needed because DOS insists on opening a char device
- X; in cooked mode. The problem is that without adding code to every
- X; application that would ever use us, we have no way to alter this
- X; because the use of O_BINARY or setmode() do not affect char devices.
- X;
- X; The solution (kludge) is to watch open requests issued thru the
- X; INT 21 vector. If we see a open request followed by a OPEN_DEV
- X; call to us, it must have been an open for us. So during the return,
- X; force a call to the ioctl facility that will switch to raw mode.
- X;
- X
- X;
- X; The Original INT 21 Vector
- X;
- Xvect_int_21 equ word ptr 4 * 21h
- Xorig_int_21 dd ? ;Original INT 21 Vector
- X
- X;
- X; OPEN_DEV flag is TRUE when we are opened
- X;
- Xopened_flag db FALSE
- X
- Xpatch_us_in proc near
- X push es
- X push ax
- X mov ax,0 ;Patch Ourselves into
- X mov es,ax ;the INT 21 Vector
- X mov ax,es:[vect_int_21] ;Offset
- X mov word ptr orig_int_21,ax
- X lea ax,our_int_21
- X mov es:[vect_int_21],ax
- X mov ax,es:[vect_int_21+2] ;Segment
- X mov word ptr orig_int_21+2,ax
- X mov ax,cs
- X mov es:[vect_int_21+2],ax
- X pop ax
- X pop es
- X ret
- Xpatch_us_in endp
- X
- Xour_int_21 proc far
- X pushf ;Save entry flags
- X cmp ah,3Dh ;Is it an open request?
- X jnz not_open_req
- X popf ;Restore entry flags
- X;
- X; We need to set things up so the 'iret' done by the INT 21
- X; code will have some the right stuff on the stack.
- X; #1 Flags with interrupts enabled
- X; #2 Return Address
- X;
- X sti ;Allow interrupts
- X pushf ;After the iret
- X cli ;Shut interrupts off
- X call cs:orig_int_21 ;While we Pass the request on
- X;
- X; Upon return, interrupts are enabled, so shut them off while we work
- X;
- X pushf
- X cli
- X cmp cs:opened_flag,FALSE ;Was it an open for us?
- X jz not_our_open
- X mov cs:opened_flag,FALSE ;Clear for next time
- X;
- X; We need to forge a call to the ioctl interface
- X; to switch DOS to raw mode when it talks to us
- X;
- X pusha
- X mov bx,ax ;Save the Handle
- X mov ax,4400h ;Get Device Information
- X pushf
- X call cs:orig_int_21
- X mov dh,0 ;Setup
- X or dl,20h ;for RAW Mode
- X mov ax,4401h ;Set Device Information
- X pushf
- X call cs:orig_int_21
- X popa
- X
- Xnot_our_open: popf ;The Original Flags to return
- X;
- X; When we return, we need to pop the flags that the original INT 21
- X; call left on the stack, and return the flags we got back
- X;
- X ret 2 ;Return and discard flags
- X
- Xnot_open_req: popf ;Pop the saved flags
- X jmp cs:orig_int_21 ;Continue with original code
- Xour_int_21 endp
- SHAR_EOF
- chmod 0644 kludge.asm ||
- echo 'restore of kludge.asm failed'
- Wc_c="`wc -c < 'kludge.asm'`"
- test 2417 -eq "$Wc_c" ||
- echo 'kludge.asm: original size 2417, current size' "$Wc_c"
- fi
- # ============= makefile ==============
- if test -f 'makefile' -a X"$1" != X"-c"; then
- echo 'x - skipping makefile (File already exists)'
- else
- echo 'x - extracting makefile (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'makefile' &&
- X#
- X# SCSI Stuff
- X#
- XSRCS = scsi.asm subs.asm ioctl.asm dump.asm units.asm kludge.asm \
- X options.inc equ.inc struct.inc
- X
- Xall: scsi.sys sformat.exe mt.exe
- X
- X#
- X# SCSI Disk Device Driver
- X#
- Xscsi.sys: scsi.obj
- X link +scsi.obj, scsi ;
- X exe2bin scsi.exe scsi.sys
- X
- Xscsi.obj: $(SRCS)
- X masm scsi.asm scsi.obj scsi.lst ;
- X
- X#
- X# SCSI Disk Formatter
- X#
- Xsformat.exe: sformat.c
- X cl -G2 -Ox -o sformat.exe sformat.c
- X
- X#
- X# SCSI Tape Erase
- X#
- Xmt.exe: mt.c
- X cl -G2 -Ox -o mt.exe mt.c
- X
- X#
- X# clean
- X#
- Xclean:
- X rm -f *.exe *.obj *.lst
- SHAR_EOF
- chmod 0644 makefile ||
- echo 'restore of makefile failed'
- Wc_c="`wc -c < 'makefile'`"
- test 506 -eq "$Wc_c" ||
- echo 'makefile: original size 506, current size' "$Wc_c"
- fi
- # ============= mt.c ==============
- if test -f 'mt.c' -a X"$1" != X"-c"; then
- echo 'x - skipping mt.c (File already exists)'
- else
- echo 'x - extracting mt.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'mt.c' &&
- X/*
- X** SCSI Tape Control (Low Level)
- X**
- X** usage: mt [-e|r|l|n|s count|m count]
- X**
- X** Revision History:
- X**
- X** Version 1.0 09/09/90 Initial Release
- X**
- X*/
- X#include <stdio.h>
- X#include <fcntl.h>
- X#include <dos.h>
- X
- X#define TRUE (1)
- X#define FALSE (0)
- X#define VERSION "mt Version 1.0 BWA"
- X
- Xextern int _doserrno;
- X
- Xstruct cmd {
- X short command; /* command type */
- X short arg1; /* command args */
- X short arg2; /* command args */
- X} ioctl_data;
- Xunion REGS inregs, outregs;
- Xstruct SREGS segregs;
- Xint fd;
- Xchar *device = "SCSITAPE", *operation = NULL;
- Xchar far *cp;
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar *argv[];
- X{
- X /*
- X ** say hello
- X */
- X puts(VERSION);
- X switch ( argc )
- X {
- X case 3:
- X if (argv[1][0] != '-' || argv[1][2] != 0) usage();
- X switch( argv[1][1] )
- X {
- X case 's':
- X ioctl_data.command = 'S';
- X ioctl_data.arg1 = atoi(argv[2]);
- X ioctl_data.arg2 = 1; /* space by filemark */
- X if (ioctl_data.arg1 > 0)
- X operation = "space forward";
- X else if (ioctl_data.arg1 < 0)
- X operation = "space backward";
- X else
- X {
- X operation = "space EOD";
- X ioctl_data.arg2 = 3; /* space to EOD */
- X }
- X break;
- X
- X case 'm':
- X ioctl_data.command = 'M';
- X ioctl_data.arg1 = atoi(argv[2]);
- X operation = "filemark";
- X break;
- X
- X default:
- X usage();
- X break;
- X }
- X break;
- X
- X case 2:
- X if (argv[1][0] != '-' || argv[1][2] != 0) usage();
- X switch( argv[1][1] )
- X {
- X case 'e':
- X /*
- X ** verify that this is what the user really wants to do
- X */
- X printf("Do you really wish to erase the tape\n");
- X printf("contained in the SCSITAPE unit (y,n)? ");
- X fflush(stdout);
- X if ( getchar() != 'y' )
- X {
- X printf("Aborting ....\n");
- X exit(1);
- X }
- X operation = "erase";
- X ioctl_data.command = 'E';
- X break;
- X
- X case 'r':
- X operation = "rewind";
- X ioctl_data.command = 'R';
- X break;
- X
- X case 'l':
- X operation = "load enable";
- X ioctl_data.command = 'L';
- X break;
- X
- X case 'n':
- X operation = "load disable";
- X ioctl_data.command = 'N';
- X break;
- X
- X default:
- X usage();
- X break;
- X }
- X break;
- X
- X default:
- X usage();
- X break;
- X }
- X
- X /*
- X ** put together the command
- X */
- X fd = open(device, O_WRONLY);
- X if ( fd < 0 )
- X {
- X perror(device);
- X exit(1);
- X }
- X inregs.h.ah = 0x44; /* ioctl */
- X inregs.h.al = 0x03; /* write */
- X inregs.x.bx = fd; /* unit */
- X inregs.x.cx = sizeof(struct cmd);
- X cp = (char *) &ioctl_data;
- X inregs.x.dx = FP_OFF(cp);
- X segregs.ds = FP_SEG(cp);
- X
- X /*
- X ** start the format
- X */
- X printf("Now performing %s command ....\n", operation);
- X puts("Please wait ....");
- X intdosx(&inregs, &outregs, &segregs);
- X
- X /*
- X ** see what happened
- X */
- X if ( outregs.x.cflag )
- X printf("DOS error %d occured during %s.\n", _doserrno, operation);
- X close(fd);
- X exit(0);
- X}
- X
- Xusage()
- X{
- X puts("usage: mt [-e|r|l|n|s count|m count]");
- X exit(1);
- X}
- SHAR_EOF
- chmod 0644 mt.c ||
- echo 'restore of mt.c failed'
- Wc_c="`wc -c < 'mt.c'`"
- test 2744 -eq "$Wc_c" ||
- echo 'mt.c: original size 2744, current size' "$Wc_c"
- fi
- # ============= options.inc ==============
- if test -f 'options.inc' -a X"$1" != X"-c"; then
- echo 'x - skipping options.inc (File already exists)'
- else
- echo 'x - extracting options.inc (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'options.inc' &&
- X;
- X; Allow multi_sector reads and writes.
- X;
- X; This means that a read request of less then CHUNK_MAX
- X; sectors will be done in one request to the drive rather
- X; then multiple single sector requests.
- X;
- X; The disadvantage here is that the code in receive_data()
- X; and send_data() must keep the transfer from exceding the
- X; 512 byte buffer on the ST-01 card.
- X;
- Xmulti_sector = 1 ;Enable multi_sector support
- X
- X;
- X; Use the extended SCSI commands for reads and writes.
- X;
- X; This means that we can access drives larger then 1Gb
- X; and read/write more then 256 sectors per command.
- X;
- X; The disadvantage here is that not all devices support
- X; the extended command set.
- X;
- Xextended_io = 0 ;Disable use of extended io commands
- X
- X;
- X; Use parity on the SCSI bus
- X;
- Xscsi_parity = 1 ;Enable use of parity on the SCSI bus
- X
- X;
- X; Reserve SCSI Address 7 for card
- X;
- Xreserve_addr = 1 ;Reserve Address for Card Use
- X
- X;
- X; Dump Sense information to the screen
- X;
- Xdump_sense = 1 ;Dump Sense Message to the Screen
- X
- X;
- X; Extended Sense or Normal Sense
- X;
- Xextended_sense = 1 ;Request Extended Sense
- X
- X;
- X; Include the code to kludge the RAW ioctl call after an open
- X;
- Xuse_kludge = 1 ;Enable the ioctl kludge
- SHAR_EOF
- chmod 0644 options.inc ||
- echo 'restore of options.inc failed'
- Wc_c="`wc -c < 'options.inc'`"
- test 1165 -eq "$Wc_c" ||
- echo 'options.inc: original size 1165, current size' "$Wc_c"
- fi
- # ============= readme.10 ==============
- if test -f 'readme.10' -a X"$1" != X"-c"; then
- echo 'x - skipping readme.10 (File already exists)'
- else
- echo 'x - extracting readme.10 (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'readme.10' &&
- XScsi Version 1.0
- X
- X The code you received with this file is a very simple SCSI device
- Xdriver that uses the Seagate ST-01 interface card. As this driver is
- Xmy first PC assembler project other then "hello world", please don't
- Xsnicker to loudly.
- X
- X The package includes the source for a device driver that will scan
- Xthe SCSI bus for disk drives and partition any drives found into chunks
- Xof 32Meg plus any leftovers. As soon as I discover a way to get DOS to
- Xlet me use > 512 byte sectors, It will just allocate the entire disk to
- Xa single logical drive. It also includes a utility to access the low
- Xlevel SCSI format function for any disk found. You may specify the
- Xinterleave when the low level format is done and the version of the
- Xdriver here seems to work fine at 1:1 with my 8Mhz NEC.
- X
- X Some of the things to look out for are:
- X
- X#1 The receive_data and send_data functions in subs.asm use polled I/O
- X to transfer data to/from the card. I would have loved to just use
- X the I/O Channel Ready line that the card is suppose to support, but
- X my NEC does not seem to use that line. Hence the polling of the REQ
- X bit in the status port.
- X
- X#2 I did not know how to do clock speed independent timing loops, so there
- X is a wait100us function in subs.asm that is very processor speed
- X dependent :-(
- X
- X#3 In ioctl.asm there is a commented out call to scsi_verify. This is
- X used by the DOS format utility to scan for errors. You may want to
- X enable the call after you get everything setup. I shut it off while
- X I was testing as I didn't want to wait for the verify everytime I
- X changed the interleave.
- X
- X To bring up the driver. Assemble and link scsi.sys and add it to
- Xyour config.sys file. After rebooting, you may optionaly do a low level
- Xformat of each disk found using sformat.exe. You then use the DOS format
- Xutility on each logical drive. I did figure out just what format needed
- Xin the way of ioctl support to get it to do the high level format for me.
- XAt this point you should have fully functional DOS drives. In testing
- XI found that with multi_sector support (subs.asm) enabled, the SCSI drives
- Xwere just about as fast as the ST-412 C: that came with the machine. I
- Xam sure that the speed problem is basic to the inner loop of the data
- Xtransfer routines, but I'm at a loss to figure out how to speed it up.
- X
- X Anyway, maybe someone can find some use for the code. I got the
- Xcard for free, so I can't really complain about the speed or cost too
- Xmuch :-)
- X
- X Also thanks to the people that sent me samples of other device drivers
- Xfor the PC. I lost the names to a disk crash, but here is the result of
- Xyour help and my thanks.
- X
- XBrian Antoine
- XAug 29, 1990
- SHAR_EOF
- chmod 0644 readme.10 ||
- echo 'restore of readme.10 failed'
- Wc_c="`wc -c < 'readme.10'`"
- test 2706 -eq "$Wc_c" ||
- echo 'readme.10: original size 2706, current size' "$Wc_c"
- fi
- # ============= readme.11 ==============
- if test -f 'readme.11' -a X"$1" != X"-c"; then
- echo 'x - skipping readme.11 (File already exists)'
- else
- echo 'x - extracting readme.11 (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'readme.11' &&
- XScsi Version 1.1
- X
- X This version of the driver add support for a single tape drive, and
- Xcleans up some of the code a little. It also adds a file that has equates
- Xto customize some of the major areas of the driver.
- X
- X When the driver is initialized it does a scan of the SCSI bus for
- Xdevices. The FIRST tape device found is assigned to a char device with the
- Xname "SCSITAPE". If no tape drive is found, the char device is still valid
- Xbut will generate a "bad unit" error when accessed.
- X
- X The SCSITAPE device expects reads and writes to be done in some variation
- Xof 512 bytes. I/O done where (size mod 512) is non-zero will generate an
- Xerror. Tape access must be done in RAW mode, and this is where I had to
- Xsome code in the driver that I'm not sure is very pretty. The problem is
- Xthat DOS insists on opening char devices in cooked mode. It does give you
- Xthe ability to switch to RAW mode, but only by using 'intdos()' to access
- Xthe ioctl interface. The MSC 'setmode()' call for binary will not effect
- Xchar devices, nor will opening the file with O_BINARY. So I had two choices.
- XI could modify every program that expected to talk to the tape so that it
- Xalso issued the ioctl stuff (see binmode.c), or I could kludge the driver
- Xto issue the required calls.
- X
- X In the end, I punted and did both. The code in binmode.c is the function
- Xthat along with 'setmode()', will make sure that ANYTHING you open is accessed
- Xin RAW mode. Simply check for any call to 'setmode()' that is switching to
- XO_BINARY, and add another call to 'binmode()'. This assumes that you have
- Xthe source to the utility in question. For those who are don't mind a little
- Xkludge amount friends. The file options.inc has an equate called 'use_kludge'
- Xthat when enabled turns on some code in kludge.asm. This code links into the
- XINT 21h vector and waits for a DOS open request to go by. When it sees an
- Xopen request, it 'calls' rather then 'jmps' to the normal vector. This allows
- Xthe driver to get the 'handle' returned by DOS. Because the SCSITAPE device
- Xenables the driver_open function, I can tell from the fact that an open is
- Xin progress and wether the driver just got an open request, wether any
- Xparticular open was for me. When the open was in fact for the SCSITAPE device,
- XI take the 'handle' returned by DOS and forge the required ioctl calls to
- Xswitch to RAW mode.
- X
- X With the addition of tape support. I now use GNU Tar to swap tapes with
- Xmy normal UN*X system at work. The driver works well enough that I have yet
- Xto have a format problem with the different systems. It is also a lot faster
- Xwhen doing backups on the PC. Using 'fastback' I would get about 1 Meg a
- Xminute thruput on my 8 Mhz AT. Using GNU Tar and the SCSITAPE device I get
- X> 2.5 Meg a minute to the tape and don't have to swap disks quite so often :-)
- X
- X Anyway, I hope that someone out there actually gets some use out of this
- Xcode. It has been a real adventure for me.
- X
- XBrian Antoine
- XSept 8, 1990
- SHAR_EOF
- chmod 0644 readme.11 ||
- echo 'restore of readme.11 failed'
- Wc_c="`wc -c < 'readme.11'`"
- test 2983 -eq "$Wc_c" ||
- echo 'readme.11: original size 2983, current size' "$Wc_c"
- fi
- # ============= readme.12 ==============
- if test -f 'readme.12' -a X"$1" != X"-c"; then
- echo 'x - skipping readme.12 (File already exists)'
- else
- echo 'x - extracting readme.12 (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'readme.12' &&
- XScsi Version 1.2
- X
- X This version of the driver enhances the tape drive support by adding
- Xa program to control the action of the tape drive, and move around within
- Xmultiple containers on the tape. As I used the Bezerkley 'mt' command for
- Xideas, the program is naturally called 'mt'. You can tell the driver to:
- X
- X#1 Rewind/No Rewind on close.
- X#2 Erase the tape.
- X#3 Step forwards or backwards X tape marks.
- X Note: the command 'mt -s 0' steps to End Of Data.
- X
- X I also did a little more work on the routines that actually transfer
- Xdate to/from the card. I found that I had left out a check for timeout
- Xin the inner loops of the the data xfer routines. When the random parity
- Xerror or other glitch occured. The driver would hang forever. Not very
- Xfriendly... The added code does not seem to slow the driver any, or at
- Xleast the disk thru-put tester I use shows no difference.
- X
- X As the driver seems to be stable now, and it does about everything
- XI started out to do. I'm going to post this to comp.sources.misc instead
- Xof alt.sources in the hopes that more people will see it. Hopefully this
- Xwill be usefull to someone else (at least they might get a good chuckle).
- X
- XBrian Antoine
- XSept 25, 1990
- SHAR_EOF
- chmod 0644 readme.12 ||
- echo 'restore of readme.12 failed'
- Wc_c="`wc -c < 'readme.12'`"
- test 1210 -eq "$Wc_c" ||
- echo 'readme.12: original size 1210, current size' "$Wc_c"
- fi
- # ============= scsi.asm ==============
- if test -f 'scsi.asm' -a X"$1" != X"-c"; then
- echo 'x - skipping scsi.asm (File already exists)'
- else
- echo 'x - extracting scsi.asm (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'scsi.asm' &&
- X;
- X; Simple SCSI Device Driver
- X;
- X .286
- X PAGE 76,132
- X
- X INCLUDE options.inc
- X INCLUDE equ.inc
- X INCLUDE struct.inc
- X;
- X; Start of Code and Data
- X;
- X_TEXT segment word public 'CODE'
- X assume cs:_TEXT, ds:_TEXT, es:_TEXT
- X
- X org 0
- X
- X;
- X; Device Header Required By DOS
- X;
- Xscsi:
- Xtape_link_ofs dw disk_link_ofs ;Forward Link
- Xtape_link_seg dw -1
- X dw 0C800h ;Char Device
- X dw tape_strategy ;Address of 1st DOS Call
- X dw dev_interrupt ;Address of 2nd DOS Call
- X db 'SCSITAPE' ;Device Name
- X
- Xdisk_link_ofs dw -1 ;Forward Link
- Xdisk_link_seg dw -1
- X dw 06040h ;Ioctl R/W, Block Device, Non-IBM, Get/Set
- X dw disk_strategy ;Address of 1st DOS Call
- X dw dev_interrupt ;Address of 2nd DOS Call
- Xdisk_count db 0 ;Number of Disks Present
- X db 7 dup(?)
- X
- X;
- X; Work Space For Our Device Driver
- X;
- X even
- Xrh_off dw ? ;Request Header Offset
- Xrh_seg dw ? ;Request Header Segment
- Xrh_type db ? ;Request Type
- X
- Xwrite_flag db FALSE ;TRUE When Tape Write Seen
- Xload_flag db TRUE ;TRUE When Tape should Load/Unload
- Xcur_drive db -1
- Xvol_id db 'NO NAME ',0
- X
- X;
- X; Define our own personal Stack
- X;
- X even
- Xnew_stack db STACK_SIZE-2 dup (?) ;Our Local Stack
- Xnew_stack_top dw ?
- X
- Xstack_ptr dw ? ;Old Stack Pointer
- Xstack_seg dw ? ;Old Stack Segment
- X
- X;
- X; Command Table
- X;
- Xcmdtab label byte ;* = Char Only Devices
- X dw INITIALIZATION ;Initialization
- X dw MEDIA_CHECK ;Media Check (Block Only)
- X dw GET_BPB ;Build BPB (Block Only)
- X dw unknown ;IOCTL Read
- X dw READ ;Read Data
- X dw done ;*Non Destructive Read
- X dw done ;*Read Status
- X dw done ;*Flush Read Buffer
- X dw WRITE ;Write Data
- X dw WRITE_VERIFY ;Write With Verify
- X dw done ;*Write Status
- X dw done ;*Flush Write Buffer
- X dw WRITE_IOCTL ;IOCTL Write
- X dw OPEN_DEV ;Device Open
- X dw CLOSE_DEV ;Device Close
- X dw done ;Removable Check
- X dw unknown ;*Write Until Busy
- X dw unknown ;Unknown Call
- X dw unknown ;Unknown Call
- X dw IOCTL ;Generic Ioctl
- X dw unknown ;Unknown Call
- X dw unknown ;Unknown Call
- X dw unknown ;Unknown Call
- X dw GET_DEV ;Get Device
- X dw SET_DEV ;Set Device
- X
- X;
- X; Strategy Procedure
- X;
- Xdisk_strategy proc far
- X mov cs:rh_seg,es ;Save Request Header Ptr Segment
- X mov cs:rh_off,bx ;Save Request Header Ptr Offset
- X mov cs:rh_type,DISK_REQUEST
- X ret
- Xdisk_strategy endp
- X
- Xtape_strategy proc far
- X mov cs:rh_seg,es ;Save Request Header Ptr Segment
- X mov cs:rh_off,bx ;Save Request Header Ptr Offset
- X mov cs:rh_type,TAPE_REQUEST
- X ret
- Xtape_strategy endp
- X
- X;
- X; Interrupt Procedure
- X;
- Xdev_interrupt proc far
- X cli ;Save Machine State On Entry
- X push ds
- X push es
- X push ax
- X push bx
- X push cx
- X push dx
- X push si
- X push di
- X push bp
- X pushf
- X
- X mov cs:stack_seg,ss ;Save Old Stack
- X mov cs:stack_ptr,sp
- X
- X mov ax,cs ;Save us the Segment Override Crap
- X mov ds,ax
- X mov es,ax
- X
- X mov ss,ax ;Setup Our Local Stack
- X lea ax,new_stack_top
- X mov sp,ax
- X sti ;We're Safe Now
- X
- X;
- X; Perform branch based on the command passed in the Request Header
- X;
- X mov es,rh_seg ;Point us at the Request Header
- X mov bx,rh_off
- X
- X mov al,es:[bx].rh_cmd ;Get Command Code
- X rol al,1 ;Get offset into table
- X lea di,cmdtab ;Get address of command table
- X mov ah,0 ;Clear hi order byte
- X add di,ax ;Add offset
- X jmp word ptr [di] ;Jump Indirect
- X
- X;
- X; Command Procedures
- X;
- XINITIALIZATION: cmp rh_type,TAPE_REQUEST ;Is this SCSITAPE: Init?
- X jz init_skip
- X mov al,es:[bx].rh0_drv_ltr ;Save the starting Drive
- X add al,041h
- X mov cur_drive,al
- X call initial ;Setup
- X if use_kludge
- X call patch_us_in
- X endif
- X mov bx,rh_off
- X mov es,rh_seg
- Xinit_skip: lea ax,initial ;Set The Break Address
- X mov es:[bx].rh0_brk_ofs,ax
- X mov es:[bx].rh0_brk_seg,cs
- X mov al,disk_count ;Number of Disk Devices Supported
- X mov es:[bx].rh0_nunits,al
- X lea dx,bpb_array ;BPB Array
- X mov es:[bx].rh0_bpb_tbo,dx
- X mov es:[bx].rh0_bpb_tbs,cs
- X jmp done
- X
- X;
- X; Has the Media Changed
- X;
- XMEDIA_CHECK: call find_unit
- X jc mc_jmp_err
- X mov di,cur_unit
- X mov al,[di].unit_mcheck ;Get Initial Status
- X mov [di].unit_mcheck,1 ;Always OK from then on
- X mov es:[bx].rh1_md_stat,al
- X lea dx,vol_id ;Address of Volume ID
- X mov es:[bx].rh1_volid_ofs,dx
- X mov es:[bx].rh1_volid_seg,cs
- X jmp done
- Xmc_jmp_err: jmp bad_unit
- X
- X;
- X; Get Disk Parameter Block
- X;
- XGET_BPB: call find_unit
- X jc get_jmp_err
- X mov dx,cur_bpb ;Address of BPB
- X mov es:[bx].rh2_pbpbo,dx
- X mov es:[bx].rh2_pbpbs,cs
- X jmp done
- Xget_jmp_err: jmp bad_unit
- X
- X;
- X; Read some data from the disk/tape
- X;
- XREAD: cmp rh_type,DISK_REQUEST
- X jz read_a_disk
- X mov ax,tape_unit ;Do We Have a Tape?
- X cmp ax,-1
- X jz read_jmp_err1
- X mov cur_unit,ax
- X call tape_read
- X jc read_jmp_err2
- X jmp done
- Xread_a_disk: call find_unit
- X jc read_jmp_err1
- X call disk_read
- X jc read_jmp_err2
- X jmp done
- Xread_jmp_err1: jmp bad_unit
- Xread_jmp_err2: jmp bad_read
- X
- X;
- X; Write some data to the disk/tape
- X;
- XWRITE equ $
- XWRITE_VERIFY: cmp rh_type,DISK_REQUEST
- X jz write_a_disk
- X mov ax,tape_unit ;Do We Have a Tape?
- X cmp ax,-1
- X jz write_jmp_err1
- X mov cur_unit,ax
- X call tape_write
- X jc write_jmp_err2
- X jmp done
- Xwrite_a_disk: call find_unit
- X jc write_jmp_err1
- X call disk_write
- X jc write_jmp_err2
- X jmp done
- Xwrite_jmp_err1: jmp bad_unit
- Xwrite_jmp_err2: jmp bad_write
- Xwrite_jmp_err3: jmp unknown
- X
- X;
- X; Write Ioctl Packet
- X;
- XWRITE_IOCTL: cmp rh_type,DISK_REQUEST
- X jz ioctl_a_disk
- X mov ax,tape_unit ;Do we have a SCSITAPE?
- X cmp ax,-1
- X jz write_jmp_err1
- X mov cur_unit,ax
- X jmp short ioctl_do
- Xioctl_a_disk: call find_unit
- X jc write_jmp_err1
- Xioctl_do: call scsi_ioctl_write
- X jc write_jmp_err3
- X jmp done
- X
- X;
- X; Special Control Functions
- X;
- XIOCTL: call find_unit
- X jc ioctl_jmp_err1
- X call scsi_ioctl
- X jc ioctl_jmp_err2
- X jmp done
- Xioctl_jmp_err1: jmp bad_unit
- Xioctl_jmp_err2: jmp unknown
- X
- X;
- X; Open Tape Device
- X;
- XOPEN_DEV: mov di,tape_unit
- X cmp di,-1 ;Do We have a SCSITAPE: Unit?
- X jz open_err1
- X mov cur_unit,di ;New Current 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 jc open_err2
- X cmp load_flag,TRUE ;Should we LOAD?
- X jnz open_ok
- X lea di,cmd_load ;Now Load Tape
- X mov [di].load_cmd_type,LOAD_TAPE
- X call docmd
- X jnc open_ok
- X call scsi_sense
- Xopen_err2: jmp general
- Xopen_err1: jmp bad_unit
- Xopen_ok: mov opened_flag,TRUE ;We are open
- X mov write_flag,FALSE ;No Writes Seen
- X jmp done
- X
- X;
- X; Close Tape Device
- X;
- XCLOSE_DEV: mov di,tape_unit
- X cmp di,-1 ;Do We have a SCSITAPE: Unit?
- X jz close_err1
- X mov cur_unit,di ;New Current Unit
- X cmp write_flag,TRUE ;Were We Writing?
- X jnz tape_no_write
- X lea di,cmd_twritefm ;End Tape with FM(s)
- X mov [di].fm_cmd_cnt_b0,CLOSE_FM_CNT
- X call docmd
- X jnc tape_no_write
- X call scsi_sense
- Xtape_no_write: cmp load_flag,TRUE ;Should we Unload?
- X jnz close_ok
- X lea di,cmd_load ;Now Unload Tape
- X mov [di].load_cmd_type,UNLOAD_TAPE
- X call docmd
- X jnc close_ok
- X call scsi_sense
- Xclose_err2: jmp general
- Xclose_err1: jmp bad_unit
- Xclose_ok: jmp done
- X
- X;
- X; Get Device Assignment
- X;
- XGET_DEV: mov es:[bx].rh_unit,0
- X jmp done
- X
- X;
- X; Set Device Assignment
- X;
- XSET_DEV: jmp done
- X
- Xbad_unit: mov es,rh_seg ;Point us at the Request Header
- X mov bx,rh_off
- X or es:[bx].rh_status,8001h
- X jmp short done
- X
- Xunknown: mov es,rh_seg ;Point us at the Request Header
- X mov bx,rh_off
- X or es:[bx].rh_status,8003h
- X jmp short done
- X
- Xbad_write: mov es,rh_seg ;Point us at the Request Header
- X mov bx,rh_off
- X or es:[bx].rh_status,800Ah
- X jmp short done
- X
- Xbad_read: mov es,rh_seg ;Point us at the Request Header
- X mov bx,rh_off
- X or es:[bx].rh_status,800Bh
- X jmp short done
- X
- Xgeneral: mov es,rh_seg ;Point us at the Request Header
- X mov bx,rh_off
- X or es:[bx].rh_status,800Ch
- X jmp short done
- X
- Xbusy: mov es,rh_seg ;Point us at the Request Header
- X mov bx,rh_off
- X or es:[bx].rh_status,0200h
- X
- Xdone: mov es,rh_seg ;Point us at the Request Header
- X mov bx,rh_off
- X or es:[bx].rh_status,0100h
- X
- X cli ;Make sure we're left alone
- X mov ax,cs:stack_seg ;Restore DOS Stack
- X mov ss,ax
- X mov ax,cs:stack_ptr
- X mov sp,ax
- X
- X popf ;Restore All Registers
- X pop bp
- X pop di
- X pop si
- X pop dx
- X pop cx
- X pop bx
- X pop ax
- X pop es
- X pop ds
- X sti ;We're Safe Now
- X ret
- X
- X INCLUDE units.asm
- X INCLUDE subs.asm
- X INCLUDE ioctl.asm
- X INCLUDE dump.asm
- X if use_kludge
- X INCLUDE kludge.asm
- X endif
- X
- X;
- X; End of Program
- X; Stuff Placed Here Gets Handed Back To DOS For Re-use
- X;
- Xinitial proc near
- X lea dx,hello_msg ;Tell them the driver version
- X call puts
- X push cs
- X pop dx
- X lea bx,seg_msg_value
- X call hex2asc4
- X lea dx,seg_msg ;And Were We Loaded
- X call puts
- X
- X call scsi_reset ;Reset the bus
- X
- X mov cx,0 ;Scan for devices
- Xscan: mov ax,cx
- X add al,030h
- X mov scan_dev,al
- X mov ax,1 ;Create Select Bit
- X shl ax,cl
- X if reserve_addr
- X or al,80h ;Add Card Select Bit
- X endif
- X mov di,cur_unit
- X mov [di].unit_select,al
- X mov [di].unit_num_drv,0 ;No Drives to start with
- X mov al,disk_count ;We will start with
- X mov [di].unit_1st_drv,al ;Drive Number if any
- X
- X lea dx,scan_dev ;Print the device number
- X call puts
- X call scsi_inquire ;Inquire as to its type
- X jnc scan_inq_ok
- X jmp scan_err
- X
- Xscan_inq_ok: mov di,cur_unit
- X lea dx,[di].unit_inq_buf.inq_manufact
- X mov [di].unit_inq_term,'$'
- X mov al,[di].unit_inq_buf.inq_dev_type
- X or al,al ;Look at device type
- X jz scan_is_drv
- X cmp tape_unit,-1 ;Do We Already Have A Tape?
- X jnz tape_jmp
- X call puts ;Make this our SCSITAPE: Unit
- X mov tape_unit,di
- X lea dx,tape_msg
- Xtape_jmp: jmp scan_puts
- X
- Xscan_is_drv: call puts ;Output the Device String
- X call scsi_capacity ;Inquire as to its size
- X lea dx,err_size
- X jc scan_puts ;Do not use unknown drives
- X lea dx,crlf
- X call puts
- X
- Xscan_next_drv: mov di,cur_unit
- X mov al,disk_count ;Number Of Drives Found
- X inc al
- X mov disk_count,al
- X mov al,[di].unit_num_drv ;We have a valid Drive
- X inc al
- X mov [di].unit_num_drv,al
- X mov al,cur_drive ;Get Current Drive Letter
- X mov drv_msg_let,al ;Insert it in message
- X inc al ;Bump Drive Letter
- X mov cur_drive,al
- X call make_bpb ;Setup the BPB for this drive
- X mov di,cur_bpb ;Current Working BPB
- X mov ax,[di].bpb_ts
- X shr ax,11
- X inc ax
- X lea bx,drv_msg_size
- X call bin_ascii
- X mov bx,bpb_hw_mark ;Get the BPB High Water Mark
- X inc bx ;Bump HW Mark for next time
- X inc bx
- X mov ax,[bx] ;Get the BPB
- X mov cur_bpb,ax ;Make it the current BPB
- X mov bpb_hw_mark,bx
- X lea dx,drv_msg
- X call puts
- X mov bx,cur_unit
- X mov ah,0
- X mov al,[bx].unit_num_drv ;Insert Drive Offset
- X dec al ;Into BPB for this Drive
- X mov [di].bpb_hs_msw,ax
- X mov al,[bx].unit_cap_buf.cap_sectors_b3
- X or al,[bx].unit_cap_buf.cap_sectors_b2
- X or al,[bx].unit_cap_buf.cap_sectors_b1
- X or al,[bx].unit_cap_buf.cap_sectors_b0
- X jnz scan_next_drv ;Room left for another Drive
- X jmp short scan_next
- X
- Xscan_err: lea dx,no_dev
- X cmp al,CNOCONNECT
- X jz scan_puts
- X lea dx,err_dev
- Xscan_puts: call puts
- X lea dx,crlf
- X call puts
- X
- Xscan_next: inc cx
- X cmp cx,MAXUNIT ;End of devices?
- X jg scan_exit
- X mov bx,cx ;Bump to next unit
- X shl bx,1
- X mov ax,word ptr unit_array[bx]
- X mov cur_unit,ax
- X jmp scan
- X
- Xscan_exit: ret
- Xinitial endp
- X
- X;
- X; Data Area Used Only During Initialization
- X;
- Xhello_msg db 0dh,0ah,'SCSI Device Driver Version 1.2',0Dh,0Ah,'$'
- Xseg_msg db 'Driver Loaded At Segment '
- Xseg_msg_value db '0000',0dh,0ah,'$'
- Xscan_dev db 'X - ','$'
- Xno_dev db '(No Installed Device)$'
- Xerr_dev db '(Error On Device)$'
- Xerr_size db 'unknown size$'
- Xdrv_msg db ' - Drive '
- Xdrv_msg_let db 'X: '
- Xdrv_msg_size db 'XXXXXX Meg',0dh,0ah,'$'
- Xtape_msg db 0dh,0ah,' - Is The SCSITAPE: Device$'
- Xcrlf db 0dh,0ah,'$'
- X
- Xdev_interrupt endp
- X_TEXT ends
- X end
- SHAR_EOF
- chmod 0644 scsi.asm ||
- echo 'restore of scsi.asm failed'
- Wc_c="`wc -c < 'scsi.asm'`"
- test 11458 -eq "$Wc_c" ||
- echo 'scsi.asm: original size 11458, current size' "$Wc_c"
- fi
- # ============= scsi.sys ==============
- if test -f 'scsi.sys' -a X"$1" != X"-c"; then
- echo 'x - skipping scsi.sys (File already exists)'
- else
- echo 'x - extracting scsi.sys (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'scsi.sys' &&
- XHSCSITAPE@`nNO NAME L2IPPPvvPP&Z#PGgo.&. $.F(K.&. $.F(KzPSQRVWU.:. &8HX@P
- XGP@
- XEFE&G
- Xi)Xr_i hPrhN
- Xri|ii(>t/ >
- XG
- X@t
- X7:ft
- XFF~F~Hutk #xkGGbVyaC>GFEGEFEGE
- Xg%
- XG&@tHg%G&:k
- Xw'FG'2FG(J UFE
- XxAj
- XB UGEGEGEGEC
- X
- X %/SCSI Unit: 0xxx, Sense Status: 0xxx, Block Address: 0xxxxxxxxx
- X$`8^@>&G+A& GCF){&MA%t&GEyC&]&E@CAhFpFc
- XE
- X@t>uh$ >
- XE~@E +"F~@"+h x>EAh@
- XG~H E
- XG%
- XG&
- XG'
- XG(uk
- XSCSI Device Driver Version 1.2
- X$Driver Loaded At Segment 0000
- X$X - $(No Installed Device)$(Error On Device)$unknown size$ - Drive X: XXXXXX Meg
- X$
- X - Is The SCSITAPE: Device$
- X$
- SHAR_EOF
- chmod 0644 scsi.sys ||
- echo 'restore of scsi.sys failed'
- Wc_c="`wc -c < 'scsi.sys'`"
- test 2518 -eq "$Wc_c" ||
- echo 'scsi.sys: original size 2518, current size' "$Wc_c"
- fi
- # ============= sformat.c ==============
- if test -f 'sformat.c' -a X"$1" != X"-c"; then
- echo 'x - skipping sformat.c (File already exists)'
- else
- echo 'x - extracting sformat.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'sformat.c' &&
- X/*
- X** SCSI Disk Formatter (Low Level)
- X**
- X** usage: sformat drive: [interleave]
- X**
- X** Revision History:
- X**
- X** Version 1.0 08/03/90 Initial Release
- X**
- X** Version 1.1 08/20/90 Add verification message.
- X**
- X** Version 1.2 09/18/90 Correct ioctl_data struct.
- X*/
- X#include <stdio.h>
- X#include <dos.h>
- X
- X#define TRUE (1)
- X#define FALSE (0)
- X#define VERSION "sformat Version 1.2 BWA"
- X
- Xextern int _doserrno;
- X
- Xstruct cmd {
- X short command; /* command type */
- X short arg1; /* command args */
- X short arg2; /* command args */
- X} ioctl_data;
- Xunion REGS inregs, outregs;
- Xstruct SREGS segregs;
- Xunsigned short interleave = 0;
- Xunsigned char drive;
- Xchar far *cp;
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar *argv[];
- X{
- X /*
- X ** say hello
- X */
- X puts(VERSION);
- X
- X /*
- X ** figure out who to format
- X */
- X switch (argc)
- X {
- X case 3:
- X interleave = atoi(argv[2]);
- X case 2:
- X if (argv[1][1] != ':') usage();
- X drive = argv[1][0];
- X drive = toupper(drive);
- X drive -= '@';
- X break;
- X
- X default:
- X usage();
- X break;
- X }
- X
- X /*
- X ** verify that this is what the user really wants to do
- X */
- X printf("Do you really wish to format the SCSI\n");
- X printf("device that contains drive %c: (y,n)? ", argv[1][0]);
- X fflush(stdout);
- X if ( getchar() != 'y' )
- X {
- X puts("Aborting low level format ....");
- X exit(1);
- X }
- X
- X /*
- X ** put together the command
- X */
- X inregs.h.ah = 0x44; /* ioctl */
- X inregs.h.al = 0x05; /* write */
- X inregs.h.bl = drive; /* unit */
- X inregs.x.cx = sizeof(struct cmd);
- X cp = (char *) &ioctl_data;
- X inregs.x.dx = FP_OFF(cp);
- X segregs.ds = FP_SEG(cp);
- X ioctl_data.command = 'F';
- X ioctl_data.arg1 = interleave;
- X
- X /*
- X ** start the format
- X */
- X puts("Now formating ....");
- X puts("Please wait ....");
- X intdosx(&inregs, &outregs, &segregs);
- X
- X /*
- X ** see what happened
- X */
- X if ( outregs.x.cflag )
- X printf("DOS error %d occured during format.\n", _doserrno);
- X else
- X puts("Formating complete.");
- X exit(0);
- X}
- X
- Xusage()
- X{
- X puts("usage: sformat drive: [interleave]");
- X exit(1);
- X}
- SHAR_EOF
- chmod 0644 sformat.c ||
- echo 'restore of sformat.c failed'
- Wc_c="`wc -c < 'sformat.c'`"
- test 1931 -eq "$Wc_c" ||
- echo 'sformat.c: original size 1931, current size' "$Wc_c"
- fi
- true || echo 'restore of struct.inc failed'
- echo End of part 1, continue with part 2
- exit 0
-
-
-