Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
hrydgard
GitHub Repository: hrydgard/ppsspp
Path: blob/master/Windows/Debugger/CtrlDisAsmView.h
3185 views
1
#pragma once
2
3
// CtrlDisAsmView
4
//
5
// This Win32 control is made to be flexible and usable with
6
// every kind of CPU architecture that has fixed width instruction words.
7
// Just supply it an instance of a class derived from Debugger, with all methods
8
// overridden for full functionality. Look at the ppc one for an example.
9
//
10
// To add to a dialog box, just draw a User Control in the dialog editor,
11
// and set classname to "CtrlDisAsmView". you also need to call CtrlDisAsmView::init()
12
// before opening this dialog, to register the window class.
13
//
14
// To get a class instance to be able to access it, just use
15
// CtrlDisAsmView::getFrom(GetDlgItem(yourdialog, IDC_yourid)).
16
17
#include <algorithm>
18
#include <vector>
19
#include <string>
20
#include <set>
21
#include <map>
22
23
#include "Common/CommonWindows.h"
24
#include "Common/Log.h"
25
#include "Core/MIPS/MIPSDebugInterface.h"
26
#include "Core/Debugger/DisassemblyManager.h"
27
28
class CtrlDisAsmView
29
{
30
HWND wnd;
31
HFONT font;
32
HFONT boldfont;
33
RECT rect;
34
35
u32 curAddress;
36
u32 selectRangeStart;
37
u32 selectRangeEnd;
38
int rowHeight;
39
int charWidth;
40
41
bool hasFocus;
42
bool showHex;
43
MIPSDebugInterface *debugger;
44
static TCHAR szClassName[];
45
46
u32 windowStart;
47
int visibleRows;
48
bool whiteBackground;
49
bool displaySymbols;
50
51
struct {
52
int addressStart;
53
int opcodeStart;
54
int argumentsStart;
55
int arrowsStart;
56
} pixelPositions;
57
58
std::vector<u32> jumpStack;
59
60
std::string searchQuery;
61
int matchAddress;
62
bool searching;
63
bool dontRedraw;
64
bool keyTaken;
65
66
enum class CopyInstructionsMode {
67
OPCODES,
68
DISASM,
69
ADDRESSES,
70
};
71
72
void assembleOpcode(u32 address, const std::string &defaultText);
73
void disassembleToFile();
74
void search(bool continueSearch);
75
void followBranch();
76
void calculatePixelPositions();
77
void updateStatusBarText();
78
void drawBranchLine(HDC hdc, std::map<u32, int> &addressPositions, const BranchLine &line);
79
void CopyInstructions(u32 startAddr, u32 endAddr, CopyInstructionsMode mode);
80
void NopInstructions(u32 startAddr, u32 endAddr);
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> &currentArguments);
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 scanVisibleFunctions();
104
void clearFunctions() { g_disassemblyManager.clear(); };
105
106
void getOpcodeText(u32 address, char* dest, int bufsize);
107
int getRowHeight() { return rowHeight; };
108
u32 yToAddress(int y);
109
110
void setDontRedraw(bool b) { dontRedraw = b; };
111
void setDebugger(MIPSDebugInterface *deb)
112
{
113
debugger=deb;
114
curAddress=debugger->GetPC();
115
g_disassemblyManager.setCpu(deb);
116
}
117
DebugInterface *getDebugger()
118
{
119
return debugger;
120
}
121
122
void scrollStepping(u32 newPc);
123
u32 getInstructionSizeAt(u32 address);
124
125
void gotoAddr(unsigned int addr)
126
{
127
if (positionLocked_ != 0)
128
return;
129
u32 windowEnd = g_disassemblyManager.getNthNextAddress(windowStart,visibleRows);
130
u32 newAddress = g_disassemblyManager.getStartAddress(addr);
131
132
if (newAddress < windowStart || newAddress >= windowEnd)
133
{
134
windowStart = g_disassemblyManager.getNthPreviousAddress(newAddress,visibleRows/2);
135
}
136
137
setCurAddress(newAddress);
138
scanVisibleFunctions();
139
redraw();
140
}
141
void gotoPC()
142
{
143
gotoAddr(debugger->GetPC());
144
}
145
u32 getSelection()
146
{
147
return curAddress;
148
}
149
150
void setShowMode(bool s)
151
{
152
showHex=s;
153
}
154
155
void toggleBreakpoint(bool toggleEnabled = false);
156
void editBreakpoint();
157
158
void scrollWindow(int lines)
159
{
160
if (lines < 0)
161
windowStart = g_disassemblyManager.getNthPreviousAddress(windowStart,abs(lines));
162
else
163
windowStart = g_disassemblyManager.getNthNextAddress(windowStart,lines);
164
165
scanVisibleFunctions();
166
redraw();
167
}
168
169
void setCurAddress(u32 newAddress, bool extend = false)
170
{
171
newAddress = g_disassemblyManager.getStartAddress(newAddress);
172
const u32 after = g_disassemblyManager.getNthNextAddress(newAddress,1);
173
curAddress = newAddress;
174
selectRangeStart = extend ? std::min(selectRangeStart, newAddress) : newAddress;
175
selectRangeEnd = extend ? std::max(selectRangeEnd, after) : after;
176
updateStatusBarText();
177
}
178
179
void LockPosition() {
180
positionLocked_++;
181
}
182
void UnlockPosition() {
183
positionLocked_--;
184
_assert_(positionLocked_ >= 0);
185
}
186
187
private:
188
bool redrawScheduled_ = false;
189
int positionLocked_ = 0;
190
};
191
192