* sim/ucsim/gui.src/serio.src/main.cc: Fixed unconditional use of
[fw/sdcc] / debugger / mcs51 / cmd.c
index da4a2e45214e772659a2d03dadd4fa6834c1e6c1..b0a8a937707d429caf8938d9da2d918bc2639c4b 100644 (file)
@@ -30,7 +30,8 @@
 #include "newalloc.h"
 
 /* default number of lines to list out */
-int listLines = 16;
+#define LISTLINES 10
+static int listlines = LISTLINES;
 
 /* mainly used to retain a reference to the active module being
    listed.  May be used as a general context for other commands if
@@ -328,12 +329,14 @@ static char *warranty=
 #endif
 
 static void printTypeInfo(link *);
-static void printValAggregates (symbol *,link *,char,unsigned int);
-static void setSymValue(symbol *sym, char *val, context *cctxt);
+static void printValAggregates (symbol *,link *,char,unsigned int,int);
+static  int printOrSetSymValue (symbol *sym, context *cctxt, 
+                                int flg, int dnum, int fmt, 
+                                char *rs, char *val, char cmp);
 
 int srcMode = SRC_CMODE ;
 static set  *dispsymbols = NULL   ; /* set of displayable symbols */
-
+static int currentFrame = 0;        /* actual displayed frame     */
 /*-----------------------------------------------------------------*/
 /* funcWithName - returns function with name                       */
 /*-----------------------------------------------------------------*/
@@ -354,10 +357,33 @@ DEFSETFUNC(funcWithName)
     return 0;
 }
 
+/*-----------------------------------------------------------------*/
+/* symWithAddr - look for symbol with sfr / sbit address           */
+/*-----------------------------------------------------------------*/
+DEFSETFUNC(symWithAddr)
+{
+    symbol *sym = item;
+    V_ARG(unsigned long,laddr);
+    V_ARG(int    ,laddrspace);
+    V_ARG(symbol **,rsym);
+
+    if (*rsym)
+        return 0;
+
+    if ( sym->addr == laddr &&
+         sym->addrspace == laddrspace ) 
+    {
+        *rsym = sym;
+        return 1;
+    }
+
+    return 0;
+}
+
 /*-----------------------------------------------------------------*/
 /* setBPatModLine - set break point at the line specified for the  */
 /*-----------------------------------------------------------------*/
-static void setBPatModLine (module *mod, int line)
+static void setBPatModLine (module *mod, int line, char bpType )
 {
   int next_line;
 
@@ -380,7 +406,7 @@ static void setBPatModLine (module *mod, int line)
          next_line++ ) {
        if (srcMode == SRC_CMODE) {
            if (mod->cLines[next_line]->addr) {
-               setBreakPoint (mod->cLines[next_line]->addr, CODE, USER
+               setBreakPoint (mod->cLines[next_line]->addr, CODE, bpType
                               userBpCB, mod->c_name, next_line);
                return;
 //             break;
@@ -388,7 +414,7 @@ static void setBPatModLine (module *mod, int line)
        }
        else {
           if (mod->asmLines[next_line]->addr) {
-              setBreakPoint (mod->asmLines[next_line]->addr, CODE, USER
+              setBreakPoint (mod->asmLines[next_line]->addr, CODE, bpType
                              userBpCB, mod->asm_name, next_line);
                return;
 //            break;
@@ -459,8 +485,16 @@ DEFSETFUNC(moduleLineWithAddr)
         {
             *rmod = mod ;
             if (line )
-                *line = mod->ncLines;
-            return 1;
+            {
+                *line = 0;
+                for ( i=0; i < mod->ncLines; i++ ) 
+                {
+                    if ( mod->cLines[i]->addr > addr)
+                        break;
+                    *line = i;
+                }
+                return 1;
+            }
         }
     }
 
@@ -612,18 +646,17 @@ DEFSETFUNC(lineNearAddr)
 /*-----------------------------------------------------------------*/
 /* discoverContext - find out the current context of the bp        */
 /*-----------------------------------------------------------------*/
-context *discoverContext (unsigned addr)
+context *discoverContext (unsigned addr, function *func)
 {
-    function *func = NULL;
     module   *mod  = NULL;
     int line = 0;
 
     /* find the function we are in */
-    if (!applyToSet(functions,funcInAddr,addr,&func)) {
-        if (!applyToSet(functions,funcWithName,"main") ||
-            !applyToSet(modules,moduleLineWithAddr,addr,&mod,&line))
+    if (!func && !applyToSet(functions,funcInAddr,addr,&func)) {
+        if (!applyToSet(functions,funcWithName,"main",&func) ||
+            !applyToSet(modules,moduleLineWithAddr,addr,&mod,NULL))
         {
-            fprintf(stderr, "Error?:discoverContext: cannot apply to set!\n");
+            fprintf(stderr, "Error?:discoverContext: cannot apply addr 0x%x\n",addr);
             return NULL;
         }
         currCtxt->func = func;
@@ -638,7 +671,10 @@ context *discoverContext (unsigned addr)
         currCtxt->modName = func->modName;
     
         /* find the c line number */
-        if(applyToSet(func->cfpoints,lineNearAddr,addr,
+        if(applyToSet(func->cfpoints,lineAtAddr,addr,
+                  &line,&currCtxt->block,&currCtxt->level)) 
+            currCtxt->cline = func->lline = line;
+        else if(applyToSet(func->cfpoints,lineNearAddr,addr,
                   &line,&currCtxt->block,&currCtxt->level)) 
             currCtxt->cline = func->lline = line;
         else
@@ -664,8 +700,7 @@ void simGo (unsigned int gaddr)
     unsigned int addr ;
     context *ctxt;
     int rv;
-    static int initial_break_flag = 0;
-
+    stopCommandList();
  top:    
     if ( userinterrupt )
     {
@@ -677,7 +712,8 @@ void simGo (unsigned int gaddr)
     /* got the pc for the break point now first
        discover the program context i.e. module, function 
        linenumber of the source etc, etc etc */
-    ctxt = discoverContext (addr);
+    currentFrame = 0; 
+    ctxt = discoverContext (addr, NULL);
     
     /* dispatch all the break point call back functions */
     rv = dispatchCB (addr,ctxt);    
@@ -687,42 +723,71 @@ void simGo (unsigned int gaddr)
        non-zero if an user break point has been hit
        if not then we continue with the execution 
        of the program */
-    if (!rv) {
-      if (!initial_break_flag) {
-        initial_break_flag = 1;  // kludge to stop only at first run
-        fprintf(stdout, "Stopping at entry.  You can now list and set breakpoints\n");
-      }
-      else {
-               gaddr = -1;
-               goto top ;
-      }
-
-// notes: kpb
-// I took this out, after running "run" it would just keep re-running
-// even after a lot of break points hit.  For some reason above code
-// not triggering(dispatchCB).  This seems to be by design, startup adds
-// a bunch of breakpoints-but they are not USER breakpoints.  Perhaps the
-// debugger changed with its implementation of "go"("run").  It seems we
-// need to add a "next" or "step" followed by a "run"...
-// I added a "step" in simi.c when we want a resume function, this seems
-// to work.
-
-// still there is question of how do we stop it initially, since
-// it must be started before it can get a context.  If so, we would
-// want it to just run up to an initial entry point you'd think...
-// I don't see why we can't set breakpoints before an initial run,
-// this does not seem right to me.
-
-// line #'s are a bit off too.
-
-#if 0
-       gaddr = -1;
-       goto top ;
-#endif
+    if (!rv) 
+    {
+               if ( gaddr == 0 )
+            gaddr = -1;
+               if ( gaddr == -1 || doingSteps == 1 )
+            goto top ;
     }
     
 }
 
+/*-----------------------------------------------------------------*/
+/* preparePrint - common parse function for                        */
+/*                output, print and display                        */
+/*-----------------------------------------------------------------*/
+static char *preparePrint(char *s, context *cctxt, int *fmt, symbol **sym)
+{
+    char *bp = s+strlen(s) -1;
+    char save_ch ;
+
+    *fmt = FMT_NON;
+    *sym = NULL;
+
+    while (isspace(*s)) s++;
+    if (!*s) 
+        return (char *)0;
+
+    while (isspace(*bp)) bp--;
+    bp++ ;
+    *bp = '\0';
+
+    if ( *s == '/' )
+    {
+        /* format of printout */
+        switch ( *++s )
+        {
+            case 'x':
+                *fmt = FMT_HEX ;
+                break;
+            case 'o':
+                *fmt = FMT_OCT ;
+                break;
+            default:
+            case 'd':
+                *fmt = FMT_DEZ ;
+                break;
+            case 't':
+                *fmt = FMT_BIN ;
+                break;
+        }
+        s++;
+        while (isspace(*s)) s++;
+    }
+    for ( bp = s; *bp && ( isalnum( *bp ) || *bp == '_'); bp++ );
+    save_ch = *bp;
+    if ( *bp )
+        *bp = '\0';
+
+    *sym = symLookup(s,cctxt);
+    *bp = save_ch;
+
+    if ( ! *sym )
+        fprintf(stdout,"No symbol \"%s\" in current context.\n", s);
+    return bp;
+}
+
 static int printAsmLine( function *func, module *m, long saddr, long eaddr)
 {
     int i,j,delta;
@@ -879,10 +944,7 @@ int cmdDisasmF(char *s, context *cctxt)
     return cmdDisasm( s, cctxt, 2);
 }
 
-/*-----------------------------------------------------------------*/
-/* cmdSetUserBp - set break point at the user specified location   */
-/*-----------------------------------------------------------------*/
-int cmdSetUserBp (char *s, context *cctxt)
+static int commonSetUserBp(char *s, context *cctxt, char bpType)
 {
     char *bp ;
     function *func = NULL;
@@ -916,12 +978,13 @@ int cmdSetUserBp (char *s, context *cctxt)
 
        /* if current context is known */
        if (cctxt->func) {
+        Dprintf(D_break, ("commonSetUserBp: a) cctxtaddr:%x \n",cctxt->addr));
            if (srcMode == SRC_CMODE)
                /* set the break point */
-               setBreakPoint ( cctxt->addr , CODE , USER , userBpCB ,
+               setBreakPoint ( cctxt->addr , CODE , bpType , userBpCB ,
                                cctxt->func->mod->c_name, cctxt->cline);
            else
-               setBreakPoint ( cctxt->addr , CODE , USER , userBpCB ,
+               setBreakPoint ( cctxt->addr , CODE , bpType , userBpCB ,
                                cctxt->func->mod->asm_name, cctxt->asmline);
                
        }
@@ -944,7 +1007,8 @@ int cmdSetUserBp (char *s, context *cctxt)
             }
             else
             {
-                setBreakPoint ( braddr , CODE , USER , userBpCB ,
+                Dprintf(D_break, ("commonSetUserBp: g) addr:%x \n",braddr));
+                setBreakPoint ( braddr , CODE , bpType , userBpCB ,
                             modul->c_name,line);
             }
             goto ret ;
@@ -952,17 +1016,20 @@ int cmdSetUserBp (char *s, context *cctxt)
                else
         {
             int line = func->exitline;
-            applyToSet(func->cfpoints,lineNearAddr,braddr,&line,NULL,NULL);
-            setBreakPoint ( braddr , CODE , USER , userBpCB ,
+            if ( !applyToSet(func->cfpoints,lineAtAddr,braddr,
+                                  &line,NULL,NULL))
+                applyToSet(func->cfpoints,lineNearAddr,braddr,&line,NULL,NULL);
+            setBreakPoint ( braddr , CODE , bpType , userBpCB ,
                             func->mod->c_name,line);
         }
        goto ret ;
     }
     /* case b) lineno */
     /* check if line number */
-    if (isdigit(*s)) {
+    if ( !strchr(s,':') && isdigit(*s)) {
        /* get the lineno */
-       int line = atoi(s);
+       int line = atoi(s) -1;
+    Dprintf(D_break, ("commonSetUserBp: b) line:%d \n",line));
 
        /* if current context not present then we must get the module
           which has main & set the break point @ line number provided
@@ -974,12 +1041,12 @@ int cmdSetUserBp (char *s, context *cctxt)
                if (!applyToSet(functions,funcWithName,"main"))
                    fprintf(stderr,"Function \"main\" not defined.\n");
                else 
-                   setBPatModLine(func->mod,line);
+                   setBPatModLine(func->mod,line, bpType);
            } else 
-               setBPatModLine(cctxt->func->mod,line);
+               setBPatModLine(cctxt->func->mod,line, bpType);
        } else {
                if (list_mod) {
-                       setBPatModLine(list_mod,line);
+                       setBPatModLine(list_mod,line, bpType);
                } else {
                  fprintf(stdout,"Sdcdb fails to have module symbol context at %d\n", __LINE__);
                }
@@ -1006,9 +1073,9 @@ int cmdSetUserBp (char *s, context *cctxt)
        }
                
        /* case c) filename:lineno */
-       if (isdigit(*(bp +1))) {                    
-        
-           setBPatModLine (mod,atoi(bp+1));        
+       if (isdigit(*(bp +1))) {                         
+        Dprintf(D_break, ("commonSetUserBp: c) line:%d \n",atoi(bp+1)));
+           setBPatModLine (mod,atoi(bp+1)-1,bpType);       
            goto ret;
            
        }
@@ -1016,27 +1083,141 @@ int cmdSetUserBp (char *s, context *cctxt)
        if (!applyToSet(functions,funcWithNameModule,bp+1,s,&func)) 
            fprintf(stderr,"Function \"%s\" not defined.\n",bp+1); 
        else        
+        Dprintf(D_break, ("commonSetUserBp: d) \n"));
            setBPatModLine (mod,
                            (srcMode == SRC_CMODE ? 
                             func->entryline :
-                            func->aentryline));
+                            func->aentryline),bpType);
        
        goto ret;
     }
             
     /* case e) function */
+    Dprintf(D_break, ("commonSetUserBp: e) \n"));
     if (!applyToSet(functions,funcWithName,s,&func))
        fprintf(stderr,"Function \"%s\" not defined.\n",s); 
     else
        setBPatModLine(func->mod,
                       (srcMode == SRC_CMODE ?
                        func->entryline :
-                       func->aentryline));
+                       func->aentryline),bpType);
 
  ret:    
     return 0;
 }
 
+/*-----------------------------------------------------------------*/
+/* cmdSetTmpUserBp - settempory break point at the user specified location   */
+/*-----------------------------------------------------------------*/
+int cmdSetTmpUserBp (char *s, context *cctxt)
+{
+    return commonSetUserBp(s, cctxt, TMPUSER );
+}
+
+/*-----------------------------------------------------------------*/
+/* cmdSetUserBp - set break point at the user specified location   */
+/*-----------------------------------------------------------------*/
+int cmdSetUserBp (char *s, context *cctxt)
+{
+    return commonSetUserBp(s, cctxt, USER );
+}
+
+/*-----------------------------------------------------------------*/
+/* cmdJump - set program counter                                   */
+/*-----------------------------------------------------------------*/
+int cmdJump (char *s, context *cctxt)
+{
+    char *bp ;
+    function *func = NULL;
+    if (STACK_EMPTY(callStack)) 
+    {
+        fprintf(stdout,"The program is not running.\n");
+        return 0;
+    } 
+
+    /* white space skip */
+    while (*s && isspace(*s)) s++;
+    
+    /* null terminate it after stripping trailing blanks*/
+    bp = s + strlen(s);
+    while (bp != s && isspace(*bp)) bp--;
+    *bp = '\0';
+    if (! *s ) 
+    {
+        fprintf(stdout,"No argument: need line or *addr.\n");
+        return 0;
+    }
+    if ( *s == '*' && isdigit(*(s+1)))
+    {
+        unsigned int addr = atoi(s);
+        if (cctxt && cctxt->func &&
+            cctxt->func->sym->addr <= addr &&
+            cctxt->func->sym->eaddr >= addr)
+        {
+            simSetPC(addr);
+            return 0;
+        }
+        fprintf(stdout,"Warning addr 0x%x outside actual function.\n",addr);
+        simSetPC(addr);
+        return 0;
+    }
+    if (isdigit(*s)) 
+    {
+        /* get the lineno */
+        int line = atoi(s) -1;
+        if (!cctxt || !cctxt->func || !cctxt->func->mod) 
+        {
+                   fprintf(stderr,"Function not defined.\n");
+            return 0;
+        }
+        if (line >= cctxt->func->entryline &&
+            line <= cctxt->func->exitline )
+        {
+            simSetPC(cctxt->func->mod->cLines[line]->addr);
+            return 0;
+        }
+        if (line >= cctxt->func->mod->ncLines )
+        {
+                   fprintf(stderr,"line not in module.\n");
+            return 0;
+        }
+        fprintf(stdout,"Warning line %d outside actual function.\n",line+1);
+        simSetPC(cctxt->func->mod->cLines[line]->addr);
+        return 0;
+    }
+    if ((bp = strchr(s,':'))) 
+    {
+        int line;
+        module *mod = NULL;
+        *bp++ = '\0';
+        if (!applyToSet(modules,moduleWithCName,s,&mod)) 
+        {
+            fprintf (stderr,"No source file named %s.\n",s);
+            return 0;
+        } 
+        if (!isdigit(*bp)) 
+        {                       
+            fprintf (stderr,"No line number.\n");
+            return 0;      
+        }
+        line = atoi(bp) -1;
+        if (line >= mod->ncLines )
+        {
+                   fprintf(stderr,"line not in module.\n");
+            return 0;
+        }
+        if ( mod != cctxt->func->mod ||
+             line < cctxt->func->entryline ||
+             line > cctxt->func->exitline )
+        {
+            fprintf(stdout,"Warning line %d outside actual function.\n",
+                    line+1);
+        }             
+        simSetPC(mod->cLines[line]->addr);
+    }
+    return 0;
+}
+
 /*-----------------------------------------------------------------*/
 /* cmdListAsm - list assembler source code                         */
 /*-----------------------------------------------------------------*/
@@ -1068,26 +1249,37 @@ int cmdSetOption (char *s, context *cctxt)
        return 0;
     }
 
+    if (strncmp(s,"listsize ",9) == 0) 
+    {
+        listlines = strtol(s+9,0,0);
+        if ( listlines < LISTLINES )
+            listlines = LISTLINES;
+        return 0;
+    }
+
+#ifdef SDCDB_DEBUG
+    if (strncmp(s,"debug ",6) == 0) 
+    {
+        sdcdbDebug = strtol(s+6,0,0);
+        return 0;
+    }
+#endif
     if (strncmp(s,"variable ",9) == 0) 
     {
         symbol *sym ;
-        char *val;
+        int fmt;
+        char *rs;
         s += 9;
-        while (isspace(*s)) s++;
-        if (!*s) return 0;
-
-        val = s;
-        while (*val && !isspace(*val) && *val != '=') val++;
-        while (isspace(*val)) *val++ = '\0';
-        if (*val) *val++ = '\0';
-        if (*val)
+        if ( !( rs = preparePrint(s, cctxt, &fmt, &sym )))
+            return 0;
+        s = rs;
+        while (*s && *s != '=') s++;
+        *s++ = '\0';
+        while (isspace(*s)) *s++ = '\0';
+        if (*s)
         {
-            if ((sym = symLookup(s,cctxt))) 
-            {
-                setSymValue(sym,val,cctxt);
+                printOrSetSymValue(sym,cctxt,0,0,0,rs,s,'\0');
                 return 0;
-            }   
-            fprintf(stdout,"No symbol \"%s\" in current context.\n",s);
         }
         else
             fprintf(stdout,"No new value for \"%s\".\n",s);
@@ -1104,7 +1296,7 @@ int cmdSetOption (char *s, context *cctxt)
 /*-----------------------------------------------------------------*/
 int cmdContinue (char *s, context *cctxt)
 {
-    if (!cctxt || !cctxt->func) {
+    if (STACK_EMPTY(callStack)) {
        fprintf(stdout,"The program is not being run.\n");
        return 0;
     }
@@ -1115,6 +1307,86 @@ int cmdContinue (char *s, context *cctxt)
     return 0;
 }
 
+/*-----------------------------------------------------------------*/
+/* cmdIgnore - set ignorecount for breakpoint                      */
+/*-----------------------------------------------------------------*/
+int cmdIgnore (char *s, context *cctxt)
+{   
+    int bpnum, cnt ;
+    while (isspace(*s)) s++;
+    if (!*s ) 
+    {
+        fprintf(stdout,"Argument required (breakpoint number).\n");
+        return 0;
+    }
+    bpnum = strtol(s,&s,10);
+    while (isspace(*s)) s++;
+    if (!*s ) 
+    {
+        fprintf(stdout,"Second argument (specified ignore-count) is missing.");
+        return 0;
+    }
+    cnt = strtol(s,0,10);
+    setUserbpIgnCount(bpnum,cnt);
+    return 0;
+}
+
+/*-----------------------------------------------------------------*/
+/* cmdCondition - set condition for breakpoint                     */
+/*-----------------------------------------------------------------*/
+int cmdCondition (char *s, context *cctxt)
+{   
+    int bpnum ;
+    while (isspace(*s)) s++;
+    if (!*s ) 
+    {
+        fprintf(stdout,"Argument required (breakpoint number).\n");
+        return 0;
+    }
+    bpnum = strtol(s,&s,10);
+    while (isspace(*s)) s++;
+    if (*s)
+        s = Safe_strdup(s);
+    else
+        s = NULL;
+    setUserbpCondition(bpnum,s);
+    return 0;
+}
+
+/*-----------------------------------------------------------------*/
+/* cmdCommands - set commands for breakpoint                       */
+/*-----------------------------------------------------------------*/
+int cmdCommands (char *s, context *cctxt)
+{   
+    int bpnum ;
+    char *cmds,*line;
+    while (isspace(*s)) s++;
+    
+    if (!*s ) 
+        bpnum = getLastBreakptNumber();
+    else
+        bpnum = strtol(s,0,10);
+
+    cmds = NULL;
+    while ((line = getNextCmdLine()))
+    {
+        while (isspace(*line)) line++;
+        if (!strncmp(line,"end",3))
+            break;
+        if (! cmds )
+        {
+            cmds = Safe_strdup(line);
+        }
+        else
+        {
+            cmds = Safe_realloc( cmds, strlen(cmds) + 1 + strlen(line));
+            strcat(cmds,line);
+        }
+    }
+    setUserbpCommand(bpnum,cmds);
+    return 0;
+}
+
 /*-----------------------------------------------------------------*/
 /* cmdDelUserBp - delete user break point                          */
 /*-----------------------------------------------------------------*/
@@ -1142,6 +1414,24 @@ int cmdDelUserBp (char *s, context *cctxt)
     return 0;
 }
 
+/*-----------------------------------------------------------------*/
+/* cmdStepi - single step exactly one instruction                   */
+/*-----------------------------------------------------------------*/
+int cmdStepi (char *s, context *cctxt)
+{
+
+    if (STACK_EMPTY(callStack))
+        fprintf(stdout,"The program is not being run.\n");
+    else 
+    {
+        doingSteps = 2;
+           simGo(2);   
+        doingSteps = 0;
+        showfull = 1;
+    }
+    return 0;
+}
+
 /*-----------------------------------------------------------------*/
 /* cmdStep - single step thru C source file                        */
 /*-----------------------------------------------------------------*/
@@ -1149,84 +1439,99 @@ int cmdStep (char *s, context *cctxt)
 {
     function *func = NULL;
 
-    if (!cctxt || !cctxt->func || !cctxt->func->mod) 
-       fprintf(stdout,"The program is not being run.\n");
+    if (STACK_EMPTY(callStack))
+        fprintf(stdout,"The program is not being run.\n");
     else {
-    int origSrcMode = srcMode;
-    if ( *s == 'i' )
-        srcMode = SRC_AMODE;
-       /* if we are @ the end of a function then set
-          break points at execution points of the
-          function in the call stack... */
-       if (cctxt->addr == cctxt->func->sym->eaddr) {
-           if ((func = STACK_PEEK(callStack))) {
-               if (srcMode == SRC_CMODE)
-                   applyToSet (func->cfpoints,setStepEPBp,STEP,
-                               func->mod->c_name);     
-               else
-                   applyToSet (func->afpoints,setStepEPBp,STEP,
-                               func->mod->asm_name);
-           }
-       } else {
-           /* set breakpoints at all function entry points
-              and all exepoints of this functions & for
-              all functions one up in the call stack */
+        /* if we are @ the end of a function then set
+           break points at execution points of the
+           function in the call stack... */
+        if (cctxt->addr == cctxt->func->sym->eaddr) {
+            if ((func = STACK_PEEK(callStack))) {
+                if (srcMode == SRC_CMODE)
+                    applyToSet (func->cfpoints,setStepEPBp,STEP,
+                                func->mod->c_name);    
+                else
+                    applyToSet (func->afpoints,setStepEPBp,STEP,
+                                func->mod->asm_name);
+            }
+        } else {
+            /* set breakpoints at all function entry points
+               and all exepoints of this functions & for
+               all functions one up in the call stack */
            
-           /* all function entry points */
-           applyToSet(functions,setStepBp); 
+            /* all function entry points */
+            applyToSet(functions,setStepBp); 
            
-           if (srcMode == SRC_CMODE) {
-               /* for all execution points in this function */
-               applyToSet(cctxt->func->cfpoints,setStepEPBp,STEP,
-                          cctxt->func->mod->c_name);
+            if (srcMode == SRC_CMODE) {
+                /* for all execution points in this function */
+                applyToSet(cctxt->func->cfpoints,setStepEPBp,STEP,
+                           cctxt->func->mod->c_name);
                
-               /* set a break point @ the current function's
-                  exit */
-               setBreakPoint (cctxt->func->sym->eaddr, CODE, STEP , 
-                              stepBpCB, cctxt->func->mod->c_name, 
-                              cctxt->func->exitline);
+                /* set a break point @ the current function's
+                   exit */
+                setBreakPoint (cctxt->func->sym->eaddr, CODE, STEP , 
+                               stepBpCB, cctxt->func->mod->c_name, 
+                               cctxt->func->exitline);
                
-               /* now break point @ callers execution points */
-               if ((func = STACK_PPEEK(callStack))) {
-                   applyToSet (func->cfpoints,setStepEPBp,STEP,
-                               func->mod->c_name);     
-                   /* set bp @ callers exit point */
-                   setBreakPoint (func->sym->eaddr, CODE, STEP , 
-                                  stepBpCB, func->mod->c_name, 
-                                  func->exitline);
-               }
-           } else {
-               /* for all execution points in this function */
-               applyToSet(cctxt->func->afpoints,setStepEPBp,STEP,
-                          cctxt->func->mod->asm_name);
+                /* now break point @ callers execution points */
+                if ((func = STACK_PPEEK(callStack))) {
+                    applyToSet (func->cfpoints,setStepEPBp,STEP,
+                                func->mod->c_name);    
+                    /* set bp @ callers exit point */
+                    setBreakPoint (func->sym->eaddr, CODE, STEP , 
+                                   stepBpCB, func->mod->c_name, 
+                                   func->exitline);
+                }
+            } else {
+                /* for all execution points in this function */
+                applyToSet(cctxt->func->afpoints,setStepEPBp,STEP,
+                           cctxt->func->mod->asm_name);
                
-               /* set a break point @ the current function's
-                  exit */
-               setBreakPoint (cctxt->func->sym->eaddr, CODE, STEP , 
-                              stepBpCB, cctxt->func->mod->asm_name, 
-                              cctxt->func->aexitline);
+                /* set a break point @ the current function's
+                   exit */
+                setBreakPoint (cctxt->func->sym->eaddr, CODE, STEP , 
+                               stepBpCB, cctxt->func->mod->asm_name, 
+                               cctxt->func->aexitline);
                
-               /* now break point @ callers execution points */
-               if ((func = STACK_PPEEK(callStack))) {
+                /* now break point @ callers execution points */
+                if ((func = STACK_PPEEK(callStack))) {
                    
-                   applyToSet (func->afpoints,setStepEPBp,STEP,
-                               func->mod->asm_name);   
+                    applyToSet (func->afpoints,setStepEPBp,STEP,
+                                func->mod->asm_name);  
                    
-                   /* set bp @ callers exit point */
-                   setBreakPoint (func->sym->eaddr, CODE, STEP , 
-                                  stepBpCB, func->mod->asm_name, 
-                                  func->aexitline);
-               }
-           }
-       }
+                    /* set bp @ callers exit point */
+                    setBreakPoint (func->sym->eaddr, CODE, STEP , 
+                                   stepBpCB, func->mod->asm_name, 
+                                   func->aexitline);
+                }
+            }
+        }
 
-    srcMode = origSrcMode;
-       simGo(-1);
-    showfull = 1;
+        doingSteps = 1;
+        simGo(2);
+        doingSteps = 0;
+        showfull = 1;
     }
     return 0;
 }
 
+/*-----------------------------------------------------------------*/
+/* cmdNexti - next instruction but proceed function call           */
+/*-----------------------------------------------------------------*/
+int cmdNexti (char *s, context *cctxt)
+{
+    if (STACK_EMPTY(callStack))
+        fprintf(stdout,"The program is not being run.\n");
+    else 
+    {
+        doingSteps = 2;
+           simGo(1);   
+        doingSteps = 0;
+        showfull = 1;
+    }  
+    return 0;
+}
+
 /*-----------------------------------------------------------------*/
 /* cmdNext - next executable C statement file                      */
 /*-----------------------------------------------------------------*/
@@ -1236,70 +1541,66 @@ int cmdNext (char *s, context *cctxt)
     /* next is almost the same as step except we don't
        we don't set break point for all function entry
        points */
-    if (!cctxt || !cctxt->func || !cctxt->func->mod) 
-       fprintf(stdout,"The program is not being run.\n");
+    if (STACK_EMPTY(callStack))
+        fprintf(stdout,"The program is not being run.\n");
     else {
-    int origSrcMode = srcMode;
-    if ( *s == 'i' )
-        srcMode = SRC_AMODE;
-       
-       /* if we are @ the end of a function then set
-          break points at execution points of the
-          function in the call stack... */
-       if (cctxt->addr == cctxt->func->sym->eaddr) {
-           if ((func = STACK_PEEK(callStack))) {
-               if (srcMode == SRC_CMODE)
-                   applyToSet (func->cfpoints,setStepEPBp,STEP,
-                               func->mod->c_name);     
-               else
-                   applyToSet (func->afpoints,setStepEPBp,STEP,
-                              func->mod->asm_name);
-           }
-       } else {
-           if (srcMode == SRC_CMODE) {
-               /* for all execution points in this function */
-               applyToSet(cctxt->func->cfpoints,setNextEPBp,NEXT,
-                          cctxt->func->mod->c_name);
-               /* set a break point @ the current function's
-                  exit */
-               setBreakPoint (cctxt->func->sym->eaddr, CODE, NEXT , 
-                              nextBpCB, cctxt->func->mod->c_name, 
-                              cctxt->func->exitline);
+        /* if we are @ the end of a function then set
+           break points at execution points of the
+           function in the call stack... */
+        if (cctxt->addr == cctxt->func->sym->eaddr) {
+            if ((func = STACK_PEEK(callStack))) {
+                if (srcMode == SRC_CMODE)
+                    applyToSet (func->cfpoints,setStepEPBp,NEXT,
+                                func->mod->c_name);    
+                else
+                    applyToSet (func->afpoints,setStepEPBp,NEXT,
+                                func->mod->asm_name);
+            }
+        } else {
+            if (srcMode == SRC_CMODE) {
+                /* for all execution points in this function */
+                applyToSet(cctxt->func->cfpoints,setNextEPBp,NEXT,
+                           cctxt->func->mod->c_name);
+                /* set a break point @ the current function's
+                   exit */
+                setBreakPoint (cctxt->func->sym->eaddr, CODE, NEXT , 
+                               nextBpCB, cctxt->func->mod->c_name, 
+                               cctxt->func->exitline);
                
-               /* now break point @ callers execution points */        
-               if ((func = STACK_PPEEK(callStack))) {
-                   applyToSet (func->cfpoints,setNextEPBp,NEXT ,
-                               func->mod->c_name);     
-                   /* set bp @ callers exit point */
-                   setBreakPoint (func->sym->eaddr, CODE, NEXT , 
-                                  stepBpCB, func->mod->c_name, 
-                                  func->exitline);
-               }
-           } else {
-               /* for all execution points in this function */
-               applyToSet(cctxt->func->afpoints,setNextEPBp,NEXT,
-                          cctxt->func->mod->asm_name);
-               /* set a break point @ the current function's
-                  exit */
-               setBreakPoint (cctxt->func->sym->eaddr, CODE, NEXT , 
-                              nextBpCB, cctxt->func->mod->asm_name, 
-                              cctxt->func->aexitline);
+                /* now break point @ callers execution points */       
+                if ((func = STACK_PPEEK(callStack))) {
+                    applyToSet (func->cfpoints,setNextEPBp,NEXT ,
+                                func->mod->c_name);    
+                    /* set bp @ callers exit point */
+                    setBreakPoint (func->sym->eaddr, CODE, NEXT , 
+                                   stepBpCB, func->mod->c_name, 
+                                   func->exitline);
+                }
+            } else {
+                /* for all execution points in this function */
+                applyToSet(cctxt->func->afpoints,setNextEPBp,NEXT,
+                           cctxt->func->mod->asm_name);
+                /* set a break point @ the current function's
+                   exit */
+                setBreakPoint (cctxt->func->sym->eaddr, CODE, NEXT , 
+                               nextBpCB, cctxt->func->mod->asm_name, 
+                               cctxt->func->aexitline);
                
-               /* now break point @ callers execution points */        
-               if ((func = STACK_PPEEK(callStack))) {
-                   applyToSet (func->cfpoints,setNextEPBp,NEXT ,
-                               func->mod->asm_name);   
-                   /* set bp @ callers exit point */
-                   setBreakPoint (func->sym->eaddr, CODE, NEXT , 
-                                  stepBpCB, func->mod->asm_name, 
-                                  func->aexitline);
-               }
-           }
-        srcMode = origSrcMode;
-           simGo(-1);  
+                /* now break point @ callers execution points */       
+                if ((func = STACK_PPEEK(callStack))) {
+                    applyToSet (func->cfpoints,setNextEPBp,NEXT ,
+                                func->mod->asm_name);  
+                    /* set bp @ callers exit point */
+                    setBreakPoint (func->sym->eaddr, CODE, NEXT , 
+                                   stepBpCB, func->mod->asm_name, 
+                                   func->aexitline);
+                }
+            }
+        }
+        doingSteps = 1;
+        simGo(1);      
+        doingSteps = 0;
         showfull = 1;
-       }
-    srcMode = origSrcMode;
     }    
     return 0;
 }
@@ -1310,13 +1611,14 @@ int cmdNext (char *s, context *cctxt)
 int cmdRun (char *s, context *cctxt)
 {
     char buff[10];
-    if (!cctxt || !cctxt->func || !cctxt->func->mod) {
+    if (STACK_EMPTY(callStack)) {
        fprintf(stdout,"Starting program\n");
     if ( ! simactive )
     {
         fprintf(stdout,"No executable file specified.\nUse the \"file\" command.\n");
         return 0;
     }
+    resetHitCount();
        simGo(0);
     } else {
        
@@ -1328,6 +1630,7 @@ int cmdRun (char *s, context *cctxt)
        fgets(buff,sizeof(buff),stdin);
        if (toupper(buff[0]) == 'Y') {
            simReset();
+        resetHitCount();
            simGo(0);
        }
     }
@@ -1601,6 +1904,69 @@ static void infoSymbols(context *ctxt)
 
 }
 
+/*-----------------------------------------------------------------*/
+/* infoRegisters - print register information                      */
+/*-----------------------------------------------------------------*/
+static void infoRegisters( int all, context *ctxt)
+{
+    static unsigned int regaddrs[] = {0x81,0x82,0x83,0xd0,0xe0,0xf0,0};
+    unsigned long val;
+    int i,j,*r;
+
+    i   = simGetValue (0xd0,'I',1);
+    fprintf(stdout,"PC  : 0x%04X  RegisterBank %d:\nR0-7:",ctxt->addr,(i>>3)&3);
+    for ( j = 0; j < 8 ; j++ )
+    {
+        val = simGetValue (j ,'R',1);
+        fprintf(stdout," 0x%02X",val);
+    }
+    fprintf(stdout,"\n");
+    val = simGetValue (0xe0,'I',1);
+    fprintf(stdout,"ACC : 0x%02X %d %c\n",val,val,(isprint(val) ? val : '.'));
+    val = simGetValue (0xf0,'I',1);
+    fprintf(stdout,"B   : 0x%02X %d %c\n",val,val,(isprint(val) ? val : '.'));
+    val = simGetValue (0x82,'I',2);
+    fprintf(stdout,"DPTR: 0x%04X %d\n",val,val);
+    val = simGetValue (0x81,'I',1);
+    fprintf(stdout,"SP  : 0x%02X\n",val);
+    fprintf(stdout,"PSW : 0x%02X | CY : %c | AC : %c | OV : %c | P : %c\n",
+            i,(i&0x80)?'1':'0',(i&0x40)?'1':'0',(i&4)?'1':'0',(i&1)?'1':'0');
+    if ( all )
+    {
+        fprintf(stdout,"Special Function Registers:\n");
+        r = regaddrs;
+        for ( i = 0x80 ; i < 0x100 ; i++ )
+        {
+            symbol *sym = NULL;
+            if ( *r && *r == i )
+            {
+                /* skip normal registers */
+                r++ ;
+                continue;
+            }
+            if (applyToSetFTrue(sfrsymbols,symWithAddr,i,'I',&sym))
+            {
+                val = simGetValue (sym->addr,sym->addrspace,sym->size);
+                fprintf(stdout,"%s : 0x%02x",sym->name,val);
+                if ( !(i & 0x07 ))
+                {
+                    for ( j = 0 ; j < 8 ; j++ )
+                    {
+                        sym = NULL;
+                        if (applyToSetFTrue(sfrsymbols,symWithAddr,i+j,'J',&sym))
+                        {
+                            //val = simGetValue (sym->addr,sym->addrspace,sym->size);
+                            fprintf(stdout," %s=%c",sym->name,(val&1)? '1':'0');
+                        }
+                        val >>= 1;
+                    }
+                }
+                fprintf(stdout,"\n");
+            }
+        }
+    }
+}
+
 /*-----------------------------------------------------------------*/
 /* infoStack - print call stack information                        */
 /*-----------------------------------------------------------------*/
@@ -1611,12 +1977,14 @@ static void infoStack(context *ctxt)
 
     STACK_STARTWALK(callStack) ;
     while ((func = STACK_WALK(callStack))) {
+    Dprintf(D_break, ("break: infoStack: %s %p (%p)\n",func->sym->name, w_callStack,p_callStack));
 
-       fprintf(stdout,"#%d 0x%04x %s () at %s:%d\n",i++,
+       fprintf(stdout,"#%d  0x%08x in %s () at %s:%d\n",i++,
                func->laddr,func->sym->name,
-               func->mod->c_name,func->lline);
+               func->mod->c_name,func->lline+1);
     }
-
+    if ( !i )
+        fprintf(stdout,"no stack.\n");
 }
 
 /*-----------------------------------------------------------------*/
@@ -1625,25 +1993,9 @@ static void infoStack(context *ctxt)
 int cmdWhere(char *s, context *cctxt)
 {
        infoStack(cctxt);
-    showfull = 1;
-       return 0;
-}
-
-/*-----------------------------------------------------------------*/
-/* cmdUp -  Up command                                             */
-/*-----------------------------------------------------------------*/
-int cmdUp(char *s, context *cctxt)
-{
        return 0;
 }
 
-/*-----------------------------------------------------------------*/
-/* cmdDown - down command                                          */
-/*-----------------------------------------------------------------*/
-int cmdDown(char *s, context *cctxt)
-{
-       return 0;
-}
 
 static int infomode = 0;
 /*-----------------------------------------------------------------*/
@@ -1662,7 +2014,6 @@ int cmdInfo (char *s, context *cctxt)
     /* info frame same as frame */
     if (strcmp(s,"frame") == 0) {
        cmdFrame (s,cctxt);
-    showfull = 1;
        return 0;
     }
 
@@ -1671,28 +2022,69 @@ int cmdInfo (char *s, context *cctxt)
        cmdListSrc (s+4,cctxt);
        return 0;
     }
-
-    /* info stack display call stack */
-    if (strcmp(s,"stack") == 0) {
-       infoStack(cctxt);
-    showfull = 1;
-       return 0;
-    }
+    if (strncmp(s,"source",6) == 0) 
+    {
+        module *m;
+        if ( s[6] == 's' )
+        {
+            int k = 0;
+            fprintf(stdout,"Source files for which symbols have been read in:\n\n");
+            for (m = setFirstItem(modules); m ; m = setNextItem(modules))
+            {
+                fprintf(stdout,"%s%s, %s",k ? ", ":"",m->cfullname, m->afullname); 
+                k = 1;
+            }
+            fprintf(stdout,"\n"); 
+        }
+        else
+        {
+            if (!cctxt || !cctxt->func || !cctxt->func->mod) 
+            {
+                fprintf(stdout,"No source file loaded\n");
+                return 0;
+            }
+            m = cctxt->func->mod;
+            fprintf(stdout,"Current source file is %s\n",m->c_name);
+            fprintf(stdout,"Located in %s\n",m->cfullname);
+            fprintf(stdout,"Contains %d lines.\nSource language is c.\n",
+                    m->ncLines);
+        }
+        return 0;
+    }
+    if (strncmp(s,"functions",7) == 0) 
+    {
+        function *f;
+        module *m = NULL;
+        fprintf(stdout,"All defined functions:\n");
+        for ( f = setFirstItem(functions); f ; f = setNextItem(functions))
+        {
+            if ( f->mod != m )
+            {
+                m = f->mod;
+                fprintf(stdout,"\nFile %s\n", m->c_name);
+            }
+            fprintf(stdout,"%s();\n",f->sym->name);
+        }
+        return 0;
+    }
+    /* info stack display call stack */
+    if (strcmp(s,"stack") == 0) {
+       infoStack(cctxt);
+    showfull = 1;
+       return 0;
+    }
 
     /* info stack display call stack */
     if (strcmp(s,"registers") == 0) {
-       fprintf(stdout,"%s",simRegs());
-       return 0;
+        infoRegisters(0,cctxt);
+           return 0;
     }
 
     /* info stack display call stack */
-    if (strcmp(s,"all-registers") == 0) {
-       fprintf(stdout,"%s",simRegs());
-       fprintf(stdout,"Special Function Registers:\n");
-    sendSim("ds 0x80 0x100\n");
-    waitForSim(100,NULL);
-    fprintf(stdout,simResponse());
-       return 0;
+    if (strcmp(s,"all-registers") == 0) 
+    {
+        infoRegisters(1,cctxt);
+        return 0;
     }
 
     /* info stack display call stack */
@@ -1733,7 +2125,9 @@ int cmdListSrc (char *s, context *cctxt)
     static int currline = 0;
     int i =0 ;
     int pline = 0;
-    int llines = listLines;
+    int llines = listlines;
+    function *func = NULL;
+
 
     while (*s && isspace(*s)) s++;
     
@@ -1741,13 +2135,13 @@ int cmdListSrc (char *s, context *cctxt)
        can be of the following formats
        LINE          - just line number
        FILE:LINE     - filename line number
+       FILE:LINE,LASTLINE  + last line
        FUNCTION      - list a function
        FILE:FUNCTION - function in file */
 
     if (*s) {
        /* case a) LINE */
        if (isdigit(*s)) {
-           sscanf(s,"%d",&pline);
            if (!cctxt || !cctxt->func || !cctxt->func->mod) {
              if (!list_mod) {
                fprintf(stdout,"Sdcdb fails to have a proper context at %d.\n", __LINE__);
@@ -1756,10 +2150,19 @@ int cmdListSrc (char *s, context *cctxt)
            }
            else
              list_mod = cctxt->func->mod;
+        pline = strtol(s,&s,10) - 1;
+        if (s && (s = strchr(s,','))) 
+        {
+            /* LINE,LASTLINE */
+            llines = strtol(s+1,0,10); 
+            if ( llines > 0 )
+                llines -= pline+1;
+            else
+                llines = listlines;
+        }
        }
        else {
            char *bp;
-           function *func = NULL;
            
            /* if ':' present then FILE:LINE || FILE:FUNCTION */
            if ((bp = strchr(s,':'))) {
@@ -1779,7 +2182,16 @@ int cmdListSrc (char *s, context *cctxt)
                            return 0;
                        }
                    }
-                   sscanf(bp,"%d",&pline);
+                   pline = strtol(bp,&bp,10) - 1;
+            if (bp && (bp = strchr(bp,','))) 
+            {
+                /* FILE:LINE,LASTLINE */
+                llines = strtol(bp+1,0,10); 
+                if ( llines > 0 )
+                    llines -= pline+1;
+                else
+                    llines = listlines;
+            }
                } else {
                    /* FILE:FUCTION */
                    if (!applyToSet(functions,funcWithNameModule,bp,s,&func)) {
@@ -1798,6 +2210,16 @@ int cmdListSrc (char *s, context *cctxt)
            }
            else {
                /* FUNCTION */
+            if (*s == '\'') 
+            {
+                /* 'FUNCTION' */
+                s++ ;
+                if ((bp = strrchr(s,'\''))) 
+                {
+                    *bp = '\0';
+                }
+                
+            }
                if (!applyToSet(functions,funcWithName,s,&func)) {
                    fprintf(stderr,"Function \"%s\" not defined.\n",s); 
                    return 0;
@@ -1836,14 +2258,43 @@ int cmdListSrc (char *s, context *cctxt)
       fprintf(stdout,"Sdcdb fails to have a valid module context at %d.\n", __LINE__);
       return 0;
     }
-    
-    if (llines > listLines) llines = listLines;
 
+    if ( pline < 0 )
+        return 0;
     if ( infomode )
     {
-           fprintf(stdout,"Line %d of \"%s\" starts at address 0x%08x.\n",pline,
-                   list_mod->c_name, list_mod->cLines[pline]->addr);
+        int firstaddr , lastaddr ;
+           if ( pline  >= list_mod->ncLines )
+            pline = cctxt->cline;
+        firstaddr = lastaddr = list_mod->cLines[pline]->addr;
+        if (!func && cctxt && cctxt->func )
+            func = cctxt->func;
+           fprintf(stdout,"Line %d of \"%s\" starts at address 0x%08x <%s+%d>", 
+                pline+1,
+                list_mod->c_name, lastaddr,
+                func ? func->sym->name : "?",
+                func ? lastaddr -func->sym->addr : 0);
+        llines = pline +1;
+        while ( pline < list_mod->ncLines )
+        {
+            pline++;
+            if ( list_mod->cLines[pline]->addr > lastaddr )
+            {
+                lastaddr = list_mod->cLines[pline]->addr -1;
+                break;
+            }
+        }
+        fprintf(stdout," and ends at 0x%08x <%s+%d>.\n", 
+                lastaddr,
+                func ? func->sym->name : "?",
+                func ? lastaddr -func->sym->addr : 0);
         infomode=0;
+        if ( func )
+            fprintf(stdout,"\032\032%s:%d:1:beg:0x%08x\n",
+                    func->mod->cfullname,
+                    llines,firstaddr);
+        else
+            showfull=1;
         return 0;
     }
     for ( i = 0 ; i < llines ; i++ ) {
@@ -1863,63 +2314,153 @@ int cmdListSrc (char *s, context *cctxt)
     return 0;
 }
 
-static void setValBasic(symbol *sym, char *val)
+static unsigned long getValBasic(symbol *sym, link *type, char *val)
 {
+    char *s;
     union 
     {          
         float f;     
         unsigned long val;
         long         sval;
         struct {
-            short    lo;
-            short    hi;
+            unsigned short    lo;
+            unsigned short    hi;
         } i;
         unsigned char b[4];
     }v;
 
-    if (IS_FLOAT(sym->type))   
-        v.f = strtof(val,NULL);    
+    if (IS_FLOAT(type))        
+        v.f = strtod(val,NULL);    
     else
-       if (IS_PTR(sym->type))
-           v.sval = strtol(val,NULL,0);
+       if (IS_PTR(type))
+           v.val = strtol(val,NULL,0);
        else
     {
-           if (IS_SPEC(sym->type) && IS_INTEGRAL(sym->type)) 
+           if (IS_INTEGRAL(type)) 
         {
-            if (IS_CHAR(sym->etype))
-            { 
-                v.b[0] = val[0];
+            link *etype;
+            if ( type->next )
+                etype = type->next;
+            else
+                etype = type;
+            if (IS_CHAR(etype))
+            {
+                if (( s = strchr(val,'\'')))
+                {
+                    if ( s[1] == '\\' )
+                        v.b[0] = strtol(s+2,NULL,8);
+                    else 
+                        v.b[0] = s[1];
+                }
+                else
+                {
+                    v.b[0] = strtol(val,NULL,0);
+                }
             }
             else
-                if (IS_INT(sym->etype)) 
-                    if (IS_LONG(sym->etype))
-                        if (SPEC_USIGN(sym->etype))
-                            v.val = strtol(val,NULL,0);
-                        else
-                            v.sval = strtol(val,NULL,0);
+                if (IS_INT(etype)) 
+                    if (IS_LONG(etype))
+                        v.val = strtol(val,NULL,0);
                     else
                         v.i.lo = strtol(val,NULL,0);
                 else
-                    v.sval = strtol(val,NULL,0);
+                    v.val = strtol(val,NULL,0);
            } 
         else
-            v.sval = strtol(val,NULL,0);
+            v.val = strtol(val,NULL,0);
     }
-    simSetValue(sym->addr,sym->addrspace,sym->size,v.sval);    
+    return v.val;
+}
+
+/*-----------------------------------------------------------------*/
+/* printFmtInteger - print value in bin,oct,dez or hex             */
+/*-----------------------------------------------------------------*/
+static void printFmtInteger(char *deffmt,int fmt, long val, 
+                            int sign, int size)
+{
+    static char digits[] = 
+    {
+        '0' , '1' , '2' , '3' , '4' , '5' ,
+        '6' , '7' , '8' , '9' , 'a' , 'b' ,
+        'c' , 'd' , 'e' , 'f' , 'g' , 'h' 
+    };
+    static int radixOfFormat[] = { 0 , 2, 8 ,10, 16  };
+    static int olenOfSize[]    = { 0 , 3, 6 , 8, 11  };
+       char buf[40];
+       char negative = 0;
+       int charPos = 38;
+    int radix;
+
+    if ( fmt == FMT_NON || fmt == FMT_DEZ )
+    {
+        fprintf(stdout,deffmt,val);
+        return;
+    }
+    radix = radixOfFormat[fmt];
+
+    /*
+    if ( sign && val < 0 )
+        negative = 1;
+    */
+
+       if (!negative)
+           val = -val;
+
+       buf[39] = '\0';
+    while (val <= -radix) 
+    {
+           buf[charPos--] = digits[-(val % radix)];
+           val = val / radix;
+       }
+       buf[charPos] = digits[-val];
+
+    switch ( fmt )
+    {
+        case FMT_OCT:
+            radix = olenOfSize[size];
+            break;
+        case FMT_HEX:
+            radix = size << 1;
+            break;
+        case FMT_BIN:
+            radix = size << 3;
+            break;
+    }
+
+    while (charPos > 39 - radix )
+    {
+        buf[--charPos] = '0';
+    } 
+    switch ( fmt )
+    {
+        case FMT_OCT:
+            if ( buf[charPos] != '0' )
+                buf[--charPos] = '0';
+            break;
+        case FMT_HEX:
+            buf[--charPos] = 'x';
+            buf[--charPos] = '0';
+            break;
+    }
+       if (negative) {
+           buf[--charPos] = '-';
+       }
+    fputs(&buf[charPos],stdout);
 }
 
 /*-----------------------------------------------------------------*/
 /* printValBasic - print value of basic types                      */
 /*-----------------------------------------------------------------*/
-static void printValBasic(symbol *sym,unsigned addr,char mem, int size)
+static void printValBasic(symbol *sym, link *type,
+                          char mem, unsigned addr,int size, int fmt)
 {
     union {    
        float f;     
        unsigned long val;
        long         sval;
        struct {
-           short    lo;
-           short    hi;
+           unsigned short    lo;
+           unsigned short    hi;
        } i;
        unsigned char b[4];
     }v;
@@ -1929,41 +2470,57 @@ static void printValBasic(symbol *sym,unsigned addr,char mem, int size)
     
     v.val = simGetValue(addr,mem,size);
     /* if this a floating point number then */
-    if (IS_FLOAT(sym->type))   
+    if (IS_FLOAT(type))        
        fprintf(stdout,"%f",v.f);    
     else
-       if (IS_PTR(sym->type))
-           fprintf(stdout,"0x%x",v.val);
+       if (IS_PTR(type))
+           fprintf(stdout,"0x%*x",size<<1,v.val);
        else
-           if (IS_SPEC(sym->type) && IS_INTEGRAL(sym->type)) {
-               if (IS_CHAR(sym->etype))
-        { 
-                   if ( isprint(v.val))
-                fprintf(stdout,"%d 0x%x '%c'",v.val,v.val,v.val);
+        if (IS_INTEGRAL(type)) 
+        {
+            link *etype;
+            if ( type->next )
+                etype = type->next;
             else
-                fprintf(stdout,"%d 0x%x '\\%o'",v.val,v.val,v.val);
-               }
-        else
-                   if (IS_INT(sym->etype)) 
-                       if (IS_LONG(sym->etype))
-                           if (SPEC_USIGN(sym->etype))
-                               fprintf(stdout,"%d 0x%x",v.val,v.val);
-                           else
-                               fprintf(stdout,"%d 0x%x",v.sval,v.sval);
-                       else
-                           fprintf(stdout,"%d 0x%x",v.i.lo,v.i.lo);
-                   else
-                       fprintf(stdout,"0x%x",v.val);
+                etype = type;
+            if (IS_CHAR(etype))
+            { 
+                if ( isprint(v.val))
+                    printFmtInteger((SPEC_USIGN(etype)?"0x%02x":"'%c'"),
+                                    fmt,(long)v.val,0,size);
+                else
+                    printFmtInteger((SPEC_USIGN(etype)?"0x%02x":"'\\%o'"),
+                                    fmt,(long)v.val,0,size);
+            }
+            else
+            {
+                if (IS_INT(etype)) 
+                    if (IS_LONG(etype))
+                        if (SPEC_USIGN(etype))
+                            printFmtInteger("%u",fmt,(long)v.val,0,size);
+                        else
+                            printFmtInteger("%d",fmt,(long)v.sval,1,size);
+                    else
+                        if (SPEC_USIGN(etype))
+                            printFmtInteger("%u",fmt,(long)v.i.lo,0,size);
+                        else
+                            printFmtInteger("%d",fmt,(long)v.i.lo,1,size);
+                else
+                {
+                    if (IS_BITVAR(etype))
+                        fprintf(stdout,"%c",(v.val?'1':'0'));
+                    else
+                        fprintf(stdout,"0x%0*x",size<<1,v.val);
+                }
+            }
            } else
-               fprintf(stdout,"0x%x",v.val);
-               
-    
+            fprintf(stdout,"0x%0*x",size<<1,v.val);  
 }
 
 /*-----------------------------------------------------------------*/
 /* printValFunc  - prints function values                          */
 /*-----------------------------------------------------------------*/
-static void printValFunc (symbol *sym)
+static void printValFunc (symbol *sym, int fmt)
 {
     fprintf(stdout,"print function not yet implemented");
 }
@@ -1971,20 +2528,21 @@ static void printValFunc (symbol *sym)
 /*-----------------------------------------------------------------*/
 /* printArrayValue - will print the values of array elements       */
 /*-----------------------------------------------------------------*/
-static void printArrayValue (symbol *sym, char space, unsigned int addr)
+static void printArrayValue (symbol *sym,  link *type,
+                             char space, unsigned int addr, int fmt)
 {
-       link *elem_type = sym->type->next;
+       link *elem_type = type->next;
        int i;
        
-       fprintf(stdout," { ");
-       for (i = 0 ; i < DCL_ELEM(sym->type) ; i++) {           
+       fprintf(stdout,"{");
+       for (i = 0 ; i < DCL_ELEM(type) ; i++) {                
                if (IS_AGGREGATE(elem_type)) {
-                       printValAggregates(sym,elem_type,space,addr);                  
+                       printValAggregates(sym,elem_type,space,addr,fmt);                      
                } else {
-                       printValBasic(sym,addr,space,getSize(elem_type));
+                       printValBasic(sym,elem_type,space,addr,getSize(elem_type),fmt);
                }
                addr += getSize(elem_type);
-               if (i != DCL_ELEM(sym->type) -1)
+               if (i != DCL_ELEM(type) -1)
                        fprintf(stdout,",");
        }
 
@@ -1994,17 +2552,19 @@ static void printArrayValue (symbol *sym, char space, unsigned int addr)
 /*-----------------------------------------------------------------*/
 /* printStructValue - prints structures elements                   */
 /*-----------------------------------------------------------------*/
-static void printStructValue (symbol *sym,link *type, char space, unsigned int addr) 
+static void printStructValue (symbol *sym, link *type, 
+                              char space, unsigned int addr, int fmt) 
 {
        symbol *fields = SPEC_STRUCT(type)->fields;
-
+    int first = 1;
        fprintf(stdout," { ");
        while (fields) {
-               fprintf(stdout,"%s = ",fields->name);
-               if (IS_AGGREGATE(fields->type)) {
-                       printValAggregates(fields,fields->type,space, addr);
+               fprintf(stdout,"%s%s = ",(first ? "": ", "),fields->name);
+               first = 0;
+        if (IS_AGGREGATE(fields->type)) {
+                       printValAggregates(fields,fields->type,space, addr, fmt);
                } else {
-                       printValBasic(fields,addr,space,getSize(fields->type));
+                       printValBasic(fields,fields->type,space,addr,getSize(fields->type), fmt);
                }
                addr += getSize(fields->type);
                fields = fields->next;
@@ -2015,70 +2575,50 @@ static void printStructValue (symbol *sym,link *type, char space, unsigned int a
 /*-----------------------------------------------------------------*/
 /* printValAggregates - print value of aggregates                  */
 /*-----------------------------------------------------------------*/
-static void printValAggregates (symbol *sym, link *type,char space,unsigned int addr)
+static void printValAggregates (symbol *sym, link *type,
+                                char space,unsigned int addr, int fmt)
 {
 
        if (IS_ARRAY(type)) {
-               printArrayValue(sym, space, addr);
+               printArrayValue(sym, type, space, addr, fmt);
                return ;
        }
 
        if (IS_STRUCT(type)) { 
-               printStructValue(sym,sym->type,space, addr); 
+               printStructValue(sym, type, space, addr, fmt); 
                return; 
        } 
 }
 
 /*-----------------------------------------------------------------*/
-/* setSymValue - set     value of a symbol                         */
+/* printOrSetSymValue - print or set value of a symbol             */
 /*-----------------------------------------------------------------*/
-static void setSymValue(symbol *sym, char *val, context *cctxt)
+static int printOrSetSymValue (symbol *sym, context *cctxt, 
+                                int flg, int dnum, int fmt, char *rs, 
+                                char *val, char cmp )
 {
+    static char fmtChar[] = " todx ";
+    static int stack = 1;
+       symbol *fields;
+    link *type;
+    unsigned int  addr; 
+    int size, n;
+    char *s, *s2;
+    char save_ch, save_ch2;
+
+    /* if it is on stack then compute address & fall thru */
     if (sym->isonstack) 
     {
         symbol *bp = symLookup("bp",cctxt);
         if (!bp) 
         {
             fprintf(stdout,"cannot determine stack frame\n");
-            return ;
+            return 1;
         }
 
         sym->addr = simGetValue(bp->addr,bp->addrspace,bp->size)
             + sym->offset ;      
     }
-    /* arrays & structures first */
-    if (IS_AGGREGATE(sym->type))
-       {
-    }
-    else
-       /* functions */
-       if (IS_FUNC(sym->type))
-    {
-    }
-       else
-    {
-        setValBasic(sym,val);
-    }
-}
-
-/*-----------------------------------------------------------------*/
-/* printSymValue - print value of a symbol                         */
-/*-----------------------------------------------------------------*/
-static void printSymValue (symbol *sym, context *cctxt, int flg, int dnum)
-{
-    static int stack = 1;
-    unsigned long val;
-    /* if it is on stack then compute address & fall thru */
-    if (sym->isonstack) {
-       symbol *bp = symLookup("bp",cctxt);
-       if (!bp) {
-           fprintf(stdout,"cannot determine stack frame\n");
-           return ;
-       }
-
-       sym->addr = simGetValue(bp->addr,bp->addrspace,bp->size)
-         + sym->offset ;      
-    }
     
     /* get the value from the simulator and
        print it */
@@ -2091,21 +2631,140 @@ static void printSymValue (symbol *sym, context *cctxt, int flg, int dnum)
             fprintf(stdout,"$%d = ",stack++);
             break;
         case 2: 
-            fprintf(stdout,"%d: %s = ",dnum,sym->name);
+            fprintf(stdout,"%d: ", dnum);
+            if ( fmt != FMT_NON )
+                fprintf(stdout,"/%c ",fmtChar[fmt]);
+            fprintf(stdout,"%s%s = ",sym->name,rs);
+            break;
+    }
+
+    addr = sym->addr;
+    type = sym->type;
+    size = sym->size;
+
+    while ( *rs )
+    {
+        if ( *rs == '[' && IS_ARRAY(type))
+        {
+            s = rs+1;
+            while ( *rs && *rs != ']' ) rs++ ;
+            save_ch = *rs;
+            *rs = '\0' ;
+            if ( ! isdigit(*s ))
+            {
+                /* index seems a variable */
+                for ( s2 = s; *s2 && ( isalnum( *s2 ) || *s2 == '_'); s2++ );
+                save_ch2 = *s2;
+                if ( *s2 )
+                    *s2 = '\0';
+                fields = symLookup(s,cctxt);
+                *s2 = save_ch2;
+                if ( ! fields )
+                {
+                    fprintf(stdout,"Unknown variable \"%s\" for index.\n", s);
+                    return 1;                    
+                }
+                /* arrays & structures first */
+                if (! IS_INTEGRAL(fields->type))
+                {
+                    fprintf(stdout,"Wrong type of variable \"%s\" for index \n", s);
+                    return 1;                    
+                }
+                n = simGetValue(fields->addr,fields->addrspace,getSize(fields->type));
+            }
+            else
+            {
+                n = strtol(s,0,0);
+            }
+            if ( n < 0 || n >= DCL_ELEM(type))
+            {
+                fprintf(stdout,"Wrong index %d.\n", n);
+                return 1;                    
+            }
+            type = type->next;
+            size = getSize(type);
+            addr += size * n;
+            *rs++ = save_ch;
+        }
+        else if ( *rs == '.' && IS_STRUCT(type))
+        {
+            s = rs+1;
+            /* search structure element */
+            for ( rs = s; *rs && ( isalnum( *rs ) || *rs == '_'); rs++ );
+            save_ch = *rs;
+            if ( *rs )
+                *rs = '\0';
+            for (fields = SPEC_STRUCT(type)->fields; fields; fields = fields->next) 
+            {
+                if (!(strcmp(s,fields->name)))
+                    break;
+            }
+            *rs = save_ch;
+            if ( ! fields )
+            {
+                fprintf(stdout,"Unknown field \"%s\" of structure\n", s);
+                return 1;                    
+            }
+            type = fields->type;
+            size = getSize(type);
+            addr += fields->offset;
+        }
+        else
             break;
     }
+
     /* arrays & structures first */
-    if (IS_AGGREGATE(sym->type))
-       printValAggregates(sym,sym->type,sym->addrspace,sym->addr);
+    if (IS_AGGREGATE(type))
+    {
+           if ( val )
+        {
+            fprintf(stdout,"Cannot set/compare aggregate variable\n");
+            return 1;
+        }
+        else
+            printValAggregates(sym,type,sym->addrspace,addr,fmt);
+    }
     else
        /* functions */
-       if (IS_FUNC(sym->type))
-           printValFunc(sym);
-       else 
-           printValBasic(sym,sym->addr,sym->addrspace,sym->size);
+       if (IS_FUNC(type))
+    {
+           if ( !val )
+            printValFunc(sym,fmt);
+        else
+            return 1;
+    }
+       else
+    { 
+           if ( val )
+        {
+            unsigned long newval;
+            newval = getValBasic(sym,type,val);
+
+            if ( cmp )
+            {
+                unsigned long lval;
+                lval = simGetValue(addr,sym->addrspace,size);
+                switch ( cmp )
+                {
+                    case '<' : return ( lval <  newval ? 1:0 ); break;
+                    case '>' : return ( lval >  newval ? 1:0 ); break;
+                    case 'l' : return ( lval <= newval ? 1:0 ); break;
+                    case 'g' : return ( lval >= newval ? 1:0 ); break;
+                    case '=' : return ( lval == newval ? 1:0 ); break;
+                    case '!' : return ( lval != newval ? 1:0 ); break;
+                }
+            }
+            else
+            {
+                simSetValue(addr,sym->addrspace,size,newval);  
+                return 1;
+            }
+        }
+        else
+            printValBasic(sym,type,sym->addrspace,addr,size,fmt);
+    }
     if ( flg > 0 ) fprintf(stdout,"\n");
-           //fprintf(stdout,"(BASIC %x,%c,%d)\n",sym->addr,sym->addrspace,sym->size);
-       
+       return 0;
 }
 
 /*-----------------------------------------------------------------*/
@@ -2208,27 +2867,57 @@ static void printTypeInfo(link *p)
     }
 }
 
+/*-----------------------------------------------------------------*/
+/* conditionIsTrue - compare variable with constant value        */
+/*-----------------------------------------------------------------*/
+int conditionIsTrue( char *s, context *cctxt)
+{   
+    symbol *sym = NULL;
+    int fmt;
+    char *rs, *dup, cmp_char;
+    dup = s = Safe_strdup(s);
+    if ( !( rs = preparePrint(s, cctxt, &fmt, &sym )) || !sym)
+        fmt = 1;
+    else if (!( s =  strpbrk(rs,"<>=!")))
+        fmt = 1;
+    else
+    {
+        cmp_char = *s;    
+        *s++ = '\0';
+        if ( *s == '=' )
+        {
+            /* if <= or >= an other char is used 
+             * == or !=  not checked in switch 
+             */
+            switch( cmp_char )
+            {
+                case '>': cmp_char = 'g' ; break;
+                case '<': cmp_char = 'l' ; break;
+            }
+            s++ ;
+        }
+        while (isspace(*s)) *s++ = '\0';
+        fmt = printOrSetSymValue(sym,cctxt,0,0,0,rs,s,cmp_char);
+    }
+    Safe_free(dup);
+    return fmt;
+}
+
 /*-----------------------------------------------------------------*/
 /* cmdPrint - print value of variable                              */
 /*-----------------------------------------------------------------*/
 int cmdPrint (char *s, context *cctxt)
 {   
     symbol *sym ;
-    char *bp = s+strlen(s) -1;
-
-    while (isspace(*s)) s++;
-    if (!*s) return 0;
-    while (isspace(*bp)) bp--;
-    bp++ ;
-    *bp = '\0';
+    int fmt;
+    char *rs;
+    if ( !( rs = preparePrint(s, cctxt, &fmt, &sym )))
+        return 0;
 
-    if ((sym = symLookup(s,cctxt))) {
-       printSymValue(sym,cctxt,1,0);
-    } else {
-       fprintf(stdout,
-               "No symbol \"%s\" in current context.\n",              
-               s);
-    }
+    if ( sym ) 
+    {
+        printOrSetSymValue(sym,cctxt,1,0,fmt,rs,NULL,'\0');
+    } 
     return 0;
 }
 
@@ -2238,30 +2927,18 @@ int cmdPrint (char *s, context *cctxt)
 int cmdOutput (char *s, context *cctxt)
 {   
     symbol *sym ;
-    char *bp = s+strlen(s) -1;
-
-    while (isspace(*s)) s++;
-    if (!*s) return 0;
-    while (isspace(*bp)) bp--;
-    bp++ ;
-    *bp = '\0';
+    int fmt;
+    char *rs;
+    if ( !( rs = preparePrint(s, cctxt, &fmt, &sym )))
+        return 0;
 
-    if ((sym = symLookup(s,cctxt))) {
-       printSymValue(sym,cctxt,0,0);
-    } else {
-       fprintf(stdout,
-               "No symbol \"%s\" in current context.",        
-               s);
-    }
+    if ( sym ) 
+    {
+        printOrSetSymValue(sym,cctxt,0,0,fmt,rs,NULL,'\0');
+    } 
     return 0;
 }
 
-typedef struct _dsymbol
-{
-    char *name;
-    int  dnum;
-} dsymbol;
-
 /** find display entry with this number */
 
 DEFSETFUNC(dsymWithNumber)
@@ -2292,7 +2969,8 @@ void displayAll(context *cctxt)
          dsym = setNextItem(dispsymbols)) 
     {
         if ( (sym = symLookup(dsym->name,cctxt)))
-            printSymValue(sym,cctxt,2,dsym->dnum);            
+            printOrSetSymValue(sym,cctxt,2,dsym->dnum,dsym->fmt,
+                               dsym->rs,NULL,'\0');
     }
 }
 
@@ -2301,32 +2979,25 @@ void displayAll(context *cctxt)
 /*-----------------------------------------------------------------*/
 int cmdDisplay (char *s, context *cctxt)
 {   
-    symbol *sym ;
-    char *bp = s+strlen(s) -1;
     static int dnum = 1;
-
-    while (isspace(*s)) s++;
-    if (!*s)
+    symbol *sym ;
+    int fmt;
+    char *rs;
+    if ( !( rs = preparePrint(s, cctxt, &fmt, &sym )))
     {
         displayAll(cctxt);
         return 0;
     }
-    while (isspace(*bp)) bp--;
-    bp++ ;
-    *bp = '\0';
 
-    if ((sym = symLookup(s,cctxt))
+    if ( sym 
     {
         dsymbol *dsym = (dsymbol *)Safe_calloc(1,sizeof(dsymbol));
         dsym->dnum = dnum++ ;
         dsym->name = sym->name;
+        dsym->fmt  = fmt;
+        dsym->rs   = gc_strdup(rs);
         addSetHead(&dispsymbols,dsym);
     }
-    else
-    {
-        fprintf(stdout,"No symbol \"%s\" in current context.\n",              
-                s);
-    }
     return 0;
 }
 
@@ -2341,6 +3012,13 @@ int cmdUnDisplay (char *s, context *cctxt)
     while (isspace(*s)) s++;
     if (!*s)
     {
+        for (dsym = setFirstItem(dispsymbols);
+             dsym;
+             dsym = setNextItem(dispsymbols))
+        {
+            Safe_free(dsym->rs);
+            Safe_free(dsym); 
+        }
         deleteSet(&dispsymbols);
         return 0;
     }
@@ -2350,6 +3028,8 @@ int cmdUnDisplay (char *s, context *cctxt)
         if (applyToSetFTrue(dispsymbols,dsymWithNumber,dnum,&dsym)) 
         {
             deleteSetItem(&dispsymbols,dsym);
+            Safe_free(dsym->rs);
+            Safe_free(dsym); 
         } 
         else
         {
@@ -2489,7 +3169,6 @@ int cmdClrUserBp (char *s, context *cctxt)
     return 0;        
 }
 
-
 /*-----------------------------------------------------------------*/
 /* cmdSimulator - send command to simulator                        */
 /*-----------------------------------------------------------------*/
@@ -2509,23 +3188,90 @@ int cmdSimulator (char *s, context *cctxt)
     return 0;
 }
 
+void setMainContext()
+{
+    function *func = NULL;
+    currentFrame = 0; 
+    if (!applyToSet(functions,funcWithName,"main",&func) &&
+        !applyToSet(functions,funcWithName,"_main",&func))
+        return;
+
+    discoverContext (func->sym->addr, func);
+}
+    
+static void printFrame()
+{
+    int i;
+    function *func     = NULL;
+    function *lastfunc = NULL;
+
+    if ( currentFrame < 0 )
+    {
+        currentFrame = 0;
+        fprintf(stdout,"Bottom (i.e., innermost) frame selected; you cannot go down.\n");
+        return;
+    }
+    STACK_STARTWALK(callStack) ;
+    for ( i = 0; i <= currentFrame ; i++ )
+    {
+        func = STACK_WALK(callStack);
+        if ( !func )
+        {
+            currentFrame = i-1;
+            fprintf(stdout,"Initial frame selected; you cannot go up.\n");
+            return;
+        }
+    }
+    fprintf(stdout,"#%d  0x%08x in %s () at %s:%d\n",
+            currentFrame,func->laddr,func->sym->name,func->mod->c_name,func->lline+1);
+    fprintf(stdout,"\032\032%s:%d:1:beg:0x%08x\n",
+            func->mod->cfullname,func->lline+1,func->laddr);
+
+    discoverContext (func->laddr, func);
+}
+
+
+/*-----------------------------------------------------------------*/
+/* cmdUp -  Up command                                             */
+/*-----------------------------------------------------------------*/
+int cmdUp(char *s, context *cctxt)
+{
+    while (isspace(*s)) s++;
+    if ( *s )
+        currentFrame += strtol(s,0,10);
+    else
+        currentFrame++ ;
+
+    printFrame();
+       return 0;
+}
+
+/*-----------------------------------------------------------------*/
+/* cmdDown - down command                                          */
+/*-----------------------------------------------------------------*/
+int cmdDown(char *s, context *cctxt)
+{
+    while (isspace(*s)) s++;
+    if ( *s )
+        currentFrame -= strtol(s,0,10);
+    else
+        currentFrame-- ;
+
+    printFrame();
+       return 0;
+}
 /*-----------------------------------------------------------------*/
 /* cmdFrame - Frame command                                        */
 /*-----------------------------------------------------------------*/
 int cmdFrame (char *s, context *cctxt)
 {   
-    function *func ;
-
-    if ((func = STACK_PEEK(callStack))) {
-       fprintf(stdout,"#0  %s () at %s:%d\n",
-               func->sym->name,func->mod->c_name,cctxt->cline);
+    function *func = NULL;
+    int i, framenr = 0;
 
-       if (cctxt->cline < func->mod->ncLines)      
-           fprintf(stdout,"%d\t%s",
-                   cctxt->cline,
-                   func->mod->cLines[cctxt->cline]->src);
-    } else
-       fprintf(stdout,"No stack.\n");
+    while (isspace(*s)) s++;
+    if ( *s )
+        currentFrame = strtol(s,0,10);
+    printFrame();
     return 0;
 }
 
@@ -2534,7 +3280,7 @@ int cmdFrame (char *s, context *cctxt)
 /*-----------------------------------------------------------------*/
 int cmdFinish (char *s, context *ctxt)
 {
-    if (!ctxt || ! ctxt->func) {
+    if (STACK_EMPTY(callStack)) {
        fprintf(stdout,"The program is not running.\n");
        return 0;
     }
@@ -2550,6 +3296,7 @@ int cmdFinish (char *s, context *ctxt)
     }
 
     simGo(-1);
+    showfull = 1;
     return 0;
     
 }