Extract call stack from running machine.
authorKeith Packard <keithp@keithp.com>
Sun, 28 Dec 2008 08:04:33 +0000 (00:04 -0800)
committerKeith Packard <keithp@keithp.com>
Wed, 29 Apr 2009 18:10:10 +0000 (11:10 -0700)
This replaces the breakpoint-managed call stack with code that reads the
stack from the target to compute it. The stack depth is computed by a
breadth-first walk of the instructions looking for a return instruction
computing the aggregate stack pointer change.

debugger/mcs51/break.c
debugger/mcs51/cmd.c
debugger/mcs51/sdcdb.c
debugger/mcs51/sdcdb.h
debugger/mcs51/simi.c
debugger/mcs51/simi.h

index 0637661932aaf1ad4edf63fe4384114dfa1cd90a..ea19450fa2ed503066ca82f1b769184aa7b2eadc 100644 (file)
@@ -31,9 +31,6 @@ hTab *bptable = NULL;
 char doingSteps    = 0;
 char userBpPresent = 0;
 
-/* call stack can be 1024 deep */
-STACK_DCL(callStack,function *,1024);
-
 #ifdef SDCDB_DEBUG
 char *debug_bp_type_strings[] =
     {"ERR-0",
@@ -111,14 +108,11 @@ int setBreakPoint (unsigned addr, char addrType, char bpType,
         userBpPresent++;
     }
 
-    if (bpType != STEP && bpType != NEXT)
-    {
-        /* if a break point does not already exist then
-           send command to simulator to add one */
-        if (!hTabSearch(bptable,addr))
-            /* send the break command to the simulator */
-            simSetBP (addr);
-    }
+    /* if a break point does not already exist then
+     send command to simulator to add one */
+    if (!hTabSearch(bptable,addr))
+       /* send the break command to the simulator */
+    simSetBP (addr);
 
     /* now add the break point to list */
     hTabAddItem(&bptable,addr,bp);
@@ -143,6 +137,7 @@ void deleteSTEPbp ()
         /* if this is a step then delete */
         if (bp->bpType == STEP)
         {
+           simClearBP(bp->addr);
             hTabDeleteItem(&bptable,bp->addr,bp,DELETE_ITEM,NULL);
             Safe_free(bp);
         }
@@ -421,59 +416,6 @@ int dispatchCB (unsigned addr, context *ctxt)
     return rv;
 }
 
-/*-----------------------------------------------------------------*/
-/* fentryCB - callback function for function entry                 */
-/*-----------------------------------------------------------------*/
-BP_CALLBACK(fentryCB)
-{
-    function *func;
-
-    /* we save the value of SP
-       which will be used to display the value of local variables
-       and parameters on the stack */
-    ctxt->func->stkaddr = simGetValue (0x81,'I',1);
-
-    Dprintf(D_break, ("break: fentryCB: BP_CALLBACK entry %s sp=0x%02x %p\n",
-                      ctxt->func->sym->name,
-                      ctxt->func->stkaddr, p_callStack));
-
-    /* and set laddr of calling function to return addr from stack */
-    if ((func = STACK_PEEK(callStack)))
-    {
-        /* extern stack ?? 'A' */
-        func->laddr = simGetValue (ctxt->func->stkaddr-1,'B',2);
-    }
-    /* add the current function into the call stack */
-    STACK_PUSH(callStack,ctxt->func);
-
-    return 0;
-}
-
-/*-----------------------------------------------------------------*/
-/* fexitCB - call back for function exit                           */
-/*-----------------------------------------------------------------*/
-BP_CALLBACK(fexitCB)
-{
-    function *func;
-    /* pop the top most from the call stack */
-    func = STACK_POP(callStack);
-
-    if (!func)
-    {
-        fprintf(stdout, "Stack underflow\n");
-        return 1;
-    }
-
-    Dprintf(D_break, ("break: fexitCB: BP_CALLBACK entry %s %p\n", func->sym->name, p_callStack));
-
-    /* check main function */
-    if ( !strcmp(func->sym->name, "main"))
-    {
-        fprintf(stdout, "Program exited with code %lu.\n", simGetValue (0x82,'I',2));
-        return 1;
-    }
-    return 0;
-}
 /*-----------------------------------------------------------------*/
 /* userBpCB - call back function for user break points             */
 /*-----------------------------------------------------------------*/
index 79dba8d30df0ccf2437d8fbbb99eef2af4f10e9f..4cae0c91c5ec1284ef09a7437c965a3744e58e3b 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"};
@@ -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,38 +660,544 @@ 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 int pc_change(unsigned addr, unsigned addrs[2])
+{
+       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)));
+               return 1;
+       }
+       
+       /* AJMP */
+       if ((insn & 0x1f) == 0x01) {
+               unsigned char   direct = simGetValue(addr+1,'C', 1);
+
+               addrs[0] = ((addr + 2) & 0xf800) | ((insn & 0xe0) << 3) | direct;
+               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) {
+               addrs[0] = new_addr;
+               return 1;
+       }
 
-    return currCtxt ;
+       addrs[0] = addr + len;
+       addrs[1] = new_addr;
+       return 2;
+}
+
+#define SEARCH_FAILED  0x8000
+
+static int
+stack_depth(unsigned pc, int search)
+{
+       unsigned new_pc[2];
+       unsigned max_pc = pc;
+       int n;
+       int s;
+       int change;
+
+       change = 0;
+       for (;;) {
+               change += stack_change(pc);
+               n = pc_change(pc, new_pc);
+               if (n == 0)
+                       return change;
+               if (n != 1)
+                       break;
+               pc = new_pc[0];
+               /* detect infinite loop */
+               if (pc == max_pc)
+                       return change;
+               if (pc > max_pc)
+                       max_pc = pc;
+       }
+       
+       if (search == 0)
+               return SEARCH_FAILED;
+       
+       for (s = 0; s < search - 1; s++) {
+               int d;
+               int i;
+               d = SEARCH_FAILED;
+               for (i = 0; i < n; i++) {
+                       d = stack_depth(new_pc[i], search-1);
+                       if (d != SEARCH_FAILED)
+                               return d + change;
+               }
+       }
+       return SEARCH_FAILED;
 }
 
+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, 100);
+       bp = sp + depth;
+       if (bp < stack_start())
+               return 0;
+       *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);
+       depth = stack_depth(pc, 100);
+       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 +1214,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);
@@ -1148,7 +1654,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;
@@ -1314,7 +1820,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;
     }
@@ -1438,7 +1944,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
     {
@@ -1450,6 +1956,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                        */
 /*-----------------------------------------------------------------*/
@@ -1457,79 +2083,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;
 }
 
@@ -1538,7 +2095,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
     {
@@ -1559,67 +2116,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;
 }
 
@@ -1629,7 +2129,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 )
     {
@@ -1653,6 +2154,7 @@ int cmdRun (char *s, context *cctxt)
         }
     }
     showfull = 1;
+    set_running(1);
     return 0;
 }
 
@@ -1990,14 +2492,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");
@@ -2307,7 +2817,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;
@@ -3252,7 +3762,7 @@ void setMainContext()
         !applyToSet(functions,funcWithName,"main",&func))
             return;
 
-    discoverContext (func->sym->addr, func);
+    discoverContext (func->sym->addr, func, currCtxt);
 }
 
 function *needExtraMainFunction()
@@ -3273,6 +3783,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 )
     {
@@ -3280,23 +3793,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);
 }
 
 
@@ -3349,10 +3867,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,
index fc132d8c87acf772b96d625c79e440e5a8c0d0b1..7fe5f8e0d906481686124e847993f27c6bc91d62 100644 (file)
    what you give them.   Help stamp out software-hoarding!
 -------------------------------------------------------------------------*/
 
+#define link unix_link
+#define _GNU_SOURCE
+#include <unistd.h>
+#undef link
 #include "sdcdb.h"
 #include "symtab.h"
 #include "simi.h"
@@ -61,6 +65,7 @@ int nsimArgs = 0;
 char model_str[20];
 /* fake filename & lineno to make linker */
 char *filename=NULL;
+char *current_directory;
 int lineno = 0;
 int fatalError = 0;
 
@@ -382,7 +387,7 @@ char *searchDirsFname (char *fname)
 {
     char *dirs , *sdirs;
     FILE *rfile = NULL;
-    char buffer[128];
+    char buffer[1024];
 
     /* first try the current directory */
     if ((rfile = fopen(fname,"r"))) {
@@ -424,7 +429,7 @@ FILE *searchDirsFopen(char *fname)
 {
     char *dirs , *sdirs;
     FILE *rfile = NULL;
-    char buffer[128];
+    char buffer[1024];
 
     /* first try the current directory */
     if ((rfile = fopen(fname,"r")))
@@ -688,35 +693,13 @@ static void functionPoints (void)
     }
 }
 
-
-/*-----------------------------------------------------------------*/
-/* setEntryExitBP - set the entry & exit Break Points for functions*/
-/*-----------------------------------------------------------------*/
-DEFSETFUNC(setEntryExitBP)
-{
-    function *func = item;
-
-    if (func->sym && func->sym->addr && func->sym->eaddr) {
-
-        /* set the entry break point */
-        setBreakPoint (func->sym->addr , CODE , FENTRY ,
-            fentryCB ,func->mod->c_name , func->entryline);
-
-        /* set the exit break point */
-        setBreakPoint (func->sym->eaddr , CODE , FEXIT  ,
-            fexitCB  ,func->mod->c_name , func->exitline );
-    }
-
-    return 0;
-}
-
 /*-----------------------------------------------------------------*/
 /* cmdFile - load file into the debugger                           */
 /*-----------------------------------------------------------------*/
 int cmdFile (char *s,context *cctxt)
 {
     FILE *cdbFile;
-    char buffer[128];
+    char buffer[1024];
     char *bp;
 
     s = trim_left(s);
@@ -771,7 +754,7 @@ int cmdFile (char *s,context *cctxt)
     /*set the break points
        required by the debugger . i.e. the function entry
        and function exit break points */
-    applyToSet(functions,setEntryExitBP);
+//    applyToSet(functions,setEntryExitBP);
 
     setMainContext();
     return 0;
@@ -847,6 +830,16 @@ int cmdHelp (char *s, context *cctxt)
 static char cmdbuff[MAX_CMD_LEN];
 static int sim_cmd_mode = 0;
 
+char *
+canonname(char *file)
+{
+    static char        buffer[1024];
+    if (*file == '/')
+       return file;
+    sprintf(buffer,"%s/%s", current_directory, file);
+    return buffer;
+}
+
 /*-----------------------------------------------------------------
  interpretCmd - interpret and do the command.  Return 0 to continue,
    return 1 to exit program.
@@ -859,7 +852,7 @@ int interpretCmd (char *s)
 
     /* if nothing & previous command exists then
        execute the previous command again */
-    if (*s == '\n' && pcmd)
+    if ((*s == '\n' || *s == '\0') && pcmd)
         strcpy(s,pcmd);
 
     /* if previous command exists & is different
@@ -912,11 +905,11 @@ int interpretCmd (char *s)
                 showfull = 0;
                 if (srcMode == SRC_CMODE)
                     fprintf(stdout,"\032\032%s:%d:1:beg:0x%08x\n",
-                        currCtxt->func->mod->cfullname,
+                        canonname(currCtxt->func->mod->cfullname),
                         currCtxt->cline+1,currCtxt->addr);
                 else
                     fprintf(stdout,"\032\032%s:%d:1:beg:0x%08x\n",
-                        currCtxt->func->mod->afullname,
+                        canonname(currCtxt->func->mod->afullname),
                         currCtxt->asmline,currCtxt->addr);
                 displayAll(currCtxt);
             }
@@ -1603,7 +1596,7 @@ static void parseCmdLine (int argc, char **argv)
             }
 
             if (strncmp(argv[i],"-cd=",4) == 0) {
-                chdir(argv[i][4]);
+                chdir(argv[i]+4);
                 continue;
             }
 
@@ -1764,6 +1757,7 @@ int main ( int argc, char **argv)
     printVersionInfo();
     printf("WARNING: SDCDB is EXPERIMENTAL.\n");
 
+    current_directory = get_current_dir_name();
     simArgs[nsimArgs++] = "s51";
     simArgs[nsimArgs++] = "-P";
     simArgs[nsimArgs++] = "-r 9756";
index b286ac161d12cd32ff58a82d33bb2af2d8b4b365..67a089cf85529e83da5d748089192a0d235a7abf 100644 (file)
@@ -79,53 +79,6 @@ typedef short bool;
  * #endif
  */
 
-/* generalpurpose stack related macros */
-#define  STACK_DCL(stack,type,size)                   \
-         typedef  type  t_##stack   ;                 \
-         t_##stack   stack[size]    ;                 \
-         t_##stack   (*p_##stack) = stack + (size);   \
-         t_##stack   (*w_##stack)   ;
-
-/* define extern stack */
-#define EXTERN_STACK_DCL(stack,type,size)             \
-        typedef type t_##stack     ;                  \
-        extern t_##stack stack[size] ;                \
-        extern t_##stack *p_##stack;                  \
-        extern t_##stack *w_##stack;
-
-#define  STACK_FULL(stack)    ((p_##stack) <= stack )
-#define  STACK_EMPTY(stack)   ((p_##stack) >= (stack +      \
-                              sizeof(stack)/sizeof(*stack)) )
-
-#define  STACK_PUSH_(stack,x) (*--p_##stack = (x))
-#define  STACK_POP_(stack)    (*p_##stack++)
-
-#define  STACK_PUSH(stack,x)  (STACK_FULL(stack)                  \
-                              ?((t_##stack)(long)(STACK_ERR(1)))  \
-                              : STACK_PUSH_(stack,x)              )
-
-#define  STACK_POP(stack)     (STACK_EMPTY(stack)                 \
-                              ?((t_##stack) NULL)  \
-                              : STACK_POP_(stack)                 )
-
-#define  STACK_PEEK(stack)    (STACK_EMPTY(stack)                 \
-                              ?((t_##stack) NULL)                 \
-                              : *p_##stack                        )
-
-#define  STACK_PPEEK(stack)    (((p_##stack + 1) >= (stack +      \
-                              sizeof(stack)/sizeof(*stack)))      \
-                              ?((t_##stack) NULL)                 \
-                              : *(p_##stack + 1)                  )
-
-#define  STACK_ERR(o)         ( o                                 \
-                              ? fprintf(stderr,"stack Overflow\n")\
-                              : fprintf(stderr,"stack underflow\n"))
-
-#define  STACK_STARTWALK(stack)   (w_##stack = p_##stack)
-
-#define  STACK_WALK(stack)    (w_##stack >= (stack + sizeof(stack)/sizeof(*stack)) \
-                               ? NULL : *w_##stack++ )
-
 #include "src/SDCCbitv.h"
 
 enum {
index c44b40718ff2047a48350343c94c1b12f9b54f6c..d75e420d73a73f3b47d20e8c39e382a7047ef1c6 100644 (file)
@@ -528,6 +528,16 @@ void simSetPC( unsigned int addr )
     simResponse();
 }
 
+unsigned int simGetPC(void)
+{
+    char *sr;
+    sendSim("pc\n");
+    waitForSim(100,NULL);
+    simResponse();
+    sr = simResponse();
+    return strtol(sr+3,0,0);
+}
+    
 int simSetValue (unsigned int addr,char mem, int size, unsigned long val)
 {
     char cachenr, i;
index 237fe27aa1d53aac733d16b1fedad15f2cb375dc..5305e79940ba4b441c54a62b94f2059f3433e465 100644 (file)
@@ -65,6 +65,7 @@ void  closeSimulator ();
 void  sendSim(char *);
 char *simResponse();
 void  simSetPC (unsigned int);
+unsigned int simGetPC (void);
 void  simSetBP (unsigned int);
 void  simClearBP (unsigned int);
 void  simLoadFile(char *);