delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1994/07/15/22:17:27

From: Warren Gill <gill AT unison DOT com>
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 <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 -


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