More keyboard controller fixes.
This commit is contained in:
@@ -29,6 +29,7 @@
|
||||
#include <86box/device.h>
|
||||
#include <86box/dma.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/keyboard.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/rom.h>
|
||||
#include <86box/nmi.h>
|
||||
@@ -265,9 +266,12 @@ reset_common(int hard)
|
||||
if (is286) {
|
||||
loadcs(0xF000);
|
||||
cpu_state.pc = 0xFFF0;
|
||||
rammask = cpu_16bitbus ? 0xFFFFFF : 0xFFFFFFFF;
|
||||
if (is6117)
|
||||
rammask |= 0x03000000;
|
||||
if (hard) {
|
||||
rammask = cpu_16bitbus ? 0xFFFFFF : 0xFFFFFFFF;
|
||||
if (is6117)
|
||||
rammask |= 0x03000000;
|
||||
mem_a20_key = mem_a20_alt = mem_a20_state = 0;
|
||||
}
|
||||
}
|
||||
idt.base = 0;
|
||||
cpu_state.flags = 2;
|
||||
@@ -315,6 +319,10 @@ reset_common(int hard)
|
||||
cache_index = 0;
|
||||
memset(_tr, 0x00, sizeof(_tr));
|
||||
memset(_cache, 0x00, sizeof(_cache));
|
||||
|
||||
/* If we have an AT or PS/2 keyboard controller, make sure the A20 state
|
||||
is correct. */
|
||||
kbc_at_a20_reset();
|
||||
}
|
||||
|
||||
if (!is286)
|
||||
|
@@ -878,6 +878,8 @@ kbc_scan_kbd_at(atkbd_t *dev)
|
||||
}
|
||||
}
|
||||
|
||||
static void write_output(atkbd_t *dev, uint8_t val);
|
||||
|
||||
static void
|
||||
kbc_poll_at(atkbd_t *dev)
|
||||
{
|
||||
@@ -905,8 +907,12 @@ kbc_poll_at(atkbd_t *dev)
|
||||
break;
|
||||
case KBC_STATE_MAIN_KBD:
|
||||
case KBC_STATE_MAIN_BOTH:
|
||||
(void) kbc_scan_kbd_at(dev);
|
||||
dev->kbc_state = KBC_STATE_MAIN_IBF;
|
||||
if (dev->status & STAT_IFULL)
|
||||
kbc_ibf_process(dev);
|
||||
else {
|
||||
(void) kbc_scan_kbd_at(dev);
|
||||
dev->kbc_state = KBC_STATE_MAIN_IBF;
|
||||
}
|
||||
break;
|
||||
case KBC_STATE_KBC_OUT:
|
||||
/* Keyboard controller command want to output multiple bytes. */
|
||||
@@ -1013,13 +1019,21 @@ kbc_poll_ps2(atkbd_t *dev)
|
||||
break;
|
||||
case KBC_STATE_MAIN_KBD:
|
||||
// pclog("KBC_STATE_MAIN_KBD\n");
|
||||
(void) kbc_scan_kbd_ps2(dev);
|
||||
dev->kbc_state = KBC_STATE_MAIN_IBF;
|
||||
if (dev->status & STAT_IFULL)
|
||||
kbc_ibf_process(dev);
|
||||
else {
|
||||
(void) kbc_scan_kbd_ps2(dev);
|
||||
dev->kbc_state = KBC_STATE_MAIN_IBF;
|
||||
}
|
||||
break;
|
||||
case KBC_STATE_MAIN_MOUSE:
|
||||
// pclog("KBC_STATE_MAIN_MOUSE\n");
|
||||
(void) kbc_scan_aux_ps2(dev);
|
||||
dev->kbc_state = KBC_STATE_MAIN_IBF;
|
||||
if (dev->status & STAT_IFULL)
|
||||
kbc_ibf_process(dev);
|
||||
else {
|
||||
(void) kbc_scan_aux_ps2(dev);
|
||||
dev->kbc_state = KBC_STATE_MAIN_IBF;
|
||||
}
|
||||
break;
|
||||
case KBC_STATE_MAIN_BOTH:
|
||||
// pclog("KBC_STATE_MAIN_BOTH\n");
|
||||
@@ -2230,7 +2244,9 @@ write64_toshiba(void *priv, uint8_t val)
|
||||
static void
|
||||
kbd_key_reset(atkbd_t *dev, int do_fa)
|
||||
{
|
||||
dev->out_new = -1;
|
||||
kbc_queue_reset(1);
|
||||
|
||||
kbd_last_scan_code = 0x00;
|
||||
|
||||
/* Set scan code set to 2. */
|
||||
@@ -2253,6 +2269,7 @@ kbd_key_reset(atkbd_t *dev, int do_fa)
|
||||
static void
|
||||
kbd_aux_reset(atkbd_t *dev, int do_fa)
|
||||
{
|
||||
dev->out_new_mouse = -1;
|
||||
kbc_queue_reset(2);
|
||||
|
||||
mouse_scan = 1;
|
||||
@@ -2475,7 +2492,15 @@ kbc_process_cmd(void *priv)
|
||||
kbd_log("ATkbc: self-test\n");
|
||||
|
||||
if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) {
|
||||
dev->status = 0x60;
|
||||
if (dev->kbc_state != KBC_STATE_RESET) {
|
||||
kbd_log("ATkbc: self-test reinitialization\n");
|
||||
/* Yes, the firmware has an OR, but we need to make sure to keep any forcibly lowered bytes lowered. */
|
||||
/* TODO: Proper P1 implementation, with OR and AND flags in the machine table. */
|
||||
dev->input_port = dev->input_port & 0xff;
|
||||
write_output(dev, 0x4b);
|
||||
}
|
||||
|
||||
dev->status = (dev->status & 0x0f) | 0x60;
|
||||
|
||||
dev->mem[0x20] = 0x30;
|
||||
dev->mem[0x21] = 0x01;
|
||||
@@ -2497,7 +2522,7 @@ kbc_process_cmd(void *priv)
|
||||
write_output(dev, 0xcf);
|
||||
}
|
||||
|
||||
dev->status = 0x60;
|
||||
dev->status = (dev->status & 0x0f) | 0x60;
|
||||
|
||||
dev->mem[0x20] = 0x10;
|
||||
dev->mem[0x21] = 0x01;
|
||||
@@ -2511,10 +2536,14 @@ kbc_process_cmd(void *priv)
|
||||
dev->mem[0x2c] = 0x15;
|
||||
}
|
||||
|
||||
dev->out_new = dev->out_new_mouse = -1;
|
||||
kbc_queue_reset(0);
|
||||
dev->kbc_state = KBC_STATE_MAIN_IBF;
|
||||
|
||||
add_to_kbc_queue_front(dev, 0x55, 0, 0x00);
|
||||
// dev->kbc_state = KBC_STATE_MAIN_IBF;
|
||||
dev->kbc_state = KBC_STATE_KBC_OUT;
|
||||
|
||||
// add_to_kbc_queue_front(dev, 0x55, 0, 0x00);
|
||||
kbc_queue_add(dev, 0x55, 0);
|
||||
break;
|
||||
|
||||
case 0xab: /* interface test */
|
||||
@@ -2814,6 +2843,7 @@ kbd_reset(void *priv)
|
||||
dev->ami_flags = ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) ? 0x01 : 0x00;
|
||||
dev->ami_stat |= 0x02;
|
||||
|
||||
dev->output_port = 0xcd;
|
||||
if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) {
|
||||
write_output(dev, 0x4b);
|
||||
} else {
|
||||
@@ -2841,6 +2871,20 @@ keyboard_at_reset(void)
|
||||
kbd_reset(SavedKbd);
|
||||
}
|
||||
|
||||
void
|
||||
kbc_at_a20_reset(void)
|
||||
{
|
||||
if (SavedKbd) {
|
||||
SavedKbd->output_port = 0xcd;
|
||||
if ((SavedKbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) {
|
||||
write_output(SavedKbd, 0x4b);
|
||||
} else {
|
||||
/* The real thing writes CF and then AND's it with BF. */
|
||||
write_output(SavedKbd, 0x8f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
kbd_close(void *priv)
|
||||
{
|
||||
|
@@ -210,6 +210,7 @@ extern void keyboard_at_set_mode(int ps2);
|
||||
extern uint8_t keyboard_at_get_mouse_scan(void);
|
||||
extern void keyboard_at_set_mouse_scan(uint8_t val);
|
||||
extern void keyboard_at_reset(void);
|
||||
extern void kbc_at_a20_reset(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@@ -2530,11 +2530,12 @@ void
|
||||
mem_a20_init(void)
|
||||
{
|
||||
if (is286) {
|
||||
rammask = cpu_16bitbus ? 0xefffff : 0xffefffff;
|
||||
mem_a20_key = mem_a20_alt = mem_a20_state = 0;
|
||||
rammask = cpu_16bitbus ? 0xffffff : 0xffffffff;
|
||||
if (is6117)
|
||||
rammask |= 0x03000000;
|
||||
flushmmucache();
|
||||
mem_a20_state = mem_a20_key | mem_a20_alt;
|
||||
// mem_a20_state = mem_a20_key | mem_a20_alt;
|
||||
} else {
|
||||
rammask = 0xfffff;
|
||||
flushmmucache();
|
||||
|
Reference in New Issue
Block a user