diff --git a/src/acpi.c b/src/acpi.c index cf81b83b4..27d5726b3 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -480,7 +480,7 @@ acpi_reg_read_via(int size, uint16_t addr, void *p) case 0x42: /* GPIO port Output Value */ if (size == 1) - ret = dev->regs.gpio_val & 0xff; + ret = (dev->regs.gpio_val & 0x2f) | 0x10; break; case 0x44: /* GPIO port Input Value */ @@ -529,6 +529,11 @@ acpi_reg_read_via_596b(int size, uint16_t addr, void *p) shift32 = (addr & 3) << 3; switch (addr) { + case 0x42: + /* GPIO port Output Value */ + if (size == 1) + ret = (dev->regs.gpio_val & 0x2f) | 0x10; + break; case 0x44: case 0x45: /* External SMI Input Value */ ret = (dev->regs.extsmi_val >> shift16) & 0xff; @@ -539,7 +544,7 @@ acpi_reg_read_via_596b(int size, uint16_t addr, void *p) break; case 0x4c: case 0x4d: case 0x4e: case 0x4f: /* GPO Port Output Value */ - ret = (dev->regs.gpi_val >> shift32) & 0xff; + ret = (dev->regs.gpo_val >> shift32) & 0xff; break; default: ret = acpi_reg_read_via_common(size, addr, p); @@ -1032,7 +1037,7 @@ acpi_reg_write_via(int size, uint16_t addr, uint8_t val, void *p) case 0x42: /* GPIO port Output Value */ if (size == 1) { - dev->regs.gpio_val = val & 0x1f; + dev->regs.gpio_val = val & 0x2f; acpi_i2c_set(dev); } break; @@ -1058,6 +1063,13 @@ acpi_reg_write_via_596b(int size, uint16_t addr, uint8_t val, void *p) shift32 = (addr & 3) << 3; switch (addr) { + case 0x42: + /* GPIO port Output Value */ + if (size == 1) { + dev->regs.gpio_val = val & 0x2f; + acpi_i2c_set(dev); + } + break; case 0x4c: case 0x4d: case 0x4e: case 0x4f: /* GPO Port Output Value */ dev->regs.gpo_val = ((dev->regs.gpo_val & ~(0xff << shift32)) | (val << shift32)) & 0x7fffffff; @@ -1569,6 +1581,10 @@ acpi_reset(void *priv) dev->regs.gpi_val = 0xffff7fc1; if (!strcmp(machines[machine].internal_name, "ficva503a")) dev->regs.gpi_val |= 0x00000004; + if (!strcmp(machines[machine].internal_name, "6via90ap")) + dev->regs.gpi_val |= 0x00000004; + dev->regs.gpi_val = 0xffffffe5; + // dev->regs.gpi_val = 0x00000004; } /* Power on always generates a resume event. */ diff --git a/src/chipset/via_apollo.c b/src/chipset/via_apollo.c index 22de563c8..e2adf3657 100644 --- a/src/chipset/via_apollo.c +++ b/src/chipset/via_apollo.c @@ -341,37 +341,36 @@ via_apollo_host_bridge_write(int func, int addr, uint8_t val, void *priv) break; case 0x61: /* Shadow RAM Control 1 */ - if ((dev->pci_conf[0x61] ^ val) & 0x03) - apollo_map(0xc0000, 0x04000, val & 0x03); - if ((dev->pci_conf[0x61] ^ val) & 0x0c) - apollo_map(0xc4000, 0x04000, (val & 0x0c) >> 2); - if ((dev->pci_conf[0x61] ^ val) & 0x30) - apollo_map(0xc8000, 0x04000, (val & 0x30) >> 4); - if ((dev->pci_conf[0x61] ^ val) & 0xc0) - apollo_map(0xcc000, 0x04000, (val & 0xc0) >> 6); + apollo_map(0xc0000, 0x04000, val & 0x03); + apollo_map(0xc4000, 0x04000, (val & 0x0c) >> 2); + apollo_map(0xc8000, 0x04000, (val & 0x30) >> 4); + apollo_map(0xcc000, 0x04000, (val & 0xc0) >> 6); + dev->pci_conf[0x61] = val; break; case 0x62: /* Shadow RAM Control 2 */ - if ((dev->pci_conf[0x62] ^ val) & 0x03) - apollo_map(0xd0000, 0x04000, val & 0x03); - if ((dev->pci_conf[0x62] ^ val) & 0x0c) - apollo_map(0xd4000, 0x04000, (val & 0x0c) >> 2); - if ((dev->pci_conf[0x62] ^ val) & 0x30) - apollo_map(0xd8000, 0x04000, (val & 0x30) >> 4); - if ((dev->pci_conf[0x62] ^ val) & 0xc0) - apollo_map(0xdc000, 0x04000, (val & 0xc0) >> 6); + apollo_map(0xd0000, 0x04000, val & 0x03); + apollo_map(0xd4000, 0x04000, (val & 0x0c) >> 2); + apollo_map(0xd8000, 0x04000, (val & 0x30) >> 4); + apollo_map(0xdc000, 0x04000, (val & 0xc0) >> 6); + dev->pci_conf[0x62] = val; break; case 0x63: /* Shadow RAM Control 3 */ - if ((dev->pci_conf[0x63] ^ val) & 0x30) { - apollo_map(0xf0000, 0x10000, (val & 0x30) >> 4); - shadowbios = (((val & 0x30) >> 4) & 0x02); - } - if ((dev->pci_conf[0x63] ^ val) & 0xc0) - apollo_map(0xe0000, 0x10000, (val & 0xc0) >> 6); + shadowbios = 0; + shadowbios_write = 0; + + apollo_map(0xf0000, 0x10000, (val & 0x30) >> 4); + shadowbios = (((val & 0x30) >> 4) & 0x02); + shadowbios_write = (((val & 0x30) >> 4) & 0x01); + + apollo_map(0xe0000, 0x10000, (val & 0xc0) >> 6); + shadowbios |= (((val & 0xc0) >> 6) & 0x02); + shadowbios_write |= (((val & 0xc0) >> 6) & 0x01); + dev->pci_conf[0x63] = val; smram_disable_all(); - if (dev->id >= VIA_691) switch (val & 0x03) { + if (dev->id >= VIA_691) switch (val & 0x03) { case 0x00: default: apollo_smram_map(dev, 1, 0x000a0000, 0x00020000, 1); /* SMM: Code DRAM, Data DRAM */ @@ -680,7 +679,8 @@ via_apollo_init(const device_t *info) memset(dev, 0, sizeof(via_apollo_t)); dev->smram = smram_add(); - apollo_smram_map(dev, 1, 0x000a0000, 0x00020000, 1); /* SMM: Code DRAM, Data DRAM */ + if (dev->id != VIA_8601) + apollo_smram_map(dev, 1, 0x000a0000, 0x00020000, 1); /* SMM: Code DRAM, Data DRAM */ pci_add_card(PCI_ADD_NORTHBRIDGE, via_apollo_read, via_apollo_write, dev); diff --git a/src/chipset/via_pipc.c b/src/chipset/via_pipc.c index 46d2f8597..0cfcc1db3 100644 --- a/src/chipset/via_pipc.c +++ b/src/chipset/via_pipc.c @@ -359,6 +359,9 @@ pipc_reset_hard(void *priv) ide_pri_disable(); ide_sec_disable(); + + nvr_via_wp_set(0x00, 0x32, dev->nvr); + nvr_via_wp_set(0x00, 0x0d, dev->nvr); } @@ -502,7 +505,7 @@ nvr_update_io_mapping(pipc_t *dev) if (dev->nvr_enabled) nvr_at_handler(0, 0x0074, dev->nvr); - if ((dev->pci_isa_regs[0x5b] & 0x02) && (dev->pci_isa_regs[0x48] & 0x08)) + if ((dev->pci_isa_regs[0x5b] & 0x02) || (dev->pci_isa_regs[0x48] & 0x08)) nvr_at_handler(1, 0x0074, dev->nvr); } @@ -682,6 +685,8 @@ pipc_write(int func, int addr, uint8_t val, void *priv) case 0x77: if (val & 0x10) pclog("PIPC: Warning: Internal I/O APIC enabled.\n"); + nvr_via_wp_set(!!(val & 0x04), 0x32, dev->nvr); + nvr_via_wp_set(!!(val & 0x02), 0x0d, dev->nvr); break; case 0x80: case 0x86: case 0x87: @@ -1013,6 +1018,8 @@ pipc_reset(void *p) pipc_write(1, 0x40, 0x04, p); else pipc_write(1, 0x40, 0x00, p); + + pipc_write(0, 0x77, 0x00, p); } diff --git a/src/include/86box/nvr.h b/src/include/86box/nvr.h index 3df78de6e..ceb1bc459 100644 --- a/src/include/86box/nvr.h +++ b/src/include/86box/nvr.h @@ -118,6 +118,7 @@ extern void nvr_at_handler(int set, uint16_t base, nvr_t *nvr); extern void nvr_at_sec_handler(int set, uint16_t base, nvr_t *nvr); extern void nvr_read_addr_set(int set, nvr_t *nvr); extern void nvr_wp_set(int set, int h, nvr_t *nvr); +extern void nvr_via_wp_set(int set, int reg, nvr_t *nvr); extern void nvr_bank_set(int base, uint8_t bank, nvr_t *nvr); extern void nvr_lock_set(int base, int size, int lock, nvr_t *nvr); diff --git a/src/mem/sst_flash.c b/src/mem/sst_flash.c index 8318c3a0f..1a0bb0550 100644 --- a/src/mem/sst_flash.c +++ b/src/mem/sst_flash.c @@ -175,13 +175,14 @@ static uint8_t sst_read_id(uint32_t addr, void *p) { sst_t *dev = (sst_t *) p; + uint8_t ret = 0xff; if ((addr & 0xffff) == 0) - return SST_ID_MANUFACTURER; /* SST */ + ret = SST_ID_MANUFACTURER; /* SST */ else if ((addr & 0xffff) == 1) - return dev->id; - else - return 0xff; + ret = dev->id; + + return ret; } @@ -237,7 +238,10 @@ sst_write(uint32_t addr, uint8_t val, void *p) case 2: case 5: /* 3rd and 6th Bus Write Cycle */ - if ((addr & 0x7fff) == 0x5555) + if ((dev->command_state == 5) && (val == SST_SECTOR_ERASE)) { + /* Sector erase - can be on any address. */ + sst_new_command(dev, addr, val); + } else if ((addr & 0x7fff) == 0x5555) sst_new_command(dev, addr, val); else dev->command_state = 0; diff --git a/src/nvr_at.c b/src/nvr_at.c index 419da7c79..a2c362905 100644 --- a/src/nvr_at.c +++ b/src/nvr_at.c @@ -299,7 +299,9 @@ typedef struct { int8_t stat; uint8_t cent, def, - flags, read_addr; + flags, read_addr, + wp_0d, wp_32, + pad, pad0; uint8_t addr[8], wp[2], bank[8], *lock; @@ -587,6 +589,7 @@ nvr_reg_write(uint16_t reg, uint8_t val, void *priv) break; case RTC_REGD: /* R/O */ +#if 0 /* 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. */ @@ -595,6 +598,10 @@ nvr_reg_write(uint16_t reg, uint8_t val, void *priv) if (val & 0x80) nvr->regs[RTC_REGD] |= 0x80; } +#else + if ((local->cent == RTC_CENTURY_VIA) && !local->wp_0d) + nvr->regs[RTC_REGD] = val/* & 0x80*/; +#endif break; case 0x2e: @@ -609,6 +616,11 @@ nvr_reg_write(uint16_t reg, uint8_t val, void *priv) } /*FALLTHROUGH*/ + case 0x32: + if ((local->cent == RTC_CENTURY_VIA) && local->wp_32) + break; + /* FALLTHROUGH */ + default: /* non-RTC registers are just NVRAM */ if ((reg == 0x2c) && (local->flags & FLAG_LS_HACK)) nvr->new = 0; @@ -686,9 +698,8 @@ nvr_read(uint16_t addr, void *priv) cycles -= ISA_CYCLES(8); if (local->bank[addr_id] == 0xff) - return 0xff; - - if (addr & 1) switch(local->addr[addr_id]) { + ret = 0xff; + else if (addr & 1) switch(local->addr[addr_id]) { case RTC_REGA: ret = (nvr->regs[RTC_REGA] & 0x7f) | local->stat; break; @@ -700,8 +711,14 @@ nvr_read(uint16_t addr, void *priv) break; case RTC_REGD: - nvr->regs[RTC_REGD] |= REGD_VRT; - ret = nvr->regs[RTC_REGD]; + /* On VIA VT82C596B onwards, bits 6-0 of this register always read 0. */ + if (local->cent == RTC_CENTURY_VIA) + ret = 0x80; + // ret = nvr->regs[RTC_REGD]/* & 0x80*/; + else { + nvr->regs[RTC_REGD] |= REGD_VRT; + ret = nvr->regs[RTC_REGD]; + } break; case 0x2c: @@ -886,6 +903,18 @@ nvr_wp_set(int set, int h, nvr_t *nvr) } +void +nvr_via_wp_set(int set, int reg, nvr_t *nvr) +{ + local_t *local = (local_t *) nvr->data; + + if (reg == 0x0d) + local->wp_0d = set; + else + local->wp_32 = set; +} + + void nvr_bank_set(int base, uint8_t bank, nvr_t *nvr) {