home *** CD-ROM | disk | FTP | other *** search
- 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 */
-