summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/debug/debugvw.h
blob: e5f4df80966d3f057fbd3e62dabf9b188e30c1ee (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
/*********************************************************************

    debugvw.h

    Debugger view engine.

****************************************************************************

    Copyright Aaron Giles
    All rights reserved.

    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions are
    met:

        * Redistributions of source code must retain the above copyright
          notice, this list of conditions and the following disclaimer.
        * Redistributions in binary form must reproduce the above copyright
          notice, this list of conditions and the following disclaimer in
          the documentation and/or other materials provided with the
          distribution.
        * Neither the name 'MAME' nor the names of its contributors may be
          used to endorse or promote products derived from this software
          without specific prior written permission.

    THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR
    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT,
    INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
    STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
    IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    POSSIBILITY OF SUCH DAMAGE.

***************************************************************************/

#ifndef __DEBUGVIEW_H__
#define __DEBUGVIEW_H__

#include "express.h"


//**************************************************************************
//  CONSTANTS
//**************************************************************************

// types passed to debug_view_manager::alloc_view()
enum debug_view_type
{
	DVT_NONE,
	DVT_CONSOLE,
	DVT_STATE,
	DVT_DISASSEMBLY,
	DVT_MEMORY,
	DVT_LOG,
	DVT_TIMERS,
	DVT_ALLOCS
};


// notifications passed to view_notify()
enum debug_view_notification
{
	VIEW_NOTIFY_NONE,
	VIEW_NOTIFY_VISIBLE_CHANGED,
	VIEW_NOTIFY_CURSOR_CHANGED,
	VIEW_NOTIFY_SOURCE_CHANGED
};


// attribute bits for debug_view_char.attrib
const UINT8 DCA_NORMAL      = 0x00;     // in Windows: black on white
const UINT8 DCA_CHANGED     = 0x01;     // in Windows: red foreground
const UINT8 DCA_SELECTED    = 0x02;     // in Windows: light red background
const UINT8 DCA_INVALID     = 0x04;     // in Windows: dark blue foreground
const UINT8 DCA_DISABLED    = 0x08;     // in Windows: darker foreground
const UINT8 DCA_ANCILLARY   = 0x10;     // in Windows: grey background
const UINT8 DCA_CURRENT     = 0x20;     // in Windows: yellow background
const UINT8 DCA_COMMENT     = 0x40;     // in Windows: green foreground


// special characters that can be passed to process_char()
const int DCH_UP            = 1;        // up arrow
const int DCH_DOWN          = 2;        // down arrow
const int DCH_LEFT          = 3;        // left arrow
const int DCH_RIGHT         = 4;        // right arrow
const int DCH_PUP           = 5;        // page up
const int DCH_PDOWN         = 6;        // page down
const int DCH_HOME          = 7;        // home
const int DCH_CTRLHOME      = 8;        // ctrl+home
const int DCH_END           = 9;        // end
const int DCH_CTRLEND       = 10;       // ctrl+end
const int DCH_CTRLRIGHT     = 11;       // ctrl+right
const int DCH_CTRLLEFT      = 12;       // ctrl+left


// special characters that can be passed to process_click()
const int DCK_LEFT_CLICK    = 1;        // left instantaneous click
const int DCK_RIGHT_CLICK   = 2;        // right instantaneous click
const int DCK_MIDDLE_CLICK  = 3;        // middle instantaneous click


//**************************************************************************
//  TYPE DEFINITIONS
//**************************************************************************

// forward references
class debug_view;


// OSD callback function for a view
typedef void (*debug_view_osd_update_func)(debug_view &view, void *osdprivate);


// a single "character" in the debug view has an ASCII value and an attribute byte
struct debug_view_char
{
	UINT8               byte;
	UINT8               attrib;
};


// pair of X,Y coordinates for sizing
class debug_view_xy
{
public:
	debug_view_xy(int _x = 0, int _y = 0) : x(_x), y(_y) { }

	INT32                   x;
	INT32                   y;
};


// debug_view_sources select from multiple sources available within a view
class debug_view_source
{
	DISABLE_COPYING(debug_view_source);

	friend class debug_view_source_list;

public:
	// construction/destruction
	debug_view_source(const char *name, device_t *device = NULL);
	virtual ~debug_view_source();

	// getters
	const char *name() const { return m_name; }
	debug_view_source *next() const { return m_next; }
	device_t *device() const { return m_device; }
	bool is_octal() const { return m_is_octal; }

private:
	// internal state
	debug_view_source *     m_next;                 // link to next item
	astring                 m_name;                 // name of the source item
	device_t *              m_device;               // associated device (if applicable)
	bool                    m_is_octal;             // is view in octal or hex
};


// a debug_view_source_list contains a list of debug_view_sources
class debug_view_source_list
{
	DISABLE_COPYING(debug_view_source_list);

public:
	// construction/destruction
	debug_view_source_list(running_machine &machine);
	~debug_view_source_list();

	// getters
	running_machine &machine() const { return m_machine; }
	const debug_view_source *head() const { return m_head; }
	int count() const { return m_count; }
	int index(const debug_view_source &source) const;
	const debug_view_source *by_index(int index) const;

	// operations
	void reset();
	void append(debug_view_source &view_source);
	const debug_view_source *match_device(device_t *device) const;
	int match_device_index(device_t *device) const { return index(*match_device(device)); }

private:
	// internal state
	running_machine &       m_machine;              // reference to our machine
	debug_view_source *     m_head;                 // head of the list
	debug_view_source *     m_tail;                 // end of the tail
	UINT32                  m_count;                // number of items in the list
};


// debug_view describes a single text-based view
class debug_view
{
	friend class debug_view_manager;

protected:
	// construction/destruction
	debug_view(running_machine &machine, debug_view_type type, debug_view_osd_update_func osdupdate, void *osdprivate);
	virtual ~debug_view();

public:
	// getters
	running_machine &machine() const { return m_machine; }
	debug_view *next() const { return m_next; }
	debug_view_type type() const { return m_type; }
	const debug_view_char *viewdata() const { return m_viewdata; }
	debug_view_xy total_size() { flush_updates(); return m_total; }
	debug_view_xy visible_size() { flush_updates(); return m_visible; }
	debug_view_xy visible_position() { flush_updates(); return m_topleft; }
	debug_view_xy cursor_position() { flush_updates(); return m_cursor; }
	bool cursor_supported() { flush_updates(); return m_supports_cursor; }
	bool cursor_visible() { flush_updates(); return m_cursor_visible; }
	const debug_view_source *source() const { return m_source; }
	const debug_view_source_list &source_list() const { return m_source_list; }

	// setters
	void set_size(int width, int height);
	void set_visible_size(debug_view_xy size);
	void set_visible_position(debug_view_xy pos);
	void set_cursor_position(debug_view_xy pos);
	void set_cursor_visible(bool visible = true);
	void set_source(const debug_view_source &source);
	void process_char(int character) { view_char(character); }
	void process_click(int button, debug_view_xy pos) { view_click(button, pos); }

protected:
	// internal updating helpers
	void begin_update() { m_update_level++; }
	void end_update();
	void force_update() { begin_update(); m_update_pending = true; end_update(); }
	void flush_updates() { begin_update(); end_update(); }
	void flush_osd_updates();

	// cursor management helpers
	void adjust_visible_x_for_cursor();
	void adjust_visible_y_for_cursor();

	// overridables
	virtual void view_update() = 0;
	virtual void view_notify(debug_view_notification type);
	virtual void view_char(int chval);
	virtual void view_click(const int button, const debug_view_xy& pos);

protected:
	// core view data
	debug_view *            m_next;             // link to the next view
	debug_view_type         m_type;             // type of view
	const debug_view_source *m_source;          // currently selected data source
	debug_view_source_list  m_source_list;      // list of available data sources

	// OSD data
	debug_view_osd_update_func m_osdupdate;     // callback for the update
	void *                  m_osdprivate;       // OSD-managed private data

	// visibility info
	debug_view_xy           m_visible;          // visible size (in rows and columns)
	debug_view_xy           m_total;            // total size (in rows and columns)
	debug_view_xy           m_topleft;          // top-left visible position (in rows and columns)
	debug_view_xy           m_cursor;           // cursor position
	bool                    m_supports_cursor;  // does this view support a cursor?
	bool                    m_cursor_visible;   // is the cursor visible?

	// update info
	bool                    m_recompute;        // does this view require a recomputation?
	UINT8                   m_update_level;     // update level; updates when this hits 0
	bool                    m_update_pending;   // true if there is a pending update
	bool                    m_osd_update_pending; // true if there is a pending update
	debug_view_char *       m_viewdata;         // current array of view data
	int                     m_viewdata_size;    // number of elements of the viewdata array

private:
	running_machine &       m_machine;          // machine associated with this view
};


// debug_view_manager manages all the views
class debug_view_manager
{
public:
	// construction/destruction
	debug_view_manager(running_machine &machine);
	~debug_view_manager();

	// getters
	running_machine &machine() const { return m_machine; }

	// view allocation
	debug_view *alloc_view(debug_view_type type, debug_view_osd_update_func osdupdate, void *osdprivate);
	void free_view(debug_view &view);

	// update helpers
	void update_all(debug_view_type type = DVT_NONE);
	void flush_osd_updates();

private:
	// private helpers
	debug_view *append(debug_view *view);

	// internal state
	running_machine &   m_machine;              // reference to our machine
	debug_view *        m_viewlist;             // list of views
};


// debug_view_expression is a helper for handling embedded expressions
class debug_view_expression
{
public:
	// construction/destruction
	debug_view_expression(running_machine &machine);
	~debug_view_expression();

	// getters
	running_machine &machine() const { return m_machine; }
	bool dirty() const { return m_dirty; }
	UINT64 last_value() const { return m_result; }
	UINT64 value() { recompute(); return m_result; }
	const char *string() const { return m_string; }
	symbol_table *context() const { return m_parsed.symbols(); }

	// setters
	void mark_dirty() { m_dirty = true; }
	void set_string(const char *string) { m_string.cpy(string); m_dirty = true; }
	void set_context(symbol_table *context);

private:
	// internal helpers
	bool recompute();

	// internal state
	running_machine &   m_machine;              // reference to the machine
	bool                m_dirty;                // true if the expression needs to be re-evaluated
	UINT64              m_result;               // last result from the expression
	parsed_expression   m_parsed;               // parsed expression data
	astring             m_string;               // copy of the expression string
};


#endif