diff --git a/src/chipset/acer_m3a.c b/src/chipset/acer_m3a.c
deleted file mode 100644
index fc7717a11..000000000
--- a/src/chipset/acer_m3a.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * 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 Acer M3A and V35N ports EAh and EBh.
- *
- *
- *
- * Authors: Sarah Walker,
- * Miran Grca,
- *
- * Copyright 2019 Miran Grca.
- */
-#include
-#include
-#include
-#include
-#include
-#include <86box/86box.h>
-#include <86box/mem.h>
-#include <86box/io.h>
-#include <86box/rom.h>
-#include <86box/pci.h>
-#include <86box/device.h>
-#include <86box/keyboard.h>
-#include <86box/chipset.h>
-
-
-typedef struct
-{
- int index;
-} acerm3a_t;
-
-
-static void
-acerm3a_out(uint16_t port, uint8_t val, void *p)
-{
- acerm3a_t *dev = (acerm3a_t *) p;
-
- if (port == 0xea)
- dev->index = val;
-}
-
-
-static uint8_t
-acerm3a_in(uint16_t port, void *p)
-{
- acerm3a_t *dev = (acerm3a_t *) p;
-
- if (port == 0xeb) {
- switch (dev->index) {
- case 2:
- return 0xfd;
- }
- }
- return 0xff;
-}
-
-
-static void
-acerm3a_close(void *p)
-{
- acerm3a_t *dev = (acerm3a_t *)p;
-
- free(dev);
-}
-
-
-static void
-*acerm3a_init(const device_t *info)
-{
- acerm3a_t *acerm3a = (acerm3a_t *) malloc(sizeof(acerm3a_t));
- memset(acerm3a, 0, sizeof(acerm3a_t));
-
- io_sethandler(0x00ea, 0x0002, acerm3a_in, NULL, NULL, acerm3a_out, NULL, NULL, acerm3a);
-
- return acerm3a;
-}
-
-
-const device_t acerm3a_device =
-{
- "Acer M3A Register",
- 0,
- 0,
- acerm3a_init,
- acerm3a_close,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL
-};
diff --git a/src/chipset/intel_4x0.c b/src/chipset/intel_4x0.c
index 5c4f5662f..7d5c6f43c 100644
--- a/src/chipset/intel_4x0.c
+++ b/src/chipset/intel_4x0.c
@@ -512,6 +512,11 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
break;
case 0x55:
switch (dev->type) {
+ case INTEL_420TX: case INTEL_420ZX:
+ /* According to the FreeBSD 3.x source code, the 420TX/ZX chipset has
+ this register. The mask is unknown, so write all bits. */
+ regs[0x55] = val;
+ break;
case INTEL_430VX: case INTEL_430TX:
regs[0x55] = val & 0x01;
break;
@@ -523,6 +528,11 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
break;
case 0x56:
switch (dev->type) {
+ case INTEL_420TX: case INTEL_420ZX:
+ /* According to the FreeBSD 3.x source code, the 420TX/ZX chipset has
+ this register. The mask is unknown, so write all bits. */
+ regs[0x56] = val;
+ break;
case INTEL_430HX:
regs[0x56] = val & 0x1f;
break;
@@ -1321,24 +1331,28 @@ static void
regs[0x06] = 0x40;
regs[0x08] = (dev->type == INTEL_420ZX) ? 0x01 : 0x00;
regs[0x0d] = 0x20;
+ /* According to information from FreeBSD 3.x source code:
+ 0x00 = 486DX, 0x20 = 486SX, 0x40 = 486DX2 or 486DX4, 0x80 = Pentium OverDrive. */
if (is486sx)
regs[0x50] = 0x20;
else if (is486sx2)
regs[0x50] = 0x60; /* Guess based on the SX, DX, and DX2 values. */
- else if (is486dx || isdx4)
+ else if (is486dx)
regs[0x50] = 0x00;
- else if (is486dx2)
+ else if (is486dx2 || isdx4)
regs[0x50] = 0x40;
else
regs[0x50] = 0x80; /* Pentium OverDrive. */
- if (cpu_busspeed <= 25000000)
+ /* According to information from FreeBSD 3.x source code:
+ 00 = 25 MHz, 01 = 33 MHz. */
+ if (cpu_busspeed > 25000000)
regs[0x50] |= 0x01;
- else if ((cpu_busspeed > 25000000) && (cpu_busspeed <= 30000000))
- regs[0x50] |= 0x02;
- else if ((cpu_busspeed > 30000000) && (cpu_busspeed <= 33333333))
- regs[0x50] |= 0x03;
regs[0x51] = 0x80;
- regs[0x52] = 0xea; /* 512 kB burst cache, set to 0xaa for 256 kB */
+ /* According to information from FreeBSD 3.x source code:
+ 0x00 = None, 0x01 = 64 kB, 0x41 = 128 kB, 0x81 = 256 kB, 0xc1 = 512 kB,
+ If bit 0 is set, then if bit 2 is also set, the cache is write back,
+ otherwise it's write through. */
+ regs[0x52] = 0xc3; /* 512 kB writeback cache */
regs[0x57] = 0x31;
regs[0x59] = 0x0f;
regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = 0x02;
diff --git a/src/chipset/sis_85c496.c b/src/chipset/sis_85c496.c
index 7fafa9607..978f5d29e 100644
--- a/src/chipset/sis_85c496.c
+++ b/src/chipset/sis_85c496.c
@@ -10,17 +10,17 @@
*
*
*
- * Authors: Sarah Walker,
- * Miran Grca,
+ * Authors: Miran Grca,
*
- * Copyright 2008-2019 Sarah Walker.
- * Copyright 2019 Miran Grca.
+ * Copyright 2019,2020 Miran Grca.
*/
+#include
#include
#include
#include
#include
#include
+#define HAVE_STDARG_H
#include <86box/86box.h>
#include "cpu.h"
#include <86box/mem.h>
@@ -30,54 +30,93 @@
#include <86box/device.h>
#include <86box/keyboard.h>
#include <86box/timer.h>
+#include <86box/dma.h>
+#include <86box/nvr.h>
+#include <86box/pic.h>
#include <86box/port_92.h>
#include <86box/hdc_ide.h>
#include <86box/machine.h>
#include <86box/chipset.h>
+#include <86box/spd.h>
typedef struct sis_85c496_t
{
- uint8_t cur_reg,
+ uint8_t cur_reg, rmsmiblk_count,
regs[127],
pci_conf[256];
+ pc_timer_t rmsmiblk_timer;
port_92_t * port_92;
+ nvr_t * nvr;
} sis_85c496_t;
+#ifdef ENABLE_SIS_85C496_LOG
+int sis_85c496_do_log = ENABLE_SIS_85C496_LOG;
+
+
+void
+sis_85c496_log(const char *fmt, ...)
+{
+ va_list ap;
+
+ if (sis_85c496_do_log) {
+ va_start(ap, fmt);
+ pclog_ex(fmt, ap);
+ va_end(ap);
+ }
+}
+#else
+#define sis_85c496_log(fmt, ...)
+#endif
+
+
static void
-sis_85c497_write(uint16_t port, uint8_t val, void *priv)
+sis_85c497_isa_write(uint16_t port, uint8_t val, void *priv)
{
sis_85c496_t *dev = (sis_85c496_t *) priv;
- uint8_t index = (port & 1) ? 0 : 1;
- if (index) {
- if ((val != 0x01) || ((val >= 0x70) && (val <= 0x76)))
- dev->cur_reg = val;
- } else {
- if (((dev->cur_reg < 0x70) && (dev->cur_reg != 0x01)) || (dev->cur_reg > 0x76))
- return;
- dev->regs[dev->cur_reg] = val;
- dev->cur_reg = 0;
+ sis_85c496_log("[%04X:%08X] ISA Write %02X to %04X\n", CS, cpu_state.pc, val, port);
+
+ if (port == 0x22)
+ dev->cur_reg = val;
+ else if (port == 0x23) switch (dev->cur_reg) {
+ case 0x01: /* Built-in 206 Timing Control */
+ dev->regs[dev->cur_reg] = val;
+ break;
+ case 0x70: /* ISA Bus Clock Selection */
+ dev->regs[dev->cur_reg] = val & 0xc0;
+ break;
+ case 0x71: /* ISA Bus Timing Control */
+ dev->regs[dev->cur_reg] = val & 0xf6;
+ break;
+ case 0x72: case 0x76: /* SMOUT */
+ case 0x74: /* BIOS Timer */
+ dev->regs[dev->cur_reg] = val;
+ break;
+ case 0x73: /* BIOS Timer */
+ dev->regs[dev->cur_reg] = val & 0xfd;
+ break;
+ case 0x75: /* DMA / Deturbo Control */
+ dev->regs[dev->cur_reg] = val & 0xfc;
+ dma_set_mask((val & 0x80) ? 0xffffffff : 0x00ffffff);
+ break;
}
}
static uint8_t
-sis_85c497_read(uint16_t port, void *priv)
+sis_85c497_isa_read(uint16_t port, void *priv)
{
sis_85c496_t *dev = (sis_85c496_t *) priv;
- uint8_t index = (port & 1) ? 0 : 1;
uint8_t ret = 0xff;
- if (index)
- ret = dev->cur_reg;
- else {
- if ((dev->cur_reg != 0x01) || ((dev->cur_reg >= 0x70) && (dev->cur_reg <= 0x76))) {
- ret = dev->regs[dev->cur_reg];
- dev->cur_reg = 0;
- }
- }
+ if (port == 0x23)
+ ret = dev->regs[dev->cur_reg];
+ else if (port == 0x33)
+ ret = 0x3c /*random_generate()*/;
+
+ sis_85c496_log("[%04X:%08X] ISA Read %02X from %04X\n", CS, cpu_state.pc, ret, port);
return ret;
}
@@ -100,170 +139,379 @@ sis_85c496_recalcmapping(sis_85c496_t *dev)
shadowbios_write |= (base >= 0xe0000) && !(dev->pci_conf[0x45] & 0x01);
shflags = (dev->pci_conf[0x45] & 0x02) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
shflags |= (dev->pci_conf[0x45] & 0x01) ? MEM_WRITE_EXTANY : MEM_WRITE_INTERNAL;
- mem_set_mem_state(base, 0x8000, shflags);
+ mem_set_mem_state_both(base, 0x8000, shflags);
} else
- mem_set_mem_state(base, 0x8000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
+ mem_set_mem_state_both(base, 0x8000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
}
+}
+
+static void
+sis_85c496_ide_handler(sis_85c496_t *dev)
+{
+ uint8_t ide_cfg[2];
+
+ ide_cfg[0] = dev->pci_conf[0x58];
+ ide_cfg[1] = dev->pci_conf[0x59];
+
+ ide_pri_disable();
+ ide_sec_disable();
+
+ if (ide_cfg[1] & 0x02) {
+ ide_set_base(0, 0x0170);
+ ide_set_side(0, 0x0376);
+ ide_set_base(1, 0x01f0);
+ ide_set_side(1, 0x03f6);
+
+ if (ide_cfg[1] & 0x01) {
+ if (!(ide_cfg[0] & 0x40))
+ ide_pri_enable();
+ if (!(ide_cfg[0] & 0x80))
+ ide_sec_enable();
+ }
+ } else {
+ ide_set_base(0, 0x01f0);
+ ide_set_side(0, 0x03f6);
+ ide_set_base(1, 0x0170);
+ ide_set_side(1, 0x0376);
+
+ if (ide_cfg[1] & 0x01) {
+ if (!(ide_cfg[0] & 0x40))
+ ide_sec_enable();
+ if (!(ide_cfg[0] & 0x80))
+ ide_pri_enable();
+ }
+ }
+}
+
+
+static void
+sis_85c496_smram_map(int smm, uint32_t addr, uint32_t size, int is_smram)
+{
+ mem_set_mem_state_smram(smm, addr, size, is_smram);
flushmmucache();
}
/* 00 - 3F = PCI Configuration, 40 - 7F = 85C496, 80 - FF = 85C497 */
static void
-sis_85c496_write(int func, int addr, uint8_t val, void *priv)
+sis_85c49x_pci_write(int func, int addr, uint8_t val, void *priv)
{
sis_85c496_t *dev = (sis_85c496_t *) priv;
- uint8_t old = dev->pci_conf[addr];
- uint8_t valxor;
+ uint8_t old, valxor;
+ uint8_t smm_irq[4] = { 10, 11, 12, 15 };
- if ((addr >= 4 && addr < 8) || addr >= 0x40)
- dev->pci_conf[addr] = val;
+ old = dev->pci_conf[addr];
+ valxor = (dev->pci_conf[addr]) ^ val;
- valxor = old ^ val;
+ sis_85c496_log("[%04X:%08X] PCI Write %02X to %02X:%02X\n", CS, cpu_state.pc, val, func, addr);
switch (addr) {
- case 0x42: /*Cache configure*/
+ /* PCI Configuration Header Registers (00h ~ 3Fh) */
+ case 0x04: /* PCI Device Command */
+ dev->pci_conf[addr] = val & 0x40;
+ break;
+ case 0x05: /* PCI Device Command */
+ dev->pci_conf[addr] = val & 0x03;
+ break;
+ case 0x07: /* Device Status */
+ dev->pci_conf[addr] &= ~(val & 0xf1);
+ break;
+
+ /* 86C496 Specific Registers (40h ~ 7Fh) */
+ case 0x40: /* CPU Configuration */
+ dev->pci_conf[addr] = val & 0x7f;
+ break;
+ case 0x41: /* DRAM Configuration */
+ dev->pci_conf[addr] = val;
+ break;
+ case 0x42: /* Cache Configure */
+ dev->pci_conf[addr] = val;
cpu_cache_ext_enabled = (val & 0x01);
cpu_update_waitstates();
break;
-
- case 0x44: /*Shadow configure*/
- if (valxor & 0xff)
- sis_85c496_recalcmapping(dev);
+ case 0x43: /* Cache Configure */
+ dev->pci_conf[addr] = val & 0x8f;
break;
- case 0x45: /*Shadow configure*/
- if (valxor & 0x03)
+ case 0x44: /* Shadow Configure */
+ dev->pci_conf[addr] = val;
+ if (valxor & 0xff) {
sis_85c496_recalcmapping(dev);
+ if (((old & 0xf0) == 0xf0) && ((val & 0xf0) == 0x30))
+ flushmmucache_nopc();
+ else
+ flushmmucache();
+ }
break;
-
- case 0x56:
+ case 0x45: /* Shadow Configure */
+ dev->pci_conf[addr] = val & 0x0f;
+ if (valxor & 0x03) {
+ sis_85c496_recalcmapping(dev);
+ flushmmucache();
+ }
+ break;
+ case 0x46: /* Cacheable Control */
+ dev->pci_conf[addr] = val;
+ break;
+ case 0x47: /* 85C496 Address Decoder */
+ dev->pci_conf[addr] = val & 0x1f;
+ break;
+ case 0x48: case 0x49: case 0x4a: case 0x4b: /* DRAM Boundary */
+ case 0x4c: case 0x4d: case 0x4e: case 0x4f:
+ // dev->pci_conf[addr] = val;
+ spd_write_drbs(dev->pci_conf, 0x40, 0x4f, 1);
+ break;
+ case 0x50: case 0x51: /* Exclusive Area 0 Setup */
+ dev->pci_conf[addr] = val;
+ break;
+ case 0x52: case 0x53: /* Exclusive Area 1 Setup */
+ dev->pci_conf[addr] = val;
+ break;
+ case 0x54: /* Exclusive Area 2 Setup */
+ dev->pci_conf[addr] = val;
+ break;
+ case 0x55: /* Exclusive Area 3 Setup */
+ dev->pci_conf[addr] = val & 0xf0;
+ break;
+ case 0x56: /* PCI / Keyboard Configure */
+ dev->pci_conf[addr] = val;
if (valxor & 0x02) {
port_92_remove(dev->port_92);
if (val & 0x02)
port_92_add(dev->port_92);
}
break;
+ case 0x57: /* Output Pin Configuration */
+ dev->pci_conf[addr] = val;
+ break;
+ case 0x58: /* Build-in IDE Controller / VESA Bus Configuration */
+ dev->pci_conf[addr] = val & 0xd7;
+ if (valxor & 0xc0)
+ sis_85c496_ide_handler(dev);
+ break;
+ case 0x59: /* Build-in IDE Controller / VESA Bus Configuration */
+ dev->pci_conf[addr] = val;
+ if (valxor & 0x03)
+ sis_85c496_ide_handler(dev);
+ break;
+ case 0x5a: /* SMRAM Remapping Configuration */
+ dev->pci_conf[addr] = val & 0xbe;
+ if (valxor & 0x3e) {
+ unmask_a20_in_smm = !!(val & 0x20);
- case 0x59:
- if (valxor & 0x02) {
- if (val & 0x02) {
- ide_set_base(0, 0x0170);
- ide_set_side(0, 0x0376);
- ide_set_base(1, 0x01f0);
- ide_set_side(1, 0x03f6);
- } else {
- ide_set_base(0, 0x01f0);
- ide_set_side(0, 0x03f6);
- ide_set_base(1, 0x0170);
- ide_set_side(1, 0x0376);
+ if (smram[0].size != 0x00000000) {
+ sis_85c496_smram_map(0, smram[0].host_base, smram[0].size, 0);
+ sis_85c496_smram_map(1, smram[0].host_base, smram[0].size, 0);
+
+ memset(&smram[0], 0x00, sizeof(smram_t));
+ mem_mapping_disable(&ram_smram_mapping[0]);
+ }
+
+ if (val & 0x06) {
+ smram[0].size = 0x00010000;
+ switch ((val >> 3) & 0x03) {
+ case 0x00:
+ smram[0].host_base = 0x00060000;
+ smram[0].ram_base = 0x000a0000;
+ break;
+ case 0x01:
+ smram[0].host_base = 0x00060000;
+ smram[0].ram_base = 0x000b0000;
+ break;
+ case 0x02:
+ smram[0].host_base = 0x000e0000;
+ smram[0].ram_base = 0x000a0000;
+ break;
+ case 0x03:
+ smram[0].host_base = 0x000e0000;
+ smram[0].ram_base = 0x000b0000;
+ break;
+ }
+
+ mem_mapping_set_addr(&ram_smram_mapping[0], smram[0].host_base, 0x00010000);
+ mem_mapping_set_exec(&ram_smram_mapping[0], ram + smram[0].ram_base);
+
+ sis_85c496_smram_map(0, smram[0].host_base, smram[0].size, ((val & 0x06) == 0x06));
+ sis_85c496_smram_map(1, smram[0].host_base, smram[0].size, (val & 0x02));
}
}
break;
-
- case 0x58:
- if (valxor & 0x80) {
- if (dev->pci_conf[0x59] & 0x02) {
- ide_sec_disable();
- if (val & 0x80)
- ide_sec_enable();
- } else {
- ide_pri_disable();
- if (val & 0x80)
- ide_pri_enable();
- }
- }
- if (valxor & 0x40) {
- if (dev->pci_conf[0x59] & 0x02) {
- ide_pri_disable();
- if (val & 0x40)
- ide_pri_enable();
- } else {
- ide_sec_disable();
- if (val & 0x40)
- ide_sec_enable();
- }
- }
+ case 0x5b: /* Programmable I/O Traps Configure */
+ case 0x5c: case 0x5d: /* Programmable I/O Trap 0 Base */
+ case 0x5e: case 0x5f: /* Programmable I/O Trap 0 Base */
+ case 0x60: case 0x61: /* IDE Controller Channel 0 Configuration */
+ case 0x62: case 0x63: /* IDE Controller Channel 1 Configuration */
+ case 0x64: case 0x65: /* Exclusive Area 3 Setup */
+ case 0x66: /* EDO DRAM Configuration */
+ case 0x68: case 0x69: /* Asymmetry DRAM Configuration */
+ dev->pci_conf[addr] = val;
break;
-
- case 0x5a:
- if (valxor & 0x04) {
- if (val & 0x04)
- mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
- else
- mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
- }
- break;
-
- case 0x67:
+ case 0x67: /* Miscellaneous Control */
+ dev->pci_conf[addr] = val & 0xf9;
if (valxor & 0x60)
port_92_set_features(dev->port_92, !!(val & 0x20), !!(val & 0x40));
break;
- case 0x82:
- sis_85c497_write(0x22, val, priv);
+ /* 86C497 Specific Registers (80h ~ FFh) */
+ case 0x80: /* PMU Configuration */
+ case 0x85: /* STPCLK# Event Control */
+ case 0x86: case 0x87: /* STPCLK# Deassertion IRQ Selection */
+ case 0x89: /* Fast Timer Count */
+ case 0x8a: /* Generic Timer Count */
+ case 0x8b: /* Slow Timer Count */
+ case 0x8e: /* Clock Throttling On Timer Count */
+ case 0x8f: /* Clock Throttling Off Timer Count */
+ case 0x90: /* Clock Throttling On Timer Reload Condition */
+ case 0x92: /* Fast Timer Reload Condition */
+ case 0x94: /* Generic Timer Reload Condition */
+ case 0x96: /* Slow Timer Reload Condition */
+ case 0x98: case 0x99: /* Fast Timer Reload IRQ Selection */
+ case 0x9a: case 0x9b: /* Generic Timer Reload IRQ Selection */
+ case 0x9c: case 0x9d: /* Slow Timer Reload IRQ Selection */
+ case 0xa2: /* SMI Request Status Selection */
+ case 0xa4: case 0xa5: /* SMI Request IRQ Selection */
+ case 0xa6: case 0xa7: /* Clock Throttlign On Timer Reload IRQ Selection */
+ case 0xa8: /* GPIO Control */
+ case 0xaa: /* GPIO DeBounce Count */
+ case 0xd2: /* Exclusive Area 2 Base Address */
+ dev->pci_conf[addr] = val;
break;
-
- case 0xc0:
- if (val & 0x80)
- pci_set_irq_routing(PCI_INTA, val & 0xf);
- else
- pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED);
+ case 0x81: /* PMU CPU Type Configuration */
+ dev->pci_conf[addr] = val & 0x9f;
break;
- case 0xc1:
- if (val & 0x80)
- pci_set_irq_routing(PCI_INTB, val & 0xf);
- else
- pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED);
+ case 0x88: /* Timer Control */
+ dev->pci_conf[addr] = val & 0x3f;
break;
- case 0xc2:
- if (val & 0x80)
- pci_set_irq_routing(PCI_INTC, val & 0xf);
- else
- pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED);
+ case 0x8d: /* RMSMIBLK Timer Count */
+ dev->pci_conf[addr] = val;
+ dev->rmsmiblk_count = val;
+ timer_stop(&dev->rmsmiblk_timer);
+ if (val >= 0x02)
+ timer_on_auto(&dev->rmsmiblk_timer, 35.0);
break;
- case 0xc3:
+ case 0x91: /* Clock Throttling On Timer Reload Condition */
+ case 0x93: /* Fast Timer Reload Condition */
+ case 0x95: /* Generic Timer Reload Condition */
+ dev->pci_conf[addr] = val & 0x03;
+ break;
+ case 0x97: /* Slow Timer Reload Condition */
+ dev->pci_conf[addr] = val & 0xc3;
+ break;
+ case 0x9e: /* Soft-SMI Generation / RMSMIBLK Trigger */
+ if (!smi_block && (val & 0x01) && (dev->pci_conf[0x80] & 0x80) && (dev->pci_conf[0xa2] & 0x10)) {
+ if (dev->pci_conf[0x80] & 0x10)
+ picint(1 << smm_irq[dev->pci_conf[0x81] & 0x03]);
+ else
+ smi_line = 1;
+ smi_block = 1;
+ dev->pci_conf[0xa0] |= 0x10;
+ }
+ if (val & 0x02) {
+ timer_stop(&dev->rmsmiblk_timer);
+ if (dev->rmsmiblk_count >= 0x02)
+ timer_on_auto(&dev->rmsmiblk_timer, 35.0);
+ }
+ break;
+ case 0xa0: case 0xa1: /* SMI Request Status */
+ dev->pci_conf[addr] &= ~val;
+ break;
+ case 0xa3: /* SMI Request Status Selection */
+ dev->pci_conf[addr] = val & 0x7f;
+ break;
+ case 0xa9: /* GPIO SMI Request Status */
+ dev->pci_conf[addr] = ~(val & 0x03);
+ break;
+ case 0xc0: /* PCI INTA# -to-IRQ Link */
+ case 0xc1: /* PCI INTB# -to-IRQ Link */
+ case 0xc2: /* PCI INTC# -to-IRQ Link */
+ case 0xc3: /* PCI INTD# -to-IRQ Link */
+ dev->pci_conf[addr] = val & 0x8f;
if (val & 0x80)
- pci_set_irq_routing(PCI_INTD, val & 0xf);
+ pci_set_irq_routing(PCI_INTA + (addr & 0x03), val & 0xf);
else
- pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED);
+ pci_set_irq_routing(PCI_INTA + (addr & 0x03), PCI_IRQ_DISABLED);
+ break;
+ case 0xc6: /* 85C497 Post / INIT Configuration */
+ dev->pci_conf[addr] = val & 0x0f;
+ break;
+ case 0xc8: case 0xc9: case 0xca: case 0xcb: /* Mail Box */
+ dev->pci_conf[addr] = val;
+ break;
+ case 0xd0: /* ISA BIOS Configuration */
+ dev->pci_conf[addr] = val & 0xfb;
+ break;
+ case 0xd1: /* ISA Address Decoder */
+ if (dev->pci_conf[0xd0] & 0x01)
+ dev->pci_conf[addr] = val;
+ break;
+ case 0xd3: /* Exclusive Area 2 Base Address */
+ dev->pci_conf[addr] = val & 0xf0;
+ break;
+ case 0xd4: /* Miscellaneous Configuration */
+ dev->pci_conf[addr] = val & 0x6e;
+ nvr_bank_set(0, !!(val & 0x40), dev->nvr);
break;
}
}
static uint8_t
-sis_85c496_read(int func, int addr, void *priv)
+sis_85c49x_pci_read(int func, int addr, void *priv)
{
sis_85c496_t *dev = (sis_85c496_t *) priv;
uint8_t ret = dev->pci_conf[addr];
switch (addr) {
case 0x82: /*Port 22h Mirror*/
- ret = inb(0x22);
+ ret = dev->cur_reg;
break;
- case 0x70: /*Port 70h Mirror*/
+ case 0x83: /*Port 70h Mirror*/
ret = inb(0x70);
break;
}
+ sis_85c496_log("[%04X:%08X] PCI Read %02X from %02X:%02X\n", CS, cpu_state.pc, ret, func, addr);
+
return ret;
}
static void
-sis_85c497_reset(sis_85c496_t *dev)
+sis_85c496_rmsmiblk_count(void *priv)
+{
+ sis_85c496_t *dev = (sis_85c496_t *) priv;
+
+ dev->rmsmiblk_count--;
+
+ if (dev->rmsmiblk_count == 1) {
+ smi_block = 0;
+ dev->rmsmiblk_count = 0;
+ timer_stop(&dev->rmsmiblk_timer);
+ } else
+ timer_on_auto(&dev->rmsmiblk_timer, 35.0);
+}
+
+
+static void
+sis_85c497_isa_reset(sis_85c496_t *dev)
{
memset(dev->regs, 0, sizeof(dev->regs));
dev->regs[0x01] = 0xc0;
dev->regs[0x71] = 0x01;
dev->regs[0x72] = 0xff;
+ dev->regs[0x76] = 0xff;
+
+ dma_set_mask(0x00ffffff);
io_removehandler(0x0022, 0x0002,
- sis_85c497_read, NULL, NULL, sis_85c497_write, NULL, NULL, dev);
+ sis_85c497_isa_read, NULL, NULL, sis_85c497_isa_write, NULL, NULL, dev);
+ io_removehandler(0x0033, 0x0001,
+ sis_85c497_isa_read, NULL, NULL, sis_85c497_isa_write, NULL, NULL, dev);
io_sethandler(0x0022, 0x0002,
- sis_85c497_read, NULL, NULL, sis_85c497_write, NULL, NULL, dev);
+ sis_85c497_isa_read, NULL, NULL, sis_85c497_isa_write, NULL, NULL, dev);
+ io_sethandler(0x0033, 0x0001,
+ sis_85c497_isa_read, NULL, NULL, sis_85c497_isa_write, NULL, NULL, dev);
}
@@ -271,8 +519,43 @@ static void
sis_85c496_reset(void *priv)
{
sis_85c496_t *dev = (sis_85c496_t *) priv;
+ int i;
- sis_85c497_reset(dev);
+ sis_85c49x_pci_write(0, 0x44, 0x00, dev);
+ sis_85c49x_pci_write(0, 0x45, 0x00, dev);
+ sis_85c49x_pci_write(0, 0x58, 0x00, dev);
+ sis_85c49x_pci_write(0, 0x59, 0x00, dev);
+ sis_85c49x_pci_write(0, 0x5a, 0x00, dev);
+
+ for (i = 0; i < 8; i++)
+ sis_85c49x_pci_write(0, 0x48 + i, 0x00, dev);
+
+ sis_85c49x_pci_write(0, 0x80, 0x00, dev);
+ sis_85c49x_pci_write(0, 0x81, 0x00, dev);
+ sis_85c49x_pci_write(0, 0x9e, 0x00, dev);
+ sis_85c49x_pci_write(0, 0x8d, 0x00, dev);
+ sis_85c49x_pci_write(0, 0xa0, 0xff, dev);
+ sis_85c49x_pci_write(0, 0xa1, 0xff, dev);
+ sis_85c49x_pci_write(0, 0xc0, 0x00, dev);
+ sis_85c49x_pci_write(0, 0xc1, 0x00, dev);
+ sis_85c49x_pci_write(0, 0xc2, 0x00, dev);
+ sis_85c49x_pci_write(0, 0xc3, 0x00, dev);
+ sis_85c49x_pci_write(0, 0xc8, 0x00, dev);
+ sis_85c49x_pci_write(0, 0xc9, 0x00, dev);
+ sis_85c49x_pci_write(0, 0xca, 0x00, dev);
+ sis_85c49x_pci_write(0, 0xcb, 0x00, dev);
+
+ sis_85c49x_pci_write(0, 0xd0, 0x79, dev);
+ sis_85c49x_pci_write(0, 0xd1, 0xff, dev);
+ sis_85c49x_pci_write(0, 0xd0, 0x78, dev);
+ sis_85c49x_pci_write(0, 0xd4, 0x00, dev);
+
+ ide_pri_disable();
+ ide_sec_disable();
+
+ nvr_bank_set(0, 0, dev->nvr);
+
+ sis_85c497_isa_reset(dev);
}
@@ -289,33 +572,29 @@ static void
*sis_85c496_init(const device_t *info)
{
sis_85c496_t *dev = malloc(sizeof(sis_85c496_t));
- memset(dev, 0, sizeof(sis_85c496_t));
-
- dev->pci_conf[0x00] = 0x39; /*SiS*/
- dev->pci_conf[0x01] = 0x10;
- dev->pci_conf[0x02] = 0x96; /*496/497*/
- dev->pci_conf[0x03] = 0x04;
-
- dev->pci_conf[0x04] = 7;
- dev->pci_conf[0x05] = 0;
+ memset(dev, 0x00, sizeof(sis_85c496_t));
+ /* PCI Configuration Header Registers (00h ~ 3Fh) */
+ dev->pci_conf[0x00] = 0x39; /* SiS */
+ dev->pci_conf[0x01] = 0x10;
+ dev->pci_conf[0x02] = 0x96; /* 496/497 */
+ dev->pci_conf[0x03] = 0x04;
+ dev->pci_conf[0x04] = 0x07;
dev->pci_conf[0x06] = 0x80;
dev->pci_conf[0x07] = 0x02;
-
- dev->pci_conf[0x08] = 2; /*Device revision*/
-
- dev->pci_conf[0x09] = 0x00; /*Device class (PCI bridge)*/
- dev->pci_conf[0x0a] = 0x00;
+ dev->pci_conf[0x08] = 0x02; /* Device revision */
+ dev->pci_conf[0x09] = 0x00; /* Device class (PCI bridge) */
dev->pci_conf[0x0b] = 0x06;
- dev->pci_conf[0x0e] = 0x00; /*Single function device*/
+ /* 86C496 Specific Registers (40h ~ 7Fh) */
+ /* 86C497 Specific Registers (80h ~ FFh) */
dev->pci_conf[0xd0] = 0x78; /* ROM at E0000-FFFFF, Flash enable. */
dev->pci_conf[0xd1] = 0xff;
- pci_add_card(PCI_ADD_NORTHBRIDGE, sis_85c496_read, sis_85c496_write, dev);
+ pci_add_card(PCI_ADD_NORTHBRIDGE, sis_85c49x_pci_read, sis_85c49x_pci_write, dev);
- sis_85c497_reset(dev);
+ sis_85c497_isa_reset(dev);
dev->port_92 = device_add(&port_92_device);
port_92_set_period(dev->port_92, 2ULL * TIMER_USEC);
@@ -323,6 +602,18 @@ static void
sis_85c496_recalcmapping(dev);
+ ide_pri_disable();
+ ide_sec_disable();
+
+ if (info->local)
+ dev->nvr = device_add(&ls486e_nvr_device);
+ else
+ dev->nvr = device_add(&at_nvr_device);
+
+ dma_high_page_init();
+
+ timer_add(&dev->rmsmiblk_timer, sis_85c496_rmsmiblk_count, dev, 0);
+
return dev;
}
@@ -340,3 +631,18 @@ const device_t sis_85c496_device =
NULL,
NULL
};
+
+
+const device_t sis_85c496_ls486e_device =
+{
+ "SiS 85c496/85c497 (Lucky Star LS-486E)",
+ DEVICE_PCI,
+ 1,
+ sis_85c496_init,
+ sis_85c496_close,
+ sis_85c496_reset,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
diff --git a/src/cpu/386_common.c b/src/cpu/386_common.c
index 1bda39a95..3bfc3ccbc 100644
--- a/src/cpu/386_common.c
+++ b/src/cpu/386_common.c
@@ -61,7 +61,8 @@ extern int optype;
extern uint32_t pccache;
-int in_sys = 0;
+int in_sys = 0, unmask_a20_in_smm = 0;
+uint32_t old_rammask = 0xffffffff;
smram_t temp_smram[2];
@@ -1100,6 +1101,13 @@ enter_smm(int in_hlt)
smm_in_hlt = in_hlt;
+ if (unmask_a20_in_smm) {
+ old_rammask = rammask;
+ rammask = cpu_16bitbus ? 0xFFFFFF : 0xFFFFFFFF;
+
+ flushmmucache();
+ }
+
CPU_BLOCK_END();
}
@@ -1151,6 +1159,12 @@ leave_smm(void)
x386_common_log("Reading %08X from memory at %08X to array element %i\n", saved_state[n], smram_state, n);
}
+ if (unmask_a20_in_smm) {
+ rammask = old_rammask;
+
+ flushmmucache();
+ }
+
x386_common_log("New SMBASE: %08X (%08X)\n", saved_state[SMRAM_FIELD_P5_SMBASE_OFFSET], saved_state[66]);
if (is_pentium) /* Intel P5 (Pentium) */
smram_restore_state_p5(saved_state);
diff --git a/src/cpu/808x.c b/src/cpu/808x.c
index a712e6830..2cde6d9c5 100644
--- a/src/cpu/808x.c
+++ b/src/cpu/808x.c
@@ -977,6 +977,7 @@ reset_common(int hard)
in_smm = smi_latched = 0;
smi_line = smm_in_hlt = 0;
+ smi_block = 0;
if (hard) {
smbase = 0x00030000;
diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c
index c958158fc..90e8e0dc9 100644
--- a/src/cpu/cpu.c
+++ b/src/cpu/cpu.c
@@ -137,6 +137,7 @@ const OpFn *x86_opcodes_REPNE;
const OpFn *x86_opcodes_3DNOW;
int in_smm = 0, smi_line = 0, smi_latched = 0, smm_in_hlt = 0;
+int smi_block = 0;
uint32_t smbase = 0x30000;
CPU *cpu_s;
@@ -358,6 +359,7 @@ cpu_set(void)
cpu_s = &machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective];
cpu_alt_reset = 0;
+ unmask_a20_in_smm = 0;
CPUID = cpu_s->cpuid_model;
is8086 = (cpu_s->cpu_type > CPU_8088);
diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h
index 567b40fc0..cf99c0ae1 100644
--- a/src/cpu/cpu.h
+++ b/src/cpu/cpu.h
@@ -412,6 +412,7 @@ extern int hasfpu;
extern uint32_t cpu_features;
extern int in_smm, smi_line, smi_latched, smm_in_hlt;
+extern int smi_block;
extern uint32_t smbase;
#ifdef USE_NEW_DYNAREC
@@ -497,7 +498,8 @@ extern int timing_retf_rm, timing_retf_pm, timing_retf_pm_outer;
extern int timing_jmp_rm, timing_jmp_pm, timing_jmp_pm_gate;
extern int timing_misaligned;
-extern int in_sys;
+extern int in_sys, unmask_a20_in_smm;
+extern uint32_t old_rammask;
extern uint16_t cpu_fast_off_count, cpu_fast_off_val;
extern uint32_t cpu_fast_off_flags;
diff --git a/src/dma.c b/src/dma.c
index bbfdf2118..3e7ac0152 100644
--- a/src/dma.c
+++ b/src/dma.c
@@ -485,9 +485,9 @@ dma_write(uint16_t addr, uint8_t val, void *priv)
case 6: /*Address registers*/
dma_wp[0] ^= 1;
if (dma_wp[0])
- dma[channel].ab = (dma[channel].ab & 0xffff00) | val;
+ dma[channel].ab = (dma[channel].ab & 0xffffff00 & dma_mask) | val;
else
- dma[channel].ab = (dma[channel].ab & 0xff00ff) | (val << 8);
+ dma[channel].ab = (dma[channel].ab & 0xffff00ff & dma_mask) | (val << 8);
dma[channel].ac = dma[channel].ab;
return;
@@ -778,14 +778,14 @@ dma16_write(uint16_t addr, uint8_t val, void *priv)
dma_wp[1] ^= 1;
if (dma_ps2.is_ps2) {
if (dma_wp[1])
- dma[channel].ab = (dma[channel].ab & 0xffff00) | val;
+ dma[channel].ab = (dma[channel].ab & 0xffffff00 & dma_mask) | val;
else
- dma[channel].ab = (dma[channel].ab & 0xff00ff) | (val << 8);
+ dma[channel].ab = (dma[channel].ab & 0xffff00ff & dma_mask) | (val << 8);
} else {
if (dma_wp[1])
- dma[channel].ab = (dma[channel].ab & 0xfffe00) | (val << 1);
+ dma[channel].ab = (dma[channel].ab & 0xfffffe00 & dma_mask) | (val << 1);
else
- dma[channel].ab = (dma[channel].ab & 0xfe01ff) | (val << 9);
+ dma[channel].ab = (dma[channel].ab & 0xfffe01ff & dma_mask) | (val << 9);
}
dma[channel].ac = dma[channel].ab;
return;
@@ -878,12 +878,12 @@ dma_page_write(uint16_t addr, uint8_t val, void *priv)
if (addr > 4) {
dma[addr].page = val & 0xfe;
- dma[addr].ab = (dma[addr].ab & 0x1ffff) | (dma[addr].page << 16);
- dma[addr].ac = (dma[addr].ac & 0x1ffff) | (dma[addr].page << 16);
+ dma[addr].ab = (dma[addr].ab & 0xff01ffff & dma_mask) | (dma[addr].page << 16);
+ dma[addr].ac = (dma[addr].ac & 0xff01ffff & dma_mask) | (dma[addr].page << 16);
} else {
dma[addr].page = (AT) ? val : val & 0xf;
- dma[addr].ab = (dma[addr].ab & 0xffff) | (dma[addr].page << 16);
- dma[addr].ac = (dma[addr].ac & 0xffff) | (dma[addr].page << 16);
+ dma[addr].ab = (dma[addr].ab & 0xff00ffff & dma_mask) | (dma[addr].page << 16);
+ dma[addr].ac = (dma[addr].ac & 0xff00ffff & dma_mask) | (dma[addr].page << 16);
}
}
}
@@ -959,6 +959,20 @@ dma_set_params(uint8_t advanced, uint32_t mask)
}
+void
+dma_set_mask(uint32_t mask)
+{
+ int i;
+
+ dma_mask = mask;
+
+ for (i = 0; i < 8; i++) {
+ dma[i].ab &= mask;
+ dma[i].ac &= mask;
+ }
+}
+
+
void
dma_reset(void)
{
@@ -1355,14 +1369,14 @@ dma_channel_read(int channel)
else if (dma_advanced)
dma_retreat(dma_c);
else
- dma_c->ac = (dma_c->ac & 0xff0000) | ((dma_c->ac - 1) & 0xffff);
+ dma_c->ac = (dma_c->ac & 0xffff0000 & dma_mask) | ((dma_c->ac - 1) & 0xffff);
} else {
if (dma_ps2.is_ps2)
dma_c->ac++;
else if (dma_advanced)
dma_advance(dma_c);
else
- dma_c->ac = (dma_c->ac & 0xff0000) | ((dma_c->ac + 1) & 0xffff);
+ dma_c->ac = (dma_c->ac & 0xffff0000 & dma_mask) | ((dma_c->ac + 1) & 0xffff);
}
} else {
temp = _dma_readw(dma_c->ac, dma_c);
@@ -1373,14 +1387,14 @@ dma_channel_read(int channel)
else if (dma_advanced)
dma_retreat(dma_c);
else
- dma_c->ac = (dma_c->ac & 0xfe0000) | ((dma_c->ac - 2) & 0x1ffff);
+ dma_c->ac = (dma_c->ac & 0xfffe0000 & dma_mask) | ((dma_c->ac - 2) & 0x1ffff);
} else {
if (dma_ps2.is_ps2)
dma_c->ac += 2;
else if (dma_advanced)
dma_advance(dma_c);
else
- dma_c->ac = (dma_c->ac & 0xfe0000) | ((dma_c->ac + 2) & 0x1ffff);
+ dma_c->ac = (dma_c->ac & 0xfffe0000 & dma_mask) | ((dma_c->ac + 2) & 0x1ffff);
}
}
@@ -1443,14 +1457,14 @@ dma_channel_write(int channel, uint16_t val)
else if (dma_advanced)
dma_retreat(dma_c);
else
- dma_c->ac = (dma_c->ac & 0xff0000) | ((dma_c->ac - 1) & 0xffff);
+ dma_c->ac = (dma_c->ac & 0xffff0000 & dma_mask) | ((dma_c->ac - 1) & 0xffff);
} else {
if (dma_ps2.is_ps2)
dma_c->ac++;
else if (dma_advanced)
dma_advance(dma_c);
else
- dma_c->ac = (dma_c->ac & 0xff0000) | ((dma_c->ac + 1) & 0xffff);
+ dma_c->ac = (dma_c->ac & 0xffff0000 & dma_mask) | ((dma_c->ac + 1) & 0xffff);
}
} else {
_dma_writew(dma_c->ac, val, dma_c);
@@ -1461,15 +1475,15 @@ dma_channel_write(int channel, uint16_t val)
else if (dma_advanced)
dma_retreat(dma_c);
else
- dma_c->ac = (dma_c->ac & 0xfe0000) | ((dma_c->ac - 2) & 0x1ffff);
- dma_c->ac = (dma_c->ac & 0xfe0000) | ((dma_c->ac - 2) & 0x1ffff);
+ dma_c->ac = (dma_c->ac & 0xfffe0000 & dma_mask) | ((dma_c->ac - 2) & 0x1ffff);
+ dma_c->ac = (dma_c->ac & 0xfffe0000 & dma_mask) | ((dma_c->ac - 2) & 0x1ffff);
} else {
if (dma_ps2.is_ps2)
dma_c->ac += 2;
else if (dma_advanced)
dma_advance(dma_c);
else
- dma_c->ac = (dma_c->ac & 0xfe0000) | ((dma_c->ac + 2) & 0x1ffff);
+ dma_c->ac = (dma_c->ac & 0xfffe0000 & dma_mask) | ((dma_c->ac + 2) & 0x1ffff);
}
}
diff --git a/src/include/86box/chipset.h b/src/include/86box/chipset.h
index 276da03c8..defc595ae 100644
--- a/src/include/86box/chipset.h
+++ b/src/include/86box/chipset.h
@@ -21,9 +21,6 @@
/* ACC */
extern const device_t acc2168_device;
-/* Acer M3A and V35N */
-extern const device_t acerm3a_device;
-
/* ALi */
extern const device_t ali1429_device;
@@ -77,6 +74,7 @@ extern const device_t cs8230_device;
extern const device_t rabbit_device;
extern const device_t sis_85c471_device;
extern const device_t sis_85c496_device;
+extern const device_t sis_85c496_ls486e_device;
#if defined(DEV_BRANCH) && defined(USE_SIS_85C50X)
extern const device_t sis_85c50x_device;
#endif
diff --git a/src/include/86box/dma.h b/src/include/86box/dma.h
index d5ee9fcb3..bc09bac97 100644
--- a/src/include/86box/dma.h
+++ b/src/include/86box/dma.h
@@ -96,8 +96,9 @@ extern void dma_bm_read(uint32_t PhysAddress, uint8_t *DataRead, uint32_t TotalS
extern void dma_bm_write(uint32_t PhysAddress, const uint8_t *DataWrite, uint32_t TotalSize, int TransferSize);
void dma_set_params(uint8_t advanced, uint32_t mask);
-void dma_ext_mode_init(void);
+void dma_set_mask(uint32_t mask);
+void dma_ext_mode_init(void);
void dma_high_page_init(void);
void dma_remove_sg(void);
diff --git a/src/include/86box/mem.h b/src/include/86box/mem.h
index 4104c4fa0..e0ff655ba 100644
--- a/src/include/86box/mem.h
+++ b/src/include/86box/mem.h
@@ -39,10 +39,10 @@
Bits 24 -31: SMM read
*/
-#define MEM_READ_ANY 0x0000
+#define MEM_READ_DISABLED 0x0000
#define MEM_READ_INTERNAL 0x0100
#define MEM_READ_EXTERNAL 0x0200
-#define MEM_READ_DISABLED 0x0300
+#define MEM_READ_ANY 0x0300
#define MEM_READ_NORMAL 0x0400 /* SMM only - means use the non-SMM state */
#define MEM_READ_EXTERNAL_EX 0x0500 /* External but with internal exec - needed by the VIA Apollo Pro */
#define MEM_READ_ROMCS 0x0600 /* EXTERNAL type + ROMC flag */
@@ -52,10 +52,10 @@
#define MEM_READ_DISABLED_EX 0x4000
#define MEM_READ_MASK 0xff00
-#define MEM_WRITE_ANY 0x0000
+#define MEM_WRITE_DISABLED 0x0000
#define MEM_WRITE_INTERNAL 0x0001
#define MEM_WRITE_EXTERNAL 0x0002
-#define MEM_WRITE_DISABLED 0x0003
+#define MEM_WRITE_ANY 0x0003
#define MEM_WRITE_NORMAL 0x0004 /* SMM only - means use the non-SMM state */
#define MEM_WRITE_EXTERNAL_EX 0x0005
#define MEM_WRITE_ROMCS 0x0006 /* EXTERNAL type + ROMC flag */
diff --git a/src/io.c b/src/io.c
index b09624064..f78dc268e 100644
--- a/src/io.c
+++ b/src/io.c
@@ -367,7 +367,7 @@ inw(uint16_t port)
ret8[0] = ret & 0xff;
ret8[1] = (ret >> 8) & 0xff;
for (i = 0; i < 2; i++) {
- p = io[port + i];
+ p = io[(port + i) & 0xffff];
while(p) {
if (p->inb && !p->inw) {
ret8[i] &= p->inb(port + i, p->priv);
@@ -414,7 +414,7 @@ outw(uint16_t port, uint16_t val)
}
for (i = 0; i < 2; i++) {
- p = io[port + i];
+ p = io[(port + i) & 0xffff];
while(p) {
if (p->outb && !p->outw) {
p->outb(port + i, val >> (i << 3), p->priv);
@@ -463,7 +463,7 @@ inl(uint16_t port)
ret16[0] = ret & 0xffff;
ret16[1] = (ret >> 16) & 0xffff;
for (i = 0; i < 4; i += 2) {
- p = io[port + i];
+ p = io[(port + i) & 0xffff];
while(p) {
if (p->inw && !p->inl) {
ret16[i >> 1] &= p->inw(port + i, p->priv);
@@ -480,7 +480,7 @@ inl(uint16_t port)
ret8[2] = (ret >> 16) & 0xff;
ret8[3] = (ret >> 24) & 0xff;
for (i = 0; i < 4; i++) {
- p = io[port + i];
+ p = io[(port + i) & 0xffff];
while(p) {
if (p->inb && !p->inw && !p->inl) {
ret8[i] &= p->inb(port + i, p->priv);
@@ -523,14 +523,13 @@ outl(uint16_t port, uint32_t val)
p->outl(port, val, p->priv);
found |= 4;
qfound++;
- // return;
}
p = p->next;
}
}
for (i = 0; i < 4; i += 2) {
- p = io[port + i];
+ p = io[(port + i) & 0xffff];
while(p) {
if (p->outw && !p->outl) {
p->outw(port + i, val >> (i << 3), p->priv);
@@ -542,7 +541,7 @@ outl(uint16_t port, uint32_t val)
}
for (i = 0; i < 4; i++) {
- p = io[port + i];
+ p = io[(port + i) & 0xffff];
while(p) {
if (p->outb && !p->outw && !p->outl) {
p->outb(port + i, val >> (i << 3), p->priv);
diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c
index cdf86fee8..6946dffa2 100644
--- a/src/machine/m_at_386dx_486.c
+++ b/src/machine/m_at_386dx_486.c
@@ -385,16 +385,11 @@ machine_at_sis_85c496_common_init(const machine_t *model)
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x05, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
- pci_register_slot(0x0B, PCI_CARD_NORMAL, 1, 2, 3, 4);
- pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1);
- pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED);
pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED);
pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED);
pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED);
-
- device_add(&sis_85c496_device);
}
@@ -409,9 +404,12 @@ machine_at_r418_init(const machine_t *model)
if (bios_only || !ret)
return ret;
- machine_at_common_init(model);
-
+ machine_at_common_init_ex(model, 2);
machine_at_sis_85c496_common_init(model);
+ device_add(&sis_85c496_device);
+ pci_register_slot(0x0B, PCI_CARD_NORMAL, 1, 2, 3, 4);
+ pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1);
+ pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x07, PCI_CARD_NORMAL, 4, 1, 2, 3);
device_add(&fdc37c665_device);
@@ -433,9 +431,11 @@ machine_at_ls486e_init(const machine_t *model)
return ret;
machine_at_common_init_ex(model, 2);
- device_add(&ls486e_nvr_device);
-
machine_at_sis_85c496_common_init(model);
+ device_add(&sis_85c496_ls486e_device);
+ pci_register_slot(0x0B, PCI_CARD_NORMAL, 1, 2, 3, 4);
+ pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1);
+ pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x06, PCI_CARD_NORMAL, 4, 1, 2, 3);
device_add(&fdc37c665_device);
@@ -456,14 +456,20 @@ machine_at_4dps_init(const machine_t *model)
if (bios_only || !ret)
return ret;
- machine_at_common_init(model);
-
+ machine_at_common_init_ex(model, 2);
machine_at_sis_85c496_common_init(model);
+ device_add(&sis_85c496_device);
+ pci_register_slot(0x0B, PCI_CARD_NORMAL, 1, 2, 3, 4);
+ pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1);
+ pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x07, PCI_CARD_NORMAL, 4, 1, 2, 3);
device_add(&w83787f_device);
device_add(&keyboard_ps2_pci_device);
+ // device_add(&sst_flash_29ee010_device);
+ device_add(&intel_flash_bxt_device);
+
return ret;
}
diff --git a/src/machine/m_at_socket7_s7.c b/src/machine/m_at_socket7_s7.c
index f997105d2..a029b717c 100644
--- a/src/machine/m_at_socket7_s7.c
+++ b/src/machine/m_at_socket7_s7.c
@@ -238,7 +238,6 @@ machine_at_acerm3a_init(const machine_t *model)
device_add(&piix3_device);
device_add(&keyboard_ps2_pci_device);
device_add(&fdc37c932fr_device);
- device_add(&acerm3a_device);
device_add(&sst_flash_29ee010_device);
@@ -271,7 +270,6 @@ machine_at_acerv35n_init(const machine_t *model)
device_add(&piix3_device);
device_add(&keyboard_ps2_pci_device);
device_add(&fdc37c932fr_device);
- device_add(&acerm3a_device);
device_add(&sst_flash_29ee010_device);
diff --git a/src/machine/m_at_socket8.c b/src/machine/m_at_socket8.c
index 04fcffd1f..41904d191 100644
--- a/src/machine/m_at_socket8.c
+++ b/src/machine/m_at_socket8.c
@@ -121,7 +121,6 @@ machine_at_v60n_init(const machine_t *model)
device_add(&piix3_device);
device_add(&keyboard_ps2_pci_device);
device_add(&fdc37c935_device);
- device_add(&acerm3a_device);
device_add(&sst_flash_29ee010_device);
return ret;
diff --git a/src/machine/m_ps1.c b/src/machine/m_ps1.c
index 52ac3a523..b971d502d 100644
--- a/src/machine/m_ps1.c
+++ b/src/machine/m_ps1.c
@@ -495,7 +495,7 @@ ps1_setup(int model)
/* Enable the PS/1 VGA controller. */
if (model == 2011)
device_add(&ps1vga_device);
- else
+ else if (model == 2021)
device_add(&ibm_ps1_2121_device);
}
diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c
index 75a211944..5c89a6eb1 100644
--- a/src/machine/machine_table.c
+++ b/src/machine/machine_table.c
@@ -221,9 +221,9 @@ const machine_t machines[] = {
{ "[i420EX] ASUS PVI-486AP4", "486ap4", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 128, 1, 127, machine_at_486ap4_init, NULL },
{ "[i420ZX] ASUS PCI/I-486SP3G", "486sp3g", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 128, 1, 127, machine_at_486sp3g_init, NULL },
{ "[i420TX] Intel Classic/PCI", "alfredo", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_alfredo_init, NULL },
- { "[SiS 496] Lucky Star LS-486E", "ls486e", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 128, 1, 127, machine_at_ls486e_init, NULL },
- { "[SiS 496] Rise Computer R418", "r418", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 255, 1, 127, machine_at_r418_init, NULL },
- { "[SiS 496] Zida Tomato 4DP", "4dps", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 255, 1, 127, machine_at_4dps_init, NULL },
+ { "[SiS 496] Lucky Star LS-486E", "ls486e", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 128, 1, 255, machine_at_ls486e_init, NULL },
+ { "[SiS 496] Rise Computer R418", "r418", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 255, 1, 255, machine_at_r418_init, NULL },
+ { "[SiS 496] Zida Tomato 4DP", "4dps", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 255, 1, 255, machine_at_4dps_init, NULL },
/* Socket 4 machines */
/* OPTi 596/597 */
diff --git a/src/mem/mem.c b/src/mem/mem.c
index 572c5878a..29d67d1a1 100644
--- a/src/mem/mem.c
+++ b/src/mem/mem.c
@@ -2520,6 +2520,11 @@ mem_reset(void)
{
uint32_t c, m, m2;
+#if FIXME
+ memset(ff_array, 0xff, sizeof(ff_array));
+#endif
+ memset(page_ff, 0xff, sizeof(page_ff));
+
m = 1024UL * mem_size;
if (ram != NULL) {
free(ram);
@@ -2654,6 +2659,9 @@ mem_log("MEM: reset: new pages=%08lx, pages_sz=%i\n", pages, pages_sz);
#endif
}
+ memset(read_mapping, 0x00, sizeof(read_mapping));
+ memset(write_mapping, 0x00, sizeof(write_mapping));
+
memset(_mem_exec, 0x00, sizeof(_mem_exec));
memset(&base_mapping, 0x00, sizeof(base_mapping));
@@ -2664,6 +2672,8 @@ mem_log("MEM: reset: new pages=%08lx, pages_sz=%i\n", pages, pages_sz);
MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
mem_set_mem_state_both(0x0a0000, 0x60000,
MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
+ mem_set_mem_state_both((mem_size << 10), (uint32_t) (0x100000000ULL - (mem_size << 10)),
+ MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
mem_mapping_add(&ram_low_mapping, 0x00000,
(mem_size > 640) ? 0xa0000 : mem_size * 1024,
@@ -2765,11 +2775,6 @@ mem_init(void)
writelookup2 = malloc((1<<20)*sizeof(uintptr_t));
#endif
-#if FIXME
- memset(ff_array, 0xff, sizeof(ff_array));
-#endif
- memset(page_ff, 0xff, sizeof(page_ff));
-
/* Reset the memory state. */
mem_reset();
}
diff --git a/src/pit.c b/src/pit.c
index b33adbc1a..fec976d79 100644
--- a/src/pit.c
+++ b/src/pit.c
@@ -1030,9 +1030,9 @@ pit_set_clock(int clock)
isa_timing = (cpuclock / (double)8000000.0);
if (cpu_64bitbus)
- bus_timing = (cpuclock / ((double)cpu_busspeed / 2));
+ bus_timing = (cpuclock / ((double)cpu_busspeed / 2));
else
- bus_timing = (cpuclock / (double)cpu_busspeed);
+ bus_timing = (cpuclock / (double)cpu_busspeed);
pci_timing = (cpuclock / (double)cpu_pci_speed);
/* PCICLK in us for use with timer_on_auto(). */
diff --git a/src/sio/sio_fdc37c93x.c b/src/sio/sio_fdc37c93x.c
index 7e08ab373..2f6a4a61b 100644
--- a/src/sio/sio_fdc37c93x.c
+++ b/src/sio/sio_fdc37c93x.c
@@ -108,8 +108,11 @@ static uint8_t
fdc37c93x_gpio_read(uint16_t port, void *priv)
{
fdc37c93x_t *dev = (fdc37c93x_t *) priv;
+ uint8_t ret = 0xff;
- return dev->gpio_regs[port & 1];
+ ret = dev->gpio_regs[port & 1];
+
+ return ret;
}
@@ -118,7 +121,8 @@ fdc37c93x_gpio_write(uint16_t port, uint8_t val, void *priv)
{
fdc37c93x_t *dev = (fdc37c93x_t *) priv;
- dev->gpio_regs[port & 1] = val;
+ if (!(port & 1))
+ dev->gpio_regs[0] = (dev->gpio_regs[0] & 0xfc) | (val & 0x03);
}
@@ -756,8 +760,8 @@ fdc37c93x_init(const device_t *info)
dev->chip_id = info->local;
- dev->gpio_regs[0] = 0xFD;
- dev->gpio_regs[1] = 0xFF;
+ dev->gpio_regs[0] = 0xff;
+ dev->gpio_regs[1] = 0xfd;
if (dev->chip_id == 0x30) {
dev->nvr = device_add(&at_nvr_device);
diff --git a/src/sio/sio_w83787f.c b/src/sio/sio_w83787f.c
index bc1a4792c..f1a6e51d8 100644
--- a/src/sio/sio_w83787f.c
+++ b/src/sio/sio_w83787f.c
@@ -145,27 +145,24 @@ w83787f_serial_handler(w83787f_t *dev, int uart)
static void
w83787f_lpt_handler(w83787f_t *dev)
{
- int ptrs0 = !!(dev->regs[1] & 4);
- int ptrs1 = !!(dev->regs[1] & 5);
- int ptrs, irq = 7;
+ int ptras = (dev->regs[1] >> 4) & 0x03;
+ int irq = 7;
uint16_t addr = 0x378, enable = 1;
- ptrs = (ptrs1 << 1) | ptrs0;
-
- switch (ptrs) {
- case 0:
+ switch (ptras) {
+ case 0x00:
addr = 0x3bc;
irq = 7;
break;
- case 1:
+ case 0x01:
addr = 0x278;
irq = 5;
break;
- case 2:
+ case 0x02:
addr = 0x378;
irq = 7;
break;
- case 3:
+ case 0x03:
default:
enable = 0;
break;
diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw
index 2334fa603..cea2187e3 100644
--- a/src/win/Makefile.mingw
+++ b/src/win/Makefile.mingw
@@ -559,7 +559,7 @@ CPUOBJ := cpu.o cpu_table.o \
x86seg.o x87.o x87_timings.o \
$(DYNARECOBJ)
-CHIPSETOBJ := acc2168.o acer_m3a.o cs8230.o ali1429.o headland.o i82335.o \
+CHIPSETOBJ := acc2168.o cs8230.o ali1429.o headland.o i82335.o \
intel_420ex.o intel_4x0.o intel_sio.o intel_piix.o ioapic.o \
neat.o opti495.o opti5x7.o scamp.o scat.o \
sis_85c310.o sis_85c471.o sis_85c496.o \