CPU and MMU fixes, fixes #1366 and the entire mess that is build 2900.

This commit is contained in:
OBattler
2021-04-10 19:05:12 +02:00
parent b931e81485
commit bcb2e5598e
5 changed files with 68 additions and 28 deletions

View File

@@ -39,6 +39,9 @@
#define do_mmut_rb(s,a,b) if (readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF) do_mmutranslate((s)+(a), b, 1, 0)
#define do_mmut_rw(s,a,b) if (readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1)) do_mmutranslate((s)+(a), b, 2, 0)
#define do_mmut_rl(s,a,b) if (readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3)) do_mmutranslate((s)+(a), b, 4, 0)
#define do_mmut_rb2(s,a,b) old_rl2 = readlookup2[(uint32_t)((s)+(a))>>12]; if (old_rl2==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF) do_mmutranslate((s)+(a), b, 1, 0)
#define do_mmut_rw2(s,a,b) old_rl2 = readlookup2[(uint32_t)((s)+(a))>>12]; if (old_rl2==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1)) do_mmutranslate((s)+(a), b, 2, 0)
#define do_mmut_rl2(s,a,b) old_rl2 = readlookup2[(uint32_t)((s)+(a))>>12]; if (old_rl2==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3)) do_mmutranslate((s)+(a), b, 4, 0)
#define do_mmut_wb(s,a,b) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF) do_mmutranslate((s)+(a), b, 1, 1)
#define do_mmut_ww(s,a,b) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1)) do_mmutranslate((s)+(a), b, 2, 1)

View File

@@ -519,14 +519,18 @@ static int opREP_CMPSB_ ## size(uint32_t fetchdat)
SEG_CHECK_READ(cpu_state.ea_seg); \
SEG_CHECK_READ(&cpu_state.seg_es); \
CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG); \
high_page = 0; \
high_page = uncached = 0; \
do_mmut_rb(cpu_state.ea_seg->base, SRC_REG, &addr64); \
if (cpu_state.abrt) return 1; \
CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG); \
do_mmut_rb(es, DEST_REG, &addr64_2); \
do_mmut_rb2(es, DEST_REG, &addr64_2); \
if (cpu_state.abrt) return 1; \
temp = readmemb_n(cpu_state.ea_seg->base, SRC_REG, addr64); if (cpu_state.abrt) return 1; \
if (uncached) \
readlookup2[(uint32_t)(es+DEST_REG)>>12] = old_rl2; \
temp2 = readmemb_n(es, DEST_REG, addr64_2); if (cpu_state.abrt) return 1; \
if (uncached) \
readlookup2[(uint32_t)(es+DEST_REG)>>12] = (uintptr_t) LOOKUP_INV; \
\
if (cpu_state.flags & D_FLAG) { DEST_REG--; SRC_REG--; } \
else { DEST_REG++; SRC_REG++; } \
@@ -559,14 +563,18 @@ static int opREP_CMPSW_ ## size(uint32_t fetchdat)
SEG_CHECK_READ(cpu_state.ea_seg); \
SEG_CHECK_READ(&cpu_state.seg_es); \
CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \
high_page = 0; \
high_page = uncached = 0; \
do_mmut_rw(cpu_state.ea_seg->base, SRC_REG, addr64a); \
if (cpu_state.abrt) return 1; \
CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \
do_mmut_rw(es, DEST_REG, addr64a_2); \
do_mmut_rw2(es, DEST_REG, addr64a_2); \
if (cpu_state.abrt) return 1; \
temp = readmemw_n(cpu_state.ea_seg->base, SRC_REG, addr64a); if (cpu_state.abrt) return 1; \
if (uncached) \
readlookup2[(uint32_t)(es+DEST_REG)>>12] = old_rl2; \
temp2 = readmemw_n(es, DEST_REG, addr64a_2); if (cpu_state.abrt) return 1; \
if (uncached) \
readlookup2[(uint32_t)(es+DEST_REG)>>12] = (uintptr_t) LOOKUP_INV; \
\
if (cpu_state.flags & D_FLAG) { DEST_REG -= 2; SRC_REG -= 2; } \
else { DEST_REG += 2; SRC_REG += 2; } \
@@ -599,14 +607,18 @@ static int opREP_CMPSL_ ## size(uint32_t fetchdat)
SEG_CHECK_READ(cpu_state.ea_seg); \
SEG_CHECK_READ(&cpu_state.seg_es); \
CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \
high_page = 0; \
high_page = uncached = 0; \
do_mmut_rl(cpu_state.ea_seg->base, SRC_REG, addr64a); \
if (cpu_state.abrt) return 1; \
CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \
do_mmut_rl(es, DEST_REG, addr64a_2); \
do_mmut_rl2(es, DEST_REG, addr64a_2); \
if (cpu_state.abrt) return 1; \
temp = readmeml_n(cpu_state.ea_seg->base, SRC_REG, addr64a); if (cpu_state.abrt) return 1; \
if (uncached) \
readlookup2[(uint32_t)(es+DEST_REG)>>12] = old_rl2; \
temp2 = readmeml_n(es, DEST_REG, addr64a_2); if (cpu_state.abrt) return 1; \
if (uncached) \
readlookup2[(uint32_t)(es+DEST_REG)>>12] = (uintptr_t) LOOKUP_INV; \
\
if (cpu_state.flags & D_FLAG) { DEST_REG -= 4; SRC_REG -= 4; } \
else { DEST_REG += 4; SRC_REG += 4; } \

View File

@@ -139,14 +139,18 @@ static int opCMPSB_a16(uint32_t fetchdat)
addr64 = addr64_2 = 0x00000000;
SEG_CHECK_READ(cpu_state.ea_seg);
high_page = 0;
high_page = uncached = 0;
do_mmut_rb(cpu_state.ea_seg->base, SI, &addr64);
if (cpu_state.abrt) return 1;
SEG_CHECK_READ(&cpu_state.seg_es);
do_mmut_rb(es, DI, &addr64_2);
do_mmut_rb2(es, DI, &addr64_2);
if (cpu_state.abrt) return 1;
src = readmemb_n(cpu_state.ea_seg->base, SI, addr64); if (cpu_state.abrt) return 1;
if (uncached)
readlookup2[(uint32_t)(es+DI)>>12] = old_rl2;
dst = readmemb_n(es, DI, addr64_2); if (cpu_state.abrt) return 1;
if (uncached)
readlookup2[(uint32_t)(es+DI)>>12] = (uintptr_t) LOOKUP_INV;
setsub8(src, dst);
if (cpu_state.flags & D_FLAG) { DI--; SI--; }
else { DI++; SI++; }
@@ -161,14 +165,18 @@ static int opCMPSB_a32(uint32_t fetchdat)
addr64 = addr64_2 = 0x00000000;
SEG_CHECK_READ(cpu_state.ea_seg);
high_page = 0;
high_page = uncached = 0;
do_mmut_rb(cpu_state.ea_seg->base, ESI, &addr64);
if (cpu_state.abrt) return 1;
SEG_CHECK_READ(&cpu_state.seg_es);
do_mmut_rb(es, EDI, &addr64_2);
do_mmut_rb2(es, EDI, &addr64_2);
if (cpu_state.abrt) return 1;
src = readmemb_n(cpu_state.ea_seg->base, ESI, addr64); if (cpu_state.abrt) return 1;
if (uncached)
readlookup2[(uint32_t)(es+EDI)>>12] = old_rl2;
dst = readmemb_n(es, EDI, addr64_2); if (cpu_state.abrt) return 1;
if (uncached)
readlookup2[(uint32_t)(es+EDI)>>12] = (uintptr_t) LOOKUP_INV;
setsub8(src, dst);
if (cpu_state.flags & D_FLAG) { EDI--; ESI--; }
else { EDI++; ESI++; }
@@ -185,14 +193,18 @@ static int opCMPSW_a16(uint32_t fetchdat)
addr64a_2[0] = addr64a_2[1] = 0x00000000;
SEG_CHECK_READ(cpu_state.ea_seg);
high_page = 0;
high_page = uncached = 0;
do_mmut_rw(cpu_state.ea_seg->base, SI, addr64a);
if (cpu_state.abrt) return 1;
SEG_CHECK_READ(&cpu_state.seg_es);
do_mmut_rw(es, DI, addr64a_2);
do_mmut_rw2(es, DI, addr64a_2);
if (cpu_state.abrt) return 1;
src = readmemw_n(cpu_state.ea_seg->base, SI, addr64a); if (cpu_state.abrt) return 1;
if (uncached)
readlookup2[(uint32_t)(es+DI)>>12] = old_rl2;
dst = readmemw_n(es, DI, addr64a_2); if (cpu_state.abrt) return 1;
if (uncached)
readlookup2[(uint32_t)(es+DI)>>12] = (uintptr_t) LOOKUP_INV;
setsub16(src, dst);
if (cpu_state.flags & D_FLAG) { DI -= 2; SI -= 2; }
else { DI += 2; SI += 2; }
@@ -208,14 +220,18 @@ static int opCMPSW_a32(uint32_t fetchdat)
addr64a_2[0] = addr64a_2[1] = 0x00000000;
SEG_CHECK_READ(cpu_state.ea_seg);
high_page = 0;
high_page = uncached = 0;
do_mmut_rw(cpu_state.ea_seg->base, ESI, addr64a);
if (cpu_state.abrt) return 1;
SEG_CHECK_READ(&cpu_state.seg_es);
do_mmut_rw(es, EDI, addr64a_2);
do_mmut_rw2(es, EDI, addr64a_2);
if (cpu_state.abrt) return 1;
src = readmemw_n(cpu_state.ea_seg->base, ESI, addr64a); if (cpu_state.abrt) return 1;
if (uncached)
readlookup2[(uint32_t)(es+EDI)>>12] = old_rl2;
dst = readmemw_n(es, EDI, addr64a_2); if (cpu_state.abrt) return 1;
if (uncached)
readlookup2[(uint32_t)(es+EDI)>>12] = (uintptr_t) LOOKUP_INV;
setsub16(src, dst);
if (cpu_state.flags & D_FLAG) { EDI -= 2; ESI -= 2; }
else { EDI += 2; ESI += 2; }
@@ -232,14 +248,18 @@ static int opCMPSL_a16(uint32_t fetchdat)
addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000;
SEG_CHECK_READ(cpu_state.ea_seg);
high_page = 0;
high_page = uncached = 0;
do_mmut_rl(cpu_state.ea_seg->base, SI, addr64a);
if (cpu_state.abrt) return 1;
SEG_CHECK_READ(&cpu_state.seg_es);
do_mmut_rl(es, DI, addr64a_2);
do_mmut_rl2(es, DI, addr64a_2);
if (cpu_state.abrt) return 1;
src = readmeml_n(cpu_state.ea_seg->base, SI, addr64a); if (cpu_state.abrt) return 1;
if (uncached)
readlookup2[(uint32_t)(es+DI)>>12] = old_rl2;
dst = readmeml_n(es, DI, addr64a_2); if (cpu_state.abrt) return 1;
if (uncached)
readlookup2[(uint32_t)(es+DI)>>12] = (uintptr_t) LOOKUP_INV;
setsub32(src, dst);
if (cpu_state.flags & D_FLAG) { DI -= 4; SI -= 4; }
else { DI += 4; SI += 4; }
@@ -255,14 +275,18 @@ static int opCMPSL_a32(uint32_t fetchdat)
addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000;
SEG_CHECK_READ(cpu_state.ea_seg);
high_page = 0;
high_page = uncached = 0;
do_mmut_rl(cpu_state.ea_seg->base, ESI, addr64a);
if (cpu_state.abrt) return 1;
SEG_CHECK_READ(&cpu_state.seg_es);
do_mmut_rl(es, EDI, addr64a_2);
do_mmut_rl2(es, EDI, addr64a_2);
if (cpu_state.abrt) return 1;
src = readmeml_n(cpu_state.ea_seg->base, ESI, addr64a); if (cpu_state.abrt) return 1;
if (uncached)
readlookup2[(uint32_t)(es+EDI)>>12] = old_rl2;
dst = readmeml_n(es, EDI, addr64a_2); if (cpu_state.abrt) return 1;
if (uncached)
readlookup2[(uint32_t)(es+EDI)>>12] = (uintptr_t) LOOKUP_INV;
setsub32(src, dst);
if (cpu_state.flags & D_FLAG) { EDI -= 4; ESI -= 4; }
else { EDI += 4; ESI += 4; }

View File

@@ -191,6 +191,8 @@ extern uint32_t biosmask, biosaddr;
extern int readlookup[256];
extern uintptr_t * readlookup2;
extern uintptr_t old_rl2;
extern uint8_t uncached;
extern int readlnext;
extern int writelookup[256];
extern uintptr_t * writelookup2;

View File

@@ -82,6 +82,8 @@ uint8_t *pccache2;
int readlnext;
int readlookup[256];
uintptr_t *readlookup2;
uintptr_t old_rl2;
uint8_t uncached = 0;
int writelnext;
int writelookup[256];
uintptr_t *writelookup2;
@@ -584,8 +586,11 @@ addreadlookup(uint32_t virt, uint32_t phys)
if (readlookup2[virt>>12] != (uintptr_t) LOOKUP_INV) return;
if (readlookup[readlnext] != (int) 0xffffffff)
if (readlookup[readlnext] != (int) 0xffffffff) {
if ((readlookup[readlnext] == ((es + DI) >> 12)) || (readlookup[readlnext] == ((es + EDI) >> 12)))
uncached = 1;
readlookup2[readlookup[readlnext]] = LOOKUP_INV;
}
#if (defined __amd64__ || defined _M_X64)
a = ((uint64_t)(phys & ~0xfff) - (uint64_t)(virt & ~0xfff));
@@ -1596,9 +1601,9 @@ void
do_mmutranslate(uint32_t addr, uint32_t *a64, int num, int write)
{
int i, cond = 1;
uint32_t old_addr = addr;
uint32_t last_addr = addr + (num - 1);
uint64_t a = 0x0000000000000000ULL;
for (i = 0; i < num; i++)
a64[i] = (uint64_t) addr;
@@ -1619,11 +1624,8 @@ do_mmutranslate(uint32_t addr, uint32_t *a64, int num, int write)
a64[i] = (uint32_t) a;
high_page = high_page || (!cpu_state.abrt && (a > 0xffffffffULL));
if ((a <= 0xffffffffULL) && pages[addr >> 12].write_b)
write ? addwritelookup(addr, a64[i]) : addreadlookup(addr, a64[i]);
} else if (!(addr & 0xfff)) {
a = mmutranslatereal(old_addr + (num - 1), write);
a = mmutranslatereal(last_addr, write);
a64[i] = (uint32_t) a;
high_page = high_page || (!cpu_state.abrt && (a64[i] > 0xffffffffULL));
@@ -1632,9 +1634,6 @@ do_mmutranslate(uint32_t addr, uint32_t *a64, int num, int write)
a = (a & 0xfffffffffffff000ULL) | ((uint64_t) (addr & 0xfff));
a64[i] = (uint32_t) a;
}
if ((a <= 0xffffffffULL) && pages[addr >> 12].write_b)
write ? addwritelookup(addr, a64[i]) : addreadlookup(addr, a64[i]);
} else {
a = (a & 0xfffffffffffff000ULL) | ((uint64_t) (addr & 0xfff));
a64[i] = (uint32_t) a;