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

@@ -180,6 +180,9 @@ ali1489_defaults(ali1489_t *dev)
dev->regs[0x3d] = 0x01;
dev->regs[0x40] = 0x03;
pic_kbd_latch(0x01);
pic_mouse_latch(0x00);
ali1489_shadow_recalc(dev);
cpu_cache_int_enabled = 0;
cpu_cache_ext_enabled = 0;
@@ -295,6 +298,7 @@ ali1489_write(uint16_t addr, uint8_t val, void *priv)
case 0x2a: /* I/O Recovery Register */
dev->regs[dev->index] = val;
pic_mouse_latch(val & 0x80);
break;
case 0x2b: /* Turbo Function Register */

View File

@@ -153,7 +153,8 @@ ali1533_write(int func, int addr, uint8_t val, void *priv)
case 0x41:
/* TODO: Bit 7 selects keyboard controller type:
0 = AT, 1 = PS/2 */
keyboard_at_set_mouse_scan((val & 0x40) ? 1 : 0);
pic_kbd_latch(!!(val & 0x80));
pic_mouse_latch(!!(val & 0x40));
dev->pci_conf[addr] = val & 0xbf;
break;
@@ -454,9 +455,7 @@ ali1533_read(int func, int addr, void *priv)
ret = 0x00;
else {
ret = dev->pci_conf[addr];
if (addr == 0x41)
ret |= (keyboard_at_get_mouse_scan() << 2);
else if (addr == 0x58)
if (addr == 0x58)
ret = (ret & 0xbf) | (dev->ide_dev_enable ? 0x40 : 0x00);
else if ((dev->type == 1) && ((addr >= 0x7c) && (addr <= 0xff)) && !dev->pmu_dev_enable) {
dev->pmu_dev_enable = 1;
@@ -1510,7 +1509,8 @@ ali1543_reset(void *priv)
dev->pci_conf[0x0a] = 0x01;
dev->pci_conf[0x0b] = 0x06;
ali1533_write(0, 0x48, 0x00, dev); // Disables all IRQ's
ali1533_write(0, 0x41, 0x00, dev); /* Disables the keyboard and mouse IRQ latch. */
ali1533_write(0, 0x48, 0x00, dev); /* Disables all IRQ's. */
ali1533_write(0, 0x44, 0x00, dev);
ali1533_write(0, 0x4d, 0x00, dev);
ali1533_write(0, 0x53, 0x00, dev);

View File

@@ -302,6 +302,7 @@ ali6117_reg_write(uint16_t addr, uint8_t val, void *priv)
case 0x36:
val &= 0xf0;
val |= dev->regs[dev->reg_offset];
pic_mouse_latch(val & 0x40);
break;
case 0x37:
@@ -426,6 +427,8 @@ ali6117_reset(void *priv)
/* On-board memory 15-16M is enabled by default. */
mem_set_mem_state_both(0x00f00000, 0x00100000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
ali6117_bank_recalc(dev);
pic_mouse_latch(0x00);
}
}
@@ -475,6 +478,9 @@ ali6117_init(const device_t *info)
}
}
if (!(dev->local & 0x08))
pic_kbd_latch(0x01);
ali6117_reset(dev);
if (!(dev->local & 0x08))

View File

@@ -30,6 +30,7 @@
#include <86box/mem.h>
#include <86box/smram.h>
#include <86box/pci.h>
#include <86box/pic.h>
#include <86box/port_92.h>
#include <86box/chipset.h>
@@ -388,6 +389,9 @@ ims8848_init(const device_t *info)
ims8848_reset(dev);
pic_kbd_latch(0x01);
pic_mouse_latch(0x01);
return dev;
}

View File

@@ -31,6 +31,7 @@
#include <86box/mem.h>
#include <86box/smram.h>
#include <86box/pci.h>
#include <86box/pic.h>
#include <86box/timer.h>
#include <86box/pit.h>
#include <86box/port_92.h>
@@ -217,6 +218,7 @@ i420ex_write(int func, int addr, uint8_t val, void *priv)
break;
case 0x4e:
dev->regs[addr] = (val & 0xf7);
pic_mouse_latch(!!(val & 0x10));
break;
case 0x50:
dev->regs[addr] = (val & 0x0f);
@@ -387,6 +389,7 @@ i420ex_reset_hard(void *priv)
dev->regs[0x4c] = 0x4d;
dev->regs[0x4e] = 0x03;
pic_mouse_latch(0x00);
/* Bits 2:1 of register 50h are 00 is 25 MHz, and 01 if 33 MHz, 10 and 11 are reserved. */
if (cpu_busspeed >= 33333333)
dev->regs[0x50] |= 0x02;
@@ -436,6 +439,9 @@ i420ex_reset(void *p)
i420ex_write(0, 0x48, 0x00, p);
/* Disable the PIC mouse latch. */
i420ex_write(0, 0x4e, 0x03, p);
for (i = 0; i < 7; i++)
i420ex_write(0, 0x59 + i, 0x00, p);
@@ -520,6 +526,8 @@ i420ex_init(const device_t *info)
i420ex_reset_hard(dev);
pic_kbd_latch(0x01);
return dev;
}

View File

@@ -512,7 +512,7 @@ piix_write(int func, int addr, uint8_t val, void *priv)
break;
case 0x4e:
fregs[0x4e] = val;
keyboard_at_set_mouse_scan((val & 0x10) ? 1 : 0);
pic_mouse_latch(!!(val & 0x10));
if (dev->type >= 4)
kbc_alias_update_io_mapping(dev);
break;
@@ -1159,9 +1159,7 @@ piix_read(int func, int addr, void *priv)
if ((func <= dev->max_func) || ((func == 1) && (dev->max_func == 0))) {
fregs = (uint8_t *) dev->regs[func];
ret = fregs[addr];
if ((func == 0) && (addr == 0x4e))
ret |= keyboard_at_get_mouse_scan();
else if ((func == 2) && (addr == 0xff))
if ((func == 2) && (addr == 0xff))
ret |= 0xef;
piix_log("PIIX function %i read: %02X from %02X\n", func, ret, addr);
@@ -1277,6 +1275,7 @@ piix_reset_hard(piix_t *dev)
fregs[0x0e] = ((dev->type > 1) || (dev->rev != 2)) ? 0x80 : 0x00;
fregs[0x4c] = 0x4d;
fregs[0x4e] = 0x03;
pic_mouse_latch(0x00);
fregs[0x60] = fregs[0x61] = fregs[0x62] = fregs[0x63] = 0x80;
fregs[0x64] = (dev->type > 3) ? 0x10 : 0x00;
fregs[0x69] = 0x02;
@@ -1446,6 +1445,9 @@ piix_reset(void *p)
piix_write(0, 0xa8, 0x0f, p);
}
/* Disable the PIC mouse latch. */
piix_write(0, 0x4e, 0x03, p);
if (dev->type == 5)
piix_write(0, 0xe1, 0x40, p);
piix_write(1, 0x04, 0x00, p);
@@ -1532,9 +1534,8 @@ piix_speed_changed(void *priv)
timer_on_auto(&dev->fast_off_timer, ((double) cpu_fast_off_val + 1) * dev->fast_off_period);
}
static void
*
piix_init(const device_t *info)
static void *
piix_init(const device_t *info)
{
piix_t *dev = (piix_t *) malloc(sizeof(piix_t));
memset(dev, 0, sizeof(piix_t));
@@ -1680,6 +1681,8 @@ static void
// device_add(&i8254_sec_device);
pic_kbd_latch(0x01);
return dev;
}

View File

@@ -27,6 +27,7 @@
#include <86box/dma.h>
#include <86box/mem.h>
#include <86box/pci.h>
#include <86box/pic.h>
#include <86box/timer.h>
#include <86box/pit.h>
#include <86box/port_92.h>
@@ -201,6 +202,7 @@ sio_write(int func, int addr, uint8_t val, void *priv)
case 0x4c:
case 0x4d:
dev->regs[addr] = (val & 0x7f);
pic_mouse_latch(!!(val & 0x10));
break;
case 0x4f:
dev->regs[addr] = val;
@@ -392,6 +394,7 @@ sio_reset_hard(void *priv)
dev->regs[0x4b] = 0x0f;
dev->regs[0x4c] = 0x56;
dev->regs[0x4d] = 0x40;
pic_mouse_latch(0x00);
dev->regs[0x4e] = 0x07;
dev->regs[0x4f] = 0x4f;
dev->regs[0x57] = 0x04;
@@ -444,6 +447,9 @@ sio_reset(void *p)
{
sio_t *dev = (sio_t *) p;
/* Disable the PIC mouse latch. */
sio_write(0, 0x4d, 0x40, p);
sio_write(0, 0x57, 0x04, p);
dma_set_params(1, 0xffffffff);
@@ -538,6 +544,8 @@ sio_init(const device_t *info)
// device_add(&i8254_sec_device);
pic_kbd_latch(0x01);
return dev;
}

View File

@@ -29,6 +29,7 @@
#include <86box/dma.h>
#include <86box/mem.h>
#include <86box/pci.h>
#include <86box/pic.h>
#include <86box/port_92.h>
#include <86box/hdc_ide.h>
#include <86box/hdc_ide_sff8038i.h>
@@ -725,6 +726,9 @@ sis_5571_init(const device_t *info)
sis_5571_reset(dev);
pic_kbd_latch(0x01);
pic_mouse_latch(0x01);
return dev;
}

View File

@@ -374,6 +374,9 @@ umc_8886_init(const device_t *info)
umc_8886_reset(dev);
pic_kbd_latch(0x01);
pic_mouse_latch(0x01);
return dev;
}

View File

@@ -222,6 +222,9 @@ pipc_reset_hard(void *priv)
dev->pci_isa_regs[0x0b] = 0x06;
dev->pci_isa_regs[0x0e] = 0x80;
pic_kbd_latch(0x01);
pic_mouse_latch(dev->local >= VIA_PIPC_586B);
dev->pci_isa_regs[0x48] = 0x01;
dev->pci_isa_regs[0x4a] = 0x04;
dev->pci_isa_regs[0x4f] = 0x03;
@@ -1063,6 +1066,11 @@ pipc_write(int func, int addr, uint8_t val, void *priv)
break;
case 0x44:
if (dev->local <= VIA_PIPC_586B)
pic_mouse_latch(val & 0x01);
break;
case 0x47:
if (val & 0x01)
trc_write(0x0047, (val & 0x80) ? 0x06 : 0x04, NULL);
@@ -1585,6 +1593,9 @@ pipc_reset(void *p)
else
pipc_write(1, 0x40, 0x00, p);
if (dev->local < VIA_PIPC_586B)
pipc_write(0, 0x44, 0x00, p);
pipc_write(0, 0x77, 0x00, p);
}

View File

@@ -129,12 +129,12 @@ typedef struct {
/* Keyboard. */
uint8_t kbd_state, key_command, key_wantdata, key_wantcmd,
key_dat, kbd_last_scan_code, sc_or,
key_cmd_queue_start, key_cmd_queue_end, key_queue_start, key_queue_end;
key_dat, kbd_last_scan_code, sc_or, key_cmd_queue_start,
key_cmd_queue_end, key_queue_start, key_queue_end;
/* Mouse. */
uint8_t mouse_state, mouse_wantcmd, mouse_dat, mouse_cmd_queue_start, mouse_cmd_queue_end,
mouse_queue_start, mouse_queue_end;
uint8_t mouse_state, mouse_wantcmd, mouse_dat, mouse_cmd_queue_start,
mouse_cmd_queue_end, mouse_queue_start, mouse_queue_end;
/* Controller. */
uint8_t mem[0x100];
@@ -154,9 +154,6 @@ typedef struct {
/* Mouse - scan FIFO. */
uint8_t mouse_queue[16];
/* Controller. */
uint16_t irq_levels, pad1;
/* Keyboard. */
int out_new, reset_delay;
@@ -624,8 +621,6 @@ static const scancode scancode_set3[512] = {
// clang-format on
};
static void add_data_kbd(uint16_t val);
// #define ENABLE_KEYBOARD_AT_LOG 1
#ifdef ENABLE_KEYBOARD_AT_LOG
int keyboard_at_do_log = ENABLE_KEYBOARD_AT_LOG;
@@ -675,10 +670,8 @@ set_scancode_map(atkbd_t *dev)
}
static void
kbc_queue_reset(uint8_t channel)
kbc_queue_reset(atkbd_t *dev, uint8_t channel)
{
atkbd_t *dev = SavedKbd;
switch (channel) {
case 1:
dev->key_queue_start = dev->key_queue_end = 0;
@@ -738,20 +731,9 @@ kbc_queue_add(atkbd_t *dev, uint8_t val, uint8_t channel)
}
}
static void
kbc_irq(atkbd_t *dev, uint16_t irq, int raise)
{
picint_common(irq, (dev->flags & KBC_TYPE_MASK) > KBC_TYPE_PS2_NOREF, raise);
if (raise)
dev->irq_levels = irq;
else
dev->irq_levels &= ~irq;
}
static int
kbc_translate(uint8_t val)
kbc_translate(atkbd_t *dev, uint8_t val)
{
atkbd_t *dev = SavedKbd;
int xt_mode = (keyboard_mode & 0x20) && ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF);
int translate = (keyboard_mode & 0x40);
uint8_t kbc_ven = dev->flags & KBC_VEN_MASK;
@@ -848,7 +830,7 @@ static void
add_to_kbc_queue_front(atkbd_t *dev, uint8_t val, uint8_t channel, uint8_t stat_hi)
{
uint8_t kbc_ven = dev->flags & KBC_VEN_MASK;
int temp = (channel == 1) ? kbc_translate(val) : val;
int temp = (channel == 1) ? kbc_translate(dev, val) : val;
if (temp == -1)
return;
@@ -869,12 +851,12 @@ add_to_kbc_queue_front(atkbd_t *dev, uint8_t val, uint8_t channel, uint8_t stat_
dev->status |= STAT_MFULL;
if (dev->mem[0x20] & 0x02)
kbc_irq(dev, 1 << 12, 1);
kbc_irq(dev, 1 << 1, 0);
picint_common(1 << 12, 0, 1);
picint_common(1 << 1, 0, 0);
} else {
if (dev->mem[0x20] & 0x01)
kbc_irq(dev, 1 << 1, 1);
kbc_irq(dev, 1 << 12, 0);
picint_common(1 << 1, 0, 1);
picint_common(1 << 12, 0, 0);
}
} else if (dev->mem[0x20] & 0x01)
picintlevel(1 << 1); /* AT KBC: IRQ 1 is level-triggered because it is tied to OBF. */
@@ -1030,7 +1012,7 @@ kbc_poll_at(atkbd_t *dev)
}
/* Do not continue dumping until OBF is clear. */
if (!(dev->status & STAT_OFULL)) {
kbd_log("ATkbc: %02X coming from channel 0\n", dev->key_ctrl_queue[dev-.key_ctrl_queue_start]);
kbd_log("ATkbc: %02X coming from channel 0\n", dev->key_ctrl_queue[dev->key_ctrl_queue_start]);
add_to_kbc_queue_front(dev, dev->key_ctrl_queue[dev->key_ctrl_queue_start], 0, 0x00);
dev->key_ctrl_queue_start = (dev->key_ctrl_queue_start + 1) & 0x3f;
if (dev->key_ctrl_queue_start == dev->key_ctrl_queue_end)
@@ -1221,7 +1203,7 @@ kbc_poll_kbd(atkbd_t *dev)
/* Process the command if needed and then return to main loop #2. */
if (dev->key_wantcmd) {
kbd_log("ATkbc: Processing keyboard command...\n");
kbc_queue_reset(4);
kbc_queue_reset(dev, 4);
// dev->out_new = -1;
kbd_process_cmd(dev);
dev->key_wantcmd = 0;
@@ -1231,18 +1213,18 @@ kbc_poll_kbd(atkbd_t *dev)
case DEV_STATE_MAIN_2:
/* Output from scan queue if needed and then return to main loop #1. */
if (keyboard_scan && (dev->out_new == -1) && (dev->key_queue_start != dev->key_queue_end)) {
kbd_log("ATkbc: %02X (DATA) on channel 1\n", dev->key_queue[key_queue_start]);
kbd_log("ATkbc: %02X (DATA) on channel 1\n", dev->key_queue[dev->key_queue_start]);
dev->out_new = dev->key_queue[dev->key_queue_start];
dev->key_queue_start = (dev->key_queue_start + 1) & 0xf;
}
if (!keyboard_scan || (dev->key_queue_start == dev->key_queue_end))
if (!keyboard_scan || dev->key_wantcmd)
dev->kbd_state = DEV_STATE_MAIN_1;
break;
case DEV_STATE_MAIN_OUT:
case DEV_STATE_RESET_OUT:
/* Output command response and then return to main loop #2. */
if ((dev->out_new == -1) && (dev->key_cmd_queue_start != dev->key_cmd_queue_end)) {
kbd_log("ATkbc: %02X (CMD ) on channel 1\n", key_cmd_queue[key_cmd_queue_start]);
kbd_log("ATkbc: %02X (CMD ) on channel 1\n", dev->key_cmd_queue[dev->key_cmd_queue_start]);
dev->out_new = dev->key_cmd_queue[dev->key_cmd_queue_start];
dev->key_cmd_queue_start = (dev->key_cmd_queue_start + 1) & 0xf;
}
@@ -1263,7 +1245,7 @@ kbc_poll_kbd(atkbd_t *dev)
/* Wait for host data. */
if (dev->key_wantcmd) {
kbd_log("ATkbc: Processing keyboard command...\n");
kbc_queue_reset(4);
kbc_queue_reset(dev, 4);
// dev->out_new = -1;
kbd_process_cmd(dev);
dev->key_wantcmd = 0;
@@ -1304,7 +1286,7 @@ kbc_poll_aux(atkbd_t *dev)
/* Process the command if needed and then return to main loop #2. */
if (dev->mouse_wantcmd) {
kbd_log("ATkbc: Processing mouse command...\n");
kbc_queue_reset(3);
kbc_queue_reset(dev, 3);
// dev->out_new_mouse = -1;
dev->mouse_state = DEV_STATE_MAIN_OUT;
mouse_write(dev->mouse_dat, mouse_p);
@@ -1321,7 +1303,7 @@ kbc_poll_aux(atkbd_t *dev)
dev->out_new_mouse = dev->mouse_queue[dev->mouse_queue_start];
dev->mouse_queue_start = (dev->mouse_queue_start + 1) & 0xf;
}
if (!mouse_scan || (dev->mouse_queue_start == dev->mouse_queue_end))
if (!mouse_scan || dev->mouse_wantcmd)
dev->mouse_state = DEV_STATE_MAIN_1;
break;
case DEV_STATE_MAIN_OUT:
@@ -1349,7 +1331,7 @@ kbc_poll_aux(atkbd_t *dev)
/* Wait for host data. */
if (dev->mouse_wantcmd) {
kbd_log("ATkbc: Processing mouse command...\n");
kbc_queue_reset(3);
kbc_queue_reset(dev, 3);
// dev->out_new_mouse = -1;
dev->mouse_state = DEV_STATE_MAIN_OUT;
mouse_write(dev->mouse_dat, mouse_p);
@@ -1578,10 +1560,10 @@ write_output(atkbd_t *dev, uint8_t val)
/* PS/2: Handle IRQ's. */
if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) {
/* IRQ 12 */
kbc_irq(dev, 1 << 12, val & 0x20);
picint_common(1 << 12, 0, val & 0x20);
/* IRQ 1 */
kbc_irq(dev, 1 << 12, val & 0x10);
picint_common(1 << 1, 0, val & 0x10);
}
/* AT, PS/2: Handle A20. */
@@ -1619,6 +1601,23 @@ write_output(atkbd_t *dev, uint8_t val)
dev->output_port = val;
}
static void
write_output_fast_a20(atkbd_t *dev, uint8_t val)
{
uint8_t old = dev->output_port;
kbd_log("ATkbc: write output port in fast A20 mode: %02X (old: %02X)\n", val, dev->output_port);
/* AT, PS/2: Handle A20. */
if ((old ^ val) & 0x02) { /* A20 enable change */
mem_a20_key = val & 0x02;
mem_a20_recalc();
flushmmucache();
}
/* Do this here to avoid an infinite reset loop. */
dev->output_port = val;
}
static void
write_cmd(atkbd_t *dev, uint8_t val)
{
@@ -2261,7 +2260,7 @@ static void
kbd_key_reset(atkbd_t *dev, int do_fa)
{
dev->out_new = -1;
kbc_queue_reset(1);
kbc_queue_reset(dev, 1);
dev->kbd_last_scan_code = 0x00;
@@ -2288,7 +2287,7 @@ static void
kbd_aux_reset(atkbd_t *dev, int do_fa)
{
dev->out_new_mouse = -1;
kbc_queue_reset(2);
kbc_queue_reset(dev, 2);
mouse_scan = 1;
@@ -2395,7 +2394,6 @@ kbd_process_cmd(void *priv)
break;
case 0xf2: /* read ID */
/* Fixed as translation will be done in add_data_kbd(). */
kbd_log("ATkbd: read keyboard id\n");
/* TODO: After keyboard type selection is implemented, make this
return the correct keyboard ID for the selected type. */
@@ -2492,7 +2490,7 @@ kbc_process_cmd(void *priv)
dev->kbc_state = KBC_STATE_MAIN_IBF;
/* Clear the keyboard controller queue. */
kbc_queue_reset(0);
kbc_queue_reset(dev, 0);
switch (dev->ib) {
/* Read data from KBC memory. */
@@ -2555,7 +2553,7 @@ kbc_process_cmd(void *priv)
}
dev->out_new = dev->out_new_mouse = -1;
kbc_queue_reset(0);
kbc_queue_reset(dev, 0);
// dev->kbc_state = KBC_STATE_MAIN_IBF;
dev->kbc_state = KBC_STATE_KBC_OUT;
@@ -2731,7 +2729,6 @@ kbc_process_cmd(void *priv)
if (bad) {
kbd_log("ATkbc: bad controller command %02x data %02x\n", dev->command, dev->ib);
add_data_kbd(0xfe);
}
}
}
@@ -2749,6 +2746,10 @@ kbd_write(uint16_t port, uint8_t val, void *priv)
dev->status &= ~STAT_CD;
if (dev->want60 && (dev->command == 0xd1)) {
kbd_log("ATkbc: write output port\n");
/* Fast A20 - ignore all other bits. */
val = (val & 0x02) | (dev->output_port & 0xfd);
/* Bit 2 of AMI flags is P22-P23 blocked (1 = yes, 0 = no),
discovered by reverse-engineering the AOpeN Vi15G BIOS. */
if (dev->ami_flags & 0x04) {
@@ -2757,7 +2758,9 @@ kbd_write(uint16_t port, uint8_t val, void *priv)
val &= ~0x0c;
val |= (dev->output_port & 0x0c);
}
write_output(dev, val | 0x01);
write_output_fast_a20(dev, val | 0x01);
dev->want60 = 0;
dev->kbc_state = KBC_STATE_MAIN_IBF;
return;
@@ -2798,11 +2801,6 @@ kbd_read(uint16_t port, void *priv)
This also means that in AT mode, the IRQ is level-triggered. */
if ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF)
picintc(1 << 1);
else if (pic_get_pci_flag() || ((dev->flags & KBC_TYPE_MASK) > KBC_TYPE_PS2_NOREF)) {
/* PS/2 MCA: Latched as level-sensitive until port 0x60 is read (and with it, OBF is cleared),
in accordance with the IBM PS/2 Model 80 Technical Reference Manual. */
kbc_irq(dev, dev->irq_levels, 0);
}
break;
case 0x64:
@@ -2849,7 +2847,7 @@ kbd_reset(void *priv)
dev->out_new = dev->out_new_mouse = -1;
for (i = 0; i < 3; i++)
kbc_queue_reset(i);
kbc_queue_reset(dev, i);
dev->kbd_last_scan_code = 0;
dev->sc_or = 0;
@@ -3290,14 +3288,6 @@ keyboard_at_set_mouse(void (*func)(uint8_t val, void *priv), void *priv)
mouse_p = priv;
}
void
keyboard_at_adddata_keyboard_raw(uint8_t val)
{
atkbd_t *dev = SavedKbd;
add_data_kbd_queue(dev, val);
}
void
keyboard_at_adddata_mouse(uint8_t val)
{
@@ -3330,28 +3320,6 @@ keyboard_at_mouse_pos(void)
return ((dev->mouse_queue_end - dev->mouse_queue_start) & 0xf);
}
void
keyboard_at_set_mouse_scan(uint8_t val)
{
atkbd_t *dev = SavedKbd;
uint8_t temp_mouse_scan = val ? 1 : 0;
if (temp_mouse_scan == !(dev->mem[0x20] & 0x20))
return;
set_enable_mouse(dev, val ? 1 : 0);
kbd_log("ATkbc: mouse scan %sabled via PCI\n", mouse_scan ? "en" : "dis");
}
uint8_t
keyboard_at_get_mouse_scan(void)
{
atkbd_t *dev = SavedKbd;
return ((dev->mem[0x20] & 0x20) ? 0x00 : 0x10);
}
void
keyboard_at_set_a20_key(int state)
{

View File

@@ -199,16 +199,11 @@ extern int keyboard_ismsexit(void);
extern void keyboard_set_is_amstrad(int ams);
extern void keyboard_at_adddata_mouse(uint8_t val);
extern void keyboard_at_adddata_mouse_direct(uint8_t val);
extern void keyboard_at_adddata_mouse_cmd(uint8_t val);
extern void keyboard_at_mouse_reset(void);
extern uint8_t keyboard_at_mouse_pos(void);
extern int keyboard_at_fixed_channel(void);
extern void keyboard_at_set_mouse(void (*mouse_write)(uint8_t val, void *), void *);
extern void keyboard_at_set_a20_key(int state);
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);

View File

@@ -46,6 +46,8 @@ extern void pic_set_shadow(int sh);
extern int pic_get_pci_flag(void);
extern void pic_set_pci_flag(int pci);
extern void pic_set_pci(void);
extern void pic_kbd_latch(int enable);
extern void pic_mouse_latch(int enable);
extern void pic_init(void);
extern void pic_init_pcjr(void);
extern void pic2_init(void);

View File

@@ -1343,6 +1343,9 @@ machine_ps2_common_init(const machine_t *model)
nmi_mask = 0x80;
ps2.uart = device_add_inst(&ns16550_device, 1);
pic_kbd_latch(0x01);
pic_mouse_latch(0x01);
}
int

View File

@@ -3774,7 +3774,7 @@ const machine_t machines[] = {
.min_multi = 0,
.max_multi = 0
},
.bus_flags = MACHINE_PS2,
.bus_flags = MACHINE_AT,
.flags = MACHINE_IDE,
.ram = {
.min = 1024,
@@ -3813,7 +3813,7 @@ const machine_t machines[] = {
.min_multi = 0,
.max_multi = 0
},
.bus_flags = MACHINE_PS2,
.bus_flags = MACHINE_AT,
.flags = MACHINE_IDE,
.ram = {
.min = 1024,
@@ -3894,7 +3894,7 @@ const machine_t machines[] = {
.min_multi = 0,
.max_multi = 0
},
.bus_flags = MACHINE_PS2,
.bus_flags = MACHINE_AT,
.flags = MACHINE_IDE,
.ram = {
.min = 1024,

View File

@@ -2822,6 +2822,10 @@ mem_remap_top(int kb)
sis_mode = 1;
}
/* Do not remap if we're have more than (16 MB - RAM) memory. */
if ((kb != 0) && (mem_size >= (16384 - kb)))
return;
if (kb == 0) {
kb = old_kb;
set = 0;

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);
}
}