From 1d4fed2110b9d7a9e13abc02d44bb741179895d5 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 4 Jan 2018 07:44:33 +0100 Subject: [PATCH] Improved 8042 (AT and PS/2 keyboard controller emulation), no more hacks, split into various devices depending on vendor (generic, AMI, IBM (MCA), Quadtel, Toshiba), and fixed several commands - hopefully fixes all existing AT+ keyboard problems (such as incorrect scan codes on some machine under some circumstances); Fixed a bug in the SMC FDC37C932 emulation, fixes the FDC on the two Acer machines; Re-added some Acer-specific I/O port handlers, fixes entry into CMOS Setup on the two Acer machines. --- src/keyboard.h | 5 + src/keyboard_at.c | 707 +++++++++++++++++++++++----------- src/machine/m_at.c | 40 +- src/machine/m_at_430fx.c | 22 +- src/machine/m_at_430hx.c | 46 ++- src/machine/m_at_430lx_nx.c | 10 +- src/machine/m_at_430vx.c | 12 +- src/machine/m_at_440fx.c | 12 +- src/machine/m_at_4gpv31.c | 7 +- src/machine/m_at_ali1429.c | 4 +- src/machine/m_at_headland.c | 5 +- src/machine/m_at_neat.c | 12 + src/machine/m_at_opti495.c | 12 + src/machine/m_at_sis_85c496.c | 2 +- src/machine/m_at_t3100e.c | 5 +- src/machine/m_at_wd76c10.c | 4 +- src/machine/m_ps1.c | 10 +- src/machine/m_ps2_isa.c | 2 +- src/machine/m_ps2_mca.c | 28 +- src/machine/machine.h | 14 +- src/machine/machine_table.c | 8 +- src/pc.c | 6 +- src/sio_fdc37c93x.c | 9 +- 23 files changed, 670 insertions(+), 312 deletions(-) diff --git a/src/keyboard.h b/src/keyboard.h index 46b4af46b..91f1a26dd 100644 --- a/src/keyboard.h +++ b/src/keyboard.h @@ -50,7 +50,12 @@ extern int mouse_scan; extern device_t keyboard_xt_device; extern device_t keyboard_tandy_device; extern device_t keyboard_at_device; +extern device_t keyboard_at_ami_device; +extern device_t keyboard_at_quadtel_device; +extern device_t keyboard_at_toshiba_device; extern device_t keyboard_ps2_device; +extern device_t keyboard_ps2_ami_device; +extern device_t keyboard_ps2_mca_device; #endif extern void keyboard_init(void); diff --git a/src/keyboard_at.c b/src/keyboard_at.c index a3260e641..73632496c 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.14 2018/01/04 + * Version: @(#)keyboard_at.c 1.0.15 2018/01/04 * * Authors: Sarah Walker, * Miran Grca, @@ -23,6 +23,7 @@ #include #include #include +#define HAVE_STDARG_H #include #include "86box.h" #include "cpu/cpu.h" @@ -68,6 +69,17 @@ #define CCB_MASK 0x68 #define MODE_MASK 0x6C +#define KBC_TYPE_ISA 0x00 +#define KBC_TYPE_PS2_1 0x01 +#define KBC_TYPE_PS2_2 0x02 +#define KBC_TYPE_MASK 0x03 + +#define KBC_VEN_GENERIC 0x00 +#define KBC_VEN_AMI 0x04 +#define KBC_VEN_IBM_MCA 0x08 +#define KBC_VEN_QUADTEL 0x0C +#define KBC_VEN_TOSHIBA 0x10 +#define KBC_VEN_MASK 0x1C typedef struct { int initialized; @@ -85,13 +97,14 @@ typedef struct { uint8_t input_port, output_port; + uint8_t old_output_port; + uint8_t key_command; int key_wantdata; int last_irq; uint8_t last_scan_code; - uint8_t default_mode; int dtrans; int first_write; @@ -99,7 +112,13 @@ typedef struct { int64_t refresh_time; int refresh; - int is_ps2; + uint32_t flags; + uint8_t output_locked; + + int64_t pulse_cb; + + uint8_t (*write60_ven)(void *p, uint8_t val); + uint8_t (*write64_ven)(void *p, uint8_t val); } atkbd_t; @@ -463,7 +482,7 @@ kbdlog(const char *fmt, ...) if (keyboard_at_do_log) { va_start(ap, fmt); - pclog(fmt, ap); + pclog_ex(fmt, ap); va_end(ap); } #endif @@ -598,11 +617,349 @@ kbd_adddata_keyboard(uint8_t val) } +static void +kbd_cmd_write(atkbd_t *kbd, uint8_t val) +{ + if ((val & 1) && (kbd->status & STAT_OFULL)) + kbd->wantirq = 1; + if (!(val & 1) && kbd->wantirq) + kbd->wantirq = 0; + + /* PS/2 type 2 keyboard controllers always force the XLAT bit to 0. */ + if ((kbd->flags & KBC_TYPE_MASK) == KBC_TYPE_PS2_2) { + val &= ~CCB_TRANSLATE; + kbd->mem[kbd->command & 0x1f] &= ~CCB_TRANSLATE; + } + + /* Scan code translate ON/OFF. */ + keyboard_mode &= 0x93; + keyboard_mode |= (val & MODE_MASK); + + /* 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_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"); + kbdlog("ATkbd: mouse interrupt is now %s\n", (val & 0x02) ? "enabled" : "disabled"); + } + +#if 0 + /* Reset scancode map. */ + kbd_setmap(kbd); +#endif +} + + +static void +kbd_output_write(atkbd_t *kbd, uint8_t val) +{ + kbdlog("Write output port\n"); + if ((kbd->output_port ^ val) & 0x20) { /*IRQ 12*/ + if (val & 0x20) + picint(1 << 12); + else + picintc(1 << 12); + } + if ((kbd->output_port ^ val) & 0x10) { /*IRQ 1*/ + if (val & 0x20) + picint(1 << 1); + else + picintc(1 << 1); + } + if ((kbd->output_port ^ val) & 0x02) { /*A20 enable change*/ + mem_a20_key = val & 0x02; + mem_a20_recalc(); + flushmmucache(); + } + if ((kbd->output_port ^ val) & 0x01) { /*Reset*/ + if (! (val & 0x01)) { + /* Pin 0 selected. */ + softresetx86(); /*Pulse reset!*/ + cpu_set_edx(); + } + } + kbd->output_port = val; +} + + +static void +kbd_output_pulse(atkbd_t *kbd, uint8_t mask) +{ + kbd_output_write(kbd, kbd->output_port & (0xF0 | mask)); + kbd->old_output_port = kbd->output_port & ~(0xF0 | mask); + kbd->pulse_cb = 6LL * TIMER_USEC; +} + + +static void +kbd_pulse_poll(void *p) +{ + atkbd_t *kbd = (atkbd_t *) p; + + kbd_output_write(kbd, kbd->output_port | kbd->old_output_port); + kbd->pulse_cb = 0LL; +} + + +static uint8_t +kbd_write64_generic(void *p, uint8_t val) +{ + atkbd_t *kbd = (atkbd_t *) p; + + switch (val) { + case 0xa4: /*Check if password installed*/ + if ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) { + kbdlog("ATkbd: check if password installed\n"); + kbd_adddata(0xf1); + return 0; + } + break; + case 0xaf: /*Read keyboard version*/ + kbdlog("ATkbd: read keyboard version\n"); + kbd_adddata(0x00); + return 0; + case 0xc0: /*Read input port*/ + kbdlog("ATkbd: read input port\n"); + + kbd_adddata(kbd->input_port | 4 | fdc_ps1_525()); + kbd->input_port = ((kbd->input_port + 1) & 3) | (kbd->input_port & 0xfc) | fdc_ps1_525(); + 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\n"); + kbd_output_pulse(kbd, val & 0x0f); + break; + } + + return 1; +} + + +static uint8_t +kbd_write60_ami(void *p, uint8_t val) +{ + atkbd_t *kbd = (atkbd_t *) p; + + switch(kbd->command) { + case 0xaf: /*AMI - set extended controller RAM*/ + kbdlog("AMI - set extended controller RAM\n"); + if (kbd->secr_phase == 1) { + kbd->mem_addr = val; + kbd->want60 = 1; + 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"); + return 0; + } + + return 1; +} + + +static uint8_t +kbd_write64_ami(void *p, uint8_t val) +{ + atkbd_t *kbd = (atkbd_t *) p; + + switch (val) { + case 0xa1: /*AMI - get controller version*/ + kbdlog("AMI - get controller version\n"); + return 0; + case 0xaf: /*Set extended controller RAM*/ + kbdlog("ATkbd: set extended controller RAM\n"); + kbd->want60 = 1; + 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)) + kbd->input_port |= (1 << (val & 0x03)); + 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"); + 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"); + kbd->output_locked = 1; + return 0; + case 0xca: /*AMI - read keyboard mode*/ + kbdlog("AMI - read keyboard mode\n"); + kbd_adddata(0x00); /*ISA mode*/ + return 0; + case 0xcb: /*AMI - set keyboard mode*/ + kbdlog("AMI - set keyboard mode\n"); + kbd->want60 = 1; + return 0; + case 0xef: /*??? - sent by AMI486*/ + kbdlog("??? - sent by AMI486\n"); + return 0; + } + + return kbd_write64_generic(kbd, val); +} + + +static uint8_t +kbd_write64_ibm_mca(void *p, uint8_t val) +{ + atkbd_t *kbd = (atkbd_t *) p; + + switch (val) { + 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\n"); + kbd_output_pulse(kbd, val & 0x03); + break; + } + + return kbd_write64_generic(kbd, val); +} + + +static uint8_t +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"); + return 0; + } + + return 1; +} + + +static uint8_t +kbd_write64_quadtel(void *p, uint8_t val) +{ + atkbd_t *kbd = (atkbd_t *) p; + + switch (val) { + case 0xcf: /*??? - sent by MegaPC BIOS*/ + kbdlog("??? - sent by MegaPC BIOS\n"); + kbd->want60 = 1; + return 0; + } + + return kbd_write64_generic(kbd, val); +} + + +static uint8_t +kbd_write60_toshiba(void *p, uint8_t val) +{ + atkbd_t *kbd = (atkbd_t *) p; + + switch(kbd->command) { + case 0xb6: /* T3100e - set colour/mono switch */ + t3100e_mono_set(val); + return 0; + } + + return 1; +} + + +static uint8_t +kbd_write64_toshiba(void *p, uint8_t val) +{ + atkbd_t *kbd = (atkbd_t *) p; + + switch (val) { + case 0xb0: /* T3100e: Turbo on */ + t3100e_turbo_set(1); + return 0; + case 0xb1: /* T3100e: Turbo off */ + t3100e_turbo_set(0); + return 0; + case 0xb2: /* T3100e: Select external display */ + t3100e_display_set(0x00); + return 0; + case 0xb3: /* T3100e: Select internal display */ + t3100e_display_set(0x01); + return 0; + case 0xb4: /* T3100e: Get configuration / status */ + kbd_adddata(t3100e_config_get()); + return 0; + case 0xb5: /* T3100e: Get colour / mono byte */ + kbd_adddata(t3100e_mono_get()); + return 0; + case 0xb6: /* T3100e: Set colour / mono byte */ + kbd->want60 = 1; + return 0; + 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'. */ + 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 */ + t3100e_notify_set(0x00); + return 0; + case 0xc0: /*Read input port*/ + kbdlog("ATkbd: read input port\n"); + + /* 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_adddata(kbd->input_port); + return 0; + + } + + return kbd_write64_generic(kbd, val); +} + + static void kbd_write(uint16_t port, uint8_t val, void *priv) { atkbd_t *kbd = (atkbd_t *)priv; int i = 0; + int bad = 1; switch (port) { case 0x60: @@ -633,78 +990,19 @@ kbd_write(uint16_t port, uint8_t val, void *priv) write_register: kbd->mem[kbd->command & 0x1f] = val; - if (kbd->command == 0x60) { - if ((val & 1) && (kbd->status & STAT_OFULL)) - kbd->wantirq = 1; - if (!(val & 1) && kbd->wantirq) - kbd->wantirq = 0; - mouse_scan = !(val & 0x20); - kbdlog("ATkbd: mouse is now %s\n", mouse_scan ? "enabled" : "disabled"); - kbdlog("ATkbd: mouse interrupt is now %s\n", (val & 0x02) ? "enabled" : "disabled"); - - /* Scan code translate ON/OFF. */ - keyboard_mode &= 0x93; - keyboard_mode |= (val & MODE_MASK); - if (kbd->first_write) { - /* A bit of a hack, but it will make the keyboard behave correctly, regardless - of what the BIOS sets here. */ - keyboard_mode &= 0xFC; - kbd->dtrans = keyboard_mode & (CCB_TRANSLATE | CCB_PCMODE); - if ((keyboard_mode & (CCB_TRANSLATE | CCB_PCMODE)) == CCB_TRANSLATE) { - /* Bit 6 on, bit 5 off, the only case in which translation is on, - therefore, set to set 2. */ - keyboard_mode |= 2; - } - kbd->default_mode = (keyboard_mode & 3); - kbd->first_write = 0; - /* No else because in all other cases, translation is off, so we need to keep it - set to set 0 which the mode &= 0xFC above will set it. */ - } - - /* Reset scancode map. */ - kbd_setmap(kbd); - } - break; - - case 0xaf: /*AMI - set extended controller RAM*/ - kbdlog("AMI - set extended controller RAM\n"); - if (kbd->secr_phase == 0) { - goto bad_command; - } else if (kbd->secr_phase == 1) { - kbd->mem_addr = val; - kbd->want60 = 1; - kbd->secr_phase = 2; - } else if (kbd->secr_phase == 2) { - kbd->mem[kbd->mem_addr] = val; - kbd->secr_phase = 0; - } - break; - - case 0xb6: /* T3100e - set colour/mono switch */ - if (romset == ROM_T3100E) - t3100e_mono_set(val); - break; - - case 0xcb: /*AMI - set keyboard mode*/ - kbdlog("AMI - set keyboard mode\n"); - break; - - case 0xcf: /*??? - sent by MegaPC BIOS*/ - kbdlog("??? - sent by MegaPC BIOS\n"); - /* To make sure the keyboard works correctly on the MegaPC. */ - keyboard_mode &= 0xFC; - keyboard_mode |= 2; - kbd_setmap(kbd); + if (kbd->command == 0x60) + kbd_cmd_write(kbd, val); break; case 0xd1: /*Write output port*/ kbdlog("Write output port\n"); - if ((kbd->output_port ^ val) & 0x02) { /*A20 enable change*/ - mem_a20_key = val & 0x02; - mem_a20_recalc(); - flushmmucache(); + if (kbd->output_locked) { + /*If keyboard controller lines P22-P23 are blocked, + we force them to remain unchanged.*/ + val &= ~0x0c; + val |= (kbd->output_port & 0x0c); } - kbd->output_port = val; + kbd_output_write(kbd, val); break; case 0xd2: /*Write to keyboard output buffer*/ @@ -719,15 +1017,20 @@ write_register: case 0xd4: /*Write to mouse*/ kbdlog("ATkbd: write to mouse (%02X)\n", val); - if (mouse_write && (machines[machine].flags & MACHINE_PS2)) + if (mouse_write && ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1)) mouse_write(val, mouse_p); else keyboard_at_adddata_mouse(0xff); break; default: -bad_command: - kbdlog("ATkbd: bad keyboard controller 0060 write %02X command %02X\n", val, kbd->command); + /* Run the vendor-specific command handler, if present, + otherwise (or if the former returns 1), assume bad command. */ + if (kbd->write60_ven) + bad = kbd->write60_ven(kbd, val); + + if (bad) + kbdlog("ATkbd: bad keyboard controller 0060 write %02X command %02X\n", val, kbd->command); } } else { /*Write to keyboard*/ @@ -817,7 +1120,7 @@ bad_command: keyboard_set3_all_break = 0; keyboard_set3_all_repeat = 0; memset(keyboard_set3_flags, 0, 272); - keyboard_mode = (keyboard_mode & 0xFC) | kbd->default_mode; + keyboard_mode = (keyboard_mode & 0xFC) | 0x02; kbd_adddata_keyboard(0xfa); kbd_setmap(kbd); break; @@ -918,12 +1221,8 @@ bad_command: kbd->want60 = 1; break; - case 0xa1: /*AMI - get controller version*/ - kbdlog("AMI - get controller version\n"); - break; - case 0xa7: /*Disable mouse port*/ - if (machines[machine].flags & MACHINE_PS2) { + if ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) { kbdlog("ATkbd: disable mouse port\n"); mouse_scan = 0; kbd->mem[0] |= 0x20; @@ -933,7 +1232,7 @@ bad_command: break; case 0xa8: /*Enable mouse port*/ - if (machines[machine].flags & MACHINE_PS2) { + if ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) { kbdlog("ATkbd: enable mouse port\n"); mouse_scan = 1; kbd->mem[0] &= 0xDF; @@ -944,7 +1243,7 @@ bad_command: case 0xa9: /*Test mouse port*/ kbdlog("ATkbd: test mouse port\n"); - if (machines[machine].flags & MACHINE_PS2) { + if ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) { kbd_adddata(0x00); /*no error*/ } else { kbd_adddata(0xff); /*no mouse*/ @@ -953,7 +1252,7 @@ bad_command: case 0xaa: /*Self-test*/ kbdlog("Self-test\n"); - if(romset == ROM_T3100E) + if ((kbd->flags & KBC_VEN_MASK) == KBC_VEN_TOSHIBA) kbd->status |= STAT_IFULL; if (! kbd->initialized) { kbd->initialized = 1; @@ -996,121 +1295,6 @@ bad_command: kbd->mem[0] &= ~0x10; break; - case 0xaf: - switch(romset) { - case ROM_AMI286: - case ROM_AMI386SX: - case ROM_AMI386DX_OPTI495: - case ROM_MR386DX_OPTI495: - case ROM_AMI486: - case ROM_WIN486: - case ROM_REVENGE: - case ROM_PLATO: - case ROM_ENDEAVOR: - case ROM_THOR: - case ROM_MRTHOR: - case ROM_AP53: - case ROM_P55T2S: -#ifdef DEV_BRANCH -#ifdef USE_I686 - case ROM_S1668: -#endif -#ifdef GREENB - case ROM_4GPV31: -#endif -#endif - /*Set extended controller RAM*/ - kbdlog("ATkbd: set extended controller RAM\n"); - kbd->want60 = 1; - kbd->secr_phase = 1; - break; - - default: - /*Read keyboard version*/ - kbdlog("ATkbd: read keyboard version\n"); - kbd_adddata(0x00); - break; - } - break; - - case 0xb0: /* T3100e: Turbo on */ - if (romset == ROM_T3100E) { - t3100e_turbo_set(1); - break; - } - case 0xb1: /* T3100e: Turbo off */ - if (romset == ROM_T3100E) { - t3100e_turbo_set(0); - break; - } - case 0xb2: /* T3100e: Select external display */ - if (romset == ROM_T3100E) { - t3100e_display_set(0x00); - break; - } - case 0xb3: /* T3100e: Select internal display */ - if (romset == ROM_T3100E) { - t3100e_display_set(0x01); - break; - } - case 0xb4: /* T3100e: Get configuration / status */ - if (romset == ROM_T3100E) { - kbd_adddata(t3100e_config_get()); - break; - } - case 0xb5: /* T3100e: Get colour / mono byte */ - if (romset == ROM_T3100E) { - kbd_adddata(t3100e_mono_get()); - break; - } - case 0xb6: /* T3100e: Set colour / mono byte */ - if (romset == ROM_T3100E) { - kbd->want60 = 1; - break; - } - case 0xb7: /* T3100e: Emulate PS/2 keyboard - not implemented */ - case 0xb8: /* T3100e: Emulate AT keyboard - not implemented */ - if (romset == ROM_T3100E) - break; - 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 (romset == ROM_T3100E) - { - if (keyboard_recv(0xb8) || /* Right Alt */ - keyboard_recv(0x9d)) /* Right Ctrl */ - kbd_adddata(0x04); - else kbd_adddata(0x00); - break; - } - case 0xbc: /* T3100e: Reset Fn+Key notification */ - if (romset == ROM_T3100E) { - t3100e_notify_set(0x00); - break; - } - case 0xb9: case 0xba: - case 0xbd: case 0xbe: case 0xbf: - /*Set keyboard lines low (B0-B7) or high (B8-BF)*/ - kbdlog("ATkbd: set keyboard lines low (B0-B7) or high (B8-BF)\n"); - kbd_adddata(0x00); - break; - - case 0xc0: /*Read input port*/ - kbdlog("ATkbd: read input port\n"); - - /* The T3100e returns all bits set except bit 6 which - * is set by t3100e_mono_set() */ - if (romset == ROM_T3100E) { - kbd->input_port = (t3100e_mono_get() & 1) ? 0xFF : 0xBF; - kbd_adddata(kbd->input_port | 4 | fdc_ps1_525()); - kbd->input_port = ((kbd->input_port + 1) & 3) | (kbd->input_port & 0xfc); - } else { - kbd_adddata(kbd->input_port | 4 | fdc_ps1_525()); - kbd->input_port = ((kbd->input_port + 1) & 3) | (kbd->input_port & 0xfc) | fdc_ps1_525(); - } - break; - 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"); kbd->status &= 0xf; @@ -1123,25 +1307,6 @@ bad_command: kbd->status |= (((kbd->input_port & 0xfc) | 0x84 | fdc_ps1_525()) & 0xf0); break; - case 0xc9: /*AMI - block P22 and P23 ???*/ - kbdlog("AMI - block P22 and P23 ???\n"); - break; - - case 0xca: /*AMI - read keyboard mode*/ - kbdlog("AMI - read keyboard mode\n"); - kbd_adddata(0x00); /*ISA mode*/ - break; - - case 0xcb: /*AMI - set keyboard mode*/ - kbdlog("AMI - set keyboard mode\n"); - kbd->want60 = 1; - break; - - case 0xcf: /*??? - sent by MegaPC BIOS*/ - kbdlog("??? - sent by MegaPC BIOS\n"); - kbd->want60 = 1; - break; - case 0xd0: /*Read output port*/ kbdlog("ATkbd: read output port\n"); kbd_adddata(kbd->output_port); @@ -1188,10 +1353,6 @@ bad_command: kbd_adddata(0x00); break; - case 0xef: /*??? - sent by AMI486*/ - kbdlog("??? - sent by AMI486\n"); - 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: @@ -1206,7 +1367,13 @@ bad_command: break; default: - kbdlog("ATkbd: bad controller command %02X\n", val); + /* Run the vendor-specific command handler, if present, + otherwise (or if the former returns 1), assume bad command. */ + if (kbd->write64_ven) + bad = kbd->write64_ven(kbd, val); + + if (bad) + kbdlog("ATkbd: bad controller command %02X\n", val); } break; } @@ -1222,7 +1389,7 @@ kbd_read(uint16_t port, void *priv) switch (port) { case 0x60: ret = kbd->out; - kbd->status &= ~(STAT_OFULL/* | STAT_MFULL*/); + kbd->status &= ~(STAT_OFULL); picintc(kbd->last_irq); kbd->last_irq = 0; break; @@ -1231,20 +1398,17 @@ kbd_read(uint16_t port, void *priv) ret = ppi.pb & ~0xe0; if (ppispeakon) ret |= 0x20; - if (kbd->is_ps2) { + if ((kbd->flags & KBC_TYPE_MASK) != KBC_TYPE_ISA) { if (kbd->refresh) ret |= 0x10; - else + else ret &= ~0x10; } break; case 0x64: ret = (kbd->status & 0xFB) | (keyboard_mode & CCB_SYSTEM); -#if 0 - if (keyboard_mode & CCB_IGNORELOCK) -#endif - ret |= STAT_LOCK; + ret |= STAT_LOCK; kbd->status &= ~(STAT_RTIMEOUT/* | STAT_TTIMEOUT*/); break; } @@ -1272,9 +1436,7 @@ kbd_reset(void *priv) kbd->dtrans = 0; kbd->first_write = 1; kbd->status = STAT_LOCK | STAT_CD; - // kbd->mem[0] = 0x31; kbd->mem[0] = 0x11; - kbd->default_mode = 0x02; kbd->wantirq = 0; kbd->output_port = 0xcd; kbd->input_port = (MDA) ? 0xf0 : 0xb0; @@ -1311,11 +1473,38 @@ kbd_init(device_t *info) timer_add(kbd_poll, &keyboard_delay, TIMER_ALWAYS_ENABLED, kbd); - if (info->local == 1) { + kbd->flags = info->local; + + if ((kbd->flags & KBC_TYPE_MASK) != KBC_TYPE_ISA) { timer_add(kbd_refresh, &kbd->refresh_time, TIMER_ALWAYS_ENABLED, kbd); + } - kbd->is_ps2 = 1; + timer_add(kbd_pulse_poll, + &kbd->pulse_cb, &kbd->pulse_cb, kbd); + + kbd->write60_ven = NULL; + kbd->write64_ven = NULL; + + switch(kbd->flags & KBC_VEN_MASK) { + 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; + break; } /* We need this, sadly. */ @@ -1350,7 +1539,37 @@ kbd_close(void *priv) device_t keyboard_at_device = { "PC/AT Keyboard", 0, + KBC_TYPE_ISA | KBC_VEN_GENERIC, + kbd_init, + kbd_close, + kbd_reset, + NULL, NULL, NULL, NULL +}; + +device_t keyboard_at_ami_device = { + "PC/AT Keyboard (AMI)", 0, + KBC_TYPE_ISA | KBC_VEN_AMI, + kbd_init, + kbd_close, + kbd_reset, + NULL, NULL, NULL, NULL +}; + +device_t keyboard_at_quadtel_device = { + "PC/AT Keyboard (Quadtel/MegaPC)", + 0, + KBC_TYPE_ISA | KBC_VEN_QUADTEL, + kbd_init, + kbd_close, + kbd_reset, + NULL, NULL, NULL, NULL +}; + +device_t keyboard_at_toshiba_device = { + "PC/AT Keyboard (Toshiba)", + 0, + KBC_TYPE_ISA | KBC_VEN_TOSHIBA, kbd_init, kbd_close, kbd_reset, @@ -1360,7 +1579,27 @@ device_t keyboard_at_device = { device_t keyboard_ps2_device = { "PS/2 Keyboard", 0, - 1, + KBC_TYPE_PS2_1 | KBC_VEN_GENERIC, + kbd_init, + kbd_close, + kbd_reset, + NULL, NULL, NULL, NULL +}; + +device_t keyboard_ps2_ami_device = { + "PS/2 Keyboard (AMI)", + 0, + KBC_TYPE_PS2_1 | KBC_VEN_AMI, + kbd_init, + kbd_close, + kbd_reset, + NULL, NULL, NULL, NULL +}; + +device_t keyboard_ps2_mca_device = { + "PS/2 Keyboard", + 0, + KBC_TYPE_PS2_1 | KBC_VEN_IBM_MCA, kbd_init, kbd_close, kbd_reset, diff --git a/src/machine/m_at.c b/src/machine/m_at.c index 945e3e8aa..ed03b4b62 100644 --- a/src/machine/m_at.c +++ b/src/machine/m_at.c @@ -18,7 +18,7 @@ void -machine_at_init(machine_t *model) +machine_at_common_init(machine_t *model) { machine_common_init(model); @@ -31,13 +31,38 @@ machine_at_init(machine_t *model) nvr_at_init(8); - device_add(&keyboard_at_device); - if (joystick_type != 7) device_add(&gameport_device); } +void +machine_at_init(machine_t *model) +{ + machine_at_common_init(model); + + device_add(&keyboard_at_device); +} + + +void +machine_at_ps2_init(machine_t *model) +{ + machine_at_common_init(model); + + device_add(&keyboard_ps2_device); +} + + +void +machine_at_common_ide_init(machine_t *model) +{ + machine_at_common_init(model); + + ide_init(); +} + + void machine_at_ide_init(machine_t *model) { @@ -47,6 +72,15 @@ machine_at_ide_init(machine_t *model) } +void +machine_at_ps2_ide_init(machine_t *model) +{ + machine_at_ps2_init(model); + + ide_init(); +} + + void machine_at_top_remap_init(machine_t *model) { diff --git a/src/machine/m_at_430fx.c b/src/machine/m_at_430fx.c index 2401e2aa2..c4db236a0 100644 --- a/src/machine/m_at_430fx.c +++ b/src/machine/m_at_430fx.c @@ -8,13 +8,13 @@ * * Implementation of the Intel 430FX PCISet chip. * - * Version: @(#)m_at_430fx.c 1.0.8 2017/11/04 + * Version: @(#)m_at_430fx.c 1.0.10 2018/01/04 * * Authors: Sarah Walker, * Miran Grca, * - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016,2017 Miran Grca. + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016,2018 Miran Grca. */ #include #include @@ -26,6 +26,7 @@ #include "../rom.h" #include "../pci.h" #include "../device.h" +#include "../keyboard.h" #include "../piix.h" #include "../intel_flash.h" #include "../sio.h" @@ -205,7 +206,7 @@ static void i430fx_init(void) void machine_at_p54tp4xe_init(machine_t *model) { - machine_at_ide_init(model); + machine_at_ps2_ide_init(model); memregs_init(); pci_init(PCI_CONFIG_TYPE_1); @@ -226,7 +227,8 @@ machine_at_p54tp4xe_init(machine_t *model) void machine_at_endeavor_init(machine_t *model) { - machine_at_ide_init(model); + machine_at_common_ide_init(model); + device_add(&keyboard_ps2_ami_device); memregs_init(); pci_init(PCI_CONFIG_TYPE_1); @@ -248,7 +250,8 @@ machine_at_endeavor_init(machine_t *model) void machine_at_zappa_init(machine_t *model) { - machine_at_ide_init(model); + machine_at_common_ide_init(model); + device_add(&keyboard_ps2_ami_device); memregs_init(); pci_init(PCI_CONFIG_TYPE_1); @@ -268,7 +271,7 @@ machine_at_zappa_init(machine_t *model) void machine_at_mb500n_init(machine_t *model) { - machine_at_ide_init(model); + machine_at_ps2_ide_init(model); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); @@ -288,7 +291,7 @@ machine_at_mb500n_init(machine_t *model) void machine_at_president_init(machine_t *model) { - machine_at_ide_init(model); + machine_at_ps2_ide_init(model); memregs_init(); pci_init(PCI_CONFIG_TYPE_1); @@ -309,7 +312,8 @@ machine_at_president_init(machine_t *model) void machine_at_thor_init(machine_t *model) { - machine_at_ide_init(model); + machine_at_common_ide_init(model); + device_add(&keyboard_ps2_ami_device); memregs_init(); pci_init(PCI_CONFIG_TYPE_1); diff --git a/src/machine/m_at_430hx.c b/src/machine/m_at_430hx.c index d1c4f76a2..75e44be96 100644 --- a/src/machine/m_at_430hx.c +++ b/src/machine/m_at_430hx.c @@ -8,13 +8,13 @@ * * Implementation of the Intel 430HX PCISet chip. * - * Version: @(#)m_at_430hx.c 1.0.8 2017/11/04 + * Version: @(#)m_at_430hx.c 1.0.10 2018/01/04 * * Authors: Sarah Walker, * Miran Grca, * - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016-2017 Miran Grca. + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. */ #include #include @@ -26,6 +26,7 @@ #include "../memregs.h" #include "../pci.h" #include "../device.h" +#include "../keyboard.h" #include "../piix.h" #include "../intel_flash.h" #include "../sio.h" @@ -189,10 +190,35 @@ static void i430hx_init(void) } +static int acerm3a_index; + + +static void +acerm3a_out(uint16_t port, uint8_t val, void *p) +{ + if (port == 0xea) + acerm3a_index = val; +} + +static uint8_t +acerm3a_in(uint16_t port, void *p) +{ + if (port == 0xeb) + { + switch (acerm3a_index) + { + case 2: + return 0xfd; + } + } + return 0xff; +} + + void machine_at_acerm3a_init(machine_t *model) { - machine_at_ide_init(model); + machine_at_ps2_ide_init(model); powermate_memregs_init(); pci_init(PCI_CONFIG_TYPE_1); @@ -206,6 +232,7 @@ machine_at_acerm3a_init(machine_t *model) i430hx_init(); piix3_init(7); fdc37c932fr_init(); + io_sethandler(0x00ea, 0x0002, acerm3a_in, NULL, NULL, acerm3a_out, NULL, NULL, NULL); device_add(&intel_flash_bxb_device); } @@ -214,7 +241,7 @@ machine_at_acerm3a_init(machine_t *model) void machine_at_acerv35n_init(machine_t *model) { - machine_at_ide_init(model); + machine_at_ps2_ide_init(model); powermate_memregs_init(); pci_init(PCI_CONFIG_TYPE_1); @@ -228,6 +255,7 @@ machine_at_acerv35n_init(machine_t *model) i430hx_init(); piix3_init(7); fdc37c932fr_init(); + io_sethandler(0x00ea, 0x0002, acerm3a_in, NULL, NULL, acerm3a_out, NULL, NULL, NULL); device_add(&intel_flash_bxb_device); } @@ -236,7 +264,8 @@ machine_at_acerv35n_init(machine_t *model) void machine_at_ap53_init(machine_t *model) { - machine_at_ide_init(model); + machine_at_common_ide_init(model); + device_add(&keyboard_ps2_ami_device); memregs_init(); powermate_memregs_init(); @@ -259,7 +288,7 @@ machine_at_ap53_init(machine_t *model) void machine_at_p55t2p4_init(machine_t *model) { - machine_at_ide_init(model); + machine_at_ps2_ide_init(model); memregs_init(); pci_init(PCI_CONFIG_TYPE_1); @@ -280,7 +309,8 @@ machine_at_p55t2p4_init(machine_t *model) void machine_at_p55t2s_init(machine_t *model) { - machine_at_ide_init(model); + machine_at_common_ide_init(model); + device_add(&keyboard_ps2_ami_device); memregs_init(); powermate_memregs_init(); diff --git a/src/machine/m_at_430lx_nx.c b/src/machine/m_at_430lx_nx.c index 055d787de..58d4d447f 100644 --- a/src/machine/m_at_430lx_nx.c +++ b/src/machine/m_at_430lx_nx.c @@ -8,13 +8,13 @@ * * Implementation of the Intel 430LX and 430NX PCISet chips. * - * Version: @(#)m_at_430lx_nx.c 1.0.8 2017/11/04 + * Version: @(#)m_at_430lx_nx.c 1.0.9 2018/01/04 * * Authors: Sarah Walker, * Miran Grca, * - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016,2017 Miran Grca. + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016,2018 Miran Grca. */ #include #include @@ -26,6 +26,7 @@ #include "../rom.h" #include "../pci.h" #include "../device.h" +#include "../keyboard.h" #include "../intel.h" #include "../intel_flash.h" #include "../intel_sio.h" @@ -212,7 +213,8 @@ static void i430nx_init(void) static void machine_at_premiere_common_init(machine_t *model) { - machine_at_ide_init(model); + machine_at_common_ide_init(model); + device_add(&keyboard_ps2_ami_device); memregs_init(); pci_init(PCI_CONFIG_TYPE_2); diff --git a/src/machine/m_at_430vx.c b/src/machine/m_at_430vx.c index 25ca83d49..a57b6aa5d 100644 --- a/src/machine/m_at_430vx.c +++ b/src/machine/m_at_430vx.c @@ -8,13 +8,13 @@ * * Implementation of the Intel 430VX PCISet chip. * - * Version: @(#)m_at_430vx.c 1.0.9 2017/11/04 + * Version: @(#)m_at_430vx.c 1.0.10 2018/01/04 * * Authors: Sarah Walker, * Miran Grca, * - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016,2017 Miran Grca. + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016,2018 Miran Grca. */ #include #include @@ -195,7 +195,7 @@ void i430vx_init(void) void machine_at_p55tvp4_init(machine_t *model) { - machine_at_ide_init(model); + machine_at_ps2_ide_init(model); memregs_init(); pci_init(PCI_CONFIG_TYPE_1); @@ -216,7 +216,7 @@ machine_at_p55tvp4_init(machine_t *model) void machine_at_i430vx_init(machine_t *model) { - machine_at_ide_init(model); + machine_at_ps2_ide_init(model); memregs_init(); pci_init(PCI_CONFIG_TYPE_1); @@ -237,7 +237,7 @@ machine_at_i430vx_init(machine_t *model) void machine_at_p55va_init(machine_t *model) { - machine_at_ide_init(model); + machine_at_ps2_ide_init(model); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); diff --git a/src/machine/m_at_440fx.c b/src/machine/m_at_440fx.c index ff4434a0a..b972d30aa 100644 --- a/src/machine/m_at_440fx.c +++ b/src/machine/m_at_440fx.c @@ -8,13 +8,13 @@ * * Implementation of the Intel 440FX PCISet chip. * - * Version: @(#)m_at_440fx.c 1.0.8 2017/11/04 + * Version: @(#)m_at_440fx.c 1.0.9 2018/01/04 * * Authors: Sarah Walker, * Miran Grca, * - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016,2017 Miran Grca. + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016,2018 Miran Grca. */ #include #include @@ -26,6 +26,7 @@ #include "../mem.h" #include "../memregs.h" #include "../device.h" +#include "../keyboard.h" #include "../piix.h" #include "../intel_flash.h" #include "../sio.h" @@ -196,7 +197,7 @@ static void i440fx_init(void) void machine_at_i440fx_init(machine_t *model) { - machine_at_ide_init(model); + machine_at_ps2_ide_init(model); memregs_init(); pci_init(PCI_CONFIG_TYPE_1); @@ -218,7 +219,8 @@ machine_at_i440fx_init(machine_t *model) void machine_at_s1668_init(machine_t *model) { - machine_at_ide_init(model); + machine_at_common_ide_init(model); + device_add(&keyboard_ps2_ami_device); memregs_init(); pci_init(PCI_CONFIG_TYPE_1); diff --git a/src/machine/m_at_4gpv31.c b/src/machine/m_at_4gpv31.c index d53fa46fe..b564b153c 100644 --- a/src/machine/m_at_4gpv31.c +++ b/src/machine/m_at_4gpv31.c @@ -11,10 +11,10 @@ * NOTE: The NEAT 82c206 code should be moved into a 82c206 module, * so it can be re-used by other boards. * - * Version: @(#)m_4gpv31.c 1.0.1 2017/12/04 + * Version: @(#)m_4gpv31.c 1.0.2 2018/01/04 * * Author: Fred N. van Kempen, - * Copyright 2017 Fred N. van Kempen. + * Copyright 2018 Fred N. van Kempen. */ #include #include @@ -141,7 +141,8 @@ neat_init(void) void machine_at_4gpv31_init(machine_t *model) { - machine_at_ide_init(model); + machine_at_common_ide_init(model); + device_add(&keyboard_at_ami_device); neat_init(); } diff --git a/src/machine/m_at_ali1429.c b/src/machine/m_at_ali1429.c index 514dc5caf..9a8bcb926 100644 --- a/src/machine/m_at_ali1429.c +++ b/src/machine/m_at_ali1429.c @@ -10,6 +10,7 @@ #include "../io.h" #include "../mem.h" #include "../device.h" +#include "../keyboard.h" #include "../disk/hdc.h" #include "../disk/hdc_ide.h" #include "machine.h" @@ -99,7 +100,8 @@ machine_at_ali1429_init(machine_t *model) { ali1429_reset(); - machine_at_ide_init(model); + machine_at_common_ide_init(model); + device_add(&keyboard_at_ami_device); ali1429_init(); diff --git a/src/machine/m_at_headland.c b/src/machine/m_at_headland.c index 23d914452..bfbb473e6 100644 --- a/src/machine/m_at_headland.c +++ b/src/machine/m_at_headland.c @@ -9,6 +9,8 @@ #include "../cpu/cpu.h" #include "../cpu/x86.h" #include "../io.h" +#include "../device.h" +#include "../keyboard.h" #include "../mem.h" #include "machine.h" @@ -68,7 +70,8 @@ static void headland_init(void) void machine_at_headland_init(machine_t *model) { - machine_at_ide_init(model); + machine_at_common_ide_init(model); + device_add(&keyboard_at_ami_device); headland_init(); } diff --git a/src/machine/m_at_neat.c b/src/machine/m_at_neat.c index b8a3d8684..5c5ccd4bf 100644 --- a/src/machine/m_at_neat.c +++ b/src/machine/m_at_neat.c @@ -7,7 +7,9 @@ #include #include #include "../86box.h" +#include "../device.h" #include "../io.h" +#include "../keyboard.h" #include "machine.h" @@ -90,3 +92,13 @@ machine_at_neat_init(machine_t *model) neat_init(); } + + +void +machine_at_neat_ami_init(machine_t *model) +{ + machine_at_common_init(model); + device_add(&keyboard_at_ami_device); + + neat_init(); +} diff --git a/src/machine/m_at_opti495.c b/src/machine/m_at_opti495.c index caf316aa9..b0d07e024 100644 --- a/src/machine/m_at_opti495.c +++ b/src/machine/m_at_opti495.c @@ -258,6 +258,8 @@ SeeAlso: #P0178,#P0187 #include "../86box.h" #include "../cpu/cpu.h" #include "../io.h" +#include "../device.h" +#include "../keyboard.h" #include "../mem.h" #include "machine.h" @@ -332,3 +334,13 @@ machine_at_opti495_init(machine_t *model) opti495_init(); } + + +void +machine_at_opti495_ami_init(machine_t *model) +{ + machine_at_common_ide_init(model); + device_add(&keyboard_at_ami_device); + + opti495_init(); +} diff --git a/src/machine/m_at_sis_85c496.c b/src/machine/m_at_sis_85c496.c index 7cf2f5af9..6e2c1c57c 100644 --- a/src/machine/m_at_sis_85c496.c +++ b/src/machine/m_at_sis_85c496.c @@ -162,7 +162,7 @@ static void sis_85c496_init(void) static void machine_at_sis_85c496_common_init(machine_t *model) { - machine_at_ide_init(model); + machine_at_ps2_ide_init(model); memregs_init(); pci_init(PCI_CONFIG_TYPE_1); diff --git a/src/machine/m_at_t3100e.c b/src/machine/m_at_t3100e.c index 73ac42fe9..5e49e8278 100644 --- a/src/machine/m_at_t3100e.c +++ b/src/machine/m_at_t3100e.c @@ -9,6 +9,7 @@ #include "../mouse.h" #include "../mem.h" #include "../device.h" +#include "../keyboard.h" #include "../cpu/cpu.h" #include "../floppy/fdd.h" #include "../video/vid_t3100e.h" @@ -683,7 +684,9 @@ void machine_at_t3100e_init(machine_t *model) memset(&t3100e_ems, 0, sizeof(t3100e_ems)); - machine_at_ide_init(model); + machine_at_common_ide_init(model); + device_add(&keyboard_at_toshiba_device); + /* Hook up system control port */ io_sethandler(0x8084, 0x0001, t3100e_sys_in, NULL, NULL, diff --git a/src/machine/m_at_wd76c10.c b/src/machine/m_at_wd76c10.c index 5e622fb6e..8df1539ef 100644 --- a/src/machine/m_at_wd76c10.c +++ b/src/machine/m_at_wd76c10.c @@ -8,6 +8,7 @@ #include "../86box.h" #include "../device.h" #include "../io.h" +#include "../keyboard.h" #include "../mem.h" #include "../serial.h" #include "../floppy/floppy.h" @@ -140,7 +141,8 @@ static void wd76c10_init(void) void machine_at_wd76c10_init(machine_t *model) { - machine_at_ide_init(model); + machine_at_common_ide_init(model); + device_add(&keyboard_at_quadtel_device); wd76c10_init(); diff --git a/src/machine/m_ps1.c b/src/machine/m_ps1.c index 41f9e7030..216108ab0 100644 --- a/src/machine/m_ps1.c +++ b/src/machine/m_ps1.c @@ -28,15 +28,15 @@ * boot. Sometimes, they do, and then it shows an "Incorrect * DOS" error message?? --FvK * - * Version: @(#)m_ps1.c 1.0.3 2017/11/08 + * Version: @(#)m_ps1.c 1.0.4 2018/01/04 * * Authors: Sarah Walker, * Miran Grca, * Fred N. van Kempen, * - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016,2017 Miran Grca. - * Copyright 2017 Fred N. van Kempen. + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016,2018 Miran Grca. + * Copyright 2018 Fred N. van Kempen. */ #include #include @@ -552,7 +552,7 @@ ps1_common_init(machine_t *model) if (romset != ROM_IBMPS1_2011) ide_init(); - device_add(&keyboard_at_device); + device_add(&keyboard_ps2_device); if (romset != ROM_IBMPS1_2133) { fdc_set_dskchg_activelow(); diff --git a/src/machine/m_ps2_isa.c b/src/machine/m_ps2_isa.c index f14106f1e..0f4e0a718 100644 --- a/src/machine/m_ps2_isa.c +++ b/src/machine/m_ps2_isa.c @@ -160,7 +160,7 @@ machine_ps2_m30_286_init(machine_t *model) pit_set_out_func(&pit, 1, pit_refresh_timer_at); dma16_init(); - device_add(&keyboard_at_device); + device_add(&keyboard_ps2_device); nvr_at_init(8); pic2_init(); ps2board_init(); diff --git a/src/machine/m_ps2_mca.c b/src/machine/m_ps2_mca.c index a3127ad47..6e6d37e31 100644 --- a/src/machine/m_ps2_mca.c +++ b/src/machine/m_ps2_mca.c @@ -260,10 +260,10 @@ static void model_55sx_write(uint16_t port, uint8_t val) case 0x104: ps2.memory_bank[ps2.option[3] & 7] &= ~0xf; ps2.memory_bank[ps2.option[3] & 7] |= (val & 0xf); - pclog("Write memory bank %i %02x\n", ps2.option[3] & 7, val); + /* pclog("Write memory bank %i %02x\n", ps2.option[3] & 7, val); */ break; case 0x105: - pclog("Write POS3 %02x\n", val); + /* pclog("Write POS3 %02x\n", val); */ ps2.option[3] = val; shadowbios = !(val & 0x10); shadowbios_write = val & 0x10; @@ -440,15 +440,15 @@ uint8_t ps2_mca_read(uint16_t port, void *p) temp = 0xff; break; } - - pclog("ps2_read: port=%04x temp=%02x\n", port, temp); + + /* pclog("ps2_read: port=%04x temp=%02x\n", port, temp); */ return temp; } static void ps2_mca_write(uint16_t port, uint8_t val, void *p) { - pclog("ps2_write: port=%04x val=%02x %04x:%04x\n", port, val, CS,cpu_state.pc); + /* pclog("ps2_write: port=%04x val=%02x %04x:%04x\n", port, val, CS,cpu_state.pc); */ switch (port) { @@ -619,18 +619,18 @@ static void mem_encoding_update() if (ps2.mem_regs[1] & 2) { mem_set_mem_state(0xe0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); - pclog("PS/2 Model 80-111: ROM space enabled\n"); + /* pclog("PS/2 Model 80-111: ROM space enabled\n"); */ } else { mem_set_mem_state(0xe0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED); - pclog("PS/2 Model 80-111: ROM space disabled\n"); + /* pclog("PS/2 Model 80-111: ROM space disabled\n"); */ } if (ps2.mem_regs[1] & 4) { mem_mapping_set_addr(&ram_low_mapping, 0x00000, 0x80000); - pclog("PS/2 Model 80-111: 00080000- 0009FFFF disabled\n"); + /* pclog("PS/2 Model 80-111: 00080000- 0009FFFF disabled\n"); */ } else { mem_mapping_set_addr(&ram_low_mapping, 0x00000, 0xa0000); - pclog("PS/2 Model 80-111: 00080000- 0009FFFF enabled\n"); + /* pclog("PS/2 Model 80-111: 00080000- 0009FFFF enabled\n"); */ } if (!(ps2.mem_regs[1] & 8)) @@ -642,10 +642,10 @@ static void mem_encoding_update() mem_split_enable(ps2.split_size, ps2.split_addr); - pclog("PS/2 Model 80-111: Split memory block enabled at %08X\n", ps2.split_addr); - } else { + /* pclog("PS/2 Model 80-111: Split memory block enabled at %08X\n", ps2.split_addr); */ + } /* else { pclog("PS/2 Model 80-111: Split memory block disabled\n"); - } + } */ } static uint8_t mem_encoding_read(uint16_t addr, void *p) @@ -773,7 +773,7 @@ static void ps2_mca_board_model_80_type2_init(int is486) break; } - pclog("ps2.mem_pos_regs[4] = %08X\n", ps2.mem_pos_regs[4]); + /* pclog("ps2.mem_pos_regs[4] = %08X\n", ps2.mem_pos_regs[4]); */ mca_add(ps2_mem_expansion_read, ps2_mem_expansion_write, NULL); mem_mapping_add(&ps2.expansion_mapping, @@ -802,7 +802,7 @@ machine_ps2_common_init(machine_t *model) dma16_init(); ps2_dma_init(); - device_add(&keyboard_ps2_device); + device_add(&keyboard_ps2_mca_device); nvr_at_init(8); pic2_init(); diff --git a/src/machine/machine.h b/src/machine/machine.h index 38c1da3b5..b659f4fe0 100644 --- a/src/machine/machine.h +++ b/src/machine/machine.h @@ -8,15 +8,15 @@ * * Handling of the emulated machines. * - * Version: @(#)machine.h 1.0.15 2017/12/25 + * Version: @(#)machine.h 1.0.16 2018/01/04 * * Authors: Sarah Walker, * Miran Grca, * Fred N. van Kempen, * - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016,2017 Miran Grca. - * Copyright 2017 Fred N. van Kempen. + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016,2018 Miran Grca. + * Copyright 2018 Fred N. van Kempen. */ #ifndef EMU_MACHINE_H # define EMU_MACHINE_H @@ -95,8 +95,12 @@ extern void machine_close(void); /* Initialization functions for boards and systems. */ extern void machine_common_init(machine_t *); +extern void machine_at_common_init(machine_t *); extern void machine_at_init(machine_t *); +extern void machine_at_ps2_init(machine_t *); +extern void machine_at_common_ide_init(machine_t *); extern void machine_at_ide_init(machine_t *); +extern void machine_at_ps2_ide_init(machine_t *); extern void machine_at_top_remap_init(machine_t *); extern void machine_at_ide_top_remap_init(machine_t *); @@ -133,7 +137,9 @@ extern void machine_at_cmdpc_init(machine_t *); extern void machine_at_headland_init(machine_t *); extern void machine_at_neat_init(machine_t *); +extern void machine_at_neat_ami_init(machine_t *); extern void machine_at_opti495_init(machine_t *); +extern void machine_at_opti495_ami_init(machine_t *); extern void machine_at_scat_init(machine_t *); extern void machine_at_compaq_init(machine_t *); diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 05d4b7888..dd1dd78dd 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -11,7 +11,7 @@ * NOTES: OpenAT wip for 286-class machine with open BIOS. * PS2_M80-486 wip, pending receipt of TRM's for machine. * - * Version: @(#)machine_table.c 1.0.10 2018/01/01 + * Version: @(#)machine_table.c 1.0.11 2018/01/04 * * Authors: Sarah Walker, * Miran Grca, @@ -58,7 +58,7 @@ machine_t machines[] = { { "[8086] Tandy 1000 SL/2", ROM_TANDY1000SL2, "tandy1000sl2", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA, 512, 768, 128, 0, machine_tandy1k_init, NULL, NULL }, { "[8086] VTech Laser XT3", ROM_LXT3, "lxt3", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 512, 1152, 128, 0, machine_xt_laserxt_init, NULL, NULL }, - { "[286 ISA] AMI 286 clone", ROM_AMI286, "ami286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 127, machine_at_neat_init, NULL, nvr_at_close }, + { "[286 ISA] AMI 286 clone", ROM_AMI286, "ami286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 127, machine_at_neat_ami_init, NULL, nvr_at_close }, { "[286 ISA] Award 286 clone", ROM_AWARD286, "award286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 127, machine_at_scat_init, NULL, nvr_at_close }, { "[286 ISA] Commodore PC 30 III", ROM_CMDPC30, "cmdpc30", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 640,16384, 128, 127, machine_at_cmdpc_init, NULL, nvr_at_close }, { "[286 ISA] Compaq Portable II", ROM_PORTABLEII, "portableii", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 640,16384, 128, 127, machine_at_compaq_init, NULL, nvr_at_close }, @@ -89,10 +89,10 @@ machine_t machines[] = { { "[386SX MCA] IBM PS/2 model 55SX", ROM_IBMPS2_M55SX, "ibmps2_m55sx", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 1, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC_PS2, 1, 8, 1, 63, machine_ps2_model_55sx_init, NULL, nvr_at_close }, - { "[386DX ISA] AMI 386DX clone", ROM_AMI386DX_OPTI495, "ami386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_opti495_init, NULL, nvr_at_close }, + { "[386DX ISA] AMI 386DX clone", ROM_AMI386DX_OPTI495, "ami386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_opti495_ami_init, NULL, nvr_at_close }, { "[386DX ISA] Amstrad MegaPC 386DX", ROM_MEGAPCDX, "megapcdx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 1, 16, 1, 127, machine_at_wd76c10_init, NULL, nvr_at_close }, { "[386DX ISA] Award 386DX clone", ROM_AWARD386DX_OPTI495, "award386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_opti495_init, NULL, nvr_at_close }, - { "[386DX ISA] MR 386DX clone", ROM_MR386DX_OPTI495, "mr386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_opti495_init, NULL, nvr_at_close }, + { "[386DX ISA] MR 386DX clone", ROM_MR386DX_OPTI495, "mr386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_opti495_ami_init, NULL, nvr_at_close }, #ifdef DEV_BRANCH #ifdef USE_PORTABLE3 { "[386DX ISA] Compaq Portable III (386)", ROM_PORTABLEIII386, "portableiii386", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_HDC | MACHINE_VIDEO, 1, 14, 1, 127, machine_at_compaq_init, NULL, nvr_at_close }, diff --git a/src/pc.c b/src/pc.c index 35f30e11e..890395ed7 100644 --- a/src/pc.c +++ b/src/pc.c @@ -665,7 +665,7 @@ pc_keyboard_send(uint8_t val) { if (AT) keyboard_at_adddata_keyboard_raw(val); - else + else keyboard_send(val); } @@ -690,9 +690,9 @@ pc_send_cae(void) pc_keyboard_send(29); /* Ctrl key pressed */ pc_keyboard_send(56); /* Alt key pressed */ pc_keyboard_send(1); /* Esc key pressed */ - pc_keyboard_send(157); /* Ctrl key released */ - pc_keyboard_send(184); /* Alt key released */ pc_keyboard_send(129); /* Esc key released */ + pc_keyboard_send(184); /* Alt key released */ + pc_keyboard_send(157); /* Ctrl key released */ } diff --git a/src/sio_fdc37c93x.c b/src/sio_fdc37c93x.c index 83fb2a511..b7a087882 100644 --- a/src/sio_fdc37c93x.c +++ b/src/sio_fdc37c93x.c @@ -9,7 +9,7 @@ * Implementation of the SMC FDC37C932FR and FDC37C935 Super * I/O Chips. * - * Version: @(#)sio_fdc37c93x.c 1.0.9 2017/12/28 + * Version: @(#)sio_fdc37c93x.c 1.0.10 2018/01/04 * * Author: Miran Grca, * Copyright 2016,2017 Miran Grca. @@ -71,6 +71,7 @@ static void fdc37c93x_fdc_handler(void) uint8_t local_enable = !!fdc37c93x_ld_regs[0][0x30]; fdc_remove(); + /* pclog("fdc37c93x: Removing FDC (%i, %i)\n", global_enable, local_enable); */ if (global_enable && local_enable) { ld_port = make_port(0); @@ -121,11 +122,10 @@ static void fdc37c93x_auxio_handler(void) { uint16_t ld_port = 0; - uint8_t global_enable = !!(fdc37c93x_regs[0x22] & (1 << 3)); uint8_t local_enable = !!fdc37c93x_ld_regs[3][0x30]; io_removehandler(fdc37c93x_gpio_base, 0x0001, fdc37c93x_gpio_read, NULL, NULL, fdc37c93x_gpio_write, NULL, NULL, NULL); - if (global_enable && local_enable) + if (local_enable) { fdc37c93x_gpio_base = ld_port = make_port(3); /* pclog("fdc37c93x: Setting Auxiliary I/O port to %04X\n", ld_port); */ @@ -440,8 +440,9 @@ static void fdc37c93x_reset(void) memset(fdc37c93x_regs, 0, 48); - fdc37c93x_regs[3] = 3; + fdc37c93x_regs[0x03] = 3; fdc37c93x_regs[0x21] = 1; + fdc37c93x_regs[0x22] = 0x39; fdc37c93x_regs[0x24] = 4; fdc37c93x_regs[0x26] = 0xF0; fdc37c93x_regs[0x27] = 3;