mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-09-05 15:27:46 -04:00
32x DMA memory copy performance optimisation
This commit is contained in:
parent
8141d75694
commit
346153e08e
5 changed files with 105 additions and 15 deletions
|
@ -1855,17 +1855,15 @@ void *p32x_sh2_get_mem_ptr(u32 a, u32 *mask, SH2 *sh2)
|
|||
{
|
||||
const sh2_memmap *mm = sh2->read8_map;
|
||||
void *ret = (void *)-1;
|
||||
u32 am;
|
||||
|
||||
mm += a >> SH2_READ_SHIFT;
|
||||
am = a & ((1 << SH2_READ_SHIFT)-1);
|
||||
if (!map_flag_set(mm->addr) && !(am & ~mm->mask)) {
|
||||
mm += SH2MAP_ADDR2OFFS_R(a);
|
||||
if (!map_flag_set(mm->addr)) {
|
||||
// directly mapped memory (SDRAM, ROM, data array)
|
||||
ret = (void *)(mm->addr << 1);
|
||||
*mask = mm->mask;
|
||||
} else if ((a & ~0x7ff) == 0) {
|
||||
// BIOS, has handler function since it shares its segment with I/O
|
||||
ret = sh2->is_slave ? Pico32xMem->sh2_rom_s.w : Pico32xMem->sh2_rom_m.w;
|
||||
ret = sh2->p_bios;
|
||||
*mask = 0x7ff;
|
||||
} else if ((a & 0xc6000000) == 0x02000000) {
|
||||
// banked ROM. Return bank address
|
||||
|
@ -1877,6 +1875,75 @@ void *p32x_sh2_get_mem_ptr(u32 a, u32 *mask, SH2 *sh2)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int p32x_sh2_memcpy(u32 dst, u32 src, int count, int size, SH2 *sh2)
|
||||
{
|
||||
u32 mask;
|
||||
void *ps, *pd;
|
||||
int len, i;
|
||||
|
||||
// check if src and dst points to memory (rom/sdram/dram/da)
|
||||
if ((pd = p32x_sh2_get_mem_ptr(dst, &mask, sh2)) == (void *)-1)
|
||||
return 0;
|
||||
if ((ps = p32x_sh2_get_mem_ptr(src, &mask, sh2)) == (void *)-1)
|
||||
return 0;
|
||||
ps += src & mask;
|
||||
len = count * size;
|
||||
|
||||
// DRAM in byte access is always in overwrite mode
|
||||
if (pd == sh2->p_dram && size == 1)
|
||||
dst |= 0x20000;
|
||||
|
||||
// align dst to halfword
|
||||
if (dst & 1) {
|
||||
p32x_sh2_write8(dst, *(u8 *)((uptr)ps ^ 1), sh2);
|
||||
ps++, dst++, len --;
|
||||
}
|
||||
|
||||
// copy data
|
||||
if ((uptr)ps & 1) {
|
||||
// unaligned, use halfword copy mode to reduce memory bandwidth
|
||||
u16 *sp = (u16 *)(ps - 1);
|
||||
u16 dl, dh = *sp++;
|
||||
for (i = 0; i < (len & ~1); i += 2, dst += 2, sp++) {
|
||||
dl = dh, dh = *sp;
|
||||
p32x_sh2_write16(dst, (dh >> 8) | (dl << 8), sh2);
|
||||
}
|
||||
if (len & 1)
|
||||
p32x_sh2_write8(dst, dh, sh2);
|
||||
} else {
|
||||
// dst and src at least halfword aligned
|
||||
u16 *sp = (u16 *)ps;
|
||||
// align dst to word
|
||||
if ((dst & 2) && len >= 2) {
|
||||
p32x_sh2_write16(dst, *sp++, sh2);
|
||||
dst += 2, len -= 2;
|
||||
}
|
||||
if ((uptr)sp & 2) {
|
||||
// halfword copy, using word writes to reduce memory bandwidth
|
||||
u16 dl, dh;
|
||||
for (i = 0; i < (len & ~3); i += 4, dst += 4, sp += 2) {
|
||||
dl = sp[0], dh = sp[1];
|
||||
p32x_sh2_write32(dst, (dl << 16) | dh, sh2);
|
||||
}
|
||||
} else {
|
||||
// word copy
|
||||
u32 d;
|
||||
for (i = 0; i < (len & ~3); i += 4, dst += 4, sp += 2) {
|
||||
d = *(u32 *)sp;
|
||||
p32x_sh2_write32(dst, (d << 16) | (d >> 16), sh2);
|
||||
}
|
||||
}
|
||||
if (len & 2) {
|
||||
p32x_sh2_write16(dst, *sp++, sh2);
|
||||
dst += 2;
|
||||
}
|
||||
if (len & 1)
|
||||
p32x_sh2_write8(dst, *sp >> 8, sh2);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
static void z80_md_bank_write_32x(unsigned int a, unsigned char d)
|
||||
|
@ -2107,8 +2174,12 @@ void Pico32xSwapDRAM(int b)
|
|||
ssh2_read16_map[0x04/2].addr = ssh2_read16_map[0x24/2].addr =
|
||||
ssh2_read32_map[0x04/2].addr = ssh2_read32_map[0x24/2].addr = MAP_MEMORY(Pico32xMem->dram[b]);
|
||||
|
||||
msh2.p_dram = ssh2.p_dram = Pico32xMem->dram[b]; // DRC conveniance ptr
|
||||
msh2.p_rom = ssh2.p_rom = Pico.rom;
|
||||
// convenience ptrs
|
||||
msh2.p_sdram = ssh2.p_sdram = Pico32xMem->sdram;
|
||||
msh2.p_dram = ssh2.p_dram = Pico32xMem->dram[b];
|
||||
msh2.p_rom = ssh2.p_rom = Pico.rom;
|
||||
msh2.p_bios = Pico32xMem->sh2_rom_m.w; msh2.p_da = msh2.data_array;
|
||||
ssh2.p_bios = Pico32xMem->sh2_rom_s.w; ssh2.p_da = ssh2.data_array;
|
||||
}
|
||||
|
||||
static void bank_switch_rom_sh2(void)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue