Mercurial > hg > Members > kono > os9 > sbc09
annotate trace.c @ 20:49fac9474858
separate trace file
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 09 Jul 2018 09:29:33 +0900 |
parents | io.c@84b28178c82f |
children | 1925cfa982fe |
rev | line source |
---|---|
9 | 1 /* 6808 Simulator V092 |
20 | 2 * |
3 * tracer | |
0 | 4 |
5 */ | |
6 | |
7 #include<stdio.h> | |
8 #include<stdlib.h> | |
9 #include<ctype.h> | |
10 #include<signal.h> | |
11 #include<sys/time.h> | |
12 | |
13 #include <unistd.h> | |
14 #include <fcntl.h> | |
15 #include <string.h> | |
1 | 16 #include <time.h> |
0 | 17 |
18 #ifdef USE_TERMIOS | |
19 #include <termios.h> | |
20 #endif | |
21 | |
22 #define engine extern | |
23 #include "v09.h" | |
24 | |
25 struct termios termsetting; | |
26 | |
27 int xmstat; /* 0= no XMODEM transfer, 1=send, 2=receiver */ | |
28 unsigned char xmbuf[132]; | |
29 int xidx; | |
30 int acknak; | |
31 int rcvdnak; | |
32 int blocknum; | |
33 | |
20 | 34 extern FILE *logfile; |
35 extern FILE *infile; | |
36 extern FILE *xfile; | |
37 extern FILE *disk[]; | |
0 | 38 |
39 extern void hexadump( unsigned char *b, int l, int loc, int w); | |
12
111e5defb8ab
boot is called, rti failed
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
11
diff
changeset
|
40 extern int disasm(int,int); |
20 | 41 extern void restore_term(void) ; |
42 | |
9 | 43 #ifdef USE_MMU |
44 extern char *prog ; // for disass | |
11 | 45 extern Byte * mem0(Byte *iphymem, Word adr, Byte *immu) ; |
9 | 46 #endif |
47 | |
0 | 48 void do_exit(void) { |
49 restore_term(); | |
50 exit(0); | |
51 } | |
52 | |
4 | 53 |
0 | 54 typedef struct bp { |
55 int address; | |
56 int count; | |
57 struct bp *next; | |
58 } BP, *BPTR; | |
59 | |
60 BPTR breakpoint = 0; | |
61 int bpskip = 0; | |
62 int trskip = 0; | |
63 int stkskip = 0; | |
64 | |
65 int getarg(char *buf, char** next) { | |
66 return strtol(buf,(char**)next,0); | |
67 } | |
68 | |
69 void printhelp(void) | |
70 { | |
71 printf( | |
72 " s [count] one step trace\n" | |
73 " n step over\n" | |
74 " f finish this call (until stack pop)\n" | |
75 " b [adr] set break point\n" | |
76 " l break point list\n" | |
77 " d [n] delte break point list\n" | |
78 " c [count] continue;\n" | |
79 " x [adr] dump\n" | |
9 | 80 #ifdef USE_MMU |
81 " xp [adr] dump physical memory\n" | |
82 #endif | |
0 | 83 " xi [adr] disassemble\n" |
1 | 84 " 0 file disk drive 0 image\n" |
85 " 1 file disk drive 1 image\n" | |
0 | 86 " L file start log to file\n" |
87 " S file set input file\n" | |
88 " X exit\n" | |
89 " q exit\n" | |
90 " U file upload from srecord file \n" | |
91 " D file download to srecord file \n" | |
92 " R do reset\n" | |
93 " h,? print this\n" | |
94 ); | |
95 } | |
96 | |
97 void do_escape(void) { | |
98 char s[80]; | |
99 int adr,skip; | |
100 if (bpskip) { // skip unbreak instruction | |
101 bpskip--; | |
102 for(BPTR b = breakpoint; b ; b=b->next) { | |
103 if (pcreg==b->address) { | |
104 if (b->count) b->count--; | |
105 if (b->count==0) { | |
106 goto restart0; | |
107 } | |
108 } | |
109 } | |
110 return; | |
111 } | |
112 if (stkskip) { // skip until return | |
113 if (sreg < stkskip ) return; | |
114 } | |
115 restart0: | |
116 stkskip = 0; | |
117 restore_term(); | |
9 | 118 #ifdef USE_MMU |
11 | 119 Byte *phyadr = mem0(phymem,pcreg,mmu); |
9 | 120 prog = (char*)phyadr - pcreg; |
121 #endif | |
0 | 122 do_trace(stdout); |
123 if (trskip>1) { // show trace and step | |
124 trskip--; | |
125 set_term(escchar); | |
126 return; | |
127 } | |
128 restart: | |
129 printf("v09>"); | |
130 fgets(s, 80, stdin); | |
131 if (s[0]) | |
132 s[strlen(s) - 1] = 0; | |
133 switch (s[0]) { | |
134 case 's': // one step trace | |
135 trskip = 1; | |
136 if (s[1]) { | |
137 trskip = getarg(s+1,0); | |
138 } | |
139 bpskip = 0; | |
140 attention = escape = 1; | |
141 break; | |
142 case 'n': // step over | |
143 stkskip = sreg; | |
144 attention = escape = 1; | |
145 break; | |
146 case 'f': // finish this call (until stack pop) | |
147 stkskip = sreg + 2; | |
148 attention = escape = 1; | |
149 break; | |
150 case 'b': // set break point | |
151 { | |
152 BPTR bp = calloc(1,sizeof(BP)); | |
153 bp->next = breakpoint; | |
154 breakpoint = bp; | |
155 bp->count = 1; | |
156 if (s[1]) { | |
157 char *next; | |
158 bp->address = getarg(s+1,&next); | |
159 if (next[0]) { | |
160 bp->count = getarg(next,&next); | |
161 } | |
162 } else { | |
163 bp->address = pcreg; | |
164 } | |
165 } | |
166 bpskip = -1; | |
167 goto restart; | |
168 case 'l': // break point list | |
169 for(BPTR bp = breakpoint; bp ; bp = bp->next) { | |
170 printf("%x %i\n", bp->address, bp->count); | |
171 } | |
172 goto restart; | |
173 case 'd': // delte break point list | |
174 if (s[1]) { | |
175 int trskip = getarg(s+1,0); | |
176 BPTR *prev = &breakpoint; | |
177 for(BPTR bp = breakpoint; bp ; bp = bp->next) { | |
178 if (trskip-- == 0) { | |
179 if (bp) { | |
180 *prev = bp->next; | |
181 } | |
182 break; | |
183 } | |
184 prev = &bp->next; | |
185 } | |
186 } | |
187 goto restart; | |
188 case 'c': // continue; | |
189 bpskip = -1; | |
190 attention = escape = 1; | |
191 if (s[1]) { | |
192 bpskip = getarg(s+1,0); | |
193 } | |
194 break; | |
195 case 'x': // dump | |
196 skip = 1; | |
197 if (s[1]=='i') skip=2; | |
9 | 198 if (s[1]=='p') skip=2; |
0 | 199 if (s[skip]) { |
200 char *next; | |
201 int adr = getarg(s+skip,&next); | |
202 int len = 32; | |
203 if (next[0]) { | |
204 len = getarg(next,&next); | |
205 } | |
9 | 206 if (skip==2 && s[1]=='i') { |
12
111e5defb8ab
boot is called, rti failed
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
11
diff
changeset
|
207 Word end = adr + len; |
111e5defb8ab
boot is called, rti failed
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
11
diff
changeset
|
208 while(adr < end) { |
9 | 209 #ifdef USE_MMU |
12
111e5defb8ab
boot is called, rti failed
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
11
diff
changeset
|
210 Byte *phyadr = mem0(phymem,adr,mmu); |
111e5defb8ab
boot is called, rti failed
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
11
diff
changeset
|
211 prog = (char*)phyadr - adr ; |
111e5defb8ab
boot is called, rti failed
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
11
diff
changeset
|
212 if (phyadr > phymem+memsize) goto restart; |
9 | 213 #endif |
12
111e5defb8ab
boot is called, rti failed
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
11
diff
changeset
|
214 int len = adr+16<end? 16 : end-adr -1 ; |
111e5defb8ab
boot is called, rti failed
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
11
diff
changeset
|
215 adr = disasm(adr,adr+len); |
9 | 216 } |
0 | 217 } else { |
9 | 218 #ifdef USE_MMU |
219 for(int i=0; len > 0 ; i+=16, len-=16) { | |
220 if (skip==2 && s[1]=='p') { | |
221 if (adr+i > memsize) goto restart; | |
222 hexadump(phymem+adr+i,len>16?16:len,adr+i,16); | |
223 } else { | |
11 | 224 Byte *phyadr = mem0(phymem,adr+i,mmu); |
9 | 225 if (phyadr > phymem+memsize) goto restart; |
226 hexadump(phyadr,len>16?16:len,adr+i,16); | |
227 } | |
228 } | |
229 #else | |
0 | 230 for(int i=0; len > 0 ; i+=16, len-=16) { |
231 hexadump(mem+adr+i,len>16?16:len,adr+i,16); | |
232 } | |
9 | 233 #endif |
0 | 234 } |
235 } else | |
236 disasm(pcreg,pcreg+32); | |
237 goto restart; | |
238 case 'L': | |
239 if (logfile) | |
240 fclose(logfile); | |
241 logfile = 0; | |
242 if (s[1]) { | |
1 | 243 int i=1; while(s[i]==' ') i++; |
244 logfile = fopen(s + i, "w"); | |
0 | 245 } |
246 break; | |
247 case 'S': | |
248 if (infile) | |
249 fclose(infile); | |
250 infile = 0; | |
251 if (s[1]) { | |
1 | 252 int i=1; while(s[i]==' ') i++; |
253 infile = fopen(s + i, "r"); | |
0 | 254 } |
255 break; | |
256 case 'h': | |
257 case '?': | |
258 printhelp(); | |
259 goto restart; | |
260 case 'X': | |
261 case 'q': | |
262 if (!xmstat) | |
263 do_exit(); | |
264 else { | |
265 xmstat = 0; | |
266 fclose(xfile); | |
267 xfile = 0; | |
268 } | |
269 break; | |
1 | 270 case '0': |
271 case '1': | |
272 { FILE **drv = &disk[ s[0]-'0'] ; | |
273 if (*drv) | |
274 fclose(*drv); | |
275 *drv = 0; | |
276 if (s[1]) { | |
277 int i=1; while(s[i]==' ') i++; | |
278 *drv = fopen(s + i, "r+b"); | |
279 if ( *drv == 0 ) { printf("can't open %s\n", &s[i]); } | |
280 } | |
281 } | |
282 break; | |
0 | 283 case 'U': |
284 if (xfile) | |
285 fclose(xfile); | |
286 xfile = 0; | |
287 if (s[1]) { | |
1 | 288 int i=1; while(s[i]==' ') i++; |
289 xfile = fopen(s + i, "rb"); | |
290 if ( xfile == 0 ) { printf("can't open %s\n", &s[i]); } | |
0 | 291 } |
292 if (xfile) | |
293 xmstat = 1; | |
294 else | |
295 xmstat = 0; | |
296 xidx = 0; | |
297 acknak = 21; | |
298 rcvdnak = EOF; | |
299 blocknum = 1; | |
300 break; | |
301 case 'D': | |
302 if (xfile) | |
303 fclose(xfile); | |
304 xfile = 0; | |
305 if (s[1]) { | |
1 | 306 int i=1; while(s[i]==' ') i++; |
307 xfile = fopen(s + i, "wb"); | |
308 if ( xfile == 0 ) { printf("can't open %s\n", &s[i]); } | |
0 | 309 } |
310 if (xfile) | |
311 xmstat = 2; | |
312 else | |
313 xmstat = 0; | |
314 xidx = 0; | |
315 acknak = 21; | |
316 blocknum = 1; | |
317 break; | |
318 case 'R': | |
319 pcreg = (mem[0xfffe] << 8) + mem[0xffff]; | |
13 | 320 bpskip = 0; |
321 attention = escape = 1; | |
0 | 322 break; |
323 } | |
324 if (tracing||breakpoint||trskip||bpskip||stkskip) { attention = escape = 1; } | |
325 else attention = 0; | |
326 set_term(escchar); | |
327 } | |
328 |