Search
lxdream.org :: lxdream/src/gui/debug_win.c :: diff
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 (13 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
1.1 --- a/src/gui/debug_win.c Sun Dec 12 07:44:49 2004 +0000
1.2 +++ b/src/gui/debug_win.c Thu Dec 08 13:38:00 2005 +0000
1.3 @@ -5,121 +5,105 @@
1.4 #include <math.h>
1.5 #include "gui.h"
1.6 #include "mem.h"
1.7 -#include "sh4dasm.h"
1.8 -#include "sh4core.h"
1.9 +#include "disasm.h"
1.10
1.11 GdkColor *msg_colors[] = { &clrError, &clrError, &clrWarn, &clrNormal,
1.12 &clrDebug, &clrTrace };
1.13
1.14 -#define REG_INT 0
1.15 -#define REG_FLT 1
1.16 -#define REG_SPECIAL 2
1.17 -
1.18 -struct reg_map_struct {
1.19 - char *name;
1.20 - int type;
1.21 - void *value;
1.22 +struct debug_info_struct {
1.23 + int disasm_from;
1.24 + int disasm_to;
1.25 + int disasm_pc;
1.26 + struct cpu_desc_struct *cpu;
1.27 + GtkCList *msgs_list;
1.28 + GtkCList *regs_list;
1.29 + GtkCList *disasm_list;
1.30 + GtkEntry *page_field;
1.31 + GtkProgressBar *icounter;
1.32 + char icounter_text[16];
1.33 + char saved_regs[0];
1.34 };
1.35
1.36 -struct reg_map_struct sh4_reg_map[] =
1.37 - { {"R0", REG_INT, &sh4r.r[0]}, {"R1", REG_INT, &sh4r.r[1]},
1.38 - {"R2", REG_INT, &sh4r.r[2]}, {"R3", REG_INT, &sh4r.r[3]},
1.39 - {"R4", REG_INT, &sh4r.r[4]}, {"R5", REG_INT, &sh4r.r[5]},
1.40 - {"R6", REG_INT, &sh4r.r[6]}, {"R7", REG_INT, &sh4r.r[7]},
1.41 - {"R8", REG_INT, &sh4r.r[8]}, {"R9", REG_INT, &sh4r.r[9]},
1.42 - {"R10",REG_INT, &sh4r.r[10]}, {"R11",REG_INT, &sh4r.r[11]},
1.43 - {"R12",REG_INT, &sh4r.r[12]}, {"R13",REG_INT, &sh4r.r[13]},
1.44 - {"R14",REG_INT, &sh4r.r[14]}, {"R15",REG_INT, &sh4r.r[15]},
1.45 - {"SR", REG_INT, &sh4r.sr}, {"GBR", REG_INT, &sh4r.gbr},
1.46 - {"SSR",REG_INT, &sh4r.ssr}, {"SPC", REG_INT, &sh4r.spc},
1.47 - {"SGR",REG_INT, &sh4r.sgr}, {"DBR", REG_INT, &sh4r.dbr},
1.48 - {"VBR",REG_INT, &sh4r.vbr},
1.49 - {"PC", REG_INT, &sh4r.pc}, {"PR", REG_INT, &sh4r.pr},
1.50 - {"MACL",REG_INT, &sh4r.mac},{"MACH",REG_INT, ((uint32_t *)&sh4r.mac)+1},
1.51 - {"FPUL", REG_INT, &sh4r.fpul}, {"FPSCR", REG_INT, &sh4r.fpscr},
1.52 - {NULL, 0, NULL} };
1.53 -
1.54 -GtkCList *msgs, *regs, *disasm;
1.55 -GtkEntry *page_field;
1.56 -GtkProgressBar *icounter;
1.57 -char icounter_text[16];
1.58 -
1.59 -struct sh4_registers sh4r_s;
1.60 -int disasm_from = -1, disasm_to = -1;
1.61 -int disasm_pc = -1;
1.62 -
1.63 -
1.64 -void init_debug_win(GtkWidget *win)
1.65 +debug_info_t init_debug_win(GtkWidget *win, struct cpu_desc_struct *cpu )
1.66 {
1.67 int i;
1.68 char buf[20];
1.69 char *arr[2];
1.70 GnomeAppBar *appbar;
1.71 +
1.72 + debug_info_t data = g_malloc0( sizeof(struct debug_info_struct) + cpu->regs_size );
1.73 + data->disasm_from = -1;
1.74 + data->disasm_to = -1;
1.75 + data->disasm_pc = -1;
1.76 + data->cpu = cpu;
1.77 +
1.78 + data->regs_list= gtk_object_get_data(GTK_OBJECT(win), "reg_list");
1.79 + arr[1] = buf;
1.80 + for( i=0; data->cpu->regs_info[i].name != NULL; i++ ) {
1.81 + arr[0] = data->cpu->regs_info[i].name;
1.82 + if( data->cpu->regs_info->type == REG_INT )
1.83 + sprintf( buf, "%08X", *((uint32_t *)data->cpu->regs_info->value) );
1.84 + else
1.85 + sprintf( buf, "%f", *((float *)data->cpu->regs_info->value) );
1.86 + gtk_clist_append( data->regs_list, arr );
1.87 + }
1.88 + gtk_widget_modify_font( GTK_WIDGET(data->regs_list), fixed_list_font );
1.89
1.90 - regs = gtk_object_get_data(GTK_OBJECT(win), "reg_list");
1.91 - arr[1] = buf;
1.92 - for( i=0; sh4_reg_map[i].name != NULL; i++ ) {
1.93 - arr[0] = sh4_reg_map[i].name;
1.94 - if( sh4_reg_map[i].type == REG_INT )
1.95 - sprintf( buf, "%08X", *((uint32_t *)sh4_reg_map[i].value) );
1.96 - else
1.97 - sprintf( buf, "%f", *((float *)sh4_reg_map[i].value) );
1.98 - gtk_clist_append( regs, arr );
1.99 - }
1.100 - gtk_widget_modify_font( GTK_WIDGET(regs), fixed_list_font );
1.101 -
1.102 - msgs = gtk_object_get_data(GTK_OBJECT(win), "output_list");
1.103 - disasm = gtk_object_get_data(GTK_OBJECT(win), "disasm_list");
1.104 - gtk_clist_set_column_width( disasm, 1, 16 );
1.105 - page_field = gtk_object_get_data(GTK_OBJECT(win), "page_field");
1.106 + data->msgs_list = gtk_object_get_data(GTK_OBJECT(win), "output_list");
1.107 + data->disasm_list = gtk_object_get_data(GTK_OBJECT(win), "disasm_list");
1.108 + gtk_clist_set_column_width( data->disasm_list, 1, 16 );
1.109 + data->page_field = gtk_object_get_data(GTK_OBJECT(win), "page_field");
1.110
1.111 appbar = gtk_object_get_data(GTK_OBJECT(win), "debug_appbar");
1.112 - icounter = gnome_appbar_get_progress( appbar );
1.113 - gtk_progress_bar_set_text(icounter, "1");
1.114 + data->icounter = gnome_appbar_get_progress( appbar );
1.115 + gtk_progress_bar_set_text(data->icounter, "1");
1.116 +
1.117 + gtk_object_set_data( GTK_OBJECT(win), "debug_data", data );
1.118 + return data;
1.119 }
1.120
1.121 /*
1.122 * Check for changed registers and update the display
1.123 */
1.124 -void update_registers( void )
1.125 +void update_registers( debug_info_t data )
1.126 {
1.127 int i;
1.128 - for( i=0; sh4_reg_map[i].name != NULL; i++ ) {
1.129 - if( sh4_reg_map[i].type == REG_INT ) {
1.130 + for( i=0; data->cpu->regs_info[i].name != NULL; i++ ) {
1.131 + if( data->cpu->regs_info[i].type == REG_INT ) {
1.132 /* Yes this _is_ probably fairly evil */
1.133 - if( *((uint32_t *)sh4_reg_map[i].value) !=
1.134 - *((uint32_t *)((char *)&sh4r_s + ((char *)sh4_reg_map[i].value - (char *)&sh4r))) ) {
1.135 + if( *((uint32_t *)data->cpu->regs_info[i].value) !=
1.136 + *((uint32_t *)((char *)data->saved_regs + ((char *)data->cpu->regs_info[i].value - (char *)data->cpu->regs))) ) {
1.137 char buf[20];
1.138 - sprintf( buf, "%08X", *((uint32_t *)sh4_reg_map[i].value) );
1.139 - gtk_clist_set_text( regs, i, 1, buf );
1.140 - gtk_clist_set_foreground( regs, i, &clrChanged );
1.141 + sprintf( buf, "%08X", *((uint32_t *)data->cpu->regs_info[i].value) );
1.142 + gtk_clist_set_text( data->regs_list, i, 1, buf );
1.143 + gtk_clist_set_foreground( data->regs_list, i, &clrChanged );
1.144 } else {
1.145 - gtk_clist_set_foreground( regs, i, &clrNormal );
1.146 + gtk_clist_set_foreground( data->regs_list, i, &clrNormal );
1.147 }
1.148 } else {
1.149 - if( *((float *)sh4_reg_map[i].value) !=
1.150 - *((float *)((char *)&sh4r_s + ((char *)sh4_reg_map[i].value - (char *)&sh4r))) ) {
1.151 + if( *((float *)data->cpu->regs_info[i].value) !=
1.152 + *((float *)((char *)data->saved_regs + ((char *)data->cpu->regs_info[i].value - (char *)data->cpu->regs))) ) {
1.153 char buf[20];
1.154 - sprintf( buf, "%f", *((float *)sh4_reg_map[i].value) );
1.155 - gtk_clist_set_text( regs, i, 1, buf );
1.156 - gtk_clist_set_foreground( regs, i, &clrChanged );
1.157 + sprintf( buf, "%f", *((float *)data->cpu->regs_info[i].value) );
1.158 + gtk_clist_set_text( data->regs_list, i, 1, buf );
1.159 + gtk_clist_set_foreground( data->regs_list, i, &clrChanged );
1.160 } else {
1.161 - gtk_clist_set_foreground( regs, i, &clrNormal );
1.162 + gtk_clist_set_foreground( data->regs_list, i, &clrNormal );
1.163 }
1.164 }
1.165 }
1.166 - if( sh4r.pc != sh4r_s.pc )
1.167 - set_disassembly_pc( sh4r.pc, FALSE );
1.168 - memcpy( &sh4r_s, &sh4r, sizeof(sh4r) );
1.169 +
1.170 + set_disassembly_pc( data, *data->cpu->pc, FALSE );
1.171 + memcpy( data->saved_regs, data->cpu->regs, data->cpu->regs_size );
1.172 }
1.173
1.174 -void update_icount( void )
1.175 +void update_icount( debug_info_t data )
1.176 {
1.177 - sprintf( icounter_text, "%d", sh4r.icount );
1.178 - gtk_progress_bar_set_text( icounter, icounter_text );
1.179 + sprintf( data->icounter_text, "%d", *data->cpu->icount );
1.180 + gtk_progress_bar_set_text( data->icounter, data->icounter_text );
1.181 }
1.182
1.183 -void set_disassembly_region( unsigned int page )
1.184 +void set_disassembly_region( debug_info_t data, unsigned int page )
1.185 {
1.186 uint32_t i, posn;
1.187 uint16_t op;
1.188 @@ -130,87 +114,107 @@
1.189 unsigned int from = page & 0xFFFFF000;
1.190 unsigned int to = from + 4096;
1.191
1.192 - gtk_clist_clear(disasm);
1.193 + gtk_clist_clear(data->disasm_list);
1.194
1.195 sprintf( addr, "%08X", from );
1.196 - gtk_entry_set_text( page_field, addr );
1.197 + gtk_entry_set_text( data->page_field, addr );
1.198
1.199 if( !mem_has_page( from ) ) {
1.200 arr[3] = "This page is currently unmapped";
1.201 - gtk_clist_append( disasm, arr );
1.202 - gtk_clist_set_foreground( disasm, 0, &clrError );
1.203 + gtk_clist_append( data->disasm_list, arr );
1.204 + gtk_clist_set_foreground( data->disasm_list, 0, &clrError );
1.205 } else {
1.206 - for( i=from; i<to; i+=2 ) {
1.207 - sh4_disasm_instruction( i, buf, sizeof(buf) );
1.208 + for( i=from; i<to; ) {
1.209 + i = data->cpu->disasm_func( i, buf, sizeof(buf) );
1.210 sprintf( addr, "%08X", i );
1.211 op = mem_read_phys_word(i);
1.212 sprintf( opcode, "%02X %02X", op&0xFF, op>>8 );
1.213 - posn = gtk_clist_append( disasm, arr );
1.214 + posn = gtk_clist_append( data->disasm_list, arr );
1.215 if( buf[0] == '?' )
1.216 - gtk_clist_set_foreground( disasm, posn, &clrWarn );
1.217 + gtk_clist_set_foreground( data->disasm_list, posn, &clrWarn );
1.218 }
1.219 - if( disasm_pc != -1 && disasm_pc >= from && disasm_pc < to )
1.220 - gtk_clist_set_foreground( disasm, (disasm_pc - from)>>1,
1.221 + if( data->disasm_pc != -1 && data->disasm_pc >= from && data->disasm_pc < to )
1.222 + gtk_clist_set_foreground( data->disasm_list, address_to_row(data, data->disasm_pc),
1.223 &clrPC );
1.224 }
1.225
1.226 if( page != from ) { /* not a page boundary */
1.227 - gtk_clist_moveto( disasm, (page-from)>>1, 0, 0.5, 0.0 );
1.228 + gtk_clist_moveto( data->disasm_list, (page-from)>>1, 0, 0.5, 0.0 );
1.229 }
1.230 - disasm_from = from;
1.231 - disasm_to = to;
1.232 + data->disasm_from = from;
1.233 + data->disasm_to = to;
1.234 }
1.235
1.236 -void jump_to_disassembly( unsigned int addr, gboolean select )
1.237 +void jump_to_disassembly( debug_info_t data, unsigned int addr, gboolean select )
1.238 {
1.239 int row;
1.240
1.241 - if( addr < disasm_from || addr >= disasm_to )
1.242 - set_disassembly_region(addr);
1.243 + if( addr < data->disasm_from || addr >= data->disasm_to )
1.244 + set_disassembly_region(data,addr);
1.245
1.246 - row = (addr-disasm_from)>>1;
1.247 + row = address_to_row( data, addr );
1.248 if(select) {
1.249 - gtk_clist_select_row( disasm, row, 0 );
1.250 + gtk_clist_select_row( data->disasm_list, row, 0 );
1.251 }
1.252 - if( gtk_clist_row_is_visible( disasm, row ) != GTK_VISIBILITY_FULL ){
1.253 - gtk_clist_moveto( disasm, row, 0, 0.5, 0.0 );
1.254 + if( gtk_clist_row_is_visible( data->disasm_list, row ) != GTK_VISIBILITY_FULL ){
1.255 + gtk_clist_moveto( data->disasm_list, row, 0, 0.5, 0.0 );
1.256 }
1.257 }
1.258
1.259 -void set_disassembly_pc( unsigned int pc, gboolean select )
1.260 +void jump_to_pc( debug_info_t data, gboolean select )
1.261 +{
1.262 + jump_to_disassembly( data, *data->cpu->pc, select );
1.263 +}
1.264 +
1.265 +void set_disassembly_pc( debug_info_t data, unsigned int pc, gboolean select )
1.266 {
1.267 int row;
1.268
1.269 - jump_to_disassembly( pc, select );
1.270 - if( disasm_pc != -1 && disasm_pc >= disasm_from && disasm_pc < disasm_to )
1.271 - gtk_clist_set_foreground( disasm, (disasm_pc - disasm_from)>>1,
1.272 + jump_to_disassembly( data, pc, select );
1.273 + if( data->disasm_pc != -1 && data->disasm_pc >= data->disasm_from &&
1.274 + data->disasm_pc < data->disasm_to )
1.275 + gtk_clist_set_foreground( data->disasm_list,
1.276 + (data->disasm_pc - data->disasm_from) / data->cpu->instr_size,
1.277 &clrNormal );
1.278 - row = (pc - disasm_from)>>1;
1.279 - gtk_clist_set_foreground( disasm, row, &clrPC );
1.280 - disasm_pc = pc;
1.281 + row = address_to_row( data, pc );
1.282 + gtk_clist_set_foreground( data->disasm_list, row, &clrPC );
1.283 + data->disasm_pc = pc;
1.284 }
1.285
1.286 +uint32_t row_to_address( debug_info_t data, int row ) {
1.287 + return data->cpu->instr_size * row + data->disasm_from;
1.288 +}
1.289
1.290 -void emit( int level, int source, char *msg, ... )
1.291 +int address_to_row( debug_info_t data, uint32_t address ) {
1.292 + if( data->disasm_from > address || data->disasm_to <= address )
1.293 + return -1;
1.294 + return (address - data->disasm_from) / data->cpu->instr_size;
1.295 +}
1.296 +
1.297 +void emit( void *ptr, int level, int source, char *msg, ... )
1.298 {
1.299 char buf[20], addr[10] = "", *p;
1.300 char *arr[3] = {buf, addr};
1.301 int posn;
1.302 time_t tm = time(NULL);
1.303 va_list ap;
1.304 + debug_info_t data;
1.305 + if( ptr == NULL )
1.306 + data = main_debug;
1.307 + else data = (debug_info_t)ptr;
1.308
1.309 va_start(ap, msg);
1.310 p = g_strdup_vprintf( msg, ap );
1.311 strftime( buf, sizeof(buf), "%H:%M:%S", localtime(&tm) );
1.312 if( source != -1 )
1.313 - sprintf( addr, "%08X", sh4r.pc );
1.314 + sprintf( addr, "%08X", *data->cpu->pc );
1.315 arr[2] = p;
1.316 - posn = gtk_clist_append(msgs, arr);
1.317 + posn = gtk_clist_append(data->msgs_list, arr);
1.318 free(p);
1.319 va_end(ap);
1.320
1.321 - gtk_clist_set_foreground( msgs, posn, msg_colors[level] );
1.322 - gtk_clist_moveto( msgs, posn, 0, 1.0, 0.0 );
1.323 + gtk_clist_set_foreground( data->msgs_list, posn, msg_colors[level] );
1.324 + gtk_clist_moveto( data->msgs_list, posn, 0, 1.0, 0.0 );
1.325
1.326 /* emit _really_ slows down the emu, to the point where the gui can be
1.327 * completely unresponsive if I don't include this:
1.328 @@ -218,3 +222,11 @@
1.329 while( gtk_events_pending() )
1.330 gtk_main_iteration();
1.331 }
1.332 +
1.333 +debug_info_t get_debug_info( GtkWidget *widget ) {
1.334 +
1.335 + GtkWidget *win = gtk_widget_get_toplevel(widget);
1.336 + debug_info_t data = (debug_info_t)gtk_object_get_data( GTK_OBJECT(win), "debug_data" );
1.337 + return data;
1.338 +}
1.339 +
.