From 6d760c926db017bea75bdd95cfa8acc3cc060ab8 Mon Sep 17 00:00:00 2001 From: notaz Date: Sat, 6 Dec 2014 18:26:16 +0200 Subject: psxmem: remove hard requirement for a mapping not all platforms have 1f800000 free not all mmap implementations use the addr hint.. --- libpcsxcore/new_dynarec/assem_arm.c | 14 ++++++++++---- libpcsxcore/psxmem.c | 4 ++-- 2 files changed, 12 insertions(+), 6 deletions(-) (limited to 'libpcsxcore') diff --git a/libpcsxcore/new_dynarec/assem_arm.c b/libpcsxcore/new_dynarec/assem_arm.c index 45edd65..9ee832e 100644 --- a/libpcsxcore/new_dynarec/assem_arm.c +++ b/libpcsxcore/new_dynarec/assem_arm.c @@ -3999,10 +3999,16 @@ static int emit_fastpath_cmp_jump(int i,int addr,int *addr_reg_override) type=0; } else if(type==MTYPE_1F80) { // scratchpad - emit_addimm(addr,-0x1f800000,HOST_TEMPREG); - emit_cmpimm(HOST_TEMPREG,0x1000); - jaddr=(int)out; - emit_jc(0); + if (psxH == (void *)0x1f800000) { + emit_addimm(addr,-0x1f800000,HOST_TEMPREG); + emit_cmpimm(HOST_TEMPREG,0x1000); + jaddr=(int)out; + emit_jc(0); + } + else { + // do usual RAM check, jump will go to the right handler + type=0; + } } #endif diff --git a/libpcsxcore/psxmem.c b/libpcsxcore/psxmem.c index 2ca5dd5..7001744 100644 --- a/libpcsxcore/psxmem.c +++ b/libpcsxcore/psxmem.c @@ -150,11 +150,11 @@ int psxMemInit() { } psxP = &psxM[0x200000]; - psxH = psxMap(0x1f800000, 0x10000, 1, MAP_TAG_OTHER); + 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 != (void *)0x1f800000) { + psxR == NULL || psxP == NULL || psxH == NULL) { SysMessage(_("Error allocating memory!")); psxMemShutdown(); return -1; -- cgit v1.2.3 From 5be6eaeb510c62ded1d5a3bd29dc94f25bc1359e Mon Sep 17 00:00:00 2001 From: notaz Date: Sat, 6 Dec 2014 19:14:34 +0200 Subject: misc: don't succeed on trash input --- libpcsxcore/misc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'libpcsxcore') diff --git a/libpcsxcore/misc.c b/libpcsxcore/misc.c index 874624d..905f142 100644 --- a/libpcsxcore/misc.c +++ b/libpcsxcore/misc.c @@ -109,6 +109,7 @@ void mmssdd( char *b, char *p ) int GetCdromFile(u8 *mdir, u8 *time, char *filename) { struct iso_directory_record *dir; + int retval = -1; u8 ddir[4096]; u8 *buf; int i; @@ -138,11 +139,12 @@ int GetCdromFile(u8 *mdir, u8 *time, char *filename) { } else { if (!strnicmp((char *)&dir->name[0], filename, strlen(filename))) { mmssdd(dir->extent, (char *)time); + retval = 0; break; } } } - return 0; + return retval; } static const unsigned int gpu_ctl_def[] = { -- cgit v1.2.3 From 1c2c2bfb00e4040a17f61e7aa2061d446ba44b76 Mon Sep 17 00:00:00 2001 From: notaz Date: Sat, 6 Dec 2014 22:52:05 +0200 Subject: misc: length is unsigned --- libpcsxcore/misc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libpcsxcore') diff --git a/libpcsxcore/misc.c b/libpcsxcore/misc.c index 905f142..a27f60f 100644 --- a/libpcsxcore/misc.c +++ b/libpcsxcore/misc.c @@ -123,7 +123,7 @@ int GetCdromFile(u8 *mdir, u8 *time, char *filename) { if (dir->length[0] == 0) { return -1; } - i += dir->length[0]; + i += (u8)dir->length[0]; if (dir->flags[0] & 0x2) { // it's a dir if (!strnicmp((char *)&dir->name[0], filename, dir->name_len[0])) { -- cgit v1.2.3 From b1ba08510c208685fda8a0a2d0e2b72d98db23b1 Mon Sep 17 00:00:00 2001 From: notaz Date: Tue, 9 Dec 2014 23:36:05 +0200 Subject: psxinterpreter: don't break strict aliasing rules --- libpcsxcore/psxinterpreter.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'libpcsxcore') diff --git a/libpcsxcore/psxinterpreter.c b/libpcsxcore/psxinterpreter.c index ff49491..cf3de79 100644 --- a/libpcsxcore/psxinterpreter.c +++ b/libpcsxcore/psxinterpreter.c @@ -727,9 +727,9 @@ void psxLWR() { */ } -void psxSB() { psxMemWrite8 (_oB_, _u8 (_rRt_)); } -void psxSH() { psxMemWrite16(_oB_, _u16(_rRt_)); } -void psxSW() { psxMemWrite32(_oB_, _u32(_rRt_)); } +void psxSB() { psxMemWrite8 (_oB_, _rRt_ & 0xff); } +void psxSH() { psxMemWrite16(_oB_, _rRt_ & 0xffff); } +void psxSW() { psxMemWrite32(_oB_, _rRt_); } u32 SWL_MASK[4] = { 0xffffff00, 0xffff0000, 0xff000000, 0 }; u32 SWL_SHIFT[4] = { 24, 16, 8, 0 }; -- cgit v1.2.3 From 2b30c1291db9d9801d51cf85f71f40fe54958898 Mon Sep 17 00:00:00 2001 From: notaz Date: Thu, 18 Dec 2014 03:56:01 +0200 Subject: spu: add a schedule callback --- libpcsxcore/new_dynarec/emu_if.c | 1 + libpcsxcore/plugins.c | 3 +++ libpcsxcore/plugins.h | 2 ++ libpcsxcore/r3000a.c | 6 ++++++ libpcsxcore/r3000a.h | 1 + libpcsxcore/spu.c | 12 ++++++++++++ libpcsxcore/spu.h | 2 ++ 7 files changed, 27 insertions(+) (limited to 'libpcsxcore') diff --git a/libpcsxcore/new_dynarec/emu_if.c b/libpcsxcore/new_dynarec/emu_if.c index cb95cb1..89e2bd6 100644 --- a/libpcsxcore/new_dynarec/emu_if.c +++ b/libpcsxcore/new_dynarec/emu_if.c @@ -60,6 +60,7 @@ static irq_func * const irq_funcs[] = { [PSXINT_CDRDMA] = cdrDmaInterrupt, [PSXINT_CDRLID] = cdrLidSeekInterrupt, [PSXINT_CDRPLAY] = cdrPlayInterrupt, + [PSXINT_SPU_UPDATE] = spuUpdate, [PSXINT_RCNT] = psxRcntUpdate, }; diff --git a/libpcsxcore/plugins.c b/libpcsxcore/plugins.c index 57078ba..e6d8a11 100644 --- a/libpcsxcore/plugins.c +++ b/libpcsxcore/plugins.c @@ -88,6 +88,7 @@ SPUreadDMAMem SPU_readDMAMem; SPUplayADPCMchannel SPU_playADPCMchannel; SPUfreeze SPU_freeze; SPUregisterCallback SPU_registerCallback; +SPUregisterScheduleCb SPU_registerScheduleCb; SPUasync SPU_async; SPUplayCDDAchannel SPU_playCDDAchannel; @@ -320,6 +321,7 @@ void *hSPUDriver = NULL; long CALLBACK SPU__configure(void) { return 0; } void CALLBACK SPU__about(void) {} long CALLBACK SPU__test(void) { return 0; } +void CALLBACK SPU__registerScheduleCb(void (CALLBACK *cb)(unsigned int)) {} #define LoadSpuSym1(dest, name) \ LoadSym(SPU_##dest, SPU##dest, name, TRUE); @@ -356,6 +358,7 @@ static int LoadSPUplugin(const char *SPUdll) { LoadSpuSym1(playADPCMchannel, "SPUplayADPCMchannel"); LoadSpuSym1(freeze, "SPUfreeze"); LoadSpuSym1(registerCallback, "SPUregisterCallback"); + LoadSpuSym0(registerScheduleCb, "SPUregisterScheduleCb"); LoadSpuSymN(async, "SPUasync"); LoadSpuSymN(playCDDAchannel, "SPUplayCDDAchannel"); diff --git a/libpcsxcore/plugins.h b/libpcsxcore/plugins.h index dfa8722..9df55bf 100644 --- a/libpcsxcore/plugins.h +++ b/libpcsxcore/plugins.h @@ -192,6 +192,7 @@ typedef void (CALLBACK* SPUwriteDMAMem)(unsigned short *, int); typedef void (CALLBACK* SPUreadDMAMem)(unsigned short *, int); typedef void (CALLBACK* SPUplayADPCMchannel)(xa_decode_t *); typedef void (CALLBACK* SPUregisterCallback)(void (CALLBACK *callback)(void)); +typedef void (CALLBACK* SPUregisterScheduleCb)(void (CALLBACK *callback)(unsigned int cycles_after)); typedef long (CALLBACK* SPUconfigure)(void); typedef long (CALLBACK* SPUtest)(void); typedef void (CALLBACK* SPUabout)(void); @@ -226,6 +227,7 @@ extern SPUreadDMAMem SPU_readDMAMem; extern SPUplayADPCMchannel SPU_playADPCMchannel; extern SPUfreeze SPU_freeze; extern SPUregisterCallback SPU_registerCallback; +extern SPUregisterScheduleCb SPU_registerScheduleCb; extern SPUasync SPU_async; extern SPUplayCDDAchannel SPU_playCDDAchannel; diff --git a/libpcsxcore/r3000a.c b/libpcsxcore/r3000a.c index f5996ac..82eb885 100644 --- a/libpcsxcore/r3000a.c +++ b/libpcsxcore/r3000a.c @@ -185,6 +185,12 @@ void psxBranchTest() { cdrLidSeekInterrupt(); } } + if (psxRegs.interrupt & (1 << PSXINT_SPU_UPDATE)) { // scheduled spu update + if ((psxRegs.cycle - psxRegs.intCycle[PSXINT_SPU_UPDATE].sCycle) >= psxRegs.intCycle[PSXINT_SPU_UPDATE].cycle) { + psxRegs.interrupt &= ~(1 << PSXINT_SPU_UPDATE); + spuUpdate(); + } + } } if (psxHu32(0x1070) & psxHu32(0x1074)) { diff --git a/libpcsxcore/r3000a.h b/libpcsxcore/r3000a.h index 13aaa59..a6a6254 100644 --- a/libpcsxcore/r3000a.h +++ b/libpcsxcore/r3000a.h @@ -160,6 +160,7 @@ enum { PSXINT_RCNT, PSXINT_CDRLID, PSXINT_CDRPLAY, + PSXINT_SPU_UPDATE, PSXINT_COUNT }; diff --git a/libpcsxcore/spu.c b/libpcsxcore/spu.c index a60c047..f23051e 100644 --- a/libpcsxcore/spu.c +++ b/libpcsxcore/spu.c @@ -26,3 +26,15 @@ void CALLBACK SPUirq(void) { psxHu32ref(0x1070) |= SWAPu32(0x200); } + +// spuUpdate +void CALLBACK SPUschedule(unsigned int cycles_after) { + psxRegs.interrupt |= (1 << PSXINT_SPU_UPDATE); + psxRegs.intCycle[PSXINT_SPU_UPDATE].cycle = cycles_after; + psxRegs.intCycle[PSXINT_SPU_UPDATE].sCycle = psxRegs.cycle; + new_dyna_set_event(PSXINT_SPU_UPDATE, cycles_after); +} + +void spuUpdate() { + SPU_async(psxRegs.cycle); +} diff --git a/libpcsxcore/spu.h b/libpcsxcore/spu.h index 85010cb..44a35d5 100644 --- a/libpcsxcore/spu.h +++ b/libpcsxcore/spu.h @@ -40,6 +40,8 @@ extern "C" { #define H_SPUoff2 0x0d8e void CALLBACK SPUirq(void); +void CALLBACK SPUschedule(unsigned int cycles_after); +void spuUpdate(); #ifdef __cplusplus } -- cgit v1.2.3 From 650adfd2da779ba8855623362c2900583e22931e Mon Sep 17 00:00:00 2001 From: notaz Date: Thu, 18 Dec 2014 23:43:08 +0200 Subject: spu: rework synchronization --- libpcsxcore/misc.c | 6 +++--- libpcsxcore/new_dynarec/pcsxmem.c | 6 +++--- libpcsxcore/plugins.h | 10 +++++----- libpcsxcore/psxcounters.c | 2 +- libpcsxcore/psxdma.c | 4 ++-- libpcsxcore/psxhw.c | 6 +++--- libpcsxcore/spu.c | 2 +- 7 files changed, 18 insertions(+), 18 deletions(-) (limited to 'libpcsxcore') diff --git a/libpcsxcore/misc.c b/libpcsxcore/misc.c index a27f60f..917a567 100644 --- a/libpcsxcore/misc.c +++ b/libpcsxcore/misc.c @@ -601,11 +601,11 @@ int SaveState(const char *file) { // spu spufP = (SPUFreeze_t *) malloc(16); - SPU_freeze(2, spufP); + SPU_freeze(2, spufP, psxRegs.cycle); Size = spufP->Size; SaveFuncs.write(f, &Size, 4); free(spufP); spufP = (SPUFreeze_t *) malloc(Size); - SPU_freeze(1, spufP); + SPU_freeze(1, spufP, psxRegs.cycle); SaveFuncs.write(f, spufP, Size); free(spufP); @@ -670,7 +670,7 @@ int LoadState(const char *file) { SaveFuncs.read(f, &Size, 4); spufP = (SPUFreeze_t *)malloc(Size); SaveFuncs.read(f, spufP, Size); - SPU_freeze(0, spufP); + SPU_freeze(0, spufP, psxRegs.cycle); free(spufP); sioFreeze(f, 0); diff --git a/libpcsxcore/new_dynarec/pcsxmem.c b/libpcsxcore/new_dynarec/pcsxmem.c index 0a75442..d5c32be 100644 --- a/libpcsxcore/new_dynarec/pcsxmem.c +++ b/libpcsxcore/new_dynarec/pcsxmem.c @@ -210,7 +210,7 @@ make_dma_func(6) static void io_spu_write16(u32 value) { // meh - SPU_writeRegister(address, value); + SPU_writeRegister(address, value, psxRegs.cycle); } static void io_spu_write32(u32 value) @@ -218,8 +218,8 @@ static void io_spu_write32(u32 value) SPUwriteRegister wfunc = SPU_writeRegister; u32 a = address; - wfunc(a, value & 0xffff); - wfunc(a + 2, value >> 16); + wfunc(a, value & 0xffff, psxRegs.cycle); + wfunc(a + 2, value >> 16, psxRegs.cycle); } static u32 io_gpu_read_status(void) diff --git a/libpcsxcore/plugins.h b/libpcsxcore/plugins.h index 9df55bf..e6ac694 100644 --- a/libpcsxcore/plugins.h +++ b/libpcsxcore/plugins.h @@ -184,12 +184,12 @@ typedef long (CALLBACK* SPUinit)(void); typedef long (CALLBACK* SPUshutdown)(void); typedef long (CALLBACK* SPUclose)(void); typedef void (CALLBACK* SPUplaySample)(unsigned char); -typedef void (CALLBACK* SPUwriteRegister)(unsigned long, unsigned short); +typedef void (CALLBACK* SPUwriteRegister)(unsigned long, unsigned short, unsigned int); typedef unsigned short (CALLBACK* SPUreadRegister)(unsigned long); typedef void (CALLBACK* SPUwriteDMA)(unsigned short); typedef unsigned short (CALLBACK* SPUreadDMA)(void); -typedef void (CALLBACK* SPUwriteDMAMem)(unsigned short *, int); -typedef void (CALLBACK* SPUreadDMAMem)(unsigned short *, int); +typedef void (CALLBACK* SPUwriteDMAMem)(unsigned short *, int, unsigned int); +typedef void (CALLBACK* SPUreadDMAMem)(unsigned short *, int, unsigned int); typedef void (CALLBACK* SPUplayADPCMchannel)(xa_decode_t *); typedef void (CALLBACK* SPUregisterCallback)(void (CALLBACK *callback)(void)); typedef void (CALLBACK* SPUregisterScheduleCb)(void (CALLBACK *callback)(unsigned int cycles_after)); @@ -205,8 +205,8 @@ typedef struct { xa_decode_t xa; unsigned char *SPUInfo; } SPUFreeze_t; -typedef long (CALLBACK* SPUfreeze)(uint32_t, SPUFreeze_t *); -typedef void (CALLBACK* SPUasync)(uint32_t); +typedef long (CALLBACK* SPUfreeze)(uint32_t, SPUFreeze_t *, uint32_t); +typedef void (CALLBACK* SPUasync)(uint32_t, uint32_t); typedef int (CALLBACK* SPUplayCDDAchannel)(short *, int); // SPU function pointers diff --git a/libpcsxcore/psxcounters.c b/libpcsxcore/psxcounters.c index 50f1792..b25674c 100644 --- a/libpcsxcore/psxcounters.c +++ b/libpcsxcore/psxcounters.c @@ -335,7 +335,7 @@ void psxRcntUpdate() if( SPU_async ) { - SPU_async( SpuUpdInterval[Config.PsxType] * rcnts[3].target ); + SPU_async( cycle, 1 ); } } diff --git a/libpcsxcore/psxdma.c b/libpcsxcore/psxdma.c index 63c2724..ff7d6a3 100644 --- a/libpcsxcore/psxdma.c +++ b/libpcsxcore/psxdma.c @@ -51,7 +51,7 @@ void psxDma4(u32 madr, u32 bcr, u32 chcr) { // SPU #endif break; } - SPU_writeDMAMem(ptr, (bcr >> 16) * (bcr & 0xffff) * 2); + SPU_writeDMAMem(ptr, (bcr >> 16) * (bcr & 0xffff) * 2, psxRegs.cycle); SPUDMA_INT((bcr >> 16) * (bcr & 0xffff) / 2); return; @@ -67,7 +67,7 @@ void psxDma4(u32 madr, u32 bcr, u32 chcr) { // SPU break; } size = (bcr >> 16) * (bcr & 0xffff) * 2; - SPU_readDMAMem(ptr, size); + SPU_readDMAMem(ptr, size, psxRegs.cycle); psxCpu->Clear(madr, size); break; diff --git a/libpcsxcore/psxhw.c b/libpcsxcore/psxhw.c index 6b9125d..c90f8c7 100644 --- a/libpcsxcore/psxhw.c +++ b/libpcsxcore/psxhw.c @@ -493,7 +493,7 @@ void psxHwWrite16(u32 add, u16 value) { default: if (add>=0x1f801c00 && add<0x1f801e00) { - SPU_writeRegister(add, value); + SPU_writeRegister(add, value, psxRegs.cycle); return; } @@ -747,8 +747,8 @@ void psxHwWrite32(u32 add, u32 value) { default: // Dukes of Hazard 2 - car engine noise if (add>=0x1f801c00 && add<0x1f801e00) { - SPU_writeRegister(add, value&0xffff); - SPU_writeRegister(add + 2, value>>16); + SPU_writeRegister(add, value&0xffff, psxRegs.cycle); + SPU_writeRegister(add + 2, value>>16, psxRegs.cycle); return; } diff --git a/libpcsxcore/spu.c b/libpcsxcore/spu.c index f23051e..90d2f4d 100644 --- a/libpcsxcore/spu.c +++ b/libpcsxcore/spu.c @@ -36,5 +36,5 @@ void CALLBACK SPUschedule(unsigned int cycles_after) { } void spuUpdate() { - SPU_async(psxRegs.cycle); + SPU_async(psxRegs.cycle, 0); } -- cgit v1.2.3 From d618a2409c80f627a43c89791ce3f7bc38a48648 Mon Sep 17 00:00:00 2001 From: notaz Date: Thu, 18 Dec 2014 23:51:42 +0200 Subject: psxcounters: don't do many spu updates not needed with new sync code --- libpcsxcore/psxcounters.c | 28 ++++++++-------------------- 1 file changed, 8 insertions(+), 20 deletions(-) (limited to 'libpcsxcore') diff --git a/libpcsxcore/psxcounters.c b/libpcsxcore/psxcounters.c index b25674c..35823da 100644 --- a/libpcsxcore/psxcounters.c +++ b/libpcsxcore/psxcounters.c @@ -61,7 +61,6 @@ static const u32 CountToTarget = 1; static const u32 FrameRate[] = { 60, 50 }; static const u32 HSyncTotal[] = { 263, 313 }; -static const u32 SpuUpdInterval[] = { 32, 32 }; #define VBlankStart 240 #define VERBOSE_LEVEL 0 @@ -73,7 +72,6 @@ Rcnt rcnts[ CounterQuantity ]; u32 hSyncCount = 0; u32 frame_counter = 0; -static u32 spuSyncCount = 0; static u32 hsync_steps = 0; static u32 base_cycle = 0; @@ -323,22 +321,10 @@ void psxRcntUpdate() if( cycle - rcnts[3].cycleStart >= rcnts[3].cycle ) { u32 leftover_cycles = cycle - rcnts[3].cycleStart - rcnts[3].cycle; - u32 next_vsync, next_lace; + u32 next_vsync; - spuSyncCount += hsync_steps; hSyncCount += hsync_steps; - // Update spu. - if( spuSyncCount >= SpuUpdInterval[Config.PsxType] ) - { - spuSyncCount = 0; - - if( SPU_async ) - { - SPU_async( cycle, 1 ); - } - } - // VSync irq. if( hSyncCount == VBlankStart ) { @@ -348,6 +334,11 @@ void psxRcntUpdate() EmuUpdate(); GPU_updateLace(); + + if( SPU_async ) + { + SPU_async( cycle, 1 ); + } } // Update lace. (with InuYasha fix) @@ -363,13 +354,10 @@ void psxRcntUpdate() } // Schedule next call, in hsyncs - hsync_steps = SpuUpdInterval[Config.PsxType] - spuSyncCount; + hsync_steps = HSyncTotal[Config.PsxType] - hSyncCount; next_vsync = VBlankStart - hSyncCount; // ok to overflow - next_lace = HSyncTotal[Config.PsxType] - hSyncCount; if( next_vsync && next_vsync < hsync_steps ) hsync_steps = next_vsync; - if( next_lace && next_lace < hsync_steps ) - hsync_steps = next_lace; rcnts[3].cycleStart = cycle - leftover_cycles; if (Config.PsxType) @@ -493,7 +481,6 @@ void psxRcntInit() } hSyncCount = 0; - spuSyncCount = 0; hsync_steps = 1; psxRcntSet(); @@ -503,6 +490,7 @@ void psxRcntInit() s32 psxRcntFreeze( void *f, s32 Mode ) { + u32 spuSyncCount = 0; u32 count; s32 i; -- cgit v1.2.3 From ce0e7ac9c11993f9165615dec870c50e1c3b39bf Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sat, 13 Dec 2014 05:53:54 +0100 Subject: psxmem: Add mman wrapper for Win32 and use it for PCSX ReARmed libretro Win32 Conflicts: Makefile.libretro --- libpcsxcore/memmap.h | 56 +++++++++++++++ libpcsxcore/memmap_win32.c | 173 +++++++++++++++++++++++++++++++++++++++++++++ libpcsxcore/psxmem.c | 3 +- 3 files changed, 231 insertions(+), 1 deletion(-) create mode 100644 libpcsxcore/memmap.h create mode 100644 libpcsxcore/memmap_win32.c (limited to 'libpcsxcore') diff --git a/libpcsxcore/memmap.h b/libpcsxcore/memmap.h new file mode 100644 index 0000000..ad56f04 --- /dev/null +++ b/libpcsxcore/memmap.h @@ -0,0 +1,56 @@ +#ifndef _MEMMAP_H +#define _MEMMAP_H + +#ifdef _WIN32 + +#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later. +#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows. +#endif + +/* All the headers include this file. */ +#ifndef _MSC_VER +#include <_mingw.h> +#endif + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define PROT_NONE 0 +#define PROT_READ 1 +#define PROT_WRITE 2 +#define PROT_EXEC 4 + +#define MAP_FILE 0 +#define MAP_SHARED 1 +#define MAP_PRIVATE 2 +#define MAP_TYPE 0xf +#define MAP_FIXED 0x10 +#define MAP_ANONYMOUS 0x20 +#define MAP_ANON MAP_ANONYMOUS + +#define MAP_FAILED ((void *)-1) + +/* Flags for msync. */ +#define MS_ASYNC 1 +#define MS_SYNC 2 +#define MS_INVALIDATE 4 + +void* mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off); +int munmap(void *addr, size_t len); +int mprotect(void *addr, size_t len, int prot); +int msync(void *addr, size_t len, int flags); +int mlock(const void *addr, size_t len); +int munlock(const void *addr, size_t len); + +#ifdef __cplusplus +}; +#endif + +#else +#include +#endif + +#endif diff --git a/libpcsxcore/memmap_win32.c b/libpcsxcore/memmap_win32.c new file mode 100644 index 0000000..f4dbdd6 --- /dev/null +++ b/libpcsxcore/memmap_win32.c @@ -0,0 +1,173 @@ +#include +#include +#include + +#include "mman.h" + +#ifndef FILE_MAP_EXECUTE +#define FILE_MAP_EXECUTE 0x0020 +#endif /* FILE_MAP_EXECUTE */ + +static int __map_mman_error(const DWORD err, const int deferr) +{ + if (err == 0) + return 0; + /* TODO: implement */ + return err; +} + +static DWORD __map_mmap_prot_page(const int prot) +{ + DWORD protect = 0; + + if (prot == PROT_NONE) + return 0; + + if ((prot & PROT_EXEC) != 0) + protect = ((prot & PROT_WRITE) != 0) ? + PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ; + else + protect = ((prot & PROT_WRITE) != 0) ? + PAGE_READWRITE : PAGE_READONLY; + + return protect; +} + +static DWORD __map_mmap_prot_file(const int prot) +{ + DWORD desiredAccess = 0; + + if (prot == PROT_NONE) + return 0; + + if ((prot & PROT_READ) != 0) + desiredAccess |= FILE_MAP_READ; + if ((prot & PROT_WRITE) != 0) + desiredAccess |= FILE_MAP_WRITE; + if ((prot & PROT_EXEC) != 0) + desiredAccess |= FILE_MAP_EXECUTE; + + return desiredAccess; +} + +void* mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off) +{ + HANDLE fm, h; + + void * map = MAP_FAILED; + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable: 4293) +#endif + + const DWORD dwFileOffsetLow = (sizeof(off_t) <= sizeof(DWORD)) ? + (DWORD)off : (DWORD)(off & 0xFFFFFFFFL); + const DWORD dwFileOffsetHigh = (sizeof(off_t) <= sizeof(DWORD)) ? + (DWORD)0 : (DWORD)((off >> 32) & 0xFFFFFFFFL); + const DWORD protect = __map_mmap_prot_page(prot); + const DWORD desiredAccess = __map_mmap_prot_file(prot); + + const off_t maxSize = off + (off_t)len; + + const DWORD dwMaxSizeLow = (sizeof(off_t) <= sizeof(DWORD)) ? + (DWORD)maxSize : (DWORD)(maxSize & 0xFFFFFFFFL); + const DWORD dwMaxSizeHigh = (sizeof(off_t) <= sizeof(DWORD)) ? + (DWORD)0 : (DWORD)((maxSize >> 32) & 0xFFFFFFFFL); + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + + errno = 0; + + if (len == 0 + /* Unsupported flag combinations */ + || (flags & MAP_FIXED) != 0 + /* Usupported protection combinations */ + || prot == PROT_EXEC) + { + errno = EINVAL; + return MAP_FAILED; + } + + h = ((flags & MAP_ANONYMOUS) == 0) ? + (HANDLE)_get_osfhandle(fildes) : INVALID_HANDLE_VALUE; + + if ((flags & MAP_ANONYMOUS) == 0 && h == INVALID_HANDLE_VALUE) + { + errno = EBADF; + return MAP_FAILED; + } + + fm = CreateFileMapping(h, NULL, protect, dwMaxSizeHigh, dwMaxSizeLow, NULL); + + if (!fm) + goto error; + + map = MapViewOfFile(fm, desiredAccess, dwFileOffsetHigh, dwFileOffsetLow, len); + + CloseHandle(fm); + + if (!map) + goto error; + + return map; +error: + errno = __map_mman_error(GetLastError(), EPERM); + return MAP_FAILED; +} + +int munmap(void *addr, size_t len) +{ + if (UnmapViewOfFile(addr)) + return 0; + + errno = __map_mman_error(GetLastError(), EPERM); + + return -1; +} + +int mprotect(void *addr, size_t len, int prot) +{ + DWORD newProtect = __map_mmap_prot_page(prot); + DWORD oldProtect = 0; + + if (VirtualProtect(addr, len, newProtect, &oldProtect)) + return 0; + + errno = __map_mman_error(GetLastError(), EPERM); + + return -1; +} + +int msync(void *addr, size_t len, int flags) +{ + if (FlushViewOfFile(addr, len)) + return 0; + + errno = __map_mman_error(GetLastError(), EPERM); + + return -1; +} + +int mlock(const void *addr, size_t len) +{ + if (VirtualLock((LPVOID)addr, len)) + return 0; + + errno = __map_mman_error(GetLastError(), EPERM); + + return -1; +} + +int munlock(const void *addr, size_t len) +{ + if (VirtualUnlock((LPVOID)addr, len)) + return 0; + + errno = __map_mman_error(GetLastError(), EPERM); + + return -1; +} + diff --git a/libpcsxcore/psxmem.c b/libpcsxcore/psxmem.c index 7001744..86da68c 100644 --- a/libpcsxcore/psxmem.c +++ b/libpcsxcore/psxmem.c @@ -28,7 +28,8 @@ #include "r3000a.h" #include "psxhw.h" #include "debug.h" -#include + +#include "memmap.h" #ifndef MAP_ANONYMOUS #define MAP_ANONYMOUS MAP_ANON -- cgit v1.2.3