From: kub Date: Fri, 29 Mar 2019 17:36:44 +0000 (+0100) Subject: debug stuff, bug fixing X-Git-Tag: v2.00~870 X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e267031a50851a7f4a3851a46bce8e2ce057ec41;p=picodrive.git debug stuff, bug fixing --- diff --git a/cpu/drc/emit_arm.c b/cpu/drc/emit_arm.c index 86d8a41d..632d476e 100644 --- a/cpu/drc/emit_arm.c +++ b/cpu/drc/emit_arm.c @@ -510,12 +510,12 @@ static int emith_xbranch(int cond, void *target, int is_call) emith_top_imm(A_COND_AL, A_OP_TST, r, imm) #define emith_cmp_r_imm(r, imm) { \ - u32 op = A_OP_CMP, imm_ = imm; \ - if (~imm_ < 0x100) { \ - imm_ = -imm_; \ - op = A_OP_CMN; \ + u32 op_ = A_OP_CMP, imm_ = (u8)imm; \ + if ((s8)imm_ < 0) { \ + imm_ = (u8)-imm_; \ + op_ = A_OP_CMN; \ } \ - emith_top_imm(A_COND_AL, op, r, imm); \ + emith_top_imm(A_COND_AL, op_, r, imm_); \ } #define emith_subf_r_imm(r, imm) \ diff --git a/cpu/sh2/compiler.c b/cpu/sh2/compiler.c index 3c5ce5b9..800e9d32 100644 --- a/cpu/sh2/compiler.c +++ b/cpu/sh2/compiler.c @@ -53,6 +53,9 @@ // 04 - asm // 08 - runtime block entry log // 10 - smc self-check +// 100 - write trace +// 200 - compare trace +// 400 - print block entry backtrace // { #ifndef DRC_DEBUG #define DRC_DEBUG 0 @@ -73,6 +76,7 @@ static int insns_compiled, hash_collisions, host_insn_count; #define dbg(...) #endif + /// #define FETCH_OP(pc) \ dr_pc_base[(pc) / 2] @@ -147,13 +151,86 @@ static char sh2dasm_buff[64]; #define do_host_disasm(x) #endif -#if (DRC_DEBUG & 8) || defined(PDB) +#if (DRC_DEBUG & (8|256|512|1024)) || defined(PDB) + +#define SH2_DUMP(sh2, reason) { \ + char ms = (sh2)->is_slave ? 's' : 'm'; \ + printf("%csh2 %s %08x\n", ms, reason, (sh2)->pc); \ + printf("%csh2 r0-7 %08x %08x %08x %08x %08x %08x %08x %08x\n", ms, \ + (sh2)->r[0], (sh2)->r[1], (sh2)->r[2], (sh2)->r[3], \ + (sh2)->r[4], (sh2)->r[5], (sh2)->r[6], (sh2)->r[7]); \ + printf("%csh2 r8-15 %08x %08x %08x %08x %08x %08x %08x %08x\n", ms, \ + (sh2)->r[8], (sh2)->r[9], (sh2)->r[10], (sh2)->r[11], \ + (sh2)->r[12], (sh2)->r[13], (sh2)->r[14], (sh2)->r[15]); \ + printf("%csh2 pc-ml %08x %08x %08x %08x %08x %08x %08x %08x\n", ms, \ + (sh2)->pc, (sh2)->ppc, (sh2)->pr, (sh2)->sr&0x3ff, \ + (sh2)->gbr, (sh2)->vbr, (sh2)->mach, (sh2)->macl); \ + printf("%csh2 tmp-p %08x %08x %08x %08x %08x %08x %08x %08x\n", ms, \ + (sh2)->drc_tmp, (sh2)->irq_cycles, \ + (sh2)->pdb_io_csum[0], (sh2)->pdb_io_csum[1], (sh2)->state, \ + (sh2)->poll_addr, (sh2)->poll_cycles, (sh2)->poll_cnt); \ +} +static SH2 csh2[2][4]; static void REGPARM(3) *sh2_drc_log_entry(void *block, SH2 *sh2, u32 sr) { if (block != NULL) { dbg(8, "= %csh2 enter %08x %p, c=%d", sh2->is_slave ? 's' : 'm', sh2->pc, block, (signed int)sr >> 12); +#if defined PDB pdb_step(sh2, sh2->pc); +#elif (DRC_DEBUG & 256) + { + static FILE *trace[2]; + int idx = sh2->is_slave; +if (sh2 != &sh2s[0] && sh2 != &sh2s[1]) printf("sh2 %p?\n",sh2); + if (!trace[0]) { + truncate("pico.trace", 0); + trace[0] = fopen("pico.trace0", "wb"); + trace[1] = fopen("pico.trace1", "wb"); + } + if (csh2[idx][0].pc != sh2->pc) { + fwrite(sh2, offsetof(SH2, read8_map), 1, trace[idx]); + fwrite(&sh2->pdb_io_csum, sizeof(sh2->pdb_io_csum), 1, trace[idx]); + memcpy(&csh2[idx][0], sh2, offsetof(SH2, icount)); + } + } +#elif (DRC_DEBUG & 512) + { + static FILE *trace[2]; + static SH2 fsh2; + int idx = sh2->is_slave; + if (!trace[0]) { + trace[0] = fopen("pico.trace0", "rb"); + trace[1] = fopen("pico.trace1", "rb"); + } + if (csh2[idx][0].pc != sh2->pc) { + if (!fread(&fsh2, offsetof(SH2, read8_map), 1, trace[idx]) || + !fread(&fsh2.pdb_io_csum, sizeof(sh2->pdb_io_csum), 1, trace[idx])) { + printf("trace eof at %08lx\n",ftell(trace[idx])); + exit(1); + } + fsh2.sr = (fsh2.sr & 0xfff) | (sh2->sr & ~0xfff); + fsh2.is_slave = idx; + if (memcmp(&fsh2, sh2, offsetof(SH2, read8_map)) || + 0)//memcmp(&fsh2.pdb_io_csum, &sh2->pdb_io_csum, sizeof(sh2->pdb_io_csum))) + { + printf("difference at %08lx!\n",ftell(trace[idx])); + SH2_DUMP(&fsh2, "file"); + SH2_DUMP(sh2, "current"); + SH2_DUMP(&csh2[idx][0], "previous"); + exit(1); + } + csh2[idx][0] = fsh2; + } + } +#elif (DRC_DEBUG & 1024) + { + int x = sh2->is_slave, i; + for (i = 0; i < ARRAY_SIZE(csh2[x]); i++) + memcpy(&csh2[x][i], &csh2[x][i+1], offsetof(SH2, icount)); + memcpy(&csh2[x][3], sh2, offsetof(SH2, icount)); + } +#endif } return block; } @@ -759,13 +836,18 @@ static u32 dr_gcregs_mask; static u32 dr_gcregs_dirty; #if PROPAGATE_CONSTANTS +static void gconst_set(sh2_reg_e r, u32 val) +{ + dr_gcregs_mask |= 1 << r; + dr_gcregs[r] = val; +} + static void gconst_new(sh2_reg_e r, u32 val) { int i; - dr_gcregs_mask |= 1 << r; + gconst_set(r, val); dr_gcregs_dirty |= 1 << r; - dr_gcregs[r] = val; // throw away old r that we might have cached for (i = ARRAY_SIZE(reg_temp) - 1; i >= 0; i--) { @@ -818,6 +900,17 @@ static void gconst_kill(sh2_reg_e r) dr_gcregs_dirty &= ~(1 << r); } +#if PROPAGATE_CONSTANTS +static void gconst_copy(sh2_reg_e rd, sh2_reg_e rs) +{ + u32 val; + + gconst_kill(rd); + if (gconst_get(rs, &val)) + gconst_set(rd, val); +} +#endif + static void gconst_clean(void) { int i; @@ -1104,7 +1197,7 @@ static void rcache_unlock_all(void) reg_temp[i].flags &= ~HRF_LOCKED; } -#ifdef DRC_CMP +#if (DRC_DEBUG & (8|256|512|1024)) || defined(DRC_CMP) static u32 rcache_used_hreg_mask(void) { u32 mask = 0; @@ -1202,18 +1295,13 @@ static void emit_move_r_imm32(sh2_reg_e dst, u32 imm) static void emit_move_r_r(sh2_reg_e dst, sh2_reg_e src) { int hr_d, hr_s; - u32 val; + hr_s = rcache_get_reg(src, RC_GR_READ); + hr_d = rcache_get_reg(dst, RC_GR_WRITE); + emith_move_r_r(hr_d, hr_s); #if PROPAGATE_CONSTANTS - if (gconst_get(src, &val)) - gconst_new(dst, val); - else + gconst_copy(dst, src); #endif - { - hr_s = rcache_get_reg(src, RC_GR_READ); - hr_d = rcache_get_reg(dst, RC_GR_WRITE); - emith_move_r_r(hr_d, hr_s); - } } // T must be clear, and comparison done just before this @@ -1231,7 +1319,7 @@ static int emit_memhandler_read(int size) rcache_clean(); -#ifndef DCR_SR_REG +#ifndef DRC_SR_REG // must writeback cycles for poll detection stuff if (reg_map_g2h[SHR_SR] != -1) emith_ctx_write(reg_map_g2h[SHR_SR], SHR_SR * 4); @@ -1244,7 +1332,7 @@ static int emit_memhandler_read(int size) case 2: emith_call(sh2_drc_read32); break; // 32 } rcache_invalidate(); -#ifndef DCR_SR_REG +#ifndef DRC_SR_REG if (reg_map_g2h[SHR_SR] != -1) emith_ctx_read(reg_map_g2h[SHR_SR], SHR_SR * 4); #endif @@ -1255,7 +1343,7 @@ static int emit_memhandler_read(int size) static void emit_memhandler_write(int size) { int arg2; -#ifndef DCR_SR_REG +#ifndef DRC_SR_REG if (reg_map_g2h[SHR_SR] != -1) emith_ctx_write(reg_map_g2h[SHR_SR], SHR_SR * 4); #endif @@ -1270,7 +1358,7 @@ static void emit_memhandler_write(int size) } rcache_invalidate(); -#ifndef DCR_SR_REG +#ifndef DRC_SR_REG if (reg_map_g2h[SHR_SR] != -1) emith_ctx_read(reg_map_g2h[SHR_SR], SHR_SR * 4); #endif @@ -1287,8 +1375,8 @@ static int emit_memhandler_read_rr(sh2_reg_e rd, sh2_reg_e rs, u32 offs, int siz hr2 = rcache_get_tmp(); emith_move_r_imm(hr2, val); } else { - gconst_new(rd, val); - hr2 = rcache_get_reg(rd, RC_GR_RMW); + emit_move_r_imm32(rd, val); + hr2 = rcache_get_reg(rd, RC_GR_READ); } return hr2; } @@ -1296,7 +1384,10 @@ static int emit_memhandler_read_rr(sh2_reg_e rd, sh2_reg_e rs, u32 offs, int siz if (gconst_get(rs, &val)) { hr = emit_get_rbase_and_offs(val + offs, &offs2); if (hr != -1) { - hr2 = rcache_get_reg(rd, RC_GR_WRITE); + if (rd == SHR_TMP) + hr2 = rcache_get_tmp(); + else + hr2 = rcache_get_reg(rd, RC_GR_WRITE); switch (size) { case 0: // 8 emith_read8s_r_r_offs(hr2, hr, offs2 ^ 1); @@ -1323,13 +1414,18 @@ static int emit_memhandler_read_rr(sh2_reg_e rd, sh2_reg_e rs, u32 offs, int siz emith_add_r_imm(hr, offs); } hr = emit_memhandler_read(size); - hr2 = rcache_get_reg(rd, RC_GR_WRITE); - if (size != 2) { + if (rd == SHR_TMP) + hr2 = hr; + else + hr2 = rcache_get_reg(rd, RC_GR_WRITE); + + if (rd != SHR_TMP && size != 2) { emith_sext(hr2, hr, (size == 1) ? 16 : 8); - } else + } else if (hr != hr2) emith_move_r_r(hr2, hr); - rcache_free_tmp(hr); + if (hr != hr2) + rcache_free_tmp(hr); return hr2; } @@ -1339,6 +1435,7 @@ static void emit_memhandler_write_rr(sh2_reg_e rd, sh2_reg_e rs, u32 offs, int s int hr; u32 val; + rcache_clean(); // XXX rcache_get_reg_arg(1, rd); if (gconst_get(rs, &val)) { @@ -1375,7 +1472,7 @@ static int emit_indirect_indexed_read(sh2_reg_e rd, sh2_reg_e rx, sh2_reg_e ry, else hr2 = hr; - if (size != 2) { // 16, 8 + if (rd != SHR_TMP && size != 2) { // 16, 8 emith_sext(hr2, hr, size ? 16 : 8); } else if (hr != hr2) // 32 emith_move_r_r(hr2, hr); @@ -1397,6 +1494,7 @@ static void emit_indirect_indexed_write(sh2_reg_e rd, sh2_reg_e rx, sh2_reg_e ry if (gconst_get(rx, &offs)) return emit_memhandler_write_rr(rd, ry, offs, size); #endif + rcache_clean(); // XXX rcache_get_reg_arg(1, rd); a0 = rcache_get_reg_arg(0, rx); t = rcache_get_reg(ry, RC_GR_READ); @@ -1459,17 +1557,6 @@ static void emit_do_static_regs(int is_write, int tmpr) /* just after lookup function, jump to address returned */ static void emit_block_entry(void) { -#if (DRC_DEBUG & 8) || defined(PDB) - int arg1, arg2; - host_arg2reg(arg1, 1); - host_arg2reg(arg2, 2); - - emit_do_static_regs(1, arg2); - emith_move_r_r_ptr(arg1, CONTEXT_REG); - emith_move_r_r(arg2, rcache_get_reg(SHR_SR, RC_GR_READ)); - emith_call(sh2_drc_log_entry); - rcache_invalidate(); -#endif emith_tst_r_r_ptr(RET_REG, RET_REG); EMITH_SJMP_START(DCOND_EQ); emith_jump_reg_c(DCOND_NE, RET_REG); @@ -1675,6 +1762,24 @@ static void REGPARM(2) *sh2_translate(SH2 *sh2, int tcache_id) emith_jump_cond(DCOND_LE, sh2_drc_exit); do_host_disasm(tcache_id); rcache_unlock_all(); + +#if (DRC_DEBUG & (8|256|512|1024)) + emit_move_r_imm32(SHR_PC, pc); + sr = rcache_get_reg(SHR_SR, RC_GR_RMW); + FLUSH_CYCLES(sr); + rcache_clean(); + tmp = rcache_used_hreg_mask(); + emith_save_caller_regs(tmp); + emit_do_static_regs(1, 0); + rcache_get_reg_arg(2, SHR_SR); + tmp2 = rcache_get_tmp_arg(0); + tmp3 = rcache_get_tmp_arg(1); + emith_move_r_imm(tmp2, (u32)tcache_ptr); + emith_move_r_r_ptr(tmp3,CONTEXT_REG); + emith_call(sh2_drc_log_entry); + emith_restore_caller_regs(tmp); + rcache_invalidate(); +#endif } #ifdef DRC_CMP @@ -1729,7 +1834,10 @@ static void REGPARM(2) *sh2_translate(SH2 *sh2, int tcache_id) emith_move_r_imm(tmp, pc); emith_tst_r_imm(sr, T); tmp2 = ops[i-1].op == OP_BRANCH_CT ? DCOND_NE : DCOND_EQ; + tmp3 = ops[i-1].op == OP_BRANCH_CT ? DCOND_EQ : DCOND_NE; + EMITH_SJMP_START(tmp3); emith_move_r_imm_c(tmp2, tmp, ops[i-1].imm); + EMITH_SJMP_END(tmp3); break; case OP_BRANCH_N: emit_move_r_imm32(SHR_PC, pc); @@ -1765,7 +1873,6 @@ static void REGPARM(2) *sh2_translate(SH2 *sh2, int tcache_id) drcf.pending_branch_direct = 1; } else { emit_move_r_r(SHR_PC, opd->rm); - ops[i+1].source |= SHR_PC; // need PC for jump after delay slot drcf.pending_branch_indirect = 1; } goto end_op; @@ -1785,7 +1892,6 @@ static void REGPARM(2) *sh2_translate(SH2 *sh2, int tcache_id) emith_move_r_r(tmp3, tmp); } emith_add_r_r(tmp, tmp2); - ops[i+1].source |= SHR_PC; // need PC for jump after delay slot drcf.pending_branch_indirect = 1; } goto end_op; @@ -1813,7 +1919,7 @@ static void REGPARM(2) *sh2_translate(SH2 *sh2, int tcache_id) case OP_UNDEFINED: elprintf_sh2(sh2, EL_ANOMALY, "drc: illegal op %04x @ %08x", op, pc - 2); - opd->imm = 4; + opd->imm = (op_flags[i] & OF_B_IN_DS) ? 6 : 4; // fallthrough case OP_TRAPA: tmp = rcache_get_reg(SHR_SP, RC_GR_RMW); @@ -1827,7 +1933,13 @@ static void REGPARM(2) *sh2_translate(SH2 *sh2, int tcache_id) // push PC rcache_get_reg_arg(0, SHR_SP); tmp = rcache_get_tmp_arg(1); - emith_move_r_imm(tmp, pc); + if (op == OP_TRAPA) + emith_move_r_imm(tmp, pc); + else if (drcf.pending_branch_indirect) { + tmp2 = rcache_get_reg(SHR_PC, RC_GR_READ); + emith_move_r_r(tmp, tmp2); + } else + emith_move_r_imm(tmp, pc - 2); emit_memhandler_write(2); // obtain new PC emit_memhandler_read_rr(SHR_PC, SHR_VBR, opd->imm * 4, 2); @@ -1988,7 +2100,6 @@ static void REGPARM(2) *sh2_translate(SH2 *sh2, int tcache_id) goto end_op; case 0x0f: // MAC.L @Rm+,@Rn+ 0000nnnnmmmm1111 emit_indirect_read_double(&tmp, &tmp2, GET_Rn(), GET_Rm(), 2); - sr = rcache_get_reg(SHR_SR, RC_GR_READ); tmp3 = rcache_get_reg(SHR_MACL, RC_GR_RMW); tmp4 = rcache_get_reg(SHR_MACH, RC_GR_RMW); @@ -2087,12 +2198,12 @@ static void REGPARM(2) *sh2_translate(SH2 *sh2, int tcache_id) case 0x0e: // MULU.W Rm,Rn 0010nnnnmmmm1110 case 0x0f: // MULS.W Rm,Rn 0010nnnnmmmm1111 tmp2 = rcache_get_reg(GET_Rn(), RC_GR_READ); + tmp3 = rcache_get_reg(GET_Rm(), RC_GR_READ); tmp = rcache_get_reg(SHR_MACL, RC_GR_WRITE); if (op & 1) { emith_sext(tmp, tmp2, 16); } else emith_clear_msb(tmp, tmp2, 16); - tmp3 = rcache_get_reg(GET_Rm(), RC_GR_READ); tmp2 = rcache_get_tmp(); if (op & 1) { emith_sext(tmp2, tmp3, 16); @@ -2308,7 +2419,7 @@ static void REGPARM(2) *sh2_translate(SH2 *sh2, int tcache_id) } tmp2 = rcache_get_reg(GET_Rn(), RC_GR_RMW); emith_sub_r_imm(tmp2, 4); - rcache_clean(); + rcache_clean(); // XXX rcache_get_reg_arg(0, GET_Rn()); tmp3 = rcache_get_reg_arg(1, tmp); if (tmp == SHR_SR) @@ -2444,6 +2555,7 @@ static void REGPARM(2) *sh2_translate(SH2 *sh2, int tcache_id) emith_bic_r_imm(sr, T); emith_cmp_r_imm(tmp, 0); emit_or_t_if_eq(sr); + rcache_clean(); // XXX emith_or_r_imm(tmp, 0x80); tmp2 = rcache_get_tmp_arg(1); // assuming it differs to tmp emith_move_r_r(tmp2, tmp); @@ -2596,7 +2708,7 @@ static void REGPARM(2) *sh2_translate(SH2 *sh2, int tcache_id) goto end_op; case 0x0800: // CMP/EQ #imm,R0 10001000iiiiiiii // XXX: could use cmn - tmp2 = rcache_get_reg(0, RC_GR_READ); + tmp2 = rcache_get_reg(SHR_R0, RC_GR_READ); sr = rcache_get_reg(SHR_SR, RC_GR_RMW); emith_bic_r_imm(sr, T); emith_cmp_r_imm(tmp2, (s8)(op & 0xff)); @@ -2679,10 +2791,11 @@ static void REGPARM(2) *sh2_translate(SH2 *sh2, int tcache_id) default: default_: - if (!(op_flags[i] & OF_B_IN_DS)) + if (!(op_flags[i] & OF_B_IN_DS)) { elprintf_sh2(sh2, EL_ANOMALY, "drc: illegal op %04x @ %08x", op, pc - 2); exit(1); + } } end_op: @@ -3268,6 +3381,15 @@ void block_stats(void) void sh2_drc_flush_all(void) { +#if (DRC_DEBUG & 1024) + int i; + printf("backtrace master:\n"); + for (i = 0; i < ARRAY_SIZE(csh2[0]); i++) + SH2_DUMP(&csh2[0][i], "bt msh2"); + printf("backtrace slave:\n"); + for (i = 0; i < ARRAY_SIZE(csh2[1]); i++) + SH2_DUMP(&csh2[1][i], "bt ssh2"); +#endif block_stats(); flush_tcache(0); flush_tcache(1); @@ -4200,13 +4322,14 @@ void scan_block(u32 base_pc, int is_slave, u8 *op_flags, u32 *end_pc_out, if (op_flags[i] & OF_DELAY_OP) { switch (opd->op) { case OP_BRANCH: + case OP_BRANCH_N: case OP_BRANCH_CT: case OP_BRANCH_CF: case OP_BRANCH_R: case OP_BRANCH_RF: elprintf(EL_ANOMALY, "%csh2 drc: branch in DS @ %08x", is_slave ? 's' : 'm', pc); - opd->op = OP_UNHANDLED; + opd->op = OP_UNDEFINED; op_flags[i] |= OF_B_IN_DS; next_is_delay = 0; break; diff --git a/cpu/sh2/compiler.h b/cpu/sh2/compiler.h index 70fdbf4e..c9cf7ab0 100644 --- a/cpu/sh2/compiler.h +++ b/cpu/sh2/compiler.h @@ -29,9 +29,9 @@ void scan_block(unsigned int base_pc, int is_slave, #if defined(DRC_SH2) // direct access to some host CPU registers used by the DRC // XXX MUST match definitions in cpu/sh2/compiler.c -#if defined(_arm__) +#if defined(__arm__) #define DRC_SR_REG r10 -#elif defined(__i386__) +#elif defined(__i386__) || defined(__x86_64__) #define DRC_SR_REG edi #else #warning "direct DRC register access not available for this host" diff --git a/pico/32x/memory.c b/pico/32x/memory.c index f82b9f99..8f2a7c2f 100644 --- a/pico/32x/memory.c +++ b/pico/32x/memory.c @@ -1344,7 +1344,7 @@ out_noprint: static u32 sh2_read16_da(u32 a, SH2 *sh2) { - return ((u16 *)sh2->data_array)[(a & 0xfff) / 2]; + return ((u16 *)sh2->data_array)[(a & 0xffe) / 2]; } static u32 sh2_read16_rom(u32 a, SH2 *sh2) @@ -1367,7 +1367,7 @@ static u32 sh2_read32_cs0(u32 a, SH2 *sh2) static u32 sh2_read32_da(u32 a, SH2 *sh2) { - u32 d = *(u32 *)(sh2->data_array + (a & 0xfff)); + u32 d = *((u32 *)sh2->data_array + (a & 0xffc)/4); return (d << 16) | (d >> 16); } @@ -1587,28 +1587,28 @@ static void REGPARM(3) sh2_write32_dram1(u32 a, u32 d, SH2 *sh2) static void REGPARM(3) sh2_write32_sdram(u32 a, u32 d, SH2 *sh2) { - u32 a1 = a & 0x3ffff; + u32 a1 = a & 0x3fffc; *(u32 *)(sh2->p_sdram + a1) = (d << 16) | (d >> 16); #ifdef DRC_SH2 unsigned short *p = &Pico32xMem->drcblk_ram[a1 >> SH2_DRCBLK_RAM_SHIFT]; if (p[0]) sh2_drc_wcheck_ram(a, p[0], sh2->is_slave); if (p[1]) - sh2_drc_wcheck_ram(a, p[1], sh2->is_slave); + sh2_drc_wcheck_ram(a+2, p[1], sh2->is_slave); #endif } static void REGPARM(3) sh2_write32_da(u32 a, u32 d, SH2 *sh2) { - u32 a1 = a & 0xfff; - *(u32 *)(sh2->data_array + a1) = (d << 16) | (d >> 16); + u32 a1 = a & 0xffc; + *((u32 *)sh2->data_array + a1/4) = (d << 16) | (d >> 16); #ifdef DRC_SH2 int id = sh2->is_slave; unsigned short *p = &Pico32xMem->drcblk_da[id][a1 >> SH2_DRCBLK_DA_SHIFT]; if (p[0]) sh2_drc_wcheck_da(a, p[0], id); if (p[1]) - sh2_drc_wcheck_da(a, p[1], id); + sh2_drc_wcheck_da(a+2, p[1], id); #endif }