
/*  send_rec.c
    For use with tm.exe Version 4
    Stephen D. Anderson --- November 13, 1994

    Low level communication function.  On entry waits for any receive
in progress.  Then sends message.  Gets receive reply if any.  Also
gets error byte associated with each received byte.  The speeds of
various operations are set in header file "send_rec.h", depending on
whether the result of compile should be TURBO, NORMAL, or TELECOM
version of the executable.

    ON ENTRY:
    "xmit_length" is the number of transmit bytes.

    ON EXIT:
    Returns integer.  The least signif byte of the integer is 0 if
    something was received, 1 if nothing received, 2 if too many 
    receive bytes, 3 if jabbering device.
    If the least signif byte of the returned integer is 0 (receive OK) 
    then the next most signif byte of the returned integer is the number 
    of received bytes and the receive record is contained in the global
    array "receive" and the error record is contained in the global
    array "receive_err."
    If the least signif byte of the returned integer is 2 (too many)
    then the next most signif byte of the returned integer is equal to
    MAX_COUNT and a truncated (to MAX_COUNT) receive record is contained
    in the global array "receive" and the truncated error record is
    contained in the global array "receive_err."

    REVISION LOG:

    Version 4.3:
    1.  Changed to clock() function instead of biostime().
    2.  Added statement ComFlushRx(com) in initial loop that waits
        for receive stuff to stop coming in.
    3.  Added variable "too_many" which indicates that there were
        too many received bytes.
    4.  Changed behavior so that if there are too many bytes, the
        "receive" and "receive_err" arrays return the receive
        bytes truncated to a length of MAX_COUNT.
    5.  October 29, 1995:  added header file "send_rec.h" to do
        conditional compilation and control speed of execution.

*/

#include "stdio.h"
#include "time.h"
#include "send_rec.h"
#include "c:\cport\include\cport.h"

int send_rec(byte xmit_length)
{

    extern COM com;
    extern byte send[], receive[], receive_err[];

    byte i,j,oldj;
    byte rec[2*MAX_COUNT];
    byte *r, *r_err;
    byte too_many;
    clock_t ftimstart,ftimstart1;

    too_many = 0;   /*  clear flag.  */ 

    /*  get rid of anything in queues.  */
    ComFlushTx(com); ComFlushRx(com);
       
    /*  check whether receive stuff coming in.  wait if it is.  */
    ftimstart = clock();
    while ((clock() - ftimstart)/CLK_TCK < EOM_WAIT)
    {
        ftimstart1 = clock();
        /*  wait long enough for next char to arrive.  */
        while ((clock() - ftimstart1)/CLK_TCK < EOM_CHAR_WAIT) ;
        /*  quit waiting if not receive data present.  */
        if ( (j = ComLenRx(com)) == 0 ) break;
        ComFlushRx(com);
    }
    if (j != 0) return(3);      /*  somebody jabbering.  so quit.  */

    /*  send message.  */
    ComRts(com, 1);  /* turn on RTS in case of PRIMM. */
    ComOut(com, send, xmit_length);
    while (ComLenTx(com)) ;  /* wait until done. */
    ComTxWait(com);
    ComRts(com, 0);

    /*  The following line is normally commented out.  Uncomment
        it to check on parity checking. */
/*    ComMode(com, W8 | S1 | EVEN);   */

    /* flush receive queue.  */
    ComFlushRx(com);

    /*  start timer to wait for receive stuff. */
    ftimstart = clock();

    /*  wait for 1st character. */
    while ((clock() - ftimstart)/CLK_TCK < START_WAIT)
    {
        if ((j = ComLenRx(com)) != 0) break;
    }

    if (j == 0) return(1);  /*  quit if no receive. */

    /*  wait until receive record length hasn't changed in 
        time of IN_MSG_WAIT.  */
    oldj = 0;
    while ((j = ComLenRx(com)) != oldj)
    {
        oldj = j;
        ftimstart = clock();
        while ((clock() - ftimstart)/CLK_TCK < IN_MSG_WAIT) ;  /*  wait.  */
    }

    /*  check for too many receive bytes.  */
    if (j > 2*MAX_COUNT)
    {
        ++too_many;
        j = 2*MAX_COUNT;
    }

    ComIn(com,rec,j);   /*  get the receive data. */

    /*  split the "rec" array into received bytes and error bytes. */
    r = receive; r_err = receive_err;
    for (i=0; i<j; )
    {
        *r_err++ = (rec[i++] & ERROR_MASK); *r++ = rec[i++];
    }

    j = j/2;    /*  adjust for error bytes. */

    /*  return byte count in upper byte, 0 in lower byte if everything
        OK or 2 in lower byte if too many bytes.  */
    if (too_many) return(256*j + 2);
    else return(256*j);
}

