delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1998/01/08/09:58:38

From: "Anthony.Appleyard" <MCLSSAA2 AT fs2 DOT mt DOT umist DOT ac DOT uk>
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>

  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 <eliz AT is DOT elta DOT co DOT il> 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;}
*/

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019