psxmem: reduce lut table size
authornotaz <notasas@gmail.com>
Sat, 14 Feb 2026 00:46:50 +0000 (02:46 +0200)
committernotaz <notasas@gmail.com>
Sun, 15 Feb 2026 22:10:05 +0000 (00:10 +0200)
No reason for them to be 64k, unused by the dynarecs anyway and just
wastes memory there. Also move to psxRegs for less literal pools on arm.

20 files changed:
frontend/libretro.c
include/compiler_features.h
libpcsxcore/cheat.c
libpcsxcore/lightrec/mem.c
libpcsxcore/lightrec/plugin.c
libpcsxcore/mdec.c
libpcsxcore/misc.c
libpcsxcore/new_dynarec/emu_if.c
libpcsxcore/new_dynarec/linkage_offsets.h
libpcsxcore/new_dynarec/new_dynarec.c
libpcsxcore/new_dynarec/pcsxmem.c
libpcsxcore/psxbios.c
libpcsxcore/psxdma.c
libpcsxcore/psxdma.h
libpcsxcore/psxhw.c
libpcsxcore/psxinterpreter.c
libpcsxcore/psxmem.c
libpcsxcore/psxmem.h
libpcsxcore/r3000a.c
libpcsxcore/r3000a.h

index a7ad22e..7f484d5 100644 (file)
@@ -1732,10 +1732,10 @@ static void set_retro_memmap(void)
    uint64_t flags_ram = RETRO_MEMDESC_SYSTEM_RAM;
    struct retro_memory_map retromap = { 0 };
    struct retro_memory_descriptor descs[] = {
-      { flags_ram, psxM, 0, 0x00000000, 0x5fe00000, 0, 0x200000 },
-      { flags_ram, psxH, 0, 0x1f800000, 0x7ffffc00, 0, 0x000400 },
+      { flags_ram, psxRegs.ptrs.psxM, 0, 0x00000000, 0x5fe00000, 0, 0x200000 },
+      { flags_ram, psxRegs.ptrs.psxH, 0, 0x1f800000, 0x7ffffc00, 0, 0x000400 },
       // not ram but let the frontend patch it if it wants; should be last
-      { flags_ram, psxR, 0, 0x1fc00000, 0x5ff80000, 0, 0x080000 },
+      { flags_ram, psxRegs.ptrs.psxR, 0, 0x1fc00000, 0x5ff80000, 0, 0x080000 },
    };
 
    retromap.descriptors = descs;
@@ -2091,7 +2091,7 @@ void *retro_get_memory_data(unsigned id)
    if (id == RETRO_MEMORY_SAVE_RAM)
       return Mcd1Data;
    else if (id == RETRO_MEMORY_SYSTEM_RAM)
-      return psxM;
+      return psxRegs.ptrs.psxM;
    else
       return NULL;
 }
index 77114ef..85fc1da 100644 (file)
@@ -1,3 +1,5 @@
+#ifndef PCSX_COMPILER_FEATURES_H_
+#define PCSX_COMPILER_FEATURES_H_
 
 #ifdef __GNUC__
 # define likely(x)       __builtin_expect((x),1)
 #  define noinline       __attribute__((noinline,noclone))
 # endif
 # define attr_unused     __attribute__((unused))
+# define nosanitize(x)   __attribute__((no_sanitize(x)))
 #else
 # define likely(x)       (x)
 # define unlikely(x)     (x)
 # define preload         (x)
 # define noinline
 # define attr_unused
+# define nosanitize(x)
 #endif
 
 // doesn't work on Android, mingw...
@@ -36,3 +40,4 @@
 #define sub_overflow(a, b, r) ({r = (u32)a - (u32)b; (a ^  b) & (a ^ r) & (1u<<31);})
 #endif
 
+#endif // PCSX_COMPILER_FEATURES_H_
index 7b81737..ae5e5c2 100644 (file)
@@ -232,7 +232,7 @@ void ApplyCheats() {
                                        break;
 
                                case CHEAT_SCRATCHPAD16: // 1F
-                                       psxHs16ref(addr) = SWAPu16(val);
+                                       psxHu16ref(addr) = SWAPu16(val);
                                        break;
 
                                case CHEAT_INC16:
@@ -513,7 +513,7 @@ void FreeCheatSearchMem() {
 
 void CheatSearchBackupMemory() {
        if (prevM != NULL) {
-               memcpy(prevM, psxM, 0x200000);
+               memcpy(prevM, psxRegs.ptrs.psxM, 0x200000);
        }
 }
 
index 4b58258..ec62853 100644 (file)
@@ -129,7 +129,7 @@ static int lightrec_mmap_ram(bool hugetlb)
        }
 
        err = 0;
-       psxM = (s8 *)base;
+       psxRegs.ptrs.psxM = (u8 *)base;
 
 err_close_memfd:
        close(memfd);
@@ -139,7 +139,7 @@ err_close_memfd:
 int lightrec_init_mmap(void)
 {
        unsigned int i;
-       s8 *base, *target;
+       u8 *base, *target;
        void *map;
        int err = lightrec_mmap_ram(true);
        if (err) {
@@ -150,7 +150,7 @@ int lightrec_init_mmap(void)
                }
        }
 
-       base = psxM;
+       base = psxRegs.ptrs.psxM;
 
        target = base + 0x1f000000;
        map = mmap(target, 0x10000,
@@ -164,7 +164,7 @@ int lightrec_init_mmap(void)
        if (map != target)
                SysMessage("lightrec: mapped parallel port at %p, wanted %p", map, target);
 
-       psxP = (s8 *)map;
+       psxRegs.ptrs.psxP = (u8 *)map;
 
        target = base + 0x1fc00000;
        map = mmap_huge(target, 0x200000,
@@ -178,7 +178,7 @@ int lightrec_init_mmap(void)
        if (map != target)
                SysMessage("lightrec: mapped bios at %p, wanted %p", map, target);
 
-       psxR = (s8 *)map;
+       psxRegs.ptrs.psxR = (u8 *)map;
 
        target = base + 0x1f800000;
        map = mmap(target, 0x10000,
@@ -192,7 +192,7 @@ int lightrec_init_mmap(void)
        if (map != target)
                SysMessage("lightrec: mapped scratchpad at %p, wanted %p", map, target);
 
-       psxH = (s8 *)map;
+       psxRegs.ptrs.psxH = (u8 *)map;
 
        target = base + 0x800000;
        map = mmap_huge(target, CODE_BUFFER_SIZE,
@@ -212,14 +212,14 @@ int lightrec_init_mmap(void)
        return 0;
 
 err_unmap_scratch:
-       munmap(psxH, 0x10000);
+       munmap(psxRegs.ptrs.psxH, 0x10000);
 err_unmap_bios:
-       munmap(psxR, 0x200000);
+       munmap(psxRegs.ptrs.psxR, 0x200000);
 err_unmap_parallel:
-       munmap(psxP, 0x10000);
+       munmap(psxRegs.ptrs.psxP, 0x10000);
 err_unmap:
        for (i = 0; i < 4; i++)
-               munmap((void *)((uintptr_t)psxM + i * 0x200000), 0x200000);
+               munmap((void *)((uintptr_t)psxRegs.ptrs.psxM + i * 0x200000), 0x200000);
        return err;
 }
 
@@ -228,9 +228,9 @@ void lightrec_free_mmap(void)
        unsigned int i;
 
        munmap(code_buffer, CODE_BUFFER_SIZE);
-       munmap(psxH, 0x10000);
-       munmap(psxR, 0x200000);
-       munmap(psxP, 0x10000);
+       munmap(psxRegs.ptrs.psxH, 0x10000);
+       munmap(psxRegs.ptrs.psxR, 0x200000);
+       munmap(psxRegs.ptrs.psxP, 0x10000);
        for (i = 0; i < 4; i++)
-               munmap((void *)((uintptr_t)psxM + i * 0x200000), 0x200000);
+               munmap((void *)((uintptr_t)psxRegs.ptrs.psxM + i * 0x200000), 0x200000);
 }
index 3e11265..bdee408 100644 (file)
@@ -362,9 +362,9 @@ static struct lightrec_mem_map lightrec_map[] = {
 static void lightrec_enable_ram(struct lightrec_state *state, bool enable)
 {
        if (enable)
-               memcpy(psxM, cache_buf, sizeof(cache_buf));
+               memcpy(psxRegs.ptrs.psxM, cache_buf, sizeof(cache_buf));
        else
-               memcpy(cache_buf, psxM, sizeof(cache_buf));
+               memcpy(cache_buf, psxRegs.ptrs.psxM, sizeof(cache_buf));
 
        ram_disabled = !enable;
 }
@@ -462,11 +462,11 @@ static const struct lightrec_ops lightrec_ops = {
 
 static int lightrec_plugin_init(void)
 {
-       lightrec_map[PSX_MAP_KERNEL_USER_RAM].address = psxM;
-       lightrec_map[PSX_MAP_BIOS].address = psxR;
-       lightrec_map[PSX_MAP_SCRATCH_PAD].address = psxH;
-       lightrec_map[PSX_MAP_HW_REGISTERS].address = psxH + 0x1000;
-       lightrec_map[PSX_MAP_PARALLEL_PORT].address = psxP;
+       lightrec_map[PSX_MAP_KERNEL_USER_RAM].address = psxRegs.ptrs.psxM;
+       lightrec_map[PSX_MAP_BIOS].address = psxRegs.ptrs.psxR;
+       lightrec_map[PSX_MAP_SCRATCH_PAD].address = psxRegs.ptrs.psxH;
+       lightrec_map[PSX_MAP_HW_REGISTERS].address = psxRegs.ptrs.psxH + 0x1000;
+       lightrec_map[PSX_MAP_PARALLEL_PORT].address = psxRegs.ptrs.psxP;
 
        if (!LIGHTREC_CUSTOM_MAP) {
 #if P_HAVE_MMAP
@@ -483,9 +483,9 @@ static int lightrec_plugin_init(void)
        }
 
        if (LIGHTREC_CUSTOM_MAP) {
-               lightrec_map[PSX_MAP_MIRROR1].address = psxM + 0x200000;
-               lightrec_map[PSX_MAP_MIRROR2].address = psxM + 0x400000;
-               lightrec_map[PSX_MAP_MIRROR3].address = psxM + 0x600000;
+               lightrec_map[PSX_MAP_MIRROR1].address = psxRegs.ptrs.psxM + 0x200000;
+               lightrec_map[PSX_MAP_MIRROR2].address = psxRegs.ptrs.psxM + 0x400000;
+               lightrec_map[PSX_MAP_MIRROR3].address = psxRegs.ptrs.psxM + 0x600000;
        }
 
        lightrec_map[PSX_MAP_CODE_BUFFER].address = code_buffer;
@@ -507,10 +507,10 @@ static int lightrec_plugin_init(void)
                        &lightrec_ops);
 
        // fprintf(stderr, "M=0x%lx, P=0x%lx, R=0x%lx, H=0x%lx\n",
-       //              (uintptr_t) psxM,
-       //              (uintptr_t) psxP,
-       //              (uintptr_t) psxR,
-       //              (uintptr_t) psxH);
+       //              (uintptr_t) psxRegs.ptrs.psxM,
+       //              (uintptr_t) psxRegs.ptrs.psxP,
+       //              (uintptr_t) psxRegs.ptrs.psxR,
+       //              (uintptr_t) psxRegs.ptrs.psxH);
 
 #ifndef _WIN32
        signal(SIGPIPE, exit);
@@ -587,9 +587,9 @@ static void print_for_big_ass_debugger(void)
 
        if (lightrec_very_debug)
                printf(" RAM 0x%08x SCRATCH 0x%08x HW 0x%08x",
-                               hash_calculate_ram(psxM, 0x200000),
-                               hash_calculate_le(psxH, 0x400),
-                               hash_calculate_le(psxH + 0x1000, 0x2000));
+                               hash_calculate_ram(psxRegs.ptrs.psxM, 0x200000),
+                               hash_calculate_le(psxRegs.ptrs.psxH, 0x400),
+                               hash_calculate_le(psxRegs.ptrs.psxH + 0x1000, 0x2000));
 
        printf(" CP0 0x%08x CP2D 0x%08x CP2C 0x%08x INT 0x%04x INTCYCLE 0x%08x GPU 0x%08x",
                        hash_calculate(regs->cp0, sizeof(regs->cp0)),
index f42e67b..18b8566 100644 (file)
@@ -457,7 +457,7 @@ void mdecInit(void) {
        memset(&mdec, 0, sizeof(mdec));
        memset(iq_y, 0, sizeof(iq_y));
        memset(iq_uv, 0, sizeof(iq_uv));
-       mdec.rl = (u16 *)&psxM[0x100000];
+       mdec.rl = (u16 *)&psxRegs.ptrs.psxM[0x100000];
 }
 
 // command register
@@ -705,7 +705,7 @@ void mdec1Interrupt() {
 }
 
 int mdecFreeze(void *f, int Mode) {
-       u8 *base = (u8 *)psxM;
+       u8 *base = (u8 *)psxRegs.ptrs.psxM;
        u32 v;
 
        gzfreeze(&mdec.reg0, sizeof(mdec.reg0));
index 145b964..fcac1a8 100644 (file)
@@ -703,7 +703,7 @@ struct misc_save_data {
 #define EX_SCREENPIC_SIZE (128 * 96 * 3)
 
 int SaveState(const char *file) {
-       struct misc_save_data *misc = (void *)(psxH + 0xf000);
+       struct misc_save_data *misc = (void *)(psxRegs.ptrs.psxH + 0xf000);
        struct origin_info oi = { 0, };
        GPUFreeze_t *gpufP = NULL;
        SPUFreezeHdr_t spufH;
@@ -757,9 +757,9 @@ int SaveState(const char *file) {
        if (Config.HLE)
                psxBiosFreeze(1);
 
-       SaveFuncs.write(f, psxM, 0x00200000);
-       SaveFuncs.write(f, psxR, 0x00080000);
-       SaveFuncs.write(f, psxH, 0x00010000);
+       SaveFuncs.write(f, psxRegs.ptrs.psxM, 0x00200000);
+       SaveFuncs.write(f, psxRegs.ptrs.psxR, 0x00080000);
+       SaveFuncs.write(f, psxRegs.ptrs.psxH, 0x00010000);
        // only partial save of psxRegisters to maintain savestate compat
        SaveFuncs.write(f, &psxRegs, offsetof(psxRegisters, gteBusyCycle));
 
@@ -797,7 +797,7 @@ cleanup:
 }
 
 int LoadState(const char *file) {
-       struct misc_save_data *misc = (void *)(psxH + 0xf000);
+       struct misc_save_data *misc = (void *)(psxRegs.ptrs.psxH + 0xf000);
        u32 biosBranchCheckOld = psxRegs.biosBranchCheck;
        void *f;
        GPUFreeze_t *gpufP = NULL;
@@ -841,9 +841,9 @@ int LoadState(const char *file) {
        // ex-ScreenPic space
        SaveFuncs.seek(f, EX_SCREENPIC_SIZE, SEEK_CUR);
 
-       SaveFuncs.read(f, psxM, 0x00200000);
-       SaveFuncs.read(f, psxR, 0x00080000);
-       SaveFuncs.read(f, psxH, 0x00010000);
+       SaveFuncs.read(f, psxRegs.ptrs.psxM, 0x00200000);
+       SaveFuncs.read(f, psxRegs.ptrs.psxR, 0x00080000);
+       SaveFuncs.read(f, psxRegs.ptrs.psxH, 0x00010000);
        SaveFuncs.read(f, &psxRegs, offsetof(psxRegisters, gteBusyCycle));
        psxRegs.gteBusyCycle = psxRegs.cycle;
        psxRegs.branching = 0;
index 7880e02..4802746 100644 (file)
@@ -616,7 +616,7 @@ static int ari64_init()
 #ifdef DRC_DBG
        memcpy(gte_handlers_nf, gte_handlers, sizeof(gte_handlers_nf));
 #endif
-       psxH_ptr = psxH;
+       psxH_ptr = psxRegs.ptrs.psxH;
        zeromem_ptr = zero_mem;
        scratch_buf_ptr = scratch_buf; // for gte_neon.S
 
index 53cef59..29be3b1 100644 (file)
@@ -23,8 +23,9 @@
 #define LO_muldivBusyCycle     (LO_gteBusyCycle + 4)
 #define LO_psxRegs_subCycle    (LO_muldivBusyCycle + 4)
 #define LO_psxRegs_biuReg      (LO_psxRegs_subCycle + 4*2)
-#define LO_stop                (LO_psxRegs_biuReg + 4)
-#define LO_psxRegs_end         (LO_stop + 4*9)
+#define LO_stop                        (LO_psxRegs_biuReg + 4)
+#define LO_psxRegs_ptrs                (LO_stop + 4*7)
+#define LO_psxRegs_end         (LO_psxRegs_ptrs + PTRSZ*10)
 #define LO_rcnts               (LO_psxRegs_end)
 #define LO_rcnts_end           (LO_rcnts + 7*4*4)
 #define LO_inv_code_start      (LO_rcnts_end)
index 1111588..e31d229 100644 (file)
@@ -2967,7 +2967,7 @@ static void *emit_fastpath_cmp_jump(int i, const struct regstat *i_regs,
     type=0;
   }
   else if(type==MTYPE_1F80) { // scratchpad
-    if (psxH == (void *)0x1f800000) {
+    if (psxRegs.ptrs.psxH == (void *)0x1f800000) {
       host_tempreg_acquire();
       emit_xorimm(addr,0x1f800000,HOST_TEMPREG);
       emit_cmpimm(HOST_TEMPREG,0x1000);
@@ -6470,11 +6470,12 @@ void new_dynarec_init(void)
 #endif
   arch_init();
   new_dynarec_test();
-  ram_offset = (uintptr_t)psxM - 0x80000000;
+  ram_offset = (uintptr_t)psxRegs.ptrs.psxM - 0x80000000;
   if (ram_offset != 0)
     SysPrintf("RAM is not directly mapped\n");
   SysPrintf("Mapped (RAM/scrp/ROM/LUTs/TC):\n");
-  SysPrintf("%p/%p/%p/%p/%p\n", psxM, psxH, psxR, mem_rtab, out);
+  SysPrintf("%p/%p/%p/%p/%p\n", psxRegs.ptrs.psxM, psxRegs.ptrs.psxH,
+    psxRegs.ptrs.psxR, mem_rtab, out);
 }
 
 void new_dynarec_cleanup(void)
@@ -6513,7 +6514,7 @@ static u_int *get_source_start(u_int addr, u_int *limit)
   {
     // used for BIOS calls mostly?
     *limit = (addr & 0xa0600000) + 0x00200000;
-    return (u_int *)(psxM + (addr & 0x1fffff));
+    return (u_int *)(psxRegs.ptrs.psxM + (addr & 0x1fffff));
   }
   else if (
     (0x9fc00000u <= addr && addr < 0x9fc80000u) ||
@@ -6526,7 +6527,7 @@ static u_int *get_source_start(u_int addr, u_int *limit)
     //  cycle_multiplier_active = 200;
 
     *limit = (addr & 0xfff00000) | 0x80000;
-    return (u_int *)((u_char *)psxR + (addr&0x7ffff));
+    return (u_int *)((u_char *)psxRegs.ptrs.psxR + (addr&0x7ffff));
   }
   return NULL;
 }
@@ -6682,7 +6683,7 @@ static noinline void do_vsync(int i)
 
   if (!is_ram_addr(addr))
       return;
-  str = (char *)psxM + (addr & 0x1fffff);
+  str = (char *)psxRegs.ptrs.psxM + (addr & 0x1fffff);
   if (!str || strncmp(str, "VSync: timeout", 14))
     return;
   // jal clearPad, jal clearRCnt; j return; nop
index 98e2c6b..804330b 100644 (file)
@@ -130,8 +130,8 @@ static void map_rcnt_rcount1(u32 mode)
 static void map_rcnt_rcount2(u32 mode)
 {
        if ((mode & 7) == 1 || (mode & 7) == 7) { // sync mode
-               map_item(&mem_iortab[IOMEM32(0x1120)], &psxH[0x1000], 0);
-               map_item(&mem_iortab[IOMEM16(0x1120)], &psxH[0x1000], 0);
+               map_item(&mem_iortab[IOMEM32(0x1120)], &psxRegs.ptrs.psxH[0x1000], 0);
+               map_item(&mem_iortab[IOMEM16(0x1120)], &psxRegs.ptrs.psxH[0x1000], 0);
        }
        else if (mode & 0x200) { // clk/8
                map_item(&mem_iortab[IOMEM32(0x1120)], rcnt2_read_count_m1, 1);
@@ -214,9 +214,10 @@ void new_dyna_pcsx_mem_isolate(int enable)
        }
        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);
+                       void *ram = psxRegs.ptrs.psxM;
+                       map_l1_mem(mem_writetab, i, 0x80000000, 0x200000, ram);
+                       map_l1_mem(mem_writetab, i, 0x00000000, 0x200000, ram);
+                       map_l1_mem(mem_writetab, i, 0xa0000000, 0x200000, ram);
                }
        }
 }
@@ -308,25 +309,26 @@ void new_dyna_pcsx_mem_init(void)
                map_item(&mem_writetab[i], mem_unmwtab, 1);
        }
 
-       // RAM and it's mirrors
+       // RAM and its mirrors
        for (i = 0; i < (0x800000 >> 12); i++) {
-               map_l1_mem(mem_readtab,  i, 0x80000000, 0x200000, psxM);
-               map_l1_mem(mem_readtab,  i, 0x00000000, 0x200000, psxM);
-               map_l1_mem(mem_readtab,  i, 0xa0000000, 0x200000, psxM);
+               void *ram = psxRegs.ptrs.psxM;
+               map_l1_mem(mem_readtab,  i, 0x80000000, 0x200000, ram);
+               map_l1_mem(mem_readtab,  i, 0x00000000, 0x200000, ram);
+               map_l1_mem(mem_readtab,  i, 0xa0000000, 0x200000, ram);
        }
        new_dyna_pcsx_mem_isolate(0);
 
-       // BIOS and it's mirrors
+       // BIOS and its mirrors
        for (i = 0; i < (0x80000 >> 12); i++) {
-               map_l1_mem(mem_readtab, i, 0x1fc00000, 0x80000, psxR);
-               map_l1_mem(mem_readtab, i, 0xbfc00000, 0x80000, psxR);
+               map_l1_mem(mem_readtab, i, 0x1fc00000, 0x80000, psxRegs.ptrs.psxR);
+               map_l1_mem(mem_readtab, i, 0xbfc00000, 0x80000, psxRegs.ptrs.psxR);
        }
 
        // 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);
+       map_l1_mem(mem_readtab, 0, 0x1f800000, 0x1000, psxRegs.ptrs.psxH);
+       map_l1_mem(mem_readtab, 0, 0x9f800000, 0x1000, psxRegs.ptrs.psxH);
+       map_l1_mem(mem_writetab, 0, 0x1f800000, 0x1000, psxRegs.ptrs.psxH);
+       map_l1_mem(mem_writetab, 0, 0x9f800000, 0x1000, psxRegs.ptrs.psxH);
 
        // I/O
        map_item(&mem_readtab[0x1f801000u >> 12], mem_iortab, 1);
@@ -343,16 +345,16 @@ void new_dyna_pcsx_mem_init(void)
 
        // fill IO tables
        for (i = 0; i < 0x1000/4; i++) {
-               map_item(&mem_iortab[i], &psxH[0x1000], 0);
-               map_item(&mem_iowtab[i], &psxH[0x1000], 0);
+               map_item(&mem_iortab[i], &psxRegs.ptrs.psxH[0x1000], 0);
+               map_item(&mem_iowtab[i], &psxRegs.ptrs.psxH[0x1000], 0);
        }
        for (; i < 0x1000/4 + 0x1000/2; i++) {
-               map_item(&mem_iortab[i], &psxH[0x1000], 0);
-               map_item(&mem_iowtab[i], &psxH[0x1000], 0);
+               map_item(&mem_iortab[i], &psxRegs.ptrs.psxH[0x1000], 0);
+               map_item(&mem_iowtab[i], &psxRegs.ptrs.psxH[0x1000], 0);
        }
        for (; i < 0x1000/4 + 0x1000/2 + 0x1000; i++) {
-               map_item(&mem_iortab[i], &psxH[0x1000], 0);
-               map_item(&mem_iowtab[i], &psxH[0x1000], 0);
+               map_item(&mem_iortab[i], &psxRegs.ptrs.psxH[0x1000], 0);
+               map_item(&mem_iowtab[i], &psxRegs.ptrs.psxH[0x1000], 0);
        }
 
        map_item(&mem_iortab[IOMEM32(0x1040)], io_read_sio32, 1);
index accecb8..500cc27 100644 (file)
@@ -332,25 +332,25 @@ static int card_io_delay;
 static u8 loadRam8(u32 addr)
 {
        assert(!(addr & 0x5f800000));
-       return psxM[addr & 0x1fffff];
+       return psxRegs.ptrs.psxM[addr & 0x1fffff];
 }
 
 static u32 loadRam32(u32 addr)
 {
        assert(!(addr & 0x5f800000));
-       return SWAP32(*((u32 *)psxM + ((addr & 0x1fffff) >> 2)));
+       return SWAP32(*((u32 *)psxRegs.ptrs.psxM + ((addr & 0x1fffff) >> 2)));
 }
 
 static void *castRam8ptr(u32 addr)
 {
        assert(!(addr & 0x5f800000));
-       return psxM + (addr & 0x1fffff);
+       return psxRegs.ptrs.psxM + (addr & 0x1fffff);
 }
 
 static void *castRam32ptr(u32 addr)
 {
        assert(!(addr & 0x5f800003));
-       return psxM + (addr & 0x1ffffc);
+       return psxRegs.ptrs.psxM + (addr & 0x1ffffc);
 }
 
 static void *loadRam8ptr(u32 addr)
@@ -366,13 +366,13 @@ static void *loadRam32ptr(u32 addr)
 static void storeRam8(u32 addr, u8 d)
 {
        assert(!(addr & 0x5f800000));
-       *((u8 *)psxM + (addr & 0x1fffff)) = d;
+       *((u8 *)psxRegs.ptrs.psxM + (addr & 0x1fffff)) = d;
 }
 
 static void storeRam32(u32 addr, u32 d)
 {
        assert(!(addr & 0x5f800000));
-       *((u32 *)psxM + ((addr & 0x1fffff) >> 2)) = SWAP32(d);
+       *((u32 *)psxRegs.ptrs.psxM + ((addr & 0x1fffff) >> 2)) = SWAP32(d);
 }
 
 static void mips_return(u32 val)
@@ -514,7 +514,7 @@ static int card_buf_io(int is_write, int port, void *buf, u32 size)
                        SaveMcd(Config.Mcd2, Mcd2Data, offset, size);
        }
        else {
-               size_t ram_offset = (s8 *)buf - psxM;
+               size_t ram_offset = (u8 *)buf - psxRegs.ptrs.psxM;
                memcpy(buf, mcdptr + offset, size);
                if (ram_offset < 0x200000)
                        psxCpu->Clear(ram_offset, (size + 3) / 4);
@@ -1902,7 +1902,7 @@ static void psxBios_SysDeqIntRP_(u32 priority, u32 chain_rm_eptr);
 
 static void psxBios_EnqueueCdIntr_(void)
 {
-       u32 *ram32 = (u32 *)psxM;
+       u32 *ram32 = (u32 *)psxRegs.ptrs.psxM;
 
        // traps should already be installed by write_chain()
        ram32[0x91d0/4] = 0;
@@ -2056,7 +2056,7 @@ static void psxBios_GetSystemInfo() { // b4
        SysPrintf("psxBios_%s %x\n", biosA0n[0xb4], a0);
        switch (a0) {
        case 0:
-       case 1: ret = SWAP32(((u32 *)psxR)[0x100/4 + a0]); break;
+       case 1: ret = SWAP32(((u32 *)psxRegs.ptrs.psxR)[0x100/4 + a0]); break;
        case 2: ret = 0xbfc0012c; break;
        case 5: ret = loadRam32(0x60) << 10; break;
        }
@@ -2403,7 +2403,7 @@ void psxBios_ChangeTh() { // 10
 }
 
 void psxBios_InitPAD() { // 0x12
-       u32 i, *ram32 = (u32 *)psxM;
+       u32 i, *ram32 = (u32 *)psxRegs.ptrs.psxM;
        PSXBIOS_LOG("psxBios_%s %x %x %x %x\n", biosB0n[0x12], a0, a1, a2, a3);
 
        // printf("%s", "PS-X Control PAD Driver  Ver 3.0");
@@ -2948,8 +2948,8 @@ void psxBios_delete() { // 45
 }
 
 void psxBios_InitCARD() { // 4a
-       u8 *ram8 = (u8 *)psxM;
-       u32 *ram32 = (u32 *)psxM;
+       u8 *ram8 = (u8 *)psxRegs.ptrs.psxM;
+       u32 *ram32 = (u32 *)psxRegs.ptrs.psxM;
        PSXBIOS_LOG("psxBios_%s: %x\n", biosB0n[0x4a], a0);
        write_chain(ram32 + A_PADCRD_CHN_E/4, 0, 0x49bc, 0x4a4c);
        //card_error = 0;
@@ -3406,12 +3406,12 @@ void (**biosB0)() = biosC0 + 128;
 static void setup_mips_code()
 {
        u32 *ptr;
-       ptr = (u32 *)&psxM[A_SYSCALL];
+       ptr = (u32 *)&psxRegs.ptrs.psxM[A_SYSCALL];
        ptr[0x00/4] = SWAPu32(0x0000000c); // syscall 0
        ptr[0x04/4] = SWAPu32(0x03e00008); // jr    $ra
        ptr[0x08/4] = SWAPu32(0x00000000); // nop
 
-       ptr = (u32 *)&psxM[A_EXCEPTION];
+       ptr = (u32 *)&psxRegs.ptrs.psxM[A_EXCEPTION];
        memset(ptr, 0, 0xc0);              // nops (to be patched by games sometimes)
        ptr[0x10/4] = SWAPu32(0x8c1a0108); // lw    $k0, (0x108)   // PCB
        ptr[0x14/4] = SWAPu32(0x00000000); // nop
@@ -3475,7 +3475,7 @@ static void write_chain(u32 *d, u32 next, u32 handler1, u32 handler2)
 
 static void setup_tt(u32 tcb_cnt, u32 evcb_cnt, u32 stack)
 {
-       u32 *ram32 = (u32 *)psxM;
+       u32 *ram32 = (u32 *)psxRegs.ptrs.psxM;
        u32 s_excb = 0x20, s_evcb, s_pcb = 4, s_tcb;
        u32 p_excb, p_evcb, p_pcb, p_tcb;
        u32 i;
@@ -3572,7 +3572,7 @@ static void spu_clear_mem(u32 addr, u32 size)
 void psxBiosSetupBootState(void)
 {
        boolean hle = Config.HLE;
-       u32 *hw = (u32 *)psxH;
+       u32 *hw = (u32 *)psxRegs.ptrs.psxH;
        int i;
 
        // see also SetBootRegs()
@@ -3656,7 +3656,7 @@ void psxBiosInit() {
 
        psxRegs.biosBranchCheck = ~0;
 
-       memset(psxM, 0, 0x10000);
+       memset(psxRegs.ptrs.psxM, 0, 0x10000);
        for(i = 0; i < 256; i++) {
                biosA0[i] = NULL;
                biosB0[i] = NULL;
@@ -3670,11 +3670,11 @@ void psxBiosInit() {
 
        if (!Config.HLE) {
                char verstr[0x24+1];
-               rom32 = (u32 *)psxR;
-               memcpy(verstr, psxR + 0x12c, 0x24);
+               rom32 = (u32 *)psxRegs.ptrs.psxR;
+               memcpy(verstr, psxRegs.ptrs.psxR + 0x12c, 0x24);
                verstr[0x24] = 0;
                SysPrintf("BIOS: %08x, '%s', '%c'\n", SWAP32(rom32[0x100/4]),
-                       verstr, psxR[0x7ff52]);
+                       verstr, psxRegs.ptrs.psxR[0x7ff52]);
                return;
        }
 
@@ -3999,10 +3999,10 @@ void psxBiosInit() {
 
        // somewhat pretend to be a SCPH1001 BIOS
        // some games look for these and take an exception if they're missing
-       rom32 = (u32 *)psxR;
+       rom32 = (u32 *)psxRegs.ptrs.psxR;
        rom32[0x100/4] = SWAP32(0x19951204);
        rom32[0x104/4] = SWAP32(3);
-       romc = (char *)psxR;
+       romc = (char *)psxRegs.ptrs.psxR;
        strcpy(romc + 0x108, "PCSX authors");
        strcpy(romc + 0x12c, "CEX-3000 PCSX HLE"); // see psxBios_GetSystemInfo
        strcpy(romc + 0x7ff32, "System ROM Version 2.2 12/04/95 A");
@@ -4010,9 +4010,9 @@ void psxBiosInit() {
 
        // fonts
        len = 0x80000 - 0x66000;
-       uncompress((Bytef *)(psxR + 0x66000), &len, font_8140, sizeof(font_8140));
+       uncompress((Bytef *)(romc + 0x66000), &len, font_8140, sizeof(font_8140));
        len = 0x80000 - 0x69d68;
-       uncompress((Bytef *)(psxR + 0x69d68), &len, font_889f, sizeof(font_889f));
+       uncompress((Bytef *)(romc + 0x69d68), &len, font_889f, sizeof(font_889f));
 
        // trap attempts to call bios directly
        rom32[0x00000/4] = HLEOP(hleop_dummy);
@@ -4028,7 +4028,7 @@ void psxBiosInit() {
                Crash Team Racing will softlock after the Sony logo.
        */
 
-       ram32 = (u32 *)psxM;
+       ram32 = (u32 *)psxRegs.ptrs.psxM;
        ram32[0x0000/4] = SWAPu32(0x00000003); // lui   $k0, 0  (overwritten by 3)
        ram32[0x0004/4] = SWAPu32(0x275a0000 + A_EXCEPTION); // addiu $k0, $k0, 0xc80
        ram32[0x0008/4] = SWAPu32(0x03400008); // jr    $k0
@@ -4069,12 +4069,12 @@ void psxBiosInit() {
        // (or rather the funcs listed there)
        // also trap the destination as some "Cheats Edition" thing overrides the
        // dispatcher with a wrapper and then jumps to the table entries directly
-       ptr = (u32 *)&psxM[A_A0_TABLE];
+       ptr = (u32 *)&psxRegs.ptrs.psxM[A_A0_TABLE];
        for (i = 0; i < 256; i++) {
                ptr[i] = SWAP32(A_A0_TRAPS + i*4);
                ram32[A_A0_TRAPS/4 + i] = HLEOP(hleop_a0t);
        }
-       ptr = (u32 *)&psxM[A_B0_TABLE];
+       ptr = (u32 *)&psxRegs.ptrs.psxM[A_B0_TABLE];
        for (i = 0; i < 256; i++) {
                ptr[i] = SWAP32(A_B0_TRAPS + i*4);
                ram32[A_B0_TRAPS/4 + i] = HLEOP(hleop_b0t);
@@ -4095,7 +4095,7 @@ void psxBiosInit() {
        ram32[0x4c64/4] = SWAP32(0x03e00008); // jr $ra
        ram32[0x4c68/4] = SWAP32(0xac000000 + A_PAD_IRQR_ENA); // sw $0, ...
 
-       ptr = (u32 *)&psxM[A_C0_TABLE];
+       ptr = (u32 *)&psxRegs.ptrs.psxM[A_C0_TABLE];
        for (i = 0; i < 256/2; i++) {
                ptr[i] = SWAP32(A_C0_TRAPS + i*4);
                ram32[A_C0_TRAPS/4 + i] = HLEOP(hleop_c0t);
@@ -4574,7 +4574,7 @@ void psxBiosCheckExe(u32 t_addr, u32 t_size, int loading_state)
        u32 start = t_addr & 0x1ffffc;
        u32 end = (start + t_size) & 0x1ffffc;
        u32 buf[sizeof(pattern) / sizeof(u32)];
-       const u32 *r32 = (u32 *)(psxM + start);
+       const u32 *r32 = (u32 *)(psxRegs.ptrs.psxM + start);
        u32 i, j;
 
        if (end <= start)
@@ -4625,8 +4625,8 @@ void psxBiosCheckBranch(void)
 }
 
 #define bfreeze(ptr, size) { \
-       if (Mode == 1) memcpy(&psxR[base], ptr, size); \
-       if (Mode == 0) memcpy(ptr, &psxR[base], size); \
+       if (Mode == 1) memcpy(&psxRegs.ptrs.psxR[base], ptr, size); \
+       if (Mode == 0) memcpy(ptr, &psxRegs.ptrs.psxR[base], size); \
        base += size; \
 }
 
index 6dc5d63..6904c43 100644 (file)
@@ -200,7 +200,7 @@ void psxDma2(u32 madr, u32 bcr, u32 chcr) { // GPU
                                do_walking = Config.hacks.gpu_slow_list_walking;
                        madr_next_p = do_walking ? &madr_next : NULL;
 
-                       cycles_sum = GPU_dmaChain((u32 *)psxM, madr & 0x1fffff,
+                       cycles_sum = GPU_dmaChain((u32 *)psxRegs.ptrs.psxM, madr & 0x1fffff,
                                        madr_next_p, &cycles_last_cmd);
 
                        HW_DMA2_MADR = SWAPu32(madr_next);
@@ -234,8 +234,8 @@ void gpuInterrupt() {
 
                do {
                        cycles_sum += cycles_last_cmd;
-                       cycles_sum += GPU_dmaChain((u32 *)psxM, madr_next & 0x1fffff,
-                                       &madr_next, &cycles_last_cmd);
+                       cycles_sum += GPU_dmaChain((u32 *)psxRegs.ptrs.psxM,
+                                       madr_next & 0x1fffff, &madr_next, &cycles_last_cmd);
                }
                while (cycles_sum <= 0 && !(madr_next & 0x800000));
                HW_DMA2_MADR = SWAPu32(madr_next);
@@ -275,7 +275,7 @@ void psxDma6(u32 madr, u32 bcr, u32 chcr) {
                // already 32-bit size
                words = bcr;
 
-               while (bcr-- && mem > (u32 *)psxM) {
+               while (bcr-- && mem > (u32 *)psxRegs.ptrs.psxM) {
                        *mem-- = SWAP32((madr - 4) & 0xffffff);
                        madr -= 4;
                }
index ce10d9d..88bb10f 100644 (file)
@@ -45,7 +45,7 @@ static inline void *getDmaRam(u32 madr, u32 *max_words)
        if (!(madr & 0x800000)) {
                madr &= 0x1ffffc;
                *max_words = (0x200000 - madr) / 4;
-               return psxM + madr;
+               return psxRegs.ptrs.psxM + madr;
        }
        return INVALID_PTR;
 }
index 1afa9c6..69d3d03 100644 (file)
@@ -29,7 +29,7 @@
 #include "../include/compiler_features.h"
 
 void psxHwReset() {
-       memset(psxH, 0, 0x10000);
+       memset(psxRegs.ptrs.psxH, 0, 0x10000);
 
        mdecInit(); // initialize mdec decoder
        cdrReset();
@@ -438,6 +438,11 @@ void psxHwWrite32(u32 add, u32 value) {
        case 0x1124: psxRcntWmode(2, value); return;
        case 0x1128: psxRcntWtarget(2, value & 0xffff); return;
 
+       case 0x1060:
+               if ((value >> 9) != 5)
+                       log_unhandled("unhandled RAM_SIZE %08x @%08x\n", value, psxRegs.pc);
+               break;
+
        case 0x1044:
        case 0x1048:
        case 0x104c:
index 68d7932..ad69c5f 100644 (file)
 #define DO_EXCEPTION_RESERVEDI
 #define HANDLE_LOAD_DELAY
 
-#ifdef __i386__
-#define INT_ATTR __attribute__((regparm(2)))
-#else
-#define INT_ATTR
-#endif
 #ifndef INVALID_PTR
 #define INVALID_PTR NULL
 #endif
@@ -174,17 +169,17 @@ static int execBreakCheck(psxRegisters *regs, u32 pc)
 // get an opcode without triggering exceptions or affecting cache
 u32 intFakeFetch(u32 pc)
 {
-       u32 *code = (u32 *)psxm(pc & ~0x3, 0);
-       if (unlikely(code == INVALID_PTR))
+       const u32 *code;
+       if (!psxm_lut((u8 **)&code, &psxRegs, pc & ~0x3, 0, psxRegs.ptrs.memRLUT))
                return 0; // nop
        return SWAP32(*code);
 
 }
 
-static u32 INT_ATTR fetchNoCache(psxRegisters *regs, u8 **memRLUT, u32 pc)
+static u32 INT_ATTR fetchNoCache(psxRegisters *regs, const uintptr_t *memRLUT, u32 pc)
 {
-       u32 *code = (u32 *)psxm_lut(pc & ~0x3, 0, memRLUT);
-       if (unlikely(code == INVALID_PTR)) {
+       const u32 *code;
+       if (!psxm_lut((u8 **)&code, regs, pc & ~0x3, 0, memRLUT)) {
                SysPrintf("game crash @%08x, ra=%08x\n", pc, regs->GPR.n.ra);
                intException(regs, pc, R3000E_IBE << 2);
                return 0; // execute as nop
@@ -201,7 +196,7 @@ static struct cache_entry {
        u32 data[4];
 } ICache[256];
 
-static u32 INT_ATTR fetchICache(psxRegisters *regs, u8 **memRLUT, u32 pc)
+static u32 INT_ATTR fetchICache(psxRegisters *regs, const uintptr_t *memRLUT, u32 pc)
 {
        // cached?
        if (pc < 0xa0000000)
@@ -211,8 +206,8 @@ static u32 INT_ATTR fetchICache(psxRegisters *regs, u8 **memRLUT, u32 pc)
 
                if (((entry->tag ^ pc) & 0xfffffff0) != 0 || pc < entry->tag)
                {
-                       const u32 *code = (u32 *)psxm_lut(pc & ~0xf, 0, memRLUT);
-                       if (unlikely(code == INVALID_PTR)) {
+                       const u32 *code;
+                       if (!psxm_lut((u8 **)&code, regs, pc & ~0x0f, 0, memRLUT)) {
                                SysPrintf("game crash @%08x, ra=%08x\n", pc, regs->GPR.n.ra);
                                intException(regs, pc, R3000E_IBE << 2);
                                return 0; // execute as nop
@@ -234,8 +229,6 @@ static u32 INT_ATTR fetchICache(psxRegisters *regs, u8 **memRLUT, u32 pc)
        return fetchNoCache(regs, memRLUT, pc);
 }
 
-static u32 (INT_ATTR *fetch)(psxRegisters *regs_, u8 **memRLUT, u32 pc) = fetchNoCache;
-
 // Make the timing events trigger faster as we are currently assuming everything
 // takes one cycle, which is not the case on real hardware.
 // FIXME: count cache misses, memory latencies, stalls to get rid of this
@@ -390,7 +383,8 @@ static void psxDoDelayBranch(psxRegisters *regs, u32 tar1, u32 code1) {
         *   has no normal delay slot, instruction at tar1 was fetched instead)
         */
        for (lim = 0; lim < 8; lim++) {
-               regs->code = code = fetch(regs, psxMemRLUT, tar1);
+               code = regs->ptrs.intFetch(regs, regs->ptrs.memRLUT, tar1);
+               regs->code = code;
                addCycle(regs);
                if (likely(!isBranch(code))) {
                        dloadStep(regs);
@@ -416,7 +410,7 @@ static void doBranch(psxRegisters *regs, u32 tar, enum R3000Abdt taken) {
        // fetch the delay slot
        pc = regs->pc;
        regs->pc = pc + 4;
-       regs->code = code = fetch(regs, psxMemRLUT, pc);
+       regs->code = code = regs->ptrs.intFetch(regs, regs->ptrs.memRLUT, pc);
 
        addCycle(regs);
 
@@ -664,15 +658,17 @@ OP(psxSYSCALL) {
        intExceptionInsn(regs_, R3000E_Syscall << 2);
 }
 
-static inline void execI_(u8 **memRLUT, psxRegisters *regs_);
+static inline void execI_(
+       u32 (INT_ATTR *fetch)(struct psxRegisters *r, const uintptr_t *luts, u32 pc),
+       const uintptr_t *memRLUT, psxRegisters *regs);
 
-static inline void psxTestSWInts(psxRegisters *regs_, int step) {
-       if ((regs_->CP0.n.Cause & regs_->CP0.n.SR & 0x0300) &&
-           (regs_->CP0.n.SR & 0x1)) {
+static inline void psxTestSWInts(psxRegisters *regs, int step) {
+       if ((regs->CP0.n.Cause & regs->CP0.n.SR & 0x0300) &&
+           (regs->CP0.n.SR & 0x1)) {
                if (step)
-                       execI_(psxMemRLUT, regs_);
-               regs_->CP0.n.Cause &= ~0x7c;
-               intException(regs_, regs_->pc, regs_->CP0.n.Cause);
+                       execI_(regs->ptrs.intFetch, regs->ptrs.memRLUT, regs);
+               regs->CP0.n.Cause &= ~0x7c;
+               intException(regs, regs->pc, regs->CP0.n.Cause);
        }
 }
 
@@ -801,17 +797,17 @@ static inline int checkST(psxRegisters *regs, u32 addr, u32 m) {
 
 #define _oB_ (regs_->GPR.r[_Rs_] + _Imm_)
 
-OP(psxLB)  { doLoad(regs_, _Rt_,  (s8)psxMemRead8(_oB_)); }
-OP(psxLBU) { doLoad(regs_, _Rt_,      psxMemRead8(_oB_)); }
-OP(psxLH)  { doLoad(regs_, _Rt_, (s16)psxMemRead16(_oB_ & ~1)); }
-OP(psxLHU) { doLoad(regs_, _Rt_,      psxMemRead16(_oB_ & ~1)); }
-OP(psxLW)  { doLoad(regs_, _Rt_,      psxMemRead32(_oB_ & ~3)); }
+OP(psxLB)  { doLoad(regs_, _Rt_,  (s8)psxMemRead8(regs_, _oB_)); }
+OP(psxLBU) { doLoad(regs_, _Rt_,      psxMemRead8(regs_, _oB_)); }
+OP(psxLH)  { doLoad(regs_, _Rt_, (s16)psxMemRead16(regs_, _oB_ & ~1)); }
+OP(psxLHU) { doLoad(regs_, _Rt_,      psxMemRead16(regs_, _oB_ & ~1)); }
+OP(psxLW)  { doLoad(regs_, _Rt_,      psxMemRead32(regs_, _oB_ & ~3)); }
 
-OP(psxLBe)  { if (checkLD(regs_, _oB_, 0)) doLoad(regs_, _Rt_,  (s8)psxMemRead8(_oB_)); }
-OP(psxLBUe) { if (checkLD(regs_, _oB_, 0)) doLoad(regs_, _Rt_,      psxMemRead8(_oB_)); }
-OP(psxLHe)  { if (checkLD(regs_, _oB_, 1)) doLoad(regs_, _Rt_, (s16)psxMemRead16(_oB_)); }
-OP(psxLHUe) { if (checkLD(regs_, _oB_, 1)) doLoad(regs_, _Rt_,      psxMemRead16(_oB_)); }
-OP(psxLWe)  { if (checkLD(regs_, _oB_, 3)) doLoad(regs_, _Rt_,      psxMemRead32(_oB_)); }
+OP(psxLBe)  { if (checkLD(regs_, _oB_, 0)) doLoad(regs_, _Rt_,  (s8)psxMemRead8(regs_, _oB_)); }
+OP(psxLBUe) { if (checkLD(regs_, _oB_, 0)) doLoad(regs_, _Rt_,      psxMemRead8(regs_, _oB_)); }
+OP(psxLHe)  { if (checkLD(regs_, _oB_, 1)) doLoad(regs_, _Rt_, (s16)psxMemRead16(regs_, _oB_)); }
+OP(psxLHUe) { if (checkLD(regs_, _oB_, 1)) doLoad(regs_, _Rt_,      psxMemRead16(regs_, _oB_)); }
+OP(psxLWe)  { if (checkLD(regs_, _oB_, 3)) doLoad(regs_, _Rt_,      psxMemRead32(regs_, _oB_)); }
 
 static void doLWL(psxRegisters *regs, u32 rt, u32 addr) {
        static const u32 LWL_MASK[4] = { 0xffffff, 0xffff, 0xff, 0 };
@@ -825,7 +821,7 @@ static void doLWL(psxRegisters *regs, u32 rt, u32 addr) {
        if (regs->dloadReg[sel] == rt)
                oldval = regs->dloadVal[sel];
 #endif
-       mem = psxMemRead32(addr & ~3);
+       mem = psxMemRead32(regs, addr & ~3);
        val = (oldval & LWL_MASK[shift]) | (mem << LWL_SHIFT[shift]);
        doLoad(regs, rt, val);
 
@@ -851,7 +847,7 @@ static void doLWR(psxRegisters *regs, u32 rt, u32 addr) {
        if (regs->dloadReg[sel] == rt)
                oldval = regs->dloadVal[sel];
 #endif
-       mem = psxMemRead32(addr & ~3);
+       mem = psxMemRead32(regs, addr & ~3);
        val = (oldval & LWR_MASK[shift]) | (mem >> LWR_SHIFT[shift]);
        doLoad(regs, rt, val);
 
@@ -871,23 +867,23 @@ OP(psxLWR) { doLWR(regs_, _Rt_, _oB_); }
 OP(psxLWLe) { if (checkLD(regs_, _oB_ & ~3, 0)) doLWL(regs_, _Rt_, _oB_); }
 OP(psxLWRe) { if (checkLD(regs_, _oB_     , 0)) doLWR(regs_, _Rt_, _oB_); }
 
-OP(psxSB) { psxMemWrite8 (_oB_, _rRt_); }
-OP(psxSH) { psxMemWrite16(_oB_, _rRt_); }
-OP(psxSW) { psxMemWrite32(_oB_, _rRt_); }
+OP(psxSB) { psxMemWrite8 (regs_, _oB_, _rRt_); }
+OP(psxSH) { psxMemWrite16(regs_, _oB_, _rRt_); }
+OP(psxSW) { psxMemWrite32(regs_, _oB_, _rRt_); }
 
-OP(psxSBe) { if (checkST(regs_, _oB_, 0)) psxMemWrite8 (_oB_, _rRt_); }
-OP(psxSHe) { if (checkST(regs_, _oB_, 1)) psxMemWrite16(_oB_, _rRt_); }
-OP(psxSWe) { if (checkST(regs_, _oB_, 3)) psxMemWrite32(_oB_, _rRt_); }
+OP(psxSBe) { if (checkST(regs_, _oB_, 0)) psxMemWrite8 (regs_, _oB_, _rRt_); }
+OP(psxSHe) { if (checkST(regs_, _oB_, 1)) psxMemWrite16(regs_, _oB_, _rRt_); }
+OP(psxSWe) { if (checkST(regs_, _oB_, 3)) psxMemWrite32(regs_, _oB_, _rRt_); }
 
 static void doSWL(psxRegisters *regs, u32 rt, u32 addr) {
        u32 val = regs->GPR.r[rt];
        switch (addr & 3) {
-               case 0: psxMemWrite8( addr     , val >> 24); break;
-               case 1: psxMemWrite16(addr & ~3, val >> 16); break;
+               case 0: psxMemWrite8( regs, addr     , val >> 24); break;
+               case 1: psxMemWrite16(regs, addr & ~3, val >> 16); break;
                case 2: // revisit: should be a single 24bit write
-                       psxMemWrite16(addr & ~3, (val >> 8) & 0xffff);
-                       psxMemWrite8( addr     , val >> 24); break;
-               case 3: psxMemWrite32(addr & ~3, val);       break;
+                       psxMemWrite16(regs, addr & ~3, (val >> 8) & 0xffff);
+                       psxMemWrite8( regs, addr     , val >> 24); break;
+               case 3: psxMemWrite32(regs, addr & ~3, val);       break;
        }
        /*
        Mem = 1234.  Reg = abcd
@@ -902,12 +898,12 @@ static void doSWL(psxRegisters *regs, u32 rt, u32 addr) {
 static void doSWR(psxRegisters *regs, u32 rt, u32 addr) {
        u32 val = regs->GPR.r[rt];
        switch (addr & 3) {
-               case 0: psxMemWrite32(addr    , val); break;
+               case 0: psxMemWrite32(regs, addr    , val); break;
                case 1: // revisit: should be a single 24bit write
-                       psxMemWrite8 (addr    , val & 0xff);
-                       psxMemWrite16(addr + 1, (val >> 8) & 0xffff); break;
-               case 2: psxMemWrite16(addr    , val & 0xffff); break;
-               case 3: psxMemWrite8 (addr    , val & 0xff); break;
+                       psxMemWrite8 (regs, addr    , val & 0xff);
+                       psxMemWrite16(regs, addr + 1, (val >> 8) & 0xffff); break;
+               case 2: psxMemWrite16(regs, addr    , val & 0xffff); break;
+               case 3: psxMemWrite8 (regs, addr    , val & 0xff); break;
        }
 
        /*
@@ -1053,7 +1049,7 @@ OP(psxCOP2_stall) {
 }
 
 OP(gteLWC2) {
-       MTC2(&regs_->CP2, psxMemRead32(_oB_), _Rt_);
+       MTC2(&regs_->CP2, psxMemRead32(regs_, _oB_), _Rt_);
 }
 
 OP(gteLWC2_stall) {
@@ -1064,11 +1060,11 @@ OP(gteLWC2_stall) {
 OP(gteLWC2e_stall) {
        gteCheckStall(0);
        if (checkLD(regs_, _oB_, 3))
-               MTC2(&regs_->CP2, psxMemRead32(_oB_), _Rt_);
+               MTC2(&regs_->CP2, psxMemRead32(regs_, _oB_), _Rt_);
 }
 
 OP(gteSWC2) {
-       psxMemWrite32(_oB_, MFC2(&regs_->CP2, _Rt_));
+       psxMemWrite32(regs_, _oB_, MFC2(&regs_->CP2, _Rt_));
 }
 
 OP(gteSWC2_stall) {
@@ -1179,7 +1175,10 @@ static void intReset() {
        psxRegs.subCycle = 0;
 }
 
-static inline void execI_(u8 **memRLUT, psxRegisters *regs) {
+static inline void execI_(
+       u32 (INT_ATTR *fetch)(struct psxRegisters *r, const uintptr_t *luts, u32 pc),
+       const uintptr_t *memRLUT, psxRegisters *regs)
+{
        u32 pc = regs->pc;
 
        addCycle(regs);
@@ -1190,7 +1189,10 @@ static inline void execI_(u8 **memRLUT, psxRegisters *regs) {
        psxBSC[regs->code >> 26](regs, regs->code);
 }
 
-static inline void execIbp(u8 **memRLUT, psxRegisters *regs) {
+static inline void execIbp(
+       u32 (INT_ATTR *fetch)(struct psxRegisters *r, const uintptr_t *luts, u32 pc),
+       const uintptr_t *memRLUT, psxRegisters *regs)
+{
        u32 pc = regs->pc;
 
        addCycle(regs);
@@ -1205,33 +1207,41 @@ static inline void execIbp(u8 **memRLUT, psxRegisters *regs) {
 }
 
 static void intExecute(psxRegisters *regs) {
-       u8 **memRLUT = psxMemRLUT;
+       u32 (INT_ATTR *fetch)(struct psxRegisters *r, const uintptr_t *luts, u32 pc) =
+               regs->ptrs.intFetch;
+       const uintptr_t *memRLUT = regs->ptrs.memRLUT;
 
        while (!regs->stop)
-               execI_(memRLUT, regs);
+               execI_(fetch, memRLUT, regs);
 }
 
 static void intExecuteBp(psxRegisters *regs) {
-       u8 **memRLUT = psxMemRLUT;
+       u32 (INT_ATTR *fetch)(struct psxRegisters *r, const uintptr_t *luts, u32 pc) =
+               regs->ptrs.intFetch;
+       const uintptr_t *memRLUT = regs->ptrs.memRLUT;
 
        while (!regs->stop)
-               execIbp(memRLUT, regs);
+               execIbp(fetch, memRLUT, regs);
 }
 
 static void intExecuteBlock(psxRegisters *regs, enum blockExecCaller caller) {
-       u8 **memRLUT = psxMemRLUT;
+       u32 (INT_ATTR *fetch)(struct psxRegisters *r, const uintptr_t *luts, u32 pc) =
+               regs->ptrs.intFetch;
+       const uintptr_t *memRLUT = regs->ptrs.memRLUT;
 
        regs->branchSeen = 0;
        while (!regs->branchSeen)
-               execI_(memRLUT, regs);
+               execI_(fetch, memRLUT, regs);
 }
 
 static void intExecuteBlockBp(psxRegisters *regs, enum blockExecCaller caller) {
-       u8 **memRLUT = psxMemRLUT;
+       u32 (INT_ATTR *fetch)(struct psxRegisters *r, const uintptr_t *luts, u32 pc) =
+               regs->ptrs.intFetch;
+       const uintptr_t *memRLUT = regs->ptrs.memRLUT;
 
        regs->branchSeen = 0;
        while (!regs->branchSeen)
-               execIbp(memRLUT, regs);
+               execIbp(fetch, memRLUT, regs);
 }
 
 static void intClear(u32 Addr, u32 Size) {
@@ -1248,7 +1258,7 @@ static void intNotify(enum R3000Anote note, void *data) {
                setupCop(psxRegs.CP0.n.SR);
                // fallthrough
        case R3000ACPU_NOTIFY_CACHE_ISOLATED: // Armored Core?
-               if (fetch == fetchICache)
+               if (psxRegs.ptrs.intFetch == fetchICache)
                        memset(&ICache, 0xff, sizeof(ICache));
                break;
        case R3000ACPU_NOTIFY_CACHE_UNISOLATED:
@@ -1347,11 +1357,11 @@ void intApplyConfig() {
        // the dynarec may occasionally call the interpreter, in such a case the
        // cache won't work (cache only works right if all fetches go through it)
        if (!Config.icache_emulation || psxCpu != &psxInt) {
-               fetch = fetchNoCache;
+               psxRegs.ptrs.intFetch = fetchNoCache;
                memset(&ICache, 0xff, sizeof(ICache));
        }
        else
-               fetch = fetchICache;
+               psxRegs.ptrs.intFetch = fetchICache;
 
        cycle_mult = Config.cycle_multiplier_override && Config.cycle_multiplier == CYCLE_MULT_DEFAULT
                ? Config.cycle_multiplier_override : Config.cycle_multiplier;
@@ -1365,8 +1375,12 @@ static void intShutdown() {
 // single step (may do several ops in case of a branch or load delay)
 // called by asm/dynarec
 void execI(psxRegisters *regs) {
+       u32 (INT_ATTR *fetch)(struct psxRegisters *r, const uintptr_t *luts, u32 pc) =
+               regs->ptrs.intFetch;
+       const uintptr_t *memRLUT = regs->ptrs.memRLUT;
+
        do {
-               execIbp(psxMemRLUT, regs);
+               execIbp(fetch, memRLUT, regs);
        } while (regs->dloadReg[0] || regs->dloadReg[1]);
 }
 
index 9b783cb..76e555e 100644 (file)
@@ -24,6 +24,7 @@
 // TODO: Implement caches & cycle penalty.
 
 #include <stdio.h>
+#include <assert.h>
 #include "psxmem.h"
 #include "psxmem_map.h"
 #include "r3000a.h"
@@ -33,6 +34,7 @@
 
 #include "lightrec/mem.h"
 #include "memmap.h"
+#include "compiler_features.h"
 
 #ifdef USE_LIBRETRO_VFS
 #include <streams/file_stream_transforms.h>
@@ -130,14 +132,6 @@ void psxUnmap(void *ptr, size_t size, enum psxMapTag tag)
        psxUnmapHook(ptr, size, tag);
 }
 
-s8 *psxM = NULL; // Kernel & User Memory (2 Meg)
-s8 *psxP = NULL; // Parallel Port (64K)
-s8 *psxR = NULL; // BIOS ROM (512K)
-s8 *psxH = NULL; // Scratch Pad (1K) & Hardware Registers (8K)
-
-u8 **psxMemWLUT = NULL;
-u8 **psxMemRLUT = NULL;
-
 /*  Playstation Memory Map (from Playstation doc by Joshua Walker)
 0x0000_0000-0x0000_ffff                Kernel (64K)
 0x0001_0000-0x001f_ffff                User Memory (1.9 Meg)
@@ -159,44 +153,86 @@ u8 **psxMemRLUT = NULL;
 
 static int psxMemInitMap(void)
 {
-       psxM = psxMap(0x80000000, 0x00210000, 1, MAP_TAG_RAM);
-       if (psxM == MAP_FAILED)
-               psxM = psxMap(0x77000000, 0x00210000, 0, MAP_TAG_RAM);
-       if (psxM == MAP_FAILED) {
+       u8 *ptr;
+
+       ptr = psxMap(0x80000000, 0x00210000, 1, MAP_TAG_RAM);
+       if (ptr == MAP_FAILED)
+               ptr = psxMap(0x77000000, 0x00210000, 0, MAP_TAG_RAM);
+       if (ptr == MAP_FAILED) {
                SysMessage("mapping main RAM failed");
-               psxM = NULL;
                return -1;
        }
-       psxP = &psxM[0x200000];
+       psxRegs.ptrs.psxM = ptr;
+       psxRegs.ptrs.psxP = ptr + 0x200000;
 
-       psxH = psxMap(0x1f800000, 0x10000, 0, MAP_TAG_OTHER);
-       if (psxH == MAP_FAILED) {
+       ptr = psxMap(0x1f800000, 0x10000, 0, MAP_TAG_OTHER);
+       if (ptr == MAP_FAILED) {
                SysMessage("Error allocating psxH");
-               psxH = NULL;
                return -1;
        }
+       psxRegs.ptrs.psxH = ptr;
 
-       psxR = psxMap(0x1fc00000, 0x80000, 0, MAP_TAG_OTHER);
-       if (psxR == MAP_FAILED) {
+       ptr = psxMap(0x1fc00000, 0x80000, 0, MAP_TAG_OTHER);
+       if (ptr == MAP_FAILED) {
                SysMessage("Error allocating psxR");
-               psxR = NULL;
                return -1;
        }
+       psxRegs.ptrs.psxR = ptr;
 
        return 0;
 }
 
 static void psxMemFreeMap(void)
 {
-       if (psxM) psxUnmap(psxM, 0x00210000, MAP_TAG_RAM);
-       if (psxH) psxUnmap(psxH, 0x10000, MAP_TAG_OTHER);
-       if (psxR) psxUnmap(psxR, 0x80000, MAP_TAG_OTHER);
-       psxM = psxH = psxR = NULL;
-       psxP = NULL;
+       if (psxRegs.ptrs.psxM) psxUnmap(psxRegs.ptrs.psxM, 0x00210000, MAP_TAG_RAM);
+       if (psxRegs.ptrs.psxH) psxUnmap(psxRegs.ptrs.psxH, 0x10000, MAP_TAG_OTHER);
+       if (psxRegs.ptrs.psxR) psxUnmap(psxRegs.ptrs.psxR, 0x80000, MAP_TAG_OTHER);
+       psxRegs.ptrs.psxM = psxRegs.ptrs.psxH = psxRegs.ptrs.psxR = NULL;
+       psxRegs.ptrs.psxP = NULL;
+}
+
+static void lutMap(uintptr_t *lut, u8 *mem, u32 size, u32 start, u32 end)
+{
+       u32 i;
+       assert((size  & ((1u << PSXM_SHIFT) - 1)) == 0);
+       assert((start & ((1u << PSXM_SHIFT) - 1)) == 0);
+       assert((end   & ((1u << PSXM_SHIFT) - 1)) == 0);
+
+       for (i = start; i < end; i += (1u << PSXM_SHIFT))
+               lut[i >> PSXM_SHIFT] = (uintptr_t)mem - (i & ~(size - 1));
+}
+
+// shouldn't this affect reads, more mirrors?
+static void mapRam(int isMapped)
+{
+       //uintptr_t *rLUT = psxRegs.ptrs.memRLUT;
+       uintptr_t *wLUT = psxRegs.ptrs.memWLUT;
+
+       if (isMapped) {
+               u8 *ram = psxRegs.ptrs.psxM;
+               u32 i;
+               for (i = 0; i < 0x800000; i += 0x200000) {
+                       lutMap(wLUT, ram, 0x200000, 0x00000000u + i, 0x00200000u + i);
+                       lutMap(wLUT, ram, 0x200000, 0x80000000u + i, 0x80200000u + i);
+                       lutMap(wLUT, ram, 0x200000, 0xa0000000u + i, 0xa0200000u + i);
+               }
+       }
+       else {
+               size_t len = (0x200000 >> PSXM_SHIFT) * sizeof(wLUT[0]);
+               //memset(rLUT + (0x00000000 >> PSXM_SHIFT), INVALID_PTR_VAL, len);
+               //memset(rLUT + (0x80000000 >> PSXM_SHIFT), INVALID_PTR_VAL, len);
+               //memset(rLUT + (0xa0000000 >> PSXM_SHIFT), INVALID_PTR_VAL, len);
+               memset(wLUT + (0x00000000 >> PSXM_SHIFT), INVALID_PTR_VAL, len);
+               memset(wLUT + (0x80000000 >> PSXM_SHIFT), INVALID_PTR_VAL, len);
+               //memset(wLUT + (0xa0000000 >> PSXM_SHIFT), INVALID_PTR_VAL, len);
+       }
 }
 
 int psxMemInit(void)
 {
+       size_t table_size = 1ul << (32 - PSXM_SHIFT);
+       uintptr_t *memRLUT;
+       uintptr_t *memWLUT;
        unsigned int i;
        int ret;
 
@@ -214,44 +250,38 @@ int psxMemInit(void)
        if (DISABLE_MEM_LUTS)
                return 0;
 
-       psxMemRLUT = (u8 **)malloc(0x10000 * sizeof(void *));
-       psxMemWLUT = (u8 **)malloc(0x10000 * sizeof(void *));
-
-       if (psxMemRLUT == NULL || psxMemWLUT == NULL) {
+       memRLUT = malloc(table_size * sizeof(memRLUT[0]) * 2);
+       if (memRLUT == NULL) {
                SysMessage("Error allocating psxMem LUTs");
                psxMemShutdown();
                return -1;
        }
 
-       memset(psxMemRLUT, (int)(uintptr_t)INVALID_PTR, 0x10000 * sizeof(void *));
-       memset(psxMemWLUT, (int)(uintptr_t)INVALID_PTR, 0x10000 * sizeof(void *));
-
-// MemR
-       for (i = 0; i < 0x80; i++) psxMemRLUT[i + 0x0000] = (u8 *)&psxM[(i & 0x1f) << 16];
-
-       memcpy(psxMemRLUT + 0x8000, psxMemRLUT, 0x80 * sizeof(void *));
-       memcpy(psxMemRLUT + 0xa000, psxMemRLUT, 0x80 * sizeof(void *));
-
-       psxMemRLUT[0x1f00] = (u8 *)psxP;
-       psxMemRLUT[0x1f80] = (u8 *)psxH;
-
-       for (i = 0; i < 0x08; i++) psxMemRLUT[i + 0x1fc0] = (u8 *)&psxR[i << 16];
-
-       memcpy(psxMemRLUT + 0x9fc0, psxMemRLUT + 0x1fc0, 0x08 * sizeof(void *));
-       memcpy(psxMemRLUT + 0xbfc0, psxMemRLUT + 0x1fc0, 0x08 * sizeof(void *));
-
-// MemW
-       for (i = 0; i < 0x80; i++) psxMemWLUT[i + 0x0000] = (u8 *)&psxM[(i & 0x1f) << 16];
+       assert((s8)INVALID_PTR_VAL == INVALID_PTR_VAL);
+       memset(memRLUT, INVALID_PTR_VAL, table_size * sizeof(memRLUT[0]) * 2);
+       memWLUT = memRLUT + table_size;
+       psxRegs.ptrs.memRLUT = memRLUT;
+       psxRegs.ptrs.memWLUT = memWLUT;
+
+       // ram
+       for (i = 0; i < 0x800000; i += 0x200000) {
+               u8 *ram = psxRegs.ptrs.psxM;
+               lutMap(memRLUT, ram, 0x200000, 0x00000000u + i, 0x00200000u + i);
+               lutMap(memRLUT, ram, 0x200000, 0x80000000u + i, 0x80200000u + i);
+               lutMap(memRLUT, ram, 0x200000, 0xa0000000u + i, 0xa0200000u + i);
+       }
+       mapRam(1);
 
-       memcpy(psxMemWLUT + 0x8000, psxMemWLUT, 0x80 * sizeof(void *));
-       memcpy(psxMemWLUT + 0xa000, psxMemWLUT, 0x80 * sizeof(void *));
+       // bios
+       lutMap(memRLUT, psxRegs.ptrs.psxR, 0x80000, 0x1fc00000u, 0x1fc80000u);
+       lutMap(memRLUT, psxRegs.ptrs.psxR, 0x80000, 0x9fc00000u, 0x9fc80000u);
+       lutMap(memRLUT, psxRegs.ptrs.psxR, 0x80000, 0xbfc00000u, 0xbfc80000u);
 
        // Don't allow writes to PIO Expansion region (psxP) to take effect.
        // NOTE: Not sure if this is needed to fix any games but seems wise,
        //       seeing as some games do read from PIO as part of copy-protection
        //       check. (See fix in psxMemReset() regarding psxP region reads).
-       psxMemWLUT[0x1f00] = INVALID_PTR;
-       psxMemWLUT[0x1f80] = (u8 *)psxH;
+       //memWLUT[0x1f000000 >> PSXM_SHIFT] = INVALID_PTR_VAL;
 
        return 0;
 }
@@ -260,8 +290,11 @@ void psxMemReset() {
        FILE *f = NULL;
        char bios[1024];
 
-       memset(psxM, 0, 0x00200000);
-       memset(psxP, 0xff, 0x00010000);
+       memset(psxRegs.ptrs.psxM, 0, 0x00200000);
+       memset(psxRegs.ptrs.psxP, 0xff, 0x00010000);
+
+       if (!DISABLE_MEM_LUTS)
+               mapRam(1);
 
        Config.HLE = TRUE;
 
@@ -272,7 +305,7 @@ void psxMemReset() {
                if (f == NULL) {
                        SysMessage(_("Could not open BIOS:\"%s\". Enabling HLE Bios!\n"), bios);
                } else {
-                       if (fread(psxR, 1, 0x80000, f) == 0x80000) {
+                       if (fread(psxRegs.ptrs.psxR, 1, 0x80000, f) == 0x80000) {
                                Config.HLE = FALSE;
                        } else {
                                SysMessage(_("The selected BIOS:\"%s\" is of wrong size. Enabling HLE Bios!\n"), bios);
@@ -281,7 +314,7 @@ void psxMemReset() {
                }
        }
        if (Config.HLE)
-               memset(psxR, 0, 0x80000);
+               memset(psxRegs.ptrs.psxR, 0, 0x80000);
 }
 
 void psxMemShutdown() {
@@ -290,8 +323,9 @@ void psxMemShutdown() {
        else
                psxMemFreeMap();
 
-       free(psxMemRLUT); psxMemRLUT = NULL;
-       free(psxMemWLUT); psxMemWLUT = NULL;
+       free(psxRegs.ptrs.memRLUT);
+       psxRegs.ptrs.memRLUT = NULL;
+       psxRegs.ptrs.memWLUT = NULL;
 }
 
 int cache_isolated;
@@ -299,17 +333,7 @@ int cache_isolated;
 void psxMemOnIsolate(int enable)
 {
        if (!DISABLE_MEM_LUTS) {
-               if (enable) {
-                       memset(psxMemWLUT + 0x0000, (int)(uintptr_t)INVALID_PTR, 0x80 * sizeof(void *));
-                       memset(psxMemWLUT + 0x8000, (int)(uintptr_t)INVALID_PTR, 0x80 * sizeof(void *));
-                       //memset(psxMemWLUT + 0xa000, (int)(uintptr_t)INVALID_PTR, 0x80 * sizeof(void *));
-               } else {
-                       int i;
-                       for (i = 0; i < 0x80; i++)
-                               psxMemWLUT[i + 0x0000] = (void *)&psxM[(i & 0x1f) << 16];
-                       memcpy(psxMemWLUT + 0x8000, psxMemWLUT, 0x80 * sizeof(void *));
-                       memcpy(psxMemWLUT + 0xa000, psxMemWLUT, 0x80 * sizeof(void *));
-               }
+               mapRam(!enable);
        }
 
        cache_isolated = enable;
@@ -317,184 +341,129 @@ void psxMemOnIsolate(int enable)
                        : R3000ACPU_NOTIFY_CACHE_UNISOLATED, NULL);
 }
 
-u8 psxMemRead8(u32 mem) {
-       char *p;
+u8 psxMemRead8(psxRegisters *regs, u32 mem) {
+       u8 *p;
        u32 t;
 
+       if (likely(psxm_(&p, regs, mem, 0)))
+               return *p;
+
        t = mem >> 16;
        if (t == 0x1f80 || t == 0x9f80 || t == 0xbf80) {
                if ((mem & 0xffff) < 0x400)
-                       return psxHu8(mem);
+                       return regs->ptrs.psxH[mem & 0x3ff];
                else
                        return psxHwRead8(mem);
-       } else {
-               p = psxm(mem, 0);
-               if (p != INVALID_PTR) {
-                       if (Config.Debug)
-                               DebugCheckBP((mem & 0xffffff) | 0x80000000, R1);
-                       return *(u8 *)p;
-               } else {
-#ifdef PSXMEM_LOG
-                       PSXMEM_LOG("err lb %8.8lx\n", mem);
-#endif
-                       return 0xFF;
-               }
        }
+       return 0xFF;
 }
 
-u16 psxMemRead16(u32 mem) {
-       char *p;
+u16 psxMemRead16(psxRegisters *regs, u32 mem) {
+       u8 *p;
        u32 t;
 
+       if (likely(psxm_(&p, regs, mem, 0)))
+               return SWAPu16(*(u16 *)p);
+
        t = mem >> 16;
        if (t == 0x1f80 || t == 0x9f80 || t == 0xbf80) {
                if ((mem & 0xffff) < 0x400)
-                       return psxHu16(mem);
+                       return SWAPu16(*(u16 *)(regs->ptrs.psxH + (mem & 0x3fe)));
                else
                        return psxHwRead16(mem);
-       } else {
-               p = psxm(mem, 0);
-               if (p != INVALID_PTR) {
-                       if (Config.Debug)
-                               DebugCheckBP((mem & 0xffffff) | 0x80000000, R2);
-                       return SWAPu16(*(u16 *)p);
-               } else {
-#ifdef PSXMEM_LOG
-                       PSXMEM_LOG("err lh %8.8lx\n", mem);
-#endif
-                       return 0xFFFF;
-               }
        }
+       return 0xFFFF;
 }
 
-u32 psxMemRead32(u32 mem) {
-       char *p;
+u32 psxMemRead32(psxRegisters *regs, u32 mem) {
+       u8 *p;
        u32 t;
 
+       if (likely(psxm_(&p, regs, mem, 0)))
+               return SWAPu32(*(u32 *)p);
+
        t = mem >> 16;
        if (t == 0x1f80 || t == 0x9f80 || t == 0xbf80) {
                if ((mem & 0xffff) < 0x400)
-                       return psxHu32(mem);
+                       return SWAPu32(*(u32 *)(regs->ptrs.psxH + (mem & 0x3fc)));
                else
                        return psxHwRead32(mem);
-       } else {
-               p = psxm(mem, 0);
-               if (p != INVALID_PTR) {
-                       if (Config.Debug)
-                               DebugCheckBP((mem & 0xffffff) | 0x80000000, R4);
-                       return SWAPu32(*(u32 *)p);
-               } else {
-                       if (mem == 0xfffe0130)
-                               return psxRegs.biuReg;
-#ifdef PSXMEM_LOG
-                       PSXMEM_LOG("err lw %8.8lx\n", mem);
-#endif
-                       return 0xFFFFFFFF;
-               }
        }
+       if (mem == 0xfffe0130)
+               return regs->biuReg;
+       return 0xFFFFFFFF;
 }
 
-void psxMemWrite8(u32 mem, u32 value) {
-       char *p;
+void psxMemWrite8(psxRegisters *regs, u32 mem, u32 value) {
+       u8 *p;
        u32 t;
 
+       if (likely(psxm_(&p, regs, mem, 1))) {
+               *p = value;
+#ifndef DRC_DISABLE
+               psxCpu->Clear(mem & ~3, 1);
+#endif
+               return;
+       }
+
        t = mem >> 16;
        if (t == 0x1f80 || t == 0x9f80 || t == 0xbf80) {
                if ((mem & 0xffff) < 0x400)
-                       psxHu8(mem) = value;
+                       regs->ptrs.psxH[mem & 0x3ff] = value;
                else
                        psxHwWrite8(mem, value);
-       } else {
-               p = psxm(mem, 1);
-               if (p != INVALID_PTR) {
-                       if (Config.Debug)
-                               DebugCheckBP((mem & 0xffffff) | 0x80000000, W1);
-                       *(u8 *)p = value;
-#ifndef DRC_DISABLE
-                       psxCpu->Clear((mem & (~3)), 1);
-#endif
-               } else {
-#ifdef PSXMEM_LOG
-                       PSXMEM_LOG("err sb %8.8lx\n", mem);
-#endif
-               }
+               return;
        }
+       log_unhandled("unhandled w8  %08x %08x @%08x\n", mem, value, regs->pc);
 }
 
-void psxMemWrite16(u32 mem, u32 value) {
-       char *p;
+void psxMemWrite16(psxRegisters *regs, u32 mem, u32 value) {
+       u8 *p;
        u32 t;
 
+       if (likely(psxm_(&p, regs, mem, 1))) {
+               *(u16 *)p = SWAPu16(value);
+#ifndef DRC_DISABLE
+               psxCpu->Clear(mem & ~3, 1);
+#endif
+               return;
+       }
+
        t = mem >> 16;
        if (t == 0x1f80 || t == 0x9f80 || t == 0xbf80) {
                if ((mem & 0xffff) < 0x400)
-                       psxHu16ref(mem) = SWAPu16(value);
+                       *(u16 *)(regs->ptrs.psxH + (mem & 0x3fe)) = SWAPu16(value);
                else
                        psxHwWrite16(mem, value);
-       } else {
-               p = psxm(mem, 1);
-               if (p != INVALID_PTR) {
-                       if (Config.Debug)
-                               DebugCheckBP((mem & 0xffffff) | 0x80000000, W2);
-                       *(u16 *)p = SWAPu16(value);
-#ifndef DRC_DISABLE
-                       psxCpu->Clear((mem & (~3)), 1);
-#endif
-               } else {
-#ifdef PSXMEM_LOG
-                       PSXMEM_LOG("err sh %8.8lx\n", mem);
-#endif
-               }
+               return;
        }
+       log_unhandled("unhandled w16 %08x %08x @%08x\n", mem, value, regs->pc);
 }
 
-void psxMemWrite32(u32 mem, u32 value) {
-       char *p;
+void psxMemWrite32(psxRegisters *regs, u32 mem, u32 value) {
+       u8 *p;
        u32 t;
 
-//     if ((mem&0x1fffff) == 0x71E18 || value == 0x48088800) SysPrintf("t2fix!!\n");
-       t = mem >> 16;
-       if (t == 0x1f80 || t == 0x9f80 || t == 0xbf80) {
-               if ((mem & 0xffff) < 0x400)
-                       psxHu32ref(mem) = SWAPu32(value);
-               else
-                       psxHwWrite32(mem, value);
-       } else {
-               p = psxm(mem, 1);
-               if (p != INVALID_PTR) {
-                       if (Config.Debug)
-                               DebugCheckBP((mem & 0xffffff) | 0x80000000, W4);
-                       *(u32 *)p = SWAPu32(value);
+       if (likely(psxm_(&p, regs, mem, 1))) {
+               *(u32 *)p = SWAPu32(value);
 #ifndef DRC_DISABLE
-                       psxCpu->Clear(mem, 1);
+               psxCpu->Clear(mem & ~3, 1);
 #endif
-               } else {
-                       if (mem == 0xfffe0130) {
-                               psxRegs.biuReg = value;
-                               return;
-                       }
-#ifdef PSXMEM_LOG
-                       PSXMEM_LOG("err sw %8.8lx\n", mem);
-#endif
-               }
+               return;
        }
-}
-
-void *psxMemPointer(u32 mem) {
-       char *p;
-       u32 t;
 
        t = mem >> 16;
        if (t == 0x1f80 || t == 0x9f80 || t == 0xbf80) {
                if ((mem & 0xffff) < 0x400)
-                       return (void *)&psxH[mem];
+                       *(u32 *)(regs->ptrs.psxH + (mem & 0x3fc)) = SWAPu32(value);
                else
-                       return NULL;
-       } else {
-               p = psxm(mem, 1);
-               if (p != INVALID_PTR) {
-                       return (void *)p;
-               }
-               return NULL;
+                       psxHwWrite32(mem, value);
+               return;
+       }
+       if (mem == 0xfffe0130) {
+               regs->biuReg = value;
+               return;
        }
+       if (!(regs->CP0.n.SR & ((1u << 16))))
+               log_unhandled("unhandled w32 %08x %08x @%08x\n", mem, value, regs->pc);
 }
index f9cc8f0..5fb0e10 100644 (file)
@@ -25,6 +25,7 @@ extern "C" {
 #endif
 
 #include "psxcommon.h"
+#include "r3000a.h"
 
 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
 
@@ -46,87 +47,53 @@ extern "C" {
 
 #endif
 
+// this is needed because:
+// - lighrec sometimes maps ram at address 0
+// - memRLUT[] may contain 0 as a valid entry
+#define INVALID_PTR_VAL -1l
 #ifdef LIGHTREC
-#define INVALID_PTR ((void *)-1)
+#define INVALID_PTR ((void *)INVALID_PTR_VAL)
 #else
 #define INVALID_PTR NULL
 #endif
 
-extern s8 *psxM;
-#define psxMs8(mem)            psxM[(mem) & 0x1fffff]
-#define psxMs16(mem)   (SWAP16(*(s16 *)&psxM[(mem) & 0x1fffff]))
-#define psxMs32(mem)   (SWAP32(*(s32 *)&psxM[(mem) & 0x1fffff]))
-#define psxMu8(mem)            (*(u8 *)&psxM[(mem) & 0x1fffff])
-#define psxMu16(mem)   (SWAP16(*(u16 *)&psxM[(mem) & 0x1fffff]))
-#define psxMu32(mem)   (SWAP32(*(u32 *)&psxM[(mem) & 0x1fffff]))
-
-#define psxMs8ref(mem) psxM[(mem) & 0x1fffff]
-#define psxMs16ref(mem)        (*(s16 *)&psxM[(mem) & 0x1fffff])
-#define psxMs32ref(mem)        (*(s32 *)&psxM[(mem) & 0x1fffff])
-#define psxMu8ref(mem) (*(u8 *)&psxM[(mem) & 0x1fffff])
-#define psxMu16ref(mem)        (*(u16 *)&psxM[(mem) & 0x1fffff])
-#define psxMu32ref(mem)        (*(u32 *)&psxM[(mem) & 0x1fffff])
-
-extern s8 *psxP;
-#define psxPs8(mem)        psxP[(mem) & 0xffff]
-#define psxPs16(mem)   (SWAP16(*(s16 *)&psxP[(mem) & 0xffff]))
-#define psxPs32(mem)   (SWAP32(*(s32 *)&psxP[(mem) & 0xffff]))
-#define psxPu8(mem)            (*(u8 *)&psxP[(mem) & 0xffff])
-#define psxPu16(mem)   (SWAP16(*(u16 *)&psxP[(mem) & 0xffff]))
-#define psxPu32(mem)   (SWAP32(*(u32 *)&psxP[(mem) & 0xffff]))
-
-#define psxPs8ref(mem) psxP[(mem) & 0xffff]
-#define psxPs16ref(mem)        (*(s16 *)&psxP[(mem) & 0xffff])
-#define psxPs32ref(mem)        (*(s32 *)&psxP[(mem) & 0xffff])
-#define psxPu8ref(mem) (*(u8 *)&psxP[(mem) & 0xffff])
-#define psxPu16ref(mem)        (*(u16 *)&psxP[(mem) & 0xffff])
-#define psxPu32ref(mem)        (*(u32 *)&psxP[(mem) & 0xffff])
-
-extern s8 *psxR;
-#define psxRs8(mem)            psxR[(mem) & 0x7ffff]
-#define psxRs16(mem)   (SWAP16(*(s16 *)&psxR[(mem) & 0x7ffff]))
-#define psxRs32(mem)   (SWAP32(*(s32 *)&psxR[(mem) & 0x7ffff]))
-#define psxRu8(mem)            (*(u8* )&psxR[(mem) & 0x7ffff])
-#define psxRu16(mem)   (SWAP16(*(u16 *)&psxR[(mem) & 0x7ffff]))
-#define psxRu32(mem)   (SWAP32(*(u32 *)&psxR[(mem) & 0x7ffff]))
-
-#define psxRs8ref(mem) psxR[(mem) & 0x7ffff]
-#define psxRs16ref(mem)        (*(s16*)&psxR[(mem) & 0x7ffff])
-#define psxRs32ref(mem)        (*(s32*)&psxR[(mem) & 0x7ffff])
-#define psxRu8ref(mem) (*(u8 *)&psxR[(mem) & 0x7ffff])
-#define psxRu16ref(mem)        (*(u16*)&psxR[(mem) & 0x7ffff])
-#define psxRu32ref(mem)        (*(u32*)&psxR[(mem) & 0x7ffff])
-
-extern s8 *psxH;
-#define psxHs8(mem)            psxH[(mem) & 0xffff]
-#define psxHs16(mem)   (SWAP16(*(s16 *)&psxH[(mem) & 0xffff]))
-#define psxHs32(mem)   (SWAP32(*(s32 *)&psxH[(mem) & 0xffff]))
-#define psxHu8(mem)            (*(u8 *)&psxH[(mem) & 0xffff])
-#define psxHu16(mem)   (SWAP16(*(u16 *)&psxH[(mem) & 0xffff]))
-#define psxHu32(mem)   (SWAP32(*(u32 *)&psxH[(mem) & 0xffff]))
-
-#define psxHs8ref(mem) psxH[(mem) & 0xffff]
-#define psxHs16ref(mem)        (*(s16 *)&psxH[(mem) & 0xffff])
-#define psxHs32ref(mem)        (*(s32 *)&psxH[(mem) & 0xffff])
-#define psxHu8ref(mem) (*(u8 *)&psxH[(mem) & 0xffff])
-#define psxHu16ref(mem)        (*(u16 *)&psxH[(mem) & 0xffff])
-#define psxHu32ref(mem)        (*(u32 *)&psxH[(mem) & 0xffff])
-
-extern u8 **psxMemWLUT;
-extern u8 **psxMemRLUT;
+#define PSXM_SHIFT 19
+
+#define psxMu8(mem)            (*(u8 *)&psxRegs.ptrs.psxM[(mem) & 0x1fffff])
+#define psxMu16(mem)   (SWAP16(*(u16 *)&psxRegs.ptrs.psxM[(mem) & 0x1fffff]))
+#define psxMu32(mem)   (SWAP32(*(u32 *)&psxRegs.ptrs.psxM[(mem) & 0x1fffff]))
+
+#define psxMu8ref(mem) (*(u8  *)&psxRegs.ptrs.psxM[(mem) & 0x1fffff])
+#define psxMu16ref(mem)        (*(u16 *)&psxRegs.ptrs.psxM[(mem) & 0x1fffff])
+#define psxMu32ref(mem)        (*(u32 *)&psxRegs.ptrs.psxM[(mem) & 0x1fffff])
+
+#define psxHu8(mem)            (*(u8 *)&psxRegs.ptrs.psxH[(mem) & 0xffff])
+#define psxHu16(mem)   (SWAP16(*(u16 *)&psxRegs.ptrs.psxH[(mem) & 0xffff]))
+#define psxHu32(mem)   (SWAP32(*(u32 *)&psxRegs.ptrs.psxH[(mem) & 0xffff]))
+
+#define psxHu8ref(mem) (*(u8  *)&psxRegs.ptrs.psxH[(mem) & 0xffff])
+#define psxHu16ref(mem)        (*(u16 *)&psxRegs.ptrs.psxH[(mem) & 0xffff])
+#define psxHu32ref(mem)        (*(u32 *)&psxRegs.ptrs.psxH[(mem) & 0xffff])
+
 extern int cache_isolated;
 
 #ifndef DISABLE_MEM_LUTS
 #define DISABLE_MEM_LUTS 0
 #endif
 
-static inline void * psxm_lut(u32 mem, int write, u8 **lut)
+// it may seem returning the pointer would be convenient here,
+// but that causes double compare (after lut and after ptr arithmetic),
+// and this is a hot path for the interpreter and non-dynarec-allowing systems, like apple
+static inline int psxm_lut(u8 **ret, const psxRegisters *regs, u32 mem, int write,
+       const uintptr_t *lut)
 {
        if (!DISABLE_MEM_LUTS) {
-               void *ptr = lut[mem >> 16];
-
-               return ptr == INVALID_PTR ? INVALID_PTR
-                       : (void *)((uintptr_t)ptr + (u16)mem);
+               uintptr_t ptr = lut[mem >> PSXM_SHIFT];
+               if (ptr != INVALID_PTR_VAL) {
+                       *ret = (u8 *)(ptr + mem);
+                       return 1;
+               }
+               return 0;
        }
 
        if (mem >= 0xa0000000)
@@ -134,54 +101,56 @@ static inline void * psxm_lut(u32 mem, int write, u8 **lut)
        else
                mem &= ~0x80000000;
 
-       if (mem < 0x800000) {
-               if (cache_isolated)
-                       return INVALID_PTR;
+       if (mem < 0x800000u) {
+               if (write && cache_isolated)
+                       return 0;
 
-               return &psxM[mem & 0x1fffff];
+               *ret = regs->ptrs.psxM + (mem & 0x1fffff);
+               return 1;
        }
 
-       if (mem > 0x1f800000 && mem <= 0x1f810000)
-               return &psxH[mem - 0x1f800000];
-
-       if (!write) {
-               if (mem > 0x1fc00000 && mem <= 0x1fc80000)
-                       return &psxR[mem - 0x1fc00000];
-
-               if (mem > 0x1f000000 && mem <= 0x1f010000)
-                       return &psxP[mem - 0x1f000000];
+       if (!write && mem - 0x1fc00000u < 0x80000u) {
+               *ret = regs->ptrs.psxR + (mem - 0x1fc00000u);
+               return 1;
        }
 
-       return INVALID_PTR;
+       return 0;
+}
+
+static inline int psxm_(u8 **ret, const psxRegisters *regs, u32 mem, int write)
+{
+       return psxm_lut(ret, regs, mem, write,
+               write ? regs->ptrs.memWLUT : regs->ptrs.memRLUT);
 }
 
 static inline void * psxm(u32 mem, int write)
 {
-       return psxm_lut(mem, write, write ? psxMemWLUT : psxMemRLUT);
+       u8 *ret;
+       if (psxm_(&ret, &psxRegs, mem, write))
+               return ret;
+       return INVALID_PTR;
 }
 
 #define PSXM(mem) psxm(mem, 0)
-#define PSXMs8(mem)            (*(s8 *)PSXM(mem))
-#define PSXMs16(mem)   (SWAP16(*(s16 *)PSXM(mem)))
-#define PSXMs32(mem)   (SWAP32(*(s32 *)PSXM(mem)))
 #define PSXMu8(mem)            (*(u8 *)PSXM(mem))
 #define PSXMu16(mem)   (SWAP16(*(u16 *)PSXM(mem)))
 #define PSXMu32(mem)   (SWAP32(*(u32 *)PSXM(mem)))
 
 #define PSXMu32ref(mem)        (*(u32 *)PSXM(mem))
 
+struct psxRegisters;
+
 int psxMemInit();
 void psxMemReset();
 void psxMemOnIsolate(int enable);
 void psxMemShutdown();
 
-u8 psxMemRead8 (u32 mem);
-u16 psxMemRead16(u32 mem);
-u32 psxMemRead32(u32 mem);
-void psxMemWrite8 (u32 mem, u32 value);
-void psxMemWrite16(u32 mem, u32 value);
-void psxMemWrite32(u32 mem, u32 value);
-void *psxMemPointer(u32 mem);
+u8  psxMemRead8 (struct psxRegisters *regs, u32 mem);
+u16 psxMemRead16(struct psxRegisters *regs, u32 mem);
+u32 psxMemRead32(struct psxRegisters *regs, u32 mem);
+void psxMemWrite8 (struct psxRegisters *regs, u32 mem, u32 value);
+void psxMemWrite16(struct psxRegisters *regs, u32 mem, u32 value);
+void psxMemWrite32(struct psxRegisters *regs, u32 mem, u32 value);
 
 #ifdef __cplusplus
 }
index 3298b76..a25c01d 100644 (file)
@@ -29,6 +29,7 @@
 #include "psxbios.h"
 #include "psxevents.h"
 #include "../include/compiler_features.h"
+#include <stddef.h>
 #include <assert.h>
 
 #ifndef ARRAY_SIZE
@@ -64,7 +65,7 @@ void psxReset() {
 
        psxMemReset();
 
-       memset(&psxRegs, 0, sizeof(psxRegs));
+       memset(&psxRegs, 0, offsetof(psxRegisters, ptrs));
 
        psxRegs.pc = 0xbfc00000; // Start in bootstrap
 
index df7882c..1de1ebd 100644 (file)
@@ -26,6 +26,12 @@ extern "C" {
 
 #include "psxcommon.h"
 
+#ifdef __i386__
+#define INT_ATTR __attribute__((regparm(2)))
+#else
+#define INT_ATTR
+#endif
+
 enum R3000Aexception {
        R3000E_Int = 0,      // Interrupt
        R3000E_AdEL = 4,     // Address error (on load/I-fetch)
@@ -217,9 +223,20 @@ typedef struct psxRegisters {
        u32 biosBranchCheck;
        u32 cpuInRecursion;
        u32 gpuIdleAfter;
-       u32 unused3[2];
        // warning: changing anything in psxRegisters requires update of all
        // asm in libpcsxcore/new_dynarec/ and may break savestates
+       // ptrs must be last
+       struct {
+               u8 *psxM; // Kernel & User Memory (2 Meg)
+               u8 *psxP; // Parallel/Expansion Port (64K) (not used)
+               u8 *psxR; // BIOS ROM (512K)
+               u8 *psxH; // Scratch Pad (1K) & Hardware Registers (8K)
+               uintptr_t *memRLUT;
+               uintptr_t *memWLUT;
+               u32 (INT_ATTR *intFetch)(struct psxRegisters *regs_,
+                                        const uintptr_t *memRLUT, u32 pc);
+               void *unused3[3];
+       } ptrs;
 } psxRegisters;
 
 extern psxRegisters psxRegs;