/*------------------------------ CFUNCT.C --------------------------------*/
int mstat;                             /* modem status                     */
int lstat;                             /* line status                      */
int comerror;                          /* error number                     */

#define PARITY 1
#define FRAME 2
#define BREAK 3

#define COMBASE 0x03F8                 /* 0x02F8 for COM2                  */

#define TXREG   COMBASE                /* Transmit reg                     */
#define RXREG   COMBASE                /* Receive reg                      */
#define INTID   COMBASE + 2            /* Interrupt ID reg                 */
#define LINSTAT COMBASE + 5            /* Line Status Reg                  */
#define MODSTAT COMBASE + 6            /* Modem Status Reg                 */

typedef struct {
   int count;                          /* number of chars now in the buffer*/
   int start;                          /* offset of next character to take */
   int size;                           /* size of the buffer               */
   char *buffer;                       /* Address of the buffer            */
} RING;

RING ibuf;                             /* input buffer                     */
RING obuf;                             /* output buffer                    */

extern void putbuf();                  /* See Figure 16.11                 */
extern int getbuf();                   /* See Figure 16.11                 */

/*-------------------------------------------------------------------------*/
void cfunct()
{
int intnr, ch;

   for (;;) {                          /* until no more ints               */

      intnr = inp(INTID);              /* Interrupt ID                     */

      if (intnr & 1) {                 /* no interrupt pending             */
         return;
      }

      switch (intnr) {

         case(0):                      /* Modem status                     */
            mstat = inp(MODSTAT);      /* Read the status                  */
            break;

         case(2):                      /* Ready to transmit                */
            if (getbuf(&obuf, &ch))    /* If we have one to send           */
               outp(TXREG, ch);        /* send it                          */
            break;

         case(4):                      /* Received Data                    */
            ch = inp(RXREG);           /* read the char                    */
            putbuf(&ibuf, ch);         /* save it in buffer                */
            break;

         case(6):                      /* Line Status                      */
            lstat = inp(LINSTAT);
            if (lstat & 4)             /* Parity error                     */
               comerror = PARITY;
            else if (lstat & 8)        /* Framing eror                     */
               comerror = FRAME;
            else if (lstat & 16)       /* Break Interrupt                  */
               comerror = BREAK;
            break;
      }
   }
}
/*-------------------------------------------------------------------------*/



