home *** CD-ROM | disk | FTP | other *** search
/ Software Recommendations - 1998 Season 1 / DNBCD4.iso / share / DOS / ipxcopy / SRC.ZIP / SRC / CBREAK.C next >
Encoding:
C/C++ Source or Header  |  1996-09-11  |  4.7 KB  |  206 lines

  1. /*
  2.  
  3.    CBREAK.C
  4.  
  5. */
  6. #include <stdio.h>
  7. #include <dos.h>
  8. #include <conio.h>
  9. #include "cbreak.h"
  10.  
  11. #define CB_FAR far
  12.  
  13. #define BITSET(x, n) ( (((unsigned) x >> n) & 0x0001) == 1 ? 1 : 0 )
  14.  
  15. #define INT09   (0x0009)      /* Keyboard interrupt number */
  16. #define INT1B   (0x001B)      /* CTRL+C interrupt number */
  17. #define INT23   (0x0023)      /* CTRL+BREAK interrupt number */
  18.  
  19. #define ESC             (0x1B)        /* ASCII escape code */
  20. #define SPACE           (0x20)        /* ASCII space  code */
  21. #define SCANCODE_C      (0x2E)        /* Scan code for the "C" key */
  22. #define CTRL_OFF_MASK   (0xFB)        /* CTRL+C bit mask */
  23. #define CTRL_ON_MASK    (0x04)        /* CTRL+C bit mask */
  24.  
  25. #define KBDMEM  (0x0000041C)  /* Keybrd buffer tail pointer address */
  26. #define KBDBUF  (0x0000041E)  /* Keyboard buffer address */
  27. #define KBDFLAG (0x00000417)  /* Keyboard flag byte address */
  28.  
  29. #define KB_DATA 0x0060      /* Kbd port address  */
  30.  
  31.  
  32. /*-------------------------------------------------------------------------*/
  33. /*  Functions pointers */
  34.  
  35. void (interrupt CB_FAR *old_break_int09)(); /* Save old kbd handler */
  36. void (interrupt CB_FAR *old_break_int1B)(); /* Save old ^C  handler */
  37. void (interrupt CB_FAR *old_break_int23)(); /* Save old brk handler */
  38.  
  39. /*-------------------------------------------------------------------------*/
  40. unsigned short CB_FAR * kbd_buf;
  41. unsigned short CB_FAR * kbd_ctrl;
  42. unsigned short CB_FAR * kbd_tail;
  43.  
  44. /*-------------------------------------------------------------------------*/
  45. /* Interrupt service routines */
  46.  
  47.  
  48. void interrupt CB_FAR break_int09(void);
  49. void interrupt CB_FAR break_int1B(void);
  50. void interrupt CB_FAR break_int23(void);
  51.  
  52. /*-------------------------------------------------------------------------*/
  53.  
  54. unsigned break_sem;              /* ^C was pressed then sem=1, else sem=0 */
  55. unsigned break_installed = 0;
  56.  
  57. void break_Install(void)
  58. {
  59.    unsigned i;
  60.  
  61.    if ( break_installed != 0 )
  62.       return;
  63.  
  64.    old_break_int09 = _dos_getvect( INT09 );
  65.    old_break_int1B = _dos_getvect( INT1B );
  66.    old_break_int23 = _dos_getvect( INT23 );
  67.  
  68.    _dos_setvect( INT09, break_int09 );
  69.    _dos_setvect( INT1B, break_int1B );
  70.    _dos_setvect( INT23, break_int23 );
  71.  
  72.    kbd_tail  = (unsigned short CB_FAR *)(long)KBDMEM;
  73.    kbd_buf   = (unsigned short CB_FAR *)(long)KBDBUF;
  74.    kbd_ctrl  = (unsigned short CB_FAR *)(long)KBDFLAG;
  75.  
  76.    for(i = 0; i < 16; i++)
  77.       kbd_buf[i] = (unsigned) (0x3900 | SPACE);
  78.  
  79.    break_sem = 0;
  80.    break_installed = 1;
  81. }
  82.  
  83. void break_Remove(void)
  84. {
  85.    if ( break_installed == 0 )
  86.       return;
  87.  
  88.    _dos_setvect( INT09, old_break_int09 );
  89.    _dos_setvect( INT1B, old_break_int1B );
  90.    _dos_setvect( INT23, old_break_int23 );
  91.  
  92.    break_installed = 0;
  93. }
  94.  
  95. int break_IsCTRLC(void)
  96. {
  97.    return break_sem == 0 ? 0 : 1;
  98. }
  99.  
  100.  
  101. /*-------------------------------------------------------------------------*/
  102. /* Interrupt service routines */
  103.  
  104.  
  105. void interrupt CB_FAR break_int09( void )
  106. {
  107.    unsigned cell;       /* Data from kbd port 60h */
  108.    unsigned indx = 0;
  109.  
  110.    _disable();
  111.  
  112.    cell = inp( KB_DATA );
  113.  
  114.    break_sem = 0;
  115.    if ( BITSET(*kbd_ctrl, 2) && (cell & 0x0ff) == SCANCODE_C )
  116.    {
  117.       break_sem = 1;
  118.       indx = ( *kbd_tail - (KBDBUF & 0x0ff) ) / 2;
  119.       *kbd_ctrl &= CTRL_OFF_MASK;
  120.    }
  121.  
  122.    old_break_int09();
  123.  
  124.    if ( break_sem != 0 )
  125.    {
  126.       *kbd_ctrl |= CTRL_ON_MASK;
  127.       kbd_buf[indx] = CTRL_C_REPLACE;
  128.    }
  129. }
  130.  
  131.  
  132.  
  133. void interrupt CB_FAR break_int1B(void)
  134. {
  135.     /* New home for CTRL+C     */
  136. }
  137.  
  138.  
  139.  
  140. void interrupt CB_FAR break_int23(void)
  141. {
  142.     /* New Home for CTRL+BREAK */
  143. }
  144.  
  145.  
  146. /*-------------------------------------------------------------------------*/
  147.  
  148. /* #define break_main */
  149. #ifdef break_main
  150.  
  151. #define LOBYTE(x)  ( (unsigned char) ((unsigned) x & 0x00FF) )
  152.  
  153. void KbdHexDump( unsigned short CB_FAR *str )
  154. {
  155.    unsigned  j;
  156.  
  157.    printf("\n");
  158.    for( j=0; j < 16; j++ )
  159.    {
  160.       if ( LOBYTE(str[j]) < 15 )
  161.          printf("0");
  162.       if ( str[j] == CTRL_C_REPLACE )
  163.          printf("03 ");
  164.       else
  165.          printf("%x ", LOBYTE(str[j]));
  166.    }
  167.    printf("     ");
  168.    for( j=0; j < 16; j++ )
  169.    {
  170.       if ( LOBYTE(str[j]) < SPACE )
  171.          printf("%c", '.');
  172.       else
  173.          printf("%c", LOBYTE(str[j]));
  174.    }
  175.    printf("\n");
  176.  
  177. }
  178.  
  179.  
  180. #include <time.h>
  181. void main (void)
  182. {
  183.    unsigned ch;
  184.  
  185.    break_Install();
  186.  
  187.    ch = 0;
  188.  
  189.    while( ch != ESC )
  190.    {
  191.       printf("%ld\n", (long)clock());
  192.       ch = getch();
  193.       if ( ch == CTRL_C_REPLACE )
  194.          printf("\nCtrl-C value\n");
  195.  
  196.       if ( break_IsCTRLC() )
  197.          printf("\nCtrl-C key was pressed!\n");
  198.  
  199.       KbdHexDump( kbd_buf );
  200.    }
  201.  
  202.    break_Remove();
  203. }
  204.  
  205. #endif
  206.