mirror of
https://github.com/holub/mame
synced 2025-07-04 17:38:08 +03:00
QT Debugger: Finished up the breakpoints window. [Andrew Gardner]
It now shows breakpoints for all CPUs and lets you sort by each field.
This commit is contained in:
parent
0ee305fd61
commit
e74983f6f8
@ -2303,7 +2303,7 @@ void device_debug::halt_on_next_instruction(const char *fmt, ...)
|
||||
int device_debug::breakpoint_set(offs_t address, const char *condition, const char *action)
|
||||
{
|
||||
// allocate a new one
|
||||
breakpoint *bp = auto_alloc(m_device.machine(), breakpoint(m_symtable, m_device.machine().debugcpu_data->bpindex++, address, condition, action));
|
||||
breakpoint *bp = auto_alloc(m_device.machine(), breakpoint(this, m_symtable, m_device.machine().debugcpu_data->bpindex++, address, condition, action));
|
||||
|
||||
// hook it into our list
|
||||
bp->m_next = m_bplist;
|
||||
@ -3278,8 +3278,14 @@ void device_debug::set_state(symbol_table &table, void *ref, UINT64 value)
|
||||
// breakpoint - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
device_debug::breakpoint::breakpoint(symbol_table &symbols, int index, offs_t address, const char *condition, const char *action)
|
||||
: m_next(NULL),
|
||||
device_debug::breakpoint::breakpoint(device_debug* debugInterface,
|
||||
symbol_table &symbols,
|
||||
int index,
|
||||
offs_t address,
|
||||
const char *condition,
|
||||
const char *action)
|
||||
: m_debugInterface(debugInterface),
|
||||
m_next(NULL),
|
||||
m_index(index),
|
||||
m_enabled(true),
|
||||
m_address(address),
|
||||
|
@ -79,9 +79,15 @@ public:
|
||||
|
||||
public:
|
||||
// construction/destruction
|
||||
breakpoint(symbol_table &symbols, int index, offs_t address, const char *condition = NULL, const char *action = NULL);
|
||||
breakpoint(device_debug* debugInterface,
|
||||
symbol_table &symbols,
|
||||
int index,
|
||||
offs_t address,
|
||||
const char *condition = NULL,
|
||||
const char *action = NULL);
|
||||
|
||||
// getters
|
||||
const device_debug *debugInterface() const { return m_debugInterface; }
|
||||
breakpoint *next() const { return m_next; }
|
||||
int index() const { return m_index; }
|
||||
bool enabled() const { return m_enabled; }
|
||||
@ -89,10 +95,14 @@ public:
|
||||
const char *condition() const { return m_condition.original_string(); }
|
||||
const char *action() const { return m_action; }
|
||||
|
||||
// setters
|
||||
void setEnabled(bool value) { m_enabled = value; }
|
||||
|
||||
private:
|
||||
// internals
|
||||
bool hit(offs_t pc);
|
||||
|
||||
const device_debug * m_debugInterface; // the interface we were created from
|
||||
breakpoint * m_next; // next in the list
|
||||
int m_index; // user reported index
|
||||
UINT8 m_enabled; // enabled?
|
||||
@ -108,7 +118,14 @@ public:
|
||||
|
||||
public:
|
||||
// construction/destruction
|
||||
watchpoint(symbol_table &symbols, int index, address_space &space, int type, offs_t address, offs_t length, const char *condition = NULL, const char *action = NULL);
|
||||
watchpoint(symbol_table &symbols,
|
||||
int index,
|
||||
address_space &space,
|
||||
int type,
|
||||
offs_t address,
|
||||
offs_t length,
|
||||
const char *condition = NULL,
|
||||
const char *action = NULL);
|
||||
|
||||
// getters
|
||||
watchpoint *next() const { return m_next; }
|
||||
@ -176,6 +193,8 @@ public:
|
||||
int logaddrchars(address_spacenum spacenum = AS_0) const { return (m_memory != NULL && m_memory->has_space(spacenum)) ? m_memory->space(spacenum).logaddrchars() : 8; }
|
||||
int min_opcode_bytes() const { return (m_disasm != NULL) ? m_disasm->max_opcode_bytes() : 1; }
|
||||
int max_opcode_bytes() const { return (m_disasm != NULL) ? m_disasm->max_opcode_bytes() : 1; }
|
||||
device_t& device() const { return m_device; }
|
||||
|
||||
|
||||
// hooks used by the rest of the system
|
||||
void start_hook(attotime endtime);
|
||||
|
@ -38,9 +38,7 @@
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "debugvw.h"
|
||||
#include "dvbpoints.h"
|
||||
#include "debugcpu.h"
|
||||
|
||||
|
||||
|
||||
@ -53,7 +51,8 @@
|
||||
//-------------------------------------------------
|
||||
|
||||
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)
|
||||
: debug_view(machine, DVT_BREAK_POINTS, osdupdate, osdprivate),
|
||||
m_sortType(SORT_INDEX_ASCENDING)
|
||||
{
|
||||
// fail if no available sources
|
||||
enumerate_sources();
|
||||
@ -61,8 +60,8 @@ debug_view_breakpoints::debug_view_breakpoints(running_machine &machine, debug_v
|
||||
throw std::bad_alloc();
|
||||
|
||||
// configure the view
|
||||
m_total.y = 50; // TODO
|
||||
m_supports_cursor = true;
|
||||
m_total.y = 10;
|
||||
m_supports_cursor = false;
|
||||
}
|
||||
|
||||
|
||||
@ -126,6 +125,55 @@ void debug_view_breakpoints::view_char(int chval)
|
||||
|
||||
void debug_view_breakpoints::view_click(const int button, const debug_view_xy& pos)
|
||||
{
|
||||
bool clickedTopRow = (m_topleft.y == pos.y);
|
||||
|
||||
if (clickedTopRow)
|
||||
{
|
||||
if (pos.x < 5 && m_sortType == SORT_INDEX_ASCENDING)
|
||||
m_sortType = SORT_INDEX_DESCENDING;
|
||||
else if (pos.x < 5)
|
||||
m_sortType = SORT_INDEX_ASCENDING;
|
||||
else if (pos.x < 9 && m_sortType == SORT_ENABLED_ASCENDING)
|
||||
m_sortType = SORT_ENABLED_DESCENDING;
|
||||
else if (pos.x < 9)
|
||||
m_sortType = SORT_ENABLED_ASCENDING;
|
||||
else if (pos.x < 31 && m_sortType == SORT_CPU_ASCENDING)
|
||||
m_sortType = SORT_CPU_DESCENDING;
|
||||
else if (pos.x < 31)
|
||||
m_sortType = SORT_CPU_ASCENDING;
|
||||
else if (pos.x < 45 && m_sortType == SORT_ADDRESS_ASCENDING)
|
||||
m_sortType = SORT_ADDRESS_DESCENDING;
|
||||
else if (pos.x < 45)
|
||||
m_sortType = SORT_ADDRESS_ASCENDING;
|
||||
else if (pos.x < 63 && m_sortType == SORT_CONDITION_ASCENDING)
|
||||
m_sortType = SORT_CONDITION_DESCENDING;
|
||||
else if (pos.x < 63)
|
||||
m_sortType = SORT_CONDITION_ASCENDING;
|
||||
else if (pos.x < 80 && m_sortType == SORT_ACTION_ASCENDING)
|
||||
m_sortType = SORT_ACTION_DESCENDING;
|
||||
else if (pos.x < 80)
|
||||
m_sortType = SORT_ACTION_ASCENDING;
|
||||
}
|
||||
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);
|
||||
|
||||
const int bpIndex = pos.y-1;
|
||||
if (bpIndex > numBPs || bpIndex < 0)
|
||||
return;
|
||||
|
||||
// Enable / disable
|
||||
if (bpList[bpIndex]->enabled())
|
||||
bpList[bpIndex]->setEnabled(false);
|
||||
else
|
||||
bpList[bpIndex]->setEnabled(true);
|
||||
|
||||
delete[] bpList;
|
||||
}
|
||||
|
||||
view_update();
|
||||
}
|
||||
|
||||
|
||||
@ -142,6 +190,174 @@ void debug_view_breakpoints::pad_astring_to_length(astring& str, int len)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Sorting functors for the qsort function
|
||||
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();
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
int numBPs = 0;
|
||||
bpList = NULL;
|
||||
for (const debug_view_source *source = m_source_list.head(); source != NULL; source = source->next())
|
||||
{
|
||||
// Alloc
|
||||
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 = 1;
|
||||
for (const debug_view_source *source = m_source_list.head(); source != NULL; source = source->next())
|
||||
{
|
||||
device_debug& debugInterface = *source->device()->debug();
|
||||
if (debugInterface.breakpoint_first() != NULL)
|
||||
{
|
||||
// Collect
|
||||
for (device_debug::breakpoint *bp = debugInterface.breakpoint_first(); bp != NULL; bp = bp->next())
|
||||
{
|
||||
bpList[numBPs-bpAddIndex] = bp;
|
||||
bpAddIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// view_update - update the contents of the
|
||||
// disassembly view
|
||||
@ -149,38 +365,48 @@ void debug_view_breakpoints::pad_astring_to_length(astring& str, int len)
|
||||
|
||||
void debug_view_breakpoints::view_update()
|
||||
{
|
||||
const debug_view_source& source = *m_source;
|
||||
const device_debug& debugInterface = *source.device()->debug();
|
||||
debug_view_char *dest = m_viewdata;
|
||||
|
||||
// Gather a list of all the breakpoints in reverse order
|
||||
int numBPs = 0;
|
||||
// Gather a list of all the breakpoints for all the CPUs
|
||||
device_debug::breakpoint** bpList = NULL;
|
||||
if (debugInterface.breakpoint_first() != NULL)
|
||||
{
|
||||
// Alloc
|
||||
for (device_debug::breakpoint *bp = debugInterface.breakpoint_first(); bp != NULL; bp = bp->next())
|
||||
numBPs++;
|
||||
bpList = new device_debug::breakpoint*[numBPs];
|
||||
const int numBPs = breakpoints(SORT_NONE, bpList);
|
||||
|
||||
// Collect
|
||||
int i = 1;
|
||||
for (device_debug::breakpoint *bp = debugInterface.breakpoint_first(); bp != NULL; bp = bp->next())
|
||||
{
|
||||
bpList[numBPs-i] = bp;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
// Set the view region so the scroll bars update
|
||||
m_total.y = numBPs+1;
|
||||
|
||||
// Draw
|
||||
debug_view_char *dest = m_viewdata;
|
||||
for (int row = 0; row < m_visible.y; row++)
|
||||
{
|
||||
UINT32 effrow = m_topleft.y + row;
|
||||
|
||||
// Header
|
||||
if (effrow == 0)
|
||||
if (row == 0)
|
||||
{
|
||||
astring header = "ID En Address Condition Action";
|
||||
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, 5);
|
||||
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, 9);
|
||||
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, 31);
|
||||
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, 45);
|
||||
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, 63);
|
||||
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, 80);
|
||||
|
||||
for (int i = 0; i < m_visible.x; i++)
|
||||
{
|
||||
dest->byte = (i < header.len()) ? header[i] : ' ';
|
||||
@ -201,23 +427,30 @@ void debug_view_breakpoints::view_update()
|
||||
pad_astring_to_length(buffer, 5);
|
||||
buffer.catprintf("%c", bp->enabled() ? 'X' : 'O');
|
||||
pad_astring_to_length(buffer, 9);
|
||||
buffer.catprintf("%s", core_i64_hex_format(bp->address(), debugInterface.logaddrchars()));
|
||||
pad_astring_to_length(buffer, 26);
|
||||
buffer.catprintf("%s", bp->debugInterface()->device().tag());
|
||||
pad_astring_to_length(buffer, 31);
|
||||
buffer.catprintf("%s", core_i64_hex_format(bp->address(), bp->debugInterface()->logaddrchars()));
|
||||
pad_astring_to_length(buffer, 45);
|
||||
if (astring(bp->condition()) != astring("1"))
|
||||
{
|
||||
buffer.catprintf("%s", bp->condition());
|
||||
pad_astring_to_length(buffer, 44);
|
||||
pad_astring_to_length(buffer, 63);
|
||||
}
|
||||
if (astring(bp->action()) != astring(""))
|
||||
{
|
||||
buffer.catprintf("%s", bp->action());
|
||||
pad_astring_to_length(buffer, 60);
|
||||
pad_astring_to_length(buffer, 80);
|
||||
}
|
||||
|
||||
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;
|
||||
@ -232,5 +465,5 @@ void debug_view_breakpoints::view_update()
|
||||
}
|
||||
}
|
||||
|
||||
delete bpList;
|
||||
delete[] bpList;
|
||||
}
|
||||
|
@ -41,6 +41,7 @@
|
||||
#define __DVBPOINTS_H__
|
||||
|
||||
#include "debugvw.h"
|
||||
#include "debugcpu.h"
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
@ -63,6 +64,23 @@ 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
|
||||
|
||||
@ -78,8 +96,11 @@ private:
|
||||
void enumerate_sources();
|
||||
bool recompute(offs_t pc, int startline, int lines);
|
||||
void pad_astring_to_length(astring& str, int len);
|
||||
int breakpoints(SortMode sort, device_debug::breakpoint**& bpList);
|
||||
|
||||
|
||||
// internal state
|
||||
SortMode m_sortType;
|
||||
};
|
||||
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
BreakpointsWindow::BreakpointsWindow(running_machine* machine, QWidget* parent) :
|
||||
WindowQt(machine, NULL)
|
||||
{
|
||||
setWindowTitle("Debug: Machine Breakpoints");
|
||||
setWindowTitle("Debug: All Breakpoints");
|
||||
|
||||
if (parent != NULL)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user