diff --git a/src/emu/debug/debugcpu.c b/src/emu/debug/debugcpu.c index 4101a0307a4..a7e9f2f4272 100644 --- a/src/emu/debug/debugcpu.c +++ b/src/emu/debug/debugcpu.c @@ -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,13 +3278,19 @@ 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), - m_index(index), - m_enabled(true), - m_address(address), - m_condition(&symbols, (condition != NULL) ? condition : "1"), - m_action((action != NULL) ? action : "") +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), + m_condition(&symbols, (condition != NULL) ? condition : "1"), + m_action((action != NULL) ? action : "") { } diff --git a/src/emu/debug/debugcpu.h b/src/emu/debug/debugcpu.h index 97da6ede8e6..0d69afb951a 100644 --- a/src/emu/debug/debugcpu.h +++ b/src/emu/debug/debugcpu.h @@ -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,16 +95,20 @@ 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); - breakpoint * m_next; // next in the list - int m_index; // user reported index - UINT8 m_enabled; // enabled? - offs_t m_address; // execution address - parsed_expression m_condition; // condition - astring m_action; // action + 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? + offs_t m_address; // execution address + parsed_expression m_condition; // condition + astring m_action; // action }; // watchpoint class @@ -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); diff --git a/src/emu/debug/dvbpoints.c b/src/emu/debug/dvbpoints.c index 99094a11d4c..990e5974155 100644 --- a/src/emu/debug/dvbpoints.c +++ b/src/emu/debug/dvbpoints.c @@ -2,7 +2,7 @@ dvpoints.c - Breakpoint debugger view. + Breakpoint debugger view. **************************************************************************** @@ -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]; - - // Collect - int i = 1; - for (device_debug::breakpoint *bp = debugInterface.breakpoint_first(); bp != NULL; bp = bp->next()) - { - bpList[numBPs-i] = bp; - i++; - } - } + const int numBPs = breakpoints(SORT_NONE, bpList); + + // 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] : ' '; @@ -195,34 +421,41 @@ void debug_view_breakpoints::view_update() if (bpi < numBPs && bpi >= 0) { device_debug::breakpoint* bp = bpList[bpi]; - - astring buffer; + + astring buffer; buffer.printf("%x", bp->index()); 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; } - + // Fill the remaining vertical space for (int i = 0; i < m_visible.x; i++) { @@ -231,6 +464,6 @@ void debug_view_breakpoints::view_update() dest++; } } - - delete bpList; + + delete[] bpList; } diff --git a/src/emu/debug/dvbpoints.h b/src/emu/debug/dvbpoints.h index be57027c186..d20e03fa49a 100644 --- a/src/emu/debug/dvbpoints.h +++ b/src/emu/debug/dvbpoints.h @@ -2,7 +2,7 @@ dvpoints.h - Breakpoint debugger view. + Breakpoint debugger view. **************************************************************************** @@ -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; }; diff --git a/src/osd/sdl/debugqtbreakpointswindow.c b/src/osd/sdl/debugqtbreakpointswindow.c index 623958da098..9ee84dbd6c5 100644 --- a/src/osd/sdl/debugqtbreakpointswindow.c +++ b/src/osd/sdl/debugqtbreakpointswindow.c @@ -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) {