comparison io.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 84b28178c82f
children 10e33568b38a
comparison
equal deleted inserted replaced
19:84b28178c82f 20:49fac9474858
82 #define SECSIZE 256 82 #define SECSIZE 256
83 83
84 84
85 int timer = 1; 85 int timer = 1;
86 struct termios termsetting; 86 struct termios termsetting;
87 87 struct termios newterm;
88 struct itimerval timercontrol;
89
90 int tflags;
88 int xmstat; /* 0= no XMODEM transfer, 1=send, 2=receiver */ 91 int xmstat; /* 0= no XMODEM transfer, 1=send, 2=receiver */
89 unsigned char xmbuf[132]; 92 unsigned char xmbuf[132];
90 int xidx; 93 int xidx;
91 int acknak; 94 int acknak;
92 int rcvdnak; 95 int rcvdnak;
93 int blocknum; 96 int blocknum;
94 97
95 FILE *logfile;
96 FILE *infile; 98 FILE *infile;
97 FILE *xfile; 99 FILE *xfile;
100 FILE *logfile;
98 FILE *disk[] = {0,0}; 101 FILE *disk[] = {0,0};
99 102
100 extern void hexadump( unsigned char *b, int l, int loc, int w);
101 extern int disasm(int,int);
102 #ifdef USE_MMU 103 #ifdef USE_MMU
103 extern char *prog ; // for disass 104 extern char *prog ; // for disass
104 extern Byte * mem0(Byte *iphymem, Word adr, Byte *immu) ; 105 extern Byte * mem0(Byte *iphymem, Word adr, Byte *immu) ;
105 #endif 106 #endif
106 107
108 extern int bpskip ;
109 extern int stkskip ;
110 extern FILE *logfile;
107 111
108 void do_timer(int,int); 112 void do_timer(int,int);
109 void do_disk(int,int); 113 void do_disk(int,int);
110 void do_mmu(int,int); 114 void do_mmu(int,int);
111 115
260 } else if (a >= 0x10+(IOPAGE&0x1ff)) { /* mmu */ 264 } else if (a >= 0x10+(IOPAGE&0x1ff)) { /* mmu */
261 do_mmu(a,c); 265 do_mmu(a,c);
262 } 266 }
263 } 267 }
264 268
265 void restore_term(void) {
266 tcsetattr(0, TCSAFLUSH, &termsetting);
267 fcntl(0, F_SETFL, tflags);
268 signal(SIGALRM, SIG_IGN);
269 }
270
271 void do_exit(void) {
272 restore_term();
273 exit(0);
274 }
275 269
276 void do_timer(int a, int c) { 270 void do_timer(int a, int c) {
277 struct itimerval timercontrol; 271 struct itimerval timercontrol;
278 if (a==0x30+(IOPAGE&0x1ff) && c==0x8f) { 272 if (a==0x30+(IOPAGE&0x1ff) && c==0x8f) {
279 timercontrol.it_interval.tv_sec = 0; 273 timercontrol.it_interval.tv_sec = 0;
334 } 328 }
335 mem[(IOPAGE&0xfe00)+a] = c; // other register such as 0xffa0-0xffaf 329 mem[(IOPAGE&0xfe00)+a] = c; // other register such as 0xffa0-0xffaf
336 #endif 330 #endif
337 } 331 }
338 332
339 typedef struct bp {
340 int address;
341 int count;
342 struct bp *next;
343 } BP, *BPTR;
344
345 BPTR breakpoint = 0;
346 int bpskip = 0;
347 int trskip = 0;
348 int stkskip = 0;
349
350 int getarg(char *buf, char** next) {
351 return strtol(buf,(char**)next,0);
352 }
353
354 void printhelp(void)
355 {
356 printf(
357 " s [count] one step trace\n"
358 " n step over\n"
359 " f finish this call (until stack pop)\n"
360 " b [adr] set break point\n"
361 " l break point list\n"
362 " d [n] delte break point list\n"
363 " c [count] continue;\n"
364 " x [adr] dump\n"
365 #ifdef USE_MMU
366 " xp [adr] dump physical memory\n"
367 #endif
368 " xi [adr] disassemble\n"
369 " 0 file disk drive 0 image\n"
370 " 1 file disk drive 1 image\n"
371 " L file start log to file\n"
372 " S file set input file\n"
373 " X exit\n"
374 " q exit\n"
375 " U file upload from srecord file \n"
376 " D file download to srecord file \n"
377 " R do reset\n"
378 " h,? print this\n"
379 );
380 }
381
382 void do_escape(void) {
383 char s[80];
384 int adr,skip;
385 if (bpskip) { // skip unbreak instruction
386 bpskip--;
387 for(BPTR b = breakpoint; b ; b=b->next) {
388 if (pcreg==b->address) {
389 if (b->count) b->count--;
390 if (b->count==0) {
391 goto restart0;
392 }
393 }
394 }
395 return;
396 }
397 if (stkskip) { // skip until return
398 if (sreg < stkskip ) return;
399 }
400 restart0:
401 stkskip = 0;
402 restore_term();
403 #ifdef USE_MMU
404 Byte *phyadr = mem0(phymem,pcreg,mmu);
405 prog = (char*)phyadr - pcreg;
406 #endif
407 do_trace(stdout);
408 if (trskip>1) { // show trace and step
409 trskip--;
410 set_term(escchar);
411 return;
412 }
413 restart:
414 printf("v09>");
415 fgets(s, 80, stdin);
416 if (s[0])
417 s[strlen(s) - 1] = 0;
418 switch (s[0]) {
419 case 's': // one step trace
420 trskip = 1;
421 if (s[1]) {
422 trskip = getarg(s+1,0);
423 }
424 bpskip = 0;
425 attention = escape = 1;
426 break;
427 case 'n': // step over
428 stkskip = sreg;
429 attention = escape = 1;
430 break;
431 case 'f': // finish this call (until stack pop)
432 stkskip = sreg + 2;
433 attention = escape = 1;
434 break;
435 case 'b': // set break point
436 {
437 BPTR bp = calloc(1,sizeof(BP));
438 bp->next = breakpoint;
439 breakpoint = bp;
440 bp->count = 1;
441 if (s[1]) {
442 char *next;
443 bp->address = getarg(s+1,&next);
444 if (next[0]) {
445 bp->count = getarg(next,&next);
446 }
447 } else {
448 bp->address = pcreg;
449 }
450 }
451 bpskip = -1;
452 goto restart;
453 case 'l': // break point list
454 for(BPTR bp = breakpoint; bp ; bp = bp->next) {
455 printf("%x %i\n", bp->address, bp->count);
456 }
457 goto restart;
458 case 'd': // delte break point list
459 if (s[1]) {
460 int trskip = getarg(s+1,0);
461 BPTR *prev = &breakpoint;
462 for(BPTR bp = breakpoint; bp ; bp = bp->next) {
463 if (trskip-- == 0) {
464 if (bp) {
465 *prev = bp->next;
466 }
467 break;
468 }
469 prev = &bp->next;
470 }
471 }
472 goto restart;
473 case 'c': // continue;
474 bpskip = -1;
475 attention = escape = 1;
476 if (s[1]) {
477 bpskip = getarg(s+1,0);
478 }
479 break;
480 case 'x': // dump
481 skip = 1;
482 if (s[1]=='i') skip=2;
483 if (s[1]=='p') skip=2;
484 if (s[skip]) {
485 char *next;
486 int adr = getarg(s+skip,&next);
487 int len = 32;
488 if (next[0]) {
489 len = getarg(next,&next);
490 }
491 if (skip==2 && s[1]=='i') {
492 Word end = adr + len;
493 while(adr < end) {
494 #ifdef USE_MMU
495 Byte *phyadr = mem0(phymem,adr,mmu);
496 prog = (char*)phyadr - adr ;
497 if (phyadr > phymem+memsize) goto restart;
498 #endif
499 int len = adr+16<end? 16 : end-adr -1 ;
500 adr = disasm(adr,adr+len);
501 }
502 } else {
503 #ifdef USE_MMU
504 for(int i=0; len > 0 ; i+=16, len-=16) {
505 if (skip==2 && s[1]=='p') {
506 if (adr+i > memsize) goto restart;
507 hexadump(phymem+adr+i,len>16?16:len,adr+i,16);
508 } else {
509 Byte *phyadr = mem0(phymem,adr+i,mmu);
510 if (phyadr > phymem+memsize) goto restart;
511 hexadump(phyadr,len>16?16:len,adr+i,16);
512 }
513 }
514 #else
515 for(int i=0; len > 0 ; i+=16, len-=16) {
516 hexadump(mem+adr+i,len>16?16:len,adr+i,16);
517 }
518 #endif
519 }
520 } else
521 disasm(pcreg,pcreg+32);
522 goto restart;
523 case 'L':
524 if (logfile)
525 fclose(logfile);
526 logfile = 0;
527 if (s[1]) {
528 int i=1; while(s[i]==' ') i++;
529 logfile = fopen(s + i, "w");
530 }
531 break;
532 case 'S':
533 if (infile)
534 fclose(infile);
535 infile = 0;
536 if (s[1]) {
537 int i=1; while(s[i]==' ') i++;
538 infile = fopen(s + i, "r");
539 }
540 break;
541 case 'h':
542 case '?':
543 printhelp();
544 goto restart;
545 case 'X':
546 case 'q':
547 if (!xmstat)
548 do_exit();
549 else {
550 xmstat = 0;
551 fclose(xfile);
552 xfile = 0;
553 }
554 break;
555 case '0':
556 case '1':
557 { FILE **drv = &disk[ s[0]-'0'] ;
558 if (*drv)
559 fclose(*drv);
560 *drv = 0;
561 if (s[1]) {
562 int i=1; while(s[i]==' ') i++;
563 *drv = fopen(s + i, "r+b");
564 if ( *drv == 0 ) { printf("can't open %s\n", &s[i]); }
565 }
566 }
567 break;
568 case 'U':
569 if (xfile)
570 fclose(xfile);
571 xfile = 0;
572 if (s[1]) {
573 int i=1; while(s[i]==' ') i++;
574 xfile = fopen(s + i, "rb");
575 if ( xfile == 0 ) { printf("can't open %s\n", &s[i]); }
576 }
577 if (xfile)
578 xmstat = 1;
579 else
580 xmstat = 0;
581 xidx = 0;
582 acknak = 21;
583 rcvdnak = EOF;
584 blocknum = 1;
585 break;
586 case 'D':
587 if (xfile)
588 fclose(xfile);
589 xfile = 0;
590 if (s[1]) {
591 int i=1; while(s[i]==' ') i++;
592 xfile = fopen(s + i, "wb");
593 if ( xfile == 0 ) { printf("can't open %s\n", &s[i]); }
594 }
595 if (xfile)
596 xmstat = 2;
597 else
598 xmstat = 0;
599 xidx = 0;
600 acknak = 21;
601 blocknum = 1;
602 break;
603 case 'R':
604 pcreg = (mem[0xfffe] << 8) + mem[0xffff];
605 bpskip = 0;
606 attention = escape = 1;
607 break;
608 }
609 if (tracing||breakpoint||trskip||bpskip||stkskip) { attention = escape = 1; }
610 else attention = 0;
611 set_term(escchar);
612 }
613
614 void timehandler(int sig) { 333 void timehandler(int sig) {
615 attention = 1; 334 attention = 1;
616 irq = 2; 335 irq = 2;
617 signal(SIGALRM, timehandler); 336 signal(SIGALRM, timehandler);
618 } 337 }
622 attention = 1; 341 attention = 1;
623 bpskip = 0; 342 bpskip = 0;
624 stkskip = 0; 343 stkskip = 0;
625 } 344 }
626 345
346 void init_term(void) {
347 tcgetattr(0, &termsetting);
348 tflags = fcntl(0, F_GETFL, 0);
349 }
350
627 void set_term(char c) { 351 void set_term(char c) {
628 struct termios newterm;
629 struct itimerval timercontrol;
630 signal(SIGQUIT, SIG_IGN); 352 signal(SIGQUIT, SIG_IGN);
631 signal(SIGTSTP, SIG_IGN); 353 signal(SIGTSTP, SIG_IGN);
632 signal(SIGINT, handler); 354 signal(SIGINT, handler);
633 signal(SIGUSR1, handler); 355 signal(SIGUSR1, handler);
634 tcgetattr(0, &termsetting);
635 newterm = termsetting; 356 newterm = termsetting;
636 newterm.c_iflag = newterm.c_iflag & ~INLCR & ~ICRNL; 357 newterm.c_iflag = newterm.c_iflag & ~INLCR & ~ICRNL;
637 newterm.c_lflag = newterm.c_lflag & ~ECHO & ~ICANON; 358 newterm.c_lflag = newterm.c_lflag & ~ECHO & ~ICANON;
638 newterm.c_cc[VTIME] = 0; 359 newterm.c_cc[VTIME] = 0;
639 newterm.c_cc[VMIN] = 1; 360 newterm.c_cc[VMIN] = 1;
640 newterm.c_cc[VINTR] = escchar; 361 newterm.c_cc[VINTR] = escchar;
641 tcsetattr(0, TCSAFLUSH, &newterm); 362 tcsetattr(0, TCSAFLUSH, &newterm);
642 tflags = fcntl(0, F_GETFL, 0);
643 fcntl(0, F_SETFL, tflags | O_NDELAY); /* Make input from stdin non-blocking */ 363 fcntl(0, F_SETFL, tflags | O_NDELAY); /* Make input from stdin non-blocking */
644 signal(SIGALRM, timehandler); 364 signal(SIGALRM, timehandler);
645 timercontrol.it_interval.tv_sec = 0; 365 timercontrol.it_interval.tv_sec = 0;
646 timercontrol.it_interval.tv_usec = 20000; 366 timercontrol.it_interval.tv_usec = 20000;
647 timercontrol.it_value.tv_sec = 0; 367 timercontrol.it_value.tv_sec = 0;
648 timercontrol.it_value.tv_usec = 20000; 368 timercontrol.it_value.tv_usec = 20000;
649 if (timer) 369 if (timer)
650 setitimer(ITIMER_REAL, &timercontrol, NULL); 370 setitimer(ITIMER_REAL, &timercontrol, NULL);
651 } 371 }
372
373 void restore_term(void) {
374 tcsetattr(0, TCSAFLUSH, &termsetting);
375 fcntl(0, F_SETFL, tflags);
376 signal(SIGALRM, SIG_IGN);
377 }
378
379
380
381