CPU and MMU cleanups and fixes, and non-Debug builds are now stripped again.

This commit is contained in:
OBattler
2021-04-10 07:18:47 +02:00
parent 99ca313565
commit c370ae7e18
22 changed files with 3488 additions and 4367 deletions

View File

@@ -134,9 +134,9 @@ static inline void fetch_ea_32_long(uint32_t rmdat)
if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC)
{ {
uint32_t addr = easeg + cpu_state.eaaddr; 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); 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); 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) if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC)
{ {
uint32_t addr = easeg + cpu_state.eaaddr; 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); 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); eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr);
} }
} }
@@ -271,7 +271,7 @@ exec386(int cycs)
CS = oldcs; CS = oldcs;
#endif #endif
cpu_state.pc = cpu_state.oldpc; cpu_state.pc = cpu_state.oldpc;
x386_log("Double fault %i\n", ins); x386_log("Double fault\n");
pmodeint(8, 0); pmodeint(8, 0);
if (cpu_state.abrt) { if (cpu_state.abrt) {
cpu_state.abrt = 0; cpu_state.abrt = 0;

View File

@@ -65,10 +65,17 @@ uint32_t old_rammask = 0xffffffff;
int soft_reset_mask = 0; 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) uint32_t addr64, addr64_2;
#define AMD_SYSCALL_SB ((star >> 32) & 0xFFFF) uint32_t addr64a[8], addr64a_2[8];
#define AMD_SYSRET_SB ((star >> 48) & 0xFFFF)
#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. */ /* These #define's and enum have been borrowed from Bochs. */
@@ -1312,7 +1319,7 @@ x86_int(int num)
else { else {
addr = (num << 2) + idt.base; addr = (num << 2) + idt.base;
if ((num << 2) + 3 > idt.limit) { if ((num << 2UL) + 3UL > idt.limit) {
if (idt.limit < 35) { if (idt.limit < 35) {
cpu_state.abrt = 0; cpu_state.abrt = 0;
softresetx86(); softresetx86();
@@ -1363,7 +1370,7 @@ x86_int_sw(int num)
else { else {
addr = (num << 2) + idt.base; addr = (num << 2) + idt.base;
if ((num << 2) + 3 > idt.limit) if ((num << 2UL) + 3UL > idt.limit)
x86_int(0x0d); x86_int(0x0d);
else { else {
if (stack32) { if (stack32) {
@@ -1447,7 +1454,7 @@ x86illegal()
int int
checkio(int port) checkio(uint32_t port)
{ {
uint16_t t; uint16_t t;
uint8_t d; uint8_t d;
@@ -1459,7 +1466,7 @@ checkio(int port)
if (cpu_state.abrt) if (cpu_state.abrt)
return 0; return 0;
if ((t + (port >> 3)) > tr.limit) if ((t + (port >> 3UL)) > tr.limit)
return 1; return 1;
cpl_override = 1; cpl_override = 1;
@@ -1599,7 +1606,7 @@ sysenter(uint32_t fetchdat)
return cpu_state.abrt; return cpu_state.abrt;
} }
if (!(cs_msr & 0xFFF8)) { if (!(msr.sysenter_cs & 0xFFF8)) {
#ifdef ENABLE_386_COMMON_LOG #ifdef ENABLE_386_COMMON_LOG
x386_common_log("SYSENTER: CS MSR is zero"); x386_common_log("SYSENTER: CS MSR is zero");
#endif #endif
@@ -1611,7 +1618,7 @@ sysenter(uint32_t fetchdat)
x386_common_log("SYSENTER started:\n"); 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(" 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(" 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); 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 #endif
@@ -1623,10 +1630,10 @@ sysenter(uint32_t fetchdat)
oldcs = CS; oldcs = CS;
#endif #endif
cpu_state.oldpc = cpu_state.pc; cpu_state.oldpc = cpu_state.pc;
ESP = esp_msr; ESP = msr.sysenter_esp;
cpu_state.pc = eip_msr; 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.base = 0;
cpu_state.seg_cs.limit_low = 0; cpu_state.seg_cs.limit_low = 0;
cpu_state.seg_cs.limit = 0xffffffff; cpu_state.seg_cs.limit = 0xffffffff;
@@ -1637,7 +1644,7 @@ sysenter(uint32_t fetchdat)
cpu_state.seg_cs.checked = 1; cpu_state.seg_cs.checked = 1;
oldcpl = 0; 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.base = 0;
cpu_state.seg_ss.limit_low = 0; cpu_state.seg_ss.limit_low = 0;
cpu_state.seg_ss.limit = 0xffffffff; cpu_state.seg_ss.limit = 0xffffffff;
@@ -1661,7 +1668,7 @@ sysenter(uint32_t fetchdat)
x386_common_log("SYSENTER completed:\n"); 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(" 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(" 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); 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 #endif
@@ -1676,7 +1683,7 @@ sysexit(uint32_t fetchdat)
x386_common_log("SYSEXIT called\n"); x386_common_log("SYSEXIT called\n");
#endif #endif
if (!(cs_msr & 0xFFF8)) { if (!(msr.sysenter_cs & 0xFFF8)) {
#ifdef ENABLE_386_COMMON_LOG #ifdef ENABLE_386_COMMON_LOG
x386_common_log("SYSEXIT: CS MSR is zero"); x386_common_log("SYSEXIT: CS MSR is zero");
#endif #endif
@@ -1704,7 +1711,7 @@ sysexit(uint32_t fetchdat)
x386_common_log("SYSEXIT start:\n"); 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(" 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(" 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); 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 #endif
@@ -1715,7 +1722,7 @@ sysexit(uint32_t fetchdat)
ESP = ECX; ESP = ECX;
cpu_state.pc = EDX; 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.base = 0;
cpu_state.seg_cs.limit_low = 0; cpu_state.seg_cs.limit_low = 0;
cpu_state.seg_cs.limit = 0xffffffff; cpu_state.seg_cs.limit = 0xffffffff;
@@ -1726,7 +1733,7 @@ sysexit(uint32_t fetchdat)
cpu_state.seg_cs.checked = 1; cpu_state.seg_cs.checked = 1;
oldcpl = 3; 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.base = 0;
cpu_state.seg_ss.limit_low = 0; cpu_state.seg_ss.limit_low = 0;
cpu_state.seg_ss.limit = 0xffffffff; cpu_state.seg_ss.limit = 0xffffffff;
@@ -1751,7 +1758,7 @@ sysexit(uint32_t fetchdat)
x386_common_log("SYSEXIT completed:\n"); 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(" 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(" 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); 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 #endif

View File

@@ -15,38 +15,37 @@
* Copyright 2008-2019 Sarah Walker. * Copyright 2008-2019 Sarah Walker.
* Copyright 2016-2019 Miran Grca. * Copyright 2016-2019 Miran Grca.
*/ */
#ifndef _386_COMMON_H_ #ifndef _386_COMMON_H_
#define _386_COMMON_H_ #define _386_COMMON_H_
#include <stddef.h> #include <stddef.h>
#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 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]==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 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]==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 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]==LOOKUP_INV || (s)==0xFFFFFFFF)?readmembl((s)+(a)): *(uint8_t *)(readlookup2[(uint32_t)((s)+(a))>>12] + (uintptr_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]==LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1))?readmemwl((s)+(a)):*(uint16_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_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]==LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3))?readmemll((s)+(a)):*(uint32_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]==LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 7))?readmemql((s)+(a)):*(uint64_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uintptr_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 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]==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 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]==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 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]==LOOKUP_INV || (s)==0xFFFFFFFF) writemembl((s)+(a),v); else *(uint8_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]==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 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]==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 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]==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 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_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]==LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1)) do_mmutranslate((s)+(a), b, 2, 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]==LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3)) do_mmutranslate((s)+(a), b, 4, 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_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]==LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1)) do_mmutranslate((s)+(a), b, 2, 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]==LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3)) do_mmutranslate((s)+(a), b, 4, 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))) \ #define check_io_perm(port) if (msw&1 && ((CPL > IOPL) || (cpu_state.eflags&VM_FLAG))) \

View File

@@ -121,9 +121,9 @@ static __inline void fetch_ea_32_long(uint32_t rmdat)
if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC)
{ {
uint32_t addr = easeg + cpu_state.eaaddr; 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); 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); 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) if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC)
{ {
uint32_t addr = easeg + cpu_state.eaaddr; 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); 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); eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr);
} }
} }

View File

@@ -33,9 +33,9 @@ static __inline void fetch_ea_32_long(uint32_t rmdat)
if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC)
{ {
uint32_t addr = easeg + cpu_state.eaaddr; 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); 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); 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) if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC)
{ {
uint32_t addr = easeg + cpu_state.eaaddr; 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); 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); eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr);
} }
} }

View File

@@ -35,43 +35,9 @@
#include <86box/ppi.h> #include <86box/ppi.h>
#include <86box/timer.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. */ /* Is the CPU 8088 or 8086. */
int is8086 = 0; 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). */ /* The prefetch queue (4 bytes for 8088, 6 bytes for 8086). */
static uint8_t pfq[6]; static uint8_t pfq[6];
@@ -148,50 +114,6 @@ x808x_log(const char *fmt, ...)
va_end(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 #else
#define x808x_log(fmt, ...) #define x808x_log(fmt, ...)
#endif #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 static void
set_ip(uint16_t new_ip) { set_ip(uint16_t new_ip) {
pfq_ip = cpu_state.pc = 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 static uint16_t
get_accum(int bits) get_accum(int bits)
{ {
@@ -865,176 +805,6 @@ seteaq(uint64_t val)
#undef FPU_8087 #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. */ /* Pushes a word to the stack. */
static void static void
push(uint16_t *val) push(uint16_t *val)
@@ -1867,7 +1637,7 @@ execx86(int cycs)
load_cs(pop()); load_cs(pop());
pfq_pos = 0; pfq_pos = 0;
} else } else
loadseg(pop(), _opseg[(opcode >> 3) & 0x03]); load_seg(pop(), _opseg[(opcode >> 3) & 0x03]);
wait(1, 0); wait(1, 0);
/* All POP segment instructions suppress interrupts for one instruction. */ /* All POP segment instructions suppress interrupts for one instruction. */
noint = 1; noint = 1;
@@ -2201,7 +1971,7 @@ execx86(int cycs)
load_cs(tempw); load_cs(tempw);
pfq_pos = 0; pfq_pos = 0;
} else } else
loadseg(tempw, _opseg[(rmdat & 0x18) >> 3]); load_seg(tempw, _opseg[(rmdat & 0x18) >> 3]);
wait(1, 0); wait(1, 0);
if (cpu_mod != 3) if (cpu_mod != 3)
wait(2, 0); wait(2, 0);
@@ -2482,7 +2252,7 @@ execx86(int cycs)
cpu_state.regs[cpu_reg].w = cpu_data; cpu_state.regs[cpu_reg].w = cpu_data;
access(57, bits); access(57, bits);
read_ea2(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); wait(1, 0);
break; break;
@@ -2985,7 +2755,5 @@ execx86(int cycs)
cpu_alu_op = 0; cpu_alu_op = 0;
} }
ins++;
} }
} }

View File

@@ -13,7 +13,7 @@
# Copyright 2020,2021 David Hrdlička. # 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) 386_dynarec_ops.c x86seg.c x87.c x87_timings.c)
if(AMD_K5) if(AMD_K5)

File diff suppressed because it is too large Load Diff

View File

@@ -40,9 +40,9 @@ enum {
#endif #endif
CPU_286, /* 286 class CPUs */ CPU_286, /* 286 class CPUs */
CPU_386SX, /* 386 class CPUs */ CPU_386SX, /* 386 class CPUs */
CPU_386DX,
CPU_IBM386SLC, CPU_IBM386SLC,
CPU_IBM486SLC, CPU_IBM486SLC,
CPU_386DX,
CPU_IBM486BL, CPU_IBM486BL,
CPU_RAPIDCAD, CPU_RAPIDCAD,
CPU_486SLC, CPU_486SLC,
@@ -53,10 +53,10 @@ enum {
CPU_i486SX2, CPU_i486SX2,
CPU_Am486SX2, CPU_Am486SX2,
CPU_i486DX, CPU_i486DX,
CPU_i486DX2,
CPU_Am486DX, CPU_Am486DX,
CPU_Am486DX2,
CPU_Cx486DX, CPU_Cx486DX,
CPU_i486DX2,
CPU_Am486DX2,
CPU_Cx486DX2, CPU_Cx486DX2,
CPU_iDX4, CPU_iDX4,
CPU_Am486DX4, CPU_Am486DX4,
@@ -236,10 +236,99 @@ typedef union {
} MMX_REG; } MMX_REG;
typedef struct { typedef struct {
uint32_t tr1, tr12; /* IDT WinChip and WinChip 2 MSR's */
uint32_t cesr; uint32_t tr1, tr12; /* 0x00000002, 0x0000000e */
uint32_t fcr; uint32_t cesr; /* 0x00000011 */
uint64_t fcr2, fcr3;
/* 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; } msr_t;
typedef struct { typedef struct {
@@ -532,7 +621,7 @@ extern void cpu_CPUID(void);
extern void cpu_RDMSR(void); extern void cpu_RDMSR(void);
extern void cpu_WRMSR(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_block_end(void);
extern void codegen_reset(void); extern void codegen_reset(void);
extern void cpu_set_edx(void); extern void cpu_set_edx(void);
@@ -612,9 +701,14 @@ typedef struct
} cyrix_t; } cyrix_t;
extern uint32_t addr64, addr64_2;
extern uint32_t addr64a[8], addr64a_2[8];
extern cyrix_t cyrix; extern cyrix_t cyrix;
extern void (*cpu_exec)(int cycs); extern void (*cpu_exec)(int cycs);
extern uint8_t do_translate, do_translate2; extern uint8_t do_translate, do_translate2;
extern void reset_808x(int hard);
#endif /*EMU_CPU_H*/ #endif /*EMU_CPU_H*/

View File

@@ -18,7 +18,7 @@ opSYSCALL(uint32_t fetchdat)
{ {
int ret; int ret;
ILLEGAL_ON(!(amd_efer & 0x0000000000000001)); ILLEGAL_ON(!(msr.amd_efer & 0x0000000000000001));
ret = syscall_op(fetchdat); ret = syscall_op(fetchdat);
@@ -38,7 +38,7 @@ opSYSRET(uint32_t fetchdat)
{ {
int ret; int ret;
ILLEGAL_ON(!(amd_efer & 0x0000000000000001)); ILLEGAL_ON(!(msr.amd_efer & 0x0000000000000001));
ret = sysret(fetchdat); ret = sysret(fetchdat);

View File

@@ -309,8 +309,8 @@ static int opCMP_b_rmw_a16(uint32_t fetchdat)
SEG_CHECK_READ(cpu_state.ea_seg); SEG_CHECK_READ(cpu_state.ea_seg);
dst = geteab(); if (cpu_state.abrt) return 1; dst = geteab(); if (cpu_state.abrt) return 1;
setsub8(dst, getr8(cpu_reg)); setsub8(dst, getr8(cpu_reg));
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); }
else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); 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); PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0);
return 0; return 0;
} }
@@ -322,8 +322,8 @@ static int opCMP_b_rmw_a32(uint32_t fetchdat)
SEG_CHECK_READ(cpu_state.ea_seg); SEG_CHECK_READ(cpu_state.ea_seg);
dst = geteab(); if (cpu_state.abrt) return 1; dst = geteab(); if (cpu_state.abrt) return 1;
setsub8(dst, getr8(cpu_reg)); setsub8(dst, getr8(cpu_reg));
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); }
else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); 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); PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1);
return 0; return 0;
} }
@@ -336,8 +336,8 @@ static int opCMP_w_rmw_a16(uint32_t fetchdat)
SEG_CHECK_READ(cpu_state.ea_seg); SEG_CHECK_READ(cpu_state.ea_seg);
dst = geteaw(); if (cpu_state.abrt) return 1; dst = geteaw(); if (cpu_state.abrt) return 1;
setsub16(dst, cpu_state.regs[cpu_reg].w); setsub16(dst, cpu_state.regs[cpu_reg].w);
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); }
else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); 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); PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0);
return 0; return 0;
} }
@@ -349,8 +349,8 @@ static int opCMP_w_rmw_a32(uint32_t fetchdat)
SEG_CHECK_READ(cpu_state.ea_seg); SEG_CHECK_READ(cpu_state.ea_seg);
dst = geteaw(); if (cpu_state.abrt) return 1; dst = geteaw(); if (cpu_state.abrt) return 1;
setsub16(dst, cpu_state.regs[cpu_reg].w); setsub16(dst, cpu_state.regs[cpu_reg].w);
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); }
else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); 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); PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1);
return 0; return 0;
} }
@@ -363,8 +363,8 @@ static int opCMP_l_rmw_a16(uint32_t fetchdat)
SEG_CHECK_READ(cpu_state.ea_seg); SEG_CHECK_READ(cpu_state.ea_seg);
dst = geteal(); if (cpu_state.abrt) return 1; dst = geteal(); if (cpu_state.abrt) return 1;
setsub32(dst, cpu_state.regs[cpu_reg].l); setsub32(dst, cpu_state.regs[cpu_reg].l);
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); }
else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); 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); PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1,0,0, 0);
return 0; return 0;
} }
@@ -376,8 +376,8 @@ static int opCMP_l_rmw_a32(uint32_t fetchdat)
SEG_CHECK_READ(cpu_state.ea_seg); SEG_CHECK_READ(cpu_state.ea_seg);
dst = geteal(); if (cpu_state.abrt) return 1; dst = geteal(); if (cpu_state.abrt) return 1;
setsub32(dst, cpu_state.regs[cpu_reg].l); setsub32(dst, cpu_state.regs[cpu_reg].l);
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); }
else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); 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); PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1,0,0, 1);
return 0; return 0;
} }
@@ -493,8 +493,8 @@ static int opTEST_b_a16(uint32_t fetchdat)
temp = geteab(); if (cpu_state.abrt) return 1; temp = geteab(); if (cpu_state.abrt) return 1;
temp2 = getr8(cpu_reg); temp2 = getr8(cpu_reg);
setznp8(temp & temp2); setznp8(temp & temp2);
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); }
else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); 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); PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0);
return 0; return 0;
} }
@@ -507,8 +507,8 @@ static int opTEST_b_a32(uint32_t fetchdat)
temp = geteab(); if (cpu_state.abrt) return 1; temp = geteab(); if (cpu_state.abrt) return 1;
temp2 = getr8(cpu_reg); temp2 = getr8(cpu_reg);
setznp8(temp & temp2); setznp8(temp & temp2);
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); }
else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); 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); PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1);
return 0; return 0;
} }
@@ -522,8 +522,8 @@ static int opTEST_w_a16(uint32_t fetchdat)
temp = geteaw(); if (cpu_state.abrt) return 1; temp = geteaw(); if (cpu_state.abrt) return 1;
temp2 = cpu_state.regs[cpu_reg].w; temp2 = cpu_state.regs[cpu_reg].w;
setznp16(temp & temp2); setznp16(temp & temp2);
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); }
else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); 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); PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0);
return 0; return 0;
} }
@@ -536,8 +536,8 @@ static int opTEST_w_a32(uint32_t fetchdat)
temp = geteaw(); if (cpu_state.abrt) return 1; temp = geteaw(); if (cpu_state.abrt) return 1;
temp2 = cpu_state.regs[cpu_reg].w; temp2 = cpu_state.regs[cpu_reg].w;
setznp16(temp & temp2); setznp16(temp & temp2);
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); }
else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); 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); PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1);
return 0; return 0;
} }
@@ -551,8 +551,8 @@ static int opTEST_l_a16(uint32_t fetchdat)
temp = geteal(); if (cpu_state.abrt) return 1; temp = geteal(); if (cpu_state.abrt) return 1;
temp2 = cpu_state.regs[cpu_reg].l; temp2 = cpu_state.regs[cpu_reg].l;
setznp32(temp & temp2); setznp32(temp & temp2);
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); }
else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); 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); PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0,(cpu_mod == 3) ? 0 : 1,0,0, 0);
return 0; return 0;
} }
@@ -565,8 +565,8 @@ static int opTEST_l_a32(uint32_t fetchdat)
temp = geteal(); if (cpu_state.abrt) return 1; temp = geteal(); if (cpu_state.abrt) return 1;
temp2 = cpu_state.regs[cpu_reg].l; temp2 = cpu_state.regs[cpu_reg].l;
setznp32(temp & temp2); setznp32(temp & temp2);
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); }
else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); 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); PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0,(cpu_mod == 3) ? 0 : 1,0,0, 1);
return 0; return 0;
} }
@@ -643,8 +643,8 @@ static int opTEST_EAX(uint32_t fetchdat)
break; \ break; \
case 0x38: /*CMP ea, #*/ \ case 0x38: /*CMP ea, #*/ \
setsub ## flag_width(dst, src); \ setsub ## flag_width(dst, src); \
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); \ if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } \
else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 7); \ else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 7); } \
break; \ break; \
} }
@@ -658,10 +658,11 @@ static int op80_a16(uint32_t fetchdat)
SEG_CHECK_WRITE(cpu_state.ea_seg); SEG_CHECK_WRITE(cpu_state.ea_seg);
src = getbyte(); if (cpu_state.abrt) return 1; src = getbyte(); if (cpu_state.abrt) return 1;
ARITH_MULTI(b, 8); 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); 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); 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; return 0;
} }
@@ -674,10 +675,11 @@ static int op80_a32(uint32_t fetchdat)
SEG_CHECK_WRITE(cpu_state.ea_seg); SEG_CHECK_WRITE(cpu_state.ea_seg);
src = getbyte(); if (cpu_state.abrt) return 1; src = getbyte(); if (cpu_state.abrt) return 1;
ARITH_MULTI(b, 8); 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); 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); 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; return 0;
} }
@@ -690,10 +692,11 @@ static int op81_w_a16(uint32_t fetchdat)
SEG_CHECK_WRITE(cpu_state.ea_seg); SEG_CHECK_WRITE(cpu_state.ea_seg);
src = getword(); if (cpu_state.abrt) return 1; src = getword(); if (cpu_state.abrt) return 1;
ARITH_MULTI(w, 16); 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); 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); 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; return 0;
} }
@@ -706,10 +709,11 @@ static int op81_w_a32(uint32_t fetchdat)
SEG_CHECK_WRITE(cpu_state.ea_seg); SEG_CHECK_WRITE(cpu_state.ea_seg);
src = getword(); if (cpu_state.abrt) return 1; src = getword(); if (cpu_state.abrt) return 1;
ARITH_MULTI(w, 16); 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); 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); 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; return 0;
} }
@@ -722,10 +726,11 @@ static int op81_l_a16(uint32_t fetchdat)
SEG_CHECK_WRITE(cpu_state.ea_seg); SEG_CHECK_WRITE(cpu_state.ea_seg);
src = getlong(); if (cpu_state.abrt) return 1; src = getlong(); if (cpu_state.abrt) return 1;
ARITH_MULTI(l, 32); 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); 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); 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; return 0;
} }
@@ -738,10 +743,11 @@ static int op81_l_a32(uint32_t fetchdat)
SEG_CHECK_WRITE(cpu_state.ea_seg); SEG_CHECK_WRITE(cpu_state.ea_seg);
src = getlong(); if (cpu_state.abrt) return 1; src = getlong(); if (cpu_state.abrt) return 1;
ARITH_MULTI(l, 32); 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); 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); 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; return 0;
} }
@@ -756,10 +762,11 @@ static int op83_w_a16(uint32_t fetchdat)
src = getbyte(); if (cpu_state.abrt) return 1; src = getbyte(); if (cpu_state.abrt) return 1;
if (src & 0x80) src |= 0xff00; if (src & 0x80) src |= 0xff00;
ARITH_MULTI(w, 16); 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); 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); 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; return 0;
} }
@@ -773,10 +780,11 @@ static int op83_w_a32(uint32_t fetchdat)
src = getbyte(); if (cpu_state.abrt) return 1; src = getbyte(); if (cpu_state.abrt) return 1;
if (src & 0x80) src |= 0xff00; if (src & 0x80) src |= 0xff00;
ARITH_MULTI(w, 16); 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); 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); 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; return 0;
} }
@@ -791,10 +799,11 @@ static int op83_l_a16(uint32_t fetchdat)
src = getbyte(); if (cpu_state.abrt) return 1; src = getbyte(); if (cpu_state.abrt) return 1;
if (src & 0x80) src |= 0xffffff00; if (src & 0x80) src |= 0xffffff00;
ARITH_MULTI(l, 32); 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); 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); 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; return 0;
} }
@@ -808,10 +817,11 @@ static int op83_l_a32(uint32_t fetchdat)
src = getbyte(); if (cpu_state.abrt) return 1; src = getbyte(); if (cpu_state.abrt) return 1;
if (src & 0x80) src |= 0xffffff00; if (src & 0x80) src |= 0xffffff00;
ARITH_MULTI(l, 32); 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); 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); 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; return 0;
} }

View File

@@ -186,8 +186,8 @@ static int opFF_w_a16(uint32_t fetchdat)
PUSH_W(cpu_state.pc); PUSH_W(cpu_state.pc);
cpu_state.pc = new_pc; cpu_state.pc = new_pc;
CPU_BLOCK_END(); CPU_BLOCK_END();
if (is486) CLOCK_CYCLES(5); if (is486) { CLOCK_CYCLES(5); }
else CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); 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_RUN((cpu_mod == 3) ? 7 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,1,0, 0);
PREFETCH_FLUSH(); PREFETCH_FLUSH();
break; break;
@@ -208,8 +208,8 @@ static int opFF_w_a16(uint32_t fetchdat)
new_pc = geteaw(); if (cpu_state.abrt) return 1; new_pc = geteaw(); if (cpu_state.abrt) return 1;
cpu_state.pc = new_pc; cpu_state.pc = new_pc;
CPU_BLOCK_END(); CPU_BLOCK_END();
if (is486) CLOCK_CYCLES(5); if (is486) { CLOCK_CYCLES(5); }
else CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); 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_RUN((cpu_mod == 3) ? 7 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0);
PREFETCH_FLUSH(); PREFETCH_FLUSH();
break; break;
@@ -285,8 +285,8 @@ static int opFF_w_a32(uint32_t fetchdat)
PUSH_W(cpu_state.pc); PUSH_W(cpu_state.pc);
cpu_state.pc = new_pc; cpu_state.pc = new_pc;
CPU_BLOCK_END(); CPU_BLOCK_END();
if (is486) CLOCK_CYCLES(5); if (is486) { CLOCK_CYCLES(5); }
else CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); 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_RUN((cpu_mod == 3) ? 7 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,1,0, 1);
PREFETCH_FLUSH(); PREFETCH_FLUSH();
break; break;
@@ -307,8 +307,8 @@ static int opFF_w_a32(uint32_t fetchdat)
new_pc = geteaw(); if (cpu_state.abrt) return 1; new_pc = geteaw(); if (cpu_state.abrt) return 1;
cpu_state.pc = new_pc; cpu_state.pc = new_pc;
CPU_BLOCK_END(); CPU_BLOCK_END();
if (is486) CLOCK_CYCLES(5); if (is486) { CLOCK_CYCLES(5); }
else CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); else { CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); }
PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 1,0,0,0, 1); PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 1,0,0,0, 1);
PREFETCH_FLUSH(); PREFETCH_FLUSH();
break; break;
@@ -385,8 +385,8 @@ static int opFF_l_a16(uint32_t fetchdat)
PUSH_L(cpu_state.pc); PUSH_L(cpu_state.pc);
cpu_state.pc = new_pc; cpu_state.pc = new_pc;
CPU_BLOCK_END(); CPU_BLOCK_END();
if (is486) CLOCK_CYCLES(5); if (is486) { CLOCK_CYCLES(5); }
else CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); 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_RUN((cpu_mod == 3) ? 7 : 10, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,1, 0);
PREFETCH_FLUSH(); PREFETCH_FLUSH();
break; break;
@@ -407,8 +407,8 @@ static int opFF_l_a16(uint32_t fetchdat)
new_pc = geteal(); if (cpu_state.abrt) return 1; new_pc = geteal(); if (cpu_state.abrt) return 1;
cpu_state.pc = new_pc; cpu_state.pc = new_pc;
CPU_BLOCK_END(); CPU_BLOCK_END();
if (is486) CLOCK_CYCLES(5); if (is486) { CLOCK_CYCLES(5); }
else CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); else { CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); }
PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 0,1,0,0, 0); PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 0,1,0,0, 0);
PREFETCH_FLUSH(); PREFETCH_FLUSH();
break; break;
@@ -484,8 +484,8 @@ static int opFF_l_a32(uint32_t fetchdat)
PUSH_L(cpu_state.pc); if (cpu_state.abrt) return 1; PUSH_L(cpu_state.pc); if (cpu_state.abrt) return 1;
cpu_state.pc = new_pc; cpu_state.pc = new_pc;
CPU_BLOCK_END(); CPU_BLOCK_END();
if (is486) CLOCK_CYCLES(5); if (is486) { CLOCK_CYCLES(5); }
else CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); 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_RUN((cpu_mod == 3) ? 7 : 10, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,1, 1);
PREFETCH_FLUSH(); PREFETCH_FLUSH();
break; break;
@@ -506,8 +506,8 @@ static int opFF_l_a32(uint32_t fetchdat)
new_pc = geteal(); if (cpu_state.abrt) return 1; new_pc = geteal(); if (cpu_state.abrt) return 1;
cpu_state.pc = new_pc; cpu_state.pc = new_pc;
CPU_BLOCK_END(); CPU_BLOCK_END();
if (is486) CLOCK_CYCLES(5); if (is486) { CLOCK_CYCLES(5); }
else CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); else { CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); }
PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 1,1,0,0, 1); PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 1,1,0,0, 1);
PREFETCH_FLUSH(); PREFETCH_FLUSH();
break; break;

View File

@@ -153,9 +153,6 @@ fx_save_stor_common(uint32_t fetchdat, int bits)
x87_settag(rec_ftw); x87_settag(rec_ftw);
CLOCK_CYCLES((cr0 & 1) ? 34 : 44); CLOCK_CYCLES((cr0 & 1) ? 34 : 44);
if (cpu_state.abrt)
x386_dynarec_log("FXRSTOR: abrt != 0\n");
} else { } else {
/* FXSAVE */ /* FXSAVE */
if ((twd & 0x0003) == 0x0003) ftwb |= 0x01; if ((twd & 0x0003) == 0x0003) ftwb |= 0x01;
@@ -217,9 +214,6 @@ fx_save_stor_common(uint32_t fetchdat, int bits)
cpu_state.ismmx = 0; cpu_state.ismmx = 0;
CLOCK_CYCLES((cr0 & 1) ? 56 : 67); CLOCK_CYCLES((cr0 & 1) ? 56 : 67);
if (cpu_state.abrt)
x386_dynarec_log("FXSAVE: abrt != 0\n");
} }
return cpu_state.abrt; return cpu_state.abrt;

View File

@@ -63,8 +63,8 @@ static int opF6_a16(uint32_t fetchdat)
case 0x08: case 0x08:
src = readmemb(cs, cpu_state.pc); cpu_state.pc++; if (cpu_state.abrt) return 1; src = readmemb(cs, cpu_state.pc); cpu_state.pc++; if (cpu_state.abrt) return 1;
setznp8(src & dst); setznp8(src & dst);
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); }
else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); 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); PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0);
break; break;
case 0x10: /*NOT b*/ case 0x10: /*NOT b*/
@@ -167,8 +167,8 @@ static int opF6_a32(uint32_t fetchdat)
case 0x08: case 0x08:
src = readmemb(cs, cpu_state.pc); cpu_state.pc++; if (cpu_state.abrt) return 1; src = readmemb(cs, cpu_state.pc); cpu_state.pc++; if (cpu_state.abrt) return 1;
setznp8(src & dst); setznp8(src & dst);
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); }
else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); 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); PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1);
break; break;
case 0x10: /*NOT b*/ case 0x10: /*NOT b*/
@@ -274,8 +274,8 @@ static int opF7_w_a16(uint32_t fetchdat)
case 0x08: case 0x08:
src = getword(); if (cpu_state.abrt) return 1; src = getword(); if (cpu_state.abrt) return 1;
setznp16(src & dst); setznp16(src & dst);
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); }
else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); 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); PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 4, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0);
break; break;
case 0x10: /*NOT w*/ case 0x10: /*NOT w*/
@@ -371,8 +371,8 @@ static int opF7_w_a32(uint32_t fetchdat)
case 0x08: case 0x08:
src = getword(); if (cpu_state.abrt) return 1; src = getword(); if (cpu_state.abrt) return 1;
setznp16(src & dst); setznp16(src & dst);
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); }
else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); 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); PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 4, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1);
break; break;
case 0x10: /*NOT w*/ case 0x10: /*NOT w*/
@@ -469,8 +469,8 @@ static int opF7_l_a16(uint32_t fetchdat)
case 0x08: case 0x08:
src = getlong(); if (cpu_state.abrt) return 1; src = getlong(); if (cpu_state.abrt) return 1;
setznp32(src & dst); setznp32(src & dst);
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); }
else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); 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); PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 5, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0);
break; break;
case 0x10: /*NOT l*/ case 0x10: /*NOT l*/
@@ -544,8 +544,8 @@ static int opF7_l_a32(uint32_t fetchdat)
case 0x08: case 0x08:
src = getlong(); if (cpu_state.abrt) return 1; src = getlong(); if (cpu_state.abrt) return 1;
setznp32(src & dst); setznp32(src & dst);
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); }
else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); 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); PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 5, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1);
break; break;
case 0x10: /*NOT l*/ case 0x10: /*NOT l*/
@@ -620,8 +620,9 @@ static int opHLT(uint32_t fetchdat)
if (!((cpu_state.flags & I_FLAG) && pic.int_pending)) if (!((cpu_state.flags & I_FLAG) && pic.int_pending))
cpu_state.pc--; cpu_state.pc--;
} }
else else {
CLOCK_CYCLES(5); CLOCK_CYCLES(5);
}
CPU_BLOCK_END(); CPU_BLOCK_END();
PREFETCH_RUN(100, 1, -1, 0,0,0,0, 0); PREFETCH_RUN(100, 1, -1, 0,0,0,0, 0);

View File

@@ -281,7 +281,7 @@ static int opMOV_AX_a16(uint32_t fetchdat)
uint16_t temp; uint16_t temp;
uint16_t addr = getwordf(); uint16_t addr = getwordf();
SEG_CHECK_READ(cpu_state.ea_seg); 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; temp = readmemw(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1;
AX = temp; AX = temp;
CLOCK_CYCLES((is486) ? 1 : 4); CLOCK_CYCLES((is486) ? 1 : 4);
@@ -305,7 +305,7 @@ static int opMOV_EAX_a16(uint32_t fetchdat)
uint32_t temp; uint32_t temp;
uint16_t addr = getwordf(); uint16_t addr = getwordf();
SEG_CHECK_READ(cpu_state.ea_seg); 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; temp = readmeml(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1;
EAX = temp; EAX = temp;
CLOCK_CYCLES((is486) ? 1 : 4); CLOCK_CYCLES((is486) ? 1 : 4);
@@ -349,7 +349,7 @@ static int opMOV_a16_AX(uint32_t fetchdat)
{ {
uint16_t addr = getwordf(); uint16_t addr = getwordf();
SEG_CHECK_WRITE(cpu_state.ea_seg); 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); writememw(cpu_state.ea_seg->base, addr, AX);
CLOCK_CYCLES((is486) ? 1 : 2); CLOCK_CYCLES((is486) ? 1 : 2);
PREFETCH_RUN(2, 3, -1, 0,0,1,0, 0); 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(); uint16_t addr = getwordf();
SEG_CHECK_WRITE(cpu_state.ea_seg); 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); writememl(cpu_state.ea_seg->base, addr, EAX);
CLOCK_CYCLES((is486) ? 1 : 2); CLOCK_CYCLES((is486) ? 1 : 2);
PREFETCH_RUN(2, 3, -1, 0,0,0,1, 0); PREFETCH_RUN(2, 3, -1, 0,0,0,1, 0);

View File

@@ -2,7 +2,8 @@
static int opREP_INSB_ ## size(uint32_t fetchdat) \ static int opREP_INSB_ ## size(uint32_t fetchdat) \
{ \ { \
int reads = 0, writes = 0, total_cycles = 0; \ int reads = 0, writes = 0, total_cycles = 0; \
uint64_t addr64 = 0x0000000000000000ULL; \ \
addr64 = 0x00000000; \
\ \
if (CNT_REG > 0) \ if (CNT_REG > 0) \
{ \ { \
@@ -11,6 +12,7 @@ static int opREP_INSB_ ## size(uint32_t fetchdat)
SEG_CHECK_WRITE(&cpu_state.seg_es); \ SEG_CHECK_WRITE(&cpu_state.seg_es); \
check_io_perm(DX); \ check_io_perm(DX); \
CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG); \ CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG); \
high_page = 0; \
do_mmut_wb(es, DEST_REG, &addr64); \ do_mmut_wb(es, DEST_REG, &addr64); \
if (cpu_state.abrt) return 1; \ if (cpu_state.abrt) return 1; \
temp = inb(DX); \ temp = inb(DX); \
@@ -34,7 +36,8 @@ static int opREP_INSB_ ## size(uint32_t fetchdat)
static int opREP_INSW_ ## size(uint32_t fetchdat) \ static int opREP_INSW_ ## size(uint32_t fetchdat) \
{ \ { \
int reads = 0, writes = 0, total_cycles = 0; \ int reads = 0, writes = 0, total_cycles = 0; \
uint64_t addr64[2]; \ \
addr64a[0] = addr64a[1] = 0x00000000; \
\ \
if (CNT_REG > 0) \ if (CNT_REG > 0) \
{ \ { \
@@ -43,11 +46,12 @@ static int opREP_INSW_ ## size(uint32_t fetchdat)
SEG_CHECK_WRITE(&cpu_state.seg_es); \ SEG_CHECK_WRITE(&cpu_state.seg_es); \
check_io_perm(DX); \ check_io_perm(DX); \
check_io_perm(DX+1); \ check_io_perm(DX+1); \
CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG + 1); \ CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \
do_mmut_ww(es, DEST_REG, addr64); \ high_page = 0; \
do_mmut_ww(es, DEST_REG, addr64a); \
if (cpu_state.abrt) return 1; \ if (cpu_state.abrt) return 1; \
temp = inw(DX); \ 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; \ if (cpu_state.flags & D_FLAG) DEST_REG -= 2; \
else 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) \ static int opREP_INSL_ ## size(uint32_t fetchdat) \
{ \ { \
int reads = 0, writes = 0, total_cycles = 0; \ 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) \ 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+1); \
check_io_perm(DX+2); \ check_io_perm(DX+2); \
check_io_perm(DX+3); \ check_io_perm(DX+3); \
CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG + 3); \ CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \
do_mmut_wl(es, DEST_REG, addr64); \ high_page = 0; \
do_mmut_wl(es, DEST_REG, addr64a); \
if (cpu_state.abrt) return 1; \ if (cpu_state.abrt) return 1; \
temp = inl(DX); \ 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; \ if (cpu_state.flags & D_FLAG) DEST_REG -= 4; \
else DEST_REG += 4; \ else DEST_REG += 4; \
@@ -135,7 +141,7 @@ static int opREP_OUTSW_ ## size(uint32_t fetchdat)
{ \ { \
uint16_t temp; \ uint16_t temp; \
SEG_CHECK_READ(cpu_state.ea_seg); \ 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; \ temp = readmemw(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \
check_io_perm(DX); \ check_io_perm(DX); \
check_io_perm(DX+1); \ check_io_perm(DX+1); \
@@ -163,7 +169,7 @@ static int opREP_OUTSL_ ## size(uint32_t fetchdat)
{ \ { \
uint32_t temp; \ uint32_t temp; \
SEG_CHECK_READ(cpu_state.ea_seg); \ 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; \ temp = readmeml(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \
check_io_perm(DX); \ check_io_perm(DX); \
check_io_perm(DX+1); \ check_io_perm(DX+1); \
@@ -190,8 +196,7 @@ static int opREP_MOVSB_ ## size(uint32_t fetchdat)
{ \ { \
int reads = 0, writes = 0, total_cycles = 0; \ int reads = 0, writes = 0, total_cycles = 0; \
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
uint64_t addr64r = 0x0000000000000000ULL; \ addr64 = addr64_2 = 0x00000000; \
uint64_t addr64w = 0x0000000000000000ULL; \
if (trap) \ if (trap) \
cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \
if (CNT_REG > 0) \ if (CNT_REG > 0) \
@@ -204,13 +209,14 @@ static int opREP_MOVSB_ ## size(uint32_t fetchdat)
uint8_t temp; \ uint8_t temp; \
\ \
CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG); \ 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; \ if (cpu_state.abrt) break; \
CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \ 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; \ if (cpu_state.abrt) break; \
temp = readmemb_n(cpu_state.ea_seg->base, SRC_REG, addr64r); 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, addr64w, temp); 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--; } \ if (cpu_state.flags & D_FLAG) { DEST_REG--; SRC_REG--; } \
else { DEST_REG++; SRC_REG++; } \ else { DEST_REG++; SRC_REG++; } \
@@ -233,8 +239,8 @@ static int opREP_MOVSW_ ## size(uint32_t fetchdat)
{ \ { \
int reads = 0, writes = 0, total_cycles = 0; \ int reads = 0, writes = 0, total_cycles = 0; \
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
uint64_t addr64r[2]; \ addr64a[0] = addr64a[1] = 0x00000000; \
uint64_t addr64w[2]; \ addr64a_2[0] = addr64a_2[1] = 0x00000000; \
if (trap) \ if (trap) \
cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \
if (CNT_REG > 0) \ if (CNT_REG > 0) \
@@ -246,14 +252,15 @@ static int opREP_MOVSW_ ## size(uint32_t fetchdat)
{ \ { \
uint16_t temp; \ uint16_t temp; \
\ \
CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 1); \ CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \
do_mmut_rw(cpu_state.ea_seg->base, SRC_REG, addr64r); \ high_page = 0; \
do_mmut_rw(cpu_state.ea_seg->base, SRC_REG, addr64a); \
if (cpu_state.abrt) break; \ if (cpu_state.abrt) break; \
CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1); \ CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \
do_mmut_ww(es, DEST_REG, addr64w); \ do_mmut_ww(es, DEST_REG, addr64a_2); \
if (cpu_state.abrt) break; \ if (cpu_state.abrt) break; \
temp = readmemw_n(cpu_state.ea_seg->base, SRC_REG, addr64r); 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, addr64w, temp); 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; } \ if (cpu_state.flags & D_FLAG) { DEST_REG -= 2; SRC_REG -= 2; } \
else { DEST_REG += 2; SRC_REG += 2; } \ else { DEST_REG += 2; SRC_REG += 2; } \
@@ -276,8 +283,8 @@ static int opREP_MOVSL_ ## size(uint32_t fetchdat)
{ \ { \
int reads = 0, writes = 0, total_cycles = 0; \ int reads = 0, writes = 0, total_cycles = 0; \
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
uint64_t addr64r[4]; \ addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; \
uint64_t addr64w[4]; \ addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; \
if (trap) \ if (trap) \
cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \
if (CNT_REG > 0) \ if (CNT_REG > 0) \
@@ -289,14 +296,15 @@ static int opREP_MOVSL_ ## size(uint32_t fetchdat)
{ \ { \
uint32_t temp; \ uint32_t temp; \
\ \
CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 3); \ CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \
do_mmut_rl(cpu_state.ea_seg->base, SRC_REG, addr64r); \ high_page = 0; \
do_mmut_rl(cpu_state.ea_seg->base, SRC_REG, addr64a); \
if (cpu_state.abrt) break; \ if (cpu_state.abrt) break; \
CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3); \ CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \
do_mmut_wl(es, DEST_REG, addr64w); \ do_mmut_wl(es, DEST_REG, addr64a_2); \
if (cpu_state.abrt) break; \ if (cpu_state.abrt) break; \
temp = readmeml_n(cpu_state.ea_seg->base, SRC_REG, addr64r); 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, addr64w, temp); 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; } \ if (cpu_state.flags & D_FLAG) { DEST_REG -= 4; SRC_REG -= 4; } \
else { 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); \ SEG_CHECK_WRITE(&cpu_state.seg_es); \
while (CNT_REG > 0) \ 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; \ writememw(es, DEST_REG, AX); if (cpu_state.abrt) return 1; \
if (cpu_state.flags & D_FLAG) DEST_REG -= 2; \ if (cpu_state.flags & D_FLAG) DEST_REG -= 2; \
else 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); \ SEG_CHECK_WRITE(&cpu_state.seg_es); \
while (CNT_REG > 0) \ 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; \ writememl(es, DEST_REG, EAX); if (cpu_state.abrt) return 1; \
if (cpu_state.flags & D_FLAG) DEST_REG -= 4; \ if (cpu_state.flags & D_FLAG) DEST_REG -= 4; \
else 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); \ SEG_CHECK_READ(cpu_state.ea_seg); \
while (CNT_REG > 0) \ 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; \ AX = readmemw(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \
if (cpu_state.flags & D_FLAG) SRC_REG -= 2; \ if (cpu_state.flags & D_FLAG) SRC_REG -= 2; \
else 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); \ SEG_CHECK_READ(cpu_state.ea_seg); \
while (CNT_REG > 0) \ 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; \ EAX = readmeml(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \
if (cpu_state.flags & D_FLAG) SRC_REG -= 4; \ if (cpu_state.flags & D_FLAG) SRC_REG -= 4; \
else 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) \ static int opREP_CMPSB_ ## size(uint32_t fetchdat) \
{ \ { \
int reads = 0, total_cycles = 0, tempz; \ int reads = 0, total_cycles = 0, tempz; \
uint64_t addr64 = 0x0000000000000000ULL; \ \
uint64_t addr642 = 0x0000000000000000ULL; \ addr64 = addr64_2 = 0x00000000; \
\ \
tempz = FV; \ tempz = FV; \
if ((CNT_REG > 0) && (FV == tempz)) \ 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.ea_seg); \
SEG_CHECK_READ(&cpu_state.seg_es); \ SEG_CHECK_READ(&cpu_state.seg_es); \
CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG); \ CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG); \
high_page = 0; \
do_mmut_rb(cpu_state.ea_seg->base, SRC_REG, &addr64); \ 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; \ if (cpu_state.abrt) return 1; \
temp = readmemb_n(cpu_state.ea_seg->base, SRC_REG, addr64); \ CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG); \
temp2 = readmemb_n(es, DEST_REG, addr642); if (cpu_state.abrt) return 1; \ 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--; } \ if (cpu_state.flags & D_FLAG) { DEST_REG--; SRC_REG--; } \
else { 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) \ static int opREP_CMPSW_ ## size(uint32_t fetchdat) \
{ \ { \
int reads = 0, total_cycles = 0, tempz; \ 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; \ tempz = FV; \
if ((CNT_REG > 0) && (FV == tempz)) \ if ((CNT_REG > 0) && (FV == tempz)) \
@@ -547,13 +558,15 @@ static int opREP_CMPSW_ ## size(uint32_t fetchdat)
uint16_t temp, temp2; \ uint16_t temp, temp2; \
SEG_CHECK_READ(cpu_state.ea_seg); \ SEG_CHECK_READ(cpu_state.ea_seg); \
SEG_CHECK_READ(&cpu_state.seg_es); \ SEG_CHECK_READ(&cpu_state.seg_es); \
CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 1); \ CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \
do_mmut_rw(cpu_state.ea_seg->base, SRC_REG, addr64); \ high_page = 0; \
CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG + 1); \ do_mmut_rw(cpu_state.ea_seg->base, SRC_REG, addr64a); \
do_mmut_rw(es, DEST_REG, addr642); \
if (cpu_state.abrt) return 1; \ if (cpu_state.abrt) return 1; \
temp = readmemw_n(cpu_state.ea_seg->base, SRC_REG, addr64); \ CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \
temp2 = readmemw_n(es, DEST_REG, addr642); if (cpu_state.abrt) return 1; \ 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; } \ if (cpu_state.flags & D_FLAG) { DEST_REG -= 2; SRC_REG -= 2; } \
else { 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) \ static int opREP_CMPSL_ ## size(uint32_t fetchdat) \
{ \ { \
int reads = 0, total_cycles = 0, tempz; \ 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; \ tempz = FV; \
if ((CNT_REG > 0) && (FV == tempz)) \ if ((CNT_REG > 0) && (FV == tempz)) \
@@ -584,13 +598,15 @@ static int opREP_CMPSL_ ## size(uint32_t fetchdat)
uint32_t temp, temp2; \ uint32_t temp, temp2; \
SEG_CHECK_READ(cpu_state.ea_seg); \ SEG_CHECK_READ(cpu_state.ea_seg); \
SEG_CHECK_READ(&cpu_state.seg_es); \ SEG_CHECK_READ(&cpu_state.seg_es); \
CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 3); \ CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \
do_mmut_rl(cpu_state.ea_seg->base, SRC_REG, addr64); \ high_page = 0; \
CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG + 3); \ do_mmut_rl(cpu_state.ea_seg->base, SRC_REG, addr64a); \
do_mmut_rl(es, DEST_REG, addr642); \
if (cpu_state.abrt) return 1; \ if (cpu_state.abrt) return 1; \
temp = readmeml_n(cpu_state.ea_seg->base, SRC_REG, addr64); \ CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \
temp2 = readmeml_n(es, DEST_REG, addr642); if (cpu_state.abrt) return 1; \ 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; } \ if (cpu_state.flags & D_FLAG) { DEST_REG -= 4; SRC_REG -= 4; } \
else { 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); \ SEG_CHECK_READ(&cpu_state.seg_es); \
while ((CNT_REG > 0) && (FV == tempz)) \ 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;\ uint16_t temp = readmemw(es, DEST_REG); if (cpu_state.abrt) break;\
setsub16(AX, temp); \ setsub16(AX, temp); \
tempz = (ZF_SET()) ? 1 : 0; \ tempz = (ZF_SET()) ? 1 : 0; \
@@ -685,7 +701,7 @@ static int opREP_SCASL_ ## size(uint32_t fetchdat)
SEG_CHECK_READ(&cpu_state.seg_es); \ SEG_CHECK_READ(&cpu_state.seg_es); \
while ((CNT_REG > 0) && (FV == tempz)) \ 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;\ uint32_t temp = readmeml(es, DEST_REG); if (cpu_state.abrt) break;\
setsub32(EAX, temp); \ setsub32(EAX, temp); \
tempz = (ZF_SET()) ? 1 : 0; \ tempz = (ZF_SET()) ? 1 : 0; \

View File

@@ -245,8 +245,8 @@ static int opPOPW_a16(uint32_t fetchdat)
else SP -= 2; else SP -= 2;
} }
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6); if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6); }
else CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5); 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); PREFETCH_RUN((cpu_mod == 3) ? 4 : 5, 2, rmdat, 1,0,(cpu_mod == 3) ? 0:1,0, 0);
return cpu_state.abrt; return cpu_state.abrt;
} }
@@ -266,8 +266,8 @@ static int opPOPW_a32(uint32_t fetchdat)
else SP -= 2; else SP -= 2;
} }
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6); if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6); }
else CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5); 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); PREFETCH_RUN((cpu_mod == 3) ? 4 : 5, 2, rmdat, 1,0,(cpu_mod == 3) ? 0:1,0, 1);
return cpu_state.abrt; return cpu_state.abrt;
} }
@@ -288,8 +288,8 @@ static int opPOPL_a16(uint32_t fetchdat)
else SP -= 4; else SP -= 4;
} }
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6); if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6); }
else CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5); 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); PREFETCH_RUN((cpu_mod == 3) ? 4 : 5, 2, rmdat, 0,1,0,(cpu_mod == 3) ? 0:1, 0);
return cpu_state.abrt; return cpu_state.abrt;
} }
@@ -309,8 +309,8 @@ static int opPOPL_a32(uint32_t fetchdat)
else SP -= 4; else SP -= 4;
} }
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6); if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6); }
else CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5); 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); PREFETCH_RUN((cpu_mod == 3) ? 4 : 5, 2, rmdat, 0,1,0,(cpu_mod == 3) ? 0:1, 1);
return cpu_state.abrt; return cpu_state.abrt;
} }
@@ -470,17 +470,16 @@ static int opLEAVE_l(uint32_t fetchdat)
} }
PUSH_SEG_OPS(CS); PUSH_SEG_OPS(CS)
PUSH_SEG_OPS(DS); PUSH_SEG_OPS(DS)
PUSH_SEG_OPS(ES); PUSH_SEG_OPS(ES)
PUSH_SEG_OPS(FS); PUSH_SEG_OPS(FS)
PUSH_SEG_OPS(GS); PUSH_SEG_OPS(GS)
PUSH_SEG_OPS(SS); PUSH_SEG_OPS(SS)
POP_SEG_OPS(DS, &cpu_state.seg_ds)
POP_SEG_OPS(DS, &cpu_state.seg_ds); POP_SEG_OPS(ES, &cpu_state.seg_es)
POP_SEG_OPS(ES, &cpu_state.seg_es); POP_SEG_OPS(FS, &cpu_state.seg_fs)
POP_SEG_OPS(FS, &cpu_state.seg_fs); POP_SEG_OPS(GS, &cpu_state.seg_gs)
POP_SEG_OPS(GS, &cpu_state.seg_gs);
static int opPOP_SS_w(uint32_t fetchdat) static int opPOP_SS_w(uint32_t fetchdat)

View File

@@ -1,17 +1,18 @@
static int opMOVSB_a16(uint32_t fetchdat) static int opMOVSB_a16(uint32_t fetchdat)
{ {
uint8_t temp; uint8_t temp;
uint64_t addr64r;
uint64_t addr64w; addr64 = addr64_2 = 0x00000000;
SEG_CHECK_READ(cpu_state.ea_seg); 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; if (cpu_state.abrt) return 1;
SEG_CHECK_WRITE(&cpu_state.seg_es); 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; if (cpu_state.abrt) return 1;
temp = readmemb_n(cpu_state.ea_seg->base, SI, addr64r); 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, addr64w, temp); 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--; } if (cpu_state.flags & D_FLAG) { DI--; SI--; }
else { DI++; SI++; } else { DI++; SI++; }
CLOCK_CYCLES(7); CLOCK_CYCLES(7);
@@ -21,17 +22,18 @@ static int opMOVSB_a16(uint32_t fetchdat)
static int opMOVSB_a32(uint32_t fetchdat) static int opMOVSB_a32(uint32_t fetchdat)
{ {
uint8_t temp; uint8_t temp;
uint64_t addr64r;
uint64_t addr64w; addr64 = addr64_2 = 0x00000000;
SEG_CHECK_READ(cpu_state.ea_seg); 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; if (cpu_state.abrt) return 1;
SEG_CHECK_WRITE(&cpu_state.seg_es); 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; if (cpu_state.abrt) return 1;
temp = readmemb_n(cpu_state.ea_seg->base, ESI, addr64r); 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, addr64w, temp); 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--; } if (cpu_state.flags & D_FLAG) { EDI--; ESI--; }
else { EDI++; ESI++; } else { EDI++; ESI++; }
CLOCK_CYCLES(7); CLOCK_CYCLES(7);
@@ -42,17 +44,19 @@ static int opMOVSB_a32(uint32_t fetchdat)
static int opMOVSW_a16(uint32_t fetchdat) static int opMOVSW_a16(uint32_t fetchdat)
{ {
uint16_t temp; 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); 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; if (cpu_state.abrt) return 1;
SEG_CHECK_WRITE(&cpu_state.seg_es); 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; if (cpu_state.abrt) return 1;
temp = readmemw_n(cpu_state.ea_seg->base, SI, addr64r); 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, addr64w, temp); 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; } if (cpu_state.flags & D_FLAG) { DI -= 2; SI -= 2; }
else { DI += 2; SI += 2; } else { DI += 2; SI += 2; }
CLOCK_CYCLES(7); CLOCK_CYCLES(7);
@@ -62,17 +66,19 @@ static int opMOVSW_a16(uint32_t fetchdat)
static int opMOVSW_a32(uint32_t fetchdat) static int opMOVSW_a32(uint32_t fetchdat)
{ {
uint16_t temp; 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); 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; if (cpu_state.abrt) return 1;
SEG_CHECK_WRITE(&cpu_state.seg_es); 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; if (cpu_state.abrt) return 1;
temp = readmemw_n(cpu_state.ea_seg->base, ESI, addr64r); 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, addr64w, temp); 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; } if (cpu_state.flags & D_FLAG) { EDI -= 2; ESI -= 2; }
else { EDI += 2; ESI += 2; } else { EDI += 2; ESI += 2; }
CLOCK_CYCLES(7); CLOCK_CYCLES(7);
@@ -83,17 +89,19 @@ static int opMOVSW_a32(uint32_t fetchdat)
static int opMOVSL_a16(uint32_t fetchdat) static int opMOVSL_a16(uint32_t fetchdat)
{ {
uint32_t temp; 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); 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; if (cpu_state.abrt) return 1;
SEG_CHECK_WRITE(&cpu_state.seg_es); 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; if (cpu_state.abrt) return 1;
temp = readmeml_n(cpu_state.ea_seg->base, SI, addr64r); 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, addr64w, temp); 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; } if (cpu_state.flags & D_FLAG) { DI -= 4; SI -= 4; }
else { DI += 4; SI += 4; } else { DI += 4; SI += 4; }
CLOCK_CYCLES(7); CLOCK_CYCLES(7);
@@ -103,17 +111,19 @@ static int opMOVSL_a16(uint32_t fetchdat)
static int opMOVSL_a32(uint32_t fetchdat) static int opMOVSL_a32(uint32_t fetchdat)
{ {
uint32_t temp; 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); 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; if (cpu_state.abrt) return 1;
SEG_CHECK_WRITE(&cpu_state.seg_es); 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; if (cpu_state.abrt) return 1;
temp = readmeml_n(cpu_state.ea_seg->base, ESI, addr64r); 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, addr64w, temp); 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; } if (cpu_state.flags & D_FLAG) { EDI -= 4; ESI -= 4; }
else { EDI += 4; ESI += 4; } else { EDI += 4; ESI += 4; }
CLOCK_CYCLES(7); CLOCK_CYCLES(7);
@@ -125,17 +135,18 @@ static int opMOVSL_a32(uint32_t fetchdat)
static int opCMPSB_a16(uint32_t fetchdat) static int opCMPSB_a16(uint32_t fetchdat)
{ {
uint8_t src, dst; uint8_t src, dst;
uint64_t addr64;
uint64_t addr642; addr64 = addr64_2 = 0x00000000;
SEG_CHECK_READ(cpu_state.ea_seg); SEG_CHECK_READ(cpu_state.ea_seg);
high_page = 0;
do_mmut_rb(cpu_state.ea_seg->base, SI, &addr64); do_mmut_rb(cpu_state.ea_seg->base, SI, &addr64);
if (cpu_state.abrt) return 1; if (cpu_state.abrt) return 1;
SEG_CHECK_READ(&cpu_state.seg_es); 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; if (cpu_state.abrt) return 1;
src = readmemb_n(cpu_state.ea_seg->base, SI, addr64); src = readmemb_n(cpu_state.ea_seg->base, SI, addr64); if (cpu_state.abrt) return 1;
dst = readmemb_n(es, DI, addr642); if (cpu_state.abrt) return 1; dst = readmemb_n(es, DI, addr64_2); if (cpu_state.abrt) return 1;
setsub8(src, dst); setsub8(src, dst);
if (cpu_state.flags & D_FLAG) { DI--; SI--; } if (cpu_state.flags & D_FLAG) { DI--; SI--; }
else { DI++; SI++; } else { DI++; SI++; }
@@ -146,17 +157,18 @@ static int opCMPSB_a16(uint32_t fetchdat)
static int opCMPSB_a32(uint32_t fetchdat) static int opCMPSB_a32(uint32_t fetchdat)
{ {
uint8_t src, dst; uint8_t src, dst;
uint64_t addr64;
uint64_t addr642; addr64 = addr64_2 = 0x00000000;
SEG_CHECK_READ(cpu_state.ea_seg); SEG_CHECK_READ(cpu_state.ea_seg);
high_page = 0;
do_mmut_rb(cpu_state.ea_seg->base, ESI, &addr64); do_mmut_rb(cpu_state.ea_seg->base, ESI, &addr64);
if (cpu_state.abrt) return 1; if (cpu_state.abrt) return 1;
SEG_CHECK_READ(&cpu_state.seg_es); 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; if (cpu_state.abrt) return 1;
src = readmemb_n(cpu_state.ea_seg->base, ESI, addr64); src = readmemb_n(cpu_state.ea_seg->base, ESI, addr64); if (cpu_state.abrt) return 1;
dst = readmemb_n(es, EDI, addr642); if (cpu_state.abrt) return 1; dst = readmemb_n(es, EDI, addr64_2); if (cpu_state.abrt) return 1;
setsub8(src, dst); setsub8(src, dst);
if (cpu_state.flags & D_FLAG) { EDI--; ESI--; } if (cpu_state.flags & D_FLAG) { EDI--; ESI--; }
else { EDI++; ESI++; } else { EDI++; ESI++; }
@@ -168,17 +180,19 @@ static int opCMPSB_a32(uint32_t fetchdat)
static int opCMPSW_a16(uint32_t fetchdat) static int opCMPSW_a16(uint32_t fetchdat)
{ {
uint16_t src, dst; 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); 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; if (cpu_state.abrt) return 1;
SEG_CHECK_READ(&cpu_state.seg_es); 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; if (cpu_state.abrt) return 1;
src = readmemw_n(cpu_state.ea_seg->base, SI, addr64); src = readmemw_n(cpu_state.ea_seg->base, SI, addr64a); if (cpu_state.abrt) return 1;
dst = readmemw_n(es, DI, addr642); if (cpu_state.abrt) return 1; dst = readmemw_n(es, DI, addr64a_2); if (cpu_state.abrt) return 1;
setsub16(src, dst); setsub16(src, dst);
if (cpu_state.flags & D_FLAG) { DI -= 2; SI -= 2; } if (cpu_state.flags & D_FLAG) { DI -= 2; SI -= 2; }
else { 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) static int opCMPSW_a32(uint32_t fetchdat)
{ {
uint16_t src, dst; 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); 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; if (cpu_state.abrt) return 1;
SEG_CHECK_READ(&cpu_state.seg_es); 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; if (cpu_state.abrt) return 1;
src = readmemw_n(cpu_state.ea_seg->base, ESI, addr64); src = readmemw_n(cpu_state.ea_seg->base, ESI, addr64a); if (cpu_state.abrt) return 1;
dst = readmemw_n(es, EDI, addr642); if (cpu_state.abrt) return 1; dst = readmemw_n(es, EDI, addr64a_2); if (cpu_state.abrt) return 1;
setsub16(src, dst); setsub16(src, dst);
if (cpu_state.flags & D_FLAG) { EDI -= 2; ESI -= 2; } if (cpu_state.flags & D_FLAG) { EDI -= 2; ESI -= 2; }
else { 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) static int opCMPSL_a16(uint32_t fetchdat)
{ {
uint32_t src, dst; 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); 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; if (cpu_state.abrt) return 1;
SEG_CHECK_READ(&cpu_state.seg_es); 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; if (cpu_state.abrt) return 1;
src = readmeml_n(cpu_state.ea_seg->base, SI, addr64); src = readmeml_n(cpu_state.ea_seg->base, SI, addr64a); if (cpu_state.abrt) return 1;
dst = readmeml_n(es, DI, addr642); if (cpu_state.abrt) return 1; dst = readmeml_n(es, DI, addr64a_2); if (cpu_state.abrt) return 1;
setsub32(src, dst); setsub32(src, dst);
if (cpu_state.flags & D_FLAG) { DI -= 4; SI -= 4; } if (cpu_state.flags & D_FLAG) { DI -= 4; SI -= 4; }
else { 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) static int opCMPSL_a32(uint32_t fetchdat)
{ {
uint32_t src, dst; 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); 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; if (cpu_state.abrt) return 1;
SEG_CHECK_READ(&cpu_state.seg_es); 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; if (cpu_state.abrt) return 1;
src = readmeml_n(cpu_state.ea_seg->base, ESI, addr64); src = readmeml_n(cpu_state.ea_seg->base, ESI, addr64a); if (cpu_state.abrt) return 1;
dst = readmeml_n(es, EDI, addr642); if (cpu_state.abrt) return 1; dst = readmeml_n(es, EDI, addr64a_2); if (cpu_state.abrt) return 1;
setsub32(src, dst); setsub32(src, dst);
if (cpu_state.flags & D_FLAG) { EDI -= 4; ESI -= 4; } if (cpu_state.flags & D_FLAG) { EDI -= 4; ESI -= 4; }
else { 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) static int opINSB_a16(uint32_t fetchdat)
{ {
uint8_t temp; uint8_t temp;
uint64_t addr64 = 0x0000000000000000ULL;
addr64 = 0x00000000;
SEG_CHECK_WRITE(&cpu_state.seg_es); SEG_CHECK_WRITE(&cpu_state.seg_es);
check_io_perm(DX); check_io_perm(DX);
high_page = 0;
do_mmut_wb(es, DI, &addr64); if (cpu_state.abrt) return 1; do_mmut_wb(es, DI, &addr64); if (cpu_state.abrt) return 1;
temp = inb(DX); temp = inb(DX);
writememb_n(es, DI, addr64, temp); if (cpu_state.abrt) return 1; 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) static int opINSB_a32(uint32_t fetchdat)
{ {
uint8_t temp; uint8_t temp;
uint64_t addr64 = 0x0000000000000000ULL;
addr64 = 0x00000000;
SEG_CHECK_WRITE(&cpu_state.seg_es); SEG_CHECK_WRITE(&cpu_state.seg_es);
check_io_perm(DX); check_io_perm(DX);
high_page = 0;
do_mmut_wb(es, EDI, &addr64); if (cpu_state.abrt) return 1; do_mmut_wb(es, EDI, &addr64); if (cpu_state.abrt) return 1;
temp = inb(DX); temp = inb(DX);
writememb_n(es, EDI, addr64, temp); if (cpu_state.abrt) return 1; 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) static int opINSW_a16(uint32_t fetchdat)
{ {
uint16_t temp; uint16_t temp;
uint64_t addr64[2];
addr64a[0] = addr64a[1] = 0x00000000;
SEG_CHECK_WRITE(&cpu_state.seg_es); SEG_CHECK_WRITE(&cpu_state.seg_es);
check_io_perm(DX); check_io_perm(DX);
check_io_perm(DX + 1); 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); 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; if (cpu_state.flags & D_FLAG) DI -= 2;
else DI += 2; else DI += 2;
CLOCK_CYCLES(15); CLOCK_CYCLES(15);
@@ -531,14 +557,16 @@ static int opINSW_a16(uint32_t fetchdat)
static int opINSW_a32(uint32_t fetchdat) static int opINSW_a32(uint32_t fetchdat)
{ {
uint16_t temp; uint16_t temp;
uint64_t addr64[2];
addr64a[0] = addr64a[1] = 0x00000000;
SEG_CHECK_WRITE(&cpu_state.seg_es); SEG_CHECK_WRITE(&cpu_state.seg_es);
high_page = 0;
check_io_perm(DX); check_io_perm(DX);
check_io_perm(DX + 1); 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); 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; if (cpu_state.flags & D_FLAG) EDI -= 2;
else EDI += 2; else EDI += 2;
CLOCK_CYCLES(15); CLOCK_CYCLES(15);
@@ -549,16 +577,18 @@ static int opINSW_a32(uint32_t fetchdat)
static int opINSL_a16(uint32_t fetchdat) static int opINSL_a16(uint32_t fetchdat)
{ {
uint32_t temp; uint32_t temp;
uint64_t addr64[4];
addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000;
SEG_CHECK_WRITE(&cpu_state.seg_es); SEG_CHECK_WRITE(&cpu_state.seg_es);
check_io_perm(DX); check_io_perm(DX);
check_io_perm(DX + 1); check_io_perm(DX + 1);
check_io_perm(DX + 2); check_io_perm(DX + 2);
check_io_perm(DX + 3); 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); 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; if (cpu_state.flags & D_FLAG) DI -= 4;
else DI += 4; else DI += 4;
CLOCK_CYCLES(15); CLOCK_CYCLES(15);
@@ -568,16 +598,18 @@ static int opINSL_a16(uint32_t fetchdat)
static int opINSL_a32(uint32_t fetchdat) static int opINSL_a32(uint32_t fetchdat)
{ {
uint32_t temp; uint32_t temp;
uint64_t addr64[4];
addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000;
SEG_CHECK_WRITE(&cpu_state.seg_es); SEG_CHECK_WRITE(&cpu_state.seg_es);
check_io_perm(DX); check_io_perm(DX);
check_io_perm(DX + 1); check_io_perm(DX + 1);
check_io_perm(DX + 2); check_io_perm(DX + 2);
check_io_perm(DX + 3); 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); 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; if (cpu_state.flags & D_FLAG) EDI -= 4;
else EDI += 4; else EDI += 4;
CLOCK_CYCLES(15); CLOCK_CYCLES(15);

View File

@@ -281,7 +281,7 @@ check_seg_valid(x86seg *s)
int valid = 1; int valid = 1;
x86seg *dt = (s->seg & 0x0004) ? &ldt : &gdt; x86seg *dt = (s->seg & 0x0004) ? &ldt : &gdt;
if (((s->seg & 0xfff8) + 7) > dt->limit) if (((s->seg & 0xfff8UL) + 7UL) > dt->limit)
valid = 0; valid = 0;
switch (s->access & 0x1f) { switch (s->access & 0x1f) {

View File

@@ -189,12 +189,10 @@ extern uint32_t rammask;
extern uint8_t *rom; extern uint8_t *rom;
extern uint32_t biosmask, biosaddr; extern uint32_t biosmask, biosaddr;
extern int readlookup[256], extern int readlookup[256];
readlookupp[256];
extern uintptr_t * readlookup2; extern uintptr_t * readlookup2;
extern int readlnext; extern int readlnext;
extern int writelookup[256], extern int writelookup[256];
writelookupp[256];
extern uintptr_t * writelookup2; extern uintptr_t * writelookup2;
extern int writelnext; extern int writelnext;
extern uint32_t ram_mapped_addr[64]; extern uint32_t ram_mapped_addr[64];
@@ -224,6 +222,7 @@ extern int readlnum,
extern int memspeed[11]; extern int memspeed[11];
extern int mmu_perm; extern int mmu_perm;
extern uint8_t high_page; /* if a high (> 4 gb) page was detected */
extern int mem_a20_state, extern int mem_a20_state,
mem_a20_alt, mem_a20_alt,
@@ -244,14 +243,14 @@ extern void writememll(uint32_t addr, uint32_t val);
extern uint64_t readmemql(uint32_t addr); extern uint64_t readmemql(uint32_t addr);
extern void writememql(uint32_t addr, uint64_t val); extern void writememql(uint32_t addr, uint64_t val);
extern uint8_t readmembl_no_mmut(uint32_t addr, uint64_t addr64); extern uint8_t readmembl_no_mmut(uint32_t addr, uint32_t a64);
extern void writemembl_no_mmut(uint32_t addr, uint64_t addr64, uint8_t val); extern void writemembl_no_mmut(uint32_t addr, uint32_t a64, uint8_t val);
extern uint16_t readmemwl_no_mmut(uint32_t addr, uint64_t *addr64); extern uint16_t readmemwl_no_mmut(uint32_t addr, uint32_t *a64);
extern void writememwl_no_mmut(uint32_t addr, uint64_t *addr64, uint16_t val); extern void writememwl_no_mmut(uint32_t addr, uint32_t *a64, uint16_t val);
extern uint32_t readmemll_no_mmut(uint32_t addr, uint64_t *addr64); extern uint32_t readmemll_no_mmut(uint32_t addr, uint32_t *a64);
extern void writememll_no_mmut(uint32_t addr, uint64_t *addr64, uint32_t val); 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 uint8_t *getpccache(uint32_t a);
extern uint64_t mmutranslatereal(uint32_t addr, int rw); extern uint64_t mmutranslatereal(uint32_t addr, int rw);

View File

@@ -80,12 +80,10 @@ uint32_t pccache;
uint8_t *pccache2; uint8_t *pccache2;
int readlnext; int readlnext;
int readlookup[256], int readlookup[256];
readlookupp[256];
uintptr_t *readlookup2; uintptr_t *readlookup2;
int writelnext; int writelnext;
int writelookup[256], int writelookup[256];
writelookupp[256];
uintptr_t *writelookup2; uintptr_t *writelookup2;
uint32_t mem_logical_addr; uint32_t mem_logical_addr;
@@ -112,8 +110,13 @@ uint64_t *byte_code_present_mask;
uint32_t purgable_page_list_head = 0; uint32_t purgable_page_list_head = 0;
int purgeable_page_count = 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. */ /* 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 *base_mapping, *last_mapping;
static mem_mapping_t *read_mapping[MEM_MAPPINGS_NO]; static mem_mapping_t *read_mapping[MEM_MAPPINGS_NO];
static mem_mapping_t *write_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. */ /* Initialize the tables for high (> 1024K) RAM. */
memset(readlookup2, 0xff, (1<<20)*sizeof(uintptr_t)); 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(writelookup2, 0xff, (1<<20)*sizeof(uintptr_t));
memset(writelookupp, 0x04, (1<<20)*sizeof(uint8_t));
readlnext = 0; readlnext = 0;
writelnext = 0; writelnext = 0;
pccache = 0xffffffff; pccache = 0xffffffff;
high_page = 0;
} }
@@ -184,11 +191,14 @@ flushmmucache(void)
for (c = 0; c < 256; c++) { for (c = 0; c < 256; c++) {
if (readlookup[c] != (int) 0xffffffff) { if (readlookup[c] != (int) 0xffffffff) {
readlookup2[readlookup[c]] = LOOKUP_INV; readlookup2[readlookup[c]] = LOOKUP_INV;
readlookupp[readlookup[c]] = 4;
readlookup[c] = 0xffffffff; readlookup[c] = 0xffffffff;
} }
if (writelookup[c] != (int) 0xffffffff) { if (writelookup[c] != (int) 0xffffffff) {
page_lookup[writelookup[c]] = NULL; page_lookup[writelookup[c]] = NULL;
page_lookupp[writelookup[c]] = 4;
writelookup2[writelookup[c]] = LOOKUP_INV; writelookup2[writelookup[c]] = LOOKUP_INV;
writelookupp[writelookup[c]] = 4;
writelookup[c] = 0xffffffff; writelookup[c] = 0xffffffff;
} }
} }
@@ -211,11 +221,14 @@ flushmmucache_nopc(void)
for (c = 0; c < 256; c++) { for (c = 0; c < 256; c++) {
if (readlookup[c] != (int) 0xffffffff) { if (readlookup[c] != (int) 0xffffffff) {
readlookup2[readlookup[c]] = LOOKUP_INV; readlookup2[readlookup[c]] = LOOKUP_INV;
readlookupp[readlookup[c]] = 4;
readlookup[c] = 0xffffffff; readlookup[c] = 0xffffffff;
} }
if (writelookup[c] != (int) 0xffffffff) { if (writelookup[c] != (int) 0xffffffff) {
page_lookup[writelookup[c]] = NULL; page_lookup[writelookup[c]] = NULL;
page_lookupp[writelookup[c]] = 4;
writelookup2[writelookup[c]] = LOOKUP_INV; writelookup2[writelookup[c]] = LOOKUP_INV;
writelookupp[writelookup[c]] = 4;
writelookup[c] = 0xffffffff; writelookup[c] = 0xffffffff;
} }
} }
@@ -230,11 +243,14 @@ flushmmucache_cr3(void)
for (c = 0; c < 256; c++) { for (c = 0; c < 256; c++) {
if (readlookup[c] != (int) 0xffffffff) { if (readlookup[c] != (int) 0xffffffff) {
readlookup2[readlookup[c]] = LOOKUP_INV; readlookup2[readlookup[c]] = LOOKUP_INV;
readlookupp[readlookup[c]] = 4;
readlookup[c] = 0xffffffff; readlookup[c] = 0xffffffff;
} }
if (writelookup[c] != (int) 0xffffffff) { if (writelookup[c] != (int) 0xffffffff) {
page_lookup[writelookup[c]] = NULL; page_lookup[writelookup[c]] = NULL;
page_lookupp[writelookup[c]] = 4;
writelookup2[writelookup[c]] = LOOKUP_INV; writelookup2[writelookup[c]] = LOOKUP_INV;
writelookupp[writelookup[c]] = 4;
writelookup[c] = 0xffffffff; writelookup[c] = 0xffffffff;
} }
} }
@@ -311,7 +327,7 @@ mmutranslatereal_normal(uint32_t addr, int rw)
} }
mmu_perm = temp & 4; mmu_perm = temp & 4;
rammap(addr2) |= 0x20; rammap(addr2) |= (rw ? 0x60 : 0x20);
return (temp & ~0x3fffff) + (addr & 0x3fffff); return (temp & ~0x3fffff) + (addr & 0x3fffff);
} }
@@ -321,8 +337,10 @@ mmutranslatereal_normal(uint32_t addr, int rw)
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; cr2 = addr;
temp &= 1; temp &= 1;
if (CPL == 3) temp |= 4; if (CPL == 3)
if (rw) temp |= 2; temp |= 4;
if (rw)
temp |= 2;
cpu_state.abrt = ABRT_PF; cpu_state.abrt = ABRT_PF;
abrt_error = temp; abrt_error = temp;
return 0xffffffffffffffffULL; return 0xffffffffffffffffULL;
@@ -385,7 +403,7 @@ mmutranslatereal_pae(uint32_t addr, int rw)
return 0xffffffffffffffffULL; return 0xffffffffffffffffULL;
} }
mmu_perm = temp & 4; mmu_perm = temp & 4;
rammap64(addr3) |= 0x20; rammap64(addr3) |= (rw ? 0x60 : 0x20);
return ((temp & ~0x1fffffULL) + (addr & 0x1fffffULL)) & 0x000000ffffffffffULL; return ((temp & ~0x1fffffULL) + (addr & 0x1fffffULL)) & 0x000000ffffffffffULL;
} }
@@ -579,8 +597,8 @@ addreadlookup(uint32_t virt, uint32_t phys)
readlookup2[virt>>12] = (uintptr_t)&ram2[a - (1 << 30)]; readlookup2[virt>>12] = (uintptr_t)&ram2[a - (1 << 30)];
else else
readlookup2[virt>>12] = (uintptr_t)&ram[a]; readlookup2[virt>>12] = (uintptr_t)&ram[a];
readlookupp[virt>>12] = mmu_perm;
readlookupp[readlnext] = mmu_perm;
readlookup[readlnext++] = virt >> 12; readlookup[readlnext++] = virt >> 12;
readlnext &= (cachesize-1); readlnext &= (cachesize-1);
@@ -608,19 +626,20 @@ addwritelookup(uint32_t virt, uint32_t phys)
#ifdef USE_NEW_DYNAREC #ifdef USE_NEW_DYNAREC
#ifdef USE_DYNAREC #ifdef USE_DYNAREC
if (pages[phys >> 12].block || (phys & ~0xfff) == recomp_page) if (pages[phys >> 12].block || (phys & ~0xfff) == recomp_page) {
#else #else
if (pages[phys >> 12].block) if (pages[phys >> 12].block) {
#endif #endif
#else #else
#ifdef USE_DYNAREC #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 #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
#endif #endif
page_lookup[virt >> 12] = &pages[phys >> 12]; page_lookup[virt >> 12] = &pages[phys >> 12];
else { page_lookupp[virt >> 12] = mmu_perm;
} else {
#if (defined __amd64__ || defined _M_X64) #if (defined __amd64__ || defined _M_X64)
a = ((uint64_t)(phys & ~0xfff) - (uint64_t)(virt & ~0xfff)); a = ((uint64_t)(phys & ~0xfff) - (uint64_t)(virt & ~0xfff));
#else #else
@@ -632,8 +651,8 @@ addwritelookup(uint32_t virt, uint32_t phys)
else else
writelookup2[virt>>12] = (uintptr_t)&ram[a]; writelookup2[virt>>12] = (uintptr_t)&ram[a];
} }
writelookupp[virt>>12] = mmu_perm;
writelookupp[writelnext] = mmu_perm;
writelookup[writelnext++] = virt >> 12; writelookup[writelnext++] = virt >> 12;
writelnext &= (cachesize - 1); writelnext &= (cachesize - 1);
@@ -768,14 +787,19 @@ write_mem_w(uint32_t addr, uint16_t val)
uint8_t uint8_t
readmembl(uint32_t addr) readmembl(uint32_t addr)
{ {
uint64_t addr64 = (uint64_t) addr;
mem_mapping_t *map; mem_mapping_t *map;
uint64_t a;
addr64 = (uint64_t) addr;
mem_logical_addr = addr; mem_logical_addr = addr;
high_page = 0;
if (cr0 >> 31) { if (cr0 >> 31) {
addr64 = mmutranslate_read(addr); a = mmutranslate_read(addr);
if (addr64 > 0xffffffffULL) addr64 = (uint32_t) a;
if (a > 0xffffffffULL)
return 0xff; return 0xff;
} }
addr = (uint32_t) (addr64 & rammask); addr = (uint32_t) (addr64 & rammask);
@@ -791,19 +815,24 @@ readmembl(uint32_t addr)
void void
writemembl(uint32_t addr, uint8_t val) writemembl(uint32_t addr, uint8_t val)
{ {
uint64_t addr64 = (uint64_t) addr;
mem_mapping_t *map; mem_mapping_t *map;
uint64_t a;
addr64 = (uint64_t) addr;
mem_logical_addr = addr; mem_logical_addr = addr;
high_page = 0;
if (page_lookup[addr>>12] && page_lookup[addr>>12]->write_b) { if (page_lookup[addr>>12] && page_lookup[addr>>12]->write_b) {
page_lookup[addr>>12]->write_b(addr, val, page_lookup[addr>>12]); page_lookup[addr>>12]->write_b(addr, val, page_lookup[addr>>12]);
return; return;
} }
if (cr0 >> 31) { if (cr0 >> 31) {
addr64 = mmutranslate_write(addr); a = mmutranslate_write(addr);
if (addr64 > 0xffffffffULL) addr64 = (uint32_t) a;
if (a > 0xffffffffULL)
return; return;
} }
addr = (uint32_t) (addr64 & rammask); 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. */ /* Read a byte from memory without MMU translation - result of previous MMU translation passed as value. */
uint8_t 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_mapping_t *map;
mem_logical_addr = addr; mem_logical_addr = addr;
if (cr0 >> 31) { if (cr0 >> 31) {
if (addr64 > 0xffffffffULL) if (cpu_state.abrt || high_page)
return 0xff; return 0xff;
addr = (uint32_t) (addr64 & rammask); addr = a64 & rammask;
} else } else
addr &= rammask; 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. */ /* Write a byte to memory without MMU translation - result of previous MMU translation passed as value. */
void 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; mem_mapping_t *map;
@@ -852,10 +881,10 @@ writemembl_no_mmut(uint32_t addr, uint64_t addr64, uint8_t val)
} }
if (cr0 >> 31) { if (cr0 >> 31) {
if (addr64 > 0xffffffffULL) if (cpu_state.abrt || high_page)
return; return;
addr = (uint32_t) (addr64 & rammask); addr = a64 & rammask;
} else } else
addr &= rammask; addr &= rammask;
@@ -868,42 +897,49 @@ writemembl_no_mmut(uint32_t addr, uint64_t addr64, uint8_t val)
uint16_t uint16_t
readmemwl(uint32_t addr) readmemwl(uint32_t addr)
{ {
uint64_t addr64[2];
mem_mapping_t *map; mem_mapping_t *map;
int i; int i;
uint64_t a;
addr64[0] = (uint64_t) addr; addr64a[0] = addr;
addr64[1] = (uint64_t) (addr + 1); addr64a[1] = addr + 1;
mem_logical_addr = addr; mem_logical_addr = addr;
high_page = 0;
if (addr & 1) { if (addr & 1) {
if (!cpu_cyrix_alignment || (addr & 7) == 7) if (!cpu_cyrix_alignment || (addr & 7) == 7)
cycles -= timing_misaligned; cycles -= timing_misaligned;
if ((addr & 0xfff) > 0xffe) { if ((addr & 0xfff) > 0xffe) {
if (cr0 >> 31) { if (cr0 >> 31) {
for (i = 0; i < 2; i++) { 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 0xffff;
} }
} }
return readmembl_no_mmut(addr, addr64[0]) | return readmembl_no_mmut(addr, addr64a[0]) |
(((uint16_t) readmembl_no_mmut(addr + 1, addr64[1])) << 8); (((uint16_t) readmembl_no_mmut(addr + 1, addr64a[1])) << 8);
} else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) } else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) {
mmu_perm = readlookupp[addr >> 12];
return *(uint16_t *)(readlookup2[addr >> 12] + addr); return *(uint16_t *)(readlookup2[addr >> 12] + addr);
} }
}
if (cr0 >> 31) { if (cr0 >> 31) {
addr64[0] = mmutranslate_read(addr); a = mmutranslate_read(addr);
if (addr64[0] > 0xffffffffULL) addr64a[0] = (uint32_t) a;
if (a > 0xffffffffULL)
return 0xffff; return 0xffff;
} else } 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]; map = read_mapping[addr >> MEM_GRANULARITY_BITS];
@@ -922,15 +958,17 @@ readmemwl(uint32_t addr)
void void
writememwl(uint32_t addr, uint16_t val) writememwl(uint32_t addr, uint16_t val)
{ {
uint64_t addr64[2];
mem_mapping_t *map; mem_mapping_t *map;
int i; int i;
uint64_t a;
addr64[0] = (uint64_t) addr; addr64a[0] = addr;
addr64[1] = (uint64_t) (addr + 1); addr64a[1] = addr + 1;
mem_logical_addr = addr; mem_logical_addr = addr;
high_page = 0;
if (addr & 1) { if (addr & 1) {
if (!cpu_cyrix_alignment || (addr & 7) == 7) if (!cpu_cyrix_alignment || (addr & 7) == 7)
cycles -= timing_misaligned; 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 /* 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. */ 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 (!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; 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 /* 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. */ their result as a parameter to be used if needed. */
writemembl_no_mmut(addr, addr64[0], val); writemembl_no_mmut(addr, addr64a[0], val);
writemembl_no_mmut(addr + 1, addr64[1], val >> 8); writemembl_no_mmut(addr + 1, addr64a[1], val >> 8);
return; return;
} else if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) { } else if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) {
mmu_perm = writelookupp[addr >> 12];
*(uint16_t *)(writelookup2[addr >> 12] + addr) = val; *(uint16_t *)(writelookup2[addr >> 12] + addr) = val;
return; return;
} }
@@ -961,17 +1001,19 @@ writememwl(uint32_t addr, uint16_t val)
if (page_lookup[addr >> 12] && page_lookup[addr >> 12]->write_w) { if (page_lookup[addr >> 12] && page_lookup[addr >> 12]->write_w) {
page_lookup[addr >> 12]->write_w(addr, val, page_lookup[addr >> 12]); page_lookup[addr >> 12]->write_w(addr, val, page_lookup[addr >> 12]);
mmu_perm = page_lookupp[addr >> 12];
return; return;
} }
if (cr0 >> 31) { if (cr0 >> 31) {
addr64[0] = mmutranslate_write(addr); a = mmutranslate_write(addr);
if (addr64[0] > 0xffffffffULL) addr64a[0] = (uint32_t) a;
return;
} else
addr64[0] = (uint64_t) addr;
addr = (uint32_t) (addr64[0] & rammask); if (a > 0xffffffffULL)
return;
}
addr = addr64a[0] & rammask;
map = write_mapping[addr >> MEM_GRANULARITY_BITS]; 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. */ /* Read a word from memory without MMU translation - results of previous MMU translation passed as array. */
uint16_t uint16_t
readmemwl_no_mmut(uint32_t addr, uint64_t *addr64) readmemwl_no_mmut(uint32_t addr, uint32_t *a64)
{ {
mem_mapping_t *map; mem_mapping_t *map;
@@ -1001,21 +1043,23 @@ readmemwl_no_mmut(uint32_t addr, uint64_t *addr64)
cycles -= timing_misaligned; cycles -= timing_misaligned;
if ((addr & 0xfff) > 0xffe) { if ((addr & 0xfff) > 0xffe) {
if (cr0 >> 31) { if (cr0 >> 31) {
if ((addr64[0] > 0xffffffffULL) || (addr64[1] > 0xffffffffULL)) if (cpu_state.abrt || high_page)
return 0xffff; return 0xffff;
} }
return readmembl_no_mmut(addr, addr64[0]) | return readmembl_no_mmut(addr, a64[0]) |
(((uint16_t) readmembl_no_mmut(addr + 1, addr64[1])) << 8); (((uint16_t) readmembl_no_mmut(addr + 1, a64[1])) << 8);
} else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) } else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) {
mmu_perm = readlookupp[addr >> 12];
return *(uint16_t *)(readlookup2[addr >> 12] + addr); return *(uint16_t *)(readlookup2[addr >> 12] + addr);
} }
}
if (cr0 >> 31) { if (cr0 >> 31) {
if (addr64[0] > 0xffffffffULL) if (cpu_state.abrt || high_page)
return 0xffff; return 0xffff;
addr = (uint32_t) (addr64[0] & rammask); addr = (uint32_t) (a64[0] & rammask);
} else } else
addr &= rammask; 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. */ /* Write a word to memory without MMU translation - results of previous MMU translation passed as array. */
void 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; mem_mapping_t *map;
@@ -1046,30 +1090,31 @@ writememwl_no_mmut(uint32_t addr, uint64_t *addr64, uint16_t val)
cycles -= timing_misaligned; cycles -= timing_misaligned;
if ((addr & 0xfff) > 0xffe) { if ((addr & 0xfff) > 0xffe) {
if (cr0 >> 31) { if (cr0 >> 31) {
if ((addr64[0] > 0xffffffffULL) || (addr64[1] > 0xffffffffULL)) if (cpu_state.abrt || high_page)
return; return;
} }
writemembl_no_mmut(addr, addr64[0], val); writemembl_no_mmut(addr, a64[0], val);
writemembl_no_mmut(addr + 1, addr64[1], val >> 8); writemembl_no_mmut(addr + 1, a64[1], val >> 8);
return; return;
} else if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) { } else if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) {
mmu_perm = writelookupp[addr >> 12];
*(uint16_t *)(writelookup2[addr >> 12] + addr) = val; *(uint16_t *)(writelookup2[addr >> 12] + addr) = val;
return; return;
} }
} else }
addr &= rammask;
if (page_lookup[addr >> 12] && page_lookup[addr >> 12]->write_w) { 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]); page_lookup[addr >> 12]->write_w(addr, val, page_lookup[addr >> 12]);
return; return;
} }
if (cr0 >> 31) { if (cr0 >> 31) {
if (addr64[0] > 0xffffffffULL) if (cpu_state.abrt || high_page)
return; return;
addr = (uint32_t) (addr64[0] & rammask); addr = (uint32_t) (a64[0] & rammask);
} else } else
addr &= rammask; addr &= rammask;
@@ -1091,47 +1136,62 @@ writememwl_no_mmut(uint32_t addr, uint64_t *addr64, uint16_t val)
uint32_t uint32_t
readmemll(uint32_t addr) readmemll(uint32_t addr)
{ {
uint64_t addr64[4];
mem_mapping_t *map; mem_mapping_t *map;
int i; int i;
uint64_t a = 0x0000000000000000ULL;
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
addr64[i] = (uint64_t) (addr + i); addr64a[i] = (uint64_t) (addr + i);
mem_logical_addr = addr; mem_logical_addr = addr;
high_page = 0;
if (addr & 3) { if (addr & 3) {
if (!cpu_cyrix_alignment || (addr & 7) > 4) if (!cpu_cyrix_alignment || (addr & 7) > 4)
cycles -= timing_misaligned; cycles -= timing_misaligned;
if ((addr & 0xfff) > 0xffc) { if ((addr & 0xfff) > 0xffc) {
if (cr0 >> 31) { if (cr0 >> 31) {
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
if ((i == 0) || !((addr + i) & 0xfff)) if (i == 0) {
addr64[i] = mmutranslate_read(addr + i); a = mmutranslate_read(addr + i);
else addr64a[i] = (uint32_t) a;
addr64[i] = (addr64[i - 1] & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); } 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; return 0xffff;
} }
} }
/* No need to waste precious CPU host cycles on mmutranslate's that were already done, just pass /* 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. */ their result as a parameter to be used if needed. */
return readmemwl_no_mmut(addr, addr64) | return readmemwl_no_mmut(addr, addr64a) |
(((uint32_t) readmemwl_no_mmut(addr + 2, &(addr64[2]))) << 16); (((uint32_t) readmemwl_no_mmut(addr + 2, &(addr64a[2]))) << 16);
} else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) } else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) {
mmu_perm = readlookupp[addr >> 12];
return *(uint32_t *)(readlookup2[addr >> 12] + addr); return *(uint32_t *)(readlookup2[addr >> 12] + addr);
} }
}
if (cr0 >> 31) { if (cr0 >> 31) {
addr64[0] = mmutranslate_read(addr); a = mmutranslate_read(addr);
if (addr64[0] > 0xffffffffULL) addr64a[0] = (uint32_t) a;
return 0xffffffff;
} else
addr64[0] = (uint64_t) addr;
addr = (uint32_t) (addr64[0] & rammask); if (a > 0xffffffffULL)
return 0xffffffff;
}
addr = addr64a[0] & rammask;
map = read_mapping[addr >> MEM_GRANULARITY_BITS]; map = read_mapping[addr >> MEM_GRANULARITY_BITS];
@@ -1155,15 +1215,17 @@ readmemll(uint32_t addr)
void void
writememll(uint32_t addr, uint32_t val) writememll(uint32_t addr, uint32_t val)
{ {
uint64_t addr64[4];
mem_mapping_t *map; mem_mapping_t *map;
int i; int i;
uint64_t a = 0x0000000000000000ULL;
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
addr64[i] = (uint64_t) (addr + i); addr64a[i] = (uint64_t) (addr + i);
mem_logical_addr = addr; mem_logical_addr = addr;
high_page = 0;
if (addr & 3) { if (addr & 3) {
if (!cpu_cyrix_alignment || (addr & 7) > 4) if (!cpu_cyrix_alignment || (addr & 7) > 4)
cycles -= timing_misaligned; 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 /* 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. */ 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 (!page_lookup[(addr + i) >> 12] || !page_lookup[(addr + i) >> 12]->write_b) {
if ((i == 0) || !((addr + i) & 0xfff)) if (i == 0) {
addr64[i] = mmutranslate_write(addr + i); a = mmutranslate_write(addr + i);
else addr64a[i] = (uint32_t) a;
addr64[i] = (addr64[i - 1] & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); } 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; 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 /* 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. */ their result as a parameter to be used if needed. */
writememwl_no_mmut(addr, &(addr64[0]), val); writememwl_no_mmut(addr, &(addr64a[0]), val);
writememwl_no_mmut(addr + 2, &(addr64[2]), val >> 16); writememwl_no_mmut(addr + 2, &(addr64a[2]), val >> 16);
return; return;
} else if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) { } else if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) {
mmu_perm = writelookupp[addr >> 12];
*(uint32_t *)(writelookup2[addr >> 12] + addr) = val; *(uint32_t *)(writelookup2[addr >> 12] + addr) = val;
return; return;
} }
} }
if (page_lookup[addr >> 12] && page_lookup[addr >> 12]->write_l) { 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, val, page_lookup[addr >> 12]);
return; return;
} }
if (cr0 >> 31) { if (cr0 >> 31) {
addr64[0] = mmutranslate_write(addr); a = mmutranslate_write(addr);
if (addr64[0] > 0xffffffffULL) addr64a[0] = (uint32_t) a;
return;
} else
addr64[0] = (uint64_t) addr;
addr = (uint32_t) (addr64[0] & rammask); if (a > 0xffffffffULL)
return;
}
addr = addr64a[0] & rammask;
map = write_mapping[addr >> MEM_GRANULARITY_BITS]; 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. */ /* Read a long from memory without MMU translation - results of previous MMU translation passed as array. */
uint32_t 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_mapping_t *map;
mem_logical_addr = addr; mem_logical_addr = addr;
@@ -1243,21 +1319,23 @@ readmemll_no_mmut(uint32_t addr, uint64_t *addr64)
cycles -= timing_misaligned; cycles -= timing_misaligned;
if ((addr & 0xfff) > 0xffc) { if ((addr & 0xfff) > 0xffc) {
if (cr0 >> 31) { if (cr0 >> 31) {
if ((addr64[0] > 0xffffffffULL) || (addr64[3] > 0xffffffffULL)) if (cpu_state.abrt || high_page)
return 0xffffffff; return 0xffffffff;
} }
return readmemwl_no_mmut(addr, addr64) | return readmemwl_no_mmut(addr, a64) |
(((uint32_t) readmemwl_no_mmut(addr + 2, &(addr64[2]))) << 16); ((uint32_t) (readmemwl_no_mmut(addr + 2, &(a64[2]))) << 16);
} else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) } else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) {
mmu_perm = readlookupp[addr >> 12];
return *(uint32_t *)(readlookup2[addr >> 12] + addr); return *(uint32_t *)(readlookup2[addr >> 12] + addr);
} }
}
if (cr0 >> 31) { if (cr0 >> 31) {
if (addr64[0] > 0xffffffffULL) if (cpu_state.abrt || high_page)
return 0xffffffff; return 0xffffffff;
addr = (uint32_t) (addr64[0] & rammask); addr = (uint32_t) (a64[0] & rammask);
} else } else
addr &= rammask; 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); ((uint32_t) (map->read_b(addr + 3, map->p)) << 24);
return 0xffffffff; return 0xffffffff;
#else
return readmemll(addr);
#endif
} }
/* Write a long to memory without MMU translation - results of previous MMU translation passed as array. */ /* Write a long to memory without MMU translation - results of previous MMU translation passed as array. */
void 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_mapping_t *map;
mem_logical_addr = addr; mem_logical_addr = addr;
@@ -1293,29 +1375,31 @@ writememll_no_mmut(uint32_t addr, uint64_t *addr64, uint32_t val)
cycles -= timing_misaligned; cycles -= timing_misaligned;
if ((addr & 0xfff) > 0xffc) { if ((addr & 0xfff) > 0xffc) {
if (cr0 >> 31) { if (cr0 >> 31) {
if ((addr64[0] > 0xffffffffULL) || (addr64[3] > 0xffffffffULL)) if (cpu_state.abrt || high_page)
return; return;
} }
writememwl_no_mmut(addr, &(addr64[0]), val); writememwl_no_mmut(addr, &(a64[0]), val);
writememwl_no_mmut(addr + 2, &(addr64[2]), val >> 16); writememwl_no_mmut(addr + 2, &(a64[2]), val >> 16);
return; return;
} else if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) { } else if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) {
mmu_perm = writelookupp[addr >> 12];
*(uint32_t *)(writelookup2[addr >> 12] + addr) = val; *(uint32_t *)(writelookup2[addr >> 12] + addr) = val;
return; return;
} }
} }
if (page_lookup[addr >> 12] && page_lookup[addr >> 12]->write_l) { 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, val, page_lookup[addr >> 12]);
return; return;
} }
if (cr0 >> 31) { if (cr0 >> 31) {
if (addr64[0] > 0xffffffffULL) if (cpu_state.abrt || high_page)
return; return;
addr = (uint32_t) (addr64[0] & rammask); addr = (uint32_t) (a64[0] & rammask);
} else } else
addr &= rammask; 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); map->write_b(addr + 3, val >> 24, map->p);
return; return;
} }
#else
writememll(addr, val);
#endif
} }
uint64_t uint64_t
readmemql(uint32_t addr) readmemql(uint32_t addr)
{ {
uint64_t addr64[8];
mem_mapping_t *map; mem_mapping_t *map;
int i, wrap_i = 1; int i;
uint64_t a = 0x0000000000000000ULL;
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
addr64[i] = (uint64_t) (addr + i); addr64a[i] = (uint64_t) (addr + i);
mem_logical_addr = addr; mem_logical_addr = addr;
high_page = 0;
if (addr & 7) { if (addr & 7) {
cycles -= timing_misaligned; cycles -= timing_misaligned;
if ((addr & 0xfff) > 0xff8) { if ((addr & 0xfff) > 0xff8) {
if (cr0 >> 31) { if (cr0 >> 31) {
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
if ((i == 0) || !((addr + i) & 0xfff)) if (i == 0) {
addr64[i] = mmutranslate_read(addr + i); a = mmutranslate_read(addr + i);
else addr64a[i] = (uint32_t) a;
addr64[i] = (addr64[wrap_i] & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); } 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; return 0xffff;
} }
} }
/* No need to waste precious CPU host cycles on mmutranslate's that were already done, just pass /* 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. */ their result as a parameter to be used if needed. */
return readmemll_no_mmut(addr, addr64) | return readmemll_no_mmut(addr, addr64a) |
(((uint64_t) readmemll_no_mmut(addr + 4, &(addr64[4]))) << 32); (((uint64_t) readmemll_no_mmut(addr + 4, &(addr64a[4]))) << 32);
} else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) } else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) {
mmu_perm = readlookupp[addr >> 12];
return *(uint64_t *)(readlookup2[addr >> 12] + addr); return *(uint64_t *)(readlookup2[addr >> 12] + addr);
} }
}
if (cr0 >> 31) { if (cr0 >> 31) {
addr64[0] = mmutranslate_read(addr); a = mmutranslate_read(addr);
if (addr64[0] > 0xffffffffULL) addr64a[0] = (uint32_t) a;
return 0xffffffffffffffffULL;
} else
addr64[0] = (uint64_t) addr;
addr = (uint32_t) (addr64[0] & rammask); if (a > 0xffffffffULL)
return 0xffffffffffffffffULL;
}
addr = addr64a[0] & rammask;
map = read_mapping[addr >> MEM_GRANULARITY_BITS]; map = read_mapping[addr >> MEM_GRANULARITY_BITS];
if (map && map->read_l) if (map && map->read_l)
@@ -1395,15 +1497,17 @@ readmemql(uint32_t addr)
void void
writememql(uint32_t addr, uint64_t val) writememql(uint32_t addr, uint64_t val)
{ {
uint64_t addr64[8];
mem_mapping_t *map; mem_mapping_t *map;
int i; int i;
uint64_t a = 0x0000000000000000ULL;
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
addr64[i] = (uint64_t) (addr + i); addr64a[i] = (uint64_t) (addr + i);
mem_logical_addr = addr; mem_logical_addr = addr;
high_page = 0;
if (addr & 7) { if (addr & 7) {
cycles -= timing_misaligned; cycles -= timing_misaligned;
if ((addr & 0xfff) > 0xff8) { 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 /* 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. */ 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 (!page_lookup[(addr + i) >> 12] || !page_lookup[(addr + i) >> 12]->write_b) {
if ((i == 0) || !((addr + i) & 0xfff)) if (i == 0) {
addr64[i] = mmutranslate_write(addr + i); a = mmutranslate_write(addr + i);
else addr64a[i] = (uint32_t) a;
addr64[i] = (addr64[i - 1] & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); } 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; 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 /* 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. */ their result as a parameter to be used if needed. */
writememll_no_mmut(addr, &(addr64[0]), val); writememll_no_mmut(addr, addr64a, val);
writememll_no_mmut(addr + 4, &(addr64[4]), val >> 32); writememll_no_mmut(addr + 4, &(addr64a[4]), val >> 32);
return; return;
} else if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) { } else if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) {
mmu_perm = writelookupp[addr >> 12];
*(uint64_t *)(writelookup2[addr >> 12] + addr) = val; *(uint64_t *)(writelookup2[addr >> 12] + addr) = val;
return; return;
} }
} }
if (page_lookup[addr >> 12] && page_lookup[addr >> 12]->write_l) { 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, val, page_lookup[addr >> 12]);
page_lookup[addr >> 12]->write_l(addr + 4, val >> 32, page_lookup[addr >> 12]); page_lookup[addr >> 12]->write_l(addr + 4, val >> 32, page_lookup[addr >> 12]);
return; return;
} }
if (cr0 >> 31) { if (cr0 >> 31) {
addr64[0] = mmutranslate_write(addr); addr64a[0] = mmutranslate_write(addr);
if (addr64[0] > 0xffffffffULL) if (addr64a[0] > 0xffffffffULL)
return; return;
} else }
addr64[0] = (uint64_t) addr;
addr = (uint32_t) (addr64[0] & rammask); addr = addr64a[0] & rammask;
map = write_mapping[addr >> MEM_GRANULARITY_BITS]; map = write_mapping[addr >> MEM_GRANULARITY_BITS];
@@ -1478,28 +1593,54 @@ writememql(uint32_t addr, uint64_t val)
void 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; 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++) { for (i = 0; i < num; i++) {
addr64[i] = (uint64_t) addr;
if (cr0 >> 31) { if (cr0 >> 31) {
if (write && ((i == 0) || !(addr & 0xfff))) if (write && ((i == 0) || !(addr & 0xfff)))
cond = (!page_lookup[addr >> 12] || !page_lookup[addr >> 12]->write_b); cond = (!page_lookup[addr >> 12] || !page_lookup[addr >> 12]->write_b);
if (cond) { 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 /* If we are on the same page, there is no need to translate again, as we can just
reuse the previous result. */ reuse the previous result. */
if ((i == 0) || !(addr & 0xfff)) { else if (i == 0) {
addr64[i] = mmutranslatereal(addr, write); a = mmutranslatereal(addr, write);
a64[i] = (uint32_t) a;
if (addr64[i] > 0xffffffffULL) high_page = high_page || (!cpu_state.abrt && (a > 0xffffffffULL));
return;
} else if ((a <= 0xffffffffULL) && pages[addr >> 12].write_b)
addr64[i] = (addr64[i - 1] & ~0xfffLL) | ((uint64_t) (addr & 0xfff)); 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++; addr++;
@@ -2660,6 +2801,7 @@ mem_reset(void)
} }
memset(page_lookup, 0x00, (1 << 20) * sizeof(page_t *)); 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)); memset(pages, 0x00, pages_sz*sizeof(page_t));
@@ -2798,8 +2940,11 @@ mem_init(void)
/* Allocate the lookup tables. */ /* Allocate the lookup tables. */
page_lookup = (page_t **)malloc((1<<20)*sizeof(page_t *)); 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)); readlookup2 = malloc((1<<20)*sizeof(uintptr_t));
readlookupp = malloc((1<<20)*sizeof(uint8_t));
writelookup2 = malloc((1<<20)*sizeof(uintptr_t)); writelookup2 = malloc((1<<20)*sizeof(uintptr_t));
writelookupp = malloc((1<<20)*sizeof(uint8_t));
} }

View File

@@ -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 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) \ 808x.o 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o $(CGTOBJ) \
x86seg.o x87.o x87_timings.o \ x86seg.o x87.o x87_timings.o \
$(DYNARECOBJ) $(DYNARECOBJ)
@@ -876,9 +876,9 @@ all: $(PROG).exe
$(PROG).exe: $(OBJ) 86Box.res $(PROG).exe: $(OBJ) 86Box.res
@echo Linking $(PROG).exe .. @echo Linking $(PROG).exe ..
@$(CC) $(LDFLAGS) -o $(PROG).exe $(OBJ) 86Box.res $(LIBS) -pipe @$(CC) $(LDFLAGS) -o $(PROG).exe $(OBJ) 86Box.res $(LIBS) -pipe
#ifneq ($(DEBUG), y) ifneq ($(DEBUG), y)
# @$(STRIP) $(PROG).exe @$(STRIP) $(PROG).exe
#endif endif
pcap_if.res: pcap_if.rc pcap_if.res: pcap_if.rc
@echo Processing $< @echo Processing $<