home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gold Fish 1
/
GoldFishApril1994_CD1.img
/
d1xx
/
d151
/
pcopy
/
pcopy.c
< prev
next >
Wrap
C/C++ Source or Header
|
1987-06-15
|
15KB
|
533 lines
char *stx[]={
" Pcopy 1.0 1 April 88 by D.Reisig",
" Pcopy 1.0 is PD",
" Made in Holland!"
};
#include "pcopy.h"
/*
* Since no commandline parameters are processed, we may prevent
* a call to exit(), by defining _main() here.
*
* We do a call to Init() which sets up all I/O, check patching
* sceentitles, loop copy function and if desired, a call to Quit()
* which returns all memory and closes all I/O.
*/
_main()
{
register struct IntuiMessage *Mesg;
register int message;
if (!Init()){
SetWindowTitles(WT,-1,stx[0]);
SetWindowTitles(W1,-1,stx[1]);
SetWindowTitles(W0,-1,stx[2]);
ConPutStr(IOHist,"\x9b0 p\n\n\n\n\n\n ");
while(1){
MainLoop();
Mesg=GetMsg(WS->UserPort);
if (Mesg){
message=Mesg->Class;
ReplyMsg(Mesg);
if (message==CLOSEWINDOW){
if (!Request(" Pcopy","","stay","away")) break;
}
}
}
}
Quit(); /* return and close everything */
return(0);
} /* _main */
/*
* See if somthing happend in the command window, check drives and
* set "Now in .." windows. Finally check if a start copy condition
* became valid.
*/
void MainLoop()
{
static int d0cnt=-1, d1cnt=-1;
CheckControl(1); /* some user command? */
if (GetDrive(D0)){ /* disk is present */
if (d0cnt!=D0->ChgNum){
ShDName(W0,D0->VolName);
d0cnt=D0->ChgNum;
}
} else{ /* disk is absent */
ShDName(W0,0);
EnAuto=-1; /* enable auto start */
}
if (GetDrive(D1)){
if (d1cnt!=D1->ChgNum){
ShDName(W1,D1->VolName);
d1cnt=D1->ChgNum;
}
} else{
ShDName(W1,0);
EnAuto=-1;
}
CheckCopy();
} /* MainLoop() */
/*
* React upon windowsizing of the history window.
* The gadgets are scanned and some minor (mostly intuition-patches)
* actions are taken. Did I do it wrong or isn't intuition that good?
*/
void CheckControl(flag)
short flag;
{
static short Excla=0, HistH=HHS;
if (HistH!=WH->Height){
HistH=WH->Height;
RefHist();
} /* NowCopy tells us which picture presently is displayed */
if (GAuto.Flags&SELECTED){
if (NowCopy){
RemoveGadget(WS,&GCopy); /* remove manual start */
GCopy.Flags&=~SELECTED; /* no surprises when changed back! */
DrawImage(WS->RPort,&IMBlnk,16,4*GGH); /* clear area */
PrintIText(WS->RPort,&ITCCon,16,4*GGH+2);
AddGadget(WS,&GUnRd,-1);
AddGadget(WS,&GNDOS,-1);
RefreshGadgets(&GUnRd,WS,0);
NowCopy=0;
}
} else{
if (!NowCopy){
RemoveGadget(WS,&GNDOS);
RemoveGadget(WS,&GUnRd);
DrawImage(WS->RPort,&IMBlnk,16,4*GGH);
AddGadget(WS,&GCopy,-1);
RefreshGadgets(&GCopy,WS,0);
NowCopy=1;
}
}
if ((GAuto.Flags&SELECTED) /* check for dangerous condition */
&&!(GNDOS.Flags&SELECTED)
&&!(GUnRd.Flags&SELECTED)){
if (!Excla){ /* display alarming exclamation */
DrawImage(WS->RPort,&IMEcla,160,5*GGH);
Excla=1;
}
}else if (Excla){ /* or remove it */
DrawImage(WS->RPort,&IMEcOf,160,5*GGH);
Excla=0;
}
if (GD0D1.Flags&SELECTED){ /* set colors and arrow according to */
ITDr0.FrontPen=PenB; /* selected direction */
ITDr1.FrontPen=PenA; /* if selected, change state and deselect */
GD0D1.GadgetRender=ArrowB; /* again */
GD0D1.SelectRender=ArrowA;
ArrowA=GD0D1.GadgetRender;
ArrowB=GD0D1.SelectRender;
PenA=ITDr0.FrontPen;
PenB=ITDr1.FrontPen;
GD0D1.Flags&=~SELECTED; /* if done deselect gadget */
RefOneGadget(&GD0D1,WS,0);
}
/* refresh (deghost) window titles */
if (!flag){ /* track window with or without depth g's */
TxT[SHORTTIME]=' ';
DrawImage(WT->RPort,&IMTTTL,0,0);
DrawImage(WT->RPort,&IMTTTL,0,9);
PrintIText(WT->RPort,&ITT,4,1);
} else{
TxT[SHORTTIME]='\0';
PrintIText(WT->RPort,&ITT,4,1);
}
PrintIText(WH->RPort,&ITH,4,1);
PrintIText(W1->RPort,&IT1,4,1);
PrintIText(W0->RPort,&IT0,4,1);
} /* CheckControl */
/*
* Gather all possible info of a drive and return disk presence.
*/
GetDrive(drive)
register DrInfo *drive;
{
register char *name=(char *)(&CopyBuffer[ROOT_VOLNAME]);
register int error;
drive->Req.io_Command=TD_CHANGESTATE;
DoIO(&drive->Req); /* is there a disk? */
if (drive->Present=~drive->Req.io_Actual){
drive->Req.io_Command=TD_CHANGENUM;
DoIO(&drive->Req); /* did we check it already? */
if (drive->ChgNum!=drive->Req.io_Actual){ /* no .. */
drive->ChgNum=drive->Req.io_Actual;
drive->DOSDisk=0;
drive->DOSBoot=0;
drive->Readable=0;
error=ReadSec(drive,0,CopyBuffer); /* readable? */
if (!error||(error!=TDERR_NoSecHdr)){
drive->Readable=-1;
if (!error&&((*CopyBuffer==0x444f5300)||(*CopyBuffer==0x4b49434b))){
drive->DOSBoot=-1; /* DOS\0 or KICK */
if (!ReadSec(drive,ROOTSECTOR,CopyBuffer)
&&!CheckSum(CopyBuffer)&&(*name<VOLNAMESIZE)){
drive->DOSDisk=-1; /* Truly Amiga-DOS */
strncpy(drive->VolName,name+1,*name);
drive->VolName[*name]='\0';
} else strcpy(drive->VolName,"\x0eNear DOS");
} else strcpy(drive->VolName,"\x0eNon DOS");
} else strcpy(drive->VolName,"\x0eUnreadable");
MotorOff(drive);
} /* end of other chgnum */
} else drive->Present=0;
return ((int)drive->Present);
} /* GetDrive() */
ReadSec(drive,sector,buffer)
register DrInfo *drive; SHORT sector; char *buffer;
{
drive->Req.io_Command=CMD_READ;
drive->Req.io_Data=(APTR)buffer;
drive->Req.io_Length=TD_SECTOR;
drive->Req.io_Offset=sector*TD_SECTOR;
DoIO(&drive->Req);
return((int)drive->Req.io_Error);
}
/*
* The checksum is OK if we add all longwords in a sector and its
* result is zero.
*/
CheckSum(Sector)
register ULONG *Sector;
{
register ULONG Sum;
register short i;
for (Sum=0,i=0;i<TD_SECTOR/4;++i) Sum+=Sector[i];
return(Sum);
}
/*
* This routine does the diskcopy. If succesful, a new title is dispayed
* in the drive's window and the name is pushed into the history
* buffer/window. A short sound signal put out.
* If an error occured, a requester is set up to ask a decision from
* the user. If aborted, a special message is displayed in the drive's
* window, and the routine is left.
*/
DiskCopy(Source,Dest,mod)
register DrInfo *Source, *Dest; short mod;
{
register int cylinder, byte, error;
char Errbuf0[64], Errbuf1[64];
char *name=(char *)(&CopyBuffer[ROOT_VOLNAME]);
OffGadget(&GD0D1,WS,0); /* disable source/dest selection */
GCopy.Flags|=GADGDISABLED; /* disable manual start */
if (NowCopy){ /* Intuition handles it bad - trick needed */
DrawImage(WS->RPort,&IMBlnk,16,4*GGH);
RefOneGadget(&GCopy,WS,0);
}
D0->Count=D0->ChgNum; /* set up for Extended Command */
D1->Count=D1->ChgNum;
if (mod==WAIT){ /* Special case, see manual */
DisplayBeep(IntuitionBase->ActiveScreen);
Delay(100);
}
/* This is the cylinder counting loop */
for (cylinder=0,byte=0;cylinder<NUMCYLS;++cylinder,byte+=BPCYL){
DrawImage(WT->RPort,&IMTmOn,cylinder*4,12); /* track window */
ReadSource:
if (error=DIOCyl(Source,byte,CopyBuffer,ETD_READ)){
stci_d(stpcpy(Errbuf0,"Source read error # "),error);
stci_d(stpcpy(Errbuf1,"On cylinder # "),cylinder);
Beep();
if (Request(Errbuf0,Errbuf1,"retry","abort")) goto ReadSource;
else break;
}
if (cylinder==ROOTCYL){
ChangeRoot(CopyBuffer);
strncpy(Dest->VolName,name+1,*name);
Dest->VolName[*name]='\0';
Dest->DOSDisk=-1;
}
WriteDestination:
if (error=DIOCyl(Dest,byte,CopyBuffer,ETD_FORMAT)){
stci_d(stpcpy(Errbuf0,"Destination write error # "),error);
stci_d(stpcpy(Errbuf1,"On cylinder # "),cylinder);
Beep();
if (Request(Errbuf0,Errbuf1,"retry","abort")) goto WriteDestination;
else break;
}
if (GVerf.Flags&SELECTED){
Dest->Req.io_Command=ETD_CLEAR;
DoIO(&Dest->Req);
if (error=DIOCyl(Dest,byte,CompBuffer,ETD_READ)){
stci_d(stpcpy(Errbuf0,"Destination read error # "),error);
stci_d(stpcpy(Errbuf1,"On cylinder # "),cylinder);
Beep();
if (Request(Errbuf0,Errbuf1,"retry","abort")) goto WriteDestination;
else break;
}
if (Compare(CopyBuffer,CompBuffer)){
stci_d(stpcpy(Errbuf1,"On cylinder # "),cylinder);
Beep();
if (Request("Verification error",Errbuf1,"retry","abort"))
goto WriteDestination;
else break;
}
}
} /* end of cylinder count loop */ /* copy done */
DrawImage(WT->RPort,&IMTmOf,0,12); /* clear track window */
RefreshWindowFrame(WT); /* depth gadgets back */
if (!error){
ConPutStr(IOHist,"\n ");
ConPutStr(IOHist,Dest->VolName);
EnterHist(Dest->VolName);
Beep(0);
} else{
strcpy(Dest->VolName,"\x0eCopy unsuccesful");
Dest->DOSDisk=0;
}
ShDName(W0,D0->VolName);
ShDName(W1,D1->VolName);
MotorOff(Source);
MotorOff(Dest);
OnGadget(&GD0D1,WS,0); /* enable direction selection */
GCopy.Flags&=~GADGDISABLED;
if (NowCopy){ /* that intuition patch again */
DrawImage(WS->RPort,&IMBlnk,16,4*GGH);
RefOneGadget(&GCopy,WS,0);
}
return(error);
} /* DiskCopy */
/*
* Read or write one cylinder.
*/
DIOCyl(drive,byte,buffer,cmd)
register DrInfo *drive; ULONG byte; char *buffer; int cmd;
{
drive->Req.io_Command=cmd;
drive->Req.io_Data=(APTR)buffer;
drive->Req.io_Length=BPCYL;
drive->Req.io_Offset=byte;
SendIO(&drive->Req);
CheckControl(0); /* see if things did change (without track dg's) */
WaitIO(&drive->Req);
return((int)drive->Req.io_Error);
}
Compare(a,b)
register ULONG *a, *b;
{
register int i;
for (i=0;i<(BPCYL/4);++i) if (*(a++)!=*(b++)) return(25); /* or 42 iyl */
return(0);
}
void MotorOff(drive)
register DrInfo *drive;
{
drive->Req.io_Command=TD_MOTOR;
drive->Req.io_Length=0;
DoIO(&drive->Req);
}
/*
* Set present time and date in the creation and last changed field
* If the bitmap is -1, it is set to +1. A new checksum is calculated.
*/
void ChangeRoot(sector)
register ULONG *sector;
{
register ULONG *ptr, sum, i;
DateStamp(§or[ROOT_ALTDAYS]);
sector[ROOT_CRTDAYS]=sector[ROOT_ALTDAYS];
sector[ROOT_CRTMINS]=sector[ROOT_ALTMINS];
sector[ROOT_CRTTICKS]=sector[ROOT_ALTTICKS];
if (sector[ROOT_BMFFLAG]==-1) sector[ROOT_BMFFLAG]=1;
for (ptr=sector,sector[ROOT_CHKSUM]=0,sum=0,i=0;i<LPSECTOR;++i)
sum+=*(ptr++);
sector[ROOT_CHKSUM]=0-sum;
} /* ChangeRoot() */
/*
* First see to get two drives. Then init (alloc) the DrInfo-structures,
* set drive names on their places (Now in.. windows and direction g's),
* Call OpenUser(), which opens the windows and get data buffers.
*/
Init(){
register short error=0;
if ((IntuitionBase=(struct IntuitionBase *)
OpenLibrary("intuition.library",0))==NULL) return(-1);
if (!AskDrives()){
if (!(D0=OpenDrive(DriveName[0],DriveNr[0]))) ++error;
if (!(D1=OpenDrive(DriveName[1],DriveNr[1]))) ++error;
} else ++error;
if (error){
Request("Pcopy did not get","two drives","OK","OK");
return(-1);
}
ITDr0.IText=D0->DevName;
strcpy(&Tx0[9],D0->DevName);
Tx0[13]=' ';
ITDr1.IText=D1->DevName;
strcpy(&Tx1[9],D1->DevName);
Tx1[13]=' ';
error=OpenUser();
if (!(CopyBuffer=(ULONG *)AllocMem(BPCYL,MEMF_CHIP))) ++error;
if (!(CompBuffer=(ULONG *)AllocMem(BPCYL,MEMF_CHIP))) ++error;
if (!(Hist=(char *)AllocMem(MHIST*MVOLNAME,PUBCLR))) ++error;
if (error) Request("Pcopy did not get","enough memory","OK","OK");
return(error);
} /* Init() */
/*
* Give it all back.
*/
void Quit()
{
CloseUser();
if (D0) CloseDrive(D0);
if (D1) CloseDrive(D1);
if (Hist) FreeMem(Hist,MHIST*MVOLNAME);
if (CopyBuffer) FreeMem(CopyBuffer,BPCYL);
if (CompBuffer) FreeMem(CompBuffer,BPCYL);
if (IntuitionBase) CloseLibrary(IntuitionBase);
}
/*
* Allocate space for the structure, inhibit DOS, setup trackdisk port
* and open trackdisk.
*/
DrInfo *OpenDrive(DrName,Unit)
char *DrName; int Unit;
{
register DrInfo *NewDr=0;
if (NewDr=(DrInfo *)AllocMem(sizeof(DrInfo),PUBCLR)){
NewDr->DevName=DrName;
NewDr->DOSInhbt=dos_packet(DeviceProc(DrName),ACTION_INHIBIT,DOSTRUE);
NewDr->Req.io_Message.mn_Node.ln_Type=NT_MESSAGE;
NewDr->Req.io_Message.mn_Node.ln_Pri=0;
if (NewDr->Req.io_Message.mn_ReplyPort=CreatePort(0,0)){
if (!(NewDr->Device=OpenDevice(TD_NAME,Unit,&NewDr->Req,1))){
}
}
}
return(NewDr);
} /* OpenDrive() */
/*
* Close trackdisk device and get rid of memory and ports involved.
*/
void CloseDrive(drive)
register DrInfo *drive;
{
if (!drive->Device){
MotorOff(drive);
CloseDevice(&drive->Req);
}
if (drive->Req.io_Message.mn_ReplyPort)
DeletePort(drive->Req.io_Message.mn_ReplyPort);
FreeMem(drive,sizeof(DrInfo));
dos_packet(DeviceProc(drive->DevName),ACTION_INHIBIT,DOSFALSE);
} /* CloseDrive */
/*
* Check if a start-copy condition occured. If so call the copy routine.
*/
void CheckCopy()
{
register DrInfo *Source, *Dest; register short DoCopy;
if (D0->Present&&D1->Present){ /* determine direction */
if (ITDr1.FrontPen==DESTCOLOR){
Source=D0;
Dest=D1;
} else{
Source=D1;
Dest=D0;
}
DoCopy=0; /* three values: FALSE/WAIT/NOWAIT */
if ((GAuto.Flags&SELECTED)&&EnAuto){
if (GUnRd.Flags&SELECTED){
if (!Dest->Readable) DoCopy=NOWAIT;
} else if (GNDOS.Flags&SELECTED){
if (!Dest->DOSBoot) DoCopy=NOWAIT;
} else DoCopy=(Dest->DOSDisk)?WAIT:NOWAIT;
} else if (GCopy.Flags&SELECTED){
GCopy.Flags&=~SELECTED;
DrawImage(WS->RPort,&IMBlnk,16,4*GGH);
RefOneGadget(&GCopy,WS,0);
DoCopy=NOWAIT;
}
if (DoCopy) DiskCopy(Source,Dest,DoCopy);
EnAuto=0;
}
}
/*
* Show disk name in Now in .. window, or clear it
*/
void ShDName(W,text)
struct Window *W; register char *text;
{
static struct IntuiText ITDiskName={ 1,0,JAM2,0,0,0,0,0 };
static struct Image IMDBlank={ 0,0,WD0-4,8,0,0,0,0,0 };
DrawImage(W->RPort,&IMDBlank,2,11);
if (text){
if (*text=='\x0e'){
ITDiskName.FrontPen=2;
++text;
} else ITDiskName.FrontPen=1;
ITDiskName.IText=text;
PrintIText(W->RPort,&ITDiskName,12,11);
}
}
/* end of pcopy.c */