Code:
// Codes for ISR redirect
#define KEYB_INT 0x09
#define KEYB_BUF 0x60
#define KEYB_CONT 0x61
#define INT_CONT 0x20
#define MAX_SCANS 89
// List of scan codes (make only):
#define K_ESC 1
#define K_1 2
#define K_2 3
#define K_3 4
#define K_4 5
#define K_5 6
#define K_6 7
#define K_7 8
#define K_8 9
#define K_9 10
#define K_0 11
#define K_MINUS 12
#define K_EQUALS 13
#define K_BACK_SPACE 14
#define K_TAB 15
#define K_Q 16
#define K_W 17
#define K_E 18
#define K_R 19
#define K_T 20
#define K_Y 21
#define K_U 22
#define K_I 23
#define K_O 24
#define K_P 25
#define K_LEFT_BRACKET 26
#define K_RIGHT_BRACKET 27
#define K_ENTER 28
#define K_CONTROL 29
#define K_A 30
#define K_S 31
#define K_D 32
#define K_F 33
#define K_G 34
#define K_H 35
#define K_J 36
#define K_K 37
#define K_L 38
#define K_SEMI_COLON 39
#define K_APOSTROPHE 40
#define K_LEFT_SHIFT 42
#define K_BACK_SLASH 43
#define K_Z 44
#define K_X 45
#define K_C 46
#define K_V 47
#define K_B 48
#define K_N 49
#define K_M 50
#define K_COMMA 51
#define K_FULL_STOP 52
#define K_FORWARD_SLASH 53
#define K_RIGHT_SHIFT 54
#define K_PRINT_SCREEN 55
#define K_ALT 56
#define K_SPACE 57
#define K_CAPS_LOCK 58
#define K_F1 59
#define K_F2 60
#define K_F3 61
#define K_F4 62
#define K_F5 63
#define K_F6 64
#define K_F7 65
#define K_F8 66
#define K_F9 67
#define K_F10 68
#define K_F11 87
#define K_F12 88
#define K_NUM_LOCK 69
#define K_SCROLL_LOCK 70
#define K_HOME 71
#define K_UP 72
#define K_PAGE_UP 73
#define K_NUM_MINUS 74
#define K_LEFT 75
#define K_NUM_5 76
#define K_RIGHT 77
#define K_NUM_PLUS 78
#define K_END 79
#define K_DOWN 80
#define K_PAGE_DOWN 81
#define K_INSERT 82
#define K_DELETE 83
unsigned char keyPressed = FALSE; // Flags the press of a key.
unsigned char rawKey; // The last scan code generated.
unsigned char keySet [MAX_SCANS]; // One for every key on the board.
// Various functions delaing with the keyboard input.
void interrupt newKeybInt (...); // For the keyboard.
void interrupt (*oldKeybInt) (...); // Keep copy of old one.
inline char isPressed (unsigned char scanCode, unsigned char turnOff);
Code:
void interrupt newKeybInt (...)
{
// This asm code courtesy of 'Tricks of the Game Programming Gurus' book:
asm
{
sti
in al, KEYB_BUF
xor ah, ah
mov rawKey, al
in al, KEYB_CONT
or al, 0x82
out KEYB_CONT, al
and al, 0x7f
out KEYB_CONT, al
mov al, 0x20
out INT_CONT, al
}
if (rawKey < MAX_SCANS) // If a make code.
{
keySet [rawKey] = TRUE; // Turn that key flag on.
keyPressed = TRUE;
}
else // Else must be a break code,
{
keySet [rawKey - 128] = FALSE; // so turn it off.
keyPressed = FALSE;
}
}
inline char isPressed (unsigned char scanCode, unsigned char turnOff)
{
if (keySet [scanCode])
{
if (turnOff)
keySet [scanCode] = FALSE;
return TRUE;
}
return FALSE;
}
And in your main:
Code:
void interrupt (*oldKeybInt) (...); // Old keyboard interrupt.
void interrupt newKeybInt (...); // New one.
.
.
.
oldKeybInt = getvect (KEYB_INT); // Re-direct ISR:
setvect (KEYB_INT, newKeybInt);
.
.
.
setvect (KEYB_INT, oldKeybInt); // When you're done, put it back
Back from when I wrote DOS games.
Use the #defined symbols to find out whether a key is held:
Code:
if (isPressed (K_SPACE, true))
fireMissile ();
The turnOff argument (here set to true) means that the player cannot simply hold down this particular key and constantly fire missiles. He has to let go and press it again and again. Obviously, if you want a control hold-downable (i.e. an accelerator in a race game) set this to false.