#define MMUOP_DEBUG 2
#define DEBUG_CD32CDTVIO 0
#define EXCEPTION3_DEBUG 0
+#define CPUTRACE_DEBUG 0
#include "sysconfig.h"
#include "sysdeps.h"
static struct cputracestruct cputrace;
+#if CPUTRACE_DEBUG
+static void validate_trace (void)
+{
+ for (int i = 0; i < cputrace.memoryoffset; i++) {
+ struct cputracememory *ctm = &cputrace.ctm[i];
+ if (ctm->data == 0xdeadf00d) {
+ write_log (L"unfinished write operation %d %08x\n", i, ctm->addr);
+ }
+ }
+}
+#endif
+
+static void debug_trace (void)
+{
+ if (cputrace.writecounter > 10000 || cputrace.readcounter > 10000)
+ write_log (L"cputrace.readcounter=%d cputrace.writecounter=%d\n", cputrace.readcounter, cputrace.writecounter);
+}
+
STATIC_INLINE void clear_trace (void)
{
+#if CPUTRACE_DEBUG
+ validate_trace ();
+#endif
struct cputracememory *ctm = &cputrace.ctm[cputrace.memoryoffset++];
ctm->mode = 0;
cputrace.cyclecounter = 0;
}
static void set_trace (uaecptr addr, int accessmode, int size)
{
+#if CPUTRACE_DEBUG
+ validate_trace ();
+#endif
struct cputracememory *ctm = &cputrace.ctm[cputrace.memoryoffset++];
ctm->addr = addr;
ctm->data = 0xdeadf00d;
cputrace.writecounter++;
else
cputrace.readcounter++;
+ debug_trace ();
}
static void add_trace (uaecptr addr, uae_u32 val, int accessmode, int size)
{
+ if (cputrace.memoryoffset < 1) {
+#if CPUTRACE_DEBUG
+ write_log (L"add_trace memoryoffset=%d!\n", cputrace.memoryoffset);
+#endif
+ return;
+ }
int mode = accessmode | (size << 4);
struct cputracememory *ctm = &cputrace.ctm[cputrace.memoryoffset - 1];
ctm->addr = addr;
else
cputrace.readcounter++;
}
+ debug_trace ();
cputrace.cyclecounter_pre = cputrace.cyclecounter_post = 0;
}
static void cputracefunc_x_do_cycles_post (unsigned long cycles, uae_u32 v)
{
+ if (cputrace.memoryoffset < 1) {
+#if CPUTRACE_DEBUG
+ write_log (L"cputracefunc_x_do_cycles_post memoryoffset=%d!\n", cputrace.memoryoffset);
+#endif
+ return;
+ }
struct cputracememory *ctm = &cputrace.ctm[cputrace.memoryoffset - 1];
ctm->data = v;
cputrace.cyclecounter_post = cycles;
return v;
}
+uae_u32 REGPARAM2 x_get_disp_ea_ce020 (uae_u32 base, uae_u32 dp)
+{
+ int reg = (dp >> 12) & 15;
+ int cycles = 0;
+ uae_u32 v;
+
+ uae_s32 regd = regs.regs[reg];
+ if ((dp & 0x800) == 0)
+ regd = (uae_s32)(uae_s16)regd;
+ regd <<= (dp >> 9) & 3;
+ if (dp & 0x100) {
+ uae_s32 outer = 0;
+ if (dp & 0x80)
+ base = 0;
+ if (dp & 0x40)
+ regd = 0;
+
+ if ((dp & 0x30) == 0x20) {
+ base += (uae_s32)(uae_s16) next_iword_020ce ();
+ cycles++;
+ }
+ if ((dp & 0x30) == 0x30) {
+ base += x_next_ilong ();
+ cycles++;
+ }
+
+ if ((dp & 0x3) == 0x2) {
+ outer = (uae_s32)(uae_s16) next_iword_020ce ();
+ cycles++;
+ }
+ if ((dp & 0x3) == 0x3) {
+ outer = next_ilong_020ce ();
+ cycles++;
+ }
+
+ if ((dp & 0x4) == 0) {
+ base += regd;
+ cycles++;
+ }
+ if (dp & 0x3) {
+ base = x_get_long (base);
+ cycles++;
+ }
+ if (dp & 0x4) {
+ base += regd;
+ cycles++;
+ }
+ v = base + outer;
+ } else {
+ v = base + (uae_s32)((uae_s8)dp) + regd;
+ }
+ if (cycles && currprefs.cpu_cycle_exact)
+ x_do_cycles (cycles * cpucycleunit);
+ return v;
+}
+
STATIC_INLINE int in_rom (uaecptr pc)
{
return (munge24 (pc) & 0xFFF80000) == 0xF80000;
for (;;) {
r->instruction_pc = m68k_getpc ();
- uae_u16 opcode = x_prefetch (0);
+ uae_u16 opcode = get_word_ce020_prefetch (0);
if (cpu_tracer) {
+
+#if CPUTRACE_DEBUG
+ validate_trace ();
+#endif
memcpy (&cputrace.regs, &r->regs, 16 * sizeof (uae_u32));
cputrace.opcode = opcode;
cputrace.ir = r->ir;
else
dstbak = dst = xmalloc (uae_u8, 1000);
- save_u32 (2);
+ save_u32 (2 | 4);
save_u16 (cputrace.opcode);
for (int i = 0; i < 16; i++)
save_u32 (cputrace.regs[i]);
write_log (_T("CPUT%d: %08x %08x %08x\n"), i, cputrace.ctm[i].addr, cputrace.ctm[i].data, cputrace.ctm[i].mode);
}
save_u32 (cputrace.startcycles);
+
+ if (currprefs.cpu_model == 68020) {
+ for (int i = 0; i < CACHELINES020; i++) {
+ save_u32 (cputrace.caches020[i].data);
+ save_u32 (cputrace.caches020[i].tag);
+ save_u8 (cputrace.caches020[i].valid ? 1 : 0);
+ }
+ save_u32 (cputrace.prefetch020addr);
+ save_u32 (cputrace.cacheholdingaddr020);
+ save_u32 (cputrace.cacheholdingdata020);
+ for (int i = 0; i < CPU_PIPELINE_MAX; i++)
+ save_u16 (cputrace.prefetch020[i]);
+ }
+
*len = dst - dstbak;
cputrace.needendcycles = 1;
return dstbak;
cpu_tracer = 0;
cputrace.state = 0;
uae_u32 v = restore_u32 ();
- if (v != 0 && v != 2)
+ if (!(v & 2))
return src;
cputrace.opcode = restore_u16 ();
for (int i = 0; i < 16; i++)
cputrace.ctm[i].mode = restore_u32 ();
}
cputrace.startcycles = restore_u32 ();
+
+ if (v & 4) {
+ if (currprefs.cpu_model == 68020) {
+ for (int i = 0; i < CACHELINES020; i++) {
+ cputrace.caches020[i].data = restore_u32 ();
+ cputrace.caches020[i].tag = restore_u32 ();
+ cputrace.caches020[i].valid = restore_u8 () != 0;
+ }
+ cputrace.prefetch020addr = restore_u32 ();
+ cputrace.cacheholdingaddr020 = restore_u32 ();
+ cputrace.cacheholdingdata020 = restore_u32 ();
+ for (int i = 0; i < CPU_PIPELINE_MAX; i++)
+ cputrace.prefetch020[i] = restore_u16 ();
+ }
+ }
+
cputrace.needendcycles = 1;
- if (v && cputrace.state)
- cpu_tracer = -1;
+ if (v && cputrace.state) {
+ if (currprefs.cpu_model > 68000) {
+ if (v & 4)
+ cpu_tracer = -1;
+ } else {
+ cpu_tracer = -1;
+ }
+ }
return src;
}
return;
}
// cache miss
- data = mem_access_delay_longi_read_ce020 (addr);
+ data = x_get_long (addr);
if (!(regs.cacr & 2)) {
c->tag = tag;
c->valid = !!(regs.cacr & 1);