Fix crash if text containing \n is printed at nonzero x
[lsnes.git] / include / core / debug.hpp
blob6439db4b71aefc5ec64bb5c9eaa208d39500431f
1 #ifndef _debug__hpp__included__
2 #define _debug__hpp__included__
4 #include <functional>
5 #include <fstream>
6 #include <cstdint>
7 #include "library/command.hpp"
8 #include "library/dispatch.hpp"
10 class emulator_dispatch;
11 class loaded_rom;
12 class memory_space;
14 /**
15 * Debugging context.
17 class debug_context
19 public:
20 debug_context(emulator_dispatch& _dispatch, loaded_rom& _rom, memory_space& _mspace, command::group& _cmd);
21 /**
22 * Type of event.
24 enum etype
26 DEBUG_READ,
27 DEBUG_WRITE,
28 DEBUG_EXEC,
29 DEBUG_TRACE,
30 DEBUG_FRAME,
32 /**
33 * Parameters for read/write/execute event.
35 struct params_rwx
37 uint64_t addr; //Address.
38 uint64_t value; //Value/CPU.
40 /**
41 * Parameters for trace event.
43 struct params_trace
45 uint64_t cpu; //CPU number.
46 const char* decoded_insn; //Decoded instruction
47 bool true_insn; //True instruction flag.
49 /**
50 * Parameters for frame event.
52 struct params_frame
54 uint64_t frame; //Frame number.
55 bool loadstated; //Loadstate flag.
57 /**
58 * Parameters for debug callback.
60 struct params
62 etype type;
63 union {
64 params_rwx rwx; //READ/WRITE/EXECUTE
65 params_trace trace; //TRACE.
66 params_frame frame; //FRAME.
69 /**
70 * Base class of debugging callbacks.
72 struct callback_base
74 /**
75 * Destructor.
77 virtual ~callback_base();
78 /**
79 * Do a callback.
81 virtual void callback(const params& p) = 0;
82 /**
83 * Notify about killed callback.
85 virtual void killed(uint64_t addr, etype type) = 0;
87 /**
88 * Placeholder for all addresses.
90 static const uint64_t all_addresses;
91 /**
92 * Add a callback.
94 void add_callback(uint64_t addr, etype type, callback_base& cb);
95 /**
96 * Remove a callback.
98 void remove_callback(uint64_t addr, etype type, callback_base& cb);
99 /**
100 * Fire a read callback.
102 void do_callback_read(uint64_t addr, uint64_t value);
104 * Fire a write callback.
106 void do_callback_write(uint64_t addr, uint64_t value);
108 * Fire a exec callback.
110 void do_callback_exec(uint64_t addr, uint64_t value);
112 * Fire a trace callback.
114 void do_callback_trace(uint64_t cpu, const char* str, bool true_insn = true);
116 * Fire a frame callback.
118 void do_callback_frame(uint64_t frame, bool loadstate);
120 * Set a cheat.
122 void set_cheat(uint64_t addr, uint64_t value);
124 * Clear a cheat.
126 void clear_cheat(uint64_t addr);
128 * Set execute callback mask.
130 void setxmask(uint64_t mask);
132 * Set tracelog file.
134 void tracelog(uint64_t cpu, const std::string& filename);
136 * Tracelogging on?
138 bool is_tracelogging(uint64_t cpu);
140 * Change tracelog change callback.
142 void set_tracelog_change_cb(std::function<void()> cb);
144 * Notify a core change.
146 void core_change();
148 * Request a break.
150 void request_break();
151 //These are public only for some debugging stuff.
152 typedef std::list<callback_base*> cb_list;
153 std::map<uint64_t, cb_list> read_cb;
154 std::map<uint64_t, cb_list> write_cb;
155 std::map<uint64_t, cb_list> exec_cb;
156 std::map<uint64_t, cb_list> trace_cb;
157 std::map<uint64_t, cb_list> frame_cb;
158 private:
159 void do_showhooks();
160 void do_genevent(const std::string& a);
161 void do_tracecmd(const std::string& a);
162 cb_list dummy_cb; //Always empty.
163 uint64_t xmask = 1;
164 std::function<void()> tracelog_change_cb;
165 emulator_dispatch& edispatch;
166 loaded_rom& rom;
167 memory_space& mspace;
168 command::group& cmd;
169 struct dispatch::target<> corechange;
170 bool corechange_r = false;
171 bool requesting_break = false;
172 command::_fnptr<> showhooks;
173 command::_fnptr<const std::string&> genevent;
174 command::_fnptr<const std::string&> tracecmd;
176 struct tracelog_file : public callback_base
178 std::ofstream stream;
179 std::string full_filename;
180 unsigned refcnt;
181 tracelog_file(debug_context& parent);
182 ~tracelog_file();
183 void callback(const params& p);
184 void killed(uint64_t addr, etype type);
185 private:
186 debug_context& parent;
188 std::map<uint64_t, tracelog_file*> trace_outputs;
190 std::map<uint64_t, cb_list>& get_lists(etype type)
192 switch(type) {
193 case DEBUG_READ: return read_cb;
194 case DEBUG_WRITE: return write_cb;
195 case DEBUG_EXEC: return exec_cb;
196 case DEBUG_TRACE: return trace_cb;
197 case DEBUG_FRAME: return frame_cb;
198 default: throw std::runtime_error("Invalid debug callback type");
203 #endif