#include <dpmi.h>

_go32_dpmi_seginfo oldkeyinfo,newkeyinfo;
volatile char nextkeyextended;
volatile char keydown[128];
volatile char extendedkeydown[128];
void initkeyhandler();
void killkeyhandler();
void keyhandler();

void initkeyhandler()
{
      int i;

      for (i=0;i<128;i++)
      {
            keydown[i]=0;
            extendedkeydown[i]=0;
      }
      nextkeyextended=0;

      asm("cli");
      _go32_dpmi_get_protected_mode_interrupt_vector(9, &oldkeyinfo);
      newkeyinfo.pm_offset=(int)keyhandler;
      newkeyinfo.pm_selector=_go32_my_cs();
      _go32_dpmi_allocate_iret_wrapper(&newkeyinfo);
      _go32_dpmi_set_protected_mode_interrupt_vector(9, &newkeyinfo);
      asm("sti");
}

void killkeyhandler()
{
      asm("cli");
      _go32_dpmi_set_protected_mode_interrupt_vector(9, &oldkeyinfo);
      _go32_dpmi_free_iret_wrapper(&newkeyinfo);
      asm("sti");
}

void keyhandler()
{
      unsigned char keyhandlercurrkey;

      asm("cli");
      keyhandlercurrkey=inportb(0x60);

      if (nextkeyextended)
      {
            if ((keyhandlercurrkey&0x80)==0)
                extendedkeydown[keyhandlercurrkey&0x7f]=1;
            else
                extendedkeydown[keyhandlercurrkey&0x7f]=0;
            nextkeyextended=0;
      }
      else
      {
      if ((keyhandlercurrkey&0x80)==0)
          keydown[keyhandlercurrkey&0x7f]=1;
      else
          keydown[keyhandlercurrkey&0x7f]=0;
      }

      if (keyhandlercurrkey==0xe0)
          nextkeyextended=1;

      if ((keydown[0x1d])&&(keyhandlercurrkey==0x2e))
      {
            asm ("movb $0x79, %%al
                    call ___djgpp_hw_exception"
             : : :"%eax","%ebx","%ecx","%edx","%esi","%edi","memory");
      }

      //reset keyboard
      {
            char b;
            b=inportb(0x61);
            outportb(0x61,b|80);
            outportb(0x61,b);
            outportb(0x20,0x20);
      }
      asm("sti");
}

int iskeydown()
{
       int count;

       asm("cli");
       for(count=0;count<128;count++)
               if(keydown[count]) return 1;
       asm("sti");

       return 0;
}
