root/kernel/chr_drv/keyboard.c

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

DEFINITIONS

This source file includes following definitions.
  1. do_keyboard
  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. scroll
  16. num
  17. applkey
  18. do_self
  19. handle_diacr
  20. cursor
  21. cur
  22. func
  23. slash
  24. star
  25. enter
  26. minus
  27. plus
  28. none
  29. kb_wait
  30. kb_ack
  31. 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 <asm/io.h>
  14 #include <asm/system.h>
  15 
  16 #define LSHIFT   0x01
  17 #define RSHIFT   0x02
  18 #define LCTRL    0x04
  19 #define RCTRL    0x08
  20 #define ALT      0x10
  21 #define ALTGR    0x20
  22 #define CAPS     0x40
  23 #define CAPSDOWN 0x80
  24 
  25 #define SCRLED   0x01
  26 #define NUMLED   0x02
  27 #define CAPSLED  0x04
  28 
  29 #define NO_META_BIT 0x80
  30 
  31 unsigned char kapplic = 0;
  32 unsigned char kmode = 0;
  33 unsigned char kleds = NUMLED;
  34 unsigned char ke0 = 0;
  35 unsigned char kraw = 0;
  36 unsigned char kbd_flags = KBDFLAGS;
  37 
  38 extern void do_keyboard_interrupt(void);
  39 extern void ctrl_alt_del(void);
  40 extern void show_mem(void), show_state(void);
  41 extern void change_console(unsigned int new_console);
  42 extern struct tty_queue *table_list[];
  43 
  44 typedef void (*fptr)(int);
  45 
  46 static unsigned char old_leds = 2;
  47 static int diacr = -1;
  48 static int npadch = 0;
  49 fptr key_table[];
  50 
  51 static void put_queue(int);
  52 void set_leds(void);
  53 static void applkey(int);
  54 static void cur(int);
  55 static void kb_wait(void), kb_ack(void);
  56 static unsigned int handle_diacr(unsigned int);
  57 
  58 void do_keyboard(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  59 {
  60         unsigned char scancode, x;
  61 
  62         scancode=inb_p(0x60);
  63         x=inb_p(0x61);
  64         outb_p(x|0x80, 0x61);
  65         outb_p(x&0x7f, 0x61);
  66         outb(0x20, 0x20);
  67         sti();
  68 
  69         if (kraw) {
  70                 put_queue(scancode);
  71                 do_keyboard_interrupt();
  72         } else if (scancode == 0xe0)
  73                 ke0 = 1;
  74         else if (scancode == 0xe1)
  75                 ke0 = 2;
  76         else {
  77                 key_table[scancode](scancode);
  78                 do_keyboard_interrupt();
  79                 ke0 = 0;
  80         }
  81 }
  82 
  83 static void put_queue(int ch)
     /* [previous][next][first][last][top][bottom][index][help] */
  84 {
  85         register struct tty_queue *qp = table_list[0];
  86         unsigned long new_head;
  87 
  88         qp->buf[qp->head]=ch;
  89         if ((new_head=(qp->head+1)&(TTY_BUF_SIZE-1)) != qp->tail)
  90                 qp->head=new_head;
  91         if (qp->proc_list != NULL)
  92                 qp->proc_list->state=0;
  93 }
  94 
  95 static void puts_queue(char *cp)
     /* [previous][next][first][last][top][bottom][index][help] */
  96 {
  97         register struct tty_queue *qp = table_list[0];
  98         unsigned long new_head;
  99         char ch;
 100 
 101         while (ch=*cp++) {
 102                 qp->buf[qp->head]=ch;
 103                 if ((new_head=(qp->head+1)&(TTY_BUF_SIZE-1))
 104                                  != qp->tail)
 105                         qp->head=new_head;
 106         }
 107         if (qp->proc_list != NULL)
 108                 qp->proc_list->state=0;
 109 }
 110 
 111 static void ctrl(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
 112 {
 113         if (ke0)
 114                 kmode|=RCTRL;
 115         else
 116                 kmode|=LCTRL;
 117 }
 118 
 119 static void alt(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
 120 {
 121         if (ke0)
 122                 kmode|=ALTGR;
 123         else
 124                 kmode|=ALT;
 125 }
 126 
 127 static void unctrl(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
 128 {
 129         if (ke0)
 130                 kmode&=(~RCTRL);
 131         else
 132                 kmode&=(~LCTRL);
 133 }
 134 
 135 static void unalt(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
 136 {
 137         if (ke0)
 138                 kmode&=(~ALTGR);
 139         else {
 140                 kmode&=(~ALT);
 141                 if (npadch != 0) {
 142                         put_queue(npadch);
 143                         npadch=0;
 144                 }
 145         }
 146 }
 147 
 148 static void lshift(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
 149 {
 150         kmode|=LSHIFT;
 151 }
 152 
 153 static void unlshift(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
 154 {
 155         kmode&=(~LSHIFT);
 156 }
 157 
 158 static void rshift(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
 159 {
 160         kmode|=RSHIFT;
 161 }
 162 
 163 static void unrshift(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
 164 {
 165         kmode&=(~RSHIFT);
 166 }
 167 
 168 static void caps(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
 169 {
 170         if (!(kmode&CAPSDOWN)) {
 171                 kleds^=CAPSLED;
 172                 kmode^=CAPS;
 173                 kmode|=CAPSDOWN;
 174                 set_leds();
 175         }
 176 }
 177 
 178 void set_leds(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 179 {
 180         if (kleds != old_leds) {
 181                 old_leds=kleds;
 182                 kb_wait();
 183                 outb(0xed, 0x60);       /* set leds command */
 184                 kb_ack();
 185                 kb_wait();
 186                 outb(kleds, 0x60);
 187                 kb_ack();
 188         }
 189 }
 190 
 191 static void uncaps(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
 192 {
 193         kmode&=(~CAPSDOWN);
 194 }
 195 
 196 static void scroll(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
 197 {
 198         if (kmode&(LSHIFT|RSHIFT))
 199                 show_mem();
 200         else
 201                 show_state();
 202         kleds^=SCRLED;
 203         set_leds();
 204 }
 205 
 206 static void num(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
 207 {
 208         if (kapplic)
 209                 applkey(0x50);
 210         else {
 211                 kleds^=NUMLED;
 212                 set_leds();
 213         }
 214 }
 215 
 216 static void applkey(int key)
     /* [previous][next][first][last][top][bottom][index][help] */
 217 {
 218         char buf[] = { 0x1b, 0x4f, 0x00, 0x00 };
 219 
 220         buf[2]=key;
 221         puts_queue(buf);
 222 }
 223 
 224 
 225 #if defined KBD_FINNISH
 226 
 227 static unsigned char key_map[] = {
 228           0,   27,  '1',  '2',  '3',  '4',  '5',  '6',
 229         '7',  '8',  '9',  '0',  '+', '\'',  127,    9,
 230         'q',  'w',  'e',  'r',  't',  'y',  'u',  'i',
 231         'o',  'p',  '}',    0,   13,    0,  'a',  's',
 232         'd',  'f',  'g',  'h',  'j',  'k',  'l',  '|',
 233         '{',    0,    0, '\'',  'z',  'x',  'c',  'v',
 234         'b',  'n',  'm',  ',',  '.',  '-',    0,  '*',
 235           0,   32,    0,    0,    0,    0,    0,    0,
 236           0,    0,    0,    0,    0,    0,    0,    0,
 237           0,    0,  '-',    0,    0,    0,  '+',    0,
 238           0,    0,    0,    0,    0,    0,  '<',    0,
 239           0,    0,    0,    0,    0,    0,    0,    0,
 240           0 };
 241 
 242 static unsigned char shift_map[] = {
 243           0,   27,  '!', '\"',  '#',  '$',  '%',  '&',
 244         '/',  '(',  ')',  '=',  '?',  '`',  127,    9, 
 245         'Q',  'W',  'E',  'R',  'T',  'Y',  'U',  'I',
 246         'O',  'P',  ']',  '^',   13,    0,  'A',  'S',
 247         'D',  'F',  'G',  'H',  'J',  'K',  'L', '\\',
 248         '[',    0,    0,  '*',  'Z',  'X',  'C',  'V',
 249         'B',  'N',  'M',  ';',  ':',  '_',    0,  '*',
 250           0,   32,    0,    0,    0,    0,    0,    0,
 251           0,    0,    0,    0,    0,    0,    0,    0,
 252           0,    0,  '-',    0,    0,    0,  '+',    0,
 253           0,    0,    0,    0,    0,    0,  '>',    0,
 254           0,    0,    0,    0,    0,    0,    0,    0,
 255           0 };
 256 
 257 static unsigned char alt_map[] = {
 258           0,    0,    0,  '@',  163,  '$',    0,    0,
 259         '{',   '[',  ']', '}', '\\',    0,    0,    0,
 260           0,    0,    0,    0,    0,    0,    0,    0,
 261           0,    0,    0,  '~',   13,    0,    0,    0,
 262           0,    0,    0,    0,    0,    0,    0,    0,
 263           0,    0,    0,    0,    0,    0,    0,    0,
 264           0,    0,    0,    0,    0,    0,    0,    0,
 265           0,    0,    0,    0,    0,    0,    0,    0,
 266           0,    0,    0,    0,    0,    0,    0,    0,
 267           0,    0,    0,    0,    0,    0,    0,    0,
 268           0,    0,    0,    0,    0,    0,  '|',    0,
 269           0,    0,    0,    0,    0,    0,    0,    0,
 270           0 };
 271 
 272 #elif defined KBD_FINNISH_LATIN1
 273 
 274 static unsigned char key_map[] = {
 275           0,   27,  '1',  '2',  '3',  '4',  '5',  '6',
 276         '7',  '8',  '9',  '0',  '+',  180,  127,    9,
 277         'q',  'w',  'e',  'r',  't',  'y',  'u',  'i',
 278         'o',  'p',  229,  168,   13,    0,  'a',  's',
 279         'd',  'f',  'g',  'h',  'j',  'k',  'l',  246,
 280         228,  167,    0, '\'',  'z',  'x',  'c',  'v',
 281         'b',  'n',  'm',  ',',  '.',  '-',    0,  '*',
 282           0,   32,    0,    0,    0,    0,    0,    0,
 283           0,    0,    0,    0,    0,    0,    0,    0,
 284           0,    0,  '-',    0,    0,    0,  '+',    0,
 285           0,    0,    0,    0,    0,    0,  '<',    0,
 286           0,    0,    0,    0,    0,    0,    0,    0,
 287           0 };
 288   
 289 static unsigned char shift_map[] = {
 290           0,   27,  '!',  '"',  '#',  '$',  '%',  '&',
 291         '/',  '(',  ')',  '=',  '?',  '`',  127,    9,
 292         'Q',  'W',  'E',  'R',  'T',  'Y',  'U',  'I',
 293         'O',  'P',  197,  '^',   13,    0,  'A',  'S',
 294         'D',  'F',  'G',  'H',  'J',  'K',  'L',  214,
 295         196,  189,    0,  '*',  'Z',  'X',  'C',  'V',
 296         'B',  'N',  'M',  ';',  ':',  '_',    0,  '*',
 297           0,   32,    0,    0,    0,    0,    0,    0,
 298           0,    0,    0,    0,    0,    0,    0,    0,
 299           0,    0,  '-',    0,    0,    0,  '+',    0,
 300           0,    0,    0,    0,    0,    0,  '>',    0,
 301           0,    0,    0,    0,    0,    0,    0,    0,
 302           0 };
 303 
 304 static unsigned char alt_map[] = {
 305           0,    0,    0,  '@',  163,  '$',    0,    0,
 306         '{',  '[',  ']',  '}', '\\',    0,    0,    0,
 307           0,    0,    0,    0,    0,    0,    0,    0,
 308           0,    0,    0,  '~',   13,    0,    0,    0,
 309           0,    0,    0,    0,    0,    0,    0,    0,
 310           0,    0,    0,    0,    0,    0,    0,    0,
 311           0,    0,    0,    0,    0,    0,    0,    0,
 312           0,    0,    0,    0,    0,    0,    0,    0,
 313           0,    0,    0,    0,    0,    0,    0,    0,
 314           0,    0,    0,    0,    0,    0,    0,    0,
 315           0,    0,    0,    0,    0,    0,  '|',    0,
 316           0,    0,    0,    0,    0,    0,    0,    0,
 317           0 };
 318 
 319 #elif defined KBD_US
 320 
 321 static unsigned char key_map[] = {
 322           0,   27,  '1',  '2',  '3',  '4',  '5',  '6',
 323         '7',  '8',  '9',  '0',  '-',  '=',  127,    9,
 324         'q',  'w',  'e',  'r',  't',  'y',  'u',  'i',
 325         'o',  'p',  '[',  ']',   13,    0,  'a',  's',
 326         'd',  'f',  'g',  'h',  'j',  'k',  'l',  ';',
 327        '\'',  '`',    0, '\\',  'z',  'x',  'c',  'v',
 328         'b',  'n',  'm',  ',',  '.',  '/',    0,  '*',
 329           0,   32,    0,    0,    0,    0,    0,    0,
 330           0,    0,    0,    0,    0,    0,    0,    0,
 331           0,    0,  '-',    0,    0,    0,  '+',    0, 
 332           0,    0,    0,    0,    0,    0,  '<',    0,
 333           0,    0,    0,    0,    0,    0,    0,    0,
 334           0 };
 335 
 336 static unsigned char shift_map[] = {
 337           0,   27,  '!',  '@',  '#',  '$',  '%',  '^',
 338         '&',  '*',  '(',  ')',  '_',  '+',  127,    9,
 339         'Q',  'W',  'E',  'R',  'T',  'Y',  'U',  'I',
 340         'O',  'P',  '{',  '}',   13,    0,  'A',  'S',
 341         'D',  'F',  'G',  'H',  'J',  'K',  'L',  ':',
 342         '"',  '~',  '0',  '|',  'Z',  'X',  'C',  'V',
 343         'B',  'N',  'M',  '<',  '>',  '?',    0,  '*',
 344           0,   32,    0,    0,    0,    0,    0,    0,
 345           0,    0,    0,    0,    0,    0,    0,    0,
 346           0,    0,  '-',    0,    0,    0,  '+',    0, 
 347           0,    0,    0,    0,    0,    0,  '>',    0,
 348           0,    0,    0,    0,    0,    0,    0,    0,
 349           0 };
 350 
 351 static unsigned char alt_map[] = {
 352           0,    0,    0,  '@',    0,  '$',    0,    0,
 353         '{',   '[',  ']', '}', '\\',    0,    0,    0,
 354           0,    0,    0,    0,    0,    0,    0,    0,
 355           0,    0,    0,  '~',   13,    0,    0,    0,
 356           0,    0,    0,    0,    0,    0,    0,    0,
 357           0,    0,    0,    0,    0,    0,    0,    0,
 358           0,    0,    0,    0,    0,    0,    0,    0,
 359           0,    0,    0,    0,    0,    0,    0,    0,
 360           0,    0,    0,    0,    0,    0,    0,    0,
 361           0,    0,    0,    0,    0,    0,    0,    0,
 362           0,    0,    0,    0,    0,    0,  '|',    0,
 363           0,    0,    0,    0,    0,    0,    0,    0,
 364           0 };
 365 
 366 #elif defined KBD_UK
 367 
 368 static unsigned char key_map[] = {
 369           0,   27,  '1',  '2',  '3',  '4',  '5',  '6',
 370         '7',  '8',  '9',  '0',  '-',  '=',  127,    9,
 371         'q',  'w',  'e',  'r',  't',  'y',  'u',  'i',
 372         'o',  'p',  '[',  ']',   13,    0,  'a',  's',
 373         'd',  'f',  'g',  'h',  'j',  'k',  'l',  ';',
 374        '\'',  '`',    0,  '#',  'z',  'x',  'c',  'v',
 375         'b',  'n',  'm',  ',',  '.',  '/',    0,  '*',
 376           0,   32,    0,    0,    0,    0,    0,    0,
 377           0,    0,    0,    0,    0,    0,    0,    0,
 378           0,    0,  '-',    0,    0,    0,  '+',    0, 
 379           0,    0,    0,    0,    0,    0, '\\',    0,
 380           0,    0,    0,    0,    0,    0,    0,    0,
 381           0 };
 382 
 383 static unsigned char shift_map[] = {
 384           0,   27,  '!',  '"',  163,  '$',  '%',  '^',
 385         '&',  '*',  '(',  ')',  '_',  '+',  127,    9,
 386         'Q',  'W',  'E',  'R',  'T',  'Y',  'U',  'I',
 387         'O',  'P',  '{',  '}',   13,    0,  'A',  'S',
 388         'D',  'F',  'G',  'H',  'J',  'K',  'L',  ':',
 389         '@',  '~',  '0',  '~',  'Z',  'X',  'C',  'V',
 390         'B',  'N',  'M',  '<',  '>',  '?',    0,  '*',
 391           0,   32,    0,    0,    0,    0,    0,    0,
 392           0,    0,    0,    0,    0,    0,    0,    0,
 393           0,    0,  '-',    0,    0,    0,  '+',    0, 
 394           0,    0,    0,    0,    0,    0,  '|',    0,
 395           0,    0,    0,    0,    0,    0,    0,    0,
 396           0 };
 397 
 398 static unsigned char alt_map[] = {
 399           0,    0,    0,  '@',    0,  '$',    0,    0,
 400         '{',   '[',  ']', '}', '\\',    0,    0,    0,
 401           0,    0,    0,    0,    0,    0,    0,    0,
 402           0,    0,    0,  '~',   13,    0,    0,    0,
 403           0,    0,    0,    0,    0,    0,    0,    0,
 404           0,    0,    0,    0,    0,    0,    0,    0,
 405           0,    0,    0,    0,    0,    0,    0,    0,
 406           0,    0,    0,    0,    0,    0,    0,    0,
 407           0,    0,    0,    0,    0,    0,    0,    0,
 408           0,    0,    0,    0,    0,    0,    0,    0,
 409           0,    0,    0,    0,    0,    0,  '|',    0,
 410           0,    0,    0,    0,    0,    0,    0,    0,
 411           0 };
 412 
 413 #elif defined KBD_GR
 414 
 415 static unsigned char key_map[] = {
 416           0,   27,  '1',  '2',  '3',  '4',  '5',  '6',
 417         '7',  '8',  '9',  '0', '\\', '\'',  127,    9,
 418         'q',  'w',  'e',  'r',  't',  'z',  'u',  'i',
 419         'o',  'p',  '@',  '+',   13,    0,  'a',  's',
 420         'd',  'f',  'g',  'h',  'j',  'k',  'l',  '[',
 421         ']',  '^',    0,  '#',  'y',  'x',  'c',  'v',
 422         'b',  'n',  'm',  ',',  '.',  '-',    0,  '*',
 423           0,   32,    0,    0,    0,    0,    0,    0,
 424           0,    0,    0,    0,    0,    0,    0,    0,
 425           0,    0,  '-',    0,    0,    0,  '+',    0,
 426           0,    0,    0,    0,    0,    0,  '<',    0,
 427           0,    0,    0,    0,    0,    0,    0,    0,
 428           0 };
 429 
 430 static unsigned char shift_map[] = {
 431           0,   27,  '!',  '"',  '#',  '$',  '%',  '&',
 432         '/',  '(',  ')',  '=',  '?',  '`',  127,    9, 
 433         'Q',  'W',  'E',  'R',  'T',  'Z',  'U',  'I',
 434         'O',  'P', '\\',  '*',   13,    0,  'A',  'S',
 435         'D',  'F',  'G',  'H',  'J',  'K',  'L',  '{',
 436         '}',  '~',    0, '\'',  'Y',  'X',  'C',  'V',
 437         'B',  'N',  'M',  ';',  ':',  '_',    0,  '*',
 438           0,   32,    0,    0,    0,    0,    0,    0,
 439           0,    0,    0,    0,    0,    0,    0,    0,
 440           0,    0,  '-',    0,    0,    0,  '+',    0,
 441           0,    0,    0,    0,    0,    0,  '>',    0,
 442           0,    0,    0,    0,    0,    0,    0,    0,
 443           0 };
 444 
 445 static unsigned char alt_map[] = {
 446           0,    0,    0,  '@',    0,  '$',    0,    0,
 447         '{',   '[',  ']', '}', '\\',    0,    0,    0,
 448         '@',    0,    0,    0,    0,    0,    0,    0,
 449           0,    0,    0,  '~',   13,    0,    0,    0,
 450           0,    0,    0,    0,    0,    0,    0,    0,
 451           0,    0,    0,    0,    0,    0,    0,    0,
 452           0,    0,    0,    0,    0,    0,    0,    0,
 453           0,    0,    0,    0,    0,    0,    0,    0,
 454           0,    0,    0,    0,    0,    0,    0,    0,
 455           0,    0,    0,    0,    0,    0,    0,    0,
 456           0,    0,    0,    0,    0,    0,  '|',    0,
 457           0,    0,    0,    0,    0,    0,    0,    0,
 458           0 };
 459 
 460 #elif defined KBD_GR_LATIN1
 461 
 462 static unsigned char key_map[] = {
 463           0,   27,  '1',  '2',  '3',  '4',  '5',  '6',
 464         '7',  '8',  '9',  '0', 223,  180,  127,    9,
 465         'q',  'w',  'e',  'r',  't',  'z',  'u',  'i',
 466         'o',  'p',  252,  '+',   13,    0,  'a',  's',
 467         'd',  'f',  'g',  'h',  'j',  'k',  'l', 246,
 468         228,   94,    0,  '#',  'y',  'x',  'c',  'v',
 469         'b',  'n',  'm',  ',',  '.',  '-',    0,  '*',
 470           0,   32,    0,    0,    0,    0,    0,    0,
 471           0,    0,    0,    0,    0,    0,    0,    0,
 472           0,    0,  '-',    0,    0,    0,  '+',    0,
 473           0,    0,    0,    0,    0,    0,  '<',    0,
 474           0,    0,    0,    0,    0,    0,    0,    0,
 475           0 };
 476 
 477 static unsigned char shift_map[] = {
 478           0,   27,  '!',  '"',  167,  '$',  '%',  '&',
 479         '/',  '(',  ')',  '=',  '?',  '`',  127,    9, 
 480         'Q',  'W',  'E',  'R',  'T',  'Z',  'U',  'I',
 481         'O',  'P',  220,  '*',   13,    0,  'A',  'S',
 482         'D',  'F',  'G',  'H',  'J',  'K',  'L',  214,
 483         196,  176,    0, '\'',  'Y',  'X',  'C',  'V',
 484         'B',  'N',  'M',  ';',  ':',  '_',    0,  '*',
 485           0,   32,    0,    0,    0,    0,    0,    0,
 486           0,    0,    0,    0,    0,    0,    0,    0,
 487           0,    0,  '-',    0,    0,    0,  '+',    0,
 488           0,    0,    0,    0,    0,    0,  '>',    0,
 489           0,    0,    0,    0,    0,    0,    0,    0,
 490           0 };
 491 
 492 static unsigned char alt_map[] = {
 493           0,    0,    0,  178,  179,  '$',    0,    0,
 494         '{',   '[',  ']', '}', '\\',    0,    0,    0,
 495         '@',    0,    0,    0,    0,    0,    0,    0,
 496           0,    0,    0,  '~',   13,    0,    0,    0,
 497           0,    0,    0,    0,    0,    0,    0,    0,
 498           0,    0,    0,    0,    0,    0,    0,    0,
 499           0,    0,  181,    0,    0,    0,    0,    0,
 500           0,    0,    0,    0,    0,    0,    0,    0,
 501           0,    0,    0,    0,    0,    0,    0,    0,
 502           0,    0,    0,    0,    0,    0,    0,    0,
 503           0,    0,    0,    0,    0,    0,  '|',    0,
 504           0,    0,    0,    0,    0,    0,    0,    0,
 505           0 };
 506 
 507 #elif defined KBD_FR
 508 
 509 static unsigned char key_map[] = {
 510           0,   27,  '&',  '{',  '"', '\'',  '(',  '-',
 511         '}',  '_',  '/',  '@',  ')',  '=',  127,    9,
 512         'a',  'z',  'e',  'r',  't',  'y',  'u',  'i',
 513         'o',  'p',  '^',  '$',   13,    0,  'q',  's',
 514         'd',  'f',  'g',  'h',  'j',  'k',  'l',  'm',
 515         '|',  '`',    0,   42,  'w',  'x',  'c',  'v',
 516         'b',  'n',  ',',  ';',  ':',  '!',    0,  '*',
 517           0,   32,    0,    0,    0,    0,    0,    0,
 518           0,    0,    0,    0,    0,    0,    0,    0,
 519           0,    0,  '-',    0,    0,    0,  '+',    0,
 520           0,    0,    0,    0,    0,    0,  '<',    0,
 521           0,    0,    0,    0,    0,    0,    0,    0,
 522           0 };
 523 
 524 static unsigned char shift_map[] = {
 525           0,   27,  '1',  '2',  '3',  '4',  '5',  '6',
 526         '7',  '8',  '9',  '0',  ']',  '+',  127,    9, 
 527         'A',  'Z',  'E',  'R',  'T',  'Y',  'U',  'I',
 528         'O',  'P',  '<',  '>',   13,    0,  'Q',  'S',
 529         'D',  'F',  'G',  'H',  'J',  'K',  'L',  'M',
 530         '%',  '~',    0,  '#',  'W',  'X',  'C',  'V',
 531         'B',  'N',  '?',  '.',  '/', '\\',    0,  '*',
 532           0,   32,    0,    0,    0,    0,    0,    0,
 533           0,    0,    0,    0,    0,    0,    0,    0,
 534           0,    0,  '-',    0,    0,    0,  '+',    0,
 535           0,    0,    0,    0,    0,    0,  '>',    0,
 536           0,    0,    0,    0,    0,    0,    0,    0,
 537           0 };
 538 
 539 static unsigned char alt_map[] = {
 540           0,    0,    0,  '~',  '#',  '{',  '[',  '|',
 541         '`', '\\',   '^',  '@', ']',  '}',    0,    0,
 542         '@',    0,    0,    0,    0,    0,    0,    0,
 543           0,    0,    0,  '~',   13,    0,    0,    0,
 544           0,    0,    0,    0,    0,    0,    0,    0,
 545           0,    0,    0,    0,    0,    0,    0,    0,
 546           0,    0,    0,    0,    0,    0,    0,    0,
 547           0,    0,    0,    0,    0,    0,    0,    0,
 548           0,    0,    0,    0,    0,    0,    0,    0,
 549           0,    0,    0,    0,    0,    0,    0,    0,
 550           0,    0,    0,    0,    0,    0,  '|',    0,
 551           0,    0,    0,    0,    0,    0,    0,    0,
 552           0 };
 553 
 554 #elif defined KBD_FR_LATIN1
 555 
 556 static unsigned char key_map[] = {
 557           0,   27,  '&',  233,  '"', '\'',  '(',  '-',
 558         232,  '_',  231,  224,  ')',  '=',  127,    9,
 559         'a',  'z',  'e',  'r',  't',  'y',  'u',  'i',
 560         'o',  'p',  '^',  '$',   13,    0,  'q',  's',
 561         'd',  'f',  'g',  'h',  'j',  'k',  'l',  'm',
 562         249,  178,    0,   42,  'w',  'x',  'c',  'v',
 563         'b',  'n',  ',',  ';',  ':',  '!',    0,  '*',
 564           0,   32,    0,    0,    0,    0,    0,    0,
 565           0,    0,    0,    0,    0,    0,    0,    0,
 566           0,    0,  '-',    0,    0,    0,  '+',    0,
 567           0,    0,    0,    0,    0,    0,  '<',    0,
 568           0,    0,    0,    0,    0,    0,    0,    0,
 569           0 };
 570 
 571 static unsigned char shift_map[] = {
 572           0,   27,  '1',  '2',  '3',  '4',  '5',  '6',
 573         '7',  '8',  '9',  '0',  176,  '+',  127,    9, 
 574         'A',  'Z',  'E',  'R',  'T',  'Y',  'U',  'I',
 575         'O',  'P',  168,  163,   13,    0,  'Q',  'S',
 576         'D',  'F',  'G',  'H',  'J',  'K',  'L',  'M',
 577         '%',    0,    0,  181,  'W',  'X',  'C',  'V',
 578         'B',  'N',  '?',  '.',  '/',  167,    0,  '*',
 579           0,   32,    0,    0,    0,    0,    0,    0,
 580           0,    0,    0,    0,    0,    0,    0,    0,
 581           0,    0,  '-',    0,    0,    0,  '+',    0,
 582           0,    0,    0,    0,    0,    0,  '>',    0,
 583           0,    0,    0,    0,    0,    0,    0,    0,
 584           0 };
 585 
 586 static unsigned char alt_map[] = {
 587           0,    0,    0,  '~',  '#',  '{',  '[',  '|',
 588         '`', '\\',   '^',  '@', ']',  '}',    0,    0,
 589         '@',    0,    0,    0,    0,    0,    0,    0,
 590           0,    0,    0,  164,   13,    0,    0,    0,
 591           0,    0,    0,    0,    0,    0,    0,    0,
 592           0,    0,    0,    0,    0,    0,    0,    0,
 593           0,    0,    0,    0,    0,    0,    0,    0,
 594           0,    0,    0,    0,    0,    0,    0,    0,
 595           0,    0,    0,    0,    0,    0,    0,    0,
 596           0,    0,    0,    0,    0,    0,    0,    0,
 597           0,    0,    0,    0,    0,    0,  '|',    0,
 598           0,    0,    0,    0,    0,    0,    0,    0,
 599           0 };
 600 
 601 #elif defined KBD_DK
 602 
 603 static unsigned char key_map[] = {
 604           0,   27,  '1',  '2',  '3',  '4',  '5',  '6',
 605         '7',  '8',  '9',  '0',  '+', '\'',  127,    9,
 606         'q',  'w',  'e',  'r',  't',  'y',  'u',  'i',
 607         'o',  'p',  229,    0,   13,    0,  'a',  's',
 608         'd',  'f',  'g',  'h',  'j',  'k',  'l',  230,
 609         162,    0,    0, '\'',  'z',  'x',  'c',  'v',
 610         'b',  'n',  'm',  ',',  '.',  '-',    0,  '*',
 611           0,   32,    0,    0,    0,    0,    0,    0,
 612           0,    0,    0,    0,    0,    0,    0,    0,
 613           0,    0,  '-',    0,    0,    0,  '+',    0,
 614           0,    0,    0,    0,    0,    0,  '<',    0,
 615           0,    0,    0,    0,    0,    0,    0,    0,
 616           0 };
 617 
 618 static unsigned char shift_map[] = {
 619           0,   27,  '!', '\"',  '#',  '$',  '%',  '&',
 620         '/',  '(',  ')',  '=',  '?',  '`',  127,    9, 
 621         'Q',  'W',  'E',  'R',  'T',  'Y',  'U',  'I',
 622         'O',  'P',  197,  '^',   13,    0,  'A',  'S',
 623         'D',  'F',  'G',  'H',  'J',  'K',  'L',  198,
 624         165,    0,    0,  '*',  'Z',  'X',  'C',  'V',
 625         'B',  'N',  'M',  ';',  ':',  '_',    0,  '*',
 626           0,   32,    0,    0,    0,    0,    0,    0,
 627           0,    0,    0,    0,    0,    0,    0,    0,
 628           0,    0,  '-',    0,    0,    0,  '+',    0,
 629           0,    0,    0,    0,    0,    0,  '>',    0,
 630           0,    0,    0,    0,    0,    0,    0,    0,
 631           0 };
 632 
 633 static unsigned char alt_map[] = {
 634           0,    0,    0,  '@',  163,  '$',    0,    0,
 635         '{',   '[',  ']', '}',    0,  '|',    0,    0,
 636           0,    0,    0,    0,    0,    0,    0,    0,
 637           0,    0,    0,  '~',   13,    0,    0,    0,
 638           0,    0,    0,    0,    0,    0,    0,    0,
 639           0,    0,    0,    0,    0,    0,    0,    0,
 640           0,    0,    0,    0,    0,    0,    0,    0,
 641           0,    0,    0,    0,    0,    0,    0,    0,
 642           0,    0,    0,    0,    0,    0,    0,    0,
 643           0,    0,    0,    0,    0,    0,    0,    0,
 644           0,    0,    0,    0,    0,    0,  '|',    0,
 645           0,    0,    0,    0,    0,    0,    0,    0,
 646           0 };
 647 
 648 #elif defined KBD_DK_LATIN1
 649 
 650 static unsigned char key_map[] = {
 651           0,   27,  '1',  '2',  '3',  '4',  '5',  '6',
 652         '7',  '8',  '9',  '0',  '+',  180,  127,    9,
 653         'q',  'w',  'e',  'r',  't',  'y',  'u',  'i',
 654         'o',  'p',  229,  168,   13,    0,  'a',  's',
 655         'd',  'f',  'g',  'h',  'j',  'k',  'l',  230,
 656         162,  189,    0, '\'',  'z',  'x',  'c',  'v',
 657         'b',  'n',  'm',  ',',  '.',  '-',    0,  '*',
 658           0,   32,    0,    0,    0,    0,    0,    0,
 659           0,    0,    0,    0,    0,    0,    0,    0,
 660           0,    0,  '-',    0,    0,    0,  '+',    0,
 661           0,    0,    0,    0,    0,    0,  '<',    0,
 662           0,    0,    0,    0,    0,    0,    0,    0,
 663           0 };
 664 
 665 static unsigned char shift_map[] = {
 666           0,   27,  '!', '\"',  '#',  '$',  '%',  '&',
 667         '/',  '(',  ')',  '=',  '?',  '`',  127,    9, 
 668         'Q',  'W',  'E',  'R',  'T',  'Y',  'U',  'I',
 669         'O',  'P',  197,  '^',   13,    0,  'A',  'S',
 670         'D',  'F',  'G',  'H',  'J',  'K',  'L',  198,
 671         165,  167,    0,  '*',  'Z',  'X',  'C',  'V',
 672         'B',  'N',  'M',  ';',  ':',  '_',    0,  '*',
 673           0,   32,    0,    0,    0,    0,    0,    0,
 674           0,    0,    0,    0,    0,    0,    0,    0,
 675           0,    0,  '-',    0,    0,    0,  '+',    0,
 676           0,    0,    0,    0,    0,    0,  '>',    0,
 677           0,    0,    0,    0,    0,    0,    0,    0,
 678           0 };
 679 
 680 static unsigned char alt_map[] = {
 681           0,    0,    0,  '@',  163,  '$',    0,    0,
 682         '{',   '[',  ']', '}',    0,  '|',    0,    0,
 683           0,    0,    0,    0,    0,    0,    0,    0,
 684           0,    0,    0,  '~',   13,    0,    0,    0,
 685           0,    0,    0,    0,    0,    0,    0,    0,
 686           0,    0,    0,    0,    0,    0,    0,    0,
 687           0,    0,    0,    0,    0,    0,    0,    0,
 688           0,    0,    0,    0,    0,    0,    0,    0,
 689           0,    0,    0,    0,    0,    0,    0,    0,
 690           0,    0,    0,    0,    0,    0,    0,    0,
 691           0,    0,    0,    0,    0,    0, '\\',    0,
 692           0,    0,    0,    0,    0,    0,    0,    0,
 693           0 };
 694 
 695 #elif defined KBD_DVORAK
 696 
 697 static unsigned char key_map[] = {
 698           0,   27,  '1',  '2',  '3',  '4',  '5',  '6',
 699         '7',  '8',  '9',  '0', '\\',  '=',  127,    9,
 700        '\'',  ',',  '.',  'p',  'y',  'f',  'g',  'c',
 701         'r',  'l',  '/',  ']',   13,    0,  'a',  'o',
 702         'e',  'u',  'i',  'd',  'h',  't',  'n',  's',
 703         '-',  '`',    0,  '[',  ';',  'q',  'j',  'k',
 704         'x',  'b',  'm',  'w',  'v',  'z',    0,  '*',
 705           0,   32,    0,    0,    0,    0,    0,    0,
 706           0,    0,    0,    0,    0,    0,    0,    0,
 707           0,    0,  '-',    0,    0,    0,  '+',    0,
 708           0,    0,    0,    0,    0,    0,  '<',    0,
 709           0,    0,    0,    0,    0,    0,    0,    0,
 710           0 };
 711 
 712 static unsigned char shift_map[] = {
 713           0,   27,  '!',  '@',  '#',  '$',  '%',  '^',
 714         '&',  '*',  '(',  ')',  '|',  '+',  127,    9,
 715         '"',  '<',  '>',  'P',  'Y',  'F',  'G',  'C',
 716         'R',  'L',  '?',  '}',   13,    0,  'A',  'O',
 717         'E',  'U',  'I',  'D',  'H',  'T',  'N',  'S',
 718         '_',  '~',    0,  '{',  ':',  'Q',  'J',  'K',
 719         'X',  'B',  'M',  'W',  'V',  'Z',    0,  '*',
 720           0,   32,    0,    0,    0,    0,    0,    0,
 721           0,    0,    0,    0,    0,    0,    0,    0,
 722           0,    0,  '-',    0,    0,    0,  '+',    0,
 723           0,    0,    0,    0,    0,    0,  '<',    0,
 724           0,    0,    0,    0,    0,    0,    0,    0,
 725           0 };
 726 
 727 static unsigned char alt_map[] = {
 728           0,    0,    0,  '@',    0,  '$',    0,    0,
 729         '{',   '[',  ']', '}', '\\',    0,    0,    0,
 730           0,    0,    0,    0,    0,    0,    0,    0,
 731           0,    0,    0,  '~',   13,    0,    0,    0,
 732           0,    0,    0,    0,    0,    0,    0,    0,
 733           0,    0,    0,    0,    0,    0,    0,    0,
 734           0,    0,    0,    0,    0,    0,    0,    0,
 735           0,    0,    0,    0,    0,    0,    0,    0,
 736           0,    0,    0,    0,    0,    0,    0,    0,
 737           0,    0,    0,    0,    0,    0,    0,    0,
 738           0,    0,    0,    0,    0,    0,  '|',    0,
 739           0,    0,    0,    0,    0,    0,    0,    0,
 740           0 };
 741 
 742 #else
 743 #error "KBD-type not defined"
 744 #endif
 745 
 746 static void do_self(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
 747 {
 748         unsigned char ch;
 749 
 750         if (kmode&ALTGR)
 751                 ch=alt_map[sc];
 752         else if (kmode&(LSHIFT|RSHIFT|LCTRL|RCTRL))
 753                 ch=shift_map[sc];
 754         else
 755                 ch=key_map[sc];
 756 
 757         if (ch == 0)
 758                 return;
 759 
 760         if ((ch=handle_diacr(ch)) == 0)
 761                 return;
 762 
 763         if (kmode&(LCTRL|RCTRL|CAPS))           /* ctrl or caps */
 764                 if ((ch>='a' && ch <='z') || (ch>=224 && ch<=254))
 765                         ch -= 32;
 766         if (kmode&(LCTRL|RCTRL))                /* ctrl */
 767                 ch &= 0x1f;
 768 
 769         if (kmode&ALT)
 770                 if (kbd_flags&NO_META_BIT) {
 771                         put_queue('\033');
 772                         put_queue(ch);
 773                 } else
 774                         put_queue(ch|0x80);
 775         else
 776                 put_queue(ch);
 777 }
 778 
 779 unsigned char accent_table[5][64] = {
 780         " \300BCD\310FGH\314JKLMN\322PQRST\331VWXYZ[\\]^_"
 781         "`\340bcd\350fgh\354jklmn\362pqrst\371vwxyz{|}~",   /* accent grave */
 782 
 783         " \301BCD\311FGH\315JKLMN\323PQRST\332VWX\335Z[\\]^_"
 784         "`\341bcd\351fgh\355jklmn\363pqrst\372vwxyz{|}~",   /* accent acute */
 785 
 786         " \302BCD\312FGH\316JKLMN\324PQRST\333VWXYZ[\\]^_"
 787         "`\342bcd\352fgh\356jklmn\364pqrst\373vwxyz{|}~",   /* circumflex */
 788 
 789         " \303BCDEFGHIJKLMN\325PQRSTUVWXYZ[\\]^_"
 790         "`\343bcdefghijklm\361\365pqrstuvwxyz{|}~",         /* tilde */
 791 
 792         " \304BCD\313FGH\316JKLMN\326PQRST\334VWXYZ[\\]^_"
 793         "`\344bcd\353fgh\357jklmn\366pqrst\374vwx\377z{|}~" /* dieresis */
 794 };
 795 
 796 
 797 /*
 798  * Check if dead key pressed. If so, check if same key pressed twice;
 799  * in that case return the char, otherwise store char and return 0.
 800  * If dead key not pressed, check if accented character pending. If
 801  * not: return the char, otherwise check if char is a space. If it is
 802  * a space return the diacritical. Else combine char with diacritical
 803  * mark and return.
 804  */
 805 
 806 unsigned int handle_diacr(unsigned int ch)
     /* [previous][next][first][last][top][bottom][index][help] */
 807 {
 808         static unsigned char diacr_table[] =
 809                 {'`', 180, '^', '~', 168, 0};           /* Must end with 0 */
 810         int i;
 811 
 812         for(i=0; diacr_table[i]; i++)
 813                 if (ch==diacr_table[i] && ((1<<i)&kbd_flags)) {
 814                         if (diacr == i) {
 815                                 diacr=-1;
 816                                 return ch;              /* pressed twice */
 817                         } else {
 818                                 diacr=i;                /* key is dead */
 819                                 return 0;
 820                         }
 821                 }
 822         if (diacr == -1)
 823                 return ch;
 824         else if (ch == ' ') {
 825                 ch=diacr_table[diacr];
 826                 diacr=-1;
 827                 return ch;
 828         } else if (ch<64 || ch>122) {
 829                 diacr=-1;
 830                 return ch;
 831         } else {
 832                 ch=accent_table[diacr][ch-64];
 833                 diacr=-1;
 834                 return ch;
 835         }
 836 }
 837                 
 838 
 839 #if defined KBD_FR
 840 static unsigned char num_table[] = "789-456+1230.";
 841 #else
 842 static unsigned char num_table[] = "789-456+1230,";
 843 #endif
 844 
 845 static unsigned char cur_table[] = "HA5-DGC+YB623";
 846 static unsigned int pad_table[] = { 7,8,9,0,4,5,6,0,1,2,3,0,0 };
 847 
 848 /*      
 849     Keypad /                    35      B7      Q
 850     Keypad *  (PrtSc)           37      B7      R
 851     Keypad NumLock              45      ??      P
 852     Keypad 7  (Home)            47      C7      w
 853     Keypad 8  (Up arrow)        48      C8      x
 854     Keypad 9  (PgUp)            49      C9      y
 855     Keypad -                    4A      CA      S
 856     Keypad 4  (Left arrow)      4B      CB      t
 857     Keypad 5                    4C      CC      u
 858     Keypad 6  (Right arrow)     4D      CD      v
 859     Keypad +                    4E      CE      l
 860     Keypad 1  (End)             4F      CF      q
 861     Keypad 2  (Down arrow)      50      D0      r
 862     Keypad 3  (PgDn)            51      D1      s
 863     Keypad 0  (Ins)             52      D2      p
 864     Keypad .  (Del)             53      D3      n
 865 */    
 866 
 867 static unsigned char appl_table[] = "wxyStuvlqrspn";
 868 
 869 static char *func_table[] = {
 870         "\033[[A", "\033[[B", "\033[[C", "\033[[D",
 871         "\033[[E", "\033[[F", "\033[[G", "\033[[H",
 872         "\033[[I", "\033[[J", "\033[[K", "\033[[L" 
 873 };
 874 
 875 
 876 static void cursor(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
 877 {
 878         if (sc < 0x47 || sc > 0x53)
 879                 return;
 880         sc-=0x47;
 881         if (sc == 12 && (kmode&(LCTRL|RCTRL)) && (kmode&(ALT|ALTGR))) {
 882                 ctrl_alt_del();
 883                 return;
 884         }
 885         if (ke0 == 1) {
 886                 cur(sc);
 887                 return;
 888         }
 889 
 890         if ((kmode&ALT) && sc!=12) {                  /* Alt-numpad */
 891                 npadch=npadch*10+pad_table[sc];
 892                 return;
 893         }
 894 
 895         if (kapplic && !(kmode&(LSHIFT|RSHIFT))) {    /* shift forces cursor */
 896                 applkey(appl_table[sc]);
 897                 return;
 898         }
 899 
 900         if (kleds&NUMLED) {
 901                 put_queue(num_table[sc]);
 902         } else
 903                 cur(sc);
 904 }
 905 
 906 static void cur(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
 907 {
 908         char buf[] = { 0x1b, '[', 0, 0, 0 };          /* must not be static */
 909 
 910         buf[2]=cur_table[sc];
 911         if (buf[2] < '9')
 912                 buf[3]='~';
 913         if (kapplic)
 914                 buf[1]='O';
 915         puts_queue(buf);
 916 }
 917 
 918 static void func(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
 919 {
 920         if (sc < 0x3b)
 921                 return;
 922         sc-=0x3b;
 923         if (sc > 9) {
 924                 sc-=18;
 925                 if (sc < 10 || sc > 11)
 926                         return;
 927         }
 928         if (kmode&ALT)
 929                 change_console(sc);
 930         else
 931                 puts_queue(func_table[sc]);
 932 }       
 933         
 934 
 935 static void slash(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
 936 {
 937         if (ke0 != 1)
 938                 do_self(sc);
 939         else if (kapplic)
 940                 applkey('Q');
 941         else
 942                 put_queue('/');
 943 }
 944 
 945 static void star(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
 946 {
 947         if (kapplic)
 948                 applkey('R');
 949         else
 950                 do_self(sc);
 951 }
 952 
 953 static void enter(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
 954 {
 955         if (ke0 != 1)
 956                 do_self(sc);
 957         else if (kapplic)
 958                 applkey('M');
 959         else
 960                 do_self(sc);
 961 }
 962 
 963 static void minus(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
 964 {
 965         if (kapplic)
 966                 applkey('S');
 967         else
 968                 do_self(sc);
 969 }
 970 
 971 static void plus(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
 972 {
 973         if (kapplic)
 974                 applkey('l');
 975         else
 976                 do_self(sc);
 977 }
 978 
 979 
 980 static void none(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
 981 {
 982 }
 983 
 984 
 985 /*
 986  * kb_wait waits for the keyboard controller buffer to empty.
 987  */
 988 
 989 static void kb_wait(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 990 {
 991         int i;
 992 
 993         for (i=0; i<0x10000; i++)
 994                 if ((inb(0x64)&0x02) == 0)
 995                         break;
 996 }
 997 
 998 /*
 999  * kb_ack waits for 0xfa to appear in port 0x60
1000  *
1001  * Suggested by Bruce Evans
1002  * Added by Niels Skou Olsen [NSO]
1003  * April 21, 1992
1004  *
1005  * Heavily inspired by kb_wait :-)
1006  * I don't know how much waiting actually is required,
1007  * but this seems to work
1008  */
1009 
1010 void kb_ack(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1011 {
1012         int i;
1013 
1014         for(i=0; i<0x10000; i++)
1015                 if (inb(0x64) == 0xfa)
1016                         break;
1017 }
1018 
1019 long no_idt[2] = {0, 0};
1020 
1021 /*
1022  * This routine reboots the machine by asking the keyboard
1023  * controller to pulse the reset-line low. We try that for a while,
1024  * and if it doesn't work, we do some other stupid things.
1025  */
1026 void hard_reset_now(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1027 {
1028         int i;
1029 
1030         sti();
1031         for (;;) {
1032                 for (i=0; i<100; i++) {
1033                         kb_wait();
1034                         *((unsigned short *)0x472)=0x1234;
1035                         outb(0xfe,0x64);         /* pulse reset low */
1036                 }
1037                 __asm__("\tlidt _no_idt"::);
1038         }
1039 }
1040         
1041 
1042 static fptr key_table[] = {
1043         none,do_self,do_self,do_self,           /* 00-03 s0 esc 1 2 */
1044         do_self,do_self,do_self,do_self,        /* 04-07 3 4 5 6 */
1045         do_self,do_self,do_self,do_self,        /* 08-0B 7 8 9 0 */
1046         do_self,do_self,do_self,do_self,        /* 0C-0F + ' bs tab */
1047         do_self,do_self,do_self,do_self,        /* 10-13 q w e r */
1048         do_self,do_self,do_self,do_self,        /* 14-17 t y u i */
1049         do_self,do_self,do_self,do_self,        /* 18-1B o p } ^ */
1050         enter,ctrl,do_self,do_self,             /* 1C-1F enter ctrl a s */
1051         do_self,do_self,do_self,do_self,        /* 20-23 d f g h */
1052         do_self,do_self,do_self,do_self,        /* 24-27 j k l | */
1053         do_self,do_self,lshift,do_self,         /* 28-2B { para lshift , */
1054         do_self,do_self,do_self,do_self,        /* 2C-2F z x c v */
1055         do_self,do_self,do_self,do_self,        /* 30-33 b n m , */
1056         do_self,slash,rshift,star,              /* 34-37 . - rshift * */
1057         alt,do_self,caps,func,                  /* 38-3B alt sp caps f1 */
1058         func,func,func,func,                    /* 3C-3F f2 f3 f4 f5 */
1059         func,func,func,func,                    /* 40-43 f6 f7 f8 f9 */
1060         func,num,scroll,cursor,                 /* 44-47 f10 num scr home */
1061         cursor,cursor,minus,cursor,             /* 48-4B up pgup - left */
1062         cursor,cursor,plus,cursor,              /* 4C-4F n5 right + end */
1063         cursor,cursor,cursor,cursor,            /* 50-53 dn pgdn ins del */
1064         none,none,do_self,func,                 /* 54-57 sysreq ? < f11 */
1065         func,none,none,none,                    /* 58-5B f12 ? ? ? */
1066         none,none,none,none,                    /* 5C-5F ? ? ? ? */
1067         none,none,none,none,                    /* 60-63 ? ? ? ? */
1068         none,none,none,none,                    /* 64-67 ? ? ? ? */
1069         none,none,none,none,                    /* 68-6B ? ? ? ? */
1070         none,none,none,none,                    /* 6C-6F ? ? ? ? */
1071         none,none,none,none,                    /* 70-73 ? ? ? ? */
1072         none,none,none,none,                    /* 74-77 ? ? ? ? */
1073         none,none,none,none,                    /* 78-7B ? ? ? ? */
1074         none,none,none,none,                    /* 7C-7F ? ? ? ? */
1075         none,none,none,none,                    /* 80-83 ? br br br */
1076         none,none,none,none,                    /* 84-87 br br br br */
1077         none,none,none,none,                    /* 88-8B br br br br */
1078         none,none,none,none,                    /* 8C-8F br br br br */
1079         none,none,none,none,                    /* 90-93 br br br br */
1080         none,none,none,none,                    /* 94-97 br br br br */
1081         none,none,none,none,                    /* 98-9B br br br br */
1082         none,unctrl,none,none,                  /* 9C-9F br unctrl br br */
1083         none,none,none,none,                    /* A0-A3 br br br br */
1084         none,none,none,none,                    /* A4-A7 br br br br */
1085         none,none,unlshift,none,                /* A8-AB br br unlshift br */
1086         none,none,none,none,                    /* AC-AF br br br br */
1087         none,none,none,none,                    /* B0-B3 br br br br */
1088         none,none,unrshift,none,                /* B4-B7 br br unrshift br */
1089         unalt,none,uncaps,none,                 /* B8-BB unalt br uncaps br */
1090         none,none,none,none,                    /* BC-BF br br br br */
1091         none,none,none,none,                    /* C0-C3 br br br br */
1092         none,none,none,none,                    /* C4-C7 br br br br */
1093         none,none,none,none,                    /* C8-CB br br br br */
1094         none,none,none,none,                    /* CC-CF br br br br */
1095         none,none,none,none,                    /* D0-D3 br br br br */
1096         none,none,none,none,                    /* D4-D7 br br br br */
1097         none,none,none,none,                    /* D8-DB br ? ? ? */
1098         none,none,none,none,                    /* DC-DF ? ? ? ? */
1099         none,none,none,none,                    /* E0-E3 e0 e1 ? ? */
1100         none,none,none,none,                    /* E4-E7 ? ? ? ? */
1101         none,none,none,none,                    /* E8-EB ? ? ? ? */
1102         none,none,none,none,                    /* EC-EF ? ? ? ? */
1103         none,none,none,none,                    /* F0-F3 ? ? ? ? */
1104         none,none,none,none,                    /* F4-F7 ? ? ? ? */
1105         none,none,none,none,                    /* F8-FB ? ? ? ? */
1106         none,none,none,none                     /* FC-FF ? ? ? ? */
1107 };

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