From 7577dbab78dd7e6e3e8f10777b227248b250151c Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 18 Dec 2020 17:09:54 +0100 Subject: [PATCH] Finished the SiS 50x work and added the two ASUS'es. --- src/chipset/sis_85c50x.c | 426 ++++++++++++++++++++--------------- src/cpu/386_common.c | 6 - src/disk/hdc_ide_cmd640.c | 9 +- src/include/86box/machine.h | 2 + src/include/86box/sio.h | 1 + src/machine/m_at_socket4_5.c | 75 +++++- src/machine/machine_table.c | 8 +- src/sio/sio_fdc37c66x.c | 35 ++- 8 files changed, 361 insertions(+), 201 deletions(-) diff --git a/src/chipset/sis_85c50x.c b/src/chipset/sis_85c50x.c index 781177b35..1cfb432f7 100644 --- a/src/chipset/sis_85c50x.c +++ b/src/chipset/sis_85c50x.c @@ -35,304 +35,368 @@ #include <86box/chipset.h> + #ifdef ENABLE_SIS_85C50X_LOG int sis_85c50x_do_log = ENABLE_SIS_85C50X_LOG; static void sis_85c50x_log(const char *fmt, ...) { - va_list ap; + va_list ap; - if (sis_85c50x_do_log) - { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } + if (sis_85c50x_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } } #else #define sis_85c50x_log(fmt, ...) #endif + typedef struct sis_85c50x_t { - uint8_t pci_conf[256], pci_conf_sb[256], regs[256], index; + uint8_t index, + pci_conf[256], pci_conf_sb[256], + regs[256]; - apm_t *apm; - smram_t *smram; + smram_t * smram; + port_92_t * port_92; } sis_85c50x_t; + static void sis_85c50x_shadow_recalc(sis_85c50x_t *dev) { - uint32_t base, i, can_read, can_write; + uint32_t base, i, can_read, can_write; - can_read = (dev->pci_conf[0x53] & 0x40) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; - can_write = (dev->pci_conf[0x53] & 0x20) ? MEM_WRITE_EXTANY : MEM_WRITE_INTERNAL; + can_read = (dev->pci_conf[0x53] & 0x40) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + can_write = (dev->pci_conf[0x53] & 0x20) ? MEM_WRITE_EXTANY : MEM_WRITE_INTERNAL; + if (!can_read) + can_write = MEM_WRITE_EXTANY; - mem_set_mem_state_both(0xf0000, 0x10000, can_read | can_write); + mem_set_mem_state_both(0xf0000, 0x10000, can_read | can_write); + shadowbios = 1; + shadowbios_write = 1; - for (i = 0; i < 4; i++) - { - base = 0xd0000 - ((i + 1) << 14); - mem_set_mem_state_both(base, 0x4000, (dev->pci_conf[0x56] & (1 << (i + 4))) ? (can_read | can_write) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY)); - mem_set_mem_state_both(base + 0x10000, 0x4000, (dev->pci_conf[0x55] & (1 << (i + 4))) ? (can_read | can_write) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY)); - mem_set_mem_state_both(base + 0x20000, 0x4000, (dev->pci_conf[0x54] & (1 << (i + 4))) ? (can_read | can_write) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY)); - } - flushmmucache(); + for (i = 0; i < 4; i++) { + base = 0xe0000 + (i << 14); + mem_set_mem_state_both(base, 0x4000, (dev->pci_conf[0x54] & (1 << (7 - i))) ? (can_read | can_write) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY)); + base = 0xd0000 + (i << 14); + mem_set_mem_state_both(base, 0x4000, (dev->pci_conf[0x55] & (1 << (7 - i))) ? (can_read | can_write) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY)); + base = 0xc0000 + (i << 14); + mem_set_mem_state_both(base, 0x4000, (dev->pci_conf[0x56] & (1 << (7 - i))) ? (can_read | can_write) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY)); + } + + flushmmucache(); } + static void sis_85c50x_smm_recalc(sis_85c50x_t *dev) { - //Note: Host Address determination is unclear - switch ((dev->pci_conf[0x65] & 0xe0) >> 5) - { + /* NOTE: Naming mismatch - what the datasheet calls "host address" is what we call ram_base. */ + uint32_t ram_base = (dev->pci_conf[0x64] << 20) | + ((dev->pci_conf[0x65] & 0x07) << 28); + + smram_disable(dev->smram); + + if ((((dev->pci_conf[0x65] & 0xe0) >> 5) != 0x00) && (ram_base == 0x00000000)) + return; + + switch ((dev->pci_conf[0x65] & 0xe0) >> 5) { case 0x00: - if (dev->pci_conf[0x54] == 0x00) - smram_enable(dev->smram, 0xa0000, 0xe0000, 0x10000, (dev->pci_conf[0x65] & 0x10), 1); + if (!(dev->pci_conf[0x54] & 0xc0)) + smram_enable(dev->smram, 0xe0000, 0xe0000, 0x8000, (dev->pci_conf[0x65] & 0x10), 1); break; case 0x01: - smram_enable(dev->smram, 0xa0000, 0xb0000, 0x10000, (dev->pci_conf[0x65] & 0x10), 1); + smram_enable(dev->smram, 0xb0000, ram_base, 0x10000, (dev->pci_conf[0x65] & 0x10), 1); break; case 0x02: - smram_enable(dev->smram, 0xa0000, 0xa0000, 0x10000, (dev->pci_conf[0x65] & 0x10), 1); + smram_enable(dev->smram, 0xa0000, ram_base, 0x10000, (dev->pci_conf[0x65] & 0x10), 1); break; case 0x04: - smram_enable(dev->smram, 0xa0000, 0xa0000, 0x8000, (dev->pci_conf[0x65] & 0x10), 1); + smram_enable(dev->smram, 0xa0000, ram_base, 0x8000, (dev->pci_conf[0x65] & 0x10), 1); break; case 0x06: - smram_enable(dev->smram, 0xa0000, 0xb0000, 0x8000, (dev->pci_conf[0x65] & 0x10), 1); + smram_enable(dev->smram, 0xb0000, ram_base, 0x8000, (dev->pci_conf[0x65] & 0x10), 1); break; - } + } } + static void sis_85c50x_write(int func, int addr, uint8_t val, void *priv) { + sis_85c50x_t *dev = (sis_85c50x_t *)priv; + uint8_t valxor = (val ^ dev->pci_conf[addr]); - sis_85c50x_t *dev = (sis_85c50x_t *)priv; - - dev->pci_conf[addr] = val; - switch (addr) - { - case 0x04: /* Command */ - dev->pci_conf[addr] = (val & 0xcf); + switch (addr) { + case 0x04: /* Command - low byte */ + dev->pci_conf[addr] = (dev->pci_conf[addr] & 0xb4) | (val & 0x4b); break; - - case 0x07: /* Status */ - dev->pci_conf[addr] = (val & 0xfe); + case 0x07: /* Status - high byte */ + dev->pci_conf[addr] = ((dev->pci_conf[addr] & 0xf9) & ~(val & 0xf8)) | (val & 0x06); + break; + case 0x50: + dev->pci_conf[addr] = val; break; - case 0x51: /* Cache */ + dev->pci_conf[addr] = val; cpu_cache_ext_enabled = (val & 0x40); + cpu_update_waitstates(); + break; + case 0x52: + dev->pci_conf[addr] = val; break; - case 0x53: /* Shadow RAM */ case 0x54: case 0x55: case 0x56: + dev->pci_conf[addr] = val; sis_85c50x_shadow_recalc(dev); + if (addr == 0x54) + sis_85c50x_smm_recalc(dev); + break; + case 0x57: case 0x58: case 0x59: case 0x5a: + case 0x5c: case 0x5d: case 0x5e: case 0x61: + case 0x62: case 0x63: case 0x67: case 0x68: + case 0x6a: case 0x6b: case 0x6c: case 0x6d: + case 0x6e: case 0x6f: + dev->pci_conf[addr] = val; break; - case 0x5f: - dev->pci_conf[addr] = (val & 0xfe); + dev->pci_conf[addr] = val & 0xfe; break; - - case 0x60: /* SMI */ - apm_set_do_smi(dev->apm, ((val & 0x02) && (dev->pci_conf[0x68] & 0x01))); - if (val & 0x02) - dev->pci_conf[0x69] &= 0x01; + case 0x5b: + dev->pci_conf[addr] = val; + if (valxor & 0xc0) + port_92_set_features(dev->port_92, !!(val & 0x40), !!(val & 0x80)); break; - case 0x64: /* SMM/SMRAM */ + case 0x60: /* SMI */ + if ((dev->pci_conf[0x68] & 0x01) && !(dev->pci_conf[addr] & 0x02) && (val & 0x02)) { + dev->pci_conf[0x69] |= 0x01; + smi_line = 1; + } + dev->pci_conf[addr] = val & 0x3e; + break; + case 0x64: /* SMRAM */ case 0x65: + dev->pci_conf[addr] = val; sis_85c50x_smm_recalc(dev); break; - case 0x66: dev->pci_conf[addr] = (val & 0x7f); break; - } - sis_85c50x_log("85C501: dev->pci_conf[%02x] = %02x\n", addr, val); + case 0x69: + dev->pci_conf[addr] &= ~(val); + break; + } + + sis_85c50x_log("85C501: dev->pci_conf[%02x] = %02x\n", addr, val); } + static uint8_t sis_85c50x_read(int func, int addr, void *priv) { - sis_85c50x_t *dev = (sis_85c50x_t *)priv; - sis_85c50x_log("85C501: dev->pci_conf[%02x] (%02x)\n", addr, dev->pci_conf[addr]); - return dev->pci_conf[addr]; + sis_85c50x_t *dev = (sis_85c50x_t *)priv; + + sis_85c50x_log("85C501: dev->pci_conf[%02x] (%02x)\n", addr, dev->pci_conf[addr]); + + return dev->pci_conf[addr]; } + static void sis_85c50x_sb_write(int func, int addr, uint8_t val, void *priv) { + sis_85c50x_t *dev = (sis_85c50x_t *)priv; - sis_85c50x_t *dev = (sis_85c50x_t *)priv; + switch (addr) { + case 0x04: /* Command */ + dev->pci_conf_sb[addr] = val & 0x0f; + break; + case 0x07: /* Status */ + dev->pci_conf_sb[addr] &= ~(val & 0x30); + break; + case 0x40: /* BIOS Control Register */ + dev->pci_conf_sb[addr] = val & 0x3f; + break; + case 0x41: case 0x42: case 0x43: case 0x44: + /* INTA/B/C/D# Remapping Control Register */ + dev->pci_conf_sb[addr] = val & 0x8f; + if (val & 0x80) + pci_set_irq_routing(PCI_INTA + (addr - 0x41), PCI_IRQ_DISABLED); + else + pci_set_irq_routing(PCI_INTA + (addr - 0x41), val & 0xf); + break; + case 0x48: /* ISA Master/DMA Memory Cycle Control Register 1 */ + case 0x49: /* ISA Master/DMA Memory Cycle Control Register 2 */ + case 0x4a: /* ISA Master/DMA Memory Cycle Control Register 3 */ + case 0x4b: /* ISA Master/DMA Memory Cycle Control Register 4 */ + dev->pci_conf_sb[addr] = val; + break; + } - dev->pci_conf_sb[addr] = val; - - switch (addr) - { - case 0x07: /* Status */ - dev->pci_conf_sb[addr] = (val & 0x36); - break; - - case 0x40: - dev->pci_conf_sb[addr] = (val & 0x3f); - break; - - case 0x41: /* PCI INTA IRQ */ - sis_85c50x_log("85C503: Remapping Slot %02x to IRQ %02x\n", PCI_INTA, (val & 0x0f)); - dev->pci_conf_sb[addr] = (val & 0x8f); - pci_set_irq_routing(PCI_INTA, !(val & 0x80) ? (val & 0x0f) : PCI_IRQ_DISABLED); - break; - case 0x42: /* PCI INTB IRQ */ - sis_85c50x_log("85C503: Remapping Slot %02x to IRQ %02x\n", PCI_INTB, (val & 0x0f)); - dev->pci_conf_sb[addr] = (val & 0x8f); - pci_set_irq_routing(PCI_INTB, !(val & 0x80) ? (val & 0x0f) : PCI_IRQ_DISABLED); - break; - case 0x43: /* PCI INTC IRQ */ - sis_85c50x_log("85C503: Remapping Slot %02x to IRQ %02x\n", PCI_INTC, (val & 0x0f)); - dev->pci_conf_sb[addr] = (val & 0x8f); - pci_set_irq_routing(PCI_INTC, !(val & 0x80) ? (val & 0x0f) : PCI_IRQ_DISABLED); - break; - case 0x44: /* PCI INTD IRQ */ - sis_85c50x_log("85C503: Remapping Slot %02x to IRQ %02x\n", PCI_INTD, (val & 0x0f)); - dev->pci_conf_sb[addr] = (val & 0x8f); - pci_set_irq_routing(PCI_INTD, !(val & 0x80) ? (val & 0x0f) : PCI_IRQ_DISABLED); - break; - } - sis_85c50x_log("85C503: dev->pci_conf_sb[%02x] = %02x\n", addr, val); + sis_85c50x_log("85C503: dev->pci_conf_sb[%02x] = %02x\n", addr, val); } + static uint8_t sis_85c50x_sb_read(int func, int addr, void *priv) { - sis_85c50x_t *dev = (sis_85c50x_t *)priv; - sis_85c50x_log("85C503: dev->pci_conf_sb[%02x] (%02x)\n", addr, dev->pci_conf_sb[addr]); - return dev->pci_conf_sb[addr]; + sis_85c50x_t *dev = (sis_85c50x_t *)priv; + sis_85c50x_log("85C503: dev->pci_conf_sb[%02x] (%02x)\n", addr, dev->pci_conf_sb[addr]); + + return dev->pci_conf_sb[addr]; } + static void sis_85c50x_isa_write(uint16_t addr, uint8_t val, void *priv) { - sis_85c50x_t *dev = (sis_85c50x_t *)priv; + sis_85c50x_t *dev = (sis_85c50x_t *)priv; - switch (addr) - { + switch (addr) { case 0x22: dev->index = val; break; case 0x23: - dev->regs[dev->index] = val; - switch (dev->index) - { - case 0x81: - dev->regs[dev->index] = (val & 0xf4); - cpu_update_waitstates(); - break; + switch (dev->index) { + case 0x80: + dev->regs[dev->index] = val & 0xe7; + break; + case 0x81: + dev->regs[dev->index] = val & 0xf4; + break; + case 0x84: case 0x88: case 0x9: case 0x8a: + case 0x8b: + dev->regs[dev->index] = val; + break; + case 0x85: + outb(0x70, val); + break; } - } - sis_85c50x_log("85C501-ISA: dev->regs[%02x] = %02x\n", addr, val); + break; + } + + sis_85c50x_log("85C501-ISA: dev->regs[%02x] = %02x\n", addr, val); } + static uint8_t sis_85c50x_isa_read(uint16_t addr, void *priv) { - sis_85c50x_t *dev = (sis_85c50x_t *)priv; - return dev->regs[dev->index]; - sis_85c50x_log("85C501-ISA: dev->regs[%02x] (%02x)\n", dev->index, dev->regs[dev->index]); + sis_85c50x_t *dev = (sis_85c50x_t *)priv; + uint8_t ret = 0xff; + + switch (addr) { + case 0x22: + ret = dev->index; + break; + + case 0x23: + if (dev->index == 0x85) + ret = inb(0x70); + else + ret = dev->regs[dev->index]; + break; + } + + sis_85c50x_log("85C501-ISA: dev->regs[%02x] (%02x)\n", dev->index, ret); + + return ret; } + static void sis_85c50x_reset(void *priv) { - sis_85c50x_t *dev = (sis_85c50x_t *)priv; + sis_85c50x_t *dev = (sis_85c50x_t *)priv; - /* North Bridge (SiS 85C501/502) */ - dev->pci_conf[0x00] = 0x39; - dev->pci_conf[0x01] = 0x10; - dev->pci_conf[0x02] = 0x06; - dev->pci_conf[0x03] = 0x04; - dev->pci_conf[0x04] = 0x04; - dev->pci_conf[0x05] = 0x00; - dev->pci_conf[0x06] = 0x00; - dev->pci_conf[0x07] = 0x00; - dev->pci_conf[0x08] = 0x00; - dev->pci_conf[0x09] = 0x00; - dev->pci_conf[0x0a] = 0x00; - dev->pci_conf[0x0b] = 0x06; - dev->pci_conf[0x0c] = 0x00; - dev->pci_conf[0x0d] = 0x00; - dev->pci_conf[0x0e] = 0x00; - dev->pci_conf[0x0f] = 0x00; + /* North Bridge (SiS 85C501/502) */ + dev->pci_conf[0x00] = 0x39; + dev->pci_conf[0x01] = 0x10; + dev->pci_conf[0x02] = 0x06; + dev->pci_conf[0x03] = 0x04; + dev->pci_conf[0x04] = 0x04; + dev->pci_conf[0x07] = 0x04; + dev->pci_conf[0x09] = 0x00; + dev->pci_conf[0x0a] = 0x00; + dev->pci_conf[0x0b] = 0x06; - sis_85c50x_write(0, 0x51, 0x00, dev); - sis_85c50x_write(0, 0x53, 0x00, dev); - sis_85c50x_write(0, 0x54, 0x00, dev); - sis_85c50x_write(0, 0x55, 0x00, dev); - sis_85c50x_write(0, 0x56, 0x00, dev); - sis_85c50x_write(0, 0x60, 0x00, dev); - sis_85c50x_write(0, 0x64, 0x00, dev); - sis_85c50x_write(0, 0x65, 0x00, dev); + sis_85c50x_write(0, 0x51, 0x00, dev); + sis_85c50x_write(0, 0x53, 0x00, dev); + sis_85c50x_write(0, 0x54, 0x00, dev); + sis_85c50x_write(0, 0x55, 0x00, dev); + sis_85c50x_write(0, 0x56, 0x00, dev); + sis_85c50x_write(0, 0x5b, 0x00, dev); + sis_85c50x_write(0, 0x60, 0x00, dev); + sis_85c50x_write(0, 0x64, 0x00, dev); + sis_85c50x_write(0, 0x65, 0x00, dev); + sis_85c50x_write(0, 0x68, 0x00, dev); + sis_85c50x_write(0, 0x69, 0xff, dev); - /* South Bridge (SiS 85C503) */ - dev->pci_conf_sb[0x00] = 0x39; - dev->pci_conf_sb[0x01] = 0x10; - dev->pci_conf_sb[0x02] = 0x08; - dev->pci_conf_sb[0x03] = 0x00; - dev->pci_conf_sb[0x04] = 0x07; - dev->pci_conf_sb[0x05] = 0x00; - dev->pci_conf_sb[0x06] = 0x00; - dev->pci_conf_sb[0x07] = 0x00; - dev->pci_conf_sb[0x08] = 0x00; - dev->pci_conf_sb[0x09] = 0x00; - dev->pci_conf_sb[0x0a] = 0x01; - dev->pci_conf_sb[0x0b] = 0x06; - dev->pci_conf_sb[0x0c] = 0x00; - dev->pci_conf_sb[0x0d] = 0x00; - dev->pci_conf_sb[0x0e] = 0x00; - dev->pci_conf_sb[0x0f] = 0x00; - sis_85c50x_write(0, 0x41, 0x80, dev); - sis_85c50x_write(0, 0x42, 0x80, dev); - sis_85c50x_write(0, 0x43, 0x80, dev); - sis_85c50x_write(0, 0x44, 0x80, dev); + /* South Bridge (SiS 85C503) */ + dev->pci_conf_sb[0x00] = 0x39; + dev->pci_conf_sb[0x01] = 0x10; + dev->pci_conf_sb[0x02] = 0x08; + dev->pci_conf_sb[0x03] = 0x00; + dev->pci_conf_sb[0x04] = 0x07; + dev->pci_conf_sb[0x05] = 0x00; + dev->pci_conf_sb[0x06] = 0x00; + dev->pci_conf_sb[0x07] = 0x02; + dev->pci_conf_sb[0x08] = 0x00; + dev->pci_conf_sb[0x09] = 0x00; + dev->pci_conf_sb[0x0a] = 0x01; + dev->pci_conf_sb[0x0b] = 0x06; + sis_85c50x_write(0, 0x41, 0x80, dev); + sis_85c50x_write(0, 0x42, 0x80, dev); + sis_85c50x_write(0, 0x43, 0x80, dev); + sis_85c50x_write(0, 0x44, 0x80, dev); } + static void sis_85c50x_close(void *priv) { - sis_85c50x_t *dev = (sis_85c50x_t *)priv; + sis_85c50x_t *dev = (sis_85c50x_t *)priv; - smram_del(dev->smram); - free(dev); + smram_del(dev->smram); + free(dev); } + static void * sis_85c50x_init(const device_t *info) { - sis_85c50x_t *dev = (sis_85c50x_t *)malloc(sizeof(sis_85c50x_t)); - memset(dev, 0, sizeof(sis_85c50x_t)); + sis_85c50x_t *dev = (sis_85c50x_t *)malloc(sizeof(sis_85c50x_t)); + memset(dev, 0x00, sizeof(sis_85c50x_t)); - pci_add_card(PCI_ADD_NORTHBRIDGE, sis_85c50x_read, sis_85c50x_write, dev); - pci_add_card(PCI_ADD_SOUTHBRIDGE, sis_85c50x_sb_read, sis_85c50x_sb_write, dev); - io_sethandler(0x0022, 0x0002, sis_85c50x_isa_read, NULL, NULL, sis_85c50x_isa_write, NULL, NULL, dev); - dev->apm = device_add(&apm_pci_device); - dev->smram = smram_add(); - device_add(&port_92_device); - sis_85c50x_reset(dev); - return dev; + /* 501/502 (Northbridge) */ + pci_add_card(PCI_ADD_NORTHBRIDGE, sis_85c50x_read, sis_85c50x_write, dev); + + /* 503 (Southbridge) */ + pci_add_card(PCI_ADD_SOUTHBRIDGE, sis_85c50x_sb_read, sis_85c50x_sb_write, dev); + io_sethandler(0x0022, 0x0002, sis_85c50x_isa_read, NULL, NULL, sis_85c50x_isa_write, NULL, NULL, dev); + + dev->smram = smram_add(); + dev->port_92 = device_add(&port_92_device); + + sis_85c50x_reset(dev); + + return dev; } + const device_t sis_85c50x_device = { - "SiS 85C50x", - DEVICE_PCI, - 0, - sis_85c50x_init, - sis_85c50x_close, - sis_85c50x_reset, - {NULL}, - NULL, - NULL, - NULL}; + "SiS 85C50x", + DEVICE_PCI, + 0, + sis_85c50x_init, sis_85c50x_close, + sis_85c50x_reset, { NULL }, + NULL, NULL, + NULL +}; diff --git a/src/cpu/386_common.c b/src/cpu/386_common.c index 062926e0a..a62ac4f04 100644 --- a/src/cpu/386_common.c +++ b/src/cpu/386_common.c @@ -1023,12 +1023,6 @@ enter_smm(int in_hlt) if (!is_am486 && !is_pentium && !is_k5 && !is_k6 && !is_p6 && !is_cx6x86) return; - if (cpu_iscyrix) { - if (!cyrix.smhr & SMHR_VALID) - cyrix.smhr = (cyrix.arr[3].base + cyrix.arr[3].size) | SMHR_VALID; - smram_state = cyrix.smhr & SMHR_ADDR_MASK; - } - x386_common_log("enter_smm(): smbase = %08X\n", smbase); x386_common_log("CS : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", cpu_state.seg_cs.seg, cpu_state.seg_cs.base, cpu_state.seg_cs.limit, cpu_state.seg_cs.limit_low, diff --git a/src/disk/hdc_ide_cmd640.c b/src/disk/hdc_ide_cmd640.c index 53500f52a..a958eebdf 100644 --- a/src/disk/hdc_ide_cmd640.c +++ b/src/disk/hdc_ide_cmd640.c @@ -378,6 +378,7 @@ cmd640_init(const device_t *info) dev->regs[0x01] = 0x10; dev->regs[0x02] = 0x40; /* PCI-0640B */ dev->regs[0x03] = 0x06; + dev->regs[0x04] = 0x01; /* Apparently required by the ASUS PCI/I-P5SP4 AND PCI/I-P54SP4 */ dev->regs[0x07] = 0x02; /* DEVSEL timing: 01 medium */ dev->regs[0x08] = 0x02; /* Revision 02 */ dev->regs[0x09] = info->local; /* Programming interface */ @@ -395,7 +396,7 @@ cmd640_init(const device_t *info) dev->regs[0x3c] = 0x14; /* IRQ 14 */ dev->regs[0x3d] = 0x01; /* INTA */ - device_add(&ide_vlb_2ch_device); + device_add(&ide_pci_2ch_device); dev->slot = pci_add_card(PCI_ADD_IDE, cmd640_pci_read, cmd640_pci_write, dev); dev->irq_mode[0] = dev->irq_mode[1] = 0; @@ -410,7 +411,7 @@ cmd640_init(const device_t *info) ide_board_set_force_ata3(0, 1); ide_board_set_force_ata3(1, 1); - ide_pri_disable(); + // ide_pri_disable(); } else if (info->flags & DEVICE_VLB) { if ((info->local & 0xffff) == 0x0078) dev->regs[0x50] |= 0x20; /* 0 = 178h, 17Ch; 1 = 078h, 07Ch */ @@ -418,9 +419,9 @@ cmd640_init(const device_t *info) accessing the configuration registers */ dev->in_cfg = 1; /* Configuration register are accessible */ - device_add(&ide_pci_2ch_device); + device_add(&ide_vlb_2ch_device); - io_sethandler(0x0078, 0x0008, + io_sethandler(info->local & 0xffff, 0x0008, cmd640_vlb_read, cmd640_vlb_readw, cmd640_vlb_readl, cmd640_vlb_write, cmd640_vlb_writew, cmd640_vlb_writel, dev); diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index b72542d2c..72ebab693 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -377,6 +377,8 @@ extern int machine_at_powermate_v_init(const machine_t *); extern int machine_at_acerv30_init(const machine_t *); #if defined(DEV_BRANCH) && defined(USE_SIS_85C50X) +extern int machine_at_p5sp4_init(const machine_t *); +extern int machine_at_p54sp4_init(const machine_t *); extern int machine_at_sq588_init(const machine_t *); #endif diff --git a/src/include/86box/sio.h b/src/include/86box/sio.h index df4d84a73..3c4702ffa 100644 --- a/src/include/86box/sio.h +++ b/src/include/86box/sio.h @@ -23,6 +23,7 @@ extern const device_t f82c710_device; extern const device_t fdc37c661_device; extern const device_t fdc37c663_device; extern const device_t fdc37c665_device; +extern const device_t fdc37c665_ide_device; extern const device_t fdc37c666_device; extern const device_t fdc37c669_device; extern const device_t fdc37c669_370_device; diff --git a/src/machine/m_at_socket4_5.c b/src/machine/m_at_socket4_5.c index fd1117a03..2cbdaa0d1 100644 --- a/src/machine/m_at_socket4_5.c +++ b/src/machine/m_at_socket4_5.c @@ -647,7 +647,66 @@ machine_at_acerv30_init(const machine_t *model) return ret; } + #if defined(DEV_BRANCH) && defined(USE_SIS_85C50X) +static void +machine_at_sp4_common_init(const machine_t *model) +{ + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + /* Excluded: 02, 03, 04, 05, 06, 07, 08, 09, 0A, 0B, 0C, 0D, 0E, 0F, 10, 11, 12, 13, 14 */ + pci_register_slot(0x0D, PCI_CARD_IDE, 1, 2, 3, 4); + /* Excluded: 02, 03*, 04*, 05*, 06*, 07*, 08* */ + /* Slots: 09 (04), 0A (03), 0B (02), 0C (07) */ + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3); + device_add(&sis_85c50x_device); + device_add(&ide_cmd640_pci_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&fdc37c665_device); + device_add(&intel_flash_bxt_device); +} + + +int +machine_at_p5sp4_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/p5sp4/0106.001", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_sp4_common_init(model); + + return ret; +} + + +int +machine_at_p54sp4_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/p54sp4/SI5I0204.AWD", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_sp4_common_init(model); + + return ret; +} + + int machine_at_sq588_init(const machine_t *model) { @@ -664,16 +723,18 @@ machine_at_sq588_init(const machine_t *model) pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x03, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x04, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x05, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x06, PCI_CARD_NORMAL, 4, 1, 2, 3); + /* Correct: 0D (01), 0F (02), 11 (03), 13 (04) */ + pci_register_slot(0x02, PCI_CARD_IDE, 1, 2, 3, 4); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x11, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x13, PCI_CARD_NORMAL, 4, 1, 2, 3); device_add(&sis_85c50x_device); + device_add(&ide_cmd640_pci_single_channel_device); device_add(&keyboard_ps2_ami_pci_device); - device_add(&ide_cmd640_pci_legacy_only_device); - device_add(&fdc37c665_device); + device_add(&fdc37c665_ide_device); device_add(&sst_flash_29ee010_device); return ret; } -#endif \ No newline at end of file +#endif diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 80d6caf7d..e4c6960c5 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -243,6 +243,11 @@ const machine_t machines[] = { /* OPTi 596/597 */ { "[OPTi 597] AMI Excalibur VLB", "excalibur", MACHINE_TYPE_SOCKET4, CPU_PKG_SOCKET4, 0, 60000000, 66666667, 0, 0, MACHINE_MULTIPLIER_FIXED, MACHINE_VLB | MACHINE_IDE, 2048, 65536, 2048, 127, machine_at_excalibur_init, NULL }, + /* SiS 85C50x */ + #if defined(DEV_BRANCH) && defined(USE_SIS_85C50X) + { "[SiS 85C50x] ASUS PCI/I-P5SP4", "p5sp4", MACHINE_TYPE_SOCKET4, CPU_PKG_SOCKET4, 0, 60000000, 66666667, 0, 0, MACHINE_MULTIPLIER_FIXED, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 131072, 8192, 127, machine_at_p5sp4_init, NULL }, + #endif + /* Socket 5 machines */ /* 430NX */ { "[i430NX] Intel Premiere/PCI II", "plato", MACHINE_TYPE_SOCKET5, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3520, 3520, 1.5, 1.5, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 2048, 131072, 2048, 127, machine_at_plato_init, NULL }, @@ -259,7 +264,8 @@ const machine_t machines[] = { /* SiS 85C50x */ #if defined(DEV_BRANCH) && defined(USE_SIS_85C50X) - { "[SiS 85C50x] BCM SQ-588", "sq588", MACHINE_TYPE_SOCKET5, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3380, 3520, 1.5, 2.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 131072, 8192, 127, machine_at_sq588_init, NULL }, + { "[SiS 85C50x] ASUS PCI/I-P54SP4", "p54sp4", MACHINE_TYPE_SOCKET5, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3380, 3520, 1.5, 2.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 131072, 8192, 127, machine_at_p54sp4_init, NULL }, + { "[SiS 85C50x] BCM SQ-588", "sq588", MACHINE_TYPE_SOCKET5, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3380, 3520, 1.5, 2.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 131072, 8192, 127, machine_at_sq588_init, NULL }, #endif /* Socket 7 machines */ diff --git a/src/sio/sio_fdc37c66x.c b/src/sio/sio_fdc37c66x.c index 13351bdbd..970925e14 100644 --- a/src/sio/sio_fdc37c66x.c +++ b/src/sio/sio_fdc37c66x.c @@ -38,7 +38,7 @@ typedef struct { uint8_t chip_id, tries, - regs[16]; + has_ide, regs[16]; int cur_reg, com3_addr, com4_addr; fdc_t *fdc; @@ -131,6 +131,18 @@ fdc_handler(fdc37c66x_t *dev) } + +static void +ide_handler(fdc37c66x_t *dev) +{ + ide_sec_disable(); + ide_set_base(1, (dev->regs[0x05] & 0x02) ? 0x170 : 0x1f0); + ide_set_side(1, (dev->regs[0x05] & 0x02) ? 0x376 : 0x3f6); + if (dev->regs[0x00] & 0x01) + ide_sec_enable(); +} + + static void fdc37c66x_write(uint16_t port, uint8_t val, void *priv) { @@ -152,6 +164,8 @@ fdc37c66x_write(uint16_t port, uint8_t val, void *priv) switch(dev->cur_reg) { case 0: + if (dev->has_ide && (valxor & 0x01)) + ide_handler(dev); if (valxor & 0x10) fdc_handler(dev); break; @@ -183,6 +197,8 @@ fdc37c66x_write(uint16_t port, uint8_t val, void *priv) case 5: if (valxor & 0x01) fdc_handler(dev); + if (dev->has_ide && (valxor & 0x02)) + ide_handler(dev); if (valxor & 0x18) fdc_update_densel_force(dev->fdc, (dev->regs[5] & 0x18) >> 3); if (valxor & 0x20) @@ -237,6 +253,9 @@ fdc37c66x_reset(fdc37c66x_t *dev) dev->regs[0x6] = 0xff; dev->regs[0xd] = dev->chip_id; dev->regs[0xe] = 0x01; + + if (dev->has_ide) + ide_handler(dev); } @@ -260,7 +279,10 @@ fdc37c66x_init(const device_t *info) dev->uart[0] = device_add_inst(&ns16550_device, 1); dev->uart[1] = device_add_inst(&ns16550_device, 2); - dev->chip_id = info->local; + dev->chip_id = info->local & 0xff; + dev->has_ide = !!(info->local & 0x100); + + if (dev->has_ide) io_sethandler(0x03f0, 0x0002, fdc37c66x_read, NULL, NULL, fdc37c66x_write, NULL, NULL, dev); @@ -291,6 +313,15 @@ const device_t fdc37c665_device = { NULL }; +const device_t fdc37c665_ide_device = { + "SMC FDC37C665 Super I/O", + 0, + 0x165, + fdc37c66x_init, fdc37c66x_close, NULL, + { NULL }, NULL, NULL, + NULL +}; + const device_t fdc37c666_device = { "SMC FDC37C666 Super I/O", 0,