1 /***************************************************************************/
2 /* */
3 /* Debugging Source File */
4 /* */
5 /* Functions are here to help developpers making cool games and/or help */
6 /* hackers modifying (i.e. changing sprites, fonts, translating, putting */
7 /* training, ...) existing games */
8 /* */
9 /* First intended to help Dave Shadoff with his open source game */
10 /* Now helps me and others to emulate CDs */
11 /* */
12 /***************************************************************************/
13 #include "debug.h"
14
15 UInt16 Bp_pos_to_restore;
16
17 // Used in RESTORE_BP to know where we must restore a BP
18
19 Breakpoint Bp_list[MAX_BP];
20
21 // Set of breakpoints
22
23 UChar save_background = 1;
24
25
26 #ifdef ALLEGRO
27
28 // If set, means we got to preserve the true display
29 // If not, we just go ahead e.g. for stepping
30
31 PALETTE save_pal;
32
33 // The true palette
34
35 BITMAP *save_bg;
36
37 // The true display
38
39
40 #endif
41
42 /* Way to accedate to the PC Engine memory */
43 /*
44 #if defined(MSDOS) || defined(WIN32)
45
46 unsigned char
47 Op6502 (register unsigned A)
48 {
49 register char __AUX;
50
51 __asm__ __volatile__ ("movl _PageR (, %%eax, 4), %%ecx "
52 "movb (%%edx, %%ecx), %%al "
53 :"=a" (__AUX)
54 :"d" (A),
55 "a" (A >> 13):"%ebx", "%ecx");
56
57 return __AUX;
58 };
59
60 #else
61 */
62
63 unsigned char
Op6502(unsigned int A)64 Op6502 (unsigned int A)
65 {
66 return (PageR[A >> 13][A]);
67 }
68
69 /*
70 #endif
71 */
72
73 void
disass_menu()74 disass_menu ()
75 {
76
77 #ifdef ALLEGRO
78 if (save_background)
79
80 {
81
82 save_bg = create_bitmap (vwidth, vheight);
83
84 blit (screen, save_bg, 0, 0, 0, 0, vwidth, vheight);
85
86 get_palette (save_pal);
87
88 }
89 #endif
90
91 #ifndef KERNEL_DS
92 disassemble (M.PC.W);
93 #else
94 disassemble (reg_pc);
95 #endif
96
97 #ifdef ALLEGRO
98 if (save_background)
99
100 {
101
102 set_palette (save_pal);
103
104 blit (save_bg, screen, 0, 0, 0, 0, vwidth, vheight);
105
106 destroy_bitmap (save_bg);
107
108 }
109
110 #endif
111 return;
112
113 };
114
115
116 /*****************************************************************************
117
118 Function: toggle_user_breakpoint
119
120 Description: set a breakpoint at the specified address if don't exist
121 or unset it if existant
122 Parameters: unsigned short where, a PCE-style address
123 Return: 0 on error
124 1 on success
125
126 *****************************************************************************/
127
128 int
toggle_user_breakpoint(UInt16 where)129 toggle_user_breakpoint (UInt16 where)
130 {
131
132 UChar dum;
133
134 for (dum = 0; dum < MAX_USER_BP; dum++)
135
136 {
137
138
139 if ((Bp_list[dum].position == where) && (Bp_list[dum].flag != NOT_USED))
140
141 { //Already set, unset it and put the right opcode
142
143 Bp_list[dum].flag = NOT_USED;
144
145 Wr6502 (where, Bp_list[dum].original_op);
146
147 return 1;
148
149 }
150
151
152 if (Bp_list[dum].flag == NOT_USED)
153
154 break;
155
156
157 }
158
159 if (dum == MAX_USER_BP)
160
161 return 0;
162
163
164 Bp_list[dum].flag = ENABLED;
165
166 Bp_list[dum].position = where;
167
168 Bp_list[dum].original_op = Op6502 (where);
169
170
171 Wr6502 (where, (UChar)(0xB + 0x10 * dum));
172
173 // Put an invalid opcode
174
175 return 1;
176
177 }
178
179
180 /*****************************************************************************
181
182 Function: display_debug_help
183
184 Description: display help on debugging
185 Parameters: none
186 Return: nothing
187
188 *****************************************************************************/
189
190 void
display_debug_help()191 display_debug_help ()
192 {
193 #ifdef ALLEGRO
194 UInt32 x;
195
196 BITMAP *bg;
197
198
199 bg = create_bitmap (vwidth, vheight);
200
201 blit (screen, bg, 0, 0, 0, 0, vwidth, vheight);
202
203 clear (screen);
204
205
206 for (x = 0; x < help_debug_size; x++)
207
208 textout_centre (screen, font, MESSAGE[language][help_debug + x],
209 vwidth / 2, blit_y + 10 * x, -1);
210
211 while (osd_keypressed ())
212 osd_readkey ();
213
214 osd_readkey ();
215
216
217 blit (bg, screen, 0, 0, 0, 0, vwidth, vheight);
218
219 destroy_bitmap (bg);
220
221 return;
222 #endif
223 }
224
225
226
227 /*****************************************************************************
228
229 Function: cvt_num
230
231 Description: convert a hexa string without prefix "0x" into a number
232 Parameters: char* string, the string to convert
233 Return: -1 on error else the given number
234
235 directly taken from Dave Shadoff emulator TGSIM*
236
237 *****************************************************************************/
cvtnum(char * string)238 UInt32 cvtnum (char *string)
239 {
240
241 UInt32 value = 0;
242
243 char *c = string;
244
245
246 while (*c != '\0')
247 {
248
249
250 value *= 16;
251
252
253 if ((*c >= '0') && (*c <= '9'))
254 {
255
256 value += (*c - '0');
257
258
259 }
260 else if ((*c >= 'A') && (*c <= 'F'))
261 {
262
263 value += (*c - 'A' + 10);
264
265
266 }
267 else if ((*c >= 'a') && (*c <= 'f'))
268 {
269
270 value += (*c - 'a' + 10);
271
272
273 }
274 else
275 {
276
277
278 return (-1);
279
280 }
281
282
283 c++;
284
285 }
286
287
288 return (value);
289
290 }
291
292
293 /*****************************************************************************
294
295 Function: set_bp_following
296
297 Description: very tricky function, set a bp to the next IP, must handle
298 correctly jump, ret,...
299 Well, the trick isn't in a 10 line function ;)
300 but in the optable.following_IP funcs
301 Parameters: UInt16 where, the current address
302 UChar nb, the nb of the breakpoint to set
303 Return: nothing
304
305 *****************************************************************************/
306 void
set_bp_following(UInt16 where,UChar nb)307 set_bp_following (UInt16 where, UChar nb)
308 {
309
310 UInt16 next_pos;
311
312 UChar op = Op6502 (where);
313
314
315 next_pos = (*optable_debug[op].following_IP) (where);
316
317
318 Bp_list[nb].position = next_pos;
319
320
321 Bp_list[nb].flag = ENABLED;
322
323
324 Bp_list[nb].original_op = Op6502 (next_pos);
325
326
327 Wr6502 (next_pos, (UChar)(0xB + 0x10 * nb));
328
329
330 return;
331
332 }
333
334
335 /*****************************************************************************
336
337 Function: change_value
338
339 Description: change the value
340 Parameters: int X, int Y : position on screen
341 UChar lenght : # of characters allowed
342 Return: the new value in int pointed by result
343
344 *****************************************************************************/
change_value(int X,int Y,UChar length,UInt32 * result)345 UChar change_value (int X, int Y, UChar length, UInt32 * result)
346 {
347 #ifdef ALLEGRO
348 char index = 0;
349
350 char value[9] = "\0\0\0\0\0\0\0\0";
351
352 int ch;
353
354
355 do
356 {
357 rectfill (screen, X, Y, X + 16, Y + 9, -15);
358 textout (screen, font, value, X, Y + 1, -1);
359 ch = osd_readkey ();
360
361 // first switch by scancode
362 switch (ch >> 8)
363 {
364 case KEY_ESC:
365 return 0;
366 case KEY_ENTER:
367 *result = cvtnum (value);
368 return 1;
369 case KEY_BACKSPACE:
370 if (index)
371 value[--index] = 0;
372 break;
373 }
374
375 // Now by ascii code
376 switch (ch & 0xff)
377 {
378 case '0'...'9':
379 case 'a'...'f':
380 case 'A'...'F':
381 if (index < length)
382 value[index++] = toupper (ch & 0xff);
383 break;
384 }
385 }
386 while (1);
387 #endif
388
389 return 0;
390 }
391