Mail Archives: djgpp/1994/07/15/22:17:27
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 <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <go32.h>
#include <dos.h>
#include <keys.h>
#include <dpmi.h>
#include <string.h>
#include <pc.h>
#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"-----------------
- Raw text -