ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/mon/src/mon_cmd.cpp
Revision: 1.1
Committed: 1999-10-04T19:31:09Z (25 years, 2 months ago) by cebix
Branch: MAIN
Branch point for: cebix
Log Message:
Initial revision

File Contents

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