
 /***************************************************************************
 *Rolf Schneider | Am Birkenwaeldchen 16/18 | 58 Hagen 7 | Tel.: 02331/45569*
 *                                                                          *
 *                      First Amiga Artists Program:                        *
 *                                                                          *
 *                          -- Artist's Copy I --                           *
 *AC6                                                                       *
 ***************************************************************************/

 /***** Includes ***********************************************************/

#include "exec/types.h"
#include "exec/nodes.h"
#include "exec/lists.h"
#include "exec/memory.h"
#include "exec/interrupts.h"
#include "exec/ports.h"
#include "exec/libraries.h"
#include "exec/io.h"
#include "exec/tasks.h"
#include "exec/execbase.h"
#include "exec/devices.h"
#include "devices/trackdisk.h"
#include "intuition/intuition.h"



typedef char FN[108];
typedef char FName[32];
extern FName Dst[200],*pDst,help;
extern FN NDst;
extern UBYTE stDst[200];
extern short zDst;




struct MsgPort *dp1,*dp2;
struct IOExtTD *dr1,*dr2;

extern struct MsgPort *CreatePort();
extern struct IORequest *CreateExtIO();
extern short SDfn,DDfn;

int TDinit()
{
int i;

dp1 = CreatePort (0,0);
dp2 = CreatePort (0,0);

dr1 = (struct IOExtTD *)CreateExtIO (dp1,sizeof(struct IOExtTD));
dr2 = (struct IOExtTD *)CreateExtIO (dp2,sizeof(struct IOExtTD));

for (i=0;i<=3;i++)
	{
	if (OpenDevice(TD_NAME,i,dr1,0)!=0) break;
	CloseDevice (dr1);
	}
return (i);
}


int TDcheck()
{
int i,ch=0,h;

for (i=1;i<=2;++i)
	{
	if (i==1) h=SDfn;
	else      h=DDfn;
	if (h==4) goto la10;
	OpenDevice (TD_NAME,h,dr1,0);
	dr1->iotd_Req.io_Command = TD_CHANGESTATE;
	DoIO(dr1);
	if (dr1->iotd_Req.io_Actual == 255) ch=ch+i;
	CloseDevice (dr1);
la10:   }
return (ch);
}



KillTD ()
{
DeleteExtIO(dr1,sizeof(struct IOExtTD));
DeletePort(dp1);
DeleteExtIO(dr2,sizeof(struct IOExtTD));
DeletePort(dp2);
}






/*************************************************************************/
/**    Help-functions....                                               **/
/**                                                                     **/
/*************************************************************************/


extern APTR AllocMem();

struct IORequest *CreateExtIO(ioReplyPort,size)
    struct MsgPort *ioReplyPort;
    LONG size;
{
    struct IORequest *ioReq;

    if (ioReplyPort == 0)
	return ((struct IORequest   *) 0);

    ioReq = (struct IORequest *)AllocMem (size, MEMF_CLEAR | MEMF_PUBLIC);

    if (ioReq == 0)
	return ((struct IORequest   *) 0);

    ioReq -> io_Message.mn_Node.ln_Type = NT_MESSAGE;
    ioReq -> io_Message.mn_Node.ln_Pri = 0;

    ioReq -> io_Message.mn_ReplyPort = ioReplyPort;

    return (ioReq);
}



DeleteExtIO(ioExt,size)
    struct IORequest *ioExt;
    LONG size;
{
    ioExt -> io_Message.mn_Node.ln_Type = 0xff;
    ioExt -> io_Device = (struct Device *) -1;
    ioExt -> io_Unit = (struct Unit *) -1;

    FreeMem (ioExt, size);
}
 

 /**************************************************************************
 *									   *
 * DiskCopy...								   *
 *									   *
 **************************************************************************/


struct Gadget G2 = {                  /* CANCEL */
	NULL,87,38,51,9,
	GADGHCOMP,
	RELVERIFY,
	BOOLGADGET,
	NULL,
	NULL,
	NULL,
	0,
	NULL,
	0,
	NULL };

struct Gadget G1 = {                   /* OK */
	&G2,49,38,19,9,
	GADGHCOMP,
	RELVERIFY,
	BOOLGADGET,
	NULL,
	NULL,
	NULL,
	0,
	NULL,
	0,
	NULL };

struct NewWindow DCNW = {
	230,60,180,80,1,2,
	DISKREMOVED|DISKINSERTED|GADGETUP,
	GIMMEZEROZERO|SIMPLE_REFRESH|ACTIVATE,
	&G1,
	NULL,
	" DiskCopy:",
	NULL,
	NULL,
	180,80,180,80,
	WBENCHSCREEN };

struct IntuiMessage *mdl;
struct Window   *DCW;
struct RastPort *DCR;

int d1ch,d2ch; 

extern struct Window *OpenWindow ();
extern UBYTE buf [11264];


DiskCopy ()
{
int i,z=9,offset;

if ((SDfn == DDfn)||(SDfn == 4)||(DDfn ==4)) return(0);
if (INNI() == 1) return (0);

     /****** MOTORS on ******/

dr1 -> iotd_Req.io_Length = 1;
dr1 -> iotd_Req.io_Command = TD_MOTOR;
DoIO (dr1);
dr2 -> iotd_Req.io_Length = 1;
dr2 -> iotd_Req.io_Command = TD_MOTOR;
DoIO (dr2);

    /****** COPY 'IT' ******/

SetAPen (DCR,3);

for (i=0;i<=79;++i)
	{
	offset = TD_SECTOR*(NUMSECS*NUMHEADS*i);

	dr1 -> iotd_Req.io_Data = (APTR)buf;
	dr1 -> iotd_Req.io_Command = ETD_READ;
	dr1 -> iotd_Req.io_Length = 11264;
	dr1 -> iotd_Req.io_Offset = offset;
	dr1 -> iotd_Count = d1ch;
	DoIO (dr1);
	if (dr1->iotd_Req.io_Error !=0) SetAPen(DCR,2);
	else				SetAPen(DCR,3);
	Move (DCR,z,16); Draw (DCR,z,27);
	Move (DCR,z+1,16); Draw (DCR,z+1,27);

	dr2 -> iotd_Req.io_Length = 11264;
	dr2 -> iotd_Req.io_Command = ETD_FORMAT;
	dr2 -> iotd_Req.io_Data = (APTR)buf;
	dr2 -> iotd_Req.io_Offset = offset;
	dr2 -> iotd_Count = d2ch;
	DoIO (dr2);
	SetAPen(DCR,0);
	Move (DCR,z,49); Draw (DCR,z,60);
	Move (DCR,z+1,49); Draw (DCR,z+1,60);

	dr2 -> iotd_Req.io_Length = 11264;
	dr2 -> iotd_Req.io_Command = ETD_WRITE;
	dr2 -> iotd_Req.io_Data = (APTR)buf;
	dr2 -> iotd_Req.io_Offset = offset;
	dr2 -> iotd_Count = d2ch;
	DoIO (dr2);
	if (dr2->iotd_Req.io_Error !=0) SetAPen(DCR,2);
	else				SetAPen(DCR,3);
	Move (DCR,z,49); Draw (DCR,z,60);
	Move (DCR,z+1,49); Draw (DCR,z+1,60);
	z=z+2;
	}

     /****** MOTORS off ******/

dr1 -> iotd_Req.io_Length = 0;
dr1 -> iotd_Req.io_Command = TD_MOTOR;
DoIO (dr1);
dr2 -> iotd_Req.io_Length = 0;
dr2 -> iotd_Req.io_Command = TD_MOTOR;
DoIO (dr2);
CloseDevice (dr1);
CloseDevice (dr2);
SetAPen (DCR,1);
RectFill (DCR,0,0,180,180);
SetAPen (DCR,2);
Move (DCR, 2,29); Text (DCR,"Please remove destin.",21);
Move (DCR,61,45); Text (DCR,"DISK !",6);
i=0;
for (;i<1;)
	{
	Wait(1<<DCW->UserPort->mp_SigBit);
	while(mdl = (struct IntuiMessage *) GetMsg (DCW->UserPort))
		{
		if ((mdl->Class == DISKREMOVED) && ((TDcheck() & 2) != 0)) i=1;
		ReplyMsg (mdl);
		}
	}
SetAPen (DCR,1);
RectFill (DCR,0,0,180,180);
SetAPen (DCR,2);
Move (DCR,13,29); Text (DCR,"Please insert next",18);
Move (DCR,33,45); Text (DCR,"desti. DISK !",13);
i=0;
for (;i<1;)
	{
	Wait(1<<DCW->UserPort->mp_SigBit);
	while(mdl = (struct IntuiMessage *) GetMsg (DCW->UserPort))
		{
		if ((mdl->Class == DISKINSERTED) && ((TDcheck() & 2) == 0)) i=1;
		ReplyMsg (mdl);
		}
	}

zDst = Dir (NDst,&Dst[0],stDst,1,help);
CloseWindow (DCW);
}


int INNI ()
{
int kane;

DCW = OpenWindow (&DCNW);
DCR = DCW -> RPort;
SetAPen (DCR,1);
RectFill (DCR,0,0,180,80);
SetAPen (DCR,2);
SetBPen (DCR,1);
SetDrMd (DCR,JAM2);

Move (DCR,13,28); Text (DCR,"Insert both DISKS!",18);
Move (DCR,50,45); Text (DCR,"OK",2);
Move (DCR,88,45); Text (DCR,"CANCEL",6);
kane = 0;
for (;kane<1;)
	{
	Wait(1<<DCW->UserPort->mp_SigBit);
	while (mdl = (struct IntuiMessage *) GetMsg (DCW->UserPort))
		{
		if (mdl->Class == GADGETUP)
			{
			if (mdl->IAddress == (APTR)&G1) kane=1;
			if (mdl->IAddress == (APTR)&G2) kane=2;
			}
		ReplyMsg (mdl);
		}
	}
if (kane == 2) { CloseWindow (DCW); return (1); }
RemoveGadget (DCW,&G1);
RemoveGadget (DCW,&G2);
SetAPen (DCR,1);
RectFill (DCR,0,0,180,80);
SetAPen (DCR,2);
Move (DCR,  8, 2); Draw (DCR,  8,64);
Move (DCR,169, 2); Draw (DCR,169,64);
Move (DCR,  0,33); Draw (DCR,171,33);
Move (DCR, 11,12); Text (DCR,"Source:", 7);
Move (DCR, 11,45); Text (DCR,"Destination:",12);
OpenDevice (TD_NAME,SDfn,dr1,0);
OpenDevice (TD_NAME,DDfn,dr2,0);
dr1 -> iotd_Req.io_Command = TD_CHANGENUM;
DoIO (dr1);
d1ch = dr1 -> iotd_Req.io_Actual;
dr2 -> iotd_Req.io_Command = TD_CHANGENUM;
DoIO (dr2);
d2ch = dr2 -> iotd_Req.io_Actual;
return (0);
}


KILLINNI ()
{
CloseDevice (dr1);
CloseDevice (dr2);
Delay (50);
CloseWindow (DCW);
}

