From 00faec9cdbc073199fa984a0450e1a961994b058 Mon Sep 17 00:00:00 2001 From: notaz Date: Sat, 13 Jul 2013 18:34:47 +0300 Subject: [PATCH] drc: lots of new debug code --- Makefile | 8 +- cpu/sh2/compiler.c | 231 +++++++++++++++++++++---------------- cpu/sh2/compiler.h | 8 ++ cpu/sh2/mame/sh2.c | 12 +- cpu/sh2/mame/sh2pico.c | 66 +++++------ cpu/sh2/sh2.c | 194 ++++++++++++++++++++++++++++++- cpu/sh2/sh2.h | 6 + pico/32x/memory.c | 5 - pico/memory.h | 5 + platform/common/common.mak | 15 +++ 10 files changed, 398 insertions(+), 152 deletions(-) diff --git a/Makefile b/Makefile index e6168ee..4df1162 100644 --- a/Makefile +++ b/Makefile @@ -6,6 +6,10 @@ CFLAGS += -Iplatform/linux/ ifndef DEBUG CFLAGS += -O2 -DNDEBUG endif +#CFLAGS += -DDRC_CMP +#drc_debug = 4 +#profile = 1 + all: config.mak target_ @@ -44,10 +48,6 @@ use_cz80 ?= 1 use_sh2mame ?= 1 endif -#drc_debug = 3 -#drc_debug_interp = 1 -#profile = 1 - -include Makefile.local ifeq "$(use_musashi)" "1" diff --git a/cpu/sh2/compiler.c b/cpu/sh2/compiler.c index 2f959d2..301686b 100644 --- a/cpu/sh2/compiler.c +++ b/cpu/sh2/compiler.c @@ -41,7 +41,6 @@ #define LINK_BRANCHES 1 // limits (per block) -#define BLOCK_CYCLE_LIMIT 100 #define MAX_BLOCK_SIZE (BLOCK_CYCLE_LIMIT * 6 * 6) // max literal offset from the block end @@ -49,7 +48,20 @@ #define MAX_LITERALS (BLOCK_CYCLE_LIMIT / 4) #define MAX_LOCAL_BRANCHES 32 -// debug stuff { +/// +#define FETCH_OP(pc) \ + dr_pc_base[(pc) / 2] + +#define FETCH32(a) \ + ((dr_pc_base[(a) / 2] << 16) | dr_pc_base[(a) / 2 + 1]) + +#ifdef DRC_SH2 + +// debug stuff +// 1 - ? +// 2 - ? +// 4 - log asm +// { #ifndef DRC_DEBUG #define DRC_DEBUG 0 #endif @@ -237,41 +249,7 @@ static void REGPARM(2) (*sh2_drc_write16)(u32 a, u32 d); static void REGPARM(2) (*sh2_drc_write16_slot)(u32 a, u32 d); static int REGPARM(3) (*sh2_drc_write32)(u32 a, u32 d, SH2 *sh2); -extern void REGPARM(2) sh2_do_op(SH2 *sh2, int opcode); - // address space stuff -static void *dr_get_pc_base(u32 pc, int is_slave) -{ - void *ret = NULL; - u32 mask = 0; - - if ((pc & ~0x7ff) == 0) { - // BIOS - ret = is_slave ? Pico32xMem->sh2_rom_s : Pico32xMem->sh2_rom_m; - mask = 0x7ff; - } - else if ((pc & 0xfffff000) == 0xc0000000) { - // data array - ret = Pico32xMem->data_array[is_slave]; - mask = 0xfff; - } - else if ((pc & 0xc6000000) == 0x06000000) { - // SDRAM - ret = Pico32xMem->sdram; - mask = 0x03ffff; - } - else if ((pc & 0xc6000000) == 0x02000000) { - // ROM - ret = Pico.rom; - mask = 0x3fffff; - } - - if (ret == NULL) - return (void *)-1; // NULL is valid value - - return (char *)ret - (pc & ~mask); -} - static int dr_ctx_get_mem_ptr(u32 a, u32 *mask) { int poffs = -1; @@ -1186,12 +1164,6 @@ static void emit_block_entry(void) goto default_; \ } -#define FETCH_OP(pc) \ - dr_pc_base[(pc) / 2] - -#define FETCH32(a) \ - ((dr_pc_base[(a) / 2] << 16) | dr_pc_base[(a) / 2 + 1]) - #define GET_Fx() \ ((op >> 4) & 0x0f) @@ -1204,9 +1176,7 @@ static void emit_block_entry(void) if (GET_Fx() >= n) \ goto default_ -// op_flags: data from 1st pass -#define OP_FLAGS(pc) op_flags[((pc) - base_pc) / 2] -#define OF_DELAY_OP (1 << 0) +static void *dr_get_pc_base(u32 pc, int is_slave); static void REGPARM(2) *sh2_translate(SH2 *sh2, int tcache_id) { @@ -1222,7 +1192,7 @@ static void REGPARM(2) *sh2_translate(SH2 *sh2, int tcache_id) int literal_addr_count = 0; int pending_branch_cond = -1; int pending_branch_pc = 0; - u8 op_flags[BLOCK_CYCLE_LIMIT + 1]; + u8 op_flags[BLOCK_CYCLE_LIMIT]; struct { u32 delayed_op:2; u32 test_irq:1; @@ -1270,56 +1240,19 @@ static void REGPARM(2) *sh2_translate(SH2 *sh2, int tcache_id) dr_link_blocks(tcache_ptr, base_pc, tcache_id); // 1st pass: scan forward for local branches - memset(op_flags, 0, sizeof(op_flags)); - for (cycles = 0, pc = base_pc; cycles < BLOCK_CYCLE_LIMIT; cycles++, pc += 2) { - op = FETCH_OP(pc); - if ((op & 0xf000) == 0xa000 || (op & 0xf000) == 0xb000) { // BRA, BSR - signed int offs = ((signed int)(op << 20) >> 19); - pc += 2; - OP_FLAGS(pc) |= OF_DELAY_OP; - ADD_TO_ARRAY(branch_target_pc, branch_target_count, pc + offs + 2,); - break; - } - if ((op & 0xf000) == 0) { - op &= 0xff; - if (op == 0x1b) // SLEEP - break; - if (op == 0x23 || op == 0x03 || op == 0x0b || op == 0x2b) { // BRAF, BSRF, RTS, RTE - pc += 2; - OP_FLAGS(pc) |= OF_DELAY_OP; - break; - } + scan_block(base_pc, sh2->is_slave, op_flags, &end_pc); + + // collect branch_targets that don't land on delay slots + for (pc = base_pc; pc <= end_pc; pc += 2) { + if (!(OP_FLAGS(pc) & OF_TARGET)) + continue; + if (OP_FLAGS(pc) & OF_DELAY_OP) { + OP_FLAGS(pc) &= ~OF_TARGET; continue; } - if ((op & 0xf0df) == 0x400b) { // JMP, JSR - pc += 2; - OP_FLAGS(pc) |= OF_DELAY_OP; - break; - } - if ((op & 0xf900) == 0x8900) { // BT(S), BF(S) - signed int offs = ((signed int)(op << 24) >> 23); - if (op & 0x0400) - OP_FLAGS(pc + 2) |= OF_DELAY_OP; - ADD_TO_ARRAY(branch_target_pc, branch_target_count, pc + offs + 4, break); - } - if ((op & 0xff00) == 0xc300) // TRAPA - break; - } - - end_pc = pc; - - // clean branch_targets that are not really local, - // and that land on delay slots - for (i = 0, tmp = 0; i < branch_target_count; i++) { - pc = branch_target_pc[i]; - if (base_pc <= pc && pc <= end_pc && !(OP_FLAGS(pc) & OF_DELAY_OP)) - branch_target_pc[tmp++] = branch_target_pc[i]; - - if (i == branch_target_count - 1) // workaround gcc 4.5.2 bug? - break; + ADD_TO_ARRAY(branch_target_pc, branch_target_count, pc, break); } - branch_target_count = tmp; if (branch_target_count > 0) { memset(branch_target_ptr, 0, sizeof(branch_target_ptr[0]) * branch_target_count); memset(branch_target_blkid, 0, sizeof(branch_target_blkid[0]) * branch_target_count); @@ -1338,9 +1271,9 @@ static void REGPARM(2) *sh2_translate(SH2 *sh2, int tcache_id) op = FETCH_OP(pc); - i = find_in_array(branch_target_pc, branch_target_count, pc); - if (i >= 0 || pc == base_pc) + if ((OP_FLAGS(pc) & OF_TARGET) || pc == base_pc) { + i = find_in_array(branch_target_pc, branch_target_count, pc); if (pc != base_pc) { /* make "subblock" - just a mid-block entry */ @@ -1382,10 +1315,25 @@ static void REGPARM(2) *sh2_translate(SH2 *sh2, int tcache_id) #if (DRC_DEBUG & 2) insns_compiled++; +#endif #if (DRC_DEBUG & 4) DasmSH2(sh2dasm_buff, pc, op); printf("%08x %04x %s\n", pc, op, sh2dasm_buff); #endif +#ifdef DRC_CMP + //if (out_pc != 0 && out_pc != (u32)-1) + // emit_move_r_imm32(SHR_PC, out_pc); + //else + if (!drcf.delayed_op) { + emit_move_r_imm32(SHR_PC, pc); + sr = rcache_get_reg(SHR_SR, RC_GR_RMW); + FLUSH_CYCLES(sr); + // rcache_clean(); // FIXME + rcache_flush(); + emit_do_static_regs(1, 0); + emith_pass_arg_r(0, CONTEXT_REG); + emith_call(do_sh2_cmp); + } #endif pc += 2; @@ -1889,6 +1837,7 @@ static void REGPARM(2) *sh2_translate(SH2 *sh2, int tcache_id) sr = rcache_get_reg(SHR_SR, RC_GR_RMW); if (drcf.delayed_op) DELAY_SAVE_T(sr); +#ifndef DRC_CMP if (FETCH_OP(pc) == 0x8bfd) { // BF #-2 if (gconst_get(GET_Rn(), &tmp)) { // XXX: limit burned cycles @@ -1901,6 +1850,7 @@ static void REGPARM(2) *sh2_translate(SH2 *sh2, int tcache_id) emith_sh2_dtbf_loop(); goto end_op; } +#endif tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW); emith_bic_r_imm(sr, T); emith_subf_r_imm(tmp, 1); @@ -2502,13 +2452,6 @@ static void REGPARM(2) *sh2_translate(SH2 *sh2, int tcache_id) default_: elprintf(EL_ANOMALY, "%csh2 drc: unhandled op %04x @ %08x", sh2->is_slave ? 's' : 'm', op, pc - 2); -#ifdef DRC_DEBUG_INTERP - emit_move_r_imm32(SHR_PC, pc - 2); - rcache_flush(); - emith_pass_arg_r(0, CONTEXT_REG); - emith_pass_arg_imm(1, op); - emith_call(sh2_do_op); -#endif break; } @@ -3151,4 +3094,90 @@ void sh2_drc_finish(SH2 *sh2) } } +#endif /* DRC_SH2 */ + +static void *dr_get_pc_base(u32 pc, int is_slave) +{ + void *ret = NULL; + u32 mask = 0; + + if ((pc & ~0x7ff) == 0) { + // BIOS + ret = is_slave ? Pico32xMem->sh2_rom_s : Pico32xMem->sh2_rom_m; + mask = 0x7ff; + } + else if ((pc & 0xfffff000) == 0xc0000000) { + // data array + ret = Pico32xMem->data_array[is_slave]; + mask = 0xfff; + } + else if ((pc & 0xc6000000) == 0x06000000) { + // SDRAM + ret = Pico32xMem->sdram; + mask = 0x03ffff; + } + else if ((pc & 0xc6000000) == 0x02000000) { + // ROM + ret = Pico.rom; + mask = 0x3fffff; + } + + if (ret == NULL) + return (void *)-1; // NULL is valid value + + return (char *)ret - (pc & ~mask); +} + +void scan_block(u32 base_pc, int is_slave, u8 *op_flags, u32 *end_pc) +{ + u16 *dr_pc_base; + u32 pc, target, op; + int cycles; + + memset(op_flags, 0, BLOCK_CYCLE_LIMIT); + + dr_pc_base = dr_get_pc_base(base_pc, is_slave); + + for (cycles = 0, pc = base_pc; cycles < BLOCK_CYCLE_LIMIT-1; cycles++, pc += 2) { + op = FETCH_OP(pc); + if ((op & 0xf000) == 0xa000 || (op & 0xf000) == 0xb000) { // BRA, BSR + signed int offs = ((signed int)(op << 20) >> 19); + pc += 2; + OP_FLAGS(pc) |= OF_DELAY_OP; + target = pc + offs + 2; + if (base_pc <= target && target < base_pc + BLOCK_CYCLE_LIMIT * 2) + OP_FLAGS(target) |= OF_TARGET; + break; + } + if ((op & 0xf000) == 0) { + op &= 0xff; + if (op == 0x1b) // SLEEP + break; + // BRAF, BSRF, RTS, RTE + if (op == 0x23 || op == 0x03 || op == 0x0b || op == 0x2b) { + pc += 2; + OP_FLAGS(pc) |= OF_DELAY_OP; + break; + } + continue; + } + if ((op & 0xf0df) == 0x400b) { // JMP, JSR + pc += 2; + OP_FLAGS(pc) |= OF_DELAY_OP; + break; + } + if ((op & 0xf900) == 0x8900) { // BT(S), BF(S) + signed int offs = ((signed int)(op << 24) >> 23); + if (op & 0x0400) + OP_FLAGS(pc + 2) |= OF_DELAY_OP; + target = pc + offs + 4; + if (base_pc <= target && target < base_pc + BLOCK_CYCLE_LIMIT * 2) + OP_FLAGS(target) |= OF_TARGET; + } + if ((op & 0xff00) == 0xc300) // TRAPA + break; + } + *end_pc = pc; +} + // vim:shiftwidth=2:expandtab diff --git a/cpu/sh2/compiler.h b/cpu/sh2/compiler.h index 16e249a..2a804c7 100644 --- a/cpu/sh2/compiler.h +++ b/cpu/sh2/compiler.h @@ -5,3 +5,11 @@ void sh2_drc_flush_all(void); void sh2_drc_wcheck_ram(unsigned int a, int val, int cpuid); void sh2_drc_wcheck_da(unsigned int a, int val, int cpuid); +#define BLOCK_CYCLE_LIMIT 128 + +#define OP_FLAGS(pc) op_flags[((pc) - (base_pc)) / 2] +#define OF_DELAY_OP (1 << 0) +#define OF_TARGET (1 << 1) + +void scan_block(unsigned int base_pc, int is_slave, + unsigned char *op_flags, unsigned int *end_pc); diff --git a/cpu/sh2/mame/sh2.c b/cpu/sh2/mame/sh2.c index 0010a69..44cd7ea 100644 --- a/cpu/sh2/mame/sh2.c +++ b/cpu/sh2/mame/sh2.c @@ -349,11 +349,13 @@ INLINE void BF(sh2_state *sh2, UINT32 d) */ INLINE void BFS(sh2_state *sh2, UINT32 d) { + sh2->delay = sh2->pc; + sh2->pc += 2; + if ((sh2->sr & T) == 0) { INT32 disp = ((INT32)d << 24) >> 24; - sh2->delay = sh2->pc; - sh2->pc = sh2->ea = sh2->pc + disp * 2 + 2; + sh2->pc = sh2->ea = sh2->pc + disp * 2; sh2->icount--; } } @@ -439,11 +441,13 @@ INLINE void BT(sh2_state *sh2, UINT32 d) */ INLINE void BTS(sh2_state *sh2, UINT32 d) { + sh2->delay = sh2->pc; + sh2->pc += 2; + if ((sh2->sr & T) != 0) { INT32 disp = ((INT32)d << 24) >> 24; - sh2->delay = sh2->pc; - sh2->pc = sh2->ea = sh2->pc + disp * 2 + 2; + sh2->pc = sh2->ea = sh2->pc + disp * 2; sh2->icount--; } } diff --git a/cpu/sh2/mame/sh2pico.c b/cpu/sh2/mame/sh2pico.c index cc6dce3..f321eb9 100644 --- a/cpu/sh2/mame/sh2pico.c +++ b/cpu/sh2/mame/sh2pico.c @@ -1,12 +1,17 @@ #include "../sh2.h" +#ifdef DRC_CMP +#include "../compiler.c" +#endif // MAME types +#ifndef INT8 typedef signed char INT8; typedef signed short INT16; typedef signed int INT32; typedef unsigned int UINT32; typedef unsigned short UINT16; typedef unsigned char UINT8; +#endif #define RB(sh2, a) p32x_sh2_read8(a,sh2) #define RW(sh2, a) p32x_sh2_read16(a,sh2) @@ -66,7 +71,12 @@ static unsigned int op_refs[0x10000]; int sh2_execute(SH2 *sh2, int cycles) { - sh2 = sh2_; +#ifdef DRC_CMP + unsigned int base_pc = 0, end_pc = 0; + unsigned char op_flags[BLOCK_CYCLE_LIMIT]; +#endif + UINT32 opcode; + sh2->icount = cycles; if (sh2->icount <= 0) @@ -76,7 +86,21 @@ int sh2_execute(SH2 *sh2, int cycles) do { - UINT32 opcode; +#ifdef DRC_CMP + if (!sh2->delay) { + if (sh2->pc < base_pc || sh2->pc > end_pc) { + base_pc = sh2->pc; + scan_block(base_pc, sh2->is_slave, + op_flags, &end_pc); + } + if ((OP_FLAGS(sh2->pc) & OF_TARGET) || sh2->pc == base_pc) { + if (sh2->icount < 0) + break; + } + + do_sh2_trace(sh2, sh2->icount); + } +#endif if (sh2->delay) { @@ -124,46 +148,16 @@ int sh2_execute(SH2 *sh2, int cycles) } } +#ifndef DRC_CMP while (sh2->icount > 0 || sh2->delay); /* can't interrupt before delay */ - - return sh2->cycles_timeslice - sh2->icount; -} - -#else // DRC_SH2 - -#ifdef __i386__ -#define REGPARM(x) __attribute__((regparm(x))) #else -#define REGPARM(x) + while (1); #endif -// drc debug -void REGPARM(2) sh2_do_op(SH2 *sh2, int opcode) -{ - sh2->pc += 2; - - switch (opcode & ( 15 << 12)) - { - case 0<<12: op0000(sh2, opcode); break; - case 1<<12: op0001(sh2, opcode); break; - case 2<<12: op0010(sh2, opcode); break; - case 3<<12: op0011(sh2, opcode); break; - case 4<<12: op0100(sh2, opcode); break; - case 5<<12: op0101(sh2, opcode); break; - case 6<<12: op0110(sh2, opcode); break; - case 7<<12: op0111(sh2, opcode); break; - case 8<<12: op1000(sh2, opcode); break; - case 9<<12: op1001(sh2, opcode); break; - case 10<<12: op1010(sh2, opcode); break; - case 11<<12: op1011(sh2, opcode); break; - case 12<<12: op1100(sh2, opcode); break; - case 13<<12: op1101(sh2, opcode); break; - case 14<<12: op1110(sh2, opcode); break; - default: op1111(sh2, opcode); break; - } + return sh2->cycles_timeslice - sh2->icount; } -#endif +#endif // DRC_SH2 #ifdef SH2_STATS #include diff --git a/cpu/sh2/sh2.c b/cpu/sh2/sh2.c index 2e0e838..d185b3f 100644 --- a/cpu/sh2/sh2.c +++ b/cpu/sh2/sh2.c @@ -57,8 +57,7 @@ void sh2_do_irq(SH2 *sh2, int level, int vector) sh2->pc = p32x_sh2_read32(sh2->vbr + vector * 4, sh2); /* 13 cycles at best */ - sh2->m68krcycles_done += C_SH2_TO_M68K(*sh2, 13); -// sh2->icount -= 13; + sh2->icount -= 13; } int sh2_irl_irq(SH2 *sh2, int level, int nested_call) @@ -77,6 +76,7 @@ int sh2_irl_irq(SH2 *sh2, int level, int nested_call) // do this to avoid missing irqs that other SH2 might clear int vector = sh2->irq_callback(sh2, level); sh2_do_irq(sh2, level, vector); + sh2->m68krcycles_done += C_SH2_TO_M68K(*sh2, 13); } else sh2->test_irq = 1; @@ -120,3 +120,193 @@ void sh2_unpack(SH2 *sh2, const unsigned char *buff) sh2->pending_int_vector = p[1]; } +#ifdef DRC_CMP + +/* trace/compare */ +#include +#include +#include + +static SH2 sh2ref[2]; +static int current_slave = -1; +static unsigned int mem_val; +static FILE *f; + +#define SH2MAP_ADDR2OFFS_R(a) \ + ((((a) >> 25) & 3) | (((a) >> 27) & 0x1c)) + +static unsigned int local_read32(SH2 *sh2, u32 a) +{ + const sh2_memmap *sh2_map = sh2->read16_map; + uptr p; + + sh2_map += SH2MAP_ADDR2OFFS_R(a); + p = sh2_map->addr; + if (!map_flag_set(p)) { + u16 *pd = (u16 *)((p << 1) + ((a & sh2_map->mask) & ~3)); + return (pd[0] << 16) | pd[1]; + } + + 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) +{ + SH2 *sh2o = &sh2ref[current->is_slave]; + u32 *regs_a = (void *)current; + u32 *regs_o = (void *)sh2o; + unsigned char v; + u32 val; + int i; + + if (f == NULL) + f = fopen("tracelog", "wb"); + + if (current->is_slave != current_slave) { + current_slave = current->is_slave; + v = 0x80 | current->is_slave; + fwrite(&v, 1, 1, f); + } + + 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]); + regs_o[i] = regs_a[i]; + } + } + + if (current->ea != sh2o->ea) { + write_uint(0x82, current->ea); + sh2o->ea = current->ea; + } + val = local_read32(current, current->ea); + if (mem_val != val) { + write_uint(0x83, val); + mem_val = val; + } + write_uint(0x84, cycles); +} + +static const char *regnames[] = { + "r0", "r1", "r2", "r3", + "r4", "r5", "r6", "r7", + "r8", "r9", "r10", "r11", + "r12", "r13", "r14", "r15", + "pc", "ppc", "pr", "sr", + "gbr", "vbr", "mach","macl", +}; + +void do_sh2_cmp(SH2 *current) +{ + static int current_slave; + static u32 current_val; + SH2 *sh2o = &sh2ref[current->is_slave]; + u32 *regs_a = (void *)current; + u32 *regs_o = (void *)sh2o; + unsigned char code; + int cycles_o = 666; + u32 sr, val; + int bad = 0; + int cycles; + int i, ret; + char csh2; + + if (f == NULL) + f = fopen("tracelog", "rb"); + + while (1) { + ret = fread(&code, 1, 1, f); + if (ret <= 0) + break; + if (code == 0x84) { + fread(&cycles_o, 1, 4, f); + break; + } + + switch (code) { + case 0x80: + case 0x81: + current_slave = code & 1; + break; + case 0x82: + fread(&sh2o->ea, 4, 1, f); + break; + case 0x83: + fread(¤t_val, 4, 1, f); + break; + default: + if (code < offsetof(SH2, read8_map) / 4) + fread(regs_o + code, 4, 1, f); + else { + printf("invalid code: %02x\n", code); + goto end; + } + break; + } + } + + if (ret <= 0) { + printf("EOF?\n"); + goto end; + } + + if (current->is_slave != current_slave) { + printf("bad slave: %d %d\n", current->is_slave, + current_slave); + bad = 1; + } + + for (i = 0; i < offsetof(SH2, read8_map) / 4; i++) { + if (i == 17 || i == 19) // ppc, sr + continue; + if (regs_a[i] != regs_o[i]) { + printf("bad %4s: %08x %08x\n", + regnames[i], regs_a[i], regs_o[i]); + bad = 1; + } + } + + sr = current->sr & 0x3f3; + cycles = (signed int)current->sr >> 12; + + if (sr != sh2o->sr) { + printf("bad SR: %03x %03x\n", sr, sh2o->sr); + bad = 1; + } + + if (cycles != cycles_o) { + printf("bad cycles: %d %d\n", cycles, cycles_o); + bad = 1; + } + + val = local_read32(current, sh2o->ea); + if (val != current_val) { + printf("bad val @%08x: %08x %08x\n", sh2o->ea, val, current_val); + bad = 1; + } + + if (!bad) { + sh2o->ppc = current->pc; + return; + } + +end: + printf("--\n"); + csh2 = current->is_slave ? 's' : 'm'; + for (i = 0; i < 16/2; i++) + printf("%csh2 r%d: %08x r%02d: %08x\n", csh2, + i, sh2o->r[i], i+8, sh2o->r[i+8]); + printf("%csh2 PC: %08x , %08x\n", csh2, sh2o->pc, sh2o->ppc); + printf("%csh2 SR: %03x PR: %08x\n", csh2, sh2o->sr, sh2o->pr); + exit(1); +} + +#endif // DRC_CMP diff --git a/cpu/sh2/sh2.h b/cpu/sh2/sh2.h index bdb2fd9..92774d0 100644 --- a/cpu/sh2/sh2.h +++ b/cpu/sh2/sh2.h @@ -89,4 +89,10 @@ int REGPARM(3) p32x_sh2_write8 (unsigned int a, unsigned int d, SH2 *sh2); int REGPARM(3) p32x_sh2_write16(unsigned int a, unsigned int d, SH2 *sh2); int REGPARM(3) p32x_sh2_write32(unsigned int a, unsigned int d, SH2 *sh2); +// debug +#ifdef DRC_CMP +void do_sh2_trace(SH2 *current, int cycles); +void do_sh2_cmp(SH2 *current); +#endif + #endif /* __SH2_H__ */ diff --git a/pico/32x/memory.c b/pico/32x/memory.c index fc4f177..cb318c7 100644 --- a/pico/32x/memory.c +++ b/pico/32x/memory.c @@ -1253,11 +1253,6 @@ static int REGPARM(3) sh2_write16_da(u32 a, u32 d, int id) } -typedef struct { - uptr addr; // stores (membase >> 1) or ((handler >> 1) | (1<<31)) - u32 mask; -} sh2_memmap; - typedef u32 (sh2_read_handler)(u32 a, int id); typedef int REGPARM(3) (sh2_write_handler)(u32 a, u32 d, int id); diff --git a/pico/memory.h b/pico/memory.h index 9a5da86..1fd7fc1 100644 --- a/pico/memory.h +++ b/pico/memory.h @@ -127,3 +127,8 @@ void name(u32 a, u32 d) \ } \ } +// 32x +typedef struct { + uptr addr; // stores (membase >> 1) or ((handler >> 1) | (1<<31)) + u32 mask; +} sh2_memmap; diff --git a/platform/common/common.mak b/platform/common/common.mak index 8d6b792..6376dca 100644 --- a/platform/common/common.mak +++ b/platform/common/common.mak @@ -1,3 +1,18 @@ +ifdef drc_debug +use_fame = 1 +use_cz80 = 1 +use_cyclone = 0 +use_drz80 = 0 + +asm_memory = 0 +asm_render = 0 +asm_ym2612 = 0 +asm_misc = 0 +asm_cdpico = 0 +asm_cdmemory = 0 +asm_mix = 0 +endif + ifeq "$(profile)" "1" CFLAGS += -fprofile-generate endif -- 2.39.2