/*-=-=-=-=-=-=-=-=-=-=-=- RCCL/RCI Notice of Copyright -=-=-=-=-=-=-=-=-=-=-*
 *									    *
 *	Copyright (C) 1987, 1991 by John E. Lloyd.			    *
 *									    *
 *	Information on copyright permissions, as well as a complete	    *
 *	disclaimer of warranty, is given in the file COPYRIGHT.		    *
 *									    *
 *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/

#include "../h/IOdevice.h"
#include "../h/cdefs.h"
#include "../h/rciTask.h"
#include "../h/rciMacros.h"

#include "driverTest.h"

static TEST_BLOCK *tblk;

#define GET_TEST_BLOCK() 					\
	if (!(tblk = (TEST_BLOCK*)getMemByName("TESTBLOCK")))	\
	 { rciAbort (0, "can't get test block\n");  		\
	 }

doprobe (td)
RCI_DESC *td;
{
	IO_DEVICE *dev = TASKDEV(td);
	int status;

	GET_TEST_BLOCK();
	status = (*dev->probe)(dev);
	if (status < 0)
	 { dev->error = getErrorCode(0);
	   rciPrintErrors();
	 }
	return (status);

}

doattach (td)
RCI_DESC *td;
{
	IO_DEVICE *dev = TASKDEV(td);
	int status;

	GET_TEST_BLOCK();
	status = (*dev->attach)(dev);
	if (status < 0)
	 { dev->error = getErrorCode(0);
	   rciPrintErrors();
	 }
	return (status);
}

dodetach (td)
RCI_DESC *td;
{
	IO_DEVICE *dev = TASKDEV(td);
	int status;

	GET_TEST_BLOCK();
	status = (*dev->detach)(dev);
	if (status < 0)
	 { dev->error = getErrorCode(0);
	   rciPrintErrors();
	 }
	return (status);
}

dosignal (td)
RCI_DESC *td;
{
	IO_DEVICE *dev = TASKDEV(td);
	int status;

	GET_TEST_BLOCK();
	status = (*dev->signal)(dev, tblk->signalNum);
	if (status < 0)
	 { dev->error = getErrorCode(0);
	   rciPrintErrors();
	 }
	return (status);
}

dotestRead (td)
RCI_DESC *td;
{
	IO_DEVICE *dev = TASKDEV(td);

	GET_TEST_BLOCK();
	return ((*dev->testRead)(dev));
}

dotestWrite (td)
RCI_DESC *td;
{
	IO_DEVICE *dev = TASKDEV(td);

	GET_TEST_BLOCK();
	return ((*dev->testWrite)(dev));
}

doread (td)
RCI_DESC *td;
{
	IO_DEVICE *dev = TASKDEV(td);
	int status;

	GET_TEST_BLOCK();
	status = (*dev->read)(dev, tblk->readBuf, BUFSIZE);
	if (status < 0)
	 { dev->error = getErrorCode(0);
	   rciPrintErrors();
	 }
	return (status);
}

dowrite (td)
RCI_DESC *td;
{
	IO_DEVICE *dev = TASKDEV(td);
	int status;

	GET_TEST_BLOCK();
	status = (*dev->write)(dev, tblk->writeBuf, tblk->writeSize);
	if (status < 0)
	 { dev->error = getErrorCode(0);
	   rciPrintErrors();
	 }
	return (status);
}

doioctl (td)
RCI_DESC *td;
{
	IO_DEVICE *dev = TASKDEV(td);
	int status;

	GET_TEST_BLOCK();
	status = (*dev->ioctl)(dev, tblk->ioctlCom, tblk->ioctlBuf);
	if (status < 0)
	 { dev->error = getErrorCode(0);
	   rciPrintErrors();
	 }
	return (status);
}

doexamine (td)
RCI_DESC *td;
{
	IO_DEVICE *dev = TASKDEV(td);
	int size = dev->size;

	GET_TEST_BLOCK();
	if (((int)dev->location % 2 == 0) && (dev->size % 2 == 0))
	 { int k;
	   int numWords = dev->size/2;
	   unsigned short *regs = (unsigned short *)(dev->location);

	   for (k=0; k<numWords; k++)
	    { tblk->peekBuf[k] = regs[k];
	    }
	 }
	else
	 { bcopy (dev->location, tblk->peekBuf, tblk->deviceSize); /* punt */
	 }
	return (1);
}

dopoke (td)
RCI_DESC *td;
{
	IO_DEVICE *dev = TASKDEV(td);
	unsigned short *p = (unsigned short *)(dev->location);

	GET_TEST_BLOCK();
	p[tblk->pokeIndex] = tblk->pokeBuf;	
	return (1);
}

dopeek (td)
RCI_DESC *td;
{
	IO_DEVICE *dev = TASKDEV(td);
	unsigned short *p = (unsigned short *)(dev->location);

	GET_TEST_BLOCK();
	tblk->peekBuf[0] = p[tblk->peekIndex];
	return (1);
}

dopulse (td)
RCI_DESC *td;
{
	IO_DEVICE *dev = TASKDEV(td);
	int i;
	unsigned short *p = (unsigned short *)(dev->location);

	GET_TEST_BLOCK();
	p[tblk->pulseIndex] |= tblk->pulseBuf;
	for (i=0; i<1000; i++)
	   ;
	p[tblk->pulseIndex] &= ~tblk->pulseBuf;	
	return (1);
}

cycleReadWrite(td)
RCI_DESC *td;
{
	IO_DEVICE *dev = TASKDEV(td);
	int count;

	(*dev->signal)(dev, 1);

	if ((count = (*dev->read)(dev, tblk->readBuf, BUFSIZE)) < 0)
	 { rciAbortErrors();
	   return (-1);
	 }
	if ((*dev->write)(dev, tblk->readBuf, count) < 0)
	 { rciAbortErrors();
	   return (-1);
	 }
	return (0);
}
