mirror of
https://github.com/holub/mame
synced 2025-04-24 17:30:55 +03:00
Debuger updates:
* Improved behaviour of bottom line in Qt and win32 debugger views. * Ported memory tracking feature from Qt to win32 module.
This commit is contained in:
parent
fd3ca4668a
commit
8d04ca7d7d
@ -66,11 +66,13 @@ void DebuggerView::paintEvent(QPaintEvent *event)
|
||||
// Handle the scroll bars
|
||||
int const horizontalScrollCharDiff = m_view->total_size().x - m_view->visible_size().x;
|
||||
horizontalScrollBar()->setRange(0, (std::max)(0, horizontalScrollCharDiff));
|
||||
horizontalScrollBar()->setPageStep(lineWidth - 1);
|
||||
|
||||
int const verticalScrollCharDiff = m_view->total_size().y - m_view->visible_size().y;
|
||||
int const verticalScrollSize = (std::max)(0, verticalScrollCharDiff);
|
||||
bool const atEnd = verticalScrollBar()->value() == verticalScrollBar()->maximum();
|
||||
verticalScrollBar()->setRange(0, verticalScrollSize);
|
||||
verticalScrollBar()->setPageStep((contentHeight / fontHeight) - 1);
|
||||
if (m_preferBottom && atEnd)
|
||||
verticalScrollBar()->setValue(verticalScrollSize);
|
||||
|
||||
@ -147,9 +149,24 @@ void DebuggerView::paintEvent(QPaintEvent *event)
|
||||
x * fontWidth,
|
||||
y * fontHeight,
|
||||
((x + width) < visibleCharDims.x) ? (width * fontWidth) : (contentWidth - (x * fontWidth)),
|
||||
((y + 1) < visibleCharDims.y) ? fontHeight : (contentHeight - (y * fontHeight)),
|
||||
fontHeight,
|
||||
bgBrush);
|
||||
|
||||
if (((y + 1) == visibleCharDims.y) && (contentHeight > (visibleCharDims.y * fontHeight)))
|
||||
{
|
||||
if (textAttr & DCA_ANCILLARY)
|
||||
bgColor.setRgb(0xe0, 0xe0, 0xe0);
|
||||
else
|
||||
bgColor.setRgb(0xff, 0xff, 0xff);
|
||||
bgBrush.setColor(bgColor);
|
||||
painter.fillRect(
|
||||
x * fontWidth,
|
||||
visibleCharDims.y * fontHeight,
|
||||
((x + width) < visibleCharDims.x) ? (width * fontWidth) : (contentWidth - (x * fontWidth)),
|
||||
contentHeight - (visibleCharDims.y * fontHeight),
|
||||
bgBrush);
|
||||
}
|
||||
|
||||
// There is a touchy interplay between font height, drawing difference, visible position, etc
|
||||
// Fonts don't get drawn "down and to the left" like boxes, so some wiggling is needed.
|
||||
painter.drawText(x * fontWidth, (y * fontHeight + (fontHeight * 0.80)), text);
|
||||
|
@ -326,7 +326,7 @@ void DebuggerMemView::addItemsToContextMenu(QMenu *menu)
|
||||
if (addressSpace)
|
||||
{
|
||||
// get the last known PC to write to this memory location
|
||||
debug_view_xy const pos = view()->cursor_position();
|
||||
debug_view_xy const pos = memView.cursor_position();
|
||||
offs_t const address = memView.addressAtCursorPosition(pos);
|
||||
offs_t a = address & addressSpace->logaddrmask();
|
||||
bool good = false;
|
||||
|
@ -21,12 +21,10 @@ debugbase_info::debugbase_info(debugger_windows_interface &debugger) :
|
||||
|
||||
void debugbase_info::smart_set_window_bounds(HWND wnd, HWND parent, RECT const &bounds)
|
||||
{
|
||||
RECT curbounds;
|
||||
int flags = 0;
|
||||
|
||||
// first get the current bounds, relative to the parent
|
||||
RECT curbounds;
|
||||
GetWindowRect(wnd, &curbounds);
|
||||
if (parent != nullptr)
|
||||
if (parent)
|
||||
{
|
||||
RECT parentbounds;
|
||||
GetWindowRect(parent, &parentbounds);
|
||||
@ -37,6 +35,7 @@ void debugbase_info::smart_set_window_bounds(HWND wnd, HWND parent, RECT const &
|
||||
}
|
||||
|
||||
// if the position matches, don't change it
|
||||
int flags = 0;
|
||||
if (curbounds.top == bounds.top && curbounds.left == bounds.left)
|
||||
flags |= SWP_NOMOVE;
|
||||
if ((curbounds.bottom - curbounds.top) == (bounds.bottom - bounds.top) &&
|
||||
@ -45,17 +44,19 @@ void debugbase_info::smart_set_window_bounds(HWND wnd, HWND parent, RECT const &
|
||||
|
||||
// if we need to, reposition the window
|
||||
if (flags != (SWP_NOMOVE | SWP_NOSIZE))
|
||||
SetWindowPos(wnd, nullptr,
|
||||
bounds.left, bounds.top,
|
||||
bounds.right - bounds.left, bounds.bottom - bounds.top,
|
||||
SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER | flags);
|
||||
{
|
||||
SetWindowPos(
|
||||
wnd, nullptr,
|
||||
bounds.left, bounds.top,
|
||||
bounds.right - bounds.left, bounds.bottom - bounds.top,
|
||||
SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER | flags);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void debugbase_info::smart_show_window(HWND wnd, bool show)
|
||||
{
|
||||
BOOL const visible = IsWindowVisible(wnd);
|
||||
if ((visible && !show) || (!visible && show))
|
||||
bool const visible = bool(IsWindowVisible(wnd));
|
||||
if (visible != show)
|
||||
ShowWindow(wnd, show ? SW_SHOW : SW_HIDE);
|
||||
}
|
||||
|
@ -401,6 +401,7 @@ void debugview_info::draw_contents(HDC windc)
|
||||
// get the client rect
|
||||
RECT client;
|
||||
GetClientRect(m_wnd, &client);
|
||||
bool const need_filldown = client.bottom > (metrics().debug_font_height() * visarea.y);
|
||||
|
||||
// create a compatible DC and an offscreen bitmap
|
||||
HDC const dc = CreateCompatibleDC(windc);
|
||||
@ -413,6 +414,9 @@ void debugview_info::draw_contents(HDC windc)
|
||||
return;
|
||||
}
|
||||
HGDIOBJ const oldbitmap = SelectObject(dc, bitmap);
|
||||
bool const show_hscroll = m_hscroll && IsWindowVisible(m_hscroll);
|
||||
if (show_hscroll)
|
||||
client.bottom -= metrics().hscroll_height();
|
||||
|
||||
// set the font
|
||||
HGDIOBJ const oldfont = SelectObject(dc, metrics().debug_font());
|
||||
@ -423,6 +427,8 @@ void debugview_info::draw_contents(HDC windc)
|
||||
// iterate over rows and columns
|
||||
for (uint32_t row = 0; row < visarea.y; row++)
|
||||
{
|
||||
bool do_filldown = (row == (visarea.y - 1)) && need_filldown;
|
||||
|
||||
// loop twice; once to fill the background and once to draw the text
|
||||
for (int iter = 0; iter < 2; iter++)
|
||||
{
|
||||
@ -451,16 +457,16 @@ void debugview_info::draw_contents(HDC windc)
|
||||
{
|
||||
COLORREF oldbg = bgcolor;
|
||||
|
||||
// reset to standard colors
|
||||
fgcolor = RGB(0x00,0x00,0x00);
|
||||
// pick new background color
|
||||
bgcolor = RGB(0xff,0xff,0xff);
|
||||
|
||||
// pick new fg/bg colors
|
||||
if (viewdata[col].attrib & DCA_VISITED) bgcolor = RGB(0xc6, 0xe2, 0xff);
|
||||
if (viewdata[col].attrib & DCA_ANCILLARY) bgcolor = RGB(0xe0,0xe0,0xe0);
|
||||
if (viewdata[col].attrib & DCA_SELECTED) bgcolor = RGB(0xff,0x80,0x80);
|
||||
if (viewdata[col].attrib & DCA_CURRENT) bgcolor = RGB(0xff,0xff,0x00);
|
||||
if ((viewdata[col].attrib & DCA_SELECTED) && (viewdata[col].attrib & DCA_CURRENT)) bgcolor = RGB(0xff,0xc0,0x80);
|
||||
|
||||
// pick new foreground color
|
||||
fgcolor = RGB(0x00,0x00,0x00);
|
||||
if (viewdata[col].attrib & DCA_CHANGED) fgcolor = RGB(0xff,0x00,0x00);
|
||||
if (viewdata[col].attrib & DCA_INVALID) fgcolor = RGB(0x00,0x00,0xff);
|
||||
if (viewdata[col].attrib & DCA_DISABLED) fgcolor = RGB((GetRValue(fgcolor) + GetRValue(bgcolor)) / 2, (GetGValue(fgcolor) + GetGValue(bgcolor)) / 2, (GetBValue(fgcolor) + GetBValue(bgcolor)) / 2);
|
||||
@ -471,21 +477,41 @@ void debugview_info::draw_contents(HDC windc)
|
||||
{
|
||||
bounds.right = bounds.left + (count * metrics().debug_font_width());
|
||||
if (iter == 0)
|
||||
{
|
||||
FillRect(dc, &bounds, bgbrush);
|
||||
if (do_filldown)
|
||||
{
|
||||
COLORREF const filldown = (last_attrib & DCA_ANCILLARY) ? RGB(0xe0,0xe0,0xe0) : RGB(0xff,0xff,0xff);
|
||||
if (oldbg != filldown)
|
||||
{
|
||||
DeleteObject(bgbrush);
|
||||
bgbrush = CreateSolidBrush(filldown);
|
||||
oldbg = filldown;
|
||||
}
|
||||
RECT padding = bounds;
|
||||
padding.top = padding.bottom;
|
||||
padding.bottom = client.bottom;
|
||||
FillRect(dc, &padding, bgbrush);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ExtTextOut(dc, bounds.left, bounds.top, 0, nullptr, buffer, count, nullptr);
|
||||
}
|
||||
bounds.left = bounds.right;
|
||||
count = 0;
|
||||
}
|
||||
|
||||
// set the new colors
|
||||
if (iter == 0 && oldbg != bgcolor)
|
||||
if (iter == 1)
|
||||
{
|
||||
SetTextColor(dc, fgcolor);
|
||||
}
|
||||
else if (oldbg != bgcolor)
|
||||
{
|
||||
DeleteObject(bgbrush);
|
||||
bgbrush = CreateSolidBrush(bgcolor);
|
||||
}
|
||||
else if (iter == 1)
|
||||
SetTextColor(dc, fgcolor);
|
||||
last_attrib = viewdata[col].attrib;
|
||||
}
|
||||
|
||||
@ -494,33 +520,43 @@ void debugview_info::draw_contents(HDC windc)
|
||||
}
|
||||
|
||||
// flush any remaining stuff
|
||||
if (count > 0)
|
||||
{
|
||||
bounds.right = bounds.left + (count * metrics().debug_font_width());
|
||||
if (iter == 0)
|
||||
FillRect(dc, &bounds, bgbrush);
|
||||
else
|
||||
ExtTextOut(dc, bounds.left, bounds.top, 0, nullptr, buffer, count, nullptr);
|
||||
}
|
||||
|
||||
// erase to the end of the line
|
||||
bounds.right = bounds.left + (count * metrics().debug_font_width());
|
||||
if (iter == 0)
|
||||
{
|
||||
bounds.left = bounds.right;
|
||||
// erase to the end of the line
|
||||
bounds.right = client.right;
|
||||
FillRect(dc, &bounds, bgbrush);
|
||||
if (do_filldown)
|
||||
{
|
||||
COLORREF const filldown = (last_attrib & DCA_ANCILLARY) ? RGB(0xe0,0xe0,0xe0) : RGB(0xff,0xff,0xff);
|
||||
if (bgcolor != filldown)
|
||||
{
|
||||
DeleteObject(bgbrush);
|
||||
bgbrush = CreateSolidBrush(filldown);
|
||||
}
|
||||
bounds.top = bounds.bottom;
|
||||
bounds.bottom = client.bottom;
|
||||
FillRect(dc, &bounds, bgbrush);
|
||||
}
|
||||
DeleteObject(bgbrush);
|
||||
}
|
||||
else if (count > 0)
|
||||
{
|
||||
ExtTextOut(dc, bounds.left, bounds.top, 0, nullptr, buffer, count, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
// advance viewdata
|
||||
viewdata += visarea.x;
|
||||
}
|
||||
|
||||
// erase anything beyond the bottom with white
|
||||
GetClientRect(m_wnd, &client);
|
||||
client.top = visarea.y * metrics().debug_font_height();
|
||||
FillRect(dc, &client, (HBRUSH)GetStockObject(WHITE_BRUSH));
|
||||
// prevent garbage from showing in the corner
|
||||
if (show_hscroll)
|
||||
{
|
||||
client.top = client.bottom;
|
||||
client.bottom = client.top + metrics().hscroll_height();
|
||||
FillRect(dc, &client, (HBRUSH)GetStockObject(WHITE_BRUSH));
|
||||
}
|
||||
|
||||
// reset the font
|
||||
SetBkMode(dc, oldbkmode);
|
||||
@ -539,47 +575,48 @@ void debugview_info::draw_contents(HDC windc)
|
||||
|
||||
void debugview_info::update()
|
||||
{
|
||||
RECT bounds, vscroll_bounds, hscroll_bounds;
|
||||
debug_view_xy totalsize, visiblesize, topleft;
|
||||
bool show_vscroll, show_hscroll;
|
||||
SCROLLINFO scrollinfo;
|
||||
|
||||
// get the updated total rows/cols and left row/col
|
||||
debug_view_xy const totalsize = m_view->total_size();
|
||||
debug_view_xy topleft = m_view->visible_position();
|
||||
|
||||
// get the view window bounds
|
||||
RECT bounds;
|
||||
GetClientRect(m_wnd, &bounds);
|
||||
debug_view_xy visiblesize;
|
||||
visiblesize.x = (bounds.right - bounds.left) / metrics().debug_font_width();
|
||||
visiblesize.y = (bounds.bottom - bounds.top) / metrics().debug_font_height();
|
||||
|
||||
// get the updated total rows/cols and left row/col
|
||||
totalsize = m_view->total_size();
|
||||
topleft = m_view->visible_position();
|
||||
|
||||
// determine if we need to show the scrollbars
|
||||
show_vscroll = show_hscroll = false;
|
||||
if (totalsize.x > visiblesize.x && bounds.bottom >= metrics().hscroll_height())
|
||||
bool const fit_hscroll = (bounds.bottom - bounds.top) > metrics().hscroll_height();
|
||||
bool show_hscroll = fit_hscroll && (totalsize.x > visiblesize.x);
|
||||
if (show_hscroll)
|
||||
{
|
||||
bounds.bottom -= metrics().hscroll_height();
|
||||
visiblesize.y = (bounds.bottom - bounds.top) / metrics().debug_font_height();
|
||||
show_hscroll = true;
|
||||
}
|
||||
if (totalsize.y > visiblesize.y && bounds.right >= metrics().vscroll_width())
|
||||
bool const fit_vscroll = (bounds.right - bounds.left) > metrics().vscroll_width();
|
||||
bool const show_vscroll = fit_vscroll && (totalsize.y > visiblesize.y);
|
||||
if (show_vscroll)
|
||||
{
|
||||
bounds.right -= metrics().vscroll_width();
|
||||
visiblesize.x = (bounds.right - bounds.left) / metrics().debug_font_width();
|
||||
show_vscroll = true;
|
||||
}
|
||||
if (!show_vscroll && totalsize.y > visiblesize.y && bounds.right >= metrics().vscroll_width())
|
||||
{
|
||||
bounds.right -= metrics().vscroll_width();
|
||||
visiblesize.x = (bounds.right - bounds.left) / metrics().debug_font_width();
|
||||
show_vscroll = true;
|
||||
if (fit_hscroll && !show_hscroll && (totalsize.x > visiblesize.x))
|
||||
{
|
||||
bounds.bottom -= metrics().hscroll_height();
|
||||
visiblesize.y = (bounds.bottom - bounds.top) / metrics().debug_font_height();
|
||||
show_hscroll = true;
|
||||
}
|
||||
}
|
||||
|
||||
// compute the bounds of the scrollbars
|
||||
RECT vscroll_bounds;
|
||||
GetClientRect(m_wnd, &vscroll_bounds);
|
||||
vscroll_bounds.left = vscroll_bounds.right - metrics().vscroll_width();
|
||||
if (show_hscroll)
|
||||
vscroll_bounds.bottom -= metrics().hscroll_height();
|
||||
|
||||
RECT hscroll_bounds;
|
||||
GetClientRect(m_wnd, &hscroll_bounds);
|
||||
hscroll_bounds.top = hscroll_bounds.bottom - metrics().hscroll_height();
|
||||
if (show_vscroll)
|
||||
@ -592,26 +629,34 @@ void debugview_info::update()
|
||||
topleft.x = std::max(totalsize.x - visiblesize.x, 0);
|
||||
|
||||
// fill out the scroll info struct for the vertical scrollbar
|
||||
scrollinfo.cbSize = sizeof(scrollinfo);
|
||||
scrollinfo.fMask = SIF_PAGE | SIF_POS | SIF_RANGE;
|
||||
scrollinfo.nMin = 0;
|
||||
scrollinfo.nMax = totalsize.y - 1;
|
||||
scrollinfo.nPage = visiblesize.y;
|
||||
scrollinfo.nPos = topleft.y;
|
||||
SetScrollInfo(m_vscroll, SB_CTL, &scrollinfo, TRUE);
|
||||
if (m_vscroll)
|
||||
{
|
||||
scrollinfo.cbSize = sizeof(scrollinfo);
|
||||
scrollinfo.fMask = SIF_PAGE | SIF_POS | SIF_RANGE;
|
||||
scrollinfo.nMin = 0;
|
||||
scrollinfo.nMax = totalsize.y - 1;
|
||||
scrollinfo.nPage = visiblesize.y;
|
||||
scrollinfo.nPos = topleft.y;
|
||||
SetScrollInfo(m_vscroll, SB_CTL, &scrollinfo, TRUE);
|
||||
}
|
||||
|
||||
// fill out the scroll info struct for the horizontal scrollbar
|
||||
scrollinfo.cbSize = sizeof(scrollinfo);
|
||||
scrollinfo.fMask = SIF_PAGE | SIF_POS | SIF_RANGE;
|
||||
scrollinfo.nMin = 0;
|
||||
scrollinfo.nMax = totalsize.x - 1;
|
||||
scrollinfo.nPage = visiblesize.x;
|
||||
scrollinfo.nPos = topleft.x;
|
||||
SetScrollInfo(m_hscroll, SB_CTL, &scrollinfo, TRUE);
|
||||
if (m_hscroll)
|
||||
{
|
||||
scrollinfo.cbSize = sizeof(scrollinfo);
|
||||
scrollinfo.fMask = SIF_PAGE | SIF_POS | SIF_RANGE;
|
||||
scrollinfo.nMin = 0;
|
||||
scrollinfo.nMax = totalsize.x - 1;
|
||||
scrollinfo.nPage = visiblesize.x;
|
||||
scrollinfo.nPos = topleft.x;
|
||||
SetScrollInfo(m_hscroll, SB_CTL, &scrollinfo, TRUE);
|
||||
}
|
||||
|
||||
// update window info
|
||||
visiblesize.y++;
|
||||
visiblesize.x++;
|
||||
if (((bounds.right - bounds.left) > (visiblesize.x * metrics().debug_font_width())) && ((topleft.x + visiblesize.x) < totalsize.x))
|
||||
visiblesize.x++;
|
||||
if (((bounds.bottom - bounds.top) > (visiblesize.y * metrics().debug_font_height())) && ((topleft.y + visiblesize.y) < totalsize.y))
|
||||
visiblesize.y++;
|
||||
m_view->set_visible_size(visiblesize);
|
||||
m_view->set_visible_position(topleft);
|
||||
|
||||
@ -691,7 +736,7 @@ uint32_t debugview_info::process_scroll(WORD type, HWND wnd)
|
||||
scrollinfo.nPos = result;
|
||||
SetScrollInfo(wnd, SB_CTL, &scrollinfo, TRUE);
|
||||
|
||||
return (uint32_t)result;
|
||||
return uint32_t(result);
|
||||
}
|
||||
|
||||
|
||||
@ -864,10 +909,11 @@ LRESULT debugview_info::view_proc(UINT message, WPARAM wparam, LPARAM lparam)
|
||||
case WM_LBUTTONDOWN:
|
||||
case WM_MBUTTONDOWN:
|
||||
{
|
||||
debug_view_xy topleft = m_view->visible_position();
|
||||
debug_view_xy const topleft = m_view->visible_position();
|
||||
debug_view_xy const visiblesize = m_view->visible_size();
|
||||
debug_view_xy newpos;
|
||||
newpos.x = topleft.x + GET_X_LPARAM(lparam) / metrics().debug_font_width();
|
||||
newpos.y = topleft.y + GET_Y_LPARAM(lparam) / metrics().debug_font_height();
|
||||
newpos.x = std::max(std::min<int>(topleft.x + GET_X_LPARAM(lparam) / metrics().debug_font_width(), topleft.x + visiblesize.x - 1), 0);
|
||||
newpos.y = std::max(std::min<int>(topleft.y + GET_Y_LPARAM(lparam) / metrics().debug_font_height(), topleft.y + visiblesize.y - 1), 0);
|
||||
m_view->process_click((message == WM_LBUTTONDOWN) ? DCK_LEFT_CLICK : DCK_MIDDLE_CLICK, newpos);
|
||||
SetFocus(m_wnd);
|
||||
break;
|
||||
@ -877,10 +923,11 @@ LRESULT debugview_info::view_proc(UINT message, WPARAM wparam, LPARAM lparam)
|
||||
case WM_RBUTTONDOWN:
|
||||
if (m_view->cursor_supported())
|
||||
{
|
||||
debug_view_xy topleft = m_view->visible_position();
|
||||
debug_view_xy const topleft = m_view->visible_position();
|
||||
debug_view_xy const visiblesize = m_view->visible_size();
|
||||
debug_view_xy newpos;
|
||||
newpos.x = topleft.x + GET_X_LPARAM(lparam) / metrics().debug_font_width();
|
||||
newpos.y = topleft.y + GET_Y_LPARAM(lparam) / metrics().debug_font_height();
|
||||
newpos.x = std::max(std::min<int>(topleft.x + GET_X_LPARAM(lparam) / metrics().debug_font_width(), topleft.x + visiblesize.x - 1), 0);
|
||||
newpos.y = std::max(std::min<int>(topleft.y + GET_Y_LPARAM(lparam) / metrics().debug_font_height(), topleft.y + visiblesize.y - 1), 0);
|
||||
m_view->set_cursor_position(newpos);
|
||||
m_view->set_cursor_visible(true);
|
||||
}
|
||||
|
@ -11,6 +11,8 @@
|
||||
|
||||
#include "debug/dvmemory.h"
|
||||
|
||||
#include "strconv.h"
|
||||
|
||||
|
||||
memoryview_info::memoryview_info(debugger_windows_interface &debugger, debugwin_info &owner, HWND parent) :
|
||||
debugview_info(debugger, owner, parent, DVT_MEMORY)
|
||||
@ -71,3 +73,86 @@ void memoryview_info::set_physical(bool physical)
|
||||
{
|
||||
view<debug_view_memory>()->set_physical(physical);
|
||||
}
|
||||
|
||||
|
||||
void memoryview_info::add_items_to_context_menu(HMENU menu)
|
||||
{
|
||||
debugview_info::add_items_to_context_menu(menu);
|
||||
|
||||
AppendMenu(menu, MF_DISABLED | MF_SEPARATOR, 0, TEXT(""));
|
||||
AppendMenu(menu, MF_GRAYED, ID_CONTEXT_LAST_PC, TEXT("Last PC"));
|
||||
}
|
||||
|
||||
void memoryview_info::update_context_menu(HMENU menu)
|
||||
{
|
||||
debugview_info::update_context_menu(menu);
|
||||
|
||||
bool enable = false;
|
||||
debug_view_memory &memview(*view<debug_view_memory>());
|
||||
debug_view_memory_source const &source = downcast<debug_view_memory_source const &>(*memview.source());
|
||||
address_space *const space = source.space();
|
||||
if (space)
|
||||
{
|
||||
if (memview.cursor_visible())
|
||||
{
|
||||
// get the last known PC to write to this memory location
|
||||
debug_view_xy const pos = memview.cursor_position();
|
||||
offs_t const address = memview.addressAtCursorPosition(pos);
|
||||
offs_t a = address & space->logaddrmask();
|
||||
if (!space->device().memory().translate(space->spacenum(), TRANSLATE_READ_DEBUG, a))
|
||||
{
|
||||
m_lastpc = "Bad address";
|
||||
}
|
||||
else
|
||||
{
|
||||
uint64_t memval = space->unmap();
|
||||
auto dis = space->device().machine().disable_side_effects();
|
||||
switch (space->data_width())
|
||||
{
|
||||
case 8: memval = space->read_byte(a); break;
|
||||
case 16: memval = space->read_word_unaligned(a); break;
|
||||
case 32: memval = space->read_dword_unaligned(a); break;
|
||||
case 64: memval = space->read_qword_unaligned(a); break;
|
||||
}
|
||||
|
||||
offs_t const pc = source.device()->debug()->track_mem_pc_from_space_address_data(
|
||||
space->spacenum(),
|
||||
address,
|
||||
memval);
|
||||
if (pc != offs_t(-1))
|
||||
{
|
||||
m_lastpc = util::string_format("Address %x written at PC=%x", address, pc);
|
||||
enable = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_lastpc = "Unknown PC";
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_lastpc = "No address";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_lastpc = "Not an address space";
|
||||
}
|
||||
ModifyMenuW(menu, ID_CONTEXT_LAST_PC, MF_BYCOMMAND, ID_CONTEXT_LAST_PC, osd::text::to_wstring(m_lastpc).c_str());
|
||||
EnableMenuItem(menu, ID_CONTEXT_LAST_PC, MF_BYCOMMAND | (enable ? MF_ENABLED : MF_GRAYED));
|
||||
}
|
||||
|
||||
void memoryview_info::handle_context_menu(unsigned command)
|
||||
{
|
||||
switch (command)
|
||||
{
|
||||
case ID_CONTEXT_LAST_PC:
|
||||
// TODO: copy to clipboard
|
||||
return;
|
||||
|
||||
default:
|
||||
debugview_info::handle_context_menu(command);
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -14,6 +14,8 @@
|
||||
|
||||
#include "debugviewinfo.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
|
||||
class memoryview_info : public debugview_info
|
||||
{
|
||||
@ -31,6 +33,19 @@ public:
|
||||
void set_chunks_per_row(uint32_t rowchunks);
|
||||
void set_reverse(bool reverse);
|
||||
void set_physical(bool physical);
|
||||
|
||||
protected:
|
||||
enum
|
||||
{
|
||||
ID_CONTEXT_LAST_PC = 101
|
||||
};
|
||||
|
||||
virtual void add_items_to_context_menu(HMENU menu) override;
|
||||
virtual void update_context_menu(HMENU menu) override;
|
||||
virtual void handle_context_menu(unsigned command) override;
|
||||
|
||||
private:
|
||||
std::string m_lastpc;
|
||||
};
|
||||
|
||||
#endif // MAME_DEBUGGER_WIN_MEMORYVIEWINFO_H
|
||||
|
Loading…
Reference in New Issue
Block a user