filename | src/gui/debug_win.c |
changeset | 10:c898b37506e0 |
prev | 9:2784c7660165 |
next | 11:0a82ef380c45 |
author | nkeynes |
date | Sun Dec 11 05:15:36 2005 +0000 (16 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 }
.