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); |
... | ... |