diff --git a/src/acpi.c b/src/acpi.c index d5201d1bf..bcb81cb4c 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -294,6 +294,93 @@ acpi_reg_read_intel(int size, uint16_t addr, void *p) return ret; } +static uint32_t +acpi_reg_read_sis(int size, uint16_t addr, void *p) +{ + acpi_t *dev = (acpi_t *) p; + uint32_t ret = 0x00000000; + int shift16, shift32; + + addr &= 0x2f; + shift16 = (addr & 1) << 3; + shift32 = (addr & 3) << 3; + + switch(addr) + { + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + ret = (dev->regs.pcntrl >> shift32) & 0xff; + break; + + case 0x12: + ret = dev->regs.p2cntrl; + break; + + case 0x13: + ret = dev->regs.gptimer; + break; + + case 0x14: case 0x15: + ret = (dev->regs.gpsts >> shift16) & 0xff; + break; + + case 0x16: case 0x17: + ret = (dev->regs.gpen >> shift16) & 0xff; + break; + + case 0x18: case 0x19: + ret = (dev->regs.gpcntrl >> shift16) & 0xff; + break; + + case 0x1a: case 0x1b: + ret = (dev->regs.gpen >> shift16) & 0xff; + break; + + case 0x1c: case 0x1d: + ret = (dev->regs.gpmux >> shift16) & 0xff; + break; + + case 0x1e: case 0x1f: + ret = (dev->regs.gplvl >> shift16) & 0xff; + break; + + case 0x20: + ret = dev->regs.smicmd; + break; + + case 0x24: + ret = dev->regs.muxcntrl; + break; + + case 0x25: + ret = dev->regs.auxsts; + break; + + case 0x26: + ret = dev->regs.auxen; + break; + + case 0x2a: + ret = dev->regs.smireg; + break; + + case 0x2b: + ret = dev->regs.acpitst; + break; + + default: + acpi_reg_read_common_regs(size, addr, p); + break; + } +#ifdef ENABLE_ACPI_LOG + if (size != 1) + acpi_log("(%i) ACPI Read (%i) %02X: %02X\n", in_smm, size, addr, ret); +#endif + return ret; +} + static uint32_t acpi_reg_read_via_common(int size, uint16_t addr, void *p) @@ -727,6 +814,93 @@ acpi_reg_write_intel(int size, uint16_t addr, uint8_t val, void *p) } } +static void +acpi_reg_write_sis(int size, uint16_t addr, uint8_t val, void *p) +{ + acpi_t *dev = (acpi_t *) p; + int shift16, shift32; + + addr &= 0x2f; + shift16 = (addr & 1) << 3; + shift32 = (addr & 3) << 3; + +switch(addr) +{ + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + dev->regs.pcntrl = ((dev->regs.pcntrl & ~(0xff << shift32)) | (val << shift32)) & 0x0000007e; + break; + + case 0x12: + dev->regs.p2cntrl = val & 1; + break; + + case 0x13: + dev->regs.gptimer = val; + break; + + case 0x14: case 0x15: + dev->regs.gpsts &= ~((val << shift16) & 0xff9f); + break; + + case 0x16: case 0x17: + dev->regs.gpen = ((dev->regs.gpen & ~(0xff << shift16)) | (val << shift16)) & 0xef1f; + break; + + case 0x18: case 0x19: + dev->regs.gpcntrl &= ~((val << shift16) & 0x07ff); + break; + + case 0x1a: case 0x1b: + dev->regs.gpen = ((dev->regs.gpen & ~(0xff << shift16)) | (val << shift16)) & 0x0187; + break; + + case 0x1c: case 0x1d: + dev->regs.gpmux = ((dev->regs.gpmux & ~(0xff << shift16)) | (val << shift16)) & 0x3f7f; + if(dev->regs.gpmux & 0x0400) + dev->regs.pmsts |= 0x0020; + break; + + case 0x1e: case 0x1f: + dev->regs.gplvl = ((dev->regs.gplvl & ~(0xff << shift16)) | (val << shift16)) & 0x0fb7; + break; + + case 0x20: + dev->regs.smicmd = val; + break; + + case 0x24: + dev->regs.muxcntrl = val & 0xc3; + break; + + case 0x25: + dev->regs.auxsts &= val & 0x1f; + break; + + case 0x26: + dev->regs.auxen = val & 0x3f; + break; + + case 0x2a: + dev->regs.smireg = val; + break; + + case 0x2b: + dev->regs.acpitst = val; + break; + + default: + acpi_reg_write_common_regs(size, addr, val, p); + break; +} + +#ifdef ENABLE_ACPI_LOG + if (size != 1) + acpi_log("(%i) ACPI Write (%i) %02X: %02X\n", in_smm, size, addr, val); +#endif +} static void acpi_reg_write_via_common(int size, uint16_t addr, uint8_t val, void *p) @@ -967,6 +1141,8 @@ acpi_reg_read_common(int size, uint16_t addr, void *p) ret = acpi_reg_read_via_596b(size, addr, p); else if (dev->vendor == VEN_INTEL) ret = acpi_reg_read_intel(size, addr, p); + else if (dev->vendor == VEN_SIS) + ret = acpi_reg_read_sis(size, addr, p); else if (dev->vendor == VEN_SMC) ret = acpi_reg_read_smc(size, addr, p); @@ -987,6 +1163,8 @@ acpi_reg_write_common(int size, uint16_t addr, uint8_t val, void *p) acpi_reg_write_via_596b(size, addr, val, p); else if (dev->vendor == VEN_INTEL) acpi_reg_write_intel(size, addr, val, p); + else if (dev->vendor == VEN_SIS) + acpi_reg_write_sis(size, addr, val, p); else if (dev->vendor == VEN_SMC) acpi_reg_write_smc(size, addr, val, p); } @@ -1166,6 +1344,9 @@ acpi_update_io_mapping(acpi_t *dev, uint32_t base, int chipset_en) default: size = 0x040; break; + case VEN_SIS: + size = 0x030; + break; case VEN_SMC: size = 0x010; break; @@ -1470,6 +1651,19 @@ const device_t acpi_intel_device = NULL }; +const device_t acpi_sis_device = +{ + "SiS ACPI", + DEVICE_PCI, + VEN_SIS, + acpi_init, + acpi_close, + acpi_reset, + { NULL }, + acpi_speed_changed, + NULL, + NULL +}; const device_t acpi_via_device = { diff --git a/src/chipset/CMakeLists.txt b/src/chipset/CMakeLists.txt index c62641c30..cc7498ddc 100644 --- a/src/chipset/CMakeLists.txt +++ b/src/chipset/CMakeLists.txt @@ -16,7 +16,7 @@ add_library(chipset OBJECT acc2168.c cs8230.c ali1217.c ali1429.c ali1489.c headland.c intel_82335.c cs4031.c intel_420ex.c intel_4x0.c intel_sio.c intel_piix.c ../ioapic.c neat.c opti283.c opti291.c opti495.c opti822.c opti895.c opti5x7.c scamp.c scat.c - sis_85c310.c sis_85c4xx.c sis_85c496.c sis_85c50x.c + sis_85c310.c sis_85c4xx.c sis_85c496.c sis_85c50x.c sis_5598.c umc_8886.c umc_8890.c umc_hb4.c via_vt82c49x.c via_vt82c505.c sis_85c310.c sis_85c4xx.c sis_85c496.c sis_85c50x.c gc100.c olivetti_eva.c stpc.c diff --git a/src/chipset/sis_5598.c b/src/chipset/sis_5598.c new file mode 100644 index 000000000..15fc44d89 --- /dev/null +++ b/src/chipset/sis_5598.c @@ -0,0 +1,969 @@ +/* + * 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. + * + * Implementation of the SiS 5597/5598 Pentium PCI/ISA Chipset. + * + * + * + * Authors: Tiseno100, + * + * Copyright 2021 Tiseno100. + */ + +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include "cpu.h" +#include <86box/timer.h> +#include <86box/io.h> +#include <86box/device.h> +#include <86box/apm.h> +#include <86box/nvr.h> + +#include <86box/acpi.h> +#include <86box/ddma.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/hdc_ide_sff8038i.h> +#include <86box/mem.h> +#include <86box/pci.h> +#include <86box/port_92.h> +#include <86box/smram.h> +#include <86box/usb.h> + +#include <86box/chipset.h> + +/* ACPI Flags */ +#define ACPI_BASE ((dev->pci_conf_sb[0][0x91] << 8) | dev->pci_conf_sb[0][0x90]) +#define ACPI_EN (dev->pci_conf_sb[0][0x40] & 0x80) + +/* DIMM */ +#define DIMM_BANK0 dev->pci_conf[0x60] +#define DIMM_BANK1 dev->pci_conf[0x61] +#define DIMM_BANK_ENABLE dev->pci_conf[0x63] + +/* IDE Flags (1 Native / 0 Compatibility)*/ +#define PRIMARY_COMP_NAT_SWITCH (dev->pci_conf_sb[1][9] & 1) +#define SECONDARY_COMP_NAT_SWITCH (dev->pci_conf_sb[1][9] & 4) +#define PRIMARY_NATIVE_BASE (dev->pci_conf_sb[1][0x11] << 8) | (dev->pci_conf_sb[1][0x10] & 0xf8) +#define PRIMARY_NATIVE_SIDE (((dev->pci_conf_sb[1][0x15] << 8) | (dev->pci_conf_sb[1][0x14] & 0xfc)) + 2) +#define SECONDARY_NATIVE_BASE (dev->pci_conf_sb[1][0x19] << 8) | (dev->pci_conf_sb[1][0x18] & 0xf8) +#define SECONDARY_NATIVE_SIDE (((dev->pci_conf_sb[1][0x1d] << 8) | (dev->pci_conf_sb[1][0x1c] & 0xfc)) + 2) +#define BUS_MASTER_BASE ((dev->pci_conf_sb[1][0x20] & 0xf0) | (dev->pci_conf_sb[1][0x21] << 8)) + +#ifdef ENABLE_SIS_5598_LOG +int sis_5598_do_log = ENABLE_SIS_5598_LOG; +static void +sis_5598_log(const char *fmt, ...) +{ + va_list ap; + + if (sis_5598_do_log) + { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define sis_5598_log(fmt, ...) +#endif + +typedef struct sis_5598_t +{ + acpi_t *acpi; + ddma_t *ddma; + nvr_t *nvr; + sff8038i_t *ide_drive[2]; + smram_t *smram; + port_92_t *port_92; + usb_t *usb; + + int nb_device_id, sb_device_id; + uint8_t pci_conf[256], pci_conf_sb[3][256]; +} sis_5598_t; + +void sis_5598_dimm_programming(sis_5598_t *dev) +{ +/* +Based completely off the PC Chips M571 Manual +Configurations are forced and don't work as intended +*/ +switch(mem_size >> 10) +{ +case 8: +DIMM_BANK_ENABLE = 1; +DIMM_BANK0 = 0xc0; +break; +case 16: +DIMM_BANK_ENABLE = 1; +DIMM_BANK0 = 0xc0; +DIMM_BANK1 = 0xc0; +break; +case 24: +DIMM_BANK_ENABLE = 1; +DIMM_BANK0 = 0xc2; +DIMM_BANK1 = 0xc0; +break; +case 32: +DIMM_BANK_ENABLE = 1; +DIMM_BANK0 = 0xc2; +DIMM_BANK1 = 0xc2; +break; +case 40: +DIMM_BANK_ENABLE = 1; +DIMM_BANK0 = 0xc8; +DIMM_BANK1 = 0xc0; +break; +case 48: +DIMM_BANK_ENABLE = 1; +DIMM_BANK0 = 0xc8; +DIMM_BANK1 = 0xc2; +break; +case 56: /* Unintended */ +case 64: +DIMM_BANK_ENABLE = 1; +DIMM_BANK0 = 0xc8; +DIMM_BANK1 = 0xc8; +break; +case 72: +DIMM_BANK_ENABLE = 1; +DIMM_BANK0 = 0xc6; +DIMM_BANK1 = 0xc0; +break; +case 80: +DIMM_BANK_ENABLE = 1; +DIMM_BANK0 = 0xc6; +DIMM_BANK1 = 0xc2; +break; +case 88: /* Unintended */ +case 96: +DIMM_BANK_ENABLE = 1; +DIMM_BANK0 = 0xc6; +DIMM_BANK1 = 0xc8; +break; +case 104: /* Unintended */ +case 112: /* Unintended */ +case 120: /* Unintended */ +case 128: +DIMM_BANK_ENABLE = 1; +DIMM_BANK0 = 0xc6; +DIMM_BANK1 = 0xc6; +break; +case 136: +DIMM_BANK_ENABLE = 1; +DIMM_BANK0 = 10 | 0xca; +DIMM_BANK1 = 0xc0; +break; +case 144: +DIMM_BANK_ENABLE = 1; +DIMM_BANK0 = 10 | 0xca; +DIMM_BANK1 = 2 | 0xc2; +break; +case 152: /* Unintended */ +case 160: +DIMM_BANK_ENABLE = 1; +DIMM_BANK0 = 10 | 0xca; +DIMM_BANK1 = 8 | 0xc8; +break; +case 168: /* Unintended */ +case 176: /* Unintended */ +case 184: /* Unintended */ +case 192: +DIMM_BANK_ENABLE = 1; +DIMM_BANK0 = 10 | 0xca; +DIMM_BANK1 = 6 | 0xc6; +break; +case 200: /* Unintended */ +case 208: /* Unintended */ +case 216: /* Unintended */ +case 224: /* Unintended */ +case 232: /* Unintended */ +case 240: /* Unintended */ +case 248: /* Unintended */ +case 256: +DIMM_BANK_ENABLE = 1; +DIMM_BANK0 = 10 | 0xca; +DIMM_BANK1 = 10 | 0xca; +break; +} +} + +void sis_5598_shadow(int cur_reg, sis_5598_t *dev) +{ + if (cur_reg == 0x76) + { + mem_set_mem_state_both(0xf0000, 0x10000, ((dev->pci_conf[cur_reg] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->pci_conf[cur_reg] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)); + } + else + { + mem_set_mem_state_both(0xc0000 + ((cur_reg & 7) * 0x8000), 0x4000, ((dev->pci_conf[cur_reg] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->pci_conf[cur_reg] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)); + mem_set_mem_state_both(0xc4000 + ((cur_reg & 7) * 0x8000), 0x4000, ((dev->pci_conf[cur_reg] & 8) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->pci_conf[cur_reg] & 2) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)); + } + flushmmucache_nopc(); +} + +void sis_5598_smram(sis_5598_t *dev) +{ + smram_disable_all(); + + switch ((dev->pci_conf[0xa3] & 0xc0) >> 6) + { + case 0: + if (dev->pci_conf[0x74] == 0) + smram_enable(dev->smram, 0x000e0000, 0x000e0000, 0x8000, dev->pci_conf[0xa3] & 0x10, 1); + break; + case 1: + if (dev->pci_conf[0x74] == 0) + smram_enable(dev->smram, 0x000e0000, 0x000a0000, 0x10000, dev->pci_conf[0xa3] & 0x10, 1); + break; + case 2: + if (dev->pci_conf[0x74] == 0) + smram_enable(dev->smram, 0x000e0000, 0x000b0000, 0x10000, dev->pci_conf[0xa3] & 0x10, 1); + break; + case 3: + smram_enable(dev->smram, 0x000a0000, 0x000a0000, 0x10000, dev->pci_conf[0xa3] & 0x10, 1); + break; + } + + flushmmucache_nopc(); +} + +void sis_5598_ddma_update(sis_5598_t *dev) +{ + for (int i = 0; i < 8; i++) + if (i != 4) + ddma_update_io_mapping(dev->ddma, i, dev->pci_conf_sb[0][0x80] >> 4, dev->pci_conf_sb[0][0x81], dev->pci_conf_sb[0][0x80] & 1); +} + +void sis_5598_ide_handler(sis_5598_t *dev) +{ + if (dev->pci_conf_sb[1][4] & 1) + { + if (dev->pci_conf_sb[1][0x4a] & 4) + { + ide_pri_disable(); + ide_set_base(0, PRIMARY_COMP_NAT_SWITCH ? PRIMARY_NATIVE_BASE : 0x1f0); + ide_set_side(0, PRIMARY_COMP_NAT_SWITCH ? PRIMARY_NATIVE_SIDE : 0x3f6); + ide_pri_enable(); + } + if (dev->pci_conf_sb[1][0x4a] & 2) + { + ide_sec_disable(); + ide_set_base(1, SECONDARY_COMP_NAT_SWITCH ? SECONDARY_NATIVE_BASE : 0x170); + ide_set_side(1, SECONDARY_COMP_NAT_SWITCH ? SECONDARY_NATIVE_SIDE : 0x376); + ide_sec_enable(); + } + } +} + +void sis_5598_bm_handler(sis_5598_t *dev) +{ + sff_bus_master_handler(dev->ide_drive[0], dev->pci_conf_sb[1][4] & 4, BUS_MASTER_BASE); + sff_bus_master_handler(dev->ide_drive[1], dev->pci_conf_sb[1][4] & 4, BUS_MASTER_BASE + 8); +} + +static void +sis_5597_write(int func, int addr, uint8_t val, void *priv) +{ + sis_5598_t *dev = (sis_5598_t *)priv; + + switch (addr) + { + case 0x04: /* Command */ + dev->pci_conf[addr] = val & 3; + break; + + case 0x05: /* Command */ + dev->pci_conf[addr] = val & 2; + break; + + case 0x07: /* Status */ + dev->pci_conf[addr] &= val & 0xb9; + break; + + case 0x0d: /* Master latency timer */ + dev->pci_conf[addr] = val; + break; + + case 0x50: /* Host Interface and DRAM arbiter */ + dev->pci_conf[addr] = val & 0xfc; + break; + + case 0x51: /* L2 Cache Controller */ + dev->pci_conf[addr] = (val & 0xcf) | 0x20; /* 512KB L2 Cache Installed */ + cpu_cache_ext_enabled = !!(val & 0x40); + cpu_update_waitstates(); + break; + + case 0x52: /* Control Register */ + dev->pci_conf[addr] = val & 0xe3; + break; + + case 0x53: /* DRAM Control Register */ + case 0x54: /* DRAM Control Register 0*/ + dev->pci_conf[addr] = val; + break; + + case 0x55: /* FPM/EDO DRAM Control Register 1 */ + dev->pci_conf[addr] = val & 0xfe; + break; + + case 0x56: /* Memory Data Latch Enable (MDLE) Delay Control Register */ + case 0x57: /* SDRAM Control Register */ + dev->pci_conf[addr] = val; + break; + + case 0x58: + dev->pci_conf[addr] = val & 0xfc; + break; + + case 0x59: /* DRAM signals driving current Control */ + dev->pci_conf[addr] = val; + break; + + case 0x5a: /* PCI signals driving current Control */ + dev->pci_conf[addr] = val & 3; + break; + + case 0x6c: /* Integrated VGA Controller Control */ + dev->pci_conf[addr] = 0; /* Kill the Integrated GPU */ + break; + + case 0x6d: /* Starting Address of Shared Memory Hole HA[28:23] */ + dev->pci_conf[addr] = val & 2; + break; + + case 0x6e: + dev->pci_conf[addr] = val & 0xc0; + break; + + case 0x70: /* shadow RAM Registers */ + case 0x71: /* shadow RAM Registers */ + case 0x72: /* shadow RAM Registers */ + case 0x73: /* shadow RAM Registers */ + case 0x74: /* shadow RAM Registers */ + case 0x75: /* shadow RAM Registers */ + case 0x76: /* Attribute of shadow RAM for BIOS area */ + dev->pci_conf[addr] = (addr == 0x76) ? (val & 0xe4) : (val & 0xee); + sis_5598_shadow(addr, dev); + break; + + case 0x77: /* Characteristics of non-cacheable area */ + dev->pci_conf[addr] = val & 0x0f; + break; + + case 0x78: /* Allocation of Non-Cacheable area I */ + case 0x79: + case 0x7a: /* Allocation of Non-Cacheable area II */ + case 0x7b: + dev->pci_conf[addr] = val; + break; + + case 0x80: /* PCI master characteristics */ + dev->pci_conf[addr] = val & 0xfe; + break; + + case 0x81: + dev->pci_conf[addr] = val & 0xbe; + break; + + case 0x82: + dev->pci_conf[addr] = val; + break; + + case 0x83: /* CPU to PCI characteristics */ + dev->pci_conf[addr] = val; + port_92_set_features(dev->port_92, !!(val & 0x40), !!(val & 0x80)); + break; + + case 0x84: /* PCI grant timer */ + case 0x85: + case 0x86: /* CPU idle timer */ + dev->pci_conf[addr] = val; + break; + + case 0x87: /* Miscellaneous register */ + dev->pci_conf[addr] = val & 0xfc; + break; + + case 0x88: /* Base address of fast back-to-back area */ + case 0x89: + dev->pci_conf[addr] = val; + break; + + case 0x8a: /* Size of fast back-to-back area */ + case 0x8b: + case 0x90: /* Legacy PMU control register */ + case 0x91: /* Address trap for Legacy PMU function */ + case 0x92: + dev->pci_conf[addr] = val; + break; + + case 0x93: /* STPCLK# and APM SMI control */ + dev->pci_conf[addr] = val; + if ((dev->pci_conf[0x9b] & 1) && (val & 1)) + { + smi_line = 1; + dev->pci_conf[0x9d] |= 1; + } + break; + + case 0x94: /* Cyrix 6x86 and PMU function control */ + dev->pci_conf[addr] = val & 0xf8; + break; + + case 0x95: + dev->pci_conf[addr] = val & 0xfb; + break; + + case 0x96: /* Time slot and Programmable 10-bit I/O port definition */ + dev->pci_conf[addr] = val & 0xfb; + break; + + case 0x97: /* Programmable 10-bit I/O port address bits A9~A2 */ + case 0x98: /* Programmable 16-bit I/O port */ + case 0x99: + case 0x9a: /* System Standby Timer events control */ + case 0x9b: /* Monitor Standdby Timer events control */ + case 0x9c: /* SMI Request events status 0 */ + case 0x9d: /* SMI Request events status 1 */ + case 0x9e: /* STPCLK# Assertion Timer */ + case 0x9f: /* STPCLK# De-assertion Timer */ + case 0xa0: /* Monitor Standby Timer */ + case 0xa1: + case 0xa2: /* System Standby Time */ + dev->pci_conf[addr] = val; + break; + + case 0xa3: /* SMRAM access control and Power supply control */ + dev->pci_conf[addr] = val & 0xd0; + sis_5598_smram(dev); + break; + } + + sis_5598_log("SiS 5597: dev->regs[%02x] = %02x POST: %02x\n", addr, dev->pci_conf[addr], inb(0x80)); +} + +static uint8_t +sis_5597_read(int func, int addr, void *priv) +{ + sis_5598_t *dev = (sis_5598_t *)priv; + sis_5598_log("SiS 5597: dev->regs[%02x] (%02x) POST: %02x\n", addr, dev->pci_conf[addr], inb(0x80)); + return dev->pci_conf[addr]; +} + +void sis_5598_pcitoisa_write(int addr, uint8_t val, sis_5598_t *dev) +{ + switch (addr) + { + case 0x04: /* Command Port */ + dev->pci_conf_sb[0][addr] = val & 0x0f; + break; + + case 0x07: /* Status */ + dev->pci_conf_sb[0][addr] &= val & 0x3f; + break; + + case 0x0d: /* Master latency timer */ + dev->pci_conf_sb[0][addr] = val; + break; + + case 0x40: /* BIOS Control Register */ + dev->pci_conf_sb[0][addr] = val; + acpi_update_io_mapping(dev->acpi, ACPI_BASE, ACPI_EN); + break; + + case 0x41: /* INTA#/INTB#INTC# Remapping Control Register */ + case 0x42: + case 0x43: + case 0x44: /* INTD# Remapping Control Register */ + dev->pci_conf_sb[0][addr] = val & ((addr == 0x44) ? 0x9f : 0x8f); + pci_set_irq_routing(addr & 7, (val & 0x80) ? (val & 0x0f) : PCI_IRQ_DISABLED); + break; + + case 0x45: + dev->pci_conf_sb[0][addr] = val & 0xfc; + switch ((val & 0xc0) >> 6) + { + case 0: + cpu_set_isa_speed(7.159); + break; + case 1: + cpu_set_isa_pci_div(4); + break; + case 2: + cpu_set_isa_pci_div(3); + break; + } + + break; + + case 0x46: + dev->pci_conf_sb[0][addr] = val; + break; + + case 0x47: /* DMA Clock and Wait State Control Register */ + dev->pci_conf_sb[0][addr] = val & 0x7f; + 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 */ + case 0x4c: /* 4Ch/4Dh/4Eh/4Fh Initialization Command Word 1/2/3/4 Mirror Register I */ + case 0x4d: /* 4Ch/4Dh/4Eh/4Fh Initialization Command Word 1/2/3/4 Mirror Register I */ + case 0x4e: /* 4Ch/4Dh/4Eh/4Fh Initialization Command Word 1/2/3/4 Mirror Register I */ + case 0x4f: /* 4Ch/4Dh/4Eh/4Fh Initialization Command Word 1/2/3/4 Mirror Register I */ + case 0x50: /* Initialization Command Word 1/2/3/4 mirror Register II */ + case 0x51: /* Initialization Command Word 1/2/3/4 mirror Register II */ + case 0x52: /* Initialization Command Word 1/2/3/4 mirror Register II */ + case 0x53: /* Initialization Command Word 1/2/3/4 mirror Register II */ + case 0x54: /* Operational Control Word 2/3 Mirror Register I */ + case 0x55: + case 0x56: /* Operational Control Word 2/3 Mirror Register II */ + case 0x57: + case 0x58: /* Counter Access Ports Mirror Register 0 */ + case 0x59: + case 0x5a: + case 0x5b: + case 0x5c: + case 0x5d: + case 0x5e: + dev->pci_conf_sb[0][addr] = val; + break; + + case 0x5f: + dev->pci_conf_sb[0][addr] = val & 0x3f; + break; + + case 0x60: /* Mirror port */ + dev->pci_conf_sb[0][addr] = (uint8_t)inb(0x70); + break; + + case 0x61: /* IDEIRQ Remapping Control Register */ + dev->pci_conf_sb[0][addr] = val & 0xcf; + if (val & 0x80) + { + sff_set_irq_line(dev->ide_drive[0], val & 0x0f); + sff_set_irq_line(dev->ide_drive[1], val & 0x0f); + } + break; + + case 0x62: /* USBIRQ Remapping Control Register */ + case 0x63: /* GPCS0 Control Register */ + case 0x64: /* GPCS1 Control Register */ + case 0x65: /* GPCS0 Output Mode Control Register */ + case 0x66: + case 0x67: /* GPCS1 Output Mode Control Register */ + case 0x68: + dev->pci_conf_sb[0][addr] = val; + break; + + case 0x69: /* GPCS0/1 De-Bounce Control Register */ + dev->pci_conf_sb[0][addr] = val & 0xdf; + break; + + case 0x6a: /* ACPI/SCI IRQ Remapping Control Register */ + dev->pci_conf_sb[0][addr] = val; + if (val & 0x80) + acpi_set_irq_line(dev->acpi, val & 0x0f); + break; + + case 0x6b: + dev->pci_conf_sb[0][addr] = val; + break; + + case 0x6c: + dev->pci_conf_sb[0][addr] = val & 0xfe; + break; + + case 0x6d: + case 0x6e: /* Software-Controlled Interrupt Request, Channels 7-0 */ + case 0x6f: /* Software-Controlled Interrupt Request, channels 15-8 */ + case 0x70: + dev->pci_conf_sb[0][addr] = val; + break; + + case 0x71: /* Type-F DMA Control Register */ + dev->pci_conf_sb[0][addr] = val & 0xef; + break; + + case 0x72: /* SMI Triggered By IRQ Control */ + dev->pci_conf_sb[0][addr] = val & 0xfa; + break; + + case 0x73: /* SMI Triggered By IRQ Control */ + dev->pci_conf_sb[0][addr] = val; + break; + + case 0x74: /* System Standby Timer Reload, System Standby State Exit And Throttling State Exit Control */ + dev->pci_conf_sb[0][addr] = val & 0xfb; + break; + + case 0x75: /* System Standby Timer Reload, System Standby State Exit And Throttling State Exit Control */ + dev->pci_conf_sb[0][addr] = val; + break; + + case 0x76: /* Monitor Standby Timer Reload And Monitor Standby State Exit Control */ + dev->pci_conf_sb[0][addr] = val & 0xfb; + break; + + case 0x77: /* Monitor Standby Timer Reload And Monitor Standby State Exit Control */ + dev->pci_conf_sb[0][addr] = val; + break; + + case 0x80: /* DDMA Control Register */ + case 0x81: + dev->pci_conf_sb[0][addr] = val & ((addr == 0x81) ? 0xff : 0xf1); + sis_5598_ddma_update(dev); + break; + + case 0x84: + dev->pci_conf_sb[0][addr] = val & 0xef; + break; + + case 0x88: + dev->pci_conf_sb[0][addr] = val; + break; + + case 0x89: /* Serial Interrupt Enable Register 1 */ + dev->pci_conf_sb[0][addr] = val & 0x7e; + break; + + case 0x8a: /* Serial Interrupt Enable Register 2 */ + dev->pci_conf_sb[0][addr] = val & 0xef; + break; + + case 0x90: /* ACPI Base Address Register */ + case 0x91: /* ACPI Base Address Register */ + dev->pci_conf_sb[0][addr] = val; + acpi_update_io_mapping(dev->acpi, ACPI_BASE, ACPI_EN); + break; + } +} + +void sis_5598_ide_write(int addr, uint8_t val, sis_5598_t *dev) +{ + switch (addr) + { + case 0x04: /* Command */ + dev->pci_conf_sb[1][addr] = val & 7; + sis_5598_ide_handler(dev); + sis_5598_bm_handler(dev); + break; + + case 0x06: /* Status */ + dev->pci_conf_sb[1][addr] = val & 0x20; + break; + + case 0x07: /* Status */ + dev->pci_conf_sb[1][addr] = val & 0x3c; + break; + + case 0x0d: /* Latency Timer */ + dev->pci_conf_sb[1][addr] = val; + break; + + case 0x09: /* Programming Interface Byte */ + case 0x10: /* Primary Channel Command Block Base Address Register */ + case 0x11: /* Primary Channel Command Block Base Address Register */ + case 0x12: /* Primary Channel Command Block Base Address Register */ + case 0x13: /* Primary Channel Command Block Base Address Register */ + case 0x14: /* Primary Channel Control Block Base Address Register */ + case 0x15: /* Primary Channel Control Block Base Address Register */ + case 0x16: /* Primary Channel Control Block Base Address Register */ + case 0x17: /* Primary Channel Control Block Base Address Register */ + case 0x18: /* Secondary Channel Command Block Base Address Register */ + case 0x19: /* Secondary Channel Command Block Base Address Register */ + case 0x1a: /* Secondary Channel Command Block Base Address Register */ + case 0x1b: /* Secondary Channel Command Block Base Address Register */ + case 0x1c: /* Secondary Channel Control Block Base Address Register */ + case 0x1d: /* Secondary Channel Control Block Base Address Register */ + case 0x1e: /* Secondary Channel Control Block Base Address Register */ + case 0x1f: /* Secondary Channel Control Block Base Address Register */ + dev->pci_conf_sb[1][addr] = val & ((addr == 9) ? 0x0f : 0xff); + sis_5598_ide_handler(dev); + break; + + case 0x20: /* Bus Master IDE Control Register Base Address */ + case 0x21: /* Bus Master IDE Control Register Base Address */ + case 0x22: /* Bus Master IDE Control Register Base Address */ + case 0x23: /* Bus Master IDE Control Register Base Address */ + dev->pci_conf_sb[1][addr] = val; + sis_5598_bm_handler(dev); + break; + + case 0x2c: /* Subsystem ID */ + dev->pci_conf_sb[1][addr] = val; + break; + + case 0x30: /* Expansion ROM Base Address */ + case 0x31: /* Expansion ROM Base Address */ + case 0x32: /* Expansion ROM Base Address */ + case 0x33: /* Expansion ROM Base Address */ + dev->pci_conf_sb[1][addr] = val; + break; + + case 0x40: /* IDE Primary Channel/Master Drive Data Recovery Time Control */ + dev->pci_conf_sb[1][addr] = val & 0xcf; + break; + + case 0x41: /* IDE Primary Channel/Master Drive Control */ + dev->pci_conf_sb[1][addr] = val & 0xe7; + break; + + case 0x42: /* IDE Primary Channel/Slave Drive Data Recovery Time Control */ + dev->pci_conf_sb[1][addr] = val & 0x0f; + break; + + case 0x43: /* IDE Primary Channel/Slave Drive Data Active Time Control */ + case 0x44: /* IDE Secondary Channel/Master Drive Data Recovery Time Control */ + case 0x45: /* IDE Secondary Channel/Master Drive Data Active Time Control */ + dev->pci_conf_sb[1][addr] = val & 0xe7; + break; + + case 0x46: /* IDE Secondary Channel/Slave Drive Data Recovery Time Control */ + dev->pci_conf_sb[1][addr] = val & 0x0f; + break; + + case 0x47: /* IDE Secondary Channel/Slave Drive Data Active Time Control */ + dev->pci_conf_sb[1][addr] = val & 0xe7; + break; + + case 0x48: /* IDE Command Recovery Time Control */ + case 0x49: /* IDE Command Active Time Control */ + dev->pci_conf_sb[1][addr] = val & 0x0f; + break; + + case 0x4a: /* IDE General Control Register 0 */ + dev->pci_conf_sb[1][addr] = val; + sis_5598_ide_handler(dev); + break; + + case 0x4b: /* IDE General Control register 1 */ + case 0x4c: /* Prefetch Count of Primary Channel */ + case 0x4d: + case 0x4e: /* Prefetch Count of Secondary Channel */ + case 0x4f: + case 0x50: /* IDE minimum accessed time register */ + case 0x51: + dev->pci_conf_sb[1][addr] = val; + break; + + case 0x52: /* IDE Miscellaneous Control Register */ + dev->pci_conf_sb[1][addr] = val & 0x0f; + break; + } +} + +void sis_5598_usb_write(int addr, uint8_t val, sis_5598_t *dev) +{ + switch (addr) + { + case 0x04: /* Command */ + dev->pci_conf_sb[2][addr] = val; + ohci_update_mem_mapping(dev->usb, dev->pci_conf_sb[2][0x11], dev->pci_conf_sb[2][0x12], dev->pci_conf_sb[2][0x13], dev->pci_conf_sb[2][4] & 1); + break; + + case 0x05: /* Command */ + dev->pci_conf_sb[2][addr] = val & 3; + break; + + case 0x06: /* Status */ + dev->pci_conf_sb[2][addr] &= val & 0xf0; + break; + + case 0x07: /* Status */ + dev->pci_conf_sb[2][addr] &= val; + break; + + case 0x0d: /* Latency Timer */ + dev->pci_conf_sb[2][addr] = val; + break; + + case 0x11: /* USB Memory Space Base Address Register */ + case 0x12: /* USB Memory Space Base Address Register */ + case 0x13: /* USB Memory Space Base Address Register */ + dev->pci_conf_sb[2][addr] = val & ((addr == 0x11) ? 0x0f : 0xff); + ohci_update_mem_mapping(dev->usb, dev->pci_conf_sb[2][0x11], dev->pci_conf_sb[2][0x12], dev->pci_conf_sb[2][0x13], dev->pci_conf_sb[2][4] & 1); + break; + + case 0x3c: /* Interrupt Line */ + case 0x3d: /* Interrupt Pin */ + case 0x3e: /* Minimum Grant Time */ + case 0x3f: /* Maximum Latency Time */ + dev->pci_conf_sb[2][addr] = val; + break; + } +} + +static void +sis_5598_write(int func, int addr, uint8_t val, void *priv) +{ + sis_5598_t *dev = (sis_5598_t *)priv; + switch (func) + { + case 0: + sis_5598_pcitoisa_write(addr, val, dev); + break; + case 1: + sis_5598_ide_write(addr, val, dev); + break; + case 2: + sis_5598_usb_write(addr, val, dev); + break; + } + sis_5598_log("SiS 5598: dev->regs[%02x][%02x] = %02x POST: %02x\n", func, addr, dev->pci_conf_sb[func][addr], inb(0x80)); +} + +static uint8_t +sis_5598_read(int func, int addr, void *priv) +{ + sis_5598_t *dev = (sis_5598_t *)priv; + if ((func >= 0) && (func <= 2)) + { + sis_5598_log("SiS 5598: dev->regs[%02x][%02x] (%02x) POST: %02x\n", func, addr, dev->pci_conf_sb[func][addr], inb(0x80)); + return dev->pci_conf_sb[func][addr]; + } + else + return 0xff; +} + +static void +sis_5598_defaults(sis_5598_t *dev) +{ + dev->pci_conf[0x00] = 0x39; /* SiS */ + dev->pci_conf[0x01] = 0x10; + dev->pci_conf[0x02] = 0x97; /* 5597 */ + dev->pci_conf[0x03] = 0x55; + dev->pci_conf[0x08] = 4; + dev->pci_conf[0x0b] = 6; + dev->pci_conf[0x0d] = 0xff; + dev->pci_conf[0x9e] = 0xff; + dev->pci_conf[0x9f] = 0xff; + dev->pci_conf[0xa0] = 0xff; + + dev->pci_conf_sb[0][0x00] = 0x39; /* SiS */ + dev->pci_conf_sb[0][0x01] = 0x10; + dev->pci_conf_sb[0][0x02] = 8; /* 5598 */ + dev->pci_conf_sb[0][0x08] = 1; + dev->pci_conf_sb[0][0x0a] = 1; + dev->pci_conf_sb[0][0x0b] = 6; + dev->pci_conf_sb[0][0x0d] = 0xff; + dev->pci_conf_sb[0][0x0e] = 0x30; + dev->pci_conf_sb[0][0x0f] = 0x30; + dev->pci_conf_sb[0][0x48] = 1; + dev->pci_conf_sb[0][0x4a] = 0x10; + dev->pci_conf_sb[0][0x4b] = 0x0f; + dev->pci_conf_sb[0][0x6d] = 0x19; + dev->pci_conf_sb[0][0x70] = 0x12; + + dev->pci_conf_sb[1][0x00] = 0x39; /* SiS */ + dev->pci_conf_sb[1][0x01] = 0x10; + dev->pci_conf_sb[1][0x02] = 0x13; /* 5513 */ + dev->pci_conf_sb[1][0x03] = 0x55; + dev->pci_conf_sb[1][0x08] = 0xd0; + dev->pci_conf_sb[0][0x09] = 0x80; + dev->pci_conf_sb[1][0x0a] = 1; + dev->pci_conf_sb[1][0x0b] = 1; + + dev->pci_conf_sb[2][0x00] = 0x39; /* SiS */ + dev->pci_conf_sb[2][0x01] = 0x10; + dev->pci_conf_sb[2][0x02] = 1; /* 7710 */ + dev->pci_conf_sb[2][0x03] = 0x70; + dev->pci_conf_sb[2][0x06] = 2; + dev->pci_conf_sb[2][0x07] = 0x80; + dev->pci_conf_sb[2][0x08] = 0xe0; + dev->pci_conf_sb[2][0x09] = 0x10; + dev->pci_conf_sb[2][0x0a] = 3; + dev->pci_conf_sb[2][0x0b] = 0x0c; + dev->pci_conf_sb[2][0x0e] = 0x10; + dev->pci_conf_sb[2][0x3d] = 1; +} + +static void +sis_5598_reset(void *priv) +{ + sis_5598_t *dev = (sis_5598_t *)priv; + + /* Program defaults */ + sis_5598_defaults(dev); + + /* Set up ACPI */ + acpi_set_slot(dev->acpi, dev->sb_device_id); + acpi_set_nvr(dev->acpi, dev->nvr); + + /* Set up IDE */ + sff_set_slot(dev->ide_drive[0], dev->sb_device_id); + sff_set_slot(dev->ide_drive[1], dev->sb_device_id); + sff_bus_master_reset(dev->ide_drive[0], BUS_MASTER_BASE); + sff_bus_master_reset(dev->ide_drive[1], BUS_MASTER_BASE + 8); +} + +static void +sis_5598_close(void *priv) +{ + sis_5598_t *dev = (sis_5598_t *)priv; + + smram_del(dev->smram); + free(dev); +} + +static void * +sis_5598_init(const device_t *info) +{ + sis_5598_t *dev = (sis_5598_t *)malloc(sizeof(sis_5598_t)); + memset(dev, 0, sizeof(sis_5598_t)); + dev->nb_device_id = pci_add_card(PCI_ADD_NORTHBRIDGE, sis_5597_read, sis_5597_write, dev); /* Device 0: SiS 5597 */ + dev->sb_device_id = pci_add_card(PCI_ADD_SOUTHBRIDGE, sis_5598_read, sis_5598_write, dev); /* Device 1: SiS 5598 */ + + /* ACPI */ + dev->acpi = device_add(&acpi_sis_device); + dev->nvr = device_add(&at_nvr_device); + + /* DDMA */ + dev->ddma = device_add(&ddma_device); + + /* RAM Bank Programming */ + sis_5598_dimm_programming(dev); + + /* SFF IDE */ + dev->ide_drive[0] = device_add_inst(&sff8038i_device, 1); + dev->ide_drive[1] = device_add_inst(&sff8038i_device, 2); + + /* SMRAM */ + dev->smram = smram_add(); + + /* Port 92 */ + dev->port_92 = device_add(&port_92_pci_device); + + /* USB */ + dev->usb = device_add(&usb_device); + + sis_5598_reset(dev); + + return dev; +} + +const device_t sis_5598_device = { + "SiS 5597/5598", + DEVICE_PCI, + 0, + sis_5598_init, + sis_5598_close, + sis_5598_reset, + {NULL}, + NULL, + NULL, + NULL}; diff --git a/src/include/86box/acpi.h b/src/include/86box/acpi.h index 33044f49b..08019d352 100644 --- a/src/include/86box/acpi.h +++ b/src/include/86box/acpi.h @@ -44,6 +44,7 @@ extern "C" { #define VEN_ALI 0x010b9 #define VEN_INTEL 0x08086 +#define VEN_SIS 0x01039 #define VEN_SMC 0x01055 #define VEN_VIA 0x01106 #define VEN_VIA_596B 0x11106 @@ -51,23 +52,23 @@ extern "C" { typedef struct { - uint8_t plvl2, plvl3, + uint8_t acpitst, auxen, auxsts, plvl2, plvl3, smicmd, gpio_dir, - gpio_val, pad, - timer32, + gpio_val, muxcntrl, pad, + timer32, smireg, gpireg[3], gporeg[4]; uint16_t pmsts, pmen, pmcntrl, gpsts, gpsts1, gpen, gpen1, gpscien, - gpcntrl, - gpsmien, pscntrl, + gpcntrl, gplvl, gpmux, + gpsel, gpsmien, pscntrl, gpscists; int smi_lock, smi_active; - uint32_t pcntrl, glbsts, + uint32_t pcntrl, p2cntrl, glbsts, devsts, glben, glbctl, devctl, padsts, paden, - gptren, timer_val, + gptren, gptimer, timer_val, gpo_val, gpi_val, extsmi_val, pad0; uint64_t tmr_overflow_time; @@ -95,6 +96,7 @@ extern int acpi_rtc_status; extern const device_t acpi_ali_device; extern const device_t acpi_intel_device; +extern const device_t acpi_sis_device; extern const device_t acpi_smc_device; extern const device_t acpi_via_device; extern const device_t acpi_via_596b_device; diff --git a/src/include/86box/chipset.h b/src/include/86box/chipset.h index 41c413f18..2daee66a2 100644 --- a/src/include/86box/chipset.h +++ b/src/include/86box/chipset.h @@ -112,6 +112,7 @@ extern const device_t sis_85c50x_device; #if defined(DEV_BRANCH) && defined(USE_SIS_5571) extern const device_t sis_5571_device; #endif +extern const device_t sis_5598_device; /* ST */ extern const device_t stpc_client_device; diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index c44ca1446..9830f6a91 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -344,7 +344,9 @@ extern int machine_at_486sp3_init(const machine_t *); extern int machine_at_486sp3c_init(const machine_t *); extern int machine_at_486sp3g_init(const machine_t *); extern int machine_at_486ap4_init(const machine_t *); +#if defined(DEV_BRANCH) && defined(NO_SIO) extern int machine_at_486vipio2_init(const machine_t *); +#endif extern int machine_at_abpb4_init(const machine_t *); extern int machine_at_win486pci_init(const machine_t *); @@ -473,6 +475,9 @@ extern int machine_at_ficva502_init(const machine_t *); extern int machine_at_ficpa2012_init(const machine_t *); +extern int machine_at_sp97xv_init(const machine_t *); +extern int machine_at_m571_init(const machine_t *); + #ifdef EMU_DEVICE_H extern const device_t *at_thor_get_device(void); extern const device_t *at_pb640_get_device(void); diff --git a/src/include/86box/nvr.h b/src/include/86box/nvr.h index 0e8eff0af..33b4c4310 100644 --- a/src/include/86box/nvr.h +++ b/src/include/86box/nvr.h @@ -81,6 +81,7 @@ typedef struct _nvr_ { void (*ven_save)(void); uint8_t regs[NVR_MAXSIZE]; /* these are the registers */ + uint8_t apc_regs[4]; /* AND THIS! IS THE APC MADAFAKA :b */ } nvr_t; diff --git a/src/include/86box/sio.h b/src/include/86box/sio.h index 4de9653aa..b0ddb1ec7 100644 --- a/src/include/86box/sio.h +++ b/src/include/86box/sio.h @@ -35,6 +35,7 @@ extern const device_t fdc37c932qf_device; extern const device_t fdc37c935_device; extern const device_t fdc37m60x_device; extern const device_t fdc37m60x_370_device; +extern const device_t it8661f_device; extern const device_t i82091aa_device; extern const device_t i82091aa_398_device; extern const device_t i82091aa_ide_device; diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index 8b2bb600b..03e6ee84d 100644 --- a/src/machine/m_at_socket7.c +++ b/src/machine/m_at_socket7.c @@ -1286,3 +1286,55 @@ machine_at_ficpa2012_init(const machine_t *model) return ret; } + +int +machine_at_sp97xv_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/sp97xv/0109XV.005", + 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, 1, 2, 3, 4); + device_add(&sis_5598_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&w83877f_device); + device_add(&sst_flash_29ee010_device); + + return ret; +} + +int +machine_at_m571_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/m571/2k0621s.rom", + 0x000c0000, 262144, 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, 1, 2, 3, 4); + pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 4, 1, 2, 3); + device_add(&sis_5598_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&it8661f_device); + device_add(&sst_flash_29ee020_device); + + return ret; +} diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index dd48c17ad..3eb7c5f7f 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -249,7 +249,9 @@ const machine_t machines[] = { { "[STPC Consumer-II] Acrosser AR-B1479", "arb1479", MACHINE_TYPE_486, CPU_PKG_STPC, 0, 66666667, 66666667, 0, 0, 2.0, 2.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 32768, 163840, 8192, 255, machine_at_arb1479_init, NULL }, { "[STPC Elite] Advantech PCM-9340", "pcm9340", MACHINE_TYPE_486, CPU_PKG_STPC, 0, 66666667, 66666667, 0, 0, 2.0, 2.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 32768, 98304, 8192, 255, machine_at_pcm9340_init, NULL }, { "[STPC Atlas] AAEON PCM-5330", "pcm5330", MACHINE_TYPE_486, CPU_PKG_STPC, 0, 66666667, 66666667, 0, 0, 2.0, 2.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 32768, 131072,32768, 255, machine_at_pcm5330_init, NULL }, +#if defined(DEV_BRANCH) && defined(NO_SIO) { "[VIA VT82C496G] FIC VIP-IO2", "486vipio2", MACHINE_TYPE_486, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCIV | MACHINE_IDE_DUAL, 1024, 131072, 1024, 255, machine_at_486vipio2_init, NULL }, +#endif /* Socket 4 machines */ /* 430LX */ @@ -360,6 +362,10 @@ const machine_t machines[] = { { "[SiS 5571] MSI MS-5146", "ms5146", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 2500, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 393216, 8192, 127, machine_at_ms5146_init, NULL }, #endif + /* SiS 5598 */ + { "[SiS 5598] ASUS SP97-XV", "sp97xv", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 60000000, 66666667, 2100, 3200, 1.5, 2.5, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 262144, 8192, 255, machine_at_sp97xv_init, NULL }, + { "[SiS 5598] PC Chips M571", "m571", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 75000000, 2500, 3500, 1.5, 3.5, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 262144, 8192, 255, machine_at_m571_init, NULL }, + /* ALi ALADDiN IV */ #if defined(DEV_BRANCH) && defined(USE_M154X) { "[ALi ALADDiN IV] PC Chips M560", "m560", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 83333333, 2500, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 262144, 8192, 255, machine_at_m560_init, NULL }, diff --git a/src/nvr_at.c b/src/nvr_at.c index 7b695cfde..ad7721d91 100644 --- a/src/nvr_at.c +++ b/src/nvr_at.c @@ -284,6 +284,10 @@ #define RTC_ALDAY 0x7D /* VIA VT82C586B - alarm day */ #define RTC_ALMONTH 0x7E /* VIA VT82C586B - alarm month */ #define RTC_CENTURY_VIA 0x7F /* century register for VIA VT82C586B */ + +#define RTC_ALDAY_SIS 0x7E /* Day of Month Alarm for SiS */ +#define RTC_ALMONT_SIS 0x7F /* Month Alarm for SiS */ + #define RTC_REGS 14 /* number of registers */ #define FLAG_LS_HACK 0x01 @@ -452,7 +456,9 @@ timer_update(void *priv) check_alarm(nvr, RTC_MINUTES) && check_alarm(nvr, RTC_HOURS) && check_alarm_via(nvr, RTC_DOM, RTC_ALDAY) && - check_alarm_via(nvr, RTC_MONTH, RTC_ALMONTH)) { + check_alarm_via(nvr, RTC_MONTH, RTC_ALMONTH) && + check_alarm_via(nvr, RTC_DOM, RTC_ALDAY_SIS) && + check_alarm_via(nvr, RTC_MONTH, RTC_ALMONT_SIS)) { nvr->regs[RTC_REGC] |= REGC_AF; if (nvr->regs[RTC_REGB] & REGB_AIE) { nvr->regs[RTC_REGC] |= REGC_IRQF; @@ -759,7 +765,6 @@ nvr_read(uint16_t addr, void *priv) return(ret); } - /* Secondary NVR write - used by SMC. */ static void nvr_sec_write(uint16_t addr, uint8_t val, void *priv) @@ -775,7 +780,6 @@ nvr_sec_read(uint16_t addr, void *priv) return nvr_read(0x72 + (addr & 1), priv); } - /* Reset the RTC state to 1980/01/01 00:00. */ static void nvr_reset(nvr_t *nvr) @@ -791,7 +795,6 @@ nvr_reset(nvr_t *nvr) nvr->regs[local->cent] = RTC_BCD(19); } - /* Process after loading from file. */ static void nvr_start(nvr_t *nvr) @@ -861,7 +864,6 @@ nvr_at_sec_handler(int set, uint16_t base, nvr_t *nvr) nvr_sec_read,NULL,NULL, nvr_sec_write,NULL,NULL, nvr); } - void nvr_read_addr_set(int set, nvr_t *nvr) { @@ -986,10 +988,8 @@ nvr_at_init(const device_t *info) /* Set up the I/O handler for this device. */ io_sethandler(0x0070, 2, nvr_read,NULL,NULL, nvr_write,NULL,NULL, nvr); - if (info->local & 8) { io_sethandler(0x0072, 2, nvr_read,NULL,NULL, nvr_write,NULL,NULL, nvr); - } nvr_at_inited = 1; } diff --git a/src/sio/CMakeLists.txt b/src/sio/CMakeLists.txt index 62debb1b5..d19a8e251 100644 --- a/src/sio/CMakeLists.txt +++ b/src/sio/CMakeLists.txt @@ -15,6 +15,7 @@ add_library(sio OBJECT sio_acc3221.c sio_f82c710.c sio_82091aa.c sio_fdc37c661.c sio_fdc37c66x.c sio_fdc37c669.c sio_fdc37c93x.c sio_fdc37m60x.c + sio_it8661f.c sio_pc87306.c sio_pc87307.c sio_pc87309.c sio_pc87310.c sio_pc87311.c sio_pc87332.c sio_prime3b.c sio_prime3c.c sio_w83787f.c sio_w83877f.c sio_w83977f.c sio_um8669f.c diff --git a/src/sio/sio_it8661f.c b/src/sio/sio_it8661f.c new file mode 100644 index 000000000..e6cd131a3 --- /dev/null +++ b/src/sio/sio_it8661f.c @@ -0,0 +1,312 @@ +/* + * 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. + * + * Implementation of the ITE IT8661F chipset. + * + * Note: This Super I/O is partially incomplete and intended only for having the intended machine to function + * + * Authors: Tiseno100 + * + * Copyright 2021 Tiseno100 + * + */ +#include +#include +#include +#include +#include +#include <86box/86box.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/device.h> +#include <86box/lpt.h> +#include <86box/serial.h> +#include <86box/fdd.h> +#include <86box/fdc.h> +#include <86box/fdd_common.h> +#include <86box/sio.h> + +#define LDN dev->regs[7] + +typedef struct +{ + fdc_t *fdc_controller; + serial_t *uart[2]; + + uint8_t index, regs[256], device_regs[6][256]; + int unlocked, enumerator; +} it8661f_t; + +uint8_t mb_pnp_key[32] = {0x6a, 0xb5, 0xda, 0xed, 0xf6, 0xfb, 0x7d, 0xbe, 0xdf, 0x6f, 0x37, 0x1b, 0x0d, 0x86, 0xc3, 0x61, 0xb0, 0x58, 0x2c, 0x16, 0x8b, 0x45, 0xa2, 0xd1, 0xe8, 0x74, 0x3a, 0x9d, 0xce, 0xe7, 0x73, 0x39}; +static void it8661f_reset(void *priv); + +void it8661_fdc(uint16_t addr, uint8_t val, it8661f_t *dev) +{ + fdc_remove(dev->fdc_controller); + + if (((addr == 0x30) && (val & 1)) || (dev->device_regs[0][0x30] & 1)) + { + switch (addr) + { + case 0x30: + dev->device_regs[0][addr] = val & 1; + break; + + case 0x31: + dev->device_regs[0][addr] = val & 3; + if (val & 1) + dev->device_regs[0][addr] |= 0x55; + break; + + case 0x60: + case 0x61: + dev->device_regs[0][addr] = val & ((addr == 0x61) ? 0xff : 0xf8); + break; + + case 0x70: + dev->device_regs[0][addr] = val & 0x0f; + break; + + case 0x74: + dev->device_regs[0][addr] = val & 7; + break; + + case 0xf0: + dev->device_regs[0][addr] = val & 0x0f; + break; + } + fdc_set_base(dev->fdc_controller, (dev->device_regs[0][0x60] << 8) | (dev->device_regs[0][0x61])); + fdc_set_irq(dev->fdc_controller, dev->device_regs[0][0x70] & 0x0f); + fdc_set_dma_ch(dev->fdc_controller, dev->device_regs[0][0x74] & 7); + + if (dev->device_regs[0][0xf0] & 1) + fdc_writeprotect(dev->fdc_controller); + + // if (dev->device_regs[0][0xf0] & 4) + // fdc_swap(dev->fdc_controller); + pclog("ITE 8661-FDC: BASE %04x IRQ %02x\n", (dev->device_regs[0][0x60] << 8) | (dev->device_regs[0][0x61]), dev->device_regs[0][0x70] & 0x0f); + } +} + +void it8661_serial(int uart, uint16_t addr, uint8_t val, it8661f_t *dev) +{ + serial_remove(dev->uart[uart]); + if (((addr == 0x30) && (val & 1)) || (dev->device_regs[1 + uart][0x30] & 1)) + { + switch (addr) + { + case 0x30: + dev->device_regs[1 + uart][addr] = val & 1; + break; + + case 0x60: + case 0x61: + dev->device_regs[1 + uart][addr] = val & ((addr == 0x61) ? 0xff : 0xf8); + break; + + case 0x70: + dev->device_regs[1 + uart][addr] = val & 0x0f; + break; + + case 0x74: + dev->device_regs[1 + uart][addr] = val & 7; + break; + + case 0xf0: + dev->device_regs[1 + uart][addr] = val & 3; + break; + } + serial_setup(dev->uart[uart], (dev->device_regs[1 + uart][0x60] << 8) | (dev->device_regs[1 + uart][0x61]), dev->device_regs[1 + uart][0x70] & 0x0f); + pclog("ITE 8661-UART%01x: BASE %04x IRQ %02x\n", 1 + (LDN % 1), (dev->device_regs[1 + uart][0x60] << 8) | (dev->device_regs[1 + uart][0x61]), dev->device_regs[1 + uart][0x70] & 0x0f); + } +} + +void it8661_lpt(uint16_t addr, uint8_t val, it8661f_t *dev) +{ + lpt1_remove(); + if (((addr == 0x30) && (val & 1)) || (dev->device_regs[3][0x30] & 1)) + { + switch (addr) + { + case 0x30: + dev->device_regs[3][addr] = val & 1; + break; + + case 0x60: + case 0x61: + dev->device_regs[3][addr] = val & ((addr == 0x61) ? 0xff : 0xf8); + break; + + case 0x70: + dev->device_regs[3][addr] = val & 0x0f; + break; + + case 0x74: + dev->device_regs[3][addr] = val & 7; + break; + + case 0xf0: + dev->device_regs[3][addr] = val & 3; + break; + } + lpt1_init((dev->device_regs[3][0x60] << 8) | (dev->device_regs[3][0x61])); + lpt1_irq(dev->device_regs[3][0x70] & 0x0f); + pclog("ITE 8661-LPT: BASE %04x IRQ %02x\n", (dev->device_regs[3][0x60] << 8) | (dev->device_regs[3][0x61]), dev->device_regs[3][0x70] & 0x0f); + } +} + +void it8661_ldn(uint16_t addr, uint8_t val, it8661f_t *dev) +{ + switch (LDN) + { + case 0: + it8661_fdc(addr, val, dev); + break; + case 1: + case 2: + it8661_serial(LDN & 2, addr, val, dev); + break; + case 3: + it8661_lpt(addr, val, dev); + break; + } +} + +static void +it8661f_write(uint16_t addr, uint8_t val, void *priv) +{ + it8661f_t *dev = (it8661f_t *)priv; + + switch (addr) + { + case 0x370: + if (!dev->unlocked) + { + (val == mb_pnp_key[dev->enumerator]) ? dev->enumerator++ : (dev->enumerator = 0); + if (dev->enumerator == 31) + { + dev->unlocked = 1; + pclog("ITE8661F: Unlocked!\n"); + } + } + else + dev->index = val; + break; + + case 0x371: + if (dev->unlocked) + { + switch (dev->index) + { + case 0x02: + dev->regs[dev->index] = val; + if (val & 1) + it8661f_reset(dev); + if (val & 2) + dev->unlocked = 0; + break; + case 0x07: + dev->regs[dev->index] = val; + break; + case 0x22: + dev->regs[dev->index] = val & 0x30; + break; + case 0x23: + dev->regs[dev->index] = val & 0x1f; + break; + default: + it8661_ldn(dev->index, val, dev); + break; + } + } + break; + } + + return; +} + +static uint8_t +it8661f_read(uint16_t addr, void *priv) +{ + it8661f_t *dev = (it8661f_t *)priv; + + pclog("IT8661F:\n", addr, dev->regs[dev->index]); + return (addr == 0xa79) ? dev->regs[dev->index] : 0xff; +} + +static void +it8661f_reset(void *priv) +{ + it8661f_t *dev = (it8661f_t *)priv; + dev->regs[0x20] = 0x86; + dev->regs[0x21] = 0x61; + + dev->device_regs[0][0x60] = 3; + dev->device_regs[0][0x61] = 0xf0; + dev->device_regs[0][0x70] = 6; + dev->device_regs[0][0x71] = 2; + dev->device_regs[0][0x74] = 2; + + dev->device_regs[1][0x60] = 3; + dev->device_regs[1][0x61] = 0xf8; + dev->device_regs[1][0x70] = 4; + dev->device_regs[1][0x71] = 2; + + dev->device_regs[2][0x60] = 2; + dev->device_regs[2][0x61] = 0xf8; + dev->device_regs[2][0x70] = 3; + dev->device_regs[2][0x71] = 2; + + dev->device_regs[3][0x60] = 3; + dev->device_regs[3][0x61] = 0x78; + dev->device_regs[3][0x70] = 7; + dev->device_regs[3][0x71] = 2; + dev->device_regs[3][0x74] = 3; + dev->device_regs[3][0xf0] = 3; +} + +static void +it8661f_close(void *priv) +{ + it8661f_t *dev = (it8661f_t *)priv; + + free(dev); +} + +static void * +it8661f_init(const device_t *info) +{ + it8661f_t *dev = (it8661f_t *)malloc(sizeof(it8661f_t)); + memset(dev, 0, sizeof(it8661f_t)); + + dev->fdc_controller = device_add(&fdc_at_smc_device); + fdc_reset(dev->fdc_controller); + + dev->uart[0] = device_add_inst(&ns16550_device, 1); + dev->uart[1] = device_add_inst(&ns16550_device, 2); + + io_sethandler(0x0370, 0x0002, it8661f_read, NULL, NULL, it8661f_write, NULL, NULL, dev); + + dev->enumerator = 0; + dev->unlocked = 0; + + it8661f_reset(dev); + return dev; +} + +const device_t it8661f_device = { + "ITE IT8661F", + 0, + 0, + it8661f_init, + it8661f_close, + NULL, + {NULL}, + NULL, + NULL, + NULL}; diff --git a/src/win/CMakeLists.txt b/src/win/CMakeLists.txt index 3fcf28d1a..cdb52aaae 100644 --- a/src/win/CMakeLists.txt +++ b/src/win/CMakeLists.txt @@ -30,6 +30,9 @@ if(MSVC) target_sources(86Box PRIVATE 86Box.manifest) target_sources(plat PRIVATE win_opendir.c) + + # Append null to resource strings (fixes file dialogs) + set_property(SOURCE 86Box.rc PROPERTY COMPILE_FLAGS -n) endif() if(DINPUT) diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 7270b1ca1..04b35caaa 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -632,7 +632,7 @@ CHIPSETOBJ := acc2168.o cs8230.o ali1217.o ali1429.o ali1489.o headland.o intel_ intel_420ex.o intel_4x0.o intel_sio.o intel_piix.o ioapic.o \ neat.o opti495.o opti822.o opti895.o opti5x7.o scamp.o scat.o via_vt82c49x.o via_vt82c505.o \ gc100.o olivetti_eva.o \ - sis_85c310.o sis_85c4xx.o sis_85c496.o sis_85c50x.o stpc.o opti283.o opti291.o \ + sis_85c310.o sis_85c4xx.o sis_85c496.o sis_85c50x.o sis_5598.o stpc.o opti283.o opti291.o \ umc_8886.o umc_8890.o umc_hb4.o \ via_apollo.o via_pipc.o wd76c10.o vl82c480.o @@ -668,6 +668,7 @@ DEVOBJ := bugger.o hwm.o hwm_lm75.o hwm_lm78.o hwm_gl518sm.o hwm_vt82c686.o ibm SIOOBJ := sio_acc3221.o \ sio_f82c710.o sio_82091aa.o \ sio_fdc37c661.o sio_fdc37c66x.o sio_fdc37c669.o sio_fdc37c93x.o sio_fdc37m60x.o \ + sio_it8661f.o \ sio_pc87306.o sio_pc87307.o sio_pc87309.o sio_pc87310.o sio_pc87311.o sio_pc87332.o \ sio_prime3b.o sio_prime3c.o \ sio_w83787f.o \ diff --git a/src/win/win_opendir.c b/src/win/win_opendir.c index d7755e372..5339f0713 100644 --- a/src/win/win_opendir.c +++ b/src/win/win_opendir.c @@ -17,8 +17,6 @@ * Copyright 1998-2007 MicroWalt Corporation * Copyright 2017 Fred N. van Kempen */ -#define UNICODE -#include #include #include #include @@ -158,10 +156,11 @@ readdir(DIR *p) default: /* regular entry. */ #ifdef UNICODE wcsncpy(p->dent.d_name, ffp->name, MAXNAMLEN+1); + p->dent.d_reclen = (char)wcslen(p->dent.d_name); #else strncpy(p->dent.d_name, ffp->name, MAXNAMLEN+1); + p->dent.d_reclen = (char)strlen(p->dent.d_name); #endif - p->dent.d_reclen = (char) wcslen(p->dent.d_name); } /* Read next entry. */ diff --git a/src/win/win_settings.c b/src/win/win_settings.c index 57fce16ba..067f7c9f9 100644 --- a/src/win/win_settings.c +++ b/src/win/win_settings.c @@ -5060,7 +5060,7 @@ static BOOL win_settings_categories_init_columns(HWND hdlg) { LVCOLUMN lvc; - int iCol; + int iCol = 0; HWND hwndList = GetDlgItem(hdlg, IDC_SETTINGSCATLIST); lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;