Merge pull request #1287 from mogaika/debug_window_improve

Debugger features
This commit is contained in:
Gregory Hainaut 2016-07-07 19:59:33 +02:00 committed by GitHub
commit a735e2b58f
11 changed files with 403 additions and 172 deletions

View File

@ -30,6 +30,8 @@ memory view:
any overwrite ansi byte
left click select byte/nibble
right click open context menu
ctrl+wheel zoom memory view
esc return to previous goto address
breakpoint list:

View File

@ -184,6 +184,37 @@ void DebugInterface::resumeCpu()
core.Resume();
}
char* DebugInterface::stringFromPointer(u32 p)
{
const int BUFFER_LEN = 25;
static char buf[BUFFER_LEN] = { 0 };
if (!isValidAddress(p))
return NULL;
try {
for (u32 i = 0; i < BUFFER_LEN; i++) {
char c = read8(p + i);
buf[i] = c;
if (c == 0) {
return i > 0 ? buf : NULL;
}
else if (c < 0x20 || c >= 0x7f) {
// non printable character
return NULL;
}
}
}
catch (Exception::Ps2Generic&) {
return NULL;
}
buf[BUFFER_LEN - 1] = 0;
buf[BUFFER_LEN - 2] = '~';
return buf;
}
bool DebugInterface::initExpression(const char* exp, PostfixExpression& dest)
{
MipsExpressionFunctions funcs(this);
@ -509,33 +540,59 @@ std::string R5900DebugInterface::disasm(u32 address, bool simplify)
bool R5900DebugInterface::isValidAddress(u32 addr)
{
// ee can't access the first part of memory.
if (addr < 0x80000)
return false;
if (addr >= 0xFFFF8000)
return true;
addr &= 0x7FFFFFFF;
u32 lopart = addr & 0xfFFffFF;
// get rid of ee ram mirrors
if ((addr >> 28) == 2 || (addr >> 28) == 3)
addr &= ~(0xF << 28);
// registers
if (addr >= 0x10000000 && addr < 0x10010000)
return true;
if (addr >= 0x12000000 && addr < 0x12001100)
return true;
switch (addr >> 28)
{
case 0:
case 2:
// case 3: throw exception (not mapped ?)
// [ 0000_8000 - 01FF_FFFF ] RAM
// [ 2000_8000 - 21FF_FFFF ] RAM MIRROR
// [ 3000_8000 - 31FF_FFFF ] RAM MIRROR
if (lopart >= 0x80000 && lopart <= 0x1ffFFff)
return !!vtlb_GetPhyPtr(lopart);
break;
case 1:
// [ 1000_0000 - 1000_CFFF ] EE register
if (lopart <= 0xcfff)
return true;
// scratchpad
if (addr >= 0x70000000 && addr < 0x70004000)
return true;
// [ 1100_0000 - 1100_FFFF ] VU mem
if (lopart >= 0x1000000 && lopart <= 0x100FFff)
return true;
return !(addr & 0x40000000) && vtlb_GetPhyPtr(addr & 0x1FFFFFFF) != NULL;
// [ 1200_0000 - 1200_FFFF ] GS regs
if (lopart >= 0x2000000 && lopart <= 0x20010ff)
return true;
// [ 1E00_0000 - 1FFF_FFFF ] ROM
// if (lopart >= 0xe000000)
// return true; throw exception (not mapped ?)
break;
case 7:
// [ 7000_0000 - 7000_3FFF ] Scratchpad
if (lopart <= 0x3fff)
return true;
break;
case 8:
case 9:
case 0xA:
case 0xB:
// [ 8000_0000 - BFFF_FFFF ] kernel
// return true;
break;
case 0xF:
// [ 8000_0000 - BFFF_FFFF ] IOP or kernel stack
if (lopart >= 0xfff8000)
return true;
break;
}
return false;
}
u32 R5900DebugInterface::getCycles()
{
return cpuRegs.cycle;

View File

@ -58,6 +58,7 @@ public:
bool isCpuPaused();
void pauseCpu();
void resumeCpu();
char *stringFromPointer(u32 p);
};
class R5900DebugInterface: public DebugInterface

View File

@ -41,6 +41,7 @@
#include <stdexcept>
#include <vector>
#include <list>
#include <stack>
#include <cstring> // string.h under c++
#include <cstdio> // stdio.h under c++
#include <cstdlib>

View File

@ -60,4 +60,4 @@ private:
u32 size;
char condition[128];
PostfixExpression compiledCondition;
};
};

View File

@ -24,6 +24,7 @@
#include <wchar.h>
#include <wx/clipbrd.h>
BEGIN_EVENT_TABLE(CtrlMemView, wxWindow)
EVT_PAINT(CtrlMemView::paintEvent)
EVT_MOUSEWHEEL(CtrlMemView::mouseEvent)
@ -45,6 +46,12 @@ enum MemoryViewMenuIdentifiers
{
ID_MEMVIEW_GOTOINDISASM = 1,
ID_MEMVIEW_COPYADDRESS,
ID_MEMVIEW_FOLLOWADDRESS,
ID_MEMVIEW_DISPLAYVALUE_8,
ID_MEMVIEW_DISPLAYVALUE_16,
ID_MEMVIEW_DISPLAYVALUE_32,
ID_MEMVIEW_DISPLAYVALUE_64,
ID_MEMVIEW_DISPLAYVALUE_128,
ID_MEMVIEW_COPYVALUE_8,
ID_MEMVIEW_COPYVALUE_16,
ID_MEMVIEW_COPYVALUE_32,
@ -60,14 +67,14 @@ CtrlMemView::CtrlMemView(wxWindow* parent, DebugInterface* _cpu)
charWidth = getDebugFontWidth();
windowStart = 0x480000;
curAddress = windowStart;
rowSize = 16;
byteGroupSize = 1;
asciiSelected = false;
selectedNibble = 0;
rowSize = 16;
addressStart = charWidth;
hexStart = addressStart + 9*charWidth;
asciiStart = hexStart + (rowSize*3+1)*charWidth;
setRowSize(16);
#ifdef _WIN32
font = wxFont(wxSize(charWidth,rowHeight),wxFONTFAMILY_DEFAULT,wxFONTSTYLE_NORMAL,wxFONTWEIGHT_NORMAL,false,L"Lucida Console");
@ -81,6 +88,13 @@ CtrlMemView::CtrlMemView(wxWindow* parent, DebugInterface* _cpu)
menu.Append(ID_MEMVIEW_GOTOINDISASM, L"Go to in Disasm");
menu.Append(ID_MEMVIEW_COPYADDRESS, L"Copy address");
menu.Append(ID_MEMVIEW_FOLLOWADDRESS, L"Follow address");
menu.AppendSeparator();
menu.Append(ID_MEMVIEW_DISPLAYVALUE_8, L"Display as 1 byte");
menu.Append(ID_MEMVIEW_DISPLAYVALUE_16, L"Display as 2 byte");
menu.Append(ID_MEMVIEW_DISPLAYVALUE_32, L"Display as 4 byte");
menu.Append(ID_MEMVIEW_DISPLAYVALUE_64, L"Display as 8 byte");
menu.Append(ID_MEMVIEW_DISPLAYVALUE_128, L"Display as 16 byte");
menu.AppendSeparator();
menu.Append(ID_MEMVIEW_COPYVALUE_8, L"Copy Value (8 bit)");
menu.Append(ID_MEMVIEW_COPYVALUE_16, L"Copy Value (16 bit)");
@ -95,6 +109,11 @@ CtrlMemView::CtrlMemView(wxWindow* parent, DebugInterface* _cpu)
SetDoubleBuffered(true);
}
void CtrlMemView::setRowSize(int bytesInRow) {
rowSize = (std::max(16, std::min(256, bytesInRow)) / 16) * 16;
asciiStart = hexStart + (rowSize * 3 + 1)*charWidth;
}
void CtrlMemView::postEvent(wxEventType type, wxString text)
{
wxCommandEvent event( type, GetId() );
@ -125,137 +144,167 @@ void CtrlMemView::redraw()
render(dc);
}
int CtrlMemView::hexGroupPositionFromIndex(int idx)
{
int groupPos = idx * charWidth * 2;
int space = (charWidth / 4);
// spaces after every byte
groupPos += idx * space;
// spaces after every 2 bytes
groupPos += (idx / 2) * space;
// spaces after every 4 bytes
return groupPos + (idx / 4) * space;
}
void CtrlMemView::render(wxDC& dc)
{
bool hasFocus = wxWindow::FindFocus() == this;
int visibleRows = GetClientSize().y/rowHeight;
int visibleRows = GetClientSize().y / rowHeight;
wxColor white = wxColor(0xFFFFFFFF);
dc.SetBrush(wxBrush(white));
dc.SetPen(wxPen(white));
const wxColor COLOR_WHITE = wxColor(0xFFFFFFFF);
const wxColor COLOR_BLACK = wxColor(0xFF000000);
const wxColor COLOR_SELECTED_BG = wxColor(0xFFFF9933);
const wxColor COLOR_SELECTED_INACTIVE_BG = wxColor(0xFFC0C0C0);
const wxColor COLOR_ADDRESS = wxColor(0xFF600000);
const wxColor COLOR_DELIMETER = wxColor(0xFFC0C0C0);
int width,height;
dc.GetSize(&width,&height);
dc.DrawRectangle(0,0,width,height);
dc.SetBrush(wxBrush(COLOR_WHITE));
dc.SetPen(wxPen(COLOR_WHITE));
for (int i = 0; i < visibleRows+1; i++)
int width, height;
dc.GetSize(&width, &height);
dc.DrawRectangle(0, 0, width, height);
const int TEMP_SIZE = 64;
wchar_t temp[TEMP_SIZE];
u32 byteGroupMask = ~(byteGroupSize - 1);
bool validCpu = cpu && cpu->isAlive();
// not hexGroupPositionFromIndex(byteGroupSize), because we dont need space after last symbol;
int groupWidth = hexGroupPositionFromIndex(byteGroupSize - 1) + charWidth * 2;
for (int i = 0; i < visibleRows + 1; i++)
{
wchar_t temp[32];
u32 rowAddress = windowStart + i * rowSize;
int rowY = rowHeight * i;
unsigned int address = windowStart + i*rowSize;
int rowY = rowHeight*i;
swprintf(temp,32,L"%08X",address);
swprintf(temp, TEMP_SIZE, L"%08X" , rowAddress);
dc.SetFont(font);
dc.SetTextForeground(wxColor(0xFF600000));
dc.DrawText(temp,addressStart,rowY);
dc.SetTextForeground(COLOR_ADDRESS);
dc.DrawText(temp, addressStart, rowY);
u32 memory[4];
bool valid = cpu != NULL && cpu->isAlive() && cpu->isValidAddress(address);
if (valid)
{
memory[0] = cpu->read32(address);
memory[1] = cpu->read32(address+4);
memory[2] = cpu->read32(address+8);
memory[3] = cpu->read32(address+12);
}
u8* m = (u8*) memory;
for (int j = 0; j < rowSize; j++)
{
if (valid)
swprintf(temp,32,L"%02X",m[j]);
else
wcscpy(temp,L"??");
u32 byteAddress = rowAddress + j;
u8 byteCurrent;
bool byteValid;
unsigned char c = m[j];
if (c < 32 || c >= 128 || valid == false)
c = '.';
if (address+j == curAddress)
{
wchar_t text[2];
try {
byteValid = validCpu && cpu->isValidAddress(byteAddress);
if (hasFocus && !asciiSelected)
{
dc.SetTextForeground(wxColor(0xFFFFFFFF));
dc.SetPen(wxColor(0xFFFF9933));
dc.SetBrush(wxColor(0xFFFF9933));
dc.DrawRectangle(hexStart+j*3*charWidth,rowY,charWidth,rowHeight);
if (selectedNibble == 0)
dc.SetFont(underlineFont);
} else {
dc.SetTextForeground(wxColor(0xFF000000));
dc.SetPen(wxColor(0xFFC0C0C0));
dc.SetBrush(wxColor(0xFFC0C0C0));
dc.DrawRectangle(hexStart+j*3*charWidth,rowY,charWidth,rowHeight);
}
text[0] = temp[0];
text[1] = 0;
dc.DrawText(text,hexStart+j*3*charWidth,rowY);
if (hasFocus && !asciiSelected)
{
dc.DrawRectangle(hexStart+j*3*charWidth+charWidth,rowY,charWidth,rowHeight);
if (selectedNibble == 1)
dc.SetFont(underlineFont);
else
dc.SetFont(font);
} else {
dc.DrawRectangle(hexStart+j*3*charWidth+charWidth,rowY,charWidth,rowHeight);
}
text[0] = temp[1];
text[1] = 0;
dc.DrawText(text,hexStart+j*3*charWidth+charWidth,rowY);
if (hasFocus && asciiSelected)
{
dc.SetTextForeground(wxColor(0xFFFFFFFF));
dc.SetPen(wxColor(0xFFFF9933));
dc.SetBrush(wxColor(0xFFFF9933));
dc.DrawRectangle(asciiStart+j*(charWidth+2),rowY,charWidth,rowHeight);
} else {
dc.SetTextForeground(wxColor(0xFF000000));
dc.SetFont(font);
dc.SetPen(wxColor(0xFFC0C0C0));
dc.SetBrush(wxColor(0xFFC0C0C0));
dc.DrawRectangle(asciiStart+j*(charWidth+2),rowY,charWidth,rowHeight);
}
text[0] = c;
text[1] = 0;
dc.DrawText(text,asciiStart+j*(charWidth+2),rowY);
} else {
wchar_t text[2];
text[0] = c;
text[1] = 0;
dc.SetTextForeground(wxColor(0xFF000000));
dc.DrawText(temp,hexStart+j*3*charWidth,rowY);
dc.DrawText(text,asciiStart+j*(charWidth+2),rowY);
if (byteValid)
byteCurrent = cpu->read8(byteAddress);
}
catch (Exception::Ps2Generic &) {
byteValid = false;
}
// not optimized way, but more flexible than previous
// calculate group position
int groupNum = j / byteGroupSize;
int groupPosX = hexStart + groupNum * byteGroupSize * 3 * charWidth;
// calculate symbol position in group
int groupIndex = j % byteGroupSize;
int symbolPosX = groupPosX + hexGroupPositionFromIndex(byteGroupSize - groupIndex - 1);
u32 groupAddress = byteAddress - groupIndex;
if (curAddress >= groupAddress && curAddress < groupAddress + byteGroupSize)
{
// if group selected, draw rectangle behind
if (groupIndex == 0) {
if (hasFocus && !asciiSelected) {
dc.SetPen(COLOR_SELECTED_BG);
dc.SetBrush(COLOR_SELECTED_BG);
}
else {
dc.SetPen(COLOR_SELECTED_INACTIVE_BG);
dc.SetBrush(COLOR_SELECTED_INACTIVE_BG);
}
dc.DrawRectangle(groupPosX, rowY, groupWidth, rowHeight);
}
dc.SetTextForeground((hasFocus && !asciiSelected) ? COLOR_WHITE : COLOR_BLACK);
}
else {
dc.SetTextForeground(COLOR_BLACK);
}
swprintf(temp, TEMP_SIZE, byteValid ? L"%02X" : L"??", byteCurrent);
// if selected byte, need hint current nibble
if (byteAddress == curAddress) {
if (selectedNibble == 1)
dc.SetFont(underlineFont);
dc.DrawText(temp + 1, symbolPosX + charWidth, rowY);
if (selectedNibble == 1)
dc.SetFont(font);
else
dc.SetFont(underlineFont);
temp[1] = 0;
dc.DrawText(temp, symbolPosX, rowY);
if (selectedNibble == 0)
dc.SetFont(font);
}
else {
dc.DrawText(temp, symbolPosX, rowY);
}
// draw in ansii text representation table
temp[1] = 0;
temp[0] = (!byteValid || byteCurrent < 32 || byteCurrent > 128) ? '.' : byteCurrent;
if (byteAddress == curAddress) {
if (hasFocus && asciiSelected) {
dc.SetPen(COLOR_SELECTED_BG);
dc.SetBrush(COLOR_SELECTED_BG);
dc.SetTextForeground(COLOR_WHITE);
}
else {
dc.SetPen(COLOR_SELECTED_INACTIVE_BG);
dc.SetBrush(COLOR_SELECTED_INACTIVE_BG);
dc.SetTextForeground(COLOR_BLACK);
}
dc.DrawRectangle(asciiStart + j*(charWidth + 2), rowY, charWidth, rowHeight);
}
else {
dc.SetTextForeground(COLOR_BLACK);
}
dc.DrawText(temp, asciiStart + j*(charWidth + 2), rowY);
}
}
// TODO: make optional?
if (true)
dc.SetPen(COLOR_DELIMETER);
dc.SetBrush(COLOR_DELIMETER);
int linestep = std::max((u32) 4, byteGroupSize);
for (int i = linestep; i < rowSize; i += linestep)
{
dc.SetPen(wxColor(0xFFC0C0C0));
dc.SetBrush(wxColor(0xFFC0C0C0));
for (int i = 4; i < rowSize; i += 4)
{
int x = hexStart+i*3*charWidth-charWidth/2;
int y = (visibleRows+1)*rowHeight;
dc.DrawLine(x,0,x,y);
}
int x = hexStart + i * 3 * charWidth - charWidth / 2;
int y = (visibleRows + 1) * rowHeight;
dc.DrawLine(x, 0, x, y);
}
}
@ -276,6 +325,29 @@ void CtrlMemView::onPopupClick(wxCommandEvent& evt)
case ID_MEMVIEW_GOTOINDISASM:
postEvent(debEVT_GOTOINDISASM,curAddress);
break;
case ID_MEMVIEW_FOLLOWADDRESS:
gotoAddress(cpu->read32(curAddress), true);
break;
case ID_MEMVIEW_DISPLAYVALUE_8:
byteGroupSize = 1;
Refresh();
break;
case ID_MEMVIEW_DISPLAYVALUE_16:
byteGroupSize = 2;
Refresh();
break;
case ID_MEMVIEW_DISPLAYVALUE_32:
byteGroupSize = 4;
Refresh();
break;
case ID_MEMVIEW_DISPLAYVALUE_64:
byteGroupSize = 8;
Refresh();
break;
case ID_MEMVIEW_DISPLAYVALUE_128:
byteGroupSize = 16;
Refresh();
break;
case ID_MEMVIEW_COPYVALUE_8:
if (wxTheClipboard->Open())
{
@ -331,6 +403,16 @@ void CtrlMemView::mouseEvent(wxMouseEvent& evt)
SetFocusFromKbd();
} else if (evt.GetEventType() == wxEVT_RIGHT_UP)
{
curAddress -= (curAddress - windowStart) % byteGroupSize;
menu.Enable(ID_MEMVIEW_FOLLOWADDRESS, (curAddress & 3) == 0);
menu.Enable(ID_MEMVIEW_DISPLAYVALUE_8, byteGroupSize != 1);
menu.Enable(ID_MEMVIEW_DISPLAYVALUE_16, byteGroupSize != 2);
menu.Enable(ID_MEMVIEW_DISPLAYVALUE_32, byteGroupSize != 4);
menu.Enable(ID_MEMVIEW_DISPLAYVALUE_64, byteGroupSize != 8);
menu.Enable(ID_MEMVIEW_DISPLAYVALUE_128, byteGroupSize != 16);
menu.Enable(ID_MEMVIEW_COPYVALUE_128,(curAddress & 15) == 0);
menu.Enable(ID_MEMVIEW_COPYVALUE_64,(curAddress & 7) == 0);
menu.Enable(ID_MEMVIEW_COPYVALUE_32,(curAddress & 3) == 0);
@ -340,11 +422,22 @@ void CtrlMemView::mouseEvent(wxMouseEvent& evt)
return;
} else if (evt.GetEventType() == wxEVT_MOUSEWHEEL)
{
if (evt.GetWheelRotation() > 0)
{
scrollWindow(-3);
} else if (evt.GetWheelRotation() < 0) {
scrollWindow(3);
if (evt.ControlDown()) {
if (evt.GetWheelRotation() > 0) {
setRowSize(rowSize + 16);
}
else {
setRowSize(rowSize - 16);
}
}
else {
if (evt.GetWheelRotation() > 0)
{
scrollWindow(-3);
}
else if (evt.GetWheelRotation() < 0) {
scrollWindow(3);
}
}
} else {
evt.Skip();
@ -366,7 +459,8 @@ void CtrlMemView::keydownEvent(wxKeyEvent& evt)
u64 addr;
if (executeExpressionWindow(this,cpu,addr) == false)
return;
gotoAddress(addr);
gotoAddress(addr, true);
}
break;
case 'b':
@ -407,6 +501,12 @@ void CtrlMemView::keydownEvent(wxKeyEvent& evt)
case WXK_PAGEDOWN:
scrollWindow(GetClientSize().y/rowHeight);
break;
case WXK_ESCAPE:
if (history.size()) {
gotoAddress(history.top());
history.pop();
}
break;
default:
evt.Skip();
break;
@ -510,12 +610,14 @@ void CtrlMemView::scrollCursor(int bytes)
int visibleRows = GetClientSize().y/rowHeight;
u32 windowEnd = windowStart+visibleRows*rowSize;
if (curAddress < windowStart)
{
windowStart = curAddress & ~15;
windowStart = (curAddress / rowSize) * curAddress;
} else if (curAddress >= windowEnd)
{
windowStart = (curAddress-(visibleRows-1)*rowSize) & ~15;
windowStart = curAddress - (visibleRows - 1)*rowSize;
windowStart = (windowStart / rowSize) * windowStart;
}
updateStatusBarText();
@ -525,22 +627,26 @@ void CtrlMemView::scrollCursor(int bytes)
void CtrlMemView::updateStatusBarText()
{
wchar_t text[64];
swprintf(text,64,L"%08X",curAddress);
int needpad = (curAddress - windowStart) % byteGroupSize;
u32 addr = curAddress - needpad;
swprintf(text, 64, L"%08X %08X", curAddress, addr);
postEvent(debEVT_SETSTATUSBARTEXT,text);
}
void CtrlMemView::gotoAddress(u32 addr)
void CtrlMemView::gotoAddress(u32 addr, bool pushInHistory)
{
int lines= GetClientSize().y/rowHeight;
u32 windowEnd = windowStart+lines*rowSize;
if (pushInHistory)
history.push(windowStart);
int lines= GetClientSize().y / rowHeight;
u32 windowEnd = windowStart + lines * rowSize;
curAddress = addr;
selectedNibble = 0;
if (curAddress < windowStart || curAddress >= windowEnd)
{
windowStart = curAddress & ~15;
}
windowStart = curAddress;
updateStatusBarText();
redraw();
@ -563,18 +669,37 @@ void CtrlMemView::gotoPoint(int x, int y)
redraw();
} else if (x >= hexStart)
{
int col = (x-hexStart) / charWidth;
if ((col/3) >= rowSize) return;
int col = (x-hexStart);
int space = (charWidth / 4);
switch (col % 3)
{
case 0: selectedNibble = 0; break;
case 1: selectedNibble = 1; break;
case 2: return; // don't change position when clicking on the space
int groupWidth = byteGroupSize * charWidth * 3;
int group = col / groupWidth;
int posInGroup = col % groupWidth;
int indexInGroup = -1;
for (int i = 0; i < int(byteGroupSize); i++) {
int start = hexGroupPositionFromIndex(i);
int end = start + 2 * charWidth -1;
if (posInGroup < start)
{
return;
}
else if (posInGroup <= end)
{
selectedNibble = ((posInGroup - start) / charWidth) % 2;
indexInGroup = i;
break;
}
}
if (indexInGroup == -1)
return;
curAddress = lineAddress + group * byteGroupSize + (byteGroupSize - indexInGroup - 1);
asciiSelected = false;
curAddress = lineAddress+col/3;
updateStatusBarText();
redraw();
}

View File

@ -30,11 +30,13 @@ public:
void scrollbarEvent(wxScrollWinEvent& evt);
void charEvent(wxKeyEvent& evt);
void redraw();
void gotoAddress(u32 address);
void gotoAddress(u32 address, bool pushInHistory = false);
DECLARE_EVENT_TABLE()
private:
void render(wxDC& dc);
int hexGroupPositionFromIndex(int idx);
void setRowSize(int bytesInRow);
void gotoPoint(int x, int y);
void updateStatusBarText();
void postEvent(wxEventType type, wxString text);
@ -49,6 +51,7 @@ private:
int charWidth;
u32 windowStart;
u32 curAddress;
u32 byteGroupSize;
int rowSize;
wxFont font,underlineFont;
@ -58,5 +61,6 @@ private:
bool asciiSelected;
int selectedNibble;
std::stack<u32> history;
wxMenu menu;
};
};

View File

@ -35,9 +35,12 @@ enum DisassemblyMenuIdentifiers
ID_REGISTERLIST_DISPLAY32 = 1,
ID_REGISTERLIST_DISPLAY64,
ID_REGISTERLIST_DISPLAY128,
ID_REGISTERLIST_DISPLAY128STRINGS,
ID_REGISTERLIST_CHANGELOWER,
ID_REGISTERLIST_CHANGEUPPER,
ID_REGISTERLIST_CHANGEVALUE
ID_REGISTERLIST_CHANGEVALUE,
ID_REGISTERLIST_GOTOINMEMORYVIEW,
ID_REGISTERLIST_GOTOINDISASM
};
@ -276,7 +279,18 @@ void CtrlRegisterList::OnDraw(wxDC& dc)
{
case 128:
{
int startIndex = std::min<int>(3,maxBits/32-1);
int startIndex = std::min<int>(3, maxBits / 32 - 1);
if (resolvePointerStrings && cpu && cpu->isAlive()) {
char *strval = cpu->stringFromPointer(value._u32[0]);
if (strval) {
static wxColor clr = wxColor(0xFF228822);
dc.SetTextForeground(clr);
dc.DrawText(wxString(strval), width - (32 * charWidth + 12), y + 2);
startIndex = 0;
}
}
int actualX = width-4-(startIndex+1)*(8*charWidth+2);
x = std::max<int>(actualX,x);
@ -396,23 +410,33 @@ void CtrlRegisterList::onPopupClick(wxCommandEvent& evt)
switch (evt.GetId())
{
case ID_REGISTERLIST_DISPLAY32:
resolvePointerStrings = false;
maxBits = 32;
SetInitialSize(ClientToWindowSize(GetMinClientSize()));
postEvent(debEVT_UPDATELAYOUT,0);
Refresh();
break;
case ID_REGISTERLIST_DISPLAY64:
resolvePointerStrings = false;
maxBits = 64;
SetInitialSize(ClientToWindowSize(GetMinClientSize()));
postEvent(debEVT_UPDATELAYOUT,0);
Refresh();
break;
case ID_REGISTERLIST_DISPLAY128:
resolvePointerStrings = false;
maxBits = 128;
SetInitialSize(ClientToWindowSize(GetMinClientSize()));
postEvent(debEVT_UPDATELAYOUT,0);
Refresh();
break;
case ID_REGISTERLIST_DISPLAY128STRINGS:
resolvePointerStrings = true;
maxBits = 128;
SetInitialSize(ClientToWindowSize(GetMinClientSize()));
postEvent(debEVT_UPDATELAYOUT, 0);
Refresh();
break;
case ID_REGISTERLIST_CHANGELOWER:
changeValue(LOWER64);
Refresh();
@ -428,6 +452,12 @@ void CtrlRegisterList::onPopupClick(wxCommandEvent& evt)
changeValue(LOWER64);
Refresh();
break;
case ID_REGISTERLIST_GOTOINMEMORYVIEW:
postEvent(debEVT_GOTOINMEMORYVIEW, cpu->getRegister(category, currentRows[category])._u32[0]);
break;
case ID_REGISTERLIST_GOTOINDISASM:
postEvent(debEVT_GOTOINDISASM, cpu->getRegister(category, currentRows[category])._u32[0]);
break;
default:
wxMessageBox( L"Unimplemented.", L"Unimplemented.", wxICON_INFORMATION);
break;
@ -496,6 +526,7 @@ void CtrlRegisterList::mouseEvent(wxMouseEvent& evt)
menu.AppendRadioItem(ID_REGISTERLIST_DISPLAY32, L"Display 32 bit");
menu.AppendRadioItem(ID_REGISTERLIST_DISPLAY64, L"Display 64 bit");
menu.AppendRadioItem(ID_REGISTERLIST_DISPLAY128, L"Display 128 bit");
menu.AppendRadioItem(ID_REGISTERLIST_DISPLAY128STRINGS, L"Display 128 bit + Resolve string pointers");
menu.AppendSeparator();
if (bits >= 64)
@ -506,10 +537,17 @@ void CtrlRegisterList::mouseEvent(wxMouseEvent& evt)
menu.Append(ID_REGISTERLIST_CHANGEVALUE, L"Change value");
}
menu.AppendSeparator();
menu.Append(ID_REGISTERLIST_GOTOINMEMORYVIEW, L"Follow in Memory view");
menu.Append(ID_REGISTERLIST_GOTOINDISASM, L"Follow in Disasm");
switch (maxBits)
{
case 128:
menu.Check(ID_REGISTERLIST_DISPLAY128,true);
if (resolvePointerStrings)
menu.Check(ID_REGISTERLIST_DISPLAY128STRINGS, true);
else
menu.Check(ID_REGISTERLIST_DISPLAY128,true);
break;
case 64:
menu.Check(ID_REGISTERLIST_DISPLAY64,true);

View File

@ -72,4 +72,5 @@ private:
u32 lastPc;
int category;
int maxBits;
};
bool resolvePointerStrings;
};

View File

@ -54,4 +54,4 @@ bool executeExpressionWindow(wxWindow* parent, DebugInterface* cpu, u64& dest, c
}
return true;
}
}

View File

@ -501,8 +501,10 @@ void DisassemblyDialog::onDebuggerEvent(wxCommandEvent& evt)
if (currentCpu != NULL)
{
currentCpu->showMemoryView();
currentCpu->getMemoryView()->gotoAddress(evt.GetInt());
currentCpu->getDisassembly()->SetFocus();
CtrlMemView *memview = currentCpu->getMemoryView();
memview->gotoAddress(evt.GetInt(), true);
memview->SetFocus();
}
} else if (type == debEVT_RUNTOPOS)
{