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