[Back to COMM SWAG index] [Back to Main SWAG index] [Original]
w{
SEAN PALMER
Using the state-driven approach, I came up With this simplistic
Avatar/0 interpreter as an example. Do With it as you wish...
by Sean L. Palmer
Public Domain
}
Program avtWrite;
{ example to do avatar/0 (FSC-0025) interpretation }
{ could easily be extended to handle /0+ and /1 codes }
Uses
  Crt;
{ this part of the Program controls the state-driven part of the display
  handler. }
Var
  saveAdr : Pointer;  { where state handler is now }
  c       : Char;     { Char accessed by state handler }
  b       : Byte Absolute c;
Procedure avtWriteCh(c2 : Char); Inline(
  $8F/$06/>C/            { pop Byte ptr [>c] }
  $FF/$1E/>SAVEADR);     { call dWord ptr [>saveAdr] }
                         { continue where handler l
                           call this Procedure from StateHandler to
                           suspend execution Until next time
}
Procedure wait; near; Assembler;
Asm                             { wait For next Char }
  pop Word ptr saveAdr          { save where to continue next time }
  retF                          { simulate Exit from calling proc }
end;
{
 a stateHandler Procedure should never ever Exit (only by calling 'wait'),
 shouldn't have any local Variables or parameters, and shouldn't call
 'wait' With anything on the stack (like from a subroutine).
 This routine is using the caller's stack, so be careful
}
Var
  avc : Char;
  avb : Byte Absolute avc;
Procedure stateHandler;
begin
  Repeat
    Case c of
      ^L :
        begin
          ClrScr;
          Textattr := 3;
        end;
      ^Y :
        begin
          wait;
          avc := c;
          wait;
          While c <> #0 do
          begin
            dec(c);
            Write(avc);
          end;
        end;
      ^V :
        begin
          wait;
          Case c of
            ^A :
              begin
                wait;
                Textattr := Byte(c);
              end;
            ^B : Textattr := Textattr or $80;
            ^C : if whereY > 1  then GotoXY(whereX, whereY - 1);
            ^D : if whereY < 25 then GotoXY(whereX, whereY + 1);
            ^E : if whereX > 1  then GotoXY(whereX - 1,whereY);
            ^F : if whereX < 80 then GotoXY(whereX + 1,whereY);
            ^G : clreol;
            ^H :
              begin
                wait;
                avb := b;
                wait;
                GotoXY(b + 1, avb + 1);
              end;
            else
              Write(^V, c);
          end;
        end;
      else
        Write(c);
   end;
   wait;
   Until False;
end;
Var
  i : Integer;
Const
  s : String = 'Oh my'^V^D^V^D^V^F^V^A#1'it works'^V^A#4',see?';
begin  {could do something like attach it to Output's InOutFunc...}
  saveAdr := ptr(seg(stateHandler), ofs(stateHandler) + 3); {skip header}
  For i := 1 to length(s) do
    avtWriteCh(s[i]);
end.
[Back to COMM SWAG index] [Back to Main SWAG index] [Original]