/******************************************************************************
 *
 *                               Sio_emul
 *
 * This module contains the driver for the PC bus emulator UART for the A1D.
 * The bus emulates a single uart port at 9600 baud rate operating through 
 * memory mapped registers and buffers.
 * History:
 *   +----------+------------+------------------------------------------------+
 *   |   Date   |     by     |     Description                                |
 *   +----------+------------+------------------------------------------------+
 *   |          | Gary       | Written                                        |
 *   +----------+------------+------------------------------------------------+
 * The data is (A1D) transferd through two 256 bytes cyclic buffers in dram.
 * Data transference to/from PC is handled by H/W.
 * 
 *****************************************************************************/

#include "sio_d.h"

#define		TXBC	(*(volatile unsigned char *)0xfffa04)
#define     	WPTR    (*(volatile unsigned char *)0xfffa00)
#define		RXBC	(*(volatile unsigned char *)0xfffa06)
#define		RPTR	(*(volatile unsigned char *)0xfffa02)
#define		MCPSR	(*(volatile unsigned char *)0xfffd02)
#define		CBTHOLD	(*(volatile unsigned char *)0xfffa08)
#define		INT_ENA	(*(volatile unsigned char *)0xfffe04)

#define BUFFER_SIZE 255
#define TR_BUF_ADDR 0x0
#define XR_BUF_ADDR 0x100

/* Primitive macros requierd by sio_d.c */
/****************************************/
 
#define READ_CHAR_IS_READY(port) 	(TXBC > (unsigned char) 0x0)
#define GET_CHAR(port)  		(eget_char())
#define READY_TO_WRITE_CHAR(port)	(RXBC < (unsigned char) 255)
#define PUT_CHAR(port, ch)		(eput_char(ch))
#define DIVISOR(divisor, port)

/****************************************************************************
 *
 * 				eget_char().
 *
 *  This function gets one byte from PC transmit buffer incrementing the 
 *  buffer pointer tr_buf_ptr to the next byte.
 *
 ****************************************************************************/

private unsigned char eget_char()
{
    unsigned char ch;

    ch = *((unsigned char *)(TR_BUF_ADDR + tr_buf_ptr)); 
    tr_buf_ptr = ((tr_buf_ptr >= BUFFER_SIZE) ? 0 : tr_buf_ptr+1);
    return ch;
}

/****************************************************************************
 *
 * 				eput_char().
 *
 *  This function sends one byte to PC receive buffer incrementing the 
 *  buffer pointer xr_buf_ptr to the next byte.
 *
 ****************************************************************************/

private void eput_char(ch)
unsigned char ch;
{
    *((unsigned char *)(XR_BUF_ADDR + xr_buf_ptr)) = ch;
    xr_buf_ptr = ((xr_buf_ptr >= BUFFER_SIZE) ? 0 : xr_buf_ptr+1);
}

/****************************************************************************
 *
 * 				init_uart().
 *
 *  This function initializes the uart.
 *
 ****************************************************************************/

private void init_uart (port, divisor, mode)
int     port;
unsigned int divisor;
int mode;
{
    MCPSR = 0x40;	/* Use IRQ3 and enable COM port interrupts	*/
    CBTHOLD = 0;	/* interrupt the FX after every 1 byte transfer */
    INT_ENA = 0x18;	/* interrupt on transmit and recieve 		*/
    tr_buf_ptr = 0;	/* reset counters				*/
    xr_buf_ptr = 0;
    TXBC = 0 ;
    WPTR = 0 ;
    RXBC = 0 ;
    RPTR = 0 ;
}
