{ > I need help on reading the keyboard in a specific way, I need to > read it as a whole not a key at a time. I need to do this for > the games I make, I have to ba able to hold down one key to > perform a Function and then hold down another key and scan both > keys at the same time but to perform 2 different Functions. For > instance, if I hold down the left arrow key to make a Character > run I should be able to hold down the space bar to make him > fire a gun at the same time. > I would Really appreciate any help anyone could give me With this. Grab this (TWOKEYS.PAS) and the next 2 messages (KEYINTR.PAS and POLL.PAS). } Program TwoKeys; Uses Crt, Poll ; { polled keyboard handler } { ----- this Program will probably hang a debugger ----- } Var X, Y : Byte ; begin ClrScr ; X := 40 ; Y := 12 ; WriteLn( 'Hit keys A S and 1 2 on the keypad' ) ; WriteLn( ' -- Esc to stop' ) ; While not KeyTable[ EscKey ] do begin GotoXY( X, Y ) ; Write( ' ' ) ; { poll the KeyTable } If KeyTable[ endKey ] and ( X > 1 ) then Dec( X ) ; If KeyTable[ DownKey ] and ( X < 80 ) then Inc( X ) ; If KeyTable[ aKey ] and ( Y > 4 ) then Dec( Y ) ; If KeyTable[ sKey ] and ( Y < 24 ) then Inc( Y ) ; GotoXY( X, Y ) ; Write( chr( 1 ) ) ; Delay( 10 ) ; end ; end. Unit KeyIntr ; { support For INT 09 routines } Interface Procedure CLI ; Inline( $FA ) ; { disable interrupts } Procedure STI ; Inline( $FB ) ; { enable interrupts } { cannot be used outside an interrupt Procedure } Procedure JumpInterrupt( p : Pointer ) ; Inline( $5B/$58/ { POP BX, AX AX:BX = p } $89/$EC/ { MOV SP, BP } $87/$46/$10/ { XCHG AX, [BP+10H] } $87/$5E/$0E/ { XCHG BX, [BP+0EH] } $5D/$07/$1F/$5F/$5E/ { POP BP, ES, DS, DI, SI } $5A/$59/ { POP DX, CX } $FA/ { CLI } $CB ) ; { RETF jmp far p } Function Control_Pressed : Boolean ; Procedure EOI ; { end of interrupt to 8259 } Function ReadScanCode : Byte ; { read keyboard } Procedure ResetKeyboard ; { prepare For next key } Procedure StoreKey( Scan, Key : Byte ); { put key in buffer For INT 16 } Implementation Uses Crt ; { Sound, NoSound } Type Address = Record { used in Pointer manipulation } Offset : Word ; Segment : Word ; end ; Const BiosDataSegment = $40 ; Var KeyState : Word Absolute BiosDataSegment:$0017 ; KeyBufferHead : Word Absolute BiosDataSegment:$001A ; KeyBufferTail : Word Absolute BiosDataSegment:$001C ; KeyBufferStart : Word Absolute BiosDataSegment:$0080 ; KeyBufferend : Word Absolute BiosDataSegment:$0082 ; Function Control_Pressed : Boolean ; begin Control_Pressed := ( KeyState and 4 ) = 4 ; end; Procedure EOI ; { end of interrupt to 8259 interrupt controller } begin CLI ; Port[$20] := $20 ; end ; Function ReadScanCode : Byte ; begin ReadScanCode := Port[$60] ; end ; Procedure ResetKeyboard ; { prepare For next key } Var N : Byte ; begin N := Port[$61] ; Port[$61] := ( N or $80 ) ; Port[$61] := N ; end ; Procedure StoreKey( Scan, Key : Byte ) ; Var { put key in buffer that INT 16 reads } P : ^Word ; N : Word ; begin address(P).segment := BiosDataSegment ; N := KeyBufferTail ; address(P).offset := N ; Inc( N, 2 ) ; { advance Pointer two Bytes } If( N = KeyBufferend ) then { end of the circular buffer } N := KeyBufferStart ; If( N = KeyBufferHead ) then { buffer full } begin EOI ; { EOI must be done before Exit } Sound( 2200 ) ; { but before anything that takes a lot } Delay( 80 ) ; { of time and can be interrupted } NoSound ; end Else begin { high Byte is scan code, low is ASCII } P^ := Scan * $100 + Key ; { store key in circular buffer } KeyBufferTail := N ; { advance tail Pointer } EOI ; end ; end ; end. Unit POLL ; { polled keyboard handler } { does not support F11 or F12 keys } Interface Const EscKey = 1 ; { key codes } aKey = 30 ; sKey = 31 ; endKey = 79 ; DownKey = 80 ; Var KeyTable : Array[ 1..127 ] of Boolean ; { KeyTable[ x ] is True when key x is pressed and stays True Until key x is released } Implementation Uses Dos, KeyIntr ; { keyboard interrupt support } Var OldInt09 : Pointer ; ExitSave : Pointer ; Procedure RestoreInt09 ; Far; begin ExitProc := ExitSave ; SetIntVec( $09, OldInt09 ) ; end ; Procedure NewInt09 ; interrupt ; Far; Var ScanCode : Byte ; KeyCode : Byte ; begin STI ; ScanCode := ReadScanCode ; KeyCode := ScanCode and $7F ; { strip make/break bit } KeyTable[ KeyCode ] := ( ScanCode and $80 ) = 0 ; ResetKeyboard ; EOI ; end ; Var N : Byte ; begin ExitSave := ExitProc ; ExitProc := addr( RestoreInt09 ) ; For N := 1 to 127 do { no key pressed } KeyTable[ N ] := False ; GetIntVec( $09, OldInt09 ) ; SetIntVec( $09, addr( NewInt09 ) ) ; end.