root/kernel/chr_drv/keyboard.c

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

DEFINITIONS

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

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

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