diff --git a/Core/Config.cpp b/Core/Config.cpp index fbf4917493..1cee99b0a9 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -172,6 +172,7 @@ void Config::Load(const char *iniFileName) debugConfig->Get("ConsoleWindowY", &iConsoleWindowY, -1); debugConfig->Get("FontWidth", &iFontWidth, 8); debugConfig->Get("FontHeight", &iFontHeight, 12); + debugConfig->Get("DisplayStatusBar", &bDisplayStatusBar, true); IniFile::Section *gleshacks = iniFile.GetOrCreateSection("GLESHacks"); gleshacks->Get("PrescaleUV", &bPrescaleUV, false); @@ -288,6 +289,7 @@ void Config::Save() debugConfig->Set("ConsoleWindowY", iConsoleWindowY); debugConfig->Set("FontWidth", iFontWidth); debugConfig->Set("FontHeight", iFontHeight); + debugConfig->Set("DisplayStatusBar", bDisplayStatusBar); KeyMap::SaveToIni(iniFile); diff --git a/Core/Config.h b/Core/Config.h index b226ed5014..a75424494d 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -149,6 +149,7 @@ public: int iConsoleWindowY; int iFontWidth; int iFontHeight; + bool bDisplayStatusBar; std::string currentDirectory; std::string externalDirectory; diff --git a/Core/FileSystems/VirtualDiscFileSystem.cpp b/Core/FileSystems/VirtualDiscFileSystem.cpp index 9c23c245b1..cc1c47e5df 100644 --- a/Core/FileSystems/VirtualDiscFileSystem.cpp +++ b/Core/FileSystems/VirtualDiscFileSystem.cpp @@ -498,9 +498,9 @@ bool VirtualDiscFileSystem::OwnsHandle(u32 handle) { PSPFileInfo VirtualDiscFileSystem::GetFileInfo(std::string filename) { PSPFileInfo x; x.name = filename; + x.access = FILEACCESS_READ; - if (filename.compare(0,8,"/sce_lbn") == 0) - { + if (filename.compare(0,8,"/sce_lbn") == 0) { u32 sectorStart = 0xFFFFFFFF, readSize = 0xFFFFFFFF; parseLBN(filename, §orStart, &readSize); @@ -517,10 +517,11 @@ PSPFileInfo VirtualDiscFileSystem::GetFileInfo(std::string filename) { int fileIndex = getFileListIndex(filename); if (fileIndex != -1 && fileList[fileIndex].handler != NULL) { x.type = FILETYPE_NORMAL; + x.isOnSectorSystem = true; + x.startSector = fileList[fileIndex].firstBlock; HandlerFileHandle temp; - if (temp.Open(basePath, filename, FILEACCESS_READ)) - { + if (temp.Open(basePath, filename, FILEACCESS_READ)) { x.exists = true; x.size = temp.Seek(0, FILEMOVE_END); temp.Close(); @@ -546,9 +547,12 @@ PSPFileInfo VirtualDiscFileSystem::GetFileInfo(std::string filename) { x.type = File::IsDirectory(fullName) ? FILETYPE_DIRECTORY : FILETYPE_NORMAL; x.exists = true; + if (fileIndex != -1) { + x.isOnSectorSystem = true; + x.startSector = fileList[fileIndex].firstBlock; + } - if (x.type != FILETYPE_DIRECTORY) - { + if (x.type != FILETYPE_DIRECTORY) { struct stat s; stat(fullName.c_str(), &s); @@ -558,7 +562,6 @@ PSPFileInfo VirtualDiscFileSystem::GetFileInfo(std::string filename) { x.startSector = fileList[fileIndex].firstBlock; x.numSectors = (x.size+2047)/2048; - x.access = s.st_mode & 0x1FF; localtime_r((time_t*)&s.st_atime,&x.atime); localtime_r((time_t*)&s.st_ctime,&x.ctime); localtime_r((time_t*)&s.st_mtime,&x.mtime); @@ -621,6 +624,10 @@ std::vector VirtualDiscFileSystem::GetDirListing(std::string path) tmFromFiletime(entry.atime, findData.ftLastAccessTime); tmFromFiletime(entry.ctime, findData.ftCreationTime); tmFromFiletime(entry.mtime, findData.ftLastWriteTime); + entry.isOnSectorSystem = true; + int fileIndex = getFileListIndex(entry.name); + if (fileIndex != -1) + entry.startSector = fileList[fileIndex].firstBlock; myVector.push_back(entry); } #else @@ -660,6 +667,10 @@ std::vector VirtualDiscFileSystem::GetDirListing(std::string path) localtime_r((time_t*)&s.st_atime,&entry.atime); localtime_r((time_t*)&s.st_ctime,&entry.ctime); localtime_r((time_t*)&s.st_mtime,&entry.mtime); + entry.isOnSectorSystem = true; + int fileIndex = getFileListIndex(entry.name); + if (fileIndex != -1) + entry.startSector = fileList[fileIndex].firstBlock; myVector.push_back(entry); } closedir(dp); diff --git a/Core/HLE/sceDisplay.cpp b/Core/HLE/sceDisplay.cpp index 3780819525..ea0695bdd5 100644 --- a/Core/HLE/sceDisplay.cpp +++ b/Core/HLE/sceDisplay.cpp @@ -23,32 +23,24 @@ // and move everything into native... #include "base/timeutil.h" -#include "Thread.h" -#include "../Core/CoreTiming.h" -#include "../Core/CoreParameter.h" +#include "Common/Thread.h" +#include "Core/CoreTiming.h" +#include "Core/CoreParameter.h" #include "Core/Reporting.h" -#include "../MIPS/MIPS.h" -#include "../HLE/HLE.h" -#include "sceAudio.h" -#include "../Host.h" -#include "../Config.h" -#include "../System.h" -#include "../Core/Core.h" -#include "sceDisplay.h" -#include "sceKernel.h" -#include "sceKernelThread.h" -#include "sceKernelInterrupt.h" +#include "Core/Config.h" +#include "Core/System.h" +#include "Core/HLE/HLE.h" +#include "Core/HLE/sceDisplay.h" +#include "Core/HLE/sceKernel.h" +#include "Core/HLE/sceKernelThread.h" +#include "Core/HLE/sceKernelInterrupt.h" -// TODO: This file should not depend directly on GLES code. -#include "../../GPU/GLES/Framebuffer.h" -#include "../../GPU/GLES/ShaderManager.h" -#include "../../GPU/GLES/TextureCache.h" -#include "../../GPU/GPUState.h" -#include "../../GPU/GPUInterface.h" +#include "GPU/GPUState.h" +#include "GPU/GPUInterface.h" struct FrameBufferState { u32 topaddr; - PspDisplayPixelFormat pspFramebufFormat; + GEBufferFormat pspFramebufFormat; int pspFramebufLinesize; }; @@ -135,7 +127,7 @@ void __DisplayInit() { numSkippedFrames = 0; framebufIsLatched = false; framebuf.topaddr = 0x04000000; - framebuf.pspFramebufFormat = PSP_DISPLAY_PIXEL_FORMAT_8888; + framebuf.pspFramebufFormat = GE_FORMAT_8888; framebuf.pspFramebufLinesize = 480; // ?? lastFlipCycles = 0; @@ -501,7 +493,7 @@ u32 sceDisplaySetFramebuf(u32 topaddr, int linesize, int pixelformat, int sync) DEBUG_LOG(HLE,"- screen off"); } else { fbstate.topaddr = topaddr; - fbstate.pspFramebufFormat = (PspDisplayPixelFormat)pixelformat; + fbstate.pspFramebufFormat = (GEBufferFormat)pixelformat; fbstate.pspFramebufLinesize = linesize; } diff --git a/Core/HLE/sceGe.cpp b/Core/HLE/sceGe.cpp index d41ecfae48..ead492db14 100644 --- a/Core/HLE/sceGe.cpp +++ b/Core/HLE/sceGe.cpp @@ -332,13 +332,13 @@ u32 sceGeSetCallback(u32 structAddr) int subIntrBase = __GeSubIntrBase(cbID); - if (ge_callback_data[cbID].finish_func) + if (ge_callback_data[cbID].finish_func != 0) { sceKernelRegisterSubIntrHandler(PSP_GE_INTR, subIntrBase | PSP_GE_SUBINTR_FINISH, ge_callback_data[cbID].finish_func, ge_callback_data[cbID].finish_arg); sceKernelEnableSubIntr(PSP_GE_INTR, subIntrBase | PSP_GE_SUBINTR_FINISH); } - if (ge_callback_data[cbID].signal_func) + if (ge_callback_data[cbID].signal_func != 0) { sceKernelRegisterSubIntrHandler(PSP_GE_INTR, subIntrBase | PSP_GE_SUBINTR_SIGNAL, ge_callback_data[cbID].signal_func, ge_callback_data[cbID].signal_arg); diff --git a/Core/HLE/sceGe.h b/Core/HLE/sceGe.h index 9659ed0b93..e11db00ed2 100644 --- a/Core/HLE/sceGe.h +++ b/Core/HLE/sceGe.h @@ -28,13 +28,13 @@ // typedef void (*PspGeCallback)(int id, void *arg); -typedef struct PspGeCallbackData +struct PspGeCallbackData { - u32 signal_func; - u32 signal_arg; //ptr - u32 finish_func; // PspGeCallback - u32 finish_arg; -} PspGeCallbackData; + u32_le signal_func; + u32_le signal_arg; //ptr + u32_le finish_func; // PspGeCallback + u32_le finish_arg; +}; void Register_sceGe_user(); diff --git a/Core/MIPS/MIPSAnalyst.cpp b/Core/MIPS/MIPSAnalyst.cpp index bd395a6e9d..8287c6d7a0 100644 --- a/Core/MIPS/MIPSAnalyst.cpp +++ b/Core/MIPS/MIPSAnalyst.cpp @@ -23,6 +23,7 @@ #include "MIPSAnalyst.h" #include "MIPSCodeUtils.h" #include "../Debugger/SymbolMap.h" +#include "../Debugger/DebugInterface.h" using namespace MIPSCodeUtils; using namespace std; @@ -530,4 +531,124 @@ namespace MIPSAnalyst } return vec; } + + MipsOpcodeInfo GetOpcodeInfo(DebugInterface* cpu, u32 address) + { + MipsOpcodeInfo info; + memset(&info,0,sizeof(info)); + + info.cpu = cpu; + info.opcodeAddress = address; + info.encodedOpcode = Memory::Read_Instruction(address); + + u32 op = info.encodedOpcode; + u32 opInfo = MIPSGetInfo(op); + info.isLikelyBranch = (opInfo & LIKELY) != 0; + + //j , jal, ... + if (opInfo & IS_JUMP) + { + info.isBranch = true; + if (opInfo & OUT_RA) // link + { + info.isLinkedBranch = true; + } + + if (opInfo & IN_RS) // to register + { + info.isBranchToRegister = true; + info.branchRegisterNum = MIPS_GET_RS(op); + info.branchTarget = cpu->GetRegValue(0,info.branchRegisterNum); + } else { // to immediate + info.branchTarget = GetJumpTarget(address); + } + } + + // movn, movz + if (opInfo & IS_CONDMOVE) + { + info.isConditional = true; + + u32 rt = cpu->GetRegValue(0,MIPS_GET_RT(op)); + switch (opInfo & CONDTYPE_MASK) + { + case CONDTYPE_EQ: + info.conditionMet = (rt == 0); + break; + case CONDTYPE_NE: + info.conditionMet = (rt != 0); + break; + } + } + + // beq, bgtz, ... + if (opInfo & IS_CONDBRANCH) + { + info.isBranch = true; + info.isConditional = true; + info.branchTarget = GetBranchTarget(address); + + if (opInfo & OUT_RA) // link + { + info.isLinkedBranch = true; + } + + u32 rt = cpu->GetRegValue(0,MIPS_GET_RT(op)); + u32 rs = cpu->GetRegValue(0,MIPS_GET_RS(op)); + switch (opInfo & CONDTYPE_MASK) + { + case CONDTYPE_EQ: + info.conditionMet = (rt == rs); + if (MIPS_GET_RT(op) == MIPS_GET_RS(op)) // always true + { + info.isConditional = false; + } + break; + case CONDTYPE_NE: + info.conditionMet = (rt != rs); + if (MIPS_GET_RT(op) == MIPS_GET_RS(op)) // always true + { + info.isConditional = false; + } + break; + case CONDTYPE_LEZ: + info.conditionMet = (((s32)rs) <= 0); + break; + case CONDTYPE_GTZ: + info.conditionMet = (((s32)rs) > 0); + break; + case CONDTYPE_LTZ: + info.conditionMet = (((s32)rs) < 0); + break; + case CONDTYPE_GEZ: + info.conditionMet = (((s32)rs) >= 0); + break; + } + } + + // lw, sh, ... + if ((opInfo & IN_MEM) || (opInfo & OUT_MEM)) + { + info.isDataAccess = true; + + switch (opInfo & MEMTYPE_MASK) + { + case MEMTYPE_BYTE: + info.dataSize = 1; + break; + case MEMTYPE_HWORD: + info.dataSize = 2; + break; + case MEMTYPE_WORD: + info.dataSize = 4; + break; + } + + u32 rs = cpu->GetRegValue(0,MIPS_GET_RS(op)); + s16 imm16 = op & 0xFFFF; + info.dataAddress = rs + imm16; + } + + return info; + } } diff --git a/Core/MIPS/MIPSAnalyst.h b/Core/MIPS/MIPSAnalyst.h index 68d8202faa..7167e8287a 100644 --- a/Core/MIPS/MIPSAnalyst.h +++ b/Core/MIPS/MIPSAnalyst.h @@ -19,6 +19,8 @@ #include "../../Globals.h" +class DebugInterface; + namespace MIPSAnalyst { void Analyze(u32 address); @@ -63,5 +65,31 @@ namespace MIPSAnalyst bool IsSyscall(u32 op); void Shutdown(); + + typedef struct + { + DebugInterface* cpu; + u32 opcodeAddress; + u32 encodedOpcode; + + // shared between branches and conditional moves + bool isConditional; + bool conditionMet; + + // branches + u32 branchTarget; + bool isBranch; + bool isLinkedBranch; + bool isLikelyBranch; + bool isBranchToRegister; + int branchRegisterNum; + + // data access + bool isDataAccess; + int dataSize; + u32 dataAddress; + } MipsOpcodeInfo; + + MipsOpcodeInfo GetOpcodeInfo(DebugInterface* cpu, u32 address); } // namespace MIPSAnalyst diff --git a/Core/MIPS/MIPSCodeUtils.cpp b/Core/MIPS/MIPSCodeUtils.cpp index 7701c682f9..9d5c0444a9 100644 --- a/Core/MIPS/MIPSCodeUtils.cpp +++ b/Core/MIPS/MIPSCodeUtils.cpp @@ -32,8 +32,8 @@ namespace MIPSCodeUtils u32 op = Memory::Read_Instruction(addr); if (op) { - op &= 0xFC000000; - if (op == 0x0C000000 || op == 0x08000000) //jal + u32 maskedOp = op & 0xFC000000; + if (maskedOp == 0x0C000000 || maskedOp == 0x08000000) //jal { u32 target = (addr & 0xF0000000) | ((op&0x03FFFFFF) << 2); return target; @@ -53,7 +53,7 @@ namespace MIPSCodeUtils u32 info = MIPSGetInfo(op); if (info & IS_CONDBRANCH) { - return addr + ((signed short)(op&0xFFFF)<<2); + return addr + 4 + ((signed short)(op&0xFFFF)<<2); } else return INVALIDTARGET; @@ -70,7 +70,7 @@ namespace MIPSCodeUtils u32 info = MIPSGetInfo(op); if ((info & IS_CONDBRANCH) && !(info & OUT_RA)) { - return addr + ((signed short)(op&0xFFFF)<<2); + return addr + 4 + ((signed short)(op&0xFFFF)<<2); } else return INVALIDTARGET; diff --git a/Core/MIPS/MIPSCodeUtils.h b/Core/MIPS/MIPSCodeUtils.h index 55741aab90..014457a429 100644 --- a/Core/MIPS/MIPSCodeUtils.h +++ b/Core/MIPS/MIPSCodeUtils.h @@ -36,6 +36,10 @@ #define MIPS_MAKE_SYSCALL(module, function) GetSyscallOp(module, GetNibByName(module, function)) #define MIPS_MAKE_BREAK() (13) // ! :) +#define MIPS_GET_OP(op) ((op>>26) & 0x3F) +#define MIPS_GET_FUNC(op) (op & 0x3F) +#define MIPS_GET_SA(op) (op>>6 & 0x1F) + #define MIPS_GET_RS(op) ((op>>21) & 0x1F) #define MIPS_GET_RT(op) ((op>>16) & 0x1F) #define MIPS_GET_RD(op) ((op>>11) & 0x1F) diff --git a/Core/MIPS/MIPSInt.cpp b/Core/MIPS/MIPSInt.cpp index c9e1fe1039..d2175c3620 100644 --- a/Core/MIPS/MIPSInt.cpp +++ b/Core/MIPS/MIPSInt.cpp @@ -50,7 +50,6 @@ #define HI currentMIPS->hi #define LO currentMIPS->lo - static inline void DelayBranchTo(u32 where) { PC += 4; diff --git a/Core/MIPS/MIPSInt.h b/Core/MIPS/MIPSInt.h index d68fce176e..7f7ad7d1c1 100644 --- a/Core/MIPS/MIPSInt.h +++ b/Core/MIPS/MIPSInt.h @@ -22,7 +22,6 @@ u32 MIPS_GetNextPC(); void MIPS_ClearDelaySlot(); int MIPS_SingleStep(); -float round_ieee_754(float num); namespace MIPSInt { diff --git a/Core/MIPS/MIPSTables.cpp b/Core/MIPS/MIPSTables.cpp index 1d722afe2c..f2e2ea42d2 100644 --- a/Core/MIPS/MIPSTables.cpp +++ b/Core/MIPS/MIPSTables.cpp @@ -94,10 +94,10 @@ const MIPSInstruction tableImmediate[64] = //xxxxxx ..... ENCODING(RegI), INSTR("j", &Jit::Comp_Jump, Dis_JumpType, Int_JumpType, IS_JUMP|IN_IMM26|DELAYSLOT), INSTR("jal", &Jit::Comp_Jump, Dis_JumpType, Int_JumpType, IS_JUMP|IN_IMM26|OUT_RA|DELAYSLOT), - INSTR("beq", &Jit::Comp_RelBranch, Dis_RelBranch2, Int_RelBranch, IS_CONDBRANCH|IN_RS|IN_RT|DELAYSLOT), - INSTR("bne", &Jit::Comp_RelBranch, Dis_RelBranch2, Int_RelBranch, IS_CONDBRANCH|IN_RS|IN_RT|DELAYSLOT), - INSTR("blez", &Jit::Comp_RelBranch, Dis_RelBranch, Int_RelBranch, IS_CONDBRANCH|IN_RS|DELAYSLOT), - INSTR("bgtz", &Jit::Comp_RelBranch, Dis_RelBranch, Int_RelBranch, IS_CONDBRANCH|IN_RS|DELAYSLOT), + INSTR("beq", &Jit::Comp_RelBranch, Dis_RelBranch2, Int_RelBranch, IS_CONDBRANCH|IN_RS|IN_RT|DELAYSLOT|CONDTYPE_EQ), + INSTR("bne", &Jit::Comp_RelBranch, Dis_RelBranch2, Int_RelBranch, IS_CONDBRANCH|IN_RS|IN_RT|DELAYSLOT|CONDTYPE_NE), + INSTR("blez", &Jit::Comp_RelBranch, Dis_RelBranch, Int_RelBranch, IS_CONDBRANCH|IN_RS|DELAYSLOT|CONDTYPE_LEZ), + INSTR("bgtz", &Jit::Comp_RelBranch, Dis_RelBranch, Int_RelBranch, IS_CONDBRANCH|IN_RS|DELAYSLOT|CONDTYPE_GTZ), //8 INSTR("addi", &Jit::Comp_IType, Dis_addi, Int_IType, IN_RS|IN_IMM16|OUT_RT), INSTR("addiu", &Jit::Comp_IType, Dis_addi, Int_IType, IN_RS|IN_IMM16|OUT_RT), @@ -113,10 +113,10 @@ const MIPSInstruction tableImmediate[64] = //xxxxxx ..... ENCODING(Cop2), //cop2 INVALID, //copU - INSTR("beql", &Jit::Comp_RelBranch, Dis_RelBranch2, Int_RelBranch, IS_CONDBRANCH|IN_RS|IN_RT|DELAYSLOT|LIKELY), //L = likely - INSTR("bnel", &Jit::Comp_RelBranch, Dis_RelBranch2, Int_RelBranch, IS_CONDBRANCH|IN_RS|IN_RT|DELAYSLOT|LIKELY), - INSTR("blezl", &Jit::Comp_RelBranch, Dis_RelBranch, Int_RelBranch, IS_CONDBRANCH|IN_RS|DELAYSLOT|LIKELY), - INSTR("bgtzl", &Jit::Comp_RelBranch, Dis_RelBranch, Int_RelBranch, IS_CONDBRANCH|IN_RS|DELAYSLOT|LIKELY), + INSTR("beql", &Jit::Comp_RelBranch, Dis_RelBranch2, Int_RelBranch, IS_CONDBRANCH|IN_RS|IN_RT|DELAYSLOT|LIKELY|CONDTYPE_EQ), //L = likely + INSTR("bnel", &Jit::Comp_RelBranch, Dis_RelBranch2, Int_RelBranch, IS_CONDBRANCH|IN_RS|IN_RT|DELAYSLOT|LIKELY|CONDTYPE_NE), + INSTR("blezl", &Jit::Comp_RelBranch, Dis_RelBranch, Int_RelBranch, IS_CONDBRANCH|IN_RS|DELAYSLOT|LIKELY|CONDTYPE_LEZ), + INSTR("bgtzl", &Jit::Comp_RelBranch, Dis_RelBranch, Int_RelBranch, IS_CONDBRANCH|IN_RS|DELAYSLOT|LIKELY|CONDTYPE_GTZ), //24 {VFPU0}, {VFPU1}, @@ -127,22 +127,22 @@ const MIPSInstruction tableImmediate[64] = //xxxxxx ..... {-2}, {Spe3},//special3 //32 - INSTR("lb", &Jit::Comp_ITypeMem, Dis_ITypeMem, Int_ITypeMem, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_RT), - INSTR("lh", &Jit::Comp_ITypeMem, Dis_ITypeMem, Int_ITypeMem, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_RT), - INSTR("lwl", &Jit::Comp_ITypeMem, Dis_ITypeMem, Int_ITypeMem, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_RT), - INSTR("lw", &Jit::Comp_ITypeMem, Dis_ITypeMem, Int_ITypeMem, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_RT), - INSTR("lbu", &Jit::Comp_ITypeMem, Dis_ITypeMem, Int_ITypeMem, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_RT), - INSTR("lhu", &Jit::Comp_ITypeMem, Dis_ITypeMem, Int_ITypeMem, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_RT), - INSTR("lwr", &Jit::Comp_ITypeMem, Dis_ITypeMem, Int_ITypeMem, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_RT), + INSTR("lb", &Jit::Comp_ITypeMem, Dis_ITypeMem, Int_ITypeMem, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_RT|MEMTYPE_BYTE), + INSTR("lh", &Jit::Comp_ITypeMem, Dis_ITypeMem, Int_ITypeMem, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_RT|MEMTYPE_HWORD), + INSTR("lwl", &Jit::Comp_ITypeMem, Dis_ITypeMem, Int_ITypeMem, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_RT|MEMTYPE_WORD), + INSTR("lw", &Jit::Comp_ITypeMem, Dis_ITypeMem, Int_ITypeMem, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_RT|MEMTYPE_WORD), + INSTR("lbu", &Jit::Comp_ITypeMem, Dis_ITypeMem, Int_ITypeMem, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_RT|MEMTYPE_BYTE), + INSTR("lhu", &Jit::Comp_ITypeMem, Dis_ITypeMem, Int_ITypeMem, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_RT|MEMTYPE_HWORD), + INSTR("lwr", &Jit::Comp_ITypeMem, Dis_ITypeMem, Int_ITypeMem, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_RT|MEMTYPE_WORD), {-2}, //40 - INSTR("sb", &Jit::Comp_ITypeMem, Dis_ITypeMem, Int_ITypeMem, IN_IMM16|IN_RS_ADDR|IN_RT|OUT_MEM), - INSTR("sh", &Jit::Comp_ITypeMem, Dis_ITypeMem, Int_ITypeMem, IN_IMM16|IN_RS_ADDR|IN_RT|OUT_MEM), - INSTR("swl", &Jit::Comp_ITypeMem, Dis_ITypeMem, Int_ITypeMem, IN_IMM16|IN_RS_ADDR|IN_RT|OUT_MEM), - INSTR("sw", &Jit::Comp_ITypeMem, Dis_ITypeMem, Int_ITypeMem, IN_IMM16|IN_RS_ADDR|IN_RT|OUT_MEM), + INSTR("sb", &Jit::Comp_ITypeMem, Dis_ITypeMem, Int_ITypeMem, IN_IMM16|IN_RS_ADDR|IN_RT|OUT_MEM|MEMTYPE_BYTE), + INSTR("sh", &Jit::Comp_ITypeMem, Dis_ITypeMem, Int_ITypeMem, IN_IMM16|IN_RS_ADDR|IN_RT|OUT_MEM|MEMTYPE_HWORD), + INSTR("swl", &Jit::Comp_ITypeMem, Dis_ITypeMem, Int_ITypeMem, IN_IMM16|IN_RS_ADDR|IN_RT|OUT_MEM|MEMTYPE_WORD), + INSTR("sw", &Jit::Comp_ITypeMem, Dis_ITypeMem, Int_ITypeMem, IN_IMM16|IN_RS_ADDR|IN_RT|OUT_MEM|MEMTYPE_WORD), {-2}, {-2}, - INSTR("swr", &Jit::Comp_ITypeMem, Dis_ITypeMem, Int_ITypeMem, IN_IMM16|IN_RS_ADDR|IN_RT|OUT_MEM), + INSTR("swr", &Jit::Comp_ITypeMem, Dis_ITypeMem, Int_ITypeMem, IN_IMM16|IN_RS_ADDR|IN_RT|OUT_MEM|MEMTYPE_WORD), INSTR("cache", &Jit::Comp_Generic, Dis_Generic, Int_Cache, 0), //48 INSTR("ll", &Jit::Comp_Generic, Dis_Generic, Int_StoreSync, 0), @@ -178,10 +178,10 @@ const MIPSInstruction tableSpecial[64] = /// 000000 ...... ...... .......... xxx INSTR("srav", &Jit::Comp_ShiftType, Dis_VarShiftType, Int_ShiftType, OUT_RD|IN_RT|IN_RS_SHIFT), //8 - INSTR("jr", &Jit::Comp_JumpReg, Dis_JumpRegType, Int_JumpRegType, DELAYSLOT), - INSTR("jalr", &Jit::Comp_JumpReg, Dis_JumpRegType, Int_JumpRegType, DELAYSLOT), - INSTR("movz", &Jit::Comp_RType3, Dis_RType3, Int_RType3, OUT_RD|IN_RS|IN_RT), - INSTR("movn", &Jit::Comp_RType3, Dis_RType3, Int_RType3, OUT_RD|IN_RS|IN_RT), + INSTR("jr", &Jit::Comp_JumpReg, Dis_JumpRegType, Int_JumpRegType, IS_JUMP|IN_RS|DELAYSLOT), + INSTR("jalr", &Jit::Comp_JumpReg, Dis_JumpRegType, Int_JumpRegType, IS_JUMP|IN_RS|OUT_RA|DELAYSLOT), + INSTR("movz", &Jit::Comp_RType3, Dis_RType3, Int_RType3, OUT_RD|IN_RS|IN_RT|IS_CONDMOVE|CONDTYPE_EQ), + INSTR("movn", &Jit::Comp_RType3, Dis_RType3, Int_RType3, OUT_RD|IN_RS|IN_RT|IS_CONDMOVE|CONDTYPE_NE), INSTR("syscall", &Jit::Comp_Syscall, Dis_Syscall, Int_Syscall,0), INSTR("break", &Jit::Comp_Break, Dis_Generic, Int_Break, 0), {-2}, @@ -327,10 +327,10 @@ const MIPSInstruction tableSpecial3[64] = const MIPSInstruction tableRegImm[32] = { - INSTR("bltz", &Jit::Comp_RelBranchRI, Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_RS|DELAYSLOT), - INSTR("bgez", &Jit::Comp_RelBranchRI, Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_RS|DELAYSLOT), - INSTR("bltzl", &Jit::Comp_RelBranchRI, Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_RS|DELAYSLOT|LIKELY), - INSTR("bgezl", &Jit::Comp_RelBranchRI, Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_RS|DELAYSLOT|LIKELY), + INSTR("bltz", &Jit::Comp_RelBranchRI, Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_RS|DELAYSLOT|CONDTYPE_LTZ), + INSTR("bgez", &Jit::Comp_RelBranchRI, Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_RS|DELAYSLOT|CONDTYPE_GEZ), + INSTR("bltzl", &Jit::Comp_RelBranchRI, Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_RS|DELAYSLOT|LIKELY|CONDTYPE_LTZ), + INSTR("bgezl", &Jit::Comp_RelBranchRI, Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_RS|DELAYSLOT|LIKELY|CONDTYPE_GEZ), {-2}, {-2}, {-2}, @@ -345,10 +345,10 @@ const MIPSInstruction tableRegImm[32] = INSTR("tnei", &Jit::Comp_Generic, Dis_Generic, 0, 0), {-2}, - INSTR("bltzal", &Jit::Comp_RelBranchRI, Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_RS|OUT_RA|DELAYSLOT), - INSTR("bgezal", &Jit::Comp_RelBranchRI, Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_RS|OUT_RA|DELAYSLOT), - INSTR("bltzall", &Jit::Comp_RelBranchRI, Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_RS|OUT_RA|DELAYSLOT|LIKELY), //L = likely - INSTR("bgezall", &Jit::Comp_RelBranchRI, Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_RS|OUT_RA|DELAYSLOT|LIKELY), + INSTR("bltzal", &Jit::Comp_RelBranchRI, Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_RS|OUT_RA|DELAYSLOT|CONDTYPE_LTZ), + INSTR("bgezal", &Jit::Comp_RelBranchRI, Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_RS|OUT_RA|DELAYSLOT|CONDTYPE_GEZ), + INSTR("bltzall", &Jit::Comp_RelBranchRI, Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_RS|OUT_RA|DELAYSLOT|LIKELY|CONDTYPE_LTZ), //L = likely + INSTR("bgezall", &Jit::Comp_RelBranchRI, Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_RS|OUT_RA|DELAYSLOT|LIKELY|CONDTYPE_GEZ), {-2}, {-2}, {-2}, diff --git a/Core/MIPS/MIPSTables.h b/Core/MIPS/MIPSTables.h index 68e453af99..c15e56a202 100644 --- a/Core/MIPS/MIPSTables.h +++ b/Core/MIPS/MIPSTables.h @@ -19,6 +19,23 @@ #include "../../Globals.h" +#define CONDTYPE_MASK 0x00000007 +#define CONDTYPE_EQ 0x00000001 +#define CONDTYPE_NE 0x00000002 +#define CONDTYPE_LEZ 0x00000003 +#define CONDTYPE_GTZ 0x00000004 +#define CONDTYPE_LTZ 0x00000005 +#define CONDTYPE_GEZ 0x00000006 + +// as long as the other flags are checked, +// there is no way to misinterprete these +// as CONDTYPE_X +#define MEMTYPE_MASK 0x00000003 +#define MEMTYPE_BYTE 0x00000001 +#define MEMTYPE_HWORD 0x00000002 +#define MEMTYPE_WORD 0x00000003 + +#define IS_CONDMOVE 0x00000008 #define DELAYSLOT 0x00000010 #define BAD_INSTRUCTION 0x00000020 #define UNCONDITIONAL 0x00000040 diff --git a/Core/System.cpp b/Core/System.cpp index 9f0dcdf984..d13eb64247 100644 --- a/Core/System.cpp +++ b/Core/System.cpp @@ -19,32 +19,26 @@ #include "Common/CommonWindows.h" #endif -#include "MemMap.h" +#include "Core/MemMap.h" -#include "MIPS/MIPS.h" +#include "Core/MIPS/MIPS.h" +#include "Core/MIPS/JitCommon/JitCommon.h" -#include "MIPS/JitCommon/JitCommon.h" - -#include "System.h" -// Bad dependency -#include "GPU/GLES/Framebuffer.h" -#include "GPU/GLES/TextureCache.h" -#include "GPU/GLES/ShaderManager.h" - -#include "PSPMixer.h" -#include "HLE/HLE.h" -#include "HLE/sceKernel.h" -#include "HLE/sceKernelMemory.h" -#include "HLE/sceAudio.h" -#include "Config.h" -#include "Core.h" -#include "CoreTiming.h" -#include "CoreParameter.h" -#include "FileSystems/MetaFileSystem.h" -#include "Loaders.h" -#include "PSPLoaders.h" -#include "ELF/ParamSFO.h" -#include "../Common/LogManager.h" +#include "Core/System.h" +#include "Core/PSPMixer.h" +#include "Core/HLE/HLE.h" +#include "Core/HLE/sceKernel.h" +#include "Core/HLE/sceKernelMemory.h" +#include "Core/HLE/sceAudio.h" +#include "Core/Config.h" +#include "Core/Core.h" +#include "Core/CoreTiming.h" +#include "Core/CoreParameter.h" +#include "Core/FileSystems/MetaFileSystem.h" +#include "Core/Loaders.h" +#include "Core/PSPLoaders.h" +#include "Core/ELF/ParamSFO.h" +#include "Common/LogManager.h" MetaFileSystem pspFileSystem; ParamSFOData g_paramSFO; diff --git a/Core/Util/PPGeDraw.cpp b/Core/Util/PPGeDraw.cpp index 401cbd9af8..5830e1d0ca 100644 --- a/Core/Util/PPGeDraw.cpp +++ b/Core/Util/PPGeDraw.cpp @@ -24,8 +24,6 @@ #include "Core/HLE/sceGe.h" #include "Core/MemMap.h" #include "image/zim_load.h" -#include "gfx/texture_atlas.h" -#include "gfx/gl_common.h" #include "util/text/utf8.h" #include "MathUtil.h" #include "Core/System.h" diff --git a/GPU/GLES/DisplayListInterpreter.cpp b/GPU/GLES/DisplayListInterpreter.cpp index 043186dde3..f52fd97579 100644 --- a/GPU/GLES/DisplayListInterpreter.cpp +++ b/GPU/GLES/DisplayListInterpreter.cpp @@ -289,7 +289,7 @@ void GLES_GPU::BeginFrame() { framebufferManager_.BeginFrame(); } -void GLES_GPU::SetDisplayFramebuffer(u32 framebuf, u32 stride, int format) { +void GLES_GPU::SetDisplayFramebuffer(u32 framebuf, u32 stride, GEBufferFormat format) { framebufferManager_.SetDisplayFramebuffer(framebuf, stride, format); } @@ -1055,7 +1055,7 @@ void GLES_GPU::DoBlockTransfer() { if (((backBuffer != 0 && dstBasePtr == backBuffer) || (displayBuffer != 0 && dstBasePtr == displayBuffer)) && dstStride == 512 && height == 272) { - framebufferManager_.DrawPixels(Memory::GetPointer(dstBasePtr), 3, 512); + framebufferManager_.DrawPixels(Memory::GetPointer(dstBasePtr), GE_FORMAT_8888, 512); } } diff --git a/GPU/GLES/DisplayListInterpreter.h b/GPU/GLES/DisplayListInterpreter.h index 15225bf3c9..2235241211 100644 --- a/GPU/GLES/DisplayListInterpreter.h +++ b/GPU/GLES/DisplayListInterpreter.h @@ -40,7 +40,7 @@ public: virtual void ExecuteOp(u32 op, u32 diff); virtual u32 DrawSync(int mode); - virtual void SetDisplayFramebuffer(u32 framebuf, u32 stride, int format); + virtual void SetDisplayFramebuffer(u32 framebuf, u32 stride, GEBufferFormat format); virtual void CopyDisplayToOutput(); virtual void BeginFrame(); virtual void UpdateStats(); diff --git a/GPU/GLES/Framebuffer.cpp b/GPU/GLES/Framebuffer.cpp index dc2eb639d4..682b3cda32 100644 --- a/GPU/GLES/Framebuffer.cpp +++ b/GPU/GLES/Framebuffer.cpp @@ -91,7 +91,7 @@ inline u16 RGBA8888toRGBA5551(u32 px) { return ((px >> 3) & 0x001F) | ((px >> 6) & 0x03E0) | ((px >> 9) & 0x7C00) | ((px >> 16) & 0x8000); } -void ConvertFromRGBA8888(u8 *dst, u8 *src, u32 stride, u32 height, int format); +void ConvertFromRGBA8888(u8 *dst, u8 *src, u32 stride, u32 height, GEBufferFormat format); void CenterRect(float *x, float *y, float *w, float *h, float origW, float origH, float frameW, float frameH) @@ -147,14 +147,14 @@ FramebufferManager::FramebufferManager() : ramDisplayFramebufPtr_(0), displayFramebufPtr_(0), displayStride_(0), - displayFormat_(0), + displayFormat_(GE_FORMAT_565), displayFramebuf_(0), prevDisplayFramebuf_(0), prevPrevDisplayFramebuf_(0), frameLastFramebufUsed(0), currentRenderVfb_(0), drawPixelsTex_(0), - drawPixelsTexFormat_(-1), + drawPixelsTexFormat_(GE_FORMAT_INVALID), convBuf(0), draw2dprogram(0) #ifndef USING_GLES2 @@ -218,7 +218,7 @@ FramebufferManager::~FramebufferManager() { delete [] convBuf; } -void FramebufferManager::DrawPixels(const u8 *framebuf, int pixelFormat, int linesize) { +void FramebufferManager::DrawPixels(const u8 *framebuf, GEBufferFormat pixelFormat, int linesize) { if (drawPixelsTex_ && drawPixelsTexFormat_ != pixelFormat) { glDeleteTextures(1, &drawPixelsTex_); drawPixelsTex_ = 0; @@ -235,24 +235,19 @@ void FramebufferManager::DrawPixels(const u8 *framebuf, int pixelFormat, int lin glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - switch (pixelFormat) { - case PSP_DISPLAY_PIXEL_FORMAT_8888: - break; - } - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 512, 272, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glBindTexture(GL_TEXTURE_2D, 0); drawPixelsTexFormat_ = pixelFormat; } // TODO: We can just change the texture format and flip some bits around instead of this. - if (pixelFormat != PSP_DISPLAY_PIXEL_FORMAT_8888 || linesize != 512) { + if (pixelFormat != GE_FORMAT_8888 || linesize != 512) { if (!convBuf) { convBuf = new u8[512 * 272 * 4]; } for (int y = 0; y < 272; y++) { switch (pixelFormat) { - case PSP_DISPLAY_PIXEL_FORMAT_565: + case GE_FORMAT_565: { const u16 *src = (const u16 *)framebuf + linesize * y; u8 *dst = convBuf + 4 * 512 * y; @@ -267,7 +262,7 @@ void FramebufferManager::DrawPixels(const u8 *framebuf, int pixelFormat, int lin } break; - case PSP_DISPLAY_PIXEL_FORMAT_5551: + case GE_FORMAT_5551: { const u16 *src = (const u16 *)framebuf + linesize * y; u8 *dst = convBuf + 4 * 512 * y; @@ -282,7 +277,7 @@ void FramebufferManager::DrawPixels(const u8 *framebuf, int pixelFormat, int lin } break; - case PSP_DISPLAY_PIXEL_FORMAT_4444: + case GE_FORMAT_4444: { const u16 *src = (const u16 *)framebuf + linesize * y; u8 *dst = convBuf + 4 * 512 * y; @@ -297,7 +292,7 @@ void FramebufferManager::DrawPixels(const u8 *framebuf, int pixelFormat, int lin } break; - case PSP_DISPLAY_PIXEL_FORMAT_8888: + case GE_FORMAT_8888: { const u8 *src = framebuf + linesize * 4 * y; u8 *dst = convBuf + 4 * 512 * y; @@ -313,7 +308,7 @@ void FramebufferManager::DrawPixels(const u8 *framebuf, int pixelFormat, int lin { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } - glTexSubImage2D(GL_TEXTURE_2D,0,0,0,512,272, GL_RGBA, GL_UNSIGNED_BYTE, pixelFormat == PSP_DISPLAY_PIXEL_FORMAT_8888 ? framebuf : convBuf); + glTexSubImage2D(GL_TEXTURE_2D,0,0,0,512,272, GL_RGBA, GL_UNSIGNED_BYTE, pixelFormat == GE_FORMAT_8888 ? framebuf : convBuf); float x, y, w, h; CenterRect(&x, &y, &w, &h, 480.0f, 272.0f, (float)PSP_CoreParameter().pixelWidth, (float)PSP_CoreParameter().pixelHeight); @@ -453,7 +448,7 @@ void FramebufferManager::SetRenderFrameBuffer() { // As there are no clear "framebuffer width" and "framebuffer height" registers, // we need to infer the size of the current framebuffer somehow. Let's try the viewport. - int fmt = gstate.framebufpixformat & 3; + GEBufferFormat fmt = static_cast(gstate.framebufpixformat & 3); int drawing_width, drawing_height; GuessDrawingSize(drawing_width, drawing_height); @@ -504,20 +499,20 @@ void FramebufferManager::SetRenderFrameBuffer() { vfb->colorDepth = FBO_8888; } else { switch (fmt) { - case GE_FORMAT_4444: - vfb->colorDepth = FBO_4444; + case GE_FORMAT_4444: + vfb->colorDepth = FBO_4444; break; - case GE_FORMAT_5551: - vfb->colorDepth = FBO_5551; + case GE_FORMAT_5551: + vfb->colorDepth = FBO_5551; break; - case GE_FORMAT_565: - vfb->colorDepth = FBO_565; + case GE_FORMAT_565: + vfb->colorDepth = FBO_565; break; - case GE_FORMAT_8888: - vfb->colorDepth = FBO_8888; + case GE_FORMAT_8888: + vfb->colorDepth = FBO_8888; break; - default: - vfb->colorDepth = FBO_8888; + default: + vfb->colorDepth = FBO_8888; break; } } @@ -840,7 +835,7 @@ void FramebufferManager::BlitFramebuffer_(VirtualFramebuffer *src, VirtualFrameb } // TODO: SSE/NEON -void ConvertFromRGBA8888(u8 *dst, u8 *src, u32 stride, u32 height, int format) { +void ConvertFromRGBA8888(u8 *dst, u8 *src, u32 stride, u32 height, GEBufferFormat format) { if(format == GE_FORMAT_8888) { if(src == dst) { return; @@ -868,6 +863,9 @@ void ConvertFromRGBA8888(u8 *dst, u8 *src, u32 stride, u32 height, int format) { dst16[i] = RGBA8888toRGBA4444(src32[i]); } break; + case GE_FORMAT_8888: + // Not possible. + break; default: break; } @@ -1101,7 +1099,7 @@ void FramebufferManager::BeginFrame() { useBufferedRendering_ = g_Config.iRenderingMode != FB_NON_BUFFERED_MODE ? 1 : 0; } -void FramebufferManager::SetDisplayFramebuffer(u32 framebuf, u32 stride, int format) { +void FramebufferManager::SetDisplayFramebuffer(u32 framebuf, u32 stride, GEBufferFormat format) { if ((framebuf & 0x04000000) == 0) { DEBUG_LOG(HLE, "Non-VRAM display framebuffer address set: %08x", framebuf); diff --git a/GPU/GLES/Framebuffer.h b/GPU/GLES/Framebuffer.h index d11bd84718..983368ac53 100644 --- a/GPU/GLES/Framebuffer.h +++ b/GPU/GLES/Framebuffer.h @@ -19,6 +19,7 @@ #include +#include "gfx/gl_common.h" #include "gfx_es2/fbo.h" // Keeps track of allocated FBOs. // Also provides facilities for drawing and later converting raw @@ -31,13 +32,6 @@ struct GLSLProgram; class TextureCache; -enum PspDisplayPixelFormat { - PSP_DISPLAY_PIXEL_FORMAT_565 = 0, - PSP_DISPLAY_PIXEL_FORMAT_5551 = 1, - PSP_DISPLAY_PIXEL_FORMAT_4444 = 2, - PSP_DISPLAY_PIXEL_FORMAT_8888 = 3, -}; - enum { FB_USAGE_DISPLAYED_FRAMEBUFFER = 1, FB_USAGE_RENDERTARGET = 2, @@ -88,7 +82,7 @@ struct VirtualFramebuffer { u16 usageFlags; - int format; // virtual, right now they are all RGBA8888 + GEBufferFormat format; // virtual, right now they are all RGBA8888 FBOColorDepth colorDepth; FBO *fbo; @@ -108,7 +102,7 @@ struct AsyncPBO { u32 stride; u32 height; u32 size; - int format; + GEBufferFormat format; bool reading; }; @@ -128,7 +122,7 @@ public: shaderManager_ = sm; } - void DrawPixels(const u8 *framebuf, int pixelFormat, int linesize); + void DrawPixels(const u8 *framebuf, GEBufferFormat pixelFormat, int linesize); void DrawActiveTexture(float x, float y, float w, float h, bool flip = false, float uscale = 1.0f, float vscale = 1.0f, GLSLProgram *program = 0); void DestroyAllFBOs(); @@ -146,7 +140,7 @@ public: // TODO: Break out into some form of FBO manager VirtualFramebuffer *GetDisplayFBO(); - void SetDisplayFramebuffer(u32 framebuf, u32 stride, int format); + void SetDisplayFramebuffer(u32 framebuf, u32 stride, GEBufferFormat format); size_t NumVFBs() const { return vfbs_.size(); } std::vector GetFramebufferList(); @@ -171,7 +165,7 @@ private: u32 ramDisplayFramebufPtr_; // workaround for MotoGP insanity u32 displayFramebufPtr_; u32 displayStride_; - int displayFormat_; + GEBufferFormat displayFormat_; VirtualFramebuffer *displayFramebuf_; VirtualFramebuffer *prevDisplayFramebuf_; @@ -198,7 +192,7 @@ private: // Used by DrawPixels unsigned int drawPixelsTex_; - int drawPixelsTexFormat_; + GEBufferFormat drawPixelsTexFormat_; u8 *convBuf; GLSLProgram *draw2dprogram; diff --git a/GPU/GLES/TextureCache.cpp b/GPU/GLES/TextureCache.cpp index c570fad768..8d2753680e 100644 --- a/GPU/GLES/TextureCache.cpp +++ b/GPU/GLES/TextureCache.cpp @@ -172,17 +172,46 @@ TextureCache::TexCacheEntry *TextureCache::GetEntryAt(u32 texaddr) { } void TextureCache::NotifyFramebuffer(u32 address, VirtualFramebuffer *framebuffer) { + // This is a rough heuristic, because sometimes our framebuffers are too tall. + static const u32 MAX_SUBAREA_Y_OFFSET = 32; + // Must be in VRAM so | 0x04000000 it is. - TexCacheEntry *entry = GetEntryAt(address | 0x04000000); - if (entry) { - DEBUG_LOG(HLE, "Render to texture detected at %08x!", address); - if (!entry->framebuffer) { - entry->framebuffer = framebuffer; - // TODO: Delete the original non-fbo texture too. - } else { - // Force a re-bind, fixes map in Tactics Ogre. - glBindTexture(GL_TEXTURE_2D, 0); - lastBoundTexture = -1; + const u64 cacheKey = (u64)(address | 0x04000000) << 32; + // If it has a clut, those are the low 32 bits, so it'll be inside this range. + // Also, if it's a subsample of the buffer, it'll also be within the FBO. + const u64 cacheKeyEnd = cacheKey + ((u64)(framebuffer->fb_stride * MAX_SUBAREA_Y_OFFSET) << 32); + + for (auto it = cache.lower_bound(cacheKey), end = cache.upper_bound(cacheKeyEnd); it != end; ++it) { + auto entry = &it->second; + + // If they match exactly, it's non-CLUT and from the top left. + if (it->first == cacheKey) { + DEBUG_LOG(HLE, "Render to texture detected at %08x!", address); + if (!entry->framebuffer) { + if (entry->format != framebuffer->format) { + WARN_LOG_REPORT_ONCE(diffFormat1, HLE, "Render to texture with different formats %d != %d", entry->format, framebuffer->format); + } + entry->framebuffer = framebuffer; + // TODO: Delete the original non-fbo texture too. + } + } else if (g_Config.iRenderingMode == FB_NON_BUFFERED_MODE || g_Config.iRenderingMode == FB_BUFFERED_MODE) { + // 3rd Birthday (and possibly other games) render to a 16 bit clut texture. + const bool compatFormat = framebuffer->format == entry->format + || (framebuffer->format == GE_FORMAT_8888 && entry->format == GE_TFMT_CLUT32) + || (framebuffer->format != GE_FORMAT_8888 && entry->format == GE_TFMT_CLUT16); + + // Is it at least the right stride? + if (framebuffer->fb_stride == entry->bufw && compatFormat) { + if (framebuffer->format != entry->format) { + WARN_LOG_REPORT_ONCE(diffFormat2, HLE, "Render to texture with different formats %d != %d at %08x", entry->format, framebuffer->format, address); + // TODO: Use an FBO to translate the palette? + entry->framebuffer = framebuffer; + } else if ((entry->addr - address) / entry->bufw < framebuffer->height) { + WARN_LOG_REPORT_ONCE(subarea, HLE, "Render to area containing texture at %08x", address); + // TODO: Keep track of the y offset. + entry->framebuffer = framebuffer; + } + } } } } @@ -990,6 +1019,7 @@ void TextureCache::SetTexture() { if (useBufferedRendering) { if (entry->framebuffer->fbo) { fbo_bind_color_as_texture(entry->framebuffer->fbo, 0); + lastBoundTexture = -1; } else { glBindTexture(GL_TEXTURE_2D, 0); lastBoundTexture = -1; @@ -1138,6 +1168,7 @@ void TextureCache::SetTexture() { entry->lodBias = 0.0f; entry->dim = gstate.texsize[0] & 0xF0F; + entry->bufw = bufw; // This would overestimate the size in many case so we underestimate instead // to avoid excessive clearing caused by cache invalidations. diff --git a/GPU/GLES/TextureCache.h b/GPU/GLES/TextureCache.h index c60a675fe8..6b3dbfd80e 100644 --- a/GPU/GLES/TextureCache.h +++ b/GPU/GLES/TextureCache.h @@ -90,6 +90,7 @@ private: u32 framesUntilNextFullHash; u8 format; u16 dim; + u16 bufw; u32 texture; //GLuint int invalidHint; u32 fullhash; diff --git a/GPU/GLES/TransformPipeline.h b/GPU/GLES/TransformPipeline.h index 93cb5d3da0..226a3a9fe6 100644 --- a/GPU/GLES/TransformPipeline.h +++ b/GPU/GLES/TransformPipeline.h @@ -21,6 +21,7 @@ #include "IndexGenerator.h" #include "VertexDecoder.h" +#include "gfx/gl_common.h" #include "gfx/gl_lost_manager.h" class LinkedShader; diff --git a/GPU/GPUInterface.h b/GPU/GPUInterface.h index b8bf970b0f..15d7d91809 100644 --- a/GPU/GPUInterface.h +++ b/GPU/GPUInterface.h @@ -171,7 +171,7 @@ public: virtual bool InterpretList(DisplayList& list) = 0; // Framebuffer management - virtual void SetDisplayFramebuffer(u32 framebuf, u32 stride, int format) = 0; + virtual void SetDisplayFramebuffer(u32 framebuf, u32 stride, GEBufferFormat format) = 0; virtual void BeginFrame() = 0; // Can be a good place to draw the "memory" framebuffer for accelerated plugins virtual void CopyDisplayToOutput() = 0; diff --git a/GPU/GPUState.h b/GPU/GPUState.h index 9ec6db998c..a09d5d6694 100644 --- a/GPU/GPUState.h +++ b/GPU/GPUState.h @@ -18,7 +18,6 @@ #pragma once #include "../Globals.h" -#include "gfx/gl_common.h" #include "ge_constants.h" struct GPUgstate diff --git a/GPU/Null/NullGpu.h b/GPU/Null/NullGpu.h index 729dab7d33..e451f146ba 100644 --- a/GPU/Null/NullGpu.h +++ b/GPU/Null/NullGpu.h @@ -31,7 +31,7 @@ public: virtual u32 DrawSync(int mode); virtual void BeginFrame() {} - virtual void SetDisplayFramebuffer(u32 framebuf, u32 stride, int format) {} + virtual void SetDisplayFramebuffer(u32 framebuf, u32 stride, GEBufferFormat format) {} virtual void CopyDisplayToOutput() {} virtual void UpdateStats(); virtual void InvalidateCache(u32 addr, int size, GPUInvalidationType type); diff --git a/GPU/ge_constants.h b/GPU/ge_constants.h index c09275053c..de4b1fbd86 100644 --- a/GPU/ge_constants.h +++ b/GPU/ge_constants.h @@ -251,6 +251,7 @@ enum GEBufferFormat GE_FORMAT_5551=1, GE_FORMAT_4444=2, GE_FORMAT_8888=3, + GE_FORMAT_INVALID=0xFF, }; #define GE_VTYPE_TRANSFORM (0<<23) diff --git a/Windows/Debugger/CtrlDisAsmView.cpp b/Windows/Debugger/CtrlDisAsmView.cpp index 1960acdfc6..9d305e5f02 100644 --- a/Windows/Debugger/CtrlDisAsmView.cpp +++ b/Windows/Debugger/CtrlDisAsmView.cpp @@ -8,6 +8,7 @@ #include "Windows/InputBox.h" #include "Core/MIPS/MIPSAsm.h" +#include "Core/MIPS/MIPSAnalyst.h" #include "Core/Config.h" #include "Windows/Debugger/CtrlDisAsmView.h" #include "Windows/Debugger/Debugger_MemoryDlg.h" @@ -343,6 +344,7 @@ void CtrlDisAsmView::onPaint(WPARAM wParam, LPARAM lParam) for (int i = 0; i < visibleRows+2; i++) { unsigned int address=windowStart + i*instructionSize; + MIPSAnalyst::MipsOpcodeInfo info = MIPSAnalyst::GetOpcodeInfo(debugger,address); int rowY1 = rowHeight*i; int rowY2 = rowHeight*(i+1); @@ -403,6 +405,12 @@ void CtrlDisAsmView::onPaint(WPARAM wParam, LPARAM lParam) const char *dizz = debugger->disasm(address, instructionSize); parseDisasm(dizz,opcode,arguments); + // display whether the condition of a branch is met + if (info.isConditional && address == debugger->getPC()) + { + strcat(arguments,info.conditionMet ? " ; true" : " ; false"); + } + int length = (int) strlen(arguments); if (length != 0) TextOut(hdc,pixelPositions.argumentsStart,rowY1+2,arguments,length); @@ -410,7 +418,7 @@ void CtrlDisAsmView::onPaint(WPARAM wParam, LPARAM lParam) TextOut(hdc,pixelPositions.opcodeStart,rowY1+2,opcode,(int)strlen(opcode)); SelectObject(hdc,font); - if (branchTarget != -1 && strcmp(opcode,"jal") != 0 && opcode[1] != 0) //unconditional 'b/j' branch + if (info.isBranch && info.isConditional) { branches[numBranches].src=rowY1 + rowHeight/2; branches[numBranches].srcAddr=address/instructionSize; @@ -491,18 +499,17 @@ void CtrlDisAsmView::onVScroll(WPARAM wParam, LPARAM lParam) void CtrlDisAsmView::followBranch() { - char opcode[64],arguments[256]; - const char *dizz = debugger->disasm(curAddress, instructionSize); - parseDisasm(dizz,opcode,arguments); + MIPSAnalyst::MipsOpcodeInfo info = MIPSAnalyst::GetOpcodeInfo(debugger,curAddress); - if (branchTarget != -1) + if (info.isBranch) { jumpStack.push_back(curAddress); - gotoAddr(branchTarget); - } else if (branchRegister != -1) + gotoAddr(info.branchTarget); + } else if (info.isDataAccess) { - jumpStack.push_back(curAddress); - gotoAddr(debugger->GetRegValue(0,branchRegister)); + // well, not exactly a branch, but we can do something anyway + SendMessage(GetParent(wnd),WM_DEB_GOTOHEXEDIT,info.dataAddress,0); + SetFocus(wnd); } } @@ -819,6 +826,41 @@ void CtrlDisAsmView::onMouseMove(WPARAM wParam, LPARAM lParam, int button) } } +void CtrlDisAsmView::updateStatusBarText() +{ + char text[512]; + MIPSAnalyst::MipsOpcodeInfo info = MIPSAnalyst::GetOpcodeInfo(debugger,curAddress); + + text[0] = 0; + if (info.isDataAccess) + { + switch (info.dataSize) + { + case 1: + sprintf(text,"[%08X] = %02X",info.dataAddress,Memory::Read_U8(info.dataAddress)); + break; + case 2: + sprintf(text,"[%08X] = %04X",info.dataAddress,Memory::Read_U16(info.dataAddress)); + break; + case 4: + sprintf(text,"[%08X] = %08X",info.dataAddress,Memory::Read_U32(info.dataAddress)); + break; + } + } + + if (info.isBranch) + { + const char* addressSymbol = debugger->findSymbolForAddress(info.branchTarget); + if (addressSymbol == NULL) + { + sprintf(text,"%08X",info.branchTarget); + } else { + sprintf(text,"%08X = %s",info.branchTarget,addressSymbol); + } + } + + SendMessage(GetParent(wnd),WM_DEB_SETSTATUSBARTEXT,0,(LPARAM)text); +} u32 CtrlDisAsmView::yToAddress(int y) { diff --git a/Windows/Debugger/CtrlDisAsmView.h b/Windows/Debugger/CtrlDisAsmView.h index b3b6f6059e..bf1ce6afb1 100644 --- a/Windows/Debugger/CtrlDisAsmView.h +++ b/Windows/Debugger/CtrlDisAsmView.h @@ -76,6 +76,7 @@ class CtrlDisAsmView void calculatePixelPositions(); bool getDisasmAddressText(u32 address, char* dest, bool abbreviateLabels); void parseDisasm(const char* disasm, char* opcode, char* arguments); + void updateStatusBarText(); public: CtrlDisAsmView(HWND _wnd); ~CtrlDisAsmView(); @@ -150,5 +151,6 @@ public: curAddress = newAddress; selectRangeStart = extend ? std::min(selectRangeStart, newAddress) : newAddress; selectRangeEnd = extend ? std::max(selectRangeEnd, after) : after; + updateStatusBarText(); } }; \ No newline at end of file diff --git a/Windows/Debugger/CtrlMemView.cpp b/Windows/Debugger/CtrlMemView.cpp index dc4980161a..4b08cae176 100644 --- a/Windows/Debugger/CtrlMemView.cpp +++ b/Windows/Debugger/CtrlMemView.cpp @@ -500,6 +500,12 @@ void CtrlMemView::onMouseMove(WPARAM wParam, LPARAM lParam, int button) } +void CtrlMemView::updateStatusBarText() +{ + char text[64]; + sprintf(text,"%08X",curAddress); + SendMessage(GetParent(wnd),WM_DEB_SETSTATUSBARTEXT,0,(LPARAM)text); +} void CtrlMemView::gotoPoint(int x, int y) { @@ -514,6 +520,7 @@ void CtrlMemView::gotoPoint(int x, int y) asciiSelected = true; curAddress = lineAddress+col; selectedNibble = 0; + updateStatusBarText(); redraw(); } else if (x >= hexStart) { @@ -529,6 +536,7 @@ void CtrlMemView::gotoPoint(int x, int y) asciiSelected = false; curAddress = lineAddress+col/3; + updateStatusBarText(); redraw(); } } @@ -545,6 +553,8 @@ void CtrlMemView::gotoAddr(unsigned int addr) { windowStart = curAddress & ~15; } + + updateStatusBarText(); redraw(); } @@ -587,6 +597,7 @@ void CtrlMemView::scrollCursor(int bytes) { windowStart = (curAddress-(visibleRows-1)*rowSize) & ~15; } - + + updateStatusBarText(); redraw(); } \ No newline at end of file diff --git a/Windows/Debugger/CtrlMemView.h b/Windows/Debugger/CtrlMemView.h index 806b4d31f9..8aa8193cf7 100644 --- a/Windows/Debugger/CtrlMemView.h +++ b/Windows/Debugger/CtrlMemView.h @@ -52,6 +52,7 @@ class CtrlMemView static TCHAR szClassName[]; DebugInterface *debugger; MemViewMode mode; + void updateStatusBarText(); public: CtrlMemView(HWND _wnd); ~CtrlMemView(); diff --git a/Windows/Debugger/DebuggerShared.h b/Windows/Debugger/DebuggerShared.h index c6109d5046..c0f8e38a1a 100644 --- a/Windows/Debugger/DebuggerShared.h +++ b/Windows/Debugger/DebuggerShared.h @@ -11,6 +11,8 @@ enum { WM_DEB_RUNTOWPARAM = WM_USER+2, WM_DEB_TABPRESSED, WM_DEB_SETDEBUGLPARAM, WM_DEB_UPDATE, + WM_DEB_SETSTATUSBARTEXT, + WM_DEB_GOTOHEXEDIT }; bool executeExpressionWindow(HWND hwnd, DebugInterface* cpu, u32& dest); diff --git a/Windows/Debugger/Debugger_Disasm.cpp b/Windows/Debugger/Debugger_Disasm.cpp index 5e20f4a286..7966cf5c5f 100644 --- a/Windows/Debugger/Debugger_Disasm.cpp +++ b/Windows/Debugger/Debugger_Disasm.cpp @@ -22,6 +22,7 @@ #include "Core/CPU.h" #include "Core/HLE/HLE.h" #include "Core/CoreTiming.h" +#include "Core/MIPS/MIPSAnalyst.h" #include "base/stringutil.h" @@ -142,6 +143,13 @@ CDisasm::CDisasm(HINSTANCE _hInstance, HWND _hParent, DebugInterface *_cpu) : Di ShowWindow(GetDlgItem(m_hDlg, IDC_DEBUGMEMVIEW), SW_NORMAL); ShowWindow(GetDlgItem(m_hDlg, IDC_THREADLIST), SW_HIDE); + // init status bar + statusBarWnd = CreateStatusWindow(WS_CHILD | WS_VISIBLE, "", m_hDlg, IDC_DISASMSTATUSBAR); + if (g_Config.bDisplayStatusBar == false) + { + ShowWindow(statusBarWnd,SW_HIDE); + } + // Actually resize the window to the proper size (after the above setup.) if (w != -1 && h != -1) { @@ -287,42 +295,29 @@ BOOL CDisasm::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) // If the current PC is on a breakpoint, the user doesn't want to do nothing. CBreakPoints::SetSkipFirst(currentMIPS->pc); - const char* dis = cpu->disasm(cpu->GetPC(),4); - const char* pos = strstr(dis,"->$"); - const char* reg = strstr(dis,"->"); - + MIPSAnalyst::MipsOpcodeInfo info = MIPSAnalyst::GetOpcodeInfo(cpu,cpu->GetPC()); ptr->setDontRedraw(true); u32 breakpointAddress = cpu->GetPC()+cpu->getInstructionSize(0); - if (memcmp(dis,"jal\t",4) == 0 || memcmp(dis,"jalr\t",5) == 0) + if (info.isBranch) { - // it's a function call with a delay slot - skip that too - breakpointAddress += cpu->getInstructionSize(0); - } else if (memcmp(dis,"j\t",2) == 0 || memcmp(dis,"b\t",2) == 0) - { - // in case of absolute branches, set the breakpoint at the branch target - sscanf(pos+3,"%08x",&breakpointAddress); - } else if (memcmp(dis,"jr\t",3) == 0) - { - // the same for jumps to registers - int regNum = -1; - for (int i = 0; i < 32; i++) + if (info.isConditional == false) { - if (strcasecmp(reg+2,cpu->GetRegName(0,i)) == 0) + if (info.isLinkedBranch) // jal, jalr { - regNum = i; - break; + // it's a function call with a delay slot - skip that too + breakpointAddress += cpu->getInstructionSize(0); + } else { // j, ... + // in case of absolute branches, set the breakpoint at the branch target + breakpointAddress = info.branchTarget; } - } - if (regNum == -1) break; - breakpointAddress = cpu->GetRegValue(0,regNum); - } else if (pos != NULL) - { - // get branch target - sscanf(pos+3,"%08x",&breakpointAddress); - CBreakPoints::AddBreakPoint(breakpointAddress,true); + } else { // beq, ... + // set breakpoint at branch target + breakpointAddress = info.branchTarget; + CBreakPoints::AddBreakPoint(breakpointAddress,true); - // also add a breakpoint after the delay slot - breakpointAddress = cpu->GetPC()+2*cpu->getInstructionSize(0); + // and after the delay slot + breakpointAddress = cpu->GetPC()+2*cpu->getInstructionSize(0); + } } SetDebugMode(false); @@ -530,9 +525,27 @@ BOOL CDisasm::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) } } break; + case WM_DEB_SETSTATUSBARTEXT: + SendMessage(statusBarWnd,WM_SETTEXT,0,lParam); + break; + case WM_DEB_GOTOHEXEDIT: + { + CtrlMemView *memory = CtrlMemView::getFrom(GetDlgItem(m_hDlg,IDC_DEBUGMEMVIEW)); + memory->gotoAddr(wParam); + + // display the memory viewer too + HWND bp = GetDlgItem(m_hDlg, IDC_BREAKPOINTLIST); + HWND mem = GetDlgItem(m_hDlg, IDC_DEBUGMEMVIEW); + HWND threads = GetDlgItem(m_hDlg, IDC_THREADLIST); + ShowWindow(bp,SW_HIDE); + ShowWindow(mem,SW_NORMAL); + ShowWindow(threads,SW_HIDE); + } + break; case WM_SIZE: { UpdateSize(LOWORD(lParam), HIWORD(lParam)); + SendMessage(statusBarWnd,WM_SIZE,0,10); SavePosition(); return TRUE; } @@ -578,20 +591,29 @@ void CDisasm::UpdateSize(WORD width, WORD height) HWND memView = GetDlgItem(m_hDlg, IDC_DEBUGMEMVIEW); HWND threads = GetDlgItem(m_hDlg, IDC_THREADLIST); + if (g_Config.bDisplayStatusBar) + { + RECT statusRect; + GetWindowRect(statusBarWnd,&statusRect); + height -= (statusRect.bottom-statusRect.top); + } else { + height -= 2; + } + int defaultHeight = defaultRect.bottom - defaultRect.top; int breakpointHeight = defaultBreakpointRect.bottom - defaultBreakpointRect.top; if (height < defaultHeight) breakpointHeight -= defaultHeight - height; - int breakpointTop = height-breakpointHeight-8; + int breakpointTop = height-breakpointHeight-4; int regWidth = regRect.right - regRect.left; int regTop = 138; int disasmWidth = width-regWidth; int disasmTop = 25; - MoveWindow(regList, 8, regTop, regWidth, height-regTop-breakpointHeight-12, TRUE); - MoveWindow(funclist, 8, regTop, regWidth, height-regTop-breakpointHeight-12, TRUE); - MoveWindow(disasm,regWidth+15,disasmTop,disasmWidth-20,height-disasmTop-breakpointHeight-12,TRUE); + MoveWindow(regList, 8, regTop, regWidth, height-regTop-breakpointHeight-8, TRUE); + MoveWindow(funclist, 8, regTop, regWidth, height-regTop-breakpointHeight-8, TRUE); + MoveWindow(disasm,regWidth+15,disasmTop,disasmWidth-20,height-disasmTop-breakpointHeight-8,TRUE); MoveWindow(breakpointList,8,breakpointTop,width-16,breakpointHeight,TRUE); MoveWindow(memView,8,breakpointTop,width-16,breakpointHeight,TRUE); MoveWindow(threads,8,breakpointTop,width-16,breakpointHeight,TRUE); diff --git a/Windows/Debugger/Debugger_Disasm.h b/Windows/Debugger/Debugger_Disasm.h index 41184baee7..e58ccba6d0 100644 --- a/Windows/Debugger/Debugger_Disasm.h +++ b/Windows/Debugger/Debugger_Disasm.h @@ -27,6 +27,7 @@ private: DebugInterface *cpu; u64 lastTicks; + HWND statusBarWnd; CtrlBreakpointList* breakpointList; CtrlThreadList* threadList; std::vector displayedBreakPoints_; diff --git a/Windows/resource.h b/Windows/resource.h index a2845517ab..5d72a7d68b 100644 Binary files a/Windows/resource.h and b/Windows/resource.h differ diff --git a/native b/native index 411a41e948..362f2dfac9 160000 --- a/native +++ b/native @@ -1 +1 @@ -Subproject commit 411a41e948de1244a8583ac2ac7e798155657400 +Subproject commit 362f2dfac950a1c8f3934a6e7409dd1e47271891