mirror of
https://github.com/holub/mame
synced 2025-07-04 17:38:08 +03:00
Many fixes for breakpoints/watchpoints views
* Fix sorting - qsort needs a ternary -1/0/1 comparator * Get rid of the redundant enums - using a funciton pointer is far more concise * Reduce number of allocations and use less expensive functions when updating * Fix off-by-one error that could cause a crash when clicking the views * Get rid of double iteration
This commit is contained in:
parent
3047ba4982
commit
2c4d4a7837
@ -13,6 +13,80 @@
|
||||
|
||||
|
||||
|
||||
// Sorting functors for the qsort function
|
||||
static int cIndexAscending(const void* a, const void* b)
|
||||
{
|
||||
const device_debug::breakpoint* left = *(device_debug::breakpoint**)a;
|
||||
const device_debug::breakpoint* right = *(device_debug::breakpoint**)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::breakpoint* left = *(device_debug::breakpoint**)a;
|
||||
const device_debug::breakpoint* right = *(device_debug::breakpoint**)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::breakpoint* left = *(device_debug::breakpoint**)a;
|
||||
const device_debug::breakpoint* right = *(device_debug::breakpoint**)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 cAddressAscending(const void* a, const void* b)
|
||||
{
|
||||
const device_debug::breakpoint* left = *(device_debug::breakpoint**)a;
|
||||
const device_debug::breakpoint* right = *(device_debug::breakpoint**)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 cConditionAscending(const void* a, const void* b)
|
||||
{
|
||||
const device_debug::breakpoint* left = *(device_debug::breakpoint**)a;
|
||||
const device_debug::breakpoint* right = *(device_debug::breakpoint**)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::breakpoint* left = *(device_debug::breakpoint**)a;
|
||||
const device_debug::breakpoint* right = *(device_debug::breakpoint**)b;
|
||||
return strcmp(left->action(), right->action());
|
||||
}
|
||||
|
||||
static int cActionDescending(const void* a, const void* b)
|
||||
{
|
||||
return cActionAscending(b, a);
|
||||
}
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// DEBUG VIEW BREAK POINTS
|
||||
//**************************************************************************
|
||||
@ -26,7 +100,7 @@ static const int tableBreaks[] = { 5, 9, 31, 45, 63, 80 };
|
||||
|
||||
debug_view_breakpoints::debug_view_breakpoints(running_machine &machine, debug_view_osd_update_func osdupdate, void *osdprivate)
|
||||
: debug_view(machine, DVT_BREAK_POINTS, osdupdate, osdprivate),
|
||||
m_sortType(SORT_INDEX_ASCENDING)
|
||||
m_sortType(cIndexAscending)
|
||||
{
|
||||
// fail if no available sources
|
||||
enumerate_sources();
|
||||
@ -79,48 +153,30 @@ void debug_view_breakpoints::view_click(const int button, const debug_view_xy& p
|
||||
|
||||
if (clickedTopRow)
|
||||
{
|
||||
if (pos.x < tableBreaks[0] && m_sortType == SORT_INDEX_ASCENDING)
|
||||
m_sortType = SORT_INDEX_DESCENDING;
|
||||
else if (pos.x < tableBreaks[0])
|
||||
m_sortType = SORT_INDEX_ASCENDING;
|
||||
else if (pos.x < tableBreaks[1] && m_sortType == SORT_ENABLED_ASCENDING)
|
||||
m_sortType = SORT_ENABLED_DESCENDING;
|
||||
if (pos.x < tableBreaks[0])
|
||||
m_sortType = (m_sortType == &cIndexAscending) ? &cIndexDescending : &cIndexAscending;
|
||||
else if (pos.x < tableBreaks[1])
|
||||
m_sortType = SORT_ENABLED_ASCENDING;
|
||||
else if (pos.x < tableBreaks[2] && m_sortType == SORT_CPU_ASCENDING)
|
||||
m_sortType = SORT_CPU_DESCENDING;
|
||||
m_sortType = (m_sortType == &cEnabledAscending) ? &cEnabledDescending : &cEnabledAscending;
|
||||
else if (pos.x < tableBreaks[2])
|
||||
m_sortType = SORT_CPU_ASCENDING;
|
||||
else if (pos.x < tableBreaks[3] && m_sortType == SORT_ADDRESS_ASCENDING)
|
||||
m_sortType = SORT_ADDRESS_DESCENDING;
|
||||
m_sortType = (m_sortType == &cCpuAscending) ? &cCpuDescending : &cCpuAscending;
|
||||
else if (pos.x < tableBreaks[3])
|
||||
m_sortType = SORT_ADDRESS_ASCENDING;
|
||||
else if (pos.x < tableBreaks[4] && m_sortType == SORT_CONDITION_ASCENDING)
|
||||
m_sortType = SORT_CONDITION_DESCENDING;
|
||||
m_sortType = (m_sortType == &cAddressAscending) ? &cAddressDescending : &cAddressAscending;
|
||||
else if (pos.x < tableBreaks[4])
|
||||
m_sortType = SORT_CONDITION_ASCENDING;
|
||||
else if (pos.x < tableBreaks[5] && m_sortType == SORT_ACTION_ASCENDING)
|
||||
m_sortType = SORT_ACTION_DESCENDING;
|
||||
m_sortType = (m_sortType == &cConditionAscending) ? &cConditionDescending : &cConditionAscending;
|
||||
else if (pos.x < tableBreaks[5])
|
||||
m_sortType = SORT_ACTION_ASCENDING;
|
||||
m_sortType = (m_sortType == &cActionAscending) ? &cActionDescending : &cActionAscending;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Gather a sorted list of all the breakpoints for all the CPUs
|
||||
device_debug::breakpoint** bpList = NULL;
|
||||
const int numBPs = breakpoints(SORT_NONE, bpList);
|
||||
gather_breakpoints();
|
||||
|
||||
const int bpIndex = pos.y - 1;
|
||||
if (bpIndex > numBPs || bpIndex < 0)
|
||||
int const bpIndex = pos.y - 1;
|
||||
if ((bpIndex >= m_buffer.count()) || (bpIndex < 0))
|
||||
return;
|
||||
|
||||
// Enable / disable
|
||||
if (bpList[bpIndex]->enabled())
|
||||
bpList[bpIndex]->setEnabled(false);
|
||||
else
|
||||
bpList[bpIndex]->setEnabled(true);
|
||||
|
||||
delete[] bpList;
|
||||
m_buffer[bpIndex]->setEnabled(!m_buffer[bpIndex]->enabled());
|
||||
|
||||
machine().debug_view().update_all(DVT_DISASSEMBLY);
|
||||
}
|
||||
@ -145,167 +201,19 @@ void debug_view_breakpoints::pad_astring_to_length(astring& str, int len)
|
||||
}
|
||||
|
||||
|
||||
// Sorting functors for the qsort function
|
||||
static int cIndexAscending(const void* a, const void* b)
|
||||
void debug_view_breakpoints::gather_breakpoints()
|
||||
{
|
||||
const device_debug::breakpoint* left = *(device_debug::breakpoint**)a;
|
||||
const device_debug::breakpoint* right = *(device_debug::breakpoint**)b;
|
||||
return left->index() > right->index();
|
||||
}
|
||||
|
||||
static int cIndexDescending(const void* a, const void* b)
|
||||
{
|
||||
const device_debug::breakpoint* left = *(device_debug::breakpoint**)a;
|
||||
const device_debug::breakpoint* right = *(device_debug::breakpoint**)b;
|
||||
return left->index() < right->index();
|
||||
}
|
||||
|
||||
static int cEnabledAscending(const void* a, const void* b)
|
||||
{
|
||||
const device_debug::breakpoint* left = *(device_debug::breakpoint**)a;
|
||||
const device_debug::breakpoint* right = *(device_debug::breakpoint**)b;
|
||||
return left->enabled() < right->enabled();
|
||||
}
|
||||
|
||||
static int cEnabledDescending(const void* a, const void* b)
|
||||
{
|
||||
const device_debug::breakpoint* left = *(device_debug::breakpoint**)a;
|
||||
const device_debug::breakpoint* right = *(device_debug::breakpoint**)b;
|
||||
return left->enabled() > right->enabled();
|
||||
}
|
||||
|
||||
static int cCpuAscending(const void* a, const void* b)
|
||||
{
|
||||
const device_debug::breakpoint* left = *(device_debug::breakpoint**)a;
|
||||
const device_debug::breakpoint* right = *(device_debug::breakpoint**)b;
|
||||
const int result = strcmp(left->debugInterface()->device().tag(), right->debugInterface()->device().tag());
|
||||
return result >= 0;
|
||||
}
|
||||
|
||||
static int cCpuDescending(const void* a, const void* b)
|
||||
{
|
||||
const device_debug::breakpoint* left = *(device_debug::breakpoint**)a;
|
||||
const device_debug::breakpoint* right = *(device_debug::breakpoint**)b;
|
||||
const int result = strcmp(left->debugInterface()->device().tag(), right->debugInterface()->device().tag());
|
||||
return result < 0;
|
||||
}
|
||||
|
||||
static int cAddressAscending(const void* a, const void* b)
|
||||
{
|
||||
const device_debug::breakpoint* left = *(device_debug::breakpoint**)a;
|
||||
const device_debug::breakpoint* right = *(device_debug::breakpoint**)b;
|
||||
return left->address() > right->address();
|
||||
}
|
||||
|
||||
static int cAddressDescending(const void* a, const void* b)
|
||||
{
|
||||
const device_debug::breakpoint* left = *(device_debug::breakpoint**)a;
|
||||
const device_debug::breakpoint* right = *(device_debug::breakpoint**)b;
|
||||
return left->address() < right->address();
|
||||
}
|
||||
|
||||
static int cConditionAscending(const void* a, const void* b)
|
||||
{
|
||||
const device_debug::breakpoint* left = *(device_debug::breakpoint**)a;
|
||||
const device_debug::breakpoint* right = *(device_debug::breakpoint**)b;
|
||||
const int result = strcmp(left->condition(), right->condition());
|
||||
return result >= 0;
|
||||
}
|
||||
|
||||
static int cConditionDescending(const void* a, const void* b)
|
||||
{
|
||||
const device_debug::breakpoint* left = *(device_debug::breakpoint**)a;
|
||||
const device_debug::breakpoint* right = *(device_debug::breakpoint**)b;
|
||||
const int result = strcmp(left->condition(), right->condition());
|
||||
return result < 0;
|
||||
}
|
||||
|
||||
static int cActionAscending(const void* a, const void* b)
|
||||
{
|
||||
const device_debug::breakpoint* left = *(device_debug::breakpoint**)a;
|
||||
const device_debug::breakpoint* right = *(device_debug::breakpoint**)b;
|
||||
const int result = strcmp(left->action(), right->action());
|
||||
return result >= 0;
|
||||
}
|
||||
|
||||
static int cActionDescending(const void* a, const void* b)
|
||||
{
|
||||
const device_debug::breakpoint* left = *(device_debug::breakpoint**)a;
|
||||
const device_debug::breakpoint* right = *(device_debug::breakpoint**)b;
|
||||
const int result = strcmp(left->action(), right->action());
|
||||
return result < 0;
|
||||
}
|
||||
|
||||
|
||||
int debug_view_breakpoints::breakpoints(SortMode sort, device_debug::breakpoint**& bpList)
|
||||
{
|
||||
// Alloc
|
||||
int numBPs = 0;
|
||||
bpList = NULL;
|
||||
for (const debug_view_source *source = m_source_list.first(); source != NULL; source = source->next())
|
||||
{
|
||||
const device_debug& debugInterface = *source->device()->debug();
|
||||
for (device_debug::breakpoint *bp = debugInterface.breakpoint_first(); bp != NULL; bp = bp->next())
|
||||
numBPs++;
|
||||
}
|
||||
bpList = new device_debug::breakpoint*[numBPs];
|
||||
|
||||
int bpAddIndex = 0;
|
||||
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();
|
||||
device_debug &debugInterface = *source->device()->debug();
|
||||
for (device_debug::breakpoint *bp = debugInterface.breakpoint_first(); bp != NULL; bp = bp->next())
|
||||
{
|
||||
bpList[bpAddIndex] = bp;
|
||||
bpAddIndex++;
|
||||
}
|
||||
m_buffer.append() = bp;
|
||||
}
|
||||
|
||||
// And now for the sort
|
||||
switch (m_sortType)
|
||||
{
|
||||
case SORT_NONE:
|
||||
break;
|
||||
case SORT_INDEX_ASCENDING:
|
||||
qsort(bpList, numBPs, sizeof(device_debug::breakpoint*), cIndexAscending);
|
||||
break;
|
||||
case SORT_INDEX_DESCENDING:
|
||||
qsort(bpList, numBPs, sizeof(device_debug::breakpoint*), cIndexDescending);
|
||||
break;
|
||||
case SORT_ENABLED_ASCENDING:
|
||||
qsort(bpList, numBPs, sizeof(device_debug::breakpoint*), cEnabledAscending);
|
||||
break;
|
||||
case SORT_ENABLED_DESCENDING:
|
||||
qsort(bpList, numBPs, sizeof(device_debug::breakpoint*), cEnabledDescending);
|
||||
break;
|
||||
case SORT_CPU_ASCENDING:
|
||||
qsort(bpList, numBPs, sizeof(device_debug::breakpoint*), cCpuAscending);
|
||||
break;
|
||||
case SORT_CPU_DESCENDING:
|
||||
qsort(bpList, numBPs, sizeof(device_debug::breakpoint*), cCpuDescending);
|
||||
break;
|
||||
case SORT_ADDRESS_ASCENDING:
|
||||
qsort(bpList, numBPs, sizeof(device_debug::breakpoint*), cAddressAscending);
|
||||
break;
|
||||
case SORT_ADDRESS_DESCENDING:
|
||||
qsort(bpList, numBPs, sizeof(device_debug::breakpoint*), cAddressDescending);
|
||||
break;
|
||||
case SORT_CONDITION_ASCENDING:
|
||||
qsort(bpList, numBPs, sizeof(device_debug::breakpoint*), cConditionAscending);
|
||||
break;
|
||||
case SORT_CONDITION_DESCENDING:
|
||||
qsort(bpList, numBPs, sizeof(device_debug::breakpoint*), cConditionDescending);
|
||||
break;
|
||||
case SORT_ACTION_ASCENDING:
|
||||
qsort(bpList, numBPs, sizeof(device_debug::breakpoint*), cActionAscending);
|
||||
break;
|
||||
case SORT_ACTION_DESCENDING:
|
||||
qsort(bpList, numBPs, sizeof(device_debug::breakpoint*), cActionDescending);
|
||||
break;
|
||||
}
|
||||
|
||||
return numBPs;
|
||||
qsort(&m_buffer[0], m_buffer.count(), sizeof(device_debug::breakpoint *), m_sortType);
|
||||
}
|
||||
|
||||
|
||||
@ -317,106 +225,95 @@ int debug_view_breakpoints::breakpoints(SortMode sort, device_debug::breakpoint*
|
||||
void debug_view_breakpoints::view_update()
|
||||
{
|
||||
// Gather a list of all the breakpoints for all the CPUs
|
||||
device_debug::breakpoint** bpList = NULL;
|
||||
const int numBPs = breakpoints(SORT_NONE, bpList);
|
||||
gather_breakpoints();
|
||||
|
||||
// Set the view region so the scroll bars update
|
||||
m_total.y = numBPs + 1;
|
||||
m_total.x = tableBreaks[ARRAY_LENGTH(tableBreaks) - 1];
|
||||
m_total.y = m_buffer.count() + 1;
|
||||
if (m_total.y < 10)
|
||||
m_total.y = 10;
|
||||
|
||||
// Draw
|
||||
debug_view_char *dest = m_viewdata;
|
||||
for (int row = 0; row < m_visible.y; row++)
|
||||
debug_view_char *dest = m_viewdata;
|
||||
astring linebuf;
|
||||
|
||||
// Header
|
||||
if (m_visible.y > 0)
|
||||
{
|
||||
UINT32 effrow = m_topleft.y + row;
|
||||
linebuf.reset();
|
||||
linebuf.cat("ID");
|
||||
if (m_sortType == &cIndexAscending) linebuf.cat('\\');
|
||||
else if (m_sortType == &cIndexDescending) linebuf.cat('/');
|
||||
pad_astring_to_length(linebuf, tableBreaks[0]);
|
||||
linebuf.cat("En");
|
||||
if (m_sortType == &cEnabledAscending) linebuf.cat('\\');
|
||||
else if (m_sortType == &cEnabledDescending) linebuf.cat('/');
|
||||
pad_astring_to_length(linebuf, tableBreaks[1]);
|
||||
linebuf.cat("CPU");
|
||||
if (m_sortType == &cCpuAscending) linebuf.cat('\\');
|
||||
else if (m_sortType == &cCpuDescending) linebuf.cat('/');
|
||||
pad_astring_to_length(linebuf, tableBreaks[2]);
|
||||
linebuf.cat("Address");
|
||||
if (m_sortType == &cAddressAscending) linebuf.cat('\\');
|
||||
else if (m_sortType == &cAddressDescending) linebuf.cat('/');
|
||||
pad_astring_to_length(linebuf, tableBreaks[3]);
|
||||
linebuf.cat("Condition");
|
||||
if (m_sortType == &cConditionAscending) linebuf.cat('\\');
|
||||
else if (m_sortType == &cConditionDescending) linebuf.cat('/');
|
||||
pad_astring_to_length(linebuf, tableBreaks[4]);
|
||||
linebuf.cat("Action");
|
||||
if (m_sortType == &cActionAscending) linebuf.cat('\\');
|
||||
else if (m_sortType == &cActionDescending) linebuf.cat('/');
|
||||
pad_astring_to_length(linebuf, tableBreaks[5]);
|
||||
|
||||
// Header
|
||||
if (row == 0)
|
||||
for (UINT32 i = m_topleft.x; i < (m_topleft.x + m_visible.x); i++, dest++)
|
||||
{
|
||||
astring header;
|
||||
header.printf("ID");
|
||||
if (m_sortType == SORT_INDEX_ASCENDING) header.catprintf("\\");
|
||||
else if (m_sortType == SORT_INDEX_DESCENDING) header.catprintf("/");
|
||||
pad_astring_to_length(header, tableBreaks[0]);
|
||||
header.catprintf("En");
|
||||
if (m_sortType == SORT_ENABLED_ASCENDING) header.catprintf("\\");
|
||||
else if (m_sortType == SORT_ENABLED_DESCENDING) header.catprintf("/");
|
||||
pad_astring_to_length(header, tableBreaks[1]);
|
||||
header.catprintf("CPU");
|
||||
if (m_sortType == SORT_CPU_ASCENDING) header.catprintf("\\");
|
||||
else if (m_sortType == SORT_CPU_DESCENDING) header.catprintf("/");
|
||||
pad_astring_to_length(header, tableBreaks[2]);
|
||||
header.catprintf("Address");
|
||||
if (m_sortType == SORT_ADDRESS_ASCENDING) header.catprintf("\\");
|
||||
else if (m_sortType == SORT_ADDRESS_DESCENDING) header.catprintf("/");
|
||||
pad_astring_to_length(header, tableBreaks[3]);
|
||||
header.catprintf("Condition");
|
||||
if (m_sortType == SORT_CONDITION_ASCENDING) header.catprintf("\\");
|
||||
else if (m_sortType == SORT_CONDITION_DESCENDING) header.catprintf("/");
|
||||
pad_astring_to_length(header, tableBreaks[4]);
|
||||
header.catprintf("Action");
|
||||
if (m_sortType == SORT_ACTION_ASCENDING) header.catprintf("\\");
|
||||
else if (m_sortType == SORT_ACTION_DESCENDING) header.catprintf("/");
|
||||
pad_astring_to_length(header, tableBreaks[5]);
|
||||
|
||||
for (int i = 0; i < m_visible.x; i++)
|
||||
{
|
||||
dest->byte = (i < header.len()) ? header[i] : ' ';
|
||||
dest->attrib = DCA_ANCILLARY;
|
||||
dest++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// Breakpoints
|
||||
int bpi = effrow-1;
|
||||
if (bpi < numBPs && bpi >= 0)
|
||||
{
|
||||
device_debug::breakpoint* bp = bpList[bpi];
|
||||
|
||||
astring buffer;
|
||||
buffer.printf("%X", bp->index());
|
||||
pad_astring_to_length(buffer, tableBreaks[0]);
|
||||
buffer.catprintf("%c", bp->enabled() ? 'X' : 'O');
|
||||
pad_astring_to_length(buffer, tableBreaks[1]);
|
||||
buffer.catprintf("%s", bp->debugInterface()->device().tag());
|
||||
pad_astring_to_length(buffer, tableBreaks[2]);
|
||||
buffer.catprintf("%s", core_i64_hex_format(bp->address(), bp->debugInterface()->logaddrchars()));
|
||||
pad_astring_to_length(buffer, tableBreaks[3]);
|
||||
if (astring(bp->condition()) != astring("1"))
|
||||
{
|
||||
buffer.catprintf("%s", bp->condition());
|
||||
pad_astring_to_length(buffer, tableBreaks[4]);
|
||||
}
|
||||
if (astring(bp->action()) != astring(""))
|
||||
{
|
||||
buffer.catprintf("%s", bp->action());
|
||||
pad_astring_to_length(buffer, tableBreaks[5]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < m_visible.x; i++)
|
||||
{
|
||||
dest->byte = (i < buffer.len()) ? buffer[i] : ' ';
|
||||
dest->attrib = DCA_NORMAL;
|
||||
|
||||
// Color disabled breakpoints red
|
||||
if (i == 5 && dest->byte == 'O')
|
||||
dest->attrib = DCA_CHANGED;
|
||||
|
||||
dest++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// Fill the remaining vertical space
|
||||
for (int i = 0; i < m_visible.x; i++)
|
||||
{
|
||||
dest->byte = ' ';
|
||||
dest->attrib = DCA_NORMAL;
|
||||
dest++;
|
||||
dest->byte = (i < linebuf.len()) ? linebuf[i] : ' ';
|
||||
dest->attrib = DCA_ANCILLARY;
|
||||
}
|
||||
}
|
||||
|
||||
delete[] bpList;
|
||||
for (int row = 1; row < m_visible.y; row++)
|
||||
{
|
||||
// Breakpoints
|
||||
int bpi = row + m_topleft.y - 1;
|
||||
if ((bpi < m_buffer.count()) && (bpi >= 0))
|
||||
{
|
||||
device_debug::breakpoint *const bp = m_buffer[bpi];
|
||||
|
||||
linebuf.reset();
|
||||
linebuf.catprintf("%2X", bp->index());
|
||||
pad_astring_to_length(linebuf, tableBreaks[0]);
|
||||
linebuf.cat(bp->enabled() ? 'X' : 'O');
|
||||
pad_astring_to_length(linebuf, tableBreaks[1]);
|
||||
linebuf.cat(bp->debugInterface()->device().tag());
|
||||
pad_astring_to_length(linebuf, tableBreaks[2]);
|
||||
linebuf.cat(core_i64_hex_format(bp->address(), bp->debugInterface()->logaddrchars()));
|
||||
pad_astring_to_length(linebuf, tableBreaks[3]);
|
||||
if (strcmp(bp->condition(), "1"))
|
||||
linebuf.cat(bp->condition());
|
||||
pad_astring_to_length(linebuf, tableBreaks[4]);
|
||||
linebuf.cat(bp->action());
|
||||
pad_astring_to_length(linebuf, tableBreaks[5]);
|
||||
|
||||
for (UINT32 i = m_topleft.x; i < (m_topleft.x + m_visible.x); i++, dest++)
|
||||
{
|
||||
dest->byte = (i < linebuf.len()) ? linebuf[i] : ' ';
|
||||
dest->attrib = DCA_NORMAL;
|
||||
|
||||
// Color disabled breakpoints red
|
||||
if ((i >= tableBreaks[0]) && (i < tableBreaks[1]) && !bp->enabled())
|
||||
dest->attrib |= DCA_CHANGED;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fill the remaining vertical space
|
||||
for (UINT32 i = m_topleft.x; i < (m_topleft.x + m_visible.x); i++, dest++)
|
||||
{
|
||||
dest->byte = ' ';
|
||||
dest->attrib = DCA_NORMAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -35,23 +35,6 @@ class debug_view_breakpoints : public debug_view
|
||||
virtual ~debug_view_breakpoints();
|
||||
|
||||
public:
|
||||
enum SortMode
|
||||
{
|
||||
SORT_NONE,
|
||||
SORT_INDEX_ASCENDING,
|
||||
SORT_INDEX_DESCENDING,
|
||||
SORT_ENABLED_ASCENDING,
|
||||
SORT_ENABLED_DESCENDING,
|
||||
SORT_CPU_ASCENDING,
|
||||
SORT_CPU_DESCENDING,
|
||||
SORT_ADDRESS_ASCENDING,
|
||||
SORT_ADDRESS_DESCENDING,
|
||||
SORT_CONDITION_ASCENDING,
|
||||
SORT_CONDITION_DESCENDING,
|
||||
SORT_ACTION_ASCENDING,
|
||||
SORT_ACTION_DESCENDING
|
||||
};
|
||||
|
||||
// getters
|
||||
// setters
|
||||
|
||||
@ -64,11 +47,12 @@ private:
|
||||
// internal helpers
|
||||
void enumerate_sources();
|
||||
void pad_astring_to_length(astring& str, int len);
|
||||
int breakpoints(SortMode sort, device_debug::breakpoint**& bpList);
|
||||
void gather_breakpoints();
|
||||
|
||||
|
||||
// internal state
|
||||
SortMode m_sortType;
|
||||
int (*m_sortType)(void const *, void const *);
|
||||
dynamic_array<device_debug::breakpoint *> m_buffer;
|
||||
};
|
||||
|
||||
|
||||
|
@ -13,6 +13,103 @@
|
||||
|
||||
|
||||
|
||||
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
|
||||
//**************************************************************************
|
||||
@ -25,7 +122,7 @@ static const int tableBreaks[] = { 5, 9, 31, 42, 60, 67, 86, 100 };
|
||||
|
||||
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(SORT_INDEX_ASCENDING)
|
||||
m_sortType(&cIndexAscending)
|
||||
{
|
||||
// fail if no available sources
|
||||
enumerate_sources();
|
||||
@ -74,60 +171,38 @@ void debug_view_watchpoints::enumerate_sources()
|
||||
|
||||
void debug_view_watchpoints::view_click(const int button, const debug_view_xy& pos)
|
||||
{
|
||||
bool clickedTopRow = (m_topleft.y == pos.y);
|
||||
bool const clickedTopRow = (m_topleft.y == pos.y);
|
||||
|
||||
if (clickedTopRow)
|
||||
{
|
||||
if (pos.x < tableBreaks[0] && m_sortType == SORT_INDEX_ASCENDING)
|
||||
m_sortType = SORT_INDEX_DESCENDING;
|
||||
else if (pos.x < tableBreaks[0])
|
||||
m_sortType = SORT_INDEX_ASCENDING;
|
||||
else if (pos.x < tableBreaks[1] && m_sortType == SORT_ENABLED_ASCENDING)
|
||||
m_sortType = SORT_ENABLED_DESCENDING;
|
||||
if (pos.x < tableBreaks[0])
|
||||
m_sortType = (m_sortType == &cIndexAscending) ? &cIndexDescending : &cIndexAscending;
|
||||
else if (pos.x < tableBreaks[1])
|
||||
m_sortType = SORT_ENABLED_ASCENDING;
|
||||
else if (pos.x < tableBreaks[2] && m_sortType == SORT_CPU_ASCENDING)
|
||||
m_sortType = SORT_CPU_DESCENDING;
|
||||
m_sortType = (m_sortType == &cEnabledAscending) ? &cEnabledDescending : &cEnabledAscending;
|
||||
else if (pos.x < tableBreaks[2])
|
||||
m_sortType = SORT_CPU_ASCENDING;
|
||||
else if (pos.x < tableBreaks[3] && m_sortType == SORT_SPACE_ASCENDING)
|
||||
m_sortType = SORT_SPACE_DESCENDING;
|
||||
m_sortType = (m_sortType == &cCpuAscending) ? &cCpuDescending : &cCpuAscending;
|
||||
else if (pos.x < tableBreaks[3])
|
||||
m_sortType = SORT_SPACE_ASCENDING;
|
||||
else if (pos.x < tableBreaks[4] && m_sortType == SORT_ADDRESS_ASCENDING)
|
||||
m_sortType = SORT_ADDRESS_DESCENDING;
|
||||
m_sortType = (m_sortType == &cSpaceAscending) ? &cSpaceDescending : &cSpaceAscending;
|
||||
else if (pos.x < tableBreaks[4])
|
||||
m_sortType = SORT_ADDRESS_ASCENDING;
|
||||
else if (pos.x < tableBreaks[5] && m_sortType == SORT_TYPE_ASCENDING)
|
||||
m_sortType = SORT_TYPE_DESCENDING;
|
||||
m_sortType = (m_sortType == &cAddressAscending) ? &cAddressDescending : &cAddressAscending;
|
||||
else if (pos.x < tableBreaks[5])
|
||||
m_sortType = SORT_TYPE_ASCENDING;
|
||||
else if (pos.x < tableBreaks[6] && m_sortType == SORT_CONDITION_ASCENDING)
|
||||
m_sortType = SORT_CONDITION_DESCENDING;
|
||||
m_sortType = (m_sortType == &cTypeAscending) ? &cTypeDescending : &cTypeAscending;
|
||||
else if (pos.x < tableBreaks[6])
|
||||
m_sortType = SORT_CONDITION_ASCENDING;
|
||||
else if (pos.x < tableBreaks[7] && m_sortType == SORT_ACTION_ASCENDING)
|
||||
m_sortType = SORT_ACTION_DESCENDING;
|
||||
m_sortType = (m_sortType == &cConditionAscending) ? &cConditionDescending : &cConditionAscending;
|
||||
else if (pos.x < tableBreaks[7])
|
||||
m_sortType = SORT_ACTION_ASCENDING;
|
||||
m_sortType = (m_sortType == &cActionAscending) ? &cActionDescending : &cActionAscending;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Gather a sorted list of all the watchpoints for all the CPUs
|
||||
device_debug::watchpoint** wpList = NULL;
|
||||
const int numWPs = watchpoints(SORT_NONE, wpList);
|
||||
gather_watchpoints();
|
||||
|
||||
const int wpIndex = pos.y - 1;
|
||||
if (wpIndex > numWPs || wpIndex < 0)
|
||||
int const wpIndex = pos.y - 1;
|
||||
if ((wpIndex >= m_buffer.count()) || (wpIndex < 0))
|
||||
return;
|
||||
|
||||
// Enable / disable
|
||||
if (wpList[wpIndex]->enabled())
|
||||
wpList[wpIndex]->setEnabled(false);
|
||||
else
|
||||
wpList[wpIndex]->setEnabled(true);
|
||||
|
||||
delete[] wpList;
|
||||
m_buffer[wpIndex]->setEnabled(!m_buffer[wpIndex]->enabled());
|
||||
}
|
||||
|
||||
begin_update();
|
||||
@ -150,216 +225,22 @@ void debug_view_watchpoints::pad_astring_to_length(astring& str, int len)
|
||||
}
|
||||
|
||||
|
||||
// Sorting functors for the qsort function
|
||||
static int cIndexAscending(const void* a, const void* b)
|
||||
void debug_view_watchpoints::gather_watchpoints()
|
||||
{
|
||||
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)
|
||||
{
|
||||
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 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() < right->enabled();
|
||||
}
|
||||
|
||||
static int cEnabledDescending(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() > right->enabled();
|
||||
}
|
||||
|
||||
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;
|
||||
const int result = strcmp(left->debugInterface()->device().tag(), right->debugInterface()->device().tag());
|
||||
return result >= 0;
|
||||
}
|
||||
|
||||
static int cCpuDescending(const void* a, const void* b)
|
||||
{
|
||||
const device_debug::watchpoint* left = *(device_debug::watchpoint**)a;
|
||||
const device_debug::watchpoint* right = *(device_debug::watchpoint**)b;
|
||||
const int result = strcmp(left->debugInterface()->device().tag(), right->debugInterface()->device().tag());
|
||||
return result < 0;
|
||||
}
|
||||
|
||||
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;
|
||||
const int result = strcmp(left->space().name(), right->space().name());
|
||||
return result >= 0;
|
||||
}
|
||||
|
||||
static int cSpaceDescending(const void* a, const void* b)
|
||||
{
|
||||
const device_debug::watchpoint* left = *(device_debug::watchpoint**)a;
|
||||
const device_debug::watchpoint* right = *(device_debug::watchpoint**)b;
|
||||
const int result = strcmp(left->space().name(), right->space().name());
|
||||
return result < 0;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
static int cAddressDescending(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();
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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 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;
|
||||
const int result = strcmp(left->condition(), right->condition());
|
||||
return result >= 0;
|
||||
}
|
||||
|
||||
static int cConditionDescending(const void* a, const void* b)
|
||||
{
|
||||
const device_debug::watchpoint* left = *(device_debug::watchpoint**)a;
|
||||
const device_debug::watchpoint* right = *(device_debug::watchpoint**)b;
|
||||
const int result = strcmp(left->condition(), right->condition());
|
||||
return result < 0;
|
||||
}
|
||||
|
||||
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;
|
||||
const int result = strcmp(left->action(), right->action());
|
||||
return result >= 0;
|
||||
}
|
||||
|
||||
static int cActionDescending(const void* a, const void* b)
|
||||
{
|
||||
const device_debug::watchpoint* left = *(device_debug::watchpoint**)a;
|
||||
const device_debug::watchpoint* right = *(device_debug::watchpoint**)b;
|
||||
const int result = strcmp(left->action(), right->action());
|
||||
return result < 0;
|
||||
}
|
||||
|
||||
|
||||
int debug_view_watchpoints::watchpoints(SortMode sort, device_debug::watchpoint**& wpList)
|
||||
{
|
||||
// Alloc
|
||||
int numWPs = 0;
|
||||
wpList = NULL;
|
||||
for (const debug_view_source *source = m_source_list.first(); source != NULL; source = source->next())
|
||||
{
|
||||
for (address_spacenum spacenum = AS_0; spacenum < ADDRESS_SPACES; spacenum++)
|
||||
{
|
||||
/* loop over the watchpoints */
|
||||
const device_debug& debugInterface = *source->device()->debug();
|
||||
for (device_debug::watchpoint *wp = debugInterface.watchpoint_first(spacenum); wp != NULL; wp = wp->next())
|
||||
numWPs++;
|
||||
}
|
||||
}
|
||||
wpList = new device_debug::watchpoint*[numWPs];
|
||||
|
||||
int wpAddIndex = 0;
|
||||
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++)
|
||||
{
|
||||
device_debug& debugInterface = *source->device()->debug();
|
||||
for (device_debug::watchpoint *wp = debugInterface.watchpoint_first(spacenum); wp != NULL; wp = wp->next())
|
||||
{
|
||||
wpList[wpAddIndex] = wp;
|
||||
wpAddIndex++;
|
||||
}
|
||||
m_buffer.append() = wp;
|
||||
}
|
||||
}
|
||||
|
||||
// And now for the sort
|
||||
switch (m_sortType)
|
||||
{
|
||||
case SORT_NONE:
|
||||
break;
|
||||
case SORT_INDEX_ASCENDING:
|
||||
qsort(wpList, numWPs, sizeof(device_debug::watchpoint*), cIndexAscending);
|
||||
break;
|
||||
case SORT_INDEX_DESCENDING:
|
||||
qsort(wpList, numWPs, sizeof(device_debug::watchpoint*), cIndexDescending);
|
||||
break;
|
||||
case SORT_ENABLED_ASCENDING:
|
||||
qsort(wpList, numWPs, sizeof(device_debug::watchpoint*), cEnabledAscending);
|
||||
break;
|
||||
case SORT_ENABLED_DESCENDING:
|
||||
qsort(wpList, numWPs, sizeof(device_debug::watchpoint*), cEnabledDescending);
|
||||
break;
|
||||
case SORT_CPU_ASCENDING:
|
||||
qsort(wpList, numWPs, sizeof(device_debug::watchpoint*), cCpuAscending);
|
||||
break;
|
||||
case SORT_CPU_DESCENDING:
|
||||
qsort(wpList, numWPs, sizeof(device_debug::watchpoint*), cCpuDescending);
|
||||
break;
|
||||
case SORT_SPACE_ASCENDING:
|
||||
qsort(wpList, numWPs, sizeof(device_debug::watchpoint*), cSpaceAscending);
|
||||
break;
|
||||
case SORT_SPACE_DESCENDING:
|
||||
qsort(wpList, numWPs, sizeof(device_debug::watchpoint*), cSpaceDescending);
|
||||
break;
|
||||
case SORT_ADDRESS_ASCENDING:
|
||||
qsort(wpList, numWPs, sizeof(device_debug::watchpoint*), cAddressAscending);
|
||||
break;
|
||||
case SORT_ADDRESS_DESCENDING:
|
||||
qsort(wpList, numWPs, sizeof(device_debug::watchpoint*), cAddressDescending);
|
||||
break;
|
||||
case SORT_TYPE_ASCENDING:
|
||||
qsort(wpList, numWPs, sizeof(device_debug::watchpoint*), cTypeAscending);
|
||||
break;
|
||||
case SORT_TYPE_DESCENDING:
|
||||
qsort(wpList, numWPs, sizeof(device_debug::watchpoint*), cTypeDescending);
|
||||
break;
|
||||
case SORT_CONDITION_ASCENDING:
|
||||
qsort(wpList, numWPs, sizeof(device_debug::watchpoint*), cConditionAscending);
|
||||
break;
|
||||
case SORT_CONDITION_DESCENDING:
|
||||
qsort(wpList, numWPs, sizeof(device_debug::watchpoint*), cConditionDescending);
|
||||
break;
|
||||
case SORT_ACTION_ASCENDING:
|
||||
qsort(wpList, numWPs, sizeof(device_debug::watchpoint*), cActionAscending);
|
||||
break;
|
||||
case SORT_ACTION_DESCENDING:
|
||||
qsort(wpList, numWPs, sizeof(device_debug::watchpoint*), cActionDescending);
|
||||
break;
|
||||
}
|
||||
|
||||
return numWPs;
|
||||
qsort(&m_buffer[0], m_buffer.count(), sizeof(device_debug::watchpoint *), m_sortType);
|
||||
}
|
||||
|
||||
|
||||
@ -371,121 +252,110 @@ int debug_view_watchpoints::watchpoints(SortMode sort, device_debug::watchpoint*
|
||||
void debug_view_watchpoints::view_update()
|
||||
{
|
||||
// Gather a list of all the watchpoints for all the CPUs
|
||||
device_debug::watchpoint** wpList = NULL;
|
||||
const int numWPs = watchpoints(SORT_NONE, wpList);
|
||||
gather_watchpoints();
|
||||
|
||||
// Set the view region so the scroll bars update
|
||||
m_total.y = numWPs + 1;
|
||||
m_total.x = tableBreaks[ARRAY_LENGTH(tableBreaks) - 1];
|
||||
m_total.y = m_buffer.count() + 1;
|
||||
if (m_total.y < 10)
|
||||
m_total.y = 10;
|
||||
|
||||
// Draw
|
||||
debug_view_char *dest = m_viewdata;
|
||||
for (int row = 0; row < m_visible.y; row++)
|
||||
debug_view_char *dest = m_viewdata;
|
||||
astring linebuf;
|
||||
|
||||
// Header
|
||||
if (m_visible.y > 0)
|
||||
{
|
||||
UINT32 effrow = m_topleft.y + row;
|
||||
linebuf.reset();
|
||||
linebuf.cat("ID");
|
||||
if (m_sortType == &cIndexAscending) linebuf.cat('\\');
|
||||
else if (m_sortType == &cIndexDescending) linebuf.cat('/');
|
||||
pad_astring_to_length(linebuf, tableBreaks[0]);
|
||||
linebuf.cat("En");
|
||||
if (m_sortType == &cEnabledAscending) linebuf.cat('\\');
|
||||
else if (m_sortType == &cEnabledDescending) linebuf.cat('/');
|
||||
pad_astring_to_length(linebuf, tableBreaks[1]);
|
||||
linebuf.cat("CPU");
|
||||
if (m_sortType == &cCpuAscending) linebuf.cat('\\');
|
||||
else if (m_sortType == &cCpuDescending) linebuf.cat('/');
|
||||
pad_astring_to_length(linebuf, tableBreaks[2]);
|
||||
linebuf.cat("Space");
|
||||
if (m_sortType == &cSpaceAscending) linebuf.cat('\\');
|
||||
else if (m_sortType == &cSpaceDescending) linebuf.cat('/');
|
||||
pad_astring_to_length(linebuf, tableBreaks[3]);
|
||||
linebuf.cat("Addresses");
|
||||
if (m_sortType == &cAddressAscending) linebuf.cat('\\');
|
||||
else if (m_sortType == &cAddressDescending) linebuf.cat('/');
|
||||
pad_astring_to_length(linebuf, tableBreaks[4]);
|
||||
linebuf.cat("Type");
|
||||
if (m_sortType == &cTypeAscending) linebuf.cat('\\');
|
||||
else if (m_sortType == &cTypeDescending) linebuf.cat('/');
|
||||
pad_astring_to_length(linebuf, tableBreaks[5]);
|
||||
linebuf.cat("Condition");
|
||||
if (m_sortType == &cConditionAscending) linebuf.cat('\\');
|
||||
else if (m_sortType == &cConditionDescending) linebuf.cat('/');
|
||||
pad_astring_to_length(linebuf, tableBreaks[6]);
|
||||
linebuf.cat("Action");
|
||||
if (m_sortType == &cActionAscending) linebuf.cat('\\');
|
||||
else if (m_sortType == &cActionDescending) linebuf.cat('/');
|
||||
pad_astring_to_length(linebuf, tableBreaks[7]);
|
||||
|
||||
// Header
|
||||
if (row == 0)
|
||||
for (UINT32 i = m_topleft.x; i < (m_topleft.x + m_visible.x); i++, dest++)
|
||||
{
|
||||
astring header;
|
||||
header.printf("ID");
|
||||
if (m_sortType == SORT_INDEX_ASCENDING) header.catprintf("\\");
|
||||
else if (m_sortType == SORT_INDEX_DESCENDING) header.catprintf("/");
|
||||
pad_astring_to_length(header, tableBreaks[0]);
|
||||
header.catprintf("En");
|
||||
if (m_sortType == SORT_ENABLED_ASCENDING) header.catprintf("\\");
|
||||
else if (m_sortType == SORT_ENABLED_DESCENDING) header.catprintf("/");
|
||||
pad_astring_to_length(header, tableBreaks[1]);
|
||||
header.catprintf("CPU");
|
||||
if (m_sortType == SORT_CPU_ASCENDING) header.catprintf("\\");
|
||||
else if (m_sortType == SORT_CPU_DESCENDING) header.catprintf("/");
|
||||
pad_astring_to_length(header, tableBreaks[2]);
|
||||
header.catprintf("Space");
|
||||
if (m_sortType == SORT_SPACE_ASCENDING) header.catprintf("\\");
|
||||
else if (m_sortType == SORT_SPACE_DESCENDING) header.catprintf("/");
|
||||
pad_astring_to_length(header, tableBreaks[3]);
|
||||
header.catprintf("Addresses");
|
||||
if (m_sortType == SORT_ADDRESS_ASCENDING) header.catprintf("\\");
|
||||
else if (m_sortType == SORT_ADDRESS_DESCENDING) header.catprintf("/");
|
||||
pad_astring_to_length(header, tableBreaks[4]);
|
||||
header.catprintf("Type");
|
||||
if (m_sortType == SORT_TYPE_ASCENDING) header.catprintf("\\");
|
||||
else if (m_sortType == SORT_TYPE_DESCENDING) header.catprintf("/");
|
||||
pad_astring_to_length(header, tableBreaks[5]);
|
||||
header.catprintf("Condition");
|
||||
if (m_sortType == SORT_CONDITION_ASCENDING) header.catprintf("\\");
|
||||
else if (m_sortType == SORT_CONDITION_DESCENDING) header.catprintf("/");
|
||||
pad_astring_to_length(header, tableBreaks[6]);
|
||||
header.catprintf("Action");
|
||||
if (m_sortType == SORT_ACTION_ASCENDING) header.catprintf("\\");
|
||||
else if (m_sortType == SORT_ACTION_DESCENDING) header.catprintf("/");
|
||||
pad_astring_to_length(header, tableBreaks[7]);
|
||||
|
||||
for (int i = 0; i < m_visible.x; i++)
|
||||
{
|
||||
dest->byte = (i < header.len()) ? header[i] : ' ';
|
||||
dest->attrib = DCA_ANCILLARY;
|
||||
dest++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// watchpoints
|
||||
int wpi = effrow-1;
|
||||
if (wpi < numWPs && wpi >= 0)
|
||||
{
|
||||
static const char *const types[] = { "unkn ", "read ", "write", "r/w " };
|
||||
device_debug::watchpoint* wp = wpList[wpi];
|
||||
|
||||
astring buffer;
|
||||
buffer.printf("%X", wp->index());
|
||||
pad_astring_to_length(buffer, tableBreaks[0]);
|
||||
buffer.catprintf("%c", wp->enabled() ? 'X' : 'O');
|
||||
pad_astring_to_length(buffer, tableBreaks[1]);
|
||||
buffer.catprintf("%s", wp->debugInterface()->device().tag());
|
||||
pad_astring_to_length(buffer, tableBreaks[2]);
|
||||
buffer.catprintf("%s", wp->space().name());
|
||||
pad_astring_to_length(buffer, tableBreaks[3]);
|
||||
buffer.catprintf("%s-%s",
|
||||
core_i64_hex_format(wp->space().byte_to_address(wp->address()), wp->space().addrchars()),
|
||||
core_i64_hex_format(wp->space().byte_to_address_end(wp->address() + wp->length()) - 1, wp->space().addrchars()));
|
||||
pad_astring_to_length(buffer, tableBreaks[4]);
|
||||
buffer.catprintf("%s", types[wp->type() & 3]);
|
||||
pad_astring_to_length(buffer, tableBreaks[5]);
|
||||
if (astring(wp->condition()) != astring("1"))
|
||||
{
|
||||
buffer.catprintf("%s", wp->condition());
|
||||
pad_astring_to_length(buffer, tableBreaks[6]);
|
||||
}
|
||||
if (astring(wp->action()) != astring(""))
|
||||
{
|
||||
buffer.catprintf("%s", wp->action());
|
||||
pad_astring_to_length(buffer, tableBreaks[7]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < m_visible.x; i++)
|
||||
{
|
||||
dest->byte = (i < buffer.len()) ? buffer[i] : ' ';
|
||||
dest->attrib = DCA_NORMAL;
|
||||
|
||||
// Color disabled watchpoints red
|
||||
if (i == 5 && dest->byte == 'O')
|
||||
dest->attrib = DCA_CHANGED;
|
||||
|
||||
dest++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// Fill the remaining vertical space
|
||||
for (int i = 0; i < m_visible.x; i++)
|
||||
{
|
||||
dest->byte = ' ';
|
||||
dest->attrib = DCA_NORMAL;
|
||||
dest++;
|
||||
dest->byte = (i < linebuf.len()) ? linebuf[i] : ' ';
|
||||
dest->attrib = DCA_ANCILLARY;
|
||||
}
|
||||
}
|
||||
|
||||
delete[] wpList;
|
||||
for (int row = 1; row < m_visible.y; row++)
|
||||
{
|
||||
// watchpoints
|
||||
int const wpi = row + m_topleft.y - 1;
|
||||
if ((wpi < m_buffer.count()) && wpi >= 0)
|
||||
{
|
||||
static char const *const types[] = { "unkn ", "read ", "write", "r/w " };
|
||||
device_debug::watchpoint *const wp = m_buffer[wpi];
|
||||
|
||||
linebuf.reset();
|
||||
linebuf.catprintf("%2X", wp->index());
|
||||
pad_astring_to_length(linebuf, tableBreaks[0]);
|
||||
linebuf.cat(wp->enabled() ? 'X' : 'O');
|
||||
pad_astring_to_length(linebuf, tableBreaks[1]);
|
||||
linebuf.cat(wp->debugInterface()->device().tag());
|
||||
pad_astring_to_length(linebuf, tableBreaks[2]);
|
||||
linebuf.cat(wp->space().name());
|
||||
pad_astring_to_length(linebuf, tableBreaks[3]);
|
||||
linebuf.cat(core_i64_hex_format(wp->space().byte_to_address(wp->address()), wp->space().addrchars()));
|
||||
linebuf.cat('-');
|
||||
linebuf.cat(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.cat(types[wp->type() & 3]);
|
||||
pad_astring_to_length(linebuf, tableBreaks[5]);
|
||||
if (strcmp(wp->condition(), "1"))
|
||||
linebuf.cat(wp->condition());
|
||||
pad_astring_to_length(linebuf, tableBreaks[6]);
|
||||
linebuf.cat(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.len()) ? 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -34,31 +34,6 @@ class debug_view_watchpoints : public debug_view
|
||||
debug_view_watchpoints(running_machine &machine, debug_view_osd_update_func osdupdate, void *osdprivate);
|
||||
virtual ~debug_view_watchpoints();
|
||||
|
||||
public:
|
||||
enum SortMode
|
||||
{
|
||||
SORT_NONE,
|
||||
SORT_INDEX_ASCENDING,
|
||||
SORT_INDEX_DESCENDING,
|
||||
SORT_ENABLED_ASCENDING,
|
||||
SORT_ENABLED_DESCENDING,
|
||||
SORT_CPU_ASCENDING,
|
||||
SORT_CPU_DESCENDING,
|
||||
SORT_SPACE_ASCENDING,
|
||||
SORT_SPACE_DESCENDING,
|
||||
SORT_ADDRESS_ASCENDING,
|
||||
SORT_ADDRESS_DESCENDING,
|
||||
SORT_TYPE_ASCENDING,
|
||||
SORT_TYPE_DESCENDING,
|
||||
SORT_CONDITION_ASCENDING,
|
||||
SORT_CONDITION_DESCENDING,
|
||||
SORT_ACTION_ASCENDING,
|
||||
SORT_ACTION_DESCENDING
|
||||
};
|
||||
|
||||
// getters
|
||||
// setters
|
||||
|
||||
protected:
|
||||
// view overrides
|
||||
virtual void view_update();
|
||||
@ -68,11 +43,12 @@ private:
|
||||
// internal helpers
|
||||
void enumerate_sources();
|
||||
void pad_astring_to_length(astring& str, int len);
|
||||
int watchpoints(SortMode sort, device_debug::watchpoint**& bpList);
|
||||
void gather_watchpoints();
|
||||
|
||||
|
||||
// internal state
|
||||
SortMode m_sortType;
|
||||
int (*m_sortType)(void const *, void const *);
|
||||
dynamic_array<device_debug::watchpoint *> m_buffer;
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user