diff --git a/src/chipset/intel_4x0.c b/src/chipset/intel_4x0.c
index 443090caa..e70d57973 100644
--- a/src/chipset/intel_4x0.c
+++ b/src/chipset/intel_4x0.c
@@ -51,7 +51,8 @@ enum
typedef struct
{
- uint8_t pm2_cntrl, max_func;
+ uint8_t pm2_cntrl, max_func,
+ smram_locked;
uint8_t regs[2][256], regs_locked[2][256];
int type;
} i4x0_t;
@@ -78,6 +79,127 @@ i4x0_map(uint32_t addr, uint32_t size, int state)
}
+static void
+i4x0_smram_map(int smm, uint32_t addr, uint32_t size, int ram)
+{
+ int state = ram ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY);
+
+ mem_set_mem_state_common(smm, addr, size, state);
+ flushmmucache();
+}
+
+
+static void
+i4x0_smram_handler_phase0(i4x0_t *dev)
+{
+ uint32_t i, n;
+
+ /* Disable any active mappings. */
+ if (dev->type >= INTEL_430FX) {
+ if (dev->type >= INTEL_440BX) {
+ /* Disable high extended SMRAM. */
+ /* TODO: This area should point to A0000-FFFFF. */
+ for (i = 0x100a0000; i < 0x100fffff; i += MEM_GRANULARITY_SIZE) {
+ /* This is to make sure that if the remaining area is smaller than
+ or equal to MEM_GRANULARITY_SIZE, we do not change the state of
+ too much memory. */
+ n = ((mem_size << 10) - i);
+ /* Cap to MEM_GRANULARITY_SIZE if i is either at or beyond the end
+ of RAM or the remaining area is bigger than MEM_GRANULARITY_SIZE. */
+ if ((i >= (mem_size << 10)) || (n > MEM_GRANULARITY_SIZE))
+ n = MEM_GRANULARITY_SIZE;
+ i4x0_smram_map(0, i, n, (i < (mem_size << 10)));
+ i4x0_smram_map(1, i, n, (i < (mem_size << 10)));
+ if (n < MEM_GRANULARITY_SIZE) {
+ i4x0_smram_map(0, i + n, MEM_GRANULARITY_SIZE - n, 0);
+ i4x0_smram_map(1, i + n, MEM_GRANULARITY_SIZE - n, 0);
+ }
+ }
+
+ /* Disable TSEG. */
+ i4x0_smram_map(1, ((mem_size << 10) - (1 << 20)), (1 << 20), 1);
+ }
+
+ /* Disable low extended SMRAM. */
+ i4x0_smram_map(0, 0xa0000, 0x20000, 0);
+ i4x0_smram_map(1, 0xa0000, 0x20000, 0);
+ } else {
+ /* Disable low extended SMRAM. */
+ i4x0_smram_map(0, 0xa0000, 0x20000, 0);
+ i4x0_smram_map(0, (mem_size << 10) - 0x10000, 0x10000, 1);
+ i4x0_smram_map(1, 0xa0000, 0x20000, 0);
+ i4x0_smram_map(1, (mem_size << 10) - 0x10000, 0x10000, 1);
+ }
+}
+
+
+static void
+i4x0_smram_handler_phase1(i4x0_t *dev)
+{
+ uint8_t *regs = (uint8_t *) dev->regs[0];
+
+ uint32_t s, base[2] = { 0x000a0000, 0x00020000 };
+ uint32_t size[2] = { 0, 0 };
+
+ if (dev->type >= INTEL_430FX) {
+ /* Set temporary bases and sizes. */
+ if ((dev->type >= INTEL_440BX) && (regs[0x73] & 0x80)) {
+ base[0] = 0x100a0000;
+ size[0] = 0x00060000;
+ } else {
+ base[0] = 0x000a0000;
+ size[0] = 0x00020000;
+ }
+
+ /* If D_OPEN = 1 and D_LCK = 0, extended SMRAM is visible outside SMM. */
+ i4x0_smram_map(0, base[0], size[0], ((regs[0x72] & 0x70) == 0x40));
+
+ /* If the register is set accordingly, disable the mapping also in SMM. */
+ i4x0_smram_map(1, base[0], size[0], ((regs[0x72] & 0x08) && !(regs[0x72] & 0x20)));
+
+ /* TSEG mapping. */
+ if (dev->type >= INTEL_440BX) {
+ if ((regs[0x72] & 0x08) && (regs[0x73] & 0x01)) {
+ size[1] = (1 << (17 + ((regs[0x73] >> 1) & 0x03)));
+ base[1] = (mem_size << 10) - size[1];
+ } else
+ base[1] = size[1] = 0x00000000;
+ i4x0_smram_map(1, base[1], size[1], 1);
+ } else
+ base[1] = size[1] = 0x00000000;
+ } else {
+ size[0] = 0x00010000;
+ switch (regs[0x72] & 0x03) {
+ case 0:
+ default:
+ base[0] = (mem_size << 10) - size[0];
+ s = 1;
+ break;
+ case 1:
+ base[0] = size[0] = 0x00000000;
+ s = 1;
+ break;
+ case 2:
+ base[0] = 0x000a0000;
+ s = 0;
+ break;
+ case 3:
+ base[0] = 0x000b0000;
+ s = 0;
+ break;
+ }
+
+ if (base[0] != 0x00000000) {
+ /* If OSS = 1 and LSS = 0, extended SMRAM is visible outside SMM. */
+ i4x0_smram_map(0, base[0], size[0], ((regs[0x72] & 0x38) == 0x20) || s);
+
+ /* If the register is set accordingly, disable the mapping also in SMM. */
+ i4x0_smram_map(0, base[0], size[0], !(regs[0x72] & 0x10) || s);
+ }
+ }
+}
+
+
static void
i4x0_mask_bar(uint8_t *regs)
{
@@ -636,19 +758,27 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
}
break;
case 0x72: /* SMRAM */
+ i4x0_smram_handler_phase0(dev);
if (dev->type >= INTEL_430FX) {
- if ((regs[0x72] & 0x10) || (val & 0x10)) {
- regs[0x72] = (val & 0x38) | 0x02;
- i4x0_map(0xa0000, 0x20000, 0);
- } else {
- regs[0x72] = (val & 0x78) | 0x02;
- i4x0_map(0xa0000, 0x20000, ((val & 0x48) == 0x48) ? 3 : 0);
+ if (dev->smram_locked)
+ regs[0x72] = (regs[0x72] & 0xdf) | (val & 0x20);
+ else {
+ regs[0x72] = (regs[0x72] & 0x87) | (val & 0x78);
+ dev->smram_locked = (val & 0x10);
+ if (dev->smram_locked)
+ regs[0x72] &= 0xbf;
}
} else {
- if ((regs[0x72] ^ val) & 0x20)
- i4x0_map(0xa0000, 0x20000, ((val & 0x20) == 0x20) ? 3 : 0);
- regs[0x72] = val & 0x3f;
+ if (dev->smram_locked)
+ regs[0x72] = (regs[0x72] & 0xef) | (val & 0x10);
+ else {
+ regs[0x72] = (regs[0x72] & 0xc0) | (val & 0x3f);
+ dev->smram_locked = (val & 0x08);
+ if (dev->smram_locked)
+ regs[0x72] &= 0xef;
+ }
}
+ i4x0_smram_handler_phase1(dev);
break;
case 0x73:
switch (dev->type) {
@@ -656,7 +786,11 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
regs[0x73] = val & 0x03;
break;
case INTEL_440BX: case INTEL_440ZX:
- regs[0x73] = val;
+ if (!dev->smram_locked) {
+ i4x0_smram_handler_phase0(dev);
+ regs[0x73] = (regs[0x72] & 0x38) | (val & 0xc7);
+ i4x0_smram_handler_phase1(dev);
+ }
break;
}
break;
diff --git a/src/chipset/via_apollo.c b/src/chipset/via_apollo.c
new file mode 100644
index 000000000..e7bb52993
--- /dev/null
+++ b/src/chipset/via_apollo.c
@@ -0,0 +1,587 @@
+/*
+ * 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 VIA Apollo series of chips.
+ *
+ *
+ *
+ * Authors: Sarah Walker,
+ * Miran Grca,
+ * Melissa Goad,
+ * Tiseno100,
+ *
+ * Copyright 2020 Miran Grca.
+ * Copyright 2020 Melissa Goad.
+ * Copyright 2020 Tiseno100.
+ */
+#include
+#include
+#include
+#include
+#include
+#include <86box/86box.h>
+#include <86box/mem.h>
+#include <86box/io.h>
+#include <86box/rom.h>
+#include <86box/pci.h>
+#include <86box/device.h>
+#include <86box/keyboard.h>
+#include <86box/chipset.h>
+
+
+typedef struct via_apollo_t
+{
+ uint16_t id;
+ uint8_t pci_conf[2][256];
+} via_apollo_t;
+
+
+static void
+apollo_map(uint32_t addr, uint32_t size, int state)
+{
+ switch (state & 3) {
+ case 0:
+ mem_set_mem_state(addr, size, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
+ break;
+ case 1:
+ mem_set_mem_state(addr, size, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
+ break;
+ case 2:
+ mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTANY);
+ break;
+ case 3:
+ mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
+ break;
+ }
+
+ flushmmucache_nopc();
+}
+
+
+static void
+apollo_smram_map(int smm, uint32_t addr, uint32_t size, int ram)
+{
+ int state = (MEM_READ_EXTANY | MEM_WRITE_EXTANY);
+
+ if (ram == 0)
+ state = (MEM_READ_EXTANY | MEM_WRITE_EXTANY);
+ else if (ram == 1)
+ state = (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
+ else if (ram == 2)
+ state = (MEM_READ_EXTERNAL_EX | MEM_WRITE_EXTANY);
+ else if (ram == 3)
+ state = (MEM_READ_DISABLED | MEM_WRITE_DISABLED);
+
+ mem_set_mem_state_common(smm, addr, size, state);
+ flushmmucache();
+}
+
+
+static void
+via_apollo_setup(via_apollo_t *dev)
+{
+ memset(dev, 0, sizeof(via_apollo_t));
+
+ /* Host Bridge */
+ dev->pci_conf[0][0x00] = 0x06; /*VIA*/
+ dev->pci_conf[0][0x01] = 0x11;
+ dev->pci_conf[0][0x02] = dev->id & 0xff;
+ dev->pci_conf[0][0x03] = (dev->id >> 8);
+
+ dev->pci_conf[0][0x04] = 6;
+ dev->pci_conf[0][0x05] = 0;
+
+ dev->pci_conf[0][0x06] = 0x90;
+ dev->pci_conf[0][0x07] = 0x02;
+
+ if (dev->id == 0x0597)
+ dev->pci_conf[0][0x08] = 1; /* Production Silicon ("Revision B") */
+ dev->pci_conf[0][0x09] = 0;
+ dev->pci_conf[0][0x0a] = 0;
+ dev->pci_conf[0][0x0b] = 6;
+ dev->pci_conf[0][0x0c] = 0;
+ dev->pci_conf[0][0x0d] = 0;
+ dev->pci_conf[0][0x0e] = 0;
+ dev->pci_conf[0][0x0f] = 0;
+ dev->pci_conf[0][0x10] = 0x08;
+ dev->pci_conf[0][0x34] = 0xa0;
+
+ if (dev->id == 0x0691) {
+ dev->pci_conf[0][0x56] = 0x01;
+ dev->pci_conf[0][0x57] = 0x01;
+ }
+ dev->pci_conf[0][0x5a] = 0x01;
+ dev->pci_conf[0][0x5b] = 0x01;
+ dev->pci_conf[0][0x5c] = 0x01;
+ dev->pci_conf[0][0x5d] = 0x01;
+ dev->pci_conf[0][0x5e] = 0x01;
+ dev->pci_conf[0][0x5f] = 0x01;
+
+ dev->pci_conf[0][0x64] = 0xec;
+ dev->pci_conf[0][0x65] = 0xec;
+ dev->pci_conf[0][0x66] = 0xec;
+ if (dev->id == 0x0691)
+ dev->pci_conf[0][0x67] = 0xec; /* DRAM Timing for Banks 6,7. */
+ dev->pci_conf[0][0x6b] = 0x01;
+
+ dev->pci_conf[0][0xa0] = 0x02;
+ dev->pci_conf[0][0xa2] = 0x10;
+ dev->pci_conf[0][0xa4] = 0x03;
+ dev->pci_conf[0][0xa5] = 0x02;
+ dev->pci_conf[0][0xa7] = 0x07;
+
+ /* PCI-to-PCI Bridge */
+
+ dev->pci_conf[1][0x00] = 0x06; /*VIA*/
+ dev->pci_conf[1][0x01] = 0x11;
+ dev->pci_conf[1][0x02] = dev->id & 0xff;
+ dev->pci_conf[1][0x03] = (dev->id >> 8) | 0x80;
+
+ dev->pci_conf[1][0x04] = 7;
+ dev->pci_conf[1][0x05] = 0;
+
+ dev->pci_conf[1][0x06] = 0x20;
+ dev->pci_conf[1][0x07] = 0x02;
+
+ dev->pci_conf[1][0x09] = 0;
+ dev->pci_conf[1][0x0a] = 4;
+ dev->pci_conf[1][0x0b] = 6;
+ dev->pci_conf[1][0x0c] = 0;
+ dev->pci_conf[1][0x0d] = 0;
+ dev->pci_conf[1][0x0e] = 1;
+ dev->pci_conf[1][0x0f] = 0;
+
+ dev->pci_conf[1][0x1c] = 0xf0;
+
+ dev->pci_conf[1][0x20] = 0xf0;
+ dev->pci_conf[1][0x21] = 0xff;
+ dev->pci_conf[1][0x24] = 0xf0;
+ dev->pci_conf[1][0x25] = 0xff;
+}
+
+
+static void
+via_apollo_host_bridge_write(int func, int addr, uint8_t val, void *priv)
+{
+ via_apollo_t *dev = (via_apollo_t *) priv;
+
+ if (func)
+ return;
+
+ /*Read-only addresses*/
+ if ((addr < 4) || ((addr >= 5) && (addr < 7)) || ((addr >= 8) && (addr < 0xd)) ||
+ ((addr >= 0xe) && (addr < 0x12)) || ((addr >= 0x14) && (addr < 0x50)) ||
+ (addr == 0x69) || ((addr >= 0x79) && (addr < 0x7e)) ||
+ ((addr >= 0x81) && (addr < 0x84)) || ((addr >= 0x85) && (addr < 0x88)) ||
+ ((addr >= 0x8c) && (addr < 0xa8)) || ((addr >= 0xaa) && (addr < 0xac)) ||
+ ((addr >= 0xad) && (addr < 0xf0)) || ((addr >= 0xf8) && (addr < 0xfc)) ||
+ (addr == 0xfd))
+ return;
+ if (((addr == 0x78) || (addr >= 0xad)) && (dev->id == 0x0597))
+ return;
+ if (((addr == 0x67) || ((addr >= 0xf0) && (addr < 0xfc))) && (dev->id != 0x0691))
+ return;
+
+ switch(addr) {
+ case 0x04:
+ dev->pci_conf[0][0x04] = (dev->pci_conf[0][0x04] & ~0x40) | (val & 0x40);
+ break;
+ case 0x07:
+ dev->pci_conf[0][0x07] &= ~(val & 0xb0);
+ break;
+ case 0x0d:
+ dev->pci_conf[0][0x0d] = (dev->pci_conf[0][0x0d] & ~0x07) | (val & 0x07);
+ dev->pci_conf[0][0x75] = (dev->pci_conf[0][0x75] & ~0x30) | ((val & 0x06) << 3);
+ break;
+
+ case 0x12: /* Graphics Aperture Base */
+ dev->pci_conf[0][0x12] = (val & 0xf0);
+ break;
+ case 0x13: /* Graphics Aperture Base */
+ dev->pci_conf[0][0x13] = val;
+ break;
+
+ case 0x50: /* Cache Control 1 */
+ if (dev->id == 0x0691)
+ dev->pci_conf[0][0x50] = val;
+ else
+ dev->pci_conf[0][0x50] = (dev->pci_conf[0][0x50] & ~0xf8) | (val & 0xf8);
+ break;
+ case 0x51: /* Cache Control 2 */
+ if (dev->id == 0x0691)
+ dev->pci_conf[0][0x51] = val;
+ else
+ dev->pci_conf[0][0x51] = (dev->pci_conf[0][0x51] & ~0xeb) | (val & 0xeb);
+ break;
+ case 0x52: /* Non_Cacheable Control */
+ if (dev->id == 0x0691)
+ dev->pci_conf[0][0x52] = (dev->pci_conf[0][0x52] & ~0x9f) | (val & 0x9f);
+ else
+ dev->pci_conf[0][0x52] = (dev->pci_conf[0][0x52] & ~0xf5) | (val & 0xf5);
+ break;
+ case 0x53: /* System Performance Control */
+ if (dev->id == 0x0691)
+ dev->pci_conf[0][0x53] = val;
+ else
+ dev->pci_conf[0][0x53] = (dev->pci_conf[0][0x53] & ~0xf0) | (val & 0xf0);
+ break;
+
+ case 0x58:
+ if (dev->id == 0x0597)
+ dev->pci_conf[0][0x58] = (dev->pci_conf[0][0x58] & ~0xee) | (val & 0xee);
+ else
+ dev->pci_conf[0][0x58] = val;
+ break;
+ case 0x59:
+ if (dev->id == 0x0691)
+ dev->pci_conf[0][0x59] = val;
+ else
+ dev->pci_conf[0][0x59] = (dev->pci_conf[0][0x59] & ~0xf0) | (val & 0xf0);
+ break;
+
+ case 0x61: /* Shadow RAM Control 1 */
+ if ((dev->pci_conf[0][0x61] ^ val) & 0x03)
+ apollo_map(0xc0000, 0x04000, val & 0x03);
+ if ((dev->pci_conf[0][0x61] ^ val) & 0x0c)
+ apollo_map(0xc4000, 0x04000, (val & 0x0c) >> 2);
+ if ((dev->pci_conf[0][0x61] ^ val) & 0x30)
+ apollo_map(0xc8000, 0x04000, (val & 0x30) >> 4);
+ if ((dev->pci_conf[0][0x61] ^ val) & 0xc0)
+ apollo_map(0xcc000, 0x04000, (val & 0xc0) >> 6);
+ dev->pci_conf[0][0x61] = val;
+ break;
+ case 0x62: /* Shadow RAM Control 2 */
+ if ((dev->pci_conf[0][0x62] ^ val) & 0x03)
+ apollo_map(0xd0000, 0x04000, val & 0x03);
+ if ((dev->pci_conf[0][0x62] ^ val) & 0x0c)
+ apollo_map(0xd4000, 0x04000, (val & 0x0c) >> 2);
+ if ((dev->pci_conf[0][0x62] ^ val) & 0x30)
+ apollo_map(0xd8000, 0x04000, (val & 0x30) >> 4);
+ if ((dev->pci_conf[0][0x62] ^ val) & 0xc0)
+ apollo_map(0xdc000, 0x04000, (val & 0xc0) >> 6);
+ dev->pci_conf[0][0x62] = val;
+ break;
+ case 0x63: /* Shadow RAM Control 3 */
+ if ((dev->pci_conf[0][0x63] ^ val) & 0x30) {
+ apollo_map(0xf0000, 0x10000, (val & 0x30) >> 4);
+ shadowbios = (((val & 0x30) >> 4) & 0x02);
+ }
+ if ((dev->pci_conf[0][0x63] ^ val) & 0xc0)
+ apollo_map(0xe0000, 0x10000, (val & 0xc0) >> 6);
+ dev->pci_conf[0][0x63] = val;
+ if (dev->id == 0x0691) switch (val & 0x03) {
+ case 0x00:
+ default:
+ apollo_smram_map(1, 0x000a0000, 0x00020000, 1); /* SMM: Code DRAM, Data DRAM */
+ apollo_smram_map(0, 0x000a0000, 0x00020000, 0); /* Non-SMM: Code PCI, Data PCI */
+ break;
+ case 0x01:
+ apollo_smram_map(1, 0x000a0000, 0x00020000, 1); /* SMM: Code DRAM, Data DRAM */
+ apollo_smram_map(0, 0x000a0000, 0x00020000, 1); /* Non-SMM: Code DRAM, Data DRAM */
+ break;
+ case 0x02:
+ apollo_smram_map(1, 0x000a0000, 0x00020000, 3); /* SMM: Code Invalid, Data Invalid */
+ apollo_smram_map(0, 0x000a0000, 0x00020000, 2); /* Non-SMM: Code DRAM, Data PCI */
+ break;
+ case 0x03:
+ apollo_smram_map(1, 0x000a0000, 0x00020000, 1); /* SMM: Code DRAM, Data DRAM */
+ apollo_smram_map(0, 0x000a0000, 0x00020000, 3); /* Non-SMM: Code Invalid, Data Invalid */
+ break;
+ } else switch (val & 0x03) {
+ case 0x00:
+ default:
+ /* Disable SMI Address Redirection (default) */
+ apollo_smram_map(1, 0x000a0000, 0x00020000, 0);
+ if (dev->id == 0x0597)
+ apollo_smram_map(1, 0x00030000, 0x00020000, 1);
+ apollo_smram_map(0, 0x000a0000, 0x00020000, 0);
+ break;
+ case 0x01:
+ /* Allow access to DRAM Axxxx-Bxxxx for both normal and SMI cycles */
+ apollo_smram_map(1, 0x000a0000, 0x00020000, 1);
+ if (dev->id == 0x0597)
+ apollo_smram_map(1, 0x00030000, 0x00020000, 1);
+ apollo_smram_map(0, 0x000a0000, 0x00020000, 1);
+ break;
+ case 0x02:
+ /* Reserved */
+ apollo_smram_map(1, 0x000a0000, 0x00020000, 3);
+ if (dev->id == 0x0597) {
+ /* TODO: SMI 3xxxx-4xxxx redirect to Axxxx-Bxxxx
+ (this needs a 3xxxx-4xxxx mapping set to EXTERNAL). */
+ apollo_smram_map(1, 0x00030000, 0x00020000, 3);
+ }
+ apollo_smram_map(0, 0x000a0000, 0x00020000, 3);
+ break;
+ case 0x03:
+ /* Allow SMI Axxxx-Bxxxx DRAM access */
+ apollo_smram_map(1, 0x000a0000, 0x00020000, 1);
+ if (dev->id == 0x0597)
+ apollo_smram_map(1, 0x00030000, 0x00020000, 1);
+ apollo_smram_map(0, 0x000a0000, 0x00020000, 0);
+ break;
+ }
+ break;
+ case 0x68:
+ if (dev->id == 0x0597)
+ dev->pci_conf[0][0x68] = (dev->pci_conf[0][0x6b] & ~0xfe) | (val & 0xfe);
+ else if (dev->id == 0x0598)
+ dev->pci_conf[0][0x68] = val;
+ else
+ dev->pci_conf[0][0x68] = (dev->pci_conf[0][0x6b] & ~0xfd) | (val & 0xfd);
+ break;
+ case 0x6b:
+ if (dev->id == 0x0691)
+ dev->pci_conf[0][0x6b] = (dev->pci_conf[0][0x6b] & ~0xcf) | (val & 0xcf);
+ else
+ dev->pci_conf[0][0x6b] = (dev->pci_conf[0][0x6b] & ~0xc1) | (val & 0xc1);
+ break;
+ case 0x6c:
+ if (dev->id == 0x0597)
+ dev->pci_conf[0][0x6c] = (dev->pci_conf[0][0x6c] & ~0x1f) | (val & 0x1f);
+ else if (dev->id == 0x0598)
+ dev->pci_conf[0][0x6c] = (dev->pci_conf[0][0x6c] & ~0x7f) | (val & 0x7f);
+ else
+ dev->pci_conf[0][0x6c] = val;
+ break;
+ case 0x6d:
+ if (dev->id == 0x0597)
+ dev->pci_conf[0][0x6d] = (dev->pci_conf[0][0x6d] & ~0x0f) | (val & 0x0f);
+ else if (dev->id == 0x0598)
+ dev->pci_conf[0][0x6d] = (dev->pci_conf[0][0x6d] & ~0x7f) | (val & 0x7f);
+ else
+ dev->pci_conf[0][0x6d] = val;
+ break;
+ case 0x6e:
+ dev->pci_conf[0][0x6e] = (dev->pci_conf[0][0x6e] & ~0xb7) | (val & 0xb7);
+ break;
+
+ case 0x70:
+ if (dev->id == 0x0597)
+ dev->pci_conf[0][0x70] = (dev->pci_conf[0][0x70] & ~0xf1) | (val & 0xf1);
+ else
+ dev->pci_conf[0][0x70] = val;
+ break;
+ case 0x74:
+ dev->pci_conf[0][0x74] = (dev->pci_conf[0][0x74] & ~0xc0) | (val & 0xc0);
+ break;
+ case 0x75:
+ dev->pci_conf[0][0x75] = (dev->pci_conf[0][0x75] & ~0xcf) | (val & 0xcf);
+ break;
+ case 0x76:
+ dev->pci_conf[0][0x76] = (dev->pci_conf[0][0x76] & ~0xf0) | (val & 0xf0);
+ break;
+ case 0x77:
+ dev->pci_conf[0][0x77] = (dev->pci_conf[0][0x77] & ~0xc0) | (val & 0xc0);
+ break;
+ case 0x7e:
+ dev->pci_conf[0][0x7e] = (dev->pci_conf[0][0x7e] & ~0x3f) | (val & 0x3f);
+ break;
+
+ case 0x80:
+ dev->pci_conf[0][0x80] = (dev->pci_conf[0][0x80] & ~0x8f) | (val & 0x8f);
+ break;
+ case 0x84:
+ /* The datasheet first mentions 7-0 but then says 3-0 are reserved -
+ - minimum of 16 MB for the graphics aperture? */
+ dev->pci_conf[0][0x84] = (dev->pci_conf[0][0x84] & ~0xf0) | (val & 0xf0);
+ break;
+ case 0x88:
+ dev->pci_conf[0][0x88] = (dev->pci_conf[0][0x88] & ~0x07) | (val & 0x07);
+ break;
+ case 0x89:
+ dev->pci_conf[0][0x89] = (dev->pci_conf[0][0x89] & ~0xf0) | (val & 0xf0);
+ break;
+
+ case 0xa8:
+ dev->pci_conf[0][0xa8] = (dev->pci_conf[0][0xa8] & ~0x03) | (val & 0x03);
+ break;
+ case 0xa9:
+ dev->pci_conf[0][0xa9] = (dev->pci_conf[0][0xa9] & ~0x03) | (val & 0x03);
+ break;
+ case 0xac:
+ dev->pci_conf[0][0xac] = (dev->pci_conf[0][0xac] & ~0x0f) | (val & 0x0f);
+ break;
+ case 0xfc:
+ if (dev->id > 0x0597)
+ dev->pci_conf[0][0xfc] = (dev->pci_conf[0][0xfc] & ~0x01) | (val & 0x01);
+ break;
+
+ default:
+ dev->pci_conf[0][addr] = val;
+ break;
+ }
+}
+
+
+static void
+via_apollo_pci_bridge_write(int func, int addr, uint8_t val, void *priv)
+{
+ via_apollo_t *dev = (via_apollo_t *) priv;
+
+ if (func != 1)
+ return;
+
+ /*Read-only addresses*/
+
+ if ((addr < 4) || ((addr >= 5) && (addr < 7)) ||
+ ((addr >= 8) && (addr < 0x18)) || (addr == 0x1b) ||
+ ((addr >= 0x1e) && (addr < 0x20)) || ((addr >= 0x28) && (addr < 0x3e)) ||
+ (addr == 0x3f) || (addr >= 0x43))
+ return;
+
+ switch(addr) {
+ case 0x04:
+ dev->pci_conf[1][0x04] = (dev->pci_conf[1][0x04] & ~0x47) | (val & 0x47);
+ break;
+ case 0x07:
+ dev->pci_conf[1][0x07] &= ~(val & 0x30);
+ break;
+
+ case 0x20: /* Memory Base */
+ dev->pci_conf[1][0x20] = val & 0xf0;
+ break;
+ case 0x22: /* Memory Limit */
+ dev->pci_conf[1][0x22] = val & 0xf0;
+ break;
+ case 0x24: /* Prefetchable Memory Base */
+ dev->pci_conf[1][0x24] = val & 0xf0;
+ break;
+ case 0x26: /* Prefetchable Memory Limit */
+ dev->pci_conf[1][0x26] = val & 0xf0;
+ break;
+
+ case 0x3e:
+ dev->pci_conf[0][0x3e] = (dev->pci_conf[0][0x3e] & ~0x06) | (val & 0x06);
+ break;
+
+ case 0x41:
+ dev->pci_conf[0][0x41] = (dev->pci_conf[0][0x41] & ~0xfe) | (val & 0xfe);
+ break;
+ case 0x42:
+ if (dev->id == 0x0597)
+ dev->pci_conf[0][0x42] = (dev->pci_conf[0][0x42] & ~0xec) | (val & 0xec);
+ else if (dev->id == 0x0598)
+ dev->pci_conf[0][0x42] = (dev->pci_conf[0][0x42] & ~0xfc) | (val & 0xfc);
+ else
+ dev->pci_conf[0][0x42] = (dev->pci_conf[0][0x42] & ~0xf4) | (val & 0xf4);
+ break;
+
+ default:
+ dev->pci_conf[1][addr] = val;
+ break;
+ }
+}
+
+
+static uint8_t
+via_apollo_read(int func, int addr, void *priv)
+{
+ via_apollo_t *dev = (via_apollo_t *) priv;
+ uint8_t ret = 0xff;
+
+ switch(func) {
+ case 0:
+ ret = dev->pci_conf[0][addr];
+ break;
+ case 1:
+ ret = dev->pci_conf[1][addr];
+ break;
+ }
+
+ return ret;
+}
+
+
+static void
+via_apollo_write(int func, int addr, uint8_t val, void *priv)
+{
+ switch(func) {
+ case 0:
+ via_apollo_host_bridge_write(func, addr, val, priv);
+ break;
+ case 1:
+ via_apollo_pci_bridge_write(func, addr, val, priv);
+ break;
+ }
+}
+
+
+static void
+via_apollo_reset(void *priv)
+{
+ via_apollo_write(0, 0x61, 0x00, priv);
+ via_apollo_write(0, 0x62, 0x00, priv);
+ via_apollo_write(0, 0x63, 0x00, priv);
+}
+
+
+static void *
+via_apollo_init(const device_t *info)
+{
+ via_apollo_t *dev = (via_apollo_t *) malloc(sizeof(via_apollo_t));
+
+ pci_add_card(PCI_ADD_NORTHBRIDGE, via_apollo_read, via_apollo_write, dev);
+
+ dev->id = info->local;
+ via_apollo_setup(dev);
+ via_apollo_reset(dev);
+
+ return dev;
+}
+
+
+static void
+via_apollo_close(void *priv)
+{
+ via_apollo_t *dev = (via_apollo_t *) priv;
+
+ free(dev);
+}
+
+
+const device_t via_vp3_device =
+{
+ "VIA Apollo VP3",
+ DEVICE_PCI,
+ 0x0597, /*VT82C597*/
+ via_apollo_init,
+ via_apollo_close,
+ via_apollo_reset,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+const device_t via_mvp3_device =
+{
+ "VIA Apollo MVP3",
+ DEVICE_PCI,
+ 0x0598, /*VT82C598MVP*/
+ via_apollo_init,
+ via_apollo_close,
+ via_apollo_reset,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+const device_t via_apro_device = {
+ "VIA Apollo Pro",
+ DEVICE_PCI,
+ 0x0691, /*VT82C691*/
+ via_apollo_init,
+ via_apollo_close,
+ via_apollo_reset,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
diff --git a/src/chipset/via_apro.c b/src/chipset/via_apro.c
deleted file mode 100644
index a9d861069..000000000
--- a/src/chipset/via_apro.c
+++ /dev/null
@@ -1,345 +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.
-
-
-
-VIA Apollo Pro North Bridge emulation
-
-VT82C691 used in the PC Partner APAS3 board
-based on the model of VIA MVP3 by mooch & Sarah
-
-Authors: Sarah Walker,
-Copyright(C) 2020 Tiseno100
-Copyright(C) 2020 Melissa Goad
-Copyright(C) 2020 Miran Grca
-
-
-Note: Due to 99.9% similarities with the VP3, MVP3 but also other later Apollo chipsets. We probably should create a common Apollo tree
-just like the Intel 4x0 series.
-
-*/
-
-#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 via_apro_t
-{
- uint8_t pci_conf[2][256];
-} via_apro_t;
-
-static void
-apro_map(uint32_t addr, uint32_t size, int state)
-{
- switch (state & 3) {
- case 0:
- mem_set_mem_state(addr, size, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
- break;
- case 1:
- mem_set_mem_state(addr, size, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
- break;
- case 2:
- mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTANY);
- break;
- case 3:
- mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
- break;
- }
-
- flushmmucache_nopc();
-}
-
-static void
-via_apro_pci_regs(via_apro_t *dev)
-{
- memset(dev, 0, sizeof(via_apro_t));
-
-// Host Bridge registers
-
- dev->pci_conf[0][0x00] = 0x06; // VIA
- dev->pci_conf[0][0x01] = 0x11;
-
- dev->pci_conf[0][0x02] = 0x91; // VT82C691
- dev->pci_conf[0][0x03] = 0x06;
-
- dev->pci_conf[0][0x04] = 6; // Command
- dev->pci_conf[0][0x05] = 0;
-
-// These(06h-0fh) probably aren't needed but as they're referenced by the MVP3 chipset code i added them too
-
- dev->pci_conf[0][0x06] = 0; // Status
- dev->pci_conf[0][0x07] = 0;
-
- dev->pci_conf[0][0x09] = 0; // Program Interface
-
- dev->pci_conf[0][0x0a] = 0; // Sub Class Code
-
- dev->pci_conf[0][0x0b] = 0; // Base Class Code
-
- dev->pci_conf[0][0x0c] = 0; // reserved
-
- dev->pci_conf[0][0x0d] = 0; // Latency Timer
-
- dev->pci_conf[0][0x0e] = 0; // Header Type
-
- dev->pci_conf[0][0x0f] = 0; // Built-in Self test
-
- dev->pci_conf[0][0x10] = 0x08; // Graphics Aperature Base
-
- dev->pci_conf[0][0x34] = 0xa0; // Capability Pointer
-
- dev->pci_conf[0][0x56] = 1; // Bank 6 Ending
- dev->pci_conf[0][0x57] = 1; // Bank 7 Ending
- dev->pci_conf[0][0x5a] = 1; // Bank 0 Ending
- dev->pci_conf[0][0x5b] = 1; // Bank 1 Ending
- dev->pci_conf[0][0x5c] = 1; // Bank 2 Ending
- dev->pci_conf[0][0x5d] = 1; // Bank 3 Ending
- dev->pci_conf[0][0x5e] = 1; // Bank 4 Ending
- dev->pci_conf[0][0x5f] = 1; // Bank 5 Ending
-
- dev->pci_conf[0][0x64] = 0xec; // DRAM Timing for Banks 0,1
- dev->pci_conf[0][0x65] = 0xec; // DRAM Timing for Banks 2,3
- dev->pci_conf[0][0x66] = 0xec; // DRAM Timing for Banks 4,5
- dev->pci_conf[0][0x67] = 0x01; // DRAM Timing for Banks 6,7
-
- dev->pci_conf[0][0x6b] = 1; // DRAM Abritration control
-
- dev->pci_conf[0][0xa4] = 0x03; // AGP Status
- dev->pci_conf[0][0xa5] = 0x02;
- dev->pci_conf[0][0xa6] = 0;
- dev->pci_conf[0][0xa7] = 0x07;
-
-// PCI-to-PCI
-
- dev->pci_conf[1][0x00] = 0x06; // VIA
- dev->pci_conf[1][0x01] = 0x11;
-
- dev->pci_conf[1][0x02] = 0x91; // VT82C691
- dev->pci_conf[1][0x03] = 0x06;
-
- dev->pci_conf[1][0x04] = 7; // Command
- dev->pci_conf[1][0x05] = 0;
-
- dev->pci_conf[1][0x06] = 0x20; // Status
- dev->pci_conf[1][0x07] = 0x02;
-
- dev->pci_conf[1][0x09] = 0; // Program Interface
-
- dev->pci_conf[1][0x0A] = 4; // Sub Class Code
-
- dev->pci_conf[1][0x0B] = 6; // Base Class Code
-
- dev->pci_conf[1][0x0C] = 0; // reserved
-
- dev->pci_conf[1][0x0D] = 0; // Latency Timer
-
- dev->pci_conf[1][0x0E] = 1; // Header Type
-
- dev->pci_conf[1][0x0F] = 0; // Built-in Self test
-
- dev->pci_conf[1][0x1c] = 0xf0; // I/O Base
-
- dev->pci_conf[1][0x20] = 0xf0; // Memory Base
- dev->pci_conf[1][0x21] = 0xff;
- dev->pci_conf[1][0x24] = 0xf0;
- dev->pci_conf[1][0x25] = 0xff;
-
-}
-
-static void
-host_bridge_write(int func, int addr, uint8_t val, void *priv)
-{
-
-via_apro_t *dev = (via_apro_t *) priv;
-
- // Read-Only registers. Exact same as MVP3
- if ((addr < 4) || ((addr >= 5) && (addr < 7)) || ((addr >= 8) && (addr < 0xd)) || ((addr >= 0xe) && (addr < 0x12)) ||
- ((addr >= 0x14) && (addr < 0x50)) || ((addr >= 0x79) && (addr < 0x7e)) || ((addr >= 0x85) && (addr < 0x88)) ||
- ((addr >= 0x8c) && (addr < 0xa8)) || ((addr >= 0xad) && (addr < 0xfd)))
- return;
-
- switch(addr){
- case 0x04: // Command
- dev->pci_conf[0][0x04] = (dev->pci_conf[0][0x04] & ~0x40) | (val & 0x40);
-
- case 0x07: // Status
- dev->pci_conf[0][0x07] &= ~(val & 0xb0);
- break;
-
- case 0x12: //Graphics Aperature Base
- dev->pci_conf[0][0x12] = (val & 0xf0);
- break;
- case 0x13:
- dev->pci_conf[0][0x13] = val;
- break;
-
- case 0x61: // Shadow RAM control 1
- if ((dev->pci_conf[0][0x61] ^ val) & 0x03)
- apro_map(0xc0000, 0x04000, val & 0x03);
- if ((dev->pci_conf[0][0x61] ^ val) & 0x0c)
- apro_map(0xc4000, 0x04000, (val & 0x0c) >> 2);
- if ((dev->pci_conf[0][0x61] ^ val) & 0x30)
- apro_map(0xc8000, 0x04000, (val & 0x30) >> 4);
- if ((dev->pci_conf[0][0x61] ^ val) & 0xc0)
- apro_map(0xcc000, 0x04000, (val & 0xc0) >> 6);
- dev->pci_conf[0][0x61] = val;
- return;
-
- case 0x62: // Shadow RAM Control 2
- if ((dev->pci_conf[0][0x62] ^ val) & 0x03)
- apro_map(0xd0000, 0x04000, val & 0x03);
- if ((dev->pci_conf[0][0x62] ^ val) & 0x0c)
- apro_map(0xd4000, 0x04000, (val & 0x0c) >> 2);
- if ((dev->pci_conf[0][0x62] ^ val) & 0x30)
- apro_map(0xd8000, 0x04000, (val & 0x30) >> 4);
- if ((dev->pci_conf[0][0x62] ^ val) & 0xc0)
- apro_map(0xdc000, 0x04000, (val & 0xc0) >> 6);
- dev->pci_conf[0][0x62] = val;
- return;
-
- case 0x63: // Shadow RAM Control 3
- if ((dev->pci_conf[0][0x63] ^ val) & 0x30) {
- apro_map(0xf0000, 0x10000, (val & 0x30) >> 4);
- shadowbios = (((val & 0x30) >> 4) & 0x02);
- }
- if ((dev->pci_conf[0][0x63] ^ val) & 0xc0)
- apro_map(0xe0000, 0x10000, (val & 0xc0) >> 6);
- dev->pci_conf[0][0x63] = val;
- return;
-
- //In case we throw somewhere
- default:
- dev->pci_conf[0][addr] = val;
- break;
- }
-}
-
-static void
-pci_to_pci_bridge_write(int func, int addr, uint8_t val, void *priv)
-{
- via_apro_t *dev = (via_apro_t *) priv;
-
- if (func != 1)
- return;
-
- //As with MVP3. Same deal
- if ((addr < 4) || ((addr >= 5) && (addr < 7)) ||
- ((addr >= 8) && (addr < 0x18)) || (addr == 0x1b) ||
- ((addr >= 0x1e) && (addr < 0x20)) || ((addr >= 0x28) && (addr < 0x3e)) ||
- (addr >= 0x43))
- return;
-
- switch(addr) {
- case 0x04:
- dev->pci_conf[1][0x04] = (dev->pci_conf[1][0x04] & ~0x47) | (val & 0x47);
- break;
- case 0x07:
- dev->pci_conf[1][0x07] &= ~(val & 0x30);
- break;
-
- case 0x20: // Memory Base
- dev->pci_conf[1][0x20] = val & 0xf0;
- break;
-
- case 0x22: // Memory Limit
- dev->pci_conf[1][0x22] = val & 0xf0;
- break;
-
- case 0x24: // Prefetchable Memory base
- dev->pci_conf[1][0x24] = val & 0xf0;
- break;
-
- case 0x26: // Prefetchable Memory limit
- dev->pci_conf[1][0x26] = val & 0xf0;
- break;
-
- default:
- dev->pci_conf[1][addr] = val;
- break;
- }
-}
-
-static uint8_t
-via_apro_read(int func, int addr, void *priv)
-{
- via_apro_t *dev = (via_apro_t *) priv;
- uint8_t ret = 0xff;
-
- switch(func) {
- case 0:
- ret = dev->pci_conf[0][addr];
- break;
- case 1:
- ret = dev->pci_conf[1][addr];
- break;
- }
-
- return ret;
-}
-
-static void
-via_apro_write(int func, int addr, uint8_t val, void *priv)
-{
- switch(func) {
- case 0:
- host_bridge_write(func, addr, val, priv);
- break;
-
- case 1:
- pci_to_pci_bridge_write(func, addr, val, priv);
- break;
- }
-}
-
-static void
-via_apro_reset(void *priv)
-{
- via_apro_write(0, 0x63, via_apro_read(0, 0x63, priv) & 0xcf, priv);
-}
-
-static void *
-via_apro_init(const device_t *info)
-{
- via_apro_t *dev = (via_apro_t *) malloc(sizeof(via_apro_t));
-
- pci_add_card(PCI_ADD_NORTHBRIDGE, via_apro_read, via_apro_write, dev);
-
- via_apro_pci_regs(dev);
-
- return dev;
-}
-
-static void
-via_apro_close(void *priv)
-{
- via_apro_t *dev = (via_apro_t *) priv;
-
- free(dev);
-}
-
-const device_t via_apro_device = {
- "VIA Apollo Pro",
- DEVICE_PCI,
- 0,
- via_apro_init,
- via_apro_close,
- via_apro_reset,
- NULL,
- NULL,
- NULL,
- NULL
-};
\ No newline at end of file
diff --git a/src/chipset/via_mvp3.c b/src/chipset/via_mvp3.c
deleted file mode 100644
index ab1c5877e..000000000
--- a/src/chipset/via_mvp3.c
+++ /dev/null
@@ -1,324 +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 VIA MVP3 chip.
- *
- *
- *
- * Authors: Sarah Walker,
- * Miran Grca,
- * Melissa Goad,
- *
- * Copyright 2020 Miran Grca, Melissa Goad.
- */
-#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 via_mvp3_t
-{
- uint8_t pci_conf[2][256];
-} via_mvp3_t;
-
-
-static void
-mvp3_map(uint32_t addr, uint32_t size, int state)
-{
- switch (state & 3) {
- case 0:
- mem_set_mem_state(addr, size, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
- break;
- case 1:
- mem_set_mem_state(addr, size, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
- break;
- case 2:
- mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTANY);
- break;
- case 3:
- mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
- break;
- }
-
- flushmmucache_nopc();
-}
-
-
-static void
-via_mvp3_setup(via_mvp3_t *dev)
-{
- memset(dev, 0, sizeof(via_mvp3_t));
-
- /* Host Bridge */
- dev->pci_conf[0][0x00] = 0x06; /*VIA*/
- dev->pci_conf[0][0x01] = 0x11;
- dev->pci_conf[0][0x02] = 0x98; /*VT82C598MVP*/
- dev->pci_conf[0][0x03] = 0x05;
-
- dev->pci_conf[0][0x04] = 6;
- dev->pci_conf[0][0x05] = 0;
-
- dev->pci_conf[0][0x06] = 0x90;
- dev->pci_conf[0][0x07] = 0x02;
-
- dev->pci_conf[0][0x09] = 0;
- dev->pci_conf[0][0x0a] = 0;
- dev->pci_conf[0][0x0b] = 6;
- dev->pci_conf[0][0x0c] = 0;
- dev->pci_conf[0][0x0d] = 0;
- dev->pci_conf[0][0x0e] = 0;
- dev->pci_conf[0][0x0f] = 0;
- dev->pci_conf[0][0x10] = 0x08;
- dev->pci_conf[0][0x34] = 0xa0;
-
- dev->pci_conf[0][0x5a] = 0x01;
- dev->pci_conf[0][0x5b] = 0x01;
- dev->pci_conf[0][0x5c] = 0x01;
- dev->pci_conf[0][0x5d] = 0x01;
- dev->pci_conf[0][0x5e] = 0x01;
- dev->pci_conf[0][0x5f] = 0x01;
-
- dev->pci_conf[0][0x64] = 0xec;
- dev->pci_conf[0][0x65] = 0xec;
- dev->pci_conf[0][0x66] = 0xec;
- dev->pci_conf[0][0x6b] = 0x01;
-
- dev->pci_conf[0][0xa0] = 0x02;
- dev->pci_conf[0][0xa2] = 0x10;
- dev->pci_conf[0][0xa4] = 0x03;
- dev->pci_conf[0][0xa5] = 0x02;
- dev->pci_conf[0][0xa7] = 0x07;
-
- /* PCI-to-PCI Bridge */
-
- dev->pci_conf[1][0x00] = 0x06; /*VIA*/
- dev->pci_conf[1][0x01] = 0x11;
- dev->pci_conf[1][0x02] = 0x98; /*VT82C598MVP*/
- dev->pci_conf[1][0x03] = 0x85;
-
- dev->pci_conf[1][0x04] = 7;
- dev->pci_conf[1][0x05] = 0;
-
- dev->pci_conf[1][0x06] = 0x20;
- dev->pci_conf[1][0x07] = 0x02;
-
- dev->pci_conf[1][0x09] = 0;
- dev->pci_conf[1][0x0a] = 4;
- dev->pci_conf[1][0x0b] = 6;
- dev->pci_conf[1][0x0c] = 0;
- dev->pci_conf[1][0x0d] = 0;
- dev->pci_conf[1][0x0e] = 1;
- dev->pci_conf[1][0x0f] = 0;
-
- dev->pci_conf[1][0x1c] = 0xf0;
-
- dev->pci_conf[1][0x20] = 0xf0;
- dev->pci_conf[1][0x21] = 0xff;
- dev->pci_conf[1][0x24] = 0xf0;
- dev->pci_conf[1][0x25] = 0xff;
-}
-
-
-static void
-via_mvp3_host_bridge_write(int func, int addr, uint8_t val, void *priv)
-{
- via_mvp3_t *dev = (via_mvp3_t *) priv;
-
- if (func)
- return;
-
- /*Read-only addresses*/
- if ((addr < 4) || ((addr >= 5) && (addr < 7)) || ((addr >= 8) && (addr < 0xd)) ||
- ((addr >= 0xe) && (addr < 0x12)) || ((addr >= 0x14) && (addr < 0x50)) ||
- ((addr >= 0x79) && (addr < 0x7e)) || ((addr >= 0x85) && (addr < 0x88)) ||
- ((addr >= 0x8c) && (addr < 0xa8)) || ((addr >= 0xad) && (addr < 0xfd)))
- return;
-
- switch(addr) {
- case 0x04:
- dev->pci_conf[0][0x04] = (dev->pci_conf[0][0x04] & ~0x40) | (val & 0x40);
- break;
- case 0x07:
- dev->pci_conf[0][0x07] &= ~(val & 0xb0);
- break;
-
- case 0x12: /* Graphics Aperture Base */
- dev->pci_conf[0][0x12] = (val & 0xf0);
- break;
- case 0x13: /* Graphics Aperture Base */
- dev->pci_conf[0][0x13] = val;
- break;
-
- case 0x61: /* Shadow RAM Control 1 */
- if ((dev->pci_conf[0][0x61] ^ val) & 0x03)
- mvp3_map(0xc0000, 0x04000, val & 0x03);
- if ((dev->pci_conf[0][0x61] ^ val) & 0x0c)
- mvp3_map(0xc4000, 0x04000, (val & 0x0c) >> 2);
- if ((dev->pci_conf[0][0x61] ^ val) & 0x30)
- mvp3_map(0xc8000, 0x04000, (val & 0x30) >> 4);
- if ((dev->pci_conf[0][0x61] ^ val) & 0xc0)
- mvp3_map(0xcc000, 0x04000, (val & 0xc0) >> 6);
- dev->pci_conf[0][0x61] = val;
- return;
- case 0x62: /* Shadow RAM Control 2 */
- if ((dev->pci_conf[0][0x62] ^ val) & 0x03)
- mvp3_map(0xd0000, 0x04000, val & 0x03);
- if ((dev->pci_conf[0][0x62] ^ val) & 0x0c)
- mvp3_map(0xd4000, 0x04000, (val & 0x0c) >> 2);
- if ((dev->pci_conf[0][0x62] ^ val) & 0x30)
- mvp3_map(0xd8000, 0x04000, (val & 0x30) >> 4);
- if ((dev->pci_conf[0][0x62] ^ val) & 0xc0)
- mvp3_map(0xdc000, 0x04000, (val & 0xc0) >> 6);
- dev->pci_conf[0][0x62] = val;
- return;
- case 0x63: /* Shadow RAM Control 3 */
- if ((dev->pci_conf[0][0x63] ^ val) & 0x30) {
- mvp3_map(0xf0000, 0x10000, (val & 0x30) >> 4);
- shadowbios = (((val & 0x30) >> 4) & 0x02);
- }
- if ((dev->pci_conf[0][0x63] ^ val) & 0xc0)
- mvp3_map(0xe0000, 0x10000, (val & 0xc0) >> 6);
- dev->pci_conf[0][0x63] = val;
- return;
-
- default:
- dev->pci_conf[0][addr] = val;
- break;
- }
-}
-
-
-static void
-via_mvp3_pci_bridge_write(int func, int addr, uint8_t val, void *priv)
-{
- via_mvp3_t *dev = (via_mvp3_t *) priv;
-
- if (func != 1)
- return;
-
- /*Read-only addresses*/
-
- if ((addr < 4) || ((addr >= 5) && (addr < 7)) ||
- ((addr >= 8) && (addr < 0x18)) || (addr == 0x1b) ||
- ((addr >= 0x1e) && (addr < 0x20)) || ((addr >= 0x28) && (addr < 0x3e)) ||
- (addr >= 0x43))
- return;
-
- switch(addr) {
- case 0x04:
- dev->pci_conf[1][0x04] = (dev->pci_conf[1][0x04] & ~0x47) | (val & 0x47);
- break;
- case 0x07:
- dev->pci_conf[1][0x07] &= ~(val & 0x30);
- break;
-
- case 0x20: /* Memory Base */
- dev->pci_conf[1][0x20] = val & 0xf0;
- break;
- case 0x22: /* Memory Limit */
- dev->pci_conf[1][0x22] = val & 0xf0;
- break;
- case 0x24: /* Prefetchable Memory Base */
- dev->pci_conf[1][0x24] = val & 0xf0;
- break;
- case 0x26: /* Prefetchable Memory Limit */
- dev->pci_conf[1][0x26] = val & 0xf0;
- break;
-
- default:
- dev->pci_conf[1][addr] = val;
- break;
- }
-}
-
-
-static uint8_t
-via_mvp3_read(int func, int addr, void *priv)
-{
- via_mvp3_t *dev = (via_mvp3_t *) priv;
- uint8_t ret = 0xff;
-
- switch(func) {
- case 0:
- ret = dev->pci_conf[0][addr];
- break;
- case 1:
- ret = dev->pci_conf[1][addr];
- break;
- }
-
- return ret;
-}
-
-
-static void
-via_mvp3_write(int func, int addr, uint8_t val, void *priv)
-{
- switch(func) {
- case 0:
- via_mvp3_host_bridge_write(func, addr, val, priv);
- break;
- case 1:
- via_mvp3_pci_bridge_write(func, addr, val, priv);
- break;
- }
-}
-
-
-static void
-via_mvp3_reset(void *priv)
-{
- via_mvp3_write(0, 0x63, via_mvp3_read(0, 0x63, priv) & 0xcf, priv);
-}
-
-
-static void *
-via_mvp3_init(const device_t *info)
-{
- via_mvp3_t *dev = (via_mvp3_t *) malloc(sizeof(via_mvp3_t));
-
- pci_add_card(PCI_ADD_NORTHBRIDGE, via_mvp3_read, via_mvp3_write, dev);
-
- via_mvp3_setup(dev);
-
- return dev;
-}
-
-
-static void
-via_mvp3_close(void *priv)
-{
- via_mvp3_t *dev = (via_mvp3_t *) priv;
-
- free(dev);
-}
-
-
-const device_t via_mvp3_device =
-{
- "VIA MVP3",
- DEVICE_PCI,
- 0,
- via_mvp3_init,
- via_mvp3_close,
- via_mvp3_reset,
- NULL,
- NULL,
- NULL,
- NULL
-};
diff --git a/src/cpu_common/386.c b/src/cpu_common/386.c
index 7768b5831..d9c6e2567 100644
--- a/src/cpu_common/386.c
+++ b/src/cpu_common/386.c
@@ -234,6 +234,10 @@ exec386(int cycs)
fetchdat = fastreadl(cs + cpu_state.pc);
if (!cpu_state.abrt) {
+#ifdef ENABLE_386_LOG
+ if (in_smm)
+ x386_log("[%04X:%08X] %08X\n", CS, cpu_state.pc, fetchdat);
+#endif
opcode = fetchdat & 0xFF;
fetchdat >>= 8;
trap = cpu_state.flags & T_FLAG;
@@ -242,7 +246,11 @@ exec386(int cycs)
x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat);
if (x86_was_reset)
break;
- }
+ } else
+#ifdef ENABLE_386_LOG
+ if (in_smm)
+ x386_log("[%04X:%08X] ABRT\n", CS, cpu_state.pc);
+#endif
#ifndef USE_NEW_DYNAREC
if (!use32) cpu_state.pc &= 0xffff;
@@ -272,12 +280,25 @@ exec386(int cycs)
}
}
- if (!in_smm && smi_line/* && is_pentium*/) {
+ if ((in_smm == 0) && smi_line) {
+#ifdef ENABLE_386_LOG
+ x386_log("SMI while not in SMM\n");
+#endif
enter_smm();
smi_line = 0;
- } else if (in_smm && smi_line/* && is_pentium*/) {
+ } else if ((in_smm == 1) && smi_line) {
+ /* Mark this so that we don't latch more than one SMI. */
+#ifdef ENABLE_386_LOG
+ x386_log("SMI while in unlatched SMM\n");
+#endif
smi_latched = 1;
smi_line = 0;
+ } else if ((in_smm == 2) && smi_line) {
+ /* Mark this so that we don't latch more than one SMI. */
+#ifdef ENABLE_386_LOG
+ x386_log("SMI while in latched SMM\n");
+#endif
+ smi_line = 0;
}
ins_cycles -= cycles;
diff --git a/src/cpu_common/386_dynarec - Cópia (2).c b/src/cpu_common/386_dynarec - Cópia (2).c
deleted file mode 100644
index 7a248b627..000000000
--- a/src/cpu_common/386_dynarec - Cópia (2).c
+++ /dev/null
@@ -1,910 +0,0 @@
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#ifndef INFINITY
-# define INFINITY (__builtin_inff())
-#endif
-
-#define HAVE_STDARG_H
-#include <86box/86box.h>
-#include "cpu.h"
-#include "x86.h"
-#include "x86_ops.h"
-#include "x87.h"
-#include <86box/io.h>
-#include <86box/mem.h>
-#include <86box/nmi.h>
-#include <86box/pic.h>
-#include <86box/timer.h>
-#include <86box/fdd.h>
-#include <86box/fdc.h>
-#ifdef USE_DYNAREC
-#include "codegen.h"
-#ifdef USE_NEW_DYNAREC
-#include "codegen_backend.h"
-#endif
-#endif
-#include "386_common.h"
-
-
-#define CPU_BLOCK_END() cpu_block_end = 1
-
-
-int inrecomp = 0, cpu_block_end = 0;
-int cpu_recomp_blocks, cpu_recomp_full_ins, cpu_new_blocks;
-int cpu_recomp_blocks_latched, cpu_recomp_ins_latched, cpu_recomp_full_ins_latched, cpu_new_blocks_latched;
-
-
-#ifdef ENABLE_386_DYNAREC_LOG
-int x386_dynarec_do_log = ENABLE_386_DYNAREC_LOG;
-
-
-void
-x386_dynarec_log(const char *fmt, ...)
-{
- va_list ap;
-
- if (x386_dynarec_do_log) {
- va_start(ap, fmt);
- pclog_ex(fmt, ap);
- va_end(ap);
- }
-}
-#else
-#define x386_dynarec_log(fmt, ...)
-#endif
-
-
-static __inline void fetch_ea_32_long(uint32_t rmdat)
-{
- eal_r = eal_w = NULL;
- easeg = cpu_state.ea_seg->base;
- if (cpu_rm == 4)
- {
- uint8_t sib = rmdat >> 8;
-
- switch (cpu_mod)
- {
- case 0:
- cpu_state.eaaddr = cpu_state.regs[sib & 7].l;
- cpu_state.pc++;
- break;
- case 1:
- cpu_state.pc++;
- cpu_state.eaaddr = ((uint32_t)(int8_t)getbyte()) + cpu_state.regs[sib & 7].l;
- break;
- case 2:
- cpu_state.eaaddr = (fastreadl(cs + cpu_state.pc + 1)) + cpu_state.regs[sib & 7].l;
- cpu_state.pc += 5;
- break;
- }
- /*SIB byte present*/
- if ((sib & 7) == 5 && !cpu_mod)
- cpu_state.eaaddr = getlong();
- else if ((sib & 6) == 4 && !cpu_state.ssegs)
- {
- easeg = ss;
- cpu_state.ea_seg = &cpu_state.seg_ss;
- }
- if (((sib >> 3) & 7) != 4)
- cpu_state.eaaddr += cpu_state.regs[(sib >> 3) & 7].l << (sib >> 6);
- }
- else
- {
- cpu_state.eaaddr = cpu_state.regs[cpu_rm].l;
- if (cpu_mod)
- {
- if (cpu_rm == 5 && !cpu_state.ssegs)
- {
- easeg = ss;
- cpu_state.ea_seg = &cpu_state.seg_ss;
- }
- if (cpu_mod == 1)
- {
- cpu_state.eaaddr += ((uint32_t)(int8_t)(rmdat >> 8));
- cpu_state.pc++;
- }
- else
- {
- cpu_state.eaaddr += getlong();
- }
- }
- else if (cpu_rm == 5)
- {
- cpu_state.eaaddr = getlong();
- }
- }
- if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC)
- {
- uint32_t addr = easeg + cpu_state.eaaddr;
- if ( readlookup2[addr >> 12] != -1)
- eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr);
- if (writelookup2[addr >> 12] != -1)
- eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr);
- }
- cpu_state.last_ea = cpu_state.eaaddr;
-}
-
-static __inline void fetch_ea_16_long(uint32_t rmdat)
-{
- eal_r = eal_w = NULL;
- easeg = cpu_state.ea_seg->base;
- if (!cpu_mod && cpu_rm == 6)
- {
- cpu_state.eaaddr = getword();
- }
- else
- {
- switch (cpu_mod)
- {
- case 0:
- cpu_state.eaaddr = 0;
- break;
- case 1:
- cpu_state.eaaddr = (uint16_t)(int8_t)(rmdat >> 8); cpu_state.pc++;
- break;
- case 2:
- cpu_state.eaaddr = getword();
- break;
- }
- cpu_state.eaaddr += (*mod1add[0][cpu_rm]) + (*mod1add[1][cpu_rm]);
- if (mod1seg[cpu_rm] == &ss && !cpu_state.ssegs)
- {
- easeg = ss;
- cpu_state.ea_seg = &cpu_state.seg_ss;
- }
- cpu_state.eaaddr &= 0xFFFF;
- }
- if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC)
- {
- uint32_t addr = easeg + cpu_state.eaaddr;
- if ( readlookup2[addr >> 12] != -1)
- eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr);
- if (writelookup2[addr >> 12] != -1)
- eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr);
- }
- cpu_state.last_ea = cpu_state.eaaddr;
-}
-
-#define fetch_ea_16(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_16_long(rmdat); if (cpu_state.abrt) return 1; }
-#define fetch_ea_32(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_32_long(rmdat); } if (cpu_state.abrt) return 1
-
-#include "x86_flags.h"
-
-
-/*Prefetch emulation is a fairly simplistic model:
- - All instruction bytes must be fetched before it starts.
- - Cycles used for non-instruction memory accesses are counted and subtracted
- from the total cycles taken
- - Any remaining cycles are used to refill the prefetch queue.
-
- Note that this is only used for 286 / 386 systems. It is disabled when the
- internal cache on 486+ CPUs is enabled.
-*/
-static int prefetch_bytes = 0;
-static int prefetch_prefixes = 0;
-
-static void prefetch_run(int instr_cycles, int bytes, int modrm, int reads, int reads_l, int writes, int writes_l, int ea32)
-{
- int mem_cycles = reads*cpu_cycles_read + reads_l*cpu_cycles_read_l + writes*cpu_cycles_write + writes_l*cpu_cycles_write_l;
-
- if (instr_cycles < mem_cycles)
- instr_cycles = mem_cycles;
-
- prefetch_bytes -= prefetch_prefixes;
- prefetch_bytes -= bytes;
- if (modrm != -1)
- {
- if (ea32)
- {
- if ((modrm & 7) == 4)
- {
- if ((modrm & 0x700) == 0x500)
- prefetch_bytes -= 5;
- else if ((modrm & 0xc0) == 0x40)
- prefetch_bytes -= 2;
- else if ((modrm & 0xc0) == 0x80)
- prefetch_bytes -= 5;
- }
- else
- {
- if ((modrm & 0xc7) == 0x05)
- prefetch_bytes -= 4;
- else if ((modrm & 0xc0) == 0x40)
- prefetch_bytes--;
- else if ((modrm & 0xc0) == 0x80)
- prefetch_bytes -= 4;
- }
- }
- else
- {
- if ((modrm & 0xc7) == 0x06)
- prefetch_bytes -= 2;
- else if ((modrm & 0xc0) != 0xc0)
- prefetch_bytes -= ((modrm & 0xc0) >> 6);
- }
- }
-
- /* Fill up prefetch queue */
- while (prefetch_bytes < 0)
- {
- prefetch_bytes += cpu_prefetch_width;
- cycles -= cpu_prefetch_cycles;
- }
-
- /* Subtract cycles used for memory access by instruction */
- instr_cycles -= mem_cycles;
-
- while (instr_cycles >= cpu_prefetch_cycles)
- {
- prefetch_bytes += cpu_prefetch_width;
- instr_cycles -= cpu_prefetch_cycles;
- }
-
- prefetch_prefixes = 0;
- if (prefetch_bytes > 16)
- prefetch_bytes = 16;
-}
-
-static void prefetch_flush()
-{
- prefetch_bytes = 0;
-}
-
-#define PREFETCH_RUN(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32) \
- do { if (cpu_prefetch_cycles) prefetch_run(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32); } while (0)
-
-#define PREFETCH_PREFIX() do { if (cpu_prefetch_cycles) prefetch_prefixes++; } while (0)
-#define PREFETCH_FLUSH() prefetch_flush()
-
-
-void enter_smm()
-{
- uint32_t smram_state = smbase + 0xfe00;
- uint32_t old_cr0 = cr0;
- uint32_t old_flags = cpu_state.flags | ((uint32_t)cpu_state.eflags << 16);
-
- cr0 &= ~0x8000000d;
- cpu_state.flags = 2;
- cpu_state.eflags = 0;
-
- in_smm = 1;
- mem_set_mem_state(smbase, 131072, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
- smi_latched = 1;
-
- mem_writel_phys(smram_state + 0xf8, smbase);
- mem_writel_phys(smram_state + 0x128, cr4);
- mem_writel_phys(smram_state + 0x130, cpu_state.seg_es.limit);
- mem_writel_phys(smram_state + 0x134, cpu_state.seg_es.base);
- mem_writel_phys(smram_state + 0x138, cpu_state.seg_es.access);
- mem_writel_phys(smram_state + 0x13c, cpu_state.seg_cs.limit);
- mem_writel_phys(smram_state + 0x140, cpu_state.seg_cs.base);
- mem_writel_phys(smram_state + 0x144, cpu_state.seg_cs.access);
- mem_writel_phys(smram_state + 0x148, cpu_state.seg_ss.limit);
- mem_writel_phys(smram_state + 0x14c, cpu_state.seg_ss.base);
- mem_writel_phys(smram_state + 0x150, cpu_state.seg_ss.access);
- mem_writel_phys(smram_state + 0x154, cpu_state.seg_ds.limit);
- mem_writel_phys(smram_state + 0x158, cpu_state.seg_ds.base);
- mem_writel_phys(smram_state + 0x15c, cpu_state.seg_ds.access);
- mem_writel_phys(smram_state + 0x160, cpu_state.seg_fs.limit);
- mem_writel_phys(smram_state + 0x164, cpu_state.seg_fs.base);
- mem_writel_phys(smram_state + 0x168, cpu_state.seg_fs.access);
- mem_writel_phys(smram_state + 0x16c, cpu_state.seg_gs.limit);
- mem_writel_phys(smram_state + 0x170, cpu_state.seg_gs.base);
- mem_writel_phys(smram_state + 0x174, cpu_state.seg_gs.access);
- mem_writel_phys(smram_state + 0x178, ldt.limit);
- mem_writel_phys(smram_state + 0x17c, ldt.base);
- mem_writel_phys(smram_state + 0x180, ldt.access);
- mem_writel_phys(smram_state + 0x184, gdt.limit);
- mem_writel_phys(smram_state + 0x188, gdt.base);
- mem_writel_phys(smram_state + 0x18c, gdt.access);
- mem_writel_phys(smram_state + 0x190, idt.limit);
- mem_writel_phys(smram_state + 0x194, idt.base);
- mem_writel_phys(smram_state + 0x198, idt.access);
- mem_writel_phys(smram_state + 0x19c, tr.limit);
- mem_writel_phys(smram_state + 0x1a0, tr.base);
- mem_writel_phys(smram_state + 0x1a4, tr.access);
-
- mem_writel_phys(smram_state + 0x1a8, cpu_state.seg_es.seg);
- mem_writel_phys(smram_state + 0x1ac, cpu_state.seg_cs.seg);
- mem_writel_phys(smram_state + 0x1b0, cpu_state.seg_ss.seg);
- mem_writel_phys(smram_state + 0x1b4, cpu_state.seg_ds.seg);
- mem_writel_phys(smram_state + 0x1b8, cpu_state.seg_fs.seg);
- mem_writel_phys(smram_state + 0x1bc, cpu_state.seg_gs.seg);
- mem_writel_phys(smram_state + 0x1c0, ldt.seg);
- mem_writel_phys(smram_state + 0x1c4, tr.seg);
-
- mem_writel_phys(smram_state + 0x1c8, dr[7]);
- mem_writel_phys(smram_state + 0x1cc, dr[6]);
- mem_writel_phys(smram_state + 0x1d0, EAX);
- mem_writel_phys(smram_state + 0x1d4, ECX);
- mem_writel_phys(smram_state + 0x1d8, EDX);
- mem_writel_phys(smram_state + 0x1dc, EBX);
- mem_writel_phys(smram_state + 0x1e0, ESP);
- mem_writel_phys(smram_state + 0x1e4, EBP);
- mem_writel_phys(smram_state + 0x1e8, ESI);
- mem_writel_phys(smram_state + 0x1ec, EDI);
- mem_writel_phys(smram_state + 0x1f0, cpu_state.pc);
- mem_writel_phys(smram_state + 0x1d0, old_flags);
- mem_writel_phys(smram_state + 0x1f8, cr3);
- mem_writel_phys(smram_state + 0x1fc, old_cr0);
-
- ds = es = fs_seg = gs = ss = 0;
-
- DS = ES = FS = GS = SS = 0;
-
- cpu_state.seg_ds.limit = cpu_state.seg_es.limit = cpu_state.seg_fs.limit = cpu_state.seg_gs.limit
- = cpu_state.seg_ss.limit = 0xffffffff;
-
- cpu_state.seg_ds.limit_high = cpu_state.seg_es.limit_high = cpu_state.seg_fs.limit_high
- = cpu_state.seg_gs.limit_high = cpu_state.seg_ss.limit_high = 0xffffffff;
-
- cpu_state.seg_ds.limit_low = cpu_state.seg_es.limit_low = cpu_state.seg_fs.limit_low
- = cpu_state.seg_gs.limit_low = cpu_state.seg_ss.limit_low = 0;
-
- cpu_state.seg_ds.access = cpu_state.seg_es.access = cpu_state.seg_fs.access
- = cpu_state.seg_gs.access = cpu_state.seg_ss.access = 0x93;
-
- cpu_state.seg_ds.checked = cpu_state.seg_es.checked = cpu_state.seg_fs.checked
- = cpu_state.seg_gs.checked = cpu_state.seg_ss.checked = 1;
-
- CS = 0x3000;
- cs = smbase;
- cpu_state.seg_cs.limit = cpu_state.seg_cs.limit_high = 0xffffffff;
- cpu_state.seg_cs.limit_low = 0;
- cpu_state.seg_cs.access = 0x93;
- cpu_state.seg_cs.checked = 1;
-
- cr4 = 0;
- dr[7] = 0x400;
- cpu_state.pc = 0x8000;
-
- nmi_mask = 0;
-}
-
-void leave_smm()
-{
- uint32_t smram_state = smbase + 0xfe00;
-
- smbase = mem_readl_phys(smram_state + 0xf8);
- cr4 = mem_readl_phys(smram_state + 0x128);
-
- cpu_state.seg_es.limit = cpu_state.seg_es.limit_high = mem_readl_phys(smram_state + 0x130);
- cpu_state.seg_es.base = mem_readl_phys(smram_state + 0x134);
- cpu_state.seg_es.limit_low = cpu_state.seg_es.base;
- cpu_state.seg_es.access = mem_readl_phys(smram_state + 0x138);
-
- cpu_state.seg_cs.limit = cpu_state.seg_cs.limit_high = mem_readl_phys(smram_state + 0x13c);
- cpu_state.seg_cs.base = mem_readl_phys(smram_state + 0x140);
- cpu_state.seg_cs.limit_low = cpu_state.seg_cs.base;
- cpu_state.seg_cs.access = mem_readl_phys(smram_state + 0x144);
-
- cpu_state.seg_ss.limit = cpu_state.seg_ss.limit_high = mem_readl_phys(smram_state + 0x148);
- cpu_state.seg_ss.base = mem_readl_phys(smram_state + 0x14c);
- cpu_state.seg_ss.limit_low = cpu_state.seg_ss.base;
- cpu_state.seg_ss.access = mem_readl_phys(smram_state + 0x150);
-
- cpu_state.seg_ds.limit = cpu_state.seg_ds.limit_high = mem_readl_phys(smram_state + 0x154);
- cpu_state.seg_ds.base = mem_readl_phys(smram_state + 0x158);
- cpu_state.seg_ds.limit_low = cpu_state.seg_ds.base;
- cpu_state.seg_ds.access = mem_readl_phys(smram_state + 0x15c);
-
- cpu_state.seg_fs.limit = cpu_state.seg_fs.limit_high = mem_readl_phys(smram_state + 0x160);
- cpu_state.seg_fs.base = mem_readl_phys(smram_state + 0x164);
- cpu_state.seg_fs.limit_low = cpu_state.seg_fs.base;
- cpu_state.seg_fs.access = mem_readl_phys(smram_state + 0x168);
-
- cpu_state.seg_gs.limit = cpu_state.seg_gs.limit_high = mem_readl_phys(smram_state + 0x16c);
- cpu_state.seg_gs.base = mem_readl_phys(smram_state + 0x170);
- cpu_state.seg_gs.limit_low = cpu_state.seg_gs.base;
- cpu_state.seg_gs.access = mem_readl_phys(smram_state + 0x174);
-
- ldt.limit = ldt.limit_high = mem_readl_phys(smram_state + 0x178);
- ldt.base = mem_readl_phys(smram_state + 0x17c);
- ldt.limit_low = ldt.base;
- ldt.access = mem_readl_phys(smram_state + 0x180);
-
- gdt.limit = gdt.limit_high = mem_readl_phys(smram_state + 0x184);
- gdt.base = mem_readl_phys(smram_state + 0x188);
- gdt.limit_low = gdt.base;
- gdt.access = mem_readl_phys(smram_state + 0x18c);
-
- idt.limit = idt.limit_high = mem_readl_phys(smram_state + 0x190);
- idt.base = mem_readl_phys(smram_state + 0x194);
- idt.limit_low = idt.base;
- idt.access = mem_readl_phys(smram_state + 0x198);
-
- tr.limit = tr.limit_high = mem_readl_phys(smram_state + 0x19c);
- tr.base = mem_readl_phys(smram_state + 0x1a0);
- tr.limit_low = tr.base;
- tr.access = mem_readl_phys(smram_state + 0x1a4);
-
- ES = mem_readl_phys(smram_state + 0x1a8);
- CS = mem_readl_phys(smram_state + 0x1ac);
- SS = mem_readl_phys(smram_state + 0x1b0);
- DS = mem_readl_phys(smram_state + 0x1b4);
- FS = mem_readl_phys(smram_state + 0x1b8);
- GS = mem_readl_phys(smram_state + 0x1bc);
- ldt.seg = mem_readl_phys(smram_state + 0x1c0);
- tr.seg = mem_readl_phys(smram_state + 0x1c4);
-
- dr[7] = mem_readl_phys(smram_state + 0x1c8);
- dr[6] = mem_readl_phys(smram_state + 0x1cc);
- EAX = mem_readl_phys(smram_state + 0x1d0);
- ECX = mem_readl_phys(smram_state + 0x1d4);
- EDX = mem_readl_phys(smram_state + 0x1d8);
- EBX = mem_readl_phys(smram_state + 0x1dc);
- ESP = mem_readl_phys(smram_state + 0x1e0);
- EBP = mem_readl_phys(smram_state + 0x1e4);
- ESI = mem_readl_phys(smram_state + 0x1e8);
- EDI = mem_readl_phys(smram_state + 0x1ec);
-
- cpu_state.pc = mem_readl_phys(smram_state + 0x1f0);
- uint32_t new_flags = mem_readl_phys(smram_state + 0x1f4);
- cpu_state.flags = new_flags & 0xffff;
- cpu_state.eflags = new_flags >> 16;
- cr3 = mem_readl_phys(smram_state + 0x1f8);
- cr0 = mem_readl_phys(smram_state + 0x1fc);
-
- cpu_state.seg_cs.access &= ~0x60;
- cpu_state.seg_cs.access |= cpu_state.seg_ss.access & 0x60; //cpl is dpl of ss
-
- if((cr0 & 1) && !(cpu_state.eflags&VM_FLAG))
- {
- cpu_state.seg_cs.checked = CS ? 1 : 0;
- cpu_state.seg_ds.checked = DS ? 1 : 0;
- cpu_state.seg_es.checked = ES ? 1 : 0;
- cpu_state.seg_fs.checked = FS ? 1 : 0;
- cpu_state.seg_gs.checked = GS ? 1 : 0;
- cpu_state.seg_ss.checked = SS ? 1 : 0;
- }
- else
- {
- cpu_state.seg_cs.checked = cpu_state.seg_ds.checked = cpu_state.seg_es.checked
- = cpu_state.seg_fs.checked = cpu_state.seg_gs.checked = cpu_state.seg_ss.checked = 1;
- }
-
- mem_restore_mem_state(smbase, 131072);
- in_smm = 0;
-
- nmi_mask = 1;
-}
-
-#define OP_TABLE(name) ops_ ## name
-#define CLOCK_CYCLES(c) cycles -= (c)
-#define CLOCK_CYCLES_ALWAYS(c) cycles -= (c)
-
-#include "386_ops.h"
-
-
-#define CACHE_ON() (!(cr0 & (1 << 30)) && !(cpu_state.flags & T_FLAG))
-
-#ifdef USE_DYNAREC
-static int cycles_main = 0;
-
-
-void exec386_dynarec(int cycs)
-{
- int vector;
- uint32_t addr;
- int tempi;
- int cycdiff;
- int oldcyc;
- uint32_t start_pc = 0;
-
- int cyc_period = cycs / 2000; /*5us*/
-
- cycles_main += cycs;
- while (cycles_main > 0)
- {
- int cycles_start;
-
- cycles += cyc_period;
- cycles_start = cycles;
-
- while (cycles>0)
- {
- oldcs = CS;
- cpu_state.oldpc = cpu_state.pc;
- oldcpl = CPL;
- cpu_state.op32 = use32;
-
-
- cycdiff=0;
- oldcyc=cycles;
- if (!CACHE_ON()) /*Interpret block*/
- {
- cpu_block_end = 0;
- x86_was_reset = 0;
- while (!cpu_block_end)
- {
- oldcs=CS;
- cpu_state.oldpc = cpu_state.pc;
- oldcpl = CPL;
- cpu_state.op32 = use32;
-
- cpu_state.ea_seg = &cpu_state.seg_ds;
- cpu_state.ssegs = 0;
-
- fetchdat = fastreadl(cs + cpu_state.pc);
- if (!cpu_state.abrt)
- {
- opcode = fetchdat & 0xFF;
- fetchdat >>= 8;
- trap = cpu_state.flags & T_FLAG;
-
- cpu_state.pc++;
- x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat);
- }
-
- if (!use32) cpu_state.pc &= 0xffff;
-
- if (((cs + cpu_state.pc) >> 12) != pccache)
- CPU_BLOCK_END();
-
-/* if (ssegs)
- {
- ds=oldds;
- ss=oldss;
- ssegs=0;
- }*/
-
- if (in_smm && smi_line && is_pentium)
- CPU_BLOCK_END();
-
- if (cpu_state.abrt)
- CPU_BLOCK_END();
- if (trap)
- CPU_BLOCK_END();
-
- if (nmi && nmi_enable && nmi_mask)
- CPU_BLOCK_END();
-
- ins++;
-
-/* if ((cs + pc) == 4)
- fatal("4\n");*/
-/* if (ins >= 141400000)
- output = 3;*/
- }
- }
- else
- {
- uint32_t phys_addr = get_phys(cs+cpu_state.pc);
- int hash = HASH(phys_addr);
- codeblock_t *block = codeblock_hash[hash];
- int valid_block = 0;
- trap = 0;
-
- if (block && !cpu_state.abrt)
- {
- page_t *page = &pages[phys_addr >> 12];
-
- /*Block must match current CS, PC, code segment size,
- and physical address. The physical address check will
- also catch any page faults at this stage*/
- valid_block = (block->pc == cs + cpu_state.pc) && (block->_cs == cs) &&
- (block->phys == phys_addr) && !((block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) &&
- ((block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK));
- if (!valid_block)
- {
- uint64_t mask = (uint64_t)1 << ((phys_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK);
-
- if (page->code_present_mask[(phys_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] & mask)
- {
- /*Walk page tree to see if we find the correct block*/
- codeblock_t *new_block = codeblock_tree_find(phys_addr, cs);
- if (new_block)
- {
- valid_block = (new_block->pc == cs + cpu_state.pc) && (new_block->_cs == cs) &&
- (new_block->phys == phys_addr) && !((new_block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) &&
- ((new_block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK));
- if (valid_block)
- block = new_block;
- }
- }
- }
-
- if (valid_block && (block->page_mask & *block->dirty_mask))
- {
- codegen_check_flush(page, page->dirty_mask[(phys_addr >> 10) & 3], phys_addr);
- page->dirty_mask[(phys_addr >> 10) & 3] = 0;
- if (!block->valid)
- valid_block = 0;
- }
- if (valid_block && block->page_mask2)
- {
- /*We don't want the second page to cause a page
- fault at this stage - that would break any
- code crossing a page boundary where the first
- page is present but the second isn't. Instead
- allow the first page to be interpreted and for
- the page fault to occur when the page boundary
- is actually crossed.*/
- uint32_t phys_addr_2 = get_phys_noabrt(block->endpc);
- page_t *page_2 = &pages[phys_addr_2 >> 12];
-
- if ((block->phys_2 ^ phys_addr_2) & ~0xfff)
- valid_block = 0;
- else if (block->page_mask2 & *block->dirty_mask2)
- {
- codegen_check_flush(page_2, page_2->dirty_mask[(phys_addr_2 >> 10) & 3], phys_addr_2);
- page_2->dirty_mask[(phys_addr_2 >> 10) & 3] = 0;
- if (!block->valid)
- valid_block = 0;
- }
- }
- if (valid_block && block->was_recompiled && (block->flags & CODEBLOCK_STATIC_TOP) && block->TOP != cpu_state.TOP)
- {
- /*FPU top-of-stack does not match the value this block was compiled
- with, re-compile using dynamic top-of-stack*/
- block->flags &= ~CODEBLOCK_STATIC_TOP;
- block->was_recompiled = 0;
- }
- }
-
- if (valid_block && block->was_recompiled)
- {
- void (*code)() = (void *)&block->data[BLOCK_START];
-
- codeblock_hash[hash] = block;
-
-inrecomp=1;
- code();
-inrecomp=0;
- if (!use32) cpu_state.pc &= 0xffff;
- cpu_recomp_blocks++;
- }
- else if (valid_block && !cpu_state.abrt)
- {
- start_pc = cpu_state.pc;
-
- cpu_block_end = 0;
- x86_was_reset = 0;
-
- cpu_new_blocks++;
-
- codegen_block_start_recompile(block);
- codegen_in_recompile = 1;
-
- while (!cpu_block_end)
- {
- oldcs=CS;
- cpu_state.oldpc = cpu_state.pc;
- oldcpl = CPL;
- cpu_state.op32 = use32;
-
- cpu_state.ea_seg = &cpu_state.seg_ds;
- cpu_state.ssegs = 0;
-
- fetchdat = fastreadl(cs + cpu_state.pc);
- if (!cpu_state.abrt)
- {
- opcode = fetchdat & 0xFF;
- fetchdat >>= 8;
- trap = cpu_state.flags & T_FLAG;
-
- cpu_state.pc++;
-
- codegen_generate_call(opcode, x86_opcodes[(opcode | cpu_state.op32) & 0x3ff], fetchdat, cpu_state.pc, cpu_state.pc-1);
-
- x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat);
-
- if (x86_was_reset)
- break;
- }
-
- if (!use32) cpu_state.pc &= 0xffff;
-
- /*Cap source code at 4000 bytes per block; this
- will prevent any block from spanning more than
- 2 pages. In practice this limit will never be
- hit, as host block size is only 2kB*/
- if ((cpu_state.pc - start_pc) > 1000)
- CPU_BLOCK_END();
-
- if (in_smm && smi_line && is_pentium)
- CPU_BLOCK_END();
-
- if (trap)
- CPU_BLOCK_END();
-
- if (nmi && nmi_enable && nmi_mask)
- CPU_BLOCK_END();
-
-
- if (cpu_state.abrt)
- {
- codegen_block_remove();
- CPU_BLOCK_END();
- }
-
- ins++;
- }
-
- if (!cpu_state.abrt && !x86_was_reset)
- codegen_block_end_recompile(block);
-
- if (x86_was_reset)
- codegen_reset();
-
- codegen_in_recompile = 0;
- }
- else if (!cpu_state.abrt)
- {
- /*Mark block but do not recompile*/
- start_pc = cpu_state.pc;
-
- cpu_block_end = 0;
- x86_was_reset = 0;
-
- codegen_block_init(phys_addr);
-
- while (!cpu_block_end)
- {
- oldcs=CS;
- cpu_state.oldpc = cpu_state.pc;
- oldcpl = CPL;
- cpu_state.op32 = use32;
-
- cpu_state.ea_seg = &cpu_state.seg_ds;
- cpu_state.ssegs = 0;
-
- codegen_endpc = (cs + cpu_state.pc) + 8;
- fetchdat = fastreadl(cs + cpu_state.pc);
-
- if (!cpu_state.abrt)
- {
- opcode = fetchdat & 0xFF;
- fetchdat >>= 8;
- trap = cpu_state.flags & T_FLAG;
-
- cpu_state.pc++;
-
- x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat);
-
- if (x86_was_reset)
- break;
- }
-
- if (!use32) cpu_state.pc &= 0xffff;
-
- /*Cap source code at 4000 bytes per block; this
- will prevent any block from spanning more than
- 2 pages. In practice this limit will never be
- hit, as host block size is only 2kB*/
- if ((cpu_state.pc - start_pc) > 1000)
- CPU_BLOCK_END();
-
- if (in_smm && smi_line && is_pentium)
- CPU_BLOCK_END();
-
- if (trap)
- CPU_BLOCK_END();
-
- if (nmi && nmi_enable && nmi_mask)
- CPU_BLOCK_END();
-
-
- if (cpu_state.abrt)
- {
- codegen_block_remove();
- CPU_BLOCK_END();
- }
-
- ins++;
- }
-
- if (!cpu_state.abrt && !x86_was_reset)
- codegen_block_end();
-
- if (x86_was_reset)
- codegen_reset();
- }
- }
-
- cycdiff=oldcyc-cycles;
- tsc += cycdiff;
-
- if (cpu_state.abrt)
- {
- flags_rebuild();
- tempi = cpu_state.abrt;
- cpu_state.abrt = 0;
- x86_doabrt(tempi);
- if (cpu_state.abrt)
- {
- cpu_state.abrt = 0;
- CS = oldcs;
- cpu_state.pc = cpu_state.oldpc;
-#ifdef ENABLE_386_DYNAREC_LOG
- x386_dynarec_log("Double fault %i\n", ins);
-#endif
- pmodeint(8, 0);
- if (cpu_state.abrt)
- {
- cpu_state.abrt = 0;
- softresetx86();
- cpu_set_edx();
-#ifdef ENABLE_386_DYNAREC_LOG
- x386_dynarec_log("Triple fault - reset\n");
-#endif
- }
- }
- }
-
- if (in_smm && smi_line && is_pentium)
- {
- enter_smm();
- }
-
- if (trap)
- {
- flags_rebuild();
- if (msw&1)
- {
- pmodeint(1,0);
- }
- else
- {
- writememw(ss,(SP-2)&0xFFFF,cpu_state.flags);
- writememw(ss,(SP-4)&0xFFFF,CS);
- writememw(ss,(SP-6)&0xFFFF,cpu_state.pc);
- SP-=6;
- addr = (1 << 2) + idt.base;
- cpu_state.flags&=~I_FLAG;
- cpu_state.flags&=~T_FLAG;
- cpu_state.pc=readmemw(0,addr);
- loadcs(readmemw(0,addr+2));
- }
- }
- else if (nmi && nmi_enable && nmi_mask)
- {
- cpu_state.oldpc = cpu_state.pc;
- oldcs = CS;
- x86_int(2);
- nmi_enable = 0;
- if (nmi_auto_clear)
- {
- nmi_auto_clear = 0;
- nmi = 0;
- }
- }
- else if ((cpu_state.flags&I_FLAG) && pic_intpending)
- {
- vector=picinterrupt();
- if (vector!=-1)
- {
- CPU_BLOCK_END();
- flags_rebuild();
- if (msw&1)
- {
- pmodeint(vector,0);
- }
- else
- {
- writememw(ss,(SP-2)&0xFFFF,cpu_state.flags);
- writememw(ss,(SP-4)&0xFFFF,CS);
- writememw(ss,(SP-6)&0xFFFF,cpu_state.pc);
- SP-=6;
- addr=vector<<2;
- cpu_state.flags&=~I_FLAG;
- cpu_state.flags&=~T_FLAG;
- oxpc=cpu_state.pc;
- cpu_state.pc=readmemw(0,addr);
- loadcs(readmemw(0,addr+2));
- }
- }
- }
- }
- if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc))
- timer_process();
-
- cycles_main -= (cycles_start - cycles);
- }
-}
-#endif
diff --git a/src/cpu_common/386_dynarec - Cópia.c b/src/cpu_common/386_dynarec - Cópia.c
deleted file mode 100644
index 337b49073..000000000
--- a/src/cpu_common/386_dynarec - Cópia.c
+++ /dev/null
@@ -1,1008 +0,0 @@
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#ifndef INFINITY
-# define INFINITY (__builtin_inff())
-#endif
-
-#define HAVE_STDARG_H
-#include <86box/86box.h>
-#include "cpu.h"
-#include "x86.h"
-#include "x86_ops.h"
-#include "x87.h"
-#include <86box/io.h>
-#include <86box/mem.h>
-#include <86box/nmi.h>
-#include <86box/pic.h>
-#include <86box/timer.h>
-#include <86box/fdd.h>
-#include <86box/fdc.h>
-#ifdef USE_DYNAREC
-#include "codegen.h"
-#ifdef USE_NEW_DYNAREC
-#include "codegen_backend.h"
-#endif
-#endif
-#include "386_common.h"
-
-
-#define CPU_BLOCK_END() cpu_block_end = 1
-
-
-int inrecomp = 0, cpu_block_end = 0;
-int cpu_recomp_blocks, cpu_recomp_full_ins, cpu_new_blocks;
-int cpu_recomp_blocks_latched, cpu_recomp_ins_latched, cpu_recomp_full_ins_latched, cpu_new_blocks_latched;
-
-
-#ifdef ENABLE_386_DYNAREC_LOG
-int x386_dynarec_do_log = ENABLE_386_DYNAREC_LOG;
-
-
-void
-x386_dynarec_log(const char *fmt, ...)
-{
- va_list ap;
-
- if (x386_dynarec_do_log) {
- va_start(ap, fmt);
- pclog_ex(fmt, ap);
- va_end(ap);
- }
-}
-#else
-#define x386_dynarec_log(fmt, ...)
-#endif
-
-
-static __inline void fetch_ea_32_long(uint32_t rmdat)
-{
- eal_r = eal_w = NULL;
- easeg = cpu_state.ea_seg->base;
- if (cpu_rm == 4)
- {
- uint8_t sib = rmdat >> 8;
-
- switch (cpu_mod)
- {
- case 0:
- cpu_state.eaaddr = cpu_state.regs[sib & 7].l;
- cpu_state.pc++;
- break;
- case 1:
- cpu_state.pc++;
- cpu_state.eaaddr = ((uint32_t)(int8_t)getbyte()) + cpu_state.regs[sib & 7].l;
- break;
- case 2:
- cpu_state.eaaddr = (fastreadl(cs + cpu_state.pc + 1)) + cpu_state.regs[sib & 7].l;
- cpu_state.pc += 5;
- break;
- }
- /*SIB byte present*/
- if ((sib & 7) == 5 && !cpu_mod)
- cpu_state.eaaddr = getlong();
- else if ((sib & 6) == 4 && !cpu_state.ssegs)
- {
- easeg = ss;
- cpu_state.ea_seg = &cpu_state.seg_ss;
- }
- if (((sib >> 3) & 7) != 4)
- cpu_state.eaaddr += cpu_state.regs[(sib >> 3) & 7].l << (sib >> 6);
- }
- else
- {
- cpu_state.eaaddr = cpu_state.regs[cpu_rm].l;
- if (cpu_mod)
- {
- if (cpu_rm == 5 && !cpu_state.ssegs)
- {
- easeg = ss;
- cpu_state.ea_seg = &cpu_state.seg_ss;
- }
- if (cpu_mod == 1)
- {
- cpu_state.eaaddr += ((uint32_t)(int8_t)(rmdat >> 8));
- cpu_state.pc++;
- }
- else
- {
- cpu_state.eaaddr += getlong();
- }
- }
- else if (cpu_rm == 5)
- {
- cpu_state.eaaddr = getlong();
- }
- }
- if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC)
- {
- uint32_t addr = easeg + cpu_state.eaaddr;
- if ( readlookup2[addr >> 12] != -1)
- eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr);
- if (writelookup2[addr >> 12] != -1)
- eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr);
- }
- cpu_state.last_ea = cpu_state.eaaddr;
-}
-
-static __inline void fetch_ea_16_long(uint32_t rmdat)
-{
- eal_r = eal_w = NULL;
- easeg = cpu_state.ea_seg->base;
- if (!cpu_mod && cpu_rm == 6)
- {
- cpu_state.eaaddr = getword();
- }
- else
- {
- switch (cpu_mod)
- {
- case 0:
- cpu_state.eaaddr = 0;
- break;
- case 1:
- cpu_state.eaaddr = (uint16_t)(int8_t)(rmdat >> 8); cpu_state.pc++;
- break;
- case 2:
- cpu_state.eaaddr = getword();
- break;
- }
- cpu_state.eaaddr += (*mod1add[0][cpu_rm]) + (*mod1add[1][cpu_rm]);
- if (mod1seg[cpu_rm] == &ss && !cpu_state.ssegs)
- {
- easeg = ss;
- cpu_state.ea_seg = &cpu_state.seg_ss;
- }
- cpu_state.eaaddr &= 0xFFFF;
- }
- if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC)
- {
- uint32_t addr = easeg + cpu_state.eaaddr;
- if ( readlookup2[addr >> 12] != -1)
- eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr);
- if (writelookup2[addr >> 12] != -1)
- eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr);
- }
- cpu_state.last_ea = cpu_state.eaaddr;
-}
-
-#define fetch_ea_16(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_16_long(rmdat); if (cpu_state.abrt) return 1; }
-#define fetch_ea_32(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_32_long(rmdat); } if (cpu_state.abrt) return 1
-
-#include "x86_flags.h"
-
-
-/*Prefetch emulation is a fairly simplistic model:
- - All instruction bytes must be fetched before it starts.
- - Cycles used for non-instruction memory accesses are counted and subtracted
- from the total cycles taken
- - Any remaining cycles are used to refill the prefetch queue.
-
- Note that this is only used for 286 / 386 systems. It is disabled when the
- internal cache on 486+ CPUs is enabled.
-*/
-static int prefetch_bytes = 0;
-static int prefetch_prefixes = 0;
-
-static void prefetch_run(int instr_cycles, int bytes, int modrm, int reads, int reads_l, int writes, int writes_l, int ea32)
-{
- int mem_cycles = reads*cpu_cycles_read + reads_l*cpu_cycles_read_l + writes*cpu_cycles_write + writes_l*cpu_cycles_write_l;
-
- if (instr_cycles < mem_cycles)
- instr_cycles = mem_cycles;
-
- prefetch_bytes -= prefetch_prefixes;
- prefetch_bytes -= bytes;
- if (modrm != -1)
- {
- if (ea32)
- {
- if ((modrm & 7) == 4)
- {
- if ((modrm & 0x700) == 0x500)
- prefetch_bytes -= 5;
- else if ((modrm & 0xc0) == 0x40)
- prefetch_bytes -= 2;
- else if ((modrm & 0xc0) == 0x80)
- prefetch_bytes -= 5;
- }
- else
- {
- if ((modrm & 0xc7) == 0x05)
- prefetch_bytes -= 4;
- else if ((modrm & 0xc0) == 0x40)
- prefetch_bytes--;
- else if ((modrm & 0xc0) == 0x80)
- prefetch_bytes -= 4;
- }
- }
- else
- {
- if ((modrm & 0xc7) == 0x06)
- prefetch_bytes -= 2;
- else if ((modrm & 0xc0) != 0xc0)
- prefetch_bytes -= ((modrm & 0xc0) >> 6);
- }
- }
-
- /* Fill up prefetch queue */
- while (prefetch_bytes < 0)
- {
- prefetch_bytes += cpu_prefetch_width;
- cycles -= cpu_prefetch_cycles;
- }
-
- /* Subtract cycles used for memory access by instruction */
- instr_cycles -= mem_cycles;
-
- while (instr_cycles >= cpu_prefetch_cycles)
- {
- prefetch_bytes += cpu_prefetch_width;
- instr_cycles -= cpu_prefetch_cycles;
- }
-
- prefetch_prefixes = 0;
- if (prefetch_bytes > 16)
- prefetch_bytes = 16;
-}
-
-static void prefetch_flush()
-{
- prefetch_bytes = 0;
-}
-
-#define PREFETCH_RUN(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32) \
- do { if (cpu_prefetch_cycles) prefetch_run(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32); } while (0)
-
-#define PREFETCH_PREFIX() do { if (cpu_prefetch_cycles) prefetch_prefixes++; } while (0)
-#define PREFETCH_FLUSH() prefetch_flush()
-
-
-void enter_smm()
-{
- uint32_t smram_state = smbase + 0xfe00;
- uint32_t old_cr0 = cr0;
- uint32_t old_flags = cpu_state.flags | ((uint32_t)cpu_state.eflags << 16);
-
- cr0 &= ~0x8000000d;
- cpu_state.flags = 2;
- cpu_state.eflags = 0;
-
- in_smm = 1;
- mem_set_mem_state(smbase, 131072, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
- smi_latched = 1;
-
- mem_writel_phys(smram_state + 0xf8, smbase);
- mem_writel_phys(smram_state + 0x128, cr4);
- mem_writel_phys(smram_state + 0x130, cpu_state.seg_es.limit);
- mem_writel_phys(smram_state + 0x134, cpu_state.seg_es.base);
- mem_writel_phys(smram_state + 0x138, cpu_state.seg_es.access);
- mem_writel_phys(smram_state + 0x13c, cpu_state.seg_cs.limit);
- mem_writel_phys(smram_state + 0x140, cpu_state.seg_cs.base);
- mem_writel_phys(smram_state + 0x144, cpu_state.seg_cs.access);
- mem_writel_phys(smram_state + 0x148, cpu_state.seg_ss.limit);
- mem_writel_phys(smram_state + 0x14c, cpu_state.seg_ss.base);
- mem_writel_phys(smram_state + 0x150, cpu_state.seg_ss.access);
- mem_writel_phys(smram_state + 0x154, cpu_state.seg_ds.limit);
- mem_writel_phys(smram_state + 0x158, cpu_state.seg_ds.base);
- mem_writel_phys(smram_state + 0x15c, cpu_state.seg_ds.access);
- mem_writel_phys(smram_state + 0x160, cpu_state.seg_fs.limit);
- mem_writel_phys(smram_state + 0x164, cpu_state.seg_fs.base);
- mem_writel_phys(smram_state + 0x168, cpu_state.seg_fs.access);
- mem_writel_phys(smram_state + 0x16c, cpu_state.seg_gs.limit);
- mem_writel_phys(smram_state + 0x170, cpu_state.seg_gs.base);
- mem_writel_phys(smram_state + 0x174, cpu_state.seg_gs.access);
- mem_writel_phys(smram_state + 0x178, ldt.limit);
- mem_writel_phys(smram_state + 0x17c, ldt.base);
- mem_writel_phys(smram_state + 0x180, ldt.access);
- mem_writel_phys(smram_state + 0x184, gdt.limit);
- mem_writel_phys(smram_state + 0x188, gdt.base);
- mem_writel_phys(smram_state + 0x18c, gdt.access);
- mem_writel_phys(smram_state + 0x190, idt.limit);
- mem_writel_phys(smram_state + 0x194, idt.base);
- mem_writel_phys(smram_state + 0x198, idt.access);
- mem_writel_phys(smram_state + 0x19c, tr.limit);
- mem_writel_phys(smram_state + 0x1a0, tr.base);
- mem_writel_phys(smram_state + 0x1a4, tr.access);
-
- mem_writel_phys(smram_state + 0x1a8, cpu_state.seg_es.seg);
- mem_writel_phys(smram_state + 0x1ac, cpu_state.seg_cs.seg);
- mem_writel_phys(smram_state + 0x1b0, cpu_state.seg_ss.seg);
- mem_writel_phys(smram_state + 0x1b4, cpu_state.seg_ds.seg);
- mem_writel_phys(smram_state + 0x1b8, cpu_state.seg_fs.seg);
- mem_writel_phys(smram_state + 0x1bc, cpu_state.seg_gs.seg);
- mem_writel_phys(smram_state + 0x1c0, ldt.seg);
- mem_writel_phys(smram_state + 0x1c4, tr.seg);
-
- mem_writel_phys(smram_state + 0x1c8, dr[7]);
- mem_writel_phys(smram_state + 0x1cc, dr[6]);
- mem_writel_phys(smram_state + 0x1d0, EAX);
- mem_writel_phys(smram_state + 0x1d4, ECX);
- mem_writel_phys(smram_state + 0x1d8, EDX);
- mem_writel_phys(smram_state + 0x1dc, EBX);
- mem_writel_phys(smram_state + 0x1e0, ESP);
- mem_writel_phys(smram_state + 0x1e4, EBP);
- mem_writel_phys(smram_state + 0x1e8, ESI);
- mem_writel_phys(smram_state + 0x1ec, EDI);
- mem_writel_phys(smram_state + 0x1f0, cpu_state.pc);
- mem_writel_phys(smram_state + 0x1d0, old_flags);
- mem_writel_phys(smram_state + 0x1f8, cr3);
- mem_writel_phys(smram_state + 0x1fc, old_cr0);
-
- ds = es = fs_seg = gs = ss = 0;
-
- DS = ES = FS = GS = SS = 0;
-
- cpu_state.seg_ds.limit = cpu_state.seg_es.limit = cpu_state.seg_fs.limit = cpu_state.seg_gs.limit
- = cpu_state.seg_ss.limit = 0xffffffff;
-
- cpu_state.seg_ds.limit_high = cpu_state.seg_es.limit_high = cpu_state.seg_fs.limit_high
- = cpu_state.seg_gs.limit_high = cpu_state.seg_ss.limit_high = 0xffffffff;
-
- cpu_state.seg_ds.limit_low = cpu_state.seg_es.limit_low = cpu_state.seg_fs.limit_low
- = cpu_state.seg_gs.limit_low = cpu_state.seg_ss.limit_low = 0;
-
- cpu_state.seg_ds.access = cpu_state.seg_es.access = cpu_state.seg_fs.access
- = cpu_state.seg_gs.access = cpu_state.seg_ss.access = 0x93;
-
- cpu_state.seg_ds.checked = cpu_state.seg_es.checked = cpu_state.seg_fs.checked
- = cpu_state.seg_gs.checked = cpu_state.seg_ss.checked = 1;
-
- CS = 0x3000;
- cs = smbase;
- cpu_state.seg_cs.limit = cpu_state.seg_cs.limit_high = 0xffffffff;
- cpu_state.seg_cs.limit_low = 0;
- cpu_state.seg_cs.access = 0x93;
- cpu_state.seg_cs.checked = 1;
-
- cr4 = 0;
- dr[7] = 0x400;
- cpu_state.pc = 0x8000;
-
- nmi_mask = 0;
-}
-
-void leave_smm()
-{
- uint32_t smram_state = smbase + 0xfe00;
-
- smbase = mem_readl_phys(smram_state + 0xf8);
- cr4 = mem_readl_phys(smram_state + 0x128);
-
- cpu_state.seg_es.limit = cpu_state.seg_es.limit_high = mem_readl_phys(smram_state + 0x130);
- cpu_state.seg_es.base = mem_readl_phys(smram_state + 0x134);
- cpu_state.seg_es.limit_low = cpu_state.seg_es.base;
- cpu_state.seg_es.access = mem_readl_phys(smram_state + 0x138);
-
- cpu_state.seg_cs.limit = cpu_state.seg_cs.limit_high = mem_readl_phys(smram_state + 0x13c);
- cpu_state.seg_cs.base = mem_readl_phys(smram_state + 0x140);
- cpu_state.seg_cs.limit_low = cpu_state.seg_cs.base;
- cpu_state.seg_cs.access = mem_readl_phys(smram_state + 0x144);
-
- cpu_state.seg_ss.limit = cpu_state.seg_ss.limit_high = mem_readl_phys(smram_state + 0x148);
- cpu_state.seg_ss.base = mem_readl_phys(smram_state + 0x14c);
- cpu_state.seg_ss.limit_low = cpu_state.seg_ss.base;
- cpu_state.seg_ss.access = mem_readl_phys(smram_state + 0x150);
-
- cpu_state.seg_ds.limit = cpu_state.seg_ds.limit_high = mem_readl_phys(smram_state + 0x154);
- cpu_state.seg_ds.base = mem_readl_phys(smram_state + 0x158);
- cpu_state.seg_ds.limit_low = cpu_state.seg_ds.base;
- cpu_state.seg_ds.access = mem_readl_phys(smram_state + 0x15c);
-
- cpu_state.seg_fs.limit = cpu_state.seg_fs.limit_high = mem_readl_phys(smram_state + 0x160);
- cpu_state.seg_fs.base = mem_readl_phys(smram_state + 0x164);
- cpu_state.seg_fs.limit_low = cpu_state.seg_fs.base;
- cpu_state.seg_fs.access = mem_readl_phys(smram_state + 0x168);
-
- cpu_state.seg_gs.limit = cpu_state.seg_gs.limit_high = mem_readl_phys(smram_state + 0x16c);
- cpu_state.seg_gs.base = mem_readl_phys(smram_state + 0x170);
- cpu_state.seg_gs.limit_low = cpu_state.seg_gs.base;
- cpu_state.seg_gs.access = mem_readl_phys(smram_state + 0x174);
-
- ldt.limit = ldt.limit_high = mem_readl_phys(smram_state + 0x178);
- ldt.base = mem_readl_phys(smram_state + 0x17c);
- ldt.limit_low = ldt.base;
- ldt.access = mem_readl_phys(smram_state + 0x180);
-
- gdt.limit = gdt.limit_high = mem_readl_phys(smram_state + 0x184);
- gdt.base = mem_readl_phys(smram_state + 0x188);
- gdt.limit_low = gdt.base;
- gdt.access = mem_readl_phys(smram_state + 0x18c);
-
- idt.limit = idt.limit_high = mem_readl_phys(smram_state + 0x190);
- idt.base = mem_readl_phys(smram_state + 0x194);
- idt.limit_low = idt.base;
- idt.access = mem_readl_phys(smram_state + 0x198);
-
- tr.limit = tr.limit_high = mem_readl_phys(smram_state + 0x19c);
- tr.base = mem_readl_phys(smram_state + 0x1a0);
- tr.limit_low = tr.base;
- tr.access = mem_readl_phys(smram_state + 0x1a4);
-
- ES = mem_readl_phys(smram_state + 0x1a8);
- CS = mem_readl_phys(smram_state + 0x1ac);
- SS = mem_readl_phys(smram_state + 0x1b0);
- DS = mem_readl_phys(smram_state + 0x1b4);
- FS = mem_readl_phys(smram_state + 0x1b8);
- GS = mem_readl_phys(smram_state + 0x1bc);
- ldt.seg = mem_readl_phys(smram_state + 0x1c0);
- tr.seg = mem_readl_phys(smram_state + 0x1c4);
-
- dr[7] = mem_readl_phys(smram_state + 0x1c8);
- dr[6] = mem_readl_phys(smram_state + 0x1cc);
- EAX = mem_readl_phys(smram_state + 0x1d0);
- ECX = mem_readl_phys(smram_state + 0x1d4);
- EDX = mem_readl_phys(smram_state + 0x1d8);
- EBX = mem_readl_phys(smram_state + 0x1dc);
- ESP = mem_readl_phys(smram_state + 0x1e0);
- EBP = mem_readl_phys(smram_state + 0x1e4);
- ESI = mem_readl_phys(smram_state + 0x1e8);
- EDI = mem_readl_phys(smram_state + 0x1ec);
-
- cpu_state.pc = mem_readl_phys(smram_state + 0x1f0);
- uint32_t new_flags = mem_readl_phys(smram_state + 0x1f4);
- cpu_state.flags = new_flags & 0xffff;
- cpu_state.eflags = new_flags >> 16;
- cr3 = mem_readl_phys(smram_state + 0x1f8);
- cr0 = mem_readl_phys(smram_state + 0x1fc);
-
- cpu_state.seg_cs.access &= ~0x60;
- cpu_state.seg_cs.access |= cpu_state.seg_ss.access & 0x60; //cpl is dpl of ss
-
- if((cr0 & 1) && !(cpu_state.eflags&VM_FLAG))
- {
- cpu_state.seg_cs.checked = CS ? 1 : 0;
- cpu_state.seg_ds.checked = DS ? 1 : 0;
- cpu_state.seg_es.checked = ES ? 1 : 0;
- cpu_state.seg_fs.checked = FS ? 1 : 0;
- cpu_state.seg_gs.checked = GS ? 1 : 0;
- cpu_state.seg_ss.checked = SS ? 1 : 0;
- }
- else
- {
- cpu_state.seg_cs.checked = cpu_state.seg_ds.checked = cpu_state.seg_es.checked
- = cpu_state.seg_fs.checked = cpu_state.seg_gs.checked = cpu_state.seg_ss.checked = 1;
- }
-
- mem_restore_mem_state(smbase, 131072);
- in_smm = 0;
-
- nmi_mask = 1;
-}
-
-#define OP_TABLE(name) ops_ ## name
-#define CLOCK_CYCLES(c) cycles -= (c)
-#define CLOCK_CYCLES_ALWAYS(c) cycles -= (c)
-
-#include "386_ops.h"
-
-
-#define CACHE_ON() (!(cr0 & (1 << 30)) && !(cpu_state.flags & T_FLAG))
-
-#ifdef USE_DYNAREC
-static int cycles_main = 0;
-
-
-void exec386_dynarec(int cycs)
-{
- int vector;
- uint32_t addr;
- int tempi;
- int cycdiff;
- int oldcyc;
- uint32_t start_pc = 0;
-
- int cyc_period = cycs / 2000; /*5us*/
-
- cycles_main += cycs;
- while (cycles_main > 0)
- {
- int cycles_start;
-
- cycles += cyc_period;
- cycles_start = cycles;
-
- while (cycles>0)
- {
-#ifndef USE_NEW_DYNAREC
- oldcs = CS;
- cpu_state.oldpc = cpu_state.pc;
- oldcpl = CPL;
- cpu_state.op32 = use32;
-
- cycdiff=0;
-#endif
- oldcyc=cycles;
- if (!CACHE_ON()) /*Interpret block*/
- {
- cpu_block_end = 0;
- x86_was_reset = 0;
- while (!cpu_block_end)
- {
-#ifndef USE_NEW_DYNAREC
- oldcs = CS;
- oldcpl = CPL;
-#endif
- cpu_state.oldpc = cpu_state.pc;
- cpu_state.op32 = use32;
-
- cpu_state.ea_seg = &cpu_state.seg_ds;
- cpu_state.ssegs = 0;
-
- fetchdat = fastreadl(cs + cpu_state.pc);
-
- if (!cpu_state.abrt)
- {
- opcode = fetchdat & 0xFF;
- fetchdat >>= 8;
- trap = cpu_state.flags & T_FLAG;
-
- cpu_state.pc++;
- x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat);
- }
-
-#ifndef USE_NEW_DYNAREC
- if (!use32) cpu_state.pc &= 0xffff;
-#endif
-
- if (((cs + cpu_state.pc) >> 12) != pccache)
- CPU_BLOCK_END();
-
- if (in_smm && smi_line && is_pentium)
- CPU_BLOCK_END();
-
- if (cpu_state.abrt)
- CPU_BLOCK_END();
- if (trap)
- CPU_BLOCK_END();
-
- if (nmi && nmi_enable && nmi_mask)
- CPU_BLOCK_END();
-
- ins++;
- }
- }
- else
- {
- uint32_t phys_addr = get_phys(cs+cpu_state.pc);
- int hash = HASH(phys_addr);
-#ifdef USE_NEW_DYNAREC
- codeblock_t *block = &codeblock[codeblock_hash[hash]];
-#else
- codeblock_t *block = codeblock_hash[hash];
-#endif
- int valid_block = 0;
-#ifdef USE_NEW_DYNAREC
-
- if (!cpu_state.abrt)
-#else
- trap = 0;
-
- if (block && !cpu_state.abrt)
-#endif
- {
- page_t *page = &pages[phys_addr >> 12];
-
- /*Block must match current CS, PC, code segment size,
- and physical address. The physical address check will
- also catch any page faults at this stage*/
- valid_block = (block->pc == cs + cpu_state.pc) && (block->_cs == cs) &&
- (block->phys == phys_addr) && !((block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) &&
- ((block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK));
- if (!valid_block)
- {
- uint64_t mask = (uint64_t)1 << ((phys_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK);
-#ifdef USE_NEW_DYNAREC
- int byte_offset = (phys_addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK;
- uint64_t byte_mask = 1ull << (PAGE_BYTE_MASK_MASK & 0x3f);
-
- if ((page->code_present_mask & mask) || (page->byte_code_present_mask[byte_offset] & byte_mask))
-#else
- if (page->code_present_mask[(phys_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] & mask)
-#endif
- {
- /*Walk page tree to see if we find the correct block*/
- codeblock_t *new_block = codeblock_tree_find(phys_addr, cs);
- if (new_block)
- {
- valid_block = (new_block->pc == cs + cpu_state.pc) && (new_block->_cs == cs) &&
- (new_block->phys == phys_addr) && !((new_block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) &&
- ((new_block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK));
- if (valid_block)
- {
- block = new_block;
-#ifdef USE_NEW_DYNAREC
- codeblock_hash[hash] = get_block_nr(block);
-#endif
- }
- }
- }
- }
-
- if (valid_block && (block->page_mask & *block->dirty_mask))
- {
-#ifdef USE_NEW_DYNAREC
- codegen_check_flush(page, page->dirty_mask, phys_addr);
- if (block->pc == BLOCK_PC_INVALID)
- valid_block = 0;
- else if (block->flags & CODEBLOCK_IN_DIRTY_LIST)
- block->flags &= ~CODEBLOCK_WAS_RECOMPILED;
-#else
- codegen_check_flush(page, page->dirty_mask[(phys_addr >> 10) & 3], phys_addr);
- page->dirty_mask[(phys_addr >> 10) & 3] = 0;
- if (!block->valid)
- valid_block = 0;
-#endif
- }
- if (valid_block && block->page_mask2)
- {
- /*We don't want the second page to cause a page
- fault at this stage - that would break any
- code crossing a page boundary where the first
- page is present but the second isn't. Instead
- allow the first page to be interpreted and for
- the page fault to occur when the page boundary
- is actually crossed.*/
-#ifdef USE_NEW_DYNAREC
- uint32_t phys_addr_2 = get_phys_noabrt(block->pc + ((block->flags & CODEBLOCK_BYTE_MASK) ? 0x40 : 0x400));
-#else
- uint32_t phys_addr_2 = get_phys_noabrt(block->endpc);
-#endif
- page_t *page_2 = &pages[phys_addr_2 >> 12];
-
- if ((block->phys_2 ^ phys_addr_2) & ~0xfff)
- valid_block = 0;
-#ifdef USE_NEW_DYNAREC
- else if (block->page_mask2 & *block->dirty_mask2)
- {
- codegen_check_flush(page_2, page_2->dirty_mask, phys_addr_2);
- if (block->pc == BLOCK_PC_INVALID)
- valid_block = 0;
- else if (block->flags & CODEBLOCK_IN_DIRTY_LIST)
- block->flags &= ~CODEBLOCK_WAS_RECOMPILED;
- }
-#else
- else if (block->page_mask2 & *block->dirty_mask2)
- {
- codegen_check_flush(page_2, page_2->dirty_mask[(phys_addr_2 >> 10) & 3], phys_addr_2);
- page_2->dirty_mask[(phys_addr_2 >> 10) & 3] = 0;
- if (!block->valid)
- valid_block = 0;
- }
-#endif
- }
-#ifdef USE_NEW_DYNAREC
- if (valid_block && (block->flags & CODEBLOCK_IN_DIRTY_LIST))
- {
- block->flags &= ~CODEBLOCK_WAS_RECOMPILED;
- if (block->flags & CODEBLOCK_BYTE_MASK)
- block->flags |= CODEBLOCK_NO_IMMEDIATES;
- else
- block->flags |= CODEBLOCK_BYTE_MASK;
- }
- if (valid_block && (block->flags & CODEBLOCK_WAS_RECOMPILED) && (block->flags & CODEBLOCK_STATIC_TOP) && block->TOP != (cpu_state.TOP & 7))
-#else
- if (valid_block && block->was_recompiled && (block->flags & CODEBLOCK_STATIC_TOP) && block->TOP != cpu_state.TOP)
-#endif
- {
- /*FPU top-of-stack does not match the value this block was compiled
- with, re-compile using dynamic top-of-stack*/
-#ifdef USE_NEW_DYNAREC
- block->flags &= ~(CODEBLOCK_STATIC_TOP | CODEBLOCK_WAS_RECOMPILED);
-#else
- block->flags &= ~CODEBLOCK_STATIC_TOP;
- block->was_recompiled = 0;
-#endif
- }
- }
-
-#ifdef USE_NEW_DYNAREC
- if (valid_block && (block->flags & CODEBLOCK_WAS_RECOMPILED))
-#else
- if (valid_block && block->was_recompiled)
-#endif
- {
- void (*code)() = (void *)&block->data[BLOCK_START];
-
-#ifndef USE_NEW_DYNAREC
- codeblock_hash[hash] = block;
-#endif
-
- inrecomp=1;
- code();
- inrecomp=0;
-
-#ifndef USE_NEW_DYNAREC
- if (!use32) cpu_state.pc &= 0xffff;
-#endif
- cpu_recomp_blocks++;
- }
- else if (valid_block && !cpu_state.abrt)
- {
-#ifdef USE_NEW_DYNAREC
- start_pc = cs+cpu_state.pc;
- const int max_block_size = (block->flags & CODEBLOCK_BYTE_MASK) ? ((128 - 25) - (start_pc & 0x3f)) : 1000;
-#else
- start_pc = cpu_state.pc;
-#endif
-
- cpu_block_end = 0;
- x86_was_reset = 0;
-
- cpu_new_blocks++;
-
- codegen_block_start_recompile(block);
- codegen_in_recompile = 1;
-
- while (!cpu_block_end)
- {
-#ifndef USE_NEW_DYNAREC
- oldcs = CS;
- oldcpl = CPL;
-#endif
- cpu_state.oldpc = cpu_state.pc;
- cpu_state.op32 = use32;
-
- cpu_state.ea_seg = &cpu_state.seg_ds;
- cpu_state.ssegs = 0;
-
- fetchdat = fastreadl(cs + cpu_state.pc);
-
- if (!cpu_state.abrt)
- {
- opcode = fetchdat & 0xFF;
- fetchdat >>= 8;
-
- trap = cpu_state.flags & T_FLAG;
-
- cpu_state.pc++;
-
- codegen_generate_call(opcode, x86_opcodes[(opcode | cpu_state.op32) & 0x3ff], fetchdat, cpu_state.pc, cpu_state.pc-1);
-
- x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat);
-
- if (x86_was_reset)
- break;
- }
-
-#ifndef USE_NEW_DYNAREC
- if (!use32) cpu_state.pc &= 0xffff;
-#endif
-
- /*Cap source code at 4000 bytes per block; this
- will prevent any block from spanning more than
- 2 pages. In practice this limit will never be
- hit, as host block size is only 2kB*/
-#ifdef USE_NEW_DYNAREC
- if (((cs+cpu_state.pc) - start_pc) >= max_block_size)
-#else
- if ((cpu_state.pc - start_pc) > 1000)
-#endif
- CPU_BLOCK_END();
-
- if (in_smm && smi_line && is_pentium)
- CPU_BLOCK_END();
-
- if (trap)
- CPU_BLOCK_END();
-
- if (nmi && nmi_enable && nmi_mask)
- CPU_BLOCK_END();
-
- if (cpu_state.abrt)
- {
- codegen_block_remove();
- CPU_BLOCK_END();
- }
-
- ins++;
- }
-
- if (!cpu_state.abrt && !x86_was_reset)
- codegen_block_end_recompile(block);
-
- if (x86_was_reset)
- codegen_reset();
-
- codegen_in_recompile = 0;
- }
- else if (!cpu_state.abrt)
- {
- /*Mark block but do not recompile*/
- start_pc = cs+cpu_state.pc;
-#ifdef USE_NEW_DYNAREC
- const int max_block_size = (block->flags & CODEBLOCK_BYTE_MASK) ? ((128 - 25) - (start_pc & 0x3f)) : 1000;
-#endif
-
- cpu_block_end = 0;
- x86_was_reset = 0;
-
- codegen_block_init(phys_addr);
-
- while (!cpu_block_end)
- {
-#ifndef USE_NEW_DYNAREC
- oldcs=CS;
- oldcpl = CPL;
-#endif
- cpu_state.oldpc = cpu_state.pc;
- cpu_state.op32 = use32;
-
- cpu_state.ea_seg = &cpu_state.seg_ds;
- cpu_state.ssegs = 0;
-
- codegen_endpc = (cs + cpu_state.pc) + 8;
- fetchdat = fastreadl(cs + cpu_state.pc);
-
- if (!cpu_state.abrt)
- {
- opcode = fetchdat & 0xFF;
- fetchdat >>= 8;
-
- trap = cpu_state.flags & T_FLAG;
-
- cpu_state.pc++;
-
- x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat);
-
- if (x86_was_reset)
- break;
- }
-
-#ifndef USE_NEW_DYNAREC
- if (!use32) cpu_state.pc &= 0xffff;
-#endif
-
- /*Cap source code at 4000 bytes per block; this
- will prevent any block from spanning more than
- 2 pages. In practice this limit will never be
- hit, as host block size is only 2kB*/
-#ifdef USE_NEW_DYNAREC
- if (((cs+cpu_state.pc) - start_pc) >= max_block_size)
-#else
- if ((cpu_state.pc - start_pc) > 1000)
-#endif
- CPU_BLOCK_END();
-
- if (in_smm && smi_line && is_pentium)
- CPU_BLOCK_END();
-
- if (trap)
- CPU_BLOCK_END();
-
- if (nmi && nmi_enable && nmi_mask)
- CPU_BLOCK_END();
-
- if (cpu_state.abrt)
- {
- codegen_block_remove();
- CPU_BLOCK_END();
- }
-
- ins++;
- }
-
- if (!cpu_state.abrt && !x86_was_reset)
- codegen_block_end();
-
- if (x86_was_reset)
- codegen_reset();
- }
-#ifdef USE_NEW_DYNAREC
- else
- cpu_state.oldpc = cpu_state.pc;
-#endif
- }
-
- cycdiff=oldcyc-cycles;
- tsc += cycdiff;
-
- if (cpu_state.abrt)
- {
- flags_rebuild();
- tempi = cpu_state.abrt;
- cpu_state.abrt = 0;
- x86_doabrt(tempi);
- if (cpu_state.abrt)
- {
- cpu_state.abrt = 0;
- cpu_state.pc = cpu_state.oldpc;
-#ifndef USE_NEW_DYNAREC
- CS = oldcs;
-#endif
- pmodeint(8, 0);
- if (cpu_state.abrt)
- {
- cpu_state.abrt = 0;
- softresetx86();
- cpu_set_edx();
-#ifdef ENABLE_386_DYNAREC_LOG
- x386_dynarec_log("Triple fault - reset\n");
-#endif
- }
- }
- }
-
- if (in_smm && smi_line && is_pentium)
- {
- enter_smm();
- }
-
- else if (trap)
- {
-#ifdef USE_NEW_DYNAREC
- trap = 0;
-#endif
- flags_rebuild();
- if (msw&1)
- {
- pmodeint(1,0);
- }
- else
- {
- writememw(ss,(SP-2)&0xFFFF,cpu_state.flags);
- writememw(ss,(SP-4)&0xFFFF,CS);
- writememw(ss,(SP-6)&0xFFFF,cpu_state.pc);
- SP-=6;
- addr = (1 << 2) + idt.base;
- cpu_state.flags &= ~I_FLAG;
- cpu_state.flags &= ~T_FLAG;
- cpu_state.pc=readmemw(0,addr);
- loadcs(readmemw(0,addr+2));
- }
- }
- else if (nmi && nmi_enable && nmi_mask)
- {
- cpu_state.oldpc = cpu_state.pc;
-#ifndef USE_NEW_DYNAREC
- oldcs = CS;
-#endif
- x86_int(2);
- nmi_enable = 0;
- if (nmi_auto_clear)
- {
- nmi_auto_clear = 0;
- nmi = 0;
- }
- }
- else if ((cpu_state.flags & I_FLAG) && pic_intpending)
- {
- vector = picinterrupt();
- if (vector != -1)
- {
- CPU_BLOCK_END();
- flags_rebuild();
- if (msw&1)
- {
- pmodeint(vector,0);
- }
- else
- {
- writememw(ss,(SP-2)&0xFFFF,cpu_state.flags);
- writememw(ss,(SP-4)&0xFFFF,CS);
- writememw(ss,(SP-6)&0xFFFF,cpu_state.pc);
- SP-=6;
- addr=vector<<2;
- cpu_state.flags &= ~I_FLAG;
- cpu_state.flags &= ~T_FLAG;
-#ifndef USE_NEW_DYNAREC
- oxpc=cpu_state.pc;
-#endif
- cpu_state.pc=readmemw(0,addr);
- loadcs(readmemw(0,addr+2));
- }
- }
- }
- }
-
- if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc))
- timer_process();
-
- cycles_main -= (cycles_start - cycles);
- }
-}
-#endif
diff --git a/src/cpu_common/386_dynarec.c b/src/cpu_common/386_dynarec.c
index 9352b27ca..bea5834a7 100644
--- a/src/cpu_common/386_dynarec.c
+++ b/src/cpu_common/386_dynarec.c
@@ -22,6 +22,7 @@
#include <86box/timer.h>
#include <86box/fdd.h>
#include <86box/fdc.h>
+#include <86box/keyboard.h>
#ifdef USE_DYNAREC
#include "codegen.h"
#ifdef USE_NEW_DYNAREC
@@ -41,70 +42,218 @@
/* TODO: Which CPU added SMBASE relocation? */
#define SMM_REVISION_ID SMM_SMBASE_RELOCATION
-// #define SMM_REVISION_ID 0
#define SMM_SAVE_STATE_MAP_SIZE 128
-enum SMMRAM_Fields {
- SMRAM_FIELD_SMBASE_OFFSET = 0,
- SMRAM_FIELD_SMM_REVISION_ID,
- SMRAM_FIELD_EAX,
- SMRAM_FIELD_ECX,
- SMRAM_FIELD_EDX,
- SMRAM_FIELD_EBX,
- SMRAM_FIELD_ESP,
- SMRAM_FIELD_EBP,
- SMRAM_FIELD_ESI,
- SMRAM_FIELD_EDI,
- SMRAM_FIELD_EIP,
- SMRAM_FIELD_EFLAGS,
- SMRAM_FIELD_DR6,
- SMRAM_FIELD_DR7,
- SMRAM_FIELD_CR0,
- SMRAM_FIELD_CR3,
- SMRAM_FIELD_CR4,
- SMRAM_FIELD_EFER,
- SMRAM_FIELD_IO_INSTRUCTION_RESTART,
- SMRAM_FIELD_AUTOHALT_RESTART,
- SMRAM_FIELD_NMI_MASK,
- SMRAM_FIELD_TR_SELECTOR,
- SMRAM_FIELD_TR_BASE,
- SMRAM_FIELD_TR_LIMIT,
- SMRAM_FIELD_TR_SELECTOR_AR,
- SMRAM_FIELD_LDTR_SELECTOR,
- SMRAM_FIELD_LDTR_BASE,
- SMRAM_FIELD_LDTR_LIMIT,
- SMRAM_FIELD_LDTR_SELECTOR_AR,
- SMRAM_FIELD_IDTR_BASE,
- SMRAM_FIELD_IDTR_LIMIT,
- SMRAM_FIELD_GDTR_BASE,
- SMRAM_FIELD_GDTR_LIMIT,
- SMRAM_FIELD_ES_SELECTOR,
- SMRAM_FIELD_ES_BASE,
- SMRAM_FIELD_ES_LIMIT,
- SMRAM_FIELD_ES_SELECTOR_AR,
- SMRAM_FIELD_CS_SELECTOR,
- SMRAM_FIELD_CS_BASE,
- SMRAM_FIELD_CS_LIMIT,
- SMRAM_FIELD_CS_SELECTOR_AR,
- SMRAM_FIELD_SS_SELECTOR,
- SMRAM_FIELD_SS_BASE,
- SMRAM_FIELD_SS_LIMIT,
- SMRAM_FIELD_SS_SELECTOR_AR,
- SMRAM_FIELD_DS_SELECTOR,
- SMRAM_FIELD_DS_BASE,
- SMRAM_FIELD_DS_LIMIT,
- SMRAM_FIELD_DS_SELECTOR_AR,
- SMRAM_FIELD_FS_SELECTOR,
- SMRAM_FIELD_FS_BASE,
- SMRAM_FIELD_FS_LIMIT,
- SMRAM_FIELD_FS_SELECTOR_AR,
- SMRAM_FIELD_GS_SELECTOR,
- SMRAM_FIELD_GS_BASE,
- SMRAM_FIELD_GS_LIMIT,
- SMRAM_FIELD_GS_SELECTOR_AR,
- SMRAM_FIELD_LAST
+enum SMMRAM_Fields_386_To_P5 {
+ SMRAM_FIELD_P5_CR0 = 0, /* 1FC */
+ SMRAM_FIELD_P5_CR3, /* 1F8 */
+ SMRAM_FIELD_P5_EFLAGS, /* 1F4 */
+ SMRAM_FIELD_P5_EIP, /* 1F0 */
+ SMRAM_FIELD_P5_EDI, /* 1EC */
+ SMRAM_FIELD_P5_ESI, /* 1E8 */
+ SMRAM_FIELD_P5_EBP, /* 1E4 */
+ SMRAM_FIELD_P5_ESP, /* 1E0 */
+ SMRAM_FIELD_P5_EBX, /* 1DC */
+ SMRAM_FIELD_P5_EDX, /* 1D8 */
+ SMRAM_FIELD_P5_ECX, /* 1D4 */
+ SMRAM_FIELD_P5_EAX, /* 1D0 */
+ SMRAM_FIELD_P5_DR6, /* 1CC */
+ SMRAM_FIELD_P5_DR7, /* 1C8 */
+ SMRAM_FIELD_P5_TR_SELECTOR, /* 1C4 */
+ SMRAM_FIELD_P5_LDTR_SELECTOR, /* 1C0 */
+ SMRAM_FIELD_P5_GS_SELECTOR, /* 1BC */
+ SMRAM_FIELD_P5_FS_SELECTOR, /* 1B8 */
+ SMRAM_FIELD_P5_DS_SELECTOR, /* 1B4 */
+ SMRAM_FIELD_P5_SS_SELECTOR, /* 1B0 */
+ SMRAM_FIELD_P5_CS_SELECTOR, /* 1AC */
+ SMRAM_FIELD_P5_ES_SELECTOR, /* 1A8 */
+ SMRAM_FIELD_P5_TR_ACCESS, /* 1A4 */
+ SMRAM_FIELD_P5_TR_BASE, /* 1A0 */
+ SMRAM_FIELD_P5_TR_LIMIT, /* 19C */
+ SMRAM_FIELD_P5_IDTR_ACCESS, /* 198 */
+ SMRAM_FIELD_P5_IDTR_BASE, /* 194 */
+ SMRAM_FIELD_P5_IDTR_LIMIT, /* 190 */
+ SMRAM_FIELD_P5_GDTR_ACCESS, /* 18C */
+ SMRAM_FIELD_P5_GDTR_BASE, /* 188 */
+ SMRAM_FIELD_P5_GDTR_LIMIT, /* 184 */
+ SMRAM_FIELD_P5_LDTR_ACCESS, /* 180 */
+ SMRAM_FIELD_P5_LDTR_BASE, /* 17C */
+ SMRAM_FIELD_P5_LDTR_LIMIT, /* 178 */
+ SMRAM_FIELD_P5_GS_ACCESS, /* 174 */
+ SMRAM_FIELD_P5_GS_BASE, /* 170 */
+ SMRAM_FIELD_P5_GS_LIMIT, /* 16C */
+ SMRAM_FIELD_P5_FS_ACCESS, /* 168 */
+ SMRAM_FIELD_P5_FS_BASE, /* 164 */
+ SMRAM_FIELD_P5_FS_LIMIT, /* 160 */
+ SMRAM_FIELD_P5_DS_ACCESS, /* 15C */
+ SMRAM_FIELD_P5_DS_BASE, /* 158 */
+ SMRAM_FIELD_P5_DS_LIMIT, /* 154 */
+ SMRAM_FIELD_P5_SS_ACCESS, /* 150 */
+ SMRAM_FIELD_P5_SS_BASE, /* 14C */
+ SMRAM_FIELD_P5_SS_LIMIT, /* 148 */
+ SMRAM_FIELD_P5_CS_ACCESS, /* 144 */
+ SMRAM_FIELD_P5_CS_BASE, /* 140 */
+ SMRAM_FIELD_P5_CS_LIMIT, /* 13C */
+ SMRAM_FIELD_P5_ES_ACCESS, /* 138 */
+ SMRAM_FIELD_P5_ES_BASE, /* 134 */
+ SMRAM_FIELD_P5_ES_LIMIT, /* 130 */
+ SMRAM_FIELD_P5_UNWRITTEN_1, /* 12C */
+ SMRAM_FIELD_P5_CR4, /* 128 */
+ SMRAM_FIELD_P5_ALTERNATE_DR6, /* 124 */
+ SMRAM_FIELD_P5_RESERVED_1, /* 120 */
+ SMRAM_FIELD_P5_RESERVED_2, /* 11C */
+ SMRAM_FIELD_P5_RESERVED_3, /* 118 */
+ SMRAM_FIELD_P5_RESERVED_4, /* 114 */
+ SMRAM_FIELD_P5_IO_RESTART_EIP, /* 110 */
+ SMRAM_FIELD_P5_IO_RESTART_ESI, /* 10C */
+ SMRAM_FIELD_P5_IO_RESTART_ECX, /* 108 */
+ SMRAM_FIELD_P5_IO_RESTART_EDI, /* 104 */
+ SMRAM_FIELD_P5_AUTOHALT_RESTART, /* 100 */
+ SMRAM_FIELD_P5_SMM_REVISION_ID, /* 0FC */
+ SMRAM_FIELD_P5_SMBASE_OFFSET, /* 0F8 */
+ SMRAM_FIELD_P5_LAST
+};
+
+enum SMMRAM_Fields_P6 {
+ SMRAM_FIELD_P6_CR0 = 0, /* 1FC */
+ SMRAM_FIELD_P6_CR3, /* 1F8 */
+ SMRAM_FIELD_P6_EFLAGS, /* 1F4 */
+ SMRAM_FIELD_P6_EIP, /* 1F0 */
+ SMRAM_FIELD_P6_EDI, /* 1EC */
+ SMRAM_FIELD_P6_ESI, /* 1E8 */
+ SMRAM_FIELD_P6_EBP, /* 1E4 */
+ SMRAM_FIELD_P6_ESP, /* 1E0 */
+ SMRAM_FIELD_P6_EBX, /* 1DC */
+ SMRAM_FIELD_P6_EDX, /* 1D8 */
+ SMRAM_FIELD_P6_ECX, /* 1D4 */
+ SMRAM_FIELD_P6_EAX, /* 1D0 */
+ SMRAM_FIELD_P6_DR6, /* 1CC */
+ SMRAM_FIELD_P6_DR7, /* 1C8 */
+ SMRAM_FIELD_P6_TR_SELECTOR, /* 1C4 */
+ SMRAM_FIELD_P6_LDTR_SELECTOR, /* 1C0 */
+ SMRAM_FIELD_P6_GS_SELECTOR, /* 1BC */
+ SMRAM_FIELD_P6_FS_SELECTOR, /* 1B8 */
+ SMRAM_FIELD_P6_DS_SELECTOR, /* 1B4 */
+ SMRAM_FIELD_P6_SS_SELECTOR, /* 1B0 */
+ SMRAM_FIELD_P6_CS_SELECTOR, /* 1AC */
+ SMRAM_FIELD_P6_ES_SELECTOR, /* 1A8 */
+ SMRAM_FIELD_P6_SS_BASE, /* 1A4 */
+ SMRAM_FIELD_P6_SS_LIMIT, /* 1A0 */
+ SMRAM_FIELD_P6_SS_SELECTOR_AR, /* 19C */
+ SMRAM_FIELD_P6_CS_BASE, /* 198 */
+ SMRAM_FIELD_P6_CS_LIMIT, /* 194 */
+ SMRAM_FIELD_P6_CS_SELECTOR_AR, /* 190 */
+ SMRAM_FIELD_P6_ES_BASE, /* 18C */
+ SMRAM_FIELD_P6_ES_LIMIT, /* 188 */
+ SMRAM_FIELD_P6_ES_SELECTOR_AR, /* 184 */
+ SMRAM_FIELD_P6_LDTR_BASE, /* 180 */
+ SMRAM_FIELD_P6_LDTR_LIMIT, /* 17C */
+ SMRAM_FIELD_P6_LDTR_SELECTOR_AR, /* 178 */
+ SMRAM_FIELD_P6_GDTR_BASE, /* 174 */
+ SMRAM_FIELD_P6_GDTR_LIMIT, /* 170 */
+ SMRAM_FIELD_P6_GDTR_SELECTOR_AR, /* 16C */
+ SMRAM_FIELD_P6_SREG_STATUS1, /* 168 */
+ SMRAM_FIELD_P6_TR_BASE, /* 164 */
+ SMRAM_FIELD_P6_TR_LIMIT, /* 160 */
+ SMRAM_FIELD_P6_TR_SELECTOR_AR, /* 15C */
+ SMRAM_FIELD_P6_IDTR_BASE, /* 158 */
+ SMRAM_FIELD_P6_IDTR_LIMIT, /* 154 */
+ SMRAM_FIELD_P6_IDTR_SELECTOR_AR, /* 150 */
+ SMRAM_FIELD_P6_GS_BASE, /* 14C */
+ SMRAM_FIELD_P6_GS_LIMIT, /* 148 */
+ SMRAM_FIELD_P6_GS_SELECTOR_AR, /* 144 */
+ SMRAM_FIELD_P6_FS_BASE, /* 140 */
+ SMRAM_FIELD_P6_FS_LIMIT, /* 13C */
+ SMRAM_FIELD_P6_FS_SELECTOR_AR, /* 138 */
+ SMRAM_FIELD_P6_DS_BASE, /* 134 */
+ SMRAM_FIELD_P6_DS_LIMIT, /* 130 */
+ SMRAM_FIELD_P6_DS_SELECTOR_AR, /* 12C */
+ SMRAM_FIELD_P6_SREG_STATUS0, /* 128 */
+ SMRAM_FIELD_P6_ALTERNATIVE_DR6, /* 124 */
+ SMRAM_FIELD_P6_CPL, /* 120 */
+ SMRAM_FIELD_P6_SMM_STATUS, /* 11C */
+ SMRAM_FIELD_P6_A20M, /* 118 */
+ SMRAM_FIELD_P6_CR4, /* 114 */
+ SMRAM_FIELD_P6_IO_RESTART_EIP, /* 110 */
+ SMRAM_FIELD_P6_IO_RESTART_ESI, /* 10C */
+ SMRAM_FIELD_P6_IO_RESTART_ECX, /* 108 */
+ SMRAM_FIELD_P6_IO_RESTART_EDI, /* 104 */
+ SMRAM_FIELD_P6_AUTOHALT_RESTART, /* 100 */
+ SMRAM_FIELD_P6_SMM_REVISION_ID, /* 0FC */
+ SMRAM_FIELD_P6_SMBASE_OFFSET, /* 0F8 */
+ SMRAM_FIELD_P6_LAST
+};
+
+enum SMMRAM_Fields_AMD_K {
+ SMRAM_FIELD_AMD_K_CR0 = 0, /* 1FC */
+ SMRAM_FIELD_AMD_K_CR3, /* 1F8 */
+ SMRAM_FIELD_AMD_K_EFLAGS, /* 1F4 */
+ SMRAM_FIELD_AMD_K_EIP, /* 1F0 */
+ SMRAM_FIELD_AMD_K_EDI, /* 1EC */
+ SMRAM_FIELD_AMD_K_ESI, /* 1E8 */
+ SMRAM_FIELD_AMD_K_EBP, /* 1E4 */
+ SMRAM_FIELD_AMD_K_ESP, /* 1E0 */
+ SMRAM_FIELD_AMD_K_EBX, /* 1DC */
+ SMRAM_FIELD_AMD_K_EDX, /* 1D8 */
+ SMRAM_FIELD_AMD_K_ECX, /* 1D4 */
+ SMRAM_FIELD_AMD_K_EAX, /* 1D0 */
+ SMRAM_FIELD_AMD_K_DR6, /* 1CC */
+ SMRAM_FIELD_AMD_K_DR7, /* 1C8 */
+ SMRAM_FIELD_AMD_K_TR_SELECTOR, /* 1C4 */
+ SMRAM_FIELD_AMD_K_LDTR_SELECTOR, /* 1C0 */
+ SMRAM_FIELD_AMD_K_GS_SELECTOR, /* 1BC */
+ SMRAM_FIELD_AMD_K_FS_SELECTOR, /* 1B8 */
+ SMRAM_FIELD_AMD_K_DS_SELECTOR, /* 1B4 */
+ SMRAM_FIELD_AMD_K_SS_SELECTOR, /* 1B0 */
+ SMRAM_FIELD_AMD_K_CS_SELECTOR, /* 1AC */
+ SMRAM_FIELD_AMD_K_ES_SELECTOR, /* 1A8 */
+ SMRAM_FIELD_AMD_K_IO_RESTART_DWORD, /* 1A4 */
+ SMRAM_FIELD_AMD_K_RESERVED_1, /* 1A0 */
+ SMRAM_FIELD_AMD_K_IO_RESTART_EIP, /* 19C */
+ SMRAM_FIELD_AMD_K_RESERVED_2, /* 198 */
+ SMRAM_FIELD_AMD_K_RESERVED_3, /* 194 */
+ SMRAM_FIELD_AMD_K_IDTR_BASE, /* 190 */
+ SMRAM_FIELD_AMD_K_IDTR_LIMIT, /* 18C */
+ SMRAM_FIELD_AMD_K_GDTR_BASE, /* 188 */
+ SMRAM_FIELD_AMD_K_GDTR_LIMIT, /* 184 */
+ SMRAM_FIELD_AMD_K_TR_ACCESS, /* 180 */
+ SMRAM_FIELD_AMD_K_TR_BASE, /* 17C */
+ SMRAM_FIELD_AMD_K_TR_LIMIT, /* 178 */
+ SMRAM_FIELD_AMD_K_LDTR_ACCESS, /* 174 - reserved on K6 */
+ SMRAM_FIELD_AMD_K_LDTR_BASE, /* 170 */
+ SMRAM_FIELD_AMD_K_LDTR_LIMIT, /* 16C */
+ SMRAM_FIELD_AMD_K_GS_ACCESS, /* 168 */
+ SMRAM_FIELD_AMD_K_GS_BASE, /* 164 */
+ SMRAM_FIELD_AMD_K_GS_LIMIT, /* 160 */
+ SMRAM_FIELD_AMD_K_FS_ACCESS, /* 15C */
+ SMRAM_FIELD_AMD_K_FS_BASE, /* 158 */
+ SMRAM_FIELD_AMD_K_FS_LIMIT, /* 154 */
+ SMRAM_FIELD_AMD_K_DS_ACCESS, /* 150 */
+ SMRAM_FIELD_AMD_K_DS_BASE, /* 14C */
+ SMRAM_FIELD_AMD_K_DS_LIMIT, /* 148 */
+ SMRAM_FIELD_AMD_K_SS_ACCESS, /* 144 */
+ SMRAM_FIELD_AMD_K_SS_BASE, /* 140 */
+ SMRAM_FIELD_AMD_K_SS_LIMIT, /* 13C */
+ SMRAM_FIELD_AMD_K_CS_ACCESS, /* 138 */
+ SMRAM_FIELD_AMD_K_CS_BASE, /* 134 */
+ SMRAM_FIELD_AMD_K_CS_LIMIT, /* 130 */
+ SMRAM_FIELD_AMD_K_ES_ACCESS, /* 12C */
+ SMRAM_FIELD_AMD_K_ES_BASE, /* 128 */
+ SMRAM_FIELD_AMD_K_ES_LIMIT, /* 124 */
+ SMRAM_FIELD_AMD_K_RESERVED_4, /* 120 */
+ SMRAM_FIELD_AMD_K_RESERVED_5, /* 11C */
+ SMRAM_FIELD_AMD_K_RESERVED_6, /* 118 */
+ SMRAM_FIELD_AMD_K_CR2, /* 114 */
+ SMRAM_FIELD_AMD_K_CR4, /* 110 */
+ SMRAM_FIELD_AMD_K_IO_RESTART_ESI, /* 10C */
+ SMRAM_FIELD_AMD_K_IO_RESTART_ECX, /* 108 */
+ SMRAM_FIELD_AMD_K_IO_RESTART_EDI, /* 104 */
+ SMRAM_FIELD_AMD_K_AUTOHALT_RESTART, /* 100 */
+ SMRAM_FIELD_AMD_K_SMM_REVISION_ID, /* 0FC */
+ SMRAM_FIELD_AMD_K_SMBASE_OFFSET, /* 0F8 */
+ SMRAM_FIELD_AMD_K_LAST
};
@@ -402,188 +551,583 @@ void smm_seg_load(x86seg *s)
}
-void smram_save_state(uint32_t *saved_state)
+void smram_save_state_p5(uint32_t *saved_state)
{
int n = 0;
- saved_state[SMRAM_FIELD_SMM_REVISION_ID] = SMM_REVISION_ID;
- saved_state[SMRAM_FIELD_SMBASE_OFFSET] = smbase;
+ saved_state[SMRAM_FIELD_P5_SMM_REVISION_ID] = SMM_REVISION_ID;
+ saved_state[SMRAM_FIELD_P5_SMBASE_OFFSET] = smbase;
for (n = 0; n < 8; n++)
- saved_state[SMRAM_FIELD_EAX + n] = cpu_state.regs[n].l;
+ saved_state[SMRAM_FIELD_P5_EAX - n] = cpu_state.regs[n].l;
- saved_state[SMRAM_FIELD_EIP] = cpu_state.pc;
- saved_state[SMRAM_FIELD_EFLAGS] = (cpu_state.eflags << 16) | (cpu_state.flags);
-
- saved_state[SMRAM_FIELD_CR0] = cr0;
- saved_state[SMRAM_FIELD_CR3] = cr3;
- if (is_pentium) {
- saved_state[SMRAM_FIELD_CR4] = cr4;
- /* TODO: Properly implement EFER */
- /* saved_state[SMRAM_FIELD_EFER] = efer; */
+ if (in_hlt) {
+ saved_state[SMRAM_FIELD_P5_AUTOHALT_RESTART] = 1;
+ saved_state[SMRAM_FIELD_P5_EIP] = cpu_state.pc + 1;
+ } else {
+ saved_state[SMRAM_FIELD_P5_AUTOHALT_RESTART] = 0;
+ saved_state[SMRAM_FIELD_P5_EIP] = cpu_state.pc;
}
- saved_state[SMRAM_FIELD_DR6] = dr[6];
- saved_state[SMRAM_FIELD_DR7] = dr[7];
+
+ saved_state[SMRAM_FIELD_P5_EFLAGS] = (cpu_state.eflags << 16) | (cpu_state.flags);
+
+ saved_state[SMRAM_FIELD_P5_CR0] = cr0;
+ saved_state[SMRAM_FIELD_P5_CR3] = cr3;
+ saved_state[SMRAM_FIELD_P5_CR4] = cr4;
+ saved_state[SMRAM_FIELD_P5_DR6] = dr[6];
+ saved_state[SMRAM_FIELD_P5_DR7] = dr[7];
/* TR */
- saved_state[SMRAM_FIELD_TR_SELECTOR] = tr.seg;
- saved_state[SMRAM_FIELD_TR_BASE] = tr.base;
- saved_state[SMRAM_FIELD_TR_LIMIT] = tr.limit;
- saved_state[SMRAM_FIELD_TR_SELECTOR_AR] = (tr.ar_high << 24) | (tr.access << 16) | tr.seg;
+ saved_state[SMRAM_FIELD_P5_TR_SELECTOR] = tr.seg;
+ saved_state[SMRAM_FIELD_P5_TR_BASE] = tr.base;
+ saved_state[SMRAM_FIELD_P5_TR_LIMIT] = tr.limit;
+ saved_state[SMRAM_FIELD_P5_TR_ACCESS] = (tr.ar_high << 16) | (tr.access << 8);
/* LDTR */
- saved_state[SMRAM_FIELD_LDTR_SELECTOR] = ldt.seg;
- saved_state[SMRAM_FIELD_LDTR_BASE] = ldt.base;
- saved_state[SMRAM_FIELD_LDTR_LIMIT] = ldt.limit;
- saved_state[SMRAM_FIELD_LDTR_SELECTOR_AR] = (ldt.ar_high << 24) | (ldt.access << 16) | ldt.seg;
+ saved_state[SMRAM_FIELD_P5_LDTR_SELECTOR] = ldt.seg;
+ saved_state[SMRAM_FIELD_P5_LDTR_BASE] = ldt.base;
+ saved_state[SMRAM_FIELD_P5_LDTR_LIMIT] = ldt.limit;
+ saved_state[SMRAM_FIELD_P5_LDTR_ACCESS] = (ldt.ar_high << 16) | (ldt.access << 8);
/* IDTR */
- saved_state[SMRAM_FIELD_IDTR_BASE] = idt.base;
- saved_state[SMRAM_FIELD_IDTR_LIMIT] = idt.limit;
+ saved_state[SMRAM_FIELD_P5_IDTR_BASE] = idt.base;
+ saved_state[SMRAM_FIELD_P5_IDTR_LIMIT] = idt.limit;
+ saved_state[SMRAM_FIELD_P5_IDTR_ACCESS] = (idt.ar_high << 16) | (idt.access << 8);
/* GDTR */
- saved_state[SMRAM_FIELD_GDTR_BASE] = gdt.base;
- saved_state[SMRAM_FIELD_GDTR_LIMIT] = gdt.limit;
+ saved_state[SMRAM_FIELD_P5_GDTR_BASE] = gdt.base;
+ saved_state[SMRAM_FIELD_P5_GDTR_LIMIT] = gdt.limit;
+ saved_state[SMRAM_FIELD_P5_GDTR_ACCESS] = (gdt.ar_high << 16) | (gdt.access << 8);
/* ES */
- saved_state[SMRAM_FIELD_ES_SELECTOR] = cpu_state.seg_es.seg;
- saved_state[SMRAM_FIELD_ES_BASE] = cpu_state.seg_es.base;
- saved_state[SMRAM_FIELD_ES_LIMIT] = cpu_state.seg_es.limit;
- saved_state[SMRAM_FIELD_ES_SELECTOR_AR] =
+ saved_state[SMRAM_FIELD_P5_ES_SELECTOR] = cpu_state.seg_es.seg;
+ saved_state[SMRAM_FIELD_P5_ES_BASE] = cpu_state.seg_es.base;
+ saved_state[SMRAM_FIELD_P5_ES_LIMIT] = cpu_state.seg_es.limit;
+ saved_state[SMRAM_FIELD_P5_ES_ACCESS] = (cpu_state.seg_es.ar_high << 16) | (cpu_state.seg_es.access << 8);
+
+ /* CS */
+ saved_state[SMRAM_FIELD_P5_CS_SELECTOR] = cpu_state.seg_cs.seg;
+ saved_state[SMRAM_FIELD_P5_CS_BASE] = cpu_state.seg_cs.base;
+ saved_state[SMRAM_FIELD_P5_CS_LIMIT] = cpu_state.seg_cs.limit;
+ saved_state[SMRAM_FIELD_P5_CS_ACCESS] = (cpu_state.seg_cs.ar_high << 16) | (cpu_state.seg_cs.access << 8);
+
+ /* DS */
+ saved_state[SMRAM_FIELD_P5_DS_SELECTOR] = cpu_state.seg_ds.seg;
+ saved_state[SMRAM_FIELD_P5_DS_BASE] = cpu_state.seg_ds.base;
+ saved_state[SMRAM_FIELD_P5_DS_LIMIT] = cpu_state.seg_ds.limit;
+ saved_state[SMRAM_FIELD_P5_DS_ACCESS] = (cpu_state.seg_ds.ar_high << 16) | (cpu_state.seg_ds.access << 8);
+
+ /* SS */
+ saved_state[SMRAM_FIELD_P5_SS_SELECTOR] = cpu_state.seg_ss.seg;
+ saved_state[SMRAM_FIELD_P5_SS_BASE] = cpu_state.seg_ss.base;
+ saved_state[SMRAM_FIELD_P5_SS_LIMIT] = cpu_state.seg_ss.limit;
+ saved_state[SMRAM_FIELD_P5_SS_ACCESS] = (cpu_state.seg_ss.ar_high << 16) | (cpu_state.seg_ss.access << 8);
+
+ /* FS */
+ saved_state[SMRAM_FIELD_P5_FS_SELECTOR] = cpu_state.seg_fs.seg;
+ saved_state[SMRAM_FIELD_P5_FS_BASE] = cpu_state.seg_fs.base;
+ saved_state[SMRAM_FIELD_P5_FS_LIMIT] = cpu_state.seg_fs.limit;
+ saved_state[SMRAM_FIELD_P5_FS_ACCESS] = (cpu_state.seg_fs.ar_high << 16) | (cpu_state.seg_fs.access << 8);
+
+ /* GS */
+ saved_state[SMRAM_FIELD_P5_GS_SELECTOR] = cpu_state.seg_gs.seg;
+ saved_state[SMRAM_FIELD_P5_GS_BASE] = cpu_state.seg_gs.base;
+ saved_state[SMRAM_FIELD_P5_GS_LIMIT] = cpu_state.seg_gs.limit;
+ saved_state[SMRAM_FIELD_P5_GS_ACCESS] = (cpu_state.seg_gs.ar_high << 16) | (cpu_state.seg_gs.access << 8);
+}
+
+
+void smram_restore_state_p5(uint32_t *saved_state)
+{
+ int n = 0;
+
+ for (n = 0; n < 8; n++)
+ cpu_state.regs[n].l = saved_state[SMRAM_FIELD_P5_EAX - n];
+
+ if (saved_state[SMRAM_FIELD_P5_AUTOHALT_RESTART] & 0xffff)
+ cpu_state.pc = saved_state[SMRAM_FIELD_P5_EIP] - 1;
+ else
+ cpu_state.pc = saved_state[SMRAM_FIELD_P5_EIP];
+
+ cpu_state.eflags = saved_state[SMRAM_FIELD_P5_EFLAGS] >> 16;
+ cpu_state.flags = saved_state[SMRAM_FIELD_P5_EFLAGS] & 0xffff;
+
+ cr0 = saved_state[SMRAM_FIELD_P5_CR0];
+ cr3 = saved_state[SMRAM_FIELD_P5_CR3];
+ cr4 = saved_state[SMRAM_FIELD_P5_CR4];
+ dr[6] = saved_state[SMRAM_FIELD_P5_DR6];
+ dr[7] = saved_state[SMRAM_FIELD_P5_DR7];
+
+ /* TR */
+ tr.seg = saved_state[SMRAM_FIELD_P5_TR_SELECTOR];
+ tr.base = saved_state[SMRAM_FIELD_P5_TR_BASE];
+ tr.limit = saved_state[SMRAM_FIELD_P5_TR_LIMIT];
+ tr.access = (saved_state[SMRAM_FIELD_P5_TR_ACCESS] >> 8) & 0xff;
+ tr.ar_high = (saved_state[SMRAM_FIELD_P5_TR_ACCESS] >> 16) & 0xff;
+ smm_seg_load(&tr);
+
+ /* LDTR */
+ ldt.seg = saved_state[SMRAM_FIELD_P5_LDTR_SELECTOR];
+ ldt.base = saved_state[SMRAM_FIELD_P5_LDTR_BASE];
+ ldt.limit = saved_state[SMRAM_FIELD_P5_LDTR_LIMIT];
+ ldt.access = (saved_state[SMRAM_FIELD_P5_LDTR_ACCESS] >> 8) & 0xff;
+ ldt.ar_high = (saved_state[SMRAM_FIELD_P5_LDTR_ACCESS] >> 16) & 0xff;
+ smm_seg_load(&ldt);
+
+ /* IDTR */
+ idt.base = saved_state[SMRAM_FIELD_P5_IDTR_BASE];
+ idt.limit = saved_state[SMRAM_FIELD_P5_IDTR_LIMIT];
+ idt.access = (saved_state[SMRAM_FIELD_P5_IDTR_ACCESS] >> 8) & 0xff;
+ idt.ar_high = (saved_state[SMRAM_FIELD_P5_IDTR_ACCESS] >> 16) & 0xff;
+
+ /* GDTR */
+ gdt.base = saved_state[SMRAM_FIELD_P5_GDTR_BASE];
+ gdt.limit = saved_state[SMRAM_FIELD_P5_GDTR_LIMIT];
+ gdt.access = (saved_state[SMRAM_FIELD_P5_GDTR_ACCESS] >> 8) & 0xff;
+ gdt.ar_high = (saved_state[SMRAM_FIELD_P5_GDTR_ACCESS] >> 16) & 0xff;
+
+ /* ES */
+ cpu_state.seg_es.seg = saved_state[SMRAM_FIELD_P5_ES_SELECTOR];
+ cpu_state.seg_es.base = saved_state[SMRAM_FIELD_P5_ES_BASE];
+ cpu_state.seg_es.limit = saved_state[SMRAM_FIELD_P5_ES_LIMIT];
+ cpu_state.seg_es.access = (saved_state[SMRAM_FIELD_P5_ES_ACCESS] >> 8) & 0xff;
+ cpu_state.seg_es.ar_high = (saved_state[SMRAM_FIELD_P5_ES_ACCESS] >> 16) & 0xff;
+ smm_seg_load(&cpu_state.seg_es);
+
+ /* CS */
+ cpu_state.seg_cs.seg = saved_state[SMRAM_FIELD_P5_CS_SELECTOR];
+ cpu_state.seg_cs.base = saved_state[SMRAM_FIELD_P5_CS_BASE];
+ cpu_state.seg_cs.limit = saved_state[SMRAM_FIELD_P5_CS_LIMIT];
+ cpu_state.seg_cs.access = (saved_state[SMRAM_FIELD_P5_CS_ACCESS] >> 8) & 0xff;
+ cpu_state.seg_cs.ar_high = (saved_state[SMRAM_FIELD_P5_CS_ACCESS] >> 16) & 0xff;
+ smm_seg_load(&cpu_state.seg_cs);
+
+ /* DS */
+ cpu_state.seg_ds.seg = saved_state[SMRAM_FIELD_P5_DS_SELECTOR];
+ cpu_state.seg_ds.base = saved_state[SMRAM_FIELD_P5_DS_BASE];
+ cpu_state.seg_ds.limit = saved_state[SMRAM_FIELD_P5_DS_LIMIT];
+ cpu_state.seg_ds.access = (saved_state[SMRAM_FIELD_P5_DS_ACCESS] >> 8) & 0xff;
+ cpu_state.seg_ds.ar_high = (saved_state[SMRAM_FIELD_P5_DS_ACCESS] >> 16) & 0xff;
+ smm_seg_load(&cpu_state.seg_ds);
+
+ /* SS */
+ cpu_state.seg_ss.seg = saved_state[SMRAM_FIELD_P5_SS_SELECTOR];
+ cpu_state.seg_ss.base = saved_state[SMRAM_FIELD_P5_SS_BASE];
+ cpu_state.seg_ss.limit = saved_state[SMRAM_FIELD_P5_SS_LIMIT];
+ cpu_state.seg_ss.access = (saved_state[SMRAM_FIELD_P5_SS_ACCESS] >> 8) & 0xff;
+ /* The actual CPL (DPL of CS) is overwritten with DPL of SS. */
+ cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~0x60) | (cpu_state.seg_ss.access & 0x60);
+ cpu_state.seg_ss.ar_high = (saved_state[SMRAM_FIELD_P5_SS_ACCESS] >> 16) & 0xff;
+ smm_seg_load(&cpu_state.seg_ss);
+
+ /* FS */
+ cpu_state.seg_fs.seg = saved_state[SMRAM_FIELD_P5_FS_SELECTOR];
+ cpu_state.seg_fs.base = saved_state[SMRAM_FIELD_P5_FS_BASE];
+ cpu_state.seg_fs.limit = saved_state[SMRAM_FIELD_P5_FS_LIMIT];
+ cpu_state.seg_fs.access = (saved_state[SMRAM_FIELD_P5_FS_ACCESS] >> 8) & 0xff;
+ cpu_state.seg_fs.ar_high = (saved_state[SMRAM_FIELD_P5_FS_ACCESS] >> 16) & 0xff;
+ smm_seg_load(&cpu_state.seg_fs);
+
+ /* GS */
+ cpu_state.seg_gs.seg = saved_state[SMRAM_FIELD_P5_GS_SELECTOR];
+ cpu_state.seg_gs.base = saved_state[SMRAM_FIELD_P5_GS_BASE];
+ cpu_state.seg_gs.limit = saved_state[SMRAM_FIELD_P5_GS_LIMIT];
+ cpu_state.seg_gs.access = (saved_state[SMRAM_FIELD_P5_GS_ACCESS] >> 8) & 0xff;
+ cpu_state.seg_gs.ar_high = (saved_state[SMRAM_FIELD_P5_GS_ACCESS] >> 16) & 0xff;
+ smm_seg_load(&cpu_state.seg_gs);
+
+ if (SMM_REVISION_ID & SMM_SMBASE_RELOCATION)
+ smbase = saved_state[SMRAM_FIELD_P5_SMBASE_OFFSET];
+}
+
+
+void smram_save_state_p6(uint32_t *saved_state)
+{
+ int n = 0;
+
+ saved_state[SMRAM_FIELD_P6_SMM_REVISION_ID] = SMM_REVISION_ID;
+ saved_state[SMRAM_FIELD_P6_SMBASE_OFFSET] = smbase;
+
+ for (n = 0; n < 8; n++)
+ saved_state[SMRAM_FIELD_P6_EAX - n] = cpu_state.regs[n].l;
+
+ if (in_hlt) {
+ saved_state[SMRAM_FIELD_P6_AUTOHALT_RESTART] = 1;
+ saved_state[SMRAM_FIELD_P6_EIP] = cpu_state.pc + 1;
+ } else {
+ saved_state[SMRAM_FIELD_P6_AUTOHALT_RESTART] = 0;
+ saved_state[SMRAM_FIELD_P6_EIP] = cpu_state.pc;
+ }
+
+ saved_state[SMRAM_FIELD_P6_EFLAGS] = (cpu_state.eflags << 16) | (cpu_state.flags);
+
+ saved_state[SMRAM_FIELD_P6_CR0] = cr0;
+ saved_state[SMRAM_FIELD_P6_CR3] = cr3;
+ saved_state[SMRAM_FIELD_P6_CR4] = cr4;
+ saved_state[SMRAM_FIELD_P6_DR6] = dr[6];
+ saved_state[SMRAM_FIELD_P6_DR7] = dr[7];
+ saved_state[SMRAM_FIELD_P6_CPL] = CPL;
+ saved_state[SMRAM_FIELD_P6_A20M] = !mem_a20_state;
+
+ /* TR */
+ saved_state[SMRAM_FIELD_P6_TR_SELECTOR] = tr.seg;
+ saved_state[SMRAM_FIELD_P6_TR_BASE] = tr.base;
+ saved_state[SMRAM_FIELD_P6_TR_LIMIT] = tr.limit;
+ saved_state[SMRAM_FIELD_P6_TR_SELECTOR_AR] = (tr.ar_high << 24) | (tr.access << 16) | tr.seg;
+
+ /* LDTR */
+ saved_state[SMRAM_FIELD_P6_LDTR_SELECTOR] = ldt.seg;
+ saved_state[SMRAM_FIELD_P6_LDTR_BASE] = ldt.base;
+ saved_state[SMRAM_FIELD_P6_LDTR_LIMIT] = ldt.limit;
+ saved_state[SMRAM_FIELD_P6_LDTR_SELECTOR_AR] = (ldt.ar_high << 24) | (ldt.access << 16) | ldt.seg;
+
+ /* IDTR */
+ saved_state[SMRAM_FIELD_P6_IDTR_BASE] = idt.base;
+ saved_state[SMRAM_FIELD_P6_IDTR_LIMIT] = idt.limit;
+ saved_state[SMRAM_FIELD_P6_IDTR_SELECTOR_AR] = (idt.ar_high << 24) | (idt.access << 16) | idt.seg;
+
+ /* GDTR */
+ saved_state[SMRAM_FIELD_P6_GDTR_BASE] = gdt.base;
+ saved_state[SMRAM_FIELD_P6_GDTR_LIMIT] = gdt.limit;
+ saved_state[SMRAM_FIELD_P6_GDTR_SELECTOR_AR] = (gdt.ar_high << 24) | (gdt.access << 16) | gdt.seg;
+
+ /* ES */
+ saved_state[SMRAM_FIELD_P6_ES_SELECTOR] = cpu_state.seg_es.seg;
+ saved_state[SMRAM_FIELD_P6_ES_BASE] = cpu_state.seg_es.base;
+ saved_state[SMRAM_FIELD_P6_ES_LIMIT] = cpu_state.seg_es.limit;
+ saved_state[SMRAM_FIELD_P6_ES_SELECTOR_AR] =
(cpu_state.seg_es.ar_high << 24) | (cpu_state.seg_es.access << 16) | cpu_state.seg_es.seg;
/* CS */
- saved_state[SMRAM_FIELD_CS_SELECTOR] = cpu_state.seg_cs.seg;
- saved_state[SMRAM_FIELD_CS_BASE] = cpu_state.seg_cs.base;
- saved_state[SMRAM_FIELD_CS_LIMIT] = cpu_state.seg_cs.limit;
- saved_state[SMRAM_FIELD_CS_SELECTOR_AR] =
+ saved_state[SMRAM_FIELD_P6_CS_SELECTOR] = cpu_state.seg_cs.seg;
+ saved_state[SMRAM_FIELD_P6_CS_BASE] = cpu_state.seg_cs.base;
+ saved_state[SMRAM_FIELD_P6_CS_LIMIT] = cpu_state.seg_cs.limit;
+ saved_state[SMRAM_FIELD_P6_CS_SELECTOR_AR] =
(cpu_state.seg_cs.ar_high << 24) | (cpu_state.seg_cs.access << 16) | cpu_state.seg_cs.seg;
/* DS */
- saved_state[SMRAM_FIELD_DS_SELECTOR] = cpu_state.seg_ds.seg;
- saved_state[SMRAM_FIELD_DS_BASE] = cpu_state.seg_ds.base;
- saved_state[SMRAM_FIELD_DS_LIMIT] = cpu_state.seg_ds.limit;
- saved_state[SMRAM_FIELD_DS_SELECTOR_AR] =
+ saved_state[SMRAM_FIELD_P6_DS_SELECTOR] = cpu_state.seg_ds.seg;
+ saved_state[SMRAM_FIELD_P6_DS_BASE] = cpu_state.seg_ds.base;
+ saved_state[SMRAM_FIELD_P6_DS_LIMIT] = cpu_state.seg_ds.limit;
+ saved_state[SMRAM_FIELD_P6_DS_SELECTOR_AR] =
(cpu_state.seg_ds.ar_high << 24) | (cpu_state.seg_ds.access << 16) | cpu_state.seg_ds.seg;
/* SS */
- saved_state[SMRAM_FIELD_SS_SELECTOR] = cpu_state.seg_ss.seg;
- saved_state[SMRAM_FIELD_SS_BASE] = cpu_state.seg_ss.base;
- saved_state[SMRAM_FIELD_SS_LIMIT] = cpu_state.seg_ss.limit;
- saved_state[SMRAM_FIELD_SS_SELECTOR_AR] =
+ saved_state[SMRAM_FIELD_P6_SS_SELECTOR] = cpu_state.seg_ss.seg;
+ saved_state[SMRAM_FIELD_P6_SS_BASE] = cpu_state.seg_ss.base;
+ saved_state[SMRAM_FIELD_P6_SS_LIMIT] = cpu_state.seg_ss.limit;
+ saved_state[SMRAM_FIELD_P6_SS_SELECTOR_AR] =
(cpu_state.seg_ss.ar_high << 24) | (cpu_state.seg_ss.access << 16) | cpu_state.seg_ss.seg;
/* FS */
- saved_state[SMRAM_FIELD_FS_SELECTOR] = cpu_state.seg_fs.seg;
- saved_state[SMRAM_FIELD_FS_BASE] = cpu_state.seg_fs.base;
- saved_state[SMRAM_FIELD_FS_LIMIT] = cpu_state.seg_fs.limit;
- saved_state[SMRAM_FIELD_FS_SELECTOR_AR] =
+ saved_state[SMRAM_FIELD_P6_FS_SELECTOR] = cpu_state.seg_fs.seg;
+ saved_state[SMRAM_FIELD_P6_FS_BASE] = cpu_state.seg_fs.base;
+ saved_state[SMRAM_FIELD_P6_FS_LIMIT] = cpu_state.seg_fs.limit;
+ saved_state[SMRAM_FIELD_P6_FS_SELECTOR_AR] =
(cpu_state.seg_fs.ar_high << 24) | (cpu_state.seg_fs.access << 16) | cpu_state.seg_fs.seg;
/* GS */
- saved_state[SMRAM_FIELD_GS_SELECTOR] = cpu_state.seg_gs.seg;
- saved_state[SMRAM_FIELD_GS_BASE] = cpu_state.seg_gs.base;
- saved_state[SMRAM_FIELD_GS_LIMIT] = cpu_state.seg_gs.limit;
- saved_state[SMRAM_FIELD_GS_SELECTOR_AR] =
+ saved_state[SMRAM_FIELD_P6_GS_SELECTOR] = cpu_state.seg_gs.seg;
+ saved_state[SMRAM_FIELD_P6_GS_BASE] = cpu_state.seg_gs.base;
+ saved_state[SMRAM_FIELD_P6_GS_LIMIT] = cpu_state.seg_gs.limit;
+ saved_state[SMRAM_FIELD_P6_GS_SELECTOR_AR] =
(cpu_state.seg_gs.ar_high << 24) | (cpu_state.seg_gs.access << 16) | cpu_state.seg_gs.seg;
}
-void smram_restore_state(uint32_t *saved_state)
+void smram_restore_state_p6(uint32_t *saved_state)
{
int n = 0;
for (n = 0; n < 8; n++)
- cpu_state.regs[n].l = saved_state[SMRAM_FIELD_EAX + n];
+ cpu_state.regs[n].l = saved_state[SMRAM_FIELD_P6_EAX - n];
- cpu_state.pc = saved_state[SMRAM_FIELD_EIP];
- cpu_state.eflags = saved_state[SMRAM_FIELD_EFLAGS] >> 16;
- cpu_state.flags = saved_state[SMRAM_FIELD_EFLAGS] & 0xffff;
+ if (saved_state[SMRAM_FIELD_P6_AUTOHALT_RESTART] & 0xffff)
+ cpu_state.pc = saved_state[SMRAM_FIELD_P6_EIP] - 1;
+ else
+ cpu_state.pc = saved_state[SMRAM_FIELD_P6_EIP];
- cr0 = saved_state[SMRAM_FIELD_CR0];
- cr3 = saved_state[SMRAM_FIELD_CR3];
- if (is_pentium) {
- cr4 = saved_state[SMRAM_FIELD_CR4];
- /* TODO: Properly implement EFER */
- /* efer = saved_state[SMRAM_FIELD_EFER]; */
- }
- dr[6] = saved_state[SMRAM_FIELD_DR6];
- dr[7] = saved_state[SMRAM_FIELD_DR7];
+ cpu_state.eflags = saved_state[SMRAM_FIELD_P6_EFLAGS] >> 16;
+ cpu_state.flags = saved_state[SMRAM_FIELD_P6_EFLAGS] & 0xffff;
+
+ cr0 = saved_state[SMRAM_FIELD_P6_CR0];
+ cr3 = saved_state[SMRAM_FIELD_P6_CR3];
+ cr4 = saved_state[SMRAM_FIELD_P6_CR4];
+ dr[6] = saved_state[SMRAM_FIELD_P6_DR6];
+ dr[7] = saved_state[SMRAM_FIELD_P6_DR7];
/* TR */
- tr.seg = saved_state[SMRAM_FIELD_TR_SELECTOR];
- tr.base = saved_state[SMRAM_FIELD_TR_BASE];
- tr.limit = saved_state[SMRAM_FIELD_TR_LIMIT];
- tr.access = (saved_state[SMRAM_FIELD_TR_SELECTOR_AR] >> 16) & 0xff;
- tr.ar_high = (saved_state[SMRAM_FIELD_TR_SELECTOR_AR] >> 24) & 0xff;
+ tr.seg = saved_state[SMRAM_FIELD_P6_TR_SELECTOR];
+ tr.base = saved_state[SMRAM_FIELD_P6_TR_BASE];
+ tr.limit = saved_state[SMRAM_FIELD_P6_TR_LIMIT];
+ tr.access = (saved_state[SMRAM_FIELD_P6_TR_SELECTOR_AR] >> 16) & 0xff;
+ tr.ar_high = (saved_state[SMRAM_FIELD_P6_TR_SELECTOR_AR] >> 24) & 0xff;
smm_seg_load(&tr);
/* LDTR */
- ldt.seg = saved_state[SMRAM_FIELD_LDTR_SELECTOR];
- ldt.base = saved_state[SMRAM_FIELD_LDTR_BASE];
- ldt.limit = saved_state[SMRAM_FIELD_LDTR_LIMIT];
- ldt.access = (saved_state[SMRAM_FIELD_LDTR_SELECTOR_AR] >> 16) & 0xff;
- ldt.ar_high = (saved_state[SMRAM_FIELD_LDTR_SELECTOR_AR] >> 24) & 0xff;
+ ldt.seg = saved_state[SMRAM_FIELD_P6_LDTR_SELECTOR];
+ ldt.base = saved_state[SMRAM_FIELD_P6_LDTR_BASE];
+ ldt.limit = saved_state[SMRAM_FIELD_P6_LDTR_LIMIT];
+ ldt.access = (saved_state[SMRAM_FIELD_P6_LDTR_SELECTOR_AR] >> 16) & 0xff;
+ ldt.ar_high = (saved_state[SMRAM_FIELD_P6_LDTR_SELECTOR_AR] >> 24) & 0xff;
smm_seg_load(&ldt);
/* IDTR */
- idt.base = saved_state[SMRAM_FIELD_IDTR_BASE];
- idt.limit = saved_state[SMRAM_FIELD_IDTR_LIMIT];
+ idt.base = saved_state[SMRAM_FIELD_P6_IDTR_BASE];
+ idt.limit = saved_state[SMRAM_FIELD_P6_IDTR_LIMIT];
+ idt.access = (saved_state[SMRAM_FIELD_P6_IDTR_SELECTOR_AR] >> 16) & 0xff;
+ idt.ar_high = (saved_state[SMRAM_FIELD_P6_IDTR_SELECTOR_AR] >> 24) & 0xff;
/* GDTR */
- gdt.base = saved_state[SMRAM_FIELD_GDTR_BASE];
- gdt.limit = saved_state[SMRAM_FIELD_GDTR_LIMIT];
+ gdt.base = saved_state[SMRAM_FIELD_P6_GDTR_BASE];
+ gdt.limit = saved_state[SMRAM_FIELD_P6_GDTR_LIMIT];
+ gdt.access = (saved_state[SMRAM_FIELD_P6_GDTR_SELECTOR_AR] >> 16) & 0xff;
+ gdt.ar_high = (saved_state[SMRAM_FIELD_P6_GDTR_SELECTOR_AR] >> 24) & 0xff;
/* ES */
- cpu_state.seg_es.seg = saved_state[SMRAM_FIELD_ES_SELECTOR];
- cpu_state.seg_es.base = saved_state[SMRAM_FIELD_ES_BASE];
- cpu_state.seg_es.limit = saved_state[SMRAM_FIELD_ES_LIMIT];
- cpu_state.seg_es.access = (saved_state[SMRAM_FIELD_ES_SELECTOR_AR] >> 16) & 0xff;
- cpu_state.seg_es.ar_high = (saved_state[SMRAM_FIELD_ES_SELECTOR_AR] >> 24) & 0xff;
+ cpu_state.seg_es.seg = saved_state[SMRAM_FIELD_P6_ES_SELECTOR];
+ cpu_state.seg_es.base = saved_state[SMRAM_FIELD_P6_ES_BASE];
+ cpu_state.seg_es.limit = saved_state[SMRAM_FIELD_P6_ES_LIMIT];
+ cpu_state.seg_es.access = (saved_state[SMRAM_FIELD_P6_ES_SELECTOR_AR] >> 16) & 0xff;
+ cpu_state.seg_es.ar_high = (saved_state[SMRAM_FIELD_P6_ES_SELECTOR_AR] >> 24) & 0xff;
smm_seg_load(&cpu_state.seg_es);
/* CS */
- cpu_state.seg_cs.seg = saved_state[SMRAM_FIELD_CS_SELECTOR];
- cpu_state.seg_cs.base = saved_state[SMRAM_FIELD_CS_BASE];
- cpu_state.seg_cs.limit = saved_state[SMRAM_FIELD_CS_LIMIT];
- cpu_state.seg_cs.access = (saved_state[SMRAM_FIELD_CS_SELECTOR_AR] >> 16) & 0xff;
- cpu_state.seg_cs.ar_high = (saved_state[SMRAM_FIELD_CS_SELECTOR_AR] >> 24) & 0xff;
+ cpu_state.seg_cs.seg = saved_state[SMRAM_FIELD_P6_CS_SELECTOR];
+ cpu_state.seg_cs.base = saved_state[SMRAM_FIELD_P6_CS_BASE];
+ cpu_state.seg_cs.limit = saved_state[SMRAM_FIELD_P6_CS_LIMIT];
+ cpu_state.seg_cs.access = (saved_state[SMRAM_FIELD_P6_CS_SELECTOR_AR] >> 16) & 0xff;
+ cpu_state.seg_cs.ar_high = (saved_state[SMRAM_FIELD_P6_CS_SELECTOR_AR] >> 24) & 0xff;
smm_seg_load(&cpu_state.seg_cs);
+ cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~0x60) | ((saved_state[SMRAM_FIELD_P6_CPL] & 0x03) << 5);
/* DS */
- cpu_state.seg_ds.seg = saved_state[SMRAM_FIELD_DS_SELECTOR];
- cpu_state.seg_ds.base = saved_state[SMRAM_FIELD_DS_BASE];
- cpu_state.seg_ds.limit = saved_state[SMRAM_FIELD_DS_LIMIT];
- cpu_state.seg_ds.access = (saved_state[SMRAM_FIELD_DS_SELECTOR_AR] >> 16) & 0xff;
- cpu_state.seg_ds.ar_high = (saved_state[SMRAM_FIELD_DS_SELECTOR_AR] >> 24) & 0xff;
+ cpu_state.seg_ds.seg = saved_state[SMRAM_FIELD_P6_DS_SELECTOR];
+ cpu_state.seg_ds.base = saved_state[SMRAM_FIELD_P6_DS_BASE];
+ cpu_state.seg_ds.limit = saved_state[SMRAM_FIELD_P6_DS_LIMIT];
+ cpu_state.seg_ds.access = (saved_state[SMRAM_FIELD_P6_DS_SELECTOR_AR] >> 16) & 0xff;
+ cpu_state.seg_ds.ar_high = (saved_state[SMRAM_FIELD_P6_DS_SELECTOR_AR] >> 24) & 0xff;
smm_seg_load(&cpu_state.seg_ds);
/* SS */
- cpu_state.seg_ss.seg = saved_state[SMRAM_FIELD_SS_SELECTOR];
- cpu_state.seg_ss.base = saved_state[SMRAM_FIELD_SS_BASE];
- cpu_state.seg_ss.limit = saved_state[SMRAM_FIELD_SS_LIMIT];
- cpu_state.seg_ss.access = (saved_state[SMRAM_FIELD_SS_SELECTOR_AR] >> 16) & 0xff;
- cpu_state.seg_ss.ar_high = (saved_state[SMRAM_FIELD_SS_SELECTOR_AR] >> 24) & 0xff;
+ cpu_state.seg_ss.seg = saved_state[SMRAM_FIELD_P6_SS_SELECTOR];
+ cpu_state.seg_ss.base = saved_state[SMRAM_FIELD_P6_SS_BASE];
+ cpu_state.seg_ss.limit = saved_state[SMRAM_FIELD_P6_SS_LIMIT];
+ cpu_state.seg_ss.access = (saved_state[SMRAM_FIELD_P6_SS_SELECTOR_AR] >> 16) & 0xff;
+ cpu_state.seg_ss.ar_high = (saved_state[SMRAM_FIELD_P6_SS_SELECTOR_AR] >> 24) & 0xff;
smm_seg_load(&cpu_state.seg_ss);
/* FS */
- cpu_state.seg_fs.seg = saved_state[SMRAM_FIELD_FS_SELECTOR];
- cpu_state.seg_fs.base = saved_state[SMRAM_FIELD_FS_BASE];
- cpu_state.seg_fs.limit = saved_state[SMRAM_FIELD_FS_LIMIT];
- cpu_state.seg_fs.access = (saved_state[SMRAM_FIELD_FS_SELECTOR_AR] >> 16) & 0xff;
- cpu_state.seg_fs.ar_high = (saved_state[SMRAM_FIELD_FS_SELECTOR_AR] >> 24) & 0xff;
+ cpu_state.seg_fs.seg = saved_state[SMRAM_FIELD_P6_FS_SELECTOR];
+ cpu_state.seg_fs.base = saved_state[SMRAM_FIELD_P6_FS_BASE];
+ cpu_state.seg_fs.limit = saved_state[SMRAM_FIELD_P6_FS_LIMIT];
+ cpu_state.seg_fs.access = (saved_state[SMRAM_FIELD_P6_FS_SELECTOR_AR] >> 16) & 0xff;
+ cpu_state.seg_fs.ar_high = (saved_state[SMRAM_FIELD_P6_FS_SELECTOR_AR] >> 24) & 0xff;
smm_seg_load(&cpu_state.seg_fs);
/* GS */
- cpu_state.seg_gs.seg = saved_state[SMRAM_FIELD_GS_SELECTOR];
- cpu_state.seg_gs.base = saved_state[SMRAM_FIELD_GS_BASE];
- cpu_state.seg_gs.limit = saved_state[SMRAM_FIELD_GS_LIMIT];
- cpu_state.seg_gs.access = (saved_state[SMRAM_FIELD_GS_SELECTOR_AR] >> 16) & 0xff;
- cpu_state.seg_gs.ar_high = (saved_state[SMRAM_FIELD_GS_SELECTOR_AR] >> 24) & 0xff;
+ cpu_state.seg_gs.seg = saved_state[SMRAM_FIELD_P6_GS_SELECTOR];
+ cpu_state.seg_gs.base = saved_state[SMRAM_FIELD_P6_GS_BASE];
+ cpu_state.seg_gs.limit = saved_state[SMRAM_FIELD_P6_GS_LIMIT];
+ cpu_state.seg_gs.access = (saved_state[SMRAM_FIELD_P6_GS_SELECTOR_AR] >> 16) & 0xff;
+ cpu_state.seg_gs.ar_high = (saved_state[SMRAM_FIELD_P6_GS_SELECTOR_AR] >> 24) & 0xff;
+ smm_seg_load(&cpu_state.seg_gs);
+
+ mem_a20_alt = (!saved_state[SMRAM_FIELD_P6_A20M]) << 1;
+ keyboard_at_set_a20_key(!saved_state[SMRAM_FIELD_P6_A20M]);
+ mem_a20_recalc();
+
+ if (SMM_REVISION_ID & SMM_SMBASE_RELOCATION)
+ smbase = saved_state[SMRAM_FIELD_P6_SMBASE_OFFSET];
+}
+
+
+void smram_save_state_amd_k(uint32_t *saved_state)
+{
+ int n = 0;
+
+ saved_state[SMRAM_FIELD_AMD_K_SMM_REVISION_ID] = SMM_REVISION_ID;
+ saved_state[SMRAM_FIELD_AMD_K_SMBASE_OFFSET] = smbase;
+
+ for (n = 0; n < 8; n++)
+ saved_state[SMRAM_FIELD_AMD_K_EAX - n] = cpu_state.regs[n].l;
+
+ if (in_hlt) {
+ saved_state[SMRAM_FIELD_AMD_K_AUTOHALT_RESTART] = 1;
+ saved_state[SMRAM_FIELD_AMD_K_EIP] = cpu_state.pc + 1;
+ } else {
+ saved_state[SMRAM_FIELD_AMD_K_AUTOHALT_RESTART] = 0;
+ saved_state[SMRAM_FIELD_AMD_K_EIP] = cpu_state.pc;
+ }
+
+ saved_state[SMRAM_FIELD_AMD_K_EFLAGS] = (cpu_state.eflags << 16) | (cpu_state.flags);
+
+ saved_state[SMRAM_FIELD_AMD_K_CR0] = cr0;
+ saved_state[SMRAM_FIELD_AMD_K_CR2] = cr2;
+ saved_state[SMRAM_FIELD_AMD_K_CR3] = cr3;
+ saved_state[SMRAM_FIELD_AMD_K_CR4] = cr4;
+ saved_state[SMRAM_FIELD_AMD_K_DR6] = dr[6];
+ saved_state[SMRAM_FIELD_AMD_K_DR7] = dr[7];
+
+ /* TR */
+ saved_state[SMRAM_FIELD_AMD_K_TR_SELECTOR] = tr.seg;
+ saved_state[SMRAM_FIELD_AMD_K_TR_BASE] = tr.base;
+ saved_state[SMRAM_FIELD_AMD_K_TR_LIMIT] = tr.limit;
+ saved_state[SMRAM_FIELD_AMD_K_TR_ACCESS] = (tr.ar_high << 16) | (tr.access << 8);
+
+ /* LDTR */
+ saved_state[SMRAM_FIELD_AMD_K_LDTR_SELECTOR] = ldt.seg;
+ saved_state[SMRAM_FIELD_AMD_K_LDTR_BASE] = ldt.base;
+ saved_state[SMRAM_FIELD_AMD_K_LDTR_LIMIT] = ldt.limit;
+ if (!is_k6)
+ saved_state[SMRAM_FIELD_AMD_K_LDTR_ACCESS] = (ldt.ar_high << 16) | (ldt.access << 8);
+
+ /* IDTR */
+ saved_state[SMRAM_FIELD_AMD_K_IDTR_BASE] = idt.base;
+ saved_state[SMRAM_FIELD_AMD_K_IDTR_LIMIT] = idt.limit;
+
+ /* GDTR */
+ saved_state[SMRAM_FIELD_AMD_K_GDTR_BASE] = gdt.base;
+ saved_state[SMRAM_FIELD_AMD_K_GDTR_LIMIT] = gdt.limit;
+
+ /* ES */
+ saved_state[SMRAM_FIELD_AMD_K_ES_SELECTOR] = cpu_state.seg_es.seg;
+ saved_state[SMRAM_FIELD_AMD_K_ES_BASE] = cpu_state.seg_es.base;
+ saved_state[SMRAM_FIELD_AMD_K_ES_LIMIT] = cpu_state.seg_es.limit;
+ saved_state[SMRAM_FIELD_AMD_K_ES_ACCESS] = (cpu_state.seg_es.ar_high << 16) | (cpu_state.seg_es.access << 8);
+
+ /* CS */
+ saved_state[SMRAM_FIELD_AMD_K_CS_SELECTOR] = cpu_state.seg_cs.seg;
+ saved_state[SMRAM_FIELD_AMD_K_CS_BASE] = cpu_state.seg_cs.base;
+ saved_state[SMRAM_FIELD_AMD_K_CS_LIMIT] = cpu_state.seg_cs.limit;
+ saved_state[SMRAM_FIELD_AMD_K_CS_ACCESS] = (cpu_state.seg_cs.ar_high << 16) | (cpu_state.seg_cs.access << 8);
+
+ /* DS */
+ saved_state[SMRAM_FIELD_AMD_K_DS_SELECTOR] = cpu_state.seg_ds.seg;
+ saved_state[SMRAM_FIELD_AMD_K_DS_BASE] = cpu_state.seg_ds.base;
+ saved_state[SMRAM_FIELD_AMD_K_DS_LIMIT] = cpu_state.seg_ds.limit;
+ saved_state[SMRAM_FIELD_AMD_K_DS_ACCESS] = (cpu_state.seg_ds.ar_high << 16) | (cpu_state.seg_ds.access << 8);
+
+ /* SS */
+ saved_state[SMRAM_FIELD_AMD_K_SS_SELECTOR] = cpu_state.seg_ss.seg;
+ saved_state[SMRAM_FIELD_AMD_K_SS_BASE] = cpu_state.seg_ss.base;
+ saved_state[SMRAM_FIELD_AMD_K_SS_LIMIT] = cpu_state.seg_ss.limit;
+ saved_state[SMRAM_FIELD_AMD_K_SS_ACCESS] = (cpu_state.seg_ss.ar_high << 16) | (cpu_state.seg_ss.access << 8);
+
+ /* FS */
+ saved_state[SMRAM_FIELD_AMD_K_FS_SELECTOR] = cpu_state.seg_fs.seg;
+ saved_state[SMRAM_FIELD_AMD_K_FS_BASE] = cpu_state.seg_fs.base;
+ saved_state[SMRAM_FIELD_AMD_K_FS_LIMIT] = cpu_state.seg_fs.limit;
+ saved_state[SMRAM_FIELD_AMD_K_FS_ACCESS] = (cpu_state.seg_fs.ar_high << 16) | (cpu_state.seg_fs.access << 8);
+
+ /* GS */
+ saved_state[SMRAM_FIELD_AMD_K_GS_SELECTOR] = cpu_state.seg_gs.seg;
+ saved_state[SMRAM_FIELD_AMD_K_GS_BASE] = cpu_state.seg_gs.base;
+ saved_state[SMRAM_FIELD_AMD_K_GS_LIMIT] = cpu_state.seg_gs.limit;
+ saved_state[SMRAM_FIELD_AMD_K_GS_ACCESS] = (cpu_state.seg_gs.ar_high << 16) | (cpu_state.seg_gs.access << 8);
+}
+
+
+void smram_restore_state_amd_k(uint32_t *saved_state)
+{
+ int n = 0;
+
+ for (n = 0; n < 8; n++)
+ cpu_state.regs[n].l = saved_state[SMRAM_FIELD_AMD_K_EAX - n];
+
+ if (saved_state[SMRAM_FIELD_AMD_K_AUTOHALT_RESTART] & 0xffff)
+ cpu_state.pc = saved_state[SMRAM_FIELD_AMD_K_EIP] - 1;
+ else
+ cpu_state.pc = saved_state[SMRAM_FIELD_AMD_K_EIP];
+
+ cpu_state.eflags = saved_state[SMRAM_FIELD_AMD_K_EFLAGS] >> 16;
+ cpu_state.flags = saved_state[SMRAM_FIELD_AMD_K_EFLAGS] & 0xffff;
+
+ cr0 = saved_state[SMRAM_FIELD_AMD_K_CR0];
+ cr2 = saved_state[SMRAM_FIELD_AMD_K_CR2];
+ cr3 = saved_state[SMRAM_FIELD_AMD_K_CR3];
+ cr4 = saved_state[SMRAM_FIELD_AMD_K_CR4];
+ dr[6] = saved_state[SMRAM_FIELD_AMD_K_DR6];
+ dr[7] = saved_state[SMRAM_FIELD_AMD_K_DR7];
+
+ /* TR */
+ tr.seg = saved_state[SMRAM_FIELD_AMD_K_TR_SELECTOR];
+ tr.base = saved_state[SMRAM_FIELD_AMD_K_TR_BASE];
+ tr.limit = saved_state[SMRAM_FIELD_AMD_K_TR_LIMIT];
+ tr.access = (saved_state[SMRAM_FIELD_AMD_K_TR_ACCESS] >> 8) & 0xff;
+ tr.ar_high = (saved_state[SMRAM_FIELD_AMD_K_TR_ACCESS] >> 16) & 0xff;
+ smm_seg_load(&tr);
+
+ /* LDTR */
+ ldt.seg = saved_state[SMRAM_FIELD_AMD_K_LDTR_SELECTOR];
+ ldt.base = saved_state[SMRAM_FIELD_AMD_K_LDTR_BASE];
+ ldt.limit = saved_state[SMRAM_FIELD_AMD_K_LDTR_LIMIT];
+ if (!is_k6) {
+ ldt.access = (saved_state[SMRAM_FIELD_AMD_K_LDTR_ACCESS] >> 8) & 0xff;
+ ldt.ar_high = (saved_state[SMRAM_FIELD_AMD_K_LDTR_ACCESS] >> 16) & 0xff;
+ }
+ smm_seg_load(&ldt);
+
+ /* IDTR */
+ idt.base = saved_state[SMRAM_FIELD_AMD_K_IDTR_BASE];
+ idt.limit = saved_state[SMRAM_FIELD_AMD_K_IDTR_LIMIT];
+
+ /* GDTR */
+ gdt.base = saved_state[SMRAM_FIELD_AMD_K_GDTR_BASE];
+ gdt.limit = saved_state[SMRAM_FIELD_AMD_K_GDTR_LIMIT];
+
+ /* ES */
+ cpu_state.seg_es.seg = saved_state[SMRAM_FIELD_AMD_K_ES_SELECTOR];
+ cpu_state.seg_es.base = saved_state[SMRAM_FIELD_AMD_K_ES_BASE];
+ cpu_state.seg_es.limit = saved_state[SMRAM_FIELD_AMD_K_ES_LIMIT];
+ cpu_state.seg_es.access = (saved_state[SMRAM_FIELD_AMD_K_ES_ACCESS] >> 8) & 0xff;
+ cpu_state.seg_es.ar_high = (saved_state[SMRAM_FIELD_AMD_K_ES_ACCESS] >> 16) & 0xff;
+ smm_seg_load(&cpu_state.seg_es);
+
+ /* CS */
+ cpu_state.seg_cs.seg = saved_state[SMRAM_FIELD_AMD_K_CS_SELECTOR];
+ cpu_state.seg_cs.base = saved_state[SMRAM_FIELD_AMD_K_CS_BASE];
+ cpu_state.seg_cs.limit = saved_state[SMRAM_FIELD_AMD_K_CS_LIMIT];
+ cpu_state.seg_cs.access = (saved_state[SMRAM_FIELD_AMD_K_CS_ACCESS] >> 8) & 0xff;
+ cpu_state.seg_cs.ar_high = (saved_state[SMRAM_FIELD_AMD_K_CS_ACCESS] >> 16) & 0xff;
+ smm_seg_load(&cpu_state.seg_cs);
+
+ /* DS */
+ cpu_state.seg_ds.seg = saved_state[SMRAM_FIELD_AMD_K_DS_SELECTOR];
+ cpu_state.seg_ds.base = saved_state[SMRAM_FIELD_AMD_K_DS_BASE];
+ cpu_state.seg_ds.limit = saved_state[SMRAM_FIELD_AMD_K_DS_LIMIT];
+ cpu_state.seg_ds.access = (saved_state[SMRAM_FIELD_AMD_K_DS_ACCESS] >> 8) & 0xff;
+ cpu_state.seg_ds.ar_high = (saved_state[SMRAM_FIELD_AMD_K_DS_ACCESS] >> 16) & 0xff;
+ smm_seg_load(&cpu_state.seg_ds);
+
+ /* SS */
+ cpu_state.seg_ss.seg = saved_state[SMRAM_FIELD_AMD_K_SS_SELECTOR];
+ cpu_state.seg_ss.base = saved_state[SMRAM_FIELD_AMD_K_SS_BASE];
+ cpu_state.seg_ss.limit = saved_state[SMRAM_FIELD_AMD_K_SS_LIMIT];
+ cpu_state.seg_ss.access = (saved_state[SMRAM_FIELD_AMD_K_SS_ACCESS] >> 8) & 0xff;
+ /* The actual CPL (DPL of CS) is overwritten with DPL of SS. */
+ cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~0x60) | (cpu_state.seg_ss.access & 0x60);
+ cpu_state.seg_ss.ar_high = (saved_state[SMRAM_FIELD_AMD_K_SS_ACCESS] >> 16) & 0xff;
+ smm_seg_load(&cpu_state.seg_ss);
+
+ /* FS */
+ cpu_state.seg_fs.seg = saved_state[SMRAM_FIELD_AMD_K_FS_SELECTOR];
+ cpu_state.seg_fs.base = saved_state[SMRAM_FIELD_AMD_K_FS_BASE];
+ cpu_state.seg_fs.limit = saved_state[SMRAM_FIELD_AMD_K_FS_LIMIT];
+ cpu_state.seg_fs.access = (saved_state[SMRAM_FIELD_AMD_K_FS_ACCESS] >> 8) & 0xff;
+ cpu_state.seg_fs.ar_high = (saved_state[SMRAM_FIELD_AMD_K_FS_ACCESS] >> 16) & 0xff;
+ smm_seg_load(&cpu_state.seg_fs);
+
+ /* GS */
+ cpu_state.seg_gs.seg = saved_state[SMRAM_FIELD_AMD_K_GS_SELECTOR];
+ cpu_state.seg_gs.base = saved_state[SMRAM_FIELD_AMD_K_GS_BASE];
+ cpu_state.seg_gs.limit = saved_state[SMRAM_FIELD_AMD_K_GS_LIMIT];
+ cpu_state.seg_gs.access = (saved_state[SMRAM_FIELD_AMD_K_GS_ACCESS] >> 8) & 0xff;
+ cpu_state.seg_gs.ar_high = (saved_state[SMRAM_FIELD_AMD_K_GS_ACCESS] >> 16) & 0xff;
smm_seg_load(&cpu_state.seg_gs);
if (SMM_REVISION_ID & SMM_SMBASE_RELOCATION)
- smbase = saved_state[SMRAM_FIELD_SMBASE_OFFSET];
+ smbase = saved_state[SMRAM_FIELD_AMD_K_SMBASE_OFFSET];
}
@@ -592,6 +1136,10 @@ void enter_smm()
uint32_t saved_state[SMM_SAVE_STATE_MAP_SIZE], n;
uint32_t smram_state = smbase + 0x10000;
+ /* If it's a CPU on which SMM is not supporter, do nothing. */
+ if (!is_pentium && !is_k5 && !is_k6 && !is_p6)
+ return;
+
x386_dynarec_log("enter_smm(): smbase = %08X\n", smbase);
x386_dynarec_log("CS : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n",
cpu_state.seg_cs.seg, cpu_state.seg_cs.base, cpu_state.seg_cs.limit, cpu_state.seg_cs.limit_low,
@@ -624,8 +1172,22 @@ void enter_smm()
x386_dynarec_log("EAX = %08X, EBX = %08X, ECX = %08X, EDX = %08X, ESI = %08X, EDI = %08X, ESP = %08X, EBP = %08X\n",
EAX, EBX, ECX, EDX, ESI, EDI, ESP, EBP);
+ in_smm = 1;
+ mem_mapping_recalc(0x00030000, 0x00020000);
+ mem_mapping_recalc(0x000a0000, 0x00060000);
+ if (!cpu_16bitbus)
+ mem_mapping_recalc(0x100a0000, 0x00060000);
+ if (mem_size >= 1024)
+ mem_mapping_recalc((mem_size << 10) - (1 << 20), (1 << 20));
+ flushmmucache();
+
memset(saved_state, 0x00, SMM_SAVE_STATE_MAP_SIZE * sizeof(uint32_t));
- smram_save_state(saved_state);
+ if (is_pentium) /* Intel P5 (Pentium) */
+ smram_save_state_p5(saved_state);
+ else if (is_k5 || is_k6) /* AMD K5 and K6 */
+ smram_save_state_amd_k(saved_state);
+ else if (is_p6) /* Intel P6 (Pentium Pro, Pentium II, Celeron) */
+ smram_save_state_p6(saved_state);
for (n = 0; n < SMM_SAVE_STATE_MAP_SIZE; n++) {
smram_state -= 4;
mem_writel_phys(smram_state, saved_state[n]);
@@ -635,12 +1197,7 @@ void enter_smm()
cpu_state.flags = 2;
cpu_state.eflags = 0;
- /* Intel 4x0 chipset stuff. */
- mem_set_mem_state(0xa0000, 131072, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
- flushmmucache_cr3();
-
- if (is_pentium)
- cr4 = 0;
+ cr4 = 0;
dr[7] = 0x400;
cpu_state.pc = 0x8000;
@@ -655,7 +1212,11 @@ void enter_smm()
memcpy(&cpu_state.seg_fs, &cpu_state.seg_ds, sizeof(x86seg));
memcpy(&cpu_state.seg_gs, &cpu_state.seg_ds, sizeof(x86seg));
- CS = (smbase >> 4);
+ if (is_p6)
+ cpu_state.seg_cs.seg = (smbase >> 4);
+ else
+ cpu_state.seg_cs.seg = 0x3000;
+ /* On Pentium, CS selector in SMM is always 3000, regardless of SMBASE. */
cpu_state.seg_cs.base = smbase;
cpu_state.seg_cs.limit = 0xffffffff;
cpu_state.seg_cs.access = 0x93;
@@ -669,9 +1230,16 @@ void enter_smm()
smm_seg_load(&cpu_state.seg_fs);
smm_seg_load(&cpu_state.seg_gs);
+ cpu_state.op32 = use32;
+
nmi_mask = 0;
- in_smm = 1;
+ if (smi_latched) {
+ in_smm = 2;
+ smi_latched = 0;
+ } else
+ in_smm = 1;
+
CPU_BLOCK_END();
}
@@ -681,20 +1249,43 @@ void leave_smm()
uint32_t saved_state[SMM_SAVE_STATE_MAP_SIZE], n;
uint32_t smram_state = smbase + 0x10000;
+ /* If it's a CPU on which SMM is not supporter, do nothing. */
+ if (!is_pentium && !is_k5 && !is_k6 && !is_p6)
+ return;
+
memset(saved_state, 0x00, SMM_SAVE_STATE_MAP_SIZE * sizeof(uint32_t));
for (n = 0; n < SMM_SAVE_STATE_MAP_SIZE; n++) {
smram_state -= 4;
saved_state[n] = mem_readl_phys(smram_state);
+ x386_dynarec_log("Reading %08X from memory at %08X to array element %i\n", saved_state[n], smram_state, n);
}
- smram_restore_state(saved_state);
+#ifdef ENABLE_386_DYNAREC_LOG
+ for (n = 0; n < SMM_SAVE_STATE_MAP_SIZE; n++) {
+ if (saved_state[n] == 0x000a0000)
+ x86_dynarec_log("SMBASE found in array element %i (we have %i)\n", n, SMRAM_FIELD_P5_SMBASE_OFFSET);
+ }
+#endif
+ x386_dynarec_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);
+ else if (is_k5 || is_k6) /* AMD K5 and K6 */
+ smram_restore_state_amd_k(saved_state);
+ else if (is_p6) /* Intel P6 (Pentium Pro, Pentium II, Celeron) */
+ smram_restore_state_p6(saved_state);
- /* Intel 4x0 chipset stuff. */
- mem_restore_mem_state(0xa0000, 131072);
- flushmmucache_cr3();
+ in_smm = 0;
+ mem_mapping_recalc(0x00030000, 0x00020000);
+ mem_mapping_recalc(0x000a0000, 0x00060000);
+ if (!cpu_16bitbus)
+ mem_mapping_recalc(0x100a0000, 0x00060000);
+ if (mem_size >= 1024)
+ mem_mapping_recalc((mem_size << 10) - (1 << 20), (1 << 20));
+ flushmmucache();
+
+ cpu_state.op32 = use32;
nmi_mask = 1;
- in_smm = 0;
CPU_BLOCK_END();
x386_dynarec_log("CS : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n",
@@ -732,8 +1323,8 @@ void leave_smm()
#define OP_TABLE(name) ops_ ## name
-#define CLOCK_CYCLES(c) cycles -= (c)
-#define CLOCK_CYCLES_ALWAYS(c) cycles -= (c)
+#define CLOCK_CYCLES(c) do { cycles -= (c); in_hlt = 0; } while(0)
+#define CLOCK_CYCLES_ALWAYS(c) do { cycles -= (c); in_hlt = 0; } while(0)
#include "386_ops.h"
@@ -809,7 +1400,7 @@ void exec386_dynarec(int cycs)
if (((cs + cpu_state.pc) >> 12) != pccache)
CPU_BLOCK_END();
- if (!in_smm && smi_line/* && is_pentium*/)
+ if ((in_smm == 0) && smi_line)
CPU_BLOCK_END();
if (cpu_state.abrt)
@@ -1038,7 +1629,7 @@ void exec386_dynarec(int cycs)
#endif
CPU_BLOCK_END();
- if (!in_smm && smi_line/* && is_pentium*/)
+ if ((in_smm == 0) && smi_line)
CPU_BLOCK_END();
if (trap)
@@ -1124,7 +1715,7 @@ void exec386_dynarec(int cycs)
#endif
CPU_BLOCK_END();
- if (!in_smm && smi_line/* && is_pentium*/)
+ if ((in_smm == 0) && smi_line)
CPU_BLOCK_END();
if (trap)
@@ -1183,12 +1774,25 @@ void exec386_dynarec(int cycs)
}
}
- if (!in_smm && smi_line/* && is_pentium*/) {
+ if ((in_smm == 0) && smi_line) {
+#ifdef ENABLE_386_DYNAREC_LOG
+ x386_dynarec_log("SMI while not in SMM\n");
+#endif
enter_smm();
smi_line = 0;
- } else if (in_smm && smi_line/* && is_pentium*/) {
+ } else if ((in_smm == 1) && smi_line) {
+ /* Mark this so that we don't latch more than one SMI. */
+#ifdef ENABLE_386_DYNAREC_LOG
+ x386_dynarec_log("SMI while in unlatched SMM\n");
+#endif
smi_latched = 1;
smi_line = 0;
+ } else if ((in_smm == 2) && smi_line) {
+ /* Mark this so that we don't latch more than one SMI. */
+#ifdef ENABLE_386_DYNAREC_LOG
+ x386_dynarec_log("SMI while in latched SMM\n");
+#endif
+ smi_line = 0;
}
else if (trap)
diff --git a/src/cpu_common/386_dynarec.c.temp b/src/cpu_common/386_dynarec.c.temp
deleted file mode 100644
index effcc7246..000000000
--- a/src/cpu_common/386_dynarec.c.temp
+++ /dev/null
@@ -1,900 +0,0 @@
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#ifndef INFINITY
-# define INFINITY (__builtin_inff())
-#endif
-
-#define HAVE_STDARG_H
-#include <86box/86box.h>
-#include "cpu.h"
-#include "x86.h"
-#include "x86_ops.h"
-#include "x87.h"
-#include <86box/io.h>
-#include <86box/mem.h>
-#include <86box/nmi.h>
-#include <86box/pic.h>
-#include <86box/timer.h>
-#include <86box/fdd.h>
-#include <86box/fdc.h>
-#ifdef USE_DYNAREC
-#include "codegen.h"
-#ifdef USE_NEW_DYNAREC
-#include "codegen_backend.h"
-#endif
-#endif
-#include "386_common.h"
-
-
-#define CPU_BLOCK_END() cpu_block_end = 1
-
-
-int inrecomp = 0, cpu_block_end = 0;
-int cpu_recomp_blocks, cpu_recomp_full_ins, cpu_new_blocks;
-int cpu_recomp_blocks_latched, cpu_recomp_ins_latched, cpu_recomp_full_ins_latched, cpu_new_blocks_latched;
-
-
-#ifdef ENABLE_386_DYNAREC_LOG
-int x386_dynarec_do_log = ENABLE_386_DYNAREC_LOG;
-
-
-void
-x386_dynarec_log(const char *fmt, ...)
-{
- va_list ap;
-
- if (x386_dynarec_do_log) {
- va_start(ap, fmt);
- pclog_ex(fmt, ap);
- va_end(ap);
- }
-}
-#else
-#define x386_dynarec_log(fmt, ...)
-#endif
-
-
-static __inline void fetch_ea_32_long(uint32_t rmdat)
-{
- eal_r = eal_w = NULL;
- easeg = cpu_state.ea_seg->base;
- if (cpu_rm == 4)
- {
- uint8_t sib = rmdat >> 8;
-
- switch (cpu_mod)
- {
- case 0:
- cpu_state.eaaddr = cpu_state.regs[sib & 7].l;
- cpu_state.pc++;
- break;
- case 1:
- cpu_state.pc++;
- cpu_state.eaaddr = ((uint32_t)(int8_t)getbyte()) + cpu_state.regs[sib & 7].l;
- break;
- case 2:
- cpu_state.eaaddr = (fastreadl(cs + cpu_state.pc + 1)) + cpu_state.regs[sib & 7].l;
- cpu_state.pc += 5;
- break;
- }
- /*SIB byte present*/
- if ((sib & 7) == 5 && !cpu_mod)
- cpu_state.eaaddr = getlong();
- else if ((sib & 6) == 4 && !cpu_state.ssegs)
- {
- easeg = ss;
- cpu_state.ea_seg = &cpu_state.seg_ss;
- }
- if (((sib >> 3) & 7) != 4)
- cpu_state.eaaddr += cpu_state.regs[(sib >> 3) & 7].l << (sib >> 6);
- }
- else
- {
- cpu_state.eaaddr = cpu_state.regs[cpu_rm].l;
- if (cpu_mod)
- {
- if (cpu_rm == 5 && !cpu_state.ssegs)
- {
- easeg = ss;
- cpu_state.ea_seg = &cpu_state.seg_ss;
- }
- if (cpu_mod == 1)
- {
- cpu_state.eaaddr += ((uint32_t)(int8_t)(rmdat >> 8));
- cpu_state.pc++;
- }
- else
- {
- cpu_state.eaaddr += getlong();
- }
- }
- else if (cpu_rm == 5)
- {
- cpu_state.eaaddr = getlong();
- }
- }
- if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC)
- {
- uint32_t addr = easeg + cpu_state.eaaddr;
- if ( readlookup2[addr >> 12] != -1)
- eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr);
- if (writelookup2[addr >> 12] != -1)
- eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr);
- }
- cpu_state.last_ea = cpu_state.eaaddr;
-}
-
-static __inline void fetch_ea_16_long(uint32_t rmdat)
-{
- eal_r = eal_w = NULL;
- easeg = cpu_state.ea_seg->base;
- if (!cpu_mod && cpu_rm == 6)
- {
- cpu_state.eaaddr = getword();
- }
- else
- {
- switch (cpu_mod)
- {
- case 0:
- cpu_state.eaaddr = 0;
- break;
- case 1:
- cpu_state.eaaddr = (uint16_t)(int8_t)(rmdat >> 8); cpu_state.pc++;
- break;
- case 2:
- cpu_state.eaaddr = getword();
- break;
- }
- cpu_state.eaaddr += (*mod1add[0][cpu_rm]) + (*mod1add[1][cpu_rm]);
- if (mod1seg[cpu_rm] == &ss && !cpu_state.ssegs)
- {
- easeg = ss;
- cpu_state.ea_seg = &cpu_state.seg_ss;
- }
- cpu_state.eaaddr &= 0xFFFF;
- }
- if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC)
- {
- uint32_t addr = easeg + cpu_state.eaaddr;
- if ( readlookup2[addr >> 12] != -1)
- eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr);
- if (writelookup2[addr >> 12] != -1)
- eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr);
- }
- cpu_state.last_ea = cpu_state.eaaddr;
-}
-
-#define fetch_ea_16(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_16_long(rmdat); if (cpu_state.abrt) return 1; }
-#define fetch_ea_32(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_32_long(rmdat); } if (cpu_state.abrt) return 1
-
-#include "x86_flags.h"
-
-
-/*Prefetch emulation is a fairly simplistic model:
- - All instruction bytes must be fetched before it starts.
- - Cycles used for non-instruction memory accesses are counted and subtracted
- from the total cycles taken
- - Any remaining cycles are used to refill the prefetch queue.
-
- Note that this is only used for 286 / 386 systems. It is disabled when the
- internal cache on 486+ CPUs is enabled.
-*/
-static int prefetch_bytes = 0;
-static int prefetch_prefixes = 0;
-
-static void prefetch_run(int instr_cycles, int bytes, int modrm, int reads, int reads_l, int writes, int writes_l, int ea32)
-{
- int mem_cycles = reads*cpu_cycles_read + reads_l*cpu_cycles_read_l + writes*cpu_cycles_write + writes_l*cpu_cycles_write_l;
-
- if (instr_cycles < mem_cycles)
- instr_cycles = mem_cycles;
-
- prefetch_bytes -= prefetch_prefixes;
- prefetch_bytes -= bytes;
- if (modrm != -1)
- {
- if (ea32)
- {
- if ((modrm & 7) == 4)
- {
- if ((modrm & 0x700) == 0x500)
- prefetch_bytes -= 5;
- else if ((modrm & 0xc0) == 0x40)
- prefetch_bytes -= 2;
- else if ((modrm & 0xc0) == 0x80)
- prefetch_bytes -= 5;
- }
- else
- {
- if ((modrm & 0xc7) == 0x05)
- prefetch_bytes -= 4;
- else if ((modrm & 0xc0) == 0x40)
- prefetch_bytes--;
- else if ((modrm & 0xc0) == 0x80)
- prefetch_bytes -= 4;
- }
- }
- else
- {
- if ((modrm & 0xc7) == 0x06)
- prefetch_bytes -= 2;
- else if ((modrm & 0xc0) != 0xc0)
- prefetch_bytes -= ((modrm & 0xc0) >> 6);
- }
- }
-
- /* Fill up prefetch queue */
- while (prefetch_bytes < 0)
- {
- prefetch_bytes += cpu_prefetch_width;
- cycles -= cpu_prefetch_cycles;
- }
-
- /* Subtract cycles used for memory access by instruction */
- instr_cycles -= mem_cycles;
-
- while (instr_cycles >= cpu_prefetch_cycles)
- {
- prefetch_bytes += cpu_prefetch_width;
- instr_cycles -= cpu_prefetch_cycles;
- }
-
- prefetch_prefixes = 0;
- if (prefetch_bytes > 16)
- prefetch_bytes = 16;
-}
-
-static void prefetch_flush()
-{
- prefetch_bytes = 0;
-}
-
-#define PREFETCH_RUN(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32) \
- do { if (cpu_prefetch_cycles) prefetch_run(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32); } while (0)
-
-#define PREFETCH_PREFIX() do { if (cpu_prefetch_cycles) prefetch_prefixes++; } while (0)
-#define PREFETCH_FLUSH() prefetch_flush()
-
-
-void enter_smm()
-{
- uint32_t smram_state = smbase + 0xfe00;
- uint32_t old_cr0 = cr0;
- uint32_t old_flags = cpu_state.flags | ((uint32_t)cpu_state.eflags << 16);
-
- cr0 &= ~0x8000000d;
- cpu_state.flags = 2;
- cpu_state.eflags = 0;
-
- in_smm = 1;
- mem_set_mem_state(smbase, 131072, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
- smi_latched = 1;
-
- mem_writel_phys(smram_state + 0xf8, smbase);
- mem_writel_phys(smram_state + 0x128, cr4);
- mem_writel_phys(smram_state + 0x130, cpu_state.seg_es.limit);
- mem_writel_phys(smram_state + 0x134, cpu_state.seg_es.base);
- mem_writel_phys(smram_state + 0x138, cpu_state.seg_es.access);
- mem_writel_phys(smram_state + 0x13c, cpu_state.seg_cs.limit);
- mem_writel_phys(smram_state + 0x140, cpu_state.seg_cs.base);
- mem_writel_phys(smram_state + 0x144, cpu_state.seg_cs.access);
- mem_writel_phys(smram_state + 0x148, cpu_state.seg_ss.limit);
- mem_writel_phys(smram_state + 0x14c, cpu_state.seg_ss.base);
- mem_writel_phys(smram_state + 0x150, cpu_state.seg_ss.access);
- mem_writel_phys(smram_state + 0x154, cpu_state.seg_ds.limit);
- mem_writel_phys(smram_state + 0x158, cpu_state.seg_ds.base);
- mem_writel_phys(smram_state + 0x15c, cpu_state.seg_ds.access);
- mem_writel_phys(smram_state + 0x160, cpu_state.seg_fs.limit);
- mem_writel_phys(smram_state + 0x164, cpu_state.seg_fs.base);
- mem_writel_phys(smram_state + 0x168, cpu_state.seg_fs.access);
- mem_writel_phys(smram_state + 0x16c, cpu_state.seg_gs.limit);
- mem_writel_phys(smram_state + 0x170, cpu_state.seg_gs.base);
- mem_writel_phys(smram_state + 0x174, cpu_state.seg_gs.access);
- mem_writel_phys(smram_state + 0x178, ldt.limit);
- mem_writel_phys(smram_state + 0x17c, ldt.base);
- mem_writel_phys(smram_state + 0x180, ldt.access);
- mem_writel_phys(smram_state + 0x184, gdt.limit);
- mem_writel_phys(smram_state + 0x188, gdt.base);
- mem_writel_phys(smram_state + 0x18c, gdt.access);
- mem_writel_phys(smram_state + 0x190, idt.limit);
- mem_writel_phys(smram_state + 0x194, idt.base);
- mem_writel_phys(smram_state + 0x198, idt.access);
- mem_writel_phys(smram_state + 0x19c, tr.limit);
- mem_writel_phys(smram_state + 0x1a0, tr.base);
- mem_writel_phys(smram_state + 0x1a4, tr.access);
-
- mem_writel_phys(smram_state + 0x1a8, cpu_state.seg_es.seg);
- mem_writel_phys(smram_state + 0x1ac, cpu_state.seg_cs.seg);
- mem_writel_phys(smram_state + 0x1b0, cpu_state.seg_ss.seg);
- mem_writel_phys(smram_state + 0x1b4, cpu_state.seg_ds.seg);
- mem_writel_phys(smram_state + 0x1b8, cpu_state.seg_fs.seg);
- mem_writel_phys(smram_state + 0x1bc, cpu_state.seg_gs.seg);
- mem_writel_phys(smram_state + 0x1c0, ldt.seg);
- mem_writel_phys(smram_state + 0x1c4, tr.seg);
-
- mem_writel_phys(smram_state + 0x1c8, dr[7]);
- mem_writel_phys(smram_state + 0x1cc, dr[6]);
- mem_writel_phys(smram_state + 0x1d0, EAX);
- mem_writel_phys(smram_state + 0x1d4, ECX);
- mem_writel_phys(smram_state + 0x1d8, EDX);
- mem_writel_phys(smram_state + 0x1dc, EBX);
- mem_writel_phys(smram_state + 0x1e0, ESP);
- mem_writel_phys(smram_state + 0x1e4, EBP);
- mem_writel_phys(smram_state + 0x1e8, ESI);
- mem_writel_phys(smram_state + 0x1ec, EDI);
- mem_writel_phys(smram_state + 0x1f0, cpu_state.pc);
- mem_writel_phys(smram_state + 0x1d0, old_flags);
- mem_writel_phys(smram_state + 0x1f8, cr3);
- mem_writel_phys(smram_state + 0x1fc, old_cr0);
-
- ds = es = fs_seg = gs = ss = 0;
-
- DS = ES = FS = GS = SS = 0;
-
- cpu_state.seg_ds.limit = cpu_state.seg_es.limit = cpu_state.seg_fs.limit = cpu_state.seg_gs.limit
- = cpu_state.seg_ss.limit = 0xffffffff;
-
- cpu_state.seg_ds.limit_high = cpu_state.seg_es.limit_high = cpu_state.seg_fs.limit_high
- = cpu_state.seg_gs.limit_high = cpu_state.seg_ss.limit_high = 0xffffffff;
-
- cpu_state.seg_ds.limit_low = cpu_state.seg_es.limit_low = cpu_state.seg_fs.limit_low
- = cpu_state.seg_gs.limit_low = cpu_state.seg_ss.limit_low = 0;
-
- cpu_state.seg_ds.access = cpu_state.seg_es.access = cpu_state.seg_fs.access
- = cpu_state.seg_gs.access = cpu_state.seg_ss.access = 0x93;
-
- cpu_state.seg_ds.checked = cpu_state.seg_es.checked = cpu_state.seg_fs.checked
- = cpu_state.seg_gs.checked = cpu_state.seg_ss.checked = 1;
-
- CS = 0x3000;
- cs = smbase;
- cpu_state.seg_cs.limit = cpu_state.seg_cs.limit_high = 0xffffffff;
- cpu_state.seg_cs.limit_low = 0;
- cpu_state.seg_cs.access = 0x93;
- cpu_state.seg_cs.checked = 1;
-
- cr4 = 0;
- dr[7] = 0x400;
- cpu_state.pc = 0x8000;
-
- nmi_mask = 0;
-}
-
-void leave_smm()
-{
- uint32_t smram_state = smbase + 0xfe00;
-
- smbase = mem_readl_phys(smram_state + 0xf8);
- cr4 = mem_readl_phys(smram_state + 0x128);
-
- cpu_state.seg_es.limit = cpu_state.seg_es.limit_high = mem_readl_phys(smram_state + 0x130);
- cpu_state.seg_es.base = mem_readl_phys(smram_state + 0x134);
- cpu_state.seg_es.limit_low = cpu_state.seg_es.base;
- cpu_state.seg_es.access = mem_readl_phys(smram_state + 0x138);
-
- cpu_state.seg_cs.limit = cpu_state.seg_cs.limit_high = mem_readl_phys(smram_state + 0x13c);
- cpu_state.seg_cs.base = mem_readl_phys(smram_state + 0x140);
- cpu_state.seg_cs.limit_low = cpu_state.seg_cs.base;
- cpu_state.seg_cs.access = mem_readl_phys(smram_state + 0x144);
-
- cpu_state.seg_ss.limit = cpu_state.seg_ss.limit_high = mem_readl_phys(smram_state + 0x148);
- cpu_state.seg_ss.base = mem_readl_phys(smram_state + 0x14c);
- cpu_state.seg_ss.limit_low = cpu_state.seg_ss.base;
- cpu_state.seg_ss.access = mem_readl_phys(smram_state + 0x150);
-
- cpu_state.seg_ds.limit = cpu_state.seg_ds.limit_high = mem_readl_phys(smram_state + 0x154);
- cpu_state.seg_ds.base = mem_readl_phys(smram_state + 0x158);
- cpu_state.seg_ds.limit_low = cpu_state.seg_ds.base;
- cpu_state.seg_ds.access = mem_readl_phys(smram_state + 0x15c);
-
- cpu_state.seg_fs.limit = cpu_state.seg_fs.limit_high = mem_readl_phys(smram_state + 0x160);
- cpu_state.seg_fs.base = mem_readl_phys(smram_state + 0x164);
- cpu_state.seg_fs.limit_low = cpu_state.seg_fs.base;
- cpu_state.seg_fs.access = mem_readl_phys(smram_state + 0x168);
-
- cpu_state.seg_gs.limit = cpu_state.seg_gs.limit_high = mem_readl_phys(smram_state + 0x16c);
- cpu_state.seg_gs.base = mem_readl_phys(smram_state + 0x170);
- cpu_state.seg_gs.limit_low = cpu_state.seg_gs.base;
- cpu_state.seg_gs.access = mem_readl_phys(smram_state + 0x174);
-
- ldt.limit = ldt.limit_high = mem_readl_phys(smram_state + 0x178);
- ldt.base = mem_readl_phys(smram_state + 0x17c);
- ldt.limit_low = ldt.base;
- ldt.access = mem_readl_phys(smram_state + 0x180);
-
- gdt.limit = gdt.limit_high = mem_readl_phys(smram_state + 0x184);
- gdt.base = mem_readl_phys(smram_state + 0x188);
- gdt.limit_low = gdt.base;
- gdt.access = mem_readl_phys(smram_state + 0x18c);
-
- idt.limit = idt.limit_high = mem_readl_phys(smram_state + 0x190);
- idt.base = mem_readl_phys(smram_state + 0x194);
- idt.limit_low = idt.base;
- idt.access = mem_readl_phys(smram_state + 0x198);
-
- tr.limit = tr.limit_high = mem_readl_phys(smram_state + 0x19c);
- tr.base = mem_readl_phys(smram_state + 0x1a0);
- tr.limit_low = tr.base;
- tr.access = mem_readl_phys(smram_state + 0x1a4);
-
- ES = mem_readl_phys(smram_state + 0x1a8);
- CS = mem_readl_phys(smram_state + 0x1ac);
- SS = mem_readl_phys(smram_state + 0x1b0);
- DS = mem_readl_phys(smram_state + 0x1b4);
- FS = mem_readl_phys(smram_state + 0x1b8);
- GS = mem_readl_phys(smram_state + 0x1bc);
- ldt.seg = mem_readl_phys(smram_state + 0x1c0);
- tr.seg = mem_readl_phys(smram_state + 0x1c4);
-
- dr[7] = mem_readl_phys(smram_state + 0x1c8);
- dr[6] = mem_readl_phys(smram_state + 0x1cc);
- EAX = mem_readl_phys(smram_state + 0x1d0);
- ECX = mem_readl_phys(smram_state + 0x1d4);
- EDX = mem_readl_phys(smram_state + 0x1d8);
- EBX = mem_readl_phys(smram_state + 0x1dc);
- ESP = mem_readl_phys(smram_state + 0x1e0);
- EBP = mem_readl_phys(smram_state + 0x1e4);
- ESI = mem_readl_phys(smram_state + 0x1e8);
- EDI = mem_readl_phys(smram_state + 0x1ec);
-
- cpu_state.pc = mem_readl_phys(smram_state + 0x1f0);
- uint32_t new_flags = mem_readl_phys(smram_state + 0x1f4);
- cpu_state.flags = new_flags & 0xffff;
- cpu_state.eflags = new_flags >> 16;
- cr3 = mem_readl_phys(smram_state + 0x1f8);
- cr0 = mem_readl_phys(smram_state + 0x1fc);
-
- cpu_state.seg_cs.access &= ~0x60;
- cpu_state.seg_cs.access |= cpu_state.seg_ss.access & 0x60; //cpl is dpl of ss
-
- if((cr0 & 1) && !(cpu_state.eflags&VM_FLAG))
- {
- cpu_state.seg_cs.checked = CS ? 1 : 0;
- cpu_state.seg_ds.checked = DS ? 1 : 0;
- cpu_state.seg_es.checked = ES ? 1 : 0;
- cpu_state.seg_fs.checked = FS ? 1 : 0;
- cpu_state.seg_gs.checked = GS ? 1 : 0;
- cpu_state.seg_ss.checked = SS ? 1 : 0;
- }
- else
- {
- cpu_state.seg_cs.checked = cpu_state.seg_ds.checked = cpu_state.seg_es.checked
- = cpu_state.seg_fs.checked = cpu_state.seg_gs.checked = cpu_state.seg_ss.checked = 1;
- }
-
- mem_restore_mem_state(smbase, 131072);
- in_smm = 0;
-
- nmi_mask = 1;
-}
-
-#define OP_TABLE(name) ops_ ## name
-#define CLOCK_CYCLES(c) cycles -= (c)
-#define CLOCK_CYCLES_ALWAYS(c) cycles -= (c)
-
-#include "386_ops.h"
-
-
-#define CACHE_ON() (!(cr0 & (1 << 30)) && !(cpu_state.flags & T_FLAG))
-
-#ifdef USE_DYNAREC
-static int cycles_main = 0;
-
-
-void exec386_dynarec(int cycs)
-{
- int vector;
- uint32_t addr;
- int tempi;
- int cycdiff;
- int oldcyc;
- uint32_t start_pc = 0;
-
- int cyc_period = cycs / 2000; /*5us*/
-
- cycles_main += cycs;
- while (cycles_main > 0)
- {
- int cycles_start;
-
- cycles += cyc_period;
- cycles_start = cycles;
-
- while (cycles>0)
- {
- oldcs = CS;
- cpu_state.oldpc = cpu_state.pc;
- oldcpl = CPL;
- cpu_state.op32 = use32;
-
- cycdiff=0;
- oldcyc=cycles;
- if (!CACHE_ON()) /*Interpret block*/
- {
- cpu_block_end = 0;
- x86_was_reset = 0;
- while (!cpu_block_end)
- {
- oldcs = CS;
- oldcpl = CPL;
- cpu_state.oldpc = cpu_state.pc;
- cpu_state.op32 = use32;
-
- cpu_state.ea_seg = &cpu_state.seg_ds;
- cpu_state.ssegs = 0;
-
- fetchdat = fastreadl(cs + cpu_state.pc);
-
- if (!cpu_state.abrt)
- {
- opcode = fetchdat & 0xFF;
- fetchdat >>= 8;
- trap = cpu_state.flags & T_FLAG;
-
- cpu_state.pc++;
- x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat);
- }
-
- if (!use32) cpu_state.pc &= 0xffff;
-
- if (((cs + cpu_state.pc) >> 12) != pccache)
- CPU_BLOCK_END();
-
- if (in_smm && smi_line && is_pentium)
- CPU_BLOCK_END();
-
- if (cpu_state.abrt)
- CPU_BLOCK_END();
- if (trap)
- CPU_BLOCK_END();
-
- if (nmi && nmi_enable && nmi_mask)
- CPU_BLOCK_END();
-
- ins++;
- }
- }
- else
- {
- uint32_t phys_addr = get_phys(cs+cpu_state.pc);
- int hash = HASH(phys_addr);
- codeblock_t *block = codeblock_hash[hash];
- int valid_block = 0;
- trap = 0;
-
- if (block && !cpu_state.abrt)
- {
- page_t *page = &pages[phys_addr >> 12];
-
- /*Block must match current CS, PC, code segment size,
- and physical address. The physical address check will
- also catch any page faults at this stage*/
- valid_block = (block->pc == cs + cpu_state.pc) && (block->_cs == cs) &&
- (block->phys == phys_addr) && !((block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) &&
- ((block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK));
- if (!valid_block)
- {
- uint64_t mask = (uint64_t)1 << ((phys_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK);
-
- if (page->code_present_mask[(phys_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] & mask)
- {
- /*Walk page tree to see if we find the correct block*/
- codeblock_t *new_block = codeblock_tree_find(phys_addr, cs);
- if (new_block)
- {
- valid_block = (new_block->pc == cs + cpu_state.pc) && (new_block->_cs == cs) &&
- (new_block->phys == phys_addr) && !((new_block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) &&
- ((new_block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK));
- if (valid_block)
- block = new_block;
- }
- }
- }
-
- if (valid_block && (block->page_mask & *block->dirty_mask))
- {
- codegen_check_flush(page, page->dirty_mask[(phys_addr >> 10) & 3], phys_addr);
- page->dirty_mask[(phys_addr >> 10) & 3] = 0;
- if (!block->valid)
- valid_block = 0;
- }
- if (valid_block && block->page_mask2)
- {
- /*We don't want the second page to cause a page
- fault at this stage - that would break any
- code crossing a page boundary where the first
- page is present but the second isn't. Instead
- allow the first page to be interpreted and for
- the page fault to occur when the page boundary
- is actually crossed.*/
- uint32_t phys_addr_2 = get_phys_noabrt(block->endpc);
- page_t *page_2 = &pages[phys_addr_2 >> 12];
-
- if ((block->phys_2 ^ phys_addr_2) & ~0xfff)
- valid_block = 0;
- else if (block->page_mask2 & *block->dirty_mask2)
- {
- codegen_check_flush(page_2, page_2->dirty_mask[(phys_addr_2 >> 10) & 3], phys_addr_2);
- page_2->dirty_mask[(phys_addr_2 >> 10) & 3] = 0;
- if (!block->valid)
- valid_block = 0;
- }
- }
- if (valid_block && block->was_recompiled && (block->flags & CODEBLOCK_STATIC_TOP) && block->TOP != cpu_state.TOP)
- {
- /*FPU top-of-stack does not match the value this block was compiled
- with, re-compile using dynamic top-of-stack*/
- block->flags &= ~CODEBLOCK_STATIC_TOP;
- block->was_recompiled = 0;
- }
- }
-
- if (valid_block && block->was_recompiled)
- {
- void (*code)() = (void *)&block->data[BLOCK_START];
-
- codeblock_hash[hash] = block;
-
- inrecomp=1;
- code();
- inrecomp=0;
- if (!use32) cpu_state.pc &= 0xffff;
- cpu_recomp_blocks++;
- }
- else if (valid_block && !cpu_state.abrt)
- {
- start_pc = cpu_state.pc;
-
- cpu_block_end = 0;
- x86_was_reset = 0;
-
- cpu_new_blocks++;
-
- codegen_block_start_recompile(block);
- codegen_in_recompile = 1;
-
- while (!cpu_block_end)
- {
- oldcs = CS;
- oldcpl = CPL;
- cpu_state.oldpc = cpu_state.pc;
- cpu_state.op32 = use32;
-
- cpu_state.ea_seg = &cpu_state.seg_ds;
- cpu_state.ssegs = 0;
-
- fetchdat = fastreadl(cs + cpu_state.pc);
-
- if (!cpu_state.abrt)
- {
- opcode = fetchdat & 0xFF;
- fetchdat >>= 8;
-
- trap = cpu_state.flags & T_FLAG;
-
- cpu_state.pc++;
-
- codegen_generate_call(opcode, x86_opcodes[(opcode | cpu_state.op32) & 0x3ff], fetchdat, cpu_state.pc, cpu_state.pc-1);
-
- x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat);
-
- if (x86_was_reset)
- break;
- }
-
- if (!use32) cpu_state.pc &= 0xffff;
-
- /*Cap source code at 4000 bytes per block; this
- will prevent any block from spanning more than
- 2 pages. In practice this limit will never be
- hit, as host block size is only 2kB*/
- if ((cpu_state.pc - start_pc) > 1000)
- CPU_BLOCK_END();
-
- if (in_smm && smi_line && is_pentium)
- CPU_BLOCK_END();
-
- if (trap)
- CPU_BLOCK_END();
-
- if (nmi && nmi_enable && nmi_mask)
- CPU_BLOCK_END();
-
- if (cpu_state.abrt)
- {
- codegen_block_remove();
- CPU_BLOCK_END();
- }
-
- ins++;
- }
-
- if (!cpu_state.abrt && !x86_was_reset)
- codegen_block_end_recompile(block);
-
- if (x86_was_reset)
- codegen_reset();
-
- codegen_in_recompile = 0;
- }
- else if (!cpu_state.abrt)
- {
- /*Mark block but do not recompile*/
- start_pc = cpu_state.pc;
-
- cpu_block_end = 0;
- x86_was_reset = 0;
-
- codegen_block_init(phys_addr);
-
- while (!cpu_block_end)
- {
- oldcs=CS;
- oldcpl = CPL;
- cpu_state.oldpc = cpu_state.pc;
- cpu_state.op32 = use32;
-
- cpu_state.ea_seg = &cpu_state.seg_ds;
- cpu_state.ssegs = 0;
-
- codegen_endpc = (cs + cpu_state.pc) + 8;
- fetchdat = fastreadl(cs + cpu_state.pc);
-
- if (!cpu_state.abrt)
- {
- opcode = fetchdat & 0xFF;
- fetchdat >>= 8;
-
- trap = cpu_state.flags & T_FLAG;
-
- cpu_state.pc++;
-
- x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat);
-
- if (x86_was_reset)
- break;
- }
-
- if (!use32) cpu_state.pc &= 0xffff;
-
- /*Cap source code at 4000 bytes per block; this
- will prevent any block from spanning more than
- 2 pages. In practice this limit will never be
- hit, as host block size is only 2kB*/
- if ((cpu_state.pc - start_pc) > 1000)
- CPU_BLOCK_END();
-
- if (in_smm && smi_line && is_pentium)
- CPU_BLOCK_END();
-
- if (trap)
- CPU_BLOCK_END();
-
- if (nmi && nmi_enable && nmi_mask)
- CPU_BLOCK_END();
-
- if (cpu_state.abrt)
- {
- codegen_block_remove();
- CPU_BLOCK_END();
- }
-
- ins++;
- }
-
- if (!cpu_state.abrt && !x86_was_reset)
- codegen_block_end();
-
- if (x86_was_reset)
- codegen_reset();
- }
- }
-
- cycdiff=oldcyc-cycles;
- tsc += cycdiff;
-
- if (cpu_state.abrt)
- {
- flags_rebuild();
- tempi = cpu_state.abrt;
- cpu_state.abrt = 0;
- x86_doabrt(tempi);
- if (cpu_state.abrt)
- {
- cpu_state.abrt = 0;
- cpu_state.pc = cpu_state.oldpc;
- CS = oldcs;
-#ifdef ENABLE_386_DYNAREC_LOG
- x386_dynarec_log("Double fault %i\n", ins);
-#endif
- pmodeint(8, 0);
- if (cpu_state.abrt)
- {
- cpu_state.abrt = 0;
- softresetx86();
- cpu_set_edx();
- #ifdef ENABLE_386_DYNAREC_LOG
- x386_dynarec_log("Triple fault - reset\n");
- #endif
- }
- }
- }
-
- if (in_smm && smi_line && is_pentium)
- {
- enter_smm();
- }
-
- else if (trap)
- {
- flags_rebuild();
- if (msw&1)
- {
- pmodeint(1,0);
- }
- else
- {
- writememw(ss,(SP-2)&0xFFFF,cpu_state.flags);
- writememw(ss,(SP-4)&0xFFFF,CS);
- writememw(ss,(SP-6)&0xFFFF,cpu_state.pc);
- SP-=6;
- addr = (1 << 2) + idt.base;
- cpu_state.flags &= ~I_FLAG;
- cpu_state.flags &= ~T_FLAG;
- cpu_state.pc=readmemw(0,addr);
- loadcs(readmemw(0,addr+2));
- }
- }
- else if (nmi && nmi_enable && nmi_mask)
- {
- cpu_state.oldpc = cpu_state.pc;
- oldcs = CS;
- x86_int(2);
- nmi_enable = 0;
- if (nmi_auto_clear)
- {
- nmi_auto_clear = 0;
- nmi = 0;
- }
- }
- else if ((cpu_state.flags&I_FLAG) && pic_intpending)
- {
- vector = picinterrupt();
- if (vector != -1)
- {
- CPU_BLOCK_END();
- flags_rebuild();
- if (msw&1)
- {
- pmodeint(vector,0);
- }
- else
- {
- writememw(ss,(SP-2)&0xFFFF,cpu_state.flags);
- writememw(ss,(SP-4)&0xFFFF,CS);
- writememw(ss,(SP-6)&0xFFFF,cpu_state.pc);
- SP-=6;
- addr=vector<<2;
- cpu_state.flags &= ~I_FLAG;
- cpu_state.flags &= ~T_FLAG;
- oxpc=cpu_state.pc;
- cpu_state.pc=readmemw(0,addr);
- loadcs(readmemw(0,addr+2));
- }
- }
- }
- }
-
- if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc))
- timer_process();
-
- cycles_main -= (cycles_start - cycles);
- }
-}
-#endif
diff --git a/src/cpu_common/386_dynarec_ops.c b/src/cpu_common/386_dynarec_ops.c
index 9965efdff..4fc9a13af 100644
--- a/src/cpu_common/386_dynarec_ops.c
+++ b/src/cpu_common/386_dynarec_ops.c
@@ -66,7 +66,7 @@ static __inline void fetch_ea_16_long(uint32_t rmdat)
#define OP_TABLE(name) dynarec_ops_ ## name
-#define CLOCK_CYCLES(c)
-#define CLOCK_CYCLES_ALWAYS(c) cycles -= (c)
+#define CLOCK_CYCLES(c) in_hlt = 0
+#define CLOCK_CYCLES_ALWAYS(c) do { cycles -= (c); in_hlt = 0; } while(0)
#include "386_ops.h"
diff --git a/src/cpu_common/808x.c b/src/cpu_common/808x.c
index 0c1bf21ab..ee805d30b 100644
--- a/src/cpu_common/808x.c
+++ b/src/cpu_common/808x.c
@@ -972,7 +972,10 @@ reset_common(int hard)
cpu_alu_op = 0;
in_smm = smi_latched = 0;
- smi_line = 0;
+ smi_line = in_hlt = 0;
+
+ if (hard)
+ smbase = 0x00030000;
}
diff --git a/src/cpu_common/cpu.c b/src/cpu_common/cpu.c
index fa8bd893a..4e770cc46 100644
--- a/src/cpu_common/cpu.c
+++ b/src/cpu_common/cpu.c
@@ -39,10 +39,13 @@
* USA.
*/
#include
+#include
#include
#include
#include
#include
+
+#define HAVE_STDARG_H
#include <86box/86box.h>
#include "cpu.h"
#include <86box/device.h>
@@ -132,7 +135,7 @@ const OpFn *x86_opcodes_REPE;
const OpFn *x86_opcodes_REPNE;
const OpFn *x86_opcodes_3DNOW;
-int in_smm = 0, smi_line = 0, smi_latched = 0;
+int in_smm = 0, smi_line = 0, smi_latched = 0, in_hlt = 0;
uint32_t smbase = 0x30000;
CPU *cpu_s;
@@ -163,7 +166,7 @@ int is286,
hascache,
isibm486,
israpidcad,
- is_pentium;
+ is_pentium, is_k5, is_k6, is_p6;
int hasfpu;
@@ -237,7 +240,29 @@ int timing_misaligned;
static uint8_t ccr0, ccr1, ccr2, ccr3, ccr4, ccr5, ccr6;
-int cpu_has_feature(int feature)
+
+#ifdef ENABLE_CPU_LOG
+int cpu_do_log = ENABLE_CPU_LOG;
+
+
+void
+cpu_log(const char *fmt, ...)
+{
+ va_list ap;
+
+ if (cpu_do_log) {
+ va_start(ap, fmt);
+ pclog_ex(fmt, ap);
+ va_end(ap);
+ }
+}
+#else
+#define cpu_log(fmt, ...)
+#endif
+
+
+int
+cpu_has_feature(int feature)
{
return cpu_features & feature;
}
@@ -291,7 +316,28 @@ cpu_set(void)
is486dx = (cpu_s->cpu_type >= CPU_i486DX) && (cpu_s->cpu_type < CPU_i486DX2);
is486dx2 = (cpu_s->cpu_type >= CPU_i486DX2) && (cpu_s->cpu_type < CPU_iDX4);
isdx4 = (cpu_s->cpu_type >= CPU_iDX4) && (cpu_s->cpu_type < CPU_WINCHIP);
- is_pentium = (cpu_s->cpu_type >= CPU_WINCHIP);
+ is_pentium = (cpu_s->cpu_type == CPU_PENTIUM) || (cpu_s->cpu_type == CPU_PENTIUMMMX);
+#if (defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_AMD_K)))
+ is_k5 = (cpu_s->cpu_type == CPU_K5) || (cpu_s->cpu_type == CPU_5K86);
+#else
+ is_k5 = 0;
+#endif
+#if (defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_AMD_K)))
+ is_k6 = (cpu_s->cpu_type == CPU_K6);
+#else
+ is_k6 = 0;
+#endif
+#ifdef USE_NEW_DYNAREC
+ is_k6 = is_k6 || (cpu_s->cpu_type == CPU_K6_2) || (cpu_s->cpu_type == CPU_K6_2C) ||
+ (cpu_s->cpu_type == CPU_K6_3) || (cpu_s->cpu_type == CPU_K6_2P) ||
+ (cpu_s->cpu_type == CPU_K6_3P);
+#endif
+#if defined(DEV_BRANCH) && defined(USE_I686)
+ is_p6 = (cpu_s->cpu_type == CPU_PENTIUMPRO) || (cpu_s->cpu_type == CPU_PENTIUM2) ||
+ (cpu_s->cpu_type == CPU_PENTIUM2D);
+#else
+ is_p6 = 0;
+#endif
hasfpu = (cpu_s->cpu_type >= CPU_i486DX) || (cpu_s->cpu_type == CPU_RAPIDCAD);
hascache = (cpu_s->cpu_type >= CPU_486SLC) || (cpu_s->cpu_type == CPU_IBM386SLC || cpu_s->cpu_type == CPU_IBM486SLC || cpu_s->cpu_type == CPU_IBM486BL);
#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86))
@@ -2362,6 +2408,7 @@ void cpu_ven_reset(void)
void cpu_RDMSR()
{
+ cpu_log("RDMSR %08X\n", ECX);
switch (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type)
{
case CPU_WINCHIP:
@@ -2833,7 +2880,7 @@ void cpu_RDMSR()
break;
default:
i686_invalid_rdmsr:
- // pclog("RDMSR: Invalid MSR: %08X\n", ECX);
+ cpu_log("RDMSR: Invalid MSR: %08X\n", ECX);
x86gpf(NULL, 0);
break;
}
@@ -2849,6 +2896,7 @@ void cpu_WRMSR()
uint64_t temp;
#endif
+ cpu_log("WRMSR %08X %08X%08X\n", ECX, EDX, EAX);
switch (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type)
{
case CPU_WINCHIP:
@@ -3249,7 +3297,7 @@ void cpu_WRMSR()
break;
default:
i686_invalid_wrmsr:
- // pclog("WRMSR: Invalid MSR: %08X\n", ECX);
+ cpu_log("WRMSR: Invalid MSR: %08X\n", ECX);
x86gpf(NULL, 0);
break;
}
diff --git a/src/cpu_common/cpu.h b/src/cpu_common/cpu.h
index 68c4f7937..5d60d7310 100644
--- a/src/cpu_common/cpu.h
+++ b/src/cpu_common/cpu.h
@@ -382,11 +382,12 @@ extern double cpu_dmulti;
extern int cpu_cyrix_alignment; /*Cyrix 5x86/6x86 only has data misalignment
penalties when crossing 8-byte boundaries*/
-extern int is8086, is286, is386, is486, is486sx, is486dx, is486sx2, is486dx2, isdx4;
+extern int is8086, is286, is386, is486, is486sx, is486dx, is486sx2, is486dx2, isdx4;
+extern int is_pentium, is_k5, is_k6, is_p6;
extern int hascache;
extern int isibm486;
-extern int is_rapidcad;
-extern int hasfpu;
+extern int is_rapidcad;
+extern int hasfpu;
#define CPU_FEATURE_RDTSC (1 << 0)
#define CPU_FEATURE_MSR (1 << 1)
#define CPU_FEATURE_MMX (1 << 2)
@@ -397,7 +398,7 @@ extern int hasfpu;
extern uint32_t cpu_features;
-extern int in_smm, smi_line, smi_latched;
+extern int in_smm, smi_line, smi_latched, in_hlt;
extern uint32_t smbase;
#ifdef USE_NEW_DYNAREC
diff --git a/src/cpu_common/cpu_table - Cópia.c b/src/cpu_common/cpu_table - Cópia.c
deleted file mode 100644
index e3f8f3f5c..000000000
--- a/src/cpu_common/cpu_table - Cópia.c
+++ /dev/null
@@ -1,695 +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.
- *
- * Define all known processor types.
- *
- * Available cpuspeeds:
- *
- * 0 = 16 MHz
- * 1 = 20 MHz
- * 2 = 25 MHz
- * 3 = 33 MHz
- * 4 = 40 MHz
- * 5 = 50 MHz
- * 6 = 66 MHz
- * 7 = 75 MHz
- * 8 = 80 MHz
- * 9 = 90 MHz
- * 10 = 100 MHz
- * 11 = 120 MHz
- * 12 = 133 MHz
- * 13 = 150 MHz
- * 14 = 160 MHz
- * 15 = 166 MHz
- * 16 = 180 MHz
- * 17 = 200 MHz
- *
- *
- *
- * Authors: Sarah Walker,
- * leilei,
- * Miran Grca,
- * Fred N. van Kempen,
- *
- * Copyright 2008-2019 Sarah Walker.
- * Copyright 2016-2019 leilei.
- * Copyright 2016-2019 Miran Grca.
- * Copyright 2017-2019 Fred N. van Kempen.
- */
-#include
-#include
-#include
-#include
-#include <86box/86box.h>
-#include "cpu.h"
-#include <86box/machine.h>
-
-
-CPU cpus_8088[] = {
- /*8088 standard*/
- {"8088/4.77", CPU_8088, 4772728, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
- {"8088/7.16", CPU_8088, 7159092, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
- {"8088/8", CPU_8088, 8000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
- {"8088/10", CPU_8088, 10000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
- {"8088/12", CPU_8088, 12000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
- {"8088/16", CPU_8088, 16000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
- {"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
-};
-
-CPU cpus_pcjr[] = {
- /*8088 PCjr*/
- {"8088/4.77", CPU_8088, 4772728, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
- {"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
-};
-
-CPU cpus_europc[] = {
- /*8088 EuroPC*/
- {"8088/4.77", CPU_8088, 4772728, 1, 0, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1},
- {"8088/7.16", CPU_8088, 7159092, 1, 0, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1},
- {"8088/9.54", CPU_8088, 9545456, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
- {"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
-};
-
-CPU cpus_8086[] = {
- /*8086 standard*/
- {"8086/7.16", CPU_8086, 7159092, 1, 0, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1},
- {"8086/8", CPU_8086, 8000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
- {"8086/9.54", CPU_8086, 9545456, 1, 0, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1},
- {"8086/10", CPU_8086, 10000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
- {"8086/12", CPU_8086, 12000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
- {"8086/16", CPU_8086, 16000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 2},
- {"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
-};
-
-CPU cpus_pc1512[] = {
- /*8086 Amstrad*/
- {"8086/8", CPU_8086, 8000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
- {"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
-};
-
-CPU cpus_286[] = {
- /*286*/
- {"286/6", CPU_286, 6000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1},
- {"286/8", CPU_286, 8000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1},
- {"286/10", CPU_286, 10000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1},
- {"286/12", CPU_286, 12500000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 2},
- {"286/16", CPU_286, 16000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 2},
- {"286/20", CPU_286, 20000000, 1, 0, 0, 0, 0, 0, 4,4,4,4, 3},
- {"286/25", CPU_286, 25000000, 1, 0, 0, 0, 0, 0, 4,4,4,4, 3},
- {"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
-};
-
-CPU cpus_ibmat[] = {
- /*286*/
- {"286/6", CPU_286, 6000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 1},
- {"286/8", CPU_286, 8000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 1},
- {"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
-};
-
-CPU cpus_ibmxt286[] = {
- /*286*/
- {"286/6", CPU_286, 6000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1},
- {"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
-};
-
-CPU cpus_ps1_m2011[] = {
- /*286*/
- {"286/10", CPU_286, 10000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1},
- {"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 9}
-};
-
-CPU cpus_ps2_m30_286[] = {
- /*286*/
- {"286/10", CPU_286, 10000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1},
- {"286/12", CPU_286, 12500000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 2},
- {"286/16", CPU_286, 16000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 2},
- {"286/20", CPU_286, 20000000, 1, 0, 0, 0, 0, 0, 4,4,4,4, 3},
- {"286/25", CPU_286, 25000000, 1, 0, 0, 0, 0, 0, 4,4,4,4, 3},
- {"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
-};
-
-CPU cpus_i386SX[] = {
- /*i386SX*/
- {"i386SX/16", CPU_386SX, 16000000, 1, 0, 0x2308, 0, 0, 0, 3,3,3,3, 2},
- {"i386SX/20", CPU_386SX, 20000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3, 3},
- {"i386SX/25", CPU_386SX, 25000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3, 3},
- {"i386SX/33", CPU_386SX, 33333333, 1, 0, 0x2308, 0, 0, 0, 6,6,3,3, 4},
- {"i386SX/40", CPU_386SX, 40000000, 1, 0, 0x2308, 0, 0, 0, 7,7,3,3, 5},
- {"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
-};
-
-CPU cpus_i386DX[] = {
- /*i386DX/RapidCAD*/
- {"i386DX/16", CPU_386DX, 16000000, 1, 0, 0x0308, 0, 0, 0, 3,3,3,3, 2},
- {"i386DX/20", CPU_386DX, 20000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3, 3},
- {"i386DX/25", CPU_386DX, 25000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3, 3},
- {"i386DX/33", CPU_386DX, 33333333, 1, 0, 0x0308, 0, 0, 0, 6,6,3,3, 4},
- {"i386DX/40", CPU_386DX, 40000000, 1, 0, 0x0308, 0, 0, 0, 7,7,3,3, 5},
- {"RapidCAD/25", CPU_RAPIDCAD, 25000000, 1, 0, 0x0430, 0, 0, CPU_SUPPORTS_DYNAREC, 4,4,3,3, 3},
- {"RapidCAD/33", CPU_RAPIDCAD, 33333333, 1, 0, 0x0430, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4},
- {"RapidCAD/40", CPU_RAPIDCAD, 40000000, 1, 0, 0x0430, 0, 0, CPU_SUPPORTS_DYNAREC, 7,7,3,3, 5},
- {"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
-};
-
-CPU cpus_Am386SX[] = {
- /*Am386SX*/
- {"Am386SX/16", CPU_386SX, 16000000, 1, 0, 0x2308, 0, 0, 0, 3,3,3,3, 2},
- {"Am386SX/20", CPU_386SX, 20000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3, 3},
- {"Am386SX/25", CPU_386SX, 25000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3, 3},
- {"Am386SX/33", CPU_386SX, 33333333, 1, 0, 0x2308, 0, 0, 0, 6,6,3,3, 4},
- {"Am386SX/40", CPU_386SX, 40000000, 1, 0, 0x2308, 0, 0, 0, 7,7,3,3, 5},
- {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
-};
-
-CPU cpus_Am386DX[] = {
- /*Am386DX*/
- {"Am386DX/25", CPU_386DX, 25000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3, 3},
- {"Am386DX/33", CPU_386DX, 33333333, 1, 0, 0x0308, 0, 0, 0, 6,6,3,3, 4},
- {"Am386DX/40", CPU_386DX, 40000000, 1, 0, 0x0308, 0, 0, 0, 7,7,3,3, 5},
- {"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
-};
-
-CPU cpus_486SLC[] = {
- /*Cx486SLC*/
- {"Cx486SLC/20", CPU_486SLC, 20000000, 1, 0, 0x400, 0, 0x0000, 0, 4,4,3,3, 3},
- {"Cx486SLC/25", CPU_486SLC, 25000000, 1, 0, 0x400, 0, 0x0000, 0, 4,4,3,3, 3},
- {"Cx486SLC/33", CPU_486SLC, 33333333, 1, 0, 0x400, 0, 0x0000, 0, 6,6,3,3, 4},
- {"Cx486SRx2/32", CPU_486SLC, 32000000, 2, 0, 0x406, 0, 0x0006, 0, 6,6,6,6, 4},
- {"Cx486SRx2/40", CPU_486SLC, 40000000, 2, 0, 0x406, 0, 0x0006, 0, 8,8,6,6, 6},
- {"Cx486SRx2/50", CPU_486SLC, 50000000, 2, 0, 0x406, 0, 0x0006, 0, 8,8,6,6, 6},
- {"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
-};
-
-CPU cpus_IBM386SLC[] = {
- /*IBM 386SLC*/
- {"386SLC/16", CPU_IBM386SLC, 16000000, 1, 0, 0x300, 0, 0, 0, 3,3,3,3, 2},
- {"386SLC/20", CPU_IBM386SLC, 20000000, 1, 0, 0x300, 0, 0, 0, 4,4,3,3, 3},
- {"386SLC/25", CPU_IBM386SLC, 25000000, 1, 0, 0x300, 0, 0, 0, 4,4,3,3, 3},
- {"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
-};
-
-CPU cpus_IBM486SLC[] = {
- /*IBM 486SLC*/
- {"486SLC/33", CPU_IBM486SLC, 33333333, 1, 0, 0x400, 0, 0, 0, 6,6,3,3, 4},
- {"486SLC2/40", CPU_IBM486SLC, 40000000, 2, 0, 0x400, 0, 0, 0, 7,7,6,6, 5},
- {"486SLC2/50", CPU_IBM486SLC, 50000000, 2, 0, 0x400, 0, 0, 0, 8,8,6,6, 6},
- {"486SLC2/66", CPU_IBM486SLC, 66666666, 2, 0, 0x400, 0, 0, 0, 12,12,6,6, 8},
- {"486SLC3/60", CPU_IBM486SLC, 60000000, 3, 0, 0x400, 0, 0, 0, 12,12,9,9, 7},
- {"486SLC3/75", CPU_IBM486SLC, 75000000, 3, 0, 0x400, 0, 0, 0, 12,12,9,9, 9},
- {"486SLC3/100", CPU_IBM486SLC, 100000000, 3, 0, 0x400, 0, 0, 0, 18,18,9,9, 12},
- {"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
-};
-
-CPU cpus_IBM486BL[] = {
- /*IBM Blue Lightning*/
- {"486BL2/50", CPU_IBM486BL, 50000000, 2, 0, 0x400, 0, 0, 0, 8,8,6,6, 6},
- {"486BL2/66", CPU_IBM486BL, 66666666, 2, 0, 0x400, 0, 0, 0, 12,12,6,6, 8},
- {"486BL3/75", CPU_IBM486BL, 75000000, 3, 0, 0x400, 0, 0, 0, 12,12,9,9, 9},
- {"486BL3/100", CPU_IBM486BL, 100000000, 3, 0, 0x400, 0, 0, 0, 18,18,9,9, 12},
- {"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
-};
-
-CPU cpus_486DLC[] = {
- /*Cx486DLC*/
- {"Cx486DLC/25", CPU_486DLC, 25000000, 1, 0, 0x401, 0, 0x0001, 0, 4, 4,3,3, 3},
- {"Cx486DLC/33", CPU_486DLC, 33333333, 1, 0, 0x401, 0, 0x0001, 0, 6, 6,3,3, 4},
- {"Cx486DLC/40", CPU_486DLC, 40000000, 1, 0, 0x401, 0, 0x0001, 0, 7, 7,3,3, 5},
- {"Cx486DRx2/32", CPU_486DLC, 32000000, 2, 0, 0x407, 0, 0x0007, 0, 6, 6,6,6, 4},
- {"Cx486DRx2/40", CPU_486DLC, 40000000, 2, 0, 0x407, 0, 0x0007, 0, 8, 8,6,6, 6},
- {"Cx486DRx2/50", CPU_486DLC, 50000000, 2, 0, 0x407, 0, 0x0007, 0, 8, 8,6,6, 6},
- {"Cx486DRx2/66", CPU_486DLC, 66666666, 2, 0, 0x407, 0, 0x0007, 0, 12,12,6,6, 8},
- {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0, 0}
-};
-
-CPU cpus_i486S1[] = {
- /*i486*/
- {"i486SX/16", CPU_i486SX, 16000000, 1, 16000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 3, 3,3,3, 2},
- {"i486SX/20", CPU_i486SX, 20000000, 1, 20000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3},
- {"i486SX/25", CPU_i486SX, 25000000, 1, 25000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3},
- {"i486SX/33", CPU_i486SX, 33333333, 1, 33333333, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6,3,3, 4},
- {"i486SX2/50", CPU_i486SX, 50000000, 2, 25000000, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 6},
- {"i486SX2/66 (Q0569)", CPU_i486SX, 66666666, 2, 33333333, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 8},
- {"i486DX/25", CPU_i486DX, 25000000, 1, 25000000, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3},
- {"i486DX/33", CPU_i486DX, 33333333, 1, 33333333, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6,3,3, 4},
- {"i486DX/50", CPU_i486DX, 50000000, 1, 25000000, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8,4,4, 6},
- {"i486DX2/40", CPU_i486DX, 40000000, 2, 20000000, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 7, 7,6,6, 5},
- {"i486DX2/50", CPU_i486DX, 50000000, 2, 25000000, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 6},
- {"i486DX2/66", CPU_i486DX, 66666666, 2, 33333333, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 8},
- {"iDX4 OverDrive 75", CPU_iDX4, 75000000, 3, 25000000, 0x1480, 0x1480, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 9}, /*Only added the DX4 OverDrive as the others would be redundant*/
- {"iDX4 OverDrive 100", CPU_iDX4, 100000000, 3, 33333333, 0x1480, 0x1480, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 12},
- {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0, 0}
-};
-CPU cpus_Am486S1[] = {
- /*Am486*/
- {"Am486SX/33", CPU_Am486SX, 33333333, 1, 33333333, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4},
- {"Am486SX/40", CPU_Am486SX, 40000000, 1, 40000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5},
- {"Am486SX2/50", CPU_Am486SX, 50000000, 2, 25000000, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6}, /*CPUID available on SX2, DX2, DX4, 5x86, >= 50 MHz*/
- {"Am486SX2/66", CPU_Am486SX, 66666666, 2, 33333333, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8}, /*Isn't on all real AMD SX2s and DX2s, availability here is pretty arbitary (and distinguishes them from the Intel chips)*/
- {"Am486DX/33", CPU_Am486DX, 33333333, 1, 33333333, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4},
- {"Am486DX/40", CPU_Am486DX, 40000000, 1, 40000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5},
- {"Am486DX2/50", CPU_Am486DX, 50000000, 2, 25000000, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6},
- {"Am486DX2/66", CPU_Am486DX, 66666666, 2, 33333333, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8},
- {"Am486DX2/80", CPU_Am486DX, 80000000, 2, 40000000, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 14,14, 6, 6, 10},
- {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
-};
-CPU cpus_Cx486S1[] = {
- /*Cyrix 486*/
- {"Cx486S/25", CPU_Cx486S, 25000000, 1, 25000000, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 4, 4, 3, 3, 3},
- {"Cx486S/33", CPU_Cx486S, 33333333, 1, 33333333, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4},
- {"Cx486S/40", CPU_Cx486S, 40000000, 1, 40000000, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5},
- {"Cx486DX/33", CPU_Cx486DX, 33333333, 1, 33333333, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4},
- {"Cx486DX/40", CPU_Cx486DX, 40000000, 1, 40000000, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5},
- {"Cx486DX2/50", CPU_Cx486DX, 50000000, 2, 25000000, 0x430, 0, 0x081b, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6},
- {"Cx486DX2/66", CPU_Cx486DX, 66666666, 2, 33333333, 0x430, 0, 0x0b1b, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8},
- {"Cx486DX2/80", CPU_Cx486DX, 80000000, 2, 40000000, 0x430, 0, 0x311b, CPU_SUPPORTS_DYNAREC, 14,14, 6, 6, 10},
- {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
-};
-
-CPU cpus_i486[] = {
- /*i486/P24T*/
- {"i486SX/16", CPU_i486SX, 16000000, 1, 16000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 3, 3,3,3, 2},
- {"i486SX/20", CPU_i486SX, 20000000, 1, 20000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3},
- {"i486SX/25", CPU_i486SX, 25000000, 1, 25000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3},
- {"i486SX/33", CPU_i486SX, 33333333, 1, 33333333, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6,3,3, 4},
- {"i486SX2/50", CPU_i486SX, 50000000, 2, 25000000, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 6},
- {"i486SX2/66 (Q0569)", CPU_i486SX, 66666666, 2, 33333333, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 8},
- {"i486DX/25", CPU_i486DX, 25000000, 1, 25000000, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3},
- {"i486DX/33", CPU_i486DX, 33333333, 1, 33333333, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6,3,3, 4},
- {"i486DX/50", CPU_i486DX, 50000000, 1, 25000000, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8,4,4, 6},
- {"i486DX2/40", CPU_i486DX, 40000000, 2, 20000000, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 7, 7,6,6, 5}, /*CPUID available on DX2, DX4, P24T, >= 40 MHz*/
- {"i486DX2/50", CPU_i486DX, 50000000, 2, 25000000, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 6},
- {"i486DX2/66", CPU_i486DX, 66666666, 2, 33333333, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 8},
- {"iDX4/75", CPU_iDX4, 75000000, 3, 25000000, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 9}, /*CPUID available on DX4, >= 75 MHz*/
- {"iDX4/100", CPU_iDX4, 100000000, 3, 33333333, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 12}, /*Is on some real Intel DX2s, limit here is pretty arbitary*/
- {"iDX4 OverDrive 75", CPU_iDX4, 75000000, 3, 25000000, 0x1480, 0x1480, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 9},
- {"iDX4 OverDrive 100", CPU_iDX4, 100000000, 3, 33333333, 0x1480, 0x1480, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 12},
- {"Pentium OverDrive 63", CPU_PENTIUM, 62500000, 5/2, 25000000, 0x1531, 0x1531, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,7,7, 15/2},
- {"Pentium OverDrive 83", CPU_PENTIUM, 83333333, 5/2, 33333333, 0x1532, 0x1532, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,8,8, 10},
- {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0, 0}
-};
-
-CPU cpus_Am486[] = {
- /*Am486/5x86*/
- {"Am486SX/33", CPU_Am486SX, 33333333, 1, 33333333, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4},
- {"Am486SX/40", CPU_Am486SX, 40000000, 1, 40000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5},
- {"Am486SX2/50", CPU_Am486SX, 50000000, 2, 25000000, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6}, /*CPUID available on SX2, DX2, DX4, 5x86, >= 50 MHz*/
- {"Am486SX2/66", CPU_Am486SX, 66666666, 2, 33333333, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8},
- {"Am486DX/33", CPU_Am486DX, 33333333, 1, 33333333, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4},
- {"Am486DX/40", CPU_Am486DX, 40000000, 1, 40000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5},
- {"Am486DX2/50", CPU_Am486DX, 50000000, 2, 25000000, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6},
- {"Am486DX2/66", CPU_Am486DX, 66666666, 2, 33333333, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8},
- {"Am486DX2/80", CPU_Am486DX, 80000000, 2, 40000000, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 14,14, 6, 6, 10},
- {"Am486DX4/75", CPU_Am486DX, 75000000, 3, 25000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 12,12, 9, 9, 9},
- {"Am486DX4/90", CPU_Am486DX, 90000000, 3, 30000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 15,15, 9, 9, 12},
- {"Am486DX4/100", CPU_Am486DX, 100000000, 3, 33333333, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 15,15, 9, 9, 12},
- {"Am486DX4/120", CPU_Am486DX, 120000000, 3, 40000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 21,21, 9, 9, 15},
- {"Am5x86/P75", CPU_Am486DX, 133333333, 4, 33333333, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 16},
- {"Am5x86/P75+", CPU_Am486DX, 150000000, 3, 25000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 28,28,12,12, 20},/*The rare P75+ was indeed a triple-clocked 150 MHz according to research*/
- {"Am5x86/P90", CPU_Am486DX, 160000000, 4, 40000000, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC, 28,28,12,12, 20},/*160 MHz on a 40 MHz bus was a common overclock and "5x86/P90" was used by a number of BIOSes to refer to that configuration*/
- {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
-};
-
-CPU cpus_Cx486[] = {
- /*Cyrix 486*/
- {"Cx486S/25", CPU_Cx486S, 25000000, 1, 25000000, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 4, 4, 3, 3, 3},
- {"Cx486S/33", CPU_Cx486S, 33333333, 1, 33333333, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4},
- {"Cx486S/40", CPU_Cx486S, 40000000, 1, 40000000, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5},
- {"Cx486DX/33", CPU_Cx486DX, 33333333, 1, 33333333, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4},
- {"Cx486DX/40", CPU_Cx486DX, 40000000, 1, 40000000, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5},
- {"Cx486DX2/50", CPU_Cx486DX, 50000000, 2, 25000000, 0x430, 0, 0x081b, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6},
- {"Cx486DX2/66", CPU_Cx486DX, 66666666, 2, 33333333, 0x430, 0, 0x0b1b, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8},
- {"Cx486DX2/80", CPU_Cx486DX, 80000000, 2, 40000000, 0x430, 0, 0x311b, CPU_SUPPORTS_DYNAREC, 14,14, 6, 6, 10},
- {"Cx486DX4/75", CPU_Cx486DX, 75000000, 3, 25000000, 0x480, 0, 0x361f, CPU_SUPPORTS_DYNAREC, 12,12, 9, 9, 9},
- {"Cx486DX4/100", CPU_Cx486DX, 100000000, 3, 33333333, 0x480, 0, 0x361f, CPU_SUPPORTS_DYNAREC, 15,15, 9, 9, 12},
-
- /*Cyrix 5x86*/
- {"Cx5x86/80", CPU_Cx5x86, 80000000, 2, 40000000, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 14,14, 6, 6, 10}, /*If we're including the Pentium 50, might as well include this*/
- {"Cx5x86/100", CPU_Cx5x86, 100000000, 3, 33333333, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 15,15, 9, 9, 12},
- {"Cx5x86/120", CPU_Cx5x86, 120000000, 3, 40000000, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 21,21, 9, 9, 15},
- {"Cx5x86/133", CPU_Cx5x86, 133333333, 4, 33333333, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 16},
- {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
-};
-
-#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86))
-CPU cpus_6x863V[] = {
- /*Cyrix 6x86*/
- {"Cx6x86/P90", CPU_Cx6x86, 80000000, 2, 40000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8, 8, 6, 6, 10},
- {"Cx6x86/PR120+", CPU_Cx6x86, 100000000, 2, 25000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 12},
- {"Cx6x86/PR133+", CPU_Cx6x86, 110000000, 2, 27500000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 14},
- {"Cx6x86/PR150+", CPU_Cx6x86, 120000000, 2, 30000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14},
- {"Cx6x86/PR166+", CPU_Cx6x86, 133333333, 2, 33333333, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16},
- {"Cx6x86/PR200+", CPU_Cx6x86, 150000000, 2, 37500000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 18},
- {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- };
-
-CPU cpus_6x86[] = {
- /*Cyrix 6x86*/
- {"Cx6x86/P90", CPU_Cx6x86, 80000000, 2, 40000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8, 8, 6, 6, 10},
- {"Cx6x86/PR120+", CPU_Cx6x86, 100000000, 2, 25000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 12},
- {"Cx6x86/PR133+", CPU_Cx6x86, 110000000, 2, 27500000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 14},
- {"Cx6x86/PR150+", CPU_Cx6x86, 120000000, 2, 30000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14},
- {"Cx6x86/PR166+", CPU_Cx6x86, 133333333, 2, 33333333, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16},
- {"Cx6x86/PR200+", CPU_Cx6x86, 150000000, 2, 37500000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 18},
-
- /*Cyrix 6x86L*/
- {"Cx6x86L/PR133+", CPU_Cx6x86L, 110000000, 2, 27500000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 14},
- {"Cx6x86L/PR150+", CPU_Cx6x86L, 120000000, 2, 30000000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14},
- {"Cx6x86L/PR166+", CPU_Cx6x86L, 133333333, 2, 33333333, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16},
- {"Cx6x86L/PR200+", CPU_Cx6x86L, 150000000, 2, 37500000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 18},
-
- /*Cyrix 6x86MX/MII*/
- {"Cx6x86MX/PR166", CPU_Cx6x86MX, 133333333, 2, 33333333, 0x600, 0x600, 0x0451, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16},
- {"Cx6x86MX/PR200", CPU_Cx6x86MX, 166666666, 5/2, 33333333, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20},
- {"Cx6x86MX/PR233", CPU_Cx6x86MX, 187500000, 5/2, 37500000, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 45/2},
- {"Cx6x86MX/PR266", CPU_Cx6x86MX, 208333333, 5/2, 41666666, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17,17, 7, 7, 25},
- {"MII/PR300", CPU_Cx6x86MX, 233333333, 7/2, 33333333, 0x601, 0x601, 0x0852, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,11,11, 28},
- {"MII/PR333", CPU_Cx6x86MX, 250000000, 3, 41666666, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 23,23, 9, 9, 30},
- {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- };
-#endif
-
-#ifdef USE_NEW_DYNAREC
- CPU cpus_6x86SS7[] = {
- /*Cyrix 6x86*/
- {"Cx6x86/P90", CPU_Cx6x86, 80000000, 2, 40000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8, 8, 6, 6, 10},
- {"Cx6x86/PR120+", CPU_Cx6x86, 100000000, 2, 25000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 12},
- {"Cx6x86/PR133+", CPU_Cx6x86, 110000000, 2, 27500000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 14},
- {"Cx6x86/PR150+", CPU_Cx6x86, 120000000, 2, 30000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14},
- {"Cx6x86/PR166+", CPU_Cx6x86, 133333333, 2, 33333333, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16},
- {"Cx6x86/PR200+", CPU_Cx6x86, 150000000, 2, 37500000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 18},
-
- /*Cyrix 6x86L*/
- {"Cx6x86L/PR133+", CPU_Cx6x86L, 110000000, 2, 27500000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 14},
- {"Cx6x86L/PR150+", CPU_Cx6x86L, 120000000, 2, 30000000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14},
- {"Cx6x86L/PR166+", CPU_Cx6x86L, 133333333, 2, 33333333, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16},
- {"Cx6x86L/PR200+", CPU_Cx6x86L, 150000000, 2, 37500000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 18},
-
- /*Cyrix 6x86MX/MII*/
- {"Cx6x86MX/PR166", CPU_Cx6x86MX, 133333333, 2, 33333333, 0x600, 0x600, 0x0451, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16},
- {"Cx6x86MX/PR200", CPU_Cx6x86MX, 166666666, 5/2, 33333333, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20},
- {"Cx6x86MX/PR233", CPU_Cx6x86MX, 187500000, 5/2, 37500000, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 45/2},
- {"Cx6x86MX/PR266", CPU_Cx6x86MX, 208333333, 5/2, 41666666, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17,17, 7, 7, 25},
- {"MII/PR300", CPU_Cx6x86MX, 233333333, 7/2, 33333333, 0x601, 0x601, 0x0852, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,11,11, 28},
- {"MII/PR333", CPU_Cx6x86MX, 250000000, 3, 41666666, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 23,23, 9, 9, 30},
- {"MII/PR366", CPU_Cx6x86MX, 250000000, 5/2, 33333333, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 23,23, 7, 7, 30},
- {"MII/PR400", CPU_Cx6x86MX, 285000000, 3, 31666666, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27, 9, 9, 34},
- {"MII/PR433", CPU_Cx6x86MX, 300000000, 3, 33333333, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27, 9, 9, 36},
- {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- };
-#endif
-
-CPU cpus_WinChip[] = {
- /*IDT WinChip*/
- {"WinChip 75", CPU_WINCHIP, 75000000, 3/2, 25000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 4, 4, 9},
- {"WinChip 90", CPU_WINCHIP, 90000000, 3/2, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9, 9, 4, 4, 21/2},
- {"WinChip 100", CPU_WINCHIP, 100000000, 3/2, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9, 9, 4, 4, 12},
- {"WinChip 120", CPU_WINCHIP, 120000000, 2, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12, 12, 6, 6, 14},
- {"WinChip 133", CPU_WINCHIP, 133333333, 2, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12, 12, 6, 6, 16},
- {"WinChip 150", CPU_WINCHIP, 150000000, 5/2, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15, 15, 7, 7, 35/2},
- {"WinChip 166", CPU_WINCHIP, 166666666, 5/2, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15, 15, 7, 7, 40},
- {"WinChip 180", CPU_WINCHIP, 180000000, 3, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 21},
- {"WinChip 200", CPU_WINCHIP, 200000000, 3, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 24},
- {"WinChip 225", CPU_WINCHIP, 225000000, 3, 37500000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 27},
- {"WinChip 240", CPU_WINCHIP, 240000000, 4, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 28},
-#ifdef USE_NEW_DYNAREC
- {"WinChip 2/200", CPU_WINCHIP2, 200000000, 3, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 24},
- {"WinChip 2/225", CPU_WINCHIP2, 225000000, 3, 37500000, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 27},
- {"WinChip 2/240", CPU_WINCHIP2, 240000000, 4, 30000000, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 30},
- {"WinChip 2/250", CPU_WINCHIP2, 250000000, 3, 41666667, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 30},
- {"WinChip 2A/200", CPU_WINCHIP2, 200000000, 3, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 24},
- {"WinChip 2A/233", CPU_WINCHIP2, 233333333, 7/2, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, (7*8)/2},
-#endif
- {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
-};
-
-#ifdef USE_NEW_DYNAREC
-CPU cpus_WinChip_SS7[] = {
- /*IDT WinChip*/
- {"WinChip 75", CPU_WINCHIP, 75000000, 3/2, 25000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 4, 4, 9},
- {"WinChip 90", CPU_WINCHIP, 90000000, 3/2, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9, 9, 4, 4, 21/2},
- {"WinChip 100", CPU_WINCHIP, 100000000, 3/2, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9, 9, 4, 4, 12},
- {"WinChip 120", CPU_WINCHIP, 120000000, 2, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12, 12, 6, 6, 14},
- {"WinChip 133", CPU_WINCHIP, 133333333, 2, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12, 12, 6, 6, 16},
- {"WinChip 150", CPU_WINCHIP, 150000000, 5/2, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15, 15, 7, 7, 35/2},
- {"WinChip 166", CPU_WINCHIP, 166666666, 5/2, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15, 15, 7, 7, 40},
- {"WinChip 180", CPU_WINCHIP, 180000000, 3, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 21},
- {"WinChip 200", CPU_WINCHIP, 200000000, 3, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 24},
- {"WinChip 225", CPU_WINCHIP, 225000000, 3, 37500000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 27},
- {"WinChip 240", CPU_WINCHIP, 240000000, 4, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 28},
- {"WinChip 2/200", CPU_WINCHIP2, 200000000, 3, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 3*8},
- {"WinChip 2/225", CPU_WINCHIP2, 225000000, 3, 37500000, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 3*9},
- {"WinChip 2/240", CPU_WINCHIP2, 240000000, 4, 30000000, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 30},
- {"WinChip 2/250", CPU_WINCHIP2, 250000000, 3, 41666667, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 30},
- {"WinChip 2A/200", CPU_WINCHIP2, 200000000, 3, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 3*8},
- {"WinChip 2A/233", CPU_WINCHIP2, 233333333, 7/2, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 21, 21, 9, 9, (7*8)/2},
- {"WinChip 2A/266", CPU_WINCHIP2, 233333333, 7/3, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 21, 21, 7, 7, 28},
- {"WinChip 2A/300", CPU_WINCHIP2, 250000000, 5/2, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 8, 8, 30},
- {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
-};
-#endif
-
-CPU cpus_Pentium5V[] = {
- /*Intel Pentium (5V, socket 4)*/
- {"Pentium 60", CPU_PENTIUM, 60000000, 1, 30000000, 0x517, 0x517, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6,3,3, 7},
- {"Pentium 66", CPU_PENTIUM, 66666666, 1, 33333333, 0x517, 0x517, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6,3,3, 8},
- {"Pentium OverDrive 120", CPU_PENTIUM, 120000000, 2, 30000000, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14},
- {"Pentium OverDrive 133", CPU_PENTIUM, 133333333, 2, 33333333, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16},
- {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0, 0}
-};
-
-CPU cpus_Pentium5V50[] = {
- /*Intel Pentium (5V, socket 4, including 50 MHz FSB)*/
- {"Pentium 50 (Q0399)", CPU_PENTIUM, 50000000, 1, 25000000, 0x513, 0x513, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 4, 4,3,3, 6},
- {"Pentium 60", CPU_PENTIUM, 60000000, 1, 30000000, 0x517, 0x517, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6,3,3, 7},
- {"Pentium 66", CPU_PENTIUM, 66666666, 1, 33333333, 0x517, 0x517, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6,3,3, 8},
- {"Pentium OverDrive 100", CPU_PENTIUM, 100000000, 2, 25000000, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8, 8,6,6, 12},
- {"Pentium OverDrive 120", CPU_PENTIUM, 120000000, 2, 30000000, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14},
- {"Pentium OverDrive 133", CPU_PENTIUM, 133333333, 2, 33333333, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16},
- {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0, 0}
-};
-
-CPU cpus_PentiumS5[] = {
- /*Intel Pentium (Socket 5)*/
- {"Pentium 75", CPU_PENTIUM, 75000000, 3/2, 25000000, 0x522, 0x522, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7,4,4, 9},
- {"Pentium OverDrive MMX 75", CPU_PENTIUMMMX, 75000000, 3/2, 25000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7,4,4, 9},
- {"Pentium 90", CPU_PENTIUM, 90000000, 3/2, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 21/2},
- {"Pentium 100/50", CPU_PENTIUM, 100000000, 2, 25000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 12},
- {"Pentium 100/66", CPU_PENTIUM, 100000000, 3/2, 33333333, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 12},
- {"Pentium 120", CPU_PENTIUM, 120000000, 2, 30000000, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14},
-
- /*Intel Pentium OverDrive*/
- {"Pentium OverDrive 125", CPU_PENTIUM, 125000000, 3, 25000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7, 16},
- {"Pentium OverDrive 150", CPU_PENTIUM, 150000000, 5/2, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2},
- {"Pentium OverDrive 166", CPU_PENTIUM, 166666666, 5/2, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 40},
- {"Pentium OverDrive MMX 125", CPU_PENTIUMMMX, 125000000, 5/2, 25000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7, 15},
- {"Pentium OverDrive MMX 150/60", CPU_PENTIUMMMX, 150000000, 5/2, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2},
- {"Pentium OverDrive MMX 166", CPU_PENTIUMMMX, 166000000, 5/2, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20},
- {"Pentium OverDrive MMX 180", CPU_PENTIUMMMX, 180000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 21},
- {"Pentium OverDrive MMX 200", CPU_PENTIUMMMX, 200000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24},
- {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0, 0}
-};
-
-CPU cpus_Pentium3V[] = {
- /*Intel Pentium*/
- {"Pentium 75", CPU_PENTIUM, 75000000, 3/2, 25000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9},
- {"Pentium OverDrive MMX 75", CPU_PENTIUMMMX, 75000000, 3/2, 25000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9},
- {"Pentium 90", CPU_PENTIUM, 90000000, 3/2, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 21/2},
- {"Pentium 100/50", CPU_PENTIUM, 100000000, 2, 25000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 12},
- {"Pentium 100/66", CPU_PENTIUM, 100000000, 3/2, 33333333, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 12},
- {"Pentium 120", CPU_PENTIUM, 120000000, 2, 30000000, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14},
- {"Pentium 133", CPU_PENTIUM, 133333333, 2, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16},
- {"Pentium 150", CPU_PENTIUM, 150000000, 5/2, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2},
- {"Pentium 166", CPU_PENTIUM, 166666666, 5/2, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20},
- {"Pentium 200", CPU_PENTIUM, 200000000, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24},
-
- /*Intel Pentium OverDrive*/
- {"Pentium OverDrive 125", CPU_PENTIUM, 125000000, 5/2, 25000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 7, 7, 15},
- {"Pentium OverDrive 150", CPU_PENTIUM, 150000000, 5/2, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2},
- {"Pentium OverDrive 166", CPU_PENTIUM, 166666666, 5/2, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20},
- {"Pentium OverDrive MMX 125", CPU_PENTIUMMMX, 125000000, 5/2, 25000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 7, 7, 15},
- {"Pentium OverDrive MMX 150/60", CPU_PENTIUMMMX, 150000000, 5/2, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2},
- {"Pentium OverDrive MMX 166", CPU_PENTIUMMMX, 166000000, 5/2, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20},
- {"Pentium OverDrive MMX 180", CPU_PENTIUMMMX, 180000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 21},
- {"Pentium OverDrive MMX 200", CPU_PENTIUMMMX, 200000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24},
- {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
-};
-
-CPU cpus_Pentium[] = {
- /*Intel Pentium*/
- {"Pentium 75", CPU_PENTIUM, 75000000, 3/2, 25000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9},
- {"Pentium OverDrive MMX 75", CPU_PENTIUMMMX, 75000000, 3/2, 25000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9},
- {"Pentium 90", CPU_PENTIUM, 90000000, 3/2, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 21/2},
- {"Pentium 100/50", CPU_PENTIUM, 100000000, 2, 25000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 12},
- {"Pentium 100/66", CPU_PENTIUM, 100000000, 3/2, 33333333, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 12},
- {"Pentium 120", CPU_PENTIUM, 120000000, 2, 30000000, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14},
- {"Pentium 133", CPU_PENTIUM, 133333333, 2, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16},
- {"Pentium 150", CPU_PENTIUM, 150000000, 5/2, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2},
- {"Pentium 166", CPU_PENTIUM, 166666666, 5/2, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20},
- {"Pentium 200", CPU_PENTIUM, 200000000, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24},
-
- /*Intel Pentium MMX*/
- {"Pentium MMX 166", CPU_PENTIUMMMX, 166666666, 5/2, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20},
- {"Pentium MMX 200", CPU_PENTIUMMMX, 200000000, 3, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24},
- {"Pentium MMX 233", CPU_PENTIUMMMX, 233333333, 7/2, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28},
-
- /*Mobile Pentium*/
- {"Mobile Pentium MMX 120", CPU_PENTIUMMMX, 120000000, 2, 30000000, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14},
- {"Mobile Pentium MMX 133", CPU_PENTIUMMMX, 133333333, 2, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16},
- {"Mobile Pentium MMX 150", CPU_PENTIUMMMX, 150000000, 5/2, 30000000, 0x544, 0x544, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2},
- {"Mobile Pentium MMX 166", CPU_PENTIUMMMX, 166666666, 5/2, 33333333, 0x544, 0x544, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20},
- {"Mobile Pentium MMX 200", CPU_PENTIUMMMX, 200000000, 3, 33333333, 0x581, 0x581, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24},
- {"Mobile Pentium MMX 233", CPU_PENTIUMMMX, 233333333, 7/2, 33333333, 0x581, 0x581, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28},
- {"Mobile Pentium MMX 266", CPU_PENTIUMMMX, 266666666, 4, 33333333, 0x582, 0x582, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32},
- {"Mobile Pentium MMX 300", CPU_PENTIUMMMX, 300000000, 9/2, 33333333, 0x582, 0x582, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 36},
-
- /*Intel Pentium OverDrive*/
- {"Pentium OverDrive 125", CPU_PENTIUM, 125000000, 5/2, 25000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 7, 7, 15},
- {"Pentium OverDrive 150", CPU_PENTIUM, 150000000, 5/2, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2},
- {"Pentium OverDrive 166", CPU_PENTIUM, 166666666, 5/2, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20},
- {"Pentium OverDrive MMX 125", CPU_PENTIUMMMX, 125000000, 5/2, 25000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 7, 7, 15},
- {"Pentium OverDrive MMX 150/60", CPU_PENTIUMMMX, 150000000, 5/2, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2},
- {"Pentium OverDrive MMX 166", CPU_PENTIUMMMX, 166000000, 5/2, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20},
- {"Pentium OverDrive MMX 180", CPU_PENTIUMMMX, 180000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 21},
- {"Pentium OverDrive MMX 200", CPU_PENTIUMMMX, 200000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24},
- {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
-};
-
-#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_AMD_K))
-CPU cpus_K5[] = {
- /*AMD K5 (Socket 5)*/
- {"K5 (5k86) 75 (P75)", CPU_K5, 75000000, 3/2, 25000000, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7,4,4, 9},
- {"K5 (SSA/5) 75 (PR75)", CPU_K5, 75000000, 3/2, 25000000, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7,4,4, 9},
- {"K5 (5k86) 90 (P90)", CPU_K5, 90000000, 3/2, 30000000, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 21/2},
- {"K5 (SSA/5) 90 (PR90)", CPU_K5, 90000000, 3/2, 30000000, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 21/2},
- {"K5 (5k86) 100 (P100)", CPU_K5, 100000000, 3/2, 33333333, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 12},
- {"K5 (SSA/5) 100 (PR100)", CPU_K5, 100000000, 3/2, 33333333, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 12},
- {"K5 (5k86) 90 (PR120)", CPU_5K86, 120000000, 2, 30000000, 0x511, 0x511, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14},
- {"K5 (5k86) 100 (PR133)", CPU_5K86, 133333333, 2, 33333333, 0x514, 0x514, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16},
- {"K5 (5k86) 105 (PR150)", CPU_5K86, 150000000, 5/2, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2},
- {"K5 (5k86) 116.5 (PR166)", CPU_5K86, 166666666, 5/2, 33333333, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20},
- {"K5 (5k86) 133 (PR200)", CPU_5K86, 200000000, 3, 33333333, 0x534, 0x534, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24},
- {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0, 0}
-};
-
-CPU cpus_K56[] = {
- /*AMD K5 (Socket 7)*/
- {"K5 (5k86) 75 (P75)", CPU_K5, 75000000, 3/2, 25000000, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9},
- {"K5 (SSA/5) 75 (PR75)", CPU_K5, 75000000, 3/2, 25000000, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9},
- {"K5 (5k86) 90 (P90)", CPU_K5, 90000000, 3/2, 30000000, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 21/2},
- {"K5 (SSA/5) 90 (PR90)", CPU_K5, 90000000, 3/2, 30000000, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 21/2},
- {"K5 (5k86) 100 (P100)", CPU_K5, 100000000, 3/2, 33333333, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 12},
- {"K5 (SSA/5) 100 (PR100)", CPU_K5, 100000000, 3/2, 33333333, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 12},
- {"K5 (5k86) 90 (PR120)", CPU_5K86, 120000000, 2, 30000000, 0x511, 0x511, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14},
- {"K5 (5k86) 100 (PR133)", CPU_5K86, 133333333, 2, 33333333, 0x514, 0x514, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16},
- {"K5 (5k86) 105 (PR150)", CPU_5K86, 150000000, 5/2, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2},
- {"K5 (5k86) 116.5 (PR166)", CPU_5K86, 166666666, 5/2, 33333333, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20},
- {"K5 (5k86) 133 (PR200)", CPU_5K86, 200000000, 3, 33333333, 0x534, 0x534, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24},
-
- /*AMD K6 (Socket 7*/
- {"K6 (Model 6) 166", CPU_K6, 166666666, 5/2, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20},
- {"K6 (Model 6) 200", CPU_K6, 200000000, 3, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24},
- {"K6 (Model 6) 233", CPU_K6, 233333333, 7/2, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21, 10, 10, 28},
- {"K6 (Model 7) 200", CPU_K6, 200000000, 3, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24},
- {"K6 (Model 7) 233", CPU_K6, 233333333, 7/2, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21, 10, 10, 28},
- {"K6 (Model 7) 266", CPU_K6, 266666666, 4, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24, 12, 12, 32},
- {"K6 (Model 7) 300", CPU_K6, 300000000, 9/2, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27, 13, 13, 36},
-#ifdef USE_NEW_DYNAREC
- {"K6-2/233", CPU_K6_2, 233333333, 7/2, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21, 10, 10, 28},
- {"K6-2/266", CPU_K6_2, 266666666, 4, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24, 12, 12, 32},
- {"K6-2/300 AFR-66", CPU_K6_2, 300000000, 9/2, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27, 13, 13, 36},
- {"K6-2/366", CPU_K6_2, 366666666, 11/2, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 33,33, 17, 17, 44},
-#endif
- {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
-};
-#endif
-
-#ifdef USE_NEW_DYNAREC
-CPU cpus_K56_SS7[] = {
- /*AMD K5 (Socket 7)*/
- {"K5 (5k86) 75 (P75)", CPU_K5, 75000000, 3/2, 25000000, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9},
- {"K5 (SSA/5) 75 (PR75)", CPU_K5, 75000000, 3/2, 25000000, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9},
- {"K5 (5k86) 90 (P90)", CPU_K5, 90000000, 3/2, 30000000, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 21/2},
- {"K5 (SSA/5) 90 (PR90)", CPU_K5, 90000000, 3/2, 30000000, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 21/2},
- {"K5 (5k86) 100 (P100)", CPU_K5, 100000000, 3/2, 33333333, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 12},
- {"K5 (SSA/5) 100 (PR100)", CPU_K5, 100000000, 3/2, 33333333, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 12},
- {"K5 (5k86) 90 (PR120)", CPU_5K86, 120000000, 2, 30000000, 0x511, 0x511, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14},
- {"K5 (5k86) 100 (PR133)", CPU_5K86, 133333333, 2, 33333333, 0x514, 0x514, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16},
- {"K5 (5k86) 105 (PR150)", CPU_5K86, 150000000, 5/2, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2},
- {"K5 (5k86) 116.5 (PR166)", CPU_5K86, 166666666, 5/2, 33333333, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20},
- {"K5 (5k86) 133 (PR200)", CPU_5K86, 200000000, 3, 33333333, 0x534, 0x534, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24},
-
- /*AMD K6 (Socket 7)*/
- {"K6 (Model 6) 166", CPU_K6, 166666666, 5/2, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20},
- {"K6 (Model 6) 200", CPU_K6, 200000000, 3, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24},
- {"K6 (Model 6) 233", CPU_K6, 233333333, 7/2, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28},
- {"K6 (Model 7) 200", CPU_K6, 200000000, 3, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24},
- {"K6 (Model 7) 233", CPU_K6, 233333333, 7/2, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28},
- {"K6 (Model 7) 266", CPU_K6, 266666666, 4, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32},
- {"K6 (Model 7) 300", CPU_K6, 300000000, 9/2, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 36},
-
- /*AMD K6-2 (Socket 7/Super Socket 7)*/
- {"K6-2/233", CPU_K6_2, 233333333, 7/2, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21, 21, 10, 10, 28},
- {"K6-2/266", CPU_K6_2, 266666666, 4, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24, 24, 12, 12, 32},
- {"K6-2/300", CPU_K6_2, 300000000, 3, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 9, 9, 36},
- {"K6-2/333", CPU_K6_2, 332500000, 7/2, 31666667, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 30, 30, 11, 11, 40},
- {"K6-2/350", CPU_K6_2C, 350000000, 7/2, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 32, 32, 11, 11, 42},
- {"K6-2/366", CPU_K6_2C, 366666666, 11/2, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 33, 33, 17, 17, 44},
- {"K6-2/380", CPU_K6_2C, 380000000, 4, 31666667, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 34, 34, 12, 12, 46},
- {"K6-2/400", CPU_K6_2C, 400000000, 4, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 36, 36, 12, 12, 48},
- {"K6-2/450", CPU_K6_2C, 450000000, 9/2, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 41, 41, 14, 14, 54},
- {"K6-2/475", CPU_K6_2C, 475000000, 5, 31666667, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 43, 43, 15, 15, 57},
- {"K6-2/500", CPU_K6_2C, 500000000, 5, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 45, 45, 15, 15, 60},
- {"K6-2/533", CPU_K6_2C, 533333333, 11/2, 32323232, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 48, 48, 17, 17, 64},
- {"K6-2/550", CPU_K6_2C, 550000000, 11/2, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 50, 50, 17, 17, 66},
-
- /*AMD K6-2+/K6-3/K6-3+ (Super Socket 7)*/
- {"K6-2+/450", CPU_K6_2P, 450000000, 9/2, 33333333, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 41, 41, 14, 14, 54},
- {"K6-2+/475", CPU_K6_2P, 475000000, 5, 31666667, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 43, 43, 15, 15, 57},
- {"K6-2+/500", CPU_K6_2P, 500000000, 5, 33333333, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 45, 45, 15, 15, 60},
- {"K6-2+/533", CPU_K6_2P, 533333333, 11/2, 32323232, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 48, 48, 17, 17, 64},
- {"K6-2+/550", CPU_K6_2P, 550000000, 11/2, 32333333, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 50, 50, 17, 17, 66},
- {"K6-III/400", CPU_K6_3, 400000000, 4, 33333333, 0x591, 0x591, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 36, 36, 12, 12, 48},
- {"K6-III/450", CPU_K6_3, 450000000, 9/2, 33333333, 0x591, 0x591, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 41, 41, 14, 14, 54},
- {"K6-III+/400", CPU_K6_3P, 400000000, 4, 33333333, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 36, 36, 12, 12, 48},
- {"K6-III+/450", CPU_K6_3P, 450000000, 9/2, 33333333, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 41, 41, 14, 14, 54},
- {"K6-III+/475", CPU_K6_3P, 475000000, 5, 31666667, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 43, 43, 15, 15, 57},
- {"K6-III+/500", CPU_K6_3P, 500000000, 5, 33333333, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 45, 45, 15, 15, 60},
- {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
-};
-#endif
-
-#ifdef DEV_BRANCH
-#ifdef USE_I686
-CPU cpus_PentiumPro[] = {
- /*Intel Pentium Pro*/
- {"Pentium Pro 50", CPU_PENTIUMPRO, 50000000, 1, 25000000, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 4, 4, 3, 3, 6},
- {"Pentium Pro 60" , CPU_PENTIUMPRO, 60000000, 1, 30000000, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 7},
- {"Pentium Pro 66" , CPU_PENTIUMPRO, 66666666, 1, 33333333, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 8},
- {"Pentium Pro 75", CPU_PENTIUMPRO, 75000000, 3/2, 25000000, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9},
- {"Pentium Pro 150", CPU_PENTIUMPRO, 150000000, 5/2, 30000000, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2},
- {"Pentium Pro 166", CPU_PENTIUMPRO, 166666666, 5/2, 33333333, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20},
- {"Pentium Pro 180", CPU_PENTIUMPRO, 180000000, 3, 30000000, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 21},
- {"Pentium Pro 200", CPU_PENTIUMPRO, 200000000, 3, 33333333, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24},
-
- /*Intel Pentium II OverDrive*/
- {"Pentium II Overdrive 50", CPU_PENTIUM2D, 50000000, 1, 25000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 4, 4, 3, 3, 6},
- {"Pentium II Overdrive 60", CPU_PENTIUM2D, 60000000, 1, 30000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 7},
- {"Pentium II Overdrive 66", CPU_PENTIUM2D, 66666666, 1, 33333333, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 8},
- {"Pentium II Overdrive 75", CPU_PENTIUM2D, 75000000, 3/2, 25000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9},
- {"Pentium II Overdrive 210", CPU_PENTIUM2D, 210000000, 7/2, 30000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17,17, 7, 7, 25},
- {"Pentium II Overdrive 233", CPU_PENTIUM2D, 233333333, 7/2, 33333333, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28},
- {"Pentium II Overdrive 240", CPU_PENTIUM2D, 240000000, 4, 30000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 29},
- {"Pentium II Overdrive 266", CPU_PENTIUM2D, 266666666, 4, 33333333, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32},
- {"Pentium II Overdrive 270", CPU_PENTIUM2D, 270000000, 9/2, 30000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 25,25,12,12, 33},
- {"Pentium II Overdrive 300/66", CPU_PENTIUM2D, 300000000, 9/2, 33333333, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 25,25,12,12, 36},
- {"Pentium II Overdrive 300/60", CPU_PENTIUM2D, 300000000, 5, 30000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 36},
- {"Pentium II Overdrive 333", CPU_PENTIUM2D, 333333333, 5, 33333333, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 40},
- {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
-};
-#endif
-#endif
diff --git a/src/cpu_common/x86_ops_i686.h b/src/cpu_common/x86_ops_i686.h
index ad0fb946e..21c6b5a7b 100644
--- a/src/cpu_common/x86_ops_i686.h
+++ b/src/cpu_common/x86_ops_i686.h
@@ -132,7 +132,7 @@ static int opSYSEXIT(uint32_t fetchdat)
do_seg_load(&cpu_state.seg_ss, sysexit_ss_seg_data);
stack32 = 1;
- flushmmucache_cr3();
+ flushmmucache();
cycles -= timing_call_pm;
diff --git a/src/cpu_common/x86_ops_misc.h b/src/cpu_common/x86_ops_misc.h
index 8447ef9da..b1a836085 100644
--- a/src/cpu_common/x86_ops_misc.h
+++ b/src/cpu_common/x86_ops_misc.h
@@ -607,6 +607,8 @@ static int opF7_l_a32(uint32_t fetchdat)
static int opHLT(uint32_t fetchdat)
{
+ in_hlt = 0;
+
if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))
{
x86gpf(NULL,0);
@@ -615,8 +617,10 @@ static int opHLT(uint32_t fetchdat)
if (!((cpu_state.flags & I_FLAG) && pic_intpending))
{
CLOCK_CYCLES_ALWAYS(100);
- if (!((cpu_state.flags & I_FLAG) && pic_intpending))
+ if (!((cpu_state.flags & I_FLAG) && pic_intpending)) {
+ in_hlt = 1;
cpu_state.pc--;
+ }
}
else
CLOCK_CYCLES(5);
@@ -831,6 +835,7 @@ static void loadall_load_segment(uint32_t addr, x86seg *s)
uint32_t attrib = readmeml(0, addr);
uint32_t segdat3 = (attrib >> 16) & 0xff;
s->access = (attrib >> 8) & 0xff;
+ s->ar_high = segdat3;
s->base = readmeml(0, addr + 4);
s->limit = readmeml(0, addr + 8);
@@ -953,10 +958,8 @@ static int opRSM(uint32_t fetchdat)
if (in_smm)
{
leave_smm();
- if (smi_latched) {
- smi_latched = 0;
+ if (smi_latched)
enter_smm();
- }
CPU_BLOCK_END();
return 0;
}
diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c
index 72f29f21e..77480f91f 100644
--- a/src/disk/hdc_ide.c
+++ b/src/disk/hdc_ide.c
@@ -115,7 +115,7 @@
typedef struct {
int bit32, cur_dev,
irq, inited,
- diag;
+ diag, force_ata3;
uint16_t base_main, side_main;
pc_timer_t timer;
} ide_board_t;
@@ -281,7 +281,7 @@ ide_irq_raise(ide_t *ide)
ide_log("IDE %i: IRQ raise\n", ide->board);
if (!(ide->fdisk & 2)) {
- if (ide_bm[ide->board] && ide_bm[ide->board]->set_irq)
+ if (!ide_boards[ide->board]->force_ata3 && ide_bm[ide->board] && ide_bm[ide->board]->set_irq)
ide_bm[ide->board]->set_irq(ide->board | 0x40, ide_bm[ide->board]->priv);
else if (ide_boards[ide->board]->irq != -1)
picint(1 << ide_boards[ide->board]->irq);
@@ -303,7 +303,7 @@ ide_irq_lower(ide_t *ide)
ide_log("IDE %i: IRQ lower\n", ide->board);
if (ide->irqstat) {
- if (ide_bm[ide->board] && ide_bm[ide->board]->set_irq)
+ if (!ide_boards[ide->board]->force_ata3 && ide_bm[ide->board] && ide_bm[ide->board]->set_irq)
ide_bm[ide->board]->set_irq(ide->board, ide_bm[ide->board]->priv);
else if (ide_boards[ide->board]->irq != -1)
picintc(1 << ide_boards[ide->board]->irq);
@@ -323,7 +323,7 @@ ide_irq_update(ide_t *ide)
if (!(ide->fdisk & 2) && ide->irqstat) {
ide_log("IDE %i: IRQ update raise\n", ide->board);
- if (ide_bm[ide->board] && ide_bm[ide->board]->set_irq) {
+ if (!ide_boards[ide->board]->force_ata3 && ide_bm[ide->board] && ide_bm[ide->board]->set_irq) {
ide_bm[ide->board]->set_irq(ide->board, ide_bm[ide->board]->priv);
ide_bm[ide->board]->set_irq(ide->board | 0x40, ide_bm[ide->board]->priv);
} else if (ide_boards[ide->board]->irq != -1) {
@@ -332,7 +332,7 @@ ide_irq_update(ide_t *ide)
}
} else if (ide->fdisk & 2) {
ide_log("IDE %i: IRQ update lower\n", ide->board);
- if (ide_bm[ide->board] && ide_bm[ide->board]->set_irq)
+ if (!ide_boards[ide->board]->force_ata3 && ide_bm[ide->board] && ide_bm[ide->board]->set_irq)
ide_bm[ide->board]->set_irq(ide->board, ide_bm[ide->board]->priv);
else if (ide_boards[ide->board]->irq != -1)
picintc(1 << ide_boards[ide->board]->irq);
@@ -390,26 +390,26 @@ static int
ide_get_max(ide_t *ide, int type)
{
if (ide->type == IDE_ATAPI)
- return ide->get_max(ide_bm[ide->board] != NULL, type);
+ return ide->get_max(!ide_boards[ide->board]->force_ata3 && (ide_bm[ide->board] != NULL), type);
switch(type) {
case TYPE_PIO: /* PIO */
- if (ide_bm[ide->board] != NULL)
+ if (!ide_boards[ide->board]->force_ata3 && (ide_bm[ide->board] != NULL))
return 1;
return 0; /* Maximum PIO 0 for legacy PIO-only drive. */
case TYPE_SDMA: /* SDMA */
- if (ide_bm[ide->board] != NULL)
+ if (!ide_boards[ide->board]->force_ata3 && (ide_bm[ide->board] != NULL))
return 2;
return -1;
case TYPE_MDMA: /* MDMA */
- if (ide_bm[ide->board] != NULL)
+ if (!ide_boards[ide->board]->force_ata3 && (ide_bm[ide->board] != NULL))
return 2;
return -1;
case TYPE_UDMA: /* UDMA */
- if (ide_bm[ide->board] != NULL)
+ if (!ide_boards[ide->board]->force_ata3 && (ide_bm[ide->board] != NULL))
return 2;
return -1;
@@ -424,16 +424,16 @@ static int
ide_get_timings(ide_t *ide, int type)
{
if (ide->type == IDE_ATAPI)
- return ide->get_timings(ide_bm[ide->board] != NULL, type);
+ return ide->get_timings(!ide_boards[ide->board]->force_ata3 && (ide_bm[ide->board] != NULL), type);
switch(type) {
case TIMINGS_DMA:
- if (ide_bm[ide->board] != NULL)
+ if (!ide_boards[ide->board]->force_ata3 && (ide_bm[ide->board] != NULL))
return 120;
return 0;
case TIMINGS_PIO:
- if (ide_bm[ide->board] != NULL)
+ if (!ide_boards[ide->board]->force_ata3 && (ide_bm[ide->board] != NULL))
return 120;
return 0;
@@ -529,7 +529,7 @@ static void ide_hd_identify(ide_t *ide)
ide_log("Current CHS translation: %i, %i, %i\n", ide->buffer[54], ide->buffer[55], ide->buffer[56]);
}
- if (ide_bm[ide->board]) {
+ if (!ide_boards[ide->board]->force_ata3 && ide_bm[ide->board]) {
ide->buffer[47] = 32 | 0x8000; /*Max sectors on multiple transfer command*/
ide->buffer[80] = 0x1e; /*ATA-1 to ATA-4 supported*/
ide->buffer[81] = 0x18; /*ATA-4 revision 18 supported*/
@@ -550,7 +550,7 @@ ide_identify(ide_t *ide)
memset(ide->buffer, 0, 512);
if (ide->type == IDE_ATAPI)
- ide->identify(ide, ide_bm[ide->board] != NULL);
+ ide->identify(ide, !ide_boards[ide->board]->force_ata3 && (ide_bm[ide->board] != NULL));
else if (ide->type != IDE_NONE)
ide_hd_identify(ide);
else {
@@ -840,7 +840,7 @@ ide_atapi_attach(ide_t *ide)
ide->type = IDE_ATAPI;
ide_allocate_buffer(ide);
ide_set_signature(ide);
- ide->mdma_mode = (1 << ide->get_max(!ide_bm[ide->board], TYPE_PIO));
+ ide->mdma_mode = (1 << ide->get_max(ide_boards[ide->board]->force_ata3 || !ide_bm[ide->board], TYPE_PIO));
ide->error = 1;
ide->cfg_spt = ide->cfg_hpc = 0;
}
@@ -926,7 +926,7 @@ ide_atapi_callback(ide_t *ide)
#endif
out = (ide->sc->packet_status & 0x01);
- if (ide_bm[ide->board] && ide_bm[ide->board]->dma) {
+ if (!ide_boards[ide->board]->force_ata3 && ide_bm[ide->board] && ide_bm[ide->board]->dma) {
ret = ide_bm[ide->board]->dma(ide->board,
ide->sc->temp_buffer, ide->sc->packet_len,
out, ide_bm[ide->board]->priv);
@@ -2040,7 +2040,7 @@ ide_callback(void *priv)
case WIN_READ_DMA:
case WIN_READ_DMA_ALT:
- if ((ide->type == IDE_ATAPI) || !ide_bm[ide->board]) {
+ if ((ide->type == IDE_ATAPI) || ide_boards[ide->board]->force_ata3 || !ide_bm[ide->board]) {
ide_log("IDE %i: DMA read aborted (bad device or board)\n", ide->channel);
goto abort_cmd;
}
@@ -2058,7 +2058,7 @@ ide_callback(void *priv)
ide->pos=0;
- if (ide_bm[ide->board] && ide_bm[ide->board]->dma) {
+ if (!ide_boards[ide->board]->force_ata3 && ide_bm[ide->board] && ide_bm[ide->board]->dma) {
/* We should not abort - we should simply wait for the host to start DMA. */
ret = ide_bm[ide->board]->dma(ide->board,
ide->sector_buffer, ide->sector_pos * 512,
@@ -2143,7 +2143,7 @@ ide_callback(void *priv)
case WIN_WRITE_DMA:
case WIN_WRITE_DMA_ALT:
- if ((ide->type == IDE_ATAPI) || !ide_bm[ide->board]) {
+ if ((ide->type == IDE_ATAPI) || ide_boards[ide->board]->force_ata3 || !ide_bm[ide->board]) {
ide_log("IDE %i: DMA write aborted (bad device type or board)\n", ide->channel);
goto abort_cmd;
}
@@ -2152,7 +2152,7 @@ ide_callback(void *priv)
goto id_not_found;
}
- if (ide_bm[ide->board] && ide_bm[ide->board]->dma) {
+ if (!ide_boards[ide->board]->force_ata3 && ide_bm[ide->board] && ide_bm[ide->board]->dma) {
if (ide->secount)
ide->sector_pos = ide->secount;
else
@@ -2466,6 +2466,20 @@ ide_clear_bus_master(int board)
}
+/* This so drives can be forced to ATA-3 (no DMA) for machines that hide the on-board PCI IDE controller
+ (eg. Packard Bell PB640 and ASUS P/I-P54TP4XE), breaking DMA drivers unless this is done. */
+extern void
+ide_board_set_force_ata3(int board, int force_ata3)
+{
+ ide_log("ide_board_set_force_ata3(%i, %i)\n", board, force_ata3);
+
+ if ((ide_boards[board] == NULL)|| !ide_boards[board]->inited)
+ return;
+
+ ide_boards[board]->force_ata3 = force_ata3;
+}
+
+
static void
ide_board_close(int board)
{
diff --git a/src/dma.c b/src/dma.c
index 8ce081bf2..ae85f3332 100644
--- a/src/dma.c
+++ b/src/dma.c
@@ -757,8 +757,6 @@ dma_channel_read(int channel)
if (!AT && !channel)
refreshread();
- /* if (!AT && channel)
- pclog("DMA refresh read on channel %i\n", channel); */
if (! dma_c->size) {
temp = _dma_read(dma_c->ac);
@@ -830,11 +828,6 @@ dma_channel_write(int channel, uint16_t val)
if ((dma_c->mode & 0xC) != 4)
return(DMA_NODATA);
- /* if (!AT)
- refreshread();
- if (!AT)
- pclog("DMA refresh write on channel %i\n", channel); */
-
if (! dma_c->size) {
_dma_write(dma_c->ac, val & 0xff);
diff --git a/src/hwm_w83781d.c b/src/hwm_w83781d.c
index a3b954c94..fc04ff37d 100644
--- a/src/hwm_w83781d.c
+++ b/src/hwm_w83781d.c
@@ -13,10 +13,12 @@
* Author: RichardG,
* Copyright 2020 RichardG.
*/
+#include
#include
#include
#include
#include
+#define HAVE_STDARG_H
#include
#include <86box/86box.h>
#include <86box/device.h>
@@ -67,6 +69,26 @@ static uint8_t w83781d_write(w83781d_t *dev, uint8_t reg, uint8_t val, uint8_t b
static void w83781d_reset(w83781d_t *dev, uint8_t initialization);
+#ifdef ENABLE_W83781D_LOG
+int w83781d_do_log = ENABLE_W83781D_LOG;
+
+
+static void
+w83781d_log(const char *fmt, ...)
+{
+ va_list ap;
+
+ if (w83781d_do_log) {
+ va_start(ap, fmt);
+ pclog_ex(fmt, ap);
+ va_end(ap);
+ }
+}
+#else
+#define w83781d_log(fmt, ...)
+#endif
+
+
static void
w83781d_remap(w83781d_t *dev)
{
@@ -200,7 +222,7 @@ w83781d_read(w83781d_t *dev, uint8_t reg, uint8_t bank)
ret = dev->regs[reg];
}
- pclog("w83781d_read(%02x, %d) = %02x\n", reg, bank, ret);
+ w83781d_log("w83781d_read(%02x, %d) = %02x\n", reg, bank, ret);
return ret;
}
diff --git a/src/include/86box/chipset.h b/src/include/86box/chipset.h
index da4942c99..87a4b44e4 100644
--- a/src/include/86box/chipset.h
+++ b/src/include/86box/chipset.h
@@ -65,6 +65,7 @@ extern const device_t sis_85c50x_device;
#endif
/* VIA */
+extern const device_t via_vp3_device;
extern const device_t via_mvp3_device;
extern const device_t via_apro_device;
diff --git a/src/include/86box/hdc_ide.h b/src/include/86box/hdc_ide.h
index 954d11971..b96379d1a 100644
--- a/src/include/86box/hdc_ide.h
+++ b/src/include/86box/hdc_ide.h
@@ -130,6 +130,8 @@ extern void ide_pri_disable(void);
extern void ide_sec_enable(void);
extern void ide_sec_disable(void);
+extern void ide_board_set_force_ata3(int board, int force_ata3);
+
extern double ide_atapi_get_period(uint8_t channel);
extern void ide_set_callback(uint8_t channel, double callback);
diff --git a/src/include/86box/keyboard.h b/src/include/86box/keyboard.h
index 649d33f8d..429e14712 100644
--- a/src/include/86box/keyboard.h
+++ b/src/include/86box/keyboard.h
@@ -101,6 +101,7 @@ extern int keyboard_ismsexit(void);
extern void keyboard_at_adddata_keyboard_raw(uint8_t val);
extern void keyboard_at_adddata_mouse(uint8_t val);
extern void keyboard_at_set_mouse(void (*mouse_write)(uint8_t val,void *), void *);
+extern void keyboard_at_set_a20_key(int state);
extern uint8_t keyboard_at_get_mouse_scan(void);
extern void keyboard_at_set_mouse_scan(uint8_t val);
extern void keyboard_at_reset(void);
diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h
index 56a7e4e1c..f8c15b240 100644
--- a/src/include/86box/machine.h
+++ b/src/include/86box/machine.h
@@ -263,6 +263,7 @@ extern int machine_at_endeavor_init(const machine_t *);
extern int machine_at_zappa_init(const machine_t *);
extern int machine_at_mb500n_init(const machine_t *);
extern int machine_at_president_init(const machine_t *);
+extern int machine_at_apollo_init(const machine_t *);
#if defined(DEV_BRANCH) && defined(USE_VECTRA54)
extern int machine_at_vectra54_init(const machine_t *);
#endif
diff --git a/src/include/86box/mem.h b/src/include/86box/mem.h
index 4559514fb..167755a2d 100644
--- a/src/include/86box/mem.h
+++ b/src/include/86box/mem.h
@@ -35,6 +35,8 @@
#define MEM_READ_INTERNAL 0x10
#define MEM_READ_EXTERNAL 0x20
#define MEM_READ_DISABLED 0x30
+#define MEM_READ_NORMAL 0x40 /* SMM only - means use the non-SMM state */
+#define MEM_READ_EXTERNAL_EX 0x50 /* External but with internal exec - needed by the VIA Apollo Pro */
#define MEM_READ_ROMCS 0x60 /* EXTERNAL type + ROMC flag */
#define MEM_READ_EXTANY 0x70 /* Any EXTERNAL type */
#define MEM_READ_MASK 0xf0
@@ -43,16 +45,21 @@
#define MEM_WRITE_INTERNAL 0x01
#define MEM_WRITE_EXTERNAL 0x02
#define MEM_WRITE_DISABLED 0x03
+#define MEM_WRITE_NORMAL 0x04 /* SMM only - means use the non-SMM state */
#define MEM_WRITE_ROMCS 0x06 /* EXTERNAL type + ROMC flag */
#define MEM_WRITE_EXTANY 0x07 /* Any EXTERNAL type */
#define MEM_WRITE_MASK 0x0f
+#define MEM_STATE_SMM_SHIFT 8
+
/* #define's for memory granularity, currently 16k, but may
change in the future - 4k works, less does not because of
internal 4k pages. */
#ifdef DEFAULT_GRANULARITY
#define MEM_GRANULARITY_BITS 14
#define MEM_GRANULARITY_SIZE (1 << MEM_GRANULARITY_BITS)
+#define MEM_GRANULARITY_HBOUND (MEM_GRANULARITY_SIZE - 2)
+#define MEM_GRANULARITY_QBOUND (MEM_GRANULARITY_SIZE - 4)
#define MEM_GRANULARITY_MASK (MEM_GRANULARITY_SIZE - 1)
#define MEM_GRANULARITY_HMASK ((1 << (MEM_GRANULARITY_BITS - 1)) - 1)
#define MEM_GRANULARITY_QMASK ((1 << (MEM_GRANULARITY_BITS - 2)) - 1)
@@ -61,6 +68,8 @@
#else
#define MEM_GRANULARITY_BITS 12
#define MEM_GRANULARITY_SIZE (1 << MEM_GRANULARITY_BITS)
+#define MEM_GRANULARITY_HBOUND (MEM_GRANULARITY_SIZE - 2)
+#define MEM_GRANULARITY_QBOUND (MEM_GRANULARITY_SIZE - 4)
#define MEM_GRANULARITY_MASK (MEM_GRANULARITY_SIZE - 1)
#define MEM_GRANULARITY_HMASK ((1 << (MEM_GRANULARITY_BITS - 1)) - 1)
#define MEM_GRANULARITY_QMASK ((1 << (MEM_GRANULARITY_BITS - 2)) - 1)
@@ -260,9 +269,12 @@ extern void mem_mapping_set_addr(mem_mapping_t *,
extern void mem_mapping_set_exec(mem_mapping_t *, uint8_t *exec);
extern void mem_mapping_disable(mem_mapping_t *);
extern void mem_mapping_enable(mem_mapping_t *);
+extern void mem_mapping_recalc(uint64_t base, uint64_t size);
+
+extern void mem_set_mem_state_common(int smm, uint32_t base, uint32_t size, int state);
extern void mem_set_mem_state(uint32_t base, uint32_t size, int state);
-extern void mem_restore_mem_state(uint32_t base, uint32_t size);
+extern void mem_set_mem_state_smm(uint32_t base, uint32_t size, int state);
extern uint8_t mem_readb_phys(uint32_t addr);
extern uint16_t mem_readw_phys(uint32_t addr);
@@ -311,6 +323,7 @@ extern void mem_add_upper_bios(void);
extern void mem_add_bios(void);
extern void mem_init(void);
+
extern void mem_reset(void);
extern void mem_remap_top(int kb);
diff --git a/src/intel_piix.c b/src/intel_piix.c
index df2cf70e0..49b5757f1 100644
--- a/src/intel_piix.c
+++ b/src/intel_piix.c
@@ -469,8 +469,13 @@ piix_write(int func, int addr, uint8_t val, void *priv)
uint8_t *fregs;
/* Return on unsupported function. */
- if (func > dev->max_func)
- return;
+ if (dev->max_func > 0) {
+ if (func > dev->max_func)
+ return;
+ } else {
+ if (func > 1)
+ return;
+ }
piix_log("PIIX function %i write: %02X to %02X\n", func, val, addr);
fregs = (uint8_t *) dev->regs[func];
@@ -872,7 +877,7 @@ piix_read(int func, int addr, void *priv)
uint8_t ret = 0xff, *fregs;
/* Return on unsupported function. */
- if (func <= dev->max_func) {
+ if ((func <= dev->max_func) || ((func == 1) && (dev->max_func == 0))) {
fregs = (uint8_t *) dev->regs[func];
ret = fregs[addr];
diff --git a/src/io.c b/src/io.c
index e1686861f..9714e6bd2 100644
--- a/src/io.c
+++ b/src/io.c
@@ -354,6 +354,9 @@ inb(uint16_t port)
// if (!found)
// pclog("inb(%04X) = %02X\n", port, ret);
+ // if (in_smm)
+ // pclog("inb(%04X) = %02X\n", port, ret);
+
return(ret);
}
@@ -364,6 +367,9 @@ outb(uint16_t port, uint8_t val)
io_t *p;
int found = 0;
+ // if (in_smm)
+ // pclog("outb(%04X, %02X)\n", port, val);
+
if (io[port]) {
p = io[port];
while(p) {
@@ -411,6 +417,9 @@ inw(uint16_t port)
if (!found)
ret = (inb(port) | (inb(port + 1) << 8));
+ // if (in_smm)
+ // pclog("inw(%04X) = %04X\n", port, ret);
+
return ret;
}
@@ -420,6 +429,9 @@ outw(uint16_t port, uint16_t val)
{
io_t *p;
+ // if (in_smm)
+ // pclog("outw(%04X, %04X)\n", port, val);
+
p = io[port];
if (p) {
while(p) {
@@ -459,6 +471,9 @@ inl(uint16_t port)
if (!found)
ret = (inw(port) | (inw(port + 2) << 16));
+ // if (in_smm)
+ // pclog("inl(%04X) = %08X\n", port, ret);
+
return ret;
}
@@ -468,6 +483,9 @@ outl(uint16_t port, uint32_t val)
{
io_t *p;
+ // if (in_smm)
+ // pclog("outl(%04X, %08X)\n", port, val);
+
p = io[port];
if (p) {
while(p) {
diff --git a/src/keyboard_at.c b/src/keyboard_at.c
index 26f86762f..7afd45a9c 100644
--- a/src/keyboard_at.c
+++ b/src/keyboard_at.c
@@ -2627,3 +2627,12 @@ keyboard_at_get_mouse_scan(void)
{
return(mouse_scan ? 0x10 : 0x00);
}
+
+
+void
+keyboard_at_set_a20_key(int state)
+{
+ atkbd_t *dev = SavedKbd;
+
+ write_output(dev, (dev->output_port & 0xfd) | ((!!state) << 1));
+}
diff --git a/src/machine/m_at_socket4_5.c b/src/machine/m_at_socket4_5.c
index dc6ad9b64..02e4074e2 100644
--- a/src/machine/m_at_socket4_5.c
+++ b/src/machine/m_at_socket4_5.c
@@ -36,6 +36,7 @@
#include <86box/keyboard.h>
#include <86box/intel_flash.h>
#include <86box/intel_sio.h>
+#include <86box/nvr.h>
#include <86box/piix.h>
#include <86box/sio.h>
#include <86box/video.h>
@@ -243,6 +244,8 @@ machine_at_p54tp4xe_init(const machine_t *model)
device_add(&keyboard_ps2_pci_device);
device_add(&i430fx_device);
device_add(&piix_device);
+ ide_board_set_force_ata3(0, 1);
+ ide_board_set_force_ata3(1, 1);
device_add(&fdc37c665_device);
device_add(&intel_flash_bxt_device);
@@ -381,6 +384,37 @@ machine_at_president_init(const machine_t *model)
}
+int
+machine_at_apollo_init(const machine_t *model)
+{
+ int ret;
+
+ ret = bios_load_linear(L"roms/machines/apollo/S728P.ROM",
+ 0x000e0000, 131072, 0);
+
+ if (bios_only || !ret)
+ return ret;
+
+ machine_at_common_init_ex(model, 2);
+ device_add(&ls486e_nvr_device);
+
+ pci_init(PCI_CONFIG_TYPE_1);
+ pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
+ pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4);
+ pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1);
+ pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2);
+ pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3);
+ pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
+ device_add(&i430fx_device);
+ device_add(&piix_device);
+ device_add(&keyboard_ps2_pci_device);
+ device_add(&fdc37c932fr_device);
+ device_add(&intel_flash_bxt_device);
+
+ return ret;
+}
+
+
#if defined(DEV_BRANCH) && defined(USE_VECTRA54)
int
machine_at_vectra54_init(const machine_t *model)
diff --git a/src/machine/m_at_socket7_s7.c b/src/machine/m_at_socket7_s7.c
index 1bbee25fd..3ea003a61 100644
--- a/src/machine/m_at_socket7_s7.c
+++ b/src/machine/m_at_socket7_s7.c
@@ -122,7 +122,8 @@ machine_at_pb640_init(const machine_t *model)
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
device_add(&i430fx_pb640_device);
device_add(&piix_device);
- device_add(&ide_isa_2ch_device);
+ ide_board_set_force_ata3(0, 1);
+ ide_board_set_force_ata3(1, 1);
if (gfxcard == VID_INTERNAL)
device_add(&gd5440_onboard_pci_device);
diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c
index 04a962c7a..ed9457c2b 100644
--- a/src/machine/machine_table.c
+++ b/src/machine/machine_table.c
@@ -179,10 +179,11 @@ const machine_t machines[] = {
{ "[486 MCA] IBM PS/2 model 70 (type 4)", "ibmps2_m70_type4", {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO, 2, 16, 2, 63, machine_ps2_model_70_type4_init, NULL },
#endif
+ { "[486 PCI] ASUS PCI/I-486SP3G", "486sp3g", {{"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 },
{ "[486 PCI] Intel Classic/PCI", "alfredo", {{"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 },
{ "[486 PCI] Lucky Star LS-486E", "ls486e", {{"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 },
{ "[486 PCI] Rise Computer R418", "r418", {{"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 },
- { "[486 PCI] ASUS PCI/I-486SP3G", "486sp3g", {{"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 },
+ { "[486 PCI] Zida Tomato 4DP", "4dps", {{"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 },
{ "[Socket 4 LX] IBM Ambra DP60 PCI", "ambradp60", {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_ambradp60_init, NULL },
#if defined(DEV_BRANCH) && defined(USE_VPP60)
@@ -195,7 +196,7 @@ const machine_t machines[] = {
{ "[Socket 5 NX] IBM Ambra DP90 PCI", "ambradp90", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_ambradp90_init, NULL },
{ "[Socket 5 NX] Gigabyte GA-586IP", "430nx", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_430nx_init, NULL },
- { "[Socket 5 FX] ASUS P/I-P54TP4XE", "p54tp4xe", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_p54tp4xe_init, NULL },
+ { "[Socket 5 FX] AMI Apollo", "apollo", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_apollo_init, NULL },
#if defined(DEV_BRANCH) && defined(USE_VECTRA54)
{ "[Socket 5 FX] HP Vectra VL 5 Series 4", "vectra54", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 767, machine_at_vectra54_init, NULL },
#endif
@@ -203,11 +204,12 @@ const machine_t machines[] = {
{ "[Socket 5 FX] PC Partner MB500N", "mb500n", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_mb500n_init, NULL },
{ "[Socket 5 FX] President Award 430FX PCI","president", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_president_init, NULL },
+ { "[Socket 7-3V FX] ASUS P/I-P54TP4XE", "p54tp4xe", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_p54tp4xe_init, NULL },
{ "[Socket 7-3V FX] Intel Advanced/ATX", "thor", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_thor_init, NULL },
+ { "[Socket 7-3V FX] Intel Advanced/EV", "endeavor", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_endeavor_init, at_endeavor_get_device },
#if defined(DEV_BRANCH) && defined(USE_MRTHOR)
{ "[Socket 7-3V FX] MR Intel Advanced/ATX", "mrthor", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_mrthor_init, NULL },
#endif
- { "[Socket 7-3V FX] Intel Advanced/EV", "endeavor", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_endeavor_init, at_endeavor_get_device },
{ "[Socket 7-3V FX] Packard Bell PB640", "pb640", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_pb640_init, at_pb640_get_device },
{ "[Socket 7-3V HX] Acer M3a", "acerm3a", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 192, 8, 127, machine_at_acerm3a_init, NULL },
diff --git a/src/mem.c b/src/mem.c
index f08c2fc9c..600cd106a 100644
--- a/src/mem.c
+++ b/src/mem.c
@@ -120,7 +120,7 @@ int purgeable_page_count = 0;
static mem_mapping_t *read_mapping[MEM_MAPPINGS_NO];
static mem_mapping_t *write_mapping[MEM_MAPPINGS_NO];
static uint8_t *_mem_exec[MEM_MAPPINGS_NO];
-static int _mem_state[MEM_MAPPINGS_NO], _mem_state_bak[MEM_MAPPINGS_NO];
+static int _mem_state[MEM_MAPPINGS_NO];
#if FIXME
#if (MEM_GRANULARITY_BITS >= 12)
@@ -1187,11 +1187,12 @@ uint16_t
mem_readw_phys(uint32_t addr)
{
mem_mapping_t *map = read_mapping[addr >> MEM_GRANULARITY_BITS];
- uint16_t temp;
+ uint16_t temp, *p;
- if (_mem_exec[addr >> MEM_GRANULARITY_BITS])
- return ((uint16_t *) _mem_exec[addr >> MEM_GRANULARITY_BITS])[(addr >> 1) & MEM_GRANULARITY_HMASK];
- else if (map && map->read_w)
+ if ((addr <= MEM_GRANULARITY_HBOUND) && (_mem_exec[addr >> MEM_GRANULARITY_BITS])) {
+ p = (uint16_t *) &(_mem_exec[addr >> MEM_GRANULARITY_BITS][addr & MEM_GRANULARITY_MASK]);
+ return *p;
+ } else if ((addr <= MEM_GRANULARITY_HBOUND) && (map && map->read_w))
return map->read_w(addr, map->p);
else {
temp = mem_readb_phys(addr + 1) << 8;
@@ -1206,11 +1207,12 @@ uint32_t
mem_readl_phys(uint32_t addr)
{
mem_mapping_t *map = read_mapping[addr >> MEM_GRANULARITY_BITS];
- uint32_t temp;
+ uint32_t temp, *p;
- if (_mem_exec[addr >> MEM_GRANULARITY_BITS])
- return ((uint32_t *) _mem_exec[addr >> MEM_GRANULARITY_BITS])[(addr >> 1) & MEM_GRANULARITY_QMASK];
- else if (map && map->read_l)
+ if ((addr <= MEM_GRANULARITY_QBOUND) && (_mem_exec[addr >> MEM_GRANULARITY_BITS])) {
+ p = (uint32_t *) &(_mem_exec[addr >> MEM_GRANULARITY_BITS][addr & MEM_GRANULARITY_MASK]);
+ return *p;
+ } else if ((addr <= MEM_GRANULARITY_QBOUND) && (map && map->read_l))
return map->read_l(addr, map->p);
else {
temp = mem_readw_phys(addr + 2) << 16;
@@ -1237,10 +1239,12 @@ void
mem_writew_phys(uint32_t addr, uint16_t val)
{
mem_mapping_t *map = write_mapping[addr >> MEM_GRANULARITY_BITS];
+ uint16_t *p;
- if (_mem_exec[addr >> MEM_GRANULARITY_BITS])
- ((uint16_t *) _mem_exec[addr >> MEM_GRANULARITY_BITS])[(addr >> 1) & MEM_GRANULARITY_HMASK] = val;
- else if (map && map->write_w)
+ if ((addr <= MEM_GRANULARITY_HBOUND) && (_mem_exec[addr >> MEM_GRANULARITY_BITS])) {
+ p = (uint16_t *) &(_mem_exec[addr >> MEM_GRANULARITY_BITS][addr & MEM_GRANULARITY_MASK]);
+ *p = val;
+ } else if ((addr <= MEM_GRANULARITY_HBOUND) && (map && map->write_w))
map->write_w(addr, val, map->p);
else {
mem_writeb_phys(addr, val & 0xff);
@@ -1253,10 +1257,12 @@ void
mem_writel_phys(uint32_t addr, uint32_t val)
{
mem_mapping_t *map = write_mapping[addr >> MEM_GRANULARITY_BITS];
+ uint32_t *p;
- if (_mem_exec[addr >> MEM_GRANULARITY_BITS])
- ((uint32_t *) _mem_exec[addr >> MEM_GRANULARITY_BITS])[(addr >> 1) & MEM_GRANULARITY_QMASK] = val;
- else if (map && map->write_l)
+ if ((addr <= MEM_GRANULARITY_QBOUND) && (_mem_exec[addr >> MEM_GRANULARITY_BITS])) {
+ p = (uint32_t *) &(_mem_exec[addr >> MEM_GRANULARITY_BITS][addr & MEM_GRANULARITY_MASK]);
+ *p = val;
+ } else if ((addr <= MEM_GRANULARITY_QBOUND) && (map && map->read_l))
map->write_l(addr, val, map->p);
else {
mem_writew_phys(addr, val & 0xffff);
@@ -1268,6 +1274,11 @@ mem_writel_phys(uint32_t addr, uint32_t val)
uint8_t
mem_read_ram(uint32_t addr, void *priv)
{
+#ifdef ENABLE_MEM_LOG
+ if ((addr >= 0xa0000) && (addr <= 0xbffff))
+ mem_log("Read B %02X from %08X\n", ram[addr], addr);
+#endif
+
addreadlookup(mem_logical_addr, addr);
return ram[addr];
@@ -1277,6 +1288,11 @@ mem_read_ram(uint32_t addr, void *priv)
uint16_t
mem_read_ramw(uint32_t addr, void *priv)
{
+#ifdef ENABLE_MEM_LOG
+ if ((addr >= 0xa0000) && (addr <= 0xbffff))
+ mem_log("Read W %04X from %08X\n", *(uint16_t *)&ram[addr], addr);
+#endif
+
addreadlookup(mem_logical_addr, addr);
return *(uint16_t *)&ram[addr];
@@ -1286,6 +1302,11 @@ mem_read_ramw(uint32_t addr, void *priv)
uint32_t
mem_read_raml(uint32_t addr, void *priv)
{
+#ifdef ENABLE_MEM_LOG
+ if ((addr >= 0xa0000) && (addr <= 0xbffff))
+ mem_log("Read L %08X from %08X\n", *(uint32_t *)&ram[addr], addr);
+#endif
+
addreadlookup(mem_logical_addr, addr);
return *(uint32_t *)&ram[addr];
@@ -1453,6 +1474,10 @@ mem_write_raml_page(uint32_t addr, uint32_t val, page_t *p)
void
mem_write_ram(uint32_t addr, uint8_t val, void *priv)
{
+#ifdef ENABLE_MEM_LOG
+ if ((addr >= 0xa0000) && (addr <= 0xbffff))
+ mem_log("Write B %02X to %08X\n", val, addr);
+#endif
addwritelookup(mem_logical_addr, addr);
mem_write_ramb_page(addr, val, &pages[addr >> 12]);
}
@@ -1461,6 +1486,10 @@ mem_write_ram(uint32_t addr, uint8_t val, void *priv)
void
mem_write_ramw(uint32_t addr, uint16_t val, void *priv)
{
+#ifdef ENABLE_MEM_LOG
+ if ((addr >= 0xa0000) && (addr <= 0xbffff))
+ mem_log("Write W %04X to %08X\n", val, addr);
+#endif
addwritelookup(mem_logical_addr, addr);
mem_write_ramw_page(addr, val, &pages[addr >> 12]);
}
@@ -1469,6 +1498,10 @@ mem_write_ramw(uint32_t addr, uint16_t val, void *priv)
void
mem_write_raml(uint32_t addr, uint32_t val, void *priv)
{
+#ifdef ENABLE_MEM_LOG
+ if ((addr >= 0xa0000) && (addr <= 0xbffff))
+ mem_log("Write L %08X to %08X\n", val, addr);
+#endif
addwritelookup(mem_logical_addr, addr);
mem_write_raml_page(addr, val, &pages[addr >> 12]);
}
@@ -1477,7 +1510,7 @@ mem_write_raml(uint32_t addr, uint32_t val, void *priv)
static uint8_t
mem_read_remapped(uint32_t addr, void *priv)
{
- if(addr >= (mem_size * 1024) && addr < ((mem_size + 384) * 1024))
+ if ((addr >= (mem_size * 1024)) && (addr < ((mem_size + 384) * 1024)))
addr = 0xA0000 + (addr - (mem_size * 1024));
addreadlookup(mem_logical_addr, addr);
return ram[addr];
@@ -1487,7 +1520,7 @@ mem_read_remapped(uint32_t addr, void *priv)
static uint16_t
mem_read_remappedw(uint32_t addr, void *priv)
{
- if(addr >= mem_size * 1024 && addr < ((mem_size + 384) * 1024))
+ if ((addr >= (mem_size * 1024)) && (addr < ((mem_size + 384) * 1024)))
addr = 0xA0000 + (addr - (mem_size * 1024));
addreadlookup(mem_logical_addr, addr);
return *(uint16_t *)&ram[addr];
@@ -1497,7 +1530,7 @@ mem_read_remappedw(uint32_t addr, void *priv)
static uint32_t
mem_read_remappedl(uint32_t addr, void *priv)
{
- if(addr >= mem_size * 1024 && addr < ((mem_size + 384) * 1024))
+ if ((addr >= (mem_size * 1024)) && (addr < ((mem_size + 384) * 1024)))
addr = 0xA0000 + (addr - (mem_size * 1024));
addreadlookup(mem_logical_addr, addr);
return *(uint32_t *)&ram[addr];
@@ -1508,7 +1541,7 @@ static void
mem_write_remapped(uint32_t addr, uint8_t val, void *priv)
{
uint32_t oldaddr = addr;
- if(addr >= mem_size * 1024 && addr < ((mem_size + 384) * 1024))
+ if ((addr >= (mem_size * 1024)) && (addr < ((mem_size + 384) * 1024)))
addr = 0xA0000 + (addr - (mem_size * 1024));
addwritelookup(mem_logical_addr, addr);
mem_write_ramb_page(addr, val, &pages[oldaddr >> 12]);
@@ -1519,7 +1552,7 @@ static void
mem_write_remappedw(uint32_t addr, uint16_t val, void *priv)
{
uint32_t oldaddr = addr;
- if(addr >= mem_size * 1024 && addr < ((mem_size + 384) * 1024))
+ if ((addr >= (mem_size * 1024)) && (addr < ((mem_size + 384) * 1024)))
addr = 0xA0000 + (addr - (mem_size * 1024));
addwritelookup(mem_logical_addr, addr);
mem_write_ramw_page(addr, val, &pages[oldaddr >> 12]);
@@ -1530,7 +1563,7 @@ static void
mem_write_remappedl(uint32_t addr, uint32_t val, void *priv)
{
uint32_t oldaddr = addr;
- if(addr >= mem_size * 1024 && addr < ((mem_size + 384) * 1024))
+ if ((addr >= (mem_size * 1024)) && (addr < ((mem_size + 384) * 1024)))
addr = 0xA0000 + (addr - (mem_size * 1024));
addwritelookup(mem_logical_addr, addr);
mem_write_raml_page(addr, val, &pages[oldaddr >> 12]);
@@ -1638,8 +1671,13 @@ mem_invalidate_range(uint32_t start_addr, uint32_t end_addr)
static __inline int
-mem_mapping_read_allowed(uint32_t flags, int state)
+mem_mapping_read_allowed(uint32_t flags, int state, int exec)
{
+ int smm_state = state >> MEM_STATE_SMM_SHIFT;
+
+ if (in_smm && ((smm_state & MEM_READ_MASK) != MEM_READ_NORMAL))
+ state = smm_state;
+
switch (state & MEM_READ_MASK) {
case MEM_READ_DISABLED:
return 0;
@@ -1659,6 +1697,12 @@ mem_mapping_read_allowed(uint32_t flags, int state)
case MEM_READ_EXTANY:
return !(flags & MEM_MAPPING_INTERNAL);
+ case MEM_READ_EXTERNAL_EX:
+ if (exec)
+ return !(flags & MEM_MAPPING_EXTERNAL);
+ else
+ return !(flags & MEM_MAPPING_INTERNAL);
+
case MEM_READ_INTERNAL:
return !(flags & MEM_MAPPING_EXTERNAL);
@@ -1673,6 +1717,11 @@ mem_mapping_read_allowed(uint32_t flags, int state)
static __inline int
mem_mapping_write_allowed(uint32_t flags, int state)
{
+ int smm_state = state >> MEM_STATE_SMM_SHIFT;
+
+ if (in_smm && ((smm_state & MEM_WRITE_MASK) != MEM_WRITE_NORMAL))
+ state = smm_state;
+
switch (state & MEM_WRITE_MASK) {
case MEM_WRITE_DISABLED:
return 0;
@@ -1703,7 +1752,7 @@ mem_mapping_write_allowed(uint32_t flags, int state)
}
-static void
+void
mem_mapping_recalc(uint64_t base, uint64_t size)
{
mem_mapping_t *map = base_mapping.next;
@@ -1729,16 +1778,29 @@ mem_mapping_recalc(uint64_t base, uint64_t size)
for (c = start; c < end; c += MEM_GRANULARITY_SIZE) {
if ((map->read_b || map->read_w || map->read_l) &&
- mem_mapping_read_allowed(map->flags, _mem_state[c >> MEM_GRANULARITY_BITS])) {
+ mem_mapping_read_allowed(map->flags, _mem_state[c >> MEM_GRANULARITY_BITS], 0)) {
+#ifdef ENABLE_MEM_LOG
+ if ((start >= 0xa0000) && (start <= 0xbffff))
+ mem_log("Read allowed: %08X (mapping for %08X)\n", map, start);
+#endif
read_mapping[c >> MEM_GRANULARITY_BITS] = map;
- if (map->exec)
- _mem_exec[c >> MEM_GRANULARITY_BITS] = map->exec + (c - map->base);
- else
- _mem_exec[c >> MEM_GRANULARITY_BITS] = NULL;
+ }
+ if (map->exec &&
+ mem_mapping_read_allowed(map->flags, _mem_state[c >> MEM_GRANULARITY_BITS], 1)) {
+#ifdef ENABLE_MEM_LOG
+ if ((start >= 0xa0000) && (start <= 0xbffff))
+ mem_log("Exec allowed: %08X (mapping for %08X)\n", map, start);
+#endif
+ _mem_exec[c >> MEM_GRANULARITY_BITS] = map->exec + (c - map->base);
}
if ((map->write_b || map->write_w || map->write_l) &&
- mem_mapping_write_allowed(map->flags, _mem_state[c >> MEM_GRANULARITY_BITS]))
+ mem_mapping_write_allowed(map->flags, _mem_state[c >> MEM_GRANULARITY_BITS])) {
+#ifdef ENABLE_MEM_LOG
+ if ((start >= 0xa0000) && (start <= 0xbffff))
+ mem_log("Write allowed: %08X (mapping for %08X)\n", map, start);
+#endif
write_mapping[c >> MEM_GRANULARITY_BITS] = map;
+ }
}
}
map = map->next;
@@ -1810,6 +1872,13 @@ mem_mapping_add(mem_mapping_t *map,
}
+void
+mem_mapping_do_recalc(mem_mapping_t *map)
+{
+ mem_mapping_recalc(map->base, map->size);
+}
+
+
void
mem_mapping_set_handler(mem_mapping_t *map,
uint8_t (*read_b)(uint32_t addr, void *p),
@@ -1888,15 +1957,19 @@ mem_mapping_enable(mem_mapping_t *map)
void
-mem_set_mem_state(uint32_t base, uint32_t size, int state)
+mem_set_mem_state_common(int smm, uint32_t base, uint32_t size, int state)
{
uint32_t c;
for (c = 0; c < size; c += MEM_GRANULARITY_SIZE) {
- _mem_state_bak[(c + base) >> MEM_GRANULARITY_BITS] = _mem_state[(c + base) >> MEM_GRANULARITY_BITS];
- _mem_state[(c + base) >> MEM_GRANULARITY_BITS] = state;
- // if (((c + base) >= 0xa0000) && ((c + base) <= 0xbffff))
- // pclog("Set mem state for block at %08X to %02X\n", c + base, state);
+ if (smm)
+ _mem_state[(c + base) >> MEM_GRANULARITY_BITS] = (_mem_state[(c + base) >> MEM_GRANULARITY_BITS] & 0x00ff) | ((state & 0xff) << 8);
+ else
+ _mem_state[(c + base) >> MEM_GRANULARITY_BITS] = (_mem_state[(c + base) >> MEM_GRANULARITY_BITS] & 0xff00) | (state & 0xff);
+#ifdef ENABLE_MEM_LOG
+ if (((c + base) >= 0xa0000) && ((c + base) <= 0xbffff))
+ mem_log("Set mem state for block at %08X to %02X\n", c + base, state);
+#endif
}
mem_mapping_recalc(base, size);
@@ -1904,17 +1977,16 @@ mem_set_mem_state(uint32_t base, uint32_t size, int state)
void
-mem_restore_mem_state(uint32_t base, uint32_t size)
+mem_set_mem_state(uint32_t base, uint32_t size, int state)
{
- uint32_t c;
+ mem_set_mem_state_common(0, base, size, state);
+}
- for (c = 0; c < size; c += MEM_GRANULARITY_SIZE) {
- _mem_state[(c + base) >> MEM_GRANULARITY_BITS] = _mem_state_bak[(c + base) >> MEM_GRANULARITY_BITS];
- // if (((c + base) >= 0xa0000) && ((c + base) <= 0xbffff))
- // pclog("Reset mem state for block at %08X\n", c + base);
- }
- mem_mapping_recalc(base, size);
+void
+mem_set_mem_state_smm(uint32_t base, uint32_t size, int state)
+{
+ mem_set_mem_state_common(1, base, size, state);
}
@@ -2082,11 +2154,15 @@ mem_log("MEM: reset: new pages=%08lx, pages_sz=%i\n", pages, pages_sz);
memset(&base_mapping, 0x00, sizeof(base_mapping));
memset(_mem_state, 0x00, sizeof(_mem_state));
- memset(_mem_state_bak, 0x00, sizeof(_mem_state_bak));
+ /* Set SMM states to (MEM_READ_NORMAL | MEM_WRITE_NORMAL). */
+ for (c = 0; c < MEM_MAPPINGS_NO; c++)
+ _mem_state[c] |= 0x4400;
mem_set_mem_state(0x000000, (mem_size > 640) ? 0xa0000 : mem_size * 1024,
MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
- mem_set_mem_state(0x0c0000, 0x40000,
+ /* mem_set_mem_state(0x0c0000, 0x40000,
+ MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); */
+ mem_set_mem_state(0x0a0000, 0x60000,
MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
mem_mapping_add(&ram_low_mapping, 0x00000,
@@ -2115,12 +2191,17 @@ mem_log("MEM: reset: new pages=%08lx, pages_sz=%i\n", pages, pages_sz);
}
}
- if (mem_size > 768)
+ /* if (mem_size > 768)
mem_mapping_add(&ram_mid_mapping, 0xc0000, 0x40000,
mem_read_ram,mem_read_ramw,mem_read_raml,
mem_write_ram,mem_write_ramw,mem_write_raml,
- ram + 0xc0000, MEM_MAPPING_INTERNAL, NULL);
-
+ ram + 0xc0000, MEM_MAPPING_INTERNAL, NULL); */
+ if (mem_size > 768)
+ mem_mapping_add(&ram_mid_mapping, 0xa0000, 0x60000,
+ mem_read_ram,mem_read_ramw,mem_read_raml,
+ mem_write_ram,mem_write_ramw,mem_write_raml,
+ ram + 0xa0000, MEM_MAPPING_INTERNAL, NULL);
+
mem_mapping_add(&ram_remapped_mapping, mem_size * 1024, 256 * 1024,
mem_read_remapped,mem_read_remappedw,mem_read_remappedl,
mem_write_remapped,mem_write_remappedw,mem_write_remappedl,
diff --git a/src/sio_detect.c b/src/sio_detect.c
index 67723a709..e322ae544 100644
--- a/src/sio_detect.c
+++ b/src/sio_detect.c
@@ -84,12 +84,18 @@ sio_detect_init(const device_t *info)
sio_detect_read, NULL, NULL, sio_detect_write, NULL, NULL, dev);
io_sethandler(0x0108, 0x0002,
sio_detect_read, NULL, NULL, sio_detect_write, NULL, NULL, dev);
- io_sethandler(0x0250, 0x0002,
+ io_sethandler(0x0250, 0x0003,
+ sio_detect_read, NULL, NULL, sio_detect_write, NULL, NULL, dev);
+ io_sethandler(0x0279, 0x0001,
sio_detect_read, NULL, NULL, sio_detect_write, NULL, NULL, dev);
io_sethandler(0x0370, 0x0002,
sio_detect_read, NULL, NULL, sio_detect_write, NULL, NULL, dev);
+ io_sethandler(0x03e3, 0x0001,
+ sio_detect_read, NULL, NULL, sio_detect_write, NULL, NULL, dev);
io_sethandler(0x03f0, 0x0002,
sio_detect_read, NULL, NULL, sio_detect_write, NULL, NULL, dev);
+ io_sethandler(0x0a79, 0x0001,
+ sio_detect_read, NULL, NULL, sio_detect_write, NULL, NULL, dev);
return dev;
}
diff --git a/src/sio_fdc37c67x.c b/src/sio_fdc37c67x.c
deleted file mode 100644
index 6d7c3d44e..000000000
--- a/src/sio_fdc37c67x.c
+++ /dev/null
@@ -1,519 +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.
- *
- * Emulation of the Winbond W83977F Super I/O Chip.
- *
- * Winbond W83977F Super I/O Chip
- * Used by the Award 430TX
- *
- *
- *
- * Author: Miran Grca,
- * Copyright 2016-2020 Miran Grca.
- */
-#include
-#include
-#include
-#include
-#include
-#include <86box/86box.h>
-#include <86box/device.h>
-#include <86box/io.h>
-#include <86box/timer.h>
-#include <86box/pci.h>
-#include <86box/mem.h>
-#include <86box/rom.h>
-#include <86box/lpt.h>
-#include <86box/serial.h>
-#include <86box/fdd.h>
-#include <86box/fdc.h>
-#include <86box/sio.h>
-
-
-#define HEFRAS (dev->regs[0x26] & 0x40)
-
-
-typedef struct {
- uint8_t tries, regs[48],
- dev_regs[256][208];
- int locked, rw_locked,
- cur_reg, base_address,
- type;
- fdc_t *fdc;
- serial_t *uart[2];
-} w83977f_t;
-
-
-static void w83977f_write(uint16_t port, uint8_t val, void *priv);
-static uint8_t w83977f_read(uint16_t port, void *priv);
-
-
-static void
-w83977f_remap(w83977f_t *dev)
-{
- io_removehandler(0x3f0, 0x0002,
- w83977f_read, NULL, NULL, w83977f_write, NULL, NULL, dev);
- io_removehandler(0x370, 0x0002,
- w83977f_read, NULL, NULL, w83977f_write, NULL, NULL, dev);
-
- dev->base_address = (HEFRAS ? 0x370 : 0x3f0);
-
- io_sethandler(dev->base_address, 0x0002,
- w83977f_read, NULL, NULL, w83977f_write, NULL, NULL, dev);
-}
-
-
-static uint8_t
-get_lpt_length(w83977f_t *dev)
-{
- uint8_t length = 4;
-
- if (((dev->dev_regs[1][0xc0] & 0x07) != 0x00) && ((dev->dev_regs[1][0xc0] & 0x07) != 0x02) &&
- ((dev->dev_regs[1][0xc0] & 0x07) != 0x04))
- length = 8;
-
- return length;
-}
-
-
-static void
-w83977f_fdc_handler(w83977f_t *dev)
-{
- uint16_t io_base = (dev->dev_regs[0][0x30] << 8) | dev->dev_regs[0][0x31];
-
- fdc_remove(dev->fdc);
-
- pclog("fdc: %02X %02X %04X\n", dev->dev_regs[0][0x00], dev->regs[0x22], io_base);
- if ((dev->dev_regs[0][0x00] & 0x01) && (dev->regs[0x22] & 0x01) && (io_base >= 0x100) && (io_base <= 0xff8))
- fdc_set_base(dev->fdc, io_base);
-
- fdc_set_irq(dev->fdc, dev->dev_regs[0][0x40] & 0x0f);
-}
-
-
-static void
-w83977f_lpt_handler(w83977f_t *dev)
-{
- uint16_t io_mask, io_base = (dev->dev_regs[1][0x30] << 8) | dev->dev_regs[1][0x31];
- int io_len = get_lpt_length(dev);
- io_base &= (0xfff & ~io_len);
- io_mask = 0xffc;
- if (io_len == 8)
- io_mask = 0xff8;
-
- lpt1_remove();
-
- if ((dev->dev_regs[1][0x00] & 0x01) && (dev->regs[0x22] & 0x08) && (io_base >= 0x100) && (io_base <= io_mask))
- lpt1_init(io_base);
-
- lpt1_irq(dev->dev_regs[1][0x40] & 0x0f);
-}
-
-
-static void
-w83977f_serial_handler(w83977f_t *dev, int uart)
-{
- uint16_t io_base = (dev->dev_regs[2 + uart][0x30] << 8) | dev->dev_regs[2 + uart][0x31];
- double clock_src = 24000000.0 / 13.0;
-
- serial_remove(dev->uart[uart]);
-
- if ((dev->dev_regs[2 + uart][0x00] & 0x01) && (dev->regs[0x22] & (0x10 << uart)) && (io_base >= 0x100) && (io_base <= 0xff8))
- serial_setup(dev->uart[uart], io_base, dev->dev_regs[2 + uart][0x40] & 0x0f);
-
- switch (dev->dev_regs[2 + uart][0xc0] & 0x03) {
- case 0x00:
- clock_src = 24000000.0 / 13.0;
- break;
- case 0x01:
- clock_src = 24000000.0 / 12.0;
- break;
- case 0x02:
- clock_src = 24000000.0 / 1.0;
- break;
- case 0x03:
- clock_src = 24000000.0 / 1.625;
- break;
- }
-
- serial_set_clock_src(dev->uart[uart], clock_src);
-}
-
-
-static void
-w83977f_write(uint16_t port, uint8_t val, void *priv)
-{
- w83977f_t *dev = (w83977f_t *) priv;
- uint8_t index = (port & 1) ? 0 : 1;
- uint8_t valxor = 0;
- uint8_t ld = dev->regs[7];
-
- // pclog("W83977F Write: %04X %02X\n", port, val);
-
- if (index) {
- if ((val == 0x87) && !dev->locked) {
- if (dev->tries) {
- dev->locked = 1;
- dev->tries = 0;
- } else
- dev->tries++;
- } else {
- if (dev->locked) {
- if (val == 0xaa)
- dev->locked = 0;
- else
- dev->cur_reg = val;
- } else {
- if (dev->tries)
- dev->tries = 0;
- }
- }
- return;
- } else {
- if (dev->locked) {
- if (dev->rw_locked)
- return;
- if (dev->cur_reg >= 0x30) {
- valxor = val ^ dev->dev_regs[ld][dev->cur_reg - 0x30];
- dev->dev_regs[ld][dev->cur_reg - 0x30] = val;
- } else {
- valxor = val ^ dev->regs[dev->cur_reg];
- dev->regs[dev->cur_reg] = val;
- }
- } else
- return;
- }
-
- switch (dev->cur_reg) {
- case 0x02:
- if (valxor & 0x02)
- softresetx86();
- break;
- case 0x22:
- if (valxor & 0x20)
- w83977f_serial_handler(dev, 1);
- if (valxor & 0x10)
- w83977f_serial_handler(dev, 0);
- if (valxor & 0x08)
- w83977f_lpt_handler(dev);
- if (valxor & 0x01)
- w83977f_fdc_handler(dev);
- break;
- case 0x26:
- if (valxor & 0x20)
- dev->rw_locked = (val & 0x20) ? 1 : 0;
- case 0x30:
- if (valxor & 0x01) switch (ld) {
- case 0x00:
- w83977f_fdc_handler(dev);
- break;
- case 0x01:
- w83977f_lpt_handler(dev);
- break;
- case 0x02: case 0x03:
- w83977f_serial_handler(dev, ld - 2);
- break;
- }
- break;
- case 0x60: case 0x61:
- if (valxor & 0xff) switch (ld) {
- case 0x00:
- w83977f_fdc_handler(dev);
- break;
- case 0x01:
- w83977f_lpt_handler(dev);
- break;
- case 0x02: case 0x03:
- w83977f_serial_handler(dev, ld - 2);
- break;
- }
- break;
- case 0x70:
- if (valxor & 0x0f) switch (ld) {
- case 0x00:
- w83977f_fdc_handler(dev);
- break;
- case 0x01:
- w83977f_lpt_handler(dev);
- break;
- case 0x02: case 0x03:
- w83977f_serial_handler(dev, ld - 2);
- break;
- }
- break;
- case 0xf0:
- switch (ld) {
- case 0x00:
- if (valxor & 0x20)
- fdc_update_drv2en(dev->fdc, (val & 0x20) ? 0 : 1);
- if (valxor & 0x10)
- fdc_set_swap(dev->fdc, (val & 0x10) ? 1 : 0);
- if (valxor & 0x01)
- fdc_update_enh_mode(dev->fdc, (val & 0x01) ? 1 : 0);
- break;
- case 0x01:
- if (valxor & 0x07)
- w83977f_lpt_handler(dev);
- break;
- case 0x02: case 0x03:
- if (valxor & 0x03)
- w83977f_serial_handler(dev, ld - 2);
- break;
- }
- break;
- case 0xf1:
- switch (ld) {
- case 0x00:
- if (valxor & 0xc0)
- fdc_update_boot_drive(dev->fdc, (val & 0xc0) >> 6);
- if (valxor & 0x0c)
- fdc_update_densel_force(dev->fdc, (val & 0x0c) >> 2);
- if (valxor & 0x02)
- fdc_set_diswr(dev->fdc, (val & 0x02) ? 1 : 0);
- if (valxor & 0x01)
- fdc_set_swwp(dev->fdc, (val & 0x01) ? 1 : 0);
- break;
- }
- break;
- case 0xf2:
- switch (ld) {
- case 0x00:
- if (valxor & 0xc0)
- fdc_update_rwc(dev->fdc, 3, (val & 0xc0) >> 6);
- if (valxor & 0x30)
- fdc_update_rwc(dev->fdc, 2, (val & 0x30) >> 4);
- if (valxor & 0x0c)
- fdc_update_rwc(dev->fdc, 1, (val & 0x0c) >> 2);
- if (valxor & 0x03)
- fdc_update_rwc(dev->fdc, 0, val & 0x03);
- break;
- }
- break;
- case 0xf4: case 0xf5: case 0xf6: case 0xf7:
- switch (ld) {
- case 0x00:
- if (valxor & 0x18)
- fdc_update_drvrate(dev->fdc, dev->cur_reg & 0x03, (val & 0x18) >> 3);
- break;
- }
- break;
- }
-}
-
-
-static uint8_t
-w83977f_read(uint16_t port, void *priv)
-{
- w83977f_t *dev = (w83977f_t *) priv;
- uint8_t ret = 0xff;
- uint8_t index = (port & 1) ? 0 : 1;
- uint8_t ld = dev->regs[7];
-
- if (dev->locked) {
- if (index)
- ret = dev->cur_reg;
- else {
- if (!dev->rw_locked) {
- if ((dev->cur_reg == 0xf2) && (ld == 0x00))
- ret = (fdc_get_rwc(dev->fdc, 0) | (fdc_get_rwc(dev->fdc, 1) << 2) | (fdc_get_rwc(dev->fdc, 2) << 4) | (fdc_get_rwc(dev->fdc, 3) << 6));
- else if (dev->cur_reg >= 0x30)
- ret = dev->dev_regs[ld][dev->cur_reg - 0x30];
- else
- ret = dev->regs[dev->cur_reg];
- }
- }
- }
-
- // pclog("W83977F Read: %04X %02X\n", port, ret);
-
- return ret;
-}
-
-
-static void
-w83977f_reset(w83977f_t *dev)
-{
- int i;
-
- memset(dev->regs, 0, 48);
- for (i = 0; i < 256; i++)
- memset(dev->dev_regs[i], 0, 208);
-
- dev->regs[0x20] = 0x97;
- dev->regs[0x21] = dev->type ? 0x73 : 0x71;
- dev->regs[0x22] = 0xff;
- dev->regs[0x24] = dev->type ? 0x84 : 0xa4;
-
- /* WARNING: Array elements are register - 0x30. */
- /* Logical Device 0 (FDC) */
- dev->dev_regs[0][0x00] = 0x01;
- if (!dev->type)
- dev->dev_regs[0][0x01] = 0x02;
- dev->dev_regs[0][0x30] = 0x03; dev->dev_regs[0][0x31] = 0xf0;
- dev->dev_regs[0][0x40] = 0x06;
- if (!dev->type)
- dev->dev_regs[0][0x41] = 0x02; /* Read-only */
- dev->dev_regs[0][0x44] = 0x02;
- dev->dev_regs[0][0xc0] = 0x0e;
-
- /* Logical Device 1 (Parallel Port) */
- dev->dev_regs[1][0x00] = 0x01;
- if (!dev->type)
- dev->dev_regs[1][0x01] = 0x02;
- dev->dev_regs[1][0x30] = 0x03; dev->dev_regs[1][0x31] = 0x78;
- dev->dev_regs[1][0x40] = 0x07;
- if (!dev->type)
- dev->dev_regs[1][0x41] = 0x02; /* Read-only */
- dev->dev_regs[1][0x44] = 0x04;
- dev->dev_regs[1][0xc0] = 0x3c; /* The datasheet says default is 3f, but also default is priner mode. */
-
- /* Logical Device 2 (UART A) */
- dev->dev_regs[2][0x00] = 0x01;
- if (!dev->type)
- dev->dev_regs[2][0x01] = 0x02;
- dev->dev_regs[2][0x30] = 0x03; dev->dev_regs[2][0x31] = 0xf8;
- dev->dev_regs[2][0x40] = 0x04;
- if (!dev->type)
- dev->dev_regs[2][0x41] = 0x02; /* Read-only */
-
- /* Logical Device 3 (UART B) */
- dev->dev_regs[3][0x00] = 0x01;
- if (!dev->type)
- dev->dev_regs[3][0x01] = 0x02;
- dev->dev_regs[3][0x30] = 0x02; dev->dev_regs[3][0x31] = 0xf8;
- dev->dev_regs[3][0x40] = 0x03;
- if (!dev->type)
- dev->dev_regs[3][0x41] = 0x02; /* Read-only */
-
- /* Logical Device 4 (RTC) */
- if (!dev->type) {
- dev->dev_regs[4][0x00] = 0x01;
- dev->dev_regs[4][0x01] = 0x02;
- dev->dev_regs[4][0x30] = 0x00; dev->dev_regs[4][0x31] = 0x70;
- dev->dev_regs[4][0x40] = 0x08;
- dev->dev_regs[4][0x41] = 0x02; /* Read-only */
- }
-
- /* Logical Device 5 (KBC) */
- dev->dev_regs[5][0x00] = 0x01;
- if (!dev->type)
- dev->dev_regs[5][0x01] = 0x02;
- dev->dev_regs[5][0x30] = 0x00; dev->dev_regs[5][0x31] = 0x60;
- dev->dev_regs[5][0x40] = 0x01;
- if (!dev->type)
- dev->dev_regs[5][0x41] = 0x02; /* Read-only */
- dev->dev_regs[5][0x42] = 0x0c;
- if (!dev->type)
- dev->dev_regs[5][0x43] = 0x02; /* Read-only? */
- dev->dev_regs[5][0xc0] = dev->type ? 0x83 : 0x40;
-
- /* Logical Device 6 (IR) = UART C */
- if (!dev->type) {
- dev->dev_regs[6][0x01] = 0x02;
- dev->dev_regs[6][0x41] = 0x02; /* Read-only */
- dev->dev_regs[6][0x44] = 0x04;
- dev->dev_regs[6][0x45] = 0x04;
- }
-
- /* Logical Device 7 (Auxiliary I/O Part I) */
- if (!dev->type)
- dev->dev_regs[7][0x01] = 0x02;
- if (!dev->type)
- dev->dev_regs[7][0x41] = 0x02; /* Read-only */
- if (!dev->type)
- dev->dev_regs[7][0x43] = 0x02; /* Read-only? */
- dev->dev_regs[7][0xb0] = 0x01; dev->dev_regs[7][0xb1] = 0x01;
- dev->dev_regs[7][0xb2] = 0x01; dev->dev_regs[7][0xb3] = 0x01;
- dev->dev_regs[7][0xb4] = 0x01; dev->dev_regs[7][0xb5] = 0x01;
- dev->dev_regs[7][0xb6] = 0x01;
- if (dev->type)
- dev->dev_regs[7][0xb7] = 0x01;
-
- /* Logical Device 8 (Auxiliary I/O Part II) */
- if (!dev->type)
- dev->dev_regs[8][0x01] = 0x02;
- if (!dev->type)
- dev->dev_regs[8][0x41] = 0x02; /* Read-only */
- if (!dev->type)
- dev->dev_regs[8][0x43] = 0x02; /* Read-only? */
- dev->dev_regs[8][0xb8] = 0x01; dev->dev_regs[8][0xb9] = 0x01;
- dev->dev_regs[8][0xba] = 0x01; dev->dev_regs[8][0xbb] = 0x01;
- dev->dev_regs[8][0xbc] = 0x01; dev->dev_regs[8][0xbd] = 0x01;
- dev->dev_regs[8][0xbe] = 0x01; dev->dev_regs[8][0xbf] = 0x01;
-
- /* Logical Device 9 (Auxiliary I/O Part III) */
- if (dev->type) {
- dev->dev_regs[7][0xb0] = 0x01; dev->dev_regs[7][0xb1] = 0x01;
- dev->dev_regs[7][0xb2] = 0x01; dev->dev_regs[7][0xb3] = 0x01;
- dev->dev_regs[7][0xb4] = 0x01; dev->dev_regs[7][0xb5] = 0x01;
- dev->dev_regs[7][0xb6] = 0x01; dev->dev_regs[7][0xb7] = 0x01;
- }
-
- fdc_reset(dev->fdc);
-
- serial_setup(dev->uart[0], SERIAL1_ADDR, SERIAL1_IRQ);
- serial_setup(dev->uart[1], SERIAL2_ADDR, SERIAL2_IRQ);
-
- w83977f_fdc_handler(dev);
- w83977f_lpt_handler(dev);
- w83977f_serial_handler(dev, 0);
- w83977f_serial_handler(dev, 1);
-
- w83977f_remap(dev);
-
- dev->locked = 0;
- dev->rw_locked = 0;
-}
-
-
-static void
-w83977f_close(void *priv)
-{
- w83977f_t *dev = (w83977f_t *) priv;
-
- free(dev);
-}
-
-
-static void *
-w83977f_init(const device_t *info)
-{
- w83977f_t *dev = (w83977f_t *) malloc(sizeof(w83977f_t));
- memset(dev, 0, sizeof(w83977f_t));
-
- dev->type = info->local;
-
- dev->fdc = device_add(&fdc_at_smc_device);
-
- dev->uart[0] = device_add_inst(&ns16550_device, 1);
- dev->uart[1] = device_add_inst(&ns16550_device, 2);
-
- w83977f_reset(dev);
-
- return dev;
-}
-
-
-const device_t w83977f_device = {
- "Winbond W83977F Super I/O",
- 0,
- 0,
- w83977f_init, w83977f_close, NULL,
- NULL, NULL, NULL,
- NULL
-};
-
-
-const device_t w83977tf_device = {
- "Winbond W83977TF Super I/O",
- 0,
- 1,
- w83977f_init, w83977f_close, NULL,
- NULL, NULL, NULL,
- NULL
-};
diff --git a/src/sio_pc87306.c b/src/sio_pc87306.c
index 2a1305e62..5f3b625f8 100644
--- a/src/sio_pc87306.c
+++ b/src/sio_pc87306.c
@@ -283,14 +283,6 @@ pc87306_write(uint16_t port, uint8_t val, void *priv)
}
}
break;
- case 4:
- // pclog("NVR RAM mask set to %i\n", !!(val & 0x80));
- break;
- case 5:
- // pclog("Reserved set to %i\n", !!(val & 0x04));
- // pclog("RTC is now %sabled\n", (val & 0x08) ? "en" : "dis");
- // pclog("NVR RAM bank set to %i\n", !!(val & 0x20));
- break;
case 9:
if (valxor & 0x44) {
fdc_update_enh_mode(dev->fdc, (val & 4) ? 1 : 0);
@@ -302,7 +294,6 @@ pc87306_write(uint16_t port, uint8_t val, void *priv)
pc87306_gpio_init(dev);
break;
case 0x12:
- // pclog("NVR RAM 38-3F lock set to %i\n", !!(val & 0x01));
if (valxor & 0x30)
pc87306_gpio_init(dev);
break;
diff --git a/src/sio_w83787f.c b/src/sio_w83787f.c
index 0af124c55..bc1a4792c 100644
--- a/src/sio_w83787f.c
+++ b/src/sio_w83787f.c
@@ -197,7 +197,6 @@ w83787f_write(uint16_t port, uint8_t val, void *priv)
w83787f_t *dev = (w83787f_t *) priv;
uint8_t valxor = 0;
uint8_t max = 0x15;
- pclog("W83787F: Write %02X to %04X\n", val, port);
if (port == 0x250) {
if (val == dev->key)
@@ -312,8 +311,6 @@ w83787f_read(uint16_t port, void *priv)
}
}
- pclog("W83787F: Read %02X from %04X\n", ret, port);
-
return ret;
}
diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw
index 3602a3f8d..f608d1e1d 100644
--- a/src/win/Makefile.mingw
+++ b/src/win/Makefile.mingw
@@ -566,7 +566,7 @@ CPUOBJ := cpu.o cpu_table.o \
CHIPSETOBJ := acc2168.o acer_m3a.o cs8230.o ali1429.o headland.o \
intel_4x0.o neat.o opti495.o scamp.o scat.o \
sis_85c471.o sis_85c496.o \
- via_mvp3.o via_apro.o wd76c10.o
+ via_apollo.o wd76c10.o
MCHOBJ := machine.o machine_table.o \
m_xt.o m_xt_compaq.o \
@@ -585,7 +585,7 @@ MCHOBJ := machine.o machine_table.o \
m_at_socket8.o
DEVOBJ := bugger.o hwm.o hwm_w83781d.o ibm_5161.o isamem.o isartc.o lpt.o postcard.o $(SERIAL) \
- sio_acc3221.o \
+ sio_detect.o sio_acc3221.o \
sio_f82c710.o \
sio_fdc37c66x.o sio_fdc37c669.o \
sio_fdc37c93x.o \
diff --git a/src/win/Makefile_ndr.mingw b/src/win/Makefile_ndr.mingw
index dc8c7c000..62caac7cf 100644
--- a/src/win/Makefile_ndr.mingw
+++ b/src/win/Makefile_ndr.mingw
@@ -571,7 +571,7 @@ CPUOBJ := cpu.o cpu_table.o \
CHIPSETOBJ := acc2168.o acer_m3a.o cs8230.o ali1429.o headland.o \
intel_4x0.o neat.o opti495.o scamp.o scat.o \
sis_85c471.o sis_85c496.o \
- via_mvp3.o via_apro.o wd76c10.o
+ via_apollo.o wd76c10.o
MCHOBJ := machine.o machine_table.o \
m_xt.o m_xt_compaq.o \