summaryrefslogtreecommitdiffstatshomepage
path: root/trunk/src/emu/debugint/debugint.c
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/src/emu/debugint/debugint.c')
-rw-r--r--trunk/src/emu/debugint/debugint.c1484
1 files changed, 1484 insertions, 0 deletions
diff --git a/trunk/src/emu/debugint/debugint.c b/trunk/src/emu/debugint/debugint.c
new file mode 100644
index 00000000000..f02ef141acb
--- /dev/null
+++ b/trunk/src/emu/debugint/debugint.c
@@ -0,0 +1,1484 @@
+/*********************************************************************
+
+ debugint.c
+
+ Internal debugger frontend using render interface.
+
+ Copyright Nicola Salmoria and the MAME Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+*********************************************************************/
+
+#include "emu.h"
+#include "ui.h"
+#include "rendfont.h"
+#include "uimenu.h"
+#include "uiinput.h"
+#include "video.h"
+#include "osdepend.h"
+
+#include "debug/debugvw.h"
+#include "debug/dvdisasm.h"
+#include "debug/dvmemory.h"
+#include "debug/dvstate.h"
+#include "debug/debugcon.h"
+#include "debug/debugcpu.h"
+
+
+/***************************************************************************
+ CONSTANTS
+***************************************************************************/
+
+#define BORDER_YTHICKNESS 1
+#define BORDER_XTHICKNESS 1
+#define HSB_HEIGHT 20
+#define VSB_WIDTH 20
+#define TITLE_HEIGHT 20
+
+enum
+{
+ RECT_DVIEW,
+ RECT_DVIEW_CLIENT,
+ RECT_DVIEW_TITLE,
+ RECT_DVIEW_HSB,
+ RECT_DVIEW_VSB,
+ RECT_DVIEW_SIZE,
+};
+
+enum
+{
+ VIEW_STATE_BUTTON = 0x01,
+ VIEW_STATE_MOVING = 0x02,
+ VIEW_STATE_SIZING = 0x04,
+ VIEW_STATE_NEEDS_UPDATE = 0x08,
+ VIEW_STATE_FOLLOW_CPU = 0x10,
+};
+
+/***************************************************************************
+ MACROS
+***************************************************************************/
+
+//#define NX(_dv, _x) ((float) (_x)/(float)rect_get_width(&(_dv)->bounds))
+//#define NY(_dv, _y) ((float) (_y)/(float)rect_get_height(&(_dv)->bounds))
+#define NX(_dv, _x) ((float) (_x)/(float) (dv)->rt_width)
+#define NY(_dv, _y) ((float) (_y)/(float) (dv)->rt_height)
+
+
+#define LIST_ADD_FRONT(_list, _elem, _type) \
+ do { \
+ (_elem)->next = _list; \
+ _list = _elem; \
+ } while (0)
+
+#define LIST_GET_PREVIOUS(_list, _elem, _prev) \
+ do { \
+ _prev = NULL; \
+ if (_list != _elem) \
+ for (_prev = _list; _prev != NULL; _prev = _prev->next) \
+ if ((_prev)->next == _elem) \
+ break; \
+ } while (0)
+
+#define LIST_GET_LAST(_list, _last) \
+ do { \
+ for (_last = _list; _last != NULL; _last = _last->next) \
+ if ((_last)->next == NULL) \
+ break; \
+ } while (0)
+
+#define LIST_REMOVE(_list, _elem, _type) \
+ do { \
+ _type *_hlp; \
+ LIST_GET_PREVIOUS(_list, _elem, _hlp); \
+ if (_hlp != NULL) \
+ (_hlp)->next = (_elem)->next; \
+ else \
+ _list = (_elem)->next; \
+ } while (0)
+
+#define LIST_ADD_BACK(_list, _elem, _type) \
+ do { \
+ _type *_hlp; \
+ LIST_GET_LAST(_list, _hlp); \
+ if (_hlp != NULL) \
+ (_hlp)->next = _elem; \
+ else \
+ _list = _elem; \
+ } while (0)
+
+/***************************************************************************
+ TYPE DEFINITIONS
+***************************************************************************/
+
+typedef struct _adjustment adjustment;
+struct _adjustment
+{
+ int visible;
+ int lower;
+ int upper;
+ int value;
+ int step_increment;
+ int page_increment;
+ int page_size;
+};
+
+class DView;
+
+class DView_edit
+{
+ DISABLE_COPYING(DView_edit);
+
+public:
+ DView_edit()
+ { }
+ ~DView_edit()
+ { }
+ int active;
+ render_container * container;
+ astring str;
+};
+
+/***************************************************************************
+ FUNCTION PROTOTYPES
+***************************************************************************/
+
+static void dview_update(debug_view &dw, void *osdprivate);
+static int map_point(DView *dv, INT32 target_x, INT32 target_y, INT32 *mapped_x, INT32 *mapped_y);
+
+class DView
+{
+ DISABLE_COPYING(DView);
+
+public:
+ DView(render_target *target, running_machine &machine, debug_view_type type, int flags)
+ : next(NULL),
+ type(0),
+ state(0),
+ ofs_x(0),
+ ofs_y(0)
+ {
+ this->target = target;
+ //dv->container = render_target_get_component_container(target, name, &pos);
+ this->container = target->debug_alloc();
+ this->view = machine.debug_view().alloc_view(type, dview_update, this);
+ this->type = type;
+ this->m_machine = &machine;
+ this->state = flags | VIEW_STATE_NEEDS_UPDATE;
+
+ // initial size
+ this->bounds.min_x = 0;
+ this->bounds.min_y = 0;
+ this->bounds.max_x = 300;
+ this->bounds.max_y = 300;
+
+ /* specials */
+ switch (type)
+ {
+ case DVT_DISASSEMBLY:
+ /* set up disasm view */
+ downcast<debug_view_disasm *>(this->view)->set_expression("curpc");
+ //debug_view_ property_UINT32(dv->view, DVP_DASM_TRACK_LIVE, 1);
+ break;
+ default:
+ break;
+ }
+ }
+ ~DView()
+ {
+ this->target->debug_free(*this->container);
+ machine().debug_view().free_view(*this->view);
+ }
+
+ running_machine &machine() const { assert(m_machine != NULL); return *m_machine; }
+
+ DView * next;
+
+ int type;
+ debug_view * view;
+ render_container * container;
+ render_target * target;
+ running_machine * m_machine;
+ int state;
+ // drawing
+ rectangle bounds;
+ int ofs_x;
+ int ofs_y;
+ astring title;
+ int last_x;
+ int last_y;
+ // Scrollbars
+ adjustment hsb;
+ adjustment vsb;
+ // render target tracking
+ INT32 rt_width;
+ INT32 rt_height;
+ //optional
+ DView_edit editor;
+};
+
+
+/***************************************************************************
+ INLINE FUNCTIONS
+***************************************************************************/
+
+INLINE int rect_get_width(rectangle *r)
+{
+ return r->max_x - r->min_x + 1;
+}
+
+INLINE int rect_get_height(rectangle *r)
+{
+ return r->max_y - r->min_y + 1;
+}
+
+INLINE void rect_set_width(rectangle *r, int width)
+{
+ r->max_x = r->min_x + width - 1;
+}
+
+INLINE void rect_set_height(rectangle *r, int height)
+{
+ r->max_y = r->min_y + height - 1;
+}
+
+INLINE void rect_move(rectangle *r, int x, int y)
+{
+ int dx = x - r->min_x;
+ int dy = y - r->min_y;
+
+ r->min_x += dx;
+ r->max_x += dx;
+ r->min_y += dy;
+ r->max_y += dy;
+}
+
+INLINE int dview_is_state(DView *dv, int state)
+{
+ return ((dv->state & state) ? TRUE : FALSE);
+}
+
+INLINE int dview_is_state_all(DView *dv, int state)
+{
+ return ((dv->state & state) == state ? TRUE : FALSE);
+}
+
+INLINE void dview_set_state(DView *dv, int state, int onoff)
+{
+ if (onoff)
+ dv->state |= state;
+ else
+ dv->state &= ~state;
+}
+
+/***************************************************************************
+ LOCAL VARIABLES
+***************************************************************************/
+
+static render_font * debug_font;
+static int debug_font_width;
+static int debug_font_height;
+static float debug_font_aspect;
+static DView * list;
+static DView * focus_view;
+
+static ui_menu * menu;
+static DView_edit * cur_editor;
+
+static void set_focus_view(DView *dv)
+{
+ if (focus_view != NULL)
+ dview_set_state(focus_view, VIEW_STATE_NEEDS_UPDATE, TRUE);
+
+ if (dv != NULL)
+ dview_set_state(dv, VIEW_STATE_NEEDS_UPDATE, TRUE);
+
+ if (focus_view != dv)
+ {
+ focus_view = dv;
+ LIST_REMOVE(list, dv, DView);
+ LIST_ADD_FRONT(list, dv, DView);
+ dv->target->debug_top(*dv->container);
+ }
+}
+
+static DView *dview_alloc(render_target *target, running_machine &machine, debug_view_type type, int flags)
+{
+ DView *dv;
+
+ dv = auto_alloc(machine, DView(target, machine, type, flags));
+
+ /* add to list */
+
+ LIST_ADD_BACK(list, dv, DView);
+
+ return dv;
+}
+
+static void dview_free(DView *dv)
+{
+ //astring_free(dv->title);
+ LIST_REMOVE(list, dv, DView);
+ auto_free(dv->machine(), dv);
+}
+
+static void dview_get_rect(DView *dv, int type, rectangle *rect)
+{
+ *rect = dv->bounds;
+ switch (type)
+ {
+ case RECT_DVIEW:
+ break;
+ case RECT_DVIEW_CLIENT:
+ rect->min_x += BORDER_XTHICKNESS;
+ rect->max_x -= (BORDER_XTHICKNESS + dv->vsb.visible * VSB_WIDTH);
+ rect->min_y += 2 * BORDER_YTHICKNESS + TITLE_HEIGHT;
+ rect->max_y -= (BORDER_YTHICKNESS + dv->hsb.visible * HSB_HEIGHT);
+ break;
+ case RECT_DVIEW_HSB:
+ rect->min_x += 0;
+ rect->max_x -= /* dv->vsb.visible * */ VSB_WIDTH;
+ rect->min_y = dv->bounds.max_y - HSB_HEIGHT;
+ rect->max_y -= 0;
+ break;
+ case RECT_DVIEW_VSB:
+ rect->min_x = dv->bounds.max_x - VSB_WIDTH;
+ rect->max_x -= 0;
+ rect->min_y += TITLE_HEIGHT;
+ rect->max_y -= /* dv->hsb.visible * */ HSB_HEIGHT;
+ break;
+ case RECT_DVIEW_SIZE:
+ rect->min_x = dv->bounds.max_x - VSB_WIDTH;
+ rect->max_x -= 0;
+ rect->min_y = dv->bounds.max_y - HSB_HEIGHT;
+ rect->max_y -= 0;
+ break;
+ case RECT_DVIEW_TITLE:
+ rect->min_x += 0;
+ rect->max_x -= 0;
+ rect->min_y += 0;
+ rect->max_y = rect->min_y + TITLE_HEIGHT - 1;
+ break;
+ default:
+ assert_always(FALSE, "unknown rectangle type");
+ }
+}
+
+
+static void dview_clear(DView *dv)
+{
+ dv->container->empty();
+}
+
+static void dview_draw_outlined_box(DView *dv, int rtype, int x, int y, int w, int h, rgb_t bg)
+{
+ rectangle r;
+
+ dview_get_rect(dv, rtype, &r);
+ ui_draw_outlined_box(dv->container, NX(dv, x + r.min_x), NY(dv, y + r.min_y),
+ NX(dv, x + r.min_x + w), NY(dv, y + r.min_y + h), bg);
+}
+
+static void dview_draw_box(DView *dv, int rtype, int x, int y, int w, int h, rgb_t col)
+{
+ rectangle r;
+
+ dview_get_rect(dv, rtype, &r);
+ dv->container->add_rect(NX(dv, x + r.min_x), NY(dv, y + r.min_y),
+ NX(dv, x + r.min_x + w), NY(dv, y + r.min_y + h), col,
+ PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
+}
+
+static void dview_draw_char(DView *dv, int rtype, int x, int y, int h, rgb_t col, UINT16 ch)
+{
+ rectangle r;
+
+ dview_get_rect(dv, rtype, &r);
+ dv->container->add_char(
+ NX(dv, x + r.min_x),
+ NY(dv, y + r.min_y),
+ NY(dv, h),
+ debug_font_aspect,
+ //(float) rect_get_height(&dv->bounds) / (float) rect_get_width(&dv->bounds), //render_get_ui_aspect(),
+ col,
+ *debug_font,
+ ch);
+}
+
+static int dview_xy_in_rect(DView *dv, int type, int x, int y)
+{
+ rectangle r;
+
+ dview_get_rect(dv, type, &r);
+ if (x >= r.min_x && x <= r.max_x && y >= r.min_y && y <= r.max_y)
+ return TRUE;
+ return FALSE;
+}
+
+static void dview_draw_hsb(DView *dv)
+{
+ int vt;
+ int ts;
+ //int sz = SLIDER_SIZE;
+ int sz;
+ rectangle r;
+ adjustment *sb = &dv->hsb;
+
+ dview_get_rect(dv, RECT_DVIEW_HSB, &r);
+
+ dview_draw_outlined_box(dv, RECT_DVIEW_HSB, 0, 0, VSB_WIDTH,HSB_HEIGHT, MAKE_ARGB(0xff, 0xff, 0x00, 0x00));
+ dview_draw_outlined_box(dv, RECT_DVIEW_HSB, rect_get_width(&r) - VSB_WIDTH, 0, VSB_WIDTH, HSB_HEIGHT, MAKE_ARGB(0xff, 0xff, 0x00, 0x00));
+
+ ts = (r.max_x - r.min_x + 1) - 2 * VSB_WIDTH;
+
+ sz = (ts * (sb->page_size)) / (sb->upper - sb->lower);
+ ts = ts - sz;
+
+ vt = (ts * (sb->value - sb->lower)) / (sb->upper - sb->lower - sb->page_size) + sz / 2 + r.min_x + VSB_WIDTH;
+
+ dview_draw_outlined_box(dv, RECT_DVIEW_HSB, vt - sz / 2, 0, sz, HSB_HEIGHT, MAKE_ARGB(0xff, 0xff, 0x00, 0x00));
+}
+
+static void dview_draw_vsb(DView *dv)
+{
+ int vt;
+ int ts;
+ //int sz = SLIDER_SIZE;
+ int sz;
+ rectangle r;
+ adjustment *sb = &dv->vsb;
+
+ dview_get_rect(dv, RECT_DVIEW_VSB, &r);
+
+ dview_draw_outlined_box(dv, RECT_DVIEW_VSB, 0, rect_get_height(&r) - HSB_HEIGHT, VSB_WIDTH, HSB_HEIGHT, MAKE_ARGB(0xff, 0xff, 0x00, 0x00));
+ dview_draw_outlined_box(dv, RECT_DVIEW_VSB, 0, 0, VSB_WIDTH, HSB_HEIGHT, MAKE_ARGB(0xff, 0xff, 0x00, 0x00));
+
+ ts = (r.max_y - r.min_y + 1) - 2 * HSB_HEIGHT;
+
+ sz = (ts * (sb->page_size)) / (sb->upper - sb->lower);
+ ts = ts - sz;
+
+ vt = (ts * (sb->value - sb->lower)) / (sb->upper - sb->lower - sb->page_size) + sz / 2 + HSB_HEIGHT;
+
+ dview_draw_outlined_box(dv, RECT_DVIEW_VSB, 0, vt - sz / 2, VSB_WIDTH, sz, MAKE_ARGB(0xff, 0xff, 0x00, 0x00));
+}
+
+static void dview_draw_size(DView *dv)
+{
+ rectangle r;
+
+ dview_get_rect(dv, RECT_DVIEW_SIZE, &r);
+
+ dview_draw_outlined_box(dv, RECT_DVIEW_SIZE, 0, 0,
+ rect_get_width(&r),rect_get_height(&r), MAKE_ARGB(0xff, 0xff, 0xff, 0x00));
+}
+
+static void dview_set_title(DView *dv, astring title)
+{
+ if (dv->title.cmp(title) != 0)
+ {
+ dv->title = title;
+ dview_set_state(dv, VIEW_STATE_NEEDS_UPDATE, TRUE);
+ }
+}
+
+static void dview_draw_title(DView *dv)
+{
+ int i;
+ rgb_t col = MAKE_ARGB(0xff,0x00,0x00,0xff);
+ rectangle r;
+
+ dview_get_rect(dv, RECT_DVIEW_TITLE, &r);
+
+ if (dv == focus_view)
+ col = MAKE_ARGB(0xff,0x00,0x7f,0x00);
+
+ dview_draw_outlined_box(dv, RECT_DVIEW_TITLE, 0, 0, rect_get_width(&dv->bounds), TITLE_HEIGHT, col);
+
+ if (!dv->title)
+ return;
+
+ for (i=0; i<strlen(dv->title); i++)
+ {
+ dview_draw_char(dv, RECT_DVIEW_TITLE, i * debug_font_width + BORDER_XTHICKNESS,
+ BORDER_YTHICKNESS, debug_font_height, //r.max_y - 2 * BORDER_YTHICKNESS,
+ MAKE_ARGB(0xff,0xff,0xff,0xff), (UINT16) dv->title[i] );
+ }
+}
+
+static int dview_on_mouse(DView *dv, int mx, int my, int button)
+{
+ int clicked = (button && !dview_is_state(dv, VIEW_STATE_BUTTON));
+ int handled = TRUE;
+ int x,y;
+
+ if (button && dview_is_state_all(dv, VIEW_STATE_BUTTON | VIEW_STATE_MOVING))
+ {
+ int dx = mx - dv->last_x;
+ int dy = my - dv->last_y;
+
+ dv->ofs_x += dx;
+ dv->ofs_y += dy;
+ dv->last_x = mx;
+ dv->last_y = my;
+ dview_set_state(dv, VIEW_STATE_NEEDS_UPDATE, TRUE);
+ return TRUE;
+ }
+ else if (button && dview_is_state_all(dv, VIEW_STATE_BUTTON | VIEW_STATE_SIZING))
+ {
+ int dx = mx - dv->last_x;
+ int dy = my - dv->last_y;
+
+ dv->bounds.max_x += dx;
+ dv->bounds.max_y += dy;
+ dv->last_x = mx;
+ dv->last_y = my;
+ dview_set_state(dv, VIEW_STATE_NEEDS_UPDATE, TRUE);
+ return TRUE;
+ }
+ else
+ dview_set_state(dv, VIEW_STATE_MOVING | VIEW_STATE_SIZING, FALSE);
+
+ if (!map_point(dv, mx, my, &x, &y))
+ return FALSE;
+
+ if (dview_xy_in_rect(dv, RECT_DVIEW_TITLE, x, y))
+ {
+ /* on title, do nothing */
+ if (clicked) {
+ dv->last_x = mx;
+ dv->last_y = my;
+ set_focus_view(dv);
+ dview_set_state(dv, VIEW_STATE_MOVING, TRUE);
+ }
+ }
+ else if (dview_xy_in_rect(dv, RECT_DVIEW_HSB, x, y))
+ {
+ /* on horizontal scrollbar */
+ debug_view_xy pos;
+ adjustment *sb = &dv->hsb;
+
+ if (clicked)
+ {
+ rectangle r;
+ int xt;
+
+ dview_get_rect(dv, RECT_DVIEW_HSB, &r);
+ x -= r.min_x;
+
+ xt = (x - VSB_WIDTH) * (sb->upper - sb->lower) / (rect_get_width(&r) - 2 * dv->vsb.visible * VSB_WIDTH) + sb->lower;
+ if (x < VSB_WIDTH)
+ sb->value -= sb->step_increment;
+ else if (x > rect_get_width(&r) - VSB_WIDTH)
+ sb->value += sb->step_increment;
+ else if (xt < sb->value)
+ sb->value -= sb->page_increment;
+ else if (xt > sb->value)
+ sb->value += sb->page_increment;
+
+ if (sb->value < sb->lower)
+ sb->value = sb->lower;
+ if (sb->value > sb->upper)
+ sb->value = sb->upper;
+ }
+
+ pos = dv->view->visible_position();
+
+ if (sb->value != pos.x)
+ {
+ pos.x = sb->value;
+ dv->view->set_visible_position(pos);
+ dview_set_state(dv, VIEW_STATE_NEEDS_UPDATE, TRUE);
+ }
+ }
+ else if (dview_xy_in_rect(dv, RECT_DVIEW_VSB, x, y) )
+ {
+ /* on vertical scrollbar */
+ debug_view_xy pos;
+ adjustment *sb = &dv->vsb;
+
+ if (clicked)
+ {
+ rectangle r;
+ int yt;
+
+ dview_get_rect(dv, RECT_DVIEW_VSB, &r);
+ y -= r.min_y;
+ yt = (y - HSB_HEIGHT) * (sb->upper - sb->lower) / (rect_get_height(&r) - 2 * HSB_HEIGHT) + sb->lower;
+
+ if (y < HSB_HEIGHT)
+ sb->value -= sb->step_increment;
+ else if (y > rect_get_height(&r) - HSB_HEIGHT)
+ sb->value += sb->step_increment;
+ else if (yt < sb->value)
+ sb->value -= sb->page_increment;
+ else if (yt > sb->value)
+ sb->value += sb->page_increment;
+
+ if (sb->value < sb->lower)
+ sb->value = sb->lower;
+ if (sb->value > sb->upper)
+ sb->value = sb->upper;
+ }
+
+ pos = dv->view->visible_position();
+
+ if (sb->value != pos.y)
+ {
+ pos.y = sb->value;
+ dv->view->set_visible_position(pos);
+ dview_set_state(dv, VIEW_STATE_NEEDS_UPDATE, TRUE);
+ }
+ }
+ else if (dview_xy_in_rect(dv, RECT_DVIEW_SIZE, x, y))
+ {
+ /* on sizing area */
+ if (clicked)
+ {
+ dv->last_x = mx;
+ dv->last_y = my;
+ set_focus_view(dv);
+ dview_set_state(dv, VIEW_STATE_SIZING, TRUE);
+ }
+ }
+ else if (dview_xy_in_rect(dv, RECT_DVIEW_CLIENT, x, y))
+ {
+ y -= TITLE_HEIGHT;
+ if (dv->view->cursor_supported() && clicked && y >= 0)
+ {
+ debug_view_xy topleft = dv->view->visible_position();
+ debug_view_xy newpos;
+ newpos.x = topleft.x + x / debug_font_width;
+ newpos.y = topleft.y + y / debug_font_height;
+ dv->view->set_cursor_position(newpos);
+ dv->view->set_cursor_visible(true);
+ }
+ if (clicked)
+ set_focus_view(dv);
+ }
+ else
+ {
+ handled = FALSE;
+ }
+ dview_set_state(dv, VIEW_STATE_BUTTON, button);
+ return handled;
+
+}
+
+INLINE void map_attr_to_fg_bg(unsigned char attr, rgb_t *fg, rgb_t *bg)
+{
+
+ *bg = MAKE_ARGB(0xff,0xff,0xff,0xff);
+ *fg = MAKE_ARGB(0xff,0x00,0x00,0x00);
+
+ if(attr & DCA_ANCILLARY)
+ *bg = MAKE_ARGB(0xff,0xe0,0xe0,0xe0);
+ if(attr & DCA_SELECTED) {
+ *bg = MAKE_ARGB(0xff,0xff,0x80,0x80);
+ }
+ if(attr & DCA_CURRENT) {
+ *bg = MAKE_ARGB(0xff,0xff,0xff,0x00);
+ }
+ if(attr & DCA_CHANGED) {
+ *fg = MAKE_ARGB(0xff,0xff,0x00,0x00);
+ }
+ if(attr & DCA_INVALID) {
+ *fg = MAKE_ARGB(0xff,0x00,0x00,0xff);
+ }
+ if(attr & DCA_DISABLED) {
+ *fg = MAKE_ARGB(RGB_ALPHA(*fg),
+ (RGB_RED(*fg)+RGB_RED(*bg)) >> 1,
+ (RGB_GREEN(*fg)+RGB_GREEN(*bg)) >> 1,
+ (RGB_BLUE(*fg)+RGB_BLUE(*bg)) >> 1);
+ }
+ if(attr & DCA_COMMENT) {
+ *fg = MAKE_ARGB(0xff,0x00,0x80,0x00);
+ }
+}
+
+static void dview_draw(DView *dv)
+{
+ const debug_view_char *viewdata;
+ debug_view_xy vsize;
+ UINT32 i, j, xx, yy;
+ rgb_t bg_base, bg, fg;
+ rectangle r;
+
+ vsize = dv->view->visible_size();
+
+ bg_base = MAKE_ARGB(0xff,0xff,0xff,0xff);
+
+ /* always start clean */
+ dview_clear(dv);
+
+ dview_draw_title(dv);
+
+ dview_get_rect(dv, RECT_DVIEW_CLIENT, &r);
+
+ dview_draw_outlined_box(dv, RECT_DVIEW_CLIENT, 0, 0,
+ rect_get_width(&r) /*- (dv->vs ? VSB_WIDTH : 0)*/,
+ rect_get_height(&r) /*- (dv->hsb.visible ? HSB_HEIGHT : 0)*/, bg_base);
+
+ /* background first */
+ viewdata = dv->view->viewdata();
+
+ yy = BORDER_YTHICKNESS;
+ for(j=0; j<vsize.y; j++)
+ {
+ xx = BORDER_XTHICKNESS;
+ for(i=0; i<vsize.x; i++)
+ {
+ map_attr_to_fg_bg(viewdata->attrib, &fg, &bg);
+
+ if (bg != bg_base)
+ dview_draw_box(dv, RECT_DVIEW_CLIENT, xx, yy,
+ debug_font_width, debug_font_height, bg);
+ xx += debug_font_width;
+ viewdata++;
+ }
+ yy += debug_font_height;
+ }
+
+ /* now the text */
+ viewdata = dv->view->viewdata();
+
+ yy = BORDER_YTHICKNESS;
+ for(j=0; j<vsize.y; j++)
+ {
+ xx = BORDER_XTHICKNESS;
+ for(i=0; i<vsize.x; i++)
+ {
+ UINT16 s;
+ unsigned char v = viewdata->byte;
+
+ if (v != ' ')
+ {
+ if(v < 128) {
+ s = v;
+ } else {
+ s = 0xc0 | (v>>6);
+ s |= (0x80 | (v & 0x3f));
+ }
+ map_attr_to_fg_bg(viewdata->attrib, &fg, &bg);
+
+ dview_draw_char(dv, RECT_DVIEW_CLIENT, xx, yy, debug_font_height, fg, s);
+ }
+ xx += debug_font_width;
+ viewdata++;
+ }
+ yy += debug_font_height;
+ }
+
+ if(dv->hsb.visible)
+ dview_draw_hsb(dv);
+ if(dv->vsb.visible)
+ dview_draw_vsb(dv);
+ dview_draw_size(dv);
+}
+
+
+static void dview_size_allocate(DView *dv)
+{
+ debug_view_xy size, pos, col, vsize;
+ render_container::user_settings rcus;
+ rectangle r;
+
+ dv->container->get_user_settings(rcus);
+ rcus.m_xoffset = (float) dv->ofs_x / (float) dv->rt_width;
+ rcus.m_yoffset = (float) dv->ofs_y / (float) dv->rt_height;
+ rcus.m_xscale = 1.0; //(float) rect_get_width(&dv->bounds) / (float) dv->rt_width;
+ rcus.m_yscale = 1.0; //(float) rect_get_height(&dv->bounds) / (float) dv->rt_height;
+ dv->container->set_user_settings(rcus);
+ //printf("%d %d %d %d\n", wpos.min_x, wpos.max_x, wpos.min_y, wpos.max_y);
+
+ pos = dv->view->visible_position();
+ size = dv->view->total_size();
+
+ dv->hsb.visible = 0;
+ dv->vsb.visible = 0;
+ dview_get_rect(dv, RECT_DVIEW_CLIENT, &r);
+
+ dv->hsb.visible = (size.x * debug_font_width > rect_get_width(&r) ? 1 : 0);
+ dv->vsb.visible = (size.y * debug_font_height > rect_get_height(&r) ? 1 : 0);
+ dview_get_rect(dv, RECT_DVIEW_CLIENT, &r);
+
+ dv->hsb.visible = (size.x * debug_font_width > rect_get_width(&r) ? 1 : 0);
+ dv->vsb.visible = (size.y * debug_font_height > rect_get_height(&r) ? 1 : 0);
+ dview_get_rect(dv, RECT_DVIEW_CLIENT, &r);
+
+ col.y = (rect_get_height(&r) - 2 * BORDER_YTHICKNESS /*+ debug_font_height - 1*/) / debug_font_height;
+ col.x = (rect_get_width(&r) - 2 * BORDER_XTHICKNESS /*+ debug_font_width - 1*/) / debug_font_width;
+
+ vsize.y = size.y - pos.y;
+ vsize.x = size.x - pos.x;
+ if(vsize.y > col.y)
+ vsize.y = col.y;
+ else if(vsize.y < col.y) {
+ pos.y = size.y-col.y;
+ if(pos.y < 0)
+ pos.y = 0;
+ vsize.y = size.y-pos.y;
+ }
+ if(vsize.x > col.x)
+ vsize.x = col.x;
+ else if(vsize.x < col.x) {
+ pos.x = size.x-col.x;
+ if(pos.x < 0)
+ pos.x = 0;
+ vsize.x = size.x-pos.x;
+ }
+
+ dv->view->set_visible_position(pos);
+ dv->view->set_visible_size(vsize);
+
+ if(dv->hsb.visible) {
+ int span = (rect_get_width(&r) - 2 * BORDER_XTHICKNESS) / debug_font_width;
+
+ if(pos.x + span > size.x)
+ pos.x = size.x - span;
+ if(pos.x < 0)
+ pos.x = 0;
+ dv->hsb.lower = 0;
+ dv->hsb.upper = size.x;
+ dv->hsb.value = pos.x;
+ dv->hsb.step_increment = 1;
+ dv->hsb.page_increment = span;
+ dv->hsb.page_size = span;
+
+ dv->view->set_visible_position(pos);
+ }
+
+ if(dv->vsb.visible) {
+ int span = (rect_get_height(&r) - 2 * BORDER_YTHICKNESS) / debug_font_height;
+
+ if(pos.y + span > size.y)
+ pos.y = size.y - span;
+ if(pos.y < 0)
+ pos.y = 0;
+ dv->vsb.lower = 0;
+ dv->vsb.upper = size.y;
+ dv->vsb.value = pos.y;
+ dv->vsb.step_increment = 1;
+ dv->vsb.page_increment = span;
+ dv->vsb.page_size = span;
+
+ dv->view->set_visible_position(pos);
+ }
+}
+
+static void dview_update(debug_view &dw, void *osdprivate)
+{
+ DView *dv = (DView *) osdprivate;
+
+ dview_set_state(dv, VIEW_STATE_NEEDS_UPDATE, TRUE);
+
+#if 0
+ debug_view_xy size = dw.total_size();
+
+ if((dv->tr != size.y) || (dv->tc != size.x))
+ gtk_widget_queue_resize(GTK_WIDGET(dv));
+ else
+ gtk_widget_queue_draw(GTK_WIDGET(dv));
+#endif
+}
+
+static void debugint_exit(running_machine &machine)
+{
+ for (DView *ndv = list; ndv != NULL; )
+ {
+ DView *temp = ndv;
+ ndv = ndv->next;
+ dview_free(temp);
+ }
+ if (debug_font != NULL)
+ {
+ machine.render().font_free(debug_font);
+ debug_font = NULL;
+ }
+
+}
+
+void debugint_init(running_machine &machine)
+{
+ unicode_char ch;
+ int chw;
+ debug_font = machine.render().font_alloc("ui.bdf"); //ui_get_font(machine);
+ debug_font_width = 0;
+ debug_font_height = 15;
+
+ menu = NULL;
+ cur_editor = NULL;
+ list = NULL;
+ focus_view = NULL;
+
+ debug_font_aspect = machine.render().ui_aspect();
+
+ for (ch=0;ch<=127;ch++)
+ {
+ chw = debug_font->char_width(debug_font_height, debug_font_aspect, ch);
+ if (chw>debug_font_width)
+ debug_font_width = chw;
+ }
+ debug_font_width++;
+ /* FIXME: above does not really work */
+ debug_font_width = 10;
+ machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(debugint_exit), &machine));
+}
+
+#if 0
+static void set_view_by_name(render_target *target, const char *name)
+{
+ int i = 0;
+ const char *s;
+
+ for (i = 0; ; i++ )
+ {
+ s = target->view_name(i);
+ if (s == NULL)
+ return;
+ //printf("%d %s\n", i, s);
+ if (strcmp(name, s) == 0)
+ {
+ target->set_view(i);
+ //printf("%d\n", target->view() );
+ return;
+ }
+ }
+}
+#endif
+
+/*-------------------------------------------------
+ Menu Callbacks
+ -------------------------------------------------*/
+
+static void process_string(DView *dv, const char *str)
+{
+ switch (dv->type)
+ {
+ case DVT_DISASSEMBLY:
+ downcast<debug_view_disasm *>(dv->view)->set_expression(str);
+ break;
+ case DVT_CONSOLE:
+ if(!dv->editor.str[(long)0])
+ debug_cpu_get_visible_cpu(dv->machine())->debug()->single_step();
+ else
+ debug_console_execute_command(dv->machine(), str, 1);
+ break;
+ case DVT_MEMORY:
+ downcast<debug_view_memory *>(dv->view)->set_expression(str);
+ break;
+ }
+}
+
+static void on_memory_window_activate(DView *dv, const ui_menu_event *event)
+{
+}
+
+static void on_disassembly_window_activate(DView *dv, const ui_menu_event *event)
+{
+ DView *ndv;
+ render_target *target;
+ const debug_view_source *source;
+
+ target = &dv->machine().render().ui_target();
+
+ ndv = dview_alloc(target, dv->machine(), DVT_DISASSEMBLY, 0);
+ ndv->editor.active = TRUE;
+ ndv->editor.container = &dv->machine().render().ui_container();
+ source = ndv->view->source();
+ dview_set_title(ndv, source->name());
+ set_focus_view(ndv);
+
+}
+
+static void on_disasm_cpu_activate(DView *dv, const ui_menu_event *event)
+{
+ const debug_view_source *current = dv->view->source();
+
+ if (event->iptkey == IPT_UI_RIGHT)
+ {
+ current = current->next();
+ if (current == NULL)
+ {
+ current = dv->view->source_list().head();
+ }
+ dv->view->set_source(*current);
+ dview_set_state(dv, VIEW_STATE_NEEDS_UPDATE, TRUE);
+ dview_set_title(dv, current->name());
+ }
+}
+
+static void on_log_window_activate(DView *dv, const ui_menu_event *event)
+{
+ DView *ndv;
+ render_target *target;
+
+ target = &dv->machine().render().ui_target();
+ ndv = dview_alloc(target, dv->machine(), DVT_LOG, 0);
+ dview_set_title(ndv, "Log");
+ set_focus_view(ndv);
+}
+
+static void on_close_activate(DView *dv, const ui_menu_event *event)
+{
+ if (focus_view == dv)
+ set_focus_view(dv->next);
+ dview_free(dv);
+}
+
+static void on_run_activate(DView *dv, const ui_menu_event *event)
+{
+ debug_cpu_get_visible_cpu(dv->machine())->debug()->go();
+}
+
+#if 0
+void on_run_h_activate(DView *dv, const ui_menu_event *event)
+{
+ debugwin_show(0);
+ debug_cpu_get_visible_cpu(dv->machine())->debug()->go();
+}
+#endif
+
+static void on_run_cpu_activate(DView *dv, const ui_menu_event *event)
+{
+ debug_cpu_get_visible_cpu(dv->machine())->debug()->go_next_device();
+}
+
+static void on_run_irq_activate(DView *dv, const ui_menu_event *event)
+{
+ debug_cpu_get_visible_cpu(dv->machine())->debug()->go_interrupt();
+}
+
+static void on_run_vbl_activate(DView *dv, const ui_menu_event *event)
+{
+ debug_cpu_get_visible_cpu(dv->machine())->debug()->go_vblank();
+}
+
+static void on_step_into_activate(DView *dv, const ui_menu_event *event)
+{
+ debug_cpu_get_visible_cpu(dv->machine())->debug()->single_step();
+}
+
+static void on_step_over_activate(DView *dv, const ui_menu_event *event)
+{
+ debug_cpu_get_visible_cpu(dv->machine())->debug()->single_step_over();
+}
+
+#ifdef UNUSED_CODE
+static void on_step_out_activate(DView *dv, const ui_menu_event *event)
+{
+ debug_cpu_get_visible_cpu(dv->machine())->debug()->single_step_out();
+}
+#endif
+
+static void on_hard_reset_activate(DView *dv, const ui_menu_event *event)
+{
+ dv->machine().schedule_hard_reset();
+}
+
+static void on_soft_reset_activate(DView *dv, const ui_menu_event *event)
+{
+ dv->machine().schedule_soft_reset();
+ debug_cpu_get_visible_cpu(dv->machine())->debug()->go();
+}
+
+static void on_exit_activate(DView *dv, const ui_menu_event *event)
+{
+ dv->machine().schedule_exit();
+}
+
+static void on_view_opcodes_activate(DView *dv, const ui_menu_event *event)
+{
+ debug_view_disasm *dasmview = downcast<debug_view_disasm *>(focus_view->view);
+ disasm_right_column rc = dasmview->right_column();
+ disasm_right_column new_rc = DASM_RIGHTCOL_NONE;
+
+ if (event->iptkey == IPT_UI_RIGHT)
+ {
+ switch (rc)
+ {
+ case DASM_RIGHTCOL_RAW: new_rc = DASM_RIGHTCOL_ENCRYPTED; break;
+ case DASM_RIGHTCOL_ENCRYPTED: new_rc = DASM_RIGHTCOL_COMMENTS; break;
+ case DASM_RIGHTCOL_COMMENTS: new_rc = DASM_RIGHTCOL_RAW; break;
+ default: break;
+ }
+ dasmview->set_right_column(new_rc);
+ dview_set_state(dv, VIEW_STATE_NEEDS_UPDATE, TRUE);
+ }
+}
+
+static void on_run_to_cursor_activate(DView *dv, const ui_menu_event *event)
+{
+ char command[64];
+
+ if (dv->view->cursor_visible() && debug_cpu_get_visible_cpu(dv->machine()) == dv->view->source()->device())
+ {
+ offs_t address = downcast<debug_view_disasm *>(dv->view)->selected_address();
+ sprintf(command, "go %X", address);
+ debug_console_execute_command(dv->machine(), command, 1);
+ }
+}
+
+/*-------------------------------------------------
+ editor
+ -------------------------------------------------*/
+
+static void render_editor(DView_edit *editor)
+{
+ float width, maxwidth;
+ float x1, y1, x2, y2;
+
+ editor->container->empty();
+ /* get the size of the text */
+ ui_draw_text_full(editor->container, editor->str, 0.0f, 0.0f, 1.0f, JUSTIFY_CENTER, WRAP_TRUNCATE,
+ DRAW_NONE, ARGB_WHITE, ARGB_BLACK, &width, NULL);
+ width += 2 * UI_BOX_LR_BORDER;
+ maxwidth = MAX(width, 0.5);
+
+ /* compute our bounds */
+ x1 = 0.5f - 0.5f * maxwidth;
+ x2 = x1 + maxwidth;
+ y1 = 0.25f;
+ y2 = 0.45f - UI_BOX_TB_BORDER;
+
+ /* draw a box */
+ ui_draw_outlined_box(editor->container, x1, y1, x2, y2, UI_BACKGROUND_COLOR);
+
+ /* take off the borders */
+ x1 += UI_BOX_LR_BORDER;
+ x2 -= UI_BOX_LR_BORDER;
+ y1 += UI_BOX_TB_BORDER;
+ y2 -= UI_BOX_TB_BORDER;
+
+ /* draw the text within it */
+ ui_draw_text_full(editor->container, editor->str, x1, y1, x2 - x1, JUSTIFY_CENTER, WRAP_TRUNCATE,
+ DRAW_NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, NULL, NULL);
+
+}
+
+/*-------------------------------------------------
+ menu_main_populate - populate the main menu
+ -------------------------------------------------*/
+
+static void CreateMainMenu(running_machine &machine)
+{
+ const char *subtext = "";
+ int rc;
+ astring title;
+
+ if (menu != NULL)
+ ui_menu_free(menu);
+ menu = ui_menu_alloc(machine, &machine.render().ui_container(),NULL,NULL);
+
+ switch (focus_view->type)
+ {
+ case DVT_DISASSEMBLY:
+ title = "Disassembly:";
+ break;
+ case DVT_CONSOLE:
+ title = "Console:";
+ break;
+ case DVT_LOG:
+ title = "Log:";
+ break;
+ case DVT_MEMORY:
+ title = "Memory:";
+ break;
+ case DVT_STATE:
+ title = "State:";
+ break;
+ }
+
+ ui_menu_item_append(menu, title.cat(focus_view->title), NULL, MENU_FLAG_DISABLE, NULL);
+ ui_menu_item_append(menu, MENU_SEPARATOR_ITEM, NULL, 0, NULL);
+
+ switch (focus_view->type)
+ {
+ case DVT_DISASSEMBLY:
+ {
+ rc = downcast<debug_view_disasm *>(focus_view->view)->right_column();
+ switch(rc)
+ {
+ case DASM_RIGHTCOL_RAW: subtext = "Raw Opcodes"; break;
+ case DASM_RIGHTCOL_ENCRYPTED: subtext = "Enc Opcodes"; break;
+ case DASM_RIGHTCOL_COMMENTS: subtext = "Comments"; break;
+ }
+ ui_menu_item_append(menu, "View", subtext, MENU_FLAG_RIGHT_ARROW, (void *)on_view_opcodes_activate);
+ ui_menu_item_append(menu, "Run to cursor", NULL, 0, (void *)on_run_to_cursor_activate);
+
+ if (!dview_is_state(focus_view, VIEW_STATE_FOLLOW_CPU))
+ {
+ ui_menu_item_append(menu, "CPU", focus_view->view->source()->name(), MENU_FLAG_RIGHT_ARROW, (void *)on_disasm_cpu_activate);
+ }
+ ui_menu_item_append(menu, MENU_SEPARATOR_ITEM, NULL, 0, NULL);
+ break;
+ }
+ }
+
+ /* add input menu items */
+
+ ui_menu_item_append(menu, "New Memory Window", NULL, 0, (void *)on_memory_window_activate);
+ ui_menu_item_append(menu, "New Disassembly Window", NULL, 0, (void *)on_disassembly_window_activate);
+ ui_menu_item_append(menu, "New Error Log Window", NULL, 0, (void *)on_log_window_activate);
+ ui_menu_item_append(menu, MENU_SEPARATOR_ITEM, NULL, 0, NULL);
+ ui_menu_item_append(menu, "Run", NULL, 0, (void *)on_run_activate);
+ ui_menu_item_append(menu, "Run to Next CPU", NULL, 0, (void *)on_run_cpu_activate);
+ ui_menu_item_append(menu, "Run until Next Interrupt on This CPU", NULL, 0, (void *)on_run_irq_activate);
+ ui_menu_item_append(menu, "Run until Next VBLANK", NULL, 0, (void *)on_run_vbl_activate);
+ ui_menu_item_append(menu, MENU_SEPARATOR_ITEM, NULL, 0, NULL);
+ ui_menu_item_append(menu, "Step Into", NULL, 0, (void *)on_step_into_activate);
+ ui_menu_item_append(menu, "Step Over", NULL, 0, (void *)on_step_over_activate);
+ ui_menu_item_append(menu, MENU_SEPARATOR_ITEM, NULL, 0, NULL);
+ ui_menu_item_append(menu, "Soft Reset", NULL, 0, (void *)on_soft_reset_activate);
+ ui_menu_item_append(menu, "Hard Reset", NULL, 0, (void *)on_hard_reset_activate);
+ ui_menu_item_append(menu, MENU_SEPARATOR_ITEM, NULL, 0, NULL);
+ if (!dview_is_state(focus_view, VIEW_STATE_FOLLOW_CPU))
+ ui_menu_item_append(menu, "Close Window", NULL, 0, (void *)on_close_activate);
+ ui_menu_item_append(menu, "Exit", NULL, 0, (void *)on_exit_activate);
+}
+
+static int map_point(DView *dv, INT32 target_x, INT32 target_y, INT32 *mapped_x, INT32 *mapped_y)
+{
+ rectangle pos;
+
+ /* default to point not mapped */
+ *mapped_x = -1;
+ *mapped_y = -1;
+
+ pos = dv->bounds;
+ pos.min_x += dv->ofs_x;
+ pos.max_x += dv->ofs_x;
+ pos.min_y += dv->ofs_y;
+ pos.max_y += dv->ofs_y;
+ //render_target_get_component_container(target, name, &pos);
+
+ if (target_x >= pos.min_x && target_x <= pos.max_x && target_y >= pos.min_y && target_y <= pos.max_y)
+ {
+ *mapped_x = target_x - pos.min_x;
+ *mapped_y = target_y - pos.min_y;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void handle_mouse(running_machine &machine)
+{
+ render_target * mouse_target;
+ INT32 x,y;
+ int button;
+
+ if (menu != NULL)
+ return;
+
+ mouse_target = ui_input_find_mouse(machine, &x, &y, &button);
+
+ if (mouse_target == NULL)
+ return;
+ //printf("mouse %d %d %d\n", x, y, button);
+
+ for (DView *dv = list; dv != NULL; dv = dv->next)
+ {
+ if (mouse_target == dv->target)
+ {
+ if (dview_on_mouse(dv, x, y, button))
+ break;
+ }
+ }
+}
+
+
+/*-------------------------------------------------
+ handle_editor - handle the editor
+-------------------------------------------------*/
+
+static void handle_editor(running_machine &machine)
+{
+ if (focus_view->editor.active)
+ {
+ ui_event event;
+
+ /* loop while we have interesting events */
+ while (ui_input_pop_event(machine, &event))
+ {
+ switch (event.event_type)
+ {
+ case UI_EVENT_CHAR:
+ /* if it's a backspace and we can handle it, do so */
+ if ((event.ch == 8 || event.ch == 0x7f) && focus_view->editor.str.len() > 0)
+ {
+ /* autoschow */
+ cur_editor = &focus_view->editor;
+ cur_editor->str = cur_editor->str.substr(0, cur_editor->str.len()-1);
+ }
+ /* if it's any other key and we're not maxed out, update */
+ else if (event.ch >= ' ' && event.ch < 0x7f)
+ {
+ char buf[10];
+ int ret;
+ /* autoschow */
+ cur_editor = &focus_view->editor;
+ ret = utf8_from_uchar(buf, 10, event.ch);
+ buf[ret] = 0;
+ cur_editor->str = cur_editor->str.cat(buf);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ if (cur_editor != NULL)
+ {
+ render_editor(cur_editor);
+ if (ui_input_pressed(machine, IPT_UI_SELECT))
+ {
+ process_string(focus_view, focus_view->editor.str);
+ focus_view->editor.str = "";
+ cur_editor = NULL;
+ }
+ if (ui_input_pressed(machine, IPT_UI_CANCEL))
+ cur_editor = NULL;
+ }
+ }
+
+}
+
+
+/*-------------------------------------------------
+ menu_main - handle the main menu
+-------------------------------------------------*/
+
+static void handle_menus(running_machine &machine)
+{
+ const ui_menu_event *event;
+
+ machine.render().ui_container().empty();
+ ui_input_frame_update(machine);
+ if (menu != NULL)
+ {
+ /* process the menu */
+ event = ui_menu_process(machine, menu, 0);
+ if (event != NULL && (event->iptkey == IPT_UI_SELECT || (event->iptkey == IPT_UI_RIGHT)))
+ {
+ //ui_menu_free(menu);
+ //menu = NULL;
+ ((void (*)(DView *, const ui_menu_event *)) event->itemref)(focus_view, event);
+ //ui_menu_stack_push(ui_menu_alloc(machine, menu->container, (ui_menu_handler_func)event->itemref, NULL));
+ CreateMainMenu(machine);
+ }
+ else if (ui_input_pressed(machine, IPT_UI_CONFIGURE))
+ {
+ ui_menu_free(menu);
+ menu = NULL;
+ }
+ }
+ else
+ {
+ /* turn on menus if requested */
+ if (ui_input_pressed(machine, IPT_UI_CONFIGURE))
+ CreateMainMenu(machine);
+ /* turn on editor if requested */
+ //if (ui_input_pressed(machine, IPT_UI_UP) && focus_view->editor.active)
+ // cur_editor = &focus_view->editor;
+ handle_editor(machine);
+ }
+}
+
+//============================================================
+// followers_set_cpu
+//============================================================
+
+static void followers_set_cpu(device_t *device)
+{
+ astring title;
+
+ for (DView *dv = list; dv != NULL; dv = dv->next)
+ {
+ if (dview_is_state(dv, VIEW_STATE_FOLLOW_CPU))
+ {
+ const debug_view_source *source = dv->view->source_list().match_device(device);
+ switch (dv->type)
+ {
+ case DVT_DISASSEMBLY:
+ case DVT_STATE:
+ dv->view->set_source(*source);
+ title.printf("%s", source->name());
+ dview_set_title(dv, title);
+ break;
+ }
+ }
+ }
+ // and recompute the children
+ //console_recompute_children(main_console);
+}
+
+
+static void dview_update_view(DView *dv)
+{
+ INT32 old_rt_width = dv->rt_width;
+ INT32 old_rt_height = dv->rt_height;
+
+ dv->rt_width = dv->target->width();
+ dv->rt_height = dv->target->height();
+ if (dview_is_state(dv, VIEW_STATE_NEEDS_UPDATE) || dv->rt_width != old_rt_width || dv->rt_height != old_rt_height)
+ {
+ dview_size_allocate(dv);
+ dview_draw(dv);
+ dview_set_state(dv, VIEW_STATE_NEEDS_UPDATE, FALSE);
+ }
+}
+
+
+static void update_views(void)
+{
+ DView *dv, *prev;
+
+ LIST_GET_LAST(list, dv);
+ while (dv != NULL)
+ {
+ dview_update_view(dv);
+ LIST_GET_PREVIOUS(list, dv, prev);
+ dv = prev;
+ }
+}
+
+
+void debugint_wait_for_debugger(device_t &device, bool firststop)
+{
+
+ if (firststop && list == NULL)
+ {
+ DView *dv;
+ render_target *target;
+
+ target = &device.machine().render().ui_target();
+
+ //set_view_by_name(target, "Debug");
+
+ dv = dview_alloc(target, device.machine(), DVT_DISASSEMBLY, VIEW_STATE_FOLLOW_CPU);
+ dv->editor.active = TRUE;
+ dv->editor.container = &device.machine().render().ui_container();
+ dv = dview_alloc(target, device.machine(), DVT_STATE, VIEW_STATE_FOLLOW_CPU);
+ dv = dview_alloc(target, device.machine(), DVT_CONSOLE, VIEW_STATE_FOLLOW_CPU);
+ dview_set_title(dv, "Console");
+ dv->editor.active = TRUE;
+ dv->editor.container = &device.machine().render().ui_container();
+ set_focus_view(dv);
+ }
+
+ followers_set_cpu(&device);
+
+ //ui_update_and_render(device.machine(), device.machine().render().ui_container()());
+ update_views();
+ device.machine().osd().update(false);
+ handle_menus(device.machine());
+ handle_mouse(device.machine());
+ //osd_sleep(osd_ticks_per_second()/60);
+
+}
+
+void debugint_update_during_game(running_machine &machine)
+{
+ if (!debug_cpu_is_stopped(machine) && machine.phase() == MACHINE_PHASE_RUNNING)
+ {
+ update_views();
+ }
+}