Icache emulation from PCSX Redux + Senquack changes from PCSX4ALL (#198)
authorgameblabla <gameblabla@users.noreply.github.com>
Sat, 2 Oct 2021 13:41:42 +0000 (13:41 +0000)
committerGitHub <noreply@github.com>
Sat, 2 Oct 2021 13:41:42 +0000 (16:41 +0300)
* Merge Icache emulation from PCSX Redux

See (Redux) :
https://github.com/grumpycoders/pcsx-redux/commit/1923ce54ef585beba3a948d50f8c30161102312c

See original icache implementation (mirror of PCSX Reloaded):
https://github.com/gameblabla/pcsxr

Without icache emulation, F1 2001 will greatly misbehave :
if you accelerate, the car will go around like crazy.
With icache emulation, it works as intended.

Our code is slightly different from theirs as i found out that
having the icache arrays in psxregs would cause crashes so instead
what i'm doing is to taking them out of there and only allocating them
on the heap (due to their great size).

Co-authored-by: Nicolas Noble <nicolasnoble@users.noreply.github.com>
* Fix issues with BREAK and some interpreter commands. Fixes F1 2000.

Note that the game is very sensible to timing issues when it comes to the CDROM
controller.
That will be for a separate commit however.

* Culling off cache bits from the hardware addresses.

Based on those PRs from PCSX-Redux :
https://github.com/grumpycoders/pcsx-redux/commit/0cd940100e96b95eea87dbb47381596f7f8dbe72#diff-009cbf66734b5de152bf170b80f8c7e03bebaa08a191f6ad7a06c7420f24b69c
https://github.com/grumpycoders/pcsx-redux/commit/03d2ba3f278868cdd7ee3a44edef7ee87e6a1589#diff-009cbf66734b5de152bf170b80f8c7e03bebaa08a191f6ad7a06c7420f24b69c

Co-authored-by: Nicolas Noble <nicolasnoble@users.noreply.github.com>
* Slightly better "open bus" behavior

OG commit is here from PCSX Redux :
https://github.com/grumpycoders/pcsx-redux/commit/128ba97f9680ab8dcd2f840f72ae998507325730#diff-8552772bc73559e3448880c9b8126252b49b95a89cfac254148d27127cbec719

Co-authored-by: Nicolas Noble <nicolasnoble@users.noreply.github.com>
* [Interpreter] Link even if branch is not taken in BGEZAL/BLTZAL

Source :
grumpycoders/pcsx-redux@c1a0569

Co-authored-by: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com>
Co-authored-by: Nicolas Noble <nicolasnoble@users.noreply.github.com>
configure
frontend/main.c
frontend/menu.c
libpcsxcore/new_dynarec/emu_if.c
libpcsxcore/psxbios.c
libpcsxcore/psxcommon.h
libpcsxcore/psxhw.c
libpcsxcore/psxinterpreter.c
libpcsxcore/psxmem.c
libpcsxcore/r3000a.c
libpcsxcore/r3000a.h

index c3ff68f..5caf0f4 100755 (executable)
--- a/configure
+++ b/configure
@@ -59,6 +59,7 @@ need_sdl="no"
 need_xlib="no"
 need_libpicofe="yes"
 need_warm="no"
+enable_icache_emu="yes"
 CFLAGS_GLES=""
 LDLIBS_GLES=""
 # these are for known platforms
@@ -93,12 +94,14 @@ set_platform()
     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"
@@ -106,6 +109,7 @@ set_platform()
     drc_cache_base="yes"
     optimize_arm926ej="yes"
     need_warm="yes"
+    enable_icache_emu="no"
     ;;
   libretro)
     sound_drivers="libretro"
@@ -134,6 +138,10 @@ for opt do
   ;;
   --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
@@ -152,6 +160,7 @@ if [ "$show_help" = "yes" ]; then
   echo "  --disable-neon           enable/disable ARM NEON optimizations [guessed]"
   echo "  --disable-dynarec        disable dynamic recompiler"
   echo "                           (dynarec is only available and enabled on ARM)"
+  echo "  --disable-icache-emu     Disables the instruction cache emulation"
   echo "influential environment variables:"
   echo "  CROSS_COMPILE CC CXX AS AR CFLAGS ASFLAGS LDFLAGS LDLIBS"
   exit 1
@@ -492,6 +501,10 @@ if [ "x$sizeof_long" = "x4" ]; then
   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
index a824fdc..3bb0f4b 100644 (file)
@@ -122,7 +122,7 @@ void emu_set_default_config(void)
 {
        // try to set sane config on which most games work
        Config.Xa = Config.Cdda = Config.Sio =
-       Config.SpuIrq = Config.RCntFix = Config.VSyncWA = 0;
+       Config.icache_emulation = Config.SpuIrq = Config.RCntFix = Config.VSyncWA = 0;
        Config.PsxAuto = 1;
 
        pl_rearmed_cbs.gpu_neon.allow_interlace = 2; // auto
index 5efd260..e2286d4 100644 (file)
@@ -397,6 +397,7 @@ static const struct {
        CE_CONFIG_VAL(SpuIrq),
        CE_CONFIG_VAL(RCntFix),
        CE_CONFIG_VAL(VSyncWA),
+       CE_CONFIG_VAL(icache_emulation),
        CE_CONFIG_VAL(Cpu),
        CE_INTVAL(region),
        CE_INTVAL_V(g_scaler, 3),
@@ -1559,7 +1560,9 @@ static const char h_cfg_nodrc[]  = "Disable dynamic recompiler and use interpret
                                   "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";
-
+static const char h_cfg_icache[] = "Allows you to play the F1 games.\n"
+                                  "Note: This breaks the PAL version of Spyro 2.";
+                                  
 static menu_entry e_menu_adv_options[] =
 {
        mee_onoff_h   ("Show CPU load",          0, g_opts, OPT_SHOWCPU, h_cfg_cpul),
@@ -1569,6 +1572,9 @@ 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),
        mee_onoff_h   ("Disable dynarec (slow!)",0, Config.Cpu, 1, h_cfg_nodrc),
index 22db5d1..1733a2a 100644 (file)
@@ -393,6 +393,24 @@ static void ari64_clear(u32 addr, u32 size)
                        invalidate_block(start);
 }
 
+#ifdef ICACHE_EMULATION
+static void ari64_notify(int note, void *data) {
+       /*
+       Should be fixed when ARM dynarec has proper icache emulation.
+       switch (note)
+       {
+               case R3000ACPU_NOTIFY_CACHE_UNISOLATED:
+                       break;
+               case R3000ACPU_NOTIFY_CACHE_ISOLATED:
+               Sent from psxDma3().
+               case R3000ACPU_NOTIFY_DMA3_EXE_LOAD:
+               default:
+                       break;
+       }
+       */
+}
+#endif
+
 static void ari64_shutdown()
 {
        new_dynarec_cleanup();
@@ -419,6 +437,9 @@ R3000Acpu psxRec = {
        intExecuteBlockT,
 #endif
        ari64_clear,
+#ifdef ICACHE_EMULATION
+       ari64_notify,
+#endif
        ari64_shutdown
 };
 
index 7a38436..ed95b06 100644 (file)
@@ -1405,7 +1405,10 @@ void psxBios_FlushCache() { // 44
 #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;
 }
 
index 8ef794b..c9d300a 100644 (file)
@@ -132,6 +132,7 @@ typedef struct {
        boolean RCntFix;
        boolean UseNet;
        boolean VSyncWA;
+       boolean icache_emulation;
        u8 Cpu; // CPU_DYNAREC or CPU_INTERPRETER
        u8 PsxType; // PSX_TYPE_NTSC or PSX_TYPE_PAL
 #ifdef _WIN32
index c90f8c7..84ce2f7 100644 (file)
@@ -44,7 +44,7 @@ void psxHwReset() {
 u8 psxHwRead8(u32 add) {
        unsigned char hard;
 
-       switch (add) {
+       switch (add & 0x1fffffff) {
                case 0x1f801040: hard = sioRead8();break; \r
 #ifdef ENABLE_SIO1API
                case 0x1f801050: hard = SIO1_readData8(); break;\r
@@ -70,7 +70,7 @@ u8 psxHwRead8(u32 add) {
 u16 psxHwRead16(u32 add) {
        unsigned short hard;
 
-       switch (add) {
+       switch (add & 0x1fffffff) {
 #ifdef PSXHW_LOG
                case 0x1f801070: PSXHW_LOG("IREG 16bit read %x\n", psxHu16(0x1070));
                        return psxHu16(0x1070);
@@ -204,7 +204,7 @@ u16 psxHwRead16(u32 add) {
 u32 psxHwRead32(u32 add) {
        u32 hard;
 
-       switch (add) {
+       switch (add & 0x1fffffff) {
                case 0x1f801040:
                        hard = sioRead8();
                        hard |= sioRead8() << 8;
@@ -355,7 +355,7 @@ u32 psxHwRead32(u32 add) {
 }
 
 void psxHwWrite8(u32 add, u8 value) {
-       switch (add) {
+       switch (add & 0x1fffffff) {
                case 0x1f801040: sioWrite8(value); break;\r
 #ifdef ENABLE_SIO1API
                case 0x1f801050: SIO1_writeData8(value); break;\r
@@ -379,7 +379,7 @@ void psxHwWrite8(u32 add, u8 value) {
 }
 
 void psxHwWrite16(u32 add, u16 value) {
-       switch (add) {
+       switch (add & 0x1fffffff) {
                case 0x1f801040:
                        sioWrite8((unsigned char)value);
                        sioWrite8((unsigned char)(value>>8));
@@ -518,7 +518,7 @@ void psxHwWrite16(u32 add, u16 value) {
 }
 
 void psxHwWrite32(u32 add, u32 value) {
-       switch (add) {
+       switch (add & 0x1fffffff) {
            case 0x1f801040:
                        sioWrite8((unsigned char)value);
                        sioWrite8((unsigned char)((value&0xff) >>  8));
index e59f93d..02e00a9 100644 (file)
@@ -49,6 +49,65 @@ void (*psxCP0[32])();
 void (*psxCP2[64])(struct psxCP2Regs *regs);
 void (*psxCP2BSC[32])();
 
+#ifdef ICACHE_EMULATION
+/*
+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)
+{
+       uint32_t pc_bank, pc_offset, pc_cache;
+       uint8_t *IAddr, *ICode;
+
+       pc_bank = pc >> 24;
+       pc_offset = pc & 0xffffff;
+       pc_cache = pc & 0xfff;
+
+       IAddr = ICache_Addr;
+       ICode = ICache_Code;
+
+       // cached - RAM
+       if (pc_bank == 0x80 || pc_bank == 0x00)
+       {
+               if (SWAP32(*(uint32_t *)(IAddr + pc_cache)) == pc_offset)
+               {
+                       // Cache hit - return last opcode used
+                       return (uint32_t *)(ICode + pc_cache);
+               }
+               else
+               {
+                       // Cache miss - addresses don't match
+                       // - default: 0xffffffff (not init)
+
+                       // cache line is 4 bytes wide
+                       pc_offset &= ~0xf;
+                       pc_cache &= ~0xf;
+
+                       // address line
+                       *(uint32_t *)(IAddr + pc_cache + 0x0) = SWAP32(pc_offset + 0x0);
+                       *(uint32_t *)(IAddr + pc_cache + 0x4) = SWAP32(pc_offset + 0x4);
+                       *(uint32_t *)(IAddr + pc_cache + 0x8) = SWAP32(pc_offset + 0x8);
+                       *(uint32_t *)(IAddr + pc_cache + 0xc) = SWAP32(pc_offset + 0xc);
+
+                       // opcode line
+                       pc_offset = pc & ~0xf;
+                       *(uint32_t *)(ICode + pc_cache + 0x0) = psxMu32ref(pc_offset + 0x0);
+                       *(uint32_t *)(ICode + pc_cache + 0x4) = psxMu32ref(pc_offset + 0x4);
+                       *(uint32_t *)(ICode + pc_cache + 0x8) = psxMu32ref(pc_offset + 0x8);
+                       *(uint32_t *)(ICode + pc_cache + 0xc) = psxMu32ref(pc_offset + 0xc);
+               }
+       }
+
+       /*
+       TODO: Probably should add cached BIOS
+       */
+       // default
+       return (uint32_t *)PSXM(pc);
+}
+#endif
+
 static void delayRead(int reg, u32 bpc) {
        u32 rold, rnew;
 
@@ -266,7 +325,17 @@ void psxDelayTest(int reg, u32 bpc) {
        u32 *code;
        u32 tmp;
 
-       code = (u32 *)PSXM(bpc);
+       #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));
        branch = 1;
 
@@ -290,7 +359,16 @@ static u32 psxBranchNoDelay(void) {
        u32 *code;
        u32 temp;
 
-       code = (u32 *)PSXM(psxRegs.pc);
+       #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));
        switch (_Op_) {
                case 0x00: // SPECIAL
@@ -419,7 +497,16 @@ static void doBranch(u32 tar) {
        if (psxDelayBranchTest(tar))
                return;
 
-       code = (u32 *)PSXM(psxRegs.pc);
+       #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));
 
        debugI();
@@ -554,7 +641,7 @@ void psxMULTU() {
 * Format:  OP rs, offset                                 *
 *********************************************************/
 #define RepZBranchi32(op)      if(_i32(_rRs_) op 0) doBranch(_BranchTarget_);
-#define RepZBranchLinki32(op)  if(_i32(_rRs_) op 0) { _SetLink(31); doBranch(_BranchTarget_); }
+#define RepZBranchLinki32(op)  { _SetLink(31); if(_i32(_rRs_) op 0) { doBranch(_BranchTarget_); } }
 
 void psxBGEZ()   { RepZBranchi32(>=) }      // Branch if Rs >= 0
 void psxBGEZAL() { RepZBranchLinki32(>=) }  // Branch if Rs >= 0 and link
@@ -575,9 +662,9 @@ void psxSRL() { if (!_Rd_) return; _u32(_rRd_) = _u32(_rRt_) >> _Sa_; } // Rd =
 * Shift arithmetic with variant register shift           *
 * Format:  OP rd, rt, rs                                 *
 *********************************************************/
-void psxSLLV() { if (!_Rd_) return; _u32(_rRd_) = _u32(_rRt_) << _u32(_rRs_); } // Rd = Rt << rs
-void psxSRAV() { if (!_Rd_) return; _i32(_rRd_) = _i32(_rRt_) >> _u32(_rRs_); } // Rd = Rt >> rs (arithmetic)
-void psxSRLV() { if (!_Rd_) return; _u32(_rRd_) = _u32(_rRt_) >> _u32(_rRs_); } // Rd = Rt >> rs (logical)
+void psxSLLV() { if (!_Rd_) return; _u32(_rRd_) = _u32(_rRt_) << (_u32(_rRs_) & 0x1F); } // Rd = Rt << rs
+void psxSRAV() { if (!_Rd_) return; _i32(_rRd_) = _i32(_rRt_) >> (_u32(_rRs_) & 0x1F); } // Rd = Rt >> rs (arithmetic)
+void psxSRLV() { if (!_Rd_) return; _u32(_rRd_) = _u32(_rRt_) >> (_u32(_rRs_) & 0x1F); } // Rd = Rt >> rs (logical)
 
 /*********************************************************
 * Load higher 16 bits of the first word in GPR with imm  *
@@ -604,7 +691,8 @@ void psxMTLO() { _rLo_ = _rRs_; } // Lo = Rs
 * Format:  OP                                            *
 *********************************************************/
 void psxBREAK() {
-       // Break exception - psx rom doens't handles this
+       psxRegs.pc -= 4;
+       psxException(0x24, branch);
 }
 
 void psxSYSCALL() {
@@ -616,6 +704,7 @@ void psxRFE() {
 //     SysPrintf("psxRFE\n");
        psxRegs.CP0.n.Status = (psxRegs.CP0.n.Status & 0xfffffff0) |
                                                  ((psxRegs.CP0.n.Status & 0x3c) >> 2);
+       psxTestSWInts();
 }
 
 /*********************************************************
@@ -639,14 +728,14 @@ void psxJAL() {   _SetLink(31); doBranch(_JumpTarget_); }
 * Format:  OP rs, rd                                     *
 *********************************************************/
 void psxJR()   {
-       doBranch(_u32(_rRs_));
+       doBranch(_rRs_ & ~3);
        psxJumpTest();
 }
 
 void psxJALR() {
        u32 temp = _u32(_rRs_);
        if (_Rd_) { _SetLink(_Rd_); }
-       doBranch(temp);
+       doBranch(temp & ~3);
 }
 
 /*********************************************************
@@ -923,10 +1012,38 @@ void (*psxCP2BSC[32])() = {
 ///////////////////////////////////////////
 
 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.
+        */
+       if (!ICache_Addr)
+       {
+               ICache_Addr = malloc(0x1000);
+               if (!ICache_Addr)
+               {
+                       return -1;
+               }
+       }
+
+       if (!ICache_Code)
+       {
+               ICache_Code = malloc(0x1000);
+               if (!ICache_Code)
+               {
+                       return -1;
+               }
+       }
+       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() {
@@ -943,12 +1060,46 @@ void intExecuteBlock() {
 static void intClear(u32 Addr, u32 Size) {
 }
 
+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
+}
+
 static void intShutdown() {
+       #ifdef ICACHE_EMULATION
+       if (ICache_Addr)
+       {
+               free(ICache_Addr);
+               ICache_Addr = NULL;
+       }
+
+       if (ICache_Code)
+       {
+               free(ICache_Code);
+               ICache_Code = NULL;
+       }
+       #endif
 }
 
 // interpreter execution
 void execI() {
-       u32 *code = (u32 *)PSXM(psxRegs.pc);
+       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));
 
        debugI();
@@ -967,5 +1118,8 @@ R3000Acpu psxInt = {
        intExecute,
        intExecuteBlock,
        intClear,
+#ifdef ICACHE_EMULATION
+       intNotify,
+#endif
        intShutdown
 };
index 61b14c6..171104c 100644 (file)
@@ -240,7 +240,7 @@ u8 psxMemRead8(u32 mem) {
 #ifdef PSXMEM_LOG
                        PSXMEM_LOG("err lb %8.8lx\n", mem);
 #endif
-                       return 0;
+                       return 0xFF;
                }
        }
 }
@@ -265,7 +265,7 @@ u16 psxMemRead16(u32 mem) {
 #ifdef PSXMEM_LOG
                        PSXMEM_LOG("err lh %8.8lx\n", mem);
 #endif
-                       return 0;
+                       return 0xFFFF;
                }
        }
 }
@@ -290,7 +290,7 @@ u32 psxMemRead32(u32 mem) {
 #ifdef PSXMEM_LOG
                        if (writeok) { PSXMEM_LOG("err lw %8.8lx\n", mem); }
 #endif
-                       return 0;
+                       return 0xFFFFFFFF;
                }
        }
 }
index 85b77cb..e21d488 100644 (file)
@@ -81,7 +81,21 @@ void psxShutdown() {
 }
 
 void psxException(u32 code, u32 bd) {
-       if (!Config.HLE && ((((psxRegs.code = PSXMu32(psxRegs.pc)) >> 24) & 0xfe) == 0x4a)) {
+       #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);
+       }
+       
+       if (!Config.HLE && ((((psxRegs.code) >> 24) & 0xfe) == 0x4a)) {
                // "hokuto no ken" / "Crash Bandicot 2" ...
                // BIOS does not allow to return to GTE instructions
                // (just skips it, supposedly because it's scheduled already)
@@ -98,7 +112,6 @@ void psxException(u32 code, u32 bd) {
 #ifdef PSXCPU_LOG
                PSXCPU_LOG("bd set!!!\n");
 #endif
-               SysPrintf("bd set!!!\n");
                psxRegs.CP0.n.Cause |= 0x80000000;
                psxRegs.CP0.n.EPC = (psxRegs.pc - 4);
        } else
index 399f9b6..4b1ec9e 100644 (file)
@@ -29,12 +29,24 @@ extern "C" {
 #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 (*Reset)();
        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 (*Shutdown)();
 } R3000Acpu;