270
/* Table to convert from PC scancodes to scan code set 2. */
271
static const unsigned char ps2_raw_keycode_set2[128] = {
272
0,118, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85,102, 13,
273
21, 29, 36, 45, 44, 53, 60, 67, 68, 77, 84, 91, 90, 20, 28, 27,
274
35, 43, 52, 51, 59, 66, 75, 76, 82, 14, 18, 93, 26, 34, 33, 42,
275
50, 49, 58, 65, 73, 74, 89,124, 17, 41, 88, 5, 6, 4, 12, 3,
276
11, 2, 10, 1, 9,119,126,108,117,125,123,107,115,116,121,105,
277
114,122,112,113,127, 96, 97,120, 7, 15, 23, 31, 39, 47, 55, 63,
278
71, 79, 86, 94, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 87,111,
279
19, 25, 57, 81, 83, 92, 95, 98, 99,100,101,103,104,106,109,110
282
/* Table to convert from PC scancodes to scan code set 3. */
283
static const unsigned char ps2_raw_keycode_set3[128] = {
284
0,118, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85,102, 13,
285
21, 29, 36, 45, 44, 53, 60, 67, 68, 77, 84, 91, 90, 17, 28, 27,
286
35, 43, 52, 51, 59, 66, 75, 76, 82, 14, 18, 92, 26, 34, 33, 42,
287
50, 49, 58, 65, 73, 74, 89,124, 25, 41, 20, 5, 6, 4, 12, 3,
288
11, 2, 10, 1, 9,118,126,108,117,125,123,107,115,116,121,105,
289
114,122,112,113,127, 96, 19,120, 7, 15, 23, 31, 39, 47, 55, 63,
290
71, 79, 86, 94, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 87,111,
291
19, 25, 57, 81, 83, 92, 95, 98, 99,100,101,103,104,106,109,110
294
237
#ifndef VBOX_DEVICE_STRUCT_TESTCASE
296
239
/* update irq and KBD_STAT_[MOUSE_]OBF */
297
240
static void kbd_update_irq(KBDState *s)
299
KBDQueue *q = &s->queue;
300
242
MouseCmdQueue *mcq = &s->mouse_command_queue;
301
243
MouseEventQueue *meq = &s->mouse_event_queue;
302
244
int irq12_level, irq1_level;
311
254
if (!(s->status & KBD_STAT_OBF)) {
312
255
s->status &= ~KBD_STAT_MOUSE_OBF;
313
256
/* Keyboard data has priority if both kbd and aux data is available. */
314
if (q->count && !(s->mode & KBD_MODE_DISABLE_KBD))
257
if (!(s->mode & KBD_MODE_DISABLE_KBD) && PS2KByteFromKbd(&s->Kbd, &val) == VINF_SUCCESS)
316
s->status |= KBD_STAT_OBF;
317
s->dbbout = q->data[q->rptr];
318
if (++q->rptr == KBD_QUEUE_SIZE)
259
bool fHaveData = true;
261
/* If scancode translation is on (it usually is), there's more work to do. */
266
s->xlat_state = XlateAT2PC(s->xlat_state, val, &xlated_val);
269
/* If the translation state is XS_BREAK, there's nothing to report
270
* and we keep going until the state changes or there's no more data.
272
while (s->xlat_state == XS_BREAK && PS2KByteFromKbd(&s->Kbd, &val) == VINF_SUCCESS)
274
s->xlat_state = XlateAT2PC(s->xlat_state, val, &xlated_val);
277
/* This can happen if the last byte in the queue is F0... */
278
if (s->xlat_state == XS_BREAK)
284
s->status |= KBD_STAT_OBF;
322
else if ((mcq->count || meq->count) /*&& !(s->mode & KBD_MODE_DISABLE_MOUSE)*/)
287
else if ((mcq->count || meq->count) && !(s->mode & KBD_MODE_DISABLE_MOUSE))
324
289
s->status |= KBD_STAT_OBF | KBD_STAT_MOUSE_OBF;
596
static void kbd_reset_keyboard(KBDState *s)
600
/* Flush the keyboard queue. */
606
static int kbd_write_keyboard(KBDState *s, int val)
608
switch(s->kbd_write_cmd) {
613
kbd_queue(s, KBD_REPLY_ACK, 0);
616
kbd_queue(s, KBD_REPLY_RESEND, 0);
619
kbd_queue(s, KBD_REPLY_ACK, 0);
620
kbd_queue(s, 0xab, 0);
621
kbd_queue(s, 0x83, 0);
624
kbd_queue(s, KBD_CMD_ECHO, 0);
628
kbd_queue(s, KBD_REPLY_ACK, 0);
630
case KBD_CMD_SCANCODE:
631
case KBD_CMD_SET_LEDS:
632
case KBD_CMD_SET_RATE:
633
s->kbd_write_cmd = val;
634
kbd_queue(s, KBD_REPLY_ACK, 0);
636
case KBD_CMD_RESET_DISABLE:
637
kbd_reset_keyboard(s);
639
kbd_queue(s, KBD_REPLY_ACK, 0);
641
case KBD_CMD_RESET_ENABLE:
642
kbd_reset_keyboard(s);
644
kbd_queue(s, KBD_REPLY_ACK, 0);
647
kbd_reset_keyboard(s);
648
kbd_queue(s, KBD_REPLY_ACK, 0);
649
kbd_queue(s, KBD_REPLY_POR, 0);
652
kbd_queue(s, KBD_REPLY_ACK, 0);
656
case KBD_CMD_SCANCODE:
659
if (s->scancode_set == 1)
660
pc_kbd_put_keycode(s, 0x43);
661
else if (s->scancode_set == 2)
662
pc_kbd_put_keycode(s, 0x41);
663
else if (s->scancode_set == 3)
664
pc_kbd_put_keycode(s, 0x3f);
666
if (val >= 1 && val <= 3) {
667
LogRel(("kbd: scan code set %d selected\n", val));
668
s->scancode_set = val;
670
kbd_queue(s, KBD_REPLY_ACK, 0);
673
return VINF_IOM_HC_IOPORT_WRITE;
675
case KBD_CMD_SET_LEDS:
678
PDMKEYBLEDS enmLeds = PDMKEYBLEDS_NONE;
680
enmLeds = (PDMKEYBLEDS)(enmLeds | PDMKEYBLEDS_SCROLLLOCK);
682
enmLeds = (PDMKEYBLEDS)(enmLeds | PDMKEYBLEDS_NUMLOCK);
684
enmLeds = (PDMKEYBLEDS)(enmLeds | PDMKEYBLEDS_CAPSLOCK);
685
s->Keyboard.pDrv->pfnLedStatusChange(s->Keyboard.pDrv, enmLeds);
687
return VINF_IOM_HC_IOPORT_WRITE;
689
kbd_queue(s, KBD_REPLY_ACK, 0);
690
s->kbd_write_cmd = -1;
693
case KBD_CMD_SET_RATE:
694
kbd_queue(s, KBD_REPLY_ACK, 0);
695
s->kbd_write_cmd = -1;
545
PS2K *GetPS2KFromDevIns(PPDMDEVINS pDevIns)
547
KBDState *pThis = PDMINS_2_DATA(pDevIns, KBDState *);
702
551
static void kbd_mouse_set_reported_buttons(KBDState *s, unsigned fButtons, unsigned fButtonMask)
1513
1354
KBDState *pThis = PDMINS_2_DATA(pDevIns, KBDState *);
1515
1356
kbd_reset(pThis);
1516
/* Activate the PS/2 keyboard by default. */
1517
if (pThis->Keyboard.pDrv)
1518
pThis->Keyboard.pDrv->pfnSetActive(pThis->Keyboard.pDrv, true);
1522
/* -=-=-=-=-=- Keyboard: IBase -=-=-=-=-=- */
1525
* @interface_method_impl{PDMIBASE,pfnQueryInterface}
1527
static DECLCALLBACK(void *) kbdKeyboardQueryInterface(PPDMIBASE pInterface, const char *pszIID)
1529
KBDState *pThis = RT_FROM_MEMBER(pInterface, KBDState, Keyboard.IBase);
1530
PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pThis->Keyboard.IBase);
1531
PDMIBASE_RETURN_INTERFACE(pszIID, PDMIKEYBOARDPORT, &pThis->Keyboard.IPort);
1536
/* -=-=-=-=-=- Keyboard: IKeyboardPort -=-=-=-=-=- */
1539
* Keyboard event handler.
1541
* @returns VBox status code.
1542
* @param pInterface Pointer to the keyboard port interface (KBDState::Keyboard.IPort).
1543
* @param u8KeyCode The keycode.
1545
static DECLCALLBACK(int) kbdKeyboardPutEvent(PPDMIKEYBOARDPORT pInterface, uint8_t u8KeyCode)
1547
KBDState *pThis = RT_FROM_MEMBER(pInterface, KBDState, Keyboard.IPort);
1548
int rc = PDMCritSectEnter(&pThis->CritSect, VERR_SEM_BUSY);
1549
AssertReleaseRC(rc);
1551
pc_kbd_put_keycode(pThis, u8KeyCode);
1553
PDMCritSectLeave(&pThis->CritSect);
1554
return VINF_SUCCESS;
1357
PS2KReset(&pThis->Kbd);