summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile9
-rw-r--r--arm/arm_emit.h12
-rw-r--r--cpu_threaded.c41
-rw-r--r--libco/libco.c2
-rw-r--r--libco/psp2.c116
-rw-r--r--libretro.c12
6 files changed, 153 insertions, 39 deletions
diff --git a/Makefile b/Makefile
index 955504d..ce7df43 100644
--- a/Makefile
+++ b/Makefile
@@ -195,11 +195,12 @@ else ifeq ($(platform), vita)
TARGET := $(TARGET_NAME)_libretro_$(platform).a
CC = arm-vita-eabi-gcc$(EXE_EXT)
AR = arm-vita-eabi-ar$(EXE_EXT)
- CFLAGS += -DVITA
- CFLAGS += -marm -mcpu=cortex-a9
- ASFLAGS += -mcpu=cortex-a9
+ CFLAGS += -DVITA -g
+ CFLAGS += -mthumb -mcpu=cortex-a9 -mfloat-abi=hard
+ CFLAGS += -Wall -mword-relocations
+ CFLAGS += -fomit-frame-pointer -ffast-math
+ ASFLAGS += -mthumb -mcpu=cortex-a9
STATIC_LINKING = 1
- HAVE_DYNAREC = 1
CPU_ARCH := arm
# CTR(3DS)
diff --git a/arm/arm_emit.h b/arm/arm_emit.h
index bfd1c49..185caef 100644
--- a/arm/arm_emit.h
+++ b/arm/arm_emit.h
@@ -49,10 +49,8 @@ void execute_swi_thumb(u32 pc);
void execute_store_u32_safe(u32 address, u32 source);
#define write32(value) \
- VITA_RW_INIT(); \
*((u32 *)translation_ptr) = value; \
- translation_ptr += 4; \
- VITA_RW_END() \
+ translation_ptr += 4 \
#define arm_relative_offset(source, offset) \
(((((u32)offset - (u32)source) - 8) >> 2) & 0xFFFFFF) \
@@ -409,17 +407,13 @@ u32 arm_disect_imm_32bit(u32 imm, u32 *stores, u32 *rotations)
cycle_count = 0 \
#define generate_branch_patch_conditional(dest, offset) \
- VITA_RW_INIT(); \
*((u32 *)(dest)) = (*((u32 *)dest) & 0xFF000000) | \
- arm_relative_offset(dest, offset); \
- VITA_RW_END(); \
+ arm_relative_offset(dest, offset) \
#define generate_branch_patch_unconditional(dest, offset) \
- VITA_RW_INIT(); \
*((u32 *)(dest)) = (*((u32 *)dest) & 0xFF000000) | \
- arm_relative_offset(dest, offset); \
- VITA_RW_END(); \
+ arm_relative_offset(dest, offset) \
// A different function is called for idle updates because of the relative
// location of the embedded PC. The idle version could be optimized to put
diff --git a/cpu_threaded.c b/cpu_threaded.c
index e3e1a14..ca5b99e 100644
--- a/cpu_threaded.c
+++ b/cpu_threaded.c
@@ -24,6 +24,7 @@
#include "common.h"
#if defined(VITA)
#include <psp2/kernel/sysmem.h>
+#include <stdio.h>
#endif
u8 *last_rom_translation_ptr = NULL;
@@ -251,7 +252,7 @@ extern u8 bit_count[256];
#define invalidate_icache_region(addr, size) \
{ \
- sceKernelSyncVMDomain(sceBlock, addr, size); \
+ int ret = sceKernelSyncVMDomain(sceBlock, addr, size); \
}
#elif defined(_3DS)
@@ -2837,8 +2838,10 @@ u8 *block_lookup_address_##type(u32 pc) \
u8 *block_address; \
\
/* Starting at the beginning, we allow for one translation cache flush. */ \
- if(translation_recursion_level == 0) \
+ if(translation_recursion_level == 0){ \
translation_flush_count = 0; \
+ RW_INIT(); \
+ } \
block_lookup_address_pc_##type(); \
\
switch(pc >> 24) \
@@ -2871,7 +2874,6 @@ u8 *block_lookup_address_##type(u32 pc) \
(ROM_BRANCH_HASH_SIZE - 1); \
u32 *block_ptr = rom_branch_hash[hash_target]; \
u32 **block_ptr_address = rom_branch_hash + hash_target; \
- RW_INIT(); \
while(block_ptr) \
{ \
if(block_ptr[0] == pc) \
@@ -2882,7 +2884,6 @@ u8 *block_lookup_address_##type(u32 pc) \
block_ptr_address = (u32 **)(block_ptr + 1); \
block_ptr = (u32 *)block_ptr[1]; \
} \
- RW_END(); \
if(!block_ptr) \
{ \
__label__ redo; \
@@ -2891,13 +2892,11 @@ u8 *block_lookup_address_##type(u32 pc) \
redo: \
\
translation_recursion_level++; \
- RW_INIT(); \
((u32 *)rom_translation_ptr)[0] = pc; \
((u32 **)rom_translation_ptr)[1] = NULL; \
*block_ptr_address = (u32 *)rom_translation_ptr; \
rom_translation_ptr += 8; \
block_address = rom_translation_ptr + block_prologue_size; \
- RW_END(); \
block_lookup_translate_##type(rom, 0); \
translation_recursion_level--; \
\
@@ -2937,7 +2936,9 @@ u8 *block_lookup_address_##type(u32 pc) \
block_address = (u8 *)(-1); \
break; \
} \
- \
+ if(translation_recursion_level == 0) \
+ RW_END(); \
+ \
return block_address; \
} \
@@ -3291,7 +3292,8 @@ s32 translate_block_arm(u32 pc, translation_region_type
u8 *translation_cache_limit = NULL;
s32 i;
u32 flag_status;
- block_exit_type external_block_exits[MAX_EXITS];
+ block_exit_type external_block_exits[MAX_EXITS];
+ RW_INIT();
generate_block_extra_vars_arm();
arm_fix_pc();
@@ -3399,7 +3401,7 @@ s32 translate_block_arm(u32 pc, translation_region_type
flush_translation_cache_bios();
break;
}
-
+ RW_END();
return -1;
}
@@ -3476,12 +3478,14 @@ s32 translate_block_arm(u32 pc, translation_region_type
{
branch_target = external_block_exits[i].branch_target;
arm_link_block();
- if(!translation_target)
- return -1;
+ if(!translation_target){
+ RW_END();
+ return -1;
+ }
generate_branch_patch_unconditional(
external_block_exits[i].branch_source, translation_target);
}
-
+ RW_END();
return 0;
}
@@ -3508,7 +3512,8 @@ s32 translate_block_thumb(u32 pc, translation_region_type
u8 *translation_cache_limit = NULL;
s32 i;
u32 flag_status;
- block_exit_type external_block_exits[MAX_EXITS];
+ block_exit_type external_block_exits[MAX_EXITS];
+ RW_INIT();
generate_block_extra_vars_thumb();
thumb_fix_pc();
@@ -3616,7 +3621,7 @@ s32 translate_block_thumb(u32 pc, translation_region_type
flush_translation_cache_bios();
break;
}
-
+ RW_END();
return -1;
}
@@ -3693,12 +3698,14 @@ s32 translate_block_thumb(u32 pc, translation_region_type
{
branch_target = external_block_exits[i].branch_target;
thumb_link_block();
- if(!translation_target)
- return -1;
+ if(!translation_target){
+ RW_END();
+ return -1;
+ }
generate_branch_patch_unconditional(
external_block_exits[i].branch_source, translation_target);
}
-
+ RW_END();
return 0;
}
diff --git a/libco/libco.c b/libco/libco.c
index 63126d3..7bcbbd0 100644
--- a/libco/libco.c
+++ b/libco/libco.c
@@ -10,6 +10,8 @@
#include "amd64.c"
#elif defined(__GNUC__) && defined(_ARCH_PPC)
#include "ppc.c"
+#elif defined(VITA)
+ #include "psp2.c"
#elif defined(__GNUC__) && (defined(__ARM_EABI__) || defined(__arm__))
#include "armeabi.c"
#elif defined(__GNUC__)
diff --git a/libco/psp2.c b/libco/psp2.c
new file mode 100644
index 0000000..3ab1bc7
--- /dev/null
+++ b/libco/psp2.c
@@ -0,0 +1,116 @@
+/*
+ libco.arm (2016-08-14)
+ author: frangarcj
+ license: public domain
+*/
+
+#define LIBCO_C
+#include "libco.h"
+
+#include <assert.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <psp2/kernel/sysmem.h>
+#include <stdio.h>
+#include <string.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+static inline int align(int x, int n) {
+ return (((x >> n) + 1) << n );
+}
+#define FOUR_KB_ALIGN(x) align(x, 12)
+#define MB_ALIGN(x) align(x, 20)
+
+static thread_local unsigned long co_active_buffer[64];
+static thread_local cothread_t co_active_handle = 0;
+static void (*co_swap)(cothread_t, cothread_t) = 0;
+static int block;
+static uint32_t co_swap_function[] = {
+ 0xe8a16ff0, /* stmia r1!, {r4-r11,sp,lr} */
+ 0xe8b0aff0, /* ldmia r0!, {r4-r11,sp,pc} */
+ 0xe12fff1e, /* bx lr */
+};
+
+void co_init() {
+ int ret;
+ void *base;
+
+ block = sceKernelAllocMemBlockForVM("libco", MB_ALIGN(FOUR_KB_ALIGN(sizeof co_swap_function)));
+ if (block < 0)
+ {
+ return;
+ }
+
+ // get base address
+ ret = sceKernelGetMemBlockBase(block, &base);
+ if (ret < 0)
+ {
+ return;
+ }
+
+ // set domain to be writable by user
+ ret = sceKernelOpenVMDomain();
+ if (ret < 0)
+ {
+ return;
+ }
+
+
+ memcpy(base,co_swap_function,sizeof co_swap_function);
+
+ // set domain back to read-only
+ ret = sceKernelCloseVMDomain();
+ if (ret < 0)
+ {
+ return;
+ }
+
+ // flush icache
+ ret = sceKernelSyncVMDomain(block, base, MB_ALIGN(FOUR_KB_ALIGN(sizeof co_swap_function)));
+ if (ret < 0)
+ {
+ return;
+ }
+
+ co_swap = (void (*)(cothread_t, cothread_t))base;
+
+
+}
+
+cothread_t co_active() {
+ if(!co_active_handle) co_active_handle = &co_active_buffer;
+ return co_active_handle;
+}
+
+cothread_t co_create(unsigned int size, void (*entrypoint)(void)) {
+ unsigned long* handle = 0;
+ if(!co_swap) {
+ co_init();
+ }
+ if(!co_active_handle) co_active_handle = &co_active_buffer;
+ size += 256;
+ size &= ~15;
+
+ if((handle = (unsigned long*)malloc(size))) {
+ unsigned long* p = (unsigned long*)((unsigned char*)handle + size);
+ handle[8] = (unsigned long)p;
+ handle[9] = (unsigned long)entrypoint;
+ }
+
+ return handle;
+}
+
+void co_delete(cothread_t handle) {
+ free(handle);
+}
+
+void co_switch(cothread_t handle) {
+ cothread_t co_previous_handle = co_active_handle;
+ co_swap(co_active_handle = handle, co_previous_handle);
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/libretro.c b/libretro.c
index b0fac00..00dfe55 100644
--- a/libretro.c
+++ b/libretro.c
@@ -9,7 +9,7 @@
#include "memmap.h"
-#if defined(VITA)
+#if defined(VITA) && defined(HAVE_DYNAREC)
#include <psp2/kernel/sysmem.h>
static int translation_caches_inited = 0;
static inline int align(int x, int n) {
@@ -159,15 +159,13 @@ void retro_init(void)
}
#endif
-#if defined(VITA)
+#if defined(VITA) && defined(HAVE_DYNAREC)
if(!translation_caches_inited){
void* currentHandle;
sceBlock = sceKernelAllocMemBlockForVM("code", MB_ALIGN(FOUR_KB_ALIGN(ROM_TRANSLATION_CACHE_SIZE +
RAM_TRANSLATION_CACHE_SIZE +
BIOS_TRANSLATION_CACHE_SIZE)));
- FILE * fd = fopen("ux0:/temp/test.txt","w+");
- fprintf(fd,"%x\n",sceBlock);
if (sceBlock < 0)
{
return;
@@ -179,9 +177,6 @@ void retro_init(void)
{
return;
}
- fprintf(fd,"%x %x\n",currentHandle,ret);
-
- fclose(fd);
rom_translation_cache = (u8*)currentHandle;
ram_translation_cache = rom_translation_cache + ROM_TRANSLATION_CACHE_SIZE;
@@ -240,7 +235,7 @@ void retro_deinit(void)
}
#endif
-#if defined(VITA)
+#if defined(VITA) && defined(HAVE_DYNAREC)
if(translation_caches_inited){
sceKernelFreeMemBlock(sceBlock);
@@ -487,7 +482,6 @@ bool retro_load_game(const struct retro_game_info* info)
}
gamepak_filename[0] = 0;
-
if (load_gamepak(info, info->path) != 0)
{
error_msg("Could not load the game file.");