home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
World of Shareware - Software Farm 2
/
wosw_2.zip
/
wosw_2
/
CPROG
/
TCOMM6.ZIP
/
LCDOC.EXE
/
LC6.DOC
next >
Wrap
Text File
|
1991-08-25
|
149KB
|
4,029 lines
OVERVIEW . .. . . . . . . . . . . .. . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . . . . . . .. . . . 1
INTRODUCTION . . . . . . . . . . . .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
What is Shareware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . 1
LICENSE, WARRANTY AND REGISTRATION . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
LICENSE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
WARRANTY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . 2
REGISTRATION . . . . . . . . .. . . . . . . .. . . .. . . .. . . . . . . .. . . .. . . .. . . . . . 2
IS REGISTRATION WORTHWHILE? . . . . . . . . . . . . . . . . . . . .. . . .. . . .. . .. 2
Serial Port Fundamentals . .. . . . . . . .. .. .. . . . . . . . . . .. . . . .. . . .. .. . . . 3
The 8250 UART family . .. . .. .. .. .. . . .. . . .. .. .. .. .. . . . . .. .. . .. . . 3
Purpose of the port . . . .. . . . . . .. . .. .. . . . .. .. . . . . . . .. . . . . . .. . 3
INTERNAL PORT DETAILS . . .. . . . .. . . .. .. . . . . .. .. . . . . .. . . .. . .. .. . . 3
The Interrupt Connection . . .. . .. . . . .. . . . .. . . . .. . . . .. . . . .. .. . 4
THE PORT REGISTERS
LiteComm
Communications ToolBox
Copyright 1987 - 1991
Information Technology, Ltd.
Information Technology
5 Park Blvd.
Lincoln, RI 02865
(401) 724-2730
OVERVIEW
INTRODUCTION
TM
The LiteComm ToolBox is a set of powerful routines designed to
provide easy access to the full capabilities of the PC's asynch-
ronous communications ports. The LiteComm ToolBox provides
interrupt-driven, buffered communications support on COM1 through
COM4 simultaneously. Now you can quickly incorporate sophis-
ticated communications support in your applications without hav-
ing in-depth knowledge of how the hardware functions.
LiteComm is the result of meeting a need for communications in
CAD/CAM applications created for a client company. Each version
of the LiteComm ToolBox depends upon its respective host compil-
er.
The 'Lite' in LiteComm refers to the high granularity of the
product. LiteComm, in simple applications, adds about 5K bytes of
overhead. Yet it provides a highly reliable base on which to
build.
As you use LiteComm, you will find yourself in good company. Li-
teComm is currently in use at ATT, IBM, NASA, and the Associated
Press, to name a few of our users. In addition, LiteComm has been
featured in at least one book, Straight Talk by Charles Bowen and
Stewart Schneider. Finally, the Turbo Pascal version of LiteComm
is the basis for the Async Professional package from Turbopower
Software.
What is Shareware
Shareware is a "try before you buy" means of software distribu-
tion. If you find a shareware product useful, pay the registra-
tion fee, and let the authors know that you support their
efforts.
Information Technology is a member of the Association of Share-
ware Professionals (ASP). ASP wants to make sure that the
shareware principle works for you. If you are unable to resolve
a shareware-related problem with an ASP member by contacting the
member directly, ASP may be able to help. The ASP Ombudsman can
help you resolve a dispute or problem with an ASP member, but
does not provide technical support for members' products. Please
write to the ASP Ombudsman at P.O. Box 5786, Bellevue, WA 98006
or send a Compuserve message via easyplex to ASP Ombudsman
70007,3536.
1
LICENSE, WARRANTY AND REGISTRATION
LICENSE
Information regarding the LiteComm license will be found in the
file LICENSE.DOC, on the distribution diskette. Please read this
information. By your use of LiteComm, we assume that you agree to
the terms and conditions of the license agreement.
If you are interested in a site license for LiteComm, please see
the file SITELICE.DOC on the distribution disk.
WARRANTY
The LiteComm warranty is in the distributed file WARRANTY.DOC. Be sure you read the warranty before using LiteComm.
REGISTRATION
Registration information and an order form are in the file
REGISTER.DOC.
IS REGISTRATION WORTHWHILE?
LiteComm is a package undergoing continuing development. We are
constantly reviewing the product to make it smaller, faster, more
reliable, and easier to use. Since its introduction in mid 1987,
we have made significant changes to the LiteComm kernel, the
heart of the ToolBox, to improve efficiency and reliability. We
have also delivered to registered users protocol engines, LXM -
the Xmodem engine, which supports Xmodem and Xmodem-1K; and LWXM
- the Windowed Xmodem engine. We also provide a version of the
Compuserve QUICKB protocol, specially adapted for use with the
LiteComm ToolBox.
We are also reviewing other protocol engine implementations. In
this release of LiteComm, for example, we have added support for
True YModem and ZModem. The small model library, as enhanced will
always be offered as a shareware product.
2
Serial Port Fundamentals
The 8250 UART family
This portion of the manual provides you with some details about the working of the 8250 (and related) UART'S, the basic component
of your system's serial port. Some close compatibles use en-
hanced versions of this chip, such as the 16450 and 16550.
LiteComm works successfully with such devices. If you have
questions about the type of serial port you are using, refer to
the manufacturer's documentation. If your serial port does not
use an 8250 or similar chip, LiteComm will not function.
Purpose of the port
The serial port converts information from the form in which it is
used within your system, to a form that can be easily used out-
side your system. Modern computers, by design, are parallel in
nature. By this we mean that information travels through the
computer's circuitry as whole units or as multiples of whole
units. In the IBM PC and related systems, information travels as
bytes (8 bits at a time), as words (16 bits at a time), or, on
80386 and 80486 based systems, as double words (32 bits at a
time).
Within the computer, such arrangements are convenient and fast.
When the computer must transfer information to an external de-
vice, data path width is a problem. To provide a parallel path
between the computer and external devices, there would have to be
enough data lines or circuits between the two to satisfy the data
path. For most modern computer systems, this would mean a mini-
mum of 8 data lines, not counting any additional control
information that also might be necessary. For certain newer
systems, the requirement might be for as many as 32 data lines.
In effect, it might be necessary to have several different ver-
sions of a device, dependent upon the data path width of the
computer.
The purpose of a serial port is to convert the information from
its internal, parallel form, to a more common, external form and
back. By using such an approach, we simplify the interconnection
of devices, reducing information to its lowest common denomina-
tor, the bit. It allows us to transfer information 1 bit at a
time, using a single data path, between devices. The real beauty
of this approach is that, by agreeing on how this external form
appears, each device can hide the details of how it works, and
still do the required task.
INTERNAL PORT DETAILS
In this section we discuss the fundamental working of serial
ports on the IBM PC and close compatible systems. It is not es-
sential that you understand this material thoroughly to be
successful with LiteComm. Still, it may help to answer some more
3
important questions that may arise as you proceed with your de-
velopment.
The Interrupt Connection
The PC is an interrupt driven system. This is a sophisticated way
of saying that the PC can pay attention to several internal de-
vices. It doesn't have to check on, or poll, them periodically.
The method by which 80x86 family interrupts work is elegant in
its simplicity. When a device needs the attention of the system,
its asserts a control signal and identifies itself with a number
ranging from 0 to 255. On the basic PC, the numbers used range
from 8 through 15 decimal. PC components translate the
identification to a memory location by multiplying the identifi-
cation by 4. The system then simulates a special form of a call
to the routine whose address is at that memory location. Since
it is impossible to predict when a device will require attention,
the system uses the far address of the routine, both segment and
offset, therefore the 4.
Once called, this routine, called the Interrupt Service Routine
or ISR, has a duty to save the state of the system when the in-
terrupt occurred. It must take care of the interrupt as quickly
as possible, and return control to the interrupted process. It
also must be aware that, while it is doing its work, other, more
important devices may require attention, too.
One device that requires constant attention is the system clock
that ticks roughly 18 times per second. In part, the PC makes
provision for this by prioritizing the interrupt scheme. The ISR
must allow for this by reenabling the interrupt control system as
rapidly as it is practical to do so. The PC's interrupt struc-
ture, if left undisturbed, will prevent interrupts of the same or
lower priority from occurring. To help you organize your
thoughts, the standard identifications for the first two serial
ports on the system are 12 (0C) and 11 (0B) for ports 1 and 2
respectively.
However, the intrreupt structure of the PC is far from perfect.
Systems that use the original ISA buss have a shortcoming. Only
one device is allowed to occupy an interrupt vector or location
at a time. This is in contrast to systems that employ either the
micro-channel buss or the EISA buss. In these latter two buss
designs, multiple devices may occupy a single intterupt location.
As you can see, dealing with the PC's interrupt structure is not
for the faint of heart. It requires a significant amount of
knowledge, and close attention to detail. LiteComm takes care of
these details for you. You are free to focus on your applica-
tion, treating the serial port in much the same way that you
would any DOS file.
4
THE PORT REGISTERS
The 8250 port is fully programmable. LiteComm has already taken
care of the intricacies of this programming. But some additional
information about each register used in the serial port may be of
use when you are attempting to communicate with an external de-
vice. For the sake of this discussion, we use the basic register
numbers. The actual register number used is the register number
referenced below used as an offset to a base port number. For
COM1 (port 1), this base is 3F8(hexadecimal).
register 0 - transmit/receive register 0 - transmit/receive register 0 - transmit/receive
In normal operation, the ISR reads individual characters from
register 0 when the become available. The ISR writes to register
0 when the transmitter portion of the 8250 is ready to accept a
character.
register 0 - baud rate selection register 0 - baud rate selection register 0 - baud rate selection
During initialization, register 0 is part of the mechanism that sets baud rate. During this process, register 0 and its compan-
ion register 1 specify the baud rate divisor (not the actual baud
rate). The baud rate divisor is a value that, when divided into a
given, preset constant, yields the desired baud rate. To set the
baud rate, you must first enable access to this mode. This is
done by writing a value of 80H to register 3, the line control
register. Once complete, the least significant byte (LSB) of the
divisor is written to register 0; the most significant byte is
written to register 1. Access to the normal modes of registers 0
and 1 are reenabled by writing any value less than 80H to the
line control register. Of course, only certain values less than
80H would be meaningful (see the line control register descrip-
tion below).
register 1 - interrupt enable register 1 - interrupt enable register 1 - interrupt enable
Values written to register 1 control the conditions that will
cause the 8250 to interrupt the system. There are four possible
conditions that can cause interrupts:
1. A character has been received (RDI) (RDI) (RDI)
2. The transmitter is ready to send a character (TDI) (TDI) (TDI)
3. An error or BREAK signal has been detected (ERI) (ERI) (ERI)
4. A modem status signal has changed (MSI) (MSI) (MSI)
The designations, in parentheses, are for our purposes only. They
are not 'standard' designations. To enable a particular type of
interrupt, you must set the corresponding bit in a byte to a 1,
then write the byte to register 1. To reset (ignore) the condi-
tion, set the corresponding bit to 0. The diagram that follows
shows the bit positions the correspond to the various conditions
described above.
5
N/A N/A N/A N/A Modem Error/ Xmit Recv
Status Break Ready Char
7 6 5 4 3 2 1 0
Register 1 Bit Definitions
register 1 - baud rate selection register 1 - baud rate selection register 1 - baud rate selection
See the description under register 0, baud rate selection.
register 2 - interrupt identification register 2 - interrupt identification register 2 - interrupt identification
Register 2, in normal operation, acts as a companion to register
1. Register 1 determines the conditions that can cause an
interrupt. Register 2 identifies the specific condition that
caused the interrupt, when more than one condition is enabled.
The least significant 3 bits of the register contain the identi-
fication. See the diagram of register 2 that follows.
N/A N/A N/A N/A N/A Int ID Int ID Int
Pend
7 6 5 4 3 2 1 0
Register 2 Bit Definitions
Since it is possible, even likely, that more than one condition
may occur simultaneously, bit 0 tells whether all conditions that
currently exist have been handled. When bit 0 has a value of 0
(yes zero), there are conditions waiting to be handled. When bit
0 has a value of 1, all outstanding conditions have been handled.
Bits 2 and 1 taken together identify the actual cause of the in-
terrupt.
Again, because of the multiple conditions that may occur, the
8250 presents the conditions in a prioritized order. When bits 2
and 1 have a value of 3 (the most important), an ERI ERI ERI condition
exists. The actual error can be read from the line status regis-
ter(register 5). Reading this register also clears the condition.
When a value of 2 is present, an RDI RDI RDI condition has occurred, and
a character should be read from port 0. If the character is not
read quickly enough, a data overrun error may occur, indicating
the loss of a character.
When bits 2 and 1 have a value of 1, a TDI TDI TDI condition has occurred
and a character may be written to register 0.
A value of zero in bits 2 and 1(least important) shows that one
or more of the modem status lines (so called) have changed. The
condition can be cleared by reading the contents of the modem
status register, register 6.
6
register 3 - line control register 3 - line control register 3 - line control
The line control register gives the means for setting those val-
ues that affect the way in which the serial port appears to the
outside world. It is through this register that the program es-
tablishes character length, parity, and other significant values.
Indirectly, register 3 also plays a role in setting the speed
(baud rate) of the port. (See the description of registers 0 and
1.)
Baud Send Force Parity Enable Stop Char Char
Div Break Parity Type Parity Bits Len Len
7 6 5 4 3 2 1 0
Register 3 Bit Definitions
register 4 - modem control register 4 - modem control register 4 - modem control
The modem control register permits control of the two modem- re-
lated signals that the serial port generates as an output. The
signals are Request To Send, RTS RTS RTS and Data Terminal Ready, DTR DTR DTR.
These two signals are handshaking signals, since they, in part,
help a connected device figure out the state of the connection.
These signals were originally designated to be used in a specific
fashion. Yet, manufacturers of specific devices have used them to
meet their needs. Your success or failure in dealing with any
specific device may depend, in part, on your understanding of how
the device's manufacturer uses these signals. LiteComm provides
you the means for manipulating these signals in a variety of
ways.
You will notice in the register 4 diagram, below that some addi-
tional positions are identified.
N/A N/A N/A Enable OUT2 OUT1 RTS DTR
Loop (reqd)
7 6 5 4 3 2 1 0
Register 4 Bit Definitions
LiteComm controls these additional positions for your benefit.
Only one deserves mention, the position labeled OUT2 OUT2 OUT2. It is
necessary for this position to have a value of 1 for the serial
port to function as an interrupting device. Since LiteComm relies
on interrupts to perform it's job, it always sets this position
correctly.
register 5 - line status register 5 - line status register 5 - line status
The program normally reads the line status register when an ERI ERI ERI
condition occurs. Each bit of the character returned has sig-
nificance, as shown in the accompanying diagram. Using the ap-
propriate functions in LiteComm, you can interrogate the value in
this register, and test for the various conditions using the
7
LiteComm- provided definitions. Note that, due to the special
nature of the BREAK BREAK BREAK signal, LiteComm treats this one condition as
a separate entity.
Time Shift Hold Recd Frame Parity Over Data
Out Reg Reg Break Error Error Run Rec'd
Empty Empty Error
7 6 5 4 3 2 1 0
Register 5 Bit Definitions
register 6 - modem status register 6 - modem status register 6 - modem status
Just as the serial port can generate certain handshaking signals,
it also can read, and report on the status of similar signals
that an external device generates. In their original form, these
signals had special significance for connections between a
terminal and a modem. We refer you to our comments, above, about
present day use of the handshaking signals.
One special note is appropriate here. The modem status register
provides two types of information. The most significant 4 bits
(see the diagram) show the current state of the 4 covered sig-
nals. The least significant 4 bits show which, if any, of the
signals have changed state (from zero to one, or vice-versa),
since the last time the register was interrogated. LiteComm up-
dates its internal tables with this value in real-time, and re-
ports the results when asked to do so. You can test the signals
individually or in combination using the LiteComm- provided
definitions.
DCD RI DSR CTS Delta Delta Delta Delta
Carr Ring Data Clear DCD RI DSR CTS
Det Ind Set Rd Send
7 6 5 4 3 2 1 0
Register 6 Bit Definitions
The LiteComm Connection
In the design of LiteComm, we have purposely 'hidden' many
underlying details we presented above. Often, you will have
little use for this additional information. This is particularly
true of most of the applications with which you will come into
contact. In most applications, you probably will open the port
or ports, set the necessary parameters and modem control signals,
and do nothing more than read and write characters using one or
more of the LiteComm functions. The beauty of LiteComm's design
is that its high degree of granularity doesn't force you to pay
the price of dragging along functions that you are not using.
The information that we presented above will help you when it is
necessary to communicate with a device that requires special
handshaking considerations, such as a cash drawer. You also may
need the information we presented if you intend to use serial
ports beyond COM2 (serial port 2).
8
Finally, by presenting the information that we have supplied, we
hope to gain a more informed user. Communications programming is
not the black art that some would have you believe, although it
can easily seem that way at times. Of the calls we receive with
questions, more than 75 per cent could be answered by the caller
himself with a more thorough understanding of the underlying
concepts and rules.
ToolBox NOTES AND WARNINGS
Note: Note: Note:Special warning for old-style PC owners
There is a known problem with serial ports on older systems. Due
to a problem with old-style 8250 and 16450 UARTS, it is possible
for the transmitter to stop functioning. This problem is cuased
by a loss of interrupts under load. While software workarounds
exist, we have decided not to include such workarounds in Lite-
Comm. Inclusion of this logic would result in added overhead to
all LiteComm users. If you believe you are experiencing this
problem, please contact us.
Note: Note: Note:Open Required
Before you can send or receive information on a serial port using
the ToolBox, you must use the open function to enable the line.
This function initializes the UART with the correct parameters,
and introduces the UART into the interrupt structure of the PC.
The ToolBox will detect, and report, any errors that you may make
in selecting the port or specifying the initial parameters.
Note: Note: Note:Close Required
The ToolBox interfaces directly with the interrupt structure of
the PC. It is critical before exiting a program that has opened a
serial port that the serial port is closed with the close func-
tion. Since it is possible for a program to terminate abnormally,
the open function installs an exit routine that will
automatically close any open ports. Good programming practice
demands that your program should close the ports explicitly. By
so doing, you may avoid problems in the future if we find it
necessary to remove the auto-close functionality. Further, the
auto-close functionality drops all modem handshaking signals ab-
solutely, while an explicit close can decide whether to drop
these signals. If you are unaware of exit functions, check your
compiler's documentation for the atexit() function for a complete
explanation. Review the description of the comm_close() function,
as well.
Failure of the open function can result from several causes, im-
proper parameters to the open function, a non-existant serial
port or insufficient memory. The memory is needed for the re-
quested buffers and related control structures for the port.
Memory for the transmit and receive buffers as well as the port
control block is allocated from free memory. It is your
responsibility to insure that adequate memory is available for
9
this purpose. This requires no particular action on your part.
If you use LiteComm in combination with other packages, the other
packages may place specific restrictions on your use of free
memory.
Note: Note: Note:Handshaking Signals
The ToolBox will, at your option, assert both the DTR and RTS
signals when you open the port. If you do not select this option
you must use the lc_setmdm function to assert (raise) this sig-
nal. In addition, some modems and other devices may require you
to assert either the DTR (Data Terminal Ready) or the RTS (Re-
quest To Send) signal before they will respond to data. Please
note that the use of handshaking signals is HIGHLY hardware-
dependant. The ToolBox provides all the functionality necessary
for you to implement almost any handshaking scheme that might be
required.
WARNING WARNING WARNING
Due to the use of all available interrupt modes of the 8250, one
user has discovered an unusual set of circumstances that can be
troublesome. If the 8250 chip detects an error condition, such
as a parity error, framing error, or data overrun error, it
causes an interrupt to which the ToolBox will respond. If these
errors occur frequently enough, the ToolBox code will spend too
much time handling the errors, and lose characters, causing
additional errors. If you encounter a situation in which your
application appears to behave erratically, especially at higher
speeds, investigate the following table.
Possible Error Conditions
Is the cabling to the other device sound and solidly con-
nected?
Are any of the signals in the cable 'floating' or are they all
properly terminated?
Is the other device functioning properly? We have encountered
situations in which a serial port on some devices tends to be
sloppy in terms of voltage levels, bit timings, and similar
problems. Any, or all, these situations can cause the erratic
operation to which we referred.
WARNING WARNING WARNING
Unless you are very familiar with the interrupt structure of the
PC, do not attempt to manipulate the interrupt enable flag out-
side the ToolBox. The ToolBox sets and clears the interrupt en-
able flag at appropriate times and assumes that it has sole
control over the flag.
Note: Note: Note:Byte Alignment
Unless otherwise specified, all library functions use byte
structure alignment. This alignment results from the way in which
the interrupt handler was developed in assembly language.
10
NEW IN VERSION 6.00
In version 6.0, we have again improved on the assembly language
interrupt handlers. In addition, there have been significant
changes in the supporting functions to tighten the code. The
result is smaller applications, often able to operate at higher
baud rates.
Other additions to LiteComm in version 6.0 include fully
automatic flow control using either software or hardware. Both
variants are programmer-configurable. This should simplify things
for some users.
In version 6.0, LiteComm will attempt to insure that you are at-
tempting to open a valid COM port. If LiteComm believes that the
port is not valid, it will return an error from comm_opn. The
addition of a global error variable should help in determining
the source of the error. See the section on LiteComm functions
for additional information.
And we have addressed an area that we have always considered a
LiteComm weakness. In previous versions of LiteComm, it was pos-
sible to detect an receive error globally, yet not know when it
occurred. With version 6.0, LiteComm now buffers errors in the
same way that it buffers incoming characters. At your option, you
can retrieve the error status associated with a character.
There have been numerous, less significant additions to LiteComm,
as well. Many are the result of user-feedback. Nearly all are
aimed at making your job simpler.
BEYOND COM2
THE ToolBox METHODOLOGY
In the design of the original PC, and in subsequent variations
such as the PC/AT, there was only provision for two serial ports.
Many manufacturers of add-in products, both serial ports and in-
ternal modems have added the capability to support 1 or more
additional ports beyond the COM2 limit. Generally, this can cause
problems in the PC since there is no room in the interrupt re-
quest scheme for additional levels of interrupts. There are no
designated interrupt vector for other additional ports.
The ToolBox approach to resolving these issues is to permit the
programmer a degree of control over the parameters that govern
the interrupt mechanism for COM3 and COM4. Specifically, these
parameters are:
1. The interrupt request (IRQ) bit that is used to mask the 8259
interrupt controller.
2. The interrupt vector number (not address) to which the port is
attached.
11
3. The base i/o register for the port itself. Of course, it we
assume that the port is an 8250 UART or compatible device.
Again, the LiteComm ToolBox will not function with non-8250
type devices.
Before you attempt to use COM3 and/or COM4, you must figure out
from the port's documentation, the appropriate values for these
three parameters. As distributed, the ToolBox assumes the
following:
Port COM 3 COM 4
IRQ Bit 4 3
Vector 0CH 0BH
Base Register 3E8H 2E8H
You may change any of these values by using the _portchg function
described below, but only before you open the port with comm_opn.
Once the port has been opened, _portchg is ineffective. _portchg
will not work on COM1 or COM2.
At present, LiteComm is not compatible with multiport boards such
as the Digiboard. The structure of these boards generally re-
quires additional programming to be used effectively. If you
want to use such a board with LiteComm, please contact us
directly for information on custom modifications to LiteComm. We
have performed such modifications for other LiteComm users.
CAUTIONS
There is an intimate relationship between the IRQ setting and its
related interrupt vector. In the PC, this relationship is con-
trolled, in part, by the 8259 interrupt controller that is set
during BIOS initialization.
In brief, the BIOS settings for the PC (and most close compa-
tibles) establish IRQ0 as vector number 08h, and subsequent IRQ
levels at increasing vector numbers. These vector numbers (or
types in INTEL terms) act as a cpu- directed call table to loca-
tions in the lowest 1K of system memory. We can alter how the
system responds to a given interrupt by replacing or changing the
values in the associated vector position to point to a routine
that we supply.
Judging from the questions asked by some users of LiteComm, there
is evidently some misunderstanding about using ports beyond COM2,
and how this all relates to your hardware. Before you can suc-
cessfully use COM3 or COM4, you must consider the following:
Does the hardware permit a change to the base port and/or the
interrupt vector to which the port responds? Some expansion
cards will support changing one and not the other, causing po-
tential hardware conflicts and lost data.
12
Does the hardware permit reassignment of the IRQ priority?
Some expansion cards permit you to alter the IRQ priority,
some won't. Briefly, from the previous discussion, any change
to the IRQ priority must allow a corresponding change to the
interrupt vector number. Without this capability, reprogram-
ming of the 8259 chip would be required.
Many add-on cards permit this dual change simply by making a
single switch or jumper setting. Unfortunately, the documenta-
tion for these cards generally assumes that you are aware of
the dual nature of the IRQ vector relationship, and may leave
you with the impression that you are changing one and not the
other. In most circumstances, this is not so.
The point to all this is that LiteComm can only provide as much
support as the hardware permits, or is capable of responding to.
If you wish to use other than the default base port, interrupt
vector, or irq priority for COM3 or COM4, then your expansion
card must be able to support the new values; in other words,
these values are all hardware-provided, and are recognized by the
LiteComm software. If your hardware does not permit changing a
value, LiteComm cannot improve the situation.
We should, at this point, add one final caution about how inter-
rupt priorities function, and their relationship to the irq bit
that you may select. The standard PC permits 8 interrupt priority
levels. The PC-AT and later systems permit a total of 16 inter-
rupt priority levels. Regardless of system type, the programmable
timer has the highest priority; the parallel printer port has the
lowest priority. When an interrupt occurs, the interrupt
controller (8259 chip) masks out all other interrupts from the
priority of the interrupting device and all lower priority de-
vices.
As an aid to making COM3 and COM4 fit, LiteComm supports inter-
rupt chaining for the COM3 and COM4 ports, on PS/2 and other mi-
crochannel systems. If you use COM3 or COM4, when an interrupt
occurs, the kernel will attempt to determine if the interrupt was
caused by the supported port or from another source. Only the
PS/2 and similar systems can reliably support interrupt chaining;
it is NOT a restriction that we impose. The restriction lies in
the design of the original PC and PC-AT buss structure.
If the kernel determines that the supported port did not cause
the interrupt, an automatic chain to the original interrupt han-
dler for that interrupt level (IRQ level) will take place. This
allows you to "patch in" or share the available interrupt vec-
tors.
If you intend to use other than the library-provided defaults, be
sure that you understand the interrupt mechanism. The use of the
automatic chaining described above can be particularly trouble-
some under some circumstances, resulting in loss of interrupts
and, potentially, a system crash.
13
Note: Note: Note:DO NOT DO NOT DO NOT attempt to mix the ToolBox functions with other
seemingly- related functions (such as the serial port BIOS calls
provided in both Turbo and Microsoft C). At least two users have
attempted to use only the receive portions of LiteComm, while
resorting to the BIOS functions to send characters or adjust port
parameters such as baud rate. The results, at best, have been
failure of the user's application to function, and, at worst,
total system lockup. This mix of functions is NOT supported and
must not be used. If you attempt such a mix, we cannot help you.
If you chose to share the interrupt vectors for COM1 or COM2, you
must be certain to open COM1 (COM2) last. The interrupt chaining
mechanism only works with COM3 and COM4. Failure to follow this
caution will result in a total loss of function of COM3 (COM4).
In addition, the ports should be opened in descending order of
the planned baud rate, i.e. the faster port should be opened
first, the slower port should be opened last. Whenever possible
or practical, you will obtain best results by using the same baud
rate on both ports.
One final caution is in order. One or two users have attempted
to trace through the interrupts as they occur using software
based debuggers. This is a risky proposition at best since most
debuggers work by tapping into, and disturbing, the interrupt
mechanism. If you feel you must use a debugger, try to avoid the
kernel routines of LiteComm, or use a hardware-based debugger
such as Periscope.
14
INSTALLATION
PACKAGE CONTENTS
Your distribution diskette contains many files that are important
to you. See the file PACKING.LST on the distribution disk for a
list of the files that you should have received.
INSTALLING LITECOMM
LiteComm is installed with the INSTALL utility that we provide on
the distribution diskette. To use this utility, follow the easy
steps below:
1. Make a copy of the distribution diskette before beginning.
2. Insert the distribution diskette in your diskette drive.
3. Make the distribution diskette the default drive by typing ei-
ther A:<ENTER> or B:<ENTER>.
4. Type the command
INSTALL<ENTER>.
INSTALL will present you with a screen that specifies the in-
stallation default values. You may freely edit them before pro-
ceeding with the installation. Use the arrow keys to move between
the various options. When you are satisfied with your responses,
press the <PAGE-DOWN> key to proceed with installation.
INSTALL will create several directories on the target disk drive.
These directories do not have to exist before you start INSTALL.
After copying the necessary files, INSTALL will decompress the
files into their final form and clean up after itself.
By default, install will create the following directories:
LITECOMM Header Files
LITECOMM\LIB PreBuilt Libraries
LITECOMM\SOURCE Package Source Code
If you prefer, of course, you may install LiteComm manually by
copying all of the distributed EXE files to your destination
disk. Then execute each to decompress it, with the exception of
INSTALL. Finally, delete each of the EXE files to clean up your
disk. They will no longer be needed.
REBUILDING THE LIBRARIES
We have provided you with the source code for LiteComm so that
you may modify our product to meet special needs. We encourage
you to use the provided MAKE files to accomplish this. They were
used in constructing the libraries you have just installed and
will make the task decidedly simpler. the make files for Turbo C
are TURBOCOMM.MAK and TLCP.MAK. The make files for Microsoft C
are MSCCOMM.MAK and MLCP.MAK.
15
We have had a report from one user that the make files are not
compatible with the version of the make utility provided with the
IBM C compiler, even though IBM's product is derived from Micro-
soft C. Unfortunately, we do not support the IBM product as we
have no way of assuring compatibility. We do understand, however,
that the Microsoft libraries are fully compatible.
GENERAL NOTES
LiteComm and its related libraries make extensive use of parame-
ters defined in the included header files. Your programs should
always use the same header file parameters. While every effort
will be made in future releases of LiteComm to preserve the val-
ues as currently provided, we cannot guarantee that changes will
never occur. The surest way to safeguard your efforts is to use
the defined parameters. Then, when new versions of LiteComm are
released, you need only recompile and relink to insure
consistency.
In the discussion of the various functions that follows, you
should assume that any references to the port variable refer to a
variable or constant that may take on a value of from 1 to 4. No
other values are acceptable, and will be rejected.
While we feel that LiteComm is written in the most efficient way
possible, commensurate with good programming practice, we cannot
be responsible for variations caused by hardware configurations
or other factors beyond our control. LiteComm has been tested on
the IBM PC-AT, IBM PS/2 and several compatible systems such as
the Zenith and Wyse equivalents. LiteComm has not been tested in
environments in which other software, most significantly TSR
(terminate and stay resident) modules exist. Some TSR programs
that "steal" interrupts for their purposes present an unfavorable
environment to other programs that rely on the interrupt struc-
ture of the computer.
If you experience erratic behavior with LiteComm in a TSR-type
situation, try executing your application without the TSR module
being present. If the problems you have experienced disappear,
suspect the TSR module.
Conversely, LiteComm provides an excellent vehicle for supporting
TSR programs that you may write. Since the package is fully
reentrant, your only concern need be with those aspects of TSR
programs are of normal concern, e.g., the non reentrant nature of
DOS.
LiteComm only uses DOS functions when opening and closing ports.
It may therefore be safely used in a TSR environment. As an
example, we have included the program SPM as part of this re-
lease. SPM is a background Serial Port Monitor that is available
as a separate shareware product. SPM was developed using Lite-
Comm.
USE WITH MULTITASKING ENVIRONMENTS
Some users have made attempts at using LiteComm with multitasking
environments such as Quarterdesk's DesqView. Use of LiteComm in
16
such an environment is certain to be affected by the way in which
the multitasking behaves with respect to interrupts. We recog-
nize that DesqView has achieved a great deal of popularity among
so-called power users. Still, LiteComm was not explicitly de-
signed for such environments, and its performance may suffer as a
result.
NOTES ON RING DETECTION
Several users have reported problems in consistently detecting a
ringing telephone by checking the state of the RI (Ring Indica-
tor) signal. The problem seems highly dependent on the type of
modem that is being used, since this signal comes from the modem.
If the duration of the signal is too short, the program may miss
the signal as the modem toggles it. One workaround that has been
successfully is to check the RICHG bit returned from lc_mstat,
rather than the RI bit. The RICHG bit will be set when the RI
bit comes one and again when the RI bit goes off. This is the
method employed in the check_for_call function.
17
FUNCTION REFERENCE
GENERAL INFORMATION
In the following pages, we provide the detailed information about
each available LiteComm ToolBox function. Each function defini-
tion includes, at a minimum, a summary of how to code the func-
tion, a description of what the function does, and an indication
of those values, if any, that the function might return.
Where appropriate, we include additional documentation about the
function. Some definitions include examples, in the sense of
code fragments illustrating the function's usage. More impor-
tantly, some definitions include additional notes and warnings as
well as references to other functions within the package.
We have made every effort to insure that the documentation of the
functions is complete and accurate. The style and manner of the
documentation assume that the reader is thoroughly familiar with
the elements of C syntax and common conventions.
FLOW CONTROL
In version 6 of LiteComm, we have incorporated fully automatic
flow control, using either software, sometimes called XON-XOFF
control, or hardware using the handshaking signals.
Note: Note: Note:It is not valid to have both methods of flow control active
at the same time. Failure to observe this restriction can cause
unpredictable results.
GLOBAL ERROR VARIABLE
Version 6 of LiteComm has a global error variable that is set by
each of the LiteComm functions. The variable, _lc_error _lc_error _lc_error, is de-
fined in LITECOMM.H. Possible values are in the file LITE-
COMM.ERR. Examining the contents of _lc_error can help you
diagnose and correct problems.
18
_portchg
SUMMARY
#include <litecomm.h>
int _portchg(port, base, irq, vector)
unsigned port;
unsigned base;
unsigned vector;
char irq;
DESCRIPTION
Changes one or more of the critical parameters for COM3 or COM4.
This function must be used before the opening port to be effec-
tive. To leave any of the parameters at its default value, make
the corresponding entry 0. Note that vector is a vector number,
not an address or pointer.
The irq parameter is NOT the irq (interrupt request) number, but
the irq mask. The following lines, reproduced from 'litecomm.h'
help illustrate this idea.
#define IRQ1 0x10 /* int req mask for port 1 - irq4 */
#define IRQ2 0x08 /* int req mask for port 2 - irq3 */
Note: Note: Note:The value for irq4 is NOT 4, but a character in which bit 4,
using INTEL's bit numbering, has a value of 1. Thus, to use irq
priority 1 as the irq for either COM3 or COM4, you would specify
0x02 as the value of irq when calling _portchg.
The default parameters are in the litecomm.h include file.
If you intend to change the default irq settings, you also MUST MUST MUST
make a corresponding change to the vector number. See the accom-
panying documentation about using COM3 and COM4 for additional
details. Failure to follow this rule may make the port appear to
be nonfunctional.
The _portchg function does NOT check to determine that you have
provided both an IRQ mask AND a new vector number.
Example Example Example
if (_portchg(port, 0x408, 0, 0, 0) == -1)
{
printf("Error Changing Port %d\n", port);
exit(1);
}
RETURN VALUES
Returns 0 if the function is successful, -1 if you attempt to
change a port other that 3 or 4.
19
comm_opn
SUMMARY
#include <litecomm.h>
int comm_opn(port, baud, parity, datab, stopb, inbufsz, outbufsz,
raisemdm)
unsigned port;
unsigned baud;
unsigned parity;
unsigned datab;
unsigned stopb;
unsigned inbufsz;
unsigned outbufsz;
DESCRIPTION
Opens the specified port for use and attaches an interrupt han-
dler to DOS for the port. Optionally, comm_opn will raise the DTR
and RTS modem control signals, if the value of raisemdm is TRUE.
The function allocates, from the heap, space for the CCB (com-
munications control block), space for the interrupt handler's
stack, and buffers for input and output of the specified sizes.
The minimum value for inbufsz is 128; the minimum size for out-
bufsz is 64.
If sufficient memory is available and the parameters are correct,
the port will be set to the parameters (baud rate, word length,
stop bits) used when the function is called. The memory overhead
associated with opening a port can be approximated by adding
about 1.2K bytes to the buffer sizes specified.
comm_opn installs an exit handler using the atexit() function to
protect DOS from problems that might arise if a program using
LiteComm fails. Still, it is sound practice to close a port
opened in this manner using comm_close explicitly in your program
to gain maximum control over the port.
The baud parameter is an unsigned integer that specifies the baud
rate you intend to use, e.g., 4800. The other parameters passed
to the function should be from the parameter set in the lite-
comm.h include file.
Example Example Example
Below are two examples of using comm_opn, the first letting
comm_opn raise the modem control signals, the second using two
function calls to do the same thing. The result of each example
is the same, an open port on which the DTR and RTS signals have
been raised.
Example 1 Example 1 Example 1
if (comm_opn(port, 1200, NPARITY, BIT8, STOP1, 256,
256, TRUE) == - 1)
{
printf("Error Opening Port %d\n", port);
exit(1);
20
}
Example 2 Example 2 Example 2
if (comm_opn(port, 1200, NPARITY, BIT8, STOP1, 256,
256, FALSE) == - 1)
{
printf("Error Opening Port %d\n", port);
exit(1);
}
lc_setmdm(port, (DTR | RTS));
RETURN VALUES
Upon successful open, the function returns port. If any error
occurs, despite the type, the function returns -1.
21
comm_close
SUMMARY
#include <litecomm.h>
int comm_close(port, dropmdm)
unsigned port;
DESCRIPTION
This function is the companion to comm_opn and, in effect, per-
forms the opposite action. Comm_close detaches the library rou-
tines from the interrupt handler, and reconnects the previous
interrupt handler.
Comm_close also releases all allocated memory used for the buff-
ering and control structures described under comm_opn. If the
value of dropmdm is non-zero, the port is closed absolutely, and
all modem control signals are dropped. If the value of dropmdm
is zero, the port is closed conditionally, and both the DTR and
RTS signals will be left in their current state.
Since comm_opn installs an exit handler using the atexit function
in both Turbo C and Microsoft C, you are not required to close
explicitly an open port. However, if you do not explictly close
the port, you will lose control over the handling of the DTR and
RTS signals since the built-in exit handler uses the absolute
form of the close.
Example Example Example
These are two equivalent examples of the comm_close function.
The first uses the absolute port close, the second uses two
function calls to do the same thing.
Example 1 Example 1 Example 1
comm_close(port, TRUE); /* absolute close */
Example 2 Example 2 Example 2
lc_clrmdm(port, (RTS | DTR)); /* lower modem control */
comm_close(port, FALSE); /* conditional close */
RETURN VALUES
If any error occurs, despite the type, the function returns -1.
22
comm_setup
SUMMARY
#include <litecomm.h>
int comm_setup(port,baud,parity,datab,stopb)
unsigned port;
unsigned baud;
unsigned parity;
unsigned datab;
unsigned stopb;
DESCRIPTION
The comm_setup function is a subset of the comm_opn function and
the remarks made in the description of comm_opn regarding the
port parameters apply.
This function is useful if you wish to change the basic commu-
nication parameters of the specified port that has already been
opened without comm_close'ing the port.
Example Example Example
if (comm_setup(port, 1200, NPARITY, BIT8, STOP1) ==
-1)
{
printf("Error Changing Port %d\n", port);
exit(1);
}
RETURN VALUES
If any error occurs, despite the type, the function returns -1.
SEE ALSO
comm_opn
23
lc_vport
SUMMARY
#include <litecomm.h>
COMM *lc_vport(port)
DESCRIPTION
lc_vport is a macro that validates that the port number specified
is correct and has been opened with the comm_opn function. It may
be of use to you in writing certain applications.
RETURN VALUES
If the port is valid and has been opened, returns a pointer to
the CCB (communications control block) for the port. Returns NULL
if an error occurs;
24
lc_icnt, lc_ocnt
SUMMARY
#include <litecomm.h>
int lc_icnt(port)
int lc_ocnt(port)
unsigned port;
DESCRIPTION
These functions may be used to determine the number of characters
currently in the input(lc_icnt) or output(lc_ocnt) buffers for
the port.
Example Example Example
#include <litecomm.h>
if (lc_icnt(port)) /* anything received ? */
puts("Characters waiting in input");
RETURN VALUES
Both functions return -1 if an error occurs (port not open or
invalid port number). The lc_icnt() function returns the number
of characters in the input buffer; lc_ocnt() returns the number
of characters remaining in the transmit buffer.
25
lc_mstat
SUMMARY
#include <litecomm.h>
int lc_mstat(port)
unsigned port;
DESCRIPTION
May be used to determine the last known state of the modem-
supplied handshake signals. These may be tested using the values
in the include file litecomm.h.
The handshake signals consist of a byte in which the bits 4-7
contain the current state of the signals (such as Clear To Send
or CTS). Bits 0-3 contain information regarding whether
individual signals have changed. lc_mstat always returns the
current values of the signals in bits 4-7. Bits 0-3 will reflect
which, if any, of the signals has changed.
The easiest approach to dealing with the returned value is to
test bits 0-3 (the DELTA or change bits) for a non-zero value.
If any non-zero value is found in bits 0-3, one or more signals
have changed _____ ___ ____ ____ __ ________ since the last call to lc_mstat.
Note: Note: Note:The functions resets the DELTA bits. The value obtained
from bits 4- 7 will correctly reflect the current state of the
signals.
To examine individual signals, litecomm.h has #defined symbols
for the change bits ,e.g., CTSCHG, and for the signals themselves
,e.g.. CTS.
Example Example Example
int curstat;
curstat = lc_mstat(port); /* get curent values */
if (curstat & DCDCHG) /* DCD changed ? */
if (! (curstat & DCD))
/* carrier still on */
puts("Remote is off-line, carrier lost");
RETURN VALUES
If the port is valid and open, returns the current modem status
bits. Returns -1 if an error occurs.
SEE ALSO
lc_got???
26
lc_got???
SUMMARY
#include "litecomm.h"
unsigned port;
lc_gotcts(port);
lc_gotdsr(port);
lc_gotri(port);
lc_gotdcd(port);
lc_gotctschg(port);
lc_gotdsrchg(port);
lc_gotrichg(port);
lc_gotdcdchg(port);
DESCRIPTION
This set of 8 macros makes the job of testing the individual mo-
dem status signals simpler.
The macros rely upon the lc_mstat function and you should refer
to the description of that function for additional information.
SEE ALSO
lc_mstat
27
lc_estat
SUMMARY
#include <litecomm.h>
int lc_estat(port)
unsigned port;
DESCRIPTION
May be used to determine the last known state of the serial
port's error status bits. These may be tested using the values in
the include file litecomm.h.
The errors that are detected and reported include:
ORUNERR - failure to fetch a character from the port before the
next character arrived. Usually a problem in the interrupt han-
dler.
PARERR - One or more characters were received in which the parity
of the character(s) did not match the current parity setting of
the port. Can be caused by line noise, or by other causes.
FRMERR - A framing error has occurred. A character arrived that
had too few or (more likely) too many bits. Usually caused by
line noise.
RETURN VALUES
If the port is valid and open, returns the current error status
bits. Returns -1 if an error occurs.
28
lc_getw
SUMMARY
#include <litecomm.h>
int lc_getw(port)
unsigned port;
DESCRIPTION
Reads a character from the serial port's input buffer. Waits in-
definitely until a character is available. If the port is dis-
connected for any reason, this function will cause a system hang
if called, so its use should be carefully controlled.
RETURN VALUES
Returns the next available character in the input buffer for the
port. Returns -1 if the port is not active, or if an invalid port
number is specified.
29
lc_setmdm
SUMMARY
#include <litecomm.h>
int lc_setmdm(port, newset)
unsigned port;
unsigned newset;
DESCRIPTION
Set one or more of the modem control signals. Because of the need
to have OUT2 set for interrupt support, the function always pro-
vides the correct setting for this bit. Use the symbolic #defines
found in the litecomm.h file. Many applications will not require
this function, if they allow comm_opn to raise these two signals.
More sophisticated applications may be required to control either
or both of the signals to provide handshaking with an external
device.
Example Example Example
/* raise the RTS modem control signal */
lc_setmdm(port, RTS);
/* raise both RTS and DTR */
lc_setmdm(port, (RTS | DTR));
RETURN VALUES
Returns 0 if the operation was successful, returns -1 otherwise.
SEE ALSO
comm_opn, lc_clrmdm, lc_togmdm, lc_setdtr, lc_setrts
30
lc_setdtr, lc_setrts
SUMMARY
#include "litecomm.h"
unsigned port;
lc_setdtr(port);
lc_setrts(port);
DESCRIPTION
lc_setdtr and lc_setrts are macros designed to help make your
code more explicit. Both macros use the lc_setmdm function to set
the DTR and RTS signals. Note that no effort is made to preserve
the current modem signal status. That is use of the lc_setdtr
macro will cause RTS to drop. The converse is true of lc_setrts.
SEE ALSO
lc_setmdm
31
lc_clrmdm
SUMMARY
#include <litecomm.h>
int lc_clrmdm(port, newset)
unsigned port;
unsigned newset;
DESCRIPTION
Companion to the setmdm function. Clears the modem control sig-
nals RTS or DTR or both. Because of the need to have OUT2 set for
interrupt support, the function always provides the correct set-
ting for this bit. Use the symbolic #defines found in the lite-
comm.h file. Generally, this function only has value if you
trying to implement some form of hardware handshaking with
another device. The comm_close function will lower both RTS and
DTS automatically, if told to do so.
Example Example Example
/* lower the RTS modem control signal */
lc_clrmdm(port, RTS);
/* lower both RTS and DTR */
lc_clrmdm(port, (RTS | DTR));
RETURN VALUES
Returns 0 if the operation was successful, returns -1 otherwise.
SEE ALSO
comm_close, lc_setmdm, lc_togmdm
32
lc_togmdm
SUMMARY
#include <litecomm.h>
int lc_togmdm(port, newset)
unsigned port;
unsigned newset;
DESCRIPTION
Companion to setmdm function. Inverts (flip-flops) the modem
control signals RTS or DTR or both. Because of the need to have
OUT2 set for interrupt support, the function always provides the
correct setting for this bit. Use the symbolic #defines found in
the litecomm.h file. This function may have value if you are
trying to implement hardware handshaking.
Example Example Example
/*
** change the RTS modem control signal to its other
** state (e.g. if raised, lower, and if lowered, raise
*/
lc_togmdm(port, RTS);
RETURN VALUES
Returns 0 if the operation was successful, returns -1 otherwise.
SEE ALSO
lc_setmdm, lc_clrmdm
33
lc_xoff
SUMMARY
#include <litecomm.h>
int lc_xoff(port, flag)
unsigned port;
int flag;
DESCRIPTION
If flag is non-zero, the function enables automatic software flow
control function. If flag is zero (the default setting),
automatic flow control is disabled.
When enabled, the LiteComm kernel will automatically transmit the
OFF character when the input buffer is approximately 2/3 full and
will automatically recognize an OFF character sent by the other
device. If the other device transmits an OFF character, the ker-
nel will refuse to send any characters until the condition is
cleared by receipt of the ON character or by disabling software
flow control altogether.
The recognition functionality is implimented in the kernel. As a
result, the transmit buffer will continue to accept input from
your program until the buffer fills completely, even though the
information will not be sent. Once the matching ON character is
received, the contents of the transmit buffer will be sent
rapidly to the other device. It is possible that the rate with
which characters are sent when this occurs may cause problems for
the other device, depending on its ability to handle the data
flow.
If you intended to implement a protocol that might include the ON
or OFF characters, be sure to disable the automatic flow control.
Failure to do so may result in a system hang.
By default, software flow control uses the XON-XOFF flow control
characters. You may change the characters to suit your applica-
tion by using the lc_setxon and lc_setxoff functions.
RETURN VALUES
Returns 0 if the operation was successful, returns -1 otherwise.
SEE ALSO
lc_gotxoff, lc_putxoff, lc_setxon, lc_setxoff
34
lc_gotxoff
SUMMARY
#include <litecomm.h>
int lc_gotxoff(port)
unsigned port;
DESCRIPTION
If the OFF character has been received, this function will return
a non-zero value. A zero is returned if the OFF character is
never received, or if the ON character is detected.
Note: Note: Note:Unlike older versions of LiteComm, lc_gotxoff is now useful
only for information. It does not alter the way in which software
flow control operates.
RETURN VALUES
Returns a nonzero value if the OFF character was detected, zero
if an OFF character was not detected, or if the ON character is
detected. Will return -1 in the case of an error.
SEE ALSO
lc_xoff, lc_putxoff, lc_setxon, lc_setxoff
35
lc_putxoff
SUMMARY
#include <litecomm.h>
int lc_putxoff(port)
unsigned port;
DESCRIPTION
See below for the values returned. If the LiteComm kernel has
sent the OFF character.
Note: Note: Note:Unlike older versions of LiteComm, this function provides
information only. Use of the function has no effect upon software
flow control.
RETURN VALUES
Returns a nonzero value if an OFF character was sent to the other
device, zero if an OFF was not sent, or if the ON character has
been sent. Will return -1 in the case of an error.
SEE ALSO
lc_xoff, lc_putxoff, lc_setxon, lc_setxoff
36
lc_setxon, lc_setxoff
SUMMARY
#include "litecomm.h"
int lc_setxon(port, xonchar);
int lc_setxoff(port, xoffchar);
unsigned port;
unsigned char xonchar;
unsigned char xoff char;
DESCRIPTION
These functions are part of the software flow control functonal-
ity of LiteComm. By default, LiteComm's software flow control
uses the XON-XOFF character scheme. If your application has dif-
ferent requirements, use the lc_setxon function to change the ON
character, lc_setxoff to set the OFF character.
RETURN VALUES
Both functions return a -1 if an error occurs. Both return a
value of zero (0) if there is no error.
SEE ALSO
lc_xoff, lc_gotxoff, lc_putxoff
37
lc_sethwflow
SUMMARY
#include "litecomm.h"
int lc_sethwflow(port, flowtype)
unsigned port;
unsigned char flowtype;
DESCRIPTION
This function specifies the type of hardware flow control to use
and activates hardware flow control. The point at which hardware
flow control is activated is the same as for software flow con-
trol.
You have complete control over which hardware signals are used
for flow control. For output (from the port) control specify ei-
ther USEDSR or USECTS. For input (to the port) control, specify
either USEDTR or USERTS. Since most hardware flow control schemes
employ both input and output flow control, you should OR the re-
quired values together, as shown in the example. Hardware flow
control remains in effect until you issue the lc_clearhwflow
function.
Note: Note: Note:The flow control scheme assumes that the input flow control
signal (RTS or DTR) have been set to the correct starting value
by the program. Thereafter, LiteComm flow control will manage the
signals.
Example Example Example
/* Use RTS-CTS flow control */
if lc_sethwflow(port, (USECTS | USERTS))
puts("Error setting flow control");
RETURN VALUES
The function returns a value of zero (0) if successful. If an
error occurs, the function returns -1.
SEE ALSO
lc_xoff, lc_clearhwflow, lc_puthwstop, lc_gothwstop
38
lc_clearhwflow
SUMMARY
#include "litecomm.h"
int lc_clearhwflow(port)
unsigned port;
DESCRIPTION
Immediately deactivates hardware flow control. Any untransmitted
characters will be sent as rapidly as possible.
RETURN VALUES
If successful, returns a value of zero (0). Retuirns -1 if an
error occurs.
SEE ALSO
lc_sethwflow, lc_puthwstop, lc_gothwstop
39
lc_puthwstop
SUMMARY
#include "litecomm.h"
int lc_puthwstop(port)
unsigned port;
DESCRIPTION
Indicates whether or not LiteComm has instructed the remote de-
vice to stop transmitting.
RETURN VALUES
If an error occurs, returns a value of -1. If input flow control
has not been asserted, returns a value of zero (0). If input flow
control has been asserted, returns a positive, non-zero value;
SEE ALSO
lc_sethwflow, lc_gothwflow
40
lc_gothwstop
SUMMARY
#include "litecomm.h"
int lc_gothwstop(port)
unsigned port;
DESCRIPTION
Indicates whether or not LiteComm has been instructed by the re-
mote device to stop transmitting.
RETURN VALUES
If an error occurs, returns a value of -1. If output flow control
has not been asserted, returns a value of zero (0). If output
flow control has been asserted by the remote device, returns a
positive, non-zero value;
SEE ALSO
lc_sethwflow, lc_puthwflow
41
lc_get
SUMMARY
#include <litecomm.h>
int lc_get(port)
unsigned port;
DESCRIPTION
Read a character from the serial port's input buffer. Discard
(ignore) the matching status value
Example Example Example
if ((ch = lc_get(port)) != -1)
/* any chars? */
ch &= 0x7f; /* mask parity */
RETURN VALUES
Returns the next available character in the input buffer for the
port. If you specified other than NO PARITY when you opened the
port, you may have to mask (make zero) the parity bit before you
use the character. Returns -1 if the port is not active, or if
there are not characters in the port's buffer.
SEE ALSO
lc_getstat, wait, purge
42
lc_getstat
SUMMARY
#include "litecomm.h"
int lc_getstat(port, ch, status);
unsigned port;
unsigned char *ch;
unsigned char *status;
DESCRIPTION
This function retrieves the next character and its corresponding
error status from the LiteComm buffers, if there are characters
available. The status that is returned is the value of the error
status register at the time the character was received. For more
information about the error status see the lc_estat function.
Note: Note: Note:The variables for ch and status must both be pointers.
RETURN VALUES
If there are characters available and no other errors occur, the
function will return a value of zero (0). If there are no other
characters, or if some other error occurs, the function returns a
value of -1.
SEE ALSO
lc_get, lc_estat, wait, purge
43
wait
SUMMARY
#include "litecomm.h"
int wait(port, secs, sig_to_check);
unsigned port;
int secs;
unsigned char sig_to_check;
DESCRIPTION
The wait function waits for secs seconds for input from the des-
ignated port before returning. Optionally, wait will also monitor
one or more of the modem status signals and return if the signal
drops.
Secs must be greater than zero. If you do not want wait to moni-
tor a modem status signal, specify zero (0) as sig_to_check. To
specify a signal, use the constants, such as DCD, found in lite-
comm.h.
Note: Note: Note:Valid signal values are CTS, DCD, DSR, and RI.
RETURN VALUES
If a character is retrieved within the time allowed, the function
returns the character. If a character is not available in the
specified time, if the specified signal is lost, or if some other
error occurs, the function returns a value of -1.
SEE ALSO
lc_get, lc_getstat
44
purge
SUMMARY
#include "litecomm.h";
void purge(port);
unsigned port;
DESCRIPTION
The purge function discards any characters received until there
are no more incoming characters for a period of 1 second.
RETURN VALUES
This function does not return any value;
SEE ALSO
wait
45
lc_peek
SUMMARY
#include <litecomm.h>
int lc_peek(port)
unsigned port;
DESCRIPTION
Look at the next character in the serial port's input buffer. Do
not remove the character from the buffer.
RETURN VALUES
Returns the next available character in the input buffer for the
port, but does not remove the character from the buffer. This
allows the application to look-ahead by one character in a
nondestructive fashion. See additional comments under lc_get re-
garding parity. Returns -1 if the port is not active, or if there
are no characters in the port's buffer.
46
lc_put
SUMMARY
#include <litecomm.h>
int lc_put(port,ch)
unsigned port;
char ch;
DESCRIPTION
Place a character into the serial port's output buffer.
RETURN VALUES
Returns 0 if successful. Note that this does not guarantee that
the character has been sent, only that no errors were detected,
and that there was room in the transmit buffer for the character.
Characters are sent from the transmit buffer when the system has
time to send them, assuming all conditions for transmission are
satisified. Returns -1 if the port is not active, or if there no
room in the port's buffer.
47
lc_gets
SUMMARY
#include <litecomm.h>
int lc_gets(port, buff, cnt)
unsigned port;
char *buff;
int cnt;
DESCRIPTION
Read a stream of, at most, cnt characters from the serial port's
input buffer into the buff location. Ignore and discard any sta-
tus information. This function is not sensitive to the NULL
character. See lc_get for additional information.
Example Example Example
char * j;
int k;
int wrk;
j = buff; /* point to top of our buffer */
k = sizeof(buff); /* set chars needed to fill */
do
{
wrk = lc_gets(port, j, k);
if (wrk != -1) /* got something ? */
{
j += wrk; /* bump buffer pointer */
k -= wrk; /* decrement chars req'd */
}
} until (k <= 0);
RETURN VALUES
Returns the count of characters transferred into buffer, or -1 if
an error occurs.
48
lc_puts
SUMMARY
#include <litecomm.h>
int lc_puts(port, buff, cnt)
unsigned port;
char *buff;
int cnt;
DESCRIPTION
Place a stream of, at most, cnt characters into the serial port's
output buffer. Any required parity will be supplied by the serial
port itself.
Example Example Example
char * j
int j;
int sent;
j = buff;
k = sizeof(buff)
do
{
sent = lc_puts(port, j, k);
if (sent > 0)
{
j += sent;
k -= sent;
}
} until (k <= 0);
RETURN VALUES
Returns the number of characters placed into the buffer. Note
that this does not guarantee that the characters have been sent.
The number of characters transferred into the output buffer may
be less than the actual request. Returns 0 if any error occurs,
or if there is no room in the port's buffer.
49
lc_flush
SUMMARY
#include <litecomm.h>
int lc_tflush(port)
int lc_rflush(port)
int lc_flshtrue(port, ch)
int lc_nflush(port, cnt)
unsigned port;
char ch;
int cnt;
DESCRIPTION
The lc_?flush functions remove characters from the specified
buffer and discard them; untransmitted characters in the transmit
buffer are NEVER sent; unprocessed characters in the receive
buffer are lost. Do not try to use the lc_tflush to force char-
acters to be transmitted. The tflush function unconditionally
empties the transmit buffer, discarding any unsent characters.
lc_tflush empties the port's transmit buffer immediately.
lc_rflush empties the port's receive and status buffers im-
mediately.
lc_flshtrue will continually dispose of received characters
until the function finds the character ch. Use caution with
this one since it does not detect port number errors, and may
appear to seize the system.
lc_nflush flushes, at most, cnt characters from the port's re-
ceive and status buffers.
RETURN VALUES
lc_flshtrue returns no values. lc_tflush and lc_rflush return 0
if successful and -1 if an error occurs. lc_nflush returns the
number of characters flushed from the receive buffer or 0 when
there are no characters to flush, or when an error occurs.
50
lc_sbrk
SUMMARY
#include <litecomm.h>
int lc_sbrk(port)
lc_gotbrk(port)
unsigned port;
DESCRIPTION
lc_sbrk() generates a BREAK signal using a particular character-
istic of the 8250 UART family to generate an accurate BREAK at
any baud rate. BREAKs generated in this manner are timed based
upon the baud rate at which the 8250 is currently initialized.
This function may or may not work correctly with other than the
actual 8250 UART or its relatives.
RETURN VALUES
lc_gotbrk returns a nonzero value if a break signal has been re-
ceived on the specified port. It returns zero otherwise.
lc_sbrk Returns 0 if successful. Returns -1 if the port is not
active.
51
newtimer_s
SUMMARY
include "lctime.h";
void newtimer_s(et, sec);
EVENT *et;
unsigned sec;
int check_timer(et);
EVENT ev;
DESCRIPTION
The newtimer_s function creates an 'event timer' that will expire
in sec seconds. This function relies upon the calculation of an
absolute time value and does not tie into any system interrupt,
permitting as many independent timeout timers as required by your
application.
The check_timer function examines the contents of an event timer
created by newtimer_s with respect to the current date and time,
and indicates whether the timer has expired.
Do not attempt to use check_timer against a variable that was not
set by newtimer_s. If you do so, the results are unpredictable
and may result in a seeming system hang.
52
Example Example Example
EVENT cdtimer;
newtimer_s(&cdtimer, 30); /* 30 second timer */
while( ! check_timer(cdtimer))
if (check_for_call(port) > 0)
{
cprintf("Incoming call\r\n");
return(1);
}
cprintf("No calls in 30 seconds\r\n");
return(0);
RETURN VALUES
The newtimer_s function returns no value but initializes a
structure that represents a point in time sec seconds from the
time that newtimer_s was called. The check_timer function returns
a nonzero value if the specified event timer has expired, a value
of zero otherwise.
53
BBS SUPPORT FUNCTIONS
INTRODUCTION
In this chapter, we discuss a set of utility functions that were
originally developed as a part of a BBS package with one of our
registered users. Not only are they useful, in and of them-
selves, but they also act as examples of using the LiteComm
ToolBox in situations that puzzle some users.
ADDITIONAL NOTES
The use of any of the functions that follow in this section re-
quire that you define, in your code, three modem setup strings
with the names MODEMSET0, MODEMSET1, and MODEMSET2, and must be
pointers to characters. In addition, they must be defined as
global variables, and must be public (i.e., not static). Below,
we show one way to do this.
Example Example Example
char istrng0[] = "ATZ\r";
char istrng1] = "ATT E0 V0 X1 M1\r";
char istrng2[] = "ATS0=1\r";
char *MODEMSET0;
char *MODEMSET1;
char *MODEMSET2;
void main(void)
{
...
MODEMSET0 = &istrng0[0];
MODEMSET1 = &istrng1[0];
MODEMSET2 = &istrng2[0];
...
}
Experienced C programmers will readily recognize that this is not
necessarily the best approach. But it does serve to illustrate
clearly the ideas involved. Be sure to define MODEMSET0, 1, and
2 as pointers to characters as shown above, and NOT as arrays.
It is a fine destinction in C, but an important one.
54
check_for_call
SUMMARY
include "lcbbs.h";
int check_for_call(port)
unsigned port;
DESCRIPTION
This function checks the status of the specified port to deter-
mine whether (1) there is an incoming call and (2) waits for up
to 30 seconds for carrier to be established with the caller if
the phone rang. Please note that this function relies upon, in
part, the HAYES command set. Use with other than HAYES- compat-
ible modems may result in unexpected hangs or other, unpredict-
able results. The function assumes that the modem parameters
have been set in the manner described in the reset_modem func-
tion.
In the event that a wrong number call is received, check_for_call
will automatically disconnect by lowering the DTR(Data Terminal
Ready) signal momentarily, then automatically call the reset_mo-
dem function. See the notes at the beginning of this chapter,
and in the discussion of the reset_modem function. This method
of disconnecting, while absolute, will only work correctly if you
HAVE NOT set your modem to ignore the DTR signals, as is possible
with some modems. Please consult your modem's documentation for
additional detail.
RETURN VALUES
If the phone was not ringing, the function returns a value of
zero. If detects a ring was detected, but does not detect
carrier within 30 seconds, the function will return a value of -1
after forcing a disconnect and resetting the modem. Otherwise,
the function returns the numeric result code, in integer form.
It is the programmer's responsibility to interpret and act upon
the result code. For the function to work properly, the modem
must be set to return numeric result codes rather than word re-
sult codes.
55
get_modem_reply
SUMMARY
include "lcbbs.h"
int get_modem_reply(port)
unsigned port;
DESCRIPTION
The get_modem_reply function is intended for use after a command
has been issued to a HAYES compatible modem. To operate proper-
ly, the modem must be set to return numeric responses rather than
word responses. The function returns to the caller when one of
the following occurs:
No response from the modem within 1 second.
More than 2 response characters received before a <CR> is de-
tected.
A <CR> is received from the modem.
Due to the internal logic employed, the programmer should call
this function, or purge the receive buffer, after each command
sent to the modem. Failure to do so will result in improper in-
terpretation of the result codes returned.
RETURN VALUES
Returns a value of -1 if there is no response from the modem
within 1 second. Otherwise returns the integer result code. If
the modem has not been set to return numeric result codes, the
results are unpredictable.
56
reset_modem
SUMMARY
include "lcbbs.h"
int reset_modem(port)
unsigned port;
DESCRIPTION
The reset_modem function initializes the modem to a known state,
suitable for use with the other bbs functions, and based upon a
set of initialization strings provided by the user's program.
See the notes at the beginning of this chapter for additional
information regarding the way that this must be done.
Because the modem-related functions in this section make certain
assumptions about the modem, your initialization strings should
include, at a minimum, the following:
No command echo
Detect carrier
Return numeric result codes
Answer the phone on the first ring (if you need to use the
check_for_call function)
A sample set of initialization strings is shown at the start of
this chapter. If you require any additional information on these
or related options, please consult your modem's documentation.
RETURN VALUES
The reset_modem function returns the same result code as those
specified for get_modem_reply.
57
disconnect
SUMMARY
include "lcbbs.h"
void disconnect(port)
unsigned port;
DESCRIPTION
The disconnect forcibly disconnects the modem from the telephone
line by lowering the DTR signal momentarily. You must be certain
that your modem IS NOT set to ignore the DTR signal for the
function to work properly.
RETURN VALUES
Disconnect returns no values.
58
HAYES MODEM FUNCTIONS
Note: Note: Note:When using the following functions, you must include the
file litehcm.h in your program. litehcm.h automatically includes
the litecomm.h header file.
FUNCTIONS
lch_codeset
lch_dial
lch_fduplex
lch_hduplex
lch_greg
lch_sreg
lch_offcarr
lch_oncarr
lch_offecho
lch_onecho
lch_hook
lch_redo
lch_numres
lch_wrdres
lch_codesoff
lch_codeson
lch_pulse
lch_tone
lch_speaker
_retset
_rettype
SUMMARY
#include <litehcm.h>
int lch_codeset(port,mode)
int lch_dial(port,dstr)
int lch_fduplex(port)
int lch_hduplex(port)
int lch_greg(port,reg)
int lch_sreg(port,reg,value)
int lch_offcarr(port)
int lch_oncarr(port)
int lch_offecho(port)
int lch_onecho(port)
int lch_hook(port,hmode)
int lch_redo(port)
int lch_numres(port)
int lch_wrdres(port)
int lch_codesoff(port)
int lch_codeson(port)
59
int lch_pulse(port)
int lch_tone(port)
int lch_speaker(port,spkmode)
int _retset()
int _rettype()
unsigned port;
unsigned mode;
char *dstr;
unsigned reg;
int value;
unsigned hmode;
unsigned spkmode;
DESCRIPTION
The values to be used with mode, hmode, and spkmode are defined
symbolically in the #include file, litehcm.h.
The lch_codeset lch_codeset lch_codeset function allows you to change the set of codes
returned by the modem when an action is specified.
lch_dial lch_dial lch_dial instructs the modem to dial the number contained in
dstr. Do not include the dialing (ATD) prefix, or the trailing
<\r>. These are provided by the function. You may include non-
numeric characters that are acceptable to your modem, since the
function does not check the contents of dstr. The dialing is in
the last known dialing mode, either pulse or tone. If you use the
lch_pulse or lch_tone functions, then dialing will be done in the
mode that was last correctly enabled. If you have not exercised
these functions, then dialing occurs in the modems default or
power-up mode.
The lch_hduplex lch_hduplex lch_hduplex and lch_fduplex lch_fduplex lch_fduplex functions place the modem into
local echo and remote echo modes respectively.
The lch_greg lch_greg lch_greg function requests that the modem report the current
value of S-register reg. Reg must be in the range 0 to 13. Use
the lc_gets, or similar function, to retrieve the modem's re-
sponse. Specifying a register outside the 0 to 13 range will
cause a return of -1.
lch_sreg lch_sreg lch_sreg is the companion to lch_greg, with the same restric-
tions. Sets the S-register reg to the value contained in value.
If value contains -1, then the register is reset to its default
(power-up) value. The function checks the value to be certain
that it is within the limits specified for the particular regis-
ter, and returns a value of -1 if the value is outside the
predefined limits.
lch_offcarr lch_offcarr lch_offcarr enables modem carrier detect, but disables the mo-
dem's carrier signal. The lch_oncarr companion enables both car-
rier detect and the modem's carrier signal. When lch_offcarr is
used the modem will receive data but will be unable to send data.
60
The lch_offecho lch_offecho lch_offecho and lch_onecho lch_onecho lch_onecho functions determine whether com-
mands sent to the modem are echoed back to the sending program.
With echo turned off, the modem will continue to accept commands,
but will not try to redisplay the command's characters.
lch_hook lch_hook lch_hook allows you to control the status of the modem's tele-
phone line connection. See your modem's documentation and the
include file for additional information.
The lch_redo lch_redo lch_redo function instructs the modem to repeat the last
command sequence executed. Generally, this function is of great-
est value in redialing numbers that are busy, although its use is
not restricted to that.
The way in which your modem responds to commands is determined,
in part, by the lch_wrdres lch_wrdres lch_wrdres and lch_numres lch_numres lch_numres functions. If you call
lch_wrdres, then modem responses use the English language re-
sponse codes, e.g,. CONNECT or OK. Calling lch_numres instructs
the modem to respond with code numbers only from the currently
selected response set, see the lch_codeset function.
You may use the functions lch_codeson lch_codeson lch_codeson and lch_codesoff lch_codesoff lch_codesoff to specify
whether you want your modem to send back response codes when it
receives a command string. In a sense, these act as companions to
the lch_xxxecho functions above.
Use the lch_speaker lch_speaker lch_speaker function to control the modem's internal
speaker, if it has one. See litehcm.h for the applicable codes.
The _retset _retset _retset and _rettype _rettype _rettype functions return, respectively, the last
known command set (lch_codeset) and last known result type
(lch_wrdres, lch_numres). These functions (_retset, _rettype) are
only of value when used with the companion functions.
GENERAL REMARKS
Several considerations are in order if you intend to use the
Hayes ToolBox functions.
You are responsible for checking the return codes from the modem
once you have given modem a command. To make the task easier, we
suggest that you turn OFF command echo. Then you won't have to
worry about separating commands from responses. Finally turn ON
numeric responses to make the interpretation of result codes
easier and faster.
Note: Note: Note:Be sure that you allow adequate time between commands for
the modem to process the command and respond. Failure to observe
this rule may result in commands being misinterpreted or "lost."
You can monitor the number of characters in the receive buffer to
help you with the timing. Or alternatively, check the response
after each command. The latter approach is more in line with what
we believe to be good programming practice.
61
RETURN VALUES
All functions return a value of -1 if a port or other error oc-
curs, zero otherwise.
62
INDEX INDEX INDEX
_lc_error, 18 get_modem_reply, 56, 57
_portchg, 12, 19 handshaking, 7, 8, 9, 10, 18,
_retset, 59, 61 30, 32, 33
_rettype, 59, 61 HAYES, 55, 56, 59, 61
HAYES MODEM FUNCTIONS, 59
16450, 3, 9
16550, 3 identification, 4, 6
8250, 3, 5, 6, 9, 10, 12, 51 INSTALL, 15
8259, 11, 12, 13 INSTALLATION, 15
interrupt, 4, 5, 6, 9, 10,
Alignment, 10 11, 12, 13, 14, 16, 19, 20,
ASP, 1 22, 28, 30, 32, 33, 52
baud, 5, 6, 7, 11, 14, 20,
23, 51 IRQ, 11, 12, 13, 19
BBS SUPPORT FUNCTIONS, 54 ISA, 4
ISR, 4, 5
BIOS, 12, 14 lc_clearhwflow, 38, 39
BREAK, 5, 8, 51
buffer, 20, 25, 29, 34, 42, lc_clrmdm, 30, 32, 33
46, 47, 48, 49, 50, 56, 61 lc_estat, 28, 43
buss, 4, 13 lc_flush, 50
lc_get, 42, 43, 44, 46, 48
C, 14, 15, 16, 18, 22, 54
chain, 13 lc_gets, 48, 60
check_for_call, 17, 55, 57 lc_getstat, 42, 43, 44
COM1, 1, 5, 12, 14 lc_getw, 29
COM2, 8, 11, 12, 14 lc_got, 26, 27
lc_gothwstop, 38, 39, 41
COM3, 11, 12, 13, 14, 19
COM4, 1, 11, 12, 13, 14, 19 lc_gotxoff, 34, 35, 37
comm_close, 20, 22, 32 lc_icnt, 25
comm_opn, 11, 12, 20, 22, 23, lc_mstat, 17, 26, 27
24, 30 lc_ocnt, 25
comm_setup, 23 lc_peek, 46
control, 3, 4, 5, 7, 8, 9, lc_put, 47
10, 11, 16, 18, 20, 22, 24, lc_puthwstop, 38, 39, 40
30, 32, 33, 34, 35, 36, 37, lc_puts, 49
38, 39, 40, 41, 61
debuggers, 14 lc_putxoff, 34, 35, 36, 37
Digiboard, 12 lc_sbrk, 51
lc_setdtr, 30, 31
disconnect, 55, 58 lc_sethwflow, 38, 39, 40, 41
divisor, 5
DTR, 7, 10, 20, 21, 22, 30, lc_setmdm, 10, 30, 31, 32, 33
31, 32, 33, 38, 55, 58 lc_setrts, 30, 31
echo, 57, 60, 61 lc_setxoff, 34, 35, 36, 37
lc_setxon, 34, 35, 36, 37
EISA, 4
ERROR, 5, 6, 10, 11, 18, 21, lc_togmdm, 30, 32, 33
22, 23, 24, 25, 26, 28, 35, lc_vport, 24
36, 37, 38, 39, 40, 41, 43, lc_xoff, 34, 35, 36, 37, 38
44, 48, 49, 50, 62 lch_codeset, 59, 60, 61
event, 52, 53, 55 lch_codesoff, 59, 61
flow control, 11, 18, 34, 35,
36, 37, 38, 39, 40, 41 lch_codeson, 59, 61
INDEX INDEX INDEX
lch_dial, 59, 60 status, 5, 6, 7, 8, 11, 26,
lch_fduplex, 59, 60 27, 28, 31, 42, 43, 44, 48,
lch_greg, 59, 60 50, 55, 61
lch_hduplex, 59, 60 TSR, 16
UART, 3, 9, 12, 51
lch_hook, 59, 61 USECTS, 38
lch_numres, 59, 61
lch_offcarr, 59, 60 USEDSR, 38
lch_offecho, 59, 61 USEDTR, 38
USERTS, 38
lch_onecho, 59, 61 vector, 4, 11, 12, 13, 19
lch_redo, 59, 61
lch_speaker, 59, 61 wait, 42, 43, 44, 45
lch_sreg, 59, 60 warning, 9, 10
warranty, 2
lch_wrdres, 59, 61 workarounds, 9
length, 7, 20
libraries, 15, 16 Xmodem, 2
license, 2 Xmodem-1K, 2
XON-XOFF, 18, 34, 37
memory, 4, 9, 10, 12, 20, 22 YModem, 2
micro-channel, 4
multitasking, 16, 17 ZModem, 2
newtimer_s, 52, 53
NULL, 24, 48
open, 8, 9, 10, 11, 12, 14,
20, 21, 22, 25, 26, 28
OUT2, 7, 30, 32, 33
parity, 7, 10, 20, 23, 28,
42, 46, 49
PC, 3, 4, 9, 10, 11, 12, 13
port, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 16, 19,
20, 21, 22, 23, 24, 25, 26,
27, 28, 29, 30, 31, 32, 33,
34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 55, 56, 57,
58, 60, 62
priority, 4, 13, 19
PS/2, 13, 16
purge, 42, 43, 45, 56
register, 5, 6, 7, 8, 12, 43,
60
Registration, 1, 2
reset_modem, 55, 57
RI, , 17, 44
RTS, 7, 10, 20, 22, 30, 31,
32, 33, 38
Shareware, 1, 2, 16