Some minor fixes, the PS/2 mouse command F0h (set remote mode) is now implemented, the PS/2 mouse command F3h (set sample rate) now actually changes the host mouse polling rate, and the Intel SIO IB and ZB now forcibly initialize a keyboard and mouse IRQ latch if the board has a PS/2 keyboard controller, to simulate the presence of a latch external to the chip.
This commit is contained in:
@@ -200,9 +200,11 @@ sio_write(int func, int addr, uint8_t val, void *priv)
|
||||
dev->regs[addr] = val;
|
||||
break;
|
||||
case 0x4c:
|
||||
dev->regs[addr] = (val & 0x7f);
|
||||
break;
|
||||
case 0x4d:
|
||||
dev->regs[addr] = (val & 0x7f);
|
||||
pic_mouse_latch(!!(val & 0x10));
|
||||
// pic_mouse_latch(!!(val & 0x10));
|
||||
break;
|
||||
case 0x4f:
|
||||
dev->regs[addr] = val;
|
||||
@@ -394,7 +396,7 @@ sio_reset_hard(void *priv)
|
||||
dev->regs[0x4b] = 0x0f;
|
||||
dev->regs[0x4c] = 0x56;
|
||||
dev->regs[0x4d] = 0x40;
|
||||
pic_mouse_latch(0x00);
|
||||
// pic_mouse_latch(0x00);
|
||||
dev->regs[0x4e] = 0x07;
|
||||
dev->regs[0x4f] = 0x4f;
|
||||
dev->regs[0x57] = 0x04;
|
||||
@@ -544,7 +546,19 @@ sio_init(const device_t *info)
|
||||
|
||||
// device_add(&i8254_sec_device);
|
||||
|
||||
pic_kbd_latch(0x01);
|
||||
// pic_kbd_latch(0x01);
|
||||
|
||||
/* The situation is as follow: SIO.AB has the IRQ 1 latch but SIO.IB and SIO.ZB do not,
|
||||
and I suspect that because of that, the IRQ 12 latch on SIO.IB and SIO.ZB, while
|
||||
evidently planned and documented in the datashet, was basically non-functional, and
|
||||
motherboard manufacturers had to install their own latches to use PS/2 keyboards
|
||||
and/or mice. One such example is the AMI Excalibur PCI Pentium, which never enables
|
||||
the SIO.ZB's IRQ 12 latch but clearly expects one since otherwise, the PS/2 mouse
|
||||
behaves erractically in the WinBIOS CMOS Setup. */
|
||||
if (machine_has_bus(machine, MACHINE_BUS_PS2)) {
|
||||
pic_kbd_latch(0x01);
|
||||
pic_mouse_latch(0x01);
|
||||
}
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
@@ -1024,7 +1024,7 @@ write64_ami(void *priv, uint8_t val)
|
||||
kbc_at_queue_add(dev, 0x28);
|
||||
kbc_at_queue_add(dev, 0x00);
|
||||
dev->state = STATE_KBC_OUT;
|
||||
break;
|
||||
return 0;
|
||||
|
||||
case 0xa1: /* get controller version */
|
||||
kbc_at_log("ATkbc: AMI - get controller version\n");
|
||||
@@ -1118,6 +1118,7 @@ write64_ami(void *priv, uint8_t val)
|
||||
add_to_kbc_queue_front(dev, 0x00, 0, 0x00);
|
||||
return 0;
|
||||
|
||||
/* TODO: The ICS SB486PV sends command B4 but expects to read *TWO* bytes. */
|
||||
case 0xb4: case 0xb5:
|
||||
/* set KBC lines P22-P23 (P2 bits 2-3) low */
|
||||
kbc_at_log("ATkbc: set KBC lines P22-P23 (P2 bits 2-3) low\n");
|
||||
|
@@ -173,9 +173,9 @@ kbc_at_dev_reset(atkbc_dev_t *dev, int do_fa)
|
||||
if (do_fa)
|
||||
kbc_at_dev_queue_add(dev, 0xfa, 0);
|
||||
|
||||
dev->execute_bat(dev);
|
||||
|
||||
dev->state = DEV_STATE_MAIN_OUT;
|
||||
|
||||
dev->execute_bat(dev);
|
||||
}
|
||||
|
||||
atkbc_dev_t *
|
||||
|
@@ -102,6 +102,8 @@ static int mouse_nbut;
|
||||
static int (*mouse_dev_poll)(int x, int y, int z, int b, void *priv);
|
||||
static void (*mouse_poll_ex)(void) = NULL;
|
||||
|
||||
static double sample_rate = 200.0;
|
||||
|
||||
#ifdef ENABLE_MOUSE_LOG
|
||||
int mouse_do_log = ENABLE_MOUSE_LOG;
|
||||
|
||||
@@ -153,7 +155,7 @@ static void
|
||||
mouse_timer_poll(void *priv)
|
||||
{
|
||||
/* Poll at 255 Hz, maximum supported by PS/2 mic. */
|
||||
timer_on_auto(&mouse_timer, 1000000.0 / 255.0);
|
||||
timer_on_auto(&mouse_timer, 1000000.0 / sample_rate);
|
||||
|
||||
#ifdef USE_GDBSTUB /* avoid a KBC FIFO overflow when CPU emulation is stalled */
|
||||
if (gdbstub_step == GDBSTUB_EXEC)
|
||||
@@ -161,6 +163,15 @@ mouse_timer_poll(void *priv)
|
||||
mouse_process();
|
||||
}
|
||||
|
||||
void
|
||||
mouse_set_sample_rate(double new_rate)
|
||||
{
|
||||
timer_stop(&mouse_timer);
|
||||
|
||||
sample_rate = new_rate;
|
||||
timer_on_auto(&mouse_timer, 1000000.0 / sample_rate);
|
||||
}
|
||||
|
||||
void
|
||||
mouse_reset(void)
|
||||
{
|
||||
@@ -179,15 +190,16 @@ mouse_reset(void)
|
||||
if (mouse_type == 0)
|
||||
return;
|
||||
|
||||
timer_add(&mouse_timer, mouse_timer_poll, NULL, 0);
|
||||
|
||||
/* Poll at 100 Hz, the default of a PS/2 mouse. */
|
||||
sample_rate = 100.0;
|
||||
timer_on_auto(&mouse_timer, 1000000.0 / sample_rate);
|
||||
|
||||
mouse_curr = mouse_devices[mouse_type].device;
|
||||
|
||||
if (mouse_curr != NULL)
|
||||
mouse_priv = device_add(mouse_curr);
|
||||
|
||||
timer_add(&mouse_timer, mouse_timer_poll, NULL, 0);
|
||||
|
||||
/* Poll at 255 Hz, maximum supported by PS/2 mic. */
|
||||
timer_on_auto(&mouse_timer, 1000000.0 / 255.0);
|
||||
}
|
||||
|
||||
/* Callback from the hardware driver. */
|
||||
|
@@ -133,7 +133,9 @@ static void
|
||||
ps2_set_defaults(atkbc_dev_t *dev)
|
||||
{
|
||||
dev->mode = MODE_STREAM;
|
||||
dev->rate = 1;
|
||||
dev->rate = 100;
|
||||
mouse_set_sample_rate(100.0);
|
||||
dev->resolution = 2;
|
||||
dev->flags &= 0x88;
|
||||
mouse_scan = 0;
|
||||
}
|
||||
@@ -177,6 +179,7 @@ ps2_write(void *priv)
|
||||
|
||||
case 0xf3: /* set sample rate */
|
||||
dev->rate = val;
|
||||
mouse_set_sample_rate((double) val);
|
||||
kbc_at_dev_queue_add(dev, 0xfa, 0); /* Command response */
|
||||
mouse_ps2_log("%s: Set sample rate [%02X]\n", dev->name, val);
|
||||
break;
|
||||
@@ -227,6 +230,7 @@ ps2_write(void *priv)
|
||||
case 0xea: /* set stream */
|
||||
mouse_ps2_log("%s: Set stream\n", dev->name);
|
||||
dev->flags &= ~FLAG_CTRLDAT;
|
||||
dev->mode = MODE_STREAM;
|
||||
mouse_scan = 1;
|
||||
kbc_at_dev_queue_add(dev, 0xfa, 0); /* ACK for command byte */
|
||||
break;
|
||||
@@ -238,6 +242,14 @@ ps2_write(void *priv)
|
||||
ps2_report_coordinates(dev, 0);
|
||||
break;
|
||||
|
||||
case 0xf0: /* set remote */
|
||||
mouse_ps2_log("%s: Set remote\n", dev->name);
|
||||
dev->flags &= ~FLAG_CTRLDAT;
|
||||
dev->mode = MODE_REMOTE;
|
||||
mouse_scan = 1;
|
||||
kbc_at_dev_queue_add(dev, 0xfa, 0); /* ACK for command byte */
|
||||
break;
|
||||
|
||||
case 0xf2: /* read ID */
|
||||
mouse_ps2_log("%s: Read ID\n", dev->name);
|
||||
kbc_at_dev_queue_add(dev, 0xfa, 0);
|
||||
|
@@ -80,6 +80,8 @@ extern void mouse_poll(void);
|
||||
|
||||
extern void mouse_bus_set_irq(void *priv, int irq);
|
||||
|
||||
extern void mouse_set_sample_rate(double new_rate);
|
||||
|
||||
extern char *mouse_get_name(int mouse);
|
||||
extern char *mouse_get_internal_name(int mouse);
|
||||
extern int mouse_get_from_internal_name(char *s);
|
||||
|
@@ -202,7 +202,7 @@ find_best_interrupt(pic_t *dev)
|
||||
|
||||
intr = dev->interrupt = (ret == -1) ? 0x17 : ret;
|
||||
|
||||
if (dev->at && (ret != 1)) {
|
||||
if (dev->at && (ret != -1)) {
|
||||
if (dev == &pic2)
|
||||
intr += 8;
|
||||
|
||||
@@ -644,7 +644,7 @@ picint_common(uint16_t num, int level, int set)
|
||||
pic2.lines |= (num >> 8);
|
||||
|
||||
/* Latch IRQ 12 if the mouse latch is enabled. */
|
||||
if (mouse_latch && (num & 0x1000))
|
||||
if ((num & 0x1000) && mouse_latch)
|
||||
pic2.lines |= 0x10;
|
||||
|
||||
pic2.irr |= (num >> 8);
|
||||
|
Reference in New Issue
Block a user