X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=libpcsxcore%2Fnew_dynarec%2Fpcsxmem.c;h=694b8d089129cc9fce38ccbfb7e72600d82df76e;hb=da65071fd7ceac663bb951b13da2563d7b16431d;hp=2306ca77b0fb8e13d8fc0fdfe45e8d1823ccc4ce;hpb=ddbaf678c49d33cf60f1eac5069e3275baa2c685;p=pcsx_rearmed.git diff --git a/libpcsxcore/new_dynarec/pcsxmem.c b/libpcsxcore/new_dynarec/pcsxmem.c index 2306ca77..694b8d08 100644 --- a/libpcsxcore/new_dynarec/pcsxmem.c +++ b/libpcsxcore/new_dynarec/pcsxmem.c @@ -6,51 +6,70 @@ */ #include -#include #include "../psxhw.h" #include "../cdrom.h" #include "../mdec.h" #include "../gpu.h" +#include "../psxmem_map.h" #include "emu_if.h" #include "pcsxmem.h" +#ifdef __thumb__ +#error the dynarec is incompatible with Thumb functions, +#error please add -marm to compile flags +#endif + //#define memprintf printf #define memprintf(...) -static u32 *mem_readtab; -static u32 *mem_writetab; -static u32 mem_iortab[(1+2+4) * 0x1000 / 4]; -static u32 mem_iowtab[(1+2+4) * 0x1000 / 4]; -static u32 mem_ffwtab[(1+2+4) * 0x1000 / 4]; -//static u32 mem_unmrtab[(1+2+4) * 0x1000 / 4]; -static u32 mem_unmwtab[(1+2+4) * 0x1000 / 4]; - -static void map_item(u32 *out, const void *h, u32 flag) +static uintptr_t *mem_readtab; +static uintptr_t *mem_writetab; +static uintptr_t mem_iortab[(1+2+4) * 0x1000 / 4]; +static uintptr_t mem_iowtab[(1+2+4) * 0x1000 / 4]; +static uintptr_t mem_ffrtab[(1+2+4) * 0x1000 / 4]; +static uintptr_t mem_ffwtab[(1+2+4) * 0x1000 / 4]; +//static uintptr_t mem_unmrtab[(1+2+4) * 0x1000 / 4]; +static uintptr_t mem_unmwtab[(1+2+4) * 0x1000 / 4]; + +static +#ifdef __clang__ +// When this is called in a loop, and 'h' is a function pointer, clang will crash. +__attribute__ ((noinline)) +#endif +void map_item(uintptr_t *out, const void *h, uintptr_t flag) { - u32 hv = (u32)h; - if (hv & 1) - fprintf(stderr, "%p has LSB set\n", h); - *out = (hv >> 1) | (flag << 31); + uintptr_t hv = (uintptr_t)h; + if (hv & 1) { + SysPrintf("FATAL: %p has LSB set\n", h); + abort(); + } + *out = (hv >> 1) | (flag << (sizeof(hv) * 8 - 1)); } // size must be power of 2, at least 4k #define map_l1_mem(tab, i, addr, size, base) \ - map_item(&tab[((addr)>>12) + i], (u8 *)(base) - (u32)(addr) - ((i << 12) & ~(size - 1)), 0) + map_item(&tab[((u32)(addr) >> 12) + i], \ + (u8 *)(base) - (u32)((addr) + ((i << 12) & ~(size - 1))), 0) #define IOMEM32(a) (((a) & 0xfff) / 4) #define IOMEM16(a) (0x1000/4 + (((a) & 0xfff) / 2)) #define IOMEM8(a) (0x1000/4 + 0x1000/2 + ((a) & 0xfff)) -u8 zero_mem[0x1000]; +u32 zero_mem[0x1000/4]; +static u32 ffff_mem[0x1000/4]; -u32 read_mem_dummy() +static u32 read_mem_dummy(u32 addr) { - return 0; + // use 'addr' and not 'address', yes the api is weird... + memprintf("unmapped r %08x @%08x %u\n", addr, psxRegs.pc, psxRegs.cycle); + return 0xffffffff; } static void write_mem_dummy(u32 data) { - memprintf("unmapped w %08x, %08x @%08x %u\n", address, data, psxRegs.pc, psxRegs.cycle); + if (!(psxRegs.CP0.n.Status & (1 << 16))) + memprintf("unmapped w %08x, %08x @%08x %u\n", + address, data, psxRegs.pc, psxRegs.cycle); } /* IO handlers */ @@ -78,7 +97,7 @@ static void io_write_sio32(u32 value) sioWrite8((unsigned char)(value >> 24)); } -#ifndef DRC_DBG +#if !defined(DRC_DBG) && defined(__arm__) static void map_rcnt_rcount0(u32 mode) { @@ -140,9 +159,7 @@ make_rcnt_funcs(2) static void io_write_ireg16(u32 value) { - if (Config.Sio) psxHu16ref(0x1070) |= 0x80; - if (Config.SpuIrq) psxHu16ref(0x1070) |= 0x200; - psxHu16ref(0x1070) &= psxHu16(0x1074) & value; + psxHu16ref(0x1070) &= value; } static void io_write_imask16(u32 value) @@ -154,9 +171,7 @@ static void io_write_imask16(u32 value) static void io_write_ireg32(u32 value) { - if (Config.Sio) psxHu32ref(0x1070) |= 0x80; - if (Config.SpuIrq) psxHu32ref(0x1070) |= 0x200; - psxHu32ref(0x1070) &= psxHu32(0x1074) & value; + psxHu32ref(0x1070) &= value; } static void io_write_imask32(u32 value) @@ -198,7 +213,7 @@ make_dma_func(6) static void io_spu_write16(u32 value) { // meh - SPU_writeRegister(address, value); + SPU_writeRegister(address, value, psxRegs.cycle); } static void io_spu_write32(u32 value) @@ -206,15 +221,23 @@ static void io_spu_write32(u32 value) SPUwriteRegister wfunc = SPU_writeRegister; u32 a = address; - wfunc(a, value & 0xffff); - wfunc(a + 2, value >> 16); + wfunc(a, value & 0xffff, psxRegs.cycle); + wfunc(a + 2, value >> 16, psxRegs.cycle); } static u32 io_gpu_read_status(void) { + u32 v; + // meh2, syncing for img bit, might want to avoid it.. gpuSyncPluginSR(); - return HW_GPU_STATUS; + v = HW_GPU_STATUS; + + // XXX: because of large timeslices can't use hSyncCount, using rough + // approximization instead. Perhaps better use hcounter code here or something. + if (hSyncCount < 240 && (HW_GPU_STATUS & PSXGPU_ILACE_BITS) != PSXGPU_ILACE_BITS) + v |= PSXGPU_LCF & (psxRegs.cycle << 20); + return v; } static void io_gpu_write_status(u32 value) @@ -223,46 +246,51 @@ static void io_gpu_write_status(u32 value) gpuSyncPluginSR(); } -static void map_ram_write(void) +void new_dyna_pcsx_mem_isolate(int enable) { int i; - for (i = 0; i < (0x800000 >> 12); i++) { - map_l1_mem(mem_writetab, i, 0x80000000, 0x200000, psxM); - map_l1_mem(mem_writetab, i, 0x00000000, 0x200000, psxM); - map_l1_mem(mem_writetab, i, 0xa0000000, 0x200000, psxM); + // note: apparently 0xa0000000 uncached access still works, + // at least read does for sure, so assume write does too + memprintf("mem isolate %d\n", enable); + if (enable) { + for (i = 0; i < (0x800000 >> 12); i++) { + map_item(&mem_writetab[0x80000|i], mem_unmwtab, 1); + map_item(&mem_writetab[0x00000|i], mem_unmwtab, 1); + //map_item(&mem_writetab[0xa0000|i], mem_unmwtab, 1); + } + } + else { + for (i = 0; i < (0x800000 >> 12); i++) { + map_l1_mem(mem_writetab, i, 0x80000000, 0x200000, psxM); + map_l1_mem(mem_writetab, i, 0x00000000, 0x200000, psxM); + map_l1_mem(mem_writetab, i, 0xa0000000, 0x200000, psxM); + } } } -static void unmap_ram_write(void) +static u32 read_biu(u32 addr) { - int i; - - for (i = 0; i < (0x800000 >> 12); i++) { - map_item(&mem_writetab[0x80000|i], mem_unmwtab, 1); - map_item(&mem_writetab[0x00000|i], mem_unmwtab, 1); - map_item(&mem_writetab[0xa0000|i], mem_unmwtab, 1); - } + if (addr != 0xfffe0130) + return read_mem_dummy(addr); + + FILE *f = fopen("/tmp/psxbiu.bin", "wb"); + fwrite(psxM, 1, 0x200000, f); + fclose(f); + memprintf("read_biu %08x @%08x %u\n", + psxRegs.biuReg, psxRegs.pc, psxRegs.cycle); + return psxRegs.biuReg; } static void write_biu(u32 value) { - memprintf("write_biu %08x, %08x @%08x %u\n", address, value, psxRegs.pc, psxRegs.cycle); - - if (address != 0xfffe0130) + if (address != 0xfffe0130) { + write_mem_dummy(value); return; - - switch (value) { - case 0x800: case 0x804: - unmap_ram_write(); - break; - case 0: case 0x1e988: - map_ram_write(); - break; - default: - printf("write_biu: unexpected val: %08x\n", value); - break; } + + memprintf("write_biu %08x @%08x %u\n", value, psxRegs.pc, psxRegs.cycle); + psxRegs.biuReg = value; } void new_dyna_pcsx_mem_load_state(void) @@ -272,7 +300,7 @@ void new_dyna_pcsx_mem_load_state(void) map_rcnt_rcount2(rcnts[2].mode); } -int pcsxmem_is_handler_dynamic(u_int addr) +int pcsxmem_is_handler_dynamic(unsigned int addr) { if ((addr & 0xfffff000) != 0x1f801000) return 0; @@ -285,11 +313,12 @@ void new_dyna_pcsx_mem_init(void) { int i; + memset(ffff_mem, 0xff, sizeof(ffff_mem)); + // have to map these further to keep tcache close to .text - mem_readtab = mmap((void *)0x08000000, 0x200000 * 4, PROT_READ | PROT_WRITE, - MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - if (mem_readtab == MAP_FAILED) { - fprintf(stderr, "failed to map mem tables\n"); + mem_readtab = psxMap(0x08000000, 0x200000 * sizeof(mem_readtab[0]), 0, MAP_TAG_LUTS); + if (mem_readtab == NULL) { + SysPrintf("failed to map mem tables\n"); exit(1); } mem_writetab = mem_readtab + 0x100000; @@ -304,7 +333,7 @@ void new_dyna_pcsx_mem_init(void) // default/unmapped memhandlers for (i = 0; i < 0x100000; i++) { //map_item(&mem_readtab[i], mem_unmrtab, 1); - map_l1_mem(mem_readtab, i, 0, 0x1000, zero_mem); + map_l1_mem(mem_readtab, i, 0, 0x1000, ffff_mem); map_item(&mem_writetab[i], mem_unmwtab, 1); } @@ -314,7 +343,7 @@ void new_dyna_pcsx_mem_init(void) map_l1_mem(mem_readtab, i, 0x00000000, 0x200000, psxM); map_l1_mem(mem_readtab, i, 0xa0000000, 0x200000, psxM); } - map_ram_write(); + new_dyna_pcsx_mem_isolate(0); // BIOS and it's mirrors for (i = 0; i < (0x80000 >> 12); i++) { @@ -324,11 +353,17 @@ void new_dyna_pcsx_mem_init(void) // scratchpad map_l1_mem(mem_readtab, 0, 0x1f800000, 0x1000, psxH); + map_l1_mem(mem_readtab, 0, 0x9f800000, 0x1000, psxH); map_l1_mem(mem_writetab, 0, 0x1f800000, 0x1000, psxH); + map_l1_mem(mem_writetab, 0, 0x9f800000, 0x1000, psxH); // I/O - map_item(&mem_readtab[0x1f801000 >> 12], mem_iortab, 1); - map_item(&mem_writetab[0x1f801000 >> 12], mem_iowtab, 1); + map_item(&mem_readtab[0x1f801000u >> 12], mem_iortab, 1); + map_item(&mem_readtab[0x9f801000u >> 12], mem_iortab, 1); + map_item(&mem_readtab[0xbf801000u >> 12], mem_iortab, 1); + map_item(&mem_writetab[0x1f801000u >> 12], mem_iowtab, 1); + map_item(&mem_writetab[0x9f801000u >> 12], mem_iowtab, 1); + map_item(&mem_writetab[0xbf801000u >> 12], mem_iowtab, 1); // L2 // unmapped tables @@ -439,9 +474,12 @@ void new_dyna_pcsx_mem_init(void) } // misc - map_item(&mem_writetab[0xfffe0130 >> 12], mem_ffwtab, 1); - for (i = 0; i < 0x1000/4 + 0x1000/2 + 0x1000; i++) + map_item(&mem_readtab[0xfffe0130u >> 12], mem_ffrtab, 1); + map_item(&mem_writetab[0xfffe0130u >> 12], mem_ffwtab, 1); + for (i = 0; i < 0x1000/4 + 0x1000/2 + 0x1000; i++) { + map_item(&mem_ffrtab[i], read_biu, 1); map_item(&mem_ffwtab[i], write_biu, 1); + } mem_rtab = mem_readtab; mem_wtab = mem_writetab; @@ -461,3 +499,9 @@ void new_dyna_pcsx_mem_reset(void) map_item(&mem_iowtab[IOMEM32(0x1810)], GPU_writeData, 1); } + +void new_dyna_pcsx_mem_shutdown(void) +{ + psxUnmap(mem_readtab, 0x200000 * sizeof(mem_readtab[0]), MAP_TAG_LUTS); + mem_writetab = mem_readtab = NULL; +}