home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 3 Comm / 03-Comm.zip / MCOMM530.ZIP / ASYNC.DOC < prev    next >
Text File  |  1990-09-08  |  81KB  |  2,224 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.                 ASYNCHRONOUS FUNCTIONS FOR MICROSOFT C / TURBO C
  8.  
  9.  
  10.             The LIB(s) on the included disk are libraries of asynch-
  11.          ronous functions designed specifically for use with MicroSoft C
  12.          or Turbo C.  The registered version has LIBs for all memory
  13.          models.  The shareware version is small model only.
  14.  
  15.  
  16.                     --- Features of the library functions ---
  17.  
  18.             o Support for 16550 UART's FIFO mode of operation
  19.  
  20.             o Fully interrupt driven
  21.  
  22.             o Baud rates up to 115,200 baud
  23.  
  24.             o User defined transmit and receive ring buffer sizes.
  25.  
  26.             o Ring buffers may be in placed in FAR memory even in small
  27.               and medium model programs.
  28.  
  29.             o User defined port addresses, IRQ use, and interrupt vector
  30.               numbers.
  31.  
  32.             o Support for simultaneous operation of 2 ports.
  33.  
  34.             o Built in support for XON/XOFF and hardware flow control
  35.  
  36.             o Block transmit and receive functions
  37.  
  38.             o Receive buffer look ahead function
  39.  
  40.             o 100% assembler code for maximum speed
  41.  
  42.             o Totally compatible with MicroSoft C, Turbo C, and other C
  43.               compilers that use standard Microsoft high level language
  44.               calling conventions.
  45.  
  46.  
  47.          ---------------------------------------------------------------
  48.                 Mike Dumdei,  6 Holly Lane,  Texarkana TX  75503
  49.                     MCOMM5 (c) 1989, 1990 All Rights Reserved
  50.          ---------------------------------------------------------------
  51.  
  52.  
  53.  
  54.  
  55.  
  56.  
  57.                             NOTES ON 16550 FIFO MODE
  58.  
  59.             The 16550 UART is automatically detected and enabled when
  60.          async_open is called.  If, for some reason, you want to operate
  61.          a 16550 UART in non-FIFO mode, automatic detection and use can
  62.          be disabled.  See async_open for more information.
  63.  
  64.                           --- Use of receiver FIFOs ---
  65.  
  66.             The receiver trigger level may be programmed for 1, 4, 8, or
  67.          14 bytes by the async_FIFOrxlvl function.  When a port is first
  68.          opened the trigger is set to 1 byte.  There are 3 reasons why I
  69.          chose to default to a 1 byte receive trigger level.
  70.  
  71.             1) While a higher trigger level results in less CPU
  72.                overhead, it also provides less overrun protection if the
  73.                CPU is slow to respond.  For example, with a 1 byte
  74.                trigger level the 16550 -- when it generates an interrupt
  75.                -- can hold 15 more characters in its FIFOs before the
  76.                CPU responds.  With a 14 byte trigger level it will only
  77.                have room for 2 more characters.
  78.  
  79.             2) The MCOMM interrupt functions completely empty the
  80.                receiver FIFOs every time an interrupt occurs.  If the
  81.                CPU is slow to respond, the interrupt handler will
  82.                process 2,3,4.. characters (whatever is in the FIFOs)
  83.                whenever it does get control so the data still gets
  84.                buffered if the CPU isn't able to keep up.
  85.  
  86.             3) Setting the trigger level at higher trigger levels when
  87.                displaying incoming data to the screen will result in a
  88.                jerky looking display, especially at low baud rates.
  89.                Again, this is because MCOMM empties the buffer
  90.                completely when it processes the interrupt.  With a
  91.                trigger level other than 1, data stacks up in the FIFOs
  92.                until the trigger level is reached.  When the interrupt
  93.                finally occurs, all the data in the FIFOs is pulled out
  94.                and made available to the higher level functions at
  95.                one time.  The result is your code sits for 4, 8, or 14
  96.                bytes (whatever the trigger is) and then puts those bytes
  97.                on the screen in a burst.  It looks rough at low baud
  98.                rates.  At 9600 baud and above you could probably get by
  99.                with a slightly higher trigger level.
  100.  
  101.             For best use of the receive FIFOs, stick with 1 byte trigger
  102.          level when displaying data to the screen.  If your application
  103.          does not display the data or uses a high baud rate, you may
  104.          want to experiment with setting it to either 4 or 8 bytes.
  105.  
  106.  
  107.  
  108.  
  109.  
  110.  
  111.                           --- Use of transmit FIFOs ---
  112.  
  113.             The MCOMM transmit interrupt handler takes a parameter (set
  114.          by async_FIFOtxlvl) that is the maximum number of bytes to load
  115.          into the transmit FIFOs at one time.  The default value for
  116.          this parameter is 3 bytes.  The reason for not loading up the
  117.          FIFOs to maximum capacity (16 bytes) is flow control.  The
  118.          16550 UART will continue to transmit characters in its FIFOs
  119.          regardless of the state of CTS, DSR, or CD, or if an XOFF is
  120.          received.  It is totally up to the software to respond to
  121.          requests for flow control.  If the FIFOs are loaded with more
  122.          bytes than the receiver can handle when it invokes flow
  123.          control, the receiver gets overwritten.  There is a bit that
  124.          can be sent to the UART to flush the transmit FIFOs but then it
  125.          is impossible to tell what was flushed and what was sent.  The
  126.          solution is to not the load the FIFOs up so full.  If the
  127.          receiving device can handle more than 3 characters of overrun,
  128.          use a larger value.  If the application does not require flow
  129.          control, you can use a 16 byte level with no problems.
  130.  
  131.             Another factor to consider concerning the transmit FIFO byte
  132.          level is that (from the NS Data Communications/LAN/UART
  133.          Handbook) the transmit FIFO empty empty indication will be
  134.          delayed by 1 character time minus the last stop bit until there
  135.          are at least 2 bytes in the transmit FIFOs simultaneously for
  136.          the current transmit operation.  After the 2 byte requirement
  137.          is met the transmit interrupt occurs immediately when the
  138.          transmit FIFOs empty.  Using a value of 3 or above (1 byte for
  139.          the transmit shift register and 2 for the FIFO registers)
  140.          guarantees the interrupt delay is deactivated.  Once the '2
  141.          bytes in the FIFOs' requirement is met, the transmit byte level
  142.          can be reduced if necessary.
  143.  
  144.  
  145.  
  146.  
  147.  
  148.  
  149.                                  GETTING STARTED
  150.  
  151.          All functions included in this library are listed on the fol-
  152.          lowing pages in alphabetical order.  The basic functions needed
  153.          to begin are: async_open, async_tx, async_rx, and async_close.
  154.          Using these four functions alone, it is possible to write a
  155.          complete communications program.
  156.  
  157.          Functions are also available to support XON/XOFF and hardware
  158.          flow control, the 16550 UART, block transmit and receive,
  159.          receive buffer look ahead, and several other features.
  160.  
  161.          All functions take a pointer to an ASYNC structure for one of
  162.          its arguments.  This structure is defined in COMM.H.  It
  163.          may be helpful to think of this structure as being similar to
  164.          the standard C library 'FILE *'.
  165.  
  166.          If you have been using versions of these routines prior to
  167.          version 5.00, there have been some changes made that will
  168.          require you to make some modifications to any existing code
  169.          before it can be used with the new libraries.  The main
  170.          differences are:
  171.  
  172.             > Async_open takes different parameters.  Also, instead
  173.               of the open function automatically allocating the ring
  174.               buffers for you, you provide the ring buffers.
  175.  
  176.             > All functions now take a pointer to an ASYNC structure
  177.               as the first argument rather than 0 (COM1) or 1 (COM2).
  178.  
  179.             > LITES is no longer supported.
  180.  
  181.  
  182.  
  183.  
  184.  
  185.  
  186.                       REGISTRATION AND DISTRIBUTION POLICY
  187.  
  188.             MCOMM5, the various versions of Smalterm, the ANSI video
  189.          routines, and other miscellaneous functions contained in the
  190.          COMM_x libraries are distributed as shareware.  If you use
  191.          these functions regularly please take time to register them.
  192.  
  193.             Two types of registration are available for MCOMM5.  The
  194.          first is $25 and includes assembled libraries for all memory
  195.          models.  No source code is included with a $25 registration.
  196.          The second type of registration costs $45 and includes lib-
  197.          raries and source code.  Previous versions were $25 for source
  198.          code and libraries.  If you send $25 and want source code based
  199.          on previous offers, you will receive a previous version of the
  200.          source.  Registered users as of 8-1-89 may upgrade their lib-
  201.          raries at any time for $3 or upgrade to the new source code
  202.          version for $10.
  203.  
  204.             I also have developed a version of these routines for use
  205.          with the DigiBoard(r) COM4 and COM8 boards that support up to
  206.          32 DigiBoard ports and 1 standard port simultaneously.  Please
  207.          contact me if you are interested in this product.  It is $35
  208.          for libraries only.  No source is available for the DigiBoard
  209.          version.
  210.  
  211.             This software is provided as is without warranty as to its
  212.          fitness for a particular use or being free of errors.  I assume
  213.          no liability for any loss or damages you may incur through its
  214.          use.  I will, however, make every effort to correct any
  215.          software errors that may exist, and provide you with a working
  216.          version.
  217.  
  218.             I will continue to assist registered and non-registered
  219.          users whenever possible.  If you have any problems using these
  220.          routines or questions, I may be contacted at:
  221.             Split Up the Middle BBS   --  214 838-6713 (modem)
  222.             Mike Dumdei               --  214 838-8307 (voice)
  223.  
  224.  
  225.  
  226.  
  227.  
  228.  
  229.          async_16550
  230.          ---------------------------------------------------------------
  231.  
  232.          Purpose: Check if 16550 UART was detected in system.
  233.  
  234.          Format:  int async_16550(port);
  235.                    ASYNC *port;       Pointer to ASYNC structure
  236.  
  237.          Example:
  238.  
  239.                   ASYNC *port;
  240.                   int is_16550;
  241.  
  242.                   is_16550 = async_16550(port);
  243.  
  244.          Returns: Returns zero if a 16550 is not in the system or the
  245.                   'ignore 16550 bit' was set when async_open was called.
  246.                   Returns NZ if a 16550 was found.  Async_open must be
  247.                   called before this function is valid.  If a 16550 is
  248.                   found, it will be placed in the FIFO mode of operation
  249.                   by async_open unless '16550 detect' was overridden.
  250.  
  251.          Remarks: This function is implemented as a macro.
  252.  
  253.                   See async_open.
  254.  
  255.  
  256.  
  257.  
  258.  
  259.  
  260.          async_breakrxd
  261.          ---------------------------------------------------------------
  262.  
  263.          Purpose: Checks if a break signal has been received.
  264.  
  265.          Format:  int async_breakrxd(port);
  266.                    ASYNC *port;       Pointer to ASYNC structure
  267.  
  268.          Example:
  269.  
  270.                   ASYNC *port;
  271.                   int break_status;
  272.  
  273.                   break_status = async_breakrxd(port);
  274.  
  275.  
  276.          Returns: If a break signal has been received the function
  277.                   returns a non-zero value.  If a break has not been
  278.                   detected, zero is returned.
  279.  
  280.          Remarks: Once a break signal has been detected, this function
  281.                   continually returns non-zero values until async_reset
  282.                   is called.  If a break is received, a line status
  283.                   register interrupt is generated.  The interrupt
  284.                   handler sets a bit in the Stat1 port structure member.
  285.                   The async_breakrxd function is a macro that checks the
  286.                   status of this bit.
  287.  
  288.                   See also async_reset, async_rx, async_stat,
  289.                   async_sndbrk.
  290.  
  291.  
  292.  
  293.  
  294.  
  295.  
  296.          async_carrier
  297.          ---------------------------------------------------------------
  298.  
  299.          Purpose: Check for the presence of a carrier.
  300.  
  301.          Format:  int async_carrier(port);
  302.                    ASYNC *port;       Pointer to ASYNC structure
  303.  
  304.          Example:
  305.  
  306.                   ASYNC *port;
  307.                   int carrier_status;
  308.  
  309.                   carrier_status = async_carrier(port);
  310.  
  311.  
  312.          Returns: A non-zero value is returned if a carrier is present.
  313.                   If the carrier detect line is LOW, zero is returned.
  314.  
  315.          Remarks: This function is implemented as a macro.  See also
  316.                   async_rx and async_stat.
  317.  
  318.  
  319.  
  320.  
  321.  
  322.  
  323.          async_close
  324.          ---------------------------------------------------------------
  325.  
  326.          Purpose: Closes a port opened by async_open.
  327.  
  328.          Format:  int async_close(port);
  329.                    ASYNC *port;    Pointer to ASYNC structure
  330.  
  331.          Example:
  332.  
  333.                   ASYNC port;
  334.                   async_close(&port);
  335.  
  336.          Returns: No return value
  337.  
  338.          Remarks: Do not attempt to close an unopened port.  Some
  339.                   minimal checking is done internally by async_close in
  340.                   an attempt to detect whether or not the specified port
  341.                   is actually opened.  If an unopened port makes it past
  342.                   those checks and the main close routine is entered,
  343.                   the system may lock up (immediately, 2 hours later, or
  344.                   never).  When a port is closed the UART registers,
  345.                   interrupt controller mask, and interrupt vectors are
  346.                   restored to the value they had when async_open was
  347.                   called.  It is possible to close the port and leave
  348.                   various signals (DTR for one) in the state you desire
  349.                   rather than in their initial state.  See async_dtr and
  350.                   async_rts for some examples on how to do this.
  351.  
  352.                   The B_ORGFIFO bit in the ASYNC 'Stat3' structure
  353.                   member is used by async_close to return the 16550 --
  354.                   if present -- to the mode it was in when async_open
  355.                   was called.  FIFOs may be 'forced' to remain enabled
  356.                   or 'forced' to be disabled when closing the port by
  357.                   first setting or resetting this bit.  Ex:
  358.  
  359.                     Force off:    port->Stat3 &= ~B_ORGFIFO;
  360.                                   async_close(port);
  361.  
  362.                     Force on:     port->Stat3 |= B_ORGFIFO;
  363.                                   async_close(port);
  364.  
  365.  
  366.  
  367.  
  368.  
  369.  
  370.          async_cts
  371.          ---------------------------------------------------------------
  372.  
  373.          Purpose: Check status of the Clear to Send signal.
  374.  
  375.          Format:  int async_cts(port);
  376.                    ASYNC *port;       Pointer to ASYNC structure
  377.  
  378.          Example:
  379.  
  380.                   ASYNC *port;
  381.                   int cts_status;
  382.  
  383.                   cts_status = async_cts(port);
  384.  
  385.          Returns: Returns zero if Clear To Send is LOW.  If CTS is HIGH,
  386.                   a non-zero value is returned.
  387.  
  388.          Remarks: This function is implemented as a macro.
  389.  
  390.  
  391.  
  392.  
  393.  
  394.  
  395.          async_dsr
  396.          ---------------------------------------------------------------
  397.  
  398.          Purpose: Check status of the Data Set Ready signal.
  399.  
  400.          Format:  int async_dsr(port);
  401.                    ASYNC *port;       Pointer to ASYNC structure
  402.  
  403.          Example:
  404.  
  405.                   ASYNC *port;
  406.                   int dsr_status;
  407.  
  408.                   dsr_status = async_dsr(port);
  409.  
  410.          Returns: Returns zero if Data Set Ready is LOW.  If DSR is
  411.                   HIGH, a non-zero value is returned.
  412.  
  413.          Remarks: This function is implemented as a macro.
  414.  
  415.  
  416.  
  417.  
  418.  
  419.  
  420.          async_dtr
  421.          ---------------------------------------------------------------
  422.  
  423.          Purpose: Set or reset the Data Terminal Ready signal.
  424.  
  425.          Format:  void async_dtr(port, DTRflag);
  426.                    ASYNC *port;       Pointer to ASYNC structure
  427.                    int DTRflag;       Set/Reset DTR flag
  428.  
  429.          Example:
  430.  
  431.                   ASYNC *port;
  432.  
  433.                   if (WantToDropDTR)
  434.                       async_dtr(port, 0);
  435.                   else if (WantDTRhigh)
  436.                       async_dtr(port, 1);
  437.  
  438.  
  439.          Returns: No return value
  440.  
  441.          Remarks: This signal is set HIGH when a port is first opened.
  442.                   When the port is closed, it is restored to the cond-
  443.                   ition it was in when the port was opened.  To force
  444.                   DTR low when a port is closed, regardless of its state
  445.                   when the port was opened, AND the port member, OldMCR,
  446.                   with NOT B_DTR.  To force DTR to remain high when the
  447.                   port is closed, OR OldMCR with B_DTR.
  448.  
  449.                     Force low:    port->OldMCR &= ~B_DTR;
  450.                                   async_close(port);
  451.  
  452.                     Force high:   port->OldMCR |= B_DTR;
  453.                                   async_close(port);
  454.  
  455.  
  456.  
  457.  
  458.  
  459.  
  460.          async_FIFOrxlvl  <5.20 addition>
  461.          ---------------------------------------------------------------
  462.  
  463.          Purpose: Set the 16550 UART's receive trigger level.
  464.  
  465.          Format:  void async_FIFOrxlvl(port, trigger_lvl);
  466.                    ASYNC *port;       Pointer to ASYNC structure
  467.                    int trigger_lvl;   Rx FIFO interrupt trigger level
  468.  
  469.          Example:
  470.  
  471.                   ASYNC *port;
  472.  
  473.                    /* set the receiver trigger level to 8 bytes */
  474.                   async_FIFOrxlvl(port, 8);
  475.  
  476.          Returns: No return value
  477.  
  478.          Remarks: Valid values for 'trigger_lvl' are 1, 4, 8, and 14
  479.                   bytes.  When a port with a 16550 UART is first opened,
  480.                   the trigger level is set to 1 byte.  See the
  481.                   discussion on 'Use of receiver FIFOs' at the beginning
  482.                   of this document.  This function has no effect if the
  483.                   FIFOs were not enabled when async_open was called.
  484.  
  485.  
  486.  
  487.  
  488.  
  489.  
  490.          async_FIFOtxlvl  <5.20 addition>
  491.          ---------------------------------------------------------------
  492.  
  493.          Purpose: Set the number of bytes loaded into the 16550 UART's
  494.                   transmit FIFOs when a transmit interrupt occurs.
  495.  
  496.          Format:  void async_FIFOtxlvl(port, bytes);
  497.                    ASYNC *port;       Pointer to ASYNC structure
  498.                    int bytes;         # of bytes to load into tx FIFOs
  499.  
  500.          Example:
  501.  
  502.                   ASYNC *port;
  503.  
  504.                    /* set the transmit FIFO byte level to 16 bytes */
  505.                   async_FIFOrxlvl(port, 16);
  506.  
  507.          Returns: No return value
  508.  
  509.          Remarks: Valid values for 'bytes' are 1 through 16 bytes.  When
  510.                   a port with a 16550 UART is first opened, the transmit
  511.                   level byte count is set to 3 bytes.  See the
  512.                   discussion on 'Use of transmit FIFOs' at the beginning
  513.                   of this document.  This function has no effect if the
  514.                   FIFOs were not enabled when async_open was called.
  515.  
  516.  
  517.  
  518.  
  519.  
  520.  
  521.          async_ignerr
  522.          ---------------------------------------------------------------
  523.  
  524.          Purpose: Set or reset 'ignore characters with errors' bit
  525.  
  526.          Format:  void async_ignerr(port, flag);
  527.                    ASYNC *port;       Pointer to ASYNC structure
  528.                    int flag;          Set/Reset flag
  529.  
  530.          Example:
  531.  
  532.                   ASYNC *port;
  533.  
  534.                   if (WantToDiscardErrChars)
  535.                       async_ignerr(port, 1);
  536.                   else if (WantToKeepErrChars)
  537.                       async_ignerr(port, 0);
  538.  
  539.  
  540.          Returns: No return value
  541.  
  542.          Remarks: This function sets the bit that determines what hap-
  543.                   pens to received characters that have parity or fram-
  544.                   ing errors.  If the function is called with the flag
  545.                   set to one, incoming characters that have framing or
  546.                   parity errors are discarded -- they do not get put
  547.                   into the receive ring buffer.  If the flag is 0, char-
  548.                   acters with errors are not ignored, they are put into
  549.                   the ring buffer.  The error bits in Stat1 that reflect
  550.                   these error conditions are set regardless of the
  551.                   setting of the discard flag.  When a port is first
  552.                   opened, the flag is set to 0.  This function is imple-
  553.                   mented as a macro.
  554.  
  555.                   See also async_stat.
  556.  
  557.  
  558.  
  559.  
  560.  
  561.  
  562.          async_msr
  563.          ---------------------------------------------------------------
  564.  
  565.          Purpose: Get the contents of the Modem Status Register.
  566.  
  567.          Format:  int async_msr(port);
  568.                    ASYNC *port;       Pointer to ASYNC structure
  569.  
  570.          Example:
  571.  
  572.                   ASYNC *port;
  573.                   int MSRcontents;
  574.  
  575.                   MSRcontents = async_msr(port);
  576.  
  577.  
  578.          Returns: The contents of the Modem Status Register.
  579.  
  580.          Remarks: This function is a macro that returns the port struc-
  581.                   ture member, MSRVal.  This value is initialized when a
  582.                   port is first opened and then updated any time a modem
  583.                   status interrupt occurs.  The reason the MSR is not
  584.                   read directly is to avoid inadvertently intercepting a
  585.                   pending MSR interrupt.  All bits returned except for
  586.                   the delta bits reflect the true current status.
  587.  
  588.  
  589.  
  590.  
  591.  
  592.  
  593.          async_msrflow
  594.          ---------------------------------------------------------------
  595.  
  596.          Purpose: Enables or disables hardware flow control.
  597.  
  598.          Format:  void async_msrflow(port, flowmask);
  599.                    ASYNC *port;       Pointer to ASYNC structure
  600.                    int flowmask;      Bit mapped flow control mask
  601.  
  602.          Example:
  603.  
  604.                   ASYNC *port;
  605.  
  606.                   if (enable_RTS_CTS_handshake)
  607.                       async_msrflow(port, B_CTS);
  608.                   else if (disable_handshake)
  609.                       async_msrflow(port, 0);
  610.  
  611.          Returns: No return value
  612.  
  613.          Remarks: The flow mask is a bit mapped value of the signal that
  614.                   is monitored by the receiver when performing flow
  615.                   control.  Bits that may be monitored are B_CTS, B_DSR,
  616.                   and B_CD.  This provides capability for RTS/CTS hand-
  617.                   shake, DTR/DSR handshake, and handshaking with the
  618.                   carrier detect line.  To monitor multiple signals, OR
  619.                   the bits together.  Both hardware flow control and
  620.                   XON/XOFF flow control may be enabled at the same time.
  621.  
  622.                   See async_xflow.
  623.  
  624.  
  625.  
  626.  
  627.  
  628.  
  629.          async_open  <5.20 modified -- see Remarks at end of function>
  630.          ---------------------------------------------------------------
  631.  
  632.          Purpose: Initializes the hardware, interrupt vector, and ASYNC
  633.                   port structure for interrupt driven operation.
  634.  
  635.          Format:
  636.                   int async_open(port, base, irqmask, vctrnbr, params);
  637.                    ASYNC *port;   Pointer to ASYNC structure
  638.                    int base;      Base port address of UART chip
  639.                    int irqmask;   8259 mask value for selected IRQ line
  640.                    int vctrnbr;   Number of selected interrupt vector
  641.                    char *params;  Baud, parity, data, & stop bits in
  642.                                    string format
  643.  
  644.          Entry:   Before calling this function you must allocate ring
  645.                   buffer memory and pre-initialize the following ASYNC
  646.                   structure members:
  647.  
  648.                    RxSize : the size that you want the receive ring
  649.                       buffer to be.  The memory allocated or set aside
  650.                       for the receive ring buffer must be contiguous
  651.                       with the memory used for the transmit  ring
  652.                       buffer.  In most cases (RxSize + TxSize) bytes
  653.                       will be allocated using some form of malloc.
  654.                       A function to do this is included in the examples.
  655.                       The combined size of RxSize + TxSize can not
  656.                       exceed 32K - 1.
  657.  
  658.                    TxSize : the size of the transmit buffer in bytes.
  659.                       As stated above, the transmit and receive buffers
  660.                       for each individual port must be allocated as one
  661.                       contiguous block.
  662.  
  663.                    RingSeg: the segment address of the memory allocated
  664.                       for the receive and transmit buffers.  FAR memory
  665.                       can be used for the receive and transmit buffers
  666.                       by using your compiler library's version of FAR
  667.                       malloc and putting the segment portion (high 16
  668.                       bits) of the returned memory pointer in RingSeg.
  669.                       If you are using a NEAR data model program and
  670.                       want NEAR ring buffers, set RingSeg equal to 0.
  671.                       With RingSeg set to zero, the open function will
  672.                       use the DS segment register for RingSeg.  Using
  673.                       FAR ring buffers causes no loss of performance.
  674.  
  675.  
  676.  
  677.  
  678.  
  679.  
  680.          async_open
  681.          ---------------------------------------------------------------
  682.  
  683.          Entry (continued):
  684.  
  685.                   RingOfst: the offset address of the memory allocated
  686.                       for the receive and transmit buffers.  This value,
  687.                       in conjunction with the RxSize and TxSize vari-
  688.                       ables, is used to set up the receive and transmit
  689.                       ring buffers.
  690.  
  691.                   THE FOLLOWING FUNCTION IS INCLUDED WITH MCOMM5 AND IS
  692.                   RECOMMENDED FOR ALLOCATING RING BUFFER MEMORY AND
  693.                   INITIALIZING THE ABOVE VARIABLES.
  694.  
  695.          #ifdef (__TURBOC__)
  696.             #define _fmalloc farmalloc    /* Turbo C's far malloc */
  697.          #endif
  698.  
  699.          int AllocRingBuffer(
  700.           ASYNC *port,                  /* pointer to port structure */
  701.           int rxsize,      /* number bytes to use for receive buffer */
  702.           int txsize,     /* number bytes to use for transmit buffer */
  703.           int useFARmem)    /* flag set if using FAR mem for buffers */
  704.          {
  705.             unsigned long memptr;
  706.             int memsize;
  707.  
  708.             memsize = rxsize + txsize;
  709.  
  710.             if (useFARmem || sizeof(char *) == 4)/* if FAR Ring bufs */
  711.                memptr = (unsigned long)_fmalloc(memsize);
  712.             else                  /* if Ring buffers use NEAR memory */
  713.                memptr = (unsigned long)(unsigned int)malloc(memsize);
  714.  
  715.              /* pre-initialize 4 required structure members */
  716.             port->RxSize = rxsize;            /* receive buffer size */
  717.             port->TxSize = txsize;           /* transmit buffer size */
  718.             port->RingSeg = (int)(memptr >> 16);          /* SEG adr */
  719.             port->RingOfst = (int)memptr;            /* OFST address */
  720.             if (memptr == 0L)
  721.                return 0;          /* return 0 if no memory available */
  722.             return 1;                   /* return 1, had some memory */
  723.          }
  724.  
  725.  
  726.  
  727.  
  728.  
  729.  
  730.          async_open
  731.          ---------------------------------------------------------------
  732.  
  733.          Example 1:
  734.  
  735.             /*
  736.                Open COM1 at 2400,N,8,1 using FAR ring buffers. COM1 is
  737.                defined in COMM.H as:  0x3f8, 0x10, 12.  It is not
  738.                necessary to check the return value of AllocRingBuffer
  739.                since async_open will return R_NOMEM if the memory
  740.                allocation function fails.
  741.             */
  742.  
  743.             #include "comm.h"
  744.  
  745.             ASYNC port;
  746.             int rcode;
  747.  
  748.             AllocRingBuffer(&port, 24000, 8000, 1);
  749.  
  750.             rcode = async_open(&port, COM1, "2400N81");
  751.           /**  or
  752.             rcode = async_open(&port, 0x3f8, 0x10, 12, "2400N81");
  753.            **  or
  754.             rcode = async_open(&port, 0x3f8, IRQ4, VCTR4, "2400N81");
  755.            **/
  756.  
  757.             if (rcode != R_OK)
  758.             {
  759.                 printf("\nAsync_open failed, exit code = %d", rcode);
  760.                 exit(rcode);
  761.             }
  762.  
  763.  
  764.  
  765.  
  766.  
  767.  
  768.          async_open
  769.          ---------------------------------------------------------------
  770.  
  771.          Example 2:
  772.  
  773.             /*
  774.                Open a port located at 0x2e0 that uses IRQ3.  In this
  775.                case NEAR ring buffers are specified and the memory for
  776.                the port structure is obtained using malloc.  See the
  777.                AllocRingBuffer function described previously.
  778.             */
  779.  
  780.             #include "comm.h"
  781.  
  782.             ASYNC *port;
  783.             int rcode;
  784.  
  785.             if ((port = (ASYNC *)malloc(sizeof ASYNC)) == NULL)
  786.             {
  787.                 printf("\nNot enough memory");
  788.                 exit(R_NOMEM);
  789.             }
  790.  
  791.             AllocRingBuffer(port, 4096, 1200, 0);
  792.  
  793.             rcode = async_open(port, 0x2e0, IRQ3, VCTR3, "115200E71");
  794.  
  795.             if (rcode != R_OK)
  796.             {
  797.                 printf("\nAsync_open failed, exit code = %d", rcode);
  798.                 exit(rcode);
  799.             }
  800.  
  801.  
  802.  
  803.  
  804.  
  805.  
  806.          async_open
  807.          ---------------------------------------------------------------
  808.  
  809.          Example 3:
  810.  
  811.             /*
  812.                Open both COM1 and COM2 at the same time.  You can open
  813.                two ports at once as long as they don't share the same
  814.                IRQ line or interrupt vector.
  815.             */
  816.  
  817.             #include "comm.h"
  818.  
  819.             ASYNC ports[2], *port[2];
  820.             int rcode;
  821.  
  822.             port[0] = &ports[0], port[1] = &ports[1];
  823.  
  824.             AllocRingBuffer(port[0], 10240, 10240, 1);
  825.             rcode = async_open(port[0], COM1, "9600N81");
  826.             if (rcode != R_OK)
  827.             {
  828.                 printf("\nAsync_open failed, exit code = %d", rcode);
  829.                 exit(rcode);
  830.             }
  831.  
  832.             AllocRingBuffer(port[1], 10240, 10240, 1);
  833.             rcode = async_open(port[1], COM2, "1200E71");
  834.             if (rcode != R_OK)
  835.             {
  836.                 printf("\nAsync_open failed, exit code = %d", rcode);
  837.                 exit(rcode);
  838.             }
  839.  
  840.  
  841.  
  842.  
  843.  
  844.  
  845.          async_open
  846.          ---------------------------------------------------------------
  847.  
  848.          Example 4:
  849.  
  850.             /*
  851.                Open COM1 using its current baud, parity, data, and
  852.                stop bit settings.  The port structure member, BPDSstr,
  853.                will reflect those settings after calling async_open.
  854.             */
  855.  
  856.             #include "comm.h"
  857.  
  858.             ASYNC *port;
  859.             int rcode;
  860.  
  861.              /* alloc port structure & ring buffer memory */
  862.             port = malloc(sizeof(ASYNC));
  863.             AllocRingBuffer(port, 4096, 2048, 1);
  864.  
  865.              /* empty parameter string causes port to be opened at
  866.                 its current settings  */
  867.             rcode = async_open(port, COM1, "");
  868.  
  869.             if (rcode != R_OK)
  870.             {
  871.                 printf("\nAsync_open failed, exit code = %d", rcode);
  872.                 exit(rcode);
  873.             }
  874.  
  875.             printf(
  876.              "\nBaud, parity, data, stop bits = %s\n", port->BPDSstr);
  877.  
  878.  
  879.  
  880.  
  881.  
  882.  
  883.          async_open
  884.          ---------------------------------------------------------------
  885.  
  886.          Returns:
  887.  
  888.                   R_OK (0) - the port was opened with no errors.
  889.  
  890.                   R_NOMEM - a NULL pointer was passed as the address
  891.                       of the ring buffers.  Probable causes are either
  892.                       failing to initialize the port structure ring
  893.                       buffer variables or assigning the RingSeg and
  894.                       RingOfst structure a NULL pointer.  This could
  895.                       occur if you use the AllocRingBuffer function or
  896.                       something similar and the call to malloc fails.
  897.  
  898.                   R_BAUDERR - the passed baud rate in the BPDS string
  899.                       was invalid.  Some possible reasons for this error
  900.                       are leading spaces in the parameter string or use
  901.                       of commas.  "115200N81" is correct. " 115200N81"
  902.                       and "115,200N81" are both incorrect.
  903.  
  904.                   R_PARITYERR - an invalid character was found in the
  905.                       parameter string where the parity should have
  906.                       been.  Commas or spaces in the parameter string
  907.                       are possible causes.  Valid parity settings are N
  908.                       - none, E - even, or O - odd.  See R_BAUDERR.
  909.  
  910.                   R_DTABITERR - an invalid number of data bits was spec-
  911.                       ified.  Only settings of 7 or 8 are supported.
  912.  
  913.                   R_STPBITERR - an invalid number of stop bits was spec-
  914.                       ified.  Stop bits must be set to either 1 or 2.
  915.  
  916.                   R_IRQUSED - an attempt was made to open two ports that
  917.                       use the same IRQ line.
  918.  
  919.                   R_VCTRUSED - an attempt was made to open two ports
  920.                       that use the same interrupt vector.
  921.  
  922.                   R_NOPORT - an attempt was made to open more than 2
  923.                       simultaneous ports.
  924.  
  925.                   R_PORTUSED - an attempt was made to open two ports
  926.                       that have the same I/O address.
  927.  
  928.  
  929.  
  930.  
  931.  
  932.  
  933.          async_open
  934.          ---------------------------------------------------------------
  935.  
  936.          Remarks (16550 support):
  937.  
  938.                   This function now automatically detects the presence
  939.                   of a 16550 UART and enables FIFO operation if one is
  940.                   detected.  If the FIFOs were already enabled when
  941.                   async_open is called they are not reset and the
  942.                   currently active receive buffer trigger level is used.
  943.                   If the FIFOs were not enabled, they are enabled and
  944.                   the receive trigger level is set to 1 byte.  This
  945.                   feature can be overridden by setting the high bit of
  946.                   the async_open 'port address' parameter.  If this bit
  947.                   is set, no attempt is made to detect a 16550 and no
  948.                   changes are made to the mode of operation of the 16550
  949.                   if one is present.  If you do choose to set this bit,
  950.                   none of the functions or bits relating to the 16550
  951.                   UART will be valid.
  952.  
  953.                     /* detect 16550 enabled */
  954.                   async_open(PortPtr, 0x3f8, IRQ, Vector, Params);
  955.  
  956.                    /* detect 16550 disabled */
  957.                   async_open(PortPtr, 0x8000|0x3f8, IRQ, Vctr, Params);
  958.  
  959.  
  960.                   To open a port that has a 16550 and force it to
  961.                   operate in non-FIFO mode:
  962.  
  963.                     ChipIOAdrs = 0x3f8;  /* COM1 for this example */
  964.  
  965.                      /* if FIFOs enabled shut them off */
  966.                     if (async_regs(ChipIOAdrs, FCRreg, RDreg) & 0xc0)
  967.                         async_regs(ChipIOAdrs, FCRreg, 0);
  968.  
  969.                      /* open port with 'ignore 16550 bit' set */
  970.                     async_open(PortPtr, ChipIOAdrs | 0x8000, IRQ,
  971.                      Vector, Params);
  972.  
  973.  
  974.  
  975.  
  976.  
  977.  
  978.          async_open
  979.          ---------------------------------------------------------------
  980.  
  981.          Remarks (versions previous to 5.00):
  982.  
  983.                   There are some major differences in the async_open
  984.                   function in MCOMM5 and previous versions of the rou-
  985.                   tines.  The two most major ones are that the parame-
  986.                   ters passed to the function are different and it is
  987.                   now necessary to allocate the memory for the ring
  988.                   buffers before calling the function.  To make things
  989.                   simpler, COM1 and COM2 are defined in COMM.H and the
  990.                   function, AllocRingBuffer, is provided.  The COM1 and
  991.                   COM2 definitions satisfy the requirements for the 2nd,
  992.                   3rd, and 4th parameters required by the function.  For
  993.                   ports other than the standard COM1 and COM2, it is
  994.                   necessary to list the individual arguments.  The func-
  995.                   tion, AllocRingBuffer, is provided in C source form on
  996.                   the disk.  This function allocates the ring buffer
  997.                   memory and initializes the required port structure
  998.                   members.  If the version of the async LIBs you are
  999.                   using has a batch file to modify the libraries to work
  1000.                   with Turbo C or Microsoft C, this function is also
  1001.                   included in compiled form in the libraries.
  1002.  
  1003.                   The return values for async_open are different and may
  1004.                   have a different meaning than in earlier versions.
  1005.  
  1006.                   If a port is opened with an empty parameter string
  1007.                   (using "" for the parameters), then the port is opened
  1008.                   at its current settings and the port member BPDSstr is
  1009.                   set to the string representation of those values.
  1010.  
  1011.                   Async_open no longer checks the BIOS ram area at 40:0
  1012.                   to verify that a port actually exists.  There were too
  1013.                   many compatibles that did not store the proper values
  1014.                   there.
  1015.  
  1016.                   The maximum combined size of the receive and transmit
  1017.                   buffers for each port is 32K - 1.
  1018.  
  1019.                   FAR ring buffers in small and medium memory model
  1020.                   programs is now supported.  Use of FAR buffers does
  1021.                   not in any way affect the speed of the routines.
  1022.  
  1023.  
  1024.  
  1025.  
  1026.  
  1027.  
  1028.          async_peek
  1029.          ---------------------------------------------------------------
  1030.  
  1031.          Purpose: Indexed receive ring buffer look ahead function.
  1032.  
  1033.          Format:  int async_peek(port, index);
  1034.                    ASYNC *port;       Pointer to ASYNC structure
  1035.                    int index;         Index value
  1036.  
  1037.          Examples:
  1038.  
  1039.                   ASYNC *port;
  1040.                   char ch, buf[10];
  1041.                   int i;
  1042.  
  1043.                    /* peek next char in receive ring buffer */
  1044.                   ch = async_peek(port, 0);
  1045.  
  1046.                    /* peek next 10 chars in receive ring buffer */
  1047.                   for (i = 0; i < 10; i++)
  1048.                       buf[i] = async_peek(port, i);
  1049.  
  1050.          Returns: This function returns the character in the receive
  1051.                   ring buffer at the indexed position.  If an attempt is
  1052.                   made to peek deeper in the ring buffer than there are
  1053.                   characters in the ring buffer, -1 (0xffff) is
  1054.                   returned.
  1055.  
  1056.          Remarks: No characters are removed from the ring buffer by this
  1057.                   function.
  1058.  
  1059.                   The index value is 0 based.
  1060.  
  1061.                   To avoid confusing the character, '\0xff', from the
  1062.                   error return value, 0xffff, use an integer size
  1063.                   variable for the return value.  The character '\0xff'
  1064.                   is returned as 0x00ff and the error condition is
  1065.                   returned as 0xffff.
  1066.  
  1067.  
  1068.  
  1069.  
  1070.  
  1071.  
  1072.          async_regs
  1073.          ---------------------------------------------------------------
  1074.  
  1075.          Purpose: Provides direct access to the UART registers.
  1076.  
  1077.          Format:  int async_regs(port, reg_ofst, value);
  1078.                    ASYNC *port;       Pointer to ASYNC structure
  1079.                    int reg_ofst;      Offset of register from base adrs
  1080.                    int value;         Value to write or -1 if reading
  1081.  
  1082.          Examples:
  1083.  
  1084.                   ASYNC *port;
  1085.                   int LCRvalue;
  1086.  
  1087.                    /* read the line control register */
  1088.                   LCRvalue = async_regs(port, LCRreg, RDreg);
  1089.  
  1090.                    /* write a 0 to the modem control register */
  1091.                   async_regs(port, MCRreg, 0);
  1092.  
  1093.          Returns: When reading a register, the return value is the value
  1094.                   of the UART register that was read.  When writing a
  1095.                   register, the return value is undefined.
  1096.  
  1097.          Remarks: The following values for register offsets are defined
  1098.                   in COMM.H for use with async_regs:
  1099.                     RXreg, TXreg - receive & transmit regs, value = 0
  1100.                     IERreg - interrupt enable register,     value = 1
  1101.                     IIDreg - interrupt identification reg,  value = 2
  1102.                     FCRreg - FIFO control register          value = 2
  1103.                     LCRreg - line control register,         value = 3
  1104.                     MCRreg - modem control register,        value = 4
  1105.                     LSRreg - line status register,          value = 5
  1106.                     MSRreg - modem status register,         value = 6
  1107.                     LObaud - offset of low baud divisor,    value = 0
  1108.                     HIbaud - offset of high baud divisor,   value = 1
  1109.                   Also RDreg is defined as -1 for use when reading one
  1110.                   of the UART registers.  See the examples.  See
  1111.                   cautions on the following page before using this
  1112.                   function.
  1113.  
  1114.  
  1115.  
  1116.  
  1117.  
  1118.  
  1119.          async_regs
  1120.          ---------------------------------------------------------------
  1121.  
  1122.          Remarks (continued):
  1123.  
  1124.                   This function is provided primarily as a debugging
  1125.                   tool.  Reading or writing to the UART registers while
  1126.                   operating in an interrupt driven mode can cause
  1127.                   several types of problems.  Do not use this function
  1128.                   unless you know what you are doing.  Do not read the
  1129.                   RXreg, IIDreg, LSRreg, or MSRreg on an open port
  1130.                   except for debugging purposes.  Do not write any of
  1131.                   the registers.
  1132.  
  1133.                   The function may be used on a port that has not yet
  1134.                   been opened if the ComBase member of the port struc-
  1135.                   ture has been set.  When async_regs is used with an
  1136.                   unopened port the UART registers may be read or writ-
  1137.                   ten without restriction.
  1138.  
  1139.  
  1140.  
  1141.  
  1142.  
  1143.  
  1144.          async_reset
  1145.          ---------------------------------------------------------------
  1146.  
  1147.          Purpose: Clear parity error bit, framing error bit, character
  1148.                   overrun bit, receive buffer overflow bit, and break
  1149.                   signal received bit in the the Stat1 byte.
  1150.  
  1151.          Format:  void async_reset(port);
  1152.                    ASYNC *port;       Pointer to ASYNC structure
  1153.  
  1154.          Example:
  1155.  
  1156.                   ASYNC *port;
  1157.  
  1158.                   if (error)
  1159.                       async_reset(port);
  1160.  
  1161.  
  1162.          Returns: No return value
  1163.  
  1164.          Remarks: This function is implemented as a macro.  See also
  1165.                   async_rx and async_stat.
  1166.  
  1167.  
  1168.  
  1169.  
  1170.  
  1171.  
  1172.          async_restart
  1173.          ---------------------------------------------------------------
  1174.  
  1175.          Purpose: Re-initialize an already opened serial port
  1176.  
  1177.          Format:  void async_restart(port);
  1178.                    ASYNC *port;       Pointer to ASYNC structure
  1179.  
  1180.          Example:
  1181.  
  1182.                   ASYNC *port;
  1183.  
  1184.                   async_restart(port);
  1185.  
  1186.  
  1187.          Returns: No return value
  1188.  
  1189.          Remarks: Async_restart resets the interrupt vector, UART regis-
  1190.                   ters, and 8259 interrupt controller mask to the values
  1191.                   necessary for interrupt driven operation.  It also
  1192.                   flushes the receive and transmit buffers and resets
  1193.                   the Stat1 byte.  Use this function to restart a comm
  1194.                   port after spawning a program that may have altered
  1195.                   the interrupt vector, UART regs, or interrupt mask.
  1196.  
  1197.                   See also async_stop.
  1198.  
  1199.  
  1200.  
  1201.  
  1202.  
  1203.  
  1204.          async_rts
  1205.          ---------------------------------------------------------------
  1206.  
  1207.          Purpose: Sets or resets the Request to Send signal.
  1208.  
  1209.          Format:  void async_rts(port, flag);
  1210.                    ASYNC *port;       Pointer to ASYNC structure
  1211.                    int flag;          Set/Reset RTS flag
  1212.  
  1213.          Example:
  1214.  
  1215.                   ASYNC *port;
  1216.  
  1217.                   if (WantToDropRTS)
  1218.                       async_rts(port, 0);
  1219.                   else if (WantRTShigh)
  1220.                       async_rts(port, 1);
  1221.  
  1222.  
  1223.          Returns: No return value
  1224.  
  1225.          Remarks: The RTS signal is primarily used for hardware hand-
  1226.                   shaking.  When a port is first opened RTS is set HIGH
  1227.                   (enabled).  When the port is closed, it is restored to
  1228.                   the condition it was in when the port was opened.  To
  1229.                   force RTS low when closing a port, regardless of its
  1230.                   state when the port was opened, AND the port member,
  1231.                   OldMCR with NOT B_RTS.  To force RTS to remain high
  1232.                   when the port is closed, OR OldMCR with B_RTS.
  1233.  
  1234.                     Force low:    port->OldMCR &= ~B_RTS;
  1235.                                   async_close(port);
  1236.  
  1237.                     Force high:   port->OldMCR |= B_RTS;
  1238.                                   async_close(port);
  1239.  
  1240.  
  1241.  
  1242.  
  1243.  
  1244.  
  1245.          async_rx
  1246.          ---------------------------------------------------------------
  1247.  
  1248.          Purpose: Gets one character from the receive ring buffer.
  1249.  
  1250.          Format:  int async_rx(port);
  1251.                    ASYNC *port;       Pointer to ASYNC structure
  1252.  
  1253.          Examples:
  1254.  
  1255.                   ASYNC *port;
  1256.                   int rxch;
  1257.  
  1258.                   rxch = async_rx(port);       /* rxch == Stat1/char */
  1259.  
  1260.                   rxch = async_rx(port) & 0xff;      /* rxch == char */
  1261.  
  1262.                    /* chk if char available & process only if it was */
  1263.                   if (!((rxch = async_rx(port)) & B_RXEMPTY)
  1264.                       procRxdChar(rxch & 0xff);
  1265.  
  1266.          Returns: Async_rx returns the character received as the low
  1267.                   byte and the Stat1 status byte as the high byte.  If
  1268.                   the receive ring buffer was empty when async_rx was
  1269.                   called the low byte will be 0 and the high byte will
  1270.                   have the B_RXEMPTY bit set.  The Stat1 byte is a bit
  1271.                   mapped value that reflects parity errors, framing
  1272.                   errors, character overrun errors, receive buffer
  1273.                   overflow errors, receive buffer empty, break signal
  1274.                   received, and carrier lost.  If no receive errors
  1275.                   have occurred, a break signal has not been received,
  1276.                   and a carrier is present, Stat1 will be 0.
  1277.  
  1278.  
  1279.  
  1280.  
  1281.  
  1282.  
  1283.          async_rx
  1284.          ---------------------------------------------------------------
  1285.  
  1286.          Remarks: Error bits set in the Stat1 byte are not necessarily
  1287.                   associated with the character just taken out of the
  1288.                   receive ring buffer.  In fact, they probably are not.
  1289.                   The error bits are set when the error is detected and
  1290.                   reset when async_reset is called.  For example:
  1291.  
  1292.                    1) 20 bytes of data are received with no errors.
  1293.                    2) Async_rx has been called 10 times so 10 characters
  1294.                       have been taken out of the ring buffer and 10 of
  1295.                       the bytes with no errors are still in the buffer.
  1296.                    3) A parity error occurs on the next byte received
  1297.                       from the UART -- the 11th byte in the receive ring
  1298.                       buffer.
  1299.                    4) The next byte taken out of the buffer, which is
  1300.                       the first of the 10 remaining good bytes will have
  1301.                       the parity error bit in the Stat1 byte.  It will
  1302.                       remain set until async_reset is called.
  1303.  
  1304.                   If the 'ignore characters with errors' bit is set (see
  1305.                   async_ignerr), then characters that have either parity
  1306.                   or framing errors are never placed in the receive ring
  1307.                   buffer.  They are read from the UART and discarded.
  1308.                   The error bits in Stat1 are set regardless of the
  1309.                   setting of the 'ignore characters with errors' bit.
  1310.  
  1311.  
  1312.  
  1313.  
  1314.  
  1315.  
  1316.          async_rxblk
  1317.          ---------------------------------------------------------------
  1318.  
  1319.          Purpose: Retrieves a block of characters from the receive ring
  1320.                   buffer.
  1321.  
  1322.          Format:  int async_rxblk(port, buf, maxchars);
  1323.                    ASYNC *port;       Pointer to ASYNC structure
  1324.                    char *buf;         Buffer for received data
  1325.                    int maxchars;      Maximum number of chars to read
  1326.  
  1327.          Example:
  1328.  
  1329.                   ASYNC *port;
  1330.                   char buf[256];
  1331.                   int bytesRead;
  1332.  
  1333.                   bytesRead = async_rxblk(port, buf, sizeof(buf));
  1334.  
  1335.          Returns: Async_rxblk returns the number of bytes read.  This
  1336.                   value will be 'maxchars' if there are that many bytes
  1337.                   available in the receive buffer.  If there are not
  1338.                   'maxchars' in the receive buffer, the entire contents
  1339.                   of the receive buffer will be moved to 'buf' and the
  1340.                   return value will be the number of bytes that were in
  1341.                   the buffer.
  1342.  
  1343.          Remarks: Very fast way to read data.  See also async_rx and
  1344.                   async_rxblkch.
  1345.  
  1346.  
  1347.  
  1348.  
  1349.  
  1350.  
  1351.          async_rxblkch
  1352.          ---------------------------------------------------------------
  1353.  
  1354.          Purpose: Retrieve bytes from the receive ring buffer until the
  1355.                   specified character is found, 'maxchars' are read, or
  1356.                   the receive ring buffer is emptied.
  1357.  
  1358.          Format:
  1359.            int async_rxblkch(port, buf, maxchars, keychar, includekey);
  1360.             ASYNC *port;      Pointer to ASYNC structure
  1361.             char *buf;        Destination for bytes read
  1362.             int maxchars;     Maximum number of chars to read
  1363.             char keychar;     Character to scan for
  1364.             int includekey;   Flag set if 'keychar' is to be read also
  1365.  
  1366.          Example:
  1367.  
  1368.            ASYNC *port;
  1369.            char buf[256];
  1370.            int bytesRead;
  1371.            int foundkey;
  1372.  
  1373.            bytesRead = async_rxblkch(port, buf, sizeof(buf), '\n', 1);
  1374.            if (bytesRead < 0)
  1375.                bytesRead = -bytesRead, foundkey = TRUE;
  1376.             else
  1377.                foundkey = FALSE;
  1378.  
  1379.          Returns: This function returns the number of bytes read if the
  1380.                   'keychar' is not found.  If the 'keychar' is found the
  1381.                   2's complement of the number of bytes read is
  1382.                   returned.
  1383.  
  1384.  
  1385.  
  1386.  
  1387.  
  1388.  
  1389.          async_rxblkch
  1390.          ---------------------------------------------------------------
  1391.  
  1392.          Remarks: The 'includekey' flag, which is the last argument of
  1393.                   the function, determines whether or not the 'keychar'
  1394.                   is to be included if it is found.  If the flag is 1
  1395.                   and the 'keychar' is found it will be the last char-
  1396.                   acter in the user buffer.  If this flag is 0 and the
  1397.                   'keychar' is found, the 'keychar' is left in the re-
  1398.                   ceive ring buffer and will be the first character read
  1399.                   when you next call one of the async_rx type functions.
  1400.                   This can cause a problem if you set this flag to 0 and
  1401.                   the 'keychar' is the first character in the receive
  1402.                   buffer.  The function will return 0, which would seem
  1403.                   to indicate that there were no bytes in the buffer.
  1404.                   Actually the character was found but since you are not
  1405.                   taking it out of the ring buffer zero bytes are read.
  1406.                   There are two ways to check for this condition.  You
  1407.                   can first call async_rxcnt to verify there are bytes
  1408.                   in the receive buffer and then call async_rxblkch.  If
  1409.                   async_rxblkch returns 0, the 'keychar' is there and is
  1410.                   the first byte in the buffer.  The other method is to
  1411.                   use async_peek to see what the next character in the
  1412.                   receive buffer is before calling async_rxblkch.
  1413.  
  1414.                   A 2's complement value of the bytes read is returned
  1415.                   by async_rxblkch when the 'keychar' is found.  For
  1416.                   actual bytes use:
  1417.                       bytes = async_rxblkch( ....);
  1418.                       if (bytes < 0)
  1419.                           bytes = -bytes;
  1420.                   A byte count less than zero is the signal the
  1421.                   'keychar' was found.  (Except for the circumstance
  1422.                   noted in the previous paragraph).
  1423.  
  1424.                   See async_rx, async_rxblk, async_rxcnt, async_peek.
  1425.  
  1426.  
  1427.  
  1428.  
  1429.  
  1430.  
  1431.          async_rxcnt
  1432.          ---------------------------------------------------------------
  1433.  
  1434.          Purpose: Returns the number of bytes in the receive ring
  1435.                   buffer.
  1436.  
  1437.          Format:  int async_rxcnt(port);
  1438.                    ASYNC *port;       Pointer to ASYNC structure
  1439.  
  1440.          Example:
  1441.  
  1442.                   ASYNC *port;
  1443.  
  1444.                   BytesInRxBuf = async_rxcnt(port);
  1445.  
  1446.          Returns: Number of bytes in the receive ring buffer
  1447.  
  1448.          Remarks: This function is implemented as a macro.
  1449.  
  1450.  
  1451.  
  1452.  
  1453.  
  1454.  
  1455.          async_rxerr
  1456.          ---------------------------------------------------------------
  1457.  
  1458.          Purpose: Checks if a receive error has been detected.
  1459.  
  1460.          Format:  int async_rxerr(port);
  1461.                    ASYNC *port;       Pointer to ASYNC structure
  1462.  
  1463.          Example:
  1464.  
  1465.                   ASYNC *port;
  1466.                   int rxerr_status;
  1467.  
  1468.                   rxerr_status = async_rxerr(port);
  1469.  
  1470.          Returns: ZR if no receive errors have been detected, NZ if
  1471.                   receive error has been detected.
  1472.  
  1473.          Remarks: Types of receive errors that are detected by this
  1474.                   function are parity errors, framing errors, UART
  1475.                   receive register overflow, and receive ring buffer
  1476.                   overflow.  This information is also returned as the
  1477.                   high byte of the async_rx and async_stat functions.
  1478.                   This function is implemented as a macro.
  1479.  
  1480.                   See also async_rx, async_stat.
  1481.  
  1482.  
  1483.  
  1484.  
  1485.  
  1486.  
  1487.          async_rxflush
  1488.          ---------------------------------------------------------------
  1489.  
  1490.          Purpose: Empties out the receive ring buffer.
  1491.  
  1492.          Format:  void async_rxflush(port);
  1493.                    ASYNC *port;       Pointer to ASYNC structure
  1494.  
  1495.          Example:
  1496.  
  1497.                   ASYNC *port;
  1498.  
  1499.                   async_rxflush(port);
  1500.  
  1501.          Returns: This function does not have a return value
  1502.  
  1503.          Remarks: Clears the receive ring buffer and -- if a 16550 is
  1504.                   present in the system with its FIFOs activated --
  1505.                   resets the receiver FIFOs.  All data that was in the
  1506.                   buffer is lost.  If XON/XOFF flow control is being
  1507.                   used and an XOFF has been sent to the remote, this
  1508.                   function automatically sends an XON.  An XON is not
  1509.                   ALWAYS sent -- only if XFLOW control is in use and the
  1510.                   async interrupt routine has sent an XOFF.  It will not
  1511.                   clear false XOFFs the remote may have received.
  1512.  
  1513.  
  1514.  
  1515.  
  1516.  
  1517.  
  1518.          async_setbpds
  1519.          ---------------------------------------------------------------
  1520.  
  1521.          Purpose: Change the baud rate, parity, number of data bits or
  1522.                   number of stop bits on an already opened port.
  1523.  
  1524.          Format:  int async_setbpds(port, params);
  1525.                    ASYNC *port;       Pointer to ASYNC structure
  1526.                    char *params;      Pointer to parameter string
  1527.  
  1528.          Example:
  1529.  
  1530.                   ASYNC *port;
  1531.                   int rcode;
  1532.  
  1533.                   rcode = async_setbpds(port, "2400E71");
  1534.  
  1535.          Returns: This function returns 0 if successful and the new
  1536.                   parameter string is copied to the port structure
  1537.                   member, BPDSstr.  Errors that can be returned are
  1538.                   R_BAUDERR, R_PARITYERR, R_DTABITERR, or R_STPBITERR.
  1539.                   If one of these error codes are returned, the port
  1540.                   settings are unchanged and the port member BPDSstr is
  1541.                   left unchanged.
  1542.  
  1543.                   See async_open for a more complete description of
  1544.                   these errors.
  1545.  
  1546.          Remarks: If 7 data bits is selected the StripMask is set to
  1547.                   strip the high bit off incoming data.  If 8 data bits
  1548.                   are selected the StripMask is disabled.
  1549.  
  1550.                   Valid baud rates are from 50 to 115200 baud.  Parity
  1551.                   may be 'E'ven, 'N'one, or 'O'dd.  The number of data
  1552.                   bits must be 7 or 8 and the number of stop bits must
  1553.                   be 1 or 2.  Do not use spaces, commas, or any other
  1554.                   type of punctuation in the parameter string.
  1555.  
  1556.                   See also async_open, async_strip.
  1557.  
  1558.  
  1559.  
  1560.  
  1561.  
  1562.  
  1563.          async_sndbrk
  1564.          ---------------------------------------------------------------
  1565.  
  1566.          Purpose: Enable or disable a break signal
  1567.  
  1568.          Format:  void async_sndbrk(port, Brkflag);
  1569.                    ASYNC *port;       Pointer to ASYNC structure
  1570.                    int Brkflag;       Set/Reset break signal flag
  1571.  
  1572.          Example:
  1573.  
  1574.                   ASYNC *port;
  1575.  
  1576.                    /* send break for 50 msec */
  1577.                   async_sndbrk(port, 1); /* enable break signal */
  1578.                   delay(50MSEC);         /* your delay function */
  1579.                   async_sndbrk(port, 0); /* disable break signal */
  1580.  
  1581.  
  1582.          Returns: No return value
  1583.  
  1584.          Remarks: This function causes the UART to send a continuous
  1585.                   break signal if it is called with the flag set to 1.
  1586.                   It must be called again with the flag set to 0 to
  1587.                   disable the break signal.
  1588.  
  1589.  
  1590.  
  1591.  
  1592.  
  1593.  
  1594.          async_stat
  1595.          ---------------------------------------------------------------
  1596.  
  1597.          Purpose: Get the current status of a port
  1598.  
  1599.          Format:  int async_stat(port, mask);
  1600.                    ASYNC *port;       Pointer to ASYNC structure
  1601.                    int mask;          Mask applied to return value
  1602.  
  1603.          Examples:
  1604.  
  1605.                   ASYNC *port;
  1606.                   int status;
  1607.  
  1608.                    /* status = all status bits */
  1609.                   status = async_stat(port, 0xffff);
  1610.  
  1611.                    /* check for XOFF received condition */
  1612.                   if (async_stat(port, B_XRXD))
  1613.                       do_something();
  1614.  
  1615.  
  1616.          Returns: Returns Stat1/Stat2 status bits after masking them
  1617.                   with the passed mask value.  Stat1 is the high byte
  1618.                   and Stat2 is the low byte of the return value.
  1619.  
  1620.                   Stat1 bit map:
  1621.                       Bit 7 = set if no carrier present
  1622.                       Bit 6 = receive ring buffer empty
  1623.                       Bit 5 = not used
  1624.                       Bit 4 = break signal was detected
  1625.                       Bit 3 = framing error was detected
  1626.                       Bit 2 = parity error was detected
  1627.                       Bit 1 = character overrun error was detected
  1628.                       Bit 0 = receive ring buffer has overflowed
  1629.  
  1630.                   Stat2 bit map:
  1631.                       Bit 7 = carrier detect monitored for flow control
  1632.                       Bit 6 = XOFF rx'd or hardware flow control active
  1633.                       Bit 5 = data set ready monitored for flow control
  1634.                       Bit 4 = clear to send monitored for flow control
  1635.                       Bit 3 = transmit ring buffer is empty
  1636.                       Bit 2 = an XOFF has been sent by interrupt handler
  1637.                       Bit 1 = an XOFF has been received
  1638.                       Bit 0 = using XON/XOFF flow control
  1639.  
  1640.  
  1641.  
  1642.  
  1643.  
  1644.  
  1645.          async_stat
  1646.          ---------------------------------------------------------------
  1647.  
  1648.          Remarks: For some situations, it is more efficient to use one
  1649.                   of the other library functions targeted specifically
  1650.                   for the information you want.  For instance, instead
  1651.                   of calling:
  1652.                        async_stat(port, B_XRXD);
  1653.                   use:
  1654.                        async_xrxd(port);
  1655.  
  1656.                   The information in the Stat1 byte is also returned as
  1657.                   the high byte of the async_rx function.  Bits 0-4 of
  1658.                   Stat1 remain set until cleared by the async_reset
  1659.                   function.
  1660.  
  1661.                   Not all bits in the Stat2 and Stat1 port structure
  1662.                   members are kept updated on a constant basis so do not
  1663.                   try to check a condition by testing the Stat1 or Stat2
  1664.                   values in the ASYNC structure.  Use one of the docu-
  1665.                   mented functions or macros to be sure of getting the
  1666.                   correct result.
  1667.  
  1668.  
  1669.  
  1670.  
  1671.  
  1672.  
  1673.          async_stop
  1674.          ---------------------------------------------------------------
  1675.  
  1676.          Purpose: Temporarily disables interrupt driven operation of an
  1677.                   already opened port.
  1678.  
  1679.          Format:  void async_stop(port);
  1680.                    ASYNC *port;       Pointer to ASYNC structure
  1681.  
  1682.          Example:
  1683.  
  1684.                   ASYNC *port;
  1685.                   int x, inhdl, outhdl, errhdl;
  1686.  
  1687.                   async_stop(port);               /* release port */
  1688.                    /* redirect console to async port */
  1689.                   x = open("COM1", O_RDWR|O_BINARY);
  1690.                   inhdl = dup(0);  outhdl = dup(1);  errhdl = dup(2);
  1691.                   dup2(x, 0);  dup2(x, 1);  dup2(x, 2);
  1692.                    /* run a redirected DOS shell */
  1693.                   spawnlp(P_WAIT, "COMMAND.COM", "COMMAND.COM", NULL);
  1694.                    /* restore stdin, stdout, stderr */
  1695.                   close(x);
  1696.                   dup2(inhdl, 0);   close(inhdl);
  1697.                   dup2(outhdl, 1);  close(outhdl);
  1698.                   dup2(errhdl, 2);  close(errhdl);
  1699.                   async_restart(port);   /* regain control of port */
  1700.  
  1701.          Returns: No return value
  1702.  
  1703.          Remarks: Call this function before spawning a program that will
  1704.                   be doing its own port I/O, such as an external commun-
  1705.                   ications program or a redirected DOS shell.  After the
  1706.                   other application has completed, call async_restart to
  1707.                   re-enable interrupt operation.
  1708.  
  1709.                   This function disables interrupts for the named port
  1710.                   by clearing UART's interrupt enable register and the
  1711.                   OUT2 bit of its modem control register.
  1712.  
  1713.                   See also async_restart.
  1714.  
  1715.  
  1716.  
  1717.  
  1718.  
  1719.  
  1720.          async_strip
  1721.          ---------------------------------------------------------------
  1722.  
  1723.          Purpose: Set the strip mask for received characters.
  1724.  
  1725.          Format:  void async_strip(port, mask);
  1726.                    ASYNC *port;       Pointer to ASYNC structure
  1727.                    char mask;         Strip mask
  1728.  
  1729.          Example:
  1730.  
  1731.                   ASYNC *port;
  1732.  
  1733.                   async_strip(port, '\x7f');
  1734.  
  1735.          Returns: No return value
  1736.  
  1737.          Remarks: The strip mask is automatically set to 0x7f when the
  1738.                   parameters are set for 7 data bits and to 0xff when 8
  1739.                   data bits are used.  All incoming data is ANDed with
  1740.                   the strip mask before it is placed in the receive ring
  1741.                   buffer.  This function is implemented as a macro.
  1742.  
  1743.  
  1744.  
  1745.  
  1746.  
  1747.  
  1748.          async_tx
  1749.          ---------------------------------------------------------------
  1750.  
  1751.          Purpose: Send 1 character to a port.
  1752.  
  1753.          Format:  int async_tx(port, ch);
  1754.                    ASYNC *port;       Pointer to ASYNC structure
  1755.                    char ch;           Character to transmit
  1756.  
  1757.          Example:
  1758.  
  1759.                   ASYNC *port;
  1760.  
  1761.                    /* send a CR/LF to a port */
  1762.                   async_tx(port, '\r');
  1763.                   async_tx(port, '\n');
  1764.  
  1765.  
  1766.          Returns: Returns the number of bytes left available in the
  1767.                   transmit ring buffer unless the ring buffer was full
  1768.                   when the function was called.  R_TXERR is returned if
  1769.                   the transmit ring buffer was full and the character
  1770.                   that was to be transmitted is not placed in the ring
  1771.                   buffer.
  1772.  
  1773.          Remarks: The error return value, R_TXERR, is a negative number.
  1774.                   The bytes free return value can never be negative.
  1775.  
  1776.                   See also async_txblk, async_txfree.
  1777.  
  1778.  
  1779.  
  1780.  
  1781.  
  1782.  
  1783.          async_txblk
  1784.          ---------------------------------------------------------------
  1785.  
  1786.          Purpose: Send a block of characters to a port.
  1787.  
  1788.          Format:  int async_txblk(port, buf, count);
  1789.                    ASYNC *port;       Pointer to ASYNC structure
  1790.                    char *buf;         Pointer to block to transmit
  1791.                    int count;         Size of block in bytes
  1792.  
  1793.          Examples:
  1794.  
  1795.                   ASYNC *port;
  1796.                   char buf[128];
  1797.                   static char *msg = "Send this message\r\n");
  1798.  
  1799.                   put_data_in_buf();
  1800.                   async_txblk(port, buf, sizeof(buf));
  1801.                   async_txblk(port, msg, strlen(msg));
  1802.  
  1803.          Returns: Returns the number of bytes left available in the
  1804.                   transmit ring buffer unless the ring buffer would not
  1805.                   hold the entire block when the function was called.
  1806.                   R_TXERR is returned if there was no room for the
  1807.                   block and none of the bytes in the block are sent.
  1808.  
  1809.          Remarks: This function is much faster than using repeated calls
  1810.                   to async_tx when multiple bytes are being transmitted.
  1811.                   The error return value, R_TXERR, is a negative number.
  1812.                   The bytes free return value can never be negative.
  1813.  
  1814.                   See also async_tx, async_txfree.
  1815.  
  1816.  
  1817.  
  1818.  
  1819.  
  1820.  
  1821.          async_txempty
  1822.          ---------------------------------------------------------------
  1823.  
  1824.          Purpose: Checks if transmit ring buffer is empty.
  1825.  
  1826.          Format:  int async_txempty(port);
  1827.                    ASYNC *port;       Pointer to ASYNC structure
  1828.  
  1829.          Example:
  1830.  
  1831.                   ASYNC *port;
  1832.  
  1833.                    /* wait for transmit ring buffer to empty out */
  1834.                   while (!async_txempty(port))
  1835.                       ;
  1836.  
  1837.          Returns: NZ if the transmit ring buffer is empty, ZR if the
  1838.                   buffer still has characters to be transmitted.
  1839.  
  1840.          Remarks: This function is implemented as a macro.
  1841.  
  1842.  
  1843.  
  1844.  
  1845.  
  1846.  
  1847.          async_txflush
  1848.          ---------------------------------------------------------------
  1849.  
  1850.          Purpose: Flushes the transmit ring buffer.
  1851.  
  1852.          Format:  void async_txflush(port);
  1853.                    ASYNC *port;       Pointer to ASYNC structure
  1854.  
  1855.          Example:
  1856.  
  1857.                   ASYNC *port;
  1858.  
  1859.                   async_txflush(port);
  1860.  
  1861.  
  1862.          Returns: No return value
  1863.  
  1864.          Remarks: Clears the transmit ring buffer and -- if a 16550
  1865.                   operating in FIFO mode is in the system -- resets the
  1866.                   transmit FIFOs.  All characters in the buffer that
  1867.                   have not been transmitted are lost.
  1868.  
  1869.  
  1870.  
  1871.  
  1872.  
  1873.  
  1874.          async_txfree
  1875.          ---------------------------------------------------------------
  1876.  
  1877.          Purpose: Returns the number of bytes left available in the
  1878.                   transmit ring buffer.
  1879.  
  1880.          Format:  int async_txfree(port);
  1881.                    ASYNC *port;       Pointer to ASYNC structure
  1882.  
  1883.          Example:
  1884.  
  1885.                   ASYNC *port;
  1886.                   int tx_bytes_available;
  1887.  
  1888.                   tx_bytes_available = async_txfree(port);
  1889.  
  1890.  
  1891.          Returns: Number of bytes of free space left in the transmit
  1892.                   buffer.
  1893.  
  1894.          Remarks: The number of free bytes left in the transmit ring
  1895.                   buffer is also the return value of async_tx and
  1896.                   async_txblk.  This function is implemented as a macro.
  1897.  
  1898.  
  1899.  
  1900.  
  1901.  
  1902.  
  1903.          async_xany
  1904.          ---------------------------------------------------------------
  1905.  
  1906.          Purpose: Checks if accepting the first character after an XOFF
  1907.                   is received as the XON character.  DOES NOT enable any
  1908.                   character XON (use async_xflow).
  1909.  
  1910.          Format:  int async_xany(port);
  1911.                    ASYNC *port;       Pointer to ASYNC structure
  1912.  
  1913.          Example:
  1914.  
  1915.                   ASYNC *port;
  1916.                   int rcode;
  1917.  
  1918.                   rcode = async_xany(port);
  1919.  
  1920.          Returns: Not zero if first character after an XOFF is to be
  1921.                   treated as an XON.  Zero if a real XON is required to
  1922.                   clear an XOFF.
  1923.  
  1924.          Remarks: This function is implemented as a macro.  See also
  1925.                   async_xflow.
  1926.  
  1927.  
  1928.  
  1929.  
  1930.  
  1931.  
  1932.          async_xflow
  1933.          ---------------------------------------------------------------
  1934.  
  1935.          Purpose: Enables/disables use of XON/XOFF flow control.
  1936.  
  1937.          Format:  void async_xflow(port, flag);
  1938.                    ASYNC *port;       Pointer to ASYNC structure
  1939.                    int flag;          Enable/Disable & any char XON flag
  1940.  
  1941.          Examples:
  1942.  
  1943.                   ASYNC *port;
  1944.  
  1945.                   async_xflow(port, B_XUSE); /* use flow control */
  1946.                   async_xflow(port, 0);      /* disable flow control */
  1947.  
  1948.                    /* use XON/XOFF flow control with any char being
  1949.                       accepted as an XON */
  1950.                   async_xflow(port, B_XUSE | B_XONANY);
  1951.  
  1952.                    /* enable XON/XOFF on transmit side only */
  1953.                   async_xflow(port, B_XUSET);
  1954.  
  1955.                    /* enable XON/XOFF on receive side only */
  1956.                   async_xflow(port, B_XUSER);
  1957.  
  1958.          Returns: No return value
  1959.  
  1960.          Remarks: Passing B_XUSET enables the transmission of XON/XOFF
  1961.                   characters when the receive buffer fills to the 'trip'
  1962.                   levels discussed in the following paragraph.  Incoming
  1963.                   XON/XOFFs are not regarded as flow control characters
  1964.                   and are stored in the ring buffer.  Passing B_XUSER,
  1965.                   enables recognition of received XON/XOFFs as flow
  1966.                   characters but does not enable transmission of
  1967.                   XON/XOFF at the trip levels.  If B_XUSE is passed,
  1968.                   both transmission and recognition of XON/XOFF as flow
  1969.                   characters is enabled (the same as B_XUSET | B_XUSER).
  1970.                   ORing B_XONANY with either B_XUSE or B_XUSER causes
  1971.                   the first character received after an XOFF to be
  1972.                   treated as the XON unless that character is another
  1973.                   XOFF.  Passing zero as the flag disables XON/XOFF flow
  1974.                   control.  The default is no flow control.
  1975.  
  1976.  
  1977.  
  1978.  
  1979.  
  1980.  
  1981.          async_xflow
  1982.          ---------------------------------------------------------------
  1983.  
  1984.          Remarks (continued):
  1985.  
  1986.                   The port structure member, XoffTrip, determines when
  1987.                   an XOFF will be sent.  Whenever the number of bytes
  1988.                   left available in receive buffer falls below XoffTrip,
  1989.                   an XOFF is sent.  The default value of XoffTrip is 25%
  1990.                   of the size of the receive buffer so an XOFF is sent
  1991.                   whenever the receive buffer is 75% full.
  1992.  
  1993.                   The port structure member, XonTrip, determines when an
  1994.                   XON will be sent.  Whenever the number of bytes left
  1995.                   available in the receive buffer rises above XonTrip,
  1996.                   an XON will be sent.  Its default value is 50% of the
  1997.                   size of the receive buffer.
  1998.  
  1999.                   The port structure member, XTxRptInit, determines how
  2000.                   many bytes may be received after an XOFF is sent
  2001.                   before another XOFF is sent.  Its default value is
  2002.                   6.25% of the size of the receive buffer or 160 bytes,
  2003.                   whichever is less.
  2004.  
  2005.                   XoffTrip, XonTrip, and XTxRptInit may all be changed
  2006.                   from their default values by directly accessing the
  2007.                   port structure.  To do this:
  2008.  
  2009.                       ASYNC *port;
  2010.                      /* send XOFF when 300 bytes left in rx ring buf */
  2011.                       port->XoffTrip = 300;
  2012.                      /* send XON when 350 bytes left in rx ring buf */
  2013.                       port->XonTrip = 350;
  2014.  
  2015.                   Be sure to keep the XonTrip level higher than the
  2016.                   XoffTrip level.  The values are for bytes left
  2017.                   available not bytes used.
  2018.  
  2019.                   The XTxRptInit value is used to automatically send
  2020.                   another XOFF in the event the first one was ignored.
  2021.                   Instead of sending an XOFF character everytime another
  2022.                   character is received, the interrupt routines wait for
  2023.                   'XTxRptInit' characters to be received and then repeat
  2024.                   the XOFF.  If this value is set to low some systems
  2025.                   that allow any character to be an XON will treat the
  2026.                   repeated XOFF character as an XON.
  2027.  
  2028.  
  2029.  
  2030.  
  2031.  
  2032.  
  2033.          async_xoffclr
  2034.          ---------------------------------------------------------------
  2035.  
  2036.          Purpose: Manually clears an XOFF received condition
  2037.  
  2038.          Format:  void async_xoffclr(port);
  2039.                    ASYNC *port;       Pointer to ASYNC structure
  2040.  
  2041.          Example:
  2042.  
  2043.                   ASYNC *port;
  2044.  
  2045.                   async_xoffclr(port);
  2046.  
  2047.          Returns: No return value
  2048.  
  2049.          Remarks: Async_xoffclr has the same effect as if the remote
  2050.                   system had sent an XON.  This will unstop the system
  2051.                   in the event a false XOFF is received or the remote's
  2052.                   XON was lost.  Use this function with caution.  Unless
  2053.                   something goes wrong, the remote will clear XOFF cond-
  2054.                   itions automatically by sending an XON.  If an XOFF is
  2055.                   manually cleared, the remote site may be overran and
  2056.                   lose data.  For use only when XON/XOFF flow control
  2057.                   has been activated.
  2058.  
  2059.                   See also async_xoffset.
  2060.  
  2061.  
  2062.  
  2063.  
  2064.  
  2065.  
  2066.          async_xoffset
  2067.          ---------------------------------------------------------------
  2068.  
  2069.          Purpose: Manually sets an XOFF received condition
  2070.  
  2071.          Format:  void async_xoffset(port);
  2072.                    ASYNC *port;       Pointer to ASYNC structure
  2073.  
  2074.          Example:
  2075.  
  2076.                   ASYNC *port;
  2077.  
  2078.                   async_xoffset(port);
  2079.  
  2080.          Returns: No return value
  2081.  
  2082.          Remarks: Forces the local site to act as though an XOFF had
  2083.                   been received.  Transmit interrupts are disabled until
  2084.                   the remote sends an XON or you call async_xoffclr.
  2085.                   For use only when XON/XOFF flow control has been
  2086.                   activated.
  2087.  
  2088.                   See also async_xoffclr.
  2089.  
  2090.  
  2091.  
  2092.  
  2093.  
  2094.  
  2095.          async_xrxd
  2096.          ---------------------------------------------------------------
  2097.  
  2098.          Purpose: Check if an XOFF has been received and has activated a
  2099.                   flow control halt.
  2100.  
  2101.          Format:  int async_xrxd(port);
  2102.                    ASYNC *port;       Pointer to ASYNC structure
  2103.  
  2104.          Example:
  2105.  
  2106.                   ASYNC *port;
  2107.                   int rcode;
  2108.  
  2109.                   rcode = async_xrxd(port);
  2110.  
  2111.          Returns: Not zero if an XOFF has been received and an XON has
  2112.                   not been received to clear it.  Returns zero if XOFF
  2113.                   flow halt is not currently active.
  2114.  
  2115.          Remarks: This function is implemented as a macro.  See also
  2116.                   async_xoffclr, async_xtxd.
  2117.  
  2118.  
  2119.  
  2120.  
  2121.  
  2122.  
  2123.          async_xtxd
  2124.          ---------------------------------------------------------------
  2125.  
  2126.          Purpose: Check if an XOFF has been sent
  2127.  
  2128.          Format:  int async_xtxd(port);
  2129.                    ASYNC *port;       Pointer to ASYNC structure
  2130.  
  2131.          Example:
  2132.  
  2133.                   ASYNC *port;
  2134.                   int rcode;
  2135.  
  2136.                   rcode = async_xtxd(port);
  2137.  
  2138.          Returns: Not zero if an XOFF has not been sent by the receive
  2139.                   interrupt routine and an XON has not been sent to
  2140.                   clear it.  Returns zero if an XOFF has not been sent.
  2141.  
  2142.          Remarks: This function is implemented as a macro.  See also
  2143.                   async_xoffclr, async_xrxd.
  2144.  
  2145.  
  2146.  
  2147.  
  2148.  
  2149.  
  2150.          async_xuse
  2151.          ---------------------------------------------------------------
  2152.  
  2153.          Purpose: Check if XON/XOFF protocol is currently being used
  2154.  
  2155.          Format:  int async_xuse(port);
  2156.                    ASYNC *port;       Pointer to ASYNC structure
  2157.  
  2158.          Example:
  2159.  
  2160.                   ASYNC *port;
  2161.  
  2162.                   rcode = async_xuse(port);
  2163.  
  2164.          Returns: Not zero if XON/XOFF protocol is being used on either
  2165.                   the transmit or receive sides, zero if XON/XOFF flow
  2166.                   is not being used at all.
  2167.  
  2168.          Remarks: This function is implemented as a macro.  See
  2169.                   async_xflow, async_xuset, async_xuser.
  2170.  
  2171.  
  2172.  
  2173.  
  2174.  
  2175.  
  2176.          async_xuser
  2177.          ---------------------------------------------------------------
  2178.  
  2179.          Purpose: Check if XON/XOFF protocol is enabled on the receive
  2180.                   side (receiver recognizes XON/XOFF as flow control).
  2181.  
  2182.          Format:  int async_xuser(port);
  2183.                    ASYNC *port;       Pointer to ASYNC structure
  2184.  
  2185.          Example:
  2186.  
  2187.                   ASYNC *port;
  2188.  
  2189.                   rcode = async_xuser(port);
  2190.  
  2191.          Returns: Not zero if XON/XOFF protocol is being used on the
  2192.                   receive side, zero if it is not.
  2193.  
  2194.          Remarks: This function is implemented as a macro.  See
  2195.                   async_xflow, async_xuset, async_xuse.
  2196.  
  2197.  
  2198.  
  2199.  
  2200.  
  2201.  
  2202.          async_xuset
  2203.          ---------------------------------------------------------------
  2204.  
  2205.          Purpose: Check if XON/XOFF protocol is enabled on the transmit
  2206.                   side (transmitter sends XOFF/XON as receive buffer
  2207.                   bytes available crosses trip levels).
  2208.  
  2209.          Format:  int async_xuset(port);
  2210.                    ASYNC *port;       Pointer to ASYNC structure
  2211.  
  2212.          Example:
  2213.  
  2214.                   ASYNC *port;
  2215.  
  2216.                   rcode = async_xuset(port);
  2217.  
  2218.          Returns: Not zero if XON/XOFF protocol is being used on the
  2219.                   transmit side, zero if it is not.
  2220.  
  2221.          Remarks: This function is implemented as a macro.  See
  2222.                   async_xflow, async_xuser, async_xuse.
  2223.  
  2224.