Search
lxdream.org :: lxdream/src/gui/gui.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/gui/gui.c
changeset 1:eea311cfd33e
next2:42349f6ea216
author nkeynes
date Sat Mar 13 00:03:32 2004 +0000 (18 years ago)
permissions -rw-r--r--
last change This commit was generated by cvs2svn to compensate for changes in r2,
which included commits to RCS files with non-trunk default branches.
file annotate diff log raw
nkeynes@1
     1
#include <stdlib.h>
nkeynes@1
     2
#include <stdarg.h>
nkeynes@1
     3
#include <gnome.h>
nkeynes@1
     4
#include <math.h>
nkeynes@1
     5
#include "gui.h"
nkeynes@1
     6
#include "mem.h"
nkeynes@1
     7
#include "sh4dasm.h"
nkeynes@1
     8
#include "sh4core.h"
nkeynes@1
     9
nkeynes@1
    10
#define REGISTER_FONT "-*-fixed-medium-r-normal--12-*-*-*-*-*-iso8859-1"
nkeynes@1
    11
nkeynes@1
    12
#define REG_INT 0
nkeynes@1
    13
#define REG_FLT 1
nkeynes@1
    14
#define REG_SPECIAL 2
nkeynes@1
    15
nkeynes@1
    16
struct reg_map_struct {
nkeynes@1
    17
    char *name;
nkeynes@1
    18
    int type;
nkeynes@1
    19
    void *value;
nkeynes@1
    20
} reg_map[] = { {"R0", REG_INT, &sh4r.r[0]}, {"R1", REG_INT, &sh4r.r[1]},
nkeynes@1
    21
                {"R2", REG_INT, &sh4r.r[2]}, {"R3", REG_INT, &sh4r.r[3]},
nkeynes@1
    22
                {"R4", REG_INT, &sh4r.r[4]}, {"R5", REG_INT, &sh4r.r[5]},
nkeynes@1
    23
                {"R6", REG_INT, &sh4r.r[6]}, {"R7", REG_INT, &sh4r.r[7]},
nkeynes@1
    24
                {"R8", REG_INT, &sh4r.r[8]}, {"R9", REG_INT, &sh4r.r[9]},
nkeynes@1
    25
                {"R10",REG_INT, &sh4r.r[10]}, {"R11",REG_INT, &sh4r.r[11]},
nkeynes@1
    26
                {"R12",REG_INT, &sh4r.r[12]}, {"R13",REG_INT, &sh4r.r[13]},
nkeynes@1
    27
                {"R14",REG_INT, &sh4r.r[14]}, {"R15",REG_INT, &sh4r.r[15]},
nkeynes@1
    28
                {"SR", REG_INT, &sh4r.sr}, {"GBR", REG_INT, &sh4r.gbr},
nkeynes@1
    29
                {"SSR",REG_INT, &sh4r.ssr}, {"SPC", REG_INT, &sh4r.spc},
nkeynes@1
    30
                {"SGR",REG_INT, &sh4r.sgr}, {"DBR", REG_INT, &sh4r.dbr},
nkeynes@1
    31
                {"VBR",REG_INT, &sh4r.vbr},
nkeynes@1
    32
                {"PC", REG_INT, &sh4r.pc}, {"PR", REG_INT, &sh4r.pr},
nkeynes@1
    33
                {"MACL",REG_INT, &sh4r.mac},{"MACH",REG_INT, ((uint32_t *)&sh4r.mac)+1},
nkeynes@1
    34
                {"FPUL", REG_INT, &sh4r.fpul}, {"FPSCR", REG_INT, &sh4r.fpscr},
nkeynes@1
    35
                {NULL, 0, NULL} };
nkeynes@1
    36
nkeynes@1
    37
GtkCList *msgs, *regs, *disasm;
nkeynes@1
    38
GdkColor clrNormal, clrChanged, clrError, clrWarn, clrPC, clrDebug, clrTrace;
nkeynes@1
    39
GtkEntry *page_field;
nkeynes@1
    40
GnomeAppBar *appbar;
nkeynes@1
    41
GtkProgressBar *icounter;
nkeynes@1
    42
char icounter_text[16];
nkeynes@1
    43
GtkStyle *fixed_list_style;
nkeynes@1
    44
PangoFontDescription *fixed_list_font;
nkeynes@1
    45
GdkColor *msg_colors[] = { &clrError, &clrError, &clrWarn, &clrNormal,
nkeynes@1
    46
                           &clrDebug, &clrTrace };
nkeynes@1
    47
nkeynes@1
    48
struct sh4_registers sh4r_s;
nkeynes@1
    49
int disasm_from = -1, disasm_to = -1;
nkeynes@1
    50
int disasm_pc = -1;
nkeynes@1
    51
nkeynes@1
    52
void open_file_callback(GtkWidget *btn, gpointer user_data);
nkeynes@1
    53
void open_file_canceled(GtkWidget *btn, gpointer user_data);
nkeynes@1
    54
void open_file( char *filename );
nkeynes@1
    55
nkeynes@1
    56
/*
nkeynes@1
    57
 * Check for changed registers and update the display
nkeynes@1
    58
 */
nkeynes@1
    59
void update_registers( void )
nkeynes@1
    60
{
nkeynes@1
    61
    int i;
nkeynes@1
    62
    for( i=0; reg_map[i].name != NULL; i++ ) {
nkeynes@1
    63
        if( reg_map[i].type == REG_INT ) {
nkeynes@1
    64
            /* Yes this _is_ probably fairly evil */
nkeynes@1
    65
            if( *((uint32_t *)reg_map[i].value) !=
nkeynes@1
    66
                *((uint32_t *)((char *)&sh4r_s + ((char *)reg_map[i].value - (char *)&sh4r))) ) {
nkeynes@1
    67
                char buf[20];
nkeynes@1
    68
                sprintf( buf, "%08X", *((uint32_t *)reg_map[i].value) );
nkeynes@1
    69
                gtk_clist_set_text( regs, i, 1, buf );
nkeynes@1
    70
                gtk_clist_set_foreground( regs, i, &clrChanged );
nkeynes@1
    71
            } else {
nkeynes@1
    72
                gtk_clist_set_foreground( regs, i, &clrNormal );
nkeynes@1
    73
            }
nkeynes@1
    74
        } else {
nkeynes@1
    75
            if( *((float *)reg_map[i].value) !=
nkeynes@1
    76
                *((float *)((char *)&sh4r_s + ((char *)reg_map[i].value - (char *)&sh4r))) ) {
nkeynes@1
    77
                char buf[20];
nkeynes@1
    78
                sprintf( buf, "%f", *((float *)reg_map[i].value) );
nkeynes@1
    79
                gtk_clist_set_text( regs, i, 1, buf );
nkeynes@1
    80
                gtk_clist_set_foreground( regs, i, &clrChanged );
nkeynes@1
    81
            } else {
nkeynes@1
    82
                gtk_clist_set_foreground( regs, i, &clrNormal );
nkeynes@1
    83
            }
nkeynes@1
    84
        }
nkeynes@1
    85
    }
nkeynes@1
    86
    if( sh4r.pc != sh4r_s.pc )
nkeynes@1
    87
        set_disassembly_pc( sh4r.pc, FALSE );
nkeynes@1
    88
    memcpy( &sh4r_s, &sh4r, sizeof(sh4r) );
nkeynes@1
    89
nkeynes@1
    90
    update_icount();
nkeynes@1
    91
    update_mmr_win();
nkeynes@1
    92
}
nkeynes@1
    93
nkeynes@1
    94
void update_icount( void )
nkeynes@1
    95
{
nkeynes@1
    96
    sprintf( icounter_text, "%d", sh4r.icount );
nkeynes@1
    97
    gtk_progress_bar_set_text( icounter, icounter_text );
nkeynes@1
    98
}
nkeynes@1
    99
nkeynes@1
   100
void set_disassembly_region( unsigned int page )
nkeynes@1
   101
{
nkeynes@1
   102
    uint32_t i, posn;
nkeynes@1
   103
    uint16_t op;
nkeynes@1
   104
    char buf[80];
nkeynes@1
   105
    char addr[10];
nkeynes@1
   106
    char opcode[6] = "";
nkeynes@1
   107
    char *arr[4] = { addr, " ", opcode, buf };
nkeynes@1
   108
    unsigned int from = page & 0xFFFFF000;
nkeynes@1
   109
    unsigned int to = from + 4096;
nkeynes@1
   110
    
nkeynes@1
   111
    gtk_clist_clear(disasm);
nkeynes@1
   112
nkeynes@1
   113
    sprintf( addr, "%08X", from );
nkeynes@1
   114
    gtk_entry_set_text( page_field, addr );
nkeynes@1
   115
nkeynes@1
   116
    if( !mem_has_page( from ) ) {
nkeynes@1
   117
        arr[3] = "This page is currently unmapped";
nkeynes@1
   118
        gtk_clist_append( disasm, arr );
nkeynes@1
   119
        gtk_clist_set_foreground( disasm, 0, &clrError );
nkeynes@1
   120
    } else {
nkeynes@1
   121
        for( i=from; i<to; i+=2 ) {
nkeynes@1
   122
            sh4_disasm_instruction( i, buf, sizeof(buf) );
nkeynes@1
   123
            sprintf( addr, "%08X", i );
nkeynes@1
   124
            op = mem_read_phys_word(i);
nkeynes@1
   125
            sprintf( opcode, "%02X %02X", op&0xFF, op>>8 );
nkeynes@1
   126
            posn = gtk_clist_append( disasm, arr );
nkeynes@1
   127
            if( buf[0] == '?' )
nkeynes@1
   128
                gtk_clist_set_foreground( disasm, posn, &clrWarn );
nkeynes@1
   129
        }
nkeynes@1
   130
        if( disasm_pc != -1 && disasm_pc >= from && disasm_pc < to )
nkeynes@1
   131
            gtk_clist_set_foreground( disasm, (disasm_pc - from)>>1,
nkeynes@1
   132
                                      &clrPC );
nkeynes@1
   133
    }
nkeynes@1
   134
nkeynes@1
   135
    if( page != from ) { /* not a page boundary */
nkeynes@1
   136
        gtk_clist_moveto( disasm, (page-from)>>1, 0, 0.5, 0.0 );
nkeynes@1
   137
    }
nkeynes@1
   138
    disasm_from = from;
nkeynes@1
   139
    disasm_to = to;
nkeynes@1
   140
}
nkeynes@1
   141
nkeynes@1
   142
void jump_to_disassembly( unsigned int addr, gboolean select )
nkeynes@1
   143
{
nkeynes@1
   144
    int row;
nkeynes@1
   145
    
nkeynes@1
   146
    if( addr < disasm_from || addr >= disasm_to )
nkeynes@1
   147
        set_disassembly_region(addr);
nkeynes@1
   148
nkeynes@1
   149
    row = (addr-disasm_from)>>1;
nkeynes@1
   150
    if(select) {
nkeynes@1
   151
        gtk_clist_select_row( disasm, row, 0 );
nkeynes@1
   152
    }
nkeynes@1
   153
    if( gtk_clist_row_is_visible( disasm, row ) != GTK_VISIBILITY_FULL ){
nkeynes@1
   154
        gtk_clist_moveto( disasm, row, 0, 0.5, 0.0 );
nkeynes@1
   155
    }
nkeynes@1
   156
}
nkeynes@1
   157
nkeynes@1
   158
void set_disassembly_pc( unsigned int pc, gboolean select )
nkeynes@1
   159
{
nkeynes@1
   160
    int row;
nkeynes@1
   161
    
nkeynes@1
   162
    jump_to_disassembly( pc, select );
nkeynes@1
   163
    if( disasm_pc != -1 && disasm_pc >= disasm_from && disasm_pc < disasm_to )
nkeynes@1
   164
        gtk_clist_set_foreground( disasm, (disasm_pc - disasm_from)>>1,
nkeynes@1
   165
                                  &clrNormal );
nkeynes@1
   166
    row = (pc - disasm_from)>>1;
nkeynes@1
   167
    gtk_clist_set_foreground( disasm, row, &clrPC );
nkeynes@1
   168
    disasm_pc = pc;
nkeynes@1
   169
}
nkeynes@1
   170
nkeynes@1
   171
void open_file_callback(GtkWidget *btn, gpointer user_data) {
nkeynes@1
   172
    GtkFileSelection *file = GTK_FILE_SELECTION(user_data);
nkeynes@1
   173
    gchar *filename = strdup( gtk_file_selection_get_filename(
nkeynes@1
   174
        GTK_FILE_SELECTION(file) ) );
nkeynes@1
   175
    gtk_widget_destroy(GTK_WIDGET(file));
nkeynes@1
   176
    open_file( filename );
nkeynes@1
   177
    free(filename);
nkeynes@1
   178
}
nkeynes@1
   179
nkeynes@1
   180
void open_file_canceled(GtkWidget *btn, gpointer user_data) {
nkeynes@1
   181
    gtk_widget_destroy(GTK_WIDGET(user_data));
nkeynes@1
   182
}
nkeynes@1
   183
nkeynes@1
   184
void open_file_dialog( void )
nkeynes@1
   185
{
nkeynes@1
   186
    GtkWidget *file;
nkeynes@1
   187
nkeynes@1
   188
    file = gtk_file_selection_new( "Open..." );
nkeynes@1
   189
    gtk_signal_connect( GTK_OBJECT(GTK_FILE_SELECTION(file)->ok_button),
nkeynes@1
   190
                        "clicked", GTK_SIGNAL_FUNC(open_file_callback), file );
nkeynes@1
   191
    gtk_signal_connect( GTK_OBJECT(GTK_FILE_SELECTION(file)->cancel_button),
nkeynes@1
   192
                        "clicked", GTK_SIGNAL_FUNC(open_file_canceled), file );
nkeynes@1
   193
    gtk_widget_show( file );
nkeynes@1
   194
}
nkeynes@1
   195
nkeynes@1
   196
void emit( int level, int source, char *msg, ... )
nkeynes@1
   197
{
nkeynes@1
   198
    char buf[20], addr[10] = "", *p;
nkeynes@1
   199
    char *arr[3] = {buf, addr};
nkeynes@1
   200
    int posn;
nkeynes@1
   201
    time_t tm = time(NULL);
nkeynes@1
   202
    va_list ap;
nkeynes@1
   203
nkeynes@1
   204
    va_start(ap, msg);
nkeynes@1
   205
    p = g_strdup_vprintf( msg, ap );
nkeynes@1
   206
    strftime( buf, sizeof(buf), "%H:%M:%S", localtime(&tm) );
nkeynes@1
   207
    if( source != -1 )
nkeynes@1
   208
        sprintf( addr, "%08X", sh4r.pc );
nkeynes@1
   209
    arr[2] = p;
nkeynes@1
   210
    posn = gtk_clist_append(msgs, arr);
nkeynes@1
   211
    free(p);
nkeynes@1
   212
    va_end(ap);
nkeynes@1
   213
nkeynes@1
   214
    gtk_clist_set_foreground( msgs, posn, msg_colors[level] );
nkeynes@1
   215
    gtk_clist_moveto( msgs, posn, 0, 1.0, 0.0 );
nkeynes@1
   216
nkeynes@1
   217
    /* emit _really_ slows down the emu, to the point where the gui can be
nkeynes@1
   218
     * completely unresponsive if I don't include this:
nkeynes@1
   219
     */
nkeynes@1
   220
    while( gtk_events_pending() )
nkeynes@1
   221
        gtk_main_iteration();
nkeynes@1
   222
}
nkeynes@1
   223
nkeynes@1
   224
void init_debug_win(GtkWidget *win)
nkeynes@1
   225
{
nkeynes@1
   226
    GdkColormap *map;
nkeynes@1
   227
    GdkFont *regfont;
nkeynes@1
   228
    GtkAdjustment *adj;
nkeynes@1
   229
    int i;
nkeynes@1
   230
    char buf[20];
nkeynes@1
   231
    char *arr[2];
nkeynes@1
   232
nkeynes@1
   233
    clrNormal.red = clrNormal.green = clrNormal.blue = 0;
nkeynes@1
   234
    clrChanged.red = clrChanged.green = 64*256;
nkeynes@1
   235
    clrChanged.blue = 154*256;
nkeynes@1
   236
    clrError.red = 65535;
nkeynes@1
   237
    clrError.green = clrError.blue = 64*256;
nkeynes@1
   238
    clrPC.red = 32*256;
nkeynes@1
   239
    clrPC.green = 170*256;
nkeynes@1
   240
    clrPC.blue = 52*256;
nkeynes@1
   241
    clrWarn = clrChanged;
nkeynes@1
   242
    clrTrace.red = 156*256;
nkeynes@1
   243
    clrTrace.green = 78*256;
nkeynes@1
   244
    clrTrace.blue = 201*256;
nkeynes@1
   245
    clrDebug = clrPC;
nkeynes@1
   246
nkeynes@1
   247
    map = gdk_colormap_new(gdk_visual_get_best(), TRUE);
nkeynes@1
   248
    gdk_colormap_alloc_color(map, &clrNormal, TRUE, TRUE);
nkeynes@1
   249
    gdk_colormap_alloc_color(map, &clrChanged, TRUE, TRUE);
nkeynes@1
   250
    gdk_colormap_alloc_color(map, &clrError, TRUE, TRUE);
nkeynes@1
   251
    gdk_colormap_alloc_color(map, &clrWarn, TRUE, TRUE);
nkeynes@1
   252
    gdk_colormap_alloc_color(map, &clrPC, TRUE, TRUE);
nkeynes@1
   253
    gdk_colormap_alloc_color(map, &clrDebug, TRUE, TRUE);
nkeynes@1
   254
    gdk_colormap_alloc_color(map, &clrTrace, TRUE, TRUE);
nkeynes@1
   255
    
nkeynes@1
   256
    fixed_list_font = pango_font_description_from_string("Courier 10");
nkeynes@1
   257
    regs = gtk_object_get_data(GTK_OBJECT(win), "reg_list");
nkeynes@1
   258
    arr[1] = buf;
nkeynes@1
   259
    for( i=0; reg_map[i].name != NULL; i++ ) {
nkeynes@1
   260
        arr[0] = reg_map[i].name;
nkeynes@1
   261
        if( reg_map[i].type == REG_INT )
nkeynes@1
   262
            sprintf( buf, "%08X", *((uint32_t *)reg_map[i].value) );
nkeynes@1
   263
        else
nkeynes@1
   264
            sprintf( buf, "%f", *((float *)reg_map[i].value) );
nkeynes@1
   265
        gtk_clist_append( regs, arr );
nkeynes@1
   266
    }
nkeynes@1
   267
nkeynes@1
   268
    fixed_list_style = gtk_style_copy( gtk_rc_get_style( GTK_WIDGET(regs) ) );
nkeynes@1
   269
    if( fixed_list_style != NULL ) {
nkeynes@1
   270
        fixed_list_style->font_desc = fixed_list_font;
nkeynes@1
   271
        gtk_widget_set_style( GTK_WIDGET(regs), fixed_list_style );
nkeynes@1
   272
    }
nkeynes@1
   273
nkeynes@1
   274
    msgs = gtk_object_get_data(GTK_OBJECT(win), "output_list");
nkeynes@1
   275
    disasm = gtk_object_get_data(GTK_OBJECT(win), "disasm_list");
nkeynes@1
   276
    gtk_clist_set_column_width( disasm, 1, 16 );
nkeynes@1
   277
    page_field = gtk_object_get_data(GTK_OBJECT(win), "page_field");
nkeynes@1
   278
nkeynes@1
   279
    appbar = gtk_object_get_data(GTK_OBJECT(win), "debug_appbar");
nkeynes@1
   280
    icounter = gnome_appbar_get_progress( appbar );
nkeynes@1
   281
    gtk_progress_bar_set_text(icounter, "1");
nkeynes@1
   282
}
.