void CtrlDisAsmView::assembleOpcode(u32 address, std::string defaultText) { u32 encoded; if (Core_IsStepping() == false) { MessageBox(wnd,L"Cannot change code while the core is running!",L"Error",MB_OK); return; } std::string op; bool result = InputBox_GetString(MainWindow::GetHInstance(),wnd,L"Assemble opcode",defaultText, op, false); if (!result) return; result = MIPSAsm::MipsAssembleOpcode(op.c_str(),debugger,address,encoded); if (result == true) { Memory::Write_U32(encoded, address); // In case this is a delay slot or combined instruction, clear cache above it too. if (MIPSComp::jit) MIPSComp::jit->ClearCacheAt(address - 4, 8); scanFunctions(); redraw(); } else { std::wstring error = ConvertUTF8ToWString(MIPSAsm::GetAssembleError()); MessageBox(wnd,error.c_str(),L"Error",MB_OK); } }
void CtrlDisAsmView::assembleOpcode(u32 address, std::string defaultText) { u32 encoded; auto memLock = Memory::Lock(); if (Core_IsStepping() == false) { MessageBox(wnd,L"Cannot change code while the core is running!",L"Error",MB_OK); return; } std::string op; bool result = InputBox_GetString(MainWindow::GetHInstance(),wnd,L"Assemble opcode",defaultText, op, false); if (!result) return; // check if it changes registers first auto seperator = op.find('='); if (seperator != std::string::npos) { std::string registerName = trimString(op.substr(0,seperator)); std::string expression = trimString(op.substr(seperator+1)); u32 value; if (parseExpression(expression.c_str(),debugger,value) == true) { for (int cat = 0; cat < debugger->GetNumCategories(); cat++) { for (int reg = 0; reg < debugger->GetNumRegsInCategory(cat); reg++) { if (strcasecmp(debugger->GetRegName(cat,reg),registerName.c_str()) == 0) { debugger->SetRegValue(cat,reg,value); SendMessage(GetParent(wnd),WM_DEB_UPDATE,0,0); return; } } } } // try to assemble the input if it failed } result = MIPSAsm::MipsAssembleOpcode(op.c_str(),debugger,address,encoded); if (result == true) { Memory::Write_U32(encoded, address); // In case this is a delay slot or combined instruction, clear cache above it too. if (MIPSComp::jit) MIPSComp::jit->InvalidateCacheAt(address - 4, 8); scanFunctions(); if (address == curAddress) gotoAddr(manager.getNthNextAddress(curAddress,1)); redraw(); } else { std::wstring error = ConvertUTF8ToWString(MIPSAsm::GetAssembleError()); MessageBox(wnd,error.c_str(),L"Error",MB_OK); } }
void CtrlDisAsmView::scrollAddressIntoView() { u32 windowEnd = manager.getNthNextAddress(windowStart,visibleRows); if (curAddress < windowStart) windowStart = curAddress; else if (curAddress >= windowEnd) windowStart = manager.getNthPreviousAddress(curAddress,visibleRows-1); scanFunctions(); }
void CtrlDisAsmView::scrollAddressIntoView() { u32 windowEnd = windowStart + visibleRows * instructionSize; if (curAddress < windowStart) windowStart = curAddress; else if (curAddress >= windowEnd) windowStart = curAddress - visibleRows * instructionSize + instructionSize; scanFunctions(); }
void CtrlDisAsmView::onVScroll(WPARAM wParam, LPARAM lParam) { switch (wParam & 0xFFFF) { case SB_LINEDOWN: windowStart = manager.getNthNextAddress(windowStart,1); break; case SB_LINEUP: windowStart = manager.getNthPreviousAddress(windowStart,1); break; case SB_PAGEDOWN: windowStart = manager.getNthNextAddress(windowStart,visibleRows); break; case SB_PAGEUP: windowStart = manager.getNthPreviousAddress(windowStart,visibleRows); break; default: return; } scanFunctions(); redraw(); }
void CtrlDisAsmView::onKeyDown(WPARAM wParam, LPARAM lParam) { dontRedraw = false; u32 windowEnd = manager.getNthNextAddress(windowStart,visibleRows); keyTaken = true; if (KeyDownAsync(VK_CONTROL)) { switch (tolower(wParam & 0xFFFF)) { case 'f': case 's': search(false); break; case 'c': case VK_INSERT: copyInstructions(selectRangeStart, selectRangeEnd, true); break; case 'x': disassembleToFile(); break; case 'a': assembleOpcode(curAddress,""); break; case 'g': { u32 addr; if (executeExpressionWindow(wnd,debugger,addr) == false) return; gotoAddr(addr); } break; case 'e': // edit breakpoint editBreakpoint(); break; case 'd': // toogle breakpoint enabled toggleBreakpoint(true); break; case VK_UP: scrollWindow(-1); scanFunctions(); break; case VK_DOWN: scrollWindow(1); scanFunctions(); break; case VK_NEXT: setCurAddress(manager.getNthPreviousAddress(windowEnd,1),KeyDownAsync(VK_SHIFT)); break; case VK_PRIOR: setCurAddress(windowStart,KeyDownAsync(VK_SHIFT)); break; } } else { switch (wParam & 0xFFFF) { case VK_DOWN: setCurAddress(manager.getNthNextAddress(curAddress,1), KeyDownAsync(VK_SHIFT)); scrollAddressIntoView(); break; case VK_UP: setCurAddress(manager.getNthPreviousAddress(curAddress,1), KeyDownAsync(VK_SHIFT)); scrollAddressIntoView(); break; case VK_NEXT: if (manager.getNthNextAddress(curAddress,1) != windowEnd && curAddressIsVisible()) { setCurAddress(manager.getNthPreviousAddress(windowEnd,1), KeyDownAsync(VK_SHIFT)); scrollAddressIntoView(); } else { setCurAddress(manager.getNthNextAddress(windowEnd,visibleRows-1), KeyDownAsync(VK_SHIFT)); scrollAddressIntoView(); } break; case VK_PRIOR: if (curAddress != windowStart && curAddressIsVisible()) { setCurAddress(windowStart, KeyDownAsync(VK_SHIFT)); scrollAddressIntoView(); } else { setCurAddress(manager.getNthPreviousAddress(windowStart,visibleRows), KeyDownAsync(VK_SHIFT)); scrollAddressIntoView(); } break; case VK_LEFT: if (jumpStack.empty()) { gotoPC(); } else { u32 addr = jumpStack[jumpStack.size()-1]; jumpStack.pop_back(); gotoAddr(addr); } return; case VK_RIGHT: followBranch(); return; case VK_TAB: displaySymbols = !displaySymbols; break; case VK_SPACE: debugger->toggleBreakpoint(curAddress); break; case VK_F3: search(true); break; default: keyTaken = false; return; } } redraw(); }