set PC if a symbol at pc reg is set
[fw/sdcc] / debugger / mcs51 / cmd.c
index 86c17d2ce294f8ff53eba4371fe1a67723f001cf..40d47ab8177e4a47426b671adf49069345b6b8d6 100644 (file)
@@ -330,8 +330,9 @@ static char *warranty=
 
 static void printTypeInfo(link *);
 static void printValAggregates (symbol *,link *,char,unsigned int,int);
-static void printOrSetSymValue (symbol *sym, context *cctxt, 
-                                int flg, int dnum, int fmt, char *rs, char *val);
+static  int printOrSetSymValue (symbol *sym, context *cctxt, 
+                                int flg, int dnum, int fmt, 
+                                char *rs, char *val, char cmp);
 
 int srcMode = SRC_CMODE ;
 static set  *dispsymbols = NULL   ; /* set of displayable symbols */
@@ -733,7 +734,7 @@ void simGo (unsigned int gaddr)
 }
 
 /*-----------------------------------------------------------------*/
-/* preparePrint - common parse function for                        */
+/* preparePrint - common parse function for  set variable,         */
 /*                output, print and display                        */
 /*-----------------------------------------------------------------*/
 static char *preparePrint(char *s, context *cctxt, int *fmt, symbol **sym)
@@ -774,12 +775,13 @@ static char *preparePrint(char *s, context *cctxt, int *fmt, symbol **sym)
         s++;
         while (isspace(*s)) s++;
     }
-    for ( bp = s; *bp && ( isalnum( *bp ) || *bp == '_'); bp++ );
+    for ( bp = s; *bp && ( isalnum( *bp ) || *bp == '_' || *bp == '$'); bp++ );
     save_ch = *bp;
     if ( *bp )
         *bp = '\0';
 
-    *sym = symLookup(s,cctxt);
+    if ( *s )
+        *sym = symLookup(s,cctxt);
     *bp = save_ch;
 
     if ( ! *sym )
@@ -977,6 +979,7 @@ static int commonSetUserBp(char *s, context *cctxt, char bpType)
 
        /* if current context is known */
        if (cctxt->func) {
+        Dprintf(D_break, ("commonSetUserBp: a) cctxtaddr:%x \n",cctxt->addr));
            if (srcMode == SRC_CMODE)
                /* set the break point */
                setBreakPoint ( cctxt->addr , CODE , bpType , userBpCB ,
@@ -1005,6 +1008,7 @@ static int commonSetUserBp(char *s, context *cctxt, char bpType)
             }
             else
             {
+                Dprintf(D_break, ("commonSetUserBp: g) addr:%x \n",braddr));
                 setBreakPoint ( braddr , CODE , bpType , userBpCB ,
                             modul->c_name,line);
             }
@@ -1023,9 +1027,10 @@ static int commonSetUserBp(char *s, context *cctxt, char bpType)
     }
     /* case b) lineno */
     /* check if line number */
-    if (isdigit(*s)) {
+    if ( !strchr(s,':') && isdigit(*s)) {
        /* get the lineno */
        int line = atoi(s) -1;
+    Dprintf(D_break, ("commonSetUserBp: b) line:%d \n",line));
 
        /* if current context not present then we must get the module
           which has main & set the break point @ line number provided
@@ -1069,8 +1074,8 @@ static int commonSetUserBp(char *s, context *cctxt, char bpType)
        }
                
        /* case c) filename:lineno */
-       if (isdigit(*(bp +1))) {                    
-        
+       if (isdigit(*(bp +1))) {                         
+        Dprintf(D_break, ("commonSetUserBp: c) line:%d \n",atoi(bp+1)));
            setBPatModLine (mod,atoi(bp+1)-1,bpType);       
            goto ret;
            
@@ -1079,6 +1084,7 @@ static int commonSetUserBp(char *s, context *cctxt, char bpType)
        if (!applyToSet(functions,funcWithNameModule,bp+1,s,&func)) 
            fprintf(stderr,"Function \"%s\" not defined.\n",bp+1); 
        else        
+        Dprintf(D_break, ("commonSetUserBp: d) \n"));
            setBPatModLine (mod,
                            (srcMode == SRC_CMODE ? 
                             func->entryline :
@@ -1088,6 +1094,7 @@ static int commonSetUserBp(char *s, context *cctxt, char bpType)
     }
             
     /* case e) function */
+    Dprintf(D_break, ("commonSetUserBp: e) \n"));
     if (!applyToSet(functions,funcWithName,s,&func))
        fprintf(stderr,"Function \"%s\" not defined.\n",s); 
     else
@@ -1270,10 +1277,10 @@ int cmdSetOption (char *s, context *cctxt)
         while (*s && *s != '=') s++;
         *s++ = '\0';
         while (isspace(*s)) *s++ = '\0';
-        if (*s)
+        if (*s && sym)
         {
-                printOrSetSymValue(sym,cctxt,0,0,0,rs,s);
-                return 0;
+            printOrSetSymValue(sym,cctxt,0,0,0,rs,s,'\0');
+            return 0;
         }
         else
             fprintf(stdout,"No new value for \"%s\".\n",s);
@@ -1301,6 +1308,52 @@ int cmdContinue (char *s, context *cctxt)
     return 0;
 }
 
+/*-----------------------------------------------------------------*/
+/* cmdIgnore - set ignorecount for breakpoint                      */
+/*-----------------------------------------------------------------*/
+int cmdIgnore (char *s, context *cctxt)
+{   
+    int bpnum, cnt ;
+    while (isspace(*s)) s++;
+    if (!*s ) 
+    {
+        fprintf(stdout,"Argument required (breakpoint number).\n");
+        return 0;
+    }
+    bpnum = strtol(s,&s,10);
+    while (isspace(*s)) s++;
+    if (!*s ) 
+    {
+        fprintf(stdout,"Second argument (specified ignore-count) is missing.");
+        return 0;
+    }
+    cnt = strtol(s,0,10);
+    setUserbpIgnCount(bpnum,cnt);
+    return 0;
+}
+
+/*-----------------------------------------------------------------*/
+/* cmdCondition - set condition for breakpoint                     */
+/*-----------------------------------------------------------------*/
+int cmdCondition (char *s, context *cctxt)
+{   
+    int bpnum ;
+    while (isspace(*s)) s++;
+    if (!*s ) 
+    {
+        fprintf(stdout,"Argument required (breakpoint number).\n");
+        return 0;
+    }
+    bpnum = strtol(s,&s,10);
+    while (isspace(*s)) s++;
+    if (*s)
+        s = Safe_strdup(s);
+    else
+        s = NULL;
+    setUserbpCondition(bpnum,s);
+    return 0;
+}
+
 /*-----------------------------------------------------------------*/
 /* cmdCommands - set commands for breakpoint                       */
 /*-----------------------------------------------------------------*/
@@ -1566,6 +1619,7 @@ int cmdRun (char *s, context *cctxt)
         fprintf(stdout,"No executable file specified.\nUse the \"file\" command.\n");
         return 0;
     }
+    resetHitCount();
        simGo(0);
     } else {
        
@@ -1577,6 +1631,7 @@ int cmdRun (char *s, context *cctxt)
        fgets(buff,sizeof(buff),stdin);
        if (toupper(buff[0]) == 'Y') {
            simReset();
+        resetHitCount();
            simGo(0);
        }
     }
@@ -1855,12 +1910,12 @@ static void infoSymbols(context *ctxt)
 /*-----------------------------------------------------------------*/
 static void infoRegisters( int all, context *ctxt)
 {
-    static unsigned int regaddrs[] = {0x81,0x82,0x83,0xd0,0xe0,0xf0,0};
+    static unsigned int regaddrs[] = {0x81,0x82,0x83,0xb8,0xd0,0xe0,0xf0,0};
     unsigned long val;
     int i,j,*r;
 
     i   = simGetValue (0xd0,'I',1);
-    fprintf(stdout,"PC  : 0x%04X  RegisterBank %d:\nR0-7:",ctxt->addr,(i>>3)&3);
+    fprintf(stdout,"IP  : 0x%04X  RegisterBank %d:\nR0-7:",ctxt->addr,(i>>3)&3);
     for ( j = 0; j < 8 ; j++ )
     {
         val = simGetValue (j ,'R',1);
@@ -2260,8 +2315,7 @@ int cmdListSrc (char *s, context *cctxt)
     return 0;
 }
 
-static void setValBasic(symbol *sym, link *type,
-                        char mem, unsigned addr,int size, char *val)
+static unsigned long getValBasic(symbol *sym, link *type, char *val)
 {
     char *s;
     union 
@@ -2277,7 +2331,7 @@ static void setValBasic(symbol *sym, link *type,
     }v;
 
     if (IS_FLOAT(type))        
-        v.f = strtof(val,NULL);    
+        v.f = strtod(val,NULL);    
     else
        if (IS_PTR(type))
            v.val = strtol(val,NULL,0);
@@ -2316,7 +2370,7 @@ static void setValBasic(symbol *sym, link *type,
         else
             v.val = strtol(val,NULL,0);
     }
-    simSetValue(addr,mem,size,v.val);  
+    return v.val;
 }
 
 /*-----------------------------------------------------------------*/
@@ -2540,8 +2594,9 @@ static void printValAggregates (symbol *sym, link *type,
 /*-----------------------------------------------------------------*/
 /* printOrSetSymValue - print or set value of a symbol             */
 /*-----------------------------------------------------------------*/
-static void printOrSetSymValue (symbol *sym, context *cctxt, 
-                           int flg, int dnum, int fmt, char *rs, char *val)
+static int printOrSetSymValue (symbol *sym, context *cctxt, 
+                                int flg, int dnum, int fmt, char *rs, 
+                                char *val, char cmp )
 {
     static char fmtChar[] = " todx ";
     static int stack = 1;
@@ -2559,7 +2614,7 @@ static void printOrSetSymValue (symbol *sym, context *cctxt,
         if (!bp) 
         {
             fprintf(stdout,"cannot determine stack frame\n");
-            return ;
+            return 1;
         }
 
         sym->addr = simGetValue(bp->addr,bp->addrspace,bp->size)
@@ -2607,14 +2662,14 @@ static void printOrSetSymValue (symbol *sym, context *cctxt,
                 *s2 = save_ch2;
                 if ( ! fields )
                 {
-                    fprintf(stdout,"Unkown variable \"%s\" for index.\n", s);
-                    return;                    
+                    fprintf(stdout,"Unknown variable \"%s\" for index.\n", s);
+                    return 1;                    
                 }
                 /* arrays & structures first */
                 if (! IS_INTEGRAL(fields->type))
                 {
                     fprintf(stdout,"Wrong type of variable \"%s\" for index \n", s);
-                    return;                    
+                    return 1;                    
                 }
                 n = simGetValue(fields->addr,fields->addrspace,getSize(fields->type));
             }
@@ -2625,7 +2680,7 @@ static void printOrSetSymValue (symbol *sym, context *cctxt,
             if ( n < 0 || n >= DCL_ELEM(type))
             {
                 fprintf(stdout,"Wrong index %d.\n", n);
-                return;                    
+                return 1;                    
             }
             type = type->next;
             size = getSize(type);
@@ -2649,7 +2704,7 @@ static void printOrSetSymValue (symbol *sym, context *cctxt,
             if ( ! fields )
             {
                 fprintf(stdout,"Unknown field \"%s\" of structure\n", s);
-                return;                    
+                return 1;                    
             }
             type = fields->type;
             size = getSize(type);
@@ -2663,7 +2718,10 @@ static void printOrSetSymValue (symbol *sym, context *cctxt,
     if (IS_AGGREGATE(type))
     {
            if ( val )
-            fprintf(stdout,"Cannot set aggregate variable\n");
+        {
+            fprintf(stdout,"Cannot set/compare aggregate variable\n");
+            return 1;
+        }
         else
             printValAggregates(sym,type,sym->addrspace,addr,fmt);
     }
@@ -2673,16 +2731,48 @@ static void printOrSetSymValue (symbol *sym, context *cctxt,
     {
            if ( !val )
             printValFunc(sym,fmt);
+        else
+            return 1;
     }
        else
     { 
            if ( val )
-            setValBasic  (sym,type,sym->addrspace,addr,size,val);
+        {
+            unsigned long newval;
+            newval = getValBasic(sym,type,val);
+
+            if ( cmp )
+            {
+                unsigned long lval;
+                lval = simGetValue(addr,sym->addrspace,size);
+                switch ( cmp )
+                {
+                    case '<' : return ( lval <  newval ? 1:0 ); break;
+                    case '>' : return ( lval >  newval ? 1:0 ); break;
+                    case 'l' : return ( lval <= newval ? 1:0 ); break;
+                    case 'g' : return ( lval >= newval ? 1:0 ); break;
+                    case '=' : return ( lval == newval ? 1:0 ); break;
+                    case '!' : return ( lval != newval ? 1:0 ); break;
+                }
+            }
+            else
+            {
+                if ( sym->addrspace == 'I' && addr == 0xb8 )
+                {
+                    /* Symbol with address of IP */
+                    if ( cctxt ) cctxt->addr = newval;
+                    simSetPC(cctxt->addr); 
+                }
+                else
+                    simSetValue(addr,sym->addrspace,size,newval);      
+                return 1;
+            }
+        }
         else
             printValBasic(sym,type,sym->addrspace,addr,size,fmt);
     }
     if ( flg > 0 ) fprintf(stdout,"\n");
-       
+       return 0;
 }
 
 /*-----------------------------------------------------------------*/
@@ -2785,6 +2875,42 @@ static void printTypeInfo(link *p)
     }
 }
 
+/*-----------------------------------------------------------------*/
+/* conditionIsTrue - compare variable with constant value        */
+/*-----------------------------------------------------------------*/
+int conditionIsTrue( char *s, context *cctxt)
+{   
+    symbol *sym = NULL;
+    int fmt;
+    char *rs, *dup, cmp_char;
+    dup = s = Safe_strdup(s);
+    if ( !( rs = preparePrint(s, cctxt, &fmt, &sym )) || !sym)
+        fmt = 1;
+    else if (!( s =  strpbrk(rs,"<>=!")))
+        fmt = 1;
+    else
+    {
+        cmp_char = *s;    
+        *s++ = '\0';
+        if ( *s == '=' )
+        {
+            /* if <= or >= an other char is used 
+             * == or !=  not checked in switch 
+             */
+            switch( cmp_char )
+            {
+                case '>': cmp_char = 'g' ; break;
+                case '<': cmp_char = 'l' ; break;
+            }
+            s++ ;
+        }
+        while (isspace(*s)) *s++ = '\0';
+        fmt = printOrSetSymValue(sym,cctxt,0,0,0,rs,s,cmp_char);
+    }
+    Safe_free(dup);
+    return fmt;
+}
+
 /*-----------------------------------------------------------------*/
 /* cmdPrint - print value of variable                              */
 /*-----------------------------------------------------------------*/
@@ -2798,7 +2924,7 @@ int cmdPrint (char *s, context *cctxt)
 
     if ( sym ) 
     {
-        printOrSetSymValue(sym,cctxt,1,0,fmt,rs,NULL);
+        printOrSetSymValue(sym,cctxt,1,0,fmt,rs,NULL,'\0');
     } 
     return 0;
 }
@@ -2816,7 +2942,7 @@ int cmdOutput (char *s, context *cctxt)
 
     if ( sym ) 
     {
-        printOrSetSymValue(sym,cctxt,0,0,fmt,rs,NULL);
+        printOrSetSymValue(sym,cctxt,0,0,fmt,rs,NULL,'\0');
     } 
     return 0;
 }
@@ -2851,7 +2977,8 @@ void displayAll(context *cctxt)
          dsym = setNextItem(dispsymbols)) 
     {
         if ( (sym = symLookup(dsym->name,cctxt)))
-            printOrSetSymValue(sym,cctxt,2,dsym->dnum,dsym->fmt,dsym->rs,NULL);
+            printOrSetSymValue(sym,cctxt,2,dsym->dnum,dsym->fmt,
+                               dsym->rs,NULL,'\0');
     }
 }