From: Warren Gill Subject: DJGPP Keyboard interrupt program To: djgpp AT sun DOT soe DOT clarkson DOT edu Date: Fri, 15 Jul 94 20:38:21 CDT Mailer: Elm [revision: 70.85] This one is long, but here it is.... The program runs in a tight loop until the spacebar is hit. /* Program to try keyboard interrupts */ #include #include #include #include #include #include #include #include #include #define TRUE (1==1) #define FALSE (0==1) #define TEST /* GO32 DPMI structs for accessing DOS memory. We set up both real mode and protected mode, just in case... */ static _go32_dpmi_seginfo dosmem; /* DOS (conventional) memory buffer */ 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 */ /* Keyboard vars */ static int requestToStop; /* Define replacements for DOS enable and disable. */ void disable() { __asm__ __volatile__ ("cli"); } void enable() { __asm__ __volatile__ ("sti"); } /* Our keyboard interrupt handler */ int kb_intr(_go32_dpmi_registers *reg) { int ch; ch = inportb(0x60); if ( ch == 57 ) /* The space-bar was hit (57 is scan code) */ requestToStop = 1; /* You could do more processing here, detect other keys, etc., but I chose to get out of the loop ASAP so I could shut down gracefully... */ outportb(0x20,0x20); /* ACK the interrupt */ enable(); } /* Install the Real Mode interrupt */ void kb_install_rm_interrupt() { int ret; rm_si.pm_offset = (int) kb_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); } #ifdef TEST printf("Real Mode callback set to %04x:%04x\n", rm_si.rm_segment, rm_si.rm_offset); #endif /* Install the real mode interrupt handler */ disable(); _go32_dpmi_get_real_mode_interrupt_vector(9, &oldirq_rm); _go32_dpmi_set_real_mode_interrupt_vector(9, &rm_si); enable(); #ifdef TEST printf("Real Mode Interrupt handler installed.\n"); #endif } /* Remove the real mode interrupt handler. */ void kb_cleanup_rm_interrupt() { disable(); _go32_dpmi_set_real_mode_interrupt_vector(9, &oldirq_rm); _go32_dpmi_free_real_mode_callback(&rm_si); enable(); #ifdef TEST printf("Real Mode Interrupt handler removed.\n"); #endif } /* Install our interrupt as the protected mode interrupt handler for the keyboard. */ void kb_install_pm_interrupt() { disable(); _go32_dpmi_get_protected_mode_interrupt_vector(9, &oldirq_pm); pm_si.pm_offset = (int) kb_intr; pm_si.pm_selector = _go32_my_cs(); _go32_dpmi_chain_protected_mode_interrupt_vector(9, &pm_si); enable(); #ifdef TEST printf("Protected Mode Interrupt handler installed.\n"); #endif } /* Remove our protected mode interrupt handler. */ void kb_cleanup_pm_interrupt() { disable(); _go32_dpmi_set_protected_mode_interrupt_vector(9, &oldirq_pm); enable(); #ifdef TEST printf("Protected Mode Interrupt handler removed.\n"); #endif } /* The main program */ int main(int argc, char **argv) { char ch; int i, done; requestToStop = 0; done = FALSE; kb_install_rm_interrupt(); kb_install_pm_interrupt(); printf("Starting...\n"); while ( !done ) { /* Normal processing proceeds... We'll just print dots! */ #ifdef TEST printf("."); #endif if ( requestToStop ) { /* Here is where to stop what you were doing. Clean up the interrupts so you can use "regular" keyboard routines. */ kb_cleanup_rm_interrupt(); kb_cleanup_pm_interrupt(); requestToStop = 0; printf("\nCommand: (Q)uit gracefully, (C)ontinue ==> "); fflush(stdout); ch = getch(); switch(ch) { case 'Q': case 'q': printf("Quit requested.\n"); printf("Will finish current process then quit.\n"); #ifdef TEST for (i=0; i<40; i++) { write(1, ".", 1); usleep(250000); } #endif done = TRUE; return 0; case 'C': case 'c': printf("Continuing..."); done = FALSE; break; default: printf("\nNo valid key was pressed.\a\n"); printf("Processing resumes...\n"); /* Resume processing */ done = FALSE; break; } if (!done) { kb_install_rm_interrupt(); kb_install_pm_interrupt(); } } /* no Request to stop.... Resume "normal" processing */ } exit(0); /* Probably shouldn't get here */ } -- ____________ --------------------------------------------------------| .:. ,;''|-- Warren Gill |.:' :.:' | Technical Services Engineer Unison Software 512/478-0611 811 Barton Springs Road warren_gill AT unison DOT com Austin, Texas 78704 USA ---------------"Semiconductors are part-time musicians"-----------------