some new cpu debug code

This commit is contained in:
notaz 2013-08-10 17:57:54 +03:00
parent f81107f590
commit 12da51c27a
12 changed files with 224 additions and 54 deletions

View file

@ -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 @@
Subproject commit 194104e334f7c26015b99c862486a73be0d80162
Subproject commit 1f9661c5a2919ba91c0f4b89985e0712871e5762

View file

@ -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_"

View file

@ -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;

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

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

View file

@ -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);

View file

@ -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

View file

@ -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