--- trunk/src/devices/dev_pckbc.c 2007/10/08 16:19:11 18 +++ trunk/src/devices/dev_pckbc.c 2007/10/08 16:19:23 20 @@ -25,7 +25,7 @@ * SUCH DAMAGE. * * - * $Id: dev_pckbc.c,v 1.53 2005/10/26 14:37:04 debug Exp $ + * $Id: dev_pckbc.c,v 1.60 2005/11/25 04:25:26 debug Exp $ * * Standard 8042 PC keyboard controller (and a 8242WB PS2 keyboard/mouse * controller), including the 8048 keyboard chip. @@ -100,8 +100,10 @@ #define STATE_WAITING_FOR_TRANSLTABLE 3 #define STATE_WAITING_FOR_F3 4 #define STATE_WAITING_FOR_FC 5 -#define STATE_LDOUTPUT 6 -#define STATE_RDOUTPUT 7 +#define STATE_WAITING_FOR_AUX 6 +#define STATE_WAITING_FOR_AUX_OUT 7 +#define STATE_LDOUTPUT 8 +#define STATE_RDOUTPUT 9 /* @@ -269,12 +271,14 @@ /* - * ascii_to_scancodes(): + * ascii_to_scancodes_type2(): * * Conversion from ASCII codes to default (US) keyboard scancodes. * (See http://www.win.tue.nl/~aeb/linux/kbd/scancodes-1.html) + * + * NOTE/TODO: This seems to be type 2, not type 1. */ -static void ascii_to_pc_scancodes(int a, struct pckbc_data *d) +static void ascii_to_pc_scancodes_type2(int a, struct pckbc_data *d) { int old_head; int p = 0; /* port */ @@ -285,7 +289,7 @@ return; } - if (d->translation_table != 1) { + if (d->translation_table != 2) { fatal("[ ascii_to_pc_scancodes: unimplemented type! ]\n"); return; } @@ -440,7 +444,7 @@ if (d->in_use && console_charavail(d->console_handle)) { ch = console_readchar(d->console_handle); if (ch >= 0) - ascii_to_pc_scancodes(ch, d); + ascii_to_pc_scancodes_type2(ch, d); } ints_enabled = d->rx_int_enable; @@ -484,11 +488,12 @@ debug("[ pckbc: (port %i) switching to translation table " "0x%02x ]\n", port_nr, cmd); switch (cmd) { - case 1: + case 2: case 3: d->translation_table = cmd; break; default:fatal("[ pckbc: (port %i) translation table " - "0x%02x is NOT YET IMPLEMENTED ]\n", port_nr, cmd); + "0x%02x is NOT YET IMPLEMENTED ]\n", + port_nr, cmd); } pckbc_add_code(d, KBR_ACK, port_nr); d->state = STATE_NORMAL; @@ -511,6 +516,24 @@ return; } + if (d->state == STATE_WAITING_FOR_AUX) { + debug("[ pckbc: (port %i) received aux data: " + "0x%02x ]\n", port_nr, cmd); + /* Echo back. */ + pckbc_add_code(d, cmd, port_nr); + d->state = STATE_NORMAL; + return; + } + + if (d->state == STATE_WAITING_FOR_AUX_OUT) { + debug("[ pckbc: (port %i) received aux out data: " + "0x%02x ]\n", port_nr, cmd); + /* Echo back. */ + pckbc_add_code(d, cmd, port_nr); + d->state = STATE_NORMAL; + return; + } + switch (cmd) { case 0x00: pckbc_add_code(d, KBR_ACK, port_nr); @@ -641,7 +664,7 @@ } } /* debug("[ pckbc: read from DATA: 0x%02x ]\n", - odata); */ + (int)odata); */ } else { debug("[ pckbc: write to DATA:"); for (i=0; ireg[relative_addr] = idata; switch (idata) { + case 0x10: + case 0x11: + /* TODO: For now, don't print warnings about + these. NetBSD sends these. */ + break; case K_RDCMDBYTE: d->state = STATE_RDCMDBYTE; break; @@ -708,6 +736,9 @@ case 0xaa: /* keyboard self-test */ pckbc_add_code(d, 0x55, port_nr); break; + case 0xab: /* keyboard interface self-test */ + pckbc_add_code(d, 0x00, port_nr); + break; case 0xad: d->cmdbyte |= KC8_KDISABLE; break; @@ -720,12 +751,18 @@ case 0xd1: d->state = STATE_LDOUTPUT; break; + case 0xd3: /* write to auxiliary device + output buffer */ + debug("[ pckbc: CONTROL 0xd3, TODO ]\n"); + d->state = STATE_WAITING_FOR_AUX_OUT; + break; case 0xd4: /* write to auxiliary port */ debug("[ pckbc: CONTROL 0xd4, TODO ]\n"); + d->state = STATE_WAITING_FOR_AUX; break; default: fatal("[ pckbc: unknown CONTROL 0x%x ]\n", - idata); + (int)idata); d->state = STATE_NORMAL; } } @@ -811,7 +848,7 @@ } } - /* SGI? */ + /* SGI? TODO: fix */ if (len == 8) odata |= (odata << 8) | (odata << 16) | (odata << 24) | (odata << 32) | (odata << 40) | (odata << 48) | @@ -858,13 +895,15 @@ d->mouse_irqnr = mouse_irqnr; d->in_use = in_use; d->pc_style_flag = pc_style_flag; - d->console_handle = console_start_slave_inputonly(machine, "pckbc"); - d->translation_table = 1; + if (d->in_use) + d->console_handle = + console_start_slave_inputonly(machine, "pckbc"); + d->translation_table = 2; d->rx_int_enable = 1; d->output_byte = 0x02; /* A20 enable on PCs */ memory_device_register(mem, "pckbc", baseaddr, - len, dev_pckbc_access, d, MEM_DEFAULT, NULL); + len, dev_pckbc_access, d, DM_DEFAULT, NULL); machine_add_tickfunction(machine, dev_pckbc_tick, d, PCKBC_TICKSHIFT); return d->console_handle;