[comp.os.msdos.programmer] Reading multiple keypresses at once

fisher@sc2a.unige.ch (Markus Fischer) (07/16/90)

In article <11396@hydra.gatech.EDU>, ccastje@prism.gatech.EDU (John Adair) writes:
> How do programs read multiple keys pressed at the same time (not just
> Alt and 'X')?  Many multiple player games allow two players to share
> the keyboard.  Is there a way to get the 8042 to alternate scan codes
> between the two keys (i doubt it)?  Do I have to sit there and poll
> the keyboard port (0x60, I think), remembering that the first key has
> sent a 'make', but not a 'break', before the second key sends a 'make'?
> Is there a simpler way to do this?
> 
> Along the same lines, how do I discard the keypresses before (or as soon
> as) they reach the buffer, preferably without having to constantly 
> read in and discard characters?

For what it's worth:  In the interrupt list (some outdated version, you can
find the latest at SIMTEL20 PD1:<MSDOS.INFO>INTER###.ZIP) I find:

INT 15 - OS HOOK - KEYBOARD INTERCEPT (AT model 3x9,Xt2,XT286,CONV,PS)
	AH = 4Fh
	AL = scan code
	CF set
Return: CF set
	    AL = scan code
	CF clear
	    scan code should not be used
Note: Called by INT 9 handler to translate scan codes

In an older posting, Tom Almy (at the time <toam@tekgvs.labs.tek.com>) used
this interrupt to remap the AT keyboard's CapsLock to another Ctrl key.  It
works beautifully.

A solution to your problem would thus be to write your own interrupt handler
for int 15, which would simply check for the AH==4fh (leaving all other
functions to the original handler, of course), and then update a global
variable to reflect the ``key-pressed state'' according the the scan code,
and clear CF.  This way, nothing would even *get* to the keyboard buffer!
(For that matter, you couldn't even put the keyboard in Ctrl, let alone
Alt-Ctrl state, with means Ctrl-C and Ctrl-Alt-Del are trapped!).

Your main loop would simply read the global variable, and act accordingly (e.g.
`left-ctrl F': player A fires at B, *and* `right-ctrl J': player B fires at A
* Both player dead: Draw!   *** GAME OVER ***   Another duel? (y/n)? _ :-)
.. hm, better release int 15 before the `(y/n)?' ...

BTW: TC's User Guide gives an example of this kind of interrupt handling, for
which you don't need a single line of assembler.  Speaking of TC, your global
variable should be `volatile' (make shure the compiler won't skip even a single
``read'' of that variable!).

Hope this helps

Markus Fischer,    Dpt. of Anthropology, Geneva.

toma@tekgvs.LABS.TEK.COM (Tom Almy) (07/18/90)

In article <204@sc2a.unige.ch> fisher@sc2a.unige.ch (Markus Fischer) writes:
>In article <11396@hydra.gatech.EDU>, ccastje@prism.gatech.EDU (John Adair) writes:
>> How do programs read multiple keys pressed at the same time (not just
>> Alt and 'X')?  [...]
>> Along the same lines, how do I discard the keypresses before (or as soon
>> as) they reach the buffer, preferably without having to constantly 
>> read in and discard characters?
>
>For what it's worth:  In the interrupt list (some outdated version, you can
>find the latest at SIMTEL20 PD1:<MSDOS.INFO>INTER###.ZIP) I find:
>
>INT 15 - OS HOOK - KEYBOARD INTERCEPT (AT model 3x9,Xt2,XT286,CONV,PS)
[...]
>In an older posting, Tom Almy (at the time <toam@tekgvs.labs.tek.com>) used
>this interrupt to remap the AT keyboard's CapsLock to another Ctrl key.  It
>works beautifully.

Well, since my name was mentioned, see my "signiture" for correct address.

I also used this interrupt hook for a Smalltalk implementation where I had
to capture key presses and releases, and the hook stuffed them in a queue.

In this application (and in the original thread authors) the typamatic action
had to be eliminated as well. I maintained a bit array of depressed keys,
and would completely toss a "make" code if the key was listed as depressed.

Lots of fun to code, and worked like a charm.

Tom Almy
toma@tekgvs.labs.tek.com
Standard Disclaimers Apply

nraoaoc@nmt.edu (Daniel Briggs) (07/19/90)

>[much discussion of reading the keyboard and maintaining state tables, etc..]

Since we're on the subject, I'll toss out a question that I have been
wondering about.  I have a little V20 based laptop that runs at 7.2 MHz.
I also have a few games for this bugger that use some variant of the technique
that we are talking about.  (I hang my head in shame, but hey!  I take lunch
hours too!)  What interests me is that even with a completely vanilla system,
naked in all respects, these games still appear to occasionally miss break
codes.  This is a drag, in that it has the effect that a key is 'stuck' on.
If I had to guess, I presume that this is due to several keys raising an
interrupt at once, while the processor has interrupts disabled.  The 8259A
can only buffer one, so somebody has to lose.  Does anybody happen to know
just what the keyboard processor will do in this situation?  How robust
have people found this technique to be for fairly demanding applications?
Does my clone maybe have a poor BIOS that spends longer than it should with
interrupts disabled?
-- 
This is a shared guest account, please send replies to
dbriggs@nrao.edu (Internet)
Dan Briggs / NRAO / P.O. Box O / Socorro, NM / 87801  (U.S. Snail)