home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!europa.asd.contel.com!emory!sol.ctr.columbia.edu!usc!rpi!bu.edu!dartvax!coos.dartmouth.edu!richard
- From: richard@coos.dartmouth.edu (Richard Brittain)
- Newsgroups: comp.os.msdos.programmer
- Subject: Keyboard reading via int 16, TurboC bioskey() routine, ctrl-BREAK
- Summary: What does bioskey() do in addition to calling int 16.
- Message-ID: <1992Nov6.043313.17388@dartvax.dartmouth.edu>
- Date: 6 Nov 92 04:33:13 GMT
- Sender: news@dartvax.dartmouth.edu (The News Manager)
- Organization: Dartmouth College, Hanover, NH
- Lines: 122
- Originator: richard@coos.dartmouth.edu
-
- Hi,
- I'm having a problem with a conflict between reading the keyboard via
- the bios int 16 interface and control-C and control-break. I
- originally used bioskey() from the TurboC v2.1 library, but that is
- written for old style keyboards and didn't seem to be totally happy
- with the command codes for the extended keyboard reads. I also
- discovered that it internally calls dos services to remap the int 1B
- vector (ctrl-brk) before making the int 16 call, so you cannot use it
- in an interrupt routine - I wanted to use this in a critical error
- handler.
-
- I wrote my own bioskey replacement, doing the remapping manually (to a
- no-op function declared type interrupt) and surrounded by
- disable()/enable(), and it seems to work fine for reading keys, except
- for ^C and ^break, which sometimes work and sometimes lock out further
- keyboard reads, and sometimes just crash the whole machine. This seems
- to behave slightly differently on the different machines I have access
- to , with different dos/4dos combinations. The original bioskey() does
- not have this problem.
- I need to be able to use this for keystroke checking in a
- running program i.e. non blocking reads.
-
- Any ideas as to what is happening would be appreciated. Any explanation of why
- it is necessary to remap int 1B would also be welcome.
-
-
- Thanks,
-
- Richard Brittain, Dept of Physics and Astronomy, Wilder Laboratory,
- Dartmouth College, Hanover NH 03755
- INTERNET: richard.brittain@dartmouth.edu
- SPAN: nsfgw::"richard@einstein.dartmouth.edu"
-
-
- The offending code follows
- /*
- * DISABLE_CBREAK will cause the bioskey() function to temporarily disable the
- * control-break interrupt . If using this, compilation/linking should have
- * use-registers=no and stack-warning=no. The Borland bioskey() does this but
- * I don't know why.
- *
- */
-
- #ifdef KEY101
- #define GETKEY 0x10 /* 0x10 extended keyboards, 0x00 old keyboards */
- #define GETKEYTEST 0x11 /* 0x11 extended keyboards, 0x01 old keyboards */
- #else
- #define GETKEY 0x00
- #define GETKEYTEST 0x01
- #endif
- #define GETSHIFT 0x02
-
-
- #ifdef DISABLE_CBREAK
- void interrupt cbreak_ignore();
-
- void interrupt cbreak_ignore()
- {
- return;
- }
- #endif
-
- int bioskey(int cmd)
- {
- /*
- * Replace bioskey() in TurboC library. Allows for extended keyboard reads
- * Use this for keyboard read functions 00,01,02,10,11,12 (Hex)
- * This routine also saves and restores the ^BREAK interrupt (1B) without
- * using DOS, so is safe to use in interrupt service routines. The Borland
- * library version of bioskey() seems to do this, but I'm not sure why.
- */
- #define FLAG_ZF 0x40
- union REGS regs;
-
- #ifdef DISABLE_CBREAK
- unsigned int cbreak_off, cbreak_seg;
- void far *fp;
- /*
- * temporarily disable the int 1B (^BREAK) routine by poking the
- * address of a no-op function into the interrupt table
- */
- #if defined(__TINY__) || defined(__SMALL__) || defined(__COMPACT__)
- fp = MK_FP(_CS, cbreak_ignore);
- #else
- fp = cbreak_ignore;
- #endif
- cbreak_off = peek(0x00,0x6C);
- cbreak_seg = peek(0x00,0x6E);
- disable();
- poke(0x00,0x6C,FP_OFF(fp));
- poke(0x00,0x6E,FP_SEG(fp));
- enable();
- #endif
- /* call the keyboard system service with the desired operation */
- regs.h.ah = (unsigned char)cmd;
- int86(0x16,®s,®s);
-
- #ifdef DISABLE_CBREAK
- /* replace the original int 1B routine */
- disable();
- poke(0x00,0x6C,cbreak_off);
- poke(0x00,0x6E,cbreak_seg);
- enable();
- #endif
- /* return keypress */
- switch(cmd) {
- case GETKEYTEST:
- /* Test zero flag - return 0 if not set, otherwise return ax */
- if ((regs.x.flags & FLAG_ZF) == 0) {
- return(regs.x.ax);
- } else {
- return(0);
- }
- case GETSHIFT:
- /* zero out the high byte */
- regs.h.ah = 0;
- return(regs.x.ax);
- default:
- /* all other functions, return ax */
- return(regs.x.ax);
- }
- }
-