From 0e0f909c94ea621d0c843979100dc7591bc541d5 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sun, 11 Oct 2020 18:52:00 -0300 Subject: [PATCH 1/9] Clean up SMBus PIIX4 code --- src/device/smbus_piix4.c | 237 ++++++++++++++++++++------------------- 1 file changed, 119 insertions(+), 118 deletions(-) diff --git a/src/device/smbus_piix4.c b/src/device/smbus_piix4.c index affadf39e..131c5c126 100644 --- a/src/device/smbus_piix4.c +++ b/src/device/smbus_piix4.c @@ -39,9 +39,9 @@ smbus_piix4_log(const char *fmt, ...) va_list ap; if (smbus_piix4_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else @@ -56,30 +56,30 @@ smbus_piix4_read(uint16_t addr, void *priv) uint8_t ret = 0x00; switch (addr - dev->io_base) { - case 0x00: - ret = dev->stat; - break; - case 0x02: - dev->index = 0; /* reading from this resets the block data index */ - ret = dev->ctl; - break; - case 0x03: - ret = dev->cmd; - break; - case 0x04: - ret = dev->addr; - break; - case 0x05: - ret = dev->data0; - break; - case 0x06: - ret = dev->data1; - break; - case 0x07: - ret = dev->data[dev->index++]; - if (dev->index >= SMBUS_PIIX4_BLOCK_DATA_SIZE) - dev->index = 0; - break; + case 0x00: + ret = dev->stat; + break; + case 0x02: + dev->index = 0; /* reading from this resets the block data index */ + ret = dev->ctl; + break; + case 0x03: + ret = dev->cmd; + break; + case 0x04: + ret = dev->addr; + break; + case 0x05: + ret = dev->data0; + break; + case 0x06: + ret = dev->data1; + break; + case 0x07: + ret = dev->data[dev->index++]; + if (dev->index >= SMBUS_PIIX4_BLOCK_DATA_SIZE) + dev->index = 0; + break; } smbus_piix4_log("SMBus PIIX4: read(%02x) = %02x\n", addr, ret); @@ -100,99 +100,100 @@ smbus_piix4_write(uint16_t addr, uint8_t val, void *priv) prev_stat = dev->next_stat; dev->next_stat = 0; switch (addr - dev->io_base) { - case 0x00: - /* some status bits are reset by writing 1 to them */ - for (smbus_addr = 0x02; smbus_addr <= 0x10; smbus_addr <<= 1) { - if (val & smbus_addr) - dev->stat &= ~smbus_addr; - } - break; - case 0x02: - dev->ctl = val & ~(0x40); /* START always reads 0 */ - if (val & 0x02) { /* cancel an in-progress command if KILL is set */ - /* cancel only if a command is in progress */ - if (prev_stat) { - dev->stat = 0x10; /* raise FAILED */ - timer_disable(&dev->response_timer); - } - } - if (val & 0x40) { /* dispatch command if START is set */ - smbus_addr = (dev->addr >> 1); - if (!smbus_has_device(smbus_addr)) { - /* raise DEV_ERR if no device is at this address */ - dev->next_stat = 0x4; - break; - } - smbus_read = (dev->addr & 0x01); + case 0x00: + /* some status bits are reset by writing 1 to them */ + for (smbus_addr = 0x02; smbus_addr <= 0x10; smbus_addr <<= 1) { + if (val & smbus_addr) + dev->stat &= ~smbus_addr; + } + break; + case 0x02: + dev->ctl = val & ~(0x40); /* START always reads 0 */ + if (val & 0x02) { /* cancel an in-progress command if KILL is set */ + /* cancel only if a command is in progress */ + if (prev_stat) { + dev->stat = 0x10; /* raise FAILED */ + timer_disable(&dev->response_timer); + } + } + if (val & 0x40) { /* dispatch command if START is set */ + smbus_addr = (dev->addr >> 1); + if (!smbus_has_device(smbus_addr)) { + /* raise DEV_ERR if no device is at this address */ + dev->next_stat = 0x4; + break; + } + smbus_read = (dev->addr & 0x01); - /* decode the 3-bit command protocol */ - switch ((val >> 2) & 0x7) { - case 0x0: /* quick R/W */ - dev->next_stat = 0x2; - break; - case 0x1: /* byte R/W */ - if (smbus_read) - dev->data0 = smbus_read_byte(smbus_addr); - else - smbus_write_byte(smbus_addr, dev->data0); - dev->next_stat = 0x2; - break; - case 0x2: /* byte data R/W */ - if (smbus_read) - dev->data0 = smbus_read_byte_cmd(smbus_addr, dev->cmd); - else - smbus_write_byte_cmd(smbus_addr, dev->cmd, dev->data0); - dev->next_stat = 0x2; - break; - case 0x3: /* word data R/W */ - if (smbus_read) { - temp = smbus_read_word_cmd(smbus_addr, dev->cmd); - dev->data0 = (temp & 0xFF); - dev->data1 = (temp >> 8); - } else { - temp = ((dev->data1 << 8) | dev->data0); - smbus_write_word_cmd(smbus_addr, dev->cmd, temp); - } - dev->next_stat = 0x2; - break; - case 0x5: /* block R/W */ - if (smbus_read) - dev->data0 = smbus_read_block_cmd(smbus_addr, dev->cmd, dev->data, SMBUS_PIIX4_BLOCK_DATA_SIZE); - else - smbus_write_block_cmd(smbus_addr, dev->cmd, dev->data, dev->data0); - dev->next_stat = 0x2; - break; - default: - /* other command protocols have undefined behavior, but raise DEV_ERR to be safe */ - dev->next_stat = 0x4; - break; - } - } - break; - case 0x03: - dev->cmd = val; - break; - case 0x04: - dev->addr = val; - break; - case 0x05: - dev->data0 = val; - break; - case 0x06: - dev->data1 = val; - break; - case 0x07: - dev->data[dev->index++] = val; - if (dev->index >= SMBUS_PIIX4_BLOCK_DATA_SIZE) - dev->index = 0; - break; + /* decode the 3-bit command protocol */ + dev->next_stat = 0x2; /* raise INTER (command completed) by default */ + switch ((val >> 2) & 0x7) { + case 0x0: /* quick R/W */ + break; + + case 0x1: /* byte R/W */ + if (smbus_read) + dev->data0 = smbus_read_byte(smbus_addr); + else + smbus_write_byte(smbus_addr, dev->data0); + break; + + case 0x2: /* byte data R/W */ + if (smbus_read) + dev->data0 = smbus_read_byte_cmd(smbus_addr, dev->cmd); + else + smbus_write_byte_cmd(smbus_addr, dev->cmd, dev->data0); + break; + + case 0x3: /* word data R/W */ + if (smbus_read) { + temp = smbus_read_word_cmd(smbus_addr, dev->cmd); + dev->data0 = (temp & 0xFF); + dev->data1 = (temp >> 8); + } else { + temp = ((dev->data1 << 8) | dev->data0); + smbus_write_word_cmd(smbus_addr, dev->cmd, temp); + } + break; + + case 0x5: /* block R/W */ + if (smbus_read) + dev->data0 = smbus_read_block_cmd(smbus_addr, dev->cmd, dev->data, SMBUS_PIIX4_BLOCK_DATA_SIZE); + else + smbus_write_block_cmd(smbus_addr, dev->cmd, dev->data, dev->data0); + break; + + default: + /* other command protocols have undefined behavior, but raise DEV_ERR to be safe */ + dev->next_stat = 0x4; + break; + } + } + break; + case 0x03: + dev->cmd = val; + break; + case 0x04: + dev->addr = val; + break; + case 0x05: + dev->data0 = val; + break; + case 0x06: + dev->data1 = val; + break; + case 0x07: + dev->data[dev->index++] = val; + if (dev->index >= SMBUS_PIIX4_BLOCK_DATA_SIZE) + dev->index = 0; + break; } /* if a status register update was given, dispatch it after 10ms to ensure nothing breaks */ if (dev->next_stat) { - dev->stat = 0x1; /* raise HOST_BUSY while waiting */ - timer_disable(&dev->response_timer); - timer_set_delay_u64(&dev->response_timer, 10 * TIMER_USEC); + dev->stat = 0x1; /* raise HOST_BUSY while waiting */ + timer_disable(&dev->response_timer); + timer_set_delay_u64(&dev->response_timer, 10 * TIMER_USEC); } } @@ -210,13 +211,13 @@ smbus_piix4_response(void *priv) void smbus_piix4_remap(smbus_piix4_t *dev, uint16_t new_io_base, uint8_t enable) { - if (dev->io_base != 0x0000) + if (dev->io_base) io_removehandler(dev->io_base, 0x10, smbus_piix4_read, NULL, NULL, smbus_piix4_write, NULL, NULL, dev); dev->io_base = new_io_base; - smbus_piix4_log("SMBus PIIX4: remap to %04Xh (enable %d)\n", dev->io_base, !!enable); + smbus_piix4_log("SMBus PIIX4: remap to %04Xh (%sabled)\n", dev->io_base, enable ? "en" : "dis"); - if ((enable) && (dev->io_base != 0x0000)) + if (enable && dev->io_base) io_sethandler(dev->io_base, 0x10, smbus_piix4_read, NULL, NULL, smbus_piix4_write, NULL, NULL, dev); } From 7a71d9ece89d63c515455d8249c4b5f6310b1d7d Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sun, 11 Oct 2020 21:04:29 -0300 Subject: [PATCH 2/9] Fix PostScript printer --- src/printer/prt_ps.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/printer/prt_ps.c b/src/printer/prt_ps.c index 03e7ea9b9..c1b39cf96 100644 --- a/src/printer/prt_ps.c +++ b/src/printer/prt_ps.c @@ -184,7 +184,7 @@ convert_to_pdf(ps_t *dev) static void -write_buffer(ps_t *dev, bool newline) +write_buffer(ps_t *dev, bool finish) { wchar_t path[1024]; FILE *fp; @@ -205,17 +205,19 @@ write_buffer(ps_t *dev, bool newline) fseek(fp, 0, SEEK_END); - fprintf(fp, "%.*s%s", POSTSCRIPT_BUFFER_LENGTH, dev->buffer, newline ? "\n" : ""); + fprintf(fp, "%.*s", POSTSCRIPT_BUFFER_LENGTH, dev->buffer); fclose(fp); dev->buffer[0] = 0; dev->buffer_pos = 0; - if (ghostscript_handle != NULL) - convert_to_pdf(dev); + if (finish) { + if (ghostscript_handle != NULL) + convert_to_pdf(dev); - dev->filename[0] = 0; + dev->filename[0] = 0; + } } @@ -224,7 +226,7 @@ timeout_timer(void *priv) { ps_t *dev = (ps_t *) priv; - write_buffer(dev, false); + write_buffer(dev, true); timer_disable(&dev->timeout_timer); } @@ -263,7 +265,7 @@ process_data(ps_t *dev) /* Ctrl+D (0x04) marks the end of the document */ case '\4': - write_buffer(dev, false); + write_buffer(dev, true); return; /* Don't bother with the others */ @@ -376,7 +378,7 @@ ps_close(void *p) return; if (dev->buffer[0] != 0) - write_buffer(dev, false); + write_buffer(dev, true); if (ghostscript_handle != NULL) { dynld_close(ghostscript_handle); From 124866baaab09f6e221281e459803bbb512c0b66 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Tue, 13 Oct 2020 19:20:14 -0300 Subject: [PATCH 3/9] Upgrade IDE maximum to UDMA/100 and add IDENTIFY word 93 (80-conductor cable detection) --- src/disk/hdc_ide.c | 5 ++++- src/disk/mo.c | 2 +- src/disk/zip.c | 2 +- src/scsi/scsi_cdrom.c | 2 +- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index 762a2d780..09e8d6d68 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -412,7 +412,7 @@ ide_get_max(ide_t *ide, int type) return -1; case TYPE_UDMA: /* UDMA */ if (!ide_boards[ide->board]->force_ata3 && (ide_bm[ide->board] != NULL)) - return 4 /*2*/; + return 5; return -1; default: @@ -620,6 +620,9 @@ ide_identify(ide_t *ide) ide->buffer[88] |= d; ide_log("PIDENTIFY DMA Mode: %04X, %04X\n", ide->buffer[62], ide->buffer[63]); } + + if (max_udma >= 4) + ide->buffer[93] = 0x6000; /* Drive reports 80-conductor cable */ } diff --git a/src/disk/mo.c b/src/disk/mo.c index 798bc0c6d..2d9c86dab 100644 --- a/src/disk/mo.c +++ b/src/disk/mo.c @@ -2013,7 +2013,7 @@ mo_get_max(int ide_has_dma, int type) ret = ide_has_dma ? 1 : -1; break; case TYPE_UDMA: - ret = ide_has_dma ? 4 /*2*/ : -1; + ret = ide_has_dma ? 5 : -1; break; } diff --git a/src/disk/zip.c b/src/disk/zip.c index d1f89fff6..d3a9a8220 100644 --- a/src/disk/zip.c +++ b/src/disk/zip.c @@ -2242,7 +2242,7 @@ zip_get_max(int ide_has_dma, int type) ret = ide_has_dma ? 1 : -1; break; case TYPE_UDMA: - ret = ide_has_dma ? 4 /*2*/ : -1; + ret = ide_has_dma ? 5 : -1; break; } diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index bf0c975f4..63d87b42c 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -2601,7 +2601,7 @@ scsi_cdrom_get_max(int ide_has_dma, int type) ret = ide_has_dma ? 2 : -1; break; case TYPE_UDMA: - ret = ide_has_dma ? 4 /*2*/ : -1; + ret = ide_has_dma ? 5 : -1; break; default: ret = -1; From 5b9d953f3be9d4c7c5ef52cf25c14e943eb8ef49 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Tue, 13 Oct 2020 19:25:40 -0300 Subject: [PATCH 4/9] Clear UHCI status register, fixing a flood of "PCI problems?" errors on Linux --- src/usb.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/usb.c b/src/usb.c index 067294496..570c36962 100644 --- a/src/usb.c +++ b/src/usb.c @@ -56,6 +56,11 @@ uhci_reg_read(uint16_t addr, void *p) uint8_t ret = 0xff; switch (addr & 0x1f) { + case 0x02: + /* Status */ + ret = 0x00; + break; + case 0x10: case 0x11: case 0x12: case 0x13: /* Port status */ ret = 0x00; From 35aedf1ba64de6f51029da9e2f2c67dc21318c06 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Tue, 13 Oct 2020 19:26:29 -0300 Subject: [PATCH 5/9] Add special case on NVR register 0D for VIA 686A/B --- src/nvr_at.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/nvr_at.c b/src/nvr_at.c index d95a6d7c0..17504f64e 100644 --- a/src/nvr_at.c +++ b/src/nvr_at.c @@ -580,7 +580,17 @@ nvr_reg_write(uint16_t reg, uint8_t val, void *priv) break; case RTC_REGC: /* R/O */ + break; + case RTC_REGD: /* R/O */ + /* VT82C686A/B have an ACPI register bit controlled by 0D bit 7. + This is overwritten on read, but testing shows BIOSes will + immediately check the ACPI register after writing to this. */ + if (local->cent == RTC_CENTURY_VIA) { + nvr->regs[RTC_REGD] &= ~0x80; + if (val & 0x80) + nvr->regs[RTC_REGD] |= 0x80; + } break; case 0x2e: From 8d8ee14966b45142c1d0327e30b7a0871a3de815 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Tue, 13 Oct 2020 19:27:48 -0300 Subject: [PATCH 6/9] Implement VIA 686A/B Super I/O and hardware monitor + a handful of fixes --- src/chipset/via_pipc.c | 76 ++++++++-- src/device/hwm_vt82c686.c | 180 ++++++++++++++++++++++++ src/include/86box/chipset.h | 2 + src/include/86box/hwm.h | 4 + src/include/86box/sio.h | 4 + src/sio/sio_vt82c686.c | 272 ++++++++++++++++++++++++++++++++++++ src/win/Makefile.mingw | 5 +- 7 files changed, 531 insertions(+), 12 deletions(-) create mode 100644 src/device/hwm_vt82c686.c create mode 100644 src/sio/sio_vt82c686.c diff --git a/src/chipset/via_pipc.c b/src/chipset/via_pipc.c index 78b2cf0f2..377f26147 100644 --- a/src/chipset/via_pipc.c +++ b/src/chipset/via_pipc.c @@ -51,6 +51,8 @@ #include <86box/machine.h> #include <86box/smbus_piix4.h> #include <86box/chipset.h> +#include <86box/sio.h> +#include <86box/hwm.h> /* Most revision numbers (PCI-ISA bridge or otherwise) were lifted from PCI device @@ -135,7 +137,7 @@ pipc_reset_hard(void *priv) dev->pci_isa_regs[0x4a] = 0x04; dev->pci_isa_regs[0x4f] = 0x03; - dev->pci_isa_regs[0x50] = (dev->local >= VIA_PIPC_686A) ? 0x2d : 0x24; + dev->pci_isa_regs[0x50] = (dev->local >= VIA_PIPC_686A) ? 0x0e : 0x24; /* 686A/B default value does not line up with default bits */ dev->pci_isa_regs[0x59] = 0x04; if (dev->local >= VIA_PIPC_686A) dev->pci_isa_regs[0x5a] = dev->pci_isa_regs[0x5f] = 0x04; @@ -180,8 +182,7 @@ pipc_reset_hard(void *priv) dev->ide_regs[0x4c] = 0xff; dev->ide_regs[0x4e] = 0xff; dev->ide_regs[0x4f] = 0xff; - dev->ide_regs[0x50] = 0x03; dev->ide_regs[0x51] = 0x03; - dev->ide_regs[0x52] = 0x03; dev->ide_regs[0x53] = 0x03; + dev->ide_regs[0x50] = dev->ide_regs[0x51] = dev->ide_regs[0x52] = dev->ide_regs[0x53] = (dev->local >= VIA_PIPC_686A) ? 0x07 : 0x03; if (dev->local >= VIA_PIPC_596A) dev->ide_regs[0x54] = 0x06; @@ -271,6 +272,9 @@ pipc_reset_hard(void *priv) dev->power_regs[0x42] = 0x40; /* external suspend-related pin, must be set */ dev->power_regs[0x48] = 0x01; + if (dev->local >= VIA_PIPC_686A) + dev->power_regs[0x70] = 0x01; + if (dev->local == VIA_PIPC_596A) dev->power_regs[0x80] = 0x01; else if (dev->local >= VIA_PIPC_596B) @@ -411,8 +415,14 @@ pipc_read(int func, int addr, void *priv) ret = dev->ide_regs[addr]; else if ((func < pm_func) && !((func == 2) ? (dev->pci_isa_regs[0x48] & 0x04) : (dev->pci_isa_regs[0x85] & 0x10))) /* USB */ ret = dev->usb_regs[func - 2][addr]; - else if (func == pm_func) /* Power */ + else if (func == pm_func) { /* Power */ ret = dev->power_regs[addr]; + if (addr == 0x42) { + ret &= ~0x10; + if (dev->nvr->regs[0x0d] & 0x80) + ret |= 0x10; + } + } else if ((func <= (pm_func + 2)) && !(dev->pci_isa_regs[0x85] & ((func == (pm_func + 1)) ? 0x04 : 0x08))) /* AC97 / MC97 */ ret = dev->ac97_regs[func - pm_func - 1][addr]; @@ -446,6 +456,7 @@ pipc_write(int func, int addr, uint8_t val, void *priv) pipc_t *dev = (pipc_t *) priv; int c; uint8_t pm_func = dev->usb[1] ? 4 : 3; + void *subdev; if (func > dev->max_func) return; @@ -488,6 +499,13 @@ pipc_write(int func, int addr, uint8_t val, void *priv) nvr_update_io_mapping(dev); break; + case 0x50: case 0x51: case 0x52: case 0x85: + dev->pci_isa_regs[addr] = val; + /* Forward Super I/O-related registers to sio_vt82c686.c */ + if ((subdev = device_get_priv(&via_vt82c686_sio_device))) + vt82c686_sio_write(addr, val, subdev); + break; + case 0x54: pci_set_irq_level(PCI_INTA, !(val & 8)); pci_set_irq_level(PCI_INTB, !(val & 4)); @@ -551,10 +569,6 @@ pipc_write(int func, int addr, uint8_t val, void *priv) dev->pci_isa_regs[addr] &= ~(val); break; - case 0x85: - dev->pci_isa_regs[addr] = val; - break; - default: dev->pci_isa_regs[addr] = val; break; @@ -707,10 +721,21 @@ pipc_write(int func, int addr, uint8_t val, void *priv) acpi_update_io_mapping(dev->acpi, c, dev->power_regs[0x41] & 0x80); break; + case 0x42: + dev->power_regs[addr] = val & 0x0f; + break; + case 0x61: case 0x62: case 0x63: dev->power_regs[(addr - 0x58)] = val; break; + case 0x70: case 0x71: case 0x74: + dev->power_regs[addr] = val; + /* Forward hardware monitor-related registers to hwm_vt82c686.c */ + if ((subdev = device_get_priv(&via_vt82c686_hwm_device))) + vt82c686_hwm_write(addr, val, subdev); + break; + case 0x80: case 0x81: case 0x84: /* 596(A) has the SMBus I/O base here instead. Enable bit is assumed. */ dev->power_regs[addr] = val; smbus_piix4_remap(dev->smbus, (dev->power_regs[0x81] << 8) | (dev->power_regs[0x80] & 0xf0), dev->power_regs[0x84] & 0x01); @@ -804,14 +829,15 @@ pipc_init(const device_t *info) return dev; } + static void pipc_close(void *p) { - pipc_t *pipc = (pipc_t *) p; + pipc_t *dev = (pipc_t *) p; pipc_log("PIPC: close()\n"); - free(pipc); + free(dev); } @@ -857,3 +883,33 @@ const device_t via_vt82c596b_device = NULL, NULL }; + + +const device_t via_vt82c686a_device = +{ + "VIA VT82C686A", + DEVICE_PCI, + VIA_PIPC_686A, + pipc_init, + pipc_close, + NULL, + NULL, + NULL, + NULL, + NULL +}; + + +const device_t via_vt82c686b_device = +{ + "VIA VT82C686B", + DEVICE_PCI, + VIA_PIPC_686B, + pipc_init, + pipc_close, + NULL, + NULL, + NULL, + NULL, + NULL +}; diff --git a/src/device/hwm_vt82c686.c b/src/device/hwm_vt82c686.c new file mode 100644 index 000000000..475162eef --- /dev/null +++ b/src/device/hwm_vt82c686.c @@ -0,0 +1,180 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Emulation of the VIA VT82C686A/B integrated hardware monitor. + * + * + * + * Author: RichardG, + * + * Copyright 2020 RichardG. + */ +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include "cpu.h" +#include <86box/smbus.h> +#include <86box/hwm.h> + + +#define CLAMP(a, min, max) (((a) < (min)) ? (min) : (((a) > (max)) ? (max) : (a))) +#define VT82C686_RPM_TO_REG(r, d) ((r) ? CLAMP(1350000 / (r * d), 1, 255) : 0) +/* Temperature formula from source comments in Linux's via686a.c driver */ +#define VT82C686_TEMP_TO_REG(t) (-1.160370e-10*(t*t*t*t*t*t) + 3.193693e-08*(t*t*t*t*t) - 1.464447e-06*(t*t*t*t) - 2.525453e-04*(t*t*t) + 1.424593e-02*(t*t) + 2.148941e+00*t + 7.275808e+01) +#define VT82C686_VOLTAGE_TO_REG(v) ((v) >> 4) + + +typedef struct { + hwm_values_t *values; + device_t *lm75[2]; + + uint8_t enable; + uint16_t io_base; + uint8_t regs[80]; +} vt82c686_t; + + +static void vt82c686_reset(vt82c686_t *dev, uint8_t initialization); + + +static uint8_t +vt82c686_read(uint16_t addr, void *priv) +{ + vt82c686_t *dev = (vt82c686_t *) priv; + return dev->regs[addr - dev->io_base]; +} + + +static void +vt82c686_write(uint16_t port, uint8_t val, void *priv) +{ + vt82c686_t *dev = (vt82c686_t *) priv; + uint8_t reg = port - dev->io_base; + + if ((reg == 0x41) || (reg == 0x42) || (reg == 0x45) || (reg == 0x46) || (reg == 0x48) || (reg == 0x4a) || (reg >= 0x4c)) + return; + + switch (reg) { + case 0x40: + if (val & 0x80) + vt82c686_reset(dev, 1); + break; + + case 0x47: + val &= 0xf0; + /* update FAN1/FAN2 values to match the new divisor */ + dev->regs[0x29] = VT82C686_RPM_TO_REG(dev->values->fans[0], 1 << ((dev->regs[0x47] >> 4) & 0x3)); + dev->regs[0x2a] = VT82C686_RPM_TO_REG(dev->values->fans[1], 1 << ((dev->regs[0x47] >> 6) & 0x3)); + break; + } + + dev->regs[reg] = val; +} + + +/* Writes to hardware monitor-related configuration space registers + of the VT82C686 power management function are sent here by via_pipc.c */ +void +vt82c686_hwm_write(uint8_t addr, uint8_t val, void *priv) +{ + vt82c686_t *dev = (vt82c686_t *) priv; + + if (dev->io_base) + io_removehandler(dev->io_base, 0x0050, + vt82c686_read, NULL, NULL, vt82c686_write, NULL, NULL, dev); + + switch (addr) { + case 0x70: + dev->io_base &= 0xff00; + dev->io_base |= val & 0x80; + break; + + case 0x71: + dev->io_base &= 0x00ff; + dev->io_base |= val << 8; + break; + + case 0x74: + dev->enable = val & 0x01; + break; + } + + if (dev->enable && dev->io_base) + io_sethandler(dev->io_base, 0x0050, + vt82c686_read, NULL, NULL, vt82c686_write, NULL, NULL, dev); +} + + +static void +vt82c686_reset(vt82c686_t *dev, uint8_t initialization) +{ + memset(dev->regs, 0, 80); + + dev->regs[0x1f] = VT82C686_TEMP_TO_REG(dev->values->temperatures[2]); + dev->regs[0x20] = VT82C686_TEMP_TO_REG(dev->values->temperatures[0]); + dev->regs[0x21] = VT82C686_TEMP_TO_REG(dev->values->temperatures[1]); + + dev->regs[0x22] = VT82C686_VOLTAGE_TO_REG(dev->values->voltages[0]); + dev->regs[0x23] = VT82C686_VOLTAGE_TO_REG(dev->values->voltages[1]); + dev->regs[0x24] = VT82C686_VOLTAGE_TO_REG(dev->values->voltages[2]); + dev->regs[0x25] = VT82C686_VOLTAGE_TO_REG(dev->values->voltages[3]); + dev->regs[0x26] = VT82C686_VOLTAGE_TO_REG(dev->values->voltages[4]); + + dev->regs[0x29] = VT82C686_RPM_TO_REG(dev->values->fans[0], 2); + dev->regs[0x2a] = VT82C686_RPM_TO_REG(dev->values->fans[1], 2); + + dev->regs[0x40] = 0x08; + dev->regs[0x47] = 0x50; + dev->regs[0x49] = (dev->values->temperatures[2] & 0x3) << 6; + dev->regs[0x49] |= (dev->values->temperatures[1] & 0x3) << 4; + dev->regs[0x4b] = (dev->values->temperatures[0] & 0x3) << 6; + dev->regs[0x4b] |= 0x15; + + if (!initialization) + vt82c686_hwm_write(0x85, 0x00, dev); +} + + +static void +vt82c686_close(void *priv) +{ + vt82c686_t *dev = (vt82c686_t *) priv; + + free(dev); +} + + +static void * +vt82c686_init(const device_t *info) +{ + vt82c686_t *dev = (vt82c686_t *) malloc(sizeof(vt82c686_t)); + memset(dev, 0, sizeof(vt82c686_t)); + + dev->values = hwm_get_values(); + + vt82c686_reset(dev, 0); + + return dev; +} + + +const device_t via_vt82c686_hwm_device = { + "VIA VT82C686 Integrated Hardware Monitor", + DEVICE_ISA, + 0, + vt82c686_init, vt82c686_close, NULL, + NULL, NULL, NULL, + NULL +}; diff --git a/src/include/86box/chipset.h b/src/include/86box/chipset.h index 2d263740f..604d3c073 100644 --- a/src/include/86box/chipset.h +++ b/src/include/86box/chipset.h @@ -123,6 +123,8 @@ extern const device_t via_apro_device; extern const device_t via_vt82c586b_device; extern const device_t via_vt82c596_device; extern const device_t via_vt82c596b_device; +extern const device_t via_vt82c686a_device; +extern const device_t via_vt82c686b_device; /* VLSI */ extern const device_t vl82c480_device; diff --git a/src/include/86box/hwm.h b/src/include/86box/hwm.h index 53d69500b..70d835f01 100644 --- a/src/include/86box/hwm.h +++ b/src/include/86box/hwm.h @@ -47,6 +47,8 @@ extern void lm75_remap(lm75_t *dev, uint8_t addr); extern uint8_t lm75_read(lm75_t *dev, uint8_t reg); extern uint8_t lm75_write(lm75_t *dev, uint8_t reg, uint8_t val); +extern void vt82c686_hwm_write(uint8_t addr, uint8_t val, void *priv); + extern const device_t lm75_1_4a_device; extern const device_t lm75_w83781d_device; @@ -59,5 +61,7 @@ extern const device_t as99127f_rev2_device; extern const device_t gl518sm_2c_device; extern const device_t gl518sm_2d_device; +extern const device_t via_vt82c686_hwm_device; + #endif /*EMU_HWM_H*/ diff --git a/src/include/86box/sio.h b/src/include/86box/sio.h index ee155f3fa..51fe2f19e 100644 --- a/src/include/86box/sio.h +++ b/src/include/86box/sio.h @@ -15,6 +15,9 @@ # define EMU_SIO_H +extern void vt82c686_sio_write(uint8_t addr, uint8_t val, void *priv); + + extern const device_t acc3221_device; extern const device_t f82c710_device; extern const device_t fdc37c661_device; @@ -39,6 +42,7 @@ extern const device_t pc97307_device; extern const device_t ps1_m2133_sio; extern const device_t sio_detect_device; extern const device_t um8669f_device; +extern const device_t via_vt82c686_sio_device; extern const device_t w83787f_device; extern const device_t w83877f_device; extern const device_t w83877f_president_device; diff --git a/src/sio/sio_vt82c686.c b/src/sio/sio_vt82c686.c new file mode 100644 index 000000000..c38dc692c --- /dev/null +++ b/src/sio/sio_vt82c686.c @@ -0,0 +1,272 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Emulation of the VIA VT82C686A/B integrated Super I/O. + * + * + * + * Author: RichardG, + * Copyright 2020 RichardG. + */ +#include +#include +#include +#include +#include +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/pci.h> +#include <86box/mem.h> +#include <86box/rom.h> +#include <86box/lpt.h> +#include <86box/serial.h> +#include <86box/fdd.h> +#include <86box/fdc.h> +#include <86box/sio.h> + + +typedef struct { + uint8_t config_enable, cur_reg, regs[32], + fdc_dma, fdc_irq, uart_irq[2], lpt_dma, lpt_irq; + fdc_t *fdc; + serial_t *uart[2]; +} vt82c686_t; + + +static uint8_t +get_lpt_length(vt82c686_t *dev) +{ + uint8_t length = 4; + + if ((dev->regs[0x02] & 0x03) == 0x2) + length = 8; + + return length; +} + + +static void +vt82c686_fdc_handler(vt82c686_t *dev) +{ + uint16_t io_base = (dev->regs[0x03] & 0xfc) << 2; + + fdc_remove(dev->fdc); + + if (dev->regs[0x02] & 0x10) + fdc_set_base(dev->fdc, io_base); + + fdc_set_irq(dev->fdc, dev->fdc_irq); +} + + +static void +vt82c686_lpt_handler(vt82c686_t *dev) +{ + uint16_t io_mask, io_base = dev->regs[0x06] << 2; + int io_len = get_lpt_length(dev); + io_base &= (0xff8 | io_len); + io_mask = 0x3fc; + if (io_len == 8) + io_mask = 0x3f8; + + lpt1_remove(); + + if (((dev->regs[0x02] & 0x03) != 0x03) && (io_base >= 0x100) && (io_base <= io_mask)) + lpt1_init(io_base); + + lpt1_irq(dev->lpt_irq); +} + + +static void +vt82c686_serial_handler(vt82c686_t *dev, int uart) +{ + serial_remove(dev->uart[uart]); + + if (dev->regs[0x02] & (uart ? 0x08 : 0x04)) + serial_setup(dev->uart[uart], (dev->regs[0x07 + uart] & 0xfe) << 2, dev->uart_irq[uart]); +} + + +static void +vt82c686_write(uint16_t port, uint8_t val, void *priv) +{ + vt82c686_t *dev = (vt82c686_t *) priv; + + if (!dev->config_enable) + return; + + if (!(port & 1)) { + /* Registers start at 0xE0 but we cut them down to start at 0x00. */ + dev->cur_reg = (val & 0x1f); + return; + } + + /* Read-only registers */ + if ((dev->cur_reg < 0x02) || (dev->cur_reg == 0x04) || (dev->cur_reg == 0x05) || ((dev->cur_reg >= 0xe9) && (dev->cur_reg < 0xee)) || + (dev->cur_reg == 0xf3) || (dev->cur_reg == 0xf5) || (dev->cur_reg == 0xf7) || (dev->cur_reg >= 0xf9)) + return; + + switch (dev->cur_reg) { + case 0x02: + dev->regs[dev->cur_reg] = val; + vt82c686_lpt_handler(dev); + vt82c686_serial_handler(dev, 0); + vt82c686_serial_handler(dev, 1); + vt82c686_fdc_handler(dev); + break; + + case 0x03: + dev->regs[dev->cur_reg] = val; + vt82c686_fdc_handler(dev); + break; + + case 0x06: + dev->regs[dev->cur_reg] = val; + vt82c686_lpt_handler(dev); + break; + + case 0x07: + dev->regs[dev->cur_reg] = val; + vt82c686_serial_handler(dev, 0); + break; + + case 0x08: + dev->regs[dev->cur_reg] = val; + vt82c686_serial_handler(dev, 1); + break; + + default: + dev->regs[dev->cur_reg] = val; + break; + } +} + + +static uint8_t +vt82c686_read(uint16_t port, void *priv) +{ + vt82c686_t *dev = (vt82c686_t *) priv; + uint8_t ret = 0xff; + + if (!(port & 1)) + ret = dev->cur_reg | 0xe0; + else + ret = dev->regs[dev->cur_reg]; + + return ret; +} + + +/* Writes to Super I/O-related configuration space registers + of the VT82C686 PCI-ISA bridge are sent here by via_pipc.c */ +void +vt82c686_sio_write(uint8_t addr, uint8_t val, void *priv) +{ + vt82c686_t *dev = (vt82c686_t *) priv; + + switch (addr) { + case 0x50: + dev->fdc_dma = val & 0x03; + vt82c686_fdc_handler(dev); + dev->lpt_dma = (val >> 2) & 0x03; + vt82c686_lpt_handler(dev); + break; + + case 0x51: + dev->fdc_irq = val & 0x0f; + vt82c686_fdc_handler(dev); + dev->lpt_irq = val >> 4; + vt82c686_lpt_handler(dev); + break; + + case 0x52: + dev->uart_irq[0] = val & 0x0f; + vt82c686_serial_handler(dev, 0); + dev->uart_irq[1] = val >> 4; + vt82c686_serial_handler(dev, 1); + break; + + case 0x85: + io_removehandler(0x3f0, 0x0002, + vt82c686_read, NULL, NULL, vt82c686_write, NULL, NULL, dev); + if (val & 0x01) + io_sethandler(0x3f0, 0x0002, + vt82c686_read, NULL, NULL, vt82c686_write, NULL, NULL, dev); + + dev->config_enable = val & 0x02; + break; + } +} + + +static void +vt82c686_reset(vt82c686_t *dev) +{ + memset(dev->regs, 0, 20); + + dev->regs[0x00] = 0x3c; + dev->regs[0x02] = 0x03; + dev->regs[0x03] = 0xfc; + dev->regs[0x06] = 0xde; + dev->regs[0x07] = 0xfe; + dev->regs[0x08] = 0xbe; + + fdc_reset(dev->fdc); + + serial_setup(dev->uart[0], SERIAL1_ADDR, SERIAL1_IRQ); + serial_setup(dev->uart[1], SERIAL2_ADDR, SERIAL2_IRQ); + + vt82c686_lpt_handler(dev); + vt82c686_serial_handler(dev, 0); + vt82c686_serial_handler(dev, 1); + vt82c686_fdc_handler(dev); + + vt82c686_sio_write(0x85, 0x00, dev); +} + + +static void +vt82c686_close(void *priv) +{ + vt82c686_t *dev = (vt82c686_t *) priv; + + free(dev); +} + + +static void * +vt82c686_init(const device_t *info) +{ + vt82c686_t *dev = (vt82c686_t *) malloc(sizeof(vt82c686_t)); + memset(dev, 0, sizeof(vt82c686_t)); + + dev->fdc = device_add(&fdc_at_smc_device); + dev->fdc_dma = 2; + + dev->uart[0] = device_add_inst(&ns16550_device, 1); + dev->uart[1] = device_add_inst(&ns16550_device, 2); + + dev->lpt_dma = 3; + + vt82c686_reset(dev); + + return dev; +} + + +const device_t via_vt82c686_sio_device = { + "VIA VT82C686 Integrated Super I/O", + 0, + 0, + vt82c686_init, vt82c686_close, NULL, + NULL, NULL, NULL, + NULL +}; diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 0e2fd0cbe..97cdf15ac 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -660,7 +660,7 @@ MCHOBJ := machine.o machine_table.o \ m_at_socket8.o m_at_slot1.o m_at_slot2.o m_at_socket370.o \ m_at_misc.o -DEVOBJ := bugger.o hwm.o hwm_lm75.o hwm_lm78.o hwm_gl518sm.o ibm_5161.o isamem.o isartc.o lpt.o pci_bridge.o postcard.o serial.o vpc2007.o \ +DEVOBJ := bugger.o hwm.o hwm_lm75.o hwm_lm78.o hwm_gl518sm.o hwm_vt82c686.o ibm_5161.o isamem.o isartc.o lpt.o pci_bridge.o postcard.o serial.o vpc2007.o \ smbus.o smbus_piix4.o \ keyboard.o \ keyboard_xt.o keyboard_at.o \ @@ -675,7 +675,8 @@ SIOOBJ := sio_acc3221.o \ sio_pc87306.o sio_pc87307.o sio_pc87309.o sio_pc87332.o \ sio_w83787f.o \ sio_w83877f.o sio_w83977f.o \ - sio_um8669f.o + sio_um8669f.o \ + sio_vt82c686.o FDDOBJ := fdd.o fdc.o fdc_pii15xb.o \ fdi2raw.o \ From 44c83812913f8a637f004f4ed03b66547e0a34e8 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Tue, 13 Oct 2020 19:28:23 -0300 Subject: [PATCH 7/9] Implement FIC VA-503A (MVP3 + 686A) and rename KA-6110 to match the naming scheme for FIC boards --- src/include/86box/machine.h | 3 +- src/machine/m_at_slot1.c | 4 +- src/machine/m_at_sockets7.c | 86 ++++++++++++++++++++++++++++++++++++- src/machine/machine_table.c | 3 +- 4 files changed, 90 insertions(+), 6 deletions(-) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 13899be44..abd3e4178 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -395,6 +395,7 @@ extern const device_t *at_pb640_get_device(void); /* m_at_super7_ss7.c */ extern int machine_at_ax59pro_init(const machine_t *); extern int machine_at_mvp3_init(const machine_t *); +extern int machine_at_ficva503a_init(const machine_t *); /* m_at_socket8.c */ extern int machine_at_686nx_init(const machine_t *); @@ -425,7 +426,7 @@ extern int machine_at_ax6bc_init(const machine_t *); extern int machine_at_atc6310bxii_init(const machine_t *); extern int machine_at_tsunamiatx_init(const machine_t *); extern int machine_at_p6sba_init(const machine_t *); -extern int machine_at_ka6100_init(const machine_t *); +extern int machine_at_ficka6100_init(const machine_t *); #ifdef EMU_DEVICE_H extern const device_t *at_tsunamiatx_get_device(void); diff --git a/src/machine/m_at_slot1.c b/src/machine/m_at_slot1.c index c028211c7..76b43b2b2 100644 --- a/src/machine/m_at_slot1.c +++ b/src/machine/m_at_slot1.c @@ -575,11 +575,11 @@ at_tsunamiatx_get_device(void) int -machine_at_ka6100_init(const machine_t *model) +machine_at_ficka6100_init(const machine_t *model) { int ret; - ret = bios_load_linear(L"roms/machines/ka6100/610011ex.bin", + ret = bios_load_linear(L"roms/machines/ficka6100/610011ex.bin", 0x000e0000, 131072, 0); if (bios_only || !ret) diff --git a/src/machine/m_at_sockets7.c b/src/machine/m_at_sockets7.c index b7328add9..cd9880a7b 100644 --- a/src/machine/m_at_sockets7.c +++ b/src/machine/m_at_sockets7.c @@ -69,7 +69,7 @@ machine_at_ax59pro_init(const machine_t *model) device_add(&keyboard_ps2_pci_device); device_add(&w83877tf_device); device_add(&sst_flash_39sf020_device); - spd_register(SPD_TYPE_SDRAM, 0x7, 512); + spd_register(SPD_TYPE_SDRAM, 0x7, 256); return ret; } @@ -101,7 +101,89 @@ machine_at_mvp3_init(const machine_t *model) device_add(&keyboard_ps2_pci_device); device_add(&w83877tf_device); device_add(&sst_flash_39sf010_device); - spd_register(SPD_TYPE_SDRAM, 0x3, 512); + spd_register(SPD_TYPE_SDRAM, 0x3, 256); + + return ret; +} + + +int +machine_at_ficva503a_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/ficva503a/jo4116.bin", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 3, 4); + pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x01, PCI_CARD_SPECIAL, 1, 2, 3, 4); + + device_add(&via_mvp3_device); + device_add(&via_vt82c686a_device); + device_add(&keyboard_ps2_pci_device); + device_add(&via_vt82c686_sio_device); + device_add(&sst_flash_39sf020_device); + spd_register(SPD_TYPE_SDRAM, 0x7, 256); + + hwm_values_t machine_hwm = { + { /* fan speeds */ + 3000, /* CPUFAN1 */ + 3000 /* ChassisFAN */ + }, { /* temperatures */ + 32, /* CPU */ + 32, /* System */ + 0 /* unused */ + }, { /* voltages */ + 3300, /* Vcore (3.3V by default) */ + 2500, /* 2.5V (unused) */ + 3300, /* 3.3V */ + RESISTOR_DIVIDER(5000, 9, 16), /* 5V (divider values bruteforced) */ + RESISTOR_DIVIDER(12000, 28, 10) /* 12V (28K/10K divider applies to W83781D but is close enough) */ + } + }; + /* Pentium, Pentium OverDrive MMX, Pentium Mobile MMX: 3.3V (real Pentium Mobile MMX is 2.45V). + Pentium MMX: 2.8 V. + AMD K6 Model 6: 2.9 V for 166/200, 3.2 V for 233. + AMD K6 Model 7: 2.2 V. */ + switch (model->cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type) { + case CPU_WINCHIP: + case CPU_WINCHIP2: +#if (defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86))) + case CPU_Cx6x86: +#endif +#if defined(DEV_BRANCH) && defined(USE_AMD_K5) + case CPU_K5: + case CPU_5K86: +#endif + machine_hwm.voltages[0] = 3500; + break; +#if (defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86))) + case CPU_Cx6x86MX: + machine_hwm.voltages[0] = 2900; + break; +#endif + case CPU_PENTIUMMMX: + machine_hwm.voltages[0] = 2800; + break; + case CPU_K6: + case CPU_K6_2: + machine_hwm.voltages[0] = 2200; + break; + } + machine_hwm.voltages[0] *= 1.32; /* multiplier bruteforced */ + hwm_set_values(machine_hwm); + device_add(&via_vt82c686_hwm_device); return ret; } diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 52c757004..f0fa6434a 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -333,6 +333,7 @@ const machine_t machines[] = { /* Apollo MVP3 */ { "[VIA MVP3] AOpen AX59 Pro", "ax59pro", MACHINE_TYPE_SOCKETS7, MACHINE_CPUS_PENTIUM_SS7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_ax59pro_init, NULL }, { "[VIA MVP3] FIC VA-503+", "ficva503p", MACHINE_TYPE_SOCKETS7, MACHINE_CPUS_PENTIUM_SS7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_mvp3_init, NULL }, + { "[VIA MVP3] FIC VA-503A", "ficva503a", MACHINE_TYPE_SOCKETS7, MACHINE_CPUS_PENTIUM_SS7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 255, machine_at_ficva503a_init, NULL }, /* Socket 8 machines */ /* 440FX */ @@ -365,7 +366,7 @@ const machine_t machines[] = { { "[i440BX] A-Trend ATC6310BXII", "atc6310bxii", MACHINE_TYPE_SLOT1, {{"Intel", cpus_PentiumII}, {"Intel/PGA370", cpus_Celeron},{"VIA", cpus_Cyrix3},{"", NULL},{"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 255, machine_at_atc6310bxii_init, NULL }, { "[i440BX] Tyan Tsunami ATX", "tsunamiatx", MACHINE_TYPE_SLOT1, {{"Intel", cpus_PentiumII}, {"Intel/PGA370", cpus_Celeron},{"VIA", cpus_Cyrix3},{"", NULL},{"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_SOUND, 8, 1024, 8, 255, machine_at_tsunamiatx_init, at_tsunamiatx_get_device }, { "[i440BX] SuperMicro Super P6SBA", "p6sba", MACHINE_TYPE_SLOT1, {{"Intel", cpus_PentiumII}, {"Intel/PGA370", cpus_Celeron},{"VIA", cpus_Cyrix3},{"", NULL},{"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 255, machine_at_p6sba_init, NULL }, - { "[VIA Apollo Pro] FIC KA-6100", "ka6100", MACHINE_TYPE_SLOT1, {{"Intel", cpus_PentiumII}, {"Intel/PGA370", cpus_Celeron},{"VIA", cpus_Cyrix3},{"", NULL},{"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 255, machine_at_ka6100_init, NULL }, + { "[VIA Apollo Pro] FIC KA-6100", "ficka6100", MACHINE_TYPE_SLOT1, {{"Intel", cpus_PentiumII}, {"Intel/PGA370", cpus_Celeron},{"VIA", cpus_Cyrix3},{"", NULL},{"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 255, machine_at_ficka6100_init, NULL }, /* Slot 2 machines(Including Slot 1/2 Hybrids) */ /* 440GX */ From 0e6ba7f796f99e0cb1d3c3d6414bf9342ef21a3e Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Tue, 13 Oct 2020 19:28:34 -0300 Subject: [PATCH 8/9] Add ACPI GPIO value for FIC VA-502A --- src/acpi.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/acpi.c b/src/acpi.c index 43529701c..2a20756c2 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -85,7 +85,7 @@ acpi_raise_smi(void *priv) { acpi_t *dev = (acpi_t *) priv; - if (dev->vendor == VEN_VIA) { + if ((dev->vendor == VEN_VIA) || (dev->vendor == VEN_VIA_596B)) { if ((dev->regs.glbctl & 0x01) && (!dev->regs.smi_lock || !dev->regs.smi_active)) { smi_line = 1; dev->regs.smi_active = 1; @@ -1137,8 +1137,15 @@ acpi_reset(void *priv) dev->regs.gpireg[0] = dev->regs.gpireg[1] = dev->regs.gpireg[2] = 0xff; for (i = 0; i < 4; i++) dev->regs.gporeg[i] = dev->gporeg_default[i]; - if (dev->vendor == VEN_VIA_596B) + if (dev->vendor == VEN_VIA_596B) { dev->regs.gpo_val = 0x7fffffff; + /* FIC VA-503A: + - Bit 11: ATX power + - Bit 4: 80-conductor cable on primary IDE channel (active low) + - Bit 3: 80-conductor cable on secondary IDE channel (active low) + - Bit 2: password cleared (active low) */ + dev->regs.gpi_val = 0xffffffe7; + } } From 8e6a52dd32a1f0bd950dd4982eb6fd6bf8af9dda Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Tue, 13 Oct 2020 19:33:46 -0300 Subject: [PATCH 9/9] Update ACPI GPIO documentation blocks to match each other --- src/acpi.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/acpi.c b/src/acpi.c index b11ea1242..ad95604b2 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -1135,13 +1135,16 @@ acpi_reset(void *priv) memset(&dev->regs, 0x00, sizeof(acpi_regs_t)); dev->regs.gpireg[0] = 0xff; dev->regs.gpireg[1] = 0xff; - dev->regs.gpireg[2] = 0xf3; /* SMSC: Bit 2: 80-conductor cable on primary IDE (0 = yes, 1 = no), Bit 3: on secondary IDE. */ + /* SMSC SLC90E66 machines: + - Bit 3: 80-conductor cable on secondary IDE channel (active low) + - Bit 2: 80-conductor cable on primary IDE channel (active low) */ + dev->regs.gpireg[2] = 0xf3; for (i = 0; i < 4; i++) dev->regs.gporeg[i] = dev->gporeg_default[i]; if (dev->vendor == VEN_VIA_596B) { dev->regs.gpo_val = 0x7fffffff; /* FIC VA-503A: - - Bit 11: ATX power + - Bit 11: ATX power (active high) - Bit 4: 80-conductor cable on primary IDE channel (active low) - Bit 3: 80-conductor cable on secondary IDE channel (active low) - Bit 2: password cleared (active low) */