[comp.lang.pascal] Desqview annoyance, help requested

acaldwel@oucsace.cs.ohiou.edu (Adam Caldwell) (05/01/91)

I am having a problem running desqview with a program that I have written...
It is more of an annoyance than anything else, but, here's the story.

I wrote a Full Screen editor to run under WWIV BBS V4.12 (binaries available
upon request), and I wanted to add a two-way chat mode to it.  The problem
is that WWIV requires that all of the I/O of a program be done through
DOS (which means that you can't have any asynchronous communications routines
in your program).  This means that, there is no what to tell where the program
input is coming from (either from the remote user, or the local user).  What
I did to get around this limitation was to install an interrupt handler on
Int 9 (The Keyboard interrupt) that drains off the local keyboard input
before the BBS has a chance to get to it.  This works very well... as long
as I am not running Desqview.  When I run Desqview, the program will 
ocassionally "freeze" while I am typing (but not when the remote user is 
typing) until I tap the Desqview key {Alt}.  Does anyone have any suggestions?

The code below shows my interrupt handler (in case anyone is interested).

---CUT HERE---
{ The following is an excerpt for a unit that I designed/use to write 
  programs to run under the BBS program WWIV 4.12.

  A note about WWIV: if a program does all of its input/output through
  DOS, then it will be run as an external under WWIV without any built
  in Asynchronous Communications routines.  The side effect of this is
  that you can't distinguish when a character comes from the local 
  keyboard, and when it comes from the remote keyboard.

  This code seperates the input from the local keyboard and the input
  that comes from the remote (user) by intercepting the Keyboard interrupt
  and storing it in a buffer which is later accessed by other functions.

  The problem that I am having is that, if I run the BBS under desqview 2.31
  with QEMM 5.11, and 2 Meg of ram, the program that is using this code
  (in my case, a Two-Way-Chat routine), occassionaly will seem to hang up
  on me.  In actuality, it continues to accept keystrokes, but doesn't 
  display them until I tap my desqview key {Alt}.  When these routines
  are run without desqview in memory, the problem disappears.

  Does anyone have any suggestions?


  The following code is original code by Adam Caldwell.  It may be freely
  used and modified by anyone.
}
 
USES Dos;

TYPE
  IntCall = PROCEDURE(dummy : WORD);   { This is used to chain the old 
                                         interrupt vector }

CONST
  BufferSize=1024;                     { overkill, but, a 1K buffer size}

VAR
  installedInt9 :boolean;              { Whether or not the new Int9 is 
                                         installed.  (initialized FALSE by
                                         the Unit that it is in - not shown }
  OldInt9 : pointer;                   { The old Int 9 vector }
  KeyBuffer : ARRAY[0..BufferSize-1] OF Char;
  Key_Buffer_Head, Key_Buffer_Tail:integer;  { circular buffer with head/tail }
  OldExitProc : pointer;               { in case there is an unusual 
                                         termination}

FUNCTION KeyPressedL:boolean;
{ This Procedure tells whether or not there is a key in the buffer }
BEGIN
  KeyPressedL:=Key_Buffer_Head<>Key_Buffer_Tail
END;

FUNCTION ReadKeyL:char;
{ Reads a key out of the local key buffer.  Works the same as ReadKey }
BEGIN
  REPEAT UNTIL KeyPressedL;  { Wait for a keystroke like readkey does }
  ReadKeyL:=KeyBuffer[Key_Buffer_Head]; { get the key from the buffer }
  Key_Buffer_Head:=(Key_Buffer_Head+1) MOD BufferSize  { increment the head }
END;

PROCEDURE NewInt9;
INTERRUPT;
VAR
  r:registers;
BEGIN
  IntCall(OldInt9)(0);  { Chain the old Int 9 Vector, 0 is a dummy value }
  r.ah:=1;              { check to see if there is a key in the "real" buffer}
  intr($16,r);
  IF (r.flags AND FZero)=0 THEN  { if there is, store it in my buffer }
  BEGIN
    r.ah:=0;
    intr($16,r);
    KeyBuffer[Key_Buffer_Tail]:=chr(r.al);
    Key_Buffer_Tail:=(Key_Buffer_Tail+1) MOD BufferSize;
    IF r.al=0 THEN      { if there is an extended keystroke ie F1, F2, etc, }
    BEGIN               { store that in the buffer too }
      KeyBuffer[Key_Buffer_Tail]:=chr(r.ah);
      Key_Buffer_Tail:=(Key_Buffer_Tail+1) MOD BufferSize;
    END;
  END;
END;



PROCEDURE MergeLocalInput;
{ This uninstalls the int vector.  For WWIV, this makes the local input and
  the remote input again be merged, hence the name }
BEGIN
  IF InstalledInt9 THEN
  BEGIN
    SetIntVec(9,OldInt9);
    InstalledInt9:=FALSE;
    ExitProc:=OldExitProc;
  END;
END;


PROCEDURE SeperateLocalInput;
{ this installs the interrupt handler. }
BEGIN
  IF NOT InstalledInt9 THEN
  BEGIN
    GetIntVec(9,OldInt9);
    SetIntVec(9,@NewInt9);
    InstalledInt9:=TRUE;
    OldExitProc:=ExitProc;
    ExitProc:=@MergeLocalInput;
    Key_Buffer_Head:=Key_Buffer_Tail;
  END;
END;

---CUT HERE---

Thanx in advance,
  Adam Caldwell

----
  acaldwel@oucsace.cs.ohiou.edu
  acaldwel@bigbird.cs.ohiou.edu
  CS755@OUACCVMB.bitnet