Search
lxdream.org :: lxdream/src/gui/debug_win.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/gui/debug_win.c
changeset 9:2784c7660165
prev8:6730608cdaf0
next10:c898b37506e0
author nkeynes
date Thu Dec 08 13:38:00 2005 +0000 (15 years ago)
permissions -rw-r--r--
last change Generalise the core debug window to allow multiple instances.
Add cpu description structure to define different cpus for use by the
debug window, in preparation for ARM implementation
file annotate diff log raw
nkeynes@2
     1
nkeynes@2
     2
#include <stdlib.h>
nkeynes@2
     3
#include <stdarg.h>
nkeynes@2
     4
#include <gnome.h>
nkeynes@2
     5
#include <math.h>
nkeynes@2
     6
#include "gui.h"
nkeynes@2
     7
#include "mem.h"
nkeynes@9
     8
#include "disasm.h"
nkeynes@2
     9
nkeynes@2
    10
GdkColor *msg_colors[] = { &clrError, &clrError, &clrWarn, &clrNormal,
nkeynes@2
    11
                           &clrDebug, &clrTrace };
nkeynes@2
    12
nkeynes@9
    13
struct debug_info_struct {
nkeynes@9
    14
    int disasm_from;
nkeynes@9
    15
    int disasm_to;
nkeynes@9
    16
    int disasm_pc;
nkeynes@9
    17
    struct cpu_desc_struct *cpu;
nkeynes@9
    18
    GtkCList *msgs_list;
nkeynes@9
    19
    GtkCList *regs_list;
nkeynes@9
    20
    GtkCList *disasm_list;
nkeynes@9
    21
    GtkEntry *page_field;
nkeynes@9
    22
    GtkProgressBar *icounter;
nkeynes@9
    23
    char icounter_text[16];
nkeynes@9
    24
    char saved_regs[0];
nkeynes@8
    25
};
nkeynes@8
    26
nkeynes@9
    27
debug_info_t init_debug_win(GtkWidget *win, struct cpu_desc_struct *cpu )
nkeynes@2
    28
{
nkeynes@2
    29
    int i;
nkeynes@2
    30
    char buf[20];
nkeynes@2
    31
    char *arr[2];
nkeynes@2
    32
    GnomeAppBar *appbar;
nkeynes@9
    33
    
nkeynes@9
    34
    debug_info_t data = g_malloc0( sizeof(struct debug_info_struct) + cpu->regs_size );
nkeynes@9
    35
    data->disasm_from = -1;
nkeynes@9
    36
    data->disasm_to = -1;
nkeynes@9
    37
    data->disasm_pc = -1;
nkeynes@9
    38
    data->cpu = cpu;
nkeynes@9
    39
    
nkeynes@9
    40
    data->regs_list= gtk_object_get_data(GTK_OBJECT(win), "reg_list");
nkeynes@9
    41
    arr[1] = buf;
nkeynes@9
    42
    for( i=0; data->cpu->regs_info[i].name != NULL; i++ ) {
nkeynes@9
    43
        arr[0] = data->cpu->regs_info[i].name;
nkeynes@9
    44
        if( data->cpu->regs_info->type == REG_INT )
nkeynes@9
    45
            sprintf( buf, "%08X", *((uint32_t *)data->cpu->regs_info->value) );
nkeynes@9
    46
        else
nkeynes@9
    47
            sprintf( buf, "%f", *((float *)data->cpu->regs_info->value) );
nkeynes@9
    48
        gtk_clist_append( data->regs_list, arr );
nkeynes@9
    49
    }
nkeynes@9
    50
    gtk_widget_modify_font( GTK_WIDGET(data->regs_list), fixed_list_font );
nkeynes@2
    51
nkeynes@9
    52
    data->msgs_list = gtk_object_get_data(GTK_OBJECT(win), "output_list");
nkeynes@9
    53
    data->disasm_list = gtk_object_get_data(GTK_OBJECT(win), "disasm_list");
nkeynes@9
    54
    gtk_clist_set_column_width( data->disasm_list, 1, 16 );
nkeynes@9
    55
    data->page_field = gtk_object_get_data(GTK_OBJECT(win), "page_field");
nkeynes@2
    56
nkeynes@2
    57
    appbar = gtk_object_get_data(GTK_OBJECT(win), "debug_appbar");
nkeynes@9
    58
    data->icounter = gnome_appbar_get_progress( appbar );
nkeynes@9
    59
    gtk_progress_bar_set_text(data->icounter, "1");
nkeynes@9
    60
nkeynes@9
    61
    gtk_object_set_data( GTK_OBJECT(win), "debug_data", data );
nkeynes@9
    62
    return data;
nkeynes@2
    63
}
nkeynes@2
    64
nkeynes@2
    65
/*
nkeynes@2
    66
 * Check for changed registers and update the display
nkeynes@2
    67
 */
nkeynes@9
    68
void update_registers( debug_info_t data )
nkeynes@2
    69
{
nkeynes@2
    70
    int i;
nkeynes@9
    71
    for( i=0; data->cpu->regs_info[i].name != NULL; i++ ) {
nkeynes@9
    72
        if( data->cpu->regs_info[i].type == REG_INT ) {
nkeynes@2
    73
            /* Yes this _is_ probably fairly evil */
nkeynes@9
    74
            if( *((uint32_t *)data->cpu->regs_info[i].value) !=
nkeynes@9
    75
                *((uint32_t *)((char *)data->saved_regs + ((char *)data->cpu->regs_info[i].value - (char *)data->cpu->regs))) ) {
nkeynes@2
    76
                char buf[20];
nkeynes@9
    77
                sprintf( buf, "%08X", *((uint32_t *)data->cpu->regs_info[i].value) );
nkeynes@9
    78
                gtk_clist_set_text( data->regs_list, i, 1, buf );
nkeynes@9
    79
                gtk_clist_set_foreground( data->regs_list, i, &clrChanged );
nkeynes@2
    80
            } else {
nkeynes@9
    81
                gtk_clist_set_foreground( data->regs_list, i, &clrNormal );
nkeynes@2
    82
            }
nkeynes@2
    83
        } else {
nkeynes@9
    84
            if( *((float *)data->cpu->regs_info[i].value) !=
nkeynes@9
    85
                *((float *)((char *)data->saved_regs + ((char *)data->cpu->regs_info[i].value - (char *)data->cpu->regs))) ) {
nkeynes@2
    86
                char buf[20];
nkeynes@9
    87
                sprintf( buf, "%f", *((float *)data->cpu->regs_info[i].value) );
nkeynes@9
    88
                gtk_clist_set_text( data->regs_list, i, 1, buf );
nkeynes@9
    89
                gtk_clist_set_foreground( data->regs_list, i, &clrChanged );
nkeynes@2
    90
            } else {
nkeynes@9
    91
                gtk_clist_set_foreground( data->regs_list, i, &clrNormal );
nkeynes@2
    92
            }
nkeynes@2
    93
        }
nkeynes@2
    94
    }
nkeynes@9
    95
nkeynes@9
    96
    set_disassembly_pc( data, *data->cpu->pc, FALSE );
nkeynes@9
    97
    memcpy( data->saved_regs, data->cpu->regs, data->cpu->regs_size );
nkeynes@2
    98
}
nkeynes@2
    99
nkeynes@9
   100
void update_icount( debug_info_t data )
nkeynes@2
   101
{
nkeynes@9
   102
    sprintf( data->icounter_text, "%d", *data->cpu->icount );
nkeynes@9
   103
    gtk_progress_bar_set_text( data->icounter, data->icounter_text );
nkeynes@2
   104
}
nkeynes@2
   105
nkeynes@9
   106
void set_disassembly_region( debug_info_t data, unsigned int page )
nkeynes@2
   107
{
nkeynes@2
   108
    uint32_t i, posn;
nkeynes@2
   109
    uint16_t op;
nkeynes@2
   110
    char buf[80];
nkeynes@2
   111
    char addr[10];
nkeynes@2
   112
    char opcode[6] = "";
nkeynes@2
   113
    char *arr[4] = { addr, " ", opcode, buf };
nkeynes@2
   114
    unsigned int from = page & 0xFFFFF000;
nkeynes@2
   115
    unsigned int to = from + 4096;
nkeynes@2
   116
    
nkeynes@9
   117
    gtk_clist_clear(data->disasm_list);
nkeynes@2
   118
nkeynes@2
   119
    sprintf( addr, "%08X", from );
nkeynes@9
   120
    gtk_entry_set_text( data->page_field, addr );
nkeynes@2
   121
nkeynes@2
   122
    if( !mem_has_page( from ) ) {
nkeynes@2
   123
        arr[3] = "This page is currently unmapped";
nkeynes@9
   124
        gtk_clist_append( data->disasm_list, arr );
nkeynes@9
   125
        gtk_clist_set_foreground( data->disasm_list, 0, &clrError );
nkeynes@2
   126
    } else {
nkeynes@9
   127
        for( i=from; i<to; ) {
nkeynes@9
   128
	    i = data->cpu->disasm_func( i, buf, sizeof(buf) );
nkeynes@2
   129
            sprintf( addr, "%08X", i );
nkeynes@2
   130
            op = mem_read_phys_word(i);
nkeynes@2
   131
            sprintf( opcode, "%02X %02X", op&0xFF, op>>8 );
nkeynes@9
   132
            posn = gtk_clist_append( data->disasm_list, arr );
nkeynes@2
   133
            if( buf[0] == '?' )
nkeynes@9
   134
                gtk_clist_set_foreground( data->disasm_list, posn, &clrWarn );
nkeynes@2
   135
        }
nkeynes@9
   136
        if( data->disasm_pc != -1 && data->disasm_pc >= from && data->disasm_pc < to )
nkeynes@9
   137
            gtk_clist_set_foreground( data->disasm_list, address_to_row(data, data->disasm_pc),
nkeynes@2
   138
                                      &clrPC );
nkeynes@2
   139
    }
nkeynes@2
   140
nkeynes@2
   141
    if( page != from ) { /* not a page boundary */
nkeynes@9
   142
        gtk_clist_moveto( data->disasm_list, (page-from)>>1, 0, 0.5, 0.0 );
nkeynes@2
   143
    }
nkeynes@9
   144
    data->disasm_from = from;
nkeynes@9
   145
    data->disasm_to = to;
nkeynes@2
   146
}
nkeynes@2
   147
nkeynes@9
   148
void jump_to_disassembly( debug_info_t data, unsigned int addr, gboolean select )
nkeynes@2
   149
{
nkeynes@2
   150
    int row;
nkeynes@2
   151
    
nkeynes@9
   152
    if( addr < data->disasm_from || addr >= data->disasm_to )
nkeynes@9
   153
        set_disassembly_region(data,addr);
nkeynes@2
   154
nkeynes@9
   155
    row = address_to_row( data, addr );
nkeynes@2
   156
    if(select) {
nkeynes@9
   157
        gtk_clist_select_row( data->disasm_list, row, 0 );
nkeynes@2
   158
    }
nkeynes@9
   159
    if( gtk_clist_row_is_visible( data->disasm_list, row ) != GTK_VISIBILITY_FULL ){
nkeynes@9
   160
        gtk_clist_moveto( data->disasm_list, row, 0, 0.5, 0.0 );
nkeynes@2
   161
    }
nkeynes@2
   162
}
nkeynes@2
   163
nkeynes@9
   164
void jump_to_pc( debug_info_t data, gboolean select )
nkeynes@9
   165
{
nkeynes@9
   166
    jump_to_disassembly( data, *data->cpu->pc, select );
nkeynes@9
   167
}
nkeynes@9
   168
nkeynes@9
   169
void set_disassembly_pc( debug_info_t data, unsigned int pc, gboolean select )
nkeynes@2
   170
{
nkeynes@2
   171
    int row;
nkeynes@2
   172
    
nkeynes@9
   173
    jump_to_disassembly( data, pc, select );
nkeynes@9
   174
    if( data->disasm_pc != -1 && data->disasm_pc >= data->disasm_from && 
nkeynes@9
   175
	data->disasm_pc < data->disasm_to )
nkeynes@9
   176
        gtk_clist_set_foreground( data->disasm_list, 
nkeynes@9
   177
				  (data->disasm_pc - data->disasm_from) / data->cpu->instr_size,
nkeynes@2
   178
                                  &clrNormal );
nkeynes@9
   179
    row = address_to_row( data, pc );
nkeynes@9
   180
    gtk_clist_set_foreground( data->disasm_list, row, &clrPC );
nkeynes@9
   181
    data->disasm_pc = pc;
nkeynes@2
   182
}
nkeynes@2
   183
nkeynes@9
   184
uint32_t row_to_address( debug_info_t data, int row ) {
nkeynes@9
   185
    return data->cpu->instr_size * row + data->disasm_from;
nkeynes@9
   186
}
nkeynes@2
   187
nkeynes@9
   188
int address_to_row( debug_info_t data, uint32_t address ) {
nkeynes@9
   189
    if( data->disasm_from > address || data->disasm_to <= address )
nkeynes@9
   190
	return -1;
nkeynes@9
   191
    return (address - data->disasm_from) / data->cpu->instr_size;
nkeynes@9
   192
}
nkeynes@9
   193
nkeynes@9
   194
void emit( void *ptr, int level, int source, char *msg, ... )
nkeynes@2
   195
{
nkeynes@2
   196
    char buf[20], addr[10] = "", *p;
nkeynes@2
   197
    char *arr[3] = {buf, addr};
nkeynes@2
   198
    int posn;
nkeynes@2
   199
    time_t tm = time(NULL);
nkeynes@2
   200
    va_list ap;
nkeynes@9
   201
    debug_info_t data;
nkeynes@9
   202
    if( ptr == NULL )
nkeynes@9
   203
	data = main_debug;
nkeynes@9
   204
    else data = (debug_info_t)ptr;
nkeynes@2
   205
nkeynes@2
   206
    va_start(ap, msg);
nkeynes@2
   207
    p = g_strdup_vprintf( msg, ap );
nkeynes@2
   208
    strftime( buf, sizeof(buf), "%H:%M:%S", localtime(&tm) );
nkeynes@2
   209
    if( source != -1 )
nkeynes@9
   210
        sprintf( addr, "%08X", *data->cpu->pc );
nkeynes@2
   211
    arr[2] = p;
nkeynes@9
   212
    posn = gtk_clist_append(data->msgs_list, arr);
nkeynes@2
   213
    free(p);
nkeynes@2
   214
    va_end(ap);
nkeynes@2
   215
nkeynes@9
   216
    gtk_clist_set_foreground( data->msgs_list, posn, msg_colors[level] );
nkeynes@9
   217
    gtk_clist_moveto( data->msgs_list, posn, 0, 1.0, 0.0 );
nkeynes@2
   218
nkeynes@2
   219
    /* emit _really_ slows down the emu, to the point where the gui can be
nkeynes@2
   220
     * completely unresponsive if I don't include this:
nkeynes@2
   221
     */
nkeynes@2
   222
    while( gtk_events_pending() )
nkeynes@2
   223
        gtk_main_iteration();
nkeynes@2
   224
}
nkeynes@9
   225
nkeynes@9
   226
debug_info_t get_debug_info( GtkWidget *widget ) {
nkeynes@9
   227
    
nkeynes@9
   228
    GtkWidget *win = gtk_widget_get_toplevel(widget);
nkeynes@9
   229
    debug_info_t data = (debug_info_t)gtk_object_get_data( GTK_OBJECT(win), "debug_data" );
nkeynes@9
   230
    return data;
nkeynes@9
   231
}
nkeynes@9
   232
.