1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25#include "qemu/osdep.h"
26#include "hw/hw.h"
27#include "hw/sysbus.h"
28#include "hw/char/escc.h"
29#include "ui/console.h"
30#include "trace.h"
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64#define CHN_C(s) ((s)->chn == escc_chn_b ? 'b' : 'a')
65
66#define SERIAL_CTRL 0
67#define SERIAL_DATA 1
68
69#define W_CMD 0
70#define CMD_PTR_MASK 0x07
71#define CMD_CMD_MASK 0x38
72#define CMD_HI 0x08
73#define CMD_CLR_TXINT 0x28
74#define CMD_CLR_IUS 0x38
75#define W_INTR 1
76#define INTR_INTALL 0x01
77#define INTR_TXINT 0x02
78#define INTR_RXMODEMSK 0x18
79#define INTR_RXINT1ST 0x08
80#define INTR_RXINTALL 0x10
81#define W_IVEC 2
82#define W_RXCTRL 3
83#define RXCTRL_RXEN 0x01
84#define W_TXCTRL1 4
85#define TXCTRL1_PAREN 0x01
86#define TXCTRL1_PAREV 0x02
87#define TXCTRL1_1STOP 0x04
88#define TXCTRL1_1HSTOP 0x08
89#define TXCTRL1_2STOP 0x0c
90#define TXCTRL1_STPMSK 0x0c
91#define TXCTRL1_CLK1X 0x00
92#define TXCTRL1_CLK16X 0x40
93#define TXCTRL1_CLK32X 0x80
94#define TXCTRL1_CLK64X 0xc0
95#define TXCTRL1_CLKMSK 0xc0
96#define W_TXCTRL2 5
97#define TXCTRL2_TXEN 0x08
98#define TXCTRL2_BITMSK 0x60
99#define TXCTRL2_5BITS 0x00
100#define TXCTRL2_7BITS 0x20
101#define TXCTRL2_6BITS 0x40
102#define TXCTRL2_8BITS 0x60
103#define W_SYNC1 6
104#define W_SYNC2 7
105#define W_TXBUF 8
106#define W_MINTR 9
107#define MINTR_STATUSHI 0x10
108#define MINTR_RST_MASK 0xc0
109#define MINTR_RST_B 0x40
110#define MINTR_RST_A 0x80
111#define MINTR_RST_ALL 0xc0
112#define W_MISC1 10
113#define W_CLOCK 11
114#define CLOCK_TRXC 0x08
115#define W_BRGLO 12
116#define W_BRGHI 13
117#define W_MISC2 14
118#define MISC2_PLLDIS 0x30
119#define W_EXTINT 15
120#define EXTINT_DCD 0x08
121#define EXTINT_SYNCINT 0x10
122#define EXTINT_CTSINT 0x20
123#define EXTINT_TXUNDRN 0x40
124#define EXTINT_BRKINT 0x80
125
126#define R_STATUS 0
127#define STATUS_RXAV 0x01
128#define STATUS_ZERO 0x02
129#define STATUS_TXEMPTY 0x04
130#define STATUS_DCD 0x08
131#define STATUS_SYNC 0x10
132#define STATUS_CTS 0x20
133#define STATUS_TXUNDRN 0x40
134#define STATUS_BRK 0x80
135#define R_SPEC 1
136#define SPEC_ALLSENT 0x01
137#define SPEC_BITS8 0x06
138#define R_IVEC 2
139#define IVEC_TXINTB 0x00
140#define IVEC_LONOINT 0x06
141#define IVEC_LORXINTA 0x0c
142#define IVEC_LORXINTB 0x04
143#define IVEC_LOTXINTA 0x08
144#define IVEC_HINOINT 0x60
145#define IVEC_HIRXINTA 0x30
146#define IVEC_HIRXINTB 0x20
147#define IVEC_HITXINTA 0x10
148#define R_INTR 3
149#define INTR_EXTINTB 0x01
150#define INTR_TXINTB 0x02
151#define INTR_RXINTB 0x04
152#define INTR_EXTINTA 0x08
153#define INTR_TXINTA 0x10
154#define INTR_RXINTA 0x20
155#define R_IPEN 4
156#define R_TXCTRL1 5
157#define R_TXCTRL2 6
158#define R_BC 7
159#define R_RXBUF 8
160#define R_RXCTRL 9
161#define R_MISC 10
162#define R_MISC1 11
163#define R_BRGLO 12
164#define R_BRGHI 13
165#define R_MISC1I 14
166#define R_EXTINT 15
167
168static void handle_kbd_command(ESCCChannelState *s, int val);
169static int serial_can_receive(void *opaque);
170static void serial_receive_byte(ESCCChannelState *s, int ch);
171
172static void clear_queue(void *opaque)
173{
174 ESCCChannelState *s = opaque;
175 ESCCSERIOQueue *q = &s->queue;
176 q->rptr = q->wptr = q->count = 0;
177}
178
179static void put_queue(void *opaque, int b)
180{
181 ESCCChannelState *s = opaque;
182 ESCCSERIOQueue *q = &s->queue;
183
184 trace_escc_put_queue(CHN_C(s), b);
185 if (q->count >= ESCC_SERIO_QUEUE_SIZE) {
186 return;
187 }
188 q->data[q->wptr] = b;
189 if (++q->wptr == ESCC_SERIO_QUEUE_SIZE) {
190 q->wptr = 0;
191 }
192 q->count++;
193 serial_receive_byte(s, 0);
194}
195
196static uint32_t get_queue(void *opaque)
197{
198 ESCCChannelState *s = opaque;
199 ESCCSERIOQueue *q = &s->queue;
200 int val;
201
202 if (q->count == 0) {
203 return 0;
204 } else {
205 val = q->data[q->rptr];
206 if (++q->rptr == ESCC_SERIO_QUEUE_SIZE) {
207 q->rptr = 0;
208 }
209 q->count--;
210 }
211 trace_escc_get_queue(CHN_C(s), val);
212 if (q->count > 0)
213 serial_receive_byte(s, 0);
214 return val;
215}
216
217static int escc_update_irq_chn(ESCCChannelState *s)
218{
219 if ((((s->wregs[W_INTR] & INTR_TXINT) && (s->txint == 1)) ||
220
221 ((((s->wregs[W_INTR] & INTR_RXMODEMSK) == INTR_RXINT1ST) ||
222 ((s->wregs[W_INTR] & INTR_RXMODEMSK) == INTR_RXINTALL)) &&
223 s->rxint == 1) ||
224 ((s->wregs[W_EXTINT] & EXTINT_BRKINT) &&
225 (s->rregs[R_STATUS] & STATUS_BRK)))) {
226 return 1;
227 }
228 return 0;
229}
230
231static void escc_update_irq(ESCCChannelState *s)
232{
233 int irq;
234
235 irq = escc_update_irq_chn(s);
236 irq |= escc_update_irq_chn(s->otherchn);
237
238 trace_escc_update_irq(irq);
239 qemu_set_irq(s->irq, irq);
240}
241
242static void escc_reset_chn(ESCCChannelState *s)
243{
244 int i;
245
246 s->reg = 0;
247 for (i = 0; i < ESCC_SERIAL_REGS; i++) {
248 s->rregs[i] = 0;
249 s->wregs[i] = 0;
250 }
251 s->wregs[W_TXCTRL1] = TXCTRL1_1STOP;
252 s->wregs[W_MINTR] = MINTR_RST_ALL;
253 s->wregs[W_CLOCK] = CLOCK_TRXC;
254 s->wregs[W_MISC2] = MISC2_PLLDIS;
255 s->wregs[W_EXTINT] = EXTINT_DCD | EXTINT_SYNCINT | EXTINT_CTSINT |
256 EXTINT_TXUNDRN | EXTINT_BRKINT;
257 if (s->disabled)
258 s->rregs[R_STATUS] = STATUS_TXEMPTY | STATUS_DCD | STATUS_SYNC |
259 STATUS_CTS | STATUS_TXUNDRN;
260 else
261 s->rregs[R_STATUS] = STATUS_TXEMPTY | STATUS_TXUNDRN;
262 s->rregs[R_SPEC] = SPEC_BITS8 | SPEC_ALLSENT;
263
264 s->rx = s->tx = 0;
265 s->rxint = s->txint = 0;
266 s->rxint_under_svc = s->txint_under_svc = 0;
267 s->e0_mode = s->led_mode = s->caps_lock_mode = s->num_lock_mode = 0;
268 clear_queue(s);
269}
270
271static void escc_reset(DeviceState *d)
272{
273 ESCCState *s = ESCC(d);
274
275 escc_reset_chn(&s->chn[0]);
276 escc_reset_chn(&s->chn[1]);
277}
278
279static inline void set_rxint(ESCCChannelState *s)
280{
281 s->rxint = 1;
282
283
284 s->rxint_under_svc = 1;
285 if (s->chn == escc_chn_a) {
286 s->rregs[R_INTR] |= INTR_RXINTA;
287 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
288 s->otherchn->rregs[R_IVEC] = IVEC_HIRXINTA;
289 else
290 s->otherchn->rregs[R_IVEC] = IVEC_LORXINTA;
291 } else {
292 s->otherchn->rregs[R_INTR] |= INTR_RXINTB;
293 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
294 s->rregs[R_IVEC] = IVEC_HIRXINTB;
295 else
296 s->rregs[R_IVEC] = IVEC_LORXINTB;
297 }
298 escc_update_irq(s);
299}
300
301static inline void set_txint(ESCCChannelState *s)
302{
303 s->txint = 1;
304 if (!s->rxint_under_svc) {
305 s->txint_under_svc = 1;
306 if (s->chn == escc_chn_a) {
307 if (s->wregs[W_INTR] & INTR_TXINT) {
308 s->rregs[R_INTR] |= INTR_TXINTA;
309 }
310 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
311 s->otherchn->rregs[R_IVEC] = IVEC_HITXINTA;
312 else
313 s->otherchn->rregs[R_IVEC] = IVEC_LOTXINTA;
314 } else {
315 s->rregs[R_IVEC] = IVEC_TXINTB;
316 if (s->wregs[W_INTR] & INTR_TXINT) {
317 s->otherchn->rregs[R_INTR] |= INTR_TXINTB;
318 }
319 }
320 escc_update_irq(s);
321 }
322}
323
324static inline void clr_rxint(ESCCChannelState *s)
325{
326 s->rxint = 0;
327 s->rxint_under_svc = 0;
328 if (s->chn == escc_chn_a) {
329 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
330 s->otherchn->rregs[R_IVEC] = IVEC_HINOINT;
331 else
332 s->otherchn->rregs[R_IVEC] = IVEC_LONOINT;
333 s->rregs[R_INTR] &= ~INTR_RXINTA;
334 } else {
335 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
336 s->rregs[R_IVEC] = IVEC_HINOINT;
337 else
338 s->rregs[R_IVEC] = IVEC_LONOINT;
339 s->otherchn->rregs[R_INTR] &= ~INTR_RXINTB;
340 }
341 if (s->txint)
342 set_txint(s);
343 escc_update_irq(s);
344}
345
346static inline void clr_txint(ESCCChannelState *s)
347{
348 s->txint = 0;
349 s->txint_under_svc = 0;
350 if (s->chn == escc_chn_a) {
351 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
352 s->otherchn->rregs[R_IVEC] = IVEC_HINOINT;
353 else
354 s->otherchn->rregs[R_IVEC] = IVEC_LONOINT;
355 s->rregs[R_INTR] &= ~INTR_TXINTA;
356 } else {
357 s->otherchn->rregs[R_INTR] &= ~INTR_TXINTB;
358 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
359 s->rregs[R_IVEC] = IVEC_HINOINT;
360 else
361 s->rregs[R_IVEC] = IVEC_LONOINT;
362 s->otherchn->rregs[R_INTR] &= ~INTR_TXINTB;
363 }
364 if (s->rxint)
365 set_rxint(s);
366 escc_update_irq(s);
367}
368
369static void escc_update_parameters(ESCCChannelState *s)
370{
371 int speed, parity, data_bits, stop_bits;
372 QEMUSerialSetParams ssp;
373
374 if (!qemu_chr_fe_backend_connected(&s->chr) || s->type != escc_serial)
375 return;
376
377 if (s->wregs[W_TXCTRL1] & TXCTRL1_PAREN) {
378 if (s->wregs[W_TXCTRL1] & TXCTRL1_PAREV)
379 parity = 'E';
380 else
381 parity = 'O';
382 } else {
383 parity = 'N';
384 }
385 if ((s->wregs[W_TXCTRL1] & TXCTRL1_STPMSK) == TXCTRL1_2STOP)
386 stop_bits = 2;
387 else
388 stop_bits = 1;
389 switch (s->wregs[W_TXCTRL2] & TXCTRL2_BITMSK) {
390 case TXCTRL2_5BITS:
391 data_bits = 5;
392 break;
393 case TXCTRL2_7BITS:
394 data_bits = 7;
395 break;
396 case TXCTRL2_6BITS:
397 data_bits = 6;
398 break;
399 default:
400 case TXCTRL2_8BITS:
401 data_bits = 8;
402 break;
403 }
404 speed = s->clock / ((s->wregs[W_BRGLO] | (s->wregs[W_BRGHI] << 8)) + 2);
405 switch (s->wregs[W_TXCTRL1] & TXCTRL1_CLKMSK) {
406 case TXCTRL1_CLK1X:
407 break;
408 case TXCTRL1_CLK16X:
409 speed /= 16;
410 break;
411 case TXCTRL1_CLK32X:
412 speed /= 32;
413 break;
414 default:
415 case TXCTRL1_CLK64X:
416 speed /= 64;
417 break;
418 }
419 ssp.speed = speed;
420 ssp.parity = parity;
421 ssp.data_bits = data_bits;
422 ssp.stop_bits = stop_bits;
423 trace_escc_update_parameters(CHN_C(s), speed, parity, data_bits, stop_bits);
424 qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
425}
426
427static void escc_mem_write(void *opaque, hwaddr addr,
428 uint64_t val, unsigned size)
429{
430 ESCCState *serial = opaque;
431 ESCCChannelState *s;
432 uint32_t saddr;
433 int newreg, channel;
434
435 val &= 0xff;
436 saddr = (addr >> serial->it_shift) & 1;
437 channel = (addr >> (serial->it_shift + 1)) & 1;
438 s = &serial->chn[channel];
439 switch (saddr) {
440 case SERIAL_CTRL:
441 trace_escc_mem_writeb_ctrl(CHN_C(s), s->reg, val & 0xff);
442 newreg = 0;
443 switch (s->reg) {
444 case W_CMD:
445 newreg = val & CMD_PTR_MASK;
446 val &= CMD_CMD_MASK;
447 switch (val) {
448 case CMD_HI:
449 newreg |= CMD_HI;
450 break;
451 case CMD_CLR_TXINT:
452 clr_txint(s);
453 break;
454 case CMD_CLR_IUS:
455 if (s->rxint_under_svc) {
456 s->rxint_under_svc = 0;
457 if (s->txint) {
458 set_txint(s);
459 }
460 } else if (s->txint_under_svc) {
461 s->txint_under_svc = 0;
462 }
463 escc_update_irq(s);
464 break;
465 default:
466 break;
467 }
468 break;
469 case W_INTR ... W_RXCTRL:
470 case W_SYNC1 ... W_TXBUF:
471 case W_MISC1 ... W_CLOCK:
472 case W_MISC2 ... W_EXTINT:
473 s->wregs[s->reg] = val;
474 break;
475 case W_TXCTRL1:
476 case W_TXCTRL2:
477 s->wregs[s->reg] = val;
478 escc_update_parameters(s);
479 break;
480 case W_BRGLO:
481 case W_BRGHI:
482 s->wregs[s->reg] = val;
483 s->rregs[s->reg] = val;
484 escc_update_parameters(s);
485 break;
486 case W_MINTR:
487 switch (val & MINTR_RST_MASK) {
488 case 0:
489 default:
490 break;
491 case MINTR_RST_B:
492 escc_reset_chn(&serial->chn[0]);
493 return;
494 case MINTR_RST_A:
495 escc_reset_chn(&serial->chn[1]);
496 return;
497 case MINTR_RST_ALL:
498 escc_reset(DEVICE(serial));
499 return;
500 }
501 break;
502 default:
503 break;
504 }
505 if (s->reg == 0)
506 s->reg = newreg;
507 else
508 s->reg = 0;
509 break;
510 case SERIAL_DATA:
511 trace_escc_mem_writeb_data(CHN_C(s), val);
512 s->tx = val;
513 if (s->wregs[W_TXCTRL2] & TXCTRL2_TXEN) {
514 if (qemu_chr_fe_backend_connected(&s->chr)) {
515
516
517 qemu_chr_fe_write_all(&s->chr, &s->tx, 1);
518 } else if (s->type == escc_kbd && !s->disabled) {
519 handle_kbd_command(s, val);
520 }
521 }
522 s->rregs[R_STATUS] |= STATUS_TXEMPTY;
523 s->rregs[R_SPEC] |= SPEC_ALLSENT;
524 set_txint(s);
525 break;
526 default:
527 break;
528 }
529}
530
531static uint64_t escc_mem_read(void *opaque, hwaddr addr,
532 unsigned size)
533{
534 ESCCState *serial = opaque;
535 ESCCChannelState *s;
536 uint32_t saddr;
537 uint32_t ret;
538 int channel;
539
540 saddr = (addr >> serial->it_shift) & 1;
541 channel = (addr >> (serial->it_shift + 1)) & 1;
542 s = &serial->chn[channel];
543 switch (saddr) {
544 case SERIAL_CTRL:
545 trace_escc_mem_readb_ctrl(CHN_C(s), s->reg, s->rregs[s->reg]);
546 ret = s->rregs[s->reg];
547 s->reg = 0;
548 return ret;
549 case SERIAL_DATA:
550 s->rregs[R_STATUS] &= ~STATUS_RXAV;
551 clr_rxint(s);
552 if (s->type == escc_kbd || s->type == escc_mouse) {
553 ret = get_queue(s);
554 } else {
555 ret = s->rx;
556 }
557 trace_escc_mem_readb_data(CHN_C(s), ret);
558 qemu_chr_fe_accept_input(&s->chr);
559 return ret;
560 default:
561 break;
562 }
563 return 0;
564}
565
566static const MemoryRegionOps escc_mem_ops = {
567 .read = escc_mem_read,
568 .write = escc_mem_write,
569 .endianness = DEVICE_NATIVE_ENDIAN,
570 .valid = {
571 .min_access_size = 1,
572 .max_access_size = 1,
573 },
574};
575
576static int serial_can_receive(void *opaque)
577{
578 ESCCChannelState *s = opaque;
579 int ret;
580
581 if (((s->wregs[W_RXCTRL] & RXCTRL_RXEN) == 0)
582 || ((s->rregs[R_STATUS] & STATUS_RXAV) == STATUS_RXAV))
583
584 ret = 0;
585 else
586 ret = 1;
587 return ret;
588}
589
590static void serial_receive_byte(ESCCChannelState *s, int ch)
591{
592 trace_escc_serial_receive_byte(CHN_C(s), ch);
593 s->rregs[R_STATUS] |= STATUS_RXAV;
594 s->rx = ch;
595 set_rxint(s);
596}
597
598static void serial_receive_break(ESCCChannelState *s)
599{
600 s->rregs[R_STATUS] |= STATUS_BRK;
601 escc_update_irq(s);
602}
603
604static void serial_receive1(void *opaque, const uint8_t *buf, int size)
605{
606 ESCCChannelState *s = opaque;
607 serial_receive_byte(s, buf[0]);
608}
609
610static void serial_event(void *opaque, int event)
611{
612 ESCCChannelState *s = opaque;
613 if (event == CHR_EVENT_BREAK)
614 serial_receive_break(s);
615}
616
617static const VMStateDescription vmstate_escc_chn = {
618 .name ="escc_chn",
619 .version_id = 2,
620 .minimum_version_id = 1,
621 .fields = (VMStateField[]) {
622 VMSTATE_UINT32(vmstate_dummy, ESCCChannelState),
623 VMSTATE_UINT32(reg, ESCCChannelState),
624 VMSTATE_UINT32(rxint, ESCCChannelState),
625 VMSTATE_UINT32(txint, ESCCChannelState),
626 VMSTATE_UINT32(rxint_under_svc, ESCCChannelState),
627 VMSTATE_UINT32(txint_under_svc, ESCCChannelState),
628 VMSTATE_UINT8(rx, ESCCChannelState),
629 VMSTATE_UINT8(tx, ESCCChannelState),
630 VMSTATE_BUFFER(wregs, ESCCChannelState),
631 VMSTATE_BUFFER(rregs, ESCCChannelState),
632 VMSTATE_END_OF_LIST()
633 }
634};
635
636static const VMStateDescription vmstate_escc = {
637 .name ="escc",
638 .version_id = 2,
639 .minimum_version_id = 1,
640 .fields = (VMStateField[]) {
641 VMSTATE_STRUCT_ARRAY(chn, ESCCState, 2, 2, vmstate_escc_chn,
642 ESCCChannelState),
643 VMSTATE_END_OF_LIST()
644 }
645};
646
647static void sunkbd_handle_event(DeviceState *dev, QemuConsole *src,
648 InputEvent *evt)
649{
650 ESCCChannelState *s = (ESCCChannelState *)dev;
651 int qcode, keycode;
652 InputKeyEvent *key;
653
654 assert(evt->type == INPUT_EVENT_KIND_KEY);
655 key = evt->u.key.data;
656 qcode = qemu_input_key_value_to_qcode(key->key);
657 trace_escc_sunkbd_event_in(qcode, QKeyCode_str(qcode),
658 key->down);
659
660 if (qcode == Q_KEY_CODE_CAPS_LOCK) {
661 if (key->down) {
662 s->caps_lock_mode ^= 1;
663 if (s->caps_lock_mode == 2) {
664 return;
665 }
666 } else {
667 s->caps_lock_mode ^= 2;
668 if (s->caps_lock_mode == 3) {
669 return;
670 }
671 }
672 }
673
674 if (qcode == Q_KEY_CODE_NUM_LOCK) {
675 if (key->down) {
676 s->num_lock_mode ^= 1;
677 if (s->num_lock_mode == 2) {
678 return;
679 }
680 } else {
681 s->num_lock_mode ^= 2;
682 if (s->num_lock_mode == 3) {
683 return;
684 }
685 }
686 }
687
688 if (qcode > qemu_input_map_qcode_to_sun_len) {
689 return;
690 }
691
692 keycode = qemu_input_map_qcode_to_sun[qcode];
693 if (!key->down) {
694 keycode |= 0x80;
695 }
696 trace_escc_sunkbd_event_out(keycode);
697 put_queue(s, keycode);
698}
699
700static QemuInputHandler sunkbd_handler = {
701 .name = "sun keyboard",
702 .mask = INPUT_EVENT_MASK_KEY,
703 .event = sunkbd_handle_event,
704};
705
706static void handle_kbd_command(ESCCChannelState *s, int val)
707{
708 trace_escc_kbd_command(val);
709 if (s->led_mode) {
710 s->led_mode = 0;
711 return;
712 }
713 switch (val) {
714 case 1:
715 clear_queue(s);
716 put_queue(s, 0xff);
717 put_queue(s, 4);
718 put_queue(s, 0x7f);
719 break;
720 case 0xe:
721 s->led_mode = 1;
722 break;
723 case 7:
724 case 0xf:
725 clear_queue(s);
726 put_queue(s, 0xfe);
727 put_queue(s, 0x21);
728 break;
729 default:
730 break;
731 }
732}
733
734static void sunmouse_event(void *opaque,
735 int dx, int dy, int dz, int buttons_state)
736{
737 ESCCChannelState *s = opaque;
738 int ch;
739
740 trace_escc_sunmouse_event(dx, dy, buttons_state);
741 ch = 0x80 | 0x7;
742
743 if (buttons_state & MOUSE_EVENT_LBUTTON)
744 ch ^= 0x4;
745 if (buttons_state & MOUSE_EVENT_MBUTTON)
746 ch ^= 0x2;
747 if (buttons_state & MOUSE_EVENT_RBUTTON)
748 ch ^= 0x1;
749
750 put_queue(s, ch);
751
752 ch = dx;
753
754 if (ch > 127)
755 ch = 127;
756 else if (ch < -127)
757 ch = -127;
758
759 put_queue(s, ch & 0xff);
760
761 ch = -dy;
762
763 if (ch > 127)
764 ch = 127;
765 else if (ch < -127)
766 ch = -127;
767
768 put_queue(s, ch & 0xff);
769
770
771
772 put_queue(s, 0);
773 put_queue(s, 0);
774}
775
776static void escc_init1(Object *obj)
777{
778 ESCCState *s = ESCC(obj);
779 SysBusDevice *dev = SYS_BUS_DEVICE(obj);
780 unsigned int i;
781
782 for (i = 0; i < 2; i++) {
783 sysbus_init_irq(dev, &s->chn[i].irq);
784 s->chn[i].chn = 1 - i;
785 }
786 s->chn[0].otherchn = &s->chn[1];
787 s->chn[1].otherchn = &s->chn[0];
788
789 sysbus_init_mmio(dev, &s->mmio);
790}
791
792static void escc_realize(DeviceState *dev, Error **errp)
793{
794 ESCCState *s = ESCC(dev);
795 unsigned int i;
796
797 s->chn[0].disabled = s->disabled;
798 s->chn[1].disabled = s->disabled;
799
800 memory_region_init_io(&s->mmio, OBJECT(dev), &escc_mem_ops, s, "escc",
801 ESCC_SIZE << s->it_shift);
802
803 for (i = 0; i < 2; i++) {
804 if (qemu_chr_fe_backend_connected(&s->chn[i].chr)) {
805 s->chn[i].clock = s->frequency / 2;
806 qemu_chr_fe_set_handlers(&s->chn[i].chr, serial_can_receive,
807 serial_receive1, serial_event, NULL,
808 &s->chn[i], NULL, true);
809 }
810 }
811
812 if (s->chn[0].type == escc_mouse) {
813 qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0,
814 "QEMU Sun Mouse");
815 }
816 if (s->chn[1].type == escc_kbd) {
817 s->chn[1].hs = qemu_input_handler_register((DeviceState *)(&s->chn[1]),
818 &sunkbd_handler);
819 }
820}
821
822static Property escc_properties[] = {
823 DEFINE_PROP_UINT32("frequency", ESCCState, frequency, 0),
824 DEFINE_PROP_UINT32("it_shift", ESCCState, it_shift, 0),
825 DEFINE_PROP_UINT32("disabled", ESCCState, disabled, 0),
826 DEFINE_PROP_UINT32("chnBtype", ESCCState, chn[0].type, 0),
827 DEFINE_PROP_UINT32("chnAtype", ESCCState, chn[1].type, 0),
828 DEFINE_PROP_CHR("chrB", ESCCState, chn[0].chr),
829 DEFINE_PROP_CHR("chrA", ESCCState, chn[1].chr),
830 DEFINE_PROP_END_OF_LIST(),
831};
832
833static void escc_class_init(ObjectClass *klass, void *data)
834{
835 DeviceClass *dc = DEVICE_CLASS(klass);
836
837 dc->reset = escc_reset;
838 dc->realize = escc_realize;
839 dc->vmsd = &vmstate_escc;
840 dc->props = escc_properties;
841 set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
842}
843
844static const TypeInfo escc_info = {
845 .name = TYPE_ESCC,
846 .parent = TYPE_SYS_BUS_DEVICE,
847 .instance_size = sizeof(ESCCState),
848 .instance_init = escc_init1,
849 .class_init = escc_class_init,
850};
851
852static void escc_register_types(void)
853{
854 type_register_static(&escc_info);
855}
856
857type_init(escc_register_types)
858