Stuffing the keyboard, a draft for the forthcoming FAQ update

Quote
>Subject: Stuffing the keyboard, a draft for the forthcoming FAQ update
>From: t...@majakka.uwasa.fi (Timo Salmi)
>Date: Wed, Nov 5, 1997 14:27 EST
>Message-id: <63qha7$...@majakka.uwasa.fi>

>120. *****
> Q: How can I stuff keystrokes in advance into the keyboard buffer?

> A: This question was actually presented in a more complicated
>format in news:comp.lang.pascal.borland. A user asked how he can
>call another program from within a Turbo Pascal program and send
>keystrokes to the program being called. This item takes on the
>entire question in the demonstration code given below.

>  {$M 2048, 0, 0}   (* <-- Important *)
>  uses Dos;

>  (* Slightly adjusted from an old message by Trevor Carlsen
>     The comments with the "{-" in the routine are his *)
>  function InsertKey (ch : char) : boolean;
>  {-Insert a key into the keyboard buffer. Key must be passed
>    with the MSB being the scan code of the key you want inserted
>    and the LSB being the ascii code. For keys that return an
>    extended code (cursor keys function keys etc.) the LSB must be
>    zero and the MSB the scan code. Returns true if successful. }
>  const
>    BufferStart     = $1E;       {-Address of the keyboard buffer  }
>    BufferEnd       = $3C;
>  var
>    head : word absolute $0040:$001A;
>    tail : word absolute $0040:$001C;
>    OldTail         : word;
>  begin
>    InsertKey       := true;
>    MemW[$0040:tail]:= ord(ch);  {-Insert the keypress             }
>    OldTail         := tail;     {-Keep record of tail position in }
>                                 {-case the key buffer was full    }
>    if tail = BufferEnd then     {-wrap around to Start of buffer  }
>      tail := BufferStart
>    else
>      inc(tail, 2);              {-To allow for newly inserted key }
>    if tail = head then begin    {-No room for inserting the key so}
>      tail := OldTail;           {-restore the status quo          }
>      InsertKey   := false;
>    end; {-if tail = head}
>  end; {-InsertKey}

>  procedure TEST;
>  var s : string;  (* The string to be stuffed into the buffer *)
>      i : byte;
>  begin
>    s := 'Timo Salmi'+#13;  (* The buffer can hold only 16 characters *)
>    for i := 1 to Length(s) do
>      if not InsertKey(s[i]) then Break;
>    write ('Calling the sufftst program from within Turbo Pascal');
>    SwapVectors;
>    Exec (GetEnv('comspec'), '/c stufftst');  (* Execution *)
>    SwapVectors;
>    if DosError <> 0 then
>      writeln ('Dos error number ', DosError)
>    else
>      writeln ('Back in the original program. ',
>               'Mission accomplished, exit code ', DosExitCode);
>  end;  (* test *)

>  begin
>    TEST;
>  end.

>  (* The contents of the STUFFTST.PAS program.
>     Compile it first for the demonstration.
>  var st : string;
>  begin
>    writeln; writeln ('This is STUFFTST.EXE program running now!');
>    write ('? '); readln (st);
>    writeln ('Your input was = ' ,st);
>  end.
>  *)
>--------------------------------------------------------------------

>   All the best, Timo

I usually prefer the int 16h func 05h approach, since if a TSR chooses to
 expand the type-ahead buffer, the int approach would probably still work,
 whereas the direct approach probably wouldn't.  Besides, the int approach is
 easier to program.  On the other hand, this function is not available in
 earlier machines (pre-PC/AT machines), but that probably won't be a problem today.