home *** CD-ROM | disk | FTP | other *** search
/ synchro.net / synchro.net.tar / synchro.net / night.owl.13 / 044A / KBGUID11.ZIP / KBFUNC.C < prev    next >
Encoding:
C/C++ Source or Header  |  1994-05-23  |  4.6 KB  |  173 lines

  1. /* KBFunc.c */
  2. /* Demonstrates the use of the keyboard and defines some functions */
  3. /* Copyright (c) 1994 Gertjan Klein */
  4. /* Freeware. See also legal information in kbguide.txt */
  5.  
  6.  
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <dos.h>
  10.  
  11. int KeybID(void);
  12. int ScanSet(int);
  13. int WaitForKeyb(void);
  14. void PrintKeys(int);
  15.  
  16. main(int argc, char **argv)
  17. {
  18.   int result, set;
  19.  
  20.   set = atoi(argv[1]);
  21.   if( (argc < 2) | (set > 3) | (set < 1) )
  22.  
  23.   {
  24.     puts("Usage: KEYBID <1..3>");
  25.     exit(1);
  26.   }
  27.   result = KeybID();              /*Determine keyboard type*/
  28.   switch (result)
  29.   {
  30.   case 0 :
  31.     puts("\nThis is an XT keyboard.");
  32.     break;
  33.   case 1 :
  34.     puts("\nThis is an AT keyboard.");
  35.     break;
  36.   case 2 :
  37.     puts("\nThis is an MF II keyboard.");
  38.     break;
  39.   default:
  40.     puts("\nError determining keyboard.");
  41.   }
  42.   if( (result == 1) | (result == 2) )
  43.   {                      /*AT or MF II keyboard: can set scanset*/
  44.     if( ScanSet(set) )              /*If scanset set succesfully*/
  45.     {
  46.       printf("Scanset set to %d\n", set);
  47.       PrintKeys(set);              /*Print hex codes of keys pressed*/
  48.     }
  49.     puts("");                  /*Newline*/
  50.     ScanSet(2);               /*Normal scanset back (is 2!)*/
  51.   }
  52. }
  53.  
  54. int KeybID(void)
  55. {
  56.   int ret_code;
  57.  
  58.   outp(0x21, 0x02);              /*Block IRQ1*/
  59.   outp(0x60, 0xf2);              /*Give command*/
  60.   if( ! WaitForKeyb() )
  61.     ret_code = 0;              /*XT-keyboard*/
  62.   else
  63.   {
  64.     if( inp(0x60) != 0xfa )
  65.       ret_code = 4;              /*No ACK: error*/
  66.     else
  67.     {
  68.       if( ! WaitForKeyb() )
  69.     ret_code = 1;              /*No ID byte: normal AT keyboard*/
  70.       else
  71.       {
  72.     if( inp(0x60) != 0xab)
  73.       ret_code = 5;           /*Unknown ID byte: error*/
  74.     else
  75.     {
  76.       if( ! WaitForKeyb() )
  77.         ret_code = 6;          /*No second ID byte: error*/
  78.       else
  79.       {
  80.         if( inp(0x60) != 0x41 )
  81.           ret_code = 7;          /*Unknown second ID byte: error*/
  82.         else
  83.           ret_code = 2;          /*MF II keyboard*/
  84.       }
  85.     }
  86.       }
  87.     }
  88.   }
  89.   outp(0x21,0x00);              /*Reenable IRQ1*/
  90.   return(ret_code);
  91. }
  92.  
  93. int ScanSet(set)
  94. {
  95.   int result;
  96.  
  97.   outp(0x21, 0x02);              /*Block IRQ1*/
  98.   outp(0x60, 0xf0);              /*Give command*/
  99.   if( WaitForKeyb() )              /*If keyboard responded*/
  100.   {
  101.     if( inp(0x60) == 0xfa)          /*If response was ACK*/
  102.     {
  103.       outp(0x60,set);              /*Send scanset to use*/
  104.       if( WaitForKeyb() )          /*If keyboard responded*/
  105.       {
  106.     if( inp(0x60) == 0xfa)          /*If response was ACK*/
  107.       result = 1;              /*Then scanset set properly*/
  108.     else result = 0;          /*Wrong ACK: error*/
  109.       }
  110.       else result = 0;              /*No ACK: error*/
  111.     }
  112.     else result = 0;              /*Wrong ACK: error*/
  113.   }
  114.   else result = 0;              /*No ACK: error*/
  115.   outp(0x21,0x00);              /*Reenable IRQ1*/
  116.   return(result);
  117. }
  118.  
  119. int WaitForKeyb(void)
  120. {
  121.   unsigned i;
  122.   int tmp;
  123.   for(i=0; i < 0xffff; i++)          /*Reasonable waiting loop*/
  124.   {
  125.     tmp = inp(0x64);              /*Get status port*/
  126.     if( (tmp & 0x01) == 0x01 )          /*If char waiting in buffer*/
  127.       return(tmp & 0x01);          /*Go back*/
  128.   }
  129.   return(tmp & 0x01);              /*No char after waiting: go back*/
  130. }
  131.  
  132. void PrintKeys(int set)
  133. {
  134.   int cnt = 0, ch, esc = 0, loop = 1;
  135.  
  136.     outp(0x21,0x02);            /*Turn off IRQ1*/
  137.     while( (inp(0x64) & 0x01) == 0x01)  /*Kill any chars waiting for us*/
  138.         ch = inp(0x60);         /*(Start clean)*/
  139.   do                      /*Do until ESC key pressed*/
  140.   {
  141.     for(;;)                  /*Eternal loop*/
  142.       if( (inp(0x64) & 0x01) == 0x01 )
  143.     break;                  /*Unless key in buffer*/
  144.     printf("%02X ", (ch = inp(0x60)) );   /*Print it*/
  145.     switch (set)              /*Check for ESC*/
  146.     {
  147.       case 1:                  /*Scanset 1 seq. for ESC: 0x43 0x00*/
  148.     if( (ch == 0x43) && (esc == 0) )      /*If make code found*/
  149.       esc = 1;                  /*Remember*/
  150.     else if( (ch == 0x00) && (esc == 1) ) /*If break after make found*/
  151.       loop = 0;              /*User wants out*/
  152.     else esc = 0;
  153.     break;
  154.       case 2:                  /*Scanset 2 seq. for ESC: 0x01 0x81 */
  155.     if( (ch == 01) && (esc == 0) )          /*If make code found*/
  156.       esc = 1;                  /*Remember*/
  157.     else if( (ch == 0x81) && (esc == 1) ) /*If break after make found*/
  158.       loop = 0;              /*User wants out*/
  159.     else esc = 0;
  160.     break;
  161.       case 3:                  /*Scanset 3: 0x64 (no break) for ESC*/
  162.     if(ch == 0x64)              /*If ESC key pressed*/
  163.       loop = 0;              /*User wants out*/
  164.     break;
  165.     }
  166.     if( ++cnt == 24 )              /*If we've placed 24 numbers on screen*/
  167.     {
  168.       cnt = 0;                  /*Its time for a*/
  169.       puts("");               /*New line*/
  170.     }
  171.   }while(loop);
  172.   outp(0x21,0x00);              /*Reenable IRQ1*/
  173. }