/*******************************************************************************
                         _                 ____    ___
                        / \      |        |           |
                       /___\     |        |--      ---
                      /     \ o  |____ o  |  o    |___

                            Amiga Loads Faster 2

                      §name:DebugDevice§
                      §date:04 Aug 1989§
                      §time:16:04:03§

              copyright 1989 Elaborate Bytes, Oliver Kastl
                  software design by Andreas Hofbauer

This program makes extensive tests of a given device. The test protocol asks for
the following i/o commands:

	CMD_START                   start unit
	TD_MOTOR                    switch motor on

	TD_CHANGESTATE              unit ready?
	TD_CHANGENUM                initial counter
	TD_PROTSTATUS               unit write protected?
	TD_GETDRIVETYPE             what unit?
	TD_GETNUMTRACKS             how big?

	CMD_READ                    read some blocks
	TD_FORMAT                   push them out again
	CMD_FLUSH                   ?
	CMD_WRITE                   write them out
	CMD_UPDATE                  be sure buffers are out
	CMD_CLEAR                   kill buffers

	TD_CHANGENUM                how often did you change disk
	TD_MOTOR                    switch motor off
	CMD_STOP                    stop unit

The following commands are not tested yet, but may be in the future.

	CMD_INVALID                 obvious
	CMD_RESET                   not sure 'bout
	TD_SEEK                     move heads
	TD_REMOVE                   jam remove irq vector
	TD_ADDCHANGEINT             properly add irq vector
	TD_REMCHANGEINT             unlink it again

	TD_RAWREAD                  reject this
	TD_RAWWRITE                 reject this
	ETD_#?                      reject these

The command HD_SCSICMD is extensively tested with the program DebugSCSI, so we
don't test it here.

	WARNING: RUNNING THIS TEST WILL DESTROY ANY DATA ON THE UNIT YOU RUN THIS
	         TEST WITH. THIS TEST IS ONLY MEANT FOR DEBUGGING PURPOSES!

It is linked together with precompiled (Amiga.pre) includes.

*******************************************************************************/

extern int Enable_Abort;
void _wb_parse() {}

void _abort()
	{
	extern void exitmain();

	printf("^C\n");
	exitmain(5);
	}

/******************************************************************************/

static struct MsgPort *MsgPort = NULL;
static struct IOStdReq *IOStdReq = NULL;
static long DeviceError = -1;
static char ReadWriteBuffer[5632]; /* 1 track @ 11 blocks */

/******************************************************************************/

static long QuickIO(iOStdReq)
	struct IOStdReq *iOStdReq;
	{
	extern long DoIO();
	long error;

	error = DoIO(iOStdReq);
	if (error) printf("\033[33m io_Error \033[31m= %ld\n", error);

	return error;
	}


/******************************************************************************/

static void DoAllTests(iOStdReq)
	struct IOStdReq *iOStdReq;
	{
	long error;

	printf("---------------- CMD_START -------------------------------------\n");
	iOStdReq->io_Command = CMD_START;
	error = QuickIO(iOStdReq);

	printf("---------------- TD_MOTOR on -----------------------------------\n");
	iOStdReq->io_Command = TD_MOTOR;
	iOStdReq->io_Length = 1;
	error = QuickIO(iOStdReq);
	printf("io_Actual = %ld\n", iOStdReq->io_Actual);

	printf("---------------- TD_CHANGESTATE --------------------------------\n");
	iOStdReq->io_Command = TD_CHANGESTATE;
	error = QuickIO(iOStdReq);
	printf("io_Actual = %ld\n", iOStdReq->io_Actual);

	printf("---------------- TD_CHANGENUM ----------------------------------\n");
	iOStdReq->io_Command = TD_CHANGENUM;
	error = QuickIO(iOStdReq);
	printf("io_Actual = %ld\n", iOStdReq->io_Actual);

	printf("---------------- TD_PROTSTATUS ---------------------------------\n");
	iOStdReq->io_Command = TD_PROTSTATUS;
	error = QuickIO(iOStdReq);
	printf("io_Actual = %ld\n", iOStdReq->io_Actual);

	printf("---------------- TD_GETDRIVETYPE -------------------------------\n");
	iOStdReq->io_Command = TD_GETDRIVETYPE;
	error = QuickIO(iOStdReq);
	printf("io_Actual = %ld\n", iOStdReq->io_Actual);

 	printf("---------------- TD_GETNUMTRACKS -------------------------------\n");
	iOStdReq->io_Command = TD_GETNUMTRACKS;
	error = QuickIO(iOStdReq);
	printf("io_Actual = %ld\n", iOStdReq->io_Actual);

	printf("---------------- CMD_READ --------------------------------------\n");
	iOStdReq->io_Command = CMD_READ;
	iOStdReq->io_Length = sizeof(ReadWriteBuffer);
	iOStdReq->io_Data = (APTR)ReadWriteBuffer;
	iOStdReq->io_Offset = 0;
	error = QuickIO(iOStdReq);
	printf("io_Actual = %ld\n", iOStdReq->io_Actual);

	printf("---------------- TD_FORMAT -------------------------------------\n");
	iOStdReq->io_Command = TD_FORMAT;
	iOStdReq->io_Length = sizeof(ReadWriteBuffer);
	iOStdReq->io_Data = (APTR)ReadWriteBuffer;
	iOStdReq->io_Offset = 0;
	error = QuickIO(iOStdReq);
	printf("io_Actual = %ld\n", iOStdReq->io_Actual);

	printf("---------------- CMD_FLUSH -------------------------------------\n");
	iOStdReq->io_Command = CMD_FLUSH;
	error = QuickIO(iOStdReq);

	printf("---------------- CMD_WRITE -------------------------------------\n");
	iOStdReq->io_Command = CMD_WRITE;
	iOStdReq->io_Length = sizeof(ReadWriteBuffer);
	iOStdReq->io_Data = (APTR)ReadWriteBuffer;
	iOStdReq->io_Offset = 0;
	error = QuickIO(iOStdReq);
	printf("io_Actual = %ld\n", iOStdReq->io_Actual);

	printf("---------------- CMD_UPDATE ------------------------------------\n");
	iOStdReq->io_Command = CMD_UPDATE;
	error = QuickIO(iOStdReq);

	printf("---------------- CMD_CLEAR -------------------------------------\n");
	iOStdReq->io_Command = CMD_CLEAR;
	error = QuickIO(iOStdReq);

	printf("---------------- TD_CHANGENUM ----------------------------------\n");
	iOStdReq->io_Command = TD_CHANGENUM;
	error = QuickIO(iOStdReq);
	printf("io_Actual = %ld\n", iOStdReq->io_Actual);

	printf("---------------- TD_MOTOR off ----------------------------------\n");
	iOStdReq->io_Command = TD_MOTOR;
	iOStdReq->io_Length = 0;
	error = QuickIO(iOStdReq);
	printf("io_Actual = %ld\n", iOStdReq->io_Actual);

	printf("---------------- CMD_STOP --------------------------------------\n");
	iOStdReq->io_Command = CMD_STOP;
	error = QuickIO(iOStdReq);
	}


/******************************************************************************/

static void exitmain(rc)
	int rc;
	{
	extern void CloseDevice();
	extern void DeleteStdIO();
	extern void DeletePort();

	if (DeviceError == 0) CloseDevice(IOStdReq);
	if (IOStdReq) DeleteStdIO(IOStdReq);
	if (MsgPort) DeletePort(MsgPort);
	exit(rc);
	}


/******************************************************************************/

main(argc, argv)
	int argc;
	char *argv[];
	{
	extern struct MsgPort *CreatePort();
	extern struct IOStdReq *CreateStdIO();
	extern long atol();
	extern long OpenDevice();

	Enable_Abort = 1; /* turn on CTRL-C */

	printf("\f\033[33;1mDebugDevice\033[31;0m copyright 1989 Elaborate Bytes, Oliver Kastl\n");
	printf("\n");
	printf("WARNING: RUNNING THIS TEST WILL DESTROY ANY DATA ON THE UNIT\n");
	printf("         YOU RUN THIS TEST WITH. THIS TEST IS ONLY MEANT FOR\n");
	printf("         DEBUGGING PURPOSES!\n");
	printf("\n");

	if (argc != 3)
		{
		printf("USAGE: DebugDevice <device> <unit>\n");
		exitmain(5);
		}

	MsgPort = CreatePort(NULL, 0L);
	if (MsgPort == NULL)
		{
		printf("ERROR: Failed creating a message port!\n");
		exitmain(20);
		}

	IOStdReq = CreateStdIO(MsgPort);
	if (IOStdReq == NULL)
		{
		printf("ERROR: Failed creating a standard I/O request!\n");
		exitmain(20);
		}

	DeviceError = OpenDevice(argv[1], atol(argv[2]), IOStdReq, 0L);
	if (DeviceError)
		{
		printf("ERROR: Failed opening device!\n");
		printf("       device = \"%s\"\n", argv[1]);
		printf("         unit = %ld\n", atol(argv[2]));
		printf("        error = %ld\n", DeviceError);
		exitmain(20);
		}

	DoAllTests(IOStdReq);

	printf("\nAll tests completed!\n");
	exitmain(0);
	}
