Use 'ao-dbg' instead of 's51' to communicate with TeleMetrum
[fw/sdcc] / debugger / mcs51 / cmd.c
index 21309c2ea4672e5b44c1a1b0aedc9b132d449855..cd038fffea32bcf9665469ffdfa2ba1671a79186 100644 (file)
@@ -1,25 +1,24 @@
 /*-------------------------------------------------------------------------
     cmd.c - source  file for debugger command execution
-
-             Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1999)
+        Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1999)
 
    This program is free software; you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by the
    Free Software Foundation; either version 2, or (at your option) any
    later version.
-   
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-   
+
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-   
+
    In other words, you are welcome to use, share and improve this program.
    You are forbidden to forbid anyone else to use, share and improve
-   what you give them.   Help stamp out software-hoarding!  
+   what you give them.   Help stamp out software-hoarding!
 -------------------------------------------------------------------------*/
 
 #include "sdcdb.h"
@@ -38,8 +37,6 @@ static int listlines = LISTLINES;
    no better context is available */
 static module *list_mod = NULL;
 
-EXTERN_STACK_DCL(callStack,function *,1024);
-
 #if defined(__APPLE__) && defined(__MACH__)
 static char *copying=
 {" GNU GENERAL PUBLIC LICENSE Version 2"};
@@ -329,13 +326,13 @@ static char *warranty=
 #endif
 
 static void printTypeInfo(link *);
-static void printValAggregates (symbol *,link *,char,unsigned int,int);
-static  int printOrSetSymValue (symbol *sym, context *cctxt, 
-                                int flg, int dnum, int fmt, 
+static void printValAggregates (symbol *,link *,char,unsigned int,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 */
+set *dispsymbols = NULL   ; /* set of displayable symbols */
 static int currentFrame = 0;        /* actual displayed frame     */
 /*-----------------------------------------------------------------*/
 /* funcWithName - returns function with name                       */
@@ -347,13 +344,13 @@ DEFSETFUNC(funcWithName)
     V_ARG(function **,funcp);
 
     if (*funcp)
-       return 0;
+        return 0;
 
     if (strcmp(func->sym->name,name) == 0) {
-       *funcp = func;
-       return 1;
+        *funcp = func;
+        return 1;
     }
-    
+
     return 0;
 }
 
@@ -371,7 +368,7 @@ DEFSETFUNC(symWithAddr)
         return 0;
 
     if ( sym->addr == laddr &&
-         sym->addrspace == laddrspace ) 
+         sym->addrspace == laddrspace )
     {
         *rsym = sym;
         return 1;
@@ -385,45 +382,49 @@ DEFSETFUNC(symWithAddr)
 /*-----------------------------------------------------------------*/
 static void setBPatModLine (module *mod, int line, char bpType )
 {
-  int next_line;
+    int next_line;
 
     /* look for the first executable line after the line
-       specified & get the break point there */    
+       specified & get the break point there */
+
+    if ( line < 0 )
+        return;
+
     if (srcMode == SRC_CMODE && line > mod->ncLines) {
-       fprintf(stderr,"No line %d in file \"%s\".\n",
-               line,mod->c_name);
-       return ;
+        fprintf(stderr,"No line %d in file \"%s\".\n",
+                line,mod->c_name);
+        return ;
     }
-    
+
     if (srcMode == SRC_AMODE && line > mod->nasmLines) {
-       fprintf(stderr,"No line %d in file \"%s\".\n",
-               line,mod->asm_name);
-       return ;
+        fprintf(stderr,"No line %d in file \"%s\".\n",
+                line,mod->asm_name);
+        return ;
     }
 
     next_line = line;
-    for ( ; next_line < (srcMode == SRC_CMODE ? mod->ncLines : mod->nasmLines ) ; 
-         next_line++ ) {
-       if (srcMode == SRC_CMODE) {
-           if (mod->cLines[next_line]->addr) {
-               setBreakPoint (mod->cLines[next_line]->addr, CODE, bpType, 
-                              userBpCB, mod->c_name, next_line);
-               return;
-//             break;
-           }
-       }
-       else {
-          if (mod->asmLines[next_line]->addr) {
-              setBreakPoint (mod->asmLines[next_line]->addr, CODE, bpType, 
-                             userBpCB, mod->asm_name, next_line);
-               return;
-//            break;
-          } 
-       }
+    for ( ; next_line < (srcMode == SRC_CMODE ? mod->ncLines : mod->nasmLines ) ;
+          next_line++ ) {
+        if (srcMode == SRC_CMODE) {
+            if (mod->cLines[next_line]->addr != INT_MAX) {
+                setBreakPoint (mod->cLines[next_line]->addr, CODE, bpType,
+                               userBpCB, mod->c_name, next_line);
+                return;
+//              break;
+            }
+        }
+        else {
+           if (mod->asmLines[next_line]->addr != INT_MAX) {
+               setBreakPoint (mod->asmLines[next_line]->addr, CODE, bpType,
+                              userBpCB, mod->asm_name, next_line);
+                return;
+//             break;
+           }
+        }
     }
 
-       fprintf(stderr,"No line %d or after in file \"%s\"..\n",
-                       line,mod->c_name);
+        fprintf(stderr,"No line %d or after in file \"%s\"..\n",
+                        line,mod->c_name);
 
     return;
 }
@@ -436,29 +437,29 @@ static void clearBPatModLine (module *mod, int line)
     /* look for the first executable line after the line
        specified & get the break point there */
     if (srcMode == SRC_CMODE && line > mod->ncLines) {
-       fprintf(stderr,"No line %d in file \"%s\".\n",
-               line,mod->c_name);
-       return ;
+        fprintf(stderr,"No line %d in file \"%s\".\n",
+                line,mod->c_name);
+        return ;
     }
-    
+
     if (srcMode == SRC_AMODE && line > mod->ncLines) {
-       fprintf(stderr,"No line %d in file \"%s\".\n",
-               line,mod->c_name);
-       return ;
-    }    
-    
-    for ( ; line < (srcMode == SRC_CMODE ? mod->ncLines : mod->nasmLines ) ; 
-         line++ ) {
-       if (srcMode == SRC_CMODE) 
-           if (mod->cLines[line]->addr) {
-               clearUSERbp (mod->cLines[line]->addr);                    
-               break;
-           }
-       else
-           if (mod->asmLines[line]->addr) {
-               clearUSERbp (mod->asmLines[line]->addr);                          
-               break;
-           }
+        fprintf(stderr,"No line %d in file \"%s\".\n",
+                line,mod->c_name);
+        return ;
+    }
+
+    for ( ; line < (srcMode == SRC_CMODE ? mod->ncLines : mod->nasmLines ) ;
+          line++ ) {
+        if (srcMode == SRC_CMODE)
+            if (mod->cLines[line]->addr) {
+                clearUSERbp (mod->cLines[line]->addr);
+                break;
+            }
+        else
+            if (mod->asmLines[line]->addr) {
+                clearUSERbp (mod->asmLines[line]->addr);
+                break;
+            }
     }
 
     return;
@@ -479,7 +480,7 @@ DEFSETFUNC(moduleLineWithAddr)
     if (*rmod)
         return 0;
 
-    for (i=0; i < mod->nasmLines; i++ ) 
+    for (i=0; i < mod->nasmLines; i++ )
     {
         if ( mod->asmLines[i]->addr == addr)
         {
@@ -487,7 +488,7 @@ DEFSETFUNC(moduleLineWithAddr)
             if (line )
             {
                 *line = 0;
-                for ( i=0; i < mod->ncLines; i++ ) 
+                for ( i=0; i < mod->ncLines; i++ )
                 {
                     if ( mod->cLines[i]->addr > addr)
                         break;
@@ -504,7 +505,7 @@ DEFSETFUNC(moduleLineWithAddr)
 /*-----------------------------------------------------------------*/
 /* funcWithNameModule - returns functions with a name module combo */
 /*-----------------------------------------------------------------*/
-DEFSETFUNC(funcWithNameModule) 
+DEFSETFUNC(funcWithNameModule)
 {
     function *func = item;
     V_ARG(char *,fname);
@@ -515,9 +516,9 @@ DEFSETFUNC(funcWithNameModule)
         return 0;
 
     if (strcmp(func->sym->name,fname) == 0 &&
-       strcmp(func->mod->c_name,mname) == 0) {
-       *funcp = func;
-       return 1;
+        strcmp(func->mod->c_name,mname) == 0) {
+        *funcp = func;
+        return 1;
     }
 
     return 0;
@@ -533,17 +534,17 @@ DEFSETFUNC(funcInAddr)
     V_ARG(function **,funcp);
 
     if (*funcp)
-       return 0;
+        return 0;
 
     /* in the address range */
     if (func->sym->addr <= addr &&
-       func->sym->eaddr >= addr) {
-       
-       *funcp = func;
-       return 1;
+        func->sym->eaddr >= addr) {
+
+        *funcp = func;
+        return 1;
     }
 
-    return 0;      
+    return 0;
 }
 
 /*-----------------------------------------------------------------*/
@@ -552,14 +553,14 @@ DEFSETFUNC(funcInAddr)
 DEFSETFUNC(setStepBp)
 {
     function *func = item;
-    
+
     if (func->sym && func->sym->addr ) {
-       
-       /* set the entry break point */
-       setBreakPoint (func->sym->addr , CODE , STEP , 
-                      stepBpCB ,func->mod->c_name , func->entryline);
 
-       return 1;
+        /* set the entry break point */
+        setBreakPoint (func->sym->addr , CODE , STEP ,
+                       stepBpCB ,func->mod->c_name , func->entryline);
+
+        return 1;
     }
 
     return 0;
@@ -573,9 +574,9 @@ DEFSETFUNC(setStepEPBp)
     exePoint *ep = item;
     V_ARG(int,bptype);
     V_ARG(char *,mname);
-   
-    setBreakPoint (ep->addr, CODE, bptype, 
-                  stepBpCB, mname, ep->line);
+
+    setBreakPoint (ep->addr, CODE, bptype,
+                   stepBpCB, mname, ep->line);
     return 1;
 }
 
@@ -587,9 +588,9 @@ DEFSETFUNC(setNextEPBp)
     exePoint *ep = item;
     V_ARG(int,bptype);
     V_ARG(char *,mname);
-   
-    setBreakPoint (ep->addr, CODE, bptype, 
-                  nextBpCB, mname, ep->line);
+
+    setBreakPoint (ep->addr, CODE, bptype,
+                   nextBpCB, mname, ep->line);
     return 1;
 }
 
@@ -606,16 +607,16 @@ DEFSETFUNC(lineAtAddr)
 
     /* address must be an exact match */
     if (ep->addr == addr) {
-       *line = ep->line;
-       if (block)
-           *block = ep->block ;
-       if (level)
-           *level = ep->level ;
-       return 1;
+        *line = ep->line;
+        if (block)
+            *block = ep->block ;
+        if (level)
+            *level = ep->level ;
+        return 1;
     }
 
     return 0;
-    
+
 }
 
 /*-----------------------------------------------------------------*/
@@ -631,106 +632,684 @@ DEFSETFUNC(lineNearAddr)
 
     /* the line in which the address is */
     if (ep->addr <= addr) {
-       *line = ep->line;
-       if (block)
-           *block = ep->block ;
-       if (level)
-           *level = ep->level ;
-       return 1;
+        *line = ep->line;
+        if (block)
+            *block = ep->block ;
+        if (level)
+            *level = ep->level ;
+        return 1;
     }
 
     return 0;
-    
+
 }
 
 /*-----------------------------------------------------------------*/
 /* discoverContext - find out the current context of the bp        */
 /*-----------------------------------------------------------------*/
-context *discoverContext (unsigned addr, function *func)
+context *discoverContext (unsigned addr, function *func, context *ctxt)
 {
     module   *mod  = NULL;
     int line = 0;
 
     /* find the function we are in */
     if (!func && !applyToSet(functions,funcInAddr,addr,&func)) {
-        if (!applyToSet(functions,funcWithName,"main",&func) ||
+        if (!applyToSet(functions,funcWithName,"_main",&func) ||
             !applyToSet(modules,moduleLineWithAddr,addr,&mod,NULL))
         {
-            fprintf(stderr, "Error?:discoverContext: cannot apply addr 0x%x\n",addr);
+            fprintf(stderr, "addr 0x%x in no module/function (runtime env?)\n",addr);
             return NULL;
         }
-        currCtxt->func = func;
-        currCtxt->addr = addr;
-        currCtxt->modName = mod->name;
-        currCtxt->cline = func->exitline;
+        ctxt->func = func;
+        ctxt->addr = addr;
+        ctxt->modName = mod->name;
+        ctxt->cline = func->exitline;
     }
     else
     {
-        currCtxt->func = func;
-        currCtxt->addr = func->laddr = addr;
-        currCtxt->modName = func->modName;
-    
+        ctxt->func = func;
+        ctxt->addr = func->laddr = addr;
+        ctxt->modName = func->modName;
+
         /* find the c line number */
         if(applyToSet(func->cfpoints,lineAtAddr,addr,
-                  &line,&currCtxt->block,&currCtxt->level)) 
-            currCtxt->cline = func->lline = line;
+                  &line,&ctxt->block,&ctxt->level))
+            ctxt->cline = func->lline = line;
         else if(applyToSet(func->cfpoints,lineNearAddr,addr,
-                  &line,&currCtxt->block,&currCtxt->level)) 
-            currCtxt->cline = func->lline = line;
+                  &line,&ctxt->block,&ctxt->level))
+            ctxt->cline = func->lline = line;
         else
-            currCtxt->cline = -1;
-    }    
+            ctxt->cline = -1;
+    }
     /* find the asm line number */
     line = 0;
     if (applyToSet(func->afpoints,lineAtAddr,addr,
-                  &line,NULL,NULL))
-        currCtxt->asmline = line;       
+                   &line,NULL,NULL))
+        ctxt->asmline = line;
     else
-        currCtxt->asmline = -1;
-        
-    return currCtxt ;
+        ctxt->asmline = -1;
+
+    return ctxt;
+}
+
+#define IS_BRANCH      1
+#define IS_CALL                2
+#define IS_RET         4
+#define IS_ADDR11      8
+#define IS_ADDR16      16
+#define IS_COND                32
+
+struct instruction {
+       unsigned char   flags;
+       unsigned char   len;
+};
+
+static struct instruction instructions[] = {
+       [0x28] = { .flags = 0, .len = 1 },      /* ADD A,Rn */
+       [0x29] = { .flags = 0, .len = 1 },      /* ADD A,Rn */
+       [0x2A] = { .flags = 0, .len = 1 },      /* ADD A,Rn */
+       [0x2B] = { .flags = 0, .len = 1 },      /* ADD A,Rn */
+       [0x2C] = { .flags = 0, .len = 1 },      /* ADD A,Rn */
+       [0x2D] = { .flags = 0, .len = 1 },      /* ADD A,Rn */
+       [0x2E] = { .flags = 0, .len = 1 },      /* ADD A,Rn */
+       [0x2F] = { .flags = 0, .len = 1 },      /* ADD A,Rn */
+       [0x25] = { .flags = 0, .len = 2 },      /* ADD A,direct */
+       [0x26] = { .flags = 0, .len = 1 },      /* ADD A,@Ri */
+       [0x27] = { .flags = 0, .len = 1 },      /* ADD A,@Ri */
+       [0x24] = { .flags = 0, .len = 2 },      /* ADD A,#data */
+       
+       [0x38] = { .flags = 0, .len = 1 },      /* ADDC A,Rn */
+       [0x39] = { .flags = 0, .len = 1 },      /* ADDC A,Rn */
+       [0x3A] = { .flags = 0, .len = 1 },      /* ADDC A,Rn */
+       [0x3B] = { .flags = 0, .len = 1 },      /* ADDC A,Rn */
+       [0x3C] = { .flags = 0, .len = 1 },      /* ADDC A,Rn */
+       [0x3D] = { .flags = 0, .len = 1 },      /* ADDC A,Rn */
+       [0x3E] = { .flags = 0, .len = 1 },      /* ADDC A,Rn */
+       [0x3F] = { .flags = 0, .len = 1 },      /* ADDC A,Rn */
+       [0x35] = { .flags = 0, .len = 2 },      /* ADDC A,direct */
+       [0x36] = { .flags = 0, .len = 1 },      /* ADDC A,@Ri */
+       [0x37] = { .flags = 0, .len = 1 },      /* ADDC A,@Ri */
+       [0x34] = { .flags = 0, .len = 2 },      /* ADDC A,#data */
+       
+       [0x98] = { .flags = 0, .len = 1 },      /* SUBB A,Rn */
+       [0x99] = { .flags = 0, .len = 1 },      /* SUBB A,Rn */
+       [0x9A] = { .flags = 0, .len = 1 },      /* SUBB A,Rn */
+       [0x9B] = { .flags = 0, .len = 1 },      /* SUBB A,Rn */
+       [0x9C] = { .flags = 0, .len = 1 },      /* SUBB A,Rn */
+       [0x9D] = { .flags = 0, .len = 1 },      /* SUBB A,Rn */
+       [0x9E] = { .flags = 0, .len = 1 },      /* SUBB A,Rn */
+       [0x9F] = { .flags = 0, .len = 1 },      /* SUBB A,Rn */
+       [0x95] = { .flags = 0, .len = 2 },      /* SUBB A,direct */
+       [0x96] = { .flags = 0, .len = 1 },      /* SUBB A,@Ri */
+       [0x97] = { .flags = 0, .len = 1 },      /* SUBB A,@Ri */
+       [0x94] = { .flags = 0, .len = 2 },      /* SUBB A,#data */
+       
+       [0x08] = { .flags = 0, .len = 1 },      /* INC Rn */
+       [0x09] = { .flags = 0, .len = 1 },      /* INC Rn */
+       [0x0A] = { .flags = 0, .len = 1 },      /* INC Rn */
+       [0x0B] = { .flags = 0, .len = 1 },      /* INC Rn */
+       [0x0C] = { .flags = 0, .len = 1 },      /* INC Rn */
+       [0x0D] = { .flags = 0, .len = 1 },      /* INC Rn */
+       [0x0E] = { .flags = 0, .len = 1 },      /* INC Rn */
+       [0x0F] = { .flags = 0, .len = 1 },      /* INC Rn */
+       [0x05] = { .flags = 0, .len = 2 },      /* INC direct */
+       [0x06] = { .flags = 0, .len = 1 },      /* INC @Ri */
+       [0x07] = { .flags = 0, .len = 1 },      /* INC @Ri */
+       [0x04] = { .flags = 0, .len = 1 },      /* INC A */
+
+       [0xA3] = { .flags = 0, .len = 1 },      /* INC DPTR */
+
+       [0x18] = { .flags = 0, .len = 1 },      /* DEC Rn */
+       [0x19] = { .flags = 0, .len = 1 },      /* DEC Rn */
+       [0x1A] = { .flags = 0, .len = 1 },      /* DEC Rn */
+       [0x1B] = { .flags = 0, .len = 1 },      /* DEC Rn */
+       [0x1C] = { .flags = 0, .len = 1 },      /* DEC Rn */
+       [0x1D] = { .flags = 0, .len = 1 },      /* DEC Rn */
+       [0x1E] = { .flags = 0, .len = 1 },      /* DEC Rn */
+       [0x1F] = { .flags = 0, .len = 1 },      /* DEC Rn */
+       [0x15] = { .flags = 0, .len = 2 },      /* DEC direct */
+       [0x16] = { .flags = 0, .len = 1 },      /* DEC @Ri */
+       [0x17] = { .flags = 0, .len = 1 },      /* DEC @Ri */
+       [0x14] = { .flags = 0, .len = 1 },      /* DEC A */
+
+       [0xA4] = { .flags = 0, .len = 1 },      /* MUL AB */
+       [0x84] = { .flags = 0, .len = 1 },      /* DIV AB */
+
+       [0xD4] = { .flags = 0, .len = 1 },      /* DA A */
+
+       [0x58] = { .flags = 0, .len = 1 },      /* ANL A,Rn */
+       [0x59] = { .flags = 0, .len = 1 },      /* ANL A,Rn */
+       [0x5A] = { .flags = 0, .len = 1 },      /* ANL A,Rn */
+       [0x5B] = { .flags = 0, .len = 1 },      /* ANL A,Rn */
+       [0x5C] = { .flags = 0, .len = 1 },      /* ANL A,Rn */
+       [0x5D] = { .flags = 0, .len = 1 },      /* ANL A,Rn */
+       [0x5E] = { .flags = 0, .len = 1 },      /* ANL A,Rn */
+       [0x5F] = { .flags = 0, .len = 1 },      /* ANL A,Rn */
+       [0x55] = { .flags = 0, .len = 2 },      /* ANL A,direct */
+       [0x56] = { .flags = 0, .len = 1 },      /* ANL A,@Ri */
+       [0x57] = { .flags = 0, .len = 1 },      /* ANL A,@Ri */
+       [0x54] = { .flags = 0, .len = 2 },      /* ANL A,#data */
+       [0x52] = { .flags = 0, .len = 2 },      /* ANL direct,A */
+       [0x53] = { .flags = 0, .len = 3 },      /* ANL direct,#data */
+
+       [0x48] = { .flags = 0, .len = 1 },      /* ORL A,Rn */
+       [0x49] = { .flags = 0, .len = 1 },      /* ORL A,Rn */
+       [0x4A] = { .flags = 0, .len = 1 },      /* ORL A,Rn */
+       [0x4B] = { .flags = 0, .len = 1 },      /* ORL A,Rn */
+       [0x4C] = { .flags = 0, .len = 1 },      /* ORL A,Rn */
+       [0x4D] = { .flags = 0, .len = 1 },      /* ORL A,Rn */
+       [0x4E] = { .flags = 0, .len = 1 },      /* ORL A,Rn */
+       [0x4F] = { .flags = 0, .len = 1 },      /* ORL A,Rn */
+       [0x45] = { .flags = 0, .len = 2 },      /* ORL A,direct */
+       [0x46] = { .flags = 0, .len = 1 },      /* ORL A,@Ri */
+       [0x47] = { .flags = 0, .len = 1 },      /* ORL A,@Ri */
+       [0x44] = { .flags = 0, .len = 2 },      /* ORL A,#data */
+       [0x42] = { .flags = 0, .len = 2 },      /* ORL direct,A */
+       [0x43] = { .flags = 0, .len = 3 },      /* ORL direct,#data */
+
+       [0x68] = { .flags = 0, .len = 1 },      /* XRL A,Rn */
+       [0x69] = { .flags = 0, .len = 1 },      /* XRL A,Rn */
+       [0x6A] = { .flags = 0, .len = 1 },      /* XRL A,Rn */
+       [0x6B] = { .flags = 0, .len = 1 },      /* XRL A,Rn */
+       [0x6C] = { .flags = 0, .len = 1 },      /* XRL A,Rn */
+       [0x6D] = { .flags = 0, .len = 1 },      /* XRL A,Rn */
+       [0x6E] = { .flags = 0, .len = 1 },      /* XRL A,Rn */
+       [0x6F] = { .flags = 0, .len = 1 },      /* XRL A,Rn */
+       [0x65] = { .flags = 0, .len = 2 },      /* XRL A,direct */
+       [0x66] = { .flags = 0, .len = 1 },      /* XRL A,@Ri */
+       [0x67] = { .flags = 0, .len = 1 },      /* XRL A,@Ri */
+       [0x64] = { .flags = 0, .len = 2 },      /* XRL A,#data */
+       [0x62] = { .flags = 0, .len = 2 },      /* XRL direct,A */
+       [0x63] = { .flags = 0, .len = 3 },      /* XRL direct,#data */
+       
+       [0xE4] = { .flags = 0, .len = 1 },      /* CLR A */
+       [0xF4] = { .flags = 0, .len = 1 },      /* CPL A */
+
+       [0x23] = { .flags = 0, .len = 1 },      /* RL A */
+       [0x33] = { .flags = 0, .len = 1 },      /* RLC A */
+       [0x03] = { .flags = 0, .len = 1 },      /* RR A */
+       [0x13] = { .flags = 0, .len = 1 },      /* RRC A */
+       
+       [0xC4] = { .flags = 0, .len = 1 },      /* SWAP A */
+
+       [0xE8] = { .flags = 0, .len = 1 },      /* MOV A,Rn */
+       [0xE9] = { .flags = 0, .len = 1 },      /* MOV A,Rn */
+       [0xEA] = { .flags = 0, .len = 1 },      /* MOV A,Rn */
+       [0xEB] = { .flags = 0, .len = 1 },      /* MOV A,Rn */
+       [0xEC] = { .flags = 0, .len = 1 },      /* MOV A,Rn */
+       [0xED] = { .flags = 0, .len = 1 },      /* MOV A,Rn */
+       [0xEE] = { .flags = 0, .len = 1 },      /* MOV A,Rn */
+       [0xEF] = { .flags = 0, .len = 1 },      /* MOV A,Rn */
+       [0xE5] = { .flags = 0, .len = 2 },      /* MOV A,direct */
+       [0xE6] = { .flags = 0, .len = 1 },      /* MOV A,@Ri */
+       [0xE7] = { .flags = 0, .len = 1 },      /* MOV A,@Ri */
+       [0x74] = { .flags = 0, .len = 2 },      /* MOV A,#data */
+
+       [0xF8] = { .flags = 0, .len = 1 },      /* MOV Rn,A */
+       [0xF9] = { .flags = 0, .len = 1 },      /* MOV Rn,A */
+       [0xFA] = { .flags = 0, .len = 1 },      /* MOV Rn,A */
+       [0xFB] = { .flags = 0, .len = 1 },      /* MOV Rn,A */
+       [0xFC] = { .flags = 0, .len = 1 },      /* MOV Rn,A */
+       [0xFD] = { .flags = 0, .len = 1 },      /* MOV Rn,A */
+       [0xFE] = { .flags = 0, .len = 1 },      /* MOV Rn,A */
+       [0xFF] = { .flags = 0, .len = 1 },      /* MOV Rn,A */
+       
+       [0xA8] = { .flags = 0, .len = 2 },      /* MOV Rn,direct */
+       [0xA9] = { .flags = 0, .len = 2 },      /* MOV Rn,direct */
+       [0xAA] = { .flags = 0, .len = 2 },      /* MOV Rn,direct */
+       [0xAB] = { .flags = 0, .len = 2 },      /* MOV Rn,direct */
+       [0xAC] = { .flags = 0, .len = 2 },      /* MOV Rn,direct */
+       [0xAD] = { .flags = 0, .len = 2 },      /* MOV Rn,direct */
+       [0xAE] = { .flags = 0, .len = 2 },      /* MOV Rn,direct */
+       [0xAF] = { .flags = 0, .len = 2 },      /* MOV Rn,direct */
+
+       [0x78] = { .flags = 0, .len = 2 },      /* MOV Rn,#data */
+       [0x79] = { .flags = 0, .len = 2 },      /* MOV Rn,#data */
+       [0x7A] = { .flags = 0, .len = 2 },      /* MOV Rn,#data */
+       [0x7B] = { .flags = 0, .len = 2 },      /* MOV Rn,#data */
+       [0x7C] = { .flags = 0, .len = 2 },      /* MOV Rn,#data */
+       [0x7D] = { .flags = 0, .len = 2 },      /* MOV Rn,#data */
+       [0x7E] = { .flags = 0, .len = 2 },      /* MOV Rn,#data */
+       [0x7F] = { .flags = 0, .len = 2 },      /* MOV Rn,#data */
+       
+       [0xF5] = { .flags = 0, .len = 2 },      /* MOV direct,A */
+       [0x88] = { .flags = 0, .len = 2 },      /* MOV direct,Rn */
+       [0x89] = { .flags = 0, .len = 2 },      /* MOV direct,Rn */
+       [0x8A] = { .flags = 0, .len = 2 },      /* MOV direct,Rn */
+       [0x8B] = { .flags = 0, .len = 2 },      /* MOV direct,Rn */
+       [0x8C] = { .flags = 0, .len = 2 },      /* MOV direct,Rn */
+       [0x8D] = { .flags = 0, .len = 2 },      /* MOV direct,Rn */
+       [0x8E] = { .flags = 0, .len = 2 },      /* MOV direct,Rn */
+       [0x8F] = { .flags = 0, .len = 2 },      /* MOV direct,Rn */
+       [0x85] = { .flags = 0, .len = 3 },      /* MOV direct,direct */
+       [0x86] = { .flags = 0, .len = 2 },      /* MOV direct,@Ri */
+       [0x87] = { .flags = 0, .len = 2 },      /* MOV direct,@Ri */
+       [0x75] = { .flags = 0, .len = 3 },      /* MOV direct,#data */
+       
+       [0xF6] = { .flags = 0, .len = 1 },      /* MOV @Ri,A */
+       [0xF7] = { .flags = 0, .len = 1 },      /* MOV @Ri,A */
+       [0xA6] = { .flags = 0, .len = 2 },      /* MOV @Ri,direct */
+       [0xA7] = { .flags = 0, .len = 2 },      /* MOV @Ri,direct */
+       [0x76] = { .flags = 0, .len = 2 },      /* MOV @Ri,#data */
+       [0x77] = { .flags = 0, .len = 2 },      /* MOV @Ri,#data */
+       
+
+       [0x90] = { .flags = 0, .len = 3 },      /* MOV DPTR,#data16 */
+       
+       [0x93] = { .flags = 0, .len = 1 },      /* MOVC A,@A+DPTR */
+       [0x83] = { .flags = 0, .len = 1 },      /* MOVC A,@A+PC */
+       
+       [0xE2] = { .flags = 0, .len = 1 },      /* MOVX A,@Ri */
+       [0xE3] = { .flags = 0, .len = 1 },      /* MOVX A,@Ri */
+       [0xE0] = { .flags = 0, .len = 1 },      /* MOVX A,@DPTR */
+       [0xF2] = { .flags = 0, .len = 1 },      /* MOVX @Ri,A */
+       [0xF3] = { .flags = 0, .len = 1 },      /* MOVX @Ri,A */
+       [0xF0] = { .flags = 0, .len = 1 },      /* MOVX @DPTR,A */
+
+       [0xC0] = { .flags = 0, .len = 2 },      /* PUSH direct */
+       [0xD0] = { .flags = 0, .len = 2 },      /* POP direct */
+       [0xF5] = { .flags = 0, .len = 2 },      /* MOV direct,A */
+       [0xF5] = { .flags = 0, .len = 2 },      /* MOV direct,A */
+       [0xF5] = { .flags = 0, .len = 2 },      /* MOV direct,A */
+       [0xF5] = { .flags = 0, .len = 2 },      /* MOV direct,A */
+
+       [0xC8] = { .flags = 0, .len = 1 },      /* XCH A,Rn */
+       [0xC9] = { .flags = 0, .len = 1 },      /* XCH A,Rn */
+       [0xCA] = { .flags = 0, .len = 1 },      /* XCH A,Rn */
+       [0xCB] = { .flags = 0, .len = 1 },      /* XCH A,Rn */
+       [0xCC] = { .flags = 0, .len = 1 },      /* XCH A,Rn */
+       [0xCD] = { .flags = 0, .len = 1 },      /* XCH A,Rn */
+       [0xCE] = { .flags = 0, .len = 1 },      /* XCH A,Rn */
+       [0xCF] = { .flags = 0, .len = 1 },      /* XCH A,Rn */
+       [0xC5] = { .flags = 0, .len = 2 },      /* XCH A,direct */
+       [0xC6] = { .flags = 0, .len = 1 },      /* XCH A,@Ri */
+       [0xC7] = { .flags = 0, .len = 1 },      /* XCH A,@Ri */
+       [0xD6] = { .flags = 0, .len = 1 },      /* XCHD A,@Ri */
+       [0xD7] = { .flags = 0, .len = 1 },      /* XCHD A,@Ri */
+
+       [0x11] = { .flags = IS_CALL, .len = 2 },        /* ACALL addr11 */
+       [0x31] = { .flags = IS_CALL, .len = 2 },        /* ACALL addr11 */
+       [0x51] = { .flags = IS_CALL, .len = 2 },        /* ACALL addr11 */
+       [0x71] = { .flags = IS_CALL, .len = 2 },        /* ACALL addr11 */
+       [0x91] = { .flags = IS_CALL, .len = 2 },        /* ACALL addr11 */
+       [0xb1] = { .flags = IS_CALL, .len = 2 },        /* ACALL addr11 */
+       [0xd1] = { .flags = IS_CALL, .len = 2 },        /* ACALL addr11 */
+       [0xf1] = { .flags = IS_CALL, .len = 2 },        /* ACALL addr11 */
+       [0x12] = { .flags = IS_CALL, .len = 3 },        /* LCALL addr16 */      
+       
+       [0x22] = { .flags = IS_RET, .len = 1 },         /* RET */       
+       [0x32] = { .flags = IS_RET, .len = 1 },         /* RETI */      
+       
+       [0x01] = { .flags = IS_BRANCH, .len = 2 },      /* AJMP addr11 */
+       [0x21] = { .flags = IS_BRANCH, .len = 2 },      /* AJMP addr11 */
+       [0x41] = { .flags = IS_BRANCH, .len = 2 },      /* AJMP addr11 */
+       [0x61] = { .flags = IS_BRANCH, .len = 2 },      /* AJMP addr11 */
+       [0x81] = { .flags = IS_BRANCH, .len = 2 },      /* AJMP addr11 */
+       [0xa1] = { .flags = IS_BRANCH, .len = 2 },      /* AJMP addr11 */
+       [0xc1] = { .flags = IS_BRANCH, .len = 2 },      /* AJMP addr11 */
+       [0xe1] = { .flags = IS_BRANCH, .len = 2 },      /* AJMP addr11 */
+       [0x02] = { .flags = IS_BRANCH, .len = 3 },      /* LJMP addr16 */
+       
+       [0x80] = { .flags = IS_BRANCH, .len = 2 },      /* SJMP rel */
+       
+       [0x73] = { .flags = IS_BRANCH, .len = 1 },      /* JMP @A+DPTR */
+       
+       [0x60] = { .flags = IS_BRANCH, .len = 2 },      /* JZ rel */
+       [0x70] = { .flags = IS_BRANCH, .len = 2 },      /* JNZ rel */
+       [0x40] = { .flags = IS_BRANCH, .len = 2 },      /* JC rel */
+       [0x50] = { .flags = IS_BRANCH, .len = 2 },      /* JNC rel */
+       [0x20] = { .flags = IS_BRANCH, .len = 3 },      /* JB bit,rel */
+       [0x30] = { .flags = IS_BRANCH, .len = 3 },      /* JNB bit,rel */
+       [0x10] = { .flags = IS_BRANCH, .len = 3 },      /* JBC bit,direct rel */
+       
+       [0xB5] = { .flags = IS_BRANCH, .len = 3 },      /* CJNE A,direct rel */
+       [0xB4] = { .flags = IS_BRANCH, .len = 3 },      /* CJNE A,#data rel */
+       [0xB8] = { .flags = IS_BRANCH, .len = 3 },      /* CJNE Rn,#data rel */
+       [0xB9] = { .flags = IS_BRANCH, .len = 3 },      /* CJNE Rn,#data rel */
+       [0xBA] = { .flags = IS_BRANCH, .len = 3 },      /* CJNE Rn,#data rel */
+       [0xBB] = { .flags = IS_BRANCH, .len = 3 },      /* CJNE Rn,#data rel */
+       [0xBC] = { .flags = IS_BRANCH, .len = 3 },      /* CJNE Rn,#data rel */
+       [0xBD] = { .flags = IS_BRANCH, .len = 3 },      /* CJNE Rn,#data rel */
+       [0xBE] = { .flags = IS_BRANCH, .len = 3 },      /* CJNE Rn,#data rel */
+       [0xBF] = { .flags = IS_BRANCH, .len = 3 },      /* CJNE Rn,#data rel */
+       [0xB6] = { .flags = IS_BRANCH, .len = 3 },      /* CJNE @Ri,direct rel */
+       [0xB7] = { .flags = IS_BRANCH, .len = 3 },      /* CJNE @Ri,direct rel */
+       
+       [0xD8] = { .flags = IS_BRANCH, .len = 2 },      /* DNJZ Rn,rel */
+       [0xD9] = { .flags = IS_BRANCH, .len = 2 },      /* DNJZ Rn,rel */
+       [0xDA] = { .flags = IS_BRANCH, .len = 2 },      /* DNJZ Rn,rel */
+       [0xDB] = { .flags = IS_BRANCH, .len = 2 },      /* DNJZ Rn,rel */
+       [0xDC] = { .flags = IS_BRANCH, .len = 2 },      /* DNJZ Rn,rel */
+       [0xDD] = { .flags = IS_BRANCH, .len = 2 },      /* DNJZ Rn,rel */
+       [0xDE] = { .flags = IS_BRANCH, .len = 2 },      /* DNJZ Rn,rel */
+       [0xDF] = { .flags = IS_BRANCH, .len = 2 },      /* DNJZ Rn,rel */
+       [0xD5] = { .flags = IS_BRANCH, .len = 3 },      /* DNJZ direct,rel */
+
+       [0x00] = { .flags = 0, .len = 1 },              /* NOP */
+
+       [0xC3] = { .flags = 0, .len = 1 },              /* CLR C */
+       [0xC2] = { .flags = 0, .len = 2 },              /* CLR bit */
+       [0xD3] = { .flags = 0, .len = 1 },              /* SETB C */
+       [0xD2] = { .flags = 0, .len = 2 },              /* SETB bit */
+       
+       [0xB3] = { .flags = 0, .len = 1 },              /* CPL C */
+       [0xB2] = { .flags = 0, .len = 2 },              /* CPL bit */
+       
+       [0x82] = { .flags = 0, .len = 2 },              /* ANL C,bit */
+       [0xB0] = { .flags = 0, .len = 2 },              /* ANL C,/bit */
+       [0x72] = { .flags = 0, .len = 2 },              /* ORL C,bit */
+       [0xA0] = { .flags = 0, .len = 2 },              /* ORL C,/bit */
+       
+       [0xA2] = { .flags = 0, .len = 2 },              /* MOV C,bit */
+       [0x92] = { .flags = 0, .len = 2 },              /* MOV bit,C */
+       
+       [0xA5] = { .flags = 0, .len = 1 },              /* TRAP */
+};
+
+#define RET    0x22
+#define RETI   0x32
+
+#define PUSH           0xC0
+#define POP            0xD0
+#define MOV_direct_A   0xF5
+#define MOV_A_direct   0xE5
+#define ADD_A_imm      0x24
+#define SP             0x81
+#define RET            0x22
+#define RETI           0x32
+#define LJMP_addr16    0x02
+#define SJMP_rel       0x80
+
+static int stack_change(unsigned addr)
+{
+       unsigned char insn;
+       unsigned char direct;
+
+       insn = simGetValue(addr, 'C', 1);
+       switch (insn) {
+       case PUSH:
+               return 1;
+       case POP:
+               return -1;
+       case MOV_direct_A:
+               direct = simGetValue(addr+1, 'C', 1);
+               if (direct == SP) {
+                       unsigned char   add_insn;
+                       unsigned char   add_direct;
+
+                       add_insn = simGetValue(addr-2, 'C', 1);
+                       if (add_insn == ADD_A_imm) {
+                               add_direct = simGetValue(addr-1, 'C', 1);
+                               return (signed char) add_direct;
+                       }
+               }
+               break;
+       case RET:
+               return 0;
+       case RETI:
+               return 1;
+       default:
+               return 0;
+       }
+}
+
+static void
+do_indent(int indent);
+
+#if 1
+#define DPC(x)
+#else
+#define DPC(x) do { do_indent(indent); printf x; } while (0);
+#endif
+
+static int pc_change(unsigned addr, unsigned addrs[2], int indent)
+{
+       unsigned char insn;
+       unsigned new_addr;
+       signed char delta;
+       int len;
+
+       insn = simGetValue(addr, 'C', 1);
+       if (instructions[insn].flags & IS_RET)
+               return 0;
+
+       if (!(instructions[insn].flags & IS_BRANCH)) {
+               addrs[0] = addr + instructions[insn].len;
+               return 1;
+       }
+
+       if (insn == LJMP_addr16) {
+               addrs[0] = ((simGetValue(addr+1, 'C', 1) << 8) |
+                         (simGetValue(addr+2, 'C', 1)));
+               DPC(("0x%04x LJMP 0x%04x\n", addr, addrs[0]));
+               return 1;
+       }
+       
+       /* AJMP */
+       if ((insn & 0x1f) == 0x01) {
+               unsigned char   direct = simGetValue(addr+1,'C', 1);
+
+               addrs[0] = ((addr + 2) & 0xf800) | ((insn & 0xe0) << 3) | direct;
+               DPC(("0x%04x AJMP 0x%04x\n", addr, addrs[0]));
+               return 1;
+       }
+
+       /* otherwise, relative branch */
+       len = instructions[insn].len;
+
+       delta = (signed char) simGetValue(addr+len-1, 'C', 1);
+       new_addr = (addr + len) + delta;
+       
+       if (insn == SJMP_rel || (addr + len) == new_addr) {
+               addrs[0] = new_addr;
+               DPC(("0x%04x SJMP 0x%04x\n", addr, addrs[0]));
+               return 1;
+       }
+       addrs[0] = (addr + len) & 0xffff;
+       addrs[1] = new_addr & 0xffff;
+
+       DPC(("0x%04x SJMP 0x%04x 0x%04x\n", addr, addrs[0], addrs[1]));
+       return 2;
+}
+
+#define SEARCH_LOOP    0x8000
+#define SEARCH_EXPIRED 0x8001
+
+#define MAX_STACK_BRANCH_TRACE 8192
+static unsigned stack_branch_trace[MAX_STACK_BRANCH_TRACE];
+
+static int
+been_here(unsigned pc, int ntrace)
+{
+       int t;
+       
+       for (t = 0; t < ntrace; t++)
+               if (stack_branch_trace[t] == pc)
+                       return 1;
+       return 0;
 }
 
+#define MAX_SEARCH     100
+
+#define indent (MAX_SEARCH - search)
+
+static int
+stack_depth(unsigned pc, int search, int ntrace)
+{
+       unsigned new_pc[2];
+       int d[2];
+       int n;
+       int s;
+       int change;
+
+       change = 0;
+       for (;;) {
+               change += stack_change(pc);
+               n = pc_change(pc, new_pc, MAX_SEARCH - search);
+               if (n == 0)
+                       return change;
+               if (n != 1)
+                       break;
+               if (new_pc[0] <= pc) {
+                       if (been_here(pc, ntrace)) {
+                               DPC(("0x%04x loop 1\n", pc));
+                               return SEARCH_LOOP;
+                       }
+                       stack_branch_trace[ntrace++] = pc;
+               }
+               pc = new_pc[0];
+       }
+       
+       if (search == 0) {
+               DPC(("0x%04x max depth\n", pc));
+               return SEARCH_EXPIRED;
+       }
+       
+       if (been_here(pc, ntrace))
+       {
+               DPC(("0x%04x loop 2\n", pc));
+               return SEARCH_LOOP;
+       }
+       stack_branch_trace[ntrace++] = pc;
+
+       for (s = 0; s < search - 1; s++) {
+               int i, j, d;
+               
+               i = 0;
+               while (i < n) {
+                       d = stack_depth(new_pc[i], search-1, ntrace);
+                       if (d == SEARCH_LOOP) {
+                               for (j = i; j < n-1; j++)
+                                       new_pc[j] = new_pc[j+1];
+                               n--;
+                               continue;
+                       }
+                       if (d != SEARCH_EXPIRED) {
+                               DPC(("success %d\n", d + change));
+                               return d + change;
+                       }
+                       i++;
+               }
+               if (n == 0) {
+                       DPC(("0x%04x loop 3\n", pc));
+                       return SEARCH_LOOP;
+               }
+       }
+       DPC(("search expired\n"));
+       return SEARCH_EXPIRED;
+}
+
+#undef indent
+
+unsigned int
+stack_start(void)
+{
+       symbol *start_stack = symLookup("__start_stack", NULL);
+       if (start_stack)
+               return start_stack->addr;
+       return 0x8;
+}
+
+static int
+frameStart(unsigned int *bpp, unsigned int *pcp)
+{
+       unsigned int bp;
+       unsigned int sp;
+       unsigned int pc;
+       int depth;
+       symbol *bp_sym;
+
+       pc = simGetPC();
+       sp = simGetValue(0x81,'I',1);
+       depth = stack_depth(pc, MAX_SEARCH, 0);
+       if (depth == SEARCH_LOOP || depth == SEARCH_EXPIRED)
+               bp = 0;
+       else
+               bp = sp + depth;
+       *bpp = bp;
+       *pcp = pc;
+       return 1;
+}
+
+static int
+frameNext(unsigned int *bpp, unsigned int *pcp)
+{
+       unsigned int bp = *bpp;
+       unsigned int pc;
+       int depth;
+       symbol *start_stack;
+
+       if (bp < stack_start())
+               return 0;
+       pc = simGetValue(bp - 1, 'B', 2);
+       if (pc == 0xffff)
+               return 0;
+       depth = stack_depth(pc, MAX_SEARCH, 0);
+       if (depth == SEARCH_LOOP || depth == SEARCH_EXPIRED)
+               bp = 0;
+       else
+               bp = bp - 2 + depth;
+       *bpp = bp;
+       *pcp = pc;
+       return 1;
+}
+
+static int running = 0;
+
+static int is_running(void) {
+    return running;
+}
+
+static int set_running(int run) {
+    running = run;
+}
 
 /*-----------------------------------------------------------------*/
 /* simGo - send 'go' cmd to simulator and wait till a break occurs */
 /*-----------------------------------------------------------------*/
 void simGo (unsigned int gaddr)
-{   
+{
     unsigned int addr ;
     context *ctxt;
     int rv;
     stopCommandList();
- top:    
+ top:
     if ( userinterrupt )
     {
         userinterrupt = 0;
         return;
     }
+#if 0
+    if ( gaddr == 0 )
+    {
+        function *func = NULL;;
+        if (applyToSet(functions,funcInAddr,gaddr,&func))
+            STACK_PUSH(callStack,func);
+    }
+#endif
     addr = simGoTillBp (gaddr);
 
     /* got the pc for the break point now first
-       discover the program context i.e. module, function 
+       discover the program context i.e. module, function
        linenumber of the source etc, etc etc */
-    currentFrame = 0; 
-    ctxt = discoverContext (addr, NULL);
-    
+    currentFrame = 0;
+    ctxt = discoverContext (addr, NULL, currCtxt);
+
     /* dispatch all the break point call back functions */
-    rv = dispatchCB (addr,ctxt);    
- ret:    
+    rv = dispatchCB (addr,ctxt);
 
     /* the dispatch call back function will return
        non-zero if an user break point has been hit
-       if not then we continue with the execution 
+       if not then we continue with the execution
        of the program */
-    if (!rv) 
+    if (!rv)
     {
-               if ( gaddr == 0 )
+        if ( gaddr == 0 )
             gaddr = -1;
-               if ( gaddr == -1 || doingSteps == 1 )
+        if ( gaddr == -1 || doingSteps == 1 )
             goto top ;
     }
-    
+
 }
 
 /*-----------------------------------------------------------------*/
@@ -739,20 +1318,17 @@ void simGo (unsigned int gaddr)
 /*-----------------------------------------------------------------*/
 static char *preparePrint(char *s, context *cctxt, int *fmt, symbol **sym)
 {
-    char *bp = s+strlen(s) -1;
+    char *bp;
     char save_ch ;
+    int ptr = 0;
 
     *fmt = FMT_NON;
     *sym = NULL;
 
-    while (isspace(*s)) s++;
-    if (!*s) 
+    s = trim(s);
+    if (!*s)
         return (char *)0;
 
-    while (isspace(*bp)) bp--;
-    bp++ ;
-    *bp = '\0';
-
     if ( *s == '/' )
     {
         /* format of printout */
@@ -773,7 +1349,11 @@ static char *preparePrint(char *s, context *cctxt, int *fmt, symbol **sym)
                 break;
         }
         s++;
-        while (isspace(*s)) s++;
+        s = trim_left(s);
+    }
+    while (*s == '*') {
+       ptr++;
+       s++;
     }
     for ( bp = s; *bp && ( isalnum( *bp ) || *bp == '_' || *bp == '$'); bp++ );
     save_ch = *bp;
@@ -783,17 +1363,19 @@ static char *preparePrint(char *s, context *cctxt, int *fmt, symbol **sym)
     if ( *s )
         *sym = symLookup(s,cctxt);
     *bp = save_ch;
+    while (ptr--)
+       strcat(bp,"*");
 
     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)
+static int printAsmLine( function *func, module *m, unsigned saddr, unsigned eaddr)
 {
     int i,j,delta;
-    int symaddr;
-    int lastaddr = saddr+1;
+    unsigned symaddr;
+    unsigned lastaddr = saddr+1;
     char *symname;
 
     if ( func )
@@ -806,7 +1388,7 @@ static int printAsmLine( function *func, module *m, long saddr, long eaddr)
         symaddr = saddr;
         symname = "" ;
     }
-    for (j=0,i=0; i < m->nasmLines; i++ ) 
+    for (j=0,i=0; i < m->nasmLines; i++ )
     {
         if ( saddr >= 0 && m->asmLines[i]->addr < saddr)
         {
@@ -816,12 +1398,12 @@ static int printAsmLine( function *func, module *m, long saddr, long eaddr)
         {
                 continue;
         }
-        if ( func && 
+        if ( func &&
             (m->asmLines[i]->addr < func->sym->addr ||
              m->asmLines[i]->addr > func->sym->eaddr ))
         {
             continue;
-        } 
+        }
         delta = m->asmLines[i]->addr - symaddr;
         if ( delta >= 0 )
         {
@@ -829,7 +1411,7 @@ static int printAsmLine( function *func, module *m, long saddr, long eaddr)
             lastaddr = m->asmLines[i]->addr;
             printf("0x%08x <%s",lastaddr,symname);
             if (delta > 0) printf("+%d",delta);
-            printf(">:\t%s",m->asmLines[i]->src);            
+            printf(">:\t%s",m->asmLines[i]->src);
         }
     }
     return lastaddr;
@@ -849,14 +1431,14 @@ static int cmdDisasm (char *s, context *cctxt, int args)
 
     if ( args > 0 )
     {
-        while (*s && isspace(*s)) s++;
+        s = trim_left(s);
 
         if ( isdigit(*s))
         {
             saddr = strtol(s,&s,0);
             if ( args > 1 )
             {
-                while (*s && isspace(*s)) s++;
+                s = trim_left(s);
 
                 if ( isdigit(*s))
                     eaddr = strtol(s,0,0);
@@ -867,7 +1449,7 @@ static int cmdDisasm (char *s, context *cctxt, int args)
     }
 
     if ( eaddr == -1 )
-    {       
+    {
         /* no start or only start so dump function */
         if ( saddr == -1 )
         {
@@ -882,7 +1464,7 @@ static int cmdDisasm (char *s, context *cctxt, int args)
             printf("Dump of assembler code for function %s:\n",func->sym->name);
             printAsmLine(func,func->mod,-1,-1);
             printf("End of assembler dump.\n");
-            return 0; 
+            return 0;
         }
         else
         {
@@ -892,14 +1474,14 @@ static int cmdDisasm (char *s, context *cctxt, int args)
                 printf("Dump of assembler code:\n");
                 printAsmLine(NULL,modul,saddr,eaddr);
                 printf("End of assembler dump.\n");
-                return 0; 
+                return 0;
             }
         }
     }
     else
     {
         if ( args > 1 )
-            printf("Dump of assembler code from 0x%08x to 0x%08x:\n",saddr,eaddr);
+            printf("Dump of assembler code from 0x%08lx to 0x%08lx:\n",saddr,eaddr);
         found = 0;
         while ( saddr < eaddr )
         {
@@ -922,12 +1504,20 @@ static int cmdDisasm (char *s, context *cctxt, int args)
         {
             if ( args > 1 )
                 printf("End of assembler dump.\n");
-            return 0; 
+            return 0;
         }
-        
+
     }
     fprintf(stderr,"No function contains specified address.\n");
-    return 0; 
+    if( saddr >= 0 )
+    {
+        char lbuf[64];
+        sprintf(lbuf,"dis 0x%lx 0 %ld\n",saddr,( eaddr == -1 )?1L:eaddr-saddr);
+        sendSim(lbuf);
+        waitForSim(1000, NULL);
+        fputs(simResponse(),stdout);
+    }
+    return 0;
 }
 /*-----------------------------------------------------------------*/
 /* cmdDisasm1 - disassemble one asm instruction                    */
@@ -949,7 +1539,7 @@ static int commonSetUserBp(char *s, context *cctxt, char bpType)
 {
     char *bp ;
     function *func = NULL;
-       
+
     /* user break point location specification can be of the following
        forms
        a) <nothing>        - break point at current location
@@ -957,42 +1547,37 @@ static int commonSetUserBp(char *s, context *cctxt, char bpType)
        c) filename:lineno  - line number of the given file
        e) filename:function- function X in file Y (useful for static functions)
        f) function         - function entry point
-       g) *addr            - break point at address 
+       g) *addr            - break point at address
     */
 
     if (!cctxt) {
-       fprintf(stdout,"No symbol table is loaded.  Use the \"file\" command.\n");
-       return 0;
+        fprintf(stdout,"No symbol table is loaded.  Use the \"file\" command.\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';
+    /* trim left and right */
+    s = trim(s);
 
     /* case a) nothing */
     /* if nothing given then current location : we know
        the current execution location from the currentContext */
     if (! *s ) {
 
-       /* if current context is known */
-       if (cctxt->func) {
+        /* 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 , bpType , userBpCB ,
-                               cctxt->func->mod->c_name, cctxt->cline);
-           else
-               setBreakPoint ( cctxt->addr , CODE , bpType , userBpCB ,
-                               cctxt->func->mod->asm_name, cctxt->asmline);
-               
-       }
-       else
-           fprintf(stderr,"No default breakpoint address now.\n");
-                       
-       goto ret ;
+            if (srcMode == SRC_CMODE)
+                /* set the break point */
+                setBreakPoint ( cctxt->addr , CODE , bpType , userBpCB ,
+                                cctxt->func->mod->c_name, cctxt->cline);
+            else
+                setBreakPoint ( cctxt->addr , CODE , bpType , userBpCB ,
+                                cctxt->func->mod->asm_name, cctxt->asmline);
+
+        }
+        else
+            fprintf(stderr,"No default breakpoint address now.\n");
+
+        goto ret ;
     }
     /* case g) *addr */
     if ( *s == '*' && isdigit(*(s+1)))
@@ -1004,17 +1589,17 @@ static int commonSetUserBp(char *s, context *cctxt, char bpType)
             module *modul;
             if (!applyToSet(modules,moduleLineWithAddr,braddr,&modul,&line))
             {
-                fprintf(stderr,"Address 0x%08x not exists in code.\n",braddr); 
+                fprintf(stderr,"Address 0x%08lx not exists in code.\n",braddr);
             }
             else
             {
-                Dprintf(D_break, ("commonSetUserBp: g) addr:%x \n",braddr));
+                Dprintf(D_break, ("commonSetUserBp: g) addr:%lx \n",braddr));
                 setBreakPoint ( braddr , CODE , bpType , userBpCB ,
                             modul->c_name,line);
             }
             goto ret ;
         }
-               else
+                else
         {
             int line = func->exitline;
             if ( !applyToSet(func->cfpoints,lineAtAddr,braddr,
@@ -1023,87 +1608,91 @@ static int commonSetUserBp(char *s, context *cctxt, char bpType)
             setBreakPoint ( braddr , CODE , bpType , userBpCB ,
                             func->mod->c_name,line);
         }
-       goto ret ;
+        goto ret ;
     }
     /* case b) lineno */
     /* check if line number */
     if ( !strchr(s,':') && isdigit(*s)) {
-       /* get the lineno */
-       int line = atoi(s) -1;
+        /* get the lineno */
+        int line = atoi(s) -1;
     Dprintf(D_break, ("commonSetUserBp: b) line:%d \n",line));
+    if ( line < 0 )
+    {
+                fprintf(stdout,"linenumber <= 0\n");
+        goto ret;
+    }
+        /* if current context not present then we must get the module
+           which has main & set the break point @ line number provided
+           of that module : if current context known then set the bp
+           at the line number given for the current module
+        */
+        if (cctxt->func) {
+            if (!cctxt->func->mod) {
+                if (!applyToSet(functions,funcWithName,"main"))
+                    fprintf(stderr,"Function \"main\" not defined.\n");
+                else
+                    setBPatModLine(func->mod,line, bpType);
+            } else
+                setBPatModLine(cctxt->func->mod,line, bpType);
+        } else {
+                if (list_mod) {
+                        setBPatModLine(list_mod,line, bpType);
+                } else {
+                  fprintf(stdout,"Sdcdb fails to have module symbol context at %d\n", __LINE__);
+                }
+        }
 
-       /* if current context not present then we must get the module
-          which has main & set the break point @ line number provided
-          of that module : if current context known then set the bp 
-          at the line number given for the current module 
-       */
-       if (cctxt->func) {
-           if (!cctxt->func->mod) {
-               if (!applyToSet(functions,funcWithName,"main"))
-                   fprintf(stderr,"Function \"main\" not defined.\n");
-               else 
-                   setBPatModLine(func->mod,line, bpType);
-           } else 
-               setBPatModLine(cctxt->func->mod,line, bpType);
-       } else {
-               if (list_mod) {
-                       setBPatModLine(list_mod,line, bpType);
-               } else {
-                 fprintf(stdout,"Sdcdb fails to have module symbol context at %d\n", __LINE__);
-               }
-       }
-       
-       goto ret;
+        goto ret;
     }
 
     if ((bp = strchr(s,':'))) {
-       
-       module *mod = NULL;
-       *bp = '\0';
-       
-       if (srcMode == SRC_CMODE) {
-           if (!applyToSet(modules,moduleWithCName,s,&mod)) {
-               fprintf (stderr,"No source file named %s.\n",s);
-               goto ret;
-           }
-       } else {
-           if (!applyToSet(modules,moduleWithAsmName,s,&mod)) {
-               fprintf (stderr,"No source file named %s.\n",s);
-               goto ret;
-           }
-       }
-               
-       /* case c) filename:lineno */
-       if (isdigit(*(bp +1))) {                         
+
+        module *mod = NULL;
+        *bp = '\0';
+
+        if (srcMode == SRC_CMODE) {
+            if (!applyToSet(modules,moduleWithCName,s,&mod)) {
+                fprintf (stderr,"No source file named %s.\n",s);
+                goto ret;
+            }
+        } else {
+            if (!applyToSet(modules,moduleWithAsmName,s,&mod)) {
+                fprintf (stderr,"No source file named %s.\n",s);
+                goto ret;
+            }
+        }
+
+        /* case c) filename:lineno */
+        if (isdigit(*(bp +1))) {
         Dprintf(D_break, ("commonSetUserBp: c) line:%d \n",atoi(bp+1)));
-           setBPatModLine (mod,atoi(bp+1)-1,bpType);       
-           goto ret;
-           
-       }
-       /* case d) filename:function */
-       if (!applyToSet(functions,funcWithNameModule,bp+1,s,&func)) 
-           fprintf(stderr,"Function \"%s\" not defined.\n",bp+1); 
-       else        
+            setBPatModLine (mod,atoi(bp+1)-1,bpType);
+            goto ret;
+
+        }
+        /* case d) filename:function */
+        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),bpType);
-       
-       goto ret;
+            setBPatModLine (mod,
+                            (srcMode == SRC_CMODE ?
+                             func->entryline :
+                             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); 
+        fprintf(stderr,"Function \"%s\" not defined.\n",s);
     else
-       setBPatModLine(func->mod,
-                      (srcMode == SRC_CMODE ?
-                       func->entryline :
-                       func->aentryline),bpType);
+        setBPatModLine(func->mod,
+                       (srcMode == SRC_CMODE ?
+                        func->entryline :
+                        func->aentryline),bpType);
 
- ret:    
+ ret:
     return 0;
 }
 
@@ -1128,22 +1717,18 @@ int cmdSetUserBp (char *s, context *cctxt)
 /*-----------------------------------------------------------------*/
 int cmdJump (char *s, context *cctxt)
 {
-    char *bp ;
+    char *bp;
     function *func = NULL;
-    if (STACK_EMPTY(callStack)) 
+    if (!is_running())
     {
         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 ) 
+    /* trim left and right */
+    s = trim(s);
+
+    if (! *s )
     {
         fprintf(stdout,"No argument: need line or *addr.\n");
         return 0;
@@ -1162,13 +1747,13 @@ int cmdJump (char *s, context *cctxt)
         simSetPC(addr);
         return 0;
     }
-    if (isdigit(*s)) 
+    if (isdigit(*s))
     {
         /* get the lineno */
         int line = atoi(s) -1;
-        if (!cctxt || !cctxt->func || !cctxt->func->mod) 
+        if (!cctxt || !cctxt->func || !cctxt->func->mod)
         {
-                   fprintf(stderr,"Function not defined.\n");
+                    fprintf(stderr,"Function not defined.\n");
             return 0;
         }
         if (line >= cctxt->func->entryline &&
@@ -1179,32 +1764,32 @@ int cmdJump (char *s, context *cctxt)
         }
         if (line >= cctxt->func->mod->ncLines )
         {
-                   fprintf(stderr,"line not in module.\n");
+                    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,':'))) 
+    if ((bp = strchr(s,':')))
     {
         int line;
         module *mod = NULL;
         *bp++ = '\0';
-        if (!applyToSet(modules,moduleWithCName,s,&mod)) 
+        if (!applyToSet(modules,moduleWithCName,s,&mod))
         {
             fprintf (stderr,"No source file named %s.\n",s);
             return 0;
-        } 
-        if (!isdigit(*bp)) 
-        {                       
+        }
+        if (!isdigit(*bp))
+        {
             fprintf (stderr,"No line number.\n");
-            return 0;      
+            return 0;
         }
         line = atoi(bp) -1;
         if (line >= mod->ncLines )
         {
-                   fprintf(stderr,"line not in module.\n");
+                    fprintf(stderr,"line not in module.\n");
             return 0;
         }
         if ( mod != cctxt->func->mod ||
@@ -1213,7 +1798,7 @@ int cmdJump (char *s, context *cctxt)
         {
             fprintf(stdout,"Warning line %d outside actual function.\n",
                     line+1);
-        }             
+        }
         simSetPC(mod->cLines[line]->addr);
     }
     return 0;
@@ -1224,12 +1809,15 @@ int cmdJump (char *s, context *cctxt)
 /*-----------------------------------------------------------------*/
 int cmdListAsm (char *s, context *cctxt)
 {
-    if (  cctxt && cctxt->func) 
+    if (  cctxt && cctxt->func)
     {
         /* actual line */
-        if (printAsmLine(cctxt->func,cctxt->func->mod,
+        if ( cctxt->addr != INT_MAX )
+        {
+            if (printAsmLine(cctxt->func,cctxt->func->mod,
                          (long)cctxt->addr,(long)cctxt->addr))
-            return 0; 
+            return 0;
+        }
     }
     return 0;
 }
@@ -1239,18 +1827,18 @@ int cmdListAsm (char *s, context *cctxt)
 /*-----------------------------------------------------------------*/
 int cmdSetOption (char *s, context *cctxt)
 {
-    while (*s && isspace(*s)) s++;
+    s = trim_left(s);
     if (strncmp(s,"srcmode",7) == 0 ) {
-       if (srcMode == SRC_CMODE)
-           srcMode = SRC_AMODE;
-       else
-           srcMode = SRC_CMODE;
-       fprintf(stderr,"source mode set to '%s'\n", 
-               (srcMode == SRC_CMODE ? "C" : "asm"));
-       return 0;
+        if (srcMode == SRC_CMODE)
+            srcMode = SRC_AMODE;
+        else
+            srcMode = SRC_CMODE;
+        fprintf(stderr,"source mode set to '%s'\n",
+                (srcMode == SRC_CMODE ? "C" : "asm"));
+        return 0;
     }
 
-    if (strncmp(s,"listsize ",9) == 0) 
+    if (strncmp(s,"listsize ",9) == 0)
     {
         listlines = strtol(s+9,0,0);
         if ( listlines < LISTLINES )
@@ -1259,13 +1847,13 @@ int cmdSetOption (char *s, context *cctxt)
     }
 
 #ifdef SDCDB_DEBUG
-    if (strncmp(s,"debug ",6) == 0) 
+    if (strncmp(s,"debug ",6) == 0)
     {
         sdcdbDebug = strtol(s+6,0,0);
         return 0;
     }
 #endif
-    if (strncmp(s,"variable ",9) == 0) 
+    if (strncmp(s,"variable ",9) == 0)
     {
         symbol *sym ;
         int fmt;
@@ -1276,7 +1864,7 @@ int cmdSetOption (char *s, context *cctxt)
         s = rs;
         while (*s && *s != '=') s++;
         *s++ = '\0';
-        while (isspace(*s)) *s++ = '\0';
+        s = trim_left(s);
         if (*s && sym)
         {
             printOrSetSymValue(sym,cctxt,0,0,0,rs,s,'\0');
@@ -1284,10 +1872,10 @@ int cmdSetOption (char *s, context *cctxt)
         }
         else
             fprintf(stdout,"No new value for \"%s\".\n",s);
-        return 0;       
+        return 0;
     }
 
+
     fprintf(stderr,"'set %s' command not yet implemented\n",s);
     return 0;
 }
@@ -1297,9 +1885,9 @@ int cmdSetOption (char *s, context *cctxt)
 /*-----------------------------------------------------------------*/
 int cmdContinue (char *s, context *cctxt)
 {
-    if (STACK_EMPTY(callStack)) {
-       fprintf(stdout,"The program is not being run.\n");
-       return 0;
+    if (!is_running()) {
+        fprintf(stdout,"The program is not being run.\n");
+        return 0;
     }
 
     fprintf(stdout,"Continuing.\n");
@@ -1312,17 +1900,17 @@ int cmdContinue (char *s, context *cctxt)
 /* cmdIgnore - set ignorecount for breakpoint                      */
 /*-----------------------------------------------------------------*/
 int cmdIgnore (char *s, context *cctxt)
-{   
+{
     int bpnum, cnt ;
-    while (isspace(*s)) s++;
-    if (!*s ) 
+    s = trim_left(s);
+    if (!*s )
     {
         fprintf(stdout,"Argument required (breakpoint number).\n");
         return 0;
     }
     bpnum = strtol(s,&s,10);
-    while (isspace(*s)) s++;
-    if (!*s ) 
+    s = trim_left(s);
+    if (!*s )
     {
         fprintf(stdout,"Second argument (specified ignore-count) is missing.");
         return 0;
@@ -1336,16 +1924,16 @@ int cmdIgnore (char *s, context *cctxt)
 /* cmdCondition - set condition for breakpoint                     */
 /*-----------------------------------------------------------------*/
 int cmdCondition (char *s, context *cctxt)
-{   
+{
     int bpnum ;
-    while (isspace(*s)) s++;
-    if (!*s ) 
+    s = trim_left(s);
+    if (!*s )
     {
         fprintf(stdout,"Argument required (breakpoint number).\n");
         return 0;
     }
     bpnum = strtol(s,&s,10);
-    while (isspace(*s)) s++;
+    s = trim_left(s);
     if (*s)
         s = Safe_strdup(s);
     else
@@ -1358,12 +1946,12 @@ int cmdCondition (char *s, context *cctxt)
 /* cmdCommands - set commands for breakpoint                       */
 /*-----------------------------------------------------------------*/
 int cmdCommands (char *s, context *cctxt)
-{   
+{
     int bpnum ;
     char *cmds,*line;
-    while (isspace(*s)) s++;
-    
-    if (!*s ) 
+    s = trim_left(s);
+
+    if (!*s )
         bpnum = getLastBreakptNumber();
     else
         bpnum = strtol(s,0,10);
@@ -1371,7 +1959,7 @@ int cmdCommands (char *s, context *cctxt)
     cmds = NULL;
     while ((line = getNextCmdLine()))
     {
-        while (isspace(*line)) line++;
+        line = trim_left(line);
         if (!strncmp(line,"end",3))
             break;
         if (! cmds )
@@ -1394,23 +1982,23 @@ int cmdCommands (char *s, context *cctxt)
 int cmdDelUserBp (char *s, context *cctxt)
 {
     int bpnum ;
-    while (isspace(*s)) s++;
-    
+    s = trim_left(s);
+
     if (!*s ) {
-       if (userBpPresent) {
-           char buffer[10];
-           fprintf (stdout,"Delete all breakpoints? (y or n) ");
-           fflush(stdout);
-           fgets(buffer,sizeof(buffer),stdin);
-           if (toupper(buffer[0]) == 'Y')
-               deleteUSERbp(-1);          
-       }
-       return 0;
+        if (userBpPresent) {
+            char buffer[10];
+            fprintf (stdout,"Delete all breakpoints? (y or n) ");
+            fflush(stdout);
+            fgets(buffer,sizeof(buffer),stdin);
+            if (toupper(buffer[0]) == 'Y')
+                deleteUSERbp(-1);
+        }
+        return 0;
     }
-    
+
     /* determine the break point number */
     if (sscanf(s,"%d",&bpnum) == 1)
-       deleteUSERbp(bpnum);
+        deleteUSERbp(bpnum);
 
     return 0;
 }
@@ -1421,98 +2009,149 @@ int cmdDelUserBp (char *s, context *cctxt)
 int cmdStepi (char *s, context *cctxt)
 {
 
-    if (STACK_EMPTY(callStack))
+    if (!is_running())
         fprintf(stdout,"The program is not being run.\n");
-    else 
+    else
     {
         doingSteps = 2;
-           simGo(2);   
+            simGo(2);
         doingSteps = 0;
         showfull = 1;
     }
     return 0;
 }
 
+static unsigned line_start_addr(context *ctx, int line)
+{
+       function *func = ctx->func;
+       module *mod = func->mod;
+       unsigned addr;
+       int nlines;
+       
+       if (srcMode == SRC_CMODE)
+               nlines = mod->ncLines;
+       else
+               nlines = mod->nasmLines;
+
+       do {
+               if (srcMode == SRC_CMODE)
+                       addr = mod->cLines[line]->addr;
+               else
+                       addr = mod->asmLines[line]->addr;
+               ++line;
+       } while (addr == 0x7fffffff && line < nlines);
+       if (addr == 0x7fffffff)
+               addr = func->sym->eaddr;
+       return addr;
+}
+
+static unsigned line_end_addr(context *ctx, int line)
+{
+       function *func = ctx->func;
+       module *mod = func->mod;
+       int next_line, nlines;
+       unsigned start_addr = line_start_addr(ctx, line);
+       unsigned next_addr = func->sym->eaddr + 1;
+       unsigned addr;
+
+       if (srcMode == SRC_CMODE)
+               nlines = mod->ncLines;
+       else
+               nlines = mod->nasmLines;
+       for (next_line = 0; next_line < nlines; next_line++) {
+               if (next_line == line)
+                       continue;
+               if (srcMode == SRC_CMODE)
+                       addr = mod->cLines[next_line]->addr;
+               else
+                       addr = mod->asmLines[next_line]->addr;
+               if (start_addr < addr && addr < next_addr)
+                       next_addr = addr;
+       }
+       return next_addr;
+}
+
+BP_CALLBACK(step_bp_callback)
+{
+       deleteSTEPbp();
+       return 1;
+}
+
+static int do_step(context *ctx, int into)
+{
+       function *func = ctx->func;
+       module *mod = func->mod;
+       srcLine **lines;
+       srcLine *line;
+       int     nlines;
+       int     start, end;
+       int     start_l;
+       unsigned len;
+       unsigned start_addr, end_addr, addr;
+       unsigned char insn;
+       unsigned char flags;
+       
+       if (srcMode == SRC_CMODE) {
+               lines = mod->cLines;
+               nlines = mod->ncLines;
+               start_l = ctx->cline;
+       } else {
+               lines = mod->asmLines;
+               nlines = mod->nasmLines;
+               start_l = ctx->asmline;
+       }
+       if (start_l == -1)
+               return 0;
+       flags = IS_BRANCH|IS_RET;
+       if (into)
+               flags |= IS_CALL;
+       line = lines[start_l];
+       start = line_start_addr(ctx, start_l);
+       end = line_end_addr(ctx, start_l);
+
+       while (start <= ctx->addr && ctx->addr < end) {
+               insn = 0xff;
+               for (addr = ctx->addr; addr < end; addr += len) {
+                       insn = simGetValue(addr, 'C', 1);
+                       if (instructions[insn].flags & flags)
+                               break;
+                       len = instructions[insn].len;
+                       if (len == 0) {
+                               fprintf(stderr, "Unknown opcode 0x%02x\n", insn);
+                               return 0;
+                       }
+               }
+               if (addr != ctx->addr) {
+                       setBreakPoint(addr, CODE, STEP,
+                                     step_bp_callback,
+                                     mod->name, start_l);
+                       doingSteps = 1;
+                       /* run to breakpoint */
+                       simGo(-1);
+                       doingSteps = 0;
+               }
+               /* step over instruction at breakpoint */
+               if (start <= ctx->addr && ctx->addr < end) {
+                       doingSteps = 2;
+                       simGo(2);
+                       doingSteps = 0;
+               }
+       }
+       stepBpCB(ctx->addr, NULL, ctx);
+       showfull = 1;
+}
+
 /*-----------------------------------------------------------------*/
 /* cmdStep - single step thru C source file                        */
 /*-----------------------------------------------------------------*/
 int cmdStep (char *s, context *cctxt)
 {
-    function *func = NULL;
-
-    if (STACK_EMPTY(callStack))
-        fprintf(stdout,"The program is not being run.\n");
-    else {
-        /* 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); 
-           
-            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);
-               
-                /* 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);
-               
-                /* now break point @ callers execution points */
-                if ((func = STACK_PPEEK(callStack))) {
-                   
-                    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);
-                }
-            }
-        }
+    function *func = NULL;
 
-        doingSteps = 1;
-        simGo(2);
-        doingSteps = 0;
-        showfull = 1;
-    }
+    if (!is_running())
+        fprintf(stdout,"The program is not being run.\n");
+    else
+       do_step(cctxt, 1);
     return 0;
 }
 
@@ -1521,15 +2160,15 @@ int cmdStep (char *s, context *cctxt)
 /*-----------------------------------------------------------------*/
 int cmdNexti (char *s, context *cctxt)
 {
-    if (STACK_EMPTY(callStack))
+    if (!is_running())
         fprintf(stdout,"The program is not being run.\n");
-    else 
+    else
     {
         doingSteps = 2;
-           simGo(1);   
+            simGo(1);
         doingSteps = 0;
         showfull = 1;
-    }  
+    }
     return 0;
 }
 
@@ -1542,67 +2181,10 @@ 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 (STACK_EMPTY(callStack))
+    if (!is_running())
         fprintf(stdout,"The program is not being run.\n");
-    else {
-        /* 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->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;
-    }    
+    else
+       do_step(cctxt, 0);
     return 0;
 }
 
@@ -1612,30 +2194,32 @@ int cmdNext (char *s, context *cctxt)
 int cmdRun (char *s, context *cctxt)
 {
     char buff[10];
-    if (STACK_EMPTY(callStack)) {
-       fprintf(stdout,"Starting program\n");
+
+    if (!is_running()) {
+        fprintf(stdout,"Starting program\n");
     if ( ! simactive )
     {
         fprintf(stdout,"No executable file specified.\nUse the \"file\" command.\n");
         return 0;
     }
     resetHitCount();
-       simGo(0);
+        simGo(0);
     } else {
-       
-       fprintf(stdout,
-               "The program being debugged has been started already.\n");
-       fprintf(stdout,"Start it from the beginning? (y or n) ");
-       fflush(stdout);
-
-       fgets(buff,sizeof(buff),stdin);
-       if (toupper(buff[0]) == 'Y') {
-           simReset();
+
+        fprintf(stdout,
+                "The program being debugged has been started already.\n");
+        fprintf(stdout,"Start it from the beginning? (y or n) ");
+        fflush(stdout);
+
+        fgets(buff,sizeof(buff),stdin);
+        if (toupper(buff[0]) == 'Y') {
+            simReset();
         resetHitCount();
-           simGo(0);
-       }
+            simGo(0);
+        }
     }
     showfull = 1;
+    set_running(1);
     return 0;
 }
 
@@ -1668,11 +2252,11 @@ int cmdListSymbols (char *s, context *cctxt)
           sy->name, sy->size, sy->level, sy->block);
         printf("    isonstack:%d, isfunc:%d, offset:%d addr:%d\n",
           sy->isonstack, sy->isfunc, sy->offset, sy->addr);
-        printf("    eaddr:%d, addr_type:%c, type:%x etype:%x\n",
+        printf("    eaddr:%d, addr_type:%c, type:%p etype:%p\n",
           sy->eaddr, sy->addr_type, sy->type, sy->etype);
         printf("    scopetype:%c, sname:%s, rname:%s addrspace:%c\n",
           sy->scopetype, sy->sname, sy->rname, sy->addrspace);
-        printf("    next:%x\n", sy->next);
+        printf("    next:%p\n", sy->next);
       }
       ++i;
       sy = setNextItem(symbols);
@@ -1699,19 +2283,17 @@ int cmdListFunctions (char *s, context *cctxt)
     printf("[functions]\n");
     f = setFirstItem(functions);
     i = 0;
-    for (;;) {
-      if (f == NULL)
-        break;
+    while (f != NULL) {
       if (our_verbose) {
-        printf("  %d) sym:%x, fname:%s, modName:%s, mod:%x\n", i,
+        printf("  %d) sym:%p, fname:%s, modName:%s, mod:%p\n", i,
           f->sym, f->sym->name, f->modName, f->mod);
         printf("    entryline:%d, aentryline:%d, exitline:%d, aexitline:%d\n",
                 f->entryline, f->aentryline, f->exitline, f->aexitline);
-        printf("    cfpoints:%x, afpoints:%x, laddr:%x, lline:%d\n",
+        printf("    cfpoints:%p, afpoints:%p, laddr:%x, lline:%d\n",
                 f->cfpoints, f->afpoints, f->laddr, f->lline);
       }
       else {
-        printf("<%s>", f->modName);
+        printf("<%s>", f->sym->name);
       }
       ++i;
       f = setNextItem(functions);
@@ -1721,7 +2303,7 @@ int cmdListFunctions (char *s, context *cctxt)
 }
 
 /*-----------------------------------------------------------------
- cmdListModules - list functions.
+ cmdListModules - list modules.
 |-----------------------------------------------------------------*/
 int cmdListModules (char *s, context *cctxt)
 {
@@ -1748,7 +2330,7 @@ int cmdListModules (char *s, context *cctxt)
         m->cfullname, m->afullname, m->name);
       printf("    c_name:%s, asm_name:%s, ncLines:%d, nasmLines:%d\n",
               m->c_name, m->asm_name, m->ncLines, m->nasmLines);
-      printf("    cLines:%x, asmLines:%x\n",
+      printf("    cLines:%p, asmLines:%p\n",
               m->cLines, m->asmLines);
       }
       if (our_verbose >= 2) {
@@ -1790,15 +2372,15 @@ static void infoSymbols(context *ctxt)
 {
   int our_verbose = 0;
 
-  printf("[context:%x] func:%x modName:%s addr:%x\n",
+  printf("[context:%p] func:%p modName:%s addr:%x\n",
     ctxt, ctxt->func, ctxt->modName, ctxt->addr);
 
   printf("  cline:%d asmline:%d block:%d level:%d\n",
-    ctxt->cline, ctxt->asmline, ctxt->level);
+    ctxt->cline, ctxt->asmline, ctxt->block, ctxt->level);
 
-  printf("[globals] currCtxt:%x, modules:%x, functions:%x symbols:%x\n",
+  printf("[globals] currCtxt:%p, modules:%p, functions:%p symbols:%p\n",
     currCtxt, modules, functions, symbols);
-  printf("  nStructs:%d, structs:%x, ssdirl:%s\n",
+  printf("  nStructs:%d, structs:%p, ssdirl:%s\n",
     nStructs, structs, ssdirl);
 
   /**************** modules *******************/
@@ -1816,7 +2398,7 @@ static void infoSymbols(context *ctxt)
         m->cfullname, m->afullname, m->name);
       printf("    c_name:%s, asm_name:%s, ncLines:%d, nasmLines:%d\n",
               m->c_name, m->asm_name, m->ncLines, m->nasmLines);
-      printf("    cLines:%x, asmLines:%x\n",
+      printf("    cLines:%p, asmLines:%p\n",
               m->cLines, m->asmLines);
       i = 0;
       if (m->cLines) {
@@ -1861,11 +2443,11 @@ static void infoSymbols(context *ctxt)
       if (f == NULL)
         break;
       if (our_verbose) {
-        printf("  %d) sym:%x, modName:%s, mod:%x\n", i,
+        printf("  %d) sym:%p, modName:%s, mod:%p\n", i,
           f->sym, f->modName, f->mod);
         printf("    entryline:%d, aentryline:%d, exitline:%d, aexitline:%d\n",
                 f->entryline, f->aentryline, f->exitline, f->aexitline);
-        printf("    cfpoints:%x, afpoints:%x, laddr:%x, lline:%d\n",
+        printf("    cfpoints:%p, afpoints:%p, laddr:%x, lline:%d\n",
                 f->cfpoints, f->afpoints, f->laddr, f->lline);
       }
       ++i;
@@ -1890,11 +2472,11 @@ static void infoSymbols(context *ctxt)
           s->name, s->size, s->level, s->block);
         printf("    isonstack:%d, isfunc:%d, offset:%d addr:%d\n",
           s->isonstack, s->isfunc, s->offset, s->addr);
-        printf("    eaddr:%d, addr_type:%c, type:%x etype:%x\n",
+        printf("    eaddr:%d, addr_type:%c, type:%p etype:%p\n",
           s->eaddr, s->addr_type, s->type, s->etype);
         printf("    scopetype:%c, sname:%s, rname:%s addrspace:%c\n",
           s->scopetype, s->sname, s->rname, s->addrspace);
-        printf("    next:%x\n", s->next);
+        printf("    next:%p\n", s->next);
       }
       ++i;
       s = setNextItem(symbols);
@@ -1910,26 +2492,26 @@ static void infoSymbols(context *ctxt)
 /*-----------------------------------------------------------------*/
 static void infoRegisters( int all, context *ctxt)
 {
-    static unsigned int regaddrs[] = {0x81,0x82,0x83,0xb8,0xd0,0xe0,0xf0,0};
+    static int regaddrs[] = {0x81,0x82,0x83,0xb8,0xd0,0xe0,0xf0,0};
     unsigned long val;
     int i,j,*r;
 
-    i   = simGetValue (0xd0,'I',1);
+    i = simGetValue (0xd0,'I',1);
     fprintf(stdout,"IP  : 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);
+        val = simGetValue (j,'R',1);
+        fprintf(stdout," 0x%02lX",val);
     }
     fprintf(stdout,"\n");
     val = simGetValue (0xe0,'I',1);
-    fprintf(stdout,"ACC : 0x%02X %d %c\n",val,val,(isprint(val) ? val : '.'));
+    fprintf(stdout,"ACC : 0x%02lX %lu %c\n",val,val,(isprint(val) ? (char)val : '.'));
     val = simGetValue (0xf0,'I',1);
-    fprintf(stdout,"B   : 0x%02X %d %c\n",val,val,(isprint(val) ? val : '.'));
+    fprintf(stdout,"B   : 0x%02lX %lu %c\n",val,val,(isprint(val) ? (char)val : '.'));
     val = simGetValue (0x82,'I',2);
-    fprintf(stdout,"DPTR: 0x%04X %d\n",val,val);
+    fprintf(stdout,"DPTR: 0x%04lX %lu\n",val,val);
     val = simGetValue (0x81,'I',1);
-    fprintf(stdout,"SP  : 0x%02X\n",val);
+    fprintf(stdout,"SP  : 0x%02lX (0x%04lX)\n",val,simGetValue (val-1,'B',2));
     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 )
@@ -1948,7 +2530,7 @@ static void infoRegisters( int all, context *ctxt)
             if (applyToSetFTrue(sfrsymbols,symWithAddr,i,'I',&sym))
             {
                 val = simGetValue (sym->addr,sym->addrspace,sym->size);
-                fprintf(stdout,"%s : 0x%02x",sym->name,val);
+                fprintf(stdout,"%s : 0x%02lx",sym->name,val);
                 if ( !(i & 0x07 ))
                 {
                     for ( j = 0 ; j < 8 ; j++ )
@@ -1975,14 +2557,22 @@ static void infoStack(context *ctxt)
 {
     function *func ;
     int i = 0 ;
-
-    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%08x in %s () at %s:%d\n",i++,
-               func->laddr,func->sym->name,
-               func->mod->c_name,func->lline+1);
+    context *ctx, my_context;
+    unsigned int bp, pc, addr = ctxt->addr;
+    int status;
+
+    for (status = frameStart(&bp,&pc); status; status = frameNext(&bp, &pc)) {
+       ctx = discoverContext(pc, NULL, &my_context);
+       if (ctx) {
+           func = ctx->func;
+       Dprintf(D_break, ("break: infoStack: %s 0x%02x\n",func->sym->name, bp));
+    
+           fprintf(stdout,"#%d  0x%08x in %s () at %s:%d\n",i++,
+                   pc,func->sym->name,
+                   func->mod->c_name,func->lline+1);
+       } else {
+           fprintf(stdout,"#%d  0x%08x\n", i++, pc);
+       }
     }
     if ( !i )
         fprintf(stdout,"no stack.\n");
@@ -1993,8 +2583,8 @@ static void infoStack(context *ctxt)
 /*-----------------------------------------------------------------*/
 int cmdWhere(char *s, context *cctxt)
 {
-       infoStack(cctxt);
-       return 0;
+        infoStack(cctxt);
+        return 0;
 }
 
 
@@ -2004,26 +2594,27 @@ static int infomode = 0;
 /*-----------------------------------------------------------------*/
 int cmdInfo (char *s, context *cctxt)
 {
-    while (isspace(*s)) s++;
+    /* trim left and_right*/
+    s = trim(s);
 
     /* list all break points */
     if (strncmp(s,"break",5) == 0) {
-       listUSERbp();
-       return 0;
+        listUSERbp();
+        return 0;
     }
 
     /* info frame same as frame */
-    if (strcmp(s,"frame") == 0) {
-       cmdFrame (s,cctxt);
-       return 0;
+    if (strncmp(s,"frame",5) == 0) {
+        cmdFrame (s+5,cctxt);
+        return 0;
     }
 
     if (strncmp(s,"line",4) == 0) {
-    infomode=1;
-       cmdListSrc (s+4,cctxt);
-       return 0;
+        infomode=1;
+        cmdListSrc (s+4,cctxt);
+        return 0;
     }
-    if (strncmp(s,"source",6) == 0) 
+    if (strncmp(s,"source",6) == 0)
     {
         module *m;
         if ( s[6] == 's' )
@@ -2032,14 +2623,14 @@ int cmdInfo (char *s, context *cctxt)
             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); 
+                fprintf(stdout,"%s%s, %s",k ? ", ":"",m->cfullname, m->afullname);
                 k = 1;
             }
-            fprintf(stdout,"\n"); 
+            fprintf(stdout,"\n");
         }
         else
         {
-            if (!cctxt || !cctxt->func || !cctxt->func->mod) 
+            if (!cctxt || !cctxt->func || !cctxt->func->mod)
             {
                 fprintf(stdout,"No source file loaded\n");
                 return 0;
@@ -2052,7 +2643,7 @@ int cmdInfo (char *s, context *cctxt)
         }
         return 0;
     }
-    if (strncmp(s,"functions",7) == 0) 
+    if (strcmp(s,"functions") == 0)
     {
         function *f;
         module *m = NULL;
@@ -2070,19 +2661,19 @@ int cmdInfo (char *s, context *cctxt)
     }
     /* info stack display call stack */
     if (strcmp(s,"stack") == 0) {
-       infoStack(cctxt);
-    showfull = 1;
-       return 0;
+        infoStack(cctxt);
+        showfull = 1;
+        return 0;
     }
 
     /* info stack display call stack */
     if (strcmp(s,"registers") == 0) {
         infoRegisters(0,cctxt);
-           return 0;
+            return 0;
     }
 
     /* info stack display call stack */
-    if (strcmp(s,"all-registers") == 0) 
+    if (strcmp(s,"all-registers") == 0)
     {
         infoRegisters(1,cctxt);
         return 0;
@@ -2112,9 +2703,9 @@ int cmdInfo (char *s, context *cctxt)
 /* cmdQuit  - quit debugging                                       */
 /*-----------------------------------------------------------------*/
 int cmdQuit (char *s, context *cctxt)
-{   
+{
     if (simactive)
-       closeSimulator();
+        closeSimulator();
     return 1;
 }
 
@@ -2122,7 +2713,7 @@ int cmdQuit (char *s, context *cctxt)
 /* cmdListSrc  - list src                                          */
 /*-----------------------------------------------------------------*/
 int cmdListSrc (char *s, context *cctxt)
-{   
+{
     static int currline = 0;
     int i =0 ;
     int pline = 0;
@@ -2130,8 +2721,8 @@ int cmdListSrc (char *s, context *cctxt)
     function *func = NULL;
 
 
-    while (*s && isspace(*s)) s++;
-    
+    s = trim_left(s);
+
     /* if the user has spcified line numer then the line number
        can be of the following formats
        LINE          - just line number
@@ -2141,118 +2732,118 @@ int cmdListSrc (char *s, context *cctxt)
        FILE:FUNCTION - function in file */
 
     if (*s) {
-       /* case a) LINE */
-       if (isdigit(*s)) {
-           if (!cctxt || !cctxt->func || !cctxt->func->mod) {
-             if (!list_mod) {
-               fprintf(stdout,"Sdcdb fails to have a proper context at %d.\n", __LINE__);
-               return 0;
-             }
-           }
-           else
-             list_mod = cctxt->func->mod;
+        /* case a) LINE */
+        if (isdigit(*s)) {
+            if (!cctxt || !cctxt->func || !cctxt->func->mod) {
+              if (!list_mod) {
+                fprintf(stdout,"Sdcdb fails to have a proper context at %d.\n", __LINE__);
+                return 0;
+              }
+            }
+            else
+              list_mod = cctxt->func->mod;
         pline = strtol(s,&s,10) - 1;
-        if (s && (s = strchr(s,','))) 
+        if (s && (s = strchr(s,',')))
         {
             /* LINE,LASTLINE */
-            llines = strtol(s+1,0,10); 
+            llines = strtol(s+1,0,10);
             if ( llines > 0 )
                 llines -= pline+1;
             else
                 llines = listlines;
         }
-       }
-       else {
-           char *bp;
-           
-           /* if ':' present then FILE:LINE || FILE:FUNCTION */
-           if ((bp = strchr(s,':'))) {
-               *bp = '\0';
-               bp ++;
-               if (isdigit(*bp)) {
-                   /* FILE:LINE */
-                   list_mod=NULL;  /* bug fix 2-09-02, moduleWithCName expects mod to be null */
-                   if (srcMode == SRC_CMODE) {
-                       if (!applyToSet(modules,moduleWithCName,s,&list_mod)) {
-                           fprintf (stderr,"No c source file named %s.\n",s);
-                           return 0;
-                       }
-                   } else {
-                       if (!applyToSet(modules,moduleWithAsmName,s,&list_mod)) {
-                           fprintf (stderr,"No source file named %s.\n",s);
-                           return 0;
-                       }
-                   }
-                   pline = strtol(bp,&bp,10) - 1;
-            if (bp && (bp = strchr(bp,','))) 
+        }
+        else {
+            char *bp;
+
+            /* if ':' present then FILE:LINE || FILE:FUNCTION */
+            if ((bp = strchr(s,':'))) {
+                *bp = '\0';
+                bp ++;
+                if (isdigit(*bp)) {
+                    /* FILE:LINE */
+                    list_mod=NULL;  /* bug fix 2-09-02, moduleWithCName expects mod to be null */
+                    if (srcMode == SRC_CMODE) {
+                        if (!applyToSet(modules,moduleWithCName,s,&list_mod)) {
+                            fprintf (stderr,"No c source file named %s.\n",s);
+                            return 0;
+                        }
+                    } else {
+                        if (!applyToSet(modules,moduleWithAsmName,s,&list_mod)) {
+                            fprintf (stderr,"No source file named %s.\n",s);
+                            return 0;
+                        }
+                    }
+                    pline = strtol(bp,&bp,10) - 1;
+            if (bp && (bp = strchr(bp,',')))
             {
                 /* FILE:LINE,LASTLINE */
-                llines = strtol(bp+1,0,10); 
+                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)) {
-                       fprintf(stdout,"Function \"%s\" not defined.\n",bp);
-                       return 0;
-                   }
-                   list_mod = func->mod;
-                   if (srcMode == SRC_CMODE) {
-                       pline = func->entryline;
-                       llines = func->exitline - func->entryline + 1;
-                   } else {
-                       pline = func->aentryline;
-                       llines = func->aexitline - func->aentryline + 1;
-                   }
-               }
-           }
-           else {
-               /* FUNCTION */
-            if (*s == '\'') 
+                } else {
+                    /* FILE:FUCTION */
+                    if (!applyToSet(functions,funcWithNameModule,bp,s,&func)) {
+                        fprintf(stdout,"Function \"%s\" not defined.\n",bp);
+                        return 0;
+                    }
+                    list_mod = func->mod;
+                    if (srcMode == SRC_CMODE) {
+                        pline = func->entryline;
+                        llines = func->exitline - func->entryline + 1;
+                    } else {
+                        pline = func->aentryline;
+                        llines = func->aexitline - func->aentryline + 1;
+                    }
+                }
+            }
+            else {
+                /* FUNCTION */
+            if (*s == '\'')
             {
                 /* 'FUNCTION' */
                 s++ ;
-                if ((bp = strrchr(s,'\''))) 
+                if ((bp = strrchr(s,'\'')))
                 {
                     *bp = '\0';
                 }
-                
+
             }
-               if (!applyToSet(functions,funcWithName,s,&func)) {
-                   fprintf(stderr,"Function \"%s\" not defined.\n",s); 
-                   return 0;
-               }
-               else {
-                   list_mod = func->mod;
-                   if (srcMode == SRC_CMODE) {
-                       pline = func->entryline;
-                       llines = func->exitline - func->entryline + 1; 
-                   } else {
-                       pline = func->aentryline;
-                       llines = func->aexitline - func->aentryline + 1; 
-                   }
-               }
-           }
-       }
+                if (!applyToSet(functions,funcWithName,s,&func)) {
+                    fprintf(stderr,"Function \"%s\" not defined.\n",s);
+                    return 0;
+                }
+                else {
+                    list_mod = func->mod;
+                    if (srcMode == SRC_CMODE) {
+                        pline = func->entryline;
+                        llines = func->exitline - func->entryline + 1;
+                    } else {
+                        pline = func->aentryline;
+                        llines = func->aexitline - func->aentryline + 1;
+                    }
+                }
+            }
+        }
     } else {
-       /* if no line specified & we had listed
-          before then continue from that listing */
-       if (currline)
-           pline = currline ;
-       else {
-           if (!cctxt || !cctxt->func || !cctxt->func->mod) {
-             fprintf(stdout,"Missing context at %d. Try list filename:lineno\n", __LINE__);
-             return 0;
-           }
-           list_mod = cctxt->func->mod;
-           if (srcMode == SRC_CMODE)
-               pline = cctxt->cline;
-           else
-               pline = cctxt->asmline;
-       }
+        /* if no line specified & we had listed
+           before then continue from that listing */
+        if (currline)
+            pline = currline ;
+        else {
+            if (!cctxt || !cctxt->func || !cctxt->func->mod) {
+              fprintf(stdout,"Missing context at %d. Try list filename:lineno\n", __LINE__);
+              return 0;
+            }
+            list_mod = cctxt->func->mod;
+            if (srcMode == SRC_CMODE)
+                pline = cctxt->cline;
+            else
+                pline = cctxt->asmline;
+        }
     }
 
     if (!list_mod) {
@@ -2264,13 +2855,13 @@ int cmdListSrc (char *s, context *cctxt)
         return 0;
     if ( infomode )
     {
-        int firstaddr , lastaddr ;
-           if ( pline  >= list_mod->ncLines )
+        unsigned 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>", 
+            fprintf(stdout,"Line %d of \"%s\" starts at address 0x%08x <%s+%d>",
                 pline+1,
                 list_mod->c_name, lastaddr,
                 func ? func->sym->name : "?",
@@ -2284,31 +2875,31 @@ int cmdListSrc (char *s, context *cctxt)
                 break;
             }
         }
-        fprintf(stdout," and ends at 0x%08x <%s+%d>.\n", 
+        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,
+                    canonname(func->mod->cfullname),
                     llines,firstaddr);
         else
             showfull=1;
         return 0;
     }
     for ( i = 0 ; i < llines ; i++ ) {
-       if (srcMode == SRC_CMODE) {
-           if ( (pline + i) >= list_mod->ncLines )
-               break;
-           fprintf(stdout,"%d\t%s",pline + i,
-                   list_mod->cLines[pline +i]->src);
-       } else {
-           if ( (pline + i) >= list_mod->nasmLines )
-               break;
-           fprintf(stdout,"%d\t%s",pline + i,
-                   list_mod->asmLines[pline +i]->src);
-       }
+        if (srcMode == SRC_CMODE) {
+            if ( (pline + i) >= list_mod->ncLines )
+                break;
+            fprintf(stdout,"%d\t%s",pline + i,
+                    list_mod->cLines[pline +i]->src);
+        } else {
+            if ( (pline + i) >= list_mod->nasmLines )
+                break;
+            fprintf(stdout,"%d\t%s",pline + i,
+                    list_mod->asmLines[pline +i]->src);
+        }
     }
     currline = pline + i ;
     return 0;
@@ -2317,9 +2908,9 @@ int cmdListSrc (char *s, context *cctxt)
 static unsigned long getValBasic(symbol *sym, link *type, char *val)
 {
     char *s;
-    union 
-    {          
-        float f;     
+    union
+    {
+        float f;
         unsigned long val;
         long         sval;
         struct {
@@ -2329,14 +2920,14 @@ static unsigned long getValBasic(symbol *sym, link *type, char *val)
         unsigned char b[4];
     }v;
 
-    if (IS_FLOAT(type))        
-        v.f = strtod(val,NULL);    
+    if (IS_FLOAT(type))
+        v.f = strtod(val,NULL);
     else
-       if (IS_PTR(type))
-           v.val = strtol(val,NULL,0);
-       else
+        if (IS_PTR(type))
+            v.val = strtol(val,NULL,0);
+        else
     {
-           if (IS_INTEGRAL(type)) 
+            if (IS_INTEGRAL(type))
         {
             link *etype;
             if ( type->next )
@@ -2349,7 +2940,7 @@ static unsigned long getValBasic(symbol *sym, link *type, char *val)
                 {
                     if ( s[1] == '\\' )
                         v.b[0] = strtol(s+2,NULL,8);
-                    else 
+                    else
                         v.b[0] = s[1];
                 }
                 else
@@ -2358,14 +2949,14 @@ static unsigned long getValBasic(symbol *sym, link *type, char *val)
                 }
             }
             else
-                if (IS_INT(etype)) 
+                if (IS_INT(etype))
                     if (IS_LONG(etype))
                         v.val = strtol(val,NULL,0);
                     else
                         v.i.lo = strtol(val,NULL,0);
                 else
                     v.val = strtol(val,NULL,0);
-           } 
+            }
         else
             v.val = strtol(val,NULL,0);
     }
@@ -2375,20 +2966,20 @@ static unsigned long getValBasic(symbol *sym, link *type, char *val)
 /*-----------------------------------------------------------------*/
 /* printFmtInteger - print value in bin,oct,dez or hex             */
 /*-----------------------------------------------------------------*/
-static void printFmtInteger(char *deffmt,int fmt, long val, 
+static void printFmtInteger(char *deffmt,int fmt, long val,
                             int sign, int size)
 {
-    static char digits[] = 
+    static char digits[] =
     {
         '0' , '1' , '2' , '3' , '4' , '5' ,
         '6' , '7' , '8' , '9' , 'a' , 'b' ,
-        'c' , 'd' , 'e' , 'f' , 'g' , 'h' 
+        '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;
+        char buf[40];
+        char negative = 0;
+        int charPos = 38;
     int radix;
 
     if ( fmt == FMT_NON || fmt == FMT_DEZ )
@@ -2403,16 +2994,16 @@ static void printFmtInteger(char *deffmt,int fmt, long val,
         negative = 1;
     */
 
-       if (!negative)
-           val = -val;
+        if (!negative)
+            val = -val;
 
-       buf[39] = '\0';
-    while (val <= -radix) 
+        buf[39] = '\0';
+    while (val <= -radix)
     {
-           buf[charPos--] = digits[-(val % radix)];
-           val = val / radix;
-       }
-       buf[charPos] = digits[-val];
+            buf[charPos--] = digits[-(val % radix)];
+            val = val / radix;
+        }
+        buf[charPos] = digits[-val];
 
     switch ( fmt )
     {
@@ -2430,7 +3021,7 @@ static void printFmtInteger(char *deffmt,int fmt, long val,
     while (charPos > 39 - radix )
     {
         buf[--charPos] = '0';
-    } 
+    }
     switch ( fmt )
     {
         case FMT_OCT:
@@ -2442,9 +3033,9 @@ static void printFmtInteger(char *deffmt,int fmt, long val,
             buf[--charPos] = '0';
             break;
     }
-       if (negative) {
-           buf[--charPos] = '-';
-       }
+        if (negative) {
+            buf[--charPos] = '-';
+        }
     fputs(&buf[charPos],stdout);
 }
 
@@ -2454,29 +3045,26 @@ static void printFmtInteger(char *deffmt,int fmt, long val,
 static void printValBasic(symbol *sym, link *type,
                           char mem, unsigned addr,int size, int fmt)
 {
-    union {    
-       float f;     
-       unsigned long val;
-       long         sval;
-       struct {
-           unsigned short    lo;
-           unsigned short    hi;
-       } i;
-       unsigned char b[4];
-    }v;
     union {
-       unsigned char b[4];
-    }v1;
-    
+        float f;
+        unsigned long val;
+        long         sval;
+        struct {
+            unsigned short    lo;
+            unsigned short    hi;
+        } i;
+        unsigned char b[4];
+    }v;
+
     v.val = simGetValue(addr,mem,size);
     /* if this a floating point number then */
-    if (IS_FLOAT(type))        
-       fprintf(stdout,"%f",v.f);    
+    if (IS_FLOAT(type))
+        fprintf(stdout,"%f",v.f);
     else
-       if (IS_PTR(type))
-           fprintf(stdout,"0x%*x",size<<1,v.val);
-       else
-        if (IS_INTEGRAL(type)) 
+        if (IS_PTR(type))
+            fprintf(stdout,"0x%0*lx",size<<1,v.val);
+        else
+        if (IS_INTEGRAL(type))
         {
             link *etype;
             if ( type->next )
@@ -2484,7 +3072,7 @@ static void printValBasic(symbol *sym, link *type,
             else
                 etype = type;
             if (IS_CHAR(etype))
-            { 
+            {
                 if ( isprint(v.val))
                     printFmtInteger((SPEC_USIGN(etype)?"0x%02x":"'%c'"),
                                     fmt,(long)v.val,0,size);
@@ -2494,7 +3082,7 @@ static void printValBasic(symbol *sym, link *type,
             }
             else
             {
-                if (IS_INT(etype)) 
+                if (IS_INT(etype))
                     if (IS_LONG(etype))
                         if (SPEC_USIGN(etype))
                             printFmtInteger("%u",fmt,(long)v.val,0,size);
@@ -2510,11 +3098,11 @@ static void printValBasic(symbol *sym, link *type,
                     if (IS_BITVAR(etype))
                         fprintf(stdout,"%c",(v.val?'1':'0'));
                     else
-                        fprintf(stdout,"0x%0*x",size<<1,v.val);
+                        fprintf(stdout,"0x%0*lx",size<<1,v.val);
                 }
             }
-           } else
-            fprintf(stdout,"0x%0*x",size<<1,v.val);  
+            } else
+            fprintf(stdout,"0x%0*lx",size<<1,v.val);
 }
 
 /*-----------------------------------------------------------------*/
@@ -2525,112 +3113,136 @@ static void printValFunc (symbol *sym, int fmt)
     fprintf(stdout,"print function not yet implemented");
 }
 
+static void
+do_indent(int indent) {
+    while (indent--)
+       fprintf(stdout, "  ");
+
+}
+
 /*-----------------------------------------------------------------*/
 /* printArrayValue - will print the values of array elements       */
 /*-----------------------------------------------------------------*/
 static void printArrayValue (symbol *sym,  link *type,
-                             char space, unsigned int addr, int fmt)
+                             char space, unsigned int addr, int fmt,
+                            int indent)
 {
-       link *elem_type = type->next;
-       int i;
-       
-       fprintf(stdout,"{");
-       for (i = 0 ; i < DCL_ELEM(type) ; i++) {                
-               if (IS_AGGREGATE(elem_type)) {
-                       printValAggregates(sym,elem_type,space,addr,fmt);                      
-               } else {
-                       printValBasic(sym,elem_type,space,addr,getSize(elem_type),fmt);
-               }
-               addr += getSize(elem_type);
-               if (i != DCL_ELEM(type) -1)
-                       fprintf(stdout,",");
+    link *elem_type = type->next;
+    int i;
+    int col;
+
+    fprintf(stdout,"{");
+    for (i = 0 ; i < DCL_ELEM(type) ; i++) {
+       if (IS_AGGREGATE(elem_type)) {
+           printValAggregates(sym,elem_type,space,addr,fmt,indent);
+           col = 0;
+       } else {
+           printValBasic(sym,elem_type,space,addr,getSize(elem_type),fmt);
+           col++;
+       }
+       addr += getSize(elem_type);
+       if (i != DCL_ELEM(type) -1) {
+           fprintf(stdout,",");
+           if (col == 16) {
+               fprintf(stdout,"\n");
+               do_indent(indent);
+               col = 0;
+           }
        }
+    }
 
-       fprintf(stdout,"}");            
+    fprintf(stdout,"}");
 }
 
 /*-----------------------------------------------------------------*/
 /* printStructValue - prints structures elements                   */
 /*-----------------------------------------------------------------*/
-static void printStructValue (symbol *sym, link *type, 
-                              char space, unsigned int addr, int fmt) 
+static void printStructValue (symbol *sym, link *type,
+                              char space, unsigned int addr, int fmt,
+                             int indent)
 {
-       symbol *fields = SPEC_STRUCT(type)->fields;
+    symbol *fields = SPEC_STRUCT(type)->fields;
     int first = 1;
-       fprintf(stdout," { ");
-       while (fields) {
-               fprintf(stdout,"%s%s = ",(first ? "": ", "),fields->name);
-               first = 0;
-        if (IS_AGGREGATE(fields->type)) {
-                       printValAggregates(fields,fields->type,space, addr, fmt);
-               } else {
-                       printValBasic(fields,fields->type,space,addr,getSize(fields->type), fmt);
-               }
-               addr += getSize(fields->type);
-               fields = fields->next;
+    do_indent (indent);
+    fprintf(stdout,"{\n");
+    while (fields) {
+       do_indent(indent + 1);
+       fprintf(stdout,"%s = ", fields->name);
+       first = 0;
+       if (IS_AGGREGATE(fields->type)) {
+           printValAggregates(fields,fields->type,space, addr, fmt, indent + 1);
+       } else {
+           printValBasic(fields,fields->type,space,addr,getSize(fields->type), fmt);
        }
-       fprintf(stdout,"}");
+        fprintf(stdout,",\n");
+       addr += getSize(fields->type);
+       fields = fields->next;
+    }
+    do_indent(indent);
+    fprintf(stdout,"}");
 }
 
 /*-----------------------------------------------------------------*/
 /* printValAggregates - print value of aggregates                  */
 /*-----------------------------------------------------------------*/
 static void printValAggregates (symbol *sym, link *type,
-                                char space,unsigned int addr, int fmt)
+                                char space,unsigned int addr, int fmt,
+                               int indent)
 {
 
-       if (IS_ARRAY(type)) {
-               printArrayValue(sym, type, space, addr, fmt);
-               return ;
-       }
+        if (IS_ARRAY(type)) {
+                printArrayValue(sym, type, space, addr, fmt, indent);
+                return ;
+        }
 
-       if (IS_STRUCT(type)) { 
-               printStructValue(sym, type, space, addr, fmt); 
-               return; 
-       } 
+        if (IS_STRUCT(type)) {
+                printStructValue(sym, type, space, addr, fmt, indent);
+                return;
+        }
 }
 
 /*-----------------------------------------------------------------*/
 /* printOrSetSymValue - print or set value of a symbol             */
 /*-----------------------------------------------------------------*/
-static int printOrSetSymValue (symbol *sym, context *cctxt, 
-                                int flg, int dnum, int fmt, char *rs, 
+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;
+        symbol *fields;
     link *type;
-    unsigned int  addr; 
+    unsigned int  addr;
     int size, n;
     char *s, *s2;
     char save_ch, save_ch2;
+    int get_member = 0;
 
     /* if it is on stack then compute address & fall thru */
-    if (sym->isonstack) 
+    if (sym->isonstack)
     {
         symbol *bp = symLookup("bp",cctxt);
-        if (!bp) 
+        if (!bp)
         {
             fprintf(stdout,"cannot determine stack frame\n");
             return 1;
         }
 
         sym->addr = simGetValue(bp->addr,bp->addrspace,bp->size)
-            + sym->offset ;      
+            + sym->offset ;
     }
-    
+
     /* get the value from the simulator and
        print it */
     switch (flg)
     {
-        case 0: 
+        case 0:
         default:
             break;
-        case 1: 
+        case 1:
             fprintf(stdout,"$%d = ",stack++);
             break;
-        case 2: 
+        case 2:
             fprintf(stdout,"%d: ", dnum);
             if ( fmt != FMT_NON )
                 fprintf(stdout,"/%c ",fmtChar[fmt]);
@@ -2644,7 +3256,7 @@ static int printOrSetSymValue (symbol *sym, context *cctxt,
 
     while ( *rs )
     {
-        if ( *rs == '[' && IS_ARRAY(type))
+        if ( *rs == '[' && (IS_ARRAY(type) || IS_PTR(type)))
         {
             s = rs+1;
             while ( *rs && *rs != ']' ) rs++ ;
@@ -2662,13 +3274,13 @@ static int printOrSetSymValue (symbol *sym, context *cctxt,
                 if ( ! fields )
                 {
                     fprintf(stdout,"Unknown variable \"%s\" for index.\n", s);
-                    return 1;                    
+                    return 1;
                 }
                 /* arrays & structures first */
                 if (! IS_INTEGRAL(fields->type))
                 {
                     fprintf(stdout,"Wrong type of variable \"%s\" for index \n", s);
-                    return 1;                    
+                    return 1;
                 }
                 n = simGetValue(fields->addr,fields->addrspace,getSize(fields->type));
             }
@@ -2676,17 +3288,19 @@ static int printOrSetSymValue (symbol *sym, context *cctxt,
             {
                 n = strtol(s,0,0);
             }
-            if ( n < 0 || n >= DCL_ELEM(type))
+            if ( IS_ARRAY(type) && (n < 0 || n >= DCL_ELEM(type)))
             {
                 fprintf(stdout,"Wrong index %d.\n", n);
-                return 1;                    
+                return 1;
             }
+           if (IS_PTR(type))
+               addr = simGetValue(addr, sym->addrspace, size);
             type = type->next;
             size = getSize(type);
-            addr += size * n;
+           addr += size * n;
             *rs++ = save_ch;
         }
-        else if ( *rs == '.' && IS_STRUCT(type))
+        else if ( (*rs == '.' || get_member) && IS_STRUCT(type))
         {
             s = rs+1;
             /* search structure element */
@@ -2694,7 +3308,7 @@ static int printOrSetSymValue (symbol *sym, context *cctxt,
             save_ch = *rs;
             if ( *rs )
                 *rs = '\0';
-            for (fields = SPEC_STRUCT(type)->fields; fields; fields = fields->next) 
+            for (fields = SPEC_STRUCT(type)->fields; fields; fields = fields->next)
             {
                 if (!(strcmp(s,fields->name)))
                     break;
@@ -2703,39 +3317,57 @@ static int printOrSetSymValue (symbol *sym, context *cctxt,
             if ( ! fields )
             {
                 fprintf(stdout,"Unknown field \"%s\" of structure\n", s);
-                return 1;                    
+                return 1;
             }
             type = fields->type;
             size = getSize(type);
             addr += fields->offset;
         }
+       else if ( *rs == '*' && IS_PTR(type))
+       {
+           addr = simGetValue(addr, sym->addrspace, size);
+           type = type->next;
+           size = getSize(type);
+           rs++;
+       }
+       else if ( rs[0] == '-' && rs[1] == '>' &&
+                IS_PTR(type) && IS_STRUCT(type->next))
+       {
+           addr = simGetValue(addr, sym->addrspace, size);
+           type = type->next;
+           size = getSize(type);
+           rs++;
+           get_member = 1;
+           continue;
+       }
         else
             break;
+       get_member = 0;
     }
 
     /* arrays & structures first */
     if (IS_AGGREGATE(type))
     {
-           if ( val )
+            if ( val )
         {
             fprintf(stdout,"Cannot set/compare aggregate variable\n");
             return 1;
         }
         else
-            printValAggregates(sym,type,sym->addrspace,addr,fmt);
+            printValAggregates(sym,type,sym->addrspace,addr,fmt,0);
     }
     else
-       /* functions */
-       if (IS_FUNC(type))
+        /* functions */
+        if (IS_FUNC(type))
     {
-           if ( !val )
+            if ( !val )
             printValFunc(sym,fmt);
         else
             return 1;
     }
-       else
-    { 
-           if ( val )
+        else
+    {
+            if ( val )
         {
             unsigned long newval;
             newval = getValBasic(sym,type,val);
@@ -2760,10 +3392,10 @@ static int printOrSetSymValue (symbol *sym, context *cctxt,
                 {
                     /* Symbol with address of IP */
                     if ( cctxt ) cctxt->addr = newval;
-                    simSetPC(cctxt->addr); 
+                    simSetPC(cctxt->addr);
                 }
                 else
-                    simSetValue(addr,sym->addrspace,size,newval);      
+                    simSetValue(addr,sym->addrspace,size,newval);
                 return 1;
             }
         }
@@ -2771,7 +3403,7 @@ static int printOrSetSymValue (symbol *sym, context *cctxt,
             printValBasic(sym,type,sym->addrspace,addr,size,fmt);
     }
     if ( flg > 0 ) fprintf(stdout,"\n");
-       return 0;
+        return 0;
 }
 
 /*-----------------------------------------------------------------*/
@@ -2781,18 +3413,18 @@ static void printStructInfo (structdef *sdef)
 {
     symbol *field = sdef->fields ;
     int i = 0 ;
-    
+
     while (field) {
-       i += field->offset;
-       field = field->next;
+        i += field->offset;
+        field = field->next;
     }
 
     fprintf(stdout,"%s %s {\n",(i ? "struct" : "union" ), sdef->tag);
     field = sdef->fields;
     while (field) {
-       printTypeInfo (field->type);
-       fprintf(stdout," %s ;\n",field->name);
-       field = field->next ;
+        printTypeInfo (field->type);
+        fprintf(stdout," %s ;\n",field->name);
+        field = field->next ;
     }
 
     fprintf(stdout,"}\n");
@@ -2805,72 +3437,72 @@ static void printStructInfo (structdef *sdef)
 static void printTypeInfo(link *p)
 {
     if (!p)
-       return ;
+        return ;
 
     if (IS_DECL(p)) {
-       switch (DCL_TYPE(p))  {
-       case FUNCTION:
-           printTypeInfo (p->next);
-           fprintf(stdout,"()");
-           break;
-       case ARRAY:
-           printTypeInfo (p->next);
-           fprintf(stdout,"[%d]",DCL_ELEM(p));
-           break;
-       
-       case IPOINTER:
-       case PPOINTER:
-       case POINTER:
-           printTypeInfo (p->next);
-           fprintf(stdout,"(_near *)");
-           break;
+        switch (DCL_TYPE(p))  {
+        case FUNCTION:
+            printTypeInfo (p->next);
+            fprintf(stdout,"()");
+            break;
+        case ARRAY:
+            printTypeInfo (p->next);
+            fprintf(stdout,"[%d]",DCL_ELEM(p));
+            break;
 
-       case FPOINTER:
-           printTypeInfo (p->next);
-           fprintf(stdout,"(_xdata *)");
-           break;
+        case IPOINTER:
+        case PPOINTER:
+        case POINTER:
+            printTypeInfo (p->next);
+            fprintf(stdout,"(_near *)");
+            break;
 
-       case CPOINTER:
-           printTypeInfo( p->next);
-           fprintf(stdout,"(_code *)");
-           break;
-           
-       case GPOINTER:
-           printTypeInfo( p->next);
-           fprintf(stdout,"(_generic *)");
-           break;                   
-       }
+        case FPOINTER:
+            printTypeInfo (p->next);
+            fprintf(stdout,"(_xdata *)");
+            break;
+
+        case CPOINTER:
+            printTypeInfo( p->next);
+            fprintf(stdout,"(_code *)");
+            break;
+
+        case GPOINTER:
+            printTypeInfo( p->next);
+            fprintf(stdout,"(_generic *)");
+            break;
+        }
     } else {
-       switch (SPEC_NOUN(p)) { /* depending on the specifier type */
-       case V_INT:
-           (IS_LONG(p) ? fputs("long ",stdout) : 
-            ( IS_SHORT(p) ? fputs("short ",stdout) : 
-              fputs("int ",stdout))) ;
-           break;
-       case V_FLOAT:
-            fputs("float ",stdout);
-            break;
+        switch (SPEC_NOUN(p)) { /* depending on the specifier type */
+        case V_INT:
+            (IS_LONG(p) ? fputs("long ",stdout) :
+             ( IS_SHORT(p) ? fputs("short ",stdout) :
+               fputs("int ",stdout))) ;
+            break;
+        case V_FLOAT:
+             fputs("float ",stdout);
+             break;
 
-       case V_CHAR:
-           fputs ("char ",stdout);
-           break;
+        case V_CHAR:
+            fputs ("char ",stdout);
+            break;
 
-       case V_VOID:
-           fputs("void ",stdout);
-           break;
+        case V_VOID:
+            fputs("void ",stdout);
+            break;
 
-       case V_STRUCT:
-           printStructInfo (SPEC_STRUCT(p));
-           break;
+        case V_STRUCT:
+            printStructInfo (SPEC_STRUCT(p));
+            break;
 
-       case V_SBIT:
-           fputs("sbit ",stdout);
-           break;
+        case V_SBIT:
+            fputs("sbit ",stdout);
+            break;
 
-       case V_BIT:
-           fprintf(stdout,": %d" ,SPEC_BLEN(p));       
-           break;
-       }
+        case V_BIT:
+            fprintf(stdout,": %d" ,SPEC_BLEN(p));
+            break;
+        }
     }
 }
 
@@ -2878,7 +3510,7 @@ 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;
@@ -2889,12 +3521,12 @@ int conditionIsTrue( char *s, context *cctxt)
         fmt = 1;
     else
     {
-        cmp_char = *s;    
+        cmp_char = *s;
         *s++ = '\0';
         if ( *s == '=' )
         {
-            /* if <= or >= an other char is used 
-             * == or !=  not checked in switch 
+            /* if <= or >= an other char is used
+             * == or !=  not checked in switch
              */
             switch( cmp_char )
             {
@@ -2903,7 +3535,7 @@ int conditionIsTrue( char *s, context *cctxt)
             }
             s++ ;
         }
-        while (isspace(*s)) *s++ = '\0';
+        s = trim_left(s);
         fmt = printOrSetSymValue(sym,cctxt,0,0,0,rs,s,cmp_char);
     }
     Safe_free(dup);
@@ -2914,17 +3546,17 @@ int conditionIsTrue( char *s, context *cctxt)
 /* cmdPrint - print value of variable                              */
 /*-----------------------------------------------------------------*/
 int cmdPrint (char *s, context *cctxt)
-{   
+{
     symbol *sym ;
     int fmt;
     char *rs;
     if ( !( rs = preparePrint(s, cctxt, &fmt, &sym )))
         return 0;
 
-    if ( sym ) 
+    if ( sym )
     {
         printOrSetSymValue(sym,cctxt,1,0,fmt,rs,NULL,'\0');
-    } 
+    }
     return 0;
 }
 
@@ -2932,17 +3564,17 @@ int cmdPrint (char *s, context *cctxt)
 /* cmdOutput - print value of variable without number and newline  */
 /*-----------------------------------------------------------------*/
 int cmdOutput (char *s, context *cctxt)
-{   
+{
     symbol *sym ;
     int fmt;
     char *rs;
     if ( !( rs = preparePrint(s, cctxt, &fmt, &sym )))
         return 0;
 
-    if ( sym ) 
+    if ( sym )
     {
         printOrSetSymValue(sym,cctxt,0,0,fmt,rs,NULL,'\0');
-    } 
+    }
     return 0;
 }
 
@@ -2973,7 +3605,7 @@ void displayAll(context *cctxt)
         return;
     for (dsym = setFirstItem(dispsymbols);
          dsym ;
-         dsym = setNextItem(dispsymbols)) 
+         dsym = setNextItem(dispsymbols))
     {
         if ( (sym = symLookup(dsym->name,cctxt)))
             printOrSetSymValue(sym,cctxt,2,dsym->dnum,dsym->fmt,
@@ -2985,7 +3617,7 @@ void displayAll(context *cctxt)
 /* cmdDisplay  - display value of variable                         */
 /*-----------------------------------------------------------------*/
 int cmdDisplay (char *s, context *cctxt)
-{   
+{
     static int dnum = 1;
     symbol *sym ;
     int fmt;
@@ -2996,7 +3628,7 @@ int cmdDisplay (char *s, context *cctxt)
         return 0;
     }
 
-    if ( sym ) 
+    if ( sym )
     {
         dsymbol *dsym = (dsymbol *)Safe_calloc(1,sizeof(dsymbol));
         dsym->dnum = dnum++ ;
@@ -3012,11 +3644,11 @@ int cmdDisplay (char *s, context *cctxt)
 /* cmdUnDisplay  - undisplay value of variable                              */
 /*-----------------------------------------------------------------*/
 int cmdUnDisplay (char *s, context *cctxt)
-{   
+{
     dsymbol *dsym;
     int dnum;
 
-    while (isspace(*s)) s++;
+    s = trim_left(s);
     if (!*s)
     {
         for (dsym = setFirstItem(dispsymbols);
@@ -3024,7 +3656,7 @@ int cmdUnDisplay (char *s, context *cctxt)
              dsym = setNextItem(dispsymbols))
         {
             Safe_free(dsym->rs);
-            Safe_free(dsym); 
+            Safe_free(dsym);
         }
         deleteSet(&dispsymbols);
         return 0;
@@ -3032,15 +3664,15 @@ int cmdUnDisplay (char *s, context *cctxt)
     while ( s && *s )
     {
         dnum = strtol(s,&s,10);
-        if (applyToSetFTrue(dispsymbols,dsymWithNumber,dnum,&dsym)) 
+        if (applyToSetFTrue(dispsymbols,dsymWithNumber,dnum,&dsym))
         {
             deleteSetItem(&dispsymbols,dsym);
             Safe_free(dsym->rs);
-            Safe_free(dsym); 
-        } 
+            Safe_free(dsym);
+        }
         else
         {
-            fprintf(stdout,"Arguments must be display numbers.\n");    
+            fprintf(stdout,"Arguments must be display numbers.\n");
         }
     }
     return 0;
@@ -3050,35 +3682,32 @@ int cmdUnDisplay (char *s, context *cctxt)
 /* cmdPrintType - print type of a variable                         */
 /*-----------------------------------------------------------------*/
 int cmdPrintType (char *s, context *cctxt)
-{   
-        symbol *sym ;
-    char *bp = s+strlen(s) -1;
+{
+    symbol *sym ;
 
-    while (isspace(*s)) s++;
+    /* trim left and right */
+    s = trim(s);
     if (!*s) return 0;
-    while (isspace(*bp)) bp--;
-    bp++ ;
-    *bp = '\0';
 
     if ((sym = symLookup(s,cctxt))) {
-       printTypeInfo(sym->type);
-       fprintf(stdout,"\n");
+        printTypeInfo(sym->type);
+        fprintf(stdout,"\n");
     } else {
-       fprintf(stdout,
-               "No symbol \"%s\" in current context.\n",
-               s);
+        fprintf(stdout,
+                "No symbol \"%s\" in current context.\n",
+                s);
     }
-    return 0;   
+    return 0;
 }
 
 /*-----------------------------------------------------------------*/
 /* cmdClrUserBp - clear user break point                           */
 /*-----------------------------------------------------------------*/
 int cmdClrUserBp (char *s, context *cctxt)
-{   
-    char *bp ;    
+{
+    char *bp ;
     function *func = NULL;
-       
+
     /* clear break point location specification can be of the following
        forms
        a) <nothing>        - break point at current location
@@ -3089,98 +3718,93 @@ int cmdClrUserBp (char *s, context *cctxt)
     */
 
     if (!cctxt) {
-       fprintf(stdout,"No symbol table is loaded.  Use the \"file\" command.\n");
-       return 0;
+        fprintf(stdout,"No symbol table is loaded.  Use the \"file\" command.\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';
+    /* trim left and right */
+    s = trim(s);
 
     /* case a) nothing */
     /* if nothing given then current location : we know
        the current execution location from the currentContext */
     if (! *s ) {
 
-       /* if current context is known */
-       if (cctxt->func) 
-           /* clear the break point @ current location */
-           clearUSERbp (cctxt->addr);
-       else
-           fprintf(stderr,"No default breakpoint address now.\n");
-                       
-       goto ret ;
+        /* if current context is known */
+        if (cctxt->func)
+            /* clear the break point @ current location */
+            clearUSERbp (cctxt->addr);
+        else
+            fprintf(stderr,"No default breakpoint address now.\n");
+
+        goto ret ;
     }
 
     /* case b) lineno */
     /* check if line number */
     if (isdigit(*s)) {
-       /* get the lineno */
-       int line = atoi(s);
-
-       /* if current context not present then we must get the module
-          which has main & set the break point @ line number provided
-          of that module : if current context known then set the bp 
-          at the line number given for the current module 
-       */
-       if (cctxt->func) {
-           if (!cctxt->func->mod) {
-               if (!applyToSet(functions,funcWithName,"main"))
-                   fprintf(stderr,"Function \"main\" not defined.\n");
-               else 
-                   clearBPatModLine(func->mod,line);
-           } else 
-               clearBPatModLine(cctxt->func->mod,line);                        
-       }
-       
-       goto ret;
+        /* get the lineno */
+        int line = atoi(s);
+
+        /* if current context not present then we must get the module
+           which has main & set the break point @ line number provided
+           of that module : if current context known then set the bp
+           at the line number given for the current module
+        */
+        if (cctxt->func) {
+            if (!cctxt->func->mod) {
+                if (!applyToSet(functions,funcWithName,"main"))
+                    fprintf(stderr,"Function \"main\" not defined.\n");
+                else
+                    clearBPatModLine(func->mod,line);
+            } else
+                clearBPatModLine(cctxt->func->mod,line);
+        }
+
+        goto ret;
     }
 
     if ((bp = strchr(s,':'))) {
-       
-       module *mod = NULL;
-       *bp = '\0';
-       
-       if (!applyToSet(modules,moduleWithCName,s,&mod)) {
-           fprintf (stderr,"No source file named %s.\n",s);
-           goto ret;
-       }
 
-       /* case c) filename:lineno */
-       if (isdigit(*(bp +1))) {                    
-        
-           clearBPatModLine (mod,atoi(bp+1));      
-           goto ret;
-           
-       }
-       /* case d) filename:function */
-       if (!applyToSet(functions,funcWithNameModule,bp+1,s,&func)) 
-           fprintf(stderr,"Function \"%s\" not defined.\n",bp+1); 
-       else
-           clearBPatModLine (mod,func->entryline);
-       
-       goto ret;
+        module *mod = NULL;
+        *bp = '\0';
+
+        if (!applyToSet(modules,moduleWithCName,s,&mod)) {
+            fprintf (stderr,"No source file named %s.\n",s);
+            goto ret;
+        }
+
+        /* case c) filename:lineno */
+        if (isdigit(*(bp +1))) {
+
+            clearBPatModLine (mod,atoi(bp+1));
+            goto ret;
+
+        }
+        /* case d) filename:function */
+        if (!applyToSet(functions,funcWithNameModule,bp+1,s,&func))
+            fprintf(stderr,"Function \"%s\" not defined.\n",bp+1);
+        else
+            clearBPatModLine (mod,func->entryline);
+
+        goto ret;
     }
-            
+
     /* case e) function */
     if (!applyToSet(functions,funcWithName,s,&func))
-       fprintf(stderr,"Function \"%s\" not defined.\n",s); 
+        fprintf(stderr,"Function \"%s\" not defined.\n",s);
     else
-       clearBPatModLine(func->mod,func->entryline);
+        clearBPatModLine(func->mod,func->entryline);
 
- ret:    
-    return 0;        
+ ret:
+    return 0;
 }
 
 /*-----------------------------------------------------------------*/
 /* cmdSimulator - send command to simulator                        */
 /*-----------------------------------------------------------------*/
 int cmdSimulator (char *s, context *cctxt)
-{   
+{
   char tmpstr[82];
 
     if (strlen(s) > 80) {
@@ -3198,12 +3822,12 @@ int cmdSimulator (char *s, context *cctxt)
 void setMainContext()
 {
     function *func = NULL;
-    currentFrame = 0; 
+    currentFrame = 0;
     if (!applyToSet(functions,funcWithName,"_main",&func) &&
         !applyToSet(functions,funcWithName,"main",&func))
             return;
 
-    discoverContext (func->sym->addr, func);
+    discoverContext (func->sym->addr, func, currCtxt);
 }
 
 function *needExtraMainFunction()
@@ -3218,12 +3842,15 @@ function *needExtraMainFunction()
     }
     return NULL;
 }
-    
+
 static void printFrame()
 {
     int i;
     function *func     = NULL;
     function *lastfunc = NULL;
+    context *ctx, my_context;
+    unsigned int bp, pc;
+    int status;
 
     if ( currentFrame < 0 )
     {
@@ -3231,23 +3858,28 @@ static void printFrame()
         fprintf(stdout,"Bottom (i.e., innermost) frame selected; you cannot go down.\n");
         return;
     }
-    STACK_STARTWALK(callStack) ;
-    for ( i = 0; i <= currentFrame ; i++ )
+    i = 0;
+    for (status = frameStart(&bp, &pc); status; status = frameNext(&bp, &pc))
     {
-        func = STACK_WALK(callStack);
-        if ( !func )
-        {
-            currentFrame = i-1;
-            fprintf(stdout,"Initial frame selected; you cannot go up.\n");
-            return;
-        }
+       if (i >= currentFrame)
+           break;
+       i++;
+    }
+    if (i < currentFrame) {
+        currentFrame = i;
+        fprintf(stdout,"Initial frame selected; you cannot go up.\n");
+        return;
+    }
+    ctx = discoverContext(pc, NULL, &my_context);
+    if (ctx && (func = ctx->func)) {
+       fprintf(stdout,"#%d  0x%08x in %s () at %s:%d\n",
+               currentFrame,pc,func->sym->name,func->mod->c_name,func->lline+1);
+       fprintf(stdout,"\032\032%s:%d:1:beg:0x%08x\n",
+               canonname(func->mod->cfullname),func->lline+1,func->laddr);
+    } else {
+       fprintf(stdout,"#%d  0x%08x\n",
+               currentFrame,pc);
     }
-    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);
 }
 
 
@@ -3256,14 +3888,14 @@ static void printFrame()
 /*-----------------------------------------------------------------*/
 int cmdUp(char *s, context *cctxt)
 {
-    while (isspace(*s)) s++;
+    s = trim_left(s);
     if ( *s )
         currentFrame += strtol(s,0,10);
     else
         currentFrame++ ;
 
     printFrame();
-       return 0;
+        return 0;
 }
 
 /*-----------------------------------------------------------------*/
@@ -3271,24 +3903,24 @@ int cmdUp(char *s, context *cctxt)
 /*-----------------------------------------------------------------*/
 int cmdDown(char *s, context *cctxt)
 {
-    while (isspace(*s)) s++;
+    s = trim_left(s);
     if ( *s )
         currentFrame -= strtol(s,0,10);
     else
         currentFrame-- ;
 
     printFrame();
-       return 0;
+        return 0;
 }
 /*-----------------------------------------------------------------*/
 /* cmdFrame - Frame command                                        */
 /*-----------------------------------------------------------------*/
 int cmdFrame (char *s, context *cctxt)
-{   
+{
     function *func = NULL;
-    int i, framenr = 0;
+    int framenr = 0;
 
-    while (isspace(*s)) s++;
+    s = trim_left(s);
     if ( *s )
         currentFrame = strtol(s,0,10);
     printFrame();
@@ -3300,25 +3932,27 @@ int cmdFrame (char *s, context *cctxt)
 /*-----------------------------------------------------------------*/
 int cmdFinish (char *s, context *ctxt)
 {
+#if 0
     if (STACK_EMPTY(callStack)) {
-       fprintf(stdout,"The program is not running.\n");
-       return 0;
+        fprintf(stdout,"The program is not running.\n");
+        return 0;
     }
+#endif
 
     if (srcMode == SRC_CMODE) {
-       setBreakPoint (ctxt->func->sym->eaddr, CODE, STEP, 
-                      stepBpCB, ctxt->func->mod->c_name, 
-                      ctxt->func->exitline);
+        setBreakPoint (ctxt->func->sym->eaddr, CODE, STEP,
+                       stepBpCB, ctxt->func->mod->c_name,
+                       ctxt->func->exitline);
     } else {
-       setBreakPoint (ctxt->func->sym->eaddr, CODE, STEP, 
-                      stepBpCB, ctxt->func->mod->asm_name, 
-                      ctxt->func->aexitline);
+        setBreakPoint (ctxt->func->sym->eaddr, CODE, STEP,
+                       stepBpCB, ctxt->func->mod->asm_name,
+                       ctxt->func->aexitline);
     }
 
     simGo(-1);
     showfull = 1;
     return 0;
-    
+
 }
 
 
@@ -3328,16 +3962,16 @@ int cmdFinish (char *s, context *ctxt)
 int cmdShow (char *s, context *cctxt)
 {
     /* skip white space */
-    while (*s && isspace(*s)) s++ ;
+    s = trim_left(s);
 
     if (strcmp(s,"copying") == 0) {
-       fputs(copying,stdout);
-       return 0;
+        fputs(copying,stdout);
+        return 0;
     }
-    
+
     if (strcmp(s,"warranty") == 0) {
-       fputs(warranty,stdout);
-       return 0;
+        fputs(warranty,stdout);
+        return 0;
     }
 
     return 0;