home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c129 / 1.ddi / ASYNCXX.C next >
Encoding:
C/C++ Source or Header  |  1989-08-11  |  10.2 KB  |  302 lines

  1. /* asyncpec.c asynchronous com routine for Microsoft C 5.1  */
  2. /* Quinn-Curtis 1989 */
  3.  
  4. #include <bios.h>
  5. #include <dos.h>
  6. #include <string.h>
  7.  
  8. #define timeout  100000     /* Readln_com times out at 10000 milliseconds*/
  9. #define max_buffer  1000  /* Circular buffer size */
  10. #define near_full   900   /* When buffer_length exceeds near_full */
  11.                           /* RTS line is disabled */
  12. #define near_empty  100   /* When buffer drops below near_empty */
  13.                           /* RTS line is enabled */
  14. int  com_flag = 0;        /*Com open flag*/
  15.  
  16. int  overrun_flag;
  17. char  com_buffer[max_buffer]; /*Circular com buffer*/
  18. int   com_port;               /* Current Com port (0 or 1) */
  19. int  intlev;                  /* Hardware interrut level for com port */
  20. int  buffer_in;               /* Pointer for input to com buffer */
  21. int  buffer_out;              /* Pointer for output from com buffer */
  22. int  buffer_length;           /* Current number of characters in com buffer */
  23. int  bf_hndshk;               /* Handshake flag for control lines */
  24.  
  25. int  thr, rbr, ier, lcr,
  26.      mcr, lsr, msr;           /*Async com board registers*/
  27.  
  28. void far *oldfunc;  /* Holds old interrupt vector */
  29.  
  30. void delay(int d)
  31. /* d = delay in milliseconds on 10 MHz AT */
  32. { int i;
  33.   int j;
  34.   int k;
  35.   j = 0;
  36.   for (k=0; k<d; k++)
  37.     for (i=1; i<200; i++)
  38.     j += 1;
  39. }
  40.  
  41. void interrupt far com_isr()
  42. {
  43.   if (com_flag == 1) {
  44.     /*Get character - store in circular buffer*/
  45.     com_buffer[buffer_in] = inp(rbr);
  46.  
  47.     /*Increment buffer_in pointer*/
  48.     buffer_in += 1;
  49.  
  50.     /*Wrap buffer pointer around to start if > max_buffer*/
  51.     if (buffer_in == max_buffer)  buffer_in = 0;
  52.  
  53.     /*Current number of characters in buffer incremented 1*/
  54.     buffer_length +=  1;
  55.     if (buffer_length > max_buffer) {
  56.       buffer_length = max_buffer;
  57.       overrun_flag = 1;
  58.     }
  59.     /*Disable RTS if buffer_length exceeds near_full constant*/
  60.     if (buffer_length > near_full) {
  61.       outp(mcr, 9);          /*Disable rts , leave dtr and out2 set*/
  62.       bf_hndshk = 1;         /*Buffer full handshake = true*/
  63.     }
  64.   }
  65.   outp(0x20,0x20);   /* End of Interrupt to 8259 */
  66. }
  67.  
  68. void reset_buffer()
  69. /* This procedure will reset the com buffer */
  70. {
  71.  
  72.   bf_hndshk = 0;     /*Buffer full handshake false*/
  73.   buffer_in = 0;     /*Set circular buffer input to 0*/
  74.   buffer_out = 0;    /*Set circular buffer output to 0*/
  75.   buffer_length = 0; /*Set buffer_length to 0*/
  76.   overrun_flag = 0;  /*Set overrun flag to false */
  77. }
  78.  
  79.  
  80. void open_com(int Cport,    /*Com port # - 0 or 1          */
  81.               int baud,     /*baud rate - 110,150,300..9600*/
  82.               int parity,   /*parity 0 = no parity         */
  83.                             /*       1 = even parity       */
  84.                             /*       2 = odd parity        */
  85.               int stopbits, /*stop bits - 1 or 2           */
  86.               int numbits,  /*word length - 7 or 8         */
  87.               int *error_code )
  88. {
  89.    int comdata;
  90.    int ptemp;
  91.  
  92.         *error_code = 0;
  93.         com_port = Cport;
  94.         comdata = 0;
  95.         if ((numbits == 7) || (numbits == 8))
  96.                 comdata = comdata | (numbits-5) ;
  97.         else *error_code = 5;
  98.  
  99.         if ((stopbits == 2) || (stopbits == 1))
  100.                 comdata = comdata | (stopbits-1) << 2 ;
  101.         else *error_code = 4;
  102.  
  103.         if ((parity == 1) || (parity == 3) || (parity == 0))
  104.                 comdata = comdata | (parity << 3) ;
  105.         else *error_code = 3;
  106.  
  107.        switch (baud){
  108.                 case 110: comdata = comdata | 0x00;
  109.                         break;
  110.                 case 150: comdata = comdata | 0x20;
  111.                         break;
  112.                 case 300: comdata = comdata | 0x40;
  113.                         break;
  114.                 case 600: comdata = comdata | 0x60;
  115.                         break;
  116.                 case 1200: comdata = comdata | 0x80;
  117.                         break;
  118.                 case 2400: comdata = comdata | 0xA0;
  119.                         break;
  120.                 case 4800: comdata = comdata | 0xC0;
  121.                         break;
  122.                 case 9600 : comdata = comdata | 0xE0;
  123.                         break;
  124.                 default : *error_code = 2;
  125.                         break;
  126.      }
  127.      if ((Cport <0) || (Cport >1 ))
  128.        *error_code = 1;
  129.      if (*error_code == 0)
  130.         _bios_serialcom( 0,Cport, comdata);
  131.  
  132.      if (Cport == 0) {
  133.        thr = 0x3f8;                    /*Set register varibles*/
  134.        rbr = 0x3f8;                    /*for port locations of*/
  135.        ier = 0x3f9;                    /*serial com port #1*/
  136.        lcr = 0x3fb;
  137.        mcr = 0x3fc;
  138.        lsr = 0x3fd;
  139.        msr = 0x3fe;
  140.       }  else {
  141.        thr = 0x2f8;                    /*Set register variables*/
  142.        rbr = 0x2f8;                    /*for port locations of*/
  143.        ier = 0x2f9;                    /*serial com port #2*/
  144.        lcr = 0x2fb;
  145.        mcr = 0x2fc;
  146.        lsr = 0x2fd;
  147.        msr = 0x2fe;
  148.       }
  149.       intlev = 0xC - Cport;
  150.       oldfunc = _dos_getvect(intlev);
  151.       _dos_setvect(intlev, com_isr);
  152.       _disable();                       /*No interrupts*/
  153.       ptemp = inp(lcr) & 0x7f;
  154.       outp(lcr,ptemp);
  155.       ptemp = inp(lsr);            /*Reset any pending errors*/
  156.       ptemp = inp(rbr);            /*Read any pending character*/
  157.       if (Cport == 0) {                /*Set irq on 8259 controller*/
  158.         ptemp = inp(0x21) & 0xef;
  159.         outp(0x21,ptemp);
  160.       }
  161.       else {
  162.         ptemp = inp(0x21) & 0xf7;
  163.         outp(0x21,ptemp);
  164.       }
  165.       outp(ier,1);       /*Enable data ready interrupt*/
  166.       ptemp = inp(mcr) | 0xb;
  167.       outp(mcr,ptemp);
  168.       _enable();         /*Turn on interrupts*/
  169.       *error_code = 0;     /*Set error code to 0*/
  170.       com_flag = 1;      /*Com inititalization flag true*/
  171.       reset_buffer();
  172. }
  173.  
  174. void close_com()
  175. /* This procedure disables the com port interrupt. */
  176. {  int ptemp;
  177.   if (com_flag==1) {
  178.     _disable();                   /*No interrupts*/
  179.     ptemp = inp(0x21) | 0x18;
  180.     outp(0x21,ptemp);             /*Set mask register to turn off interrupt*/
  181.     ptemp = inp(lcr) | 0x7f;
  182.     outp(lcr,ptemp);              /*Turn off 8250 data ready interrupt*/
  183.     outp(ier,0);
  184.     outp(mcr,0);                  /*Disable out2 on 8250*/
  185.     _dos_setvect(intlev, oldfunc); /* return to old interrupt vector */
  186.     _enable();                     /*Turn on interrupts*/
  187.     com_flag = 0;
  188.   }
  189. }
  190.  
  191. void check_com(char *c, int *error_code)  /*error code for check_com       */
  192.                          /*   0 = no error                */
  193.                          /*   6 = no character available  */
  194.                          /*   7 = buffer overflow         */
  195.                          /*  10 = com port not initialized */
  196. /*This procedure returns 1 character from the com_buffer, at the array element*/
  197. /*pointed to by the circular buffer pointer buffer_out.                       */
  198.  
  199. {
  200.  if (com_flag == 0)  /*Make sure com port has been initialized*/
  201.    *error_code = 10;
  202.  else
  203.    {
  204.    if (buffer_length == 0)          /*Check to see if any characters in buffer*/
  205.       *error_code = 6;
  206.    else {
  207.      if (overrun_flag == 1)           /*buffer overflow */
  208.        *error_code = 7;
  209.      else *error_code = 0;
  210.      *c = (com_buffer[buffer_out]);   /*Get charater out of buffer*/
  211.      buffer_out += 1;                 /*Increment buffer_out_pointer*/
  212.                                       /*Wrap buffer_out pointer around if > */
  213.                                       /*max_buffer*/
  214.      if (buffer_out == max_buffer) buffer_out = 0;
  215.      buffer_length -= 1; /*Decrement buffer_length*/
  216.  
  217.      /*Enable RTS if buffer_length < near_empty*/
  218.      if (bf_hndshk && (buffer_length < near_empty)) {
  219.        outp(mcr,0xb);
  220.        bf_hndshk = 0;
  221.      }
  222.    }
  223.   }
  224. }
  225.  
  226.  
  227. void send_com(char c,        /*Character to send out com port*/
  228.               int *error_code)   /*Error code for send_com       */
  229.                                          /*  0 = no error                */
  230.                                          /*  8 = time out error          */
  231.                                          /* 10 = com port not initialized*/
  232. /*This procedure sends a character out the com port.                     */
  233.  
  234. {
  235.  int handshake;
  236.  long counter;
  237.  
  238.  if (com_flag == 0)  /*Make sure com port has been initialized*/
  239.    *error_code = 10;
  240.  else
  241.  {
  242.   counter = 0;         /* Initialize time out counter          */
  243.   handshake = 0x30;    /* Use the following handshake values:  */
  244.                        /*          0x0 no handshake            */
  245.                        /*          0x10 CTS handshaking         */
  246.                        /*          0x20 DSR handshaking         */
  247.                        /*          0x30 CTS and DSR handshaking */
  248.   do {
  249.     counter += 1;
  250.     delay(1);          /*delay 1 millisecond - causes timeout at 10 seconds*/
  251.   }
  252.   while
  253.        ((((inp(msr) & handshake) != handshake) ||   /*Check handshake*/
  254.          ((inp(lsr) & 0x20) != 0x20)) &&    /*Check that transmit reg empty*/
  255.           (counter < timeout));             /* Give up after 10 seconds */
  256.   if (counter == timeout)
  257.     *error_code = 8;
  258.   else
  259.   {
  260.     _disable();          /*No interrpts*/
  261.     outp(thr,c);        /*Transmit character*/
  262.     _enable();          /*Interrupts on*/
  263.     *error_code = 0;
  264.   }
  265.  }
  266. }
  267.  
  268.  
  269. void writeln_com(char *str,      /*string to send out com port*/
  270.                  int *error_code) /*error code for writeln_com*/
  271. {  int length;
  272.    int i;
  273.    length = strlen( str );
  274.  
  275.    for (i=0; i < length; i++){
  276.       send_com( str[i], error_code );
  277.    }
  278.   send_com(13,error_code);
  279. /* send_com(10,error_code); */ /* Send linefeed if required */
  280. }
  281.  
  282.  
  283. void readln_com(char *str,               /*string to received from com port*/
  284.                  int *error_code)           /*error code for writeln_com*/
  285. {  int i=0;
  286.    char c;
  287.    long counter = 0;
  288.    do {
  289.      check_com(&c,error_code);
  290.      if (*error_code == 0) {
  291.        str[i]=c;
  292.        i += 1;
  293.      }  else {
  294.        delay(1);
  295.        counter += 1;
  296.      }
  297.    } while ((i < 255) && (c != 13) && (counter < timeout));
  298.    if (counter == timeout) *error_code = 8;
  299.    str[i] = 0;
  300. }
  301.  
  302.