diff --git a/src/chipset/ali1489.c b/src/chipset/ali1489.c index 70ff509ab..706b67f12 100644 --- a/src/chipset/ali1489.c +++ b/src/chipset/ali1489.c @@ -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 */ diff --git a/src/chipset/ali1543.c b/src/chipset/ali1543.c index 150e54468..5aabd6c63 100644 --- a/src/chipset/ali1543.c +++ b/src/chipset/ali1543.c @@ -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); diff --git a/src/chipset/ali6117.c b/src/chipset/ali6117.c index 98451067a..588aec3c3 100644 --- a/src/chipset/ali6117.c +++ b/src/chipset/ali6117.c @@ -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)) diff --git a/src/chipset/ims8848.c b/src/chipset/ims8848.c index 0cdc833b5..57580f125 100644 --- a/src/chipset/ims8848.c +++ b/src/chipset/ims8848.c @@ -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; } diff --git a/src/chipset/intel_420ex.c b/src/chipset/intel_420ex.c index 98c2d0386..2b1a08622 100644 --- a/src/chipset/intel_420ex.c +++ b/src/chipset/intel_420ex.c @@ -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,7 +389,8 @@ i420ex_reset_hard(void *priv) dev->regs[0x4c] = 0x4d; dev->regs[0x4e] = 0x03; - /* Bits 2:1 of register 50h are 00 is 25 MHz, and 01 if 33 MHz, 10 and 11 are reserved. */ + 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; dev->regs[0x51] = 0x80; @@ -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; } diff --git a/src/chipset/intel_piix.c b/src/chipset/intel_piix.c index 180940e26..94468b435 100644 --- a/src/chipset/intel_piix.c +++ b/src/chipset/intel_piix.c @@ -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; } diff --git a/src/chipset/intel_sio.c b/src/chipset/intel_sio.c index d94cac04a..eb7aad983 100644 --- a/src/chipset/intel_sio.c +++ b/src/chipset/intel_sio.c @@ -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; } diff --git a/src/chipset/sis_5571.c b/src/chipset/sis_5571.c index daf64aa74..53ef7956e 100644 --- a/src/chipset/sis_5571.c +++ b/src/chipset/sis_5571.c @@ -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; } diff --git a/src/chipset/umc_8886.c b/src/chipset/umc_8886.c index dea5ac99a..3def68666 100644 --- a/src/chipset/umc_8886.c +++ b/src/chipset/umc_8886.c @@ -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; } diff --git a/src/chipset/via_pipc.c b/src/chipset/via_pipc.c index 373935eee..402021513 100644 --- a/src/chipset/via_pipc.c +++ b/src/chipset/via_pipc.c @@ -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); } diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index 194339c72..5cc5f012a 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -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) { diff --git a/src/include/86box/keyboard.h b/src/include/86box/keyboard.h index 0fd25dbd0..b7f2a67bc 100644 --- a/src/include/86box/keyboard.h +++ b/src/include/86box/keyboard.h @@ -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); diff --git a/src/include/86box/pic.h b/src/include/86box/pic.h index 52bc920e4..eae6a6afb 100644 --- a/src/include/86box/pic.h +++ b/src/include/86box/pic.h @@ -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); diff --git a/src/machine/m_ps2_mca.c b/src/machine/m_ps2_mca.c index 5057b65ea..3de9ef491 100644 --- a/src/machine/m_ps2_mca.c +++ b/src/machine/m_ps2_mca.c @@ -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 diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 3a11769f8..244af7623 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -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, diff --git a/src/mem/mem.c b/src/mem/mem.c index a71621d51..f3f0f3110 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -2873,6 +2873,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; diff --git a/src/pic.c b/src/pic.c index 9920a23e9..cb5fcb0c5 100644 --- a/src/pic.c +++ b/src/pic.c @@ -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); } }