From da398832c4bbd3058bb78a104dccdbd5038f4af4 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 14 Sep 2025 23:30:40 +0200 Subject: [PATCH] CUBX: Implement CMD-648 disabling via ACPI GPIO, fixes #6169. --- src/acpi.c | 6 +++++- src/disk/hdc.c | 4 ++++ src/disk/hdc_ide_cmd646.c | 24 ++++++++++++++---------- src/include/86box/hdc.h | 1 + 4 files changed, 24 insertions(+), 11 deletions(-) diff --git a/src/acpi.c b/src/acpi.c index 6ecca841b..411662e39 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -41,6 +41,7 @@ #include <86box/i2c.h> #include <86box/video.h> #include <86box/smbus.h> +#include <86box/hdc.h> #include <86box/hdc_ide.h> #include <86box/hdc_ide_sff8038i.h> #include <86box/sis_55xx.h> @@ -1219,8 +1220,11 @@ acpi_reg_write_intel(int size, uint16_t addr, uint8_t val, void *priv) case 0x36: case 0x37: /* GPOREG - General Purpose Output Register (IO) */ - if (size == 1) + if (size == 1) { dev->regs.gporeg[addr & 3] = val; + if ((addr == 0x34) && !strcmp(machine_get_internal_name(), "cubx")) + hdc_onboard_enabled = (val & 0x01); + } break; default: acpi_reg_write_common_regs(size, addr, val, priv); diff --git a/src/disk/hdc.c b/src/disk/hdc.c index 135528401..1e0d3f2bb 100644 --- a/src/disk/hdc.c +++ b/src/disk/hdc.c @@ -32,6 +32,8 @@ int hdc_current[HDC_MAX] = { 0, 0 }; +int hdc_onboard_enabled = 1; + #ifdef ENABLE_HDC_LOG int hdc_do_log = ENABLE_HDC_LOG; @@ -114,6 +116,8 @@ hdc_init(void) void hdc_reset(void) { + hdc_onboard_enabled = 1; + for (int i = 0; i < HDC_MAX; i++) { hdc_log("HDC %i: reset(current=%d, internal=%d)\n", i, hdc_current[i], hdc_current[i] == HDC_INTERNAL); diff --git a/src/disk/hdc_ide_cmd646.c b/src/disk/hdc_ide_cmd646.c index 7aa920e22..333cd5e30 100644 --- a/src/disk/hdc_ide_cmd646.c +++ b/src/disk/hdc_ide_cmd646.c @@ -145,6 +145,7 @@ cmd646_ide_handlers(cmd646_t *dev) int first = 0; int reg09 = dev->regs[0x09]; int reg50 = dev->regs[0x50]; + int dev_enabled = (hdc_onboard_enabled || !(dev->local & CMD64X_ONBOARD)); if ((dev->local & CMD_TYPE_648) && (dev->local & CMD648_RAID)) { reg09 = 0xff; @@ -180,7 +181,7 @@ cmd646_ide_handlers(cmd646_t *dev) if (dev->local & CMD_TYPE_648) pri_enabled = pri_enabled && (dev->regs[0x51] & 0x04); - if (pri_enabled) + if (dev_enabled && pri_enabled) ide_handlers(first, 1); if (dev->single_channel) @@ -205,7 +206,7 @@ cmd646_ide_handlers(cmd646_t *dev) sff_set_irq_mode(dev->bm[1], irq_mode[1]); cmd646_log("IDE %i: %04X, %04X, %i\n", first + 1, main, side, irq_mode[1]); - if ((dev->regs[0x04] & 0x01) && (dev->regs[0x51] & 0x08)) + if (dev_enabled && (dev->regs[0x04] & 0x01) && (dev->regs[0x51] & 0x08)) ide_handlers(first + 1, 1); } @@ -213,9 +214,10 @@ static void cmd646_ide_bm_handlers(cmd646_t *dev) { uint16_t base = (dev->regs[0x20] & 0xf0) | (dev->regs[0x21] << 8); + int dev_enabled = (hdc_onboard_enabled || !(dev->local & CMD64X_ONBOARD)); - sff_bus_master_handler(dev->bm[0], (dev->regs[0x04] & 1), base); - sff_bus_master_handler(dev->bm[1], (dev->regs[0x04] & 1), base + 8); + sff_bus_master_handler(dev->bm[0], dev_enabled && (dev->regs[0x04] & 1), base); + sff_bus_master_handler(dev->bm[1], dev_enabled && (dev->regs[0x04] & 1), base + 8); } uint8_t @@ -296,15 +298,16 @@ cmd646_bios_handler(cmd646_t *dev) static void cmd646_pci_write(int func, int addr, uint8_t val, void *priv) { - cmd646_t *dev = (cmd646_t *) priv; - int reg50 = dev->regs[0x50]; + cmd646_t *dev = (cmd646_t *) priv; + int reg50 = dev->regs[0x50]; + int dev_enabled = (hdc_onboard_enabled || !(dev->local & CMD64X_ONBOARD)); if ((dev->local & CMD_TYPE_648) && (dev->regs[0x0a] == 0x04) && (dev->regs[0x0b] == 0x01)) reg50 |= 0x40; cmd646_log("[%04X:%08X] (%08X) cmd646_pci_write(%i, %02X, %02X)\n", CS, cpu_state.pc, ESI, func, addr, val); - if (func == 0x00) + if (dev_enabled && (func == 0x00)) switch (addr) { case 0x04: if (dev->has_bios) @@ -480,10 +483,11 @@ cmd646_pci_write(int func, int addr, uint8_t val, void *priv) static uint8_t cmd646_pci_read(int func, int addr, void *priv) { - cmd646_t *dev = (cmd646_t *) priv; - uint8_t ret = 0xff; + cmd646_t *dev = (cmd646_t *) priv; + uint8_t ret = 0xff; + int dev_enabled = (hdc_onboard_enabled || !(dev->local & CMD64X_ONBOARD)); - if (func == 0x00) { + if (dev_enabled && (func == 0x00)) { ret = dev->regs[addr]; if ((addr == 0x09) && (dev->local & CMD_TYPE_648) && (dev->regs[0x0a] == 0x04)) diff --git a/src/include/86box/hdc.h b/src/include/86box/hdc.h index 26fed9b0a..214ed84e5 100644 --- a/src/include/86box/hdc.h +++ b/src/include/86box/hdc.h @@ -30,6 +30,7 @@ #define HDC_MAX 4 extern int hdc_current[HDC_MAX]; +extern int hdc_onboard_enabled; extern const device_t st506_xt_xebec_device; /* st506_xt_xebec */ extern const device_t st506_xt_wdxt_gen_device; /* st506_xt_wdxt_gen */