From: "Anthony.Appleyard" Organization: Materials Science Centre To: DJGPP AT delorie DOT com Date: Thu, 8 Jan 1998 14:57:19 GMT Subject: Hooking interrupt 9 in a laptop Reply-to: Anthony DOT Appleyard AT umist DOT ac DOT uk Message-ID: <1E6A8F763CA@fs2.mt.umist.ac.uk> Precedence: bulk A.Appleyard wrote:- > If int09 is hooked anyway while a djgpp C++ program is running, couldn't > the next revision of djgpp alter that hook code to save the raw keyboard > events in a 128-byte circular buffer? Eli Zaretskii replied:- > It will, if you write this stuff and submit it to DJ Delorie ;-). /* If this assembler subroutine was put in DJGPP\SRC\LIBC\GO32\EXCEPTN.S and called from any start of interrupt 9 hook routines such as ___djgpp_kbd_hdlr and ___djgpp_kbd_hdlr_pc98, it should save the raw keyboard events in a circular buffer which the user could read without having to re-hook interrupt 9 himself. This should help djgpp users with laptops, since I find that re-hooking interrupt 9 on a laptop causes various system malfunctions after the program has exited, perhaps from something clashing with the laptop's extra keyboard software that translates `Fn' key combinations into imitations of presses and releases of desktop keys which are missing on laptops. */ .global _keyeventbuf .global _keyeventbufip .global _keyeventbufop // Circular buffer. Buffer pointers are byte vars, so wraparound is automatic. _keyeventbuf: .space 256 // unsigned char keyeventbuf[256]; _keyeventbufip: .byte 0 // unsigned char keyeventbufip=0; _keyeventbufop: .byte 0 // unsigned char keyeventbufop=0; .align 4 _keyboardeventsaver: // void keyboardeventsaver() { pushl %eax // register unsigned char E; pushl %ebx // register unsigned char P; inb $0x60,%al // E = the keyboard event; movb _keyeventbufip,%bl // P = keyeventbufip; movzbl %bl,%ebx movb %al,_keyeventbuf(%ebx) // keyeventbuf[P] = E; incb _keyeventbufip // keyeventbufip++; incb %al // P++; cmpb %bl,_keyeventbufop // if(P == keyeventbufop) jne NOTFULL // { decb _keyeventbufip // keyeventbufip--; decb %bl // P--; decb %bl // P--; movzbl %bl,%ebx movb $0xff,_keyeventbuf(%ebx) // keyeventbuf[P]=0xff; NOTFULL: // } popl %ebx //// 0xff in the buffer == "here the buffer got full" popl %eax ret // } /* This line should be put in some suitable #include file:- extern unsigned char keyeventbuf[256],keyeventbufip,keyeventbufop; //----- Get a keyboard event code. Returns 0 if the buffer was empty. unsigned char getkeyevent(){ return if(keyeventbufip==keyeventbufop) ?0: keyeventbuf[++keyeventbufop];} //----- Empty the keyboard event buffer inline void emptykeyboardbuf(){keyeventbufip=keyeventbufop=0;} //----- Put an event in the keyboard event buffer yourself:- int injectkeyboardevent(unsigned char E){ keyboardbuf[keyboardbufip++]=E; if(keyboardbufip!=keyboardbufop) return 1; keyboardbuf[(--keyboardbufip)-1]=0xff; return 0;} */