Mail Archives: djgpp/1996/05/03/10:10:22
Xref: | news2.mv.net comp.os.msdos.djgpp:3385
|
From: | pavlichum AT topaz DOT cqu DOT edu DOT au (Thunder Child)
|
Newsgroups: | comp.os.msdos.djgpp
|
Subject: | Newbie probs : hooking keyboard int
|
Date: | 1 May 96 13:01:21 +1000
|
Organization: | Central Queensland University, Australia
|
Lines: | 90
|
Message-ID: | <1996May1.130121@topaz>
|
NNTP-Posting-Host: | topaz.cqu.edu.au
|
To: | djgpp AT delorie DOT com
|
DJ-Gateway: | from newsgroup comp.os.msdos.djgpp
|
Would people in this group please cast an eye over this code, especially
if you use inline asm & interrupts. I'm new to the world of PMODE, as well
as the lower level stuff. I've implemented interrupt service routines under
Turbo C, though. (They make it so easy:).
This code compiles, but crashes when I test it. I've read the what the
info files and FAQ have to say, but the problem is still not obvious to me.
Note : I haven't locked any of the variables or code, but my test programs
are so small they shouldn't need this. Also, does one need to
explicitly push and pop registers altered if extended asm isn't used?
One way or the other it doen't seem to be my problem anyway. (I've
checked).
BTW, I'd like to congratulate the author of RHIDE... Made my life much
easier. It would be very nice if rhide could somehow integrate the existing
info files, though. (I suppose this would be difficult if the info files
are being regularly updated). Another enhancement could be interfacing
RHIDE with one of the debuggers, though I'm not sure if this practical
or even possible.
// ***************************************************************************
//Filename: KEYBOARD.C
//Purpose : Keyboard interrupt handler (INT9).
//Compiler: DJGPP C v2.0
//Author : Mark Pavlichuk.
// ***************************************************************************
//
// This is a port of a keyboard interrupt handler I wrote under Turbo C.
// It is also an effort to learn more about DJGPP specific code and pmode.
//
#include <dpmi.h> //Included for DPMI interrupt hooking/unhooking functions.
unsigned char keytable[128]; //Table to keep track off all keys
//depressed and released.
static __dpmi_paddr oldint9_addr, //Protected mode memory addresses that
newint9_addr; //we create to hold the old and new INT9
//keyboard interrupt handler addresses.
static void newint9_code(void) //New interrupt 9 handler code.
{ //(INT9 is triggered by keyboard input)
asm("
cli ;//Disable interrupts.
inb $0x60,%al ;//Read the keyboard input.
;//(Port 60h is the keyboard port).
xorw %bx,%bx ;//Clear BX.
movb %al,%bl ;//Save the input byte to BX.
testb $0b10000000,%al ;//Test if the input is a keypress or
;//a keyrelease code. Note : bit 8 is
;//set (ie. 128 is added to a keys
;//scancode) when a key is released.
jz keypressed ;//If scancode was a keypress goto
;//'keypressed:'
xorb %al,%al ;//If not (ie. was a keyrelease), zero
;//the scancode because the key is
;//no longer depressed.
keypressed:
andw $0b01111111,%ebx ;//Mask the keypressed/released bit
;//from our original scancode. (We will
;//now use it as an offset when we
movb %ax,_keytable(,%ebx,1) ;//update our table).
movb $0x20,%al ;//Output a 'non-specific EOI' (end of
out %al,$0x20 ;//interrupt) command (20h) to the
;//ICR (interrupt command register)
;//on port 20h.
sti ;//DJGPP requires an explicit 'sti'
iret ;//before returning from an interrupt.
");
}
void installkeyboardint(void)
{
__dpmi_get_protected_mode_interrupt_vector(0x09, &oldint9_addr);
//Store old keyboard interrupt vector.
newint9_addr.offset32 = (int)newint9_code;
newint9_addr.selector = _my_cs();
__dpmi_set_protected_mode_interrupt_vector(0x09, &newint9_addr);
//Hook our new handler to interrupt 9.
}
void restorekeyboardint(void)
{
__dpmi_set_protected_mode_interrupt_vector(0x09, &oldint9_addr);
}
- Raw text -