Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
hrydgard
GitHub Repository: hrydgard/ppsspp
Path: blob/master/Windows/Debugger/CtrlDisAsmView.h
5683 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
HWND wnd;
30
HFONT font;
31
HFONT boldfont;
32
RECT rect;
33
34
u32 curAddress;
35
u32 selectRangeStart;
36
u32 selectRangeEnd;
37
int rowHeight;
38
int charWidth;
39
40
bool hasFocus;
41
bool showHex;
42
MIPSDebugInterface *debugger;
43
44
u32 windowStart;
45
int visibleRows;
46
bool whiteBackground;
47
bool displaySymbols;
48
49
struct {
50
int addressStart;
51
int opcodeStart;
52
int argumentsStart;
53
int arrowsStart;
54
} pixelPositions;
55
56
std::vector<u32> jumpStack;
57
58
std::string searchQuery;
59
int matchAddress;
60
bool searching;
61
bool dontRedraw;
62
bool keyTaken;
63
64
enum class CopyInstructionsMode {
65
OPCODES,
66
DISASM,
67
ADDRESSES,
68
};
69
70
void assembleOpcode(u32 address, const std::string &defaultText);
71
void disassembleToFile();
72
void search(bool continueSearch);
73
void followBranch();
74
void calculatePixelPositions();
75
void updateStatusBarText();
76
void drawBranchLine(HDC hdc, std::map<u32, int> &addressPositions, const BranchLine &line);
77
void CopyInstructions(u32 startAddr, u32 endAddr, CopyInstructionsMode mode);
78
void NopInstructions(u32 startAddr, u32 endAddr);
79
std::set<std::string> getSelectedLineArguments();
80
void drawArguments(HDC hdc, const DisassemblyLineInfo &line, int x, int y, int textColor, const std::set<std::string> &currentArguments);
81
82
public:
83
CtrlDisAsmView(HWND _wnd);
84
~CtrlDisAsmView();
85
static void init();
86
static void deinit();
87
static LRESULT CALLBACK wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
88
static CtrlDisAsmView * getFrom(HWND wnd);
89
90
void onChar(WPARAM wParam, LPARAM lParam);
91
void onPaint(WPARAM wParam, LPARAM lParam);
92
void onVScroll(WPARAM wParam, LPARAM lParam);
93
void onKeyDown(WPARAM wParam, LPARAM lParam);
94
void onKeyUp(WPARAM wParam, LPARAM lParam);
95
void onMouseDown(WPARAM wParam, LPARAM lParam, int button);
96
void onMouseUp(WPARAM wParam, LPARAM lParam, int button);
97
void onMouseMove(WPARAM wParam, LPARAM lParam, int button);
98
void scrollAddressIntoView();
99
bool curAddressIsVisible();
100
void redraw();
101
void scanVisibleFunctions();
102
void clearFunctions() { g_disassemblyManager.clear(); };
103
104
void getOpcodeText(u32 address, char* dest, int bufsize);
105
int getRowHeight() { return rowHeight; };
106
u32 yToAddress(int y);
107
108
void setDontRedraw(bool b) { dontRedraw = b; };
109
void setDebugger(MIPSDebugInterface *deb)
110
{
111
debugger=deb;
112
curAddress=debugger->GetPC();
113
g_disassemblyManager.setCpu(deb);
114
}
115
DebugInterface *getDebugger()
116
{
117
return debugger;
118
}
119
120
void scrollStepping(u32 newPc);
121
u32 getInstructionSizeAt(u32 address);
122
123
void gotoAddr(unsigned int addr)
124
{
125
if (positionLocked_ != 0)
126
return;
127
u32 windowEnd = g_disassemblyManager.getNthNextAddress(windowStart,visibleRows);
128
u32 newAddress = g_disassemblyManager.getStartAddress(addr);
129
130
if (newAddress < windowStart || newAddress >= windowEnd)
131
{
132
windowStart = g_disassemblyManager.getNthPreviousAddress(newAddress,visibleRows/2);
133
}
134
135
setCurAddress(newAddress);
136
scanVisibleFunctions();
137
redraw();
138
}
139
void gotoPC()
140
{
141
gotoAddr(debugger->GetPC());
142
}
143
u32 getSelection()
144
{
145
return curAddress;
146
}
147
148
void setShowMode(bool s)
149
{
150
showHex=s;
151
}
152
153
void toggleBreakpoint(bool toggleEnabled = false);
154
void editBreakpoint();
155
156
void scrollWindow(int lines)
157
{
158
if (lines < 0)
159
windowStart = g_disassemblyManager.getNthPreviousAddress(windowStart,abs(lines));
160
else
161
windowStart = g_disassemblyManager.getNthNextAddress(windowStart,lines);
162
163
scanVisibleFunctions();
164
redraw();
165
}
166
167
void setCurAddress(u32 newAddress, bool extend = false)
168
{
169
newAddress = g_disassemblyManager.getStartAddress(newAddress);
170
const u32 after = g_disassemblyManager.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
177
void LockPosition() {
178
positionLocked_++;
179
}
180
void UnlockPosition() {
181
positionLocked_--;
182
_assert_(positionLocked_ >= 0);
183
}
184
185
private:
186
bool redrawScheduled_ = false;
187
int positionLocked_ = 0;
188
};
189
190