/*
 * basic TTY terminal example demonstrating SIO serial i/o library
 *
 * Gets settings from term.ini or creates one if none exists
 *
 * Demonstrates messaging used to multiplex serial i/o with other
 * events.
 *
 * The keyboard thread and the sio subsystem can both generate events
 * for the serial thread.  Either event will awaken the serial thread
 * and it will then act on the request.
 */

#include <dos.h>
#include <stdio.h>
#include <rtos.h>
#include <sio.h>
#include <inifile.h>

void *peer = NULL;              /* peer for messaging */
#define PEER_KBCHAR  EMSG_USER  /* indicates new keyboard char arrived */

void kbd_thread( DWORD port )
{
    BYTE ch;

    do {
        if ( kbhit() ) {
            ch = getch();

            /* exit on ~ character */
            if ( ch == '~' ) break;
            if ( peer )
                kwritemessage( peer, PEER_KBCHAR, ch );
        }
        rt_sleep(10);
    } while ( 1 );
    kwritemessage( kmainthread, 0, 0 );
}

void serial_thread( DWORD port )
{
    BYTE ch;
    int msg;
    DWORD val;

    /* get a message when new data arrived */
    sio_msg( port, 0, 1 );

    do {
        kreadmessage( &msg, &val );
        switch ( msg ) {
            case PEER_KBCHAR :
                        sio_writebyte( port, (BYTE) val );
                        break;
            case EMSG_BQ_WAITING :
                        /* could be several chars */
                        while ( sio_recv_waiting( port )) {
                            ch = sio_readbyte( port );
                            putch( ch );
                        }
                        break;
        }
    } while ( 1 );
}

main()
{
    int comport = 1;        /* com port */
    WORD port = 0x3f8;      /* its i/o port base */
    int baud = 9600;
    int irq = 4;

    int temp;
    DWORD dummy;

    rt_init( 100 );

    if (( comport = GetIniDWORD( "term.ini", "com", "port", 0 )) == 0 ){
        comport = 1;
        SetIniDWORD("term.ini","com","port", comport );
    }
    if ( comport == 2 ) {
        port = 0x2f8;
        irq = 3;
    }
    if (( baud = GetIniDWORD( "term.ini", "com", "baud", 0 )) == 0 ){
        baud = 9600;
        SetIniDWORD("term.ini","com","baud", baud );
    }


    sio_init( comport, port, irq, 4096, 4096, NULL, 0 );

    sio_setup( comport, baud, 8, 0, 1, 1 );
    cprintf("Press ~ to exit\r\n");

    rt_newthread( kbd_thread, comport, 2048, 0, "keyboard thread" );
    peer = rt_newthread( serial_thread, comport, 2048, 0, "serial input thread");

    /* wait until we're done */
    kreadmessage( &temp, &dummy );

    sio_close( comport );
    cprintf("\r\nDone\r\n");
}


