/*
**	SPTIMER.C
**
**	James L. Bates
**	Batech Corporation
**	c/o Cogitate, Inc.
**	24000 Telegraph
**	Southfield, MI 48034
**
**	Signal Process Timer
**	+  Using RS232 serial interface control/status lines
**	+  Use DTR/DSR for outside timing envelope trigger
**	+  Use Keyboard to supplement outside timing envelope trigger
**
*/

#include <stdio.h>
#include <conio.h>

unsigned long	c_off;
unsigned long	c_total;
unsigned long	elapsed_time;
unsigned long	elapsed_seconds;

/*  Attempt to normalize the two numbers to integers */
unsigned int CommonDenominate(on,id)
unsigned long	on;
unsigned int	id;
{
	unsigned long	e_on, e_off, ls_on, ls_off;
	unsigned int	p_on, p_off, p_total;

	/*  Round c_on and c_c_off to reasonable levels	*/
	c_off  = c_total - on;
	ls_on  = on;
	ls_off = c_off;
	while (1)
	{
		if (on == 0l)
		{	if (c_off == 0l)
			{	c_off = 1l;
			     	on    = 1l;
				break;		/* both zero */
			}
			c_off = 1l;
		     	on    = 0l;
			break;
		}
		if (c_off == 0l)
		{	on    = 1l;
			break;
		}
		while ( on > 10000 || c_off > 10000 )
		{
			on++;
			on >>= 1;
			if (on == 0l)
				on = 1l;
			c_off++;
			c_off >>= 1;
			if (c_off == 0l)
				c_off = 1l;
		}
		break;
	}
	p_total = (int)(on + c_off);
	p_on    = (int)((on *10000)/(long)p_total);
	p_off   = (int)((c_off*10000)/(long)p_total);

	e_on  = (( elapsed_time * on    ) * 55 ) / (long)p_total;
	e_off = (( elapsed_time * c_off ) * 55 ) / (long)p_total;
	printf("%d %4ld.%03ld %3d.%02d%% %4ld.%03ld %3d.%02d%% %4ld.%03ld\n",
		id,
		e_on/1000,e_on%1000,
		p_on/100,p_on%100,
		e_off/1000,e_off%1000,
		p_off/100,p_off%100,
		elapsed_seconds/1000,elapsed_seconds%1000 );
	return (int)on;
}


main()
{
	unsigned int	addr;		/* async comm port address */
	unsigned int	val;		/* async comm port buffer  */
	unsigned int	kb_env;		/* keyboard timing envelope */
	unsigned long	c_on1;
	unsigned long	start_time, stop_time;

	addr	= 0x03fe;

	printf("SPTIMER - Signal Processing Timer...\n");
	printf("....press any data key to start/stop\n");
	printf("    or wait for DSR trigger signal...\n");

	c_on1 = 0l;
	c_off = 0l;
	/*  Wait for Outside Timing Envelope Trigger    */	
	kb_env = 1;		/* initialize to kb timing envelope */
	while (!kbhit())
	{	_asm
	 	{     	mov	dx,addr	; comm port address
	 		xor	ax,ax	; clear for int val
	 		in	al,dx	; read the modem status
	 		mov	val,ax	; save the status value
	 	}
	 	if ( val & 0x20 )	/* DSR raised high?	*/
		{	kb_env = 0;	/* DSR timing envelope  */
			break;		/* exit the while loop	*/
		}
	}
	/*  if triggered by keyboard and not DSR
	**		read the kb character
	*/
	if (!(val&0x20))		/* if DSR not raised high 	  */
		getch();		/* then we must have a kb trigger */
	/*
	**	the following puts is for visual confirmation only.
	**	It lets us know that our triggers are working, but
	**	it may also skew the timing somewhat, since putting
	**	these characters to the screen may take time.
	**	Remove for more accurate timings.
	*/
	puts("..timing..");		/* this may skew timing		  */

	get_time(&start_time);
#include "sp1.inc"
	get_time(&stop_time);
	/*  if terminated by keyboard and not DSR
	**		read the kb character	*/
	if (kbhit())
		getch();
	/*  Outside Timing Envelope Complete    */
	c_total = c_on1 + c_off;
	elapsed_time = stop_time - start_time;
	elapsed_seconds = (elapsed_time*55);

	printf("start:%ld stop:%ld  elapsed:%ld\n",
		start_time,stop_time,elapsed_time);
	printf("on:%ld off:%ld total %ld\n",
		c_on1, c_off, c_total );

	printf("  -------ON------- -------OFF------  -TOTAL-\n");
	printf("#  seconds percent  seconds percent  seconds\n");
	CommonDenominate(c_on1,1);
}

get_time(time)
long	*time;
{
	_asm
	{	push	es
		mov	bx,time
		mov	ax,040h
		mov	es,ax
		mov	ax,es:[06ch]
		mov	0[bx],ax
		mov	ax,es:[06eh]
		mov	2[bx],ax
		pop	es
	}
}

