Debugger: Add option to display VU0F registers as floats

This commit is contained in:
Ty Lamontagne 2021-08-01 18:16:36 -04:00 committed by refractionpcsx2
parent f11334cb3b
commit 8f171c70f5
3 changed files with 122 additions and 63 deletions

View File

@ -1,5 +1,5 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2014 PCSX2 Dev Team
* Copyright (C) 2002-2021 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
@ -375,13 +375,13 @@ DebugInterface::RegisterType R5900DebugInterface::getRegisterType(int cat)
{
case EECAT_GPR:
case EECAT_CP0:
case EECAT_VU0F:
case EECAT_VU0I:
case EECAT_FCR:
case EECAT_GSPRIV:
default:
return NORMAL;
case EECAT_FPR:
case EECAT_VU0F:
return SPECIAL;
}
}
@ -485,18 +485,19 @@ wxString R5900DebugInterface::getRegisterString(int cat, int num)
{
switch (cat)
{
case EECAT_GPR:
case EECAT_CP0:
case EECAT_FCR:
return getRegister(cat,num).ToString();
case EECAT_FPR:
case EECAT_GPR:
case EECAT_CP0:
case EECAT_FCR:
case EECAT_VU0F:
return getRegister(cat, num).ToString();
case EECAT_FPR:
{
char str[64];
sprintf(str,"%f",fpuRegs.fpr[num].f);
return wxString(str,wxConvUTF8);
}
default:
return L"";
default:
return L"";
}
}

View File

@ -1,5 +1,5 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2014 PCSX2 Dev Team
* Copyright (C) 2002-2021 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
@ -36,6 +36,7 @@ enum DisassemblyMenuIdentifiers
ID_REGISTERLIST_DISPLAY64,
ID_REGISTERLIST_DISPLAY128,
ID_REGISTERLIST_DISPLAY128STRINGS,
ID_REGISTERLIST_DISPLAYVU0FFLOATS,
ID_REGISTERLIST_CHANGELOWER,
ID_REGISTERLIST_CHANGEUPPER,
ID_REGISTERLIST_CHANGEVALUE,
@ -53,10 +54,11 @@ CtrlRegisterList::CtrlRegisterList(wxWindow* parent, DebugInterface* _cpu)
maxBits = 128;
lastPc = 0xFFFFFFFF;
resolvePointerStrings = false;
displayVU0FAsFloat = false;
for (int i = 0; i < cpu->getRegisterCategoryCount(); i++)
{
int count = cpu->getRegisterCount(i);
const int count = cpu->getRegisterCount(i);
ChangedReg* regs = new ChangedReg[count];
memset(regs,0,sizeof(ChangedReg)*count);
@ -68,7 +70,7 @@ CtrlRegisterList::CtrlRegisterList(wxWindow* parent, DebugInterface* _cpu)
maxLen = std::max<int>(maxLen,strlen(cpu->getRegisterName(i,k)));
}
int x = 17+(maxLen+2)*charWidth;
const int x = 17+(maxLen+2)*charWidth;
startPositions.push_back(x);
currentRows.push_back(0);
}
@ -76,7 +78,7 @@ CtrlRegisterList::CtrlRegisterList(wxWindow* parent, DebugInterface* _cpu)
SetDoubleBuffered(true);
SetInitialSize(ClientToWindowSize(GetMinClientSize()));
wxSize actualSize = getOptimalSize();
const wxSize actualSize = getOptimalSize();
SetVirtualSize(actualSize);
SetScrollbars(1, rowHeight, actualSize.x, actualSize.y / rowHeight, 0, 0);
}
@ -97,7 +99,12 @@ wxSize CtrlRegisterList::getOptimalSize() const
for (int i = 0; i < cpu->getRegisterCategoryCount(); i++)
{
int bits = std::min<u32>(maxBits, cpu->getRegisterSize(i));
int start = startPositions[i];
// Workaround for displaying VU0F registers as floats
if (i == EECAT_VU0F && displayVU0FAsFloat)
bits = 128;
const int start = startPositions[i];
int w = start + (bits / 4) * charWidth;
if (bits > 32)
@ -137,14 +144,14 @@ void CtrlRegisterList::refreshChangedRegs()
for (size_t cat = 0; cat < changedCategories.size(); cat++)
{
ChangedReg* regs = changedCategories[cat];
int size = cpu->getRegisterSize(category);
const int size = cpu->getRegisterSize(category);
for (int i = 0; i < cpu->getRegisterCount(cat); i++)
{
ChangedReg& reg = regs[i];
memset(&reg.changed,0,sizeof(reg.changed));
u128 newValue = cpu->getRegister(cat,i);
const u128 newValue = cpu->getRegister(cat,i);
if (reg.oldValue != newValue)
{
@ -211,7 +218,7 @@ void CtrlRegisterList::OnDraw(wxDC& dc)
int endRow = startRow + ceil(float(GetClientSize().y) / rowHeight);
// draw categories
int width = GetClientSize().x;
const int width = GetClientSize().x;
if (startRow == 0)
{
int piece = width /cpu->getRegisterCategoryCount();
@ -245,17 +252,37 @@ void CtrlRegisterList::OnDraw(wxDC& dc)
startRow = std::max<int>(0,startRow-1);
endRow = std::min<int>(cpu->getRegisterCount(category)-1,endRow-1);
int nameStart = 17;
int valueStart = startPositions[category];
// Add a title to help identify registers W Z Y X
if (category == EECAT_VU0F)
{
const int piece = width / 5; // 4 registers + space for register name
const wxString titles[4] = { "W","Z","Y","X" };
const int titleAmt = abs((maxBits / 32) - 4);
for (int iter = 4; iter > titleAmt; iter--)
{
dc.SetBrush(wxBrush(wxColor(0xFFFFEFE8)));
dc.SetPen(wxPen(wxColor(0xFF000000)));
dc.DrawRectangle((piece * iter) + 3, rowHeight,piece,rowHeight);
dc.DrawText(titles[iter - 1], (piece * iter) + piece / 2,rowHeight + 2);
}
}
const int nameStart = 17;
const int valueStart = startPositions[category];
ChangedReg* changedRegs = changedCategories[category];
int registerBits = cpu->getRegisterSize(category);
const int registerBits = cpu->getRegisterSize(category);
DebugInterface::RegisterType type = cpu->getRegisterType(category);
for (int i = startRow; i <= endRow; i++)
{
int x = valueStart;
int y = rowHeight*(i+1);
// Skip a row if we are showing our VU0f registers
// This makes room for the WZYX title
const int y = rowHeight*(i + (category == EECAT_VU0F ? 2 : 1));
wxColor backgroundColor;
if (currentRows[category] == i)
@ -273,11 +300,37 @@ void CtrlRegisterList::OnDraw(wxDC& dc)
dc.SetTextForeground(colorNormal);
dc.DrawText(wxString(name,wxConvUTF8),nameStart,y+2);
u128 value = cpu->getRegister(category,i);
ChangedReg& changed = changedRegs[i];
const u128 value = cpu->getRegister(category,i);
const ChangedReg& changed = changedRegs[i];
switch (type)
{
[[fallthrough]]; // If we fallthrough, display VU0f as hexadecimal
case DebugInterface::SPECIAL: // let debug interface format them and just display them
{
if (changed.changed[0] || changed.changed[1] || changed.changed[2] || changed.changed[3])
dc.SetTextForeground(colorChanged);
else
dc.SetTextForeground(colorUnchanged);
if (category == EECAT_VU0F)
{
if (displayVU0FAsFloat)
{
char str[256];
const u128 val = cpu->getRegister(category, i);
// Use std::bit_cast in C++20. The below is technically UB
sprintf(str, "%7.2f %7.2f %7.2f %7.2f", *(float*)&val._u32[3], *(float*)&val._u32[2], *(float*)&val._u32[1], *(float*)&val._u32[0]);
dc.DrawText(wxString(str), x, y + 2);
break;
}
}
else
{
dc.DrawText(cpu->getRegisterString(category, i), x, y + 2);
break;
}
case DebugInterface::NORMAL: // display them in 32 bit parts
switch (registerBits)
{
@ -286,7 +339,7 @@ void CtrlRegisterList::OnDraw(wxDC& dc)
int startIndex = std::min<int>(3, maxBits / 32 - 1);
if (resolvePointerStrings && cpu->isAlive()) {
char *strval = cpu->stringFromPointer(value._u32[0]);
const char *strval = cpu->stringFromPointer(value._u32[0]);
if (strval) {
static wxColor clr = wxColor(0xFF228822);
dc.SetTextForeground(clr);
@ -295,7 +348,7 @@ void CtrlRegisterList::OnDraw(wxDC& dc)
}
}
int actualX = width-4-(startIndex+1)*(8*charWidth+2);
const int actualX = width-4-(startIndex+1)*(8*charWidth+2);
x = std::max<int>(actualX,x);
if (startIndex != 3)
@ -355,15 +408,6 @@ void CtrlRegisterList::OnDraw(wxDC& dc)
}
}
break;
case DebugInterface::SPECIAL: // let debug interface format them and just display them
{
if (changed.changed[0] || changed.changed[1] || changed.changed[2] || changed.changed[3])
dc.SetTextForeground(colorChanged);
else
dc.SetTextForeground(colorUnchanged);
dc.DrawText(cpu->getRegisterString(category,i),x,y+2);
break;
}
}
}
@ -441,6 +485,12 @@ void CtrlRegisterList::onPopupClick(wxCommandEvent& evt)
postEvent(debEVT_UPDATELAYOUT, 0);
Refresh();
break;
case ID_REGISTERLIST_DISPLAYVU0FFLOATS:
displayVU0FAsFloat = !displayVU0FAsFloat;
SetInitialSize(ClientToWindowSize(GetMinClientSize()));
postEvent(debEVT_UPDATELAYOUT, 0);
Refresh();
break;
case ID_REGISTERLIST_CHANGELOWER:
changeValue(LOWER64);
Refresh();
@ -514,25 +564,48 @@ void CtrlRegisterList::mouseEvent(wxMouseEvent& evt)
wxClientDC dc(this);
wxPoint pos = evt.GetPosition();
int x = dc.DeviceToLogicalX(pos.x) + xOffset;
int y = dc.DeviceToLogicalY(pos.y) + yOffset * rowHeight;
const int x = dc.DeviceToLogicalX(pos.x) + xOffset;
const int y = dc.DeviceToLogicalY(pos.y) + yOffset * rowHeight;
if (evt.GetEventType() == wxEVT_RIGHT_UP)
{
if (y >= rowHeight)
{
int row = (y-rowHeight)/rowHeight;
const int row = (y-rowHeight)/rowHeight;
if (row != currentRows[category] && row < cpu->getRegisterCount(category))
setCurrentRow(row);
}
wxMenu menu;
int bits = cpu->getRegisterSize(category);
const int bits = cpu->getRegisterSize(category);
if (!(category == EECAT_VU0F && displayVU0FAsFloat))
{
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");
switch (maxBits)
{
case 128:
if (resolvePointerStrings)
menu.Check(ID_REGISTERLIST_DISPLAY128STRINGS, true);
else
menu.Check(ID_REGISTERLIST_DISPLAY128, true);
break;
case 64:
menu.Check(ID_REGISTERLIST_DISPLAY64, true);
break;
case 32:
menu.Check(ID_REGISTERLIST_DISPLAY32, true);
break;
}
}
if (category == EECAT_VU0F)
menu.AppendCheckItem(ID_REGISTERLIST_DISPLAYVU0FFLOATS, L"Display VU0f registers as floats")->Check(displayVU0FAsFloat);
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)
@ -547,22 +620,6 @@ void CtrlRegisterList::mouseEvent(wxMouseEvent& evt)
menu.Append(ID_REGISTERLIST_GOTOINMEMORYVIEW, L"Follow in Memory view");
menu.Append(ID_REGISTERLIST_GOTOINDISASM, L"Follow in Disasm");
switch (maxBits)
{
case 128:
if (resolvePointerStrings)
menu.Check(ID_REGISTERLIST_DISPLAY128STRINGS, true);
else
menu.Check(ID_REGISTERLIST_DISPLAY128,true);
break;
case 64:
menu.Check(ID_REGISTERLIST_DISPLAY64,true);
break;
case 32:
menu.Check(ID_REGISTERLIST_DISPLAY32,true);
break;
}
menu.Bind(wxEVT_MENU, &CtrlRegisterList::onPopupClick, this);
PopupMenu(&menu,evt.GetPosition());
return;
@ -572,8 +629,8 @@ void CtrlRegisterList::mouseEvent(wxMouseEvent& evt)
{
if (y < rowHeight)
{
int piece = GetSize().x/cpu->getRegisterCategoryCount();
int cat = std::min<int>(x/piece,cpu->getRegisterCategoryCount()-1);
const int piece = GetSize().x/cpu->getRegisterCategoryCount();
const int cat = std::min<int>(x/piece,cpu->getRegisterCategoryCount()-1);
if (cat != category)
{
@ -581,7 +638,7 @@ void CtrlRegisterList::mouseEvent(wxMouseEvent& evt)
Refresh();
}
} else {
int row = (y-rowHeight)/rowHeight;
const int row = (y - (rowHeight * 2) )/rowHeight;
if (row != currentRows[category] && row < cpu->getRegisterCount(category))
setCurrentRow(row);
}
@ -595,7 +652,7 @@ void CtrlRegisterList::ensureVisible(int index) {
//scroll vertically to keep a logical position visible
int x, y;
GetViewStart(&x, &y);
int visibleOffset = floor(float(GetClientSize().y) / rowHeight) - 1;
const int visibleOffset = floor(float(GetClientSize().y) / rowHeight) - 1;
if (index < y)
Scroll(x, index);
else if (index > y + visibleOffset)

View File

@ -1,5 +1,5 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2014 PCSX2 Dev Team
* Copyright (C) 2002-2021 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
@ -74,4 +74,5 @@ private:
int category;
int maxBits;
bool resolvePointerStrings;
bool displayVU0FAsFloat;
};