/* DIGTEST.C, Gauntlet Digitizer testing program */
/* KJ Kranzusch */
/* Copyright (c) 1992 GRiD Systems Corporation, All Rights Reserved */

/* This code represents the portions of a GRiD Diagnostic program that
   was written to test the PalmPad digitizer.  It shows how to use
	the SetPointNotification call to receive control during specified
	pen states.

	THIS IS NOT A COMPLETE PROGRAM.  IMPORTANT SECTIONS HAVE BEEN REMOVED.
	
	This code is meant as a guideline for writing your own programs.

	It is imperative that you consider the processing that is allowed
	during the handler.  At a call frequency of up to 5 ms, you cannot
	perform any undue processing (no DOS, no screen I/O).  Also remember
	that you are given control unconditionally from the BIOS.  You
	must set your DS if data access is planned.

*/


typedef unsigned char BOOLEAN;
typedef unsigned short WORD;

union REGS regs;

int load_conditions=0,speed=0,threshold=0,event_mask=0;

static short savedAX[100];
static short savedBX[100];
static short savedCX[100];
static short savedDX[100];
static short bufPos = 0;
static short outPos = 0;
static short dataReady = 0;
BOOLEAN inInterceptor = FALSE;

	/****************************/
	/* CODE REMOVED FOR BREVITY */
	/****************************/

/*********************************************************/
/* USER HANDLER ROUTINE */
/*
	IMPORTANT: With a calling frequency of up to 5 ms, this
	routine MUST BE FAST!  Not allowed to do anything major
	except set a few flags or copy values into transition
	buffers.  Don't even try to do screen I/O!
*/

far interceptor (void)
{

	WORD saveDS;
	WORD codeSeg;

	saveDS = _DS;

	/* Since this was compiled in the tiny model, our code segment is our
		data segment.  Switch to our data segment so we can deposit the
		points in a buffer. */

	codeSeg = _CS;
	_DS = codeSeg;

	/* We don't have time to actually print anything, so just
	   copy the regs to a FIFO to be displayed by the main
	   routine. */

		disable();
		inInterceptor = TRUE;
		savedAX[bufPos] = saveAX;
		savedBX[bufPos] = saveBX;
		savedCX[bufPos] = _CX;
		savedDX[bufPos] = _DX;
		bufPos++;
		if (bufPos >= sizeof (savedAX) / sizeof (savedAX[0]))
		  bufPos = 0;
		dataReady++;
		enable();
		inInterceptor = FALSE;

	/* Restore DS */

	_DS = saveDS;
}


	/****************************/
	/* CODE REMOVED FOR BREVITY */
	/****************************/


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


void set_event_mask()
{

	/* Set new event mask */
	/* Safer to do this directly rather than using the regs structure
		and the int86() call in order to use _CS */

	_BX = FP_OFF(interceptor);
	_ES = _CS;						/* TINY MODEL => CS=DS */

	_AX = 0xE47B;
	_DX = 0;

	_CX = event_mask;				/* Enter matching mask here! */
	geninterrupt (0x15);

}

	/****************************/
	/* CODE REMOVED FOR BREVITY */
	/****************************/


void set_load_conditions()
{

	/* Set load conditions */
	regs.x.ax = 0xE47A;
	regs.h.dl = 0;
	regs.x.cx = 0xCC;     /* Load when down & near and during state changes */
	int86(0x15,&regs,&regs);

}

void set_speed()
{

	/* Set speed */
	regs.x.ax = 0xE46C;
	regs.h.dl = 2;
	regs.x.cx = 100;
	int86(0x15,&regs,&regs);

}

void set_threshold()
{

	/* Set threshold */
	regs.x.ax = 0xE47C;
	if (threshold != -1)
		{
		regs.h.dl = 1;
		regs.x.cx = threshold;
		}
	else
		{
		regs.h.dl = 0;
		regs.x.cx = 0;
		}
	int86(0x15,&regs,&regs);

}

void start_points()
{

	regs.x.ax = 0xE461;
	regs.x.bx = 0x0000;
	regs.x.cx = 0x0000;
	int86(0x15,&regs,&regs);

}

	/****************************/
	/* CODE REMOVED FOR BREVITY */
	/****************************/


void scroll_events()
{

	char ch;

	clrscr();

	while (!kbhit())
		{
		/* If there are points ready in the FIFO, display them!
		*/
		if (dataReady)
			{
			printf ("%04x %04x %04x %04x \n",
				savedAX[outPos],savedBX[outPos],savedCX[outPos],savedDX[outPos]);
			if (fileflag)
				fprintf (fp,"%04x %04x %04x %04x \n",
				savedAX[outPos],savedBX[outPos],savedCX[outPos],savedDX[outPos]);
			outPos++;
			if (outPos >= sizeof (savedAX) / sizeof (savedAX[0]))
				outPos = 0;
			dataReady--;
			}
		}

	ch = getchar();


}



int process_screens()
{

	/****************************/
	/* CODE REMOVED FOR BREVITY */
	/****************************/

	set_load_conditions();
	set_speed();
	set_threshold();
	set_event_mask();

	/****************************/
	/* CODE REMOVED FOR BREVITY */
	/****************************/

	scroll_events();

}



main()
{

	/****************************/
	/* CODE REMOVED FOR BREVITY */
	/****************************/

	start_points();
	while(process_screens());

}

