void CDisasm::SetDebugMode(bool _bDebug, bool switchPC) { HWND hDlg = m_hDlg; // Update Dialog Windows if (_bDebug && globalUIState == UISTATE_INGAME && PSP_IsInited()) { Core_WaitInactive(TEMP_BREAKPOINT_WAIT_MS); CBreakPoints::ClearTemporaryBreakPoints(); breakpointList->reloadBreakpoints(); threadList->reloadThreads(); stackTraceView->loadStackTrace(); moduleList->loadModules(); updateThreadLabel(false); SetDlgItemText(m_hDlg, IDC_STOPGO, L"Go"); EnableWindow( GetDlgItem(hDlg, IDC_STOPGO), TRUE); EnableWindow( GetDlgItem(hDlg, IDC_STEP), TRUE); EnableWindow( GetDlgItem(hDlg, IDC_STEPOVER), TRUE); EnableWindow( GetDlgItem(hDlg, IDC_STEPHLE), TRUE); EnableWindow( GetDlgItem(hDlg, IDC_STEPOUT), TRUE); CtrlDisAsmView *ptr = CtrlDisAsmView::getFrom(GetDlgItem(m_hDlg,IDC_DISASMVIEW)); ptr->setDontRedraw(false); if (switchPC) ptr->gotoPC(); ptr->scanFunctions(); CtrlMemView *mem = CtrlMemView::getFrom(GetDlgItem(m_hDlg,IDC_DEBUGMEMVIEW)); mem->redraw(); // update the callstack //CDisam::blah blah UpdateDialog(); } else { updateThreadLabel(true); if (globalUIState == UISTATE_INGAME && PSP_IsInited()) { SetDlgItemText(m_hDlg, IDC_STOPGO, L"Stop"); EnableWindow( GetDlgItem(hDlg, IDC_STOPGO), TRUE); } else { SetDlgItemText(m_hDlg, IDC_STOPGO, L"Go"); EnableWindow( GetDlgItem(hDlg, IDC_STOPGO), FALSE); } EnableWindow( GetDlgItem(hDlg, IDC_STEP), FALSE); EnableWindow( GetDlgItem(hDlg, IDC_STEPOVER), FALSE); EnableWindow( GetDlgItem(hDlg, IDC_STEPHLE), FALSE); EnableWindow( GetDlgItem(hDlg, IDC_STEPOUT), FALSE); CtrlRegisterList *reglist = CtrlRegisterList::getFrom(GetDlgItem(m_hDlg,IDC_REGLIST)); reglist->redraw(); } }
void EmuScreen::sendMessage(const char *message, const char *value) { // External commands, like from the Windows UI. if (!strcmp(message, "pause")) { screenManager()->push(new GamePauseScreen(gamePath_)); } else if (!strcmp(message, "stop")) { // We will push MainScreen in update(). PSP_Shutdown(); bootPending_ = false; invalid_ = true; host->UpdateDisassembly(); } else if (!strcmp(message, "reset")) { PSP_Shutdown(); bootPending_ = true; invalid_ = true; host->UpdateDisassembly(); std::string resetError; if (!PSP_InitStart(PSP_CoreParameter(), &resetError)) { ELOG("Error resetting: %s", resetError.c_str()); screenManager()->switchScreen(new MainScreen()); System_SendMessage("event", "failstartgame"); return; } } else if (!strcmp(message, "boot")) { const char *ext = strrchr(value, '.'); if (!strcmp(ext, ".ppst")) { SaveState::Load(value, &AfterStateLoad); } else { PSP_Shutdown(); bootPending_ = true; bootGame(value); } } else if (!strcmp(message, "control mapping")) { UpdateUIState(UISTATE_MENU); screenManager()->push(new ControlMappingScreen()); } else if (!strcmp(message, "settings")) { UpdateUIState(UISTATE_MENU); screenManager()->push(new GameSettingsScreen(gamePath_)); } else if (!strcmp(message, "gpu resized") || !strcmp(message, "gpu clear cache")) { if (gpu) { gpu->ClearCacheNextFrame(); gpu->Resized(); } Reporting::UpdateConfig(); RecreateViews(); } else if (!strcmp(message, "gpu dump next frame")) { if (gpu) gpu->DumpNextFrame(); } else if (!strcmp(message, "clear jit")) { currentMIPS->ClearJitCache(); if (PSP_IsInited()) { currentMIPS->UpdateCore(g_Config.bJit ? CPU_JIT : CPU_INTERPRETER); } } else if (!strcmp(message, "window minimized")) { if (!strcmp(value, "true")) { gstate_c.skipDrawReason |= SKIPDRAW_WINDOW_MINIMIZED; } else { gstate_c.skipDrawReason &= ~SKIPDRAW_WINDOW_MINIMIZED; } } }
void CDisasm::UpdateDialog(bool _bComplete) { HWND gotoInt = GetDlgItem(m_hDlg, IDC_GOTOINT); /* ComboBox_ResetContent(gotoInt); for (int i=0; i<numRegions; i++) { // TODO: wchar_t int n = ComboBox_AddString(gotoInt,regions[i].name); ComboBox_SetItemData(gotoInt,n,regions[i].start); } ComboBox_InsertString(gotoInt,0,"[Goto Rgn]"); ComboBox_SetItemData(gotoInt,0,0xFFFFFFFF); ComboBox_SetCurSel(gotoInt,0); */ CtrlDisAsmView *ptr = CtrlDisAsmView::getFrom(GetDlgItem(m_hDlg,IDC_DISASMVIEW)); ptr->redraw(); CtrlRegisterList *rl = CtrlRegisterList::getFrom(GetDlgItem(m_hDlg,IDC_REGLIST)); rl->redraw(); // Update Debug Counter wchar_t tempTicks[24]; if (PSP_IsInited()) { _snwprintf(tempTicks, 24, L"%lld", CoreTiming::GetTicks() - lastTicks); SetDlgItemText(m_hDlg, IDC_DEBUG_COUNT, tempTicks); } // Update Register Dialog for (int i=0; i<numCPUs; i++) if (memoryWindow[i]) memoryWindow[i]->Update(); // repaint windows at the bottom. only the memory view needs to be forced to // redraw. all others are updated manually InvalidateRect (GetDlgItem(m_hDlg, IDC_DEBUGMEMVIEW), NULL, TRUE); UpdateWindow (GetDlgItem(m_hDlg, IDC_DEBUGMEMVIEW)); }
void Core_RunLoop() { while ((globalUIState != UISTATE_INGAME || !PSP_IsInited()) && globalUIState != UISTATE_EXIT) { time_update(); #if defined(_WIN32) && !defined(USING_QT_UI) double startTime = time_now_d(); UpdateRunLoop(); // Simple throttling to not burn the GPU in the menu. time_update(); double diffTime = time_now_d() - startTime; int sleepTime = (int) (1000000.0 / 60.0) - (int) (diffTime * 1000000.0); if (sleepTime > 0) Sleep(sleepTime / 1000); GL_SwapBuffers(); #else UpdateRunLoop(); #endif } while (!coreState && globalUIState == UISTATE_INGAME) { time_update(); UpdateRunLoop(); #if defined(_WIN32) && !defined(USING_QT_UI) if (!Core_IsStepping()) { GL_SwapBuffers(); } #endif } }
DisassemblyFunction::DisassemblyFunction(u32 _address, u32 _size): address(_address), size(_size) { auto memLock = Memory::Lock(); if (!PSP_IsInited()) return; hash = computeHash(address,size); load(); }
DisassemblyData::DisassemblyData(u32 _address, u32 _size, DataType _type): address(_address), size(_size), type(_type) { auto memLock = Memory::Lock(); if (!PSP_IsInited()) return; hash = computeHash(address,size); createLines(); }
bool IsEnabled() { if (g_Config.sReportHost.empty() || (!currentSupported && PSP_IsInited())) return false; // Disabled by default for now. if (g_Config.sReportHost.compare("default") == 0) return false; return true; }
void EmuScreen::checkPowerDown() { if (coreState == CORE_POWERDOWN && !PSP_IsIniting()) { if (PSP_IsInited()) { PSP_Shutdown(); } ILOG("SELF-POWERDOWN!"); screenManager()->switchScreen(new MainScreen()); bootPending_ = false; invalid_ = true; } }
void EmuScreen::bootGame(const std::string &filename) { if (PSP_IsIniting()) { std::string error_string; booted_ = PSP_InitUpdate(&error_string); if (booted_) { invalid_ = !PSP_IsInited(); if (invalid_) { errorMessage_ = error_string; ERROR_LOG(BOOT, "%s", errorMessage_.c_str()); System_SendMessage("event", "failstartgame"); return; } bootComplete(); } return; } invalid_ = true; CoreParameter coreParam; coreParam.cpuCore = g_Config.bJit ? CPU_JIT : CPU_INTERPRETER; coreParam.gpuCore = g_Config.bSoftwareRendering ? GPU_SOFTWARE : GPU_GLES; coreParam.enableSound = g_Config.bEnableSound; coreParam.fileToStart = filename; coreParam.mountIso = ""; coreParam.startPaused = false; coreParam.printfEmuLog = false; coreParam.headLess = false; if (g_Config.iInternalResolution == 0) { coreParam.renderWidth = dp_xres; coreParam.renderHeight = dp_yres; } else { if (g_Config.iInternalResolution < 0) g_Config.iInternalResolution = 1; coreParam.renderWidth = 480 * g_Config.iInternalResolution; coreParam.renderHeight = 272 * g_Config.iInternalResolution; } coreParam.outputWidth = dp_xres; coreParam.outputHeight = dp_yres; coreParam.pixelWidth = pixel_xres; coreParam.pixelHeight = pixel_yres; std::string error_string; if (!PSP_InitStart(coreParam, &error_string)) { booted_ = true; invalid_ = true; errorMessage_ = error_string; ERROR_LOG(BOOT, "%s", errorMessage_.c_str()); System_SendMessage("event", "failstartgame"); return; } }
void EmuScreen::bootGame(const std::string &filename) { if (PSP_IsIniting()) { std::string error_string; bootPending_ = !PSP_InitUpdate(&error_string); if (!bootPending_) { invalid_ = !PSP_IsInited(); if (invalid_) { errorMessage_ = error_string; ERROR_LOG(BOOT, "%s", errorMessage_.c_str()); System_SendMessage("event", "failstartgame"); return; } bootComplete(); } return; } invalid_ = true; CoreParameter coreParam; coreParam.cpuCore = g_Config.bJit ? CPU_JIT : CPU_INTERPRETER; coreParam.gpuCore = g_Config.bSoftwareRendering ? GPU_SOFTWARE : GPU_GLES; if (g_Config.iGPUBackend == GPU_BACKEND_DIRECT3D9) { coreParam.gpuCore = GPU_DIRECTX9; } coreParam.enableSound = g_Config.bEnableSound; coreParam.fileToStart = filename; coreParam.mountIso = ""; coreParam.mountRoot = ""; coreParam.startPaused = false; coreParam.printfEmuLog = false; coreParam.headLess = false; const Bounds &bounds = screenManager()->getUIContext()->GetBounds(); if (g_Config.iInternalResolution == 0) { coreParam.renderWidth = bounds.w; coreParam.renderHeight = bounds.h; } else { if (g_Config.iInternalResolution < 0) g_Config.iInternalResolution = 1; coreParam.renderWidth = 480 * g_Config.iInternalResolution; coreParam.renderHeight = 272 * g_Config.iInternalResolution; } std::string error_string; if (!PSP_InitStart(coreParam, &error_string)) { bootPending_ = false; invalid_ = true; errorMessage_ = error_string; ERROR_LOG(BOOT, "%s", errorMessage_.c_str()); System_SendMessage("event", "failstartgame"); } }
jint Java_com_ruin_psp_PSP_readRAMU32(JNIEnv *env, jclass clazz, jint address) { u32 start = PSP_GetUserMemoryBase() + (u32)address; u32 size = 32; auto memLock = Memory::Lock(); if (!PSP_IsInited()) return 0; if (!checkStart(start, size)) return 0; return (jint) Memory::Read_U32(start); }
void DisassemblyData::recheck() { auto memLock = Memory::Lock(); if (!PSP_IsInited()) return; u32 newHash = computeHash(address,size); if (newHash != hash) { hash = newHash; createLines(); } }
void DisassemblyFunction::recheck() { auto memLock = Memory::Lock(); if (!PSP_IsInited()) return; u32 newHash = computeHash(address,size); if (hash != newHash) { hash = newHash; clear(); load(); } }
void CDisasm::stepInto() { if (!PSP_IsInited() || !Core_IsStepping()) { return; } CtrlDisAsmView *ptr = CtrlDisAsmView::getFrom(GetDlgItem(m_hDlg,IDC_DISASMVIEW)); lastTicks = CoreTiming::GetTicks(); u32 currentPc = cpu->GetPC(); // If the current PC is on a breakpoint, the user doesn't want to do nothing. CBreakPoints::SetSkipFirst(currentMIPS->pc); u32 newAddress = currentPc+ptr->getInstructionSizeAt(currentPc); MIPSAnalyst::MipsOpcodeInfo info = MIPSAnalyst::GetOpcodeInfo(cpu,currentPc); if (info.isBranch) { ptr->scrollStepping(newAddress); } else { bool scroll = true; if (currentMIPS->inDelaySlot) { MIPSAnalyst::MipsOpcodeInfo prevInfo = MIPSAnalyst::GetOpcodeInfo(cpu,currentPc-cpu->getInstructionSize(0)); if (!prevInfo.isConditional || prevInfo.conditionMet) scroll = false; } if (scroll) { ptr->scrollStepping(newAddress); } } for (u32 i = 0; i < (newAddress-currentPc)/4; i++) { Core_DoSingleStep(); Sleep(1); } _dbg_update_(); ptr->gotoPC(); UpdateDialog(); vfpudlg->Update(); CtrlMemView::getFrom(GetDlgItem(m_hDlg,IDC_DEBUGMEMVIEW))->redraw(); threadList->reloadThreads(); stackTraceView->loadStackTrace(); updateThreadLabel(false); }
void CDisasm::stepOver() { if (!PSP_IsInited() || Core_IsActive()) { return; } CtrlDisAsmView *ptr = CtrlDisAsmView::getFrom(GetDlgItem(m_hDlg,IDC_DISASMVIEW)); lastTicks = CoreTiming::GetTicks(); // If the current PC is on a breakpoint, the user doesn't want to do nothing. CBreakPoints::SetSkipFirst(currentMIPS->pc); u32 currentPc = cpu->GetPC(); MIPSAnalyst::MipsOpcodeInfo info = MIPSAnalyst::GetOpcodeInfo(cpu,cpu->GetPC()); ptr->setDontRedraw(true); u32 breakpointAddress = currentPc+ptr->getInstructionSizeAt(currentPc); if (info.isBranch) { if (info.isConditional == false) { if (info.isLinkedBranch) // jal, jalr { // 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; } } else { // beq, ... if (info.conditionMet) { breakpointAddress = info.branchTarget; } else { breakpointAddress = currentPc+2*cpu->getInstructionSize(0); ptr->scrollStepping(breakpointAddress); } } } else { ptr->scrollStepping(breakpointAddress); } SetDebugMode(false, true); CBreakPoints::AddBreakPoint(breakpointAddress,true); _dbg_update_(); Core_EnableStepping(false); Sleep(1); ptr->gotoAddr(breakpointAddress); UpdateDialog(); }
void CDisasm::runToLine() { if (!PSP_IsInited()) { return; } CtrlDisAsmView *ptr = CtrlDisAsmView::getFrom(GetDlgItem(m_hDlg,IDC_DISASMVIEW)); u32 pos = ptr->getSelection(); lastTicks = CoreTiming::GetTicks(); ptr->setDontRedraw(true); SetDebugMode(false, true); CBreakPoints::AddBreakPoint(pos,true); _dbg_update_(); Core_EnableStepping(false); }
jfloat Java_com_ruin_psp_PSP_readRAMU32Float (JNIEnv *env, jclass clazz, jint address) { u32 start = PSP_GetUserMemoryBase() + (u32)address; u32 size = 32; auto memLock = Memory::Lock(); if (!PSP_IsInited()) return 0; if (!checkStart(start, size)) return 0; u32 dat = Memory::Read_U32(start); float f; memcpy(&f, &dat, sizeof(f)); return (jfloat) f; }
void CtrlMemView::onChar(WPARAM wParam, LPARAM lParam) { auto memLock = Memory::Lock(); if (!PSP_IsInited()) return; if (KeyDownAsync(VK_CONTROL) || wParam == VK_TAB) return; if (!Memory::IsValidAddress(curAddress)) { scrollCursor(1); return; } bool active = Core_IsActive(); if (active) Core_EnableStepping(true); if (asciiSelected) { u8 newValue = wParam; Memory::WriteUnchecked_U8(newValue,curAddress); scrollCursor(1); } else { wParam = tolower(wParam); int inputValue = -1; if (wParam >= '0' && wParam <= '9') inputValue = wParam - '0'; if (wParam >= 'a' && wParam <= 'f') inputValue = wParam -'a' + 10; if (inputValue >= 0) { int shiftAmount = (1-selectedNibble)*4; u8 oldValue = Memory::ReadUnchecked_U8(curAddress); oldValue &= ~(0xF << shiftAmount); u8 newValue = oldValue | (inputValue << shiftAmount); Memory::WriteUnchecked_U8(newValue,curAddress); scrollCursor(1); } } if (active) Core_EnableStepping(false); }
void Core_RunLoop(GraphicsContext *ctx, InputState *input_state) { graphicsContext = ctx; while ((GetUIState() != UISTATE_INGAME || !PSP_IsInited()) && GetUIState() != UISTATE_EXIT) { time_update(); #if defined(USING_WIN_UI) double startTime = time_now_d(); UpdateRunLoop(input_state); // Simple throttling to not burn the GPU in the menu. time_update(); double diffTime = time_now_d() - startTime; int sleepTime = (int)(1000.0 / 60.0) - (int)(diffTime * 1000.0); if (sleepTime > 0) Sleep(sleepTime); if (!windowHidden) { ctx->SwapBuffers(); } #else UpdateRunLoop(input_state); #endif } while (!coreState && GetUIState() == UISTATE_INGAME) { time_update(); UpdateRunLoop(input_state); #if defined(USING_WIN_UI) if (!windowHidden && !Core_IsStepping()) { ctx->SwapBuffers(); // Keep the system awake for longer than normal for cutscenes and the like. const double now = time_now_d(); if (now < lastActivity + ACTIVITY_IDLE_TIMEOUT) { // Only resetting it ever prime number seconds in case the call is expensive. // Using a prime number to ensure there's no interaction with other periodic events. if (now - lastKeepAwake > 89.0 || now < lastKeepAwake) { SetThreadExecutionState(ES_SYSTEM_REQUIRED | ES_DISPLAY_REQUIRED); lastKeepAwake = now; } } } #endif } }
jbyteArray Java_com_ruin_psp_PSP_readRam(JNIEnv *env, jclass clazz, jint address, jint size) { u32 start = PSP_GetUserMemoryBase() + (u32)address; auto memLock = Memory::Lock(); if (!PSP_IsInited()) return 0; if (!checkStart(start, size)) return 0; u8 *ptr = Memory::GetPointer(start); jbyte arr[size]; memcpy(&arr, ptr, sizeof(arr)); jbyteArray ret = env->NewByteArray(size); env->SetByteArrayRegion(ret, 0, size, arr); return ret; }
void CDisasm::stepOut() { if (!PSP_IsInited()) { return; } auto threads = GetThreadsInfo(); u32 entry, stackTop; for (size_t i = 0; i < threads.size(); i++) { if (threads[i].isCurrent) { entry = threads[i].entrypoint; stackTop = threads[i].initialStack; break; } } auto frames = MIPSStackWalk::Walk(cpu->GetPC(),cpu->GetRegValue(0,31),cpu->GetRegValue(0,29),entry,stackTop); if (frames.size() < 2) return; u32 breakpointAddress = frames[1].pc; lastTicks = CoreTiming::GetTicks(); // If the current PC is on a breakpoint, the user doesn't want to do nothing. CBreakPoints::SetSkipFirst(currentMIPS->pc); CtrlDisAsmView *ptr = CtrlDisAsmView::getFrom(GetDlgItem(m_hDlg,IDC_DISASMVIEW)); ptr->setDontRedraw(true); SetDebugMode(false, true); CBreakPoints::AddBreakPoint(breakpointAddress,true); _dbg_update_(); Core_EnableStepping(false); Sleep(1); ptr->gotoAddr(breakpointAddress); UpdateDialog(); }
bool CtrlDisAsmView::getDisasmAddressText(u32 address, char* dest, bool abbreviateLabels, bool showData) { auto memLock = Memory::Lock(); if (!PSP_IsInited()) return false; if (displaySymbols) { const std::string addressSymbol = symbolMap.GetLabelString(address); if (!addressSymbol.empty()) { for (int k = 0; addressSymbol[k] != 0; k++) { // abbreviate long names if (abbreviateLabels && k == 16 && addressSymbol[k+1] != 0) { *dest++ = '+'; break; } *dest++ = addressSymbol[k]; } *dest++ = ':'; *dest = 0; return true; } else { sprintf(dest," %08X",address); return false; } } else { if (showData) { sprintf(dest, "%08X %08X", address, Memory::Read_Instruction(address, true).encoding); } else { sprintf(dest, "%08X", address); } return false; } }
CDisasm::CDisasm(HINSTANCE _hInstance, HWND _hParent, DebugInterface *_cpu) : Dialog((LPCSTR)IDD_DISASM, _hInstance, _hParent) { cpu = _cpu; lastTicks = PSP_IsInited() ? CoreTiming::GetTicks() : 0; keepStatusBarText = false; hideBottomTabs = false; SetWindowText(m_hDlg, ConvertUTF8ToWString(_cpu->GetName()).c_str()); #ifdef THEMES //if (WTL::CTheme::IsThemingSupported()) //EnableThemeDialogTexture(m_hDlg ,ETDT_ENABLETAB); #endif RECT windowRect; GetWindowRect(m_hDlg,&windowRect); int defaultWidth = windowRect.right-windowRect.left; int defaultHeight = windowRect.bottom-windowRect.top; minWidth = defaultWidth - 100; minHeight = defaultHeight - 200; int x = g_Config.iDisasmWindowX == -1 ? windowRect.left : g_Config.iDisasmWindowX; int y = g_Config.iDisasmWindowY == -1 ? windowRect.top : g_Config.iDisasmWindowY; int w = g_Config.iDisasmWindowW == -1 ? defaultWidth : g_Config.iDisasmWindowW; int h = g_Config.iDisasmWindowH == -1 ? defaultHeight : g_Config.iDisasmWindowH; // init status bar statusBarWnd = CreateWindowEx(0, STATUSCLASSNAME, L"", WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, m_hDlg, (HMENU)IDC_DISASMSTATUSBAR, _hInstance, NULL); if (g_Config.bDisplayStatusBar == false) { ShowWindow(statusBarWnd,SW_HIDE); } CtrlDisAsmView *ptr = CtrlDisAsmView::getFrom(GetDlgItem(m_hDlg,IDC_DISASMVIEW)); ptr->setDebugger(cpu); ptr->gotoAddr(0x00000000); CtrlRegisterList *rl = CtrlRegisterList::getFrom(GetDlgItem(m_hDlg,IDC_REGLIST)); rl->setCPU(cpu); leftTabs = new TabControl(GetDlgItem(m_hDlg,IDC_LEFTTABS)); leftTabs->SetIgnoreBottomMargin(true); leftTabs->AddTab(GetDlgItem(m_hDlg,IDC_REGLIST),L"Regs"); leftTabs->AddTab(GetDlgItem(m_hDlg,IDC_FUNCTIONLIST),L"Funcs"); leftTabs->ShowTab(0); // subclass the goto edit box HWND editWnd = GetDlgItem(m_hDlg,IDC_ADDRESS); DefGotoEditProc = (WNDPROC)GetWindowLongPtr(editWnd,GWLP_WNDPROC); SetWindowLongPtr(editWnd,GWLP_WNDPROC,(LONG_PTR)GotoEditProc); // subclass the function list HWND funcListWnd = GetDlgItem(m_hDlg,IDC_FUNCTIONLIST); DefFuncListProc = (WNDPROC)GetWindowLongPtr(funcListWnd,GWLP_WNDPROC); SetWindowLongPtr(funcListWnd,GWLP_WNDPROC,(LONG_PTR)FuncListProc); // init bottom tabs bottomTabs = new TabControl(GetDlgItem(m_hDlg,IDC_DEBUG_BOTTOMTABS)); HWND memHandle = GetDlgItem(m_hDlg,IDC_DEBUGMEMVIEW); CtrlMemView *mem = CtrlMemView::getFrom(memHandle); mem->setDebugger(_cpu); bottomTabs->AddTab(memHandle,L"Memory"); breakpointList = new CtrlBreakpointList(GetDlgItem(m_hDlg,IDC_BREAKPOINTLIST),cpu,ptr); breakpointList->reloadBreakpoints(); bottomTabs->AddTab(breakpointList->GetHandle(),L"Breakpoints"); threadList = new CtrlThreadList(GetDlgItem(m_hDlg,IDC_THREADLIST)); threadList->reloadThreads(); bottomTabs->AddTab(threadList->GetHandle(),L"Threads"); stackTraceView = new CtrlStackTraceView(GetDlgItem(m_hDlg,IDC_STACKFRAMES),cpu,ptr); stackTraceView->loadStackTrace(); bottomTabs->AddTab(stackTraceView->GetHandle(),L"Stack frames"); moduleList = new CtrlModuleList(GetDlgItem(m_hDlg,IDC_MODULELIST),cpu); moduleList->loadModules(); bottomTabs->AddTab(moduleList->GetHandle(),L"Modules"); bottomTabs->SetShowTabTitles(g_Config.bShowBottomTabTitles); bottomTabs->ShowTab(memHandle); // Actually resize the window to the proper size (after the above setup.) // do it twice so that the window definitely receives a WM_SIZE message with // the correct size (the default from the .rc tends to be off) MoveWindow(m_hDlg,x,y,1,1,FALSE); MoveWindow(m_hDlg,x,y,w,h,TRUE); SetDebugMode(true, true); }
void CtrlDisAsmView::updateStatusBarText() { auto memLock = Memory::Lock(); if (!PSP_IsInited()) return; char text[512]; DisassemblyLineInfo line; manager.getLine(curAddress,true,line); text[0] = 0; if (line.type == DISTYPE_OPCODE || line.type == DISTYPE_MACRO) { if (line.info.isDataAccess) { if (!Memory::IsValidAddress(line.info.dataAddress)) { sprintf(text,"Invalid address %08X",line.info.dataAddress); } else { switch (line.info.dataSize) { case 1: sprintf(text,"[%08X] = %02X",line.info.dataAddress,Memory::Read_U8(line.info.dataAddress)); break; case 2: sprintf(text,"[%08X] = %04X",line.info.dataAddress,Memory::Read_U16(line.info.dataAddress)); break; case 4: // TODO: Could also be a float... { u32 data = Memory::Read_U32(line.info.dataAddress); const std::string addressSymbol = symbolMap.GetLabelString(data); if (!addressSymbol.empty()) { sprintf(text,"[%08X] = %s (%08X)",line.info.dataAddress,addressSymbol.c_str(),data); } else { sprintf(text,"[%08X] = %08X",line.info.dataAddress,data); } break; } case 16: // TODO: vector break; } } } if (line.info.isBranch) { const std::string addressSymbol = symbolMap.GetLabelString(line.info.branchTarget); if (addressSymbol.empty()) { sprintf(text,"%08X",line.info.branchTarget); } else { sprintf(text,"%08X = %s",line.info.branchTarget,addressSymbol.c_str()); } } } else if (line.type == DISTYPE_DATA) { u32 start = symbolMap.GetDataStart(curAddress); if (start == -1) start = curAddress; u32 diff = curAddress-start; const std::string label = symbolMap.GetLabelString(start); if (!label.empty()) { if (diff != 0) sprintf(text,"%08X (%s) + %08X",start,label.c_str(),diff); else sprintf(text,"%08X (%s)",start,label.c_str()); } else { if (diff != 0) sprintf(text,"%08X + %08X",start,diff); else sprintf(text,"%08X",start); } } SendMessage(GetParent(wnd),WM_DEB_SETSTATUSBARTEXT,0,(LPARAM)text); const std::string label = symbolMap.GetLabelString(line.info.opcodeAddress); if (!label.empty()) { SendMessage(GetParent(wnd),WM_DEB_SETSTATUSBARTEXT,1,(LPARAM)label.c_str()); } }
BOOL CDisasm::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) { //if (!m_hDlg) return FALSE; switch(message) { case WM_INITDIALOG: { return TRUE; } break; case WM_NOTIFY: switch (wParam) { case IDC_LEFTTABS: leftTabs->HandleNotify(lParam); break; case IDC_BREAKPOINTLIST: breakpointList->HandleNotify(lParam); break; case IDC_THREADLIST: threadList->HandleNotify(lParam); break; case IDC_STACKFRAMES: stackTraceView->HandleNotify(lParam); break; case IDC_MODULELIST: moduleList->HandleNotify(lParam); break; case IDC_DEBUG_BOTTOMTABS: bottomTabs->HandleNotify(lParam); break; } break; case WM_COMMAND: { CtrlDisAsmView *ptr = CtrlDisAsmView::getFrom(GetDlgItem(m_hDlg,IDC_DISASMVIEW)); CtrlRegisterList *reglist = CtrlRegisterList::getFrom(GetDlgItem(m_hDlg,IDC_REGLIST)); switch(LOWORD(wParam)) { case ID_TOGGLE_PAUSE: SendMessage(MainWindow::GetHWND(),WM_COMMAND,ID_TOGGLE_PAUSE,0); break; case ID_DEBUG_DISPLAYMEMVIEW: bottomTabs->ShowTab(GetDlgItem(m_hDlg,IDC_DEBUGMEMVIEW)); break; case ID_DEBUG_DISPLAYBREAKPOINTLIST: bottomTabs->ShowTab(breakpointList->GetHandle()); break; case ID_DEBUG_DISPLAYTHREADLIST: bottomTabs->ShowTab(threadList->GetHandle()); break; case ID_DEBUG_DISPLAYSTACKFRAMELIST: bottomTabs->ShowTab(stackTraceView->GetHandle()); break; case ID_DEBUG_DSIPLAYREGISTERLIST: leftTabs->ShowTab(0); break; case ID_DEBUG_DSIPLAYFUNCTIONLIST: leftTabs->ShowTab(1); break; case ID_DEBUG_ADDBREAKPOINT: { keepStatusBarText = true; bool isRunning = Core_IsActive(); if (isRunning) { SetDebugMode(true, false); Core_EnableStepping(true); Core_WaitInactive(200); } BreakpointWindow bpw(m_hDlg,cpu); if (bpw.exec()) bpw.addBreakpoint(); if (isRunning) { SetDebugMode(false, false); Core_EnableStepping(false); } keepStatusBarText = false; } break; case ID_DEBUG_STEPOVER: if (GetFocus() == GetDlgItem(m_hDlg,IDC_DISASMVIEW)) stepOver(); break; case ID_DEBUG_STEPINTO: if (GetFocus() == GetDlgItem(m_hDlg,IDC_DISASMVIEW)) stepInto(); break; case ID_DEBUG_RUNTOLINE: if (GetFocus() == GetDlgItem(m_hDlg,IDC_DISASMVIEW)) runToLine(); break; case ID_DEBUG_STEPOUT: if (GetFocus() == GetDlgItem(m_hDlg,IDC_DISASMVIEW)) stepOut(); break; case ID_DEBUG_HIDEBOTTOMTABS: { RECT rect; hideBottomTabs = !hideBottomTabs; GetClientRect(m_hDlg,&rect); UpdateSize(rect.right-rect.left,rect.bottom-rect.top); } break; case ID_DEBUG_TOGGLEBOTTOMTABTITLES: bottomTabs->SetShowTabTitles(!bottomTabs->GetShowTabTitles()); break; case IDC_SHOWVFPU: vfpudlg->Show(true); break; case IDC_FUNCTIONLIST: switch (HIWORD(wParam)) { case CBN_DBLCLK: { HWND lb = GetDlgItem(m_hDlg,LOWORD(wParam)); int n = ListBox_GetCurSel(lb); if (n!=-1) { unsigned int addr = (unsigned int)ListBox_GetItemData(lb,n); ptr->gotoAddr(addr); SetFocus(GetDlgItem(m_hDlg, IDC_DISASMVIEW)); } } break; }; break; case IDC_GOTOINT: switch (HIWORD(wParam)) { case LBN_SELCHANGE: { HWND lb =GetDlgItem(m_hDlg,LOWORD(wParam)); int n = ComboBox_GetCurSel(lb); unsigned int addr = (unsigned int)ComboBox_GetItemData(lb,n); if (addr != 0xFFFFFFFF) { ptr->gotoAddr(addr); SetFocus(GetDlgItem(m_hDlg, IDC_DISASMVIEW)); } } break; }; break; case IDC_STOPGO: { if (!PSP_IsInited()) { break; } if (!Core_IsStepping()) // stop { ptr->setDontRedraw(false); SetDebugMode(true, true); Core_EnableStepping(true); _dbg_update_(); Sleep(1); //let cpu catch up ptr->gotoPC(); UpdateDialog(); vfpudlg->Update(); } else { // go lastTicks = CoreTiming::GetTicks(); // If the current PC is on a breakpoint, the user doesn't want to do nothing. CBreakPoints::SetSkipFirst(currentMIPS->pc); SetDebugMode(false, true); Core_EnableStepping(false); } } break; case IDC_STEP: stepInto(); break; case IDC_STEPOVER: stepOver(); break; case IDC_STEPOUT: stepOut(); break; case IDC_STEPHLE: { if (Core_IsActive()) break; lastTicks = CoreTiming::GetTicks(); // If the current PC is on a breakpoint, the user doesn't want to do nothing. CBreakPoints::SetSkipFirst(currentMIPS->pc); hleDebugBreak(); SetDebugMode(false, true); _dbg_update_(); Core_EnableStepping(false); } break; case IDC_MEMCHECK: SendMessage(m_hDlg,WM_COMMAND,ID_DEBUG_ADDBREAKPOINT,0); break; case IDC_GOTOPC: { ptr->gotoPC(); SetFocus(GetDlgItem(m_hDlg, IDC_DISASMVIEW)); UpdateDialog(); } break; case IDC_GOTOLR: { ptr->gotoAddr(cpu->GetLR()); SetFocus(GetDlgItem(m_hDlg, IDC_DISASMVIEW)); } break; case IDC_ALLFUNCTIONS: { symbolMap.FillSymbolListBox(GetDlgItem(m_hDlg, IDC_FUNCTIONLIST),ST_FUNCTION); break; } default: return FALSE; } return TRUE; } case WM_DEB_MAPLOADED: NotifyMapLoaded(); break; case WM_DEB_GOTOWPARAM: { CtrlDisAsmView *ptr = CtrlDisAsmView::getFrom(GetDlgItem(m_hDlg,IDC_DISASMVIEW)); ptr->gotoAddr(wParam); SetFocus(GetDlgItem(m_hDlg,IDC_DISASMVIEW)); break; } case WM_DEB_GOTOADDRESSEDIT: { if (!PSP_IsInited()) { break; } wchar_t szBuffer[256]; CtrlDisAsmView *ptr = CtrlDisAsmView::getFrom(GetDlgItem(m_hDlg,IDC_DISASMVIEW)); GetWindowText(GetDlgItem(m_hDlg,IDC_ADDRESS),szBuffer,256); u32 addr; if (parseExpression(ConvertWStringToUTF8(szBuffer).c_str(),cpu,addr) == false) { displayExpressionError(GetDlgItem(m_hDlg,IDC_ADDRESS)); } else { ptr->gotoAddr(addr); SetFocus(GetDlgItem(m_hDlg, IDC_DISASMVIEW)); } UpdateDialog(); } break; case WM_DEB_SETDEBUGLPARAM: SetDebugMode(lParam != 0, true); return TRUE; case WM_DEB_UPDATE: Update(); return TRUE; case WM_DEB_TABPRESSED: bottomTabs->NextTab(true); SetFocus(bottomTabs->CurrentTabHandle()); break; case WM_DEB_SETSTATUSBARTEXT: if (!keepStatusBarText) SetWindowText(statusBarWnd, ConvertUTF8ToWString((const char *)lParam).c_str()); break; case WM_DEB_GOTOHEXEDIT: { CtrlMemView *memory = CtrlMemView::getFrom(GetDlgItem(m_hDlg,IDC_DEBUGMEMVIEW)); memory->gotoAddr(wParam); // display the memory viewer too bottomTabs->ShowTab(GetDlgItem(m_hDlg,IDC_DEBUGMEMVIEW)); } break; case WM_SIZE: { UpdateSize(LOWORD(lParam), HIWORD(lParam)); SendMessage(statusBarWnd,WM_SIZE,0,10); SavePosition(); return TRUE; } case WM_MOVE: SavePosition(); break; case WM_GETMINMAXINFO: { MINMAXINFO *m = (MINMAXINFO *)lParam; // Reduce the minimum size slightly, so they can size it however they like. m->ptMinTrackSize.x = minWidth; //m->ptMaxTrackSize.x = m->ptMinTrackSize.x; m->ptMinTrackSize.y = minHeight; } return TRUE; case WM_CLOSE: Show(false); return TRUE; case WM_ACTIVATE: if (wParam == WA_ACTIVE || wParam == WA_CLICKACTIVE) { g_activeWindow = WINDOW_CPUDEBUGGER; } break; } return FALSE; }
void UpdateConfig() { currentSupported = IsSupported(); if (!currentSupported && PSP_IsInited()) everUnsupported = true; }
void DisassemblyManager::analyze(u32 address, u32 size = 1024) { u32 end = address+size; address &= ~3; u32 start = address; while (address < end && start <= address) { if (!PSP_IsInited()) return; auto it = findDisassemblyEntry(entries,address,false); if (it != entries.end()) { DisassemblyEntry* entry = it->second; entry->recheck(); address = entry->getLineAddress(0)+entry->getTotalSize(); continue; } SymbolInfo info; if (!symbolMap.GetSymbolInfo(&info,address,ST_ALL)) { if (address % 4) { u32 next = std::min<u32>((address+3) & ~3,symbolMap.GetNextSymbolAddress(address,ST_ALL)); DisassemblyData* data = new DisassemblyData(address,next-address,DATATYPE_BYTE); entries[address] = data; address = next; continue; } u32 next = symbolMap.GetNextSymbolAddress(address,ST_ALL); if ((next % 4) && next != (u32)-1) { u32 alignedNext = next & ~3; if (alignedNext != address) { DisassemblyOpcode* opcode = new DisassemblyOpcode(address,(alignedNext-address)/4); entries[address] = opcode; } DisassemblyData* data = new DisassemblyData(address,next-alignedNext,DATATYPE_BYTE); entries[alignedNext] = data; } else { DisassemblyOpcode* opcode = new DisassemblyOpcode(address,(next-address)/4); entries[address] = opcode; } address = next; continue; } switch (info.type) { case ST_FUNCTION: { DisassemblyFunction* function = new DisassemblyFunction(info.address,info.size); entries[info.address] = function; address = info.address+info.size; } break; case ST_DATA: { DisassemblyData* data = new DisassemblyData(info.address,info.size,symbolMap.GetDataType(info.address)); entries[info.address] = data; address = info.address+info.size; } break; default: break; } } }
bool MIPSDebugInterface::isAlive() { return PSP_IsInited() && coreState != CORE_ERROR && coreState != CORE_POWERDOWN; }
bool MIPSDebugInterface::isAlive() { return PSP_IsInited(); }
void CtrlBreakpointList::GetColumnText(wchar_t* dest, int row, int col) { if (!PSP_IsInited()) { return; } bool isMemory; int index = getBreakpointIndex(row,isMemory); if (index == -1) return; switch (col) { case BPL_TYPE: { if (isMemory) { switch ((int)displayedMemChecks_[index].cond) { case MEMCHECK_READ: wcscpy(dest,L"Read"); break; case MEMCHECK_WRITE: wcscpy(dest,L"Write"); break; case MEMCHECK_READWRITE: wcscpy(dest,L"Read/Write"); break; case MEMCHECK_WRITE | MEMCHECK_WRITE_ONCHANGE: wcscpy(dest,L"Write Change"); break; case MEMCHECK_READWRITE | MEMCHECK_WRITE_ONCHANGE: wcscpy(dest,L"Read/Write Change"); break; } } else { wcscpy(dest,L"Execute"); } } break; case BPL_OFFSET: { if (isMemory) { wsprintf(dest,L"0x%08X",displayedMemChecks_[index].start); } else { wsprintf(dest,L"0x%08X",displayedBreakPoints_[index].addr); } } break; case BPL_SIZELABEL: { if (isMemory) { auto mc = displayedMemChecks_[index]; if (mc.end == 0) wsprintf(dest,L"0x%08X",1); else wsprintf(dest,L"0x%08X",mc.end-mc.start); } else { const std::string sym = g_symbolMap->GetLabelString(displayedBreakPoints_[index].addr); if (!sym.empty()) { std::wstring s = ConvertUTF8ToWString(sym); wcscpy(dest,s.c_str()); } else { wcscpy(dest,L"-"); } } } break; case BPL_OPCODE: { if (isMemory) { wcscpy(dest,L"-"); } else { char temp[256]; disasm->getOpcodeText(displayedBreakPoints_[index].addr, temp, sizeof(temp)); std::wstring s = ConvertUTF8ToWString(temp); wcscpy(dest,s.c_str()); } } break; case BPL_CONDITION: { if (isMemory || displayedBreakPoints_[index].hasCond == false) { wcscpy(dest,L"-"); } else { std::wstring s = ConvertUTF8ToWString(displayedBreakPoints_[index].cond.expressionString); wcscpy(dest,s.c_str()); } } break; case BPL_HITS: { if (isMemory) { wsprintf(dest,L"%d",displayedMemChecks_[index].numHits); } else { wsprintf(dest,L"-"); } } break; case BPL_ENABLED: { wsprintf(dest,L"\xFFFE"); } break; } }