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 10:c898b37506e0
prev9:2784c7660165
next11:0a82ef380c45
author nkeynes
date Sun Dec 11 05:15:36 2005 +0000 (15 years ago)
permissions -rw-r--r--
last change Add CPU disasembly options to mode dropdown
Split sh4/mem.c into core mem.c and sh4/mem.c
Start adding copyright comments to file headers
view annotate diff log raw
     1 /**
     2  * $Id: debug_win.c,v 1.4 2005-12-11 05:15:36 nkeynes Exp $
     3  * This file is responsible for the main debugger gui frame.
     4  *
     5  * Copyright (c) 2005 Nathan Keynes.
     6  *
     7  * This program is free software; you can redistribute it and/or modify
     8  * it under the terms of the GNU General Public License as published by
     9  * the Free Software Foundation; either version 2 of the License, or
    10  * (at your option) any later version.
    11  *
    12  * This program is distributed in the hope that it will be useful,
    13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    15  * GNU General Public License for more details.
    16  */
    17 #include <stdlib.h>
    18 #include <stdarg.h>
    19 #include <gnome.h>
    20 #include <math.h>
    21 #include "gui.h"
    22 #include "mem.h"
    23 #include "disasm.h"
    25 GdkColor *msg_colors[] = { &clrError, &clrError, &clrWarn, &clrNormal,
    26                            &clrDebug, &clrTrace };
    28 struct debug_info_struct {
    29     int disasm_from;
    30     int disasm_to;
    31     int disasm_pc;
    32     struct cpu_desc_struct *cpu;
    33     GtkCList *msgs_list;
    34     GtkCList *regs_list;
    35     GtkCList *disasm_list;
    36     GtkEntry *page_field;
    37     GtkProgressBar *icounter;
    38     char icounter_text[16];
    39     char saved_regs[0];
    40 };
    42 debug_info_t init_debug_win(GtkWidget *win, struct cpu_desc_struct *cpu )
    43 {
    44     int i;
    45     char buf[20];
    46     char *arr[2];
    47     GnomeAppBar *appbar;
    49     debug_info_t data = g_malloc0( sizeof(struct debug_info_struct) + cpu->regs_size );
    50     data->disasm_from = -1;
    51     data->disasm_to = -1;
    52     data->disasm_pc = -1;
    53     data->cpu = cpu;
    55     data->regs_list= gtk_object_get_data(GTK_OBJECT(win), "reg_list");
    56     arr[1] = buf;
    57     for( i=0; data->cpu->regs_info[i].name != NULL; i++ ) {
    58         arr[0] = data->cpu->regs_info[i].name;
    59         if( data->cpu->regs_info->type == REG_INT )
    60             sprintf( buf, "%08X", *((uint32_t *)data->cpu->regs_info->value) );
    61         else
    62             sprintf( buf, "%f", *((float *)data->cpu->regs_info->value) );
    63         gtk_clist_append( data->regs_list, arr );
    64     }
    65     gtk_widget_modify_font( GTK_WIDGET(data->regs_list), fixed_list_font );
    67     data->msgs_list = gtk_object_get_data(GTK_OBJECT(win), "output_list");
    68     data->disasm_list = gtk_object_get_data(GTK_OBJECT(win), "disasm_list");
    69     gtk_clist_set_column_width( data->disasm_list, 1, 16 );
    70     data->page_field = gtk_object_get_data(GTK_OBJECT(win), "page_field");
    72     appbar = gtk_object_get_data(GTK_OBJECT(win), "debug_appbar");
    73     data->icounter = gnome_appbar_get_progress( appbar );
    74     gtk_progress_bar_set_text(data->icounter, "1");
    76     gtk_object_set_data( GTK_OBJECT(win), "debug_data", data );
    77     return data;
    78 }
    80 /*
    81  * Check for changed registers and update the display
    82  */
    83 void update_registers( debug_info_t data )
    84 {
    85     int i;
    86     for( i=0; data->cpu->regs_info[i].name != NULL; i++ ) {
    87         if( data->cpu->regs_info[i].type == REG_INT ) {
    88             /* Yes this _is_ probably fairly evil */
    89             if( *((uint32_t *)data->cpu->regs_info[i].value) !=
    90                 *((uint32_t *)((char *)data->saved_regs + ((char *)data->cpu->regs_info[i].value - (char *)data->cpu->regs))) ) {
    91                 char buf[20];
    92                 sprintf( buf, "%08X", *((uint32_t *)data->cpu->regs_info[i].value) );
    93                 gtk_clist_set_text( data->regs_list, i, 1, buf );
    94                 gtk_clist_set_foreground( data->regs_list, i, &clrChanged );
    95             } else {
    96                 gtk_clist_set_foreground( data->regs_list, i, &clrNormal );
    97             }
    98         } else {
    99             if( *((float *)data->cpu->regs_info[i].value) !=
   100                 *((float *)((char *)data->saved_regs + ((char *)data->cpu->regs_info[i].value - (char *)data->cpu->regs))) ) {
   101                 char buf[20];
   102                 sprintf( buf, "%f", *((float *)data->cpu->regs_info[i].value) );
   103                 gtk_clist_set_text( data->regs_list, i, 1, buf );
   104                 gtk_clist_set_foreground( data->regs_list, i, &clrChanged );
   105             } else {
   106                 gtk_clist_set_foreground( data->regs_list, i, &clrNormal );
   107             }
   108         }
   109     }
   111     set_disassembly_pc( data, *data->cpu->pc, FALSE );
   112     memcpy( data->saved_regs, data->cpu->regs, data->cpu->regs_size );
   113 }
   115 void update_icount( debug_info_t data )
   116 {
   117     sprintf( data->icounter_text, "%d", *data->cpu->icount );
   118     gtk_progress_bar_set_text( data->icounter, data->icounter_text );
   119 }
   121 void set_disassembly_region( debug_info_t data, unsigned int page )
   122 {
   123     uint32_t i, posn;
   124     uint16_t op;
   125     char buf[80];
   126     char addr[10];
   127     char opcode[6] = "";
   128     char *arr[4] = { addr, " ", opcode, buf };
   129     unsigned int from = page & 0xFFFFF000;
   130     unsigned int to = from + 4096;
   132     gtk_clist_clear(data->disasm_list);
   134     sprintf( addr, "%08X", from );
   135     gtk_entry_set_text( data->page_field, addr );
   137     if( !mem_has_page( from ) ) {
   138         arr[3] = "This page is currently unmapped";
   139         gtk_clist_append( data->disasm_list, arr );
   140         gtk_clist_set_foreground( data->disasm_list, 0, &clrError );
   141     } else {
   142         for( i=from; i<to; ) {
   143 	    i = data->cpu->disasm_func( i, buf, sizeof(buf) );
   144             sprintf( addr, "%08X", i );
   145             op = sh4_read_phys_word(i);
   146             sprintf( opcode, "%02X %02X", op&0xFF, op>>8 );
   147             posn = gtk_clist_append( data->disasm_list, arr );
   148             if( buf[0] == '?' )
   149                 gtk_clist_set_foreground( data->disasm_list, posn, &clrWarn );
   150         }
   151         if( data->disasm_pc != -1 && data->disasm_pc >= from && data->disasm_pc < to )
   152             gtk_clist_set_foreground( data->disasm_list, address_to_row(data, data->disasm_pc),
   153                                       &clrPC );
   154     }
   156     if( page != from ) { /* not a page boundary */
   157         gtk_clist_moveto( data->disasm_list, (page-from)>>1, 0, 0.5, 0.0 );
   158     }
   159     data->disasm_from = from;
   160     data->disasm_to = to;
   161 }
   163 void jump_to_disassembly( debug_info_t data, unsigned int addr, gboolean select )
   164 {
   165     int row;
   167     if( addr < data->disasm_from || addr >= data->disasm_to )
   168         set_disassembly_region(data,addr);
   170     row = address_to_row( data, addr );
   171     if(select) {
   172         gtk_clist_select_row( data->disasm_list, row, 0 );
   173     }
   174     if( gtk_clist_row_is_visible( data->disasm_list, row ) != GTK_VISIBILITY_FULL ){
   175         gtk_clist_moveto( data->disasm_list, row, 0, 0.5, 0.0 );
   176     }
   177 }
   179 void jump_to_pc( debug_info_t data, gboolean select )
   180 {
   181     jump_to_disassembly( data, *data->cpu->pc, select );
   182 }
   184 void set_disassembly_pc( debug_info_t data, unsigned int pc, gboolean select )
   185 {
   186     int row;
   188     jump_to_disassembly( data, pc, select );
   189     if( data->disasm_pc != -1 && data->disasm_pc >= data->disasm_from && 
   190 	data->disasm_pc < data->disasm_to )
   191         gtk_clist_set_foreground( data->disasm_list, 
   192 				  (data->disasm_pc - data->disasm_from) / data->cpu->instr_size,
   193                                   &clrNormal );
   194     row = address_to_row( data, pc );
   195     gtk_clist_set_foreground( data->disasm_list, row, &clrPC );
   196     data->disasm_pc = pc;
   197 }
   199 void set_disassembly_cpu( debug_info_t data, char *cpu )
   200 {
   203 }
   205 uint32_t row_to_address( debug_info_t data, int row ) {
   206     return data->cpu->instr_size * row + data->disasm_from;
   207 }
   209 int address_to_row( debug_info_t data, uint32_t address ) {
   210     if( data->disasm_from > address || data->disasm_to <= address )
   211 	return -1;
   212     return (address - data->disasm_from) / data->cpu->instr_size;
   213 }
   216 void emit( void *ptr, int level, int source, char *msg, ... )
   217 {
   218     char buf[20], addr[10] = "", *p;
   219     char *arr[3] = {buf, addr};
   220     int posn;
   221     time_t tm = time(NULL);
   222     va_list ap;
   223     debug_info_t data;
   224     if( ptr == NULL )
   225 	data = main_debug;
   226     else data = (debug_info_t)ptr;
   228     va_start(ap, msg);
   229     p = g_strdup_vprintf( msg, ap );
   230     strftime( buf, sizeof(buf), "%H:%M:%S", localtime(&tm) );
   231     if( source != -1 )
   232         sprintf( addr, "%08X", *data->cpu->pc );
   233     arr[2] = p;
   234     posn = gtk_clist_append(data->msgs_list, arr);
   235     free(p);
   236     va_end(ap);
   238     gtk_clist_set_foreground( data->msgs_list, posn, msg_colors[level] );
   239     gtk_clist_moveto( data->msgs_list, posn, 0, 1.0, 0.0 );
   241     /* emit _really_ slows down the emu, to the point where the gui can be
   242      * completely unresponsive if I don't include this:
   243      */
   244     while( gtk_events_pending() )
   245         gtk_main_iteration();
   246 }
   248 debug_info_t get_debug_info( GtkWidget *widget ) {
   250     GtkWidget *win = gtk_widget_get_toplevel(widget);
   251     debug_info_t data = (debug_info_t)gtk_object_get_data( GTK_OBJECT(win), "debug_data" );
   252     return data;
   253 }
.