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