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 CtrlMemView::onKeyDown(WPARAM wParam, LPARAM lParam) { if (ctrlDown) { switch (tolower(wParam & 0xFFFF)) { case 'g': { ctrlDown = false; u32 addr; if (executeExpressionWindow(wnd,debugger,addr) == false) return; gotoAddr(addr); return; } break; case 'f': case 's': search(false); return; case 'c': search(true); return; } } switch (wParam & 0xFFFF) { case VK_DOWN: scrollCursor(rowSize); break; case VK_UP: scrollCursor(-rowSize); break; case VK_LEFT: scrollCursor(-1); break; case VK_RIGHT: scrollCursor(1); break; case VK_NEXT: scrollWindow(visibleRows); break; case VK_PRIOR: scrollWindow(-visibleRows); break; case VK_CONTROL: ctrlDown = true; break; case VK_TAB: SendMessage(GetParent(wnd),WM_DEB_TABPRESSED,0,0); break; default: return; } }
void CtrlDisAsmView::FollowBranch() { const char *temp = debugger->disasm(selection,align);; const char *mojs=strstr(temp,"->$"); if (mojs) { u32 dest; sscanf(mojs+3,"%08x",&dest); if (dest) { marker = selection; gotoAddr(dest); } } }
void CtrlDisAsmView::followBranch() { MIPSAnalyst::MipsOpcodeInfo info = MIPSAnalyst::GetOpcodeInfo(debugger,curAddress); if (info.isBranch) { jumpStack.push_back(curAddress); gotoAddr(info.branchTarget); } else if (info.isDataAccess) { // well, not exactly a branch, but we can do something anyway SendMessage(GetParent(wnd),WM_DEB_GOTOHEXEDIT,info.dataAddress,0); SetFocus(wnd); } }
void CtrlDisplayListView::onKeyDown(WPARAM wParam, LPARAM lParam) { u32 windowEnd = windowStart+visibleRows*instructionSize; switch (wParam & 0xFFFF) { case VK_DOWN: setCurAddress(curAddress + instructionSize, KeyDownAsync(VK_SHIFT)); scrollAddressIntoView(); break; case VK_UP: setCurAddress(curAddress - instructionSize, KeyDownAsync(VK_SHIFT)); scrollAddressIntoView(); break; case VK_NEXT: if (curAddress != windowEnd - instructionSize && curAddressIsVisible()) { setCurAddress(windowEnd - instructionSize, KeyDownAsync(VK_SHIFT)); scrollAddressIntoView(); } else { setCurAddress(curAddress + visibleRows * instructionSize, KeyDownAsync(VK_SHIFT)); scrollAddressIntoView(); } break; case VK_PRIOR: if (curAddress != windowStart && curAddressIsVisible()) { setCurAddress(windowStart, KeyDownAsync(VK_SHIFT)); scrollAddressIntoView(); } else { setCurAddress(curAddress - visibleRows * instructionSize, KeyDownAsync(VK_SHIFT)); scrollAddressIntoView(); } break; case VK_LEFT: gotoAddr(list.pc); return; case VK_SPACE: toggleBreakpoint(); break; case VK_F10: case VK_F11: SendMessage(GetParent(wnd),WM_GEDBG_STEPDISPLAYLIST,0,0); break; } redraw(); }
void shutdownInterface_SPI(void){ gotoAddr(00,0); gotoBank(00); writeByte (0, _SNESBankAndData, GPPUB, 0x00);//SNESBankAndData._writeRegister(GPPUB,0x00) # Disables Pull-Up Resistors on MCP SNES Data 0-7 writeByte (0, _SNESBankAndData, DEFVALB, 0xFF);//SNESBankAndData._writeRegister(DEFVALB,0xFF) # Expect MCP SNES Data 0-7 to default to 0xFF writeByte (0, _SNESBankAndData, GPINTENB, 0x00);//SNESBankAndData._writeRegister(GPINTENB,0x00) # Sets up all of SNES Data 0-7 to be interrupt disabled writeByte (0, _SNESAddressPins, IODIRA, 0xFF);//SNESAddressPins._writeRegister(IODIRA,0xFF) # Set MCP bank A to outputs (SNES Addr 0-7) writeByte (0, _SNESAddressPins, IODIRB, 0xFF);//SNESAddressPins._writeRegister(IODIRB,0xFF) # Set MCP bank B to outputs (SNES Addr 8-15) writeByte (0, _SNESBankAndData, IODIRA, 0xFF);//SNESBankAndData._writeRegister(IODIRA,0xFF) # Set MCP bank A to outputs (SNES Bank 0-7) changeDataDir(1);//writeByte (0, _SNESBankAndData, IODIRB, 0xFF);//SNESBankAndData._writeRegister(IODIRB,0xFF) # Set MCP bank B to inputs (SNES Data 0-7) writeByte (0, _IOControls, IODIRA, 0xEF);//IOControls._writeRegister(IODIRA,0xEF) # Set MCP bank A to inputs; WITH EXCEPTION TO MOSFET setIOControl(0); //writeByte (0, _IOControls, GPIOA, 0x10);//IOControls._writeRegister(GPIOA,0x10) #Turn off MOSFET }
void gotoOffset(uint32_t offset,int isLowROM){ //static uint32_t currentOffset = 0; // printf("Forth\n"); uint8_t bank = 0; uint32_t addr = 0; if (isLowROM == 0){ bank = (uint8_t)( offset / 65536); //64Kilobyte pages addr = offset - (bank * 65536); //64kilobyte pages } else{ bank = (uint8_t)( offset / 32768); //32kilobyte pages addr = offset - (bank * 32768); //32kilobyte pages } //printf("Fifth\n"); gotoBank(bank); gotoAddr(addr,isLowROM); // printf("BANK: %d, ADDR: %d\n",bank, addr); //currentOffset = offset; }
void CtrlDisplayListView::onKeyDown(WPARAM wParam, LPARAM lParam) { u32 windowEnd = windowStart+visibleRows*instructionSize; switch (wParam & 0xFFFF) { case VK_DOWN: setCurAddress(curAddress + instructionSize, GetAsyncKeyState(VK_SHIFT) != 0); scrollAddressIntoView(); break; case VK_UP: setCurAddress(curAddress - instructionSize, GetAsyncKeyState(VK_SHIFT) != 0); scrollAddressIntoView(); break; case VK_NEXT: if (curAddress != windowEnd - instructionSize && curAddressIsVisible()) { setCurAddress(windowEnd - instructionSize, GetAsyncKeyState(VK_SHIFT) != 0); scrollAddressIntoView(); } else { setCurAddress(curAddress + visibleRows * instructionSize, GetAsyncKeyState(VK_SHIFT) != 0); scrollAddressIntoView(); } break; case VK_PRIOR: if (curAddress != windowStart && curAddressIsVisible()) { setCurAddress(windowStart, GetAsyncKeyState(VK_SHIFT) != 0); scrollAddressIntoView(); } else { setCurAddress(curAddress - visibleRows * instructionSize, GetAsyncKeyState(VK_SHIFT) != 0); scrollAddressIntoView(); } break; case VK_LEFT: gotoAddr(list.pc); return; } redraw(); }
void CtrlDisAsmView::followBranch() { DisassemblyLineInfo line; manager.getLine(curAddress,true,line); if (line.type == DISTYPE_OPCODE || line.type == DISTYPE_MACRO) { if (line.info.isBranch) { jumpStack.push_back(curAddress); gotoAddr(line.info.branchTarget); } else if (line.info.hasRelevantAddress) { // well, not exactly a branch, but we can do something anyway SendMessage(GetParent(wnd),WM_DEB_GOTOHEXEDIT,line.info.releventAddress,0); SetFocus(wnd); } } else if (line.type == DISTYPE_DATA) { // jump to the start of the current line SendMessage(GetParent(wnd),WM_DEB_GOTOHEXEDIT,curAddress,0); SetFocus(wnd); } }
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(); }
void CtrlDisAsmView::search(bool continueSearch) { u32 searchAddress; if (continueSearch == false || searchQuery[0] == 0) { if (InputBox_GetString(MainWindow::GetHInstance(),MainWindow::GetHWND(),L"Search for:","",searchQuery) == false || searchQuery[0] == 0) { SetFocus(wnd); return; } for (size_t i = 0; i < searchQuery.size(); i++) { searchQuery[i] = tolower(searchQuery[i]); } SetFocus(wnd); searchAddress = manager.getNthNextAddress(curAddress,1); } else { searchAddress = manager.getNthNextAddress(matchAddress,1); } // limit address to sensible ranges if (searchAddress < 0x04000000) searchAddress = 0x04000000; if (searchAddress >= 0x04200000 && searchAddress < 0x08000000) searchAddress = 0x08000000; if (searchAddress >= 0x0A000000) { MessageBox(wnd,L"Not found",L"Search",MB_OK); return; } searching = true; redraw(); // so the cursor is disabled DisassemblyLineInfo lineInfo; while (searchAddress < 0x0A000000) { manager.getLine(searchAddress,displaySymbols,lineInfo); char addressText[64]; getDisasmAddressText(searchAddress,addressText,true,lineInfo.type == DISTYPE_OPCODE); const char* opcode = lineInfo.name.c_str(); const char* arguments = lineInfo.params.c_str(); char merged[512]; int mergePos = 0; // I'm doing it manually to convert everything to lowercase at the same time for (int i = 0; addressText[i] != 0; i++) merged[mergePos++] = tolower(addressText[i]); merged[mergePos++] = ' '; for (int i = 0; opcode[i] != 0; i++) merged[mergePos++] = tolower(opcode[i]); merged[mergePos++] = ' '; for (int i = 0; arguments[i] != 0; i++) merged[mergePos++] = tolower(arguments[i]); merged[mergePos] = 0; // match! if (strstr(merged, searchQuery.c_str()) != NULL) { matchAddress = searchAddress; searching = false; gotoAddr(searchAddress); return; } // cancel search if ((searchAddress % 256) == 0 && KeyDownAsync(VK_ESCAPE)) { searching = false; return; } searchAddress = manager.getNthNextAddress(searchAddress,1); if (searchAddress >= 0x04200000 && searchAddress < 0x08000000) searchAddress = 0x08000000; } MessageBox(wnd,L"Not found",L"Search",MB_OK); searching = false; }
uint8_t readAddrBank(int32_t addr, uint8_t bank){ gotoBank(bank); gotoAddr(addr,0); return readData(); }
uint8_t readAddr(int32_t addr, int isLowROM){ gotoAddr(addr,isLowROM); return readData(); }
void CtrlMemView::search(bool continueSearch) { u32 searchAddress; if (continueSearch == false || searchQuery[0] == 0) { if (InputBox_GetString(GetModuleHandle(NULL),wnd,L"Search for", "",searchQuery) == false) { SetFocus(wnd); return; } SetFocus(wnd); searchAddress = curAddress+1; } else { searchAddress = matchAddress+1; } std::vector<u8> searchData; if (asciiSelected) { for (size_t i = 0; i < searchQuery.length(); i++) { char c = searchQuery[i]; searchData.push_back(c); } } else { size_t index = 0; while (index < searchQuery.size()) { if (searchQuery[index] == ' ' || searchQuery[index] == '\t') { index++; continue; } u8 value = 0; for (int i = 0; i < 2; i++) { char c = tolower(searchQuery[index++]); if (c >= 'a' && c <= 'f') { value |= (c-'a'+10) << (1-i)*4; } else if (c >= '0' && c <= '9') { value |= (c-'0') << (1-i)*4; } else { MessageBox(wnd,L"Invalid search text.",L"Error",MB_OK); return; } } searchData.push_back(value); } } std::vector<std::pair<u32,u32>> memoryAreas; memoryAreas.push_back(std::pair<u32,u32>(0x04000000,0x04200000)); memoryAreas.push_back(std::pair<u32,u32>(0x08000000,0x0A000000)); searching = true; redraw(); // so the cursor is disabled for (size_t i = 0; i < memoryAreas.size(); i++) { u32 segmentStart = memoryAreas[i].first; u32 segmentEnd = memoryAreas[i].second; u8* dataPointer = Memory::GetPointer(segmentStart); if (dataPointer == NULL) continue; // better safe than sorry, I guess if (searchAddress < segmentStart) searchAddress = segmentStart; if (searchAddress >= segmentEnd) continue; int index = searchAddress-segmentStart; int endIndex = segmentEnd-segmentStart-(int)searchData.size(); while (index < endIndex) { // cancel search if ((index % 256) == 0 && KeyDownAsync(VK_ESCAPE)) { searching = false; return; } if (memcmp(&dataPointer[index],searchData.data(),searchData.size()) == 0) { matchAddress = index+segmentStart; searching = false; gotoAddr(matchAddress); return; } index++; } } MessageBox(wnd,L"Not found",L"Search",MB_OK); searching = false; redraw(); }
void CtrlDisAsmView::onKeyDown(WPARAM wParam, LPARAM lParam) { dontRedraw = false; u32 windowEnd = windowStart+visibleRows*instructionSize; keyTaken = true; if (controlHeld) { switch (tolower(wParam & 0xFFFF)) { case 's': search(false); break; case 'c': search(true); break; case 'x': disassembleToFile(); break; case 'a': controlHeld = false; assembleOpcode(curAddress,""); break; case 'g': { u32 addr; controlHeld = false; if (executeExpressionWindow(wnd,debugger,addr) == false) return; gotoAddr(addr); } break; } } else { switch (wParam & 0xFFFF) { case VK_DOWN: setCurAddress(curAddress + instructionSize, GetAsyncKeyState(VK_SHIFT) != 0); scrollAddressIntoView(); break; case VK_UP: setCurAddress(curAddress - instructionSize, GetAsyncKeyState(VK_SHIFT) != 0); scrollAddressIntoView(); break; case VK_NEXT: if (curAddress != windowEnd - instructionSize && curAddressIsVisible()) { setCurAddress(windowEnd - instructionSize, GetAsyncKeyState(VK_SHIFT) != 0); scrollAddressIntoView(); } else { setCurAddress(curAddress + visibleRows * instructionSize, GetAsyncKeyState(VK_SHIFT) != 0); scrollAddressIntoView(); } break; case VK_PRIOR: if (curAddress != windowStart && curAddressIsVisible()) { setCurAddress(windowStart, GetAsyncKeyState(VK_SHIFT) != 0); scrollAddressIntoView(); } else { setCurAddress(curAddress - visibleRows * instructionSize, GetAsyncKeyState(VK_SHIFT) != 0); 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_CONTROL: controlHeld = true; break; case VK_SPACE: debugger->toggleBreakpoint(curAddress); break; default: keyTaken = false; return; } } redraw(); }
void CtrlDisAsmView::search(bool continueSearch) { u32 searchAddress; if (continueSearch == false || searchQuery[0] == 0) { if (InputBox_GetString(MainWindow::GetHInstance(),MainWindow::GetHWND(),L"Search for:","",searchQuery) == false || searchQuery[0] == 0) { SetFocus(wnd); return; } for (int i = 0; searchQuery[i] != 0; i++) { searchQuery[i] = tolower(searchQuery[i]); } SetFocus(wnd); searchAddress = curAddress+instructionSize; } else { searchAddress = matchAddress+instructionSize; } // limit address to sensible ranges if (searchAddress < 0x04000000) searchAddress = 0x04000000; if (searchAddress >= 0x04200000 && searchAddress < 0x08000000) searchAddress = 0x08000000; if (searchAddress >= 0x0A000000) { MessageBox(wnd,L"Not found",L"Search",MB_OK); return; } searching = true; redraw(); // so the cursor is disabled while (searchAddress < 0x0A000000) { char addressText[64],opcode[64],arguments[256]; const char *dis = debugger->disasm(searchAddress, instructionSize); parseDisasm(dis,opcode,arguments); getDisasmAddressText(searchAddress,addressText,true); char merged[512]; int mergePos = 0; // I'm doing it manually to convert everything to lowercase at the same time for (int i = 0; addressText[i] != 0; i++) merged[mergePos++] = tolower(addressText[i]); merged[mergePos++] = ' '; for (int i = 0; opcode[i] != 0; i++) merged[mergePos++] = tolower(opcode[i]); merged[mergePos++] = ' '; for (int i = 0; arguments[i] != 0; i++) merged[mergePos++] = tolower(arguments[i]); merged[mergePos] = 0; // match! if (strstr(merged, searchQuery.c_str()) != NULL) { matchAddress = searchAddress; searching = false; gotoAddr(searchAddress); return; } // cancel search if ((searchAddress % 256) == 0 && GetAsyncKeyState(VK_ESCAPE)) { searching = false; return; } searchAddress += instructionSize; if (searchAddress >= 0x04200000 && searchAddress < 0x08000000) searchAddress = 0x08000000; } MessageBox(wnd,L"Not found",L"Search",MB_OK); searching = false; }