root/kernel/chr_drv/keyboard.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. kb_wait
  2. keyboard_interrupt
  3. put_queue
  4. puts_queue
  5. ctrl
  6. alt
  7. unctrl
  8. unalt
  9. lshift
  10. unlshift
  11. rshift
  12. unrshift
  13. caps
  14. uncaps
  15. show_ptregs
  16. scroll
  17. num
  18. applkey
  19. sysreq
  20. do_self
  21. handle_diacr
  22. cursor
  23. cur
  24. func
  25. slash
  26. star
  27. enter
  28. minus
  29. plus
  30. none
  31. send_data
  32. kbd_bh
  33. hard_reset_now
  34. kbd_init

   1 /*
   2  * linux/kernel/chr_drv/keyboard.c
   3  *
   4  * Keyboard driver for Linux v0.96 using Latin-1.
   5  *
   6  * Written for linux by Johan Myreen as a translation from
   7  * the assembly version by Linus (with diacriticals added)
   8  *
   9  * Some additional features added by Christoph Niemann (ChN), March 1993
  10  */
  11 
  12 #define KEYBOARD_IRQ 1
  13 
  14 #include <linux/sched.h>
  15 #include <linux/ctype.h>
  16 #include <linux/tty.h>
  17 #include <linux/mm.h>
  18 #include <linux/ptrace.h>
  19 #include <linux/keyboard.h>
  20 #include <linux/interrupt.h>
  21 #include <linux/config.h>
  22 #include <linux/signal.h>
  23 
  24 #ifndef KBD_DEFFLAGS
  25 #ifdef CONFIG_KBD_META
  26 #define KBD_DEFFLAGS ((1 << VC_NUMLOCK) | (1 << VC_REPEAT) | (1 << VC_META))
  27 #else
  28 #define KBD_DEFFLAGS ((1 << VC_NUMLOCK) | (1 << VC_REPEAT))
  29 #endif
  30 #endif
  31 
  32 /*
  33  * The default IO slowdown is doing 'inb()'s from 0x61, which should be
  34  * safe. But as that is the keyboard controller chip address, we do our
  35  * slowdowns here by doing short jumps: the keyboard controller should
  36  * be able to keep up
  37  */
  38 #define REALLY_SLOW_IO
  39 #define SLOW_IO_BY_JUMPING
  40 #include <asm/io.h>
  41 #include <asm/system.h>
  42 
  43 extern void do_keyboard_interrupt(void);
  44 extern void ctrl_alt_del(void);
  45 extern void change_console(unsigned int new_console);
  46 
  47 #define fake_keyboard_interrupt() \
  48 __asm__ __volatile__("int $0x21")
  49 
  50 unsigned long kbd_flags = 0;
  51 unsigned long kbd_dead_keys = 0;
  52 unsigned long kbd_prev_dead_keys = 0;
  53 
  54 static int want_console = -1;
  55 static int last_console = 0;            /* last used VC */
  56 static unsigned char rep = 0xff;        /* last pressed key */
  57 struct kbd_struct kbd_table[NR_CONSOLES];
  58 static struct kbd_struct * kbd = kbd_table;
  59 static struct tty_struct * tty = NULL;
  60 
  61 static volatile unsigned char acknowledge = 0;
  62 static volatile unsigned char resend = 0;
  63 
  64 typedef void (*fptr)(int);
  65 
  66 static int diacr = -1;
  67 static int npadch = 0;
  68 fptr key_table[];
  69 
  70 static void put_queue(int);
  71 static void applkey(int);
  72 static void cur(int);
  73 static unsigned int handle_diacr(unsigned int);
  74 
  75 static struct pt_regs * pt_regs;
  76 
  77 static inline void kb_wait(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  78 {
  79         int i;
  80 
  81         for (i=0; i<0x10000; i++)
  82                 if ((inb_p(0x64) & 0x02) == 0)
  83                         break;
  84 }
  85 
  86 static void keyboard_interrupt(int int_pt_regs)
     /* [previous][next][first][last][top][bottom][index][help] */
  87 {
  88         unsigned char scancode;
  89 
  90         pt_regs = (struct pt_regs *) int_pt_regs;
  91         kbd_prev_dead_keys |= kbd_dead_keys;
  92         if (!kbd_dead_keys)
  93                 kbd_prev_dead_keys = 0;
  94         kbd_dead_keys = 0;
  95         kb_wait();
  96         if (!(inb_p(0x64) & 0x01))
  97                 goto end_kbd_intr;
  98         scancode = inb(0x60);
  99         mark_bh(KEYBOARD_BH);
 100         if (scancode == 0xfa) {
 101                 acknowledge = 1;
 102                 goto end_kbd_intr;
 103         } else if (scancode == 0xfe) {
 104                 resend = 1;
 105                 goto end_kbd_intr;
 106         }
 107         tty = TTY_TABLE(0);
 108         kbd = kbd_table + fg_console;
 109         if (vc_kbd_flag(kbd,VC_RAW)) {
 110                 kbd_flags = 0;
 111                 put_queue(scancode);
 112                 goto end_kbd_intr;
 113         }
 114         if (scancode == 0xe0) {
 115                 set_kbd_dead(KGD_E0);
 116                 goto end_kbd_intr;
 117         } else if (scancode == 0xe1) {
 118                 set_kbd_dead(KGD_E1);
 119                 goto end_kbd_intr;
 120         }
 121         /*
 122          *  The keyboard maintains its own internal caps lock and num lock
 123          *  statuses. In caps lock mode E0 AA precedes make code and E0 2A
 124          *  follows break code. In num lock mode, E0 2A precedes make
 125          *  code and E0 AA follows break code. We do our own book-keeping,
 126          *  so we will just ignore these.
 127          */
 128         if (kbd_dead(KGD_E0) && (scancode == 0x2a || scancode == 0xaa))
 129                 goto end_kbd_intr;
 130         /*
 131          *  Repeat a key only if the input buffers are empty or the
 132          *  characters get echoed locally. This makes key repeat usable
 133          *  with slow applications and unders heavy loads.
 134          */
 135         if ((scancode != rep) || 
 136             (vc_kbd_flag(kbd,VC_REPEAT) && tty &&
 137              (L_ECHO(tty) || (EMPTY(&tty->secondary) && EMPTY(&tty->read_q)))))
 138                 key_table[scancode](scancode);
 139         rep = scancode;
 140 end_kbd_intr:
 141 }
 142 
 143 static void put_queue(int ch)
     /* [previous][next][first][last][top][bottom][index][help] */
 144 {
 145         struct tty_queue *qp;
 146         unsigned long new_head;
 147 
 148         wake_up(&keypress_wait);
 149         if (!tty)
 150                 return;
 151         qp = &tty->read_q;
 152 
 153         qp->buf[qp->head]=ch;
 154         if ((new_head=(qp->head+1)&(TTY_BUF_SIZE-1)) != qp->tail)
 155                 qp->head=new_head;
 156         wake_up_interruptible(&qp->proc_list);
 157 }
 158 
 159 static void puts_queue(char *cp)
     /* [previous][next][first][last][top][bottom][index][help] */
 160 {
 161         struct tty_queue *qp;
 162         unsigned long new_head;
 163         char ch;
 164 
 165         wake_up_interruptible(&keypress_wait);
 166         if (!tty)
 167                 return;
 168         qp = &tty->read_q;
 169 
 170         while ((ch = *(cp++)) != 0) {
 171                 qp->buf[qp->head]=ch;
 172                 if ((new_head=(qp->head+1)&(TTY_BUF_SIZE-1))
 173                                  != qp->tail)
 174                         qp->head=new_head;
 175         }
 176         wake_up_interruptible(&qp->proc_list);
 177 }
 178 
 179 static void ctrl(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
 180 {
 181         if (kbd_dead(KGD_E0))
 182                 set_kbd_flag(KG_RCTRL);
 183         else
 184                 set_kbd_flag(KG_LCTRL);
 185 }
 186 
 187 static void alt(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
 188 {
 189         if (kbd_dead(KGD_E0))
 190                 set_kbd_flag(KG_ALTGR);
 191         else
 192                 set_kbd_flag(KG_ALT);
 193 }
 194 
 195 static void unctrl(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
 196 {
 197         if (kbd_dead(KGD_E0))
 198                 clr_kbd_flag(KG_RCTRL);
 199         else
 200                 clr_kbd_flag(KG_LCTRL);
 201 }
 202 
 203 static void unalt(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
 204 {
 205         if (kbd_dead(KGD_E0))
 206                 clr_kbd_flag(KG_ALTGR);
 207         else {
 208                 clr_kbd_flag(KG_ALT);
 209                 if (npadch != 0) {
 210                         put_queue(npadch);
 211                         npadch=0;
 212                 }
 213         }
 214 }
 215 
 216 static void lshift(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
 217 {
 218         set_kbd_flag(KG_LSHIFT);
 219 }
 220 
 221 static void unlshift(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
 222 {
 223         clr_kbd_flag(KG_LSHIFT);
 224 }
 225 
 226 static void rshift(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
 227 {
 228         set_kbd_flag(KG_RSHIFT);
 229 }
 230 
 231 static void unrshift(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
 232 {
 233         clr_kbd_flag(KG_RSHIFT);
 234 }
 235 
 236 static void caps(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
 237 {
 238         if (kbd_flag(KG_CAPSLOCK))
 239                 return;         /* key already pressed: defeat repeat */
 240         set_kbd_flag(KG_CAPSLOCK);
 241         chg_vc_kbd_flag(kbd,VC_CAPSLOCK);
 242 }
 243 
 244 static void uncaps(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
 245 {
 246         clr_kbd_flag(KG_CAPSLOCK);
 247 }
 248 
 249 static void show_ptregs(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 250 {
 251         if (!pt_regs)
 252                 return;
 253         printk("\nEIP: %04x:%08x",0xffff & pt_regs->cs,pt_regs->eip);
 254         if (pt_regs->cs & 3)
 255                 printk(" ESP: %04x:%08x",0xffff & pt_regs->cs,pt_regs->eip);
 256         printk(" EFLAGS: %08x",pt_regs->eflags);
 257         printk("\nEAX: %08x EBX: %08x ECX: %08x EDX: %08x",
 258                 pt_regs->orig_eax,pt_regs->ebx,pt_regs->ecx,pt_regs->edx);
 259         printk("\nESI: %08x EDI: %08x EBP: %08x",
 260                 pt_regs->esi, pt_regs->edi, pt_regs->ebp);
 261         printk(" DS: %04x ES: %04x FS: %04x GS: %04x\n",
 262                 0xffff & pt_regs->ds,0xffff & pt_regs->es,
 263                 0xffff & pt_regs->fs,0xffff & pt_regs->gs);
 264 }
 265 
 266 static void scroll(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
 267 {
 268         if (kbd_dead(KGD_E0))
 269                 put_queue(INTR_CHAR(tty));
 270         else if ( sc != rep )   /* no autorepeat for scroll lock, ChN */
 271                 if (kbd_flag(KG_LSHIFT) || kbd_flag(KG_RSHIFT))
 272                         show_mem();
 273                 else if (kbd_flag(KG_ALT) || kbd_flag(KG_ALTGR))
 274                         show_ptregs();
 275                 else if (kbd_flag(KG_LCTRL) || kbd_flag(KG_RCTRL))
 276                         show_state();
 277                 else {
 278                         if (vc_kbd_flag(kbd, VC_SCROLLOCK))
 279                                 /* pressing srcoll lock 2nd time sends ^Q, ChN */
 280                                 put_queue(START_CHAR(tty));
 281                         else
 282 
 283                                 /* pressing srcoll lock 1st time sends ^S, ChN */
 284                                 put_queue(STOP_CHAR(tty));
 285                         chg_vc_kbd_flag(kbd,VC_SCROLLOCK);
 286                 }
 287         
 288 }
 289 
 290 static void num(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
 291 {
 292         if (kbd_flag(KG_LCTRL))
 293                 /* pause key pressed, sends E1 1D 45, ChN */
 294                 chg_vc_kbd_flag(kbd,VC_PAUSE);
 295         else if (vc_kbd_flag(kbd,VC_APPLIC))
 296                 applkey(0x50);
 297         else if ( rep != sc )   /* no autorepeat for numlock, ChN */
 298                 chg_vc_kbd_flag(kbd,VC_NUMLOCK);
 299 }
 300 
 301 static void applkey(int key)
     /* [previous][next][first][last][top][bottom][index][help] */
 302 {
 303         char buf[] = { 0x1b, 0x4f, 0x00, 0x00 };
 304 
 305         buf[2] = key;
 306         puts_queue(buf);
 307 }
 308 
 309 static void sysreq(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
 310 {
 311         /* pressing alt-printscreen switches to the last used console, ChN */
 312         if ( sc != rep)
 313                 want_console = last_console;
 314 }
 315 
 316 #if defined KBD_FINNISH
 317 
 318 static unsigned char key_map[] = {
 319           0,   27,  '1',  '2',  '3',  '4',  '5',  '6',
 320         '7',  '8',  '9',  '0',  '+', '\'',  127,    9,
 321         'q',  'w',  'e',  'r',  't',  'y',  'u',  'i',
 322         'o',  'p',  '}',    0,   13,    0,  'a',  's',
 323         'd',  'f',  'g',  'h',  'j',  'k',  'l',  '|',
 324         '{',    0,    0, '\'',  'z',  'x',  'c',  'v',
 325         'b',  'n',  'm',  ',',  '.',  '-',    0,  '*',
 326           0,   32,    0,    0,    0,    0,    0,    0,
 327           0,    0,    0,    0,    0,    0,    0,    0,
 328           0,    0,  '-',    0,    0,    0,  '+',    0,
 329           0,    0,    0,    0,    0,    0,  '<',    0,
 330           0,    0,    0,    0,    0,    0,    0,    0,
 331           0 };
 332 
 333 static unsigned char shift_map[] = {
 334           0,   27,  '!', '\"',  '#',  '$',  '%',  '&',
 335         '/',  '(',  ')',  '=',  '?',  '`',  127,    9,
 336         'Q',  'W',  'E',  'R',  'T',  'Y',  'U',  'I',
 337         'O',  'P',  ']',  '^',   13,    0,  'A',  'S',
 338         'D',  'F',  'G',  'H',  'J',  'K',  'L', '\\',
 339         '[',    0,    0,  '*',  'Z',  'X',  'C',  'V',
 340         'B',  'N',  'M',  ';',  ':',  '_',    0,  '*',
 341           0,   32,    0,    0,    0,    0,    0,    0,
 342           0,    0,    0,    0,    0,    0,    0,    0,
 343           0,    0,  '-',    0,    0,    0,  '+',    0,
 344           0,    0,    0,    0,    0,    0,  '>',    0,
 345           0,    0,    0,    0,    0,    0,    0,    0,
 346           0 };
 347 
 348 static unsigned char alt_map[] = {
 349           0,    0,    0,  '@',  163,  '$',    0,    0,
 350         '{',   '[',  ']', '}', '\\',    0,    0,    0,
 351           0,    0,    0,    0,    0,    0,    0,    0,
 352           0,    0,    0,  '~',   13,    0,    0,    0,
 353           0,    0,    0,    0,    0,    0,    0,    0,
 354           0,    0,    0,    0,    0,    0,    0,    0,
 355           0,    0,    0,    0,    0,    0,    0,    0,
 356           0,    0,    0,    0,    0,    0,    0,    0,
 357           0,    0,    0,    0,    0,    0,    0,    0,
 358           0,    0,    0,    0,    0,    0,    0,    0,
 359           0,    0,    0,    0,    0,    0,  '|',    0,
 360           0,    0,    0,    0,    0,    0,    0,    0,
 361           0 };
 362 
 363 #elif defined KBD_FINNISH_LATIN1
 364 
 365 static unsigned char key_map[] = {
 366           0,   27,  '1',  '2',  '3',  '4',  '5',  '6',
 367         '7',  '8',  '9',  '0',  '+',  180,  127,    9,
 368         'q',  'w',  'e',  'r',  't',  'y',  'u',  'i',
 369         'o',  'p',  229,  168,   13,    0,  'a',  's',
 370         'd',  'f',  'g',  'h',  'j',  'k',  'l',  246,
 371         228,  167,    0, '\'',  'z',  'x',  'c',  'v',
 372         'b',  'n',  'm',  ',',  '.',  '-',    0,  '*',
 373           0,   32,    0,    0,    0,    0,    0,    0,
 374           0,    0,    0,    0,    0,    0,    0,    0,
 375           0,    0,  '-',    0,    0,    0,  '+',    0,
 376           0,    0,    0,    0,    0,    0,  '<',    0,
 377           0,    0,    0,    0,    0,    0,    0,    0,
 378           0 };
 379 
 380 static unsigned char shift_map[] = {
 381           0,   27,  '!',  '"',  '#',  '$',  '%',  '&',
 382         '/',  '(',  ')',  '=',  '?',  '`',  127,    9,
 383         'Q',  'W',  'E',  'R',  'T',  'Y',  'U',  'I',
 384         'O',  'P',  197,  '^',   13,    0,  'A',  'S',
 385         'D',  'F',  'G',  'H',  'J',  'K',  'L',  214,
 386         196,  189,    0,  '*',  'Z',  'X',  'C',  'V',
 387         'B',  'N',  'M',  ';',  ':',  '_',    0,  '*',
 388           0,   32,    0,    0,    0,    0,    0,    0,
 389           0,    0,    0,    0,    0,    0,    0,    0,
 390           0,    0,  '-',    0,    0,    0,  '+',    0,
 391           0,    0,    0,    0,    0,    0,  '>',    0,
 392           0,    0,    0,    0,    0,    0,    0,    0,
 393           0 };
 394 
 395 static unsigned char alt_map[] = {
 396           0,    0,    0,  '@',  163,  '$',    0,    0,
 397         '{',  '[',  ']',  '}', '\\',    0,    0,    0,
 398           0,    0,    0,    0,    0,    0,    0,    0,
 399           0,    0,    0,  '~',   13,    0,    0,    0,
 400           0,    0,    0,    0,    0,    0,    0,    0,
 401           0,    0,    0,    0,    0,    0,    0,    0,
 402           0,    0,    0,    0,    0,    0,    0,    0,
 403           0,    0,    0,    0,    0,    0,    0,    0,
 404           0,    0,    0,    0,    0,    0,    0,    0,
 405           0,    0,    0,    0,    0,    0,    0,    0,
 406           0,    0,    0,    0,    0,    0,  '|',    0,
 407           0,    0,    0,    0,    0,    0,    0,    0,
 408           0 };
 409 
 410 #elif defined KBD_US
 411 
 412 static unsigned char key_map[] = {
 413           0,   27,  '1',  '2',  '3',  '4',  '5',  '6',
 414         '7',  '8',  '9',  '0',  '-',  '=',  127,    9,
 415         'q',  'w',  'e',  'r',  't',  'y',  'u',  'i',
 416         'o',  'p',  '[',  ']',   13,    0,  'a',  's',
 417         'd',  'f',  'g',  'h',  'j',  'k',  'l',  ';',
 418         '\'', '`',    0, '\\',  'z',  'x',  'c',  'v',
 419         'b',  'n',  'm',  ',',  '.',  '/',    0,  '*',
 420           0,   32,    0,    0,    0,    0,    0,    0,
 421           0,    0,    0,    0,    0,    0,    0,    0,
 422           0,    0,  '-',    0,    0,    0,  '+',    0,
 423           0,    0,    0,    0,    0,    0,  '<',    0,
 424           0,    0,    0,    0,    0,    0,    0,    0,
 425           0 };
 426 
 427 static unsigned char shift_map[] = {
 428           0,   27,  '!',  '@',  '#',  '$',  '%',  '^',
 429         '&',  '*',  '(',  ')',  '_',  '+',  127,    9,
 430         'Q',  'W',  'E',  'R',  'T',  'Y',  'U',  'I',
 431         'O',  'P',  '{',  '}',   13,    0,  'A',  'S',
 432         'D',  'F',  'G',  'H',  'J',  'K',  'L',  ':',
 433         '"',  '~',  '0',  '|',  'Z',  'X',  'C',  'V',
 434         'B',  'N',  'M',  '<',  '>',  '?',    0,  '*',
 435           0,   32,    0,    0,    0,    0,    0,    0,
 436           0,    0,    0,    0,    0,    0,    0,    0,
 437           0,    0,  '-',    0,    0,    0,  '+',    0,
 438           0,    0,    0,    0,    0,    0,  '>',    0,
 439           0,    0,    0,    0,    0,    0,    0,    0,
 440           0 };
 441 
 442 static unsigned char alt_map[] = {
 443           0,    0,    0,  '@',    0,  '$',    0,    0,
 444         '{',   '[',  ']', '}', '\\',    0,    0,    0,
 445           0,    0,    0,    0,    0,    0,    0,    0,
 446           0,    0,    0,  '~',   13,    0,    0,    0,
 447           0,    0,    0,    0,    0,    0,    0,    0,
 448           0,    0,    0,    0,    0,    0,    0,    0,
 449           0,    0,    0,    0,    0,    0,    0,    0,
 450           0,    0,    0,    0,    0,    0,    0,    0,
 451           0,    0,    0,    0,    0,    0,    0,    0,
 452           0,    0,    0,    0,    0,    0,    0,    0,
 453           0,    0,    0,    0,    0,    0,  '|',    0,
 454           0,    0,    0,    0,    0,    0,    0,    0,
 455           0 };
 456 
 457 #elif defined KBD_UK
 458 
 459 static unsigned char key_map[] = {
 460           0,   27,  '1',  '2',  '3',  '4',  '5',  '6',
 461         '7',  '8',  '9',  '0',  '-',  '=',  127,    9,
 462         'q',  'w',  'e',  'r',  't',  'y',  'u',  'i',
 463         'o',  'p',  '[',  ']',   13,    0,  'a',  's',
 464         'd',  'f',  'g',  'h',  'j',  'k',  'l',  ';',
 465         '\'', '`',    0,  '#',  'z',  'x',  'c',  'v',
 466         'b',  'n',  'm',  ',',  '.',  '/',    0,  '*',
 467           0,   32,    0,    0,    0,    0,    0,    0,
 468           0,    0,    0,    0,    0,    0,    0,    0,
 469           0,    0,  '-',    0,    0,    0,  '+',    0,
 470           0,    0,    0,    0,    0,    0, '\\',    0,
 471           0,    0,    0,    0,    0,    0,    0,    0,
 472           0 };
 473 
 474 static unsigned char shift_map[] = {
 475           0,   27,  '!',  '"',  163,  '$',  '%',  '^',
 476         '&',  '*',  '(',  ')',  '_',  '+',  127,    9,
 477         'Q',  'W',  'E',  'R',  'T',  'Y',  'U',  'I',
 478         'O',  'P',  '{',  '}',   13,    0,  'A',  'S',
 479         'D',  'F',  'G',  'H',  'J',  'K',  'L',  ':',
 480         '@',  '~',  '0',  '~',  'Z',  'X',  'C',  'V',
 481         'B',  'N',  'M',  '<',  '>',  '?',    0,  '*',
 482           0,   32,    0,    0,    0,    0,    0,    0,
 483           0,    0,    0,    0,    0,    0,    0,    0,
 484           0,    0,  '-',    0,    0,    0,  '+',    0,
 485           0,    0,    0,    0,    0,    0,  '|',    0,
 486           0,    0,    0,    0,    0,    0,    0,    0,
 487           0 };
 488 
 489 static unsigned char alt_map[] = {
 490           0,    0,    0,  '@',    0,  '$',    0,    0,
 491         '{',   '[',  ']', '}', '\\',    0,    0,    0,
 492           0,    0,    0,    0,    0,    0,    0,    0,
 493           0,    0,    0,  '~',   13,    0,    0,    0,
 494           0,    0,    0,    0,    0,    0,    0,    0,
 495           0,    0,    0,    0,    0,    0,    0,    0,
 496           0,    0,    0,    0,    0,    0,    0,    0,
 497           0,    0,    0,    0,    0,    0,    0,    0,
 498           0,    0,    0,    0,    0,    0,    0,    0,
 499           0,    0,    0,    0,    0,    0,    0,    0,
 500           0,    0,    0,    0,    0,    0,  '|',    0,
 501           0,    0,    0,    0,    0,    0,    0,    0,
 502           0 };
 503 
 504 #elif defined KBD_GR
 505 
 506 static unsigned char key_map[] = {
 507           0,   27,  '1',  '2',  '3',  '4',  '5',  '6',
 508         '7',  '8',  '9',  '0', '\\', '\'',  127,    9,
 509         'q',  'w',  'e',  'r',  't',  'z',  'u',  'i',
 510         'o',  'p',  '@',  '+',   13,    0,  'a',  's',
 511         'd',  'f',  'g',  'h',  'j',  'k',  'l',  '[',
 512         ']',  '^',    0,  '#',  'y',  'x',  'c',  'v',
 513         'b',  'n',  'm',  ',',  '.',  '-',    0,  '*',
 514           0,   32,    0,    0,    0,    0,    0,    0,
 515           0,    0,    0,    0,    0,    0,    0,    0,
 516           0,    0,  '-',    0,    0,    0,  '+',    0,
 517           0,    0,    0,    0,    0,    0,  '<',    0,
 518           0,    0,    0,    0,    0,    0,    0,    0,
 519           0 };
 520 
 521 static unsigned char shift_map[] = {
 522           0,   27,  '!',  '"',  '#',  '$',  '%',  '&',
 523         '/',  '(',  ')',  '=',  '?',  '`',  127,    9,
 524         'Q',  'W',  'E',  'R',  'T',  'Z',  'U',  'I',
 525         'O',  'P', '\\',  '*',   13,    0,  'A',  'S',
 526         'D',  'F',  'G',  'H',  'J',  'K',  'L',  '{',
 527         '}',  '~',    0, '\'',  'Y',  'X',  'C',  'V',
 528         'B',  'N',  'M',  ';',  ':',  '_',    0,  '*',
 529           0,   32,    0,    0,    0,    0,    0,    0,
 530           0,    0,    0,    0,    0,    0,    0,    0,
 531           0,    0,  '-',    0,    0,    0,  '+',    0,
 532           0,    0,    0,    0,    0,    0,  '>',    0,
 533           0,    0,    0,    0,    0,    0,    0,    0,
 534           0 };
 535 
 536 static unsigned char alt_map[] = {
 537           0,    0,    0,  '@',    0,  '$',    0,    0,
 538         '{',   '[',  ']', '}', '\\',    0,    0,    0,
 539         '@',    0,    0,    0,    0,    0,    0,    0,
 540           0,    0,    0,  '~',   13,    0,    0,    0,
 541           0,    0,    0,    0,    0,    0,    0,    0,
 542           0,    0,    0,    0,    0,    0,    0,    0,
 543           0,    0,    0,    0,    0,    0,    0,    0,
 544           0,    0,    0,    0,    0,    0,    0,    0,
 545           0,    0,    0,    0,    0,    0,    0,    0,
 546           0,    0,    0,    0,    0,    0,    0,    0,
 547           0,    0,    0,    0,    0,    0,  '|',    0,
 548           0,    0,    0,    0,    0,    0,    0,    0,
 549           0 };
 550 
 551 #elif defined KBD_GR_LATIN1
 552 
 553 static unsigned char key_map[] = {
 554           0,   27,  '1',  '2',  '3',  '4',  '5',  '6',
 555         '7',  '8',  '9',  '0', 223,  180,  127,    9,
 556         'q',  'w',  'e',  'r',  't',  'z',  'u',  'i',
 557         'o',  'p',  252,  '+',   13,    0,  'a',  's',
 558         'd',  'f',  'g',  'h',  'j',  'k',  'l', 246,
 559         228,   94,    0,  '#',  'y',  'x',  'c',  'v',
 560         'b',  'n',  'm',  ',',  '.',  '-',    0,  '*',
 561           0,   32,    0,    0,    0,    0,    0,    0,
 562           0,    0,    0,    0,    0,    0,    0,    0,
 563           0,    0,  '-',    0,    0,    0,  '+',    0,
 564           0,    0,    0,    0,    0,    0,  '<',    0,
 565           0,    0,    0,    0,    0,    0,    0,    0,
 566           0 };
 567 
 568 static unsigned char shift_map[] = {
 569           0,   27,  '!',  '"',  167,  '$',  '%',  '&',
 570         '/',  '(',  ')',  '=',  '?',  '`',  127,    9,
 571         'Q',  'W',  'E',  'R',  'T',  'Z',  'U',  'I',
 572         'O',  'P',  220,  '*',   13,    0,  'A',  'S',
 573         'D',  'F',  'G',  'H',  'J',  'K',  'L',  214,
 574         196,  176,    0, '\'',  'Y',  'X',  'C',  'V',
 575         'B',  'N',  'M',  ';',  ':',  '_',    0,  '*',
 576           0,   32,    0,    0,    0,    0,    0,    0,
 577           0,    0,    0,    0,    0,    0,    0,    0,
 578           0,    0,  '-',    0,    0,    0,  '+',    0,
 579           0,    0,    0,    0,    0,    0,  '>',    0,
 580           0,    0,    0,    0,    0,    0,    0,    0,
 581           0 };
 582 
 583 static unsigned char alt_map[] = {
 584           0,    0,    0,  178,  179,  '$',    0,    0,
 585         '{',   '[',  ']', '}', '\\',    0,    0,    0,
 586         '@',    0,    0,    0,    0,    0,    0,    0,
 587           0,    0,    0,  '~',   13,    0,    0,    0,
 588           0,    0,    0,    0,    0,    0,    0,    0,
 589           0,    0,    0,    0,    0,    0,    0,    0,
 590           0,    0,  181,    0,    0,    0,    0,    0,
 591           0,    0,    0,    0,    0,    0,    0,    0,
 592           0,    0,    0,    0,    0,    0,    0,    0,
 593           0,    0,    0,    0,    0,    0,    0,    0,
 594           0,    0,    0,    0,    0,    0,  '|',    0,
 595           0,    0,    0,    0,    0,    0,    0,    0,
 596           0 };
 597 
 598 #elif defined KBD_FR
 599 
 600 static unsigned char key_map[] = {
 601           0,   27,  '&',  '{',  '"', '\'',  '(',  '-',
 602         '}',  '_',  '/',  '@',  ')',  '=',  127,    9,
 603         'a',  'z',  'e',  'r',  't',  'y',  'u',  'i',
 604         'o',  'p',  '^',  '$',   13,    0,  'q',  's',
 605         'd',  'f',  'g',  'h',  'j',  'k',  'l',  'm',
 606         '|',  '`',    0,   42,  'w',  'x',  'c',  'v',
 607         'b',  'n',  ',',  ';',  ':',  '!',    0,  '*',
 608           0,   32,    0,    0,    0,    0,    0,    0,
 609           0,    0,    0,    0,    0,    0,    0,    0,
 610           0,    0,  '-',    0,    0,    0,  '+',    0,
 611           0,    0,    0,    0,    0,    0,  '<',    0,
 612           0,    0,    0,    0,    0,    0,    0,    0,
 613           0 };
 614 
 615 static unsigned char shift_map[] = {
 616           0,   27,  '1',  '2',  '3',  '4',  '5',  '6',
 617         '7',  '8',  '9',  '0',  ']',  '+',  127,    9,
 618         'A',  'Z',  'E',  'R',  'T',  'Y',  'U',  'I',
 619         'O',  'P',  '<',  '>',   13,    0,  'Q',  'S',
 620         'D',  'F',  'G',  'H',  'J',  'K',  'L',  'M',
 621         '%',  '~',    0,  '#',  'W',  'X',  'C',  'V',
 622         'B',  'N',  '?',  '.',  '/', '\\',    0,  '*',
 623           0,   32,    0,    0,    0,    0,    0,    0,
 624           0,    0,    0,    0,    0,    0,    0,    0,
 625           0,    0,  '-',    0,    0,    0,  '+',    0,
 626           0,    0,    0,    0,    0,    0,  '>',    0,
 627           0,    0,    0,    0,    0,    0,    0,    0,
 628           0 };
 629 
 630 static unsigned char alt_map[] = {
 631           0,    0,    0,  '~',  '#',  '{',  '[',  '|',
 632         '`', '\\',   '^',  '@', ']',  '}',    0,    0,
 633         '@',    0,    0,    0,    0,    0,    0,    0,
 634           0,    0,    0,  '~',   13,    0,    0,    0,
 635           0,    0,    0,    0,    0,    0,    0,    0,
 636           0,    0,    0,    0,    0,    0,    0,    0,
 637           0,    0,    0,    0,    0,    0,    0,    0,
 638           0,    0,    0,    0,    0,    0,    0,    0,
 639           0,    0,    0,    0,    0,    0,    0,    0,
 640           0,    0,    0,    0,    0,    0,    0,    0,
 641           0,    0,    0,    0,    0,    0,  '|',    0,
 642           0,    0,    0,    0,    0,    0,    0,    0,
 643           0 };
 644 
 645 #elif defined KBD_FR_LATIN1
 646 
 647 static unsigned char key_map[] = {
 648           0,   27,  '&',  233,  '"', '\'',  '(',  '-',
 649         232,  '_',  231,  224,  ')',  '=',  127,    9,
 650         'a',  'z',  'e',  'r',  't',  'y',  'u',  'i',
 651         'o',  'p',  '^',  '$',   13,    0,  'q',  's',
 652         'd',  'f',  'g',  'h',  'j',  'k',  'l',  'm',
 653         249,  178,    0,   42,  'w',  'x',  'c',  'v',
 654         'b',  'n',  ',',  ';',  ':',  '!',    0,  '*',
 655           0,   32,    0,    0,    0,    0,    0,    0,
 656           0,    0,    0,    0,    0,    0,    0,    0,
 657           0,    0,  '-',    0,    0,    0,  '+',    0,
 658           0,    0,    0,    0,    0,    0,  '<',    0,
 659           0,    0,    0,    0,    0,    0,    0,    0,
 660           0 };
 661 
 662 static unsigned char shift_map[] = {
 663           0,   27,  '1',  '2',  '3',  '4',  '5',  '6',
 664         '7',  '8',  '9',  '0',  176,  '+',  127,    9,
 665         'A',  'Z',  'E',  'R',  'T',  'Y',  'U',  'I',
 666         'O',  'P',  168,  163,   13,    0,  'Q',  'S',
 667         'D',  'F',  'G',  'H',  'J',  'K',  'L',  'M',
 668         '%',    0,    0,  181,  'W',  'X',  'C',  'V',
 669         'B',  'N',  '?',  '.',  '/',  167,    0,  '*',
 670           0,   32,    0,    0,    0,    0,    0,    0,
 671           0,    0,    0,    0,    0,    0,    0,    0,
 672           0,    0,  '-',    0,    0,    0,  '+',    0,
 673           0,    0,    0,    0,    0,    0,  '>',    0,
 674           0,    0,    0,    0,    0,    0,    0,    0,
 675           0 };
 676 
 677 static unsigned char alt_map[] = {
 678           0,    0,    0,  '~',  '#',  '{',  '[',  '|',
 679         '`', '\\',   '^',  '@', ']',  '}',    0,    0,
 680         '@',    0,    0,    0,    0,    0,    0,    0,
 681           0,    0,    0,  164,   13,    0,    0,    0,
 682           0,    0,    0,    0,    0,    0,    0,    0,
 683           0,    0,    0,    0,    0,    0,    0,    0,
 684           0,    0,    0,    0,    0,    0,    0,    0,
 685           0,    0,    0,    0,    0,    0,    0,    0,
 686           0,    0,    0,    0,    0,    0,    0,    0,
 687           0,    0,    0,    0,    0,    0,    0,    0,
 688           0,    0,    0,    0,    0,    0,  '|',    0,
 689           0,    0,    0,    0,    0,    0,    0,    0,
 690           0 };
 691 
 692 #elif defined KBD_DK
 693 
 694 static unsigned char key_map[] = {
 695           0,   27,  '1',  '2',  '3',  '4',  '5',  '6',
 696         '7',  '8',  '9',  '0',  '+', '\'',  127,    9,
 697         'q',  'w',  'e',  'r',  't',  'y',  'u',  'i',
 698         'o',  'p',  229,    0,   13,    0,  'a',  's',
 699         'd',  'f',  'g',  'h',  'j',  'k',  'l',  230,
 700         162,    0,    0, '\'',  'z',  'x',  'c',  'v',
 701         'b',  'n',  'm',  ',',  '.',  '-',    0,  '*',
 702           0,   32,    0,    0,    0,    0,    0,    0,
 703           0,    0,    0,    0,    0,    0,    0,    0,
 704           0,    0,  '-',    0,    0,    0,  '+',    0,
 705           0,    0,    0,    0,    0,    0,  '<',    0,
 706           0,    0,    0,    0,    0,    0,    0,    0,
 707           0 };
 708 
 709 static unsigned char shift_map[] = {
 710           0,   27,  '!', '\"',  '#',  '$',  '%',  '&',
 711         '/',  '(',  ')',  '=',  '?',  '`',  127,    9,
 712         'Q',  'W',  'E',  'R',  'T',  'Y',  'U',  'I',
 713         'O',  'P',  197,  '^',   13,    0,  'A',  'S',
 714         'D',  'F',  'G',  'H',  'J',  'K',  'L',  198,
 715         165,    0,    0,  '*',  'Z',  'X',  'C',  'V',
 716         'B',  'N',  'M',  ';',  ':',  '_',    0,  '*',
 717           0,   32,    0,    0,    0,    0,    0,    0,
 718           0,    0,    0,    0,    0,    0,    0,    0,
 719           0,    0,  '-',    0,    0,    0,  '+',    0,
 720           0,    0,    0,    0,    0,    0,  '>',    0,
 721           0,    0,    0,    0,    0,    0,    0,    0,
 722           0 };
 723 
 724 static unsigned char alt_map[] = {
 725           0,    0,    0,  '@',  163,  '$',    0,    0,
 726         '{',   '[',  ']', '}',    0,  '|',    0,    0,
 727           0,    0,    0,    0,    0,    0,    0,    0,
 728           0,    0,    0,  '~',   13,    0,    0,    0,
 729           0,    0,    0,    0,    0,    0,    0,    0,
 730           0,    0,    0,    0,    0,    0,    0,    0,
 731           0,    0,    0,    0,    0,    0,    0,    0,
 732           0,    0,    0,    0,    0,    0,    0,    0,
 733           0,    0,    0,    0,    0,    0,    0,    0,
 734           0,    0,    0,    0,    0,    0,    0,    0,
 735           0,    0,    0,    0,    0,    0,  '\\',    0,
 736           0,    0,    0,    0,    0,    0,    0,    0,
 737           0 };
 738 
 739 #elif defined KBD_DK_LATIN1
 740 
 741 static unsigned char key_map[] = {
 742           0,   27,  '1',  '2',  '3',  '4',  '5',  '6',
 743         '7',  '8',  '9',  '0',  '+',  180,  127,    9,
 744         'q',  'w',  'e',  'r',  't',  'y',  'u',  'i',
 745         'o',  'p',  229,  168,   13,    0,  'a',  's',
 746         'd',  'f',  'g',  'h',  'j',  'k',  'l',  230,
 747         162,  189,    0, '\'',  'z',  'x',  'c',  'v',
 748         'b',  'n',  'm',  ',',  '.',  '-',    0,  '*',
 749           0,   32,    0,    0,    0,    0,    0,    0,
 750           0,    0,    0,    0,    0,    0,    0,    0,
 751           0,    0,  '-',    0,    0,    0,  '+',    0,
 752           0,    0,    0,    0,    0,    0,  '<',    0,
 753           0,    0,    0,    0,    0,    0,    0,    0,
 754           0 };
 755 
 756 static unsigned char shift_map[] = {
 757           0,   27,  '!', '\"',  '#',  '$',  '%',  '&',
 758         '/',  '(',  ')',  '=',  '?',  '`',  127,    9,
 759         'Q',  'W',  'E',  'R',  'T',  'Y',  'U',  'I',
 760         'O',  'P',  197,  '^',   13,    0,  'A',  'S',
 761         'D',  'F',  'G',  'H',  'J',  'K',  'L',  198,
 762         165,  167,    0,  '*',  'Z',  'X',  'C',  'V',
 763         'B',  'N',  'M',  ';',  ':',  '_',    0,  '*',
 764           0,   32,    0,    0,    0,    0,    0,    0,
 765           0,    0,    0,    0,    0,    0,    0,    0,
 766           0,    0,  '-',    0,    0,    0,  '+',    0,
 767           0,    0,    0,    0,    0,    0,  '>',    0,
 768           0,    0,    0,    0,    0,    0,    0,    0,
 769           0 };
 770 
 771 static unsigned char alt_map[] = {
 772           0,    0,    0,  '@',  163,  '$',    0,    0,
 773         '{',   '[',  ']', '}',    0,  '|',    0,    0,
 774           0,    0,    0,    0,    0,    0,    0,    0,
 775           0,    0,    0,  '~',   13,    0,    0,    0,
 776           0,    0,    0,    0,    0,    0,    0,    0,
 777           0,    0,    0,    0,    0,    0,    0,    0,
 778           0,    0,    0,    0,    0,    0,    0,    0,
 779           0,    0,    0,    0,    0,    0,    0,    0,
 780           0,    0,    0,    0,    0,    0,    0,    0,
 781           0,    0,    0,    0,    0,    0,    0,    0,
 782           0,    0,    0,    0,    0,    0, '\\',    0,
 783           0,    0,    0,    0,    0,    0,    0,    0,
 784           0 };
 785 
 786 #elif defined KBD_DVORAK
 787 
 788 static unsigned char key_map[] = {
 789           0,   27,  '1',  '2',  '3',  '4',  '5',  '6',
 790         '7',  '8',  '9',  '0', '\\',  '=',  127,    9,
 791         '\'', ',',  '.',  'p',  'y',  'f',  'g',  'c',
 792         'r',  'l',  '/',  ']',   13,    0,  'a',  'o',
 793         'e',  'u',  'i',  'd',  'h',  't',  'n',  's',
 794         '-',  '`',    0,  '[',  ';',  'q',  'j',  'k',
 795         'x',  'b',  'm',  'w',  'v',  'z',    0,  '*',
 796           0,   32,    0,    0,    0,    0,    0,    0,
 797           0,    0,    0,    0,    0,    0,    0,    0,
 798           0,    0,  '-',    0,    0,    0,  '+',    0,
 799           0,    0,    0,    0,    0,    0,  '<',    0,
 800           0,    0,    0,    0,    0,    0,    0,    0,
 801           0 };
 802 
 803 static unsigned char shift_map[] = {
 804           0,   27,  '!',  '@',  '#',  '$',  '%',  '^',
 805         '&',  '*',  '(',  ')',  '|',  '+',  127,    9,
 806         '"',  '<',  '>',  'P',  'Y',  'F',  'G',  'C',
 807         'R',  'L',  '?',  '}',   13,    0,  'A',  'O',
 808         'E',  'U',  'I',  'D',  'H',  'T',  'N',  'S',
 809         '_',  '~',    0,  '{',  ':',  'Q',  'J',  'K',
 810         'X',  'B',  'M',  'W',  'V',  'Z',    0,  '*',
 811           0,   32,    0,    0,    0,    0,    0,    0,
 812           0,    0,    0,    0,    0,    0,    0,    0,
 813           0,    0,  '-',    0,    0,    0,  '+',    0,
 814           0,    0,    0,    0,    0,    0,  '<',    0,
 815           0,    0,    0,    0,    0,    0,    0,    0,
 816           0 };
 817 
 818 static unsigned char alt_map[] = {
 819           0,    0,    0,  '@',    0,  '$',    0,    0,
 820         '{',   '[',  ']', '}', '\\',    0,    0,    0,
 821           0,    0,    0,    0,    0,    0,    0,    0,
 822           0,    0,    0,  '~',   13,    0,    0,    0,
 823           0,    0,    0,    0,    0,    0,    0,    0,
 824           0,    0,    0,    0,    0,    0,    0,    0,
 825           0,    0,    0,    0,    0,    0,    0,    0,
 826           0,    0,    0,    0,    0,    0,    0,    0,
 827           0,    0,    0,    0,    0,    0,    0,    0,
 828           0,    0,    0,    0,    0,    0,    0,    0,
 829           0,    0,    0,    0,    0,    0,  '|',    0,
 830           0,    0,    0,    0,    0,    0,    0,    0,
 831           0 };
 832 
 833 #elif defined KBD_SG
 834 
 835 static unsigned char key_map[] = {
 836           0,   27,  '1',  '2',  '3',  '4',  '5',  '6',
 837         '7',  '8',  '9',  '0', '\'',  '^',  127,    9,
 838         'q',  'w',  'e',  'r',  't',  'z',  'u',  'i',
 839         'o',  'p',    0,    0,   13,    0,  'a',  's',
 840         'd',  'f',  'g',  'h',  'j',  'k',  'l',    0,
 841           0,    0,    0,  '$',  'y',  'x',  'c',  'v',
 842         'b',  'n',  'm',  ',',  '.',  '-',    0,  '*',
 843           0,   32,    0,    0,    0,    0,    0,    0,
 844           0,    0,    0,    0,    0,    0,    0,    0,
 845           0,    0,  '-',    0,    0,    0,  '+',    0,
 846           0,    0,    0,    0,    0,    0,  '<',    0,
 847           0,    0,    0,    0,    0,    0,    0,    0,
 848           0 };
 849 
 850 static unsigned char shift_map[] = {
 851           0,   27,  '+',  '"',  '*',    0,  '%',  '&',
 852         '/',  '(',  ')',  '=',  '?',  '`',  127,    9,
 853         'Q',  'W',  'E',  'R',  'T',  'Z',  'U',  'I',
 854         'O',  'P',    0,  '!',   13,    0,  'A',  'S',
 855         'D',  'F',  'G',  'H',  'J',  'K',  'L',    0,
 856           0,    0,    0,    0,  'Y',  'X',  'C',  'V',
 857         'B',  'N',  'M',  ';',  ':',  '_',    0,  '*',
 858           0,   32,    0,    0,    0,    0,    0,    0,
 859           0,    0,    0,    0,    0,    0,    0,    0,
 860           0,    0,  '-',    0,    0,    0,  '+',    0,
 861           0,    0,    0,    0,    0,    0,  '>',    0,
 862           0,    0,    0,    0,    0,    0,    0,    0,
 863           0 };
 864 
 865 static unsigned char alt_map[] = {
 866           0,    0,    0,  '@',  '#',    0,    0,    0,
 867         '|',    0,    0,    0, '\'',  '~',    0,    0,
 868         '@',    0,    0,    0,    0,    0,    0,    0,
 869           0,    0,   '[',  ']',  13,    0,    0,    0,
 870           0,    0,    0,    0,    0,    0,    0,    0,
 871         '{',    0,    0,  '}',    0,    0,    0,    0,
 872           0,    0,    0,    0,    0,    0,    0,    0,
 873           0,    0,    0,    0,    0,    0,    0,    0,
 874           0,    0,    0,    0,    0,    0,    0,    0,
 875           0,    0,    0,    0,    0,    0,    0,    0,
 876           0,    0,    0,    0,    0,    0, '\\',    0,
 877           0,    0,    0,    0,    0,    0,    0,    0,
 878           0 };
 879 
 880 #elif defined KBD_SG_LATIN1
 881 
 882 static unsigned char key_map[] = {
 883           0,   27,  '1',  '2',  '3',  '4',  '5',  '6',
 884         '7',  '8',  '9',  '0', '\'',  '^',  127,    9,
 885         'q',  'w',  'e',  'r',  't',  'z',  'u',  'i',
 886         'o',  'p',  252,    0,   13,    0,  'a',  's',
 887         'd',  'f',  'g',  'h',  'j',  'k',  'l',  246,
 888         228,  167,    0,  '$',  'y',  'x',  'c',  'v',
 889         'b',  'n',  'm',  ',',  '.',  '-',    0,  '*',
 890           0,   32,    0,    0,    0,    0,    0,    0,
 891           0,    0,    0,    0,    0,    0,    0,    0,
 892           0,    0,  '-',    0,    0,    0,  '+',    0,
 893           0,    0,    0,    0,    0,    0,  '<',    0,
 894           0,    0,    0,    0,    0,    0,    0,    0,
 895           0 };
 896 
 897 static unsigned char shift_map[] = {
 898           0,   27,  '+',  '"',  '*',  231,  '%',  '&',
 899         '/',  '(',  ')',  '=',  '?',  '`',  127,    9,
 900         'Q',  'W',  'E',  'R',  'T',  'Z',  'U',  'I',
 901         'O',  'P',  220,  '!',   13,    0,  'A',  'S',
 902         'D',  'F',  'G',  'H',  'J',  'K',  'L',  214,
 903         196,  176,    0,  163,  'Y',  'X',  'C',  'V',
 904         'B',  'N',  'M',  ';',  ':',  '_',    0,  '*',
 905           0,   32,    0,    0,    0,    0,    0,    0,
 906           0,    0,    0,    0,    0,    0,    0,    0,
 907           0,    0,  '-',    0,    0,    0,  '+',    0,
 908           0,    0,    0,    0,    0,    0,  '>',    0,
 909           0,    0,    0,    0,    0,    0,    0,    0,
 910           0 };
 911 
 912 static unsigned char alt_map[] = {
 913           0,    0,    0,  '@',  '#',    0,    0,  172,
 914         '|',  162,    0,    0, '\'',  '~',    0,    0,
 915         '@',    0,    0,    0,    0,    0,    0,    0,
 916           0,    0,  '[',  ']',   13,    0,    0,    0,
 917           0,    0,    0,    0,    0,    0,    0,  233,
 918         '{',    0,    0,  '}',    0,    0,    0,    0,
 919           0,    0,    0,    0,    0,    0,    0,    0,
 920           0,    0,    0,    0,    0,    0,    0,    0,
 921           0,    0,    0,    0,    0,    0,    0,    0,
 922           0,    0,    0,    0,    0,    0,    0,    0,
 923           0,    0,    0,    0,    0,    0, '\\',    0,
 924           0,    0,    0,    0,    0,    0,    0,    0,
 925           0 };
 926 
 927 #elif defined KBD_NO
 928 
 929 static unsigned char key_map[] = {
 930           0,   27,  '1',  '2',  '3',  '4',  '5',  '6',
 931         '7',  '8',  '9',  '0',  '+', '\\',  127,    9,
 932         'q',  'w',  'e',  'r',  't',  'y',  'u',  'i',
 933         'o',  'p',  '}',  '~',   13,    0,  'a',  's',
 934         'd',  'f',  'g',  'h',  'j',  'k',  'l',  '|',
 935         '{',  '|',    0, '\'',  'z',  'x',  'c',  'v',
 936         'b',  'n',  'm',  ',',  '.',  '-',    0,  '*',
 937           0,   32,    0,    0,    0,    0,    0,    0,
 938           0,    0,    0,    0,    0,    0,    0,    0,
 939           0,    0,  '-',    0,    0,    0,  '+',    0,
 940           0,    0,    0,    0,    0,    0,  '<',    0,
 941           0,    0,    0,    0,    0,    0,    0,    0,
 942           0 };
 943 
 944 static unsigned char shift_map[] = {
 945           0,   27,  '!', '\"',  '#',  '$',  '%',  '&',
 946         '/',  '(',  ')',  '=',  '?',  '`',  127,    9,
 947         'Q',  'W',  'E',  'R',  'T',  'Y',  'U',  'I',
 948         'O',  'P',  ']',  '^',   13,    0,  'A',  'S',
 949         'D',  'F',  'G',  'H',  'J',  'K',  'L', '\\',
 950         '[',    0,    0,  '*',  'Z',  'X',  'C',  'V',
 951         'B',  'N',  'M',  ';',  ':',  '_',    0,  '*',
 952           0,   32,    0,    0,    0,    0,    0,    0,
 953           0,    0,    0,    0,    0,    0,    0,    0,
 954           0,    0,  '-',    0,    0,    0,  '+',    0,
 955           0,    0,    0,    0,    0,    0,  '>',    0,
 956           0,    0,    0,    0,    0,    0,    0,    0,
 957           0 };
 958 
 959 static unsigned char alt_map[] = {
 960           0,    0,    0,  '@',    0,  '$',    0,    0,
 961         '{',   '[',  ']', '}',    0, '\'',    0,    0,
 962           0,    0,    0,    0,    0,    0,    0,    0,
 963           0,    0,    0,  '~',   13,    0,    0,    0,
 964           0,    0,    0,    0,    0,    0,    0,    0,
 965           0,    0,    0,    0,    0,    0,    0,    0,
 966           0,    0,    0,    0,    0,    0,    0,    0,
 967           0,    0,    0,    0,    0,    0,    0,    0,
 968           0,    0,    0,    0,    0,    0,    0,    0,
 969           0,    0,    0,    0,    0,    0,    0,    0,
 970           0,    0,    0,    0,    0,    0,    0,    0,
 971           0,    0,    0,    0,    0,    0,    0,    0,
 972           0 };
 973 
 974 #elif defined KBD_SF
 975 
 976 static unsigned char key_map[] = {
 977           0,   27,  '1',  '2',  '3',  '4',  '5',  '6',
 978         '7',  '8',  '9',  '0', '\'',  '^',  127,    9,
 979         'q',  'w',  'e',  'r',  't',  'z',  'u',  'i',
 980         'o',  'p',    0,    0,   13,    0,  'a',  's',
 981         'd',  'f',  'g',  'h',  'j',  'k',  'l',    0,
 982           0,    0,   0,   '$',  'y',  'x',  'c',  'v',
 983         'b',  'n',  'm',  ',',  '.',  '-',    0,  '*',
 984           0,   32,    0,    0,    0,    0,    0,    0,
 985           0,    0,    0,    0,    0,    0,    0,    0,
 986           0,    0,  '-',    0,    0,    0,  '+',    0,
 987           0,    0,    0,    0,    0,    0,  '<',    0,
 988           0,    0,    0,    0,    0,    0,    0,    0,
 989           0 };
 990 static unsigned char shift_map[] = {
 991           0,   27,  '+',  '"',  '*',    0,  '%',  '&',
 992         '/',  '(',  ')',  '=',  '?',  '`',  127,    9,
 993         'Q',  'W',  'E',  'R',  'T',  'Z',  'U',  'I',
 994         'O',  'P',    0,  '!',   13,    0,  'A',  'S',
 995         'D',  'F',  'G',  'H',  'J',  'K',  'L',    0,
 996           0,    0,    0,    0,  'Y',  'X',  'C',  'V',
 997         'B',  'N',  'M',  ';',  ':',  '_',    0,  '*',
 998           0,   32,    0,    0,    0,    0,    0,    0,
 999           0,    0,    0,    0,    0,    0,    0,    0,
1000           0,    0,  '-',    0,    0,    0,  '+',    0,
1001           0,    0,    0,    0,    0,    0,  '>',    0,
1002           0,    0,    0,    0,    0,    0,    0,    0,
1003           0 };
1004 static unsigned char alt_map[] = {
1005           0,    0,    0,  '@',  '#',    0,    0,    0,
1006         '|',    0,    0,    0,  '\'', '~',    0,    0,
1007           0,    0,    0,    0,    0,    0,    0,    0,
1008           0,    0,   '[',  ']',  13,    0,    0,    0,
1009           0,    0,    0,    0,    0,    0,    0,    0,
1010          '{',   0,    0,   '}',   0,    0,    0,    0,
1011           0,    0,    0,    0,    0,    0,    0,    0,
1012           0,    0,    0,    0,    0,    0,    0,    0,
1013           0,    0,    0,    0,    0,    0,    0,    0,
1014           0,    0,    0,    0,    0,    0,    0,    0,
1015           0,    0,    0,    0,    0,    0,  '\\',   0,
1016           0,    0,    0,    0,    0,    0,    0,    0,
1017           0 };
1018 
1019 #elif defined KBD_SF_LATIN1
1020 
1021 static unsigned char key_map[] = {
1022           0,   27,  '1',  '2',  '3',  '4',  '5',  '6',
1023         '7',  '8',  '9',  '0', '\'',  '^',  127,    9,
1024         'q',  'w',  'e',  'r',  't',  'z',  'u',  'i',
1025         'o',  'p',  232,  168,   13,    0,  'a',  's',
1026         'd',  'f',  'g',  'h',  'j',  'k',  'l',  233,
1027         224,  167,    0,  '$',  'y',  'x',  'c',  'v',
1028         'b',  'n',  'm',  ',',  '.',  '-',    0,  '*',
1029           0,   32,    0,    0,    0,    0,    0,    0,
1030           0,    0,    0,    0,    0,    0,    0,    0,
1031           0,    0,  '-',    0,    0,    0,  '+',    0,
1032           0,    0,    0,    0,    0,    0,  '<',    0,
1033           0,    0,    0,    0,    0,    0,    0,    0,
1034           0 };
1035 static unsigned char shift_map[] = {
1036           0,   27,  '+',  '"',  '*',  231,  '%',  '&',
1037         '/',  '(',  ')',  '=',  '?',  '`',  127,    9,
1038         'Q',  'W',  'E',  'R',  'T',  'Z',  'U',  'I',
1039         'O',  'P',  252,  '!',   13,    0,  'A',  'S',
1040         'D',  'F',  'G',  'H',  'J',  'K',  'L',  246,
1041         228,  176,    0,  163,  'Y',  'X',  'C',  'V',
1042         'B',  'N',  'M',  ';',  ':',  '_',    0,  '*',
1043           0,   32,    0,    0,    0,    0,    0,    0,
1044           0,    0,    0,    0,    0,    0,    0,    0,
1045           0,    0,  '-',    0,    0,    0,  '+',    0,
1046           0,    0,    0,    0,    0,    0,  '>',    0,
1047           0,    0,    0,    0,    0,    0,    0,    0,
1048           0 };
1049 static unsigned char alt_map[] = {
1050           0,    0,    0,  '@',  '#',    0,    0,  172,
1051         '|',   162,   0,    0,  180,  '~',    0,    0,
1052           0,    0,    0,    0,    0,    0,    0,    0,
1053           0,    0,   '[',  ']',  13,    0,    0,    0,
1054           0,    0,    0,    0,    0,    0,    0,    0,
1055          '{',   0,    0,   '}',   0,    0,    0,    0,
1056           0,    0,    0,    0,    0,    0,    0,    0,
1057           0,    0,    0,    0,    0,    0,    0,    0,
1058           0,    0,    0,    0,    0,    0,    0,    0,
1059           0,    0,    0,    0,    0,    0,    0,    0,
1060           0,    0,    0,    0,    0,    0,  '\\',   0,
1061           0,    0,    0,    0,    0,    0,    0,    0,
1062           0 };
1063 #else
1064 #error "KBD-type not defined"
1065 #endif
1066 
1067 static void do_self(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
1068 {
1069         unsigned char ch;
1070 
1071         if (kbd_flag(KG_ALTGR))
1072                 ch = alt_map[sc];
1073         else if (kbd_flag(KG_LSHIFT) || kbd_flag(KG_RSHIFT) ||
1074                  kbd_flag(KG_LCTRL) || kbd_flag(KG_RCTRL))
1075                 ch = shift_map[sc];
1076         else
1077                 ch = key_map[sc];
1078 
1079         if (ch == 0)
1080                 return;
1081 
1082         if ((ch = handle_diacr(ch)) == 0)
1083                 return;
1084 
1085         if (kbd_flag(KG_LCTRL) || kbd_flag(KG_RCTRL) ||
1086             vc_kbd_flag(kbd,VC_CAPSLOCK))       /* ctrl or caps */
1087                 if ((ch >= 'a' && ch <= 'z') || (ch >= 224 && ch <= 254))
1088                         ch -= 32;
1089         if (kbd_flag(KG_LCTRL) || kbd_flag(KG_RCTRL))   /* ctrl */
1090                 ch &= 0x1f;
1091 
1092         if (kbd_flag(KG_ALT))
1093                 if (vc_kbd_flag(kbd,VC_META)) {
1094                         put_queue('\033');
1095                         put_queue(ch);
1096                 } else
1097                         put_queue(ch|0x80);
1098         else
1099                 put_queue(ch);
1100 }
1101 
1102 unsigned char accent_table[5][64] = {
1103         " \300BCD\310FGH\314JKLMN\322PQRST\331VWXYZ[\\]^_"
1104         "`\340bcd\350fgh\354jklmn\362pqrst\371vwxyz{|}~",   /* accent grave */
1105 
1106         " \301BCD\311FGH\315JKLMN\323PQRST\332VWX\335Z[\\]^_"
1107         "`\341bcd\351fgh\355jklmn\363pqrst\372vwxyz{|}~",   /* accent acute */
1108 
1109         " \302BCD\312FGH\316JKLMN\324PQRST\333VWXYZ[\\]^_"
1110         "`\342bcd\352fgh\356jklmn\364pqrst\373vwxyz{|}~",   /* circumflex */
1111 
1112         " \303BCDEFGHIJKLMN\325PQRSTUVWXYZ[\\]^_"
1113         "`\343bcdefghijklm\361\365pqrstuvwxyz{|}~",         /* tilde */
1114 
1115         " \304BCD\313FGH\316JKLMN\326PQRST\334VWXYZ[\\]^_"
1116         "`\344bcd\353fgh\357jklmn\366pqrst\374vwx\377z{|}~" /* dieresis */
1117 };
1118 
1119 /*
1120  * Check if dead key pressed. If so, check if same key pressed twice;
1121  * in that case return the char, otherwise store char and return 0.
1122  * If dead key not pressed, check if accented character pending. If
1123  * not: return the char, otherwise check if char is a space. If it is
1124  * a space return the diacritical. Else combine char with diacritical
1125  * mark and return.
1126  */
1127 
1128 unsigned int handle_diacr(unsigned int ch)
     /* [previous][next][first][last][top][bottom][index][help] */
1129 {
1130         static unsigned char diacr_table[] =
1131                 {'`', 180, '^', '~', 168, 0};           /* Must end with 0 */
1132         static unsigned char ret_diacr[] =
1133                 {'`', '\'', '^', '~', '"' };            /* Must not end with 0 */
1134         int i;
1135 
1136         for(i=0; diacr_table[i]; i++)
1137                 if (ch==diacr_table[i] && ((1<<i)&kbd->kbd_flags)) {
1138                         if (diacr == i) {
1139                                 diacr=-1;
1140                                 return ret_diacr[i];    /* pressed twice */
1141                         } else {
1142                                 diacr=i;                /* key is dead */
1143                                 return 0;
1144                         }
1145                 }
1146         if (diacr == -1)
1147                 return ch;
1148         else if (ch == ' ') {
1149                 ch=ret_diacr[diacr];
1150                 diacr=-1;
1151                 return ch;
1152         } else if (ch<64 || ch>122) {
1153                 diacr=-1;
1154                 return ch;
1155         } else {
1156                 ch=accent_table[diacr][ch-64];
1157                 diacr=-1;
1158                 return ch;
1159         }
1160 }
1161 
1162 #if defined KBD_FR || defined KBD_US || defined KBD_UK || defined KBD_FR_LATIN1
1163 static unsigned char num_table[] = "789-456+1230.";
1164 #else
1165 static unsigned char num_table[] = "789-456+1230,";
1166 #endif
1167 
1168 static unsigned char cur_table[] = "1A5-DGC+4B623";
1169 static unsigned int pad_table[] = { 7,8,9,0,4,5,6,0,1,2,3,0,0 };
1170 
1171 /*
1172     Keypad /                    35      B7      Q
1173     Keypad *  (PrtSc)           37      B7      R
1174     Keypad NumLock              45      ??      P
1175     Keypad 7  (Home)            47      C7      w
1176     Keypad 8  (Up arrow)        48      C8      x
1177     Keypad 9  (PgUp)            49      C9      y
1178     Keypad -                    4A      CA      S
1179     Keypad 4  (Left arrow)      4B      CB      t
1180     Keypad 5                    4C      CC      u
1181     Keypad 6  (Right arrow)     4D      CD      v
1182     Keypad +                    4E      CE      l
1183     Keypad 1  (End)             4F      CF      q
1184     Keypad 2  (Down arrow)      50      D0      r
1185     Keypad 3  (PgDn)            51      D1      s
1186     Keypad 0  (Ins)             52      D2      p
1187     Keypad .  (Del)             53      D3      n
1188 */
1189 
1190 static unsigned char appl_table[] = "wxyStuvlqrspn";
1191 
1192 /*
1193   Set up keyboard to generate DEC VT200 F-keys.
1194   DEC F1  - F5  not implemented (DEC HOLD, LOCAL PRINT, SETUP, SW SESS, BREAK)
1195   DEC F6  - F10 are mapped to F6 - F10
1196   DEC F11 - F20 are mapped to Shift-F1 - Shift-F10
1197   DEC HELP and DEC DO are mapped to F11, F12 or Shift- F11, F12.
1198   Regular (?) Linux F1-F5 remain the same.
1199 */
1200 
1201 static char *func_table[2][12] = { /* DEC F1 - F10 */ {
1202         "\033[[A",  "\033[[B",  "\033[[C",  "\033[[D",
1203         "\033[[E",  "\033[17~", "\033[18~", "\033[19~",
1204         "\033[20~", "\033[21~", "\033[28~", "\033[29~"
1205 }, /* DEC F11 - F20 */ {
1206         "\033[23~", "\033[24~", "\033[25~", "\033[26~",
1207         "\033[28~", "\033[29~", "\033[31~", "\033[32~",
1208         "\033[33~", "\033[34~", "\033[28~", "\033[29~"
1209 }};
1210 
1211 static void cursor(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
1212 {
1213         if (sc < 0x47 || sc > 0x53)
1214                 return;
1215         sc -= 0x47;
1216         if (sc == 12 &&
1217             (kbd_flag(KG_LCTRL) || kbd_flag(KG_RCTRL)) &&
1218             (kbd_flag(KG_ALT) || kbd_flag(KG_ALTGR))) {
1219                 ctrl_alt_del();
1220                 return;
1221         }
1222         if (kbd_dead(KGD_E0)) {
1223                 cur(sc);
1224                 return;
1225         }
1226 
1227         if (kbd_flag(KG_ALT) && sc != 12) {                     /* Alt-numpad */
1228                 npadch=npadch*10+pad_table[sc];
1229                 return;
1230         }
1231 
1232         if (vc_kbd_flag(kbd,VC_APPLIC) &&
1233             !kbd_flag(KG_LSHIFT) &&     /* shift forces cursor */
1234             !kbd_flag(KG_RSHIFT)) {
1235                 applkey(appl_table[sc]);
1236                 return;
1237         }
1238 
1239         if (vc_kbd_flag(kbd,VC_NUMLOCK)) {
1240                 put_queue(num_table[sc]);
1241         } else
1242                 cur(sc);
1243 }
1244 
1245 static void cur(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
1246 {
1247         char buf[] = { 0x1b, '[', 0, 0, 0 };            /* must not be static */
1248 
1249         buf[2]=cur_table[sc];
1250         if (buf[2] < '9')
1251                 buf[3]='~';
1252         else
1253                 if ((buf[2] >= 'A' && buf[2] <= 'D') ?
1254                     vc_kbd_flag(kbd,VC_CKMODE) :
1255                     vc_kbd_flag(kbd,VC_APPLIC))
1256                         buf[1]='O';
1257         puts_queue(buf);
1258 }
1259 
1260 static void func(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
1261 {
1262         if (sc < 0x3b)
1263                 return;
1264         sc-=0x3b;
1265         if (sc > 9) {
1266                 sc-=18;
1267                 if (sc < 10 || sc > 11)
1268                         return;
1269         }
1270         if (kbd_flag(KG_ALT))
1271                 want_console = sc;
1272         else
1273                 if (kbd_flag(KG_LSHIFT) || kbd_flag(KG_RSHIFT)) /* DEC F11 - F20 */
1274                         puts_queue(func_table[1][sc]);
1275                 else                                    /* DEC F1 - F10 */
1276                         puts_queue(func_table[0][sc]);
1277 }
1278 
1279 static void slash(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
1280 {
1281         if (!kbd_dead(KGD_E0))
1282                 do_self(sc);
1283         else if (vc_kbd_flag(kbd,VC_APPLIC))
1284                 applkey('Q');
1285         else
1286                 put_queue('/');
1287 }
1288 
1289 static void star(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
1290 {
1291         if (kbd_dead(KGD_E0))
1292                 /* Print screen key sends E0 2A E0 37 and puts
1293                    the VT100-ESC sequence ESC [ i into the queue, ChN */
1294                 puts_queue("\033\133\151");
1295         else if (vc_kbd_flag(kbd,VC_APPLIC))
1296                 applkey('R');
1297         else
1298                 do_self(sc);
1299 }
1300 
1301 static void enter(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
1302 {
1303         if (kbd_dead(KGD_E0) && vc_kbd_flag(kbd,VC_APPLIC))
1304                 applkey('M');
1305         else {
1306                 put_queue(13);
1307                 if (vc_kbd_flag(kbd,VC_CRLF))
1308                         put_queue(10);
1309         }
1310 }
1311 
1312 static void minus(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
1313 {
1314         if (vc_kbd_flag(kbd,VC_APPLIC))
1315                 applkey('S');
1316         else
1317                 do_self(sc);
1318 }
1319 
1320 static void plus(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
1321 {
1322         if (vc_kbd_flag(kbd,VC_APPLIC))
1323                 applkey('l');
1324         else
1325                 do_self(sc);
1326 }
1327 
1328 static void none(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
1329 {
1330 }
1331 
1332 /*
1333  * send_data sends a character to the keyboard and waits
1334  * for a acknowledge, possibly retrying if asked to. Returns
1335  * the success status.
1336  */
1337 static int send_data(unsigned char data)
     /* [previous][next][first][last][top][bottom][index][help] */
1338 {
1339         int retries = 3;
1340         int i;
1341 
1342         do {
1343                 kb_wait();
1344                 acknowledge = 0;
1345                 resend = 0;
1346                 outb_p(data, 0x60);
1347                 for(i=0; i<0x20000; i++) {
1348                         inb_p(0x64);            /* just as a delay */
1349                         if (acknowledge)
1350                                 return 1;
1351                         if (resend)
1352                                 goto repeat;
1353                 }
1354                 return 0;
1355 repeat:
1356         } while (retries-- > 0);
1357         return 0;
1358 }
1359 
1360 /*
1361  * This routine is the bottom half of the keyboard interrupt
1362  * routine, and runs with all interrupts enabled. It does
1363  * console changing, led setting and copy_to_cooked, which can
1364  * take a reasonably long time.
1365  *
1366  * Aside from timing (which isn't really that important for
1367  * keyboard interrupts as they happen often), using the software
1368  * interrupt routines for this thing allows us to easily mask
1369  * this when we don't want any of the above to happen. Not yet
1370  * used, but this allows for easy and efficient race-condition
1371  * prevention later on.
1372  */
1373 static void kbd_bh(void * unused)
     /* [previous][next][first][last][top][bottom][index][help] */
1374 {
1375         static unsigned char old_leds = -1;
1376         unsigned char leds = kbd_table[fg_console].flags & LED_MASK;
1377 
1378         if (leds != old_leds) {
1379                 old_leds = leds;
1380                 if (!send_data(0xed) || !send_data(leds))
1381                         send_data(0xf4);        /* re-enable kbd if any errors */
1382         }
1383         if (want_console >= 0) {
1384                 if (want_console != fg_console) {
1385                         last_console = fg_console;
1386                         change_console(want_console);
1387                 }
1388                 want_console = -1;
1389         }
1390         do_keyboard_interrupt();
1391         cli();
1392         if (inb_p(0x64) & 0x01)
1393                 fake_keyboard_interrupt();
1394         sti();
1395 }
1396 
1397 long no_idt[2] = {0, 0};
1398 
1399 /*
1400  * This routine reboots the machine by asking the keyboard
1401  * controller to pulse the reset-line low. We try that for a while,
1402  * and if it doesn't work, we do some other stupid things.
1403  */
1404 void hard_reset_now(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1405 {
1406         int i, j;
1407         extern unsigned long pg0[1024];
1408 
1409         sti();
1410 /* rebooting needs to touch the page at absolute addr 0 */
1411         pg0[0] = 7;
1412         *((unsigned short *)0x472) = 0x1234;
1413         for (;;) {
1414                 for (i=0; i<100; i++) {
1415                         kb_wait();
1416                         for(j = 0; j < 100000 ; j++)
1417                                 /* nothing */;
1418                         outb(0xfe,0x64);         /* pulse reset low */
1419                 }
1420                 __asm__("\tlidt _no_idt"::);
1421         }
1422 }
1423 
1424 static fptr key_table[] = {
1425         none,do_self,do_self,do_self,           /* 00-03 s0 esc 1 2 */
1426         do_self,do_self,do_self,do_self,        /* 04-07 3 4 5 6 */
1427         do_self,do_self,do_self,do_self,        /* 08-0B 7 8 9 0 */
1428         do_self,do_self,do_self,do_self,        /* 0C-0F + ' bs tab */
1429         do_self,do_self,do_self,do_self,        /* 10-13 q w e r */
1430         do_self,do_self,do_self,do_self,        /* 14-17 t y u i */
1431         do_self,do_self,do_self,do_self,        /* 18-1B o p } ^ */
1432         enter,ctrl,do_self,do_self,             /* 1C-1F enter ctrl a s */
1433         do_self,do_self,do_self,do_self,        /* 20-23 d f g h */
1434         do_self,do_self,do_self,do_self,        /* 24-27 j k l | */
1435         do_self,do_self,lshift,do_self,         /* 28-2B { para lshift , */
1436         do_self,do_self,do_self,do_self,        /* 2C-2F z x c v */
1437         do_self,do_self,do_self,do_self,        /* 30-33 b n m , */
1438         do_self,slash,rshift,star,              /* 34-37 . - rshift * */
1439         alt,do_self,caps,func,                  /* 38-3B alt sp caps f1 */
1440         func,func,func,func,                    /* 3C-3F f2 f3 f4 f5 */
1441         func,func,func,func,                    /* 40-43 f6 f7 f8 f9 */
1442         func,num,scroll,cursor,                 /* 44-47 f10 num scr home */
1443         cursor,cursor,minus,cursor,             /* 48-4B up pgup - left */
1444         cursor,cursor,plus,cursor,              /* 4C-4F n5 right + end */
1445         cursor,cursor,cursor,cursor,            /* 50-53 dn pgdn ins del */
1446         sysreq,none,do_self,func,                       /* 54-57 sysreq ? < f11 */
1447         func,none,none,none,                    /* 58-5B f12 ? ? ? */
1448         none,none,none,none,                    /* 5C-5F ? ? ? ? */
1449         none,none,none,none,                    /* 60-63 ? ? ? ? */
1450         none,none,none,none,                    /* 64-67 ? ? ? ? */
1451         none,none,none,none,                    /* 68-6B ? ? ? ? */
1452         none,none,none,none,                    /* 6C-6F ? ? ? ? */
1453         none,none,none,none,                    /* 70-73 ? ? ? ? */
1454         none,none,none,none,                    /* 74-77 ? ? ? ? */
1455         none,none,none,none,                    /* 78-7B ? ? ? ? */
1456         none,none,none,none,                    /* 7C-7F ? ? ? ? */
1457         none,none,none,none,                    /* 80-83 ? br br br */
1458         none,none,none,none,                    /* 84-87 br br br br */
1459         none,none,none,none,                    /* 88-8B br br br br */
1460         none,none,none,none,                    /* 8C-8F br br br br */
1461         none,none,none,none,                    /* 90-93 br br br br */
1462         none,none,none,none,                    /* 94-97 br br br br */
1463         none,none,none,none,                    /* 98-9B br br br br */
1464         none,unctrl,none,none,                  /* 9C-9F br unctrl br br */
1465         none,none,none,none,                    /* A0-A3 br br br br */
1466         none,none,none,none,                    /* A4-A7 br br br br */
1467         none,none,unlshift,none,                /* A8-AB br br unlshift br */
1468         none,none,none,none,                    /* AC-AF br br br br */
1469         none,none,none,none,                    /* B0-B3 br br br br */
1470         none,none,unrshift,none,                /* B4-B7 br br unrshift br */
1471         unalt,none,uncaps,none,                 /* B8-BB unalt br uncaps br */
1472         none,none,none,none,                    /* BC-BF br br br br */
1473         none,none,none,none,                    /* C0-C3 br br br br */
1474         none,none,none,none,                    /* C4-C7 br br br br */
1475         none,none,none,none,                    /* C8-CB br br br br */
1476         none,none,none,none,                    /* CC-CF br br br br */
1477         none,none,none,none,                    /* D0-D3 br br br br */
1478         none,none,none,none,                    /* D4-D7 br br br br */
1479         none,none,none,none,                    /* D8-DB br ? ? ? */
1480         none,none,none,none,                    /* DC-DF ? ? ? ? */
1481         none,none,none,none,                    /* E0-E3 e0 e1 ? ? */
1482         none,none,none,none,                    /* E4-E7 ? ? ? ? */
1483         none,none,none,none,                    /* E8-EB ? ? ? ? */
1484         none,none,none,none,                    /* EC-EF ? ? ? ? */
1485         none,none,none,none,                    /* F0-F3 ? ? ? ? */
1486         none,none,none,none,                    /* F4-F7 ? ? ? ? */
1487         none,none,none,none,                    /* F8-FB ? ? ? ? */
1488         none,none,none,none                     /* FC-FF ? ? ? ? */
1489 };
1490 
1491 unsigned long kbd_init(unsigned long kmem_start)
     /* [previous][next][first][last][top][bottom][index][help] */
1492 {
1493         int i;
1494         struct kbd_struct * kbd;
1495 
1496         kbd = kbd_table + 0;
1497         for (i = 0 ; i < NR_CONSOLES ; i++,kbd++) {
1498                 kbd->flags = KBD_DEFFLAGS;
1499                 kbd->default_flags = KBD_DEFFLAGS;
1500                 kbd->kbd_flags = KBDFLAGS;
1501         }
1502         bh_base[KEYBOARD_BH].routine = kbd_bh;
1503         request_irq(KEYBOARD_IRQ,keyboard_interrupt);
1504         mark_bh(KEYBOARD_BH);
1505         return kmem_start;
1506 }

/* [previous][next][first][last][top][bottom][index][help] */