Fixed the keyboard controller reset state, fixes Xi8088.

This commit is contained in:
OBattler
2023-04-08 03:11:53 +02:00
parent c0be988ec4
commit d4b57298ad
2 changed files with 88 additions and 36 deletions

View File

@@ -37,7 +37,6 @@
#include <86box/mem.h> #include <86box/mem.h>
#include <86box/device.h> #include <86box/device.h>
#include <86box/machine.h> #include <86box/machine.h>
#include <86box/m_xt_xi8088.h>
#include <86box/m_at_t3100e.h> #include <86box/m_at_t3100e.h>
#include <86box/fdd.h> #include <86box/fdd.h>
#include <86box/fdc.h> #include <86box/fdc.h>
@@ -81,15 +80,15 @@
#define KBC_VEN_IBM_MCA 0x08 #define KBC_VEN_IBM_MCA 0x08
#define KBC_VEN_QUADTEL 0x0c #define KBC_VEN_QUADTEL 0x0c
#define KBC_VEN_TOSHIBA 0x10 #define KBC_VEN_TOSHIBA 0x10
#define KBC_VEN_XI8088 0x14 #define KBC_VEN_IBM_PS1 0x14
#define KBC_VEN_IBM_PS1 0x18 #define KBC_VEN_ACER 0x18
#define KBC_VEN_ACER 0x1c #define KBC_VEN_INTEL_AMI 0x1c
#define KBC_VEN_INTEL_AMI 0x20 #define KBC_VEN_OLIVETTI 0x20
#define KBC_VEN_OLIVETTI 0x24 #define KBC_VEN_NCR 0x24
#define KBC_VEN_NCR 0x28 #define KBC_VEN_PHOENIX 0x28
#define KBC_VEN_SAMSUNG 0x2c #define KBC_VEN_ALI 0x2c
#define KBC_VEN_ALI 0x30 #define KBC_VEN_TG 0x30
#define KBC_VEN_PHOENIX 0x3c #define KBC_VEN_TG_GREEN 0x34
#define KBC_VEN_MASK 0x3c #define KBC_VEN_MASK 0x3c
enum { enum {
@@ -109,9 +108,9 @@ typedef struct {
output_port, old_output_port, key_command, output_locked, output_port, old_output_port, key_command, output_locked,
ami_stat, want60, key_wantdata, ami_flags, ami_stat, want60, key_wantdata, ami_flags,
key_wantcmd, key_dat, mouse_wantcmd, mouse_dat, key_wantcmd, key_dat, mouse_wantcmd, mouse_dat,
kbc_state, kbd_state, mouse_state, pad; kbc_state, kbd_state, mouse_state, pci;
uint16_t irq_levels, pad0; uint16_t irq_levels, pad;
uint8_t mem[0x100]; uint8_t mem[0x100];
@@ -713,7 +712,8 @@ add_to_kbc_queue_front(atkbd_t *dev, uint8_t val, uint8_t channel, uint8_t stat_
{ {
uint8_t kbc_ven = dev->flags & KBC_VEN_MASK; uint8_t kbc_ven = dev->flags & KBC_VEN_MASK;
if ((kbc_ven == KBC_VEN_AMI) || ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF)) if ((kbc_ven == KBC_VEN_AMI) || (kbc_ven == KBC_VEN_TG) ||
(kbc_ven == KBC_VEN_TG_GREEN) || ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF))
stat_hi |= ((dev->input_port & 0x80) ? 0x10 : 0x00); stat_hi |= ((dev->input_port & 0x80) ? 0x10 : 0x00);
else else
stat_hi |= 0x10; stat_hi |= 0x10;
@@ -870,9 +870,10 @@ kbc_poll_at(atkbd_t *dev)
{ {
switch (dev->kbc_state) { switch (dev->kbc_state) {
case KBC_STATE_RESET: case KBC_STATE_RESET:
if ((dev->status & STAT_IFULL) && (dev->status & STAT_CD) && (dev->ib == 0xaa)) { if (dev->status & STAT_IFULL) {
dev->status &= ~STAT_IFULL; dev->status = ((dev->status & 0x0f) | 0x10) & ~STAT_IFULL;
kbc_process_cmd(dev); if ((dev->status & STAT_CD) && (dev->ib == 0xaa))
kbc_process_cmd(dev);
} }
break; break;
case KBC_STATE_NORMAL: case KBC_STATE_NORMAL:
@@ -951,9 +952,10 @@ kbc_poll_ps2(atkbd_t *dev)
{ {
switch (dev->kbc_state) { switch (dev->kbc_state) {
case KBC_STATE_RESET: case KBC_STATE_RESET:
if ((dev->status & STAT_IFULL) && (dev->status & STAT_CD) && (dev->ib == 0xaa)) { if (dev->status & STAT_IFULL) {
dev->status &= ~STAT_IFULL; dev->status = ((dev->status & 0x0f) | 0x10) & ~STAT_IFULL;
kbc_process_cmd(dev); if ((dev->status & STAT_CD) && (dev->ib == 0xaa))
kbc_process_cmd(dev);
} }
break; break;
case KBC_STATE_NORMAL: case KBC_STATE_NORMAL:
@@ -1451,13 +1453,15 @@ write_cmd(atkbd_t *dev, uint8_t val)
/* ISA AT keyboard controllers use bit 5 for keyboard mode (1 = PC/XT, 2 = AT); /* 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. PS/2 (and EISA/PCI) keyboard controllers use it as the PS/2 mouse enable switch.
The AMIKEY firmware apparently uses this bit for something else. */ The AMIKEY firmware apparently uses this bit for something else. */
if ((kbc_ven == KBC_VEN_AMI) || ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF)) { if ((kbc_ven == KBC_VEN_AMI) || (kbc_ven == KBC_VEN_TG) ||
(kbc_ven == KBC_VEN_TG_GREEN) || ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF)) {
keyboard_mode &= ~CCB_PCMODE; keyboard_mode &= ~CCB_PCMODE;
kbd_log("ATkbc: mouse interrupt is now %s\n", (val & 0x02) ? "enabled" : "disabled"); kbd_log("ATkbc: mouse interrupt is now %s\n", (val & 0x02) ? "enabled" : "disabled");
} }
if ((kbc_ven == KBC_VEN_AMI) || ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF)) { if ((kbc_ven == KBC_VEN_AMI) || (kbc_ven == KBC_VEN_TG) ||
(kbc_ven == KBC_VEN_TG_GREEN) || ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF)) {
/* Update the output port to mirror the IBF and OBF bits, if active. */ /* Update the output port to mirror the IBF and OBF bits, if active. */
write_output(dev, (dev->output_port & 0x0f) | ((val & 0x03) << 4) | ((val & 0x20) ? 0xc0 : 0x00)); write_output(dev, (dev->output_port & 0x0f) | ((val & 0x03) << 4) | ((val & 0x20) ? 0xc0 : 0x00));
} }
@@ -1559,7 +1563,16 @@ write64_generic(void *priv, uint8_t val)
0, 0x00); 0, 0x00);
dev->input_port = ((dev->input_port + 1) & 3) | (dev->input_port & 0xfc); dev->input_port = ((dev->input_port + 1) & 3) | (dev->input_port & 0xfc);
} else { } else {
if (((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) && ((dev->flags & KBC_VEN_MASK) != KBC_VEN_INTEL_AMI)) if ((kbc_ven == KBC_VEN_TG) || (kbc_ven == KBC_VEN_TG_GREEN)) {
/* Bit 3, 2:
1, 1: TriGem logo;
1, 0: Garbled logo;
0, 1: Epson logo;
0, 0: Generic AMI logo. */
if (dev->pci)
fixed_bits |= 8;
add_to_kbc_queue_front(dev, dev->input_port | fixed_bits, 0, 0x00);
} else if (((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) && ((dev->flags & KBC_VEN_MASK) != KBC_VEN_INTEL_AMI))
#if 0 #if 0
add_to_kbc_queue_front(dev, (dev->input_port | fixed_bits) & add_to_kbc_queue_front(dev, (dev->input_port | fixed_bits) &
(((dev->flags & KBC_VEN_MASK) == KBC_VEN_ACER) ? 0xeb : 0xef), 0, 0x00); (((dev->flags & KBC_VEN_MASK) == KBC_VEN_ACER) ? 0xeb : 0xef), 0, 0x00);
@@ -1671,18 +1684,25 @@ write64_ami(void *priv, uint8_t val)
case 0xa1: /* get controller version */ case 0xa1: /* get controller version */
kbd_log("ATkbc: AMI - get controller version\n"); kbd_log("ATkbc: AMI - get controller version\n");
if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) { if ((kbc_ven == KBC_VEN_TG) || (kbc_ven == KBC_VEN_TG_GREEN))
add_to_kbc_queue_front(dev, 'Z', 0, 0x00);
else if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) {
if (kbc_ven == KBC_VEN_ALI) if (kbc_ven == KBC_VEN_ALI)
add_to_kbc_queue_front(dev, 'F', 0, 0x00); add_to_kbc_queue_front(dev, 'F', 0, 0x00);
else if ((dev->flags & KBC_VEN_MASK) == KBC_VEN_INTEL_AMI) else if ((dev->flags & KBC_VEN_MASK) == KBC_VEN_INTEL_AMI)
add_to_kbc_queue_front(dev, '5', 0, 0x00); add_to_kbc_queue_front(dev, '5', 0, 0x00);
else if (is_pentium) else if (cpu_64bitbus)
add_to_kbc_queue_front(dev, 'R', 0, 0x00); add_to_kbc_queue_front(dev, 'R', 0, 0x00);
else if (is486)
add_to_kbc_queue_front(dev, 'P', 0, 0x00);
else else
add_to_kbc_queue_front(dev, 'H', 0, 0x00); add_to_kbc_queue_front(dev, 'H', 0, 0x00);
} else if (is386 && !is486) } else if (is386 && !is486) {
add_to_kbc_queue_front(dev, 'B', 0, 0x00); if (cpu_16bitbus)
else if (!is386) add_to_kbc_queue_front(dev, 'D', 0, 0x00);
else
add_to_kbc_queue_front(dev, 'B', 0, 0x00);
} else if (!is386)
add_to_kbc_queue_front(dev, '8', 0, 0x00); add_to_kbc_queue_front(dev, '8', 0, 0x00);
else else
add_to_kbc_queue_front(dev, 'F', 0, 0x00); add_to_kbc_queue_front(dev, 'F', 0, 0x00);
@@ -2583,7 +2603,7 @@ kbd_reset(void *priv)
dev->key_wantdata = 0; dev->key_wantdata = 0;
/* Set up the correct Video Type bits. */ /* Set up the correct Video Type bits. */
if ((kbc_ven == KBC_VEN_XI8088) || (kbc_ven == KBC_VEN_ACER)) if (!is286 || (kbc_ven == KBC_VEN_ACER))
dev->input_port = video_is_mda() ? 0xb0 : 0xf0; dev->input_port = video_is_mda() ? 0xb0 : 0xf0;
else else
dev->input_port = video_is_mda() ? 0xf0 : 0xb0; dev->input_port = video_is_mda() ? 0xf0 : 0xb0;
@@ -2664,6 +2684,7 @@ kbd_init(const device_t *info)
memset(dev, 0x00, sizeof(atkbd_t)); memset(dev, 0x00, sizeof(atkbd_t));
dev->flags = info->local; dev->flags = info->local;
dev->pci = !!(info->flags & DEVICE_PCI);
video_reset(gfxcard[0]); video_reset(gfxcard[0]);
kbd_reset(dev); kbd_reset(dev);
@@ -2683,7 +2704,6 @@ kbd_init(const device_t *info)
case KBC_VEN_GENERIC: case KBC_VEN_GENERIC:
case KBC_VEN_NCR: case KBC_VEN_NCR:
case KBC_VEN_IBM_PS1: case KBC_VEN_IBM_PS1:
case KBC_VEN_XI8088:
dev->write64_ven = write64_generic; dev->write64_ven = write64_generic;
break; break;
@@ -2693,8 +2713,9 @@ kbd_init(const device_t *info)
case KBC_VEN_AMI: case KBC_VEN_AMI:
case KBC_VEN_INTEL_AMI: case KBC_VEN_INTEL_AMI:
case KBC_VEN_SAMSUNG:
case KBC_VEN_ALI: case KBC_VEN_ALI:
case KBC_VEN_TG:
case KBC_VEN_TG_GREEN:
dev->write60_ven = write60_ami; dev->write60_ven = write60_ami;
dev->write64_ven = write64_ami; dev->write64_ven = write64_ami;
break; break;
@@ -2748,11 +2769,11 @@ const device_t keyboard_at_ami_device = {
.config = NULL .config = NULL
}; };
const device_t keyboard_at_samsung_device = { const device_t keyboard_at_tg_ami_device = {
.name = "PC/AT Keyboard (Samsung)", .name = "PC/AT Keyboard (TriGem AMI)",
.internal_name = "keyboard_at_samsung", .internal_name = "keyboard_at_tg_ami",
.flags = 0, .flags = 0,
.local = KBC_TYPE_ISA | KBC_VEN_SAMSUNG, .local = KBC_TYPE_ISA | KBC_VEN_TG,
.init = kbd_init, .init = kbd_init,
.close = kbd_close, .close = kbd_close,
.reset = kbd_reset, .reset = kbd_reset,
@@ -2850,7 +2871,7 @@ const device_t keyboard_ps2_xi8088_device = {
.name = "PS/2 Keyboard (Xi8088)", .name = "PS/2 Keyboard (Xi8088)",
.internal_name = "keyboard_ps2_xi8088", .internal_name = "keyboard_ps2_xi8088",
.flags = 0, .flags = 0,
.local = KBC_TYPE_PS2_1 | KBC_VEN_XI8088, .local = KBC_TYPE_PS2_1 | KBC_VEN_GENERIC,
.init = kbd_init, .init = kbd_init,
.close = kbd_close, .close = kbd_close,
.reset = kbd_reset, .reset = kbd_reset,
@@ -2874,6 +2895,20 @@ const device_t keyboard_ps2_ami_device = {
.config = NULL .config = NULL
}; };
const device_t keyboard_ps2_tg_ami_device = {
.name = "PS/2 Keyboard (TriGem AMI)",
.internal_name = "keyboard_ps2_tg_ami",
.flags = 0,
.local = KBC_TYPE_PS2_NOREF | KBC_VEN_TG,
.init = kbd_init,
.close = kbd_close,
.reset = kbd_reset,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t keyboard_ps2_mca_device = { const device_t keyboard_ps2_mca_device = {
.name = "PS/2 Keyboard", .name = "PS/2 Keyboard",
.internal_name = "keyboard_ps2_mca", .internal_name = "keyboard_ps2_mca",
@@ -2972,6 +3007,20 @@ const device_t keyboard_ps2_intel_ami_pci_device = {
.config = NULL .config = NULL
}; };
const device_t keyboard_ps2_tg_ami_pci_device = {
.name = "PS/2 Keyboard (TriGem AMI)",
.internal_name = "keyboard_ps2_tg_ami_pci",
.flags = DEVICE_PCI,
.local = KBC_TYPE_PS2_NOREF | KBC_VEN_TG,
.init = kbd_init,
.close = kbd_close,
.reset = kbd_reset,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t keyboard_ps2_acer_pci_device = { const device_t keyboard_ps2_acer_pci_device = {
.name = "PS/2 Keyboard (Acer 90M002A)", .name = "PS/2 Keyboard (Acer 90M002A)",
.internal_name = "keyboard_ps2_acer_pci", .internal_name = "keyboard_ps2_acer_pci",

View File

@@ -159,7 +159,7 @@ extern const device_t keyboard_xt_zenith_device;
extern const device_t keyboard_xtclone_device; extern const device_t keyboard_xtclone_device;
extern const device_t keyboard_at_device; extern const device_t keyboard_at_device;
extern const device_t keyboard_at_ami_device; extern const device_t keyboard_at_ami_device;
extern const device_t keyboard_at_samsung_device; extern const device_t keyboard_at_tg_ami_device;
extern const device_t keyboard_at_toshiba_device; extern const device_t keyboard_at_toshiba_device;
extern const device_t keyboard_at_olivetti_device; extern const device_t keyboard_at_olivetti_device;
extern const device_t keyboard_at_ncr_device; extern const device_t keyboard_at_ncr_device;
@@ -168,6 +168,8 @@ extern const device_t keyboard_ps2_ps1_device;
extern const device_t keyboard_ps2_ps1_pci_device; extern const device_t keyboard_ps2_ps1_pci_device;
extern const device_t keyboard_ps2_xi8088_device; extern const device_t keyboard_ps2_xi8088_device;
extern const device_t keyboard_ps2_ami_device; extern const device_t keyboard_ps2_ami_device;
extern const device_t keyboard_ps2_tg_ami_device;
extern const device_t keyboard_ps2_tg_ami_green_device;
extern const device_t keyboard_ps2_olivetti_device; extern const device_t keyboard_ps2_olivetti_device;
extern const device_t keyboard_ps2_mca_device; extern const device_t keyboard_ps2_mca_device;
extern const device_t keyboard_ps2_mca_2_device; extern const device_t keyboard_ps2_mca_2_device;
@@ -177,6 +179,7 @@ extern const device_t keyboard_ps2_ami_pci_device;
extern const device_t keyboard_ps2_intel_ami_pci_device; extern const device_t keyboard_ps2_intel_ami_pci_device;
extern const device_t keyboard_ps2_acer_pci_device; extern const device_t keyboard_ps2_acer_pci_device;
extern const device_t keyboard_ps2_ali_pci_device; extern const device_t keyboard_ps2_ali_pci_device;
extern const device_t keyboard_ps2_tg_ami_pci_device;
#endif /*EMU_DEVICE_H*/ #endif /*EMU_DEVICE_H*/
extern void keyboard_init(void); extern void keyboard_init(void);