view 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 source

/* 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);
}