Commit f94f5d717c14d18e0a4af2b157ca5a231d7bcc38
1 parent
3aa22b4b
Add support for raw AT keyboard scancodes.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1749 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
35 additions
and
1 deletions
hw/pckbd.c
| ... | ... | @@ -295,6 +295,7 @@ void kbd_write_data(void *opaque, uint32_t addr, uint32_t val) |
| 295 | 295 | break; |
| 296 | 296 | case KBD_CCMD_WRITE_MODE: |
| 297 | 297 | s->mode = val; |
| 298 | + ps2_keyboard_set_translation(s->kbd, (s->mode & KBD_MODE_KCC) != 0); | |
| 298 | 299 | /* ??? */ |
| 299 | 300 | kbd_update_irq(s); |
| 300 | 301 | break; | ... | ... |
hw/ps2.c
| ... | ... | @@ -83,6 +83,10 @@ typedef struct { |
| 83 | 83 | typedef struct { |
| 84 | 84 | PS2State common; |
| 85 | 85 | int scan_enabled; |
| 86 | + /* Qemu uses translated PC scancodes internally. To avoid multiple | |
| 87 | + conversions we do the translation (if any) in the PS/2 emulation | |
| 88 | + not the keyboard controller. */ | |
| 89 | + int translate; | |
| 86 | 90 | } PS2KbdState; |
| 87 | 91 | |
| 88 | 92 | typedef struct { |
| ... | ... | @@ -99,6 +103,18 @@ typedef struct { |
| 99 | 103 | uint8_t mouse_buttons; |
| 100 | 104 | } PS2MouseState; |
| 101 | 105 | |
| 106 | +/* Table to convert from PC scancodes to raw scancodes. */ | |
| 107 | +static const unsigned char ps2_raw_keycode[128] = { | |
| 108 | + 0,118, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85,102, 13, | |
| 109 | + 21, 29, 36, 45, 44, 53, 60, 67, 68, 77, 84, 91, 90, 20, 28, 27, | |
| 110 | + 35, 43, 52, 51, 59, 66, 75, 76, 82, 14, 18, 93, 26, 34, 33, 42, | |
| 111 | + 50, 49, 58, 65, 73, 74, 89,124, 17, 41, 88, 5, 6, 4, 12, 3, | |
| 112 | + 11, 2, 10, 1, 9,119,126,108,117,125,123,107,115,116,121,105, | |
| 113 | + 114,122,112,113,127, 96, 97,120, 7, 15, 23, 31, 39, 47, 55, 63, | |
| 114 | + 71, 79, 86, 94, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 87,111, | |
| 115 | + 19, 25, 57, 81, 83, 92, 95, 98, 99,100,101,103,104,106,109,110 | |
| 116 | +}; | |
| 117 | + | |
| 102 | 118 | void ps2_queue(void *opaque, int b) |
| 103 | 119 | { |
| 104 | 120 | PS2State *s = (PS2State *)opaque; |
| ... | ... | @@ -115,7 +131,13 @@ void ps2_queue(void *opaque, int b) |
| 115 | 131 | |
| 116 | 132 | static void ps2_put_keycode(void *opaque, int keycode) |
| 117 | 133 | { |
| 118 | - PS2MouseState *s = opaque; | |
| 134 | + PS2KbdState *s = opaque; | |
| 135 | + if (!s->translate && keycode < 0xe0) | |
| 136 | + { | |
| 137 | + if (keycode & 0x80) | |
| 138 | + ps2_queue(&s->common, 0xf0); | |
| 139 | + keycode = ps2_raw_keycode[keycode & 0x7f]; | |
| 140 | + } | |
| 119 | 141 | ps2_queue(&s->common, keycode); |
| 120 | 142 | } |
| 121 | 143 | |
| ... | ... | @@ -214,6 +236,16 @@ void ps2_write_keyboard(void *opaque, int val) |
| 214 | 236 | } |
| 215 | 237 | } |
| 216 | 238 | |
| 239 | +/* Set the scancode translation mode. | |
| 240 | + 0 = raw scancodes. | |
| 241 | + 1 = translated scancodes (used by qemu internally). */ | |
| 242 | + | |
| 243 | +void ps2_keyboard_set_translation(void *opaque, int mode) | |
| 244 | +{ | |
| 245 | + PS2KbdState *s = (PS2KbdState *)opaque; | |
| 246 | + s->translate = mode; | |
| 247 | +} | |
| 248 | + | |
| 217 | 249 | static void ps2_mouse_send_packet(PS2MouseState *s) |
| 218 | 250 | { |
| 219 | 251 | unsigned int b; | ... | ... |
vl.h
| ... | ... | @@ -969,6 +969,7 @@ void ps2_write_mouse(void *, int val); |
| 969 | 969 | void ps2_write_keyboard(void *, int val); |
| 970 | 970 | uint32_t ps2_read_data(void *); |
| 971 | 971 | void ps2_queue(void *, int b); |
| 972 | +void ps2_keyboard_set_translation(void *opaque, int mode); | |
| 972 | 973 | |
| 973 | 974 | /* smc91c111.c */ |
| 974 | 975 | void smc91c111_init(NICInfo *, uint32_t, void *, int); | ... | ... |