Subversion Repositories HelenOS-historic

Rev

Rev 671 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 671 Rev 878
Line 45... Line 45...
45
 * It takes care of low-level keyboard functions.
45
 * It takes care of low-level keyboard functions.
46
 */
46
 */
47
 
47
 
48
#define i8042_DATA      0x60
48
#define i8042_DATA      0x60
49
#define i8042_STATUS        0x64
49
#define i8042_STATUS        0x64
-
 
50
#define i8042_BUFFER_FULL_MASK      0x01
50
 
51
 
51
 
52
 
52
/** Keyboard commands. */
53
/** Keyboard commands. */
53
#define KBD_ENABLE  0xf4
54
#define KBD_ENABLE  0xf4
54
#define KBD_DISABLE 0xf5
55
#define KBD_DISABLE 0xf5
Line 77... Line 78...
77
#define SPECIAL     '?'
78
#define SPECIAL     '?'
78
#define KEY_RELEASE 0x80
79
#define KEY_RELEASE 0x80
79
 
80
 
80
static void key_released(__u8 sc);
81
static void key_released(__u8 sc);
81
static void key_pressed(__u8 sc);
82
static void key_pressed(__u8 sc);
-
 
83
static char key_read(chardev_t *d);
82
 
84
 
83
#define PRESSED_SHIFT       (1<<0)
85
#define PRESSED_SHIFT       (1<<0)
84
#define PRESSED_CAPSLOCK    (1<<1)
86
#define PRESSED_CAPSLOCK    (1<<1)
85
#define LOCKED_CAPSLOCK     (1<<0)
87
#define LOCKED_CAPSLOCK     (1<<0)
86
 
88
 
-
 
89
#define ACTIVE_READ_BUFF_SIZE 16 /*Must be power of 2*/
-
 
90
 
-
 
91
 
-
 
92
__u8 active_read_buff[ACTIVE_READ_BUFF_SIZE]={0};
-
 
93
 
87
SPINLOCK_INITIALIZE(keylock);       /**< keylock protects keyflags and lockflags. */
94
SPINLOCK_INITIALIZE(keylock);       /**< keylock protects keyflags and lockflags. */
88
static volatile int keyflags;       /**< Tracking of multiple keypresses. */
95
static volatile int keyflags;       /**< Tracking of multiple keypresses. */
89
static volatile int lockflags;      /**< Tracking of multiple keys lockings. */
96
static volatile int lockflags;      /**< Tracking of multiple keys lockings. */
90
 
97
 
91
static void i8042_suspend(chardev_t *);
98
static void i8042_suspend(chardev_t *);
92
static void i8042_resume(chardev_t *);
99
static void i8042_resume(chardev_t *);
93
 
100
 
94
static chardev_t kbrd;
101
static chardev_t kbrd;
95
static chardev_operations_t ops = {
102
static chardev_operations_t ops = {
96
    .suspend = i8042_suspend,
103
    .suspend = i8042_suspend,
97
    .resume = i8042_resume
104
    .resume = i8042_resume,
-
 
105
    .read = key_read
98
};
106
};
99
 
107
 
100
/** Primary meaning of scancodes. */
108
/** Primary meaning of scancodes. */
101
static char sc_primary_map[] = {
109
static char sc_primary_map[] = {
102
    SPECIAL, /* 0x00 */
110
    SPECIAL, /* 0x00 */
Line 394... Line 402...
394
 
402
 
395
/* Called from getc(). */
403
/* Called from getc(). */
396
void i8042_suspend(chardev_t *d)
404
void i8042_suspend(chardev_t *d)
397
{
405
{
398
}
406
}
-
 
407
 
-
 
408
 
-
 
409
static __u8 active_read_buff_read(void)
-
 
410
{
-
 
411
    static int i=0;
-
 
412
    i&=(ACTIVE_READ_BUFF_SIZE-1);
-
 
413
    if(!active_read_buff[i])
-
 
414
    {
-
 
415
        return 0;
-
 
416
    }
-
 
417
    return active_read_buff[i++];
-
 
418
}
-
 
419
 
-
 
420
static void active_read_buff_write(__u8 ch)
-
 
421
{
-
 
422
    static int i=0;
-
 
423
    active_read_buff[i]=ch;
-
 
424
    i++;
-
 
425
    i&=(ACTIVE_READ_BUFF_SIZE-1);
-
 
426
    active_read_buff[i]=0;
-
 
427
}
-
 
428
 
-
 
429
 
-
 
430
static void active_readed_key_pressed(__u8 sc)
-
 
431
{
-
 
432
    char *map = sc_primary_map;
-
 
433
    char ascii = sc_primary_map[sc];
-
 
434
    bool shift, capslock;
-
 
435
    bool letter = false;
-
 
436
 
-
 
437
    /*spinlock_lock(&keylock);*/
-
 
438
    switch (sc) {
-
 
439
    case SC_LSHIFT:
-
 
440
    case SC_RSHIFT:
-
 
441
            keyflags |= PRESSED_SHIFT;
-
 
442
        break;
-
 
443
    case SC_CAPSLOCK:
-
 
444
        keyflags |= PRESSED_CAPSLOCK;
-
 
445
        break;
-
 
446
    case SC_SPEC_ESCAPE:
-
 
447
        break;
-
 
448
    case SC_LEFTARR:
-
 
449
        active_read_buff_write(0x1b);
-
 
450
        active_read_buff_write(0x5b);
-
 
451
        active_read_buff_write(0x44);
-
 
452
        break;
-
 
453
    case SC_RIGHTARR:
-
 
454
        active_read_buff_write(0x1b);
-
 
455
        active_read_buff_write(0x5b);
-
 
456
        active_read_buff_write(0x43);
-
 
457
        break;
-
 
458
    case SC_UPARR:
-
 
459
        active_read_buff_write(0x1b);
-
 
460
        active_read_buff_write(0x5b);
-
 
461
        active_read_buff_write(0x41);
-
 
462
        break;
-
 
463
    case SC_DOWNARR:
-
 
464
        active_read_buff_write(0x1b);
-
 
465
        active_read_buff_write(0x5b);
-
 
466
        active_read_buff_write(0x42);
-
 
467
        break;
-
 
468
    case SC_HOME:
-
 
469
        active_read_buff_write(0x1b);
-
 
470
        active_read_buff_write(0x4f);
-
 
471
        active_read_buff_write(0x48);
-
 
472
        break;
-
 
473
    case SC_END:
-
 
474
        active_read_buff_write(0x1b);
-
 
475
        active_read_buff_write(0x4f);
-
 
476
        active_read_buff_write(0x46);
-
 
477
        break;
-
 
478
    case SC_DELETE:
-
 
479
        active_read_buff_write(0x1b);
-
 
480
        active_read_buff_write(0x5b);
-
 
481
        active_read_buff_write(0x33);
-
 
482
        active_read_buff_write(0x7e);
-
 
483
        break;
-
 
484
    default:
-
 
485
            letter = is_lower(ascii);
-
 
486
        capslock = (keyflags & PRESSED_CAPSLOCK) || (lockflags & LOCKED_CAPSLOCK);
-
 
487
        shift = keyflags & PRESSED_SHIFT;
-
 
488
        if (letter && capslock)
-
 
489
            shift = !shift;
-
 
490
        if (shift)
-
 
491
            map = sc_secondary_map;
-
 
492
        active_read_buff_write(map[sc]);
-
 
493
        break;
-
 
494
    }
-
 
495
    /*spinlock_unlock(&keylock);*/
-
 
496
 
-
 
497
}
-
 
498
 
-
 
499
 
-
 
500
static char key_read(chardev_t *d)
-
 
501
{
-
 
502
    char ch;   
-
 
503
   
-
 
504
 
-
 
505
    while(!(ch=active_read_buff_read()))
-
 
506
    {
-
 
507
        __u8 x;
-
 
508
        while (!((x=inb(i8042_STATUS))&i8042_BUFFER_FULL_MASK));
-
 
509
        x = inb(i8042_DATA);
-
 
510
        if (x & KEY_RELEASE)
-
 
511
            key_released(x ^ KEY_RELEASE);
-
 
512
        else
-
 
513
            active_readed_key_pressed(x);
-
 
514
    }
-
 
515
    return ch;
-
 
516
}
-
 
517
 
-
 
518