Fixed the build.

This commit is contained in:
Andrew Gardner 2013-07-26 03:40:55 +00:00
parent 416c9d0190
commit 6ab38a50ef
3 changed files with 653 additions and 0 deletions

2
.gitattributes vendored
View File

@ -989,6 +989,8 @@ src/emu/debug/dvstate.c svneol=native#text/plain
src/emu/debug/dvstate.h svneol=native#text/plain
src/emu/debug/dvtext.c svneol=native#text/plain
src/emu/debug/dvtext.h svneol=native#text/plain
src/emu/debug/dvwpoints.c svneol=native#text/plain
src/emu/debug/dvwpoints.h svneol=native#text/plain
src/emu/debug/express.c svneol=native#text/plain
src/emu/debug/express.h svneol=native#text/plain
src/emu/debug/textbuf.c svneol=native#text/plain

540
src/emu/debug/dvwpoints.c Normal file
View File

@ -0,0 +1,540 @@
/*********************************************************************
dvwpoints.c
Watchpoint debugger view.
****************************************************************************
Copyright Aaron Giles
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name 'MAME' nor the names of its contributors may be
used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
***************************************************************************/
#include "emu.h"
#include "dvwpoints.h"
//**************************************************************************
// 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(SORT_INDEX_ASCENDING)
{
// fail if no available sources
enumerate_sources();
if (m_source_list.count() == 0)
throw std::bad_alloc();
// configure the view
m_total.y = 10;
m_supports_cursor = false;
}
//-------------------------------------------------
// ~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())
{
astring name;
name.printf("%s '%s'", dasm->device().name(), dasm->device().tag());
m_source_list.append(*auto_alloc(machine(), debug_view_source(name.cstr(), &dasm->device())));
}
// reset the source to a known good entry
set_source(*m_source_list.head());
}
//-------------------------------------------------
// view_notify - handle notification of updates
// to cursor changes
//-------------------------------------------------
void debug_view_watchpoints::view_notify(debug_view_notification type)
{
}
//-------------------------------------------------
// view_char - handle a character typed within
// the current view
//-------------------------------------------------
void debug_view_watchpoints::view_char(int chval)
{
}
//-------------------------------------------------
// 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 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;
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;
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;
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;
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;
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;
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;
else if (pos.x < tableBreaks[7])
m_sortType = SORT_ACTION_ASCENDING;
}
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);
const int wpIndex = pos.y-1;
if (wpIndex > numWPs || wpIndex < 0)
return;
// Enable / disable
if (wpList[wpIndex]->enabled())
wpList[wpIndex]->setEnabled(false);
else
wpList[wpIndex]->setEnabled(true);
delete[] wpList;
}
view_update();
}
void debug_view_watchpoints::pad_astring_to_length(astring& str, int len)
{
int diff = len - str.len();
if (diff > 0)
{
astring buffer;
buffer.expand(diff);
for (int i = 0; i < diff; i++)
buffer.catprintf(" ");
str.catprintf("%s", buffer.cstr());
}
}
// Sorting functors for the qsort function
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)
{
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.head(); 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;
for (const debug_view_source *source = m_source_list.head(); source != NULL; source = source->next())
{
// Collect
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++;
}
}
}
// 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;
}
//-------------------------------------------------
// view_update - update the contents of the
// disassembly view
//-------------------------------------------------
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);
// Set the view region so the scroll bars update
m_total.y = numWPs+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 (row == 0)
{
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++;
}
}
delete[] wpList;
}

111
src/emu/debug/dvwpoints.h Normal file
View File

@ -0,0 +1,111 @@
/*********************************************************************
dvwpoints.h
Watchpoint debugger view.
****************************************************************************
Copyright Aaron Giles
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name 'MAME' nor the names of its contributors may be
used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
***************************************************************************/
#ifndef __DVWPOINTS_H__
#define __DVWPOINTS_H__
#include "debugvw.h"
#include "debugcpu.h"
//**************************************************************************
// CONSTANTS
//**************************************************************************
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
// debug view for watchpoints
class debug_view_watchpoints : public debug_view
{
friend resource_pool_object<debug_view_watchpoints>::~resource_pool_object();
friend class debug_view_manager;
// construction/destruction
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();
virtual void view_notify(debug_view_notification type);
virtual void view_char(int chval);
virtual void view_click(const int button, const debug_view_xy& pos);
private:
// internal helpers
void enumerate_sources();
bool recompute(offs_t pc, int startline, int lines);
void pad_astring_to_length(astring& str, int len);
int watchpoints(SortMode sort, device_debug::watchpoint**& bpList);
// internal state
SortMode m_sortType;
};
#endif