//============================================================ // // debugwin.c - SDL/GTK+ debug window handling // // Copyright (c) 1996-2010, Nicola Salmoria and the MAME Team. // Visit http://mamedev.org for licensing and usage restrictions. // // SDLMAME by Olivier Galibert and R. Belmont // //============================================================ #if !defined(NO_DEBUGGER) #include #include #include "dview.h" #include "osdsdl.h" #include "debugger.h" #include "debug/dvdisasm.h" #include "debug/dvmemory.h" #include "debug/dvstate.h" #include "debug-intf.h" #include "debug-sup.h" #include "debug-cb.h" #include "config.h" //============================================================ // PARAMETERS //============================================================ #if 1 #define LOG(x...) #else #define LOG(x) printf x #endif #define MAX_VIEWS (4) enum { WIN_TYPE_MAIN = 0x01, WIN_TYPE_MEMORY = 0x02, WIN_TYPE_DISASM = 0x04, WIN_TYPE_LOG = 0x08, WIN_TYPE_ALL = 0x0f }; //============================================================ // TYPES //============================================================ struct hentry { struct hentry *h; char *e; }; struct win_i; struct edit { GtkEntry *edit_w; struct hentry *h, *ch; char *hold; int keep_last; void (*cb)(win_i *,const char *); win_i *cbp; }; struct win_i { int type; win_i * next; GtkWidget * win; edit ed; running_machine * machine; // machine DView * views[MAX_VIEWS]; device_t * cpu; // current CPU }; struct windowState { windowState() : type(0), sizeX(-1), sizeY(-1), positionX(-1), positionY(-1) { } ~windowState() { } void loadFromXmlDataNode(xml_data_node* wnode) { if (!wnode) return; type = xml_get_attribute_int(wnode, "type", type); sizeX = xml_get_attribute_int(wnode, "size_x", sizeX); sizeY = xml_get_attribute_int(wnode, "size_y", sizeY); positionX = xml_get_attribute_int(wnode, "position_x", positionX); positionY = xml_get_attribute_int(wnode, "position_y", positionY); } int type; int sizeX; int sizeY; int positionX; int positionY; }; windowState windowStateArray[64]; int windowStateCount = 0; //============================================================ // LOCAL VARIABLES //============================================================ static win_i *win_list; //============================================================ // PROTOTYPES //============================================================ static void debugmain_init(running_machine &machine); static void memorywin_new(running_machine &machine); static void disasmwin_new(running_machine &machine); static void logwin_new(running_machine &machine); //============================================================ // run_func_on_win_list //============================================================ static void run_func_on_win_list(void (*f)(GtkWidget *widget), int win_type_mask) { win_i *p; for(p = win_list; p; p = p->next) if ((p->type & win_type_mask) != 0) f(p->win); } //============================================================ // get_win_i //============================================================ static win_i *get_win_i(GtkWidget *win, int win_type_mask) { win_i *p; assert(win != NULL); LOG(("====== %p %x\n", win, win_type_mask)); for(p = win_list; p != NULL; p = p->next) { LOG(("%p %p %x\n", p, p->win, p->type)); if (((p->type & win_type_mask) != 0) && (win == p->win)) return p; } assert(0); return NULL; } //============================================================ // get_view //============================================================ static DView *get_view(win_i *win, int type) { int i; for (i=0; iviews[i]->dv_type == type) return win->views[i]; return 0; assert(0); } //============================================================ // get_running_machine //============================================================ static running_machine *get_running_machine(GtkWidget *win) { win_i *p = get_win_i(win, WIN_TYPE_ALL); return p->machine; /* fixme*/ } //============================================================ // get_first_win_i //============================================================ static win_i *get_first_win_i(int win_type_mask) { win_i *p; for(p = win_list; p; p = p->next) { if ((p->type & win_type_mask) != 0) return p; } return NULL; } //============================================================ // add_win_i //============================================================ static win_i *add_win_i(running_machine &machine, int win_type) { win_i *win = (win_i *) osd_malloc(sizeof(*win)); memset(win, 0, sizeof(*win)); win->cpu = NULL; win->machine = &machine; win->type = win_type; win->next = win_list; win_list = win; return win; } //============================================================ // remove_win_i //============================================================ static void remove_win_i(win_i *win) { win_i **p = &win_list; while(*p != win) p = &(*p)->next; if(win->next) *p = win->next; else *p = NULL; } //============================================================ // debugwin_show //============================================================ static void debugwin_show(int show) { void (*f)(GtkWidget *widget) = show ? gtk_widget_show : gtk_widget_hide; run_func_on_win_list(f, WIN_TYPE_ALL); } //============================================================ // edit_add_hist //============================================================ static void edit_add_hist(edit *e, const char *text) { if(e->ch) e->ch = 0; if(e->hold) { osd_free(e->hold); e->hold =0; } if(!e->h || (text[0] && strcmp(text, e->h->e))) { hentry *h = (hentry *) osd_malloc(sizeof(hentry)); h->h = e->h; h->e = mame_strdup(text); e->h = h; } } //============================================================ // edit_set_field //============================================================ static void edit_set_field(edit *e) { if(e->keep_last) { gtk_entry_set_text(e->edit_w, e->h->e); gtk_editable_select_region(GTK_EDITABLE(e->edit_w), 0, -1); } else gtk_entry_set_text(e->edit_w, ""); } //============================================================ // edit_activate //============================================================ static void edit_activate(GtkEntry *item, gpointer user_data) { edit *e = (edit *) user_data; const char *text = gtk_entry_get_text(e->edit_w); edit_add_hist(e, text); e->cb(e->cbp, text); edit_set_field(e); } //============================================================ // edit_hist_back //============================================================ static void edit_hist_back(edit *e) { const char *text = gtk_entry_get_text(e->edit_w); if(e->ch) { if(!e->ch->h) return; e->ch = e->ch->h; } else { if(!e->h) return; if(!strcmp(text, e->h->e)) { if(!e->h->h) return; e->ch = e->h->h; } else { if(text[0]) e->hold = mame_strdup(text); e->ch = e->h; } } gtk_entry_set_text(e->edit_w, e->ch->e); gtk_editable_select_region(GTK_EDITABLE(e->edit_w), 0, -1); } //============================================================ // dedit_hist_forward //============================================================ static void edit_hist_forward(edit *e) { hentry *h, *hp; if(!e->ch) return; h = e->h; hp = 0; while(h != e->ch) { hp = h; h = h->h; } if(hp) { e->ch = hp; gtk_entry_set_text(e->edit_w, hp->e); } else if(e->hold) { gtk_entry_set_text(e->edit_w, e->hold); osd_free(e->hold); e->hold = 0; e->ch = 0; } else { gtk_entry_set_text(e->edit_w, ""); e->ch = 0; } gtk_editable_select_region(GTK_EDITABLE(e->edit_w), 0, -1); } //============================================================ // edit_key //============================================================ static gboolean edit_key(GtkWidget *item, GdkEventKey *k, gpointer user_data) { edit *e = (edit *)user_data; switch(k->keyval) { case GDK_Up: edit_hist_back(e); return TRUE; case GDK_Down: edit_hist_forward(e); return TRUE; } return FALSE; } //============================================================ // edit_init //============================================================ static void edit_init(edit *e, GtkWidget *w, const char *ft, int kl, void (*cb)(win_i *, const char *), win_i *cbp) { e->edit_w = GTK_ENTRY(w); e->h = 0; e->ch = 0; e->hold = 0; e->keep_last = kl; e->cb = cb; e->cbp = cbp; if(ft) edit_add_hist(e, ft); edit_set_field(e); g_signal_connect(e->edit_w, "activate", G_CALLBACK(edit_activate), e); g_signal_connect(e->edit_w, "key-press-event", G_CALLBACK(edit_key), e); } //============================================================ // debugwin_show //============================================================ static void edit_del(edit *e) { hentry *h = e->h; while(h) { hentry *he = h->h; osd_free(h->e); osd_free(h); h = he; } } //============================================================ // disasmview_update_checks //============================================================ static void disasmview_update_checks(win_i *info) { DView *disasm; assert(info != NULL); // assert(info->type == WIN_TYPE_MAIN); disasm = get_view(info, DVT_DISASSEMBLY); int rc = downcast(disasm->view)->right_column(); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(lookup_widget(info->win, "raw_opcodes")), rc == DASM_RIGHTCOL_RAW); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(lookup_widget(info->win, "enc_opcodes")), rc == DASM_RIGHTCOL_ENCRYPTED); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(lookup_widget(info->win, "comments")), rc == DASM_RIGHTCOL_COMMENTS); } //============================================================ // debugmain_set_cpu //============================================================ static void debugmain_set_cpu(device_t *device) { win_i *dmain = get_first_win_i(WIN_TYPE_MAIN); DView *dv; if (device != dmain->cpu) { astring title; dmain->cpu = device; // first set all the views to the new cpu // FIXME: Iterate over all views ! dv = get_view(dmain, DVT_DISASSEMBLY); dv->view->set_source(*dv->view->source_list().match_device(device)); dv = get_view(dmain, DVT_STATE); dv->view->set_source(*dv->view->source_list().match_device(device)); // then update the caption title.printf("Debug: %s - %s '%s'", device->machine().system().name, device->name(), device->tag()); gtk_window_set_title(GTK_WINDOW(dmain->win), title); disasmview_update_checks(dmain); } } //============================================================ // configuration_load //============================================================ static void configuration_load(running_machine &machine, int config_type, xml_data_node *parentnode) { xml_data_node *wnode; /* we only care about game files */ if (config_type != CONFIG_TYPE_GAME) return; /* might not have any data */ if (parentnode == NULL) return; /* configuration load */ int i = 0; for (wnode = xml_get_sibling(parentnode->child, "window"); wnode != NULL; wnode = xml_get_sibling(wnode->next, "window")) { windowStateArray[i].loadFromXmlDataNode(wnode); i++; } windowStateCount = i; } //============================================================ // configuration_save //============================================================ static void configuration_save(running_machine &machine, int config_type, xml_data_node *parentnode) { /* we only care about game files */ if (config_type != CONFIG_TYPE_GAME) return; // Loop over all the nodes for(win_i *p = win_list; p != NULL; p = p->next) { /* create a node */ xml_data_node *debugger_node; debugger_node = xml_add_child(parentnode, "window", NULL); xml_set_attribute_int(debugger_node, "type", p->type); if (debugger_node != NULL) { int x, y; gtk_window_get_position(GTK_WINDOW(p->win), &x, &y); xml_set_attribute_int(debugger_node, "position_x", x); xml_set_attribute_int(debugger_node, "position_y", y); gtk_window_get_size(GTK_WINDOW(p->win), &x, &y); xml_set_attribute_int(debugger_node, "size_x", x); xml_set_attribute_int(debugger_node, "size_y", y); } } } //============================================================ // sdl_osd_interface::init_debugger //============================================================ void sdl_osd_interface::init_debugger() { /* register callbacks */ config_register(machine(), "debugger", config_saveload_delegate(FUNC(configuration_load), &machine()), config_saveload_delegate(FUNC(configuration_save), &machine())); } //============================================================ // wait_for_debugger //============================================================ void sdl_osd_interface::wait_for_debugger(device_t &device, bool firststop) { win_i *dmain = get_first_win_i(WIN_TYPE_MAIN); // Create a console window if one doesn't already exist if(!dmain) { // GTK init should probably be done earlier gtk_init(0, 0); debugmain_init(machine()); // Resize the main window for (int i = 0; i < windowStateCount; i++) { if (windowStateArray[i].type == WIN_TYPE_MAIN) { gtk_window_move(GTK_WINDOW(win_list->win), windowStateArray[i].positionX, windowStateArray[i].positionY); gtk_window_resize(GTK_WINDOW(win_list->win), windowStateArray[i].sizeX, windowStateArray[i].sizeY); } } // Respawn and reposition every other window for (int i = 0; i < windowStateCount; i++) { if (!windowStateArray[i].type || windowStateArray[i].type == WIN_TYPE_MAIN) continue; switch (windowStateArray[i].type) { case WIN_TYPE_MEMORY: memorywin_new(machine()); break; case WIN_TYPE_DISASM: disasmwin_new(machine()); break; case WIN_TYPE_LOG: logwin_new(machine()); break; default: break; } gtk_window_move(GTK_WINDOW(win_list->win), windowStateArray[i].positionX, windowStateArray[i].positionY); gtk_window_resize(GTK_WINDOW(win_list->win), windowStateArray[i].sizeX, windowStateArray[i].sizeY); } // Bring focus back to the main window gtk_window_present(GTK_WINDOW(get_first_win_i(WIN_TYPE_MAIN)->win)); } // update the views in the console to reflect the current CPU debugmain_set_cpu(&device); debugwin_show(1); gtk_main_iteration(); } //============================================================ // debugwin_update_during_game //============================================================ void debugwin_update_during_game(running_machine &machine) { win_i *dmain = get_first_win_i(WIN_TYPE_MAIN); if(dmain) { gtk_main_iteration_do(FALSE); } } //============================================================ // debugmain_process_string //============================================================ static void debugmain_process_string(win_i *win, const char *str) { if(!str[0]) debug_cpu_get_visible_cpu(*win->machine)->debug()->single_step(); else debug_console_execute_command(*win->machine, str, 1); } //============================================================ // debugmain_destroy //============================================================ static void debugmain_destroy(GtkObject *obj, gpointer user_data) { win_i *dmain = get_first_win_i(WIN_TYPE_MAIN); dmain->machine->schedule_exit(); } //============================================================ // debugmain_init //============================================================ static void debugmain_init(running_machine &machine) { win_i *dmain; dmain = add_win_i(machine, WIN_TYPE_MAIN); dmain->win = create_debugmain(); dmain->views[0] = DVIEW(lookup_widget(dmain->win, "console")); dmain->views[1] = DVIEW(lookup_widget(dmain->win, "disasm")); dmain->views[2] = DVIEW(lookup_widget(dmain->win, "registers")); dview_set_debug_view(dmain->views[0], machine, DVT_CONSOLE); dview_set_debug_view(dmain->views[1], machine, DVT_DISASSEMBLY); dview_set_debug_view(dmain->views[2], machine, DVT_STATE); edit_init(&dmain->ed, lookup_widget(dmain->win, "edit"), 0, 0, debugmain_process_string, dmain); /* set up disasm view */ downcast(dmain->views[1]->view)->set_expression("curpc"); // debug_view_set_property_UINT32(dmain->disasm, DVP_DASM_TRACK_LIVE, 1); g_signal_connect(dmain->win, "destroy", G_CALLBACK(debugmain_destroy), dmain); gtk_widget_show_all(dmain->win); } //============================================================ // memorywin_update_checks //============================================================ static void memorywin_update_checks(win_i *info) { DView *memory = get_view(info, DVT_MEMORY); debug_view_memory *memview = downcast(memory->view); int bpc = memview->bytes_per_chunk(); bool rev = memview->reverse(); bool pa = memview->physical(); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(lookup_widget(info->win, "chunks_1")), bpc == 1); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(lookup_widget(info->win, "chunks_2")), bpc == 2); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(lookup_widget(info->win, "chunks_4")), bpc == 4); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(lookup_widget(info->win, "physical_addresses")), pa); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(lookup_widget(info->win, "logical_addresses")), !pa); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(lookup_widget(info->win, "reverse")), rev); } //============================================================ // memorywin_zone_changed //============================================================ static void memorywin_zone_changed(GtkComboBox *zone_w, win_i *mem) { int sel = gtk_combo_box_get_active(zone_w); astring title; DView *memory = get_view(mem, DVT_MEMORY); assert(mem->type == WIN_TYPE_MEMORY); // update the source memory->view->set_source(*memory->view->source_list().by_index(sel)); // change the checkmarks in the menu memorywin_update_checks(mem); // update the window title const debug_view_source *source = memory->view->source(); title.printf("Memory: %s", source->name()); gtk_window_set_title(GTK_WINDOW(mem->win), title); } //============================================================ // memorywin_process_string //============================================================ static void memorywin_process_string(win_i *win, const char *str) { win_i *mem = (win_i *) win; DView *memory = get_view(mem, DVT_MEMORY); assert(mem->type == WIN_TYPE_MEMORY); downcast(memory->view)->set_expression(str); } //============================================================ // memorywin_destroy //============================================================ static void memorywin_destroy(GtkObject *obj, gpointer user_data) { win_i *mem = (win_i *) user_data; remove_win_i(mem); edit_del(&mem->ed); osd_free(mem); } //============================================================ // memorywin_new //============================================================ static void memorywin_new(running_machine &machine) { win_i *mem; int item; //, cursel; device_t *curcpu = debug_cpu_get_visible_cpu(machine); GtkComboBox * zone_w; mem = add_win_i(machine, WIN_TYPE_MEMORY); mem->win = create_memorywin(); mem->views[0] = DVIEW(lookup_widget(mem->win, "memoryview")); dview_set_debug_view(mem->views[0], machine, DVT_MEMORY); zone_w = GTK_COMBO_BOX(lookup_widget(mem->win, "zone")); edit_init(&mem->ed, lookup_widget(mem->win, "edit"), "0", 1, memorywin_process_string, mem); downcast(mem->views[0]->view)->set_expression("0"); // populate the combobox // cursel = 0; item = 0; for (const debug_view_source *source = mem->views[0]->view->source_list().head(); source != NULL; source = source->next()) { gtk_combo_box_append_text(zone_w, source->name()); item++; } const debug_view_source *source = mem->views[0]->view->source_list().match_device(curcpu); gtk_combo_box_set_active(zone_w, mem->views[0]->view->source_list().index(*source)); mem->views[0]->view->set_source(*source); g_signal_connect(zone_w, "changed", G_CALLBACK(memorywin_zone_changed), mem); g_signal_connect(mem->win, "destroy", G_CALLBACK(memorywin_destroy), mem); gtk_widget_show_all(mem->win); } //============================================================ // disasmwin_cpu_changed //============================================================ static void disasmwin_cpu_changed(GtkComboBox *cpu_w, win_i *dis) { astring title; DView *disasm = get_view(dis, DVT_DISASSEMBLY); disasm->view->set_source(*disasm->view->source_list().by_index(gtk_combo_box_get_active(cpu_w))); disasmview_update_checks(dis); const debug_view_source *source = disasm->view->source(); title.printf("Disassembly: %s", source->name()); gtk_window_set_title(GTK_WINDOW(dis->win), title); } //============================================================ // disasmwin_process_string //============================================================ static void disasmwin_process_string(win_i *win, const char *str) { win_i *dis = (win_i *) win; DView *disasm = get_view(dis, DVT_DISASSEMBLY); assert(dis->type == WIN_TYPE_DISASM); downcast(disasm->view)->set_expression(str); } //============================================================ // disasmwin_destroy //============================================================ static void disasmwin_destroy(GtkObject *obj, gpointer user_data) { win_i *dis = (win_i *) user_data; remove_win_i(dis); edit_del(&dis->ed); osd_free(dis); } //============================================================ // disasmwin_new //============================================================ static void disasmwin_new(running_machine &machine) { win_i *dis; int item; //, cursel; device_t *curcpu = debug_cpu_get_visible_cpu(machine); GtkComboBox *cpu_w; astring title; dis = add_win_i(machine, WIN_TYPE_DISASM); dis->win = create_disasmwin(); dis->views[0] = DVIEW(lookup_widget(dis->win, "disasmview")); dview_set_debug_view(dis->views[0], machine, DVT_DISASSEMBLY); cpu_w = GTK_COMBO_BOX(lookup_widget(dis->win, "cpu")); edit_init(&dis->ed, lookup_widget(dis->win, "edit"), "curpc", 1, disasmwin_process_string, dis); downcast(dis->views[0]->view)->set_expression("curpc"); // populate the combobox // cursel = 0; item = 0; for (const debug_view_source *source = dis->views[0]->view->source_list().head(); source != NULL; source = source->next()) { gtk_combo_box_append_text(cpu_w, source->name()); item++; } const debug_view_source *source = dis->views[0]->view->source_list().match_device(curcpu); gtk_combo_box_set_active(cpu_w, dis->views[0]->view->source_list().index(*source)); dis->views[0]->view->set_source(*source); title.printf("Disassembly: %s", source->name()); gtk_window_set_title(GTK_WINDOW(dis->win), title); g_signal_connect(cpu_w, "changed", G_CALLBACK(disasmwin_cpu_changed), dis); // g_signal_connect(dis->edit_w, "activate", G_CALLBACK(disasmwin_process_string), dis); g_signal_connect(dis->win, "destroy", G_CALLBACK(disasmwin_destroy), dis); gtk_widget_show_all(dis->win); } //============================================================ // logwin_destroy //============================================================ static void logwin_destroy(GtkObject *obj, gpointer user_data) { win_i *log = (win_i *) user_data; remove_win_i(log); osd_free(log); } //============================================================ // logwin_new //============================================================ static void logwin_new(running_machine &machine) { win_i *log; log = add_win_i(machine, WIN_TYPE_LOG); log->win = create_logwin(); log->views[0] = DVIEW(lookup_widget(log->win, "logview")); dview_set_debug_view(log->views[0], machine, DVT_LOG); g_signal_connect(log->win, "destroy", G_CALLBACK(logwin_destroy), log); gtk_widget_show_all(log->win); } //============================================================ // Menu Callbacks //============================================================ void on_raw_opcodes_activate(GtkWidget *win) { win_i *info = get_win_i(win, WIN_TYPE_MAIN | WIN_TYPE_DISASM); DView *disasm = get_view(info, DVT_DISASSEMBLY); if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(lookup_widget(info->win, "raw_opcodes")))) { downcast(disasm->view)->set_right_column(DASM_RIGHTCOL_RAW); } } void on_enc_opcodes_activate(GtkWidget *win) { win_i *info = get_win_i(win, WIN_TYPE_MAIN | WIN_TYPE_DISASM); DView *disasm = get_view(info, DVT_DISASSEMBLY); if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(lookup_widget(info->win, "enc_opcodes")))) { downcast(disasm->view)->set_right_column(DASM_RIGHTCOL_ENCRYPTED); } } void on_comments_activate(GtkWidget *win) { win_i *info = get_win_i(win, WIN_TYPE_MAIN | WIN_TYPE_DISASM); DView *disasm = get_view(info, DVT_DISASSEMBLY); if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(lookup_widget(info->win, "comments")))) { downcast(disasm->view)->set_right_column(DASM_RIGHTCOL_COMMENTS); } } void on_new_mem_activate(GtkWidget *win) { memorywin_new(*get_running_machine(win)); } void on_new_disasm_activate(GtkWidget *win) { disasmwin_new(*get_running_machine(win)); } void on_new_errorlog_activate(GtkWidget *win) { logwin_new(*get_running_machine(win)); } void on_run_activate(GtkWidget *win) { debug_cpu_get_visible_cpu(*get_running_machine(win))->debug()->go(); } void on_run_h_activate(GtkWidget *win) { debugwin_show(0); debug_cpu_get_visible_cpu(*get_running_machine(win))->debug()->go(); } void on_run_cpu_activate(GtkWidget *win) { debug_cpu_get_visible_cpu(*get_running_machine(win))->debug()->go_next_device(); } void on_run_irq_activate(GtkWidget *win) { debug_cpu_get_visible_cpu(*get_running_machine(win))->debug()->go_interrupt(); } void on_run_vbl_activate(GtkWidget *win) { debug_cpu_get_visible_cpu(*get_running_machine(win))->debug()->go_vblank(); } void on_step_into_activate(GtkWidget *win) { debug_cpu_get_visible_cpu(*get_running_machine(win))->debug()->single_step(); } void on_step_over_activate(GtkWidget *win) { debug_cpu_get_visible_cpu(*get_running_machine(win))->debug()->single_step_over(); } void on_step_out_activate(GtkWidget *win) { debug_cpu_get_visible_cpu(*get_running_machine(win))->debug()->single_step_out(); } void on_hard_reset_activate(GtkWidget *win) { get_running_machine(win)->schedule_hard_reset(); } void on_soft_reset_activate(GtkWidget *win) { get_running_machine(win)->schedule_soft_reset(); debug_cpu_get_visible_cpu(*get_running_machine(win))->debug()->go(); } void on_exit_activate(GtkWidget *win) { get_running_machine(win)->schedule_exit(); } void on_chunks_1_activate(GtkWidget *win) { win_i *info = get_win_i(win, WIN_TYPE_MEMORY); DView *memory = get_view(info, DVT_MEMORY); if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(lookup_widget(info->win, "chunks_1")))) { downcast(memory->view)->set_bytes_per_chunk(1); } } void on_chunks_2_activate(GtkWidget *win) { win_i *info = get_win_i(win, WIN_TYPE_MEMORY); DView *memory = get_view(info, DVT_MEMORY); if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(lookup_widget(info->win, "chunks_2")))) { downcast(memory->view)->set_bytes_per_chunk(2); } } void on_chunks_4_activate(GtkWidget *win) { win_i *info = get_win_i(win, WIN_TYPE_MEMORY); DView *memory = get_view(info, DVT_MEMORY); if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(lookup_widget(info->win, "chunks_4")))) { downcast(memory->view)->set_bytes_per_chunk(4); } } void on_logical_addresses_group_changed(GtkWidget *win) { win_i *info = get_win_i(win, WIN_TYPE_MEMORY); DView *memory = get_view(info, DVT_MEMORY); if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(lookup_widget(info->win, "logical_addresses")))) { downcast(memory->view)->set_physical(false); } } void on_physical_addresses_group_changed(GtkWidget *win) { win_i *info = get_win_i(win, WIN_TYPE_MEMORY); DView *memory = get_view(info, DVT_MEMORY); if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(lookup_widget(info->win, "physical_addresses")))) { downcast(memory->view)->set_physical(true); } } void on_reverse_activate(GtkWidget *win) { win_i *info = get_win_i(win, WIN_TYPE_MEMORY); DView *memory = get_view(info, DVT_MEMORY); downcast(memory->view)->set_reverse(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(lookup_widget(info->win, "reverse")))); } void on_ibpl_activate(GtkWidget *win) { win_i *info = get_win_i(win, WIN_TYPE_MEMORY); DView *memory = get_view(info, DVT_MEMORY); debug_view_memory *memview = downcast(memory->view); memview->set_chunks_per_row(memview->chunks_per_row() + 1); } void on_dbpl_activate(GtkWidget *win) { win_i *info = get_win_i(win, WIN_TYPE_MEMORY); DView *memory = get_view(info, DVT_MEMORY); debug_view_memory *memview = downcast(memory->view); memview->set_chunks_per_row(memview->chunks_per_row() - 1); } void on_run_to_cursor_activate(GtkWidget *win) { win_i *info = get_win_i(win, WIN_TYPE_ALL); DView *disasm = get_view(info, DVT_DISASSEMBLY); astring command; if (disasm->view->cursor_visible()) { if (debug_cpu_get_visible_cpu(*info->machine) == disasm->view->source()->device()) { offs_t address = downcast(disasm->view)->selected_address(); command.printf("go 0x%X", address); debug_console_execute_command(*info->machine, command, 1); } } } void on_set_breakpoint_at_cursor_activate(GtkWidget *win) { win_i *info = get_win_i(win, WIN_TYPE_ALL); DView *disasm = get_view(info, DVT_DISASSEMBLY); astring command; if (disasm->view->cursor_visible()) { if (debug_cpu_get_visible_cpu(*info->machine) == disasm->view->source()->device()) { offs_t address = downcast(disasm->view)->selected_address(); device_debug *cpuinfo = disasm->view->source()->device()->debug(); device_debug::breakpoint *bp; INT32 bpindex = -1; /* first find an existing breakpoint at this address */ for (bp = cpuinfo->breakpoint_first(); bp != NULL; bp = bp->next()) if (address == bp->address()) { bpindex = bp->index(); break; } /* if it doesn't exist, add a new one */ if (bpindex == -1) command.printf("bpset 0x%X", address); else command.printf("bpclear 0x%X", bpindex); debug_console_execute_command(*info->machine, command, 1); } } } gboolean on_disasm_button_press_event(GtkWidget *widget, GdkEventButton *event, gpointer user_data) { DView *info = (DView *) widget; LOG(("gef %f %f %p %p\n", event->x, event->y, info, widget)); if (info->view->cursor_supported()) { DViewClass *dvc = DVIEW_GET_CLASS(info); debug_view_xy topleft = info->view->visible_position(); debug_view_xy newpos; newpos.x = topleft.x + event->x / dvc->fixedfont_width; newpos.y = topleft.y + event->y / dvc->fixedfont_height; info->view->set_cursor_position(newpos); info->view->set_cursor_visible(true); gtk_widget_grab_focus(widget); //SetFocus(wnd); } return true; } gboolean on_memoryview_button_press_event(GtkWidget *widget, GdkEventButton *event, gpointer user_data) { return on_disasm_button_press_event(widget, event, user_data); } gboolean on_memoryview_key_press_event(GtkWidget *widget, GdkEventKey *event, gpointer user_data) { DView *info = (DView *) widget; //printf("%s\n", event->string); //printf("The name of this keysym is `%s'\n", // gdk_keyval_name(event->keyval)); //if (/*waiting_for_debugger ||*/ !debugwin_seq_pressed(info->view-> owner->machine())) switch (event->keyval) { case GDK_Up: info->view->process_char(DCH_UP); break; case GDK_Down: info->view->process_char(DCH_DOWN); break; case GDK_Left: if ((event->state & GDK_CONTROL_MASK) != 0) info->view->process_char(DCH_CTRLLEFT); else info->view->process_char(DCH_LEFT); break; case GDK_Right: if ((event->state & GDK_CONTROL_MASK) != 0) info->view->process_char(DCH_CTRLRIGHT); else info->view->process_char(DCH_RIGHT); break; case GDK_Prior: info->view->process_char(DCH_PUP); break; case GDK_Next: info->view->process_char(DCH_PDOWN); break; case GDK_Home: if ((event->state & GDK_CONTROL_MASK) != 0) info->view->process_char(DCH_CTRLHOME); else info->view->process_char(DCH_HOME); break; case GDK_End: if ((event->state & GDK_CONTROL_MASK) != 0) info->view->process_char(DCH_CTRLEND); else info->view->process_char(DCH_END); break; case GDK_Escape: //if (info->owner->focuswnd != NULL) // SetFocus(info->owner->focuswnd); //info->owner->ignore_char_lparam = lparam >> 16; break; case GDK_Tab: //if (GetAsyncKeyState(VK_SHIFT) & 0x8000) // debugwin_view_prev_view(info->owner, info); //else // debugwin_view_next_view(info->view, dvw); break; default: if (event->keyval >= 32 && event->keyval < 127 && info->view->cursor_supported()) info->view->process_char(event->keyval); } return true; } #else #include "sdlinc.h" #include "emu.h" #include "osdepend.h" #include "osdsdl.h" // win32 stubs for linking void sdl_osd_interface::init_debugger() { } void sdl_osd_interface::wait_for_debugger(device_t &device, bool firststop) { } // win32 stubs for linking void debugwin_update_during_game(running_machine &machine) { } #endif