/*
	This serial port driver is borrowed heavily from DZComm.  I have
	simplified it by removing a lot of the functionality (hardware 
	flow control, etc.).  For more details and the full version see
	http://dzcomm.sourceforge.net
*/

/*
    FreeRTOS V8.1.0 - Copyright (C) 2014 Real Time Engineers Ltd. 
    All rights reserved

    VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

    ***************************************************************************
     *                                                                       *
     *    FreeRTOS provides completely free yet professionally developed,    *
     *    robust, strictly quality controlled, supported, and cross          *
     *    platform software that has become a de facto standard.             *
     *                                                                       *
     *    Help yourself get started quickly and support the FreeRTOS         *
     *    project by purchasing a FreeRTOS tutorial book, reference          *
     *    manual, or both from: http://www.FreeRTOS.org/Documentation        *
     *                                                                       *
     *    Thank you!                                                         *
     *                                                                       *
    ***************************************************************************

    This file is part of the FreeRTOS distribution.

    FreeRTOS is free software; you can redistribute it and/or modify it under
    the terms of the GNU General Public License (version 2) as published by the
    Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.

    >>!   NOTE: The modification to the GPL is included to allow you to     !<<
    >>!   distribute a combined work that includes FreeRTOS without being   !<<
    >>!   obliged to provide the source code for proprietary components     !<<
    >>!   outside of the FreeRTOS kernel.                                   !<<

    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    FOR A PARTICULAR PURPOSE.  Full license text is available from the following
    link: http://www.freertos.org/a00114.html

    1 tab == 4 spaces!

    ***************************************************************************
     *                                                                       *
     *    Having a problem?  Start by reading the FAQ "My application does   *
     *    not run, what could be wrong?"                                     *
     *                                                                       *
     *    http://www.FreeRTOS.org/FAQHelp.html                               *
     *                                                                       *
    ***************************************************************************

    http://www.FreeRTOS.org - Documentation, books, training, latest versions,
    license and Real Time Engineers Ltd. contact details.

    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
    including FreeRTOS+Trace - an indispensable productivity tool, a DOS
    compatible FAT file system, and our tiny thread aware UDP/IP stack.

    http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
    Integrity Systems to sell under the OpenRTOS brand.  Low cost OpenRTOS
    licenses offer ticketed support, indemnification and middleware.

    http://www.SafeRTOS.com - High Integrity Systems also provide a safety
    engineered and independently SIL3 certified version for use in safety and
    mission critical applications that require provable dependability.

    1 tab == 4 spaces!
*/



#include <stdlib.h>
#include <dos.h>
#include "FreeRTOS.h"
#include "queue.h"
#include "task.h"
#include "semphr.h"
#include "portasm.h"

#define serMAX_IRQs						( 16 )
#define serTRANSMIT_HOLD_EMPTY_INT		( 0x02 )
#define serCOM1_STANDARD_IRQ			( ( unsigned char ) 4 )
#define serCOM2_STANDARD_IRQ			( ( unsigned char ) 3 )


#define	serIMR_8259_0					( ( unsigned char ) 0x21 )
#define	serIMR_8259_1					( ( unsigned char ) 0xa1 )
#define	serISR_8259_0					( ( unsigned char ) 0x20 )
#define	serISR_8259_1					( ( unsigned char ) 0xa0 )
#define	serALL_COMS_INTERRUPTS			( ( unsigned char ) 0x0f )
#define	serALL_MODEM_CTRL_INTERRUPTS	( ( unsigned char ) 0x0f )

#define serTRANSMIT_HOLD_OFFSET					( 0 )
#define serRECEIVE_DATA_OFFSET					( 0 )
#define serBAUD_RATE_DIVISOR_LOW_OFFSET			( 0 )
#define serBAUD_RATE_DIVISOR_HIGH_OFFSET		( 1 )
#define serINTERRUPT_ENABLE_OFFSET				( 1 )
#define serINTERRUPT_ID_OFFSET					( 2 )
#define serFIFO_CTRL_OFFSET						( 2 )
#define serLINE_CTRL_OFFSET						( 3 )
#define serMODEM_CTRL_OFFSET					( 4 )
#define serLINE_STATUS_OFFSET					( 5 )
#define serMODEM_STATUS_OFFSET					( 6 )
#define serSCR_OFFSET							( 7 )

#define serMAX_BAUD			( ( unsigned long ) 115200UL )

#define serNO_INTERRUPTS	( 0x00 )

#define vInterruptOn( pxPort, ucInterrupt )										\
{																				\
	unsigned char ucIn = portINPUT_BYTE( pxPort->usInterruptEnableReg );	\
	if( !( ucIn & ucInterrupt ) )												\
	{																			\
		portOUTPUT_BYTE( pxPort->usInterruptEnableReg, ucIn | ucInterrupt );	\
	}																			\
}																				
/*-----------------------------------------------------------*/

#define vInterruptOff( pxPort, ucInterrupt )									\
{																				\
	unsigned char ucIn = portINPUT_BYTE( pxPort->usInterruptEnableReg );	\
	if( ucIn & ucInterrupt )													\
	{																			\
		portOUTPUT_BYTE( pxPort->usInterruptEnableReg, ucIn & ~ucInterrupt);	\
	}																			\
}
/*-----------------------------------------------------------*/

typedef enum
{ 
	serCOM1, 
	serCOM2, 
	serCOM3, 
	serCOM4, 
	serCOM5, 
	serCOM6, 
	serCOM7, 
	serCOM8 
} eCOMPort;

typedef enum 
{ 
	serNO_PARITY, 
	serODD_PARITY, 
	serEVEN_PARITY, 
	serMARK_PARITY, 
	serSPACE_PARITY 
} eParity;

typedef enum 
{ 
	serSTOP_1, 
	serSTOP_2 
} eStopBits;

typedef enum 
{ 
	serBITS_5, 
	serBITS_6, 
	serBITS_7, 
	serBITS_8 
} eDataBits;

typedef enum 
{ 
	ser50,		
	ser75,		
	ser110,		
	ser134,		
	ser150,    
	ser200,
	ser300,		
	ser600,		
	ser1200,	
	ser1800,	
	ser2400,   
	ser4800,
	ser9600,		
	ser19200,	
	ser38400,	
	ser57600,	
	ser115200
} eBaud;

/* This *MUST* match the order in the eBaud definition. */
unsigned long ulBaudFromEnum[] = 
{ 
	( unsigned long ) 50, 
	( unsigned long ) 75, 
	( unsigned long ) 110, 
	( unsigned long ) 134, 
	( unsigned long ) 150,	
	( unsigned long ) 200, 
	( unsigned long ) 300, 
	( unsigned long ) 600, 
	( unsigned long ) 1200, 
	( unsigned long ) 1800, 
	( unsigned long ) 2400,   
	( unsigned long ) 4800,   
	( unsigned long ) 9600,  
	( unsigned long ) 19200,  
	( unsigned long ) 38400UL,
	( unsigned long ) 57600UL,
	( unsigned long ) 115200UL
};

typedef struct xCOM_PORT
{ 
	unsigned short sPort;   /* comm port address eg. 0x3f8    */
	unsigned char ucIRQ;    /* comm IRQ eg. 3                 */

	/* Next two fields used for setting up the IRQ routine and
	* (un)masking the interrupt in certain circumstances.
	*/
	unsigned short usIRQVector;
	unsigned char ucInterruptEnableMast;

	/* Read/Write buffers. */
	QueueHandle_t xRxedChars; 
	QueueHandle_t xCharsForTx;

	/* This lot are set up to minimise CPU time where accessing the comm
	* port's registers.
	*/
	unsigned short usTransmitHoldReg; 
	unsigned short usReceiveDataRegister;
	unsigned short usBaudRateDivisorLow; 
	unsigned short usBaudRateDivisorHigh;
	unsigned short usInterruptEnableReg;
	unsigned short usInterruptIDReg;
	unsigned short usFIFOCtrlReg;
	unsigned short usLineCtrlReg;
	unsigned short usModemCtrlReg;
	unsigned short usLineStatusReg;
	unsigned short usModemStatusReg;
	unsigned short usSCRReg;
	unsigned short us8259InterruptServiceReg;
	unsigned short us8259InterruptMaskReg;

	/* This semaphore does nothing useful except test a feature of the
	scheduler. */
	SemaphoreHandle_t xTestSem;

} xComPort;

typedef xComPort *xComPortHandle;

/* A xComPort structure can be associated with each IRQ.  Initially none
are create/installed. */
xComPort *xPortStatus[ serMAX_IRQs ] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };

/*-----------------------------------------------------------*/

/* These prototypes are repeated here so we don't have to include the serial header.  This allows
the xComPortHandle structure details to be private to this file. */
xComPortHandle xSerialPortInit( eCOMPort ePort, eBaud eWantedBaud, eParity eWantedParity, eDataBits eWantedDataBits, eStopBits eWantedStopBits, unsigned portBASE_TYPE uxBufferLength );
portBASE_TYPE xSerialGetChar( xComPortHandle pxPort, char *pcRxedChar, TickType_t xBlockTime );
portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, char cOutChar, TickType_t xBlockTime );
portBASE_TYPE xSerialWaitForSemaphore( xComPortHandle xPort );

static void prvSetupPortHardware( xComPort *pxPort, eCOMPort ePort, eBaud eWantedBaud, eParity eWantedParity, eDataBits eWantedDataBits, eStopBits eWantedStopBits );
static short sComPortISR( const xComPort * const pxPort );

/*-----------------------------------------------------------*/

/* Define an interrupt handler for each slot in the xPortStatus array. */

#define COM_IRQ_WRAPPER(N)										\
	static void __interrupt COM_IRQ##N##_WRAPPER( void )		\
	{															\
		portDISABLE_INTERRUPTS();								\
		if( sComPortISR( xPortStatus[##N##] ) )					\
		{														\
			portSWITCH_CONTEXT();								\
		}														\
	} 

COM_IRQ_WRAPPER( 0 )
COM_IRQ_WRAPPER( 1 )
COM_IRQ_WRAPPER( 2 )
COM_IRQ_WRAPPER( 3 )
COM_IRQ_WRAPPER( 4 )
COM_IRQ_WRAPPER( 5 )
COM_IRQ_WRAPPER( 6 )
COM_IRQ_WRAPPER( 7 )
COM_IRQ_WRAPPER( 8 )
COM_IRQ_WRAPPER( 9 )
COM_IRQ_WRAPPER( 10 )
COM_IRQ_WRAPPER( 11 )
COM_IRQ_WRAPPER( 12 )
COM_IRQ_WRAPPER( 13 )
COM_IRQ_WRAPPER( 14 )
COM_IRQ_WRAPPER( 15 )

static pxISR xISRs[ serMAX_IRQs ] = 
{
	COM_IRQ0_WRAPPER, 
	COM_IRQ1_WRAPPER, 
	COM_IRQ2_WRAPPER, 
	COM_IRQ3_WRAPPER, 
	COM_IRQ4_WRAPPER, 
	COM_IRQ5_WRAPPER, 
	COM_IRQ6_WRAPPER, 
	COM_IRQ7_WRAPPER, 
	COM_IRQ8_WRAPPER, 
	COM_IRQ9_WRAPPER, 
	COM_IRQ10_WRAPPER, 
	COM_IRQ11_WRAPPER, 
	COM_IRQ12_WRAPPER, 
	COM_IRQ13_WRAPPER, 
	COM_IRQ14_WRAPPER,
	COM_IRQ15_WRAPPER
};

static pxISR xOldISRs[ serMAX_IRQs ] = { NULL };

/*-----------------------------------------------------------*/


xComPortHandle xSerialPortInit( eCOMPort ePort, eBaud eWantedBaud, eParity eWantedParity, eDataBits eWantedDataBits, eStopBits eWantedStopBits, unsigned portBASE_TYPE uxBufferLength )
{
xComPort *pxPort;

	/* Create a structure to handle this port. */
	pxPort = ( xComPort * ) pvPortMalloc( sizeof( xComPort ) );
	
	if( pxPort != NULL )
	{
		/* Create the queues used by the comtest task. */
		pxPort->xRxedChars = xQueueCreate( uxBufferLength, ( unsigned portBASE_TYPE ) sizeof( char ) );
		pxPort->xCharsForTx = xQueueCreate( uxBufferLength, ( unsigned portBASE_TYPE ) sizeof( char ) );

		/* Create the test semaphore.  This does nothing useful except test a feature of the scheduler. */
		vSemaphoreCreateBinary( pxPort->xTestSem );

		prvSetupPortHardware( pxPort, ePort, eWantedBaud, eWantedParity, eWantedDataBits, eWantedStopBits );

		return pxPort;
	}

	return NULL;
}
/*-----------------------------------------------------------*/

static void prvSetupPortHardware( xComPort *pxPort, eCOMPort ePort, eBaud eWantedBaud, eParity eWantedParity, eDataBits eWantedDataBits, eStopBits eWantedStopBits )
{
short sIn;
unsigned long ulDivisor;
unsigned char ucDivisorLow;
unsigned char ucDivisorHigh;
unsigned char ucCommParam;

	/* IRQ numbers - standard */
	if( ( ePort == serCOM1 ) || ( ePort == serCOM3 ) || ( ePort == serCOM5 ) || ( ePort == serCOM7 ) )
	{
		pxPort->ucIRQ = serCOM1_STANDARD_IRQ;
		pxPort->sPort = 0x3f8;
	}
	else
	{
		pxPort->ucIRQ = serCOM2_STANDARD_IRQ;
		pxPort->sPort = 0x2f8;
	}

	/* Set up variables in port making it easy to see which sIn/o address is which */
	pxPort->usTransmitHoldReg = pxPort->sPort + serTRANSMIT_HOLD_OFFSET;
	pxPort->usReceiveDataRegister = pxPort->sPort + serRECEIVE_DATA_OFFSET;
	pxPort->usBaudRateDivisorLow = pxPort->sPort + serBAUD_RATE_DIVISOR_LOW_OFFSET;
	pxPort->usBaudRateDivisorHigh = pxPort->sPort + serBAUD_RATE_DIVISOR_HIGH_OFFSET;
	pxPort->usInterruptEnableReg = pxPort->sPort + serINTERRUPT_ENABLE_OFFSET;
	pxPort->usInterruptIDReg = pxPort->sPort + serINTERRUPT_ID_OFFSET;
	pxPort->usFIFOCtrlReg = pxPort->sPort + serFIFO_CTRL_OFFSET;
	pxPort->usLineCtrlReg = pxPort->sPort + serLINE_CTRL_OFFSET;
	pxPort->usModemCtrlReg = pxPort->sPort + serMODEM_CTRL_OFFSET;
	pxPort->usLineStatusReg = pxPort->sPort + serLINE_STATUS_OFFSET;
	pxPort->usModemStatusReg = pxPort->sPort + serMODEM_STATUS_OFFSET;
	pxPort->usSCRReg = pxPort->sPort + serSCR_OFFSET;

	/* Set communication parameters. */
	ulDivisor = serMAX_BAUD / ulBaudFromEnum[ eWantedBaud ];
	ucDivisorLow = ( unsigned char ) ulDivisor & ( unsigned char ) 0xff;
	ucDivisorHigh = ( unsigned char ) ( ( ( unsigned short ) ulDivisor >> 8 ) & 0xff );
	
	switch( eWantedParity )
	{	
		case serNO_PARITY:		ucCommParam = 0x00;
								break;
		case serODD_PARITY:		ucCommParam = 0x08;
								break;
		case serEVEN_PARITY:	ucCommParam = 0x18;
								break;
		case serMARK_PARITY:	ucCommParam = 0x28;
								break;
		case serSPACE_PARITY:	ucCommParam = 0x38;
								break;
		default:				ucCommParam = 0x00;
								break;
	}

	switch ( eWantedDataBits )
	{
		case serBITS_5:	ucCommParam |= 0x00;
						break;
		case serBITS_6:	ucCommParam |= 0x01;
						break;
		case serBITS_7:	ucCommParam |= 0x02;
						break;
		case serBITS_8:	ucCommParam |= 0x03;
						break;
		default:		ucCommParam |= 0x03;
						break;
	}

	if( eWantedStopBits == serSTOP_2 ) 
	{
		ucCommParam |= 0x04;
	}

	/* Reset UART into known state - Thanks to Bradley Town */
	portOUTPUT_BYTE( pxPort->usLineCtrlReg, 0x00 );			/* Access usTransmitHoldReg/RBR/usInterruptEnableReg */
	portOUTPUT_BYTE( pxPort->usInterruptEnableReg, 0x00 );	/* Disable interrupts from UART */
	portOUTPUT_BYTE( pxPort->usModemCtrlReg, 0x04 );		/* Enable some multi-port cards */

	/* Code based on stuff from SVAsync lib. Clear UART Status and data registers
	setting up FIFO if possible */
	sIn = portINPUT_BYTE( pxPort->usSCRReg );
	portOUTPUT_BYTE( pxPort->usSCRReg, 0x55 );

	if( portINPUT_BYTE( pxPort->usSCRReg ) == 0x55 )
	{
		/* The chip is better than an 8250 */
		portOUTPUT_BYTE( pxPort->usSCRReg, sIn );	/* Set usSCRReg back to what it was before */
		portINPUT_BYTE( pxPort->usSCRReg);			/* Give slow motherboards a chance */

		/* Try and start the FIFO. It appears that some chips need a two call 
		protocol, but those that don't seem to work even if you do start it twice. 
		The first call is simply to start it, the second starts it and sets an 8 
		byte FIFO trigger level. */
		portOUTPUT_BYTE( pxPort->usFIFOCtrlReg, 0x01 );
		portINPUT_BYTE( pxPort->usFIFOCtrlReg );			/* Give slow motherboards a chance to catch up */
		portOUTPUT_BYTE( pxPort->usFIFOCtrlReg, 0x87 );

		/* Check that the FIFO initialised */
		if( ( portINPUT_BYTE( pxPort->usInterruptIDReg ) & 0xc0 ) != 0xc0 )
		{
			/* It didn't so we assume it isn't there but disable it to be on the 
			safe side. */
			portOUTPUT_BYTE( pxPort->usInterruptIDReg, 0xfe );
		}
	}

	/* End of (modified) SVAsync code.  
	Set interrupt parameters calculating mask for 8259 controller's 
	IMR and number of interrupt handler for given irq level	 */
	if (pxPort->ucIRQ <= 7)
	{	
		/* if 0<=irq<=7 first IMR address used */
		pxPort->ucInterruptEnableMast = ~(0x01 << pxPort->ucIRQ);
		pxPort->usIRQVector = pxPort->ucIRQ + 8;
		pxPort->us8259InterruptMaskReg = serIMR_8259_0;
		pxPort->us8259InterruptServiceReg = serISR_8259_0;
	}
	else
	{
		pxPort->ucInterruptEnableMast = ~( 0x01 << ( pxPort->ucIRQ % 8 ) );
		pxPort->usIRQVector = 0x70 + ( pxPort->ucIRQ - 8) ;
		pxPort->us8259InterruptMaskReg = serIMR_8259_1;
		pxPort->us8259InterruptServiceReg = serISR_8259_1;
	}

	/* Set Port Toggle to usBaudRateDivisorLow/usBaudRateDivisorHigh registers 
	to set baud rate */
	portOUTPUT_BYTE( pxPort->usLineCtrlReg, ucCommParam | 0x80 );
	portOUTPUT_BYTE( pxPort->usBaudRateDivisorLow, ucDivisorLow );
	portOUTPUT_BYTE( pxPort->usBaudRateDivisorHigh, ucDivisorHigh );

	/* reset usLineCtrlReg and Port Toggleout */
	portOUTPUT_BYTE( pxPort->usLineCtrlReg, ucCommParam & 0x7F );

	portENTER_CRITICAL();

	if( xPortStatus[ pxPort->ucIRQ ] == NULL )
	{	
		xPortStatus[ pxPort->ucIRQ ] = pxPort;
	}
	
	xOldISRs[ pxPort->ucIRQ ] = _dos_getvect( pxPort->usIRQVector );
	_dos_setvect( pxPort->usIRQVector, xISRs[ pxPort->ucIRQ ] );

	/* enable interrupt pxPort->ucIRQ level */
	portOUTPUT_BYTE( pxPort->us8259InterruptMaskReg, portINPUT_BYTE( pxPort->us8259InterruptMaskReg ) & pxPort->ucInterruptEnableMast );

	/* And allow interrupts again now the hairy bit's done */
	portEXIT_CRITICAL();		

	/* This version does not allow flow control. */
	portOUTPUT_BYTE( pxPort->usModemCtrlReg, serALL_MODEM_CTRL_INTERRUPTS );

	/* enable all communication's interrupts */
	portOUTPUT_BYTE( pxPort->usInterruptEnableReg, serALL_COMS_INTERRUPTS );
}
/*-----------------------------------------------------------*/

static short sComPortISR( const xComPort * const pxPort )
{
short sInterruptID;
char cIn, cOut;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
extern void vComTestUnsuspendTask( void );

	portOUTPUT_BYTE( pxPort->us8259InterruptMaskReg, ( portINPUT_BYTE( pxPort->us8259InterruptMaskReg) | ~pxPort->ucInterruptEnableMast ) );

	/* Decide which UART has issued the interrupt */
	sInterruptID = portINPUT_BYTE( pxPort->usInterruptIDReg );

	/* service whatever requests the calling UART may have. The top 4 bits are
	either unused or indicate the presence of a functioning FIFO, which we don't
	need to know. So trim them off to simplify the switch statement below. */
	sInterruptID &= 0x0f;
	do
	{
		switch( sInterruptID )
		{
			case 0x0c:	/* Timeout
						Called when FIFO not up to trigger level but no activity for 
						a while. Handled exactly as RDAINT, see below for 
						description. */
						do
						{
							cIn = ( char ) portINPUT_BYTE( pxPort->usReceiveDataRegister );						
							xQueueSendFromISR( pxPort->xRxedChars, &cIn, &xHigherPriorityTaskWoken );

							/* Also release the semaphore - this does nothing interesting and is just a test.
							We first attempt to unsuspend the task to check the scheduler correctely detects
							this as an invalid call, then give the semaphore for real. */
							vComTestUnsuspendTask();
							xSemaphoreGiveFromISR( pxPort->xTestSem, &xHigherPriorityTaskWoken );

						} while( portINPUT_BYTE( pxPort->usLineStatusReg ) & 0x01 );
						break;

			case 0x06:	/* LSINT */
						portINPUT_BYTE( pxPort->usLineStatusReg );
						break;

			case 0x04:	/* RDAINT */
						/* The usInterruptIDReg flag tested above stops when the 
						FIFO is below the trigger level rather than empty, whereas 
						this flag allows one to empty it: (do loop because there 
						must be at least one to read by virtue of having got here.) */
						do
						{
							cIn = ( char ) portINPUT_BYTE( pxPort->usReceiveDataRegister );						
							xQueueSendFromISR( pxPort->xRxedChars, &cIn, &xHigherPriorityTaskWoken );

							/* Also release the semaphore - this does nothing interesting and is just a test.
							We first attempt to unsuspend the task to check the scheduler correctely detects
							this as an invalid call, then give the semaphore for real. */
							vComTestUnsuspendTask();
							xSemaphoreGiveFromISR( pxPort->xTestSem, &xHigherPriorityTaskWoken );

						} while( portINPUT_BYTE( pxPort->usLineStatusReg ) & 0x01 );
						break;

			case 0x02:	/* serTRANSMIT_HOLD_EMPTY_INT */
						if( xQueueReceiveFromISR( pxPort->xCharsForTx, &cOut, &xHigherPriorityTaskWoken ) != pdTRUE )						
						{																						
							/* Queue empty, nothing to send */													
							vInterruptOff( pxPort, serTRANSMIT_HOLD_EMPTY_INT);									
						}																						
						else																					
						{																						
							portOUTPUT_BYTE( pxPort->usTransmitHoldReg, ( short ) cOut );					
						}
						break;

			case 0x00:	/* MSINT */
						portINPUT_BYTE( pxPort->usModemStatusReg );
						break;
		}		

		/* Get the next instruction, trimming as above */
		sInterruptID = portINPUT_BYTE( pxPort->usInterruptIDReg ) & 0x0f;

	} while( !( sInterruptID & 0x01 ) );

	if( pxPort->ucIRQ > 7 )
	{
		portOUTPUT_BYTE( 0xA0, 0x60 + ( pxPort->ucIRQ & 0x07 ) );
		portOUTPUT_BYTE( 0x20, 0x62);
	}
	else
	{
		portOUTPUT_BYTE( 0x20, 0x60 + pxPort->ucIRQ );
	}

	portOUTPUT_BYTE( pxPort->us8259InterruptMaskReg, portINPUT_BYTE( pxPort->us8259InterruptMaskReg ) & pxPort->ucInterruptEnableMast );

	/* If posting any of the characters to a queue woke a task that was blocked on
	the queue we may want to return to the task just woken (depending on its 
	priority relative to the task this ISR interrupted. */
	return xHigherPriorityTaskWoken;
}
/*-----------------------------------------------------------*/

portBASE_TYPE xSerialGetChar( xComPortHandle pxPort, char *pcRxedChar, TickType_t xBlockTime )
{
	/* Get the next character from the buffer, note that this routine is only 
	called having checked that the is (at least) one to get */
	if( xQueueReceive( pxPort->xRxedChars, pcRxedChar, xBlockTime ) )
	{
		return pdTRUE;
	}
	else
	{
		return pdFALSE;
	}
}
/*-----------------------------------------------------------*/

portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, char cOutChar, TickType_t xBlockTime )
{
	if( xQueueSend( pxPort->xCharsForTx, &cOutChar, xBlockTime ) != pdPASS )
	{
		return pdFAIL;
	}

	vInterruptOn( pxPort, serTRANSMIT_HOLD_EMPTY_INT );

	return pdPASS;
}
/*-----------------------------------------------------------*/

void vSerialPutString( xComPortHandle pxPort, const char * const pcString, unsigned short usStringLength )
{
char * pcNextChar;
const TickType_t xNoBlock = ( TickType_t ) 0;

	/* Stop warnings. */
	( void ) usStringLength;

	pcNextChar = ( char * ) pcString;
	while( *pcNextChar )
	{
		xSerialPutChar( pxPort, *pcNextChar, xNoBlock );
		pcNextChar++;
	}
}
/*-----------------------------------------------------------*/

portBASE_TYPE xSerialWaitForSemaphore( xComPortHandle xPort )
{
const TickType_t xBlockTime = ( TickType_t ) 0xffff;

	/* This function does nothing interesting, but test the 
	semaphore from ISR mechanism. */
	return xSemaphoreTake( xPort->xTestSem, xBlockTime );	
}
/*-----------------------------------------------------------*/

void vSerialClose( xComPortHandle xPort )
{
	portENTER_CRITICAL();

	/* Turn off the interrupts. */
	portOUTPUT_BYTE( xPort->usModemCtrlReg, serNO_INTERRUPTS );
	portOUTPUT_BYTE( xPort->usInterruptEnableReg, serNO_INTERRUPTS );

	/* Put back the original ISR. */
	_dos_setvect( xPort->usIRQVector, xOldISRs[ xPort->ucIRQ ] );

	/* Remove the reference in the array of xComPort structures. */
	xPortStatus[ xPort->ucIRQ ] = NULL;

	/* Delete the queues. */
	vQueueDelete( xPort->xRxedChars );
	vQueueDelete( xPort->xCharsForTx );

	vPortFree( ( void * ) xPort );

	portEXIT_CRITICAL();
}

