diff --git a/src/keyboard_at.c b/src/keyboard_at.c index 391f725be..29baa0250 100644 --- a/src/keyboard_at.c +++ b/src/keyboard_at.c @@ -8,7 +8,7 @@ * * Intel 8042 (AT keyboard controller) emulation. * - * Version: @(#)keyboard_at.c 1.0.37 2018/05/25 + * Version: @(#)keyboard_at.c 1.0.36 2018/05/12 * * Authors: Sarah Walker, * Miran Grca, @@ -44,32 +44,30 @@ #include "sound/snd_speaker.h" #include "video/video.h" #include "keyboard.h" -#include "mouse.h" +#define STAT_PARITY 0x80 +#define STAT_RTIMEOUT 0x40 +#define STAT_TTIMEOUT 0x20 +#define STAT_MFULL 0x20 +#define STAT_LOCK 0x10 +#define STAT_CD 0x08 +#define STAT_SYSFLAG 0x04 +#define STAT_IFULL 0x02 +#define STAT_OFULL 0x01 -#define STAT_PARITY 0x80 -#define STAT_RTIMEOUT 0x40 -#define STAT_TTIMEOUT 0x20 -#define STAT_MFULL 0x20 -#define STAT_LOCK 0x10 -#define STAT_CD 0x08 -#define STAT_SYSFLAG 0x04 -#define STAT_IFULL 0x02 -#define STAT_OFULL 0x01 +#define PS2_REFRESH_TIME (16LL * TIMER_USEC) -#define PS2_REFRESH_TIME (16LL * TIMER_USEC) +#define CCB_UNUSED 0x80 +#define CCB_TRANSLATE 0x40 +#define CCB_PCMODE 0x20 +#define CCB_ENABLEKBD 0x10 +#define CCB_IGNORELOCK 0x08 +#define CCB_SYSTEM 0x04 +#define CCB_ENABLEMINT 0x02 +#define CCB_ENABLEKINT 0x01 -#define CCB_UNUSED 0x80 -#define CCB_TRANSLATE 0x40 -#define CCB_PCMODE 0x20 -#define CCB_ENABLEKBD 0x10 -#define CCB_IGNORELOCK 0x08 -#define CCB_SYSTEM 0x04 -#define CCB_ENABLEMINT 0x02 -#define CCB_ENABLEKINT 0x01 - -#define CCB_MASK 0x68 -#define MODE_MASK 0x6C +#define CCB_MASK 0x68 +#define MODE_MASK 0x6c #define KBC_TYPE_ISA 0x00 #define KBC_TYPE_PS2_1 0x01 @@ -79,9 +77,10 @@ #define KBC_VEN_GENERIC 0x00 #define KBC_VEN_AMI 0x04 #define KBC_VEN_IBM_MCA 0x08 -#define KBC_VEN_QUADTEL 0x0C +#define KBC_VEN_QUADTEL 0x0c #define KBC_VEN_TOSHIBA 0x10 -#define KBC_VEN_MASK 0x1C +#define KBC_VEN_MASK 0x1c + typedef struct { int initialized; @@ -122,25 +121,19 @@ typedef struct { uint8_t (*write60_ven)(void *p, uint8_t val); uint8_t (*write64_ven)(void *p, uint8_t val); - - int64_t timeout; } atkbd_t; /* bit 0 = repeat, bit 1 = makes break code? */ -uint8_t keyboard_set3_flags[512]; -uint8_t keyboard_set3_all_repeat; -uint8_t keyboard_set3_all_break; +uint8_t keyboard_set3_flags[512]; +uint8_t keyboard_set3_all_repeat; +uint8_t keyboard_set3_all_break; /* Bits 0 - 1 = scan code set, bit 6 = translate or not. */ -uint8_t keyboard_mode = 0x42; +uint8_t keyboard_mode = 0x42; -#ifdef ENABLE_KEYBOARD_AT_LOG -int keyboard_at_do_log = ENABLE_KEYBOARD_AT_LOG; -#endif - -int mouse_queue_start = 0, - mouse_queue_end = 0; +int mouse_queue_start = 0, + mouse_queue_end = 0; static uint8_t key_ctrl_queue[16]; @@ -158,38 +151,38 @@ static atkbd_t *CurrentKbd = NULL; // FIXME: remove!!! --FvK /* Non-translated to translated scan codes. */ static const uint8_t nont_to_t[256] = { - 0xFF, 0x43, 0x41, 0x3F, 0x3D, 0x3B, 0x3C, 0x58, - 0x64, 0x44, 0x42, 0x40, 0x3E, 0x0F, 0x29, 0x59, - 0x65, 0x38, 0x2A, 0x70, 0x1D, 0x10, 0x02, 0x5A, - 0x66, 0x71, 0x2C, 0x1F, 0x1E, 0x11, 0x03, 0x5B, - 0x67, 0x2E, 0x2D, 0x20, 0x12, 0x05, 0x04, 0x5C, - 0x68, 0x39, 0x2F, 0x21, 0x14, 0x13, 0x06, 0x5D, - 0x69, 0x31, 0x30, 0x23, 0x22, 0x15, 0x07, 0x5E, - 0x6A, 0x72, 0x32, 0x24, 0x16, 0x08, 0x09, 0x5F, - 0x6B, 0x33, 0x25, 0x17, 0x18, 0x0B, 0x0A, 0x60, - 0x6C, 0x34, 0x35, 0x26, 0x27, 0x19, 0x0C, 0x61, - 0x6D, 0x73, 0x28, 0x74, 0x1A, 0x0D, 0x62, 0x6E, - 0x3A, 0x36, 0x1C, 0x1B, 0x75, 0x2B, 0x63, 0x76, - 0x55, 0x56, 0x77, 0x78, 0x79, 0x7A, 0x0E, 0x7B, - 0x7C, 0x4F, 0x7D, 0x4B, 0x47, 0x7E, 0x7F, 0x6F, - 0x52, 0x53, 0x50, 0x4C, 0x4D, 0x48, 0x01, 0x45, - 0x57, 0x4E, 0x51, 0x4A, 0x37, 0x49, 0x46, 0x54, + 0xff, 0x43, 0x41, 0x3f, 0x3d, 0x3b, 0x3c, 0x58, + 0x64, 0x44, 0x42, 0x40, 0x3e, 0x0f, 0x29, 0x59, + 0x65, 0x38, 0x2a, 0x70, 0x1d, 0x10, 0x02, 0x5a, + 0x66, 0x71, 0x2c, 0x1f, 0x1e, 0x11, 0x03, 0x5b, + 0x67, 0x2e, 0x2d, 0x20, 0x12, 0x05, 0x04, 0x5c, + 0x68, 0x39, 0x2f, 0x21, 0x14, 0x13, 0x06, 0x5d, + 0x69, 0x31, 0x30, 0x23, 0x22, 0x15, 0x07, 0x5e, + 0x6a, 0x72, 0x32, 0x24, 0x16, 0x08, 0x09, 0x5f, + 0x6b, 0x33, 0x25, 0x17, 0x18, 0x0b, 0x0a, 0x60, + 0x6c, 0x34, 0x35, 0x26, 0x27, 0x19, 0x0c, 0x61, + 0x6d, 0x73, 0x28, 0x74, 0x1a, 0x0d, 0x62, 0x6e, + 0x3a, 0x36, 0x1c, 0x1b, 0x75, 0x2b, 0x63, 0x76, + 0x55, 0x56, 0x77, 0x78, 0x79, 0x7a, 0x0e, 0x7b, + 0x7c, 0x4f, 0x7d, 0x4b, 0x47, 0x7e, 0x7f, 0x6f, + 0x52, 0x53, 0x50, 0x4c, 0x4d, 0x48, 0x01, 0x45, + 0x57, 0x4e, 0x51, 0x4a, 0x37, 0x49, 0x46, 0x54, 0x80, 0x81, 0x82, 0x41, 0x54, 0x85, 0x86, 0x87, - 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, - 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, - 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, - 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, - 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, - 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, - 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, - 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, - 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, - 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, - 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, - 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, - 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, - 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff }; static const scancode scancode_set1[512] = { @@ -582,9 +575,8 @@ static const scancode scancode_set3[512] = { { { -1},{ -1} }, { { -1},{ -1} }, { {0xe0,0xfe,-1},{0xe0,0xF0,0xFE,-1} }, { {0xe0,0xff,-1},{0xe0,0xF0,0xFF,-1} } /*1fc*/ }; - static void -kbdlog(const char *fmt, ...) +kbd_log(const char *fmt, ...) { #ifdef ENABLE_KEYBOARD_AT_LOG va_list ap; @@ -597,7 +589,6 @@ kbdlog(const char *fmt, ...) #endif } - static void kbd_setmap(atkbd_t *kbd) { @@ -631,7 +622,9 @@ kbd_poll(void *priv) if ((kbd->out_new != -1) && !kbd->last_irq) { kbd->wantirq = 0; if (kbd->out_new & 0x100) { - kbdlog("ATkbd: want mouse data\n"); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: want mouse data\n"); +#endif if (kbd->mem[0] & 0x02) picint(0x1000); kbd->out = kbd->out_new & 0xff; @@ -641,7 +634,9 @@ kbd_poll(void *priv) kbd->status |= STAT_MFULL; kbd->last_irq = 0x1000; } else { - kbdlog("ATkbd: want keyboard data\n"); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: want keyboard data\n"); +#endif if (kbd->mem[0] & 0x01) picint(2); kbd->out = kbd->out_new & 0xff; @@ -653,16 +648,13 @@ kbd_poll(void *priv) } } - if (kbd->out_new == -1 && !(kbd->status & STAT_OFULL) && - key_ctrl_queue_start != key_ctrl_queue_end) { + if (kbd->out_new == -1 && !(kbd->status & STAT_OFULL) && key_ctrl_queue_start != key_ctrl_queue_end) { kbd->out_new = key_ctrl_queue[key_ctrl_queue_start] | 0x200; key_ctrl_queue_start = (key_ctrl_queue_start + 1) & 0xf; - } else if (!(kbd->status & STAT_OFULL) && kbd->out_new == -1 && - kbd->out_delayed != -1) { + } else if (!(kbd->status & STAT_OFULL) && kbd->out_new == -1 && kbd->out_delayed != -1) { kbd->out_new = kbd->out_delayed; kbd->out_delayed = -1; - } else if (!(kbd->status & STAT_OFULL) && kbd->out_new == -1 && - !(kbd->mem[0] & 0x10) && kbd->out_delayed != -1) { + } else if (!(kbd->status & STAT_OFULL) && kbd->out_new == -1 && !(kbd->mem[0] & 0x10) && kbd->out_delayed != -1) { kbd->out_new = kbd->out_delayed; kbd->out_delayed = -1; } else if (!(kbd->status & STAT_OFULL) && kbd->out_new == -1/* && !(kbd->mem[0] & 0x20)*/ && @@ -709,21 +701,26 @@ kbd_adddata_vals(uint8_t *val, uint8_t len) or = 0; } else send = val[i]; - kbdlog("%02X", send); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("%02X", send); +#endif kbd_adddata(send); - if (i < (len - 1)) kbdlog(" "); +#ifdef ENABLE_KEYBOARD_LOG + if (i < (len - 1)) kbd_log(" "); +#endif } +#ifdef ENABLE_KEYBOARD_LOG if (translate) { - kbdlog(" original: ("); + kbd_log(" original: ("); for (i = 0; i < len; i++) { - kbdlog("%02X", val[i]); - if (i < (len - 1)) kbdlog(" "); + kbd_log("%02X", val[i]); + if (i < (len - 1)) kbd_log(" "); } - kbdlog(")"); + kbd_log(")"); } - - kbdlog("\n"); + kbd_log("\n"); +#endif } @@ -740,23 +737,25 @@ kbd_adddata_keyboard(uint16_t val) /* Allow for scan code translation. */ if (translate && (val == 0xf0)) { - kbdlog("Translate is on, F0 prefix detected\n"); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: translate is on, F0 prefix detected\n"); +#endif sc_or = 0x80; return; } /* Skip break code if translated make code has bit 7 set. */ if (translate && (sc_or == 0x80) && (val & 0x80)) { - kbdlog("Translate is on, skipping scan code: %02X (original: F0 %02X)\n", nont_to_t[val], val); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: translate is on, skipping scan code: %02X (original: F0 %02X)\n", nont_to_t[val], val); +#endif sc_or = 0; return; } /* Test for T3100E 'Fn' key (Right Alt / Right Ctrl) */ - if (romset == ROM_T3100E && (keyboard_recv(0xb8) || keyboard_recv(0x9d))) - { - switch (val) - { + if (romset == ROM_T3100E && (keyboard_recv(0xb8) || keyboard_recv(0x9d))) { + switch (val) { case 0x4f: t3100e_notify_set(0x01); break; /* End */ case 0x50: t3100e_notify_set(0x02); break; /* Down */ case 0x51: t3100e_notify_set(0x03); break; /* PgDn */ @@ -775,13 +774,19 @@ kbd_adddata_keyboard(uint16_t val) } } - kbdlog("Translate is %s, ", translate ? "on" : "off"); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: translate is %s, ", translate ? "on" : "off"); +#endif switch(val) { case FAKE_LSHIFT_ON: - kbdlog("fake left shift on, scan code: "); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("fake left shift on, scan code: "); +#endif if (num_lock) { if (shift_states) { - kbdlog("N/A (one or both shifts on)\n"); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("N/A (one or both shifts on)\n"); +#endif break; } else { /* Num lock on and no shifts are pressed, send non-inverted fake shift. */ @@ -795,7 +800,9 @@ kbd_adddata_keyboard(uint16_t val) kbd_adddata_vals(fake_shift, 2); break; default: - kbdlog("N/A (scan code set %i)\n", keyboard_mode & 0x02); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("N/A (scan code set %i)\n", keyboard_mode & 0x02); +#endif break; } } @@ -812,7 +819,9 @@ kbd_adddata_keyboard(uint16_t val) kbd_adddata_vals(fake_shift, 3); break; default: - kbdlog("N/A (scan code set %i)\n", keyboard_mode & 0x02); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("N/A (scan code set %i)\n", keyboard_mode & 0x02); +#endif break; } } @@ -828,19 +837,27 @@ kbd_adddata_keyboard(uint16_t val) kbd_adddata_vals(fake_shift, 3); break; default: - kbdlog("N/A (scan code set %i)\n", keyboard_mode & 0x02); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("N/A (scan code set %i)\n", keyboard_mode & 0x02); +#endif break; } } +#ifdef ENABLE_KEYBOARD_LOG if (!shift_states) - kbdlog("N/A (both shifts off)\n"); + kbd_log("N/A (both shifts off)\n"); +#endif } break; case FAKE_LSHIFT_OFF: - kbdlog("fake left shift on, scan code: "); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("fake left shift on, scan code: "); +#endif if (num_lock) { if (shift_states) { - kbdlog("N/A (one or both shifts on)\n"); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("N/A (one or both shifts on)\n"); +#endif break; } else { /* Num lock on and no shifts are pressed, send non-inverted fake shift. */ @@ -854,7 +871,9 @@ kbd_adddata_keyboard(uint16_t val) kbd_adddata_vals(fake_shift, 3); break; default: - kbdlog("N/A (scan code set %i)\n", keyboard_mode & 0x02); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("N/A (scan code set %i)\n", keyboard_mode & 0x02); +#endif break; } } @@ -871,7 +890,9 @@ kbd_adddata_keyboard(uint16_t val) kbd_adddata_vals(fake_shift, 2); break; default: - kbdlog("N/A (scan code set %i)\n", keyboard_mode & 0x02); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("N/A (scan code set %i)\n", keyboard_mode & 0x02); +#endif break; } } @@ -887,23 +908,29 @@ kbd_adddata_keyboard(uint16_t val) kbd_adddata_vals(fake_shift, 2); break; default: - kbdlog("N/A (scan code set %i)\n", keyboard_mode & 0x02); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("N/A (scan code set %i)\n", keyboard_mode & 0x02); +#endif break; } } +#ifdef ENABLE_KEYBOARD_LOG if (!shift_states) - kbdlog("N/A (both shifts off)\n"); + kbd_log("N/A (both shifts off)\n"); +#endif } break; default: - kbdlog("scan code: "); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("scan code: "); if (translate) { - kbdlog("%02X (original: ", (nont_to_t[val] | sc_or)); + kbd_log("%02X (original: ", (nont_to_t[val] | sc_or)); if (sc_or == 0x80) - kbdlog("F0 "); - kbdlog("%02X)\n", val); + kbd_log("F0 "); + kbd_log("%02X)\n", val); } else - kbdlog("%02X\n", val); + kbd_log("%02X\n", val); +#endif key_queue[key_queue_end] = (translate ? (nont_to_t[val] | sc_or) : val); key_queue_end = (key_queue_end + 1) & 0xf; @@ -917,7 +944,9 @@ kbd_adddata_keyboard(uint16_t val) static void kbd_output_write(atkbd_t *kbd, uint8_t val) { - kbdlog("Write output port: %02X (old: %02X)\n", val, kbd->output_port); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: write output port: %02X (old: %02X)\n", val, kbd->output_port); +#endif if ((kbd->output_port ^ val) & 0x20) { /*IRQ 12*/ if (val & 0x20) picint(1 << 12); @@ -949,7 +978,9 @@ kbd_output_write(atkbd_t *kbd, uint8_t val) static void kbd_cmd_write(atkbd_t *kbd, uint8_t val) { - kbdlog("Write command byte: %02X (old: %02X)\n", val, kbd->mem[0]); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: write command byte: %02X (old: %02X)\n", val, kbd->mem[0]); +#endif if ((val & 1) && (kbd->status & STAT_OFULL)) kbd->wantirq = 1; @@ -967,18 +998,23 @@ kbd_cmd_write(atkbd_t *kbd, uint8_t val) keyboard_mode |= (val & MODE_MASK); keyboard_scan = !(val & 0x10); - kbdlog("ATkbd: keyboard is now %s\n", mouse_scan ? "enabled" : "disabled"); - kbdlog("ATkbd: keyboard interrupt is now %s\n", (val & 0x01) ? "enabled" : "disabled"); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: keyboard is now %s\n", keyboard_scan ? "enabled" : "disabled"); + kbd_log("ATkbd: keyboard interrupt is now %s\n", (val & 0x01) ? "enabled" : "disabled"); +#endif /* ISA AT keyboard controllers use bit 5 for keyboard mode (1 = PC/XT, 2 = AT); PS/2 (and EISA/PCI) keyboard controllers use it as the PS/2 mouse enable switch. */ - if (((kbd->flags & KBC_VEN_MASK) == KBC_VEN_AMI) || ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1)) { + if (((kbd->flags & KBC_VEN_MASK) == KBC_VEN_AMI) || + ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1)) { keyboard_mode &= ~CCB_PCMODE; mouse_scan = !(val & 0x20); - kbdlog("ATkbd: mouse is now %s\n", mouse_scan ? "enabled" : "disabled"); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: mouse is now %s\n", mouse_scan ? "enabled" : "disabled"); - kbdlog("ATkbd: mouse interrupt is now %s\n", (val & 0x02) ? "enabled" : "disabled"); + kbd_log("ATkbd: mouse interrupt is now %s\n", (val & 0x02) ? "enabled" : "disabled"); +#endif } } @@ -1004,110 +1040,138 @@ kbd_pulse_poll(void *p) } -static void -kbd_timeout_poll(void *p) -{ - atkbd_t *kbd = (atkbd_t *) p; - - kbd->key_wantdata = 0; - kbd->want60 = 0; - if (mouse_p) - mouse_clear_data(mouse_p); - - kbd->timeout = 0LL; -} - - static void kbd_keyboard_set(atkbd_t *kbd, uint8_t enable) { - kbd->mem[0] &= 0xef; - kbd->mem[0] |= (enable ? 0x00 : 0x10); - keyboard_scan = enable; + kbd->mem[0] &= 0xef; + kbd->mem[0] |= (enable ? 0x00 : 0x10); + + if (enable) + kbd->status |= STAT_LOCK; + else + kbd->status &= ~STAT_LOCK; + + keyboard_scan = enable; } static void kbd_mouse_set(atkbd_t *kbd, uint8_t enable) { - kbd->mem[0] &= 0xdf; - kbd->mem[0] |= (enable ? 0x00 : 0x20); - mouse_scan = enable; + kbd->mem[0] &= 0xdf; + kbd->mem[0] |= (enable ? 0x00 : 0x20); + mouse_scan = enable; } static uint8_t kbd_write64_generic(void *p, uint8_t val) { - atkbd_t *kbd = (atkbd_t *) p; + atkbd_t *kbd = (atkbd_t *)p; switch (val) { - case 0xa4: /*Check if password installed*/ + case 0xa4: /*Check if password installed*/ if ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) { - kbdlog("ATkbd: check if password installed\n"); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: check if password installed\n"); +#endif kbd_adddata(0xf1); return 0; - } else - kbdlog("ATkbd: bad command A4\n"); + } +#ifdef ENABLE_KEYBOARD_LOG + else + kbd_log("ATkbd: bad command A4\n"); +#endif break; - case 0xa7: /*Disable mouse port*/ + + case 0xa7: /*Disable mouse port*/ if ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) { - kbdlog("ATkbd: disable mouse port\n"); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: disable mouse port\n"); +#endif kbd_mouse_set(kbd, 0); return 0; - } else - kbdlog("ATkbd: bad command A7\n"); + } +#ifdef ENABLE_KEYBOARD_LOG + else + kbd_log("ATkbd: bad command A7\n"); +#endif break; - case 0xa8: /*Enable mouse port*/ + + case 0xa8: /*Enable mouse port*/ if ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) { - kbdlog("ATkbd: enable mouse port\n"); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: enable mouse port\n"); +#endif kbd_mouse_set(kbd, 1); return 0; - } else - kbdlog("ATkbd: bad command A8\n"); + } +#ifdef ENABLE_KEYBOARD_LOG + else + kbd_log("ATkbd: bad command A8\n"); +#endif break; - case 0xa9: /*Test mouse port*/ - kbdlog("ATkbd: test mouse port\n"); + + case 0xa9: /*Test mouse port*/ +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: test mouse port\n"); +#endif if ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) { if (mouse_write) kbd_adddata(0x00); /*no error*/ else kbd_adddata(0xff); /*no mouse*/ return 0; - } else - kbdlog("ATkbd: bad command A9\n"); + } +#ifdef ENABLE_KEYBOARD_LOG + else + kbd_log("ATkbd: bad command A9\n"); +#endif break; - case 0xaf: /*Read keyboard version*/ - kbdlog("ATkbd: read keyboard version\n"); + + case 0xaf: /*Read keyboard version*/ +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: read keyboard version\n"); +#endif kbd_adddata(0x00); return 0; - case 0xc0: /*Read input port*/ - kbdlog("ATkbd: read input port\n"); + + case 0xc0: /*Read input port*/ +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: read input port\n"); +#endif kbd_adddata(kbd->input_port | 4 | fdc_ps1_525()); kbd->input_port = ((kbd->input_port + 1) & 3) | (kbd->input_port & 0xfc) | fdc_ps1_525(); return 0; - case 0xd3: /*Write mouse output buffer*/ + + case 0xd3: /*Write mouse output buffer*/ if ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) { - kbdlog("ATkbd: write mouse output buffer\n"); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: write mouse output buffer\n"); +#endif kbd->want60 = 1; - kbd->timeout = 25000LL * TIMER_USEC; return 0; } break; - case 0xd4: /*Write to mouse*/ + + case 0xd4: /*Write to mouse*/ if ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) { - kbdlog("ATkbd: write to mouse\n"); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: write to mouse\n"); +#endif kbd->want60 = 1; - kbd->timeout = 25000LL * TIMER_USEC; return 0; } break; + case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: case 0xf7: case 0xf8: case 0xf9: case 0xfa: case 0xfb: case 0xfc: case 0xfd: case 0xfe: case 0xff: - // kbdlog("ATkbd: pulse %01X\n", val & 0x0f); +#ifdef ENABLE_KEYBOARD_LOG + // kbd_log("ATkbd: pulse %01X\n", val & 0x0f); +#endif kbd_output_pulse(kbd, val & 0x0f); return 0; } @@ -1131,25 +1195,32 @@ kbd_write60_ami(void *p, uint8_t val) case 0x54: case 0x55: case 0x56: case 0x57: case 0x58: case 0x59: case 0x5a: case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f: - kbdlog("AMI - alias write to register %08X\n", kbd->command); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: AMI - alias write to %08X\n", kbd->command); +#endif kbd->mem[kbd->command & 0x1f] = val; if (kbd->command == 0x60) kbd_cmd_write(kbd, val); return 0; - case 0xaf: /*AMI - set extended controller RAM*/ - kbdlog("AMI - set extended controller RAM\n"); + + case 0xaf: /*AMI - set extended controller RAM*/ +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: AMI - set extended controller RAM\n"); +#endif if (kbd->secr_phase == 1) { kbd->mem_addr = val; kbd->want60 = 1; - kbd->timeout = 25000LL * TIMER_USEC; kbd->secr_phase = 2; } else if (kbd->secr_phase == 2) { kbd->mem[kbd->mem_addr] = val; kbd->secr_phase = 0; } return 0; - case 0xcb: /*AMI - set keyboard mode*/ - kbdlog("AMI - set keyboard mode\n"); + + case 0xcb: /*AMI - set keyboard mode*/ +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: AMI - set keyboard mode\n"); +#endif return 0; } @@ -1171,9 +1242,12 @@ kbd_write64_ami(void *p, uint8_t val) case 0x14: case 0x15: case 0x16: case 0x17: case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f: - kbdlog("AMI - alias read from register %08X\n", val); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: AMI - alias read from %08X\n", val); +#endif kbd_adddata(kbd->mem[val]); return 0; + case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47: case 0x48: case 0x49: case 0x4a: case 0x4b: @@ -1182,125 +1256,172 @@ kbd_write64_ami(void *p, uint8_t val) case 0x54: case 0x55: case 0x56: case 0x57: case 0x58: case 0x59: case 0x5a: case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f: - kbdlog("AMI - alias write to register %08X\n", kbd->command); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: AMI - alias write to %08X\n", kbd->command); +#endif kbd->want60 = 1; - kbd->timeout = 25000LL * TIMER_USEC; return 0; - case 0xa1: /*AMI - get controller version*/ - kbdlog("AMI - get controller version\n"); + + case 0xa1: /*AMI - get controller version*/ +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: AMI - get controller version\n"); +#endif return 0; + case 0xa2: /*AMI - reset keyboard controller lines P22 and P23 low*/ if ((kbd->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_1) { - kbdlog("AMI - reset keyboard controller lines P22 and P23 low\n"); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: AMI - clear KBC lines P22 and P23\n"); +#endif kbd_output_write(kbd, kbd->output_port & 0xf3); kbd_adddata(0x00); return 0; } break; + case 0xa3: /*AMI - set keyboard controller lines P22 and P23 high*/ if ((kbd->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_1) { - kbdlog("AMI - set keyboard controller lines P22 and P23 high\n"); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: AMI - set KBC lines P22 and P23\n"); +#endif kbd_output_write(kbd, kbd->output_port | 0x0c); kbd_adddata(0x00); return 0; } break; - case 0xa4: /* AMI - write clock = low */ + + case 0xa4: /* AMI - write clock = low */ if ((kbd->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_1) { - kbdlog("AMI - write clock = low\n"); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: AMI - write clock = low\n"); +#endif kbd->ami_stat &= 0xfe; return 0; } break; - case 0xa5: /* AMI - write clock = high */ + + case 0xa5: /* AMI - write clock = high */ if ((kbd->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_1) { - kbdlog("AMI - write clock = high\n"); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: AMI - write clock = high\n"); +#endif kbd->ami_stat |= 0x01; return 0; } break; - case 0xa6: /* AMI - read clock */ + + case 0xa6: /* AMI - read clock */ if ((kbd->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_1) { - kbdlog("AMI - read clock\n"); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: AMI - read clock\n"); +#endif kbd_adddata(!!(kbd->ami_stat & 1)); return 0; } break; - case 0xa7: /* AMI - write cache bad */ + + case 0xa7: /* AMI - write cache bad */ if ((kbd->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_1) { - kbdlog("AMI - write cache bad\n"); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: AMI - write cache bad\n"); +#endif kbd->ami_stat &= 0xfd; return 0; } break; - case 0xa8: /* AMI - write cache good */ + + case 0xa8: /* AMI - write cache good */ if ((kbd->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_1) { - kbdlog("AMI - write cache good\n"); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: AMI - write cache good\n"); +#endif kbd->ami_stat |= 0x02; return 0; } break; - case 0xa9: /* AMI - read cache */ + + case 0xa9: /* AMI - read cache */ if ((kbd->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_1) { - kbdlog("AMI - read cache\n"); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: AMI - read cache\n"); +#endif kbd_adddata(!!(kbd->ami_stat & 2)); return 0; } break; - case 0xaf: /*Set extended controller RAM*/ - kbdlog("ATkbd: set extended controller RAM\n"); + + case 0xaf: /*Set extended controller RAM*/ +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: set extended controller RAM\n"); +#endif kbd->want60 = 1; - kbd->timeout = 25000LL * TIMER_USEC; kbd->secr_phase = 1; return 0; + case 0xb0: case 0xb1: case 0xb2: case 0xb3: /*Set keyboard controller line P10-P13 (input port bits 0-3) low*/ if (!PCI || (val > 0xb1)) kbd->input_port &= ~(1 << (val & 0x03)); kbd_adddata(0x00); return 0; + case 0xb4: case 0xb5: /*Set keyboard controller line P22-P23 (output port bits 2-3) low*/ if (!PCI) kbd_output_write(kbd, kbd->output_port & ~(4 << (val & 0x01))); kbd_adddata(0x00); return 0; + case 0xb8: case 0xb9: case 0xba: case 0xbb: /*Set keyboard controller line P10-P13 (input port bits 0-3) high*/ - if (!PCI || (val > 0xb9)) { + if (!PCI || (val > 0xb9)) kbd->input_port |= (1 << (val & 0x03)); - kbd_adddata(0x00); - } + kbd_adddata(0x00); return 0; + case 0xbc: case 0xbd: /*Set keyboard controller line P22-P23 (output port bits 2-3) high*/ if (!PCI) kbd_output_write(kbd, kbd->output_port | (4 << (val & 0x01))); kbd_adddata(0x00); return 0; + case 0xc8: /*AMI - unblock keyboard controller lines P22 and P23 (allow command D1 to change bits 2 and 3 of the output port)*/ - kbdlog("AMI - unblock keyboard controller lines P22 and P23\n"); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: AMI - unblock KBC lines P22 and P23\n"); +#endif kbd->output_locked = 1; return 0; + case 0xc9: /*AMI - block keyboard controller lines P22 and P23 (prevent command D1 from changing bits 2 and 3 of the output port)*/ - kbdlog("AMI - block keyboard controller lines P22 and P23\n"); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: AMI - block KBC lines P22 and P23\n"); +#endif kbd->output_locked = 1; return 0; - case 0xca: /*AMI - read keyboard mode*/ - kbdlog("AMI - read keyboard mode\n"); + + case 0xca: /*AMI - read keyboard mode*/ +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: AMI - read keyboard mode\n"); +#endif kbd_adddata(0x00); /*ISA mode*/ return 0; - case 0xcb: /*AMI - set keyboard mode*/ - kbdlog("AMI - set keyboard mode\n"); + + case 0xcb: /*AMI - set keyboard mode*/ +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: AMI - set keyboard mode\n"); +#endif kbd->want60 = 1; - kbd->timeout = 25000LL * TIMER_USEC; return 0; - case 0xef: /*??? - sent by AMI486*/ - kbdlog("??? - sent by AMI486\n"); + + case 0xef: /*??? - sent by AMI486*/ +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: ??? - sent by AMI486\n"); +#endif return 0; } @@ -1315,23 +1436,34 @@ kbd_write64_ibm_mca(void *p, uint8_t val) switch (val) { case 0xc1: /*Copy bits 0 to 3 of input port to status bits 4 to 7*/ - kbdlog("ATkbd: copy bits 0 to 3 of input port to status bits 4 to 7\n"); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: copy bits 0 to 3 of input port to status bits 4 to 7\n"); +#endif kbd->status &= 0xf; kbd->status |= ((((kbd->input_port & 0xfc) | 0x84 | fdc_ps1_525()) & 0xf) << 4); return 0; + case 0xc2: /*Copy bits 4 to 7 of input port to status bits 4 to 7*/ - kbdlog("ATkbd: copy bits 4 to 7 of input port to status bits 4 to 7\n"); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: copy bits 4 to 7 of input port to status bits 4 to 7\n"); +#endif kbd->status &= 0xf; kbd->status |= (((kbd->input_port & 0xfc) | 0x84 | fdc_ps1_525()) & 0xf0); return 0; + case 0xaf: - kbdlog("ATkbd: bad kbc command AF\n"); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: bad KBC command AF\n"); +#endif return 1; + case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: case 0xf7: case 0xf8: case 0xf9: case 0xfa: case 0xfb: case 0xfc: case 0xfd: case 0xfe: case 0xff: - kbdlog("ATkbd: pulse: %01X\n", (val & 0x03) | 0x0c); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: pulse: %01X\n", (val & 0x03) | 0x0c); +#endif kbd_output_pulse(kbd, (val & 0x03) | 0x0c); return 0; } @@ -1346,8 +1478,10 @@ kbd_write60_quadtel(void *p, uint8_t val) atkbd_t *kbd = (atkbd_t *) p; switch(kbd->command) { - case 0xcf: /*??? - sent by MegaPC BIOS*/ - kbdlog("??? - sent by MegaPC BIOS\n"); + case 0xcf: /*??? - sent by MegaPC BIOS*/ +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: ??? - sent by MegaPC BIOS\n"); +#endif return 0; } @@ -1362,12 +1496,16 @@ kbd_write64_quadtel(void *p, uint8_t val) switch (val) { case 0xaf: - kbdlog("ATkbd: bad kbc command AF\n"); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: bad KBC command AF\n"); +#endif return 1; - case 0xcf: /*??? - sent by MegaPC BIOS*/ - kbdlog("??? - sent by MegaPC BIOS\n"); + + case 0xcf: /*??? - sent by MegaPC BIOS*/ +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: ??? - sent by MegaPC BIOS\n"); +#endif kbd->want60 = 1; - kbd->timeout = 25000LL * TIMER_USEC; return 0; } @@ -1381,7 +1519,7 @@ kbd_write60_toshiba(void *p, uint8_t val) atkbd_t *kbd = (atkbd_t *) p; switch(kbd->command) { - case 0xb6: /* T3100e - set colour/mono switch */ + case 0xb6: /* T3100e - set color/mono switch */ t3100e_mono_set(val); return 0; } @@ -1397,51 +1535,65 @@ kbd_write64_toshiba(void *p, uint8_t val) switch (val) { case 0xaf: - kbdlog("ATkbd: bad kbc command AF\n"); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: bad KBC command AF\n"); +#endif return 1; - case 0xb0: /* T3100e: Turbo on */ + + case 0xb0: /* T3100e: Turbo on */ t3100e_turbo_set(1); return 0; - case 0xb1: /* T3100e: Turbo off */ + + case 0xb1: /* T3100e: Turbo off */ t3100e_turbo_set(0); return 0; - case 0xb2: /* T3100e: Select external display */ + + case 0xb2: /* T3100e: Select external display */ t3100e_display_set(0x00); return 0; - case 0xb3: /* T3100e: Select internal display */ + + case 0xb3: /* T3100e: Select internal display */ t3100e_display_set(0x01); return 0; - case 0xb4: /* T3100e: Get configuration / status */ + + case 0xb4: /* T3100e: Get configuration / status */ kbd_adddata(t3100e_config_get()); return 0; - case 0xb5: /* T3100e: Get colour / mono byte */ + + case 0xb5: /* T3100e: Get colour / mono byte */ kbd_adddata(t3100e_mono_get()); return 0; - case 0xb6: /* T3100e: Set colour / mono byte */ + + case 0xb6: /* T3100e: Set colour / mono byte */ kbd->want60 = 1; - kbd->timeout = 25000LL * TIMER_USEC; return 0; - case 0xb7: /* T3100e: Emulate PS/2 keyboard - not implemented */ - case 0xb8: /* T3100e: Emulate AT keyboard - not implemented */ + + case 0xb7: /* T3100e: Emulate PS/2 keyboard - not implemented */ + case 0xb8: /* T3100e: Emulate AT keyboard - not implemented */ return 0; - case 0xbb: /* T3100e: Read 'Fn' key. - Return it for right Ctrl and right Alt; on the real - T3100e, these keystrokes could only be generated - using 'Fn'. */ + + case 0xbb: /* T3100e: Read 'Fn' key. + Return it for right Ctrl and right Alt; on the real + T3100e, these keystrokes could only be generated + using 'Fn'. */ if (keyboard_recv(0xb8) || /* Right Alt */ keyboard_recv(0x9d)) /* Right Ctrl */ kbd_adddata(0x04); else kbd_adddata(0x00); return 0; - case 0xbc: /* T3100e: Reset Fn+Key notification */ + + case 0xbc: /* T3100e: Reset Fn+Key notification */ t3100e_notify_set(0x00); return 0; - case 0xc0: /*Read input port*/ - kbdlog("ATkbd: read input port\n"); + + case 0xc0: /*Read input port*/ +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: read input port\n"); +#endif /* The T3100e returns all bits set except bit 6 which * is set by t3100e_mono_set() */ - kbd->input_port = (t3100e_mono_get() & 1) ? 0xFF : 0xBF; + kbd->input_port = (t3100e_mono_get() & 1) ? 0xff : 0xbf; kbd_adddata(kbd->input_port); return 0; @@ -1462,6 +1614,9 @@ kbd_write(uint16_t port, uint8_t val, void *priv) if (romset == ROM_XI8088 && port == 0x63) port = 0x61; +#ifdef _DEBUG + kbd_log("ATkbd: write(%04X, %02X)\n", port, val); +#endif switch (port) { case 0x60: if (kbd->want60) { @@ -1482,7 +1637,9 @@ kbd_write(uint16_t port, uint8_t val, void *priv) break; case 0xd1: /*Write output port*/ - // kbdlog("Write output port\n"); +#ifdef ENABLE_KEYBOARD_LOG + // kbd_log("ATkbd: write output port\n"); +#endif if (kbd->output_locked) { /*If keyboard controller lines P22-P23 are blocked, we force them to remain unchanged.*/ @@ -1493,23 +1650,33 @@ kbd_write(uint16_t port, uint8_t val, void *priv) break; case 0xd2: /*Write to keyboard output buffer*/ - kbdlog("ATkbd: write to keyboard output buffer\n"); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: write to keyboard output buffer\n"); +#endif kbd_adddata_keyboard(val); break; case 0xd3: /*Write to mouse output buffer*/ - kbdlog("ATkbd: write to mouse output buffer\n"); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: write to mouse output buffer\n"); +#endif if (mouse_write && ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1)) keyboard_at_adddata_mouse(val); break; case 0xd4: /*Write to mouse*/ - kbdlog("ATkbd: write to mouse (%02X)\n", val); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: write to mouse (%02X)\n", val); +#endif kbd_mouse_set(kbd, 1); if (mouse_write && ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1)) mouse_write(val, mouse_p); - else if (!mouse_write && ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1)) + else if (!mouse_write && ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1)) { +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: adding 0xFF to queue\n"); +#endif keyboard_at_adddata_mouse(0xff); + } break; default: @@ -1518,8 +1685,12 @@ kbd_write(uint16_t port, uint8_t val, void *priv) if (kbd->write60_ven) bad = kbd->write60_ven(kbd, val); +#ifdef ENABLE_KEYBOARD_LOG if (bad) - kbdlog("ATkbd: bad keyboard controller 0060 write %02X command %02X\n", val, kbd->command); + kbd_log("ATkbd: bad keyboard controller 0060 write %02X command %02X\n", val, kbd->command); +#else + (void)bad; +#endif } } else { /*Write to keyboard*/ @@ -1549,119 +1720,166 @@ kbd_write(uint16_t port, uint8_t val, void *priv) break; default: - kbdlog("ATkbd: bad keyboard 0060 write %02X command %02X\n", val, kbd->key_command); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: bad keyboard 0060 write %02X command %02X\n", val, kbd->key_command); +#endif + break; } + + /* Keyboard command is now done. */ + kbd->key_command = 0x00; } else { - kbd->key_command = val; + /* No keyboard command in progress. */ + kbd->key_command = 0x00; + kbd_keyboard_set(kbd, 1); + switch (val) { case 0x00: - kbdlog("ATkbd: command 00\n"); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: command 00\n"); +#endif kbd_adddata_keyboard(0xfa); break; case 0x05: /*??? - sent by NT 4.0*/ - kbdlog("ATkbd: nt 4.0 command fe\n"); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: NT4.0 command FE\n"); +#endif kbd_adddata_keyboard(0xfe); break; case 0x71: /*These two commands are sent by Pentium-era AMI BIOS'es.*/ case 0x82: - kbdlog("ATkbd: pentium-era ami bios command %02x\n", val); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: Pentium-era AMI BIOS command %02X\n", val); +#endif break; case 0xed: /*Set/reset LEDs*/ - kbdlog("ATkbd: set/reset leds\n"); - kbd->key_wantdata = 1; - kbd->timeout = 25000LL * TIMER_USEC; +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: set/reset leds\n"); +#endif kbd_adddata_keyboard(0xfa); + + kbd->key_wantdata = 1; + kbd->key_command = val; break; case 0xee: /*Diagnostic echo*/ - kbdlog("ATkbd: diagnostic echo\n"); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: ECHO\n"); +#endif kbd_adddata_keyboard(0xee); break; case 0xef: /*NOP (No OPeration). Reserved for future use.*/ - kbdlog("ATkbd: kbd nop\n"); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: NOP\n"); +#endif break; case 0xf0: /*Get/set scan code set*/ - kbdlog("ATkbd: scan code set\n"); - kbd->key_wantdata = 1; - kbd->timeout = 25000LL * TIMER_USEC; +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: scan code set\n"); +#endif kbd_adddata_keyboard(0xfa); + kbd->key_wantdata = 1; + kbd->key_command = val; break; case 0xf2: /*Read ID*/ /* Fixed as translation will be done in kbd_adddata_keyboard(). */ - kbdlog("ATkbd: read keyboard id\n"); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: read keyboard id\n"); +#endif kbd_adddata_keyboard(0xfa); kbd_adddata_keyboard(0xab); kbd_adddata_keyboard(0x83); break; case 0xf3: /*Set typematic rate/delay*/ - kbdlog("ATkbd: set typematic rate/delay\n"); - kbd->key_wantdata = 1; - kbd->timeout = 25000LL * TIMER_USEC; +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: set typematic rate/delay\n"); +#endif kbd_adddata_keyboard(0xfa); + kbd->key_wantdata = 1; + kbd->key_command = val; break; case 0xf4: /*Enable keyboard*/ - kbdlog("ATkbd: enable keyboard via keyboard\n"); - keyboard_scan = 1; +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: enable keyboard via keyboard\n"); +#endif kbd_adddata_keyboard(0xfa); + keyboard_scan = 1; break; case 0xf5: /*Disable keyboard*/ - kbdlog("ATkbd: disable keyboard via keyboard\n"); - keyboard_scan = 0; +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: disable keyboard via keyboard\n"); +#endif kbd_adddata_keyboard(0xfa); + keyboard_scan = 0; break; case 0xf6: /*Set defaults*/ - kbdlog("ATkbd: set defaults\n"); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: set defaults\n"); +#endif + kbd_adddata_keyboard(0xfa); + keyboard_set3_all_break = 0; keyboard_set3_all_repeat = 0; memset(keyboard_set3_flags, 0, 512); keyboard_mode = (keyboard_mode & 0xFC) | 0x02; - kbd_adddata_keyboard(0xfa); kbd_setmap(kbd); break; case 0xf7: /*Set all keys to repeat*/ - kbdlog("ATkbd: set all keys to repeat\n"); - keyboard_set3_all_break = 1; +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: set all keys to repeat\n"); +#endif kbd_adddata_keyboard(0xfa); + keyboard_set3_all_break = 1; break; case 0xf8: /*Set all keys to give make/break codes*/ - kbdlog("ATkbd: set all keys to give make/break codes\n"); - keyboard_set3_all_break = 1; +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: set all keys to give make/break codes\n"); +#endif kbd_adddata_keyboard(0xfa); + keyboard_set3_all_break = 1; break; case 0xf9: /*Set all keys to give make codes only*/ - kbdlog("ATkbd: set all keys to give make codes only\n"); - keyboard_set3_all_break = 0; +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: set all keys to give make codes only\n"); +#endif kbd_adddata_keyboard(0xfa); + keyboard_set3_all_break = 0; break; case 0xfa: /*Set all keys to repeat and give make/break codes*/ - kbdlog("ATkbd: set all keys to repeat and give make/break codes\n"); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: set all keys to repeat and give make/break codes\n"); +#endif + kbd_adddata_keyboard(0xfa); keyboard_set3_all_repeat = 1; keyboard_set3_all_break = 1; - kbd_adddata_keyboard(0xfa); break; case 0xfe: /*Resend last scan code*/ - kbdlog("ATkbd: reset last scan code\n"); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: reset last scan code\n"); +#endif kbd_adddata_keyboard(kbd->last_scan_code); break; case 0xff: /*Reset*/ - kbdlog("ATkbd: kbd reset\n"); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: kbd reset\n"); +#endif key_queue_start = key_queue_end = 0; /*Clear key queue*/ kbd_adddata_keyboard(0xfa); kbd_adddata_keyboard(0xaa); @@ -1672,7 +1890,9 @@ kbd_write(uint16_t port, uint8_t val, void *priv) break; default: - kbdlog("ATkbd: bad keyboard command %02X\n", val); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: bad keyboard command %02X\n", val); +#endif kbd_adddata_keyboard(0xfe); } } @@ -1701,8 +1921,26 @@ kbd_write(uint16_t port, uint8_t val, void *priv) break; case 0x64: + /* + * Try to recover from bad commands. + * + * If we get a command here, but seem to be still in + * keyboard-command data mode, abort that... + */ + if (kbd->key_wantdata || kbd->key_command) { + kbd_log("ATkbd: *** BUG ALERT *** aborting previous keyboard command 0x%02X (data %d)\n", kbd->key_command, kbd->key_wantdata); + + /* If they were waiting for data.. */ + kbd_adddata(0xfa); + + /* Abort the previous command. */ + kbd->key_command = 0x00; + kbd->key_wantdata = 0; + } + kbd->want60 = 0; kbd->command = val; + /*New controller command*/ switch (val) { case 0x20: case 0x21: case 0x22: case 0x23: @@ -1725,11 +1963,12 @@ kbd_write(uint16_t port, uint8_t val, void *priv) case 0x78: case 0x79: case 0x7a: case 0x7b: case 0x7c: case 0x7d: case 0x7e: case 0x7f: kbd->want60 = 1; - kbd->timeout = 25000LL * TIMER_USEC; break; - case 0xaa: /*Self-test*/ - kbdlog("Self-test\n"); + case 0xaa: /*Self-test*/ +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: self-test\n"); +#endif if ((kbd->flags & KBC_VEN_MASK) == KBC_VEN_TOSHIBA) kbd->status |= STAT_IFULL; if (! kbd->initialized) { @@ -1746,64 +1985,82 @@ kbd_write(uint16_t port, uint8_t val, void *priv) kbd_adddata(0x55); break; - case 0xab: /*Interface test*/ - kbdlog("ATkbd: interface test\n"); + case 0xab: /*Interface test*/ +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: interface test\n"); +#endif kbd_adddata(0x00); /*no error*/ break; - case 0xac: /*Diagnostic dump*/ - kbdlog("ATkbd: diagnostic dump\n"); - for (i=0; i<16; i++) + case 0xac: /*Diagnostic dump*/ +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: diagnostic dump\n"); +#endif + for (i = 0; i < 16; i++) kbd_adddata(kbd->mem[i]); kbd_adddata((kbd->input_port & 0xf0) | 0x80); kbd_adddata(kbd->output_port); kbd_adddata(kbd->status); break; - case 0xad: /*Disable keyboard*/ - kbdlog("ATkbd: disable keyboard\n"); + case 0xad: /*Disable keyboard*/ +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: disable keyboard\n"); +#endif kbd_keyboard_set(kbd, 0); break; - case 0xae: /*Enable keyboard*/ - kbdlog("ATkbd: enable keyboard\n"); + case 0xae: /*Enable keyboard*/ +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: enable keyboard\n"); +#endif kbd_keyboard_set(kbd, 1); break; - case 0xd0: /*Read output port*/ - kbdlog("ATkbd: read output port\n"); + case 0xd0: /*Read output port*/ +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: read output port\n"); +#endif mask = 0xff; - if(!keyboard_scan) + if (! keyboard_scan) mask &= 0xbf; - if(!mouse_scan && ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1)) + if (!mouse_scan && ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1)) mask &= 0xf7; kbd_adddata(kbd->output_port & mask); break; - case 0xd1: /*Write output port*/ - // kbdlog("ATkbd: write output port\n"); + case 0xd1: /*Write output port*/ +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: write output port\n"); +#endif kbd->want60 = 1; - kbd->timeout = 25000LL * TIMER_USEC; break; - case 0xd2: /*Write keyboard output buffer*/ - kbdlog("ATkbd: write keyboard output buffer\n"); + case 0xd2: /*Write keyboard output buffer*/ +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: write keyboard output buffer\n"); +#endif kbd->want60 = 1; - kbd->timeout = 25000LL * TIMER_USEC; break; - case 0xdd: /* Disable A20 Address Line */ - kbdlog("ATkbd: disable A20 Address Line\n"); + case 0xdd: /* Disable A20 Address Line */ +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: disable A20\n"); +#endif kbd_output_write(kbd, kbd->output_port & 0xfd); break; - case 0xdf: /* Enable A20 Address Line */ - kbdlog("ATkbd: enable A20 address line\n"); + case 0xdf: /* Enable A20 Address Line */ +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: enable A20\n"); +#endif kbd_output_write(kbd, kbd->output_port | 0x02); break; - case 0xe0: /*Read test inputs*/ - kbdlog("ATkbd: read test inputs\n"); + case 0xe0: /*Read test inputs*/ +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: read test inputs\n"); +#endif kbd_adddata(0x00); break; @@ -1813,8 +2070,10 @@ kbd_write(uint16_t port, uint8_t val, void *priv) if (kbd->write64_ven) bad = kbd->write64_ven(kbd, val); +#ifdef ENABLE_KEYBOARD_LOG if (bad) - kbdlog("ATkbd: bad controller command %02X\n", val); + kbd_log("ATkbd: bad controller command %02X\n", val); +#endif } break; } @@ -1858,13 +2117,19 @@ kbd_read(uint16_t port, void *priv) case 0x64: ret = (kbd->status & 0xFB) | (keyboard_mode & CCB_SYSTEM); +#if 0 ret |= STAT_LOCK; +#endif /* The transmit timeout (TTIMEOUT) flag should *NOT* be cleared, otherwise the IBM PS/2 Model 80's BIOS gives error 8601 (mouse error). */ kbd->status &= ~(STAT_RTIMEOUT/* | STAT_TTIMEOUT*/); break; } +#ifdef _DEBUG + kbd_log("ATkbd: read(%04X) = %02X\n", port, ret); +#endif + return(ret); } @@ -1896,7 +2161,6 @@ kbd_reset(void *priv) kbd->last_irq = 0; kbd->secr_phase = 0; kbd->key_wantdata = 0; - kbd->timeout = 0LL; keyboard_mode = 0x02 | kbd->dtrans; @@ -1931,9 +2195,13 @@ kbd_init(const device_t *info) timer_add(kbd_poll, &keyboard_delay, TIMER_ALWAYS_ENABLED, kbd); if ((kbd->flags & KBC_TYPE_MASK) != KBC_TYPE_ISA) { - if ((kbd->flags & KBC_TYPE_MASK) == KBC_TYPE_PS2_2) - keyboard_mode &= ~0x03; /* These machines force translation off, so the keyboard - must start in scan code set 0. */ + if ((kbd->flags & KBC_TYPE_MASK) == KBC_TYPE_PS2_2) { + /* + * These machines force translation off, so the + * the keyboard must start in scan code set 0. + */ + keyboard_mode &= ~0x03; + } timer_add(kbd_refresh, &kbd->refresh_time, TIMER_ALWAYS_ENABLED, kbd); @@ -1942,9 +2210,6 @@ kbd_init(const device_t *info) timer_add(kbd_pulse_poll, &kbd->pulse_cb, &kbd->pulse_cb, kbd); - timer_add(kbd_timeout_poll, - &kbd->timeout, &kbd->timeout, kbd); - kbd->write60_ven = NULL; kbd->write64_ven = NULL; @@ -1952,17 +2217,21 @@ kbd_init(const device_t *info) case KBC_VEN_GENERIC: kbd->write64_ven = &kbd_write64_generic; break; + case KBC_VEN_AMI: kbd->write60_ven = &kbd_write60_ami; kbd->write64_ven = &kbd_write64_ami; break; + case KBC_VEN_IBM_MCA: kbd->write64_ven = &kbd_write64_ibm_mca; break; + case KBC_VEN_QUADTEL: kbd->write60_ven = &kbd_write60_quadtel; kbd->write64_ven = &kbd_write64_quadtel; break; + case KBC_VEN_TOSHIBA: kbd->write60_ven = &kbd_write60_toshiba; kbd->write64_ven = &kbd_write64_toshiba; @@ -2005,7 +2274,7 @@ const device_t keyboard_at_device = { kbd_init, kbd_close, kbd_reset, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }; const device_t keyboard_at_ami_device = { @@ -2015,7 +2284,7 @@ const device_t keyboard_at_ami_device = { kbd_init, kbd_close, kbd_reset, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }; const device_t keyboard_at_toshiba_device = { @@ -2025,7 +2294,7 @@ const device_t keyboard_at_toshiba_device = { kbd_init, kbd_close, kbd_reset, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }; const device_t keyboard_ps2_device = { @@ -2035,7 +2304,7 @@ const device_t keyboard_ps2_device = { kbd_init, kbd_close, kbd_reset, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }; const device_t keyboard_ps2_ami_device = { @@ -2045,7 +2314,7 @@ const device_t keyboard_ps2_ami_device = { kbd_init, kbd_close, kbd_reset, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }; const device_t keyboard_ps2_mca_device = { @@ -2055,7 +2324,7 @@ const device_t keyboard_ps2_mca_device = { kbd_init, kbd_close, kbd_reset, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }; const device_t keyboard_ps2_mca_2_device = { @@ -2065,7 +2334,7 @@ const device_t keyboard_ps2_mca_2_device = { kbd_init, kbd_close, kbd_reset, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }; const device_t keyboard_ps2_quadtel_device = { @@ -2075,9 +2344,10 @@ const device_t keyboard_ps2_quadtel_device = { kbd_init, kbd_close, kbd_reset, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }; + const device_t keyboard_ps2_pci_device = { "PS/2 Keyboard", DEVICE_PCI, @@ -2098,6 +2368,15 @@ const device_t keyboard_ps2_ami_pci_device = { NULL, NULL, NULL }; +void +keyboard_at_reset(void) +{ + atkbd_t *kbd = CurrentKbd; + + if (kbd != NULL) + kbd_reset(kbd); +} + void keyboard_at_set_mouse(void (*func)(uint8_t val, void *priv), void *priv) @@ -2133,7 +2412,9 @@ keyboard_at_set_mouse_scan(uint8_t val) kbd_mouse_set(kbd, val ? 1 : 0); - kbdlog("ATkbd: mouse scan %sabled via PCI\n", mouse_scan ? "en" : "dis"); +#ifdef ENABLE_KEYBOARD_LOG + kbd_log("ATkbd: mouse scan %sabled via PCI\n", mouse_scan ? "en" : "dis"); +#endif }