BBS: Inland Empire Archive
Date: 11-18-92 (22:24) Number: 389
From: BRENT ASHLEY Refer#: NONE
To: RAYMOND PAQUIN Recvd: NO
Subj: QB SIMULATNEOUS INPUT Conf: (2) Quik_Bas
There seems to be a way to detect multiple keys pressed at once
that isn't too complex if you know about hooking interrupts.
The BIOS keyboard routine (INT 9) calls INT 15h service 4Fh before
it deals with each scan code that comes from the keyboard,
allowing a user to get this raw data and act upon it. This feature is
only available on AT machines and later, so earlier machines will have
to use an INT 9 hook - a little more complex but doable.
When a key is pressed or released, INT 9 is generated and the BIOS
retrieves the scan code from the keyboard I/O port. You can find
a list of scan codes in your QB BASIC language reference - for
instance, the codes for the 1,2,3 and 4 keys along the top row of
the keyboard are 2,3,4 and 5. When the key is PRESSED, the scan
code is generated, and when it is RELEASED, the scan code plus
&H80 is generated. Soooo.... you can hook this interrupt and tell
when any key is pressed or released.
If you were to maintain within your interrupt handler an array (or
more efficiently, a bit array) of true/false elements representing
each key, you could easily poll that array from your program and
determine which keys are pressed at any one time. Further, you
could decide not to pass that information on to the BIOS and have
full control of the keyboard.
A test program, written in QB with Crescent's PDQ, follows. It
installs itself in memory, steals INT 15h service 4Fh, and
monitors the 1,2,3 and 4 keys, displaying their status at the top
right of your screen. By playing with the keys, you can see that
it's quite simple to get chords happening.
It's a real pity I can't follow this message with a Postit of the
executable for those who don't have PDQ. This is exactly the type of
thing Postit was meant for. If the power-dorks would ease off, it could
be a pretty useful tool in the right hands. If there is enough call for
it, I'll write an ASM module to maintain an integer array as described
above, callable from QB.
DIM Registers AS RegType
Pgm$ = "Multikey v1.0"
CALL PDQPrint(Pgm$, CSRLIN, POS(0), 7)
Row = 1 : Column = 73 : Colr = 7
Registers.IntNum = &H15
CALL IntEntry2(Registers, Zero)
IF Registers.AX\256 = &H4F THEN
ScanCode = Registers.AX AND 255
SELECT CASE ScanCode
CASE 2 : MID$(Keys$,1,1) = "1"
CASE 3 : MID$(Keys$,2,1) = "2"
CASE 4 : MID$(Keys$,3,1) = "3"
CASE 5 : MID$(Keys$,4,1) = "4"
CASE 130 : MID$(Keys$,1,1) = " "
CASE 131 : MID$(Keys$,2,1) = " "
CASE 132 : MID$(Keys$,3,1) = " "
CASE 133 : MID$(Keys$,4,1) = " "
CALL PDQPrint(Keys$, Row, Column, Colr)
--- FidoPCB v1.3 [ff053/x]
* Origin: Canada Remote Systems, Mississauga, Ontario (1:229/15)