2009-07-28 15:32:10 -06:00
|
|
|
// Copyright (C) 2003 Dolphin Project.
|
2008-12-07 22:30:24 -07:00
|
|
|
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU General Public License as published by
|
|
|
|
// the Free Software Foundation, version 2.0.
|
|
|
|
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU General Public License 2.0 for more details.
|
|
|
|
|
|
|
|
// A copy of the GPL 2.0 should have been included with the program.
|
|
|
|
// If not, see http://www.gnu.org/licenses/
|
|
|
|
|
|
|
|
// Official SVN repository and contact information can be found at
|
|
|
|
// http://code.google.com/p/dolphin-emu/
|
|
|
|
|
|
|
|
#include "Common.h"
|
2009-02-01 07:23:11 -07:00
|
|
|
|
2009-06-28 06:15:31 -06:00
|
|
|
#include "DebugInterface.h"
|
|
|
|
#include "BreakPoints.h"
|
2008-12-07 22:30:24 -07:00
|
|
|
|
2009-06-28 06:15:31 -06:00
|
|
|
void TMemCheck::Action(DebugInterface *debug_interface, u32 iValue, u32 addr, bool write, int size, u32 pc)
|
2008-12-07 22:30:24 -07:00
|
|
|
{
|
|
|
|
if ((write && OnWrite) || (!write && OnRead))
|
|
|
|
{
|
|
|
|
if (Log)
|
|
|
|
{
|
2009-06-28 05:47:39 -06:00
|
|
|
DEBUG_LOG(MEMMAP, "CHK %08x %s%i at %08x (%s)",
|
2008-12-07 22:30:24 -07:00
|
|
|
iValue, write ? "Write" : "Read", // read or write
|
|
|
|
size*8, addr, // address
|
2009-06-28 09:52:15 -06:00
|
|
|
debug_interface->getDescription(addr).c_str() // symbol map description
|
2008-12-07 22:30:24 -07:00
|
|
|
);
|
|
|
|
}
|
|
|
|
if (Break)
|
2009-06-28 06:15:31 -06:00
|
|
|
debug_interface->breakNow();
|
2008-12-07 22:30:24 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-12-20 07:00:33 -07:00
|
|
|
bool BreakPoints::IsAddressBreakPoint(u32 _iAddress)
|
2008-12-07 22:30:24 -07:00
|
|
|
{
|
|
|
|
std::vector<TBreakPoint>::iterator iter;
|
|
|
|
for (iter = m_BreakPoints.begin(); iter != m_BreakPoints.end(); ++iter)
|
|
|
|
if ((*iter).iAddress == _iAddress)
|
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2008-12-20 07:00:33 -07:00
|
|
|
bool BreakPoints::IsTempBreakPoint(u32 _iAddress)
|
2008-12-07 22:30:24 -07:00
|
|
|
{
|
|
|
|
std::vector<TBreakPoint>::iterator iter;
|
|
|
|
|
|
|
|
for (iter = m_BreakPoints.begin(); iter != m_BreakPoints.end(); ++iter)
|
|
|
|
if ((*iter).iAddress == _iAddress && (*iter).bTemporary)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2009-02-01 07:23:11 -07:00
|
|
|
bool BreakPoints::Add(u32 em_address, bool temp)
|
2008-12-07 22:30:24 -07:00
|
|
|
{
|
2008-12-20 05:10:59 -07:00
|
|
|
if (!IsAddressBreakPoint(em_address)) // only add new addresses
|
2008-12-07 22:30:24 -07:00
|
|
|
{
|
|
|
|
TBreakPoint pt; // breakpoint settings
|
|
|
|
pt.bOn = true;
|
|
|
|
pt.bTemporary = temp;
|
2008-12-20 05:10:59 -07:00
|
|
|
pt.iAddress = em_address;
|
2008-12-07 22:30:24 -07:00
|
|
|
|
|
|
|
m_BreakPoints.push_back(pt);
|
2009-02-01 07:23:11 -07:00
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
return false;
|
2008-12-07 22:30:24 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-02-01 07:23:11 -07:00
|
|
|
bool BreakPoints::Remove(u32 _iAddress)
|
2008-12-07 22:30:24 -07:00
|
|
|
{
|
|
|
|
std::vector<TBreakPoint>::iterator iter;
|
|
|
|
for (iter = m_BreakPoints.begin(); iter != m_BreakPoints.end(); ++iter)
|
|
|
|
{
|
|
|
|
if ((*iter).iAddress == _iAddress)
|
|
|
|
{
|
|
|
|
m_BreakPoints.erase(iter);
|
2009-02-01 07:23:11 -07:00
|
|
|
return true;
|
2008-12-07 22:30:24 -07:00
|
|
|
}
|
|
|
|
}
|
2009-02-01 07:23:11 -07:00
|
|
|
return false;
|
2008-12-07 22:30:24 -07:00
|
|
|
}
|
|
|
|
|
2008-12-20 07:00:33 -07:00
|
|
|
void BreakPoints::Clear()
|
2008-12-07 22:30:24 -07:00
|
|
|
{
|
|
|
|
m_BreakPoints.clear();
|
|
|
|
}
|
|
|
|
|
2008-12-20 07:00:33 -07:00
|
|
|
void BreakPoints::DeleteByAddress(u32 _Address)
|
2008-12-07 22:30:24 -07:00
|
|
|
{
|
|
|
|
// first check breakpoints
|
|
|
|
{
|
|
|
|
std::vector<TBreakPoint>::iterator iter;
|
|
|
|
for (iter = m_BreakPoints.begin(); iter != m_BreakPoints.end(); ++iter)
|
|
|
|
{
|
|
|
|
if ((*iter).iAddress == _Address)
|
|
|
|
{
|
|
|
|
m_BreakPoints.erase(iter);
|
|
|
|
return;
|
2008-12-20 07:00:33 -07:00
|
|
|
}
|
2008-12-07 22:30:24 -07:00
|
|
|
}
|
|
|
|
}
|
2008-12-20 07:00:33 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void MemChecks::Add(const TMemCheck& _rMemoryCheck)
|
|
|
|
{
|
|
|
|
m_MemChecks.push_back(_rMemoryCheck);
|
|
|
|
}
|
|
|
|
|
2008-12-07 22:30:24 -07:00
|
|
|
|
2008-12-20 07:00:33 -07:00
|
|
|
TMemCheck *MemChecks::GetMemCheck(u32 address)
|
|
|
|
{
|
|
|
|
std::vector<TMemCheck>::iterator iter;
|
|
|
|
for (iter = m_MemChecks.begin(); iter != m_MemChecks.end(); ++iter)
|
|
|
|
{
|
|
|
|
if ((*iter).bRange)
|
|
|
|
{
|
|
|
|
if (address >= (*iter).StartAddress && address <= (*iter).EndAddress)
|
|
|
|
return &(*iter);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ((*iter).StartAddress == address)
|
|
|
|
return &(*iter);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//none found
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void MemChecks::Clear()
|
|
|
|
{
|
|
|
|
m_MemChecks.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
void MemChecks::DeleteByAddress(u32 _Address)
|
|
|
|
{
|
2008-12-07 22:30:24 -07:00
|
|
|
std::vector<TMemCheck>::iterator iter;
|
|
|
|
for (iter = m_MemChecks.begin(); iter != m_MemChecks.end(); ++iter)
|
|
|
|
{
|
|
|
|
if ((*iter).StartAddress == _Address)
|
|
|
|
{
|
|
|
|
m_MemChecks.erase(iter);
|
2009-06-28 06:15:31 -06:00
|
|
|
return;
|
2008-12-07 22:30:24 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|