sh2 memory interface optimzations
authorkub <derkub@gmail.com>
Wed, 3 Apr 2019 21:21:20 +0000 (23:21 +0200)
committerkub <derkub@gmail.com>
Tue, 30 Jul 2019 14:34:40 +0000 (16:34 +0200)
cpu/drc/emit_arm.c
cpu/drc/emit_x86.c
cpu/sh2/compiler.c
cpu/sh2/compiler.h
cpu/sh2/sh2.h
pico/32x/memory.c
pico/32x/memory_arm.S [new file with mode: 0644]
pico/32x/sh2soc.c
pico/pico_int.h
tools/mkoffsets.sh

index 4421c64..c255a8b 100644 (file)
@@ -65,6 +65,9 @@
 #define DCOND_VS A_COND_VS
 #define DCOND_VC A_COND_VC
 
+#define DCOND_CS A_COND_HS
+#define DCOND_CC A_COND_LO
+
 /* addressing mode 1 */
 #define A_AM1_LSL 0
 #define A_AM1_LSR 1
 #define EOP_STR_SIMPLE(rd,rn)           EOP_C_AM2_IMM(A_COND_AL,1,0,0,rn,rd,0)
 
 #define EOP_LDR_REG_LSL(cond,rd,rn,rm,shift_imm) EOP_C_AM2_REG(cond,1,0,1,rn,rd,shift_imm,A_AM1_LSL,rm)
+#define EOP_LDRB_REG_LSL(cond,rd,rn,rm,shift_imm) EOP_C_AM2_REG(cond,1,1,1,rn,rd,shift_imm,A_AM1_LSL,rm);
 
 #define EOP_LDRH_IMM2(cond,rd,rn,offset_8)  EOP_C_AM3_IMM(cond,1,1,rn,rd,0,1,offset_8)
+#define EOP_LDRH_REG2(cond,rd,rn,rm)        EOP_C_AM3_REG(cond,1,1,rn,rd,0,1,rm)
 
 #define EOP_LDRH_IMM(   rd,rn,offset_8)  EOP_C_AM3_IMM(A_COND_AL,1,1,rn,rd,0,1,offset_8)
 #define EOP_LDRH_SIMPLE(rd,rn)           EOP_C_AM3_IMM(A_COND_AL,1,1,rn,rd,0,1,0)
@@ -479,6 +484,8 @@ static int emith_xbranch(int cond, void *target, int is_call)
 #define emith_adc_r_r(d, s) \
        EOP_ADC_REG(A_COND_AL,0,d,d,s,A_AM1_LSL,0)
 
+#define emith_and_r_r_c(cond, d, s) \
+       EOP_AND_REG(cond,0,d,d,s,A_AM1_LSL,0)
 #define emith_and_r_r(d, s) \
        EOP_AND_REG(A_COND_AL,0,d,d,s,A_AM1_LSL,0)
 
@@ -677,12 +684,24 @@ static int emith_xbranch(int cond, void *target, int is_call)
 // misc
 #define emith_read_r_r_offs_c(cond, r, rs, offs) \
        EOP_LDR_IMM2(cond, r, rs, offs)
+#define emith_read_r_r_r_c(cond, r, rs, rm) \
+       EOP_LDR_REG_LSL(cond, r, rs, rm, 0)
+#define emith_read_r_r_r(r, rs, rm) \
+       EOP_LDR_REG_LSL(A_COND_AL, r, rs, rm, 0)
 
 #define emith_read8_r_r_offs_c(cond, r, rs, offs) \
        EOP_LDRB_IMM2(cond, r, rs, offs)
+#define emith_read8_r_r_r_c(cond, r, rs, rm) \
+       EOP_LDRB_REG_LSL(cond, r, rs, rm, 0)
+#define emith_read8_r_r_r(r, rs, rm) \
+       EOP_LDRB_REG_LSL(A_COND_AL, r, rs, rm, 0)
 
 #define emith_read16_r_r_offs_c(cond, r, rs, offs) \
        EOP_LDRH_IMM2(cond, r, rs, offs)
+#define emith_read16_r_r_r_c(cond, r, rs, rm) \
+       EOP_LDRH_REG2(cond, r, rs, rm)
+#define emith_read16_r_r_r(r, rs, rm) \
+       EOP_LDRH_REG2(A_COND_AL, r, rs, rm)
 
 #define emith_read_r_r_offs(r, rs, offs) \
        emith_read_r_r_offs_c(A_COND_AL, r, rs, offs)
@@ -844,11 +863,20 @@ static int emith_xbranch(int cond, void *target, int is_call)
 #define emith_sh2_drc_exit() \
        EOP_LDMFD_SP(A_R4M|A_R5M|A_R6M|A_R7M|A_R8M|A_R9M|A_R10M|A_R11M|A_R12M|A_R15M)
 
-#define emith_sh2_wcall(a, tab) { \
-       emith_lsr(12, a, SH2_WRITE_SHIFT); \
-       EOP_LDR_REG_LSL(A_COND_AL,12,tab,12,2); \
-       emith_move_r_r(2, CONTEXT_REG); \
-       emith_jump_reg(12); \
+// assumes a is in arg0, tab, func and mask are temp
+#define emith_sh2_rcall(a, tab, func, mask) { \
+       emith_lsr(mask, a, SH2_READ_SHIFT); \
+       EOP_ADD_REG_LSL(tab, tab, mask, 3); \
+       EOP_LDMIA(tab, (1<<func)|(1<<mask)); \
+       emith_addf_r_r_r(func,func,func); \
+}
+
+// assumes a, val are in arg0 and arg1, tab and func are temp
+#define emith_sh2_wcall(a, val, tab, func) { \
+       emith_lsr(func, a, SH2_WRITE_SHIFT); \
+       EOP_LDR_REG_LSL(A_COND_AL,func,tab,func,2); \
+       emith_move_r_r(2, CONTEXT_REG); /* arg2 */ \
+       emith_jump_reg(func); \
 }
 
 #define emith_sh2_dtbf_loop() { \
index 4f9dd5a..816e929 100644 (file)
@@ -52,6 +52,9 @@ enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI };
 #define DCOND_VS ICOND_JO      // oVerflow Set
 #define DCOND_VC ICOND_JNO     // oVerflow Clear
 
+#define DCOND_CS ICOND_JB      // carry set
+#define DCOND_CC ICOND_JAE     // carry clear
+
 #define EMIT_PTR(ptr, val, type) \
        *(type *)(ptr) = val
 
@@ -118,6 +121,11 @@ enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI };
 #define emith_add_r_r(d, s) \
        EMIT_OP_MODRM(0x01, 3, s, d)
 
+#define emith_add_r_r_ptr(d, s) do { \
+       EMIT_REX_IF(1, dst, src); \
+       EMIT_OP_MODRM64(0x01, 3, s, d); \
+} while (0)
+
 #define emith_sub_r_r(d, s) \
        EMIT_OP_MODRM(0x29, 3, s, d)
 
@@ -341,6 +349,15 @@ enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI };
        emith_tst_r_imm(r, imm)
 #define emith_ror_c(cond, d, s, cnt) \
        emith_ror(d, s, cnt)
+#define emith_and_r_r_c(cond, d, s) \
+       emith_and_r_r(d, s);
+
+#define emith_read8_r_r_r_c(cond, r, rs, rm) \
+       emith_read8_r_r_r(r, rs, rm)
+#define emith_read16_r_r_r_c(cond, r, rs, rm) \
+       emith_read16_r_r_r(r, rs, rm)
+#define emith_read_r_r_r_c(cond, r, rs, rm) \
+       emith_read_r_r_r(r, rs, rm)
 
 #define emith_read_r_r_offs_c(cond, r, rs, offs) \
        emith_read_r_r_offs(r, rs, offs)
@@ -621,6 +638,30 @@ enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI };
        emith_write_r_r_offs(r, rs, offs); \
 } while (0)
 
+#define emith_read8_r_r_r(r, rs, rm) do { \
+       int r_ = r; \
+       if (!is_abcdx(r)) \
+               r_ = rcache_get_tmp(); \
+       EMIT(0x0f, u8); \
+       EMIT_OP_MODRM(0xb6, 0, r, 4); \
+       EMIT_SIB(0, rs, rm); /* mov r, [rm + rs * 1] */ \
+       if ((r) != r_) { \
+               emith_move_r_r(r, r_); \
+               rcache_free_tmp(r_); \
+       } \
+} while (0)
+
+#define emith_read16_r_r_r(r, rs, rm) do { \
+       EMIT(0x0f, u8); \
+       EMIT_OP_MODRM(0xb7, 0, r, 4); \
+       EMIT_SIB(0, rs, rm); /* mov r, [rm + rs * 1] */ \
+} while (0)
+
+#define emith_read_r_r_r(r, rs, rm) do { \
+       EMIT_OP_MODRM(0x8b, 0, r, 4); \
+       EMIT_SIB(0, rs, rm); /* mov r, [rm + rs * 1] */ \
+} while (0)
+
 #define emith_ctx_read(r, offs) \
        emith_read_r_r_offs(r, CONTEXT_REG, offs)
 
@@ -888,15 +929,30 @@ enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI };
        if ((mask) & (1 << xAX)) emith_pop(xAX); \
 } while (0)
 
-#define emith_sh2_wcall(a, tab) { \
+#define emith_sh2_rcall(a, tab, func, mask) { \
+       emith_lsr(mask, a, SH2_READ_SHIFT); \
+       EMIT_REX_IF(1, mask, tab); \
+       EMIT_OP_MODRM64(0x8d, 0, tab, 4); \
+       EMIT_SIB64(PTR_SCALE, mask, tab); /* lea tab, [tab + mask * {4,8}] */ \
+       EMIT_REX_IF(1, mask, tab); \
+       EMIT_OP_MODRM64(0x8d, 0, tab, 4); \
+       EMIT_SIB64(PTR_SCALE, mask, tab); /* lea tab, [tab + mask * {4,8}] */ \
+       EMIT_REX_IF(1, func, tab); \
+       EMIT_OP_MODRM64(0x8b, 0, func, tab); /* mov func, [tab] */ \
+       EMIT_OP_MODRM64(0x8b, 1, mask, tab); \
+       EMIT(1 << PTR_SCALE, u8); /* mov mask, [tab + {4,8}] */ \
+       emith_add_r_r_ptr(func, func); \
+}
+
+#define emith_sh2_wcall(a, val, tab, func) { \
        int arg2_; \
        host_arg2reg(arg2_, 2); \
-       emith_lsr(NA_TMP_REG, a, SH2_WRITE_SHIFT); \
-       EMIT_REX_IF(1, NA_TMP_REG, tab); \
-       EMIT_OP_MODRM64(0x8b, 0, NA_TMP_REG, 4); \
-       EMIT_SIB64(PTR_SCALE, NA_TMP_REG, tab); /* mov tmp, [tab + tmp * {4,8}] */ \
+       emith_lsr(func, a, SH2_WRITE_SHIFT); /* tmp = a >> WRT_SHIFT */ \
+       EMIT_REX_IF(1, func, tab); \
+       EMIT_OP_MODRM64(0x8b, 0, func, 4); \
+       EMIT_SIB64(PTR_SCALE, func, tab); /* mov tmp, [tab + tmp * {4,8}] */ \
        emith_move_r_r_ptr(arg2_, CONTEXT_REG); \
-       emith_jump_reg(NA_TMP_REG); \
+       emith_jump_reg(func); \
 }
 
 #define emith_sh2_dtbf_loop() { \
index 1b300cc..bfd98e2 100644 (file)
@@ -328,7 +328,7 @@ struct block_list {
 static struct block_list **inval_lookup[TCACHE_BUFFERS];
 
 static const int hash_table_sizes[TCACHE_BUFFERS] = {
-  0x1000,
+  0x4000,
   0x100,
   0x100,
 };
@@ -498,12 +498,12 @@ static void            (*sh2_drc_dispatcher)(void);
 static void            (*sh2_drc_exit)(void);
 static void            (*sh2_drc_test_irq)(void);
 
-static u32  REGPARM(2) (*sh2_drc_read8)(u32 a, SH2 *sh2);
-static u32  REGPARM(2) (*sh2_drc_read16)(u32 a, SH2 *sh2);
-static u32  REGPARM(2) (*sh2_drc_read32)(u32 a, SH2 *sh2);
+static u32  REGPARM(1) (*sh2_drc_read8)(u32 a);
+static u32  REGPARM(1) (*sh2_drc_read16)(u32 a);
+static u32  REGPARM(1) (*sh2_drc_read32)(u32 a);
 static void REGPARM(2) (*sh2_drc_write8)(u32 a, u32 d);
 static void REGPARM(2) (*sh2_drc_write16)(u32 a, u32 d);
-static void REGPARM(3) (*sh2_drc_write32)(u32 a, u32 d, SH2 *sh2);
+static void REGPARM(2) (*sh2_drc_write32)(u32 a, u32 d);
 
 // flags for memory access
 #define MF_SIZEMASK 0x03        // size of access
@@ -787,7 +787,7 @@ static void *dr_prepare_ext_branch(u32 pc, int is_slave, int tcache_id)
   cnt = i + 1;
   if (cnt >= block_link_pool_max_counts[tcache_id]) {
     dbg(1, "bl overflow for tcache %d", tcache_id);
-    return NULL;
+    return sh2_drc_dispatcher;
   }
   bl += cnt;
   block_link_pool_counts[tcache_id]++;
@@ -848,7 +848,7 @@ static void dr_link_blocks(struct block_entry *be, int tcache_id)
     dbg(1, "warning: " #array " overflow"); \
     failcode; \
   } else \
-  array[count++] = item; \
+    array[count++] = item; \
 }
 
 static int find_in_array(u32 *array, size_t size, u32 what)
@@ -1806,7 +1806,7 @@ static int emit_get_rbase_and_offs(SH2 *sh2, u32 a, u32 *offs)
   hr = rcache_get_tmp();
   if (mask < 0x1000) {
     // can't access data array or BIOS directly from ROM or SDRAM,
-    // since code may run on both SH2s (if the tcache_id would be known...)
+    // since code may run on both SH2s (tcache_id of translation block needed))
     emith_ctx_read(hr, poffs);
     if (a & mask & ~omask)
       emith_add_r_imm(hr, a & mask & ~omask);
@@ -1896,8 +1896,6 @@ static void emit_or_t_if_eq(int srr)
 // rd = @(arg0)
 static int emit_memhandler_read(int size)
 {
-  int arg1;
-
   rcache_clean_tmp();
 #ifndef DRC_SR_REG
   // must writeback cycles for poll detection stuff
@@ -1905,8 +1903,6 @@ static int emit_memhandler_read(int size)
     rcache_evict_vreg(guest_regs[SHR_SR].vreg);
 #endif
 
-  arg1 = rcache_get_tmp_arg(1);
-  emith_move_r_r_ptr(arg1, CONTEXT_REG);
   switch (size & MF_SIZEMASK) {
   case 0:   emith_call(sh2_drc_read8);      break; // 8
   case 1:   emith_call(sh2_drc_read16);     break; // 16
@@ -1920,16 +1916,12 @@ static int emit_memhandler_read(int size)
 // @(arg0) = arg1
 static void emit_memhandler_write(int size)
 {
-  int arg2;
-
   rcache_clean_tmp();
 #ifndef DRC_SR_REG
   if (guest_regs[SHR_SR].vreg != -1)
     rcache_evict_vreg(guest_regs[SHR_SR].vreg);
 #endif
 
-  arg2 = rcache_get_tmp_arg(2);
-  emith_move_r_r_ptr(arg2, CONTEXT_REG);
   switch (size & MF_SIZEMASK) {
   case 0:   emith_call(sh2_drc_write8);     break;  // 8
   case 1:   emith_call(sh2_drc_write16);    break;  // 16
@@ -2372,7 +2364,6 @@ static void REGPARM(2) *sh2_translate(SH2 *sh2, int 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, NULL);
       FLUSH_CYCLES(sr);
       rcache_clean();
@@ -2392,7 +2383,6 @@ static void REGPARM(2) *sh2_translate(SH2 *sh2, int tcache_id)
 
 #ifdef DRC_CMP
     if (!(op_flags[i] & OF_DELAY_OP)) {
-      emit_move_r_imm32(SHR_PC, pc);
       sr = rcache_get_reg(SHR_SR, RC_GR_RMW, NULL);
       FLUSH_CYCLES(sr);
       rcache_clean();
@@ -3666,16 +3656,69 @@ end_op:
 
 static void sh2_generate_utils(void)
 {
-  int arg0, arg1, arg2, sr, tmp;
-
-  sh2_drc_read8  = p32x_sh2_read8;
-  sh2_drc_read16 = p32x_sh2_read16;
-  sh2_drc_read32 = p32x_sh2_read32;
+  int arg0, arg1, arg2, arg3, sr, tmp;
 
   host_arg2reg(arg0, 0);
   host_arg2reg(arg1, 1);
   host_arg2reg(arg2, 2);
+  host_arg2reg(arg3, 3);
   emith_move_r_r(arg0, arg0); // nop
+  emith_move_r_r(arg1, arg1); // nop
+  emith_move_r_r(arg2, arg2); // nop
+  emith_move_r_r(arg3, arg3); // nop
+
+  // sh2_drc_write8(u32 a, u32 d)
+  sh2_drc_write8 = (void *)tcache_ptr;
+  emith_ctx_read_ptr(arg2, offsetof(SH2, write8_tab));
+  emith_sh2_wcall(arg0, arg1, arg2, arg3);
+
+  // sh2_drc_write16(u32 a, u32 d)
+  sh2_drc_write16 = (void *)tcache_ptr;
+  emith_ctx_read_ptr(arg2, offsetof(SH2, write16_tab));
+  emith_sh2_wcall(arg0, arg1, arg2, arg3);
+
+  // sh2_drc_write32(u32 a, u32 d)
+  sh2_drc_write32 = (void *)tcache_ptr;
+  emith_ctx_read_ptr(arg2, offsetof(SH2, write32_tab));
+  emith_sh2_wcall(arg0, arg1, arg2, arg3);
+
+  // d = sh2_drc_read8(u32 a)
+  sh2_drc_read8 = (void *)tcache_ptr;
+  emith_ctx_read_ptr(arg1, offsetof(SH2, read8_map));
+  emith_sh2_rcall(arg0, arg1, arg2, arg3);
+  EMITH_SJMP_START(DCOND_CS);
+  emith_and_r_r_c(DCOND_CC, arg0, arg3);
+  emith_eor_r_imm_c(DCOND_CC, arg0, 1);
+  emith_read8_r_r_r_c(DCOND_CC, RET_REG, arg0, arg2);
+  emith_ret_c(DCOND_CC);
+  EMITH_SJMP_END(DCOND_CS);
+  emith_move_r_r_ptr(arg1, CONTEXT_REG);
+  emith_jump_reg(arg2);
+
+  // d = sh2_drc_read16(u32 a)
+  sh2_drc_read16 = (void *)tcache_ptr;
+  emith_ctx_read_ptr(arg1, offsetof(SH2, read16_map));
+  emith_sh2_rcall(arg0, arg1, arg2, arg3);
+  EMITH_SJMP_START(DCOND_CS);
+  emith_and_r_r_c(DCOND_CC, arg0, arg3);
+  emith_read16_r_r_r_c(DCOND_CC, RET_REG, arg0, arg2);
+  emith_ret_c(DCOND_CC);
+  EMITH_SJMP_END(DCOND_CS);
+  emith_move_r_r_ptr(arg1, CONTEXT_REG);
+  emith_jump_reg(arg2);
+
+  // d = sh2_drc_read32(u32 a)
+  sh2_drc_read32 = (void *)tcache_ptr;
+  emith_ctx_read_ptr(arg1, offsetof(SH2, read32_map));
+  emith_sh2_rcall(arg0, arg1, arg2, arg3);
+  EMITH_SJMP_START(DCOND_CS);
+  emith_and_r_r_c(DCOND_CC, arg0, arg3);
+  emith_read_r_r_r_c(DCOND_CC, RET_REG, arg0, arg2);
+  emith_ror_c(DCOND_CC, RET_REG, RET_REG, 16);
+  emith_ret_c(DCOND_CC);
+  EMITH_SJMP_END(DCOND_CS);
+  emith_move_r_r_ptr(arg1, CONTEXT_REG);
+  emith_jump_reg(arg2);
 
   // sh2_drc_exit(void)
   sh2_drc_exit = (void *)tcache_ptr;
@@ -3766,21 +3809,6 @@ static void sh2_generate_utils(void)
   emith_call(sh2_drc_test_irq);
   emith_jump(sh2_drc_dispatcher);
 
-  // sh2_drc_write8(u32 a, u32 d)
-  sh2_drc_write8 = (void *)tcache_ptr;
-  emith_ctx_read_ptr(arg2, offsetof(SH2, write8_tab));
-  emith_sh2_wcall(arg0, arg2);
-
-  // sh2_drc_write16(u32 a, u32 d)
-  sh2_drc_write16 = (void *)tcache_ptr;
-  emith_ctx_read_ptr(arg2, offsetof(SH2, write16_tab));
-  emith_sh2_wcall(arg0, arg2);
-
-  // sh2_drc_write32(u32 a, u32 d)
-  sh2_drc_write32 = (void *)tcache_ptr;
-  emith_ctx_read_ptr(arg2, offsetof(SH2, write32_tab));
-  emith_sh2_wcall(arg0, arg2);
-
 #ifdef PDB_NET
   // debug
   #define MAKE_READ_WRAPPER(func) { \
@@ -3815,11 +3843,6 @@ static void sh2_generate_utils(void)
   MAKE_WRITE_WRAPPER(sh2_drc_write8);
   MAKE_WRITE_WRAPPER(sh2_drc_write16);
   MAKE_WRITE_WRAPPER(sh2_drc_write32);
-#if (DRC_DEBUG & 4)
-  host_dasm_new_symbol(sh2_drc_read8);
-  host_dasm_new_symbol(sh2_drc_read16);
-  host_dasm_new_symbol(sh2_drc_read32);
-#endif
 #endif
 
   rcache_invalidate();
@@ -3831,6 +3854,9 @@ static void sh2_generate_utils(void)
   host_dasm_new_symbol(sh2_drc_write8);
   host_dasm_new_symbol(sh2_drc_write16);
   host_dasm_new_symbol(sh2_drc_write32);
+  host_dasm_new_symbol(sh2_drc_read8);
+  host_dasm_new_symbol(sh2_drc_read16);
+  host_dasm_new_symbol(sh2_drc_read32);
 #endif
 }
 
@@ -3955,14 +3981,15 @@ static void sh2_smc_rm_blocks(u32 a, u16 *drc_ram_blk, int tcache_id, u32 shift,
   }
 }
 
-void sh2_drc_wcheck_ram(unsigned int a, int val, int cpuid)
+void sh2_drc_wcheck_ram(unsigned int a, int val, SH2 *sh2)
 {
-  dbg(2, "%csh2 smc check @%08x", cpuid ? 's' : 'm', a);
+  dbg(2, "%csh2 smc check @%08x", sh2->is_slave ? 's' : 'm', a);
   sh2_smc_rm_blocks(a, Pico32xMem->drcblk_ram, 0, SH2_DRCBLK_RAM_SHIFT, 0x3ffff);
 }
 
-void sh2_drc_wcheck_da(unsigned int a, int val, int cpuid)
+void sh2_drc_wcheck_da(unsigned int a, int val, SH2 *sh2)
 {
+  int cpuid = sh2->is_slave;
   dbg(2, "%csh2 smc check @%08x", cpuid ? 's' : 'm', a);
   sh2_smc_rm_blocks(a, Pico32xMem->drcblk_da[cpuid],
     1 + cpuid, SH2_DRCBLK_DA_SHIFT, 0xfff);
@@ -4051,6 +4078,9 @@ void sh2_drc_mem_setup(SH2 *sh2)
   sh2->p_da = sh2->data_array;
   sh2->p_sdram = Pico32xMem->sdram;
   sh2->p_rom = Pico.rom;
+  // sh2->p_dram filled in dram bank switching
+  sh2->p_drcblk_da = Pico32xMem->drcblk_da[!!sh2->is_slave];
+  sh2->p_drcblk_ram = Pico32xMem->drcblk_ram;
 }
 
 void sh2_drc_frame(void)
@@ -4103,6 +4133,7 @@ int sh2_drc_init(SH2 *sh2)
     // disasm the utils
     tcache_dsm_ptrs[0] = tcache;
     do_host_disasm(0);
+    fflush(stdout);
 #endif
 #if (DRC_DEBUG & 1)
     hash_collisions = 0;
index b690435..6a8596b 100644 (file)
@@ -1,7 +1,7 @@
 int  sh2_drc_init(SH2 *sh2);
 void sh2_drc_finish(SH2 *sh2);
-void sh2_drc_wcheck_ram(unsigned int a, int val, int cpuid);
-void sh2_drc_wcheck_da(unsigned int a, int val, int cpuid);
+void sh2_drc_wcheck_ram(unsigned int a, int val, SH2 *sh2);
+void sh2_drc_wcheck_da(unsigned int a, int val, SH2 *sh2);
 
 #ifdef DRC_SH2
 void sh2_drc_mem_setup(SH2 *sh2);
index 7faa844..a073d43 100644 (file)
@@ -36,6 +36,9 @@ typedef struct SH2_
        void            *p_da;\r
        void            *p_sdram;\r
        void            *p_rom;\r
+       void            *p_dram;\r
+       void            *p_drcblk_da;\r
+       void            *p_drcblk_ram;\r
        unsigned int    pdb_io_csum[2];\r
 \r
 #define SH2_STATE_RUN   (1 << 0)       // to prevent recursion\r
index 8f2a7c2..4732983 100644 (file)
@@ -1066,41 +1066,41 @@ void PicoWrite16_32x(u32 a, u32 d)
 }
 
 /* quirk: in both normal and overwrite areas only nonzero values go through */
-#define sh2_write8_dramN(n) \
+#define sh2_write8_dramN(p, a, d) \
   if ((d & 0xff) != 0) { \
-    u8 *dram = (u8 *)Pico32xMem->dram[n]; \
+    u8 *dram = (u8 *)p; \
     dram[(a & 0x1ffff) ^ 1] = d; \
   }
 
 static void m68k_write8_dram0_ow(u32 a, u32 d)
 {
-  sh2_write8_dramN(0);
+  sh2_write8_dramN(Pico32xMem->dram[0], a, d);
 }
 
 static void m68k_write8_dram1_ow(u32 a, u32 d)
 {
-  sh2_write8_dramN(1);
+  sh2_write8_dramN(Pico32xMem->dram[1], a, d);
 }
 
-#define sh2_write16_dramN(n) \
-  u16 *pd = &Pico32xMem->dram[n][(a & 0x1ffff) / 2]; \
+#define sh2_write16_dramN(p, a, d) \
+  u16 *pd = &((u16 *)p)[(a & 0x1ffff) / 2]; \
   if (!(a & 0x20000)) { \
     *pd = d; \
-    return; \
-  } \
-  /* overwrite */ \
-  if (!(d & 0x00ff)) d |= *pd & 0x00ff; \
-  if (!(d & 0xff00)) d |= *pd & 0xff00; \
-  *pd = d;
+  } else { \
+    u16 v = *pd; /* overwrite */ \
+    if (!(d & 0x00ff)) d |= v & 0x00ff; \
+    if (!(d & 0xff00)) d |= v & 0xff00; \
+    *pd = d; \
+  }
 
 static void m68k_write16_dram0_ow(u32 a, u32 d)
 {
-  sh2_write16_dramN(0);
+  sh2_write16_dramN(Pico32xMem->dram[0], a, d);
 }
 
 static void m68k_write16_dram1_ow(u32 a, u32 d)
 {
-  sh2_write16_dramN(1);
+  sh2_write16_dramN(Pico32xMem->dram[1], a, d);
 }
 
 // -----------------------------------------------------------------
@@ -1229,14 +1229,14 @@ static void bank_switch_rom_68k(int b)
 // -----------------------------------------------------------------
 
 // read8
-static u32 sh2_read8_unmapped(u32 a, SH2 *sh2)
+static REGPARM(2) u32 sh2_read8_unmapped(u32 a, SH2 *sh2)
 {
   elprintf_sh2(sh2, EL_32X, "unmapped r8  [%08x]       %02x @%06x",
     a, 0, sh2_pc(sh2));
   return 0;
 }
 
-static u32 sh2_read8_cs0(u32 a, SH2 *sh2)
+static u32 REGPARM(2) sh2_read8_cs0(u32 a, SH2 *sh2)
 {
   u32 d = 0;
   DRC_SAVE_SR(sh2);
@@ -1282,27 +1282,28 @@ out:
   return d;
 }
 
-static u32 sh2_read8_da(u32 a, SH2 *sh2)
+static u32 REGPARM(2) sh2_read8_da(u32 a, SH2 *sh2)
 {
   return sh2->data_array[(a & 0xfff) ^ 1];
 }
 
 // for ssf2
-static u32 sh2_read8_rom(u32 a, SH2 *sh2)
+static u32 REGPARM(2) sh2_read8_rom(u32 a, SH2 *sh2)
 {
   u32 bank = carthw_ssf2_banks[(a >> 19) & 7] << 19;
-  return Pico.rom[(bank + (a & 0x7ffff)) ^ 1];
+  u8 *p = sh2->p_rom;
+  return p[(bank + (a & 0x7ffff)) ^ 1];
 }
 
 // read16
-static u32 sh2_read16_unmapped(u32 a, SH2 *sh2)
+static u32 REGPARM(2) sh2_read16_unmapped(u32 a, SH2 *sh2)
 {
   elprintf_sh2(sh2, EL_32X, "unmapped r16 [%08x]     %04x @%06x",
     a, 0, sh2_pc(sh2));
   return 0;
 }
 
-static u32 sh2_read16_cs0(u32 a, SH2 *sh2)
+static u32 REGPARM(2) sh2_read16_cs0(u32 a, SH2 *sh2)
 {
   u32 d = 0;
   DRC_SAVE_SR(sh2);
@@ -1342,39 +1343,41 @@ out_noprint:
   return d;
 }
 
-static u32 sh2_read16_da(u32 a, SH2 *sh2)
+static u32 REGPARM(2) sh2_read16_da(u32 a, SH2 *sh2)
 {
   return ((u16 *)sh2->data_array)[(a & 0xffe) / 2];
 }
 
-static u32 sh2_read16_rom(u32 a, SH2 *sh2)
+static u32 REGPARM(2) sh2_read16_rom(u32 a, SH2 *sh2)
 {
   u32 bank = carthw_ssf2_banks[(a >> 19) & 7] << 19;
-  return *(u16 *)(Pico.rom + bank + (a & 0x7fffe));
+  u16 *p = sh2->p_rom;
+  return p[(bank + (a & 0x7fffe)) / 2];
 }
 
-static u32 sh2_read32_unmapped(u32 a, SH2 *sh2)
+static u32 REGPARM(2) sh2_read32_unmapped(u32 a, SH2 *sh2)
 {
   elprintf_sh2(sh2, EL_32X, "unmapped r32 [%08x]     %08x @%06x",
     a, 0, sh2_pc(sh2));
   return 0;
 }
 
-static u32 sh2_read32_cs0(u32 a, SH2 *sh2)
+static u32 REGPARM(2) sh2_read32_cs0(u32 a, SH2 *sh2)
 {
   return (sh2_read16_cs0(a, sh2) << 16) | sh2_read16_cs0(a + 2, sh2);
 }
 
-static u32 sh2_read32_da(u32 a, SH2 *sh2)
+static u32 REGPARM(2) sh2_read32_da(u32 a, SH2 *sh2)
 {
   u32 d = *((u32 *)sh2->data_array + (a & 0xffc)/4);
   return (d << 16) | (d >> 16);
 }
 
-static u32 sh2_read32_rom(u32 a, SH2 *sh2)
+static u32 REGPARM(2) sh2_read32_rom(u32 a, SH2 *sh2)
 {
   u32 bank = carthw_ssf2_banks[(a >> 19) & 7] << 19;
-  u32 d = *(u32 *)(Pico.rom + bank + (a & 0x7fffc));
+  u32 *p = sh2->p_rom;
+  u32 d = p[(bank + (a & 0x7fffc)) / 4];
   return (d << 16) | (d >> 16);
 }
 
@@ -1420,25 +1423,21 @@ out:
   DRC_RESTORE_SR(sh2);
 }
 
-static void REGPARM(3) sh2_write8_dram0(u32 a, u32 d, SH2 *sh2)
-{
-  sh2_write8_dramN(0);
-}
-
-static void REGPARM(3) sh2_write8_dram1(u32 a, u32 d, SH2 *sh2)
+static void REGPARM(3) sh2_write8_dram(u32 a, u32 d, SH2 *sh2)
 {
-  sh2_write8_dramN(1);
+  sh2_write8_dramN(sh2->p_dram, a, d);
 }
 
 static void REGPARM(3) sh2_write8_sdram(u32 a, u32 d, SH2 *sh2)
 {
   u32 a1 = a & 0x3ffff;
 #ifdef DRC_SH2
-  int t = Pico32xMem->drcblk_ram[a1 >> SH2_DRCBLK_RAM_SHIFT];
+  u16 *p = sh2->p_drcblk_ram;
+  int t = p[a1 >> SH2_DRCBLK_RAM_SHIFT];
   if (t)
-    sh2_drc_wcheck_ram(a, t, sh2->is_slave);
+    sh2_drc_wcheck_ram(a, t, sh2);
 #endif
-  Pico32xMem->sdram[a1 ^ 1] = d;
+  ((u8 *)sh2->p_sdram)[a1 ^ 1] = d;
 }
 
 static void REGPARM(3) sh2_write8_sdram_wt(u32 a, u32 d, SH2 *sh2)
@@ -1457,10 +1456,10 @@ static void REGPARM(3) sh2_write8_da(u32 a, u32 d, SH2 *sh2)
 {
   u32 a1 = a & 0xfff;
 #ifdef DRC_SH2
-  int id = sh2->is_slave;
-  int t = Pico32xMem->drcblk_da[id][a1 >> SH2_DRCBLK_DA_SHIFT];
+  u16 *p = sh2->p_drcblk_da;
+  int t = p[a1 >> SH2_DRCBLK_DA_SHIFT];
   if (t)
-    sh2_drc_wcheck_da(a, t, id);
+    sh2_drc_wcheck_da(a, t, sh2);
 #endif
   sh2->data_array[a1 ^ 1] = d;
 }
@@ -1503,42 +1502,38 @@ out:
   DRC_RESTORE_SR(sh2);
 }
 
-static void REGPARM(3) sh2_write16_dram0(u32 a, u32 d, SH2 *sh2)
+static void REGPARM(3) sh2_write16_dram(u32 a, u32 d, SH2 *sh2)
 {
-  sh2_write16_dramN(0);
-}
-
-static void REGPARM(3) sh2_write16_dram1(u32 a, u32 d, SH2 *sh2)
-{
-  sh2_write16_dramN(1);
+  sh2_write16_dramN(sh2->p_dram, a, d);
 }
 
 static void REGPARM(3) sh2_write16_sdram(u32 a, u32 d, SH2 *sh2)
 {
-  u32 a1 = a & 0x3ffff;
+  u32 a1 = a & 0x3fffe;
 #ifdef DRC_SH2
-  int t = Pico32xMem->drcblk_ram[a1 >> SH2_DRCBLK_RAM_SHIFT];
+  u16 *p = sh2->p_drcblk_ram;
+  int t = p[a1 >> SH2_DRCBLK_RAM_SHIFT];
   if (t)
-    sh2_drc_wcheck_ram(a, t, sh2->is_slave);
+    sh2_drc_wcheck_ram(a, t, sh2);
 #endif
-  ((u16 *)Pico32xMem->sdram)[a1 / 2] = d;
+  ((u16 *)sh2->p_sdram)[a1 / 2] = d;
 }
 
 static void REGPARM(3) sh2_write16_da(u32 a, u32 d, SH2 *sh2)
 {
-  u32 a1 = a & 0xfff;
+  u32 a1 = a & 0xffe;
 #ifdef DRC_SH2
-  int id = sh2->is_slave;
-  int t = Pico32xMem->drcblk_da[id][a1 >> SH2_DRCBLK_DA_SHIFT];
+  u16 *p = sh2->p_drcblk_da;
+  int t = p[a1 >> SH2_DRCBLK_DA_SHIFT];
   if (t)
-    sh2_drc_wcheck_da(a, t, id);
+    sh2_drc_wcheck_da(a, t, sh2);
 #endif
   ((u16 *)sh2->data_array)[a1 / 2] = d;
 }
 
 static void REGPARM(3) sh2_write16_rom(u32 a, u32 d, SH2 *sh2)
 {
-  u32 a1 = a & 0x3fffff;
+  u32 a1 = a & 0x3ffffe;
   // tweak for WWF Raw: does writes to ROM area, and it doesn't work without
   // allowing this.
   // Presumably the write goes to the CPU cache and is read back from there,
@@ -1562,54 +1557,53 @@ static void REGPARM(3) sh2_write32_cs0(u32 a, u32 d, SH2 *sh2)
   sh2_write16_cs0(a + 2, d, sh2);
 }
 
-#define sh2_write32_dramN(n) \
-  u32 *pd = (u32 *)&Pico32xMem->dram[n][(a & 0x1ffff) / 2]; \
+#define sh2_write32_dramN(p, a, d) \
+  u32 *pd = &((u32 *)p)[(a & 0x1ffff) / 4]; \
   if (!(a & 0x20000)) { \
     *pd = (d << 16) | (d >> 16); \
-    return; \
-  } \
-  /* overwrite */ \
-  u8 *pb = (u8 *)pd; \
-  if (d & 0x000000ff) pb[2] = d; \
-  if (d & 0x0000ff00) pb[3] = d >> 8; \
-  if (d & 0x00ff0000) pb[0] = d >> 16; \
-  if (d & 0xff000000) pb[1] = d >> 24; \
-
-static void REGPARM(3) sh2_write32_dram0(u32 a, u32 d, SH2 *sh2)
-{
-  sh2_write32_dramN(0);
-}
+  } else { \
+    /* overwrite */ \
+    u32 v = *pd, m = 0; d = (d << 16) | (d >> 16) ; \
+    if (!(d & 0x000000ff)) m |= 0x000000ff; \
+    if (!(d & 0x0000ff00)) m |= 0x0000ff00; \
+    if (!(d & 0x00ff0000)) m |= 0x00ff0000; \
+    if (!(d & 0xff000000)) m |= 0xff000000; \
+    *pd = d | (v&m); \
+  }
 
-static void REGPARM(3) sh2_write32_dram1(u32 a, u32 d, SH2 *sh2)
+static void REGPARM(3) sh2_write32_dram(u32 a, u32 d, SH2 *sh2)
 {
-  sh2_write32_dramN(1);
+  sh2_write32_dramN(sh2->p_dram, a, d);
 }
 
 static void REGPARM(3) sh2_write32_sdram(u32 a, u32 d, SH2 *sh2)
 {
   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+2, p[1], sh2->is_slave);
+  u16 *p = sh2->p_drcblk_ram;
+  int t = p[a1 >> SH2_DRCBLK_RAM_SHIFT];
+  if (t)
+    sh2_drc_wcheck_ram(a, t, sh2);
+  int u = p[(a1+2) >> SH2_DRCBLK_RAM_SHIFT];
+  if (u)
+    sh2_drc_wcheck_ram(a+2, u, sh2);
 #endif
+  *(u32 *)(sh2->p_sdram + a1) = (d << 16) | (d >> 16);
 }
 
 static void REGPARM(3) sh2_write32_da(u32 a, u32 d, SH2 *sh2)
 {
   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+2, p[1], id);
+  u16 *p = sh2->p_drcblk_da;
+  int t = p[a1 >> SH2_DRCBLK_DA_SHIFT];
+  if (t)
+    sh2_drc_wcheck_da(a, t, sh2);
+  int u = p[(a1+2) >> SH2_DRCBLK_DA_SHIFT];
+  if (u)
+    sh2_drc_wcheck_da(a+2, u, sh2);
 #endif
+  *((u32 *)sh2->data_array + a1/4) = (d << 16) | (d >> 16);
 }
 
 static void REGPARM(3) sh2_write32_rom(u32 a, u32 d, SH2 *sh2)
@@ -1919,9 +1913,7 @@ void Pico32xSwapDRAM(int b)
   sh2_read16_map[0x04/2].addr = sh2_read16_map[0x24/2].addr =
   sh2_read32_map[0x04/2].addr = sh2_read32_map[0x24/2].addr = MAP_MEMORY(Pico32xMem->dram[b]);
 
-  sh2_write8_map[0x04/2]  = sh2_write8_map[0x24/2]  = b ? sh2_write8_dram1 : sh2_write8_dram0;
-  sh2_write16_map[0x04/2] = sh2_write16_map[0x24/2] = b ? sh2_write16_dram1 : sh2_write16_dram0;
-  sh2_write32_map[0x04/2] = sh2_write32_map[0x24/2] = b ? sh2_write32_dram1 : sh2_write32_dram0;
+  msh2.p_dram = ssh2.p_dram = Pico32xMem->dram[b]; // DRC conveniance ptr
 }
 
 static void bank_switch_rom_sh2(void)
@@ -2035,10 +2027,14 @@ void PicoMemSetup32x(void)
   sh2_read32_map[0x02/2].mask = sh2_read32_map[0x22/2].mask = 0x3ffffc; // FIXME
   sh2_write16_map[0x02/2] = sh2_write16_map[0x22/2] = sh2_write16_rom;
   sh2_write32_map[0x02/2] = sh2_write32_map[0x22/2] = sh2_write32_rom;
-  // CS2 - DRAM - done by Pico32xSwapDRAM()
+  // CS2 - DRAM 
   sh2_read8_map[0x04/2].mask  = sh2_read8_map[0x24/2].mask  = 0x01ffff;
   sh2_read16_map[0x04/2].mask = sh2_read16_map[0x24/2].mask = 0x01fffe;
   sh2_read32_map[0x04/2].mask = sh2_read32_map[0x24/2].mask = 0x01fffc;
+  sh2_write8_map[0x04/2]  = sh2_write8_map[0x24/2]  = sh2_write8_dram;
+  sh2_write16_map[0x04/2] = sh2_write16_map[0x24/2] = sh2_write16_dram;
+  sh2_write32_map[0x04/2] = sh2_write32_map[0x24/2] = sh2_write32_dram;
+
   // CS3 - SDRAM
   sh2_read8_map[0x06/2].addr   = sh2_read8_map[0x26/2].addr   =
   sh2_read16_map[0x06/2].addr  = sh2_read16_map[0x26/2].addr  =
diff --git a/pico/32x/memory_arm.S b/pico/32x/memory_arm.S
new file mode 100644 (file)
index 0000000..90c86dd
--- /dev/null
@@ -0,0 +1,305 @@
+/*\r
+ * PicoDrive 32X memory access functions, assembler version\r
+ * (C) KUB, 2018\r
+ *\r
+ * This work is licensed under the terms of MAME license.\r
+ * See COPYING file in the top-level directory.\r
+ */\r
+\r
+#include "../pico_int_o32.h"\r
+\r
+@ 32X bank sizes... TODO this should somehow come from an include file\r
+.equ SH2_ROM_SHIFT, 10      @ 0x003fffff\r
+.equ SH2_RAM_SHIFT, 14      @ 0x0003ffff\r
+.equ SH2_DRAM_SHIFT,15      @ 0x0001ffff\r
+.equ SH2_DA_SHIFT,  20      @ 0x00000fff\r
+\r
+.equ SH2_DRAM_OW, 1<<(32-SH2_DRAM_SHIFT) @ DRAM overwrite mode bit\r
+\r
+.text\r
+\r
+@ u32 a\r
+.global sh2_read8_rom\r
+.global sh2_read8_sdram\r
+.global sh2_read8_da\r
+.global sh2_read8_dram\r
+.global sh2_read16_rom\r
+.global sh2_read16_sdram\r
+.global sh2_read16_da\r
+.global sh2_read16_dram\r
+.global sh2_read32_rom\r
+.global sh2_read32_sdram\r
+.global sh2_read32_da\r
+.global sh2_read32_dram\r
+\r
+@ u32 a, u32 d\r
+.global sh2_write8_sdram\r
+.global sh2_write8_da\r
+.global sh2_write8_dram\r
+.global sh2_write16_sdram\r
+.global sh2_write16_da\r
+.global sh2_write16_dram\r
+.global sh2_write32_sdram\r
+.global sh2_write32_da\r
+.global sh2_write32_dram\r
+\r
+sh2_read8_rom:\r
+    ldr     ip, [r1, #OFS_SH2_p_rom]\r
+    eor     r0, r0, #1\r
+    lsl     r0, #SH2_ROM_SHIFT\r
+    ldrb    r0, [ip, r0, lsr #SH2_ROM_SHIFT]\r
+    bx      lr\r
+\r
+sh2_read8_sdram:\r
+    ldr     ip, [r1, #OFS_SH2_p_sdram]\r
+    eor     r0, r0, #1\r
+    lsl     r0, #SH2_RAM_SHIFT\r
+    ldrb    r0, [ip, r0, lsr #SH2_RAM_SHIFT]\r
+    bx      lr\r
+\r
+sh2_read8_da:\r
+    ldr     ip, [r1, #OFS_SH2_p_da]\r
+    eor     r0, r0, #1\r
+    lsl     r0, #SH2_DA_SHIFT\r
+    ldrb    r0, [ip, r0, lsr #SH2_DA_SHIFT]\r
+    bx      lr\r
+\r
+sh2_read8_dram:\r
+    ldr     ip, [r1, #OFS_SH2_p_dram]\r
+    eor     r0, r0, #1\r
+    lsl     r0, #SH2_DRAM_SHIFT\r
+    ldrb    r0, [ip, r0, lsr #SH2_DRAM_SHIFT]\r
+    bx      lr\r
+\r
+sh2_read16_rom:\r
+    ldr     ip, [r1, #OFS_SH2_p_rom]\r
+    lsl     r0, #SH2_ROM_SHIFT\r
+    lsr     r0, #SH2_ROM_SHIFT\r
+    ldrh    r0, [ip, r0]\r
+    bx      lr\r
+\r
+sh2_read16_sdram:\r
+    ldr     ip, [r1, #OFS_SH2_p_sdram]\r
+    lsl     r0, #SH2_RAM_SHIFT\r
+    lsr     r0, #SH2_RAM_SHIFT\r
+    ldrh    r0, [ip, r0]\r
+    bx      lr\r
+\r
+sh2_read16_da:\r
+    ldr     ip, [r1, #OFS_SH2_p_da]\r
+    lsl     r0, #SH2_DA_SHIFT\r
+    lsr     r0, #SH2_DA_SHIFT\r
+    ldrh    r0, [ip, r0]\r
+    bx      lr\r
+\r
+sh2_read16_dram:\r
+    ldr     ip, [r1, #OFS_SH2_p_dram]\r
+    lsl     r0, #SH2_DRAM_SHIFT\r
+    lsr     r0, #SH2_DRAM_SHIFT\r
+    ldrh    r0, [ip, r0]\r
+    bx      lr\r
+\r
+sh2_read32_rom:\r
+    ldr     ip, [r1, #OFS_SH2_p_rom]\r
+    lsl     r0, #SH2_ROM_SHIFT\r
+    ldr     r0, [ip, r0, lsr #SH2_ROM_SHIFT]\r
+    ror     r0, r0, #16\r
+    bx      lr\r
+\r
+sh2_read32_sdram:\r
+    ldr     ip, [r1, #OFS_SH2_p_sdram]\r
+    lsl     r0, #SH2_RAM_SHIFT\r
+    ldr     r0, [ip, r0, lsr #SH2_RAM_SHIFT]\r
+    ror     r0, r0, #16\r
+    bx      lr\r
+\r
+sh2_read32_da:\r
+    ldr     ip, [r1, #OFS_SH2_p_da]\r
+    lsl     r0, #SH2_DA_SHIFT\r
+    ldr     r0, [ip, r0, lsr #SH2_DA_SHIFT]\r
+    ror     r0, r0, #16\r
+    bx      lr\r
+\r
+sh2_read32_dram:\r
+    ldr     ip, [r1, #OFS_SH2_p_dram]\r
+    lsl     r0, #SH2_DRAM_SHIFT\r
+    ldr     r0, [ip, r0, lsr #SH2_DRAM_SHIFT]\r
+    ror     r0, r0, #16\r
+    bx      lr\r
+\r
+sh2_write8_sdram:\r
+    @ preserve r0 and r2 for tail call\r
+    ldr     ip, [r2, #OFS_SH2_p_sdram]\r
+    eor     r3, r0, #1\r
+    lsl     r3, #SH2_RAM_SHIFT\r
+    strb    r1, [ip, r3, lsr #SH2_RAM_SHIFT]\r
+#ifdef DRC_SH2\r
+    ldr     ip, [r2, #OFS_SH2_p_drcblk_ram]\r
+    ldrb    r1, [ip, r3, lsr #SH2_RAM_SHIFT+1]\r
+    bic     r0, r0, #1\r
+    cmp     r1, #0\r
+    bxeq    lr\r
+    b       sh2_drc_wcheck_ram\r
+#else\r
+    bx      lr\r
+#endif\r
+\r
+sh2_write8_da:\r
+    @ preserve r0 and r2 for tail call\r
+    ldr     ip, [r2, #OFS_SH2_p_da]\r
+    eor     r3, r0, #1\r
+    lsl     r3, #SH2_DA_SHIFT\r
+    strb    r1, [ip, r3, lsr #SH2_DA_SHIFT]\r
+#ifdef DRC_SH2\r
+    ldr     ip, [r2, #OFS_SH2_p_drcblk_da]\r
+    ldrb    r1, [ip, r3, lsr #SH2_DA_SHIFT+1]\r
+    bic     r0, r0, #1\r
+    cmp     r1, #0\r
+    bxeq    lr\r
+    b       sh2_drc_wcheck_da\r
+#else\r
+    bx      lr\r
+#endif\r
+\r
+sh2_write8_dram:\r
+    tst     r1, #0xff\r
+    ldrne   ip, [r2, #OFS_SH2_p_dram]\r
+    eorne   r3, r0, #1\r
+    lslne   r3, #SH2_DRAM_SHIFT\r
+    strneb  r1, [ip, r3, lsr #SH2_DRAM_SHIFT]\r
+    bx      lr\r
+\r
+sh2_write16_sdram:\r
+    @ preserve r0 and r2 for tail call\r
+    ldr     ip, [r2, #OFS_SH2_p_sdram]\r
+    lsl     r3, r0, #SH2_RAM_SHIFT\r
+    lsr     r3, r3, #SH2_RAM_SHIFT\r
+    strh    r1, [ip, r3]\r
+#ifdef DRC_SH2\r
+    ldr     ip, [r2, #OFS_SH2_p_drcblk_ram]\r
+    ldrb    r1, [ip, r3, lsr #1]\r
+    cmp     r1, #0\r
+    bxeq    lr\r
+    b       sh2_drc_wcheck_ram\r
+#else\r
+    bx      lr\r
+#endif\r
+\r
+sh2_write16_da:\r
+    @ preserve r0 and r2 for tail call\r
+    ldr     ip, [r2, #OFS_SH2_p_da]\r
+    lsl     r3, r0, #SH2_DA_SHIFT\r
+    lsr     r3, r3, #SH2_DA_SHIFT\r
+    strh    r1, [ip, r3]\r
+#ifdef DRC_SH2\r
+    ldr     ip, [r2, #OFS_SH2_p_drcblk_da]\r
+    ldrb    r1, [ip, r3, lsr #1]\r
+    cmp     r1, #0\r
+    bxeq    lr\r
+    b       sh2_drc_wcheck_da\r
+#else\r
+    bx      lr\r
+#endif\r
+\r
+sh2_write16_dram:\r
+    ldr     ip, [r2, #OFS_SH2_p_dram]\r
+    tst     r0, #SH2_DRAM_OW\r
+    lsl     r3, r0, #SH2_DRAM_SHIFT\r
+    lsr     r3, r3, #SH2_DRAM_SHIFT\r
+    streqh  r1, [ip, r3]\r
+    bxeq    lr\r
+    add     ip, ip, r3\r
+    tst     r1, #0xff\r
+    strneb  r1, [ip, #0]\r
+    tst     r1, #0xff00\r
+    lsrne   r1, r1, #8\r
+    strneb  r1, [ip, #1]\r
+    bx      lr\r
+\r
+sh2_write32_sdram:\r
+    @ preserve r0 and r2 for tail call\r
+    ldr     ip, [r2, #OFS_SH2_p_sdram]\r
+    ror     r1, r1, #16\r
+    lsl     r3, r0, #SH2_RAM_SHIFT\r
+    str     r1, [ip, r3, lsr #SH2_RAM_SHIFT]\r
+#ifdef DRC_SH2\r
+    ldr     ip, [r2, #OFS_SH2_p_drcblk_ram]\r
+    ldrb    r1, [ip, r3, lsr #SH2_RAM_SHIFT+1]!\r
+    cmp     r1, #0\r
+    beq     1f\r
+    stmfd   sp!, {r0, r1, r2, ip}\r
+    bl      sh2_drc_wcheck_ram\r
+    ldmfd   sp!, {r0, r1, r2, ip}\r
+1:  ldrb    r1, [ip, #1]\r
+    cmp     r1, #0\r
+    bxeq    lr\r
+    add     r0, r0, #2\r
+    b       sh2_drc_wcheck_ram\r
+#else\r
+    bx      lr\r
+#endif\r
+\r
+sh2_write32_da:\r
+    @ preserve r0 and r2 for tail call\r
+    ldr     ip, [r2, #OFS_SH2_p_da]\r
+    ror     r1, r1, #16\r
+    lsl     r3, r0, #SH2_DA_SHIFT\r
+    str     r1, [ip, r3, lsr #SH2_DA_SHIFT]\r
+#ifdef DRC_SH2\r
+    ldr     ip, [r2, #OFS_SH2_p_drcblk_da]\r
+    ldrb    r1, [ip, r3, lsr #SH2_DA_SHIFT+1]!\r
+    cmp     r1, #0\r
+    beq     1f\r
+    stmfd   sp!, {r0, r1, r2, ip}\r
+    bl      sh2_drc_wcheck_da\r
+    ldmfd   sp!, {r0, r1, r2, ip}\r
+1:  ldrb    r1, [ip, #1]\r
+    cmp     r1, #0\r
+    bxeq    lr\r
+    add     r0, r0, #2\r
+    b       sh2_drc_wcheck_da\r
+#else\r
+    bx      lr\r
+#endif\r
+\r
+sh2_write32_dram:\r
+    ldr     ip, [r2, #OFS_SH2_p_dram]\r
+    tst     r0, #SH2_DRAM_OW\r
+    lsl     r3, r0, #SH2_DRAM_SHIFT\r
+    roreq   r1, r1, #16\r
+    streq   r1, [ip, r3, lsr #SH2_DRAM_SHIFT]\r
+    bxeq    lr\r
+#if 1\r
+    ldr     r0, [ip, r3, lsr #SH2_DRAM_SHIFT]\r
+    ror     r1, r1, #16\r
+    mov     r2, #0\r
+    tst     r1, #0x00ff0000\r
+    orrne   r2, r2, #0x00ff0000\r
+    tst     r1, #0xff000000\r
+    orrne   r2, r2, #0xff000000\r
+    tst     r1, #0x000000ff\r
+    orrne   r2, r2, #0x000000ff\r
+    tst     r1, #0x0000ff00\r
+    orrne   r2, r2, #0x0000ff00\r
+    bic     r0, r0, r2\r
+    orr     r0, r0, r1\r
+    str     r0, [ip, r3, lsr #SH2_DRAM_SHIFT]\r
+#else\r
+    add     ip, ip, r3, lsr #SH2_DRAM_SHIFT\r
+    tst     r1, #0x00ff0000\r
+    lsrne   r3, r1, #16\r
+    strneb  r3, [ip, #0]\r
+    tst     r1, #0xff000000\r
+    lsrne   r3, r1, #24\r
+    strneb  r3, [ip, #1]\r
+    tst     r1, #0x000000ff\r
+    strneb  r1, [ip, #2]\r
+    tst     r1, #0x0000ff00\r
+    lsrne   r3, r1, #8\r
+    strneb  r3, [ip, #3]\r
+#endif\r
+    bx      lr\r
+\r
+.pool\r
+\r
+@ vim:filetype=armasm\r
index f8e657f..4aae2a0 100644 (file)
@@ -229,7 +229,7 @@ void sh2_peripheral_reset(SH2 *sh2)
 // SH2 internal peripheral memhandlers
 // we keep them in little endian format
 
-u32 sh2_peripheral_read8(u32 a, SH2 *sh2)
+u32 REGPARM(2) sh2_peripheral_read8(u32 a, SH2 *sh2)
 {
   u8 *r = (void *)sh2->peri_regs;
   u32 d;
@@ -242,7 +242,7 @@ u32 sh2_peripheral_read8(u32 a, SH2 *sh2)
   return d;
 }
 
-u32 sh2_peripheral_read16(u32 a, SH2 *sh2)
+u32 REGPARM(2) sh2_peripheral_read16(u32 a, SH2 *sh2)
 {
   u16 *r = (void *)sh2->peri_regs;
   u32 d;
@@ -255,7 +255,7 @@ u32 sh2_peripheral_read16(u32 a, SH2 *sh2)
   return d;
 }
 
-u32 sh2_peripheral_read32(u32 a, SH2 *sh2)
+u32 REGPARM(2) sh2_peripheral_read32(u32 a, SH2 *sh2)
 {
   u32 d;
   a &= 0x1fc;
index 4d599ce..497649b 100644 (file)
@@ -958,9 +958,9 @@ void p32x_dreq1_trigger(void);
 void p32x_timers_recalc(void);\r
 void p32x_timers_do(unsigned int m68k_slice);\r
 void sh2_peripheral_reset(SH2 *sh2);\r
-unsigned int sh2_peripheral_read8(unsigned int a, SH2 *sh2);\r
-unsigned int sh2_peripheral_read16(unsigned int a, SH2 *sh2);\r
-unsigned int sh2_peripheral_read32(unsigned int a, SH2 *sh2);\r
+unsigned int REGPARM(2) sh2_peripheral_read8(unsigned int a, SH2 *sh2);\r
+unsigned int REGPARM(2) sh2_peripheral_read16(unsigned int a, SH2 *sh2);\r
+unsigned int REGPARM(2) sh2_peripheral_read32(unsigned int a, SH2 *sh2);\r
 void REGPARM(3) sh2_peripheral_write8(unsigned int a, unsigned int d, SH2 *sh2);\r
 void REGPARM(3) sh2_peripheral_write16(unsigned int a, unsigned int d, SH2 *sh2);\r
 void REGPARM(3) sh2_peripheral_write32(unsigned int a, unsigned int d, SH2 *sh2);\r
index 90e6586..13e5549 100755 (executable)
@@ -87,3 +87,12 @@ get_define OFS_EST_ PicoEState HighPal               ; echo "$line" >>$fn
 
 get_define OFS_PMEM_ PicoMem vram              ; echo "$line" >>$fn
 get_define OFS_PMEM_ PicoMem vsram             ; echo "$line" >>$fn
+
+get_define OFS_SH2_ SH2_ is_slave              ; echo "$line" >>$fn
+get_define OFS_SH2_ SH2_ p_bios                        ; echo "$line" >>$fn
+get_define OFS_SH2_ SH2_ p_da                  ; echo "$line" >>$fn
+get_define OFS_SH2_ SH2_ p_sdram                       ; echo "$line" >>$fn
+get_define OFS_SH2_ SH2_ p_rom                 ; echo "$line" >>$fn
+get_define OFS_SH2_ SH2_ p_dram                        ; echo "$line" >>$fn
+get_define OFS_SH2_ SH2_ p_drcblk_da           ; echo "$line" >>$fn
+get_define OFS_SH2_ SH2_ p_drcblk_ram          ; echo "$line" >>$fn