delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1997/04/28/09:18:48

Newsgroups: comp.os.msdos.djgpp
From: cgouldie AT wt DOT net (Chris Gouldie)
Subject: Re: Keyboard Handlers
Date: Mon, 28 Apr 1997 00:06:00 GMT
Message-ID: <cgouldie.2.3363E9E5@wt.net>
Lines: 361
References: <Pine DOT SUN DOT 3 DOT 91 DOT 970422093604 DOT 28433B-100000 AT chris>
Organization: World Trade Network
NNTP-Posting-Host: 206.139.154.211
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp

In article <Pine DOT SUN DOT 3 DOT 91 DOT 970422093604 DOT 28433B-100000 AT chris> Andy Eder <sp1edea AT doc DOT ntu DOT ac DOT uk> writes:

>Can somebody please help ? I am attempting to implement my own keyboard 
>handler and I cannot get it to work. My system either crashes or locks 
>up. As this is my first attempt at such things, I don't know where I am 
>going wrong.

>void RemoveKeyboard()
>   {
>   _go32_dpmi_set_protected_mode_interrupt_vector(0x09,&Old_Handler);
you need 
    _go32_dpmi_free_iret_wrapper (&new_handler);
for one thing.

>   }
>     

>Any suggestions ???

>Thanks,
>Andy

>Andy - cc505870 AT ntu DOT ac DOT uk

Here's my handler. Works good, and I supplied an example prog with it. Feel 
free to do anything you want with it.

/*file kb.cc*/

#include <dpmi.h>
#include <shorts.def>

char keynames [106] [16] =
{"", "Escape", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "-", "=",
"Backspace", "Tab", "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "[",
"]", "Enter", "Left Control", "A", "S", "D", "F", "G", "H", "J", "K", "L",
";", "'", "`", "Left Shift", "\\", "Z", "X", "C", "V", "B", "N", "M", ",",
".", "/", "Right Shift", "* (Keypad)", "Left Alt", "Space Bar", "Caps Lock",
"F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "Num Lock",
"Scroll Lock", "7 (Keypad)", "8 (Keypad)", "9 (Keypad)", "- (Keypad)",
"4 (Keypad)", "5 (Keypad)", "6 (Keypad)", "+ (Keypad)", "1 (Keypad)",
"2 (Keypad)", "3 (Keypad)", "0 (Keypad)", ". (Keypad)", "Print Screen",
"", "", "F11", "F12", "Enter (Keypad)", "Right Control", "/ (Keypad)",
"Right Alt", "Home", "Up Arrow", "Page up", "Left Arrow", "Right Arrow",
"End", "Down Arrow", "Page Down", "Insert", "Delete", "Pause", "Macro",
 "Control-Break"};

uchar xkey_tbl [84] =
{ 89, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 91, 0, 84, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 105, 93, 94, 95,
  0, 96, 0, 97, 0, 98, 99, 100, 101, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ,0 ,0 ,0 , 104};

_go32_dpmi_seginfo old_kb_handler, new_kb_handler;

int keyvent;

uchar key_queue [30];

uchar keys_pressed_table [256];

int skip_pause_bytes = 0, jump_bytes = 0, paused = 0, ex_key_next = 0;
int kq_head, kq_tail;

void clear_key_table ()
{ for (int i = 0; i < 106; keys_pressed_table [i++] = 0); }

void clear_key_queue ()
{ for (int i = 0; i < 30; key_queue [i++] = 0); }

void kb_handler ()
{ asm ("cli                                           \n\t"
       "xorl    %edx, %edx                            \n\t"
       "xorl    %eax, %eax                            \n\t"
       "xorl    %ebx, %ebx                            \n\t"
       "inb     $0x60, %al                            \n\t"
       "movb    %al, %bl                              \n\t"
       "cmpl    $0, _skip_pause_bytes                 \n\t"
       "je      no_pause                              \n\t"
       "decl    _skip_pause_bytes                     \n\t"
       "jne     kb_end                                \n\t"
       "movb    $1, _keys_pressed_table+103           \n\t"
       "movb    $103, %bl                             \n\t"
       "jmp     enque                                 \n\t"
       "no_pause:                                     \n\t"
       "cmpl    $0, _ex_key_next                      \n\t"
       "je      reg_key                               \n\t"
       "movl    $0, _ex_key_next                      \n\t"
       "cmpb    $70, %al                              \n\t"
       "jne     not_control_break                     \n\t"
       "movl    $2, _jump_bytes                       \n\t"
       "cmpb    $0, _keys_pressed_table+105           \n\t"
       "jne     zero_break_flag                       \n\t"
       "movb    $1, _keys_pressed_table+105           \n\t"
       "movb    $105, %bl                             \n\t"
       "jmp     enque                                 \n\t"
       "zero_break_flag:                              \n\t"
       "movb    $0, _keys_pressed_table+105           \n\t"
       "movb    $233, %bl                             \n\t"
       "jmp     enque                                 \n\t"
       "not_control_break:                            \n\t"
       "cmpb    $198, %al                             \n\t"
       "je      kb_end                                \n\t"
       "cmpb    $42, %al                              \n\t"
       "je      kb_end                                \n\t"
       "cmpb    $170, %al                             \n\t"
       "je      kb_end                                \n\t"
       "movb    $1, %cl                               \n\t"
       "movb    $0, %bl                               \n\t"
       "testb   $128, %al                             \n\t"
       "je      ex_key_down                           \n\t"
       "andl    $0x7F, %eax                           \n\t"
       "xorl    %ecx, %ecx                            \n\t"
       "movb    $128, %bl                             \n\t"
       "ex_key_down:                                  \n\t"
       "subb    $28, %al                              \n\t"
       "movb    _xkey_tbl(%eax), %dl                  \n\t"
       "addb    %dl, %bl                              \n\t"
       "movb    %cl, _keys_pressed_table(%edx)        \n\t"
       "movb    $0, _keys_pressed_table+103           \n\t"
       "jmp     enque                                 \n\t"
       "reg_key:                                      \n\t"
       "cmpb    $225, %al                             \n\t"
       "jne     not_pause                             \n\t"
       "movl    $5, _skip_pause_bytes                 \n\t"
       "jmp     kb_end                                \n\t"
       "not_pause:                                    \n\t"
       "cmpb    $224, %al                             \n\t"
       "jne     not_extended                          \n\t"
       "movl    $1, _ex_key_next                      \n\t"
       "movb    $0, _keys_pressed_table+103           \n\t"
       "jmp     kb_end                                \n\t"
       "not_extended:                                 \n\t"
       "movb    $1, %cl                               \n\t"
       "testb   $128, %al                             \n\t"
       "je      key_down                              \n\t"
       "xorl    %ecx, %ecx                            \n\t"
       "andb    $0x7F, %al                            \n\t"
       "key_down:                                     \n\t"
       "movb    %cl, _keys_pressed_table(%eax)        \n\t"
       "movb    $0, _keys_pressed_table+103           \n\t"
       "enque:                                        \n\t"
       "movl    _kq_tail, %eax                        \n\t"
       "movb    %bl, _key_queue(%eax)                 \n\t"
       "incl    _kq_tail                              \n\t"
       "cmpl    $30, _kq_tail                         \n\t"
       "jne     kb_end                                \n\t"
       "movb    $0, _kq_tail                          \n\t"
       "kb_end:                                       \n\t"
       "movb    $0x20, %al                            \n\t"
       "outb    %al, $0x20                            \n\t"
       "sti                                           \n\t"
       );
}

void install_kb_handler ()
{ new_kb_handler.pm_offset = ulong (kb_handler);
  new_kb_handler.pm_selector = _go32_my_cs ();
  _go32_dpmi_get_protected_mode_interrupt_vector (9, &old_kb_handler);
  _go32_dpmi_lock_code (kb_handler, install_kb_handler - kb_handler);
  _go32_dpmi_allocate_iret_wrapper (&new_kb_handler);
  _go32_dpmi_set_protected_mode_interrupt_vector (9, &new_kb_handler);
  clear_key_table ();
  clear_key_queue ();
}

int empty_key_queue ()
{ return ( kq_head == kq_tail); }

uchar get_queued_key ()
{ uchar key_event = key_queue [kq_head];
  kq_head++;
  if (kq_head == 30) kq_head = 0;
  return (key_event);
}

void cleanup_kb_handler ()
{ _go32_dpmi_free_iret_wrapper (&new_kb_handler);
  _go32_dpmi_set_protected_mode_interrupt_vector (9, &old_kb_handler);
}

int ispressed (int whichkey)
{ return (keys_pressed_table [whichkey]); }

/*file testkb.cc*/

#include <iostream.h>
#include <conio.h>
#include <shorts.def>
#include <kbint.h>
#include <defkeys.h>
#include <sys/nearptr.h>
#include <pc.h>

char ch = null_key;

void wait_retrace ()
{ while (inportb (0x03DA) & 8);
  while (!(inportb (0x03DA) & 8));
}

void pause_routine ()
{ char *screen_ptr = (char *)(__djgpp_conventional_base + 0xB8000);
  int x_pos = 0, y_pos = 1, xdir = 1, ydir = 1, oldx_pos = 0, oldy_pos = 1;
  while (ispressed (pause_key))
  { wait_retrace ();
    for (int index2 = 0; index2 < 5; index2++ )
      screen_ptr [oldy_pos*160 + oldx_pos*2 + index2*2] = 32;
    oldx_pos = x_pos;
    oldy_pos = y_pos;
    for (int index1 = 0; index1 < 5; index1++ )
      screen_ptr [y_pos*160 + x_pos*2 + index1*2] =
        keynames [pause_key] [index1];
    x_pos += xdir;
    y_pos += ydir;
    if (x_pos == 74 || x_pos == 0) xdir = -xdir;
    if (y_pos == 24 || y_pos == 0) ydir = -ydir;
    if (!empty_key_queue ()) ch = get_queued_key ();
  }
}

void main ()
{ if (__djgpp_nearptr_enable ())
  { install_kb_handler ();
    while (ch != escape_key)
    { clrscr ();
      cout << "Keys Pressed:" <<"\n";
      for (int index = 1; index < 106; index++)
      if (ispressed (index)) cout << keynames [index] << "\n";
      while (empty_key_queue ());
      ch = get_queued_key ();
      if (ch == pause_key) pause_routine ();
    }
    cleanup_kb_handler ();
    __djgpp_nearptr_disable ();
  }
}

/*file kbint.h*/

extern uchar keys_pressed_table [106];
extern void install_kb_handler ();
extern void cleanup_kb_handler ();
extern int ispressed (int whichkey);
extern int empty_key_queue ();
extern uchar get_queued_key ();
extern char keynames [106] [16];

/*file shorts.def*/

typedef unsigned char uchar;
typedef unsigned short ushort;
typedef unsigned int uint;
typedef unsigned long ulong;

/*file defkeys.h*/

#define null_key 0
#define escape_key 1
#define one_key 2
#define two_key 3
#define three_key 4
#define four_key 5
#define five_key 6
#define six_key 7
#define seven_key 8
#define eight_key 9
#define nine_key 10
#define ten_key 11
#define minus_key 12
#define equal_key 13
#define backspace_key 14
#define tab_key 15
#define q_key 16
#define w_key 17
#define e_key 18
#define r_key 19
#define t_key 20
#define y_key 21
#define u_key 22
#define i_key 23
#define o_key 24
#define p_key 25
#define left_brace_key 26
#define right_brace_key 27
#define enter_key 28
#define left_control_key 29
#define a_key 30
#define s_key 31
#define d_key 32
#define f_key 33
#define g_key 34
#define h_key 35
#define j_key 36
#define k_key 37
#define l_key 38
#define semicolon_key 39
#define apostrophe_key 40
#define tilda_key 41
#define left_shift_key 42
#define backslash_key 43
#define z_key 44
#define x_key 45
#define c_key 46
#define v_key 47
#define b_key 48
#define n_key 49
#define m_key 50
#define comma_key 51
#define period_key 52
#define slash_key 53
#define right_shift_key 54
#define keypad_asterisk 55
#define left_alt_key 56
#define space_bar 57
#define caps_lock_key 58
#define f1_key 59
#define f2_key 60
#define f3_key 61
#define f4_key 62
#define f5_key 63
#define f6_key 64
#define f7_key 65
#define f8_key 66
#define f9_key 67
#define f10_key 68
#define keypad_num_lock 69
#define scroll_lock_key 70
#define keypad_7 71
#define keypad_8 72
#define keypad_9 73
#define keypad_minus 74
#define keypad_4 75
#define keypad_5 76
#define keypad_6 77
#define keypad_plus 78
#define keypad_1 79
#define keypad_2 80
#define keypad_3 81
#define keypad_0 82
#define keypad_period 83
#define print_screen_key 84
#define f11_key 87
#define f12_key 88
#define keypad_enter 89
#define right_control_key 90
#define keypad_slash 91
#define right_alt_key 92
#define home_key 93
#define up_key 94
#define page_up_key 95
#define left_key 96
#define right_key 97
#define end_key 98
#define down_key 99
#define page_down_key 100
#define insert_key 101
#define delete_key 102
#define pause_key 103
#define macro_key 104
#define control_break 105

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019