| 
									
										
										
										
											2015-05-24 06:55:12 +02:00
										 |  |  | // Copyright 2008 Dolphin Emulator Project
 | 
					
						
							| 
									
										
										
										
											2015-05-18 01:08:10 +02:00
										 |  |  | // Licensed under GPLv2+
 | 
					
						
							| 
									
										
										
										
											2013-04-17 23:09:55 -04:00
										 |  |  | // Refer to the license.txt file included.
 | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-25 09:35:56 +00:00
										 |  |  | #include <sstream>
 | 
					
						
							| 
									
										
										
										
											2014-02-20 04:11:52 +01:00
										 |  |  | #include <string>
 | 
					
						
							|  |  |  | #include <vector>
 | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-17 05:18:15 -05:00
										 |  |  | #include "Common/BreakPoints.h"
 | 
					
						
							| 
									
										
										
										
											2014-09-07 20:06:58 -05:00
										 |  |  | #include "Common/CommonTypes.h"
 | 
					
						
							| 
									
										
										
										
											2014-02-17 05:18:15 -05:00
										 |  |  | #include "Common/DebugInterface.h"
 | 
					
						
							|  |  |  | #include "Core/PowerPC/JitCommon/JitBase.h"
 | 
					
						
							| 
									
										
										
										
											2014-02-20 04:11:52 +01:00
										 |  |  | #include "Core/PowerPC/JitCommon/JitCache.h"
 | 
					
						
							| 
									
										
										
										
											2014-02-17 05:18:15 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-15 00:38:21 -04:00
										 |  |  | bool BreakPoints::IsAddressBreakPoint(u32 address) const | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-02-12 16:00:34 +01:00
										 |  |  | 	for (const TBreakPoint& bp : m_BreakPoints) | 
					
						
							| 
									
										
										
										
											2015-04-15 00:38:21 -04:00
										 |  |  | 		if (bp.iAddress == address) | 
					
						
							| 
									
										
										
										
											2011-02-25 09:35:56 +00:00
										 |  |  | 			return true; | 
					
						
							| 
									
										
										
										
											2014-03-03 00:39:08 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-25 09:35:56 +00:00
										 |  |  | 	return false; | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-15 00:38:21 -04:00
										 |  |  | bool BreakPoints::IsTempBreakPoint(u32 address) const | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-02-12 16:00:34 +01:00
										 |  |  | 	for (const TBreakPoint& bp : m_BreakPoints) | 
					
						
							| 
									
										
										
										
											2015-04-15 00:38:21 -04:00
										 |  |  | 		if (bp.iAddress == address && bp.bTemporary) | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 			return true; | 
					
						
							| 
									
										
										
										
											2014-03-03 00:39:08 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 	return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-25 09:35:56 +00:00
										 |  |  | BreakPoints::TBreakPointsStr BreakPoints::GetStrings() const | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-02-25 09:35:56 +00:00
										 |  |  | 	TBreakPointsStr bps; | 
					
						
							| 
									
										
										
										
											2014-02-12 16:00:34 +01:00
										 |  |  | 	for (const TBreakPoint& bp : m_BreakPoints) | 
					
						
							| 
									
										
										
										
											2011-02-25 09:35:56 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2013-10-29 01:09:01 -04:00
										 |  |  | 		if (!bp.bTemporary) | 
					
						
							| 
									
										
										
										
											2011-02-25 09:35:56 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2013-10-29 01:09:01 -04:00
										 |  |  | 			std::stringstream ss; | 
					
						
							|  |  |  | 			ss << std::hex << bp.iAddress << " " << (bp.bOn ? "n" : ""); | 
					
						
							|  |  |  | 			bps.push_back(ss.str()); | 
					
						
							| 
									
										
										
										
											2011-02-25 09:35:56 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-25 09:35:56 +00:00
										 |  |  | 	return bps; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-29 01:09:01 -04:00
										 |  |  | void BreakPoints::AddFromStrings(const TBreakPointsStr& bpstrs) | 
					
						
							| 
									
										
										
										
											2011-02-25 09:35:56 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-02-12 16:00:34 +01:00
										 |  |  | 	for (const std::string& bpstr : bpstrs) | 
					
						
							| 
									
										
										
										
											2011-02-25 09:35:56 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		TBreakPoint bp; | 
					
						
							| 
									
										
										
										
											2013-10-29 01:09:01 -04:00
										 |  |  | 		std::stringstream ss; | 
					
						
							|  |  |  | 		ss << std::hex << bpstr; | 
					
						
							|  |  |  | 		ss >> bp.iAddress; | 
					
						
							|  |  |  | 		bp.bOn = bpstr.find("n") != bpstr.npos; | 
					
						
							| 
									
										
										
										
											2011-02-25 09:35:56 +00:00
										 |  |  | 		bp.bTemporary = false; | 
					
						
							|  |  |  | 		Add(bp); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void BreakPoints::Add(const TBreakPoint& bp) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (!IsAddressBreakPoint(bp.iAddress)) | 
					
						
							| 
									
										
										
										
											2012-03-15 21:48:19 +11:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2011-02-25 09:35:56 +00:00
										 |  |  | 		m_BreakPoints.push_back(bp); | 
					
						
							| 
									
										
										
										
											2012-03-15 21:48:19 +11:00
										 |  |  | 		if (jit) | 
					
						
							| 
									
										
										
										
											2014-09-26 13:45:24 -07:00
										 |  |  | 			jit->GetBlockCache()->InvalidateICache(bp.iAddress, 4, true); | 
					
						
							| 
									
										
										
										
											2012-03-15 21:48:19 +11:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-25 09:35:56 +00:00
										 |  |  | void BreakPoints::Add(u32 em_address, bool temp) | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-12-20 12:10:59 +00:00
										 |  |  | 	if (!IsAddressBreakPoint(em_address)) // only add new addresses
 | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		TBreakPoint pt; // breakpoint settings
 | 
					
						
							|  |  |  | 		pt.bOn = true; | 
					
						
							|  |  |  | 		pt.bTemporary = temp; | 
					
						
							| 
									
										
										
										
											2008-12-20 12:10:59 +00:00
										 |  |  | 		pt.iAddress = em_address; | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		m_BreakPoints.push_back(pt); | 
					
						
							| 
									
										
										
										
											2012-03-15 21:48:19 +11:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if (jit) | 
					
						
							| 
									
										
										
										
											2014-09-26 13:45:24 -07:00
										 |  |  | 			jit->GetBlockCache()->InvalidateICache(em_address, 4, true); | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-15 21:48:19 +11:00
										 |  |  | void BreakPoints::Remove(u32 em_address) | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-02-12 16:00:34 +01:00
										 |  |  | 	for (auto i = m_BreakPoints.begin(); i != m_BreakPoints.end(); ++i) | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2012-03-15 21:48:19 +11:00
										 |  |  | 		if (i->iAddress == em_address) | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2011-02-25 09:35:56 +00:00
										 |  |  | 			m_BreakPoints.erase(i); | 
					
						
							| 
									
										
										
										
											2012-03-15 21:48:19 +11:00
										 |  |  | 			if (jit) | 
					
						
							| 
									
										
										
										
											2014-09-26 13:45:24 -07:00
										 |  |  | 				jit->GetBlockCache()->InvalidateICache(em_address, 4, true); | 
					
						
							| 
									
										
										
										
											2011-02-25 09:35:56 +00:00
										 |  |  | 			return; | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-15 21:48:19 +11:00
										 |  |  | void BreakPoints::Clear() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-01-08 15:02:50 -06:00
										 |  |  | 	if (jit) | 
					
						
							| 
									
										
										
										
											2012-03-15 21:48:19 +11:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2014-02-12 16:00:34 +01:00
										 |  |  | 		for (const TBreakPoint& bp : m_BreakPoints) | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2014-09-26 13:45:24 -07:00
										 |  |  | 			jit->GetBlockCache()->InvalidateICache(bp.iAddress, 4, true); | 
					
						
							| 
									
										
										
										
											2014-02-12 16:00:34 +01:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-03-15 21:48:19 +11:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-10-29 01:23:17 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-08 15:02:50 -06:00
										 |  |  | 	m_BreakPoints.clear(); | 
					
						
							| 
									
										
										
										
											2012-03-15 21:48:19 +11:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2011-02-25 09:35:56 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-18 11:02:26 +11:00
										 |  |  | void BreakPoints::ClearAllTemporary() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	for (const TBreakPoint& bp : m_BreakPoints) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		if (bp.bTemporary) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			if (jit) | 
					
						
							|  |  |  | 				jit->GetBlockCache()->InvalidateICache(bp.iAddress, 4, true); | 
					
						
							|  |  |  | 			Remove(bp.iAddress); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-25 09:35:56 +00:00
										 |  |  | MemChecks::TMemChecksStr MemChecks::GetStrings() const | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-02-25 09:35:56 +00:00
										 |  |  | 	TMemChecksStr mcs; | 
					
						
							| 
									
										
										
										
											2014-02-12 16:00:34 +01:00
										 |  |  | 	for (const TMemCheck& bp : m_MemChecks) | 
					
						
							| 
									
										
										
										
											2011-02-25 09:35:56 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		std::stringstream mc; | 
					
						
							| 
									
										
										
										
											2013-10-29 01:09:01 -04:00
										 |  |  | 		mc << std::hex << bp.StartAddress; | 
					
						
							|  |  |  | 		mc << " " << (bp.bRange ? bp.EndAddress : bp.StartAddress) << " " << | 
					
						
							|  |  |  | 			(bp.bRange ? "n" : "") << (bp.OnRead ? "r" : "") << | 
					
						
							|  |  |  | 			(bp.OnWrite ? "w" : "") << (bp.Log ? "l" : "") << (bp.Break ? "p" : ""); | 
					
						
							| 
									
										
										
										
											2011-02-25 09:35:56 +00:00
										 |  |  | 		mcs.push_back(mc.str()); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return mcs; | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-29 01:09:01 -04:00
										 |  |  | void MemChecks::AddFromStrings(const TMemChecksStr& mcstrs) | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-02-12 16:00:34 +01:00
										 |  |  | 	for (const std::string& mcstr : mcstrs) | 
					
						
							| 
									
										
										
										
											2011-02-25 09:35:56 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		TMemCheck mc; | 
					
						
							| 
									
										
										
										
											2013-10-29 01:09:01 -04:00
										 |  |  | 		std::stringstream ss; | 
					
						
							|  |  |  | 		ss << std::hex << mcstr; | 
					
						
							|  |  |  | 		ss >> mc.StartAddress; | 
					
						
							| 
									
										
										
										
											2014-02-16 23:51:41 -05:00
										 |  |  | 		mc.bRange  = mcstr.find("n") != mcstr.npos; | 
					
						
							|  |  |  | 		mc.OnRead  = mcstr.find("r") != mcstr.npos; | 
					
						
							|  |  |  | 		mc.OnWrite = mcstr.find("w") != mcstr.npos; | 
					
						
							|  |  |  | 		mc.Log     = mcstr.find("l") != mcstr.npos; | 
					
						
							|  |  |  | 		mc.Break   = mcstr.find("p") != mcstr.npos; | 
					
						
							| 
									
										
										
										
											2011-02-25 09:35:56 +00:00
										 |  |  | 		if (mc.bRange) | 
					
						
							| 
									
										
										
										
											2013-10-29 01:09:01 -04:00
										 |  |  | 			ss >> mc.EndAddress; | 
					
						
							| 
									
										
										
										
											2011-02-25 09:35:56 +00:00
										 |  |  | 		else | 
					
						
							|  |  |  | 			mc.EndAddress = mc.StartAddress; | 
					
						
							|  |  |  | 		Add(mc); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2008-12-20 14:00:33 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MemChecks::Add(const TMemCheck& _rMemoryCheck) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2015-04-23 00:05:31 -04:00
										 |  |  | 	bool had_any = HasAny(); | 
					
						
							| 
									
										
										
										
											2014-03-09 21:14:26 +01:00
										 |  |  | 	if (GetMemCheck(_rMemoryCheck.StartAddress) == nullptr) | 
					
						
							| 
									
										
										
										
											2011-02-25 09:35:56 +00:00
										 |  |  | 		m_MemChecks.push_back(_rMemoryCheck); | 
					
						
							| 
									
										
										
										
											2015-04-23 00:05:31 -04:00
										 |  |  | 	// If this is the first one, clear the JIT cache so it can switch to
 | 
					
						
							|  |  |  | 	// watchpoint-compatible code.
 | 
					
						
							| 
									
										
										
										
											2015-06-07 03:03:35 -07:00
										 |  |  | 	if (!had_any && jit) | 
					
						
							| 
									
										
										
										
											2015-04-23 00:05:31 -04:00
										 |  |  | 		jit->ClearCache(); | 
					
						
							| 
									
										
										
										
											2008-12-20 14:00:33 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-25 09:35:56 +00:00
										 |  |  | void MemChecks::Remove(u32 _Address) | 
					
						
							| 
									
										
										
										
											2008-12-20 14:00:33 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-02-12 16:00:34 +01:00
										 |  |  | 	for (auto i = m_MemChecks.begin(); i != m_MemChecks.end(); ++i) | 
					
						
							| 
									
										
										
										
											2008-12-20 14:00:33 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2011-02-25 09:35:56 +00:00
										 |  |  | 		if (i->StartAddress == _Address) | 
					
						
							| 
									
										
										
										
											2008-12-20 14:00:33 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2011-02-25 09:35:56 +00:00
										 |  |  | 			m_MemChecks.erase(i); | 
					
						
							|  |  |  | 			return; | 
					
						
							| 
									
										
										
										
											2008-12-20 14:00:33 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2011-02-25 09:35:56 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-06-07 03:03:35 -07:00
										 |  |  | 	if (!HasAny() && jit) | 
					
						
							| 
									
										
										
										
											2015-04-23 00:05:31 -04:00
										 |  |  | 		jit->ClearCache(); | 
					
						
							| 
									
										
										
										
											2011-02-25 09:35:56 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-21 21:16:51 +01:00
										 |  |  | TMemCheck* MemChecks::GetMemCheck(u32 address) | 
					
						
							| 
									
										
										
										
											2011-02-25 09:35:56 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-02-12 16:00:34 +01:00
										 |  |  | 	for (TMemCheck& bp : m_MemChecks) | 
					
						
							| 
									
										
										
										
											2011-02-25 09:35:56 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2013-10-29 01:09:01 -04:00
										 |  |  | 		if (bp.bRange) | 
					
						
							| 
									
										
										
										
											2008-12-20 14:00:33 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2013-10-29 01:09:01 -04:00
										 |  |  | 			if (address >= bp.StartAddress && address <= bp.EndAddress) | 
					
						
							|  |  |  | 				return &(bp); | 
					
						
							| 
									
										
										
										
											2008-12-20 14:00:33 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2013-10-29 01:09:01 -04:00
										 |  |  | 		else if (bp.StartAddress == address) | 
					
						
							| 
									
										
										
										
											2014-03-03 00:39:08 -05:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2013-10-29 01:09:01 -04:00
										 |  |  | 			return &(bp); | 
					
						
							| 
									
										
										
										
											2014-03-03 00:39:08 -05:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2008-12-20 14:00:33 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-25 09:35:56 +00:00
										 |  |  | 	// none found
 | 
					
						
							| 
									
										
										
										
											2014-03-09 21:14:26 +01:00
										 |  |  | 	return nullptr; | 
					
						
							| 
									
										
										
										
											2008-12-20 14:00:33 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-21 21:16:51 +01:00
										 |  |  | bool TMemCheck::Action(DebugInterface* debug_interface, u32 iValue, u32 addr, bool write, int size, u32 pc) | 
					
						
							| 
									
										
										
										
											2008-12-20 14:00:33 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-02-25 09:35:56 +00:00
										 |  |  | 	if ((write && OnWrite) || (!write && OnRead)) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		if (Log) | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2011-02-25 11:03:49 +00:00
										 |  |  | 			INFO_LOG(MEMMAP, "CHK %08x (%s) %s%i %0*x at %08x (%s)", | 
					
						
							| 
									
										
										
										
											2014-03-03 00:39:08 -05:00
										 |  |  | 				pc, debug_interface->GetDescription(pc).c_str(), | 
					
						
							| 
									
										
										
										
											2011-02-25 11:03:49 +00:00
										 |  |  | 				write ? "Write" : "Read", size*8, size*2, iValue, addr, | 
					
						
							| 
									
										
										
										
											2014-03-03 00:39:08 -05:00
										 |  |  | 				debug_interface->GetDescription(addr).c_str() | 
					
						
							| 
									
										
										
										
											2011-02-25 09:35:56 +00:00
										 |  |  | 				); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-03-03 00:39:08 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-23 01:22:35 -04:00
										 |  |  | 		return true; | 
					
						
							| 
									
										
										
										
											2011-02-25 09:35:56 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-04-23 01:22:35 -04:00
										 |  |  | 	return false; | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-10-19 21:45:40 +11:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-28 04:28:50 -07:00
										 |  |  | bool Watches::IsAddressWatch(u32 _iAddress) const | 
					
						
							| 
									
										
										
										
											2014-10-19 21:45:40 +11:00
										 |  |  | { | 
					
						
							|  |  |  | 	for (const TWatch& bp : m_Watches) | 
					
						
							|  |  |  | 		if (bp.iAddress == _iAddress) | 
					
						
							|  |  |  | 			return true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Watches::TWatchesStr Watches::GetStrings() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	TWatchesStr bps; | 
					
						
							|  |  |  | 	for (const TWatch& bp : m_Watches) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		std::stringstream ss; | 
					
						
							| 
									
										
										
										
											2014-10-24 22:24:17 +11:00
										 |  |  | 		ss << std::hex << bp.iAddress << " " << bp.name; | 
					
						
							| 
									
										
										
										
											2014-10-19 21:45:40 +11:00
										 |  |  | 		bps.push_back(ss.str()); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return bps; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Watches::AddFromStrings(const TWatchesStr& bpstrs) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	for (const std::string& bpstr : bpstrs) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		TWatch bp; | 
					
						
							|  |  |  | 		std::stringstream ss; | 
					
						
							|  |  |  | 		ss << std::hex << bpstr; | 
					
						
							|  |  |  | 		ss >> bp.iAddress; | 
					
						
							| 
									
										
										
										
											2014-10-26 16:14:17 +11:00
										 |  |  | 		ss >> std::ws; | 
					
						
							|  |  |  | 		getline(ss, bp.name); | 
					
						
							| 
									
										
										
										
											2014-10-19 21:45:40 +11:00
										 |  |  | 		Add(bp); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Watches::Add(const TWatch& bp) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (!IsAddressWatch(bp.iAddress)) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		m_Watches.push_back(bp); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Watches::Add(u32 em_address) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (!IsAddressWatch(em_address)) // only add new addresses
 | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		TWatch pt; // breakpoint settings
 | 
					
						
							|  |  |  | 		pt.bOn = true; | 
					
						
							|  |  |  | 		pt.iAddress = em_address; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		m_Watches.push_back(pt); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Watches::Update(int count, u32 em_address) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	m_Watches.at(count).iAddress = em_address; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-26 23:23:45 +11:00
										 |  |  | void Watches::UpdateName(int count, const std::string name) | 
					
						
							| 
									
										
										
										
											2014-10-19 21:45:40 +11:00
										 |  |  | { | 
					
						
							|  |  |  | 	m_Watches.at(count).name = name; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Watches::Remove(u32 em_address) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	for (auto i = m_Watches.begin(); i != m_Watches.end(); ++i) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		if (i->iAddress == em_address) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			m_Watches.erase(i); | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Watches::Clear() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	m_Watches.clear(); | 
					
						
							|  |  |  | } |