From 04ae339ba1190e00d84c1a5b31a1ab875075be17 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 7 Jul 2025 03:07:22 +0200 Subject: [PATCH] Parallel ports: Fix EPP-related ports handling, appears to fix a reported sound regression. --- src/device/lpt.c | 33 +++++++++++++---------------- src/include/86box/lpt.h | 1 + src/sio/sio_ali5123.c | 46 ++++++++++++++++++++++++++++++++++------- src/sio/sio_pc87306.c | 14 +++++++------ 4 files changed, 62 insertions(+), 32 deletions(-) diff --git a/src/device/lpt.c b/src/device/lpt.c index 11afc04f9..4c5578490 100644 --- a/src/device/lpt.c +++ b/src/device/lpt.c @@ -626,34 +626,29 @@ lpt_set_ext(const int port, const uint8_t ext) void lpt_set_ecp(const int port, const uint8_t ecp) { - if (lpt_ports[port].enabled) { - const uint16_t addr = lpt_ports[port].addr; - lpt_port_setup(port, 0xfff); + if (lpt_ports[port].enabled) lpt_ports[port].ecp = ecp; - lpt_port_setup(port, addr); - } } void lpt_set_epp(const int port, const uint8_t epp) { - if (lpt_ports[port].enabled) { - const uint16_t addr = lpt_ports[port].addr; - lpt_port_setup(port, 0xfff); + if (lpt_ports[port].enabled) lpt_ports[port].epp = epp; - lpt_port_setup(port, addr); - } } void lpt_set_lv2(const int port, const uint8_t lv2) { - if (lpt_ports[port].enabled) { - const uint16_t addr = lpt_ports[port].addr; - lpt_port_setup(port, 0xfff); + if (lpt_ports[port].enabled) lpt_ports[port].lv2 = lv2; - lpt_port_setup(port, addr); - } +} + +void +lpt_set_fifo_threshold(const int port, const int threshold) +{ + if (lpt_ports[port].enabled) + fifo_set_trigger_len(lpt_ports[port].fifo, threshold); } void @@ -778,19 +773,19 @@ void lpt_port_setup(const int i, const uint16_t port) { if (lpt_ports[i].enabled) { - if (lpt_ports[i].addr != 0xffff) { + if ((lpt_ports[i].addr != 0x0000) && (lpt_ports[i].addr != 0xffff)) { io_removehandler(lpt_ports[i].addr, 0x0007, lpt_read, NULL, NULL, lpt_write, NULL, NULL, &lpt_ports[i]); io_removehandler(lpt_ports[i].addr + 0x0400, 0x0007, lpt_read, NULL, NULL, lpt_write, NULL, NULL, &lpt_ports[i]); } - if (port != 0xffff) { + if ((port != 0x0000) && (port != 0xffff)) { lpt_log("Set handler: %04X-%04X\n", port, port + 0x0003); io_sethandler(port, 0x0003, lpt_read, NULL, NULL, lpt_write, NULL, NULL, &lpt_ports[i]); if (lpt_ports[i].epp) - io_sethandler(lpt_ports[i].addr + 0x0003, 0x0003, lpt_read, NULL, NULL, lpt_write, NULL, NULL, &lpt_ports[i]); + io_sethandler(port + 0x0003, 0x0005, lpt_read, NULL, NULL, lpt_write, NULL, NULL, &lpt_ports[i]); if (lpt_ports[i].ecp || lpt_ports[i].lv2) { io_sethandler(port + 0x0400, 0x0003, lpt_read, NULL, NULL, lpt_write, NULL, NULL, &lpt_ports[i]); if (lpt_ports[i].epp) - io_sethandler(lpt_ports[i].addr + 0x0403, 0x0003, lpt_read, NULL, NULL, lpt_write, NULL, NULL, &lpt_ports[i]); + io_sethandler(port + 0x0404, 0x0003, lpt_read, NULL, NULL, lpt_write, NULL, NULL, &lpt_ports[i]); } } lpt_ports[i].addr = port; diff --git a/src/include/86box/lpt.h b/src/include/86box/lpt.h index c13d70291..b3e4d070b 100644 --- a/src/include/86box/lpt.h +++ b/src/include/86box/lpt.h @@ -37,6 +37,7 @@ extern void lpt_set_ext(int port, uint8_t ext); extern void lpt_set_ecp(int port, uint8_t ecp); extern void lpt_set_epp(int port, uint8_t epp); extern void lpt_set_lv2(int port, uint8_t lv2); +extern void lpt_set_fifo_threshold(int port, int threshold); extern void lpt_reset(void); extern void lpt_close(void); extern void lpt_init(void); diff --git a/src/sio/sio_ali5123.c b/src/sio/sio_ali5123.c index e0f676d7c..7dc522b30 100644 --- a/src/sio/sio_ali5123.c +++ b/src/sio/sio_ali5123.c @@ -81,25 +81,57 @@ ali5123_fdc_handler(ali5123_t *dev) static void ali5123_lpt_handler(ali5123_t *dev) { - uint16_t ld_port = 0; + uint16_t ld_port = 0x0000; + uint16_t mask = 0xfffc; uint8_t global_enable = !(dev->regs[0x22] & (1 << 3)); uint8_t local_enable = !!dev->ld_regs[3][0x30]; uint8_t lpt_irq = dev->ld_regs[3][0x70]; uint8_t lpt_dma = dev->ld_regs[3][0x74]; + uint8_t lpt_mode = dev->ld_regs[3][0xf0] & 0x07; if (lpt_irq > 15) lpt_irq = 0xff; - if (lpt_dma == 4) + if (lpt_dma >= 4) lpt_dma = 0xff; lpt1_remove(); - lpt_set_epp(0, !!(dev->ld_regs[3][0xf0] & 0x01)); - lpt_set_ecp(0, !!(dev->ld_regs[3][0xf0] & 0x02)); - lpt_set_ext(0, !(dev->ld_regs[3][0xf0] & 0x04) || !!(dev->ld_regs[3][0xf1] & 0x80)); + lpt_set_fifo_threshold(0, (dev->ld_regs[3][0xf0] & 0x78) >> 3); + if ((lpt_mode == 0x04) && (dev->ld_regs[3][0xf1] & 0x80)) + lpt_mode = 0x00; + switch (lpt_mode) { + default: + case 0x04: + lpt_set_epp(0, 0); + lpt_set_ecp(0, 0); + lpt_set_ext(0, 0); + break; + case 0x00: + lpt_set_epp(0, 0); + lpt_set_ecp(0, 0); + lpt_set_ext(0, 1); + break; + case 0x01: case 0x05: + mask = 0xfff8; + lpt_set_epp(0, 1); + lpt_set_ecp(0, 0); + lpt_set_ext(0, 0); + break; + case 0x02: + lpt_set_epp(0, 0); + lpt_set_ecp(0, 1); + lpt_set_ext(0, 0); + break; + case 0x03: case 0x07: + mask = 0xfff8; + lpt_set_epp(0, 1); + lpt_set_ecp(0, 1); + lpt_set_ext(0, 0); + break; + } if (global_enable && local_enable) { - ld_port = make_port(dev, 3) & 0xFFFC; - if ((ld_port >= 0x0100) && (ld_port <= 0x0FFC)) + ld_port = (make_port(dev, 3) & 0xfffc) & mask; + if ((ld_port >= 0x0100) && (ld_port <= (0x0ffc & mask))) lpt1_setup(ld_port); } lpt1_irq(lpt_irq); diff --git a/src/sio/sio_pc87306.c b/src/sio/sio_pc87306.c index e42c48ab4..5a0a8798a 100644 --- a/src/sio/sio_pc87306.c +++ b/src/sio/sio_pc87306.c @@ -123,6 +123,8 @@ lpt1_handler(pc87306_t *dev) uint8_t lpt_irq = LPT2_IRQ; uint8_t lpt_dma = ((dev->regs[0x18] & 0x06) >> 1); + lpt1_remove(); + if (lpt_dma == 0x00) lpt_dma = 0xff; @@ -157,17 +159,17 @@ lpt1_handler(pc87306_t *dev) if (dev->regs[0x1b] & 0x10) lpt_irq = (dev->regs[0x1b] & 0x20) ? 7 : 5; + lpt_set_ext(0, !!(dev->regs[0x02] & 0x80)); + + lpt_set_epp(0, !!(dev->regs[0x04] & 0x01)); + lpt_set_ecp(0, !!(dev->regs[0x04] & 0x04)); + if (lpt_port) lpt1_setup(lpt_port); lpt1_irq(lpt_irq); lpt_port_dma(0, lpt_dma); - - lpt_set_ext(0, !!(dev->regs[0x02] & 0x80)); - - lpt_set_epp(0, !!(dev->regs[0x04] & 0x01)); - lpt_set_ecp(0, !!(dev->regs[0x04] & 0x04)); } static void @@ -386,7 +388,7 @@ pc87306_write(uint16_t port, uint8_t val, void *priv) if (valxor & 0x70) { lpt1_remove(); if (!(val & 0x40)) - dev->regs[0x19] = 0xEF; + dev->regs[0x19] = 0xef; if ((dev->regs[0x00] & 1) && !(dev->regs[0x02] & 1)) lpt1_handler(dev); }