Mercurial > hg > Members > kono > os9 > sbc09
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 |