Mercurial > hg > Members > kono > os9 > sbc09
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/trace.c Mon Jul 09 09:29:33 2018 +0900 @@ -0,0 +1,328 @@ +/* 6808 Simulator V092 + * + * tracer + +*/ + +#include<stdio.h> +#include<stdlib.h> +#include<ctype.h> +#include<signal.h> +#include<sys/time.h> + +#include <unistd.h> +#include <fcntl.h> +#include <string.h> +#include <time.h> + +#ifdef USE_TERMIOS +#include <termios.h> +#endif + +#define engine extern +#include "v09.h" + +struct termios termsetting; + +int xmstat; /* 0= no XMODEM transfer, 1=send, 2=receiver */ +unsigned char xmbuf[132]; +int xidx; +int acknak; +int rcvdnak; +int blocknum; + +extern FILE *logfile; +extern FILE *infile; +extern FILE *xfile; +extern FILE *disk[]; + +extern void hexadump( unsigned char *b, int l, int loc, int w); +extern int disasm(int,int); +extern void restore_term(void) ; + +#ifdef USE_MMU +extern char *prog ; // for disass +extern Byte * mem0(Byte *iphymem, Word adr, Byte *immu) ; +#endif + +void do_exit(void) { + restore_term(); + exit(0); +} + + +typedef struct bp { + int address; + int count; + struct bp *next; +} BP, *BPTR; + +BPTR breakpoint = 0; +int bpskip = 0; +int trskip = 0; +int stkskip = 0; + +int getarg(char *buf, char** next) { + return strtol(buf,(char**)next,0); +} + +void printhelp(void) +{ + printf( + " s [count] one step trace\n" + " n step over\n" + " f finish this call (until stack pop)\n" + " b [adr] set break point\n" + " l break point list\n" + " d [n] delte break point list\n" + " c [count] continue;\n" + " x [adr] dump\n" +#ifdef USE_MMU + " xp [adr] dump physical memory\n" +#endif + " xi [adr] disassemble\n" + " 0 file disk drive 0 image\n" + " 1 file disk drive 1 image\n" + " L file start log to file\n" + " S file set input file\n" + " X exit\n" + " q exit\n" + " U file upload from srecord file \n" + " D file download to srecord file \n" + " R do reset\n" + " h,? print this\n" + ); +} + +void do_escape(void) { + char s[80]; + int adr,skip; + if (bpskip) { // skip unbreak instruction + bpskip--; + for(BPTR b = breakpoint; b ; b=b->next) { + if (pcreg==b->address) { + if (b->count) b->count--; + if (b->count==0) { + goto restart0; + } + } + } + return; + } + if (stkskip) { // skip until return + if (sreg < stkskip ) return; + } +restart0: + stkskip = 0; + restore_term(); +#ifdef USE_MMU + Byte *phyadr = mem0(phymem,pcreg,mmu); + prog = (char*)phyadr - pcreg; +#endif + do_trace(stdout); + if (trskip>1) { // show trace and step + trskip--; + set_term(escchar); + return; + } +restart: + printf("v09>"); + fgets(s, 80, stdin); + if (s[0]) + s[strlen(s) - 1] = 0; + switch (s[0]) { + case 's': // one step trace + trskip = 1; + if (s[1]) { + trskip = getarg(s+1,0); + } + bpskip = 0; + attention = escape = 1; + break; + case 'n': // step over + stkskip = sreg; + attention = escape = 1; + break; + case 'f': // finish this call (until stack pop) + stkskip = sreg + 2; + attention = escape = 1; + break; + case 'b': // set break point + { + BPTR bp = calloc(1,sizeof(BP)); + bp->next = breakpoint; + breakpoint = bp; + bp->count = 1; + if (s[1]) { + char *next; + bp->address = getarg(s+1,&next); + if (next[0]) { + bp->count = getarg(next,&next); + } + } else { + bp->address = pcreg; + } + } + bpskip = -1; + goto restart; + case 'l': // break point list + for(BPTR bp = breakpoint; bp ; bp = bp->next) { + printf("%x %i\n", bp->address, bp->count); + } + goto restart; + case 'd': // delte break point list + if (s[1]) { + int trskip = getarg(s+1,0); + BPTR *prev = &breakpoint; + for(BPTR bp = breakpoint; bp ; bp = bp->next) { + if (trskip-- == 0) { + if (bp) { + *prev = bp->next; + } + break; + } + prev = &bp->next; + } + } + goto restart; + case 'c': // continue; + bpskip = -1; + attention = escape = 1; + if (s[1]) { + bpskip = getarg(s+1,0); + } + break; + case 'x': // dump + skip = 1; + if (s[1]=='i') skip=2; + if (s[1]=='p') skip=2; + if (s[skip]) { + char *next; + int adr = getarg(s+skip,&next); + int len = 32; + if (next[0]) { + len = getarg(next,&next); + } + if (skip==2 && s[1]=='i') { + Word end = adr + len; + while(adr < end) { +#ifdef USE_MMU + Byte *phyadr = mem0(phymem,adr,mmu); + prog = (char*)phyadr - adr ; + if (phyadr > phymem+memsize) goto restart; +#endif + int len = adr+16<end? 16 : end-adr -1 ; + adr = disasm(adr,adr+len); + } + } else { +#ifdef USE_MMU + for(int i=0; len > 0 ; i+=16, len-=16) { + if (skip==2 && s[1]=='p') { + if (adr+i > memsize) goto restart; + hexadump(phymem+adr+i,len>16?16:len,adr+i,16); + } else { + Byte *phyadr = mem0(phymem,adr+i,mmu); + if (phyadr > phymem+memsize) goto restart; + hexadump(phyadr,len>16?16:len,adr+i,16); + } + } +#else + for(int i=0; len > 0 ; i+=16, len-=16) { + hexadump(mem+adr+i,len>16?16:len,adr+i,16); + } +#endif + } + } else + disasm(pcreg,pcreg+32); + goto restart; + case 'L': + if (logfile) + fclose(logfile); + logfile = 0; + if (s[1]) { + int i=1; while(s[i]==' ') i++; + logfile = fopen(s + i, "w"); + } + break; + case 'S': + if (infile) + fclose(infile); + infile = 0; + if (s[1]) { + int i=1; while(s[i]==' ') i++; + infile = fopen(s + i, "r"); + } + break; + case 'h': + case '?': + printhelp(); + goto restart; + case 'X': + case 'q': + if (!xmstat) + do_exit(); + else { + xmstat = 0; + fclose(xfile); + xfile = 0; + } + break; + case '0': + case '1': + { FILE **drv = &disk[ s[0]-'0'] ; + if (*drv) + fclose(*drv); + *drv = 0; + if (s[1]) { + int i=1; while(s[i]==' ') i++; + *drv = fopen(s + i, "r+b"); + if ( *drv == 0 ) { printf("can't open %s\n", &s[i]); } + } + } + break; + case 'U': + if (xfile) + fclose(xfile); + xfile = 0; + if (s[1]) { + int i=1; while(s[i]==' ') i++; + xfile = fopen(s + i, "rb"); + if ( xfile == 0 ) { printf("can't open %s\n", &s[i]); } + } + if (xfile) + xmstat = 1; + else + xmstat = 0; + xidx = 0; + acknak = 21; + rcvdnak = EOF; + blocknum = 1; + break; + case 'D': + if (xfile) + fclose(xfile); + xfile = 0; + if (s[1]) { + int i=1; while(s[i]==' ') i++; + xfile = fopen(s + i, "wb"); + if ( xfile == 0 ) { printf("can't open %s\n", &s[i]); } + } + if (xfile) + xmstat = 2; + else + xmstat = 0; + xidx = 0; + acknak = 21; + blocknum = 1; + break; + case 'R': + pcreg = (mem[0xfffe] << 8) + mem[0xffff]; + bpskip = 0; + attention = escape = 1; + break; + } + if (tracing||breakpoint||trskip||bpskip||stkskip) { attention = escape = 1; } + else attention = 0; + set_term(escchar); +} +