home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #26 / NN_1992_26.iso / spool / comp / os / msdos / programm / 10372 < prev    next >
Encoding:
Text File  |  1992-11-06  |  4.3 KB  |  135 lines

  1. Path: sparky!uunet!europa.asd.contel.com!emory!sol.ctr.columbia.edu!usc!rpi!bu.edu!dartvax!coos.dartmouth.edu!richard
  2. From: richard@coos.dartmouth.edu (Richard Brittain)
  3. Newsgroups: comp.os.msdos.programmer
  4. Subject: Keyboard reading via int 16, TurboC bioskey() routine, ctrl-BREAK
  5. Summary: What does bioskey() do in addition to calling int 16.
  6. Message-ID: <1992Nov6.043313.17388@dartvax.dartmouth.edu>
  7. Date: 6 Nov 92 04:33:13 GMT
  8. Sender: news@dartvax.dartmouth.edu (The News Manager)
  9. Organization: Dartmouth College, Hanover, NH
  10. Lines: 122
  11. Originator: richard@coos.dartmouth.edu
  12.  
  13. Hi,
  14. I'm having a problem with a conflict between reading the keyboard via
  15. the bios int 16 interface and control-C and control-break.  I
  16. originally used bioskey() from the TurboC v2.1 library, but that is
  17. written for old style keyboards and didn't seem to be totally happy
  18. with the command codes for the extended keyboard reads.  I also
  19. discovered that it internally calls dos services to remap the int 1B
  20. vector (ctrl-brk) before making the int 16 call, so you cannot use it
  21. in an interrupt routine - I wanted to use this in a critical error
  22. handler.
  23.  
  24. I wrote my own bioskey replacement, doing the remapping manually (to a
  25. no-op function declared type interrupt) and surrounded by
  26. disable()/enable(), and it seems to work fine for reading keys, except
  27. for ^C and ^break, which sometimes work and sometimes lock out further
  28. keyboard reads, and sometimes just crash the whole machine.  This seems
  29. to behave slightly differently on the different machines I have access
  30. to , with different dos/4dos combinations.  The original bioskey() does
  31. not have this problem.
  32. I need to be able to use this for keystroke checking in a
  33. running program i.e. non blocking reads.
  34.  
  35. Any ideas as to what is happening would be appreciated.  Any explanation of why 
  36. it is necessary to remap int 1B would also be welcome.
  37.  
  38.  
  39. Thanks,
  40.  
  41. Richard Brittain,        Dept of Physics and Astronomy, Wilder Laboratory, 
  42.                          Dartmouth College, Hanover NH 03755
  43. INTERNET: richard.brittain@dartmouth.edu
  44. SPAN:     nsfgw::"richard@einstein.dartmouth.edu"
  45.  
  46.  
  47. The offending code follows
  48. /*
  49.  *  DISABLE_CBREAK will cause the bioskey() function to temporarily disable the
  50.  *  control-break interrupt .  If using this, compilation/linking should have
  51.  *  use-registers=no and stack-warning=no.  The Borland bioskey() does this but
  52.  *  I don't know why.
  53.  *
  54.  */
  55.  
  56. #ifdef KEY101
  57.   #define GETKEY        0x10 /* 0x10 extended keyboards, 0x00 old keyboards */
  58.   #define GETKEYTEST    0x11 /* 0x11 extended keyboards, 0x01 old keyboards */
  59. #else
  60.   #define GETKEY        0x00
  61.   #define GETKEYTEST    0x01
  62. #endif
  63. #define    GETSHIFT        0x02
  64.  
  65.  
  66. #ifdef DISABLE_CBREAK
  67. void interrupt cbreak_ignore();
  68.  
  69. void interrupt cbreak_ignore()
  70. {
  71.     return;
  72. }
  73. #endif
  74.  
  75. int  bioskey(int cmd)
  76. {
  77. /*
  78.  * Replace bioskey() in TurboC library.  Allows for extended keyboard reads
  79.  * Use this for keyboard read functions 00,01,02,10,11,12 (Hex)
  80.  * This routine also saves and restores the ^BREAK interrupt (1B) without
  81.  * using DOS, so is safe to use in interrupt service routines.  The Borland
  82.  * library version of bioskey() seems to do this, but I'm not sure why.
  83.  */
  84. #define FLAG_ZF 0x40
  85.     union REGS regs;
  86.  
  87. #ifdef DISABLE_CBREAK
  88.     unsigned int cbreak_off, cbreak_seg;
  89.     void far *fp;
  90.     /*
  91.      * temporarily disable the int 1B (^BREAK) routine by poking the
  92.      * address of a no-op function into the interrupt table
  93.      */
  94.     #if defined(__TINY__) || defined(__SMALL__) || defined(__COMPACT__)
  95.      fp = MK_FP(_CS, cbreak_ignore);
  96.     #else
  97.      fp = cbreak_ignore;
  98.     #endif
  99.     cbreak_off = peek(0x00,0x6C);
  100.     cbreak_seg = peek(0x00,0x6E);
  101.     disable();
  102.     poke(0x00,0x6C,FP_OFF(fp));
  103.     poke(0x00,0x6E,FP_SEG(fp));
  104.     enable();
  105. #endif
  106.     /* call the keyboard system service with the desired operation */
  107.     regs.h.ah = (unsigned char)cmd;
  108.     int86(0x16,®s,®s);
  109.  
  110. #ifdef DISABLE_CBREAK
  111.     /* replace the original int 1B routine */
  112.     disable();
  113.     poke(0x00,0x6C,cbreak_off);
  114.     poke(0x00,0x6E,cbreak_seg);
  115.     enable();
  116. #endif
  117.     /* return keypress */
  118.     switch(cmd) {
  119.         case GETKEYTEST:
  120.             /* Test zero flag - return 0 if not set, otherwise return ax */
  121.             if ((regs.x.flags & FLAG_ZF) == 0) {
  122.                 return(regs.x.ax);
  123.             } else {
  124.                 return(0);
  125.             }
  126.         case GETSHIFT:
  127.             /* zero out the high byte */
  128.             regs.h.ah = 0;
  129.             return(regs.x.ax);
  130.         default:
  131.             /* all other functions, return ax */
  132.             return(regs.x.ax);
  133.     }
  134. }
  135.