Merge pull request #654 from pcercuei/lightrec-mmap-zero
authorLibretroAdmin <105389611+LibretroAdmin@users.noreply.github.com>
Mon, 30 May 2022 15:14:02 +0000 (16:14 +0100)
committerGitHub <noreply@github.com>
Mon, 30 May 2022 15:14:02 +0000 (16:14 +0100)
Lightrec: Make memory map as perfect as possible

13 files changed:
Makefile
Makefile.libretro
libpcsxcore/cdrom.c
libpcsxcore/lightrec/mem.c [new file with mode: 0644]
libpcsxcore/lightrec/mem.h [new file with mode: 0644]
libpcsxcore/lightrec/plugin.c
libpcsxcore/misc.c
libpcsxcore/psxbios.c
libpcsxcore/psxdma.c
libpcsxcore/psxinterpreter.c
libpcsxcore/psxmem.c
libpcsxcore/psxmem.h
libpcsxcore/r3000a.c

index 6a83f46..bff1a1c 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -47,6 +47,8 @@ ifdef PCNT
 CFLAGS += -DPCNT
 endif
 
+LIGHTREC_CUSTOM_MAP ?= 0
+
 # core
 OBJS += libpcsxcore/cdriso.o libpcsxcore/cdrom.o libpcsxcore/cheat.o libpcsxcore/database.o \
        libpcsxcore/decode_xa.o libpcsxcore/mdec.o \
@@ -89,7 +91,12 @@ libpcsxcore/psxbios.o: CFLAGS += -Wno-nonnull
 # dynarec
 ifeq "$(DYNAREC)" "lightrec"
 CFLAGS += -Ideps/lightning/include -Ideps/lightrec -Iinclude/lightning -Iinclude/lightrec \
-                 -DLIGHTREC -DLIGHTREC_STATIC
+                 -DLIGHTREC -DLIGHTREC_STATIC \
+                 -DLIGHTREC_CUSTOM_MAP=$(LIGHTREC_CUSTOM_MAP)
+LDLIBS += -lrt
+ifeq ($(LIGHTREC_CUSTOM_MAP),1)
+OBJS += libpcsxcore/lightrec/mem.o
+endif
 OBJS += libpcsxcore/lightrec/plugin.o
 OBJS += deps/lightning/lib/jit_disasm.o \
                deps/lightning/lib/jit_memory.o \
@@ -108,6 +115,7 @@ OBJS += deps/lightning/lib/jit_disasm.o \
                deps/lightrec/regcache.o \
                deps/lightrec/recompiler.o \
                deps/lightrec/reaper.o
+libpcsxcore/lightrec/mem.o: CFLAGS += -D_GNU_SOURCE
 ifeq ($(MMAP_WIN32),1)
 CFLAGS += -Iinclude/mman
 OBJS += deps/mman/mman.o
index dd89682..3edda64 100644 (file)
@@ -51,6 +51,9 @@ ifeq ($(platform), unix)
        TARGET := $(TARGET_NAME)_libretro.so
        fpic := -fPIC
        THREAD_RENDERING = 1
+ifeq ($(shell uname),Linux)
+       LIGHTREC_CUSTOM_MAP := 1
+endif
 ifneq ($(findstring SunOS,$(shell uname -s)),)
        CC = gcc
 endif
@@ -92,6 +95,7 @@ else ifeq ($(platform), linux-portable)
        LIBDL :=
        LIBM :=
        NO_UNDEF_CHECK = 1
+       LIGHTREC_CUSTOM_MAP := 1
 
 # OS X
 else ifeq ($(platform), osx)
index 1646d0e..6f4027c 100644 (file)
@@ -1491,7 +1491,7 @@ void psxDma3(u32 madr, u32 bcr, u32 chcr) {
 
 
                        ptr = (u8 *)PSXM(madr);
-                       if (ptr == NULL) {
+                       if (ptr == INVALID_PTR) {
                                CDR_LOG("psxDma3() Log: *** DMA 3 *** NULL Pointer!\n");
                                break;
                        }
diff --git a/libpcsxcore/lightrec/mem.c b/libpcsxcore/lightrec/mem.c
new file mode 100644 (file)
index 0000000..76608ea
--- /dev/null
@@ -0,0 +1,190 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+/*
+ * Copyright (C) 2022 Paul Cercueil <paul@crapouillou.net>
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <sys/shm.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "../psxhw.h"
+#include "../psxmem.h"
+#include "../r3000a.h"
+
+#include "mem.h"
+
+#define ARRAY_SIZE(a) (sizeof(a) ? (sizeof(a) / sizeof((a)[0])) : 0)
+
+#ifndef MAP_FIXED_NOREPLACE
+#define MAP_FIXED_NOREPLACE 0x100000
+#endif
+
+static const uintptr_t supported_io_bases[] = {
+       0x0,
+       0x10000000,
+       0x40000000,
+       0x80000000,
+};
+
+static void * mmap_huge(void *addr, size_t length, int prot, int flags,
+                       int fd, off_t offset)
+{
+       void *map = MAP_FAILED;
+
+       if (length >= 0x200000) {
+               map = mmap(addr, length, prot,
+                          flags | MAP_HUGETLB | (21 << MAP_HUGE_SHIFT),
+                          fd, offset);
+               if (map != MAP_FAILED)
+                       printf("Hugetlb mmap to address 0x%lx succeeded\n", (uintptr_t) addr);
+       }
+
+       if (map == MAP_FAILED) {
+               map = mmap(addr, length, prot, flags, fd, offset);
+               if (map != MAP_FAILED)
+                       printf("Regular mmap to address 0x%lx succeeded\n", (uintptr_t) addr);
+       }
+
+       return map;
+}
+
+static int lightrec_mmap_ram(bool hugetlb)
+{
+       unsigned int i, j;
+       int err, memfd, flags = 0;
+       uintptr_t base;
+       void *map;
+
+       if (hugetlb)
+               flags |= MFD_HUGETLB;
+
+       memfd = memfd_create("/lightrec_memfd", flags);
+       if (memfd < 0) {
+               err = -errno;
+               fprintf(stderr, "Failed to create memfd: %d\n", err);
+               return err;
+       }
+
+       err = ftruncate(memfd, 0x200000);
+       if (err < 0) {
+               err = -errno;
+               fprintf(stderr, "Could not trim memfd: %d\n", err);
+               goto err_close_memfd;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(supported_io_bases); i++) {
+               base = supported_io_bases[i];
+
+               for (j = 0; j < 4; j++) {
+                       map = mmap_huge((void *)(base + j * 0x200000),
+                                       0x200000, PROT_READ | PROT_WRITE,
+                                       MAP_SHARED | MAP_FIXED, memfd, 0);
+                       if (map == MAP_FAILED)
+                               break;
+               }
+
+               /* Impossible to map using this base */
+               if (j == 0)
+                       continue;
+
+               /* All mirrors mapped - we got a match! */
+               if (j == 4)
+                       break;
+
+               /* Only some mirrors mapped - clean the mess and try again */
+               for (; j > 0; j--)
+                       munmap((void *)(base + (j - 1) * 0x200000), 0x200000);
+       }
+
+       if (i == ARRAY_SIZE(supported_io_bases)) {
+               err = -EINVAL;
+               goto err_close_memfd;
+       }
+
+       err = 0;
+       psxM = (s8 *)base;
+
+err_close_memfd:
+       close(memfd);
+       return err;
+}
+
+int lightrec_init_mmap(void)
+{
+       unsigned int i;
+       uintptr_t base;
+       void *map;
+       int err;
+
+       err = lightrec_mmap_ram(true);
+       if (err) {
+               err = lightrec_mmap_ram(false);
+               if (err) {
+                       fprintf(stderr, "Unable to mmap RAM and mirrors\n");
+                       return err;
+               }
+       }
+
+       base = (uintptr_t) psxM;
+
+       map = mmap((void *)(base + 0x1f000000), 0x10000,
+                  PROT_READ | PROT_WRITE,
+                  MAP_PRIVATE | MAP_FIXED_NOREPLACE | MAP_ANONYMOUS, 0, 0);
+       if (map == MAP_FAILED) {
+               err = -EINVAL;
+               fprintf(stderr, "Unable to mmap parallel port\n");
+               goto err_unmap;
+       }
+
+       psxP = (s8 *)map;
+
+       map = mmap_huge((void *)(base + 0x1fc00000), 0x200000,
+                       PROT_READ | PROT_WRITE,
+                       MAP_PRIVATE | MAP_FIXED_NOREPLACE | MAP_ANONYMOUS, 0, 0);
+       if (map == MAP_FAILED) {
+               err = -EINVAL;
+               fprintf(stderr, "Unable to mmap BIOS\n");
+               goto err_unmap_parallel;
+       }
+
+       psxR = (s8 *)map;
+
+       map = mmap((void *)(base + 0x1f800000), 0x10000,
+                  PROT_READ | PROT_WRITE,
+                  MAP_PRIVATE | MAP_FIXED_NOREPLACE | MAP_ANONYMOUS, 0, 0);
+       if (map == MAP_FAILED) {
+               err = -EINVAL;
+               fprintf(stderr, "Unable to mmap scratchpad\n");
+               goto err_unmap_bios;
+       }
+
+       psxH = (s8 *)map;
+
+       return 0;
+
+err_unmap_bios:
+       munmap(psxR, 0x80000);
+err_unmap_parallel:
+       munmap(psxP, 0x10000);
+err_unmap:
+       for (i = 0; i < 4; i++)
+               munmap((void *)((uintptr_t)psxM + i * 0x200000), 0x200000);
+       return err;
+}
+
+void lightrec_free_mmap(void)
+{
+       unsigned int i;
+
+       munmap(psxH, 0x10000);
+       munmap(psxR, 0x80000);
+       munmap(psxP, 0x10000);
+       for (i = 0; i < 4; i++)
+               munmap((void *)((uintptr_t)psxM + i * 0x200000), 0x200000);
+}
diff --git a/libpcsxcore/lightrec/mem.h b/libpcsxcore/lightrec/mem.h
new file mode 100644 (file)
index 0000000..7f04ce5
--- /dev/null
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2022 Paul Cercueil <paul@crapouillou.net>
+ */
+
+#ifndef __LIGHTREC_MEM_H__
+#define __LIGHTREC_MEM_H__
+
+int lightrec_init_mmap(void);
+void lightrec_free_mmap(void);
+
+#endif /* __LIGHTREC_MEM_H__ */
index fe99e73..4b28c56 100644 (file)
@@ -311,6 +311,12 @@ static int lightrec_plugin_init(void)
        lightrec_map[PSX_MAP_SCRATCH_PAD].address = psxH;
        lightrec_map[PSX_MAP_PARALLEL_PORT].address = psxP;
 
+       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_debug = !!getenv("LIGHTREC_DEBUG");
        lightrec_very_debug = !!getenv("LIGHTREC_VERY_DEBUG");
        use_lightrec_interpreter = !!getenv("LIGHTREC_INTERPRETER");
index a07ab19..94fac61 100644 (file)
@@ -254,7 +254,7 @@ int LoadCdrom() {
                incTime();
                READTRACK();
 
-               if (ptr != NULL) memcpy(ptr, buf+12, 2048);
+               if (ptr != INVALID_PTR) memcpy(ptr, buf+12, 2048);
 
                tmpHead.t_size -= 2048;
                tmpHead.t_addr += 2048;
@@ -300,7 +300,7 @@ int LoadCdromFile(const char *filename, EXE_HEADER *head) {
                READTRACK();
 
                mem = PSXM(addr);
-               if (mem)
+               if (mem != INVALID_PTR)
                        memcpy(mem, buf + 12, 2048);
 
                size -= 2048;
@@ -489,7 +489,7 @@ int Load(const char *ExePath) {
                                section_address = SWAP32(tmpHead.t_addr);
                                section_size = SWAP32(tmpHead.t_size);
                                mem = PSXM(section_address);
-                               if (mem != NULL) {
+                               if (mem != INVALID_PTR) {
                                        fseek(tmpFile, 0x800, SEEK_SET);
                                        fread_to_ram(mem, section_size, 1, tmpFile);
                                        psxCpu->Clear(section_address, section_size / 4);
@@ -518,7 +518,7 @@ int Load(const char *ExePath) {
                                                        EMU_LOG("Loading %08X bytes from %08X to %08X\n", section_size, ftell(tmpFile), section_address);
 #endif
                                                        mem = PSXM(section_address);
-                                                       if (mem != NULL) {
+                                                       if (mem != INVALID_PTR) {
                                                                fread_to_ram(mem, section_size, 1, tmpFile);
                                                                psxCpu->Clear(section_address, section_size / 4);
                                                        }
index 373057d..5a8f71b 100644 (file)
@@ -373,7 +373,7 @@ void psxBios_getc(void) // 0x03, 0x35
 #endif
        v0 = -1;
 
-       if (pa1) {
+       if (pa1 != INVALID_PTR) {
                switch (a0) {
                        case 2: buread(pa1, 1, 1); break;
                        case 3: buread(pa1, 2, 1); break;
@@ -392,7 +392,7 @@ void psxBios_putc(void) // 0x09, 0x3B
        PSXBIOS_LOG("psxBios_%s\n", biosA0n[0x09]);
 #endif
        v0 = -1;
-       if (!pa1) {
+       if (pa1 == INVALID_PTR) {
                pc0 = ra;
                return;
        }
@@ -1261,7 +1261,7 @@ void psxBios_printf() { // 0x3f
        void *psp;
 
        psp = PSXM(sp);
-       if (psp) {
+       if (psp != INVALID_PTR) {
                memcpy(save, psp, 4 * 4);
                psxMu32ref(sp) = SWAP32((u32)a0);
                psxMu32ref(sp + 4) = SWAP32((u32)a1);
@@ -2112,7 +2112,7 @@ void psxBios_open() { // 0x32
 
        v0 = -1;
 
-       if (pa0) {
+       if (pa0 != INVALID_PTR) {
                if (!strncmp(pa0, "bu00", 4)) {
                        buopen(1, Mcd1Data, Config.Mcd1);
                }
@@ -2166,7 +2166,7 @@ void psxBios_read() { // 0x34
 
        v0 = -1;
 
-       if (pa1) {
+       if (pa1 != INVALID_PTR) {
                switch (a0) {
                        case 2: buread(pa1, 1, a2); break;
                        case 3: buread(pa1, 2, a2); break;
@@ -2189,7 +2189,7 @@ void psxBios_write() { // 0x35/0x03
 #endif
 
        v0 = -1;
-       if (!pa1) {
+       if (pa1 == INVALID_PTR) {
                pc0 = ra;
                return;
        }
@@ -2293,7 +2293,7 @@ void psxBios_firstfile() { // 42
 
        v0 = 0;
 
-       if (pa0) {
+       if (pa0 != INVALID_PTR) {
                strcpy(ffile, pa0);
                pfile = ffile+5;
                nfile = 0;
@@ -2371,7 +2371,7 @@ void psxBios_rename() { // 44
 
        v0 = 0;
 
-       if (pa0 && pa1) {
+       if (pa0 != INVALID_PTR && pa1 != INVALID_PTR) {
                if (!strncmp(pa0, "bu00", 4) && !strncmp(pa1, "bu00", 4)) {
                        burename(1);
                }
@@ -2413,7 +2413,7 @@ void psxBios_delete() { // 45
 
        v0 = 0;
 
-       if (pa0) {
+       if (pa0 != INVALID_PTR) {
                if (!strncmp(pa0, "bu00", 4)) {
                        budelete(1);
                }
@@ -2476,7 +2476,7 @@ void psxBios__card_write() { // 0x4e
        card_active_chan = a0;
        port = a0 >> 4;
 
-       if (pa2) {
+       if (pa2 != INVALID_PTR) {
                if (port == 0) {
                        memcpy(Mcd1Data + a1 * 128, pa2, 128);
                        SaveMcd(Config.Mcd1, Mcd1Data, a1 * 128, 128);
@@ -2512,7 +2512,7 @@ void psxBios__card_read() { // 0x4f
        card_active_chan = a0;
        port = a0 >> 4;
 
-       if (pa2) {
+       if (pa2 != INVALID_PTR) {
                if (port == 0) {
                        memcpy(pa2, Mcd1Data + a1 * 128, 128);
                } else {
index 03ee563..0480ce6 100644 (file)
@@ -45,7 +45,7 @@ void psxDma4(u32 madr, u32 bcr, u32 chcr) { // SPU
                        PSXDMA_LOG("*** DMA4 SPU - mem2spu *** %x addr = %x size = %x\n", chcr, madr, bcr);
 #endif
                        ptr = (u16 *)PSXM(madr);
-                       if (ptr == NULL) {
+                       if (ptr == INVALID_PTR) {
 #ifdef CPU_LOG
                                CPU_LOG("*** DMA4 SPU - mem2spu *** NULL Pointer!!!\n");
 #endif
@@ -62,7 +62,7 @@ void psxDma4(u32 madr, u32 bcr, u32 chcr) { // SPU
                        PSXDMA_LOG("*** DMA4 SPU - spu2mem *** %x addr = %x size = %x\n", chcr, madr, bcr);
 #endif
                        ptr = (u16 *)PSXM(madr);
-                       if (ptr == NULL) {
+                       if (ptr == INVALID_PTR) {
 #ifdef CPU_LOG
                                CPU_LOG("*** DMA4 SPU - spu2mem *** NULL Pointer!!!\n");
 #endif
@@ -138,7 +138,7 @@ void psxDma2(u32 madr, u32 bcr, u32 chcr) { // GPU
                        PSXDMA_LOG("*** DMA2 GPU - vram2mem *** %lx addr = %lx size = %lx\n", chcr, madr, bcr);
 #endif
                        ptr = (u32 *)PSXM(madr);
-                       if (ptr == NULL) {
+                       if (ptr == INVALID_PTR) {
 #ifdef CPU_LOG
                                CPU_LOG("*** DMA2 GPU - vram2mem *** NULL Pointer!!!\n");
 #endif
@@ -160,7 +160,7 @@ void psxDma2(u32 madr, u32 bcr, u32 chcr) { // GPU
                        PSXDMA_LOG("*** DMA 2 - GPU mem2vram *** %lx addr = %lx size = %lx\n", chcr, madr, bcr);
 #endif
                        ptr = (u32 *)PSXM(madr);
-                       if (ptr == NULL) {
+                       if (ptr == INVALID_PTR) {
 #ifdef CPU_LOG
                                CPU_LOG("*** DMA2 GPU - mem2vram *** NULL Pointer!!!\n");
 #endif
@@ -228,7 +228,7 @@ void psxDma6(u32 madr, u32 bcr, u32 chcr) {
 #endif
 
        if (chcr == 0x11000002) {
-               if (mem == NULL) {
+               if (mem == INVALID_PTR) {
 #ifdef CPU_LOG
                        CPU_LOG("*** DMA6 OT *** NULL Pointer!!!\n");
 #endif
index dd732b0..e6f1587 100644 (file)
@@ -60,7 +60,7 @@ void (*psxCP2BSC[32])();
 static u32 fetchNoCache(u32 pc)
 {
        u32 *code = (u32 *)PSXM(pc);
-       return ((code == NULL) ? 0 : SWAP32(*code));
+       return ((code == INVALID_PTR) ? 0 : SWAP32(*code));
 }
 
 /*
@@ -83,7 +83,7 @@ static u32 fetchICache(u32 pc)
                if (((entry->tag ^ pc) & 0xfffffff0) != 0 || pc < entry->tag)
                {
                        u32 *code = (u32 *)PSXM(pc & ~0x0f);
-                       if (!code)
+                       if (code == INVALID_PTR)
                                return 0;
 
                        entry->tag = pc;
index 6f85f82..1f7aa8c 100644 (file)
@@ -29,6 +29,7 @@
 #include "psxhw.h"
 #include "debug.h"
 
+#include "lightrec/mem.h"
 #include "memmap.h"
 
 #ifdef USE_LIBRETRO_VFS
@@ -63,7 +64,7 @@ retry:
        if (psxMapHook != NULL) {
                ret = psxMapHook(addr, size, 0, tag);
                if (ret == NULL)
-                       return NULL;
+                       return MAP_FAILED;
        }
        else {
                /* avoid MAP_FIXED, it overrides existing mappings.. */
@@ -73,7 +74,7 @@ retry:
                req = (void *)addr;
                ret = mmap(req, size, PROT_READ | PROT_WRITE, flags, -1, 0);
                if (ret == MAP_FAILED)
-                       return NULL;
+                       return ret;
        }
 
        if (addr != 0 && ret != (void *)addr) {
@@ -82,7 +83,7 @@ retry:
 
                if (is_fixed) {
                        psxUnmap(ret, size, tag);
-                       return NULL;
+                       return MAP_FAILED;
                }
 
                if (((addr ^ (unsigned long)ret) & ~0xff000000l) && try_ < 2)
@@ -139,18 +140,12 @@ u8 **psxMemRLUT = NULL;
 0xbfc0_0000-0xbfc7_ffff                BIOS Mirror (512K) Uncached
 */
 
-int psxMemInit() {
-       int i;
-
-       psxMemRLUT = (u8 **)malloc(0x10000 * sizeof(void *));
-       psxMemWLUT = (u8 **)malloc(0x10000 * sizeof(void *));
-       memset(psxMemRLUT, 0, 0x10000 * sizeof(void *));
-       memset(psxMemWLUT, 0, 0x10000 * sizeof(void *));
-
+static int psxMemInitMap(void)
+{
        psxM = psxMap(0x80000000, 0x00210000, 1, MAP_TAG_RAM);
-       if (psxM == NULL)
+       if (psxM == MAP_FAILED)
                psxM = psxMap(0x77000000, 0x00210000, 0, MAP_TAG_RAM);
-       if (psxM == NULL) {
+       if (psxM == MAP_FAILED) {
                SysMessage(_("mapping main RAM failed"));
                return -1;
        }
@@ -159,13 +154,49 @@ int psxMemInit() {
        psxH = psxMap(0x1f800000, 0x10000, 0, MAP_TAG_OTHER);
        psxR = psxMap(0x1fc00000, 0x80000, 0, MAP_TAG_OTHER);
 
-       if (psxMemRLUT == NULL || psxMemWLUT == NULL || 
-           psxR == NULL || psxP == NULL || psxH == NULL) {
+       if (psxR == MAP_FAILED || psxH == MAP_FAILED) {
                SysMessage(_("Error allocating memory!"));
                psxMemShutdown();
                return -1;
        }
 
+       return 0;
+}
+
+static void psxMemFreeMap(void)
+{
+       psxUnmap(psxM, 0x00210000, MAP_TAG_RAM); psxM = NULL;
+       psxUnmap(psxH, 0x10000, MAP_TAG_OTHER); psxH = NULL;
+       psxUnmap(psxR, 0x80000, MAP_TAG_OTHER); psxR = NULL;
+}
+
+int psxMemInit(void)
+{
+       unsigned int i;
+       int ret;
+
+       if (LIGHTREC_CUSTOM_MAP && Config.Cpu == CPU_DYNAREC)
+               ret = lightrec_init_mmap();
+       else
+               ret = psxMemInitMap();
+       if (ret) {
+               SysMessage(_("Error allocating memory!"));
+               psxMemShutdown();
+               return -1;
+       }
+
+       psxMemRLUT = (u8 **)malloc(0x10000 * sizeof(void *));
+       psxMemWLUT = (u8 **)malloc(0x10000 * sizeof(void *));
+
+       if (psxMemRLUT == NULL || psxMemWLUT == NULL) {
+               SysMessage(_("Error allocating memory!"));
+               psxMemShutdown();
+               return -1;
+       }
+
+       memset(psxMemRLUT, 0xff, 0x10000 * sizeof(void *));
+       memset(psxMemWLUT, 0xff, 0x10000 * sizeof(void *));
+
 // MemR
        for (i = 0; i < 0x80; i++) psxMemRLUT[i + 0x0000] = (u8 *)&psxM[(i & 0x1f) << 16];
 
@@ -190,7 +221,7 @@ int psxMemInit() {
        // 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] = NULL;
+       psxMemWLUT[0x1f00] = INVALID_PTR;
        psxMemWLUT[0x1f80] = (u8 *)psxH;
 
        return 0;
@@ -224,9 +255,10 @@ void psxMemReset() {
 }
 
 void psxMemShutdown() {
-       psxUnmap(psxM, 0x00210000, MAP_TAG_RAM); psxM = NULL;
-       psxUnmap(psxH, 0x10000, MAP_TAG_OTHER); psxH = NULL;
-       psxUnmap(psxR, 0x80000, MAP_TAG_OTHER); psxR = NULL;
+       if (LIGHTREC_CUSTOM_MAP && Config.Cpu == CPU_DYNAREC)
+               lightrec_free_mmap();
+       else
+               psxMemFreeMap();
 
        free(psxMemRLUT); psxMemRLUT = NULL;
        free(psxMemWLUT); psxMemWLUT = NULL;
@@ -244,7 +276,7 @@ u8 psxMemRead8(u32 mem) {
                        return psxHwRead8(mem);
        } else {
                p = (char *)(psxMemRLUT[t]);
-               if (p != NULL) {
+               if (p != INVALID_PTR) {
                        if (Config.Debug)
                                DebugCheckBP((mem & 0xffffff) | 0x80000000, R1);
                        return *(u8 *)(p + (mem & 0xffff));
@@ -269,7 +301,7 @@ u16 psxMemRead16(u32 mem) {
                        return psxHwRead16(mem);
        } else {
                p = (char *)(psxMemRLUT[t]);
-               if (p != NULL) {
+               if (p != INVALID_PTR) {
                        if (Config.Debug)
                                DebugCheckBP((mem & 0xffffff) | 0x80000000, R2);
                        return SWAPu16(*(u16 *)(p + (mem & 0xffff)));
@@ -294,7 +326,7 @@ u32 psxMemRead32(u32 mem) {
                        return psxHwRead32(mem);
        } else {
                p = (char *)(psxMemRLUT[t]);
-               if (p != NULL) {
+               if (p != INVALID_PTR) {
                        if (Config.Debug)
                                DebugCheckBP((mem & 0xffffff) | 0x80000000, R4);
                        return SWAPu32(*(u32 *)(p + (mem & 0xffff)));
@@ -319,7 +351,7 @@ void psxMemWrite8(u32 mem, u8 value) {
                        psxHwWrite8(mem, value);
        } else {
                p = (char *)(psxMemWLUT[t]);
-               if (p != NULL) {
+               if (p != INVALID_PTR) {
                        if (Config.Debug)
                                DebugCheckBP((mem & 0xffffff) | 0x80000000, W1);
                        *(u8 *)(p + (mem & 0xffff)) = value;
@@ -346,7 +378,7 @@ void psxMemWrite16(u32 mem, u16 value) {
                        psxHwWrite16(mem, value);
        } else {
                p = (char *)(psxMemWLUT[t]);
-               if (p != NULL) {
+               if (p != INVALID_PTR) {
                        if (Config.Debug)
                                DebugCheckBP((mem & 0xffffff) | 0x80000000, W2);
                        *(u16 *)(p + (mem & 0xffff)) = SWAPu16(value);
@@ -374,7 +406,7 @@ void psxMemWrite32(u32 mem, u32 value) {
                        psxHwWrite32(mem, value);
        } else {
                p = (char *)(psxMemWLUT[t]);
-               if (p != NULL) {
+               if (p != INVALID_PTR) {
                        if (Config.Debug)
                                DebugCheckBP((mem & 0xffffff) | 0x80000000, W4);
                        *(u32 *)(p + (mem & 0xffff)) = SWAPu32(value);
@@ -398,9 +430,9 @@ void psxMemWrite32(u32 mem, u32 value) {
                                        case 0x800: case 0x804:
                                                if (writeok == 0) break;
                                                writeok = 0;
-                                               memset(psxMemWLUT + 0x0000, 0, 0x80 * sizeof(void *));
-                                               memset(psxMemWLUT + 0x8000, 0, 0x80 * sizeof(void *));
-                                               memset(psxMemWLUT + 0xa000, 0, 0x80 * sizeof(void *));
+                                               memset(psxMemWLUT + 0x0000, 0xff, 0x80 * sizeof(void *));
+                                               memset(psxMemWLUT + 0x8000, 0xff, 0x80 * sizeof(void *));
+                                               memset(psxMemWLUT + 0xa000, 0xff, 0x80 * sizeof(void *));
                                                /* Required for icache interpreter otherwise Armored Core won't boot on icache interpreter */
                                                psxCpu->Notify(R3000ACPU_NOTIFY_CACHE_ISOLATED, NULL);
                                                break;
@@ -436,7 +468,7 @@ void *psxMemPointer(u32 mem) {
                        return NULL;
        } else {
                p = (char *)(psxMemWLUT[t]);
-               if (p != NULL) {
+               if (p != INVALID_PTR) {
                        return (void *)(p + (mem & 0xffff));
                }
                return NULL;
index fbf5f67..a69b4a3 100644 (file)
@@ -49,6 +49,8 @@ extern "C" {
 
 #endif
 
+#define INVALID_PTR ((void *)-1)
+
 extern s8 *psxM;
 #define psxMs8(mem)            psxM[(mem) & 0x1fffff]
 #define psxMs16(mem)   (SWAP16(*(s16 *)&psxM[(mem) & 0x1fffff]))
@@ -112,7 +114,7 @@ extern s8 *psxH;
 extern u8 **psxMemWLUT;
 extern u8 **psxMemRLUT;
 
-#define PSXM(mem)              (psxMemRLUT[(mem) >> 16] == 0 ? NULL : (u8*)(psxMemRLUT[(mem) >> 16] + ((mem) & 0xffff)))
+#define PSXM(mem)              (psxMemRLUT[(mem) >> 16] == INVALID_PTR ? INVALID_PTR : (u8*)(psxMemRLUT[(mem) >> 16] + ((mem) & 0xffff)))
 #define PSXMs8(mem)            (*(s8 *)PSXM(mem))
 #define PSXMs16(mem)   (SWAP16(*(s16 *)PSXM(mem)))
 #define PSXMs32(mem)   (SWAP32(*(s32 *)PSXM(mem)))
index 3a7c358..57ae830 100644 (file)
@@ -76,10 +76,11 @@ void psxReset() {
 }
 
 void psxShutdown() {
-       psxMemShutdown();
        psxBiosShutdown();
 
        psxCpu->Shutdown();
+
+       psxMemShutdown();
 }
 
 void psxException(u32 code, u32 bd) {