2012-11-01 15:19:01 +00:00
|
|
|
// NOTE: Apologies for the quality of this code, this is really from pre-opensource Dolphin - that is, 2003.
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
//CtrlDisAsmView
|
|
|
|
// CtrlDisAsmView.cpp
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
//This Win32 control is made to be flexible and usable with
|
|
|
|
//every kind of CPU architechture that has fixed width instruction words.
|
|
|
|
//Just supply it an instance of a class derived from Debugger, with all methods
|
|
|
|
//overridden for full functionality. Look at the ppc one for an example.
|
|
|
|
//
|
|
|
|
//To add to a dialog box, just draw a User Control in the dialog editor,
|
|
|
|
//and set classname to "CtrlDisAsmView". you also need to call CtrlDisAsmView::init()
|
|
|
|
//before opening this dialog, to register the window class.
|
|
|
|
//
|
|
|
|
//To get a class instance to be able to access it, just use
|
|
|
|
// CtrlDisAsmView::getFrom(GetDlgItem(yourdialog, IDC_yourid)).
|
|
|
|
|
|
|
|
#include "../../Core/Debugger/DebugInterface.h"
|
|
|
|
|
2013-07-29 03:52:09 +00:00
|
|
|
#include "Common/CommonWindows.h"
|
2013-06-26 09:10:26 +00:00
|
|
|
#include <vector>
|
2013-07-21 08:07:26 +00:00
|
|
|
#include <algorithm>
|
|
|
|
|
|
|
|
using std::min;
|
|
|
|
using std::max;
|
|
|
|
|
2012-11-01 15:19:01 +00:00
|
|
|
|
2013-09-22 09:09:11 +00:00
|
|
|
enum LineType { LINE_UP, LINE_DOWN, LINE_RIGHT };
|
2013-09-22 09:00:44 +00:00
|
|
|
|
2013-09-22 09:09:11 +00:00
|
|
|
struct BranchLine
|
2013-09-22 09:00:44 +00:00
|
|
|
{
|
|
|
|
u32 first;
|
|
|
|
u32 second;
|
|
|
|
LineType type;
|
|
|
|
int laneIndex;
|
2013-09-22 09:09:11 +00:00
|
|
|
};
|
2013-09-22 09:00:44 +00:00
|
|
|
|
2013-09-22 09:09:11 +00:00
|
|
|
struct DisassemblyFunction
|
2013-09-22 09:00:44 +00:00
|
|
|
{
|
|
|
|
u32 hash;
|
|
|
|
std::vector<BranchLine> lines;
|
2013-09-22 09:09:11 +00:00
|
|
|
};
|
2013-09-22 09:00:44 +00:00
|
|
|
|
2012-11-01 15:19:01 +00:00
|
|
|
class CtrlDisAsmView
|
|
|
|
{
|
|
|
|
HWND wnd;
|
|
|
|
HFONT font;
|
|
|
|
HFONT boldfont;
|
|
|
|
RECT rect;
|
|
|
|
|
2013-09-22 09:00:44 +00:00
|
|
|
std::map<u32,DisassemblyFunction> functions;
|
|
|
|
std::vector<u32> visibleFunctionAddresses;
|
|
|
|
std::vector<BranchLine> strayLines;
|
|
|
|
|
2013-06-29 17:59:42 +00:00
|
|
|
u32 curAddress;
|
2013-07-21 08:07:26 +00:00
|
|
|
u32 selectRangeStart;
|
|
|
|
u32 selectRangeEnd;
|
2012-11-01 15:19:01 +00:00
|
|
|
int rowHeight;
|
2013-07-09 09:17:57 +00:00
|
|
|
int charWidth;
|
2012-11-01 15:19:01 +00:00
|
|
|
|
|
|
|
bool hasFocus;
|
|
|
|
bool showHex;
|
|
|
|
DebugInterface *debugger;
|
|
|
|
static TCHAR szClassName[];
|
|
|
|
|
2013-06-29 17:59:42 +00:00
|
|
|
u32 windowStart;
|
2013-06-25 21:52:56 +00:00
|
|
|
int visibleRows;
|
|
|
|
int instructionSize;
|
|
|
|
bool whiteBackground;
|
|
|
|
bool displaySymbols;
|
|
|
|
u32 branchTarget;
|
|
|
|
int branchRegister;
|
|
|
|
|
|
|
|
struct {
|
|
|
|
int addressStart;
|
|
|
|
int opcodeStart;
|
|
|
|
int argumentsStart;
|
|
|
|
int arrowsStart;
|
|
|
|
} pixelPositions;
|
|
|
|
|
2013-06-26 09:10:26 +00:00
|
|
|
std::vector<u32> jumpStack;
|
2013-06-25 21:52:56 +00:00
|
|
|
|
2013-08-26 17:00:16 +00:00
|
|
|
std::string searchQuery;
|
2013-06-26 09:10:26 +00:00
|
|
|
int matchAddress;
|
|
|
|
bool searching;
|
2013-06-26 21:14:15 +00:00
|
|
|
bool dontRedraw;
|
2013-08-17 19:20:24 +00:00
|
|
|
bool keyTaken;
|
2013-06-26 09:10:26 +00:00
|
|
|
|
2013-07-28 13:24:33 +00:00
|
|
|
void assembleOpcode(u32 address, std::string defaultText);
|
2013-06-26 09:48:14 +00:00
|
|
|
void disassembleToFile();
|
2013-06-26 09:10:26 +00:00
|
|
|
void search(bool continueSearch);
|
2013-06-25 21:52:56 +00:00
|
|
|
void followBranch();
|
|
|
|
void calculatePixelPositions();
|
2013-06-26 09:48:14 +00:00
|
|
|
bool getDisasmAddressText(u32 address, char* dest, bool abbreviateLabels);
|
2013-06-25 21:52:56 +00:00
|
|
|
void parseDisasm(const char* disasm, char* opcode, char* arguments);
|
2013-07-30 14:19:05 +00:00
|
|
|
void updateStatusBarText();
|
2013-09-22 09:00:44 +00:00
|
|
|
void drawBranchLine(HDC hdc, BranchLine& line);
|
2013-11-09 18:57:43 +00:00
|
|
|
void copyInstructions(u32 startAddr, u32 endAddr, bool withDisasm);
|
2012-11-01 15:19:01 +00:00
|
|
|
public:
|
|
|
|
CtrlDisAsmView(HWND _wnd);
|
|
|
|
~CtrlDisAsmView();
|
|
|
|
static void init();
|
|
|
|
static void deinit();
|
|
|
|
static LRESULT CALLBACK wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
|
|
|
static CtrlDisAsmView * getFrom(HWND wnd);
|
|
|
|
|
2013-08-17 19:20:24 +00:00
|
|
|
void onChar(WPARAM wParam, LPARAM lParam);
|
2012-11-01 15:19:01 +00:00
|
|
|
void onPaint(WPARAM wParam, LPARAM lParam);
|
|
|
|
void onVScroll(WPARAM wParam, LPARAM lParam);
|
|
|
|
void onKeyDown(WPARAM wParam, LPARAM lParam);
|
2013-06-26 09:10:26 +00:00
|
|
|
void onKeyUp(WPARAM wParam, LPARAM lParam);
|
2012-11-01 15:19:01 +00:00
|
|
|
void onMouseDown(WPARAM wParam, LPARAM lParam, int button);
|
|
|
|
void onMouseUp(WPARAM wParam, LPARAM lParam, int button);
|
|
|
|
void onMouseMove(WPARAM wParam, LPARAM lParam, int button);
|
2013-07-08 05:55:57 +00:00
|
|
|
void scrollAddressIntoView();
|
|
|
|
bool curAddressIsVisible();
|
2012-11-01 15:19:01 +00:00
|
|
|
void redraw();
|
2013-09-22 09:00:44 +00:00
|
|
|
void scanFunctions();
|
2013-09-22 11:00:25 +00:00
|
|
|
void clearFunctions()
|
|
|
|
{
|
|
|
|
functions.clear();
|
|
|
|
visibleFunctionAddresses.clear();
|
|
|
|
strayLines.clear();
|
|
|
|
};
|
2013-09-22 09:09:11 +00:00
|
|
|
|
2013-06-27 19:07:49 +00:00
|
|
|
void getOpcodeText(u32 address, char* dest);
|
2013-10-18 22:58:42 +00:00
|
|
|
int getRowHeight() { return rowHeight; };
|
2013-07-21 08:07:26 +00:00
|
|
|
u32 yToAddress(int y);
|
2012-11-01 15:19:01 +00:00
|
|
|
|
2013-06-26 21:14:15 +00:00
|
|
|
void setDontRedraw(bool b) { dontRedraw = b; };
|
2012-11-01 15:19:01 +00:00
|
|
|
void setDebugger(DebugInterface *deb)
|
|
|
|
{
|
|
|
|
debugger=deb;
|
|
|
|
curAddress=debugger->getPC();
|
2013-06-25 21:52:56 +00:00
|
|
|
instructionSize=debugger->getInstructionSize(0);
|
2012-11-01 15:19:01 +00:00
|
|
|
}
|
|
|
|
DebugInterface *getDebugger()
|
|
|
|
{
|
|
|
|
return debugger;
|
|
|
|
}
|
2013-10-18 23:19:39 +00:00
|
|
|
|
|
|
|
u32 getWindowEnd() { return windowStart+visibleRows*instructionSize; };
|
2012-11-01 15:19:01 +00:00
|
|
|
void gotoAddr(unsigned int addr)
|
|
|
|
{
|
2013-06-25 21:52:56 +00:00
|
|
|
u32 windowEnd = windowStart+visibleRows*instructionSize;
|
|
|
|
u32 newAddress = addr&(~(instructionSize-1));
|
|
|
|
|
|
|
|
if (newAddress < windowStart || newAddress >= windowEnd)
|
|
|
|
{
|
|
|
|
windowStart = newAddress-visibleRows/2*instructionSize;
|
|
|
|
}
|
|
|
|
|
2013-07-21 08:07:26 +00:00
|
|
|
setCurAddress(newAddress);
|
2013-09-22 11:00:25 +00:00
|
|
|
scanFunctions();
|
2012-11-01 15:19:01 +00:00
|
|
|
redraw();
|
|
|
|
}
|
|
|
|
void gotoPC()
|
|
|
|
{
|
2013-06-25 21:52:56 +00:00
|
|
|
gotoAddr(debugger->getPC()&(~(instructionSize-1)));
|
2012-11-01 15:19:01 +00:00
|
|
|
}
|
2013-06-29 17:59:42 +00:00
|
|
|
u32 getSelection()
|
2012-11-01 15:19:01 +00:00
|
|
|
{
|
|
|
|
return curAddress;
|
|
|
|
}
|
|
|
|
|
|
|
|
void setShowMode(bool s)
|
|
|
|
{
|
|
|
|
showHex=s;
|
|
|
|
}
|
|
|
|
|
2013-10-30 11:12:33 +00:00
|
|
|
void toggleBreakpoint(bool toggleEnabled = false);
|
|
|
|
void editBreakpoint();
|
2013-06-25 21:52:56 +00:00
|
|
|
|
|
|
|
void scrollWindow(int lines)
|
|
|
|
{
|
|
|
|
windowStart += lines*instructionSize;
|
2013-09-22 09:00:44 +00:00
|
|
|
scanFunctions();
|
2013-06-25 21:52:56 +00:00
|
|
|
redraw();
|
|
|
|
}
|
2013-07-21 08:07:26 +00:00
|
|
|
|
|
|
|
void setCurAddress(u32 newAddress, bool extend = false)
|
|
|
|
{
|
|
|
|
u32 after = newAddress + instructionSize;
|
|
|
|
curAddress = newAddress;
|
|
|
|
selectRangeStart = extend ? std::min(selectRangeStart, newAddress) : newAddress;
|
|
|
|
selectRangeEnd = extend ? std::max(selectRangeEnd, after) : after;
|
2013-07-30 14:19:05 +00:00
|
|
|
updateStatusBarText();
|
2013-07-21 08:07:26 +00:00
|
|
|
}
|
2012-11-01 15:19:01 +00:00
|
|
|
};
|