[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]