As I mentioned in a previous post, I am making a new game with CGA graphics, targeting the early PCs. I'm still early in the process; just drawing a few things to the screen. My issue is that about 1 out of every 10 times I run the game, it crashes after I exit. The crash takes various forms, usually locking up and not accepting input.
I think the crash is somehow related to my custom keyboard handler in some way. The keyboard handler itself seems to work fine, but the crash upon exit only seems to happen when it is enabled. Relevant code is below, and I'm also posting a link to a zip of the code and the binary (compiled with Watcom C compiler). Any thoughts or suggestions would be welcome!
Here is my custom keyboard routine:
// Use our own keyboard interrupt routine to track
// multiple keypresses and save CPU time.
void __interrupt __far NewKbdRoutine() {
_asm {
sti // Enable higher-priority interrupts (timer)
in al, 0x60 // Read raw keycode from keyboard buffer port
xor ah,ah // blank out high byte
mov raw_key, ax // copy low byte to raw_key global variable
in al, 0x61 // Read value from keyboard control port
or al, 0x80 // set bit 7 in value
out 0x61,al // write value to keyboard control port
and al,0x7F // mask out bit 7
out 0x61,al // write value to keyboard control port
}
switch( raw_key )
case KEY_UP_DOWN: {
key_state |= UP_PRESSED;
break;
case KEY_DOWN_DOWN:
key_state |= DOWN_PRESSED;
break;
case KEY_LEFT_DOWN:
key_state |= LEFT_PRESSED;
break;
case KEY_RIGHT_DOWN:
key_state |= RIGHT_PRESSED;
break;
case KEY_SPACE_DOWN:
key_state |= SPACE_PRESSED;
break;
case KEY_ESCAPE_DOWN:
key_state |= ESC_PRESSED;
case KEY_X_DOWN:
key_state |= ESC_PRESSED;
case KEY_Q_DOWN:
key_state |= ESC_PRESSED;
break;
case KEY_UP_UP:
key_state &= ~UP_PRESSED;
break;
case KEY_DOWN_UP:
key_state &= ~DOWN_PRESSED;
break;
case KEY_LEFT_UP:
key_state &= ~LEFT_PRESSED;
break;
case KEY_RIGHT_UP:
key_state &= ~RIGHT_PRESSED;
break;
case KEY_SPACE_UP:
key_state &= ~SPACE_PRESSED;
break;
default: break;
}
_disable(); // Interrups are re-disabled right before the EOI signal.
outp( 0x20, 0x20 ); // EOI for interrupt
}
The custom keyboard handler is installed with this code:
// Install new keyboard routine for speed
// and multiple keypress detection
OldKbdRoutine = _dos_getvect(KEYBOARD_INT);
_dos_setvect(KEYBOARD_INT, NewKbdRoutine);
The old routine is restored in my program's exit function with the following code:
_dos_setvect(KEYBOARD_INT, OldKbdRoutine);
A link to a zip of the source and binary may be found here:
CGAINV.ZIP
Thanks in advance for any advice! |