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 (24 years, 7 months ago) by cebix
Branch: MAIN
Branch point for: cebix
Log Message:
Initial revision

File Contents

# User Rev Content
1 cebix 1.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     }