                AVATAR Console, Level 1, Specification

                Copyright (C) 1990, G. Adam Stanislav
                All Rights Reserved

1. This document assumes you are familiar with Avatar 0 and Avatar 0+
(AVT/0 and AVT/0+) specifications.

2. Avatar, level 1 (AVT/1), consists of two main divisions:

        - Avatar protocol
        - Avatar console

3. Avatar protocol is designed for more efficient use of online services.
It will be described in a separate document. For now, let us just reveal
that Avatar protocol is based on an asymetrical model. In this it differs
from many protocols, especially those used for file transfer.

4. Symetrical protocols are designed as if both ends of the communications
link were equal. Most file transfer protocols, such as Xmodem, are symetrical.
They do not distinguish between the uplink and the downlink. A file can be
both downloaded and uploaded using the same Xmodem protocol.

5. In real life, computers are not designed symetrically. There is the CPU and
the console, or the system and the terminal, or the BBS and the user, etc.
Symetrical protocols can ignore this distinction because of their limited
purpose.

6. Avatar, as an asymetrical protocol, allows more than file transfer. It can
handle such things as a user logon to a system, transfer of multiple files
in either direction simultaneously with other activities, etc. Further
details are beyond the scope of this document.

7. Avatar console is the division of Avatar that most of us are already
familiar with. Level 0 is used by Opus-CBCS, version 1.10 and up. While
Avatar protocol is designed to work with serial communications, Avatar
console can also be used locally. It can be implemented either in hardware
or software. The enclosed AVATAR.SYS is an example of Avatar console
software implementation in MS DOS world. We will be calling AVATAR.SYS, or
any similar software, as well as any appropriate hardware circuits "the
driver."

8. There were three main reasons for the development of Avatar console:

        - speed
        - versatility
        - portability

9. A similar system has been in use, often called "ANSI graphics." This
designation is only partly correct. It does not deal with graphics. It is
character oriented (just as AVT/1 is). It is only a subset of ANSI standard.

10. ANSI graphics lack in all three main reasons for Avatar console as listed
above. It uses long codes which are easy for humans to read. However, as they
control the console, they are never read anyway. But an ANSI code to set
color attribute can be up to 7 bytes long. A comparable Avatar code is three
bytes long, thus takes much less time to transfer over the communication
link.

11. ANSI graphics were designed a while ago and do not support many modern
ideas, such as multiple windows, sound control, direction of the flow, etc.
Avatar console incorporates these commands.

12. There are many dialects of ANSI graphics. While there is a defined
standard, various manufacturers decided to adapt whatever they wanted. Avatar
console is very straightforward. Because it was not defined by a committee,
there are no compromises in Avatar console.

        Avatar, level 1 (AVT/1), console control codes:

        Overview:

13. Except for ^L (clear current window) and ^Y (repeat character), all Avatar
control codes start with AVTCODE (^V, SYN, 22 decimal, 16 hexadecimal).
AVTCODE is followed by a one-byte code defining the command. The command
byte may be followed by parameters. While the number of parameters varies
from command to command, it is always the same for the same command. The only
exception is ^V^Y - repeat pattern.

14. There is a clue to know whether an Avatar code is a console code or a
protocol code. Avatar console commands are in the range of 01-3F hexadecimal.
Avatar protocol codes are above this range. There is no Avatar control code
of 00. If a control code greater than 3F is somehow sent to the console, the
driver turns its high bits off like this:

                code = code AND 3F;

15. This overview lists the console command codes without the initial AVTCODE
or parameters. The command code is followed by the number of parameters the
code uses, then by a brief desription.

        ^A  - 1 - set current attribute
        ^B  - 0 - turn blink on
        ^C  - 0 - move cursor one line up
        ^D  - 0 - move cursor one line down
        ^E  - 0 - move cursor one column left
        ^F  - 0 - move cursor one column rught
        ^G  - 0 - clear to the end of the line
        ^H  - 2 - locate cursor position
        ^I  - 0 - turn insert mode on
        ^J  - 5 - scroll area up
        ^K  - 5 - scroll area down
        ^L  - 3 - clear area, set current attribute
        ^M  - 4 - initialize area, set current attribute
        ^N  - 0 - delete character, sroll eol left
        ^O  - 0 - turn clockwise mode on
        ^P  - ? - dummy call, NOP
        ^Q  - 1 - query the driver
        ^R  - 0 - reset the driver
        ^S  - 3 - sound a tone
        ^T  - 1 - highlight cursor position
        ^U  - 2 - highlight a window
        ^V  - 6 - define a window
        ^W  - 1 - switch to a window
        ^X  - 0 - flush input
        ^Y  - * - repeat pattern
        ^Z  - ? - <reserved>
        ESC - ? - reserved for ANSI
        FS  - 0 - go to sleep
        GS  - 0 - wake up
        RS  - 0 - start vertical mode
        US  - 0 - end vertical mode
        SP  - ? - <reserved>
        !   - 4 - poke
        "   - 0 - do not wrap at eol (wrap off)
        #   - 0 - switch direction at eol (wrap zigzag)
        $   - 0 - wrap at eol (wrap on)
        %   - 0 - reverse LF action
        &   - 0 - normalize LF action
        '   - 1 - set cursor type
        (   - 0 - do not print in reverse
        )   - 0 - print in reverse
        *   - 1 - make system pause
        +   - 0 - insert line
        ,   - 0 - insert column
        -   - 0 - delete line
        .   - 0 - delete column
        /   - 1 - set/reset static mode
        0   - 1 - highlight eol
        1   - 1 - highlight bol
        2-9 - ? - <reserved>
        :   - 1 - keyboard mode
        ;   - ? - <reserved>
        <   - 5 - scroll area left
        =   - 1 - set parser mode (cooked or raw)
        >   - 5 - scroll area right
        ?   - 2 - peek

        Detailed description:

        ^L         - Clear the current window and set current attribute
                   to default. Change current attribute to equal default
                   attribute. In AVT/0 the default attribute is always 3.
                   In AVT/1, the default attribute of window 0 is 7. All
                   other windows can have any default attribute defined.

        ^Y <a> <b> - Print byte <a> <b> times.

        ^V ^A <a>  - Set current color attribute to <a>. Default attribute
                   remains unchanged. If <a> has high bit set, ignore it.

        ^V ^B      - Turn blink on.

        ^V ^C      - Move the cursor one line up. Do nothing if you are
                   at the top line of current window already.

        ^V ^D      - Move the cursor one line down. Do nothing if you are
                   at the bottom line of current window already.

        ^V ^E      - Move the cursor one column to the left. Do nothing
                   if you already are at the leftmost column of the window.

        ^V ^F      - Move the cursor one column to the right. Do nothing
                   if you already are at the rightmost column of the window.

        ^V ^G      - Clear the rest of line (cleol) in current window
                   using current attribute.

        ^V ^H <r> <c> - Move the cursor to row <r> and column <c> in current
                   window. Note that the upper left corner of the window
                   is 1, 1.

16. All of the above codes have been defined in the original AVT/0 spec. They
function identically as before, however, they do not necessarily control
the entire screen. AVT/0 recognized only 1 window which covered the entire
screen and had a default attribute of 3. AVT/1 recognizes 256 windows,
numbered 0-255. They originally cover the entire screen and have a default
color attribute of 7. In window 0 these defaults cannot be changed, in all
other windows they can as described later.

17. To emulate AVT/0 with an AVT/1 driver, define a window (other than 0), make
it cover the entire screen and set its default attribute to 3. Set the parser
mode to raw (see later for details). Switch to that window. Now you are
fully compatible with AVT/0.

        ^V ^I      - Turn insert mode ON. It stays on until any other
                   Avatar console command except ^Y and ^V ^Y. Switching
                   to a different window and then back does not turn it
                   off either (although it is confined to the window it
                   was defined in).

        ^V ^J <a> <b> <c> <d> <e> - Scroll area <bcde> up by <a> lines.
                   If <a> is 0 or greater than the number of lines in the
                   window, this command will clear the area. Whatever is
                   scrolled in, is set to current attribute. (This can be
                   used as an alternative to clearing the screen without
                   changing current attribute, although better alternatives
                   exist).

        ^V ^K <a> <b> <c> <d> <e> - Same as ^V ^J but scroll the are down.

        ^V ^L <a> <b> <c> - Clear area, starting at current cursor position,
                   of <b> lines and <c> columns, using <a> color attribute.
                   <a> also becomes the new current attribute.
                   This is probably the most efficient way of clearing an
                   area of the screen without forcing the current attribute
                   to be the same as default attribute. It is a subcommand
                   of ^V ^M with its character parameter defaulting to blank.

        ^V ^M <a> <b> <c> <d> - Initialize area. Similar to ^V ^L. It sets
                   current attribute to <a> and fills <c> lines and <d>
                   columns with character <b>.

        ^V ^N      - delete character at current cursor position. Scroll the
                   rest of the line in current window left.

        ^V ^Y <a> [...] <c> - repeat pattern. <a> defines the number of bytes
                   in the pattern, <c> the number of times the pattern
                   should be repeated. If either value is a zero, nothing
                   is done. The pattern can contain Avatar console codes,
                   including other ^V ^Y patterns.

18. The above commands were defined in AVT/0+. There is one change from AVT/0+
int AVT/1: A backspace moves one column back (unless at the leftmode end of
the window already). In AVT/0 this did not overwrite the character at that
position. This behavior was not using backspace in its usual manner and
was unnecessarily duplicating another AVT/0 command. Therefore, AVT/1 console
will print a blank in current attribute over the character the cursor is
moved to. This corresponds to the way backspace is generally used in other
console systems. It does not really break backwards compatibility because
Opus 1.10+ always sends a BS SP BS sequence which results in the same. I am
not sure at the moment what Luke does, but since Luke was not released yet,
I will fix it to work as defined here. I am not aware of any other BBS
software using Avatar, everyone seems to have been waiting for this doc. :-)

19. New commands in AVT/1:

        ^V ^O      - turn clockwise mode on. If the cursor is not at the
                   edges of the window, printing continues in the same
                   direction as it was before this command was issued.
                   However, once an edge is reached (typically the rightmost
                   column of the window), printing continues in clockwise
                   direction. That means: If at the rightmost column, text
                   is printed downwards; if in the last row, text is printed
                   to the left; in the leftmost column text is moving upwards;
                   in the first row it is printed to the right.

                   This command is designed to allow creating a frame
                   around a window. Typically, the window should be shrunk
                   by one column and row in every direction after the
                   frame was created. Otherwise the frame will be overwritten.

                   The frame mode stays on until a CR is sent to the console.

        ^V ^P      - This is a dummy call. ^P is the same as DLE which
                   could become real confusing.

        ^V ^Q <a>  - Query the driver. <a> defines the type of query. The
                   driver sends its reply to stdout (or to the serial port
                   if the driver is designed to work in serial communications
                   only). This can be used to determine whether an AVT/1
                   console driver is present. If no reply is detected, AVT/0
                   or no Avatar at all should be assumed.

                   If stdout is buffered, the reply is given highest
                   possible priority. In other words, sending a query to
                   stdout will result in the reply being the next thing
                   read from stdin, even if something else was waiting in
                   stdin buffer. However, if several queries are send to
                   Avatar console, the replies will come out in the same
                   order as the queries.

                   In practical life this means stdin has two buffers,
                   on for regular input, one for replies to Avatar queries.
                   The replies to queries are appended to reply buffer.
                   But stdin always checks the reply buffer before its
                   regular buffer.

                   It is important to realize that the size of reply
                   buffer is only guaranteed to hold the longest reply
                   possible. If several queries occur in a row without
                   reading the replies, the reply buffer may overflow.
                   In that case, no new replies will be appended until
                   some room is cleared in the reply buffer.

                   This means a query should be immediately followed by
                   reading the reply. However, you may want to place several
                   queries which result in short replies (see below)
                   when using AVT/1 in serial communications because of
                   the propagation delay.

                   Individual queries and types of replies that offer
                   are described later in this document.

        ^V ^R      - reset the driver. All windows are reset to the
                   initial default values: full screen, color attribute
                   7, left-to-write, regular cursor, etc. Window 0 becomes
                   current default window. Cursor position remains at the
                   same physical position on the screen it was immediately
                   before the reset.

                   A remote system should never issue the reset command.
                   Instead, it should send ^V followed by capital R. This
                   is the Avatar protocol Reset Request. We are running ahead
                   of ourselves by saying this, but Avatar console is designed
                   to work with Avatar protocol (at least for remote control).
                   Originally, we did not intend to release Avatar console
                   specs before Avatar protocol specs but too many people
                   have asked we do...

                   At any rate, the reason why a remote system should not
                   release the reset command directly is that it lets the
                   local terminal program decide whether it should be using
                   raw or cooked mode for the output. The reset command
                   places Avatar console in cooked mode. As will be
                   explained in the protocol specs, the local terminal may
                   not want to use the cooked mode. Thus, an intelligent
                   Avatar terminal *may* decide to switch back to raw mode
                   after it issues the reset command.

                   This in no way interferes with terminal programs that are
                   not AVT/1 aware and that simply send output to AVATAR.SYS
                   without even knowing about it. If you re-read paragraph
                   14 above, you will notice that the parser will convert
                   the R to a ^R before sending it out to the interpreter.
                   Please note it must be a CAPITAL R for this to function
                   properly.

        ^V ^S <a> <b> <c> - Sound tone <a> in octave <b> of duration <c>.
                   The tone byte is defined by the following formula:

                       <a> = (tone - 'A') * 2 + sharp

                   In this formula, tone is somewhere between 'A' and 'G',
                   sharp = 0 or 1 as case may be.

                   In other words, A = 0, A# = 1, B = 2, B# = 3, etc.
                   If the value of <a> is 14 or greater, a musical pause
                   of duration <c> is included. In that case the octave
                   parameter is ignored and can have any value.

                   Please note that some tones are musically identical.
                   Thus E# is the same as F. Avatar lets you request
                   either but will of course make identical sounds for
                   the two.

                   Musically, B# is the same as C. Because, however,
                   an octave starts with a C and ends with a B#, Avatar
                   will not play the same tone for B# and C. B# sharp
                   will be one octave above C.

                   Octave is a signed integer (8 bits). Middle octave
                   equals 0, next higher equals 1, etc. The octave
                   below middle equals -1 (same as 255 unsigned), etc.
                   Please be advised there are only so many octaves human
                   ear can detect.

                   Duration is defined in tenths of a second (depending
                   on the computer system this value is approximate,
                   AVATAR.SYS uses two clock ticks as its measure, i.e.
                   1/9.1 sec). If two identical tones follow each other
                   with no intervening pause, Avatar will play them legato,
                   without a break.

                   Avatar console buffers the tones requested. The size
                   of the buffer may vary from driver to driver, but as
                   long as the system has the ability of at least primitive
                   multitasking, processing continues while music plays.
                   This is of course the case with AVATAR.SYS as multitasking
                   is fairly easy to achieve on the PC.   :-)

        ^V ^T <a>  - highlight current cursor position. Color attribute
                   at current cursor position is replaced with <a>. If the
                   high bit of <a> is on, the highlighted character will
                   start blinking. This command does not change current
                   attribute or default attribute, only highlights the one
                   character at cursor position.

        ^V ^U <a> <b> - highlight window <a> with the attribute of <b>.
                   The entire window is filled with attribute <b>. Any
                   characters present in the window will remain there,
                   only their color attribute will change. The command
                   does not change current or default attribute. This
                   command was designed with menus in mind, but of
                   course can be used for other purposes.

        ^V ^V <a> <b> <c> <d> <e> <f> - define a window. Window, in
                   Avatar terminology, is an area of the screen with
                   certain attributes (such as color, direction of the
                   flow, wrap behavior, etc.). Every window has a handle,
                   which is a byte between 0-255. That means there are
                   256 windows altogether. Initially, all windows have
                   the same size (full screen) and attributes (color 7,
                   left-to-right direction, wrap on, etc.). This command
                   redefines window <a> to color attribute <b> and
                   location <cdef> on the physical screen. It does not
                   switch to the window, only defines it. However, if that
                   happens to be the default window, changes happen
                   immediately. If this means that the cursor ends up
                   outside of the redefined window, it is moved to the
                   closest position inside. If, on the other hand, the
                   cursor is inside the window after its parameters
                   changed, the cursor remains at the same physical location
                   it was before.

                   The color attribute <b> sets both the default attribute
                   and current attribute. Default attribute can be changed
                   only with this command, while current attribute can be
                   changed with commands, already described above.

                   Window 0 is special in that it covers full screen and
                   has default color attribute of 7. This window cannot
                   be redefined. Any attempt to redefine window 0 will be
                   ignored: Avatar driver will read the command but not
                   act on it.

                   Note that AVT/0 only has one window which covers the full
                   screen and has default attribute of 3. The simplest
                   way to emulate AVT/0 is by defining a full screen window
                   with color attribute 3 and switching to it. Obviously,
                   it has to be a window other than 0.

        ^V ^W <a>  - switch to the window whose handle is <a>. All screen
                   output will be confined to the area of the window in
                   the attributes of the window. Avatar driver remembers
                   all the attributes of every window and restore them
                   each time you switch to a window. This includes color
                   attributes, cursor position, cursor type, direction
                   of the flow, wrap mode, etc.

                   Rapidly switching among windows and writing to them
                   will create the illusion of simultaneous writing to
                   several windows.

                   Unlike the attributes, the *contents* of a window are
                   not preserved when a window switch occurs. That means
                   that overlapping windows overwrite each other. This is
                   why it is important to understand Avatar windows as
                   areas of the screen with certain attributes and nothing
                   else. It is the responsibility of the application
                   to save and restore contents of windows if it wants
                   to have overlapping windows that do not destroy each
                   others contents. The peek and poke commands described
                   below make this possible.

        ^V FS      - put the interpreter to sleep. The parser remains
                   active (the difference between the interpreter and the
                   the parser is described elsewhere in this document),
                   and will still process any queries. Other than that,
                   it will pass all output to the console that existed
                   before Avatar console.

                   This command was added to accommodate systems that
                   need both AVATAR and ANSI consoles. Because there is
                   no provision in ANSI console for any "competition,"
                   Avatar lets you pretend it is not there.

                   In practical life on a PC, if you load ANSI.SYS
                   *before* AVATAR.SYS, you can switch between them
                   by issuing this and the following command.

                   By the way, FS is ASCII 28, or 1C hex.

        ^V GS      - complement of previous command. It will wake Avatar
                   interpreter up. All commands will be processed by
                   Avatar console.

                   GS is ASCII 29, 1D hex.

        ^V RS      - switch current window to vertical mode. In other
                   words, from now on write vertically rather than
                   horizontally. This command was added to accomodate
                   languages such as Japanese that write vertically.
                   (RS is ASCII 30, or 1E hex.)

        ^V US      - switch to horizontal mode. It complements previous
                   command. US is ASCII 31, 1F hex. It is also a country
                   that usually writes horizontally.

        ^V ! <a> <b> <c> <d> - poke character <a> of color attribute <b>
                   at the <cd> location of the *physical* screen. This is
                   a low level command which bypasses the window structure.
                   Or, if you prefer, you can say it always writes to
                   window 0, no matter what the current window is.

                   It does not change anything else: Further processing
                   continues in the same window at the same cursor
                   position as before. If you are a programmer, you can
                   think of it as an "interrupt."

        ^V "       - turn wrap off in current window. In other words, if
                   you come to the window boundary, ignore all output until
                   you get to a carriage return (although a line feed should
                   still work).

        ^V #       - wrap in zigzag mode. Whenever you come to the window
                   boundary, *or* encounter a carriage return, reverse the
                   direction of the flow.

                   In other words, zigzag between left-to-right and
                   right-to-left, or between top-to-bottom and
                   bottom-to-top.

                   This was added because some languages write this
                   way.

        ^V $       - wrap at end of line without switching the direction
                   of the flow. This is the default after a reset.

        ^V %       - reverse LF action. Normally, line feed moves the
                   cursor to next line (or column in vertical mode).
                   This command tells Avatar to move the cursor to
                   previous line (column).

        ^V &       - normalize LF action. It cancels out previous command.
                   LF will cause the cursor to move to next line (column).

        ^V ' <a>   - set cursor type. The value of <a> decides the type:
                        1 - default,
                        2 - hidden,
                        3 - big.

                   In the above, 1, 2 and 3 are binary number, i.e.,
                   you can call them ^A, ^B and ^C if you prefer.

                   Default cursor type is the regular cursor the computer
                   uses most of the time. Hidden cursor is invisible.
                   Big cursor covers the entire character cell.

        ^V (       - do not print in reverse. This is the default. It
                   cancels out next command and cause Avatar to print
                   left-to-right in horizontal mode or top-to-bottom
                   in vertical.

        ^V )       - print in reverse. This is here to accommodate Hebrew
                   and other languages that print right-to-left. In vertical
                   mode it prints bottom-to-top.

        ^V * <a>   - system pause. The length of the pause is defined
                   by <a>. Its value is in tenths of a second. If <a>
                   equals 0, the system will pause for an hour.

                   There is a potential of abuse here. A jokester could
                   transfer a ^V ^Y ^C ^V * ^@ <255> and lock up the
                   system for ten days and 15 hours.Therefore,
                   AVATAR.SYS lets you break out of the pause command
                   by pressing the SysRq key. In case of a loop like the
                   one described above you may need to press the key several
                   times. AVATAR.SYS clears its pause flag both when SysRq
                   is depressed and released.

        ^V +       - insert a blank line at current cursor position.
                   In vertical mode it inserts a column.

        ^V ,       - insert a blank column. In vertical mode it inserts
                   a blank line.

        ^V -       - delete current line. In vertical mode it deletes
                   current column.

        ^V .       - delete current column (line in vertical mode).

        ^V / <a>   - set or reset static mode depending on the value of
                   <a>. If <a> = '[', start (set) static mode. If <a> = ']',
                   end (reset) static mode. Any other version of <a> does
                   nothing.

                   In static mode, cursor is not advanced to the next position
                   after a character has been written. With insert mode OFF,
                   this will mean that every character overwrites the previous
                   character written. With insert mode ON, this will create
                   some interesting special effects.

        ^V 0 <a>   - highlight eol. Current cursor position and the
                   rest of the line will change their color attributes
                   to <a>. Current and default color attributes are
                   unaffected.

        ^V 1 <a>   - highlight bol. Current cursor position and all the
                   characters before it all the way to the beginning
                   of the line are highlighted.

                   The above six commands were designed mostly with
                   full screen editors in mind.

        ^V : <a>   - keyboard mode. By default, the input from Avatar console
                   comes in the form of ASCII codes for whatever character
                   is typed. If a function key is pressed, Avatar console
                   inputs a NUL (ASCII 0) followed by the keyboard scan code.
                   On a non-IBM system this scan code is expected to be the
                   scan code of the comparable key of the IBM PC keyboard.
                   This is known as PC keyboard emulation, and has been
                   documented since AVT/0.

                   OPTIONALLY, it is possible to change this behavior with
                   this command. <a> is a numeral between 0 and 4. By numeral
                   we mean a character '0' rather than binary 0. In other
                   words numerals 0-4 are ASCII codes 30-34 hexadecimal.

                   This command clears the keyboard buffers (both the system
                   buffer and the Avatar driver internal buffer). If
                   applicable, it changes the input behavior. It then returns
                   itself with the new value of input behavior. Behavior 0
                   is the default and must be supported by any Avatar driver
                   to be compatible. The rest of them are optional.

                   If an invalid or unsupported <a> is used in this command,
                   Avatar console clears the buffers, then returns this command
                   with the current behavior.

                   As this command is more complex than most others, it is
                   described below in more detail.

        ^V < <a> <b> <c> <d> <e> - scroll area left. Works just like
                   ^V ^J but left.

        ^V = <a>   - set parser mode. If <a> equals 'R', the mode is set
                   to raw. If it equals 'C', the mode is set to cooked.

                   Avatar console ands <a> with 1Fh before evaluating it.
                   Then it compares it ^R and ^C. That means the value can
                   be 'R', 'r', ^R, 'C', 'c', ^C, and even some others
                   that result in ^R or ^C with their hight bits turned off.

        ^V > <a> <b> <c> <d> <e> - scroll area right. Same as ^V ^J but
                   scrolls right.

        ^V ? <a> <b> - peek at the physical location <ab> on the screen.
                   It returns appropriate poke command in reply buffer.
                   In other words, it writes a poke into stdout. Similar to
                   poke, it bypasses the window structure and works on
                   the physical screen.

                   The peek and poke commands allow for limited pop-up
                   windows sent over serial lines. The program simply
                   peeks at every screen position it wants to overwrite,
                   and pokes the new value in it. It stores the result
                   of the peeks in a buffer. When it wants to restore
                   the original window, it simply sends the buffer out.

                   Granted, this will work slow in a large window at
                   300 baud, but it is pretty much the only way to do it.

                   For *local* console only, commercial version of
                   AVATAR.SYS contains functionality to achieve the
                   same result instantly, bypassing Avatar codes. But
                   that cannot work remotely.

                   Avatar protocole (not console) will have provisions
                   for achieving the same result more efficiently. But
                   that requires the collaboration of the terminal
                   program. It cannot be achieved by the console driver
                   alone without reserving megabytes of memory for its
                   use.   :-)

        The two steps of Avatar console processing

20. Avatar console works in two steps:

                   1. parsing
                   2. interpreting

21. As a matter of fact, just about every console uses these two steps,
although they may not necessarily talk about it. Because of these two steps,
Avatar console driver consists of two distinct sections:

                   1. the parser, and
                   2. the interpreter

22. Again, this is nothing new to the student of computer science, although it
may be new, even confusing, to the casual computer user.

23. When a character is sent to Avatar console for output through stdout, it
first goes to the parser. Depending on the current setup defined by the parser
control codes as well as some other circumstances, the parser will or will not
modify the character before sending it out.

24. Secondly, depending on the current setup, the parser will send the
character out to the interpreter, or it will send it out to the parser of
another console such as ANSI or TTY.

25. That said, let us discuss the first idea, that of changing or not changing
the character. To my great surprise there seems to have been some confusion
about how AVT/0 parser was supposed to be behaving at this point. To see why,
let's get into some historical perspective:

                   Avatar console was not developed from scratch. Rather,
                   it descended from a creature of Wynn Wagner, III, called
                   oANSI. Wynn, the original author of Opus-CBCS, wanted to
                   simplify screen handling as far as the Opus sysop was
                   concerned. At that time, ANSI escape sequences were just
                   about the only way of controlling the remote screen.

                   Wynn developed a system of codes which were much shorter
                   than ANSI. These are the same codes used in the original
                   AVT/0 spec. They were designed specifically for Opus, which
                   explains some of the quirks of AVT/0 (such as default
                   color attribute of 3 rather than 7). Opus is able to read
                   a file containing these sequences and convert them to the
                   appropriate ANSI sequences.

                   At the time Opus first came out, however, oANSI codes were
                   just pure binary codes. If you wanted to use them, you had
                   to type them in by hand using your favorite editor.
                   Because oANSI can contain any control code imaginable,
                   and because different text editors are using different
                   control codes as their own editing commands, there was a
                   need to bypass the limitation.

                   The solution was simple and elegant: Whenever Opus reads
                   a DLE (ASCII 16, or 10 hex, or ^P), it reads in one more
                   byte, strips off its high bits and converts it into a
                   control code. In other words, Opus treats the file it
                   reads as a "cooked" one.

                   Avatar, level 0 (AVT/0 and AVT/0+), does not use cooked
                   mode. There seemed to be no need for it at the time. The
                   reason why AVT/0 was designed was to speed up screen
                   control. Using DLE escaping seemed a waste of time. Opus
                   1.10 (and later) treats oANSI files as cooked, but converts
                   their contents into raw mode before sending them out.

                   Thus for example, if an oANSI file contains a DLE followed
                   by the letter 'V', Opus 1.10 will send out a ^V. There is
                   positively no mention of DLE escaping in any AVT/0
                   documentation, as it is not used there.

                   Yet, it came to my attention that some programmers assumed
                   DLE escaping should be used in AVT/0. This is a *wrong*
                   assumption, not based on Avatar docs.

26. Now, back to the present. Meanwhile it became obvious that DLE escaping
might be useful. Because it does not use cooked mode, AVT/0 only works with an
ideal data communications link, i.e. a link that modifies nothing.
Unfortunately, that is not always the case.

27. Let's examine some possible distortions:

                   The XON, XOFF protocol is a common way of dealing with
                   buffer overrun. I do not want to go to any details about
                   it here, because those who are familiar with the
                   technicalities of this protocol would get bored, while
                   those who are not either could not care less, or might
                   need an explanation deeper than space permits.

                   At any rate, whenever this protocol is used, ^Q and ^S
                   are sent out to stop and restart the flow. The two
                   codes are eaten by the protocol and never get through.
                   It so happens that Opus is not using this protocol when
                   it is sending data to the caller's screen. But an
                   inexperienced caller may have *his* terminal software
                   configured for the XON, XOFF protocol. In that case any
                   Avatar code that contains either ^Q or ^S will be
                   distorted.

                   In AVT/0 chances of using ^Q and ^S are close to zero.
                   The only place they could appear would be as a color
                   attribute, but they do not represent a commonly used
                   color.

                   In AVT/1, ^V ^Q is the query code, ^Q ^S is the sound code.
                   The possibility of the XON, XOFF protocol getting in the
                   way is stronger.

                   PC Pursuit of Telenet uses some control codes as its own
                   escape code. Anyone who tried to upload a large file to
                   a remote BBS over PC Pursuit using SEAlink got bitten by
                   Telenet escape codes.

                   It is unlikely the Telenet escape codes of CR @ CR would
                   happen in Avatar, but it is possible (e.g. in the
                   parameters of the define window command).

28. Other problems may occur locally, at terminal end:

                   MS DOS exapnds the TAB character into a number of blank
                   spaces before it sends it to the console. TAB is the same
                   as ^I which can be a color attribute. Moreover, ^V ^I is
                   Avatar code to turn insert mode on. Thus, sending a ^I
                   to the screen using standard MS DOS calls (which is
                   what most programs running under MS DOS do) will result
                   in something we did not want.

                   C language uses NUL as "end of string" marker. But NUL
                   can be a window number in Avatar. A C program containing
                   NUL in the middle of a string will not send the whole
                   string, and it will never send the NUL.

                   A commonly used C function printf() expands a line feed
                   to a carriage return followed by a line feed, at least it
                   does it in the world of PC's.

29. Because of all these possible problems, Avatar parser works, by default,
in the cooked mode. That means when it reads a DLE, it waits for the next
character. When the character comes, the parser strips the high bits and sends
the result to the interpreter. Notice I said high bits, not high bit. So,
if we call the character c, this is what it does:

                   c = c and 1F

Here, 1F is a hexadecimal number.

30. Also note that Avatar parser does not pass the DLE to the intepreter. Of
course, if there are two DLE's in a row, the second one will get through
because DLE and DLE equals DLE.

31. For compatibility with AVT/0, there is a code to turn Avatar parser to raw
mode (see ^V = above). If you instruct Avatar parser to function in raw mode,
it will not consider DLE an escape character, but will pass it onto the
interpreter. The interpreter itself knows nothing about escaping. It
interprets the codes exactly as they are defined. As you know, the interpreter
is a separate part of Avatar console. It blindly interprets whatever codes
get to it.

32. Cooked mode is the default. That means when Avatar console first starts, it
is in cooked mode. Whenever it is reset, it goes to cooked mode. As cooked
and raw modes are functions of the parser, rather than interpreter, the same
mode is always in all Avatar windows. The parser knows nothing about the
windows, the interpreter does. But the interpreter knows nothing about raw
and cooked modes, the parser does.

33. Here is some sample code of this section of the parser. Here we assume a
variable parsermode which can either equal RAW or COOKED:

        void parser (char c) {    /* c = character received */

                static char lastchar = '\0';

                if (parsermode == COOKED) {

                        if (lastchar == DLE) {
                                c &= 0x1f;
                                lastchar = '\0';
                        }
                        else if (c == DLE) {
                                lastchar = DLE;
                                return;         /* Note this !!! */
                        }
                }

                interpret(c);
        }

34. If you are not quite home in C, I'd like to tell you that a static
variable keeps its value inbetween calls to this function. Its initial
value is '\0' (NUL), but when it is changed to DLE, it remains DLE until
it is explicitly changed.

35. Now to the idea of the parser sending its output to the interpreter or
somewhere else. While we think there is no need to use ANSI codes once
Avatar has become established, we still have to deal with older software
using ANSI sequences.

36. Avatar console does not understand ANSI codes, with the only exception
being <esc>[2J - clear the screen. Whenever Avatar console detects this
sequence, it will clear current window.

37. To accommodate software unsing ANSI codes, Avatar console is willing to
send its interpreter to bed. The ^V FS code tells the interpreter to go to
sleep. Whenever the parser sees the interpreter is asleep, it passes all
output on to whatever console existed before Avatar.

38. In practical life: If, on a PC, ANSI.SYS is loaded *before* AVATAR.SYS,
ANSI will be in control when Avatar interpreter is asleep.

39. You can awaken the interpreter by sending ^V GS to Avatar console. Note
that Avatar is not responsible for another console to exist, let alone for it
to be ANSI. But in real life, at least in PC world, there always exists a
console. MS DOS creates a very primitive TTY console which still exists
even if another console driver (even several drivers) is loaded.

40. Outside of MS DOS world, creators of Avatar console drivers should make
sure that there either is a default console or they should write one.
