// Copyright (c) 2012- PPSSPP Project. // 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 or later versions. // 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 git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #pragma once #include "../../Globals.h" #include // TODO: Replace with expression or something. struct BreakPointCond { u32 todo; u32 Evaluate() const { return 1; } }; struct BreakPoint { BreakPoint() : hasCond(false) {} u32 addr; bool enabled; bool temporary; bool hasCond; BreakPointCond cond; bool operator == (const BreakPoint &other) const { return addr == other.addr; } bool operator < (const BreakPoint &other) const { return addr < other.addr; } }; enum MemCheckCondition { MEMCHECK_READ = 0x01, MEMCHECK_WRITE = 0x02, MEMCHECK_READWRITE = 0x03, }; enum MemCheckResult { MEMCHECK_IGNORE = 0x00, MEMCHECK_LOG = 0x01, MEMCHECK_BREAK = 0x02, MEMCHECK_BOTH = 0x03, }; struct MemCheck { MemCheck(); u32 start; u32 end; MemCheckCondition cond; MemCheckResult result; u32 numHits; void Action(u32 addr, bool write, int size, u32 pc); bool operator == (const MemCheck &other) const { return start == other.start && end == other.end; } }; // BreakPoints cannot overlap, only one is allowed per address. // MemChecks can overlap, as long as their ends are different. // WARNING: MemChecks are not used in the interpreter or HLE currently. class CBreakPoints { public: static const size_t INVALID_BREAKPOINT = -1; static const size_t INVALID_MEMCHECK = -1; static bool IsAddressBreakPoint(u32 addr); static bool IsTempBreakPoint(u32 addr); static void AddBreakPoint(u32 addr, bool temp = false); static void RemoveBreakPoint(u32 addr); static void ChangeBreakPoint(u32 addr, bool enable); static void ClearAllBreakPoints(); static void ClearTemporaryBreakPoints(); // Makes a copy. Temporary breakpoints can't have conditions. static void ChangeBreakPointAddCond(u32 addr, const BreakPointCond &cond); static void ChangeBreakPointRemoveCond(u32 addr); static BreakPointCond *GetBreakPointCondition(u32 addr); static void AddMemCheck(u32 start, u32 end, MemCheckCondition cond, MemCheckResult result); static void RemoveMemCheck(u32 start, u32 end); static void ChangeMemCheck(u32 start, u32 end, MemCheckCondition cond, MemCheckResult result); static void ClearAllMemChecks(); static MemCheck *GetMemCheck(u32 address, int size); // TODO: MemChecks somehow too? static void SetSkipFirst(u32 pc) { breakSkipFirstAt_ = pc; } static u32 CheckSkipFirst() { u32 pc = breakSkipFirstAt_; breakSkipFirstAt_ = 0; return pc; } static const std::vector GetMemChecks(); static const std::vector GetBreakpoints(); static void Update(u32 addr = 0); private: static size_t FindBreakpoint(u32 addr, bool matchTemp = false, bool temp = false); // Finds exactly, not using a range check. static size_t FindMemCheck(u32 start, u32 end); static std::vector breakPoints_; static u32 breakSkipFirstAt_; static std::vector memChecks_; };