ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/mon/src/mon_cmd.cpp
Revision: 1.4
Committed: 1999-10-25T08:04:47Z (24 years, 6 months ago) by cebix
Branch: MAIN
Changes since 1.3: +3 -2 lines
Log Message:
- Unix: added mkinstalldirs to "make install" target
- user-defined functions for memory access can be supplied

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