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