home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / communic / encom100 / encom.hlp < prev    next >
Encoding:
Text File  |  1992-07-08  |  38.8 KB  |  652 lines

  1. `co(0,7);                    EnCom version 1.00 from EnQue Software                    `co();
  2. `tab(2);`color_default(LIGHTGRAY,BLUE);`color_keyword(YELLOW,BLUE);`color_first_char(WHITE,BLUE);
  3.  
  4.           `keyword(1) Using EnQue Help, Using This Help);          `keyword(5) Flow Control, Flow Control );
  5.           `keyword(2) Introduction, An Introduction to);              `keyword(6) CRC & Message Formatting, CRC and Message);
  6.           `keyword(3) Design Concepts, EnCom Design);           `keyword(7) 16550 UART Support, EnCom 16550 UART);
  7.           `keyword(4) How EnCom Works, EnCom Mechanics);           `keyword(8) EnCom Library Reference, The EnCom Library);
  8.   
  9.   Press `co(15,?);[Tab]`co();, the arrow keys, or `co(15,?);1`co(); - `co(15,?);8`co(); to move the cursor to the desired
  10.   topic, and press `co(15,?);[Enter]`co();.
  11. `co(15,?);
  12.   To order the large model libraries, complete source code and printed
  13.     documentation, send a check or money order for $99.95 to the address
  14.     below.  Order before September 1, 1992 and save 50% with our special
  15.     summer price of $49.95!  Orders from outside the USA please add $5.00
  16.     for additional shipping and handling costs.
  17. `co();
  18.   We recommend you page through and read all of this documentation and use
  19.   the hypertext features when the help is used as a reference.`co();
  20.  
  21. `co(0,7);                          Using This Help System                              `co();
  22.     This help system is part of EnQue's UltraWin and InTUItion libraries,
  23.   and was designed for useful hypertext systems.  We use it for the disk-
  24.   based documentation for our products.  Using the help system is very
  25.   easy.  Simply use the keypad cursor keys to move around the help.  You
  26.   can also position the cursor on a keyword and press `co(15,?);[Enter]`co(); to move
  27.   quickly to the section that deals with that keyword.  Keywords for this
  28.   documentation show up like this `co(15,1);K`co(14,1);eyword`co();.  To move back to the previous
  29.   section, simply press the `co(15,?);[Backspace]`co(); key.
  30.  
  31.     If you have a mouse, you can double-click on keywords, grab the scroll
  32.     bars at the right and bottom of the help window, or click on any of the
  33.     buttons.  The buttons can also be used by pressing `co(15,?);ALT-KEY`co();, where `co(15,?);KEY`co(); is
  34.     the highlighted letter.
  35.  
  36.         If you are a Borland C/Turbo C user, you can load our tiny TCKBD.COM
  37.     TSR.  This 4k routine allows you to invoke our help engine from the
  38.     Integrated Environment, searching for the function/keyword on which the
  39.     cursor resides, in much the same way as Borland's help.  To do this, you
  40.     must setup our help engine as a Transfer program.  See your Borland manual
  41.     for details.  Include on the command line the $NOSWAP macro so that our
  42.     help will overlay and restore the current window.  A typical command line
  43.     from within the transfer editor for EGA/VGA 43/50 row mode for ENQHELP.EXE
  44.     might look like this: `co(15,?);"$NOSWAP ENCOMREF.HLP 1 0 2 2 77 40"`co();. The first
  45.     numeric parameter is set to 1.  This tells the help engine to call our TSR
  46.     to get the string at the current cursor location, and use that as the
  47.     search string.  The next is a user search string (just use 0 to tell the
  48.     engine no command line search string), and the next four numeric
  49.     parameters are the screen coordinates start x, start y, end x, and end y.
  50.     These last four parameters are optional.  A window of the default size
  51.     will be created if they are omitted.
  52.  
  53.       You may also run the help engine directly from the command line,
  54.     removing the $NOSWAP macro.  You need not load TCKBD.COM to do this.
  55.     (TCKBD.COM merely allows the help engine to read the word that your cursor
  56.     is currently pointing to - it does not ever have to be loaded, it merely
  57.     adds functionality).
  58.  
  59. `co(0,7);                          An Introduction to EnCom                            `co();
  60.  
  61.     Welcome to the EnCom library, version 1.00 (C) 1992 EnQue Software!
  62.   EnCom provides the PC programming community with a powerful tool for
  63.   developing communications applications.  The EnCom library is written in
  64.   100% portable C and supports the Borland and Microsoft families of
  65.   compilers.  See `keyword(disclaimer,Disclaimer); for legal information on using the library.
  66.  
  67.   For information about this or other EnQue products, please contact us at:
  68.  
  69.        `co(14,?);EnQue Software                  Fax/Voice: (816) 987-2515
  70.        Route 1, Box 116C               24 Hr BBS: (816) 353-0991
  71.        Pleasant Hill, MO 64080             Kevin: (816) 987-5709
  72.                                             Boyd: (816) 353-5561`co();
  73. `co(15,?);
  74.   To order the large model libraries, complete source code and printed
  75.     documentation, send a check or money order for $99.95 to the address
  76.     above.  Order before September 1, 1992 and save 50% with our special
  77.     summer price of $49.95!  Orders from outside the USA please add $5.00
  78.     for additional shipping and handling costs.
  79.  
  80. `co(0,7);                               Disclaimer                                     `co();
  81.  
  82.     EnCom is a user supported communications library for the IBM PC.  EnCom
  83.     is copyrighted material.  However, we distribute the small model libraries
  84.     and disk-based documentation at no charge.  We do this so that you can
  85.     actually use the library to be sure it suits your needs before purchasing
  86.     the product.  Please feel free to give the small model libraries and
  87.     disk-based documentation to whomever you wish.  You are also free to
  88.     distribute any executables generated with EnCom royalty free.
  89.     
  90.       Under no conditions may you duplicate or distribute the EnCom large
  91.     model libraries or EnCom source code without the prior written consent of
  92.     EnQue Software.
  93.  
  94.       Purchasing the commercial version provides you not only with large model
  95.     libraries and complete source code, but also free technical support and
  96.     software upgrades through the EnQue BBS.
  97.  
  98.     The authors have taken great care in preparing this disk-based manual
  99.     and accompanying programs and data, including research, development, and
  100.     testing.  The authors make no expressed or implied warranty of any kind
  101.     with regard to the software or accompanying documentation.  In no event
  102.     shall the authors or EnQue Software be liable for incidental or
  103.     consequential damages in connection or arising out of the performance or
  104.     use of any part of this product.
  105.  
  106. `co(0,7);                           EnCom Design Concepts                              `co();
  107.  
  108.     The EnCom library was designed around several key concepts, which we
  109.   feel separates EnCom from other libraries of its type.  Please note that
  110.   we assume some working knowledge of PC communications.  Our documentation
  111.   would unfortunately triple in size if we covered all aspects, making it
  112.   more difficult to understand.  If you need more information on the 8250
  113.   UART, modem control, etc. refer to your computer or modem manual, or a
  114.   text pertaining to PC communications.
  115.  
  116.   Press `co(15,?);[Tab]`co(); or the arrow keys to move the cursor to the desired concept,
  117.   and press `co(15,?);[Enter]`co();.
  118.  
  119.   `keyword(Small Code Size,1. Small);
  120.   `keyword(100% Portable C,2. 100%);
  121.   `keyword(Ease of Use,3. Ease);
  122.   `keyword(Rich in Features,4. Rich);
  123.   `keyword(Sample C Code,5. Sample C);
  124.   
  125.   `co(15,?);1. Small Code Size:`co();
  126.        The library must be very small, consisting of as few functions as are
  127.      necessary to accomplish a well-rounded comm toolbox.  Many other
  128.      products boast of hundreds of functions, many of which are redundant,
  129.      and some of which are just unnecessary.  We try to concentrate on
  130.      making the library lean and mean, and work hard on eliminating fluff.
  131.      As a result the library is very powerful, but is only about 16K in
  132.      size!
  133.   
  134.   `co(15,?);2. 100% Portable C`co();
  135.        The library must be 100% portable C.  This may come as a real
  136.      surprise to many.  If you don't think 100% C can be small and fast then
  137.      you must take a look at our text windowing library UltraWin, or our
  138.      user interface library InTUItion!  In real terms, the only function
  139.      within the library that should even be considered as an assembler
  140.      candidate is the interrupt routine itself.  However, with efficient C
  141.      coding and today's optimizing compilers, the speed of the C code is
  142.      within a few percent of the assembly version.  We discovered this after
  143.      hours of hand-optimizing the assembly code for the interrupt routine,
  144.      and then comparing its performance against a carefully optimize C
  145.      interrupt routine.  The extra few percent gained is not worth the loss
  146.      in portability.  Another reason to strive for 100% C is that you the
  147.      customer can more easily understand and if needed modify the code,
  148.      thereby making the product more usable.  And if you wish to port the
  149.      code to another CPU or another platform, your job will be much easier
  150.      without assembly headaches.  In addition, by taking advantage of the
  151.      fast memory move capabilites of the PC and FIFO (first in, first out)
  152.      capabilities of UARTs such as the 16550, speeds as high as 115,000
  153.      Kbaud are readily attainable, all in 100% C, and even on older PC's.
  154.   
  155.   `co(15,?);3. Ease of Use`co();
  156.        The library must be very easy to use.  The first two concepts make
  157.      this an easily attainable target.  By keeping the library in 100% C,
  158.      and concentrating on more functionality with less code, the learning
  159.      curve for EnCom is measured in minutes and hours, not days and weeks as
  160.      is the case with many of our competitors.  Functions are concise, well
  161.      documented, clearly named, and intuitive in nature.  The bottom line is
  162.      that if a function is not needed, it is not in our library.
  163.   
  164.   `co(15,?);4. Rich in Features`co();
  165.        The library must be very rich in features, yet easy to learn.  It
  166.      has always been our belief that the best solution to a problem is
  167.      usually the least complex solution.  When carefully thought out, a
  168.      simple solution can be both functional and elegant.  Contrary to what
  169.      many companies believe, it is possible to have a small, concise, easy
  170.      to learn library and yet be rich in features.  The following are just
  171.      a few examples of what we have been able to put into EnCom!
  172.  
  173.          A)  `co(12,?);Fully interrupt driven transmit and receive`co(); with queues up to
  174.              64K in size, and a `keyword(queue status,EnCom's "Queue Status"); mode where each character is
  175.              queued along with the current line status register, allowing a
  176.              character by character look at errors.
  177.          B)  `co(12,?);Interrupt handlers`co(); for line/modem control and break.
  178.          C)  Support for `co(12,?);`keyword(Comm 1-4,Comm 1-4 Support); and FIFO'ed UARTs`co(); such as the 16550.
  179.          D)  Enhanced keyboard control such as `co(12,?);Ctrl-C and Ctrl-Break
  180.              handling`co();.  This feature takes control from the OS and places
  181.              it in your hands.
  182.          E)  `co(12,?);Timer and sound support`co();.  Enhanced timing resolution and
  183.              interrupt-driven time events is crucial to comm software, yet
  184.              so many libraries leave this feature out.  In addition, control
  185.              of the PC speaker is provided, and can be automatically turned
  186.              off via the timer interrupt.
  187.          F)  `co(12,?);CRC generation and message formatting/encryption routines.`co();
  188.              Perhaps no other library offers these features.  EnCom can
  189.              generate CRC's based on any polynomial, including the CRC-16
  190.              and CCITT standards.  In addition, message formatting routines
  191.              are included that greatly simplify custom communications
  192.              between two PC's.  These routines are explained in more detail
  193.              later.  Needless to say, if you have data to send between two
  194.              machines, you will fall in love with these routines!
  195.   
  196.   `co(15,?);5. Sample C code to begin using immediately`co();
  197.        Two programs with full source are included.  The first and simplest
  198.      is only a few dozen lines yet implements full bidirectional
  199.      communications and can be used to dial a BBS.  If ANSI.SYS is loaded
  200.      into your system, it will even emulate an ANSI terminal.  This program,
  201.      called START.C, shows how simple using EnCom really is.  Just type
  202.      START with an optional port and baud rate (default is COM1 at 2400
  203.      baud).  To use COM2 at 1200 baud, type `co(15,?);START 2 1200`co(); and press
  204.      `co(15,?);[Enter]`co();.
  205.     
  206.        The second program is a "testbed" for EnCom and shows the use of most
  207.          of EnCom's macros and functions.  This program uses UltraWin for
  208.          display, so many functions will seem unfamiliar.  However, the code is
  209.          very straightforward.  This program, COM_DEMO.C, takes the same
  210.          optional parameters as START.C.  Once running, you may press Alt-H for
  211.          a list of function keys and what they do.  One thing to keep in mind
  212.          here is that it won't seem like anything happens when many keys are
  213.          pressed.  This is the nature of manipulating comm hardware.  For
  214.          instance, toggling the DTR line won't show much unless you have a
  215.          breakout box hooked to the port.  Ideally, you will hook this to
  216.          another machine or "loop" it back to itself so that anything sent is
  217.          received.  While we are on that subject, the PC UART has a built-in
  218.          diagnostics loopback mode which can be set by calling `keyword(com_232_ctrl,[ENCOMREF.HLP]/// com_232_ctrl);.
  219.          However, when this mode is activated, all the modem control lines are
  220.          "disconnected" from the outside world, including OUT2.  OUT2 is used by
  221.          many comm boards to "mask" interrupts from the UART.  Therefore, when
  222.          placed in loopback mode, nothing is sent or received.  You will notice
  223.          though that "toggling" the control lines such as DTR or RTS will show a
  224.          corresponding change on DSR and CTS.  This is a very important point.
  225.          If you ever enable LOOP (it is disabled automatically by the init
  226.          functions), you will more than likely lose interrupt capability!
  227.        
  228.        Also, to show you the power of the library, we have included a
  229.      powerful communications program in its own right.  The terminal
  230.      application supplied illustrates the use of EnCom functions, and
  231.      contains `co(12,?); VT100 terminal emulation, upload and download ASCII,
  232.      Xmodem Checksum, Xmodem CRC, and Ymodem protocols.`co();
  233.  
  234.        This mini-application also demonstrates the power of our sister
  235.          products, UltraWin and InTUItion, and was written in just a few weeks
  236.          using the three libraries.  To start the program, just type TD and
  237.          press `co(15,?);[Enter]`co();.  This defaults to 2400 baud on COM2.  To change the port
  238.          and baud rate from the command line, type the additional parameters
  239.          just as in START.C.  For example, to use a modem on COM1 at 1200 baud,
  240.          just type `co(15,?);TD 1 1200`co(); and press `co(15,?);[Enter]`co();.  After the program comes up,
  241.          you can press ALT-Z for help.
  242.  
  243.        Note that the executable is only about 100K even though it uses the
  244.          low-level windowing library, the higher-level user interface library, a
  245.          powerful hypertext help engine, and, of course, EnCom, not to mention
  246.          the complete VT100 emulation and file transfer protocols and all the
  247.          standard C stuff!  `co(12,?);Most competing comm libraries are larger than
  248.          this complete application!`co();
  249.  
  250.      `co(15,9);NOTE: Complete source code is included on purchase of EnCom!`co();
  251.   
  252. `co(0,7);                            Comm 1-4 Support                                  `co();
  253.  
  254.       EnCom supports comm ports 1-4.  However, due to hardware limitations
  255.     with most PC's, there can only be one device active on a given interrupt.
  256.     Comm 1 and Comm 3 share IRQ 4 while Comm 2 and Comm 4 share IRQ 3.
  257.     Therefore, only two ports can be operating simultaneously, ports 1 and 2,
  258.     1 and 4, 2 and 3, or 3 and 4.  You cannot operate Comm 1 and 3 or
  259.     Comm 2 and 4 at the same time.  You can have all four ports in your PC,
  260.     but only two can be active at once.  A future version of EnCom will
  261.     support multi-port boards which are designed to get around this limitation.
  262.  
  263. `co(0,7);                      EnCom Mechanics and Interrupts                          `co();
  264.  
  265.     The most important routine in any communications library is the comm
  266.   interrupt routine.  It comprises the heart of the entire library.  It is
  267.   in this routine that all data is received and transmitted.  All other
  268.   functions merely help you get the data into and out of the transmit and
  269.   receive queues.
  270.   
  271.     The interrupt routine has three primary tasks:
  272.     
  273.     1)  `keyword(Receive,The Receive Interrupt); data from the UART.
  274.     2)  `keyword(Transmit,The Transmit Interrupt); data to the UART.
  275.     3)  `keyword(Watch,Interrupt Status); the control lines and break status.
  276.     
  277.   Of these four, the first two are the most critical, and by nature the
  278.   most complex.
  279.  
  280. `co(0,7);                          The Receive Interrupt                               `co();
  281.  
  282.     When the UART receives a character, it generates an interrupt.  The
  283.     interrupt routines sees that this is a new character and must decide what
  284.     to do with it.  First it checks to see if there are any errors (i.e.
  285.     parity, framing or overrun).  If there is an error, it increments the
  286.     appropriate counter in the port structure.  It then checks to see if
  287.     `co(15,?);XON/XOFF`co(); handshaking is being used.  If it is in use, it checks to see if
  288.     the character was an XOFF and if so, turns the transmitter off.  If not,
  289.     it checks to see if the character was an XON character.  If so, it resumes
  290.     transmission.  Next, it checks to see if adding the character to the
  291.     receive queue will cause the queue to hit its "highwater" mark.  The
  292.     "highwater" mark is a user-definable number that when hit makes the
  293.     interrupt tell the other system "I have all the data I can safely take for
  294.     now".  If this condition is met, the interrupt routine sends an XOFF
  295.     character to the other system, thereby temporarily halting its
  296.     transmission.  Finally, if the character is not processed by the above
  297.     flow control, it is stored into the receive queue.
  298.     
  299.       This may sound somewhat complicated, but it is really quite simple.
  300.     Basically, data is received and stored in the receive queue, and if the
  301.     queue starts to get full, we tell the other system to "hang on a minute".
  302.     Likewise, we check to see if the other system is telling us to "hang on
  303.     a minute", so we do not fill up its queue.  Keep in mind that both
  304.     systems can send and receive data simultaneously!
  305.  
  306.  
  307. `co(0,7);                          The Transmit Interrupt                              `co();
  308.  
  309.     The transmit interrupt handling is much simpler than the receive
  310.   interrupt, as it only has to do a simple check.  If no flow control is
  311.   in use, we simply send the byte.  If `co(15,?);XON/XOFF`co(); is in use, we check to
  312.   see if transmission is temporarily suspended, and if so do nothing.
  313.   Otherwise, we send the next byte in the transmit queue.
  314.  
  315. `co(0,7);                    Interrupt Status and Line Control                         `co();
  316.  
  317.     When the line status (DSR, DCD, CTS, RI) changes, an interrupt is
  318.   generated.  The status of each of the lines is stored as a separate bit
  319.   in the port status variable.  By storing in this manner, you can
  320.   utilize the variable to find out if any of the lines have changed over
  321.   a period of one or many characters.  We provide a comprehensive set of
  322.   macros that allow you to determine the state of these lines directly,
  323.   or if the state has changed since you last checked.  Several methods
  324.   of flow control can be handled here as well, see `keyword(Flow Control, Flow Control ); for
  325.   more information.
  326.   
  327.     When a "break" condition is sensed, the interrupt routine simply 
  328.   increments the break counter in the port structure.  The user application
  329.   can check this variable to determine if a break condition has occured.
  330.  
  331. `co(0,7);                                  Flow Control                               `co();
  332.  
  333.     EnCom provides several methods of flow control.  The following lists
  334.   the flow control types supported by EnCom.
  335.   
  336.   `co(15,?);XON/XOFF`co();
  337.       Perhaps the most common flow control, a bidirectional software method
  338.     as described above in `keyword(Receive,The Receive Interrupt);.  The primary drawback to XON/XOFF
  339.     is that there must be two unique characters that will not be used for
  340.     anything else, thereby preventing the reception and transmission of binary
  341.     data.
  342.  
  343.   `co(15,?);DCR/DCD`co();
  344.     Unlike XON/XOFF, this is a hardware flow control.  It works as follows:
  345.     First, if DCD (Data Carrier Detect) flow control is enabled, all incoming
  346.     data will be ignored unless DCD is asserted (Logic 1).  The same option is
  347.     available using the DSR (Data Set Ready Line).  These two lines can be
  348.     used in combination, requiring that both be asserted for data to be
  349.     received. These modes are set with the functions `keyword(set_dcd_flow,[ENCOMREF.HLP]/// set_dcd_flow); and
  350.     `keyword(set_dsr_flow,[ENCOMREF.HLP]/// set_dsr_flow);.
  351.  
  352.   `co(15,?);RTS/CTS`co();
  353.     RTS/CTS (Request-to-send / Clear-to-send) handshaking is another form of
  354.     hardware flow control.  This is a half-duplex method and is not commonly
  355.     used with modern communications equipment, but is included for
  356.     compatibility.  Here's how it works.  When data needs to be transmitted,
  357.     the system asserts RTS.  The data communications equipment senses this,
  358.     finishes what it's doing (sending data), and asserts the CTS line.  When
  359.     we see the CTS line go high, we send our data.  When we are through, we
  360.     drop the RTS line to tell the communications equipment that we are
  361.     through.  Use the `keyword(set_cts_flow,[ENCOMREF.HLP]#define set_cts_flow); macro for this flow control.
  362.  
  363.   `co(15,?);High Speed RTS/CTS`co();
  364.          This is a bidirectional RTS/CTS method, sometimes referred to as RTR/CTS
  365.      (ready-to-receive / clear-to-send).  This is set by using the same
  366.   `keyword(set_cts_flow,[ENCOMREF.HLP]#define set_cts_flow); macro as RTS/CTS, but passing the #define HS_RTS_CTS instead
  367.     of ON.  This flow control method, as used by many high speed modems, works
  368.     as follows:  When the receiving system can accept data, it sets RTS (RTR)
  369.     high, telling the transmitting equipment that it is ready to receive.
  370.     This is set when the receive queue is below the "lowwater" mark as set by
  371.     the `keyword(set_lowwater,[ENCOMREF.HLP]#define set_lowwater); macro.  When the receive queue reaches the "highwater"
  372.     mark, as set by the `keyword(set_highwater,[ENCOMREF.HLP]#define set_highwater); macro, it drops RTR, telling the
  373.     transmitting equipment to "hold on".  When the transmitting equipment
  374.     needs to send data, it waits until the CTS line goes high.  It then
  375.     transmits until the CTS line drops low.  This is similar to the standard
  376.     RTS/CTS method but the lines remain independent; the transmitter never
  377.     issues a request-to-send, it merely checks the state of the CTS line. This
  378.     method is probably the best handshaking method available, since XON/XOFF
  379.     is limited to ASCII data and the others are not bidirectional. Its use
  380.     is recommended wherever possible.
  381.  
  382.         Computer                                                   Modem
  383.          ---------                                                  -------
  384.     RTS (RTR) --->--- computer tells modem it's ready --->--- CTS
  385.     CTS       ---<--- modem tells computer it's ready ---<--- RTS (RTR)
  386.  
  387.  
  388.         That's about it.  Other methods can be used but are not "built into" the
  389.     library.  Complete control over the modem control lines is only a macro or
  390.     function call away!
  391.  
  392. `co(0,7);                   EnCom's "Queue Status" Receive Mode                        `co();
  393.  
  394.     EnCom has the ability to queue the line status register with every
  395.   character received.  This can be enabled or disabled at any time using
  396.   the `keyword(set_queue_status,[ENCOMREF.HLP]#define set_queue_status); macro.  When enabled, the character is queued
  397.   followed by the status.  The status byte is an exact copy of the UART's
  398.   line status register and can be checked using the masks defined in
  399.   ENCOM.H.  These are as follows:
  400.     `co(12,?);
  401.     /*-------------------- line status register bit masks ------------------*/
  402.     #define DR          0x01                    /* data ready                                                         0    */
  403.     #define OE          0x02                    /* overrun error                                                 1    */
  404.     #define PE          0x04                    /* parity error                                                  2    */
  405.     #define FE          0x08                    /* framing error                                                  3    */
  406.     #define BI          0x10                    /* break interrupt                                             4    */
  407.     #define THRE     0x20                    /* transmitter holding register empty         5    */
  408.     #define TSRE     0x40                    /* transmitter shift   register empty         6    */
  409.     #define F_ERR  0x80                    /* FIFO error (only for 16550)           7    */
  410.     `co();  
  411.  
  412.         Keep in mind that when enabled, the receive queue will require twice the
  413.     space to store a given number of characters.  Also, when extracting data
  414.     from the queue using `keyword(com_getc,[ENCOMREF.HLP]/// com_getc); and `keyword(com_getc_qty,[ENCOMREF.HLP]/// com_getc_qty); the status information
  415.     is removed as well.  See these routines for more information.
  416.  
  417.  
  418. `co(0,7);                        CRC and Message Formatting                            `co();
  419.  
  420.     EnCom's CRC generation functions provide much more than just support
  421.   for X/Ymodem CRC calculation.  CRC in general is an excellent way to
  422.   verify the integrity of serially transmitted data.  The EnCom routines
  423.   will support the generation of CRC's for any polynomial, including the
  424.   standard CRC-16 and CRCCITT standards, in both forward and reverse modes.
  425.   The standard method, forward CRCCITT with preset 0's, is used by
  426.   X/Ymodem and will suffice for most needs.
  427.   
  428.     Many of you are probably wondering what "message formatting" routines
  429.   are.  Just sit back and follow along, because chances are, you will find
  430.   a use for these after you finish reading this section.  The best way to
  431.   describe this facility is to show you an example.
  432.   
  433.     Joe at Weather Systems, Inc. takes data readings from several different
  434.   instruments every 10 seconds 24 hours a day.  The equipment that came
  435.   with the instruments included a PC board that just plugged into his
  436.   computer, and some lab-type software written in C that gives him access
  437.   to the numbers from each of the instruments.  Joe wrote a program that
  438.   "snapshots" the data every 10 seconds, and stores it in a structure.  The
  439.   structure looks like this:
  440.   
  441.   typedef struct wdata_struct
  442.   {
  443.     int     wind_speed;
  444.     int     wind_direction;
  445.     int     temp;
  446.     int     humidity;
  447.     double  rainfall;
  448.     double  pressure;
  449.     long    timedate;
  450.   } WDATA;
  451.   
  452.     Ok, so Joe has his data in a nice little structure, and he can log these
  453.     structures to disk for storage.  The problem arises when Joe's boss, Dick,
  454.     tells him that he needs the data to be transmitted over a lease line to
  455.     Dan at the Chicago office 24 hours a day.  The boss also wants the data
  456.     transmitted as fast as the modem will allow, namely 9600 baud.  He also
  457.     wants the data encrypted, so that if anyone is watching the line, they
  458.     won't know what the data is.  So how does Joe do this?  Joe knows he needs
  459.     some sort of ending character that will mark the end of a structure, but
  460.     since he is sending doubles, ints, and longs, how can he guarantee the end
  461.     character he chooses is not in the structure?  That would really mess
  462.     things up.  Things get even more complicated when Dick tells Joe he wants
  463.     another structure sent every few seconds that is a whole set of different
  464.     variables, and whatever algorithm he uses must be able to send any other
  465.     structures defined later.  What does Joe do (besides quit)?
  466.   
  467.       Joe wishes he had a function that would just take any structure and
  468.     transmit it without having to worry about all the ugly details.  Then
  469.     he reads about EnCom's message facilities and this sparks his interest.
  470.     After reading about the function `keyword(fmt_msg,[ENCOMREF.HLP]/// fmt_msg); he raises his hands to the sky
  471.     and does a little dance.  The function is exactly what he needs.
  472.     
  473.       The fmt_msg function encapsulates any data into a unit called a
  474.     "message".  A message is a data packet that contains the data in a
  475.     "quoted" format followed by a two-byte CRC and a unique ending flag
  476.     character.  So what does this mean?
  477.     
  478.       Quoting a message is a process by which undesired characters that are
  479.     within the data are translated into a two-character sequence that does
  480.     not contain an undesired character.  This is necessary if we wish to
  481.     have a message that does not contain our end flag character.  This
  482.     is how Joe's problem of having the end flag character a part of
  483.     his structure is resolved.  See `keyword(quoting,Quoting Mechanics); for specific details.
  484.  
  485.     Once fmt_msg quotes and encrypts the data, it then calculates the CRC
  486.     for the entire message, and appends the two bytes to the end of the
  487.     message. Finally, the end flag character is tagged on and the message can
  488.     be transmitted by calling `keyword(com_putc_qty,[ENCOMREF.HLP]/// com_putc_qty);.  It's that simple!
  489.  
  490.     When the receiving system in Chicago gets the data, it checks for the
  491.   unique ending flag character as a mark of the end of the packet.  It
  492.   then pulls the entire message out of the port receive queue, (end-flag to
  493.   end-flag), knows that the last two bytes are the CRC, and calculates the
  494.   CRC on all but the last two bytes.  It then compares it to the transmitted
  495.   CRC and if they do not match, it pitches the message.  To encapsulate
  496.   all this, we give you a little function called get_msg that does all
  497.   the decryption, dequoting, and CRC checking for you!
  498.   
  499.     Select `keyword(example,A Specific Example); for a run-through of the process EnCom goes through
  500.   when fmt_msg and get_msg are used.
  501.  
  502. `co(0,7);                             Quoting Mechanics                                `co();
  503.  
  504.     To "quote" a message, we simply check for an end flag character, and
  505.     when found, replace it with the quote flag character 0x88, followed by the
  506.     end flag character "exclusive or'ed" with the quote mask character 0x11.
  507.     This installs a two-byte sequence that cannot contain the original end
  508.     flag character.  Since the quote flag itself marks a two-byte sequence,
  509.     then any occurences of that character must also be quoted to a two-byte
  510.     sequence, just like the end flag. This end flag can be set to whatever
  511.     character you wish, although it is a good idea to select a character that
  512.     does not appear very often in the type of data you are sending to avoid
  513.     expanding the data by a significant amount. (It must not be 0x88 or 0x11).
  514.  
  515. `co(0,7);                             A Specific Example                               `co();
  516.  
  517.   /*----------------------------- Joe's Code ------------------------------*/
  518.     int len;
  519.     PORT  Port;                                                            /* Joe's channel 1 port struct     */
  520.     WDATA wdata;                                                        /* where the data is stored      */
  521.   uchar buffer[sizeof(WDATA)*2+5];                /* make sure we have enough room */
  522.   ...                                                                            /* init code goes here                     */
  523.   `keyword(set_encrypt,[ENCOMREF.HLP]#define set_encrypt);(0x21,&Port);                                 /* set encryption character      */
  524.   `keyword(set_match,[ENCOMREF.HLP]#define set_match);(0xf0,&Port);                                     /* set match (end_flag) character*/
  525.   `keyword(init_msg,[ENCOMREF.HLP]#define init_msg);(&Port);                                                /* tell functions about chars         */
  526.  
  527.     while( 1 )
  528.     {
  529.         get_data(&wdata);                                            /* Joe's function to get the data*/
  530.         len = `keyword(fmt_msg,[ENCOMREF.HLP]/// fmt_msg);((uchar *) &wdata,       /* format the message            */
  531.                       buffer, sizeof(WDATA));
  532.       `keyword(com_putc_qty,[ENCOMREF.HLP]/// com_putc_qty);(buffer, len, &Port);            /* send the data to Chicago          */
  533.     }
  534.  
  535.   /*----------------------------- Dan's Code ------------------------------*/
  536.     int len;
  537.     PORT  Port;                                                            /* Dan's channel 3 port struct     */
  538.     WDATA wdata;                                                        /* where the data is stored      */
  539.   uchar buffer[sizeof(WDATA)*2+5];                /* make sure we have enough space*/
  540.   ...                                                                            /* init code goes here                     */
  541.   `keyword(set_encrypt,[ENCOMREF.HLP]#define set_encrypt);(0x21,&Port);                                 /* set encryption character      */
  542.   `keyword(set_match,[ENCOMREF.HLP]#define set_match);(0xf0,&Port);                                     /* set match (end_flag) character*/
  543.   `keyword(init_msg,[ENCOMREF.HLP]#define init_msg);(&Port);                                                /* tell functions about chars    */
  544.     
  545.     while( 1 )
  546.     {
  547.         if( `keyword(msg_cnt,[ENCOMREF.HLP]#define msg_cnt);(&Port) )                  /* is there a message available? */
  548.         {
  549.             if( !(len = `keyword(get_msg,[ENCOMREF.HLP]/// get_msg);(buffer,&Port)) )/* if so, go get it                            */
  550.                 printf("Error\r\n");                            /* if 0 returned, there an error */
  551.             movmem(buffer, &wdata, len);                /* get copy into structure             */
  552.             print_data(&wdata);                 /* Dan's print routine                     */
  553.             save_data(&wdata);                                    /* Dan's save routine                         */
  554.         }
  555.     }
  556.  
  557.       Note that we get the message into a temporary buffer; this is because
  558.     the two byte CRC is extracted into the message.  This is due to the fact
  559.     that we don't yet know it's the CRC until the end_flag is hit.  This two
  560.     byte CRC is not included in the count, however.  If the CRC fails, get_msg
  561.     returns a 0, otherwise the length is returned.  That's all there is to it!
  562.  
  563. `co(0,7);                        EnCom 16550 UART Support                              `co();
  564.  
  565.         EnCom fully supports the 16550AF and 16550AFN UARTs.  The library will
  566.     automatically detect the type of UART in your system (8250, 16450, 16550)
  567.     and enable the FIFO's for you.  You can override this with the provided
  568.     macros.  There are many varieties and revisions to the UARTs used in PC's.
  569.     Most older 8088 based system use the 8250.  AT variety machines with their
  570.     somewhat higher speed used the 8250A or 16450 (both detected as a 16450).
  571.     These are functionally identical to the 8250 except for faster access time
  572.     and a single scratchpad register.  The 16550 in it's original variety was
  573.     "buggy" and the FIFO's were not useable; EnCom detects this as a 16450,
  574.     thereby disabling the FIFO's.  The 16550AF and 16550AFN are generally not
  575.     found in most machines due to their higher cost; however, if you are doing
  576.     high speed communications or need that little extra performance edge,
  577.     these parts are the way to go.  They can reduce transmit interrupt
  578.     overhead by nearly 16 to 1, and receive interrupt overhead by nearly the
  579.     same, depending on the receive trigger level set.  As stated, these parts
  580.     are automatically sensed and enabled.  The receive trigger is defaulted to
  581.     8 but can be set to 1, 4, 8, or 14 using the `keyword(com_fifo_trigger,[ENCOMREF.HLP]/// com_fifo_trigger); function.
  582.     Another function, `keyword(com_fifo_ctrl,[ENCOMREF.HLP]/// com_fifo_ctrl);, allows enabling/disabling the FIFO's as
  583.     well as clearing them.  It is recommended that the macros we provide for
  584.     FIFO control be used as opposed to calling com_fifo_ctrl yourself.
  585.  
  586.       NOTE: Even though the 16650 generates an interrupt every "x" characters,
  587.     if the FIFO trigger level is not reached and no data has been received
  588.     for 4 character times, a "timeout" interrupt will be generated and the
  589.     remaining bytes will be extracted; a wonderful feature of the 16550!
  590.  
  591. `co(0,7);                       The EnCom Library Reference                            `co();
  592.  
  593.     The EnCom library is composed of both `keyword(macros,EnCom Macros); and `keyword(functions,[ENCOMREF.HLP]EnCom Functions);.  To keep
  594.   the library small, any functionality that takes one line or less of C
  595.   code is implemented with a macro.  Some of the macros simply call one
  596.   of the functions with the proper parameters.  Many of the modem commands
  597.   are implemented in this manner.   Other macros serve to "hide" the port
  598.   structure.
  599.   
  600.       The EnCom library has a few global variables that may be used in special
  601.   cases.  For more information see `keyword(Structures and Globals,EnCom Structures);.
  602.  
  603.  
  604. `co(0,7);                      EnCom Structures and Globals                            `co();
  605.  
  606.     The only structure definition used by EnCom is the PORT structure.  It
  607.   is used by nearly every function in the library.  It should never be
  608.   necessary to access the structure directly, as the functions and macros
  609.   we provide handle all the details for you.  See `keyword(ENCOM.H,[ENCOM.H]ENCOM.H); for details.
  610.  
  611.       Several global variables may be used in special cases.  They are as
  612.     follows:
  613.     `co(12,?);  
  614.   int   Tics_per_sec;                            /* ~ tics/second of clock interrupt         */
  615.     char  Pause_char = '~';         /* pause character used by modem_cmd      */
  616.     char  Clear_rx_char = '<';            /* clear rx que char used by modem_cmd */
  617.     char  Clear_tx_char = '>';      /* clear tx que char used by modem_cmd */
  618.     uchar Encrypt_char = 0x35;      /* encryption character used by msg'ing*/
  619.     uchar End_flag = 0xf0;          /* end flag character used by msg'ing  */
  620.     `co();
  621.   The Encrypt_char and End_flag are set by calling the macros set_encrypt
  622.   and set_match, followed by init_msg.  Do not change Tics_per_sec as this
  623.   is set by init_clock. The other variables can be changed as needed.
  624.  
  625.  
  626. `co(0,7);                                EnCom Macros                                  `co();
  627.  
  628.     The EnCom macros add excellent capability to the EnCom libarary.  We
  629.     employ an OOP technique and do a little "information hiding" for you.
  630.     Basically, we try to provide you with an easy to understand macro to
  631.     access all the port structure variables that you might need.  While you
  632.     can do this directly, there is no guarantee that the results will be what
  633.     you expect, or that we will never modify the structure.  Therefore, by
  634.     providing you with macro access, the code size remains small and you
  635.     don't have to worry about the details of the data structures.  However, if
  636.     you don't find a macro to do what you need, feel free to access the data
  637.     structure; better yet, write a macro and let us know about it!  The macros
  638.     are divided into categories for ease of reference.  These are:
  639.   
  640.   `keyword(General Macros,[ENCOMREF.HLP]EnCom General Mac);            `keyword(Comm Macros,[ENCOMREF.HLP]EnCom Com);       `keyword(Message Macros,[ENCOMREF.HLP]EnCom Mes);
  641.   `keyword(Handshaking Macros,[ENCOMREF.HLP]EnCom Hand);        `keyword(Modem Macros,[ENCOMREF.HLP]EnCom Mod);      `keyword(Line Status Macros,[ENCOMREF.HLP]EnCom Line);
  642.   `keyword(16550 Support Macros,[ENCOMREF.HLP]EnCom 16550);
  643.  
  644.     In addition, the modem and line status macros come in two basic types.
  645.     The "immediate" type determines the state at the time of the macros
  646.     execution, while the "static" type informs you of a state change since the
  647.     last clear macro was executed.  These allows you to check for the current
  648.     status, as well as changes in status over time.  The static type uses a
  649.     variable in the port structure, that gets "or'ed" with the appropriate bits
  650.     on interrupt, and is ideal for block mode checking.
  651.  
  652.