Date: Fri, 24 Mar 1995 11:13:15 +0200 From: sarda_jea AT lsi DOT supelec DOT fr To: djgpp AT sun DOT soe DOT clarkson DOT edu Subject: Again : intercept the Keyboard interrupt Hello, First of all thanks to those who answered to my previous question. I've tried to install my own Keyboard interrupt handler following the example of sb.c (the soundblaster demonstration program). My program should write " HELLO " on the screen each time a button is pushed or released. When I run it and when I push a button it writes 2 times " HELLO " on the screen then it makes a protection fault. So I've included the little source code which install the interrupt handler. If you see what is wrong in it, please tell me. #include #include #include #include #include #include #include /* * GO32 DPMI structs for accessing DOS memory. */ static _go32_dpmi_seginfo oldirq_rm; /* original real mode IRQ */ static _go32_dpmi_registers rm_regs; static _go32_dpmi_seginfo rm_si; /* real mode interrupt segment info */ static _go32_dpmi_seginfo oldirq_pm; /* original prot-mode IRQ */ static _go32_dpmi_seginfo pm_si; /* prot-mode interrupt segment info */ static unsigned int irq; void disable() { asm("cli"); } void enable() { asm("sti"); } /* * Interrupt handler * * This is called in both protected mode and in real mode -- this means * we don't have to switch modes when we service the interrupt. */ void intr(_go32_dpmi_registers *reg) { disable(); printf(" HELLO \n"); enable(); } /* * Install our interrupt as the real mode interrupt handler * * * We accomplish this by have GO32 allocate a real mode callback for us. * The callback packages our protected mode code up in a real mode wrapper. */ void install_rm_interrupt() { int ret; rm_si.pm_offset = (int) intr; ret = _go32_dpmi_allocate_real_mode_callback_iret(&rm_si, &rm_regs); if (ret != 0) { printf("cannot allocate real mode callback, error=%04x\n",ret); exit(1); } printf("real mode callback is at %04x:%04x\n", rm_si.rm_segment, rm_si.rm_offset); /* * Install our real mode interrupt handler */ disable(); _go32_dpmi_get_real_mode_interrupt_vector(irq, &oldirq_rm); _go32_dpmi_set_real_mode_interrupt_vector(irq, &rm_si); enable(); } /* * Remove our real mode interrupt handler. */ void cleanup_rm_interrupt() { disable(); _go32_dpmi_set_real_mode_interrupt_vector(irq, &oldirq_rm); _go32_dpmi_free_real_mode_callback(&rm_si); enable(); } /* * Install our interrupt as the protected mode interrupt handle * */ void install_pm_interrupt() { disable(); _go32_dpmi_get_protected_mode_interrupt_vector(irq, &oldirq_pm); pm_si.pm_offset = (int) intr; pm_si.pm_selector = _go32_my_cs(); _go32_dpmi_chain_protected_mode_interrupt_vector(irq, &pm_si); enable(); } /* * Remove our protected mode interrupt handler. */ void cleanup_pm_interrupt() { disable(); _go32_dpmi_set_protected_mode_interrupt_vector(irq, &oldirq_pm); enable(); } /* * Restore system to same state before exiting. */ void cleanup() { /* * Remove our interrupt handlers */ cleanup_rm_interrupt(); cleanup_pm_interrupt(); } int main() { char c; int i; irq=9; install_rm_interrupt(); install_pm_interrupt(); for(i=0;i<10000000;i++){} cleanup_rm_interrupt(); cleanup_pm_interrupt(); return 0; }