Use 'ao-dbg' instead of 's51' to communicate with TeleMetrum
[fw/sdcc] / debugger / mcs51 / cmd.c
index 059826bb4eefc63098db5510124cf6f3ece6ae12..cd038fffea32bcf9665469ffdfa2ba1671a79186 100644 (file)
@@ -37,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"};
@@ -328,7 +326,7 @@ static char *warranty=
 #endif
 
 static void printTypeInfo(link *);
-static void printValAggregates (symbol *,link *,char,unsigned int,int);
+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);
@@ -649,7 +647,7 @@ DEFSETFUNC(lineNearAddr)
 /*-----------------------------------------------------------------*/
 /* 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;
@@ -662,39 +660,610 @@ context *discoverContext (unsigned addr, function *func)
             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;
+        ctxt->asmline = line;
     else
-        currCtxt->asmline = -1;
+        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
 
-    return currCtxt ;
+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 */
 /*-----------------------------------------------------------------*/
@@ -710,19 +1279,21 @@ void simGo (unsigned int gaddr)
         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
        linenumber of the source etc, etc etc */
     currentFrame = 0;
-    ctxt = discoverContext (addr, NULL);
+    ctxt = discoverContext (addr, NULL, currCtxt);
 
     /* dispatch all the break point call back functions */
     rv = dispatchCB (addr,ctxt);
@@ -749,6 +1320,7 @@ static char *preparePrint(char *s, context *cctxt, int *fmt, symbol **sym)
 {
     char *bp;
     char save_ch ;
+    int ptr = 0;
 
     *fmt = FMT_NON;
     *sym = NULL;
@@ -779,6 +1351,10 @@ static char *preparePrint(char *s, context *cctxt, int *fmt, symbol **sym)
         s++;
         s = trim_left(s);
     }
+    while (*s == '*') {
+       ptr++;
+       s++;
+    }
     for ( bp = s; *bp && ( isalnum( *bp ) || *bp == '_' || *bp == '$'); bp++ );
     save_ch = *bp;
     if ( *bp )
@@ -787,6 +1363,8 @@ 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);
@@ -903,7 +1481,7 @@ static int cmdDisasm (char *s, context *cctxt, int args)
     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 )
         {
@@ -1011,11 +1589,11 @@ 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);
             }
@@ -1141,7 +1719,7 @@ int cmdJump (char *s, context *cctxt)
 {
     char *bp;
     function *func = NULL;
-    if (STACK_EMPTY(callStack))
+    if (!is_running())
     {
         fprintf(stdout,"The program is not running.\n");
         return 0;
@@ -1307,7 +1885,7 @@ int cmdSetOption (char *s, context *cctxt)
 /*-----------------------------------------------------------------*/
 int cmdContinue (char *s, context *cctxt)
 {
-    if (STACK_EMPTY(callStack)) {
+    if (!is_running()) {
         fprintf(stdout,"The program is not being run.\n");
         return 0;
     }
@@ -1431,7 +2009,7 @@ int cmdDelUserBp (char *s, context *cctxt)
 int cmdStepi (char *s, context *cctxt)
 {
 
-    if (0 /*STACK_EMPTY(callStack)*/)
+    if (!is_running())
         fprintf(stdout,"The program is not being run.\n");
     else
     {
@@ -1443,6 +2021,126 @@ int cmdStepi (char *s, context *cctxt)
     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                        */
 /*-----------------------------------------------------------------*/
@@ -1450,79 +2148,10 @@ int cmdStep (char *s, context *cctxt)
 {
     function *func = NULL;
 
-    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,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);
-                }
-            }
-        }
-
-        doingSteps = 1;
-        simGo(2);
-        doingSteps = 0;
-        showfull = 1;
-    }
+    else
+       do_step(cctxt, 1);
     return 0;
 }
 
@@ -1531,7 +2160,7 @@ 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
     {
@@ -1552,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;
 }
 
@@ -1622,7 +2194,8 @@ int cmdNext (char *s, context *cctxt)
 int cmdRun (char *s, context *cctxt)
 {
     char buff[10];
-    if (STACK_EMPTY(callStack)) {
+
+    if (!is_running()) {
         fprintf(stdout,"Starting program\n");
     if ( ! simactive )
     {
@@ -1646,6 +2219,7 @@ int cmdRun (char *s, context *cctxt)
         }
     }
     showfull = 1;
+    set_running(1);
     return 0;
 }
 
@@ -1927,17 +2501,17 @@ static void infoRegisters( int all, context *ctxt)
     for ( j = 0; j < 8 ; j++ )
     {
         val = simGetValue (j,'R',1);
-        fprintf(stdout," 0x%02X",val);
+        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 (0x%04X)\n",val,simGetValue (val-1,'B',2));
+    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 )
@@ -1956,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++ )
@@ -1983,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");
@@ -2016,7 +2598,7 @@ int cmdInfo (char *s, context *cctxt)
     s = trim(s);
 
     /* list all break points */
-    if (strcmp(s,"break") == 0) {
+    if (strncmp(s,"break",5) == 0) {
         listUSERbp();
         return 0;
     }
@@ -2300,7 +2882,7 @@ int cmdListSrc (char *s, context *cctxt)
         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;
@@ -2480,7 +3062,7 @@ static void printValBasic(symbol *sym, link *type,
         fprintf(stdout,"%f",v.f);
     else
         if (IS_PTR(type))
-            fprintf(stdout,"0x%*x",size<<1,v.val);
+            fprintf(stdout,"0x%0*lx",size<<1,v.val);
         else
         if (IS_INTEGRAL(type))
         {
@@ -2516,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);
+            fprintf(stdout,"0x%0*lx",size<<1,v.val);
 }
 
 /*-----------------------------------------------------------------*/
@@ -2531,67 +3113,90 @@ 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;
+    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);
-                } else {
-                        printValBasic(sym,elem_type,space,addr,getSize(elem_type),fmt);
-                }
-                addr += getSize(elem_type);
-                if (i != DCL_ELEM(type) -1)
-                        fprintf(stdout,",");
-        }
+    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)
+                              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;
-        }
-        fprintf(stdout,"}");
+    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,",\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);
+                printArrayValue(sym, type, space, addr, fmt, indent);
                 return ;
         }
 
         if (IS_STRUCT(type)) {
-                printStructValue(sym, type, space, addr, fmt);
+                printStructValue(sym, type, space, addr, fmt, indent);
                 return;
         }
 }
@@ -2611,6 +3216,7 @@ static int printOrSetSymValue (symbol *sym, context *cctxt,
     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)
@@ -2650,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++ ;
@@ -2682,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;
             }
+           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 */
@@ -2715,8 +3323,26 @@ static int printOrSetSymValue (symbol *sym, context *cctxt,
             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 */
@@ -2728,7 +3354,7 @@ static int printOrSetSymValue (symbol *sym, context *cctxt,
             return 1;
         }
         else
-            printValAggregates(sym,type,sym->addrspace,addr,fmt);
+            printValAggregates(sym,type,sym->addrspace,addr,fmt,0);
     }
     else
         /* functions */
@@ -3201,7 +3827,7 @@ void setMainContext()
         !applyToSet(functions,funcWithName,"main",&func))
             return;
 
-    discoverContext (func->sym->addr, func);
+    discoverContext (func->sym->addr, func, currCtxt);
 }
 
 function *needExtraMainFunction()
@@ -3222,6 +3848,9 @@ static void printFrame()
     int i;
     function *func     = NULL;
     function *lastfunc = NULL;
+    context *ctx, my_context;
+    unsigned int bp, pc;
+    int status;
 
     if ( currentFrame < 0 )
     {
@@ -3229,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);
 }
 
 
@@ -3298,10 +3932,12 @@ 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;
     }
+#endif
 
     if (srcMode == SRC_CMODE) {
         setBreakPoint (ctxt->func->sym->eaddr, CODE, STEP,