                                                                                        Historical Overview                                                                                                                                                                                                                                                                       Wynn Wagner III,  the  author  of  Opus-CBCS,  developed a method          of storing video control codes in a file sent to the Opus caller which          was meant  as a replacement of ANSI escape codes.  Its main advantages          were:                                                                                                                                                                    The codes are smaller than ANSI, thus needing less disk                         storage space.                                                                                                                                                 The codes are in the binary form easily interpreted by the                      computer (ANSI sequences use ASCII).                                                                                                                           The same file can be sent to callers who do or do not have                      the ability of interpreting ANSI codes - in the former case                     the codes are first translated to ANSI, in the latter they                      are ignored.                                                                                                                                               Because of lack of an appropriate  name,  Wynn  temporarily named          the codes oANSI with the understanding that a better name was needed.                                                                                                When George Stanislav  started  working  on  a  TinyTerm communi-          cations program,  he  had the idea  that  if  Opus-CBCS could send the          "oANSI"  codes directly over the  phone  lines,  it would speed up the          communications considerably.  A typical ANSI sequence contains 4 times          as many bytes as the codes developed by Wynn Wagner.                                                                                                                 That phone call to Wynn resulted in two things:                                                                                                                     TinyTerm can interpret the "oANSI" codes and translate                          them to ANSI, then send them to stdout where they are                           converted to colors by ANSI.SYS.                                                                                                                               Opus-CBCS, starting with gamma version 1.10.iii, will                           send the codes without converting them to ANSI sequences.                       (It will still send ANSI codes to users without the proper                      terminal software.)                                                                                                                                        He took over the coding  of  the  part of Opus handling the video          codes.  He realized the codes  were  offering  us much more power than          just translating them to  ANSI  escape  sequences.  George proposed to          call the codes AVATAR, the Advanced Video Attribute Terminal Assembler          and Recreator.  Wynn readily accepted the new name.                                                                                                                                                                                                                                                                                                                                                         The Two Levels of Avatar                                                                                                                                                                                                                                                                                                                                                 Avatar is more than a video  attribute  controller.  It is a pro-          tocol which,  if need be,  can totally  eliminate the  interference of          line  noise.   However,  this  document  is  not  concerned  with  the          advanced  topics  of  Avatar  (which  no  BBS ware is using as of this          writing).                                                                                                                                                            A full Avatar session with  all  its  advanced features starts by          exchanging the AVINIT  packets.  The  caller  sends a packet which de-          scribes the video capabilities  of  his/her  system.  It also contains          the caller's name,  password  and  some  other  optional  information.          It also tells the  BBS  if  the  user  is  calling  in  person or just          emulating  a BBS session with an Avatar terminal program.                                                                                                            The called system  (the BBS)  replies to the AVINIT packet with a          packet that informs the user of his current status, i.e. you  can stay          until 16:30 PST,  or you are denied access,  or  I  am processing mail          now but you can call back at 10:43 PST, etc.                                                                                                                         Until such AVINIT packets are exchanged, only the Avatar commands          that were part of the original oANSI codes can be sent from the BBS to          to the  caller.  The  caller's  term  program  should  send  no Avatar          commands,  with the exception of function key codes, before the AVINIT          packets are exchanged.  This assures that a BBS program which does not          support full Avatar can still take advantage of the faster transfer of          video codes using Avatar as opposed to ANSI escape sequences.  It also          permits the caller whose term program does not support full Avatar but          can interpret the basic codes to  take advantage of the term program's          abilities.                                                                                                                                                           The two levels of Avatar  then  are:  a  full session and a basic          session.  This document is  concerned  with  the  BASIC Avatar session          only.  The full session will be defined in the future.                                                                                                                                                                                                                                                                                                                                                           Basic Avatar Commands                                                                                                                                                                                                                                                                     Before the AVINIT  packets  are  exchanged,  the BBS can send the          basic Avatar commands if so permitted  by the user's choice, typically          recorded  in  the  user  datafile  (ie. USER.BBS).  Because  Avatar is          window oriented,  in a basic session  the  full  screen is  considered          the default  window.  Further,  the  default  color of  the  window is          assumed  to  be  3  (cyan text on a black background).  All  bytes are          taken at their face  value  without  escaping.  However,  save for one          exception  described below,  no basic Avatar code will have  the  high          bit set.  Therefore, the term program should reset the high bit of all          bytes except as described below.                                                                                                                              The basic commands are:                                                                                                                                              <^L>        -   clear the current window and set current attribute                              to default. In the basic session this means:                                    Clear the screen and set its attribute to 3.                                                                                                    <^Y>        -   Read two bytes from the modem. Send the first one                               to the screen as many times as the binary value                                 of the second one. This is the exception where                                  the two bytes may have their high bit set. Do                                   not reset it here!                                                                                                                              <^V> <^A> <attr> - Set the color attribute to <attr>. The default                               attribute remains unchanged. However, all text                                  will be displayed in <attr> until the next ^V^A,                                ^V^B, or ^L.                                                                                                                                    <^V> <^B>   -   Turn the high bit of current attribute on. In                                   other words, turn blink on.                                                                                                                     <^V> <^C>   -   Move the cursor one line up. Do nothing, if you                                 already are at the top line of the current                                      window.                                                                                                                                         <^V> <^D>   -   Move the cursor one line down. Do nothing if you                                already are at the bottom line of the current                                   window.                                                                                                                                         <^V> <^E>   -   Move the cursor one column to the left. Do nothing                              if you already are at the leftmost column of the                                current window.                                                                                                                                 <^V> <^F>   -   Move the cursor one column to the right. Do nothing                             if you already are at the rightmost column of the                               current window.                                                                                                                                 <^V> <^G>   -   Clear the rest of the line in the current window                                using the current attribute (not to be confused                                 with the default attribute).                                                                                                                    <^V> <^H> <row> <col>   -   Move the cursor to the <row> <col>                                  position within the current window.                                                                                                                                                                                        Comments:                                                                                                                                                              Current attribute and default  attribute  are not necessarily the          same.  Whenever the window is cleared by the <^L> command, the current          attribute is made  equal  to  the  default  attribute.  There  is also          another command to make the  current  attribute  equal  to the default          attribute.  However,  this command is not a part  of  the basic Avatar          command set and therefore cannot be used before the AVINIT packets are          exchanged.                                                                                                                                                           Whatever characters  are  sent  to  the  screen,  they  should be          displayed using the CURRENT attribute.  There is an exception to this,          but only after the AVINIT packets have been exchanged.                                                                                                               The attribute byte is an  eight-bit  value.  As  basic Avatar can          only transfer 7-bit commands,  the high bit of the attribute  byte can          be set only by the <^V> <^B> command. The <attr> byte of the <^V> <^A>          <attr> command should  be  AND-ed  with  7F (hexadecimal).  The colors          set by the attribute byte are  the  same as are the colors of the text          mode of an IBM color graphics adapter.                                                                                                                           That means the bits of the attribute byte have the following meaning:                                                                                            bit:         7   6   5   4   3   2   1   0                                                   -   -   -   -   -   -   -   -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          text color                                                                                                                                                                                                                     background color                                                                                                                                                                                                                        blink                                                                                                                                               If the blink bit  is  set,  the  text  is  blinking,  else  it is not          blinking.                                                                                                                                                            The bits of background color  can  have values 0 - 7, the bits of          the text  color  can  have  values  0 - 15.  The  value  indicates the          following colors:                                                                                                                                                             0      black                                                                    1      blue                                                                     2      green                                                                    3      cyan                                                                     4      red                                                                      5      magenta                                                                  6      brown                                                                    7      gray  (i.e. non-itense white)                                            8      dark gray                                                                9      light blue                                                              10      light green                                                             11      light cyan                                                              12      light red                                                               13      light magenta                                                           14      yellow                                                                  15      white (intense)                                                                                                                             Colors 8 - 15 are the same as 0 - 7 but with high intensity.                                                                                                        Please note that these values are different from the numbers used          by ANSI escape codes,  if  you  are  familiar  with  TheDraw or BASIC,          these are the same numbers used by the two programs.                                                                                                                                                                                                                                                                                                                                                                                                                                          The Function Key Codes                                                                                                                                                                                                                                                                     An Avatar capable BBS can  accept  function  keys from the remote          caller.  This  feature is optional  (for the term program)  but highly          recommended.                                                                                                                                                         On an IBM (compatible) computer  this means that if a caller hits          a function key  (ie., left arrow,  page up,  F7, insert, alt-H, etc.),          the term program should send two  bytes  to the Avatar capable BBS:  A          binary zero followed by the keyboard scancode.  Please  note that con-          trol keys (^A, ^B, etc.)  are  not  function  keys  but  have an ASCII          value which is the only byte that should be transfered.                                                                                                              There are two keys on  the  IBM  keyboard  that  do have an ASCII          value but also  offer a separate  scan  code.  These are the gray-plus          and the gray-minus.  If  one  of  these  keys  is  hit,  treat it as a          function  key - send  the  binary  zero  followed  by  the  scan code.          This way if the BBS treats  them  differently  from a regular plus and          minus keys,  the caller can take  advantage of the keys.  On the other          hand,  BBS writers who do not want  to  assign the gray keys a special          value, should watch for their codes  and  treat them as a regular plus          and minus.                                                                                                                                                           Systems that use a  different  keyboard  layout  (and scan codes)          than IBM can emulate IBM by  declaring  which  keys are considered the          arrows, f-keys, etc.  If you  have  the arrow keys,  for example,  but          their scan codes are different,  still  send  the binary zero and  the          scan code that an IBM keyboard  would  assign  to that particular key.          This should be transparent to the user.                                                                                                                              There is an obvious problem  here.  All  terminal programs I have          seen use function keys internally.  A switch is needed so the user can          decide whether a function key  is  meant  for  the internal use of the          term program or it should be  transfered to the BBS.  Most but not all          IBM clones have a scroll lock key,  some even have an LED indicator on          it.  The IBM programs could use that as a switch to know what the user          means by hitting a function key.  Since some compatibles do not have a          scroll lock key (ie. Tandy 1000),  the Avatar capable BBS should never          expect the <shift> <F1> combination  to  be  transfered.  That way the          term program can  use  <shift> <F1>  to  switch  between the local and          remote use of function keys if the scroll lock key is not available.                                                                                                                                                                                                                                                                                                                                                             Conclusion                                                                                                                                                                                                                                                                                      This should about summarize  the basic Avatar commands.  Portions          of this documentation was written  by  George Stanislav before leaving          summer vacation  realizing  that  it  would  be  nice to give software          developers of both BBS software and  Communication  programs something          before releasing the specs of the full Avatar implementation.                                                                                                        Here is also  some  sample C code.  It assumes you  have some low          communications functions of  your own.  For the screen  output it uses          Turbo C library, but you can use anything you want.                                                                                                                                                                                          #include <conio.h>                                                                                                                                              int def_attr = 3;                                                               int cur_attr = 3;                                                               int lastline = 25;                                                              int lastrow  = 80;                                                                                                                                              /* WARNING: This code has not been tested. */                                   /* It is just meant as an example.         */                                                                                                                   void pascal avatar()                                                            {                                                                                int c,i,j;                                                                                                                                                      switch (mgetchar())            /* Read a char from the modem */                  {                                                                                  case 12 :       textattr(cur_attr = def_attr);  /* ^L */                                        clrscr();                                                                       break;                                                                                                                                          case 25 :       c = mgetchar();                 /* ^Y */                                        j = mgetchar();                                                                 for (i = 0; i < j; i++)                                                                 cprintf("%c",c);        /* print in color */                            break;                                                                                                                                          case 22 :       switch(mgetchar())              /* ^V */                                        {                                                                                case 1 : cur_attr = mgetchar() & 0x7f;                                                   textattr(cur_attr);                                                             break;                                                                                                                                                 case 2 : cur_attr = 0x80;                                                               textattr(cur_attr);                                                             break;                                                                                                                                                 case 3 : if ((i = wherey()) > 1)                                                               gotoxy(wherex(),i - 1);                                                   break;                                                                                                                                                 case 4 : if ((i = wherey()) < lastline)                                                        gotoxy(wherex(), i + 1);                                                  break;                                                                                                                                                 case 5 : if ((i = wherex()) > 1)                                                               gotoxy(i - 1,wherey());                                                   break;                                                                                                                                                 case 6 : if ((i = wherex()) < lastrow)                                                         gotoxy(i + 1,wherey());                                                   break;                                                                                                                                                 case 7 : cleol();                                                                        break;                                                                                                                                                 case 8 : i = mgetchar();                                                                 gotoxy(mgetchar(),i);                                                 }                                                            }                                                                             }                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   Definitions                                                                                                                                                                                                                                                                            Avatar, level 0 - The Avatar protocol as presented at Fidocon '88 and                   described in AVATAR0.C, dated 23 August 1989, plus extensions                   defined in this document.                                                                                                                               AVT/0   -  An abbreviation for Avatar, level 0,  suggested by Joaquim                   Homrighausen.                                                                                                                                           Current attribute - Video attribute defined by the last  ^V^A,  ^V^L,                   ^V^M or ^L AVT/0 command whichever happened last.  In  AVT/0,                   ^L sets the value of current attribute to 3,  ^V^L,  ^V^M and                   ^V^A to an explicit value.  In addition, ^V^B turns blink on.                                                                                                                                                                                                                                                                                                                                                       Extending AVT/0                                                                                                                                                                                                                                                                              It had become  clear  some  of  the  Avatar  commands  originally          reserved for AVT/1 would be very  useful  in AVT/0.  George  Stanislav          was hesitant to  add  them  for one  simple  reason:  Any  addition on          level 0 would break all  existing  Avatar  emulating software.  At the          time these  modifications  were  made,  there  were  only  three known          programs that had implemented  Avatar  emulation.  Those programs were          Stanislav's own Tiny Term,  Joaquim Homrighasen's Frontdoor, and Jason          Galanter's Jterm.                                                                                                                                                    Stanislav was assured by  Joaquim  and  Jason that they would put          the new commands in  their  programs,  thus  nothing  would be broken.          With that assurance in mind,  he  felt confident no chaos would result          from adding these new commands.                                                                                                                                                                                                                                                                                                                                                                      New Commands (brief definitions)                                                                                                                                                                                                                                        <^V><^I>  -  Turn insert mode ON.  It stays on until any other AVT/0                         command except <^Y>  and  <^V><^Y> is encountered after                         which it is turned off;                                                                                                                            <^V><^J><numlines><upper><left><lower><right>  -  scroll area up;                                                                                               <^V><^K><numlines><upper><left><lower><right>  -  scroll area down;                                                                                                            <^V><^L><attr><lines><columns>  -  clear area, set                                                                 attribute;                                                                                                             <^V><^M><attr><char><lines><columns>  -  initialize area,                                                                set attribute;                                                                                                                                     <^V><^N>  -  delete character,                                                               scroll rest of                                                                  line left;                                                                                                             <^V><^Y><numchars><char>[...]<count>  -  repeat pattern.                                                                                                                                                                                                                                                                                                                                                    Detailed Description                                                                                                                                                                                                                                                                Insert mode: Insert mode controls the way characters are printed on the                 screen. Insert mode is always assumed OFF unless explicitly set                 ON by the ^V^I command after  which  it  stays on until another                 AVT/0 command except for  ^Y or  ^V^Y  is encountered.  Then it                 reverses back to off.                                                                                                                                           Whenever insert mode  is  OFF,  characters  are  printed on the                 screen like this:                                                                                                                                               1. Print  character at  current cursor position  using  current                    attribute, overwriting whatever  was previously displayed at                    current cursor position;                                                                                                                                     2. Move cursor to next position,  usually  one character to the                    right.  At  end of the line,  move  the cursor to next  line                    (possibly scrolling  the  display  or  current  window if in                    AVT/1).                                                                                                                                                      Whenever insert  mode  is  ON,  characters  are  printed on the                 screen as follows:                                                                                                                                              1. Starting at current cursor position and going all the way to                    the second last  character on current line,  scroll the text                    one character to the right;                                                                                                                                  2. Discard the character previously  at the end of the line, do                    NO move it at the beginning of the next line;                                                                                                                3. Print character  at  current  cursor position  using current                    attribute;                                                                                                                                                   4. Move cursor  to  next  position,  precisely  as in par. 2 of                    insert mode off.                                                                                                                                            If ^Y or ^V^Y are encountered, the string of characters they com-          press is first expanded,  then treated as  an ordinary stream of char-          acters printed according to the above rules.                                                                                                                         Any other AVT/0 command turns insert  mode back off.  Please note          that in either case the cursor is  moved  to  its  next position in an          identical  manner.  The mere fact  the  cursor  is moved to next line,          or even scrolls the screen a line up,  does  NOT turn insert mode off.          Only an AVT/0 except as mentioned  above  can change insert mode on or          off.                                                                                                                                                                 If control  characters are  a  part of the text stream,  they are          interpreted indentically in insert mode on and off as follows:                                                                                                      Carriage return  -  move cursor at the beginning of the same line;                                                                                              Line feed        -  move cursor one  line  down  (scroll screen or                                  window [in AVT/1] if necessary), do not change                                  cursor column;                                                                                                                              Back space       -  move cursor one  position to the left.  Do NOT                                  overwrite  the  character  at  that  position.                                  Do  nothing  if   already   at   the  leftmost                                  position;                                                                                                                                   Tab              -  move cursor to next tab position without over-                                  writing  anything.  Tab  positions  are  mult-                                  iples of  8.  Do  nothing  if  already at  the                                  rightmost position.                                                                                                                   A space is treated as a character, not as a control character.                                                                                                                                                                                  Scrolling an area (^V^J and ^V^K): The area defined by its upper, left,                 lower and  right  coordinates  is  scrolled  up  <^V^J) or down                 (^V^K) by <numlines> lines  filling  the  gap with blank spaces                 using current attribute.  If the value of <numlines> is zero or                 exceeds the actual  number of  lines within  the scrolled area,                 the area is filled with blanks using current attribute.                                                                                                         These two commands do  NOT  change  the position of the cursor,                 nor do they define the  scrolled  area  as  the default window.                                                                                                 The coordinates are relative  to  the  upper left corner of the                 screen (or current window in AVT/1).  The  coordinates of upper                 left corner are 1,1.  If a coordinate  contains  0, it is to be                 changed to 1.                                                                                                                                           Initializing an area (^V^M): This command contains several steps:                                                                                                      1. Set current attribute to <attr>;                                                                                                                             2. Starting at current  cursor  position  (inclusively), ending                    at  current  cursor  position  plus  number  of <lines>  and                    <columns>,  print <char> at all position inside the  defined                    area.  Do not move the  cursor.  If the number of columns or                    lines exceeds whatever  is  available to the right and below                    current cursor  position,  truncate  the  dimensions  to fit                    within  the  limits  of  the  screen  (or  current window in                    AVT/1).                                                                                                                                               Clearing an area (^V^L): This  is  a  shortcut   version  of  the  ^V^M                 command.  The character  to  be used  to initialize the area of                 the screen is assumed to be a blank space.  In other words,  it                 sets current attribute and clears  an area of the screen start-                 ing at current cursor position (which remains unchanged).                                                                                                      Please note that the  usual  7-bit  restriction  applies to ^V^L.          That means that the attribute byte should  be anded with 7f hex before          applying.  If blinking is desired,  ^V^B  should be used next.                                                                                                       On the other  hand,  requiring  to  ignore  the  high bit in ^V^M          would make it impossible  to  fill  the  area  of  the  screen  with a          blinking  pattern.  Therefore,  if  bit  7  of  attr  is  set in ^V^M,          current attribute is set to <attr> AND 7f hex  and  blink is turned on          before filling the area with a character.                                                                                                                     Deleting a character (^V^N): Starting  at  the  column one character to                 the right of current cursor  position all the way to end of the                 line, scroll the text one character position to the left.  This                 effectively deletes the character  at  current cursor position.                 Print a blank space using  current  attribute  at the rightmost                 end of the line to fill the gap.  Do  not change current cursor                 position.  If the cursor  is  at  the  end of  the line, simply                 overwrite the last character with  a  blank space using current                 attribute.                                                                                                                                              Repeat pattern: This is an extension  of  the ^Y command which allows a                 group of characters to form a repetititious pattern. <numchars>                 determines the number of characters in the pattern, <count> the                 number of times the pattern is  to be printed out.  The pattern                 may contain AVT/0 codes.                                                                                                                                For example, <^V><^Y><#3>ABC<#4> expands to "ABCABCABCABC".                                                                                                                                                                                                                                                                        Scrolling Philosophy                                                                                                                                                                                                                                                                        An important philosophical  question  has  not been answered yet:          When scrolling the contents of an area (in the scrolling commands ^V^J          and ^V^J, in insert mode ON and  in  deleting  characters ^V^N) should          only the text be scrolled and  the  attribute  of  the  scrolled areas          remain where they are or should the attributes move as well.                                                                                                         A case can  be made  for  either  approach.  Obviously,  the gaps          created by scrolling are filled with current attribute,  therefore, it          seems more  logical  to  scroll  the  attributes  along  with the text          (else there  would be  no  need to  fill  the  gaps).  Thus we  follow          a  consistent principle of video  attributes  belonging to a character          (be it a blank,  a digit,  or  a true character),  not  to a location.          Whenever a character is scrolled to a different location, it takes its          attribute along.                                                                                                                                             