~vcs-imports/qemu/git

« back to all changes in this revision

Viewing changes to hw/ps2.c

  • Committer: pbrook
  • Date: 2006-10-22 00:18:54 UTC
  • Revision ID: git-v1:e6e5906b6e0a81718066ca43aef57515026c6624
ColdFire target.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2196 c046a42c-6fe2-441c-8c8c-71466251a162

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * QEMU PS/2 keyboard/mouse emulation
3
 
 *
 
3
 * 
4
4
 * Copyright (c) 2003 Fabrice Bellard
5
 
 *
 
5
 * 
6
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7
7
 * of this software and associated documentation files (the "Software"), to deal
8
8
 * in the Software without restriction, including without limitation the rights
21
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
22
 * THE SOFTWARE.
23
23
 */
24
 
#include "hw.h"
25
 
#include "ps2.h"
26
 
#include "console.h"
 
24
#include "vl.h"
27
25
 
28
26
/* debug PC keyboard */
29
27
//#define DEBUG_KBD
34
32
/* Keyboard Commands */
35
33
#define KBD_CMD_SET_LEDS        0xED    /* Set keyboard leds */
36
34
#define KBD_CMD_ECHO            0xEE
37
 
#define KBD_CMD_SCANCODE        0xF0    /* Get/set scancode set */
38
35
#define KBD_CMD_GET_ID          0xF2    /* get keyboard ID */
39
36
#define KBD_CMD_SET_RATE        0xF3    /* Set typematic rate */
40
37
#define KBD_CMD_ENABLE          0xF4    /* Enable scanning */
44
41
 
45
42
/* Keyboard Replies */
46
43
#define KBD_REPLY_POR           0xAA    /* Power on reset */
47
 
#define KBD_REPLY_ID            0xAB    /* Keyboard ID */
48
44
#define KBD_REPLY_ACK           0xFA    /* Command ACK */
49
45
#define KBD_REPLY_RESEND        0xFE    /* Command NACK, send the cmd again */
50
46
 
91
87
       conversions we do the translation (if any) in the PS/2 emulation
92
88
       not the keyboard controller.  */
93
89
    int translate;
94
 
    int scancode_set; /* 1=XT, 2=AT, 3=PS/2 */
95
90
} PS2KbdState;
96
91
 
97
92
typedef struct {
134
129
    s->update_irq(s->update_arg, 1);
135
130
}
136
131
 
137
 
/*
138
 
   keycode is expressed as follow:
139
 
   bit 7    - 0 key pressed, 1 = key released
140
 
   bits 6-0 - translated scancode set 2
141
 
 */
142
132
static void ps2_put_keycode(void *opaque, int keycode)
143
133
{
144
134
    PS2KbdState *s = opaque;
145
 
 
146
 
    /* XXX: add support for scancode sets 1 and 3 */
147
 
    if (!s->translate && keycode < 0xe0 && s->scancode_set == 2)
 
135
    if (!s->translate && keycode < 0xe0)
148
136
      {
149
137
        if (keycode & 0x80)
150
138
            ps2_queue(&s->common, 0xf0);
158
146
    PS2State *s = (PS2State *)opaque;
159
147
    PS2Queue *q;
160
148
    int val, index;
161
 
 
 
149
    
162
150
    q = &s->queue;
163
151
    if (q->count == 0) {
164
152
        /* NOTE: if no data left, we return the last keyboard one
184
172
static void ps2_reset_keyboard(PS2KbdState *s)
185
173
{
186
174
    s->scan_enabled = 1;
187
 
    s->scancode_set = 2;
188
175
}
189
176
 
190
177
void ps2_write_keyboard(void *opaque, int val)
203
190
            break;
204
191
        case KBD_CMD_GET_ID:
205
192
            ps2_queue(&s->common, KBD_REPLY_ACK);
206
 
            /* We emulate a MF2 AT keyboard here */
207
 
            ps2_queue(&s->common, KBD_REPLY_ID);
208
 
            if (s->translate)
209
 
                ps2_queue(&s->common, 0x41);
210
 
            else
211
 
                ps2_queue(&s->common, 0x83);
 
193
            ps2_queue(&s->common, 0xab);
 
194
            ps2_queue(&s->common, 0x83);
212
195
            break;
213
196
        case KBD_CMD_ECHO:
214
197
            ps2_queue(&s->common, KBD_CMD_ECHO);
217
200
            s->scan_enabled = 1;
218
201
            ps2_queue(&s->common, KBD_REPLY_ACK);
219
202
            break;
220
 
        case KBD_CMD_SCANCODE:
221
203
        case KBD_CMD_SET_LEDS:
222
204
        case KBD_CMD_SET_RATE:
223
205
            s->common.write_cmd = val;
243
225
            break;
244
226
        }
245
227
        break;
246
 
    case KBD_CMD_SCANCODE:
247
 
        if (val == 0) {
248
 
            if (s->scancode_set == 1)
249
 
                ps2_put_keycode(s, 0x43);
250
 
            else if (s->scancode_set == 2)
251
 
                ps2_put_keycode(s, 0x41);
252
 
            else if (s->scancode_set == 3)
253
 
                ps2_put_keycode(s, 0x3f);
254
 
        } else {
255
 
            if (val >= 1 && val <= 3)
256
 
                s->scancode_set = val;
257
 
            ps2_queue(&s->common, KBD_REPLY_ACK);
258
 
        }
259
 
        s->common.write_cmd = -1;
260
 
        break;
261
228
    case KBD_CMD_SET_LEDS:
262
229
        ps2_queue(&s->common, KBD_REPLY_ACK);
263
230
        s->common.write_cmd = -1;
327
294
    s->mouse_dz -= dz1;
328
295
}
329
296
 
330
 
static void ps2_mouse_event(void *opaque,
 
297
static void ps2_mouse_event(void *opaque, 
331
298
                            int dx, int dy, int dz, int buttons_state)
332
299
{
333
300
    PS2MouseState *s = opaque;
344
311
        s->mouse_buttons == buttons_state)
345
312
        return;
346
313
    s->mouse_buttons = buttons_state;
347
 
 
 
314
    
348
315
    if (!(s->mouse_status & MOUSE_STATUS_REMOTE) &&
349
316
        (s->common.queue.count < (PS2_QUEUE_SIZE - 16))) {
350
317
        for(;;) {
357
324
    }
358
325
}
359
326
 
360
 
void ps2_mouse_fake_event(void *opaque)
361
 
{
362
 
    ps2_mouse_event(opaque, 1, 0, 0, 0);
363
 
}
364
 
 
365
327
void ps2_write_mouse(void *opaque, int val)
366
328
{
367
329
    PS2MouseState *s = (PS2MouseState *)opaque;
467
429
                s->mouse_detect_state = 0;
468
430
            break;
469
431
        case 2:
470
 
            if (val == 80)
 
432
            if (val == 80) 
471
433
                s->mouse_type = 3; /* IMPS/2 */
472
434
            s->mouse_detect_state = 0;
473
435
            break;
474
436
        case 3:
475
 
            if (val == 80)
 
437
            if (val == 80) 
476
438
                s->mouse_type = 4; /* IMEX */
477
439
            s->mouse_detect_state = 0;
478
440
            break;
501
463
 
502
464
static void ps2_common_save (QEMUFile *f, PS2State *s)
503
465
{
504
 
    qemu_put_be32 (f, s->write_cmd);
505
 
    qemu_put_be32 (f, s->queue.rptr);
506
 
    qemu_put_be32 (f, s->queue.wptr);
507
 
    qemu_put_be32 (f, s->queue.count);
 
466
    qemu_put_be32s (f, &s->write_cmd);
 
467
    qemu_put_be32s (f, &s->queue.rptr);
 
468
    qemu_put_be32s (f, &s->queue.wptr);
 
469
    qemu_put_be32s (f, &s->queue.count);
508
470
    qemu_put_buffer (f, s->queue.data, sizeof (s->queue.data));
509
471
}
510
472
 
511
473
static void ps2_common_load (QEMUFile *f, PS2State *s)
512
474
{
513
 
    s->write_cmd=qemu_get_be32 (f);
514
 
    s->queue.rptr=qemu_get_be32 (f);
515
 
    s->queue.wptr=qemu_get_be32 (f);
516
 
    s->queue.count=qemu_get_be32 (f);
 
475
    qemu_get_be32s (f, &s->write_cmd);
 
476
    qemu_get_be32s (f, &s->queue.rptr);
 
477
    qemu_get_be32s (f, &s->queue.wptr);
 
478
    qemu_get_be32s (f, &s->queue.count);
517
479
    qemu_get_buffer (f, s->queue.data, sizeof (s->queue.data));
518
480
}
519
481
 
522
484
    PS2KbdState *s = (PS2KbdState*)opaque;
523
485
 
524
486
    ps2_common_save (f, &s->common);
525
 
    qemu_put_be32(f, s->scan_enabled);
526
 
    qemu_put_be32(f, s->translate);
527
 
    qemu_put_be32(f, s->scancode_set);
 
487
    qemu_put_be32s(f, &s->scan_enabled);
 
488
    qemu_put_be32s(f, &s->translate);
528
489
}
529
490
 
530
491
static void ps2_mouse_save(QEMUFile* f, void* opaque)
538
499
    qemu_put_8s(f, &s->mouse_wrap);
539
500
    qemu_put_8s(f, &s->mouse_type);
540
501
    qemu_put_8s(f, &s->mouse_detect_state);
541
 
    qemu_put_be32(f, s->mouse_dx);
542
 
    qemu_put_be32(f, s->mouse_dy);
543
 
    qemu_put_be32(f, s->mouse_dz);
 
502
    qemu_put_be32s(f, &s->mouse_dx);
 
503
    qemu_put_be32s(f, &s->mouse_dy);
 
504
    qemu_put_be32s(f, &s->mouse_dz);
544
505
    qemu_put_8s(f, &s->mouse_buttons);
545
506
}
546
507
 
548
509
{
549
510
    PS2KbdState *s = (PS2KbdState*)opaque;
550
511
 
551
 
    if (version_id != 2 && version_id != 3)
 
512
    if (version_id != 2)
552
513
        return -EINVAL;
553
514
 
554
515
    ps2_common_load (f, &s->common);
555
 
    s->scan_enabled=qemu_get_be32(f);
556
 
    s->translate=qemu_get_be32(f);
557
 
    if (version_id == 3)
558
 
        s->scancode_set=qemu_get_be32(f);
559
 
    else
560
 
        s->scancode_set=2;
 
516
    qemu_get_be32s(f, &s->scan_enabled);
 
517
    qemu_get_be32s(f, &s->translate);
561
518
    return 0;
562
519
}
563
520
 
575
532
    qemu_get_8s(f, &s->mouse_wrap);
576
533
    qemu_get_8s(f, &s->mouse_type);
577
534
    qemu_get_8s(f, &s->mouse_detect_state);
578
 
    s->mouse_dx=qemu_get_be32(f);
579
 
    s->mouse_dy=qemu_get_be32(f);
580
 
    s->mouse_dz=qemu_get_be32(f);
 
535
    qemu_get_be32s(f, &s->mouse_dx);
 
536
    qemu_get_be32s(f, &s->mouse_dy);
 
537
    qemu_get_be32s(f, &s->mouse_dz);
581
538
    qemu_get_8s(f, &s->mouse_buttons);
582
539
    return 0;
583
540
}
588
545
 
589
546
    s->common.update_irq = update_irq;
590
547
    s->common.update_arg = update_arg;
591
 
    s->scancode_set = 2;
592
548
    ps2_reset(&s->common);
593
 
    register_savevm("ps2kbd", 0, 3, ps2_kbd_save, ps2_kbd_load, s);
 
549
    register_savevm("ps2kbd", 0, 2, ps2_kbd_save, ps2_kbd_load, s);
594
550
    qemu_add_kbd_event_handler(ps2_put_keycode, s);
595
551
    qemu_register_reset(ps2_reset, &s->common);
596
552
    return s;
604
560
    s->common.update_arg = update_arg;
605
561
    ps2_reset(&s->common);
606
562
    register_savevm("ps2mouse", 0, 2, ps2_mouse_save, ps2_mouse_load, s);
607
 
    qemu_add_mouse_event_handler(ps2_mouse_event, s, 0, "QEMU PS/2 Mouse");
 
563
    qemu_add_mouse_event_handler(ps2_mouse_event, s, 0);
608
564
    qemu_register_reset(ps2_reset, &s->common);
609
565
    return s;
610
566
}