Fixed the "minor bug fix" in the AT / PS/2 keyboard controller, reworked PS/2 keyboard controller IRQ latches, and correctly disabled memory top remaps if there's more than (16 MB - remap size) RAM (fixes segmentation faults on some machines with 16+ MB of RAM).

This commit is contained in:
OBattler
2023-04-11 23:21:52 +02:00
parent 5da3e78fc1
commit ef17003f1b
17 changed files with 194 additions and 107 deletions

View File

@@ -51,7 +51,8 @@ static pc_timer_t pic_timer;
static int shadow = 0, elcr_enabled = 0,
tmr_inited = 0, latched = 0,
pic_pci = 0;
pic_pci = 0, kbd_latch = 0,
mouse_latch = 0;
static uint16_t smi_irq_mask = 0x0000,
smi_irq_status = 0x0000;
@@ -389,6 +390,23 @@ pic_command(pic_t *dev)
dev->auto_eoi_rotate = !!(dev->ocw2 & 0x80);
}
uint8_t
pic_latch_read(uint16_t addr, void *priv)
{
uint8_t ret = 0xff;
pic_log("pic_latch_read(): %02X%02X\n", pic2.lines & 0x10, pic.lines & 0x02);
if (kbd_latch && (pic.lines & 0x02))
picintc(0x0002);
if (mouse_latch && (pic2.lines & 0x10))
picintc(0x1000);
/* Return FF - we just lower IRQ 1 and IRQ 12. */
return ret;
}
uint8_t
pic_read(uint16_t addr, void *priv)
{
@@ -520,10 +538,47 @@ pic_set_pci(void)
}
void
pic_init(void)
pic_kbd_latch(int enable)
{
pic_log("PIC keyboard latch now %sabled\n", enable ? "en" : "dis");
if ((enable | mouse_latch) != (kbd_latch | mouse_latch)) {
kbd_latch = enable;
io_handler(kbd_latch | mouse_latch, 0x0060, 0x0001, pic_latch_read, NULL, NULL, NULL, NULL, NULL, NULL);
}
if (!enable)
picintc(0x0002);
}
void
pic_mouse_latch(int enable)
{
pic_log("PIC mouse latch now %sabled\n", enable ? "en" : "dis");
if ((kbd_latch | enable) != (kbd_latch | mouse_latch)) {
mouse_latch = enable;
io_handler(kbd_latch | mouse_latch, 0x0060, 0x0001, pic_latch_read, NULL, NULL, NULL, NULL, NULL, NULL);
}
if (!enable)
picintc(0x1000);
}
static void
pic_reset_hard(void)
{
pic_reset();
pic_kbd_latch(0x00);
pic_mouse_latch(0x00);
}
void
pic_init(void)
{
pic_reset_hard();
shadow = 0;
io_sethandler(0x0020, 0x0002, pic_read, NULL, NULL, pic_write, NULL, NULL, &pic);
}
@@ -531,7 +586,7 @@ pic_init(void)
void
pic_init_pcjr(void)
{
pic_reset();
pic_reset_hard();
shadow = 0;
io_sethandler(0x0020, 0x0008, pic_read, NULL, NULL, pic_write, NULL, NULL, &pic);
@@ -588,6 +643,10 @@ picint_common(uint16_t num, int level, int set)
if (level)
pic2.lines |= (num >> 8);
/* Latch IRQ 12 if the mouse latch is enabled. */
if (mouse_latch && (num & 0x1000))
pic2.lines |= 0x10;
pic2.irr |= (num >> 8);
}
@@ -595,6 +654,9 @@ picint_common(uint16_t num, int level, int set)
if (level)
pic.lines |= (num & 0x00ff);
if (kbd_latch && (num & 0x0002))
pic.lines |= 0x02;
pic.irr |= (num & 0x00ff);
}
} else {
@@ -602,11 +664,13 @@ picint_common(uint16_t num, int level, int set)
if (num & 0xff00) {
pic2.lines &= ~(num >> 8);
pic2.irr &= ~(num >> 8);
}
if (num & 0x00ff) {
pic.lines &= ~(num & 0x00ff);
pic.irr &= ~(num & 0x00ff);
}
}