]> git.proxmox.com Git - mirror_qemu.git/blob - hw/slavio_serial.c
No keyboard mode (Robert Reif)
[mirror_qemu.git] / hw / slavio_serial.c
1 /*
2 * QEMU Sparc SLAVIO serial port emulation
3 *
4 * Copyright (c) 2003-2005 Fabrice Bellard
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24 #include "hw.h"
25 #include "sun4m.h"
26 #include "qemu-char.h"
27 #include "console.h"
28
29 /* debug serial */
30 //#define DEBUG_SERIAL
31
32 /* debug keyboard */
33 //#define DEBUG_KBD
34
35 /* debug mouse */
36 //#define DEBUG_MOUSE
37
38 /*
39 * This is the serial port, mouse and keyboard part of chip STP2001
40 * (Slave I/O), also produced as NCR89C105. See
41 * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C105.txt
42 *
43 * The serial ports implement full AMD AM8530 or Zilog Z8530 chips,
44 * mouse and keyboard ports don't implement all functions and they are
45 * only asynchronous. There is no DMA.
46 *
47 */
48
49 /*
50 * Modifications:
51 * 2006-Aug-10 Igor Kovalenko : Renamed KBDQueue to SERIOQueue, implemented
52 * serial mouse queue.
53 * Implemented serial mouse protocol.
54 */
55
56 #ifdef DEBUG_SERIAL
57 #define SER_DPRINTF(fmt, args...) \
58 do { printf("SER: " fmt , ##args); } while (0)
59 #else
60 #define SER_DPRINTF(fmt, args...)
61 #endif
62 #ifdef DEBUG_KBD
63 #define KBD_DPRINTF(fmt, args...) \
64 do { printf("KBD: " fmt , ##args); } while (0)
65 #else
66 #define KBD_DPRINTF(fmt, args...)
67 #endif
68 #ifdef DEBUG_MOUSE
69 #define MS_DPRINTF(fmt, args...) \
70 do { printf("MSC: " fmt , ##args); } while (0)
71 #else
72 #define MS_DPRINTF(fmt, args...)
73 #endif
74
75 typedef enum {
76 chn_a, chn_b,
77 } chn_id_t;
78
79 #define CHN_C(s) ((s)->chn == chn_b? 'b' : 'a')
80
81 typedef enum {
82 ser, kbd, mouse,
83 } chn_type_t;
84
85 #define SERIO_QUEUE_SIZE 256
86
87 typedef struct {
88 uint8_t data[SERIO_QUEUE_SIZE];
89 int rptr, wptr, count;
90 } SERIOQueue;
91
92 typedef struct ChannelState {
93 qemu_irq irq;
94 int reg;
95 int rxint, txint, rxint_under_svc, txint_under_svc;
96 chn_id_t chn; // this channel, A (base+4) or B (base+0)
97 chn_type_t type;
98 struct ChannelState *otherchn;
99 uint8_t rx, tx, wregs[16], rregs[16];
100 SERIOQueue queue;
101 CharDriverState *chr;
102 int e0_mode, led_mode, caps_lock_mode, num_lock_mode;
103 int disabled;
104 } ChannelState;
105
106 struct SerialState {
107 struct ChannelState chn[2];
108 };
109
110 #define SERIAL_MAXADDR 7
111 #define SERIAL_SIZE (SERIAL_MAXADDR + 1)
112
113 static void handle_kbd_command(ChannelState *s, int val);
114 static int serial_can_receive(void *opaque);
115 static void serial_receive_byte(ChannelState *s, int ch);
116 static inline void set_txint(ChannelState *s);
117
118 static void clear_queue(void *opaque)
119 {
120 ChannelState *s = opaque;
121 SERIOQueue *q = &s->queue;
122 q->rptr = q->wptr = q->count = 0;
123 }
124
125 static void put_queue(void *opaque, int b)
126 {
127 ChannelState *s = opaque;
128 SERIOQueue *q = &s->queue;
129
130 SER_DPRINTF("channel %c put: 0x%02x\n", CHN_C(s), b);
131 if (q->count >= SERIO_QUEUE_SIZE)
132 return;
133 q->data[q->wptr] = b;
134 if (++q->wptr == SERIO_QUEUE_SIZE)
135 q->wptr = 0;
136 q->count++;
137 serial_receive_byte(s, 0);
138 }
139
140 static uint32_t get_queue(void *opaque)
141 {
142 ChannelState *s = opaque;
143 SERIOQueue *q = &s->queue;
144 int val;
145
146 if (q->count == 0) {
147 return 0;
148 } else {
149 val = q->data[q->rptr];
150 if (++q->rptr == SERIO_QUEUE_SIZE)
151 q->rptr = 0;
152 q->count--;
153 }
154 SER_DPRINTF("channel %c get 0x%02x\n", CHN_C(s), val);
155 if (q->count > 0)
156 serial_receive_byte(s, 0);
157 return val;
158 }
159
160 static int slavio_serial_update_irq_chn(ChannelState *s)
161 {
162 if ((s->wregs[1] & 1) && // interrupts enabled
163 (((s->wregs[1] & 2) && s->txint == 1) || // tx ints enabled, pending
164 ((((s->wregs[1] & 0x18) == 8) || ((s->wregs[1] & 0x18) == 0x10)) &&
165 s->rxint == 1) || // rx ints enabled, pending
166 ((s->wregs[15] & 0x80) && (s->rregs[0] & 0x80)))) { // break int e&p
167 return 1;
168 }
169 return 0;
170 }
171
172 static void slavio_serial_update_irq(ChannelState *s)
173 {
174 int irq;
175
176 irq = slavio_serial_update_irq_chn(s);
177 irq |= slavio_serial_update_irq_chn(s->otherchn);
178
179 SER_DPRINTF("IRQ = %d\n", irq);
180 qemu_set_irq(s->irq, irq);
181 }
182
183 static void slavio_serial_reset_chn(ChannelState *s)
184 {
185 int i;
186
187 s->reg = 0;
188 for (i = 0; i < SERIAL_SIZE; i++) {
189 s->rregs[i] = 0;
190 s->wregs[i] = 0;
191 }
192 s->wregs[4] = 4;
193 s->wregs[9] = 0xc0;
194 s->wregs[11] = 8;
195 s->wregs[14] = 0x30;
196 s->wregs[15] = 0xf8;
197 if (s->disabled)
198 s->rregs[0] = 0x7c;
199 else
200 s->rregs[0] = 0x44;
201 s->rregs[1] = 6;
202
203 s->rx = s->tx = 0;
204 s->rxint = s->txint = 0;
205 s->rxint_under_svc = s->txint_under_svc = 0;
206 s->e0_mode = s->led_mode = s->caps_lock_mode = s->num_lock_mode = 0;
207 clear_queue(s);
208 }
209
210 static void slavio_serial_reset(void *opaque)
211 {
212 SerialState *s = opaque;
213 slavio_serial_reset_chn(&s->chn[0]);
214 slavio_serial_reset_chn(&s->chn[1]);
215 }
216
217 static inline void clr_rxint(ChannelState *s)
218 {
219 s->rxint = 0;
220 s->rxint_under_svc = 0;
221 if (s->chn == chn_a) {
222 if (s->wregs[9] & 0x10)
223 s->otherchn->rregs[2] = 0x60;
224 else
225 s->otherchn->rregs[2] = 0x06;
226 s->rregs[3] &= ~0x20;
227 } else {
228 if (s->wregs[9] & 0x10)
229 s->rregs[2] = 0x60;
230 else
231 s->rregs[2] = 0x06;
232 s->otherchn->rregs[3] &= ~4;
233 }
234 if (s->txint)
235 set_txint(s);
236 slavio_serial_update_irq(s);
237 }
238
239 static inline void set_rxint(ChannelState *s)
240 {
241 s->rxint = 1;
242 if (!s->txint_under_svc) {
243 s->rxint_under_svc = 1;
244 if (s->chn == chn_a) {
245 if (s->wregs[9] & 0x10)
246 s->otherchn->rregs[2] = 0x30;
247 else
248 s->otherchn->rregs[2] = 0x0c;
249 } else {
250 if (s->wregs[9] & 0x10)
251 s->rregs[2] = 0x20;
252 else
253 s->rregs[2] = 0x04;
254 }
255 }
256 if (s->chn == chn_a)
257 s->rregs[3] |= 0x20;
258 else
259 s->otherchn->rregs[3] |= 4;
260 slavio_serial_update_irq(s);
261 }
262
263 static inline void clr_txint(ChannelState *s)
264 {
265 s->txint = 0;
266 s->txint_under_svc = 0;
267 if (s->chn == chn_a) {
268 if (s->wregs[9] & 0x10)
269 s->otherchn->rregs[2] = 0x60;
270 else
271 s->otherchn->rregs[2] = 0x06;
272 s->rregs[3] &= ~0x10;
273 } else {
274 if (s->wregs[9] & 0x10)
275 s->rregs[2] = 0x60;
276 else
277 s->rregs[2] = 0x06;
278 s->otherchn->rregs[3] &= ~2;
279 }
280 if (s->rxint)
281 set_rxint(s);
282 slavio_serial_update_irq(s);
283 }
284
285 static inline void set_txint(ChannelState *s)
286 {
287 s->txint = 1;
288 if (!s->rxint_under_svc) {
289 s->txint_under_svc = 1;
290 if (s->chn == chn_a) {
291 if (s->wregs[9] & 0x10)
292 s->otherchn->rregs[2] = 0x10;
293 else
294 s->otherchn->rregs[2] = 0x08;
295 } else {
296 s->rregs[2] = 0;
297 }
298 }
299 if (s->chn == chn_a)
300 s->rregs[3] |= 0x10;
301 else
302 s->otherchn->rregs[3] |= 2;
303 slavio_serial_update_irq(s);
304 }
305
306 static void slavio_serial_update_parameters(ChannelState *s)
307 {
308 int speed, parity, data_bits, stop_bits;
309 QEMUSerialSetParams ssp;
310
311 if (!s->chr || s->type != ser)
312 return;
313
314 if (s->wregs[4] & 1) {
315 if (s->wregs[4] & 2)
316 parity = 'E';
317 else
318 parity = 'O';
319 } else {
320 parity = 'N';
321 }
322 if ((s->wregs[4] & 0x0c) == 0x0c)
323 stop_bits = 2;
324 else
325 stop_bits = 1;
326 switch (s->wregs[5] & 0x60) {
327 case 0x00:
328 data_bits = 5;
329 break;
330 case 0x20:
331 data_bits = 7;
332 break;
333 case 0x40:
334 data_bits = 6;
335 break;
336 default:
337 case 0x60:
338 data_bits = 8;
339 break;
340 }
341 speed = 2457600 / ((s->wregs[12] | (s->wregs[13] << 8)) + 2);
342 switch (s->wregs[4] & 0xc0) {
343 case 0x00:
344 break;
345 case 0x40:
346 speed /= 16;
347 break;
348 case 0x80:
349 speed /= 32;
350 break;
351 default:
352 case 0xc0:
353 speed /= 64;
354 break;
355 }
356 ssp.speed = speed;
357 ssp.parity = parity;
358 ssp.data_bits = data_bits;
359 ssp.stop_bits = stop_bits;
360 SER_DPRINTF("channel %c: speed=%d parity=%c data=%d stop=%d\n", CHN_C(s),
361 speed, parity, data_bits, stop_bits);
362 qemu_chr_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
363 }
364
365 static void slavio_serial_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
366 {
367 SerialState *serial = opaque;
368 ChannelState *s;
369 uint32_t saddr;
370 int newreg, channel;
371
372 val &= 0xff;
373 saddr = (addr & 3) >> 1;
374 channel = (addr & SERIAL_MAXADDR) >> 2;
375 s = &serial->chn[channel];
376 switch (saddr) {
377 case 0:
378 SER_DPRINTF("Write channel %c, reg[%d] = %2.2x\n", CHN_C(s), s->reg, val & 0xff);
379 newreg = 0;
380 switch (s->reg) {
381 case 0:
382 newreg = val & 7;
383 val &= 0x38;
384 switch (val) {
385 case 8:
386 newreg |= 0x8;
387 break;
388 case 0x28:
389 clr_txint(s);
390 break;
391 case 0x38:
392 if (s->rxint_under_svc)
393 clr_rxint(s);
394 else if (s->txint_under_svc)
395 clr_txint(s);
396 break;
397 default:
398 break;
399 }
400 break;
401 case 1 ... 3:
402 case 6 ... 8:
403 case 10 ... 11:
404 case 14 ... 15:
405 s->wregs[s->reg] = val;
406 break;
407 case 4:
408 case 5:
409 case 12:
410 case 13:
411 s->wregs[s->reg] = val;
412 slavio_serial_update_parameters(s);
413 break;
414 case 9:
415 switch (val & 0xc0) {
416 case 0:
417 default:
418 break;
419 case 0x40:
420 slavio_serial_reset_chn(&serial->chn[1]);
421 return;
422 case 0x80:
423 slavio_serial_reset_chn(&serial->chn[0]);
424 return;
425 case 0xc0:
426 slavio_serial_reset(serial);
427 return;
428 }
429 break;
430 default:
431 break;
432 }
433 if (s->reg == 0)
434 s->reg = newreg;
435 else
436 s->reg = 0;
437 break;
438 case 1:
439 SER_DPRINTF("Write channel %c, ch %d\n", CHN_C(s), val);
440 s->tx = val;
441 if (s->wregs[5] & 8) { // tx enabled
442 if (s->chr)
443 qemu_chr_write(s->chr, &s->tx, 1);
444 else if (s->type == kbd && !s->disabled) {
445 handle_kbd_command(s, val);
446 }
447 }
448 s->rregs[0] |= 4; // Tx buffer empty
449 s->rregs[1] |= 1; // All sent
450 set_txint(s);
451 break;
452 default:
453 break;
454 }
455 }
456
457 static uint32_t slavio_serial_mem_readb(void *opaque, target_phys_addr_t addr)
458 {
459 SerialState *serial = opaque;
460 ChannelState *s;
461 uint32_t saddr;
462 uint32_t ret;
463 int channel;
464
465 saddr = (addr & 3) >> 1;
466 channel = (addr & SERIAL_MAXADDR) >> 2;
467 s = &serial->chn[channel];
468 switch (saddr) {
469 case 0:
470 SER_DPRINTF("Read channel %c, reg[%d] = %2.2x\n", CHN_C(s), s->reg, s->rregs[s->reg]);
471 ret = s->rregs[s->reg];
472 s->reg = 0;
473 return ret;
474 case 1:
475 s->rregs[0] &= ~1;
476 clr_rxint(s);
477 if (s->type == kbd || s->type == mouse)
478 ret = get_queue(s);
479 else
480 ret = s->rx;
481 SER_DPRINTF("Read channel %c, ch %d\n", CHN_C(s), ret);
482 if (s->chr)
483 qemu_chr_accept_input(s->chr);
484 return ret;
485 default:
486 break;
487 }
488 return 0;
489 }
490
491 static int serial_can_receive(void *opaque)
492 {
493 ChannelState *s = opaque;
494 int ret;
495
496 if (((s->wregs[3] & 1) == 0) // Rx not enabled
497 || ((s->rregs[0] & 1) == 1)) // char already available
498 ret = 0;
499 else
500 ret = 1;
501 //SER_DPRINTF("channel %c can receive %d\n", CHN_C(s), ret);
502 return ret;
503 }
504
505 static void serial_receive_byte(ChannelState *s, int ch)
506 {
507 SER_DPRINTF("channel %c put ch %d\n", CHN_C(s), ch);
508 s->rregs[0] |= 1;
509 s->rx = ch;
510 set_rxint(s);
511 }
512
513 static void serial_receive_break(ChannelState *s)
514 {
515 s->rregs[0] |= 0x80;
516 slavio_serial_update_irq(s);
517 }
518
519 static void serial_receive1(void *opaque, const uint8_t *buf, int size)
520 {
521 ChannelState *s = opaque;
522 serial_receive_byte(s, buf[0]);
523 }
524
525 static void serial_event(void *opaque, int event)
526 {
527 ChannelState *s = opaque;
528 if (event == CHR_EVENT_BREAK)
529 serial_receive_break(s);
530 }
531
532 static CPUReadMemoryFunc *slavio_serial_mem_read[3] = {
533 slavio_serial_mem_readb,
534 slavio_serial_mem_readb,
535 slavio_serial_mem_readb,
536 };
537
538 static CPUWriteMemoryFunc *slavio_serial_mem_write[3] = {
539 slavio_serial_mem_writeb,
540 slavio_serial_mem_writeb,
541 slavio_serial_mem_writeb,
542 };
543
544 static void slavio_serial_save_chn(QEMUFile *f, ChannelState *s)
545 {
546 int tmp;
547 tmp = 0;
548 qemu_put_be32s(f, &tmp); /* unused, was IRQ. */
549 qemu_put_be32s(f, &s->reg);
550 qemu_put_be32s(f, &s->rxint);
551 qemu_put_be32s(f, &s->txint);
552 qemu_put_be32s(f, &s->rxint_under_svc);
553 qemu_put_be32s(f, &s->txint_under_svc);
554 qemu_put_8s(f, &s->rx);
555 qemu_put_8s(f, &s->tx);
556 qemu_put_buffer(f, s->wregs, 16);
557 qemu_put_buffer(f, s->rregs, 16);
558 }
559
560 static void slavio_serial_save(QEMUFile *f, void *opaque)
561 {
562 SerialState *s = opaque;
563
564 slavio_serial_save_chn(f, &s->chn[0]);
565 slavio_serial_save_chn(f, &s->chn[1]);
566 }
567
568 static int slavio_serial_load_chn(QEMUFile *f, ChannelState *s, int version_id)
569 {
570 int tmp;
571
572 if (version_id > 2)
573 return -EINVAL;
574
575 qemu_get_be32s(f, &tmp); /* unused */
576 qemu_get_be32s(f, &s->reg);
577 qemu_get_be32s(f, &s->rxint);
578 qemu_get_be32s(f, &s->txint);
579 if (version_id >= 2) {
580 qemu_get_be32s(f, &s->rxint_under_svc);
581 qemu_get_be32s(f, &s->txint_under_svc);
582 }
583 qemu_get_8s(f, &s->rx);
584 qemu_get_8s(f, &s->tx);
585 qemu_get_buffer(f, s->wregs, 16);
586 qemu_get_buffer(f, s->rregs, 16);
587 return 0;
588 }
589
590 static int slavio_serial_load(QEMUFile *f, void *opaque, int version_id)
591 {
592 SerialState *s = opaque;
593 int ret;
594
595 ret = slavio_serial_load_chn(f, &s->chn[0], version_id);
596 if (ret != 0)
597 return ret;
598 ret = slavio_serial_load_chn(f, &s->chn[1], version_id);
599 return ret;
600
601 }
602
603 SerialState *slavio_serial_init(target_phys_addr_t base, qemu_irq irq,
604 CharDriverState *chr1, CharDriverState *chr2)
605 {
606 int slavio_serial_io_memory, i;
607 SerialState *s;
608
609 s = qemu_mallocz(sizeof(SerialState));
610 if (!s)
611 return NULL;
612
613 slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read, slavio_serial_mem_write, s);
614 cpu_register_physical_memory(base, SERIAL_SIZE, slavio_serial_io_memory);
615
616 s->chn[0].chr = chr1;
617 s->chn[1].chr = chr2;
618 s->chn[0].disabled = 0;
619 s->chn[1].disabled = 0;
620
621 for (i = 0; i < 2; i++) {
622 s->chn[i].irq = irq;
623 s->chn[i].chn = 1 - i;
624 s->chn[i].type = ser;
625 if (s->chn[i].chr) {
626 qemu_chr_add_handlers(s->chn[i].chr, serial_can_receive,
627 serial_receive1, serial_event, &s->chn[i]);
628 }
629 }
630 s->chn[0].otherchn = &s->chn[1];
631 s->chn[1].otherchn = &s->chn[0];
632 register_savevm("slavio_serial", base, 2, slavio_serial_save, slavio_serial_load, s);
633 qemu_register_reset(slavio_serial_reset, s);
634 slavio_serial_reset(s);
635 return s;
636 }
637
638 static const uint8_t keycodes[128] = {
639 127, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 43, 53,
640 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 89, 76, 77, 78,
641 79, 80, 81, 82, 83, 84, 85, 86, 87, 42, 99, 88, 100, 101, 102, 103,
642 104, 105, 106, 107, 108, 109, 110, 47, 19, 121, 119, 5, 6, 8, 10, 12,
643 14, 16, 17, 18, 7, 98, 23, 68, 69, 70, 71, 91, 92, 93, 125, 112,
644 113, 114, 94, 50, 0, 0, 124, 9, 11, 0, 0, 0, 0, 0, 0, 0,
645 90, 0, 46, 22, 13, 111, 52, 20, 96, 24, 28, 74, 27, 123, 44, 66,
646 0, 45, 2, 4, 48, 0, 0, 21, 0, 0, 0, 0, 0, 120, 122, 67,
647 };
648
649 static const uint8_t e0_keycodes[128] = {
650 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
651 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 76, 0, 0,
652 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
653 0, 0, 0, 0, 0, 109, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0,
654 0, 0, 0, 0, 0, 0, 0, 68, 69, 70, 0, 91, 0, 93, 0, 112,
655 113, 114, 94, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
656 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
657 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
658 };
659
660 static void sunkbd_event(void *opaque, int ch)
661 {
662 ChannelState *s = opaque;
663 int release = ch & 0x80;
664
665 KBD_DPRINTF("Untranslated keycode %2.2x (%s)\n", ch, release? "release" : "press");
666 switch (ch) {
667 case 58: // Caps lock press
668 s->caps_lock_mode ^= 1;
669 if (s->caps_lock_mode == 2)
670 return; // Drop second press
671 break;
672 case 69: // Num lock press
673 s->num_lock_mode ^= 1;
674 if (s->num_lock_mode == 2)
675 return; // Drop second press
676 break;
677 case 186: // Caps lock release
678 s->caps_lock_mode ^= 2;
679 if (s->caps_lock_mode == 3)
680 return; // Drop first release
681 break;
682 case 197: // Num lock release
683 s->num_lock_mode ^= 2;
684 if (s->num_lock_mode == 3)
685 return; // Drop first release
686 break;
687 case 0xe0:
688 s->e0_mode = 1;
689 return;
690 default:
691 break;
692 }
693 if (s->e0_mode) {
694 s->e0_mode = 0;
695 ch = e0_keycodes[ch & 0x7f];
696 } else {
697 ch = keycodes[ch & 0x7f];
698 }
699 KBD_DPRINTF("Translated keycode %2.2x\n", ch);
700 put_queue(s, ch | release);
701 }
702
703 static void handle_kbd_command(ChannelState *s, int val)
704 {
705 KBD_DPRINTF("Command %d\n", val);
706 if (s->led_mode) { // Ignore led byte
707 s->led_mode = 0;
708 return;
709 }
710 switch (val) {
711 case 1: // Reset, return type code
712 clear_queue(s);
713 put_queue(s, 0xff);
714 put_queue(s, 4); // Type 4
715 put_queue(s, 0x7f);
716 break;
717 case 0xe: // Set leds
718 s->led_mode = 1;
719 break;
720 case 7: // Query layout
721 case 0xf:
722 clear_queue(s);
723 put_queue(s, 0xfe);
724 put_queue(s, 0); // XXX, layout?
725 break;
726 default:
727 break;
728 }
729 }
730
731 static void sunmouse_event(void *opaque,
732 int dx, int dy, int dz, int buttons_state)
733 {
734 ChannelState *s = opaque;
735 int ch;
736
737 MS_DPRINTF("dx=%d dy=%d buttons=%01x\n", dx, dy, buttons_state);
738
739 ch = 0x80 | 0x7; /* protocol start byte, no buttons pressed */
740
741 if (buttons_state & MOUSE_EVENT_LBUTTON)
742 ch ^= 0x4;
743 if (buttons_state & MOUSE_EVENT_MBUTTON)
744 ch ^= 0x2;
745 if (buttons_state & MOUSE_EVENT_RBUTTON)
746 ch ^= 0x1;
747
748 put_queue(s, ch);
749
750 ch = dx;
751
752 if (ch > 127)
753 ch=127;
754 else if (ch < -127)
755 ch=-127;
756
757 put_queue(s, ch & 0xff);
758
759 ch = -dy;
760
761 if (ch > 127)
762 ch=127;
763 else if (ch < -127)
764 ch=-127;
765
766 put_queue(s, ch & 0xff);
767
768 // MSC protocol specify two extra motion bytes
769
770 put_queue(s, 0);
771 put_queue(s, 0);
772 }
773
774 void slavio_serial_ms_kbd_init(target_phys_addr_t base, qemu_irq irq,
775 int disabled)
776 {
777 int slavio_serial_io_memory, i;
778 SerialState *s;
779
780 s = qemu_mallocz(sizeof(SerialState));
781 if (!s)
782 return;
783 for (i = 0; i < 2; i++) {
784 s->chn[i].irq = irq;
785 s->chn[i].chn = 1 - i;
786 s->chn[i].chr = NULL;
787 }
788 s->chn[0].otherchn = &s->chn[1];
789 s->chn[1].otherchn = &s->chn[0];
790 s->chn[0].type = mouse;
791 s->chn[1].type = kbd;
792 s->chn[0].disabled = disabled;
793 s->chn[1].disabled = disabled;
794
795 slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read, slavio_serial_mem_write, s);
796 cpu_register_physical_memory(base, SERIAL_SIZE, slavio_serial_io_memory);
797
798 qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0, "QEMU Sun Mouse");
799 qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1]);
800 register_savevm("slavio_serial_mouse", base, 2, slavio_serial_save, slavio_serial_load, s);
801 qemu_register_reset(slavio_serial_reset, s);
802 slavio_serial_reset(s);
803 }