diff options
| author | SND\weimingzhi_cp <SND\weimingzhi_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97> | 2011-01-12 02:51:29 +0000 |
|---|---|---|
| committer | SND\weimingzhi_cp <SND\weimingzhi_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97> | 2011-01-12 02:51:29 +0000 |
| commit | 27e8b5744ddab50cc9ef50b6ee1f3a94010a8cea (patch) | |
| tree | c38e3e5475e499b769368cb34129c70f1e2a36f8 /libpcsxcore/r3000a.h | |
| parent | 9bbb363c552598dcec7d17c7e6386a6f405edcab (diff) | |
| download | pcsxr-27e8b5744ddab50cc9ef50b6ee1f3a94010a8cea.tar.gz | |
- Added -slowboot parameter.
- Load SBI file from patches/SLUS_xxx.xx.sbi instead.
- Inlined the I-cache code for performance improvement.
- Fixed endianness issue (not tested).
git-svn-id: https://pcsxr.svn.codeplex.com/svn/pcsxr@62024 e17a0e51-4ae3-4d35-97c3-1a29b211df97
Diffstat (limited to 'libpcsxcore/r3000a.h')
| -rw-r--r-- | libpcsxcore/r3000a.h | 76 |
1 files changed, 75 insertions, 1 deletions
diff --git a/libpcsxcore/r3000a.h b/libpcsxcore/r3000a.h index 8d5fd618..3547069e 100644 --- a/libpcsxcore/r3000a.h +++ b/libpcsxcore/r3000a.h @@ -173,11 +173,85 @@ typedef struct { struct { u32 sCycle, cycle; } intCycle[32]; u8 ICache_Addr[0x1000]; u8 ICache_Code[0x1000]; - u32 ICache_valid; + boolean ICache_valid; } psxRegisters; extern psxRegisters psxRegs; +/*
+Formula One 2001
+- Use old CPU cache code when the RAM location is
+ updated with new code (affects in-game racing)
+
+TODO:
+- I-cache / D-cache swapping
+- Isolate D-cache from RAM
+*/
+
+static inline u32 *Read_ICache(u32 pc, boolean isolate) {
+ u32 pc_bank, pc_offset, pc_cache;
+ u8 *IAddr, *ICode;
+
+ pc_bank = pc >> 24;
+ pc_offset = pc & 0xffffff;
+ pc_cache = pc & 0xfff;
+
+ IAddr = psxRegs.ICache_Addr;
+ ICode = psxRegs.ICache_Code;
+
+ // clear I-cache
+ if (!psxRegs.ICache_valid) {
+ memset(psxRegs.ICache_Addr, 0xff, sizeof(psxRegs.ICache_Addr));
+ memset(psxRegs.ICache_Code, 0xff, sizeof(psxRegs.ICache_Code));
+
+ psxRegs.ICache_valid = TRUE;
+ }
+
+ // uncached
+ if (pc_bank >= 0xa0)
+ return PSXM(pc);
+
+ // cached - RAM
+ if (pc_bank == 0x80 || pc_bank == 0x00) {
+ if (SWAP32(*(u32 *)(IAddr + pc_cache)) == pc_offset) {
+ // Cache hit - return last opcode used
+ return ICode + pc_cache;
+ } else {
+ // Cache miss - addresses don't match
+ // - default: 0xffffffff (not init)
+
+ if (!isolate) {
+ // cache line is 4 bytes wide
+ pc_offset &= ~0xf;
+ pc_cache &= ~0xf;
+
+ // address line
+ *(u32 *)(IAddr + pc_cache + 0x0) = SWAP32(pc_offset + 0x0);
+ *(u32 *)(IAddr + pc_cache + 0x4) = SWAP32(pc_offset + 0x4);
+ *(u32 *)(IAddr + pc_cache + 0x8) = SWAP32(pc_offset + 0x8);
+ *(u32 *)(IAddr + pc_cache + 0xc) = SWAP32(pc_offset + 0xc);
+
+ // opcode line
+ pc_offset = pc & ~0xf;
+ *(u32 *)(ICode + pc_cache + 0x0) = psxMu32(pc_offset + 0x0);
+ *(u32 *)(ICode + pc_cache + 0x4) = psxMu32(pc_offset + 0x4);
+ *(u32 *)(ICode + pc_cache + 0x8) = psxMu32(pc_offset + 0x8);
+ *(u32 *)(ICode + pc_cache + 0xc) = psxMu32(pc_offset + 0xc);
+ }
+
+ // normal code
+ return PSXM(pc);
+ }
+ }
+
+ /*
+ TODO: Probably should add cached BIOS
+ */
+
+ // default
+ return PSXM(pc);
+}
+ #if defined(__BIGENDIAN__) #define _i32(x) *(s32 *)&x |
