1//============================================================================
2//
3// SSSS tt lll lll
4// SS SS tt ll ll
5// SS tttttt eeee ll ll aaaa
6// SSSS tt ee ee ll ll aa
7// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
8// SS SS tt ee ll ll aa aa
9// SSSS ttt eeeee llll llll aaaaa
10//
11// Copyright (c) 1995-2019 by Bradford W. Mott, Stephen Anthony
12// and the Stella Team
13//
14// See the file "License.txt" for information on usage and redistribution of
15// this file, and for a DISCLAIMER OF ALL WARRANTIES.
16//============================================================================
17
18#ifndef BREAKPOINT_HXX
19#define BREAKPOINT_HXX
20
21#include <unordered_map>
22
23#include "bspf.hxx"
24
25/**
26 This class handles simple debugger breakpoints.
27
28 @author Thomas Jentzsch
29*/
30class BreakpointMap
31{
32private:
33 static const uInt16 ADDRESS_MASK = 0x1fff; // either 0x1fff or 0xffff (not needed then)
34
35public:
36 // breakpoint flags
37 static const uInt32 ONE_SHOT = 1 << 0; // used for 'trace' command
38
39 static const uInt8 ANY_BANK = 255; // breakpoint valid in any bank
40
41 struct Breakpoint
42 {
43 uInt16 addr;
44 uInt8 bank;
45
46 Breakpoint()
47 : addr(0), bank(0) { }
48 Breakpoint(const Breakpoint& bp)
49 : addr(bp.addr), bank(bp.bank) { }
50 explicit Breakpoint(uInt16 c_addr, uInt8 c_bank)
51 : addr(c_addr), bank(c_bank) { }
52
53 bool operator==(const Breakpoint& other) const
54 {
55 if(addr == other.addr)
56 {
57 if(bank == ANY_BANK || other.bank == ANY_BANK)
58 return true;
59 else
60 return bank == other.bank;
61 }
62 return false;
63 }
64 bool operator<(const Breakpoint& other) const
65 {
66 return bank < other.bank ||
67 (bank == other.bank && addr < other.addr);
68 }
69 };
70 using BreakpointList = std::vector<Breakpoint>;
71
72 BreakpointMap();
73 virtual ~BreakpointMap() = default;
74
75 bool isInitialized() const { return myInitialized; }
76
77 /** Add new breakpoint */
78 void add(const Breakpoint& breakpoint, const uInt32 flags = 0);
79 void add(const uInt16 addr, const uInt8 bank, const uInt32 flags = 0);
80
81 /** Erase breakpoint */
82 void erase(const Breakpoint& breakpoint);
83 void erase(const uInt16 addr, const uInt8 bank);
84
85 /** Get info for breakpoint */
86 uInt32 get(const Breakpoint& breakpoint) const;
87 uInt32 get(uInt16 addr, uInt8 bank) const;
88
89 /** Check if a breakpoint exists */
90 bool check(const Breakpoint& breakpoint) const;
91 bool check(const uInt16 addr, const uInt8 bank) const;
92
93 /** Returns a sorted list of breakpoints */
94 BreakpointList getBreakpoints() const;
95
96 /** clear all breakpoints */
97 void clear() { myMap.clear(); }
98 size_t size() { return myMap.size(); }
99
100private:
101 Breakpoint convertBreakpoint(const Breakpoint& breakpoint);
102
103 struct BreakpointHash {
104 size_t operator()(const Breakpoint& bp) const {
105 return std::hash<uInt64>()(
106 uInt64(bp.addr) * 13 // only check for address, bank check via == operator
107 );
108 }
109 };
110
111 std::unordered_map<Breakpoint, uInt32, BreakpointHash> myMap;
112 bool myInitialized;
113};
114
115#endif
116