summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/debug/dvwpoints.cpp
diff options
context:
space:
mode:
author Miodrag Milanovic <mmicko@gmail.com>2015-11-08 12:56:12 +0100
committer Miodrag Milanovic <mmicko@gmail.com>2015-11-08 12:56:12 +0100
commit7c19aac60e12d6f5ea301bdb34d7826a01e0b06f (patch)
treef310d86aa2c6bfc19d115307dedde4eb0cd52dad /src/emu/debug/dvwpoints.cpp
parenta57b46ae933badd7441ce1644711dbb851e2b504 (diff)
Rename *.c -> *.cpp in our source (nw)
Diffstat (limited to 'src/emu/debug/dvwpoints.cpp')
-rw-r--r--src/emu/debug/dvwpoints.cpp361
1 files changed, 361 insertions, 0 deletions
diff --git a/src/emu/debug/dvwpoints.cpp b/src/emu/debug/dvwpoints.cpp
new file mode 100644
index 00000000000..2e5f89b24f3
--- /dev/null
+++ b/src/emu/debug/dvwpoints.cpp
@@ -0,0 +1,361 @@
+// license:BSD-3-Clause
+// copyright-holders:Aaron Giles
+/*********************************************************************
+
+ dvwpoints.c
+
+ Watchpoint debugger view.
+
+***************************************************************************/
+
+#include "emu.h"
+#include "dvwpoints.h"
+
+
+
+static int cIndexAscending(const void* a, const void* b)
+{
+ const device_debug::watchpoint* left = *(device_debug::watchpoint**)a;
+ const device_debug::watchpoint* right = *(device_debug::watchpoint**)b;
+ return left->index() - right->index();
+}
+
+static int cIndexDescending(const void* a, const void* b)
+{
+ return cIndexAscending(b, a);
+}
+
+static int cEnabledAscending(const void* a, const void* b)
+{
+ const device_debug::watchpoint* left = *(device_debug::watchpoint**)a;
+ const device_debug::watchpoint* right = *(device_debug::watchpoint**)b;
+ return (left->enabled() ? 1 : 0) - (right->enabled() ? 1 : 0);
+}
+
+static int cEnabledDescending(const void* a, const void* b)
+{
+ return cEnabledAscending(b, a);
+}
+
+static int cCpuAscending(const void* a, const void* b)
+{
+ const device_debug::watchpoint* left = *(device_debug::watchpoint**)a;
+ const device_debug::watchpoint* right = *(device_debug::watchpoint**)b;
+ return strcmp(left->debugInterface()->device().tag(), right->debugInterface()->device().tag());
+}
+
+static int cCpuDescending(const void* a, const void* b)
+{
+ return cCpuAscending(b, a);
+}
+
+static int cSpaceAscending(const void* a, const void* b)
+{
+ const device_debug::watchpoint* left = *(device_debug::watchpoint**)a;
+ const device_debug::watchpoint* right = *(device_debug::watchpoint**)b;
+ return strcmp(left->space().name(), right->space().name());
+}
+
+static int cSpaceDescending(const void* a, const void* b)
+{
+ return cSpaceAscending(b, a);
+}
+
+static int cAddressAscending(const void* a, const void* b)
+{
+ const device_debug::watchpoint* left = *(device_debug::watchpoint**)a;
+ const device_debug::watchpoint* right = *(device_debug::watchpoint**)b;
+ return (left->address() > right->address()) ? 1 : (left->address() < right->address()) ? -1 : 0;
+}
+
+static int cAddressDescending(const void* a, const void* b)
+{
+ return cAddressAscending(b, a);
+}
+
+static int cTypeAscending(const void* a, const void* b)
+{
+ const device_debug::watchpoint* left = *(device_debug::watchpoint**)a;
+ const device_debug::watchpoint* right = *(device_debug::watchpoint**)b;
+ return left->type() - right->type();
+}
+
+static int cTypeDescending(const void* a, const void* b)
+{
+ return cTypeAscending(b, a);
+}
+
+static int cConditionAscending(const void* a, const void* b)
+{
+ const device_debug::watchpoint* left = *(device_debug::watchpoint**)a;
+ const device_debug::watchpoint* right = *(device_debug::watchpoint**)b;
+ return strcmp(left->condition(), right->condition());
+}
+
+static int cConditionDescending(const void* a, const void* b)
+{
+ return cConditionAscending(b, a);
+}
+
+static int cActionAscending(const void* a, const void* b)
+{
+ const device_debug::watchpoint* left = *(device_debug::watchpoint**)a;
+ const device_debug::watchpoint* right = *(device_debug::watchpoint**)b;
+ return strcmp(left->action(), right->action());
+}
+
+static int cActionDescending(const void* a, const void* b)
+{
+ return cActionAscending(b, a);
+}
+
+
+//**************************************************************************
+// DEBUG VIEW WATCH POINTS
+//**************************************************************************
+
+static const int tableBreaks[] = { 5, 9, 31, 42, 60, 67, 86, 100 };
+
+//-------------------------------------------------
+// debug_view_watchpoints - constructor
+//-------------------------------------------------
+
+debug_view_watchpoints::debug_view_watchpoints(running_machine &machine, debug_view_osd_update_func osdupdate, void *osdprivate)
+ : debug_view(machine, DVT_WATCH_POINTS, osdupdate, osdprivate),
+ m_sortType(&cIndexAscending)
+{
+ // fail if no available sources
+ enumerate_sources();
+ if (m_source_list.count() == 0)
+ throw std::bad_alloc();
+}
+
+
+//-------------------------------------------------
+// ~debug_view_watchpoints - destructor
+//-------------------------------------------------
+
+debug_view_watchpoints::~debug_view_watchpoints()
+{
+}
+
+
+//-------------------------------------------------
+// enumerate_sources - enumerate all possible
+// sources for a disassembly view
+//-------------------------------------------------
+
+void debug_view_watchpoints::enumerate_sources()
+{
+ // start with an empty list
+ m_source_list.reset();
+
+ // iterate over devices with disassembly interfaces
+ disasm_interface_iterator iter(machine().root_device());
+ for (device_disasm_interface *dasm = iter.first(); dasm != NULL; dasm = iter.next())
+ {
+ std::string name;
+ strprintf(name, "%s '%s'", dasm->device().name(), dasm->device().tag());
+ m_source_list.append(*global_alloc(debug_view_source(name.c_str(), &dasm->device())));
+ }
+
+ // reset the source to a known good entry
+ set_source(*m_source_list.first());
+}
+
+
+//-------------------------------------------------
+// view_click - handle a mouse click within the
+// current view
+//-------------------------------------------------
+
+void debug_view_watchpoints::view_click(const int button, const debug_view_xy& pos)
+{
+ bool const clickedTopRow = (m_topleft.y == pos.y);
+
+ if (clickedTopRow)
+ {
+ if (pos.x < tableBreaks[0])
+ m_sortType = (m_sortType == &cIndexAscending) ? &cIndexDescending : &cIndexAscending;
+ else if (pos.x < tableBreaks[1])
+ m_sortType = (m_sortType == &cEnabledAscending) ? &cEnabledDescending : &cEnabledAscending;
+ else if (pos.x < tableBreaks[2])
+ m_sortType = (m_sortType == &cCpuAscending) ? &cCpuDescending : &cCpuAscending;
+ else if (pos.x < tableBreaks[3])
+ m_sortType = (m_sortType == &cSpaceAscending) ? &cSpaceDescending : &cSpaceAscending;
+ else if (pos.x < tableBreaks[4])
+ m_sortType = (m_sortType == &cAddressAscending) ? &cAddressDescending : &cAddressAscending;
+ else if (pos.x < tableBreaks[5])
+ m_sortType = (m_sortType == &cTypeAscending) ? &cTypeDescending : &cTypeAscending;
+ else if (pos.x < tableBreaks[6])
+ m_sortType = (m_sortType == &cConditionAscending) ? &cConditionDescending : &cConditionAscending;
+ else if (pos.x < tableBreaks[7])
+ m_sortType = (m_sortType == &cActionAscending) ? &cActionDescending : &cActionAscending;
+ }
+ else
+ {
+ // Gather a sorted list of all the watchpoints for all the CPUs
+ gather_watchpoints();
+
+ int const wpIndex = pos.y - 1;
+ if ((wpIndex >= m_buffer.size()) || (wpIndex < 0))
+ return;
+
+ // Enable / disable
+ m_buffer[wpIndex]->setEnabled(!m_buffer[wpIndex]->enabled());
+ }
+
+ begin_update();
+ m_update_pending = true;
+ end_update();
+}
+
+
+void debug_view_watchpoints::pad_astring_to_length(std::string& str, int len)
+{
+ int diff = len - str.length();
+ if (diff > 0)
+ {
+ std::string buffer;
+ for (int i = 0; i < diff; i++)
+ buffer.append(" ");
+ strcatprintf(str, "%s", buffer.c_str());
+ }
+}
+
+
+void debug_view_watchpoints::gather_watchpoints()
+{
+ m_buffer.resize(0);
+ for (const debug_view_source *source = m_source_list.first(); source != NULL; source = source->next())
+ {
+ // Collect
+ device_debug &debugInterface = *source->device()->debug();
+ for (address_spacenum spacenum = AS_0; spacenum < ADDRESS_SPACES; spacenum++)
+ {
+ for (device_debug::watchpoint *wp = debugInterface.watchpoint_first(spacenum); wp != NULL; wp = wp->next())
+ m_buffer.push_back(wp);
+ }
+ }
+
+ // And now for the sort
+ if (!m_buffer.empty())
+ qsort(&m_buffer[0], m_buffer.size(), sizeof(device_debug::watchpoint *), m_sortType);
+}
+
+
+//-------------------------------------------------
+// view_update - update the contents of the
+// watchpoints view
+//-------------------------------------------------
+
+void debug_view_watchpoints::view_update()
+{
+ // Gather a list of all the watchpoints for all the CPUs
+ gather_watchpoints();
+
+ // Set the view region so the scroll bars update
+ m_total.x = tableBreaks[ARRAY_LENGTH(tableBreaks) - 1];
+ m_total.y = m_buffer.size() + 1;
+ if (m_total.y < 10)
+ m_total.y = 10;
+
+ // Draw
+ debug_view_char *dest = &m_viewdata[0];
+ std::string linebuf;
+
+ // Header
+ if (m_visible.y > 0)
+ {
+ linebuf.clear();
+ linebuf.append("ID");
+ if (m_sortType == &cIndexAscending) linebuf.push_back('\\');
+ else if (m_sortType == &cIndexDescending) linebuf.push_back('/');
+ pad_astring_to_length(linebuf, tableBreaks[0]);
+ linebuf.append("En");
+ if (m_sortType == &cEnabledAscending) linebuf.push_back('\\');
+ else if (m_sortType == &cEnabledDescending) linebuf.push_back('/');
+ pad_astring_to_length(linebuf, tableBreaks[1]);
+ linebuf.append("CPU");
+ if (m_sortType == &cCpuAscending) linebuf.push_back('\\');
+ else if (m_sortType == &cCpuDescending) linebuf.push_back('/');
+ pad_astring_to_length(linebuf, tableBreaks[2]);
+ linebuf.append("Space");
+ if (m_sortType == &cSpaceAscending) linebuf.push_back('\\');
+ else if (m_sortType == &cSpaceDescending) linebuf.push_back('/');
+ pad_astring_to_length(linebuf, tableBreaks[3]);
+ linebuf.append("Addresses");
+ if (m_sortType == &cAddressAscending) linebuf.push_back('\\');
+ else if (m_sortType == &cAddressDescending) linebuf.push_back('/');
+ pad_astring_to_length(linebuf, tableBreaks[4]);
+ linebuf.append("Type");
+ if (m_sortType == &cTypeAscending) linebuf.push_back('\\');
+ else if (m_sortType == &cTypeDescending) linebuf.push_back('/');
+ pad_astring_to_length(linebuf, tableBreaks[5]);
+ linebuf.append("Condition");
+ if (m_sortType == &cConditionAscending) linebuf.push_back('\\');
+ else if (m_sortType == &cConditionDescending) linebuf.push_back('/');
+ pad_astring_to_length(linebuf, tableBreaks[6]);
+ linebuf.append("Action");
+ if (m_sortType == &cActionAscending) linebuf.push_back('\\');
+ else if (m_sortType == &cActionDescending) linebuf.push_back('/');
+ pad_astring_to_length(linebuf, tableBreaks[7]);
+
+ for (UINT32 i = m_topleft.x; i < (m_topleft.x + m_visible.x); i++, dest++)
+ {
+ dest->byte = (i < linebuf.length()) ? linebuf[i] : ' ';
+ dest->attrib = DCA_ANCILLARY;
+ }
+ }
+
+ for (int row = 1; row < m_visible.y; row++)
+ {
+ // watchpoints
+ int const wpi = row + m_topleft.y - 1;
+ if ((wpi < m_buffer.size()) && wpi >= 0)
+ {
+ static char const *const types[] = { "unkn ", "read ", "write", "r/w " };
+ device_debug::watchpoint *const wp = m_buffer[wpi];
+
+ linebuf.clear();
+ strcatprintf(linebuf, "%2X", wp->index());
+ pad_astring_to_length(linebuf, tableBreaks[0]);
+ linebuf.push_back(wp->enabled() ? 'X' : 'O');
+ pad_astring_to_length(linebuf, tableBreaks[1]);
+ linebuf.append(wp->debugInterface()->device().tag());
+ pad_astring_to_length(linebuf, tableBreaks[2]);
+ linebuf.append(wp->space().name());
+ pad_astring_to_length(linebuf, tableBreaks[3]);
+ linebuf.append(core_i64_hex_format(wp->space().byte_to_address(wp->address()), wp->space().addrchars()));
+ linebuf.push_back('-');
+ linebuf.append(core_i64_hex_format(wp->space().byte_to_address_end(wp->address() + wp->length()) - 1, wp->space().addrchars()));
+ pad_astring_to_length(linebuf, tableBreaks[4]);
+ linebuf.append(types[wp->type() & 3]);
+ pad_astring_to_length(linebuf, tableBreaks[5]);
+ if (strcmp(wp->condition(), "1"))
+ linebuf.append(wp->condition());
+ pad_astring_to_length(linebuf, tableBreaks[6]);
+ linebuf.append(wp->action());
+ pad_astring_to_length(linebuf, tableBreaks[7]);
+
+ for (UINT32 i = m_topleft.x; i < (m_topleft.x + m_visible.x); i++, dest++)
+ {
+ dest->byte = (i < linebuf.length()) ? linebuf[i] : ' ';
+ dest->attrib = DCA_NORMAL;
+
+ // Color disabled watchpoints red
+ if ((i >= tableBreaks[0]) && (i < tableBreaks[1]) && !wp->enabled())
+ dest->attrib |= DCA_CHANGED;
+ }
+ }
+ else
+ {
+ // Fill the remaining vertical space
+ for (int i = 0; i < m_visible.x; i++, dest++)
+ {
+ dest->byte = ' ';
+ dest->attrib = DCA_NORMAL;
+ }
+ }
+ }
+}