                       R.V. Rodygin (Russia, Novosibirsk)
              comport.com: the program for control of serial ports
                    according to a user-written script file.
                         Version 1.2 (2003, October 6).

   1. Purpose of the program:

The program is intended for transmitting of bytes to serial ports, manipulating
by their baud rate, controlling of their LCR and MCR registers and of system
speaker according to arbitrary timetable defined in user-written script file.
The user can observe on the screen all actions performed by the program, as
well as all information received by the program from serial ports.

The program is designed for execution under DOS, however works correctly also
under Windows 95/98/ME. Under Windows NT/2000 functionality of the program is
pared-down: unforeseen delays (up to hundreds of milliseconds) are possible
when requested timetable is executing.

Hardware requirements: Intel-compatible processor not worse than Intel386.

The program can operate with serial ports COM1 and COM2 only.

   2. Script files:

The name of a used script file is defined in a command line when the program is
launched. If the command line is empty, the default filename "comport.cfg" is
used.

The letter case is significant: all keywords must be in lowercase. Hexadecimal
digits can be both in uppercase or lowercase. Hexadecimal numbers are not
prefixed/suffixed with "0x" or "h": the program determines by context, whether
the number is decimal or hexadecimal. Zeroes in high-order digits of
hexadecimal numbers cannot be omitted. Zeroes in high-order digits of decimal
numbers must be omitted.

The text can contain comments: the comment is a part of a string, since symbols
// and up to end of string (as in C++). If in some place of text a single space
is allowed, that place can contain also arbitrary sequence of spaces, line
feeds, "tab" symbols and comments.

When numbers of row and column are counting, a "tab" symbol is counted as
single symbol.

   3. Structure of a script file:

The text of a script file consists of descriptions of controlled objects, one
after another. Before, between and after these descriptions the spaces are
allowed. The program is able to control three objects: the serial port "COM1",
the serial port "COM2" and the system speaker. Each object can be described no
more than once (therefore, the text can contain from 0 to 3 descriptions).
The order of the descriptions is inessential.

If the script file exists, but not contains any descriptions, the program
doesn't do anything, but not terminates to let the user look the date-line of
the program. If there are several descriptions, they are executing
simultaneously and independently one from another.

Each description consists of three parts: the identificator of object (com1,
com2 or speaker), the "once" statement and the "repeat" statement. The "once"
statement defines the part of timetable, which is executed once, immediately
after the program is launched. The "repeat" statement defines the part of
timetable, which executed cyclically, after completion of "once" statement
execution, and until the user terminates program execution.

Both the "once" and the "repeat" statements can be omitted. If the "once"
statement is omitted, execution of the "repeat" statement starts just after
starting of the program. If the "repeat" statement is omitted, after completion
of the "once" statement execution the program finishes execution of timetable
for corresponding object. If the program finished execution of timetables for
all used objects, program execution is terminated withouth waiting of users
command.

   4. Sequences of commands:

Both the "once" and the "repeat" statement consists from corresponding keyword
("once" or "repeat"), after which a sequence of commands is placed. The
sequence is enclosed in curly braces. Each command in the sequence consists of
a symbol or a keyword designating its type, after which the parameter is
placed. Following types of the commands are used:

>H            send the byte to the serial port
lcr=R         write the byte to the Line Control Register
mcr=R         write the byte to the Modem Control Register
rate=D        set the baud rate
+D            wait during specified interval of time
timeout=D     set timeout to transmitting of a byte to the serial port
~D            turn on the speaker
^             turn off the speaker

Where:
   H means two-digit hexadecimal number
   D means decimal number
   R means either two-digit hexadecimal number, or value, presented in symbolic
     form

Sequences of commands for objects "com1" or "com2" can contain all this
commands. Sequences of commands for object "speaker" can contain only these
commands: +D, ~D and ^.

Total length of all sequences of commands is limited only by volume of memory,
assigned for storing of commands. This volume is equal to 32768 bytes. Each
command occupies in this memory from 2 to 6 bytes.

   5. The command "send the byte to the serial port":

This command has format >H where H is two-digit hexadecimal number.

Time of transmitting of the byte to the serial port is limited by timeout (see
below).

   6. The command "write the byte to the Line Control Register":

This command has format lcr=R where R is either two-digit hexadecimal number,
or value, presented in symbolic form, which is represented as list of field
values, enclosed in brackets. Field values must be separated by spaces and can
be arranged in any order. The LCR register has three fields: the number of data
bits, the number of stop bits and the parity type. Following field values are
allowed:

field "the number of data bits":
   data5 - five data bits
   data6 - six data bits
   data7 - seven data bits
   data8 - eight data bits

field "the number of stop bits":
   stop1 - one stop bit
   stop2 - one and a half, or two stop bits

field "the parity type":
   odd    - parity is odd
   even   - parity is even
   stuck0 - the parity bit always is equal to 0
   stuck1 - the parity bit always is equal to 1

If some of fields are not explicitly defined then their values are equal to
zero, in particular:
   if the number of data bits is omitted, then there are 5 data bits (!)
   if the number of stop bits is omitted, then there are 1 stop bit
   if the parity type is omitted, then parity is not used
Empty brackets means then all fields are equal to zero.

When the program is started, it set value of the Line Control Register to
[data8 stop1].

   7. The command "write the byte to the Modem Control Register":

This command has format mcr=R where R is either two-digit hexadecimal number
or value, presented in symbolic form, which is represented as list of bit
names, enclosed in brackets. The bits, which names are specified in the list,
will be set. Other bits will be reset. Empty brackets mean then all bits must
be reset. The bit names must be delimited by spaces and can be arranged in any
order. Following bit names are allowed:

loopback - activate loopback for diagnostic testing
out1     - signal at the OUT1 pin
rts      - signal at the RTS pin
dtr      - signal at the DTR pin

When the program is started, it sets the value of the Modem Control Register to
RTS|DTR|STI.

   8. The command "set the baud rate":

This command has format rate=D where D is decimal number, specifying the clock
divisor of the serial port. The divisor must be in range 1...65535 and is
evaluated as 115200/speed.

When the program is started, it set the baud rate to 9600 bit/s (divisor=12).

   9. The command "wait during specified interval of time":

This command has format +D where D is decimal number, specifying the time
interval. Interval is measured in "ticks" of the Real Time Clock (RTC). Each
"tick" is equal to 1/1024 part of second, i.e. approximately one millisecond.

The program measures time with quantizing error to one "tick". This achieved
by hooking of interrupts from the Real Time Clock.

   10. The command "set timeout to transmitting a byte to the serial port":

This command has format timeout=D where D is decimal number, specifying time
of waiting of acknowledge from the serial port to transmitting of a byte. When
acknowledge do not arrive during this time, the program assumes then
transmitting of the byte was unsuccessful. Then the program goes on to
executing of next command. Timeout value is measured in "ticks" of the RTC (see
above).

The command "timeout" do not result in writing anything to hardware ports, but
is merely internal command, that influences to execution of subsequent commands
">".

When the program is started, the timeout value is pre-setted to 10 "ticks".

   11. The command "turn on the speaker":

This command has format ~D, where D is decimal number, specifying the divisor
word of sound (not frequency !). The divisor word must be in the range
1...65535. Frequency (in hertz) of the sound can be calculated as
1193180/divisor word.

The sound will be continued until the command "turn off the speaker" will be
executed, or the program will be terminated. Sound can be preempted by the
subsequent command "turn on the speaker", even if that command reffers to
another object).

   12. The command "turn off the speaker":

The command has format ^.

   13. Additional notes:

The program does not permit the user to operate DLAB bit of the LCR register
and OUT2 (in other words STI) bit of the MCR register. This is because these
bits are used for special purposes. If parameter of the "lcr=" or "mcr="
commands is defined in hexadecimal form, corresponding bits of this parameter
are ignoring by the program.

The "lcr=", "mcr=", "rate=" and "timeout=" commands are synchronous. The ">"
and "+" commands are asynchronous. In the user standpoint, there is following
distinction: when time of execution of sequence of the commands is calculating,
we can assume, than synchronous commands are executed instantly (actually its
executing, of course, take up some time, but executing proceeds simultaneously
with counting of next "tick" by the RTC). On the contrary, execution of
asynchronous commands cannot be assumed as instantaneous: even if the ">"
command is executed in very short time, nevertheless when several such command
is executed, its times are pooled.

A sequence of commands, defined in a "repeat" statement, must contain at least
one asynchronous command (">" or "+"). If such command is not contained, the
program issues the error message when it parse the script file (otherwise the
program would enter to perpetual cycle at the time of interrupt).

   14. Tracing:

When the program is running, all important events are reflected in two pages of
screen (one for each serial port). The page, representing the serial port COM1
is displayed when the user presses the F2 key, the page for COM2 - when the F3
key. A sequence of following tracing messages is reflected on the screen pages:

Reset    (black on white background)
   The serial port was initialized (including LCR=[date8, stop1],
   MCR=RTS|DTR|STI)

>H       (blue on black background)
   The byte H was written to transmitting buffer of the serial port.

lcr=H    (black on green background)
   The byte H was written to the Line Control Register.

mcr=H    (black on cyan background)
   The byte H was written to the Modem Control Register.

rate=H   (black on magenta background)
   The baud rate corresponding to divisor H was assigned.

<H       (yellow on black background)
   The byte H was accepted from the serial port.

msr=H    (black on yellow background)
   An interrupt was arose because of changing of value of the Modem Status
   Register. New value of the MSR is equal to H.

!H       (red on black background)
   A message was accepted, reported of serial port error. Value of the Line
   Status Register is equal to H.

!t       (black on red background)
   The timeout of transmitting of a byte to the serial port was elapsed.

}        (black on white background)
   The user "froze" the screen pages.

{        (black on white background)
   The user "defroze" the screen pages.

Tracing messages contains values, actually written to registers. This value can
be not equal to parameters of corresponding commands (see "additional notes").

   15. Timekeeping:

When the tracing messages are arrived, the program can perform timekeeping,
i.e. show time intervals between those messages. Timekeepeng is performed by
means of following messages:

+D       (gray on black background)
   D "ticks" of the RTC was elapsed. Actually elapsed time is indicated, not
   only time ordered by "+" command. The program does not show empty intervals
   of time.

+?       (gray on black background)
   More than 48.5 days was elapsed. The program uses 64-bit counter of "ticks",
   however it can show on a screen and read from a file only 32-bit numbers.

[        (gray on black background)
   Timekeeping was switched on.

]        (gray on black background)
   Timekeeping was switched off.

Timekeeping can be switched on by "[" key and be switched off by "]" key.
Immediately after launching of the program the timekeeping is switched off.

When timekeeping is switched off, the program consumes slightly less amount of
processor time.

   16. Statistics:

The program counts basic events (a byte was transmitted, a byte was received
etc) which occurs with the serial ports while the program is running. The user
can view obtained statistics on the screen page that arises when he presses F4
key. This page also reflects current state of the serial ports: divisor of baud
rate, values of LCR, MCR and MSR registers. Register values are showed in
binary form: "one" is shown as '+' and "zero" - as '-'.

All counters are 32-bits. Overflow checking is not performed, therefore when
program work in long time (more than 3 days) some counters can contain
incorrect values.

When screen page with statistics do not shown on the screen, program consumes
slightly less amount of processor time.

   17. "Freezing" of the screen pages:

Contents of the screen pages can be "frozen" by the user command. When the
pages are "frozen", displaying of incoming tracing messages is stopped and
updating of images of statistics items is stopped also. Generation of the
signal and counting of statistics are not stopped. Tracing messages, that
income when the pages are "frozen", will be lost.

"Frozen" pages can be switched by the F1...F5 keys just as "not frozen".
The user "freezes" screen pages by pressing of the '-' key and "defreezes" by
pressing of the '+' key (keys on the main keyboard or on the keypad can be
used). Immediatelly after program launching the trace is not "frozen".

When the pages are "frozen", the counter of seconds, elapsed from starting of
the program, is "frozen" also. Until this counter is "frozen", its fractional
part is additionally written to it. Fractional part is evaluated in "ticks" of
the RTC (1/1024 part of second). When the tracing is not "frozen", only
integer part of counter is showed on the screen.

When the pages are "frozen", the program consumes slightly less amount of
processor time.

   18. Known errors:

1) The video mode is not restored when the program is terminated.

2) When the program is launched under Windows95/98 and switching between
   window and full-screen modes occurs, contents of the screen pages can be
   corrupted. This is bug in Windows, not in the program.
