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