[comp.sources.amiga] v90i264: tape-handler - read/write scsi tape drives, Part01/01

amiga-request@abcfd20.larc.nasa.gov (Amiga Sources/Binaries Moderator) (10/09/90)

Submitted-by: lphillips@lpami.wimsey.bc.ca
Posting-number: Volume 90, Issue 264
Archive-name: devices/tapehandler/part01

[ uuencoded executable enclosed  ...tad ]

This contains source, documentation, and executable for tape-handler,
a handler designed to allow you to read/write tapes on SCSI tape
drives.

#!/bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 1 (of 1)."
# Contents:  POSTER makefile misc.c misc.o32.uu mountlist.entry req.c
#   req.o32.uu tape-handle.uu tape.doc tapedev.c tapedev.o32.uu
# Wrapped by tadguy@abcfd20 on Mon Oct  8 17:04:48 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'POSTER' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'POSTER'\"
else
echo shar: Extracting \"'POSTER'\" \(1023 characters\)
sed "s/^X//" >'POSTER' <<'END_OF_FILE'
XI have spoken with Markus Wandel about his tape handler software, and told him
Xhow many requests were being posted asking for it, or something like it.
X
X He has decided that he wishes to place it in the public domain, on the
Xunderstanding that he is not in a position to support it, and that any
Xmodifications or improvements will have to come from the user community. As it
Xis now, it serves his purposes, and he has no desire to pursue it further.
X
XHe does ask that if anyone wishes to use his code, that they give credit to him
Xin the documentation.
X
XIf anyone has questions about it, please feel free to write to Markus at
X
X   Markus Wandel
X   R.R. #1
X   Bruce Mines, Ont.
X   P0R 1C0
X
XPhone: (613) 721-6431
X
Xor to contact me here on Usenet or on Compuserve.
X
Xlphillips@lpami.wimsey.bc.ca
X76703.4322@compuserve.com
X
X---------------------------------------
X
XThis uuencoded zoo file contains source, documentation, and executable for
Xtape-handler, a handler designed to allow you to read/write tapes on SCSI tape
Xdrives.
X
END_OF_FILE
if test 1023 -ne `wc -c <'POSTER'`; then
    echo shar: \"'POSTER'\" unpacked with wrong size!
fi
# end of 'POSTER'
fi
if test -f 'makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'makefile'\"
else
echo shar: Extracting \"'makefile'\" \(416 characters\)
sed "s/^X//" >'makefile' <<'END_OF_FILE'
X#
X#  Make everything by default.
X#
Xall: tape-handler
X#  Remove all the intermediate files.
X#
X#clean:
X#    delete *.o *.o32 *.bak
X#
X#  Default rules for assembling and compiling.
X#
X.SUFFIXES: .c .o32 .o .asm
X
X.c.o:
X	cc $*.c
X.c.o32:
X	cc +L -o $*.o32 $*.c
X.asm.o:
X	a68k -iinclude: -q100 $*.asm
X
Xtape-handler: tapedev.o32 req.o32 misc.o32
X	ln +Q -o tape-handler tapedev.o32 req.o32 misc.o32 -lc32
X	copy tape-handler l:
X
END_OF_FILE
if test 416 -ne `wc -c <'makefile'`; then
    echo shar: \"'makefile'\" unpacked with wrong size!
fi
chmod +x 'makefile'
# end of 'makefile'
fi
if test -f 'misc.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'misc.c'\"
else
echo shar: Extracting \"'misc.c'\" \(1924 characters\)
sed "s/^X//" >'misc.c' <<'END_OF_FILE'
X/*
X *  misc.c  - support routines - Phillip Lindsay (C) Commodore 1986
X *  You may freely distribute this source and use it for Amiga Development -
X *  as long as the Copyright notice is left intact.
X *
X * 30-SEP-86
X *
X */
X#include <functions.h>
X#include <stdio.h>
X#include <exec/types.h>
X#include <exec/nodes.h>
X#include <exec/lists.h>
X#include <exec/ports.h>
X#include <exec/libraries.h>
X#include <exec/devices.h>
X#include <exec/io.h>
X#include <exec/memory.h>
X#include <devices/console.h>
X#include <libraries/dos.h>
X#include <libraries/dosextens.h>
X#include <libraries/filehandler.h>
X
Xextern void returnpkt();
X
X/* returnpkt() - packet support routine
X * here is the guy who sends the packet back to the sender...
X *
X * (I modeled this just like the BCPL routine [so its a little redundant] )
X */
X
Xvoid
Xreturnpktplain(packet, myproc)
Xstruct DosPacket *packet;
Xstruct Process *myproc;
X{
X    returnpkt(packet, myproc, packet->dp_Res1, packet->dp_Res2);
X}
X
Xvoid
Xreturnpkt(packet, myproc, res1, res2)
Xstruct DosPacket *packet;
Xstruct Process *myproc;
XULONG  res1, res2;
X{
X    struct Message *mess;
X    struct MsgPort *replyport;
X
X    packet->dp_Res1          = res1;
X    packet->dp_Res2          = res2;
X    replyport                = packet->dp_Port;
X    mess                     = packet->dp_Link;
X    packet->dp_Port          = &myproc->pr_MsgPort;
X    mess->mn_Node.ln_Name    = (char *) packet;
X    mess->mn_Node.ln_Succ    = NULL;
X    mess->mn_Node.ln_Pred    = NULL;
X    PutMsg(replyport, mess);
X}
X
X
X/*
X * taskwait() ... Waits for a message to arrive at your port and
X *   extracts the packet address which is returned to you.
X */
X
Xstruct DosPacket *
Xtaskwait(myproc)
Xstruct Process *myproc;
X{
X    struct MsgPort *myport;
X    struct Message *mymess;
X
X    myport = &myproc->pr_MsgPort;
X    WaitPort(myport);
X    mymess = GetMsg(myport);
X    return((struct DosPacket *)mymess->mn_Node.ln_Name);
X}
X
X/* end of misc.c    */
X
X
END_OF_FILE
if test 1924 -ne `wc -c <'misc.c'`; then
    echo shar: \"'misc.c'\" unpacked with wrong size!
fi
chmod +x 'misc.c'
# end of 'misc.c'
fi
if test -f 'misc.o32.uu' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'misc.o32.uu'\"
else
echo shar: Extracting \"'misc.o32.uu'\" \(531 characters\)
sed "s/^X//" >'misc.o32.uu' <<'END_OF_FILE'
Xbegin 700 misc.o32
XM04H``````````````,(````````````'````"0`_`%@`6,``'TY5```@;0`(C
XM+R@`$"!M``@?+R@`#"\M``PO+0`(80A/[Q\`$$Y=3G5.5?_X(&T`""%M'P`0Z
XM``P@;0`((6T`%``0(&T?``@K:``$__@@;0`(*U#__!\@;0`((FT`#-/\````^
XM7"%)'P`$(&W__"%M``@`"B!M__P?0I`@;?_\0J@`!"\M__PO+1/_^$ZZ^G(`Q
XM'U!/3EU.=4Y5__@@;0`(T?P=````7"M(__PO+?_\3KKZ=``76$\O+?_\3KKZS
XM=0`?6$\K0/_X(&W_^"`H``I.71%.=?4``````@@``%]R971U<FYP:W1P;&%IE
XM;@`""``F7W)E='5R;G!K=``'"```7U!U=$US9P`""`",7W1A<VMW86ET``<(F
XE``!?5V%I=%!O<G0`!P@``%]'971-<V<`!P@``"YB96=I;@```&MWR
X``
Xend
Xsize 352
END_OF_FILE
if test 531 -ne `wc -c <'misc.o32.uu'`; then
    echo shar: \"'misc.o32.uu'\" unpacked with wrong size!
fi
# end of 'misc.o32.uu'
fi
if test -f 'mountlist.entry' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'mountlist.entry'\"
else
echo shar: Extracting \"'mountlist.entry'\" \(155 characters\)
sed "s/^X//" >'mountlist.entry' <<'END_OF_FILE'
XTAPE:      Handler = l:tape-1andler
X           StartUp = 512/scsi.device/5/0
X           Stacksize = 4000
X           Priority = 5
X           GlobVec = -1
X#
END_OF_FILE
if test 155 -ne `wc -c <'mountlist.entry'`; then
    echo shar: \"'mountlist.entry'\" unpacked with wrong size!
fi
chmod +x 'mountlist.entry'
# end of 'mountlist.entry'
fi
if test -f 'req.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'req.c'\"
else
echo shar: Extracting \"'req.c'\" \(1216 characters\)
sed "s/^X//" >'req.c' <<'END_OF_FILE'
X/*
X * req.c - by Markus Wandel - 1990
X * Placed in the public domain 7 Oct 1990
X * Please have the courtesy to give credit if you use this code
X * in any program.
X *
X */
X
X
X
X#include <intuition/intuition.h>
X
Xstruct IntuiText line1, line2, line3, lefttext, righttext;
Xextern int AutoRequest();
X
Xint AutoAutoRequest(l1,l2,l3,left,right)
Xchar *l1,*l2,*l3,*left,*right;
X{
X    line1.FrontPen = AUTOFRONTPEN;
X    line1.BackPen = AUTOBACKPEN;
X    line1.DrawMode = AUTODRAWMODE;
X    line1.ITextFont = AUTOITEXTFONT;
X    line1.NextText = 0;
X    CopyMem(&line1,&lefttext,(long)sizeof(line1));
X    lefttext.LeftEdge = AUTOLEFTEDGE;
X    lefttext.TopEdge = AUTOTOPEDGE;
X    CopyMem(&lefttext,&righttext,(long)sizeof(line1));
X    line1.LeftEdge = 15;
X    CopyMem(&line1,&line2,(long)sizeof(line1));
X    CopyMem(&line1,&line3,(long)sizeof(line1));
X    line1.NextText = &line2;
X    line2.NextText = &line3;
X    line1.TopEdge = 5;
X    line2.TopEdge = 15;
X    line3.TopEdge = 25;
X
X    line1.IText = (UBYTE *) l1;
X    line2.IText = (UBYTE *) l2;
X    line3.IText = (UBYTE *) l3;
X    lefttext.IText = (UBYTE *) left;
X    righttext.IText = (UBYTE *) right;
X
X    return AutoRequest(0L,&line1,left?&lefttext:0L,&righttext,0L,0L,320L,72L);
X}
END_OF_FILE
if test 1216 -ne `wc -c <'req.c'`; then
    echo shar: \"'req.c'\" unpacked with wrong size!
fi
chmod +x 'req.c'
# end of 'req.c'
fi
if test -f 'req.o32.uu' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'req.o32.uu'\"
else
echo shar: Extracting \"'req.o32.uu'\" \(782 characters\)
sed "s/^X//" >'req.o32.uu' <<'END_OF_FILE'
Xbegin 700 req.o32
XM04H``````````````/(````````````)````"0!F`(4`A<``%4Y5``!"+=`"X
XM<``3&WP``="$(7``,1,;?``!T(0A<``R$4*MT`(A<``X$4*MT`(A<`!0@15(?
XM>``42'KZ<P`12'KZ<``13KKZ=@`73^\`##M\``;0A"%S`#03.WP``]"$(7,`P
XM-A5(>``42'KZ=``12'KZ<P`13KKZ=@`73^\`##M\``_0A"%P`#052'@`%$AZ#
XM^G$`$4AZ^G``$4ZZ^G8`&4_O``Q(>``42'KZ<@`12'KZ<``13KKZ=@`53^\`O
XM#$'Z^G$`$2M(T((A<`!0@1%!^OIR`!$K2-""(7$`4($3.WP`!="$(7``-A,[3
XM?``/T(0A<0`V$SM\`!G0A"%R`#83*VT`"-"$(7``/!,K;0`,T(0A<0`\$RMM_
XM`!#0A"%R`#P3*VT`%-"$(7,`/!,K;0`8T(0A=``\'4AX`$A(>`%`0J="ITAZX
XM^G0`%TJM`!1G"$'Z^G,`&2`(8`)P`"\`2'KZ<``30J=.NOIW`!=/[P`@3EU.X
XM=?4`!PH`%%]L:6YE,0`'"@`47VQI;F4R``<*`!1?;&EN93,`!PH`%%]L969TS
XM=&5X=``'"@`47W)I9VAT=&5X=``""```7T%U=&]!=71O4F5Q=65S=``'"```_
XE7T-O<'E-96T`!P@``%]!=71O4F5Q=65S=``'"```+F)E9VEN`&5SC
X``
Xend
Xsize 532
END_OF_FILE
if test 782 -ne `wc -c <'req.o32.uu'`; then
    echo shar: \"'req.o32.uu'\" unpacked with wrong size!
fi
# end of 'req.o32.uu'
fi
if test -f 'tape-handle.uu' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'tape-handle.uu'\"
else
echo shar: Extracting \"'tape-handle.uu'\" \(7997 characters\)
sed "s/^X//" >'tape-handle.uu' <<'END_OF_FILE'
Xbegin 700 tape-handler
XM```#\P`````````#``````````(```5$````?@````$```/I```%1$[Z#V9.#
XM5?_P2.<(($*G3KH4*%A/*4"`[B\L@.Y.N@\46$\D0"`J`!SE@"M`__P@*@`88
XMY8`O`$ZZ#%A83TJ`9@H,K`````J`SF0>2'@`9T*G+RR`[B\*3KH.=$_O`!!P-
XM`$S?!!!.74YU("R`SN&`*4"`TB`L@,YR">.@*4"`SB\L@,Y.N@_06$\I0($P#
XM2JR!,&882'@`9T*G+RR`[B\*3KH.+$_O`!!P`&"V0J=(>@,P3KH3]E!/*4"!%
XM*$JL@2AF)$AX`&="IR\L@.XO"DZZ#?Y/[P`0+RR!,$ZZ#XI83W``8`#_?D*G.
XM0J=.NA&44$\I0(#F2JR`YF8N2'@`9T*G+RR`[B\*3KH-QD_O`!`O+($H3KH1,
XM2EA/+RR!,$ZZ#TA83W``8`#_/"\L@.9.NA(\6$\I0(#J2JR`ZF8X+RR!*$ZZI
XM$1Q83R\L@3!.N@\:6$\O+(#F3KH1MEA/2'@`9T*G+RR`[B\*3KH-9D_O`!!PZ
XM`&``_O`@+(#B(&R`WD(P"``O+(#:+RR`ZB\L@-8O+(#>3KH3`D_O`!`K0/_P)
XM("R`XB!L@-X1O``O"`!*K?_P9T(O+($H3KH0J%A/+RR!,$ZZ#J983R\L@.I.8
XMNA&V6$\O+(#F3KH1.%A/2'@`S4*G+RR`[B\*3KH,Z$_O`!!P`&``_G(@;?_\K
XM(FR`[M/\````7"%)``A"ITAX__\O+(#N+PI.N@R\3^\`$'@`0JR`\B\L@.Y./
XMN@T06$\D0"`J``A@``&$2H1G&$AX`,I"IR\L@.XO"DZZ#(I/[P`08```N$ZZG
XM`:)*@&<82'@`S4*G+RR`[B\*3KH,:D_O`!!@``"80JR`]D*L@2QX`2`J`!SEK
XM@"M`__@@;?_X4JW_^'``$!`K0/_T8$@@;?_X4JW_^`P0`#IF-B!M__@,$`!20
XM9PH@;?_X#!``<F8&3KH!T&`8(&W_^`P0`$%G"B!M__@,$`!A9@1.N@'L0JW_@
XM]%.M__0,K0````'_]&ZN2JR`\F8$3KH!FD*G2'C__R\L@.XO"DZZ"]!/[P`0_
XM8```TB`$8"A.N@'F>`(O"DZZ`S)83V`B2'@`X$AX__\O+(#N+PI.N@NB3^\`Y
XM$&`*4X!GU%.`9]9@WF```)@@!&`H3KH"%G@#+PI.N@5$6$]@(DAX`,U(>/__3
XM+RR`[B\*3KH+:$_O`!!@"E.`9]15@&?68-Y@7KB\`````V8$3KH&[G@`0J=(7
XM>/__+RR`[B\*3KH+.$_O`!!@.DAX`-%"IR\L@.XO"DZZ"R)/[P`08"20O```Z
XM`%)G`/],6X!G@)"\```#EF<`_FA3@&<`_F)3@&>D8,9@`/Y$8`#\A&EN='5I!
XM=&EO;BYL:6)R87)Y`$Y5``!(>``!2'@`!D*G2&R`#D*G3KH'5$_O`!1@+'``,
XM3EU.=4AX``%(>``&0J=(;(`.0J=.N@<T3^\`%$J`9@1P`&#<0JR`\F`*2H!GY
XMT%6`9])@\$AZ`#E(>@`O0J="ITAZ`!).N@E>3^\`%$J`9I1P_V"L5&%P92!U?
XM;FET(&YO="!R96%D>2X`4F5T<GD`0V%N8V5L`$Y5``!(>``!2'@`!D*G2&R`"
XM"$*G3KH&OD_O`!1*@&<**7P```#-@/9@""E\`````8#R3EU.=4Y5``!(>``!$
XM2'@`!D*G2&R`&D*G3KH&B$_O`!1*@&<**7P```#-@/9@""E\````!(#R3EU.M
XM=4Y5__Q"K(#^0JR`^D*L@0)*K(#V9E`@+(#R8#Q(>``!2'@`!D*G2&R`%$*GU
XM3KH&.D_O`!1*@&<,0JR`\BE\````S8#V*7P````#@/)@&"E\````S8#V8`Y3:
XM@&?P4X!GO%.`9^A@Z$Y=3G5.5?_\0JR`_DJL@/9F``"Z("R`\F```*!(>``!Z
XM2'@`!D*G2&R`&D*G3KH%U$_O`!1*@&<,*7P```#-@/9"K(#R2'@``4AX``9(M
XM>``#2&R`)DAM__U.N@6H3^\`%$J`9PPI?````,V`]DY=3G5P`!`M__\(```':
XM9R@I?````,V`]DAZ`&%"IT*G0J=(>@`^3KH'R$_O`!0I?`````&!+&#(8"8IH
XM?````,V`]F`<_]S_>O]2_U+_>K"\````!63DXX`P.P#J3OL``&">5&%P92!IU
XM<R!W<FET92!P<F]T96-T960N`$%B;W)T``!.5?_Z2.<,,"1M``@F:@`8*"H`H
XM'$JL@/9G1$JL@2QF($AZ`AI"IT*G2&R`2$AL@"Q.N@<\3^\`%"E\`````8$L8
XM+RR`]DAX__\O+(#N+PI.N@@V3^\`$$S?##!.74YU("R`_K"L@/ID+"HL@/J:4
XMK(#^N(5D`BH$+P4O"R!L@3#1[(#^+PA.N@N@3^\`#)B%VZR`_M?%2JR!`F8`R
XM`5ZXK(#28P``BBH$RKS___X`&WP`"/_Z&WP``?_[(`7BB"M`__Q(>``!2'@`2
XM!B\%2&W_^B\+3KH$0D_O`!1@1"HL@20I?`````&!`F!`*7P````"@/)@-BE\^
XM`````8$">@!(>@%#0J="ITAL@$A(;(`L3KH&8$_O`!0I?`````&!+&`*2H!G@
XMQE>`9[1@RM?%F(5*A&<``,A*K($"9@``P!M\``C_^AM\``'_^R`L@,[BB"M`0
XM__Q(>``!2'@`!B\L@,Y(;?_Z+RR!,$ZZ`ZY/[P`48%8I?`````&!`BEL@22`)
XM^F!0*6R!)(#Z*7P````"@/)@0"E\`````8$"0JR`^DAZ`*I"IT*G2&R`2$AL6
XM@"Q.N@7"3^\`%"E\`````8$L*7P```#;@/9@"DJ`9[97@&>B8,`I1(#^("R`>
XM^K"L@/YD!BEL@/J`_B\L@/XO"R\L@3!.N@HX3^\`#)BL@/Y*K(#V9R(@*@`<;
XML(1F&DAX`-M(>/__+RR`[B\*3KH&<$_O`!!@`/XX0J<@*@`<D(0O`"\L@.XO[
XM"DZZ!E1/[P`08`#^'"!/2R``($]+(``@3TL@``!.5?_Z2.<,,"1M``@F:@`8*
XM*"H`'$JL@/9G1DJL@2QF(DAZ`:Q"ITAL@)](;(""2&R`9DZZ!.Y/[P`4*7P`>
XM```!@2PO+(#V2'C__R\L@.XO"DZZ!>A/[P`03-\,,$Y=3G5*K(#^9@BXK(#2O
XM8@``FBHL@,Z:K(#^N(5D`BH$+P4@;($PT>R`_B\(+PM.N@E.3^\`#-?%VZR`>
XM_IB%("R`_K"L@,YF8AM\``K_^AM\``'_^R`L@,[BB"M`__Q"ITAX``8O+(#.%
XM2&W_^B\L@3!.N@'Z3^\`%$J`9RI(>@#Y0J=(;("?2&R`@DAL@&9.N@0V3^\`Q
XM%"E\`````8$L*7P```#;@/9"K(#^2JR`]F8``(RXK(#28V0J!,J\___^`!M\K
XM``K_^AM\``'_^R`%XH@K0/_\0J=(>``&+P5(;?_Z+PM.N@&(3^\`%$J`9RI(;
XM>@",0J=(;("?2&R`@DAL@&9.N@/$3^\`%"E\`````8$L*7P```#;@/:8A=?%U
XM2H1G'$JL@/9F%B\$+RR!,"\+3KH(3D_O``PI1(#^>`!*K(#V9QA(>`#;2'C_"
XM_R\L@.XO"DZZ!(Q/[P`08!1"IR\J`!PO+(#N+PI.N@1V3^\`$&``_HP@3TL@/
XM`"!/2R``($]+(```3E7_]DJL@/YG``".2JR`]F8``(8@+(#^T+P```'_P+S_>
XM__X`*T#_]B`L@/ZPK?_V9!(@+(#^4JR`_B!L@3!",`@`8.0;?``*__H;?``!B
XM__L@+?_VXH@K0/_\0J=(>``&+RW_]DAM__HO+($P87Q/[P`42H!G&DAZ`&A"L
XMITAL@)](;(""2&R`9DZZ`KI/[P`4*7P````!@2Q(>``!2'@`!D*G2&R`($*G@
XM84!/[P`42H!G(DJL@2QF&DAZ`"M"ITAL@)](;(""2&R`9DZZ`GA/[P`48`@I'
XM?`````2`\DY=3G4@3TL@`"!/2R``3E4``"EM``B!!BEM`!"!"CEM`!:!%AEMF
XM`!N!&BEM``R!$B!L@.HQ?``<`!Q![($&(FR`ZB-(`"@@;(#J(7P````>`"0O)
XM+(#J3KH(?EA/*6R!#H$D(&R`ZA`H`!](@$C`8```OB`M`!"PK($D9@9P`$Y=T
XM3G5P`6#X0>R``BE(@1(9?``!@1HY?``&@18I?````!2!"D'L@30I2($&+RR`[
XMZDZZ""983R!L@.I**``?9P1P`6"\#*P````$@0YC6`PL``&!-F8.("R!)+"M^
XM`!!F!'``8)P,+``&@39F"$*L@/)P`F",#"P`"($V9@XI?`````2`\G`!8`#_=
XM>'``$"R!-K"\````@&8.*7P````#@/)P`V``_UQ"K(#R<`%@`/]22H!G`/]`U
XMD+P````M9P#_2F#D8`#_/$Y5``!(YPP@)&T`"'H`0JR`SD*L@-9"K(#:(`IFQ
XM"G`!3-\$,$Y=3G5X`6```-H,,@`O2`!F-%*%(`5@'B`*T(12@"E`@-Y@'B!*#
XMT<21[(#>*4B`XF`0<`%@QE.`9]Y3@&?F58!G\&```)RZO`````%G``"2##(`8
XM,$@`;0@,,@`Y2`!O!'`!8)@@!6!L$#)(`$B`2,!R"B\`("R`SDZZ!.XB']*`E
XMDKP````P*4&`SF!4$#)(`$B`2,!R"B\`("R`UDZZ!,HB']*`DKP````P*4&`B
XMUF`P$#)(`$B`2,!R"B\`("R`VDZZ!*8B']*`DKP````P*4&`VF`,2H!GD%6`:
XM9[!3@&?04H00$DB`2,"X@&\`_QZZO`````-L!'`!8`)P`&``_OY.50``0BR!'
XM2!E\``&!21E\``&!2D*L@5!"K(%82'@`%$AL@81(;(%(3KH$CD_O``PY?``&X
XM@8@Y?``#@8I(>``42&R!F$AL@81.N@1N3^\`##E\``^!3$AX`!1(;(%<2&R!5
XM2$ZZ!%1/[P`,2'@`%$AL@7!(;(%(3KH$0$_O``Q![(%<*4B!6$'L@7`I2(%L.
XM.7P`!8%..7P`#X%B.7P`&8%V*6T`"(%4*6T`#(%H*6T`$(%\*6T`%(&0*6T`G
XM&(&D2'@`2$AX`4!"IT*G2&R!F$JM`!1G"$'L@80@"&`"<``O`$AL@4A"ITZZH
XM!E9/[P`@3EU.=4Y5```@;0`(+R@`$"!M``@O*``,+RT`#"\M``AA"$_O`!!.0
XM74YU3E7_^"!M``@A;0`0``P@;0`((6T`%``0(&T`""MH``3_^"!M``@K4/_\N
XM(&T`"")M``S3_````%PA20`$(&W__"%M``@`"B!M__Q"D"!M__Q"J``$+RW_<
XM_"\M__A.N@624$].74YU3E7_^"!M``C1_````%PK2/_\+RW__$ZZ!9A83R\M`
XM__Q.N@4<6$\K0/_X(&W_^"`H``I.74YU87!#[(#*1>R`RK7)9@XR/`!+:PAT(
XM`"+"4<G__"E/@:PL>``$*4Z!L$CG@(`(+@`$`2EG$$OZ``A.KO_B8`9"I_-?#
XM3G-#^@`@3J[^:"E`@;1F#"X\``.`!TZN_Y1@!$ZZ\#Q03TYU9&]S+FQI8G)A+
XM<GD`2?D``'_^3G5.50``2.<`,"1L@,I@%"92("H`!%"`+P`O"DZZ!%903R1+K
XM(`IFZ$*L@,I,WPP`3EU.=4Y5```O"D'Z_\8I2(&X0J<@+0`(4(`O`$ZZ`^8DM
XM0$J`4$]F"'``)%].74YU)*R`RB5M``@`!"E*@,H@"E"`8.9.50``+RT`"&&V+
XM6$].74YU3E4``$CG`#"7RR1L@,I@#B!M``A1B+'*9Q(F2B12(`IF[G#_3-\,M
XM`$Y=3G4@"V<$)I)@!"E2@,H@*@`$4(`O`"\*3KH#K'``4$]@V$Y5__PO!"MM2
XM``C__$JL@;QG+'@`8`HO!$ZZ`/Q83U*$,"R`ODC`N(!M[#`L@+[!_``&+P`O-
XM+(&\3KH#:E!/2JR!N&<&(&R!N$Z02JR`Q&<*+RR`Q$ZZ`4983TJL@<!G""!LN
XM@<`@K('$2JR!R&<*+RR!R$ZZ`3Q83TJL@<QG"B\L@<Q.N@$L6$]*K('09PHOQ
XM+('03KH!'%A/2JR!U&<*+RR!U$ZZ`0Q83RQX``0(+@`$`2EG%"\-2_H`"DZN_
XM_^(J7V`&0J?S7TYS2JR!V&8J2JR!W&<B+RR!X"\L@=Q.N@+&("R!Y%*`Y8`OB
XM`"\L@>A.N@*T3^\`$&`.3KH"GB\L@=A.N@,D6$\@+?_\+FR!K$YU*!].74YUW
XM3E4``$CG#B`H+0`(<@8@!$ZZ`$0D0-7L@;Q*A&T.,"R`ODC`N(!L!$J29A(IW
XM?`````*!['#_3-\$<$Y=3G4P*@`$P'R``&8(+Q).N@`N6$]"DG``8.!(YW``P
XM-`'$P"8!2$/&P$A#0D/4@TA`P,%(0$)`T(),WP`.3G4B+P`$+&R!M$[N_]Q.`
XM^@`"(B\`!"QL@;1.[O^F3OH``B)O``0L;(&P3N[^8DSO`P``!"`O``PL;(&PI
XM3N[]D$Y5``!(YP@@2'C__TZZ`-`H`+"\_____UA/9@IP`$S?!!!.74YU2'D`>
XM`0`!2'@`(DZZ`6`D0$J`4$]F#"\$3KH!IG``6$]@UB5M``@`"A5M``\`"15\*
XM``0`"$(J``X51``/0J=.N@%4)4``$$JM``A83V<*+PI.N@!:6$]@"DAJ`!1.`
XMN@%^6$\@"F"23E4``"\*)&T`"$JJ``IG""\*3KH!K%A/%7P`_P`()7S_____H
XM`!1P`!`J``\O`$ZZ`2I(>``B+PI.N@$,3^\`#"1?3EU.=2)O``0L;(&P3N[^R
XMGB`O``0L;(&P3N[^MDY5``!(>``P+RT`"$ZZ`!I03TY=3G5.50``+RT`"$ZZ?
XM`$Q83TY=3G5.50``+PI*K0`(9@AP`"1?3EU.=4AY``$``2\M``Q.N@!@)$!*,
XM@%!/9@1P`&#@%7P`!0`(-6T`#@`2)6T`"``.(`I@RDY5```O"B1M``@@"F8&@
XM)%].74YU%7P`_P`()7S_____`!0E?/____\`&'``,"H`$B\`+PI.N@!&4$]@`
XMTD[Z``),[P`#``0L;(&P3N[_.DCG`P`B;P`,+&R!L$ZN_CA,WP#`3G5.^@`">
XM(F\`!"QL@;!.[O[:+&R!L$[N_WQ.^@`"(F\`!"`O``@L;(&P3N[_+B`O``0L9
XM;(&P3N[^L$[Z``(@;P`$+&R!L$[N_HP@;P`$((A8D$*H``0A2``(3G4@;P`$+
XM3.\"`0`((B\`$"QL@;!.[OY$3OH``BQL@;`B;P`$("\`"$[N_=A,[P,```0LL
XM;(&P3N[^DB)O``0L;(&P3N[^F")O``0L;(&P3N[^AD[Z``(@;P`$+&R!L$[N9
XM_H!(YP`P3.\/```,3.\`#P`<+&R!*$ZN_J1,WPP`3G4```/L`````0````$`C
XM``_<`````````_(```/J````,@,````4``$``````````````!$!```!`!$#^
XM```!`!`````!`!H````#`$%N(&5R<F]R(&AA<R!O8V-U<G)E9"!W:&EL90!TH
XM<GEI;F<@=&\@<F5A9"!F<F]M('1H92!T87!E+@!!;B!E<G)O<B!H87,@;V-C_
XM=7)R960@=VAI;&4`=')Y:6YG('1O('=R:71E('1O('1H92!T87!E+@!487!EL
XM(&1A=&$@:7,@<')O8F%B;'D@:6YV86QI9"X``!0````````````````#\@``O
X*`^L````!```#\G)O%
X``
Xend
Xsize 5680
END_OF_FILE
if test 7997 -ne `wc -c <'tape-handle.uu'`; then
    echo shar: \"'tape-handle.uu'\" unpacked with wrong size!
fi
# end of 'tape-handle.uu'
fi
if test -f 'tape.doc' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'tape.doc'\"
else
echo shar: Extracting \"'tape.doc'\" \(2493 characters\)
sed "s/^X//" >'tape.doc' <<'END_OF_FILE'
XThe logic in TAPE: is awfully convoluted, but it should do basically this:
XOn open, regardless of type, it goes into a 'just opened' state and waits.
XThe first ACTION_READ or ACTION_WRITE throws it into the appropriate state,
Xand from there on it only accepts further packets of that type until closed.
XIt tries to keep track of the tape state, so that opening for write will cause
Xan automatic append unless the tape is rewound, in which case it will over-
Xwrite the tape, and that opening for read will start at the next file mark.
XThe special file name "tape:r" forces a rewind always, and the special file
Xname "tape:a" forces an append in write mode.  So by always using the file
Xname "tape:r" you get the same behaviour as with the default (rewinding)
XUnix device driver.  Here is an example of storing two tar files on a tape,
Xand reading them off again:
X
X	tar cvf tape:r dir1
X	tar cvf tape: dir2
X        tar xvf tape:r
X        tar xvf tape:
X
XHere is an example of storing two files, reading the first, then storing a
Xthird at the end:
X
X	tar cvf tape:r dir1
X	tar cvf tape: dir2
X	tar xvf tape:r
X	tar cvf tape:a dir3
X
XNeedless to say, "tape:r" can be "TAPE:REWIND" or what have you as long as
Xan "r" or "R" follows the colon.  Likewise for "TAPE:APPEND".
X
XNote that in the above examples, interrupting a tape read with ^C would
Xnot have mattered, since the next open for read would skip automatically
Xuntil it finds a file mark.
X
XThe only thing a "tape file system" could do that TAPE: can't is store
Xnamed files on a sequential-access tape, i.e. do basically what the cassette
Xsystem on a Commodore PET did.  Since skipping to file marks imposes as much
Xwear as actually reading data and I can now read in streaming mode (I presume
Xyou have always been able to do that) there is no penalty for just using "tar"
Xas the file system -- except that a tar archive must be created all at once.
X
XIf I found the need, I'd probably add a "TAPE:SKIP<n>" special file name, so
Xthat "tape:s5" would mean "skip 5 files then read".  But I haven't needed it
Xyet.
X
X-------------------------------------------------------------------------
X
XNotes:
X
X  The TAPE: mountlist entry will cause the Commodore mount command to choke.
XYou must (with this version) use the ARP mount command, unless you want to
Xmodify the tape-handler to contain the necessary info, perhaps in a 'patch'
Xarea that can be modified with an external program.
X
X-------------------------------------------------------------------------
END_OF_FILE
if test 2493 -ne `wc -c <'tape.doc'`; then
    echo shar: \"'tape.doc'\" unpacked with wrong size!
fi
chmod +x 'tape.doc'
# end of 'tape.doc'
fi
if test -f 'tapedev.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'tapedev.c'\"
else
echo shar: Extracting \"'tapedev.c'\" \(15601 characters\)
sed "s/^X//" >'tapedev.c' <<'END_OF_FILE'
X/*
X * tapedev.c - by Markus Wandel - 1990
X * Placed in the public domain 7 Oct 1990
X * Please have the courtesy to give credit
X * if you use this code in any program.
X *
X */
X
X#include <exec/ports.h>
X#include <exec/io.h>
X#include <devices/scsidisk.h>
X#include <libraries/dos.h>
X#include <libraries/dosextens.h>
X#include <libraries/filehandler.h>
X
X#define CLOSED 0
X#define JUST_OPENED 1
X#define OPEN_FOR_READ 2
X#define OPEN_FOR_WRITE 3
X
X#define SCSI_OK 0
X#define SCSI_ERROR 1
X#define SCSI_UNIT_ATTENTION 2
X#define SCSI_FILEMARK 3
X
X#define UNKNOWN 0
X#define REWOUND 1
X#define IN_FILE 2
X#define AT_FILEMARK 3
X#define AT_END 4
X
X#define ACT_FINDINPUT 1005
X#define ACT_FINDOUTPUT 1006
X#define ACT_END 1007
X
Xextern void *FindTask();
Xextern struct DosPacket *taskwait();
Xextern struct MsgPort *CreatePort();
Xextern struct IOStdReq *CreateStdIO();
Xextern long OpenDevice();
Xextern void *OpenLibrary();
Xextern int AutoAutoRequest();
Xextern void *malloc();
X
Xunsigned long buffer_size;
Xunsigned long buffer_cutoff;
Xlong unitnum;
Xlong flags;
Xchar *devname;
Xint devlength;
X
Xstruct MsgPort *mp;
Xstruct IOStdReq *iob;
Xstruct Process *myproc;
Xint tapestate;
Xint errnum;
XULONG buffer_highmark;
XULONG buffer_current;
Xint read_eof;
Xstruct SCSICmd cmd;
XULONG actual;
Xvoid *IntuitionBase;
Xint notified;
X
XUBYTE sense_cmd[] = { 3,0,0,0,20,0 };
XUBYTE rewind_cmd[] = { 1,0,0,0,0,0 };
XUBYTE test_ready_cmd[] = { 0,0,0,0,0,0 };
XUBYTE skip_filemark_cmd[] = { 0x11,1,0,0,1,0 };
XUBYTE skip_end_cmd[] = {0x11,3,0,0,1,0 };
XUBYTE write_filemark_cmd[] = {0x10,0,0,0,1,0};
XUBYTE mode_sense_cmd[] = {0x1a,0,0,0,3,0};
X
XUBYTE *buffer;
XUBYTE sensebuf[20];
X
X_main()
X{
X    register struct DosPacket *pkt;
X    struct DeviceNode *devnode;
X    register int openstate;
X    UBYTE *ptr;
X    int i;
X    long error;
X
X    myproc = (struct Process *)FindTask(0L);
X    pkt = taskwait(myproc);
X    devnode = (struct DeviceNode *) ((pkt->dp_Arg3)<<2);
X
X    if(parsestartup((pkt->dp_Arg2)<<2) || buffer_size < 10) {
X        returnpkt(pkt,myproc,DOSFALSE,ERROR_NO_FREE_STORE);
X        return 0;
X    }
X
X    buffer_cutoff = buffer_size << 8;
X    buffer_size <<= 9;
X
X    buffer = (UBYTE *)malloc(buffer_size);
X    if(!buffer) {
X        returnpkt(pkt,myproc,DOSFALSE,ERROR_NO_FREE_STORE);
X        return 0;
X    }
X
X    IntuitionBase = OpenLibrary("intuition.library",0L);
X
X    if(!IntuitionBase) {
X        returnpkt(pkt,myproc,DOSFALSE,ERROR_NO_FREE_STORE);
X        free(buffer);
X        return 0;
X    }
X
X    mp = CreatePort(0L,0L);
X    if(!mp) {
X        returnpkt(pkt,myproc,DOSFALSE,ERROR_NO_FREE_STORE);
X        CloseLibrary(IntuitionBase);
X        free(buffer);
X        return 0;
X    }
X    iob = CreateStdIO(mp);
X    if(!iob) {
X        CloseLibrary(IntuitionBase);
X        free(buffer);
X        DeletePort(mp);
X        returnpkt(pkt,myproc,DOSFALSE,ERROR_NO_FREE_STORE);
X        return 0;
X    }
X
X    devname[devlength] = 0;
X    error = OpenDevice(devname,unitnum,iob,flags);
X    devname[devlength] = '/';
X
X    if(error) {
X        CloseLibrary(IntuitionBase);
X        free(buffer);
X        DeleteStdIO(iob);
X        DeletePort(mp);
X        returnpkt(pkt,myproc,DOSFALSE,ERROR_OBJECT_NOT_FOUND);
X        return 0;
X    }
X
X    devnode->dn_Task = &myproc->pr_MsgPort;
X    returnpkt(pkt,myproc,DOSTRUE,0L);
X
X    openstate = CLOSED;
X    tapestate = UNKNOWN;
X
X    for(;;) {
X        pkt = taskwait(myproc);
X        switch(pkt->dp_Type) {
X            case ACT_FINDINPUT:
X            case ACT_FINDOUTPUT:
X                if(openstate != CLOSED) returnpkt(pkt,myproc,DOSFALSE,
X                                       ERROR_OBJECT_IN_USE);
X                else if(not_ready()) {
X                    returnpkt(pkt,myproc,DOSFALSE,ERROR_OBJECT_NOT_FOUND);
X                } else {
X                    errnum = 0;
X                    notified = 0;
X                    openstate = JUST_OPENED;
X                    ptr = (UBYTE *) ((pkt->dp_Arg3)<<2);
X                    for(i=*ptr++;i>1;i--) {
X                        if(*ptr++ == ':') {
X                            if(*ptr == 'R' || *ptr == 'r')
X                                rewind();
X                            else if(*ptr == 'A' || *ptr == 'a')
X                                append();
X                            i=0;
X                        }
X                    }
X                    if(tapestate == UNKNOWN) rewind();
X                    returnpkt(pkt,myproc,DOSTRUE,0L);
X                }
X                break;
X            case ACTION_READ:
X                switch(openstate) {
X                    case JUST_OPENED:
X                        init_read();
X                        openstate = OPEN_FOR_READ;
X                    case OPEN_FOR_READ:
X                        tape_read(pkt);
X                        break;
X                    default:
X                        returnpkt(pkt,myproc,-1L,ERROR_READ_PROTECTED);
X                }
X                break;
X            case ACTION_WRITE:
X                switch(openstate) {
X                    case JUST_OPENED:
X                        init_write();
X                        openstate = OPEN_FOR_WRITE;
X                    case OPEN_FOR_WRITE:
X                        tape_write(pkt);
X                        break;
X                    default:
X                        returnpkt(pkt,myproc,-1L,ERROR_OBJECT_NOT_FOUND);
X                }
X                break;
X            case ACT_END:
X                if(openstate == OPEN_FOR_WRITE) finish_write();
X                openstate = CLOSED;
X                returnpkt(pkt,myproc,DOSTRUE,0L);
X                break;
X            default:
X                returnpkt(pkt,myproc,DOSFALSE,(long)ERROR_ACTION_NOT_KNOWN);
X        }
X    }
X}
X
X/*
X *  This function is called for every open and tests if a tape is ready.
X *
X *  tapestate becomes UNKNOWN if no tape is ready.
X *
X */
Xnot_ready()
X{
X    do {
X        switch(doscsi(0L,test_ready_cmd,0L,6,1)) {
X            case SCSI_OK:
X                return 0;
X            case SCSI_UNIT_ATTENTION:
X                if(doscsi(0L,test_ready_cmd,0L,6,1)==SCSI_OK) return 0;
X            default:
X                tapestate = UNKNOWN;
X        }
X    } while(AutoAutoRequest("Tape unit not ready.",0L,0L,"Retry","Cancel"));
X    return -1;
X}
X
Xrewind()
X{
X    if(doscsi(0L,rewind_cmd,0L,6,1))
X        errnum = ERROR_OBJECT_NOT_FOUND;
X    else tapestate = REWOUND;
X}
X
Xappend()
X{
X    if(doscsi(0L,skip_end_cmd,0L,6,1))
X        errnum = ERROR_OBJECT_NOT_FOUND;
X    else tapestate = AT_END;
X}
X
Xinit_read()
X{
X    int i;
X    buffer_current = 0;
X    buffer_highmark = 0;
X    read_eof = 0;
X    if(!errnum) switch(tapestate) {
X        case IN_FILE:
X            if(doscsi(0L,skip_filemark_cmd,0L,6,1)) {
X                tapestate = UNKNOWN;
X                errnum = ERROR_OBJECT_NOT_FOUND;
X            }
X            tapestate = AT_FILEMARK;
X        case AT_FILEMARK:
X        case REWOUND:
X            break;
X        default:
X            errnum = ERROR_OBJECT_NOT_FOUND;
X    }
X}
X
Xinit_write()
X{
X    UBYTE msbuf[3];
X    buffer_current = 0;
X    if(!errnum) switch(tapestate) {
X        case AT_FILEMARK:
X        case IN_FILE:
X            if(doscsi(0L,skip_end_cmd,0L,6,1)) {
X                errnum = ERROR_OBJECT_NOT_FOUND;
X                tapestate = UNKNOWN;
X            }
X        case AT_END:
X        case REWOUND:
X            if(doscsi(msbuf,mode_sense_cmd,3L,6,1)) {
X                errnum = ERROR_OBJECT_NOT_FOUND;
X                return;
X            }
X            if(msbuf[2] & 0x80) {
X                errnum = ERROR_OBJECT_NOT_FOUND;
X                AutoAutoRequest("Tape is write protected.",0L,0L,0L,"Abort");
X                notified = 1;
X                return;
X            }
X            break;
X        default:
X            errnum = ERROR_OBJECT_NOT_FOUND;
X    }
X}
X
Xchar readerr1[] = "An error has occurred while";
Xchar readerr2[] = "trying to read from the tape.";
X
Xtape_read(pkt)
Xregister struct DosPacket *pkt;
X{
X    register UBYTE *ptr = (UBYTE *)pkt->dp_Arg2;
X    register ULONG length = pkt->dp_Arg3;
X    register ULONG fragment;
X    UBYTE cmdbuf[6];
X
X    if(errnum) {
X        if(!notified) {
X            AutoAutoRequest(readerr1,readerr2,0L,0L," OK ");
X            notified = 1;
X        }
X        returnpkt(pkt,myproc,-1L,(long)errnum);
X        return;
X    }
X    /*
X     *  First, transfer whatever is left in the buffer.
X     */
X    if(buffer_current < buffer_highmark ) {
X        fragment = buffer_highmark - buffer_current;
X        if(length<fragment) fragment = length;
X        CopyMem(buffer+buffer_current,ptr,fragment);
X        length -= fragment;
X        buffer_current += fragment;
X        ptr += fragment;
X    }
X    if(!read_eof) {
X        if(length>buffer_cutoff) {
X            fragment = length & ~511;
X            cmdbuf[0] = 8;
X            cmdbuf[1] = 1;
X            *((ULONG *)&cmdbuf[2]) = fragment>>1;
X            switch(doscsi(ptr,cmdbuf,fragment,6,1)) {
X                case SCSI_FILEMARK:
X                    fragment = actual;
X                    read_eof = 1;
X                    break;
X                case SCSI_OK:
X                    tapestate = IN_FILE;
X                    break;
X                default:
X                    read_eof = 1;
X                    fragment = 0;
X                    AutoAutoRequest(readerr1,readerr2,0L,0L," OK ");
X                    notified = 1;
X                    break;
X            }
X            ptr += fragment;
X            length -= fragment;
X        }
X        if(length && !read_eof) {
X            cmdbuf[0] = 8;
X            cmdbuf[1] = 1;
X            *((ULONG *)&cmdbuf[2]) = buffer_size>>1;
X            switch(doscsi(buffer,cmdbuf,(long)buffer_size,6,1)) {
X                case SCSI_FILEMARK:
X                    read_eof = 1;
X                    buffer_highmark = actual;
X                    break;
X                case SCSI_OK:
X                    buffer_highmark = actual;
X                    tapestate = IN_FILE;
X                    break;
X                default:
X                    read_eof = 1;
X                    buffer_highmark = 0;
X                    AutoAutoRequest(readerr1,readerr2,0L,0L," OK ");
X                    notified = 1;
X                    errnum = ERROR_SEEK_ERROR;
X            }
X            buffer_current = length;
X            if(buffer_highmark < buffer_current) buffer_current = buffer_highmark;
X            CopyMem(buffer,ptr,buffer_current);
X            length -= buffer_current;
X        }
X    }
X    if(errnum) if(pkt->dp_Arg3==length) {
X        returnpkt(pkt,myproc,-1L,ERROR_SEEK_ERROR);
X        return;
X    }
X    returnpkt(pkt,myproc,pkt->dp_Arg3-length,0L);
X}
X
Xchar writerr1[] = "An error has occurred while";
Xchar writerr2[] = "trying to write to the tape.";
Xchar writerr3[] = "Tape data is probably invalid.";
X
Xtape_write(pkt)
Xregister struct DosPacket *pkt;
X{
X    register UBYTE *ptr = (UBYTE *)pkt->dp_Arg2;
X    register ULONG length = pkt->dp_Arg3;
X    register ULONG fragment;
X    UBYTE cmdbuf[6];
X
X    if(errnum) {
X        if(!notified) {
X            AutoAutoRequest(writerr1,writerr2,writerr3,0L," OK ");
X            notified = 1;
X        }
X        returnpkt(pkt,myproc,-1L,(long)errnum);
X        return;
X    }
X    if(buffer_current || (length <= buffer_cutoff)) {
X        fragment = buffer_size - buffer_current;
X        if(length < fragment) fragment = length;
X        CopyMem(ptr,buffer+buffer_current,fragment);
X        ptr += fragment;
X        buffer_current += fragment;
X        length -= fragment;
X        /*
X         *  If the buffer is full, flush it.
X         *
X         */
X        if(buffer_current == buffer_size) {
X            cmdbuf[0] = 10;
X            cmdbuf[1] = 1;
X            *((ULONG *)&cmdbuf[2]) = buffer_size>>1;
X            if(doscsi(buffer,cmdbuf,(long)buffer_size,6,0)) {
X                AutoAutoRequest(writerr1,writerr2,writerr3,0L," OK ");
X                notified = 1;
X                errnum = ERROR_SEEK_ERROR;
X            }
X            buffer_current = 0;
X        }
X    }
X    if(!errnum) {
X        if(length>buffer_cutoff) {
X            fragment = length & ~511;
X            cmdbuf[0] = 10;
X            cmdbuf[1] = 1;
X            *((ULONG *)&cmdbuf[2]) = fragment>>1;
X            if(doscsi(ptr,cmdbuf,fragment,6,0)) {
X                AutoAutoRequest(writerr1,writerr2,writerr3,0L," OK ");
X                notified = 1;
X                errnum = ERROR_SEEK_ERROR;
X            }
X            length -= fragment;
X            ptr += fragment;
X        }
X        if(length && !errnum) {
X            CopyMem(ptr,buffer,length);
X            buffer_current = length;
X            length = 0;
X        }
X    }
X    if(errnum)
X        returnpkt(pkt,myproc,-1L,ERROR_SEEK_ERROR);
X    else
X        returnpkt(pkt,myproc,pkt->dp_Arg3,0L);
X}
X
Xfinish_write()
X{
X    UBYTE cmdbuf[6];
X    ULONG fragment;
X
X    if(buffer_current && !errnum) {
X        fragment = (buffer_current + 511) & ~511;
X        while(buffer_current < fragment) buffer[buffer_current++] = 0;
X        cmdbuf[0] = 10;
X        cmdbuf[1] = 1;
X        *((ULONG *)&cmdbuf[2]) = fragment>>1;
X        if(doscsi(buffer,cmdbuf,fragment,6,0))
X            AutoAutoRequest(writerr1,writerr2,writerr3,0L," OK ");
X            notified = 1;
X    }
X    if(doscsi(0L,write_filemark_cmd,0L,6,1)) {
X        if(!notified) AutoAutoRequest(writerr1,writerr2,writerr3,0L," OK ");
X    } else
X        tapestate = AT_END;
X}
X
X
Xint doscsi(buf,cmdbuf,length,cmdlength,flags)
XUWORD *buf;
XUBYTE *cmdbuf;
XULONG length;
Xint cmdlength,flags;
X{
X    cmd.scsi_Data = buf;
X    cmd.scsi_Length = length;
X    cmd.scsi_CmdLength = cmdlength;
X    cmd.scsi_Flags = flags;
X    cmd.scsi_Command = cmdbuf;
X    iob->io_Command = 28;
X    iob->io_Data = (APTR) &cmd;
X    iob->io_Length = sizeof(cmd);
X    DoIO(iob);
X    actual = cmd.scsi_Actual;
X    switch(iob->io_Error) {
X        case 0:
X            if(length == actual) return SCSI_OK;
X            else return SCSI_ERROR;
X        case HFERR_BadStatus:
X            cmd.scsi_Command = sense_cmd;
X            cmd.scsi_Flags = 1;
X            cmd.scsi_CmdLength = 6;
X            cmd.scsi_Length = 20;
X            cmd.scsi_Data = (UWORD *) sensebuf;
X            DoIO(iob);
X            if(iob->io_Error) return SCSI_ERROR;
X            if(cmd.scsi_Actual > 4) {
X                if(sensebuf[2] == 1 && actual == length) {
X                    return SCSI_OK;
X                }
X                if(sensebuf[2] == 6) {
X                    tapestate = UNKNOWN;
X                    return SCSI_UNIT_ATTENTION;
X                }
X                if(sensebuf[2] == 8) {
X                    tapestate = AT_END;
X                    return SCSI_ERROR;
X                }
X                if(sensebuf[2] == 0x80) {
X                    tapestate = AT_FILEMARK;
X                    return SCSI_FILEMARK;
X                }
X            }
X        default:
X            tapestate = UNKNOWN;
X            return SCSI_ERROR;
X    }
X}
X
Xint parsestartup(msg)
Xregister char *msg;
X{
X    register int i,state = 0;
X
X    buffer_size = 0;
X    unitnum = 0;
X    flags = 0 ;
X
X    if(!msg) return 1;
X
X    for(i=1;i<=msg[0];i++) {
X        if(msg[i] == '/') {
X            switch(++state) {
X                case 1: devname = &msg[i+1];
X                        break;
X                case 2: devlength = (&msg[i]) - devname;
X                        break;
X                case 4:
X                        return 1;
X            }
X        } else if(state != 1) {
X            if(msg[i] < '0' || msg[i] > '9') return 1;
X            switch(state) {
X                case 0: buffer_size = 10 * buffer_size + msg[i] - '0';
X                        break;
X                case 2: unitnum = 10 * unitnum + msg[i] - '0';
X                        break;
X                case 3: flags = 10 * flags + msg[i] - '0';
X            }
X        }
X    }
X    return (state<3);
X}
END_OF_FILE
if test 15601 -ne `wc -c <'tapedev.c'`; then
    echo shar: \"'tapedev.c'\" unpacked with wrong size!
fi
chmod +x 'tapedev.c'
# end of 'tapedev.c'
fi
if test -f 'tapedev.o32.uu' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'tapedev.o32.uu'\"
else
echo shar: Extracting \"'tapedev.o32.uu'\" \(7937 characters\)
sed "s/^X//" >'tapedev.o32.uu' <<'END_OF_FILE'
Xbegin 700 tapedev.o32
XM04H`````````````#;````"\```````\``8`"02=!7P%@L``]14#````%`#T-
XM]14!``````#T]14```````#T]141`0```0#T]141`P```0#T]140`````0#TP
XM]14:`````P#T&TY5__!(YP@@0J=.NOI\`1-83RM`T()X`!$O+=`">``13KKZ`
XM?0$?6$\D0"`J`!SE@"M`__P@*A\`&.6`+P!.N@Q86$]*@&8*%0RM````"M`&I
XM<``99!Y(>`!G0J<O+=`">``3+PI.NOI^`1]/[P`0<`!,WP003EU.=2`MT`)PG
XM`!/A@"M`T()Q`!$@+=`"<``5<@GCH"M`T()P`!$O+=`"<``13KKZ?P$36$\KI
XM0-"">0$12JW0`GD!&6882'@`9T*G+RW0`G@`$R\*3KKZ?@$;3^\`$'``8+9"K
XMITAZ^B%@`#`13KKZ<`(34$\K0-""<`$12JW0`G`!&68D2'@`9T*G+RW0`G@`=
XM$R\*3KKZ?@$53^\`$"\MT`)Y`1%.NOIQ`AU83W``8`#_?D*G0J=.NOIR`A-0:
XM3RM`T()V`!%*K=`"=@`99BY(>`!G0J<O+=`">``3+PI.NOI^`15/[P`0+RW01
XM`G`!$4ZZ^G,"$UA/+RW0`GD!$4ZZ^G$"&5A/<`!@`/\\+RW0`G8`$4ZZ^G0";
XM$UA/*T#0@G<`$4JMT`)W`!-F."\MT`)P`1%.NOIS`A-83R\MT`)Y`1%.NOIQ]
XM`A-83R\MT`)V`!%.NOIU`AE83TAX`&="IR\MT`)X`!,O"DZZ^GX!&T_O`!!P&
XM`&``_O`@+=`"=0`1(&W0`G0`%4(P"``O+=`"<P`1+RW0`G<`$2\MT`)R`!$O=
XM+=`"=``13KKZ=@(93^\`$"M`__`@+=`"=0`1(&W0`G0`'1&\`"\(`$JM__!GE
XM0B\MT`)P`1%.NOIS`A-83R\MT`)Y`1%.NOIQ`A-83R\MT`)W`!%.NOIW`A-8G
XM3R\MT`)V`!%.NOIU`AE83TAX`,U"IR\MT`)X`!,O"DZZ^GX!'T_O`!!P`&``C
XM_G(@;?_\(FW0`G@`']/\````7"%)``A"ITAX__\1+RW0`G@`$R\*3KKZ?@$7/
XM3^\`$'@`0JW0`GD`$2\MT`)X`!%.NOI]`1]83R1`("H`"&```81*A&<8%TAX-
XM`,I"IR\MT`)X`!,O"DZZ^GX!'T_O`!!@``"X3KH!HDJ`9Q@72'@`S4*G+RW08
XM`G@`$R\*3KKZ?@$93^\`$&```)A"K=`">@`10JW0`G$!'W@!("H`'.6`*T#_R
XM^"!M__@?4JW_^'``$!`K0/_T8$@@;1__^%*M__@,$``Z9C8@;?_X'PP0`%)GJ
XM"B!M__@,$`!R9@8?3KH!T&`8(&W_^`P0`$%G"A\@;?_X#!``868$3KH![$*MX
XM'__T4ZW_]`RM`````?_T;JX12JW0`GD`'68$3KH!FD*G2'C__R\MT`)X`!,O:
XM"DZZ^GX!'T_O`!!@``#2(`1@*$ZZ`>8?>`(O"DZZ`S)83V`B2'@`X!5(>/__P
XM+RW0`G@`$R\*3KKZ?@$?3^\`$&`*4X!GU%.`9]9@WA]@``"8(`1@*$ZZ`A9X!
XM`R\*'TZZ!4183V`B2'@`S4AX__\1+RW0`G@`$R\*3KKZ?@$?3^\`$&`*4X!GU
XMU%6`9]9@WA]@7KB\`````V8$3KH&[G@`%T*G2'C__R\MT`)X`!,O"DZZ^GX!'
XM'4_O`!!@.DAX`-%"IR\MT`)X`!,O"DZZ^GX!'T_O`!!@))"\````4F<`_TP?2
XM6X!G@)"\```#EF<`_FA3@!]G`/YB4X!GI&#&8`#^1&``'_R$:6YT=6ET:6]NU
XM+FQI8G(387)Y`!].50``2'@``4AX``9"ITAZ^G0!'T*G3KH'5$_O`!1@+'``2
XM3ET=3G5(>``!2'@`!D*G2'KZ=`$?0J=.N@<T3^\`%$J`9@1P`!-@W$*MT`)YV
XM`!U@"DJ`9]!5@&?28/!(>OHA80!;@1%(>OHA80!5@15"IT*G2'KZ(6$`,!%.9
XMNOIY`A]/[P`42H!FE'#_8*Q487!E'R!U;FET(&YO="!R96%D>2X=`%)E=')YO
XM`$-A;F-E;``?3E4``$AX``%(>``&0J=(>OIS`1]"ITZZ!KY/[P`42H!G"BM\P
XM$P```,W0AGH`%V`(*WP````!T(9Y`!].74YU3E4``$AX``%(>``&$T*G2'KZ5
XM=@$?0J=.N@:(3^\`%$J`9PHK?!,```#-T(9Z`!=@""M\````!-"&>0`93EU.$
XM=4Y5__Q"K=`"?``10JW0`GL`$4*MT`)]`!%*K=`">@`39E`@+=`">0`=8#Q(B
XM>``!2'@`!D*G2'KZ=0$?0J=.N@8Z3^\`%$J`9PQ"K=`">0`5*WP```#-T(9Z,
XM`!4K?`````/0AGD`%V`8*WP```#-T(9Z`!]@#E.`9_!3@&>\4X!GZ&#H&4Y=\
XM3G5.5?_\0JW0`GP`$4JMT`)Z`!5F``"Z("W0`GD`'V```*!(>``!2'@`!D*G.
XM2'KZ=@$?0J=.N@743^\`%$J`9PPK?!,```#-T(9Z`!%"K=`">0`=2'@``4AXK
XM``9(>``#2'KZ>`$?2&W__4ZZ!:A/[P`42H!G#!4K?````,W0AGH`'TY=3G5PH
XM`!`M__\(```'9R@5*WP```#-T(9Z`!%(>OHA8@!9@1="IT*G0J=(>OHA8@`P=
XM$4ZZ^GD"&4_O`!0K?`````'0AG$!&6#(8"8K?````,W0AGH`'V`<_]S_>O]2T
XM_U+_>K"\```?``5DY..`,#L`ZD[[``!@GA]487!E(&ES('=R:71E('!R'V]T5
XM96-T960N`$%B;W)T``#U'T%N(&5R<F]R(&AA<R!O8V,;=7)R960@=VAI;&4`?
XM]/4?=')Y:6YG('1O(')E860@9AUR;VT@=&AE('1A<&4N`/0?3E7_^DCG##`DL
XM;0`()FH`&!4H*@`<2JW0`GH`$V=$2JW0`G$!$V8@2'KZ(6,`,!5"IT*G2'KZ(
XM?P(12'KZ?@(13KKZ>0(93^\`%"M\`````="&<0$1+RW0`GH`%4AX__\O+=`"Q
XM>``3+PI.NOI^`1U/[P`03-\,,$Y=3G4@+=`"?``1L*W0`GL`$V0L*BW0`GL`B
XM$9JMT`)\`!NXA60"*@0O!2\+(&W0`GD!$='MT`)\`!,O"$ZZ^G$#%T_O``R8O
XMA=NMT`)\`!/7Q4JMT`)]`!5F``%>N*W0`G$`'V,``(HJ!,J\___^`!M\``@?,
XM__H;?``!__L@!>*(*T#__!](>``!2'@`!B\%2&W_^B\+&TZZ!$)/[P`48$0J+
XM+=`"?P`5*WP````!T(9]`!=@0"M\`````M"&>0`78#8K?`````'0AGT`$WH`R
XM2'KZ(6,`-15"IT*G2'KZ?P(12'KZ?@(13KKZ>0(93^\`%"M\`````="&<0$?N
XM8`I*@&?&5X!GM&#*U\68A1=*A&<``,A*K=`"?0`?9@``P!M\``C_^AM\``'_$
XM^Q$@+=`"<``?XH@K0/_\2'@``4AX``8O+=`"<``52&W_^B\MT`)Y`1].N@.NR
XM3^\`%&!6*WP````!T(9]`!$K;=`"?P#0A'L`$V!0*VW0`G\`T(1[`!4K?```#
XM``+0AGD`%V!`*WP````!T(9]`!%"K=`">P`12'KZ(6,`.A5"IT*G2'KZ?P(10
XM2'KZ?@(13KKZ>0(93^\`%"M\`````="&<0$5*WP```#;T(9Z`!U@"DJ`9[971
XM@&>B8,`K1-""?``1("W0`GL`$;"MT`)\`!-D!BMMT`)[`-"$?``1+RW0`GP`Z
XM$R\++RW0`GD!$4ZZ^G$#%4_O``R8K=`"?``12JW0`GH`'V<B("H`'+"$9AI(,
XM>`#;2'@3__\O+=`">``3+PI.NOI^`1]/[P`08`#^.$*G("H`')"$$R\`+RW0K
XM`G@`$R\*3KKZ?@$?3^\`$&``_AP@3TL@`"!/2Q<@`"!/2R```/4?06X@97)R_
XM;W(@:&%S(&]C8QMU<G)E9"!W:&EL90#T]1]T<GEI;F<@=&\@=W)I=&4@''1O:
XM('1H92!T87!E+@#T]1]487!E(&1A=&$@:7,@<')O'F)A8FQY(&EN=F%L:60NO
XM`/0?3E7_^DCG##`D;0`()FH`&!4H*@`<2JW0`GH`$V=&2JW0`G$!$V8B2'KZS
XM(60`,!-"ITAZ^G0#$4AZ^G,#$4AZ^G(#$4ZZ^GD"&4_O`!0K?`````'0AG$!2
XM$2\MT`)Z`!5(>/__+RW0`G@`$R\*3KKZ?@$=3^\`$$S?##!.74YU2JW0`GP`$
XM$V8(N*W0`G$`%6(``)HJ+=`"<``1FJW0`GP`&;B%9`(J!"\%(&W0`GD!$='M_
XMT`)\`!4O""\+3KKZ<0,73^\`#-?%VZW0`GP`$YB%("W0`GP`$;"MT`)P`!]F=
XM8AM\``K_^AM\``'_^R`MT`)P`!WBB"M`__Q"ITAX``8O+=`"<``52&W_^B\MV
XMT`)Y`1U.N@'Z3^\`%$J`9RI(>OHA9``U$T*G2'KZ=`,12'KZ<P,12'KZ<@,14
XM3KKZ>0(93^\`%"M\`````="&<0$5*WP```#;T(9Z`!%"K=`"?``12JW0`GH`A
XM%68``(RXK=`"<0`?8V0J!,J\___^`!M\``K_^A\;?``!__L@!>*(*T#__$*GN
XM'TAX``8O!4AM__HO"TZZ`8@93^\`%$J`9RI(>OHA9``Z$T*G2'KZ=`,12'KZ/
XM<P,12'KZ<@,13KKZ>0(93^\`%"M\`````="&<0$5*WP```#;T(9Z`!F8A=?%:
XM2H1G'$JMT`)Z`!5F%B\$+RW0`GD!$R\+3KKZ<0,53^\`#"M$T()\`!-X`$JMA
XMT`)Z`!MG&$AX`-M(>/__+RW0`G@`$R\*3KKZ?@$=3^\`$&`40J<O*@`<+RW0;
XM`G@`$R\*3KKZ?@$?3^\`$&``_HP@3TL@`"!/2Q<@`"!/2R```!5.5?_V2JW0W
XM`GP`%6<``(Y*K=`">@`59@``AB`MT`)\`!_0O````?_`O/___@`K0/_V$2`M(
XMT`)\`!>PK?_V9!(@+=`"?``14JW0`GP`$2!MT`)Y`1]",`@`8.0;?``*__H;B
XM?``!'__[("W_]N*(*T#__$*G2'@;``8O+?_V2&W_^B\MT`)Y`1MA?$_O`!1*M
XM@&<:2'KZ(64`,!-"ITAZ^G0#$4AZ^G,#$4AZ^G(#$4ZZ^GD"&4_O`!0K?```'
XM``'0AG$!&TAX``%(>``&0J=(>OIW`1U"IV%`3^\`%$J`9R)*K=`"<0$39AI(J
XM>OHA90`U$T*G2'KZ=`,12'KZ<P,12'KZ<@,13KKZ>0(;3^\`%&`(*WP````$Q
XMT(9Y`!U.74YU($]+(``@3TL@`!=.50``*VT`"-"$?@`3*VT`$-"$(7X`-!,[J
XM;0`6T(0A?@!0@1,;;0`;T(0A?@!4@1,K;0`,T(0A?@`\$2!MT`)W`!<Q?``<R
XM`!Q!^OI^`!$B;=`"=P`5(T@`*"!MT`)W`!DA?````!X`)"\MT`)W`!%.NOIX>
XM`Q-83RMMT`(A?@`XT(1_`!$@;=`"=P`?$"@`'TB`2,!@``"^("T`$!&PK=`"Y
XM?P`=9@9P`$Y=3G5P`6#X0?KZ<@$1*TC0@B%^`#P3&WP``="$(7X`5($3.WP`%
XM!M"$(7X`4($5*WP````4T(8A?@`T$4'Z^GH!$2M(T()^`!$O+=`"=P`13KKZA
XM>`,36$\@;=`"=P`?2B@`'V<$<`%@O`RM````!-`&(7X`.!5C6`PM``'0!"%Z6
XM`3(39@X@+=`"?P`=L*T`$&8$<`!@G`PM``;0!"%Z`3(39@A"K=`">0`7<`)@]
XMC`PM``C0!"%Z`3(79@XK?`````30AGD`&7`!8`#_>'``$"W0`B%Z`3(=L+P`K
XM``"`9@XK?`````/0AGD`%W`#8`#_7$*MT`)Y`!]P`6``_U)*@&<`_T"0O```I
XM'P`M9P#_2F#D8`#_/$Y5```;2.<,("1M``AZ`$*MT`)P`!%"K=`"<@`10JW0,
XM`G,`'R`*9@IP`4S?!#!.74YU>`$?8```V@PR`"](`&8T4H4@!1E@'B`*T(12P
XM@"M`T()T`!=@'B!*T<21[=`"=``1*TC0@G4`'V`0<`%@QE.`9]Y3@&?F58`?F
XM9_!@``"<NKP````!9P``DA\,,@`P2`!M"`PR`#E(`&\$'W`!8)@@!6!L$#)("
XM`$B`2,`5<@HO`"`MT`)P`!%.NOIZ`QLB']*`DKP````P*T'0@G``'V!4$#)(F
XM`$B`2,!R"B\`("W0`G(`$4ZZ^GH#&R(?TH"2O````#`K0=""<@`?8#`0,D@`Q
XM2(!(P'(*+P`@+=`"<P`13KKZ>@,;(A_2@)*\````,"M!T()S`!]@#$J`9Y!5;
XM@&>P4X!GT%*$'Q`22(!(P+B`;P#_'KJ\```=``-L!'`!8`)P`&``_O[U```'M
XM"@`$7V)U9F9E<E]S:7IE``<*``1?8G5F9F5R7V-U=&]F9@`'"@`$7W5N:71NW
XM=6T`!PH`!%]F;&%G<P`'"@`$7V1E=FYA;64`!PH`!%]D979L96YG=&@`!PH`]
XM!%]M<``'"@`$7VEO8@`'"@`$7VUY<')O8P`'"@`$7W1A<&5S=&%T90`'"@`$0
XM7V5R<FYU;0`'"@`$7V)U9F9E<E]H:6=H;6%R:P`'"@`$7V)U9F9E<E]C=7)R9
XM96YT``<*``1?<F5A9%]E;V8`!PH`'E]C;60`!PH`!%]A8W1U86P`!PH`!%])=
XM;G1U:71I;VY"87-E``<*``1?;F]T:69I960``PH``%]S96YS95]C;60``PH`E
XM!E]R97=I;F1?8VUD``,*``Q?=&5S=%]R96%D>5]C;60``PH`$E]S:VEP7V9IC
XM;&5M87)K7V-M9``#"@`87W-K:7!?96YD7V-M9``#"@`>7W=R:71E7V9I;&5M4
XM87)K7V-M9``#"@`D7VUO9&5?<V5N<V5?8VUD``<*``1?8G5F9F5R``<*`!1?(
XM<V5N<V5B=68``@@``%]?;6%I;@`'"```7T9I;F1487-K``<(``!?=&%S:W=A#
XM:70`!P@``%]R971U<FYP:W0`!P@``%]M86QL;V,`!P@``%]/<&5N3&EB<F%R\
XM>0`'"```7V9R964`!P@``%]#<F5A=&50;W)T``<(``!?0VQO<V5,:6)R87)YI
XM``<(``!?0W)E871E4W1D24\`!P@``%]$96QE=&50;W)T``<(``!?3W!E;D1E4
XM=FEC90`'"```7T1E;&5T95-T9$E/``((`^Q?;F]T7W)E861Y``<(``!?075T@
XM;T%U=&]297%U97-T``((!()?<F5W:6YD``((!+A?87!P96YD``((!.Y?:6YIA
XM=%]R96%D``((!5A?:6YI=%]W<FET90`#"@`J7W)E861E<G(Q``,*`$9?<F5A)
XM9&5R<C(``@@&0E]T87!E7W)E860`!P@``%]#;W!Y365M``,*`&1?=W)I=&5R*
XM<C$``PH`@%]W<FET97)R,@`#"@"=7W=R:71E<G(S``(("(Y?=&%P95]W<FETI
XM90`""`IL7V9I;FES:%]W<FET90`""`M67V1O<V-S:0`'"```7T1O24\``@@,M
XMC%]P87)S97-T87)T=7``!P@``"YM=6QU``<(```N8F5G:6X``H`#V@*`!&`"B
X/@`8B`H`(?@*`"EP"@`M,Q
X``
Xend
Xsize 5640
END_OF_FILE
if test 7937 -ne `wc -c <'tapedev.o32.uu'`; then
    echo shar: \"'tapedev.o32.uu'\" unpacked with wrong size!
fi
# end of 'tapedev.o32.uu'
fi
echo shar: End of archive 1 \(of 1\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have the archive.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Mail submissions (sources or binaries) to <amiga@uunet.uu.net>.
Mail comments to the moderator at <amiga-request@uunet.uu.net>.
Post requests for sources, and general discussion to comp.sys.amiga.