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 //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); }