/* rs232.h v1.6 */
#define rs_232_h

/* port characteristic definitions for use with rs_initport */
   /* port id's */
#define RS_PORT1 '1'       /* port 1 */
#define RS_PORT2 '2'       /*   .    */
#define RS_PORT3 '3'       /*   .    */
#define RS_PORT4 '4'       /* port 4 */
#define RS_USERPORT '0'    /* user defined I/O base address and IRQ */
   /* baud rates */
#define RS_B110 110L       /* 110 baud */
#define RS_B300 300L       /*    .     */
#define RS_B600 600L       /*    .     */
#define RS_B1200 1200L     /*    .     */
#define RS_B2400 2400L     /*    .     */
#define RS_B4800 4800L     /*    .     */
#define RS_B9600 9600L     /*    .     */
#define RS_B19K 19200L     /*    .     */
#define RS_B38K 38400L     /*    .     */
#define RS_B57K 57600L     /*    .     */
#define RS_B115K 115200L   /* 115200 baud */
   /* parity */
#define RS_NOPAR 'N'       /* no parity */
#define RS_EVPAR 'E'       /* even parity */
#define RS_ODPAR 'O'       /* odd parity */
#define RS_SPPAR 'S'       /* space parity */
#define RS_MKPAR 'M'       /* mark parity */
   /* data bits */
#define RS_DBIT8 '8'       /* 8 data bits */
#define RS_DBIT7 '7'       /* 7 data bits */
   /* stop bits */
#define RS_SBIT1 '1'       /* 1 stop bit */
#define RS_SBIT2 '2'       /* 2 stop bits */
/* values returned by rs_initport */
#define RS_UART4 4         /* init. OK, UART is 16550AF,C,CF */
#define RS_UART3 3         /* init. OK, UART is 16550 */
#define RS_UART2 2         /* init. OK, UART is 8250A or 16450 */
#define RS_UART1 1         /* init. OK, UART is 8250 or 8250B */
#define RS_NOUART 0        /* init. failed - no UART detected */
#define RS_BADIBUF -1      /* init. failed - in. buffer or size bad */
#define RS_BADOBUF -2      /* init. failed - out. buffer or size bad */
#define RS_BADPORT -3      /* init. failed - invalid port argument */
#define RS_BADPAR -4       /* init. failed - invalid parity argument */
#define RS_BADDBIT -5      /* init. failed - invalid data bits argument */
#define RS_BADSBIT -6      /* init. failed - invalid stop bits argument */
#define RS_BADBAUD -7      /* init. failed - invalid baud argument */

/* bit definitions to test value returned by rs_error */
#define RS_RBER 0x01       /* Receive data overrun (receive buffer) */
#define RS_ROER 0x02       /* Receive data overrun (UART) */
#define RS_PERR 0x04       /* Parity error */
#define RS_FERR 0x08       /* Framing error */
#define RS_BKDT 0x10       /* Break detected */
#define RS_FFER 0x80       /* Error in receive FIFO */

/* definitions for use with rs_modctrl */
#define RS_GETMSR 0 /* command to read state of modem status lines */
  /* bit definitions to test value returned with RS_GETMSR cmd */
  #define RS_CTSCHG 0x01   /* CTS changed states */
  #define RS_DSRCHG 0x02   /* DSR changed states */
  #define RS_RICHG  0x04   /* RI changed states */
  #define RS_DCDCHG 0x08   /* DCD changed states */
  #define RS_CTSSTE 0x10   /* state of CTS */
  #define RS_DSRSTE 0x20   /* state of DSR */
  #define RS_RISTE  0x40   /* state of RI */
  #define RS_DCDSTE 0x80   /* state of DCD */
#define RS_WRTMCR 1 /* command to control hardware control lines */
  /* parameter1 definitions for use with RS_WRTMCR and RS_GETMCR commands */
  #define RS_MCRDTR 1      /* DTR line */
  #define RS_MCRRTS 2      /* RTS line */
  /* parameter2 definitions for use with RS_WRTMCR command */
  #define RS_LINON 1       /* turn selected line on */
  #define RS_LINOFF 0      /* turn selected line off */
#define RS_GETMCR 2 /* command to return current state of modem control reg. */

/* command definitions for rs_timer */
#define RS_CLRTIM 0 /* return timer count, set timer to 0 */
#define RS_GETTIM 1 /* return timer count, do not clear */

/* definitions for rs_setflow */
#define RS_FLWOFF 0 /* command to turn flow control off */
#define RS_FLWHDW 1 /* command to turn hardware flow control on */
  /* parameter1 bit definitions for use with RS_FLWHDW command */
  #define RS_FLWCTS 1      /* use CTS line */
  #define RS_FLWDSR 2      /* use DSR line */
  #define RS_FLWRI  4      /* use RI line */
  #define RS_FLWDCD 8      /* use DCD line */
#define RS_FLWXON 2 /* command to turn XON/XOFF flow control on */
  /* parameter1 and parameter2 definitions for use with RS_FLWXON */
  #define RS_XON 0x11      /* standard XON character */
  #define RS_XOFF 0x13     /* standard XOFF character */
#define RS_FLWSTAT 3 /* command to return status of flow control */
  /* values returned by RS_FLWSTAT command */
  #define RS_FLWHLT 1      /* output halted by flow control */
  #define RS_FLWNHLT 0     /* output not halted by flow control */
#define RS_FLWINS 4 /* command to insert control byte in output stream */

/*****************************************************************/
/***                   function prototypes                     ***/
/*****************************************************************/
#ifdef __cplusplus
extern "C"{
#endif
     /* interrupt handler */
void interrupt rs_inthndlr(void);

     /* port initialization: Sets up port parameters, installs interrupt
        vector, enables interrupts.  Input and output buffers are 'rotary'
        buffers - buffer size must be a power of 2.  Function returns the
        following:
          4 - Success, 16550 UART, FIFOs enabled.
          3 - Success, 16550 UART, FIFOs unavailable.
          2 - Success, 8250A or 16450 UART
          1 - Success, 8250B UART
          0 - Fail, no UART detected
         -1 - Fail, bad input buffer
         -2 - Fail, bad output buffer
         -3 - Fail, bad port argument
         -4 - Fail, bad parity argument
         -5 - Fail, bad data bits argument
         -6 - Fail, bad stop bits argument
         -7 - Fail, bad baud argument
        Example:
      status = rs_initport(port,baud,parity,bits,stop,in_bufsize,in_bufptr,\
                           out_bufsize,out_bufptr);
      port = '1','2','3', or '4'
      baud = 110, 300, 1200, 2400, 4800, 9600, 19200, 38400, 57600 or 115200
      parity = 'N', 'E', 'O', 'S' or 'M'
      bits = '7' or '8'
      stop = '1' or '2'
      in_bufsize = (power of 2) >= 2 <= 32768
      in_bufptr = char pointer to previously allocated input buffer
      out_bufsize = (power of 2) >= 2 <= 32768
      out_bufptr = char pointer to previously allocated output buffer */
int rs_initport(char, long, char, char, char,
                unsigned, char *, unsigned, char *);

     /* Send single byte out port - if no room in output buffer, wait
        til there's room.  Return 0 on success, or -1 if no room in
        output buffer and output is currently disabled via flow control
        or if port is unavailable.  If RS_POLLED_XMIT is defined, xmit buffer
        and xmit interrupts are not used. */
int rs_sndbyt(int);

     /* Send string of specified length out port - if no room in output
        buffer, waits til there's room.  Return 0 on success or number of
        bytes copied to output buffer if not enough room for entire string
        and output is currently disabled via flow control.  Returns -1 if
        port is not available.  If length is 0 (unspecified), send chars
        from string up to but not including terminating nul character.
        If RS_POLLED_XMIT is defined in header, xmit interrupts are not used
        and the function does not return until the string has been sent. */
int rs_sndstr(int,char *);

     /* Scan characters in input buffer for specified string.  Return offset
        into buffer if found, -1 if not found */
int rs_scanin(char *);

     /* Non-destructive read of next character in input buffer */
int rs_peek(void);

     /* Get single char, return -1 if none available or port is not
        available. */
int rs_getbyt(void);

     /* Get specified number of characters from input buffer.  If less
        than the specified number of characters are available, get as
        many as are available.  If length of string is unspecified (0),
        copy characters up to and including terminating nul. Return number
        of characters copied or -1 if port is unavailable.  Null terminate
        string. */
int rs_getstr(int, char *);

     /* Return number of characters waiting to be read from input buffer. */
unsigned rs_inrcvd(void);

     /* Return amount of free space in output buffer. */
unsigned rs_outfre(void);

     /* Return code for last error detected as follows:
        bit 0: 1 = Receive overrun (buffer)
        bit 1: 1 = Receive overrun (UART)
        bit 2: 1 = Parity error
        bit 3: 1 = Framing error
        bit 4: 1 = Break detected
        bit 7: 1 = Error in receive FIFO
     Return 0 if no error since last call to rs_error()   */
int rs_error(void);

     /* If rs_cmd = 0, return modem status as follows:
          bit 0: CTS line changed state
          bit 1: DTR line change state
          bit 2: RI line changed state
          bit 3: DCD line changed state
          bit 4: current state of CTS line
          bit 5: current state of DTR line
          bit 6: current state of RI line
          bit 7: current state of DCD line
        Bits 0 - 3 will be 0 unless a status line has changed states since
        the last call to rs_modctrl();
        If rs_cmd = 1, parameter 1 is bit pattern for line to control.
        Parameter2 = 0 turns line off, parameter 2 = 1 turns line on.
        Returns -1 if port is unavailable. */
int rs_modctrl(int rs_cmd,...);

     /* Send break to remote.  Return -1 if port is unavailable. */
int rs_break(void);

     /* clear output buffer of any bytes not yet sent */
void rs_clrout(void);

     /* clear input buffer of any bytes received but not yet read */
void rs_clrin(void);

     /* return 0 if no keystrokes pending, 1 if key has been pressed */
int rs_keyhit(void);

     /* If rs_cmd = 0, set timer to 0 and return 18.2Hz tick count since
        timer was last zeroed or port was initialized.
        If rs_cmd = 1, return current value of timer.*/
unsigned rs_timer(int rs_cmd);

     /* Set flow control characteristics or check status
               rs_cmd = 0: Turn flow control off
               rs_cmd = 1: Set flow control to hardware.  Parameter1
                           is hardware line to monitor.
               rs_cmd = 2: Set flow control to XON/XOFF - Parameter1
                           is character to use for XON, Parameter2
                           is character to use for XOFF.
               rs_cmd = 3: Return status of flow control - 0 = output
                           normal, 1 = output halted
               rs_cmd = 4: Insert control character in output stream.
                           Parameter1 is control character.
        Returns -1 if port is unavailable */
int rs_setflow(int rs_cmd,...);

     /* Call this function before exiting program or when finished with port.
        Restores interrupt vector and interrupt mask, and disables port
        interrupts. */
void rs_close(void);

struct rs_userport{
  int base;
  char irq;
  };

extern struct rs_userport rs_user;

#ifdef __cplusplus
}
#endif
