1 // NOTE: Apologies for the quality of this code, this is really from pre-opensource Dolphin - that is, 2003. 2 3 #pragma once 4 5 ////////////////////////////////////////////////////////////////////////// 6 //CtrlDisAsmView 7 // CtrlDisAsmView.cpp 8 ////////////////////////////////////////////////////////////////////////// 9 //This Win32 control is made to be flexible and usable with 10 //every kind of CPU architechture that has fixed width instruction words. 11 //Just supply it an instance of a class derived from Debugger, with all methods 12 //overridden for full functionality. Look at the ppc one for an example. 13 // 14 //To add to a dialog box, just draw a User Control in the dialog editor, 15 //and set classname to "CtrlDisAsmView". you also need to call CtrlDisAsmView::init() 16 //before opening this dialog, to register the window class. 17 // 18 //To get a class instance to be able to access it, just use 19 // CtrlDisAsmView::getFrom(GetDlgItem(yourdialog, IDC_yourid)). 20 21 #include "../../Core/Debugger/DebugInterface.h" 22 #include "../../Core/Debugger/DisassemblyManager.h" 23 24 25 #include "Common/CommonWindows.h" 26 #include <vector> 27 #include <algorithm> 28 29 using std::min; 30 using std::max; 31 32 class CtrlDisAsmView 33 { 34 HWND wnd; 35 HFONT font; 36 HFONT boldfont; 37 RECT rect; 38 39 DisassemblyManager manager; 40 u32 curAddress; 41 u32 selectRangeStart; 42 u32 selectRangeEnd; 43 int rowHeight; 44 int charWidth; 45 46 bool hasFocus; 47 bool showHex; 48 DebugInterface *debugger; 49 static TCHAR szClassName[]; 50 51 u32 windowStart; 52 int visibleRows; 53 bool whiteBackground; 54 bool displaySymbols; 55 56 struct { 57 int addressStart; 58 int opcodeStart; 59 int argumentsStart; 60 int arrowsStart; 61 } pixelPositions; 62 63 std::vector<u32> jumpStack; 64 65 std::string searchQuery; 66 int matchAddress; 67 bool searching; 68 bool dontRedraw; 69 bool keyTaken; 70 71 void assembleOpcode(u32 address, std::string defaultText); 72 std::string disassembleRange(u32 start, u32 size); 73 void disassembleToFile(); 74 void search(bool continueSearch); 75 void followBranch(); 76 void calculatePixelPositions(); 77 bool getDisasmAddressText(u32 address, char* dest, bool abbreviateLabels, bool showData); 78 void updateStatusBarText(); 79 void drawBranchLine(HDC hdc, std::map<u32,int>& addressPositions, BranchLine& line); 80 void copyInstructions(u32 startAddr, u32 endAddr, bool withDisasm); 81 std::set<std::string> getSelectedLineArguments(); 82 void drawArguments(HDC hdc, const DisassemblyLineInfo &line, int x, int y, int textColor, const std::set<std::string> ¤tArguments); 83 84 public: 85 CtrlDisAsmView(HWND _wnd); 86 ~CtrlDisAsmView(); 87 static void init(); 88 static void deinit(); 89 static LRESULT CALLBACK wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); 90 static CtrlDisAsmView * getFrom(HWND wnd); 91 92 void onChar(WPARAM wParam, LPARAM lParam); 93 void onPaint(WPARAM wParam, LPARAM lParam); 94 void onVScroll(WPARAM wParam, LPARAM lParam); 95 void onKeyDown(WPARAM wParam, LPARAM lParam); 96 void onKeyUp(WPARAM wParam, LPARAM lParam); 97 void onMouseDown(WPARAM wParam, LPARAM lParam, int button); 98 void onMouseUp(WPARAM wParam, LPARAM lParam, int button); 99 void onMouseMove(WPARAM wParam, LPARAM lParam, int button); 100 void scrollAddressIntoView(); 101 bool curAddressIsVisible(); 102 void redraw(); 103 void scanFunctions(); clearFunctions()104 void clearFunctions() { manager.clear(); }; 105 106 void getOpcodeText(u32 address, char* dest, int bufsize); getRowHeight()107 int getRowHeight() { return rowHeight; }; 108 u32 yToAddress(int y); 109 setDontRedraw(bool b)110 void setDontRedraw(bool b) { dontRedraw = b; }; setDebugger(DebugInterface * deb)111 void setDebugger(DebugInterface *deb) 112 { 113 debugger=deb; 114 curAddress=debugger->getPC(); 115 manager.setCpu(deb); 116 } getDebugger()117 DebugInterface *getDebugger() 118 { 119 return debugger; 120 } 121 122 void scrollStepping(u32 newPc); 123 u32 getInstructionSizeAt(u32 address); 124 gotoAddr(unsigned int addr)125 void gotoAddr(unsigned int addr) 126 { 127 u32 windowEnd = manager.getNthNextAddress(windowStart,visibleRows); 128 u32 newAddress = manager.getStartAddress(addr); 129 130 if (newAddress < windowStart || newAddress >= windowEnd) 131 { 132 windowStart = manager.getNthPreviousAddress(newAddress,visibleRows/2); 133 } 134 135 setCurAddress(newAddress); 136 scanFunctions(); 137 redraw(); 138 } gotoPC()139 void gotoPC() 140 { 141 gotoAddr(debugger->getPC()); 142 } getSelection()143 u32 getSelection() 144 { 145 return curAddress; 146 } 147 setShowMode(bool s)148 void setShowMode(bool s) 149 { 150 showHex=s; 151 } 152 153 void toggleBreakpoint(bool toggleEnabled = false); 154 void editBreakpoint(); 155 scrollWindow(int lines)156 void scrollWindow(int lines) 157 { 158 if (lines < 0) 159 windowStart = manager.getNthPreviousAddress(windowStart,abs(lines)); 160 else 161 windowStart = manager.getNthNextAddress(windowStart,lines); 162 163 scanFunctions(); 164 redraw(); 165 } 166 167 void setCurAddress(u32 newAddress, bool extend = false) 168 { 169 newAddress = manager.getStartAddress(newAddress); 170 u32 after = manager.getNthNextAddress(newAddress,1); 171 curAddress = newAddress; 172 selectRangeStart = extend ? std::min(selectRangeStart, newAddress) : newAddress; 173 selectRangeEnd = extend ? std::max(selectRangeEnd, after) : after; 174 updateStatusBarText(); 175 } 176 };