ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/mon/src/mon_cmd.cpp
Revision: 1.6
Committed: 2000-06-10T19:07:37Z (23 years, 11 months ago) by hellwig
Branch: MAIN
Changes since 1.5: +4 -0 lines
Log Message:
- changes for SheepShaver

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