/******************************************************************************\
**	TUSimpleTermDrvrPatch.c			Persistor CF2 TPU UART Simple Terminal example
**	
**	Release:		2002/01/20
*****************************************************************************
**	
**	COPYRIGHT (C) 1995-2002 PERSISTOR INSTRUMENTS INC., ALL RIGHTS RESERVED
**	
**	Developed by: John H. Godley for Persistor Instruments Inc.
**	254-J Shore Road, Bourne, MA 02532  USA
**	jhgodley@persistor.com - http://www.persistor.com
**	
**	Copyright (C) 1995-2001 Persistor Instruments Inc.
**	All rights reserved.
**	
*****************************************************************************
**	
**	Copyright and License Information
**	
**	Persistor Instruments Inc. (hereafter, PII) grants you (hereafter,
**	Licensee) a non-exclusive, non-transferable license to use the software
**	source code contained in this single source file with hardware products
**	sold by PII. Licensee may distribute binary derivative works using this
**	software and running on PII hardware products to third parties without
**	fee or other restrictions.
**	
**	PII MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
**	SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
**	IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
**	OR NON-INFRINGEMENT. PII SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY
**	LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE OR
**	ITS DERIVATIVES.
**	
**	By using or copying this Software, Licensee agrees to abide by the
**	copyright law and all other applicable laws of the U.S. including, but
**	not limited to, export control laws, and the terms of this license. PII
**	shall have the right to terminate this license immediately by written
**	notice upon Licensee's breach of, or non-compliance with, any of its
**	terms. Licensee may be held legally responsible for any copyright
**	infringement or damages resulting from Licensee's failure to abide by
**	the terms of this license. 
**	
\******************************************************************************/

#include	<cfxbios.h>		// Persistor BIOS and I/O Definitions
#include	<cfxpico.h>		// Persistor PicoDOS Definitions

#include	<ctype.h>
#include	<errno.h>
#include	<stdarg.h>
#include	<stddef.h>
#include	<stdio.h>
#include	<stdlib.h>
#include	<string.h>
#include	<time.h>

// To see changes, search for: 	// ###TUSimpleTermDrvrPatch

void InstallAltTPUartHandlers(void *tuport);	// ###TUSimpleTermDrvrPatch

/******************************************************************************\
**	TUSimpleTermCmd		CIOgetclp
\******************************************************************************/
char *TUSimpleTermCmd(CmdInfoPtr cip);
char *TUSimpleTermCmd(CmdInfoPtr )
	{
	TUPort		*tuport;
	short		rxch, txch;
	long		baud = 9600;

	cprintf("\nPersistor CF2 TPU UART terminal example\n");
	
//
//	INITIALIZE THE TPU UART MODULE
//		This really belongs in your main() function should generally only
//		be called once at the start of your program. Repeat calls to TUInit
//		release any existing TPU UART channels and attempts to use them
//		without reopening will fail or crash the system.
//
	TUInit(calloc, free);		// give TU manager access to our heap

//
//	OPEN THE TPU UART PORT
//		This is the simplest form of opening a port since we implicitly
//		accept all of the default configuration settings defined by the
//		TUChParams structure which is defined in <cfxpico.h> by passing
//		zero for the last parameter. See the TUAltConsoleCmd for an
//		example showing how to supply custom configuration parameters
//		for an open call.
//
//		The Rx and Tx TPU channels are selected by their associated pin
//		number on the CF2's connector C. The actual TPU channels are
//		never directly referenced after opening, and the pin numbers,
//		or well named macros, are much more intuitive. In this case,
//		we're using the pins that connect to the auxiliary RS232
//		driver for connector AUX1 on a fully loaded PicoDAQ2 RecipeCard
//		which is why also setup pins C29 and C30 to enable the MAX3222.

	rxch = TPUChanFromPin(33);	// AUX1 RS232 receiver on PicoDAQ2 board
	txch = TPUChanFromPin(34);	// AUX1 RS232 transmitter on PicoDAQ2 board
	PIOSet(29);					// enable MAX322 transmitter (/OFF)
	PIOClear(30);				// enable MAX322 receivers (/EN)

	tuport = TUOpen(rxch, txch, baud, 0);
	if (tuport == 0)
		{
		cprintf("\n!!! Unexpected error opening TU channel, aborting\n");
		goto exitTUST;
		}

//
//	PREPARE FOR POSSIBLE FAST BLOCK TRANSFERS
//		The TPU UARTs only work with interrupt driven queues, but the
//		main SCI UART run in polled mode until explicitly directed to
//		switch to queued interrupt driven mode. We'll do that now in
//		case we get some big block requests from actions like paste
//		or send text files.
 
	SCIRxSetBuffered(true);	// switch SCI to buffered receive mode
	SCITxSetBuffered(true);	// switch SCI to buffered transmit mode

//
//	ENTER THE TERMINAL LOOP
//		For as long a the PBM button isn't pushed (or pin-C39 grounded,
//		we alternately check the TPU UART receive queue for data, and if
//		found, grab it and send it to the main SCI UART for viewing. Then
//		we check the main SCI UART's queue to see if any keyboard data
//		has come in, and if so, grab that and send it out to whatever is
//		on the receiving end of the TPU UART.
//
//		Note that we used the abbreviated console I/O style macro names
//		(defined in <cfxpico.h> instead of the longer and more descriptive
//		actual function names. You are free to use whatever you prefer.

InstallAltTPUartHandlers(tuport);		// ###TUSimpleTermDrvrPatch

	while(PIORead(IRQ5))		// run until PBM button pushed
		{
		if (tgetq(tuport))				// we've got data from afar
			cputc(tgetc(tuport));		// grab it and show it

		if (cgetq())					// we've got data from the keyboard
			tputc(tuport, cgetc());	// send it off
		}
exitTUST:
	if (tuport)
		TUClose(tuport);
	return 0;

	}	//____ TUSimpleTermCmd() ____//



// ###TUSimpleTermDrvrPatch
// everything below

#include	<mc68332.h>		// Persistor 68332 Module Map
#include	<tpu68332.h>	// Persistor 68332 TPU Macros and Definitions

enum 	// UART Parameter RAM Fields
	{
	uartParityTemp,
	uartMatchRate,
	uartRxTxDataReg,
	uartDataSize,
	uartActualBitCount,
	uartShiftRegister
	};

typedef struct
	{
	ulong	saveregs;		// 48E7 E0C0	movem.l   d0-d2/a0-a1,-(a7)
	ushort	slot;			// 7008			moveq     #??,d0
	ushort	jsr;			// 4EB9			jsr       TU?xHandler
	vfptr	handler;		// 0000 0000
	ulong	restregs;		// 4CDF 0307	movem.l   (a7)+,d0-d2/a0-a1
	ushort	rte;			// 4E73			rte
	}	TPisr;

const TPisr TPisrTemplate = // open must adjust slot and handler fields
		{ 0x48E7E0C0, 0x7000, 0x4EB9, 0x00000000, 0x4CDF0307, 0x4E73};

typedef struct
	{
	void			*port;		// reverse link
	short			slot;		// TPU channel 1-15
	short			priority;	// TPU channel priority (off,lo,mid,hi)
	long			baud;		// BAUD rate
	short			autob;		// auto BAUD change
	short			flags;		// flags
	short			parity;		// parity
	short			bits;		// data bits
	vfptr			previsr;	// former interrupt handler
	TPisr			isr;		// ISR wrapper
	short			size;		// buffer size
	volatile short	free;		// free space for insert
	volatile short	head;		// head index
	volatile short	tail;		// tail index
	uchar			*buffer;
	}	TUChan;

#undef		TUPort	// from <cfxpico.h> vptr
typedef struct
	{			
	TUChan		*rxchp;		// receiver
	TUChan		*txchp;		// transmitter
	char		*tpfbuf;	// printf buffer
	}	TUPort;

TUChan	*TUChanLookup[16] : 0x62CC;	// associates channel with TUChan pointer;

void TURxHandler(ushort slot:__d0);
void TUTxHandler(ushort slot:__d0);

/******************************************************************************\
**	InstallAltTPUartHandlers		
\******************************************************************************/
void InstallAltTPUartHandlers(void *tuport)
	{
	TUPort *tup = (TUPort *)tuport;

	if (tup->rxchp)
		tup->rxchp->isr.handler = TURxHandler; // ISR wrapper handler
	
	if (tup->txchp)
		tup->txchp->isr.handler = TUTxHandler; // ISR wrapper handler

	}	//____ InstallAltTPUartHandlers() ____//


/******************************************************************************\
**	TUTxHandler		
\******************************************************************************/
void TUTxHandler(ushort slot:__d0)
	{
	TUChan		*tchp = TUChanLookup[slot];

	if (tchp->free != tchp->size)
		{
		TPUClearInterrupt(slot);
//		TPRAM[tchp->slot][uartRxTxDataReg] = *(tchp->buffer + tchp->tail++);
		TPRAM[tchp->slot][uartRxTxDataReg] = *(tchp->buffer + tchp->tail++) + 1;// ###TUSimpleTermDrvrPatch
		if (tchp->tail == tchp->size)
			tchp->tail = 0;
		tchp->free += 1;		
		}
	else
		{
		TPUDisableInterrupt(slot);
		tchp->flags = false;
		}

	}	//____ TUTxHandler() ____//


/******************************************************************************\
**	TURxHandler		
\******************************************************************************/
void TURxHandler(ushort slot:__d0)
	{
	TUChan		*tchp = TUChanLookup[slot];

	if (tchp->free == 0)	// no room
		{
		tchp->flags++;	// bump overrun count
		}
	else
		{
//		*(tchp->buffer + tchp->head++) = TPRAM[tchp->slot][uartRxTxDataReg];
		*(tchp->buffer + tchp->head++) = TPRAM[tchp->slot][uartRxTxDataReg] + 1;// ###TUSimpleTermDrvrPatch
		if (tchp->head == tchp->size)
			tchp->head = 0;
		tchp->free -= 1;
		}

	TPUClearInterrupt(slot);
	
	}	//____ TURxHandler() ____//







