From: kub Date: Wed, 3 Apr 2019 21:21:20 +0000 (+0200) Subject: sh2 memory interface optimzations X-Git-Tag: v2.00~868 X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6822ba9d646d09a091e9e9b03a7cefc3ff77e620;p=picodrive.git sh2 memory interface optimzations --- diff --git a/cpu/drc/emit_arm.c b/cpu/drc/emit_arm.c index 4421c641..c255a8b8 100644 --- a/cpu/drc/emit_arm.c +++ b/cpu/drc/emit_arm.c @@ -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 @@ -184,8 +187,10 @@ #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<> 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() { \ diff --git a/cpu/sh2/compiler.c b/cpu/sh2/compiler.c index 1b300cc3..bfd98e2b 100644 --- a/cpu/sh2/compiler.c +++ b/cpu/sh2/compiler.c @@ -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; diff --git a/cpu/sh2/compiler.h b/cpu/sh2/compiler.h index b690435c..6a8596b8 100644 --- a/cpu/sh2/compiler.h +++ b/cpu/sh2/compiler.h @@ -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); diff --git a/cpu/sh2/sh2.h b/cpu/sh2/sh2.h index 7faa844b..a073d43f 100644 --- a/cpu/sh2/sh2.h +++ b/cpu/sh2/sh2.h @@ -36,6 +36,9 @@ typedef struct SH2_ void *p_da; void *p_sdram; void *p_rom; + void *p_dram; + void *p_drcblk_da; + void *p_drcblk_ram; unsigned int pdb_io_csum[2]; #define SH2_STATE_RUN (1 << 0) // to prevent recursion diff --git a/pico/32x/memory.c b/pico/32x/memory.c index 8f2a7c2f..47329835 100644 --- a/pico/32x/memory.c +++ b/pico/32x/memory.c @@ -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 index 00000000..90c86ddf --- /dev/null +++ b/pico/32x/memory_arm.S @@ -0,0 +1,305 @@ +/* + * PicoDrive 32X memory access functions, assembler version + * (C) KUB, 2018 + * + * This work is licensed under the terms of MAME license. + * See COPYING file in the top-level directory. + */ + +#include "../pico_int_o32.h" + +@ 32X bank sizes... TODO this should somehow come from an include file +.equ SH2_ROM_SHIFT, 10 @ 0x003fffff +.equ SH2_RAM_SHIFT, 14 @ 0x0003ffff +.equ SH2_DRAM_SHIFT,15 @ 0x0001ffff +.equ SH2_DA_SHIFT, 20 @ 0x00000fff + +.equ SH2_DRAM_OW, 1<<(32-SH2_DRAM_SHIFT) @ DRAM overwrite mode bit + +.text + +@ u32 a +.global sh2_read8_rom +.global sh2_read8_sdram +.global sh2_read8_da +.global sh2_read8_dram +.global sh2_read16_rom +.global sh2_read16_sdram +.global sh2_read16_da +.global sh2_read16_dram +.global sh2_read32_rom +.global sh2_read32_sdram +.global sh2_read32_da +.global sh2_read32_dram + +@ u32 a, u32 d +.global sh2_write8_sdram +.global sh2_write8_da +.global sh2_write8_dram +.global sh2_write16_sdram +.global sh2_write16_da +.global sh2_write16_dram +.global sh2_write32_sdram +.global sh2_write32_da +.global sh2_write32_dram + +sh2_read8_rom: + ldr ip, [r1, #OFS_SH2_p_rom] + eor r0, r0, #1 + lsl r0, #SH2_ROM_SHIFT + ldrb r0, [ip, r0, lsr #SH2_ROM_SHIFT] + bx lr + +sh2_read8_sdram: + ldr ip, [r1, #OFS_SH2_p_sdram] + eor r0, r0, #1 + lsl r0, #SH2_RAM_SHIFT + ldrb r0, [ip, r0, lsr #SH2_RAM_SHIFT] + bx lr + +sh2_read8_da: + ldr ip, [r1, #OFS_SH2_p_da] + eor r0, r0, #1 + lsl r0, #SH2_DA_SHIFT + ldrb r0, [ip, r0, lsr #SH2_DA_SHIFT] + bx lr + +sh2_read8_dram: + ldr ip, [r1, #OFS_SH2_p_dram] + eor r0, r0, #1 + lsl r0, #SH2_DRAM_SHIFT + ldrb r0, [ip, r0, lsr #SH2_DRAM_SHIFT] + bx lr + +sh2_read16_rom: + ldr ip, [r1, #OFS_SH2_p_rom] + lsl r0, #SH2_ROM_SHIFT + lsr r0, #SH2_ROM_SHIFT + ldrh r0, [ip, r0] + bx lr + +sh2_read16_sdram: + ldr ip, [r1, #OFS_SH2_p_sdram] + lsl r0, #SH2_RAM_SHIFT + lsr r0, #SH2_RAM_SHIFT + ldrh r0, [ip, r0] + bx lr + +sh2_read16_da: + ldr ip, [r1, #OFS_SH2_p_da] + lsl r0, #SH2_DA_SHIFT + lsr r0, #SH2_DA_SHIFT + ldrh r0, [ip, r0] + bx lr + +sh2_read16_dram: + ldr ip, [r1, #OFS_SH2_p_dram] + lsl r0, #SH2_DRAM_SHIFT + lsr r0, #SH2_DRAM_SHIFT + ldrh r0, [ip, r0] + bx lr + +sh2_read32_rom: + ldr ip, [r1, #OFS_SH2_p_rom] + lsl r0, #SH2_ROM_SHIFT + ldr r0, [ip, r0, lsr #SH2_ROM_SHIFT] + ror r0, r0, #16 + bx lr + +sh2_read32_sdram: + ldr ip, [r1, #OFS_SH2_p_sdram] + lsl r0, #SH2_RAM_SHIFT + ldr r0, [ip, r0, lsr #SH2_RAM_SHIFT] + ror r0, r0, #16 + bx lr + +sh2_read32_da: + ldr ip, [r1, #OFS_SH2_p_da] + lsl r0, #SH2_DA_SHIFT + ldr r0, [ip, r0, lsr #SH2_DA_SHIFT] + ror r0, r0, #16 + bx lr + +sh2_read32_dram: + ldr ip, [r1, #OFS_SH2_p_dram] + lsl r0, #SH2_DRAM_SHIFT + ldr r0, [ip, r0, lsr #SH2_DRAM_SHIFT] + ror r0, r0, #16 + bx lr + +sh2_write8_sdram: + @ preserve r0 and r2 for tail call + ldr ip, [r2, #OFS_SH2_p_sdram] + eor r3, r0, #1 + lsl r3, #SH2_RAM_SHIFT + strb r1, [ip, r3, lsr #SH2_RAM_SHIFT] +#ifdef DRC_SH2 + ldr ip, [r2, #OFS_SH2_p_drcblk_ram] + ldrb r1, [ip, r3, lsr #SH2_RAM_SHIFT+1] + bic r0, r0, #1 + cmp r1, #0 + bxeq lr + b sh2_drc_wcheck_ram +#else + bx lr +#endif + +sh2_write8_da: + @ preserve r0 and r2 for tail call + ldr ip, [r2, #OFS_SH2_p_da] + eor r3, r0, #1 + lsl r3, #SH2_DA_SHIFT + strb r1, [ip, r3, lsr #SH2_DA_SHIFT] +#ifdef DRC_SH2 + ldr ip, [r2, #OFS_SH2_p_drcblk_da] + ldrb r1, [ip, r3, lsr #SH2_DA_SHIFT+1] + bic r0, r0, #1 + cmp r1, #0 + bxeq lr + b sh2_drc_wcheck_da +#else + bx lr +#endif + +sh2_write8_dram: + tst r1, #0xff + ldrne ip, [r2, #OFS_SH2_p_dram] + eorne r3, r0, #1 + lslne r3, #SH2_DRAM_SHIFT + strneb r1, [ip, r3, lsr #SH2_DRAM_SHIFT] + bx lr + +sh2_write16_sdram: + @ preserve r0 and r2 for tail call + ldr ip, [r2, #OFS_SH2_p_sdram] + lsl r3, r0, #SH2_RAM_SHIFT + lsr r3, r3, #SH2_RAM_SHIFT + strh r1, [ip, r3] +#ifdef DRC_SH2 + ldr ip, [r2, #OFS_SH2_p_drcblk_ram] + ldrb r1, [ip, r3, lsr #1] + cmp r1, #0 + bxeq lr + b sh2_drc_wcheck_ram +#else + bx lr +#endif + +sh2_write16_da: + @ preserve r0 and r2 for tail call + ldr ip, [r2, #OFS_SH2_p_da] + lsl r3, r0, #SH2_DA_SHIFT + lsr r3, r3, #SH2_DA_SHIFT + strh r1, [ip, r3] +#ifdef DRC_SH2 + ldr ip, [r2, #OFS_SH2_p_drcblk_da] + ldrb r1, [ip, r3, lsr #1] + cmp r1, #0 + bxeq lr + b sh2_drc_wcheck_da +#else + bx lr +#endif + +sh2_write16_dram: + ldr ip, [r2, #OFS_SH2_p_dram] + tst r0, #SH2_DRAM_OW + lsl r3, r0, #SH2_DRAM_SHIFT + lsr r3, r3, #SH2_DRAM_SHIFT + streqh r1, [ip, r3] + bxeq lr + add ip, ip, r3 + tst r1, #0xff + strneb r1, [ip, #0] + tst r1, #0xff00 + lsrne r1, r1, #8 + strneb r1, [ip, #1] + bx lr + +sh2_write32_sdram: + @ preserve r0 and r2 for tail call + ldr ip, [r2, #OFS_SH2_p_sdram] + ror r1, r1, #16 + lsl r3, r0, #SH2_RAM_SHIFT + str r1, [ip, r3, lsr #SH2_RAM_SHIFT] +#ifdef DRC_SH2 + ldr ip, [r2, #OFS_SH2_p_drcblk_ram] + ldrb r1, [ip, r3, lsr #SH2_RAM_SHIFT+1]! + cmp r1, #0 + beq 1f + stmfd sp!, {r0, r1, r2, ip} + bl sh2_drc_wcheck_ram + ldmfd sp!, {r0, r1, r2, ip} +1: ldrb r1, [ip, #1] + cmp r1, #0 + bxeq lr + add r0, r0, #2 + b sh2_drc_wcheck_ram +#else + bx lr +#endif + +sh2_write32_da: + @ preserve r0 and r2 for tail call + ldr ip, [r2, #OFS_SH2_p_da] + ror r1, r1, #16 + lsl r3, r0, #SH2_DA_SHIFT + str r1, [ip, r3, lsr #SH2_DA_SHIFT] +#ifdef DRC_SH2 + ldr ip, [r2, #OFS_SH2_p_drcblk_da] + ldrb r1, [ip, r3, lsr #SH2_DA_SHIFT+1]! + cmp r1, #0 + beq 1f + stmfd sp!, {r0, r1, r2, ip} + bl sh2_drc_wcheck_da + ldmfd sp!, {r0, r1, r2, ip} +1: ldrb r1, [ip, #1] + cmp r1, #0 + bxeq lr + add r0, r0, #2 + b sh2_drc_wcheck_da +#else + bx lr +#endif + +sh2_write32_dram: + ldr ip, [r2, #OFS_SH2_p_dram] + tst r0, #SH2_DRAM_OW + lsl r3, r0, #SH2_DRAM_SHIFT + roreq r1, r1, #16 + streq r1, [ip, r3, lsr #SH2_DRAM_SHIFT] + bxeq lr +#if 1 + ldr r0, [ip, r3, lsr #SH2_DRAM_SHIFT] + ror r1, r1, #16 + mov r2, #0 + tst r1, #0x00ff0000 + orrne r2, r2, #0x00ff0000 + tst r1, #0xff000000 + orrne r2, r2, #0xff000000 + tst r1, #0x000000ff + orrne r2, r2, #0x000000ff + tst r1, #0x0000ff00 + orrne r2, r2, #0x0000ff00 + bic r0, r0, r2 + orr r0, r0, r1 + str r0, [ip, r3, lsr #SH2_DRAM_SHIFT] +#else + add ip, ip, r3, lsr #SH2_DRAM_SHIFT + tst r1, #0x00ff0000 + lsrne r3, r1, #16 + strneb r3, [ip, #0] + tst r1, #0xff000000 + lsrne r3, r1, #24 + strneb r3, [ip, #1] + tst r1, #0x000000ff + strneb r1, [ip, #2] + tst r1, #0x0000ff00 + lsrne r3, r1, #8 + strneb r3, [ip, #3] +#endif + bx lr + +.pool + +@ vim:filetype=armasm diff --git a/pico/32x/sh2soc.c b/pico/32x/sh2soc.c index f8e657f5..4aae2a04 100644 --- a/pico/32x/sh2soc.c +++ b/pico/32x/sh2soc.c @@ -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; diff --git a/pico/pico_int.h b/pico/pico_int.h index 4d599ce8..497649b6 100644 --- a/pico/pico_int.h +++ b/pico/pico_int.h @@ -958,9 +958,9 @@ void p32x_dreq1_trigger(void); void p32x_timers_recalc(void); void p32x_timers_do(unsigned int m68k_slice); void sh2_peripheral_reset(SH2 *sh2); -unsigned int sh2_peripheral_read8(unsigned int a, SH2 *sh2); -unsigned int sh2_peripheral_read16(unsigned int a, SH2 *sh2); -unsigned int sh2_peripheral_read32(unsigned int a, SH2 *sh2); +unsigned int REGPARM(2) sh2_peripheral_read8(unsigned int a, SH2 *sh2); +unsigned int REGPARM(2) sh2_peripheral_read16(unsigned int a, SH2 *sh2); +unsigned int REGPARM(2) sh2_peripheral_read32(unsigned int a, SH2 *sh2); void REGPARM(3) sh2_peripheral_write8(unsigned int a, unsigned int d, SH2 *sh2); void REGPARM(3) sh2_peripheral_write16(unsigned int a, unsigned int d, SH2 *sh2); void REGPARM(3) sh2_peripheral_write32(unsigned int a, unsigned int d, SH2 *sh2); diff --git a/tools/mkoffsets.sh b/tools/mkoffsets.sh index 90e65867..13e55495 100755 --- a/tools/mkoffsets.sh +++ b/tools/mkoffsets.sh @@ -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