~ubuntu-branches/ubuntu/breezy/tiemu/breezy

« back to all changes in this revision

Viewing changes to src/gui/debugger/dbg_code.c

  • Committer: Bazaar Package Importer
  • Author(s): Julien BLACHE
  • Date: 2005-06-02 16:50:15 UTC
  • mfrom: (1.2.1 upstream) (2.1.1 sarge)
  • Revision ID: james.westby@ubuntu.com-20050602165015-59ab24414tl2wzol
Tags: 1.99+svn1460-1
* New snapshot.
* debian/control:
  + Updated build-depends.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Hey EMACS -*- linux-c -*- */
 
2
/* $Id: dbg_code.c 1455 2005-05-31 18:38:03Z roms $ */
 
3
 
 
4
/*  TiEmu - an TI 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, Romain Li�vin, Kevin Kofler
 
11
 *
 
12
 *  This program is free software; you can redistribute it and/or modify
 
13
 *  it under the terms of the GNU General Public License as published by
 
14
 *  the Free Software Foundation; either version 2 of the License, or
 
15
 *  (at your option) any later version.
 
16
 *
 
17
 *  This program is distributed in the hope that it will be useful,
 
18
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
19
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
20
 *  GNU General Public License for more details.
 
21
 *
 
22
 *  You should have received a copy of the GNU General Public License
 
23
 *  along with this program; if not, write to the Free Software
 
24
 *  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
 
25
 */
 
26
 
 
27
#ifdef HAVE_CONFIG_H
 
28
#  include <config.h>
 
29
#endif
 
30
 
 
31
#include <gtk/gtk.h>
 
32
#include <glade/glade.h>
 
33
#include <gdk/gdkkeysyms.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_all.h"
 
42
#include "dbg_romcall.h"
 
43
 
 
44
//#define FIXED_SIZE
 
45
 
 
46
static GladeXML *xml = NULL;
 
47
static GtkWidget *wnd = NULL;
 
48
static gint already_open = 0;
 
49
 
 
50
enum { 
 
51
            COL_ICON, COL_ADDR, COL_OPCODE, COL_OPERAND,
 
52
        COL_HEXADDR, COL_FONT, COL_COLOR
 
53
};
 
54
#define CLIST_NVCOLS    (4)             // 4 visible columns
 
55
#define CLIST_NCOLS             (7)             // 7 real columns
 
56
 
 
57
#define FONT_NAME       "courier"
 
58
 
 
59
#ifdef FIXED_SIZE
 
60
#define NLINES      10
 
61
#else
 
62
static gint NLINES = 10;        
 
63
#endif
 
64
 
 
65
static GtkListStore* clist_create(GtkWidget *widget)
 
66
{
 
67
        GtkTreeView *view = GTK_TREE_VIEW(widget);
 
68
        GtkListStore *store;
 
69
        GtkTreeModel *model;
 
70
        GtkCellRenderer *renderer;
 
71
        GtkTreeSelection *selection;
 
72
    const gchar *text[CLIST_NVCOLS] = { _(""), _("Address"), _("Opcode"), _("Operand") };
 
73
    gint i;
 
74
        
 
75
        store = gtk_list_store_new(CLIST_NCOLS,
 
76
                                GDK_TYPE_PIXBUF, 
 
77
                G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
 
78
                G_TYPE_INT, G_TYPE_STRING, GDK_TYPE_COLOR,
 
79
                                -1
 
80
            );
 
81
    model = GTK_TREE_MODEL(store);
 
82
        
 
83
    gtk_tree_view_set_model(view, model); 
 
84
    gtk_tree_view_set_headers_visible(view, TRUE);
 
85
        gtk_tree_view_set_rules_hint(view, FALSE);
 
86
  
 
87
        renderer = gtk_cell_renderer_pixbuf_new();
 
88
        gtk_tree_view_insert_column_with_attributes(view, -1, 
 
89
            text[COL_ICON], renderer, 
 
90
            "pixbuf", COL_ICON,
 
91
                        NULL);
 
92
  
 
93
        for(i = COL_ADDR; i <= COL_OPERAND; i++)
 
94
        {
 
95
                renderer = gtk_cell_renderer_text_new();
 
96
                gtk_tree_view_insert_column_with_attributes(view, -1, 
 
97
            text[i], renderer, 
 
98
            "text", i,
 
99
                        "background-gdk", COL_COLOR,
 
100
                        NULL);
 
101
        }
 
102
    
 
103
    for (i = 0; i < CLIST_NVCOLS; i++) 
 
104
    {
 
105
                GtkTreeViewColumn *col;
 
106
                
 
107
                col = gtk_tree_view_get_column(view, i);
 
108
                gtk_tree_view_column_set_resizable(col, TRUE);
 
109
        }
 
110
        
 
111
        selection = gtk_tree_view_get_selection(view);
 
112
        gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
 
113
 
 
114
        return store;
 
115
}
 
116
 
 
117
static void clist_populate(GtkListStore *store, uint32_t addr)
 
118
{
 
119
    GtkTreeIter iter;
 
120
    GdkPixbuf *pix;
 
121
    gint i;
 
122
    GdkColor *color, color1, color2;
 
123
        gboolean success;
 
124
    uint32_t pc = ti68k_debug_get_pc();
 
125
 
 
126
        /* We can't start disassembling stuff before GDB is even loaded, and in the
 
127
           cases where we have GDB running, but not the debugger, it's just a waste
 
128
           of time. */
 
129
        if (!dbg_on) return;
 
130
 
 
131
        gdk_color_parse("White", &color1);
 
132
        gdk_colormap_alloc_colors(gdk_colormap_get_system(), &color1, 1, FALSE, FALSE, &success);
 
133
        gdk_color_parse("Green", &color2);
 
134
        gdk_colormap_alloc_colors(gdk_colormap_get_system(), &color2, 1, FALSE, FALSE, &success);
 
135
 
 
136
    for(i = 0; i < NLINES; i++)
 
137
    {
 
138
        gchar *output;
 
139
        int offset;
 
140
                gchar** split;
 
141
        gchar** row_text = g_malloc0((CLIST_NVCOLS + 1) * sizeof(gchar *));
 
142
        uint32_t value;
 
143
        
 
144
        // disassemble at 'addr' address into 'output' and returns offset to the
 
145
        // next instruction address
 
146
        offset = ti68k_debug_disassemble(addr, &output);
 
147
 
 
148
        split = g_strsplit(output, " ", 3);
 
149
                g_free(output);
 
150
 
 
151
                row_text[0] = g_strdup(split[0]);
 
152
                sscanf(row_text[0], "%x", &value);
 
153
        if(split[1] == NULL)
 
154
            row_text[1] = g_strdup("");
 
155
                else
 
156
                        row_text[1] = g_strdup(split[1]);
 
157
                if(split[2] == NULL)
 
158
            row_text[2] = g_strdup("");
 
159
                else
 
160
                        row_text[2] = g_strdup(split[2]);
 
161
 
 
162
                if(g_list_find(bkpts.code, GINT_TO_POINTER(addr)) != NULL)
 
163
                pix = create_pixbuf("bkpt.xpm");
 
164
        else
 
165
                pix = create_pixbuf("void.xpm");
 
166
 
 
167
        color = (addr == pc) ? &color2 : &color1;
 
168
 
 
169
        gtk_list_store_append(store, &iter);
 
170
            gtk_list_store_set(store, &iter, 
 
171
        COL_ICON, pix,
 
172
            COL_ADDR, row_text[0], 
 
173
                COL_OPCODE, row_text[1],
 
174
        COL_OPERAND, row_text[2],
 
175
        COL_HEXADDR, value,
 
176
                COL_FONT, FONT_NAME,
 
177
                COL_COLOR, color,
 
178
                -1);
 
179
 
 
180
        addr += offset;
 
181
        g_strfreev(split);
 
182
                g_strfreev(row_text);
 
183
                g_object_unref(pix);
 
184
    }
 
185
}
 
186
 
 
187
static void cyccnt_refresh(GtkWidget *l1, GtkWidget *l2)
 
188
{
 
189
        unsigned int count, diff;
 
190
        gchar *str1, *str2;
 
191
 
 
192
        count = ti68k_get_cycle_count(0, &diff);
 
193
        str1 = g_strdup_printf("%u", count);
 
194
        str2 = g_strdup_printf("%u", diff);
 
195
 
 
196
        gtk_label_set_text(GTK_LABEL(l1), str1);
 
197
        gtk_label_set_text(GTK_LABEL(l2), str2);
 
198
 
 
199
        g_free(str1);
 
200
        g_free(str2);
 
201
}
 
202
 
 
203
static void clist_refresh(GtkListStore *store, gboolean reload)
 
204
{
 
205
    GtkTreeModel *model = GTK_TREE_MODEL(store);
 
206
    gboolean valid;
 
207
    GtkTreeIter iter;
 
208
 
 
209
    uint32_t addr;
 
210
    uint32_t pc;
 
211
    int found = 0;
 
212
 
 
213
        GdkColor *color, color1, color2;
 
214
        gboolean success;
 
215
 
 
216
    const int offset = 3;   // 3 instructions are still visible
 
217
    uint32_t addr3;
 
218
    gint i;
 
219
 
 
220
    pc = ti68k_debug_get_pc();
 
221
 
 
222
        gdk_color_parse("White", &color1);
 
223
        gdk_colormap_alloc_colors(gdk_colormap_get_system(), &color1, 1, FALSE, FALSE, &success);
 
224
        gdk_color_parse("Green", &color2);
 
225
        gdk_colormap_alloc_colors(gdk_colormap_get_system(), &color2, 1, FALSE, FALSE, &success);
 
226
 
 
227
    // check for refresh (search for pc)
 
228
    for(valid = gtk_tree_model_get_iter_first(model, &iter), i = 0;
 
229
        valid; 
 
230
        valid = gtk_tree_model_iter_next(model, &iter), i++)
 
231
    {
 
232
        gchar *str;
 
233
 
 
234
        gtk_tree_model_get(model, &iter, COL_ADDR, &str, -1);
 
235
        sscanf(str, "%x", &addr);
 
236
 
 
237
        if(i == offset)
 
238
            addr3 = addr;
 
239
 
 
240
        if(addr == pc)
 
241
            found = i+1;
 
242
 
 
243
        g_free(str);
 
244
    }
 
245
 
 
246
        // pc not found, erase and populate
 
247
    if(!found && reload)
 
248
    {
 
249
        gtk_list_store_clear(store);
 
250
        clist_populate(store, ti68k_debug_get_pc());
 
251
    }
 
252
 
 
253
    // repopulate so that 3 instructions are still visible at the bottom of the list
 
254
    if(found && reload)
 
255
    {
 
256
        if(NLINES - found < offset)
 
257
        {
 
258
            gtk_list_store_clear(store);
 
259
            clist_populate(store, addr3);
 
260
        }
 
261
    }
 
262
 
 
263
    // look for pc and matching bkpt
 
264
    for(valid = gtk_tree_model_get_iter_first(model, &iter);
 
265
        valid; 
 
266
        valid = gtk_tree_model_iter_next(model, &iter))
 
267
    {
 
268
        GdkPixbuf *pix;
 
269
        gchar *str;
 
270
 
 
271
        gtk_tree_model_get(model, &iter, COL_ADDR, &str, -1);
 
272
        sscanf(str, "%x", &addr);
 
273
 
 
274
                color = (addr == pc) ? &color2 : &color1;
 
275
 
 
276
        if(g_list_find(bkpts.code, GINT_TO_POINTER(addr)) != NULL)
 
277
            pix = create_pixbuf("bkpt.xpm");
 
278
                else if(g_list_find(bkpts.code, GINT_TO_POINTER(addr|BKPT_TMP_MASK)) != NULL)
 
279
            pix = create_pixbuf("bkpt_tmp.xpm");
 
280
        else
 
281
            pix = create_pixbuf("void.xpm");
 
282
 
 
283
        gtk_list_store_set(store, &iter, COL_ICON, pix, COL_COLOR, color, -1);
 
284
        g_free(str);
 
285
                g_object_unref(pix);
 
286
    }
 
287
 
 
288
        // update cycle counter
 
289
        cyccnt_refresh(glade_get("label3"), glade_get("label4"));
 
290
}
 
291
 
 
292
static GtkWidget *list;
 
293
static GtkListStore *store;
 
294
static GtkWidget *combo;
 
295
 
 
296
typedef struct {
 
297
        GtkWidget *b1;
 
298
        GtkWidget *b2;
 
299
        GtkWidget *b3;
 
300
        GtkWidget *b4;
 
301
        GtkWidget *b5;
 
302
        GtkWidget *b6;
 
303
        GtkWidget *b7;
 
304
} TB;
 
305
static TB tb;
 
306
 
 
307
typedef struct {
 
308
    GtkWidget *m1;
 
309
    GtkWidget *m2;
 
310
    GtkWidget *m3;
 
311
    GtkWidget *m4;
 
312
    GtkWidget *m5;
 
313
        GtkWidget *m6;
 
314
} MI;
 
315
static MI mi;
 
316
 
 
317
static void tb_set_states(int s1, int s2, int s3, int s4, int s5, int s6, int s7)
 
318
{
 
319
        gtk_widget_set_sensitive(tb.b1, s1);
 
320
        gtk_widget_set_sensitive(tb.b2, s2);
 
321
        gtk_widget_set_sensitive(tb.b3, s3);
 
322
        gtk_widget_set_sensitive(tb.b4, s4);
 
323
        gtk_widget_set_sensitive(tb.b5, s5);
 
324
        gtk_widget_set_sensitive(tb.b6, s6);
 
325
        gtk_widget_set_sensitive(tb.b7, s7);
 
326
 
 
327
    gtk_widget_set_sensitive(mi.m1, s1);
 
328
        gtk_widget_set_sensitive(mi.m2, s2);
 
329
        gtk_widget_set_sensitive(mi.m3, s3);
 
330
        gtk_widget_set_sensitive(mi.m4, s4);
 
331
        gtk_widget_set_sensitive(mi.m5, s5);
 
332
        gtk_widget_set_sensitive(mi.m6, s6);
 
333
}
 
334
 
 
335
/*
 
336
        Display source code window
 
337
*/
 
338
 
 
339
extern int update_submenu(GtkWidget*, gpointer);
 
340
 
 
341
GtkWidget* dbgcode_create_window(void)
 
342
{
 
343
        GtkWidget *dbox;
 
344
    GtkWidget *data;    
 
345
        
 
346
        xml = glade_xml_new
 
347
                (tilp_paths_build_glade("dbg_code-2.glade"), "dbgcode_window",
 
348
                 PACKAGE);
 
349
        if (!xml)
 
350
                g_error(_("%s: GUI loading failed !\n"), __FILE__);
 
351
        glade_xml_signal_autoconnect(xml);
 
352
 
 
353
        dbox = glade_xml_get_widget(xml, "dbgcode_window");
 
354
#ifdef WND_TRANSIENT
 
355
        gtk_window_set_transient_for(GTK_WINDOW(dbox), GTK_WINDOW(main_wnd));
 
356
#endif
 
357
 
 
358
    data = glade_xml_get_widget(xml, "windows1_menu");
 
359
    g_signal_connect(G_OBJECT(data), "map", G_CALLBACK(update_submenu), NULL);
 
360
 
 
361
        tb.b1 = glade_xml_get_widget(xml, "button1");
 
362
        tb.b2 = glade_xml_get_widget(xml, "button2");
 
363
        tb.b3 = glade_xml_get_widget(xml, "button3");
 
364
        tb.b4 = glade_xml_get_widget(xml, "button4");
 
365
        tb.b5 = glade_xml_get_widget(xml, "button5");
 
366
        tb.b6 = glade_xml_get_widget(xml, "button6");
 
367
        tb.b7 = glade_xml_get_widget(xml, "button7");
 
368
 
 
369
    mi.m1 = glade_xml_get_widget(xml, "run1");
 
370
    mi.m2 = glade_xml_get_widget(xml, "step1");
 
371
    mi.m3 = glade_xml_get_widget(xml, "step_over1");
 
372
        mi.m4 = glade_xml_get_widget(xml, "step_out1");
 
373
    mi.m5 = glade_xml_get_widget(xml, "run_to_cursor1");
 
374
    mi.m6 = glade_xml_get_widget(xml, "break1");        
 
375
 
 
376
        list = glade_xml_get_widget(xml, "treeview1");
 
377
    store = clist_create(list);
 
378
        clist_populate(store, ti68k_debug_get_pc());
 
379
 
 
380
        gtk_tree_view_expand_all(GTK_TREE_VIEW(list));
 
381
        gtk_widget_show(list);
 
382
 
 
383
        data = glade_xml_get_widget(xml, "progressbar1");
 
384
        gtk_widget_hide(data);
 
385
 
 
386
        dbgromcall_create_window(xml);
 
387
 
 
388
        already_open = !0;
 
389
 
 
390
        return wnd = dbox;
 
391
}
 
392
 
 
393
GtkWidget* dbgcode_display_window(void)
 
394
{
 
395
        if(!already_open)
 
396
                wnd = dbgcode_create_window();
 
397
    
 
398
#ifdef WND_STATE
 
399
        if(!options3.code.minimized)
 
400
        {
 
401
                gtk_window_resize(GTK_WINDOW(wnd), options3.code.rect.w, options3.code.rect.h);
 
402
                gtk_window_move(GTK_WINDOW(wnd), options3.code.rect.x, options3.code.rect.y);
 
403
        }
 
404
        else
 
405
                gtk_window_iconify(GTK_WINDOW(wnd));
 
406
#endif
 
407
 
 
408
        gtk_widget_set_sensitive(list, TRUE);   
 
409
        tb_set_states(1, 1, 1, 1, 1, 0, 1);
 
410
    set_other_windows_sensitivity(TRUE);
 
411
     
 
412
    gtk_list_store_clear(store);
 
413
        clist_refresh(store, TRUE);
 
414
 
 
415
        dbgromcall_refresh_window();
 
416
        gtk_widget_show(wnd);
 
417
 
 
418
    return wnd;
 
419
}
 
420
 
 
421
void dbgcode_refresh_window(void)
 
422
{
 
423
        if(options3.code.visible)
 
424
        {
 
425
                gtk_list_store_clear(store);
 
426
                clist_refresh(store, TRUE);
 
427
        }
 
428
}
 
429
 
 
430
void dbgcode_disasm_at(uint32_t addr)
 
431
{
 
432
        GtkTreeView *view = GTK_TREE_VIEW(list);
 
433
        GtkTreePath *path;
 
434
        //GtkTreeViewColumn *column;
 
435
 
 
436
    gtk_list_store_clear(store);
 
437
    clist_populate(store, addr);
 
438
 
 
439
        //set selection
 
440
        path = gtk_tree_path_new_from_string("0");
 
441
    gtk_tree_view_set_cursor(view, path, NULL, FALSE);
 
442
        //gtk_tree_view_row_activated(view, path, column);        // show selection
 
443
    gtk_tree_path_free(path);
 
444
}
 
445
 
 
446
 
 
447
GLADE_CB void
 
448
on_quit1_activate                      (GtkMenuItem     *menuitem,
 
449
                                        gpointer         user_data);
 
450
 
 
451
GLADE_CB void
 
452
on_run1_activate                       (GtkMenuItem     *menuitem,
 
453
                                        gpointer         user_data)
 
454
{
 
455
#if 0
 
456
        tb_set_states(0, 0, 0, 0, 0, 1, 0);
 
457
    gtk_widget_set_sensitive(list, FALSE);
 
458
    set_other_windows_sensitivity(FALSE);
 
459
 
 
460
        ti68k_debug_step();     // skip possible current bkpt
 
461
    ti68k_engine_start();
 
462
#else
 
463
        on_quit1_activate(menuitem, user_data);
 
464
#endif
 
465
}
 
466
 
 
467
 
 
468
GLADE_CB void
 
469
on_step1_activate                      (GtkMenuItem     *menuitem,
 
470
                                        gpointer         user_data)
 
471
{
 
472
    static int i =0;
 
473
 
 
474
        ti68k_debug_step();
 
475
 
 
476
        clist_refresh(store, TRUE);
 
477
    dbgregs_refresh_window();
 
478
        dbgpclog_refresh_window();
 
479
    dbgmem_refresh_window();
 
480
        dbgstack_refresh_window();
 
481
 
 
482
    // force refresh !
 
483
    while(gtk_events_pending()) gtk_main_iteration_do(FALSE);
 
484
}
 
485
 
 
486
 
 
487
GLADE_CB void
 
488
on_step_over1_activate                 (GtkMenuItem     *menuitem,
 
489
                                        gpointer         user_data)
 
490
{
 
491
        tb_set_states(0, 0, 0, 0, 0, 1, 0);
 
492
    ti68k_debug_step_over();
 
493
        tb_set_states(1, 1, 1, 1, 1, 0, 1);
 
494
 
 
495
        clist_refresh(store, TRUE);
 
496
    dbgregs_refresh_window();
 
497
        dbgpclog_refresh_window();
 
498
    dbgmem_refresh_window();
 
499
        dbgstack_refresh_window();
 
500
 
 
501
        // force refresh !
 
502
    while(gtk_events_pending()) gtk_main_iteration_do(FALSE);
 
503
}
 
504
 
 
505
GLADE_CB void
 
506
on_step_out1_activate                 (GtkMenuItem     *menuitem,
 
507
                                        gpointer         user_data)
 
508
{
 
509
    ti68k_debug_step_out();
 
510
 
 
511
        clist_refresh(store, TRUE);
 
512
    dbgregs_refresh_window();
 
513
        dbgpclog_refresh_window();
 
514
    dbgmem_refresh_window();
 
515
        dbgstack_refresh_window();
 
516
 
 
517
        // force refresh !
 
518
    while(gtk_events_pending()) gtk_main_iteration_do(FALSE);
 
519
}
 
520
 
 
521
 
 
522
GLADE_CB void
 
523
on_run_to_cursor1_activate             (GtkMenuItem     *menuitem,
 
524
                                        gpointer         user_data)
 
525
{
 
526
    //GtkWidget *list = (GtkWidget *)(menuitem);   // arg are swapped, why ?
 
527
        GtkTreeView *view = GTK_TREE_VIEW(list);
 
528
        GtkTreeModel *model = gtk_tree_view_get_model(view);
 
529
        GtkListStore *store = GTK_LIST_STORE(model);
 
530
    GtkTreeSelection *selection;
 
531
    GtkTreeIter iter;
 
532
    gboolean valid;
 
533
    gchar *str;
 
534
    uint32_t addr;
 
535
 
 
536
    selection = gtk_tree_view_get_selection(view);
 
537
    valid = gtk_tree_selection_get_selected(selection, NULL, &iter);
 
538
        if(!valid) return;
 
539
 
 
540
    // Get address to go
 
541
    gtk_tree_model_get(model, &iter, COL_ADDR, &str, -1);
 
542
    sscanf(str, "%x", &addr);
 
543
 
 
544
        tb_set_states(0, 0, 0, 0, 0, 1, 0);
 
545
    set_other_windows_sensitivity(FALSE);
 
546
 
 
547
    ti68k_debug_skip(addr);
 
548
    gtk_tree_selection_unselect_iter(selection, &iter);
 
549
 
 
550
        tb_set_states(1, 1, 1, 1, 1, 0, 1);
 
551
    set_other_windows_sensitivity(TRUE);
 
552
    
 
553
        clist_refresh(store, FALSE);
 
554
    dbgregs_refresh_window();
 
555
        dbgpclog_refresh_window();
 
556
    dbgmem_refresh_window();
 
557
        dbgstack_refresh_window();
 
558
}
 
559
 
 
560
 
 
561
GLADE_CB void
 
562
on_break1_activate                     (GtkMenuItem     *menuitem,
 
563
                                        gpointer         user_data)
 
564
{
 
565
    // Mode 1 is fastest
 
566
#if 0
 
567
    //GtkWidget *list = (GtkWidget *)(menuitem);   // arg are swapped, why ?
 
568
        GtkTreeView *view = GTK_TREE_VIEW(list);
 
569
        GtkTreeModel *model = gtk_tree_view_get_model(view);
 
570
        GtkListStore *store = GTK_LIST_STORE(model);
 
571
 
 
572
    ti68k_engine_stop();
 
573
    gtk_widget_set_sensitive(list, TRUE);
 
574
        tb_set_states(1, 1, 1, 1, 1, 0, 1);
 
575
    set_other_windows_sensitivity(TRUE);
 
576
    clist_refresh(store);
 
577
#else
 
578
    ti68k_debug_break();
 
579
#endif
 
580
}
 
581
 
 
582
 
 
583
// Toggle breakpoint
 
584
GLADE_CB void
 
585
dbgcode_button6_clicked                     (GtkButton       *button,
 
586
                                        gpointer         user_data)
 
587
{
 
588
    //GtkWidget *list = GTK_WIDGET(button);   // arg are swapped, why ?
 
589
        GtkTreeView *view = GTK_TREE_VIEW(list);
 
590
        GtkTreeModel *model = gtk_tree_view_get_model(view);
 
591
        GtkListStore *store = GTK_LIST_STORE(model);
 
592
    GtkTreeSelection *selection;
 
593
    GtkTreeIter iter;
 
594
    gboolean valid;
 
595
    gchar *str;
 
596
    uint32_t addr;
 
597
 
 
598
    selection = gtk_tree_view_get_selection(view);
 
599
    valid = gtk_tree_selection_get_selected(selection, NULL, &iter);
 
600
        if(!valid) return;
 
601
 
 
602
    gtk_tree_model_get(model, &iter, COL_ADDR, &str, -1);
 
603
    sscanf(str, "%x", &addr);
 
604
 
 
605
    if(g_list_find(bkpts.code, GINT_TO_POINTER(addr)) == NULL)
 
606
        ti68k_bkpt_add_address(addr);
 
607
    else
 
608
        ti68k_bkpt_del_address(addr);
 
609
 
 
610
    clist_refresh(store, FALSE);
 
611
    dbgregs_refresh_window();
 
612
        dbgpclog_refresh_window();
 
613
    dbgmem_refresh_window();
 
614
    dbgbkpts_refresh_window();
 
615
        dbgstack_refresh_window();
 
616
}
 
617
 
 
618
// Toggle tmp breakpoint
 
619
GLADE_CB void
 
620
dbgcode_button7_clicked                     (GtkButton       *button,
 
621
                                        gpointer         user_data)
 
622
{
 
623
    //GtkWidget *list = GTK_WIDGET(button);   // arg are swapped, why ?
 
624
        GtkTreeView *view = GTK_TREE_VIEW(list);
 
625
        GtkTreeModel *model = gtk_tree_view_get_model(view);
 
626
        GtkListStore *store = GTK_LIST_STORE(model);
 
627
    GtkTreeSelection *selection;
 
628
    GtkTreeIter iter;
 
629
    gboolean valid;
 
630
    gchar *str;
 
631
    uint32_t addr;
 
632
 
 
633
    selection = gtk_tree_view_get_selection(view);
 
634
    valid = gtk_tree_selection_get_selected(selection, NULL, &iter);
 
635
        if(!valid) return;
 
636
 
 
637
    gtk_tree_model_get(model, &iter, COL_ADDR, &str, -1);
 
638
    sscanf(str, "%x", &addr);
 
639
 
 
640
    if(g_list_find(bkpts.code, GINT_TO_POINTER(addr | BKPT_TMP_MASK)) == NULL)
 
641
        ti68k_bkpt_add_address(addr | BKPT_TMP_MASK);
 
642
    else
 
643
        ti68k_bkpt_del_address(addr | BKPT_TMP_MASK);
 
644
 
 
645
    clist_refresh(store, FALSE);
 
646
    dbgregs_refresh_window();
 
647
        dbgpclog_refresh_window();
 
648
    dbgmem_refresh_window();
 
649
    dbgbkpts_refresh_window();
 
650
        dbgstack_refresh_window();
 
651
}
 
652
 
 
653
// Reset cycle counter
 
654
GLADE_CB void
 
655
dbgcode_button8_clicked                     (GtkButton       *button,
 
656
                                        gpointer         user_data)
 
657
{
 
658
        ti68k_get_cycle_count(!0, NULL);
 
659
        gtk_label_set_text(GTK_LABEL(glade_get("label3")), "0");
 
660
}
 
661
 
 
662
/***** Popup menu *****/
 
663
 
 
664
/*
 
665
        Display popup menu (right click)
 
666
*/
 
667
static GtkWidget* display_popup_menu(void)
 
668
{
 
669
        GladeXML *xml;
 
670
        GtkWidget *menu;
 
671
 
 
672
        xml = glade_xml_new
 
673
            (tilp_paths_build_glade("dbg_code-2.glade"), "dbgcode_popup",
 
674
             PACKAGE);
 
675
        if (!xml)
 
676
                g_error(_("%s: GUI loading failed !\n"), __FILE__);
 
677
        glade_xml_signal_autoconnect(xml);
 
678
 
 
679
        menu = glade_xml_get_widget(xml, "dbgcode_popup");
 
680
        return menu;
 
681
}
 
682
 
 
683
GLADE_CB gboolean
 
684
on_treeview1_button_press_event        (GtkWidget       *widget,
 
685
                                        GdkEventButton  *event,
 
686
                                        gpointer         user_data)
 
687
{
 
688
    switch (event->type) 
 
689
    {
 
690
    case GDK_BUTTON_PRESS:      // third button clicked
 
691
            if (event->button == 3) 
 
692
        {
 
693
            GdkEventButton *bevent;
 
694
            GtkWidget *menu;
 
695
 
 
696
                    bevent = (GdkEventButton *) (event);
 
697
            menu = display_popup_menu();
 
698
 
 
699
                    gtk_menu_popup(GTK_MENU(menu),
 
700
                                       NULL, NULL, NULL, NULL,
 
701
                                       bevent->button, bevent->time);
 
702
                gtk_widget_show(menu);
 
703
 
 
704
                    return TRUE;
 
705
            }
 
706
            break;
 
707
    default:
 
708
        break;
 
709
    }
 
710
 
 
711
    return FALSE;
 
712
}
 
713
 
 
714
static int export_disasm_to_file(GtkWidget *widget)
 
715
{
 
716
        GtkTreeView *view = GTK_TREE_VIEW(widget);
 
717
        GtkTreeModel *model = gtk_tree_view_get_model(view);
 
718
        GtkListStore *store = GTK_LIST_STORE(model);
 
719
    GtkTreeIter iter;
 
720
    gchar *str;
 
721
    uint32_t addr, start;
 
722
    gchar *output;
 
723
    int offset;
 
724
        int i, j;
 
725
 
 
726
        FILE *f;
 
727
        gchar **split;
 
728
 
 
729
    // starting address
 
730
    gtk_tree_model_get_iter_first(model, &iter);
 
731
    gtk_tree_model_get(model, &iter, COL_ADDR, &str, -1);
 
732
    sscanf(str, "%x", &start);
 
733
 
 
734
#ifdef __WIN32__
 
735
        f = fopen("C:\\disasm.txt", "a+t");
 
736
#else
 
737
        f = fopen("/tmp/disasm.txt", "a+t");
 
738
#endif
 
739
        if(f == NULL)
 
740
                return -1;
 
741
 
 
742
        addr = start;
 
743
        for(i = 0; i < NLINES; i++)
 
744
        {
 
745
                offset = ti68k_debug_disassemble(addr, &output);
 
746
                addr += offset;
 
747
 
 
748
                split = g_strsplit(output, " ", 3);
 
749
                g_free(output);
 
750
 
 
751
                fprintf(f, "%s\t%s", split[0], split[1]);
 
752
                for(j=10-strlen(split[1]); j >= 0; j--)
 
753
                        fprintf(f, " ");
 
754
                fprintf(f, "\t%s", split[2]);
 
755
                for(j=16-strlen(split[2]); j >= 0; j--)
 
756
                        fprintf(f, " ");
 
757
                fprintf(f, "\t;\n");
 
758
                g_strfreev(split);
 
759
        }
 
760
 
 
761
        fclose(f);
 
762
 
 
763
        return 0;
 
764
}
 
765
 
 
766
// used to implement accelerator keys
 
767
GLADE_CB void
 
768
on_go_to_address1_activate             (GtkMenuItem     *menuitem,
 
769
                                        gpointer         user_data);
 
770
GLADE_CB void
 
771
on_set_tmp_bkpt1_activate            (GtkMenuItem     *menuitem,
 
772
                                        gpointer         user_data);
 
773
GLADE_CB void
 
774
on_set_breakpoint1_activate            (GtkMenuItem     *menuitem,
 
775
                                        gpointer         user_data);
 
776
 
 
777
GLADE_CB void
 
778
on_set_pc_to_selection1_activate       (GtkMenuItem     *menuitem,
 
779
                                        gpointer         user_data);
 
780
 
 
781
GLADE_CB gboolean
 
782
on_treeview1_key_press_event           (GtkWidget       *widget,
 
783
                                        GdkEventKey     *event,
 
784
                                        gpointer         user_data)
 
785
{
 
786
    GtkTreeView *view = GTK_TREE_VIEW(widget);
 
787
        GtkTreeModel *model = gtk_tree_view_get_model(view);
 
788
        GtkListStore *store = GTK_LIST_STORE(model);
 
789
    GtkTreeSelection *selection;
 
790
    GtkTreeIter iter;
 
791
    GtkTreePath *path;
 
792
    gboolean valid;
 
793
    gchar *str;
 
794
    gchar *row;
 
795
    gint row_idx, row_max;
 
796
    uint32_t addr, start;
 
797
    gchar *output;
 
798
    int offset;
 
799
 
 
800
    // starting address
 
801
    gtk_tree_model_get_iter_first(model, &iter);
 
802
    gtk_tree_model_get(model, &iter, COL_ADDR, &str, -1);
 
803
    sscanf(str, "%x", &start);
 
804
 
 
805
    // current address
 
806
    selection = gtk_tree_view_get_selection(view);
 
807
    valid = gtk_tree_selection_get_selected(selection, NULL, &iter);
 
808
    if(valid)
 
809
    {
 
810
        gtk_tree_model_get(model, &iter, COL_ADDR, &str, -1);
 
811
        sscanf(str, "%x", &addr);
 
812
 
 
813
        row = gtk_tree_model_get_string_from_iter(model, &iter);
 
814
        sscanf(row, "%i", &row_idx);
 
815
        row_max = gtk_tree_model_iter_n_children(model, NULL) - 1;
 
816
    }
 
817
    else
 
818
        row_idx = row_max = -1;
 
819
 
 
820
    // bind our key
 
821
        switch(event->keyval) 
 
822
        {
 
823
        case GDK_F2:
 
824
                on_set_breakpoint1_activate(NULL, NULL);
 
825
                return FALSE;
 
826
        case GDK_F3:
 
827
                on_set_tmp_bkpt1_activate(NULL, NULL);
 
828
                return FALSE;
 
829
        case GDK_F6:
 
830
                export_disasm_to_file(widget);
 
831
                return FALSE;
 
832
        case GDK_F1:
 
833
                str = g_strdup_printf("%i", row_idx+1);
 
834
        path = gtk_tree_path_new_from_string(str);      // restore selection
 
835
                g_free(str);
 
836
        gtk_tree_selection_select_path(selection, path);
 
837
                on_set_pc_to_selection1_activate(NULL, user_data);
 
838
                return FALSE;
 
839
        case GDK_G:
 
840
        case GDK_g:
 
841
                on_go_to_address1_activate(NULL, user_data);
 
842
                return TRUE;
 
843
 
 
844
    case GDK_Up:
 
845
        if(row_max == -1)
 
846
            break;
 
847
 
 
848
        if(row_idx > 0)
 
849
            break;
 
850
 
 
851
        gtk_list_store_clear(store);
 
852
        clist_populate(store, addr - 2);
 
853
        return FALSE;
 
854
 
 
855
    case GDK_Down:
 
856
        if(row_max == -1)
 
857
            break;
 
858
 
 
859
        if(row_idx < row_max)
 
860
            break;
 
861
 
 
862
        offset = ti68k_debug_disassemble(start, &output);
 
863
                g_free(output);
 
864
 
 
865
        gtk_list_store_clear(store);
 
866
        clist_populate(store, start + offset);
 
867
    
 
868
        str = g_strdup_printf("%i", row_max);
 
869
        path = gtk_tree_path_new_from_string(str);      // restore selection
 
870
                g_free(str);
 
871
        gtk_tree_selection_select_path(selection, path);
 
872
 
 
873
        return TRUE;
 
874
 
 
875
    case GDK_Page_Up:
 
876
        if(row_max == -1)
 
877
            break;
 
878
 
 
879
        if(row_idx > 0)
 
880
            break;
 
881
 
 
882
        gtk_list_store_clear(store);
 
883
        clist_populate(store, addr - 0x10);
 
884
 
 
885
                path = gtk_tree_path_new_from_string("0");
 
886
        gtk_tree_view_set_cursor(view, path, NULL, FALSE);
 
887
 
 
888
        return TRUE;
 
889
 
 
890
    case GDK_Page_Down:
 
891
        if(row_max == -1)
 
892
            break;
 
893
 
 
894
        if(row_idx < row_max)
 
895
            break;
 
896
 
 
897
        gtk_list_store_clear(store);
 
898
        clist_populate(store, addr/* + 0x10*/);
 
899
 
 
900
                str = g_strdup_printf("%i", row_max);
 
901
        path = gtk_tree_path_new_from_string(str);      // restore selection
 
902
                g_free(str);
 
903
        gtk_tree_selection_select_path(selection, path);
 
904
 
 
905
        return TRUE;
 
906
 
 
907
        default:
 
908
                return FALSE;
 
909
        }
 
910
 
 
911
        return FALSE;
 
912
}
 
913
 
 
914
// note: user_data data passing has been manually added to Glade file
 
915
GLADE_CB void
 
916
on_go_to_address1_activate             (GtkMenuItem     *menuitem,
 
917
                                        gpointer         user_data)
 
918
{
 
919
    uint32_t addr = 0;
 
920
 
 
921
    if(display_dbgmem_address(&addr) == -1)
 
922
                return;
 
923
 
 
924
    gtk_list_store_clear(store);
 
925
    clist_populate(store, addr);
 
926
}
 
927
 
 
928
 
 
929
GLADE_CB void
 
930
on_go_to_pc1_activate                  (GtkMenuItem     *menuitem,
 
931
                                        gpointer         user_data)
 
932
{
 
933
    clist_refresh(store, TRUE);
 
934
}
 
935
 
 
936
 
 
937
GLADE_CB void
 
938
on_set_breakpoint1_activate            (GtkMenuItem     *menuitem,
 
939
                                        gpointer         user_data)
 
940
{
 
941
    dbgcode_button6_clicked(NULL, NULL);
 
942
}
 
943
 
 
944
 
 
945
GLADE_CB void
 
946
on_set_tmp_bkpt1_activate            (GtkMenuItem     *menuitem,
 
947
                                        gpointer         user_data)
 
948
{
 
949
    dbgcode_button7_clicked(NULL, NULL);
 
950
}
 
951
 
 
952
 
 
953
GLADE_CB void
 
954
on_set_pc_to_selection1_activate       (GtkMenuItem     *menuitem,
 
955
                                        gpointer         user_data)
 
956
{
 
957
    //GtkWidget *list = GTK_WIDGET(user_data);
 
958
        GtkTreeView *view = GTK_TREE_VIEW(list);
 
959
        GtkTreeModel *model = gtk_tree_view_get_model(view);
 
960
        GtkListStore *store = GTK_LIST_STORE(model);
 
961
    GtkTreeSelection *selection;
 
962
    GtkTreeIter iter;
 
963
    gboolean valid;
 
964
    gchar *str;
 
965
    uint32_t addr;
 
966
 
 
967
    selection = gtk_tree_view_get_selection(view);
 
968
    valid = gtk_tree_selection_get_selected(selection, NULL, &iter);
 
969
        if(!valid) return;
 
970
    gtk_tree_model_get(model, &iter, COL_ADDR, &str, -1);
 
971
    sscanf(str, "%x", &addr);
 
972
 
 
973
    ti68k_register_set_pc(addr);
 
974
    dbgcode_refresh_window();
 
975
    dbgregs_refresh_window();
 
976
    dbgmem_refresh_window();
 
977
}
 
978
 
 
979
GLADE_CB void
 
980
on_view_memory1_activate       (GtkMenuItem     *menuitem,
 
981
                                gpointer         user_data)
 
982
{
 
983
    //GtkWidget *list = GTK_WIDGET(user_data);
 
984
        GtkTreeView *view = GTK_TREE_VIEW(list);
 
985
        GtkTreeModel *model = gtk_tree_view_get_model(view);
 
986
        GtkListStore *store = GTK_LIST_STORE(model);
 
987
    GtkTreeSelection *selection;
 
988
    GtkTreeIter iter;
 
989
    gboolean valid;
 
990
    gchar *str;
 
991
    uint32_t addr;
 
992
 
 
993
    selection = gtk_tree_view_get_selection(view);
 
994
    valid = gtk_tree_selection_get_selected(selection, NULL, &iter);
 
995
        if(!valid) return;
 
996
    gtk_tree_model_get(model, &iter, COL_ADDR, &str, -1);
 
997
    sscanf(str, "%x", &addr);
 
998
    
 
999
    printf("addr = %x\n", addr);
 
1000
    dbgmem_add_tab(addr);
 
1001
}
 
1002
 
 
1003
 
 
1004
GLADE_CB void
 
1005
on_treeview1_size_allocate             (GtkWidget       *widget,
 
1006
                                        GdkRectangle    *allocation,
 
1007
                                        gpointer         user_data)
 
1008
{
 
1009
#ifndef FIXED_SIZE
 
1010
        GtkTreeView *view = GTK_TREE_VIEW(list);
 
1011
        GtkTreePath *path;
 
1012
        GdkRectangle rect;
 
1013
        static int old = 0;
 
1014
 
 
1015
        path = gtk_tree_path_new_from_string("0");
 
1016
        gtk_tree_view_get_background_area(view, path, NULL, &rect);
 
1017
        g_free(path);
 
1018
 
 
1019
        if(rect.height == 0)
 
1020
                return;
 
1021
 
 
1022
        NLINES = allocation->height / rect.height - 1;
 
1023
        //printf("#lines: %i (%i %i)\n", NLINES, allocation->height, rect.height);
 
1024
 
 
1025
        if(old != NLINES)
 
1026
        {       
 
1027
                gtk_list_store_clear(store);
 
1028
                clist_refresh(store, TRUE);
 
1029
        }
 
1030
 
 
1031
        old = NLINES;
 
1032
#endif
 
1033
}