From 27e8b5744ddab50cc9ef50b6ee1f3a94010a8cea Mon Sep 17 00:00:00 2001 From: "SND\\weimingzhi_cp" Date: Wed, 12 Jan 2011 02:51:29 +0000 Subject: - 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 --- libpcsxcore/cdriso.c | 60 ------------------------ libpcsxcore/cdrom.c | 26 +++++------ libpcsxcore/misc.c | 1 + libpcsxcore/ppf.c | 62 +++++++++++++++++++++++- libpcsxcore/ppf.h | 3 ++ libpcsxcore/psxinterpreter.c | 109 ++----------------------------------------- libpcsxcore/r3000a.c | 7 +-- libpcsxcore/r3000a.h | 76 +++++++++++++++++++++++++++++- 8 files changed, 157 insertions(+), 187 deletions(-) (limited to 'libpcsxcore') diff --git a/libpcsxcore/cdriso.c b/libpcsxcore/cdriso.c index f2746943..5c83990b 100644 --- a/libpcsxcore/cdriso.c +++ b/libpcsxcore/cdriso.c @@ -701,61 +701,6 @@ static int opensubfile(const char *isoname) { return 0; } -// redump.org SBI files -u8 sbitime[256][3]; -u8 sbicount; - -int opensbifile(const char *isoname) { - FILE *sbihandle; - char sbiname[MAXPATHLEN]; - - - // init - sbicount = 0; - - - // copy name of the iso and change extension from .img to .sbi - strncpy(sbiname, isoname, sizeof(sbiname)); - sbiname[MAXPATHLEN - 1] = '\0'; - if (strlen(sbiname) >= 4) { - strcpy(sbiname + strlen(sbiname) - 4, ".sbi"); - } - else { - return -1; - } - - sbihandle = fopen(sbiname, "rb"); - if (sbihandle == NULL) { - return -1; - } - - - // 4-byte SBI header - fread( sbiname, 1, 4, sbihandle ); - while( !feof(sbihandle) ) { - u8 subq[11]; - fread( sbitime[ sbicount++ ], 1, 3, sbihandle ); - fread( subq, 1, 11, sbihandle ); - } - - - return 0; -} - -int checkSBI(u8 *time) { - int lcv; - - // both BCD format - for( lcv=0; lcv. + * Copyright (c) 2010, shalma. * - * Based on P.E.Op.S CDR Plugin by Pete Bernert. + * PPF code based on P.E.Op.S CDR Plugin by Pete Bernert. * Copyright (c) 2002, Pete Bernert. * * This program is free software; you can redistribute it and/or modify @@ -330,3 +331,60 @@ void BuildPPFCache() { SysPrintf(_("Loaded PPF %d.0 patch: %s.\n"), method + 1, szPPF); } + +// redump.org SBI files +static u8 sbitime[256][3], sbicount; + +void LoadSBI() { + FILE *sbihandle; + char buffer[16], sbifile[MAXPATHLEN]; + + // Generate filename in the format of SLUS_123.45.sbi + buffer[0] = toupper(CdromId[0]); + buffer[1] = toupper(CdromId[1]); + buffer[2] = toupper(CdromId[2]); + buffer[3] = toupper(CdromId[3]); + buffer[4] = '_'; + buffer[5] = CdromId[4]; + buffer[6] = CdromId[5]; + buffer[7] = CdromId[6]; + buffer[8] = '.'; + buffer[9] = CdromId[7]; + buffer[10] = CdromId[8]; + buffer[11] = '.'; + buffer[12] = 's'; + buffer[13] = 'b'; + buffer[14] = 'i'; + buffer[15] = '\0'; + + sprintf(sbifile, "%s%s", Config.PatchesDir, buffer); + + // init + sbicount = 0; + + sbihandle = fopen(sbifile, "rb"); + if (sbihandle == NULL) return; + + // 4-byte SBI header + fseek(sbihandle, 4, SEEK_SET); + while (!feof(sbihandle)) { + fread(sbitime[sbicount++], 1, 3, sbihandle); + fseek(sbihandle, 11, SEEK_CUR); + } + + SysPrintf(_("Loaded SBI file: %s.\n"), sbifile); +} + +boolean CheckSBI(const u8 *time) { + int lcv; + + // both BCD format + for (lcv = 0; lcv < sbicount; lcv++) { + if (time[0] == sbitime[lcv][0] && + time[1] == sbitime[lcv][1] && + time[2] == sbitime[lcv][2]) + return TRUE; + } + + return FALSE; +} diff --git a/libpcsxcore/ppf.h b/libpcsxcore/ppf.h index f578028b..a8adecbb 100644 --- a/libpcsxcore/ppf.h +++ b/libpcsxcore/ppf.h @@ -27,6 +27,9 @@ void BuildPPFCache(); void FreePPFCache(); void CheckPPFCache(unsigned char *pB, unsigned char m, unsigned char s, unsigned char f); +void LoadSBI(); +boolean CheckSBI(const u8 *time); + #ifdef __cplusplus } #endif diff --git a/libpcsxcore/psxinterpreter.c b/libpcsxcore/psxinterpreter.c index 1ddc73cd..77791897 100644 --- a/libpcsxcore/psxinterpreter.c +++ b/libpcsxcore/psxinterpreter.c @@ -47,102 +47,6 @@ void (*psxREG[32])(); void (*psxCP0[32])(); void (*psxCP2[64])(); void (*psxCP2BSC[32])(); - -/* -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 -*/ - -u32 *Read_ICache( u32 pc, u32 isolate ) -{ -#define U32_PTR(x) (SWAP32(* (u32 *)(x))) -#define U32_PTR_REF(x) (* (u32 *)(x)) - - - 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; - - - //return PSXM(pc); - - - - // clear I-cache - if( psxRegs.ICache_valid == 0 ) - { - memset( psxRegs.ICache_Addr, 0xff, sizeof(psxRegs.ICache_Addr) ); - memset( psxRegs.ICache_Code, 0xff, sizeof(psxRegs.ICache_Code) ); - - psxRegs.ICache_valid = 1; - } - - - - // uncached - if( pc_bank >= 0xa0 ) - return PSXM(pc); - - - // cached - RAM - if( pc_bank == 0x80 || pc_bank == 0x00 ) - { - if( U32_PTR( 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 == 0 ) - { - // cache line is 4 bytes wide - pc_offset &= ~0xf; - pc_cache &= ~0xf; - - // address line - U32_PTR_REF( IAddr + pc_cache + 0x0 ) = pc_offset + 0x0; - U32_PTR_REF( IAddr + pc_cache + 0x4 ) = pc_offset + 0x4; - U32_PTR_REF( IAddr + pc_cache + 0x8 ) = pc_offset + 0x8; - U32_PTR_REF( IAddr + pc_cache + 0xc ) = pc_offset + 0xc; - - // opcode line - pc_offset = pc & ~0xf; - U32_PTR_REF( ICode + pc_cache + 0x0 ) = psxMu32( pc_offset + 0x0 ); - U32_PTR_REF( ICode + pc_cache + 0x4 ) = psxMu32( pc_offset + 0x4 ); - U32_PTR_REF( ICode + pc_cache + 0x8 ) = psxMu32( pc_offset + 0x8 ); - U32_PTR_REF( ICode + pc_cache + 0xc ) = psxMu32( pc_offset + 0xc ); - } - - // normal code - return PSXM(pc); - } - } - - - /* - TODO: Probably should add cached BIOS - */ - - - // default - return PSXM(pc); -} - static void delayRead(int reg, u32 bpc) { u32 rold, rnew; @@ -362,8 +266,7 @@ void psxDelayTest(int reg, u32 bpc) { u32 tmp; // Don't execute yet - just peek - //code = (u32 *)PSXM(bpc); - code = Read_ICache(bpc,1); + code = Read_ICache(bpc, TRUE); tmp = ((code == NULL) ? 0 : SWAP32(*code)); branch = 1; @@ -392,8 +295,7 @@ __inline void doBranch(u32 tar) { branchPC = tar; // branch delay slot - //code = (u32 *)PSXM(psxRegs.pc); - code = Read_ICache( psxRegs.pc, 1 ); + code = Read_ICache(psxRegs.pc, TRUE); psxRegs.code = ((code == NULL) ? 0 : SWAP32(*code)); @@ -1039,7 +941,7 @@ static int intInit() { } static void intReset() { - psxRegs.ICache_valid = 0; + psxRegs.ICache_valid = FALSE; } static void intExecute() { @@ -1059,9 +961,8 @@ static void intShutdown() { } // interpreter execution -inline void execI() { - //u32 *code = (u32 *)PSXM(psxRegs.pc); - u32 *code = Read_ICache( psxRegs.pc,0 ); +inline void execI() { + u32 *code = Read_ICache(psxRegs.pc, FALSE); psxRegs.code = ((code == NULL) ? 0 : SWAP32(*code)); debugI(); diff --git a/libpcsxcore/r3000a.c b/libpcsxcore/r3000a.c index bcae44ef..1422d52f 100644 --- a/libpcsxcore/r3000a.c +++ b/libpcsxcore/r3000a.c @@ -25,10 +25,7 @@ #include "cdrom.h" #include "mdec.h" #include "gpu.h" -#include "gte.h" - -extern u32 *Read_ICache( u32 pc, u32 isolate ); - +#include "gte.h" R3000Acpu *psxCpu = NULL; psxRegisters psxRegs; @@ -116,7 +113,7 @@ void psxBranchTest() { u32 opcode; // Crash Bandicoot 2: Don't run exceptions when GTE in pipeline - opcode = *Read_ICache( psxRegs.pc, 1 ); + opcode = SWAP32(*Read_ICache(psxRegs.pc, TRUE)); if( ((opcode >> 24) & 0xfe) != 0x4a ) { #ifdef PSXCPU_LOG PSXCPU_LOG("Interrupt: %x %x\n", psxHu32(0x1070), psxHu32(0x1074)); 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 -- cgit v1.2.3