/*
 *	Sio.c
 *	Created: 27Jun87 by J.A. Lydiatt
 *
 *	Amiga Serial I/O Library
 *
 *	$Id: sio.c,v 1.2 90/01/16 10:27:26 crash Exp Locker: crash $
 */

#ifndef lint
static char RCSid[] = "$Id: sio.c,v 1.2 90/01/16 10:27:26 crash Exp Locker: crash $";
#endif /* lint */

#include <stdio.h>
#ifndef TRUE
#  define TRUE -1
#  define FALSE 0
#endif

/*--- Timer Function Declarations --- */

extern void CloseTimer();	/* Return Timer's resources to the System */
extern int  OpenTimer(); 	/* Returns True if Timer Device Opened OK */ 
extern void StartTimer();	/* (long)seconds, (long)microseconds      */
extern int  TimerExpired();     /* Returns True if Timer interval expired */

/*--- SerialIO Function Declarations --- */

extern struct EOExtSer *InitSerialIO(); /* problems? return NULL	  */
extern void CloseSerialIO();		/* Return SerialIO resources	  */
extern int  CheckSerIO();		/* TRUE if character available    */
extern char SerIORead();		/* Returns a Char from serial port*/
extern void SerIOWrite(); 		/* Writes one byte to serial port */ 
extern void SetSerBaud();		/* (int)baud - set baud rate	  */

/*--------------------------------------------------------------*/
/*	 getspeed/getbaud: check for valid baud parameters	*/
/*--------------------------------------------------------------*/

static struct {
	unsigned baudr;
	int speedcode;

} speeds[] = {
	300,	300,
	1200,	1200,
	2400,	2400,
	4800,	4800,
	9600,	9600,
	19200, 19200,
	0,
};

static unsigned getspeed(code)
{
	register n;

	for (n=0; speeds[n].baudr; ++n)
		if (speeds[n].speedcode == code)
			return speeds[n].baudr;
	return 0;
}


static unsigned getbaud(code)
char *code;
{
	register n;
	register int Baudrate;
	
	Baudrate = atoi(code);
	
	for (n=0; speeds[n].baudr; ++n)
		if (speeds[n].baudr == Baudrate)
			return speeds[n].speedcode;
	return 0;
}

void ssendbrk(cnt)
int cnt;
{
	SerIOBreak(cnt * 250000L);
}

/*--------------------------------------------------------------*/
/*	SIOInit: initialize serial I/O				*/
/*--------------------------------------------------------------*/


SIOInit ( whichport, speed )
char * whichport;
char * speed;
{
	unsigned int baud;
	extern void SetXonMode();

	/*  fprintf( stderr, "sioinit %s %s\n", whichport, speed ); /* */

	if ( InitSerialIO() == NULL ) {
		fprintf( stderr, "Can't open Serial Port\n" );
		return( -1 );
	}

     if ( baud = getbaud( speed ) )
	SetSerBaud( baud );

     if ( !OpenTimer() )
	{
	   CloseSerialIO();
	   fprintf( stderr, "Can't open the Timer Device\n" );
	   return -1;
        }

     SetXonMode( (int)FALSE );
     return( 0 );
}

/*--------------------------------------------------------------*/
/*	SIOSpeed:  set the serial Baud rate 			*/
/*--------------------------------------------------------------*/

SIOSpeed( speed )
char *speed;
{
    unsigned int baud;

    if (baud = getbaud( speed ))
		SetSerBaud( baud );
}

/*--------------------------------------------------------------*/
/*	SIOInBuffer/ SIOOutBuffer:	Set Buffer Size.	*/
/*--------------------------------------------------------------*/

SIOInBuffer ( buf, size )
char * buf;
int size;
{
}

SIOOutBuffer ( buf, size )
char * buf;
int size;
{
}

/*--------------------------------------------------------------*/
/*	SIOClose:	Close Serial port.			*/
/*--------------------------------------------------------------*/

SIOClose ( dtr )
{
   CloseSerialIO();
   CloseTimer();
}

/*--------------------------------------------------------------*/
/*	SIOWrite: send count characters to serial port		*/
/*--------------------------------------------------------------*/

SIOWrite ( buf, count )
register char * buf;
int count;
{
	register int nsent;
	char *prt();

	nsent = count;
	while ( nsent-- )
	   SerIOWrite( *buf++ );

	return count;
}

/*--------------------------------------------------------------*/
/*	SIORead: read mincount <= #characters <= maxcount	*/
/*	return  # of characters read, or -1 if timed out after	*/
/*	after tenths / 10 seconds.				*/
/*--------------------------------------------------------------*/


int SIORead ( buf, mincount, maxcount, tenths )
register char *buf;
int	mincount;
int	maxcount;
int	tenths; /* timeout is in tenth's of seconds */
{
        /* A bit of a Kludge to get the project started */

	long seconds, microSeconds;
	unsigned long waitMask;
	int  timerON ;
	register int received;

#if 0
	fprintf (stderr, "Read  m= %d T= %ld", maxcount, Ticks  );
#endif
	if ( tenths == 0 ) {
		if (!CheckSerIO()) return -1;
		tenths = 10;
	}
	seconds = tenths / 10;
	microSeconds = ((long)(tenths) - seconds * 10L) * 100000L;

	received = 0;
	waitMask = (1L << GetSerialSigBit()) | (1L << GetTimerSigBit() ); 
	timerON = FALSE;
	do {
	    if ( CheckSerIO() ) {
			*buf++ = SerIORead();
			received++;
			if ( mincount <= received && received <= maxcount )
				return received;
		}
	    if ( !timerON ) {
			StartTimer( seconds, microSeconds );
			timerON = TRUE;
		}
	    Wait( waitMask );
	} while ( !TimerExpired() );
	return -1;
}
