#include <stdio.h>
#include <stdarg.h>
#include <string.h>
+#ifndef _WIN32
#include <sys/mman.h>
+#else
+#include <io.h>
+#include <windows.h>
+#include <sys/types.h>
+#endif
#include <errno.h>
#ifdef __MACH__
#include <libkern/OSCacheControl.h>
#include "common/version.h"
#include "libretro.h"
-#ifndef MAP_ANONYMOUS
-#define MAP_ANONYMOUS MAP_ANON
-#endif
-
static retro_video_refresh_t video_cb;
static retro_input_poll_t input_poll_cb;
static retro_input_state_t input_state_cb;
#endif
}
+#ifdef _WIN32
+/* mmap() replacement for Windows
+ *
+ * Author: Mike Frysinger <vapier@gentoo.org>
+ * Placed into the public domain
+ */
+
+/* References:
+ * CreateFileMapping: http://msdn.microsoft.com/en-us/library/aa366537(VS.85).aspx
+ * CloseHandle: http://msdn.microsoft.com/en-us/library/ms724211(VS.85).aspx
+ * MapViewOfFile: http://msdn.microsoft.com/en-us/library/aa366761(VS.85).aspx
+ * UnmapViewOfFile: http://msdn.microsoft.com/en-us/library/aa366882(VS.85).aspx
+ */
+
+#define PROT_READ 0x1
+#define PROT_WRITE 0x2
+/* This flag is only available in WinXP+ */
+#ifdef FILE_MAP_EXECUTE
+#define PROT_EXEC 0x4
+#else
+#define PROT_EXEC 0x0
+#define FILE_MAP_EXECUTE 0
+#endif
+
+#define MAP_SHARED 0x01
+#define MAP_PRIVATE 0x02
+#define MAP_ANONYMOUS 0x20
+#define MAP_ANON MAP_ANONYMOUS
+#define MAP_FAILED ((void *) -1)
+
+#ifdef __USE_FILE_OFFSET64
+# define DWORD_HI(x) (x >> 32)
+# define DWORD_LO(x) ((x) & 0xffffffff)
+#else
+# define DWORD_HI(x) (0)
+# define DWORD_LO(x) (x)
+#endif
+
+static void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset)
+{
+ if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC))
+ return MAP_FAILED;
+ if (fd == -1) {
+ if (!(flags & MAP_ANON) || offset)
+ return MAP_FAILED;
+ } else if (flags & MAP_ANON)
+ return MAP_FAILED;
+
+ DWORD flProtect;
+ if (prot & PROT_WRITE) {
+ if (prot & PROT_EXEC)
+ flProtect = PAGE_EXECUTE_READWRITE;
+ else
+ flProtect = PAGE_READWRITE;
+ } else if (prot & PROT_EXEC) {
+ if (prot & PROT_READ)
+ flProtect = PAGE_EXECUTE_READ;
+ else if (prot & PROT_EXEC)
+ flProtect = PAGE_EXECUTE;
+ } else
+ flProtect = PAGE_READONLY;
+
+ off_t end = length + offset;
+ HANDLE mmap_fd, h;
+ if (fd == -1)
+ mmap_fd = INVALID_HANDLE_VALUE;
+ else
+ mmap_fd = (HANDLE)_get_osfhandle(fd);
+ h = CreateFileMapping(mmap_fd, NULL, flProtect, DWORD_HI(end), DWORD_LO(end), NULL);
+ if (h == NULL)
+ return MAP_FAILED;
+
+ DWORD dwDesiredAccess;
+ if (prot & PROT_WRITE)
+ dwDesiredAccess = FILE_MAP_WRITE;
+ else
+ dwDesiredAccess = FILE_MAP_READ;
+ if (prot & PROT_EXEC)
+ dwDesiredAccess |= FILE_MAP_EXECUTE;
+ if (flags & MAP_PRIVATE)
+ dwDesiredAccess |= FILE_MAP_COPY;
+ void *ret = MapViewOfFile(h, dwDesiredAccess, DWORD_HI(offset), DWORD_LO(offset), length);
+ if (ret == NULL) {
+ CloseHandle(h);
+ ret = MAP_FAILED;
+ }
+ return ret;
+}
+
+static void munmap(void *addr, size_t length)
+{
+ UnmapViewOfFile(addr);
+ /* ruh-ro, we leaked handle from CreateFileMapping() ... */
+}
+#endif
+
+#ifndef MAP_ANONYMOUS
+#define MAP_ANONYMOUS MAP_ANON
+#endif
+
void *plat_mmap(unsigned long addr, size_t size, int need_exec, int is_fixed)
{
- int flags = MAP_PRIVATE | MAP_ANONYMOUS;
- void *req, *ret;
+ int flags = MAP_PRIVATE | MAP_ANONYMOUS;
+ void *req, *ret;
- req = (void *)addr;
- ret = mmap(req, size, PROT_READ | PROT_WRITE, flags, -1, 0);
- if (ret == MAP_FAILED) {
- lprintf("mmap(%08lx, %zd) failed: %d\n", addr, size, errno);
- return NULL;
- }
+ req = (void *)addr;
+ ret = mmap(req, size, PROT_READ | PROT_WRITE, flags, -1, 0);
+ if (ret == MAP_FAILED) {
+ lprintf("mmap(%08lx, %zd) failed: %d\n", addr, size, errno);
+ return NULL;
+ }
- if (addr != 0 && ret != (void *)addr) {
- lprintf("warning: wanted to map @%08lx, got %p\n",
- addr, ret);
+ if (addr != 0 && ret != (void *)addr) {
+ lprintf("warning: wanted to map @%08lx, got %p\n",
+ addr, ret);
- if (is_fixed) {
- munmap(ret, size);
- return NULL;
- }
- }
+ if (is_fixed) {
+ munmap(ret, size);
+ return NULL;
+ }
+ }
return ret;
}
int plat_mem_set_exec(void *ptr, size_t size)
{
- int ret = mprotect(ptr, size, PROT_READ | PROT_WRITE | PROT_EXEC);
- if (ret != 0)
- lprintf("mprotect(%p, %zd) failed: %d\n", ptr, size, errno);
-
+#ifdef _WIN32
+ int ret = VirtualProtect(ptr,size,PAGE_EXECUTE_READWRITE,0);
+ if (ret == 0)
+ lprintf("mprotect(%p, %zd) failed: %d\n", ptr, size, 0);
+#else
+ int ret = mprotect(ptr, size, PROT_READ | PROT_WRITE | PROT_EXEC);
+ if (ret != 0)
+ lprintf("mprotect(%p, %zd) failed: %d\n", ptr, size, errno);
+#endif
return ret;
}
//{ "region", "Region; Auto|NTSC|PAL" },
{ "picodrive_input1", "Input device 1; 3 button pad|6 button pad|None" },
{ "picodrive_input2", "Input device 2; 3 button pad|6 button pad|None" },
+#ifdef DRC_SH2
+ { "picodrive_drc", "Dynamic recompilers; enabled|disabled" },
+#endif
{ NULL, NULL },
};
static const char * const biosfiles_us[] = {
- "us_scd1_9210", "us_scd2_9306", "SegaCDBIOS9303", "bios_CD_U"
+ "us_scd2_9306", "SegaCDBIOS9303", "us_scd1_9210", "bios_CD_U"
};
static const char * const biosfiles_eu[] = {
- "eu_mcd1_9210", "eu_mcd2_9306", "eu_mcd2_9303", "bios_CD_E"
+ "eu_mcd2_9306", "eu_mcd2_9303", "eu_mcd1_9210", "bios_CD_E"
};
static const char * const biosfiles_jp[] = {
- "jp_mcd1_9112", "jp_mcd1_9111", "bios_CD_J"
+ "jp_mcd2_921222", "jp_mcd1_9112", "jp_mcd1_9111", "bios_CD_J"
};
static void make_system_path(char *buf, size_t buf_size,
var.key = "picodrive_input2";
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
PicoSetInputDevice(1, input_name_to_val(var.value));
+
+#ifdef DRC_SH2
+ var.value = NULL;
+ var.key = "picodrive_drc";
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
+ if (strcmp(var.value, "enabled") == 0)
+ PicoOpt |= POPT_EN_DRC;
+ else
+ PicoOpt &= ~POPT_EN_DRC;
+ }
+#endif
}
void retro_run(void)
| POPT_EN_32X|POPT_EN_PWM
| POPT_ACC_SPRITES|POPT_DIS_32C_BORDER;
#ifdef __arm__
- PicoOpt |= POPT_EN_SVP_DRC;
+ PicoOpt |= POPT_EN_DRC;
#endif
PsndRate = 44100;
PicoAutoRgnOrder = 0x184; // US, EU, JP