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

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