filename | src/gui/debug_win.c |
changeset | 9:2784c7660165 |
prev | 8:6730608cdaf0 |
next | 10: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 }
.