Browse Source

some new cpu debug code

notaz 10 years ago
parent
commit
12da51c27a
12 changed files with 224 additions and 54 deletions
  1. 2 1
      Makefile
  2. 1 1
      cpu/cyclone
  3. 1 1
      cpu/cyclone_config.h
  4. 20 37
      cpu/sh2/sh2.c
  5. 32 1
      pico/debug.c
  6. 20 0
      pico/debug.h
  7. 5 3
      pico/m68kif_cyclone.s
  8. 1 1
      pico/pico.c
  9. 1 0
      pico/pico_cmn.c
  10. 15 4
      pico/pico_int.h
  11. 118 0
      pico/sek.c
  12. 8 5
      platform/common/common.mak

+ 2 - 1
Makefile

@@ -6,7 +6,8 @@ CFLAGS += -O2 -DNDEBUG
 endif
 #CFLAGS += -DEVT_LOG
 #CFLAGS += -DDRC_CMP
-#drc_debug = 4
+#cpu_cmp = 1
+#drc_debug = 3
 #profile = 1
 
 

+ 1 - 1
cpu/cyclone

@@ -1 +1 @@
-Subproject commit 194104e334f7c26015b99c862486a73be0d80162
+Subproject commit 1f9661c5a2919ba91c0f4b89985e0712871e5762

+ 1 - 1
cpu/cyclone_config.h

@@ -19,7 +19,7 @@
 #define MEMHANDLERS_NEED_CYCLES     1
 #define MEMHANDLERS_CHANGE_PC       0
 #define MEMHANDLERS_CHANGE_FLAGS    0
-#define MEMHANDLERS_CHANGE_CYCLES   0
+#define MEMHANDLERS_CHANGE_CYCLES   1
 
 #define MEMHANDLERS_DIRECT_PREFIX   "cyclone_"
 

+ 20 - 37
cpu/sh2/sh2.c

@@ -136,15 +136,6 @@ void sh2_unpack(SH2 *sh2, const unsigned char *buff)
 
 static SH2 sh2ref[2];
 static unsigned int mem_val;
-static FILE *f;
-
-enum ctl_byte {
-	CTL_MASTERSLAVE = 0x80,
-	CTL_EA = 0x82,
-	CTL_EAVAL = 0x83,
-	CTL_M68KPC = 0x84,
-	CTL_CYCLES = 0x85,
-};
 
 static unsigned int local_read32(SH2 *sh2, u32 a)
 {
@@ -176,12 +167,6 @@ static unsigned int local_read32(SH2 *sh2, u32 a)
 	return 0;
 }
 
-static void write_uint(unsigned char ctl, unsigned int v)
-{
-	fwrite(&ctl, 1, 1, f);
-	fwrite(&v, sizeof(v), 1, f);
-}
-
 void do_sh2_trace(SH2 *current, int cycles)
 {
 	static int current_slave = -1;
@@ -193,39 +178,36 @@ void do_sh2_trace(SH2 *current, int cycles)
 	u32 val;
 	int i;
 
-	if (f == NULL)
-		f = fopen("tracelog", "wb");
-
 	if (SekPc != current_m68k_pc) {
 		current_m68k_pc = SekPc;
-		write_uint(CTL_M68KPC, current_m68k_pc);
+		tl_write_uint(CTL_M68KPC, current_m68k_pc);
 	}
 
 	if (current->is_slave != current_slave) {
 		current_slave = current->is_slave;
 		v = CTL_MASTERSLAVE | current->is_slave;
-		fwrite(&v, 1, 1, f);
+		tl_write(&v, sizeof(v));
 	}
 
 	for (i = 0; i < offsetof(SH2, read8_map) / 4; i++) {
 		if (i == 17) // ppc
 			continue;
 		if (regs_a[i] != regs_o[i]) {
-			write_uint(i, regs_a[i]);
+			tl_write_uint(CTL_SH2_R + i, regs_a[i]);
 			regs_o[i] = regs_a[i];
 		}
 	}
 
 	if (current->ea != sh2o->ea) {
-		write_uint(CTL_EA, current->ea);
+		tl_write_uint(CTL_EA, current->ea);
 		sh2o->ea = current->ea;
 	}
 	val = local_read32(current, current->ea);
 	if (mem_val != val) {
-		write_uint(CTL_EAVAL, val);
+		tl_write_uint(CTL_EAVAL, val);
 		mem_val = val;
 	}
-	write_uint(CTL_CYCLES, cycles);
+	tl_write_uint(CTL_CYCLES, cycles);
 }
 
 static const char *regnames[] = {
@@ -264,17 +246,14 @@ void do_sh2_cmp(SH2 *current)
 	int cycles;
 	int i, ret;
 
-	if (f == NULL) {
-		f = fopen("tracelog", "rb");
-		sh2ref[1].is_slave = 1;
-	}
+	sh2ref[1].is_slave = 1;
 
 	while (1) {
-		ret = fread(&code, 1, 1, f);
+		ret = tl_read(&code, 1);
 		if (ret <= 0)
 			break;
 		if (code == CTL_CYCLES) {
-			fread(&cycles_o, 1, 4, f);
+			tl_read(&cycles_o, 4);
 			break;
 		}
 
@@ -284,23 +263,27 @@ void do_sh2_cmp(SH2 *current)
 			current_slave = code & 1;
 			break;
 		case CTL_EA:
-			fread(&sh2o->ea, 4, 1, f);
+			tl_read_uint(&sh2o->ea);
 			break;
 		case CTL_EAVAL:
-			fread(&current_val, 4, 1, f);
+			tl_read_uint(&current_val);
 			break;
 		case CTL_M68KPC:
-			fread(&val, 4, 1, f);
+			tl_read_uint(&val);
 			if (SekPc != val) {
 				printf("m68k: %08x %08x\n", SekPc, val);
 				bad = 1;
 			}
 			break;
 		default:
-			if (code < offsetof(SH2, read8_map) / 4)
-				fread(regs_o + code, 4, 1, f);
-			else {
-				printf("invalid code: %02x\n", code);
+			if (CTL_SH2_R <= code && code < CTL_SH2_R +
+			    offsetof(SH2, read8_map) / 4)
+			{
+				tl_read_uint(regs_o + code - CTL_SH2_R);
+			}
+			else
+			{
+				printf("wrong code: %02x\n", code);
 				goto end;
 			}
 			break;

+ 32 - 1
pico/debug.c

@@ -40,7 +40,7 @@ char *PDebugMain(void)
   sprintf(dstrp, "mode set 4: %02x\n", (r=reg[0xC])); MVP;
   sprintf(dstrp, "interlace: %i%i, cells: %i, shadow: %i\n", bit(r,2), bit(r,1), (r&0x80) ? 40 : 32, bit(r,3)); MVP;
   sprintf(dstrp, "scroll size: w: %i, h: %i  SRAM: %i; eeprom: %i (%i)\n", reg[0x10]&3, (reg[0x10]&0x30)>>4,
-  	!!(SRam.flags & SRF_ENABLED), !!(SRam.flags & SRF_EEPROM), SRam.eeprom_type); MVP;
+    !!(SRam.flags & SRF_ENABLED), !!(SRam.flags & SRF_EEPROM), SRam.eeprom_type); MVP;
   sprintf(dstrp, "sram range: %06x-%06x, reg: %02x\n", SRam.start, SRam.end, Pico.m.sram_reg); MVP;
   sprintf(dstrp, "pend int: v:%i, h:%i, vdp status: %04x\n", bit(pv->pending_ints,5), bit(pv->pending_ints,4), pv->status); MVP;
   sprintf(dstrp, "pal: %i, hw: %02x, frame#: %i, cycles: %i\n", Pico.m.pal, Pico.m.hardware, Pico.m.frame_count, SekCyclesDoneT()); MVP;
@@ -535,4 +535,35 @@ void pevt_dump(void)
 }
 #endif
 
+#if defined(CPU_CMP_R) || defined(CPU_CMP_W) || defined(DRC_CMP)
+static FILE *tl_f;
+
+void tl_write(const void *ptr, size_t size)
+{
+  if (tl_f == NULL)
+    tl_f = fopen("tracelog", "wb");
+
+  fwrite(ptr, 1, size, tl_f);
+}
+
+void tl_write_uint(unsigned char ctl, unsigned int v)
+{
+  tl_write(&ctl, sizeof(ctl));
+  tl_write(&v, sizeof(v));
+}
+
+int tl_read(void *ptr, size_t size)
+{
+  if (tl_f == NULL)
+    tl_f = fopen("tracelog", "rb");
+
+  return fread(ptr, 1, size, tl_f);
+}
+
+int tl_read_uint(void *ptr)
+{
+  return tl_read(ptr, 4);
+}
+#endif
+
 // vim:shiftwidth=2:ts=2:expandtab

+ 20 - 0
pico/debug.h

@@ -9,3 +9,23 @@ void PDebugDumpMem(void);
 void PDebugZ80Frame(void);
 void PDebugCPUStep(void);
 
+#if defined(CPU_CMP_R) || defined(CPU_CMP_W) || defined(DRC_CMP)
+enum ctl_byte {
+  CTL_68K_SLAVE = 0x02,
+  CTL_68K_PC = 0x04,
+  CTL_68K_SR = 0x05,
+  CTL_68K_CYCLES = 0x06,
+  CTL_68K_R = 0x10, // .. 0x20
+  CTL_MASTERSLAVE = 0x80,
+  CTL_EA = 0x82,
+  CTL_EAVAL = 0x83,
+  CTL_M68KPC = 0x84,
+  CTL_CYCLES = 0x85,
+  CTL_SH2_R = 0x90, // .. 0xa8
+};
+
+void tl_write(const void *ptr, size_t size);
+void tl_write_uint(unsigned char ctl, unsigned int v);
+int tl_read(void *ptr, size_t size);
+int tl_read_uint(void *ptr);
+#endif

+ 5 - 3
pico/m68kif_cyclone.s

@@ -24,16 +24,18 @@
 cyclone_checkpc:
     ldr     r1, [r7, #0x60]  @ membase
     sub     r0, r0, r1
-    bic     r0, r0, #0xff000000
-    bics    r0, r0, #1
+    and     r3, r0, #0xff000000
+    bic     r0, r0, #1
+    bics    r2, r0, #0xff000000
     beq     crashed
 
     ldr     r1, [r7, #0x6c]  @ read16 map
-    mov     r2, r0, lsr #M68K_MEM_SHIFT
+    mov     r2, r2, lsr #M68K_MEM_SHIFT
     ldr     r1, [r1, r2, lsl #2]
     movs    r1, r1, lsl #1
     bcs     crashed
 
+    sub     r1, r1, r3
     str     r1, [r7, #0x60]  @ membase
     add     r0, r0, r1
     bx      lr

+ 1 - 1
pico/pico.c

@@ -146,7 +146,7 @@ int PicoReset(void)
   if (Pico.romsize <= 0)
     return 1;
 
-#ifdef DRC_CMP
+#if defined(CPU_CMP_R) || defined(CPU_CMP_W) || defined(DRC_CMP)
   PicoOpt |= POPT_DIS_VDP_FIFO|POPT_DIS_IDLE_DET;
 #endif
 

+ 1 - 0
pico/pico_cmn.c

@@ -50,6 +50,7 @@ static __inline void SekRunM68k(int cyc)
 #endif
 
 out:
+  SekTrace(0);
   pevt_log_m68k_o(EVT_RUN_END);
   pprof_end(m68k);
 }

+ 15 - 4
pico/pico_int.h

@@ -46,8 +46,10 @@ extern struct Cyclone PicoCpuCM68k, PicoCpuCS68k;
 #define SekEndTimesliceS68k(after) PicoCpuCS68k.cycles=after
 #define SekPc (PicoCpuCM68k.pc-PicoCpuCM68k.membase)
 #define SekPcS68k (PicoCpuCS68k.pc-PicoCpuCS68k.membase)
-#define SekDar(x) (x < 8 ? PicoCpuCM68k.d[x] : PicoCpuCM68k.a[x - 8])
+#define SekDar(x)     (x < 8 ? PicoCpuCM68k.d[x] : PicoCpuCM68k.a[x - 8])
+#define SekDarS68k(x) (x < 8 ? PicoCpuCS68k.d[x] : PicoCpuCS68k.a[x - 8])
 #define SekSr     CycloneGetSr(&PicoCpuCM68k)
+#define SekSrS68k CycloneGetSr(&PicoCpuCS68k)
 #define SekSetStop(x) { PicoCpuCM68k.state_flags&=~1; if (x) { PicoCpuCM68k.state_flags|=1; PicoCpuCM68k.cycles=0; } }
 #define SekSetStopS68k(x) { PicoCpuCS68k.state_flags&=~1; if (x) { PicoCpuCS68k.state_flags|=1; PicoCpuCS68k.cycles=0; } }
 #define SekIsStoppedM68k() (PicoCpuCM68k.state_flags&1)
@@ -74,8 +76,10 @@ extern M68K_CONTEXT PicoCpuFM68k, PicoCpuFS68k;
 #define SekEndTimesliceS68k(after) PicoCpuFS68k.io_cycle_counter=after
 #define SekPc     fm68k_get_pc(&PicoCpuFM68k)
 #define SekPcS68k fm68k_get_pc(&PicoCpuFS68k)
-#define SekDar(x) (x < 8 ? PicoCpuFM68k.dreg[x].D : PicoCpuFM68k.areg[x - 8].D)
+#define SekDar(x)     (x < 8 ? PicoCpuFM68k.dreg[x].D : PicoCpuFM68k.areg[x - 8].D)
+#define SekDarS68k(x) (x < 8 ? PicoCpuFS68k.dreg[x].D : PicoCpuFS68k.areg[x - 8].D)
 #define SekSr     PicoCpuFM68k.sr
+#define SekSrS68k PicoCpuFS68k.sr
 #define SekSetStop(x) { \
 	PicoCpuFM68k.execinfo &= ~FM68K_HALTED; \
 	if (x) { PicoCpuFM68k.execinfo |= FM68K_HALTED; PicoCpuFM68k.io_cycle_counter = 0; } \
@@ -109,8 +113,10 @@ extern m68ki_cpu_core PicoCpuMM68k, PicoCpuMS68k;
 #define SekEndTimesliceS68k(after) PicoCpuMS68k.cyc_remaining_cycles=after
 #define SekPc m68k_get_reg(&PicoCpuMM68k, M68K_REG_PC)
 #define SekPcS68k m68k_get_reg(&PicoCpuMS68k, M68K_REG_PC)
-#define SekDar(x) PicoCpuMM68k.dar[x]
-#define SekSr m68k_get_reg(&PicoCpuMM68k, M68K_REG_SR)
+#define SekDar(x)     PicoCpuMM68k.dar[x]
+#define SekDarS68k(x) PicoCpuMS68k.dar[x]
+#define SekSr     m68k_get_reg(&PicoCpuMM68k, M68K_REG_SR)
+#define SekSrS68k m68k_get_reg(&PicoCpuMS68k, M68K_REG_SR)
 #define SekSetStop(x) { \
 	if(x) { SET_CYCLES(0); PicoCpuMM68k.stopped=STOP_LEVEL_STOP; } \
 	else PicoCpuMM68k.stopped=0; \
@@ -633,6 +639,11 @@ PICO_INTERNAL void SekUnpackCpu(const unsigned char *cpu, int is_sub);
 void SekStepM68k(void);
 void SekInitIdleDet(void);
 void SekFinishIdleDet(void);
+#if defined(CPU_CMP_R) || defined(CPU_CMP_W)
+void SekTrace(int is_s68k);
+#else
+#define SekTrace(x)
+#endif
 
 // cd/sek.c
 PICO_INTERNAL void SekInitS68k(void);

+ 118 - 0
pico/sek.c

@@ -420,6 +420,122 @@ void SekFinishIdleDet(void)
 }
 
 
+#if defined(CPU_CMP_R) || defined(CPU_CMP_W)
+#include "debug.h"
+
+struct ref_68k {
+  u32 dar[16];
+  u32 pc;
+  u32 sr;
+  u32 cycles;
+  u32 pc_prev;
+};
+struct ref_68k ref_68ks[2];
+static int current_68k;
+
+void SekTrace(int is_s68k)
+{
+  struct ref_68k *x68k = &ref_68ks[is_s68k];
+  u32 pc = is_s68k ? SekPcS68k : SekPc;
+  u32 sr = is_s68k ? SekSrS68k : SekSr;
+  u32 cycles = is_s68k ? SekCycleCntS68k : SekCycleCnt;
+  u32 r;
+  u8 cmd;
+#ifdef CPU_CMP_W
+  int i;
+
+  if (is_s68k != current_68k) {
+    current_68k = is_s68k;
+    cmd = CTL_68K_SLAVE | current_68k;
+    tl_write(&cmd, sizeof(cmd));
+  }
+  if (pc != x68k->pc) {
+    x68k->pc = pc;
+    tl_write_uint(CTL_68K_PC, x68k->pc);
+  }
+  if (sr != x68k->sr) {
+    x68k->sr = sr;
+    tl_write_uint(CTL_68K_SR, x68k->sr);
+  }
+  for (i = 0; i < 16; i++) {
+    r = is_s68k ? SekDarS68k(i) : SekDar(i);
+    if (r != x68k->dar[i]) {
+      x68k->dar[i] = r;
+      tl_write_uint(CTL_68K_R + i, r);
+    }
+  }
+  tl_write_uint(CTL_68K_CYCLES, cycles);
+#else
+  int i, bad = 0;
+
+  while (1)
+  {
+    int ret = tl_read(&cmd, sizeof(cmd));
+    if (ret == 0) {
+      elprintf(EL_STATUS, "EOF");
+      exit(1);
+    }
+    switch (cmd) {
+    case CTL_68K_SLAVE:
+    case CTL_68K_SLAVE + 1:
+      current_68k = cmd & 1;
+      break;
+    case CTL_68K_PC:
+      tl_read_uint(&x68k->pc);
+      break;
+    case CTL_68K_SR:
+      tl_read_uint(&x68k->sr);
+      break;
+    case CTL_68K_CYCLES:
+      tl_read_uint(&x68k->cycles);
+      goto breakloop;
+    default:
+      if (CTL_68K_R <= cmd && cmd < CTL_68K_R + 0x10)
+        tl_read_uint(&x68k->dar[cmd - CTL_68K_R]);
+      else
+        elprintf(EL_STATUS, "invalid cmd: %02x", cmd);
+    }
+  }
+
+breakloop:
+  if (is_s68k != current_68k) {
+		printf("bad 68k: %d %d\n", is_s68k, current_68k);
+    bad = 1;
+  }
+  if (cycles != x68k->cycles) {
+		printf("bad cycles: %u %u\n", cycles, x68k->cycles);
+    bad = 1;
+  }
+  if ((pc ^ x68k->pc) & 0xffffff) {
+		printf("bad PC: %08x %08x\n", pc, x68k->pc);
+    bad = 1;
+  }
+  if (sr != x68k->sr) {
+		printf("bad SR:  %03x %03x\n", sr, x68k->sr);
+    bad = 1;
+  }
+  for (i = 0; i < 16; i++) {
+    r = is_s68k ? SekDarS68k(i) : SekDar(i);
+    if (r != x68k->dar[i]) {
+		  printf("bad %c%d: %08x %08x\n", i < 8 ? 'D' : 'A', i & 7,
+        r, x68k->dar[i]);
+      bad = 1;
+    }
+  }
+  if (bad) {
+    for (i = 0; i < 8; i++)
+			printf("D%d: %08x  A%d: %08x\n", i, x68k->dar[i],
+        i, x68k->dar[i + 8]);
+		printf("PC: %08x, %08x\n", x68k->pc, x68k->pc_prev);
+
+    PDebugDumpMem();
+    exit(1);
+  }
+  x68k->pc_prev = x68k->pc;
+#endif
+}
+#endif // CPU_CMP_*
+
 #if defined(EMU_M68K) && M68K_INSTRUCTION_HOOK == OPT_SPECIFY_HANDLER
 static unsigned char op_flags[0x400000/2] = { 0, };
 static int atexit_set = 0;
@@ -447,3 +563,5 @@ void instruction_hook(void)
     op_flags[REG_PC/2] = 1;
 }
 #endif
+
+// vim:shiftwidth=2:ts=2:expandtab

+ 8 - 5
platform/common/common.mak

@@ -30,6 +30,13 @@ SRCS_COMMON += $(R)cpu/debug.c
  LDFLAGS += -lreadline
  endif
 endif
+ifeq "$(cpu_cmp)" "1"
+ifdef cpu_cmp_w
+DEFINES += CPU_CMP_W
+else
+DEFINES += CPU_CMP_R
+endif # cpu_cmp_w
+endif
 ifeq "$(pprof)" "1"
 DEFINES += PPROF
 SRCS_COMMON += $(R)platform/linux/pprof.c
@@ -157,10 +164,6 @@ SRCS_COMMON += $(R)cpu/sh2/mame/sh2dasm.c
 SRCS_COMMON += $(R)platform/libpicofe/linux/host_dasm.c
 LDFLAGS += -lbfd -lopcodes -liberty
 endif
-ifeq "$(drc_debug_interp)" "1"
-DEFINES += DRC_DEBUG_INTERP
-use_sh2mame = 1
-endif
 endif # use_sh2drc
 #
 ifeq "$(use_sh2mame)" "1"
@@ -183,7 +186,7 @@ $(FR)cpu/cyclone/Cyclone.h:
 
 $(FR)cpu/cyclone/Cyclone.s:
 	@echo building Cyclone...
-	@make -C $(R)cpu/cyclone/ CONFIG_FILE='\"../cyclone_config.h\"'
+	@make -C $(R)cpu/cyclone/ CONFIG_FILE=../cyclone_config.h
 
 $(FR)cpu/musashi/m68kops.c:
 	@make -C $(R)cpu/musashi