From 288b9ad179d5164fa969df89ce7bfcc9946cb17c Mon Sep 17 00:00:00 2001 From: kbongers Date: Mon, 28 Apr 2003 17:54:02 +0000 Subject: [PATCH] Martins ddd changes git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@2572 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- debugger/README | 257 ++++++++++++++ debugger/mcs51/cmd.c | 764 ++++++++++++++++++++++++++++------------ debugger/mcs51/cmd.h | 2 + debugger/mcs51/sdcdb.c | 63 +++- debugger/mcs51/sdcdb.h | 22 ++ debugger/mcs51/simi.c | 345 +++++++++++------- debugger/mcs51/simi.h | 17 + debugger/mcs51/symtab.c | 3 +- debugger/mcs51/symtab.h | 1 - 9 files changed, 1125 insertions(+), 349 deletions(-) diff --git a/debugger/README b/debugger/README index 86b02612..c86d642b 100644 --- a/debugger/README +++ b/debugger/README @@ -4,6 +4,263 @@ SDCDB debugger - Development notes. ====================== +ddd - Notes from Martin Helmling, April 28, 2003 +======================== + +To fullfill the requirements of 'ddd' ( Data Display Debugger ) to use it at +graphical frontend to 'sdcdb' some new commands must be implemented. + +Now you can run the ddd with the commandline + +ddd -debugger 'sdcdb -cpu 8032 ' + +Following commands are additional implemented: + +1. execution: + +stepi - Step one instruction exactly using simulator 'step' command. +nexti - Step one instruction, but proceed through subroutine calls using simulator 'next' command. +break * - Set breakpoint at program address + +log examples: +-> "stepi\n" +<- "Simulator stopped at Address 0x0051\n" + "\032\032x.c:31:1:beg:0x00000051\n" + "(sdcdb) " +-> "nexti\n" +<- "Simulator stopped at Address 0x0055\n" + "\032\032x.c:33:1:beg:0x00000055\n" + "(sdcdb) " + +2. show machine code window: + +x /i - disassemble one asm command +x disassemble asm commands + +log examples: +-> "x /i 0x00000055\n" +<- "0x00000055 :\t\tmov\tr0,#_l\n" + "(sdcdb) " +-> "disassemble 0x00000055\n" +<- "Dump of assembler code for function main:\n" + "0x0000004f
:\t\tmov\tr0,#_ttt\n" + "0x00000051 :\t\tmov\t@r0,#0x01\n" +<- "0x00000053 :\t\tmov\tr2,#0x09\n" + "0x00000055 :\t\tmov\tr0,#_l\n" +... + "0x000000c1 :\t\tret\n" + "End of assembler dump.\n" + "(sdcdb) " +-> "disassemble 0x40 0x45\n" +<- "Dump of assembler code from 0x00000040 to 0x00000045:\n" + "0x00000040 :\t\tinc\tr0\n" + "0x00000041 :\t\tmov\t@r0,ar3\n" + "0x00000043 :\t\tmov\ta,r3\n" + "0x00000044 :\t\trlc\ta\n" + "0x00000045 :\t\tsubb\ta,acc\n" + "End of assembler dump.\n" + "(sdcdb) " +-> "break x.c:23\n" +<- "Breakpoint 1 at 0x4b: file x.c, line 23.\n" + "(sdcdb) " +-> "info breakpoints\n" +<- "Num Type Disp Enb Address What\n" + "1 breakpoint keep y 0x0000004b at x.c:23\n" + "(sdcdb) " +-> + +3. show registers and stack + +frame - print information about the current Stack +where - print stack +up - Select and print stack frame that called this one +down - Select and print stack frame that called this one +info registers - show registers +info all-registers - show also special these function registers, + which are symbolical defined. +help show short help for ddd tooltip info +log examples: + +-> "where\n" +<- "#0 0x0000004b in subfunc1 () at x.c:23\n" + "#1 0x0000004f in main () at x.c:31\n" + "(sdcdb) " +-> "frame\n" +<- "#0 0x0000004b in subfunc1 () at x.c:23\n" + "\032\032x.c:23:1:beg:0x0000004b\n" + "(sdcdb) " +-> "up\n" +<- "#1 0x0000004f in main () at x.c:31\n" + "\032\032x.c:31:1:beg:0x0000004f\n" + "(sdcdb) " +-> "frame\n" +<- "#1 0x0000004f in main () at x.c:31\n" + "\032\032x.c:31:1:beg:0x0000004f\n" + "(sdcdb) " +-> "down\n" +<- "#0 0x0000004b in subfunc1 () at x.c:23\n" + "\032\032x.c:23:1:beg:0x0000004b\n" + "(sdcdb) " +-> "frame\n" +<- "#0 0x0000004b in subfunc1 () at x.c:23\n" + "\032\032x.c:23:1:beg:0x0000004b\n" + "(sdcdb) " +-> "info registers\n" +<- "R0 : 0x87 135 .\n" + "R1 : 0x00 0 .\n" + "R2 : 0x05 5 .\n" + "R3 : 0x00 0 .\n" + "R4 : 0x00 0 .\n" + "R5 : 0x08 8 .\n" + "R6 : 0x00 0 .\n" + "ACC : 0x00 0 .\n" + "B : 0x00 0 .\n" + "DPTR: 0x0005 5\n" + "@DPTR: 0x00 0 .\n" + "PSW : 0x00 | CY : 0 | AC : 0 | OV : 0 | P : 0\n" + "(sdcdb) " +# Showing all registers. +-> "info all-registers\n" +<- "R0 : 0x87 135 .\n" + "R1 : 0x00 0 .\n" + "R2 : 0x05 5 .\n" + "R3 : 0x00 0 .\n" + "R4 : 0x00 0 .\n" + "R5 : 0x08 8 .\n" + "R6 : 0x00 0 .\n" + "ACC : 0x00 0 .\n" + "B : 0x00 0 .\n" + "DPTR: 0x0005 5\n" + "@DPTR: 0x00 0 .\n" + "PSW : 0x00 | CY : 0 | AC : 0 | OV : 0 | P : 0\n" + "Special Function Registers:\n" +<- "P0=0xff P0_0=1 P0_1=1 P0_2=1 P0_3=1\n" + "SP=0x13\n" + "(sdcdb) " +-> "help step\n" +<- "Step program until it reaches a different source line.\n" + "(sdcdb) " +-> "help stepi\n" +<- "Step one instruction exactly.\n" + "(sdcdb) " + +4. show and set variables: +output [/] print value of without newline for tooltip of ddd +print [/] print value of with newline +display [/] print value of every time the program is stopped + or 'display' command without args is used. + +set variable = + + + is the format for the basic type which is print out. +If no format is set the default format is used. +format is set by ddd 'x' as hex 'o' as octal, 'd' as dezimal and 't' as binary. + + can by a variable , a array element , a structure element ( [] and . is parsed ). +indices of arrays may be constants or variables. +( dereference of pointers and casting today not implemented !! ) + +log examples: +code: + +typedef unsigned char uchar; +idata long l; +typedef struct _txstate +{ + uchar dstatus[4]; + uchar avalue [8 ]; +} txstate_t; + +xdata txstate_t txstates[8]; + +-> "output l\n" +<- "5(sdcdb) " +-> "display l\n" +<- "(sdcdb) " +-> "display /x l\n" +<- "(sdcdb) " +-> "display\n" +<- "2: /x l = 0x00000005\n" + "1: l = 5\n" + "(sdcdb) " +-> "display /o l\n" +<- "(sdcdb) " +-> "display\n" +<- "3: /o l = 00000000005\n" + "2: /x l = 0x00000005\n" + "1: l = 5\n" + "(sdcdb) " +-> "display /d l\n" +<- "(sdcdb) " +-> "display\n" +<- "4: /d l = 5\n" + "3: /o l = 00000000005\n" + "2: /x l = 0x00000005\n" + "1: l = 5\n" + "(sdcdb) " +-> "display /t l\n" +<- "(sdcdb) " +-> "display\n" +<- "5: /t l = 00000000000000000000000000000101\n" + "4: /d l = 5\n" + "3: /o l = 00000000005\n" + "2: /x l = 0x00000005\n" + "1: l = 5\n" + "(sdcdb) " +-> "output l\n" +<- "5(sdcdb) " +-> "print txstates\n" +<- "$2 = { { dstatus = {\'\\1\',\'\\0\',\'\\0\',\'\\0\'}, + avalue = {\'\\0\',\'\\0\',\'\\0\',\'\\0\',\'\\0\',\'\\0\',\'\\0\',\'\\0\'}}, + { dstatus = {\'\\0\',\'\\2\',\'\\0\',\'\\0\'}, + avalue = {\'\\0\',\'\\0\',\'\\0\',\'\\0\',\'\\0\',\'\\0\',\'\\0\',\'\\0\'}}, + { dstatus = {\'\\0\',\'\\0\',\'\\375\',\'\\0\'}, + avalue = {\'\\0\',\'\\0\',\'\\0\',\'\\0\',\'\\0\',\'\\0\',\'\\0\',\'\\0\'}}, + { dstatus = {\'\\0\',\'\\0\',\'\\0\',\'\\0\'}, + avalue = {\'\\0\',\'\\0\',\'\\0\',\'\\4\',\'\\0\',\'\\0\',\'\\0\',\ +'\\0\'}}, { dstatus = {\'\\0\',\'\\0\',\'\\0\',\'\\0\'}, + avalue = {\'\\0\',\'\\0\',\'\\0\',\'\\0\',\'\\0\',\'\\0\',\'\\0\',\'\\0\'}}, + { dstatus = {\'\\0\',\'\\0\',\'\\0\',\'\\0\'}, + avalue = {\'\\0\',\'\\0\',\'\\0\',\'\\0\',\'\\0\',\'\\0\',\'\\0\',\'\\0\'}}, + { dstatus = {\'\\0\',\'\\0\',\'\\0\',\'\\0\'}, + avalue = {\'\\0\',\'\\0\',\'\\0\',\'\\0\',\'\\0\',\'\\0\',\'\\0\',\'\\0\'}}, + { dstatus = {\'\\0\',\'\\0\',\'\\0\',\'\\0\'}, + avalue = {\'\\0\',\'\\0\',\'\\0\',\'\\0\',\'\\0\',\'\\0\',\'\\0\',\'\\ +0\'}}}\n" + "(sdcdb) " +-> "print txstates[1].dstatus[1]\n" +<- "$5 = \'\\2\'\n" + "(sdcdb) " +-> "print /x txstates[1].dstatus[1]\n" +<- "$7 = 0x02\n" +-> "output txstates[1].dstatus[1]\n" +<- "\'\\2\'(sdcdb) " +-> "set variable txstates[1].dstatus[1] = 0x10\n" +<- "(sdcdb) " +-> "print /t txstates[1].dstatus[1]\n" +<- "$9 = 00010000\n" +-> "print /x txstates[1].dstatus[1]\n" +<- "$10 = 0x10\n" + +-> "output l\n" +<- "5(sdcdb) " +-> "set variable l = 2\n" +<- "(sdcdb) " +-> "print l\n" +<- "$15 = 2\n" +-> "print /x txstates[l].dstatus[2]\n" +<- "$16 = 0xfd\n" + + +--------------------------------------------------- + +Implementation Notes: + +IMEM and XMEM are cached to optimize the printaut of structures and arrays + + + Notes April 23, 2003 ======================== Martin Helmling added support for ddd GUI debugger. diff --git a/debugger/mcs51/cmd.c b/debugger/mcs51/cmd.c index da4a2e45..ded949d7 100644 --- a/debugger/mcs51/cmd.c +++ b/debugger/mcs51/cmd.c @@ -328,12 +328,13 @@ static char *warranty= #endif static void printTypeInfo(link *); -static void printValAggregates (symbol *,link *,char,unsigned int); -static void setSymValue(symbol *sym, char *val, context *cctxt); +static void printValAggregates (symbol *,link *,char,unsigned int,int); +static void printOrSetSymValue (symbol *sym, context *cctxt, + int flg, int dnum, int fmt, char *rs, char *val); int srcMode = SRC_CMODE ; static set *dispsymbols = NULL ; /* set of displayable symbols */ - +static int currentFrame = 0; /* actual displayed frame */ /*-----------------------------------------------------------------*/ /* funcWithName - returns function with name */ /*-----------------------------------------------------------------*/ @@ -354,6 +355,29 @@ DEFSETFUNC(funcWithName) return 0; } +/*-----------------------------------------------------------------*/ +/* symWithAddr - look for symbol with sfr / sbit address */ +/*-----------------------------------------------------------------*/ +DEFSETFUNC(symWithAddr) +{ + symbol *sym = item; + V_ARG(unsigned long,laddr); + V_ARG(int ,laddrspace); + V_ARG(symbol **,rsym); + + if (*rsym) + return 0; + + if ( sym->addr == laddr && + sym->addrspace == laddrspace ) + { + *rsym = sym; + return 1; + } + + return 0; +} + /*-----------------------------------------------------------------*/ /* setBPatModLine - set break point at the line specified for the */ /*-----------------------------------------------------------------*/ @@ -618,6 +642,8 @@ context *discoverContext (unsigned addr) module *mod = NULL; int line = 0; + currentFrame = 0; + /* find the function we are in */ if (!applyToSet(functions,funcInAddr,addr,&func)) { if (!applyToSet(functions,funcWithName,"main") || @@ -723,6 +749,61 @@ void simGo (unsigned int gaddr) } +/*-----------------------------------------------------------------*/ +/* preparePrint - common parse function for */ +/* output, print and display */ +/*-----------------------------------------------------------------*/ +static char *preparePrint(char *s, context *cctxt, int *fmt, symbol **sym) +{ + char *bp = s+strlen(s) -1; + char save_ch ; + + *fmt = FMT_NON; + *sym = NULL; + + while (isspace(*s)) s++; + if (!*s) + return (char *)0; + + while (isspace(*bp)) bp--; + bp++ ; + *bp = '\0'; + + if ( *s == '/' ) + { + /* format of printout */ + switch ( *++s ) + { + case 'x': + *fmt = FMT_HEX ; + break; + case 'o': + *fmt = FMT_OCT ; + break; + default: + case 'd': + *fmt = FMT_DEZ ; + break; + case 't': + *fmt = FMT_BIN ; + break; + } + s++; + while (isspace(*s)) s++; + } + for ( bp = s; *bp && ( isalnum( *bp ) || *bp == '_'); bp++ ); + save_ch = *bp; + if ( *bp ) + *bp = '\0'; + + *sym = symLookup(s,cctxt); + *bp = save_ch; + + if ( ! *sym ) + fprintf(stdout,"No symbol \"%s\" in current context.\n", s); + return bp; +} + static int printAsmLine( function *func, module *m, long saddr, long eaddr) { int i,j,delta; @@ -1071,23 +1152,19 @@ int cmdSetOption (char *s, context *cctxt) if (strncmp(s,"variable ",9) == 0) { symbol *sym ; - char *val; + int fmt; + char *rs; s += 9; - while (isspace(*s)) s++; - if (!*s) return 0; - - val = s; - while (*val && !isspace(*val) && *val != '=') val++; - while (isspace(*val)) *val++ = '\0'; - if (*val) *val++ = '\0'; - if (*val) + if ( !( rs = preparePrint(s, cctxt, &fmt, &sym ))) + return 0; + s = rs; + while (*s && *s != '=') s++; + *s++ = '\0'; + while (isspace(*s)) *s++ = '\0'; + if (*s) { - if ((sym = symLookup(s,cctxt))) - { - setSymValue(sym,val,cctxt); + printOrSetSymValue(sym,cctxt,0,0,0,rs,s); return 0; - } - fprintf(stdout,"No symbol \"%s\" in current context.\n",s); } else fprintf(stdout,"No new value for \"%s\".\n",s); @@ -1142,6 +1219,22 @@ int cmdDelUserBp (char *s, context *cctxt) return 0; } +/*-----------------------------------------------------------------*/ +/* cmdStepi - single step exactly one instruction */ +/*-----------------------------------------------------------------*/ +int cmdStepi (char *s, context *cctxt) +{ + + if (!cctxt || !cctxt->func || !cctxt->func->mod) + fprintf(stdout,"The program is not being run.\n"); + else + { + simGo(2); + showfull = 1; + } + return 0; +} + /*-----------------------------------------------------------------*/ /* cmdStep - single step thru C source file */ /*-----------------------------------------------------------------*/ @@ -1152,9 +1245,6 @@ int cmdStep (char *s, context *cctxt) if (!cctxt || !cctxt->func || !cctxt->func->mod) fprintf(stdout,"The program is not being run.\n"); else { - int origSrcMode = srcMode; - if ( *s == 'i' ) - srcMode = SRC_AMODE; /* if we are @ the end of a function then set break points at execution points of the function in the call stack... */ @@ -1220,13 +1310,27 @@ int cmdStep (char *s, context *cctxt) } } - srcMode = origSrcMode; simGo(-1); showfull = 1; } return 0; } +/*-----------------------------------------------------------------*/ +/* cmdNexti - next instruction but proceed function call */ +/*-----------------------------------------------------------------*/ +int cmdNexti (char *s, context *cctxt) +{ + if (!cctxt || !cctxt->func || !cctxt->func->mod) + fprintf(stdout,"The program is not being run.\n"); + else + { + simGo(1); + showfull = 1; + } + return 0; +} + /*-----------------------------------------------------------------*/ /* cmdNext - next executable C statement file */ /*-----------------------------------------------------------------*/ @@ -1239,10 +1343,6 @@ int cmdNext (char *s, context *cctxt) if (!cctxt || !cctxt->func || !cctxt->func->mod) fprintf(stdout,"The program is not being run.\n"); else { - int origSrcMode = srcMode; - if ( *s == 'i' ) - srcMode = SRC_AMODE; - /* if we are @ the end of a function then set break points at execution points of the function in the call stack... */ @@ -1295,11 +1395,9 @@ int cmdNext (char *s, context *cctxt) func->aexitline); } } - srcMode = origSrcMode; simGo(-1); showfull = 1; } - srcMode = origSrcMode; } return 0; } @@ -1612,7 +1710,7 @@ static void infoStack(context *ctxt) STACK_STARTWALK(callStack) ; while ((func = STACK_WALK(callStack))) { - fprintf(stdout,"#%d 0x%04x %s () at %s:%d\n",i++, + fprintf(stdout,"#%d 0x%08x in %s () at %s:%d\n",i++, func->laddr,func->sym->name, func->mod->c_name,func->lline); } @@ -1625,25 +1723,9 @@ static void infoStack(context *ctxt) int cmdWhere(char *s, context *cctxt) { infoStack(cctxt); - showfull = 1; return 0; } -/*-----------------------------------------------------------------*/ -/* cmdUp - Up command */ -/*-----------------------------------------------------------------*/ -int cmdUp(char *s, context *cctxt) -{ - return 0; -} - -/*-----------------------------------------------------------------*/ -/* cmdDown - down command */ -/*-----------------------------------------------------------------*/ -int cmdDown(char *s, context *cctxt) -{ - return 0; -} static int infomode = 0; /*-----------------------------------------------------------------*/ @@ -1662,7 +1744,6 @@ int cmdInfo (char *s, context *cctxt) /* info frame same as frame */ if (strcmp(s,"frame") == 0) { cmdFrame (s,cctxt); - showfull = 1; return 0; } @@ -1686,13 +1767,36 @@ int cmdInfo (char *s, context *cctxt) } /* info stack display call stack */ - if (strcmp(s,"all-registers") == 0) { - fprintf(stdout,"%s",simRegs()); - fprintf(stdout,"Special Function Registers:\n"); - sendSim("ds 0x80 0x100\n"); - waitForSim(100,NULL); - fprintf(stdout,simResponse()); - return 0; + if (strcmp(s,"all-registers") == 0) + { + int i,j; + fprintf(stdout,"%s",simRegs()); + fprintf(stdout,"Special Function Registers:\n"); + for ( i = 0 ; i < 0x100 ; i++ ) + { + symbol *sym = NULL; + unsigned long val; + if (applyToSetFTrue(sfrsymbols,symWithAddr,i,'I',&sym)) + { + val = simGetValue (sym->addr,sym->addrspace,sym->size); + fprintf(stdout,"%s=0x%02x",sym->name,val); + if ( !(i & 0x07 )) + { + for ( j = 0 ; j < 8 ; j++ ) + { + sym = NULL; + if (applyToSetFTrue(sfrsymbols,symWithAddr,i+j,'J',&sym)) + { + //val = simGetValue (sym->addr,sym->addrspace,sym->size); + fprintf(stdout," %s=%c",sym->name,(val&1)? '1':'0'); + } + val >>= 1; + } + } + fprintf(stdout,"\n"); + } + } + return 0; } /* info stack display call stack */ @@ -1863,63 +1967,154 @@ int cmdListSrc (char *s, context *cctxt) return 0; } -static void setValBasic(symbol *sym, char *val) +static void setValBasic(symbol *sym, link *type, + char mem, unsigned addr,int size, char *val) { + char *s; union { float f; unsigned long val; long sval; struct { - short lo; - short hi; + unsigned short lo; + unsigned short hi; } i; unsigned char b[4]; }v; - if (IS_FLOAT(sym->type)) + if (IS_FLOAT(type)) v.f = strtof(val,NULL); else - if (IS_PTR(sym->type)) - v.sval = strtol(val,NULL,0); + if (IS_PTR(type)) + v.val = strtol(val,NULL,0); else { - if (IS_SPEC(sym->type) && IS_INTEGRAL(sym->type)) + if (IS_INTEGRAL(type)) { - if (IS_CHAR(sym->etype)) - { - v.b[0] = val[0]; + link *etype; + if ( type->next ) + etype = type->next; + else + etype = type; + if (IS_CHAR(etype)) + { + if (( s = strchr(val,'\''))) + { + if ( s[1] == '\\' ) + v.b[0] = strtol(s+2,NULL,8); + else + v.b[0] = s[1]; + } + else + { + v.b[0] = strtol(val,NULL,0); + } } else - if (IS_INT(sym->etype)) - if (IS_LONG(sym->etype)) - if (SPEC_USIGN(sym->etype)) - v.val = strtol(val,NULL,0); - else - v.sval = strtol(val,NULL,0); + if (IS_INT(etype)) + if (IS_LONG(etype)) + v.val = strtol(val,NULL,0); else v.i.lo = strtol(val,NULL,0); else - v.sval = strtol(val,NULL,0); + v.val = strtol(val,NULL,0); } else - v.sval = strtol(val,NULL,0); + v.val = strtol(val,NULL,0); } - simSetValue(sym->addr,sym->addrspace,sym->size,v.sval); + simSetValue(addr,mem,size,v.val); +} + +/*-----------------------------------------------------------------*/ +/* printFmtInteger - print value in bin,oct,dez or hex */ +/*-----------------------------------------------------------------*/ +static void printFmtInteger(char *deffmt,int fmt, long val, + int sign, int size) +{ + static char digits[] = + { + '0' , '1' , '2' , '3' , '4' , '5' , + '6' , '7' , '8' , '9' , 'a' , 'b' , + 'c' , 'd' , 'e' , 'f' , 'g' , 'h' + }; + static int radixOfFormat[] = { 0 , 2, 8 ,10, 16 }; + static int olenOfSize[] = { 0 , 3, 6 , 8, 11 }; + char buf[40]; + char negative = 0; + int charPos = 38; + int radix; + + if ( fmt == FMT_NON || fmt == FMT_DEZ ) + { + fprintf(stdout,deffmt,val); + return; + } + radix = radixOfFormat[fmt]; + + /* + if ( sign && val < 0 ) + negative = 1; + */ + + if (!negative) + val = -val; + + buf[39] = '\0'; + while (val <= -radix) + { + buf[charPos--] = digits[-(val % radix)]; + val = val / radix; + } + buf[charPos] = digits[-val]; + + switch ( fmt ) + { + case FMT_OCT: + radix = olenOfSize[size]; + break; + case FMT_HEX: + radix = size << 1; + break; + case FMT_BIN: + radix = size << 3; + break; + } + + while (charPos > 39 - radix ) + { + buf[--charPos] = '0'; + } + switch ( fmt ) + { + case FMT_OCT: + if ( buf[charPos] != '0' ) + buf[--charPos] = '0'; + break; + case FMT_HEX: + buf[--charPos] = 'x'; + buf[--charPos] = '0'; + break; + } + if (negative) { + buf[--charPos] = '-'; + } + fputs(&buf[charPos],stdout); } /*-----------------------------------------------------------------*/ /* printValBasic - print value of basic types */ /*-----------------------------------------------------------------*/ -static void printValBasic(symbol *sym,unsigned addr,char mem, int size) +static void printValBasic(symbol *sym, link *type, + char mem, unsigned addr,int size, int fmt) { union { float f; unsigned long val; long sval; struct { - short lo; - short hi; + unsigned short lo; + unsigned short hi; } i; unsigned char b[4]; }v; @@ -1929,41 +2124,55 @@ static void printValBasic(symbol *sym,unsigned addr,char mem, int size) v.val = simGetValue(addr,mem,size); /* if this a floating point number then */ - if (IS_FLOAT(sym->type)) + if (IS_FLOAT(type)) fprintf(stdout,"%f",v.f); else - if (IS_PTR(sym->type)) - fprintf(stdout,"0x%x",v.val); + if (IS_PTR(type)) + fprintf(stdout,"0x%*x",size<<1,v.val); else - if (IS_SPEC(sym->type) && IS_INTEGRAL(sym->type)) { - if (IS_CHAR(sym->etype)) - { - if ( isprint(v.val)) - fprintf(stdout,"%d 0x%x '%c'",v.val,v.val,v.val); + if (IS_INTEGRAL(type)) + { + link *etype; + if ( type->next ) + etype = type->next; else - fprintf(stdout,"%d 0x%x '\\%o'",v.val,v.val,v.val); - } - else - if (IS_INT(sym->etype)) - if (IS_LONG(sym->etype)) - if (SPEC_USIGN(sym->etype)) - fprintf(stdout,"%d 0x%x",v.val,v.val); - else - fprintf(stdout,"%d 0x%x",v.sval,v.sval); - else - fprintf(stdout,"%d 0x%x",v.i.lo,v.i.lo); - else - fprintf(stdout,"0x%x",v.val); + etype = type; + if (IS_CHAR(etype)) + { + if ( isprint(v.val)) + printFmtInteger("'%c'",fmt,(long)v.val,0,size); + else + printFmtInteger("'\\%o'",fmt,(long)v.val,0,size); + } + else + { + if (IS_INT(etype)) + if (IS_LONG(etype)) + if (SPEC_USIGN(etype)) + printFmtInteger("%u",fmt,(long)v.val,0,size); + else + printFmtInteger("%d",fmt,(long)v.sval,1,size); + else + if (SPEC_USIGN(etype)) + printFmtInteger("%u",fmt,(long)v.i.lo,0,size); + else + printFmtInteger("%d",fmt,(long)v.i.lo,1,size); + else + { + if (IS_BITVAR(etype)) + fprintf(stdout,"%c",(v.val?'1':'0')); + else + fprintf(stdout,"0x%0*x",size<<1,v.val); + } + } } else - fprintf(stdout,"0x%x",v.val); - - + fprintf(stdout,"0x%0*x",size<<1,v.val); } /*-----------------------------------------------------------------*/ /* printValFunc - prints function values */ /*-----------------------------------------------------------------*/ -static void printValFunc (symbol *sym) +static void printValFunc (symbol *sym, int fmt) { fprintf(stdout,"print function not yet implemented"); } @@ -1971,20 +2180,21 @@ static void printValFunc (symbol *sym) /*-----------------------------------------------------------------*/ /* printArrayValue - will print the values of array elements */ /*-----------------------------------------------------------------*/ -static void printArrayValue (symbol *sym, char space, unsigned int addr) +static void printArrayValue (symbol *sym, link *type, + char space, unsigned int addr, int fmt) { - link *elem_type = sym->type->next; + link *elem_type = type->next; int i; - fprintf(stdout," { "); - for (i = 0 ; i < DCL_ELEM(sym->type) ; i++) { + fprintf(stdout,"{"); + for (i = 0 ; i < DCL_ELEM(type) ; i++) { if (IS_AGGREGATE(elem_type)) { - printValAggregates(sym,elem_type,space,addr); + printValAggregates(sym,elem_type,space,addr,fmt); } else { - printValBasic(sym,addr,space,getSize(elem_type)); + printValBasic(sym,elem_type,space,addr,getSize(elem_type),fmt); } addr += getSize(elem_type); - if (i != DCL_ELEM(sym->type) -1) + if (i != DCL_ELEM(type) -1) fprintf(stdout,","); } @@ -1994,17 +2204,19 @@ static void printArrayValue (symbol *sym, char space, unsigned int addr) /*-----------------------------------------------------------------*/ /* printStructValue - prints structures elements */ /*-----------------------------------------------------------------*/ -static void printStructValue (symbol *sym,link *type, char space, unsigned int addr) +static void printStructValue (symbol *sym, link *type, + char space, unsigned int addr, int fmt) { symbol *fields = SPEC_STRUCT(type)->fields; - + int first = 1; fprintf(stdout," { "); while (fields) { - fprintf(stdout,"%s = ",fields->name); - if (IS_AGGREGATE(fields->type)) { - printValAggregates(fields,fields->type,space, addr); + fprintf(stdout,"%s%s = ",(first ? "": ", "),fields->name); + first = 0; + if (IS_AGGREGATE(fields->type)) { + printValAggregates(fields,fields->type,space, addr, fmt); } else { - printValBasic(fields,addr,space,getSize(fields->type)); + printValBasic(fields,fields->type,space,addr,getSize(fields->type), fmt); } addr += getSize(fields->type); fields = fields->next; @@ -2015,25 +2227,37 @@ static void printStructValue (symbol *sym,link *type, char space, unsigned int a /*-----------------------------------------------------------------*/ /* printValAggregates - print value of aggregates */ /*-----------------------------------------------------------------*/ -static void printValAggregates (symbol *sym, link *type,char space,unsigned int addr) +static void printValAggregates (symbol *sym, link *type, + char space,unsigned int addr, int fmt) { if (IS_ARRAY(type)) { - printArrayValue(sym, space, addr); + printArrayValue(sym, type, space, addr, fmt); return ; } if (IS_STRUCT(type)) { - printStructValue(sym,sym->type,space, addr); + printStructValue(sym, type, space, addr, fmt); return; } } /*-----------------------------------------------------------------*/ -/* setSymValue - set value of a symbol */ +/* printOrSetSymValue - print or set value of a symbol */ /*-----------------------------------------------------------------*/ -static void setSymValue(symbol *sym, char *val, context *cctxt) +static void printOrSetSymValue (symbol *sym, context *cctxt, + int flg, int dnum, int fmt, char *rs, char *val) { + static char fmtChar[] = " todx "; + static int stack = 1; + symbol *fields; + link *type; + unsigned int addr; + int size, n; + char *s, *s2; + char save_ch, save_ch2; + + /* if it is on stack then compute address & fall thru */ if (sym->isonstack) { symbol *bp = symLookup("bp",cctxt); @@ -2046,39 +2270,6 @@ static void setSymValue(symbol *sym, char *val, context *cctxt) sym->addr = simGetValue(bp->addr,bp->addrspace,bp->size) + sym->offset ; } - /* arrays & structures first */ - if (IS_AGGREGATE(sym->type)) - { - } - else - /* functions */ - if (IS_FUNC(sym->type)) - { - } - else - { - setValBasic(sym,val); - } -} - -/*-----------------------------------------------------------------*/ -/* printSymValue - print value of a symbol */ -/*-----------------------------------------------------------------*/ -static void printSymValue (symbol *sym, context *cctxt, int flg, int dnum) -{ - static int stack = 1; - unsigned long val; - /* if it is on stack then compute address & fall thru */ - if (sym->isonstack) { - symbol *bp = symLookup("bp",cctxt); - if (!bp) { - fprintf(stdout,"cannot determine stack frame\n"); - return ; - } - - sym->addr = simGetValue(bp->addr,bp->addrspace,bp->size) - + sym->offset ; - } /* get the value from the simulator and print it */ @@ -2091,20 +2282,111 @@ static void printSymValue (symbol *sym, context *cctxt, int flg, int dnum) fprintf(stdout,"$%d = ",stack++); break; case 2: - fprintf(stdout,"%d: %s = ",dnum,sym->name); + fprintf(stdout,"%d: ", dnum); + if ( fmt != FMT_NON ) + fprintf(stdout,"/%c ",fmtChar[fmt]); + fprintf(stdout,"%s%s = ",sym->name,rs); break; } + + addr = sym->addr; + type = sym->type; + size = sym->size; + + while ( *rs ) + { + if ( *rs == '[' && IS_ARRAY(type)) + { + s = rs+1; + while ( *rs && *rs != ']' ) rs++ ; + save_ch = *rs; + *rs = '\0' ; + if ( ! isdigit(*s )) + { + /* index seems a variable */ + for ( s2 = s; *s2 && ( isalnum( *s2 ) || *s2 == '_'); s2++ ); + save_ch2 = *s2; + if ( *s2 ) + *s2 = '\0'; + fields = symLookup(s,cctxt); + *s2 = save_ch2; + if ( ! fields ) + { + fprintf(stdout,"Unkown variable \"%s\" for index.\n", s); + return; + } + /* arrays & structures first */ + if (! IS_INTEGRAL(fields->type)) + { + fprintf(stdout,"Wrong type of variable \"%s\" for index \n", s); + return; + } + n = simGetValue(fields->addr,fields->addrspace,getSize(fields->type)); + } + else + { + n = strtol(s,0,0); + } + if ( n < 0 || n >= DCL_ELEM(type)) + { + fprintf(stdout,"Wrong index %d.\n", n); + return; + } + type = type->next; + size = getSize(type); + addr += size * n; + *rs++ = save_ch; + } + else if ( *rs == '.' && IS_STRUCT(type)) + { + s = rs+1; + /* search structure element */ + for ( rs = s; *rs && ( isalnum( *rs ) || *rs == '_'); rs++ ); + save_ch = *rs; + if ( *rs ) + *rs = '\0'; + for (fields = SPEC_STRUCT(type)->fields; fields; fields = fields->next) + { + if (!(strcmp(s,fields->name))) + break; + } + *rs = save_ch; + if ( ! fields ) + { + fprintf(stdout,"Unknown field \"%s\" of structure\n", s); + return; + } + type = fields->type; + size = getSize(type); + addr += fields->offset; + } + else + break; + } + /* arrays & structures first */ - if (IS_AGGREGATE(sym->type)) - printValAggregates(sym,sym->type,sym->addrspace,sym->addr); + if (IS_AGGREGATE(type)) + { + if ( val ) + fprintf(stdout,"Cannot set aggregate variable\n"); + else + printValAggregates(sym,type,sym->addrspace,addr,fmt); + } else /* functions */ - if (IS_FUNC(sym->type)) - printValFunc(sym); - else - printValBasic(sym,sym->addr,sym->addrspace,sym->size); + if (IS_FUNC(type)) + { + if ( !val ) + printValFunc(sym,fmt); + } + else + { + if ( val ) + setValBasic (sym,type,sym->addrspace,addr,size,val); + else + printValBasic(sym,type,sym->addrspace,addr,size,fmt); + } if ( flg > 0 ) fprintf(stdout,"\n"); - //fprintf(stdout,"(BASIC %x,%c,%d)\n",sym->addr,sym->addrspace,sym->size); } @@ -2214,21 +2496,15 @@ static void printTypeInfo(link *p) int cmdPrint (char *s, context *cctxt) { symbol *sym ; - char *bp = s+strlen(s) -1; - - while (isspace(*s)) s++; - if (!*s) return 0; - while (isspace(*bp)) bp--; - bp++ ; - *bp = '\0'; + int fmt; + char *rs; + if ( !( rs = preparePrint(s, cctxt, &fmt, &sym ))) + return 0; - if ((sym = symLookup(s,cctxt))) { - printSymValue(sym,cctxt,1,0); - } else { - fprintf(stdout, - "No symbol \"%s\" in current context.\n", - s); - } + if ( sym ) + { + printOrSetSymValue(sym,cctxt,1,0,fmt,rs,NULL); + } return 0; } @@ -2238,30 +2514,18 @@ int cmdPrint (char *s, context *cctxt) int cmdOutput (char *s, context *cctxt) { symbol *sym ; - char *bp = s+strlen(s) -1; - - while (isspace(*s)) s++; - if (!*s) return 0; - while (isspace(*bp)) bp--; - bp++ ; - *bp = '\0'; + int fmt; + char *rs; + if ( !( rs = preparePrint(s, cctxt, &fmt, &sym ))) + return 0; - if ((sym = symLookup(s,cctxt))) { - printSymValue(sym,cctxt,0,0); - } else { - fprintf(stdout, - "No symbol \"%s\" in current context.", - s); - } + if ( sym ) + { + printOrSetSymValue(sym,cctxt,0,0,fmt,rs,NULL); + } return 0; } -typedef struct _dsymbol -{ - char *name; - int dnum; -} dsymbol; - /** find display entry with this number */ DEFSETFUNC(dsymWithNumber) @@ -2292,7 +2556,7 @@ void displayAll(context *cctxt) dsym = setNextItem(dispsymbols)) { if ( (sym = symLookup(dsym->name,cctxt))) - printSymValue(sym,cctxt,2,dsym->dnum); + printOrSetSymValue(sym,cctxt,2,dsym->dnum,dsym->fmt,dsym->rs,NULL); } } @@ -2301,32 +2565,25 @@ void displayAll(context *cctxt) /*-----------------------------------------------------------------*/ int cmdDisplay (char *s, context *cctxt) { - symbol *sym ; - char *bp = s+strlen(s) -1; static int dnum = 1; - - while (isspace(*s)) s++; - if (!*s) + symbol *sym ; + int fmt; + char *rs; + if ( !( rs = preparePrint(s, cctxt, &fmt, &sym ))) { displayAll(cctxt); return 0; } - while (isspace(*bp)) bp--; - bp++ ; - *bp = '\0'; - if ((sym = symLookup(s,cctxt))) + if ( sym ) { dsymbol *dsym = (dsymbol *)Safe_calloc(1,sizeof(dsymbol)); dsym->dnum = dnum++ ; dsym->name = sym->name; + dsym->fmt = fmt; + dsym->rs = gc_strdup(rs); addSetHead(&dispsymbols,dsym); } - else - { - fprintf(stdout,"No symbol \"%s\" in current context.\n", - s); - } return 0; } @@ -2341,6 +2598,13 @@ int cmdUnDisplay (char *s, context *cctxt) while (isspace(*s)) s++; if (!*s) { + for (dsym = setFirstItem(dispsymbols); + dsym; + dsym = setNextItem(dispsymbols)) + { + Safe_free(dsym->rs); + Safe_free(dsym); + } deleteSet(&dispsymbols); return 0; } @@ -2350,6 +2614,8 @@ int cmdUnDisplay (char *s, context *cctxt) if (applyToSetFTrue(dispsymbols,dsymWithNumber,dnum,&dsym)) { deleteSetItem(&dispsymbols,dsym); + Safe_free(dsym->rs); + Safe_free(dsym); } else { @@ -2509,23 +2775,85 @@ int cmdSimulator (char *s, context *cctxt) return 0; } +static int printFrame(int framenr, int getlast) +{ + int i; + function *func = NULL; + function *lastfunc = NULL; + + STACK_STARTWALK(callStack) ; + if ( framenr < 0 ) + framenr = 0; + for ( i = 0; i <= framenr ; i++ ) + { + lastfunc = func; + func = STACK_WALK(callStack); + if ( !func ) + { + framenr = i-1; + break; + } + } + if (! func && getlast ) + func = lastfunc; + + if ( func ) + { + fprintf(stdout,"#%d 0x%08x in %s () at %s:%d\n", + framenr,func->laddr,func->sym->name,func->mod->c_name,func->lline); + fprintf(stdout,"\032\032%s:%d:1:beg:0x%08x\n", + func->mod->cfullname,func->lline,func->laddr); + } + else + fprintf(stdout,"No stack.\n"); + + return framenr; +} + + +/*-----------------------------------------------------------------*/ +/* cmdUp - Up command */ +/*-----------------------------------------------------------------*/ +int cmdUp(char *s, context *cctxt) +{ + while (isspace(*s)) s++; + if ( *s ) + currentFrame += strtol(s,0,10); + else + currentFrame++ ; + + currentFrame = printFrame(currentFrame, 1 ); + return 0; +} + +/*-----------------------------------------------------------------*/ +/* cmdDown - down command */ +/*-----------------------------------------------------------------*/ +int cmdDown(char *s, context *cctxt) +{ + while (isspace(*s)) s++; + if ( *s ) + currentFrame -= strtol(s,0,10); + else + currentFrame-- ; + + currentFrame = printFrame(currentFrame, 1 ); + return 0; +} /*-----------------------------------------------------------------*/ /* cmdFrame - Frame command */ /*-----------------------------------------------------------------*/ int cmdFrame (char *s, context *cctxt) { - function *func ; - - if ((func = STACK_PEEK(callStack))) { - fprintf(stdout,"#0 %s () at %s:%d\n", - func->sym->name,func->mod->c_name,cctxt->cline); + function *func = NULL; + int i, framenr = 0; - if (cctxt->cline < func->mod->ncLines) - fprintf(stdout,"%d\t%s", - cctxt->cline, - func->mod->cLines[cctxt->cline]->src); - } else - fprintf(stdout,"No stack.\n"); + while (isspace(*s)) s++; + if ( *s ) + framenr = strtol(s,0,10); + else + framenr = currentFrame; + printFrame( framenr, 0 ); return 0; } diff --git a/debugger/mcs51/cmd.h b/debugger/mcs51/cmd.h index b010d54d..632e5fa1 100644 --- a/debugger/mcs51/cmd.h +++ b/debugger/mcs51/cmd.h @@ -45,6 +45,8 @@ extern int cmdInfo (char *, context *); extern int cmdShow (char *, context *); extern int cmdFinish (char *, context *); +extern int cmdStepi (char *, context *); +extern int cmdNexti (char *, context *); extern int cmdUp (char *, context *); extern int cmdDown (char *, context *); extern int cmdWhere (char *, context *); diff --git a/debugger/mcs51/sdcdb.c b/debugger/mcs51/sdcdb.c index 260a744d..cb241699 100644 --- a/debugger/mcs51/sdcdb.c +++ b/debugger/mcs51/sdcdb.c @@ -37,6 +37,7 @@ cdbrecs *recsRoot = NULL ; set *modules = NULL; /* set of all modules */ set *functions = NULL ; /* set of functions */ set *symbols = NULL ; /* set of symbols */ +set *sfrsymbols= NULL ; /* set of symbols of sfr or sbit */ int nStructs = 0 ; structdef **structs = NULL ; /* all structures */ int nLinkrecs = 0; @@ -67,7 +68,7 @@ struct cmdtab precede the synonym "b" */ /* break point */ { "break" , cmdSetUserBp , - "{b}reak\t\t\t [LINE | FILE:LINE | FILE:FUNCTION | FUNCTION]\n", + "{b}reak\t\t\t [LINE | FILE:LINE | FILE:FUNCTION | FUNCTION | *
]\n", }, { "b" , cmdSetUserBp , NULL }, @@ -81,16 +82,22 @@ struct cmdtab }, { "c" , cmdContinue , NULL }, - { "disassemble",cmdDisasmF , "x disassemble asm commands\n" }, + { "disassemble",cmdDisasmF , "disassemble [startaddr [endaddress]]\tdisassemble asm commands\n" }, { "delete" , cmdDelUserBp , "{d}elete n\t\t clears break point number n\n" }, { "display" , cmdDisplay , - "display []\t print value of given variable each time the program stops\n" + "display [/] []\t print value of given variable each time the program stops\n" }, { "undisplay" , cmdUnDisplay , "undisplay []\t dont display this variable or all\n" }, + { "down" , cmdDown , + "down\t\tSelect and print stack frame called by this one.\nAn argument says how many frames down to go.\n" + }, + { "up" , cmdUp , + "up\t\tSelect and print stack frame that called this one.\nAn argument says how many frames up to go.\n" + }, { "d" , cmdDelUserBp , NULL }, { "info" , cmdInfo , @@ -114,20 +121,26 @@ struct cmdtab " \t copying & distribution terms, warranty\n" }, { "set" , cmdSetOption , "set \t\t toggle between c/asm.\nset variable = >value\t\tset variable to new value\n" }, + { "stepi" , cmdStepi , + "stepi\t\t\tStep one instruction exactly.\n" + }, { "step" , cmdStep , - "{s}tep\t\t\t Step program until it reaches a different source line.\n" + "{s}tep\t\t\tStep program until it reaches a different source line.\n" }, { "s" , cmdStep , NULL }, + { "nexti" , cmdNexti , + "nexti\t\t\tStep one instruction, but proceed through subroutine calls.\n" + }, { "next" , cmdNext , - "{n}ext\t\t\t Step program, proceeding through subroutine calls.\n" + "{n}ext\t\t\tStep program, proceeding through subroutine calls.\n" }, { "n" , cmdNext , NULL }, { "run" , cmdRun , - "{r}un\t\t\t Start debugged program. \n" + "{r}un\t\t\tStart debugged program. \n" }, { "r" , cmdRun , NULL }, { "ptype" , cmdPrintType , - "{pt}ype \t print type information of a variable\n" + "{pt}ype \tprint type information of a variable\n" }, { "pt" , cmdPrintType , NULL }, { "print" , cmdPrint , @@ -141,13 +154,13 @@ struct cmdtab "file \t\t load symbolic information from \n" }, { "frame" , cmdFrame , - "{fr}ame\t\t\t print information about the current Stack\n" + "{fr}ame\t\t print information about the current Stack\n" }, { "finish" , cmdFinish , "{fi}nish\t\t execute till return of current function\n" }, { "fi" , cmdFinish , NULL }, - { "where" , cmdWhere , "where\t\t\t print stack\n" }, + { "where" , cmdWhere , "where\t\t print stack\n" }, { "fr" , cmdFrame , NULL }, { "f" , cmdFrame , NULL }, { "x /i" , cmdDisasm1 , "x\t\t disassemble one asm command\n" }, @@ -435,6 +448,23 @@ static void loadModules () } } +/*-----------------------------------------------------------------*/ +/* generate extra sets of sfr and sbit symbols */ +/*-----------------------------------------------------------------*/ +static void specialFunctionRegs () +{ + symbol *sym; + for (sym = setFirstItem(symbols); + sym ; + sym = setNextItem(symbols)) + { + if ( sym->addrspace == 'I' || + sym->addrspace == 'J') + { + addSet(&sfrsymbols,sym); + } + } +} /*-----------------------------------------------------------------*/ /* functionPoints - determine the execution points within a func */ /*-----------------------------------------------------------------*/ @@ -517,7 +547,7 @@ static void functionPoints () #ifdef SDCDB_DEBUG if (!( D_sdcdb & sdcdbDebug)) - return; + continue; Dprintf(D_sdcdb, ("sdcdb: function '%s' has the following C exePoints\n", func->sym->name)); @@ -601,6 +631,9 @@ int cmdFile (char *s,context *cctxt) module */ functionPoints(); + /* extract known special function registers */ + specialFunctionRegs(); + /* start the simulator & setup connection to it */ if ( sock == -1 ) openSimulator((char **)simArgs,nsimArgs); @@ -641,7 +674,15 @@ int cmdHelp (char *s, context *cctxt) for (i = 0 ; i < (sizeof(cmdTab)/sizeof(struct cmdtab)) ; i++) { if ((cmdTab[i].htxt) && !strcmp(cmdTab[i].cmd,s)) - fprintf(stdout,"%s",cmdTab[i].htxt); + { + s = strrchr(cmdTab[i].htxt,'\t'); + if ( !s ) + s = cmdTab[i].htxt; + else + s++; + fprintf(stdout,"%s",s); + break; + } } return 0; } diff --git a/debugger/mcs51/sdcdb.h b/debugger/mcs51/sdcdb.h index b5afc122..80c42627 100644 --- a/debugger/mcs51/sdcdb.h +++ b/debugger/mcs51/sdcdb.h @@ -136,6 +136,14 @@ enum { MOD_REC }; +enum { + FMT_NON = 0, + FMT_BIN = 1, + FMT_OCT = 2, + FMT_DEZ = 3, + FMT_HEX = 4 +}; + enum { SRC_CMODE = 1, SRC_AMODE }; /*-----------------------------------------------------------------*/ @@ -222,11 +230,24 @@ typedef struct context { int level ; /* current level number */ } context ; +/*-----------------------------------------------------------------*/ +/* symbol display information */ +/*-----------------------------------------------------------------*/ +typedef struct _dsymbol +{ + char *name; + int dnum; + int fmt; + char *rs; +} dsymbol; + + extern cdbrecs *recsRoot ; extern context *currCtxt ; extern set *modules ; /* set of modules */ extern set *functions; /* set of functions */ extern set *symbols ; /* set of symbols */ +extern set *sfrsymbols;/* set of symbols of sfr or sbit */ extern char *currModName ; extern short userinterrupt ; @@ -236,6 +257,7 @@ extern struct structdef **structs ; /* all structures */ extern char *ssdirl; /* source directory search path */ void **resize (void **, int ); char *alloccpy(char *,int ); +char *gc_strdup(const char *s); srcLine **loadFile (char *name, int *nlines); extern short fullname; extern int srcMode; diff --git a/debugger/mcs51/simi.c b/debugger/mcs51/simi.c index 7fec50f0..0edc1e98 100644 --- a/debugger/mcs51/simi.c +++ b/debugger/mcs51/simi.c @@ -45,6 +45,73 @@ static char *sbp = simibuff; /* simulator buffer pointer */ extern char **environ; char simactive = 0; +static memcache_t memCache[NMEM_CACHE]; + +/*-----------------------------------------------------------------*/ +/* get data from memory cache/ load cache from simulator */ +/*-----------------------------------------------------------------*/ +static char *getMemCache(unsigned int addr,int cachenum, int size) +{ + char *resp, *buf; + unsigned int laddr; + memcache_t *cache = &memCache[cachenum]; + + if ( cache->size <= 0 || + cache->addr > addr || + cache->addr + cache->size < addr + size ) + { + if ( cachenum == IMEM_CACHE ) + { + sendSim("di 0x0 0xff\n"); + } + else + { + laddr = addr & 0xffffffc0; + sprintf(cache->buffer,"dx 0x%x 0x%x\n",laddr,laddr+0xff ); + sendSim(cache->buffer); + } + waitForSim(100,NULL); + resp = simResponse(); + cache->addr = strtol(resp,0,0); + buf = cache->buffer; + cache->size = 0; + while ( *resp && *(resp+1) && *(resp+2)) + { + /* cache is a stringbuffer with ascii data like + " 00 00 00 00 00 00 00 00" + */ + resp += 2; + laddr = 0; + /* skip thru the address part */ + while (isxdigit(*resp)) resp++; + while ( *resp && *resp != '\n') + { + if ( laddr < 24 ) + { + laddr++ ; + *buf++ = *resp ; + } + resp++; + } + resp++ ; + cache->size += 8; + } + *buf = '\0'; + if ( cache->addr > addr || + cache->addr + cache->size < addr + size ) + return NULL; + } + return cache->buffer + (addr - cache->addr)*3; +} + +/*-----------------------------------------------------------------*/ +/* invalidate memory cache */ +/*-----------------------------------------------------------------*/ +static void invalidateCache( int cachenum ) +{ + memCache[cachenum].size = 0; +} + /*-----------------------------------------------------------------*/ /* waitForSim - wait till simulator is done its job */ /*-----------------------------------------------------------------*/ @@ -74,6 +141,8 @@ void openSimulator (char **args, int nargs) int i ; Dprintf(D_simi, ("simi: openSimulator\n")); + invalidateCache(XMEM_CACHE); + invalidateCache(IMEM_CACHE); /* fork and start the simulator as a subprocess */ if ((simPid = fork())) { Dprintf(D_simi, ("simi: simulator pid %d\n",(int) simPid)); @@ -148,47 +217,89 @@ void sendSim(char *s) fflush(simout); } -int simSetValue (unsigned int addr,char mem, int size, unsigned long val) + +static int getMemString(char *buffer, char wrflag, + unsigned int addr, char mem, int size ) { - char buffer[40], *s,*prefix; - int i; + int cachenr = NMEM_CACHE; + char *prefix; + char *cmd ; + + if ( wrflag ) + cmd = "set mem"; + else + cmd = "dump"; + buffer[0] = '\0' ; + switch (mem) { - case 'A': - prefix = "x"; - break; - case 'B': - prefix = "i"; + case 'A': /* External stack */ + case 'F': /* External ram */ + prefix = "xram"; + cachenr = XMEM_CACHE; break; - case 'C': - case 'D': - prefix = "c"; + case 'C': /* Code */ + case 'D': /* Code / static segment */ + prefix = "rom"; break; - case 'E': - case 'G': - prefix = "i"; + case 'B': /* Internal stack */ + case 'E': /* Internal ram (lower 128) bytes */ + case 'G': /* Internal ram */ + prefix = "iram"; + cachenr = IMEM_CACHE; break; - case 'F': - prefix = "x"; + case 'H': /* Bit addressable */ + case 'J': /* SBIT space */ + cachenr = BIT_CACHE; + if ( wrflag ) + { + cmd = "set bit"; + } + sprintf(buffer,"%s 0x%x\n",cmd,addr); + return cachenr; break; - case 'H': - prefix = "bit" ; - break; - case 'I': + case 'I': /* SFR space */ prefix = "sfr" ; break; - case 'J': - prefix = "sbit" ; - break; - case 'R': - return; /* set registers !! */ - //prefix = "i" ; + case 'R': /* Register space */ + if ( !wrflag ) + { + cachenr = REG_CACHE; + sprintf(buffer,"info reg\n"); + return cachenr; + } + prefix = "iram"; + /* get register bank */ + cachenr = simGetValue (0xd0,'I',1); + addr += cachenr & 0x18 ; + cachenr = IMEM_CACHE; break; - default: - return; + default: + case 'Z': /* undefined space code */ + return cachenr; } - sprintf(buffer,"set mem %s 0x%x",prefix,addr); - s = buffer + strlen(buffer); + if ( wrflag ) + sprintf(buffer,"%s %s 0x%x\n",cmd,prefix,addr,addr); + else + sprintf(buffer,"%s %s 0x%x 0x%x\n",cmd,prefix,addr,addr+size-1); + return cachenr; +} + +int simSetValue (unsigned int addr,char mem, int size, unsigned long val) +{ + char cachenr, i; + char buffer[40]; + char *s; + + if ( size <= 0 ) + return 0; + + cachenr = getMemString(buffer,1,addr,mem,size); + if ( cachenr < NMEM_CACHE ) + { + invalidateCache(cachenr); + } + s = buffer + strlen(buffer) -1; for ( i = 0 ; i < size ; i++ ) { sprintf(s," 0x%x", val & 0xff); @@ -201,107 +312,77 @@ int simSetValue (unsigned int addr,char mem, int size, unsigned long val) simResponse(); } + /*-----------------------------------------------------------------*/ /* simGetValue - get value @ address for mem space */ /*-----------------------------------------------------------------*/ unsigned long simGetValue (unsigned int addr,char mem, int size) { unsigned int b[4] = {0,0,0,0}; /* can be a max of four bytes long */ - char i; - char *prefix; - char buffer[20]; + char cachenr, i; + char buffer[40]; char *resp; - switch (mem) { - case 'A': - prefix = "dx"; - break; - case 'B': - prefix = "di"; - break; - case 'C': - case 'D': - prefix = "dch"; - break; - case 'E': - case 'G': - prefix = "di"; - break; - case 'F': - prefix = "dx"; - break; - case 'H': - case 'J': -// prefix = "db" ; - prefix = "dump" ; - break; - case 'I': - prefix = "ds" ; - break; - case 'R': - prefix = "i r" ; - break; - default: - prefix = "dump" ; - break; - } - - /* create the simulator command */ - sprintf(buffer,"%s 0x%x \n",prefix,addr); - sendSim(buffer); - waitForSim(100,NULL); - resp = simResponse(); - - /* got the response we need to parse it the response - is of the form - [address] [v] [v] [v] ... special case in - case of bit variables which case it becomes - [address] [assembler bit address] [v] */ - /* first skip thru white space */ - while (isspace(*resp)) resp++ ; - - if (strncmp(resp, "0x",2) == 0) - resp += 2; + if ( size <= 0 ) + return 0; - /* then make the branch for bit variables */ - /* skip thru the address part */ - while (isxdigit(*resp)) resp++; + cachenr = getMemString(buffer,0,addr,mem,size); - if (!strcmp(prefix,"i r")) + resp = NULL; + if ( cachenr < NMEM_CACHE ) { - /* skip registers */ - for (i = 0 ; i < addr ; i++ ) + resp = getMemCache(addr,cachenr,size); + } + if ( !resp ) + { + /* create the simulator command */ + sendSim(buffer); + waitForSim(100,NULL); + resp = simResponse(); + + /* got the response we need to parse it the response + is of the form + [address] [v] [v] [v] ... special case in + case of bit variables which case it becomes + [address] [assembler bit address] [v] */ + /* first skip thru white space */ + while (isspace(*resp)) resp++ ; + + if (strncmp(resp, "0x",2) == 0) + resp += 2; + + /* skip thru the address part */ + while (isxdigit(*resp)) resp++; + + /* then make the branch for bit variables */ + if ( cachenr == REG_CACHE ) { - while (isspace(*resp)) resp++ ; - /* skip */ - while (isxdigit(*resp)) resp++; + /* skip registers */ + for (i = 0 ; i < addr ; i++ ) + { + while (isspace(*resp)) resp++ ; + /* skip */ + while (isxdigit(*resp)) resp++; + } } - } - - if (!strcmp(prefix,"dump")) { - - /* skip white space */ - while (isspace(*resp)) resp++ ; - - /* skip thru the assembler bit address */ - while (!isspace(*resp)) resp++; - - /* white space */ - while (isspace(*resp)) resp++ ; - - /* scan in the value */ - sscanf(resp,"%d",&b[0]); - } else { - - for (i = 0 ; i < size ; i++ ) { - /* skip white space */ - while (isspace(*resp)) resp++ ; - - sscanf(resp,"%x",&b[i]); + } + /* make the branch for bit variables */ + if ( cachenr == BIT_CACHE) + { + /* skip until newline */ + while (*resp && *resp != '\n' ) resp++ ; + if ( *--resp != '0' ) + b[0] = 1; + } + else + { + for (i = 0 ; i < size ; i++ ) + { + /* skip white space */ + while (isspace(*resp)) resp++ ; - /* skip */ - while (isxdigit(*resp)) resp++; - } + b[i] = strtol(resp,&resp,16); + } } return b[0] | b[1] << 8 | b[2] << 16 | b[3] << 24 ; @@ -355,6 +436,8 @@ unsigned int simGoTillBp ( unsigned int gaddr) char *sfmt; int wait_ms = 1000; + invalidateCache(XMEM_CACHE); + invalidateCache(IMEM_CACHE); if (gaddr == 0) { /* initial start, start & stop from address 0 */ char buf[20]; @@ -371,7 +454,15 @@ unsigned int simGoTillBp ( unsigned int gaddr) sendSim ("run\n"); wait_ms = 100; } - else { + else if (gaddr == 1 ) { /* nexti */ + sendSim ("next\n"); + wait_ms = 100; + } + else if (gaddr == 2 ) { /* stepi */ + sendSim ("step\n"); + wait_ms = 100; + } + else { printf("Error, simGoTillBp > 0!\n"); exit(1); } @@ -381,6 +472,22 @@ unsigned int simGoTillBp ( unsigned int gaddr) /* get the simulator response */ svr = sr = strdup(simResponse()); + if ( gaddr == 1 || gaddr == 2 ) + { + int nl; + for ( nl = 0; nl < 3 ; nl++ ) + { + while (*sr && *sr != '\n') sr++ ; + sr++ ; + } + if ( nl < 3 ) + return 0; + gaddr = strtol(sr,0,0); + /* empty response */ + simibuff[0] = '\0'; + return gaddr; + + } /* figure out the address of the break point the simulators response in a break point situation is of the form [... F* ] @@ -420,6 +527,8 @@ unsigned int simGoTillBp ( unsigned int gaddr) /*-----------------------------------------------------------------*/ void simReset () { + invalidateCache(XMEM_CACHE); + invalidateCache(IMEM_CACHE); sendSim("res\n"); waitForSim(100,NULL); } diff --git a/debugger/mcs51/simi.h b/debugger/mcs51/simi.h index 05ace69a..7003c74a 100644 --- a/debugger/mcs51/simi.h +++ b/debugger/mcs51/simi.h @@ -26,6 +26,23 @@ #define SIMI_H #define MAX_SIM_BUFF 8*1024 + +#define MAX_CACHE_SIZE 2048 +/* number of cache */ +#define IMEM_CACHE 0 +#define XMEM_CACHE 1 +#define NMEM_CACHE 2 +/* special index */ +#define REG_CACHE 3 +#define BIT_CACHE 4 + +typedef struct _memcache +{ + int addr; + int size; + char buffer[MAX_CACHE_SIZE]; +} memcache_t; + //#define SIMNAME "s51" extern int sock; extern char simactive; diff --git a/debugger/mcs51/symtab.c b/debugger/mcs51/symtab.c index 2e2e5008..506ef79b 100644 --- a/debugger/mcs51/symtab.c +++ b/debugger/mcs51/symtab.c @@ -327,6 +327,7 @@ structdef *parseStruct (char *s) name = alloccpy(bp,s - bp); nsdef = structWithName(name); nsdef->fields = NULL; + nsdef->size = 0; s++; while (*s && *s != ']') { int offset ; @@ -342,7 +343,7 @@ structdef *parseStruct (char *s) fields = nsdef->fields = sym; else fields = fields->next = sym; - + nsdef->size += sym->size; } return nsdef; diff --git a/debugger/mcs51/symtab.h b/debugger/mcs51/symtab.h index 42047609..3f7845f9 100644 --- a/debugger/mcs51/symtab.h +++ b/debugger/mcs51/symtab.h @@ -239,7 +239,6 @@ void parseFunc (char *); module *parseModule (char *, bool ); void parseLnkRec (char *); symbol *symLookup (char *,context *); - DEFSETFUNC(moduleWithName); DEFSETFUNC(moduleWithCName); DEFSETFUNC(moduleWithAsmName); -- 2.30.2