diff --git a/Core/Debugger/DebugInterface.h b/Core/Debugger/DebugInterface.h index cc3109b0ae..892a708a60 100644 --- a/Core/Debugger/DebugInterface.h +++ b/Core/Debugger/DebugInterface.h @@ -40,6 +40,7 @@ public: virtual void runToBreakpoint() {} virtual int getColor(unsigned int address){return 0xFFFFFFFF;} virtual const char *getDescription(unsigned int address) {return "";} + virtual const char *findSymbolForAddress(unsigned int address) { return NULL; }; virtual const char *GetName() = 0; virtual int GetGPRSize() = 0; //32 or 64 diff --git a/Core/Debugger/SymbolMap.cpp b/Core/Debugger/SymbolMap.cpp index 711dbfaa44..2fbae9c69d 100644 --- a/Core/Debugger/SymbolMap.cpp +++ b/Core/Debugger/SymbolMap.cpp @@ -226,6 +226,16 @@ int SymbolMap::GetSymbolNum(unsigned int address, SymbolType symmask) return -1; } +const char* SymbolMap::getDirectSymbol(u32 address) +{ + for (size_t i = 0, n = entries.size(); i < n; i++) + { + MapEntry &entry = entries[i]; + unsigned int addr = entry.vaddress; + if (addr == address) return entries[i].name; + } + return NULL; +} char descriptionTemp[256]; @@ -247,18 +257,32 @@ char *SymbolMap::GetDescription(unsigned int address) } #ifdef _WIN32 + +static const int defaultSymbolsAddresses[] = { + 0x08800000, 0x08804000, 0x04000000, 0x88000000, 0x00010000 +}; + +static const char* defaultSymbolsNames[] = { + "User memory", "Default load address", "VRAM","Kernel memory","Scratchpad" +}; + +static const int defaultSymbolsAmount = sizeof(defaultSymbolsAddresses)/sizeof(const int); + void SymbolMap::FillSymbolListBox(HWND listbox,SymbolType symmask) { ShowWindow(listbox,SW_HIDE); ListBox_ResetContent(listbox); - //int style = GetWindowLong(listbox,GWL_STYLE); - - ListBox_AddString(listbox,"(0x80000000)"); - ListBox_SetItemData(listbox,0,0x80000000); - - //ListBox_AddString(listbox,"(0x80002000)"); - //ListBox_SetItemData(listbox,1,0x80002000); + if (symmask & ST_DATA) + { + for (int i = 0; i < defaultSymbolsAmount; i++) + { + char temp[256]; + sprintf(temp,"0x%08X (%s)",defaultSymbolsAddresses[i],defaultSymbolsNames[i]); + int index = ListBox_AddString(listbox,temp); + ListBox_SetItemData(listbox,index,defaultSymbolsAddresses[i]); + } + } SendMessage(listbox, WM_SETREDRAW, FALSE, 0); SendMessage(listbox, LB_INITSTORAGE, (WPARAM)entries.size(), (LPARAM)entries.size() * 30); @@ -267,7 +291,13 @@ void SymbolMap::FillSymbolListBox(HWND listbox,SymbolType symmask) if (entries[i].type & symmask) { char temp[256]; - sprintf(temp,"%s (%d)",entries[i].name,entries[i].size); + if (entries[i].type & ST_FUNCTION || !(entries[i].type & ST_DATA)) + { + sprintf(temp,"%s",entries[i].name); + } else { + sprintf(temp,"0x%08X (%s)",entries[i].vaddress,entries[i].name); + } + int index = ListBox_AddString(listbox,temp); ListBox_SetItemData(listbox,index,entries[i].vaddress); } diff --git a/Core/Debugger/SymbolMap.h b/Core/Debugger/SymbolMap.h index daf3cb8bb4..20d572c3e0 100644 --- a/Core/Debugger/SymbolMap.h +++ b/Core/Debugger/SymbolMap.h @@ -58,6 +58,7 @@ public: void IncreaseRunCount(int num); unsigned int GetRunCount(int num); void SortSymbols(); + const char* getDirectSymbol(u32 address); void UseFuncSignaturesFile(const char *filename, u32 maxAddress); void CompileFuncSignaturesFile(const char *filename); diff --git a/Core/MIPS/MIPSDebugInterface.cpp b/Core/MIPS/MIPSDebugInterface.cpp index c925aaff51..3a64260f1e 100644 --- a/Core/MIPS/MIPSDebugInterface.cpp +++ b/Core/MIPS/MIPSDebugInterface.cpp @@ -81,6 +81,11 @@ const char *MIPSDebugInterface::getDescription(unsigned int address) return symbolMap.GetDescription(address); } +const char *MIPSDebugInterface::findSymbolForAddress(unsigned int address) +{ + return symbolMap.getDirectSymbol(address); +} + void MIPSDebugInterface::runToBreakpoint() { diff --git a/Core/MIPS/MIPSDebugInterface.h b/Core/MIPS/MIPSDebugInterface.h index 93c15d8249..4a75959e96 100644 --- a/Core/MIPS/MIPSDebugInterface.h +++ b/Core/MIPS/MIPSDebugInterface.h @@ -40,6 +40,7 @@ public: virtual void runToBreakpoint(); virtual int getColor(unsigned int address); virtual const char *getDescription(unsigned int address); + virtual const char *findSymbolForAddress(unsigned int address); //overridden functions const char *GetName(); diff --git a/Core/MIPS/MIPSTables.cpp b/Core/MIPS/MIPSTables.cpp index a15707929a..7326a66a27 100644 --- a/Core/MIPS/MIPSTables.cpp +++ b/Core/MIPS/MIPSTables.cpp @@ -893,8 +893,7 @@ void MIPSDisAsm(u32 op, u32 pc, char *out, bool tabsToSpaces) { if (op == 0) { - //ANDEQ R0,R0,R0 is probably not used for legitimate purposes :P - sprintf(out,"---\t---"); + sprintf(out,"nop"); } else { diff --git a/Windows/Debugger/CtrlDisAsmView.cpp b/Windows/Debugger/CtrlDisAsmView.cpp index b57871f5d3..3b9a3e8924 100644 --- a/Windows/Debugger/CtrlDisAsmView.cpp +++ b/Windows/Debugger/CtrlDisAsmView.cpp @@ -1,4 +1,4 @@ -// NOTE: Apologies for the quality of this code, this is really from pre-opensource Dolphin - that is, 2003. +// NOTE: Apologies for the quality of this code, this is really from pre-opensource Dolphin - that is, 2003. #include "../resource.h" #include "../../Core/MemMap.h" @@ -74,6 +74,14 @@ LRESULT CALLBACK CtrlDisAsmView::wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPA case WM_VSCROLL: ccp->onVScroll(wParam,lParam); break; + case WM_MOUSEWHEEL: + if (GET_WHEEL_DELTA_WPARAM(wParam) > 0) + { + ccp->scrollWindow(-3); + } else if (GET_WHEEL_DELTA_WPARAM(wParam) < 0) { + ccp->scrollWindow(3); + } + break; case WM_ERASEBKGND: return FALSE; case WM_KEYDOWN: @@ -93,6 +101,9 @@ LRESULT CALLBACK CtrlDisAsmView::wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPA ccp->hasFocus=false; ccp->redraw(); break; + case WM_GETDLGCODE: + return DLGC_WANTARROWS|DLGC_WANTTAB; + break; default: break; } @@ -115,15 +126,21 @@ CtrlDisAsmView::CtrlDisAsmView(HWND _wnd) SetWindowLongPtr(wnd, GWLP_USERDATA, (LONG)this); SetWindowLong(wnd, GWL_STYLE, GetWindowLong(wnd,GWL_STYLE) | WS_VSCROLL); SetScrollRange(wnd, SB_VERT, -1,1,TRUE); - font = CreateFont(11,0,0,0,FW_DONTCARE,FALSE,FALSE,FALSE,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH, + font = CreateFont(12,8,0,0,FW_DONTCARE,FALSE,FALSE,FALSE,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH, "Lucida Console"); - boldfont = CreateFont(11,0,0,0,FW_DEMIBOLD,FALSE,FALSE,FALSE,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH, + boldfont = CreateFont(12,8,0,0,FW_DEMIBOLD,FALSE,FALSE,FALSE,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH, "Lucida Console"); curAddress=0; - rowHeight=12; - align=2; - selecting=false; + rowHeight=14; + instructionSize=4; showHex=false; + hasFocus = false; + + jumpIndex = 0; + windowStart = curAddress; + whiteBackground = false; + displaySymbols = true; + calculatePixelPositions(); } @@ -133,188 +150,236 @@ CtrlDisAsmView::~CtrlDisAsmView() DeleteObject(boldfont); } -void fillRect(HDC hdc, RECT *rect, COLORREF colour) +COLORREF scaleColor(COLORREF color, float factor) { - COLORREF oldcr = SetBkColor(hdc, colour); - ExtTextOut(hdc, 0, 0, ETO_OPAQUE, rect, "", 0, 0); - SetBkColor(hdc, oldcr); + unsigned char r = color & 0xFF; + unsigned char g = (color >> 8) & 0xFF; + unsigned char b = (color >> 16) & 0xFF; + + r = min(255,max((int)(r*factor),0)); + g = min(255,max((int)(g*factor),0)); + b = min(255,max((int)(b*factor),0)); + + return (color & 0xFF000000) | (b << 16) | (g << 8) | r; } - -u32 halfAndHalf(u32 a, u32 b) +void CtrlDisAsmView::getDisasmAddressText(u32 address, char* dest) { - return ((a>>1)&0x7f7f7f7f) + ((b>>1)&0x7f7f7f7f); + if (displaySymbols) + { + const char* addressSymbol = debugger->findSymbolForAddress(address); + if (addressSymbol != NULL) + { + if (memcmp(addressSymbol,"z_",2) == 0) addressSymbol += 2; + if (memcmp(addressSymbol,"zz_",3) == 0) addressSymbol += 3; + + for (int k = 0; addressSymbol[k] != 0; k++) + { + // abbreviate long names + if (k == 16 && addressSymbol[k+1] != 0) + { + *dest++ = '+'; + break; + } + *dest++ = addressSymbol[k]; + } + *dest++ = ':'; + *dest = 0; + } else { + sprintf(dest," %08X",address); + } + } else { + sprintf(dest,"%08X %08X",address,Memory::ReadUnchecked_U32(address)); + } } +void CtrlDisAsmView::parseDisasm(const char* disasm, char* opcode, char* arguments) +{ + branchTarget = -1; + branchRegister = -1; + + // copy opcode + while (*disasm != 0 && *disasm != '\t') + { + *opcode++ = *disasm++; + } + *opcode = 0; + + if (*disasm++ == 0) + { + *arguments = 0; + return; + } + + const char* jumpAddress = strstr(disasm,"->$"); + const char* jumpRegister = strstr(disasm,"->"); + while (*disasm != 0) + { + // parse symbol + if (disasm == jumpAddress) + { + sscanf(disasm+3,"%08x",&branchTarget); + + const char* addressSymbol = debugger->findSymbolForAddress(branchTarget); + if (addressSymbol != NULL && displaySymbols) + { + if (memcmp(addressSymbol,"z_",2) == 0) addressSymbol += 2; + if (memcmp(addressSymbol,"zz_",3) == 0) addressSymbol += 3; + arguments += sprintf(arguments,"%s",addressSymbol); + } else { + arguments += sprintf(arguments,"0x%08X",branchTarget); + } + + disasm += 3+8; + continue; + } + + if (disasm == jumpRegister) + { + disasm += 2; + for (int i = 0; i < 32; i++) + { + if (stricmp(jumpRegister+2,debugger->GetRegName(0,i)) == 0) + { + branchRegister = i; + break; + } + } + } + + if (*disasm == ' ') + { + disasm++; + continue; + } + *arguments++ = *disasm++; + } + + *arguments = 0; +} -//Yeah this truly turned into a mess with the latest additions.. but it sure looks nice ;) void CtrlDisAsmView::onPaint(WPARAM wParam, LPARAM lParam) { + if (!debugger->isAlive()) return; + struct branch { int src,dst,srcAddr; - bool conditional; }; branch branches[256]; int numBranches=0; - - - GetClientRect(wnd, &rect); PAINTSTRUCT ps; - HDC hdc; - - hdc = BeginPaint(wnd, &ps); - // TODO: Add any drawing code here... - int width = rect.right; - int numRows=(rect.bottom/rowHeight)/2+1; - //numRows=(numRows&(~1)) + 1; - SetBkMode(hdc, TRANSPARENT); - DWORD bgColor = 0xffffff; - HPEN nullPen=CreatePen(0,0,bgColor); - HPEN currentPen=CreatePen(0,0,0); - HPEN selPen=CreatePen(0,0,0x808080); - HPEN condPen=CreatePen(0,0,0xFF3020); + HDC actualHdc = BeginPaint(wnd, &ps); + HDC hdc = CreateCompatibleDC(actualHdc); + HBITMAP hBM = CreateCompatibleBitmap(actualHdc, rect.right-rect.left, rect.bottom-rect.top); + SelectObject(hdc, hBM); - LOGBRUSH lbr; - lbr.lbHatch=0; lbr.lbStyle=0; - lbr.lbColor=bgColor; - HBRUSH nullBrush=CreateBrushIndirect(&lbr); - lbr.lbColor=0xFFEfE8; - HBRUSH currentBrush=CreateBrushIndirect(&lbr); - lbr.lbColor=0x70FF70; - HBRUSH pcBrush=CreateBrushIndirect(&lbr); + SetBkMode(hdc, TRANSPARENT); + + HPEN nullPen=CreatePen(0,0,0xffffff); + HPEN condPen=CreatePen(0,0,0xFF3020); + HBRUSH nullBrush=CreateSolidBrush(0xffffff); + HBRUSH currentBrush=CreateSolidBrush(0xFFEfE8); HPEN oldPen=(HPEN)SelectObject(hdc,nullPen); HBRUSH oldBrush=(HBRUSH)SelectObject(hdc,nullBrush); - - HFONT oldFont = (HFONT)SelectObject(hdc,(HGDIOBJ)font); HICON breakPoint = (HICON)LoadIcon(GetModuleHandle(0),(LPCSTR)IDI_STOP); HICON breakPointDisable = (HICON)LoadIcon(GetModuleHandle(0),(LPCSTR)IDI_STOPDISABLE); - int i; - curAddress&=~(align-1); - align=(debugger->getInstructionSize(0)); - for (i=-numRows; i<=numRows; i++) + for (int i = 0; i < visibleRows+2; i++) { - unsigned int address=curAddress + i*align; + unsigned int address=windowStart + i*instructionSize; - int rowY1 = rect.bottom/2 + rowHeight*i - rowHeight/2; - int rowY2 = rect.bottom/2 + rowHeight*i + rowHeight/2; - char temp[256]; - int temp_len = sprintf(temp,"%08x",address); + int rowY1 = rowHeight*i; + int rowY2 = rowHeight*(i+1); - lbr.lbColor=marker==address?0xffeee0:debugger->getColor(address); - u32 bg = lbr.lbColor; - //SelectObject(hdc,currentBrush); - SelectObject(hdc,nullPen); - Rectangle(hdc,0,rowY1,16,rowY2); - - if (selecting && address == selection) - SelectObject(hdc,selPen); - else - SelectObject(hdc,i==0 ? currentPen : nullPen); - - HBRUSH mojsBrush=CreateBrushIndirect(&lbr); - SelectObject(hdc,mojsBrush); + // draw background + COLORREF backgroundColor = whiteBackground ? 0xFFFFFF : debugger->getColor(address); + COLORREF textColor = 0x000000; if (address == debugger->getPC()) - SelectObject(hdc,pcBrush); - //else - // SelectObject(hdc,i==0 ? currentBrush : nullBrush); - - Rectangle(hdc,16,rowY1,width,rowY2); - SelectObject(hdc,currentBrush); - DeleteObject(mojsBrush); - SetTextColor(hdc,halfAndHalf(bg,0)); - TextOut(hdc,17,rowY1,temp,temp_len); - SetTextColor(hdc,0x000000); - if (debugger->isAlive()) { - const TCHAR *dizz = debugger->disasm(address, align); - char dis[512]; - strcpy(dis, dizz); - TCHAR *dis2 = strchr(dis,'\t'); - TCHAR desc[256]=""; - if (dis2) + backgroundColor = scaleColor(backgroundColor,1.05f); + } + + if (address == curAddress) + { + if (hasFocus) { - *dis2=0; - dis2++; - const char *mojs=strstr(dis2,"->$"); - if (mojs) - { - for (int j=0; j<8; ++j) - { - bool found=false; - for (int k=0; k<22; ++k) - { - if (mojs[j+3]=="0123456789ABCDEFabcdef"[k]) - found=true; - } - if (!found) - { - mojs=0; - break; - } - } - } - if (mojs) - { - int offs; - sscanf(mojs+3,"%08x",&offs); - branches[numBranches].src=rowY1 + rowHeight/2; - branches[numBranches].srcAddr=address/align; - branches[numBranches].dst=(int)(rowY1+((__int64)offs-(__int64)address)*rowHeight/align + rowHeight/2); - branches[numBranches].conditional = (dis[1]!=0); //unconditional 'b' branch - numBranches++; - const char *t = debugger->getDescription(offs); - if (memcmp(t,"z_",2)==0) - t+=2; - if (memcmp(t,"zz_",3)==0) - t+=3; - sprintf(desc,"-->%s", t); - SetTextColor(hdc,0x600060); - } - else - SetTextColor(hdc,0x000000); - TextOut(hdc,149,rowY1,dis2,(int)strlen(dis2)); - } - SetTextColor(hdc,0x007000); - SelectObject(hdc,boldfont); - TextOut(hdc,84,rowY1,dis,(int)strlen(dis)); - SelectObject(hdc,font); - if (desc[0]==0) - { - const char *t = debugger->getDescription(address); - if (memcmp(t,"z_",2)==0) - t+=2; - if (memcmp(t,"zz_",3)==0) - t+=3; - strcpy(desc,t); - } - if (memcmp(desc,"-->",3) == 0) - SetTextColor(hdc,0x0000FF); - else - SetTextColor(hdc,halfAndHalf(halfAndHalf(bg,0),bg)); - //char temp[256]; - //UnDecorateSymbolName(desc,temp,255,UNDNAME_COMPLETE); - if (strlen(desc)) - TextOut(hdc,max(280,width/3+190),rowY1,desc,(int)strlen(desc)); - if (debugger->isBreakpoint(address)) - { - DrawIconEx(hdc,2,rowY1,breakPoint,32,32,0,0,DI_NORMAL); + backgroundColor = 0xFF9933; + textColor = 0xFFFFFF; + } else { + backgroundColor = 0xC0C0C0; } } + + HBRUSH backgroundBrush = CreateSolidBrush(backgroundColor); + HPEN backgroundPen = CreatePen(0,0,backgroundColor); + SelectObject(hdc,backgroundBrush); + SelectObject(hdc,backgroundPen); + Rectangle(hdc,0,rowY1,rect.right,rowY1+rowHeight); + + SelectObject(hdc,currentBrush); + SelectObject(hdc,nullPen); + + DeleteObject(backgroundBrush); + DeleteObject(backgroundPen); + + // display address/symbol + if (debugger->isBreakpoint(address)) + { + textColor = 0x0000FF; + DrawIconEx(hdc,2,rowY1,breakPoint,32,32,0,0,DI_NORMAL); + } + SetTextColor(hdc,textColor); + + char addressText[64]; + getDisasmAddressText(address,addressText); + TextOut(hdc,pixelPositions.addressStart,rowY1+2,addressText,(int)strlen(addressText)); + + if (address == debugger->getPC()) + { + TextOutW(hdc,pixelPositions.opcodeStart-8,rowY1,L"■",1); + } + + // display opcode + char opcode[64],arguments[256]; + const char *dizz = debugger->disasm(address, instructionSize); + parseDisasm(dizz,opcode,arguments); + + int length = (int) strlen(arguments); + if (length != 0) TextOut(hdc,pixelPositions.argumentsStart,rowY1+2,arguments,length); + + SelectObject(hdc,boldfont); + 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 + { + branches[numBranches].src=rowY1 + rowHeight/2; + branches[numBranches].srcAddr=address/instructionSize; + branches[numBranches].dst=(int)(rowY1+((__int64)branchTarget-(__int64)address)*rowHeight/instructionSize + rowHeight/2); + numBranches++; + } } - for (i=0; i-200) + if (branches[i].dst < 0) { + LineTo(hdc,x+2,branches[i].src); + LineTo(hdc,x+2,0); + } else if (branches[i].dst > rect.bottom) + { + LineTo(hdc,x+2,branches[i].src); + LineTo(hdc,x+2,rect.bottom); + } else { LineTo(hdc,x+2,branches[i].src); LineTo(hdc,x+2,branches[i].dst); LineTo(hdc,x-4,branches[i].dst); @@ -323,29 +388,21 @@ void CtrlDisAsmView::onPaint(WPARAM wParam, LPARAM lParam) LineTo(hdc,x-4,branches[i].dst); LineTo(hdc,x+1,branches[i].dst+5); } - else - { - LineTo(hdc,x+4,branches[i].src); - //MoveToEx(hdc,x+2,branches[i].dst-4,0); - //LineTo(hdc,x+6,branches[i].dst); - //LineTo(hdc,x+1,branches[i].dst+5); - } - //LineTo(hdc,x,branches[i].dst+4); - - //LineTo(hdc,x-2,branches[i].dst); } SelectObject(hdc,oldFont); SelectObject(hdc,oldPen); SelectObject(hdc,oldBrush); - + + // copy bitmap to the actual hdc + BitBlt(actualHdc,0,0,rect.right,rect.bottom,hdc,0,0,SRCCOPY); + DeleteObject(hBM); + DeleteDC(hdc); + DeleteObject(nullPen); - DeleteObject(currentPen); - DeleteObject(selPen); DeleteObject(condPen); DeleteObject(nullBrush); - DeleteObject(pcBrush); DeleteObject(currentBrush); DestroyIcon(breakPoint); @@ -358,23 +415,23 @@ void CtrlDisAsmView::onPaint(WPARAM wParam, LPARAM lParam) void CtrlDisAsmView::onVScroll(WPARAM wParam, LPARAM lParam) { - RECT rect; - GetClientRect(this->wnd, &rect); - int page=(rect.bottom/rowHeight)/2-1; - switch (wParam & 0xFFFF) { case SB_LINEDOWN: - curAddress+=align; + windowStart += instructionSize; + curAddress += instructionSize; break; case SB_LINEUP: - curAddress-=align; + windowStart -= instructionSize; + curAddress -= instructionSize; break; case SB_PAGEDOWN: - curAddress+=page*align; + windowStart += visibleRows*instructionSize; + curAddress += visibleRows*instructionSize; break; case SB_PAGEUP: - curAddress-=page*align; + windowStart -= visibleRows*instructionSize; + curAddress -= visibleRows*instructionSize; break; default: return; @@ -382,25 +439,76 @@ void CtrlDisAsmView::onVScroll(WPARAM wParam, LPARAM lParam) redraw(); } +void CtrlDisAsmView::followBranch() +{ + char opcode[64],arguments[256]; + const char *dizz = debugger->disasm(curAddress, instructionSize); + parseDisasm(dizz,opcode,arguments); + + if (jumpIndex == 256) return; + if (branchTarget != -1) + { + jumpStack[jumpIndex++] = curAddress; + gotoAddr(branchTarget); + } else if (branchRegister != -1) + { + jumpStack[jumpIndex++] = curAddress; + gotoAddr(debugger->GetRegValue(0,branchRegister)); + } +} + + void CtrlDisAsmView::onKeyDown(WPARAM wParam, LPARAM lParam) { - RECT rect; - GetClientRect(this->wnd, &rect); - int page=(rect.bottom/rowHeight)/2-1; + u32 windowEnd = windowStart+visibleRows*instructionSize; switch (wParam & 0xFFFF) { case VK_DOWN: - curAddress+=align; + if (curAddress == windowEnd-instructionSize) + { + windowStart += instructionSize; + } + curAddress += instructionSize; break; case VK_UP: - curAddress-=align; + if (curAddress == windowStart) + { + windowStart -= instructionSize; + } + curAddress-=instructionSize; break; case VK_NEXT: - curAddress+=page*align; + if (curAddress != windowEnd-instructionSize) + { + curAddress = windowEnd-instructionSize; + } else { + windowStart += visibleRows*instructionSize; + curAddress += visibleRows*instructionSize; + } break; case VK_PRIOR: - curAddress-=page*align; + if (curAddress != windowStart) + { + curAddress = windowStart; + } else { + windowStart -= visibleRows*instructionSize; + curAddress -= visibleRows*instructionSize; + } + break; + case VK_LEFT: + if (jumpIndex == 0) + { + gotoPC(); + } else { + gotoAddr(jumpStack[--jumpIndex]); + } + return; + case VK_RIGHT: + followBranch(); + return; + case VK_TAB: + displaySymbols = !displaySymbols; break; default: return; @@ -411,6 +519,9 @@ void CtrlDisAsmView::onKeyDown(WPARAM wParam, LPARAM lParam) void CtrlDisAsmView::redraw() { + GetClientRect(wnd, &rect); + visibleRows = rect.bottom/rowHeight; + InvalidateRect(wnd, NULL, FALSE); UpdateWindow(wnd); } @@ -419,22 +530,19 @@ void CtrlDisAsmView::redraw() void CtrlDisAsmView::onMouseDown(WPARAM wParam, LPARAM lParam, int button) { int x = LOWORD(lParam); - int y = HIWORD(lParam); - if (x>16) + int y = HIWORD(lParam); + + int newAddress = yToAddress(y); + if (button == 1) { - oldSelection=selection; - selection=yToAddress(y); - SetCapture(wnd); - bool oldselecting=selecting; - selecting=true; - if (!oldselecting || (selection!=oldSelection)) - redraw(); - } - else - { - debugger->toggleBreakpoint(yToAddress(y)); - redraw(); + if (newAddress == curAddress) + { + debugger->toggleBreakpoint(curAddress); + } } + + curAddress = newAddress; + redraw(); } void CtrlDisAsmView::onMouseUp(WPARAM wParam, LPARAM lParam, int button) @@ -449,61 +557,55 @@ void CtrlDisAsmView::onMouseUp(WPARAM wParam, LPARAM lParam, int button) case ID_DISASM_GOTOINMEMORYVIEW: for (int i=0; iGoto(selection); + memoryWindow[i]->Goto(curAddress); break; case ID_DISASM_ADDHLE: break; case ID_DISASM_TOGGLEBREAKPOINT: - debugger->toggleBreakpoint(selection); + debugger->toggleBreakpoint(curAddress); redraw(); break; case ID_DISASM_COPYINSTRUCTIONDISASM: - W32Util::CopyTextToClipboard(wnd, debugger->disasm(selection,align)); + { + char temp[256],opcode[64],arguments[256]; + const char *dizz = debugger->disasm(curAddress, instructionSize); + parseDisasm(dizz,opcode,arguments); + sprintf(temp,"%s\t%s",opcode,arguments); + + W32Util::CopyTextToClipboard(wnd, temp); + } break; case ID_DISASM_COPYADDRESS: { char temp[16]; - sprintf(temp,"%08x",selection); + sprintf(temp,"%08X",curAddress); W32Util::CopyTextToClipboard(wnd, temp); } break; case ID_DISASM_SETPCTOHERE: - debugger->setPC(selection); + debugger->setPC(curAddress); redraw(); break; case ID_DISASM_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); - } - } - } + followBranch(); break; case ID_DISASM_COPYINSTRUCTIONHEX: { char temp[24]; - sprintf(temp,"%08x",debugger->readMemory(selection)); + sprintf(temp,"%08X",debugger->readMemory(curAddress)); W32Util::CopyTextToClipboard(wnd,temp); } break; case ID_DISASM_RUNTOHERE: { - debugger->setBreakpoint(selection); + debugger->setBreakpoint(curAddress); debugger->runToBreakpoint(); redraw(); } break; case ID_DISASM_RENAMEFUNCTION: { - int sym = symbolMap.GetSymbolNum(selection); + int sym = symbolMap.GetSymbolNum(curAddress); if (sym != -1) { char name[256]; @@ -525,45 +627,26 @@ void CtrlDisAsmView::onMouseUp(WPARAM wParam, LPARAM lParam, int button) } return; } - int x = LOWORD(lParam); - int y = HIWORD(lParam); - if (x>16) - { - curAddress=yToAddress(y); - selecting=false; - ReleaseCapture(); - redraw(); - } + + redraw(); } void CtrlDisAsmView::onMouseMove(WPARAM wParam, LPARAM lParam, int button) { - if (button&1) - { - int x = LOWORD(lParam); - int y = (signed short)HIWORD(lParam); - if (x>16) - { - if (y<0) - { - curAddress-=align; - redraw(); - } - else if (y>rect.bottom) - { - curAddress+=align; - redraw(); - } - else - onMouseDown(wParam,lParam,1); - } - } + } int CtrlDisAsmView::yToAddress(int y) { - int ydiff=y-rect.bottom/2-rowHeight/2; - ydiff=(int)(floorf((float)ydiff / (float)rowHeight))+1; - return curAddress + ydiff * align; + int line = y/rowHeight; + return windowStart + line*instructionSize; } + +void CtrlDisAsmView::calculatePixelPositions() +{ + pixelPositions.addressStart = 16; + pixelPositions.opcodeStart = pixelPositions.addressStart + 18*8; + pixelPositions.argumentsStart = pixelPositions.opcodeStart + 9*8; + pixelPositions.arrowsStart = pixelPositions.argumentsStart + 30*8; +} \ No newline at end of file diff --git a/Windows/Debugger/CtrlDisAsmView.h b/Windows/Debugger/CtrlDisAsmView.h index 34130c96aa..6168fe641c 100644 --- a/Windows/Debugger/CtrlDisAsmView.h +++ b/Windows/Debugger/CtrlDisAsmView.h @@ -30,19 +30,35 @@ class CtrlDisAsmView RECT rect; int curAddress; - int align; int rowHeight; - int selection; - int marker; - int oldSelection; - bool selectionChanged; - bool selecting; bool hasFocus; bool showHex; DebugInterface *debugger; static TCHAR szClassName[]; + int windowStart; + int visibleRows; + int instructionSize; + bool whiteBackground; + bool displaySymbols; + u32 branchTarget; + int branchRegister; + + struct { + int addressStart; + int opcodeStart; + int argumentsStart; + int arrowsStart; + } pixelPositions; + + u32 jumpStack[256]; + int jumpIndex; + + void followBranch(); + void calculatePixelPositions(); + void getDisasmAddressText(u32 address, char* dest); + void parseDisasm(const char* disasm, char* opcode, char* arguments); public: CtrlDisAsmView(HWND _wnd); ~CtrlDisAsmView(); @@ -59,17 +75,13 @@ public: void onMouseMove(WPARAM wParam, LPARAM lParam, int button); void redraw(); - void setAlign(int l) - { - align=l; - } int yToAddress(int y); void setDebugger(DebugInterface *deb) { debugger=deb; curAddress=debugger->getPC(); - align=debugger->getInstructionSize(0); + instructionSize=debugger->getInstructionSize(0); } DebugInterface *getDebugger() { @@ -77,13 +89,20 @@ public: } void gotoAddr(unsigned int addr) { - curAddress=addr&(~(align-1)); + u32 windowEnd = windowStart+visibleRows*instructionSize; + u32 newAddress = addr&(~(instructionSize-1)); + + if (newAddress < windowStart || newAddress >= windowEnd) + { + windowStart = newAddress-visibleRows/2*instructionSize; + } + + curAddress = newAddress; redraw(); } void gotoPC() { - curAddress=debugger->getPC()&(~(align-1)); - redraw(); + gotoAddr(debugger->getPC()&(~(instructionSize-1))); } unsigned int getSelection() { @@ -100,4 +119,11 @@ public: debugger->toggleBreakpoint(curAddress); redraw(); } + + void scrollWindow(int lines) + { + windowStart += lines*instructionSize; + curAddress += lines*instructionSize; + redraw(); + } }; \ No newline at end of file diff --git a/Windows/Debugger/CtrlMemView.cpp b/Windows/Debugger/CtrlMemView.cpp index 817787481f..7927d3ad26 100644 --- a/Windows/Debugger/CtrlMemView.cpp +++ b/Windows/Debugger/CtrlMemView.cpp @@ -32,7 +32,6 @@ CtrlMemView::CtrlMemView(HWND _wnd) "Lucida Console"); curAddress=0; rowHeight=12; - selecting=false; mode=MV_NORMAL; debugger = 0; @@ -125,7 +124,7 @@ LRESULT CALLBACK CtrlMemView::wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM ccp->onChar(wParam,lParam); break; case WM_LBUTTONDOWN: SetFocus(hwnd); lmbDown=true; ccp->onMouseDown(wParam,lParam,1); break; - case WM_RBUTTONDOWN: rmbDown=true; ccp->onMouseDown(wParam,lParam,2); break; + case WM_RBUTTONDOWN: SetFocus(hwnd); rmbDown=true; ccp->onMouseDown(wParam,lParam,2); break; case WM_MOUSEMOVE: ccp->onMouseMove(wParam,lParam,(lmbDown?1:0) | (rmbDown?2:0)); break; case WM_LBUTTONUP: lmbDown=false; ccp->onMouseUp(wParam,lParam,1); break; case WM_RBUTTONUP: rmbDown=false; ccp->onMouseUp(wParam,lParam,2); break; @@ -449,7 +448,16 @@ void CtrlMemView::onMouseUp(WPARAM wParam, LPARAM lParam, int button) case ID_MEMVIEW_COPYVALUE: { char temp[24]; - sprintf(temp,"%08x",Memory::ReadUnchecked_U32(selection)); + + // it's admittedly not really useful like this + if (asciiSelected) + { + unsigned char c = Memory::IsValidAddress(curAddress) ? Memory::ReadUnchecked_U8(curAddress) : '.'; + if (c < 32 || c >= 128) c = '.'; + sprintf(temp,"%c",c); + } else { + sprintf(temp,"%02X",Memory::IsValidAddress(curAddress) ? Memory::ReadUnchecked_U8(curAddress) : 0xFF); + } W32Util::CopyTextToClipboard(wnd,temp); } break; diff --git a/Windows/Debugger/CtrlMemView.h b/Windows/Debugger/CtrlMemView.h index 02dac887dc..0110297485 100644 --- a/Windows/Debugger/CtrlMemView.h +++ b/Windows/Debugger/CtrlMemView.h @@ -47,10 +47,6 @@ class CtrlMemView int visibleRows; - int selection; - int oldSelection; - bool selectionChanged; - bool selecting; bool hasFocus; static TCHAR szClassName[]; DebugInterface *debugger; diff --git a/Windows/Debugger/Debugger_Disasm.cpp b/Windows/Debugger/Debugger_Disasm.cpp index 135a6af73a..79fd177776 100644 --- a/Windows/Debugger/Debugger_Disasm.cpp +++ b/Windows/Debugger/Debugger_Disasm.cpp @@ -137,7 +137,6 @@ BOOL CDisasm::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) switch (HIWORD(wParam)) { case CBN_DBLCLK: - case CBN_SELCHANGE: { HWND lb = GetDlgItem(m_hDlg,LOWORD(wParam)); int n = ListBox_GetCurSel(lb); @@ -426,7 +425,6 @@ void CDisasm::UpdateDialog(bool _bComplete) ComboBox_SetCurSel(gotoInt,0); */ CtrlDisAsmView *ptr = CtrlDisAsmView::getFrom(GetDlgItem(m_hDlg,IDC_DISASMVIEW)); - ptr->setAlign(cpu->getInstructionSize(0)); ptr->redraw(); CtrlRegisterList *rl = CtrlRegisterList::getFrom(GetDlgItem(m_hDlg,IDC_REGLIST)); rl->redraw(); diff --git a/Windows/ppsspp.rc b/Windows/ppsspp.rc index 1cf38844d8..fa2bd34a2b 100644 Binary files a/Windows/ppsspp.rc and b/Windows/ppsspp.rc differ