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 (24 years, 7 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

# User Rev Content
1 cebix 1.1 /*
2     * mon_cmd.cpp - mon standard commands
3     *
4 cebix 1.2 * 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 cebix 1.1 */
20    
21 cebix 1.2 #include "sysdeps.h"
22 cebix 1.1
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 cebix 1.2 #include "version.h"
31 cebix 1.1
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 cebix 1.2 fprintf(monout, "mon V%d.%d\n", VERSION_MAJOR, VERSION_MINOR);
121 cebix 1.1 }
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     }