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
};