home *** CD-ROM | disk | FTP | other *** search
- `co(0,7); EnCom version 1.00 from EnQue Software `co();
- `tab(2);`color_default(LIGHTGRAY,BLUE);`color_keyword(YELLOW,BLUE);`color_first_char(WHITE,BLUE);
-
- `keyword(1) Using EnQue Help, Using This Help); `keyword(5) Flow Control, Flow Control );
- `keyword(2) Introduction, An Introduction to); `keyword(6) CRC & Message Formatting, CRC and Message);
- `keyword(3) Design Concepts, EnCom Design); `keyword(7) 16550 UART Support, EnCom 16550 UART);
- `keyword(4) How EnCom Works, EnCom Mechanics); `keyword(8) EnCom Library Reference, The EnCom Library);
-
- Press `co(15,?);[Tab]`co();, the arrow keys, or `co(15,?);1`co(); - `co(15,?);8`co(); to move the cursor to the desired
- topic, and press `co(15,?);[Enter]`co();.
- `co(15,?);
- To order the large model libraries, complete source code and printed
- documentation, send a check or money order for $99.95 to the address
- below. Order before September 1, 1992 and save 50% with our special
- summer price of $49.95! Orders from outside the USA please add $5.00
- for additional shipping and handling costs.
- `co();
- We recommend you page through and read all of this documentation and use
- the hypertext features when the help is used as a reference.`co();
-
- `co(0,7); Using This Help System `co();
- This help system is part of EnQue's UltraWin and InTUItion libraries,
- and was designed for useful hypertext systems. We use it for the disk-
- based documentation for our products. Using the help system is very
- easy. Simply use the keypad cursor keys to move around the help. You
- can also position the cursor on a keyword and press `co(15,?);[Enter]`co(); to move
- quickly to the section that deals with that keyword. Keywords for this
- documentation show up like this `co(15,1);K`co(14,1);eyword`co();. To move back to the previous
- section, simply press the `co(15,?);[Backspace]`co(); key.
-
- If you have a mouse, you can double-click on keywords, grab the scroll
- bars at the right and bottom of the help window, or click on any of the
- buttons. The buttons can also be used by pressing `co(15,?);ALT-KEY`co();, where `co(15,?);KEY`co(); is
- the highlighted letter.
-
- If you are a Borland C/Turbo C user, you can load our tiny TCKBD.COM
- TSR. This 4k routine allows you to invoke our help engine from the
- Integrated Environment, searching for the function/keyword on which the
- cursor resides, in much the same way as Borland's help. To do this, you
- must setup our help engine as a Transfer program. See your Borland manual
- for details. Include on the command line the $NOSWAP macro so that our
- help will overlay and restore the current window. A typical command line
- from within the transfer editor for EGA/VGA 43/50 row mode for ENQHELP.EXE
- might look like this: `co(15,?);"$NOSWAP ENCOMREF.HLP 1 0 2 2 77 40"`co();. The first
- numeric parameter is set to 1. This tells the help engine to call our TSR
- to get the string at the current cursor location, and use that as the
- search string. The next is a user search string (just use 0 to tell the
- engine no command line search string), and the next four numeric
- parameters are the screen coordinates start x, start y, end x, and end y.
- These last four parameters are optional. A window of the default size
- will be created if they are omitted.
-
- You may also run the help engine directly from the command line,
- removing the $NOSWAP macro. You need not load TCKBD.COM to do this.
- (TCKBD.COM merely allows the help engine to read the word that your cursor
- is currently pointing to - it does not ever have to be loaded, it merely
- adds functionality).
-
- `co(0,7); An Introduction to EnCom `co();
-
- Welcome to the EnCom library, version 1.00 (C) 1992 EnQue Software!
- EnCom provides the PC programming community with a powerful tool for
- developing communications applications. The EnCom library is written in
- 100% portable C and supports the Borland and Microsoft families of
- compilers. See `keyword(disclaimer,Disclaimer); for legal information on using the library.
-
- For information about this or other EnQue products, please contact us at:
-
- `co(14,?);EnQue Software Fax/Voice: (816) 987-2515
- Route 1, Box 116C 24 Hr BBS: (816) 353-0991
- Pleasant Hill, MO 64080 Kevin: (816) 987-5709
- Boyd: (816) 353-5561`co();
- `co(15,?);
- To order the large model libraries, complete source code and printed
- documentation, send a check or money order for $99.95 to the address
- above. Order before September 1, 1992 and save 50% with our special
- summer price of $49.95! Orders from outside the USA please add $5.00
- for additional shipping and handling costs.
-
- `co(0,7); Disclaimer `co();
-
- EnCom is a user supported communications library for the IBM PC. EnCom
- is copyrighted material. However, we distribute the small model libraries
- and disk-based documentation at no charge. We do this so that you can
- actually use the library to be sure it suits your needs before purchasing
- the product. Please feel free to give the small model libraries and
- disk-based documentation to whomever you wish. You are also free to
- distribute any executables generated with EnCom royalty free.
-
- Under no conditions may you duplicate or distribute the EnCom large
- model libraries or EnCom source code without the prior written consent of
- EnQue Software.
-
- Purchasing the commercial version provides you not only with large model
- libraries and complete source code, but also free technical support and
- software upgrades through the EnQue BBS.
-
- The authors have taken great care in preparing this disk-based manual
- and accompanying programs and data, including research, development, and
- testing. The authors make no expressed or implied warranty of any kind
- with regard to the software or accompanying documentation. In no event
- shall the authors or EnQue Software be liable for incidental or
- consequential damages in connection or arising out of the performance or
- use of any part of this product.
-
- `co(0,7); EnCom Design Concepts `co();
-
- The EnCom library was designed around several key concepts, which we
- feel separates EnCom from other libraries of its type. Please note that
- we assume some working knowledge of PC communications. Our documentation
- would unfortunately triple in size if we covered all aspects, making it
- more difficult to understand. If you need more information on the 8250
- UART, modem control, etc. refer to your computer or modem manual, or a
- text pertaining to PC communications.
-
- Press `co(15,?);[Tab]`co(); or the arrow keys to move the cursor to the desired concept,
- and press `co(15,?);[Enter]`co();.
-
- `keyword(Small Code Size,1. Small);
- `keyword(100% Portable C,2. 100%);
- `keyword(Ease of Use,3. Ease);
- `keyword(Rich in Features,4. Rich);
- `keyword(Sample C Code,5. Sample C);
-
- `co(15,?);1. Small Code Size:`co();
- The library must be very small, consisting of as few functions as are
- necessary to accomplish a well-rounded comm toolbox. Many other
- products boast of hundreds of functions, many of which are redundant,
- and some of which are just unnecessary. We try to concentrate on
- making the library lean and mean, and work hard on eliminating fluff.
- As a result the library is very powerful, but is only about 16K in
- size!
-
- `co(15,?);2. 100% Portable C`co();
- The library must be 100% portable C. This may come as a real
- surprise to many. If you don't think 100% C can be small and fast then
- you must take a look at our text windowing library UltraWin, or our
- user interface library InTUItion! In real terms, the only function
- within the library that should even be considered as an assembler
- candidate is the interrupt routine itself. However, with efficient C
- coding and today's optimizing compilers, the speed of the C code is
- within a few percent of the assembly version. We discovered this after
- hours of hand-optimizing the assembly code for the interrupt routine,
- and then comparing its performance against a carefully optimize C
- interrupt routine. The extra few percent gained is not worth the loss
- in portability. Another reason to strive for 100% C is that you the
- customer can more easily understand and if needed modify the code,
- thereby making the product more usable. And if you wish to port the
- code to another CPU or another platform, your job will be much easier
- without assembly headaches. In addition, by taking advantage of the
- fast memory move capabilites of the PC and FIFO (first in, first out)
- capabilities of UARTs such as the 16550, speeds as high as 115,000
- Kbaud are readily attainable, all in 100% C, and even on older PC's.
-
- `co(15,?);3. Ease of Use`co();
- The library must be very easy to use. The first two concepts make
- this an easily attainable target. By keeping the library in 100% C,
- and concentrating on more functionality with less code, the learning
- curve for EnCom is measured in minutes and hours, not days and weeks as
- is the case with many of our competitors. Functions are concise, well
- documented, clearly named, and intuitive in nature. The bottom line is
- that if a function is not needed, it is not in our library.
-
- `co(15,?);4. Rich in Features`co();
- The library must be very rich in features, yet easy to learn. It
- has always been our belief that the best solution to a problem is
- usually the least complex solution. When carefully thought out, a
- simple solution can be both functional and elegant. Contrary to what
- many companies believe, it is possible to have a small, concise, easy
- to learn library and yet be rich in features. The following are just
- a few examples of what we have been able to put into EnCom!
-
- A) `co(12,?);Fully interrupt driven transmit and receive`co(); with queues up to
- 64K in size, and a `keyword(queue status,EnCom's "Queue Status"); mode where each character is
- queued along with the current line status register, allowing a
- character by character look at errors.
- B) `co(12,?);Interrupt handlers`co(); for line/modem control and break.
- C) Support for `co(12,?);`keyword(Comm 1-4,Comm 1-4 Support); and FIFO'ed UARTs`co(); such as the 16550.
- D) Enhanced keyboard control such as `co(12,?);Ctrl-C and Ctrl-Break
- handling`co();. This feature takes control from the OS and places
- it in your hands.
- E) `co(12,?);Timer and sound support`co();. Enhanced timing resolution and
- interrupt-driven time events is crucial to comm software, yet
- so many libraries leave this feature out. In addition, control
- of the PC speaker is provided, and can be automatically turned
- off via the timer interrupt.
- F) `co(12,?);CRC generation and message formatting/encryption routines.`co();
- Perhaps no other library offers these features. EnCom can
- generate CRC's based on any polynomial, including the CRC-16
- and CCITT standards. In addition, message formatting routines
- are included that greatly simplify custom communications
- between two PC's. These routines are explained in more detail
- later. Needless to say, if you have data to send between two
- machines, you will fall in love with these routines!
-
- `co(15,?);5. Sample C code to begin using immediately`co();
- Two programs with full source are included. The first and simplest
- is only a few dozen lines yet implements full bidirectional
- communications and can be used to dial a BBS. If ANSI.SYS is loaded
- into your system, it will even emulate an ANSI terminal. This program,
- called START.C, shows how simple using EnCom really is. Just type
- START with an optional port and baud rate (default is COM1 at 2400
- baud). To use COM2 at 1200 baud, type `co(15,?);START 2 1200`co(); and press
- `co(15,?);[Enter]`co();.
-
- The second program is a "testbed" for EnCom and shows the use of most
- of EnCom's macros and functions. This program uses UltraWin for
- display, so many functions will seem unfamiliar. However, the code is
- very straightforward. This program, COM_DEMO.C, takes the same
- optional parameters as START.C. Once running, you may press Alt-H for
- a list of function keys and what they do. One thing to keep in mind
- here is that it won't seem like anything happens when many keys are
- pressed. This is the nature of manipulating comm hardware. For
- instance, toggling the DTR line won't show much unless you have a
- breakout box hooked to the port. Ideally, you will hook this to
- another machine or "loop" it back to itself so that anything sent is
- received. While we are on that subject, the PC UART has a built-in
- diagnostics loopback mode which can be set by calling `keyword(com_232_ctrl,[ENCOMREF.HLP]/// com_232_ctrl);.
- However, when this mode is activated, all the modem control lines are
- "disconnected" from the outside world, including OUT2. OUT2 is used by
- many comm boards to "mask" interrupts from the UART. Therefore, when
- placed in loopback mode, nothing is sent or received. You will notice
- though that "toggling" the control lines such as DTR or RTS will show a
- corresponding change on DSR and CTS. This is a very important point.
- If you ever enable LOOP (it is disabled automatically by the init
- functions), you will more than likely lose interrupt capability!
-
- Also, to show you the power of the library, we have included a
- powerful communications program in its own right. The terminal
- application supplied illustrates the use of EnCom functions, and
- contains `co(12,?); VT100 terminal emulation, upload and download ASCII,
- Xmodem Checksum, Xmodem CRC, and Ymodem protocols.`co();
-
- This mini-application also demonstrates the power of our sister
- products, UltraWin and InTUItion, and was written in just a few weeks
- using the three libraries. To start the program, just type TD and
- press `co(15,?);[Enter]`co();. This defaults to 2400 baud on COM2. To change the port
- and baud rate from the command line, type the additional parameters
- just as in START.C. For example, to use a modem on COM1 at 1200 baud,
- just type `co(15,?);TD 1 1200`co(); and press `co(15,?);[Enter]`co();. After the program comes up,
- you can press ALT-Z for help.
-
- Note that the executable is only about 100K even though it uses the
- low-level windowing library, the higher-level user interface library, a
- powerful hypertext help engine, and, of course, EnCom, not to mention
- the complete VT100 emulation and file transfer protocols and all the
- standard C stuff! `co(12,?);Most competing comm libraries are larger than
- this complete application!`co();
-
- `co(15,9);NOTE: Complete source code is included on purchase of EnCom!`co();
-
- `co(0,7); Comm 1-4 Support `co();
-
- EnCom supports comm ports 1-4. However, due to hardware limitations
- with most PC's, there can only be one device active on a given interrupt.
- Comm 1 and Comm 3 share IRQ 4 while Comm 2 and Comm 4 share IRQ 3.
- Therefore, only two ports can be operating simultaneously, ports 1 and 2,
- 1 and 4, 2 and 3, or 3 and 4. You cannot operate Comm 1 and 3 or
- Comm 2 and 4 at the same time. You can have all four ports in your PC,
- but only two can be active at once. A future version of EnCom will
- support multi-port boards which are designed to get around this limitation.
-
- `co(0,7); EnCom Mechanics and Interrupts `co();
-
- The most important routine in any communications library is the comm
- interrupt routine. It comprises the heart of the entire library. It is
- in this routine that all data is received and transmitted. All other
- functions merely help you get the data into and out of the transmit and
- receive queues.
-
- The interrupt routine has three primary tasks:
-
- 1) `keyword(Receive,The Receive Interrupt); data from the UART.
- 2) `keyword(Transmit,The Transmit Interrupt); data to the UART.
- 3) `keyword(Watch,Interrupt Status); the control lines and break status.
-
- Of these four, the first two are the most critical, and by nature the
- most complex.
-
- `co(0,7); The Receive Interrupt `co();
-
- When the UART receives a character, it generates an interrupt. The
- interrupt routines sees that this is a new character and must decide what
- to do with it. First it checks to see if there are any errors (i.e.
- parity, framing or overrun). If there is an error, it increments the
- appropriate counter in the port structure. It then checks to see if
- `co(15,?);XON/XOFF`co(); handshaking is being used. If it is in use, it checks to see if
- the character was an XOFF and if so, turns the transmitter off. If not,
- it checks to see if the character was an XON character. If so, it resumes
- transmission. Next, it checks to see if adding the character to the
- receive queue will cause the queue to hit its "highwater" mark. The
- "highwater" mark is a user-definable number that when hit makes the
- interrupt tell the other system "I have all the data I can safely take for
- now". If this condition is met, the interrupt routine sends an XOFF
- character to the other system, thereby temporarily halting its
- transmission. Finally, if the character is not processed by the above
- flow control, it is stored into the receive queue.
-
- This may sound somewhat complicated, but it is really quite simple.
- Basically, data is received and stored in the receive queue, and if the
- queue starts to get full, we tell the other system to "hang on a minute".
- Likewise, we check to see if the other system is telling us to "hang on
- a minute", so we do not fill up its queue. Keep in mind that both
- systems can send and receive data simultaneously!
-
-
- `co(0,7); The Transmit Interrupt `co();
-
- The transmit interrupt handling is much simpler than the receive
- interrupt, as it only has to do a simple check. If no flow control is
- in use, we simply send the byte. If `co(15,?);XON/XOFF`co(); is in use, we check to
- see if transmission is temporarily suspended, and if so do nothing.
- Otherwise, we send the next byte in the transmit queue.
-
- `co(0,7); Interrupt Status and Line Control `co();
-
- When the line status (DSR, DCD, CTS, RI) changes, an interrupt is
- generated. The status of each of the lines is stored as a separate bit
- in the port status variable. By storing in this manner, you can
- utilize the variable to find out if any of the lines have changed over
- a period of one or many characters. We provide a comprehensive set of
- macros that allow you to determine the state of these lines directly,
- or if the state has changed since you last checked. Several methods
- of flow control can be handled here as well, see `keyword(Flow Control, Flow Control ); for
- more information.
-
- When a "break" condition is sensed, the interrupt routine simply
- increments the break counter in the port structure. The user application
- can check this variable to determine if a break condition has occured.
-
- `co(0,7); Flow Control `co();
-
- EnCom provides several methods of flow control. The following lists
- the flow control types supported by EnCom.
-
- `co(15,?);XON/XOFF`co();
- Perhaps the most common flow control, a bidirectional software method
- as described above in `keyword(Receive,The Receive Interrupt);. The primary drawback to XON/XOFF
- is that there must be two unique characters that will not be used for
- anything else, thereby preventing the reception and transmission of binary
- data.
-
- `co(15,?);DCR/DCD`co();
- Unlike XON/XOFF, this is a hardware flow control. It works as follows:
- First, if DCD (Data Carrier Detect) flow control is enabled, all incoming
- data will be ignored unless DCD is asserted (Logic 1). The same option is
- available using the DSR (Data Set Ready Line). These two lines can be
- used in combination, requiring that both be asserted for data to be
- received. These modes are set with the functions `keyword(set_dcd_flow,[ENCOMREF.HLP]/// set_dcd_flow); and
- `keyword(set_dsr_flow,[ENCOMREF.HLP]/// set_dsr_flow);.
-
- `co(15,?);RTS/CTS`co();
- RTS/CTS (Request-to-send / Clear-to-send) handshaking is another form of
- hardware flow control. This is a half-duplex method and is not commonly
- used with modern communications equipment, but is included for
- compatibility. Here's how it works. When data needs to be transmitted,
- the system asserts RTS. The data communications equipment senses this,
- finishes what it's doing (sending data), and asserts the CTS line. When
- we see the CTS line go high, we send our data. When we are through, we
- drop the RTS line to tell the communications equipment that we are
- through. Use the `keyword(set_cts_flow,[ENCOMREF.HLP]#define set_cts_flow); macro for this flow control.
-
- `co(15,?);High Speed RTS/CTS`co();
- This is a bidirectional RTS/CTS method, sometimes referred to as RTR/CTS
- (ready-to-receive / clear-to-send). This is set by using the same
- `keyword(set_cts_flow,[ENCOMREF.HLP]#define set_cts_flow); macro as RTS/CTS, but passing the #define HS_RTS_CTS instead
- of ON. This flow control method, as used by many high speed modems, works
- as follows: When the receiving system can accept data, it sets RTS (RTR)
- high, telling the transmitting equipment that it is ready to receive.
- This is set when the receive queue is below the "lowwater" mark as set by
- the `keyword(set_lowwater,[ENCOMREF.HLP]#define set_lowwater); macro. When the receive queue reaches the "highwater"
- mark, as set by the `keyword(set_highwater,[ENCOMREF.HLP]#define set_highwater); macro, it drops RTR, telling the
- transmitting equipment to "hold on". When the transmitting equipment
- needs to send data, it waits until the CTS line goes high. It then
- transmits until the CTS line drops low. This is similar to the standard
- RTS/CTS method but the lines remain independent; the transmitter never
- issues a request-to-send, it merely checks the state of the CTS line. This
- method is probably the best handshaking method available, since XON/XOFF
- is limited to ASCII data and the others are not bidirectional. Its use
- is recommended wherever possible.
-
- Computer Modem
- --------- -------
- RTS (RTR) --->--- computer tells modem it's ready --->--- CTS
- CTS ---<--- modem tells computer it's ready ---<--- RTS (RTR)
-
-
- That's about it. Other methods can be used but are not "built into" the
- library. Complete control over the modem control lines is only a macro or
- function call away!
-
- `co(0,7); EnCom's "Queue Status" Receive Mode `co();
-
- EnCom has the ability to queue the line status register with every
- character received. This can be enabled or disabled at any time using
- the `keyword(set_queue_status,[ENCOMREF.HLP]#define set_queue_status); macro. When enabled, the character is queued
- followed by the status. The status byte is an exact copy of the UART's
- line status register and can be checked using the masks defined in
- ENCOM.H. These are as follows:
- `co(12,?);
- /*-------------------- line status register bit masks ------------------*/
- #define DR 0x01 /* data ready 0 */
- #define OE 0x02 /* overrun error 1 */
- #define PE 0x04 /* parity error 2 */
- #define FE 0x08 /* framing error 3 */
- #define BI 0x10 /* break interrupt 4 */
- #define THRE 0x20 /* transmitter holding register empty 5 */
- #define TSRE 0x40 /* transmitter shift register empty 6 */
- #define F_ERR 0x80 /* FIFO error (only for 16550) 7 */
- `co();
-
- Keep in mind that when enabled, the receive queue will require twice the
- space to store a given number of characters. Also, when extracting data
- from the queue using `keyword(com_getc,[ENCOMREF.HLP]/// com_getc); and `keyword(com_getc_qty,[ENCOMREF.HLP]/// com_getc_qty); the status information
- is removed as well. See these routines for more information.
-
-
- `co(0,7); CRC and Message Formatting `co();
-
- EnCom's CRC generation functions provide much more than just support
- for X/Ymodem CRC calculation. CRC in general is an excellent way to
- verify the integrity of serially transmitted data. The EnCom routines
- will support the generation of CRC's for any polynomial, including the
- standard CRC-16 and CRCCITT standards, in both forward and reverse modes.
- The standard method, forward CRCCITT with preset 0's, is used by
- X/Ymodem and will suffice for most needs.
-
- Many of you are probably wondering what "message formatting" routines
- are. Just sit back and follow along, because chances are, you will find
- a use for these after you finish reading this section. The best way to
- describe this facility is to show you an example.
-
- Joe at Weather Systems, Inc. takes data readings from several different
- instruments every 10 seconds 24 hours a day. The equipment that came
- with the instruments included a PC board that just plugged into his
- computer, and some lab-type software written in C that gives him access
- to the numbers from each of the instruments. Joe wrote a program that
- "snapshots" the data every 10 seconds, and stores it in a structure. The
- structure looks like this:
-
- typedef struct wdata_struct
- {
- int wind_speed;
- int wind_direction;
- int temp;
- int humidity;
- double rainfall;
- double pressure;
- long timedate;
- } WDATA;
-
- Ok, so Joe has his data in a nice little structure, and he can log these
- structures to disk for storage. The problem arises when Joe's boss, Dick,
- tells him that he needs the data to be transmitted over a lease line to
- Dan at the Chicago office 24 hours a day. The boss also wants the data
- transmitted as fast as the modem will allow, namely 9600 baud. He also
- wants the data encrypted, so that if anyone is watching the line, they
- won't know what the data is. So how does Joe do this? Joe knows he needs
- some sort of ending character that will mark the end of a structure, but
- since he is sending doubles, ints, and longs, how can he guarantee the end
- character he chooses is not in the structure? That would really mess
- things up. Things get even more complicated when Dick tells Joe he wants
- another structure sent every few seconds that is a whole set of different
- variables, and whatever algorithm he uses must be able to send any other
- structures defined later. What does Joe do (besides quit)?
-
- Joe wishes he had a function that would just take any structure and
- transmit it without having to worry about all the ugly details. Then
- he reads about EnCom's message facilities and this sparks his interest.
- After reading about the function `keyword(fmt_msg,[ENCOMREF.HLP]/// fmt_msg); he raises his hands to the sky
- and does a little dance. The function is exactly what he needs.
-
- The fmt_msg function encapsulates any data into a unit called a
- "message". A message is a data packet that contains the data in a
- "quoted" format followed by a two-byte CRC and a unique ending flag
- character. So what does this mean?
-
- Quoting a message is a process by which undesired characters that are
- within the data are translated into a two-character sequence that does
- not contain an undesired character. This is necessary if we wish to
- have a message that does not contain our end flag character. This
- is how Joe's problem of having the end flag character a part of
- his structure is resolved. See `keyword(quoting,Quoting Mechanics); for specific details.
-
- Once fmt_msg quotes and encrypts the data, it then calculates the CRC
- for the entire message, and appends the two bytes to the end of the
- message. Finally, the end flag character is tagged on and the message can
- be transmitted by calling `keyword(com_putc_qty,[ENCOMREF.HLP]/// com_putc_qty);. It's that simple!
-
- When the receiving system in Chicago gets the data, it checks for the
- unique ending flag character as a mark of the end of the packet. It
- then pulls the entire message out of the port receive queue, (end-flag to
- end-flag), knows that the last two bytes are the CRC, and calculates the
- CRC on all but the last two bytes. It then compares it to the transmitted
- CRC and if they do not match, it pitches the message. To encapsulate
- all this, we give you a little function called get_msg that does all
- the decryption, dequoting, and CRC checking for you!
-
- Select `keyword(example,A Specific Example); for a run-through of the process EnCom goes through
- when fmt_msg and get_msg are used.
-
- `co(0,7); Quoting Mechanics `co();
-
- To "quote" a message, we simply check for an end flag character, and
- when found, replace it with the quote flag character 0x88, followed by the
- end flag character "exclusive or'ed" with the quote mask character 0x11.
- This installs a two-byte sequence that cannot contain the original end
- flag character. Since the quote flag itself marks a two-byte sequence,
- then any occurences of that character must also be quoted to a two-byte
- sequence, just like the end flag. This end flag can be set to whatever
- character you wish, although it is a good idea to select a character that
- does not appear very often in the type of data you are sending to avoid
- expanding the data by a significant amount. (It must not be 0x88 or 0x11).
-
- `co(0,7); A Specific Example `co();
-
- /*----------------------------- Joe's Code ------------------------------*/
- int len;
- PORT Port; /* Joe's channel 1 port struct */
- WDATA wdata; /* where the data is stored */
- uchar buffer[sizeof(WDATA)*2+5]; /* make sure we have enough room */
- ... /* init code goes here */
- `keyword(set_encrypt,[ENCOMREF.HLP]#define set_encrypt);(0x21,&Port); /* set encryption character */
- `keyword(set_match,[ENCOMREF.HLP]#define set_match);(0xf0,&Port); /* set match (end_flag) character*/
- `keyword(init_msg,[ENCOMREF.HLP]#define init_msg);(&Port); /* tell functions about chars */
-
- while( 1 )
- {
- get_data(&wdata); /* Joe's function to get the data*/
- len = `keyword(fmt_msg,[ENCOMREF.HLP]/// fmt_msg);((uchar *) &wdata, /* format the message */
- buffer, sizeof(WDATA));
- `keyword(com_putc_qty,[ENCOMREF.HLP]/// com_putc_qty);(buffer, len, &Port); /* send the data to Chicago */
- }
-
- /*----------------------------- Dan's Code ------------------------------*/
- int len;
- PORT Port; /* Dan's channel 3 port struct */
- WDATA wdata; /* where the data is stored */
- uchar buffer[sizeof(WDATA)*2+5]; /* make sure we have enough space*/
- ... /* init code goes here */
- `keyword(set_encrypt,[ENCOMREF.HLP]#define set_encrypt);(0x21,&Port); /* set encryption character */
- `keyword(set_match,[ENCOMREF.HLP]#define set_match);(0xf0,&Port); /* set match (end_flag) character*/
- `keyword(init_msg,[ENCOMREF.HLP]#define init_msg);(&Port); /* tell functions about chars */
-
- while( 1 )
- {
- if( `keyword(msg_cnt,[ENCOMREF.HLP]#define msg_cnt);(&Port) ) /* is there a message available? */
- {
- if( !(len = `keyword(get_msg,[ENCOMREF.HLP]/// get_msg);(buffer,&Port)) )/* if so, go get it */
- printf("Error\r\n"); /* if 0 returned, there an error */
- movmem(buffer, &wdata, len); /* get copy into structure */
- print_data(&wdata); /* Dan's print routine */
- save_data(&wdata); /* Dan's save routine */
- }
- }
-
- Note that we get the message into a temporary buffer; this is because
- the two byte CRC is extracted into the message. This is due to the fact
- that we don't yet know it's the CRC until the end_flag is hit. This two
- byte CRC is not included in the count, however. If the CRC fails, get_msg
- returns a 0, otherwise the length is returned. That's all there is to it!
-
- `co(0,7); EnCom 16550 UART Support `co();
-
- EnCom fully supports the 16550AF and 16550AFN UARTs. The library will
- automatically detect the type of UART in your system (8250, 16450, 16550)
- and enable the FIFO's for you. You can override this with the provided
- macros. There are many varieties and revisions to the UARTs used in PC's.
- Most older 8088 based system use the 8250. AT variety machines with their
- somewhat higher speed used the 8250A or 16450 (both detected as a 16450).
- These are functionally identical to the 8250 except for faster access time
- and a single scratchpad register. The 16550 in it's original variety was
- "buggy" and the FIFO's were not useable; EnCom detects this as a 16450,
- thereby disabling the FIFO's. The 16550AF and 16550AFN are generally not
- found in most machines due to their higher cost; however, if you are doing
- high speed communications or need that little extra performance edge,
- these parts are the way to go. They can reduce transmit interrupt
- overhead by nearly 16 to 1, and receive interrupt overhead by nearly the
- same, depending on the receive trigger level set. As stated, these parts
- are automatically sensed and enabled. The receive trigger is defaulted to
- 8 but can be set to 1, 4, 8, or 14 using the `keyword(com_fifo_trigger,[ENCOMREF.HLP]/// com_fifo_trigger); function.
- Another function, `keyword(com_fifo_ctrl,[ENCOMREF.HLP]/// com_fifo_ctrl);, allows enabling/disabling the FIFO's as
- well as clearing them. It is recommended that the macros we provide for
- FIFO control be used as opposed to calling com_fifo_ctrl yourself.
-
- NOTE: Even though the 16650 generates an interrupt every "x" characters,
- if the FIFO trigger level is not reached and no data has been received
- for 4 character times, a "timeout" interrupt will be generated and the
- remaining bytes will be extracted; a wonderful feature of the 16550!
-
- `co(0,7); The EnCom Library Reference `co();
-
- The EnCom library is composed of both `keyword(macros,EnCom Macros); and `keyword(functions,[ENCOMREF.HLP]EnCom Functions);. To keep
- the library small, any functionality that takes one line or less of C
- code is implemented with a macro. Some of the macros simply call one
- of the functions with the proper parameters. Many of the modem commands
- are implemented in this manner. Other macros serve to "hide" the port
- structure.
-
- The EnCom library has a few global variables that may be used in special
- cases. For more information see `keyword(Structures and Globals,EnCom Structures);.
-
-
- `co(0,7); EnCom Structures and Globals `co();
-
- The only structure definition used by EnCom is the PORT structure. It
- is used by nearly every function in the library. It should never be
- necessary to access the structure directly, as the functions and macros
- we provide handle all the details for you. See `keyword(ENCOM.H,[ENCOM.H]ENCOM.H); for details.
-
- Several global variables may be used in special cases. They are as
- follows:
- `co(12,?);
- int Tics_per_sec; /* ~ tics/second of clock interrupt */
- char Pause_char = '~'; /* pause character used by modem_cmd */
- char Clear_rx_char = '<'; /* clear rx que char used by modem_cmd */
- char Clear_tx_char = '>'; /* clear tx que char used by modem_cmd */
- uchar Encrypt_char = 0x35; /* encryption character used by msg'ing*/
- uchar End_flag = 0xf0; /* end flag character used by msg'ing */
- `co();
- The Encrypt_char and End_flag are set by calling the macros set_encrypt
- and set_match, followed by init_msg. Do not change Tics_per_sec as this
- is set by init_clock. The other variables can be changed as needed.
-
-
- `co(0,7); EnCom Macros `co();
-
- The EnCom macros add excellent capability to the EnCom libarary. We
- employ an OOP technique and do a little "information hiding" for you.
- Basically, we try to provide you with an easy to understand macro to
- access all the port structure variables that you might need. While you
- can do this directly, there is no guarantee that the results will be what
- you expect, or that we will never modify the structure. Therefore, by
- providing you with macro access, the code size remains small and you
- don't have to worry about the details of the data structures. However, if
- you don't find a macro to do what you need, feel free to access the data
- structure; better yet, write a macro and let us know about it! The macros
- are divided into categories for ease of reference. These are:
-
- `keyword(General Macros,[ENCOMREF.HLP]EnCom General Mac); `keyword(Comm Macros,[ENCOMREF.HLP]EnCom Com); `keyword(Message Macros,[ENCOMREF.HLP]EnCom Mes);
- `keyword(Handshaking Macros,[ENCOMREF.HLP]EnCom Hand); `keyword(Modem Macros,[ENCOMREF.HLP]EnCom Mod); `keyword(Line Status Macros,[ENCOMREF.HLP]EnCom Line);
- `keyword(16550 Support Macros,[ENCOMREF.HLP]EnCom 16550);
-
- In addition, the modem and line status macros come in two basic types.
- The "immediate" type determines the state at the time of the macros
- execution, while the "static" type informs you of a state change since the
- last clear macro was executed. These allows you to check for the current
- status, as well as changes in status over time. The static type uses a
- variable in the port structure, that gets "or'ed" with the appropriate bits
- on interrupt, and is ideal for block mode checking.
-