From 72c1c36ec639a68e9080e80fac8e30f1e2b3a2da Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 10 Jul 2020 02:05:49 +0200 Subject: [PATCH] OPTi 5x7 no longer does excess logging, running of timers on the recompiler is now done on every fourth AT KBC port 61h read instead of every 3F4h read, added some safety precautions to io.c to handle the cases where a handler removes itself, implmented the STPC ELCR and refresh control, and fixed the messed up register reading in the PC87307 and PC87309 implementations. --- src/chipset/opti5x7.c | 25 +++++++++++++++++++-- src/chipset/stpc.c | 14 +++++++++++- src/device/keyboard_at.c | 8 +++++-- src/floppy/fdc.c | 6 +---- src/include/86box/pci.h | 3 +++ src/include/86box/pit.h | 2 ++ src/io.c | 48 +++++++++++++++++++++++++--------------- src/machine/m_at.c | 1 + src/machine/m_ps1.c | 1 + src/machine/m_ps2_isa.c | 1 + src/pci.c | 12 ++++++++-- src/pit.c | 5 +++-- src/sio/sio_pc87307.c | 4 ++-- src/sio/sio_pc87309.c | 6 ++--- 14 files changed, 99 insertions(+), 37 deletions(-) diff --git a/src/chipset/opti5x7.c b/src/chipset/opti5x7.c index af224437d..d851da766 100644 --- a/src/chipset/opti5x7.c +++ b/src/chipset/opti5x7.c @@ -41,6 +41,27 @@ typedef struct port_92_t *port_92; } opti5x7_t; + +#ifdef ENABLE_OPTI5X7_LOG +int opti5x7_do_log = ENABLE_OPTI5X7_LOG; + + +static void +opti5x7_log(const char *fmt, ...) +{ + va_list ap; + + if (opti5x7_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define opti5x7_log(fmt, ...) +#endif + + static void opti5x7_recalc(opti5x7_t *dev) { @@ -81,7 +102,7 @@ static void opti5x7_write(uint16_t addr, uint8_t val, void *priv) { opti5x7_t *dev = (opti5x7_t *) priv; - pclog("Write %02x to OPTi 5x7 address %02x\n", val, addr); + opti5x7_log("Write %02x to OPTi 5x7 address %02x\n", val, addr); switch (addr) { case 0x22: @@ -113,7 +134,7 @@ opti5x7_read(uint16_t addr, void *priv) switch (addr) { case 0x24: - pclog("Read from OPTi 5x7 register %02x\n", dev->idx); + opti5x7_log("Read from OPTi 5x7 register %02x\n", dev->idx); ret = dev->regs[dev->idx]; break; } diff --git a/src/chipset/stpc.c b/src/chipset/stpc.c index f0a821f32..6d5177be8 100644 --- a/src/chipset/stpc.c +++ b/src/chipset/stpc.c @@ -27,6 +27,8 @@ #include <86box/rom.h> #include <86box/pci.h> #include <86box/pic.h> +#include <86box/timer.h> +#include <86box/pit.h> #include <86box/device.h> #include <86box/keyboard.h> #include <86box/port_92.h> @@ -631,6 +633,9 @@ stpc_reg_write(uint16_t addr, uint8_t val, void *priv) case 0x56: case 0x57: /* ELCR goes here */ + elcr_write(dev->reg_offset, val, NULL); + if (dev->reg_offset == 0x57) + refresh_at_enable = val & 0x01; break; } @@ -649,7 +654,11 @@ stpc_reg_read(uint16_t addr, void *priv) ret = dev->reg_offset; else if (dev->reg_offset >= 0xc0) return 0xff; /* Cyrix CPU registers: let the CPU code handle those */ - else + else if ((dev->reg_offset == 0x56) || (dev->reg_offset == 0x57)) { + ret = elcr_read(dev->reg_offset, NULL); + if (dev->reg_offset == 0x57) + ret |= (dev->regs[dev->reg_offset] & 0x01); + } else ret = dev->regs[dev->reg_offset]; stpc_log("STPC: reg_read(%04X) = %02X\n", addr, ret); @@ -837,6 +846,9 @@ stpc_init(const device_t *info) device_add(&port_92_pci_device); + pci_elcr_io_disable(); + refresh_at_enable = 0; + return dev; } diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index ee5b0f496..8415538c9 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -2207,6 +2207,7 @@ kbd_read(uint16_t port, void *priv) { atkbd_t *dev = (atkbd_t *)priv; uint8_t ret = 0xff; + static int flip_flop = 0; if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) sub_cycles(ISA_CYCLES(8)); @@ -2244,11 +2245,14 @@ kbd_read(uint16_t port, void *priv) else ret &= ~0x04; } +#ifdef USE_DYNAREC + flip_flop = (flip_flop + 1) & 3; + if (cpu_use_dynarec && (flip_flop == 3)) + update_tsc(); +#endif break; case 0x64: - // ret = (dev->status & 0xFB) | (keyboard_mode & CCB_SYSTEM); - // ret |= STAT_UNLOCKED; ret = (dev->status & 0xFB); if (dev->mem[0] & STAT_SYSFLAG) ret |= STAT_SYSFLAG; diff --git a/src/floppy/fdc.c b/src/floppy/fdc.c index c49ba984d..47784982a 100644 --- a/src/floppy/fdc.c +++ b/src/floppy/fdc.c @@ -1350,10 +1350,6 @@ fdc_read(uint16_t addr, void *priv) break; case 4: /*Status*/ ret = fdc->stat; -#ifdef USE_DYNAREC - if (cpu_use_dynarec) - update_tsc(); -#endif break; case 5: /*Data*/ if ((fdc->stat & 0xf0) == 0xf0) { @@ -1891,7 +1887,7 @@ fdc_data(fdc_t *fdc, uint8_t data) void fdc_finishread(fdc_t *fdc) { - fdc->inread = 0; + fdc->inread = 0; } diff --git a/src/include/86box/pci.h b/src/include/86box/pci.h index 7fb118195..830324c1a 100644 --- a/src/include/86box/pci.h +++ b/src/include/86box/pci.h @@ -103,6 +103,9 @@ extern uint8_t trc_read(uint16_t port, void *priv); extern void trc_write(uint16_t port, uint8_t val, void *priv); extern void pci_elcr_set_enabled(int enabled); +extern void pci_elcr_io_disable(void); +extern void elcr_write(uint16_t port, uint8_t val, void *priv); +extern uint8_t elcr_read(uint16_t port, void *priv); #endif /*EMU_PCI_H*/ diff --git a/src/include/86box/pit.h b/src/include/86box/pit.h index 4684c9632..366be2ad6 100644 --- a/src/include/86box/pit.h +++ b/src/include/86box/pit.h @@ -59,6 +59,8 @@ extern uint64_t PITCONST, ISACONST, VGACONST2, RTCCONST, ACPICONST; +extern int refresh_at_enable; + /* Gets a counter's count. */ extern uint16_t pit_ctr_get_count(ctr_t *ctr); diff --git a/src/io.c b/src/io.c index f78dc268e..b9dfcf370 100644 --- a/src/io.c +++ b/src/io.c @@ -283,18 +283,19 @@ uint8_t inb(uint16_t port) { uint8_t ret = 0xff; - io_t *p; + io_t *p, *q; int found = 0; int qfound = 0; p = io[port]; while(p) { + q = p->next; if (p->inb) { ret &= p->inb(port, p->priv); found |= 1; qfound++; } - p = p->next; + p = q; } if (port & 0x80) @@ -316,18 +317,19 @@ inb(uint16_t port) void outb(uint16_t port, uint8_t val) { - io_t *p; + io_t *p, *q; int found = 0; int qfound = 0; p = io[port]; while(p) { + q = p->next; if (p->outb) { p->outb(port, val, p->priv); found |= 1; qfound++; } - p = p->next; + p = q; } if (!found) { @@ -347,7 +349,7 @@ outb(uint16_t port, uint8_t val) uint16_t inw(uint16_t port) { - io_t *p; + io_t *p, *q; uint16_t ret = 0xffff; int found = 0; int qfound = 0; @@ -356,12 +358,13 @@ inw(uint16_t port) p = io[port]; while(p) { + q = p->next; if (p->inw) { ret &= p->inw(port, p->priv); found |= 2; qfound++; } - p = p->next; + p = q; } ret8[0] = ret & 0xff; @@ -369,12 +372,13 @@ inw(uint16_t port) for (i = 0; i < 2; i++) { p = io[(port + i) & 0xffff]; while(p) { + q = p->next; if (p->inb && !p->inw) { ret8[i] &= p->inb(port + i, p->priv); found |= 1; qfound++; } - p = p->next; + p = q; } } ret = (ret8[1] << 8) | ret8[0]; @@ -398,30 +402,32 @@ inw(uint16_t port) void outw(uint16_t port, uint16_t val) { - io_t *p; + io_t *p, *q; int found = 0; int qfound = 0; int i = 0; p = io[port]; while(p) { + q = p->next; if (p->outw) { p->outw(port, val, p->priv); found |= 2; qfound++; } - p = p->next; + p = q; } for (i = 0; i < 2; i++) { p = io[(port + i) & 0xffff]; while(p) { + q = p->next; if (p->outb && !p->outw) { p->outb(port + i, val >> (i << 3), p->priv); found |= 1; qfound++; } - p = p->next; + p = q; } } @@ -442,7 +448,7 @@ outw(uint16_t port, uint16_t val) uint32_t inl(uint16_t port) { - io_t *p; + io_t *p, *q; uint32_t ret = 0xffffffff; uint16_t ret16[2]; uint8_t ret8[4]; @@ -452,12 +458,13 @@ inl(uint16_t port) p = io[port]; while(p) { + q = p->next; if (p->inl) { ret &= p->inl(port, p->priv); found |= 4; qfound++; } - p = p->next; + p = q; } ret16[0] = ret & 0xffff; @@ -465,12 +472,13 @@ inl(uint16_t port) for (i = 0; i < 4; i += 2) { p = io[(port + i) & 0xffff]; while(p) { + q = p->next; if (p->inw && !p->inl) { ret16[i >> 1] &= p->inw(port + i, p->priv); found |= 2; qfound++; } - p = p->next; + p = q; } } ret = (ret16[1] << 16) | ret16[0]; @@ -482,12 +490,13 @@ inl(uint16_t port) for (i = 0; i < 4; i++) { p = io[(port + i) & 0xffff]; while(p) { + q = p->next; if (p->inb && !p->inw && !p->inl) { ret8[i] &= p->inb(port + i, p->priv); found |= 1; qfound++; } - p = p->next; + p = q; } } ret = (ret8[3] << 24) | (ret8[2] << 16) | (ret8[1] << 8) | ret8[0]; @@ -511,7 +520,7 @@ inl(uint16_t port) void outl(uint16_t port, uint32_t val) { - io_t *p; + io_t *p, *q; int found = 0; int qfound = 0; int i = 0; @@ -519,36 +528,39 @@ outl(uint16_t port, uint32_t val) p = io[port]; if (p) { while(p) { + q = p->next; if (p->outl) { p->outl(port, val, p->priv); found |= 4; qfound++; } - p = p->next; + p = q; } } for (i = 0; i < 4; i += 2) { p = io[(port + i) & 0xffff]; while(p) { + q = p->next; if (p->outw && !p->outl) { p->outw(port + i, val >> (i << 3), p->priv); found |= 2; qfound++; } - p = p->next; + p = q; } } for (i = 0; i < 4; i++) { p = io[(port + i) & 0xffff]; while(p) { + q = p->next; if (p->outb && !p->outw && !p->outl) { p->outb(port + i, val >> (i << 3), p->priv); found |= 1; qfound++; } - p = p->next; + p = q; } } diff --git a/src/machine/m_at.c b/src/machine/m_at.c index 7adc98ecd..9ee653a32 100644 --- a/src/machine/m_at.c +++ b/src/machine/m_at.c @@ -64,6 +64,7 @@ machine_at_common_init_ex(const machine_t *model, int type) { machine_common_init(model); + refresh_at_enable = 1; pit_ctr_set_out_func(&pit->counters[1], pit_refresh_timer_at); pic2_init(); dma16_init(); diff --git a/src/machine/m_ps1.c b/src/machine/m_ps1.c index 651ef1d25..f308d969a 100644 --- a/src/machine/m_ps1.c +++ b/src/machine/m_ps1.c @@ -506,6 +506,7 @@ ps1_common_init(const machine_t *model) mem_remap_top(384); + refresh_at_enable = 1; pit_ctr_set_out_func(&pit->counters[1], pit_refresh_timer_at); dma16_init(); diff --git a/src/machine/m_ps2_isa.c b/src/machine/m_ps2_isa.c index 9300d05d4..226a3eda4 100644 --- a/src/machine/m_ps2_isa.c +++ b/src/machine/m_ps2_isa.c @@ -178,6 +178,7 @@ machine_ps2_m30_286_init(const machine_t *model) device_add(&fdc_at_ps1_device); + refresh_at_enable = 1; pit_ctr_set_out_func(&pit->counters[1], pit_refresh_timer_at); dma16_init(); device_add(&keyboard_ps2_ps2_device); diff --git a/src/pci.c b/src/pci.c index ace9e14e5..336cd8d2f 100644 --- a/src/pci.c +++ b/src/pci.c @@ -189,7 +189,7 @@ pci_read(uint16_t port, void *priv) } -static void +void elcr_write(uint16_t port, uint8_t val, void *priv) { pci_log("ELCR%i: WRITE %02X\n", port & 1, val); @@ -214,7 +214,7 @@ elcr_write(uint16_t port, uint8_t val, void *priv) } -static uint8_t +uint8_t elcr_read(uint16_t port, void *priv) { pci_log("ELCR%i: READ %02X\n", port & 1, elcr[port & 1]); @@ -641,6 +641,14 @@ pci_elcr_set_enabled(int enabled) } +void +pci_elcr_io_disable(void) +{ + io_removehandler(0x04d0, 0x0002, + elcr_read,NULL,NULL, elcr_write,NULL,NULL, NULL); +} + + static void pci_reset_regs(void) { diff --git a/src/pit.c b/src/pit.c index fec976d79..9e140650d 100644 --- a/src/pit.c +++ b/src/pit.c @@ -53,7 +53,8 @@ uint64_t PITCONST, ISACONST, VGACONST1, VGACONST2, RTCCONST, ACPICONST; -int io_delay = 5; +int refresh_at_enable = 1, + io_delay = 5; int64_t firsttime = 1; @@ -743,7 +744,7 @@ pit_refresh_timer_xt(int new_out, int old_out) void pit_refresh_timer_at(int new_out, int old_out) { - if (new_out && !old_out) + if (refresh_at_enable && new_out && !old_out) ppi.pb ^= 0x10; } diff --git a/src/sio/sio_pc87307.c b/src/sio/sio_pc87307.c index 0921c4677..0a1578c76 100644 --- a/src/sio/sio_pc87307.c +++ b/src/sio/sio_pc87307.c @@ -413,11 +413,11 @@ pc87307_read(uint16_t port, void *priv) ret = dev->cur_reg; else { if (dev->cur_reg >= 0x30) - ret = dev->regs[dev->cur_reg]; + ret = dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30]; else if (dev->cur_reg == 0x24) ret = dev->pcregs[dev->regs[0x23]]; else - ret = dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30]; + ret = dev->regs[dev->cur_reg]; } return ret; diff --git a/src/sio/sio_pc87309.c b/src/sio/sio_pc87309.c index f60d02374..0b55b9655 100644 --- a/src/sio/sio_pc87309.c +++ b/src/sio/sio_pc87309.c @@ -337,9 +337,9 @@ pc87309_read(uint16_t port, void *priv) if (index) ret = dev->cur_reg & 0x1f; else { - if (dev->cur_reg == 8) - ret = 0x70; - else if (dev->cur_reg < 28) + if (dev->cur_reg >= 0x30) + ret = dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30]; + else ret = dev->regs[dev->cur_reg]; }