Martins ddd changes
[fw/sdcc] / debugger / mcs51 / simi.c
index 12430d1e625a5bbc4ad54d7c80854332f34f952d..0edc1e98d58d19d55993286b6d37a86ff8ff1f73 100644 (file)
 FILE *simin ; /* stream for simulator input */
 FILE *simout; /* stream for simulator output */
 
-int sock ; /* socket descriptor to comm with simulator */
+int sock = -1; /* socket descriptor to comm with simulator */
 pid_t simPid;
 static char simibuff[MAX_SIM_BUFF];    /* sim buffer       */
 static char regBuff[MAX_SIM_BUFF];
 static char *sbp = simibuff;           /* simulator buffer pointer */
 extern char **environ;
 char simactive = 0;
+
+static memcache_t memCache[NMEM_CACHE];
+
 /*-----------------------------------------------------------------*/
-/* readSim - reads one character into simulator buffer             */
+/* get data from  memory cache/ load cache from simulator          */
 /*-----------------------------------------------------------------*/
-void readSim(int resetp)
+static char *getMemCache(unsigned int addr,int cachenum, int size)
 {
-    int ch ;
-    /* if reset required then point to beginning of buffer */
-    if (resetp)
-       sbp = simibuff;
-    
-    Dprintf(D_simi, ("readSim: reading from sim["));
-
-    while ((ch = fgetc(simin))) {
-
-#ifdef SDCDB_DEBUG     
- if (D_simi) {
-       fputc(ch,stdout);
- }
-#endif
-
-       *sbp++ = ch;    
+    char *resp, *buf;
+    unsigned int laddr;
+    memcache_t *cache = &memCache[cachenum];
+
+    if ( cache->size <=   0 ||
+         cache->addr > addr ||
+         cache->addr + cache->size < addr + size )
+    {
+        if ( cachenum == IMEM_CACHE )
+        {
+            sendSim("di 0x0 0xff\n");
+        }
+        else
+        {
+            laddr = addr & 0xffffffc0;
+            sprintf(cache->buffer,"dx 0x%x 0x%x\n",laddr,laddr+0xff );
+            sendSim(cache->buffer);
+        }
+        waitForSim(100,NULL);
+        resp = simResponse();
+        cache->addr = strtol(resp,0,0);
+        buf = cache->buffer;
+        cache->size = 0;
+        while ( *resp && *(resp+1) && *(resp+2))
+        {
+            /* cache is a stringbuffer with ascii data like
+               " 00 00 00 00 00 00 00 00"
+            */
+            resp += 2;
+            laddr = 0;
+            /* skip thru the address part */
+            while (isxdigit(*resp)) resp++;
+            while ( *resp && *resp != '\n')
+            {
+                if ( laddr < 24 )
+                {
+                    laddr++ ;
+                    *buf++ = *resp ;
+                }
+                resp++;
+            }
+            resp++ ;
+            cache->size += 8;
+        }
+        *buf = '\0';
+        if ( cache->addr > addr ||
+             cache->addr + cache->size < addr + size )
+            return NULL;
     }
+    return cache->buffer + (addr - cache->addr)*3;
+}
 
-    Dprintf(D_simi, ("] end readSim\n"));
-
-    *sbp = '\0';
+/*-----------------------------------------------------------------*/
+/* invalidate memory cache                                         */
+/*-----------------------------------------------------------------*/
+static void invalidateCache( int cachenum )
+{
+    memCache[cachenum].size = 0;  
 }
 
 /*-----------------------------------------------------------------*/
 /* waitForSim - wait till simulator is done its job                */
 /*-----------------------------------------------------------------*/
-void waitForSim()
+void waitForSim(int timeout_ms, char *expect)
 {
-    readSim(TRUE);
+  int i=0;
+  int ch;
+
+Dprintf(D_simi, ("simi: waitForSim start(%d)\n", timeout_ms));
+    sbp = simibuff;
+
+    while ((ch = fgetc(simin)) > 0 ) {
+      *sbp++ = ch;
+    }
+    *sbp = 0;
+    Dprintf(D_simi, ("waitForSim(%d) got[%s]\n", timeout_ms, simibuff));
+
 }
 
 /*-----------------------------------------------------------------*/
@@ -88,25 +139,25 @@ void openSimulator (char **args, int nargs)
     struct sockaddr_in sin;     
     int retry = 0;
     int i ;
-    char *simargs[32] = { "s51","-P","-r 9756", NULL };
-    
-    /* create the arguments */
-    for ( i = 0 ; i < nargs ;i++) {
-       simargs[i+3] = args[i];       
-    }
-    simargs[i+3]= NULL;
+ Dprintf(D_simi, ("simi: openSimulator\n"));
 
+    invalidateCache(XMEM_CACHE);
+    invalidateCache(IMEM_CACHE);
     /* fork and start the simulator as a subprocess */
     if ((simPid = fork())) {
-      Dprintf(D_simi, ("simulator pid %d\n",(int) simPid));
+      Dprintf(D_simi, ("simi: simulator pid %d\n",(int) simPid));
     }
     else {
-       
-       /* we are in the child process : start the simulator */
-       if (execvp("s51",simargs) < 0) {
-           perror("cannot exec simulator");
-           exit(1);
-       }       
+      /* we are in the child process : start the simulator */
+      signal(SIGHUP , SIG_IGN );
+      signal(SIGINT , SIG_IGN );
+      signal(SIGABRT, SIG_IGN );
+      signal(SIGCHLD, SIG_IGN );
+
+      if (execvp(args[0],args) < 0) {
+        perror("cannot exec simulator");
+        exit(1);
+      }
     }
     
  try_connect:
@@ -141,8 +192,8 @@ void openSimulator (char **args, int nargs)
        exit(1);
     }
 
-    /* now that we have opend wait for the prompt */
-    waitForSim();
+    /* now that we have opened, wait for the prompt */
+    waitForSim(200,NULL);
     simactive = 1;
 }
 /*-----------------------------------------------------------------*/
@@ -158,91 +209,180 @@ char *simResponse()
 /*-----------------------------------------------------------------*/
 void sendSim(char *s)
 {
-    Dprintf(D_simi, ("sendSim-->%s", s));  // s has LF at end already
+    if ( ! simout ) 
+        return;
+
+    Dprintf(D_simi, ("simi: sendSim-->%s", s));  // s has LF at end already
     fputs(s,simout);
     fflush(simout);
 }
 
+
+static int getMemString(char *buffer, char wrflag, 
+                        unsigned int addr, char mem, int size )
+{
+    int cachenr = NMEM_CACHE;
+    char *prefix;
+    char *cmd ;
+
+    if ( wrflag )
+        cmd = "set mem";
+    else
+        cmd = "dump";
+    buffer[0] = '\0' ;
+
+    switch (mem) 
+    {
+        case 'A': /* External stack */
+        case 'F': /* External ram */
+            prefix = "xram";
+            cachenr = XMEM_CACHE;
+            break;
+        case 'C': /* Code */
+        case 'D': /* Code / static segment */
+            prefix = "rom";
+            break;
+        case 'B': /* Internal stack */  
+        case 'E': /* Internal ram (lower 128) bytes */
+        case 'G': /* Internal ram */
+            prefix = "iram";
+            cachenr = IMEM_CACHE;
+            break;
+        case 'H': /* Bit addressable */
+        case 'J': /* SBIT space */
+            cachenr = BIT_CACHE;
+            if ( wrflag )
+            {
+                cmd = "set bit";
+            }
+            sprintf(buffer,"%s 0x%x\n",cmd,addr);
+            return cachenr;
+            break;
+        case 'I': /* SFR space */
+            prefix = "sfr" ;
+            break;
+        case 'R': /* Register space */ 
+            if ( !wrflag )
+            {
+                cachenr = REG_CACHE;
+                sprintf(buffer,"info reg\n");
+                return cachenr;
+            }
+            prefix = "iram";
+            /* get register bank */
+            cachenr = simGetValue (0xd0,'I',1); 
+            addr   += cachenr & 0x18 ;
+            cachenr = IMEM_CACHE;
+            break;
+        default: 
+        case 'Z': /* undefined space code */
+            return cachenr;
+    }
+    if ( wrflag )
+        sprintf(buffer,"%s %s 0x%x\n",cmd,prefix,addr,addr);
+    else
+        sprintf(buffer,"%s %s 0x%x 0x%x\n",cmd,prefix,addr,addr+size-1);
+    return cachenr;
+}
+
+int simSetValue (unsigned int addr,char mem, int size, unsigned long val)
+{
+    char cachenr, i;
+    char buffer[40];
+    char *s;
+
+    if ( size <= 0 )
+        return 0;
+
+    cachenr = getMemString(buffer,1,addr,mem,size);
+    if ( cachenr < NMEM_CACHE )
+    {
+        invalidateCache(cachenr);
+    }
+    s = buffer + strlen(buffer) -1;
+    for ( i = 0 ; i < size ; i++ )
+    {
+        sprintf(s," 0x%x", val & 0xff);
+        s += strlen(s);
+        val >>= 8;
+    }
+    sprintf(s,"\n");
+    sendSim(buffer);
+    waitForSim(100,NULL);
+    simResponse();   
+}
+
+
 /*-----------------------------------------------------------------*/
 /* simGetValue - get value @ address for mem space                 */
 /*-----------------------------------------------------------------*/
 unsigned long simGetValue (unsigned int addr,char mem, int size)
 {
     unsigned int b[4] = {0,0,0,0}; /* can be a max of four bytes long */
-    char i;
-    char *prefix;
-    char buffer[20];
+    char cachenr, i;
+    char buffer[40];
     char *resp;
 
-    switch (mem) {
-    case 'A':
-      prefix = "dx";
-      break;
-    case 'B':       
-      prefix = "di";
-      break;
-    case 'C':
-    case 'D':
-       prefix = "dch";
-       break;
-    case 'E':
-    case 'G':
-       prefix = "di";
-       break;
-    case 'F':
-       prefix = "dx";
-       break;
-    case 'H':
-    case 'J':
-       prefix = "db" ;
-       break;
-    case 'I':
-       prefix = "ds" ;
-       break;  
-    }
-    
-    /* create the simulator command */
-    sprintf(buffer,"%s 0x%x \n",prefix,addr);
-    sendSim(buffer);
-    waitForSim();
-    resp = simResponse();
-
-    /* got the response we need to parse it the response
-       is of the form 
-       [address] [v] [v] [v] ... special case in
-       case of bit variables which case it becomes
-       [address] [assembler bit address] [v] */
-    /* first skip thru white space */
-    while (isspace(*resp)) resp++ ;
-
-    /* then make the branch for bit variables */
-    /* skip thru the address part */
-    while (isxdigit(*resp)) resp++;
-    
-    if (!strcmp(prefix,"db")) {
-
-       /* skip white space */
-       while (isspace(*resp)) resp++ ;
-    
-       /* skip thru the assembler bit address */
-       while (!isspace(*resp)) resp++;
+    if ( size <= 0 )
+        return 0;
 
-       /* white space */
-       while (isspace(*resp)) resp++ ;
+    cachenr = getMemString(buffer,0,addr,mem,size);
 
-       /* scan in the value */
-       sscanf(resp,"%d",&b[0]);
-    } else {
-       
-       for (i = 0 ; i < size ; i++ ) {
-           /* skip white space */
-           while (isspace(*resp)) resp++ ;
-           
-           sscanf(resp,"%x",&b[i]);
+    resp = NULL;
+    if ( cachenr < NMEM_CACHE )
+    {
+        resp = getMemCache(addr,cachenr,size);
+    }
+    if ( !resp )
+    {
+        /* create the simulator command */
+        sendSim(buffer);
+        waitForSim(100,NULL);
+        resp = simResponse();
+
+        /* got the response we need to parse it the response
+           is of the form 
+           [address] [v] [v] [v] ... special case in
+           case of bit variables which case it becomes
+           [address] [assembler bit address] [v] */
+        /* first skip thru white space */
+        while (isspace(*resp)) resp++ ;
+
+        if (strncmp(resp, "0x",2) == 0)
+            resp += 2;
+
+        /* skip thru the address part */
+        while (isxdigit(*resp)) resp++;
+
+        /* then make the branch for bit variables */
+        if ( cachenr == REG_CACHE ) 
+        {
+            /* skip registers */
+            for (i = 0 ; i < addr ; i++ ) 
+            {
+                while (isspace(*resp)) resp++ ;
+                /* skip */
+                while (isxdigit(*resp)) resp++;
+            }
+        }
+    }   
+    /* make the branch for bit variables */
+    if ( cachenr == BIT_CACHE) 
+    {
+        /* skip until newline */
+        while (*resp && *resp != '\n' ) resp++ ;
+        if ( *--resp != '0' )
+            b[0] = 1;
+    }
+    else 
+    {  
+        for (i = 0 ; i < size ; i++ ) 
+        {
+            /* skip white space */
+            while (isspace(*resp)) resp++ ;
            
-           /* skip */
-           while (isxdigit(*resp)) resp++;
-       }
+            b[i] = strtol(resp,&resp,16);
+        }
     }
 
     return b[0] | b[1] << 8 | b[2] << 16 | b[3] << 24 ;
@@ -258,7 +398,7 @@ void simSetBP (unsigned int addr)
 
     sprintf(buff,"break 0x%x\n",addr);
     sendSim(buff);
-    waitForSim();
+    waitForSim(100,NULL);
 }
 
 /*-----------------------------------------------------------------*/
@@ -270,7 +410,7 @@ void simClearBP (unsigned int addr)
 
     sprintf(buff,"clear 0x%x\n",addr);
     sendSim(buff);
-    waitForSim();  
+    waitForSim(100,NULL);
 }
 
 /*-----------------------------------------------------------------*/
@@ -283,7 +423,7 @@ void simLoadFile (char *s)
     sprintf(buff,"l \"%s\"\n",s);
     printf(buff);
     sendSim(buff);
-    waitForSim();    
+    waitForSim(500,NULL);
 }
 
 /*-----------------------------------------------------------------*/
@@ -294,11 +434,14 @@ unsigned int simGoTillBp ( unsigned int gaddr)
     char *sr, *svr;
     unsigned addr ; 
     char *sfmt;
+    int wait_ms = 1000;
 
-    /* kpb: new code 8-03-01 */
+    invalidateCache(XMEM_CACHE);
+    invalidateCache(IMEM_CACHE);
     if (gaddr == 0) {
       /* initial start, start & stop from address 0 */
-       char buf[20];
+      char buf[20];
+
          // this program is setting up a bunch of breakpoints automatically
          // at key places.  Like at startup & main() and other function
          // entry points.  So we don't need to setup one here..
@@ -306,54 +449,62 @@ unsigned int simGoTillBp ( unsigned int gaddr)
       //sleep(1);
       //waitForSim();
 
-       sendSim("run 0x0\n");
-      sleep(1);  /* do I need this? */
+      sendSim("run 0x0\n");
     } else     if (gaddr == -1) { /* resume */
-
-      // try adding this(kpb)
-      sendSim("step\n");
-      usleep(100000);
-      waitForSim();
-
-       sendSim ("run\n");
+      sendSim ("run\n");
+      wait_ms = 100;
     }
-    else {
+    else       if (gaddr == 1 ) { /* nexti */
+      sendSim ("next\n");
+      wait_ms = 100;
+    }
+    else       if (gaddr == 2 ) { /* stepi */
+      sendSim ("step\n");
+      wait_ms = 100;
+    }
+    else  { 
       printf("Error, simGoTillBp > 0!\n");
       exit(1);
     }
 
-#if 0
-    if (gaddr != -1) {
-       char buf[20];
-       sprintf(buf,"g 0x%x\n",gaddr);
-       sendSim(buf);
-    } else     
-       sendSim ("g\n");
-#endif
-    
-    waitForSim();
+    waitForSim(wait_ms, NULL);
     
     /* get the simulator response */
     svr  = sr = strdup(simResponse());
 
+    if ( gaddr == 1 || gaddr == 2 )
+    {
+        int nl;
+        for ( nl = 0; nl < 3 ; nl++ )
+        {
+            while (*sr && *sr != '\n') sr++ ;
+            sr++ ;
+        }
+        if ( nl < 3 )
+            return 0;
+        gaddr = strtol(sr,0,0);
+        /* empty response */
+        simibuff[0] = '\0';
+        return gaddr;
+        
+    }
     /* figure out the address of the break point the simulators 
        response in a break point situation is of the form 
        [... F* <addr> <disassembled instruction> ] 
        we will ignore till we get F* then parse the address */
     while (*sr) {
-       
-       if (strncmp(sr,"Stop at",7) == 0) {
-           sr += 7;
-           sfmt = "%x";
-           break;
-       } 
-           
-       if (*sr == 'F' && ( *(sr+1) == '*' || *(sr+1) == ' ')) {
-           sr += 2;
-           sfmt = "%x";
-           break;
-       }
-       sr++;
+      if (strncmp(sr,"Stop at",7) == 0) {
+          sr += 7;
+          sfmt = "%x";
+          break;
+      } 
+
+      if (*sr == 'F' && ( *(sr+1) == '*' || *(sr+1) == ' ')) {
+          sr += 2;
+          sfmt = "%x";
+          break;
+      }
+      sr++;
     }
 
     if (!*sr) {
@@ -376,8 +527,10 @@ unsigned int simGoTillBp ( unsigned int gaddr)
 /*-----------------------------------------------------------------*/
 void simReset ()
 {
+    invalidateCache(XMEM_CACHE);
+    invalidateCache(IMEM_CACHE);
     sendSim("res\n");
-    waitForSim();
+    waitForSim(100,NULL);
 }
 
 /*-----------------------------------------------------------------*/
@@ -411,12 +564,17 @@ char  *simRegs()
     int i;
 
     sendSim("info registers\n");
-    //kpb(8-5-01) sendSim("dr\n");
 
-    waitForSim();
-    /* make it some more readable */
+    waitForSim(100,NULL);
+         
     resp  = simResponse();
 
+#if 0
+    return resp;
+
+#else
+    /*Take this out(2-09-02) cant see as its that useful to reformat, karl.*/
+  
     /* the response is of the form 
        XXXXXX R0 R1 R2 R3 R4 R5 R6 R7 ........
        XXXXXX XX . ACC=0xxx dd cc B=0xxx dd cc DPTR= 0xxxxx @DPTR= 0xxx dd cc
@@ -483,8 +641,7 @@ F  0x006d 75 87 80 MOV   PCON,#80
            getValueStr(resp,"P="));
 
     return regBuff;
-    
-    
+#endif
 
 }
 
@@ -493,12 +650,18 @@ F  0x006d 75 87 80 MOV   PCON,#80
 /*-----------------------------------------------------------------*/
 void closeSimulator ()
 {
-
+    if ( ! simin || ! simout || sock == -1 )
+    {
+        simactive = 0;
+        return;
+    }
     sendSim("q\n");
     kill (simPid,SIGKILL);
     fclose (simin);
     fclose (simout);
     shutdown(sock,2);   
     close(sock);    
-    
+    sock = -1;
 }
+
+