From 5d9de974ee186d93ad3c75405dff15082b4aa760 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 22 Apr 2023 03:48:50 +0200 Subject: [PATCH 01/15] More keyboard controller clean-ups and fixes to mem/mem.c and port_92.c - OS/2 1.3 now works on IBM PS/2 MCA machines. --- src/device/kbc_at.c | 225 +++++++++++++++++++---------------- src/include/86box/keyboard.h | 1 - src/machine/m_ps2_mca.c | 6 +- src/mem/mem.c | 2 +- src/port_92.c | 20 +++- 5 files changed, 142 insertions(+), 112 deletions(-) diff --git a/src/device/kbc_at.c b/src/device/kbc_at.c index 287d8b4d0..2c9433bd9 100644 --- a/src/device/kbc_at.c +++ b/src/device/kbc_at.c @@ -64,25 +64,22 @@ #define MODE_MASK 0x6c #define KBC_TYPE_ISA 0x00 /* AT ISA-based chips */ -#define KBC_TYPE_PS2_NOREF 0x01 /* PS2 type, no refresh */ -#define KBC_TYPE_PS2_1 0x02 /* PS2 on PS/2, type 1 */ -#define KBC_TYPE_PS2_2 0x03 /* PS2 on PS/2, type 2 */ +#define KBC_TYPE_PS2_1 0x01 /* PS2 on PS/2, type 1 */ +#define KBC_TYPE_PS2_2 0x02 /* PS2 on PS/2, type 2 */ +#define KBC_TYPE_GREEN 0x03 /* PS2 green controller */ #define KBC_TYPE_MASK 0x03 #define KBC_VEN_GENERIC 0x00 -#define KBC_VEN_AMI 0x04 -#define KBC_VEN_IBM_MCA 0x08 -#define KBC_VEN_QUADTEL 0x0c -#define KBC_VEN_TOSHIBA 0x10 -#define KBC_VEN_IBM_PS1 0x14 -#define KBC_VEN_ACER 0x18 -#define KBC_VEN_INTEL_AMI 0x1c -#define KBC_VEN_OLIVETTI 0x20 +#define KBC_VEN_IBM_PS1 0x04 +#define KBC_VEN_TOSHIBA 0x08 +#define KBC_VEN_OLIVETTI 0x0c +#define KBC_VEN_AMI 0x10 +#define KBC_VEN_TRIGEM_AMI 0x14 +#define KBC_VEN_QUADTEL 0x18 +#define KBC_VEN_PHOENIX 0x1c +#define KBC_VEN_ACER 0x20 #define KBC_VEN_NCR 0x24 -#define KBC_VEN_PHOENIX 0x28 -#define KBC_VEN_ALI 0x2c -#define KBC_VEN_TG 0x30 -#define KBC_VEN_TG_GREEN 0x34 +#define KBC_VEN_ALI 0x28 #define KBC_VEN_MASK 0x3c #define FLAG_CLOCK 0x01 @@ -210,6 +207,7 @@ kbc_at_queue_add(atkbc_t *dev, uint8_t val) static int kbc_translate(atkbc_t *dev, uint8_t val) { + /* TODO: Does the IBM AT keyboard controller firmware apply translation in XT mode or not? */ int xt_mode = (dev->mem[0x20] & 0x20) && !(dev->misc_flags & FLAG_PS2); int translate = (dev->mem[0x20] & 0x40) || xt_mode || ((dev->flags & KBC_TYPE_MASK) == KBC_TYPE_PS2_2); uint8_t kbc_ven = dev->flags & KBC_VEN_MASK; @@ -308,8 +306,8 @@ add_to_kbc_queue_front(atkbc_t *dev, uint8_t val, uint8_t channel, uint8_t stat_ if (temp == -1) return; - if ((kbc_ven == KBC_VEN_AMI) || (kbc_ven == KBC_VEN_TG) || - (kbc_ven == KBC_VEN_TG_GREEN) || (dev->misc_flags & FLAG_PS2)) + if ((kbc_ven == KBC_VEN_AMI) || (kbc_ven == KBC_VEN_TRIGEM_AMI) || + (dev->misc_flags & FLAG_PS2)) stat_hi |= ((dev->p1 & 0x80) ? 0x10 : 0x00); else stat_hi |= 0x10; @@ -675,7 +673,7 @@ write_p2(atkbc_t *dev, uint8_t val) coreboot machines. */ pc_reset_hard(); } else { - softresetx86(); /*Pulse reset!*/ + softresetx86(); /* Pulse reset! */ cpu_set_edx(); flushmmucache(); if (kbc_ven == KBC_VEN_ALI) @@ -797,11 +795,59 @@ write64_generic(void *priv, uint8_t val) add_to_kbc_queue_front(dev, kbc_award_revision, 0, 0x00); return 0; + /* + P1 bits: 76543210 + ----------------- + IBM PS/1: xxxxxxxx + IBM PS/2 MCA: xxxxx1xx + Intel AMI Pentium BIOS'es with AMI MegaKey KB-5 keyboard controller: x1x1xxxx + Acer: xxx0x0xx + Packard Bell PB450: xxxxx1xx + P6RP4: xx1xx1xx + Epson Action Tower 2600: xxxx01xx + TriGem Hawk: xxxx11xx + + Bit 7: AT KBC only - keyboard inhibited (often physical lock): 0 = yes, 1 = no (also Compaq); + Bit 6: Mostly, display: 0 = CGA, 1 = MDA, inverted on Xi8088 and Acer KBC's; + Intel AMI MegaKey KB-5: Used for green features, SMM handler expects it to be set; + IBM PS/1 Model 2011: 0 = current FDD is 3.5", 1 = current FDD is 5.25"; + Comapq: 0 = Compaq dual-scan display, 1 = non-Compaq display. + Bit 5: Mostly, manufacturing jumper: 0 = installed (infinite loop at POST), 1 = not installed; + NCR: power-on default speed: 0 = high, 1 = low; + Compaq: System board DIP switch 5: 0 = ON, 1 = OFF. + Bit 4: (Which board?): RAM on motherboard: 0 = 512 kB, 1 = 256 kB; + NCR: RAM on motherboard: 0 = unsupported, 1 = 512 kB; + Acer: Must be 0; + Intel AMI MegaKey KB-5: Must be 1; + IBM PS/1: Ignored; + Compaq: 0 = Auto speed selected, 1 = High speed selected. + Bit 3: TriGem AMIKey: most significant bit of 2-bit OEM ID; + NCR: Coprocessor detect (1 = yes, 0 = no); + Compaq: 0 = Slow (4 MHz), 1 = Fast (8 MHz); + Sometimes configured for clock switching; + Bit 2: TriGem AMIKey: least significant bit of 2-bit OEM ID; + Bit 3, 2: + 1, 1: TriGem logo; + 1, 0: Garbled logo; + 0, 1: Epson logo; + 0, 0: Generic AMI logo. + NCR: Unused; + IBM PS/2: Keyboard power: 0 = no power (fuse error), 1 = OK + (for some reason, www.win.tue.nl has this in reverse); + Compaq: FPU: 0 = 80287, 1 = none; + Sometimes configured for clock switching; + Bit 1: PS/2: Auxiliary device data in; + Compaq: Reserved; + NCR: High/auto speed. + Bit 0: PS/2: Keyboard device data in; + Compaq: Reserved; + NCR: DMA mode. + */ case 0xc0: /* read P1 */ kbc_at_log("ATkbc: read P1\n"); fixed_bits = 4; /* The SMM handlers of Intel AMI Pentium BIOS'es expect bit 6 to be set. */ - if (kbc_ven == KBC_VEN_INTEL_AMI) + if ((kbc_ven == KBC_VEN_AMI) && ((dev->flags & KBC_TYPE_MASK) == KBC_TYPE_GREEN)) fixed_bits |= 0x40; if (kbc_ven == KBC_VEN_IBM_PS1) { current_drive = fdc_get_current_drive(); @@ -820,7 +866,7 @@ write64_generic(void *priv, uint8_t val) */ add_to_kbc_queue_front(dev, (dev->p1 | fixed_bits | (video_is_mda() ? 0x40 : 0x00) | (hasfpu ? 0x08 : 0x00)) & 0xdf, 0, 0x00); - } else if ((kbc_ven == KBC_VEN_TG) || (kbc_ven == KBC_VEN_TG_GREEN)) { + } else if (kbc_ven == KBC_VEN_TRIGEM_AMI) { /* Bit 3, 2: 1, 1: TriGem logo; 1, 0: Garbled logo; @@ -829,13 +875,31 @@ write64_generic(void *priv, uint8_t val) if (dev->misc_flags & FLAG_PCI) fixed_bits |= 8; add_to_kbc_queue_front(dev, dev->p1 | fixed_bits, 0, 0x00); - } else if (((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) && ((dev->flags & KBC_VEN_MASK) != KBC_VEN_INTEL_AMI)) + } else if (((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) && ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_GREEN)) add_to_kbc_queue_front(dev, ((dev->p1 | fixed_bits) & 0xf0) | (((dev->flags & KBC_VEN_MASK) == KBC_VEN_ACER) ? 0x08 : 0x0c), 0, 0x00); else add_to_kbc_queue_front(dev, dev->p1 | fixed_bits, 0, 0x00); dev->p1 = ((dev->p1 + 1) & 3) | (dev->p1 & 0xfc); return 0; + case 0xc1: /*Copy bits 0 to 3 of P1 to status bits 4 to 7*/ + if (dev->misc_flags & FLAG_PS2) { + kbc_at_log("ATkbc: copy bits 0 to 3 of P1 to status bits 4 to 7\n"); + dev->status &= 0x0f; + dev->status |= (dev->p1 << 4); + return 0; + } + break; + + case 0xc2: /*Copy bits 4 to 7 of P1 to status bits 4 to 7*/ + if (dev->misc_flags & FLAG_PS2) { + kbc_at_log("ATkbc: copy bits 4 to 7 of P1 to status bits 4 to 7\n"); + dev->status &= 0x0f; + dev->status |= (dev->p1 & 0xf0); + return 0; + } + break; + case 0xd3: /* write auxiliary output buffer */ if (dev->misc_flags & FLAG_PS2) { kbc_at_log("ATkbc: write auxiliary output buffer\n"); @@ -903,10 +967,13 @@ write60_ami(void *priv, uint8_t val) dev->ami_flags = val; dev->misc_flags &= ~FLAG_PS2; if (val & 0x01) { + kbc_at_log("ATkbc: AMI: Emulate PS/2 keyboard\n"); dev->misc_flags |= FLAG_PS2; kbc_at_do_poll = kbc_at_poll_ps2; - } else + } else { + kbc_at_log("ATkbc: AMI: Emulate AT keyboard\n"); kbc_at_do_poll = kbc_at_poll_at; + } return 0; } @@ -1112,37 +1179,6 @@ write64_ami(void *priv, uint8_t val) return write64_generic(dev, val); } -static uint8_t -write64_ibm_mca(void *priv, uint8_t val) -{ - atkbc_t *dev = (atkbc_t *) priv; - - switch (val) { - case 0xc1: /*Copy bits 0 to 3 of P1 to status bits 4 to 7*/ - kbc_at_log("ATkbc: copy bits 0 to 3 of P1 to status bits 4 to 7\n"); - dev->status &= 0x0f; - dev->status |= ((((dev->p1 & 0xfc) | 0x84) & 0x0f) << 4); - return 0; - - case 0xc2: /*Copy bits 4 to 7 of P1 to status bits 4 to 7*/ - kbc_at_log("ATkbc: copy bits 4 to 7 of P1 to status bits 4 to 7\n"); - dev->status &= 0x0f; - dev->status |= (((dev->p1 & 0xfc) | 0x84) & 0xf0); - return 0; - - case 0xaf: - kbc_at_log("ATkbc: bad KBC command AF\n"); - return 1; - - case 0xf0 ... 0xff: - kbc_at_log("ATkbc: pulse: %01X\n", (val & 0x03) | 0x0c); - pulse_output(dev, (val & 0x03) | 0x0c); - return 0; - } - - return write64_generic(dev, val); -} - static uint8_t write60_quadtel(void *priv, uint8_t val) { @@ -1260,15 +1296,17 @@ write64_toshiba(void *priv, uint8_t val) dev->state = STATE_KBC_PARAM; return 0; + /* TODO: Toshiba KBC mode switching. */ case 0xb7: /* T3100e: Emulate PS/2 keyboard */ case 0xb8: /* T3100e: Emulate AT keyboard */ - dev->flags &= ~KBC_TYPE_MASK; + dev->misc_flags &= ~FLAG_PS2; if (val == 0xb7) { kbc_at_log("ATkbc: T3100e: Emulate PS/2 keyboard\n"); - dev->flags |= KBC_TYPE_PS2_NOREF; + dev->misc_flags |= FLAG_PS2; + kbc_at_do_poll = kbc_at_poll_ps2; } else { kbc_at_log("ATkbc: T3100e: Emulate AT keyboard\n"); - dev->flags |= KBC_TYPE_ISA; + kbc_at_do_poll = kbc_at_poll_at; } return 0; @@ -1333,7 +1371,7 @@ kbc_at_process_cmd(void *priv) case 0xaa: /* self-test */ kbc_at_log("ATkbc: self-test\n"); - if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) { + if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) { if (dev->state != STATE_RESET) { kbc_at_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. */ @@ -1531,7 +1569,7 @@ kbc_at_process_cmd(void *priv) if (dev->ib == 0xbb) break; - if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) { + if (dev->misc_flags & FLAG_PS2) { set_enable_aux(dev, 1); if ((dev->ports[1] != NULL) && (dev->ports[1]->priv != NULL)) { dev->ports[1]->wantcmd = 1; @@ -1614,7 +1652,7 @@ kbc_at_read(uint16_t port, void *priv) atkbc_t *dev = (atkbc_t *) priv; uint8_t ret = 0xff; - if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) + if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) cycles -= ISA_CYCLES(8); switch (port) { @@ -1667,10 +1705,10 @@ kbc_at_reset(void *priv) dev->sc_or = 0; - dev->ami_flags = ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) ? 0x01 : 0x00; + dev->ami_flags = ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) ? 0x01 : 0x00; dev->misc_flags = 0x00; - if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) { + if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) { dev->misc_flags |= FLAG_PS2; kbc_at_do_poll = kbc_at_poll_ps2; } else @@ -1679,7 +1717,7 @@ kbc_at_reset(void *priv) dev->misc_flags |= FLAG_CACHE; dev->p2 = 0xcd; - if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) { + if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) { write_p2(dev, 0x4b); } else { /* The real thing writes CF and then AND's it with BF. */ @@ -1694,7 +1732,7 @@ static void kbc_at_close(void *priv) { atkbc_t *dev = (atkbc_t *) priv; - int i, max_ports = ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) ? 2 : 1; + int i, max_ports = ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) ? 2 : 1; kbc_at_reset(dev); @@ -1752,12 +1790,6 @@ kbc_at_init(const device_t *info) dev->write64_ven = write64_olivetti; break; - case KBC_VEN_INTEL_AMI: - kbc_ami_revision = '5'; - dev->write60_ven = write60_ami; - dev->write64_ven = write64_ami; - break; - case KBC_VEN_ALI: kbc_ami_revision = 'F'; kbc_award_revision = 0x43; @@ -1765,15 +1797,16 @@ kbc_at_init(const device_t *info) dev->write64_ven = write64_ami; break; - case KBC_VEN_TG: - case KBC_VEN_TG_GREEN: + case KBC_VEN_TRIGEM_AMI: kbc_ami_revision = 'Z'; dev->write60_ven = write60_ami; dev->write64_ven = write64_ami; break; case KBC_VEN_AMI: - if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) { + if ((dev->flags & KBC_TYPE_MASK) == KBC_TYPE_GREEN) + kbc_ami_revision = '5'; + else if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) { if (cpu_64bitbus) kbc_ami_revision = 'R'; else if (is486) @@ -1794,10 +1827,6 @@ kbc_at_init(const device_t *info) dev->write64_ven = write64_ami; break; - case KBC_VEN_IBM_MCA: - dev->write64_ven = write64_ibm_mca; - break; - case KBC_VEN_QUADTEL: dev->write60_ven = write60_quadtel; dev->write64_ven = write64_quadtel; @@ -1809,7 +1838,7 @@ kbc_at_init(const device_t *info) break; } - max_ports = ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) ? 2 : 1; + max_ports = ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) ? 2 : 1; for (i = 0; i < max_ports; i++) { kbc_at_ports[i] = (kbc_at_port_t *) malloc(sizeof(kbc_at_port_t)); @@ -1858,7 +1887,7 @@ const device_t keyboard_at_tg_ami_device = { .name = "PC/AT Keyboard (TriGem AMI)", .internal_name = "keyboard_at_tg_ami", .flags = DEVICE_KBC, - .local = KBC_TYPE_ISA | KBC_VEN_TG, + .local = KBC_TYPE_ISA | KBC_VEN_TRIGEM_AMI, .init = kbc_at_init, .close = kbc_at_close, .reset = kbc_at_reset, @@ -1914,7 +1943,7 @@ const device_t keyboard_ps2_device = { .name = "PS/2 Keyboard", .internal_name = "keyboard_ps2", .flags = DEVICE_KBC, - .local = KBC_TYPE_PS2_NOREF | KBC_VEN_GENERIC, + .local = KBC_TYPE_PS2_1 | KBC_VEN_GENERIC, .init = kbc_at_init, .close = kbc_at_close, .reset = kbc_at_reset, @@ -1928,7 +1957,7 @@ const device_t keyboard_ps2_ps1_device = { .name = "PS/2 Keyboard (IBM PS/1)", .internal_name = "keyboard_ps2_ps1", .flags = DEVICE_KBC, - .local = KBC_TYPE_PS2_NOREF | KBC_VEN_IBM_PS1, + .local = KBC_TYPE_PS2_1 | KBC_VEN_IBM_PS1, .init = kbc_at_init, .close = kbc_at_close, .reset = kbc_at_reset, @@ -1942,7 +1971,7 @@ const device_t keyboard_ps2_ps1_pci_device = { .name = "PS/2 Keyboard (IBM PS/1)", .internal_name = "keyboard_ps2_ps1_pci", .flags = DEVICE_KBC | DEVICE_PCI, - .local = KBC_TYPE_PS2_NOREF | KBC_VEN_IBM_PS1, + .local = KBC_TYPE_PS2_1 | KBC_VEN_IBM_PS1, .init = kbc_at_init, .close = kbc_at_close, .reset = kbc_at_reset, @@ -1970,7 +1999,7 @@ const device_t keyboard_ps2_ami_device = { .name = "PS/2 Keyboard (AMI)", .internal_name = "keyboard_ps2_ami", .flags = DEVICE_KBC, - .local = KBC_TYPE_PS2_NOREF | KBC_VEN_AMI, + .local = KBC_TYPE_PS2_1 | KBC_VEN_AMI, .init = kbc_at_init, .close = kbc_at_close, .reset = kbc_at_reset, @@ -1984,21 +2013,7 @@ const device_t keyboard_ps2_tg_ami_device = { .name = "PS/2 Keyboard (TriGem AMI)", .internal_name = "keyboard_ps2_tg_ami", .flags = DEVICE_KBC, - .local = KBC_TYPE_PS2_NOREF | KBC_VEN_TG, - .init = kbc_at_init, - .close = kbc_at_close, - .reset = kbc_at_reset, - { .available = NULL }, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t keyboard_ps2_mca_device = { - .name = "PS/2 Keyboard", - .internal_name = "keyboard_ps2_mca", - .flags = DEVICE_KBC, - .local = KBC_TYPE_PS2_1 | KBC_VEN_IBM_MCA, + .local = KBC_TYPE_PS2_1 | KBC_VEN_TRIGEM_AMI, .init = kbc_at_init, .close = kbc_at_close, .reset = kbc_at_reset, @@ -2012,7 +2027,7 @@ const device_t keyboard_ps2_mca_2_device = { .name = "PS/2 Keyboard", .internal_name = "keyboard_ps2_mca_2", .flags = DEVICE_KBC, - .local = KBC_TYPE_PS2_2 | KBC_VEN_IBM_MCA, + .local = KBC_TYPE_PS2_2 | KBC_VEN_GENERIC, .init = kbc_at_init, .close = kbc_at_close, .reset = kbc_at_reset, @@ -2026,7 +2041,7 @@ const device_t keyboard_ps2_quadtel_device = { .name = "PS/2 Keyboard (Quadtel/MegaPC)", .internal_name = "keyboard_ps2_quadtel", .flags = DEVICE_KBC, - .local = KBC_TYPE_PS2_NOREF | KBC_VEN_QUADTEL, + .local = KBC_TYPE_PS2_1 | KBC_VEN_QUADTEL, .init = kbc_at_init, .close = kbc_at_close, .reset = kbc_at_reset, @@ -2040,7 +2055,7 @@ const device_t keyboard_ps2_pci_device = { .name = "PS/2 Keyboard", .internal_name = "keyboard_ps2_pci", .flags = DEVICE_KBC | DEVICE_PCI, - .local = KBC_TYPE_PS2_NOREF | KBC_VEN_GENERIC, + .local = KBC_TYPE_PS2_1 | KBC_VEN_GENERIC, .init = kbc_at_init, .close = kbc_at_close, .reset = kbc_at_reset, @@ -2054,7 +2069,7 @@ const device_t keyboard_ps2_ami_pci_device = { .name = "PS/2 Keyboard (AMI)", .internal_name = "keyboard_ps2_ami_pci", .flags = DEVICE_KBC | DEVICE_PCI, - .local = KBC_TYPE_PS2_NOREF | KBC_VEN_AMI, + .local = KBC_TYPE_PS2_1 | KBC_VEN_AMI, .init = kbc_at_init, .close = kbc_at_close, .reset = kbc_at_reset, @@ -2068,7 +2083,7 @@ const device_t keyboard_ps2_ali_pci_device = { .name = "PS/2 Keyboard (ALi M5123/M1543C)", .internal_name = "keyboard_ps2_ali_pci", .flags = DEVICE_KBC | DEVICE_PCI, - .local = KBC_TYPE_PS2_NOREF | KBC_VEN_ALI, + .local = KBC_TYPE_PS2_1 | KBC_VEN_ALI, .init = kbc_at_init, .close = kbc_at_close, .reset = kbc_at_reset, @@ -2082,7 +2097,7 @@ const device_t keyboard_ps2_intel_ami_pci_device = { .name = "PS/2 Keyboard (AMI)", .internal_name = "keyboard_ps2_intel_ami_pci", .flags = DEVICE_KBC | DEVICE_PCI, - .local = KBC_TYPE_PS2_NOREF | KBC_VEN_INTEL_AMI, + .local = KBC_TYPE_GREEN | KBC_VEN_AMI, .init = kbc_at_init, .close = kbc_at_close, .reset = kbc_at_reset, @@ -2096,7 +2111,7 @@ const device_t keyboard_ps2_tg_ami_pci_device = { .name = "PS/2 Keyboard (TriGem AMI)", .internal_name = "keyboard_ps2_tg_ami_pci", .flags = DEVICE_KBC | DEVICE_PCI, - .local = KBC_TYPE_PS2_NOREF | KBC_VEN_TG, + .local = KBC_TYPE_PS2_1 | KBC_VEN_TRIGEM_AMI, .init = kbc_at_init, .close = kbc_at_close, .reset = kbc_at_reset, @@ -2110,7 +2125,7 @@ const device_t keyboard_ps2_acer_pci_device = { .name = "PS/2 Keyboard (Acer 90M002A)", .internal_name = "keyboard_ps2_acer_pci", .flags = DEVICE_KBC | DEVICE_PCI, - .local = KBC_TYPE_PS2_NOREF | KBC_VEN_ACER, + .local = KBC_TYPE_PS2_1 | KBC_VEN_ACER, .init = kbc_at_init, .close = kbc_at_close, .reset = kbc_at_reset, diff --git a/src/include/86box/keyboard.h b/src/include/86box/keyboard.h index 6f7517e9d..fe642fec1 100644 --- a/src/include/86box/keyboard.h +++ b/src/include/86box/keyboard.h @@ -225,7 +225,6 @@ extern const device_t keyboard_ps2_ami_device; extern const device_t keyboard_ps2_tg_ami_device; extern const device_t keyboard_ps2_tg_ami_green_device; extern const device_t keyboard_ps2_olivetti_device; -extern const device_t keyboard_ps2_mca_device; extern const device_t keyboard_ps2_mca_2_device; extern const device_t keyboard_ps2_quadtel_device; extern const device_t keyboard_ps2_pci_device; diff --git a/src/machine/m_ps2_mca.c b/src/machine/m_ps2_mca.c index 3de9ef491..328de216b 100644 --- a/src/machine/m_ps2_mca.c +++ b/src/machine/m_ps2_mca.c @@ -998,7 +998,7 @@ ps2_mca_board_model_55sx_init(int has_sec_nvram, int slots) } mca_init(slots); - device_add(&keyboard_ps2_mca_device); + device_add(&keyboard_ps2_device); if (has_sec_nvram == 1) device_add(&ps2_nvr_55ls_device); @@ -1162,7 +1162,7 @@ ps2_mca_board_model_70_type34_init(int is_type4, int slots) ps2.split_addr = mem_size * 1024; mca_init(slots); - device_add(&keyboard_ps2_mca_device); + device_add(&keyboard_ps2_device); ps2.planar_read = model_70_type3_read; ps2.planar_write = model_70_type3_write; @@ -1255,7 +1255,7 @@ ps2_mca_board_model_80_type2_init(int is486) ps2.split_addr = mem_size * 1024; mca_init(8); - device_add(&keyboard_ps2_mca_device); + device_add(&keyboard_ps2_device); ps2.planar_read = model_80_read; ps2.planar_write = model_80_write; diff --git a/src/mem/mem.c b/src/mem/mem.c index f3f0f3110..910f67619 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -2898,7 +2898,7 @@ mem_remap_top(int kb) if (addr >= 0x000c0000) addr += 0x00010000; } - if (start_addr != 0) + if (start_addr == 0) start_addr = addr; pages[c].mem = set ? &ram[addr] : page_ff; pages[c].write_b = set ? mem_write_ramb_page : NULL; diff --git a/src/port_92.c b/src/port_92.c index cbc419569..fd0471b0e 100644 --- a/src/port_92.c +++ b/src/port_92.c @@ -69,11 +69,18 @@ port_92_readw(uint16_t port, void *priv) return ret; } +/* + This does the exact same thing as keyboard controller reset. + TODO: ALi M1543(c) behavior. + */ static void port_92_pulse(void *priv) { - resetx86(); + softresetx86(); /* Pulse reset! */ cpu_set_edx(); + flushmmucache(); + + cpu_alt_reset = 1; } static void @@ -166,6 +173,15 @@ port_92_remove(void *priv) port_92_readb, NULL, NULL, port_92_writeb, NULL, NULL, dev); } +static void +port_92_reset(void *priv) +{ + cpu_alt_reset = 0; + + mem_a20_alt = 0x00; + mem_a20_recalc(); +} + static void port_92_close(void *priv) { @@ -252,7 +268,7 @@ const device_t port_92_pci_device = { .local = PORT_92_PCI, .init = port_92_init, .close = port_92_close, - .reset = NULL, + .reset = port_92_reset, { .available = NULL }, .speed_changed = NULL, .force_redraw = NULL, From 8d6181de50133e8b7a0e48e391974cf225326abf Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 22 Apr 2023 08:38:15 +0200 Subject: [PATCH 02/15] A small change in device/keyboard_at.c so the keyboard no longer loses track of what command a parameter is intended for when interrupted by another command. --- src/device/keyboard_at.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index 886016023..19a754d7b 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -788,10 +788,9 @@ keyboard_at_write(void *priv) dev->state = DEV_STATE_MAIN_WANT_IN; } - dev->command = val; - - switch (dev->command) { + switch (val) { case 0xed: /* set/reset LEDs */ + dev->command = val; keyboard_at_log("%s: set/reset LEDs\n", dev->name); dev->flags |= FLAG_CTRLDAT; kbc_at_dev_queue_add(dev, 0xfa, 0); /* ACK for command byte */ @@ -811,6 +810,7 @@ keyboard_at_write(void *priv) case 0xf0: /* get/set scan code set */ if (dev->type & FLAG_PS2) { + dev->command = val; keyboard_at_log("%s: scan code set\n", dev->name); dev->flags |= FLAG_CTRLDAT; kbc_at_dev_queue_add(dev, 0xfa, 0); /* ACK for command byte */ @@ -833,6 +833,7 @@ keyboard_at_write(void *priv) break; case 0xf3: /* set command mode */ + dev->command = val; keyboard_at_log("%s: set typematic rate/delay\n", dev->name); dev->flags |= FLAG_CTRLDAT; kbc_at_dev_queue_add(dev, 0xfa, 0); /* ACK for command byte */ From cc4dd568bd48031a9169aa59190bd210979aae97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Hrdli=C4=8Dka?= Date: Sat, 22 Apr 2023 18:05:36 +0200 Subject: [PATCH 03/15] Update README.md The contribution requirements section is basically stating the sky is blue, not sure the point of it --- README.md | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/README.md b/README.md index a1e3985e1..05a2a9ed2 100644 --- a/README.md +++ b/README.md @@ -49,16 +49,6 @@ Licensing The emulator can also optionally make use of [munt](https://github.com/munt/munt), [FluidSynth](https://www.fluidsynth.org/), [Ghostscript](https://www.ghostscript.com/) and [Discord Game SDK](https://discord.com/developers/docs/game-sdk/sdk-starter-guide), which are distributed under their respective licenses. -Contribution requirements -------------------------- - Formal codification of the project's emulated hardware contribution requirements, which all have to be met to accept an addition: -* A ROM must be available; -* Documentation must be available or it must be feasible to reverse engineer with a reasonable amount of time and effort; -* It must be feasible to implement with a reasonable amount of time and effort; -* It has to fall inside the project's scope. - -Where unsure or for more details about the project's emulated hardware contribution requirements, contact a Contributor or higher. - Donations --------- We do not charge you for the emulator but donations are still welcome: From c076406450f46df3806015d44605e45be89673a7 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sat, 22 Apr 2023 18:41:42 -0300 Subject: [PATCH 04/15] 386_common: Optimize I/O permission checking for word and dword operations (based on qemu) --- src/cpu/386_common.c | 19 ++++++++++--------- src/cpu/386_common.h | 6 +++--- src/cpu/cpu.h | 2 +- src/cpu/x86_ops_io.h | 40 ++++++++++++--------------------------- src/cpu/x86_ops_rep.h | 20 ++++++-------------- src/cpu/x86_ops_rep_dyn.h | 20 ++++++-------------- src/cpu/x86_ops_string.h | 40 ++++++++++++--------------------------- 7 files changed, 50 insertions(+), 97 deletions(-) diff --git a/src/cpu/386_common.c b/src/cpu/386_common.c index 2df72c20e..454815de0 100644 --- a/src/cpu/386_common.c +++ b/src/cpu/386_common.c @@ -1427,25 +1427,26 @@ x86illegal(void) } int -checkio(uint32_t port) +checkio(uint32_t port, int mask) { uint16_t t; - uint8_t d; cpl_override = 1; t = readmemw(tr.base, 0x66); - cpl_override = 0; - if (cpu_state.abrt) + if (cpu_state.abrt) { + cpl_override = 0; return 0; + } - if ((t + (port >> 3UL)) > tr.limit) - return 1; + if ((t + (port >> 3UL) + 1) > tr.limit) { + cpl_override = 0; + return mask; + } - cpl_override = 1; - d = readmembl(tr.base + t + (port >> 3)); + t = readmemwl(tr.base + t + (port >> 3)); cpl_override = 0; - return d & (1 << (port & 7)); + return (t >> (port & 7)) & mask; } #ifdef OLD_DIVEXCP diff --git a/src/cpu/386_common.h b/src/cpu/386_common.h index f26eb7f98..ae71347b6 100644 --- a/src/cpu/386_common.h +++ b/src/cpu/386_common.h @@ -97,11 +97,11 @@ if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \ do_mmutranslate((s) + (a), b, 4, 1) -int checkio(uint32_t port); +int checkio(uint32_t port, int mask); -#define check_io_perm(port) \ +#define check_io_perm(port, size) \ if (msw & 1 && ((CPL > IOPL) || (cpu_state.eflags & VM_FLAG))) { \ - int tempi = checkio(port); \ + int tempi = checkio(port, (1 << size) - 1); \ if (cpu_state.abrt) \ return 1; \ if (tempi) { \ diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 93dae98d1..f8ffaced3 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -642,7 +642,7 @@ extern void cpu_CPUID(void); extern void cpu_RDMSR(void); extern void cpu_WRMSR(void); -extern int checkio(uint32_t port); +extern int checkio(uint32_t port, int mask); extern void codegen_block_end(void); extern void codegen_reset(void); extern void cpu_set_edx(void); diff --git a/src/cpu/x86_ops_io.h b/src/cpu/x86_ops_io.h index c4d46404d..8a99b8668 100644 --- a/src/cpu/x86_ops_io.h +++ b/src/cpu/x86_ops_io.h @@ -2,7 +2,7 @@ static int opIN_AL_imm(uint32_t fetchdat) { uint16_t port = (uint16_t) getbytef(); - check_io_perm(port); + check_io_perm(port, 1); AL = inb(port); CLOCK_CYCLES(12); PREFETCH_RUN(12, 2, -1, 1, 0, 0, 0, 0); @@ -14,8 +14,7 @@ static int opIN_AX_imm(uint32_t fetchdat) { uint16_t port = (uint16_t) getbytef(); - check_io_perm(port); - check_io_perm(port + 1); + check_io_perm(port, 2); AX = inw(port); CLOCK_CYCLES(12); PREFETCH_RUN(12, 2, -1, 1, 0, 0, 0, 0); @@ -27,10 +26,7 @@ static int opIN_EAX_imm(uint32_t fetchdat) { uint16_t port = (uint16_t) getbytef(); - check_io_perm(port); - check_io_perm(port + 1); - check_io_perm(port + 2); - check_io_perm(port + 3); + check_io_perm(port, 4); EAX = inl(port); CLOCK_CYCLES(12); PREFETCH_RUN(12, 2, -1, 0, 1, 0, 0, 0); @@ -43,7 +39,7 @@ static int opOUT_AL_imm(uint32_t fetchdat) { uint16_t port = (uint16_t) getbytef(); - check_io_perm(port); + check_io_perm(port, 1); outb(port, AL); CLOCK_CYCLES(10); PREFETCH_RUN(10, 2, -1, 0, 0, 1, 0, 0); @@ -57,8 +53,7 @@ static int opOUT_AX_imm(uint32_t fetchdat) { uint16_t port = (uint16_t) getbytef(); - check_io_perm(port); - check_io_perm(port + 1); + check_io_perm(port, 2); outw(port, AX); CLOCK_CYCLES(10); PREFETCH_RUN(10, 2, -1, 0, 0, 1, 0, 0); @@ -70,10 +65,7 @@ static int opOUT_EAX_imm(uint32_t fetchdat) { uint16_t port = (uint16_t) getbytef(); - check_io_perm(port); - check_io_perm(port + 1); - check_io_perm(port + 2); - check_io_perm(port + 3); + check_io_perm(port, 4); outl(port, EAX); CLOCK_CYCLES(10); PREFETCH_RUN(10, 2, -1, 0, 0, 0, 1, 0); @@ -85,7 +77,7 @@ opOUT_EAX_imm(uint32_t fetchdat) static int opIN_AL_DX(uint32_t fetchdat) { - check_io_perm(DX); + check_io_perm(DX, 1); AL = inb(DX); CLOCK_CYCLES(12); PREFETCH_RUN(12, 1, -1, 1, 0, 0, 0, 0); @@ -96,8 +88,7 @@ opIN_AL_DX(uint32_t fetchdat) static int opIN_AX_DX(uint32_t fetchdat) { - check_io_perm(DX); - check_io_perm(DX + 1); + check_io_perm(DX, 2); AX = inw(DX); CLOCK_CYCLES(12); PREFETCH_RUN(12, 1, -1, 1, 0, 0, 0, 0); @@ -108,10 +99,7 @@ opIN_AX_DX(uint32_t fetchdat) static int opIN_EAX_DX(uint32_t fetchdat) { - check_io_perm(DX); - check_io_perm(DX + 1); - check_io_perm(DX + 2); - check_io_perm(DX + 3); + check_io_perm(DX, 4); EAX = inl(DX); CLOCK_CYCLES(12); PREFETCH_RUN(12, 1, -1, 0, 1, 0, 0, 0); @@ -123,7 +111,7 @@ opIN_EAX_DX(uint32_t fetchdat) static int opOUT_AL_DX(uint32_t fetchdat) { - check_io_perm(DX); + check_io_perm(DX, 1); outb(DX, AL); CLOCK_CYCLES(11); PREFETCH_RUN(11, 1, -1, 0, 0, 1, 0, 0); @@ -134,8 +122,7 @@ opOUT_AL_DX(uint32_t fetchdat) static int opOUT_AX_DX(uint32_t fetchdat) { - check_io_perm(DX); - check_io_perm(DX + 1); + check_io_perm(DX, 2); outw(DX, AX); CLOCK_CYCLES(11); PREFETCH_RUN(11, 1, -1, 0, 0, 1, 0, 0); @@ -146,10 +133,7 @@ opOUT_AX_DX(uint32_t fetchdat) static int opOUT_EAX_DX(uint32_t fetchdat) { - check_io_perm(DX); - check_io_perm(DX + 1); - check_io_perm(DX + 2); - check_io_perm(DX + 3); + check_io_perm(DX, 4); outl(DX, EAX); PREFETCH_RUN(11, 1, -1, 0, 0, 0, 1, 0); if (nmi && nmi_enable && nmi_mask) diff --git a/src/cpu/x86_ops_rep.h b/src/cpu/x86_ops_rep.h index 67bd8433d..4b8f42185 100644 --- a/src/cpu/x86_ops_rep.h +++ b/src/cpu/x86_ops_rep.h @@ -9,7 +9,7 @@ uint8_t temp; \ \ SEG_CHECK_WRITE(&cpu_state.seg_es); \ - check_io_perm(DX); \ + check_io_perm(DX, 1); \ CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG); \ high_page = 0; \ do_mmut_wb(es, DEST_REG, &addr64); \ @@ -48,8 +48,7 @@ uint16_t temp; \ \ SEG_CHECK_WRITE(&cpu_state.seg_es); \ - check_io_perm(DX); \ - check_io_perm(DX + 1); \ + check_io_perm(DX, 2); \ CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ high_page = 0; \ do_mmut_ww(es, DEST_REG, addr64a); \ @@ -88,10 +87,7 @@ uint32_t temp; \ \ SEG_CHECK_WRITE(&cpu_state.seg_es); \ - check_io_perm(DX); \ - check_io_perm(DX + 1); \ - check_io_perm(DX + 2); \ - check_io_perm(DX + 3); \ + check_io_perm(DX, 4); \ CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ high_page = 0; \ do_mmut_wl(es, DEST_REG, addr64a); \ @@ -132,7 +128,7 @@ temp = readmemb(cpu_state.ea_seg->base, SRC_REG); \ if (cpu_state.abrt) \ return 1; \ - check_io_perm(DX); \ + check_io_perm(DX, 1); \ outb(DX, temp); \ if (cpu_state.flags & D_FLAG) \ SRC_REG--; \ @@ -163,8 +159,7 @@ temp = readmemw(cpu_state.ea_seg->base, SRC_REG); \ if (cpu_state.abrt) \ return 1; \ - check_io_perm(DX); \ - check_io_perm(DX + 1); \ + check_io_perm(DX, 2); \ outw(DX, temp); \ if (cpu_state.flags & D_FLAG) \ SRC_REG -= 2; \ @@ -195,10 +190,7 @@ temp = readmeml(cpu_state.ea_seg->base, SRC_REG); \ if (cpu_state.abrt) \ return 1; \ - check_io_perm(DX); \ - check_io_perm(DX + 1); \ - check_io_perm(DX + 2); \ - check_io_perm(DX + 3); \ + check_io_perm(DX, 4); \ outl(DX, temp); \ if (cpu_state.flags & D_FLAG) \ SRC_REG -= 4; \ diff --git a/src/cpu/x86_ops_rep_dyn.h b/src/cpu/x86_ops_rep_dyn.h index 576baa403..5c64ed94d 100644 --- a/src/cpu/x86_ops_rep_dyn.h +++ b/src/cpu/x86_ops_rep_dyn.h @@ -7,7 +7,7 @@ uint8_t temp; \ \ SEG_CHECK_WRITE(&cpu_state.seg_es); \ - check_io_perm(DX); \ + check_io_perm(DX, 1); \ CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG); \ high_page = 0; \ do_mmut_wb(es, DEST_REG, &addr64); \ @@ -40,8 +40,7 @@ uint16_t temp; \ \ SEG_CHECK_WRITE(&cpu_state.seg_es); \ - check_io_perm(DX); \ - check_io_perm(DX + 1); \ + check_io_perm(DX, 2); \ CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ high_page = 0; \ do_mmut_ww(es, DEST_REG, addr64a); \ @@ -74,10 +73,7 @@ uint32_t temp; \ \ SEG_CHECK_WRITE(&cpu_state.seg_es); \ - check_io_perm(DX); \ - check_io_perm(DX + 1); \ - check_io_perm(DX + 2); \ - check_io_perm(DX + 3); \ + check_io_perm(DX, 4); \ CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ high_page = 0; \ do_mmut_wl(es, DEST_REG, addr64a); \ @@ -112,7 +108,7 @@ temp = readmemb(cpu_state.ea_seg->base, SRC_REG); \ if (cpu_state.abrt) \ return 1; \ - check_io_perm(DX); \ + check_io_perm(DX, 1); \ outb(DX, temp); \ if (cpu_state.flags & D_FLAG) \ SRC_REG--; \ @@ -137,8 +133,7 @@ temp = readmemw(cpu_state.ea_seg->base, SRC_REG); \ if (cpu_state.abrt) \ return 1; \ - check_io_perm(DX); \ - check_io_perm(DX + 1); \ + check_io_perm(DX, 2); \ outw(DX, temp); \ if (cpu_state.flags & D_FLAG) \ SRC_REG -= 2; \ @@ -163,10 +158,7 @@ temp = readmeml(cpu_state.ea_seg->base, SRC_REG); \ if (cpu_state.abrt) \ return 1; \ - check_io_perm(DX); \ - check_io_perm(DX + 1); \ - check_io_perm(DX + 2); \ - check_io_perm(DX + 3); \ + check_io_perm(DX, 4); \ outl(DX, temp); \ if (cpu_state.flags & D_FLAG) \ SRC_REG -= 4; \ diff --git a/src/cpu/x86_ops_string.h b/src/cpu/x86_ops_string.h index 5cc5f3806..c3875a648 100644 --- a/src/cpu/x86_ops_string.h +++ b/src/cpu/x86_ops_string.h @@ -804,7 +804,7 @@ opINSB_a16(uint32_t fetchdat) addr64 = 0x00000000; SEG_CHECK_WRITE(&cpu_state.seg_es); - check_io_perm(DX); + check_io_perm(DX, 1); CHECK_WRITE(&cpu_state.seg_es, DI, DI); high_page = 0; do_mmut_wb(es, DI, &addr64); @@ -830,7 +830,7 @@ opINSB_a32(uint32_t fetchdat) addr64 = 0x00000000; SEG_CHECK_WRITE(&cpu_state.seg_es); - check_io_perm(DX); + check_io_perm(DX, 1); high_page = 0; CHECK_WRITE(&cpu_state.seg_es, EDI, EDI); do_mmut_wb(es, EDI, &addr64); @@ -857,8 +857,7 @@ opINSW_a16(uint32_t fetchdat) addr64a[0] = addr64a[1] = 0x00000000; SEG_CHECK_WRITE(&cpu_state.seg_es); - check_io_perm(DX); - check_io_perm(DX + 1); + check_io_perm(DX, 2); CHECK_WRITE(&cpu_state.seg_es, DI, DI + 1UL); high_page = 0; do_mmut_ww(es, DI, addr64a); @@ -885,8 +884,7 @@ opINSW_a32(uint32_t fetchdat) SEG_CHECK_WRITE(&cpu_state.seg_es); high_page = 0; - check_io_perm(DX); - check_io_perm(DX + 1); + check_io_perm(DX, 2); CHECK_WRITE(&cpu_state.seg_es, EDI, EDI + 1UL); do_mmut_ww(es, EDI, addr64a); if (cpu_state.abrt) @@ -912,10 +910,7 @@ opINSL_a16(uint32_t fetchdat) addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; SEG_CHECK_WRITE(&cpu_state.seg_es); - check_io_perm(DX); - check_io_perm(DX + 1); - check_io_perm(DX + 2); - check_io_perm(DX + 3); + check_io_perm(DX, 4); CHECK_WRITE(&cpu_state.seg_es, DI, DI + 3UL); high_page = 0; do_mmut_wl(es, DI, addr64a); @@ -941,10 +936,7 @@ opINSL_a32(uint32_t fetchdat) addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; SEG_CHECK_WRITE(&cpu_state.seg_es); - check_io_perm(DX); - check_io_perm(DX + 1); - check_io_perm(DX + 2); - check_io_perm(DX + 3); + check_io_perm(DX, 4); CHECK_WRITE(&cpu_state.seg_es, EDI, EDI + 3UL); high_page = 0; do_mmut_wl(es, DI, addr64a); @@ -973,7 +965,7 @@ opOUTSB_a16(uint32_t fetchdat) temp = readmemb(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; - check_io_perm(DX); + check_io_perm(DX, 1); if (cpu_state.flags & D_FLAG) SI--; else @@ -993,7 +985,7 @@ opOUTSB_a32(uint32_t fetchdat) temp = readmemb(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; - check_io_perm(DX); + check_io_perm(DX, 1); if (cpu_state.flags & D_FLAG) ESI--; else @@ -1014,8 +1006,7 @@ opOUTSW_a16(uint32_t fetchdat) temp = readmemw(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; - check_io_perm(DX); - check_io_perm(DX + 1); + check_io_perm(DX, 2); if (cpu_state.flags & D_FLAG) SI -= 2; else @@ -1035,8 +1026,7 @@ opOUTSW_a32(uint32_t fetchdat) temp = readmemw(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; - check_io_perm(DX); - check_io_perm(DX + 1); + check_io_perm(DX, 2); if (cpu_state.flags & D_FLAG) ESI -= 2; else @@ -1057,10 +1047,7 @@ opOUTSL_a16(uint32_t fetchdat) temp = readmeml(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; - check_io_perm(DX); - check_io_perm(DX + 1); - check_io_perm(DX + 2); - check_io_perm(DX + 3); + check_io_perm(DX, 4); if (cpu_state.flags & D_FLAG) SI -= 4; else @@ -1080,10 +1067,7 @@ opOUTSL_a32(uint32_t fetchdat) temp = readmeml(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; - check_io_perm(DX); - check_io_perm(DX + 1); - check_io_perm(DX + 2); - check_io_perm(DX + 3); + check_io_perm(DX, 4); if (cpu_state.flags & D_FLAG) ESI -= 4; else From b6fbc748377cb046b9824960e3016ee0faa79f09 Mon Sep 17 00:00:00 2001 From: SuperMaxusa <41739128+SuperMaxusa@users.noreply.github.com> Date: Sun, 23 Apr 2023 01:05:20 +0300 Subject: [PATCH 05/15] Update uk-UA.rc --- src/win/languages/uk-UA.rc | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/win/languages/uk-UA.rc b/src/win/languages/uk-UA.rc index b3c7f4017..7c4b9ba62 100644 --- a/src/win/languages/uk-UA.rc +++ b/src/win/languages/uk-UA.rc @@ -250,7 +250,7 @@ END #define STR_CANCEL "Відміна" #define STR_GLOBAL "Зберегти ці параметри як &глобальні за замовчуванням" #define STR_DEFAULT "&За замовчуванням" -#define STR_LANGUAGE "Язык:" +#define STR_LANGUAGE "Мова:" #define STR_ICONSET "Набір іконок:" #define STR_GAIN "Посилення" @@ -306,11 +306,11 @@ END #define STR_NET_TYPE "Тип мережі:" #define STR_PCAP "Пристрій PCap:" -#define STR_NET "Мережева карта:" -#define STR_NET1 "Network card 1:" -#define STR_NET2 "Network card 2:" -#define STR_NET3 "Network card 3:" -#define STR_NET4 "Network card 4:" +#define STR_NET "Мережевий адаптер:" +#define STR_NET1 "Мережева карта 1:" +#define STR_NET2 "Мережева карта 2:" +#define STR_NET3 "Мережева карта 3:" +#define STR_NET4 "Мережева карта 4:" #define STR_COM1 "Пристрій COM1:" #define STR_COM2 "Пристрій COM2:" @@ -404,11 +404,11 @@ BEGIN IDS_2055 "Образи ZIP (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0" IDS_2056 "86Box не зміг знайти жодного відповідного для використання файлу з ПЗУ.\n\nБудь ласка завантажте набір ПЗУ і витягніть його в каталог ""roms""." IDS_2057 "(порожньо)" - IDS_2058 "Образи ZIP (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0Всі файли (*.*)\0*.*\0" + IDS_2058 "Образи ZIP (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0Усі файли (*.*)\0*.*\0" IDS_2059 "Турбо" IDS_2060 "Увімк" IDS_2061 "Вимк" - IDS_2062 "Всі образи (*.86F;*.DSK;*.FLP;*.IM?;*.*FD?)\0*.86F;*.DSK;*.FLP;*.IM?;*.*FD?\0Прості посекторні образи (*.DSK;*.FLP;*.IM?;*.*FD?)\0*.DSK;*.FLP;*.IM?;*.IMG;*.*FD?\0Образ поверхні (*.86F)\0*.86F\0" + IDS_2062 "Усі образи (*.86F;*.DSK;*.FLP;*.IM?;*.*FD?)\0*.86F;*.DSK;*.FLP;*.IM?;*.*FD?\0Прості посекторні образи (*.DSK;*.FLP;*.IM?;*.*FD?)\0*.DSK;*.FLP;*.IM?;*.IMG;*.*FD?\0Образ поверхні (*.86F)\0*.86F\0" IDS_2063 "Системна плата ""%hs"" недоступна через відсутність файлу її ПЗУ в каталозі roms/machines. Переключення на доступну системну плату." END @@ -464,14 +464,14 @@ BEGIN IDS_2107 "%u" IDS_2108 "%u МБ (CHS: %i, %i, %i)" IDS_2109 "Дисковод %i (%s): %ls" - IDS_2110 "Всі образи (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Розширені образи секторів (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Основні образи секторів (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Образи Flux (*.FDI)\0*.FDI\0Образи Surface (*.86F;*.MFM)\0*.86F;*.MFM\0Всі файли (*.*)\0*.*\0" + IDS_2110 "Усі образи (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Розширені образи секторів (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Основні образи секторів (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Образи Flux (*.FDI)\0*.FDI\0Образи Surface (*.86F;*.MFM)\0*.86F;*.MFM\0Всі файли (*.*)\0*.*\0" IDS_2111 "Неможливо ініціалізувати FreeType" IDS_2112 "Неможливо ініціалізувати SDL, потрібно SDL2.dll" IDS_2113 "Ви впевнені, що хочете виконати холодне перезавантаження емульованої машини?" IDS_2114 "Ви впевнені, що хочете вийти з 86Box?" IDS_2115 "Неможливо ініціалізувати Ghostscript" IDS_2116 "Магнітооптичний %i (%ls): %ls" - IDS_2117 "Образи магнітооптичних дисків (*.IM?;*.MDI)\0*.IM?;*.MDI\0Все файлы (*.*)\0*.*\0" + IDS_2117 "Образи магнітооптичних дисків (*.IM?;*.MDI)\0*.IM?;*.MDI\0Усі файлі (*.*)\0*.*\0" IDS_2118 "Ласкаво просимо в 86Box!" IDS_2119 "Вбудований контролер" IDS_2120 "Вихід" @@ -503,7 +503,7 @@ BEGIN #else #define LIB_NAME_GS "libgs" #endif - IDS_2133 LIB_NAME_GS " потрібно для автоматичного перетворення файлів PostScript в PDF.\n\nВсі документи, відправлені на загальний принтер PostScript, будуть збережені у вигляді файлів PostScript (.ps)." + IDS_2133 LIB_NAME_GS " потрібно для автоматичного перетворення файлів PostScript в PDF.\n\nсі документи, відправлені на загальний принтер PostScript, будуть збережені у вигляді файлів PostScript (.ps)." #ifdef _WIN32 #define LIB_NAME_FLUIDSYNTH "libfluidsynth.dll" #else @@ -527,7 +527,7 @@ BEGIN IDS_2149 "Касета: %s" IDS_2150 "Образи касет (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Усі файли (*.*)\0*. *\0" IDS_2151 "Картридж %i: %ls" - IDS_2152 "Образи картриджів (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Всі файли (*.*)\0*.*\0" + IDS_2152 "Образи картриджів (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Усі файли (*.*)\0*.*\0" IDS_2153 "Помилка ініціалізації рендерера" IDS_2154 "Неможливо ініціалізувати рендерер OpenGL (3.0). Будь ласка, використовуйте інший рендерер." IDS_2155 "Відновити виконання" @@ -541,7 +541,7 @@ BEGIN IDS_2163 "No Dynarec" IDS_2164 "Old Dynarec" IDS_2165 "New Dynarec" - IDS_2166 "Video card #2 ""%hs"" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." + IDS_2166 "Відеокарта #2 ""%hs"" недоступна через відсутність файлу її ПЗУ в каталозі roms/video. Відключення другої відеокарти." END STRINGTABLE DISCARDABLE @@ -556,7 +556,7 @@ BEGIN IDS_4103 "Вибрати існуючий жорсткий диск" IDS_4104 "Розмір образів дисків HDI не може перевищувати 4 ГБ." IDS_4105 "Розмір образів дисків не може перевищувати 127 ГБ." - IDS_4106 "Образи жорстких дисків (*.HD?;*.IM?;*.VHD)\0*.HD?;*.IM?;*.VHD\0Всі файли (*.*)\0*.*\0 " + IDS_4106 "Образи жорстких дисків (*.HD?;*.IM?;*.VHD)\0*.HD?;*.IM?;*.VHD\0Усі файли (*.*)\0*.*\0 " IDS_4107 "Неможливо прочитати файл" IDS_4108 "Неможливо записати файл" IDS_4109 "Образи HDI або HDX з розміром сектора, відмінним від 512, не підтримуються." @@ -580,7 +580,7 @@ BEGIN IDS_4127 "Диференційований образ VHD (.vhd)" IDS_4128 "Великі блоки (2 МБ)" IDS_4129 "Маленькі блоки (512 КБ)" - IDS_4130 "Файли VHD (*.VHD)\0*.VHD\0Всі файли (*.*)\0*.*\0" + IDS_4130 "Файли VHD (*.VHD)\0*.VHD\0Усі файли (*.*)\0*.*\0" IDS_4131 "Виберіть батьківський VHD" IDS_4132 "Це може означати, що батьківський образ був змінений після того, як було створено диференційований образ.\n\nЦе також може статися, якщо файли зображення були переміщені або скопійовані, або через помилку в програмі, що створила цей диск.\n \nВи хочете виправити тимчасові позначки?" IDS_4133 "Тимчасові мітки батьківського та дочірнього дисків не співпадають" From 3dbb03d6e418907698e697ee2ce5cc3bd1368e61 Mon Sep 17 00:00:00 2001 From: SuperMaxusa <41739128+SuperMaxusa@users.noreply.github.com> Date: Sun, 23 Apr 2023 01:07:52 +0300 Subject: [PATCH 06/15] Update uk-UA.po --- src/qt/languages/uk-UA.po | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qt/languages/uk-UA.po b/src/qt/languages/uk-UA.po index 0ebe3e5cc..4193fe934 100644 --- a/src/qt/languages/uk-UA.po +++ b/src/qt/languages/uk-UA.po @@ -305,7 +305,7 @@ msgid "&Default" msgstr "&За замовчуванням" msgid "Language:" -msgstr "Язык:" +msgstr "Мова:" msgid "Icon set:" msgstr "Набір іконок:" @@ -446,7 +446,7 @@ msgid "PCap device:" msgstr "Пристрій PCap:" msgid "Network adapter:" -msgstr "Мережева карта:" +msgstr "Мережевий адаптер:" msgid "COM1 Device:" msgstr "Пристрій COM1:" From 9f55afc7a1b7ee85005904302444a9dc7c6347ba Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sat, 22 Apr 2023 21:37:41 -0300 Subject: [PATCH 07/15] Add LIKELY/UNLIKELY macros --- src/include/86box/86box.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/include/86box/86box.h b/src/include/86box/86box.h index b88fa24ef..a4c0a5761 100644 --- a/src/include/86box/86box.h +++ b/src/include/86box/86box.h @@ -55,6 +55,14 @@ #define BCD16(x) ((((x) / 1000) << 12) | (((x) / 100) << 8) | BCD8(x)) #define BCD32(x) ((((x) / 10000000) << 28) | (((x) / 1000000) << 24) | (((x) / 100000) << 20) | (((x) / 10000) << 16) | BCD16(x)) +#if defined(__GNUC__) || defined(__clang__) +# define UNLIKELY(x) __builtin_expect((x), 0) +# define LIKELY(x) __builtin_expect((x), 1) +#else +# define UNLIKELY(x) (x) +# define LIKELY(x) (x) +#endif + #ifdef __cplusplus extern "C" { #endif From 4253c7bae73daa5658c6de4d13bc299e33981347 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sat, 22 Apr 2023 22:28:18 -0300 Subject: [PATCH 08/15] 386_common: Handle IOPB segment limit corner case more like the old code --- src/cpu/386_common.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/src/cpu/386_common.c b/src/cpu/386_common.c index 454815de0..25afccc95 100644 --- a/src/cpu/386_common.c +++ b/src/cpu/386_common.c @@ -1053,13 +1053,13 @@ enter_smm(int in_hlt) memset(saved_state, 0x00, SMM_SAVE_STATE_MAP_SIZE * sizeof(uint32_t)); - if (is_cxsmm) /* Cx6x86 */ + if (is_cxsmm) /* Cx6x86 */ smram_save_state_cyrix(saved_state, in_hlt); else if (is_pentium || is_am486) /* Am486 / 5x86 / Intel P5 (Pentium) */ smram_save_state_p5(saved_state, in_hlt); - else if (is_k5 || is_k6) /* AMD K5 and K6 */ + else if (is_k5 || is_k6) /* AMD K5 and K6 */ smram_save_state_amd_k(saved_state, in_hlt); - else if (is_p6) /* Intel P6 (Pentium Pro, Pentium II, Celeron) */ + else if (is_p6) /* Intel P6 (Pentium Pro, Pentium II, Celeron) */ smram_save_state_p6(saved_state, in_hlt); cr0 &= ~0x8000000d; @@ -1224,13 +1224,13 @@ leave_smm(void) } x386_common_log("New SMBASE: %08X (%08X)\n", saved_state[SMRAM_FIELD_P5_SMBASE_OFFSET], saved_state[66]); - if (is_cxsmm) /* Cx6x86 */ + if (is_cxsmm) /* Cx6x86 */ smram_restore_state_cyrix(saved_state); else if (is_pentium || is_am486) /* Am486 / 5x86 / Intel P5 (Pentium) */ smram_restore_state_p5(saved_state); - else if (is_k5 || is_k6) /* AMD K5 and K6 */ + else if (is_k5 || is_k6) /* AMD K5 and K6 */ smram_restore_state_amd_k(saved_state); - else if (is_p6) /* Intel P6 (Pentium Pro, Pentium II, Celeron) */ + else if (is_p6) /* Intel P6 (Pentium Pro, Pentium II, Celeron) */ smram_restore_state_p6(saved_state); in_smm = 0; @@ -1429,24 +1429,27 @@ x86illegal(void) int checkio(uint32_t port, int mask) { - uint16_t t; + uint32_t t; cpl_override = 1; t = readmemw(tr.base, 0x66); - if (cpu_state.abrt) { + if (UNLIKELY(cpu_state.abrt)) { cpl_override = 0; return 0; } - if ((t + (port >> 3UL) + 1) > tr.limit) { - cpl_override = 0; - return mask; + t += (port >> 3UL); + mask <<= (port & 7); + if (UNLIKELY(mask & 0xff00)) { + if (LIKELY(t < tr.limit)) + mask &= readmemwl(tr.base + t); + } else { + if (LIKELY(t <= tr.limit)) + mask &= readmembl(tr.base + t); } - - t = readmemwl(tr.base + t + (port >> 3)); cpl_override = 0; - return (t >> (port & 7)) & mask; + return mask; } #ifdef OLD_DIVEXCP From 982c3a4f38cc63bc5d729ee9a7f98613566e98f2 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 23 Apr 2023 16:39:56 +0600 Subject: [PATCH 09/15] qt_d3d9renderer: HiDPI and stability fixes --- src/qt/qt_d3d9renderer.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/qt/qt_d3d9renderer.cpp b/src/qt/qt_d3d9renderer.cpp index fed8e72b3..bbbb80e59 100644 --- a/src/qt/qt_d3d9renderer.cpp +++ b/src/qt/qt_d3d9renderer.cpp @@ -80,7 +80,7 @@ D3D9Renderer::showEvent(QShowEvent *event) params.BackBufferCount = 1; params.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; params.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; - params.hDeviceWindow = windowHandle; + params.hDeviceWindow = (HWND) winId(); HRESULT result = d3d9->CreateDeviceEx(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, windowHandle, D3DCREATE_MULTITHREADED | D3DCREATE_HARDWARE_VERTEXPROCESSING, ¶ms, nullptr, &d3d9dev); if (FAILED(result)) @@ -118,10 +118,10 @@ D3D9Renderer::paintEvent(QPaintEvent *event) srcRect.bottom = source.bottom(); srcRect.left = source.left(); srcRect.right = source.right(); - dstRect.top = destination.top(); - dstRect.bottom = destination.bottom(); - dstRect.left = destination.left(); - dstRect.right = destination.right(); + dstRect.top = destination.top() * devicePixelRatioF(); + dstRect.bottom = destination.bottom() * devicePixelRatioF(); + dstRect.left = destination.left() * devicePixelRatioF(); + dstRect.right = destination.right() * devicePixelRatioF(); d3d9dev->BeginScene(); d3d9dev->Clear(0, nullptr, D3DCLEAR_TARGET, 0xFF000000, 0, 0); while (surfaceInUse) { } From 46cd82e54f3b2c15bb8e59be2f090824e4c40495 Mon Sep 17 00:00:00 2001 From: SuperMaxusa <41739128+SuperMaxusa@users.noreply.github.com> Date: Sun, 23 Apr 2023 15:27:10 +0300 Subject: [PATCH 10/15] small fix in uk-UA.rc --- src/win/languages/uk-UA.rc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/win/languages/uk-UA.rc b/src/win/languages/uk-UA.rc index 7c4b9ba62..df9350364 100644 --- a/src/win/languages/uk-UA.rc +++ b/src/win/languages/uk-UA.rc @@ -464,7 +464,7 @@ BEGIN IDS_2107 "%u" IDS_2108 "%u МБ (CHS: %i, %i, %i)" IDS_2109 "Дисковод %i (%s): %ls" - IDS_2110 "Усі образи (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Розширені образи секторів (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Основні образи секторів (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Образи Flux (*.FDI)\0*.FDI\0Образи Surface (*.86F;*.MFM)\0*.86F;*.MFM\0Всі файли (*.*)\0*.*\0" + IDS_2110 "Усі образи (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Розширені образи секторів (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Основні образи секторів (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Образи Flux (*.FDI)\0*.FDI\0Образи Surface (*.86F;*.MFM)\0*.86F;*.MFM\0Усі файли (*.*)\0*.*\0" IDS_2111 "Неможливо ініціалізувати FreeType" IDS_2112 "Неможливо ініціалізувати SDL, потрібно SDL2.dll" IDS_2113 "Ви впевнені, що хочете виконати холодне перезавантаження емульованої машини?" From 2d222f22c7b7d41252b4cbb4adf6a4444ad9a514 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 23 Apr 2023 20:39:34 +0600 Subject: [PATCH 11/15] qt: Destroy existing Direct3D 9 devices if it exists --- src/qt/qt_d3d9renderer.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/qt/qt_d3d9renderer.cpp b/src/qt/qt_d3d9renderer.cpp index bbbb80e59..f2c9fe9f4 100644 --- a/src/qt/qt_d3d9renderer.cpp +++ b/src/qt/qt_d3d9renderer.cpp @@ -24,11 +24,16 @@ D3D9Renderer::D3D9Renderer(QWidget *parent, int monitor_index) windowHandle = (HWND) winId(); surfaceInUse = true; + finalized = true; RendererCommon::parentWidget = parent; this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); this->m_monitor_index = monitor_index; + + d3d9surface = nullptr; + d3d9dev = nullptr; + d3d9 = nullptr; } D3D9Renderer::~D3D9Renderer() @@ -67,6 +72,7 @@ D3D9Renderer::hideEvent(QHideEvent *event) void D3D9Renderer::showEvent(QShowEvent *event) { + if (d3d9) finalize(); params = {}; if (FAILED(Direct3DCreate9Ex(D3D_SDK_VERSION, &d3d9))) { From 3b54cb085eca1ef674604ae10c29cfa3349ecba7 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 24 Apr 2023 02:47:17 +0200 Subject: [PATCH 12/15] Some minor bugfixes. --- src/chipset/ali1543.c | 13 +++++++++---- src/device/kbc_at.c | 26 ++++++++++++++++++++++++-- src/device/kbc_at_dev.c | 2 +- src/device/mouse_ps2.c | 3 +-- src/sio/sio_ali5123.c | 4 ++++ 5 files changed, 39 insertions(+), 9 deletions(-) diff --git a/src/chipset/ali1543.c b/src/chipset/ali1543.c index 0b5fe5761..f3296bd20 100644 --- a/src/chipset/ali1543.c +++ b/src/chipset/ali1543.c @@ -151,11 +151,13 @@ ali1533_write(int func, int addr, uint8_t val, void *priv) break; case 0x41: - /* TODO: Bit 7 selects keyboard controller type: - 0 = AT, 1 = PS/2 */ pic_kbd_latch(1); - pic_mouse_latch(!!(val & 0x40)); - dev->pci_conf[addr] = val & 0xbf; + // pic_kbd_latch(!!(val & 0x80)); + if (dev->type == 1) + pic_mouse_latch(!!(val & 0x40) || !(dev->pci_conf[0x78] & 0x02)); + else + pic_mouse_latch(!!(val & 0x40)); + dev->pci_conf[addr] = val; break; case 0x42: /* ISA Bus Speed */ @@ -431,6 +433,7 @@ ali1533_write(int func, int addr, uint8_t val, void *priv) if (dev->type == 1) { ali1543_log("PCI78 = %02X\n", val); dev->pci_conf[addr] = val & 0x33; + pic_mouse_latch(!!(dev->pci_conf[0x41] & 0x40) || !(val & 0x02)); } break; @@ -1520,6 +1523,8 @@ ali1543_reset(void *priv) ali1533_write(0, 0x74, 0x00, dev); ali1533_write(0, 0x75, 0x00, dev); ali1533_write(0, 0x76, 0x00, dev); + if (dev->type == 1) + ali1533_write(0, 0x78, 0x00, dev); unmask_a20_in_smm = 1; } diff --git a/src/device/kbc_at.c b/src/device/kbc_at.c index 2c9433bd9..9b8a3de3d 100644 --- a/src/device/kbc_at.c +++ b/src/device/kbc_at.c @@ -801,12 +801,30 @@ write64_generic(void *priv, uint8_t val) IBM PS/1: xxxxxxxx IBM PS/2 MCA: xxxxx1xx Intel AMI Pentium BIOS'es with AMI MegaKey KB-5 keyboard controller: x1x1xxxx - Acer: xxx0x0xx + Acer: xxxxx0xx Packard Bell PB450: xxxxx1xx P6RP4: xx1xx1xx Epson Action Tower 2600: xxxx01xx TriGem Hawk: xxxx11xx + Machine input based on current code: 11111111 + Everything non-Green: Pull down bit 7 if not PS/2 and keyboard is inhibited. + Pull down bit 6 if primary display is CGA. + Xi8088: Pull down bit 6 if primary display is MDA. + Acer: Pull down bit 6 if primary display is MDA. + Pull down bit 2 always (must be so to enable CMOS Setup). + IBM PS/1: Pull down bit 6 if current floppy drive is 3.5". + Epson Action Tower 2600: Pull down bit 3 always (for Epson logo). + NCR: Pull down bit 5 always (power-on default speed = high). + Pull down bit 3 if there is no FPU. + Pull down bits 1 and 0 always? + Compaq: Pull down bit 6 if Compaq dual-scan display is in use. + Pull down bit 5 if system board DIP switch is ON. + Pull down bit 4 if CPU speed selected is auto. + Pull down bit 3 if CPU speed selected is slow (4 MHz). + Pull down bit 2 if FPU is present. + Pull down bits 1 and 0 always? + Bit 7: AT KBC only - keyboard inhibited (often physical lock): 0 = yes, 1 = no (also Compaq); Bit 6: Mostly, display: 0 = CGA, 1 = MDA, inverted on Xi8088 and Acer KBC's; Intel AMI MegaKey KB-5: Used for green features, SMM handler expects it to be set; @@ -817,7 +835,6 @@ write64_generic(void *priv, uint8_t val) Compaq: System board DIP switch 5: 0 = ON, 1 = OFF. Bit 4: (Which board?): RAM on motherboard: 0 = 512 kB, 1 = 256 kB; NCR: RAM on motherboard: 0 = unsupported, 1 = 512 kB; - Acer: Must be 0; Intel AMI MegaKey KB-5: Must be 1; IBM PS/1: Ignored; Compaq: 0 = Auto speed selected, 1 = High speed selected. @@ -851,6 +868,7 @@ write64_generic(void *priv, uint8_t val) fixed_bits |= 0x40; if (kbc_ven == KBC_VEN_IBM_PS1) { current_drive = fdc_get_current_drive(); + /* (B0 or F0) | (fdd_is_525(current_drive) on bit 6) */ add_to_kbc_queue_front(dev, dev->p1 | fixed_bits | (fdd_is_525(current_drive) ? 0x40 : 0x00), 0, 0x00); } else if (kbc_ven == KBC_VEN_NCR) { @@ -864,6 +882,7 @@ write64_generic(void *priv, uint8_t val) * bit 1: high/auto speed * bit 0: dma mode */ + /* (B0 or F0) | 0x04 | (display on bit 6) | (fpu on bit 3) */ add_to_kbc_queue_front(dev, (dev->p1 | fixed_bits | (video_is_mda() ? 0x40 : 0x00) | (hasfpu ? 0x08 : 0x00)) & 0xdf, 0, 0x00); } else if (kbc_ven == KBC_VEN_TRIGEM_AMI) { @@ -874,10 +893,13 @@ write64_generic(void *priv, uint8_t val) 0, 0: Generic AMI logo. */ if (dev->misc_flags & FLAG_PCI) fixed_bits |= 8; + /* (B0 or F0) | (0x04 or 0x0c) */ add_to_kbc_queue_front(dev, dev->p1 | fixed_bits, 0, 0x00); } else if (((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) && ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_GREEN)) + /* (B0 or F0) | (0x08 or 0x0c) */ add_to_kbc_queue_front(dev, ((dev->p1 | fixed_bits) & 0xf0) | (((dev->flags & KBC_VEN_MASK) == KBC_VEN_ACER) ? 0x08 : 0x0c), 0, 0x00); else + /* (B0 or F0) | (0x04 or 0x44) */ add_to_kbc_queue_front(dev, dev->p1 | fixed_bits, 0, 0x00); dev->p1 = ((dev->p1 + 1) & 3) | (dev->p1 & 0xfc); return 0; diff --git a/src/device/kbc_at_dev.c b/src/device/kbc_at_dev.c index 87fdd51c6..ca3dc1361 100644 --- a/src/device/kbc_at_dev.c +++ b/src/device/kbc_at_dev.c @@ -119,7 +119,7 @@ kbc_at_dev_poll(void *priv) case DEV_STATE_MAIN_2: /* Output from scan queue if needed and then return to main loop #1. */ if (*dev->scan && (dev->port->out_new == -1) && (dev->queue_start != dev->queue_end)) { - kbc_at_dev_log("%s %1: %02X (DATA) on channel 1\n", dev->name, dev->inst, dev->queue[dev->queue_start]); + kbc_at_dev_log("%s: %02X (DATA) on channel 1\n", dev->name, dev->queue[dev->queue_start]); dev->port->out_new = dev->queue[dev->queue_start]; dev->queue_start = (dev->queue_start + 1) & 0xf; } diff --git a/src/device/mouse_ps2.c b/src/device/mouse_ps2.c index 4027c6173..5563909ba 100644 --- a/src/device/mouse_ps2.c +++ b/src/device/mouse_ps2.c @@ -135,6 +135,7 @@ ps2_set_defaults(atkbc_dev_t *dev) dev->mode = MODE_STREAM; dev->rate = 1; dev->flags &= 0x88; + mouse_scan = 0; } static void @@ -144,8 +145,6 @@ ps2_bat(void *priv) ps2_set_defaults(dev); - mouse_scan = 1; - kbc_at_dev_queue_add(dev, 0xaa, 0); kbc_at_dev_queue_add(dev, 0x00, 0); } diff --git a/src/sio/sio_ali5123.c b/src/sio/sio_ali5123.c index 33e4022c6..54949a125 100644 --- a/src/sio/sio_ali5123.c +++ b/src/sio/sio_ali5123.c @@ -174,6 +174,7 @@ ali5123_reset(ali5123_t *dev) serial_setup(dev->uart[1], 0x03e8, dev->ld_regs[5][0x70]); /* Logical device 7: Keyboard */ + dev->ld_regs[7][0x30] = 1; dev->ld_regs[7][0x70] = 1; /* TODO: Register F0 bit 6: 0 = PS/2, 1 = AT */ @@ -253,6 +254,9 @@ ali5123_write(uint16_t port, uint8_t val, void *priv) case 0x06: case 0x08 ... 0x0a: return; + case 0x07: + if (dev->cur_reg == 0xf0) + val &= 0xbf; } dev->ld_regs[cur_ld][dev->cur_reg] = val; } From 78a897f07aaf24c9e3b0cbcfa52fe0f6678df5b9 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 26 Apr 2023 01:42:23 +0200 Subject: [PATCH 13/15] 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. --- src/chipset/intel_sio.c | 20 +++++++++++++++++--- src/device/kbc_at.c | 3 ++- src/device/kbc_at_dev.c | 4 ++-- src/device/mouse.c | 24 ++++++++++++++++++------ src/device/mouse_ps2.c | 14 +++++++++++++- src/include/86box/mouse.h | 2 ++ src/pic.c | 4 ++-- 7 files changed, 56 insertions(+), 15 deletions(-) diff --git a/src/chipset/intel_sio.c b/src/chipset/intel_sio.c index eb7aad983..3f253d832 100644 --- a/src/chipset/intel_sio.c +++ b/src/chipset/intel_sio.c @@ -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; } diff --git a/src/device/kbc_at.c b/src/device/kbc_at.c index 9b8a3de3d..24121e699 100644 --- a/src/device/kbc_at.c +++ b/src/device/kbc_at.c @@ -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"); diff --git a/src/device/kbc_at_dev.c b/src/device/kbc_at_dev.c index ca3dc1361..71a0b4e08 100644 --- a/src/device/kbc_at_dev.c +++ b/src/device/kbc_at_dev.c @@ -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 * diff --git a/src/device/mouse.c b/src/device/mouse.c index 13d9999c7..0ee714377 100644 --- a/src/device/mouse.c +++ b/src/device/mouse.c @@ -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. */ diff --git a/src/device/mouse_ps2.c b/src/device/mouse_ps2.c index 5563909ba..7d9730f28 100644 --- a/src/device/mouse_ps2.c +++ b/src/device/mouse_ps2.c @@ -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); diff --git a/src/include/86box/mouse.h b/src/include/86box/mouse.h index 317e267a0..b697c5d38 100644 --- a/src/include/86box/mouse.h +++ b/src/include/86box/mouse.h @@ -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); diff --git a/src/pic.c b/src/pic.c index 25a90e1c7..4f9b8aa8f 100644 --- a/src/pic.c +++ b/src/pic.c @@ -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); From 9874efcbf5151741fb523602059ed904f6805612 Mon Sep 17 00:00:00 2001 From: Moonif Fatayri Date: Wed, 26 Apr 2023 19:27:04 +0400 Subject: [PATCH 14/15] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 05a2a9ed2..158a8677f 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,7 @@ It is also recommended to use a manager application with 86Box for easier handli * [86Box Manager](https://github.com/86Box/86BoxManager) by [Overdoze](https://github.com/daviunic) (Windows only) * [86Box Manager Lite](https://github.com/insanemal/86box_manager_py) by [Insanemal](https://github.com/insanemal) * [WinBox for 86Box](https://github.com/86Box/WinBox-for-86Box) by Laci bá' (Windows only) +* [MacBox for 86Box](https://github.com/Moonif/MacBox) by [Moonif](https://github.com/Moonif) (MacOs only) It is also possible to use 86Box on its own with the `--vmpath`/`-P` command line option. From 5d0304d52023d9f677ff6443e99e1f6723568c6a Mon Sep 17 00:00:00 2001 From: Moonif Fatayri Date: Wed, 26 Apr 2023 19:29:23 +0400 Subject: [PATCH 15/15] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 158a8677f..72cd0c9d9 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ It is also recommended to use a manager application with 86Box for easier handli * [86Box Manager](https://github.com/86Box/86BoxManager) by [Overdoze](https://github.com/daviunic) (Windows only) * [86Box Manager Lite](https://github.com/insanemal/86box_manager_py) by [Insanemal](https://github.com/insanemal) * [WinBox for 86Box](https://github.com/86Box/WinBox-for-86Box) by Laci bá' (Windows only) -* [MacBox for 86Box](https://github.com/Moonif/MacBox) by [Moonif](https://github.com/Moonif) (MacOs only) +* [MacBox for 86Box](https://github.com/Moonif/MacBox) by [Moonif](https://github.com/Moonif) (MacOS only) It is also possible to use 86Box on its own with the `--vmpath`/`-P` command line option.