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.
-----
Brent
-----
'
' Multikey.BAS - demonstrates hooking INT 15h svc 4Fh to monitor
' raw scan codes to enable detection of multiple
' keys pressed.
'
' Requires Crescent's PDQ
'
DEFINT A-Z
'$INCLUDE: 'PDQDecl.BAS'
DIM Registers AS RegType
' init stuff
Pgm$ = "Multikey v1.0"
CALL PDQPrint(Pgm$, CSRLIN, POS(0), 7)
Row = 1 : Column = 73 : Colr = 7
Keys$=" "
' hook interrupt &H15
Registers.IntNum = &H15
CALL PointIntHere(Registers)
GOTO EndIt
CALL IntEntry1
CALL IntEntry2(Registers, Zero)
' only interested in service &H4F
IF Registers.AX\256 = &H4F THEN
' extract scan code from AL
ScanCode = Registers.AX AND 255
' set flag in display string
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) = " "
END SELECT
' display string
CALL PDQPrint(Keys$, Row, Column, Colr) 'display the scan code
ENDIF
' allow BIOS to carry on with keystroke
CALL GotoOldInt(Registers)
' save space by releasing environment
EndIt:
CALL ReleaseEnv
CALL EndTSR(Pgm$)
--- FidoPCB v1.3 [ff053/x]
* Origin: Canada Remote Systems, Mississauga, Ontario (1:229/15)

Books at Amazon:
Back to BASIC: The History, Corruption, and Future of the Language
Hackers: Heroes of the Computer Revolution (including Tiny BASIC)
Go to: The Story of the Math Majors, Bridge Players, Engineers, Chess Wizards, Scientists and Iconoclasts who were the Hero Programmers of the Software Revolution
The Advent of the Algorithm: The Idea that Rules the World
Moths in the Machine: The Power and Perils of Programming
Mastering Visual Basic .NET