 #include <devices/trackdisk.h>
 #include <intuition/intuition.h>

 #define NL 0
 /********
 *		I N T U I
 \***************************/

 struct IntuiText Stat_Str = 
 	{ 1, 0, JAM2, 2, 1, NL, (UBYTE *) "       TT                ", NL};

 char *mess[] =
 {
	"   Disk operation O.K.   ",
	"    Disk WriteProtect    ",
	"    No disk in drive     ",
	"     Disk unreadable     ",
	"      Disk inserted      ",
	"       Disk removed      ",
	"    A PVL production     ",
	"   No Virus in memory    ",
	"  Disk is not installed  ",
	" Disk contains AntiVirus ",
	" Disk contains Normal BB ",
	" Disk contains Sound BB  ",
	"    Unknown BootBlock    ",
	"  Old AntiVirus on Disk  ",
	"    SCA-Virus killed     ",
	" Disk contains SCA-Virus ",
	"   ByteWarrior killed    ",
	"Disk contains ByteWarrior",
	"    ByteBandit killed    ",
	"Disk contains ByteBandit ",
	" Disk contains ABC-Virus "
 };

 /**************************************************************************\
 *	    T R A C K D I S K . D E V I C E   G L O B A L    V A R S        *
 \**************************************************************************/

 struct MsgPort *diskport;
 struct IOExtTD *diskreq;

 extern struct MsgPort *CreatePort();
 extern struct IORequest *CreateExtIO();

 extern int drive, bootblock;
 extern APTR BootBlocks[];
 extern struct Window *w;

 ULONG diskChangeCount;

int OpenDiskDevice(drivenr)
int drivenr;
{
	int error;

	if (!(diskport = CreatePort (0L, 0L)))
		return (0);
	if (!(diskreq = (struct IOExtTD *) CreateExtIO
		(diskport, (LONG) sizeof (struct IOExtTD))))
	{
		DeletePort (diskport);
		return (0);
	}
	return (!OpenDevice (TD_NAME, (LONG) drivenr, diskreq, 0L) ? 1 : 0);
}
CloseDiskDevice (flag)
int flag;	/* if flag = 1 Device is open */
{
	if (flag)
		CloseDevice (diskreq);
	DeleteExtIO (diskreq, (LONG) sizeof (struct IOExtTD));
	DeletePort (diskport);
}

void Motor (flag)
LONG flag;
{
   diskreq->iotd_Req.io_Length = flag; /* 1 = aan en 0 = uit */
   diskreq->iotd_Req.io_Command = TD_MOTOR;
   DoIO (diskreq);
}

int present=1;

void CheckDisk ()
{
	diskreq->iotd_Req.io_Command = TD_CHANGESTATE;
	DoIO (diskreq);
	if (diskreq->iotd_Req.io_Actual && present)
	{
		present = 0;
		PrintMessage (5);
	}
	if (!diskreq->iotd_Req.io_Actual && !present)
	{
		present = 1;
		PrintMessage (4);
	}
}

int ReadBootBlock()
{
	int error;
	diskreq->iotd_Req.io_Command = ETD_CLEAR;
	DoIO (diskreq);
	diskreq->iotd_Req.io_Command = TD_CHANGENUM;
	DoIO (diskreq);
	diskChangeCount = diskreq->iotd_Req.io_Actual;
	/* Motor (1L); */
	diskreq->iotd_Req.io_Length = TD_SECTOR * 2;
	diskreq->iotd_Req.io_Data = (APTR) BootBlocks[3];
	diskreq->iotd_Req.io_Command = ETD_READ;
	diskreq->iotd_Count = diskChangeCount;
	diskreq->iotd_Req.io_Offset = 0;
	DoIO (diskreq);
	if (error = DiskError())
		PrintMessage(error);
	Motor (0L);
	present = 1;	/* Dit voorkomt dat de message overschreven wordt
					 * door 'disk inserted'
					 */
	return (error);
}


int WriteBootBlock()
{
	int error;
	diskreq->iotd_Req.io_Command = ETD_CLEAR;
	DoIO (diskreq);
	diskreq->iotd_Req.io_Command = TD_CHANGENUM;
	DoIO (diskreq);
	diskChangeCount = diskreq->iotd_Req.io_Actual;
	Motor (1L);
	diskreq->iotd_Req.io_Length = TD_SECTOR * 2;
	diskreq->iotd_Req.io_Data = (APTR) BootBlocks[bootblock];
	diskreq->iotd_Req.io_Command = ETD_WRITE;
	diskreq->iotd_Count = diskChangeCount;
	diskreq->iotd_Req.io_Offset = 0;
	DoIO (diskreq);
	error = DiskError();
	present = 1;	/* Dit voorkomt dat de message overschreven wordt
					 * door 'disk inserted'
					 */
	PrintMessage(error);
	if (!error)
	{
		diskreq->iotd_Req.io_Command = CMD_UPDATE;
		DoIO (diskreq);
		error = DiskError();
		PrintMessage(error);
	}
	Motor (0L);
	return (error);
}

int DiskError()
{
	int errnum;
	switch ((char) diskreq->iotd_Req.io_Error)
	{
		case TDERR_WriteProt:
					errnum = 1;
					break;
		case TDERR_DiskChanged:
					errnum = 2;
					break;
		case TDERR_BadSecSum:
		case TDERR_BadSecHdr:
		case TDERR_NoSecHdr:
					errnum = 3;
					break;
		case default:
					errnum = 0;
					break;
	}
	return (errnum);
}

PrintMessage(errnum)
int errnum;
{
	strcpy ( Stat_Str.IText, mess[errnum]);
	PrintIText (w->RPort, &Stat_Str, 35L, 80L);
}
