Use 'ao-dbg' instead of 's51' to communicate with TeleMetrum
[fw/sdcc] / debugger / mcs51 / sdcdb.c
index d86dcfc8f71efe12824349cd61c0e1341f4e9061..8df52526574ae2c77fc29e30d94becfd3d10f9d0 100644 (file)
 /*-------------------------------------------------------------------------
   sdcdb.c - main source file for sdcdb debugger
 /*-------------------------------------------------------------------------
   sdcdb.c - main source file for sdcdb debugger
-             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 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.
    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.
    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
    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!
 -------------------------------------------------------------------------*/
 
 -------------------------------------------------------------------------*/
 
+#define link unix_link
+#define _GNU_SOURCE
+#include <unistd.h>
+#undef link
 #include "sdcdb.h"
 #include "symtab.h"
 #include "simi.h"
 #include "break.h"
 #include "cmd.h"
 #include "sdcdb.h"
 #include "symtab.h"
 #include "simi.h"
 #include "break.h"
 #include "cmd.h"
+#include "newalloc.h"
+#if defined HAVE_LIBREADLINE && HAVE_LIBREADLINE != -1
+#define HAVE_READLINE_COMPLETITION  1
+#endif
+#ifdef HAVE_LIBREADLINE
+#include <readline/readline.h>
+#include <readline/history.h>
+#endif  /* HAVE_LIBREADLINE */
+
+#ifdef SDCDB_DEBUG
+int   sdcdbDebug = 0;
+#endif
 
 char *currModName = NULL;
 cdbrecs *recsRoot = NULL ;
 set  *modules = NULL;    /* set of all modules */
 set  *functions = NULL ; /* set of functions */
 set  *symbols = NULL   ; /* set of symbols */
 
 char *currModName = NULL;
 cdbrecs *recsRoot = NULL ;
 set  *modules = NULL;    /* set of all modules */
 set  *functions = NULL ; /* set of functions */
 set  *symbols = NULL   ; /* set of symbols */
+set  *sfrsymbols= NULL ; /* set of symbols of sfr or sbit */
 int nStructs = 0 ;
 structdef **structs = NULL ; /* all structures */
 int nLinkrecs = 0;
 linkrec **linkrecs = NULL; /* all linkage editor records */
 context *currCtxt = NULL;
 short fullname = 0;
 int nStructs = 0 ;
 structdef **structs = NULL ; /* all structures */
 int nLinkrecs = 0;
 linkrec **linkrecs = NULL; /* all linkage editor records */
 context *currCtxt = NULL;
 short fullname = 0;
-char *ssdirl = SDCC_LIB_DIR ":" SDCC_LIB_DIR "/small" ;
-char *simArgs[8];
+short showfull = 0;
+char userinterrupt = 0;
+char nointerrupt = 0;
+char contsim = 0;
+char *ssdirl = DATADIR LIB_DIR_SUFFIX ":" DATADIR LIB_DIR_SUFFIX DIR_SEPARATOR_STRING "small" ;
+char *simArgs[40];
 int nsimArgs = 0;
 int nsimArgs = 0;
+char model_str[20];
+/* fake filename & lineno to make linker */
+char *filename=NULL;
+char *current_directory;
+int lineno = 0;
+int fatalError = 0;
+
+static void commandLoop(FILE *cmdfile);
+#ifdef HAVE_READLINE_COMPLETITION
+char *completionCmdSource(const char *text, int state);
+char *completionCmdFile(const char *text, int state);
+char *completionCmdInfo(const char *text, int state);
+char *completionCmdShow(const char *text, int state);
+char *completionCmdListSymbols(const char *text, int state);
+char *completionCmdPrintType(const char *text, int state);
+char *completionCmdPrint(const char *text, int state);
+char *completionCmdDelUserBp(const char *text, int state);
+char *completionCmdUnDisplay(const char *text, int state);
+char *completionCmdSetUserBp(const char *text, int state);
+char *completionCmdSetOption(const char *text, int state);
+#else
+#define completionCmdSource NULL
+#define completionCmdFile NULL
+#define completionCmdInfo NULL
+#define completionCmdShow NULL
+#define completionCmdListSymbols NULL
+#define completionCmdPrintType NULL
+#define completionCmdPrint NULL
+#define completionCmdDelUserBp NULL
+#define completionCmdUnDisplay NULL
+#define completionCmdSetUserBp NULL
+#define completionCmdSetOption NULL
+#endif /* HAVE_READLINE_COMPLETITION */
 
 /* command table */
 struct cmdtab
 {
 
 /* command table */
 struct cmdtab
 {
-    char      *cmd ;  /* command the user will enter */       
+    char      *cmd ;  /* command the user will enter */
     int (*cmdfunc)(char *,context *);   /* function to execute when command is entered */
     int (*cmdfunc)(char *,context *);   /* function to execute when command is entered */
-    char *htxt ;    /* short help text */    
-    
+#ifdef HAVE_READLINE_COMPLETITION
+    rl_compentry_func_t *completion_func;
+#else
+    void *dummy;
+#endif  /* HAVE_READLINE_COMPLETITION */
+    char *htxt ;    /* short help text */
+
 } cmdTab[] = {
     /* NOTE:- the search is done from the top, so "break" should
        precede the synonym "b" */
     /* break point */
 } cmdTab[] = {
     /* NOTE:- the search is done from the top, so "break" should
        precede the synonym "b" */
     /* break point */
-    { "break"    ,  cmdSetUserBp  ,
-      "{b}reak\t\t\t [LINE |  FILE:LINE | FILE:FUNCTION | FUNCTION]\n",
+    { "break"    ,  cmdSetUserBp  , completionCmdSetUserBp,
+      "{b}reak\t\t\t [LINE | FILE:LINE | FILE:FUNCTION | FUNCTION | *<address>]\n",
+    },
+    { "tbreak"   ,  cmdSetTmpUserBp , completionCmdSetUserBp/*same as "break"*/,
+      "tbreak\t\t\t [LINE | FILE:LINE | FILE:FUNCTION | FUNCTION | *<address>]\n",
     },
     },
-    { "b"        ,  cmdSetUserBp  , NULL },
+    { "b"        ,  cmdSetUserBp  , completionCmdSetUserBp ,  NULL,},
 
 
-    { "clear"    ,  cmdClrUserBp  ,
+    { "jump"   ,  cmdJump , NULL,
+      "jump\t\t\tContinue program being debugged at specified line or address\n [LINE | FILE:LINE | *<address>]\n",
+    },
+    { "clear"    ,  cmdClrUserBp  , completionCmdSetUserBp/*same as "break"*/,
       "{cl}ear\t\t\t [LINE | FILE:LINE | FILE:FUNCTION | FUNCTION]\n"
     },
       "{cl}ear\t\t\t [LINE | FILE:LINE | FILE:FUNCTION | FUNCTION]\n"
     },
-    { "cl"       ,  cmdClrUserBp  , NULL },
+    { "cl"       ,  cmdClrUserBp  , completionCmdSetUserBp/*same as "break"*/ , NULL,},
 
 
-    { "continue" ,  cmdContinue   ,
+    { "continue" ,  cmdContinue   ,  NULL,
       "{c}ontinue\t\t Continue program being debugged, after breakpoint.\n"
     },
       "{c}ontinue\t\t Continue program being debugged, after breakpoint.\n"
     },
-    { "c"        ,  cmdContinue   , NULL },
+    { "condition" ,  cmdCondition   ,  completionCmdDelUserBp/*same as "delete"*/,
+      "condition brkpoint_number expr\t\tSet condition for breakpoint.\n"
+    },
+    { "ignore" ,  cmdIgnore  ,  completionCmdDelUserBp/*same as "delete"*/,
+      "ignore brkpoint_number count\t\tSet ignore count for breakpoint.\n"
+    },
+    { "commands" ,  cmdCommands  ,  completionCmdDelUserBp/*same as "delete"*/,
+      "commands [brkpoint_number]\t\tSetting commands for breakpoint.\n"
+    },
+    { "c"        ,  cmdContinue   , NULL ,  NULL,},
 
 
-    { "delete" ,  cmdDelUserBp  ,
+    { "disassemble",cmdDisasmF    ,  NULL, "disassemble [startaddr [endaddress]]\tdisassemble asm commands\n" },
+    { "delete" ,  cmdDelUserBp  , completionCmdDelUserBp,
       "{d}elete n\t\t clears break point number n\n"
     },
       "{d}elete n\t\t clears break point number n\n"
     },
-    { "d"        ,  cmdDelUserBp  , NULL },
+    { "display"    ,  cmdDisplay     , completionCmdPrint/*same as "print"*/,
+      "display [/<fmt>] [<variable>]\t print value of given variable each time the program stops\n"
+    },
+    { "undisplay"  ,  cmdUnDisplay   , completionCmdUnDisplay,
+      "undisplay [<variable>]\t dont display this variable or all\n"
+    },
+    { "down"     ,  cmdDown      , NULL,
+      "down\t\tSelect and print stack frame called by this one.\nAn argument says how many frames down to go.\n"
+    },
+    { "up"       ,  cmdUp      , NULL,
+      "up\t\tSelect and print stack frame that called this one.\nAn argument says how many frames up to go.\n"
+    },
+    { "d"        ,  cmdDelUserBp  , completionCmdDelUserBp, NULL },
 
 
-    { "help"     ,  cmdHelp       ,
-      "{h|?}elp\t\t this message\n"
-    },    
-    { "?"        ,  cmdHelp       , NULL },
-    { "h"        ,  cmdHelp       , NULL },
-    
-    { "info"     ,  cmdInfo       ,
-      "info\n"
-      "\t {break}\t list all break points\n"
-      "\t {stack}\t information about call stack\n"
-      "\t {frame}\t current frame information\n"
-      "\t {registers}\t display value of all registers\n"
+    { "info"     ,  cmdInfo       , completionCmdInfo,
+      "info <break stack frame registers all-registers line source functions symbols variables>\n"
+      "\t list all break points, call-stack, frame or register information\n"
     },
 
     },
 
-    { "listasm"  ,  cmdListAsm    ,
+    { "listasm"  ,  cmdListAsm    , NULL,
       "listasm {la}\t\t list assembler code for the current C line\n"
     },
       "listasm {la}\t\t list assembler code for the current C line\n"
     },
-    { "la"       ,  cmdListAsm    , NULL },
-    { "list"     ,  cmdListSrc    ,
+    { "la"       ,  cmdListAsm    , NULL, NULL },
+    { "ls"       ,  cmdListSymbols  , completionCmdListSymbols, "ls,lf,lm\t\t list symbols,functions,modules\n" },
+    { "lf"       ,  cmdListFunctions, completionCmdListSymbols, NULL },
+    { "lm"       ,  cmdListModules  , completionCmdListSymbols, NULL },
+    { "list"     ,  cmdListSrc    , completionCmdSetUserBp/*same as "break"*/,
       "{l}ist\t\t\t [LINE | FILE:LINE | FILE:FUNCTION | FUNCTION]\n"
       "{l}ist\t\t\t [LINE | FILE:LINE | FILE:FUNCTION | FUNCTION]\n"
-    },    
-    { "l"        ,  cmdListSrc    , NULL },
-    { "show"     ,  cmdShow       ,
-      "show\n"
-      "\t {copying}\t copying & distribution terms\n"
-      "\t {warranty}\t warranty information\n"
-    },
-    { "set"      ,  cmdSetOption  , NULL },    
-    { "step"     ,  cmdStep       ,
-      "{s}tep\t\t\t Step program until it reaches a different source line.\n"
-    },
-    { "s"        ,  cmdStep       , NULL },
-    { "next"     ,  cmdNext       , 
-      "{n}ext\t\t\t Step program, proceeding through subroutine calls.\n"
-    },
-    { "n"        ,  cmdNext       , NULL },
-    { "run"      ,  cmdRun        , 
-      "{r}un\t\t\t Start debugged program. \n"
-    },
-    { "r"        ,  cmdRun        , NULL },
-    { "ptype"    ,  cmdPrintType  , 
-      "{pt}ype <variable>\t print type information of a variable\n"
-    },
-    { "pt"       ,  cmdPrintType  , NULL },
-    { "print"    ,  cmdPrint      , 
+    },
+    { "l"        ,  cmdListSrc    , completionCmdSetUserBp/*same as "break"*/, NULL },
+    { "show"     ,  cmdShow       , completionCmdShow,
+      "show"
+      " <copying warranty>\t copying & distribution terms, warranty\n"
+    },
+    { "set"      ,  cmdSetOption  , completionCmdSetOption, "set <srcmode>\t\t toggle between c/asm.\nset variable <var> = >value\t\tset variable to new value\n" },
+    { "stepi"    ,  cmdStepi      , NULL,
+      "stepi\t\t\tStep one instruction exactly.\n"
+    },
+    { "step"     ,  cmdStep       , NULL,
+      "{s}tep\t\t\tStep program until it reaches a different source line.\n"
+    },
+    { "source"   ,  cmdSource      , completionCmdSource,
+      "source <FILE>\t\t\tRead commands from a file named FILE.\n"
+    },
+    { "s"        ,  cmdStep       , NULL, NULL },
+    { "nexti"    ,  cmdNexti      , NULL,
+      "nexti\t\t\tStep one instruction, but proceed through subroutine calls.\n"
+    },
+    { "next"     ,  cmdNext       , NULL,
+      "{n}ext\t\t\tStep program, proceeding through subroutine calls.\n"
+    },
+    { "n"        ,  cmdNext       , NULL, NULL },
+    { "run"      ,  cmdRun        , NULL,
+      "{r}un\t\t\tStart debugged program. \n"
+    },
+    { "r"        ,  cmdRun        , NULL, NULL },
+    { "ptype"    ,  cmdPrintType  , completionCmdPrintType,
+      "{pt}ype <variable>\tprint type information of a variable\n"
+    },
+    { "pt"       ,  cmdPrintType  , NULL, NULL },
+    { "print"    ,  cmdPrint      , completionCmdPrintType,
       "{p}rint <variable>\t print value of given variable\n"
     },
       "{p}rint <variable>\t print value of given variable\n"
     },
-    { "p"        ,  cmdPrint      , NULL },
-    { "file"     ,  cmdFile       ,
+    { "output"   ,  cmdOutput      , completionCmdPrint/*same as "print"*/,
+      "output <variable>\t print value of given variable without $ and newline \n"
+    },
+    { "p"        ,  cmdPrint      , completionCmdPrintType, NULL },
+    { "file"     ,  cmdFile       , completionCmdFile,
       "file <filename>\t\t load symbolic information from <filename>\n"
       "file <filename>\t\t load symbolic information from <filename>\n"
-    },  
-    { "frame"    ,  cmdFrame      , 
-      "{fr}ame\t\t\t print information about the current Stack\n"
     },
     },
-    { "finish"   ,  cmdFinish     ,
+    { "frame"    ,  cmdFrame      , NULL,
+      "{fr}ame\t\t print information about the current Stack\n"
+    },
+    { "finish"   ,  cmdFinish     , NULL,
       "{fi}nish\t\t execute till return of current function\n"
     },
       "{fi}nish\t\t execute till return of current function\n"
     },
-    { "fi"       ,  cmdFinish     , NULL },
-    { "fr"       ,  cmdFrame      , NULL },
-    { "f"        ,  cmdFrame      , NULL },
-    { "!"        ,  cmdSimulator  , 
+    { "fi"       ,  cmdFinish     , NULL, NULL },
+    { "where"    ,  cmdWhere      , NULL, "where\t\t print stack\n" },
+    { "fr"       ,  cmdFrame      , NULL, NULL },
+    { "f"        ,  cmdFrame      , NULL, NULL },
+    { "x /i"     ,  cmdDisasm1    , NULL, "x\t\t disassemble one asm command\n" },
+    { "!"        ,  cmdSimulator  , NULL,
       "!<simulator command>\t send a command directly to the simulator\n"
     },
       "!<simulator command>\t send a command directly to the simulator\n"
     },
-    { "quit"     ,  cmdQuit       , 
+    { "."        ,  cmdSimulator  , NULL,
+      ".{cmd}\t switch from simulator or debugger command mode\n"
+    },
+    { "help"     ,  cmdHelp       , NULL,
+      "{h|?}elp\t [CMD_NAME | 0,1,2,3(help page)] (general help or specific help)\n"
+    },
+    { "?"        ,  cmdHelp       , NULL, NULL },
+    { "h"        ,  cmdHelp       , NULL, NULL },
+
+    { "quit"     ,  cmdQuit       , NULL,
       "{q}uit\t\t\t \"Watch me now. Iam going Down. My name is Bobby Brown\"\n"
     },
       "{q}uit\t\t\t \"Watch me now. Iam going Down. My name is Bobby Brown\"\n"
     },
-    { "q"        ,  cmdQuit       , NULL }
+    { "q"        ,  cmdQuit       , NULL, NULL }
 };
 
 };
 
+/*-----------------------------------------------------------------*/
+/* trimming functions                                              */
+/*-----------------------------------------------------------------*/
+char *trim_left(char *s)
+{
+    while (isspace(*s))
+        ++s;
+
+    return s;
+}
+
+char *trim_right(char *s)
+{
+    char *p = &s[strlen(s) - 1];
+
+    while (p >= s && isspace(*p))
+      --p;
+    *++p = '\0';
+
+    return s;
+}
+
+char *trim(char *s)
+{
+    return trim_right(trim_left(s));
+}
+
+/*-----------------------------------------------------------------*/
+/* gc_strdup - make a string duplicate garbage collector aware     */
+/*-----------------------------------------------------------------*/
+char *gc_strdup(const char *s)
+{
+    char *ret;
+    ret = Safe_malloc(strlen(s)+1);
+    strcpy(ret, s);
+    return ret;
+}
+
 /*-----------------------------------------------------------------*/
 /* alloccpy - allocate copy and return a new string                */
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
 /* alloccpy - allocate copy and return a new string                */
 /*-----------------------------------------------------------------*/
@@ -150,9 +291,9 @@ char *alloccpy ( char *s, int size)
     char *d;
 
     if (!size)
     char *d;
 
     if (!size)
-       return NULL;
+        return NULL;
 
 
-    ALLOC(d,size+1);
+    d = Safe_malloc(size+1);
     memcpy(d,s,size);
     d[size] = '\0';
 
     memcpy(d,s,size);
     d[size] = '\0';
 
@@ -167,17 +308,17 @@ void **resize (void **array, int newSize)
     void **vptr;
 
     if (array)
     void **vptr;
 
     if (array)
-       vptr = GC_realloc(array,newSize*(sizeof(void **)));
+        vptr = Safe_realloc(array,newSize*(sizeof(void **)));
     else
     else
-       vptr = GC_malloc(sizeof(void **));
-    
+        vptr = calloc(1, sizeof(void **));
+
     if (!vptr) {
     if (!vptr) {
-       fprintf(stderr,"sdcdb: out of memory \n");
-       exit(1);
+        fprintf(stderr,"sdcdb: out of memory \n");
+        exit(1);
     }
 
     return vptr;
     }
 
     return vptr;
-       
+
 }
 
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
@@ -189,51 +330,51 @@ static int readCdb (FILE *file)
     cdbrecs *currl ;
     char buffer[1024];
     char *bp ;
     cdbrecs *currl ;
     char buffer[1024];
     char *bp ;
-    
+
     if (!(bp = fgets(buffer,sizeof(buffer),file)))
     if (!(bp = fgets(buffer,sizeof(buffer),file)))
-           return 0;
-    
-    ALLOC(currl,sizeof(cdbrecs));
+        return 0;
+
+    currl = Safe_calloc(1,sizeof(cdbrecs));
     recsRoot = currl ;
 
     while (1) {
     recsRoot = currl ;
 
     while (1) {
-       
-       /* make sure this is a cdb record */
-       if (strchr("STLFM",*bp) && *(bp+1) == ':') {
-           /* depending on the record type */
-           
-           switch (*bp) {
-           case 'S':
-               /* symbol record */
-               currl->type = SYM_REC;
-               break;
-           case 'T':
-               currl->type = STRUCT_REC;
-               break;
-           case 'L':
-               currl->type = LNK_REC;
-               break;
-           case 'F':
-               currl->type = FUNC_REC;
-               break;
-           case 'M':
-               currl->type = MOD_REC ;
-           }
-           
-           bp += 2;
-           ALLOC(currl->line,strlen(bp));
-           strncpy(currl->line,bp,strlen(bp)-1);
-           currl->line[strlen(bp)-1] = '\0';
-       }
-       
-       if (!(bp = fgets(buffer,sizeof(buffer),file)))
-           break;
-       
-       if (feof(file))
-           break;
-       
-       ALLOC(currl->next,sizeof(cdbrecs));
-       currl = currl->next;
+
+        /* make sure this is a cdb record */
+        if (strchr("STLFM",*bp) && *(bp+1) == ':') {
+            /* depending on the record type */
+
+            switch (*bp) {
+            case 'S':
+                /* symbol record */
+                currl->type = SYM_REC;
+                break;
+            case 'T':
+                currl->type = STRUCT_REC;
+                break;
+            case 'L':
+                currl->type = LNK_REC;
+                break;
+            case 'F':
+                currl->type = FUNC_REC;
+                break;
+            case 'M':
+                currl->type = MOD_REC ;
+            }
+
+            bp += 2;
+            currl->line = Safe_malloc(strlen(bp));
+            strncpy(currl->line,bp,strlen(bp)-1);
+            currl->line[strlen(bp)-1] = '\0';
+        }
+
+        if (!(bp = fgets(buffer,sizeof(buffer),file)))
+            break;
+
+        if (feof(file))
+            break;
+
+        currl->next = Safe_calloc(1,sizeof(cdbrecs));
+        currl = currl->next;
     }
 
     return (recsRoot->line ? 1 : 0);
     }
 
     return (recsRoot->line ? 1 : 0);
@@ -246,39 +387,39 @@ char *searchDirsFname (char *fname)
 {
     char *dirs , *sdirs;
     FILE *rfile = NULL;
 {
     char *dirs , *sdirs;
     FILE *rfile = NULL;
-    char buffer[128];
+    char buffer[1024];
 
     /* first try the current directory */
     if ((rfile = fopen(fname,"r"))) {
 
     /* first try the current directory */
     if ((rfile = fopen(fname,"r"))) {
-       fclose(rfile);
-       return strdup(fname) ;
+        fclose(rfile);
+        return strdup(fname) ;
     }
 
     if (!ssdirl)
     }
 
     if (!ssdirl)
-       return strdup(fname);
+        return strdup(fname);
 
     /* make a copy of the source directories */
 
     /* make a copy of the source directories */
-    dirs = sdirs = strdup(ssdirl);    
-   
-    /* assume that the separator is ':' 
+    dirs = sdirs = strdup(ssdirl);
+
+    /* assume that the separator is ':'
        and try for each directory in the search list */
     dirs = strtok(dirs,":");
     while (dirs) {
        and try for each directory in the search list */
     dirs = strtok(dirs,":");
     while (dirs) {
-       if (dirs[strlen(dirs)] == '/')
-           sprintf(buffer,"%s%s",dirs,fname);
-       else
-           sprintf(buffer,"%s/%s",dirs,fname);
-       if ((rfile = fopen(buffer,"r")))
-           break ;
-       dirs = strtok(NULL,":");
-    }
-    
+        if (dirs[strlen(dirs)] == '/')
+            sprintf(buffer,"%s%s",dirs,fname);
+        else
+            sprintf(buffer,"%s/%s",dirs,fname);
+        if ((rfile = fopen(buffer,"r")))
+            break ;
+        dirs = strtok(NULL,":");
+    }
+
     free(sdirs);
     if (rfile) {
     free(sdirs);
     if (rfile) {
-       fclose(rfile);
-       return strdup(buffer);
+        fclose(rfile);
+        return strdup(buffer);
     } else
     } else
-       return strdup(fname);    
+        return strdup(fname);
 }
 
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
@@ -288,30 +429,30 @@ FILE *searchDirsFopen(char *fname)
 {
     char *dirs , *sdirs;
     FILE *rfile = NULL;
 {
     char *dirs , *sdirs;
     FILE *rfile = NULL;
-    char buffer[128];
+    char buffer[1024];
 
     /* first try the current directory */
     if ((rfile = fopen(fname,"r")))
 
     /* first try the current directory */
     if ((rfile = fopen(fname,"r")))
-       return rfile;
+        return rfile;
 
     if (!ssdirl)
 
     if (!ssdirl)
-       return NULL;
+        return NULL;
     /* make a copy of the source directories */
     /* make a copy of the source directories */
-    dirs = sdirs = strdup(ssdirl);    
-   
-    /* assume that the separator is ':' 
+    dirs = sdirs = strdup(ssdirl);
+
+    /* assume that the separator is ':'
        and try for each directory in the search list */
     dirs = strtok(dirs,":");
     while (dirs) {
        and try for each directory in the search list */
     dirs = strtok(dirs,":");
     while (dirs) {
-       sprintf(buffer,"%s/%s",dirs,fname);
-       if ((rfile = fopen(buffer,"r")))
-           break ;
-       dirs = strtok(NULL,":");
+        sprintf(buffer,"%s/%s",dirs,fname);
+        if ((rfile = fopen(buffer,"r")))
+            break ;
+        dirs = strtok(NULL,":");
     }
     }
-    
+
     free(sdirs);
     return rfile ;
     free(sdirs);
     return rfile ;
-    
+
 }
 
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
@@ -323,20 +464,21 @@ srcLine **loadFile (char *name, int *nlines)
     char buffer[512];
     char *bp;
     srcLine **slines = NULL;
     char buffer[512];
     char *bp;
     srcLine **slines = NULL;
-    
-    
+
+
     if (!(mfile = searchDirsFopen(name))) {
     if (!(mfile = searchDirsFopen(name))) {
-       fprintf(stderr,"sdcdb: cannot open module %s -- use '--directory=<source directory> option\n",name);
-       return NULL;
+        fprintf(stderr,"sdcdb: cannot open module %s -- use '--directory=<source directory> option\n",name);
+        return NULL;
     }
 
     while ((bp = fgets(buffer,sizeof(buffer),mfile))) {
     }
 
     while ((bp = fgets(buffer,sizeof(buffer),mfile))) {
-       (*nlines)++;
+        (*nlines)++;
 
 
-       slines = (srcLine **)resize((void **)slines,*nlines);
+        slines = (srcLine **)resize((void **)slines,*nlines);
 
 
-       ALLOC(slines[(*nlines)-1],sizeof(srcLine));
-       slines[(*nlines)-1]->src = alloccpy(bp,strlen(bp));     
+        slines[(*nlines)-1] = Safe_calloc(1,sizeof(srcLine));
+        slines[(*nlines)-1]->src = alloccpy(bp,strlen(bp));
+        slines[(*nlines)-1]->addr= INT_MAX;
     }
 
     fclose(mfile);
     }
 
     fclose(mfile);
@@ -347,7 +489,7 @@ srcLine **loadFile (char *name, int *nlines)
 /*-----------------------------------------------------------------*/
 /* loadModules - reads the source files into module structure      */
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
 /* loadModules - reads the source files into module structure      */
 /*-----------------------------------------------------------------*/
-static void loadModules ()
+static void loadModules (void)
 {
     cdbrecs *loop;
     module *currMod;
 {
     cdbrecs *loop;
     module *currMod;
@@ -356,212 +498,254 @@ static void loadModules ()
     /* go thru the records & find out the module
        records & load the modules specified */
     for ( loop = recsRoot ; loop ; loop = loop->next ) {
     /* go thru the records & find out the module
        records & load the modules specified */
     for ( loop = recsRoot ; loop ; loop = loop->next ) {
-       
-       switch (loop->type) {
-       /* for module records do */
-       case MOD_REC: 
-           currMod = parseModule(loop->line,TRUE);
-           currModName = currMod->name ;
-           
-           currMod->cfullname = searchDirsFname(currMod->c_name);
-
-           /* load it into buffer */
-           currMod->cLines = loadFile (currMod->c_name,
-                                       &currMod->ncLines);
-
-           /* do the same for the assembler file */
-           currMod->afullname = searchDirsFname(currMod->asm_name);
-           currMod->asmLines=loadFile (currMod->asm_name,
-                                       &currMod->nasmLines);
-           break;
 
 
-       /* if this is a function record */
-       case FUNC_REC:
-           parseFunc(loop->line);
-           break;
-
-       /* if this is a structure record */
-       case STRUCT_REC:
-           parseStruct(loop->line);
-           break;
-
-       /* if symbol then parse the symbol */
-       case  SYM_REC:
-           parseSymbol(loop->line,&rs);
-           break;      
-
-       case LNK_REC:
-           parseLnkRec(loop->line);
-           break;
-       }
+        switch (loop->type) {
+        /* for module records do */
+        case MOD_REC:
+            currMod = parseModule(loop->line, TRUE);
+            currModName = currMod->name ;
+
+            currMod->cfullname = searchDirsFname(currMod->c_name);
+
+            /* load it into buffer */
+            currMod->cLines = loadFile (currMod->c_name,
+            &currMod->ncLines);
+
+            /* do the same for the assembler file */
+            currMod->afullname = searchDirsFname(currMod->asm_name);
+            currMod->asmLines=loadFile (currMod->asm_name,
+                &currMod->nasmLines);
+            break;
+
+        /* if this is a function record */
+        case FUNC_REC:
+            parseFunc(loop->line);
+            break;
+
+        /* if this is a structure record */
+        case STRUCT_REC:
+            parseStruct(loop->line);
+            break;
+
+        /* if symbol then parse the symbol */
+        case  SYM_REC:
+            parseSymbol(loop->line,&rs,2);
+            break;
+
+        case LNK_REC:
+            parseLnkRec(loop->line);
+            break;
+        }
     }
 }
 
     }
 }
 
+/*-----------------------------------------------------------------*/
+/* generate extra sets of sfr and sbit symbols                     */
+/*-----------------------------------------------------------------*/
+static void specialFunctionRegs (void)
+{
+    symbol *sym;
+    for (sym = setFirstItem(symbols);
+         sym ;
+         sym = setNextItem(symbols))
+    {
+        if ( sym->addrspace == 'I' ||
+             sym->addrspace == 'J')
+        {
+            addSet(&sfrsymbols,sym);
+        }
+    }
+}
 /*-----------------------------------------------------------------*/
 /* functionPoints - determine the execution points within a func   */
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
 /* functionPoints - determine the execution points within a func   */
 /*-----------------------------------------------------------------*/
-static void functionPoints ()
+static void functionPoints (void)
 {
     function *func;
     symbol *sym;
 {
     function *func;
     symbol *sym;
+    exePoint *ep ;
+
+    // add _main dummy for runtime env
+    if ((func = needExtraMainFunction()))
+    {
+        function *func1;
+
+        /* alloc new _main function */
+        func1 = Safe_calloc(1,sizeof(function));
+        *func1 = *func;
+        func1->sym = Safe_calloc(1,sizeof(symbol));
+        *func1->sym =  *func->sym;
+        func1->sym->name  = alloccpy("_main",5);
+        func1->sym->rname = alloccpy("G$_main$0$",10);
+        /* TODO must be set by symbol information */
+        func1->sym->addr  = 0;
+        func1->sym->eaddr = 0x2f;
+        addSet(&functions,func1);
+    }
 
     /* for all functions do */
     for ( func = setFirstItem(functions); func;
 
     /* for all functions do */
     for ( func = setFirstItem(functions); func;
-         func = setNextItem(functions)) {
-       int j ;
-       module *mod;
-       
-       sym = func->sym;
-
-#ifdef SDCDB_DEBUG     
-       printf("func '%s' has entry '%x' exit '%x'\n",
-              func->sym->name,
-              func->sym->addr,
-              func->sym->eaddr);
-#endif
-       if (!func->sym->addr && !func->sym->eaddr)
-           continue ;
-
-       /* for all source lines in the module find
-          the ones with address >= start and <= end
-          and put them in the point */
-       mod = NULL ;
-       if (! applyToSet(modules,moduleWithName,func->modName,&mod))
-           continue ;
-       func->mod = mod ;       
-       func->entryline= INT_MAX;
-       func->exitline =  0;
-       func->aentryline = INT_MAX ;
-       func->aexitline = 0;
-
-       /* do it for the C Lines first */
-       for ( j = 0 ; j < mod->ncLines ; j++ ) {
-           if (mod->cLines[j]->addr >= sym->addr &&
-               mod->cLines[j]->addr <= sym->eaddr ) {
-               
-               exePoint *ep ;
-
-               /* add it to the execution point */
-               if (func->entryline > j)
-                   func->entryline = j;
-
-               if (func->exitline < j)
-                   func->exitline = j;
-
-               ALLOC(ep,sizeof(exePoint));
-               ep->addr =  mod->cLines[j]->addr ;
-               ep->line = j;
-               ep->block= mod->cLines[j]->block;
-               ep->level= mod->cLines[j]->level;
-               addSet(&func->cfpoints,ep);
-           }
-       }
-
-       /* do the same for asm execution points */
-       for ( j = 0 ; j < mod->nasmLines ; j++ ) {
-           if (mod->asmLines[j]->addr >= sym->addr &&
-               mod->asmLines[j]->addr <= sym->eaddr ) {
-               
-               exePoint *ep ;
-               /* add it to the execution point */
-               if (func->aentryline > j)
-                   func->aentryline = j;
-
-               if (func->aexitline < j)
-                   func->aexitline = j;
-
-               /* add it to the execution point */
-               ALLOC(ep,sizeof(exePoint));
-               ep->addr =  mod->asmLines[j]->addr ;
-               ep->line = j;
-               addSet(&func->afpoints,ep);     
-           }
-       }
+          func = setNextItem(functions)) {
+        int j ;
+        module *mod;
+
+        sym = func->sym;
+
+        Dprintf(D_sdcdb, ("sdcdb: func '%s' has entry '0x%x' exit '0x%x'\n",
+                          func->sym->name,
+                          func->sym->addr,
+                          func->sym->eaddr));
+
+        if (!func->sym->addr && !func->sym->eaddr)
+            continue ;
+
+        /* for all source lines in the module find
+           the ones with address >= start and <= end
+           and put them in the point */
+        mod = NULL ;
+        if (! applyToSet(modules,moduleWithName,func->modName,&mod))
+            continue ;
+        func->mod = mod ;
+        func->entryline= INT_MAX-2;
+        func->exitline =  0;
+        func->aentryline = INT_MAX-2 ;
+        func->aexitline = 0;
+
+        /* do it for the C Lines first */
+        for ( j = 0 ; j < mod->ncLines ; j++ ) {
+            if (mod->cLines[j]->addr < INT_MAX &&
+                mod->cLines[j]->addr >= sym->addr &&
+                mod->cLines[j]->addr <= sym->eaddr ) {
+
+
+                /* add it to the execution point */
+                if (func->entryline > j)
+                    func->entryline = j;
+
+                if (func->exitline < j)
+                    func->exitline = j;
+
+                ep = Safe_calloc(1,sizeof(exePoint));
+                ep->addr =  mod->cLines[j]->addr ;
+                ep->line = j;
+                ep->block= mod->cLines[j]->block;
+                ep->level= mod->cLines[j]->level;
+                addSet(&func->cfpoints,ep);
+            }
+        }
+        /* check double line execution points of module */
+        for (ep = setFirstItem(mod->cfpoints); ep;
+             ep = setNextItem(mod->cfpoints))
+        {
+            if (ep->addr >= sym->addr &&
+                ep->addr <= sym->eaddr )
+            {
+                addSet(&func->cfpoints,ep);
+            }
+        }
+        /* do the same for asm execution points */
+        for ( j = 0 ; j < mod->nasmLines ; j++ ) {
+            if (mod->asmLines[j]->addr < INT_MAX &&
+                mod->asmLines[j]->addr >= sym->addr &&
+                mod->asmLines[j]->addr <= sym->eaddr ) {
+
+                exePoint *ep ;
+                /* add it to the execution point */
+                if (func->aentryline > j)
+                    func->aentryline = j;
+
+                if (func->aexitline < j)
+                    func->aexitline = j;
+
+                /* add it to the execution point */
+                ep = Safe_calloc(1,sizeof(exePoint));
+                ep->addr =  mod->asmLines[j]->addr ;
+                ep->line = j;
+                addSet(&func->afpoints,ep);
+            }
+        }
+        if ( func->entryline == INT_MAX-2 )
+            func->entryline = 0;
+        if ( func->aentryline == INT_MAX-2 )
+            func->aentryline = 0;
 
 #ifdef SDCDB_DEBUG
 
 #ifdef SDCDB_DEBUG
-       printf("function '%s' has the following C exePoints\n",
-              func->sym->name);
-       {
-           exePoint *ep;
-
-           for (ep = setFirstItem(func->cfpoints); ep;
-                ep = setNextItem(func->cfpoints))
-               fprintf (stdout,"{%x,%d} %s",ep->addr,ep->line,mod->cLines[ep->line]->src);
-
-           fprintf(stdout," and the following ASM exePoints\n");
-           for (ep = setFirstItem(func->afpoints); ep;
-                ep = setNextItem(func->afpoints))
-               fprintf (stdout,"{%x,%d} %s",ep->addr,ep->line,mod->asmLines[ep->line]->src);
-                   
-       }
+        if (!( D_sdcdb & sdcdbDebug))
+            continue;
+
+        Dprintf(D_sdcdb, ("sdcdb: function '%s' has the following C exePoints\n",
+                          func->sym->name));
+        {
+            exePoint *ep;
+
+            for (ep = setFirstItem(func->cfpoints); ep;
+                 ep = setNextItem(func->cfpoints))
+                Dprintf(D_sdcdb, ("sdcdb: {0x%x,%d} %s",
+                                  ep->addr,ep->line+1,mod->cLines[ep->line]->src));
+
+            Dprintf(D_sdcdb, ("sdcdb:  and the following ASM exePoints\n"));
+            for (ep = setFirstItem(func->afpoints); ep;
+                 ep = setNextItem(func->afpoints))
+                Dprintf (D_sdcdb, ("sdcdb: {0x%x,%d} %s",
+                                   ep->addr,ep->line+1,mod->asmLines[ep->line]->src));
+        }
 #endif
     }
 }
 
 #endif
     }
 }
 
-
-/*-----------------------------------------------------------------*/
-/* setEntryExitBP - set the entry & exit Break Points for functions*/
-/*-----------------------------------------------------------------*/
-DEFSETFUNC(setEntryExitBP)
-{
-    function *func = item;
-
-    if (func->sym && func->sym->addr && func->sym->eaddr) {
-
-       /* set the entry break point */
-       setBreakPoint (func->sym->addr , CODE , FENTRY , 
-                      fentryCB ,func->mod->c_name , func->entryline);
-
-       /* set the exit break point */
-       setBreakPoint (func->sym->eaddr , CODE , FEXIT  ,
-                      fexitCB  ,func->mod->c_name , func->exitline );
-    }
-
-    return 0;
-}
-
 /*-----------------------------------------------------------------*/
 /* cmdFile - load file into the debugger                           */
 /*-----------------------------------------------------------------*/
 int cmdFile (char *s,context *cctxt)
 {
     FILE *cdbFile;
 /*-----------------------------------------------------------------*/
 /* cmdFile - load file into the debugger                           */
 /*-----------------------------------------------------------------*/
 int cmdFile (char *s,context *cctxt)
 {
     FILE *cdbFile;
-    char buffer[128];
+    char buffer[1024];
     char *bp;
 
     char *bp;
 
-    while (isspace(*s)) s++;
+    s = trim_left(s);
+
     if (!*s) {
     if (!*s) {
-       fprintf(stdout,"No exec file now.\nNo symbol file now.\n");
-       return 0;
+        fprintf(stdout,"No exec file now.\nNo symbol file now.\n");
+        return 0;
     }
 
     sprintf(buffer,"%s.cdb",s);
     /* try creating the cdbfile */
     if (!(cdbFile = searchDirsFopen(buffer))) {
     }
 
     sprintf(buffer,"%s.cdb",s);
     /* try creating the cdbfile */
     if (!(cdbFile = searchDirsFopen(buffer))) {
-       fprintf(stdout,"Cannot open file\"%s\"",buffer);
-       return 0;
+        fprintf(stdout,"Cannot open file\"%s\", no symbolic information loaded\n",buffer);
+        // return 0;
     }
 
     /* allocate for context */
     }
 
     /* allocate for context */
-    ALLOC(currCtxt ,sizeof(context));
-    
-    /* readin the debug information */
-    if (!readCdb (cdbFile)) {
-       fprintf(stdout,"No symbolic information found in file %s.cdb\n",s);
-       return 0;
-    }  
-       
+    currCtxt = Safe_calloc(1,sizeof(context));
+
+    if (cdbFile) {
+        /* readin the debug information */
+        if (!readCdb (cdbFile)) {
+            fprintf(stdout,"No symbolic information found in file %s.cdb\n",s);
+          //return 0;
+        }
+    }
+
     /* parse and load the modules required */
     loadModules();
     /* parse and load the modules required */
     loadModules();
-    
+
     /* determine the execution points for this
        module */
     functionPoints();
 
     /* determine the execution points for this
        module */
     functionPoints();
 
+    /* extract known special function registers */
+    specialFunctionRegs();
+
     /* start the simulator & setup connection to it */
     /* start the simulator & setup connection to it */
-    openSimulator((char **)simArgs,nsimArgs);
+#ifdef _WIN32
+    if (INVALID_SOCKET == sock)
+#else
+    if ( sock == -1 )
+#endif
+        openSimulator((char **)simArgs,nsimArgs);
     fprintf(stdout,"%s",simResponse());
     fprintf(stdout,"%s",simResponse());
-    /* now send the filename to be loaded to the simulator */    
+    /* now send the filename to be loaded to the simulator */
     sprintf(buffer,"%s.ihx",s);
     bp=searchDirsFname(buffer);
     simLoadFile(bp);
     sprintf(buffer,"%s.ihx",s);
     bp=searchDirsFname(buffer);
     simLoadFile(bp);
@@ -570,9 +754,28 @@ int cmdFile (char *s,context *cctxt)
     /*set the break points
        required by the debugger . i.e. the function entry
        and function exit break points */
     /*set the break points
        required by the debugger . i.e. the function entry
        and function exit break points */
-    applyToSet(functions,setEntryExitBP);
+//    applyToSet(functions,setEntryExitBP);
+
+    setMainContext();
+    return 0;
+}
 
 
-    /* ad we are done */
+/*-----------------------------------------------------------------*/
+/* cmdSource - read commands from file                             */
+/*-----------------------------------------------------------------*/
+int cmdSource (char *s, context *cctxt)
+{
+    FILE *cmdfile;
+
+    s = trim(s);
+
+    if (!( cmdfile = searchDirsFopen(s)))
+    {
+        fprintf(stderr,"commandfile '%s' not found\n",s);
+        return 0;
+    }
+    commandLoop( cmdfile );
+    fclose( cmdfile );
     return 0;
 }
 
     return 0;
 }
 
@@ -580,106 +783,769 @@ int cmdFile (char *s,context *cctxt)
 /* cmdHelp - help command                                          */
 /*-----------------------------------------------------------------*/
 int cmdHelp (char *s, context *cctxt)
 /* cmdHelp - help command                                          */
 /*-----------------------------------------------------------------*/
 int cmdHelp (char *s, context *cctxt)
-{   
+{
     int i ;
     int i ;
-        
+    int endline = 999;
+    int startline = 0;
+
+    s = trim_left(s);
+
+    if (isdigit(*s)) {
+        endline = ((*s - '0') * 20) + 20;
+        if (endline > 0)
+            startline = endline - 20;
+    }
+    else if (*s)
+    {
+        for (i = 0 ; i < (sizeof(cmdTab)/sizeof(struct cmdtab)) ; i++)
+        {
+            if ((cmdTab[i].htxt) && !strcmp(cmdTab[i].cmd,s))
+            {
+                s = strrchr(cmdTab[i].htxt,'\t');
+                if ( !s )
+                    s = cmdTab[i].htxt;
+                else
+                    s++;
+                fprintf(stdout,"%s",s);
+                break;
+            }
+        }
+        return 0;
+    }
+
     for (i = 0 ; i < (sizeof(cmdTab)/sizeof(struct cmdtab)) ; i++) {
     for (i = 0 ; i < (sizeof(cmdTab)/sizeof(struct cmdtab)) ; i++) {
-       
-       /* command string matches */
-       if (cmdTab[i].htxt)
-           fprintf(stdout,"%s",cmdTab[i].htxt);
+
+        /* command string matches */
+
+        if ((cmdTab[i].htxt) && (i >= startline))
+            fprintf(stdout,"%s",cmdTab[i].htxt);
+        if (i == endline)
+            break;
     }
     }
-           
+
     return 0;
 }
 
 #define MAX_CMD_LEN 512
     return 0;
 }
 
 #define MAX_CMD_LEN 512
-char *prompt = "(sdcdb) ";
-char cmdbuff[MAX_CMD_LEN];
+static char cmdbuff[MAX_CMD_LEN];
+static int sim_cmd_mode = 0;
 
 
-/*-----------------------------------------------------------------*/
-/* interpretCmd - interpret and do the command                     */
-/*-----------------------------------------------------------------*/
+char *
+canonname(char *file)
+{
+    static char        buffer[1024];
+    if (*file == '/')
+       return file;
+    sprintf(buffer,"%s/%s", current_directory, file);
+    return buffer;
+}
+
+/*-----------------------------------------------------------------
+ interpretCmd - interpret and do the command.  Return 0 to continue,
+   return 1 to exit program.
+|-----------------------------------------------------------------*/
 int interpretCmd (char *s)
 {
     static char *pcmd = NULL;
     int i ;
     int rv = 0 ;
 int interpretCmd (char *s)
 {
     static char *pcmd = NULL;
     int i ;
     int rv = 0 ;
+
     /* if nothing & previous command exists then
        execute the previous command again */
     /* if nothing & previous command exists then
        execute the previous command again */
-    if (*s == '\n' && pcmd)
-       strcpy(s,pcmd);
+    if ((*s == '\n' || *s == '\0') && pcmd)
+        strcpy(s,pcmd);
+
     /* if previous command exists & is different
        from the current command then copy it */
     if (pcmd) {
     /* if previous command exists & is different
        from the current command then copy it */
     if (pcmd) {
-       if (strcmp(pcmd,s)) {
-           free(pcmd);
-           pcmd = strdup(s);
-       }
+        if (strcmp(pcmd,s)) {
+           free(pcmd);
+           pcmd = strdup(s);
+        }
     } else
     } else
-       pcmd = strdup(s);
-    /* lookup the command table and do the
-       task required */
-    strtok(s,"\n");
+        pcmd = strdup(s);
+
+    /* trim trailing blanks */
+    s = trim_right(s);
+
+    if (sim_cmd_mode) {
+        if (strcmp(s,".") == 0) {
+          sim_cmd_mode = 0;
+          return 0;
+        }
+        else if (s[0] == '.') {
+            /* kill the preceeding '.' and pass on as SDCDB command */
+            char *s1 = s+1;
+            char *s2 = s;
+            while (*s1 != 0)
+                *s2++ = *s1++;
+            *s2 = 0;
+        } else {
+            cmdSimulator (s, currCtxt);
+            return 0;
+        }
+    } else {
+        if (strcmp(s,".") ==0) {
+            sim_cmd_mode = 1;
+            return 0;
+        }
+    }
 
     for (i = 0 ; i < (sizeof(cmdTab)/sizeof(struct cmdtab)) ; i++) {
 
     for (i = 0 ; i < (sizeof(cmdTab)/sizeof(struct cmdtab)) ; i++) {
-       
-       /* command string matches */
-       if (strncmp(s,cmdTab[i].cmd,strlen(cmdTab[i].cmd)) == 0) {
-           if (!cmdTab[i].cmdfunc)
-               return 1;
-           rv = (*cmdTab[i].cmdfunc)(s + strlen(cmdTab[i].cmd),currCtxt);
-           
-           /* if full name then give the file name & position */
-           if (fullname && currCtxt && currCtxt->func) {
-               if (srcMode == SRC_CMODE)
-                   fprintf(stdout,"\032\032%s:%d:1\n",
-                           currCtxt->func->mod->cfullname,
-                           currCtxt->cline+1);
-               else
-                   fprintf(stdout,"\032\032%s:%d:1\n",
-                           currCtxt->func->mod->afullname,
-                           currCtxt->asmline+1); 
-           }
-           goto ret;
-       }
-    }
-   
+
+        /* command string matches */
+        if (strncmp(s,cmdTab[i].cmd,strlen(cmdTab[i].cmd)) == 0) {
+            if (!cmdTab[i].cmdfunc)
+                return 1;
+
+            rv = (*cmdTab[i].cmdfunc)(s + strlen(cmdTab[i].cmd),currCtxt);
+
+            /* if full name then give the file name & position */
+            if (fullname && showfull && currCtxt && currCtxt->func) {
+                showfull = 0;
+                if (srcMode == SRC_CMODE)
+                    fprintf(stdout,"\032\032%s:%d:1:beg:0x%08x\n",
+                        canonname(currCtxt->func->mod->cfullname),
+                        currCtxt->cline+1,currCtxt->addr);
+                else
+                    fprintf(stdout,"\032\032%s:%d:1:beg:0x%08x\n",
+                        canonname(currCtxt->func->mod->afullname),
+                        currCtxt->asmline,currCtxt->addr);
+                displayAll(currCtxt);
+            }
+            goto ret;
+        }
+    }
+
     fprintf(stdout,"Undefined command: \"%s\".  Try \"help\".\n",s);
  ret:
     return rv;
 }
 
     fprintf(stdout,"Undefined command: \"%s\".  Try \"help\".\n",s);
  ret:
     return rv;
 }
 
+static FILE *actualcmdfile=NULL ;
+static char *actualcmds=NULL;
+static int   stopcmdlist;
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
-/* commandLoop - the main command loop                             */
+/* getNextCmdLine get additional lines used by special commands    */
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
-void commandLoop()
+char *getNextCmdLine(void)
 {
 {
+    //fprintf(stderr,"getNextCmdLine() actualcmdfile=%p\n",actualcmdfile);
+    if (!actualcmdfile)
+        return NULL;
+    fprintf(stdout,">");
+    fflush(stdout);
+    if (fgets(cmdbuff,sizeof(cmdbuff),actualcmdfile) == NULL)
+    {
+        // fprintf(stderr,"getNextCmdLine() returns null\n");
+        return NULL;
+    }
+    //fprintf(stderr,"getNextCmdLine() returns: %s",cmdbuff);
+    return cmdbuff;
+}
 
 
-    while (1) {
-       fprintf(stdout,"%s",prompt);
-       fflush(stdout);
+void setCmdLine( char *cmds )
+{
+    actualcmds = cmds;
+}
+
+void stopCommandList()
+{
+    stopcmdlist = 1;
+}
+
+#ifdef HAVE_READLINE_COMPLETITION
+// helper function for doing readline completion.
+// input: toknum=index of token to find (0=first token)
+// output: *start=first character index of the token,
+//                or the index of '\0'
+//         *end=first blank character right after the token,
+//                or the index of '\0'
+// return value: 0=token not found, 1=token found
+int completionHelper_GetTokenNumber(int toknum, int *start, int *end)
+{
+    int tok_index;
+    const char *p = rl_line_buffer;
+
+    tok_index = 0;
+    *start = *end = 0;
+    while (p[*end] != 0)
+    {
+        // start = skip blanks from end
+        *start = *end;
+        while (p[*start] && isspace( p[*start] ))
+            (*start)++;
+
+        // end = skip non-blanks from start
+        *end = *start;
+        while (p[*end] && !isspace( p[*end] ))
+            (*end)++;
+
+        if (tok_index == toknum)
+            return 1;   // found
+
+        tok_index++;
+    }
+
+    return 0;   // not found
+}
+
+// helper function for doing readline completion.
+// returns the token number that we were asked to complete.
+// 0=first token (command name), 1=second token...
+int completionHelper_GetCurrTokenNumber()
+{
+    int toknum, start, end;
+
+    toknum = start = end = 0;
+    while (1)
+    {
+        if (!completionHelper_GetTokenNumber(toknum, &start, &end))
+            return toknum;
 
 
-       if (fgets(cmdbuff,sizeof(cmdbuff),stdin) == NULL)
-           break;
+        if (rl_point <= end)
+            return toknum;
 
 
-       if (interpretCmd(cmdbuff))
-           break;
-       
+        toknum++;
     }
 }
 
     }
 }
 
+// exapmle for vallist on entry:
+//          "copying\0warranty\0";
+char *completionCompleteFromStrList(const char *text, int state, char *vallist)
+{
+    static char *ptr;
+    int len;
+
+    if (state == 0)
+        ptr = vallist;
+    else
+        ptr += strlen(ptr)+1;
+
+    len = strlen(text);
+    while (*ptr)
+    {
+        if ( (len < strlen(ptr)) &&
+              !strncmp(text, ptr, len) )
+            return strdup(ptr);
+
+        ptr += strlen(ptr)+1;
+    }
+
+    return NULL;
+}
+
+// readline library completion function.
+// completes from the list of all sdcdb command.
+char *completionCommandsList(const char *text, int state)
+{
+    static int i = 0;
+
+    if (state == 0) // new completion?
+    {   // yes, only complete if this is the first token on the line.
+        int ok = 0; // try to complete this request?
+        char *p = rl_line_buffer;
+
+        // skip blanks
+        while (p && isspace(*p))
+        {
+            if (p-rl_line_buffer == rl_point)
+                ok = 1;
+            p++;
+        }
+
+        while (p && !isspace(*p))
+        {
+            if (p-rl_line_buffer == rl_point)
+                ok = 1;
+            p++;
+        }
+
+        if (p-rl_line_buffer == rl_point)
+            ok = 1;
+
+        if ( !ok )
+            return NULL; // no more completions
+
+        i = 0;  // ok, gonna complete. initialize static variable.
+    }
+    else i++;
+
+    for (; i < (sizeof(cmdTab)/sizeof(struct cmdtab)) ; i++)
+    {
+        int len = strlen(text);
+        if (len <= strlen(cmdTab[i].cmd))
+        {
+            if (strncmp(text,cmdTab[i].cmd,len) == 0)
+                return strdup(cmdTab[i].cmd);
+        }
+    }
+
+    return NULL; // no more completions
+}
+
+// readline library completion function.
+// completes from the list of symbols.
+char *completionSymbolName(const char *text, int state)
+{
+    static symbol *sy;
+
+    if (state == 0) // new completion?
+        sy = setFirstItem(symbols); // yes
+    else
+      sy = setNextItem(symbols);
+
+    for (; sy != NULL; )
+    {
+        int len = strlen(text);
+        if (len <= strlen(sy->name))
+        {
+            if (strncmp(text,sy->name,len) == 0)
+                return strdup(sy->name);
+        }
+
+        sy = setNextItem(symbols);
+    }
+    return NULL;
+}
+
+// readline library completion function.
+// completes from the list known functions.
+// module_flag - if false, ignore function module name
+//               if true, compare against module_name:fnction_name
+char *completionFunctionName(const char *text, int state, int module_flag)
+{
+    static function *f;
+
+    if (state == 0) // new completion?
+        f = setFirstItem(functions); // yes
+    else
+      f = setNextItem(functions);
+
+    for (; f != NULL; )
+    {
+        int text_len = strlen(text);
+
+        if (!module_flag)
+        {
+            if (text_len <= strlen(f->sym->name) &&
+                !strncmp(text,f->sym->name,text_len))
+                return strdup(f->sym->name);
+        }
+        else
+        {
+            int modname_len = strlen(f->mod->c_name);
+            int funcname_len = strlen(f->sym->name);
+            char *functext = malloc(modname_len+funcname_len+2);
+            //assert(functext);
+            strcpy(functext,f->mod->c_name);
+            strcat(functext,":");
+            strcat(functext,f->sym->name);
+            if (text_len <= strlen(functext) &&
+                !strncmp(text,functext,text_len))
+                return functext;
+            else
+                free(functext);
+        }
+        f = setNextItem(functions);
+    }
+    return NULL;
+}
+
+// readline library completion function.
+// completes from the list known modules.
+char *completionModuleName(const char *text, int state)
+{
+    static module *m;
+
+    if (state == 0) // new completion?
+        m = setFirstItem(modules); // yes
+    else
+      m = setNextItem(modules);
+
+    for (; m != NULL; )
+    {
+        int len = strlen(text);
+        if ( (len <= strlen(m->c_name)) &&
+             !strncmp(text,m->c_name,len) )
+            return strdup(m->c_name);
+
+        if ( (len <= strlen(m->asm_name)) &&
+             (strncmp(text,m->asm_name,len) == 0) )
+            return strdup(m->asm_name);
+
+        m = setNextItem(modules);
+    }
+    return NULL;
+}
+
+// readline completion function for "file" command
+char *completionCmdFile(const char *text, int state)
+{
+    if (state == 0)
+    {
+        if (completionHelper_GetCurrTokenNumber() != 1)
+            return NULL;
+    }
+
+    // we use filename_completion_function() from the readline library.
+    return rl_filename_completion_function(text, state);
+}
+
+// readline completion function for "source" command
+char *completionCmdSource(const char *text, int state)
+{
+    return completionCmdFile(text, state);
+}
+
+// readline completion function for "info" command
+char *completionCmdInfo(const char *text, int state)
+{
+    static char *ptr;
+
+    if (state == 0)
+    {
+        if (completionHelper_GetCurrTokenNumber() != 1)
+            return NULL;
+    }
+
+    return completionCompleteFromStrList(text, state,
+            "break\0stack\0frame\0registers\0all-registers\0"
+            "line\0source\0functions\0symbols\0variables\0");
+}
+
+// readline completion function for "show" command
+char *completionCmdShow(const char *text, int state)
+{
+    static char *ptr;
+
+    if (state == 0)
+    {
+        if (completionHelper_GetCurrTokenNumber() != 1)
+            return NULL;
+    }
+    return completionCompleteFromStrList(text, state, "copying\0warranty\0");
+}
+
+// readline completion function for "la" command
+char *completionCmdListSymbols(const char *text, int state)
+{
+    static char *ptr;
+
+    if (state == 0)
+    {
+        if (completionHelper_GetCurrTokenNumber() != 1)
+            return NULL;
+    }
+    return completionCompleteFromStrList(text, state, "v1\0v2\0");
+}
+
+char *completionCmdPrintType(const char *text, int state)
+{
+    if (state == 0)
+    {
+        if (completionHelper_GetCurrTokenNumber() != 1)
+            return NULL;
+    }
+    return completionSymbolName(text, state);
+}
+
+char *completionCmdPrint(const char *text, int state)
+{
+    if (state == 0)
+    {
+        int i = completionHelper_GetCurrTokenNumber();
+        if (i != 1 && i != 2)
+            return NULL;
+    }
+    return completionSymbolName(text, state);
+}
+
+char *completionCmdDelUserBp(const char *text, int state)
+{
+    static breakp *bp;
+    static int k;
+
+    if (state == 0)
+    {
+        if (completionHelper_GetCurrTokenNumber() != 1)
+            return NULL;
+
+        if (!userBpPresent)
+            return NULL;
+
+        bp = hTabFirstItem(bptable,&k);
+    }
+    else
+        bp = hTabNextItem(bptable,&k);
+
+    for ( ; bp ; bp = hTabNextItem(bptable,&k))
+    {
+        if (bp->bpType == USER || bp->bpType == TMPUSER)
+        {
+            char buff[20];
+            sprintf(buff, "%d", bp->bpnum);
+            return strdup(buff);
+        }
+    }
+
+    return NULL;
+}
+
+// readline completion function for "undisplay" command
+char *completionCmdUnDisplay(const char *text, int state)
+{
+    static dsymbol *dsym;
+
+    if (state == 0)
+    {
+        if (completionHelper_GetCurrTokenNumber() != 1)
+            return NULL;
+        dsym = setFirstItem(dispsymbols);
+    }
+
+    if (dsym)
+    {
+        char buff[30];
+        sprintf(buff, "%d", dsym->dnum);
+        dsym = setNextItem(dispsymbols);
+        return strdup(buff);
+    }
+    return NULL;
+}
+
+char *completionCmdSetUserBp(const char *text, int state)
+{
+    static int internal_state; // 0=calling completionFunctionName(text, state, 0)
+                               // 1=calling completionFunctionName(text, 1, 1)
+    if (state == 0)
+    {
+        if (completionHelper_GetCurrTokenNumber() != 1)
+            return NULL;
+
+        internal_state = 0;
+    }
+    if (internal_state == 0)
+    {
+        char *p = completionFunctionName(text, state, 0);
+        if (p)
+            return p;
+        internal_state = 1;
+        return completionFunctionName(text, 0, 1);
+    }
+    else
+    {
+        return completionFunctionName(text, 1, 1);
+    }
+}
+
+char *completionCmdSetOption(const char *text, int state)
+{
+    static char *ptr;
+    static int currtok;
+
+    if (state == 0)
+    {
+        int start,end;
+
+        currtok = completionHelper_GetCurrTokenNumber();
+
+        if (currtok == 2 || currtok == 3)
+        {
+            // make sure token 1 == "variable"
+            completionHelper_GetTokenNumber(1, &start, &end);
+            if (end - start != 8 ||
+                strncmp(rl_line_buffer+start,"variable",8))
+                return NULL;
+        }
+        else if (currtok != 1)
+        {
+            return NULL;
+        }
+    }
+
+    switch (currtok)
+    {
+        case 1:
+            return completionCompleteFromStrList(text, state,
+#ifdef SDCDB_DEBUG
+                "debug\0"
+#endif
+                "srcmode\0listsize\0variable\0");
+        case 2:
+            return completionSymbolName(text, state);
+
+        case 3:
+            return completionCompleteFromStrList(text, state, "=\0");
+    }
+}
+
+// our main readline completion function
+// calls the other completion functions as needed.
+char *completionMain(const char *text, int state)
+{
+    static rl_compentry_func_t *compl_func;
+    int i, start, end, len;
+
+    if (state == 0) // new completion?
+    {
+        compl_func = NULL;
+
+        if (completionHelper_GetCurrTokenNumber() == 0)
+            compl_func = &completionCommandsList;
+        else
+        {   // not completing first token, find the right completion
+            // function according to the first token the user typed.
+            completionHelper_GetTokenNumber(0, &start, &end);
+            len = end-start;
+
+            for (i=0; i < (sizeof(cmdTab)/sizeof(struct cmdtab)) ; i++)
+            {
+                if (!strncmp(rl_line_buffer+start,cmdTab[i].cmd,len) &&
+                    cmdTab[i].cmd[len] == '\0')
+                {
+                    compl_func = cmdTab[i].completion_func;
+                    break;
+                }
+            }
+        }
+        if (!compl_func)
+            return NULL;
+    }
+
+    return (*compl_func)(text,state);
+}
+#endif  /* HAVE_READLINE_COMPLETITION */
+
+/*-----------------------------------------------------------------*/
+/* commandLoop - the main command loop or loop over command file   */
+/*-----------------------------------------------------------------*/
+static void commandLoop(FILE *cmdfile)
+{
+    char *line, save_ch, *s;
+    char *line_read;
+
+#ifdef HAVE_LIBREADLINE
+    FILE *old_rl_instream, *old_rl_outstream;
+    actualcmdfile = cmdfile;
+
+#ifdef HAVE_READLINE_COMPLETITION
+    rl_completion_entry_function = completionMain;
+#endif  /* HAVE_READLINE_COMPLETITION */
+    rl_readline_name = "sdcdb"; // Allow conditional parsing of the ~/.inputrc file.
+
+    // save readline's input/output streams
+    // this is done to support nested calls to commandLoop()
+    // i wonder if it works...
+    old_rl_instream = rl_instream;
+    old_rl_outstream = rl_outstream;
+
+    // set new streams for readline
+    if ( cmdfile == stdin )
+        rl_instream = rl_outstream = NULL;  // use stdin/stdout pair
+    else
+        rl_instream = rl_outstream = cmdfile;
+
+      while (1)
+      {
+          if ( cmdfile == stdin )
+          {
+              if (sim_cmd_mode)
+                  line_read = (char*)readline ("(sim) ");
+              else
+                  line_read = (char*)readline ("(sdcdb) ");
+          }
+          else
+              line_read = (char*)readline ("");
+
+        if (line_read)
+        {
+            /* If the line has any text in it,
+               save it on the history. */
+            if (line_read && *line_read)
+              add_history (line_read);
+
+             // FIX: readline returns malloced string.
+             //   should check the source to verify it can be used
+             //    directly. for now - just copy it to cmdbuff.
+            strcpy(cmdbuff,line_read);
+#if defined(_WIN32) || defined(HAVE_RL_FREE)
+            rl_free(line_read);
+#else
+            free(line_read);
+#endif
+            line_read = NULL;
+        }
+        else
+            break;  // EOF
+#else
+    actualcmdfile = cmdfile;
+
+    while (1)
+    {
+        if ( cmdfile == stdin )
+        {
+            if (sim_cmd_mode)
+                printf("(sim) ");
+            else
+                fprintf(stdout,"(sdcdb) ");
+            fflush(stdout);
+        }
+        //fprintf(stderr,"commandLoop actualcmdfile=%p cmdfile=%p\n",
+        //        actualcmdfile,cmdfile);
+        if (fgets(cmdbuff,sizeof(cmdbuff),cmdfile) == NULL)
+            break;
+#endif  /* HAVE_LIBREADLINE */
+
+          if (interpretCmd(cmdbuff))
+              break;
+
+        while ( actualcmds )
+        {
+            strcpy(cmdbuff,actualcmds);
+            actualcmds = NULL;
+            stopcmdlist= 0;
+            for ( line = cmdbuff; *line ; line = s )
+            {
+                if ( (s=strchr(line ,'\n')))
+                {
+                    save_ch = *++s;
+                    *s = '\0';
+                }
+                else
+                {
+                    s += strlen( line );
+                    save_ch = '\0';
+                }
+                if (interpretCmd( line ))
+                {
+                    *s = save_ch;
+                    break;
+                }
+                *s = save_ch;
+                if ( stopcmdlist )
+                    break;
+            }
+        }
+    }
+#ifdef HAVE_LIBREADLINE
+    // restore readline's input/output streams
+    rl_instream = old_rl_instream;
+    rl_outstream = old_rl_outstream;
+#endif  /* HAVE_LIBREADLINE */
+}
+
 /*-----------------------------------------------------------------*/
 /* printVersionInfo - print the version information                */
 /*-----------------------------------------------------------------*/
 static void printVersionInfo()
 {
     fprintf(stdout,
 /*-----------------------------------------------------------------*/
 /* printVersionInfo - print the version information                */
 /*-----------------------------------------------------------------*/
 static void printVersionInfo()
 {
     fprintf(stdout,
-           "SDCDB is free software and you are welcome to distribute copies of it\n"
-           "under certain conditions; type \"show copying\" to see the conditions.\n"
-           "There is absolutely no warranty for SDCDB; type \"show warranty\" for details.\n"
-           "SDCDB 0.8 . Copyright (C) 1999 Sandeep Dutta (sandeep.dutta@usa.net)\n"
-           "Type ? for help\n");
+        "SDCDB is free software and you are welcome to distribute copies of it\n"
+        "under certain conditions; type \"show copying\" to see the conditions.\n"
+        "There is absolutely no warranty for SDCDB; type \"show warranty\" for details.\n"
+        "SDCDB 0.8 . Copyright (C) 1999 Sandeep Dutta (sandeep.dutta@usa.net)\n"
+        "Type ? for help\n");
 
 }
 
 
 }
 
@@ -690,92 +1556,200 @@ static void parseCmdLine (int argc, char **argv)
 {
     int i ;
     char *filename = NULL;
 {
     int i ;
     char *filename = NULL;
-    char buffer[100];
+    int passon_args_flag = 0;  /* if true, pass on args to simulator */
+
+    Dprintf(D_sdcdb, ("sdcdb: parseCmdLine\n"));
+    contsim=0;
+
     for ( i = 1; i < argc ; i++) {
     for ( i = 1; i < argc ; i++) {
-       fprintf(stdout,"%s\n",argv[i]);
-       
-       /* if this is an option */
-       if (argv[i][0] == '-') {
-           
-           /* if directory then mark directory */
-           if (strncmp(argv[i],"--directory=",12) == 0) {
-               if (!ssdirl)
-                   ssdirl = &argv[i][12];
-               else {
-                   char *p = malloc(strlen(ssdirl)+strlen(&argv[i][12])+2);
-                   strcat(strcat(strcpy(p,&argv[i][12]),":"),ssdirl);
-                   ssdirl = p;
-               }
-               continue;
-           }
-           
-           if (strncmp(argv[i],"-fullname",9) == 0) {
-               fullname = TRUE;
-               continue;
-           }
-           
-           if (strcmp(argv[i],"-cd") == 0) {
-               i++;
-               chdir(argv[i]);
-               continue;
-           }
-           
-           if (strncmp(argv[i],"-cd=",4) == 0) {
-               chdir(argv[i][4]);
-               continue;
-           }
-           
-           /* the simulator arguments */
-
-           /* cpu */
-           if (strcmp(argv[i],"-t") == 0 ||
-               strcmp(argv[i],"-cpu") == 0) {
-
-                   simArgs[nsimArgs++] = "-t";          
-                   simArgs[nsimArgs++] = strdup(argv[++i]);
-                   continue ;
-           }
-           
-           /* XTAL Frequency */
-           if (strcmp(argv[i],"-X") == 0 ||
-               strcmp(argv[i],"-frequency") == 0) {
-                   simArgs[nsimArgs++] = "-X";
-                   simArgs[nsimArgs++] = strdup(argv[++i]);
-                   continue ;
-           }
-
-           /* serial port */
-           if (strcmp(argv[i],"-s") == 0) {
-                   simArgs[nsimArgs++] = "-s";         
-                   simArgs[nsimArgs++] = strdup(argv[++i]);
-                   continue ;
-           }
-
-           if (strcmp(argv[i],"-S") == 0) {
-                   simArgs[nsimArgs++] = "-s";         
-                   simArgs[nsimArgs++] = strdup(argv[++i]);
-                   continue ;
-           }   
-
-           fprintf(stderr,"unknown option %s --- ignored\n",
-                   argv[i]);
-       } else {
-           /* must be file name */
-           if (filename) {
-               fprintf(stderr,"too many filenames .. parameter '%s' ignored\n",
-                       argv[i]);
-               continue ;
-           }
-
-           filename = strtok(argv[i],".");
-
-       }           
-    }
-    
+        //fprintf(stdout,"%s\n",argv[i]);
+
+        if (passon_args_flag) { /* if true, pass on args to simulator */
+            simArgs[nsimArgs++] = strdup(argv[i]);
+            continue;
+        }
+
+        /* if this is an option */
+        if (argv[i][0] == '-') {
+
+            /* if directory then mark directory */
+            if (strncmp(argv[i],"--directory=",12) == 0) {
+                if (!ssdirl)
+                    ssdirl = &argv[i][12];
+                else {
+                    char *p = Safe_malloc(strlen(ssdirl)+strlen(&argv[i][12])+2);
+                    strcat(strcat(strcpy(p,&argv[i][12]),":"),ssdirl);
+                    ssdirl = p;
+                }
+                continue;
+            }
+
+            if (strncmp(argv[i],"-fullname",9) == 0) {
+                fullname = TRUE;
+                continue;
+            }
+
+            if (strcmp(argv[i],"-cd") == 0) {
+                i++;
+                chdir(argv[i]);
+                 continue;
+            }
+
+            if (strncmp(argv[i],"-cd=",4) == 0) {
+                chdir(argv[i]+4);
+                continue;
+            }
+
+#ifdef SDCDB_DEBUG
+            if (strncmp(argv[i],"-d=",3) == 0) {
+                sdcdbDebug = strtol(&argv[i][3],0,0);
+                continue;
+            }
+#endif
+            if (strncmp(argv[i],"-contsim",8) == 0) {
+                contsim=1;
+                continue;
+            }
+            if (strncmp(argv[i],"-q",2) == 0) {
+                continue;
+            }
+
+            /* model string */
+            if (strncmp(argv[i],"-m",2) == 0) {
+                strncpy(model_str, &argv[i][2], 15);
+                if (strcmp(model_str,"avr") == 0)
+                    simArgs[0] = "savr";
+                else if (strcmp(model_str,"xa") == 0)
+                    simArgs[0] = "sxa";
+                else if (strcmp(model_str,"z80") == 0)
+                    simArgs[0] = "sz80";
+                continue ;
+            }
+
+            /* -z all remaining options are for simulator */
+            if (strcmp(argv[i],"-z") == 0) {
+                passon_args_flag = 1;
+                continue ;
+            }
+
+            /* the simulator arguments */
+
+            /* cpu */
+            if (strcmp(argv[i],"-t") == 0 ||
+                strcmp(argv[i],"-cpu") == 0) {
+
+                simArgs[nsimArgs++] = "-t";
+                simArgs[nsimArgs++] = strdup(argv[++i]);
+                continue ;
+            }
+
+            /* XTAL Frequency */
+            if (strcmp(argv[i],"-X") == 0 ||
+                strcmp(argv[i],"-frequency") == 0) {
+                simArgs[nsimArgs++] = "-X";
+                simArgs[nsimArgs++] = strdup(argv[++i]);
+                continue ;
+            }
+
+            /* serial port */
+            if ( (strcmp(argv[i],"-S") == 0) ||
+                (strcmp(argv[i],"-s") == 0) ||
+                (strcmp(argv[i],"-T") == 0) ||
+                (strcmp(argv[i],"--tty") == 0)) {
+               simArgs[nsimArgs++] = "--tty";
+                simArgs[nsimArgs++] = strdup(argv[++i]);
+                continue ;
+            }
+
+            /* network serial port */
+            if ( (strcmp(argv[i],"-k") == 0)) {
+                simArgs[nsimArgs++] = strdup(argv[i]);
+                simArgs[nsimArgs++] = strdup(argv[++i]);
+                continue ;
+            }
+
+            fprintf(stderr,"unknown option %s --- ignored\n",
+                argv[i]);
+
+        } else {
+            /* must be file name */
+            if (filename) {
+                fprintf(stderr,"too many filenames .. parameter '%s' ignored\n",
+                    argv[i]);
+                continue ;
+            }
+
+            if (-1 != access(argv[i], 0)) {
+                /* file exists: strip the cdb or ihx externsion */
+                char *p = strrchr(argv[i], '.');
+
+                if (NULL != p &&
+                    (0 == strcmp(p, ".cdb") || 0 == strcmp(p, ".ihx")))
+                    *p = '\0';
+            }
+            filename = argv[i];
+
+        }
+    }
+
     if (filename)
     if (filename)
-       cmdFile(filename,NULL);
+        cmdFile(filename,NULL);
 }
 }
-  
+
+/*-----------------------------------------------------------------*/
+/* setsignals -  catch some signals                                */
+/*-----------------------------------------------------------------*/
+#include <signal.h>
+static void
+bad_signal(int sig)
+{
+    if ( simactive )
+        closeSimulator();
+    exit(1);
+}
+
+static void
+sigintr(int sig)
+{
+    /* may be interrupt from user: stop debugger and also simulator */
+    userinterrupt = 1;
+    if ( !nointerrupt )
+        sendSim("stop\n");
+}
+
+#ifndef _WIN32
+/* the only child can be the simulator */
+static void sigchld(int sig)
+{
+    /* the only child can be the simulator */
+    int status, retpid;
+    retpid = wait ( &status );
+    /* if ( retpid == simPid ) */
+    simactive = 0;
+}
+#endif
+
+static void
+setsignals()
+{
+    signal(SIGINT , sigintr );
+    signal(SIGABRT, bad_signal);
+    signal(SIGTERM, bad_signal);
+
+#ifndef _WIN32
+    signal(SIGHUP , SIG_IGN);
+    signal(SIGCONT, SIG_IGN);
+    signal(SIGCHLD, sigchld );
+
+    signal(SIGALRM, bad_signal);
+    //signal(SIGFPE,  bad_signal);
+    //signal(SIGILL,  bad_signal);
+    signal(SIGPIPE, bad_signal);
+    signal(SIGQUIT, bad_signal);
+    //signal(SIGSEGV, bad_signal);
+#endif
+}
+
 /*-----------------------------------------------------------------*/
 /* main -                                                          */
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
 /* main -                                                          */
 /*-----------------------------------------------------------------*/
@@ -783,10 +1757,18 @@ static void parseCmdLine (int argc, char **argv)
 int main ( int argc, char **argv)
 {
     printVersionInfo();
 int main ( int argc, char **argv)
 {
     printVersionInfo();
+    printf("WARNING: SDCDB is EXPERIMENTAL.\n");
+
+    current_directory = get_current_dir_name();
+    simArgs[nsimArgs++] = "ao-dbg";
+    simArgs[nsimArgs++] = "-P";
+    simArgs[nsimArgs++] = "-r 9756";
     /* parse command line */
     /* parse command line */
+
+    setsignals();
     parseCmdLine(argc,argv);
 
     parseCmdLine(argc,argv);
 
-    commandLoop();
-    
+    commandLoop(stdin);
+
     return 0;
 }
     return 0;
 }