Use 'ao-dbg' instead of 's51' to communicate with TeleMetrum
[fw/sdcc] / debugger / mcs51 / simi.c
index 16e25b7ed50e7ed4daa57dd0478c344fe56f74d1..4a771a339fcc4782fa304011bb4b6aa4afb2733b 100644 (file)
@@ -1,29 +1,36 @@
 /*-------------------------------------------------------------------------
   simi.c - source file for simulator interaction
-
-             Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1999)
+        Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1999)
 
    This program is free software; you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by the
    Free Software Foundation; either version 2, or (at your option) any
    later version.
-   
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-   
+
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-   
+
    In other words, you are welcome to use, share and improve this program.
    You are forbidden to forbid anyone else to use, share and improve
-   what you give them.   Help stamp out software-hoarding!  
+   what you give them.   Help stamp out software-hoarding!
 -------------------------------------------------------------------------*/
 #include "sdcdb.h"
 #include "simi.h"
+#include "newalloc.h"
 
+#ifdef _WIN32
+#include <windows.h>
+#include <winsock2.h>
+#include <signal.h>
+#include <io.h>
+#include <fcntl.h>
+#else
 #ifdef HAVE_SYS_SOCKET_H
 #include <sys/types.h>
 #include <sys/socket.h>
 #else
 #error "Cannot build debugger without socket support"
 #endif
+#endif
+
 FILE *simin ; /* stream for simulator input */
 FILE *simout; /* stream for simulator output */
 
-int sock ; /* socket descriptor to comm with simulator */
-pid_t simPid;
+#ifdef _WIN32
+SOCKET sock = INVALID_SOCKET;
+PROCESS_INFORMATION *simPid = NULL;
+#else
+int sock = -1; /* socket descriptor to comm with simulator */
+pid_t simPid = -1;
+#endif
 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;
-    
-#ifdef SDCDB_DEBUG
-    fprintf(stderr,"stderr--> reading from sim\n");
-#endif
-
-    while ((ch = fgetc(simin))) {
-#ifdef SDCDB_DEBUG     
-       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 if ( cachenum == SREG_CACHE )
+        {
+            sendSim("ds 0x80 0xff\n");
+        }
+        else if ( cachenum == CMEM_CACHE )
+       {
+#define CMEM_CACHE_MASK ((MAX_CACHE_SIZE >> 2) - 1)
+            laddr = addr & ~CMEM_CACHE_MASK;
+            sprintf(cache->buffer,"dump rom 0x%x 0x%x\n",laddr,laddr+CMEM_CACHE_MASK );
+            sendSim(cache->buffer);
+       }
+       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;
     }
-#ifdef SDCDB_DEBUG
-    fprintf(stderr,"stderr--> reading from sim done\n");
-#endif
+    return cache->buffer + (addr - cache->addr)*3;
+}
 
-    *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));
+
 }
 
 /*-----------------------------------------------------------------*/
 /* openSimulator - create a pipe to talk to simulator              */
 /*-----------------------------------------------------------------*/
+#ifdef _WIN32
+static void init_winsock(void)
+{
+    static int is_initialized = 0;
+
+    if (!is_initialized)
+    {
+        WSADATA wsaData;
+        int iResult;
+
+        // Initialize Winsock
+        if (0 != WSAStartup(MAKEWORD(2,2), &wsaData))
+        {
+            fprintf(stderr, "WSAStartup failed: %d\n", iResult);
+            exit(1);
+        }
+    }
+}
+
+static char *argsToCmdLine(char **args, int nargs)
+{
+#define CHUNCK  256
+    int i;
+    int cmdPos = 0;
+    char *cmd = Safe_malloc(CHUNCK);
+    int cmdLen = CHUNCK;
+
+    for (i = 0; i < nargs; i++)
+    {
+        int quote = 0;
+        int argLen = strlen(args[i]);
+
+        if (NULL != strchr(args[i], ' '))
+        {
+            quote = 1;
+            argLen += 2;
+        }
+
+        if (0 < i)
+            ++argLen;
+
+        if (cmdPos + argLen >= cmdLen)
+        {
+            do
+            {
+                cmdLen += cmdLen;
+            }
+            while (cmdPos + argLen >= cmdLen);
+            cmd = Safe_realloc(cmd, cmdLen);
+        }
+
+        if (0 < i)
+        {
+            cmd[cmdPos++] = ' ';
+            --argLen;
+        }
+
+        if (quote)
+        {
+            cmd[cmdPos++] = '"';
+            --argLen;
+        }
+
+        memcpy(&cmd[cmdPos], args[i], argLen);
+        cmdPos += argLen;
+
+        if (quote)
+            cmd[cmdPos++] = '"';
+    }
+
+    cmd[cmdPos] = '\0';
+
+    return cmd;
+}
+
+static PROCESS_INFORMATION *execSimulator(char **args, int nargs)
+{
+    STARTUPINFO si;
+    static PROCESS_INFORMATION pi;
+    char *cmdLine = argsToCmdLine(args, nargs);
+
+    memset(&si, 0, sizeof(si));
+    si.cb = sizeof(si);
+    memset(&pi, 0, sizeof(pi));
+
+    // Start the child process.
+    if (!CreateProcess(NULL,   // No module name (use command line)
+        cmdLine, // Command line
+        NULL,           // Process handle not inheritable
+        NULL,           // Thread handle not inheritable
+        FALSE,          // Set handle inheritance to FALSE
+        0,              // No creation flags
+        NULL,           // Use parent's environment block
+        NULL,           // Use parent's starting directory
+        &si,            // Pointer to STARTUPINFO structure
+        &pi)            // Pointer to PROCESS_INFORMATION structure
+    )
+    {
+        Safe_free(cmdLine);
+        printf( "CreateProcess failed (%d).\n", GetLastError() );
+        return NULL;
+    }
+
+    Safe_free(cmdLine);
+    return &pi;
+}
+
 void openSimulator (char **args, int nargs)
 {
-    struct sockaddr_in sin;     
+    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;
+    int i;
+    int fh;
+
+    init_winsock();
 
-    /* fork and start the simulator as a subprocess */
-    if ((simPid = fork())) {
+    Dprintf(D_simi, ("simi: openSimulator\n"));
 #ifdef SDCDB_DEBUG
-       printf("simulator pid %d\n",(int) simPid);
-#endif
+    if (D_simi & sdcdbDebug)
+    {
+        printf("simi: openSimulator: ");
+        for (i=0; i < nargs; i++ )
+        {
+            printf("arg%d: %s ",i,args[i]);
+        }
+        printf("\n");
     }
-    else {
-       
-       /* we are in the child process : start the simulator */
-       if (execvp("s51",simargs) < 0) {
-           perror("cannot exec simulator");
-           exit(1);
-       }       
+#endif
+    invalidateCache(XMEM_CACHE);
+    invalidateCache(IMEM_CACHE);
+    invalidateCache(SREG_CACHE);
+    invalidateCache(CMEM_CACHE);
+
+    if (INVALID_SOCKET == (sock = WSASocket(PF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0))) {
+        fprintf(stderr, "cannot create socket: %d\n", WSAGetLastError());
+        exit(1);
     }
-    
- try_connect:
-    sock = socket(AF_INET,SOCK_STREAM,0);
-    
+
     memset(&sin,0,sizeof(sin));
     sin.sin_family = AF_INET;
     sin.sin_addr.s_addr = inet_addr("127.0.0.1");
     sin.sin_port = htons(9756);
-    
-    sleep(1);
+
+ try_connect:
     /* connect to the simulator */
-    if (connect(sock,(struct sockaddr *) &sin, sizeof(sin)) < 0) {
-       /* if failed then wait 1 second & try again
-          do this for 10 secs only */
-       if (retry < 10) {
-           retry ++;
-           sleep (1);
-           goto try_connect;
-       }
-       perror("connect failed :");
-       exit(1);
+    if (SOCKET_ERROR == connect(sock, (struct sockaddr *)&sin, sizeof(sin)))
+    {
+        /* if failed then wait 1 second & try again
+           do this for 10 secs only */
+        if (retry < 10)
+        {
+            if ( !retry )
+                simPid = execSimulator(args, nargs);
+            retry ++;
+            Sleep(1000);
+            goto try_connect;
+        }
+        perror("connect failed :");
+        exit(1);
     }
+
+    fh = _open_osfhandle((intptr_t)sock, _O_TEXT);
+    if (-1 == fh)
+    {
+        perror("cannot _open_osfhandle");
+        exit(1);
+    }
+
     /* go the socket now turn it into a file handle */
-    if (!(simin = fdopen(sock,"r"))) {
-       fprintf(stderr,"cannot open socket for read\n");
-       exit(1);
+    if (!(simin = fdopen(fh, "r")))
+    {
+        perror("cannot open socket for read");
+        exit(1);
     }
 
-    if (!(simout = fdopen(sock,"w"))) {
-       fprintf(stderr,"cannot open socket for write\n");
-       exit(1);
+    fh = _open_osfhandle((intptr_t)sock, _O_TEXT);
+    if (-1 == fh)
+    {
+        perror("cannot _open_osfhandle");
+        exit(1);
     }
 
-    /* now that we have opend wait for the prompt */
-    waitForSim();
+    if (!(simout = fdopen(fh, "w")))
+    {
+        perror("cannot open socket for write");
+        exit(1);
+    }
+    /* now that we have opened, wait for the prompt */
+    waitForSim(200, NULL);
     simactive = 1;
 }
+#else
+static int execSimulator(char **args, int nargs)
+{
+    if ((simPid = fork()))
+    {
+        Dprintf(D_simi, ("simi: simulator pid %d\n",(int) simPid));
+    }
+    else
+    {
+        /* we are in the child process : start the simulator */
+        signal(SIGINT , SIG_IGN );
+        signal(SIGABRT, SIG_IGN );
+        signal(SIGHUP , SIG_IGN );
+        signal(SIGCHLD, SIG_IGN );
+
+        if (execvp(args[0],args) < 0)
+        {
+            perror("cannot exec simulator");
+            exit(1);
+        }
+    }
+    return simPid;
+}
+
+void openSimulator (char **args, int nargs)
+{
+    struct sockaddr_in sin;
+    int retry = 0;
+    int i;
+    Dprintf(D_simi, ("simi: openSimulator\n"));
+#ifdef SDCDB_DEBUG
+    if (D_simi & sdcdbDebug)
+    {
+        printf("simi: openSimulator: ");
+        for (i=0; i < nargs; i++ )
+        {
+            printf("arg%d: %s ",i,args[i]);
+        }
+        printf("\n");
+    }
+#endif
+    invalidateCache(XMEM_CACHE);
+    invalidateCache(IMEM_CACHE);
+    invalidateCache(SREG_CACHE);
+    invalidateCache(CMEM_CACHE);
+
+    if ((sock = socket(AF_INET,SOCK_STREAM,0)) < 0)
+    {
+        perror("cannot create socket");
+        exit(1);
+    }
+
+    memset(&sin,0,sizeof(sin));
+    sin.sin_family = AF_INET;
+    sin.sin_addr.s_addr = inet_addr("127.0.0.1");
+    sin.sin_port = htons(9756);
+
+ try_connect:
+    /* connect to the simulator */
+    if (connect(sock,(struct sockaddr *) &sin, sizeof(sin)) < 0)
+    {
+        /* if failed then wait 1 second & try again
+           do this for 10 secs only */
+        if (retry < 10)
+        {
+            if ( !retry )
+            {
+                simPid = execSimulator(args, nargs);
+            }
+            retry ++;
+            sleep (1);
+            goto try_connect;
+        }
+        perror("connect failed :");
+        exit(1);
+    }
+    /* go the socket now turn it into a file handle */
+    if (!(simin = fdopen(sock,"r")))
+    {
+        fprintf(stderr,"cannot open socket for read\n");
+        exit(1);
+    }
+
+    if (!(simout = fdopen(sock,"w")))
+    {
+        fprintf(stderr,"cannot open socket for write\n");
+        exit(1);
+    }
+    /* now that we have opened, wait for the prompt */
+    waitForSim(200,NULL);
+    simactive = 1;
+}
+#endif
+
 /*-----------------------------------------------------------------*/
 /* simResponse - returns buffer to simulator's response            */
 /*-----------------------------------------------------------------*/
-char *simResponse()
+char *simResponse(void)
 {
     return simibuff;
 }
@@ -159,94 +457,190 @@ char *simResponse()
 /*-----------------------------------------------------------------*/
 void sendSim(char *s)
 {
+    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 */
+       case 'P': /* Pdata space */
+            prefix = "xram";
+            cachenr = XMEM_CACHE;
+            break;
+        case 'C': /* Code */
+        case 'D': /* Code / static segment */
+            prefix = "rom";
+           cachenr = CMEM_CACHE;
+            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" ;
+            cachenr = SREG_CACHE;
+            break;
+        case 'R': /* Register space */
+            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);
+    else
+        sprintf(buffer,"%s %s 0x%x 0x%x\n",cmd,prefix,*addr,*addr+size-1);
+    return cachenr;
+}
+
+void simSetPC( unsigned int addr )
+{
+    char buffer[40];
+    sprintf(buffer,"pc %d\n", addr);
+    sendSim(buffer);
+    waitForSim(100,NULL);
+    simResponse();
+}
+
+unsigned int simGetPC(void)
+{
+    char *sr;
+    sendSim("pc\n");
+    waitForSim(100,NULL);
+    simResponse();
+    sr = simResponse();
+    return strtol(sr+3,0,0);
+}
+    
+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%lx", val & 0xff);
+        s += strlen(s);
+        val >>= 8;
+    }
+    sprintf(s,"\n");
+    sendSim(buffer);
+    waitForSim(100,NULL);
+    simResponse();
+    return 0;
+}
+
+
 /*-----------------------------------------------------------------*/
 /* 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;  
+    if ( size <= 0 )
+        return 0;
+
+    cachenr = getMemString(buffer,0,&addr,mem,size);
+
+    resp = NULL;
+    if ( cachenr < NMEM_CACHE )
+    {
+        resp = getMemCache(addr,cachenr,size);
     }
-    
-    /* 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")) {
+    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 */
+        resp = trim_left(resp);
+
+        if (strncmp(resp, "0x",2) == 0)
+            resp += 2;
+
+        /* skip thru the address part */
+        while (isxdigit(*resp)) resp++;
 
-       /* skip white space */
-       while (isspace(*resp)) resp++ ;
-    
-       /* skip thru the assembler bit address */
-       while (!isspace(*resp)) resp++;
-
-       /* white space */
-       while (isspace(*resp)) resp++ ;
-
-       /* 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]);
-           
-           /* 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 */
+            resp = trim_left(resp);
+
+            b[i] = strtol(resp,&resp,16);
+        }
     }
 
     return b[0] | b[1] << 8 | b[2] << 16 | b[3] << 24 ;
-       
+
 }
 
 /*-----------------------------------------------------------------*/
@@ -258,7 +652,7 @@ void simSetBP (unsigned int addr)
 
     sprintf(buff,"break 0x%x\n",addr);
     sendSim(buff);
-    waitForSim();
+    waitForSim(100,NULL);
 }
 
 /*-----------------------------------------------------------------*/
@@ -270,7 +664,7 @@ void simClearBP (unsigned int addr)
 
     sprintf(buff,"clear 0x%x\n",addr);
     sendSim(buff);
-    waitForSim();  
+    waitForSim(100,NULL);
 }
 
 /*-----------------------------------------------------------------*/
@@ -280,10 +674,10 @@ void simLoadFile (char *s)
 {
     char buff[128];
 
-    sprintf(buff,"l %s\n",s);
-    printf(buff);
+    sprintf(buff,"file \"%s\"\n",s);
+    printf("%s",buff);
     sendSim(buff);
-    waitForSim();    
+    waitForSim(500,NULL);
 }
 
 /*-----------------------------------------------------------------*/
@@ -291,166 +685,123 @@ void simLoadFile (char *s)
 /*-----------------------------------------------------------------*/
 unsigned int simGoTillBp ( unsigned int gaddr)
 {
-    char *sr, *svr;
-    unsigned addr ; 
+    char *sr;
+    unsigned addr ;
     char *sfmt;
+    int wait_ms = 1000;
+
+    invalidateCache(XMEM_CACHE);
+    invalidateCache(IMEM_CACHE);
+    invalidateCache(SREG_CACHE);
+    if (gaddr == 0) {
+        /* initial start, start & stop from address 0 */
+        //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..
+        //sendSim("break 0x0\n");
+        //sleep(1);
+        //waitForSim();
+
+        sendSim("reset\n");
+        waitForSim(wait_ms, NULL);
+        sendSim("run 0x0\n");
+    } else      if (gaddr == -1) { /* resume */
+        sendSim ("run\n");
+        wait_ms = 100;
+    }
+    else        if (gaddr == 1 ) { /* nexti or next */
+        sendSim ("next\n");
+        wait_ms = 100;
+    }
+    else        if (gaddr == 2 ) { /* stepi or step */
+        sendSim ("step\n");
+        wait_ms = 100;
+    }
+    else  {
+        printf("Error, simGoTillBp > 0!\n");
+        exit(1);
+    }
+
+    waitForSim(wait_ms, NULL);
 
-    if (gaddr != -1) {
-       char buf[20];
-       sprintf(buf,"g 0x%x\n",gaddr);
-       sendSim(buf);
-    } else     
-       sendSim ("g\n");
-    
-    waitForSim();
-    
     /* get the simulator response */
-    svr  = sr = strdup(simResponse());
-
-    /* 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++;
+    sr = simResponse();
+    /* check for errors */
+    while ( *sr )
+    {
+        while ( *sr && *sr != 'E' ) sr++ ;
+        if ( !*sr )
+            break;
+        if ( ! strncmp(sr,"Error:",6))
+        {
+            fputs(sr,stdout);
+            break;
+        }
+        sr++ ;
     }
 
-    if (!*sr) return 0;
+    nointerrupt = 1;
+    /* get answer of stop command */
+    if ( userinterrupt )
+        waitForSim(wait_ms, NULL);
 
-    while (isspace(*sr)) sr++ ;
-
-    if (sscanf(sr,sfmt,&addr) != 1)
-       return 0;
-    else
-       return addr;
-     
+    /* better solution: ask pc */
+    sendSim ("pc\n");
+    waitForSim(100, NULL);
+    sr = simResponse();
+    nointerrupt = 0;
 
+    gaddr = strtol(sr+3,0,0);
+    return gaddr;
 }
 
 /*-----------------------------------------------------------------*/
 /* simReset - reset the simulator                                  */
 /*-----------------------------------------------------------------*/
-void simReset ()
+void simReset (void)
 {
+    invalidateCache(XMEM_CACHE);
+    invalidateCache(IMEM_CACHE);
+    invalidateCache(SREG_CACHE);
+    invalidateCache(CMEM_CACHE);
     sendSim("res\n");
-    waitForSim();
+    waitForSim(100,NULL);
 }
 
-/*-----------------------------------------------------------------*/
-/* getValueStr - read a value followed by a string =               */
-/*-----------------------------------------------------------------*/
-static unsigned int getValueStr (char *src,char *cstr)
-{
-    int i = strlen(cstr);
-    int rv;
-    /* look for the string */
-    if (! (src = strstr(src,cstr)))
-       return 0;
-
-    src += i;
-    if (!*src) return 0;
-
-    /* look for the digit */
-    while (*src && !isxdigit(*src)) src++;
-    sscanf(src,"%x",&rv);
-    return rv;
-}
-
-/*-----------------------------------------------------------------*/
-/* simRegs - returns value of registers                            */
-/*-----------------------------------------------------------------*/
-char  *simRegs()
-{   
-    char *resp ;
-    unsigned int rv;
-    char *rb = regBuff;
-    int i;
-
-    sendSim("dr\n");
-    waitForSim();
-    /* make it some more readable */
-    resp  = simResponse();
-
-    /* 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
-       XXXXXX XX . PSW= 0xxx CY=[1|0] AC=[0|1] OV=[0|1] P=[1|0] */
-    memset(regBuff,0,sizeof(regBuff));
-    /* skip the first numerics */
-    while (*resp && !isxdigit(*resp)) resp++;
-    while (*resp && isxdigit(*resp)) resp++;
-
-    /* now get the eight registers */
-    for (i = 0 ; i < 7 ; i++) {
-        while (*resp && isspace(*resp)) resp++;
-       if (!*resp)
-           break;
-       rv = strtol(resp,&resp,16);
-       sprintf(rb,"R%d  : 0x%02X %d %c\n",i,rv,rv,(isprint(rv) ? rv : '.'));
-       rb += strlen(rb);
-    }
-
-    if (!*resp) return regBuff;
-
-    /* skip till end of line */
-    while (*resp && *resp != '\n') resp++;
-    while (*resp && !isxdigit(*resp)) resp++;
-    while (*resp && isxdigit(*resp)) resp++;
-    
-    /* accumulator value */
-    rv = getValueStr(resp,"ACC");
-    sprintf(rb,"ACC : 0x%02X %d %c\n",rv,rv,(isprint(rv) ? rv : '.'));
-    rb += strlen(rb);
-    
-    /* value of B */
-    rv = getValueStr(resp,"B=");
-    sprintf(rb,"B   : 0x%02X %d %c\n",rv,rv,(isprint(rv) ? rv : '.'));
-    rb += strlen(rb);
-
-    rv = getValueStr(resp,"DPTR=");
-    sprintf(rb,"DPTR: 0x%04X %d\n",rv,rv);
-    rb += strlen(rb);
-
-    rv = getValueStr(resp,"@DPTR=");
-    sprintf(rb,"@DPTR: 0x%02X %d %c\n", rv,rv,(isprint(rv) ? rv : '.'));
-    rb += strlen(rb);
-    
-    sprintf(rb,"PSW  : 0x%02X | CY : %d | AC : %d | OV : %d | P : %d\n",
-           getValueStr(resp,"PSW="),
-           getValueStr(resp,"CY="),
-           getValueStr(resp,"AC="),
-           getValueStr(resp,"OV="),
-           getValueStr(resp,"P="));
-
-    return regBuff;
-    
-    
-
-}
 
 /*-----------------------------------------------------------------*/
 /* closeSimulator - close connection to simulator                  */
 /*-----------------------------------------------------------------*/
-void closeSimulator ()
+void closeSimulator (void)
 {
-
-    sendSim("q\n");
-    kill (simPid,SIGKILL);
+#ifdef _WIN32
+    if ( ! simin || ! simout || INVALID_SOCKET == sock )
+#else
+    if ( ! simin || ! simout || sock == -1 )
+#endif
+    {
+        simactive = 0;
+        return;
+    }
+    simactive = 0;
+    sendSim("quit\n");
     fclose (simin);
     fclose (simout);
-    shutdown(sock,2);   
-    close(sock);    
-    
+    shutdown(sock,2);
+#ifdef _WIN32
+    closesocket(sock);
+    sock = -1;
+    if (NULL != simPid)
+        TerminateProcess(simPid->hProcess, 0);
+    // Close process and thread handles.
+    CloseHandle(simPid->hProcess);
+    CloseHandle(simPid->hThread);
+#else
+    close(sock);
+    sock = -1;
+    if ( simPid > 0 )
+        kill (simPid,SIGKILL);
+#endif
 }