home *** CD-ROM | disk | FTP | other *** search
/ World of Shareware - Software Farm 2 / wosw_2.zip / wosw_2 / CPROG / ASYNCPEC.ZIP / ASYNCPEC.C next >
C/C++ Source or Header  |  1989-05-03  |  11KB  |  304 lines

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