QB SIMULATNEOUS INPUT

 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)
Outer Court
Echo Basic Postings

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