1 /* Hey EMACS -*- linux-c -*- */
2 /* $Id: dbg_bkpts.c 2825 2009-05-06 19:48:47Z roms $ */
3 
4 /*  TiEmu - Tiemu Is an EMUlator
5  *
6  *  Copyright (c) 2000-2001, Thomas Corvazier, Romain Lievin
7  *  Copyright (c) 2001-2003, Romain Lievin
8  *  Copyright (c) 2003, Julien Blache
9  *  Copyright (c) 2004, Romain Li�vin
10  *  Copyright (c) 2005-2006, Romain Li�vin, Kevin Kofler
11  *  Copyright (c) 2007, Romain Li�vin
12  *
13  *  This program is free software; you can redistribute it and/or modify
14  *  it under the terms of the GNU General Public License as published by
15  *  the Free Software Foundation; either version 2 of the License, or
16  *  (at your option) any later version.
17  *
18  *  This program is distributed in the hope that it will be useful,
19  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
20  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  *  GNU General Public License for more details.
22  *
23  *  You should have received a copy of the GNU General Public License
24  *  along with this program; if not, write to the Free Software
25  *  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
26  */
27 
28 #ifdef HAVE_CONFIG_H
29 #  include <config.h>
30 #endif
31 
32 #include <gtk/gtk.h>
33 #include <glade/glade.h>
34 #include <string.h>
35 
36 #include "intl.h"
37 #include "paths.h"
38 #include "support.h"
39 #include "ti68k_int.h"
40 #include "struct.h"
41 #include "dbg_wnds.h"
42 #include "bkpts.h"
43 #include "handles.h"
44 
45 static GladeXML *xml = NULL;
46 static GtkWidget *wnd = NULL;
47 
48 enum {
49 	    COL_SYMBOL, COL_TYPE, COL_STATUS, COL_START, COL_END, COL_MODE,
50 		COL_DATA, COL_FONT
51 };
52 #define CLIST_NVCOLS	(6)		// 7 visible columns
53 #define CLIST_NCOLS		(8)		// 7 real columns
54 
clist_create(GtkWidget * widget)55 static GtkListStore* clist_create(GtkWidget *widget)
56 {
57 	GtkTreeView *view = GTK_TREE_VIEW(widget);
58 	GtkListStore *store;
59 	GtkTreeModel *model;
60 	GtkCellRenderer *renderer;
61 	GtkTreeSelection *selection;
62     const gchar *text[CLIST_NVCOLS] = {
63 		_("Symbol"), _("Type"), _("Status"), _("Start"), _("End"), _("Mode")
64     };
65     gint i;
66 
67 	store = gtk_list_store_new(CLIST_NCOLS,
68 				G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
69 				G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_STRING,
70 				-1
71             );
72     model = GTK_TREE_MODEL(store);
73 
74     gtk_tree_view_set_model(view, model);
75     gtk_tree_view_set_headers_visible(view, TRUE);
76 	gtk_tree_view_set_rules_hint(view, FALSE);
77 
78 	for(i = COL_SYMBOL; i <= COL_MODE; i++)
79 	{
80 		renderer = gtk_cell_renderer_text_new();
81 		gtk_tree_view_insert_column_with_attributes(view, -1,
82             text[i], renderer,
83             "text", i,
84 			"font", COL_FONT,
85 			NULL);
86 	}
87 
88     for (i = 0; i < CLIST_NVCOLS; i++)
89     {
90 		GtkTreeViewColumn *col;
91 
92 		col = gtk_tree_view_get_column(view, i);
93 		gtk_tree_view_column_set_resizable(col, TRUE);
94 	}
95 
96 	selection = gtk_tree_view_get_selection(view);
97 	gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE);
98 
99 	return store;
100 }
101 
102 static GList** bkpts_mem_access[6] = {
103 	&bkpts.mem_rb, &bkpts.mem_rw, &bkpts.mem_rl,
104 	&bkpts.mem_wb, &bkpts.mem_ww, &bkpts.mem_wl,
105 };
106 static  GList** bkpts_mem_range[2] = {
107 	&bkpts.mem_rng_r, &bkpts.mem_rng_w,
108 };
109 static const int bkpts_memacc_rw[6] = {
110     BK_READ_BYTE, BK_READ_WORD, BK_READ_LONG,
111     BK_WRITE_BYTE, BK_WRITE_WORD, BK_WRITE_LONG,
112 };
113 static const int bkpts_memrng_rw[2] = {
114 	BK_READ, BK_WRITE
115 };
116 
clist_populate(GtkListStore * store)117 static void clist_populate(GtkListStore *store)
118 {
119 	GList *l;
120     GtkTreeIter iter, iter2;
121 	gint i;
122 
123 	GtkTreeModel *model = GTK_TREE_MODEL(store);
124 	gboolean valid, valid2, removed;
125 	uint32_t mode, mode2;
126 
127 	// Code breakpoints
128 	for(l = bkpts.code; l != NULL; l = g_list_next(l))
129 	{
130 		uint32_t addr = GPOINTER_TO_INT(l->data);
131 		gchar *str;
132 
133 		str = g_strdup_printf("0x%06x", BKPT_ADDR(addr));
134 
135 		gtk_list_store_append(store, &iter);
136 
137 		gtk_list_store_set(store, &iter,
138 		COL_SYMBOL, str,
139 		COL_TYPE, ti68k_bkpt_type_to_string(BK_TYPE_CODE),
140 		COL_STATUS, BKPT_IS_ENABLED(addr) ? _("enabled") : _("disabled"),
141 		COL_START, str,
142 		COL_END, "",
143         COL_MODE, BKPT_IS_TMP(addr) ? _("one-shot") : "",
144 		COL_DATA, l->data,
145 		-1);
146 /*
147 		if(options3.dbg_font_type)
148 			gtk_list_store_set(store, &iter, COL_FONT, options3.dbg_font_name, -1);
149 */
150 		g_free(str);
151 	}
152 
153 	// Vector breakpoints
154 	for(l = bkpts.exception; l != NULL; l = g_list_next(l))
155 	{
156 		gint n = GPOINTER_TO_INT(l->data);
157 		gchar *str1, *str2;
158 		gint bn = BKPT_ADDR(n);
159 
160 		str1 = g_strdup_printf("#%i - %s", bn, ti68k_exception_to_string(bn));
161 		str2 = g_strdup_printf("0x%06x", 4 * bn);
162 
163 		gtk_list_store_append(store, &iter);
164 		gtk_list_store_set(store, &iter,
165 		COL_SYMBOL, str1,
166 		COL_TYPE, ti68k_bkpt_type_to_string(BK_TYPE_EXCEPTION),
167 		COL_STATUS, BKPT_IS_ENABLED(n) ? _("enabled") : _("disabled"),
168 		COL_START, str2,
169 		COL_END, "",
170 		COL_MODE, "",
171 		COL_DATA, l->data,
172 		-1);
173 /*
174 		if(options3.dbg_font_type)
175 			gtk_list_store_set(store, &iter, COL_FONT, options3.dbg_font_name, -1);
176 */
177 		g_free(str1);
178 		g_free(str2);
179 	}
180 
181 	// Memory access breakpoints
182 	for(i = 0; i < 6; i++)
183 	{
184 		for(l = *bkpts_mem_access[i]; l != NULL; l = g_list_next(l))
185 		{
186 			uint32_t addr = GPOINTER_TO_INT(l->data);
187 			gchar *str;
188 
189 			str = g_strdup_printf("0x%06x", BKPT_ADDR(addr));
190 
191 			gtk_list_store_append(store, &iter);
192 			gtk_list_store_set(store, &iter,
193 			COL_SYMBOL, str,
194 			COL_TYPE, ti68k_bkpt_type_to_string(BK_TYPE_ACCESS),
195 			COL_STATUS, BKPT_IS_ENABLED(addr) ? _("enabled") : _("disabled"),
196 			COL_START, str,
197 			COL_END, "",
198             COL_MODE, ti68k_bkpt_mode_to_string(BK_TYPE_ACCESS, bkpts_memacc_rw[i]),
199 			COL_DATA, l->data,
200 			-1);
201 /*
202 			if(options3.dbg_font_type)
203 				gtk_list_store_set(store, &iter, COL_FONT, options3.dbg_font_name, -1);
204 */
205 			g_free(str);
206 		}
207 	}
208 
209 	// Memory range breakpoints
210 	for(i = 0; i < 2; i++)
211 	{
212 		for(l = *(bkpts_mem_range[i]); l != NULL; l = g_list_next(l))
213 		{
214 			ADDR_RANGE *s = l->data;
215 			gchar *str1, *str2;
216 
217 			str1 = g_strdup_printf("0x%06x", BKPT_ADDR(s->val1));
218 			str2 = g_strdup_printf("0x%06x", BKPT_ADDR(s->val2));
219 
220 			gtk_list_store_append(store, &iter);
221 			gtk_list_store_set(store, &iter,
222 			COL_SYMBOL, str1,
223 			COL_TYPE, ti68k_bkpt_type_to_string(BK_TYPE_RANGE),
224 			COL_STATUS, BKPT_IS_ENABLED(s->val1) ? _("enabled") : _("disabled"),
225 			COL_START, str1,
226 			COL_END, str2,
227             COL_MODE, ti68k_bkpt_mode_to_string(BK_TYPE_RANGE, bkpts_memrng_rw[i]),
228 			COL_DATA, l->data,
229 			-1);
230 /*
231 			if(options3.dbg_font_type)
232 				gtk_list_store_set(store, &iter, COL_FONT, options3.dbg_font_name, -1);
233 */
234 			g_free(str1);
235 			g_free(str2);
236 		}
237 	}
238 
239 	// Bit change breakpoints
240 	for(l = bkpts.bits; l != NULL; l = g_list_next(l))
241 	{
242 		ADDR_BIT *s = l->data;
243 		gchar *str;
244 
245 		str = g_strdup_printf("0x%06x", BKPT_ADDR(s->addr));
246 
247 		gtk_list_store_append(store, &iter);
248 			gtk_list_store_set(store, &iter,
249 			COL_SYMBOL, str,
250 			COL_TYPE, ti68k_bkpt_type_to_string(BK_TYPE_BIT),
251 			COL_STATUS, BKPT_IS_ENABLED(s->addr) ? _("enabled") : _("disabled"),
252 			COL_START, str,
253 			COL_END, "",
254             COL_MODE, "",
255 			COL_DATA, l->data,
256 			-1);
257 /*
258 			if(options3.dbg_font_type)
259 				gtk_list_store_set(store, &iter, COL_FONT, options3.dbg_font_name, -1);
260 */
261 		g_free(str);
262 	}
263 
264 	// parse list to merge informations: ugly/heavy code !
265 	for(valid = gtk_tree_model_get_iter_first(model, &iter);
266         valid;
267         valid = gtk_tree_model_iter_next(model, &iter))
268     {
269 		gchar** row_text = g_malloc0((CLIST_NVCOLS + 1) * sizeof(gchar *));
270 
271 		gtk_tree_model_get(model, &iter,
272 				COL_SYMBOL, &row_text[COL_SYMBOL],
273 				COL_TYPE, &row_text[COL_TYPE],
274 				COL_START, &row_text[COL_START],
275 				COL_END, &row_text[COL_END],
276 				COL_MODE, &row_text[COL_MODE],
277 				-1);
278 		mode = ti68k_string_to_bkpt_mode(row_text[COL_MODE]);
279 
280 		memcpy(&iter2, &iter, sizeof(GtkTreeIter));
281 		for(valid2 = gtk_tree_model_iter_next(model, &iter2);
282 			valid2;
283 			removed = FALSE)
284 		{
285 				gchar** row_text2 = g_malloc0((CLIST_NVCOLS + 1) * sizeof(gchar *));
286 
287 				gtk_tree_model_get(model, &iter2,
288 				COL_SYMBOL, &row_text2[COL_SYMBOL],
289 				COL_TYPE, &row_text2[COL_TYPE],
290 				COL_START, &row_text2[COL_START],
291 				COL_END, &row_text2[COL_END],
292 				COL_MODE, &row_text2[COL_MODE],
293 				-1);
294 				mode2 = ti68k_string_to_bkpt_mode(row_text2[COL_MODE]);
295 
296 				if(!strcmp(row_text2[COL_TYPE], _("access")) || !strcmp(row_text2[COL_TYPE], _("range")))
297 				{
298 					if(!strcmp(row_text[COL_START], row_text2[COL_START]) && !strcmp(row_text[COL_END], row_text2[COL_END]))
299 					{
300 						if( ((mode & BK_READ) && (mode2 & BK_WRITE)) || ((mode & BK_WRITE) && (mode2 & BK_READ)) )
301 						{
302 							const gchar *new_str;
303 
304 							new_str = ti68k_bkpt_mode_to_string(0, mode | BK_RW);
305 							gtk_list_store_set(store, &iter, COL_MODE, new_str, -1);
306 
307 							valid2 = gtk_list_store_remove(store, &iter2);
308 							removed = TRUE;
309 						}
310 					}
311 				}
312 
313 				g_strfreev(row_text2);
314 
315 				if(!removed)
316 					valid2 = gtk_tree_model_iter_next(model, &iter2);
317 		}
318 
319 		g_strfreev(row_text);
320 	}
321 
322 	// Prgm entry breakpoints
323 	for(l = bkpts.pgmentry; l != NULL; l = g_list_next(l))
324 	{
325 		uint32_t addr = GPOINTER_TO_INT(l->data);
326 		gchar *str;
327 
328 		str = g_strdup_printf("#%04x", BKPT_ADDR(addr) >> 16);
329 
330 		gtk_list_store_append(store, &iter);
331 
332 		gtk_list_store_set(store, &iter,
333 		COL_SYMBOL, str,
334 		COL_TYPE, ti68k_bkpt_type_to_string(BK_TYPE_PGMENTRY),
335 		COL_STATUS, BKPT_IS_ENABLED(addr) ? _("enabled") : _("disabled"),
336 		COL_START, str,
337 		COL_END, "",
338         COL_MODE, BKPT_IS_TMP(addr) ? _("one-shot") : "",
339 		COL_DATA, l->data,
340 		-1);
341 /*
342 		if(options3.dbg_font_type)
343 			gtk_list_store_set(store, &iter, COL_FONT, options3.dbg_font_name, -1);
344 */
345 		g_free(str);
346 	}
347 }
348 
349 static GtkListStore *store = NULL;
350 
351 /*
352 	Display registers window
353 */
dbgbkpts_create_window(void)354 GtkWidget* dbgbkpts_create_window(void)
355 {
356 	GtkWidget *dbox;
357     GtkWidget *data;
358 
359 	xml = glade_xml_new
360 		(tilp_paths_build_glade("dbg_bkpts-2.glade"), "dbgbkpts_window",
361 		 PACKAGE);
362 	if (!xml)
363 		g_error(_("%s: GUI loading failed!\n"), __FILE__);
364 	glade_xml_signal_autoconnect(xml);
365 
366 	dbox = glade_xml_get_widget(xml, "dbgbkpts_window");
367 	if(options3.transient)
368 		gtk_window_set_transient_for(GTK_WINDOW(dbox), GTK_WINDOW(main_wnd));
369 
370 	data = glade_xml_get_widget(xml, "treeview1");
371     store = clist_create(data);
372 	clist_populate(store);
373 
374 	gtk_tree_view_expand_all(GTK_TREE_VIEW(data));
375 
376 	return wnd = dbox;
377 }
378 
dbgbkpts_display_window(void)379 GtkWidget* dbgbkpts_display_window(void)
380 {
381 #ifdef WND_STATE
382 	if(!options3.bkpts.minimized)
383 	{
384 		gtk_window_resize(GTK_WINDOW(wnd), options3.bkpts.rect.w, options3.bkpts.rect.h);
385 		gtk_window_move(GTK_WINDOW(wnd), options3.bkpts.rect.x, options3.bkpts.rect.y);
386 	}
387 	else
388 		gtk_window_iconify(GTK_WINDOW(wnd));
389 #endif
390 
391 	if(!GTK_WIDGET_VISIBLE(dbgw.bkpts) && !options3.bkpts.closed)
392 		gtk_widget_show(wnd);
393 
394 	return wnd;
395 }
396 
dbgbkpts_refresh_window(void)397 void dbgbkpts_refresh_window(void)
398 {
399 	WND_TMR_START();
400 
401 	if(!options3.bkpts.closed)
402 	{
403 		gtk_list_store_clear(store);
404 		clist_populate(store);
405 
406 		display_dbgcause_dbox2(glade_get("statusbar1"));
407 	}
408 
409 	WND_TMR_STOP("Breakpoints Refresh Time");
410 }
411 
dbgbkpts_erase_context(void)412 void dbgbkpts_erase_context(void)
413 {
414 	display_dbgcause_dbox2(glade_get("statusbar1"));
415 }
416 
display_dbgbkpts_popup_menu(void)417 static GtkWidget* display_dbgbkpts_popup_menu(void)
418 {
419 	GladeXML *xml;
420 	GtkWidget *data;
421 
422 	xml = glade_xml_new
423 	    (tilp_paths_build_glade("dbg_bkpts-2.glade"), "dbgbkpts_popup",
424 	     PACKAGE);
425 	if (!xml)
426 		g_error(_("dbg_bkpts-2.glade: GUI loading failed !\n"));
427 	glade_xml_signal_autoconnect(xml);
428 
429 	data = glade_xml_get_widget(xml, "dbgbkpts_popup");
430 
431 	return data;
432 }
433 
434 /* Add bkpt */
435 GLADE_CB void
dbgbkpts_button1_clicked(GtkButton * button,gpointer user_data)436 dbgbkpts_button1_clicked                     (GtkButton       *button,
437                                         gpointer         user_data)
438 {
439 	GtkWidget *menu;
440 	guint butt = 0;
441 	guint32 time;
442 
443 	time = gtk_get_current_event_time();
444 	menu = display_dbgbkpts_popup_menu();
445 	gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, butt, time);
446 	gtk_widget_show(menu);
447 }
448 
449 /* Remove bkpt */
450 GLADE_CB void
dbgbkpts_button2_clicked(GtkButton * button,gpointer user_data)451 dbgbkpts_button2_clicked                     (GtkButton       *button,
452                                         gpointer         user_data)
453 {
454     GtkWidget *list = GTK_WIDGET(button);   // arg are swapped, why ?
455 	GtkTreeView *view = GTK_TREE_VIEW(list);
456 	GtkTreeSelection *selection;
457 	GtkTreeModel *model;
458 	GList *l;
459 
460 	// get selection
461 	selection = gtk_tree_view_get_selection(view);
462 	for (l = gtk_tree_selection_get_selected_rows(selection, &model);
463 	     l != NULL; l = l->next)
464 	{
465 		GtkTreeIter iter;
466 		GtkTreePath *path = l->data;
467         gchar** row_text = g_malloc0((CLIST_NVCOLS + 1) * sizeof(gchar *));
468         uint32_t n, type, min, max, mode;
469 
470 		gtk_tree_model_get_iter(model, &iter, path);
471 		gtk_tree_model_get(model, &iter,
472             COL_SYMBOL, &row_text[COL_SYMBOL],
473             COL_TYPE, &row_text[COL_TYPE],
474             COL_START, &row_text[COL_START],
475             COL_END, &row_text[COL_END],
476             COL_MODE, &row_text[COL_MODE],
477             -1);
478 
479         type = ti68k_string_to_bkpt_type(row_text[COL_TYPE]);
480         switch(type)
481         {
482         case BK_TYPE_CODE:
483             sscanf(row_text[COL_START], "%x", &min);
484             ti68k_bkpt_del_address(min);
485 			dbgcode_refresh_window();
486             break;
487         case BK_TYPE_EXCEPTION:
488             sscanf(row_text[COL_SYMBOL], "#%i", &n);
489             ti68k_bkpt_del_exception(n);
490             break;
491         case BK_TYPE_ACCESS:
492             mode = ti68k_string_to_bkpt_mode(row_text[COL_MODE]);
493             sscanf(row_text[COL_START], "%x", &min);
494             ti68k_bkpt_del_access(min, mode);
495             break;
496         case BK_TYPE_RANGE:
497             mode = ti68k_string_to_bkpt_mode(row_text[COL_MODE]);
498             sscanf(row_text[COL_START], "%x", &min);
499             sscanf(row_text[COL_END], "%x", &max);
500             ti68k_bkpt_del_range(min, max, mode);
501             break;
502 		case BK_TYPE_PGMENTRY:
503 			sscanf(row_text[COL_SYMBOL], "#%04x", &n);
504 			ti68k_bkpt_del_pgmentry((uint16_t)n);
505 			break;
506 		case BK_TYPE_BIT:
507 			mode = ti68k_string_to_bkpt_mode(row_text[COL_MODE]);
508             sscanf(row_text[COL_START], "%x", &min);
509             ti68k_bkpt_del_bits(min);
510         }
511         g_strfreev(row_text);
512     }
513 
514 	// free selection
515 	g_list_foreach (l, (GFunc)gtk_tree_path_free, NULL);
516 	g_list_free (l);
517 
518     dbgbkpts_refresh_window();
519 }
520 
521 
522 /* Disable bkpt */
523 GLADE_CB void
dbgbkpts_button3_clicked(GtkButton * button,GtkWidget * widget,gpointer user_data)524 dbgbkpts_button3_clicked                     (GtkButton       *button,
525                                               GtkWidget       *widget,
526                                               gpointer         user_data)
527 {
528 	GtkWidget *list = GTK_WIDGET(button);   // arg are swapped, why ?
529 	GtkTreeView *view = GTK_TREE_VIEW(list);
530 	GtkTreeSelection *selection;
531 	GtkTreeModel *model;
532 	GList *l;
533 
534 	// get selection
535 	selection = gtk_tree_view_get_selection(view);
536 	for (l = gtk_tree_selection_get_selected_rows(selection, &model);
537 	     l != NULL; l = l->next)
538 	{
539 		GtkTreeIter iter;
540 		GtkTreePath *path = l->data;
541         gchar** row_text = g_malloc0((CLIST_NVCOLS + 1) * sizeof(gchar *));
542         uint32_t n, type, min, max, mode;
543 
544 		gtk_tree_model_get_iter(model, &iter, path);
545 		gtk_tree_model_get(model, &iter,
546             COL_SYMBOL, &row_text[COL_SYMBOL],
547             COL_TYPE, &row_text[COL_TYPE],
548             COL_START, &row_text[COL_START],
549             COL_END, &row_text[COL_END],
550             COL_MODE, &row_text[COL_MODE],
551             -1);
552 
553         type = ti68k_string_to_bkpt_type(row_text[COL_TYPE]);
554         switch(type)
555         {
556         case BK_TYPE_CODE:
557             sscanf(row_text[COL_START], "%x", &min);
558             {
559               uint32_t addr = BKPT_ADDR(min);
560               ti68k_bkpt_set_address(addr, BKPT_DISABLE(min));
561             }
562             break;
563         case BK_TYPE_EXCEPTION:
564             sscanf(row_text[COL_SYMBOL], "#%i", &n);
565             {
566               uint32_t addr = BKPT_ADDR(n);
567               ti68k_bkpt_set_exception(addr, BKPT_DISABLE(n));
568             }
569             break;
570         case BK_TYPE_ACCESS:
571             mode = ti68k_string_to_bkpt_mode(row_text[COL_MODE]);
572             sscanf(row_text[COL_START], "%x", &min);
573             {
574               uint32_t addr = BKPT_ADDR(min);
575               ti68k_bkpt_set_access(addr, mode, BKPT_DISABLE(min));
576             }
577             break;
578         case BK_TYPE_RANGE:
579             mode = ti68k_string_to_bkpt_mode(row_text[COL_MODE]);
580             sscanf(row_text[COL_START], "%x", &min);
581             sscanf(row_text[COL_END], "%x", &max);
582             {
583               uint32_t addr1 = BKPT_ADDR(min);
584               uint32_t addr2 = BKPT_ADDR(max);
585               ti68k_bkpt_set_range(addr1, addr2, mode,
586                                    BKPT_DISABLE(min), BKPT_DISABLE(max));
587             }
588             break;
589         case BK_TYPE_PGMENTRY:
590             //sscanf(row_text[COL_SYMBOL], "#%04x", &n);
591             //{
592             //  uint32_t addr = BKPT_ADDR(n);
593             //  ti68k_bkpt_set_pgmentry(addr, BKPT_DISABLE(n));
594             //}
595             break;
596 		case BK_TYPE_BIT:
597 			mode = ti68k_string_to_bkpt_mode(row_text[COL_MODE]);
598             sscanf(row_text[COL_START], "%x", &min);
599             {
600               uint32_t addr = BKPT_ADDR(min);
601               ti68k_bkpt_set_bits(addr, BKPT_DISABLE(addr));
602             }
603 			break;
604 
605         }
606         g_strfreev(row_text);
607     }
608 
609 	// free selection
610 	g_list_foreach (l, (GFunc)gtk_tree_path_free, NULL);
611 	g_list_free (l);
612 
613     dbgbkpts_refresh_window();
614 }
615 
616 
617 /* Enable bkpt */
618 GLADE_CB void
dbgbkpts_button4_clicked(GtkButton * button,gpointer user_data)619 dbgbkpts_button4_clicked                     (GtkButton       *button,
620                                               gpointer         user_data)
621 {
622 	GtkWidget *list = GTK_WIDGET(button);   // arg are swapped, why ?
623 	GtkTreeView *view = GTK_TREE_VIEW(list);
624 	GtkTreeSelection *selection;
625 	GtkTreeModel *model;
626 	GList *l;
627 
628 	// get selection
629 	selection = gtk_tree_view_get_selection(view);
630 	for (l = gtk_tree_selection_get_selected_rows(selection, &model);
631 	     l != NULL; l = l->next)
632 	{
633 		GtkTreeIter iter;
634 		GtkTreePath *path = l->data;
635         gchar** row_text = g_malloc0((CLIST_NVCOLS + 1) * sizeof(gchar *));
636         uint32_t n, type, min, max, mode;
637 
638 		gtk_tree_model_get_iter(model, &iter, path);
639 		gtk_tree_model_get(model, &iter,
640             COL_SYMBOL, &row_text[COL_SYMBOL],
641             COL_TYPE, &row_text[COL_TYPE],
642             COL_START, &row_text[COL_START],
643             COL_END, &row_text[COL_END],
644             COL_MODE, &row_text[COL_MODE],
645             -1);
646 
647         type = ti68k_string_to_bkpt_type(row_text[COL_TYPE]);
648         switch(type)
649         {
650         case BK_TYPE_CODE:
651             sscanf(row_text[COL_START], "%x", &min);
652             {
653               uint32_t addr = BKPT_ADDR(min);
654               ti68k_bkpt_set_address(addr, BKPT_ENABLE(min));
655             }
656             break;
657         case BK_TYPE_EXCEPTION:
658             sscanf(row_text[COL_SYMBOL], "#%i", &n);
659             {
660               uint32_t addr = BKPT_ADDR(n);
661               ti68k_bkpt_set_exception(addr, BKPT_ENABLE(n));
662             }
663             break;
664         case BK_TYPE_ACCESS:
665             mode = ti68k_string_to_bkpt_mode(row_text[COL_MODE]);
666             sscanf(row_text[COL_START], "%x", &min);
667             {
668               uint32_t addr = BKPT_ADDR(min);
669               ti68k_bkpt_set_access(addr, mode, BKPT_ENABLE(min));
670             }
671             break;
672         case BK_TYPE_RANGE:
673             mode = ti68k_string_to_bkpt_mode(row_text[COL_MODE]);
674             sscanf(row_text[COL_START], "%x", &min);
675             sscanf(row_text[COL_END], "%x", &max);
676             {
677               uint32_t addr1 = BKPT_ADDR(min);
678               uint32_t addr2 = BKPT_ADDR(max);
679               ti68k_bkpt_set_range(addr1, addr2, mode,
680                                    BKPT_ENABLE(min), BKPT_ENABLE(max));
681             }
682             break;
683         case BK_TYPE_PGMENTRY:
684             //sscanf(row_text[COL_SYMBOL], "#%04x", &n);
685             //{
686             //  uint32_t addr = BKPT_ADDR(n);
687             //  ti68k_bkpt_set_pgmentry(addr, BKPT_ENABLE(n));
688             //}
689             break;
690 		case BK_TYPE_BIT:
691 			mode = ti68k_string_to_bkpt_mode(row_text[COL_MODE]);
692             sscanf(row_text[COL_START], "%x", &min);
693             {
694               uint32_t addr = BKPT_ADDR(min);
695               ti68k_bkpt_set_bits(addr, BKPT_ENABLE(addr));
696             }
697 			break;
698         }
699         g_strfreev(row_text);
700     }
701 
702 	// free selection
703 	g_list_foreach (l, (GFunc)gtk_tree_path_free, NULL);
704 	g_list_free (l);
705 
706     dbgbkpts_refresh_window();
707 }
708 
709 
710 /* Go to bkpt address */
711 GLADE_CB void
dbgbkpts_button5_clicked(GtkButton * button,gpointer user_data)712 dbgbkpts_button5_clicked                     (GtkButton       *button,
713                                               gpointer         user_data)
714 {
715 	GtkWidget *list = GTK_WIDGET(button);   // arg are swapped, why ?
716 	GtkTreeView *view = GTK_TREE_VIEW(list);
717 	GtkTreeSelection *selection;
718 	GtkTreeModel *model;
719 	GList *l;
720 
721 	// get selection
722 	selection = gtk_tree_view_get_selection(view);
723 	l = gtk_tree_selection_get_selected_rows(selection, &model);
724 	if(l != NULL)
725 	{
726 		GtkTreeIter iter;
727 		GtkTreePath *path = l->data;
728         gchar** row_text = g_malloc0((CLIST_NVCOLS + 1) * sizeof(gchar *));
729         uint32_t type, min, n, addr;
730 
731 		gtk_tree_model_get_iter(model, &iter, path);
732 		gtk_tree_model_get(model, &iter,
733             COL_SYMBOL, &row_text[COL_SYMBOL],
734             COL_TYPE, &row_text[COL_TYPE],
735             COL_START, &row_text[COL_START],
736             COL_END, &row_text[COL_END],
737             COL_MODE, &row_text[COL_MODE],
738             -1);
739 
740 		type = ti68k_string_to_bkpt_type(row_text[COL_TYPE]);
741 		switch(type)
742         {
743         case BK_TYPE_CODE:
744             sscanf(row_text[COL_START], "%x", &min);
745 			addr = BKPT_ADDR(min);
746           	dbgcode_disasm_at(addr);
747             break;
748         case BK_TYPE_EXCEPTION:
749             sscanf(row_text[COL_SYMBOL], "#%i", &n);
750 			dbgcode_disasm_at(mem_rd_long(4*n));
751             break;
752         case BK_TYPE_ACCESS:
753 		case BK_TYPE_RANGE:
754 		case BK_TYPE_BIT:
755             sscanf(row_text[COL_START], "%x", &min);
756             addr = BKPT_ADDR(min);
757             dbgmem_add_tab(addr);
758             break;
759         case BK_TYPE_PGMENTRY:
760 			{
761 				gpointer data;
762 				uint16_t handle, offset;
763 
764 				gtk_tree_model_get(model, &iter, COL_DATA, &data, -1);
765 
766 				handle = GPOINTER_TO_INT(data) >> 16;
767 				offset = GPOINTER_TO_INT(data) & 0xffff;
768 				addr = heap_deref(handle) + offset;
769 
770 				dbgcode_disasm_at(addr);
771 			}
772             break;
773         }
774         g_strfreev(row_text);
775     }
776 
777 	// free selection
778 	g_list_foreach (l, (GFunc)gtk_tree_path_free, NULL);
779 	g_list_free (l);
780 }
781 
782 GLADE_CB gboolean
on_treeview2_button_press_event(GtkWidget * widget,GdkEventButton * event,gpointer user_data)783 on_treeview2_button_press_event        (GtkWidget       *widget,
784                                         GdkEventButton  *event,
785                                         gpointer         user_data)
786 {
787 	GtkTreeView *view = GTK_TREE_VIEW(widget);
788     GtkTreeModel *model = gtk_tree_view_get_model(view);
789 	GtkTreePath *path;
790 	GtkTreeViewColumn *column;
791     GtkTreeIter iter;
792     gboolean ret;
793 
794     if (event->type != GDK_2BUTTON_PRESS)	// double-click ?
795 		return FALSE;
796 	else
797 	{
798 		// retrieve selection
799 		gint tx = (gint) event->x;
800 	    gint ty = (gint) event->y;
801 	    gint cx, cy;
802 		gchar** row_text = g_malloc0((CLIST_NVCOLS + 1) * sizeof(gchar *));
803 		uint32_t type;
804 		gpointer data;
805 
806         ret = gtk_tree_view_get_path_at_pos(view, tx, ty, &path, &column, &cx, &cy);
807         if(ret == FALSE)
808             return FALSE;
809 
810 		if (!gtk_tree_model_get_iter(model, &iter, path))
811 		    return FALSE;
812         gtk_tree_path_free(path);
813 
814         gtk_tree_model_get(model, &iter,
815             COL_SYMBOL, &row_text[COL_SYMBOL],
816             COL_TYPE, &row_text[COL_TYPE],
817             COL_START, &row_text[COL_START],
818             COL_END, &row_text[COL_END],
819             COL_MODE, &row_text[COL_MODE],
820 			COL_DATA, &data,
821             -1);
822 
823         type = ti68k_string_to_bkpt_type(row_text[COL_TYPE]);
824 		if(type == BK_TYPE_CODE)
825 		{
826 			uint32_t old_addr, new_addr;
827 
828 			sscanf(row_text[COL_START], "%x", &old_addr);
829 			new_addr = old_addr;
830 
831 			if(display_dbgmem_address(&new_addr) == -1)
832 				return TRUE;
833 
834 			ti68k_bkpt_set_address(old_addr, new_addr);
835 			dbgbkpts_refresh_window();
836 			dbgcode_refresh_window();
837 		}
838 		if((type == BK_TYPE_ACCESS) || (type == BK_TYPE_RANGE))
839 		{
840 			uint32_t old_min, old_max;
841 			uint32_t new_min, new_max;
842 			uint32_t new_type;
843 			uint32_t old_mode, new_mode;
844 
845             old_mode = ti68k_string_to_bkpt_mode(row_text[COL_MODE]);
846             sscanf(row_text[COL_START], "%x", &old_min);
847             sscanf(row_text[COL_END], "%x", &old_max);
848 
849             new_type = type; new_mode = old_mode; new_min = old_min; new_max = old_max;
850 			if(dbgdata_display_dbox(&new_mode, &new_type, &new_min, &new_max) == -1)
851 				return TRUE;
852 
853 			if(type != new_type)
854 				return TRUE;
855 
856 			if(new_type == BK_TYPE_ACCESS)
857 			{
858 				ti68k_bkpt_del_access(old_min, old_mode);
859 				ti68k_bkpt_add_access(new_min, new_mode);
860 				//ti68k_bkpt_set_access(old_min, mode, new_min);
861 			}
862 			else if(new_type == BK_TYPE_RANGE)
863 			{
864 				ti68k_bkpt_del_range(old_min, old_max, old_mode);
865 				ti68k_bkpt_add_range(new_min, new_max, new_mode);
866 				//ti68k_bkpt_set_range(old_min, old_max, mode, new_min, new_max);
867 			}
868 			dbgbkpts_refresh_window();
869 		}
870 		if(type == BK_TYPE_BIT)
871 		{
872 			uint32_t old_addr;
873 			ADDR_BIT *s = (ADDR_BIT *)data;
874 
875 			sscanf(row_text[COL_START], "%x", &old_addr);
876 
877 			if(dbgbits_display_dbox(&s->addr, &s->checks, &s->states) == -1)
878 				return TRUE;
879 
880 			dbgbkpts_refresh_window();
881 		}
882 
883 		g_strfreev(row_text);
884 
885 		return TRUE;
886     }
887 
888     return FALSE;
889 }
890 
891 GLADE_CB void
dbgbkpts_bit_activate(GtkMenuItem * menuitem,gpointer user_data)892 dbgbkpts_bit_activate                  (GtkMenuItem     *menuitem,
893                                         gpointer         user_data)
894 {
895 	uint32_t addr = 0;
896 	uint8_t checks = 0, states = 0xff;
897 
898 	if(dbgbits_display_dbox(&addr, &checks, &states) != 0)
899 		return;
900 
901 	ti68k_bkpt_add_bits(addr, checks, states);
902 
903 	dbgbkpts_refresh_window();
904 }
905 
906 GLADE_CB void
dbgbkpts_data_activate(GtkMenuItem * menuitem,gpointer user_data)907 dbgbkpts_data_activate                    (GtkMenuItem     *menuitem,
908                                         gpointer         user_data)
909 {
910 	uint32_t mode, type=-1, min, max;
911 
912 	// fill infos
913 	if(dbgdata_display_dbox(&mode, &type, &min, &max) != 0)
914 		return;
915 
916 	// add breakpoint
917 	if(type == BK_TYPE_ACCESS)
918 		ti68k_bkpt_add_access(min, mode) ;
919 	else if(type == BK_TYPE_RANGE)
920 		ti68k_bkpt_add_range(min, max, mode);
921 
922 	// and refresh
923 	dbgbkpts_refresh_window();
924 }
925 
926 
927 GLADE_CB void
dbgbkpts_vector_activate(GtkMenuItem * menuitem,gpointer user_data)928 dbgbkpts_vector_activate               (GtkMenuItem     *menuitem,
929                                         gpointer         user_data)
930 {
931 	dbgvectors_display_dbox();
932 }
933 
934 GLADE_CB void
dbgbkpts_prgmentry1_activate(GtkMenuItem * menuitem,gpointer user_data)935 dbgbkpts_prgmentry1_activate           (GtkMenuItem     *menuitem,
936                                         gpointer         user_data)
937 {
938 	dbgentry_display_dbox();
939 }
940 
941 
942