Mercurial > hg > Members > kono > os9 > sbc09
annotate trace.c @ 21:1925cfa982fe
fixing trace
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 09 Jul 2018 11:25:28 +0900 |
parents | 49fac9474858 |
children | 10e33568b38a |
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) ; |
21 | 46 extern int paddr(Word adr, Byte *immu) ; |
47 #else | |
48 #define paddr(a,m) (a) | |
9 | 49 #endif |
50 | |
0 | 51 void do_exit(void) { |
52 restore_term(); | |
53 exit(0); | |
54 } | |
55 | |
4 | 56 |
0 | 57 typedef struct bp { |
21 | 58 int address; // physical address |
59 int laddr; | |
0 | 60 int count; |
61 struct bp *next; | |
62 } BP, *BPTR; | |
63 | |
64 BPTR breakpoint = 0; | |
65 int bpskip = 0; | |
66 int trskip = 0; | |
67 int stkskip = 0; | |
68 | |
69 int getarg(char *buf, char** next) { | |
70 return strtol(buf,(char**)next,0); | |
71 } | |
72 | |
73 void printhelp(void) | |
74 { | |
75 printf( | |
76 " s [count] one step trace\n" | |
77 " n step over\n" | |
78 " f finish this call (until stack pop)\n" | |
79 " b [adr] set break point\n" | |
80 " l break point list\n" | |
81 " d [n] delte break point list\n" | |
82 " c [count] continue;\n" | |
83 " x [adr] dump\n" | |
9 | 84 #ifdef USE_MMU |
85 " xp [adr] dump physical memory\n" | |
86 #endif | |
0 | 87 " xi [adr] disassemble\n" |
1 | 88 " 0 file disk drive 0 image\n" |
89 " 1 file disk drive 1 image\n" | |
0 | 90 " L file start log to file\n" |
91 " S file set input file\n" | |
92 " X exit\n" | |
93 " q exit\n" | |
94 " U file upload from srecord file \n" | |
95 " D file download to srecord file \n" | |
96 " R do reset\n" | |
97 " h,? print this\n" | |
98 ); | |
99 } | |
100 | |
21 | 101 |
102 void setbreak(int adr,int count) ; | |
103 void nexti(void); | |
104 | |
0 | 105 void do_escape(void) { |
106 char s[80]; | |
107 int adr,skip; | |
108 if (bpskip) { // skip unbreak instruction | |
109 bpskip--; | |
21 | 110 int lpc = paddr(pcreg,mmu); |
111 BPTR *prev = &breakpoint; | |
112 for(BPTR b = breakpoint; b ; b=b->next, prev=prev->next) { | |
113 if (lpc==b->address) { | |
114 if (b->count==-1) { // temporaly break point | |
115 BPTR next = b->next; | |
116 free(b); | |
117 prev->next = next; | |
118 goto restart0; | |
119 } | |
0 | 120 if (b->count) b->count--; |
121 if (b->count==0) { | |
122 goto restart0; | |
123 } | |
124 } | |
125 } | |
126 return; | |
127 } | |
128 if (stkskip) { // skip until return | |
129 if (sreg < stkskip ) return; | |
130 } | |
131 restart0: | |
132 stkskip = 0; | |
133 restore_term(); | |
9 | 134 #ifdef USE_MMU |
11 | 135 Byte *phyadr = mem0(phymem,pcreg,mmu); |
9 | 136 prog = (char*)phyadr - pcreg; |
137 #endif | |
0 | 138 do_trace(stdout); |
139 if (trskip>1) { // show trace and step | |
140 trskip--; | |
141 set_term(escchar); | |
142 return; | |
143 } | |
144 restart: | |
145 printf("v09>"); | |
146 fgets(s, 80, stdin); | |
147 if (s[0]) | |
148 s[strlen(s) - 1] = 0; | |
149 switch (s[0]) { | |
21 | 150 case 'n': // step over |
151 if (nexti()) { | |
152 bpskip = -1; | |
153 break; | |
154 } | |
0 | 155 case 's': // one step trace |
156 trskip = 1; | |
157 if (s[1]) { | |
158 trskip = getarg(s+1,0); | |
159 } | |
160 bpskip = 0; | |
161 attention = escape = 1; | |
162 break; | |
163 case 'f': // finish this call (until stack pop) | |
164 stkskip = sreg + 2; | |
165 attention = escape = 1; | |
166 break; | |
167 case 'b': // set break point | |
21 | 168 if (s[1]) { |
169 char *next; | |
170 int count = 0; | |
171 int adr = getarg(s+0,&next); | |
172 if (next[0]) { | |
173 count = getarg(next,&next); | |
174 } | |
175 setbreak(adr,count); | |
176 } else { | |
177 setbreak(pcreg,0); | |
0 | 178 } |
179 bpskip = -1; | |
180 goto restart; | |
181 case 'l': // break point list | |
182 for(BPTR bp = breakpoint; bp ; bp = bp->next) { | |
21 | 183 #ifdef USE_MMU |
184 printf("%x %x %d\n", bp->laddr, bp->address, bp->count); | |
185 #else | |
186 printf("%x %d\n", bp->address, bp->count); | |
187 #endif | |
0 | 188 } |
189 goto restart; | |
190 case 'd': // delte break point list | |
191 if (s[1]) { | |
192 int trskip = getarg(s+1,0); | |
193 BPTR *prev = &breakpoint; | |
194 for(BPTR bp = breakpoint; bp ; bp = bp->next) { | |
195 if (trskip-- == 0) { | |
21 | 196 BPTR next = b->next; |
197 free(bp); | |
198 prev->next = next; | |
0 | 199 break; |
200 } | |
201 prev = &bp->next; | |
202 } | |
203 } | |
204 goto restart; | |
205 case 'c': // continue; | |
206 bpskip = -1; | |
207 attention = escape = 1; | |
208 if (s[1]) { | |
209 bpskip = getarg(s+1,0); | |
210 } | |
211 break; | |
212 case 'x': // dump | |
213 skip = 1; | |
214 if (s[1]=='i') skip=2; | |
9 | 215 if (s[1]=='p') skip=2; |
0 | 216 if (s[skip]) { |
217 char *next; | |
218 int adr = getarg(s+skip,&next); | |
219 int len = 32; | |
220 if (next[0]) { | |
221 len = getarg(next,&next); | |
222 } | |
9 | 223 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
|
224 Word end = adr + len; |
111e5defb8ab
boot is called, rti failed
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
11
diff
changeset
|
225 while(adr < end) { |
9 | 226 #ifdef USE_MMU |
12
111e5defb8ab
boot is called, rti failed
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
11
diff
changeset
|
227 Byte *phyadr = mem0(phymem,adr,mmu); |
111e5defb8ab
boot is called, rti failed
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
11
diff
changeset
|
228 prog = (char*)phyadr - adr ; |
111e5defb8ab
boot is called, rti failed
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
11
diff
changeset
|
229 if (phyadr > phymem+memsize) goto restart; |
9 | 230 #endif |
12
111e5defb8ab
boot is called, rti failed
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
11
diff
changeset
|
231 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
|
232 adr = disasm(adr,adr+len); |
9 | 233 } |
0 | 234 } else { |
9 | 235 #ifdef USE_MMU |
236 for(int i=0; len > 0 ; i+=16, len-=16) { | |
237 if (skip==2 && s[1]=='p') { | |
238 if (adr+i > memsize) goto restart; | |
239 hexadump(phymem+adr+i,len>16?16:len,adr+i,16); | |
240 } else { | |
11 | 241 Byte *phyadr = mem0(phymem,adr+i,mmu); |
9 | 242 if (phyadr > phymem+memsize) goto restart; |
243 hexadump(phyadr,len>16?16:len,adr+i,16); | |
244 } | |
245 } | |
246 #else | |
0 | 247 for(int i=0; len > 0 ; i+=16, len-=16) { |
248 hexadump(mem+adr+i,len>16?16:len,adr+i,16); | |
249 } | |
9 | 250 #endif |
0 | 251 } |
252 } else | |
253 disasm(pcreg,pcreg+32); | |
254 goto restart; | |
255 case 'L': | |
256 if (logfile) | |
257 fclose(logfile); | |
258 logfile = 0; | |
259 if (s[1]) { | |
1 | 260 int i=1; while(s[i]==' ') i++; |
261 logfile = fopen(s + i, "w"); | |
0 | 262 } |
263 break; | |
264 case 'S': | |
265 if (infile) | |
266 fclose(infile); | |
267 infile = 0; | |
268 if (s[1]) { | |
1 | 269 int i=1; while(s[i]==' ') i++; |
270 infile = fopen(s + i, "r"); | |
0 | 271 } |
272 break; | |
273 case 'h': | |
274 case '?': | |
275 printhelp(); | |
276 goto restart; | |
277 case 'X': | |
278 case 'q': | |
279 if (!xmstat) | |
280 do_exit(); | |
281 else { | |
282 xmstat = 0; | |
283 fclose(xfile); | |
284 xfile = 0; | |
285 } | |
286 break; | |
1 | 287 case '0': |
288 case '1': | |
289 { FILE **drv = &disk[ s[0]-'0'] ; | |
290 if (*drv) | |
291 fclose(*drv); | |
292 *drv = 0; | |
293 if (s[1]) { | |
294 int i=1; while(s[i]==' ') i++; | |
295 *drv = fopen(s + i, "r+b"); | |
296 if ( *drv == 0 ) { printf("can't open %s\n", &s[i]); } | |
297 } | |
298 } | |
299 break; | |
0 | 300 case 'U': |
301 if (xfile) | |
302 fclose(xfile); | |
303 xfile = 0; | |
304 if (s[1]) { | |
1 | 305 int i=1; while(s[i]==' ') i++; |
306 xfile = fopen(s + i, "rb"); | |
307 if ( xfile == 0 ) { printf("can't open %s\n", &s[i]); } | |
0 | 308 } |
309 if (xfile) | |
310 xmstat = 1; | |
311 else | |
312 xmstat = 0; | |
313 xidx = 0; | |
314 acknak = 21; | |
315 rcvdnak = EOF; | |
316 blocknum = 1; | |
317 break; | |
318 case 'D': | |
319 if (xfile) | |
320 fclose(xfile); | |
321 xfile = 0; | |
322 if (s[1]) { | |
1 | 323 int i=1; while(s[i]==' ') i++; |
324 xfile = fopen(s + i, "wb"); | |
325 if ( xfile == 0 ) { printf("can't open %s\n", &s[i]); } | |
0 | 326 } |
327 if (xfile) | |
328 xmstat = 2; | |
329 else | |
330 xmstat = 0; | |
331 xidx = 0; | |
332 acknak = 21; | |
333 blocknum = 1; | |
334 break; | |
335 case 'R': | |
336 pcreg = (mem[0xfffe] << 8) + mem[0xffff]; | |
13 | 337 bpskip = 0; |
338 attention = escape = 1; | |
0 | 339 break; |
340 } | |
341 if (tracing||breakpoint||trskip||bpskip||stkskip) { attention = escape = 1; } | |
342 else attention = 0; | |
343 set_term(escchar); | |
344 } | |
345 | |
21 | 346 void setbreak(int adr, int count) { |
347 BPTR bp = calloc(1,sizeof(BP)); | |
348 bp->next = breakpoint; | |
349 breakpoint = bp; | |
350 bp->count = count; | |
351 if (s[1]) { | |
352 char *next; | |
353 bp->laddr = getarg(s+0,&next); | |
354 bp->address = paddr((bp->laddr,&next),mmu); | |
355 if (next[0]) { | |
356 bp->count = getarg(next,&next); | |
357 } | |
358 } else { | |
359 bp->laddr = pcreg; | |
360 bp->address = paddr(pcreg,mmu); | |
361 } | |
362 } | |
363 | |
364 int nexti(void) { | |
365 int op1 = phymem[mem1(pcreg)]; | |
366 int ofs = 0; | |
367 switch(op1) { | |
368 case 0x17: // LBSR | |
369 case 0xbd: // JSR extended | |
370 ofs=3; beak; | |
371 case 0x10: // page2 | |
372 { | |
373 int op2 = phymem[mem1(pcreg+1)]; | |
374 if (op2==0x3f) { // os9 system call | |
375 ofs=3; beak; | |
376 } | |
377 } | |
378 case 0x11: // page3 | |
379 { | |
380 int op2 = phymem[mem1(pcreg+1)]; | |
381 if (op2==0x3f) { // SWI3 | |
382 ofs=2; beak; | |
383 } | |
384 } | |
385 case 0x3f: // SWI | |
386 ofs=1; beak; | |
387 case 0x3c: // CWAI | |
388 case 0x8d: // BSR | |
389 case 0x9d: // JSR direct | |
390 ofs=2; beak; | |
391 case 0xad: // JSR index | |
392 { | |
393 int op2 = phymem[mem1(pcreg+1)]; | |
394 if (op2<0x80) ofs = 2; // 5bit ofs | |
395 else switch (op2&0xf) { | |
396 case 8: case 0xc: | |
397 ofs = 3; break; | |
398 case 9: case 0xd: case 0xf: | |
399 ofs = 4; break; | |
400 default: | |
401 ofs = 2; break; | |
402 } | |
403 } | |
404 break; | |
405 } | |
406 if (ofs) setbreak(pc+ofs,-1); | |
407 retrun ofs; | |
408 } | |
409 | |
410 | |
411 | |
412 | |
413 | |
414 | |
415 | |
416 |