'===========================================================================
' Subject: MULTIPLE KEY PROCESSING            Date: 08-08-98 (05:29)       
'  Author: Andre Victor                       Code: QB, QBasic, PDS        
'  Origin: anvictor@ruralsp.com.br          Packet: KEYBOARD.ABC
'===========================================================================
' multiple keys processing for QBasic 1.1
' by Andre V1ctor / BRAZIL 1998
' 100% public domain - but please give some credit if you use it. :)
'
' WARNING!!! after call KbdInit, Ctrl-Break, Ctrl-Alt-Del and
'            the BASIC's procedures: INKEY$ and SLEEP don't will work.
'
DEFINT A-Z

TYPE KEYBOARD                                   ' keyboard struct (258 bytes)
 aANY    AS INTEGER
 ESC     AS INTEGER
 NPD     AS STRING * 20
 f000000 AS STRING * 4
 BSPC    AS INTEGER
 tTAB    AS INTEGER
 f000001 AS STRING * 24
 ENTER   AS INTEGER
 Ctrl    AS INTEGER
 f000002 AS STRING * 24
 LFSH    AS INTEGER
 f000003 AS STRING * 22
 RGSH    AS INTEGER
 PRT     AS INTEGER
 Alt     AS INTEGER
 sSPC    AS INTEGER
 CAP     AS INTEGER
 F1      AS INTEGER
 F2      AS INTEGER
 F3      AS INTEGER
 F4      AS INTEGER
 F5      AS INTEGER
 F6      AS INTEGER
 F7      AS INTEGER
 F8      AS INTEGER
 F9      AS INTEGER
 F10     AS INTEGER
 NUM     AS INTEGER
 SCRL    AS INTEGER
 HOME    AS INTEGER
 UP      AS INTEGER
 PGUP    AS INTEGER
 MIN     AS INTEGER
 LEFT    AS INTEGER
 MID     AS INTEGER
 RIGHT   AS INTEGER
 PLUS    AS INTEGER
 eEND    AS INTEGER
 DOWN    AS INTEGER
 PGDW    AS INTEGER
 INS     AS INTEGER
 Del     AS INTEGER
 f000004 AS STRING * 6
 F11     AS INTEGER
 F12     AS INTEGER
 f000005 AS STRING * 80
END TYPE
'
DECLARE SUB KbdInit (kbd AS KEYBOARD)
DECLARE SUB KbdDone ()
     DIM KbdCode(0 TO 87) AS INTEGER            ' my data
     DIM KbdFlag AS INTEGER

     DIM kbd AS KEYBOARD                        ' your data
    
     KbdInit kbd                                ' initialize

     CLS
    DO
    
     LOCATE 1, 1: PRINT kbd.tTAB; kbd.UP; kbd.ENTER; "     "
     LOCATE 2, 1: PRINT kbd.LEFT; kbd.sSPC; kbd.RIGHT; "     "
     LOCATE 3, 1: PRINT kbd.Ctrl; kbd.DOWN; kbd.Alt; "     "
   
    LOOP UNTIL kbd.ESC

     KbdDone                                    ' terminate (don't forget)


':::::::::::::::::::::::::::::::::::::::::::::::::
KbdCode:                                        ' machine code
DATA 50,53,56,1E,FB,BE,34,12,B8,34,12,8E,D8,E4
DATA 60,88,C4,24,7F,32,FF,8A,D8,D1,E3,03,DE,D0
DATA E4,1A,E4,F6,D4,88,27,22,C4,88,04,E4,61,88
DATA C4,0C,80,E6,61,88,E0,E6,61,FA,B0,20,E6,20
DATA FB,1F,5E,5B,58,CF,55,89,E5,57,06,1E,8B,5E
DATA 0A,8B,3F,8B,5E,0C,8B,07,8E,C0,8B,5E,06,8B
DATA 07,50,26,89,45,06,8B,5E,08,8B,07,50,26,89
DATA 45,09,8C,C0,8E,D8,B4,35,B0,09,CD,21,89,9D
DATA A0,00,8C,C0,89,85,A3,00,89,FA,B4,25,B0,09
DATA CD,21,07,5F,33,C0,B9,80,00,F3,AB,1F,07,5F
DATA 5D,CA,08,00,06,1E,B8,40,00,8E,C0,26,A1,1C
DATA 00,26,A3,1A,00,BA,34,12,B8,34,12,8E,D8,B4
DATA 25,B0,09,CD,21,1F,07,CB

':::::::::::::::::::::::::::::::::::::::::::::::::
SUB KbdDone
' restores old keyboard handler. must be called before exiting program.

     SHARED KbdCode() AS INTEGER
     SHARED KbdFlag AS INTEGER

    IF (KbdFlag) THEN
     KbdFlag = 0

     DEF SEG = VARSEG(KbdCode(0))

     CALL absolute(VARPTR(KbdCode(0)) + 144)
    END IF

END SUB

':::::::::::::::::::::::::::::::::::::::::::::::::
SUB KbdInit (kbd AS KEYBOARD)
' initializes new keyboard handler.

     SHARED KbdCode() AS INTEGER
     SHARED KbdFlag AS INTEGER
     DIM bt AS STRING
     DIM i AS INTEGER

    IF (NOT KbdFlag) THEN
     KbdFlag = -1

     DEF SEG = VARSEG(KbdCode(0))
    
     RESTORE KbdCode
     FOR i = 0 TO 175
      READ bt
      POKE VARPTR(KbdCode(0)) + i, VAL("&H" + bt)
     NEXT i
  
     CALL absolute(VARSEG(KbdCode(0)), VARPTR(KbdCode(0)), VARSEG(kbd), VARPTR(kbd), VARPTR(KbdCode(0)) + 62)
    END IF

END SUB
