From a4f16a799e41c6e58a71d933a4ee3d06db0ae79f Mon Sep 17 00:00:00 2001 From: nerd73 Date: Fri, 9 Apr 2021 20:24:47 -0600 Subject: [PATCH 01/25] Add the TMC PAT54PV An ISA/VLB Socket 5 machine. Also makes KBC command A0 return 0x28 then 0 so that the BIOS can function. --- src/device/keyboard_at.c | 5 +++++ src/include/86box/machine.h | 2 ++ src/machine/m_at_socket4_5.c | 20 ++++++++++++++++++++ src/machine/machine_table.c | 3 +++ 4 files changed, 30 insertions(+) diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index 143e80dc3..143b0bb60 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -1325,6 +1325,11 @@ write64_ami(void *priv, uint8_t val) dev->want60 = 1; return 0; + case 0xa0: /* copyright message */ + add_data(dev, 0x28); + add_data(dev, 0x00); + break; + case 0xa1: /* get controller version */ kbd_log("ATkbc: AMI - get controller version\n"); add_data(dev, 'H'); diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 2fe39b483..136663ff1 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -381,6 +381,8 @@ extern const device_t *at_cpqiii_get_device(void); /* m_at_socket4_5.c */ extern int machine_at_excalibur_init(const machine_t *); +extern int machine_at_pat54pv_init(const machine_t *); + extern int machine_at_hot543_init(const machine_t *); extern int machine_at_p54vl_init(const machine_t *); diff --git a/src/machine/m_at_socket4_5.c b/src/machine/m_at_socket4_5.c index ec40d220d..8a96770c9 100644 --- a/src/machine/m_at_socket4_5.c +++ b/src/machine/m_at_socket4_5.c @@ -62,7 +62,27 @@ machine_at_excalibur_init(const machine_t *model) return ret; } +int +machine_at_pat54pv_init(const machine_t *model) +{ + int ret; + ret = bios_load_linear("roms/machines/pat54pv/pat54pv.bin", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + device_add(&opti5x7_device); + device_add(&keyboard_at_ami_device); + + if (fdc_type == FDC_INTERNAL) + device_add(&fdc_at_device); + + return ret; +} int machine_at_hot543_init(const machine_t *model) { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index d293a23c7..a0222ccba 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -284,6 +284,9 @@ const machine_t machines[] = { { "[i430FX] NEC PowerMate V", "powermate_v", MACHINE_TYPE_SOCKET5, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3380, 3520, 1.5, 2.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 131072, 8192, 127, machine_at_powermate_v_init, NULL }, { "[i430FX] PC Partner MB500N", "mb500n", MACHINE_TYPE_SOCKET5, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3380, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_IDE_DUAL, 8192, 131072, 8192, 127, machine_at_mb500n_init, NULL }, + /* OPTi 596/597 */ + { "[OPTi 597] TMC PAT54PV", "pat54pv", MACHINE_TYPE_SOCKET5, CPU_PKG_SOCKET5_7, 0, 60000000, 66666667, 3520, 3520, 1.5, 1.5, MACHINE_VLB, 2048, 65536, 2048, 127, machine_at_pat54pv_init, NULL }, + /* OPTi 596/597/822 */ { "[OPTi 597] Shuttle HOT-543", "hot543", MACHINE_TYPE_SOCKET5, CPU_PKG_SOCKET5_7, 0, 60000000, 66666667, 3520, 3520, 1.5, 1.5, MACHINE_PCI | MACHINE_VLB, 8192, 131072, 8192, 127, machine_at_hot543_init, NULL }, { "[OPTi 597] Supermicro P54VL-PCI", "p54vl", MACHINE_TYPE_SOCKET5, CPU_PKG_SOCKET5_7, 0, 60000000, 66666667, 3520, 3520, 1.5, 1.5, MACHINE_PCI | MACHINE_VLB, 8192, 131072, 8192, 127, machine_at_p54vl_init, NULL }, From 84c4ae7e93c2591e36017fbf09607a8c58c10236 Mon Sep 17 00:00:00 2001 From: nerd73 Date: Fri, 9 Apr 2021 21:26:28 -0600 Subject: [PATCH 02/25] The PAT54PV bios blacklists AMD CPUs. --- src/machine/machine_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index a0222ccba..3b0667b6f 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -285,7 +285,7 @@ const machine_t machines[] = { { "[i430FX] PC Partner MB500N", "mb500n", MACHINE_TYPE_SOCKET5, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3380, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_IDE_DUAL, 8192, 131072, 8192, 127, machine_at_mb500n_init, NULL }, /* OPTi 596/597 */ - { "[OPTi 597] TMC PAT54PV", "pat54pv", MACHINE_TYPE_SOCKET5, CPU_PKG_SOCKET5_7, 0, 60000000, 66666667, 3520, 3520, 1.5, 1.5, MACHINE_VLB, 2048, 65536, 2048, 127, machine_at_pat54pv_init, NULL }, + { "[OPTi 597] TMC PAT54PV", "pat54pv", MACHINE_TYPE_SOCKET5, CPU_PKG_SOCKET5_7, CPU_BLOCK(CPU_K5, CPU_5K86), 60000000, 66666667, 3520, 3520, 1.5, 1.5, MACHINE_VLB, 2048, 65536, 2048, 127, machine_at_pat54pv_init, NULL }, /* OPTi 596/597/822 */ { "[OPTi 597] Shuttle HOT-543", "hot543", MACHINE_TYPE_SOCKET5, CPU_PKG_SOCKET5_7, 0, 60000000, 66666667, 3520, 3520, 1.5, 1.5, MACHINE_PCI | MACHINE_VLB, 8192, 131072, 8192, 127, machine_at_hot543_init, NULL }, From c370ae7e18b1004a85c6c4fc9cba3de0dabf554a Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 10 Apr 2021 07:18:47 +0200 Subject: [PATCH 03/25] CPU and MMU cleanups and fixes, and non-Debug builds are now stripped again. --- src/cpu/386.c | 10 +- src/cpu/386_common.c | 45 +- src/cpu/386_common.h | 43 +- src/cpu/386_dynarec.c | 8 +- src/cpu/386_dynarec_ops.c | 8 +- src/cpu/808x.c | 352 +-- src/cpu/CMakeLists.txt | 2 +- src/cpu/cpu.c | 6223 ++++++++++++++++--------------------- src/cpu/cpu.h | 110 +- src/cpu/x86_ops_amd.h | 4 +- src/cpu/x86_ops_arith.h | 102 +- src/cpu/x86_ops_call.h | 32 +- src/cpu/x86_ops_i686.h | 6 - src/cpu/x86_ops_misc.h | 27 +- src/cpu/x86_ops_mov.h | 8 +- src/cpu/x86_ops_rep.h | 144 +- src/cpu/x86_ops_stack.h | 37 +- src/cpu/x86_ops_string.h | 200 +- src/cpu/x86seg.c | 2 +- src/include/86box/mem.h | 21 +- src/mem/mem.c | 463 ++- src/win/Makefile.mingw | 8 +- 22 files changed, 3488 insertions(+), 4367 deletions(-) diff --git a/src/cpu/386.c b/src/cpu/386.c index 3a3e36d58..ea29d2570 100644 --- a/src/cpu/386.c +++ b/src/cpu/386.c @@ -134,9 +134,9 @@ static inline void fetch_ea_32_long(uint32_t rmdat) if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) { uint32_t addr = easeg + cpu_state.eaaddr; - if ( readlookup2[addr >> 12] != -1) + if ( readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); - if (writelookup2[addr >> 12] != -1) + if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); } } @@ -174,9 +174,9 @@ static inline void fetch_ea_16_long(uint32_t rmdat) if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) { uint32_t addr = easeg + cpu_state.eaaddr; - if ( readlookup2[addr >> 12] != -1) + if ( readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); - if (writelookup2[addr >> 12] != -1) + if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); } } @@ -271,7 +271,7 @@ exec386(int cycs) CS = oldcs; #endif cpu_state.pc = cpu_state.oldpc; - x386_log("Double fault %i\n", ins); + x386_log("Double fault\n"); pmodeint(8, 0); if (cpu_state.abrt) { cpu_state.abrt = 0; diff --git a/src/cpu/386_common.c b/src/cpu/386_common.c index 1800aad71..9324976af 100644 --- a/src/cpu/386_common.c +++ b/src/cpu/386_common.c @@ -65,10 +65,17 @@ uint32_t old_rammask = 0xffffffff; int soft_reset_mask = 0; +int in_smm = 0, smi_line = 0, smi_latched = 0, smm_in_hlt = 0; +int smi_block = 0; +uint32_t smbase = 0x30000; -#define AMD_SYSCALL_EIP (star & 0xFFFFFFFF) -#define AMD_SYSCALL_SB ((star >> 32) & 0xFFFF) -#define AMD_SYSRET_SB ((star >> 48) & 0xFFFF) +uint32_t addr64, addr64_2; +uint32_t addr64a[8], addr64a_2[8]; + + +#define AMD_SYSCALL_EIP (msr.star & 0xFFFFFFFF) +#define AMD_SYSCALL_SB ((msr.star >> 32) & 0xFFFF) +#define AMD_SYSRET_SB ((msr.star >> 48) & 0xFFFF) /* These #define's and enum have been borrowed from Bochs. */ @@ -1312,7 +1319,7 @@ x86_int(int num) else { addr = (num << 2) + idt.base; - if ((num << 2) + 3 > idt.limit) { + if ((num << 2UL) + 3UL > idt.limit) { if (idt.limit < 35) { cpu_state.abrt = 0; softresetx86(); @@ -1363,7 +1370,7 @@ x86_int_sw(int num) else { addr = (num << 2) + idt.base; - if ((num << 2) + 3 > idt.limit) + if ((num << 2UL) + 3UL > idt.limit) x86_int(0x0d); else { if (stack32) { @@ -1447,7 +1454,7 @@ x86illegal() int -checkio(int port) +checkio(uint32_t port) { uint16_t t; uint8_t d; @@ -1459,7 +1466,7 @@ checkio(int port) if (cpu_state.abrt) return 0; - if ((t + (port >> 3)) > tr.limit) + if ((t + (port >> 3UL)) > tr.limit) return 1; cpl_override = 1; @@ -1599,7 +1606,7 @@ sysenter(uint32_t fetchdat) return cpu_state.abrt; } - if (!(cs_msr & 0xFFF8)) { + if (!(msr.sysenter_cs & 0xFFF8)) { #ifdef ENABLE_386_COMMON_LOG x386_common_log("SYSENTER: CS MSR is zero"); #endif @@ -1611,7 +1618,7 @@ sysenter(uint32_t fetchdat) x386_common_log("SYSENTER started:\n"); x386_common_log(" CS %04X/%i: b=%08X l=%08X (%08X-%08X) a=%02X%02X; EIP=%08X\n", cpu_state.seg_cs.seg, !!cpu_state.seg_cs.checked, cpu_state.seg_cs.base, cpu_state.seg_cs.limit, cpu_state.seg_cs.limit_low, cpu_state.seg_cs.limit_high, cpu_state.seg_cs.ar_high, cpu_state.seg_cs.access, cpu_state.pc); x386_common_log(" SS %04X/%i: b=%08X l=%08X (%08X-%08X) a=%02X%02X; ESP=%08X\n", cpu_state.seg_ss.seg, !!cpu_state.seg_ss.checked, cpu_state.seg_ss.base, cpu_state.seg_ss.limit, cpu_state.seg_ss.limit_low, cpu_state.seg_ss.limit_high, cpu_state.seg_ss.ar_high, cpu_state.seg_ss.access, ESP); - x386_common_log(" Misc. : MSR (CS/ESP/EIP)=%04X/%08X/%08X pccache=%08X/%08X\n", cs_msr, esp_msr, eip_msr, pccache, pccache2); + x386_common_log(" Misc. : MSR (CS/ESP/EIP)=%04X/%08X/%08X pccache=%08X/%08X\n", msr.sysenter_cs, msr.sysenter_esp, msr.sysenter_eip, pccache, pccache2); x386_common_log(" EFLAGS=%04X%04X/%i 32=%i/%i ECX=%08X EDX=%08X abrt=%02X\n", cpu_state.eflags, cpu_state.flags, !!trap, !!use32, !!stack32, ECX, EDX, cpu_state.abrt); #endif @@ -1623,10 +1630,10 @@ sysenter(uint32_t fetchdat) oldcs = CS; #endif cpu_state.oldpc = cpu_state.pc; - ESP = esp_msr; - cpu_state.pc = eip_msr; + ESP = msr.sysenter_esp; + cpu_state.pc = msr.sysenter_eip; - cpu_state.seg_cs.seg = (cs_msr & 0xfffc); + cpu_state.seg_cs.seg = (msr.sysenter_cs & 0xfffc); cpu_state.seg_cs.base = 0; cpu_state.seg_cs.limit_low = 0; cpu_state.seg_cs.limit = 0xffffffff; @@ -1637,7 +1644,7 @@ sysenter(uint32_t fetchdat) cpu_state.seg_cs.checked = 1; oldcpl = 0; - cpu_state.seg_ss.seg = ((cs_msr + 8) & 0xfffc); + cpu_state.seg_ss.seg = ((msr.sysenter_cs + 8) & 0xfffc); cpu_state.seg_ss.base = 0; cpu_state.seg_ss.limit_low = 0; cpu_state.seg_ss.limit = 0xffffffff; @@ -1661,7 +1668,7 @@ sysenter(uint32_t fetchdat) x386_common_log("SYSENTER completed:\n"); x386_common_log(" CS %04X/%i: b=%08X l=%08X (%08X-%08X) a=%02X%02X; EIP=%08X\n", cpu_state.seg_cs.seg, !!cpu_state.seg_cs.checked, cpu_state.seg_cs.base, cpu_state.seg_cs.limit, cpu_state.seg_cs.limit_low, cpu_state.seg_cs.limit_high, cpu_state.seg_cs.ar_high, cpu_state.seg_cs.access, cpu_state.pc); x386_common_log(" SS %04X/%i: b=%08X l=%08X (%08X-%08X) a=%02X%02X; ESP=%08X\n", cpu_state.seg_ss.seg, !!cpu_state.seg_ss.checked, cpu_state.seg_ss.base, cpu_state.seg_ss.limit, cpu_state.seg_ss.limit_low, cpu_state.seg_ss.limit_high, cpu_state.seg_ss.ar_high, cpu_state.seg_ss.access, ESP); - x386_common_log(" Misc. : MSR (CS/ESP/EIP)=%04X/%08X/%08X pccache=%08X/%08X\n", cs_msr, esp_msr, eip_msr, pccache, pccache2); + x386_common_log(" Misc. : MSR (CS/ESP/EIP)=%04X/%08X/%08X pccache=%08X/%08X\n", msr.sysenter_cs, msr.sysenter_esp, msr.sysenter_eip, pccache, pccache2); x386_common_log(" EFLAGS=%04X%04X/%i 32=%i/%i ECX=%08X EDX=%08X abrt=%02X\n", cpu_state.eflags, cpu_state.flags, !!trap, !!use32, !!stack32, ECX, EDX, cpu_state.abrt); #endif @@ -1676,7 +1683,7 @@ sysexit(uint32_t fetchdat) x386_common_log("SYSEXIT called\n"); #endif - if (!(cs_msr & 0xFFF8)) { + if (!(msr.sysenter_cs & 0xFFF8)) { #ifdef ENABLE_386_COMMON_LOG x386_common_log("SYSEXIT: CS MSR is zero"); #endif @@ -1704,7 +1711,7 @@ sysexit(uint32_t fetchdat) x386_common_log("SYSEXIT start:\n"); x386_common_log(" CS %04X/%i: b=%08X l=%08X (%08X-%08X) a=%02X%02X; EIP=%08X\n", cpu_state.seg_cs.seg, !!cpu_state.seg_cs.checked, cpu_state.seg_cs.base, cpu_state.seg_cs.limit, cpu_state.seg_cs.limit_low, cpu_state.seg_cs.limit_high, cpu_state.seg_cs.ar_high, cpu_state.seg_cs.access, cpu_state.pc); x386_common_log(" SS %04X/%i: b=%08X l=%08X (%08X-%08X) a=%02X%02X; ESP=%08X\n", cpu_state.seg_ss.seg, !!cpu_state.seg_ss.checked, cpu_state.seg_ss.base, cpu_state.seg_ss.limit, cpu_state.seg_ss.limit_low, cpu_state.seg_ss.limit_high, cpu_state.seg_ss.ar_high, cpu_state.seg_ss.access, ESP); - x386_common_log(" Misc. : MSR (CS/ESP/EIP)=%04X/%08X/%08X pccache=%08X/%08X\n", cs_msr, esp_msr, eip_msr, pccache, pccache2); + x386_common_log(" Misc. : MSR (CS/ESP/EIP)=%04X/%08X/%08X pccache=%08X/%08X\n", msr.sysenter_cs, msr.sysenter_esp, msr.sysenter_eip, pccache, pccache2); x386_common_log(" EFLAGS=%04X%04X/%i 32=%i/%i ECX=%08X EDX=%08X abrt=%02X\n", cpu_state.eflags, cpu_state.flags, !!trap, !!use32, !!stack32, ECX, EDX, cpu_state.abrt); #endif @@ -1715,7 +1722,7 @@ sysexit(uint32_t fetchdat) ESP = ECX; cpu_state.pc = EDX; - cpu_state.seg_cs.seg = (((cs_msr + 16) & 0xfffc) | 3); + cpu_state.seg_cs.seg = (((msr.sysenter_cs + 16) & 0xfffc) | 3); cpu_state.seg_cs.base = 0; cpu_state.seg_cs.limit_low = 0; cpu_state.seg_cs.limit = 0xffffffff; @@ -1726,7 +1733,7 @@ sysexit(uint32_t fetchdat) cpu_state.seg_cs.checked = 1; oldcpl = 3; - cpu_state.seg_ss.seg = (((cs_msr + 24) & 0xfffc) | 3); + cpu_state.seg_ss.seg = (((msr.sysenter_cs + 24) & 0xfffc) | 3); cpu_state.seg_ss.base = 0; cpu_state.seg_ss.limit_low = 0; cpu_state.seg_ss.limit = 0xffffffff; @@ -1751,7 +1758,7 @@ sysexit(uint32_t fetchdat) x386_common_log("SYSEXIT completed:\n"); x386_common_log(" CS %04X/%i: b=%08X l=%08X (%08X-%08X) a=%02X%02X; EIP=%08X\n", cpu_state.seg_cs.seg, !!cpu_state.seg_cs.checked, cpu_state.seg_cs.base, cpu_state.seg_cs.limit, cpu_state.seg_cs.limit_low, cpu_state.seg_cs.limit_high, cpu_state.seg_cs.ar_high, cpu_state.seg_cs.access, cpu_state.pc); x386_common_log(" SS %04X/%i: b=%08X l=%08X (%08X-%08X) a=%02X%02X; ESP=%08X\n", cpu_state.seg_ss.seg, !!cpu_state.seg_ss.checked, cpu_state.seg_ss.base, cpu_state.seg_ss.limit, cpu_state.seg_ss.limit_low, cpu_state.seg_ss.limit_high, cpu_state.seg_ss.ar_high, cpu_state.seg_ss.access, ESP); - x386_common_log(" Misc. : MSR (CS/ESP/EIP)=%04X/%08X/%08X pccache=%08X/%08X\n", cs_msr, esp_msr, eip_msr, pccache, pccache2); + x386_common_log(" Misc. : MSR (CS/ESP/EIP)=%04X/%08X/%08X pccache=%08X/%08X\n", msr.sysenter_cs, msr.sysenter_esp, msr.sysenter_eip, pccache, pccache2); x386_common_log(" EFLAGS=%04X%04X/%i 32=%i/%i ECX=%08X EDX=%08X abrt=%02X\n", cpu_state.eflags, cpu_state.flags, !!trap, !!use32, !!stack32, ECX, EDX, cpu_state.abrt); #endif diff --git a/src/cpu/386_common.h b/src/cpu/386_common.h index 61f68b693..4d182d4c0 100644 --- a/src/cpu/386_common.h +++ b/src/cpu/386_common.h @@ -15,38 +15,37 @@ * Copyright 2008-2019 Sarah Walker. * Copyright 2016-2019 Miran Grca. */ - #ifndef _386_COMMON_H_ #define _386_COMMON_H_ #include -#define readmemb_n(s,a,b) ((readlookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF)?readmembl_no_mmut((s)+(a),b): *(uint8_t *)(readlookup2[(uint32_t)((s)+(a))>>12] + (uintptr_t)((s) + (a))) ) -#define readmemw_n(s,a,b) ((readlookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1))?readmemwl_no_mmut((s)+(a),b):*(uint16_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) -#define readmeml_n(s,a,b) ((readlookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3))?readmemll_no_mmut((s)+(a),b):*(uint32_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) -#define readmemb(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF)?readmembl((s)+(a)): *(uint8_t *)(readlookup2[(uint32_t)((s)+(a))>>12] + (uintptr_t)((s) + (a))) ) -#define readmemw(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1))?readmemwl((s)+(a)):*(uint16_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) -#define readmeml(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3))?readmemll((s)+(a)):*(uint32_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) -#define readmemq(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 7))?readmemql((s)+(a)):*(uint64_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uintptr_t)((s)+(a)))) +#define readmemb_n(s,a,b) ((readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF)?readmembl_no_mmut((s)+(a),b): *(uint8_t *)(readlookup2[(uint32_t)((s)+(a))>>12] + (uintptr_t)((s) + (a))) ) +#define readmemw_n(s,a,b) ((readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1))?readmemwl_no_mmut((s)+(a),b):*(uint16_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) +#define readmeml_n(s,a,b) ((readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3))?readmemll_no_mmut((s)+(a),b):*(uint32_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) +#define readmemb(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF)?readmembl((s)+(a)): *(uint8_t *)(readlookup2[(uint32_t)((s)+(a))>>12] + (uintptr_t)((s) + (a))) ) +#define readmemw(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1))?readmemwl((s)+(a)):*(uint16_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) +#define readmeml(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3))?readmemll((s)+(a)):*(uint32_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) +#define readmemq(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 7))?readmemql((s)+(a)):*(uint64_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uintptr_t)((s)+(a)))) -#define writememb_n(s,a,b,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF) writemembl_no_mmut((s)+(a),b,v); else *(uint8_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v -#define writememw_n(s,a,b,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1)) writememwl_no_mmut((s)+(a),b,v); else *(uint16_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v -#define writememl_n(s,a,b,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3)) writememll_no_mmut((s)+(a),b,v); else *(uint32_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v -#define writememb(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF) writemembl((s)+(a),v); else *(uint8_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v -#define writememw(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1)) writememwl((s)+(a),v); else *(uint16_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v -#define writememl(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3)) writememll((s)+(a),v); else *(uint32_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v -#define writememq(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 7)) writememql((s)+(a),v); else *(uint64_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v +#define writememb_n(s,a,b,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF) writemembl_no_mmut((s)+(a),b,v); else *(uint8_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v +#define writememw_n(s,a,b,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1)) writememwl_no_mmut((s)+(a),b,v); else *(uint16_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v +#define writememl_n(s,a,b,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3)) writememll_no_mmut((s)+(a),b,v); else *(uint32_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v +#define writememb(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF) writemembl((s)+(a),v); else *(uint8_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v +#define writememw(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1)) writememwl((s)+(a),v); else *(uint16_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v +#define writememl(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3)) writememll((s)+(a),v); else *(uint32_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v +#define writememq(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 7)) writememql((s)+(a),v); else *(uint64_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v -#define do_mmut_rb(s,a,b) if (readlookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF) do_mmutranslate((s)+(a), b, 1, 0) -#define do_mmut_rw(s,a,b) if (readlookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1)) do_mmutranslate((s)+(a), b, 2, 0) -#define do_mmut_rl(s,a,b) if (readlookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3)) do_mmutranslate((s)+(a), b, 4, 0) +#define do_mmut_rb(s,a,b) if (readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF) do_mmutranslate((s)+(a), b, 1, 0) +#define do_mmut_rw(s,a,b) if (readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1)) do_mmutranslate((s)+(a), b, 2, 0) +#define do_mmut_rl(s,a,b) if (readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3)) do_mmutranslate((s)+(a), b, 4, 0) -#define do_mmut_wb(s,a,b) if (writelookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF) do_mmutranslate((s)+(a), b, 1, 1) -#define do_mmut_ww(s,a,b) if (writelookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1)) do_mmutranslate((s)+(a), b, 2, 1) -#define do_mmut_wl(s,a,b) if (writelookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3)) do_mmutranslate((s)+(a), b, 4, 1) +#define do_mmut_wb(s,a,b) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF) do_mmutranslate((s)+(a), b, 1, 1) +#define do_mmut_ww(s,a,b) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1)) do_mmutranslate((s)+(a), b, 2, 1) +#define do_mmut_wl(s,a,b) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3)) do_mmutranslate((s)+(a), b, 4, 1) -int checkio(int port); +int checkio(uint32_t port); #define check_io_perm(port) if (msw&1 && ((CPL > IOPL) || (cpu_state.eflags&VM_FLAG))) \ diff --git a/src/cpu/386_dynarec.c b/src/cpu/386_dynarec.c index 4a8b3637e..ab1572c85 100644 --- a/src/cpu/386_dynarec.c +++ b/src/cpu/386_dynarec.c @@ -121,9 +121,9 @@ static __inline void fetch_ea_32_long(uint32_t rmdat) if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) { uint32_t addr = easeg + cpu_state.eaaddr; - if ( readlookup2[addr >> 12] != -1) + if ( readlookup2[addr >> 12] != (uintptr_t) -1) eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); - if (writelookup2[addr >> 12] != -1) + if (writelookup2[addr >> 12] != (uintptr_t) -1) eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); } } @@ -161,9 +161,9 @@ static __inline void fetch_ea_16_long(uint32_t rmdat) if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) { uint32_t addr = easeg + cpu_state.eaaddr; - if ( readlookup2[addr >> 12] != -1) + if (readlookup2[addr >> 12] != (uintptr_t) -1) eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); - if (writelookup2[addr >> 12] != -1) + if (writelookup2[addr >> 12] != (uintptr_t) -1) eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); } } diff --git a/src/cpu/386_dynarec_ops.c b/src/cpu/386_dynarec_ops.c index 9854f24bf..ef18c2558 100644 --- a/src/cpu/386_dynarec_ops.c +++ b/src/cpu/386_dynarec_ops.c @@ -33,9 +33,9 @@ static __inline void fetch_ea_32_long(uint32_t rmdat) if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) { uint32_t addr = easeg + cpu_state.eaaddr; - if ( readlookup2[addr >> 12] != -1) + if ( readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); - if (writelookup2[addr >> 12] != -1) + if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); } } @@ -47,9 +47,9 @@ static __inline void fetch_ea_16_long(uint32_t rmdat) if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) { uint32_t addr = easeg + cpu_state.eaaddr; - if ( readlookup2[addr >> 12] != -1) + if ( readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); - if (writelookup2[addr >> 12] != -1) + if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); } } diff --git a/src/cpu/808x.c b/src/cpu/808x.c index c14a2b604..329ebe25f 100644 --- a/src/cpu/808x.c +++ b/src/cpu/808x.c @@ -35,43 +35,9 @@ #include <86box/ppi.h> #include <86box/timer.h> -/* The opcode of the instruction currently being executed. */ -uint8_t opcode; - -/* The tables to speed up the setting of the Z, N, and P cpu_state.flags. */ -uint8_t znptable8[256]; -uint16_t znptable16[65536]; - -/* A 16-bit zero, needed because some speed-up arrays contain pointers to it. */ -uint16_t zero = 0; - -/* MOD and R/M stuff. */ -uint16_t *mod1add[2][8]; -uint32_t *mod1seg[8]; -uint32_t rmdat; - -/* XT CPU multiplier. */ -uint64_t xt_cpu_multi; - /* Is the CPU 8088 or 8086. */ int is8086 = 0; -/* Variables for handling the non-maskable interrupts. */ -int nmi = 0, nmi_auto_clear = 0; - -/* Was the CPU ever reset? */ -int x86_was_reset = 0; - -/* Amount of instructions executed - used to calculate the % shown in the title bar. */ -int ins = 0; - -/* Is the TRAP flag on? */ -int trap = 0; - -/* The current effective address's segment. */ -uint32_t easeg; - - /* The prefetch queue (4 bytes for 8088, 6 bytes for 8086). */ static uint8_t pfq[6]; @@ -148,50 +114,6 @@ x808x_log(const char *fmt, ...) va_end(ap); } } - - -void -dumpregs(int force) -{ - int c; - char *seg_names[4] = { "ES", "CS", "SS", "DS" }; - - /* Only dump when needed, and only once.. */ - if (indump || (!force && !dump_on_exit)) - return; - - x808x_log("EIP=%08X CS=%04X DS=%04X ES=%04X SS=%04X FLAGS=%04X\n", - cpu_state.pc, CS, DS, ES, SS, cpu_state.flags); - x808x_log("Old CS:EIP: %04X:%08X; %i ins\n", oldcs, cpu_state.oldpc, ins); - for (c = 0; c < 4; c++) { - x808x_log("%s : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n", - seg_names[c], _opseg[c]->base, _opseg[c]->limit, - _opseg[c]->access, _opseg[c]->limit_low, _opseg[c]->limit_high); - } - if (is386) { - x808x_log("FS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n", - seg_fs, cpu_state.seg_fs.limit, cpu_state.seg_fs.access, cpu_state.seg_fs.limit_low, cpu_state.seg_fs.limit_high); - x808x_log("GS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n", - gs, cpu_state.seg_gs.limit, cpu_state.seg_gs.access, cpu_state.seg_gs.limit_low, cpu_state.seg_gs.limit_high); - x808x_log("GDT : base=%06X limit=%04X\n", gdt.base, gdt.limit); - x808x_log("LDT : base=%06X limit=%04X\n", ldt.base, ldt.limit); - x808x_log("IDT : base=%06X limit=%04X\n", idt.base, idt.limit); - x808x_log("TR : base=%06X limit=%04X\n", tr.base, tr.limit); - x808x_log("386 in %s mode: %i-bit data, %-i-bit stack\n", - (msw & 1) ? ((cpu_state.eflags & VM_FLAG) ? "V86" : "protected") : "real", - (use32) ? 32 : 16, (stack32) ? 32 : 16); - x808x_log("CR0=%08X CR2=%08X CR3=%08X CR4=%08x\n", cr0, cr2, cr3, cr4); - x808x_log("EAX=%08X EBX=%08X ECX=%08X EDX=%08X\nEDI=%08X ESI=%08X EBP=%08X ESP=%08X\n", - EAX, EBX, ECX, EDX, EDI, ESI, EBP, ESP); - } else { - x808x_log("808x/286 in %s mode\n", (msw & 1) ? "protected" : "real"); - x808x_log("AX=%04X BX=%04X CX=%04X DX=%04X DI=%04X SI=%04X BP=%04X SP=%04X\n", - AX, BX, CX, DX, DI, SI, BP, SP); - } - x808x_log("Entries in readlookup : %i writelookup : %i\n", readlnum, writelnum); - x87_dumpregs(); - indump = 0; -} #else #define x808x_log(fmt, ...) #endif @@ -602,6 +524,63 @@ pfq_clear() } +static void +load_cs(uint16_t seg) +{ + cpu_state.seg_cs.base = seg << 4; + cpu_state.seg_cs.seg = seg & 0xffff; +} + + +static void +load_seg(uint16_t seg, x86seg *s) +{ + s->base = seg << 4; + s->seg = seg & 0xffff; +} + + +void +reset_808x(int hard) +{ + biu_cycles = 0; + in_rep = 0; + in_lock = 0; + completed = 1; + repeating = 0; + clear_lock = 0; + refresh = 0; + ovr_seg = NULL; + + if (hard) { + opseg[0] = &es; + opseg[1] = &cs; + opseg[2] = &ss; + opseg[3] = &ds; + _opseg[0] = &cpu_state.seg_es; + _opseg[1] = &cpu_state.seg_cs; + _opseg[2] = &cpu_state.seg_ss; + _opseg[3] = &cpu_state.seg_ds; + + pfq_size = (is8086) ? 6 : 4; + pfq_clear(); + } + + if (AT) { + load_cs(0xF000); + cpu_state.pc = 0xFFF0; + rammask = cpu_16bitbus ? 0xFFFFFF : 0xFFFFFFFF; + } else { + load_cs(0xFFFF); + cpu_state.pc = 0; + rammask = 0xfffff; + } + + prefetching = 1; + cpu_alu_op = 0; +} + + static void set_ip(uint16_t new_ip) { pfq_ip = cpu_state.pc = new_ip; @@ -616,45 +595,6 @@ refreshread(void) { } -/* Preparation of the various arrays needed to speed up the MOD and R/M work. */ -static void -makemod1table(void) -{ - mod1add[0][0] = &BX; - mod1add[0][1] = &BX; - mod1add[0][2] = &BP; - mod1add[0][3] = &BP; - mod1add[0][4] = &SI; - mod1add[0][5] = &DI; - mod1add[0][6] = &BP; - mod1add[0][7] = &BX; - mod1add[1][0] = &SI; - mod1add[1][1] = &DI; - mod1add[1][2] = &SI; - mod1add[1][3] = &DI; - mod1add[1][4] = &zero; - mod1add[1][5] = &zero; - mod1add[1][6] = &zero; - mod1add[1][7] = &zero; - mod1seg[0] = &ds; - mod1seg[1] = &ds; - mod1seg[2] = &ss; - mod1seg[3] = &ss; - mod1seg[4] = &ds; - mod1seg[5] = &ds; - mod1seg[6] = &ss; - mod1seg[7] = &ds; - opseg[0] = &es; - opseg[1] = &cs; - opseg[2] = &ss; - opseg[3] = &ds; - _opseg[0] = &cpu_state.seg_es; - _opseg[1] = &cpu_state.seg_cs; - _opseg[2] = &cpu_state.seg_ss; - _opseg[3] = &cpu_state.seg_ds; -} - - static uint16_t get_accum(int bits) { @@ -865,176 +805,6 @@ seteaq(uint64_t val) #undef FPU_8087 -/* Prepare the ZNP table needed to speed up the setting of the Z, N, and P cpu_state.flags. */ -static void -makeznptable(void) -{ - int c, d, e; - for (c = 0; c < 256; c++) { - d = 0; - for (e = 0; e < 8; e++) { - if (c & (1 << e)) - d++; - } - if (d & 1) - znptable8[c] = 0; - else - znptable8[c] = P_FLAG; -#ifdef ENABLE_808X_LOG - if (c == 0xb1) - x808x_log("znp8 b1 = %i %02X\n", d, znptable8[c]); -#endif - if (!c) - znptable8[c] |= Z_FLAG; - if (c & 0x80) - znptable8[c] |= N_FLAG; - } - - for (c = 0; c < 65536; c++) { - d = 0; - for (e = 0; e < 8; e++) { - if (c & (1 << e)) - d++; - } - if (d & 1) - znptable16[c] = 0; - else - znptable16[c] = P_FLAG; -#ifdef ENABLE_808X_LOG - if (c == 0xb1) - x808x_log("znp16 b1 = %i %02X\n", d, znptable16[c]); - if (c == 0x65b1) - x808x_log("znp16 65b1 = %i %02X\n", d, znptable16[c]); -#endif - if (!c) - znptable16[c] |= Z_FLAG; - if (c & 0x8000) - znptable16[c] |= N_FLAG; - } -} - - -static void load_cs(uint16_t seg) -{ - cpu_state.seg_cs.base = seg << 4; - CS = seg & 0xffff; -} - - -/* Common reset function. */ -static void -reset_common(int hard) -{ - /* Make sure to gracefully leave SMM. */ - if (in_smm) - leave_smm(); - - biu_cycles = 0; - in_rep = 0; - in_lock = 0; - completed = 1; - repeating = 0; - clear_lock = 0; - refresh = 0; - - if (hard) { -#ifdef ENABLE_808X_LOG - x808x_log("x86 reset\n"); -#endif - ins = 0; - } - use32 = 0; - cpu_cur_status = 0; - stack32 = 0; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - msw = 0; - if (hascache) - cr0 = 1 << 30; - else - cr0 = 0; - cpu_cache_int_enabled = 0; - cpu_update_waitstates(); - cr4 = 0; - cpu_state.eflags = 0; - cgate32 = 0; - if (AT) { - load_cs(0xF000); - cpu_state.pc = 0xFFF0; - rammask = cpu_16bitbus ? 0xFFFFFF : 0xFFFFFFFF; - } else { - load_cs(0xFFFF); - cpu_state.pc = 0; - rammask = 0xfffff; - } - idt.base = 0; - idt.limit = is386 ? 0x03FF : 0xFFFF; - cpu_state.flags = 2; - trap = 0; - ovr_seg = NULL; - - EAX = EBX = ECX = EDX = ESI = EDI = EBP = ESP = 0; - - if (hard) { - makeznptable(); - resetreadlookup(); - makemod1table(); - pfq_clear(); - cpu_set_edx(); - mmu_perm = 4; - pfq_size = (is8086) ? 6 : 4; - } - x86seg_reset(); -#ifdef USE_DYNAREC - if (hard) - codegen_reset(); -#endif - if (!hard) - flushmmucache(); - x86_was_reset = 1; - cpu_alt_reset = 0; - - prefetching = 1; - - cpu_ven_reset(); - - cpu_alu_op = 0; - - in_smm = smi_latched = 0; - smi_line = smm_in_hlt = 0; - smi_block = 0; - - if (hard) { - smbase = is_am486 ? 0x00060000 : 0x00030000; - ppi_reset(); - } - in_sys = 0; - - shadowbios = shadowbios_write = 0; - alt_access = cpu_end_block_after_ins = 0; -} - - -/* Hard reset. */ -void -resetx86(void) -{ - reset_common(1); - - soft_reset_mask = 0; -} - - -/* Soft reset. */ -void -softresetx86(void) -{ - if (soft_reset_mask) - return; - - reset_common(0); -} - - /* Pushes a word to the stack. */ static void push(uint16_t *val) @@ -1867,7 +1637,7 @@ execx86(int cycs) load_cs(pop()); pfq_pos = 0; } else - loadseg(pop(), _opseg[(opcode >> 3) & 0x03]); + load_seg(pop(), _opseg[(opcode >> 3) & 0x03]); wait(1, 0); /* All POP segment instructions suppress interrupts for one instruction. */ noint = 1; @@ -2201,7 +1971,7 @@ execx86(int cycs) load_cs(tempw); pfq_pos = 0; } else - loadseg(tempw, _opseg[(rmdat & 0x18) >> 3]); + load_seg(tempw, _opseg[(rmdat & 0x18) >> 3]); wait(1, 0); if (cpu_mod != 3) wait(2, 0); @@ -2482,7 +2252,7 @@ execx86(int cycs) cpu_state.regs[cpu_reg].w = cpu_data; access(57, bits); read_ea2(bits); - loadseg(cpu_data, (opcode & 0x01) ? &cpu_state.seg_ds : &cpu_state.seg_es); + load_seg(cpu_data, (opcode & 0x01) ? &cpu_state.seg_ds : &cpu_state.seg_es); wait(1, 0); break; @@ -2985,7 +2755,5 @@ execx86(int cycs) cpu_alu_op = 0; } - - ins++; } } diff --git a/src/cpu/CMakeLists.txt b/src/cpu/CMakeLists.txt index 6fe97a35c..ab27b77c0 100644 --- a/src/cpu/CMakeLists.txt +++ b/src/cpu/CMakeLists.txt @@ -13,7 +13,7 @@ # Copyright 2020,2021 David Hrdlička. # -add_library(cpu OBJECT cpu.c cpu_table.c 808x.c 386.c 386_common.c 386_dynarec.c +add_library(cpu OBJECT cpu.c cpu_table.c fpu.c x86.c 808x.c 386.c 386_common.c 386_dynarec.c 386_dynarec_ops.c x86seg.c x87.c x87_timings.c) if(AMD_K5) diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 1d17496fa..4f31ab5ad 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -1,42 +1,22 @@ /* - * VARCem Virtual ARchaeological Computer EMulator. - * An emulator of (mostly) x86-based PC systems and devices, - * using the ISA,EISA,VLB,MCA and PCI system buses, roughly - * spanning the era between 1981 and 1995. + * 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 VARCem Project. + * This file is part of the 86Box distribution. * * CPU type handler. * - * - * - * Authors: Fred N. van Kempen, - * Sarah Walker, + * Authors: Sarah Walker, * leilei, * Miran Grca, + * Fred N. van Kempen, * - * Copyright 2018 Fred N. van Kempen. * Copyright 2008-2018 Sarah Walker. * Copyright 2016-2018 leilei. * Copyright 2016-2018 Miran Grca. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the: - * - * Free Software Foundation, Inc. - * 59 Temple Place - Suite 330 - * Boston, MA 02111-1307 - * USA. + * Copyright 2018 Fred N. van Kempen. */ #include #include @@ -69,13 +49,6 @@ #define CCR3_NMI_EN (1 << 1) -cyrix_t cyrix; - - -static void cpu_write(uint16_t addr, uint8_t val, void *priv); -static uint8_t cpu_read(uint16_t addr, void *priv); - - enum { CPUID_FPU = (1 << 0), CPUID_VME = (1 << 1), @@ -93,174 +66,75 @@ enum { }; /*Addition flags returned by CPUID function 0x80000001*/ -enum -{ - CPUID_3DNOW = (1 << 31) -}; +#define CPUID_3DNOW (1UL << 31UL) #ifdef USE_DYNAREC -const OpFn *x86_dynarec_opcodes; -const OpFn *x86_dynarec_opcodes_0f; -const OpFn *x86_dynarec_opcodes_d8_a16; -const OpFn *x86_dynarec_opcodes_d8_a32; -const OpFn *x86_dynarec_opcodes_d9_a16; -const OpFn *x86_dynarec_opcodes_d9_a32; -const OpFn *x86_dynarec_opcodes_da_a16; -const OpFn *x86_dynarec_opcodes_da_a32; -const OpFn *x86_dynarec_opcodes_db_a16; -const OpFn *x86_dynarec_opcodes_db_a32; -const OpFn *x86_dynarec_opcodes_dc_a16; -const OpFn *x86_dynarec_opcodes_dc_a32; -const OpFn *x86_dynarec_opcodes_dd_a16; -const OpFn *x86_dynarec_opcodes_dd_a32; -const OpFn *x86_dynarec_opcodes_de_a16; -const OpFn *x86_dynarec_opcodes_de_a32; -const OpFn *x86_dynarec_opcodes_df_a16; -const OpFn *x86_dynarec_opcodes_df_a32; -const OpFn *x86_dynarec_opcodes_REPE; -const OpFn *x86_dynarec_opcodes_REPNE; -const OpFn *x86_dynarec_opcodes_3DNOW; +const OpFn *x86_dynarec_opcodes, *x86_dynarec_opcodes_0f, + *x86_dynarec_opcodes_d8_a16, *x86_dynarec_opcodes_d8_a32, + *x86_dynarec_opcodes_d9_a16, *x86_dynarec_opcodes_d9_a32, + *x86_dynarec_opcodes_da_a16, *x86_dynarec_opcodes_da_a32, + *x86_dynarec_opcodes_db_a16, *x86_dynarec_opcodes_db_a32, + *x86_dynarec_opcodes_dc_a16, *x86_dynarec_opcodes_dc_a32, + *x86_dynarec_opcodes_dd_a16, *x86_dynarec_opcodes_dd_a32, + *x86_dynarec_opcodes_de_a16, *x86_dynarec_opcodes_de_a32, + *x86_dynarec_opcodes_df_a16, *x86_dynarec_opcodes_df_a32, + *x86_dynarec_opcodes_REPE, *x86_dynarec_opcodes_REPNE, + *x86_dynarec_opcodes_3DNOW; #endif -const OpFn *x86_opcodes; -const OpFn *x86_opcodes_0f; -const OpFn *x86_opcodes_d8_a16; -const OpFn *x86_opcodes_d8_a32; -const OpFn *x86_opcodes_d9_a16; -const OpFn *x86_opcodes_d9_a32; -const OpFn *x86_opcodes_da_a16; -const OpFn *x86_opcodes_da_a32; -const OpFn *x86_opcodes_db_a16; -const OpFn *x86_opcodes_db_a32; -const OpFn *x86_opcodes_dc_a16; -const OpFn *x86_opcodes_dc_a32; -const OpFn *x86_opcodes_dd_a16; -const OpFn *x86_opcodes_dd_a32; -const OpFn *x86_opcodes_de_a16; -const OpFn *x86_opcodes_de_a32; -const OpFn *x86_opcodes_df_a16; -const OpFn *x86_opcodes_df_a32; -const OpFn *x86_opcodes_REPE; -const OpFn *x86_opcodes_REPNE; -const OpFn *x86_opcodes_3DNOW; +const OpFn *x86_opcodes, *x86_opcodes_0f, + *x86_opcodes_d8_a16, *x86_opcodes_d8_a32, + *x86_opcodes_d9_a16, *x86_opcodes_d9_a32, + *x86_opcodes_da_a16, *x86_opcodes_da_a32, + *x86_opcodes_db_a16, *x86_opcodes_db_a32, + *x86_opcodes_dc_a16, *x86_opcodes_dc_a32, + *x86_opcodes_dd_a16, *x86_opcodes_dd_a32, + *x86_opcodes_de_a16, *x86_opcodes_de_a32, + *x86_opcodes_df_a16, *x86_opcodes_df_a32, + *x86_opcodes_REPE, *x86_opcodes_REPNE, + *x86_opcodes_3DNOW; -int in_smm = 0, smi_line = 0, smi_latched = 0, smm_in_hlt = 0; -int smi_block = 0; -uint32_t smbase = 0x30000; +uint16_t cpu_fast_off_count, cpu_fast_off_val; +uint16_t temp_seg_data[4] = {0, 0, 0, 0}; + +int isa_cycles, + + cpu_cycles_read, cpu_cycles_read_l, cpu_cycles_write, cpu_cycles_write_l, + cpu_prefetch_cycles, cpu_prefetch_width, cpu_mem_prefetch_cycles, cpu_rom_prefetch_cycles, + cpu_waitstates, cpu_cache_int_enabled, cpu_cache_ext_enabled, + cpu_isa_speed, cpu_pci_speed, cpu_isa_pci_div, cpu_agp_speed, cpu_alt_reset, + + cpu_override, cpu_effective, cpu_multi, cpu_16bitbus, cpu_64bitbus, cpu_busspeed, + cpu_cyrix_alignment, CPUID, + + is286, is386, is486 = 1, is486sx, is486dx, is486sx2, is486dx2, isdx4, + cpu_isintel, cpu_iscyrix, hascache, isibm486, israpidcad, is_vpc, + is_am486, is_pentium, is_k5, is_k6, is_p6, is_cx6x86, hasfpu, + + timing_rr, timing_mr, timing_mrl, timing_rm, timing_rml, + timing_mm, timing_mml, timing_bt, timing_bnt, + timing_int, timing_int_rm, timing_int_v86, timing_int_pm, + timing_int_pm_outer, timing_iret_rm, timing_iret_v86, timing_iret_pm, + timing_iret_pm_outer, timing_call_rm, timing_call_pm, timing_call_pm_gate, + timing_call_pm_gate_inner, timing_retf_rm, timing_retf_pm, timing_retf_pm_outer, + timing_jmp_rm, timing_jmp_pm, timing_jmp_pm_gate, timing_misaligned; + +uint32_t cpu_features, cpu_fast_off_flags; + +uint64_t cpu_CR4_mask, tsc = 0; +uint64_t pmc[2] = {0, 0}; + +double cpu_dmulti; + +msr_t msr; + +cpu_state_t cpu_state; + +cyrix_t cyrix; cpu_family_t *cpu_f; CPU *cpu_s; -int cpu_override; -int cpu_effective; -int cpu_multi; -double cpu_dmulti; -int cpu_16bitbus, cpu_64bitbus; -int cpu_busspeed; -int cpu_cyrix_alignment; -int CPUID; -uint64_t cpu_CR4_mask; -int isa_cycles; -int cpu_cycles_read, cpu_cycles_read_l, - cpu_cycles_write, cpu_cycles_write_l; -int cpu_prefetch_cycles, cpu_prefetch_width, - cpu_mem_prefetch_cycles, cpu_rom_prefetch_cycles; -int cpu_waitstates; -int cpu_cache_int_enabled, cpu_cache_ext_enabled; -int cpu_isa_speed, cpu_pci_speed, cpu_isa_pci_div, cpu_agp_speed, cpu_alt_reset; -uint16_t cpu_fast_off_count, cpu_fast_off_val; -uint32_t cpu_fast_off_flags; -int is_vpc; - -uint32_t cpu_features; - -int is286, - is386, - is486 = 1, - is486sx, is486dx, is486sx2, is486dx2, isdx4, - cpu_isintel, cpu_iscyrix, - hascache, - isibm486, - israpidcad, - is_am486, is_pentium, is_k5, is_k6, is_p6, is_cx6x86; - -int hasfpu; - -uint64_t tsc = 0; -msr_t msr; -cpu_state_t cpu_state; -uint64_t pmc[2] = {0, 0}; - -uint16_t temp_seg_data[4] = {0, 0, 0, 0}; - -uint64_t mtrr_cap_msr = 0x00000508; -uint64_t mtrr_physbase_msr[8] = {0, 0, 0, 0, 0, 0, 0, 0}; -uint64_t mtrr_physmask_msr[8] = {0, 0, 0, 0, 0, 0, 0, 0}; -uint64_t mtrr_fix64k_8000_msr = 0; -uint64_t mtrr_fix16k_8000_msr = 0; -uint64_t mtrr_fix16k_a000_msr = 0; -uint64_t mtrr_fix4k_msr[8] = {0, 0, 0, 0, 0, 0, 0, 0}; -uint64_t mtrr_deftype_msr = 0; - -uint64_t ibm_por_msr = 0; /*Processor Operation Register*/ -uint64_t ibm_crcr_msr = 0; /*Cache Region Control Register*/ -uint64_t ibm_por2_msr = 0; /*Processor Operation Register*/ - -uint16_t cs_msr = 0; -uint32_t esp_msr = 0; -uint32_t eip_msr = 0; -uint64_t apic_base_msr = 0; -uint64_t pat_msr = 0; -uint64_t msr_ia32_pmc[8] = {0, 0, 0, 0, 0, 0, 0, 0}; -uint64_t ecx17_msr = 0; -uint64_t ecx2a_msr = 0; -uint64_t ecx79_msr = 0; -uint64_t ecx8x_msr[4] = {0, 0, 0, 0}; -uint64_t ecx116_msr = 0; -uint64_t ecx11x_msr[4] = {0, 0, 0, 0}; -uint64_t ecx11e_msr = 0; -uint64_t ecx186_msr = 0; -uint64_t ecx187_msr = 0; -uint64_t ecx1e0_msr = 0; - -/* Model Identification MSR's used by some Acer BIOSes*/ -uint64_t ecx404_msr = 0; -uint64_t ecx408_msr = 0; -uint64_t ecx40c_msr = 0; -uint64_t ecx410_msr = 0; -uint64_t ecx570_msr = 0; - -uint64_t ecx83_msr = 0; /* AMD K5 and K6 MSR's. */ - -/* MSR used by some Intel AMI boards */ -uint64_t ecx1002ff_msr = 0; - -/* Some weird long MSR's used by i686 AMI & some Phoenix BIOSes */ -uint64_t ecxf0f00250_msr = 0; -uint64_t ecxf0f00258_msr = 0; -uint64_t ecxf0f00259_msr = 0; - -uint64_t star = 0; /* AMD K6-2+. */ - -uint64_t amd_efer = 0, amd_whcr = 0, - amd_uwccr = 0, amd_epmr = 0, /* AMD K6-2+ registers. */ - amd_psor = 0, amd_pfir = 0, - amd_l2aar = 0; - -int timing_rr; -int timing_mr, timing_mrl; -int timing_rm, timing_rml; -int timing_mm, timing_mml; -int timing_bt, timing_bnt; -int timing_int, timing_int_rm, timing_int_v86, timing_int_pm, - timing_int_pm_outer; -int timing_iret_rm, timing_iret_v86, timing_iret_pm, - timing_iret_pm_outer; -int timing_call_rm, timing_call_pm, timing_call_pm_gate, - timing_call_pm_gate_inner; -int timing_retf_rm, timing_retf_pm, timing_retf_pm_outer; -int timing_jmp_rm, timing_jmp_pm, timing_jmp_pm_gate; -int timing_misaligned; uint8_t do_translate = 0, do_translate2 = 0; @@ -269,7 +143,11 @@ void (*cpu_exec)(int cycs); static uint8_t ccr0, ccr1, ccr2, ccr3, ccr4, ccr5, ccr6; -static int cyrix_addr; +static int cyrix_addr; + + +static void cpu_write(uint16_t addr, uint8_t val, void *priv); +static uint8_t cpu_read(uint16_t addr, void *priv); #ifdef ENABLE_CPU_LOG @@ -295,1599 +173,1204 @@ cpu_log(const char *fmt, ...) int cpu_has_feature(int feature) { - return cpu_features & feature; + return cpu_features & feature; } void cpu_dynamic_switch(int new_cpu) { - if (cpu_effective == new_cpu) - return; + int c; - int c = cpu; - cpu = new_cpu; - cpu_set(); - pc_speed_changed(); - cpu = c; + if (cpu_effective == new_cpu) + return; + + c = cpu; + cpu = new_cpu; + cpu_set(); + pc_speed_changed(); + cpu = c; } void cpu_set_edx(void) { - EDX = cpu_s->edx_reset; + EDX = cpu_s->edx_reset; } + cpu_family_t * cpu_get_family(const char *internal_name) { - int c = 0; - while (cpu_families[c].package) { - if (!strcmp(internal_name, cpu_families[c].internal_name)) - return (cpu_family_t *) &cpu_families[c]; - c++; - } + int c = 0; - return NULL; + while (cpu_families[c].package) { + if (!strcmp(internal_name, cpu_families[c].internal_name)) + return (cpu_family_t *) &cpu_families[c]; + c++; + } + + return NULL; } uint8_t cpu_is_eligible(const cpu_family_t *cpu_family, int cpu, int machine) { - if (cpu_override > 1) /* full override */ - return 1; - - /* Get machine. */ - const machine_t *machine_s = &machines[machine]; - - /* Add implicit CPU package compatibility. */ - uint32_t packages = machine_s->cpu_package; - if (packages & CPU_PKG_SOCKET3) - packages |= CPU_PKG_SOCKET1; - else if (packages & CPU_PKG_SLOT1) - packages |= CPU_PKG_SOCKET370; - - if (!(cpu_family->package & packages)) /* package type */ - return 0; - - if (cpu_override) /* partial override */ - return 1; - - const CPU *cpu_s = &cpu_family->cpus[cpu]; - - /* Check CPU blocklist. */ - if (machine_s->cpu_block) { - uint8_t i = 0; - while (machine_s->cpu_block[i]) { - if (machine_s->cpu_block[i++] == cpu_s->cpu_type) - return 0; - } - } - - uint32_t bus_speed = cpu_s->rspeed / cpu_s->multi; - - if (machine_s->cpu_min_bus && (bus_speed < (machine_s->cpu_min_bus - 840907))) /* minimum bus speed with ~0.84 MHz (for 8086) tolerance */ - return 0; - - if (machine_s->cpu_max_bus && (bus_speed > (machine_s->cpu_max_bus + 840907))) /* maximum bus speed with ~0.84 MHz (for 8086) tolerance */ - return 0; - - if (machine_s->cpu_min_voltage && (cpu_s->voltage < (machine_s->cpu_min_voltage - 100))) /* minimum voltage with 0.1V tolerance */ - return 0; - - if (machine_s->cpu_max_voltage && (cpu_s->voltage > (machine_s->cpu_max_voltage + 100))) /* maximum voltage with 0.1V tolerance */ - return 0; - - /* Account for CPUs which use a different internal multiplier than specified by jumpers. */ - double multi = cpu_s->multi; - if (cpu_s->cpu_flags & CPU_FIXED_MULTIPLIER) { - return 1; /* don't care about multiplier compatibility on fixed multiplier CPUs */ - } else if (cpu_family->package & CPU_PKG_SOCKET5_7) { - if ((multi == 1.5) && (cpu_s->cpu_type == CPU_5K86) && (machine_s->cpu_min_multi > 1.5)) /* K5 5k86 */ - multi = 2.0; - else if (multi == 1.75) /* K5 5k86 */ - multi = 2.5; - else if (multi == 2.0) { - if (cpu_s->cpu_type == CPU_5K86) /* K5 5k86 */ - multi = 3.0; - else if (cpu_s->cpu_type == CPU_K6_2P || cpu_s->cpu_type == CPU_K6_3P) /* K6-2+ / K6-3+ */ - multi = 2.5; - else if ((cpu_s->cpu_type == CPU_WINCHIP || cpu_s->cpu_type == CPU_WINCHIP2) && (machine_s->cpu_min_multi > 2.0)) /* WinChip (2) */ - multi = 2.5; - } - else if (multi == (7.0 / 3.0)) /* WinChip 2A - 2.33x */ - multi = 5.0; - else if (multi == (8.0 / 3.0)) /* WinChip 2A - 2.66x */ - multi = 5.5; - else if ((multi == 3.0) && (cpu_s->cpu_type == CPU_Cx6x86 || cpu_s->cpu_type == CPU_Cx6x86L)) /* 6x86(L) */ - multi = 1.5; - else if (multi == (10.0 / 3.0)) /* WinChip 2A - 3.33x */ - multi = 2.0; - else if ((multi == 3.5) && (machine_s->cpu_min_multi < 3.5)) /* standard set by the Pentium MMX */ - multi = 1.5; - else if (multi == 4.0) { - if (cpu_s->cpu_type == CPU_WINCHIP || cpu_s->cpu_type == CPU_WINCHIP2) { /* WinChip (2) */ - if (machine_s->cpu_min_multi >= 1.5) - multi = 1.5; - else if (machine_s->cpu_min_multi >= 3.5) - multi = 3.5; - else if (machine_s->cpu_min_multi >= 4.5) - multi = 4.5; - } else if (cpu_s->cpu_type == CPU_Cx6x86 || cpu_s->cpu_type == CPU_Cx6x86L) /* 6x86(L) */ - multi = 3.0; - } - else if ((multi == 5.0) && (cpu_s->cpu_type == CPU_WINCHIP || cpu_s->cpu_type == CPU_WINCHIP2) && (machine_s->cpu_min_multi > 5.0)) /* WinChip (2) */ - multi = 5.5; - else if ((multi == 6.0) && (machine_s->cpu_max_multi < 6.0)) /* K6-2(+) / K6-3(+) */ - multi = 2.0; - } - - if (multi < machine_s->cpu_min_multi) /* minimum multiplier */ - return 0; - - if (machine_s->cpu_max_multi && (multi > machine_s->cpu_max_multi)) /* maximum multiplier */ - return 0; + const machine_t *machine_s = &machines[machine]; + const CPU *cpu_s = &cpu_family->cpus[cpu]; + uint32_t packages, bus_speed; + uint8_t i; + double multi; + /* Full override. */ + if (cpu_override > 1) return 1; + + /* Add implicit CPU package compatibility. */ + packages = machine_s->cpu_package; + if (packages & CPU_PKG_SOCKET3) + packages |= CPU_PKG_SOCKET1; + else if (packages & CPU_PKG_SLOT1) + packages |= CPU_PKG_SOCKET370; + + /* Package type. */ + if (!(cpu_family->package & packages)) + return 0; + + /* Partial override. */ + if (cpu_override) + return 1; + + /* Check CPU blocklist. */ + if (machine_s->cpu_block) { + i = 0; + + while (machine_s->cpu_block[i]) { + if (machine_s->cpu_block[i++] == cpu_s->cpu_type) + return 0; + } + } + + bus_speed = cpu_s->rspeed / cpu_s->multi; + + /* Minimum bus speed with ~0.84 MHz (for 8086) tolerance. */ + if (machine_s->cpu_min_bus && (bus_speed < (machine_s->cpu_min_bus - 840907))) + return 0; + + /* Maximum bus speed with ~0.84 MHz (for 8086) tolerance. */ + if (machine_s->cpu_max_bus && (bus_speed > (machine_s->cpu_max_bus + 840907))) + return 0; + + /* Minimum voltage with 0.1V tolerance. */ + if (machine_s->cpu_min_voltage && (cpu_s->voltage < (machine_s->cpu_min_voltage - 100))) + return 0; + + /* Maximum voltage with 0.1V tolerance. */ + if (machine_s->cpu_max_voltage && (cpu_s->voltage > (machine_s->cpu_max_voltage + 100))) + return 0; + + /* Account for CPUs which use a different internal multiplier than specified by jumpers. */ + multi = cpu_s->multi; + + /* Don't care about multiplier compatibility on fixed multiplier CPUs. */ + if (cpu_s->cpu_flags & CPU_FIXED_MULTIPLIER) + return 1; + else if (cpu_family->package & CPU_PKG_SOCKET5_7) { + if ((multi == 1.5) && (cpu_s->cpu_type == CPU_5K86) && (machine_s->cpu_min_multi > 1.5)) /* K5 5k86 */ + multi = 2.0; + else if (multi == 1.75) /* K5 5k86 */ + multi = 2.5; + else if (multi == 2.0) { + if (cpu_s->cpu_type == CPU_5K86) /* K5 5k86 */ + multi = 3.0; + /* K6-2+ / K6-3+ */ + else if ((cpu_s->cpu_type == CPU_K6_2P) || (cpu_s->cpu_type == CPU_K6_3P)) + multi = 2.5; + else if (((cpu_s->cpu_type == CPU_WINCHIP) || (cpu_s->cpu_type == CPU_WINCHIP2)) && + (machine_s->cpu_min_multi > 2.0)) /* WinChip (2) */ + multi = 2.5; + } + else if (multi == (7.0 / 3.0)) /* WinChip 2A - 2.33x */ + multi = 5.0; + else if (multi == (8.0 / 3.0)) /* WinChip 2A - 2.66x */ + multi = 5.5; + else if ((multi == 3.0) && (cpu_s->cpu_type == CPU_Cx6x86 || cpu_s->cpu_type == CPU_Cx6x86L)) /* 6x86(L) */ + multi = 1.5; + else if (multi == (10.0 / 3.0)) /* WinChip 2A - 3.33x */ + multi = 2.0; + else if ((multi == 3.5) && (machine_s->cpu_min_multi < 3.5)) /* standard set by the Pentium MMX */ + multi = 1.5; + else if (multi == 4.0) { + /* WinChip (2) */ + if ((cpu_s->cpu_type == CPU_WINCHIP) || (cpu_s->cpu_type == CPU_WINCHIP2)) { + if (machine_s->cpu_min_multi >= 1.5) + multi = 1.5; + else if (machine_s->cpu_min_multi >= 3.5) + multi = 3.5; + else if (machine_s->cpu_min_multi >= 4.5) + multi = 4.5; + } else if ((cpu_s->cpu_type == CPU_Cx6x86) || (cpu_s->cpu_type == CPU_Cx6x86L)) /* 6x86(L) */ + multi = 3.0; + } else if ((multi == 5.0) && ((cpu_s->cpu_type == CPU_WINCHIP) || (cpu_s->cpu_type == CPU_WINCHIP2)) && + (machine_s->cpu_min_multi > 5.0)) /* WinChip (2) */ + multi = 5.5; + else if ((multi == 6.0) && (machine_s->cpu_max_multi < 6.0)) /* K6-2(+) / K6-3(+) */ + multi = 2.0; + } + + /* Minimum multiplier, */ + if (multi < machine_s->cpu_min_multi) + return 0; + + /* Maximum multiplier. */ + if (machine_s->cpu_max_multi && (multi > machine_s->cpu_max_multi)) + return 0; + + return 1; } uint8_t cpu_family_is_eligible(const cpu_family_t *cpu_family, int machine) { - int c = 0; + int c = 0; - while (cpu_family->cpus[c].cpu_type) { - if (cpu_is_eligible(cpu_family, c, machine)) - return 1; - c++; - } + while (cpu_family->cpus[c].cpu_type) { + if (cpu_is_eligible(cpu_family, c, machine)) + return 1; + c++; + } - return 0; + return 0; } -int fpu_get_type(const cpu_family_t *cpu_family, int cpu, const char *internal_name) -{ - const CPU *cpu_s = &cpu_family->cpus[cpu]; - const FPU *fpus = cpu_s->fpus; - int fpu_type = fpus[0].type; - int c = 0; - - while (fpus[c].internal_name) - { - if (!strcmp(internal_name, fpus[c].internal_name)) - fpu_type = fpus[c].type; - c++; - } - - return fpu_type; -} - -const char *fpu_get_internal_name(const cpu_family_t *cpu_family, int cpu, int type) -{ - const CPU *cpu_s = &cpu_family->cpus[cpu]; - const FPU *fpus = cpu_s->fpus; - int c = 0; - - while (fpus[c].internal_name) - { - if (fpus[c].type == type) - return fpus[c].internal_name; - c++; - } - - return fpus[0].internal_name; -} - -const char *fpu_get_name_from_index(const cpu_family_t *cpu_family, int cpu, int c) -{ - const CPU *cpu_s = &cpu_family->cpus[cpu]; - const FPU *fpus = cpu_s->fpus; - - return fpus[c].name; -} - -int fpu_get_type_from_index(const cpu_family_t *cpu_family, int cpu, int c) -{ - const CPU *cpu_s = &cpu_family->cpus[cpu]; - const FPU *fpus = cpu_s->fpus; - - return fpus[c].type; -} - void cpu_set(void) { - cpu_effective = cpu; - cpu_s = (CPU *) &cpu_f->cpus[cpu_effective]; + cpu_effective = cpu; + cpu_s = (CPU *) &cpu_f->cpus[cpu_effective]; #ifdef USE_ACYCS - acycs = 0; + acycs = 0; #endif - cpu_alt_reset = 0; - unmask_a20_in_smm = 0; + cpu_alt_reset = 0; + unmask_a20_in_smm = 0; - CPUID = cpu_s->cpuid_model; - is8086 = (cpu_s->cpu_type > CPU_8088); - is286 = (cpu_s->cpu_type >= CPU_286); - is386 = (cpu_s->cpu_type >= CPU_386SX); - israpidcad = (cpu_s->cpu_type == CPU_RAPIDCAD); - isibm486 = (cpu_s->cpu_type == CPU_IBM386SLC) || (cpu_s->cpu_type == CPU_IBM486SLC) || (cpu_s->cpu_type == CPU_IBM486BL); - is486 = (cpu_s->cpu_type >= CPU_i486SX) || (cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_486DLC || cpu_s->cpu_type == CPU_RAPIDCAD); - is486sx = (cpu_s->cpu_type >= CPU_i486SX) && (cpu_s->cpu_type < CPU_i486SX2); - is486sx2 = (cpu_s->cpu_type >= CPU_i486SX2) && (cpu_s->cpu_type < CPU_i486DX); - 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_am486 = (cpu_s->cpu_type == CPU_Am486SX) || (cpu_s->cpu_type == CPU_Am486SX2) || (cpu_s->cpu_type == CPU_Am486DX) || - (cpu_s->cpu_type == CPU_Am486DX2) || (cpu_s->cpu_type == CPU_Am486DX4) || (cpu_s->cpu_type == CPU_Am5x86); - is_pentium = (cpu_s->cpu_type == CPU_P24T) || (cpu_s->cpu_type == CPU_PENTIUM) || (cpu_s->cpu_type == CPU_PENTIUMMMX); - /* Not Pentiums, but they share the same SMM save state table layout. */ - is_pentium |= (cpu_s->cpu_type == CPU_i486DX2) || (cpu_s->cpu_type == CPU_iDX4); - /* The WinChip datasheet claims these are Pentium-compatible. */ - is_pentium |= (cpu_s->cpu_type == CPU_WINCHIP) || (cpu_s->cpu_type == CPU_WINCHIP2); -#if defined(DEV_BRANCH) && defined(USE_AMD_K5) - is_k5 = (cpu_s->cpu_type == CPU_K5) || (cpu_s->cpu_type == CPU_5K86); + CPUID = cpu_s->cpuid_model; + is8086 = (cpu_s->cpu_type > CPU_8088); + is286 = (cpu_s->cpu_type >= CPU_286); + is386 = (cpu_s->cpu_type >= CPU_386SX); + israpidcad = (cpu_s->cpu_type == CPU_RAPIDCAD); + isibm486 = (cpu_s->cpu_type == CPU_IBM386SLC) || (cpu_s->cpu_type == CPU_IBM486SLC) || + (cpu_s->cpu_type == CPU_IBM486BL); + is486 = (cpu_s->cpu_type >= CPU_RAPIDCAD); + is486sx = (cpu_s->cpu_type >= CPU_i486SX) && (cpu_s->cpu_type < CPU_i486SX2); + is486sx2 = (cpu_s->cpu_type >= CPU_i486SX2) && (cpu_s->cpu_type < CPU_i486DX); + 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_am486 = !strcmp(cpu_f->manufacturer, "AMD") && (cpu_s->cpu_type >= CPU_Am486SX) && (cpu_s->cpu_type <= CPU_Am5x86); + + cpu_isintel = !strcmp(cpu_f->manufacturer, "Intel"); + cpu_iscyrix = !strcmp(cpu_f->manufacturer, "Cyrix"); + + /* The 486DX2 and iDX4 have the same SMM save state table layout as Pentiums, + and the WinChip datasheet claims those are Pentium-compatible as well. */ + is_pentium = (cpu_isintel && (cpu_s->cpu_type >= CPU_i486DX2) && (cpu_s->cpu_type < CPU_PENTIUMPRO)) || + !strcmp(cpu_f->manufacturer, "IDT"); + is_k5 = !strcmp(cpu_f->manufacturer, "AMD") && (cpu_s->cpu_type > CPU_Am5x86); + is_k6 = (cpu_s->cpu_type >= CPU_K6) && !strcmp(cpu_f->manufacturer, "AMD"); + /* The Samuel 2 datasheet claims it's Celeron-compatible. */ + is_p6 = (cpu_isintel && (cpu_s->cpu_type >= CPU_PENTIUMPRO)) || !strcmp(cpu_f->manufacturer, "VIA"); + is_cx6x86 = !strcmp(cpu_f->manufacturer, "Cyrix") && (cpu_s->cpu_type > CPU_Cx5x86); + + hasfpu = (fpu_type != FPU_NONE); + 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); + + cpu_16bitbus = (cpu_s->cpu_type == CPU_286) || (cpu_s->cpu_type == CPU_386SX) || + (cpu_s->cpu_type == CPU_486SLC) || (cpu_s->cpu_type == CPU_IBM386SLC) || + (cpu_s->cpu_type == CPU_IBM486SLC); + cpu_64bitbus = (cpu_s->cpu_type >= CPU_WINCHIP); + + if (cpu_s->multi) + cpu_busspeed = cpu_s->rspeed / cpu_s->multi; + else + cpu_busspeed = cpu_s->rspeed; + cpu_multi = (int) ceil(cpu_s->multi); + cpu_dmulti = cpu_s->multi; + ccr0 = ccr1 = ccr2 = ccr3 = ccr4 = ccr5 = ccr6 = 0; + + cpu_update_waitstates(); + + isa_cycles = cpu_s->atclk_div; + + if (cpu_s->rspeed <= 8000000) + cpu_rom_prefetch_cycles = cpu_mem_prefetch_cycles; + else + cpu_rom_prefetch_cycles = cpu_s->rspeed / 1000000; + + cpu_set_isa_pci_div(0); + cpu_set_pci_speed(0); + cpu_set_agp_speed(0); + + io_handler(cpu_iscyrix, 0x0022, 0x0002, cpu_read, NULL, NULL, cpu_write, NULL, NULL, NULL); + + io_handler(hasfpu, 0x00f0, 0x000f, cpu_read, NULL, NULL, cpu_write, NULL, NULL, NULL); + io_handler(hasfpu, 0xf007, 0x0001, cpu_read, NULL, NULL, cpu_write, NULL, NULL, NULL); + +#ifdef USE_DYNAREC + x86_setopcodes(ops_386, ops_386_0f, dynarec_ops_386, dynarec_ops_386_0f); #else - is_k5 = 0; + x86_setopcodes(ops_386, ops_386_0f); #endif - is_k6 = (cpu_s->cpu_type == CPU_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); - is_p6 = (cpu_s->cpu_type == CPU_PENTIUMPRO) || (cpu_s->cpu_type == CPU_PENTIUM2) || - (cpu_s->cpu_type == CPU_PENTIUM2D); - /* The Samuel 2 datasheet claims it's Celeron-compatible. */ - is_p6 |= (cpu_s->cpu_type == CPU_CYRIX3S) || (cpu_s->cpu_type == CPU_EDEN); -#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) - is_cx6x86 = (cpu_s->cpu_type == CPU_Cx6x86) || (cpu_s->cpu_type == CPU_Cx6x86MX) || - (cpu_s->cpu_type == CPU_Cx6x86L) || (cpu_s->cpu_type == CPU_CxGX1); + x86_opcodes_REPE = ops_REPE; + x86_opcodes_REPNE = ops_REPNE; + x86_opcodes_3DNOW = ops_3DNOW; +#ifdef USE_DYNAREC + x86_dynarec_opcodes_REPE = dynarec_ops_REPE; + x86_dynarec_opcodes_REPNE = dynarec_ops_REPNE; + x86_dynarec_opcodes_3DNOW = dynarec_ops_3DNOW; +#endif + + if (hasfpu) { +#ifdef USE_DYNAREC + x86_dynarec_opcodes_d8_a16 = dynarec_ops_fpu_d8_a16; + x86_dynarec_opcodes_d8_a32 = dynarec_ops_fpu_d8_a32; + x86_dynarec_opcodes_d9_a16 = dynarec_ops_fpu_d9_a16; + x86_dynarec_opcodes_d9_a32 = dynarec_ops_fpu_d9_a32; + x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_da_a16; + x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_da_a32; + x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_db_a16; + x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_db_a32; + x86_dynarec_opcodes_dc_a16 = dynarec_ops_fpu_dc_a16; + x86_dynarec_opcodes_dc_a32 = dynarec_ops_fpu_dc_a32; + x86_dynarec_opcodes_dd_a16 = dynarec_ops_fpu_dd_a16; + x86_dynarec_opcodes_dd_a32 = dynarec_ops_fpu_dd_a32; + x86_dynarec_opcodes_de_a16 = dynarec_ops_fpu_de_a16; + x86_dynarec_opcodes_de_a32 = dynarec_ops_fpu_de_a32; + x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_df_a16; + x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_df_a32; +#endif + x86_opcodes_d8_a16 = ops_fpu_d8_a16; + x86_opcodes_d8_a32 = ops_fpu_d8_a32; + x86_opcodes_d9_a16 = ops_fpu_d9_a16; + x86_opcodes_d9_a32 = ops_fpu_d9_a32; + x86_opcodes_da_a16 = ops_fpu_da_a16; + x86_opcodes_da_a32 = ops_fpu_da_a32; + x86_opcodes_db_a16 = ops_fpu_db_a16; + x86_opcodes_db_a32 = ops_fpu_db_a32; + x86_opcodes_dc_a16 = ops_fpu_dc_a16; + x86_opcodes_dc_a32 = ops_fpu_dc_a32; + x86_opcodes_dd_a16 = ops_fpu_dd_a16; + x86_opcodes_dd_a32 = ops_fpu_dd_a32; + x86_opcodes_de_a16 = ops_fpu_de_a16; + x86_opcodes_de_a32 = ops_fpu_de_a32; + x86_opcodes_df_a16 = ops_fpu_df_a16; + x86_opcodes_df_a32 = ops_fpu_df_a32; + } else { +#ifdef USE_DYNAREC + x86_dynarec_opcodes_d8_a16 = dynarec_ops_nofpu_a16; + x86_dynarec_opcodes_d8_a32 = dynarec_ops_nofpu_a32; + x86_dynarec_opcodes_d9_a16 = dynarec_ops_nofpu_a16; + x86_dynarec_opcodes_d9_a32 = dynarec_ops_nofpu_a32; + x86_dynarec_opcodes_da_a16 = dynarec_ops_nofpu_a16; + x86_dynarec_opcodes_da_a32 = dynarec_ops_nofpu_a32; + x86_dynarec_opcodes_db_a16 = dynarec_ops_nofpu_a16; + x86_dynarec_opcodes_db_a32 = dynarec_ops_nofpu_a32; + x86_dynarec_opcodes_dc_a16 = dynarec_ops_nofpu_a16; + x86_dynarec_opcodes_dc_a32 = dynarec_ops_nofpu_a32; + x86_dynarec_opcodes_dd_a16 = dynarec_ops_nofpu_a16; + x86_dynarec_opcodes_dd_a32 = dynarec_ops_nofpu_a32; + x86_dynarec_opcodes_de_a16 = dynarec_ops_nofpu_a16; + x86_dynarec_opcodes_de_a32 = dynarec_ops_nofpu_a32; + x86_dynarec_opcodes_df_a16 = dynarec_ops_nofpu_a16; + x86_dynarec_opcodes_df_a32 = dynarec_ops_nofpu_a32; +#endif + x86_opcodes_d8_a16 = ops_nofpu_a16; + x86_opcodes_d8_a32 = ops_nofpu_a32; + x86_opcodes_d9_a16 = ops_nofpu_a16; + x86_opcodes_d9_a32 = ops_nofpu_a32; + x86_opcodes_da_a16 = ops_nofpu_a16; + x86_opcodes_da_a32 = ops_nofpu_a32; + x86_opcodes_db_a16 = ops_nofpu_a16; + x86_opcodes_db_a32 = ops_nofpu_a32; + x86_opcodes_dc_a16 = ops_nofpu_a16; + x86_opcodes_dc_a32 = ops_nofpu_a32; + x86_opcodes_dd_a16 = ops_nofpu_a16; + x86_opcodes_dd_a32 = ops_nofpu_a32; + x86_opcodes_de_a16 = ops_nofpu_a16; + x86_opcodes_de_a32 = ops_nofpu_a32; + x86_opcodes_df_a16 = ops_nofpu_a16; + x86_opcodes_df_a32 = ops_nofpu_a32; + } + +#ifdef USE_DYNAREC + codegen_timing_set(&codegen_timing_486); +#endif + + memset(&msr, 0, sizeof(msr)); + + timing_misaligned = 0; + cpu_cyrix_alignment = 0; + cpu_CR4_mask = 0; + + switch (cpu_s->cpu_type) { + case CPU_8088: + case CPU_8086: + break; + + case CPU_286: +#ifdef USE_DYNAREC + x86_setopcodes(ops_286, ops_286_0f, dynarec_ops_286, dynarec_ops_286_0f); #else - is_cx6x86 = 0; + x86_setopcodes(ops_286, ops_286_0f); #endif - hasfpu = (fpu_type != FPU_NONE); - 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); - cpu_isintel = !strcmp(cpu_f->manufacturer, "Intel"); - cpu_iscyrix = (cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_486DLC || cpu_s->cpu_type == CPU_Cx486S || cpu_s->cpu_type == CPU_Cx486DX || cpu_s->cpu_type == CPU_Cx486DX2 || cpu_s->cpu_type == CPU_Cx486DX4 || cpu_s->cpu_type == CPU_Cx5x86 || cpu_s->cpu_type == CPU_Cx6x86 || cpu_s->cpu_type == CPU_Cx6x86MX || cpu_s->cpu_type == CPU_Cx6x86L || cpu_s->cpu_type == CPU_CxGX1); - - cpu_16bitbus = (cpu_s->cpu_type == CPU_286 || cpu_s->cpu_type == CPU_386SX || cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_IBM386SLC || cpu_s->cpu_type == CPU_IBM486SLC ); - cpu_64bitbus = (cpu_s->cpu_type >= CPU_WINCHIP); - - if (cpu_s->multi) - cpu_busspeed = cpu_s->rspeed / cpu_s->multi; - else - cpu_busspeed = cpu_s->rspeed; - cpu_multi = (int) ceil(cpu_s->multi); - cpu_dmulti = cpu_s->multi; - ccr0 = ccr1 = ccr2 = ccr3 = ccr4 = ccr5 = ccr6 = 0; - - - - cpu_update_waitstates(); - - isa_cycles = cpu_s->atclk_div; - - if (cpu_s->rspeed <= 8000000) - cpu_rom_prefetch_cycles = cpu_mem_prefetch_cycles; - else - cpu_rom_prefetch_cycles = cpu_s->rspeed / 1000000; - - cpu_set_isa_pci_div(0); - cpu_set_pci_speed(0); - cpu_set_agp_speed(0); - - if (cpu_iscyrix) - io_sethandler(0x0022, 0x0002, cpu_read, NULL, NULL, cpu_write, NULL, NULL, NULL); - else - io_removehandler(0x0022, 0x0002, cpu_read, NULL, NULL, cpu_write, NULL, NULL, NULL); - - if (hasfpu) { - io_sethandler(0x00f0, 0x000f, cpu_read, NULL, NULL, cpu_write, NULL, NULL, NULL); - io_sethandler(0xf007, 0x0001, cpu_read, NULL, NULL, cpu_write, NULL, NULL, NULL); - } else { - io_removehandler(0x00f0, 0x000f, cpu_read, NULL, NULL, cpu_write, NULL, NULL, NULL); - io_removehandler(0xf007, 0x0001, cpu_read, NULL, NULL, cpu_write, NULL, NULL, NULL); - } + if (fpu_type == FPU_287) { #ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_386_0f, dynarec_ops_386, dynarec_ops_386_0f); -#else - x86_setopcodes(ops_386, ops_386_0f); + x86_dynarec_opcodes_d9_a16 = dynarec_ops_fpu_287_d9_a16; + x86_dynarec_opcodes_d9_a32 = dynarec_ops_fpu_287_d9_a32; + x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_287_da_a16; + x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_287_da_a32; + x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_287_db_a16; + x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_287_db_a32; + x86_dynarec_opcodes_dc_a16 = dynarec_ops_fpu_287_dc_a16; + x86_dynarec_opcodes_dc_a32 = dynarec_ops_fpu_287_dc_a32; + x86_dynarec_opcodes_dd_a16 = dynarec_ops_fpu_287_dd_a16; + x86_dynarec_opcodes_dd_a32 = dynarec_ops_fpu_287_dd_a32; + x86_dynarec_opcodes_de_a16 = dynarec_ops_fpu_287_de_a16; + x86_dynarec_opcodes_de_a32 = dynarec_ops_fpu_287_de_a32; + x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_287_df_a16; + x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_287_df_a32; #endif - x86_opcodes_REPE = ops_REPE; - x86_opcodes_REPNE = ops_REPNE; - x86_opcodes_3DNOW = ops_3DNOW; -#ifdef USE_DYNAREC - x86_dynarec_opcodes_REPE = dynarec_ops_REPE; - x86_dynarec_opcodes_REPNE = dynarec_ops_REPNE; - x86_dynarec_opcodes_3DNOW = dynarec_ops_3DNOW; -#endif - -#ifdef USE_DYNAREC - if (hasfpu) - { - x86_dynarec_opcodes_d8_a16 = dynarec_ops_fpu_d8_a16; - x86_dynarec_opcodes_d8_a32 = dynarec_ops_fpu_d8_a32; - x86_dynarec_opcodes_d9_a16 = dynarec_ops_fpu_d9_a16; - x86_dynarec_opcodes_d9_a32 = dynarec_ops_fpu_d9_a32; - x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_da_a16; - x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_da_a32; - x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_db_a16; - x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_db_a32; - x86_dynarec_opcodes_dc_a16 = dynarec_ops_fpu_dc_a16; - x86_dynarec_opcodes_dc_a32 = dynarec_ops_fpu_dc_a32; - x86_dynarec_opcodes_dd_a16 = dynarec_ops_fpu_dd_a16; - x86_dynarec_opcodes_dd_a32 = dynarec_ops_fpu_dd_a32; - x86_dynarec_opcodes_de_a16 = dynarec_ops_fpu_de_a16; - x86_dynarec_opcodes_de_a32 = dynarec_ops_fpu_de_a32; - x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_df_a16; - x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_df_a32; - } - else - { - x86_dynarec_opcodes_d8_a16 = dynarec_ops_nofpu_a16; - x86_dynarec_opcodes_d8_a32 = dynarec_ops_nofpu_a32; - x86_dynarec_opcodes_d9_a16 = dynarec_ops_nofpu_a16; - x86_dynarec_opcodes_d9_a32 = dynarec_ops_nofpu_a32; - x86_dynarec_opcodes_da_a16 = dynarec_ops_nofpu_a16; - x86_dynarec_opcodes_da_a32 = dynarec_ops_nofpu_a32; - x86_dynarec_opcodes_db_a16 = dynarec_ops_nofpu_a16; - x86_dynarec_opcodes_db_a32 = dynarec_ops_nofpu_a32; - x86_dynarec_opcodes_dc_a16 = dynarec_ops_nofpu_a16; - x86_dynarec_opcodes_dc_a32 = dynarec_ops_nofpu_a32; - x86_dynarec_opcodes_dd_a16 = dynarec_ops_nofpu_a16; - x86_dynarec_opcodes_dd_a32 = dynarec_ops_nofpu_a32; - x86_dynarec_opcodes_de_a16 = dynarec_ops_nofpu_a16; - x86_dynarec_opcodes_de_a32 = dynarec_ops_nofpu_a32; - x86_dynarec_opcodes_df_a16 = dynarec_ops_nofpu_a16; - x86_dynarec_opcodes_df_a32 = dynarec_ops_nofpu_a32; - } - codegen_timing_set(&codegen_timing_486); -#endif - - if (hasfpu) - { - x86_opcodes_d8_a16 = ops_fpu_d8_a16; - x86_opcodes_d8_a32 = ops_fpu_d8_a32; - x86_opcodes_d9_a16 = ops_fpu_d9_a16; - x86_opcodes_d9_a32 = ops_fpu_d9_a32; - x86_opcodes_da_a16 = ops_fpu_da_a16; - x86_opcodes_da_a32 = ops_fpu_da_a32; - x86_opcodes_db_a16 = ops_fpu_db_a16; - x86_opcodes_db_a32 = ops_fpu_db_a32; - x86_opcodes_dc_a16 = ops_fpu_dc_a16; - x86_opcodes_dc_a32 = ops_fpu_dc_a32; - x86_opcodes_dd_a16 = ops_fpu_dd_a16; - x86_opcodes_dd_a32 = ops_fpu_dd_a32; - x86_opcodes_de_a16 = ops_fpu_de_a16; - x86_opcodes_de_a32 = ops_fpu_de_a32; - x86_opcodes_df_a16 = ops_fpu_df_a16; - x86_opcodes_df_a32 = ops_fpu_df_a32; - } - else - { - x86_opcodes_d8_a16 = ops_nofpu_a16; - x86_opcodes_d8_a32 = ops_nofpu_a32; - x86_opcodes_d9_a16 = ops_nofpu_a16; - x86_opcodes_d9_a32 = ops_nofpu_a32; - x86_opcodes_da_a16 = ops_nofpu_a16; - x86_opcodes_da_a32 = ops_nofpu_a32; - x86_opcodes_db_a16 = ops_nofpu_a16; - x86_opcodes_db_a32 = ops_nofpu_a32; - x86_opcodes_dc_a16 = ops_nofpu_a16; - x86_opcodes_dc_a32 = ops_nofpu_a32; - x86_opcodes_dd_a16 = ops_nofpu_a16; - x86_opcodes_dd_a32 = ops_nofpu_a32; - x86_opcodes_de_a16 = ops_nofpu_a16; - x86_opcodes_de_a32 = ops_nofpu_a32; - x86_opcodes_df_a16 = ops_nofpu_a16; - x86_opcodes_df_a32 = ops_nofpu_a32; - } - - memset(&msr, 0, sizeof(msr)); - - timing_misaligned = 0; - cpu_cyrix_alignment = 0; - cpu_CR4_mask = 0; - - switch (cpu_s->cpu_type) - { - case CPU_8088: - case CPU_8086: - break; - - case CPU_286: -#ifdef USE_DYNAREC - x86_setopcodes(ops_286, ops_286_0f, dynarec_ops_286, dynarec_ops_286_0f); -#else - x86_setopcodes(ops_286, ops_286_0f); -#endif - if (fpu_type == FPU_287) - { -#ifdef USE_DYNAREC - x86_dynarec_opcodes_d9_a16 = dynarec_ops_fpu_287_d9_a16; - x86_dynarec_opcodes_d9_a32 = dynarec_ops_fpu_287_d9_a32; - x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_287_da_a16; - x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_287_da_a32; - x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_287_db_a16; - x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_287_db_a32; - x86_dynarec_opcodes_dc_a16 = dynarec_ops_fpu_287_dc_a16; - x86_dynarec_opcodes_dc_a32 = dynarec_ops_fpu_287_dc_a32; - x86_dynarec_opcodes_dd_a16 = dynarec_ops_fpu_287_dd_a16; - x86_dynarec_opcodes_dd_a32 = dynarec_ops_fpu_287_dd_a32; - x86_dynarec_opcodes_de_a16 = dynarec_ops_fpu_287_de_a16; - x86_dynarec_opcodes_de_a32 = dynarec_ops_fpu_287_de_a32; - x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_287_df_a16; - x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_287_df_a32; -#endif - x86_opcodes_d9_a16 = ops_fpu_287_d9_a16; - x86_opcodes_d9_a32 = ops_fpu_287_d9_a32; - x86_opcodes_da_a16 = ops_fpu_287_da_a16; - x86_opcodes_da_a32 = ops_fpu_287_da_a32; - x86_opcodes_db_a16 = ops_fpu_287_db_a16; - x86_opcodes_db_a32 = ops_fpu_287_db_a32; - x86_opcodes_dc_a16 = ops_fpu_287_dc_a16; - x86_opcodes_dc_a32 = ops_fpu_287_dc_a32; - x86_opcodes_dd_a16 = ops_fpu_287_dd_a16; - x86_opcodes_dd_a32 = ops_fpu_287_dd_a32; - x86_opcodes_de_a16 = ops_fpu_287_de_a16; - x86_opcodes_de_a32 = ops_fpu_287_de_a32; - x86_opcodes_df_a16 = ops_fpu_287_df_a16; - x86_opcodes_df_a32 = ops_fpu_287_df_a32; + x86_opcodes_d9_a16 = ops_fpu_287_d9_a16; + x86_opcodes_d9_a32 = ops_fpu_287_d9_a32; + x86_opcodes_da_a16 = ops_fpu_287_da_a16; + x86_opcodes_da_a32 = ops_fpu_287_da_a32; + x86_opcodes_db_a16 = ops_fpu_287_db_a16; + x86_opcodes_db_a32 = ops_fpu_287_db_a32; + x86_opcodes_dc_a16 = ops_fpu_287_dc_a16; + x86_opcodes_dc_a32 = ops_fpu_287_dc_a32; + x86_opcodes_dd_a16 = ops_fpu_287_dd_a16; + x86_opcodes_dd_a32 = ops_fpu_287_dd_a32; + x86_opcodes_de_a16 = ops_fpu_287_de_a16; + x86_opcodes_de_a32 = ops_fpu_287_de_a32; + x86_opcodes_df_a16 = ops_fpu_287_df_a16; + x86_opcodes_df_a32 = ops_fpu_287_df_a32; } - timing_rr = 2; /*register dest - register src*/ - timing_rm = 7; /*register dest - memory src*/ - timing_mr = 7; /*memory dest - register src*/ - timing_mm = 7; /*memory dest - memory src*/ - timing_rml = 9; /*register dest - memory src long*/ - timing_mrl = 11; /*memory dest - register src long*/ - timing_mml = 11; /*memory dest - memory src*/ - timing_bt = 7-3; /*branch taken*/ - timing_bnt = 3; /*branch not taken*/ - timing_int = 0; - timing_int_rm = 23; - timing_int_v86 = 0; - timing_int_pm = 40; - timing_int_pm_outer = 78; - timing_iret_rm = 17; - timing_iret_v86 = 0; - timing_iret_pm = 31; - timing_iret_pm_outer = 55; - timing_call_rm = 13; - timing_call_pm = 26; - timing_call_pm_gate = 52; - timing_call_pm_gate_inner = 82; - timing_retf_rm = 15; - timing_retf_pm = 25; - timing_retf_pm_outer = 55; - timing_jmp_rm = 11; - timing_jmp_pm = 23; - timing_jmp_pm_gate = 38; - break; - - case CPU_IBM486SLC: - case CPU_IBM386SLC: + + timing_rr = 2; /* register dest - register src */ + timing_rm = 7; /* register dest - memory src */ + timing_mr = 7; /* memory dest - register src */ + timing_mm = 7; /* memory dest - memory src */ + timing_rml = 9; /* register dest - memory src long */ + timing_mrl = 11; /* memory dest - register src long */ + timing_mml = 11; /* memory dest - memory src */ + timing_bt = 4; /* branch taken */ + timing_bnt = 3; /* branch not taken */ + + timing_int = 0; + timing_int_rm = 23; + timing_int_v86 = 0; + timing_int_pm = 40; + timing_int_pm_outer = 78; + timing_iret_rm = 17; + timing_iret_v86 = 0; + timing_iret_pm = 31; + timing_iret_pm_outer = 55; + timing_call_rm = 13; + timing_call_pm = 26; + timing_call_pm_gate = 52; + timing_call_pm_gate_inner = 82; + timing_retf_rm = 15; + timing_retf_pm = 25; + timing_retf_pm_outer = 55; + timing_jmp_rm = 11; + timing_jmp_pm = 23; + timing_jmp_pm_gate = 38; + break; + + case CPU_IBM486SLC: + case CPU_IBM386SLC: + case CPU_IBM486BL: #ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_ibm486_0f, dynarec_ops_386, dynarec_ops_ibm486_0f); + x86_setopcodes(ops_386, ops_ibm486_0f, dynarec_ops_386, dynarec_ops_ibm486_0f); #else - x86_setopcodes(ops_386, ops_ibm486_0f); + x86_setopcodes(ops_386, ops_ibm486_0f); #endif - cpu_features = CPU_FEATURE_MSR; - case CPU_386SX: - timing_rr = 2; /*register dest - register src*/ - timing_rm = 6; /*register dest - memory src*/ - timing_mr = 7; /*memory dest - register src*/ - timing_mm = 6; /*memory dest - memory src*/ - timing_rml = 8; /*register dest - memory src long*/ - timing_mrl = 11; /*memory dest - register src long*/ - timing_mml = 10; /*memory dest - memory src*/ - timing_bt = 7-3; /*branch taken*/ - timing_bnt = 3; /*branch not taken*/ - timing_int = 0; - timing_int_rm = 37; - timing_int_v86 = 59; - timing_int_pm = 99; - timing_int_pm_outer = 119; - timing_iret_rm = 22; - timing_iret_v86 = 60; - timing_iret_pm = 38; - timing_iret_pm_outer = 82; - timing_call_rm = 17; - timing_call_pm = 34; - timing_call_pm_gate = 52; - timing_call_pm_gate_inner = 86; - timing_retf_rm = 18; - timing_retf_pm = 32; - timing_retf_pm_outer = 68; - timing_jmp_rm = 12; - timing_jmp_pm = 27; - timing_jmp_pm_gate = 45; - break; - - case CPU_IBM486BL: + cpu_features = CPU_FEATURE_MSR; + /* FALLTHROUGH */ + case CPU_386SX: + case CPU_386DX: + if (fpu_type == FPU_287) { /* In case we get Deskpro 386 emulation */ #ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_ibm486_0f, dynarec_ops_386, dynarec_ops_ibm486_0f); + x86_dynarec_opcodes_d9_a16 = dynarec_ops_fpu_287_d9_a16; + x86_dynarec_opcodes_d9_a32 = dynarec_ops_fpu_287_d9_a32; + x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_287_da_a16; + x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_287_da_a32; + x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_287_db_a16; + x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_287_db_a32; + x86_dynarec_opcodes_dc_a16 = dynarec_ops_fpu_287_dc_a16; + x86_dynarec_opcodes_dc_a32 = dynarec_ops_fpu_287_dc_a32; + x86_dynarec_opcodes_dd_a16 = dynarec_ops_fpu_287_dd_a16; + x86_dynarec_opcodes_dd_a32 = dynarec_ops_fpu_287_dd_a32; + x86_dynarec_opcodes_de_a16 = dynarec_ops_fpu_287_de_a16; + x86_dynarec_opcodes_de_a32 = dynarec_ops_fpu_287_de_a32; + x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_287_df_a16; + x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_287_df_a32; +#endif + x86_opcodes_d9_a16 = ops_fpu_287_d9_a16; + x86_opcodes_d9_a32 = ops_fpu_287_d9_a32; + x86_opcodes_da_a16 = ops_fpu_287_da_a16; + x86_opcodes_da_a32 = ops_fpu_287_da_a32; + x86_opcodes_db_a16 = ops_fpu_287_db_a16; + x86_opcodes_db_a32 = ops_fpu_287_db_a32; + x86_opcodes_dc_a16 = ops_fpu_287_dc_a16; + x86_opcodes_dc_a32 = ops_fpu_287_dc_a32; + x86_opcodes_dd_a16 = ops_fpu_287_dd_a16; + x86_opcodes_dd_a32 = ops_fpu_287_dd_a32; + x86_opcodes_de_a16 = ops_fpu_287_de_a16; + x86_opcodes_de_a32 = ops_fpu_287_de_a32; + x86_opcodes_df_a16 = ops_fpu_287_df_a16; + x86_opcodes_df_a32 = ops_fpu_287_df_a32; + } + + timing_rr = 2; /* register dest - register src */ + timing_rm = 6; /* register dest - memory src */ + timing_mr = 7; /* memory dest - register src */ + timing_mm = 6; /* memory dest - memory src */ + if (cpu_s->cpu_type >= CPU_386DX) { + timing_rml = 6; /* register dest - memory src long */ + timing_mrl = 7; /* memory dest - register src long */ + timing_mml = 6; /* memory dest - memory src */ + } else { + timing_rml = 8; /* register dest - memory src long */ + timing_mrl = 11; /* memory dest - register src long */ + timing_mml = 10; /* memory dest - memory src */ + } + timing_bt = 4; /* branch taken */ + timing_bnt = 3; /* branch not taken */ + + timing_int = 0; + timing_int_rm = 37; + timing_int_v86 = 59; + timing_int_pm = 99; + timing_int_pm_outer = 119; + timing_iret_rm = 22; + timing_iret_v86 = 60; + timing_iret_pm = 38; + timing_iret_pm_outer = 82; + timing_call_rm = 17; + timing_call_pm = 34; + timing_call_pm_gate = 52; + timing_call_pm_gate_inner = 86; + timing_retf_rm = 18; + timing_retf_pm = 32; + timing_retf_pm_outer = 68; + timing_jmp_rm = 12; + timing_jmp_pm = 27; + timing_jmp_pm_gate = 45; + break; + + case CPU_486SLC: +#ifdef USE_DYNAREC + x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f); #else - x86_setopcodes(ops_386, ops_ibm486_0f); + x86_setopcodes(ops_386, ops_486_0f); #endif - cpu_features = CPU_FEATURE_MSR; - case CPU_386DX: - if (fpu_type == FPU_287) /*In case we get Deskpro 386 emulation*/ - { + + timing_rr = 1; /* register dest - register src */ + timing_rm = 3; /* register dest - memory src */ + timing_mr = 5; /* memory dest - register src */ + timing_mm = 3; + timing_rml = 5; /* register dest - memory src long */ + timing_mrl = 7; /* memory dest - register src long */ + timing_mml = 7; + timing_bt = 5; /* branch taken */ + timing_bnt = 1; /* branch not taken */ + + timing_int = 4; /* unknown */ + timing_int_rm = 14; + timing_int_v86 = 82; + timing_int_pm = 49; + timing_int_pm_outer = 77; + timing_iret_rm = 14; + timing_iret_v86 = 66; + timing_iret_pm = 31; + timing_iret_pm_outer = 66; + timing_call_rm = 12; + timing_call_pm = 30; + timing_call_pm_gate = 41; + timing_call_pm_gate_inner = 83; + timing_retf_rm = 13; + timing_retf_pm = 26; + timing_retf_pm_outer = 61; + timing_jmp_rm = 9; + timing_jmp_pm = 26; + timing_jmp_pm_gate = 37; + timing_misaligned = 3; + break; + + case CPU_486DLC: #ifdef USE_DYNAREC - x86_dynarec_opcodes_d9_a16 = dynarec_ops_fpu_287_d9_a16; - x86_dynarec_opcodes_d9_a32 = dynarec_ops_fpu_287_d9_a32; - x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_287_da_a16; - x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_287_da_a32; - x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_287_db_a16; - x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_287_db_a32; - x86_dynarec_opcodes_dc_a16 = dynarec_ops_fpu_287_dc_a16; - x86_dynarec_opcodes_dc_a32 = dynarec_ops_fpu_287_dc_a32; - x86_dynarec_opcodes_dd_a16 = dynarec_ops_fpu_287_dd_a16; - x86_dynarec_opcodes_dd_a32 = dynarec_ops_fpu_287_dd_a32; - x86_dynarec_opcodes_de_a16 = dynarec_ops_fpu_287_de_a16; - x86_dynarec_opcodes_de_a32 = dynarec_ops_fpu_287_de_a32; - x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_287_df_a16; - x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_287_df_a32; -#endif - x86_opcodes_d9_a16 = ops_fpu_287_d9_a16; - x86_opcodes_d9_a32 = ops_fpu_287_d9_a32; - x86_opcodes_da_a16 = ops_fpu_287_da_a16; - x86_opcodes_da_a32 = ops_fpu_287_da_a32; - x86_opcodes_db_a16 = ops_fpu_287_db_a16; - x86_opcodes_db_a32 = ops_fpu_287_db_a32; - x86_opcodes_dc_a16 = ops_fpu_287_dc_a16; - x86_opcodes_dc_a32 = ops_fpu_287_dc_a32; - x86_opcodes_dd_a16 = ops_fpu_287_dd_a16; - x86_opcodes_dd_a32 = ops_fpu_287_dd_a32; - x86_opcodes_de_a16 = ops_fpu_287_de_a16; - x86_opcodes_de_a32 = ops_fpu_287_de_a32; - x86_opcodes_df_a16 = ops_fpu_287_df_a16; - x86_opcodes_df_a32 = ops_fpu_287_df_a32; - } - timing_rr = 2; /*register dest - register src*/ - timing_rm = 6; /*register dest - memory src*/ - timing_mr = 7; /*memory dest - register src*/ - timing_mm = 6; /*memory dest - memory src*/ - timing_rml = 6; /*register dest - memory src long*/ - timing_mrl = 7; /*memory dest - register src long*/ - timing_mml = 6; /*memory dest - memory src*/ - timing_bt = 7-3; /*branch taken*/ - timing_bnt = 3; /*branch not taken*/ - timing_int = 0; - timing_int_rm = 37; - timing_int_v86 = 59; - timing_int_pm = 99; - timing_int_pm_outer = 119; - timing_iret_rm = 22; - timing_iret_v86 = 60; - timing_iret_pm = 38; - timing_iret_pm_outer = 82; - timing_call_rm = 17; - timing_call_pm = 34; - timing_call_pm_gate = 52; - timing_call_pm_gate_inner = 86; - timing_retf_rm = 18; - timing_retf_pm = 32; - timing_retf_pm_outer = 68; - timing_jmp_rm = 12; - timing_jmp_pm = 27; - timing_jmp_pm_gate = 45; - break; - - - case CPU_RAPIDCAD: -#ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f); + x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f); #else - x86_setopcodes(ops_386, ops_486_0f); + x86_setopcodes(ops_386, ops_486_0f); #endif - timing_rr = 1; /*register dest - register src*/ - timing_rm = 2; /*register dest - memory src*/ - timing_mr = 3; /*memory dest - register src*/ - timing_mm = 3; - timing_rml = 2; /*register dest - memory src long*/ - timing_mrl = 3; /*memory dest - register src long*/ - timing_mml = 3; - timing_bt = 3-1; /*branch taken*/ - timing_bnt = 1; /*branch not taken*/ - timing_int = 4; - timing_int_rm = 26; - timing_int_v86 = 82; - timing_int_pm = 44; - timing_int_pm_outer = 71; - timing_iret_rm = 15; - timing_iret_v86 = 36; /*unknown*/ - timing_iret_pm = 20; - timing_iret_pm_outer = 36; - timing_call_rm = 18; - timing_call_pm = 20; - timing_call_pm_gate = 35; - timing_call_pm_gate_inner = 69; - timing_retf_rm = 13; - timing_retf_pm = 17; - timing_retf_pm_outer = 35; - timing_jmp_rm = 17; - timing_jmp_pm = 19; - timing_jmp_pm_gate = 32; - timing_misaligned = 3; - break; - - case CPU_486SLC: -#ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f); -#else - x86_setopcodes(ops_386, ops_486_0f); -#endif - timing_rr = 1; /*register dest - register src*/ - timing_rm = 3; /*register dest - memory src*/ - timing_mr = 5; /*memory dest - register src*/ - timing_mm = 3; - timing_rml = 5; /*register dest - memory src long*/ - timing_mrl = 7; /*memory dest - register src long*/ - timing_mml = 7; - timing_bt = 6-1; /*branch taken*/ - timing_bnt = 1; /*branch not taken*/ - /*unknown*/ - timing_int = 4; - timing_int_rm = 14; - timing_int_v86 = 82; - timing_int_pm = 49; - timing_int_pm_outer = 77; - timing_iret_rm = 14; - timing_iret_v86 = 66; - timing_iret_pm = 31; - timing_iret_pm_outer = 66; - timing_call_rm = 12; - timing_call_pm = 30; - timing_call_pm_gate = 41; - timing_call_pm_gate_inner = 83; - timing_retf_rm = 13; - timing_retf_pm = 26; - timing_retf_pm_outer = 61; - timing_jmp_rm = 9; - timing_jmp_pm = 26; - timing_jmp_pm_gate = 37; - timing_misaligned = 3; - break; - - case CPU_486DLC: -#ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f); -#else - x86_setopcodes(ops_386, ops_486_0f); -#endif - timing_rr = 1; /*register dest - register src*/ - timing_rm = 3; /*register dest - memory src*/ - timing_mr = 3; /*memory dest - register src*/ - timing_mm = 3; - timing_rml = 3; /*register dest - memory src long*/ - timing_mrl = 3; /*memory dest - register src long*/ - timing_mml = 3; - timing_bt = 6-1; /*branch taken*/ - timing_bnt = 1; /*branch not taken*/ - /*unknown*/ - timing_int = 4; - timing_int_rm = 14; - timing_int_v86 = 82; - timing_int_pm = 49; - timing_int_pm_outer = 77; - timing_iret_rm = 14; - timing_iret_v86 = 66; - timing_iret_pm = 31; - timing_iret_pm_outer = 66; - timing_call_rm = 12; - timing_call_pm = 30; - timing_call_pm_gate = 41; - timing_call_pm_gate_inner = 83; - timing_retf_rm = 13; - timing_retf_pm = 26; - timing_retf_pm_outer = 61; - timing_jmp_rm = 9; - timing_jmp_pm = 26; - timing_jmp_pm_gate = 37; - timing_misaligned = 3; - break; - - case CPU_iDX4: + + timing_rr = 1; /* register dest - register src */ + timing_rm = 3; /* register dest - memory src */ + timing_mr = 3; /* memory dest - register src */ + timing_mm = 3; + timing_rml = 3; /* register dest - memory src long */ + timing_mrl = 3; /* memory dest - register src long */ + timing_mml = 3; + timing_bt = 5; /* branch taken */ + timing_bnt = 1; /* branch not taken */ + + timing_int = 4; /* unknown */ + timing_int_rm = 14; + timing_int_v86 = 82; + timing_int_pm = 49; + timing_int_pm_outer = 77; + timing_iret_rm = 14; + timing_iret_v86 = 66; + timing_iret_pm = 31; + timing_iret_pm_outer = 66; + timing_call_rm = 12; + timing_call_pm = 30; + timing_call_pm_gate = 41; + timing_call_pm_gate_inner = 83; + timing_retf_rm = 13; + timing_retf_pm = 26; + timing_retf_pm_outer = 61; + timing_jmp_rm = 9; + timing_jmp_pm = 26; + timing_jmp_pm_gate = 37; + + timing_misaligned = 3; + break; + + case CPU_iDX4: cpu_features = CPU_FEATURE_CR4 | CPU_FEATURE_VME; cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_VME; - /*FALLTHROUGH*/ - case CPU_i486SX: - case CPU_i486SX2: - case CPU_i486DX: - case CPU_i486DX2: + /* FALLTHROUGH */ + case CPU_RAPIDCAD: + case CPU_i486SX: + case CPU_i486SX2: + case CPU_i486DX: + case CPU_i486DX2: + case CPU_Am486SX: + case CPU_Am486SX2: + case CPU_Am486DX: + case CPU_Am486DX2: + case CPU_Am486DX4: + case CPU_Am5x86: + /*AMD timing identical to Intel*/ #ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f); + x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f); #else - x86_setopcodes(ops_386, ops_486_0f); + x86_setopcodes(ops_386, ops_486_0f); #endif - timing_rr = 1; /*register dest - register src*/ - timing_rm = 2; /*register dest - memory src*/ - timing_mr = 3; /*memory dest - register src*/ - timing_mm = 3; - timing_rml = 2; /*register dest - memory src long*/ - timing_mrl = 3; /*memory dest - register src long*/ - timing_mml = 3; - timing_bt = 3-1; /*branch taken*/ - timing_bnt = 1; /*branch not taken*/ - timing_int = 4; - timing_int_rm = 26; - timing_int_v86 = 82; - timing_int_pm = 44; - timing_int_pm_outer = 71; - timing_iret_rm = 15; - timing_iret_v86 = 36; /*unknown*/ - timing_iret_pm = 20; - timing_iret_pm_outer = 36; - timing_call_rm = 18; - timing_call_pm = 20; - timing_call_pm_gate = 35; - timing_call_pm_gate_inner = 69; - timing_retf_rm = 13; - timing_retf_pm = 17; - timing_retf_pm_outer = 35; - timing_jmp_rm = 17; - timing_jmp_pm = 19; - timing_jmp_pm_gate = 32; - timing_misaligned = 3; - break; - case CPU_Am486SX: - case CPU_Am486SX2: - case CPU_Am486DX: - case CPU_Am486DX2: - case CPU_Am486DX4: - case CPU_Am5x86: - /*AMD timing identical to Intel*/ -#ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f); -#else - x86_setopcodes(ops_386, ops_486_0f); -#endif - timing_rr = 1; /*register dest - register src*/ - timing_rm = 2; /*register dest - memory src*/ - timing_mr = 3; /*memory dest - register src*/ - timing_mm = 3; - timing_rml = 2; /*register dest - memory src long*/ - timing_mrl = 3; /*memory dest - register src long*/ - timing_mml = 3; - timing_bt = 3-1; /*branch taken*/ - timing_bnt = 1; /*branch not taken*/ - timing_int = 4; - timing_int_rm = 26; - timing_int_v86 = 82; - timing_int_pm = 44; - timing_int_pm_outer = 71; - timing_iret_rm = 15; - timing_iret_v86 = 36; /*unknown*/ - timing_iret_pm = 20; - timing_iret_pm_outer = 36; - timing_call_rm = 18; - timing_call_pm = 20; - timing_call_pm_gate = 35; - timing_call_pm_gate_inner = 69; - timing_retf_rm = 13; - timing_retf_pm = 17; - timing_retf_pm_outer = 35; - timing_jmp_rm = 17; - timing_jmp_pm = 19; - timing_jmp_pm_gate = 32; - timing_misaligned = 3; - break; - - case CPU_Cx486S: - case CPU_Cx486DX: - case CPU_Cx486DX2: - case CPU_Cx486DX4: -#ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f); -#else - x86_setopcodes(ops_386, ops_486_0f); -#endif - timing_rr = 1; /*register dest - register src*/ - timing_rm = 3; /*register dest - memory src*/ - timing_mr = 3; /*memory dest - register src*/ - timing_mm = 3; - timing_rml = 3; /*register dest - memory src long*/ - timing_mrl = 3; /*memory dest - register src long*/ - timing_mml = 3; - timing_bt = 4-1; /*branch taken*/ - timing_bnt = 1; /*branch not taken*/ - timing_int = 4; - timing_int_rm = 14; - timing_int_v86 = 82; - timing_int_pm = 49; - timing_int_pm_outer = 77; - timing_iret_rm = 14; - timing_iret_v86 = 66; /*unknown*/ - timing_iret_pm = 31; - timing_iret_pm_outer = 66; - timing_call_rm = 12; - timing_call_pm = 30; - timing_call_pm_gate = 41; - timing_call_pm_gate_inner = 83; - timing_retf_rm = 13; - timing_retf_pm = 26; - timing_retf_pm_outer = 61; - timing_jmp_rm = 9; - timing_jmp_pm = 26; - timing_jmp_pm_gate = 37; - timing_misaligned = 3; - break; - - case CPU_Cx5x86: -#ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f); -#else - x86_setopcodes(ops_386, ops_486_0f); -#endif - timing_rr = 1; /*register dest - register src*/ - timing_rm = 1; /*register dest - memory src*/ - timing_mr = 2; /*memory dest - register src*/ - timing_mm = 2; - timing_rml = 1; /*register dest - memory src long*/ - timing_mrl = 2; /*memory dest - register src long*/ - timing_mml = 2; - timing_bt = 5-1; /*branch taken*/ - timing_bnt = 1; /*branch not taken*/ - timing_int = 0; - timing_int_rm = 9; - timing_int_v86 = 82; /*unknown*/ - timing_int_pm = 21; - timing_int_pm_outer = 32; - timing_iret_rm = 7; - timing_iret_v86 = 26; /*unknown*/ - timing_iret_pm = 10; - timing_iret_pm_outer = 26; - timing_call_rm = 4; - timing_call_pm = 15; - timing_call_pm_gate = 26; - timing_call_pm_gate_inner = 35; - timing_retf_rm = 4; - timing_retf_pm = 7; - timing_retf_pm_outer = 23; - timing_jmp_rm = 5; - timing_jmp_pm = 7; - timing_jmp_pm_gate = 17; - timing_misaligned = 2; - cpu_cyrix_alignment = 1; - break; + timing_rr = 1; /* register dest - register src */ + timing_rm = 2; /* register dest - memory src */ + timing_mr = 3; /* memory dest - register src */ + timing_mm = 3; + timing_rml = 2; /* register dest - memory src long */ + timing_mrl = 3; /* memory dest - register src long */ + timing_mml = 3; + timing_bt = 2; /* branch taken */ + timing_bnt = 1; /* branch not taken */ - case CPU_WINCHIP: + timing_int = 4; + timing_int_rm = 26; + timing_int_v86 = 82; + timing_int_pm = 44; + timing_int_pm_outer = 71; + timing_iret_rm = 15; + timing_iret_v86 = 36; /* unknown */ + timing_iret_pm = 20; + timing_iret_pm_outer = 36; + timing_call_rm = 18; + timing_call_pm = 20; + timing_call_pm_gate = 35; + timing_call_pm_gate_inner = 69; + timing_retf_rm = 13; + timing_retf_pm = 17; + timing_retf_pm_outer = 35; + timing_jmp_rm = 17; + timing_jmp_pm = 19; + timing_jmp_pm_gate = 32; + + timing_misaligned = 3; + break; + + case CPU_Cx486S: + case CPU_Cx486DX: + case CPU_Cx486DX2: + case CPU_Cx486DX4: #ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_winchip_0f, dynarec_ops_386, dynarec_ops_winchip_0f); + x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f); #else - x86_setopcodes(ops_386, ops_winchip_0f); + x86_setopcodes(ops_386, ops_486_0f); #endif - timing_rr = 1; /*register dest - register src*/ - timing_rm = 2; /*register dest - memory src*/ - timing_mr = 2; /*memory dest - register src*/ - timing_mm = 3; - timing_rml = 2; /*register dest - memory src long*/ - timing_mrl = 2; /*memory dest - register src long*/ - timing_mml = 3; - timing_bt = 3-1; /*branch taken*/ - timing_bnt = 1; /*branch not taken*/ - cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MMX | CPU_FEATURE_MSR | CPU_FEATURE_CR4; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE; + + timing_rr = 1; /* register dest - register src */ + timing_rm = 3; /* register dest - memory src */ + timing_mr = 3; /* memory dest - register src */ + timing_mm = 3; + timing_rml = 3; /* register dest - memory src long */ + timing_mrl = 3; /* memory dest - register src long */ + timing_mml = 3; + timing_bt = 3; /* branch taken */ + timing_bnt = 1; /* branch not taken */ + + timing_int = 4; + timing_int_rm = 14; + timing_int_v86 = 82; + timing_int_pm = 49; + timing_int_pm_outer = 77; + timing_iret_rm = 14; + timing_iret_v86 = 66; /* unknown */ + timing_iret_pm = 31; + timing_iret_pm_outer = 66; + timing_call_rm = 12; + timing_call_pm = 30; + timing_call_pm_gate = 41; + timing_call_pm_gate_inner = 83; + timing_retf_rm = 13; + timing_retf_pm = 26; + timing_retf_pm_outer = 61; + timing_jmp_rm = 9; + timing_jmp_pm = 26; + timing_jmp_pm_gate = 37; + + timing_misaligned = 3; + break; + + case CPU_Cx5x86: +#ifdef USE_DYNAREC + x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f); +#else + x86_setopcodes(ops_386, ops_486_0f); +#endif + + timing_rr = 1; /* register dest - register src */ + timing_rm = 1; /* register dest - memory src */ + timing_mr = 2; /* memory dest - register src */ + timing_mm = 2; + timing_rml = 1; /* register dest - memory src long */ + timing_mrl = 2; /* memory dest - register src long */ + timing_mml = 2; + timing_bt = 4; /* branch taken */ + timing_bnt = 1; /* branch not taken */ + + timing_int = 0; + timing_int_rm = 9; + timing_int_v86 = 82; /* unknown */ + timing_int_pm = 21; + timing_int_pm_outer = 32; + timing_iret_rm = 7; + timing_iret_v86 = 26; /* unknown */ + timing_iret_pm = 10; + timing_iret_pm_outer = 26; + timing_call_rm = 4; + timing_call_pm = 15; + timing_call_pm_gate = 26; + timing_call_pm_gate_inner = 35; + timing_retf_rm = 4; + timing_retf_pm = 7; + timing_retf_pm_outer = 23; + timing_jmp_rm = 5; + timing_jmp_pm = 7; + timing_jmp_pm_gate = 17; + + timing_misaligned = 2; + + cpu_cyrix_alignment = 1; + break; + + case CPU_WINCHIP: + case CPU_WINCHIP2: +#ifdef USE_DYNAREC + if (cpu_s->cpu_type == CPU_WINCHIP2) + x86_setopcodes(ops_386, ops_winchip2_0f, dynarec_ops_386, dynarec_ops_winchip2_0f); + else + x86_setopcodes(ops_386, ops_winchip_0f, dynarec_ops_386, dynarec_ops_winchip_0f); +#else + if (cpu_s->cpu_type == CPU_WINCHIP2) + x86_setopcodes(ops_386, ops_winchip2_0f); + else + x86_setopcodes(ops_386, ops_winchip_0f); +#endif + + timing_rr = 1; /* register dest - register src */ + timing_rm = 2; /* register dest - memory src */ + timing_mr = 2; /* memory dest - register src */ + timing_mm = 3; + timing_rml = 2; /* register dest - memory src long */ + timing_mrl = 2; /* memory dest - register src long */ + timing_mml = 3; + timing_bt = 2; /* branch taken */ + timing_bnt = 1; /* branch not taken */ + /*unknown*/ - timing_int_rm = 26; - timing_int_v86 = 82; - timing_int_pm = 44; - timing_int_pm_outer = 71; - timing_iret_rm = 7; - timing_iret_v86 = 26; - timing_iret_pm = 10; - timing_iret_pm_outer = 26; - timing_call_rm = 4; - timing_call_pm = 15; - timing_call_pm_gate = 26; - timing_call_pm_gate_inner = 35; - timing_retf_rm = 4; - timing_retf_pm = 7; - timing_retf_pm_outer = 23; - timing_jmp_rm = 5; - timing_jmp_pm = 7; - timing_jmp_pm_gate = 17; -#ifdef USE_DYNAREC - codegen_timing_set(&codegen_timing_winchip); -#endif - timing_misaligned = 2; - cpu_cyrix_alignment = 1; - break; + timing_int_rm = 26; + timing_int_v86 = 82; + timing_int_pm = 44; + timing_int_pm_outer = 71; + timing_iret_rm = 7; + timing_iret_v86 = 26; + timing_iret_pm = 10; + timing_iret_pm_outer = 26; + timing_call_rm = 4; + timing_call_pm = 15; + timing_call_pm_gate = 26; + timing_call_pm_gate_inner = 35; + timing_retf_rm = 4; + timing_retf_pm = 7; + timing_retf_pm_outer = 23; + timing_jmp_rm = 5; + timing_jmp_pm = 7; + timing_jmp_pm_gate = 17; + + timing_misaligned = 2; + + cpu_cyrix_alignment = 1; + + cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MMX | CPU_FEATURE_MSR | CPU_FEATURE_CR4; + if (cpu_s->cpu_type == CPU_WINCHIP2) + cpu_features |= CPU_FEATURE_3DNOW; + msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); + if (cpu_s->cpu_type == CPU_WINCHIP2) + msr.fcr |= (1 << 18) | (1 << 20); + cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE; - case CPU_WINCHIP2: -#ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_winchip2_0f, dynarec_ops_386, dynarec_ops_winchip2_0f); -#else - x86_setopcodes(ops_386, ops_winchip2_0f); -#endif - timing_rr = 1; /*register dest - register src*/ - timing_rm = 2; /*register dest - memory src*/ - timing_mr = 2; /*memory dest - register src*/ - timing_mm = 3; - timing_rml = 2; /*register dest - memory src long*/ - timing_mrl = 2; /*memory dest - register src long*/ - timing_mml = 3; - timing_bt = 3-1; /*branch taken*/ - timing_bnt = 1; /*branch not taken*/ - cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MMX | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_3DNOW; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 18) | (1 << 19) | (1 << 20) | (1 << 21); - cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE; - /*unknown*/ - timing_int_rm = 26; - timing_int_v86 = 82; - timing_int_pm = 44; - timing_int_pm_outer = 71; - timing_iret_rm = 7; - timing_iret_v86 = 26; - timing_iret_pm = 10; - timing_iret_pm_outer = 26; - timing_call_rm = 4; - timing_call_pm = 15; - timing_call_pm_gate = 26; - timing_call_pm_gate_inner = 35; - timing_retf_rm = 4; - timing_retf_pm = 7; - timing_retf_pm_outer = 23; - timing_jmp_rm = 5; - timing_jmp_pm = 7; - timing_jmp_pm_gate = 17; - timing_misaligned = 2; - cpu_cyrix_alignment = 1; #ifdef USE_DYNAREC - codegen_timing_set(&codegen_timing_winchip2); + if (cpu_s->cpu_type == CPU_WINCHIP2) + codegen_timing_set(&codegen_timing_winchip2); + else + codegen_timing_set(&codegen_timing_winchip); #endif - break; + break; - case CPU_P24T: - case CPU_PENTIUM: + case CPU_P24T: + case CPU_PENTIUM: + case CPU_PENTIUMMMX: #ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_pentium_0f, dynarec_ops_386, dynarec_ops_pentium_0f); + if (cpu_s->cpu_type == CPU_PENTIUMMMX) + x86_setopcodes(ops_386, ops_pentiummmx_0f, dynarec_ops_386, dynarec_ops_pentiummmx_0f); + else + x86_setopcodes(ops_386, ops_pentium_0f, dynarec_ops_386, dynarec_ops_pentium_0f); #else - x86_setopcodes(ops_386, ops_pentium_0f); + if (cpu_s->cpu_type == CPU_PENTIUMMMX) + x86_setopcodes(ops_386, ops_pentiummmx_0f); + else + x86_setopcodes(ops_386, ops_pentium_0f); #endif - timing_rr = 1; /*register dest - register src*/ - timing_rm = 2; /*register dest - memory src*/ - timing_mr = 3; /*memory dest - register src*/ - timing_mm = 3; - timing_rml = 2; /*register dest - memory src long*/ - timing_mrl = 3; /*memory dest - register src long*/ - timing_mml = 3; - timing_bt = 0; /*branch taken*/ - timing_bnt = 2; /*branch not taken*/ - timing_int = 6; - timing_int_rm = 11; - timing_int_v86 = 54; - timing_int_pm = 25; - timing_int_pm_outer = 42; - timing_iret_rm = 7; - timing_iret_v86 = 27; /*unknown*/ - timing_iret_pm = 10; - timing_iret_pm_outer = 27; - timing_call_rm = 4; - timing_call_pm = 4; - timing_call_pm_gate = 22; - timing_call_pm_gate_inner = 44; - timing_retf_rm = 4; - timing_retf_pm = 4; - timing_retf_pm_outer = 23; - timing_jmp_rm = 3; - timing_jmp_pm = 3; - timing_jmp_pm_gate = 18; - timing_misaligned = 3; - cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE; -#ifdef USE_DYNAREC - codegen_timing_set(&codegen_timing_pentium); -#endif - break; - case CPU_PENTIUMMMX: + timing_rr = 1; /* register dest - register src */ + timing_rm = 2; /* register dest - memory src */ + timing_mr = 3; /* memory dest - register src */ + timing_mm = 3; + timing_rml = 2; /* register dest - memory src long */ + timing_mrl = 3; /* memory dest - register src long */ + timing_mml = 3; + timing_bt = 0; /* branch taken */ + if (cpu_s->cpu_type == CPU_PENTIUMMMX) + timing_bnt = 1; /* branch not taken */ + else + timing_bnt = 2; /* branch not taken */ + + timing_int = 6; + timing_int_rm = 11; + timing_int_v86 = 54; + timing_int_pm = 25; + timing_int_pm_outer = 42; + timing_iret_rm = 7; + timing_iret_v86 = 27; /* unknown */ + timing_iret_pm = 10; + timing_iret_pm_outer = 27; + timing_call_rm = 4; + timing_call_pm = 4; + timing_call_pm_gate = 22; + timing_call_pm_gate_inner = 44; + timing_retf_rm = 4; + timing_retf_pm = 4; + timing_retf_pm_outer = 23; + timing_jmp_rm = 3; + timing_jmp_pm = 3; + timing_jmp_pm_gate = 18; + + timing_misaligned = 3; + + cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME; + if (cpu_s->cpu_type == CPU_PENTIUMMMX) + cpu_features |= CPU_FEATURE_MMX; + msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); + cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE; #ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_pentiummmx_0f, dynarec_ops_386, dynarec_ops_pentiummmx_0f); -#else - x86_setopcodes(ops_386, ops_pentiummmx_0f); + codegen_timing_set(&codegen_timing_pentium); #endif - timing_rr = 1; /*register dest - register src*/ - timing_rm = 2; /*register dest - memory src*/ - timing_mr = 3; /*memory dest - register src*/ - timing_mm = 3; - timing_rml = 2; /*register dest - memory src long*/ - timing_mrl = 3; /*memory dest - register src long*/ - timing_mml = 3; - timing_bt = 0; /*branch taken*/ - timing_bnt = 1; /*branch not taken*/ - timing_int = 6; - timing_int_rm = 11; - timing_int_v86 = 54; - timing_int_pm = 25; - timing_int_pm_outer = 42; - timing_iret_rm = 7; - timing_iret_v86 = 27; /*unknown*/ - timing_iret_pm = 10; - timing_iret_pm_outer = 27; - timing_call_rm = 4; - timing_call_pm = 4; - timing_call_pm_gate = 22; - timing_call_pm_gate_inner = 44; - timing_retf_rm = 4; - timing_retf_pm = 4; - timing_retf_pm_outer = 23; - timing_jmp_rm = 3; - timing_jmp_pm = 3; - timing_jmp_pm_gate = 18; - timing_misaligned = 3; - cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_MMX; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE; -#ifdef USE_DYNAREC - codegen_timing_set(&codegen_timing_pentium); -#endif - break; + break; #if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) - case CPU_Cx6x86: + case CPU_Cx6x86: + case CPU_Cx6x86L: + case CPU_CxGX1: + case CPU_Cx6x86MX: + if (cpu_s->cpu_type == CPU_Cx6x86MX) { #ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_c6x86_0f, dynarec_ops_386, dynarec_ops_c6x86_0f); -#else - x86_setopcodes(ops_386, ops_c6x86_0f); + x86_setopcodes(ops_386, ops_c6x86mx_0f, dynarec_ops_386, dynarec_ops_c6x86mx_0f); + x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_686_da_a16; + x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_686_da_a32; + x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_686_db_a16; + x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_686_db_a32; + x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_686_df_a16; + x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_686_df_a32; #endif - timing_rr = 1; /*register dest - register src*/ - timing_rm = 1; /*register dest - memory src*/ - timing_mr = 2; /*memory dest - register src*/ - timing_mm = 2; - timing_rml = 1; /*register dest - memory src long*/ - timing_mrl = 2; /*memory dest - register src long*/ - timing_mml = 2; - timing_bt = 0; /*branch taken*/ - timing_bnt = 2; /*branch not taken*/ - timing_int_rm = 9; - timing_int_v86 = 46; - timing_int_pm = 21; - timing_int_pm_outer = 32; - timing_iret_rm = 7; - timing_iret_v86 = 26; - timing_iret_pm = 10; - timing_iret_pm_outer = 26; - timing_call_rm = 3; - timing_call_pm = 4; - timing_call_pm_gate = 15; - timing_call_pm_gate_inner = 26; - timing_retf_rm = 4; - timing_retf_pm = 4; - timing_retf_pm_outer = 23; - timing_jmp_rm = 1; - timing_jmp_pm = 4; - timing_jmp_pm_gate = 14; - timing_misaligned = 2; - cpu_cyrix_alignment = 1; - cpu_features = CPU_FEATURE_RDTSC; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); -#ifdef USE_DYNAREC - codegen_timing_set(&codegen_timing_686); -#endif - CPUID = 0; /*Disabled on powerup by default*/ - break; + x86_opcodes_da_a16 = ops_fpu_686_da_a16; + x86_opcodes_da_a32 = ops_fpu_686_da_a32; + x86_opcodes_db_a16 = ops_fpu_686_db_a16; + x86_opcodes_db_a32 = ops_fpu_686_db_a32; + x86_opcodes_df_a16 = ops_fpu_686_df_a16; + x86_opcodes_df_a32 = ops_fpu_686_df_a32; + } - case CPU_Cx6x86L: #ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_pentium_0f, dynarec_ops_386, dynarec_ops_pentium_0f); + if (cpu_s->cpu_type == CPU_Cx6x86MX) + x86_setopcodes(ops_386, ops_c6x86mx_0f, dynarec_ops_386, dynarec_ops_c6x86mx_0f); + else if (cpu_s->cpu_type == CPU_Cx6x86L) + x86_setopcodes(ops_386, ops_pentium_0f, dynarec_ops_386, dynarec_ops_pentium_0f); + else + x86_setopcodes(ops_386, ops_c6x86_0f, dynarec_ops_386, dynarec_ops_c6x86_0f); #else - x86_setopcodes(ops_386, ops_pentium_0f); + if (cpu_s->cpu_type == CPU_Cx6x86MX) + x86_setopcodes(ops_386, ops_c6x86mx_0f); + else if (cpu_s->cpu_type == CPU_Cx6x86L) + x86_setopcodes(ops_386, ops_pentium_0f); + else + x86_setopcodes(ops_386, ops_c6x86_0f); #endif - timing_rr = 1; /*register dest - register src*/ - timing_rm = 1; /*register dest - memory src*/ - timing_mr = 2; /*memory dest - register src*/ - timing_mm = 2; - timing_rml = 1; /*register dest - memory src long*/ - timing_mrl = 2; /*memory dest - register src long*/ - timing_mml = 2; - timing_bt = 0; /*branch taken*/ - timing_bnt = 2; /*branch not taken*/ - timing_int_rm = 9; - timing_int_v86 = 46; - timing_int_pm = 21; - timing_int_pm_outer = 32; - timing_iret_rm = 7; - timing_iret_v86 = 26; - timing_iret_pm = 10; - timing_iret_pm_outer = 26; - timing_call_rm = 3; - timing_call_pm = 4; - timing_call_pm_gate = 15; - timing_call_pm_gate_inner = 26; - timing_retf_rm = 4; - timing_retf_pm = 4; - timing_retf_pm_outer = 23; - timing_jmp_rm = 1; - timing_jmp_pm = 4; - timing_jmp_pm_gate = 14; - timing_misaligned = 2; - cpu_cyrix_alignment = 1; - cpu_features = CPU_FEATURE_RDTSC; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); -#ifdef USE_DYNAREC - codegen_timing_set(&codegen_timing_686); -#endif - ccr4 = 0x80; - break; + timing_rr = 1; /* register dest - register src */ + timing_rm = 1; /* register dest - memory src */ + timing_mr = 2; /* memory dest - register src */ + timing_mm = 2; + timing_rml = 1; /* register dest - memory src long */ + timing_mrl = 2; /* memory dest - register src long */ + timing_mml = 2; + if (cpu_s->cpu_type == CPU_CxGX1) { + timing_bt = 4; /* branch taken */ + timing_bnt = 1; /* branch not taken */ + } else { + timing_bt = 0; /* branch taken */ + timing_bnt = 2; /* branch not taken */ + } - case CPU_CxGX1: -#ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_pentium_0f, dynarec_ops_386, dynarec_ops_pentium_0f); -#else - x86_setopcodes(ops_386, ops_pentium_0f); -#endif - timing_rr = 1; /*register dest - register src*/ - timing_rm = 1; /*register dest - memory src*/ - timing_mr = 2; /*memory dest - register src*/ - timing_mm = 2; - timing_rml = 1; /*register dest - memory src long*/ - timing_mrl = 2; /*memory dest - register src long*/ - timing_mml = 2; - timing_bt = 5-1; /*branch taken*/ - timing_bnt = 1; /*branch not taken*/ - timing_misaligned = 2; - cpu_cyrix_alignment = 1; - cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_PCE; -#ifdef USE_DYNAREC - codegen_timing_set(&codegen_timing_686); -#endif - break; + /* Make the CxGX1 share the timings with most other Cyrix C6x86's due to the real + ones still being unknown. */ + timing_int_rm = 9; + timing_int_v86 = 46; + timing_int_pm = 21; + timing_int_pm_outer = 32; + timing_iret_rm = 7; + timing_iret_v86 = 26; + timing_iret_pm = 10; + timing_iret_pm_outer = 26; + timing_call_rm = 3; + timing_call_pm = 4; + timing_call_pm_gate = 15; + timing_call_pm_gate_inner = 26; + timing_retf_rm = 4; + timing_retf_pm = 4; + timing_retf_pm_outer = 23; + timing_jmp_rm = 1; + timing_jmp_pm = 4; + timing_jmp_pm_gate = 14; + + timing_misaligned = 2; + + cpu_cyrix_alignment = 1; + + cpu_features = CPU_FEATURE_RDTSC; + if (cpu_s->cpu_type >= CPU_CxGX1) + cpu_features |= CPU_FEATURE_MSR | CPU_FEATURE_CR4; + if (cpu_s->cpu_type == CPU_Cx6x86MX) + cpu_features |= CPU_FEATURE_MMX; + msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); + if (cpu_s->cpu_type >= CPU_CxGX1) + cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_PCE; - - case CPU_Cx6x86MX: #ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_c6x86mx_0f, dynarec_ops_386, dynarec_ops_c6x86mx_0f); - x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_686_da_a16; - x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_686_da_a32; - x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_686_db_a16; - x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_686_db_a32; - x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_686_df_a16; - x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_686_df_a32; -#else - x86_setopcodes(ops_386, ops_c6x86mx_0f); + codegen_timing_set(&codegen_timing_686); #endif - x86_opcodes_da_a16 = ops_fpu_686_da_a16; - x86_opcodes_da_a32 = ops_fpu_686_da_a32; - x86_opcodes_db_a16 = ops_fpu_686_db_a16; - x86_opcodes_db_a32 = ops_fpu_686_db_a32; - x86_opcodes_df_a16 = ops_fpu_686_df_a16; - x86_opcodes_df_a32 = ops_fpu_686_df_a32; - timing_rr = 1; /*register dest - register src*/ - timing_rm = 1; /*register dest - memory src*/ - timing_mr = 2; /*memory dest - register src*/ - timing_mm = 2; - timing_rml = 1; /*register dest - memory src long*/ - timing_mrl = 2; /*memory dest - register src long*/ - timing_mml = 2; - timing_bt = 0; /*branch taken*/ - timing_bnt = 2; /*branch not taken*/ - timing_int_rm = 9; - timing_int_v86 = 46; - timing_int_pm = 21; - timing_int_pm_outer = 32; - timing_iret_rm = 7; - timing_iret_v86 = 26; - timing_iret_pm = 10; - timing_iret_pm_outer = 26; - timing_call_rm = 3; - timing_call_pm = 4; - timing_call_pm_gate = 15; - timing_call_pm_gate_inner = 26; - timing_retf_rm = 4; - timing_retf_pm = 4; - timing_retf_pm_outer = 23; - timing_jmp_rm = 1; - timing_jmp_pm = 4; - timing_jmp_pm_gate = 14; - timing_misaligned = 2; - cpu_cyrix_alignment = 1; - cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_MMX; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_PCE; -#ifdef USE_DYNAREC - codegen_timing_set(&codegen_timing_686); -#endif - ccr4 = 0x80; - break; + + if ((cpu_s->cpu_type == CPU_Cx6x86L) || (cpu_s->cpu_type == CPU_Cx6x86MX)) + ccr4 = 0x80; + else if (CPU_Cx6x86) + CPUID = 0; /* Disabled on powerup by default */ + break; #endif #if defined(DEV_BRANCH) && defined(USE_AMD_K5) - case CPU_K5: - case CPU_5K86: -#ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_pentiummmx_0f, dynarec_ops_386, dynarec_ops_pentiummmx_0f); -#else - x86_setopcodes(ops_386, ops_pentiummmx_0f); + case CPU_K5: + case CPU_5K86: #endif - timing_rr = 1; /*register dest - register src*/ - timing_rm = 2; /*register dest - memory src*/ - timing_mr = 3; /*memory dest - register src*/ - timing_mm = 3; - timing_rml = 2; /*register dest - memory src long*/ - timing_mrl = 3; /*memory dest - register src long*/ - timing_mml = 3; - timing_bt = 0; /*branch taken*/ - timing_bnt = 1; /*branch not taken*/ - timing_int = 6; - timing_int_rm = 11; - timing_int_v86 = 54; - timing_int_pm = 25; - timing_int_pm_outer = 42; - timing_iret_rm = 7; - timing_iret_v86 = 27; /*unknown*/ - timing_iret_pm = 10; - timing_iret_pm_outer = 27; - timing_call_rm = 4; - timing_call_pm = 4; - timing_call_pm_gate = 22; - timing_call_pm_gate_inner = 44; - timing_retf_rm = 4; - timing_retf_pm = 4; - timing_retf_pm_outer = 23; - timing_jmp_rm = 3; - timing_jmp_pm = 3; - timing_jmp_pm_gate = 18; - timing_misaligned = 3; - cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_MMX; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE; + case CPU_K6: + case CPU_K6_2: + case CPU_K6_2C: + case CPU_K6_3: + case CPU_K6_2P: + case CPU_K6_3P: #ifdef USE_DYNAREC - codegen_timing_set(&codegen_timing_k6); -#endif - break; -#endif - - case CPU_K6: -#ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_k6_0f, dynarec_ops_386, dynarec_ops_k6_0f); -#else - x86_setopcodes(ops_386, ops_k6_0f); -#endif - timing_rr = 1; /*register dest - register src*/ - timing_rm = 2; /*register dest - memory src*/ - timing_mr = 3; /*memory dest - register src*/ - timing_mm = 3; - timing_rml = 2; /*register dest - memory src long*/ - timing_mrl = 3; /*memory dest - register src long*/ - timing_mml = 3; - timing_bt = 0; /*branch taken*/ - timing_bnt = 1; /*branch not taken*/ - timing_int = 6; - timing_int_rm = 11; - timing_int_v86 = 54; - timing_int_pm = 25; - timing_int_pm_outer = 42; - timing_iret_rm = 7; - timing_iret_v86 = 27; /*unknown*/ - timing_iret_pm = 10; - timing_iret_pm_outer = 27; - timing_call_rm = 4; - timing_call_pm = 4; - timing_call_pm_gate = 22; - timing_call_pm_gate_inner = 44; - timing_retf_rm = 4; - timing_retf_pm = 4; - timing_retf_pm_outer = 23; - timing_jmp_rm = 3; - timing_jmp_pm = 3; - timing_jmp_pm_gate = 18; - timing_misaligned = 3; - cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_MMX; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE; -#ifdef USE_DYNAREC - codegen_timing_set(&codegen_timing_k6); -#endif - break; - - case CPU_K6_2: - case CPU_K6_2C: - case CPU_K6_3: - case CPU_K6_2P: - case CPU_K6_3P: -#ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_k62_0f, dynarec_ops_386, dynarec_ops_k62_0f); -#else - x86_setopcodes(ops_386, ops_k62_0f); -#endif - timing_rr = 1; /*register dest - register src*/ - timing_rm = 2; /*register dest - memory src*/ - timing_mr = 3; /*memory dest - register src*/ - timing_mm = 3; - timing_rml = 2; /*register dest - memory src long*/ - timing_mrl = 3; /*memory dest - register src long*/ - timing_mml = 3; - timing_bt = 0; /*branch taken*/ - timing_bnt = 1; /*branch not taken*/ - timing_int = 6; - timing_int_rm = 11; - timing_int_v86 = 54; - timing_int_pm = 25; - timing_int_pm_outer = 42; - timing_iret_rm = 7; - timing_iret_v86 = 27; /*unknown*/ - timing_iret_pm = 10; - timing_iret_pm_outer = 27; - timing_call_rm = 4; - timing_call_pm = 4; - timing_call_pm_gate = 22; - timing_call_pm_gate_inner = 44; - timing_retf_rm = 4; - timing_retf_pm = 4; - timing_retf_pm_outer = 23; - timing_jmp_rm = 3; - timing_jmp_pm = 3; - timing_jmp_pm_gate = 18; - timing_misaligned = 3; - cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_MMX | CPU_FEATURE_3DNOW; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE; -#ifdef USE_DYNAREC - codegen_timing_set(&codegen_timing_k6); -#endif - break; - - case CPU_PENTIUMPRO: -#ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_pentiumpro_0f, dynarec_ops_386, dynarec_ops_pentiumpro_0f); - x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_686_da_a16; - x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_686_da_a32; - x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_686_db_a16; - x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_686_db_a32; - x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_686_df_a16; - x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_686_df_a32; -#else - x86_setopcodes(ops_386, ops_pentiumpro_0f); -#endif - x86_opcodes_da_a16 = ops_fpu_686_da_a16; - x86_opcodes_da_a32 = ops_fpu_686_da_a32; - x86_opcodes_db_a16 = ops_fpu_686_db_a16; - x86_opcodes_db_a32 = ops_fpu_686_db_a32; - x86_opcodes_df_a16 = ops_fpu_686_df_a16; - x86_opcodes_df_a32 = ops_fpu_686_df_a32; - timing_rr = 1; /*register dest - register src*/ - timing_rm = 2; /*register dest - memory src*/ - timing_mr = 3; /*memory dest - register src*/ - timing_mm = 3; - timing_rml = 2; /*register dest - memory src long*/ - timing_mrl = 3; /*memory dest - register src long*/ - timing_mml = 3; - timing_bt = 0; /*branch taken*/ - timing_bnt = 1; /*branch not taken*/ - timing_int = 6; - timing_int_rm = 11; - timing_int_v86 = 54; - timing_int_pm = 25; - timing_int_pm_outer = 42; - timing_iret_rm = 7; - timing_iret_v86 = 27; /*unknown*/ - timing_iret_pm = 10; - timing_iret_pm_outer = 27; - timing_call_rm = 4; - timing_call_pm = 4; - timing_call_pm_gate = 22; - timing_call_pm_gate_inner = 44; - timing_retf_rm = 4; - timing_retf_pm = 4; - timing_retf_pm_outer = 23; - timing_jmp_rm = 3; - timing_jmp_pm = 3; - timing_jmp_pm_gate = 18; - timing_misaligned = 3; - cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_PAE | CR4_MCE | CR4_PCE; -#ifdef USE_DYNAREC - codegen_timing_set(&codegen_timing_p6); -#endif - break; - - case CPU_PENTIUM2: -#ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_pentium2_0f, dynarec_ops_386, dynarec_ops_pentium2_0f); - x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_686_da_a16; - x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_686_da_a32; - x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_686_db_a16; - x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_686_db_a32; - x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_686_df_a16; - x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_686_df_a32; -#else - x86_setopcodes(ops_386, ops_pentium2_0f); -#endif - x86_opcodes_da_a16 = ops_fpu_686_da_a16; - x86_opcodes_da_a32 = ops_fpu_686_da_a32; - x86_opcodes_db_a16 = ops_fpu_686_db_a16; - x86_opcodes_db_a32 = ops_fpu_686_db_a32; - x86_opcodes_df_a16 = ops_fpu_686_df_a16; - x86_opcodes_df_a32 = ops_fpu_686_df_a32; - timing_rr = 1; /*register dest - register src*/ - timing_rm = 2; /*register dest - memory src*/ - timing_mr = 3; /*memory dest - register src*/ - timing_mm = 3; - timing_rml = 2; /*register dest - memory src long*/ - timing_mrl = 3; /*memory dest - register src long*/ - timing_mml = 3; - timing_bt = 0; /*branch taken*/ - timing_bnt = 1; /*branch not taken*/ - timing_int = 6; - timing_int_rm = 11; - timing_int_v86 = 54; - timing_int_pm = 25; - timing_int_pm_outer = 42; - timing_iret_rm = 7; - timing_iret_v86 = 27; /*unknown*/ - timing_iret_pm = 10; - timing_iret_pm_outer = 27; - timing_call_rm = 4; - timing_call_pm = 4; - timing_call_pm_gate = 22; - timing_call_pm_gate_inner = 44; - timing_retf_rm = 4; - timing_retf_pm = 4; - timing_retf_pm_outer = 23; - timing_jmp_rm = 3; - timing_jmp_pm = 3; - timing_jmp_pm_gate = 18; - timing_misaligned = 3; - cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_MMX; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_PAE | CR4_MCE | CR4_PCE; -#ifdef USE_DYNAREC - codegen_timing_set(&codegen_timing_p6); -#endif - break; - - case CPU_PENTIUM2D: -#ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_pentium2d_0f, dynarec_ops_386, dynarec_ops_pentium2d_0f); - x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_686_da_a16; - x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_686_da_a32; - x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_686_db_a16; - x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_686_db_a32; - x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_686_df_a16; - x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_686_df_a32; -#else - x86_setopcodes(ops_386, ops_pentium2d_0f); -#endif - x86_opcodes_da_a16 = ops_fpu_686_da_a16; - x86_opcodes_da_a32 = ops_fpu_686_da_a32; - x86_opcodes_db_a16 = ops_fpu_686_db_a16; - x86_opcodes_db_a32 = ops_fpu_686_db_a32; - x86_opcodes_df_a16 = ops_fpu_686_df_a16; - x86_opcodes_df_a32 = ops_fpu_686_df_a32; - timing_rr = 1; /*register dest - register src*/ - timing_rm = 2; /*register dest - memory src*/ - timing_mr = 3; /*memory dest - register src*/ - timing_mm = 3; - timing_rml = 2; /*register dest - memory src long*/ - timing_mrl = 3; /*memory dest - register src long*/ - timing_mml = 3; - timing_bt = 0; /*branch taken*/ - timing_bnt = 1; /*branch not taken*/ - timing_int = 6; - timing_int_rm = 11; - timing_int_v86 = 54; - timing_int_pm = 25; - timing_int_pm_outer = 42; - timing_iret_rm = 7; - timing_iret_v86 = 27; /*unknown*/ - timing_iret_pm = 10; - timing_iret_pm_outer = 27; - timing_call_rm = 4; - timing_call_pm = 4; - timing_call_pm_gate = 22; - timing_call_pm_gate_inner = 44; - timing_retf_rm = 4; - timing_retf_pm = 4; - timing_retf_pm_outer = 23; - timing_jmp_rm = 3; - timing_jmp_pm = 3; - timing_jmp_pm_gate = 18; - timing_misaligned = 3; - cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_MMX; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PAE | CR4_PCE | CR4_OSFXSR; -#ifdef USE_DYNAREC - codegen_timing_set(&codegen_timing_p6); -#endif - break; - - case CPU_CYRIX3S: - case CPU_EDEN: /* This till proper timings get discovered */ -#ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_winchip2_0f, dynarec_ops_386, dynarec_ops_winchip2_0f); -#else - x86_setopcodes(ops_386, ops_winchip2_0f); -#endif - timing_rr = 1; /*register dest - register src*/ - timing_rm = 2; /*register dest - memory src*/ - timing_mr = 2; /*memory dest - register src*/ - timing_mm = 3; - timing_rml = 2; /*register dest - memory src long*/ - timing_mrl = 2; /*memory dest - register src long*/ - timing_mml = 3; - timing_bt = 3-1; /*branch taken*/ - timing_bnt = 1; /*branch not taken*/ - cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MMX | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_3DNOW; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 18) | (1 << 19) | (1 << 20) | (1 << 21); - cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE; - /*unknown*/ - timing_int_rm = 26; - timing_int_v86 = 82; - timing_int_pm = 44; - timing_int_pm_outer = 71; - timing_iret_rm = 7; - timing_iret_v86 = 26; - timing_iret_pm = 10; - timing_iret_pm_outer = 26; - timing_call_rm = 4; - timing_call_pm = 15; - timing_call_pm_gate = 26; - timing_call_pm_gate_inner = 35; - timing_retf_rm = 4; - timing_retf_pm = 7; - timing_retf_pm_outer = 23; - timing_jmp_rm = 5; - timing_jmp_pm = 7; - timing_jmp_pm_gate = 17; - timing_misaligned = 2; - cpu_cyrix_alignment = 1; -#ifdef USE_DYNAREC - codegen_timing_set(&codegen_timing_winchip); -#endif - break; - - default: - fatal("cpu_set : unknown CPU type %i\n", cpu_s->cpu_type); - } - - - switch (fpu_type) - { - case FPU_NONE: - break; - - case FPU_8087: - x87_timings = x87_timings_8087; - break; - - case FPU_287: - x87_timings = x87_timings_287; - break; - - case FPU_287XL: - case FPU_387: - x87_timings = x87_timings_387; - break; - - case FPU_487SX: - default: - x87_timings = x87_timings_486; - } - - if (is386) { -#ifdef USE_DYNAREC - if (cpu_use_dynarec) - cpu_exec = exec386_dynarec; + if (cpu_s->cpu_type >= CPU_K6_2) + x86_setopcodes(ops_386, ops_k62_0f, dynarec_ops_386, dynarec_ops_k62_0f); +#if defined(DEV_BRANCH) && defined(USE_AMD_K5) + else if (cpu_s->cpu_type == CPU_K6) + x86_setopcodes(ops_386, ops_k6_0f, dynarec_ops_386, dynarec_ops_k6_0f); else + x86_setopcodes(ops_386, ops_pentiummmx_0f, dynarec_ops_386, dynarec_ops_pentiummmx_0f); +#else + else + x86_setopcodes(ops_386, ops_k6_0f, dynarec_ops_386, dynarec_ops_k6_0f); #endif - cpu_exec = exec386; - } else if (cpu_s->cpu_type >= CPU_286) - cpu_exec = exec386; +#else + if (cpu_s->cpu_type >= CPU_K6_2) + x86_setopcodes(ops_386, ops_k62_0f); +#if defined(DEV_BRANCH) && defined(USE_AMD_K5) + else if (cpu_s->cpu_type = CPU_K6) + x86_setopcodes(ops_386, ops_k6_0f); + else + x86_setopcodes(ops_386, ops_pentiummmx_0f); +#else + else + x86_setopcodes(ops_386, ops_k6_0f); +#endif +#endif + + timing_rr = 1; /* register dest - register src */ + timing_rm = 2; /* register dest - memory src */ + timing_mr = 3; /* memory dest - register src */ + timing_mm = 3; + timing_rml = 2; /* register dest - memory src long */ + timing_mrl = 3; /* memory dest - register src long */ + timing_mml = 3; + timing_bt = 0; /* branch taken */ + timing_bnt = 1; /* branch not taken */ + + timing_int = 6; + timing_int_rm = 11; + timing_int_v86 = 54; + timing_int_pm = 25; + timing_int_pm_outer = 42; + timing_iret_rm = 7; + timing_iret_v86 = 27; /* unknown */ + timing_iret_pm = 10; + timing_iret_pm_outer = 27; + timing_call_rm = 4; + timing_call_pm = 4; + timing_call_pm_gate = 22; + timing_call_pm_gate_inner = 44; + timing_retf_rm = 4; + timing_retf_pm = 4; + timing_retf_pm_outer = 23; + timing_jmp_rm = 3; + timing_jmp_pm = 3; + timing_jmp_pm_gate = 18; + + timing_misaligned = 3; + + cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_MMX; + if (cpu_s->cpu_type >= CPU_K6_2) + cpu_features |= CPU_FEATURE_3DNOW; + msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); +#if defined(DEV_BRANCH) && defined(USE_AMD_K5) + cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE; + if (cpu_s->cpu_type >= CPU_K6) { + cpu_CR4_mask |= (CR4_VME | CR4_PVI | CR4_PSE); + if (cpu_s->cpu_type <= CPU_K6) + cpu_CR4_mask |= CR4_PCE; + } +#else + cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE; + if (cpu_s->cpu_type == CPU_K6) + cpu_CR4_mask |= CR4_PCE; +#endif + +#ifdef USE_DYNAREC + codegen_timing_set(&codegen_timing_k6); +#endif + break; + + case CPU_PENTIUMPRO: + case CPU_PENTIUM2: + case CPU_PENTIUM2D: +#ifdef USE_DYNAREC + /* TODO: Perhaps merge the three opcode tables with some instructions UD#'ing depending on + CPU type. */ + if (cpu_s->cpu_type == CPU_PENTIUM2D) + x86_setopcodes(ops_386, ops_pentium2d_0f, dynarec_ops_386, dynarec_ops_pentium2d_0f); + else if (cpu_s->cpu_type == CPU_PENTIUM2) + x86_setopcodes(ops_386, ops_pentium2_0f, dynarec_ops_386, dynarec_ops_pentium2_0f); + else + x86_setopcodes(ops_386, ops_pentiumpro_0f, dynarec_ops_386, dynarec_ops_pentiumpro_0f); + x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_686_da_a16; + x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_686_da_a32; + x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_686_db_a16; + x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_686_db_a32; + x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_686_df_a16; + x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_686_df_a32; +#else + if (cpu_s->cpu_type == CPU_PENTIUM2D) + x86_setopcodes(ops_386, ops_pentium2d_0f); + else + x86_setopcodes(ops_386, ops_pentium2_0f); +#endif + x86_opcodes_da_a16 = ops_fpu_686_da_a16; + x86_opcodes_da_a32 = ops_fpu_686_da_a32; + x86_opcodes_db_a16 = ops_fpu_686_db_a16; + x86_opcodes_db_a32 = ops_fpu_686_db_a32; + x86_opcodes_df_a16 = ops_fpu_686_df_a16; + x86_opcodes_df_a32 = ops_fpu_686_df_a32; + + timing_rr = 1; /* register dest - register src */ + timing_rm = 2; /* register dest - memory src */ + timing_mr = 3; /* memory dest - register src */ + timing_mm = 3; + timing_rml = 2; /* register dest - memory src long */ + timing_mrl = 3; /* memory dest - register src long */ + timing_mml = 3; + timing_bt = 0; /* branch taken */ + timing_bnt = 1; /* branch not taken */ + + timing_int = 6; + timing_int_rm = 11; + timing_int_v86 = 54; + timing_int_pm = 25; + timing_int_pm_outer = 42; + timing_iret_rm = 7; + timing_iret_v86 = 27; /* unknown */ + timing_iret_pm = 10; + timing_iret_pm_outer = 27; + timing_call_rm = 4; + timing_call_pm = 4; + timing_call_pm_gate = 22; + timing_call_pm_gate_inner = 44; + timing_retf_rm = 4; + timing_retf_pm = 4; + timing_retf_pm_outer = 23; + timing_jmp_rm = 3; + timing_jmp_pm = 3; + timing_jmp_pm_gate = 18; + + timing_misaligned = 3; + + cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME; + if (cpu_s->cpu_type >= CPU_PENTIUM2) + cpu_features |= CPU_FEATURE_MMX; + msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); + cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PAE | CR4_PCE; + if (cpu_s->cpu_type == CPU_PENTIUM2D) + cpu_CR4_mask |= CR4_OSFXSR; + +#ifdef USE_DYNAREC + codegen_timing_set(&codegen_timing_p6); +#endif + break; + + case CPU_CYRIX3S: + case CPU_EDEN: /* This until proper timings get discovered */ +#ifdef USE_DYNAREC + x86_setopcodes(ops_386, ops_winchip2_0f, dynarec_ops_386, dynarec_ops_winchip2_0f); +#else + x86_setopcodes(ops_386, ops_winchip2_0f); +#endif + timing_rr = 1; /* register dest - register src */ + timing_rm = 2; /* register dest - memory src */ + timing_mr = 2; /* memory dest - register src */ + timing_mm = 3; + timing_rml = 2; /* register dest - memory src long */ + timing_mrl = 2; /* memory dest - register src long */ + timing_mml = 3; + timing_bt = 2; /* branch taken */ + timing_bnt = 1; /* branch not taken */ + + timing_int_rm = 26; /* unknown */ + timing_int_v86 = 82; + timing_int_pm = 44; + timing_int_pm_outer = 71; + timing_iret_rm = 7; + timing_iret_v86 = 26; + timing_iret_pm = 10; + timing_iret_pm_outer = 26; + timing_call_rm = 4; + timing_call_pm = 15; + timing_call_pm_gate = 26; + timing_call_pm_gate_inner = 35; + timing_retf_rm = 4; + timing_retf_pm = 7; + timing_retf_pm_outer = 23; + timing_jmp_rm = 5; + timing_jmp_pm = 7; + timing_jmp_pm_gate = 17; + + timing_misaligned = 2; + + cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MMX | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_3DNOW; + msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 18) | (1 << 19) | (1 << 20) | (1 << 21); + cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE; + + cpu_cyrix_alignment = 1; + +#ifdef USE_DYNAREC + codegen_timing_set(&codegen_timing_winchip); +#endif + break; + + default: + fatal("cpu_set : unknown CPU type %i\n", cpu_s->cpu_type); + } + + switch (fpu_type) { + case FPU_NONE: + break; + + case FPU_8087: + x87_timings = x87_timings_8087; + break; + + case FPU_287: + x87_timings = x87_timings_287; + break; + + case FPU_287XL: + case FPU_387: + x87_timings = x87_timings_387; + break; + + case FPU_487SX: + default: + x87_timings = x87_timings_486; + } + + if (is386) { +#ifdef USE_DYNAREC + if (cpu_use_dynarec) + cpu_exec = exec386_dynarec; else - cpu_exec = execx86; +#endif + cpu_exec = exec386; + } else if (cpu_s->cpu_type >= CPU_286) + cpu_exec = exec386; + else + cpu_exec = execx86; } @@ -1982,1991 +1465,1569 @@ cpu_current_pc(char *bufp) void cpu_CPUID(void) { - switch (cpu_s->cpu_type) - { - case CPU_RAPIDCAD: - case CPU_i486DX: - case CPU_i486DX2: - if (!EAX) - { - EAX = 0x00000001; - EBX = 0x756e6547; - EDX = 0x49656e69; - ECX = 0x6c65746e; - } - else if (EAX == 1) - { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU; /*FPU*/ - } - else - EAX = EBX = ECX = EDX = 0; - break; + switch (cpu_s->cpu_type) { + case CPU_RAPIDCAD: + case CPU_i486DX: + case CPU_i486DX2: + if (!EAX) { + EAX = 0x00000001; + EBX = 0x756e6547; + EDX = 0x49656e69; + ECX = 0x6c65746e; + } else if (EAX == 1) { + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU; /*FPU*/ + } else + EAX = EBX = ECX = EDX = 0; + break; - case CPU_iDX4: - if (!EAX) - { - EAX = 0x00000001; - EBX = 0x756e6547; - EDX = 0x49656e69; - ECX = 0x6c65746e; - } - else if (EAX == 1) - { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME; - } - else - EAX = EBX = ECX = EDX = 0; - break; + case CPU_iDX4: + if (!EAX) { + EAX = 0x00000001; + EBX = 0x756e6547; + EDX = 0x49656e69; + ECX = 0x6c65746e; + } else if (EAX == 1) { + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME; + } else + EAX = EBX = ECX = EDX = 0; + break; - case CPU_Am486SX: - case CPU_Am486SX2: - if (!EAX) - { - EAX = 1; - EBX = 0x68747541; - ECX = 0x444D4163; - EDX = 0x69746E65; - } - else if (EAX == 1) - { - EAX = CPUID; - EBX = ECX = EDX = 0; /*No FPU*/ - } - else - EAX = EBX = ECX = EDX = 0; - break; + case CPU_Am486SX: + case CPU_Am486SX2: + if (!EAX) { + EAX = 1; + EBX = 0x68747541; + ECX = 0x444D4163; + EDX = 0x69746E65; + } else if (EAX == 1) { + EAX = CPUID; + EBX = ECX = EDX = 0; /*No FPU*/ + } else + EAX = EBX = ECX = EDX = 0; + break; - case CPU_Am486DX: - case CPU_Am486DX2: - case CPU_Am486DX4: - case CPU_Am5x86: - if (!EAX) - { - EAX = 1; - EBX = 0x68747541; - ECX = 0x444D4163; - EDX = 0x69746E65; - } - else if (EAX == 1) - { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU; /*FPU*/ - } - else - EAX = EBX = ECX = EDX = 0; - break; - - case CPU_WINCHIP: - if (!EAX) - { - EAX = 1; - if (msr.fcr2 & (1 << 14)) - { - EBX = msr.fcr3 >> 32; - ECX = msr.fcr3 & 0xffffffff; - EDX = msr.fcr2 >> 32; - } - else - { - EBX = 0x746e6543; /*CentaurHauls*/ - ECX = 0x736c7561; - EDX = 0x48727561; - } - } - else if (EAX == 1) - { - EAX = 0x540; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR; - if (cpu_has_feature(CPU_FEATURE_CX8)) - EDX |= CPUID_CMPXCHG8B; - if (msr.fcr & (1 << 9)) - EDX |= CPUID_MMX; - } - else - EAX = EBX = ECX = EDX = 0; - break; + case CPU_Am486DX: + case CPU_Am486DX2: + case CPU_Am486DX4: + case CPU_Am5x86: + if (!EAX) { + EAX = 1; + EBX = 0x68747541; + ECX = 0x444D4163; + EDX = 0x69746E65; + } else if (EAX == 1) { + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU; /*FPU*/ + } else + EAX = EBX = ECX = EDX = 0; + break; - case CPU_WINCHIP2: - switch (EAX) - { - case 0: - EAX = 1; - if (msr.fcr2 & (1 << 14)) - { - EBX = msr.fcr3 >> 32; - ECX = msr.fcr3 & 0xffffffff; - EDX = msr.fcr2 >> 32; - } - else - { - EBX = 0x746e6543; /*CentaurHauls*/ - ECX = 0x736c7561; - EDX = 0x48727561; - } - break; - case 1: - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR; - if (cpu_has_feature(CPU_FEATURE_CX8)) - EDX |= CPUID_CMPXCHG8B; - if (msr.fcr & (1 << 9)) - EDX |= CPUID_MMX; - break; - case 0x80000000: - EAX = 0x80000005; - break; - case 0x80000001: - EAX = CPUID; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR; + case CPU_WINCHIP: + if (!EAX) { + EAX = 1; + if (msr.fcr2 & (1 << 14)) { + EBX = msr.fcr3 >> 32; + ECX = msr.fcr3 & 0xffffffff; + EDX = msr.fcr2 >> 32; + } else { + EBX = 0x746e6543; /* CentaurHauls */ + ECX = 0x736c7561; + EDX = 0x48727561; + } + } else if (EAX == 1) { + EAX = 0x540; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR; if (cpu_has_feature(CPU_FEATURE_CX8)) EDX |= CPUID_CMPXCHG8B; - if (msr.fcr & (1 << 9)) - EDX |= CPUID_MMX; - if (cpu_has_feature(CPU_FEATURE_3DNOW)) - EDX |= CPUID_3DNOW; - break; - - case 0x80000002: /*Processor name string*/ - EAX = 0x20544449; /*IDT WinChip 2-3D*/ - EBX = 0x436e6957; - ECX = 0x20706968; - EDX = 0x44332d32; - break; - - case 0x80000005: /*Cache information*/ - EBX = 0x08800880; /*TLBs*/ - ECX = 0x20040120; /*L1 data cache*/ - EDX = 0x20020120; /*L1 instruction cache*/ - break; - - default: - EAX = EBX = ECX = EDX = 0; - break; - } - break; - - case CPU_P24T: - case CPU_PENTIUM: - if (!EAX) - { - EAX = 0x00000001; - EBX = 0x756e6547; - EDX = 0x49656e69; - ECX = 0x6c65746e; - } - else if (EAX == 1) - { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B; - } - else - EAX = EBX = ECX = EDX = 0; - break; + if (msr.fcr & (1 << 9)) + EDX |= CPUID_MMX; + } else + EAX = EBX = ECX = EDX = 0; + break; + + case CPU_WINCHIP2: + switch (EAX) { + case 0: + EAX = 1; + if (msr.fcr2 & (1 << 14)) { + EBX = msr.fcr3 >> 32; + ECX = msr.fcr3 & 0xffffffff; + EDX = msr.fcr2 >> 32; + } else { + EBX = 0x746e6543; /* CentaurHauls */ + ECX = 0x736c7561; + EDX = 0x48727561; + } + break; + case 1: + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR; + if (cpu_has_feature(CPU_FEATURE_CX8)) + EDX |= CPUID_CMPXCHG8B; + if (msr.fcr & (1 << 9)) + EDX |= CPUID_MMX; + break; + case 0x80000000: + EAX = 0x80000005; + break; + case 0x80000001: + EAX = CPUID; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR; + if (cpu_has_feature(CPU_FEATURE_CX8)) + EDX |= CPUID_CMPXCHG8B; + if (msr.fcr & (1 << 9)) + EDX |= CPUID_MMX; + if (cpu_has_feature(CPU_FEATURE_3DNOW)) + EDX |= CPUID_3DNOW; + break; + + case 0x80000002: /* Processor name string */ + EAX = 0x20544449; /* IDT WinChip 2-3D */ + EBX = 0x436e6957; + ECX = 0x20706968; + EDX = 0x44332d32; + break; + + case 0x80000005: /*Cache information*/ + EBX = 0x08800880; /*TLBs*/ + ECX = 0x20040120; /*L1 data cache*/ + EDX = 0x20020120; /*L1 instruction cache*/ + break; + + default: + EAX = EBX = ECX = EDX = 0; + break; + } + break; + + case CPU_P24T: + case CPU_PENTIUM: + if (!EAX) { + EAX = 0x00000001; + EBX = 0x756e6547; + EDX = 0x49656e69; + ECX = 0x6c65746e; + } else if (EAX == 1) { + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B; + } else + EAX = EBX = ECX = EDX = 0; + break; #if defined(DEV_BRANCH) && defined(USE_AMD_K5) - case CPU_K5: - if (!EAX) - { - EAX = 0x00000001; - EBX = 0x68747541; - EDX = 0x69746E65; - ECX = 0x444D4163; - } - else if (EAX == 1) - { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B; - } - else - EAX = EBX = ECX = EDX = 0; - break; + case CPU_K5: + if (!EAX) { + EAX = 0x00000001; + EBX = 0x68747541; + EDX = 0x69746E65; + ECX = 0x444D4163; + } else if (EAX == 1) { + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B; + } else + EAX = EBX = ECX = EDX = 0; + break; - case CPU_5K86: - if (!EAX) - { - EAX = 0x00000001; - EBX = 0x68747541; - EDX = 0x69746E65; - ECX = 0x444D4163; - } - else if (EAX == 1) - { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B; - } - else if (EAX == 0x80000000) - { - EAX = 0x80000005; - EBX = ECX = EDX = 0; - } - else if (EAX == 0x80000001) - { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B; - } - else if (EAX == 0x80000002) - { + case CPU_5K86: + if (!EAX) { + EAX = 0x00000001; + EBX = 0x68747541; + EDX = 0x69746E65; + ECX = 0x444D4163; + } else if (EAX == 1) { + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B; + } else if (EAX == 0x80000000) { + EAX = 0x80000005; + EBX = ECX = EDX = 0; + } else if (EAX == 0x80000001) { + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B; + } else if (EAX == 0x80000002) { EAX = 0x2D444D41; EBX = 0x7428354B; ECX = 0x5020296D; EDX = 0x65636F72; - } - else if (EAX == 0x80000003) - { + } else if (EAX == 0x80000003) { EAX = 0x726F7373; EBX = ECX = EDX = 0; - } - else if (EAX == 0x80000004) - { + } else if (EAX == 0x80000004) EAX = EBX = ECX = EDX = 0; - } - else if (EAX == 0x80000005) - { + else if (EAX == 0x80000005) { EAX = 0; EBX = 0x04800000; ECX = 0x08040120; EDX = 0x10040120; - } - else - EAX = EBX = ECX = EDX = 0; - break; + } else + EAX = EBX = ECX = EDX = 0; + break; #endif - case CPU_K6: - if (!EAX) - { - EAX = 0x00000001; - EBX = 0x68747541; - EDX = 0x69746E65; - ECX = 0x444D4163; - } - else if (EAX == 1) - { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; - } - else if (EAX == 0x80000000) - { - EAX = 0x80000005; - EBX = ECX = EDX = 0; - } - else if (EAX == 0x80000001) - { - EAX = CPUID + 0x100; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX; - } - else if (EAX == 0x80000002) - { + case CPU_K6: + if (!EAX) { + EAX = 0x00000001; + EBX = 0x68747541; + EDX = 0x69746E65; + ECX = 0x444D4163; + } else if (EAX == 1) { + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; + } else if (EAX == 0x80000000) { + EAX = 0x80000005; + EBX = ECX = EDX = 0; + } else if (EAX == 0x80000001) { + EAX = CPUID + 0x100; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX; + } else if (EAX == 0x80000002) { EAX = 0x2D444D41; EBX = 0x6D74364B; ECX = 0x202F7720; EDX = 0x746C756D; - } - else if (EAX == 0x80000003) - { + } else if (EAX == 0x80000003) { EAX = 0x64656D69; EBX = 0x65206169; ECX = 0x6E657478; EDX = 0x6E6F6973; - } - else if (EAX == 0x80000004) - { + } else if (EAX == 0x80000004) { EAX = 0x73; EBX = ECX = EDX = 0; - } - else if (EAX == 0x80000005) - { + } else if (EAX == 0x80000005) { EAX = 0; EBX = 0x02800140; ECX = 0x20020220; EDX = 0x20020220; - } - else if (EAX == 0x8FFFFFFF) - { + } else if (EAX == 0x8FFFFFFF) { EAX = 0x4778654E; EBX = 0x72656E65; ECX = 0x6F697461; EDX = 0x444D416E; + } else + EAX = EBX = ECX = EDX = 0; + break; + + case CPU_K6_2: + case CPU_K6_2C: + switch (EAX) { + case 0: + EAX = 1; + EBX = 0x68747541; /* AuthenticAMD */ + ECX = 0x444d4163; + EDX = 0x69746e65; + break; + case 1: + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; + break; + case 0x80000000: + EAX = 0x80000005; + break; + case 0x80000001: + EAX = CPUID + 0x100; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX | CPUID_3DNOW; + break; + case 0x80000002: /* Processor name string */ + EAX = 0x2d444d41; /* AMD-K6(tm) 3D pr */ + EBX = 0x7428364b; + ECX = 0x3320296d; + EDX = 0x72702044; + break; + case 0x80000003: /* Processor name string */ + EAX = 0x7365636f; /* ocessor */ + EBX = 0x00726f73; + ECX = 0x00000000; + EDX = 0x00000000; + break; + case 0x80000005: /*Cache information*/ + EBX = 0x02800140; /*TLBs*/ + ECX = 0x20020220; /*L1 data cache*/ + EDX = 0x20020220; /*L1 instruction cache*/ + break; + default: + EAX = EBX = ECX = EDX = 0; + break; } - else - EAX = EBX = ECX = EDX = 0; - break; + break; - case CPU_K6_2: - case CPU_K6_2C: - switch (EAX) - { - case 0: - EAX = 1; - EBX = 0x68747541; /*AuthenticAMD*/ - ECX = 0x444d4163; - EDX = 0x69746e65; - break; - case 1: - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; - break; - case 0x80000000: - EAX = 0x80000005; - break; - case 0x80000001: - EAX = CPUID+0x100; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX | CPUID_3DNOW; - break; + case CPU_K6_3: + switch (EAX) { + case 0: + EAX = 1; + EBX = 0x68747541; /* AuthenticAMD */ + ECX = 0x444d4163; + EDX = 0x69746e65; + break; + case 1: + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; + break; + case 0x80000000: + EAX = 0x80000006; + break; + case 0x80000001: + EAX = CPUID + 0x100; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX | CPUID_3DNOW; + break; + case 0x80000002: /* Processor name string */ + EAX = 0x2d444d41; /* AMD-K6(tm) 3D+ P */ + EBX = 0x7428364b; + ECX = 0x3320296d; + EDX = 0x50202b44; + break; + case 0x80000003: /* Processor name string */ + EAX = 0x65636f72; /* rocessor */ + EBX = 0x726f7373; + ECX = 0x00000000; + EDX = 0x00000000; + break; + case 0x80000005: /* Cache information */ + EBX = 0x02800140; /* TLBs */ + ECX = 0x20020220; /*L1 data cache*/ + EDX = 0x20020220; /*L1 instruction cache*/ + break; + case 0x80000006: /* L2 Cache information */ + ECX = 0x01004220; + break; + default: + EAX = EBX = ECX = EDX = 0; + break; + } + break; - case 0x80000002: /*Processor name string*/ - EAX = 0x2d444d41; /*AMD-K6(tm) 3D pr*/ - EBX = 0x7428364b; - ECX = 0x3320296d; - EDX = 0x72702044; - break; - - case 0x80000003: /*Processor name string*/ - EAX = 0x7365636f; /*ocessor*/ - EBX = 0x00726f73; - ECX = 0x00000000; - EDX = 0x00000000; - break; - - case 0x80000005: /*Cache information*/ - EBX = 0x02800140; /*TLBs*/ - ECX = 0x20020220; /*L1 data cache*/ - EDX = 0x20020220; /*L1 instruction cache*/ - break; - - default: - EAX = EBX = ECX = EDX = 0; - break; - } - break; - - case CPU_K6_3: - switch (EAX) - { - case 0: - EAX = 1; - EBX = 0x68747541; /*AuthenticAMD*/ - ECX = 0x444d4163; - EDX = 0x69746e65; - break; - case 1: - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; - break; - case 0x80000000: - EAX = 0x80000006; - break; - case 0x80000001: - EAX = CPUID+0x100; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX | CPUID_3DNOW; - break; - - case 0x80000002: /*Processor name string*/ - EAX = 0x2d444d41; /*AMD-K6(tm) 3D+ P*/ - EBX = 0x7428364b; - ECX = 0x3320296d; - EDX = 0x50202b44; - break; - - case 0x80000003: /*Processor name string*/ - EAX = 0x65636f72; /*rocessor*/ - EBX = 0x726f7373; - ECX = 0x00000000; - EDX = 0x00000000; - break; - - case 0x80000005: /*Cache information*/ - EBX = 0x02800140; /*TLBs*/ - ECX = 0x20020220; /*L1 data cache*/ - EDX = 0x20020220; /*L1 instruction cache*/ - break; - - case 0x80000006: /*L2 Cache information*/ - ECX = 0x01004220; - break; - - default: - EAX = EBX = ECX = EDX = 0; - break; - } - break; - - case CPU_K6_2P: - case CPU_K6_3P: - switch (EAX) - { - case 0: - EAX = 1; - EBX = 0x68747541; /*AuthenticAMD*/ - ECX = 0x444d4163; - EDX = 0x69746e65; - break; - case 1: - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; - break; - case 0x80000000: - EAX = 0x80000007; - break; - case 0x80000001: - EAX = CPUID+0x100; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX | CPUID_3DNOW; - break; - - case 0x80000002: /*Processor name string*/ - EAX = 0x2d444d41; /*AMD-K6(tm)-III P*/ - EBX = 0x7428364b; - ECX = 0x492d296d; - EDX = 0x50204949; - break; - - case 0x80000003: /*Processor name string*/ - EAX = 0x65636f72; /*rocessor*/ - EBX = 0x726f7373; - ECX = 0x00000000; - EDX = 0x00000000; - break; - - case 0x80000005: /*Cache information*/ - EBX = 0x02800140; /*TLBs*/ - ECX = 0x20020220; /*L1 data cache*/ - EDX = 0x20020220; /*L1 instruction cache*/ - break; - - case 0x80000006: /*L2 Cache information*/ - if (cpu_s->cpu_type == CPU_K6_3P) - ECX = 0x01004220; - else - ECX = 0x00804220; - break; - - case 0x80000007: /*PowerNow information*/ - EDX = 7; - break; - - default: - EAX = EBX = ECX = EDX = 0; - break; - } - break; - - case CPU_PENTIUMMMX: - if (!EAX) - { - EAX = 0x00000001; - EBX = 0x756e6547; - EDX = 0x49656e69; - ECX = 0x6c65746e; - } - else if (EAX == 1) - { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; - } - else - EAX = EBX = ECX = EDX = 0; - break; + case CPU_K6_2P: + case CPU_K6_3P: + switch (EAX) { + case 0: + EAX = 1; + EBX = 0x68747541; /* AuthenticAMD */ + ECX = 0x444d4163; + EDX = 0x69746e65; + break; + case 1: + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; + break; + case 0x80000000: + EAX = 0x80000007; + break; + case 0x80000001: + EAX = CPUID + 0x100; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX | CPUID_3DNOW; + break; + case 0x80000002: /* Processor name string */ + EAX = 0x2d444d41; /* AMD-K6(tm)-III P */ + EBX = 0x7428364b; + ECX = 0x492d296d; + EDX = 0x50204949; + break; + case 0x80000003: /* Processor name string */ + EAX = 0x65636f72; /* rocessor */ + EBX = 0x726f7373; + ECX = 0x00000000; + EDX = 0x00000000; + break; + case 0x80000005: /* Cache information */ + EBX = 0x02800140; /* TLBs */ + ECX = 0x20020220; /* L1 data cache */ + EDX = 0x20020220; /* L1 instruction cache */ + break; + case 0x80000006: /* L2 Cache information */ + if (cpu_s->cpu_type == CPU_K6_3P) + ECX = 0x01004220; + else + ECX = 0x00804220; + break; + case 0x80000007: /* PowerNow information */ + EDX = 7; + break; + default: + EAX = EBX = ECX = EDX = 0; + break; + } + break; + case CPU_PENTIUMMMX: + if (!EAX) { + EAX = 0x00000001; + EBX = 0x756e6547; + EDX = 0x49656e69; + ECX = 0x6c65746e; + } else if (EAX == 1) { + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; + } else + EAX = EBX = ECX = EDX = 0; + break; #if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) - case CPU_Cx6x86: - if (!EAX) - { - EAX = 0x00000001; - EBX = 0x69727943; - EDX = 0x736e4978; - ECX = 0x64616574; - } - else if (EAX == 1) - { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU; - } - else - EAX = EBX = ECX = EDX = 0; - break; + case CPU_Cx6x86: + if (!EAX) { + EAX = 0x00000001; + EBX = 0x69727943; + EDX = 0x736e4978; + ECX = 0x64616574; + } else if (EAX == 1) { + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU; + } else + EAX = EBX = ECX = EDX = 0; + break; + case CPU_Cx6x86L: + if (!EAX) { + EAX = 0x00000001; + EBX = 0x69727943; + EDX = 0x736e4978; + ECX = 0x64616574; + } else if (EAX == 1) { + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_CMPXCHG8B; + } else + EAX = EBX = ECX = EDX = 0; + break; - case CPU_Cx6x86L: - if (!EAX) - { - EAX = 0x00000001; - EBX = 0x69727943; - EDX = 0x736e4978; - ECX = 0x64616574; - } - else if (EAX == 1) - { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_CMPXCHG8B; - } - else - EAX = EBX = ECX = EDX = 0; - break; + case CPU_CxGX1: + if (!EAX) { + EAX = 0x00000001; + EBX = 0x69727943; + EDX = 0x736e4978; + ECX = 0x64616574; + } else if (EAX == 1) { + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B; + } else + EAX = EBX = ECX = EDX = 0; + break; - - case CPU_CxGX1: - if (!EAX) - { - EAX = 0x00000001; - EBX = 0x69727943; - EDX = 0x736e4978; - ECX = 0x64616574; - } - else if (EAX == 1) - { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B; - } - else - EAX = EBX = ECX = EDX = 0; - break; - - - - case CPU_Cx6x86MX: - if (!EAX) - { - EAX = 0x00000001; - EBX = 0x69727943; - EDX = 0x736e4978; - ECX = 0x64616574; - } - else if (EAX == 1) - { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_CMOV | CPUID_MMX; - } - else - EAX = EBX = ECX = EDX = 0; - break; + case CPU_Cx6x86MX: + if (!EAX) { + EAX = 0x00000001; + EBX = 0x69727943; + EDX = 0x736e4978; + ECX = 0x64616574; + } else if (EAX == 1) { + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_CMOV | CPUID_MMX; + } else + EAX = EBX = ECX = EDX = 0; + break; #endif - case CPU_PENTIUMPRO: - if (!EAX) - { - EAX = 0x00000002; - EBX = 0x756e6547; - EDX = 0x49656e69; - ECX = 0x6c65746e; - } - else if (EAX == 1) - { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_CMPXCHG8B | CPUID_MTRR | CPUID_SEP | CPUID_CMOV; - } - else if (EAX == 2) - { + case CPU_PENTIUMPRO: + if (!EAX) { + EAX = 0x00000002; + EBX = 0x756e6547; + EDX = 0x49656e69; + ECX = 0x6c65746e; + } else if (EAX == 1) { + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_CMPXCHG8B | CPUID_MTRR | CPUID_SEP | CPUID_CMOV; + } else if (EAX == 2) { EAX = 0x00000001; EBX = ECX = 0; EDX = 0x00000000; - } - else - EAX = EBX = ECX = EDX = 0; - break; + } else + EAX = EBX = ECX = EDX = 0; + break; - case CPU_PENTIUM2: - if (!EAX) - { - EAX = 0x00000002; - EBX = 0x756e6547; - EDX = 0x49656e69; - ECX = 0x6c65746e; - } - else if (EAX == 1) - { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_MTRR | CPUID_SEP | CPUID_CMOV; - } - else if (EAX == 2) - { + case CPU_PENTIUM2: + if (!EAX) { + EAX = 0x00000002; + EBX = 0x756e6547; + EDX = 0x49656e69; + ECX = 0x6c65746e; + } else if (EAX == 1) { + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_MTRR | CPUID_SEP | CPUID_CMOV; + } else if (EAX == 2) { EAX = 0x00000001; EBX = ECX = 0; EDX = 0x00000000; - } - else - EAX = EBX = ECX = EDX = 0; - break; + } else + EAX = EBX = ECX = EDX = 0; + break; - case CPU_PENTIUM2D: - if (!EAX) - { - EAX = 0x00000002; - EBX = 0x756e6547; - EDX = 0x49656e69; - ECX = 0x6c65746e; - } - else if (EAX == 1) - { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_MTRR | CPUID_SEP | CPUID_FXSR | CPUID_CMOV; - } - else if (EAX == 2) - { + case CPU_PENTIUM2D: + if (!EAX) { + EAX = 0x00000002; + EBX = 0x756e6547; + EDX = 0x49656e69; + ECX = 0x6c65746e; + } else if (EAX == 1) { + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_MTRR | CPUID_SEP | CPUID_FXSR | CPUID_CMOV; + } else if (EAX == 2) { EAX = 0x00000001; EBX = ECX = 0; EDX = 0x00000000; + } else + EAX = EBX = ECX = EDX = 0; + break; + + case CPU_CYRIX3S: + switch (EAX) { + case 0: + EAX = 1; + if (msr.fcr2 & (1 << 14)) { + EBX = msr.fcr3 >> 32; + ECX = msr.fcr3 & 0xffffffff; + EDX = msr.fcr2 >> 32; + } else { + EBX = 0x746e6543; /* CentaurHauls */ + ECX = 0x736c7561; + EDX = 0x48727561; + } + break; + case 1: + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MMX | CPUID_MTRR; + if (cpu_has_feature(CPU_FEATURE_CX8)) + EDX |= CPUID_CMPXCHG8B; + break; + case 0x80000000: + EAX = 0x80000005; + break; + case 0x80000001: + EAX = CPUID; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MMX | CPUID_MTRR | CPUID_3DNOW; + if (cpu_has_feature(CPU_FEATURE_CX8)) + EDX |= CPUID_CMPXCHG8B; + break; + case 0x80000002: /* Processor name string */ + EAX = 0x20414956; /* VIA Samuel */ + EBX = 0x756d6153; + ECX = 0x00006c65; + EDX = 0x00000000; + break; + case 0x80000005: /* Cache information */ + EBX = 0x08800880; /* TLBs */ + ECX = 0x40040120; /* L1 data cache */ + EDX = 0x40020120; /* L1 instruction cache */ + break; + default: + EAX = EBX = ECX = EDX = 0; + break; } - else - EAX = EBX = ECX = EDX = 0; - break; + break; - case CPU_CYRIX3S: - switch (EAX) - { - case 0: - EAX = 1; - if (msr.fcr2 & (1 << 14)) - { - EBX = msr.fcr3 >> 32; - ECX = msr.fcr3 & 0xffffffff; - EDX = msr.fcr2 >> 32; - } - else - { - EBX = 0x746e6543; /*CentaurHauls*/ - ECX = 0x736c7561; - EDX = 0x48727561; - } - break; - case 1: - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MMX | CPUID_MTRR; - if (cpu_has_feature(CPU_FEATURE_CX8)) - EDX |= CPUID_CMPXCHG8B; - break; - case 0x80000000: - EAX = 0x80000005; - break; - case 0x80000001: - EAX = CPUID; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MMX | CPUID_MTRR | CPUID_3DNOW; - if (cpu_has_feature(CPU_FEATURE_CX8)) - EDX |= CPUID_CMPXCHG8B; - break; - case 0x80000002: /*Processor name string*/ - EAX = 0x20414956; /*VIA Samuel*/ - EBX = 0x756d6153; - ECX = 0x00006c65; - EDX = 0x00000000; - break; - - case 0x80000005: /*Cache information*/ - EBX = 0x08800880; /*TLBs*/ - ECX = 0x40040120; /*L1 data cache*/ - EDX = 0x40020120; /*L1 instruction cache*/ - break; - - default: - EAX = EBX = ECX = EDX = 0; - break; - } - break; - - case CPU_EDEN: - switch (EAX) - { - case 0: - EAX = 1; - if (msr.fcr2 & (1 << 14)) - { - EBX = msr.fcr3 >> 32; - ECX = msr.fcr3 & 0xffffffff; - EDX = msr.fcr2 >> 32; - } - else - { - EBX = 0x746e6543; /*CentaurHauls*/ - ECX = 0x736c7561; - EDX = 0x48727561; - } - break; - case 1: - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MMX | CPUID_MTRR; - if (cpu_has_feature(CPU_FEATURE_CX8)) - EDX |= CPUID_CMPXCHG8B; - break; - case 0x80000000: - EAX = 0x80000006; - break; - case 0x80000001: - EAX = CPUID; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MMX | CPUID_MTRR | CPUID_3DNOW; - if (cpu_has_feature(CPU_FEATURE_CX8)) - EDX |= CPUID_CMPXCHG8B; - break; - case 0x80000002: /*Processor name string*/ - case 0x80000003: - case 0x80000004: - EAX = 0x20414956; /*VIA Samuel 2*/ - EBX = 0x756d6153; - ECX = 0x32206c65; - EDX = 0x00000000; - break; - - case 0x80000005: /*Cache information*/ - EBX = 0x08800880; /*TLBs*/ - ECX = 0x40040120; /*L1 data cache*/ - EDX = 0x40020120; /*L1 instruction cache*/ - break; - - case 0x80000006: - ECX = 0x40040120; /*L2 data cache*/ - break; - - default: - EAX = EBX = ECX = EDX = 0; - break; - } - break; - } + case CPU_EDEN: + switch (EAX) { + case 0: + EAX = 1; + if (msr.fcr2 & (1 << 14)) { + EBX = msr.fcr3 >> 32; + ECX = msr.fcr3 & 0xffffffff; + EDX = msr.fcr2 >> 32; + } else { + EBX = 0x746e6543; /* CentaurHauls */ + ECX = 0x736c7561; + EDX = 0x48727561; + } + break; + case 1: + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MMX | CPUID_MTRR; + if (cpu_has_feature(CPU_FEATURE_CX8)) + EDX |= CPUID_CMPXCHG8B; + break; + case 0x80000000: + EAX = 0x80000006; + break; + case 0x80000001: + EAX = CPUID; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MMX | CPUID_MTRR | CPUID_3DNOW; + if (cpu_has_feature(CPU_FEATURE_CX8)) + EDX |= CPUID_CMPXCHG8B; + break; + case 0x80000002: /* Processor name string */ + case 0x80000003: + case 0x80000004: + EAX = 0x20414956; /* VIA Samuel 2 */ + EBX = 0x756d6153; + ECX = 0x32206c65; + EDX = 0x00000000; + break; + case 0x80000005: /* Cache information */ + EBX = 0x08800880; /* TLBs */ + ECX = 0x40040120; /* L1 data cache */ + EDX = 0x40020120; /* L1 instruction cache */ + break; + case 0x80000006: + ECX = 0x40040120; /* L2 data cache */ + break; + default: + EAX = EBX = ECX = EDX = 0; + break; + } + break; + } } -void cpu_ven_reset(void) + +void +cpu_ven_reset(void) { - switch (cpu_s->cpu_type) - { + memset(&msr, 0, sizeof(msr)); + + switch (cpu_s->cpu_type) { + case CPU_K6_2P: + case CPU_K6_3P: + case CPU_K6_3: + case CPU_K6_2C: + msr.amd_psor = (cpu_s->cpu_type >= CPU_K6_3) ? 0x008cULL : 0x018cULL; + /* FALLTHROUGH */ + case CPU_K6_2: #if defined(DEV_BRANCH) && defined(USE_AMD_K5) - case CPU_K5: - case CPU_5K86: + case CPU_K5: + case CPU_5K86: #endif - case CPU_K6: - amd_efer = amd_whcr = 0ULL; - break; - case CPU_K6_2: - amd_efer = amd_whcr = 0ULL; - star = 0ULL; - break; - case CPU_K6_2C: - amd_efer = 2ULL; - amd_whcr = star = 0ULL; - amd_psor = 0x018cULL; - amd_uwccr = 0ULL; - break; - case CPU_K6_3: - amd_efer = 2ULL; - amd_whcr = star = 0ULL; - amd_psor = 0x008cULL; - amd_uwccr = 0ULL; - amd_pfir = amd_l2aar = 0ULL; - break; - case CPU_K6_2P: - case CPU_K6_3P: - amd_efer = 2ULL; - amd_whcr = star = 0ULL; - amd_psor = 0x008cULL; - amd_uwccr = 0ULL; - amd_pfir = amd_l2aar = 0ULL; - amd_epmr = 0ULL; - break; - } + case CPU_K6: + msr.amd_efer = (cpu_s->cpu_type >= CPU_K6_2C) ? 2ULL : 0ULL; + break; + + case CPU_PENTIUMPRO: + case CPU_PENTIUM2: + case CPU_PENTIUM2D: + msr.mtrr_cap = 0x00000508ULL; + /* FALLTHROUGH */ + break; + } } -void cpu_RDMSR() + +void +cpu_RDMSR(void) { - switch (cpu_s->cpu_type) - { - case CPU_IBM386SLC: - EAX = EDX = 0; - switch (ECX) - { - case 0x1000: - EAX = ibm_por_msr & 0xfeff; - break; - - case 0x1001: - EAX = ibm_crcr_msr & 0xffffffffff; - break; - } - break; - - case CPU_IBM486SLC: - case CPU_IBM486BL: - EAX = EDX = 0; - switch (ECX) - { - case 0x1000: - EAX = ibm_por_msr & 0xffeff; - break; - - case 0x1001: - EAX = ibm_crcr_msr & 0xffffffffff; - break; - - if (cpu_s->multi) { - case 0x1002: - EAX = ibm_por2_msr & 0x3f000000; - break; - } - } - break; - - case CPU_WINCHIP: - case CPU_WINCHIP2: - EAX = EDX = 0; - switch (ECX) - { - case 0x02: - EAX = msr.tr1; - break; - case 0x0e: - EAX = msr.tr12; - break; - case 0x10: - EAX = tsc & 0xffffffff; - EDX = tsc >> 32; - break; - case 0x11: - EAX = msr.cesr; - break; - case 0x107: - EAX = msr.fcr; - break; - case 0x108: - EAX = msr.fcr2 & 0xffffffff; - EDX = msr.fcr2 >> 32; - break; - case 0x10a: - EAX = cpu_multi & 3; - break; - } - break; - - case CPU_CYRIX3S: - case CPU_EDEN: - EAX = EDX = 0; - switch (ECX) - { - case 0x10: - EAX = tsc & 0xffffffff; - EDX = tsc >> 32; - break; - case 0x2A: - EAX = 0xC4000000; - EDX = 0; - if (cpu_dmulti == 3) - EAX |= ((0 << 25) | (0 << 24) | (0 << 23) | (1 << 22)); - else if (cpu_dmulti == 3.5) - EAX |= ((0 << 25) | (1 << 24) | (0 << 23) | (1 << 22)); - else if (cpu_dmulti == 4) - EAX |= ((0 << 25) | (0 << 24) | (1 << 23) | (0 << 22)); - else if (cpu_dmulti == 4.5) - EAX |= ((0 << 25) | (1 << 24) | (1 << 23) | (0 << 22)); - else if (cpu_dmulti == 5) - EAX |= 0; - else if (cpu_dmulti == 5.5) - EAX |= ((0 << 25) | (1 << 24) | (0 << 23) | (0 << 22)); - else if (cpu_dmulti == 6) - EAX |= ((1 << 25) | (0 << 24) | (1 << 23) | (1 << 22)); - else if (cpu_dmulti == 6.5) - EAX |= ((1 << 25) | (1 << 24) | (1 << 23) | (1 << 22)); - else if (cpu_dmulti == 7) - EAX |= ((1 << 25) | (0 << 24) | (0 << 23) | (1 << 22)); - else - EAX |= ((0 << 25) | (0 << 24) | (0 << 23) | (1 << 22)); - if (cpu_busspeed >= 84000000) - EAX |= (1 << 19); - break; - case 0x1107: - EAX = msr.fcr; - break; - case 0x1108: - EAX = msr.fcr2 & 0xffffffff; - EDX = msr.fcr2 >> 32; - break; - case 0x200: case 0x201: case 0x202: case 0x203: case 0x204: case 0x205: case 0x206: case 0x207: - case 0x208: case 0x209: case 0x20A: case 0x20B: case 0x20C: case 0x20D: case 0x20E: case 0x20F: - if (ECX & 1) - { - EAX = mtrr_physmask_msr[(ECX - 0x200) >> 1] & 0xffffffff; - EDX = mtrr_physmask_msr[(ECX - 0x200) >> 1] >> 32; - } - else - { - EAX = mtrr_physbase_msr[(ECX - 0x200) >> 1] & 0xffffffff; - EDX = mtrr_physbase_msr[(ECX - 0x200) >> 1] >> 32; - } - break; - case 0x250: - EAX = mtrr_fix64k_8000_msr & 0xffffffff; - EDX = mtrr_fix64k_8000_msr >> 32; - break; - case 0x258: - EAX = mtrr_fix16k_8000_msr & 0xffffffff; - EDX = mtrr_fix16k_8000_msr >> 32; - break; - case 0x259: - EAX = mtrr_fix16k_a000_msr & 0xffffffff; - EDX = mtrr_fix16k_a000_msr >> 32; - break; - case 0x268: case 0x269: case 0x26A: case 0x26B: case 0x26C: case 0x26D: case 0x26E: case 0x26F: - EAX = mtrr_fix4k_msr[ECX - 0x268] & 0xffffffff; - EDX = mtrr_fix4k_msr[ECX - 0x268] >> 32; - break; - case 0x2FF: - EAX = mtrr_deftype_msr & 0xffffffff; - EDX = mtrr_deftype_msr >> 32; - break; - } - break; - -#if defined(DEV_BRANCH) && defined(USE_AMD_K5) - case CPU_K5: - case CPU_5K86: -#endif - case CPU_K6: - EAX = EDX = 0; - switch (ECX) - { - case 0x0000000e: - EAX = msr.tr12; - break; - case 0x00000010: - EAX = tsc & 0xffffffff; - EDX = tsc >> 32; - break; - case 0x00000083: - EAX = ecx83_msr & 0xffffffff; - EDX = ecx83_msr >> 32; - break; - case 0xC0000080: - EAX = amd_efer & 0xffffffff; - EDX = amd_efer >> 32; - break; - case 0xC0000082: - EAX = amd_whcr & 0xffffffff; - EDX = amd_whcr >> 32; - break; - default: - x86gpf(NULL, 0); - break; - } - break; + switch (cpu_s->cpu_type) { + case CPU_IBM386SLC: + case CPU_IBM486SLC: + case CPU_IBM486BL: + EAX = EDX = 0; + switch (ECX) { + case 0x1000: + EAX = msr.ibm_por & ((cpu_s->cpu_type > CPU_IBM386SLC) ? 0xffeff : 0xfeff); + break; - case CPU_K6_2: - EAX = EDX = 0; - switch (ECX) - { - case 0x0000000e: - EAX = msr.tr12; - break; - case 0x00000010: - EAX = tsc & 0xffffffff; - EDX = tsc >> 32; - break; - case 0x00000083: - EAX = ecx83_msr & 0xffffffff; - EDX = ecx83_msr >> 32; - break; - case 0xC0000080: - EAX = amd_efer & 0xffffffff; - EDX = amd_efer >> 32; - break; - case 0xC0000081: - EAX = star & 0xffffffff; - EDX = star >> 32; - break; - case 0xC0000082: - EAX = amd_whcr & 0xffffffff; - EDX = amd_whcr >> 32; - break; - default: - x86gpf(NULL, 0); - break; - } - break; + case 0x1001: + EAX = msr.ibm_crcr & 0xffffffffff; + break; - case CPU_K6_2C: - EAX = EDX = 0; - switch (ECX) - { - case 0x0000000e: - EAX = msr.tr12; - break; - case 0x00000010: - EAX = tsc & 0xffffffff; - EDX = tsc >> 32; - break; - case 0x00000083: - EAX = ecx83_msr & 0xffffffff; - EDX = ecx83_msr >> 32; - break; - case 0xC0000080: - EAX = amd_efer & 0xffffffff; - EDX = amd_efer >> 32; - break; - case 0xC0000081: - EAX = star & 0xffffffff; - EDX = star >> 32; - break; - case 0xC0000082: - EAX = amd_whcr & 0xffffffff; - EDX = amd_whcr >> 32; - break; - case 0xC0000085: - EAX = amd_uwccr & 0xffffffff; - EDX = amd_uwccr >> 32; - break; - case 0xC0000087: - EAX = amd_psor & 0xffffffff; - EDX = amd_psor >> 32; - break; - case 0xC0000088: - EAX = amd_pfir & 0xffffffff; - EDX = amd_pfir >> 32; - break; - default: - x86gpf(NULL, 0); - break; - } - break; + case 0x1002: + if ((cpu_s->cpu_type > CPU_IBM386SLC) && cpu_s->multi) + EAX = msr.ibm_por2 & 0x3f000000; + break; + } + break; - case CPU_K6_3: - EAX = EDX = 0; - switch (ECX) - { - case 0x0000000e: - EAX = msr.tr12; - break; - case 0x00000010: - EAX = tsc & 0xffffffff; - EDX = tsc >> 32; - break; - case 0x00000083: - EAX = ecx83_msr & 0xffffffff; - EDX = ecx83_msr >> 32; - break; - case 0xC0000080: - EAX = amd_efer & 0xffffffff; - EDX = amd_efer >> 32; - break; - case 0xC0000081: - EAX = star & 0xffffffff; - EDX = star >> 32; - break; - case 0xC0000082: - EAX = amd_whcr & 0xffffffff; - EDX = amd_whcr >> 32; - break; - case 0xC0000085: - EAX = amd_uwccr & 0xffffffff; - EDX = amd_uwccr >> 32; - break; - case 0xC0000087: - EAX = amd_psor & 0xffffffff; - EDX = amd_psor >> 32; - break; - case 0xC0000088: - EAX = amd_pfir & 0xffffffff; - EDX = amd_pfir >> 32; - break; - case 0xC0000089: - EAX = amd_l2aar & 0xffffffff; - EDX = amd_l2aar >> 32; - break; - default: - x86gpf(NULL, 0); - break; - } - break; - - case CPU_K6_2P: - case CPU_K6_3P: - EAX = EDX = 0; - switch (ECX) - { - case 0x0000000e: - EAX = msr.tr12; - break; - case 0x00000010: - EAX = tsc & 0xffffffff; - EDX = tsc >> 32; - break; - case 0x00000083: - EAX = ecx83_msr & 0xffffffff; - EDX = ecx83_msr >> 32; - break; - case 0xC0000080: - EAX = amd_efer & 0xffffffff; - EDX = amd_efer >> 32; - break; - case 0xC0000081: - EAX = star & 0xffffffff; - EDX = star >> 32; - break; - case 0xC0000082: - EAX = amd_whcr & 0xffffffff; - EDX = amd_whcr >> 32; - break; - case 0xC0000085: - EAX = amd_uwccr & 0xffffffff; - EDX = amd_uwccr >> 32; - break; - case 0xC0000086: - EAX = amd_epmr & 0xffffffff; - EDX = amd_epmr >> 32; - break; - case 0xC0000087: - EAX = amd_psor & 0xffffffff; - EDX = amd_psor >> 32; - break; - case 0xC0000088: - EAX = amd_pfir & 0xffffffff; - EDX = amd_pfir >> 32; - break; - case 0xC0000089: - EAX = amd_l2aar & 0xffffffff; - EDX = amd_l2aar >> 32; - break; - default: - x86gpf(NULL, 0); - break; - } - break; - - case CPU_P24T: - case CPU_PENTIUM: - case CPU_PENTIUMMMX: - EAX = EDX = 0; - switch (ECX) - { - case 0x10: + case CPU_WINCHIP: + case CPU_WINCHIP2: + EAX = EDX = 0; + switch (ECX) { + case 0x02: + EAX = msr.tr1; + break; + case 0x0e: + EAX = msr.tr12; + break; + case 0x10: EAX = tsc & 0xffffffff; EDX = tsc >> 32; break; - } - break; -#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) - case CPU_Cx6x86: - case CPU_Cx6x86L: - case CPU_CxGX1: - case CPU_Cx6x86MX: - switch (ECX) - { - case 0x10: - EAX = tsc & 0xffffffff; - EDX = tsc >> 32; - break; - } - break; -#endif + case 0x11: + EAX = msr.cesr; + break; + case 0x107: + EAX = msr.fcr; + break; + case 0x108: + EAX = msr.fcr2 & 0xffffffff; + EDX = msr.fcr2 >> 32; + break; + case 0x10a: + EAX = cpu_multi & 3; + break; + } + break; - case CPU_PENTIUMPRO: - case CPU_PENTIUM2: - case CPU_PENTIUM2D: - EAX = EDX = 0; - switch (ECX) - { - case 0x10: - EAX = tsc & 0xffffffff; - EDX = tsc >> 32; - break; - case 0x17: - if (cpu_s->cpu_type != CPU_PENTIUM2D) goto i686_invalid_rdmsr; - EAX = ecx17_msr & 0xffffffff; - EDX = ecx17_msr >> 32; - break; - case 0x1B: - EAX = apic_base_msr & 0xffffffff; - EDX = apic_base_msr >> 32; - cpu_log("APIC_BASE read : %08X%08X\n", EDX, EAX); - break; - case 0x2A: - EAX = 0xC4000000; - EDX = 0; - if (cpu_dmulti == 2.5) - EAX |= ((0 << 25) | (1 << 24) | (1 << 23) | (1 << 22)); - else if (cpu_dmulti == 3) - EAX |= ((0 << 25) | (0 << 24) | (0 << 23) | (1 << 22)); - else if (cpu_dmulti == 3.5) - EAX |= ((0 << 25) | (1 << 24) | (0 << 23) | (1 << 22)); - else if (cpu_dmulti == 4) - EAX |= ((0 << 25) | (0 << 24) | (1 << 23) | (0 << 22)); - else if (cpu_dmulti == 4.5) - EAX |= ((0 << 25) | (1 << 24) | (1 << 23) | (0 << 22)); - else if (cpu_dmulti == 5) - EAX |= 0; - else if (cpu_dmulti == 5.5) - EAX |= ((0 << 25) | (1 << 24) | (0 << 23) | (0 << 22)); - else if (cpu_dmulti == 6) - EAX |= ((1 << 25) | (0 << 24) | (1 << 23) | (1 << 22)); - else if (cpu_dmulti == 6.5) - EAX |= ((1 << 25) | (1 << 24) | (1 << 23) | (1 << 22)); - else if (cpu_dmulti == 7) - EAX |= ((1 << 25) | (0 << 24) | (0 << 23) | (1 << 22)); - else if (cpu_dmulti == 7.5) - EAX |= ((1 << 25) | (1 << 24) | (0 << 23) | (1 << 22)); - else if (cpu_dmulti == 8) - EAX |= ((1 << 25) | (0 << 24) | (1 << 23) | (0 << 22)); - else - EAX |= ((0 << 25) | (1 << 24) | (1 << 23) | (1 << 22)); - if (cpu_s->cpu_type != CPU_PENTIUMPRO) { - if (cpu_busspeed >= 84000000) - EAX |= (1 << 19); - } - break; - case 0x79: - EAX = ecx79_msr & 0xffffffff; - EDX = ecx79_msr >> 32; - break; - case 0x88: case 0x89: case 0x8A: case 0x8B: - EAX = ecx8x_msr[ECX - 0x88] & 0xffffffff; - EDX = ecx8x_msr[ECX - 0x88] >> 32; - break; - case 0xC1: case 0xC2: case 0xC3: case 0xC4: case 0xC5: case 0xC6: case 0xC7: case 0xC8: - EAX = msr_ia32_pmc[ECX - 0xC1] & 0xffffffff; - EDX = msr_ia32_pmc[ECX - 0xC1] >> 32; - break; - case 0xFE: - EAX = mtrr_cap_msr & 0xffffffff; - EDX = mtrr_cap_msr >> 32; - break; - case 0x116: - EAX = ecx116_msr & 0xffffffff; - EDX = ecx116_msr >> 32; - break; - case 0x118: case 0x119: case 0x11A: case 0x11B: - EAX = ecx11x_msr[ECX - 0x118] & 0xffffffff; - EDX = ecx11x_msr[ECX - 0x118] >> 32; - break; - case 0x11E: - EAX = ecx11e_msr & 0xffffffff; - EDX = ecx11e_msr >> 32; - break; - case 0x174: - if (cpu_s->cpu_type == CPU_PENTIUMPRO) goto i686_invalid_rdmsr; - EAX &= 0xFFFF0000; - EAX |= cs_msr; - EDX = 0x00000000; - break; - case 0x175: - if (cpu_s->cpu_type == CPU_PENTIUMPRO) goto i686_invalid_rdmsr; - EAX = esp_msr; - EDX = 0x00000000; - break; - case 0x176: - if (cpu_s->cpu_type == CPU_PENTIUMPRO) goto i686_invalid_rdmsr; - EAX = eip_msr; - EDX = 0x00000000; - break; - case 0x179: - EAX = EDX = 0x00000000; - break; - case 0x186: - EAX = ecx186_msr & 0xffffffff; - EDX = ecx186_msr >> 32; - break; - case 0x187: - EAX = ecx187_msr & 0xffffffff; - EDX = ecx187_msr >> 32; - break; - case 0x1E0: - EAX = ecx1e0_msr & 0xffffffff; - EDX = ecx1e0_msr >> 32; - break; - case 0x200: case 0x201: case 0x202: case 0x203: case 0x204: case 0x205: case 0x206: case 0x207: - case 0x208: case 0x209: case 0x20A: case 0x20B: case 0x20C: case 0x20D: case 0x20E: case 0x20F: - if (ECX & 1) - { - EAX = mtrr_physmask_msr[(ECX - 0x200) >> 1] & 0xffffffff; - EDX = mtrr_physmask_msr[(ECX - 0x200) >> 1] >> 32; - } - else - { - EAX = mtrr_physbase_msr[(ECX - 0x200) >> 1] & 0xffffffff; - EDX = mtrr_physbase_msr[(ECX - 0x200) >> 1] >> 32; - } - break; + case CPU_CYRIX3S: + case CPU_EDEN: + EAX = EDX = 0; + switch (ECX) { + case 0x10: + EAX = tsc & 0xffffffff; + EDX = tsc >> 32; + break; + case 0x2a: + EAX = 0xc4000000; + EDX = 0; + if (cpu_dmulti == 3) + EAX |= ((0 << 25) | (0 << 24) | (0 << 23) | (1 << 22)); + else if (cpu_dmulti == 3.5) + EAX |= ((0 << 25) | (1 << 24) | (0 << 23) | (1 << 22)); + else if (cpu_dmulti == 4) + EAX |= ((0 << 25) | (0 << 24) | (1 << 23) | (0 << 22)); + else if (cpu_dmulti == 4.5) + EAX |= ((0 << 25) | (1 << 24) | (1 << 23) | (0 << 22)); + else if (cpu_dmulti == 5) + EAX |= 0; + else if (cpu_dmulti == 5.5) + EAX |= ((0 << 25) | (1 << 24) | (0 << 23) | (0 << 22)); + else if (cpu_dmulti == 6) + EAX |= ((1 << 25) | (0 << 24) | (1 << 23) | (1 << 22)); + else if (cpu_dmulti == 6.5) + EAX |= ((1 << 25) | (1 << 24) | (1 << 23) | (1 << 22)); + else if (cpu_dmulti == 7) + EAX |= ((1 << 25) | (0 << 24) | (0 << 23) | (1 << 22)); + else + EAX |= ((0 << 25) | (0 << 24) | (0 << 23) | (1 << 22)); + if (cpu_busspeed >= 84000000) + EAX |= (1 << 19); + break; + case 0x1107: + EAX = msr.fcr; + break; + case 0x1108: + EAX = msr.fcr2 & 0xffffffff; + EDX = msr.fcr2 >> 32; + break; + case 0x200: case 0x201: case 0x202: case 0x203: + case 0x204: case 0x205: case 0x206: case 0x207: + case 0x208: case 0x209: case 0x20a: case 0x20b: + case 0x20c: case 0x20d: case 0x20e: case 0x20f: + if (ECX & 1) { + EAX = msr.mtrr_physmask[(ECX - 0x200) >> 1] & 0xffffffff; + EDX = msr.mtrr_physmask[(ECX - 0x200) >> 1] >> 32; + } else { + EAX = msr.mtrr_physbase[(ECX - 0x200) >> 1] & 0xffffffff; + EDX = msr.mtrr_physbase[(ECX - 0x200) >> 1] >> 32; + } + break; case 0x250: - EAX = mtrr_fix64k_8000_msr & 0xffffffff; - EDX = mtrr_fix64k_8000_msr >> 32; - break; + EAX = msr.mtrr_fix64k_8000 & 0xffffffff; + EDX = msr.mtrr_fix64k_8000 >> 32; + break; case 0x258: - EAX = mtrr_fix16k_8000_msr & 0xffffffff; - EDX = mtrr_fix16k_8000_msr >> 32; - break; + EAX = msr.mtrr_fix16k_8000 & 0xffffffff; + EDX = msr.mtrr_fix16k_8000 >> 32; + break; case 0x259: - EAX = mtrr_fix16k_a000_msr & 0xffffffff; - EDX = mtrr_fix16k_a000_msr >> 32; - break; - case 0x268: case 0x269: case 0x26A: case 0x26B: case 0x26C: case 0x26D: case 0x26E: case 0x26F: - EAX = mtrr_fix4k_msr[ECX - 0x268] & 0xffffffff; - EDX = mtrr_fix4k_msr[ECX - 0x268] >> 32; - break; + EAX = msr.mtrr_fix16k_a000 & 0xffffffff; + EDX = msr.mtrr_fix16k_a000 >> 32; + break; + case 0x268: case 0x269: case 0x26a: case 0x26b: + case 0x26c: case 0x26d: case 0x26e: case 0x26f: + EAX = msr.mtrr_fix4k[ECX - 0x268] & 0xffffffff; + EDX = msr.mtrr_fix4k[ECX - 0x268] >> 32; + break; + case 0x2ff: + EAX = msr.mtrr_deftype & 0xffffffff; + EDX = msr.mtrr_deftype >> 32; + break; + } + break; + +#if defined(DEV_BRANCH) && defined(USE_AMD_K5) + case CPU_K5: + case CPU_5K86: +#endif + case CPU_K6: + case CPU_K6_2: + case CPU_K6_2C: + case CPU_K6_3: + case CPU_K6_2P: + case CPU_K6_3P: + EAX = EDX = 0; + switch (ECX) { + case 0x0000000e: + EAX = msr.tr12; + break; + case 0x00000010: + EAX = tsc & 0xffffffff; + EDX = tsc >> 32; + break; + case 0x00000083: + EAX = msr.ecx83 & 0xffffffff; + EDX = msr.ecx83 >> 32; + break; + case 0xc0000080: + EAX = msr.amd_efer & 0xffffffff; + EDX = msr.amd_efer >> 32; + break; + case 0xc0000081: + if (cpu_s->cpu_type < CPU_K6_2) + goto amd_k_invalid_rdmsr; + + EAX = msr.star & 0xffffffff; + EDX = msr.star >> 32; + break; + case 0xc0000082: + EAX = msr.amd_whcr & 0xffffffff; + EDX = msr.amd_whcr >> 32; + break; + case 0xc0000085: + if (cpu_s->cpu_type < CPU_K6_2C) + goto amd_k_invalid_rdmsr; + + EAX = msr.amd_uwccr & 0xffffffff; + EDX = msr.amd_uwccr >> 32; + break; + case 0xc0000086: + if (cpu_s->cpu_type < CPU_K6_2P) + goto amd_k_invalid_rdmsr; + + EAX = msr.amd_epmr & 0xffffffff; + EDX = msr.amd_epmr >> 32; + break; + case 0xc0000087: + if (cpu_s->cpu_type < CPU_K6_2C) + goto amd_k_invalid_rdmsr; + + EAX = msr.amd_psor & 0xffffffff; + EDX = msr.amd_psor >> 32; + break; + case 0xc0000088: + if (cpu_s->cpu_type < CPU_K6_2C) + goto amd_k_invalid_rdmsr; + + EAX = msr.amd_pfir & 0xffffffff; + EDX = msr.amd_pfir >> 32; + break; + case 0xc0000089: + if (cpu_s->cpu_type < CPU_K6_3) + goto amd_k_invalid_rdmsr; + + EAX = msr.amd_l2aar & 0xffffffff; + EDX = msr.amd_l2aar >> 32; + break; + default: +amd_k_invalid_rdmsr: + x86gpf(NULL, 0); + break; + } + break; + + case CPU_P24T: + case CPU_PENTIUM: + case CPU_PENTIUMMMX: +#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) + case CPU_Cx6x86: + case CPU_Cx6x86L: + case CPU_CxGX1: + case CPU_Cx6x86MX: + if (cpu_s->cpu_type < CPU_Cx6x86) +#endif + EAX = EDX = 0; + switch (ECX) { + case 0x10: + EAX = tsc & 0xffffffff; + EDX = tsc >> 32; + break; + } + break; + + case CPU_PENTIUMPRO: + case CPU_PENTIUM2: + case CPU_PENTIUM2D: + EAX = EDX = 0; + switch (ECX) { + case 0x10: + EAX = tsc & 0xffffffff; + EDX = tsc >> 32; + break; + case 0x17: + if (cpu_s->cpu_type != CPU_PENTIUM2D) + goto i686_invalid_rdmsr; + + EAX = msr.ecx17 & 0xffffffff; + EDX = msr.ecx17 >> 32; + break; + case 0x1B: + EAX = msr.apic_base & 0xffffffff; + EDX = msr.apic_base >> 32; + cpu_log("APIC_BASE read : %08X%08X\n", EDX, EAX); + break; + case 0x2a: + EAX = 0xc4000000; + EDX = 0; + if (cpu_dmulti == 2.5) + EAX |= ((0 << 25) | (1 << 24) | (1 << 23) | (1 << 22)); + else if (cpu_dmulti == 3) + EAX |= ((0 << 25) | (0 << 24) | (0 << 23) | (1 << 22)); + else if (cpu_dmulti == 3.5) + EAX |= ((0 << 25) | (1 << 24) | (0 << 23) | (1 << 22)); + else if (cpu_dmulti == 4) + EAX |= ((0 << 25) | (0 << 24) | (1 << 23) | (0 << 22)); + else if (cpu_dmulti == 4.5) + EAX |= ((0 << 25) | (1 << 24) | (1 << 23) | (0 << 22)); + else if (cpu_dmulti == 5) + EAX |= 0; + else if (cpu_dmulti == 5.5) + EAX |= ((0 << 25) | (1 << 24) | (0 << 23) | (0 << 22)); + else if (cpu_dmulti == 6) + EAX |= ((1 << 25) | (0 << 24) | (1 << 23) | (1 << 22)); + else if (cpu_dmulti == 6.5) + EAX |= ((1 << 25) | (1 << 24) | (1 << 23) | (1 << 22)); + else if (cpu_dmulti == 7) + EAX |= ((1 << 25) | (0 << 24) | (0 << 23) | (1 << 22)); + else if (cpu_dmulti == 7.5) + EAX |= ((1 << 25) | (1 << 24) | (0 << 23) | (1 << 22)); + else if (cpu_dmulti == 8) + EAX |= ((1 << 25) | (0 << 24) | (1 << 23) | (0 << 22)); + else + EAX |= ((0 << 25) | (1 << 24) | (1 << 23) | (1 << 22)); + if (cpu_s->cpu_type != CPU_PENTIUMPRO) { + if (cpu_busspeed >= 84000000) + EAX |= (1 << 19); + } + break; + case 0x79: + EAX = msr.ecx79 & 0xffffffff; + EDX = msr.ecx79 >> 32; + break; + case 0x88: case 0x89: case 0x8a: case 0x8b: + EAX = msr.ecx8x[ECX - 0x88] & 0xffffffff; + EDX = msr.ecx8x[ECX - 0x88] >> 32; + break; + case 0xc1: case 0xc2: case 0xc3: case 0xc4: + case 0xc5: case 0xc6: case 0xc7: case 0xc8: + EAX = msr.ia32_pmc[ECX - 0xC1] & 0xffffffff; + EDX = msr.ia32_pmc[ECX - 0xC1] >> 32; + break; + case 0xfe: + EAX = msr.mtrr_cap & 0xffffffff; + EDX = msr.mtrr_cap >> 32; + break; + case 0x116: + EAX = msr.ecx116 & 0xffffffff; + EDX = msr.ecx116 >> 32; + break; + case 0x118: case 0x119: case 0x11a: case 0x11b: + EAX = msr.ecx11x[ECX - 0x118] & 0xffffffff; + EDX = msr.ecx11x[ECX - 0x118] >> 32; + break; + case 0x11e: + EAX = msr.ecx11e & 0xffffffff; + EDX = msr.ecx11e >> 32; + break; + case 0x174: + if (cpu_s->cpu_type == CPU_PENTIUMPRO) + goto i686_invalid_rdmsr; + + EAX &= 0xffff0000; + EAX |= msr.sysenter_cs; + EDX = 0x00000000; + break; + case 0x175: + if (cpu_s->cpu_type == CPU_PENTIUMPRO) + goto i686_invalid_rdmsr; + + EAX = msr.sysenter_esp; + EDX = 0x00000000; + break; + case 0x176: + if (cpu_s->cpu_type == CPU_PENTIUMPRO) + goto i686_invalid_rdmsr; + + EAX = msr.sysenter_eip; + EDX = 0x00000000; + break; + case 0x179: + EAX = EDX = 0x00000000; + break; + case 0x186: + EAX = msr.ecx186 & 0xffffffff; + EDX = msr.ecx186 >> 32; + break; + case 0x187: + EAX = msr.ecx187 & 0xffffffff; + EDX = msr.ecx187 >> 32; + break; + case 0x1e0: + EAX = msr.ecx1e0 & 0xffffffff; + EDX = msr.ecx1e0 >> 32; + break; + case 0x200: case 0x201: case 0x202: case 0x203: + case 0x204: case 0x205: case 0x206: case 0x207: + case 0x208: case 0x209: case 0x20a: case 0x20b: + case 0x20c: case 0x20d: case 0x20e: case 0x20f: + if (ECX & 1) { + EAX = msr.mtrr_physmask[(ECX - 0x200) >> 1] & 0xffffffff; + EDX = msr.mtrr_physmask[(ECX - 0x200) >> 1] >> 32; + } else { + EAX = msr.mtrr_physbase[(ECX - 0x200) >> 1] & 0xffffffff; + EDX = msr.mtrr_physbase[(ECX - 0x200) >> 1] >> 32; + } + break; + case 0x250: + EAX = msr.mtrr_fix64k_8000 & 0xffffffff; + EDX = msr.mtrr_fix64k_8000 >> 32; + break; + case 0x258: + EAX = msr.mtrr_fix16k_8000 & 0xffffffff; + EDX = msr.mtrr_fix16k_8000 >> 32; + break; + case 0x259: + EAX = msr.mtrr_fix16k_a000 & 0xffffffff; + EDX = msr.mtrr_fix16k_a000 >> 32; + break; + case 0x268: case 0x269: case 0x26a: case 0x26b: + case 0x26c: case 0x26d: case 0x26e: case 0x26f: + EAX = msr.mtrr_fix4k[ECX - 0x268] & 0xffffffff; + EDX = msr.mtrr_fix4k[ECX - 0x268] >> 32; + break; case 0x277: - EAX = pat_msr & 0xffffffff; - EDX = pat_msr >> 32; - break; - case 0x2FF: - EAX = mtrr_deftype_msr & 0xffffffff; - EDX = mtrr_deftype_msr >> 32; - break; + EAX = msr.pat & 0xffffffff; + EDX = msr.pat >> 32; + break; + case 0x2ff: + EAX = msr.mtrr_deftype & 0xffffffff; + EDX = msr.mtrr_deftype >> 32; + break; case 0x404: - EAX = ecx404_msr & 0xffffffff; - EDX = ecx404_msr >> 32; - break; + EAX = msr.ecx404 & 0xffffffff; + EDX = msr.ecx404 >> 32; + break; case 0x408: - EAX = ecx408_msr & 0xffffffff; - EDX = ecx408_msr >> 32; - break; + EAX = msr.ecx408 & 0xffffffff; + EDX = msr.ecx408 >> 32; + break; case 0x40c: - EAX = ecx40c_msr & 0xffffffff; - EDX = ecx40c_msr >> 32; - break; + EAX = msr.ecx40c & 0xffffffff; + EDX = msr.ecx40c >> 32; + break; case 0x410: - EAX = ecx410_msr & 0xffffffff; - EDX = ecx410_msr >> 32; - break; + EAX = msr.ecx410 & 0xffffffff; + EDX = msr.ecx410 >> 32; + break; case 0x570: - EAX = ecx570_msr & 0xffffffff; - EDX = ecx570_msr >> 32; - break; + EAX = msr.ecx570 & 0xffffffff; + EDX = msr.ecx570 >> 32; + break; case 0x1002ff: - EAX = ecx1002ff_msr & 0xffffffff; - EDX = ecx1002ff_msr >> 32; - break; + EAX = msr.ecx1002ff & 0xffffffff; + EDX = msr.ecx1002ff >> 32; + break; case 0xf0f00250: - EAX = ecxf0f00250_msr & 0xffffffff; - EDX = ecxf0f00250_msr >> 32; - break; + EAX = msr.ecxf0f00250 & 0xffffffff; + EDX = msr.ecxf0f00250 >> 32; + break; case 0xf0f00258: - EAX = ecxf0f00258_msr & 0xffffffff; - EDX = ecxf0f00258_msr >> 32; - break; + EAX = msr.ecxf0f00258 & 0xffffffff; + EDX = msr.ecxf0f00258 >> 32; + break; case 0xf0f00259: - EAX = ecxf0f00259_msr & 0xffffffff; - EDX = ecxf0f00259_msr >> 32; - break; + EAX = msr.ecxf0f00259 & 0xffffffff; + EDX = msr.ecxf0f00259 >> 32; + break; default: i686_invalid_rdmsr: - cpu_log("RDMSR: Invalid MSR: %08X\n", ECX); - x86gpf(NULL, 0); - break; - } - break; - } + cpu_log("RDMSR: Invalid MSR: %08X\n", ECX); + x86gpf(NULL, 0); + break; + } + break; + } - cpu_log("RDMSR %08X %08X%08X\n", ECX, EDX, EAX); + cpu_log("RDMSR %08X %08X%08X\n", ECX, EDX, EAX); } -void cpu_WRMSR() + +void +cpu_WRMSR(void) { - uint64_t temp; + uint64_t temp; - cpu_log("WRMSR %08X %08X%08X\n", ECX, EDX, EAX); - switch (cpu_s->cpu_type) - { - case CPU_IBM386SLC: - switch (ECX) - { - case 0x1000: - ibm_por_msr = EAX & 0xfeff; - if (EAX & (1 << 7)) - cpu_cache_int_enabled = 1; - else - cpu_cache_int_enabled = 0; - break; - case 0x1001: - ibm_crcr_msr = EAX & 0xffffffffff; - break; - } - break; - - case CPU_IBM486BL: - case CPU_IBM486SLC: - switch (ECX) - { - case 0x1000: - ibm_por_msr = EAX & 0xffeff; - if (EAX & (1 << 7)) - cpu_cache_int_enabled = 1; - else - cpu_cache_int_enabled = 0; - break; - case 0x1001: - ibm_crcr_msr = EAX & 0xffffffffff; - break; - if (cpu_s->multi) { - case 0x1002: - ibm_por2_msr = EAX & 0x3f000000; - } - break; - } - break; - - case CPU_WINCHIP: - case CPU_WINCHIP2: - switch (ECX) - { - case 0x02: - msr.tr1 = EAX & 2; - break; - case 0x0e: - msr.tr12 = EAX & 0x228; - break; - case 0x10: - tsc = EAX | ((uint64_t)EDX << 32); - break; - case 0x11: - msr.cesr = EAX & 0xff00ff; - break; - case 0x107: - msr.fcr = EAX; - if (EAX & (1 << 9)) - cpu_features |= CPU_FEATURE_MMX; - else - cpu_features &= ~CPU_FEATURE_MMX; - if (EAX & (1 << 1)) - cpu_features |= CPU_FEATURE_CX8; - else - cpu_features &= ~CPU_FEATURE_CX8; - if ((EAX & (1 << 20)) && cpu_s->cpu_type >= CPU_WINCHIP2) - cpu_features |= CPU_FEATURE_3DNOW; - else - cpu_features &= ~CPU_FEATURE_3DNOW; - if (EAX & (1 << 29)) - CPUID = 0; - else - CPUID = cpu_s->cpuid_model; - break; - case 0x108: - msr.fcr2 = EAX | ((uint64_t)EDX << 32); - break; - case 0x109: - msr.fcr3 = EAX | ((uint64_t)EDX << 32); - break; - } - break; - case CPU_CYRIX3S: - case CPU_EDEN: - switch (ECX) - { - case 0x10: - tsc = EAX | ((uint64_t)EDX << 32); - break; - case 0x1107: - msr.fcr = EAX; - if (EAX & (1 << 1)) - cpu_features |= CPU_FEATURE_CX8; - else - cpu_features &= ~CPU_FEATURE_CX8; - break; - case 0x1108: - msr.fcr2 = EAX | ((uint64_t)EDX << 32); - break; - case 0x1109: - msr.fcr3 = EAX | ((uint64_t)EDX << 32); - break; - case 0x200: case 0x201: case 0x202: case 0x203: case 0x204: case 0x205: case 0x206: case 0x207: - case 0x208: case 0x209: case 0x20A: case 0x20B: case 0x20C: case 0x20D: case 0x20E: case 0x20F: - if (ECX & 1) - mtrr_physmask_msr[(ECX - 0x200) >> 1] = EAX | ((uint64_t)EDX << 32); - else - mtrr_physbase_msr[(ECX - 0x200) >> 1] = EAX | ((uint64_t)EDX << 32); - break; - case 0x250: - mtrr_fix64k_8000_msr = EAX | ((uint64_t)EDX << 32); - break; - case 0x258: - mtrr_fix16k_8000_msr = EAX | ((uint64_t)EDX << 32); - break; - case 0x259: - mtrr_fix16k_a000_msr = EAX | ((uint64_t)EDX << 32); - break; - case 0x268: case 0x269: case 0x26A: case 0x26B: case 0x26C: case 0x26D: case 0x26E: case 0x26F: - mtrr_fix4k_msr[ECX - 0x268] = EAX | ((uint64_t)EDX << 32); - break; - case 0x2FF: - mtrr_deftype_msr = EAX | ((uint64_t)EDX << 32); - break; - } - break; - -#if defined(DEV_BRANCH) && defined(USE_AMD_K5) - case CPU_K5: - case CPU_5K86: -#endif - case CPU_K6: - switch (ECX) - { - case 0x0e: - msr.tr12 = EAX & 0x228; - break; - case 0x10: - tsc = EAX | ((uint64_t)EDX << 32); - break; - case 0x83: - ecx83_msr = EAX | ((uint64_t)EDX << 32); - break; - case 0xC0000080: - temp = EAX | ((uint64_t)EDX << 32); - if (temp & ~1ULL) - x86gpf(NULL, 0); - else - amd_efer = temp; - break; - case 0xC0000082: - amd_whcr = EAX | ((uint64_t)EDX << 32); - break; - default: - x86gpf(NULL, 0); - break; - } - break; + cpu_log("WRMSR %08X %08X%08X\n", ECX, EDX, EAX); - case CPU_K6_2: - switch (ECX) - { - case 0x0e: - msr.tr12 = EAX & 0x228; - break; - case 0x10: - tsc = EAX | ((uint64_t)EDX << 32); - break; - case 0x83: - ecx83_msr = EAX | ((uint64_t)EDX << 32); - break; - case 0xC0000080: - temp = EAX | ((uint64_t)EDX << 32); - if (temp & ~1ULL) - x86gpf(NULL, 0); - else - amd_efer = temp; - break; - case 0xC0000081: - star = EAX | ((uint64_t)EDX << 32); - break; - case 0xC0000082: - amd_whcr = EAX | ((uint64_t)EDX << 32); - break; - default: - x86gpf(NULL, 0); - break; - } - break; + switch (cpu_s->cpu_type) { + case CPU_IBM386SLC: + case CPU_IBM486BL: + case CPU_IBM486SLC: + switch (ECX) { + case 0x1000: + msr.ibm_por = EAX & ((cpu_s->cpu_type > CPU_IBM386SLC) ? 0xffeff : 0xfeff); + cpu_cache_int_enabled = (EAX & (1 << 7)); + break; + case 0x1001: + msr.ibm_crcr = EAX & 0xffffffffff; + break; + case 0x1002: + if ((cpu_s->cpu_type > CPU_IBM386SLC) && cpu_s->multi) + msr.ibm_por2 = EAX & 0x3f000000; + break; + } + break; - case CPU_K6_2C: - switch (ECX) - { - case 0x0e: - msr.tr12 = EAX & 0x228; - break; - case 0x10: - tsc = EAX | ((uint64_t)EDX << 32); - break; - case 0x83: - ecx83_msr = EAX | ((uint64_t)EDX << 32); - break; - case 0xC0000080: - temp = EAX | ((uint64_t)EDX << 32); - if (temp & ~0xfULL) - x86gpf(NULL, 0); - else - amd_efer = temp; - break; - case 0xC0000081: - star = EAX | ((uint64_t)EDX << 32); - break; - case 0xC0000082: - amd_whcr = EAX | ((uint64_t)EDX << 32); - break; - case 0xC0000085: - amd_uwccr = EAX | ((uint64_t)EDX << 32); - break; - case 0xC0000087: - amd_psor = EAX | ((uint64_t)EDX << 32); - break; - case 0xC0000088: - amd_pfir = EAX | ((uint64_t)EDX << 32); - break; - default: - x86gpf(NULL, 0); - break; - } - break; - - case CPU_K6_3: - switch (ECX) - { - case 0x0e: - msr.tr12 = EAX & 0x228; - break; - case 0x10: - tsc = EAX | ((uint64_t)EDX << 32); - break; - case 0x83: - ecx83_msr = EAX | ((uint64_t)EDX << 32); - break; - case 0xC0000080: - temp = EAX | ((uint64_t)EDX << 32); - if (temp & ~0x1fULL) - x86gpf(NULL, 0); - else - amd_efer = temp; - break; - case 0xC0000081: - star = EAX | ((uint64_t)EDX << 32); - break; - case 0xC0000082: - amd_whcr = EAX | ((uint64_t)EDX << 32); - break; - case 0xC0000085: - amd_uwccr = EAX | ((uint64_t)EDX << 32); - break; - case 0xC0000087: - amd_psor = EAX | ((uint64_t)EDX << 32); - break; - case 0xC0000088: - amd_pfir = EAX | ((uint64_t)EDX << 32); - break; - case 0xC0000089: - amd_l2aar = EAX | ((uint64_t)EDX << 32); - break; - default: - x86gpf(NULL, 0); - break; - } - break; - - case CPU_K6_2P: - case CPU_K6_3P: - switch (ECX) - { - case 0x0e: - msr.tr12 = EAX & 0x228; - break; - case 0x10: - tsc = EAX | ((uint64_t)EDX << 32); - break; - case 0x83: - ecx83_msr = EAX | ((uint64_t)EDX << 32); - break; - case 0xC0000080: - temp = EAX | ((uint64_t)EDX << 32); - if (temp & ~0x1fULL) - x86gpf(NULL, 0); - else - amd_efer = temp; - break; - case 0xC0000081: - star = EAX | ((uint64_t)EDX << 32); - break; - case 0xC0000082: - amd_whcr = EAX | ((uint64_t)EDX << 32); - break; - case 0xC0000085: - amd_uwccr = EAX | ((uint64_t)EDX << 32); - break; - case 0xC0000086: - amd_epmr = EAX | ((uint64_t)EDX << 32); - break; - case 0xC0000087: - amd_psor = EAX | ((uint64_t)EDX << 32); - break; - case 0xC0000088: - amd_pfir = EAX | ((uint64_t)EDX << 32); - break; - case 0xC0000089: - amd_l2aar = EAX | ((uint64_t)EDX << 32); - break; - default: - x86gpf(NULL, 0); - break; - } - break; - - case CPU_P24T: - case CPU_PENTIUM: - case CPU_PENTIUMMMX: - switch (ECX) - { - case 0x10: + case CPU_WINCHIP: + case CPU_WINCHIP2: + switch (ECX) { + case 0x02: + msr.tr1 = EAX & 2; + break; + case 0x0e: + msr.tr12 = EAX & 0x228; + break; + case 0x10: tsc = EAX | ((uint64_t)EDX << 32); break; - case 0x8B: - cpu_log("WRMSR: Invalid MSR: 0x8B\n"); - x86gpf(NULL, 0); /*Needed for Vista to correctly break on Pentium*/ + case 0x11: + msr.cesr = EAX & 0xff00ff; break; - } - break; -#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) - case CPU_Cx6x86: - case CPU_Cx6x86L: - case CPU_CxGX1: - case CPU_Cx6x86MX: - switch (ECX) - { - case 0x10: - tsc = EAX | ((uint64_t)EDX << 32); - break; - } - break; -#endif + case 0x107: + msr.fcr = EAX; + if (EAX & (1 << 9)) + cpu_features |= CPU_FEATURE_MMX; + else + cpu_features &= ~CPU_FEATURE_MMX; + if (EAX & (1 << 1)) + cpu_features |= CPU_FEATURE_CX8; + else + cpu_features &= ~CPU_FEATURE_CX8; + if ((EAX & (1 << 20)) && cpu_s->cpu_type >= CPU_WINCHIP2) + cpu_features |= CPU_FEATURE_3DNOW; + else + cpu_features &= ~CPU_FEATURE_3DNOW; + if (EAX & (1 << 29)) + CPUID = 0; + else + CPUID = cpu_s->cpuid_model; + break; + case 0x108: + msr.fcr2 = EAX | ((uint64_t)EDX << 32); + break; + case 0x109: + msr.fcr3 = EAX | ((uint64_t)EDX << 32); + break; + } + break; - case CPU_PENTIUMPRO: - case CPU_PENTIUM2: - case CPU_PENTIUM2D: - switch (ECX) - { - case 0x10: - tsc = EAX | ((uint64_t)EDX << 32); - break; - case 0x17: - if (cpu_s->cpu_type != CPU_PENTIUM2D) goto i686_invalid_wrmsr; - ecx17_msr = EAX | ((uint64_t)EDX << 32); - break; - case 0x1B: - cpu_log("APIC_BASE write: %08X%08X\n", EDX, EAX); - // apic_base_msr = EAX | ((uint64_t)EDX << 32); - break; - case 0x2A: - ecx2a_msr = EAX | ((uint64_t)EDX << 32); - break; - case 0x79: - ecx79_msr = EAX | ((uint64_t)EDX << 32); - break; - case 0x88: case 0x89: case 0x8A: case 0x8B: - ecx8x_msr[ECX - 0x88] = EAX | ((uint64_t)EDX << 32); - break; - case 0xC1: case 0xC2: case 0xC3: case 0xC4: case 0xC5: case 0xC6: case 0xC7: case 0xC8: - msr_ia32_pmc[ECX - 0xC1] = EAX | ((uint64_t)EDX << 32); - break; - case 0xFE: - mtrr_cap_msr = EAX | ((uint64_t)EDX << 32); - break; - case 0x116: - ecx116_msr = EAX | ((uint64_t)EDX << 32); - break; - case 0x118: case 0x119: case 0x11A: case 0x11B: - ecx11x_msr[ECX - 0x118] = EAX | ((uint64_t)EDX << 32); - break; - case 0x11E: - ecx11e_msr = EAX | ((uint64_t)EDX << 32); - break; - case 0x174: - if (cpu_s->cpu_type == CPU_PENTIUMPRO) goto i686_invalid_wrmsr; - cs_msr = EAX & 0xFFFF; - break; - case 0x175: - if (cpu_s->cpu_type == CPU_PENTIUMPRO) goto i686_invalid_wrmsr; - esp_msr = EAX; - break; - case 0x176: - if (cpu_s->cpu_type == CPU_PENTIUMPRO) goto i686_invalid_wrmsr; - eip_msr = EAX; - break; - case 0x179: - break; - case 0x186: - ecx186_msr = EAX | ((uint64_t)EDX << 32); - break; - case 0x187: - ecx187_msr = EAX | ((uint64_t)EDX << 32); - break; - case 0x1E0: - ecx1e0_msr = EAX | ((uint64_t)EDX << 32); - break; - case 0x200: case 0x201: case 0x202: case 0x203: case 0x204: case 0x205: case 0x206: case 0x207: - case 0x208: case 0x209: case 0x20A: case 0x20B: case 0x20C: case 0x20D: case 0x20E: case 0x20F: - if (ECX & 1) - mtrr_physmask_msr[(ECX - 0x200) >> 1] = EAX | ((uint64_t)EDX << 32); - else - mtrr_physbase_msr[(ECX - 0x200) >> 1] = EAX | ((uint64_t)EDX << 32); - break; + case CPU_CYRIX3S: + case CPU_EDEN: + switch (ECX) { + case 0x10: + tsc = EAX | ((uint64_t)EDX << 32); + break; + case 0x1107: + msr.fcr = EAX; + if (EAX & (1 << 1)) + cpu_features |= CPU_FEATURE_CX8; + else + cpu_features &= ~CPU_FEATURE_CX8; + break; + case 0x1108: + msr.fcr2 = EAX | ((uint64_t)EDX << 32); + break; + case 0x1109: + msr.fcr3 = EAX | ((uint64_t)EDX << 32); + break; + case 0x200: case 0x201: case 0x202: case 0x203: + case 0x204: case 0x205: case 0x206: case 0x207: + case 0x208: case 0x209: case 0x20a: case 0x20b: + case 0x20c: case 0x20d: case 0x20e: case 0x20f: + if (ECX & 1) + msr.mtrr_physmask[(ECX - 0x200) >> 1] = EAX | ((uint64_t)EDX << 32); + else + msr.mtrr_physbase[(ECX - 0x200) >> 1] = EAX | ((uint64_t)EDX << 32); + break; case 0x250: - mtrr_fix64k_8000_msr = EAX | ((uint64_t)EDX << 32); - break; + msr.mtrr_fix64k_8000 = EAX | ((uint64_t)EDX << 32); + break; case 0x258: - mtrr_fix16k_8000_msr = EAX | ((uint64_t)EDX << 32); - break; + msr.mtrr_fix16k_8000 = EAX | ((uint64_t)EDX << 32); + break; case 0x259: - mtrr_fix16k_a000_msr = EAX | ((uint64_t)EDX << 32); - break; + msr.mtrr_fix16k_a000 = EAX | ((uint64_t)EDX << 32); + break; case 0x268: case 0x269: case 0x26A: case 0x26B: case 0x26C: case 0x26D: case 0x26E: case 0x26F: - mtrr_fix4k_msr[ECX - 0x268] = EAX | ((uint64_t)EDX << 32); - break; + msr.mtrr_fix4k[ECX - 0x268] = EAX | ((uint64_t)EDX << 32); + break; + case 0x2ff: + msr.mtrr_deftype = EAX | ((uint64_t)EDX << 32); + break; + } + break; + +#if defined(DEV_BRANCH) && defined(USE_AMD_K5) + case CPU_K5: + case CPU_5K86: +#endif + case CPU_K6: + case CPU_K6_2: + case CPU_K6_2C: + case CPU_K6_3: + case CPU_K6_2P: + case CPU_K6_3P: + switch (ECX) { + case 0x0e: + msr.tr12 = EAX & 0x228; + break; + case 0x10: + tsc = EAX | ((uint64_t)EDX << 32); + break; + case 0x83: + msr.ecx83 = EAX | ((uint64_t)EDX << 32); + break; + case 0xc0000080: + temp = EAX | ((uint64_t)EDX << 32); + if (temp & ~1ULL) + x86gpf(NULL, 0); + else + msr.amd_efer = temp; + break; + case 0xc0000081: + if (cpu_s->cpu_type < CPU_K6_2) + goto amd_k_invalid_wrmsr; + + msr.star = EAX | ((uint64_t)EDX << 32); + break; + case 0xc0000082: + msr.amd_whcr = EAX | ((uint64_t)EDX << 32); + break; + case 0xc0000085: + if (cpu_s->cpu_type < CPU_K6_2C) + goto amd_k_invalid_wrmsr; + + msr.amd_uwccr = EAX | ((uint64_t)EDX << 32); + break; + case 0xc0000086: + if (cpu_s->cpu_type < CPU_K6_2P) + goto amd_k_invalid_wrmsr; + + msr.amd_epmr = EAX | ((uint64_t)EDX << 32); + break; + case 0xc0000087: + if (cpu_s->cpu_type < CPU_K6_2C) + goto amd_k_invalid_wrmsr; + + msr.amd_psor = EAX | ((uint64_t)EDX << 32); + break; + case 0xc0000088: + if (cpu_s->cpu_type < CPU_K6_2C) + goto amd_k_invalid_wrmsr; + + msr.amd_pfir = EAX | ((uint64_t)EDX << 32); + break; + case 0xc0000089: + if (cpu_s->cpu_type < CPU_K6_3) + goto amd_k_invalid_wrmsr; + + msr.amd_l2aar = EAX | ((uint64_t)EDX << 32); + break; + default: +amd_k_invalid_wrmsr: + x86gpf(NULL, 0); + break; + } + break; + + case CPU_P24T: + case CPU_PENTIUM: + case CPU_PENTIUMMMX: +#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) + case CPU_Cx6x86: + case CPU_Cx6x86L: + case CPU_CxGX1: + case CPU_Cx6x86MX: +#endif + switch (ECX) { + case 0x10: + tsc = EAX | ((uint64_t)EDX << 32); + break; + case 0x8b: +#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) + if (cpu_s->cpu_type < CPU_Cx6x86) { +#endif + cpu_log("WRMSR: Invalid MSR: 0x8B\n"); + x86gpf(NULL, 0); /* Needed for Vista to correctly break on Pentium */ +#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) + } +#endif + break; + } + break; + + case CPU_PENTIUMPRO: + case CPU_PENTIUM2: + case CPU_PENTIUM2D: + switch (ECX) { + case 0x10: + tsc = EAX | ((uint64_t)EDX << 32); + break; + case 0x17: + if (cpu_s->cpu_type != CPU_PENTIUM2D) + goto i686_invalid_wrmsr; + + msr.ecx17 = EAX | ((uint64_t)EDX << 32); + break; + case 0x1b: + cpu_log("APIC_BASE write: %08X%08X\n", EDX, EAX); + // msr.apic_base = EAX | ((uint64_t)EDX << 32); + break; + case 0x2a: + break; + case 0x79: + msr.ecx79 = EAX | ((uint64_t)EDX << 32); + break; + case 0x88: case 0x89: case 0x8a: case 0x8b: + msr.ecx8x[ECX - 0x88] = EAX | ((uint64_t)EDX << 32); + break; + case 0xc1: case 0xc2: case 0xc3: case 0xc4: + case 0xc5: case 0xc6: case 0xc7: case 0xc8: + msr.ia32_pmc[ECX - 0xC1] = EAX | ((uint64_t)EDX << 32); + break; + case 0xfe: + msr.mtrr_cap = EAX | ((uint64_t)EDX << 32); + break; + case 0x116: + msr.ecx116 = EAX | ((uint64_t)EDX << 32); + break; + case 0x118: case 0x119: case 0x11a: case 0x11b: + msr.ecx11x[ECX - 0x118] = EAX | ((uint64_t)EDX << 32); + break; + case 0x11e: + msr.ecx11e = EAX | ((uint64_t)EDX << 32); + break; + case 0x174: + if (cpu_s->cpu_type == CPU_PENTIUMPRO) + goto i686_invalid_wrmsr; + + msr.sysenter_cs = EAX & 0xFFFF; + break; + case 0x175: + if (cpu_s->cpu_type == CPU_PENTIUMPRO) + goto i686_invalid_wrmsr; + + msr.sysenter_esp = EAX; + break; + case 0x176: + if (cpu_s->cpu_type == CPU_PENTIUMPRO) + goto i686_invalid_wrmsr; + + msr.sysenter_eip = EAX; + break; + case 0x179: + break; + case 0x186: + msr.ecx186 = EAX | ((uint64_t)EDX << 32); + break; + case 0x187: + msr.ecx187 = EAX | ((uint64_t)EDX << 32); + break; + case 0x1e0: + msr.ecx1e0 = EAX | ((uint64_t)EDX << 32); + break; + case 0x200: case 0x201: case 0x202: case 0x203: + case 0x204: case 0x205: case 0x206: case 0x207: + case 0x208: case 0x209: case 0x20a: case 0x20b: + case 0x20c: case 0x20d: case 0x20e: case 0x20f: + if (ECX & 1) + msr.mtrr_physmask[(ECX - 0x200) >> 1] = EAX | ((uint64_t)EDX << 32); + else + msr.mtrr_physbase[(ECX - 0x200) >> 1] = EAX | ((uint64_t)EDX << 32); + break; + case 0x250: + msr.mtrr_fix64k_8000 = EAX | ((uint64_t)EDX << 32); + break; + case 0x258: + msr.mtrr_fix16k_8000 = EAX | ((uint64_t)EDX << 32); + break; + case 0x259: + msr.mtrr_fix16k_a000 = EAX | ((uint64_t)EDX << 32); + break; + case 0x268: case 0x269: case 0x26a: case 0x26b: + case 0x26c: case 0x26d: case 0x26e: case 0x26f: + msr.mtrr_fix4k[ECX - 0x268] = EAX | ((uint64_t)EDX << 32); + break; case 0x277: - pat_msr = EAX | ((uint64_t)EDX << 32); - break; - case 0x2FF: - mtrr_deftype_msr = EAX | ((uint64_t)EDX << 32); - break; + msr.pat = EAX | ((uint64_t)EDX << 32); + break; + case 0x2ff: + msr.mtrr_deftype = EAX | ((uint64_t)EDX << 32); + break; case 0x404: - ecx404_msr = EAX | ((uint64_t)EDX << 32); - break; + msr.ecx404 = EAX | ((uint64_t)EDX << 32); + break; case 0x408: - ecx408_msr = EAX | ((uint64_t)EDX << 32); - break; + msr.ecx408 = EAX | ((uint64_t)EDX << 32); + break; case 0x40c: - ecx40c_msr = EAX | ((uint64_t)EDX << 32); - break; + msr.ecx40c = EAX | ((uint64_t)EDX << 32); + break; case 0x410: - ecx410_msr = EAX | ((uint64_t)EDX << 32); - break; + msr.ecx410 = EAX | ((uint64_t)EDX << 32); + break; case 0x570: - ecx570_msr = EAX | ((uint64_t)EDX << 32); - break; + msr.ecx570 = EAX | ((uint64_t)EDX << 32); + break; case 0x1002ff: - ecx1002ff_msr = EAX | ((uint64_t)EDX << 32); - break; + msr.ecx1002ff = EAX | ((uint64_t)EDX << 32); + break; case 0xf0f00250: - ecxf0f00250_msr = EAX | ((uint64_t)EDX << 32); - break; + msr.ecxf0f00250 = EAX | ((uint64_t)EDX << 32); + break; case 0xf0f00258: - ecxf0f00258_msr = EAX | ((uint64_t)EDX << 32); - break; + msr.ecxf0f00258 = EAX | ((uint64_t)EDX << 32); + break; case 0xf0f00259: - ecxf0f00259_msr = EAX | ((uint64_t)EDX << 32); - break; + msr.ecxf0f00259 = EAX | ((uint64_t)EDX << 32); + break; default: i686_invalid_wrmsr: - cpu_log("WRMSR: Invalid MSR: %08X\n", ECX); - x86gpf(NULL, 0); - break; - } - break; - } + cpu_log("WRMSR: Invalid MSR: %08X\n", ECX); + x86gpf(NULL, 0); + break; + } + break; + } } -static void cpu_write(uint16_t addr, uint8_t val, void *priv) + +static void +cpu_write(uint16_t addr, uint8_t val, void *priv) { - if (addr == 0xf0) { - /* Writes to F0 clear FPU error and deassert the interrupt. */ - if (is286) - picintc(1 << 13); - else - nmi = 0; - return; - } else if (addr >= 0xf1) - return; /* FPU stuff */ + if (addr == 0xf0) { + /* Writes to F0 clear FPU error and deassert the interrupt. */ + if (is286) + picintc(1 << 13); + else + nmi = 0; + return; + } else if (addr >= 0xf1) + return; /* FPU stuff */ - if (!(addr & 1)) - cyrix_addr = val; - else switch (cyrix_addr) - { - case 0xc0: /*CCR0*/ - ccr0 = val; - break; - case 0xc1: /*CCR1*/ - if ((ccr3 & CCR3_SMI_LOCK) && !in_smm) - val = (val & ~(CCR1_USE_SMI | CCR1_SMAC | CCR1_SM3)) | (ccr1 & (CCR1_USE_SMI | CCR1_SMAC | CCR1_SM3)); - ccr1 = val; - break; - case 0xc2: /*CCR2*/ - ccr2 = val; - break; - case 0xc3: /*CCR3*/ - if ((ccr3 & CCR3_SMI_LOCK) && !in_smm) - val = (val & ~(CCR3_NMI_EN)) | (ccr3 & CCR3_NMI_EN) | CCR3_SMI_LOCK; - ccr3 = val; - break; - case 0xcd: - if (!(ccr3 & CCR3_SMI_LOCK) || in_smm) - { - cyrix.arr[3].base = (cyrix.arr[3].base & ~0xff000000) | (val << 24); - cyrix.smhr &= ~SMHR_VALID; - } - break; - case 0xce: - if (!(ccr3 & CCR3_SMI_LOCK) || in_smm) - { - cyrix.arr[3].base = (cyrix.arr[3].base & ~0x00ff0000) | (val << 16); - cyrix.smhr &= ~SMHR_VALID; - } - break; - case 0xcf: - if (!(ccr3 & CCR3_SMI_LOCK) || in_smm) - { - cyrix.arr[3].base = (cyrix.arr[3].base & ~0x0000f000) | ((val & 0xf0) << 8); - if ((val & 0xf) == 0xf) - cyrix.arr[3].size = 1ull << 32; /*4 GB*/ - else if (val & 0xf) - cyrix.arr[3].size = 2048 << (val & 0xf); - else - cyrix.arr[3].size = 0; /*Disabled*/ - cyrix.smhr &= ~SMHR_VALID; - } - break; + if (!(addr & 1)) + cyrix_addr = val; + else switch (cyrix_addr) { + case 0xc0: /* CCR0 */ + ccr0 = val; + break; + case 0xc1: /* CCR1 */ + if ((ccr3 & CCR3_SMI_LOCK) && !in_smm) + val = (val & ~(CCR1_USE_SMI | CCR1_SMAC | CCR1_SM3)) | (ccr1 & (CCR1_USE_SMI | CCR1_SMAC | CCR1_SM3)); + ccr1 = val; + break; + case 0xc2: /* CCR2 */ + ccr2 = val; + break; + case 0xc3: /* CCR3 */ + if ((ccr3 & CCR3_SMI_LOCK) && !in_smm) + val = (val & ~(CCR3_NMI_EN)) | (ccr3 & CCR3_NMI_EN) | CCR3_SMI_LOCK; + ccr3 = val; + break; + case 0xcd: + if (!(ccr3 & CCR3_SMI_LOCK) || in_smm) { + cyrix.arr[3].base = (cyrix.arr[3].base & ~0xff000000) | (val << 24); + cyrix.smhr &= ~SMHR_VALID; + } + break; + case 0xce: + if (!(ccr3 & CCR3_SMI_LOCK) || in_smm) { + cyrix.arr[3].base = (cyrix.arr[3].base & ~0x00ff0000) | (val << 16); + cyrix.smhr &= ~SMHR_VALID; + } + break; + case 0xcf: + if (!(ccr3 & CCR3_SMI_LOCK) || in_smm) { + cyrix.arr[3].base = (cyrix.arr[3].base & ~0x0000f000) | ((val & 0xf0) << 8); + if ((val & 0xf) == 0xf) + cyrix.arr[3].size = 1ull << 32; /* 4 GB */ + else if (val & 0xf) + cyrix.arr[3].size = 2048 << (val & 0xf); + else + cyrix.arr[3].size = 0; /* Disabled */ + cyrix.smhr &= ~SMHR_VALID; + } + break; - case 0xe8: /*CCR4*/ - if ((ccr3 & 0xf0) == 0x10) - { - ccr4 = val; + case 0xe8: /* CCR4 */ + if ((ccr3 & 0xf0) == 0x10) { + ccr4 = val; #if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) - if (cpu_s->cpu_type >= CPU_Cx6x86) - { - if (val & 0x80) - CPUID = cpu_s->cpuid_model; - else - CPUID = 0; - } + if (cpu_s->cpu_type >= CPU_Cx6x86) { + if (val & 0x80) + CPUID = cpu_s->cpuid_model; + else + CPUID = 0; + } #endif - } - break; - case 0xe9: /*CCR5*/ - if ((ccr3 & 0xf0) == 0x10) - ccr5 = val; - break; - case 0xea: /*CCR6*/ - if ((ccr3 & 0xf0) == 0x10) - ccr6 = val; - break; - } + } + break; + case 0xe9: /* CCR5 */ + if ((ccr3 & 0xf0) == 0x10) + ccr5 = val; + break; + case 0xea: /* CCR6 */ + if ((ccr3 & 0xf0) == 0x10) + ccr6 = val; + break; + } } -static uint8_t cpu_read(uint16_t addr, void *priv) + +static uint8_t +cpu_read(uint16_t addr, void *priv) { - if (addr == 0xf007) - return 0x7f; + if (addr == 0xf007) + return 0x7f; - if (addr >= 0xf0) - return 0xff; /* FPU stuff */ + if (addr >= 0xf0) + return 0xff; /* FPU stuff */ - if (addr & 1) - { - switch (cyrix_addr) - { - case 0xc0: return ccr0; - case 0xc1: return ccr1; - case 0xc2: return ccr2; - case 0xc3: return ccr3; - case 0xe8: return ((ccr3 & 0xf0) == 0x10) ? ccr4 : 0xff; - case 0xe9: return ((ccr3 & 0xf0) == 0x10) ? ccr5 : 0xff; - case 0xea: return ((ccr3 & 0xf0) == 0x10) ? ccr6 : 0xff; - case 0xfe: return cpu_s->cyrix_id & 0xff; - case 0xff: return cpu_s->cyrix_id >> 8; - } - if ((cyrix_addr & 0xf0) == 0xc0) return 0xff; - if (cyrix_addr == 0x20 && cpu_s->cpu_type == CPU_Cx5x86) return 0xff; - } - return 0xff; + if (addr & 1) { + switch (cyrix_addr) { + case 0xc0: + return ccr0; + case 0xc1: + return ccr1; + case 0xc2: + return ccr2; + case 0xc3: + return ccr3; + case 0xe8: + return ((ccr3 & 0xf0) == 0x10) ? ccr4 : 0xff; + case 0xe9: + return ((ccr3 & 0xf0) == 0x10) ? ccr5 : 0xff; + case 0xea: + return ((ccr3 & 0xf0) == 0x10) ? ccr6 : 0xff; + case 0xfe: + return cpu_s->cyrix_id & 0xff; + case 0xff: + return cpu_s->cyrix_id >> 8; + } + + if ((cyrix_addr & 0xf0) == 0xc0) + return 0xff; + + if (cyrix_addr == 0x20 && cpu_s->cpu_type == CPU_Cx5x86) + return 0xff; + } + + return 0xff; } @@ -3975,16 +3036,16 @@ void x86_setopcodes(const OpFn *opcodes, const OpFn *opcodes_0f, const OpFn *dynarec_opcodes, const OpFn *dynarec_opcodes_0f) { - x86_opcodes = opcodes; - x86_opcodes_0f = opcodes_0f; - x86_dynarec_opcodes = dynarec_opcodes; - x86_dynarec_opcodes_0f = dynarec_opcodes_0f; + x86_opcodes = opcodes; + x86_opcodes_0f = opcodes_0f; + x86_dynarec_opcodes = dynarec_opcodes; + x86_dynarec_opcodes_0f = dynarec_opcodes_0f; } #else x86_setopcodes(const OpFn *opcodes, const OpFn *opcodes_0f) { - x86_opcodes = opcodes; - x86_opcodes_0f = opcodes_0f; + x86_opcodes = opcodes; + x86_opcodes_0f = opcodes_0f; } #endif @@ -3992,48 +3053,44 @@ x86_setopcodes(const OpFn *opcodes, const OpFn *opcodes_0f) void cpu_update_waitstates(void) { - cpu_s = (CPU *) &cpu_f->cpus[cpu_effective]; + cpu_s = (CPU *) &cpu_f->cpus[cpu_effective]; - if (is486) - cpu_prefetch_width = 16; - else - cpu_prefetch_width = cpu_16bitbus ? 2 : 4; + if (is486) + cpu_prefetch_width = 16; + else + cpu_prefetch_width = cpu_16bitbus ? 2 : 4; - if (cpu_cache_int_enabled) - { - /* Disable prefetch emulation */ - cpu_prefetch_cycles = 0; - } - else if (cpu_waitstates && (cpu_s->cpu_type >= CPU_286 && cpu_s->cpu_type <= CPU_386DX)) - { - /* Waitstates override */ - cpu_prefetch_cycles = cpu_waitstates+1; - cpu_cycles_read = cpu_waitstates+1; - cpu_cycles_read_l = (cpu_16bitbus ? 2 : 1) * (cpu_waitstates+1); - cpu_cycles_write = cpu_waitstates+1; - cpu_cycles_write_l = (cpu_16bitbus ? 2 : 1) * (cpu_waitstates+1); - } - else if (cpu_cache_ext_enabled) - { - /* Use cache timings */ - cpu_prefetch_cycles = cpu_s->cache_read_cycles; - cpu_cycles_read = cpu_s->cache_read_cycles; - cpu_cycles_read_l = (cpu_16bitbus ? 2 : 1) * cpu_s->cache_read_cycles; - cpu_cycles_write = cpu_s->cache_write_cycles; - cpu_cycles_write_l = (cpu_16bitbus ? 2 : 1) * cpu_s->cache_write_cycles; - } - else - { - /* Use memory timings */ - cpu_prefetch_cycles = cpu_s->mem_read_cycles; - cpu_cycles_read = cpu_s->mem_read_cycles; - cpu_cycles_read_l = (cpu_16bitbus ? 2 : 1) * cpu_s->mem_read_cycles; - cpu_cycles_write = cpu_s->mem_write_cycles; - cpu_cycles_write_l = (cpu_16bitbus ? 2 : 1) * cpu_s->mem_write_cycles; - } - if (is486) - cpu_prefetch_cycles = (cpu_prefetch_cycles * 11) / 16; - cpu_mem_prefetch_cycles = cpu_prefetch_cycles; - if (cpu_s->rspeed <= 8000000) - cpu_rom_prefetch_cycles = cpu_mem_prefetch_cycles; + if (cpu_cache_int_enabled) { + /* Disable prefetch emulation */ + cpu_prefetch_cycles = 0; + } else if (cpu_waitstates && (cpu_s->cpu_type >= CPU_286 && cpu_s->cpu_type <= CPU_386DX)) { + /* Waitstates override */ + cpu_prefetch_cycles = cpu_waitstates+1; + cpu_cycles_read = cpu_waitstates+1; + cpu_cycles_read_l = (cpu_16bitbus ? 2 : 1) * (cpu_waitstates+1); + cpu_cycles_write = cpu_waitstates+1; + cpu_cycles_write_l = (cpu_16bitbus ? 2 : 1) * (cpu_waitstates+1); + } else if (cpu_cache_ext_enabled) { + /* Use cache timings */ + cpu_prefetch_cycles = cpu_s->cache_read_cycles; + cpu_cycles_read = cpu_s->cache_read_cycles; + cpu_cycles_read_l = (cpu_16bitbus ? 2 : 1) * cpu_s->cache_read_cycles; + cpu_cycles_write = cpu_s->cache_write_cycles; + cpu_cycles_write_l = (cpu_16bitbus ? 2 : 1) * cpu_s->cache_write_cycles; + } else { + /* Use memory timings */ + cpu_prefetch_cycles = cpu_s->mem_read_cycles; + cpu_cycles_read = cpu_s->mem_read_cycles; + cpu_cycles_read_l = (cpu_16bitbus ? 2 : 1) * cpu_s->mem_read_cycles; + cpu_cycles_write = cpu_s->mem_write_cycles; + cpu_cycles_write_l = (cpu_16bitbus ? 2 : 1) * cpu_s->mem_write_cycles; + } + + if (is486) + cpu_prefetch_cycles = (cpu_prefetch_cycles * 11) / 16; + + cpu_mem_prefetch_cycles = cpu_prefetch_cycles; + + if (cpu_s->rspeed <= 8000000) + cpu_rom_prefetch_cycles = cpu_mem_prefetch_cycles; } diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index e3e90a845..2ebd1362e 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -40,9 +40,9 @@ enum { #endif CPU_286, /* 286 class CPUs */ CPU_386SX, /* 386 class CPUs */ - CPU_386DX, CPU_IBM386SLC, CPU_IBM486SLC, + CPU_386DX, CPU_IBM486BL, CPU_RAPIDCAD, CPU_486SLC, @@ -53,10 +53,10 @@ enum { CPU_i486SX2, CPU_Am486SX2, CPU_i486DX, - CPU_i486DX2, CPU_Am486DX, - CPU_Am486DX2, CPU_Cx486DX, + CPU_i486DX2, + CPU_Am486DX2, CPU_Cx486DX2, CPU_iDX4, CPU_Am486DX4, @@ -236,10 +236,99 @@ typedef union { } MMX_REG; typedef struct { - uint32_t tr1, tr12; - uint32_t cesr; - uint32_t fcr; - uint64_t fcr2, fcr3; + /* IDT WinChip and WinChip 2 MSR's */ + uint32_t tr1, tr12; /* 0x00000002, 0x0000000e */ + uint32_t cesr; /* 0x00000011 */ + + /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ + uint64_t ecx17; /* 0x00000017 - Only on Pentium II Deschutes */ + uint64_t apic_base; /* 0x0000001b - Should the Pentium not also have this? */ + uint64_t ecx79; /* 0x00000079 */ + + /* AMD K5, 5k86, K6, K6-2, K6-2C, K6-3, K6-2P, and K6-3P MSR's */ + uint64_t ecx83; /* 0x00000083 - AMD K5 and K6 MSR's. */ + + /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ + uint64_t ecx8x[4]; /* 0x00000088 - 0x0000008b */ + uint64_t ia32_pmc[8]; /* 0x000000c1 - 0x000000c8 */ + uint64_t mtrr_cap; /* 0x000000fe */ + + /* IDT WinChip and WinChip 2 MSR's that are also on the VIA Cyrix III and Eden */ + uint32_t fcr; /* 0x00000107 (IDT), 0x00001107 (VIA) */ + uint64_t fcr2, fcr3; /* 0x00000108 (IDT), 0x00001108 (VIA) */ + + /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ + uint64_t ecx116; /* 0x00000116 */ + uint64_t ecx11x[4]; /* 0x00000118 - 0x0000011b */ + uint64_t ecx11e; /* 0x0000011e */ + + /* Pentium II Klamath and Pentium II Deschutes MSR's */ + uint16_t sysenter_cs; /* 0x00000174 - SYSENTER/SYSEXIT MSR's */ + uint32_t sysenter_esp; /* 0x00000175 - SYSENTER/SYSEXIT MSR's */ + uint32_t sysenter_eip; /* 0x00000176 - SYSENTER/SYSEXIT MSR's */ + + /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ + uint64_t ecx186, ecx187; /* 0x00000186, 0x00000187 */ + uint64_t ecx1e0; /* 0x000001e0 */ + + /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's that are also + on the VIA Cyrix III and Eden */ + uint64_t mtrr_physbase[8]; /* 0x00000200 - 0x0000020f */ + uint64_t mtrr_physmask[8]; /* 0x00000200 - 0x0000020f (ECX & 1) */ + uint64_t mtrr_fix64k_8000; /* 0x00000250 */ + uint64_t mtrr_fix16k_8000; /* 0x00000258 */ + uint64_t mtrr_fix16k_a000; /* 0x00000259 */ + uint64_t mtrr_fix4k[8]; /* 0x00000268 - 0x0000026f */ + + /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ + uint64_t pat; /* 0x00000277 */ + + /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's that are also + on the VIA Cyrix III and Eden */ + uint64_t mtrr_deftype; /* 0x000002ff */ + + /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ + uint64_t ecx404; /* 0x00000404 - Model Identification MSR's used by some Acer BIOSes */ + uint64_t ecx408; /* 0x00000408 */ + uint64_t ecx40c; /* 0x0000040c */ + uint64_t ecx410; /* 0x00000410 */ + uint64_t ecx570; /* 0x00000570 */ + + /* IBM 386SLC, 486SLC, and 486BL MSR's */ + uint64_t ibm_por; /* 0x00001000 - Processor Operation Register */ + uint64_t ibm_crcr; /* 0x00001001 - Cache Region Control Register */ + + /* IBM 486SLC and 486BL MSR's */ + uint64_t ibm_por2; /* 0x00001002 - Processor Operation Register */ + + /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ + uint64_t ecx1002ff; /* 0x001002ff - MSR used by some Intel AMI boards */ + + /* AMD K5, 5k86, K6, K6-2, K6-2C, K6-3, K6-2P, and K6-3P MSR's */ + uint64_t amd_efer; /* 0xc0000080 */ + + /* AMD K6-2, K6-2C, K6-3, K6-2P, and K6-3P MSR's */ + uint64_t star; /* 0xc0000081 */ + + /* AMD K5, 5k86, K6, K6-2, K6-2C, K6-3, K6-2P, and K6-3P MSR's */ + uint64_t amd_whcr; /* 0xc0000082 */ + + /* AMD K6-2C, K6-3, K6-2P, and K6-3P MSR's */ + uint64_t amd_uwccr; /* 0xc0000085 */ + + /* AMD K6-2P and K6-3P MSR's */ + uint64_t amd_epmr; /* 0xc0000086 */ + + /* AMD K6-2C, K6-3, K6-2P, and K6-3P MSR's */ + uint64_t amd_psor, amd_pfir; /* 0xc0000087, 0xc0000088 */ + + /* K6-3, K6-2P, and K6-3P MSR's */ + uint64_t amd_l2aar; /* 0xc0000089 */ + + /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ + uint64_t ecxf0f00250; /* 0xf0f00250 - Some weird long MSR's used by i686 AMI & some Phoenix BIOSes */ + uint64_t ecxf0f00258; /* 0xf0f00258 */ + uint64_t ecxf0f00259; /* 0xf0f00259 */ } msr_t; typedef struct { @@ -532,7 +621,7 @@ extern void cpu_CPUID(void); extern void cpu_RDMSR(void); extern void cpu_WRMSR(void); -extern int checkio(int port); +extern int checkio(uint32_t port); extern void codegen_block_end(void); extern void codegen_reset(void); extern void cpu_set_edx(void); @@ -612,9 +701,14 @@ typedef struct } cyrix_t; +extern uint32_t addr64, addr64_2; +extern uint32_t addr64a[8], addr64a_2[8]; + extern cyrix_t cyrix; extern void (*cpu_exec)(int cycs); extern uint8_t do_translate, do_translate2; +extern void reset_808x(int hard); + #endif /*EMU_CPU_H*/ diff --git a/src/cpu/x86_ops_amd.h b/src/cpu/x86_ops_amd.h index 0674c8187..a378b9fe9 100644 --- a/src/cpu/x86_ops_amd.h +++ b/src/cpu/x86_ops_amd.h @@ -18,7 +18,7 @@ opSYSCALL(uint32_t fetchdat) { int ret; - ILLEGAL_ON(!(amd_efer & 0x0000000000000001)); + ILLEGAL_ON(!(msr.amd_efer & 0x0000000000000001)); ret = syscall_op(fetchdat); @@ -38,7 +38,7 @@ opSYSRET(uint32_t fetchdat) { int ret; - ILLEGAL_ON(!(amd_efer & 0x0000000000000001)); + ILLEGAL_ON(!(msr.amd_efer & 0x0000000000000001)); ret = sysret(fetchdat); diff --git a/src/cpu/x86_ops_arith.h b/src/cpu/x86_ops_arith.h index 489fd5e57..d837d3a64 100644 --- a/src/cpu/x86_ops_arith.h +++ b/src/cpu/x86_ops_arith.h @@ -309,8 +309,8 @@ static int opCMP_b_rmw_a16(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); dst = geteab(); if (cpu_state.abrt) return 1; setsub8(dst, getr8(cpu_reg)); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0); return 0; } @@ -322,8 +322,8 @@ static int opCMP_b_rmw_a32(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); dst = geteab(); if (cpu_state.abrt) return 1; setsub8(dst, getr8(cpu_reg)); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1); return 0; } @@ -336,8 +336,8 @@ static int opCMP_w_rmw_a16(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); dst = geteaw(); if (cpu_state.abrt) return 1; setsub16(dst, cpu_state.regs[cpu_reg].w); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0); return 0; } @@ -349,8 +349,8 @@ static int opCMP_w_rmw_a32(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); dst = geteaw(); if (cpu_state.abrt) return 1; setsub16(dst, cpu_state.regs[cpu_reg].w); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1); return 0; } @@ -363,8 +363,8 @@ static int opCMP_l_rmw_a16(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); dst = geteal(); if (cpu_state.abrt) return 1; setsub32(dst, cpu_state.regs[cpu_reg].l); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1,0,0, 0); return 0; } @@ -376,8 +376,8 @@ static int opCMP_l_rmw_a32(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); dst = geteal(); if (cpu_state.abrt) return 1; setsub32(dst, cpu_state.regs[cpu_reg].l); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1,0,0, 1); return 0; } @@ -493,8 +493,8 @@ static int opTEST_b_a16(uint32_t fetchdat) temp = geteab(); if (cpu_state.abrt) return 1; temp2 = getr8(cpu_reg); setznp8(temp & temp2); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0); return 0; } @@ -507,8 +507,8 @@ static int opTEST_b_a32(uint32_t fetchdat) temp = geteab(); if (cpu_state.abrt) return 1; temp2 = getr8(cpu_reg); setznp8(temp & temp2); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1); return 0; } @@ -522,8 +522,8 @@ static int opTEST_w_a16(uint32_t fetchdat) temp = geteaw(); if (cpu_state.abrt) return 1; temp2 = cpu_state.regs[cpu_reg].w; setznp16(temp & temp2); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0); return 0; } @@ -536,8 +536,8 @@ static int opTEST_w_a32(uint32_t fetchdat) temp = geteaw(); if (cpu_state.abrt) return 1; temp2 = cpu_state.regs[cpu_reg].w; setznp16(temp & temp2); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1); return 0; } @@ -551,8 +551,8 @@ static int opTEST_l_a16(uint32_t fetchdat) temp = geteal(); if (cpu_state.abrt) return 1; temp2 = cpu_state.regs[cpu_reg].l; setznp32(temp & temp2); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0,(cpu_mod == 3) ? 0 : 1,0,0, 0); return 0; } @@ -565,8 +565,8 @@ static int opTEST_l_a32(uint32_t fetchdat) temp = geteal(); if (cpu_state.abrt) return 1; temp2 = cpu_state.regs[cpu_reg].l; setznp32(temp & temp2); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0,(cpu_mod == 3) ? 0 : 1,0,0, 1); return 0; } @@ -643,8 +643,8 @@ static int opTEST_EAX(uint32_t fetchdat) break; \ case 0x38: /*CMP ea, #*/ \ setsub ## flag_width(dst, src); \ - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); \ - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 7); \ + if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } \ + else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 7); } \ break; \ } @@ -658,10 +658,11 @@ static int op80_a16(uint32_t fetchdat) SEG_CHECK_WRITE(cpu_state.ea_seg); src = getbyte(); if (cpu_state.abrt) return 1; ARITH_MULTI(b, 8); - if ((rmdat & 0x38) == 0x38) + if ((rmdat & 0x38) == 0x38) { PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - else + } else { PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); + } return 0; } @@ -674,10 +675,11 @@ static int op80_a32(uint32_t fetchdat) SEG_CHECK_WRITE(cpu_state.ea_seg); src = getbyte(); if (cpu_state.abrt) return 1; ARITH_MULTI(b, 8); - if ((rmdat & 0x38) == 0x38) + if ((rmdat & 0x38) == 0x38) { PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - else + } else { PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); + } return 0; } @@ -690,10 +692,11 @@ static int op81_w_a16(uint32_t fetchdat) SEG_CHECK_WRITE(cpu_state.ea_seg); src = getword(); if (cpu_state.abrt) return 1; ARITH_MULTI(w, 16); - if ((rmdat & 0x38) == 0x38) + if ((rmdat & 0x38) == 0x38) { PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 4, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - else + } else { PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 4, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); + } return 0; } @@ -706,10 +709,11 @@ static int op81_w_a32(uint32_t fetchdat) SEG_CHECK_WRITE(cpu_state.ea_seg); src = getword(); if (cpu_state.abrt) return 1; ARITH_MULTI(w, 16); - if ((rmdat & 0x38) == 0x38) + if ((rmdat & 0x38) == 0x38) { PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 4, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - else + } else { PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 4, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); + } return 0; } @@ -722,10 +726,11 @@ static int op81_l_a16(uint32_t fetchdat) SEG_CHECK_WRITE(cpu_state.ea_seg); src = getlong(); if (cpu_state.abrt) return 1; ARITH_MULTI(l, 32); - if ((rmdat & 0x38) == 0x38) + if ((rmdat & 0x38) == 0x38) { PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 6, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); - else + } else { PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 6, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); + } return 0; } @@ -738,10 +743,11 @@ static int op81_l_a32(uint32_t fetchdat) SEG_CHECK_WRITE(cpu_state.ea_seg); src = getlong(); if (cpu_state.abrt) return 1; ARITH_MULTI(l, 32); - if ((rmdat & 0x38) == 0x38) + if ((rmdat & 0x38) == 0x38) { PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 6, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); - else + } else { PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 6, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); + } return 0; } @@ -756,10 +762,11 @@ static int op83_w_a16(uint32_t fetchdat) src = getbyte(); if (cpu_state.abrt) return 1; if (src & 0x80) src |= 0xff00; ARITH_MULTI(w, 16); - if ((rmdat & 0x38) == 0x38) + if ((rmdat & 0x38) == 0x38) { PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - else + } else { PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); + } return 0; } @@ -773,10 +780,11 @@ static int op83_w_a32(uint32_t fetchdat) src = getbyte(); if (cpu_state.abrt) return 1; if (src & 0x80) src |= 0xff00; ARITH_MULTI(w, 16); - if ((rmdat & 0x38) == 0x38) + if ((rmdat & 0x38) == 0x38) { PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - else + } else { PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); + } return 0; } @@ -791,10 +799,11 @@ static int op83_l_a16(uint32_t fetchdat) src = getbyte(); if (cpu_state.abrt) return 1; if (src & 0x80) src |= 0xffffff00; ARITH_MULTI(l, 32); - if ((rmdat & 0x38) == 0x38) + if ((rmdat & 0x38) == 0x38) { PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); - else + } else { PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); + } return 0; } @@ -808,10 +817,11 @@ static int op83_l_a32(uint32_t fetchdat) src = getbyte(); if (cpu_state.abrt) return 1; if (src & 0x80) src |= 0xffffff00; ARITH_MULTI(l, 32); - if ((rmdat & 0x38) == 0x38) + if ((rmdat & 0x38) == 0x38) { PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); - else + } else { PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); + } return 0; } diff --git a/src/cpu/x86_ops_call.h b/src/cpu/x86_ops_call.h index 57a5995b0..427d504fc 100644 --- a/src/cpu/x86_ops_call.h +++ b/src/cpu/x86_ops_call.h @@ -186,8 +186,8 @@ static int opFF_w_a16(uint32_t fetchdat) PUSH_W(cpu_state.pc); cpu_state.pc = new_pc; CPU_BLOCK_END(); - if (is486) CLOCK_CYCLES(5); - else CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); + if (is486) { CLOCK_CYCLES(5); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); } PREFETCH_RUN((cpu_mod == 3) ? 7 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,1,0, 0); PREFETCH_FLUSH(); break; @@ -208,8 +208,8 @@ static int opFF_w_a16(uint32_t fetchdat) new_pc = geteaw(); if (cpu_state.abrt) return 1; cpu_state.pc = new_pc; CPU_BLOCK_END(); - if (is486) CLOCK_CYCLES(5); - else CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); + if (is486) { CLOCK_CYCLES(5); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); } PREFETCH_RUN((cpu_mod == 3) ? 7 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); PREFETCH_FLUSH(); break; @@ -285,8 +285,8 @@ static int opFF_w_a32(uint32_t fetchdat) PUSH_W(cpu_state.pc); cpu_state.pc = new_pc; CPU_BLOCK_END(); - if (is486) CLOCK_CYCLES(5); - else CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); + if (is486) { CLOCK_CYCLES(5); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); } PREFETCH_RUN((cpu_mod == 3) ? 7 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,1,0, 1); PREFETCH_FLUSH(); break; @@ -307,8 +307,8 @@ static int opFF_w_a32(uint32_t fetchdat) new_pc = geteaw(); if (cpu_state.abrt) return 1; cpu_state.pc = new_pc; CPU_BLOCK_END(); - if (is486) CLOCK_CYCLES(5); - else CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); + if (is486) { CLOCK_CYCLES(5); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); } PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 1,0,0,0, 1); PREFETCH_FLUSH(); break; @@ -385,8 +385,8 @@ static int opFF_l_a16(uint32_t fetchdat) PUSH_L(cpu_state.pc); cpu_state.pc = new_pc; CPU_BLOCK_END(); - if (is486) CLOCK_CYCLES(5); - else CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); + if (is486) { CLOCK_CYCLES(5); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); } PREFETCH_RUN((cpu_mod == 3) ? 7 : 10, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,1, 0); PREFETCH_FLUSH(); break; @@ -407,8 +407,8 @@ static int opFF_l_a16(uint32_t fetchdat) new_pc = geteal(); if (cpu_state.abrt) return 1; cpu_state.pc = new_pc; CPU_BLOCK_END(); - if (is486) CLOCK_CYCLES(5); - else CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); + if (is486) { CLOCK_CYCLES(5); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); } PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 0,1,0,0, 0); PREFETCH_FLUSH(); break; @@ -484,8 +484,8 @@ static int opFF_l_a32(uint32_t fetchdat) PUSH_L(cpu_state.pc); if (cpu_state.abrt) return 1; cpu_state.pc = new_pc; CPU_BLOCK_END(); - if (is486) CLOCK_CYCLES(5); - else CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); + if (is486) { CLOCK_CYCLES(5); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); } PREFETCH_RUN((cpu_mod == 3) ? 7 : 10, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,1, 1); PREFETCH_FLUSH(); break; @@ -506,8 +506,8 @@ static int opFF_l_a32(uint32_t fetchdat) new_pc = geteal(); if (cpu_state.abrt) return 1; cpu_state.pc = new_pc; CPU_BLOCK_END(); - if (is486) CLOCK_CYCLES(5); - else CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); + if (is486) { CLOCK_CYCLES(5); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); } PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 1,1,0,0, 1); PREFETCH_FLUSH(); break; diff --git a/src/cpu/x86_ops_i686.h b/src/cpu/x86_ops_i686.h index dad86b410..3f2d85766 100644 --- a/src/cpu/x86_ops_i686.h +++ b/src/cpu/x86_ops_i686.h @@ -153,9 +153,6 @@ fx_save_stor_common(uint32_t fetchdat, int bits) x87_settag(rec_ftw); CLOCK_CYCLES((cr0 & 1) ? 34 : 44); - - if (cpu_state.abrt) - x386_dynarec_log("FXRSTOR: abrt != 0\n"); } else { /* FXSAVE */ if ((twd & 0x0003) == 0x0003) ftwb |= 0x01; @@ -217,9 +214,6 @@ fx_save_stor_common(uint32_t fetchdat, int bits) cpu_state.ismmx = 0; CLOCK_CYCLES((cr0 & 1) ? 56 : 67); - - if (cpu_state.abrt) - x386_dynarec_log("FXSAVE: abrt != 0\n"); } return cpu_state.abrt; diff --git a/src/cpu/x86_ops_misc.h b/src/cpu/x86_ops_misc.h index e326543a2..a64a3edbb 100644 --- a/src/cpu/x86_ops_misc.h +++ b/src/cpu/x86_ops_misc.h @@ -63,8 +63,8 @@ static int opF6_a16(uint32_t fetchdat) case 0x08: src = readmemb(cs, cpu_state.pc); cpu_state.pc++; if (cpu_state.abrt) return 1; setznp8(src & dst); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); break; case 0x10: /*NOT b*/ @@ -167,8 +167,8 @@ static int opF6_a32(uint32_t fetchdat) case 0x08: src = readmemb(cs, cpu_state.pc); cpu_state.pc++; if (cpu_state.abrt) return 1; setznp8(src & dst); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); break; case 0x10: /*NOT b*/ @@ -274,8 +274,8 @@ static int opF7_w_a16(uint32_t fetchdat) case 0x08: src = getword(); if (cpu_state.abrt) return 1; setznp16(src & dst); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 4, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); break; case 0x10: /*NOT w*/ @@ -371,8 +371,8 @@ static int opF7_w_a32(uint32_t fetchdat) case 0x08: src = getword(); if (cpu_state.abrt) return 1; setznp16(src & dst); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 4, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); break; case 0x10: /*NOT w*/ @@ -469,8 +469,8 @@ static int opF7_l_a16(uint32_t fetchdat) case 0x08: src = getlong(); if (cpu_state.abrt) return 1; setznp32(src & dst); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 5, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); break; case 0x10: /*NOT l*/ @@ -544,8 +544,8 @@ static int opF7_l_a32(uint32_t fetchdat) case 0x08: src = getlong(); if (cpu_state.abrt) return 1; setznp32(src & dst); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 5, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); break; case 0x10: /*NOT l*/ @@ -620,8 +620,9 @@ static int opHLT(uint32_t fetchdat) if (!((cpu_state.flags & I_FLAG) && pic.int_pending)) cpu_state.pc--; } - else + else { CLOCK_CYCLES(5); + } CPU_BLOCK_END(); PREFETCH_RUN(100, 1, -1, 0,0,0,0, 0); diff --git a/src/cpu/x86_ops_mov.h b/src/cpu/x86_ops_mov.h index 2c96317b7..8702578b1 100644 --- a/src/cpu/x86_ops_mov.h +++ b/src/cpu/x86_ops_mov.h @@ -281,7 +281,7 @@ static int opMOV_AX_a16(uint32_t fetchdat) uint16_t temp; uint16_t addr = getwordf(); SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, addr, addr+1); + CHECK_READ(cpu_state.ea_seg, addr, addr + 1UL); temp = readmemw(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; AX = temp; CLOCK_CYCLES((is486) ? 1 : 4); @@ -305,7 +305,7 @@ static int opMOV_EAX_a16(uint32_t fetchdat) uint32_t temp; uint16_t addr = getwordf(); SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, addr, addr+3); + CHECK_READ(cpu_state.ea_seg, addr, addr + 3UL); temp = readmeml(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; EAX = temp; CLOCK_CYCLES((is486) ? 1 : 4); @@ -349,7 +349,7 @@ static int opMOV_a16_AX(uint32_t fetchdat) { uint16_t addr = getwordf(); SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE_COMMON(cpu_state.ea_seg, addr, addr + 1); + CHECK_WRITE_COMMON(cpu_state.ea_seg, addr, addr + 1UL); writememw(cpu_state.ea_seg->base, addr, AX); CLOCK_CYCLES((is486) ? 1 : 2); PREFETCH_RUN(2, 3, -1, 0,0,1,0, 0); @@ -369,7 +369,7 @@ static int opMOV_a16_EAX(uint32_t fetchdat) { uint16_t addr = getwordf(); SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE_COMMON(cpu_state.ea_seg, addr, addr + 3); + CHECK_WRITE_COMMON(cpu_state.ea_seg, addr, addr + 3UL); writememl(cpu_state.ea_seg->base, addr, EAX); CLOCK_CYCLES((is486) ? 1 : 2); PREFETCH_RUN(2, 3, -1, 0,0,0,1, 0); diff --git a/src/cpu/x86_ops_rep.h b/src/cpu/x86_ops_rep.h index e276fe90e..4d1f0ea61 100644 --- a/src/cpu/x86_ops_rep.h +++ b/src/cpu/x86_ops_rep.h @@ -2,7 +2,8 @@ static int opREP_INSB_ ## size(uint32_t fetchdat) \ { \ int reads = 0, writes = 0, total_cycles = 0; \ - uint64_t addr64 = 0x0000000000000000ULL; \ + \ + addr64 = 0x00000000; \ \ if (CNT_REG > 0) \ { \ @@ -11,6 +12,7 @@ static int opREP_INSB_ ## size(uint32_t fetchdat) SEG_CHECK_WRITE(&cpu_state.seg_es); \ check_io_perm(DX); \ CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG); \ + high_page = 0; \ do_mmut_wb(es, DEST_REG, &addr64); \ if (cpu_state.abrt) return 1; \ temp = inb(DX); \ @@ -34,7 +36,8 @@ static int opREP_INSB_ ## size(uint32_t fetchdat) static int opREP_INSW_ ## size(uint32_t fetchdat) \ { \ int reads = 0, writes = 0, total_cycles = 0; \ - uint64_t addr64[2]; \ + \ + addr64a[0] = addr64a[1] = 0x00000000; \ \ if (CNT_REG > 0) \ { \ @@ -43,11 +46,12 @@ static int opREP_INSW_ ## size(uint32_t fetchdat) SEG_CHECK_WRITE(&cpu_state.seg_es); \ check_io_perm(DX); \ check_io_perm(DX+1); \ - CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG + 1); \ - do_mmut_ww(es, DEST_REG, addr64); \ + CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ + high_page = 0; \ + do_mmut_ww(es, DEST_REG, addr64a); \ if (cpu_state.abrt) return 1; \ temp = inw(DX); \ - writememw_n(es, DEST_REG, addr64, temp); if (cpu_state.abrt) return 1; \ + writememw_n(es, DEST_REG, addr64a, temp); if (cpu_state.abrt) return 1; \ \ if (cpu_state.flags & D_FLAG) DEST_REG -= 2; \ else DEST_REG += 2; \ @@ -67,7 +71,8 @@ static int opREP_INSW_ ## size(uint32_t fetchdat) static int opREP_INSL_ ## size(uint32_t fetchdat) \ { \ int reads = 0, writes = 0, total_cycles = 0; \ - uint64_t addr64[4]; \ + \ + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; \ \ if (CNT_REG > 0) \ { \ @@ -78,11 +83,12 @@ static int opREP_INSL_ ## size(uint32_t fetchdat) check_io_perm(DX+1); \ check_io_perm(DX+2); \ check_io_perm(DX+3); \ - CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG + 3); \ - do_mmut_wl(es, DEST_REG, addr64); \ + CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ + high_page = 0; \ + do_mmut_wl(es, DEST_REG, addr64a); \ if (cpu_state.abrt) return 1; \ temp = inl(DX); \ - writememl_n(es, DEST_REG, addr64, temp); if (cpu_state.abrt) return 1; \ + writememl_n(es, DEST_REG, addr64a, temp); if (cpu_state.abrt) return 1; \ \ if (cpu_state.flags & D_FLAG) DEST_REG -= 4; \ else DEST_REG += 4; \ @@ -135,7 +141,7 @@ static int opREP_OUTSW_ ## size(uint32_t fetchdat) { \ uint16_t temp; \ SEG_CHECK_READ(cpu_state.ea_seg); \ - CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 1); \ + CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ temp = readmemw(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ check_io_perm(DX); \ check_io_perm(DX+1); \ @@ -163,7 +169,7 @@ static int opREP_OUTSL_ ## size(uint32_t fetchdat) { \ uint32_t temp; \ SEG_CHECK_READ(cpu_state.ea_seg); \ - CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 3); \ + CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ temp = readmeml(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ check_io_perm(DX); \ check_io_perm(DX+1); \ @@ -190,27 +196,27 @@ static int opREP_MOVSB_ ## size(uint32_t fetchdat) { \ int reads = 0, writes = 0, total_cycles = 0; \ int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - uint64_t addr64r = 0x0000000000000000ULL; \ - uint64_t addr64w = 0x0000000000000000ULL; \ + addr64 = addr64_2 = 0x00000000; \ if (trap) \ cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ if (CNT_REG > 0) \ { \ SEG_CHECK_READ(cpu_state.ea_seg); \ SEG_CHECK_WRITE(&cpu_state.seg_es); \ - } \ + } \ while (CNT_REG > 0) \ { \ uint8_t temp; \ \ CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG); \ - do_mmut_rb(cpu_state.ea_seg->base, SRC_REG, &addr64r); \ + high_page = 0; \ + do_mmut_rb(cpu_state.ea_seg->base, SRC_REG, &addr64) ; \ if (cpu_state.abrt) break; \ CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \ - do_mmut_wb(es, DEST_REG, &addr64w); \ + do_mmut_wb(es, DEST_REG, &addr64_2); \ if (cpu_state.abrt) break; \ - temp = readmemb_n(cpu_state.ea_seg->base, SRC_REG, addr64r); if (cpu_state.abrt) return 1; \ - writememb_n(es, DEST_REG, addr64w, temp); if (cpu_state.abrt) return 1; \ + temp = readmemb_n(cpu_state.ea_seg->base, SRC_REG, addr64); if (cpu_state.abrt) return 1; \ + writememb_n(es, DEST_REG, addr64_2, temp); if (cpu_state.abrt) return 1; \ \ if (cpu_state.flags & D_FLAG) { DEST_REG--; SRC_REG--; } \ else { DEST_REG++; SRC_REG++; } \ @@ -233,27 +239,28 @@ static int opREP_MOVSW_ ## size(uint32_t fetchdat) { \ int reads = 0, writes = 0, total_cycles = 0; \ int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - uint64_t addr64r[2]; \ - uint64_t addr64w[2]; \ + addr64a[0] = addr64a[1] = 0x00000000; \ + addr64a_2[0] = addr64a_2[1] = 0x00000000; \ if (trap) \ cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ if (CNT_REG > 0) \ { \ SEG_CHECK_READ(cpu_state.ea_seg); \ SEG_CHECK_WRITE(&cpu_state.seg_es); \ - } \ + } \ while (CNT_REG > 0) \ { \ uint16_t temp; \ \ - CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 1); \ - do_mmut_rw(cpu_state.ea_seg->base, SRC_REG, addr64r); \ + CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ + high_page = 0; \ + do_mmut_rw(cpu_state.ea_seg->base, SRC_REG, addr64a); \ if (cpu_state.abrt) break; \ - CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1); \ - do_mmut_ww(es, DEST_REG, addr64w); \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ + do_mmut_ww(es, DEST_REG, addr64a_2); \ if (cpu_state.abrt) break; \ - temp = readmemw_n(cpu_state.ea_seg->base, SRC_REG, addr64r); if (cpu_state.abrt) return 1; \ - writememw_n(es, DEST_REG, addr64w, temp); if (cpu_state.abrt) return 1; \ + temp = readmemw_n(cpu_state.ea_seg->base, SRC_REG, addr64a); if (cpu_state.abrt) return 1; \ + writememw_n(es, DEST_REG, addr64a_2, temp); if (cpu_state.abrt) return 1; \ \ if (cpu_state.flags & D_FLAG) { DEST_REG -= 2; SRC_REG -= 2; } \ else { DEST_REG += 2; SRC_REG += 2; } \ @@ -276,27 +283,28 @@ static int opREP_MOVSL_ ## size(uint32_t fetchdat) { \ int reads = 0, writes = 0, total_cycles = 0; \ int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - uint64_t addr64r[4]; \ - uint64_t addr64w[4]; \ + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; \ + addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; \ if (trap) \ cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ if (CNT_REG > 0) \ { \ SEG_CHECK_READ(cpu_state.ea_seg); \ SEG_CHECK_WRITE(&cpu_state.seg_es); \ - } \ + } \ while (CNT_REG > 0) \ { \ uint32_t temp; \ \ - CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 3); \ - do_mmut_rl(cpu_state.ea_seg->base, SRC_REG, addr64r); \ + CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ + high_page = 0; \ + do_mmut_rl(cpu_state.ea_seg->base, SRC_REG, addr64a); \ if (cpu_state.abrt) break; \ - CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3); \ - do_mmut_wl(es, DEST_REG, addr64w); \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ + do_mmut_wl(es, DEST_REG, addr64a_2); \ if (cpu_state.abrt) break; \ - temp = readmeml_n(cpu_state.ea_seg->base, SRC_REG, addr64r); if (cpu_state.abrt) return 1; \ - writememl_n(es, DEST_REG, addr64w, temp); if (cpu_state.abrt) return 1; \ + temp = readmeml_n(cpu_state.ea_seg->base, SRC_REG, addr64a); if (cpu_state.abrt) return 1; \ + writememl_n(es, DEST_REG, addr64a_2, temp); if (cpu_state.abrt) return 1; \ \ if (cpu_state.flags & D_FLAG) { DEST_REG -= 4; SRC_REG -= 4; } \ else { DEST_REG += 4; SRC_REG += 4; } \ @@ -356,7 +364,7 @@ static int opREP_STOSW_ ## size(uint32_t fetchdat) SEG_CHECK_WRITE(&cpu_state.seg_es); \ while (CNT_REG > 0) \ { \ - CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1); \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ writememw(es, DEST_REG, AX); if (cpu_state.abrt) return 1; \ if (cpu_state.flags & D_FLAG) DEST_REG -= 2; \ else DEST_REG += 2; \ @@ -385,7 +393,7 @@ static int opREP_STOSL_ ## size(uint32_t fetchdat) SEG_CHECK_WRITE(&cpu_state.seg_es); \ while (CNT_REG > 0) \ { \ - CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3); \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ writememl(es, DEST_REG, EAX); if (cpu_state.abrt) return 1; \ if (cpu_state.flags & D_FLAG) DEST_REG -= 4; \ else DEST_REG += 4; \ @@ -444,7 +452,7 @@ static int opREP_LODSW_ ## size(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); \ while (CNT_REG > 0) \ { \ - CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 1); \ + CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ AX = readmemw(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ if (cpu_state.flags & D_FLAG) SRC_REG -= 2; \ else SRC_REG += 2; \ @@ -473,7 +481,7 @@ static int opREP_LODSL_ ## size(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); \ while (CNT_REG > 0) \ { \ - CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 3); \ + CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ EAX = readmeml(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ if (cpu_state.flags & D_FLAG) SRC_REG -= 4; \ else SRC_REG += 4; \ @@ -501,8 +509,8 @@ static int opREP_LODSL_ ## size(uint32_t fetchdat) static int opREP_CMPSB_ ## size(uint32_t fetchdat) \ { \ int reads = 0, total_cycles = 0, tempz; \ - uint64_t addr64 = 0x0000000000000000ULL; \ - uint64_t addr642 = 0x0000000000000000ULL; \ + \ + addr64 = addr64_2 = 0x00000000; \ \ tempz = FV; \ if ((CNT_REG > 0) && (FV == tempz)) \ @@ -511,12 +519,14 @@ static int opREP_CMPSB_ ## size(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); \ SEG_CHECK_READ(&cpu_state.seg_es); \ CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG); \ + high_page = 0; \ do_mmut_rb(cpu_state.ea_seg->base, SRC_REG, &addr64); \ - CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG); \ - do_mmut_rb(es, DEST_REG, &addr642); \ if (cpu_state.abrt) return 1; \ - temp = readmemb_n(cpu_state.ea_seg->base, SRC_REG, addr64); \ - temp2 = readmemb_n(es, DEST_REG, addr642); if (cpu_state.abrt) return 1; \ + CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG); \ + do_mmut_rb(es, DEST_REG, &addr64_2); \ + if (cpu_state.abrt) return 1; \ + temp = readmemb_n(cpu_state.ea_seg->base, SRC_REG, addr64); if (cpu_state.abrt) return 1; \ + temp2 = readmemb_n(es, DEST_REG, addr64_2); if (cpu_state.abrt) return 1; \ \ if (cpu_state.flags & D_FLAG) { DEST_REG--; SRC_REG--; } \ else { DEST_REG++; SRC_REG++; } \ @@ -538,8 +548,9 @@ static int opREP_CMPSB_ ## size(uint32_t fetchdat) static int opREP_CMPSW_ ## size(uint32_t fetchdat) \ { \ int reads = 0, total_cycles = 0, tempz; \ - uint64_t addr64[2]; \ - uint64_t addr642[2]; \ + \ + addr64a[0] = addr64a[1] = 0x00000000; \ + addr64a_2[0] = addr64a_2[1] = 0x00000000; \ \ tempz = FV; \ if ((CNT_REG > 0) && (FV == tempz)) \ @@ -547,13 +558,15 @@ static int opREP_CMPSW_ ## size(uint32_t fetchdat) uint16_t temp, temp2; \ SEG_CHECK_READ(cpu_state.ea_seg); \ SEG_CHECK_READ(&cpu_state.seg_es); \ - CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 1); \ - do_mmut_rw(cpu_state.ea_seg->base, SRC_REG, addr64); \ - CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG + 1); \ - do_mmut_rw(es, DEST_REG, addr642); \ + CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ + high_page = 0; \ + do_mmut_rw(cpu_state.ea_seg->base, SRC_REG, addr64a); \ if (cpu_state.abrt) return 1; \ - temp = readmemw_n(cpu_state.ea_seg->base, SRC_REG, addr64); \ - temp2 = readmemw_n(es, DEST_REG, addr642); if (cpu_state.abrt) return 1; \ + CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ + do_mmut_rw(es, DEST_REG, addr64a_2); \ + if (cpu_state.abrt) return 1; \ + temp = readmemw_n(cpu_state.ea_seg->base, SRC_REG, addr64a); if (cpu_state.abrt) return 1; \ + temp2 = readmemw_n(es, DEST_REG, addr64a_2); if (cpu_state.abrt) return 1; \ \ if (cpu_state.flags & D_FLAG) { DEST_REG -= 2; SRC_REG -= 2; } \ else { DEST_REG += 2; SRC_REG += 2; } \ @@ -575,8 +588,9 @@ static int opREP_CMPSW_ ## size(uint32_t fetchdat) static int opREP_CMPSL_ ## size(uint32_t fetchdat) \ { \ int reads = 0, total_cycles = 0, tempz; \ - uint64_t addr64[4]; \ - uint64_t addr642[4]; \ + \ + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; \ + addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; \ \ tempz = FV; \ if ((CNT_REG > 0) && (FV == tempz)) \ @@ -584,13 +598,15 @@ static int opREP_CMPSL_ ## size(uint32_t fetchdat) uint32_t temp, temp2; \ SEG_CHECK_READ(cpu_state.ea_seg); \ SEG_CHECK_READ(&cpu_state.seg_es); \ - CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 3); \ - do_mmut_rl(cpu_state.ea_seg->base, SRC_REG, addr64); \ - CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG + 3); \ - do_mmut_rl(es, DEST_REG, addr642); \ + CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ + high_page = 0; \ + do_mmut_rl(cpu_state.ea_seg->base, SRC_REG, addr64a); \ if (cpu_state.abrt) return 1; \ - temp = readmeml_n(cpu_state.ea_seg->base, SRC_REG, addr64); \ - temp2 = readmeml_n(es, DEST_REG, addr642); if (cpu_state.abrt) return 1; \ + CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ + do_mmut_rl(es, DEST_REG, addr64a_2); \ + if (cpu_state.abrt) return 1; \ + temp = readmeml_n(cpu_state.ea_seg->base, SRC_REG, addr64a); if (cpu_state.abrt) return 1; \ + temp2 = readmeml_n(es, DEST_REG, addr64a_2); if (cpu_state.abrt) return 1; \ \ if (cpu_state.flags & D_FLAG) { DEST_REG -= 4; SRC_REG -= 4; } \ else { DEST_REG += 4; SRC_REG += 4; } \ @@ -653,7 +669,7 @@ static int opREP_SCASW_ ## size(uint32_t fetchdat) SEG_CHECK_READ(&cpu_state.seg_es); \ while ((CNT_REG > 0) && (FV == tempz)) \ { \ - CHECK_READ_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1); \ + CHECK_READ_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ uint16_t temp = readmemw(es, DEST_REG); if (cpu_state.abrt) break;\ setsub16(AX, temp); \ tempz = (ZF_SET()) ? 1 : 0; \ @@ -685,7 +701,7 @@ static int opREP_SCASL_ ## size(uint32_t fetchdat) SEG_CHECK_READ(&cpu_state.seg_es); \ while ((CNT_REG > 0) && (FV == tempz)) \ { \ - CHECK_READ_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3); \ + CHECK_READ_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ uint32_t temp = readmeml(es, DEST_REG); if (cpu_state.abrt) break;\ setsub32(EAX, temp); \ tempz = (ZF_SET()) ? 1 : 0; \ diff --git a/src/cpu/x86_ops_stack.h b/src/cpu/x86_ops_stack.h index 9ca1171a0..5bed0b741 100644 --- a/src/cpu/x86_ops_stack.h +++ b/src/cpu/x86_ops_stack.h @@ -245,8 +245,8 @@ static int opPOPW_a16(uint32_t fetchdat) else SP -= 2; } - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6); - else CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5); + if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5); } PREFETCH_RUN((cpu_mod == 3) ? 4 : 5, 2, rmdat, 1,0,(cpu_mod == 3) ? 0:1,0, 0); return cpu_state.abrt; } @@ -266,8 +266,8 @@ static int opPOPW_a32(uint32_t fetchdat) else SP -= 2; } - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6); - else CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5); + if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5); } PREFETCH_RUN((cpu_mod == 3) ? 4 : 5, 2, rmdat, 1,0,(cpu_mod == 3) ? 0:1,0, 1); return cpu_state.abrt; } @@ -288,8 +288,8 @@ static int opPOPL_a16(uint32_t fetchdat) else SP -= 4; } - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6); - else CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5); + if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5); } PREFETCH_RUN((cpu_mod == 3) ? 4 : 5, 2, rmdat, 0,1,0,(cpu_mod == 3) ? 0:1, 0); return cpu_state.abrt; } @@ -309,8 +309,8 @@ static int opPOPL_a32(uint32_t fetchdat) else SP -= 4; } - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6); - else CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5); + if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5); } PREFETCH_RUN((cpu_mod == 3) ? 4 : 5, 2, rmdat, 0,1,0,(cpu_mod == 3) ? 0:1, 1); return cpu_state.abrt; } @@ -470,17 +470,16 @@ static int opLEAVE_l(uint32_t fetchdat) } -PUSH_SEG_OPS(CS); -PUSH_SEG_OPS(DS); -PUSH_SEG_OPS(ES); -PUSH_SEG_OPS(FS); -PUSH_SEG_OPS(GS); -PUSH_SEG_OPS(SS); - -POP_SEG_OPS(DS, &cpu_state.seg_ds); -POP_SEG_OPS(ES, &cpu_state.seg_es); -POP_SEG_OPS(FS, &cpu_state.seg_fs); -POP_SEG_OPS(GS, &cpu_state.seg_gs); +PUSH_SEG_OPS(CS) +PUSH_SEG_OPS(DS) +PUSH_SEG_OPS(ES) +PUSH_SEG_OPS(FS) +PUSH_SEG_OPS(GS) +PUSH_SEG_OPS(SS) +POP_SEG_OPS(DS, &cpu_state.seg_ds) +POP_SEG_OPS(ES, &cpu_state.seg_es) +POP_SEG_OPS(FS, &cpu_state.seg_fs) +POP_SEG_OPS(GS, &cpu_state.seg_gs) static int opPOP_SS_w(uint32_t fetchdat) diff --git a/src/cpu/x86_ops_string.h b/src/cpu/x86_ops_string.h index 2cdbd7959..675489aed 100644 --- a/src/cpu/x86_ops_string.h +++ b/src/cpu/x86_ops_string.h @@ -1,17 +1,18 @@ static int opMOVSB_a16(uint32_t fetchdat) { uint8_t temp; - uint64_t addr64r; - uint64_t addr64w; + + addr64 = addr64_2 = 0x00000000; SEG_CHECK_READ(cpu_state.ea_seg); - do_mmut_rb(cpu_state.ea_seg->base, SI, &addr64r); + high_page = 0; + do_mmut_rb(cpu_state.ea_seg->base, SI, &addr64); if (cpu_state.abrt) return 1; SEG_CHECK_WRITE(&cpu_state.seg_es); - do_mmut_wb(es, DI, &addr64w); + do_mmut_wb(es, DI, &addr64_2); if (cpu_state.abrt) return 1; - temp = readmemb_n(cpu_state.ea_seg->base, SI, addr64r); if (cpu_state.abrt) return 1; - writememb_n(es, DI, addr64w, temp); if (cpu_state.abrt) return 1; + temp = readmemb_n(cpu_state.ea_seg->base, SI, addr64); if (cpu_state.abrt) return 1; + writememb_n(es, DI, addr64_2, temp); if (cpu_state.abrt) return 1; if (cpu_state.flags & D_FLAG) { DI--; SI--; } else { DI++; SI++; } CLOCK_CYCLES(7); @@ -21,17 +22,18 @@ static int opMOVSB_a16(uint32_t fetchdat) static int opMOVSB_a32(uint32_t fetchdat) { uint8_t temp; - uint64_t addr64r; - uint64_t addr64w; + + addr64 = addr64_2 = 0x00000000; SEG_CHECK_READ(cpu_state.ea_seg); - do_mmut_rb(cpu_state.ea_seg->base, ESI, &addr64r); + high_page = 0; + do_mmut_rb(cpu_state.ea_seg->base, ESI, &addr64); if (cpu_state.abrt) return 1; SEG_CHECK_WRITE(&cpu_state.seg_es); - do_mmut_wb(es, EDI, &addr64w); + do_mmut_wb(es, EDI, &addr64_2); if (cpu_state.abrt) return 1; - temp = readmemb_n(cpu_state.ea_seg->base, ESI, addr64r); if (cpu_state.abrt) return 1; - writememb_n(es, EDI, addr64w, temp); if (cpu_state.abrt) return 1; + temp = readmemb_n(cpu_state.ea_seg->base, ESI, addr64); if (cpu_state.abrt) return 1; + writememb_n(es, EDI, addr64_2, temp); if (cpu_state.abrt) return 1; if (cpu_state.flags & D_FLAG) { EDI--; ESI--; } else { EDI++; ESI++; } CLOCK_CYCLES(7); @@ -42,17 +44,19 @@ static int opMOVSB_a32(uint32_t fetchdat) static int opMOVSW_a16(uint32_t fetchdat) { uint16_t temp; - uint64_t addr64r[2]; - uint64_t addr64w[2]; + + addr64a[0] = addr64a[1] = 0x00000000; + addr64a_2[0] = addr64a_2[1] = 0x00000000; SEG_CHECK_READ(cpu_state.ea_seg); - do_mmut_rw(cpu_state.ea_seg->base, SI, addr64r); + high_page = 0; + do_mmut_rw(cpu_state.ea_seg->base, SI, addr64a); if (cpu_state.abrt) return 1; SEG_CHECK_WRITE(&cpu_state.seg_es); - do_mmut_ww(es, DI, addr64w); + do_mmut_ww(es, DI, addr64a_2); if (cpu_state.abrt) return 1; - temp = readmemw_n(cpu_state.ea_seg->base, SI, addr64r); if (cpu_state.abrt) return 1; - writememw_n(es, DI, addr64w, temp); if (cpu_state.abrt) return 1; + temp = readmemw_n(cpu_state.ea_seg->base, SI, addr64a); if (cpu_state.abrt) return 1; + writememw_n(es, DI, addr64a_2, temp); if (cpu_state.abrt) return 1; if (cpu_state.flags & D_FLAG) { DI -= 2; SI -= 2; } else { DI += 2; SI += 2; } CLOCK_CYCLES(7); @@ -62,17 +66,19 @@ static int opMOVSW_a16(uint32_t fetchdat) static int opMOVSW_a32(uint32_t fetchdat) { uint16_t temp; - uint64_t addr64r[2]; - uint64_t addr64w[2]; + + addr64a[0] = addr64a[1] = 0x00000000; + addr64a_2[0] = addr64a_2[1] = 0x00000000; SEG_CHECK_READ(cpu_state.ea_seg); - do_mmut_rw(cpu_state.ea_seg->base, ESI, addr64r); + high_page = 0; + do_mmut_rw(cpu_state.ea_seg->base, ESI, addr64a); if (cpu_state.abrt) return 1; SEG_CHECK_WRITE(&cpu_state.seg_es); - do_mmut_ww(es, EDI, addr64w); + do_mmut_ww(es, EDI, addr64a_2); if (cpu_state.abrt) return 1; - temp = readmemw_n(cpu_state.ea_seg->base, ESI, addr64r); if (cpu_state.abrt) return 1; - writememw_n(es, EDI, addr64w, temp); if (cpu_state.abrt) return 1; + temp = readmemw_n(cpu_state.ea_seg->base, ESI, addr64a); if (cpu_state.abrt) return 1; + writememw_n(es, EDI, addr64a_2, temp); if (cpu_state.abrt) return 1; if (cpu_state.flags & D_FLAG) { EDI -= 2; ESI -= 2; } else { EDI += 2; ESI += 2; } CLOCK_CYCLES(7); @@ -83,17 +89,19 @@ static int opMOVSW_a32(uint32_t fetchdat) static int opMOVSL_a16(uint32_t fetchdat) { uint32_t temp; - uint64_t addr64r[4]; - uint64_t addr64w[4]; + + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; + addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; SEG_CHECK_READ(cpu_state.ea_seg); - do_mmut_rl(cpu_state.ea_seg->base, SI, addr64r); + high_page = 0; + do_mmut_rl(cpu_state.ea_seg->base, SI, addr64a); if (cpu_state.abrt) return 1; SEG_CHECK_WRITE(&cpu_state.seg_es); - do_mmut_wl(es, DI, addr64w); + do_mmut_wl(es, DI, addr64a_2); if (cpu_state.abrt) return 1; - temp = readmeml_n(cpu_state.ea_seg->base, SI, addr64r); if (cpu_state.abrt) return 1; - writememl_n(es, DI, addr64w, temp); if (cpu_state.abrt) return 1; + temp = readmeml_n(cpu_state.ea_seg->base, SI, addr64a); if (cpu_state.abrt) return 1; + writememl_n(es, DI, addr64a_2, temp); if (cpu_state.abrt) return 1; if (cpu_state.flags & D_FLAG) { DI -= 4; SI -= 4; } else { DI += 4; SI += 4; } CLOCK_CYCLES(7); @@ -103,17 +111,19 @@ static int opMOVSL_a16(uint32_t fetchdat) static int opMOVSL_a32(uint32_t fetchdat) { uint32_t temp; - uint64_t addr64r[4]; - uint64_t addr64w[4]; + + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; + addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; SEG_CHECK_READ(cpu_state.ea_seg); - do_mmut_rl(cpu_state.ea_seg->base, ESI, addr64r); + high_page = 0; + do_mmut_rl(cpu_state.ea_seg->base, ESI, addr64a); if (cpu_state.abrt) return 1; SEG_CHECK_WRITE(&cpu_state.seg_es); - do_mmut_wl(es, EDI, addr64w); + do_mmut_wl(es, EDI, addr64a_2); if (cpu_state.abrt) return 1; - temp = readmeml_n(cpu_state.ea_seg->base, ESI, addr64r); if (cpu_state.abrt) return 1; - writememl_n(es, EDI, addr64w, temp); if (cpu_state.abrt) return 1; + temp = readmeml_n(cpu_state.ea_seg->base, ESI, addr64a); if (cpu_state.abrt) return 1; + writememl_n(es, EDI, addr64a_2, temp); if (cpu_state.abrt) return 1; if (cpu_state.flags & D_FLAG) { EDI -= 4; ESI -= 4; } else { EDI += 4; ESI += 4; } CLOCK_CYCLES(7); @@ -125,17 +135,18 @@ static int opMOVSL_a32(uint32_t fetchdat) static int opCMPSB_a16(uint32_t fetchdat) { uint8_t src, dst; - uint64_t addr64; - uint64_t addr642; + + addr64 = addr64_2 = 0x00000000; SEG_CHECK_READ(cpu_state.ea_seg); + high_page = 0; do_mmut_rb(cpu_state.ea_seg->base, SI, &addr64); if (cpu_state.abrt) return 1; SEG_CHECK_READ(&cpu_state.seg_es); - do_mmut_rb(es, DI, &addr642); + do_mmut_rb(es, DI, &addr64_2); if (cpu_state.abrt) return 1; - src = readmemb_n(cpu_state.ea_seg->base, SI, addr64); - dst = readmemb_n(es, DI, addr642); if (cpu_state.abrt) return 1; + src = readmemb_n(cpu_state.ea_seg->base, SI, addr64); if (cpu_state.abrt) return 1; + dst = readmemb_n(es, DI, addr64_2); if (cpu_state.abrt) return 1; setsub8(src, dst); if (cpu_state.flags & D_FLAG) { DI--; SI--; } else { DI++; SI++; } @@ -146,17 +157,18 @@ static int opCMPSB_a16(uint32_t fetchdat) static int opCMPSB_a32(uint32_t fetchdat) { uint8_t src, dst; - uint64_t addr64; - uint64_t addr642; + + addr64 = addr64_2 = 0x00000000; SEG_CHECK_READ(cpu_state.ea_seg); + high_page = 0; do_mmut_rb(cpu_state.ea_seg->base, ESI, &addr64); if (cpu_state.abrt) return 1; SEG_CHECK_READ(&cpu_state.seg_es); - do_mmut_rb(es, EDI, &addr642); + do_mmut_rb(es, EDI, &addr64_2); if (cpu_state.abrt) return 1; - src = readmemb_n(cpu_state.ea_seg->base, ESI, addr64); - dst = readmemb_n(es, EDI, addr642); if (cpu_state.abrt) return 1; + src = readmemb_n(cpu_state.ea_seg->base, ESI, addr64); if (cpu_state.abrt) return 1; + dst = readmemb_n(es, EDI, addr64_2); if (cpu_state.abrt) return 1; setsub8(src, dst); if (cpu_state.flags & D_FLAG) { EDI--; ESI--; } else { EDI++; ESI++; } @@ -168,17 +180,19 @@ static int opCMPSB_a32(uint32_t fetchdat) static int opCMPSW_a16(uint32_t fetchdat) { uint16_t src, dst; - uint64_t addr64[2]; - uint64_t addr642[2]; + + addr64a[0] = addr64a[1] = 0x00000000; + addr64a_2[0] = addr64a_2[1] = 0x00000000; SEG_CHECK_READ(cpu_state.ea_seg); - do_mmut_rw(cpu_state.ea_seg->base, SI, addr64); + high_page = 0; + do_mmut_rw(cpu_state.ea_seg->base, SI, addr64a); if (cpu_state.abrt) return 1; SEG_CHECK_READ(&cpu_state.seg_es); - do_mmut_rw(es, DI, addr642); + do_mmut_rw(es, DI, addr64a_2); if (cpu_state.abrt) return 1; - src = readmemw_n(cpu_state.ea_seg->base, SI, addr64); - dst = readmemw_n(es, DI, addr642); if (cpu_state.abrt) return 1; + src = readmemw_n(cpu_state.ea_seg->base, SI, addr64a); if (cpu_state.abrt) return 1; + dst = readmemw_n(es, DI, addr64a_2); if (cpu_state.abrt) return 1; setsub16(src, dst); if (cpu_state.flags & D_FLAG) { DI -= 2; SI -= 2; } else { DI += 2; SI += 2; } @@ -189,17 +203,19 @@ static int opCMPSW_a16(uint32_t fetchdat) static int opCMPSW_a32(uint32_t fetchdat) { uint16_t src, dst; - uint64_t addr64[2]; - uint64_t addr642[2]; + + addr64a[0] = addr64a[1] = 0x00000000; + addr64a_2[0] = addr64a_2[1] = 0x00000000; SEG_CHECK_READ(cpu_state.ea_seg); - do_mmut_rw(cpu_state.ea_seg->base, ESI, addr64); + high_page = 0; + do_mmut_rw(cpu_state.ea_seg->base, ESI, addr64a); if (cpu_state.abrt) return 1; SEG_CHECK_READ(&cpu_state.seg_es); - do_mmut_rw(es, EDI, addr642); + do_mmut_rw(es, EDI, addr64a_2); if (cpu_state.abrt) return 1; - src = readmemw_n(cpu_state.ea_seg->base, ESI, addr64); - dst = readmemw_n(es, EDI, addr642); if (cpu_state.abrt) return 1; + src = readmemw_n(cpu_state.ea_seg->base, ESI, addr64a); if (cpu_state.abrt) return 1; + dst = readmemw_n(es, EDI, addr64a_2); if (cpu_state.abrt) return 1; setsub16(src, dst); if (cpu_state.flags & D_FLAG) { EDI -= 2; ESI -= 2; } else { EDI += 2; ESI += 2; } @@ -211,17 +227,19 @@ static int opCMPSW_a32(uint32_t fetchdat) static int opCMPSL_a16(uint32_t fetchdat) { uint32_t src, dst; - uint64_t addr64[4]; - uint64_t addr642[4]; + + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; + addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; SEG_CHECK_READ(cpu_state.ea_seg); - do_mmut_rl(cpu_state.ea_seg->base, SI, addr64); + high_page = 0; + do_mmut_rl(cpu_state.ea_seg->base, SI, addr64a); if (cpu_state.abrt) return 1; SEG_CHECK_READ(&cpu_state.seg_es); - do_mmut_rl(es, DI, addr642); + do_mmut_rl(es, DI, addr64a_2); if (cpu_state.abrt) return 1; - src = readmeml_n(cpu_state.ea_seg->base, SI, addr64); - dst = readmeml_n(es, DI, addr642); if (cpu_state.abrt) return 1; + src = readmeml_n(cpu_state.ea_seg->base, SI, addr64a); if (cpu_state.abrt) return 1; + dst = readmeml_n(es, DI, addr64a_2); if (cpu_state.abrt) return 1; setsub32(src, dst); if (cpu_state.flags & D_FLAG) { DI -= 4; SI -= 4; } else { DI += 4; SI += 4; } @@ -232,17 +250,19 @@ static int opCMPSL_a16(uint32_t fetchdat) static int opCMPSL_a32(uint32_t fetchdat) { uint32_t src, dst; - uint64_t addr64[4]; - uint64_t addr642[4]; + + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; + addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; SEG_CHECK_READ(cpu_state.ea_seg); - do_mmut_rl(cpu_state.ea_seg->base, ESI, addr64); + high_page = 0; + do_mmut_rl(cpu_state.ea_seg->base, ESI, addr64a); if (cpu_state.abrt) return 1; SEG_CHECK_READ(&cpu_state.seg_es); - do_mmut_rl(es, EDI, addr642); + do_mmut_rl(es, EDI, addr64a_2); if (cpu_state.abrt) return 1; - src = readmeml_n(cpu_state.ea_seg->base, ESI, addr64); - dst = readmeml_n(es, EDI, addr642); if (cpu_state.abrt) return 1; + src = readmeml_n(cpu_state.ea_seg->base, ESI, addr64a); if (cpu_state.abrt) return 1; + dst = readmeml_n(es, EDI, addr64a_2); if (cpu_state.abrt) return 1; setsub32(src, dst); if (cpu_state.flags & D_FLAG) { EDI -= 4; ESI -= 4; } else { EDI += 4; ESI += 4; } @@ -481,10 +501,12 @@ static int opSCASL_a32(uint32_t fetchdat) static int opINSB_a16(uint32_t fetchdat) { uint8_t temp; - uint64_t addr64 = 0x0000000000000000ULL; + + addr64 = 0x00000000; SEG_CHECK_WRITE(&cpu_state.seg_es); check_io_perm(DX); + high_page = 0; do_mmut_wb(es, DI, &addr64); if (cpu_state.abrt) return 1; temp = inb(DX); writememb_n(es, DI, addr64, temp); if (cpu_state.abrt) return 1; @@ -497,10 +519,12 @@ static int opINSB_a16(uint32_t fetchdat) static int opINSB_a32(uint32_t fetchdat) { uint8_t temp; - uint64_t addr64 = 0x0000000000000000ULL; + + addr64 = 0x00000000; SEG_CHECK_WRITE(&cpu_state.seg_es); check_io_perm(DX); + high_page = 0; do_mmut_wb(es, EDI, &addr64); if (cpu_state.abrt) return 1; temp = inb(DX); writememb_n(es, EDI, addr64, temp); if (cpu_state.abrt) return 1; @@ -514,14 +538,16 @@ static int opINSB_a32(uint32_t fetchdat) static int opINSW_a16(uint32_t fetchdat) { uint16_t temp; - uint64_t addr64[2]; + + addr64a[0] = addr64a[1] = 0x00000000; SEG_CHECK_WRITE(&cpu_state.seg_es); check_io_perm(DX); check_io_perm(DX + 1); - do_mmut_ww(es, DI, addr64); if (cpu_state.abrt) return 1; + high_page = 0; + do_mmut_ww(es, DI, addr64a); if (cpu_state.abrt) return 1; temp = inw(DX); - writememw_n(es, DI, addr64, temp); if (cpu_state.abrt) return 1; + writememw_n(es, DI, addr64a, temp); if (cpu_state.abrt) return 1; if (cpu_state.flags & D_FLAG) DI -= 2; else DI += 2; CLOCK_CYCLES(15); @@ -531,14 +557,16 @@ static int opINSW_a16(uint32_t fetchdat) static int opINSW_a32(uint32_t fetchdat) { uint16_t temp; - uint64_t addr64[2]; + + addr64a[0] = addr64a[1] = 0x00000000; SEG_CHECK_WRITE(&cpu_state.seg_es); + high_page = 0; check_io_perm(DX); check_io_perm(DX + 1); - do_mmut_ww(es, EDI, addr64); if (cpu_state.abrt) return 1; + do_mmut_ww(es, EDI, addr64a); if (cpu_state.abrt) return 1; temp = inw(DX); - writememw_n(es, EDI, addr64, temp); if (cpu_state.abrt) return 1; + writememw_n(es, EDI, addr64a, temp); if (cpu_state.abrt) return 1; if (cpu_state.flags & D_FLAG) EDI -= 2; else EDI += 2; CLOCK_CYCLES(15); @@ -549,16 +577,18 @@ static int opINSW_a32(uint32_t fetchdat) static int opINSL_a16(uint32_t fetchdat) { uint32_t temp; - uint64_t addr64[4]; + + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; SEG_CHECK_WRITE(&cpu_state.seg_es); check_io_perm(DX); check_io_perm(DX + 1); check_io_perm(DX + 2); check_io_perm(DX + 3); - do_mmut_wl(es, DI, addr64); if (cpu_state.abrt) return 1; + high_page = 0; + do_mmut_wl(es, DI, addr64a); if (cpu_state.abrt) return 1; temp = inl(DX); - writememl_n(es, DI, addr64, temp); if (cpu_state.abrt) return 1; + writememl_n(es, DI, addr64a, temp); if (cpu_state.abrt) return 1; if (cpu_state.flags & D_FLAG) DI -= 4; else DI += 4; CLOCK_CYCLES(15); @@ -568,16 +598,18 @@ static int opINSL_a16(uint32_t fetchdat) static int opINSL_a32(uint32_t fetchdat) { uint32_t temp; - uint64_t addr64[4]; + + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; SEG_CHECK_WRITE(&cpu_state.seg_es); check_io_perm(DX); check_io_perm(DX + 1); check_io_perm(DX + 2); check_io_perm(DX + 3); - do_mmut_wl(es, DI, addr64); if (cpu_state.abrt) return 1; + high_page = 0; + do_mmut_wl(es, DI, addr64a); if (cpu_state.abrt) return 1; temp = inl(DX); - writememl_n(es, EDI, addr64, temp); if (cpu_state.abrt) return 1; + writememl_n(es, EDI, addr64a, temp); if (cpu_state.abrt) return 1; if (cpu_state.flags & D_FLAG) EDI -= 4; else EDI += 4; CLOCK_CYCLES(15); diff --git a/src/cpu/x86seg.c b/src/cpu/x86seg.c index 64ea5dd6f..a9c3923c8 100644 --- a/src/cpu/x86seg.c +++ b/src/cpu/x86seg.c @@ -281,7 +281,7 @@ check_seg_valid(x86seg *s) int valid = 1; x86seg *dt = (s->seg & 0x0004) ? &ldt : &gdt; - if (((s->seg & 0xfff8) + 7) > dt->limit) + if (((s->seg & 0xfff8UL) + 7UL) > dt->limit) valid = 0; switch (s->access & 0x1f) { diff --git a/src/include/86box/mem.h b/src/include/86box/mem.h index 6410d6d30..52e1ba810 100644 --- a/src/include/86box/mem.h +++ b/src/include/86box/mem.h @@ -189,12 +189,10 @@ extern uint32_t rammask; extern uint8_t *rom; extern uint32_t biosmask, biosaddr; -extern int readlookup[256], - readlookupp[256]; +extern int readlookup[256]; extern uintptr_t * readlookup2; extern int readlnext; -extern int writelookup[256], - writelookupp[256]; +extern int writelookup[256]; extern uintptr_t * writelookup2; extern int writelnext; extern uint32_t ram_mapped_addr[64]; @@ -224,6 +222,7 @@ extern int readlnum, extern int memspeed[11]; extern int mmu_perm; +extern uint8_t high_page; /* if a high (> 4 gb) page was detected */ extern int mem_a20_state, mem_a20_alt, @@ -244,14 +243,14 @@ extern void writememll(uint32_t addr, uint32_t val); extern uint64_t readmemql(uint32_t addr); extern void writememql(uint32_t addr, uint64_t val); -extern uint8_t readmembl_no_mmut(uint32_t addr, uint64_t addr64); -extern void writemembl_no_mmut(uint32_t addr, uint64_t addr64, uint8_t val); -extern uint16_t readmemwl_no_mmut(uint32_t addr, uint64_t *addr64); -extern void writememwl_no_mmut(uint32_t addr, uint64_t *addr64, uint16_t val); -extern uint32_t readmemll_no_mmut(uint32_t addr, uint64_t *addr64); -extern void writememll_no_mmut(uint32_t addr, uint64_t *addr64, uint32_t val); +extern uint8_t readmembl_no_mmut(uint32_t addr, uint32_t a64); +extern void writemembl_no_mmut(uint32_t addr, uint32_t a64, uint8_t val); +extern uint16_t readmemwl_no_mmut(uint32_t addr, uint32_t *a64); +extern void writememwl_no_mmut(uint32_t addr, uint32_t *a64, uint16_t val); +extern uint32_t readmemll_no_mmut(uint32_t addr, uint32_t *a64); +extern void writememll_no_mmut(uint32_t addr, uint32_t *a64, uint32_t val); -extern void do_mmutranslate(uint32_t addr, uint64_t *addr64, int num, int write); +extern void do_mmutranslate(uint32_t addr, uint32_t *a64, int num, int write); extern uint8_t *getpccache(uint32_t a); extern uint64_t mmutranslatereal(uint32_t addr, int rw); diff --git a/src/mem/mem.c b/src/mem/mem.c index 062375994..73f89b3eb 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -80,12 +80,10 @@ uint32_t pccache; uint8_t *pccache2; int readlnext; -int readlookup[256], - readlookupp[256]; +int readlookup[256]; uintptr_t *readlookup2; int writelnext; -int writelookup[256], - writelookupp[256]; +int writelookup[256]; uintptr_t *writelookup2; uint32_t mem_logical_addr; @@ -112,8 +110,13 @@ uint64_t *byte_code_present_mask; uint32_t purgable_page_list_head = 0; int purgeable_page_count = 0; +uint8_t high_page = 0; /* if a high (> 4 gb) page was detected */ + /* FIXME: re-do this with a 'mem_ops' struct. */ +static uint8_t *page_lookupp; /* pagetable mmu_perm lookup */ +static uint8_t *readlookupp; +static uint8_t *writelookupp; static mem_mapping_t *base_mapping, *last_mapping; static mem_mapping_t *read_mapping[MEM_MAPPINGS_NO]; static mem_mapping_t *write_mapping[MEM_MAPPINGS_NO]; @@ -168,11 +171,15 @@ resetreadlookup(void) /* Initialize the tables for high (> 1024K) RAM. */ memset(readlookup2, 0xff, (1<<20)*sizeof(uintptr_t)); + memset(readlookupp, 0x04, (1<<20)*sizeof(uint8_t)); + memset(writelookup2, 0xff, (1<<20)*sizeof(uintptr_t)); + memset(writelookupp, 0x04, (1<<20)*sizeof(uint8_t)); readlnext = 0; writelnext = 0; pccache = 0xffffffff; + high_page = 0; } @@ -184,11 +191,14 @@ flushmmucache(void) for (c = 0; c < 256; c++) { if (readlookup[c] != (int) 0xffffffff) { readlookup2[readlookup[c]] = LOOKUP_INV; + readlookupp[readlookup[c]] = 4; readlookup[c] = 0xffffffff; } if (writelookup[c] != (int) 0xffffffff) { page_lookup[writelookup[c]] = NULL; + page_lookupp[writelookup[c]] = 4; writelookup2[writelookup[c]] = LOOKUP_INV; + writelookupp[writelookup[c]] = 4; writelookup[c] = 0xffffffff; } } @@ -211,11 +221,14 @@ flushmmucache_nopc(void) for (c = 0; c < 256; c++) { if (readlookup[c] != (int) 0xffffffff) { readlookup2[readlookup[c]] = LOOKUP_INV; + readlookupp[readlookup[c]] = 4; readlookup[c] = 0xffffffff; } if (writelookup[c] != (int) 0xffffffff) { page_lookup[writelookup[c]] = NULL; + page_lookupp[writelookup[c]] = 4; writelookup2[writelookup[c]] = LOOKUP_INV; + writelookupp[writelookup[c]] = 4; writelookup[c] = 0xffffffff; } } @@ -230,11 +243,14 @@ flushmmucache_cr3(void) for (c = 0; c < 256; c++) { if (readlookup[c] != (int) 0xffffffff) { readlookup2[readlookup[c]] = LOOKUP_INV; + readlookupp[readlookup[c]] = 4; readlookup[c] = 0xffffffff; } if (writelookup[c] != (int) 0xffffffff) { page_lookup[writelookup[c]] = NULL; + page_lookupp[writelookup[c]] = 4; writelookup2[writelookup[c]] = LOOKUP_INV; + writelookupp[writelookup[c]] = 4; writelookup[c] = 0xffffffff; } } @@ -277,7 +293,7 @@ mem_flush_write_page(uint32_t addr, uint32_t virt) static __inline uint64_t mmutranslatereal_normal(uint32_t addr, int rw) { - uint32_t temp,temp2,temp3; + uint32_t temp, temp2, temp3; uint32_t addr2; if (cpu_state.abrt) @@ -311,18 +327,20 @@ mmutranslatereal_normal(uint32_t addr, int rw) } mmu_perm = temp & 4; - rammap(addr2) |= 0x20; + rammap(addr2) |= (rw ? 0x60 : 0x20); return (temp & ~0x3fffff) + (addr & 0x3fffff); } temp = rammap((temp & ~0xfff) + ((addr >> 10) & 0xffc)); temp3 = temp & temp2; - if (!(temp&1) || ((CPL == 3) && !(temp3 & 4) && !cpl_override) || (rw && !(temp3 & 2) && (((CPL == 3) && !cpl_override) || (is486 && (cr0 & WP_FLAG))))) { + if (!(temp & 1) || ((CPL == 3) && !(temp3 & 4) && !cpl_override) || (rw && !(temp3 & 2) && (((CPL == 3) && !cpl_override) || (is486 && (cr0 & WP_FLAG))))) { cr2 = addr; temp &= 1; - if (CPL == 3) temp |= 4; - if (rw) temp |= 2; + if (CPL == 3) + temp |= 4; + if (rw) + temp |= 2; cpu_state.abrt = ABRT_PF; abrt_error = temp; return 0xffffffffffffffffULL; @@ -330,17 +348,17 @@ mmutranslatereal_normal(uint32_t addr, int rw) mmu_perm = temp & 4; rammap(addr2) |= 0x20; - rammap((temp2 & ~0xfff) + ((addr >> 10) & 0xffc)) |= (rw?0x60:0x20); + rammap((temp2 & ~0xfff) + ((addr >> 10) & 0xffc)) |= (rw ? 0x60 : 0x20); - return (uint64_t) ((temp&~0xfff)+(addr&0xfff)); + return (uint64_t) ((temp & ~0xfff) + (addr & 0xfff)); } static __inline uint64_t mmutranslatereal_pae(uint32_t addr, int rw) { - uint64_t temp,temp2,temp3,temp4; - uint64_t addr2,addr3,addr4; + uint64_t temp, temp2, temp3, temp4; + uint64_t addr2, addr3, addr4; if (cpu_state.abrt) return 0xffffffffffffffffULL; @@ -385,7 +403,7 @@ mmutranslatereal_pae(uint32_t addr, int rw) return 0xffffffffffffffffULL; } mmu_perm = temp & 4; - rammap64(addr3) |= 0x20; + rammap64(addr3) |= (rw ? 0x60 : 0x20); return ((temp & ~0x1fffffULL) + (addr & 0x1fffffULL)) & 0x000000ffffffffffULL; } @@ -405,7 +423,7 @@ mmutranslatereal_pae(uint32_t addr, int rw) mmu_perm = temp & 4; rammap64(addr3) |= 0x20; - rammap64(addr4) |= (rw? 0x60 : 0x20); + rammap64(addr4) |= (rw ? 0x60 : 0x20); return ((temp & ~0xfffULL) + ((uint64_t) (addr & 0xfff))) & 0x000000ffffffffffULL; } @@ -579,8 +597,8 @@ addreadlookup(uint32_t virt, uint32_t phys) readlookup2[virt>>12] = (uintptr_t)&ram2[a - (1 << 30)]; else readlookup2[virt>>12] = (uintptr_t)&ram[a]; + readlookupp[virt>>12] = mmu_perm; - readlookupp[readlnext] = mmu_perm; readlookup[readlnext++] = virt >> 12; readlnext &= (cachesize-1); @@ -608,19 +626,20 @@ addwritelookup(uint32_t virt, uint32_t phys) #ifdef USE_NEW_DYNAREC #ifdef USE_DYNAREC - if (pages[phys >> 12].block || (phys & ~0xfff) == recomp_page) + if (pages[phys >> 12].block || (phys & ~0xfff) == recomp_page) { #else - if (pages[phys >> 12].block) + if (pages[phys >> 12].block) { #endif #else #ifdef USE_DYNAREC - if (pages[phys >> 12].block[0] || pages[phys >> 12].block[1] || pages[phys >> 12].block[2] || pages[phys >> 12].block[3] || (phys & ~0xfff) == recomp_page) + if (pages[phys >> 12].block[0] || pages[phys >> 12].block[1] || pages[phys >> 12].block[2] || pages[phys >> 12].block[3] || (phys & ~0xfff) == recomp_page) { #else - if (pages[phys >> 12].block[0] || pages[phys >> 12].block[1] || pages[phys >> 12].block[2] || pages[phys >> 12].block[3]) + if (pages[phys >> 12].block[0] || pages[phys >> 12].block[1] || pages[phys >> 12].block[2] || pages[phys >> 12].block[3]) { #endif #endif page_lookup[virt >> 12] = &pages[phys >> 12]; - else { + page_lookupp[virt >> 12] = mmu_perm; + } else { #if (defined __amd64__ || defined _M_X64) a = ((uint64_t)(phys & ~0xfff) - (uint64_t)(virt & ~0xfff)); #else @@ -632,8 +651,8 @@ addwritelookup(uint32_t virt, uint32_t phys) else writelookup2[virt>>12] = (uintptr_t)&ram[a]; } + writelookupp[virt>>12] = mmu_perm; - writelookupp[writelnext] = mmu_perm; writelookup[writelnext++] = virt >> 12; writelnext &= (cachesize - 1); @@ -768,14 +787,19 @@ write_mem_w(uint32_t addr, uint16_t val) uint8_t readmembl(uint32_t addr) { - uint64_t addr64 = (uint64_t) addr; mem_mapping_t *map; + uint64_t a; + addr64 = (uint64_t) addr; mem_logical_addr = addr; + high_page = 0; + if (cr0 >> 31) { - addr64 = mmutranslate_read(addr); - if (addr64 > 0xffffffffULL) + a = mmutranslate_read(addr); + addr64 = (uint32_t) a; + + if (a > 0xffffffffULL) return 0xff; } addr = (uint32_t) (addr64 & rammask); @@ -791,19 +815,24 @@ readmembl(uint32_t addr) void writemembl(uint32_t addr, uint8_t val) { - uint64_t addr64 = (uint64_t) addr; mem_mapping_t *map; + uint64_t a; + addr64 = (uint64_t) addr; mem_logical_addr = addr; + high_page = 0; + if (page_lookup[addr>>12] && page_lookup[addr>>12]->write_b) { page_lookup[addr>>12]->write_b(addr, val, page_lookup[addr>>12]); return; } if (cr0 >> 31) { - addr64 = mmutranslate_write(addr); - if (addr64 > 0xffffffffULL) + a = mmutranslate_write(addr); + addr64 = (uint32_t) a; + + if (a > 0xffffffffULL) return; } addr = (uint32_t) (addr64 & rammask); @@ -816,17 +845,17 @@ writemembl(uint32_t addr, uint8_t val) /* Read a byte from memory without MMU translation - result of previous MMU translation passed as value. */ uint8_t -readmembl_no_mmut(uint32_t addr, uint64_t addr64) +readmembl_no_mmut(uint32_t addr, uint32_t a64) { mem_mapping_t *map; mem_logical_addr = addr; if (cr0 >> 31) { - if (addr64 > 0xffffffffULL) + if (cpu_state.abrt || high_page) return 0xff; - addr = (uint32_t) (addr64 & rammask); + addr = a64 & rammask; } else addr &= rammask; @@ -840,7 +869,7 @@ readmembl_no_mmut(uint32_t addr, uint64_t addr64) /* Write a byte to memory without MMU translation - result of previous MMU translation passed as value. */ void -writemembl_no_mmut(uint32_t addr, uint64_t addr64, uint8_t val) +writemembl_no_mmut(uint32_t addr, uint32_t a64, uint8_t val) { mem_mapping_t *map; @@ -852,10 +881,10 @@ writemembl_no_mmut(uint32_t addr, uint64_t addr64, uint8_t val) } if (cr0 >> 31) { - if (addr64 > 0xffffffffULL) + if (cpu_state.abrt || high_page) return; - addr = (uint32_t) (addr64 & rammask); + addr = a64 & rammask; } else addr &= rammask; @@ -868,42 +897,49 @@ writemembl_no_mmut(uint32_t addr, uint64_t addr64, uint8_t val) uint16_t readmemwl(uint32_t addr) { - uint64_t addr64[2]; mem_mapping_t *map; int i; + uint64_t a; - addr64[0] = (uint64_t) addr; - addr64[1] = (uint64_t) (addr + 1); + addr64a[0] = addr; + addr64a[1] = addr + 1; mem_logical_addr = addr; + high_page = 0; + if (addr & 1) { if (!cpu_cyrix_alignment || (addr & 7) == 7) cycles -= timing_misaligned; if ((addr & 0xfff) > 0xffe) { if (cr0 >> 31) { for (i = 0; i < 2; i++) { - addr64[i] = mmutranslate_read(addr + i); + a = mmutranslate_read(addr + i); + addr64a[i] = (uint32_t) a; - if (addr64[i] > 0xffffffffULL) + if (a > 0xffffffffULL) return 0xffff; } } - return readmembl_no_mmut(addr, addr64[0]) | - (((uint16_t) readmembl_no_mmut(addr + 1, addr64[1])) << 8); - } else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) + return readmembl_no_mmut(addr, addr64a[0]) | + (((uint16_t) readmembl_no_mmut(addr + 1, addr64a[1])) << 8); + } else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) { + mmu_perm = readlookupp[addr >> 12]; return *(uint16_t *)(readlookup2[addr >> 12] + addr); + } } if (cr0 >> 31) { - addr64[0] = mmutranslate_read(addr); - if (addr64[0] > 0xffffffffULL) + a = mmutranslate_read(addr); + addr64a[0] = (uint32_t) a; + + if (a > 0xffffffffULL) return 0xffff; } else - addr64[0] = (uint64_t) addr; + addr64a[0] = (uint64_t) addr; - addr = (uint32_t) (addr64[0] & rammask); + addr = addr64a[0] & rammask; map = read_mapping[addr >> MEM_GRANULARITY_BITS]; @@ -922,15 +958,17 @@ readmemwl(uint32_t addr) void writememwl(uint32_t addr, uint16_t val) { - uint64_t addr64[2]; mem_mapping_t *map; int i; + uint64_t a; - addr64[0] = (uint64_t) addr; - addr64[1] = (uint64_t) (addr + 1); + addr64a[0] = addr; + addr64a[1] = addr + 1; mem_logical_addr = addr; + high_page = 0; + if (addr & 1) { if (!cpu_cyrix_alignment || (addr & 7) == 7) cycles -= timing_misaligned; @@ -940,9 +978,10 @@ writememwl(uint32_t addr, uint16_t val) /* Do not translate a page that has a valid lookup, as that is by definition valid and the whole purpose of the lookup is to avoid repeat identical translations. */ if (!page_lookup[(addr + i) >> 12] || !page_lookup[(addr + i) >> 12]->write_b) { - addr64[i] = mmutranslate_write(addr + i); + a = mmutranslate_write(addr + i); + addr64a[i] = (uint32_t) a; - if (addr64[i] > 0xffffffffULL) + if (a > 0xffffffffULL) return; } } @@ -950,10 +989,11 @@ writememwl(uint32_t addr, uint16_t val) /* No need to waste precious CPU host cycles on mmutranslate's that were already done, just pass their result as a parameter to be used if needed. */ - writemembl_no_mmut(addr, addr64[0], val); - writemembl_no_mmut(addr + 1, addr64[1], val >> 8); + writemembl_no_mmut(addr, addr64a[0], val); + writemembl_no_mmut(addr + 1, addr64a[1], val >> 8); return; } else if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) { + mmu_perm = writelookupp[addr >> 12]; *(uint16_t *)(writelookup2[addr >> 12] + addr) = val; return; } @@ -961,17 +1001,19 @@ writememwl(uint32_t addr, uint16_t val) if (page_lookup[addr >> 12] && page_lookup[addr >> 12]->write_w) { page_lookup[addr >> 12]->write_w(addr, val, page_lookup[addr >> 12]); + mmu_perm = page_lookupp[addr >> 12]; return; } if (cr0 >> 31) { - addr64[0] = mmutranslate_write(addr); - if (addr64[0] > 0xffffffffULL) - return; - } else - addr64[0] = (uint64_t) addr; + a = mmutranslate_write(addr); + addr64a[0] = (uint32_t) a; - addr = (uint32_t) (addr64[0] & rammask); + if (a > 0xffffffffULL) + return; + } + + addr = addr64a[0] & rammask; map = write_mapping[addr >> MEM_GRANULARITY_BITS]; @@ -990,7 +1032,7 @@ writememwl(uint32_t addr, uint16_t val) /* Read a word from memory without MMU translation - results of previous MMU translation passed as array. */ uint16_t -readmemwl_no_mmut(uint32_t addr, uint64_t *addr64) +readmemwl_no_mmut(uint32_t addr, uint32_t *a64) { mem_mapping_t *map; @@ -1001,21 +1043,23 @@ readmemwl_no_mmut(uint32_t addr, uint64_t *addr64) cycles -= timing_misaligned; if ((addr & 0xfff) > 0xffe) { if (cr0 >> 31) { - if ((addr64[0] > 0xffffffffULL) || (addr64[1] > 0xffffffffULL)) + if (cpu_state.abrt || high_page) return 0xffff; } - return readmembl_no_mmut(addr, addr64[0]) | - (((uint16_t) readmembl_no_mmut(addr + 1, addr64[1])) << 8); - } else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) + return readmembl_no_mmut(addr, a64[0]) | + (((uint16_t) readmembl_no_mmut(addr + 1, a64[1])) << 8); + } else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) { + mmu_perm = readlookupp[addr >> 12]; return *(uint16_t *)(readlookup2[addr >> 12] + addr); + } } if (cr0 >> 31) { - if (addr64[0] > 0xffffffffULL) + if (cpu_state.abrt || high_page) return 0xffff; - addr = (uint32_t) (addr64[0] & rammask); + addr = (uint32_t) (a64[0] & rammask); } else addr &= rammask; @@ -1035,7 +1079,7 @@ readmemwl_no_mmut(uint32_t addr, uint64_t *addr64) /* Write a word to memory without MMU translation - results of previous MMU translation passed as array. */ void -writememwl_no_mmut(uint32_t addr, uint64_t *addr64, uint16_t val) +writememwl_no_mmut(uint32_t addr, uint32_t *a64, uint16_t val) { mem_mapping_t *map; @@ -1046,30 +1090,31 @@ writememwl_no_mmut(uint32_t addr, uint64_t *addr64, uint16_t val) cycles -= timing_misaligned; if ((addr & 0xfff) > 0xffe) { if (cr0 >> 31) { - if ((addr64[0] > 0xffffffffULL) || (addr64[1] > 0xffffffffULL)) + if (cpu_state.abrt || high_page) return; } - writemembl_no_mmut(addr, addr64[0], val); - writemembl_no_mmut(addr + 1, addr64[1], val >> 8); + writemembl_no_mmut(addr, a64[0], val); + writemembl_no_mmut(addr + 1, a64[1], val >> 8); return; } else if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) { + mmu_perm = writelookupp[addr >> 12]; *(uint16_t *)(writelookup2[addr >> 12] + addr) = val; return; } - } else - addr &= rammask; + } if (page_lookup[addr >> 12] && page_lookup[addr >> 12]->write_w) { + mmu_perm = page_lookupp[addr >> 12]; page_lookup[addr >> 12]->write_w(addr, val, page_lookup[addr >> 12]); return; } if (cr0 >> 31) { - if (addr64[0] > 0xffffffffULL) + if (cpu_state.abrt || high_page) return; - addr = (uint32_t) (addr64[0] & rammask); + addr = (uint32_t) (a64[0] & rammask); } else addr &= rammask; @@ -1091,47 +1136,62 @@ writememwl_no_mmut(uint32_t addr, uint64_t *addr64, uint16_t val) uint32_t readmemll(uint32_t addr) { - uint64_t addr64[4]; mem_mapping_t *map; int i; + uint64_t a = 0x0000000000000000ULL; for (i = 0; i < 4; i++) - addr64[i] = (uint64_t) (addr + i); + addr64a[i] = (uint64_t) (addr + i); mem_logical_addr = addr; + high_page = 0; + if (addr & 3) { if (!cpu_cyrix_alignment || (addr & 7) > 4) cycles -= timing_misaligned; if ((addr & 0xfff) > 0xffc) { if (cr0 >> 31) { for (i = 0; i < 4; i++) { - if ((i == 0) || !((addr + i) & 0xfff)) - addr64[i] = mmutranslate_read(addr + i); - else - addr64[i] = (addr64[i - 1] & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); + if (i == 0) { + a = mmutranslate_read(addr + i); + addr64a[i] = (uint32_t) a; + } else if (!((addr + i) & 0xfff)) { + a = mmutranslate_read(addr + 3); + addr64a[i] = (uint32_t) a; + if (!cpu_state.abrt) { + a = (a & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); + addr64a[i] = (uint32_t) a; + } + } else { + a = (a & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); + addr64a[i] = (uint32_t) a; + } - if (addr64[i] > 0xffffffffULL) + if (a > 0xffffffffULL) return 0xffff; } } /* No need to waste precious CPU host cycles on mmutranslate's that were already done, just pass their result as a parameter to be used if needed. */ - return readmemwl_no_mmut(addr, addr64) | - (((uint32_t) readmemwl_no_mmut(addr + 2, &(addr64[2]))) << 16); - } else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) + return readmemwl_no_mmut(addr, addr64a) | + (((uint32_t) readmemwl_no_mmut(addr + 2, &(addr64a[2]))) << 16); + } else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) { + mmu_perm = readlookupp[addr >> 12]; return *(uint32_t *)(readlookup2[addr >> 12] + addr); + } } if (cr0 >> 31) { - addr64[0] = mmutranslate_read(addr); - if (addr64[0] > 0xffffffffULL) - return 0xffffffff; - } else - addr64[0] = (uint64_t) addr; + a = mmutranslate_read(addr); + addr64a[0] = (uint32_t) a; - addr = (uint32_t) (addr64[0] & rammask); + if (a > 0xffffffffULL) + return 0xffffffff; + } + + addr = addr64a[0] & rammask; map = read_mapping[addr >> MEM_GRANULARITY_BITS]; @@ -1155,15 +1215,17 @@ readmemll(uint32_t addr) void writememll(uint32_t addr, uint32_t val) { - uint64_t addr64[4]; mem_mapping_t *map; int i; + uint64_t a = 0x0000000000000000ULL; for (i = 0; i < 4; i++) - addr64[i] = (uint64_t) (addr + i); + addr64a[i] = (uint64_t) (addr + i); mem_logical_addr = addr; + high_page = 0; + if (addr & 3) { if (!cpu_cyrix_alignment || (addr & 7) > 4) cycles -= timing_misaligned; @@ -1173,12 +1235,22 @@ writememll(uint32_t addr, uint32_t val) /* Do not translate a page that has a valid lookup, as that is by definition valid and the whole purpose of the lookup is to avoid repeat identical translations. */ if (!page_lookup[(addr + i) >> 12] || !page_lookup[(addr + i) >> 12]->write_b) { - if ((i == 0) || !((addr + i) & 0xfff)) - addr64[i] = mmutranslate_write(addr + i); - else - addr64[i] = (addr64[i - 1] & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); + if (i == 0) { + a = mmutranslate_write(addr + i); + addr64a[i] = (uint32_t) a; + } else if (!((addr + i) & 0xfff)) { + a = mmutranslate_write(addr + 3); + addr64a[i] = (uint32_t) a; + if (!cpu_state.abrt) { + a = (a & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); + addr64a[i] = (uint32_t) a; + } + } else { + a = (a & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); + addr64a[i] = (uint32_t) a; + } - if (addr64[i] > 0xffffffffULL) + if (a > 0xffffffffULL) return; } } @@ -1186,28 +1258,31 @@ writememll(uint32_t addr, uint32_t val) /* No need to waste precious CPU host cycles on mmutranslate's that were already done, just pass their result as a parameter to be used if needed. */ - writememwl_no_mmut(addr, &(addr64[0]), val); - writememwl_no_mmut(addr + 2, &(addr64[2]), val >> 16); + writememwl_no_mmut(addr, &(addr64a[0]), val); + writememwl_no_mmut(addr + 2, &(addr64a[2]), val >> 16); return; } else if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) { + mmu_perm = writelookupp[addr >> 12]; *(uint32_t *)(writelookup2[addr >> 12] + addr) = val; return; } } if (page_lookup[addr >> 12] && page_lookup[addr >> 12]->write_l) { + mmu_perm = page_lookupp[addr >> 12]; page_lookup[addr >> 12]->write_l(addr, val, page_lookup[addr >> 12]); return; } if (cr0 >> 31) { - addr64[0] = mmutranslate_write(addr); - if (addr64[0] > 0xffffffffULL) - return; - } else - addr64[0] = (uint64_t) addr; + a = mmutranslate_write(addr); + addr64a[0] = (uint32_t) a; - addr = (uint32_t) (addr64[0] & rammask); + if (a > 0xffffffffULL) + return; + } + + addr = addr64a[0] & rammask; map = write_mapping[addr >> MEM_GRANULARITY_BITS]; @@ -1232,8 +1307,9 @@ writememll(uint32_t addr, uint32_t val) /* Read a long from memory without MMU translation - results of previous MMU translation passed as array. */ uint32_t -readmemll_no_mmut(uint32_t addr, uint64_t *addr64) +readmemll_no_mmut(uint32_t addr, uint32_t *a64) { +#ifndef NO_MMUT mem_mapping_t *map; mem_logical_addr = addr; @@ -1243,21 +1319,23 @@ readmemll_no_mmut(uint32_t addr, uint64_t *addr64) cycles -= timing_misaligned; if ((addr & 0xfff) > 0xffc) { if (cr0 >> 31) { - if ((addr64[0] > 0xffffffffULL) || (addr64[3] > 0xffffffffULL)) + if (cpu_state.abrt || high_page) return 0xffffffff; } - return readmemwl_no_mmut(addr, addr64) | - (((uint32_t) readmemwl_no_mmut(addr + 2, &(addr64[2]))) << 16); - } else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) + return readmemwl_no_mmut(addr, a64) | + ((uint32_t) (readmemwl_no_mmut(addr + 2, &(a64[2]))) << 16); + } else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) { + mmu_perm = readlookupp[addr >> 12]; return *(uint32_t *)(readlookup2[addr >> 12] + addr); + } } if (cr0 >> 31) { - if (addr64[0] > 0xffffffffULL) + if (cpu_state.abrt || high_page) return 0xffffffff; - addr = (uint32_t) (addr64[0] & rammask); + addr = (uint32_t) (a64[0] & rammask); } else addr &= rammask; @@ -1277,13 +1355,17 @@ readmemll_no_mmut(uint32_t addr, uint64_t *addr64) ((uint32_t) (map->read_b(addr + 3, map->p)) << 24); return 0xffffffff; +#else + return readmemll(addr); +#endif } /* Write a long to memory without MMU translation - results of previous MMU translation passed as array. */ void -writememll_no_mmut(uint32_t addr, uint64_t *addr64, uint32_t val) +writememll_no_mmut(uint32_t addr, uint32_t *a64, uint32_t val) { +#ifndef NO_MMUT mem_mapping_t *map; mem_logical_addr = addr; @@ -1293,29 +1375,31 @@ writememll_no_mmut(uint32_t addr, uint64_t *addr64, uint32_t val) cycles -= timing_misaligned; if ((addr & 0xfff) > 0xffc) { if (cr0 >> 31) { - if ((addr64[0] > 0xffffffffULL) || (addr64[3] > 0xffffffffULL)) + if (cpu_state.abrt || high_page) return; } - writememwl_no_mmut(addr, &(addr64[0]), val); - writememwl_no_mmut(addr + 2, &(addr64[2]), val >> 16); + writememwl_no_mmut(addr, &(a64[0]), val); + writememwl_no_mmut(addr + 2, &(a64[2]), val >> 16); return; } else if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) { + mmu_perm = writelookupp[addr >> 12]; *(uint32_t *)(writelookup2[addr >> 12] + addr) = val; return; } } if (page_lookup[addr >> 12] && page_lookup[addr >> 12]->write_l) { + mmu_perm = page_lookupp[addr >> 12]; page_lookup[addr >> 12]->write_l(addr, val, page_lookup[addr >> 12]); return; } if (cr0 >> 31) { - if (addr64[0] > 0xffffffffULL) + if (cpu_state.abrt || high_page) return; - addr = (uint32_t) (addr64[0] & rammask); + addr = (uint32_t) (a64[0] & rammask); } else addr &= rammask; @@ -1337,52 +1421,70 @@ writememll_no_mmut(uint32_t addr, uint64_t *addr64, uint32_t val) map->write_b(addr + 3, val >> 24, map->p); return; } +#else + writememll(addr, val); +#endif } uint64_t readmemql(uint32_t addr) { - uint64_t addr64[8]; mem_mapping_t *map; - int i, wrap_i = 1; + int i; + uint64_t a = 0x0000000000000000ULL; for (i = 0; i < 8; i++) - addr64[i] = (uint64_t) (addr + i); + addr64a[i] = (uint64_t) (addr + i); mem_logical_addr = addr; + high_page = 0; + if (addr & 7) { cycles -= timing_misaligned; if ((addr & 0xfff) > 0xff8) { if (cr0 >> 31) { for (i = 0; i < 8; i++) { - if ((i == 0) || !((addr + i) & 0xfff)) - addr64[i] = mmutranslate_read(addr + i); - else - addr64[i] = (addr64[wrap_i] & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); + if (i == 0) { + a = mmutranslate_read(addr + i); + addr64a[i] = (uint32_t) a; + } else if (!((addr + i) & 0xfff)) { + a = mmutranslate_read(addr + 7); + addr64a[i] = (uint32_t) a; + if (!cpu_state.abrt) { + a = (a & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); + addr64a[i] = (uint32_t) a; + } + } else { + a = (a & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); + addr64a[i] = (uint32_t) a; + } - if (addr64[i] > 0xffffffffULL) + if (a > 0xffffffffULL) return 0xffff; } } /* No need to waste precious CPU host cycles on mmutranslate's that were already done, just pass their result as a parameter to be used if needed. */ - return readmemll_no_mmut(addr, addr64) | - (((uint64_t) readmemll_no_mmut(addr + 4, &(addr64[4]))) << 32); - } else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) + return readmemll_no_mmut(addr, addr64a) | + (((uint64_t) readmemll_no_mmut(addr + 4, &(addr64a[4]))) << 32); + } else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) { + mmu_perm = readlookupp[addr >> 12]; return *(uint64_t *)(readlookup2[addr >> 12] + addr); + } } if (cr0 >> 31) { - addr64[0] = mmutranslate_read(addr); - if (addr64[0] > 0xffffffffULL) - return 0xffffffffffffffffULL; - } else - addr64[0] = (uint64_t) addr; + a = mmutranslate_read(addr); + addr64a[0] = (uint32_t) a; - addr = (uint32_t) (addr64[0] & rammask); + if (a > 0xffffffffULL) + return 0xffffffffffffffffULL; + } + + addr = addr64a[0] & rammask; map = read_mapping[addr >> MEM_GRANULARITY_BITS]; if (map && map->read_l) @@ -1395,15 +1497,17 @@ readmemql(uint32_t addr) void writememql(uint32_t addr, uint64_t val) { - uint64_t addr64[8]; mem_mapping_t *map; int i; + uint64_t a = 0x0000000000000000ULL; for (i = 0; i < 8; i++) - addr64[i] = (uint64_t) (addr + i); + addr64a[i] = (uint64_t) (addr + i); mem_logical_addr = addr; + high_page = 0; + if (addr & 7) { cycles -= timing_misaligned; if ((addr & 0xfff) > 0xff8) { @@ -1412,12 +1516,22 @@ writememql(uint32_t addr, uint64_t val) /* Do not translate a page that has a valid lookup, as that is by definition valid and the whole purpose of the lookup is to avoid repeat identical translations. */ if (!page_lookup[(addr + i) >> 12] || !page_lookup[(addr + i) >> 12]->write_b) { - if ((i == 0) || !((addr + i) & 0xfff)) - addr64[i] = mmutranslate_write(addr + i); - else - addr64[i] = (addr64[i - 1] & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); + if (i == 0) { + a = mmutranslate_write(addr + i); + addr64a[i] = (uint32_t) a; + } else if (!((addr + i) & 0xfff)) { + a = mmutranslate_write(addr + 7); + addr64a[i] = (uint32_t) a; + if (!cpu_state.abrt) { + a = (a & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); + addr64a[i] = (uint32_t) a; + } + } else { + a = (a & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); + addr64a[i] = (uint32_t) a; + } - if (addr64[i] > 0xffffffffULL) + if (addr64a[i] > 0xffffffffULL) return; } } @@ -1425,29 +1539,30 @@ writememql(uint32_t addr, uint64_t val) /* No need to waste precious CPU host cycles on mmutranslate's that were already done, just pass their result as a parameter to be used if needed. */ - writememll_no_mmut(addr, &(addr64[0]), val); - writememll_no_mmut(addr + 4, &(addr64[4]), val >> 32); + writememll_no_mmut(addr, addr64a, val); + writememll_no_mmut(addr + 4, &(addr64a[4]), val >> 32); return; } else if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) { + mmu_perm = writelookupp[addr >> 12]; *(uint64_t *)(writelookup2[addr >> 12] + addr) = val; return; } } if (page_lookup[addr >> 12] && page_lookup[addr >> 12]->write_l) { + mmu_perm = page_lookupp[addr >> 12]; page_lookup[addr >> 12]->write_l(addr, val, page_lookup[addr >> 12]); page_lookup[addr >> 12]->write_l(addr + 4, val >> 32, page_lookup[addr >> 12]); return; } if (cr0 >> 31) { - addr64[0] = mmutranslate_write(addr); - if (addr64[0] > 0xffffffffULL) + addr64a[0] = mmutranslate_write(addr); + if (addr64a[0] > 0xffffffffULL) return; - } else - addr64[0] = (uint64_t) addr; + } - addr = (uint32_t) (addr64[0] & rammask); + addr = addr64a[0] & rammask; map = write_mapping[addr >> MEM_GRANULARITY_BITS]; @@ -1478,28 +1593,54 @@ writememql(uint32_t addr, uint64_t val) void -do_mmutranslate(uint32_t addr, uint64_t *addr64, int num, int write) +do_mmutranslate(uint32_t addr, uint32_t *a64, int num, int write) { int i, cond = 1; + uint32_t old_addr = addr; + uint64_t a = 0x0000000000000000ULL; + + for (i = 0; i < num; i++) + a64[i] = (uint64_t) addr; for (i = 0; i < num; i++) { - addr64[i] = (uint64_t) addr; - if (cr0 >> 31) { if (write && ((i == 0) || !(addr & 0xfff))) cond = (!page_lookup[addr >> 12] || !page_lookup[addr >> 12]->write_b); if (cond) { + /* If we have encountered at least one page fault, mark all subsequent addresses as + having page faulted, prevents false negatives in readmem*l_no_mmut. */ + if ((i > 0) && cpu_state.abrt && !high_page) + a64[i] = a64[i - 1]; /* If we are on the same page, there is no need to translate again, as we can just reuse the previous result. */ - if ((i == 0) || !(addr & 0xfff)) { - addr64[i] = mmutranslatereal(addr, write); + else if (i == 0) { + a = mmutranslatereal(addr, write); + a64[i] = (uint32_t) a; - if (addr64[i] > 0xffffffffULL) - return; - } else - addr64[i] = (addr64[i - 1] & ~0xfffLL) | ((uint64_t) (addr & 0xfff)); - } + high_page = high_page || (!cpu_state.abrt && (a > 0xffffffffULL)); + + if ((a <= 0xffffffffULL) && pages[addr >> 12].write_b) + write ? addwritelookup(addr, a64[i]) : addreadlookup(addr, a64[i]); + } else if (!(addr & 0xfff)) { + a = mmutranslatereal(old_addr + (num - 1), write); + a64[i] = (uint32_t) a; + + high_page = high_page || (!cpu_state.abrt && (a64[i] > 0xffffffffULL)); + + if (!cpu_state.abrt) { + a = (a & 0xfffffffffffff000ULL) | ((uint64_t) (addr & 0xfff)); + a64[i] = (uint32_t) a; + } + + if ((a <= 0xffffffffULL) && pages[addr >> 12].write_b) + write ? addwritelookup(addr, a64[i]) : addreadlookup(addr, a64[i]); + } else { + a = (a & 0xfffffffffffff000ULL) | ((uint64_t) (addr & 0xfff)); + a64[i] = (uint32_t) a; + } + } else + mmu_perm = page_lookupp[addr >> 12]; } addr++; @@ -2660,6 +2801,7 @@ mem_reset(void) } memset(page_lookup, 0x00, (1 << 20) * sizeof(page_t *)); + memset(page_lookupp, 0x04, (1 << 20) * sizeof(uint8_t)); memset(pages, 0x00, pages_sz*sizeof(page_t)); @@ -2798,8 +2940,11 @@ mem_init(void) /* Allocate the lookup tables. */ page_lookup = (page_t **)malloc((1<<20)*sizeof(page_t *)); + page_lookupp = (uint8_t *)malloc((1<<20)*sizeof(uint8_t)); readlookup2 = malloc((1<<20)*sizeof(uintptr_t)); + readlookupp = malloc((1<<20)*sizeof(uint8_t)); writelookup2 = malloc((1<<20)*sizeof(uintptr_t)); + writelookupp = malloc((1<<20)*sizeof(uint8_t)); } diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 0a5a6db30..1c9245198 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -616,7 +616,7 @@ MAINOBJ := 86box.o config.o random.o timer.o io.o acpi.o apm.o dma.o ddma.o \ MEMOBJ := catalyst_flash.o i2c_eeprom.o intel_flash.o mem.o rom.o smram.o spd.o sst_flash.o -CPUOBJ := cpu.o cpu_table.o \ +CPUOBJ := cpu.o cpu_table.o fpu.o x86.o \ 808x.o 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o $(CGTOBJ) \ x86seg.o x87.o x87_timings.o \ $(DYNARECOBJ) @@ -876,9 +876,9 @@ all: $(PROG).exe $(PROG).exe: $(OBJ) 86Box.res @echo Linking $(PROG).exe .. @$(CC) $(LDFLAGS) -o $(PROG).exe $(OBJ) 86Box.res $(LIBS) -pipe -#ifneq ($(DEBUG), y) -# @$(STRIP) $(PROG).exe -#endif +ifneq ($(DEBUG), y) + @$(STRIP) $(PROG).exe +endif pcap_if.res: pcap_if.rc @echo Processing $< From 59906638818c087fac897175ed37e98fc410f6ae Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 10 Apr 2021 07:22:49 +0200 Subject: [PATCH 04/25] Keyboard reset fixes and the two files I forgot in the previous commit. --- src/cpu/fpu.c | 101 +++++++++++++ src/cpu/x86.c | 315 +++++++++++++++++++++++++++++++++++++++ src/device/keyboard_at.c | 3 +- 3 files changed, 418 insertions(+), 1 deletion(-) create mode 100644 src/cpu/fpu.c create mode 100644 src/cpu/x86.c diff --git a/src/cpu/fpu.c b/src/cpu/fpu.c new file mode 100644 index 000000000..2d74b256a --- /dev/null +++ b/src/cpu/fpu.c @@ -0,0 +1,101 @@ +/* + * 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. + * + * FPU type handler. + * + * Authors: Sarah Walker, + * Miran Grca, + * + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. + */ +#include +#include +#include +#include +#include +#include + +#define HAVE_STDARG_H +#include <86box/86box.h> +#include "cpu.h" + + +#ifdef ENABLE_FPU_LOG +int fpu_do_log = ENABLE_FPU_LOG; + + +void +fpu_log(const char *fmt, ...) +{ + va_list ap; + + if (fpu_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define fpu_log(fmt, ...) +#endif + + +int +fpu_get_type(const cpu_family_t *cpu_family, int cpu, const char *internal_name) +{ + const CPU *cpu_s = &cpu_family->cpus[cpu]; + const FPU *fpus = cpu_s->fpus; + int fpu_type = fpus[0].type; + int c = 0; + + while (fpus[c].internal_name) { + if (!strcmp(internal_name, fpus[c].internal_name)) + fpu_type = fpus[c].type; + c++; + } + + return fpu_type; +} + + +const char * +fpu_get_internal_name(const cpu_family_t *cpu_family, int cpu, int type) +{ + const CPU *cpu_s = &cpu_family->cpus[cpu]; + const FPU *fpus = cpu_s->fpus; + int c = 0; + + while (fpus[c].internal_name) { + if (fpus[c].type == type) + return fpus[c].internal_name; + c++; + } + + return fpus[0].internal_name; +} + + +const char * +fpu_get_name_from_index(const cpu_family_t *cpu_family, int cpu, int c) +{ + const CPU *cpu_s = &cpu_family->cpus[cpu]; + const FPU *fpus = cpu_s->fpus; + + return fpus[c].name; +} + + +int +fpu_get_type_from_index(const cpu_family_t *cpu_family, int cpu, int c) +{ + const CPU *cpu_s = &cpu_family->cpus[cpu]; + const FPU *fpus = cpu_s->fpus; + + return fpus[c].type; +} diff --git a/src/cpu/x86.c b/src/cpu/x86.c new file mode 100644 index 000000000..321ebedda --- /dev/null +++ b/src/cpu/x86.c @@ -0,0 +1,315 @@ +/* + * 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. + * + * Functions common to all emulated x86 CPU's. + * + * Authors: Andrew Jenner, + * Miran Grca, + * + * Copyright 2015-2020 Andrew Jenner. + * Copyright 2016-2020 Miran Grca. + */ +#include +#include +#include +#include +#include +#include + +#define HAVE_STDARG_H +#include <86box/86box.h> +#include "cpu.h" +#include "x86.h" +#include <86box/machine.h> +#include <86box/io.h> +#include <86box/mem.h> +#include <86box/rom.h> +#include <86box/nmi.h> +#include <86box/pic.h> +#include <86box/ppi.h> +#include <86box/timer.h> + +/* The opcode of the instruction currently being executed. */ +uint8_t opcode; + +/* The tables to speed up the setting of the Z, N, and P cpu_state.flags. */ +uint8_t znptable8[256]; +uint16_t znptable16[65536]; + +/* A 16-bit zero, needed because some speed-up arrays contain pointers to it. */ +uint16_t zero = 0; + +/* MOD and R/M stuff. */ +uint16_t *mod1add[2][8]; +uint32_t *mod1seg[8]; +uint32_t rmdat; + +/* XT CPU multiplier. */ +uint64_t xt_cpu_multi; + +/* Variables for handling the non-maskable interrupts. */ +int nmi = 0, nmi_auto_clear = 0; + +/* Was the CPU ever reset? */ +int x86_was_reset = 0; + +/* Is the TRAP flag on? */ +int trap = 0; + +/* The current effective address's segment. */ +uint32_t easeg; + + +#ifdef ENABLE_X86_LOG +void dumpregs(int); + +int x86_do_log = ENABLE_X86_LOG; +int indump = 0; + + +static void +x808x_log(const char *fmt, ...) +{ + va_list ap; + + if (x808x_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} + + +void +dumpregs(int force) +{ + int c; + char *seg_names[4] = { "ES", "CS", "SS", "DS" }; + + /* Only dump when needed, and only once.. */ + if (indump || (!force && !dump_on_exit)) + return; + + x808x_log("EIP=%08X CS=%04X DS=%04X ES=%04X SS=%04X FLAGS=%04X\n", + cpu_state.pc, CS, DS, ES, SS, cpu_state.flags); + x808x_log("Old CS:EIP: %04X:%08X; %i ins\n", oldcs, cpu_state.oldpc, ins); + for (c = 0; c < 4; c++) { + x808x_log("%s : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n", + seg_names[c], _opseg[c]->base, _opseg[c]->limit, + _opseg[c]->access, _opseg[c]->limit_low, _opseg[c]->limit_high); + } + if (is386) { + x808x_log("FS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n", + seg_fs, cpu_state.seg_fs.limit, cpu_state.seg_fs.access, cpu_state.seg_fs.limit_low, cpu_state.seg_fs.limit_high); + x808x_log("GS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n", + gs, cpu_state.seg_gs.limit, cpu_state.seg_gs.access, cpu_state.seg_gs.limit_low, cpu_state.seg_gs.limit_high); + x808x_log("GDT : base=%06X limit=%04X\n", gdt.base, gdt.limit); + x808x_log("LDT : base=%06X limit=%04X\n", ldt.base, ldt.limit); + x808x_log("IDT : base=%06X limit=%04X\n", idt.base, idt.limit); + x808x_log("TR : base=%06X limit=%04X\n", tr.base, tr.limit); + x808x_log("386 in %s mode: %i-bit data, %-i-bit stack\n", + (msw & 1) ? ((cpu_state.eflags & VM_FLAG) ? "V86" : "protected") : "real", + (use32) ? 32 : 16, (stack32) ? 32 : 16); + x808x_log("CR0=%08X CR2=%08X CR3=%08X CR4=%08x\n", cr0, cr2, cr3, cr4); + x808x_log("EAX=%08X EBX=%08X ECX=%08X EDX=%08X\nEDI=%08X ESI=%08X EBP=%08X ESP=%08X\n", + EAX, EBX, ECX, EDX, EDI, ESI, EBP, ESP); + } else { + x808x_log("808x/286 in %s mode\n", (msw & 1) ? "protected" : "real"); + x808x_log("AX=%04X BX=%04X CX=%04X DX=%04X DI=%04X SI=%04X BP=%04X SP=%04X\n", + AX, BX, CX, DX, DI, SI, BP, SP); + } + x808x_log("Entries in readlookup : %i writelookup : %i\n", readlnum, writelnum); + x87_dumpregs(); + indump = 0; +} +#else +#define x808x_log(fmt, ...) +#endif + + +/* Preparation of the various arrays needed to speed up the MOD and R/M work. */ +static void +makemod1table(void) +{ + mod1add[0][0] = &BX; + mod1add[0][1] = &BX; + mod1add[0][2] = &BP; + mod1add[0][3] = &BP; + mod1add[0][4] = &SI; + mod1add[0][5] = &DI; + mod1add[0][6] = &BP; + mod1add[0][7] = &BX; + mod1add[1][0] = &SI; + mod1add[1][1] = &DI; + mod1add[1][2] = &SI; + mod1add[1][3] = &DI; + mod1add[1][4] = &zero; + mod1add[1][5] = &zero; + mod1add[1][6] = &zero; + mod1add[1][7] = &zero; + mod1seg[0] = &ds; + mod1seg[1] = &ds; + mod1seg[2] = &ss; + mod1seg[3] = &ss; + mod1seg[4] = &ds; + mod1seg[5] = &ds; + mod1seg[6] = &ss; + mod1seg[7] = &ds; +} + + +/* Prepare the ZNP table needed to speed up the setting of the Z, N, and P cpu_state.flags. */ +static void +makeznptable(void) +{ + int c, d, e; + for (c = 0; c < 256; c++) { + d = 0; + for (e = 0; e < 8; e++) { + if (c & (1 << e)) + d++; + } + if (d & 1) + znptable8[c] = 0; + else + znptable8[c] = P_FLAG; +#ifdef ENABLE_808X_LOG + if (c == 0xb1) + x808x_log("znp8 b1 = %i %02X\n", d, znptable8[c]); +#endif + if (!c) + znptable8[c] |= Z_FLAG; + if (c & 0x80) + znptable8[c] |= N_FLAG; + } + + for (c = 0; c < 65536; c++) { + d = 0; + for (e = 0; e < 8; e++) { + if (c & (1 << e)) + d++; + } + if (d & 1) + znptable16[c] = 0; + else + znptable16[c] = P_FLAG; +#ifdef ENABLE_808X_LOG + if (c == 0xb1) + x808x_log("znp16 b1 = %i %02X\n", d, znptable16[c]); + if (c == 0x65b1) + x808x_log("znp16 65b1 = %i %02X\n", d, znptable16[c]); +#endif + if (!c) + znptable16[c] |= Z_FLAG; + if (c & 0x8000) + znptable16[c] |= N_FLAG; + } +} + + +/* Common reset function. */ +static void +reset_common(int hard) +{ + /* Make sure to gracefully leave SMM. */ + if (in_smm) + leave_smm(); + +#ifdef ENABLE_808X_LOG + if (hard) + x808x_log("x86 reset\n"); +#endif + + use32 = 0; + cpu_cur_status = 0; + stack32 = 0; + msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); + msw = 0; + if (hascache) + cr0 = 1 << 30; + else + cr0 = 0; + cpu_cache_int_enabled = 0; + cpu_update_waitstates(); + cr4 = 0; + cpu_state.eflags = 0; + cgate32 = 0; + if (is286) { + if (AT) { + loadcs(0xF000); + cpu_state.pc = 0xFFF0; + rammask = cpu_16bitbus ? 0xFFFFFF : 0xFFFFFFFF; + } else { + loadcs(0xFFFF); + cpu_state.pc = 0; + rammask = 0xfffff; + } + } + idt.base = 0; + idt.limit = is386 ? 0x03FF : 0xFFFF; + cpu_state.flags = 2; + trap = 0; + + EAX = EBX = ECX = EDX = ESI = EDI = EBP = ESP = 0; + + if (hard) { + makeznptable(); + resetreadlookup(); + makemod1table(); + cpu_set_edx(); + mmu_perm = 4; + } + x86seg_reset(); +#ifdef USE_DYNAREC + if (hard) + codegen_reset(); +#endif + if (!hard) + flushmmucache(); + x86_was_reset = 1; + cpu_alt_reset = 0; + + cpu_ven_reset(); + + in_smm = smi_latched = 0; + smi_line = smm_in_hlt = 0; + smi_block = 0; + + if (hard) { + smbase = is_am486 ? 0x00060000 : 0x00030000; + ppi_reset(); + } + in_sys = 0; + + shadowbios = shadowbios_write = 0; + alt_access = cpu_end_block_after_ins = 0; + + if (!is286) + reset_808x(hard); +} + + +/* Hard reset. */ +void +resetx86(void) +{ + reset_common(1); + + soft_reset_mask = 0; +} + + +/* Soft reset. */ +void +softresetx86(void) +{ + if (soft_reset_mask) + return; + + reset_common(0); +} diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index 143b0bb60..d2126f299 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -1059,8 +1059,9 @@ write_output(atkbd_t *dev, uint8_t val) if ((dev->output_port ^ val) & 0x01) { /*Reset*/ if (! (val & 0x01)) { /* Pin 0 selected. */ - resetx86(); /*Pulse reset!*/ + softresetx86(); /*Pulse reset!*/ cpu_set_edx(); + smbase = is_am486 ? 0x00060000 : 0x00030000; } } /* Mask off the A20 stuff because we use mem_a20_key directly for that. */ From b931e81485a9f84f4e0b89e402ee4fadf1cb31ff Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 10 Apr 2021 07:23:36 +0200 Subject: [PATCH 05/25] Fixed a PIT bug (reported by qeggers). --- src/pit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pit.c b/src/pit.c index e9f25237b..9646097ec 100644 --- a/src/pit.c +++ b/src/pit.c @@ -647,7 +647,7 @@ pit_read(uint16_t addr, void *priv) break; case 3: case 0x83: - if (ctr->wm & 0x80) + if (ctr->rm & 0x80) ret = ~(ctr->l & 0xff); else ret = count >> ((ctr->rm & 0x80) ? 8 : 0); From b0bff5007ce268f696792b00321495b65cd30c9c Mon Sep 17 00:00:00 2001 From: nerd73 Date: Fri, 9 Apr 2021 23:46:47 -0600 Subject: [PATCH 06/25] TMC PAT54PV supports 50 mhz FSB speed --- src/machine/machine_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 3b0667b6f..6cdc5af37 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -285,7 +285,7 @@ const machine_t machines[] = { { "[i430FX] PC Partner MB500N", "mb500n", MACHINE_TYPE_SOCKET5, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3380, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_IDE_DUAL, 8192, 131072, 8192, 127, machine_at_mb500n_init, NULL }, /* OPTi 596/597 */ - { "[OPTi 597] TMC PAT54PV", "pat54pv", MACHINE_TYPE_SOCKET5, CPU_PKG_SOCKET5_7, CPU_BLOCK(CPU_K5, CPU_5K86), 60000000, 66666667, 3520, 3520, 1.5, 1.5, MACHINE_VLB, 2048, 65536, 2048, 127, machine_at_pat54pv_init, NULL }, + { "[OPTi 597] TMC PAT54PV", "pat54pv", MACHINE_TYPE_SOCKET5, CPU_PKG_SOCKET5_7, CPU_BLOCK(CPU_K5, CPU_5K86), 50000000, 66666667, 3520, 3520, 1.5, 1.5, MACHINE_VLB, 2048, 65536, 2048, 127, machine_at_pat54pv_init, NULL }, /* OPTi 596/597/822 */ { "[OPTi 597] Shuttle HOT-543", "hot543", MACHINE_TYPE_SOCKET5, CPU_PKG_SOCKET5_7, 0, 60000000, 66666667, 3520, 3520, 1.5, 1.5, MACHINE_PCI | MACHINE_VLB, 8192, 131072, 8192, 127, machine_at_hot543_init, NULL }, From bcb2e5598edcefae54674f2a4c974f39f16826bc Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 10 Apr 2021 19:05:12 +0200 Subject: [PATCH 07/25] CPU and MMU fixes, fixes #1366 and the entire mess that is build 2900. --- src/cpu/386_common.h | 3 +++ src/cpu/x86_ops_rep.h | 24 +++++++++++++++----- src/cpu/x86_ops_string.h | 48 ++++++++++++++++++++++++++++++---------- src/include/86box/mem.h | 2 ++ src/mem/mem.c | 19 ++++++++-------- 5 files changed, 68 insertions(+), 28 deletions(-) diff --git a/src/cpu/386_common.h b/src/cpu/386_common.h index 4d182d4c0..d9201f997 100644 --- a/src/cpu/386_common.h +++ b/src/cpu/386_common.h @@ -39,6 +39,9 @@ #define do_mmut_rb(s,a,b) if (readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF) do_mmutranslate((s)+(a), b, 1, 0) #define do_mmut_rw(s,a,b) if (readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1)) do_mmutranslate((s)+(a), b, 2, 0) #define do_mmut_rl(s,a,b) if (readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3)) do_mmutranslate((s)+(a), b, 4, 0) +#define do_mmut_rb2(s,a,b) old_rl2 = readlookup2[(uint32_t)((s)+(a))>>12]; if (old_rl2==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF) do_mmutranslate((s)+(a), b, 1, 0) +#define do_mmut_rw2(s,a,b) old_rl2 = readlookup2[(uint32_t)((s)+(a))>>12]; if (old_rl2==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1)) do_mmutranslate((s)+(a), b, 2, 0) +#define do_mmut_rl2(s,a,b) old_rl2 = readlookup2[(uint32_t)((s)+(a))>>12]; if (old_rl2==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3)) do_mmutranslate((s)+(a), b, 4, 0) #define do_mmut_wb(s,a,b) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF) do_mmutranslate((s)+(a), b, 1, 1) #define do_mmut_ww(s,a,b) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1)) do_mmutranslate((s)+(a), b, 2, 1) diff --git a/src/cpu/x86_ops_rep.h b/src/cpu/x86_ops_rep.h index 4d1f0ea61..d76613151 100644 --- a/src/cpu/x86_ops_rep.h +++ b/src/cpu/x86_ops_rep.h @@ -519,14 +519,18 @@ static int opREP_CMPSB_ ## size(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); \ SEG_CHECK_READ(&cpu_state.seg_es); \ CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG); \ - high_page = 0; \ + high_page = uncached = 0; \ do_mmut_rb(cpu_state.ea_seg->base, SRC_REG, &addr64); \ if (cpu_state.abrt) return 1; \ CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG); \ - do_mmut_rb(es, DEST_REG, &addr64_2); \ + do_mmut_rb2(es, DEST_REG, &addr64_2); \ if (cpu_state.abrt) return 1; \ temp = readmemb_n(cpu_state.ea_seg->base, SRC_REG, addr64); if (cpu_state.abrt) return 1; \ + if (uncached) \ + readlookup2[(uint32_t)(es+DEST_REG)>>12] = old_rl2; \ temp2 = readmemb_n(es, DEST_REG, addr64_2); if (cpu_state.abrt) return 1; \ + if (uncached) \ + readlookup2[(uint32_t)(es+DEST_REG)>>12] = (uintptr_t) LOOKUP_INV; \ \ if (cpu_state.flags & D_FLAG) { DEST_REG--; SRC_REG--; } \ else { DEST_REG++; SRC_REG++; } \ @@ -559,14 +563,18 @@ static int opREP_CMPSW_ ## size(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); \ SEG_CHECK_READ(&cpu_state.seg_es); \ CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ - high_page = 0; \ + high_page = uncached = 0; \ do_mmut_rw(cpu_state.ea_seg->base, SRC_REG, addr64a); \ if (cpu_state.abrt) return 1; \ CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ - do_mmut_rw(es, DEST_REG, addr64a_2); \ + do_mmut_rw2(es, DEST_REG, addr64a_2); \ if (cpu_state.abrt) return 1; \ temp = readmemw_n(cpu_state.ea_seg->base, SRC_REG, addr64a); if (cpu_state.abrt) return 1; \ + if (uncached) \ + readlookup2[(uint32_t)(es+DEST_REG)>>12] = old_rl2; \ temp2 = readmemw_n(es, DEST_REG, addr64a_2); if (cpu_state.abrt) return 1; \ + if (uncached) \ + readlookup2[(uint32_t)(es+DEST_REG)>>12] = (uintptr_t) LOOKUP_INV; \ \ if (cpu_state.flags & D_FLAG) { DEST_REG -= 2; SRC_REG -= 2; } \ else { DEST_REG += 2; SRC_REG += 2; } \ @@ -599,14 +607,18 @@ static int opREP_CMPSL_ ## size(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); \ SEG_CHECK_READ(&cpu_state.seg_es); \ CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ - high_page = 0; \ + high_page = uncached = 0; \ do_mmut_rl(cpu_state.ea_seg->base, SRC_REG, addr64a); \ if (cpu_state.abrt) return 1; \ CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ - do_mmut_rl(es, DEST_REG, addr64a_2); \ + do_mmut_rl2(es, DEST_REG, addr64a_2); \ if (cpu_state.abrt) return 1; \ temp = readmeml_n(cpu_state.ea_seg->base, SRC_REG, addr64a); if (cpu_state.abrt) return 1; \ + if (uncached) \ + readlookup2[(uint32_t)(es+DEST_REG)>>12] = old_rl2; \ temp2 = readmeml_n(es, DEST_REG, addr64a_2); if (cpu_state.abrt) return 1; \ + if (uncached) \ + readlookup2[(uint32_t)(es+DEST_REG)>>12] = (uintptr_t) LOOKUP_INV; \ \ if (cpu_state.flags & D_FLAG) { DEST_REG -= 4; SRC_REG -= 4; } \ else { DEST_REG += 4; SRC_REG += 4; } \ diff --git a/src/cpu/x86_ops_string.h b/src/cpu/x86_ops_string.h index 675489aed..fbec20dd9 100644 --- a/src/cpu/x86_ops_string.h +++ b/src/cpu/x86_ops_string.h @@ -139,14 +139,18 @@ static int opCMPSB_a16(uint32_t fetchdat) addr64 = addr64_2 = 0x00000000; SEG_CHECK_READ(cpu_state.ea_seg); - high_page = 0; + high_page = uncached = 0; do_mmut_rb(cpu_state.ea_seg->base, SI, &addr64); if (cpu_state.abrt) return 1; SEG_CHECK_READ(&cpu_state.seg_es); - do_mmut_rb(es, DI, &addr64_2); + do_mmut_rb2(es, DI, &addr64_2); if (cpu_state.abrt) return 1; src = readmemb_n(cpu_state.ea_seg->base, SI, addr64); if (cpu_state.abrt) return 1; + if (uncached) + readlookup2[(uint32_t)(es+DI)>>12] = old_rl2; dst = readmemb_n(es, DI, addr64_2); if (cpu_state.abrt) return 1; + if (uncached) + readlookup2[(uint32_t)(es+DI)>>12] = (uintptr_t) LOOKUP_INV; setsub8(src, dst); if (cpu_state.flags & D_FLAG) { DI--; SI--; } else { DI++; SI++; } @@ -161,14 +165,18 @@ static int opCMPSB_a32(uint32_t fetchdat) addr64 = addr64_2 = 0x00000000; SEG_CHECK_READ(cpu_state.ea_seg); - high_page = 0; + high_page = uncached = 0; do_mmut_rb(cpu_state.ea_seg->base, ESI, &addr64); if (cpu_state.abrt) return 1; SEG_CHECK_READ(&cpu_state.seg_es); - do_mmut_rb(es, EDI, &addr64_2); + do_mmut_rb2(es, EDI, &addr64_2); if (cpu_state.abrt) return 1; src = readmemb_n(cpu_state.ea_seg->base, ESI, addr64); if (cpu_state.abrt) return 1; + if (uncached) + readlookup2[(uint32_t)(es+EDI)>>12] = old_rl2; dst = readmemb_n(es, EDI, addr64_2); if (cpu_state.abrt) return 1; + if (uncached) + readlookup2[(uint32_t)(es+EDI)>>12] = (uintptr_t) LOOKUP_INV; setsub8(src, dst); if (cpu_state.flags & D_FLAG) { EDI--; ESI--; } else { EDI++; ESI++; } @@ -185,14 +193,18 @@ static int opCMPSW_a16(uint32_t fetchdat) addr64a_2[0] = addr64a_2[1] = 0x00000000; SEG_CHECK_READ(cpu_state.ea_seg); - high_page = 0; + high_page = uncached = 0; do_mmut_rw(cpu_state.ea_seg->base, SI, addr64a); if (cpu_state.abrt) return 1; SEG_CHECK_READ(&cpu_state.seg_es); - do_mmut_rw(es, DI, addr64a_2); + do_mmut_rw2(es, DI, addr64a_2); if (cpu_state.abrt) return 1; src = readmemw_n(cpu_state.ea_seg->base, SI, addr64a); if (cpu_state.abrt) return 1; + if (uncached) + readlookup2[(uint32_t)(es+DI)>>12] = old_rl2; dst = readmemw_n(es, DI, addr64a_2); if (cpu_state.abrt) return 1; + if (uncached) + readlookup2[(uint32_t)(es+DI)>>12] = (uintptr_t) LOOKUP_INV; setsub16(src, dst); if (cpu_state.flags & D_FLAG) { DI -= 2; SI -= 2; } else { DI += 2; SI += 2; } @@ -208,14 +220,18 @@ static int opCMPSW_a32(uint32_t fetchdat) addr64a_2[0] = addr64a_2[1] = 0x00000000; SEG_CHECK_READ(cpu_state.ea_seg); - high_page = 0; + high_page = uncached = 0; do_mmut_rw(cpu_state.ea_seg->base, ESI, addr64a); if (cpu_state.abrt) return 1; SEG_CHECK_READ(&cpu_state.seg_es); - do_mmut_rw(es, EDI, addr64a_2); + do_mmut_rw2(es, EDI, addr64a_2); if (cpu_state.abrt) return 1; src = readmemw_n(cpu_state.ea_seg->base, ESI, addr64a); if (cpu_state.abrt) return 1; + if (uncached) + readlookup2[(uint32_t)(es+EDI)>>12] = old_rl2; dst = readmemw_n(es, EDI, addr64a_2); if (cpu_state.abrt) return 1; + if (uncached) + readlookup2[(uint32_t)(es+EDI)>>12] = (uintptr_t) LOOKUP_INV; setsub16(src, dst); if (cpu_state.flags & D_FLAG) { EDI -= 2; ESI -= 2; } else { EDI += 2; ESI += 2; } @@ -232,14 +248,18 @@ static int opCMPSL_a16(uint32_t fetchdat) addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; SEG_CHECK_READ(cpu_state.ea_seg); - high_page = 0; + high_page = uncached = 0; do_mmut_rl(cpu_state.ea_seg->base, SI, addr64a); if (cpu_state.abrt) return 1; SEG_CHECK_READ(&cpu_state.seg_es); - do_mmut_rl(es, DI, addr64a_2); + do_mmut_rl2(es, DI, addr64a_2); if (cpu_state.abrt) return 1; src = readmeml_n(cpu_state.ea_seg->base, SI, addr64a); if (cpu_state.abrt) return 1; + if (uncached) + readlookup2[(uint32_t)(es+DI)>>12] = old_rl2; dst = readmeml_n(es, DI, addr64a_2); if (cpu_state.abrt) return 1; + if (uncached) + readlookup2[(uint32_t)(es+DI)>>12] = (uintptr_t) LOOKUP_INV; setsub32(src, dst); if (cpu_state.flags & D_FLAG) { DI -= 4; SI -= 4; } else { DI += 4; SI += 4; } @@ -255,14 +275,18 @@ static int opCMPSL_a32(uint32_t fetchdat) addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; SEG_CHECK_READ(cpu_state.ea_seg); - high_page = 0; + high_page = uncached = 0; do_mmut_rl(cpu_state.ea_seg->base, ESI, addr64a); if (cpu_state.abrt) return 1; SEG_CHECK_READ(&cpu_state.seg_es); - do_mmut_rl(es, EDI, addr64a_2); + do_mmut_rl2(es, EDI, addr64a_2); if (cpu_state.abrt) return 1; src = readmeml_n(cpu_state.ea_seg->base, ESI, addr64a); if (cpu_state.abrt) return 1; + if (uncached) + readlookup2[(uint32_t)(es+EDI)>>12] = old_rl2; dst = readmeml_n(es, EDI, addr64a_2); if (cpu_state.abrt) return 1; + if (uncached) + readlookup2[(uint32_t)(es+EDI)>>12] = (uintptr_t) LOOKUP_INV; setsub32(src, dst); if (cpu_state.flags & D_FLAG) { EDI -= 4; ESI -= 4; } else { EDI += 4; ESI += 4; } diff --git a/src/include/86box/mem.h b/src/include/86box/mem.h index 52e1ba810..07d89c406 100644 --- a/src/include/86box/mem.h +++ b/src/include/86box/mem.h @@ -191,6 +191,8 @@ extern uint32_t biosmask, biosaddr; extern int readlookup[256]; extern uintptr_t * readlookup2; +extern uintptr_t old_rl2; +extern uint8_t uncached; extern int readlnext; extern int writelookup[256]; extern uintptr_t * writelookup2; diff --git a/src/mem/mem.c b/src/mem/mem.c index 73f89b3eb..000937341 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -82,6 +82,8 @@ uint8_t *pccache2; int readlnext; int readlookup[256]; uintptr_t *readlookup2; +uintptr_t old_rl2; +uint8_t uncached = 0; int writelnext; int writelookup[256]; uintptr_t *writelookup2; @@ -584,8 +586,11 @@ addreadlookup(uint32_t virt, uint32_t phys) if (readlookup2[virt>>12] != (uintptr_t) LOOKUP_INV) return; - if (readlookup[readlnext] != (int) 0xffffffff) + if (readlookup[readlnext] != (int) 0xffffffff) { + if ((readlookup[readlnext] == ((es + DI) >> 12)) || (readlookup[readlnext] == ((es + EDI) >> 12))) + uncached = 1; readlookup2[readlookup[readlnext]] = LOOKUP_INV; + } #if (defined __amd64__ || defined _M_X64) a = ((uint64_t)(phys & ~0xfff) - (uint64_t)(virt & ~0xfff)); @@ -1596,9 +1601,9 @@ void do_mmutranslate(uint32_t addr, uint32_t *a64, int num, int write) { int i, cond = 1; - uint32_t old_addr = addr; + uint32_t last_addr = addr + (num - 1); uint64_t a = 0x0000000000000000ULL; - + for (i = 0; i < num; i++) a64[i] = (uint64_t) addr; @@ -1619,11 +1624,8 @@ do_mmutranslate(uint32_t addr, uint32_t *a64, int num, int write) a64[i] = (uint32_t) a; high_page = high_page || (!cpu_state.abrt && (a > 0xffffffffULL)); - - if ((a <= 0xffffffffULL) && pages[addr >> 12].write_b) - write ? addwritelookup(addr, a64[i]) : addreadlookup(addr, a64[i]); } else if (!(addr & 0xfff)) { - a = mmutranslatereal(old_addr + (num - 1), write); + a = mmutranslatereal(last_addr, write); a64[i] = (uint32_t) a; high_page = high_page || (!cpu_state.abrt && (a64[i] > 0xffffffffULL)); @@ -1632,9 +1634,6 @@ do_mmutranslate(uint32_t addr, uint32_t *a64, int num, int write) a = (a & 0xfffffffffffff000ULL) | ((uint64_t) (addr & 0xfff)); a64[i] = (uint32_t) a; } - - if ((a <= 0xffffffffULL) && pages[addr >> 12].write_b) - write ? addwritelookup(addr, a64[i]) : addreadlookup(addr, a64[i]); } else { a = (a & 0xfffffffffffff000ULL) | ((uint64_t) (addr & 0xfff)); a64[i] = (uint32_t) a; From 8aae3f6163ae01b799a5224de490d7e5a35f34dc Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 10 Apr 2021 19:46:06 +0200 Subject: [PATCH 08/25] Reverted the inappropriate PIT "fix" by qeggers that actually broke PIT readouts while writing the counts (so yes, the wm was intended, not rm), fixes several machines. --- src/pit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pit.c b/src/pit.c index 9646097ec..e9f25237b 100644 --- a/src/pit.c +++ b/src/pit.c @@ -647,7 +647,7 @@ pit_read(uint16_t addr, void *priv) break; case 3: case 0x83: - if (ctr->rm & 0x80) + if (ctr->wm & 0x80) ret = ~(ctr->l & 0xff); else ret = count >> ((ctr->rm & 0x80) ? 8 : 0); From c4fd9e775333f9262240b5f1224600bc49106027 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 10 Apr 2021 19:49:07 +0200 Subject: [PATCH 09/25] Added a comment to that piece of code in pit.c to avoid future confusion. --- src/pit.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pit.c b/src/pit.c index e9f25237b..a4b865f1c 100644 --- a/src/pit.c +++ b/src/pit.c @@ -647,6 +647,8 @@ pit_read(uint16_t addr, void *priv) break; case 3: case 0x83: + /* Yes, wm is correct here - this is to ensure correct readout while the + count is being written. */ if (ctr->wm & 0x80) ret = ~(ctr->l & 0xff); else From 8175289c9d32655ce224f919631b79c9ace00d3e Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 10 Apr 2021 22:22:19 +0200 Subject: [PATCH 10/25] Am486 SMBASE is now correctly initialized to 30000, 60000 is for the Am486DXL and Am486DXL2, which we do not emulate. --- src/cpu/x86.c | 2 +- src/device/keyboard_at.c | 2 +- src/machine/machine.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cpu/x86.c b/src/cpu/x86.c index 321ebedda..70ef37701 100644 --- a/src/cpu/x86.c +++ b/src/cpu/x86.c @@ -281,7 +281,7 @@ reset_common(int hard) smi_block = 0; if (hard) { - smbase = is_am486 ? 0x00060000 : 0x00030000; + smbase = 0x00030000; ppi_reset(); } in_sys = 0; diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index d2126f299..f6b9f7be0 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -1061,7 +1061,7 @@ write_output(atkbd_t *dev, uint8_t val) /* Pin 0 selected. */ softresetx86(); /*Pulse reset!*/ cpu_set_edx(); - smbase = is_am486 ? 0x00060000 : 0x00030000; + smbase = 0x00030000; } } /* Mask off the A20 stuff because we use mem_a20_key directly for that. */ diff --git a/src/machine/machine.c b/src/machine/machine.c index 19f821419..e3869c970 100644 --- a/src/machine/machine.c +++ b/src/machine/machine.c @@ -81,7 +81,7 @@ machine_init_ex(int m) /* Reset the memory state. */ mem_reset(); - smbase = is_am486 ? 0x00060000 : 0x00030000; + smbase = 0x00030000; lpt_init(); } From 8b6f9707d58e4dac258484aa66c4b6fd92beae55 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 11 Apr 2021 07:25:08 +0200 Subject: [PATCH 11/25] More CPU fixes, and SMM now implemented on Cyrix Cx486 and Cx5x86 CPU's as well as on Intel/AMI SX, DX, and SX2 CPU's. --- src/chipset/sis_85c496.c | 13 +++++- src/cpu/386_common.c | 40 ++++++++--------- src/cpu/386_ops.h | 92 ++++++++++++++++++++++++++++++++++++++++ src/cpu/cpu.c | 24 +++++++---- src/cpu/cpu.h | 5 +-- src/cpu/x86.c | 2 +- src/cpu/x86_ops.h | 2 + src/cpu/x86_ops_cyrix.h | 34 +++++++-------- src/cpu/x86_ops_pmode.h | 2 - src/cpu/x86seg.c | 12 ++++-- src/device/keyboard_at.c | 2 +- src/machine/machine.c | 2 +- 12 files changed, 168 insertions(+), 62 deletions(-) diff --git a/src/chipset/sis_85c496.c b/src/chipset/sis_85c496.c index f309e3a36..e06dc54c5 100644 --- a/src/chipset/sis_85c496.c +++ b/src/chipset/sis_85c496.c @@ -299,7 +299,7 @@ sis_85c49x_pci_write(int func, int addr, uint8_t val, void *priv) smram_disable_all(); - if (val & 0x06) { + if (val & 0x02) { host_base = 0x00060000; ram_base = 0x000a0000; size = 0x00010000; @@ -453,6 +453,12 @@ sis_85c49x_pci_read(int func, int addr, void *priv) uint8_t ret = dev->pci_conf[addr]; switch (addr) { + case 0xa0: + ret &= 0x10; + break; + case 0xa1: + ret = 0x00; + break; case 0x82: /*Port 22h Mirror*/ ret = dev->cur_reg; break; @@ -517,6 +523,7 @@ sis_85c496_reset(void *priv) sis_85c49x_pci_write(0, 0x58, 0x00, dev); sis_85c49x_pci_write(0, 0x59, 0x00, dev); sis_85c49x_pci_write(0, 0x5a, 0x00, dev); + // sis_85c49x_pci_write(0, 0x5a, 0x06, dev); for (i = 0; i < 8; i++) sis_85c49x_pci_write(0, 0x48 + i, 0x00, dev); @@ -589,7 +596,7 @@ static void pci_add_card(PCI_ADD_NORTHBRIDGE, sis_85c49x_pci_read, sis_85c49x_pci_write, dev); - sis_85c497_isa_reset(dev); + // sis_85c497_isa_reset(dev); dev->port_92 = device_add(&port_92_device); port_92_set_period(dev->port_92, 2ULL * TIMER_USEC); @@ -609,6 +616,8 @@ static void timer_add(&dev->rmsmiblk_timer, sis_85c496_rmsmiblk_count, dev, 0); + sis_85c496_reset(dev); + return dev; } diff --git a/src/cpu/386_common.c b/src/cpu/386_common.c index 9324976af..5aa1d4b3c 100644 --- a/src/cpu/386_common.c +++ b/src/cpu/386_common.c @@ -1027,7 +1027,7 @@ enter_smm(int in_hlt) uint32_t smram_state = smbase + 0x10000; /* If it's a CPU on which SMM is not supported, do nothing. */ - if (!is_am486 && !is_pentium && !is_k5 && !is_k6 && !is_p6 && !is_cx6x86) + if (!is_am486 && !is_pentium && !is_k5 && !is_k6 && !is_p6 && !is_cxsmm) return; x386_common_log("enter_smm(): smbase = %08X\n", smbase); @@ -1066,7 +1066,7 @@ enter_smm(int in_hlt) smram_backup_all(); smram_recalc_all(0); - if (cpu_iscyrix) { + if (is_cxsmm) { if (!(cyrix.smhr & SMHR_VALID)) cyrix.smhr = (cyrix.arr[3].base + cyrix.arr[3].size) | SMHR_VALID; smram_state = cyrix.smhr & SMHR_ADDR_MASK; @@ -1074,11 +1074,11 @@ enter_smm(int in_hlt) memset(saved_state, 0x00, SMM_SAVE_STATE_MAP_SIZE * sizeof(uint32_t)); - if (cpu_iscyrix) /* Cx6x86 */ + if (is_cxsmm) /* Cx6x86 */ smram_save_state_cyrix(saved_state, in_hlt); - if (is_pentium || is_am486) /* Am486 / 5x86 / Intel P5 (Pentium) */ + else if (is_pentium || is_am486) /* Am486 / 5x86 / Intel P5 (Pentium) */ smram_save_state_p5(saved_state, in_hlt); - else if (is_k5 || is_k6) /* AMD K5 and K6 */ + else if (is_k5 || is_k6) /* AMD K5 and K6 */ smram_save_state_amd_k(saved_state, in_hlt); else if (is_p6) /* Intel P6 (Pentium Pro, Pentium II, Celeron) */ smram_save_state_p6(saved_state, in_hlt); @@ -1091,8 +1091,11 @@ enter_smm(int in_hlt) dr[7] = 0x400; - if (cpu_iscyrix) { + if (is_cxsmm) { cpu_state.pc = 0x0000; + cpl_override = 1; + cyrix_write_seg_descriptor(smram_state - 0x20, &cpu_state.seg_cs); + cpl_override = 0; cpu_state.seg_cs.seg = (cyrix.arr[3].base >> 4); cpu_state.seg_cs.base = cyrix.arr[3].base; cpu_state.seg_cs.limit = 0xffffffff; @@ -1137,15 +1140,14 @@ enter_smm(int in_hlt) cpu_state.op32 = use32; cpl_override = 1; - if (cpu_iscyrix) { + if (is_cxsmm) { writememl(0, smram_state - 0x04, saved_state[0]); writememl(0, smram_state - 0x08, saved_state[1]); writememl(0, smram_state - 0x0c, saved_state[2]); writememl(0, smram_state - 0x10, saved_state[3]); writememl(0, smram_state - 0x14, saved_state[4]); writememl(0, smram_state - 0x18, saved_state[5]); - cyrix_write_seg_descriptor(smram_state - 0x20, &cpu_state.seg_cs); - writememl(0, smram_state - 0x18, saved_state[6]); + writememl(0, smram_state - 0x24, saved_state[6]); } else { for (n = 0; n < SMM_SAVE_STATE_MAP_SIZE; n++) { smram_state -= 4; @@ -1214,13 +1216,13 @@ leave_smm(void) uint32_t smram_state = smbase + 0x10000; /* If it's a CPU on which SMM is not supported (or not implemented in 86Box), do nothing. */ - if (!is_am486 && !is_pentium && !is_k5 && !is_k6 && !is_p6 && !is_cx6x86) + if (!is_am486 && !is_pentium && !is_k5 && !is_k6 && !is_p6 && !is_cxsmm) return; memset(saved_state, 0x00, SMM_SAVE_STATE_MAP_SIZE * sizeof(uint32_t)); cpl_override = 1; - if (cpu_iscyrix) { + if (is_cxsmm) { smram_state = cyrix.smhr & SMHR_ADDR_MASK; saved_state[0] = readmeml(0, smram_state - 0x04); saved_state[1] = readmeml(0, smram_state - 0x08); @@ -1246,13 +1248,13 @@ leave_smm(void) } x386_common_log("New SMBASE: %08X (%08X)\n", saved_state[SMRAM_FIELD_P5_SMBASE_OFFSET], saved_state[66]); - if (cpu_iscyrix) /* Cx6x86 */ + if (is_cxsmm) /* Cx6x86 */ smram_restore_state_cyrix(saved_state); - else if (is_pentium) /* Intel P5 (Pentium) */ + else if (is_pentium || is_am486) /* Am486 / 5x86 / Intel P5 (Pentium) */ smram_restore_state_p5(saved_state); - else if (is_k5 || is_k6) /* AMD K5 and K6 */ + 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) */ + else if (is_p6) /* Intel P6 (Pentium Pro, Pentium II, Celeron) */ smram_restore_state_p6(saved_state); in_smm = 0; @@ -1637,7 +1639,6 @@ sysenter(uint32_t fetchdat) cpu_state.seg_cs.base = 0; cpu_state.seg_cs.limit_low = 0; cpu_state.seg_cs.limit = 0xffffffff; - cpu_state.seg_cs.limit_raw = 0x000fffff; cpu_state.seg_cs.limit_high = 0xffffffff; cpu_state.seg_cs.access = 0x9b; cpu_state.seg_cs.ar_high = 0xcf; @@ -1648,7 +1649,6 @@ sysenter(uint32_t fetchdat) cpu_state.seg_ss.base = 0; cpu_state.seg_ss.limit_low = 0; cpu_state.seg_ss.limit = 0xffffffff; - cpu_state.seg_ss.limit_raw = 0x000fffff; cpu_state.seg_ss.limit_high = 0xffffffff; cpu_state.seg_ss.access = 0x93; cpu_state.seg_ss.ar_high = 0xcf; @@ -1726,7 +1726,6 @@ sysexit(uint32_t fetchdat) cpu_state.seg_cs.base = 0; cpu_state.seg_cs.limit_low = 0; cpu_state.seg_cs.limit = 0xffffffff; - cpu_state.seg_cs.limit_raw = 0x000fffff; cpu_state.seg_cs.limit_high = 0xffffffff; cpu_state.seg_cs.access = 0xfb; cpu_state.seg_cs.ar_high = 0xcf; @@ -1737,7 +1736,6 @@ sysexit(uint32_t fetchdat) cpu_state.seg_ss.base = 0; cpu_state.seg_ss.limit_low = 0; cpu_state.seg_ss.limit = 0xffffffff; - cpu_state.seg_ss.limit_raw = 0x000fffff; cpu_state.seg_ss.limit_high = 0xffffffff; cpu_state.seg_ss.access = 0xf3; cpu_state.seg_ss.ar_high = 0xcf; @@ -1789,7 +1787,6 @@ syscall_op(uint32_t fetchdat) cpu_state.seg_cs.base = 0; cpu_state.seg_cs.limit_low = 0; cpu_state.seg_cs.limit = 0xffffffff; - cpu_state.seg_cs.limit_raw = 0x000fffff; cpu_state.seg_cs.limit_high = 0xffffffff; cpu_state.seg_cs.access = 0x9b; cpu_state.seg_cs.ar_high = 0xcf; @@ -1801,7 +1798,6 @@ syscall_op(uint32_t fetchdat) cpu_state.seg_ss.base = 0; cpu_state.seg_ss.limit_low = 0; cpu_state.seg_ss.limit = 0xffffffff; - cpu_state.seg_ss.limit_raw = 0x000fffff; cpu_state.seg_ss.limit_high = 0xffffffff; cpu_state.seg_ss.access = 0x93; cpu_state.seg_ss.ar_high = 0xcf; @@ -1852,7 +1848,6 @@ sysret(uint32_t fetchdat) cpu_state.seg_cs.base = 0; cpu_state.seg_cs.limit_low = 0; cpu_state.seg_cs.limit = 0xffffffff; - cpu_state.seg_cs.limit_raw = 0x000fffff; cpu_state.seg_cs.limit_high = 0xffffffff; cpu_state.seg_cs.access = 0xfb; cpu_state.seg_cs.ar_high = 0xcf; @@ -1864,7 +1859,6 @@ sysret(uint32_t fetchdat) cpu_state.seg_ss.base = 0; cpu_state.seg_ss.limit_low = 0; cpu_state.seg_ss.limit = 0xffffffff; - cpu_state.seg_ss.limit_raw = 0x000fffff; cpu_state.seg_ss.limit_high = 0xffffffff; cpu_state.seg_ss.access = 0xf3; cpu_state.seg_cs.ar_high = 0xcf; diff --git a/src/cpu/386_ops.h b/src/cpu/386_ops.h index acfbb8532..b12c5476f 100644 --- a/src/cpu/386_ops.h +++ b/src/cpu/386_ops.h @@ -635,6 +635,98 @@ const OpFn OP_TABLE(486_0f)[1024] = /*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, }; + +const OpFn OP_TABLE(c486_0f)[1024] = +{ + /*16-bit data, 16-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opRDSHR_a16, opWRSHR_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opSVDC_a16, opRSDC_a16, opSVLDT_a16, opRSLDT_a16, opSVTS_a16, opRSTS_a16, ILLEGAL, ILLEGAL, + +/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w, +/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16, +/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16, +/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_w_a16,opLSS_w_a16, opBTR_w_r_a16, opLFS_w_a16, opLGS_w_a16, opMOVZX_w_b_a16,opMOVZX_w_w_a16,ILLEGAL, ILLEGAL, opBA_w_a16, opBTC_w_r_a16, opBSF_w_a16, opBSR_w_a16, opMOVSX_w_b_a16,ILLEGAL, + +/*c0*/ opXADD_b_a16, opXADD_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, +/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + + /*32-bit data, 16-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opRDSHR_a16, opWRSHR_a16, opSVDC_a16, opRSDC_a16, opSVLDT_a16, opRSLDT_a16, opSVTS_a16, opRSTS_a16, ILLEGAL, ILLEGAL, + +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l, +/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16, +/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16, +/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_l_a16,opLSS_l_a16, opBTR_l_r_a16, opLFS_l_a16, opLGS_l_a16, opMOVZX_l_b_a16,opMOVZX_l_w_a16,ILLEGAL, ILLEGAL, opBA_l_a16, opBTC_l_r_a16, opBSF_l_a16, opBSR_l_a16, opMOVSX_l_b_a16,opMOVSX_l_w_a16, + +/*c0*/ opXADD_b_a16, opXADD_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, +/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + + /*16-bit data, 32-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opRDSHR_a32, opWRSHR_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opSVDC_a32, opRSDC_a32, opSVLDT_a32, opRSLDT_a32, opSVTS_a32, opRSTS_a32, ILLEGAL, ILLEGAL, + +/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w, +/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32, +/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32, +/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_w_a32,opLSS_w_a32, opBTR_w_r_a32, opLFS_w_a32, opLGS_w_a32, opMOVZX_w_b_a32,opMOVZX_w_w_a32,ILLEGAL, ILLEGAL, opBA_w_a32, opBTC_w_r_a32, opBSF_w_a32, opBSR_w_a32, opMOVSX_w_b_a32,ILLEGAL, + +/*c0*/ opXADD_b_a32, opXADD_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, +/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + + /*32-bit data, 32-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opRDSHR_a32, opWRSHR_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opSVDC_a16, opRSDC_a16, opSVLDT_a16, opRSLDT_a16, opSVTS_a16, opRSTS_a16, ILLEGAL, ILLEGAL, + +/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l, +/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32, +/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32, +/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_l_a32,opLSS_l_a32, opBTR_l_r_a32, opLFS_l_a32, opLGS_l_a32, opMOVZX_l_b_a32,opMOVZX_l_w_a32,ILLEGAL, ILLEGAL, opBA_l_a32, opBTC_l_r_a32, opBSF_l_a32, opBSR_l_a32, opMOVSX_l_b_a32,opMOVSX_l_w_a32, + +/*c0*/ opXADD_b_a32, opXADD_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, +/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +}; + const OpFn OP_TABLE(ibm486_0f)[1024] = { /*16-bit data, 16-bit addr*/ diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 4f31ab5ad..7d71744e9 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -110,7 +110,7 @@ int isa_cycles, is286, is386, is486 = 1, is486sx, is486dx, is486sx2, is486dx2, isdx4, cpu_isintel, cpu_iscyrix, hascache, isibm486, israpidcad, is_vpc, - is_am486, is_pentium, is_k5, is_k6, is_p6, is_cx6x86, hasfpu, + is_am486, is_486_org, is_pentium, is_k5, is_k6, is_p6, is_cxsmm, hasfpu, timing_rr, timing_mr, timing_mrl, timing_rm, timing_rml, timing_mm, timing_mml, timing_bt, timing_bnt, @@ -373,6 +373,8 @@ 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_486_org = (cpu_s->cpu_type == CPU_i486SX) || (cpu_s->cpu_type == CPU_i486DX) || + (cpu_s->cpu_type == CPU_Am486SX) || (cpu_s->cpu_type == CPU_Am486DX); is_am486 = !strcmp(cpu_f->manufacturer, "AMD") && (cpu_s->cpu_type >= CPU_Am486SX) && (cpu_s->cpu_type <= CPU_Am5x86); cpu_isintel = !strcmp(cpu_f->manufacturer, "Intel"); @@ -380,13 +382,13 @@ cpu_set(void) /* The 486DX2 and iDX4 have the same SMM save state table layout as Pentiums, and the WinChip datasheet claims those are Pentium-compatible as well. */ - is_pentium = (cpu_isintel && (cpu_s->cpu_type >= CPU_i486DX2) && (cpu_s->cpu_type < CPU_PENTIUMPRO)) || + is_pentium = (cpu_isintel && (cpu_s->cpu_type >= CPU_i486SX) && (cpu_s->cpu_type < CPU_PENTIUMPRO)) || !strcmp(cpu_f->manufacturer, "IDT"); is_k5 = !strcmp(cpu_f->manufacturer, "AMD") && (cpu_s->cpu_type > CPU_Am5x86); is_k6 = (cpu_s->cpu_type >= CPU_K6) && !strcmp(cpu_f->manufacturer, "AMD"); /* The Samuel 2 datasheet claims it's Celeron-compatible. */ is_p6 = (cpu_isintel && (cpu_s->cpu_type >= CPU_PENTIUMPRO)) || !strcmp(cpu_f->manufacturer, "VIA"); - is_cx6x86 = !strcmp(cpu_f->manufacturer, "Cyrix") && (cpu_s->cpu_type > CPU_Cx5x86); + is_cxsmm = !strcmp(cpu_f->manufacturer, "Cyrix") && (cpu_s->cpu_type >= CPU_Cx486S); hasfpu = (fpu_type != FPU_NONE); hascache = (cpu_s->cpu_type >= CPU_486SLC) || (cpu_s->cpu_type == CPU_IBM386SLC) || @@ -816,9 +818,9 @@ cpu_set(void) case CPU_Cx486DX2: case CPU_Cx486DX4: #ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f); + x86_setopcodes(ops_386, ops_c486_0f, dynarec_ops_386, dynarec_ops_c486_0f); #else - x86_setopcodes(ops_386, ops_486_0f); + x86_setopcodes(ops_386, ops_c486_0f); #endif timing_rr = 1; /* register dest - register src */ @@ -856,9 +858,9 @@ cpu_set(void) case CPU_Cx5x86: #ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f); + x86_setopcodes(ops_386, ops_c486_0f, dynarec_ops_386, dynarec_ops_c486_0f); #else - x86_setopcodes(ops_386, ops_486_0f); + x86_setopcodes(ops_386, ops_c486_0f); #endif timing_rr = 1; /* register dest - register src */ @@ -1027,7 +1029,6 @@ cpu_set(void) case CPU_Cx6x86MX: if (cpu_s->cpu_type == CPU_Cx6x86MX) { #ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_c6x86mx_0f, dynarec_ops_386, dynarec_ops_c6x86mx_0f); x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_686_da_a16; x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_686_da_a32; x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_686_db_a16; @@ -1049,7 +1050,8 @@ cpu_set(void) else if (cpu_s->cpu_type == CPU_Cx6x86L) x86_setopcodes(ops_386, ops_pentium_0f, dynarec_ops_386, dynarec_ops_pentium_0f); else - x86_setopcodes(ops_386, ops_c6x86_0f, dynarec_ops_386, dynarec_ops_c6x86_0f); + x86_setopcodes(ops_386, ops_c6x86mx_0f, dynarec_ops_386, dynarec_ops_c6x86mx_0f); + // x86_setopcodes(ops_386, ops_c6x86_0f, dynarec_ops_386, dynarec_ops_c6x86_0f); #else if (cpu_s->cpu_type == CPU_Cx6x86MX) x86_setopcodes(ops_386, ops_c6x86mx_0f); @@ -2935,23 +2937,27 @@ cpu_write(uint16_t addr, uint8_t val, void *priv) ccr2 = val; break; case 0xc3: /* CCR3 */ + pclog("CC3 WRITE: %02X\n", val); if ((ccr3 & CCR3_SMI_LOCK) && !in_smm) val = (val & ~(CCR3_NMI_EN)) | (ccr3 & CCR3_NMI_EN) | CCR3_SMI_LOCK; ccr3 = val; break; case 0xcd: + pclog("ARR3_24 WRITE: %02X\n", val); if (!(ccr3 & CCR3_SMI_LOCK) || in_smm) { cyrix.arr[3].base = (cyrix.arr[3].base & ~0xff000000) | (val << 24); cyrix.smhr &= ~SMHR_VALID; } break; case 0xce: + pclog("ARR3_16 WRITE: %02X\n", val); if (!(ccr3 & CCR3_SMI_LOCK) || in_smm) { cyrix.arr[3].base = (cyrix.arr[3].base & ~0x00ff0000) | (val << 16); cyrix.smhr &= ~SMHR_VALID; } break; case 0xcf: + pclog("ARR3_08 WRITE: %02X\n", val); if (!(ccr3 & CCR3_SMI_LOCK) || in_smm) { cyrix.arr[3].base = (cyrix.arr[3].base & ~0x0000f000) | ((val & 0xf0) << 8); if ((val & 0xf) == 0xf) diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 2ebd1362e..2a9996a06 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -218,8 +218,7 @@ typedef struct { uint8_t access, ar_high; int8_t checked; /*Non-zero if selector is known to be valid*/ uint16_t seg; - uint32_t base, - limit, limit_raw, + uint32_t base, limit, limit_low, limit_high; } x86seg; @@ -484,7 +483,7 @@ 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 is_am486, is_pentium, is_k5, is_k6, is_p6, is_cx6x86; +extern int is_am486, is_486_org, is_pentium, is_k5, is_k6, is_p6, is_cxsmm; extern int hascache; extern int isibm486; extern int is_rapidcad; diff --git a/src/cpu/x86.c b/src/cpu/x86.c index 70ef37701..f8e13764e 100644 --- a/src/cpu/x86.c +++ b/src/cpu/x86.c @@ -281,7 +281,7 @@ reset_common(int hard) smi_block = 0; if (hard) { - smbase = 0x00030000; + smbase = is_486_org ? 0x00060000 : 0x00030000; ppi_reset(); } in_sys = 0; diff --git a/src/cpu/x86_ops.h b/src/cpu/x86_ops.h index 1e81b386a..dc0d62782 100644 --- a/src/cpu/x86_ops.h +++ b/src/cpu/x86_ops.h @@ -79,6 +79,7 @@ extern const OpFn dynarec_ops_386[1024]; extern const OpFn dynarec_ops_386_0f[1024]; extern const OpFn dynarec_ops_486_0f[1024]; +extern const OpFn dynarec_ops_c486_0f[1024]; extern const OpFn dynarec_ops_ibm486_0f[1024]; extern const OpFn dynarec_ops_winchip_0f[1024]; @@ -176,6 +177,7 @@ extern const OpFn ops_386[1024]; extern const OpFn ops_386_0f[1024]; extern const OpFn ops_486_0f[1024]; +extern const OpFn ops_c486_0f[1024]; extern const OpFn ops_ibm486_0f[1024]; extern const OpFn ops_winchip_0f[1024]; diff --git a/src/cpu/x86_ops_cyrix.h b/src/cpu/x86_ops_cyrix.h index e6464ce84..9ca01a9b3 100644 --- a/src/cpu/x86_ops_cyrix.h +++ b/src/cpu/x86_ops_cyrix.h @@ -35,7 +35,7 @@ static void opSVDC_common(uint32_t fetchdat) } static int opSVDC_a16(uint32_t fetchdat) { - if (cpu_cur_status & CPU_STATUS_SMM) + if (in_smm) { fetch_ea_16(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); @@ -48,7 +48,7 @@ static int opSVDC_a16(uint32_t fetchdat) } static int opSVDC_a32(uint32_t fetchdat) { - if (cpu_cur_status & CPU_STATUS_SMM) + if (in_smm) { fetch_ea_32(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); @@ -86,7 +86,7 @@ static void opRSDC_common(uint32_t fetchdat) } static int opRSDC_a16(uint32_t fetchdat) { - if (cpu_cur_status & CPU_STATUS_SMM) + if (in_smm) { fetch_ea_16(fetchdat); SEG_CHECK_READ(cpu_state.ea_seg); @@ -99,7 +99,7 @@ static int opRSDC_a16(uint32_t fetchdat) } static int opRSDC_a32(uint32_t fetchdat) { - if (cpu_cur_status & CPU_STATUS_SMM) + if (in_smm) { fetch_ea_32(fetchdat); SEG_CHECK_READ(cpu_state.ea_seg); @@ -113,7 +113,7 @@ static int opRSDC_a32(uint32_t fetchdat) static int opSVLDT_a16(uint32_t fetchdat) { - if (cpu_cur_status & CPU_STATUS_SMM) + if (in_smm) { fetch_ea_16(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); @@ -127,7 +127,7 @@ static int opSVLDT_a16(uint32_t fetchdat) } static int opSVLDT_a32(uint32_t fetchdat) { - if (cpu_cur_status & CPU_STATUS_SMM) + if (in_smm) { fetch_ea_32(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); @@ -142,7 +142,7 @@ static int opSVLDT_a32(uint32_t fetchdat) static int opRSLDT_a16(uint32_t fetchdat) { - if (cpu_cur_status & CPU_STATUS_SMM) + if (in_smm) { fetch_ea_16(fetchdat); SEG_CHECK_READ(cpu_state.ea_seg); @@ -155,7 +155,7 @@ static int opRSLDT_a16(uint32_t fetchdat) } static int opRSLDT_a32(uint32_t fetchdat) { - if (cpu_cur_status & CPU_STATUS_SMM) + if (in_smm) { fetch_ea_32(fetchdat); SEG_CHECK_READ(cpu_state.ea_seg); @@ -169,7 +169,7 @@ static int opRSLDT_a32(uint32_t fetchdat) static int opSVTS_a16(uint32_t fetchdat) { - if (cpu_cur_status & CPU_STATUS_SMM) + if (in_smm) { fetch_ea_16(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); @@ -183,7 +183,7 @@ static int opSVTS_a16(uint32_t fetchdat) } static int opSVTS_a32(uint32_t fetchdat) { - if (cpu_cur_status & CPU_STATUS_SMM) + if (in_smm) { fetch_ea_32(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); @@ -198,7 +198,7 @@ static int opSVTS_a32(uint32_t fetchdat) static int opRSTS_a16(uint32_t fetchdat) { - if (cpu_cur_status & CPU_STATUS_SMM) + if (in_smm) { fetch_ea_16(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); @@ -212,7 +212,7 @@ static int opRSTS_a16(uint32_t fetchdat) } static int opRSTS_a32(uint32_t fetchdat) { - if (cpu_cur_status & CPU_STATUS_SMM) + if (in_smm) { fetch_ea_32(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); @@ -227,7 +227,7 @@ static int opRSTS_a32(uint32_t fetchdat) static int opSMINT(uint32_t fetchdat) { - if (cpu_cur_status & CPU_STATUS_SMM) + if (in_smm) fatal("opSMINT\n"); else x86illegal(); @@ -237,7 +237,7 @@ static int opSMINT(uint32_t fetchdat) static int opRDSHR_a16(uint32_t fetchdat) { - if (cpu_cur_status & CPU_STATUS_SMM) + if (in_smm) fatal("opRDSHR_a16\n"); else x86illegal(); @@ -246,7 +246,7 @@ static int opRDSHR_a16(uint32_t fetchdat) } static int opRDSHR_a32(uint32_t fetchdat) { - if (cpu_cur_status & CPU_STATUS_SMM) + if (in_smm) fatal("opRDSHR_a32\n"); else x86illegal(); @@ -256,7 +256,7 @@ static int opRDSHR_a32(uint32_t fetchdat) static int opWRSHR_a16(uint32_t fetchdat) { - if (cpu_cur_status & CPU_STATUS_SMM) + if (in_smm) fatal("opWRSHR_a16\n"); else x86illegal(); @@ -265,7 +265,7 @@ static int opWRSHR_a16(uint32_t fetchdat) } static int opWRSHR_a32(uint32_t fetchdat) { - if (cpu_cur_status & CPU_STATUS_SMM) + if (in_smm) fatal("opWRSHR_a32\n"); else x86illegal(); diff --git a/src/cpu/x86_ops_pmode.h b/src/cpu/x86_ops_pmode.h index b372da126..b031fac22 100644 --- a/src/cpu/x86_ops_pmode.h +++ b/src/cpu/x86_ops_pmode.h @@ -198,7 +198,6 @@ static int op0F00_common(uint32_t fetchdat, int ea32) granularity = readmemb(0, addr + 6) & 0x80; if (cpu_state.abrt) return 1; ldt.limit = limit; - ldt.limit_raw = limit; ldt.access = access; ldt.ar_high = ar_high; if (granularity) @@ -232,7 +231,6 @@ static int op0F00_common(uint32_t fetchdat, int ea32) if (cpu_state.abrt) return 1; tr.seg = sel; tr.limit = limit; - tr.limit_raw = limit; tr.access = access; tr.ar_high = ar_high; if (granularity) diff --git a/src/cpu/x86seg.c b/src/cpu/x86seg.c index a9c3923c8..1304f041c 100644 --- a/src/cpu/x86seg.c +++ b/src/cpu/x86seg.c @@ -227,7 +227,6 @@ void do_seg_load(x86seg *s, uint16_t *segdat) { s->limit = segdat[0] | ((segdat[3] & 0x000f) << 16); - s->limit_raw = s->limit; if (segdat[3] & 0x0080) s->limit = (s->limit << 12) | 0xfff; s->base = segdat[1] | ((segdat[2] & 0x00ff) << 16); @@ -2382,9 +2381,14 @@ taskswitch286(uint16_t seg, uint16_t *segdat, int is32) void cyrix_write_seg_descriptor(uint32_t addr, x86seg *seg) { - writememl(0, addr, (seg->limit_raw & 0xffff) | (seg->base << 16)); + uint32_t limit_raw = seg->limit; + + if (seg->ar_high & 0x80) + limit_raw >>= 12; + + writememl(0, addr, (limit_raw & 0xffff) | (seg->base << 16)); writememl(0, addr + 4, ((seg->base >> 16) & 0xff) | (seg->access << 8) | - (seg->limit_raw & 0xf0000) | (seg->ar_high << 16) | + (limit_raw & 0xf0000) | (seg->ar_high << 16) | (seg->base & 0xff000000)); } @@ -2420,4 +2424,6 @@ cyrix_load_seg_descriptor(uint32_t addr, x86seg *seg) codegen_flat_ss = 0; } } + + pclog("clsd(): NEW CS:IP = %04X:%08X (%08X)\n", CS, cpu_state.pc, cs + cpu_state.pc); } diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index f6b9f7be0..600c61bb4 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -1061,7 +1061,7 @@ write_output(atkbd_t *dev, uint8_t val) /* Pin 0 selected. */ softresetx86(); /*Pulse reset!*/ cpu_set_edx(); - smbase = 0x00030000; + smbase = is_486_org ? 0x00060000 : 0x00030000; } } /* Mask off the A20 stuff because we use mem_a20_key directly for that. */ diff --git a/src/machine/machine.c b/src/machine/machine.c index e3869c970..045e81c30 100644 --- a/src/machine/machine.c +++ b/src/machine/machine.c @@ -81,7 +81,7 @@ machine_init_ex(int m) /* Reset the memory state. */ mem_reset(); - smbase = 0x00030000; + smbase = is_486_org ? 0x00060000 : 0x00030000; lpt_init(); } From 9587a254bcb8f978e8431250b90473fb6b9b5329 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 11 Apr 2021 07:30:01 +0200 Subject: [PATCH 12/25] Removed excess logging from cpu/cpu.c. --- src/cpu/cpu.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 7d71744e9..191754d7f 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -2937,27 +2937,23 @@ cpu_write(uint16_t addr, uint8_t val, void *priv) ccr2 = val; break; case 0xc3: /* CCR3 */ - pclog("CC3 WRITE: %02X\n", val); if ((ccr3 & CCR3_SMI_LOCK) && !in_smm) val = (val & ~(CCR3_NMI_EN)) | (ccr3 & CCR3_NMI_EN) | CCR3_SMI_LOCK; ccr3 = val; break; case 0xcd: - pclog("ARR3_24 WRITE: %02X\n", val); if (!(ccr3 & CCR3_SMI_LOCK) || in_smm) { cyrix.arr[3].base = (cyrix.arr[3].base & ~0xff000000) | (val << 24); cyrix.smhr &= ~SMHR_VALID; } break; case 0xce: - pclog("ARR3_16 WRITE: %02X\n", val); if (!(ccr3 & CCR3_SMI_LOCK) || in_smm) { cyrix.arr[3].base = (cyrix.arr[3].base & ~0x00ff0000) | (val << 16); cyrix.smhr &= ~SMHR_VALID; } break; case 0xcf: - pclog("ARR3_08 WRITE: %02X\n", val); if (!(ccr3 & CCR3_SMI_LOCK) || in_smm) { cyrix.arr[3].base = (cyrix.arr[3].base & ~0x0000f000) | ((val & 0xf0) << 8); if ((val & 0xf) == 0xf) From 5223f8af3d5520dff63bc36ed6f353f0202b854f Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 11 Apr 2021 07:36:12 +0200 Subject: [PATCH 13/25] Removed x86_ops_cyrix.h from the Dev branch. --- src/cpu/386_ops.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/cpu/386_ops.h b/src/cpu/386_ops.h index b12c5476f..a66913a4f 100644 --- a/src/cpu/386_ops.h +++ b/src/cpu/386_ops.h @@ -170,9 +170,7 @@ extern void x386_dynarec_log(const char *fmt, ...); #include "x86_ops_bcd.h" #include "x86_ops_bit.h" #include "x86_ops_bitscan.h" -#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) #include "x86_ops_cyrix.h" -#endif #include "x86_ops_flag.h" #include "x86_ops_fpu.h" #include "x86_ops_inc_dec.h" From 7aac3a3d21a721f9217144914f4c47b763b27049 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 11 Apr 2021 08:30:46 +0200 Subject: [PATCH 14/25] Removed more excess logging. --- src/cpu/x86_ops_cyrix.h | 2 -- src/cpu/x86seg.c | 2 -- 2 files changed, 4 deletions(-) diff --git a/src/cpu/x86_ops_cyrix.h b/src/cpu/x86_ops_cyrix.h index 9ca01a9b3..500b119fb 100644 --- a/src/cpu/x86_ops_cyrix.h +++ b/src/cpu/x86_ops_cyrix.h @@ -29,7 +29,6 @@ static void opSVDC_common(uint32_t fetchdat) writememw(0, easeg+cpu_state.eaaddr+8, GS); break; default: - pclog("opSVDC: unknown rmdat %02x\n", rmdat); x86illegal(); } } @@ -80,7 +79,6 @@ static void opRSDC_common(uint32_t fetchdat) cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_gs); break; default: - pclog("opRSDC: unknown rmdat %02x\n", rmdat); x86illegal(); } } diff --git a/src/cpu/x86seg.c b/src/cpu/x86seg.c index 1304f041c..763ca1358 100644 --- a/src/cpu/x86seg.c +++ b/src/cpu/x86seg.c @@ -2424,6 +2424,4 @@ cyrix_load_seg_descriptor(uint32_t addr, x86seg *seg) codegen_flat_ss = 0; } } - - pclog("clsd(): NEW CS:IP = %04X:%08X (%08X)\n", CS, cpu_state.pc, cs + cpu_state.pc); } From da82b11b29e7ef2dfbd11dc1550a8c8859e914cf Mon Sep 17 00:00:00 2001 From: Panagiotis <58827426+tiseno100@users.noreply.github.com> Date: Sun, 11 Apr 2021 15:33:11 +0300 Subject: [PATCH 15/25] Few minor changes on the Intel i450KX --- src/chipset/intel_i450kx.c | 27 ++++++++------------------- src/win/86Box.rc | 2 +- 2 files changed, 9 insertions(+), 20 deletions(-) diff --git a/src/chipset/intel_i450kx.c b/src/chipset/intel_i450kx.c index f4779546c..3435dc8ae 100644 --- a/src/chipset/intel_i450kx.c +++ b/src/chipset/intel_i450kx.c @@ -66,9 +66,9 @@ i450kx_log(const char *fmt, ...) /* SMRAM */ #define SMRAM_ADDR (((dev->pb_pci_conf[0xb9] << 8) | dev->pb_pci_conf[0xb8]) << 17) -#define SMRAM_SIZE (1 << (((dev->pb_pci_conf[0xbb] >> 4) + 1) * 16)) #define SMRAM_ADDR_MC (((dev->mc_pci_conf[0xb9] << 8) | dev->mc_pci_conf[0xb8]) << 16) -#define SMRAM_SIZE_MC (1 << (((dev->mc_pci_conf[0xbb] >> 4) + 1) * 16)) +#define SMRAM_SIZE (((dev->pb_pci_conf[0xbb] >> 4) + 1) * 64) +#define SMRAM_SIZE_MC (((dev->mc_pci_conf[0xbb] >> 4) + 1) * 64) /* Miscellaneous */ #define ENABLE_SEGMENT (MEM_READ_EXTANY | MEM_WRITE_EXTANY) @@ -101,10 +101,7 @@ void i450kx_smm(uint32_t smram_addr, uint32_t smram_size, i450kx_t *dev) smram_disable_all(); if ((smram_addr != 0) && !!(dev->mc_pci_conf[0x57] & 8)) - { smram_enable(dev->smram, smram_addr, smram_addr, smram_size, !!(dev->pb_pci_conf[0x57] & 8), 1); - mem_set_mem_state_smram_ex(1, smram_addr, smram_size, 0x03); - } flushmmucache(); } @@ -263,11 +260,7 @@ pb_write(int func, int addr, uint8_t val, void *priv) case 0xb8: case 0xb9: case 0xbb: - if (addr == 0xbb) - dev->pb_pci_conf[addr] = val & 0xf0; - else - dev->pb_pci_conf[addr] = val; - + dev->pb_pci_conf[addr] = !(addr == 0xbb) ? val : (val & 0xf0); i450kx_smm(SMRAM_ADDR, SMRAM_SIZE, dev); break; @@ -324,7 +317,6 @@ mc_write(int func, int addr, uint8_t val, void *priv) case 0x58: dev->mc_pci_conf[addr] = val & 2; - mem_set_mem_state_both(0xa0000, 0x20000, (val & 2) ? ENABLE_SEGMENT : DISABLE_SEGMENT); break; case 0x59: @@ -354,8 +346,8 @@ mc_write(int func, int addr, uint8_t val, void *priv) case 0x6d: case 0x6e: case 0x6f: - dev->mc_pci_conf[addr] = ((addr & 0x0f) % 2) ? val : (val & 7); - spd_write_drbs(dev->mc_pci_conf, 0x60, 0x6f, 1); + dev->mc_pci_conf[addr] = ((addr & 0x0f) % 2) ? 0 : (val & 0x7f); + spd_write_drbs(dev->mc_pci_conf, 0x60, 0x6f, 4); break; case 0x74: @@ -447,10 +439,7 @@ mc_write(int func, int addr, uint8_t val, void *priv) case 0xb8: case 0xb9: case 0xbb: - if (addr == 0xbb) - dev->mc_pci_conf[addr] = val & 0xf0; - else - dev->mc_pci_conf[addr] = val; + dev->mc_pci_conf[addr] = !(addr == 0xbb) ? val : (val & 0xf0); i450kx_smm(SMRAM_ADDR_MC, SMRAM_SIZE_MC, dev); break; @@ -500,7 +489,7 @@ i450kx_reset(void *priv) dev->pb_pci_conf[0x05] = 4; dev->pb_pci_conf[0x06] = 0x40; dev->pb_pci_conf[0x07] = 2; - dev->pb_pci_conf[0x08] = 1; + dev->pb_pci_conf[0x08] = 2; dev->pb_pci_conf[0x0b] = 6; dev->pb_pci_conf[0x0c] = 8; dev->pb_pci_conf[0x0d] = 0x20; @@ -526,7 +515,7 @@ i450kx_reset(void *priv) dev->mc_pci_conf[0x02] = 0xc5; dev->mc_pci_conf[0x03] = 0x84; dev->mc_pci_conf[0x06] = 0x80; - dev->mc_pci_conf[0x08] = 1; + dev->mc_pci_conf[0x08] = 4; dev->mc_pci_conf[0x0b] = 5; dev->mc_pci_conf[0x49] = 0x14; dev->mc_pci_conf[0x4c] = 0x0b; diff --git a/src/win/86Box.rc b/src/win/86Box.rc index 2fc62098e..6bdf861ae 100644 --- a/src/win/86Box.rc +++ b/src/win/86Box.rc @@ -1018,7 +1018,7 @@ BEGIN IDS_2123 "Save" IDS_2124 "About 86Box" IDS_2125 "86Box v" EMU_VERSION - IDS_2126 "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, MoochMcGee, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2. See LICENSE for more information." + IDS_2126 "An emulator of old computers\n\nAuthors: Miran Grca (OBattler), Sarah Walker, Fred N. van Kempen (waltje), SA1988, MoochMcGee, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2. See LICENSE for more information." IDS_2127 "OK" IDS_2128 "Hardware not available" #ifdef _WIN32 From b6b5558aa36471f80c6472065393910d1543ea32 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 12 Apr 2021 03:42:03 +0200 Subject: [PATCH 16/25] Added the ability to size the window to a specific resolution, closes #1362; Fixed unsolicited mouse captures after a double-click in an open file dialog, fixes #1367. --- src/include/86box/resource.h | 9 +- src/include/86box/win.h | 4 + src/win/86Box.rc | 20 +++++ src/win/Makefile.mingw | 2 +- src/win/win_specify_dim.c | 157 +++++++++++++++++++++++++++++++++++ src/win/win_ui.c | 35 +++++--- 6 files changed, 213 insertions(+), 14 deletions(-) create mode 100644 src/win/win_specify_dim.c diff --git a/src/include/86box/resource.h b/src/include/86box/resource.h index 28abd983b..27f8f8d0e 100644 --- a/src/include/86box/resource.h +++ b/src/include/86box/resource.h @@ -28,6 +28,7 @@ #define DLG_STATUS 102 /* top-level dialog */ #define DLG_SND_GAIN 103 /* top-level dialog */ #define DLG_NEW_FLOPPY 104 /* top-level dialog */ +#define DLG_SPECIFY_DIM 105 /* top-level dialog */ #define DLG_CONFIG 110 /* top-level dialog */ #define DLG_CFG_MACHINE 111 /* sub-dialog of config */ #define DLG_CFG_VIDEO 112 /* sub-dialog of config */ @@ -256,7 +257,6 @@ #define IDC_COMBO_DISK_SIZE 1201 #define IDC_COMBO_RPM_MODE 1202 - /* For the DeviceConfig code, re-do later. */ #define IDC_CONFIG_BASE 1300 #define IDC_CONFIGURE_VID 1300 @@ -277,6 +277,10 @@ #define IDC_RENDER 1381 #define IDC_STATUS 1382 +#define IDC_EDIT_WIDTH 1400 /* specify main window dimensions dialog */ +#define IDC_WIDTHSPIN 1401 +#define IDC_EDIT_HEIGHT 1402 +#define IDC_HEIGHTSPIN 1403 #define IDM_ABOUT 40001 #define IDC_ABOUT_ICON 65535 @@ -308,12 +312,13 @@ #define IDM_VID_SCALE_2X 40056 #define IDM_VID_SCALE_3X 40057 #define IDM_VID_SCALE_4X 40058 -#define IDM_VID_HIDPI 40059 +#define IDM_VID_HIDPI 40059 #define IDM_VID_FULLSCREEN 40060 #define IDM_VID_FS_FULL 40061 #define IDM_VID_FS_43 40062 #define IDM_VID_FS_KEEPRATIO 40063 #define IDM_VID_FS_INT 40064 +#define IDM_VID_SPECIFY_DIM 40065 #define IDM_VID_FORCE43 40066 #define IDM_VID_OVERSCAN 40067 #define IDM_VID_INVERT 40069 diff --git a/src/include/86box/win.h b/src/include/86box/win.h index 7c642cbc2..0f0162c11 100644 --- a/src/include/86box/win.h +++ b/src/include/86box/win.h @@ -174,6 +174,10 @@ extern void SoundGainDialogCreate(HWND hwnd); extern void NewFloppyDialogCreate(HWND hwnd, int id, int part); +/* Functions in win_specify_dim.c: */ +extern void SpecifyDimensionsDialogCreate(HWND hwnd); + + /* Functions in win_settings.c: */ #define SETTINGS_PAGE_MACHINE 0 #define SETTINGS_PAGE_VIDEO 1 diff --git a/src/win/86Box.rc b/src/win/86Box.rc index 2fc62098e..cfa2275ab 100644 --- a/src/win/86Box.rc +++ b/src/win/86Box.rc @@ -71,6 +71,7 @@ BEGIN #endif END MENUITEM SEPARATOR + MENUITEM "Specify dimensions", IDM_VID_SPECIFY_DIM MENUITEM "F&orce 4:3 display ratio", IDM_VID_FORCE43 POPUP "&Window scale factor" BEGIN @@ -342,6 +343,25 @@ BEGIN #endif END +DLG_SPECIFY_DIM DIALOG DISCARDABLE 0, 0, 175, 47 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Specify Main Window Dimensions" +FONT 9, "Segoe UI" +BEGIN + LTEXT "Width:",IDT_1709,7,9,24,12 + EDITTEXT IDC_EDIT_WIDTH,33,7,45,12,ES_AUTOHSCROLL | ES_NUMBER + CONTROL "",IDC_WIDTHSPIN,"msctls_updown32",UDS_SETBUDDYINT | + UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS,76,6, + 12,12 + LTEXT "Height:",IDT_1710,97,9,24,12 + EDITTEXT IDC_EDIT_HEIGHT,123,7,45,12,ES_AUTOHSCROLL | ES_NUMBER + CONTROL "",IDC_HEIGHTSPIN,"msctls_updown32",UDS_SETBUDDYINT | + UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS,166,6, + 12,12 + DEFPUSHBUTTON "OK",IDOK,30,26,50,14 + PUSHBUTTON "Cancel",IDCANCEL,99,26,50,14 +END + DLG_CFG_MACHINE DIALOG DISCARDABLE 107, 0, 305, 200 STYLE DS_CONTROL | WS_CHILD FONT 9, "Segoe UI" diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 1c9245198..7f493d925 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -447,7 +447,7 @@ else UIOBJ := win_ui.o win_stbar.o \ win_sdl.o \ win_dialog.o win_about.o \ - win_settings.o win_devconf.o win_snd_gain.o \ + win_settings.o win_devconf.o win_snd_gain.o win_specify_dim.o \ win_new_floppy.o win_jsconf.o win_media_menu.o endif diff --git a/src/win/win_specify_dim.c b/src/win/win_specify_dim.c new file mode 100644 index 000000000..42bc4edd3 --- /dev/null +++ b/src/win/win_specify_dim.c @@ -0,0 +1,157 @@ +/* + * 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. + * + * Handle the dialog for specifying the dimensions of the main window. + * + * + * + * Authors: Miran Grca, + * + * Copyright 2016-2018 Miran Grca. + */ +#define UNICODE +#define BITMAP WINDOWS_BITMAP +#include +#include +#undef BITMAP +#include +#include +#include +#include +#include +#include +#include <86box/86box.h> +#include <86box/config.h> +#include <86box/plat.h> +#include <86box/sound.h> +#include <86box/win.h> + + +#if defined(__amd64__) || defined(__aarch64__) +static LRESULT CALLBACK +#else +static BOOL CALLBACK +#endif +SpecifyDimensionsDialogProcedure(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + HWND h, h2; + HMENU hmenu; + UDACCEL accel, accel2; + RECT r; + uint32_t temp_x = 0, temp_y = 0; + int dpi = 96; + LPTSTR lptsTemp; + char *stransi; + + switch (message) { + case WM_INITDIALOG: + GetWindowRect(hwndRender, &r); + + h = GetDlgItem(hdlg, IDC_WIDTHSPIN); + h2 = GetDlgItem(hdlg, IDC_EDIT_WIDTH); + SendMessage(h, UDM_SETBUDDY, (WPARAM)h2, 0); + SendMessage(h, UDM_SETRANGE, 0, (120 << 16) | 2048); + accel.nSec = 0; + accel.nInc = 8; + SendMessage(h, UDM_SETACCEL, 1, (LPARAM)&accel); + SendMessage(h, UDM_SETPOS, 0, r.right - r.left); + + h = GetDlgItem(hdlg, IDC_HEIGHTSPIN); + h2 = GetDlgItem(hdlg, IDC_EDIT_HEIGHT); + SendMessage(h, UDM_SETBUDDY, (WPARAM)h2, 0); + SendMessage(h, UDM_SETRANGE, 0, (120 << 16) | 2048); + accel2.nSec = 0; + accel2.nInc = 8; + SendMessage(h, UDM_SETACCEL, 1, (LPARAM)&accel2); + SendMessage(h, UDM_SETPOS, 0, r.bottom - r.top); + break; + + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDOK: + lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR)); + stransi = (char *)malloc(512); + + h = GetDlgItem(hdlg, IDC_EDIT_WIDTH); + SendMessage(h, WM_GETTEXT, 255, (LPARAM) lptsTemp); + wcstombs(stransi, lptsTemp, 512); + sscanf(stransi, "%u", &temp_x); + + h = GetDlgItem(hdlg, IDC_EDIT_HEIGHT); + SendMessage(h, WM_GETTEXT, 255, (LPARAM) lptsTemp); + wcstombs(stransi, lptsTemp, 512); + sscanf(stransi, "%u", &temp_y); + + window_remember = 1; + vid_resize = 1; + hmenu = GetMenu(hwndMain); + CheckMenuItem(hmenu, IDM_VID_RESIZE, MF_CHECKED); + + SetWindowLongPtr(hwndMain, GWL_STYLE, (WS_OVERLAPPEDWINDOW) | WS_VISIBLE); + + /* scale the screen base on DPI */ + if (dpi_scale) { + dpi = win_get_dpi(hwndMain); + temp_x = MulDiv(temp_x, dpi, 96); + temp_y = MulDiv(temp_y, dpi, 96); + } else { + temp_x = temp_x; + temp_y = temp_y; + } + + ResizeWindowByClientArea(hwndMain, temp_x, temp_y + sbar_height); + + if (mouse_capture) + ClipCursor(&r); + + CheckMenuItem(hmenu, IDM_VID_SCALE_1X + scale, MF_UNCHECKED); + CheckMenuItem(hmenu, IDM_VID_SCALE_2X, MF_CHECKED); + scale = 1; + EnableMenuItem(hmenu, IDM_VID_SCALE_1X, MF_GRAYED); + EnableMenuItem(hmenu, IDM_VID_SCALE_2X, MF_GRAYED); + EnableMenuItem(hmenu, IDM_VID_SCALE_3X, MF_GRAYED); + EnableMenuItem(hmenu, IDM_VID_SCALE_4X, MF_GRAYED); + + scrnsz_x = temp_x; + scrnsz_y = temp_y; + doresize = 1; + + CheckMenuItem(hmenu, IDM_VID_REMEMBER, MF_CHECKED); + GetWindowRect(hwndMain, &r); + window_x = r.left; + window_y = r.top; + window_w = r.right - r.left; + window_h = r.bottom - r.top; + + config_save(); + + free(stransi); + free(lptsTemp); + + EndDialog(hdlg, 0); + return TRUE; + + case IDCANCEL: + EndDialog(hdlg, 0); + return TRUE; + + default: + break; + } + break; + } + + return(FALSE); +} + + +void +SpecifyDimensionsDialogCreate(HWND hwnd) +{ + DialogBox(hinstance, (LPCTSTR)DLG_SPECIFY_DIM, hwnd, SpecifyDimensionsDialogProcedure); +} diff --git a/src/win/win_ui.c b/src/win/win_ui.c index de0dba0d8..e690a0706 100644 --- a/src/win/win_ui.c +++ b/src/win/win_ui.c @@ -61,9 +61,9 @@ HWND hwndMain, /* application main window */ HMENU menuMain; /* application main menu */ HICON hIcon[256]; /* icon data loaded from resources */ RECT oldclip; /* mouse rect */ -int sbar_height = 23; /* statusbar height */ +int sbar_height = 23; /* statusbar height */ int minimized = 0; -int infocus = 1; +int infocus = 1, button_down = 0; int rctrl_is_lalt = 0; int user_resize = 0; @@ -456,10 +456,14 @@ input_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) #endif break; + case WM_LBUTTONDOWN: + button_down |= 1; + break; + case WM_LBUTTONUP: - pclog("video_fullscreen = %i\n", video_fullscreen); - if (! video_fullscreen) + if ((button_down & 1) && !video_fullscreen) plat_mouse_capture(1); + button_down &= ~1; break; case WM_MBUTTONUP: @@ -511,12 +515,12 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; #ifdef MTR_ENABLED - case IDM_ACTION_BEGIN_TRACE: - case IDM_ACTION_END_TRACE: - case IDM_ACTION_TRACE: - tracing_on = !tracing_on; - handle_trace(hmenu, tracing_on); - break; + case IDM_ACTION_BEGIN_TRACE: + case IDM_ACTION_END_TRACE: + case IDM_ACTION_TRACE: + tracing_on = !tracing_on; + handle_trace(hmenu, tracing_on); + break; #endif case IDM_ACTION_HRESET: @@ -696,6 +700,10 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) config_save(); break; + case IDM_VID_SPECIFY_DIM: + SpecifyDimensionsDialogCreate(hwnd); + break; + case IDM_VID_FORCE43: video_toggle_option(hmenu, &force_43, IDM_VID_FORCE43); video_force_resize_set(1); @@ -1063,9 +1071,14 @@ static LRESULT CALLBACK SubWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { + case WM_LBUTTONDOWN: + button_down |= 2; + break; + case WM_LBUTTONUP: - if (! video_fullscreen) + if ((button_down & 2) && !video_fullscreen) plat_mouse_capture(1); + button_down &= ~2; break; case WM_MBUTTONUP: From 2c12f47bd72fb46e7ce3782ef1115eff9cc017cf Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 12 Apr 2021 04:57:16 +0200 Subject: [PATCH 17/25] Updated win/CMakeLists.txt. --- src/win/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/win/CMakeLists.txt b/src/win/CMakeLists.txt index dd5e7b28c..f2f995d6d 100644 --- a/src/win/CMakeLists.txt +++ b/src/win/CMakeLists.txt @@ -19,7 +19,7 @@ add_library(plat OBJECT win.c win_dynld.c win_thread.c win_cdrom.c win_keyboard.c win_crashdump.c win_midi.c win_mouse.c) add_library(ui OBJECT win_ui.c win_stbar.c win_sdl.c win_dialog.c win_about.c - win_settings.c win_devconf.c win_snd_gain.c win_new_floppy.c + win_settings.c win_devconf.c win_snd_gain.c win_specify_dim.o win_new_floppy.c win_jsconf.c win_media_menu.c 86Box.rc) if(MSVC) From 58a1939dbf35339c45797a41c4a3e89e9379f16a Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 12 Apr 2021 05:58:59 +0200 Subject: [PATCH 18/25] Improved the main window size specifying, now has an option to lock the window to the specified size, making it unresizable. --- src/config.c | 30 +++++++++++++++- src/include/86box/86box.h | 1 + src/include/86box/resource.h | 1 + src/win/86Box.rc | 10 +++--- src/win/win.c | 14 ++++---- src/win/win_specify_dim.c | 68 ++++++++++++++++++++++++------------ src/win/win_ui.c | 57 ++++++++++++++++++++++-------- 7 files changed, 132 insertions(+), 49 deletions(-) diff --git a/src/config.c b/src/config.c index ab42cca31..2b01cf8a5 100644 --- a/src/config.c +++ b/src/config.c @@ -450,7 +450,9 @@ load_general(void) char temp[512]; char *p; - vid_resize = !!config_get_int(cat, "vid_resize", 0); + vid_resize = config_get_int(cat, "vid_resize", 0); + if (vid_resize & ~3) + vid_resize &= 3; memset(temp, '\0', sizeof(temp)); p = config_get_string(cat, "vid_renderer", "default"); @@ -488,6 +490,25 @@ load_general(void) window_w = window_h = window_x = window_y = 0; } + if (vid_resize & 2) { + p = config_get_string(cat, "window_fixed_res", NULL); + if (p == NULL) + p = "120x120"; + sscanf(p, "%ix%i", &fixed_size_x, &fixed_size_y); + if (fixed_size_x < 120) + fixed_size_x = 120; + if (fixed_size_x > 2048) + fixed_size_x = 2048; + if (fixed_size_y < 120) + fixed_size_y = 120; + if (fixed_size_y > 2048) + fixed_size_y = 2048; + } else { + config_delete_var(cat, "window_fixed_res"); + + fixed_size_x = fixed_size_y = 120; + } + sound_gain = config_get_int(cat, "sound_gain", 0); confirm_reset = config_get_int(cat, "confirm_reset", 1); @@ -1720,6 +1741,7 @@ config_load(void) fpu_type = fpu_get_type(cpu_f, cpu, "none"); gfxcard = video_get_video_from_internal_name("cga"); vid_api = plat_vidapi("default"); + vid_resize = 0; time_sync = TIME_SYNC_ENABLED; hdc_current = hdc_get_from_internal_name("none"); serial_enabled[0] = 1; @@ -1857,6 +1879,12 @@ save_general(void) config_delete_var(cat, "window_coordinates"); } + if (vid_resize & 2) { + sprintf(temp, "%ix%i", fixed_size_x, fixed_size_y); + config_set_string(cat, "window_fixed_res", temp); + } else + config_delete_var(cat, "window_fixed_res"); + if (sound_gain != 0) config_set_int(cat, "sound_gain", sound_gain); else diff --git a/src/include/86box/86box.h b/src/include/86box/86box.h index 83ca91ba8..1429c698c 100644 --- a/src/include/86box/86box.h +++ b/src/include/86box/86box.h @@ -120,6 +120,7 @@ extern int enable_crashdump; /* (C) enable crash dump */ extern int is_pentium; /* TODO: Move back to cpu/cpu.h when it's figured out, how to remove that hack from the ET4000/W32p. */ +extern int fixed_size_x, fixed_size_y; #ifdef ENABLE_LOG_TOGGLES diff --git a/src/include/86box/resource.h b/src/include/86box/resource.h index 27f8f8d0e..3a029a25f 100644 --- a/src/include/86box/resource.h +++ b/src/include/86box/resource.h @@ -281,6 +281,7 @@ #define IDC_WIDTHSPIN 1401 #define IDC_EDIT_HEIGHT 1402 #define IDC_HEIGHTSPIN 1403 +#define IDC_CHECK_LOCK_SIZE 1404 #define IDM_ABOUT 40001 #define IDC_ABOUT_ICON 65535 diff --git a/src/win/86Box.rc b/src/win/86Box.rc index 215ebe0e3..da174a4fa 100644 --- a/src/win/86Box.rc +++ b/src/win/86Box.rc @@ -343,7 +343,7 @@ BEGIN #endif END -DLG_SPECIFY_DIM DIALOG DISCARDABLE 0, 0, 175, 47 +DLG_SPECIFY_DIM DIALOG DISCARDABLE 0, 0, 175, 66 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Specify Main Window Dimensions" FONT 9, "Segoe UI" @@ -358,8 +358,10 @@ BEGIN CONTROL "",IDC_HEIGHTSPIN,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS,166,6, 12,12 - DEFPUSHBUTTON "OK",IDOK,30,26,50,14 - PUSHBUTTON "Cancel",IDCANCEL,99,26,50,14 + CONTROL "Lock to this size",IDC_CHECK_LOCK_SIZE,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,26,94,10 + DEFPUSHBUTTON "OK",IDOK,30,45,50,14 + PUSHBUTTON "Cancel",IDCANCEL,99,45,50,14 END DLG_CFG_MACHINE DIALOG DISCARDABLE 107, 0, 305, 200 @@ -1038,7 +1040,7 @@ BEGIN IDS_2123 "Save" IDS_2124 "About 86Box" IDS_2125 "86Box v" EMU_VERSION - IDS_2126 "An emulator of old computers\n\nAuthors: Miran Grca (OBattler), Sarah Walker, Fred N. van Kempen (waltje), SA1988, MoochMcGee, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2. See LICENSE for more information." + IDS_2126 "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, MoochMcGee, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2. See LICENSE for more information." IDS_2127 "OK" IDS_2128 "Hardware not available" #ifdef _WIN32 diff --git a/src/win/win.c b/src/win/win.c index 901ae267c..f82bc7a3e 100644 --- a/src/win/win.c +++ b/src/win/win.c @@ -1032,7 +1032,7 @@ plat_setfullscreen(int on) plat_resize(scrnsz_x, scrnsz_y); if (vid_resize) { /* scale the screen base on DPI */ - if (window_remember) { + if (!(vid_resize & 2) && window_remember) { MoveWindow(hwndMain, window_x, window_y, window_w, window_h, TRUE); GetClientRect(hwndMain, &rect); @@ -1040,11 +1040,11 @@ plat_setfullscreen(int on) temp_y = rect.bottom - rect.top + 1 - sbar_height; } else { if (dpi_scale) { - temp_x = MulDiv(unscaled_size_x, dpi, 96); - temp_y = MulDiv(unscaled_size_y, dpi, 96); + temp_x = MulDiv((vid_resize & 2) ? fixed_size_x : unscaled_size_x, dpi, 96); + temp_y = MulDiv((vid_resize & 2) ? fixed_size_y : unscaled_size_y, dpi, 96); } else { - temp_x = unscaled_size_x; - temp_y = unscaled_size_y; + temp_x = (vid_resize & 2) ? fixed_size_x : unscaled_size_x; + temp_y = (vid_resize & 2) ? fixed_size_y : unscaled_size_y; } /* Main Window. */ @@ -1061,8 +1061,8 @@ plat_setfullscreen(int on) if (mouse_capture) ClipCursor(&rect); - scrnsz_x = unscaled_size_x; - scrnsz_y = unscaled_size_y; + scrnsz_x = (vid_resize & 2) ? fixed_size_x : unscaled_size_x; + scrnsz_y = (vid_resize & 2) ? fixed_size_y : unscaled_size_y; } } video_fullscreen &= 1; diff --git a/src/win/win_specify_dim.c b/src/win/win_specify_dim.c index 42bc4edd3..547ee93b1 100644 --- a/src/win/win_specify_dim.c +++ b/src/win/win_specify_dim.c @@ -44,7 +44,7 @@ SpecifyDimensionsDialogProcedure(HWND hdlg, UINT message, WPARAM wParam, LPARAM UDACCEL accel, accel2; RECT r; uint32_t temp_x = 0, temp_y = 0; - int dpi = 96; + int dpi = 96, lock; LPTSTR lptsTemp; char *stransi; @@ -69,6 +69,9 @@ SpecifyDimensionsDialogProcedure(HWND hdlg, UINT message, WPARAM wParam, LPARAM accel2.nInc = 8; SendMessage(h, UDM_SETACCEL, 1, (LPARAM)&accel2); SendMessage(h, UDM_SETPOS, 0, r.bottom - r.top); + + h = GetDlgItem(hdlg, IDC_CHECK_LOCK_SIZE); + SendMessage(h, BM_SETCHECK, !!(vid_resize & 2), 0); break; case WM_COMMAND: @@ -81,18 +84,33 @@ SpecifyDimensionsDialogProcedure(HWND hdlg, UINT message, WPARAM wParam, LPARAM SendMessage(h, WM_GETTEXT, 255, (LPARAM) lptsTemp); wcstombs(stransi, lptsTemp, 512); sscanf(stransi, "%u", &temp_x); + fixed_size_x = temp_x; h = GetDlgItem(hdlg, IDC_EDIT_HEIGHT); SendMessage(h, WM_GETTEXT, 255, (LPARAM) lptsTemp); wcstombs(stransi, lptsTemp, 512); sscanf(stransi, "%u", &temp_y); + fixed_size_y = temp_y; - window_remember = 1; - vid_resize = 1; + h = GetDlgItem(hdlg, IDC_CHECK_LOCK_SIZE); + lock = SendMessage(h, BM_GETCHECK, 0, 0); + + if (lock) { + vid_resize = 2; + window_remember = 0; + } else { + vid_resize = 1; + window_remember = 1; + } hmenu = GetMenu(hwndMain); - CheckMenuItem(hmenu, IDM_VID_RESIZE, MF_CHECKED); + CheckMenuItem(hmenu, IDM_VID_REMEMBER, (window_remember == 1) ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(hmenu, IDM_VID_RESIZE, (vid_resize == 1) ? MF_CHECKED : MF_UNCHECKED); + EnableMenuItem(hmenu, IDM_VID_RESIZE, (vid_resize & 2) ? MF_GRAYED : MF_ENABLED); - SetWindowLongPtr(hwndMain, GWL_STYLE, (WS_OVERLAPPEDWINDOW) | WS_VISIBLE); + if (vid_resize == 1) + SetWindowLongPtr(hwndMain, GWL_STYLE, (WS_OVERLAPPEDWINDOW) | WS_VISIBLE); + else + SetWindowLongPtr(hwndMain, GWL_STYLE, (WS_OVERLAPPEDWINDOW & ~WS_SIZEBOX & ~WS_MAXIMIZEBOX) | WS_VISIBLE); /* scale the screen base on DPI */ if (dpi_scale) { @@ -106,27 +124,31 @@ SpecifyDimensionsDialogProcedure(HWND hdlg, UINT message, WPARAM wParam, LPARAM ResizeWindowByClientArea(hwndMain, temp_x, temp_y + sbar_height); + if (vid_resize) { + CheckMenuItem(hmenu, IDM_VID_SCALE_1X + scale, MF_UNCHECKED); + CheckMenuItem(hmenu, IDM_VID_SCALE_2X, MF_CHECKED); + scale = 1; + } + EnableMenuItem(hmenu, IDM_VID_SCALE_1X, vid_resize ? MF_GRAYED : MF_ENABLED); + EnableMenuItem(hmenu, IDM_VID_SCALE_2X, vid_resize ? MF_GRAYED : MF_ENABLED); + EnableMenuItem(hmenu, IDM_VID_SCALE_3X, vid_resize ? MF_GRAYED : MF_ENABLED); + EnableMenuItem(hmenu, IDM_VID_SCALE_4X, vid_resize ? MF_GRAYED : MF_ENABLED); + + scrnsz_x = fixed_size_x; + scrnsz_y = fixed_size_y; + doresize = 1; + + GetWindowRect(hwndMain, &r); + if (mouse_capture) ClipCursor(&r); - CheckMenuItem(hmenu, IDM_VID_SCALE_1X + scale, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_VID_SCALE_2X, MF_CHECKED); - scale = 1; - EnableMenuItem(hmenu, IDM_VID_SCALE_1X, MF_GRAYED); - EnableMenuItem(hmenu, IDM_VID_SCALE_2X, MF_GRAYED); - EnableMenuItem(hmenu, IDM_VID_SCALE_3X, MF_GRAYED); - EnableMenuItem(hmenu, IDM_VID_SCALE_4X, MF_GRAYED); - - scrnsz_x = temp_x; - scrnsz_y = temp_y; - doresize = 1; - - CheckMenuItem(hmenu, IDM_VID_REMEMBER, MF_CHECKED); - GetWindowRect(hwndMain, &r); - window_x = r.left; - window_y = r.top; - window_w = r.right - r.left; - window_h = r.bottom - r.top; + if (!(vid_resize & 2) && window_remember) { + window_x = r.left; + window_y = r.top; + window_w = r.right - r.left; + window_h = r.bottom - r.top; + } config_save(); diff --git a/src/win/win_ui.c b/src/win/win_ui.c index e690a0706..de76d142b 100644 --- a/src/win/win_ui.c +++ b/src/win/win_ui.c @@ -66,6 +66,7 @@ int minimized = 0; int infocus = 1, button_down = 0; int rctrl_is_lalt = 0; int user_resize = 0; +int fixed_size_x = 0, fixed_size_y = 0; extern char openfilestring[512]; extern WCHAR wopenfilestring[512]; @@ -125,7 +126,7 @@ int win_get_system_metrics(int index, int dpi) { void ResizeWindowByClientArea(HWND hwnd, int width, int height) { - if (vid_resize || padded_frame) { + if ((vid_resize == 1) || padded_frame) { int padding = win_get_system_metrics(SM_CXPADDEDBORDER, dpi); width += (win_get_system_metrics(SM_CXFRAME, dpi) + padding) * 2; height += (win_get_system_metrics(SM_CYFRAME, dpi) + padding) * 2; @@ -279,13 +280,13 @@ ResetAllMenus(void) CheckMenuItem(menuMain, IDM_VID_OVERSCAN, enable_overscan?MF_CHECKED:MF_UNCHECKED); CheckMenuItem(menuMain, IDM_VID_INVERT, invert_display ? MF_CHECKED : MF_UNCHECKED); - if (vid_resize) + if (vid_resize == 1) CheckMenuItem(menuMain, IDM_VID_RESIZE, MF_CHECKED); CheckMenuItem(menuMain, IDM_VID_SDL_SW+vid_api, MF_CHECKED); CheckMenuItem(menuMain, IDM_VID_FS_FULL+video_fullscreen_scale, MF_CHECKED); CheckMenuItem(menuMain, IDM_VID_REMEMBER, window_remember?MF_CHECKED:MF_UNCHECKED); CheckMenuItem(menuMain, IDM_VID_SCALE_1X+scale, MF_CHECKED); - CheckMenuItem(menuMain, IDM_VID_HIDPI, dpi_scale?MF_CHECKED:MF_UNCHECKED); + CheckMenuItem(menuMain, IDM_VID_HIDPI, dpi_scale?MF_CHECKED:MF_UNCHECKED); CheckMenuItem(menuMain, IDM_VID_CGACON, vid_cga_contrast?MF_CHECKED:MF_UNCHECKED); CheckMenuItem(menuMain, IDM_VID_GRAYCT_601+video_graytype, MF_CHECKED); @@ -300,6 +301,20 @@ ResetAllMenus(void) #ifdef MTR_ENABLED EnableMenuItem(menuMain, IDM_ACTION_END_TRACE, MF_DISABLED); #endif + + if (vid_resize) { + if (vid_resize >= 2) { + CheckMenuItem(menuMain, IDM_VID_RESIZE, MF_UNCHECKED); + EnableMenuItem(menuMain, IDM_VID_RESIZE, MF_GRAYED); + } + + CheckMenuItem(menuMain, IDM_VID_SCALE_1X + scale, MF_UNCHECKED); + CheckMenuItem(menuMain, IDM_VID_SCALE_2X, MF_CHECKED); + EnableMenuItem(menuMain, IDM_VID_SCALE_1X, MF_GRAYED); + EnableMenuItem(menuMain, IDM_VID_SCALE_2X, MF_GRAYED); + EnableMenuItem(menuMain, IDM_VID_SCALE_3X, MF_GRAYED); + EnableMenuItem(menuMain, IDM_VID_SCALE_4X, MF_GRAYED); + } } @@ -599,10 +614,10 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; case IDM_VID_RESIZE: - vid_resize = !vid_resize; - CheckMenuItem(hmenu, IDM_VID_RESIZE, (vid_resize)? MF_CHECKED : MF_UNCHECKED); + vid_resize ^= 1; + CheckMenuItem(hmenu, IDM_VID_RESIZE, (vid_resize & 1) ? MF_CHECKED : MF_UNCHECKED); - if (vid_resize) + if (vid_resize == 1) SetWindowLongPtr(hwnd, GWL_STYLE, (WS_OVERLAPPEDWINDOW) | WS_VISIBLE); else SetWindowLongPtr(hwnd, GWL_STYLE, (WS_OVERLAPPEDWINDOW & ~WS_SIZEBOX & ~WS_MAXIMIZEBOX) | WS_VISIBLE); @@ -642,7 +657,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) window_remember = !window_remember; CheckMenuItem(hmenu, IDM_VID_REMEMBER, window_remember ? MF_CHECKED : MF_UNCHECKED); GetWindowRect(hwnd, &rect); - if (window_remember) { + if (!(vid_resize & 2) && window_remember) { window_x = rect.left; window_y = rect.top; window_w = rect.right - rect.left; @@ -837,9 +852,19 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) GetWindowRect(hwndSBAR, &rect); sbar_height = rect.bottom - rect.top; rect_p = (RECT*)lParam; - if (vid_resize) + if (vid_resize == 1) MoveWindow(hwnd, rect_p->left, rect_p->top, rect_p->right - rect_p->left, rect_p->bottom - rect_p->top, TRUE); - else if (!user_resize) + else if (vid_resize >= 2) { + temp_x = fixed_size_x; + temp_y = fixed_size_y; + if (dpi_scale) { + temp_x = MulDiv(temp_x, dpi, 96); + temp_y = MulDiv(temp_y, dpi, 96); + } + + /* Main Window. */ + ResizeWindowByClientArea(hwndMain, temp_x, temp_y + sbar_height); + } else if (!user_resize) doresize = 1; break; @@ -1243,10 +1268,10 @@ ui_init(int nCmdShow) sbar_height = sbar_rect.bottom - sbar_rect.top; /* Set up main window for resizing if configured. */ - if (vid_resize) + if (vid_resize == 1) SetWindowLongPtr(hwnd, GWL_STYLE, (WS_OVERLAPPEDWINDOW)); - else + else SetWindowLongPtr(hwnd, GWL_STYLE, (WS_OVERLAPPEDWINDOW&~WS_SIZEBOX&~WS_THICKFRAME&~WS_MAXIMIZEBOX)); @@ -1256,10 +1281,15 @@ ui_init(int nCmdShow) /* Initiate a resize in order to properly arrange all controls. Move to the last-saved position if needed. */ - if (window_remember) + if ((vid_resize < 2) && window_remember) MoveWindow(hwnd, window_x, window_y, window_w, window_h, TRUE); - else + else { + if (vid_resize >= 2) { + scrnsz_x = fixed_size_x; + scrnsz_y = fixed_size_y; + } ResizeWindowByClientArea(hwndMain, scrnsz_x, scrnsz_y + sbar_height); + } /* Reset all menus to their defaults. */ ResetAllMenus(); @@ -1479,7 +1509,6 @@ plat_resize(int x, int y) { /* First, see if we should resize the UI window. */ if (!vid_resize) { - /* scale the screen base on DPI */ if (dpi_scale) { x = MulDiv(x, dpi, 96); From e91a938f079af1c8bf68a43122fff2bdfecf61f2 Mon Sep 17 00:00:00 2001 From: Daniel Gurney Date: Mon, 12 Apr 2021 23:32:25 +0300 Subject: [PATCH 19/25] Fix cmake --- src/win/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/win/CMakeLists.txt b/src/win/CMakeLists.txt index f2f995d6d..1588a4d7e 100644 --- a/src/win/CMakeLists.txt +++ b/src/win/CMakeLists.txt @@ -19,7 +19,7 @@ add_library(plat OBJECT win.c win_dynld.c win_thread.c win_cdrom.c win_keyboard.c win_crashdump.c win_midi.c win_mouse.c) add_library(ui OBJECT win_ui.c win_stbar.c win_sdl.c win_dialog.c win_about.c - win_settings.c win_devconf.c win_snd_gain.c win_specify_dim.o win_new_floppy.c + win_settings.c win_devconf.c win_snd_gain.c win_specify_dim.c win_new_floppy.c win_jsconf.c win_media_menu.c 86Box.rc) if(MSVC) From 1a7bcec0f41a475ed73eae915ecab7cd0d3b0ae6 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 13 Apr 2021 00:31:09 +0200 Subject: [PATCH 20/25] The Soyo 4SA2 now correctly has the Winbond W83787F Super I/O chip. --- src/machine/m_at_386dx_486.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 3fc72e971..1852f9846 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -887,7 +887,7 @@ machine_at_4sa2_init(const machine_t *model) pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x11, PCI_CARD_NORMAL, 4, 1, 2, 3); - device_add(&pc87332_device); + device_add(&w83787f_device); device_add(&keyboard_ps2_pci_device); device_add(&intel_flash_bxt_device); From 77c18c0708a9b458e38e037d24ca0cebc5531315 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 13 Apr 2021 01:18:56 +0200 Subject: [PATCH 21/25] Improved the status bar's handling of hard disks and other storage devices on internal controllers. --- src/win/win_stbar.c | 58 ++++++++++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 25 deletions(-) diff --git a/src/win/win_stbar.c b/src/win/win_stbar.c index 58566ab71..3ae3f0f5c 100644 --- a/src/win/win_stbar.c +++ b/src/win/win_stbar.c @@ -432,7 +432,8 @@ ui_sb_set_ready(int ready) void ui_sb_update_panes(void) { - int i, id, hdint; + int i, id; + int mfm_int, xta_int, esdi_int, ide_int, scsi_int; int edge = 0; int c_mfm, c_esdi, c_xta; int c_ide, c_scsi; @@ -446,7 +447,12 @@ ui_sb_update_panes(void) sb_ready = 0; } - hdint = (machines[machine].flags & MACHINE_HDC) ? 1 : 0; + mfm_int = (machines[machine].flags & MACHINE_MFM) ? 1 : 0; + xta_int = (machines[machine].flags & MACHINE_XTA) ? 1 : 0; + esdi_int = (machines[machine].flags & MACHINE_ESDI) ? 1 : 0; + ide_int = (machines[machine].flags & MACHINE_IDE_QUAD) ? 1 : 0; + scsi_int = (machines[machine].flags & MACHINE_SCSI_DUAL) ? 1 : 0; + c_mfm = hdd_count(HDD_BUS_MFM); c_esdi = hdd_count(HDD_BUS_ESDI); c_xta = hdd_count(HDD_BUS_XTA); @@ -487,11 +493,11 @@ ui_sb_update_panes(void) for (i=0; i Date: Tue, 13 Apr 2021 02:33:40 +0200 Subject: [PATCH 22/25] The Intel 420TX and 420ZX chipsets now correctly have 57h as the SMRAM control register (identified by register write logging on the ASUS P/I-486SP3G) rather than 72h, fixes hangs and errors on the ASUS P/I-486SP3G. --- src/chipset/intel_4x0.c | 64 ++++++++++++++++++++++++++++++++--------- src/mem/mem.c | 2 +- 2 files changed, 51 insertions(+), 15 deletions(-) diff --git a/src/chipset/intel_4x0.c b/src/chipset/intel_4x0.c index 5a7b79e3c..2f0c7cc39 100644 --- a/src/chipset/intel_4x0.c +++ b/src/chipset/intel_4x0.c @@ -120,20 +120,22 @@ i4x0_smram_handler_phase0(i4x0_t *dev) static void i4x0_smram_handler_phase1(i4x0_t *dev) { + uint8_t *regs = (uint8_t *) dev->regs; uint32_t tom = (mem_size << 10); + uint8_t *reg = (dev->type >= INTEL_430LX) ? &(regs[0x72]) : &(regs[0x57]); uint8_t *ext_reg = (dev->type >= INTEL_440BX) ? &(regs[0x73]) : &(regs[0x71]); uint32_t s, base[2] = { 0x000a0000, 0x00000000 }; uint32_t size[2] = { 0x00010000, 0x00000000 }; - if (dev->type >= INTEL_430FX) { + if ((dev->type <= INTEL_420ZX) || (dev->type >= INTEL_430FX)) { /* Set temporary bases and sizes. */ if (((dev->type == INTEL_430TX) || (dev->type >= INTEL_440BX)) && (*ext_reg & 0x80)) { base[0] = 0x100a0000; size[0] = 0x00060000; - } else if (((dev->type == INTEL_440LX) || (dev->type == INTEL_440EX)) && ((regs[0x72] & 0x07) == 0x04)) { + } else if (((dev->type == INTEL_440LX) || (dev->type == INTEL_440EX)) && ((*reg & 0x07) == 0x04)) { base[0] = 0x000c0000; size[0] = 0x00010000; } else { @@ -141,11 +143,11 @@ i4x0_smram_handler_phase1(i4x0_t *dev) size[0] = 0x00020000; } - if (regs[0x72] & 0x08) + if (*reg & 0x08) smram_enable(dev->smram_low, base[0], base[0] & 0x000f0000, size[0], - ((regs[0x72] & 0x78) == 0x48), (regs[0x72] & 0x08)); + ((*reg & 0x78) == 0x48), (*reg & 0x08)); - if ((regs[0x72] & 0x28) == 0x28) { + if ((*reg & 0x28) == 0x28) { /* If SMRAM is enabled and DCLS is set, then data goes to PCI, but code still goes to DRAM. */ mem_set_mem_state_smram_ex(1, base[0], size[0], 0x02); @@ -153,7 +155,7 @@ i4x0_smram_handler_phase1(i4x0_t *dev) /* TSEG mapping. */ if ((dev->type == INTEL_430TX) || (dev->type >= INTEL_440BX)) { - if ((regs[0x72] & 0x08) && (*ext_reg & 0x01)) { + if ((*reg & 0x08) && (*ext_reg & 0x01)) { size[1] = (1 << (17 + ((*ext_reg >> 1) & 0x03))); tom -= size[1]; base[1] = tom; @@ -169,7 +171,7 @@ i4x0_smram_handler_phase1(i4x0_t *dev) } } else { size[0] = 0x00010000; - switch (regs[0x72] & 0x03) { + switch (*reg & 0x03) { case 0: default: base[0] = (mem_size << 10) - size[0]; @@ -191,9 +193,9 @@ i4x0_smram_handler_phase1(i4x0_t *dev) if (size[0] != 0x00000000) { smram_enable(dev->smram_low, base[0], base[0], size[0], - (((regs[0x72] & 0x38) == 0x20) || s), 1); + (((*reg & 0x38) == 0x20) || s), 1); - if (regs[0x72] & 0x10) { + if (*reg & 0x10) { /* If SMRAM is enabled and DCLS is set, then data goes to PCI, but code still goes to DRAM. */ mem_set_mem_state_smram_ex(1, base[0], size[0], 0x02); @@ -517,7 +519,19 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) break; case 0x57: switch (dev->type) { + /* On the 420TX and 420ZX, this is the SMRAM space register. */ case INTEL_420TX: case INTEL_420ZX: + i4x0_smram_handler_phase0(dev); + if (dev->smram_locked) + regs[0x57] = (regs[0x57] & 0xdf) | (val & 0x20); + else { + regs[0x57] = (regs[0x57] & 0x87) | (val & 0x78); + dev->smram_locked = (val & 0x10); + if (dev->smram_locked) + regs[0x57] &= 0xbf; + } + i4x0_smram_handler_phase1(dev); + break; case INTEL_430LX: default: regs[0x57] = val & 0x3f; break; @@ -824,6 +838,9 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) } break; case 0x72: /* SMRAM */ + if (dev->type <= INTEL_420ZX) + break; + i4x0_smram_handler_phase0(dev); if (dev->type >= INTEL_430FX) { if (dev->smram_locked) @@ -1215,6 +1232,10 @@ i4x0_reset(void *priv) i4x0_t *dev = (i4x0_t *)priv; int i; + if ((dev->type == INTEL_440LX) || (dev->type == INTEL_440BX) || + (dev->type == INTEL_440ZX)) + memset(dev->regs_locked, 0x00, 256 * sizeof(uint8_t)); + if (dev->type >= INTEL_430FX) i4x0_write(0, 0x59, 0x00, priv); else @@ -1229,14 +1250,18 @@ i4x0_reset(void *priv) if (dev->type >= INTEL_430FX) { dev->regs[0x72] &= 0xef; /* Forcibly unlock the SMRAM register. */ i4x0_write(0, 0x72, 0x02, priv); - } else { + } else if (dev->type >= INTEL_430LX) { dev->regs[0x72] &= 0xf7; /* Forcibly unlock the SMRAM register. */ i4x0_write(0, 0x72, 0x00, priv); + } else { + dev->regs[0x57] &= 0xef; /* Forcibly unlock the SMRAM register. */ + i4x0_write(0, 0x57, 0x02, priv); } - if ((dev->type == INTEL_440LX) || (dev->type == INTEL_440BX) || - (dev->type == INTEL_440ZX)) - memset(dev->regs_locked, 0x00, 256 * sizeof(uint8_t)); + if ((dev->type == INTEL_430TX) || (dev->type >= INTEL_440BX)) { + i4x0_write(0, (dev->type >= INTEL_440BX) ? 0x73 : 0x71, + (dev->type >= INTEL_440BX) ? 0x38 : 0x00, priv); + } } @@ -1554,7 +1579,18 @@ static void i4x0_write(regs[0x5d], 0x5d, 0x00, dev); i4x0_write(regs[0x5e], 0x5e, 0x00, dev); i4x0_write(regs[0x5f], 0x5f, 0x00, dev); - i4x0_write(regs[0x72], 0x72, 0x00, dev); + + if (dev->type >= INTEL_430FX) + i4x0_write(0, 0x72, 0x02, dev); + else if (dev->type >= INTEL_430LX) + i4x0_write(0, 0x72, 0x00, dev); + else + i4x0_write(0, 0x57, 0x02, dev); + + if ((dev->type == INTEL_430TX) || (dev->type >= INTEL_440BX)) { + i4x0_write(0, (dev->type >= INTEL_440BX) ? 0x73 : 0x71, + (dev->type >= INTEL_440BX) ? 0x38 : 0x00, dev); + } pci_add_card(PCI_ADD_NORTHBRIDGE, i4x0_read, i4x0_write, dev); diff --git a/src/mem/mem.c b/src/mem/mem.c index 000937341..1d54d7880 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -691,7 +691,7 @@ getpccache(uint32_t a) return &_mem_exec[a64 >> MEM_GRANULARITY_BITS][(uintptr_t)(a64 & MEM_GRANULARITY_PAGE) - (uintptr_t)(a2 & ~0xfff)]; } - mem_log("Bad getpccache %08X%08X\n", (uint32_t) (a >> 32), (uint32_t) (a & 0xffffffff)); + mem_log("Bad getpccache %08X%08X\n", (uint32_t) (a64 >> 32), (uint32_t) (a64 & 0xffffffffULL)); return (uint8_t *)&ff_pccache; } From 5a228ba8dbe954068eee69907cd57698cb959f76 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 13 Apr 2021 02:35:13 +0200 Subject: [PATCH 23/25] Removed excess logging from intel_sio.c. --- src/chipset/intel_sio.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/chipset/intel_sio.c b/src/chipset/intel_sio.c index d456c96df..ed1c141b1 100644 --- a/src/chipset/intel_sio.c +++ b/src/chipset/intel_sio.c @@ -218,7 +218,6 @@ sio_write(int func, int addr, uint8_t val, void *priv) break; case 0x60: case 0x61: case 0x62: case 0x63: if (dev->id == 0x03) { - pclog("Set IRQ routing: INT %c -> %02X\n", 0x41 + (addr & 0x03), val); sio_log("Set IRQ routing: INT %c -> %02X\n", 0x41 + (addr & 0x03), val); dev->regs[addr] = val & 0x8f; if (val & 0x80) From 76f3f08d785597ea00c7f29bc70fb81a22577a87 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 13 Apr 2021 03:47:46 +0200 Subject: [PATCH 24/25] The Intel SIO and PIIX* southbridges now have the undocumented (by the datasheets, but fully documented by the Intel motherboard technical specifications) second PIT on ports 48h-4Bh. --- src/chipset/intel_piix.c | 2 ++ src/chipset/intel_sio.c | 2 ++ src/include/86box/pit.h | 1 + src/pit.c | 18 ++++++++++++++++-- 4 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/chipset/intel_piix.c b/src/chipset/intel_piix.c index 2c6ed1500..50d345448 100644 --- a/src/chipset/intel_piix.c +++ b/src/chipset/intel_piix.c @@ -1374,6 +1374,8 @@ static void else dev->board_config[1] |= 0x00; + device_add(&i8254_sec_device); + return dev; } diff --git a/src/chipset/intel_sio.c b/src/chipset/intel_sio.c index ed1c141b1..91f9128a0 100644 --- a/src/chipset/intel_sio.c +++ b/src/chipset/intel_sio.c @@ -539,6 +539,8 @@ sio_init(const device_t *info) timer_add(&dev->timer, NULL, NULL, 0); + device_add(&i8254_sec_device); + return dev; } diff --git a/src/include/86box/pit.h b/src/include/86box/pit.h index 027955c69..bf8d71048 100644 --- a/src/include/86box/pit.h +++ b/src/include/86box/pit.h @@ -109,6 +109,7 @@ extern void pit_handler(int set, uint16_t base, int size, void *priv); #ifdef EMU_DEVICE_H extern const device_t i8253_device; extern const device_t i8254_device; +extern const device_t i8254_sec_device; extern const device_t i8254_ext_io_device; extern const device_t i8254_ps2_device; #endif diff --git a/src/pit.c b/src/pit.c index a4b865f1c..9db4c45dd 100644 --- a/src/pit.c +++ b/src/pit.c @@ -63,6 +63,7 @@ int64_t firsttime = 1; #define PIT_PS2 16 /* The PIT is the PS/2's second PIT. */ #define PIT_EXT_IO 32 /* The PIT has externally specified port I/O. */ #define PIT_CUSTOM_CLOCK 64 /* The PIT uses custom clock inputs provided by another provider. */ +#define PIT_SECONDARY 128 /* The PIT is secondary (ports 0048-004B). */ enum { @@ -826,8 +827,10 @@ pit_init(const device_t *info) dev->flags = info->local; - if (!(dev->flags & PIT_EXT_IO)) - io_sethandler(0x0040, 0x0004, pit_read, NULL, NULL, pit_write, NULL, NULL, dev); + if (!(dev->flags & PIT_EXT_IO)) { + io_sethandler((dev->flags & PIT_SECONDARY) ? 0x0048 : 0x0040, 0x0004, + pit_read, NULL, NULL, pit_write, NULL, NULL, dev); + } return dev; } @@ -855,6 +858,17 @@ const device_t i8254_device = }; +const device_t i8254_sec_device = +{ + "Intel 8254 Programmable Interval Timer (Secondary)", + DEVICE_ISA, + PIT_8254 | PIT_SECONDARY, + pit_init, pit_close, NULL, + { NULL }, NULL, NULL, + NULL +}; + + const device_t i8254_ext_io_device = { "Intel 8254 Programmable Interval Timer (External I/O)", From 3746b722c7aa4021b0f53e8f62b65608bb7788c7 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 13 Apr 2021 18:57:01 +0200 Subject: [PATCH 25/25] The two 486 machines with on-board SCSI controllers now have the MACHINE_SCSI flag. --- src/machine/machine_table.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 6cdc5af37..4ed5f966b 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -233,8 +233,8 @@ const machine_t machines[] = { { "[ALi M1489] AMI WinBIOS 486 PCI", "win486pci", MACHINE_TYPE_486, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCI | MACHINE_IDE_DUAL, 1024, 65536, 1024, 255, machine_at_win486pci_init, NULL }, { "[OPTi 802G] IBM PC 330 (type 6573)", "pc330_6573", MACHINE_TYPE_486, CPU_PKG_SOCKET3_PC330, 0, 25000000, 33333333, 0, 0, 2.0, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE, 1024, 65536, 1024, 127, machine_at_pc330_6573_init, NULL }, { "[i420EX] ASUS PVI-486AP4", "486ap4", MACHINE_TYPE_486, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCIV | MACHINE_IDE_DUAL, 1024, 131072, 1024, 127, machine_at_486ap4_init, NULL }, - { "[i420ZX] ASUS PCI/I-486SP3G", "486sp3g", MACHINE_TYPE_486, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCI | MACHINE_IDE_DUAL, 1024, 131072, 1024, 127, machine_at_486sp3g_init, NULL }, - { "[i420TX] ASUS PCI/I-486SP3", "486sp3", MACHINE_TYPE_486, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCI | MACHINE_IDE_DUAL, 1024, 131072, 1024, 127, machine_at_486sp3_init, NULL }, + { "[i420ZX] ASUS PCI/I-486SP3G", "486sp3g", MACHINE_TYPE_486, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCI | MACHINE_IDE_DUAL | MACHINE_SCSI, 1024, 131072, 1024, 127, machine_at_486sp3g_init, NULL }, + { "[i420TX] ASUS PCI/I-486SP3", "486sp3", MACHINE_TYPE_486, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCI | MACHINE_IDE_DUAL | MACHINE_SCSI, 1024, 131072, 1024, 127, machine_at_486sp3_init, NULL }, { "[i420TX] Intel Classic/PCI", "alfredo", MACHINE_TYPE_486, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 2048, 131072, 2048, 127, machine_at_alfredo_init, NULL }, { "[SiS 496] ASUS PVI-486SP3C", "486sp3c", MACHINE_TYPE_486, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCIV | MACHINE_IDE_DUAL, 1024, 261120, 1024, 255, machine_at_486sp3c_init, NULL }, { "[SiS 496] Lucky Star LS-486E", "ls486e", MACHINE_TYPE_486, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCI | MACHINE_IDE_DUAL, 1024, 131072, 1024, 255, machine_at_ls486e_init, NULL },