struct / union in initializer, RFE #901.
[sdcc.git] / sdcc-extra / emu / rrgb / debugger.c
blobb7dc4f35f65049b8292a91553097de25ae5866f9
1 #include "disgb.h"
2 #include "z80.h"
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <ctype.h>
6 #include "debugger.h"
8 extern unsigned short callback_stack[100];
9 extern int callback_stack_pos;
11 void profile(void)
13 pmfunction walk;
14 char buffer[100];
16 walk = fun_first;
18 while (walk!=NULL) {
19 format_label( buffer, walk->addr );
20 printf("%s:\n"
21 " Calls:\t%u\n"
22 " tstates:\t%u\n"
23 " avg:\t%u (%u%%)\n",
24 buffer,
25 walk->num_calls,
26 walk->tstates,
27 (walk->tstates)/(walk->num_calls),
28 (int)(100*walk->tstates/tstates)
30 walk = walk->next;
34 char *get_param( char *from, int *storein )
36 char *end, tmp;
38 /* Find the first real character */
39 while (isspace(*from)&&(*from!='\0')) {
40 from++;
43 if (*from =='\0')
44 return NULL;
46 end = from;
47 /* Search till the end of the string */
48 while (!isspace(*end)&&(*end!='\0')) {
49 end++;
52 tmp = *end;
53 *end='\0';
54 *storein = parse_label(from);
55 *end = tmp;
56 return end;
59 int getparams( char *string, int *start, int *end, int pc, int defoffset )
61 char *tmp;
63 if ((tmp=get_param(&string[1],start))!=NULL) {
64 if ((tmp=get_param(tmp, end))!=NULL) {
65 return 2;
67 else {
68 *end = *start+defoffset;
69 return 1;
72 else {
73 *end = pc+defoffset;
74 *start = pc;
75 return 0;
79 void show_callback_stack(void)
81 int start, i;
82 char buffer[100];
84 start = callback_stack_pos-5;
85 if (start<0)
86 start = 0;
87 for (i=start; i<callback_stack_pos; i++) {
88 format_label( buffer, callback_stack[i] );
89 printf(" %s\n", buffer );
93 int setBreakpoint( unsigned int addr )
95 int i;
96 i=1;
98 while ((i<5)&&(breakpoints[i]!=addr)) {
99 i++;
102 if (i==5) {
103 /* New breakpoint */
104 i = 1;
105 while ((i<5)&&(breakpoints[i]!=0))
106 i++;
107 if (i==5) {
108 return -1; /* Couldnt set */
110 breakpoints[i] = addr;
111 return i;
113 return -2;
116 void printRegisters( pmregs regs )
118 printf("BC = %02X%02X DE = %02X%02X HL = %02X%02X\n"
119 "A = %02X F = %02X PC = %04X\n"
120 "SP = %04X\n"
121 ,*regs->b, *regs->c, *regs->d, *regs->e, *regs->h, *regs->l,
122 *regs->a, *regs->f, *regs->pc,
123 *regs->sp
127 int clearBreakpoint( unsigned int addr )
129 int i;
130 i=1;
132 while ((i<5)&&(breakpoints[i]!=addr))
133 i++;
134 if (i==5)
135 return -1;
136 breakpoints[i] = 0;
137 return i;
140 int enterDebugger( pmregs regs )
142 char string[100];
143 unsigned char *ppc;
144 unsigned int dpc = *regs->pc;
145 int debugging, updateLine;
146 int offset = 0;
148 int start, end, dumpCount, i;
150 debugging = 1;
151 updateLine = 1;
154 if (flags & DLIMITEDRUN) {
155 printf("Error: Tried to enter the debugger in a limited length run\n");
156 exit(-1);
159 while (debugging) {
160 if (updateLine) {
161 ppc = &mem[dpc];
162 offset = disass( NULL, ppc, dpc );
163 /* printf("%4X: %s\n", dpc, string );*/
165 updateLine = 0;
167 printf("!: ");
168 fflush(stdout);
169 if (fgets( string, sizeof(string), stdin ) == NULL) {
170 break;
172 switch (string[0]) {
173 case 'd': {
174 /* Dump: d [start] [end]
175 If no end, end = start + 0x40
176 If no start, use PC
178 getparams( string, &start, &end, dpc, 0x10 );
179 dumpCount = 0;
180 while (start < end ) {
181 if (dumpCount ==0) {
182 printf("%4X: ", start);
184 printf(" %02X", mem[start++]);
185 dumpCount++;
186 if (dumpCount == 8)
187 printf(" ");
189 if (dumpCount == 16) {
190 printf(" ");
191 for (i=16; i>0; i--) {
192 if (isprint(mem[start-i])) {
193 printf("%c", mem[start-i]);
195 else
196 printf(".");
198 printf("\n");
199 dumpCount = 0;
202 if (dumpCount!=0)
203 printf("\n");
205 break;
207 case 'r': {
208 /* Registers */
209 printRegisters( regs );
210 break;
212 #if DISABLED
213 case 'f': {
214 /* Print float in HLDE */
215 printGBfloat((int)(*regs->h)<<8 |*regs->l, (int)(*regs->d)<<8 | (int)(*regs->e) );
216 break;
218 #endif
219 case 'n': {
220 /* Execute until next line */
221 breakpoints[0] = dpc + offset;
222 debugging = 0;
223 break;
225 case 't': {
226 /* Trace into (run one instruction) */
227 return 1;
229 case 'g': {
230 /* Continue */
231 debugging = 0;
232 break;
234 case 'q': {
235 /* Quit */
236 *regs->cpuRunning = 0;
237 debugging = 0;
238 break;
240 case 'b': {
241 if (get_param( &string[1], &start)==NULL) {
242 /* List breakpoints */
243 for (end = 1; end <5; end++) {
244 printf("Breakpoint %u at %04X\n", end, breakpoints[end]);
247 else {
248 end = setBreakpoint(start);
249 switch (end) {
250 case -1: {
251 printf("Couldnt set breakpoint.\n");
252 break;
254 case -2: {
255 printf("Cleared breakpoint %i.\n", clearBreakpoint( start ));
256 break;
258 default: {
259 printf("Set breakpoint %u to %04X.\n", end, start);
263 break;
266 case 'u': {
267 /* Unassemble: u [start] [end]
268 If no end, end = start + 0x8
269 If no start, start = pc
271 getparams( string, &start, &end, dpc, 0x8 );
272 ppc = &mem[start];
273 while (start < end) {
274 offset=disass( NULL, ppc, start );
275 start += offset;
276 ppc +=offset;
278 break;
280 case 's': {
281 show_callback_stack();
282 break;
284 case '?': {
285 printf("unassemble u [start] [end]\n"
286 "dump range d [start] [end]\n"
287 "quit q\n"
288 "help ?\n"
289 "go g\n"
290 "breakpoint b addr\n"
291 "show registers r\n"
292 "go until next n\n"
293 "trace into t\n"
294 "stack s\n"
295 "fp hlde f\n"
297 break;
300 default: {
301 printf("?\n");
302 break;
306 return 0;