No need to to have a build-time option now.
need_xlib="no"
need_libpicofe="yes"
need_warm="no"
-enable_icache_emu="yes"
CFLAGS_GLES=""
LDLIBS_GLES=""
# these are for known platforms
optimize_cortexa8="yes"
have_arm_neon="yes"
need_xlib="yes"
- enable_icache_emu="no"
;;
maemo)
ram_fixed="yes"
drc_cache_base="yes"
optimize_cortexa8="yes"
have_arm_neon="yes"
- enable_icache_emu="no"
;;
caanoo)
sound_drivers="oss"
drc_cache_base="yes"
optimize_arm926ej="yes"
need_warm="yes"
- enable_icache_emu="no"
;;
libretro)
sound_drivers="libretro"
;;
--disable-dynarec) enable_dynarec="no"
;;
- --disable-icache-emu) enable_icache_emu="no"
- ;;
- --enable-icache-emu) enable_icache_emu="yes"
- ;;
*) echo "ERROR: unknown option $opt"; show_help="yes"
;;
esac
CFLAGS="$CFLAGS -D_FILE_OFFSET_BITS=64"
fi
-if [ "$enable_icache_emu" = "yes" ]; then
- CFLAGS="$CFLAGS -DICACHE_EMULATION"
-fi
-
cat > $TMPC <<EOF
void test(void *f, void *d) { fread(d, 1, 1, f); }
EOF
// ------------ adv options menu ------------
+#ifndef DRC_DISABLE
static const char h_cfg_psxclk[] = "Over/under-clock the PSX, default is " DEFAULT_PSX_CLOCK_S "\n"
"(lower value - less work for the emu, may be faster)";
static const char h_cfg_nosmc[] = "Will cause crashes when loading, break memcards";
static const char h_cfg_gteunn[] = "May cause graphical glitches";
static const char h_cfg_gteflgs[] = "Will cause graphical glitches";
+#endif
static const char h_cfg_stalls[] = "Will cause some games to run too fast";
static menu_entry e_menu_speed_hacks[] =
{
+#ifndef DRC_DISABLE
mee_range_h ("PSX CPU clock, %%", 0, psx_clock, 1, 500, h_cfg_psxclk),
mee_onoff_h ("Disable SMC checks", 0, new_dynarec_hacks, NDHACK_NO_SMC_CHECK, h_cfg_nosmc),
mee_onoff_h ("Assume GTE regs unneeded", 0, new_dynarec_hacks, NDHACK_GTE_UNNEEDED, h_cfg_gteunn),
mee_onoff_h ("Disable GTE flags", 0, new_dynarec_hacks, NDHACK_GTE_NO_FLAGS, h_cfg_gteflgs),
+#endif
mee_onoff_h ("Disable CPU/GTE stalls", 0, Config.DisableStalls, 1, h_cfg_stalls),
mee_end,
};
// "(timing hack, breaks other games)";
static const char h_cfg_rcnt2[] = "InuYasha Sengoku Battle Fix\n"
"(timing hack, breaks other games)";
+#ifndef DRC_DISABLE
static const char h_cfg_nodrc[] = "Disable dynamic recompiler and use interpreter\n"
"Might be useful to overcome some dynarec bugs";
-static const char h_cfg_shacks[] = "Breaks games but may give better performance\n"
- "must reload game for any change to take effect";
-#ifdef ICACHE_EMULATION
-static const char h_cfg_icache[] = "Allows you to play the F1 games.\n"
- "Note: This breaks the PAL version of Spyro 2.";
#endif
+static const char h_cfg_shacks[] = "Breaks games but may give better performance";
+static const char h_cfg_icache[] = "Support F1 games (only when dynarec is off).\n"
+ "Note: This breaks the PAL version of Spyro 2.";
static menu_entry e_menu_adv_options[] =
{
mee_onoff_h ("Disable CD Audio", 0, Config.Cdda, 1, h_cfg_cdda),
//mee_onoff_h ("SIO IRQ Always Enabled", 0, Config.Sio, 1, h_cfg_sio),
mee_onoff_h ("SPU IRQ Always Enabled", 0, Config.SpuIrq, 1, h_cfg_spuirq),
-#ifdef ICACHE_EMULATION
mee_onoff_h ("ICache emulation", 0, Config.icache_emulation, 1, h_cfg_icache),
-#endif
//mee_onoff_h ("Rootcounter hack", 0, Config.RCntFix, 1, h_cfg_rcnt1),
mee_onoff_h ("Rootcounter hack 2", 0, Config.VSyncWA, 1, h_cfg_rcnt2),
+#ifndef DRC_DISABLE
mee_onoff_h ("Disable dynarec (slow!)",0, Config.Cpu, 1, h_cfg_nodrc),
+#endif
mee_handler_h ("[Speed hacks]", menu_loop_speed_hacks, h_cfg_shacks),
mee_end,
};
#include "emu_if.h"
#include "pcsxmem.h"
#include "../psxhle.h"
+#include "../psxinterpreter.h"
#include "../r3000a.h"
#include "../cdrom.h"
#include "../psxdma.h"
invalidate_block(start);
}
-#ifdef ICACHE_EMULATION
static void ari64_notify(int note, void *data) {
/*
Should be fixed when ARM dynarec has proper icache emulation.
}
*/
}
-#endif
static void ari64_apply_config()
{
+ intApplyConfig();
+
if (Config.DisableStalls)
new_dynarec_hacks |= NDHACK_NO_STALLS;
else
ari64_execute,
ari64_execute_until,
ari64_clear,
-#ifdef ICACHE_EMULATION
ari64_notify,
-#endif
ari64_apply_config,
ari64_shutdown
};
-diff --git a/Makefile b/Makefile
-index 0db94f7..e4fe560 100644
---- a/Makefile
-+++ b/Makefile
-@@ -26,6 +26,7 @@ endif
- else # NO_CONFIG_MAK
- config.mak:
- endif
-+CFLAGS += -UICACHE_EMULATION
-
- -include Makefile.local
-
diff --git a/libpcsxcore/new_dynarec/emu_if.c b/libpcsxcore/new_dynarec/emu_if.c
index 2df259b..2a15e6e 100644
--- a/libpcsxcore/new_dynarec/emu_if.c
#ifdef PSXBIOS_LOG
PSXBIOS_LOG("psxBios_%s\n", biosA0n[0x44]);
#endif
-#ifdef ICACHE_EMULATION
psxCpu->Notify(R3000ACPU_NOTIFY_CACHE_ISOLATED, NULL);
psxCpu->Notify(R3000ACPU_NOTIFY_CACHE_UNISOLATED, NULL);
-#endif
pc0 = ra;
}
void (*psxCP2[64])(struct psxCP2Regs *regs);
void (*psxCP2BSC[32])();
-#ifdef ICACHE_EMULATION
+static u32 fetchNoCache(u32 pc)
+{
+ u32 *code = (u32 *)PSXM(pc);
+ return ((code == NULL) ? 0 : SWAP32(*code));
+}
+
/*
Formula One 2001 :
Use old CPU cache code when the RAM location is updated with new code (affects in-game racing)
*/
static u8* ICache_Addr;
static u8* ICache_Code;
-uint32_t *Read_ICache(uint32_t pc)
+static u32 fetchICache(u32 pc)
{
uint32_t pc_bank, pc_offset, pc_cache;
uint8_t *IAddr, *ICode;
if (SWAP32(*(uint32_t *)(IAddr + pc_cache)) == pc_offset)
{
// Cache hit - return last opcode used
- return (uint32_t *)(ICode + pc_cache);
+ return *(uint32_t *)(ICode + pc_cache);
}
else
{
TODO: Probably should add cached BIOS
*/
// default
- return (uint32_t *)PSXM(pc);
+ return fetchNoCache(pc);
}
-#endif
+
+u32 (*fetch)(u32 pc) = fetchNoCache;
static void delayRead(int reg, u32 bpc) {
u32 rold, rnew;
}
void psxDelayTest(int reg, u32 bpc) {
- u32 *code;
- u32 tmp;
-
- #ifdef ICACHE_EMULATION
- if (Config.icache_emulation)
- {
- code = Read_ICache(psxRegs.pc);
- }
- else
- #endif
- {
- code = (u32 *)PSXM(psxRegs.pc);
- }
-
- tmp = ((code == NULL) ? 0 : SWAP32(*code));
+ u32 tmp = fetch(psxRegs.pc);
branch = 1;
switch (psxTestLoadDelay(reg, tmp)) {
}
static u32 psxBranchNoDelay(void) {
- u32 *code;
u32 temp;
- #ifdef ICACHE_EMULATION
- if (Config.icache_emulation)
- {
- code = Read_ICache(psxRegs.pc);
- }
- else
- #endif
- {
- code = (u32 *)PSXM(psxRegs.pc);
- }
- psxRegs.code = ((code == NULL) ? 0 : SWAP32(*code));
+ psxRegs.code = fetch(psxRegs.pc);
switch (_Op_) {
case 0x00: // SPECIAL
switch (_Funct_) {
}
static void doBranch(u32 tar) {
- u32 *code;
u32 tmp;
branch2 = branch = 1;
if (psxDelayBranchTest(tar))
return;
- #ifdef ICACHE_EMULATION
- if (Config.icache_emulation)
- {
- code = Read_ICache(psxRegs.pc);
- }
- else
- #endif
- {
- code = (u32 *)PSXM(psxRegs.pc);
- }
- psxRegs.code = ((code == NULL) ? 0 : SWAP32(*code));
+ psxRegs.code = fetch(psxRegs.pc);
debugI();
///////////////////////////////////////////
static int intInit() {
- #ifdef ICACHE_EMULATION
/* We have to allocate the icache memory even if
* the user has not enabled it as otherwise it can cause issues.
*/
}
memset(ICache_Addr, 0xff, 0x1000);
memset(ICache_Code, 0xff, 0x1000);
- #endif
return 0;
}
static void intReset() {
- #ifdef ICACHE_EMULATION
memset(ICache_Addr, 0xff, 0x1000);
memset(ICache_Code, 0xff, 0x1000);
- #endif
}
void intExecute() {
}
void intNotify (int note, void *data) {
- #ifdef ICACHE_EMULATION
/* Gameblabla - Only clear the icache if it's isolated */
if (note == R3000ACPU_NOTIFY_CACHE_ISOLATED)
{
memset(ICache_Addr, 0xff, 0x1000);
memset(ICache_Code, 0xff, 0x1000);
}
- #endif
}
-void applyConfig() {
+void intApplyConfig() {
assert(psxBSC[18] == psxCOP2 || psxBSC[18] == psxCOP2_stall);
assert(psxBSC[50] == gteLWC2 || psxBSC[50] == gteLWC2_stall);
assert(psxBSC[58] == gteSWC2 || psxBSC[58] == gteSWC2_stall);
psxSPC[26] = psxDIV_stall;
psxSPC[27] = psxDIVU_stall;
}
+
+ // 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;
+ else
+ fetch = fetchICache;
}
static void intShutdown() {
- #ifdef ICACHE_EMULATION
if (ICache_Addr)
{
free(ICache_Addr);
free(ICache_Code);
ICache_Code = NULL;
}
- #endif
}
// interpreter execution
void execI() {
- u32 *code;
- #ifdef ICACHE_EMULATION
- if (Config.icache_emulation)
- {
- code = Read_ICache(psxRegs.pc);
- }
- else
- #endif
- {
- code = (u32 *)PSXM(psxRegs.pc);
- }
- psxRegs.code = ((code == NULL) ? 0 : SWAP32(*code));
+ psxRegs.code = fetch(psxRegs.pc);
debugI();
intExecute,
intExecuteBlock,
intClear,
-#ifdef ICACHE_EMULATION
intNotify,
-#endif
- applyConfig,
+ intApplyConfig,
intShutdown
};
+extern u32 (*fetch)(u32 pc);
+
// called by "new_dynarec"
void execI();
void psxNULL();
+void intApplyConfig();
memset(psxMemWLUT + 0x0000, 0, 0x80 * sizeof(void *));
memset(psxMemWLUT + 0x8000, 0, 0x80 * sizeof(void *));
memset(psxMemWLUT + 0xa000, 0, 0x80 * sizeof(void *));
-#ifdef ICACHE_EMULATION
/* Required for icache interpreter otherwise Armored Core won't boot on icache interpreter */
psxCpu->Notify(R3000ACPU_NOTIFY_CACHE_ISOLATED, NULL);
-#endif
break;
case 0x00: case 0x1e988:
if (writeok == 1) break;
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 *));
-#ifdef ICACHE_EMULATION
/* Dynarecs might take this opportunity to flush their code cache */
psxCpu->Notify(R3000ACPU_NOTIFY_CACHE_UNISOLATED, NULL);
-#endif
break;
default:
#ifdef PSXMEM_LOG
#include "cdrom.h"
#include "mdec.h"
#include "gte.h"
+#include "psxinterpreter.h"
R3000Acpu *psxCpu = NULL;
#ifdef DRC_DISABLE
psxCpu = &psxInt;
} else psxCpu = &psxRec;
#else
+ Config.Cpu = CPU_INTERPRETER;
psxCpu = &psxInt;
#endif
}
void psxException(u32 code, u32 bd) {
- #ifdef ICACHE_EMULATION
- /* Dynarecs may use this codepath and crash as a result.
- * This should only be used for the interpreter. - Gameblabla
- * */
- if (Config.icache_emulation && Config.Cpu == CPU_INTERPRETER)
- {
- psxRegs.code = SWAPu32(*Read_ICache(psxRegs.pc));
- }
- else
- #endif
- {
- psxRegs.code = PSXMu32(psxRegs.pc);
- }
+ psxRegs.code = fetch(psxRegs.pc);
if (!Config.HLE && ((((psxRegs.code) >> 24) & 0xfe) == 0x4a)) {
// "hokuto no ken" / "Crash Bandicot 2" ...
#include "psxcounters.h"
#include "psxbios.h"
-#ifdef ICACHE_EMULATION
enum {
R3000ACPU_NOTIFY_CACHE_ISOLATED = 0,
R3000ACPU_NOTIFY_CACHE_UNISOLATED = 1,
R3000ACPU_NOTIFY_DMA3_EXE_LOAD = 2
};
-extern uint32_t *Read_ICache(uint32_t pc);
-#endif
typedef struct {
int (*Init)();
void (*Execute)(); /* executes up to a break */
void (*ExecuteBlock)(); /* executes up to a jump */
void (*Clear)(u32 Addr, u32 Size);
-#ifdef ICACHE_EMULATION
void (*Notify)(int note, void *data);
-#endif
void (*ApplyConfig)();
void (*Shutdown)();
} R3000Acpu;