ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/mon/src/mon_cmd.cpp
Revision: 1.2
Committed: 1999-10-04T21:16:02Z (25 years, 2 months ago) by cebix
Branch: MAIN
Changes since 1.1: +18 -5 lines
Log Message:
- GPL'ified sources
- added provisions for autoconf stuff

File Contents

# Content
1 /*
2 * mon_cmd.cpp - mon standard commands
3 *
4 * mon (C) 1997-1999 Christian Bauer, Marc Hellwig
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21 #include "sysdeps.h"
22
23 #include "mon.h"
24 #include "mon_cmd.h"
25 #include "mon_ppc.h"
26 #include "mon_68k.h"
27 #include "mon_x86.h"
28 #include "mon_6502.h"
29 #include "mon_8080.h"
30 #include "version.h"
31
32
33 /*
34 * range_args = [expression] [[COMMA] expression] END
35 *
36 * Read start address to "adr", end address to "end_adr".
37 * "adr" defaults to '.', "end_adr" defaults to '.'+def_range
38 *
39 * true: OK, false: Error
40 */
41
42 static bool range_args(uint32 *adr, uint32 *end_adr, uint32 def_range)
43 {
44 *adr = mon_dot_address;
45 *end_adr = mon_dot_address + def_range;
46
47 if (mon_token == T_END)
48 return true;
49 else {
50 if (!mon_expression(adr))
51 return false;
52 *end_adr = *adr + def_range;
53 if (mon_token == T_END)
54 return true;
55 else {
56 if (mon_token == T_COMMA) mon_get_token();
57 if (!mon_expression(end_adr))
58 return false;
59 return mon_token == T_END;
60 }
61 }
62 }
63
64
65 /*
66 * byte_string = (expression | STRING) {COMMA (expression | STRING)} END
67 */
68
69 static bool byte_string(uint8 *s, uint32 &len)
70 {
71 uint32 value;
72
73 len = 0;
74 goto start;
75
76 for (;;) {
77 if (mon_token == T_COMMA) {
78 mon_get_token();
79
80 start:
81 if (mon_token == T_STRING) {
82 uint8 *p = (uint8 *)mon_string;
83 while ((*s++ = *p++) != 0) ;
84 s--;
85 len += strlen(mon_string);
86 mon_get_token();
87 } else if (mon_expression(&value)) {
88 *s++ = value;
89 len++;
90 } else
91 return false;
92
93 } else if (mon_token == T_END)
94 return true;
95 else {
96 mon_error("',' expected");
97 return false;
98 }
99 }
100 }
101
102
103 /*
104 * Convert character to printable character
105 */
106
107 static inline uint8 char2print(uint8 c)
108 {
109 return (c >= 0x20 && c <= 0x7e) ? c : '.';
110 }
111
112
113 /*
114 * Show version
115 * ver
116 */
117
118 void version(void)
119 {
120 fprintf(monout, "mon V%d.%d\n", VERSION_MAJOR, VERSION_MINOR);
121 }
122
123
124 /*
125 * Redirect output
126 * o [file]
127 */
128
129 void redir_output(void)
130 {
131 // Close old file
132 if (monout != monerr) {
133 fclose(monout);
134 monout = monerr;
135 return;
136 }
137
138 // No argument given?
139 if (mon_token == T_END)
140 return;
141
142 // Otherwise open file
143 if (mon_token == T_STRING) {
144 mon_get_token();
145 if (mon_token != T_END) {
146 mon_error("Too many arguments");
147 return;
148 }
149 if (!(monout = fopen(mon_string, "w")))
150 mon_error("Unable to open file");
151 } else
152 mon_error("'\"' around file name expected");
153 }
154
155
156 /*
157 * Compute and display expression
158 * ? expression
159 */
160
161 void print_expr(void)
162 {
163 uint32 val;
164
165 if (!mon_expression(&val))
166 return;
167 if (mon_token != T_END) {
168 mon_error("Too many arguments");
169 return;
170 }
171
172 if (val > 0x7fffffff) {
173 fprintf(monout, "Hex unsigned: $%08lx\n"
174 "Hex signed : -$%08lx\n"
175 "Dec unsigned: %lu\n"
176 "Dec signed : %ld\n", val, -val, val, val);
177 fprintf(monout, "Char : '%c%c%c%c'\n", char2print(val >> 24), char2print(val >> 16), char2print(val >> 8), char2print(val));
178 } else {
179 fprintf(monout, "Hex : $%08lx\n"
180 "Dec : %ld\n", val, val);
181 fprintf(monout, "Char: '%c%c%c%c'\n", char2print(val >> 24), char2print(val >> 16), char2print(val >> 8), char2print(val));
182 }
183 }
184
185
186 /*
187 * Execute shell command
188 * \ "command"
189 */
190
191 void shell_command(void)
192 {
193 if (mon_token != T_STRING) {
194 mon_error("'\"' around command expected");
195 return;
196 }
197 mon_get_token();
198 if (mon_token != T_END) {
199 mon_error("Too many arguments");
200 return;
201 }
202 system(mon_string);
203 }
204
205
206 /*
207 * Memory dump
208 * m [start [end]]
209 */
210
211 #define MEMDUMP_BPL 16 // Bytes per line
212
213 void memory_dump(void)
214 {
215 uint32 adr, end_adr;
216 uint8 mem[MEMDUMP_BPL + 1];
217
218 mem[MEMDUMP_BPL] = 0;
219
220 if (!range_args(&adr, &end_adr, 16 * MEMDUMP_BPL - 1)) // 16 lines unless end address specified
221 return;
222
223 while (adr <= end_adr && !mon_aborted()) {
224 fprintf(monout, "%08lx:", mon_use_real_mem ? adr: adr % mon_mem_size);
225 for (int i=0; i<MEMDUMP_BPL; i++, adr++) {
226 if (i % 4 == 0)
227 fprintf(monout, " %08lx", mon_read_word(adr));
228 mem[i] = char2print(mon_read_byte(adr));
229 }
230 fprintf(monout, " '%s'\n", mem);
231 }
232
233 mon_dot_address = adr;
234 }
235
236
237 /*
238 * ASCII dump
239 * i [start [end]]
240 */
241
242 #define ASCIIDUMP_BPL 64 // Bytes per line
243
244 void ascii_dump(void)
245 {
246 uint32 adr, end_adr;
247 uint8 str[ASCIIDUMP_BPL + 1];
248
249 str[ASCIIDUMP_BPL] = 0;
250
251 if (!range_args(&adr, &end_adr, 16 * ASCIIDUMP_BPL - 1)) // 16 lines unless end address specified
252 return;
253
254 while (adr <= end_adr && !mon_aborted()) {
255 fprintf(monout, "%08lx:", mon_use_real_mem ? adr : adr % mon_mem_size);
256 for (int i=0; i<ASCIIDUMP_BPL; i++, adr++)
257 str[i] = char2print(mon_read_byte(adr));
258 fprintf(monout, " '%s'\n", str);
259 }
260
261 mon_dot_address = adr;
262 }
263
264
265 /*
266 * Disassemble
267 * d [start [end]]
268 * d65 [start [end]]
269 * d68 [start [end]]
270 * d80 [start [end]]
271 * d86 [start [end]]
272 */
273
274 enum CPUType {
275 CPU_PPC,
276 CPU_6502,
277 CPU_680x0,
278 CPU_8080,
279 CPU_80x86
280 };
281
282 static void disassemble(CPUType type)
283 {
284 uint32 adr, end_adr;
285
286 if (!range_args(&adr, &end_adr, 16 * 4 - 1)) // 16 lines unless end address specified
287 return;
288
289 switch (type) {
290 case CPU_PPC:
291 while (adr <= end_adr && !mon_aborted()) {
292 uint32 w = mon_read_word(adr);
293 fprintf(monout, "%08lx: %08lx\t", mon_use_real_mem ? adr : adr % mon_mem_size, w);
294 disass_ppc(monout, mon_use_real_mem ? adr : adr % mon_mem_size, w);
295 adr += 4;
296 }
297 break;
298
299 case CPU_6502:
300 while (adr <= end_adr && !mon_aborted()) {
301 uint8 op = mon_read_byte(adr);
302 uint8 lo = mon_read_byte(adr + 1);
303 uint8 hi = mon_read_byte(adr + 2);
304 fprintf(monout, "%08lx: ", mon_use_real_mem ? adr : adr % mon_mem_size);
305 adr += disass_6502(monout, mon_use_real_mem ? adr : adr % mon_mem_size, op, lo, hi);
306 }
307 break;
308
309 case CPU_680x0:
310 while (adr <= end_adr && !mon_aborted()) {
311 uint16 buf[8];
312 buf[0] = mon_read_half(adr);
313 buf[1] = mon_read_half(adr + 2);
314 buf[2] = mon_read_half(adr + 4);
315 buf[3] = mon_read_half(adr + 6);
316 buf[4] = mon_read_half(adr + 8);
317 buf[5] = mon_read_half(adr + 10);
318 buf[6] = mon_read_half(adr + 12);
319 buf[7] = mon_read_half(adr + 14);
320 fprintf(monout, "%08lx: ", mon_use_real_mem ? adr : adr % mon_mem_size);
321 adr += disass_68k(monout, mon_use_real_mem ? adr : adr % mon_mem_size, buf);
322 }
323 break;
324
325 case CPU_8080:
326 while (adr <= end_adr && !mon_aborted()) {
327 uint8 op = mon_read_byte(adr);
328 uint8 lo = mon_read_byte(adr + 1);
329 uint8 hi = mon_read_byte(adr + 2);
330 fprintf(monout, "%08lx: ", mon_use_real_mem ? adr : adr % mon_mem_size);
331 adr += disass_8080(monout, mon_use_real_mem ? adr : adr % mon_mem_size, op, lo, hi);
332 }
333 break;
334
335 case CPU_80x86:
336 while (adr <= end_adr && !mon_aborted()) {
337 uint8 buf[16];
338 for (int i=0; i<16; i++)
339 buf[i] = mon_read_byte(adr + i);
340 fprintf(monout, "%08lx: ", mon_use_real_mem ? adr : adr % mon_mem_size);
341 adr += disass_x86(monout, mon_use_real_mem ? adr : adr % mon_mem_size, buf);
342 }
343 break;
344 }
345
346 mon_dot_address = adr;
347 }
348
349 void disassemble_ppc(void)
350 {
351 disassemble(CPU_PPC);
352 }
353
354 void disassemble_6502(void)
355 {
356 disassemble(CPU_6502);
357 }
358
359 void disassemble_680x0(void)
360 {
361 disassemble(CPU_680x0);
362 }
363
364 void disassemble_8080(void)
365 {
366 disassemble(CPU_8080);
367 }
368
369 void disassemble_80x86(void)
370 {
371 disassemble(CPU_80x86);
372 }
373
374
375 /*
376 * Modify memory
377 * : addr bytestring
378 */
379
380 void modify(void)
381 {
382 uint32 adr, len, src_adr = 0;
383 uint8 str[256];
384
385 if (!mon_expression(&adr))
386 return;
387 if (!byte_string(str, len))
388 return;
389
390 while (src_adr < len)
391 mon_write_byte(adr++, str[src_adr++]);
392
393 mon_dot_address = adr;
394 }
395
396
397 /*
398 * Fill
399 * f start end bytestring
400 */
401
402 void fill(void)
403 {
404 uint32 adr, end_adr, len, src_adr = 0;
405 uint8 str[256];
406
407 if (!mon_expression(&adr))
408 return;
409 if (!mon_expression(&end_adr))
410 return;
411 if (!byte_string(str, len))
412 return;
413
414 while (adr <= end_adr)
415 mon_write_byte(adr++, str[src_adr++ % len]);
416 }
417
418
419 /*
420 * Transfer memory
421 * t start end dest
422 */
423
424 void transfer(void)
425 {
426 uint32 adr, end_adr, dest;
427 int num;
428
429 if (!mon_expression(&adr))
430 return;
431 if (!mon_expression(&end_adr))
432 return;
433 if (!mon_expression(&dest))
434 return;
435 if (mon_token != T_END) {
436 mon_error("Too many arguments");
437 return;
438 }
439
440 num = end_adr - adr + 1;
441
442 if (dest < adr)
443 for (int i=0; i<num; i++)
444 mon_write_byte(dest++, mon_read_byte(adr++));
445 else {
446 dest += end_adr - adr;
447 for (int i=0; i<num; i++)
448 mon_write_byte(dest--, mon_read_byte(end_adr--));
449 }
450 }
451
452
453 /*
454 * Compare
455 * c start end dest
456 */
457
458 void compare(void)
459 {
460 uint32 adr, end_adr, dest;
461 int num = 0;
462
463 if (!mon_expression(&adr))
464 return;
465 if (!mon_expression(&end_adr))
466 return;
467 if (!mon_expression(&dest))
468 return;
469 if (mon_token != T_END) {
470 mon_error("Too many arguments");
471 return;
472 }
473
474 while (adr <= end_adr && !mon_aborted()) {
475 if (mon_read_byte(adr) != mon_read_byte(dest)) {
476 fprintf(monout, "%08lx ", mon_use_real_mem ? adr : adr % mon_mem_size);
477 num++;
478 if (!(num & 7))
479 fputc('\n', monout);
480 }
481 adr++; dest++;
482 }
483
484 if (num & 7)
485 fputc('\n', monout);
486 fprintf(monout, "%d byte(s) different\n", num);
487 }
488
489
490 /*
491 * Search for byte string
492 * h start end bytestring
493 */
494
495 void hunt(void)
496 {
497 uint32 adr, end_adr, len;
498 uint8 str[256];
499 int num = 0;
500
501 if (!mon_expression(&adr))
502 return;
503 if (!mon_expression(&end_adr))
504 return;
505 if (!byte_string(str, len))
506 return;
507
508 while ((adr+len-1) <= end_adr && !mon_aborted()) {
509 uint32 i;
510
511 for (i=0; i<len; i++)
512 if (mon_read_byte(adr + i) != str[i])
513 break;
514
515 if (i == len) {
516 fprintf(monout, "%08lx ", mon_use_real_mem ? adr : adr % mon_mem_size);
517 num++;
518 if (num == 1)
519 mon_dot_address = adr;
520 if (!(num & 7))
521 fputc('\n', monout);
522 }
523 adr++;
524 }
525
526 if (num & 7)
527 fputc('\n', monout);
528 fprintf(monout, "Found %d occurrences\n", num);
529 }
530
531
532 /*
533 * Load data
534 * [ start "file"
535 */
536
537 void load_data(void)
538 {
539 uint32 start_adr;
540 FILE *file;
541 int fc;
542
543 if (!mon_expression(&start_adr))
544 return;
545 if (mon_token == T_END) {
546 mon_error("Missing file name");
547 return;
548 }
549 if (mon_token != T_STRING) {
550 mon_error("'\"' around file name expected");
551 return;
552 }
553 mon_get_token();
554 if (mon_token != T_END) {
555 mon_error("Too many arguments");
556 return;
557 }
558
559 if (!(file = fopen(mon_string, "rb")))
560 mon_error("Unable to open file");
561 else {
562 uint32 adr = start_adr;
563
564 while ((fc = fgetc(file)) != EOF)
565 mon_write_byte(adr++, fc);
566 fclose(file);
567
568 fprintf(monerr, "%08lx bytes read from %08lx to %08lx\n", adr - start_adr, mon_use_real_mem ? start_adr : start_adr % mon_mem_size, mon_use_real_mem ? adr-1 : (adr-1) % mon_mem_size);
569 mon_dot_address = adr;
570 }
571 }
572
573
574 /*
575 * Save data
576 * ] start size "file"
577 */
578
579 void save_data(void)
580 {
581 uint32 start_adr, size;
582 FILE *file;
583
584 if (!mon_expression(&start_adr))
585 return;
586 if (!mon_expression(&size))
587 return;
588 if (mon_token == T_END) {
589 mon_error("Missing file name");
590 return;
591 }
592 if (mon_token != T_STRING) {
593 mon_error("'\"' around file name expected");
594 return;
595 }
596 mon_get_token();
597 if (mon_token != T_END) {
598 mon_error("Too many arguments");
599 return;
600 }
601
602 if (!(file = fopen(mon_string, "wb")))
603 mon_error("Unable to create file");
604 else {
605 uint32 adr = start_adr, end_adr = start_adr + size - 1;
606
607 while (adr <= end_adr)
608 fputc(mon_read_byte(adr++), file);
609 fclose(file);
610
611 fprintf(monerr, "%08lx bytes written from %08lx to %08lx\n", size, mon_use_real_mem ? start_adr : start_adr % mon_mem_size, mon_use_real_mem ? end_adr : end_adr % mon_mem_size);
612 }
613 }