home *** CD-ROM | disk | FTP | other *** search
/ nisttime.carsoncity.k12.mi.us / nisttime.carsoncity.k12.mi.us.tar / nisttime.carsoncity.k12.mi.us / pub / acts / rdbuf.c < prev    next >
C/C++ Source or Header  |  1996-11-07  |  5KB  |  179 lines

  1. int rdbuf(ibuf,ie1,ie2,ie3,tmo)
  2. char ibuf[],ie1,ie2,ie3;
  3. int tmo;
  4. {
  5. /*
  6.     this subroutine reads characters from the serial line.  the
  7.     SUN version uses a loop on the system read call.  for the
  8.     IBMPC version if BIOS is defined, the read is done using
  9.     interrupt calls to the port defined by cmport.  if BIOS is not
  10.     defined, direct calls are made to the hardware using inport and
  11.     outport at the hardware address cmadr.  the characters are stored
  12.     in ibuf.  the operation continues until any one of the three line
  13.     terminators ie1, ie2 or ie3 is found.  the operation also ends
  14.     on the 280th character if no line terminator is found before that.
  15.     the input line is terminated by a zero byte; the last
  16.     character before the zero byte is the terminator.
  17.  
  18.     the parameter tmo is a time-out count.  if no character is
  19.     received before tmo goes to zero, the subroutine returns with
  20.     a count of zero (a time-out on a partial line will result in
  21.     the line being thrown away).  in this version (7 jan 92), the
  22.     time-out parameter is in units of ticks of the clock and the
  23.     elapsed time is measured directly by reading the clock rather
  24.     than by counting a variable that is scaled to the cpu speed
  25.     as in the previous versions.  the idea is to generate a time-
  26.     out loop that is less sensitive to the details of the cpu
  27.     speed estimator, which does not work consistently for many
  28.     of the 386/486 configurations
  29.  
  30.     the comparison against the terminating characters is made after
  31.     the 8th bit is cleared in the received character.  Thus if a
  32.     terminating character has its 8th bit on (i.e. is negative),
  33.     then it will never be matched and is effectively removed from
  34.     the comparison.
  35. */
  36. #include "nistime.h"
  37. #include <stdio.h>
  38. #ifdef IBMPC
  39. #include <dos.h>
  40. #endif
  41. #ifdef SUN
  42. #include <sys/ioctl.h>
  43. #endif
  44. extern int debug;
  45. int j;
  46. #ifdef IBMPC
  47. unsigned char stat,mstat;
  48. int k,kk;
  49. #endif
  50. char cc;
  51. #ifdef IBMPC
  52. #ifdef BIOS
  53. extern int cmport;
  54. #endif
  55. #ifndef BIOS
  56. extern int cmadr;
  57. #endif
  58. #endif
  59. int tcount;             /*used in time-out loop */
  60. #ifdef SUN
  61. extern int cmport;
  62. LONG k;
  63. LONG tlimit = -10000;
  64. #endif
  65.     j=0;            /*initialize buffer index */
  66. #ifdef SUN
  67.     tcount=tlimit;
  68. /*
  69.     loop until character is ready or tcount goes to 0
  70. */
  71.     do
  72.     {
  73.        do
  74.        {
  75.           ioctl(cmport,FIONREAD,&k);
  76.           tcount++;
  77.        } while( (tcount < 0 ) && (k < 1) ) ;
  78.        if(tcount == 0)
  79.           {
  80.           tcount=tlimit;
  81.           tmo++;
  82.           if(tmo == 0)
  83.         {
  84.         if(debug != 0)  /*show whatever we got ... */
  85.            {
  86.            ibuf[j]='\0';
  87.            printf("\n timeout in rdbuf, %d chars read. \n %s",
  88.             j,ibuf);
  89.            return (0);
  90.         }
  91.           }
  92.        }
  93.        else
  94.           {
  95.           read(cmport,&cc,1);
  96.           ibuf[j]= cc = cc & 0x7f;
  97.           j++;
  98.           tcount=tlimit;
  99.           }
  100.     } while( (j < 280) && (cc != ie1) && (cc != ie2) && (cc != ie3) );
  101. #endif
  102. #ifdef IBMPC
  103.     do                      /*loop over input character stream*/
  104.       {
  105.       tcount=tmo;           /*initialize time-out counter */
  106.       _AH=0;
  107.       geninterrupt(0x1a);
  108.       kk=_DX;                       /*get lower half of time*/
  109.       do
  110.        {
  111. /*
  112.        loop until character is available or tcount goes to 0.
  113. */
  114.        #ifdef BIOS
  115.        _AH=3;
  116.        _DX=cmport;
  117.        geninterrupt(0x14);
  118.        stat=_AH;
  119.        mstat=_AL;
  120.        #endif
  121.        #ifndef BIOS
  122.        stat=inportb(cmadr+lsreg);     /* read line status*/
  123.        mstat=inportb(cmadr+msreg);    /* read modem status*/
  124.        #endif
  125.        _AH=0;
  126.        geninterrupt(0x1a);
  127.        k=_DX;               /*get current lower half of time*/
  128.        if(k != kk)          /*if tick has changed */
  129.           {         /*increment counter, exit with time-out if it is 0*/
  130.           if(++tcount >= 0)
  131.         {
  132.         if(debug != 0)  /*show partial output, if any*/
  133.            {
  134.            ibuf[j]= '\0';
  135.            printf("\n timeout in rdbuf, %d chars rec'd.,\n %s",
  136.               j,ibuf);
  137.         }
  138.         return(0);
  139.           }
  140.           kk=k;             /*otherwise save new value of tick */
  141.        }
  142.        }  while ( (stat & 1) == 0);    /*while buffer is empty */
  143. /*      if we came out of previous loop, a character is ready
  144.     to be read
  145. */
  146.        #ifdef BIOS
  147.        _AH=2;
  148.        _DX=cmport;
  149.        geninterrupt(0x14);
  150.        cc=_AL;
  151.        #endif
  152.        #ifndef BIOS
  153.        cc=inportb(cmadr);
  154.        #endif
  155.        ibuf[j++]= cc= cc & '\x7f';    /* turn off ms bit */
  156. /*
  157.     if clear to send and carrier detect have been lost then
  158.     the fact that a character is ready to be read is an error
  159.     terminate line here. how can the hardware do this over
  160.     and over again ??
  161. */
  162.        if( (mstat && 0xb0) == 0)
  163.           {
  164.           ibuf[j]=0;
  165.           if(debug != 0) printf("\nCTS or DCD lost.");
  166.           return(j);
  167.        }
  168. /*
  169.     continue loop until one of terminators is found or until
  170.     280th character is read.  exit if any of these conditions
  171.     is satisfied, add terminating NULL to buffer and return
  172.     count of number of characters read
  173. */
  174.     } while ( (j < 280) && (cc != ie1) && (cc != ie2) && (cc != ie3));
  175. #endif
  176.     ibuf[j]=0;
  177.     return(j);
  178. }
  179.