Reworked some memory and CPU parts to fix bugs, improve performance by getting rid of excess calls to mmutranslate(), and properly invalidate page bytes on page invalidation on new recompiler.

This commit is contained in:
OBattler
2021-03-24 19:52:44 +01:00
parent be8c03b3c0
commit 1a643ab040
9 changed files with 897 additions and 671 deletions

View File

@@ -21,16 +21,30 @@
#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 readmemw_n(s,a,b) ((readlookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1))?readmemwl_no_mmut((s)+(a),b):*(uint16_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a))))
#define readmeml_n(s,a,b) ((readlookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3))?readmemll_no_mmut((s)+(a),b):*(uint32_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a))))
#define readmemb(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF)?readmembl((s)+(a)): *(uint8_t *)(readlookup2[(uint32_t)((s)+(a))>>12] + (uintptr_t)((s) + (a))) )
#define readmemw(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1))?readmemwl((s)+(a)):*(uint16_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a))))
#define readmeml(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3))?readmemll((s)+(a)):*(uint32_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a))))
#define readmemq(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 7))?readmemql((s)+(a)):*(uint64_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uintptr_t)((s)+(a))))
#define writememb_n(s,a,b,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF) writemembl_no_mmut((s)+(a),b,v); else *(uint8_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v
#define writememw_n(s,a,b,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1)) writememwl_no_mmut((s)+(a),b,v); else *(uint16_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v
#define writememl_n(s,a,b,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3)) writememll_no_mmut((s)+(a),b,v); else *(uint32_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v
#define writememb(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF) writemembl((s)+(a),v); else *(uint8_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v
#define writememw(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1)) writememwl((s)+(a),v); else *(uint16_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v
#define writememl(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3)) writememll((s)+(a),v); else *(uint32_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v
#define writememq(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 7)) writememql((s)+(a),v); else *(uint64_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v
#define do_mmut_rb(s,a,b) if (readlookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF) do_mmutranslate((s)+(a), b, 1, 0)
#define do_mmut_rw(s,a,b) if (readlookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1)) do_mmutranslate((s)+(a), b, 2, 0)
#define do_mmut_rl(s,a,b) if (readlookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3)) do_mmutranslate((s)+(a), b, 4, 0)
#define do_mmut_wb(s,a,b) if (writelookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF) do_mmutranslate((s)+(a), b, 1, 1)
#define do_mmut_ww(s,a,b) if (writelookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1)) do_mmutranslate((s)+(a), b, 2, 1)
#define do_mmut_wl(s,a,b) if (writelookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3)) do_mmutranslate((s)+(a), b, 4, 1)
int checkio(int port);
@@ -82,12 +96,6 @@ int checkio(int port);
else \
x86np("Read from seg not present", (chseg)->seg & 0xfffc); \
return 1; \
} \
if (cr0 >> 31) { \
(void) mmutranslatereal((chseg)->base + low, 0); \
(void) mmutranslatereal((chseg)->base + high, 0); \
if (cpu_state.abrt) \
return 1; \
}
#define CHECK_READ_REP(chseg, low, high) \
@@ -103,12 +111,6 @@ int checkio(int port);
else \
x86np("Read from seg not present", (chseg)->seg & 0xfffc); \
break; \
} \
if (cr0 >> 31) { \
(void) mmutranslatereal((chseg)->base + low, 0); \
(void) mmutranslatereal((chseg)->base + high, 0); \
if (cpu_state.abrt) \
break; \
}
#define CHECK_WRITE_COMMON(chseg, low, high) \
@@ -127,13 +129,7 @@ int checkio(int port);
}
#define CHECK_WRITE(chseg, low, high) \
CHECK_WRITE_COMMON(chseg, low, high) \
if (cr0 >> 31) { \
(void) mmutranslatereal((chseg)->base + low, 1); \
(void) mmutranslatereal((chseg)->base + high, 1); \
if (cpu_state.abrt) \
return 1; \
}
CHECK_WRITE_COMMON(chseg, low, high)
#define CHECK_WRITE_REP(chseg, low, high) \
if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high)) \
@@ -148,12 +144,6 @@ int checkio(int port);
else \
x86np("Write (REP) to seg not present", (chseg)->seg & 0xfffc); \
break; \
} \
if (cr0 >> 31) { \
(void) mmutranslatereal((chseg)->base + low, 1); \
(void) mmutranslatereal((chseg)->base + high, 1); \
if (cpu_state.abrt) \
break; \
}

View File

@@ -262,6 +262,10 @@ int timing_retf_rm, timing_retf_pm, timing_retf_pm_outer;
int timing_jmp_rm, timing_jmp_pm, timing_jmp_pm_gate;
int timing_misaligned;
uint8_t do_translate = 0, do_translate2 = 0;
void (*cpu_exec)(int cycs);
static uint8_t ccr0, ccr1, ccr2, ccr3, ccr4, ccr5, ccr6;
@@ -1872,6 +1876,18 @@ cpu_set(void)
default:
x87_timings = x87_timings_486;
}
if (is386) {
#ifdef USE_DYNAREC
if (cpu_use_dynarec)
cpu_exec = exec386_dynarec;
else
#endif
cpu_exec = exec386;
} else if (cpu_s->cpu_type >= CPU_286)
cpu_exec = exec386;
else
cpu_exec = execx86;
}

View File

@@ -614,4 +614,7 @@ typedef struct
extern cyrix_t cyrix;
extern void (*cpu_exec)(int cycs);
extern uint8_t do_translate, do_translate2;
#endif /*EMU_CPU_H*/

View File

@@ -2,6 +2,7 @@
static int opREP_INSB_ ## size(uint32_t fetchdat) \
{ \
int reads = 0, writes = 0, total_cycles = 0; \
uint64_t addr64 = 0x0000000000000000ULL; \
\
if (CNT_REG > 0) \
{ \
@@ -10,8 +11,10 @@ static int opREP_INSB_ ## size(uint32_t fetchdat)
SEG_CHECK_WRITE(&cpu_state.seg_es); \
check_io_perm(DX); \
CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG); \
do_mmut_wb(es, DEST_REG, &addr64); \
if (cpu_state.abrt) return 1; \
temp = inb(DX); \
writememb(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \
writememb_n(es, DEST_REG, addr64, temp); if (cpu_state.abrt) return 1; \
\
if (cpu_state.flags & D_FLAG) DEST_REG--; \
else DEST_REG++; \
@@ -31,6 +34,7 @@ static int opREP_INSB_ ## size(uint32_t fetchdat)
static int opREP_INSW_ ## size(uint32_t fetchdat) \
{ \
int reads = 0, writes = 0, total_cycles = 0; \
uint64_t addr64[2]; \
\
if (CNT_REG > 0) \
{ \
@@ -40,8 +44,10 @@ static int opREP_INSW_ ## size(uint32_t fetchdat)
check_io_perm(DX); \
check_io_perm(DX+1); \
CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG + 1); \
do_mmut_ww(es, DEST_REG, addr64); \
if (cpu_state.abrt) return 1; \
temp = inw(DX); \
writememw(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \
writememw_n(es, DEST_REG, addr64, temp); if (cpu_state.abrt) return 1; \
\
if (cpu_state.flags & D_FLAG) DEST_REG -= 2; \
else DEST_REG += 2; \
@@ -61,6 +67,7 @@ static int opREP_INSW_ ## size(uint32_t fetchdat)
static int opREP_INSL_ ## size(uint32_t fetchdat) \
{ \
int reads = 0, writes = 0, total_cycles = 0; \
uint64_t addr64[4]; \
\
if (CNT_REG > 0) \
{ \
@@ -72,8 +79,10 @@ static int opREP_INSL_ ## size(uint32_t fetchdat)
check_io_perm(DX+2); \
check_io_perm(DX+3); \
CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG + 3); \
do_mmut_wl(es, DEST_REG, addr64); \
if (cpu_state.abrt) return 1; \
temp = inl(DX); \
writememl(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \
writememl_n(es, DEST_REG, addr64, temp); if (cpu_state.abrt) return 1; \
\
if (cpu_state.flags & D_FLAG) DEST_REG -= 4; \
else DEST_REG += 4; \
@@ -181,6 +190,8 @@ static int opREP_MOVSB_ ## size(uint32_t fetchdat)
{ \
int reads = 0, writes = 0, total_cycles = 0; \
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
uint64_t addr64r = 0x0000000000000000ULL; \
uint64_t addr64w = 0x0000000000000000ULL; \
if (trap) \
cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \
if (CNT_REG > 0) \
@@ -193,9 +204,13 @@ static int opREP_MOVSB_ ## size(uint32_t fetchdat)
uint8_t temp; \
\
CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG); \
do_mmut_rb(cpu_state.ea_seg->base, SRC_REG, &addr64r); \
if (cpu_state.abrt) break; \
CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \
temp = readmemb(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \
writememb(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \
do_mmut_wb(es, DEST_REG, &addr64w); \
if (cpu_state.abrt) break; \
temp = readmemb_n(cpu_state.ea_seg->base, SRC_REG, addr64r); if (cpu_state.abrt) return 1; \
writememb_n(es, DEST_REG, addr64w, temp); if (cpu_state.abrt) return 1; \
\
if (cpu_state.flags & D_FLAG) { DEST_REG--; SRC_REG--; } \
else { DEST_REG++; SRC_REG++; } \
@@ -218,6 +233,8 @@ static int opREP_MOVSW_ ## size(uint32_t fetchdat)
{ \
int reads = 0, writes = 0, total_cycles = 0; \
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
uint64_t addr64r[2]; \
uint64_t addr64w[2]; \
if (trap) \
cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \
if (CNT_REG > 0) \
@@ -230,9 +247,13 @@ static int opREP_MOVSW_ ## size(uint32_t fetchdat)
uint16_t temp; \
\
CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 1); \
do_mmut_rw(cpu_state.ea_seg->base, SRC_REG, addr64r); \
if (cpu_state.abrt) break; \
CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1); \
temp = readmemw(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \
writememw(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \
do_mmut_ww(es, DEST_REG, addr64w); \
if (cpu_state.abrt) break; \
temp = readmemw_n(cpu_state.ea_seg->base, SRC_REG, addr64r); if (cpu_state.abrt) return 1; \
writememw_n(es, DEST_REG, addr64w, temp); if (cpu_state.abrt) return 1; \
\
if (cpu_state.flags & D_FLAG) { DEST_REG -= 2; SRC_REG -= 2; } \
else { DEST_REG += 2; SRC_REG += 2; } \
@@ -255,6 +276,8 @@ static int opREP_MOVSL_ ## size(uint32_t fetchdat)
{ \
int reads = 0, writes = 0, total_cycles = 0; \
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
uint64_t addr64r[4]; \
uint64_t addr64w[4]; \
if (trap) \
cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \
if (CNT_REG > 0) \
@@ -267,9 +290,13 @@ static int opREP_MOVSL_ ## size(uint32_t fetchdat)
uint32_t temp; \
\
CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 3); \
do_mmut_rl(cpu_state.ea_seg->base, SRC_REG, addr64r); \
if (cpu_state.abrt) break; \
CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3); \
temp = readmeml(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \
writememl(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \
do_mmut_wl(es, DEST_REG, addr64w); \
if (cpu_state.abrt) break; \
temp = readmeml_n(cpu_state.ea_seg->base, SRC_REG, addr64r); if (cpu_state.abrt) return 1; \
writememl_n(es, DEST_REG, addr64w, temp); if (cpu_state.abrt) return 1; \
\
if (cpu_state.flags & D_FLAG) { DEST_REG -= 4; SRC_REG -= 4; } \
else { DEST_REG += 4; SRC_REG += 4; } \
@@ -467,10 +494,15 @@ static int opREP_LODSL_ ## size(uint32_t fetchdat)
} \
#define CHEK_READ(a, b, c)
#define REP_OPS_CMPS_SCAS(size, CNT_REG, SRC_REG, DEST_REG, FV) \
static int opREP_CMPSB_ ## size(uint32_t fetchdat) \
{ \
int reads = 0, total_cycles = 0, tempz; \
uint64_t addr64 = 0x0000000000000000ULL; \
uint64_t addr642 = 0x0000000000000000ULL; \
\
tempz = FV; \
if ((CNT_REG > 0) && (FV == tempz)) \
@@ -479,9 +511,12 @@ 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); \
do_mmut_rb(cpu_state.ea_seg->base, SRC_REG, &addr64); \
CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG); \
temp = readmemb(cpu_state.ea_seg->base, SRC_REG); \
temp2 = readmemb(es, DEST_REG); if (cpu_state.abrt) return 1; \
do_mmut_rb(es, DEST_REG, &addr642); \
if (cpu_state.abrt) return 1; \
temp = readmemb_n(cpu_state.ea_seg->base, SRC_REG, addr64); \
temp2 = readmemb_n(es, DEST_REG, addr642); if (cpu_state.abrt) return 1; \
\
if (cpu_state.flags & D_FLAG) { DEST_REG--; SRC_REG--; } \
else { DEST_REG++; SRC_REG++; } \
@@ -503,6 +538,8 @@ static int opREP_CMPSB_ ## size(uint32_t fetchdat)
static int opREP_CMPSW_ ## size(uint32_t fetchdat) \
{ \
int reads = 0, total_cycles = 0, tempz; \
uint64_t addr64[2]; \
uint64_t addr642[2]; \
\
tempz = FV; \
if ((CNT_REG > 0) && (FV == tempz)) \
@@ -511,9 +548,12 @@ 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 + 1); \
do_mmut_rw(cpu_state.ea_seg->base, SRC_REG, addr64); \
CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG + 1); \
temp = readmemw(cpu_state.ea_seg->base, SRC_REG); \
temp2 = readmemw(es, DEST_REG); if (cpu_state.abrt) return 1; \
do_mmut_rw(es, DEST_REG, addr642); \
if (cpu_state.abrt) return 1; \
temp = readmemw_n(cpu_state.ea_seg->base, SRC_REG, addr64); \
temp2 = readmemw_n(es, DEST_REG, addr642); if (cpu_state.abrt) return 1; \
\
if (cpu_state.flags & D_FLAG) { DEST_REG -= 2; SRC_REG -= 2; } \
else { DEST_REG += 2; SRC_REG += 2; } \
@@ -535,6 +575,8 @@ static int opREP_CMPSW_ ## size(uint32_t fetchdat)
static int opREP_CMPSL_ ## size(uint32_t fetchdat) \
{ \
int reads = 0, total_cycles = 0, tempz; \
uint64_t addr64[4]; \
uint64_t addr642[4]; \
\
tempz = FV; \
if ((CNT_REG > 0) && (FV == tempz)) \
@@ -543,9 +585,12 @@ 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 + 3); \
do_mmut_rl(cpu_state.ea_seg->base, SRC_REG, addr64); \
CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG + 3); \
temp = readmeml(cpu_state.ea_seg->base, SRC_REG); \
temp2 = readmeml(es, DEST_REG); if (cpu_state.abrt) return 1; \
do_mmut_rl(es, DEST_REG, addr642); \
if (cpu_state.abrt) return 1; \
temp = readmeml_n(cpu_state.ea_seg->base, SRC_REG, addr64); \
temp2 = readmeml_n(es, DEST_REG, addr642); if (cpu_state.abrt) return 1; \
\
if (cpu_state.flags & D_FLAG) { DEST_REG -= 4; SRC_REG -= 4; } \
else { DEST_REG += 4; SRC_REG += 4; } \

View File

@@ -1,11 +1,17 @@
static int opMOVSB_a16(uint32_t fetchdat)
{
uint8_t temp;
uint64_t addr64r;
uint64_t addr64w;
SEG_CHECK_READ(cpu_state.ea_seg);
do_mmut_rb(cpu_state.ea_seg->base, SI, &addr64r);
if (cpu_state.abrt) return 1;
SEG_CHECK_WRITE(&cpu_state.seg_es);
temp = readmemb(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1;
writememb(es, DI, temp); if (cpu_state.abrt) return 1;
do_mmut_wb(es, DI, &addr64w);
if (cpu_state.abrt) return 1;
temp = readmemb_n(cpu_state.ea_seg->base, SI, addr64r); if (cpu_state.abrt) return 1;
writememb_n(es, DI, addr64w, temp); if (cpu_state.abrt) return 1;
if (cpu_state.flags & D_FLAG) { DI--; SI--; }
else { DI++; SI++; }
CLOCK_CYCLES(7);
@@ -15,11 +21,17 @@ static int opMOVSB_a16(uint32_t fetchdat)
static int opMOVSB_a32(uint32_t fetchdat)
{
uint8_t temp;
uint64_t addr64r;
uint64_t addr64w;
SEG_CHECK_READ(cpu_state.ea_seg);
do_mmut_rb(cpu_state.ea_seg->base, ESI, &addr64r);
if (cpu_state.abrt) return 1;
SEG_CHECK_WRITE(&cpu_state.seg_es);
temp = readmemb(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1;
writememb(es, EDI, temp); if (cpu_state.abrt) return 1;
do_mmut_wb(es, EDI, &addr64w);
if (cpu_state.abrt) return 1;
temp = readmemb_n(cpu_state.ea_seg->base, ESI, addr64r); if (cpu_state.abrt) return 1;
writememb_n(es, EDI, addr64w, temp); if (cpu_state.abrt) return 1;
if (cpu_state.flags & D_FLAG) { EDI--; ESI--; }
else { EDI++; ESI++; }
CLOCK_CYCLES(7);
@@ -30,11 +42,17 @@ static int opMOVSB_a32(uint32_t fetchdat)
static int opMOVSW_a16(uint32_t fetchdat)
{
uint16_t temp;
uint64_t addr64r[2];
uint64_t addr64w[2];
SEG_CHECK_READ(cpu_state.ea_seg);
do_mmut_rw(cpu_state.ea_seg->base, SI, addr64r);
if (cpu_state.abrt) return 1;
SEG_CHECK_WRITE(&cpu_state.seg_es);
temp = readmemw(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1;
writememw(es, DI, temp); if (cpu_state.abrt) return 1;
do_mmut_ww(es, DI, addr64w);
if (cpu_state.abrt) return 1;
temp = readmemw_n(cpu_state.ea_seg->base, SI, addr64r); if (cpu_state.abrt) return 1;
writememw_n(es, DI, addr64w, temp); if (cpu_state.abrt) return 1;
if (cpu_state.flags & D_FLAG) { DI -= 2; SI -= 2; }
else { DI += 2; SI += 2; }
CLOCK_CYCLES(7);
@@ -44,11 +62,17 @@ static int opMOVSW_a16(uint32_t fetchdat)
static int opMOVSW_a32(uint32_t fetchdat)
{
uint16_t temp;
uint64_t addr64r[2];
uint64_t addr64w[2];
SEG_CHECK_READ(cpu_state.ea_seg);
do_mmut_rw(cpu_state.ea_seg->base, ESI, addr64r);
if (cpu_state.abrt) return 1;
SEG_CHECK_WRITE(&cpu_state.seg_es);
temp = readmemw(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1;
writememw(es, EDI, temp); if (cpu_state.abrt) return 1;
do_mmut_ww(es, EDI, addr64w);
if (cpu_state.abrt) return 1;
temp = readmemw_n(cpu_state.ea_seg->base, ESI, addr64r); if (cpu_state.abrt) return 1;
writememw_n(es, EDI, addr64w, temp); if (cpu_state.abrt) return 1;
if (cpu_state.flags & D_FLAG) { EDI -= 2; ESI -= 2; }
else { EDI += 2; ESI += 2; }
CLOCK_CYCLES(7);
@@ -59,11 +83,17 @@ static int opMOVSW_a32(uint32_t fetchdat)
static int opMOVSL_a16(uint32_t fetchdat)
{
uint32_t temp;
uint64_t addr64r[4];
uint64_t addr64w[4];
SEG_CHECK_READ(cpu_state.ea_seg);
do_mmut_rl(cpu_state.ea_seg->base, SI, addr64r);
if (cpu_state.abrt) return 1;
SEG_CHECK_WRITE(&cpu_state.seg_es);
temp = readmeml(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1;
writememl(es, DI, temp); if (cpu_state.abrt) return 1;
do_mmut_wl(es, DI, addr64w);
if (cpu_state.abrt) return 1;
temp = readmeml_n(cpu_state.ea_seg->base, SI, addr64r); if (cpu_state.abrt) return 1;
writememl_n(es, DI, addr64w, temp); if (cpu_state.abrt) return 1;
if (cpu_state.flags & D_FLAG) { DI -= 4; SI -= 4; }
else { DI += 4; SI += 4; }
CLOCK_CYCLES(7);
@@ -73,11 +103,17 @@ static int opMOVSL_a16(uint32_t fetchdat)
static int opMOVSL_a32(uint32_t fetchdat)
{
uint32_t temp;
uint64_t addr64r[4];
uint64_t addr64w[4];
SEG_CHECK_READ(cpu_state.ea_seg);
do_mmut_rl(cpu_state.ea_seg->base, ESI, addr64r);
if (cpu_state.abrt) return 1;
SEG_CHECK_WRITE(&cpu_state.seg_es);
temp = readmeml(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1;
writememl(es, EDI, temp); if (cpu_state.abrt) return 1;
do_mmut_wl(es, EDI, addr64w);
if (cpu_state.abrt) return 1;
temp = readmeml_n(cpu_state.ea_seg->base, ESI, addr64r); if (cpu_state.abrt) return 1;
writememl_n(es, EDI, addr64w, temp); if (cpu_state.abrt) return 1;
if (cpu_state.flags & D_FLAG) { EDI -= 4; ESI -= 4; }
else { EDI += 4; ESI += 4; }
CLOCK_CYCLES(7);
@@ -89,11 +125,17 @@ static int opMOVSL_a32(uint32_t fetchdat)
static int opCMPSB_a16(uint32_t fetchdat)
{
uint8_t src, dst;
uint64_t addr64;
uint64_t addr642;
SEG_CHECK_READ(cpu_state.ea_seg);
do_mmut_rb(cpu_state.ea_seg->base, SI, &addr64);
if (cpu_state.abrt) return 1;
SEG_CHECK_READ(&cpu_state.seg_es);
src = readmemb(cpu_state.ea_seg->base, SI);
dst = readmemb(es, DI); if (cpu_state.abrt) return 1;
do_mmut_rb(es, DI, &addr642);
if (cpu_state.abrt) return 1;
src = readmemb_n(cpu_state.ea_seg->base, SI, addr64);
dst = readmemb_n(es, DI, addr642); if (cpu_state.abrt) return 1;
setsub8(src, dst);
if (cpu_state.flags & D_FLAG) { DI--; SI--; }
else { DI++; SI++; }
@@ -104,11 +146,17 @@ static int opCMPSB_a16(uint32_t fetchdat)
static int opCMPSB_a32(uint32_t fetchdat)
{
uint8_t src, dst;
uint64_t addr64;
uint64_t addr642;
SEG_CHECK_READ(cpu_state.ea_seg);
do_mmut_rb(cpu_state.ea_seg->base, ESI, &addr64);
if (cpu_state.abrt) return 1;
SEG_CHECK_READ(&cpu_state.seg_es);
src = readmemb(cpu_state.ea_seg->base, ESI);
dst = readmemb(es, EDI); if (cpu_state.abrt) return 1;
do_mmut_rb(es, EDI, &addr642);
if (cpu_state.abrt) return 1;
src = readmemb_n(cpu_state.ea_seg->base, ESI, addr64);
dst = readmemb_n(es, EDI, addr642); if (cpu_state.abrt) return 1;
setsub8(src, dst);
if (cpu_state.flags & D_FLAG) { EDI--; ESI--; }
else { EDI++; ESI++; }
@@ -120,11 +168,17 @@ static int opCMPSB_a32(uint32_t fetchdat)
static int opCMPSW_a16(uint32_t fetchdat)
{
uint16_t src, dst;
uint64_t addr64[2];
uint64_t addr642[2];
SEG_CHECK_READ(cpu_state.ea_seg);
do_mmut_rw(cpu_state.ea_seg->base, SI, addr64);
if (cpu_state.abrt) return 1;
SEG_CHECK_READ(&cpu_state.seg_es);
src = readmemw(cpu_state.ea_seg->base, SI);
dst = readmemw(es, DI); if (cpu_state.abrt) return 1;
do_mmut_rw(es, DI, addr642);
if (cpu_state.abrt) return 1;
src = readmemw_n(cpu_state.ea_seg->base, SI, addr64);
dst = readmemw_n(es, DI, addr642); if (cpu_state.abrt) return 1;
setsub16(src, dst);
if (cpu_state.flags & D_FLAG) { DI -= 2; SI -= 2; }
else { DI += 2; SI += 2; }
@@ -135,11 +189,17 @@ static int opCMPSW_a16(uint32_t fetchdat)
static int opCMPSW_a32(uint32_t fetchdat)
{
uint16_t src, dst;
uint64_t addr64[2];
uint64_t addr642[2];
SEG_CHECK_READ(cpu_state.ea_seg);
do_mmut_rw(cpu_state.ea_seg->base, ESI, addr64);
if (cpu_state.abrt) return 1;
SEG_CHECK_READ(&cpu_state.seg_es);
src = readmemw(cpu_state.ea_seg->base, ESI);
dst = readmemw(es, EDI); if (cpu_state.abrt) return 1;
do_mmut_rw(es, EDI, addr642);
if (cpu_state.abrt) return 1;
src = readmemw_n(cpu_state.ea_seg->base, ESI, addr64);
dst = readmemw_n(es, EDI, addr642); if (cpu_state.abrt) return 1;
setsub16(src, dst);
if (cpu_state.flags & D_FLAG) { EDI -= 2; ESI -= 2; }
else { EDI += 2; ESI += 2; }
@@ -151,11 +211,17 @@ static int opCMPSW_a32(uint32_t fetchdat)
static int opCMPSL_a16(uint32_t fetchdat)
{
uint32_t src, dst;
uint64_t addr64[4];
uint64_t addr642[4];
SEG_CHECK_READ(cpu_state.ea_seg);
do_mmut_rl(cpu_state.ea_seg->base, SI, addr64);
if (cpu_state.abrt) return 1;
SEG_CHECK_READ(&cpu_state.seg_es);
src = readmeml(cpu_state.ea_seg->base, SI);
dst = readmeml(es, DI); if (cpu_state.abrt) return 1;
do_mmut_rl(es, DI, addr642);
if (cpu_state.abrt) return 1;
src = readmeml_n(cpu_state.ea_seg->base, SI, addr64);
dst = readmeml_n(es, DI, addr642); if (cpu_state.abrt) return 1;
setsub32(src, dst);
if (cpu_state.flags & D_FLAG) { DI -= 4; SI -= 4; }
else { DI += 4; SI += 4; }
@@ -166,11 +232,17 @@ static int opCMPSL_a16(uint32_t fetchdat)
static int opCMPSL_a32(uint32_t fetchdat)
{
uint32_t src, dst;
uint64_t addr64[4];
uint64_t addr642[4];
SEG_CHECK_READ(cpu_state.ea_seg);
do_mmut_rl(cpu_state.ea_seg->base, ESI, addr64);
if (cpu_state.abrt) return 1;
SEG_CHECK_READ(&cpu_state.seg_es);
src = readmeml(cpu_state.ea_seg->base, ESI);
dst = readmeml(es, EDI); if (cpu_state.abrt) return 1;
do_mmut_rl(es, EDI, addr642);
if (cpu_state.abrt) return 1;
src = readmeml_n(cpu_state.ea_seg->base, ESI, addr64);
dst = readmeml_n(es, EDI, addr642); if (cpu_state.abrt) return 1;
setsub32(src, dst);
if (cpu_state.flags & D_FLAG) { EDI -= 4; ESI -= 4; }
else { EDI += 4; ESI += 4; }
@@ -409,11 +481,13 @@ static int opSCASL_a32(uint32_t fetchdat)
static int opINSB_a16(uint32_t fetchdat)
{
uint8_t temp;
uint64_t addr64 = 0x0000000000000000ULL;
SEG_CHECK_WRITE(&cpu_state.seg_es);
check_io_perm(DX);
do_mmut_wb(es, DI, &addr64); if (cpu_state.abrt) return 1;
temp = inb(DX);
writememb(es, DI, temp); if (cpu_state.abrt) return 1;
writememb_n(es, DI, addr64, temp); if (cpu_state.abrt) return 1;
if (cpu_state.flags & D_FLAG) DI--;
else DI++;
CLOCK_CYCLES(15);
@@ -423,11 +497,13 @@ static int opINSB_a16(uint32_t fetchdat)
static int opINSB_a32(uint32_t fetchdat)
{
uint8_t temp;
uint64_t addr64 = 0x0000000000000000ULL;
SEG_CHECK_WRITE(&cpu_state.seg_es);
check_io_perm(DX);
do_mmut_wb(es, EDI, &addr64); if (cpu_state.abrt) return 1;
temp = inb(DX);
writememb(es, EDI, temp); if (cpu_state.abrt) return 1;
writememb_n(es, EDI, addr64, temp); if (cpu_state.abrt) return 1;
if (cpu_state.flags & D_FLAG) EDI--;
else EDI++;
CLOCK_CYCLES(15);
@@ -438,12 +514,14 @@ static int opINSB_a32(uint32_t fetchdat)
static int opINSW_a16(uint32_t fetchdat)
{
uint16_t temp;
uint64_t addr64[2];
SEG_CHECK_WRITE(&cpu_state.seg_es);
check_io_perm(DX);
check_io_perm(DX + 1);
do_mmut_ww(es, DI, addr64); if (cpu_state.abrt) return 1;
temp = inw(DX);
writememw(es, DI, temp); if (cpu_state.abrt) return 1;
writememw_n(es, DI, addr64, temp); if (cpu_state.abrt) return 1;
if (cpu_state.flags & D_FLAG) DI -= 2;
else DI += 2;
CLOCK_CYCLES(15);
@@ -453,12 +531,14 @@ static int opINSW_a16(uint32_t fetchdat)
static int opINSW_a32(uint32_t fetchdat)
{
uint16_t temp;
uint64_t addr64[2];
SEG_CHECK_WRITE(&cpu_state.seg_es);
check_io_perm(DX);
check_io_perm(DX + 1);
do_mmut_ww(es, EDI, addr64); if (cpu_state.abrt) return 1;
temp = inw(DX);
writememw(es, EDI, temp); if (cpu_state.abrt) return 1;
writememw_n(es, EDI, addr64, temp); if (cpu_state.abrt) return 1;
if (cpu_state.flags & D_FLAG) EDI -= 2;
else EDI += 2;
CLOCK_CYCLES(15);
@@ -469,14 +549,16 @@ static int opINSW_a32(uint32_t fetchdat)
static int opINSL_a16(uint32_t fetchdat)
{
uint32_t temp;
uint64_t addr64[4];
SEG_CHECK_WRITE(&cpu_state.seg_es);
check_io_perm(DX);
check_io_perm(DX + 1);
check_io_perm(DX + 2);
check_io_perm(DX + 3);
do_mmut_wl(es, DI, addr64); if (cpu_state.abrt) return 1;
temp = inl(DX);
writememl(es, DI, temp); if (cpu_state.abrt) return 1;
writememl_n(es, DI, addr64, temp); if (cpu_state.abrt) return 1;
if (cpu_state.flags & D_FLAG) DI -= 4;
else DI += 4;
CLOCK_CYCLES(15);
@@ -486,14 +568,16 @@ static int opINSL_a16(uint32_t fetchdat)
static int opINSL_a32(uint32_t fetchdat)
{
uint32_t temp;
uint64_t addr64[4];
SEG_CHECK_WRITE(&cpu_state.seg_es);
check_io_perm(DX);
check_io_perm(DX + 1);
check_io_perm(DX + 2);
check_io_perm(DX + 3);
do_mmut_wl(es, DI, addr64); if (cpu_state.abrt) return 1;
temp = inl(DX);
writememl(es, EDI, temp); if (cpu_state.abrt) return 1;
writememl_n(es, EDI, addr64, temp); if (cpu_state.abrt) return 1;
if (cpu_state.flags & D_FLAG) EDI -= 4;
else EDI += 4;
CLOCK_CYCLES(15);