/*************************************************************************
**   File:  serial.c
**      contains routines to read from and write to serial port
**
**   Functions:
**	init_ser() - opens and initializes serial port
**	clos_ser() - closes serial port and cleans up
**	sendchar() - sends a single character out the port
**	readchar() - waits for a character from serial port, timeout, or
**		operator abort (ESC key)
**	cond_read() - returns character from serial port if present, or
**		-1 if none available -- does not block
**	dial_str() - sends a string out the serial port
**
*************************************************************************/
#include "term.h"

/* declarations for the serial stuff */
extern struct MsgPort *CreatePort();
struct IOExtSer *Read_Request;
char rs_in[2];
struct IOExtSer *Write_Request;
char rs_out[2];

extern struct Window *mywindow;             /* ptr to applications window */
extern struct timerequest *timer;	/* for timer request */
extern int timeout;
extern USHORT abort;

init_ser()
{
	Read_Request = (struct IOExtSer *)AllocMem(sizeof(*Read_Request),MEMF_PUBLIC|MEMF_CLEAR);
	Read_Request->io_SerFlags = SERF_SHARED | SERF_XDISABLED;
	Read_Request->IOSer.io_Message.mn_ReplyPort = CreatePort("Read_RS",0);
	if(OpenDevice(SERIALNAME,NULL,Read_Request,NULL))
	{
		puts("Cant open Read device\n");
		CloseWindow( mywindow );
		DeletePort(Read_Request->IOSer.io_Message.mn_ReplyPort);
		FreeMem(Read_Request,sizeof(*Read_Request));
		exit(TRUE);
	}
	Read_Request->IOSer.io_Command = CMD_READ;
	Read_Request->IOSer.io_Length = 1;
	Read_Request->IOSer.io_Data = (APTR) &rs_in[0];

	Write_Request = (struct IOExtSer *)AllocMem(sizeof(*Write_Request),MEMF_PUBLIC|MEMF_CLEAR);
	Write_Request->io_SerFlags = SERF_SHARED | SERF_XDISABLED;
	Write_Request->IOSer.io_Message.mn_ReplyPort = CreatePort("Write_RS",0);
	if(OpenDevice(SERIALNAME,NULL,Write_Request,NULL))
	{
		puts("Cant open Write device\n");
		CloseWindow( mywindow );
		DeletePort(Write_Request->IOSer.io_Message.mn_ReplyPort);
		FreeMem(Write_Request,sizeof(*Write_Request));
		DeletePort(Read_Request->IOSer.io_Message.mn_ReplyPort);
		FreeMem(Read_Request,sizeof(*Read_Request));
		exit(TRUE);
	}
	Write_Request->IOSer.io_Command = CMD_WRITE;
	Write_Request->IOSer.io_Length = 1;
	Write_Request->IOSer.io_Data = (APTR) &rs_out[0];

	Read_Request->io_SerFlags = SERF_SHARED | SERF_XDISABLED;
	Read_Request->io_Baud = 1200;
	Read_Request->io_ReadLen = 8;
	Read_Request->io_WriteLen = 8;
	Read_Request->io_CtlChar = 1L;
	Read_Request->IOSer.io_Command = SDCMD_SETPARAMS;
	DoIO(Read_Request);
	Read_Request->IOSer.io_Command = CMD_READ;

	return(0);
}

clos_ser() 
{
	CloseDevice(Read_Request);
	DeletePort(Read_Request->IOSer.io_Message.mn_ReplyPort);
	FreeMem(Read_Request,sizeof(*Read_Request));
	CloseDevice(Write_Request);
	DeletePort(Write_Request->IOSer.io_Message.mn_ReplyPort);
	FreeMem(Write_Request,sizeof(*Write_Request));
}


/**************************************************************/
/* send char and read char functions for the xmodem function */
/************************************************************/
sendchar(ch)
unsigned char ch;
{
	rs_out[0] = ch;
	DoIO(Write_Request);
}

unsigned char readchar()
{
	unsigned char c;
	int rd,ch;

	rd = FALSE;

	while (rd == FALSE) {
		Wait((1 << Read_Request->IOSer.io_Message.mn_ReplyPort->mp_SigBit)
			| ( 1 << mywindow->UserPort->mp_SigBit)
			| (1 << timer->tr_node.io_Message.mn_ReplyPort->mp_SigBit) 
			);

		if (test_kbd_abort()) {
			emits("\n\nUser Cancelled Transfer");
			abort = 1;
			rd = TRUE;
			ch = 0;
		}

		if(CheckIO(Read_Request))
		{
			ch=rs_in[0];
			rd = TRUE;
			BeginIO(Read_Request);
		}
		else if (CheckIO(timer) && (!timer->tr_node.io_Error)) {
			timeout = TRUE;
			emits("\nTimeout Waiting For Character\n");
			return(-1);
		}
	}
		c = ch;
		return(c);
}


cond_read()			/* Read a character from the comm port.
    				   Returns -1 if no character available */
{
	unsigned char ch;

	if(CheckIO(Read_Request))
	{
		ch=rs_in[0];
		BeginIO(Read_Request);
		return((int) ch);
	}
	return(-1);
}

dial_str(str)
	char *str;
{
	int i;
	for (i=0;str[i];i++) {
		rs_out[0] = (str[i] & 0x7f);
		DoIO(Write_Request);
		Wait(1 << Read_Request->IOSer.io_Message.mn_ReplyPort->mp_SigBit);
		if (CheckIO(Read_Request)) {
			WaitIO(Read_Request);
			emit(rs_in[0]&0x7f);
			BeginIO(Read_Request);
		}
	}
	return(0);
}


