From 61663d9a01b96fd84cd8d1bd67fca540375fe01e Mon Sep 17 00:00:00 2001 From: Panagiotis <58827426+tiseno100@users.noreply.github.com> Date: Wed, 16 Dec 2020 15:08:18 +0200 Subject: [PATCH 1/7] Early SiS 50x rework Rewrote the chipset to adopt the new API --- src/chipset/sis_85c50x.c | 542 +++++++++++++-------------------------- 1 file changed, 185 insertions(+), 357 deletions(-) diff --git a/src/chipset/sis_85c50x.c b/src/chipset/sis_85c50x.c index 9e50ef3c9..46b293da1 100644 --- a/src/chipset/sis_85c50x.c +++ b/src/chipset/sis_85c50x.c @@ -6,436 +6,264 @@ * * This file is part of the 86Box distribution. * - * Implementation of the SiS 85c501/85c503 chip. + * Implementation of the SiS 85C50x Chipset. * * * - * Authors: Sarah Walker, - * Miran Grca, + * Authors: Tiseno100, * - * Copyright 2019 Miran Grca. + * Copyright 2020 Tiseno100. */ + #include #include #include #include #include #include <86box/86box.h> -#include <86box/mem.h> -#include <86box/io.h> -#include <86box/rom.h> -#include <86box/pci.h> #include <86box/device.h> -#include <86box/keyboard.h> -#include <86box/port_92.h> +#include <86box/io.h> +#include <86box/timer.h> + +#include <86box/apm.h> +#include <86box/mem.h> +#include <86box/smram.h> +#include <86box/pci.h> + #include <86box/chipset.h> - -typedef struct sis_85c501_t +#ifdef ENABLE_SIS_85C50X_LOG +int sis_85c50x_do_log = ENABLE_SIS_85C50X_LOG; +static void +sis_85c50x_log(const char *fmt, ...) { - /* 85c501 */ - uint8_t turbo_reg; + va_list ap; - /* 85c503 */ + if (sis_85c50x_do_log) + { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define sis_85c50x_log(fmt, ...) +#endif - /* Registers */ - uint8_t pci_conf[2][256]; +typedef struct sis_85c50x_t +{ + uint8_t pci_conf[256], pci_conf_sb[256]; - /* 85c50x ISA */ - uint8_t cur_reg, - regs[39]; + apm_t *apm; + smram_t *smram; } sis_85c50x_t; - static void -sis_85c501_recalcmapping(sis_85c50x_t *dev) +sis_85c50x_shadow_recalc(sis_85c50x_t *dev) { - int c, d; - uint32_t base; + uint32_t base, i, can_read, can_write; - for (c = 0; c < 1; c++) { - for (d = 0; d < 4; d++) { - base = 0xe0000 + (d << 14); - if (dev->pci_conf[0][0x54 + c] & (1 << (d + 4))) { - switch (dev->pci_conf[0][0x53] & 0x60) { - case 0x00: - mem_set_mem_state(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL); - break; - case 0x20: - mem_set_mem_state(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); - break; - case 0x40: - mem_set_mem_state(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - break; - case 0x60: - mem_set_mem_state(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_EXTANY); - break; - } - } else - mem_set_mem_state(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + 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; + + mem_set_mem_state_both(0xf0000, 0x10000, can_read | can_write); + + 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(); - shadowbios = 1; + flushmmucache(); } - static void -sis_85c501_write(int func, int addr, uint8_t val, void *priv) +sis_85c50x_smm_recalc(sis_85c50x_t *dev) { - sis_85c50x_t *dev = (sis_85c50x_t *) priv; - - if (func) - return; - - if ((addr >= 0x10) && (addr < 0x4f)) - return; - - switch (addr) { - case 0x00: case 0x01: case 0x02: case 0x03: - case 0x08: case 0x09: case 0x0a: case 0x0b: - case 0x0c: case 0x0e: - return; - - case 0x04: /*Command register*/ - val &= 0x42; - val |= 0x04; + //Note: Host Address determination is unclear + 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); break; - case 0x05: - val &= 0x01; + case 0x01: + smram_enable(dev->smram, 0xa0000, 0xb0000, 0x10000, (dev->pci_conf[0x65] & 0x10), 1); break; - - case 0x06: /*Status*/ - val = 0; + case 0x02: + smram_enable(dev->smram, 0xa0000, 0xa0000, 0x10000, (dev->pci_conf[0x65] & 0x10), 1); break; - case 0x07: - val = 0x02; + case 0x04: + smram_enable(dev->smram, 0xa0000, 0xa0000, 0x8000, (dev->pci_conf[0x65] & 0x10), 1); break; - - case 0x54: /*Shadow configure*/ - if ((dev->pci_conf[0][0x54] & val) ^ 0xf0) { - dev->pci_conf[0][0x54] = val; - sis_85c501_recalcmapping(dev); - } + case 0x06: + smram_enable(dev->smram, 0xa0000, 0xb0000, 0x8000, (dev->pci_conf[0x65] & 0x10), 1); break; - } - - dev->pci_conf[0][addr] = val; + } } +static void +sis_85c50x_write(int func, int addr, uint8_t val, void *priv) +{ + + sis_85c50x_t *dev = (sis_85c50x_t *)priv; + + dev->pci_conf[addr] = val; + switch (addr) + { + case 0x51: + cpu_cache_ext_enabled = (val & 0x40); + break; + + case 0x53: + case 0x54: + case 0x55: + case 0x56: + sis_85c50x_shadow_recalc(dev); + break; + + case 0x60: + apm_set_do_smi(dev->apm, (val & 0x02)); + break; + + case 0x64: + case 0x65: + sis_85c50x_smm_recalc(dev); + break; + } + sis_85c50x_log("85C501: dev->pci_conf[%02x] = %02x", 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)", addr, dev->pci_conf[addr]); + return dev->pci_conf[addr]; +} static void -sis_85c503_write(int func, int addr, uint8_t val, void *priv) +sis_85c50x_sb_write(int func, int addr, uint8_t val, void *priv) { - sis_85c50x_t *dev = (sis_85c50x_t *) priv; - if (func > 0) - return; + sis_85c50x_t *dev = (sis_85c50x_t *)priv; - if (addr >= 0x0f && addr < 0x41) - return; - - switch(addr) { - case 0x00: case 0x01: case 0x02: case 0x03: - case 0x08: case 0x09: case 0x0a: case 0x0b: - case 0x0e: - return; - - case 0x04: /*Command register*/ - val &= 0x08; - val |= 0x07; - break; - case 0x05: - val = 0; - break; - - case 0x06: /*Status*/ - val = 0; - break; - case 0x07: - val = 0x02; - break; + dev->pci_conf_sb[addr] = val; + switch (addr) + { case 0x41: - if (val & 0x80) - pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED); - else - pci_set_irq_routing(PCI_INTA, val & 0xf); + pci_set_irq_routing(PCI_INTA, (val & 0x80) ? (val & 0x0f) : PCI_IRQ_DISABLED); break; case 0x42: - if (val & 0x80) - pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED); - else - pci_set_irq_routing(PCI_INTC, val & 0xf); + pci_set_irq_routing(PCI_INTB, (val & 0x80) ? (val & 0x0f) : PCI_IRQ_DISABLED); break; case 0x43: - if (val & 0x80) - pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED); - else - pci_set_irq_routing(PCI_INTB, val & 0xf); + pci_set_irq_routing(PCI_INTC, (val & 0x80) ? (val & 0x0f) : PCI_IRQ_DISABLED); break; case 0x44: - if (val & 0x80) - pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); - else - pci_set_irq_routing(PCI_INTD, val & 0xf); + pci_set_irq_routing(PCI_INTD, (val & 0x80) ? (val & 0x0f) : PCI_IRQ_DISABLED); break; - } - - dev->pci_conf[1][addr] = val; + } + sis_85c50x_log("85C503: dev->pci_conf_sb[%02x] = %02x", addr, val); } - -static void -sis_85c50x_isa_write(uint16_t port, uint8_t val, void *priv) -{ - sis_85c50x_t *dev = (sis_85c50x_t *) priv; - - if (port & 1) { - if (dev->cur_reg <= 0x1a) - dev->regs[dev->cur_reg] = val; - } else - dev->cur_reg = val; -} - - static uint8_t -sis_85c501_read(int func, int addr, void *priv) +sis_85c50x_sb_read(int func, int addr, void *priv) { - sis_85c50x_t *dev = (sis_85c50x_t *) priv; - - if (func) - return 0xff; - - return dev->pci_conf[0][addr]; + sis_85c50x_t *dev = (sis_85c50x_t *)priv; + sis_85c50x_log("85C503: dev->pci_conf_sb[%02x] (%02x)", addr, dev->pci_conf_sb[addr]); + return dev->pci_conf_sb[addr]; } - -static uint8_t -sis_85c503_read(int func, int addr, void *priv) -{ - sis_85c50x_t *dev = (sis_85c50x_t *) priv; - - if (func > 0) - return 0xff; - - return dev->pci_conf[1][addr]; -} - - -static uint8_t -sis_85c50x_isa_read(uint16_t port, void *priv) -{ - sis_85c50x_t *dev = (sis_85c50x_t *) priv; - - if (port & 1) { - if (dev->cur_reg <= 0x1a) - return dev->regs[dev->cur_reg]; - else - return 0xff; - } else - return dev->cur_reg; -} - - -static void -sis_85c50x_isa_reset(sis_85c50x_t *dev) -{ - int mem_size_mb, i = 0; - - memset(dev->regs, 0, sizeof(dev->regs)); - - dev->cur_reg = 0; - for (i = 0; i < 0x27; i++) - dev->regs[i] = 0x00; - - dev->regs[9] = 0x40; - - mem_size_mb = mem_size >> 10; - switch (mem_size_mb) { - case 0: case 1: - dev->regs[9] |= 0; - break; - case 2: case 3: - dev->regs[9] |= 1; - break; - case 4: - dev->regs[9] |= 2; - break; - case 5: - dev->regs[9] |= 0x20; - break; - case 6: case 7: - dev->regs[9] |= 9; - break; - case 8: case 9: - dev->regs[9] |= 4; - break; - case 10: case 11: - dev->regs[9] |= 5; - break; - case 12: case 13: case 14: case 15: - dev->regs[9] |= 0xB; - break; - case 16: - dev->regs[9] |= 0x13; - break; - case 17: - dev->regs[9] |= 0x21; - break; - case 18: case 19: - dev->regs[9] |= 6; - break; - case 20: case 21: case 22: case 23: - dev->regs[9] |= 0xD; - break; - case 24: case 25: case 26: case 27: - case 28: case 29: case 30: case 31: - dev->regs[9] |= 0xE; - break; - case 32: case 33: case 34: case 35: - dev->regs[9] |= 0x1B; - break; - case 36: case 37: case 38: case 39: - dev->regs[9] |= 0xF; - break; - case 40: case 41: case 42: case 43: - case 44: case 45: case 46: case 47: - dev->regs[9] |= 0x17; - break; - case 48: - dev->regs[9] |= 0x1E; - break; - default: - if (mem_size_mb < 64) - dev->regs[9] |= 0x1E; - else if ((mem_size_mb >= 65) && (mem_size_mb < 68)) - dev->regs[9] |= 0x22; - else - dev->regs[9] |= 0x24; - break; - } - - dev->regs[0x11] = 9; - dev->regs[0x12] = 0xFF; - dev->regs[0x23] = 0xF0; - dev->regs[0x26] = 1; - - io_removehandler(0x22, 0x0002, - sis_85c50x_isa_read, NULL, NULL, sis_85c50x_isa_write, NULL, NULL, dev); - io_sethandler(0x22, 0x0002, - sis_85c50x_isa_read, NULL, NULL, sis_85c50x_isa_write, NULL, NULL, dev); -} - - static void sis_85c50x_reset(void *priv) { - sis_85c50x_t *dev = (sis_85c50x_t *) priv; + sis_85c50x_t *dev = (sis_85c50x_t *)priv; - uint8_t val = 0; + /* North Bridge */ + 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; - val = sis_85c501_read(0, 0x54, priv); /* Read current value of 0x44. */ - sis_85c501_write(0, 0x54, val & 0xf, priv); /* Turn off shadow BIOS but keep the lower 4 bits. */ + 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_isa_reset(dev); + /* South Bridge */ + 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, 0x00, dev); + sis_85c50x_write(0, 0x42, 0x00, dev); + sis_85c50x_write(0, 0x43, 0x00, dev); + sis_85c50x_write(0, 0x44, 0x00, dev); } - -static void -sis_85c50x_setup(sis_85c50x_t *dev) -{ - memset(dev, 0, sizeof(sis_85c50x_t)); - - /* 85c501 */ - dev->pci_conf[0][0x00] = 0x39; /*SiS*/ - dev->pci_conf[0][0x01] = 0x10; - dev->pci_conf[0][0x02] = 0x06; /*501/502*/ - dev->pci_conf[0][0x03] = 0x04; - - dev->pci_conf[0][0x04] = 7; - dev->pci_conf[0][0x05] = 0; - - dev->pci_conf[0][0x06] = 0x80; - dev->pci_conf[0][0x07] = 0x02; - - dev->pci_conf[0][0x08] = 0; /*Device revision*/ - - dev->pci_conf[0][0x09] = 0x00; /*Device class (PCI bridge)*/ - dev->pci_conf[0][0x0a] = 0x00; - dev->pci_conf[0][0x0b] = 0x06; - - dev->pci_conf[0][0x0e] = 0x00; /*Single function device*/ - - dev->pci_conf[0][0x50] = 0xbc; - dev->pci_conf[0][0x51] = 0xfb; - dev->pci_conf[0][0x52] = 0xad; - dev->pci_conf[0][0x53] = 0xfe; - - shadowbios = 1; - - /* 85c503 */ - dev->pci_conf[1][0x00] = 0x39; /*SiS*/ - dev->pci_conf[1][0x01] = 0x10; - dev->pci_conf[1][0x02] = 0x08; /*503*/ - dev->pci_conf[1][0x03] = 0x00; - - dev->pci_conf[1][0x04] = 7; - dev->pci_conf[1][0x05] = 0; - - dev->pci_conf[1][0x06] = 0x80; - dev->pci_conf[1][0x07] = 0x02; - - dev->pci_conf[1][0x08] = 0; /*Device revision*/ - - dev->pci_conf[1][0x09] = 0x00; /*Device class (PCI bridge)*/ - dev->pci_conf[1][0x0a] = 0x01; - dev->pci_conf[1][0x0b] = 0x06; - - dev->pci_conf[1][0x0e] = 0x00; /*Single function device*/ - - dev->pci_conf[1][0x41] = dev->pci_conf[1][0x42] = - dev->pci_conf[1][0x43] = dev->pci_conf[1][0x44] = 0x80; -} - - static void sis_85c50x_close(void *priv) { - sis_85c50x_t *dev = (sis_85c50x_t *) priv; + sis_85c50x_t *dev = (sis_85c50x_t *)priv; - 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)); + sis_85c50x_t *dev = (sis_85c50x_t *)malloc(sizeof(sis_85c50x_t)); + memset(dev, 0, sizeof(sis_85c50x_t)); - pci_add_card(0, sis_85c501_read, sis_85c501_write, dev); - pci_add_card(5, sis_85c503_read, sis_85c503_write, dev); + 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); + dev->apm = device_add(&apm_pci_device); + dev->smram = smram_add(); + sis_85c50x_reset(dev); - sis_85c50x_setup(dev); - sis_85c50x_isa_reset(dev); - - device_add(&port_92_pci_device); - - return dev; + return dev; } - -const device_t sis_85c50x_device = -{ - "SiS 85c501/85c503", - DEVICE_PCI, - 0, - sis_85c50x_init, - sis_85c50x_close, - sis_85c50x_reset, - { NULL }, - NULL, - NULL, - NULL -}; +const device_t sis_85c50x_device = { + "SiS 85C50x", + DEVICE_PCI, + 0, + sis_85c50x_init, + sis_85c50x_close, + sis_85c50x_reset, + {NULL}, + NULL, + NULL, + NULL}; From e05bd5d9375bab0408d5cb31e80d580134c1b4ec Mon Sep 17 00:00:00 2001 From: Panagiotis <58827426+tiseno100@users.noreply.github.com> Date: Wed, 16 Dec 2020 15:25:33 +0200 Subject: [PATCH 2/7] Added Port 92 & ISA bus on the SiS 50x --- src/chipset/sis_85c50x.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/chipset/sis_85c50x.c b/src/chipset/sis_85c50x.c index 46b293da1..00b7af4d6 100644 --- a/src/chipset/sis_85c50x.c +++ b/src/chipset/sis_85c50x.c @@ -29,6 +29,7 @@ #include <86box/mem.h> #include <86box/smram.h> #include <86box/pci.h> +#include <86box/port_92.h> #include <86box/chipset.h> @@ -52,7 +53,7 @@ sis_85c50x_log(const char *fmt, ...) typedef struct sis_85c50x_t { - uint8_t pci_conf[256], pci_conf_sb[256]; + uint8_t pci_conf[256], pci_conf_sb[256], regs[256]; apm_t *apm; smram_t *smram; @@ -177,6 +178,26 @@ sis_85c50x_sb_read(int func, int addr, void *priv) 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; +dev->regs[addr] = val; + +if(addr == 0x81) +cpu_update_waitstates(); + +sis_85c50x_log("85C501-ISA: dev->is[%02x] = %02x", 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[addr]; +sis_85c50x_log("85C501-ISA: dev->is[%02x] (%02x)", addr, dev->regs[addr]); +} + static void sis_85c50x_reset(void *priv) { @@ -249,8 +270,10 @@ sis_85c50x_init(const device_t *info) 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; From fbab9d8643d579faba2625e4f3227537ce521852 Mon Sep 17 00:00:00 2001 From: Panagiotis <58827426+tiseno100@users.noreply.github.com> Date: Wed, 16 Dec 2020 15:27:58 +0200 Subject: [PATCH 3/7] Identation fixes --- src/chipset/sis_85c50x.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/chipset/sis_85c50x.c b/src/chipset/sis_85c50x.c index 00b7af4d6..23204ac29 100644 --- a/src/chipset/sis_85c50x.c +++ b/src/chipset/sis_85c50x.c @@ -181,21 +181,21 @@ sis_85c50x_sb_read(int func, int addr, void *priv) static void sis_85c50x_isa_write(uint16_t addr, uint8_t val, void *priv) { -sis_85c50x_t *dev = (sis_85c50x_t *)priv; -dev->regs[addr] = val; + sis_85c50x_t *dev = (sis_85c50x_t *)priv; + dev->regs[addr] = val; -if(addr == 0x81) -cpu_update_waitstates(); + if (addr == 0x81) + cpu_update_waitstates(); -sis_85c50x_log("85C501-ISA: dev->is[%02x] = %02x", addr, val); + sis_85c50x_log("85C501-ISA: dev->regs[%02x] = %02x", 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[addr]; -sis_85c50x_log("85C501-ISA: dev->is[%02x] (%02x)", addr, dev->regs[addr]); + sis_85c50x_t *dev = (sis_85c50x_t *)priv; + return dev->regs[addr]; + sis_85c50x_log("85C501-ISA: dev->regs[%02x] (%02x)", addr, dev->regs[addr]); } static void From 4b0b03e0560de46810d3455fe1b6e4c7503ff30e Mon Sep 17 00:00:00 2001 From: Panagiotis <58827426+tiseno100@users.noreply.github.com> Date: Thu, 17 Dec 2020 09:19:51 +0200 Subject: [PATCH 4/7] Multiple fixes for the SiS 85C50x - Fixed the PCI IRQ setting - Added a missing register needed to trigger an APM SMI - Registers with reserved bits are now safe - The ISA controller is properly implemented --- src/chipset/sis_85c50x.c | 91 +++++++++++++++++++++++++++++----------- 1 file changed, 66 insertions(+), 25 deletions(-) diff --git a/src/chipset/sis_85c50x.c b/src/chipset/sis_85c50x.c index 23204ac29..be7c6a4cb 100644 --- a/src/chipset/sis_85c50x.c +++ b/src/chipset/sis_85c50x.c @@ -53,7 +53,7 @@ sis_85c50x_log(const char *fmt, ...) typedef struct sis_85c50x_t { - uint8_t pci_conf[256], pci_conf_sb[256], regs[256]; + uint8_t pci_conf[256], pci_conf_sb[256], regs[256], index; apm_t *apm; smram_t *smram; @@ -113,25 +113,42 @@ sis_85c50x_write(int func, int addr, uint8_t val, void *priv) dev->pci_conf[addr] = val; switch (addr) { - case 0x51: + case 0x04: /* Command */ + dev->pci_conf[addr] = (val & 0xcf); + break; + + case 0x07: /* Status */ + dev->pci_conf[addr] = (val & 0xfe); + break; + + case 0x51: /* Cache */ cpu_cache_ext_enabled = (val & 0x40); break; - case 0x53: + case 0x53: /* Shadow RAM */ case 0x54: case 0x55: case 0x56: sis_85c50x_shadow_recalc(dev); break; - case 0x60: - apm_set_do_smi(dev->apm, (val & 0x02)); + case 0x5f: + dev->pci_conf[addr] = (val & 0xfe); break; - case 0x64: + case 0x60: /* SMI */ + apm_set_do_smi(dev->apm, ((val & 0x02) && (dev->pci_conf[0x68] & 0x01))); + if (val & 0x02) + dev->pci_conf[0x69] &= 0x01; + break; + case 0x64: /* SMM/SMRAM */ case 0x65: sis_85c50x_smm_recalc(dev); break; + + case 0x66: + dev->pci_conf[addr] = (val & 0x7f); + break; } sis_85c50x_log("85C501: dev->pci_conf[%02x] = %02x", addr, val); } @@ -154,17 +171,29 @@ sis_85c50x_sb_write(int func, int addr, uint8_t val, void *priv) switch (addr) { - case 0x41: - pci_set_irq_routing(PCI_INTA, (val & 0x80) ? (val & 0x0f) : PCI_IRQ_DISABLED); + case 0x07: /* Status */ + dev->pci_conf_sb[addr] = (val & 0x36); break; - case 0x42: - pci_set_irq_routing(PCI_INTB, (val & 0x80) ? (val & 0x0f) : PCI_IRQ_DISABLED); + + case 0x40: + dev->pci_conf_sb[addr] = (val & 0x3f); break; - case 0x43: - pci_set_irq_routing(PCI_INTC, (val & 0x80) ? (val & 0x0f) : PCI_IRQ_DISABLED); + + case 0x41: /* PCI INTA IRQ */ + dev->pci_conf_sb[addr] = (val & 0x8f); + pci_set_irq_routing(PCI_INTA, !(val & 0x80) ? (val & 0x0f) : PCI_IRQ_DISABLED); break; - case 0x44: - pci_set_irq_routing(PCI_INTD, (val & 0x80) ? (val & 0x0f) : PCI_IRQ_DISABLED); + case 0x42: /* PCI INTB IRQ */ + 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 */ + 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 */ + 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", addr, val); @@ -182,11 +211,23 @@ static void sis_85c50x_isa_write(uint16_t addr, uint8_t val, void *priv) { sis_85c50x_t *dev = (sis_85c50x_t *)priv; - dev->regs[addr] = val; - if (addr == 0x81) - cpu_update_waitstates(); + 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; + } + } sis_85c50x_log("85C501-ISA: dev->regs[%02x] = %02x", addr, val); } @@ -194,8 +235,8 @@ static uint8_t sis_85c50x_isa_read(uint16_t addr, void *priv) { sis_85c50x_t *dev = (sis_85c50x_t *)priv; - return dev->regs[addr]; - sis_85c50x_log("85C501-ISA: dev->regs[%02x] (%02x)", addr, dev->regs[addr]); + return dev->regs[dev->index]; + sis_85c50x_log("85C501-ISA: dev->regs[%02x] (%02x)", dev->index, dev->regs[dev->index]); } static void @@ -203,7 +244,7 @@ sis_85c50x_reset(void *priv) { sis_85c50x_t *dev = (sis_85c50x_t *)priv; - /* North Bridge */ + /* North Bridge (SiS 85C501/502) */ dev->pci_conf[0x00] = 0x39; dev->pci_conf[0x01] = 0x10; dev->pci_conf[0x02] = 0x06; @@ -230,7 +271,7 @@ sis_85c50x_reset(void *priv) sis_85c50x_write(0, 0x64, 0x00, dev); sis_85c50x_write(0, 0x65, 0x00, dev); - /* South Bridge */ + /* South Bridge (SiS 85C503) */ dev->pci_conf_sb[0x00] = 0x39; dev->pci_conf_sb[0x01] = 0x10; dev->pci_conf_sb[0x02] = 0x08; @@ -247,10 +288,10 @@ sis_85c50x_reset(void *priv) dev->pci_conf_sb[0x0d] = 0x00; dev->pci_conf_sb[0x0e] = 0x00; dev->pci_conf_sb[0x0f] = 0x00; - sis_85c50x_write(0, 0x41, 0x00, dev); - sis_85c50x_write(0, 0x42, 0x00, dev); - sis_85c50x_write(0, 0x43, 0x00, dev); - sis_85c50x_write(0, 0x44, 0x00, dev); + 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 From 78efeca0da77b601202aae36eb5e1a7fbe6fc50f Mon Sep 17 00:00:00 2001 From: Panagiotis <58827426+tiseno100@users.noreply.github.com> Date: Thu, 17 Dec 2020 09:24:16 +0200 Subject: [PATCH 5/7] The SiS 50x can now be compiled --- src/win/Makefile.mingw | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 655790221..4a9d2b4e5 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -75,6 +75,9 @@ ifeq ($(DEV_BUILD), y) ifndef SIO_DETECT SIO_DETECT := y endif + ifndef USE_SIS_85C50X + USE_SIS_85C50X := y + endif ifndef STPC STPC := y endif @@ -148,6 +151,9 @@ else ifndef SIO_DETECT SIO_DETECT := n endif + ifndef USE_SIS_85C50X + USE_SIS_85C50X := n + endif ifndef STPC STPC := y endif @@ -543,6 +549,11 @@ OPTS += -DUSE_SIO_DETECT DEVBROBJ += sio_detect.o endif +ifeq ($(USE_SIS_85C50X), y) +OPTS += -DUSE_SIS_85C50X +DEVBROBJ += sis_85c50x.o +endif + ifeq ($(STPC), y) OPTS += -DUSE_STPC DEVBROBJ += stpc.o From d1e205cff430cd7d4dfe7669ce2aaa0bfc2f0c93 Mon Sep 17 00:00:00 2001 From: Panagiotis <58827426+tiseno100@users.noreply.github.com> Date: Thu, 17 Dec 2020 13:38:10 +0200 Subject: [PATCH 6/7] Fixed logging & Added the BCM SQ-588 --- src/chipset/sis_85c50x.c | 19 ++++++++++++------- src/include/86box/machine.h | 4 ++++ src/machine/m_at_socket4_5.c | 31 +++++++++++++++++++++++++++++++ src/machine/machine_table.c | 5 +++++ 4 files changed, 52 insertions(+), 7 deletions(-) diff --git a/src/chipset/sis_85c50x.c b/src/chipset/sis_85c50x.c index be7c6a4cb..781177b35 100644 --- a/src/chipset/sis_85c50x.c +++ b/src/chipset/sis_85c50x.c @@ -15,11 +15,13 @@ * Copyright 2020 Tiseno100. */ +#include #include #include #include #include #include +#define HAVE_STDARG_H #include <86box/86box.h> #include <86box/device.h> #include <86box/io.h> @@ -150,14 +152,14 @@ sis_85c50x_write(int func, int addr, uint8_t val, void *priv) dev->pci_conf[addr] = (val & 0x7f); break; } - sis_85c50x_log("85C501: dev->pci_conf[%02x] = %02x", addr, val); + 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)", addr, dev->pci_conf[addr]); + sis_85c50x_log("85C501: dev->pci_conf[%02x] (%02x)\n", addr, dev->pci_conf[addr]); return dev->pci_conf[addr]; } @@ -180,30 +182,34 @@ sis_85c50x_sb_write(int func, int addr, uint8_t val, void *priv) 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", 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)", addr, dev->pci_conf_sb[addr]); + sis_85c50x_log("85C503: dev->pci_conf_sb[%02x] (%02x)\n", addr, dev->pci_conf_sb[addr]); return dev->pci_conf_sb[addr]; } @@ -228,7 +234,7 @@ sis_85c50x_isa_write(uint16_t addr, uint8_t val, void *priv) break; } } - sis_85c50x_log("85C501-ISA: dev->regs[%02x] = %02x", addr, val); + sis_85c50x_log("85C501-ISA: dev->regs[%02x] = %02x\n", addr, val); } static uint8_t @@ -236,7 +242,7 @@ 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)", dev->index, dev->regs[dev->index]); + sis_85c50x_log("85C501-ISA: dev->regs[%02x] (%02x)\n", dev->index, dev->regs[dev->index]); } static void @@ -316,7 +322,6 @@ sis_85c50x_init(const device_t *info) dev->smram = smram_add(); device_add(&port_92_device); sis_85c50x_reset(dev); - return dev; } diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index d920ef494..b72542d2c 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -376,6 +376,10 @@ extern int machine_at_vectra54_init(const machine_t *); 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_sq588_init(const machine_t *); +#endif + #ifdef EMU_DEVICE_H extern const device_t *at_endeavor_get_device(void); #define at_vectra54_get_device at_endeavor_get_device diff --git a/src/machine/m_at_socket4_5.c b/src/machine/m_at_socket4_5.c index de61ed113..fd1117a03 100644 --- a/src/machine/m_at_socket4_5.c +++ b/src/machine/m_at_socket4_5.c @@ -646,3 +646,34 @@ machine_at_acerv30_init(const machine_t *model) return ret; } + +#if defined(DEV_BRANCH) && defined(USE_SIS_85C50X) +int +machine_at_sq588_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/sq588/sq588b03.rom", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + 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); + 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); + device_add(&sis_85c50x_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&ide_cmd640_pci_legacy_only_device); + device_add(&fdc37c665_device); + device_add(&sst_flash_29ee010_device); + + return ret; +} +#endif \ No newline at end of file diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index c852b0057..80d6caf7d 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -257,6 +257,11 @@ const machine_t machines[] = { { "[i430FX] NEC PowerMate V", "powermate_v", 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_powermate_v_init, NULL }, { "[i430FX] PC Partner MB500N", "mb500n", MACHINE_TYPE_SOCKET5, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3380, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_IDE_DUAL, 8192, 131072, 8192, 127, machine_at_mb500n_init, NULL }, + /* 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 }, + #endif + /* Socket 7 machines */ /* 430FX */ { "[i430FX] ASUS P/I-P54TP4XE", "p54tp4xe", MACHINE_TYPE_SOCKET7_3V, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3380, 3600, 1.5, 2.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 131072, 8192, 127, machine_at_p54tp4xe_init, NULL }, From 7577dbab78dd7e6e3e8f10777b227248b250151c Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 18 Dec 2020 17:09:54 +0100 Subject: [PATCH 7/7] 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,