home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 10 / 10.iso / l / l352 / 1.img / EXAMPLES / KEYS.C < prev    next >
Encoding:
C/C++ Source or Header  |  1991-08-06  |  2.9 KB  |  105 lines

  1. /* 
  2. KEYS.C -- demonstrate use of BIOS data area in 286|DOS-Extender
  3.  
  4. Borland C++ protected mode:     
  5.     bcc286 keys.c
  6.     keys
  7. */
  8.  
  9. #include <stdlib.h>
  10. #include <stdio.h>
  11. #include <conio.h>
  12.  
  13. #ifdef DOSX286
  14. #include <phapi.h>
  15. #else
  16. typedef unsigned char UCHAR;
  17. typedef unsigned USHORT;
  18. typedef unsigned long ULONG;
  19. #endif
  20.  
  21. #ifdef DOSX286
  22. #if defined(_MSC_VER) && (_MSC_VER >= 600)
  23. /*
  24.     Microsoft C 6.0 - 
  25.     We use based variables, which are perfect for mapped selectors
  26.     in 286|DOS-Extender, and much nicer to work with than either
  27.     the MAKEP() or MK_FP() macros.
  28. */
  29. _segment bios;
  30. #define TICKS()             (*((ULONG _based(bios) *) 0x6C))
  31. #define KB_STAT             (*((UCHAR _based(bios) *) 0x17))
  32. #define KB_HEAD             (*((USHORT _based(bios) *) 0x1A))
  33. #define KB_TAIL             (*((USHORT _based(bios) *) 0x1C))
  34. #else
  35. /*
  36.     Microsoft C 5.1 -
  37.     For protected mode, instead of using hard-wired addresses such
  38.     as 0x46C (0040:006C), we use the MAKEP() macro to create a far
  39.     pointer containing the selector returned from DosGetBIOSSeg(),
  40.     plus the offset from the beginning of the BIOS data area.
  41. */
  42. unsigned bios;
  43. #define TICKS()             (*((ULONG far *) MAKEP(bios, 0x6C)))
  44. #define KB_STAT             (*((UCHAR far *) MAKEP(bios, 0x17)))
  45. #define KB_HEAD             (*((USHORT far *) MAKEP(bios, 0x1A)))
  46. #define KB_TAIL             (*((USHORT far *) MAKEP(bios, 0x1C)))
  47. #endif
  48. #else
  49. // note that in real mode, 0000:046C is equivalent to 0040:006C
  50. #define TICKS()             (*((ULONG far *) 0x46C))
  51. #define KB_STAT             (*((UCHAR far *) 0x417))
  52. #define KB_HEAD             (*((USHORT far *) 0x41A))
  53. #define KB_TAIL             (*((USHORT far *) 0x41C))
  54. #endif
  55.  
  56. #define KB_HIT()            (KB_HEAD != KB_TAIL)
  57. #define CTRL()              (KB_STAT & 4)
  58. #define ALT()               (KB_STAT & 8)
  59.  
  60. #define ESC                 0x1B
  61.  
  62. void fail(char *s, unsigned ret)
  63. {
  64.     printf("%s ret=%04X (%u)\n", s, ret, ret);
  65.     exit(ret);
  66. }
  67.  
  68. main()
  69. {
  70.     USHORT ret;
  71.     int done = 0;
  72.     int c;
  73.     
  74. #ifdef DOSX286
  75.     /*
  76.         Notice that DosGetBIOSSeg() is called only once, at the 
  77.         beginning of the program. We can then freely use the 
  78.         selector for as long as we want.
  79.     */
  80.     if ((ret = DosGetBIOSSeg((PSEL) &bios)) != 0)
  81.         fail("DosGetBIOSSeg - failure", ret);
  82. #endif
  83.  
  84.     /* Note: Ctrl-Esc probably not a good choice: used by Windows too! */
  85.     puts("Press keys; Ctrl-Esc to quit");
  86.     while (! done)
  87.         if (KB_HIT())
  88.         {
  89.             c = getch();
  90.             printf("TIME=%-8lX ST=%02X CHAR=%02X ", TICKS(), KB_STAT, c);
  91.             if (c == 0)
  92.                 printf("%02X", getch());  /* extended character */
  93.             printf("\n");
  94.             if ((c == ESC) && CTRL()) /* Ctrl-ESC */ 
  95.                 break;
  96.     }
  97.     
  98. #ifdef DOSX286
  99.     /* Do _NOT_ DosFreeSeg(bios) ! */
  100. #endif
  101.  
  102.     puts("bye");
  103.     return 0;
  104. }
  105.