Mercurial > hg > Members > kono > os9 > sbc09
annotate trace.c @ 28:d34482fd6945
fix ui
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 11 Jul 2018 09:03:54 +0900 |
parents | 7104ad38bed3 |
children | 3c14d647bb51 |
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" | |
28 | 79 " b [adr] set break point (on current physical addreaa)\n" |
0 | 80 " l break point list\n" |
81 " d [n] delte break point list\n" | |
82 " c [count] continue;\n" | |
28 | 83 " x [adr] [count[ dump\n" |
9 | 84 #ifdef USE_MMU |
28 | 85 " xp page [adr] dump physical memory\n" |
9 | 86 #endif |
28 | 87 " xi [adr] [count[ 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) ; | |
22 | 103 int nexti(void); |
21 | 104 |
0 | 105 void do_escape(void) { |
106 char s[80]; | |
28 | 107 int adr,page; |
0 | 108 if (bpskip) { // skip unbreak instruction |
109 bpskip--; | |
24 | 110 int ppc = paddr(pcreg,mmu); |
21 | 111 BPTR *prev = &breakpoint; |
22 | 112 for(BPTR b = breakpoint; b ; prev=&b->next, b=b->next ) { |
24 | 113 if (ppc==b->address /* || pcreg==b->laddr */) { |
21 | 114 if (b->count==-1) { // temporaly break point |
115 BPTR next = b->next; | |
116 free(b); | |
22 | 117 *prev = next; |
21 | 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>"); | |
28 | 146 fgets(s, sizeof(s)-1, stdin); |
147 s[strlen(s)-1] = 0; // chop | |
0 | 148 switch (s[0]) { |
28 | 149 default: |
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; | |
23 | 171 int adr = getarg(s+1,&next); |
21 | 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; | |
28 | 181 case 'B': // break point list |
0 | 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; | |
22 | 194 for(BPTR bp = breakpoint; bp ; prev=&bp->next, bp = bp->next) { |
0 | 195 if (trskip-- == 0) { |
22 | 196 BPTR next = bp->next; |
21 | 197 free(bp); |
22 | 198 *prev = 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; | |
28 | 212 case 'x': // dump |
213 { char *next = s+1; | |
214 if (s[1]=='i') next=s+2; | |
215 else if (s[1]=='p') { | |
216 next = s+2; | |
217 if (next[0]) { | |
218 page = getarg(next,&next); | |
219 } | |
220 } | |
221 if (next[0]) { | |
222 int adr = getarg(next,&next); | |
0 | 223 int len = 32; |
224 if (next[0]) { | |
225 len = getarg(next,&next); | |
226 } | |
28 | 227 if (s[1]=='i') { |
12
111e5defb8ab
boot is called, rti failed
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
11
diff
changeset
|
228 Word end = adr + len; |
111e5defb8ab
boot is called, rti failed
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
11
diff
changeset
|
229 while(adr < end) { |
9 | 230 #ifdef USE_MMU |
12
111e5defb8ab
boot is called, rti failed
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
11
diff
changeset
|
231 Byte *phyadr = mem0(phymem,adr,mmu); |
111e5defb8ab
boot is called, rti failed
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
11
diff
changeset
|
232 prog = (char*)phyadr - adr ; |
111e5defb8ab
boot is called, rti failed
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
11
diff
changeset
|
233 if (phyadr > phymem+memsize) goto restart; |
9 | 234 #endif |
12
111e5defb8ab
boot is called, rti failed
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
11
diff
changeset
|
235 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
|
236 adr = disasm(adr,adr+len); |
9 | 237 } |
0 | 238 } else { |
9 | 239 #ifdef USE_MMU |
240 for(int i=0; len > 0 ; i+=16, len-=16) { | |
28 | 241 if (s[1]=='p') { |
242 int phy = page * 0x2000 + adr + i; | |
243 if (phy > rommemsize) goto restart; | |
244 hexadump(phymem+phy,len>16?16:len,adr+i,16); | |
9 | 245 } else { |
11 | 246 Byte *phyadr = mem0(phymem,adr+i,mmu); |
28 | 247 if (phyadr > phymem+rommemsize) goto restart; |
9 | 248 hexadump(phyadr,len>16?16:len,adr+i,16); |
249 } | |
250 } | |
251 #else | |
0 | 252 for(int i=0; len > 0 ; i+=16, len-=16) { |
253 hexadump(mem+adr+i,len>16?16:len,adr+i,16); | |
254 } | |
9 | 255 #endif |
0 | 256 } |
257 } else | |
258 disasm(pcreg,pcreg+32); | |
259 goto restart; | |
28 | 260 } |
0 | 261 case 'L': |
262 if (logfile) | |
263 fclose(logfile); | |
264 logfile = 0; | |
265 if (s[1]) { | |
1 | 266 int i=1; while(s[i]==' ') i++; |
267 logfile = fopen(s + i, "w"); | |
0 | 268 } |
269 break; | |
270 case 'S': | |
271 if (infile) | |
272 fclose(infile); | |
273 infile = 0; | |
274 if (s[1]) { | |
1 | 275 int i=1; while(s[i]==' ') i++; |
276 infile = fopen(s + i, "r"); | |
0 | 277 } |
278 break; | |
279 case 'h': | |
280 case '?': | |
281 printhelp(); | |
282 goto restart; | |
283 case 'X': | |
284 case 'q': | |
285 if (!xmstat) | |
286 do_exit(); | |
287 else { | |
288 xmstat = 0; | |
289 fclose(xfile); | |
290 xfile = 0; | |
291 } | |
292 break; | |
1 | 293 case '0': |
294 case '1': | |
295 { FILE **drv = &disk[ s[0]-'0'] ; | |
296 if (*drv) | |
297 fclose(*drv); | |
298 *drv = 0; | |
299 if (s[1]) { | |
300 int i=1; while(s[i]==' ') i++; | |
301 *drv = fopen(s + i, "r+b"); | |
302 if ( *drv == 0 ) { printf("can't open %s\n", &s[i]); } | |
303 } | |
304 } | |
305 break; | |
0 | 306 case 'U': |
307 if (xfile) | |
308 fclose(xfile); | |
309 xfile = 0; | |
310 if (s[1]) { | |
1 | 311 int i=1; while(s[i]==' ') i++; |
312 xfile = fopen(s + i, "rb"); | |
313 if ( xfile == 0 ) { printf("can't open %s\n", &s[i]); } | |
0 | 314 } |
315 if (xfile) | |
316 xmstat = 1; | |
317 else | |
318 xmstat = 0; | |
319 xidx = 0; | |
320 acknak = 21; | |
321 rcvdnak = EOF; | |
322 blocknum = 1; | |
323 break; | |
324 case 'D': | |
325 if (xfile) | |
326 fclose(xfile); | |
327 xfile = 0; | |
328 if (s[1]) { | |
1 | 329 int i=1; while(s[i]==' ') i++; |
330 xfile = fopen(s + i, "wb"); | |
331 if ( xfile == 0 ) { printf("can't open %s\n", &s[i]); } | |
0 | 332 } |
333 if (xfile) | |
334 xmstat = 2; | |
335 else | |
336 xmstat = 0; | |
337 xidx = 0; | |
338 acknak = 21; | |
339 blocknum = 1; | |
340 break; | |
341 case 'R': | |
342 pcreg = (mem[0xfffe] << 8) + mem[0xffff]; | |
13 | 343 bpskip = 0; |
24 | 344 #ifdef USE_MMU |
345 mmu = &mem[0xffa0]; | |
28 | 346 mem[0xffa7]=0x3f; |
24 | 347 #endif |
13 | 348 attention = escape = 1; |
0 | 349 break; |
350 } | |
351 if (tracing||breakpoint||trskip||bpskip||stkskip) { attention = escape = 1; } | |
352 else attention = 0; | |
353 set_term(escchar); | |
354 } | |
355 | |
21 | 356 void setbreak(int adr, int count) { |
357 BPTR bp = calloc(1,sizeof(BP)); | |
358 bp->next = breakpoint; | |
359 breakpoint = bp; | |
360 bp->count = count; | |
22 | 361 bp->laddr = adr; |
362 bp->address = paddr(adr,mmu); | |
21 | 363 } |
364 | |
365 int nexti(void) { | |
22 | 366 #ifdef USE_MMU |
367 int op1 = *mem0(phymem,pcreg,mmu); | |
368 int op2 = *mem0(phymem,pcreg+1,mmu); | |
369 #else | |
370 int op1 = mem[pcreg]; | |
371 int op2 = mem[pcreg+1]; | |
372 #endif | |
21 | 373 int ofs = 0; |
374 switch(op1) { | |
375 case 0x17: // LBSR | |
376 case 0xbd: // JSR extended | |
22 | 377 ofs=3; break; |
21 | 378 case 0x10: // page2 |
379 { | |
380 if (op2==0x3f) { // os9 system call | |
22 | 381 ofs=3; break; |
21 | 382 } |
383 } | |
384 case 0x11: // page3 | |
385 { | |
386 if (op2==0x3f) { // SWI3 | |
22 | 387 ofs=2; break; |
21 | 388 } |
389 } | |
390 case 0x3f: // SWI | |
22 | 391 ofs=1; break; |
21 | 392 case 0x3c: // CWAI |
393 case 0x8d: // BSR | |
394 case 0x9d: // JSR direct | |
22 | 395 ofs=2; break; |
21 | 396 case 0xad: // JSR index |
397 { | |
398 if (op2<0x80) ofs = 2; // 5bit ofs | |
399 else switch (op2&0xf) { | |
400 case 8: case 0xc: | |
401 ofs = 3; break; | |
402 case 9: case 0xd: case 0xf: | |
403 ofs = 4; break; | |
404 default: | |
405 ofs = 2; break; | |
406 } | |
407 } | |
408 break; | |
409 } | |
22 | 410 if (ofs) setbreak(pcreg+ofs,-1); |
411 return ofs; | |
21 | 412 } |
413 | |
414 | |
415 | |
416 | |
417 | |
418 | |
419 | |
420 |