From a994737257dc5b358b732bc21efb1442af9373a3 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Wed, 31 Mar 2021 20:38:51 -0300 Subject: [PATCH 1/2] ISAPnP: follow spec and don't reset read data port on reset command, fixes UM8669F AMI machines --- src/device/isapnp.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/device/isapnp.c b/src/device/isapnp.c index 73b1584b8..b4bb2860f 100644 --- a/src/device/isapnp.c +++ b/src/device/isapnp.c @@ -387,8 +387,7 @@ isapnp_write_data(uint16_t addr, uint8_t val, void *priv) case 0x02: /* Config Control */ if (val & 0x01) { isapnp_log("ISAPnP: Reset\n"); - isapnp_set_read_data(0, dev); - + card = dev->first_card; while (card) { ld = card->first_ld; From 906fc6a0da6e9ea4ee4403fce36118fed621fc51 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Wed, 31 Mar 2021 20:53:04 -0300 Subject: [PATCH 2/2] ISAPnP: add proper support for I/O range checks, decoupling the device's I/O handlers away when range checking is enabled --- src/device/isapnp.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/device/isapnp.c b/src/device/isapnp.c index b4bb2860f..20c55742b 100644 --- a/src/device/isapnp.c +++ b/src/device/isapnp.c @@ -85,7 +85,7 @@ enum { typedef struct _isapnp_device_ { uint8_t number; uint8_t regs[256]; - uint8_t mem_upperlimit, irq_types, io_16bit; + uint8_t mem_upperlimit, irq_types, io_16bit, io_len[8]; struct _isapnp_device_ *next; } isapnp_device_t; @@ -142,7 +142,10 @@ isapnp_device_config_changed(isapnp_card_t *card, isapnp_device_t *ld) } for (i = 0; i < 8; i++) { reg_base = 0x60 + (2 * i); - card->config.io[i].base = (ld->regs[reg_base] << 8) | ld->regs[reg_base + 1]; + if (ld->regs[0x31] & 0x02) + card->config.io[i].base = 0; /* let us handle I/O range check reads */ + else + card->config.io[i].base = (ld->regs[reg_base] << 8) | ld->regs[reg_base + 1]; } for (i = 0; i < 2; i++) { reg_base = 0x70 + (2 * i); @@ -490,15 +493,19 @@ isapnp_write_data(uint16_t addr, uint8_t val, void *priv) case 0x31: /* I/O Range Check */ CHECK_CURRENT_LD(); - for (uint8_t reg = 0x60; reg <= 0x6e; reg += 2) { - io_addr = (dev->current_ld->regs[reg] << 8) | dev->current_ld->regs[reg + 1]; + for (uint8_t i = 0; i < 8; i++) { + if (!dev->current_ld->io_len[i]) + continue; + + io_addr = (dev->current_ld->regs[0x60 + (2 * i)] << 8) | dev->current_ld->regs[0x61 + (2 * i)]; if (dev->current_ld->regs[dev->reg] & 0x02) - io_removehandler(io_addr, 1, isapnp_read_rangecheck, NULL, NULL, NULL, NULL, NULL, dev->current_ld); + io_removehandler(io_addr, dev->current_ld->io_len[i], isapnp_read_rangecheck, NULL, NULL, NULL, NULL, NULL, dev->current_ld); if (val & 0x02) - io_sethandler(io_addr, 1, isapnp_read_rangecheck, NULL, NULL, NULL, NULL, NULL, dev->current_ld); + io_sethandler(io_addr, dev->current_ld->io_len[i], isapnp_read_rangecheck, NULL, NULL, NULL, NULL, NULL, dev->current_ld); } dev->current_ld->regs[dev->reg] = val & 0x03; + isapnp_device_config_changed(dev->current_ld_card, dev->current_ld); break; @@ -788,13 +795,16 @@ isapnp_add_card(uint8_t *rom, uint16_t rom_size, if (io > 7) fatal("ISAPnP: I/O descriptor overflow (%d)\n", io); - isapnp_log("ISAPnP: >>%s I/O range %d %d-bit decode\n", in_df ? ">" : "", io, (card->rom[i + 1] & 0x01) ? 16 : 10); + isapnp_log("ISAPnP: >>%s I/O range %d %d-bit decode, %d ports\n", in_df ? ">" : "", io, (card->rom[i + 1] & 0x01) ? 16 : 10, card->rom[i + 7]); if (card->rom[i + 1] & 0x01) ld->io_16bit |= 1 << io; else ld->io_16bit &= ~(1 << io); + if (card->rom[i + 7] > ld->io_len[io]) + ld->io_len[io] = card->rom[i + 7]; + io++; break;