H
Hartmut
Hi guys out there...,
I am not shure if this is the right forum for my Question.
Have a problem using my own Keyboard interrupt handler. The handler
works
fine as long as i do not press keys like pause, arrow keys etc. My
system
returns with a stack overflow.
Is there something i have overseen in my keyboard Interrupt Service
Routine?
I just want to get the key pressed and store it in a variable for
later processing. This comprises all keys available on the keyboard.
Can't use a while( !_bios_keybrd(_NKEYBRD_READY) ) construct, because
this
keeps my program in a trap. See code ready-for-compile code below...
Sorry, that the code is written in C++ ... ;-)
My System:
Pentium II-MMX 233MHz
Award BIOS v4.51PG
Pure MS-DOS 6.2 (no MFC or WinX.X installed)
MS C700 optimizing compiler (PWB)
//**************************************
#include <dos.h>
#include <bios.h>
#include <iostream.h>
#include <stdlib>
#define _DEBUG
#define TRUE (1==1)
#define FALSE (1==0)
typedef int INT;
typedef unsigned int UINT;
typedef unsigned char BOOL;
typedef void (__far __interrupt *KEYBOARDISR)(void);
class EventHandler
{
public:
EventHandler();
~EventHandler();
public:
static void (__far __interrupt *old_KeyboardISR)(); /* ptr. to old
keybrd int handler */
static void __far __interrupt KeyboardISR(void);
BOOL KeyboardSetHandler( KEYBOARDISR pISRfunc );
static INT iEventCounter;
static UINT m_siKeyStroke;
void RestoreKeyboard(void);
};
// initializing class members
INT EventHandler::iEventCounter = 0;
UINT EventHandler::m_siKeyStroke = 0;
void (__far __interrupt *EventHandler:ld_KeyboardISR)() = NULL;
// constructor
EventHandler::EventHandler()
{
KeyboardSetHandler( KeyboardISR );
}
EventHandler::~EventHandler()
{
RestoreKeyboard();
}
// sets keyb ISR
BOOL EventHandler::KeyboardSetHandler( KEYBOARDISR pISRfunc )
{
if(pISRfunc == NULL) return(FALSE);
EventHandler:ld_KeyboardISR = _dos_getvect(0x09);
_dos_setvect( 0x09, pISRfunc );
return(TRUE);
}
// the Keyboard Interrupt Service Routine
void __far __interrupt EventHandler::KeyboardISR()
{
(*EventHandler:ld_KeyboardISR)(); /* call old interrupt handler */
/****
My intention to call the old interrupt handler is to fill the
AX register value of INT16h with the desired keystroke.
_bios_keybrd
should exactly return this value, but it does not (always)...
****/
EventHandler::m_siKeyStroke = (UINT)_bios_keybrd( _NKEYBRD_READ );
EventHandler::iEventCounter++;
#ifdef _DEBUG
// ...ok, i know we schould not call low level I/O stuff
// in a interrupt handler, but for debugging its ok ;-)
cout << "Event Counter = " << EventHandler::iEventCounter
<< " Key: " << EventHandler::m_siKeyStroke << endl;
#endif
}
void EventHandler::RestoreKeyboard(void)
{
_dos_setvect( 0x09, EventHandler:ld_KeyboardISR );
}
int main(void)
{
EventHandler kbdEvent;
while(TRUE) // ...sorry, needs a reboot
;
return(0);
}
//**************************************
I am not shure if this is the right forum for my Question.
Have a problem using my own Keyboard interrupt handler. The handler
works
fine as long as i do not press keys like pause, arrow keys etc. My
system
returns with a stack overflow.
Is there something i have overseen in my keyboard Interrupt Service
Routine?
I just want to get the key pressed and store it in a variable for
later processing. This comprises all keys available on the keyboard.
Can't use a while( !_bios_keybrd(_NKEYBRD_READY) ) construct, because
this
keeps my program in a trap. See code ready-for-compile code below...
Sorry, that the code is written in C++ ... ;-)
My System:
Pentium II-MMX 233MHz
Award BIOS v4.51PG
Pure MS-DOS 6.2 (no MFC or WinX.X installed)
MS C700 optimizing compiler (PWB)
//**************************************
#include <dos.h>
#include <bios.h>
#include <iostream.h>
#include <stdlib>
#define _DEBUG
#define TRUE (1==1)
#define FALSE (1==0)
typedef int INT;
typedef unsigned int UINT;
typedef unsigned char BOOL;
typedef void (__far __interrupt *KEYBOARDISR)(void);
class EventHandler
{
public:
EventHandler();
~EventHandler();
public:
static void (__far __interrupt *old_KeyboardISR)(); /* ptr. to old
keybrd int handler */
static void __far __interrupt KeyboardISR(void);
BOOL KeyboardSetHandler( KEYBOARDISR pISRfunc );
static INT iEventCounter;
static UINT m_siKeyStroke;
void RestoreKeyboard(void);
};
// initializing class members
INT EventHandler::iEventCounter = 0;
UINT EventHandler::m_siKeyStroke = 0;
void (__far __interrupt *EventHandler:ld_KeyboardISR)() = NULL;
// constructor
EventHandler::EventHandler()
{
KeyboardSetHandler( KeyboardISR );
}
EventHandler::~EventHandler()
{
RestoreKeyboard();
}
// sets keyb ISR
BOOL EventHandler::KeyboardSetHandler( KEYBOARDISR pISRfunc )
{
if(pISRfunc == NULL) return(FALSE);
EventHandler:ld_KeyboardISR = _dos_getvect(0x09);
_dos_setvect( 0x09, pISRfunc );
return(TRUE);
}
// the Keyboard Interrupt Service Routine
void __far __interrupt EventHandler::KeyboardISR()
{
(*EventHandler:ld_KeyboardISR)(); /* call old interrupt handler */
/****
My intention to call the old interrupt handler is to fill the
AX register value of INT16h with the desired keystroke.
_bios_keybrd
should exactly return this value, but it does not (always)...
****/
EventHandler::m_siKeyStroke = (UINT)_bios_keybrd( _NKEYBRD_READ );
EventHandler::iEventCounter++;
#ifdef _DEBUG
// ...ok, i know we schould not call low level I/O stuff
// in a interrupt handler, but for debugging its ok ;-)
cout << "Event Counter = " << EventHandler::iEventCounter
<< " Key: " << EventHandler::m_siKeyStroke << endl;
#endif
}
void EventHandler::RestoreKeyboard(void)
{
_dos_setvect( 0x09, EventHandler:ld_KeyboardISR );
}
int main(void)
{
EventHandler kbdEvent;
while(TRUE) // ...sorry, needs a reboot
;
return(0);
}
//**************************************