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 \