home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Dream 44
/
Amiga_Dream_44.iso
/
Amiga
/
workbench
/
pilotes
/
Zorro
/
vbak2091.lha
/
vbak2091.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-08-13
|
16KB
|
741 lines
/* vb2091 V1.2 (13.8.97)
(c) in 1994 by Volker Barthelmann
modified 1996-97 by Andreas R. Kleinert,
Andreas_Kleinert@t-online.de
USAGE AT YOUR OWN RISK. NOBODY CAN BE HELD RESPONSIBLE FOR ANY DAMAGES.
*/
#include "compiler.h"
#define AUTHORS "vb2091 V1.2 (c) in 1994 by Volker Barthelmann.\n" \
"Changes by Andreas R. Kleinert in 1996-97\n"
#define RISK "USAGE AT YOUR OWN RISK.\n" \
"NOBODY CAN BE HELD RESPONSIBLE FOR ANY DAMAGES.\n"
#ifdef __SASC
#define __USE_SYSBASE
#endif
#ifndef __inline
#define __inline inline
#endif
#ifndef inline
#define inline
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <exec/execbase.h>
#include <exec/memory.h>
#include <exec/io.h>
#include <exec/semaphores.h>
#include <devices/trackdisk.h>
#include <devices/timer.h>
#include <dos/dosextens.h>
#include <dos/filehandler.h>
#include <dos/dostags.h>
#ifdef __SASC
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/utility.h>
#include <clib/alib_protos.h>
#else
#include <clib/exec_protos.h>
#include <clib/alib_protos.h>
#include <clib/dos_protos.h>
#endif /* __SASC */
#define DEV_BEGINIO (-30)
#define min(a,b) ((a) < (b) ? (a) : (b))
#define RESERVED (1<<0)
#define BROKEN (1<<1)
#define SINGLEF (1<<2)
#define NOCACHE (1<<3)
#define NOWRITE (1<<4)
#define NOASYNCH (1<<5)
#define MAXUNIT 8
#ifdef __SASC
void __asm (*oldbeginio)(register __a1 struct IOStdReq *req, register __a6 struct Device *dev);
__aligned struct IOStdReq *IO [MAXUNIT] = { 0, 0, 0, 0, 0, 0, 0, 0};
__aligned void *Unit[MAXUNIT] = { 0, 0, 0, 0, 0, 0, 0, 0};
char __aligned zahl[] = "0123456789";
void __inline __regargs copymem(UBYTE *s, UBYTE *d, ULONG b);
void __inline __regargs copymem(UBYTE *s, UBYTE *d, ULONG b)
{
while(b--) *d++ = *s++;
}
void __inline __regargs copymemquick(ULONG *s, ULONG *d, ULONG b);
void __inline __regargs copymemquick(ULONG *s, ULONG *d, ULONG b)
{
while(b) { *d++ = *s++; b -= 4; }
}
void __inline __regargs FastCopy(APTR s, APTR d, ULONG b);
void __inline __regargs FastCopy(APTR s, APTR d, ULONG b)
{
/* -----------------------------------------------------
#define one out of: OS_COPY_PLAIN, OS_COPY_OPT
OWN_COPY_PLAIN, OWN_COPY_OPT
OWN_COPY_SPECIAL
----------------------------------------------------- */
#define OWN_COPY_SPECIAL
/* >>--------------------------------------------------- */
#ifdef OS_COPY_PLAIN
CopyMem(s, d, b);
#endif
/* >>--------------------------------------------------- */
#ifdef OS_COPY_OPT
if((ULONG)b & 3) CopyMem( s, d, b);
else if((ULONG)s & 3) CopyMem( s, d, b);
else if((ULONG)d & 3) CopyMem( s, d, b);
else CopyMemQuick( s, d, b);
#endif
/* >>--------------------------------------------------- */
#ifdef OWN_COPY_PLAIN
copymem(s, d, b);
#endif
/* >>--------------------------------------------------- */
#ifdef OWN_COPY_OPT
if((ULONG)b & 3) copymem( s, d, b);
else if((ULONG)s & 3) copymem( s, d, b);
else if((ULONG)d & 3) copymem( s, d, b);
else copymemquick( s, d, b);
#endif
/* >>------------ FASTEST in comparison ---------------- */
/* >> on 4000/040 with 16 MB FAST */
#ifdef OWN_COPY_SPECIAL
if((ULONG)b & 3) CopyMem( s, d, b);
else if((ULONG)s & 3) CopyMem( s, d, b);
else if((ULONG)d & 3) CopyMem( s, d, b);
else copymemquick( s, d, b);
#endif
}
#else /* __SASC */
#ifdef __VBCC
void (*oldbeginio)(__reg("a1") struct IOStdReq *, __reg("a6") struct Device *);
#else
void (*oldbeginio)( register __a1 struct IOStdReq *req_a1 GNUCREG(a1), register __a6 struct Device *dev GNUCREG(a6) );
#endif /* __VBCC */
struct IOStdReq *IO [MAXUNIT] = { 0, 0, 0, 0, 0, 0, 0, 0};
void *Unit[MAXUNIT] = { 0, 0, 0, 0, 0, 0, 0, 0};
char zahl[] = "0123456789";
#define FastCopy CopyMem
#endif /* __SASC */
ULONG flags = 0, UnitNr = 0, unitmask = 0;
ULONG SIZE = 262144, DIVSIZE2 = 131072, msize;
ULONG MAXN = 16, MIN1BUF = 131072, MIN2BUF = 65536;
ULONG MULMIN2BUF = 16 * 131072;
struct SignalSemaphore *ss = NULL;
UBYTE *buffer = NULL;
UBYTE *buffer2 = NULL;
#ifdef __SASC
void __saveds __asm mybeginio(register __a1 struct IOStdReq *req_a1,register __a6 struct Device *dev_a6)
{
struct IOStdReq *req = req_a1;
struct Device *dev = dev_a6;
ULONG flag;
#else
#ifdef __VBCC
void mybeginio(__reg("a1") struct IOStdReq *req,__reg("a6") struct Device *dev)
{
ULONG flag;
geta4();
#else
ULONG __saveds ASM mybeginio( register __a1 struct IOStdReq *req_a1 GNUCREG(a1), register __a6 struct Device *dev GNUCREG(a6) )
{
struct IOStdReq *req = req_a1;
struct Device *dev = dev_a6;
ULONG flag;
#endif /* __VBCC */
#endif
ObtainSemaphore(ss);
for(flag = 0; flag < MAXUNIT; flag++)
{
if(req->io_Unit == Unit[flag])
{
struct IOStdReq *mreq;
struct MsgPort *port;
ULONG actual,data,offset,length,lactual,un;
mreq = req;
un = flag;
if((req->io_Command & 0xFF) == CMD_READ)
{
ULONG ldata, msize;
if(!(flags & BROKEN))
if((ULONG) req->io_Data < 16777216) goto old;
port = (struct MsgPort *) CreatePort(NULL,0);
if(!port) goto old;
IO[un]->io_Message.mn_ReplyPort = port;
actual = 0;
length = mreq->io_Length;
if(length < MIN1BUF)
{
msize = min( length, DIVSIZE2);
}else
{
if(length > MULMIN2BUF) msize = min((length+MAXN-1)/MAXN, DIVSIZE2);
else msize = min( MIN2BUF, DIVSIZE2);
}
if(msize >= 512) msize = msize & 0xfffffe00;
offset = mreq->io_Offset;
data = (ULONG) mreq->io_Data;
lactual = (flag = 0);
ldata = data;
req = IO[un];
dev = IO[un]->io_Device;
if(flags & NOCACHE) CacheControl(0, CACRF_EnableD);
if(flags & SINGLEF)
{
do
{
req->io_Command = CMD_READ;
req->io_Offset = offset;
req->io_Length = min(SIZE, length);
req->io_Length = min(msize, length);
req->io_Data = buffer;
#ifdef __SASC
oldbeginio(req, dev);
#else
#ifdef __VBCC
oldbeginio(req, dev);
#else
oldbeginio(req, dev);
#endif /* __VBCC */
#endif
WaitIO((struct IORequest *) req);
lactual = req->io_Actual;
actual += lactual;
ldata = data;
data += lactual;
offset += lactual;
length -= lactual;
flag = 1-flag; /* toggle 0/1 */
FastCopy(buffer,(APTR) ldata,lactual);
}while( (length) && (req->io_Actual >= req->io_Length) );
}else
{
do
{
req->io_Command = CMD_READ;
req->io_Offset = offset;
req->io_Length = min(msize, length);
if(!flag) req->io_Data = buffer;
else req->io_Data = buffer2;
#ifdef __SASC
oldbeginio(req, dev);
#else
#ifdef __VBCC
oldbeginio(req, dev);
#else
oldbeginio(req, dev);
#endif /* __VBCC */
#endif
if(flag) FastCopy(buffer, (APTR) ldata, lactual);
else FastCopy(buffer2, (APTR) ldata, lactual);
WaitIO((struct IORequest *) req);
lactual = req->io_Actual;
actual += lactual;
ldata = data;
data += lactual;
offset += lactual;
length -= lactual;
flag = 1-flag; /* toggle 0/1 */
}while( (length) && (req->io_Actual >= req->io_Length) );
if(flag) FastCopy(buffer, (APTR) ldata, lactual);
else FastCopy(buffer2, (APTR) ldata, lactual);
}
if(flags & NOCACHE) CacheControl(0xffffffff, CACRF_EnableD);
mreq->io_Actual = actual;
mreq->io_Error = req->io_Error;
if(!(mreq->io_Flags & IOF_QUICK)) ReplyMsg(&mreq->io_Message);
DeletePort(port);
ReleaseSemaphore(ss);
return;
}
if((req->io_Command & 0xFF) == CMD_WRITE)
{
if(flags & NOWRITE) goto old;
if(!(flags & BROKEN))
if((ULONG) req->io_Data<16777216) goto old;
port = (struct MsgPort *) CreatePort(NULL,0);
if(!port) goto old;
IO[un]->io_Message.mn_ReplyPort = port;
actual = 0;
length = mreq->io_Length;
offset = mreq->io_Offset;
data = (ULONG) mreq->io_Data;
req = IO[un];
dev = IO[un]->io_Device;
if(flags & NOCACHE) CacheControl(0,CACRF_EnableD);
do
{
if(SIZE >= length) req->io_Length = length;
else req->io_Length = SIZE;
FastCopy((APTR) data, buffer, req->io_Length);
req->io_Offset = offset;
req->io_Data = buffer;
req->io_Command = CMD_WRITE;
#ifdef __SASC
oldbeginio(req, dev);
#else
#ifdef __VBCC
oldbeginio(req, dev);
#else
oldbeginio(req, dev);
#endif /* __VBCC */
#endif
WaitIO((struct IORequest *) req);
actual += (lactual = req->io_Actual);
data += lactual;
offset += lactual;
length -= lactual;
}while( (length) && (req->io_Actual >= req->io_Length) );
if(flags & NOCACHE) CacheControl(0xffffffff, CACRF_EnableD);
mreq->io_Actual = actual;
mreq->io_Error = req->io_Error;
if(!(mreq->io_Flags & IOF_QUICK)) ReplyMsg(&mreq->io_Message);
DeletePort(port);
ReleaseSemaphore(ss);
return;
}
break;
}
}
old:
#ifdef __SASC
oldbeginio(req, dev);
#else
#ifdef __VBCC
oldbeginio(req, dev);
#else
oldbeginio(req, dev);
#endif /* __VBCC */
#endif
if(flags & NOASYNCH)
{
ULONG sig = 1<<req->io_Message.mn_ReplyPort->mp_SigBit;
Wait(sig);
SetSignal(sig, sig); /* again */
}
ReleaseSemaphore(ss);
}
#ifdef __SASC
void __regargs __chkabort(void) { } /* don't break us ! */
void __regargs _CXBRK(void) { }
void __inline StdioWrite(BPTR out, char *txt);
void __inline StdioWrite(BPTR out, char *txt)
{
if(out) Write(out, txt, strlen(txt));
}
#else
#ifdef __VBCC
void StdioWrite(BPTR out, char *txt);
void StdioWrite(BPTR out, char *txt)
{
if(out) Write(out, txt, strlen(txt));
}
#else
void inline StdioWrite(BPTR out, char *txt);
void inline StdioWrite(BPTR out, char *txt)
{
if(out) Write(out, txt, strlen(txt));
}
#endif /* __VBCC */
#endif
char version[] = "\0$VER: vb2091 1.2 (13.8.97)";
int main(long argc, char *argv[])
{
ULONG tmp, op, devopen, i, j, ret = 0;
ULONG opened[8], patched[8];
struct MsgPort *iosink[MAXUNIT] = {0,0,0,0,0,0,0,0};
char *Device, *p;
UBYTE port_name[256];
tmp = 0;
devopen = 0;
Device = "2nd.scsi.device";
op = Output();
for(i=1; i<argc; i++)
{
if(!strcmp("BUFSIZE",argv[i]))
{
SIZE = atol(argv[++i])*1024;
if(!SIZE) SIZE = 262144;
DIVSIZE2 = SIZE >> 1;
continue;
}
if(!strcmp("MIN1BUF",argv[i]))
{
MIN1BUF = atol(argv[++i])*1024;
if(!MIN1BUF) MIN1BUF = 131072;
continue;
}
if(!strcmp("MIN2BUF",argv[i]))
{
MIN2BUF = atol(argv[++i])*1024;
if(!MIN2BUF) MIN2BUF = 65536;
continue;
}
if(!strcmp("MAXN",argv[i]))
{
MAXN = atol(argv[++i]);
if(!MAXN) MAXN = 16;
continue;
}
if(!strcmp("DEVICE",argv[i]))
{
Device = argv[++i];
continue;
}
if(!strcmp("UNIT",argv[i]))
{
p = argv[++i];
while(*p!=0)
{
if(*p<'0'||*p>'7')
{
StdioWrite(op, "You can only use unit 0..7!!\n");
exit(0);
}
unitmask|=1<<(*p-'0');
p++;
}
continue;
}
if(!strcmp("BROKEN",argv[i]))
{
flags |= BROKEN;
continue;
}
if(!strcmp("SINGLE",argv[i]))
{
flags |= SINGLEF;
continue;
}
if(!strcmp("NOCACHE",argv[i]))
{
flags |= NOCACHE;
continue;
}
if(!strcmp("NOWRITE",argv[i]))
{
flags |= NOWRITE;
continue;
}
if(!strcmp("NOASYNCH",argv[i]))
{
flags |= NOASYNCH;
continue;
}
StdioWrite(op,"Wrong argument: ");
StdioWrite(op,argv[i]);
StdioWrite(op,"\nPLEASE READ THE MANUAL !!\n");
exit(0);
}
strcpy(port_name, "vb2091_");
strcat(port_name, Device);
if(FindPort(port_name))
{
StdioWrite(op, "vb2091 already running for this device !\n");
exit(0);
}
MULMIN2BUF = MIN2BUF * MAXN;
StdioWrite(op, AUTHORS);
StdioWrite(op, RISK);
for(i=0;i<MAXUNIT;i++)
{
opened[i] = FALSE;
patched[i] = FALSE;
if(!(unitmask&(1<<i))) continue;
iosink[i] = (struct MsgPort *)CreatePort(NULL, 0);
if(iosink[i])
{
IO[i] = (struct IOStdReq *) CreateExtIO(iosink[i], sizeof(struct IOStdReq));
if(IO[i]) tmp = OpenDevice(Device, i, (struct IORequest *) IO[i], 0);
}
if(tmp || (!IO[i]) || (!iosink[i]))
{
UBYTE digit[2];
StdioWrite(op,"Unable to open ");
StdioWrite(op, Device);
StdioWrite(op," Unit ");
digit[0] = zahl[i];
digit[1] = (UBYTE) 0;
StdioWrite(op, digit);
StdioWrite(op,"\n");
IO[i] = 0;
continue;
}else
{
UBYTE digit[2];
StdioWrite(op, "Opened ");
StdioWrite(op, Device);
StdioWrite(op, " Unit ");
digit[0] = zahl[i];
digit[1] = (UBYTE) 0;
StdioWrite(op, digit);
StdioWrite(op,"\n");
devopen = 1;
opened[i] = TRUE;
patched[i] = TRUE;
SumLibrary((struct Library *) IO[i]->io_Device);
#ifdef __SASC
if(oldbeginio==NULL) oldbeginio = (void (* __asm )(register __a1 struct IOStdReq *req,
register __a6 struct Device *dev)) SetFunction((struct Library *) IO[i]->io_Device, DEV_BEGINIO, (APTR) &mybeginio);
#else
if(oldbeginio==NULL) oldbeginio = (void (* )()) SetFunction((struct Library *) IO[i]->io_Device, DEV_BEGINIO, (APTR) &mybeginio);
#endif /* __SASC */
Unit[i]=IO[i]->io_Unit;
}
}
ss = (struct SignalSemaphore *)AllocVec(sizeof (struct SignalSemaphore), MEMF_PUBLIC);
if(ss)
{
InitSemaphore(ss);
if(flags & BROKEN) buffer = (char *) AllocVec(SIZE, MEMF_24BITDMA|MEMF_FAST|MEMF_PUBLIC);
else buffer = (char *) AllocVec(SIZE, MEMF_24BITDMA|MEMF_PUBLIC);
if(buffer)
{
buffer2 = buffer + DIVSIZE2;
if(devopen)
{
struct MsgPort *inst;
inst = (struct MsgPort *)CreatePort(port_name, 0);
Wait(SIGBREAKF_CTRL_C);
if(inst) DeletePort(inst);
}
ObtainSemaphore(ss);
for(i=0; i<MAXUNIT; i++)
{
j = MAXUNIT-i-1;
if(IO[j])
{
if(patched[j]) SetFunction((struct Library *) IO[j]->io_Device, DEV_BEGINIO, (APTR) oldbeginio);
if(opened[j]) CloseDevice((struct IORequest *) IO[j]);
DeleteExtIO((struct IORequest *) IO[j]);
}
if(iosink[j]) DeletePort(iosink[j]);
}
ReleaseSemaphore(ss);
FreeVec(buffer);
}else
{
StdioWrite(op,"Cannot allocate buffer!!\n");
ret = 20;
}
FreeVec(ss);
}else
{
StdioWrite(op,"Cannot allocate semaphore!!\n");
ret = 20;
}
exit(ret);
}