set PC if a symbol at pc reg is set
[fw/sdcc] / debugger / mcs51 / cmd.c
1 /*-------------------------------------------------------------------------
2     cmd.c - source  file for debugger command execution
3
4               Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1999)
5
6    This program is free software; you can redistribute it and/or modify it
7    under the terms of the GNU General Public License as published by the
8    Free Software Foundation; either version 2, or (at your option) any
9    later version.
10    
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15    
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19    
20    In other words, you are welcome to use, share and improve this program.
21    You are forbidden to forbid anyone else to use, share and improve
22    what you give them.   Help stamp out software-hoarding!  
23 -------------------------------------------------------------------------*/
24
25 #include "sdcdb.h"
26 #include "symtab.h"
27 #include "simi.h"
28 #include "break.h"
29 #include "cmd.h"
30 #include "newalloc.h"
31
32 /* default number of lines to list out */
33 #define LISTLINES 10
34 static int listlines = LISTLINES;
35
36 /* mainly used to retain a reference to the active module being
37    listed.  May be used as a general context for other commands if
38    no better context is available */
39 static module *list_mod = NULL;
40
41 EXTERN_STACK_DCL(callStack,function *,1024);
42
43 #if defined(__APPLE__) && defined(__MACH__)
44 static char *copying=
45 {" GNU GENERAL PUBLIC LICENSE Version 2"};
46 static char *warranty=
47 {" NO WARRANTY"};
48 #else
49 static char *copying=
50 "                   GNU GENERAL PUBLIC LICENSE\n"
51 "                       Version 2, June 1991\n"
52 "\n"
53 " Copyright (C) 1989, 1991 Free Software Foundation, Inc.\n"
54 " 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA\n"
55 " Everyone is permitted to copy and distribute verbatim copies\n"
56 " of this license document, but changing it is not allowed.\n"
57 "\n"
58 "                            Preamble\n"
59 "\n"
60 "  The licenses for most software are designed to take away your\n"
61 "freedom to share and change it.  By contrast, the GNU General Public\n"
62 "License is intended to guarantee your freedom to share and change free\n"
63 "software--to make sure the software is free for all its users.  This\n"
64 "General Public License applies to most of the Free Software\n"
65 "Foundation's software and to any other program whose authors commit to\n"
66 "using it.  (Some other Free Software Foundation software is covered by\n"
67 "the GNU Library General Public License instead.)  You can apply it to\n"
68 "your programs, too.\n"
69 "\n"
70 "  When we speak of free software, we are referring to freedom, not\n"
71 "price.  Our General Public Licenses are designed to make sure that you\n"
72 "have the freedom to distribute copies of free software (and charge for\n"
73 "this service if you wish), that you receive source code or can get it\n"
74 "if you want it, that you can change the software or use pieces of it\n"
75 "in new free programs; and that you know you can do these things.\n"
76 "\n"
77 "  To protect your rights, we need to make restrictions that forbid\n"
78 "anyone to deny you these rights or to ask you to surrender the rights.\n"
79 "These restrictions translate to certain responsibilities for you if you\n"
80 "distribute copies of the software, or if you modify it.\n"
81 "\n"
82 "  For example, if you distribute copies of such a program, whether\n"
83 "gratis or for a fee, you must give the recipients all the rights that\n"
84 "you have.  You must make sure that they, too, receive or can get the\n"
85 "source code.  And you must show them these terms so they know their\n"
86 "rights.\n"
87 "\n"
88 "  We protect your rights with two steps: (1) copyright the software, and\n"
89 "(2) offer you this license which gives you legal permission to copy,\n"
90 "distribute and/or modify the software.\n"
91 "\n"
92 "  Also, for each author's protection and ours, we want to make certain\n"
93 "that everyone understands that there is no warranty for this free\n"
94 "software.  If the software is modified by someone else and passed on, we\n"
95 "want its recipients to know that what they have is not the original, so\n"
96 "that any problems introduced by others will not reflect on the original\n"
97 "authors' reputations.\n"
98 "\n"
99 "  Finally, any free program is threatened constantly by software\n"
100 "patents.  We wish to avoid the danger that redistributors of a free\n"
101 "program will individually obtain patent licenses, in effect making the\n"
102 "program proprietary.  To prevent this, we have made it clear that any\n"
103 "patent must be licensed for everyone's free use or not licensed at all.\n"
104 "\n"
105 "  The precise terms and conditions for copying, distribution and\n"
106 "modification follow.\n"
107 "^L\n"
108 "                    GNU GENERAL PUBLIC LICENSE\n"
109 "   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n"
110 "\n"
111 "  0. This License applies to any program or other work which contains\n"
112 "a notice placed by the copyright holder saying it may be distributed\n"
113 "under the terms of this General Public License.  The \"Program\", below,\n"
114 "refers to any such program or work, and a \"work based on the Program\"\n"
115 "means either the Program or any derivative work under copyright law:\n"
116 "that is to say, a work containing the Program or a portion of it,\n"
117 "either verbatim or with modifications and/or translated into another\n"
118 "language.  (Hereinafter, translation is included without limitation in\n"
119 "the term \"modification\".)  Each licensee is addressed as \"you\".\n"
120 "\n"
121 "Activities other than copying, distribution and modification are not\n"
122 "covered by this License; they are outside its scope.  The act of\n"
123 "running the Program is not restricted, and the output from the Program\n"
124 "is covered only if its contents constitute a work based on the\n"
125 "Program (independent of having been made by running the Program).\n"
126 "Whether that is true depends on what the Program does.\n"
127 "\n"
128 "  1. You may copy and distribute verbatim copies of the Program's\n"
129 "source code as you receive it, in any medium, provided that you\n"
130 "conspicuously and appropriately publish on each copy an appropriate\n"
131 "copyright notice and disclaimer of warranty; keep intact all the\n"
132 "notices that refer to this License and to the absence of any warranty;\n"
133 "and give any other recipients of the Program a copy of this License\n"
134 "along with the Program.\n"
135 "\n"
136 "You may charge a fee for the physical act of transferring a copy, and\n"
137 "you may at your option offer warranty protection in exchange for a fee.\n"
138 "\n"
139 "  2. You may modify your copy or copies of the Program or any portion\n"
140 "of it, thus forming a work based on the Program, and copy and\n"
141 "distribute such modifications or work under the terms of Section 1\n"
142 "above, provided that you also meet all of these conditions:\n"
143 "\n"
144 "    a) You must cause the modified files to carry prominent notices\n"
145 "    stating that you changed the files and the date of any change.\n"
146 "\n"
147 "    b) You must cause any work that you distribute or publish, that in\n"
148 "    whole or in part contains or is derived from the Program or any\n"
149 "    part thereof, to be licensed as a whole at no charge to all third\n"
150 "    parties under the terms of this License.\n"
151 "\n"
152 "    c) If the modified program normally reads commands interactively\n"
153 "    when run, you must cause it, when started running for such\n"
154 "    interactive use in the most ordinary way, to print or display an\n"
155 "    announcement including an appropriate copyright notice and a\n"
156 "    notice that there is no warranty (or else, saying that you provide\n"
157 "    a warranty) and that users may redistribute the program under\n"
158 "    these conditions, and telling the user how to view a copy of this\n"
159 "    License.  (Exception: if the Program itself is interactive but\n"
160 "    does not normally print such an announcement, your work based on\n"
161 "    the Program is not required to print an announcement.)\n"
162 "\n"
163 "These requirements apply to the modified work as a whole.  If\n"
164 "identifiable sections of that work are not derived from the Program,\n"
165 "and can be reasonably considered independent and separate works in\n"
166 "themselves, then this License, and its terms, do not apply to those\n"
167 "sections when you distribute them as separate works.  But when you\n"
168 "distribute the same sections as part of a whole which is a work based\n"
169 "on the Program, the distribution of the whole must be on the terms of\n"
170 "this License, whose permissions for other licensees extend to the\n"
171 "entire whole, and thus to each and every part regardless of who wrote it.\n"
172 "\n"
173 "Thus, it is not the intent of this section to claim rights or contest\n"
174 "your rights to work written entirely by you; rather, the intent is to\n"
175 "exercise the right to control the distribution of derivative or\n"
176 "collective works based on the Program.\n"
177 "\n"
178 "In addition, mere aggregation of another work not based on the Program\n"
179 "with the Program (or with a work based on the Program) on a volume of\n"
180 "a storage or distribution medium does not bring the other work under\n"
181 "the scope of this License.\n"
182 "\n"
183 "  3. You may copy and distribute the Program (or a work based on it,\n"
184 "under Section 2) in object code or executable form under the terms of\n"
185 "Sections 1 and 2 above provided that you also do one of the following:\n"
186 "\n"
187 "    a) Accompany it with the complete corresponding machine-readable\n"
188 "    source code, which must be distributed under the terms of Sections\n"
189 "    1 and 2 above on a medium customarily used for software interchange; or,\n"
190 "\n"
191 "    b) Accompany it with a written offer, valid for at least three\n"
192 "    years, to give any third party, for a charge no more than your\n"
193 "    cost of physically performing source distribution, a complete\n"
194 "    machine-readable copy of the corresponding source code, to be\n"
195 "    distributed under the terms of Sections 1 and 2 above on a medium\n"
196 "    customarily used for software interchange; or,\n"
197 "\n"
198 "    c) Accompany it with the information you received as to the offer\n"
199 "    to distribute corresponding source code.  (This alternative is\n"
200 "    allowed only for noncommercial distribution and only if you\n"
201 "    received the program in object code or executable form with such\n"
202 "    an offer, in accord with Subsection b above.)\n"
203 "\n"
204 "The source code for a work means the preferred form of the work for\n"
205 "making modifications to it.  For an executable work, complete source\n"
206 "code means all the source code for all modules it contains, plus any\n"
207 "associated interface definition files, plus the scripts used to\n"
208 "control compilation and installation of the executable.  However, as a\n"
209 "special exception, the source code distributed need not include\n"
210 "anything that is normally distributed (in either source or binary\n"
211 "form) with the major components (compiler, kernel, and so on) of the\n"
212 "operating system on which the executable runs, unless that component\n"
213 "itself accompanies the executable.\n"
214 "\n"
215 "If distribution of executable or object code is made by offering\n"
216 "access to copy from a designated place, then offering equivalent\n"
217 "access to copy the source code from the same place counts as\n"
218 "distribution of the source code, even though third parties are not\n"
219 "compelled to copy the source along with the object code.\n"
220 "^L\n"
221 "  4. You may not copy, modify, sublicense, or distribute the Program\n"
222 "except as expressly provided under this License.  Any attempt\n"
223 "otherwise to copy, modify, sublicense or distribute the Program is\n"
224 "void, and will automatically terminate your rights under this License.\n"
225 "However, parties who have received copies, or rights, from you under\n"
226 "this License will not have their licenses terminated so long as such\n"
227 "parties remain in full compliance.\n"
228 "\n"
229 "  5. You are not required to accept this License, since you have not\n"
230 "signed it.  However, nothing else grants you permission to modify or\n"
231 "distribute the Program or its derivative works.  These actions are\n"
232 "prohibited by law if you do not accept this License.  Therefore, by\n"
233 "modifying or distributing the Program (or any work based on the\n"
234 "Program), you indicate your acceptance of this License to do so, and\n"
235 "all its terms and conditions for copying, distributing or modifying\n"
236 "the Program or works based on it.\n"
237 "\n"
238 "  6. Each time you redistribute the Program (or any work based on the\n"
239 "Program), the recipient automatically receives a license from the\n"
240 "original licensor to copy, distribute or modify the Program subject to\n"
241 "these terms and conditions.  You may not impose any further\n"
242 "restrictions on the recipients' exercise of the rights granted herein.\n"
243 "You are not responsible for enforcing compliance by third parties to\n"
244 "this License.\n"
245 "\n"
246 "  7. If, as a consequence of a court judgment or allegation of patent\n"
247 "infringement or for any other reason (not limited to patent issues),\n"
248 "conditions are imposed on you (whether by court order, agreement or\n"
249 "otherwise) that contradict the conditions of this License, they do not\n"
250 "excuse you from the conditions of this License.  If you cannot\n"
251 "distribute so as to satisfy simultaneously your obligations under this\n"
252 "License and any other pertinent obligations, then as a consequence you\n"
253 "may not distribute the Program at all.  For example, if a patent\n"
254 "license would not permit royalty-free redistribution of the Program by\n"
255 "all those who receive copies directly or indirectly through you, then\n"
256 "the only way you could satisfy both it and this License would be to\n"
257 "refrain entirely from distribution of the Program.\n"
258 "\n"
259 "If any portion of this section is held invalid or unenforceable under\n"
260 "any particular circumstance, the balance of the section is intended to\n"
261 "apply and the section as a whole is intended to apply in other\n"
262 "circumstances.\n"
263 "\n"
264 "It is not the purpose of this section to induce you to infringe any\n"
265 "patents or other property right claims or to contest validity of any\n"
266 "such claims; this section has the sole purpose of protecting the\n"
267 "integrity of the free software distribution system, which is\n"
268 "implemented by public license practices.  Many people have made\n"
269 "generous contributions to the wide range of software distributed\n"
270 "through that system in reliance on consistent application of that\n"
271 "system; it is up to the author/donor to decide if he or she is willing\n"
272 "to distribute software through any other system and a licensee cannot\n"
273 "impose that choice.\n"
274 "\n"
275 "This section is intended to make thoroughly clear what is believed to\n"
276 "be a consequence of the rest of this License.\n"
277 "\n"
278 "  8. If the distribution and/or use of the Program is restricted in\n"
279 "certain countries either by patents or by copyrighted interfaces, the\n"
280 "original copyright holder who places the Program under this License\n"
281 "may add an explicit geographical distribution limitation excluding\n"
282 "those countries, so that distribution is permitted only in or among\n"
283 "countries not thus excluded.  In such case, this License incorporates\n"
284 "the limitation as if written in the body of this License.\n"
285 "\n"
286 "  9. The Free Software Foundation may publish revised and/or new versions\n"
287 "of the General Public License from time to time.  Such new versions will\n"
288 "be similar in spirit to the present version, but may differ in detail to\n"
289 "address new problems or concerns.\n"
290 "\n"
291 "Each version is given a distinguishing version number.  If the Program\n"
292 "specifies a version number of this License which applies to it and \"any\n"
293 "later version\", you have the option of following the terms and conditions\n"
294 "either of that version or of any later version published by the Free\n"
295 "Software Foundation.  If the Program does not specify a version number of\n"
296 "this License, you may choose any version ever published by the Free Software\n"
297 "Foundation.\n"
298 "\n"
299 "  10. If you wish to incorporate parts of the Program into other free\n"
300 "programs whose distribution conditions are different, write to the author\n"
301 "to ask for permission.  For software which is copyrighted by the Free\n"
302 "Software Foundation, write to the Free Software Foundation; we sometimes\n"
303 "make exceptions for this.  Our decision will be guided by the two goals\n"
304 "of preserving the free status of all derivatives of our free software and\n"
305 "of promoting the sharing and reuse of software generally.\n";
306
307 static char *warranty=
308 "                            NO WARRANTY\n"
309 "\n"
310 "  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\n"
311 "FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN\n"
312 "OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\n"
313 "PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\n"
314 "OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n"
315 "MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS\n"
316 "TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE\n"
317 "PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\n"
318 "REPAIR OR CORRECTION.\n"
319 "\n"
320 "  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\n"
321 "WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\n"
322 "REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\n"
323 "INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\n"
324 "OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\n"
325 "TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\n"
326 "YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\n"
327 "PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\n"
328 "POSSIBILITY OF SUCH DAMAGES.\n";
329 #endif
330
331 static void printTypeInfo(link *);
332 static void printValAggregates (symbol *,link *,char,unsigned int,int);
333 static  int printOrSetSymValue (symbol *sym, context *cctxt, 
334                                 int flg, int dnum, int fmt, 
335                                 char *rs, char *val, char cmp);
336
337 int srcMode = SRC_CMODE ;
338 static set  *dispsymbols = NULL   ; /* set of displayable symbols */
339 static int currentFrame = 0;        /* actual displayed frame     */
340 /*-----------------------------------------------------------------*/
341 /* funcWithName - returns function with name                       */
342 /*-----------------------------------------------------------------*/
343 DEFSETFUNC(funcWithName)
344 {
345     function *func = item;
346     V_ARG(char *,name);
347     V_ARG(function **,funcp);
348
349     if (*funcp)
350         return 0;
351
352     if (strcmp(func->sym->name,name) == 0) {
353         *funcp = func;
354         return 1;
355     }
356     
357     return 0;
358 }
359
360 /*-----------------------------------------------------------------*/
361 /* symWithAddr - look for symbol with sfr / sbit address           */
362 /*-----------------------------------------------------------------*/
363 DEFSETFUNC(symWithAddr)
364 {
365     symbol *sym = item;
366     V_ARG(unsigned long,laddr);
367     V_ARG(int    ,laddrspace);
368     V_ARG(symbol **,rsym);
369
370     if (*rsym)
371         return 0;
372
373     if ( sym->addr == laddr &&
374          sym->addrspace == laddrspace ) 
375     {
376         *rsym = sym;
377         return 1;
378     }
379
380     return 0;
381 }
382
383 /*-----------------------------------------------------------------*/
384 /* setBPatModLine - set break point at the line specified for the  */
385 /*-----------------------------------------------------------------*/
386 static void setBPatModLine (module *mod, int line, char bpType )
387 {
388   int next_line;
389
390     /* look for the first executable line after the line
391        specified & get the break point there */    
392     if (srcMode == SRC_CMODE && line > mod->ncLines) {
393         fprintf(stderr,"No line %d in file \"%s\".\n",
394                 line,mod->c_name);
395         return ;
396     }
397     
398     if (srcMode == SRC_AMODE && line > mod->nasmLines) {
399         fprintf(stderr,"No line %d in file \"%s\".\n",
400                 line,mod->asm_name);
401         return ;
402     }
403
404     next_line = line;
405     for ( ; next_line < (srcMode == SRC_CMODE ? mod->ncLines : mod->nasmLines ) ; 
406           next_line++ ) {
407         if (srcMode == SRC_CMODE) {
408             if (mod->cLines[next_line]->addr) {
409                 setBreakPoint (mod->cLines[next_line]->addr, CODE, bpType, 
410                                userBpCB, mod->c_name, next_line);
411                 return;
412 //              break;
413             }
414         }
415         else {
416            if (mod->asmLines[next_line]->addr) {
417                setBreakPoint (mod->asmLines[next_line]->addr, CODE, bpType, 
418                               userBpCB, mod->asm_name, next_line);
419                 return;
420 //             break;
421            } 
422         }
423     }
424
425         fprintf(stderr,"No line %d or after in file \"%s\"..\n",
426                         line,mod->c_name);
427
428     return;
429 }
430
431 /*-----------------------------------------------------------------*/
432 /* clearBPatModLine - clr break point at the line specified        */
433 /*-----------------------------------------------------------------*/
434 static void clearBPatModLine (module *mod, int line)
435 {
436     /* look for the first executable line after the line
437        specified & get the break point there */
438     if (srcMode == SRC_CMODE && line > mod->ncLines) {
439         fprintf(stderr,"No line %d in file \"%s\".\n",
440                 line,mod->c_name);
441         return ;
442     }
443     
444     if (srcMode == SRC_AMODE && line > mod->ncLines) {
445         fprintf(stderr,"No line %d in file \"%s\".\n",
446                 line,mod->c_name);
447         return ;
448     }    
449     
450     for ( ; line < (srcMode == SRC_CMODE ? mod->ncLines : mod->nasmLines ) ; 
451           line++ ) {
452         if (srcMode == SRC_CMODE) 
453             if (mod->cLines[line]->addr) {
454                 clearUSERbp (mod->cLines[line]->addr);                    
455                 break;
456             }
457         else
458             if (mod->asmLines[line]->addr) {
459                 clearUSERbp (mod->asmLines[line]->addr);                          
460                 break;
461             }
462     }
463
464     return;
465 }
466
467 /*-----------------------------------------------------------------*/
468 /* moduleLineWithAddr - finds and returns a line  with a given address */
469 /*-----------------------------------------------------------------*/
470 DEFSETFUNC(moduleLineWithAddr)
471 {
472     module *mod = item;
473     int i;
474
475     V_ARG(unsigned int,addr);
476     V_ARG(module **,rmod);
477     V_ARG(int *,line);
478
479     if (*rmod)
480         return 0;
481
482     for (i=0; i < mod->nasmLines; i++ ) 
483     {
484         if ( mod->asmLines[i]->addr == addr)
485         {
486             *rmod = mod ;
487             if (line )
488             {
489                 *line = 0;
490                 for ( i=0; i < mod->ncLines; i++ ) 
491                 {
492                     if ( mod->cLines[i]->addr > addr)
493                         break;
494                     *line = i;
495                 }
496                 return 1;
497             }
498         }
499     }
500
501     return 0;
502 }
503
504 /*-----------------------------------------------------------------*/
505 /* funcWithNameModule - returns functions with a name module combo */
506 /*-----------------------------------------------------------------*/
507 DEFSETFUNC(funcWithNameModule) 
508 {
509     function *func = item;
510     V_ARG(char *,fname);
511     V_ARG(char *,mname);
512     V_ARG(function **,funcp);
513
514     if (*funcp)
515         return 0;
516
517     if (strcmp(func->sym->name,fname) == 0 &&
518         strcmp(func->mod->c_name,mname) == 0) {
519         *funcp = func;
520         return 1;
521     }
522
523     return 0;
524 }
525
526 /*-----------------------------------------------------------------*/
527 /* funcInAddr - given an address returns the function              */
528 /*-----------------------------------------------------------------*/
529 DEFSETFUNC(funcInAddr)
530 {
531     function *func = item;
532     V_ARG(unsigned int,addr);
533     V_ARG(function **,funcp);
534
535     if (*funcp)
536         return 0;
537
538     /* in the address range */
539     if (func->sym->addr <= addr &&
540         func->sym->eaddr >= addr) {
541         
542         *funcp = func;
543         return 1;
544     }
545
546     return 0;       
547 }
548
549 /*-----------------------------------------------------------------*/
550 /* setStepBp - will set STEP Bp @ function entry points            */
551 /*-----------------------------------------------------------------*/
552 DEFSETFUNC(setStepBp)
553 {
554     function *func = item;
555     
556     if (func->sym && func->sym->addr ) {
557         
558         /* set the entry break point */
559         setBreakPoint (func->sym->addr , CODE , STEP , 
560                        stepBpCB ,func->mod->c_name , func->entryline);
561
562         return 1;
563     }
564
565     return 0;
566 }
567
568 /*-----------------------------------------------------------------*/
569 /* setStepEPBp - sets a given type of bp @ the execution point     */
570 /*-----------------------------------------------------------------*/
571 DEFSETFUNC(setStepEPBp)
572 {
573     exePoint *ep = item;
574     V_ARG(int,bptype);
575     V_ARG(char *,mname);
576    
577     setBreakPoint (ep->addr, CODE, bptype, 
578                    stepBpCB, mname, ep->line);
579     return 1;
580 }
581
582 /*-----------------------------------------------------------------*/
583 /* setNextEPBp - sets a given type of bp @ the execution point     */
584 /*-----------------------------------------------------------------*/
585 DEFSETFUNC(setNextEPBp)
586 {
587     exePoint *ep = item;
588     V_ARG(int,bptype);
589     V_ARG(char *,mname);
590    
591     setBreakPoint (ep->addr, CODE, bptype, 
592                    nextBpCB, mname, ep->line);
593     return 1;
594 }
595
596 /*-----------------------------------------------------------------*/
597 /* lineAtAddr - for execution points returns the one with addr     */
598 /*-----------------------------------------------------------------*/
599 DEFSETFUNC(lineAtAddr)
600 {
601     exePoint *ep = item;
602     V_ARG(unsigned int,addr);
603     V_ARG(int *,line);
604     V_ARG(int *,block);
605     V_ARG(int *,level);
606
607     /* address must be an exact match */
608     if (ep->addr == addr) {
609         *line = ep->line;
610         if (block)
611             *block = ep->block ;
612         if (level)
613             *level = ep->level ;
614         return 1;
615     }
616
617     return 0;
618     
619 }
620
621 /*-----------------------------------------------------------------*/
622 /* lineNearAddr - for execution points returns the one with addr   */
623 /*-----------------------------------------------------------------*/
624 DEFSETFUNC(lineNearAddr)
625 {
626     exePoint *ep = item;
627     V_ARG(unsigned int,addr);
628     V_ARG(int *,line);
629     V_ARG(int *,block);
630     V_ARG(int *,level);
631
632     /* the line in which the address is */
633     if (ep->addr <= addr) {
634         *line = ep->line;
635         if (block)
636             *block = ep->block ;
637         if (level)
638             *level = ep->level ;
639         return 1;
640     }
641
642     return 0;
643     
644 }
645
646 /*-----------------------------------------------------------------*/
647 /* discoverContext - find out the current context of the bp        */
648 /*-----------------------------------------------------------------*/
649 context *discoverContext (unsigned addr, function *func)
650 {
651     module   *mod  = NULL;
652     int line = 0;
653
654     /* find the function we are in */
655     if (!func && !applyToSet(functions,funcInAddr,addr,&func)) {
656         if (!applyToSet(functions,funcWithName,"main",&func) ||
657             !applyToSet(modules,moduleLineWithAddr,addr,&mod,NULL))
658         {
659             fprintf(stderr, "Error?:discoverContext: cannot apply addr 0x%x\n",addr);
660             return NULL;
661         }
662         currCtxt->func = func;
663         currCtxt->addr = addr;
664         currCtxt->modName = mod->name;
665         currCtxt->cline = func->exitline;
666     }
667     else
668     {
669         currCtxt->func = func;
670         currCtxt->addr = func->laddr = addr;
671         currCtxt->modName = func->modName;
672     
673         /* find the c line number */
674         if(applyToSet(func->cfpoints,lineAtAddr,addr,
675                   &line,&currCtxt->block,&currCtxt->level)) 
676             currCtxt->cline = func->lline = line;
677         else if(applyToSet(func->cfpoints,lineNearAddr,addr,
678                   &line,&currCtxt->block,&currCtxt->level)) 
679             currCtxt->cline = func->lline = line;
680         else
681             currCtxt->cline = func->exitline;
682     }    
683     /* find the asm line number */
684     line = 0;
685     if (applyToSet(func->afpoints,lineAtAddr,addr,
686                    &line,NULL,NULL))
687         currCtxt->asmline = line;       
688     else
689         currCtxt->asmline = -1;
690         
691     return currCtxt ;
692 }
693
694
695 /*-----------------------------------------------------------------*/
696 /* simGo - send 'go' cmd to simulator and wait till a break occurs */
697 /*-----------------------------------------------------------------*/
698 void simGo (unsigned int gaddr)
699 {   
700     unsigned int addr ;
701     context *ctxt;
702     int rv;
703     stopCommandList();
704  top:    
705     if ( userinterrupt )
706     {
707         userinterrupt = 0;
708         return;
709     }
710     addr = simGoTillBp (gaddr);
711
712     /* got the pc for the break point now first
713        discover the program context i.e. module, function 
714        linenumber of the source etc, etc etc */
715     currentFrame = 0; 
716     ctxt = discoverContext (addr, NULL);
717     
718     /* dispatch all the break point call back functions */
719     rv = dispatchCB (addr,ctxt);    
720  ret:    
721
722     /* the dispatch call back function will return
723        non-zero if an user break point has been hit
724        if not then we continue with the execution 
725        of the program */
726     if (!rv) 
727     {
728         if ( gaddr == 0 )
729             gaddr = -1;
730         if ( gaddr == -1 || doingSteps == 1 )
731             goto top ;
732     }
733     
734 }
735
736 /*-----------------------------------------------------------------*/
737 /* preparePrint - common parse function for  set variable,         */
738 /*                output, print and display                        */
739 /*-----------------------------------------------------------------*/
740 static char *preparePrint(char *s, context *cctxt, int *fmt, symbol **sym)
741 {
742     char *bp = s+strlen(s) -1;
743     char save_ch ;
744
745     *fmt = FMT_NON;
746     *sym = NULL;
747
748     while (isspace(*s)) s++;
749     if (!*s) 
750         return (char *)0;
751
752     while (isspace(*bp)) bp--;
753     bp++ ;
754     *bp = '\0';
755
756     if ( *s == '/' )
757     {
758         /* format of printout */
759         switch ( *++s )
760         {
761             case 'x':
762                 *fmt = FMT_HEX ;
763                 break;
764             case 'o':
765                 *fmt = FMT_OCT ;
766                 break;
767             default:
768             case 'd':
769                 *fmt = FMT_DEZ ;
770                 break;
771             case 't':
772                 *fmt = FMT_BIN ;
773                 break;
774         }
775         s++;
776         while (isspace(*s)) s++;
777     }
778     for ( bp = s; *bp && ( isalnum( *bp ) || *bp == '_' || *bp == '$'); bp++ );
779     save_ch = *bp;
780     if ( *bp )
781         *bp = '\0';
782
783     if ( *s )
784         *sym = symLookup(s,cctxt);
785     *bp = save_ch;
786
787     if ( ! *sym )
788         fprintf(stdout,"No symbol \"%s\" in current context.\n", s);
789     return bp;
790 }
791
792 static int printAsmLine( function *func, module *m, long saddr, long eaddr)
793 {
794     int i,j,delta;
795     int symaddr;
796     int lastaddr = saddr+1;
797     char *symname;
798
799     if ( func )
800     {
801         symaddr = func->sym->addr;
802         symname = func->sym->name;
803     }
804     else
805     {
806         symaddr = saddr;
807         symname = "" ;
808     }
809     for (j=0,i=0; i < m->nasmLines; i++ ) 
810     {
811         if ( saddr >= 0 && m->asmLines[i]->addr < saddr)
812         {
813                 continue;
814         }
815         if ( eaddr >= 0 && m->asmLines[i]->addr > eaddr)
816         {
817                 continue;
818         }
819         if ( func && 
820             (m->asmLines[i]->addr < func->sym->addr ||
821              m->asmLines[i]->addr > func->sym->eaddr ))
822         {
823             continue;
824         } 
825         delta = m->asmLines[i]->addr - symaddr;
826         if ( delta >= 0 )
827         {
828             j++;
829             lastaddr = m->asmLines[i]->addr;
830             printf("0x%08x <%s",lastaddr,symname);
831             if (delta > 0) printf("+%d",delta);
832             printf(">:\t%s",m->asmLines[i]->src);            
833         }
834     }
835     return lastaddr;
836 }
837
838 /*-----------------------------------------------------------------*/
839 /* cmdDisasm - disassemble  asm instruction                        */
840 /*-----------------------------------------------------------------*/
841 static int cmdDisasm (char *s, context *cctxt, int args)
842 {
843     function *func = NULL;
844     long  saddr = -1;
845     long  eaddr = -1;
846     int   found = 0;
847     module *modul;
848     /* white space skip */
849
850     if ( args > 0 )
851     {
852         while (*s && isspace(*s)) s++;
853
854         if ( isdigit(*s))
855         {
856             saddr = strtol(s,&s,0);
857             if ( args > 1 )
858             {
859                 while (*s && isspace(*s)) s++;
860
861                 if ( isdigit(*s))
862                     eaddr = strtol(s,0,0);
863             }
864             else
865                 eaddr = saddr+1;
866         }
867     }
868
869     if ( eaddr == -1 )
870     {       
871         /* no start or only start so dump function */
872         if ( saddr == -1 )
873         {
874             func = cctxt->func;
875         }
876         else
877         {
878             applyToSet(functions,funcInAddr,saddr,&func);
879         }
880         if ( func )
881         {
882             printf("Dump of assembler code for function %s:\n",func->sym->name);
883             printAsmLine(func,func->mod,-1,-1);
884             printf("End of assembler dump.\n");
885             return 0; 
886         }
887         else
888         {
889             if (applyToSet(modules,moduleLineWithAddr,saddr,&modul,NULL))
890             {
891                 eaddr = saddr + 5;
892                 printf("Dump of assembler code:\n");
893                 printAsmLine(NULL,modul,saddr,eaddr);
894                 printf("End of assembler dump.\n");
895                 return 0; 
896             }
897         }
898     }
899     else
900     {
901         if ( args > 1 )
902             printf("Dump of assembler code from 0x%08x to 0x%08x:\n",saddr,eaddr);
903         found = 0;
904         while ( saddr < eaddr )
905         {
906             func = NULL;
907             if (applyToSet(functions,funcInAddr,saddr,&func))
908             {
909                 found = 1;
910                 modul = func->mod;
911             }
912             else
913             {
914                 if ( found )
915                     break;
916                 if (!applyToSet(modules,moduleLineWithAddr,saddr,&modul,NULL))
917                     break;
918             }
919             saddr = printAsmLine(func,modul,saddr,eaddr) + 1;
920         }
921         if( saddr >= eaddr)
922         {
923             if ( args > 1 )
924                 printf("End of assembler dump.\n");
925             return 0; 
926         }
927         
928     }
929     fprintf(stderr,"No function contains specified address.\n");
930     return 0; 
931 }
932 /*-----------------------------------------------------------------*/
933 /* cmdDisasm1 - disassemble one asm instruction                    */
934 /*-----------------------------------------------------------------*/
935 int cmdDisasm1 (char *s, context *cctxt)
936 {
937     return cmdDisasm( s, cctxt, 1);
938 }
939
940 /*-----------------------------------------------------------------*/
941 /* cmdDisasmF - disassemble asm instructions                       */
942 /*-----------------------------------------------------------------*/
943 int cmdDisasmF(char *s, context *cctxt)
944 {
945     return cmdDisasm( s, cctxt, 2);
946 }
947
948 static int commonSetUserBp(char *s, context *cctxt, char bpType)
949 {
950     char *bp ;
951     function *func = NULL;
952         
953     /* user break point location specification can be of the following
954        forms
955        a) <nothing>        - break point at current location
956        b) lineno           - number of the current module
957        c) filename:lineno  - line number of the given file
958        e) filename:function- function X in file Y (useful for static functions)
959        f) function         - function entry point
960        g) *addr            - break point at address 
961     */
962
963     if (!cctxt) {
964         fprintf(stdout,"No symbol table is loaded.  Use the \"file\" command.\n");
965         return 0;
966     }
967     /* white space skip */
968     while (*s && isspace(*s)) s++;
969     
970     /* null terminate it after stripping trailing blanks*/
971     bp = s + strlen(s);
972     while (bp != s && isspace(*bp)) bp--;
973     *bp = '\0';
974
975     /* case a) nothing */
976     /* if nothing given then current location : we know
977        the current execution location from the currentContext */
978     if (! *s ) {
979
980         /* if current context is known */
981         if (cctxt->func) {
982         Dprintf(D_break, ("commonSetUserBp: a) cctxtaddr:%x \n",cctxt->addr));
983             if (srcMode == SRC_CMODE)
984                 /* set the break point */
985                 setBreakPoint ( cctxt->addr , CODE , bpType , userBpCB ,
986                                 cctxt->func->mod->c_name, cctxt->cline);
987             else
988                 setBreakPoint ( cctxt->addr , CODE , bpType , userBpCB ,
989                                 cctxt->func->mod->asm_name, cctxt->asmline);
990                 
991         }
992         else
993             fprintf(stderr,"No default breakpoint address now.\n");
994                         
995         goto ret ;
996     }
997     /* case g) *addr */
998     if ( *s == '*' && isdigit(*(s+1)))
999     {
1000         int  line   = 0;
1001         long braddr = strtol(s+1,0,0);
1002         if (!applyToSet(functions,funcInAddr,braddr,&func))
1003         {
1004             module *modul;
1005             if (!applyToSet(modules,moduleLineWithAddr,braddr,&modul,&line))
1006             {
1007                 fprintf(stderr,"Address 0x%08x not exists in code.\n",braddr); 
1008             }
1009             else
1010             {
1011                 Dprintf(D_break, ("commonSetUserBp: g) addr:%x \n",braddr));
1012                 setBreakPoint ( braddr , CODE , bpType , userBpCB ,
1013                             modul->c_name,line);
1014             }
1015             goto ret ;
1016         }
1017                 else
1018         {
1019             int line = func->exitline;
1020             if ( !applyToSet(func->cfpoints,lineAtAddr,braddr,
1021                                   &line,NULL,NULL))
1022                 applyToSet(func->cfpoints,lineNearAddr,braddr,&line,NULL,NULL);
1023             setBreakPoint ( braddr , CODE , bpType , userBpCB ,
1024                             func->mod->c_name,line);
1025         }
1026         goto ret ;
1027     }
1028     /* case b) lineno */
1029     /* check if line number */
1030     if ( !strchr(s,':') && isdigit(*s)) {
1031         /* get the lineno */
1032         int line = atoi(s) -1;
1033     Dprintf(D_break, ("commonSetUserBp: b) line:%d \n",line));
1034
1035         /* if current context not present then we must get the module
1036            which has main & set the break point @ line number provided
1037            of that module : if current context known then set the bp 
1038            at the line number given for the current module 
1039         */
1040         if (cctxt->func) {
1041             if (!cctxt->func->mod) {
1042                 if (!applyToSet(functions,funcWithName,"main"))
1043                     fprintf(stderr,"Function \"main\" not defined.\n");
1044                 else 
1045                     setBPatModLine(func->mod,line, bpType);
1046             } else 
1047                 setBPatModLine(cctxt->func->mod,line, bpType);
1048         } else {
1049                 if (list_mod) {
1050                         setBPatModLine(list_mod,line, bpType);
1051                 } else {
1052                   fprintf(stdout,"Sdcdb fails to have module symbol context at %d\n", __LINE__);
1053                 }
1054         }
1055         
1056         goto ret;
1057     }
1058
1059     if ((bp = strchr(s,':'))) {
1060         
1061         module *mod = NULL;
1062         *bp = '\0';
1063         
1064         if (srcMode == SRC_CMODE) {
1065             if (!applyToSet(modules,moduleWithCName,s,&mod)) {
1066                 fprintf (stderr,"No source file named %s.\n",s);
1067                 goto ret;
1068             }
1069         } else {
1070             if (!applyToSet(modules,moduleWithAsmName,s,&mod)) {
1071                 fprintf (stderr,"No source file named %s.\n",s);
1072                 goto ret;
1073             }
1074         }
1075                 
1076         /* case c) filename:lineno */
1077         if (isdigit(*(bp +1))) {                         
1078         Dprintf(D_break, ("commonSetUserBp: c) line:%d \n",atoi(bp+1)));
1079             setBPatModLine (mod,atoi(bp+1)-1,bpType);       
1080             goto ret;
1081             
1082         }
1083         /* case d) filename:function */
1084         if (!applyToSet(functions,funcWithNameModule,bp+1,s,&func)) 
1085             fprintf(stderr,"Function \"%s\" not defined.\n",bp+1); 
1086         else        
1087         Dprintf(D_break, ("commonSetUserBp: d) \n"));
1088             setBPatModLine (mod,
1089                             (srcMode == SRC_CMODE ? 
1090                              func->entryline :
1091                              func->aentryline),bpType);
1092         
1093         goto ret;
1094     }
1095             
1096     /* case e) function */
1097     Dprintf(D_break, ("commonSetUserBp: e) \n"));
1098     if (!applyToSet(functions,funcWithName,s,&func))
1099         fprintf(stderr,"Function \"%s\" not defined.\n",s); 
1100     else
1101         setBPatModLine(func->mod,
1102                        (srcMode == SRC_CMODE ?
1103                         func->entryline :
1104                         func->aentryline),bpType);
1105
1106  ret:    
1107     return 0;
1108 }
1109
1110 /*-----------------------------------------------------------------*/
1111 /* cmdSetTmpUserBp - settempory break point at the user specified location   */
1112 /*-----------------------------------------------------------------*/
1113 int cmdSetTmpUserBp (char *s, context *cctxt)
1114 {
1115     return commonSetUserBp(s, cctxt, TMPUSER );
1116 }
1117
1118 /*-----------------------------------------------------------------*/
1119 /* cmdSetUserBp - set break point at the user specified location   */
1120 /*-----------------------------------------------------------------*/
1121 int cmdSetUserBp (char *s, context *cctxt)
1122 {
1123     return commonSetUserBp(s, cctxt, USER );
1124 }
1125
1126 /*-----------------------------------------------------------------*/
1127 /* cmdJump - set program counter                                   */
1128 /*-----------------------------------------------------------------*/
1129 int cmdJump (char *s, context *cctxt)
1130 {
1131     char *bp ;
1132     function *func = NULL;
1133     if (STACK_EMPTY(callStack)) 
1134     {
1135         fprintf(stdout,"The program is not running.\n");
1136         return 0;
1137     } 
1138
1139     /* white space skip */
1140     while (*s && isspace(*s)) s++;
1141     
1142     /* null terminate it after stripping trailing blanks*/
1143     bp = s + strlen(s);
1144     while (bp != s && isspace(*bp)) bp--;
1145     *bp = '\0';
1146     if (! *s ) 
1147     {
1148         fprintf(stdout,"No argument: need line or *addr.\n");
1149         return 0;
1150     }
1151     if ( *s == '*' && isdigit(*(s+1)))
1152     {
1153         unsigned int addr = atoi(s);
1154         if (cctxt && cctxt->func &&
1155             cctxt->func->sym->addr <= addr &&
1156             cctxt->func->sym->eaddr >= addr)
1157         {
1158             simSetPC(addr);
1159             return 0;
1160         }
1161         fprintf(stdout,"Warning addr 0x%x outside actual function.\n",addr);
1162         simSetPC(addr);
1163         return 0;
1164     }
1165     if (isdigit(*s)) 
1166     {
1167         /* get the lineno */
1168         int line = atoi(s) -1;
1169         if (!cctxt || !cctxt->func || !cctxt->func->mod) 
1170         {
1171                     fprintf(stderr,"Function not defined.\n");
1172             return 0;
1173         }
1174         if (line >= cctxt->func->entryline &&
1175             line <= cctxt->func->exitline )
1176         {
1177             simSetPC(cctxt->func->mod->cLines[line]->addr);
1178             return 0;
1179         }
1180         if (line >= cctxt->func->mod->ncLines )
1181         {
1182                     fprintf(stderr,"line not in module.\n");
1183             return 0;
1184         }
1185         fprintf(stdout,"Warning line %d outside actual function.\n",line+1);
1186         simSetPC(cctxt->func->mod->cLines[line]->addr);
1187         return 0;
1188     }
1189     if ((bp = strchr(s,':'))) 
1190     {
1191         int line;
1192         module *mod = NULL;
1193         *bp++ = '\0';
1194         if (!applyToSet(modules,moduleWithCName,s,&mod)) 
1195         {
1196             fprintf (stderr,"No source file named %s.\n",s);
1197             return 0;
1198         } 
1199         if (!isdigit(*bp)) 
1200         {                        
1201             fprintf (stderr,"No line number.\n");
1202             return 0;       
1203         }
1204         line = atoi(bp) -1;
1205         if (line >= mod->ncLines )
1206         {
1207                     fprintf(stderr,"line not in module.\n");
1208             return 0;
1209         }
1210         if ( mod != cctxt->func->mod ||
1211              line < cctxt->func->entryline ||
1212              line > cctxt->func->exitline )
1213         {
1214             fprintf(stdout,"Warning line %d outside actual function.\n",
1215                     line+1);
1216         }             
1217         simSetPC(mod->cLines[line]->addr);
1218     }
1219     return 0;
1220 }
1221
1222 /*-----------------------------------------------------------------*/
1223 /* cmdListAsm - list assembler source code                         */
1224 /*-----------------------------------------------------------------*/
1225 int cmdListAsm (char *s, context *cctxt)
1226 {
1227     if (  cctxt && cctxt->func) 
1228     {
1229         /* actual line */
1230         if (printAsmLine(cctxt->func,cctxt->func->mod,
1231                          (long)cctxt->addr,(long)cctxt->addr))
1232             return 0; 
1233     }
1234     return 0;
1235 }
1236
1237 /*-----------------------------------------------------------------*/
1238 /* cmdSetOption - set debugger options                             */
1239 /*-----------------------------------------------------------------*/
1240 int cmdSetOption (char *s, context *cctxt)
1241 {
1242     while (*s && isspace(*s)) s++;
1243     if (strncmp(s,"srcmode",7) == 0 ) {
1244         if (srcMode == SRC_CMODE)
1245             srcMode = SRC_AMODE;
1246         else
1247             srcMode = SRC_CMODE;
1248         fprintf(stderr,"source mode set to '%s'\n", 
1249                 (srcMode == SRC_CMODE ? "C" : "asm"));
1250         return 0;
1251     }
1252
1253     if (strncmp(s,"listsize ",9) == 0) 
1254     {
1255         listlines = strtol(s+9,0,0);
1256         if ( listlines < LISTLINES )
1257             listlines = LISTLINES;
1258         return 0;
1259     }
1260
1261 #ifdef SDCDB_DEBUG
1262     if (strncmp(s,"debug ",6) == 0) 
1263     {
1264         sdcdbDebug = strtol(s+6,0,0);
1265         return 0;
1266     }
1267 #endif
1268     if (strncmp(s,"variable ",9) == 0) 
1269     {
1270         symbol *sym ;
1271         int fmt;
1272         char *rs;
1273         s += 9;
1274         if ( !( rs = preparePrint(s, cctxt, &fmt, &sym )))
1275             return 0;
1276         s = rs;
1277         while (*s && *s != '=') s++;
1278         *s++ = '\0';
1279         while (isspace(*s)) *s++ = '\0';
1280         if (*s && sym)
1281         {
1282             printOrSetSymValue(sym,cctxt,0,0,0,rs,s,'\0');
1283             return 0;
1284         }
1285         else
1286             fprintf(stdout,"No new value for \"%s\".\n",s);
1287         return 0;       
1288     }
1289
1290  
1291     fprintf(stderr,"'set %s' command not yet implemented\n",s);
1292     return 0;
1293 }
1294
1295 /*-----------------------------------------------------------------*/
1296 /* cmdContinue - continue till next break point                    */
1297 /*-----------------------------------------------------------------*/
1298 int cmdContinue (char *s, context *cctxt)
1299 {
1300     if (STACK_EMPTY(callStack)) {
1301         fprintf(stdout,"The program is not being run.\n");
1302         return 0;
1303     }
1304
1305     fprintf(stdout,"Continuing.\n");
1306     simGo(-1);
1307     showfull = 1;
1308     return 0;
1309 }
1310
1311 /*-----------------------------------------------------------------*/
1312 /* cmdIgnore - set ignorecount for breakpoint                      */
1313 /*-----------------------------------------------------------------*/
1314 int cmdIgnore (char *s, context *cctxt)
1315 {   
1316     int bpnum, cnt ;
1317     while (isspace(*s)) s++;
1318     if (!*s ) 
1319     {
1320         fprintf(stdout,"Argument required (breakpoint number).\n");
1321         return 0;
1322     }
1323     bpnum = strtol(s,&s,10);
1324     while (isspace(*s)) s++;
1325     if (!*s ) 
1326     {
1327         fprintf(stdout,"Second argument (specified ignore-count) is missing.");
1328         return 0;
1329     }
1330     cnt = strtol(s,0,10);
1331     setUserbpIgnCount(bpnum,cnt);
1332     return 0;
1333 }
1334
1335 /*-----------------------------------------------------------------*/
1336 /* cmdCondition - set condition for breakpoint                     */
1337 /*-----------------------------------------------------------------*/
1338 int cmdCondition (char *s, context *cctxt)
1339 {   
1340     int bpnum ;
1341     while (isspace(*s)) s++;
1342     if (!*s ) 
1343     {
1344         fprintf(stdout,"Argument required (breakpoint number).\n");
1345         return 0;
1346     }
1347     bpnum = strtol(s,&s,10);
1348     while (isspace(*s)) s++;
1349     if (*s)
1350         s = Safe_strdup(s);
1351     else
1352         s = NULL;
1353     setUserbpCondition(bpnum,s);
1354     return 0;
1355 }
1356
1357 /*-----------------------------------------------------------------*/
1358 /* cmdCommands - set commands for breakpoint                       */
1359 /*-----------------------------------------------------------------*/
1360 int cmdCommands (char *s, context *cctxt)
1361 {   
1362     int bpnum ;
1363     char *cmds,*line;
1364     while (isspace(*s)) s++;
1365     
1366     if (!*s ) 
1367         bpnum = getLastBreakptNumber();
1368     else
1369         bpnum = strtol(s,0,10);
1370
1371     cmds = NULL;
1372     while ((line = getNextCmdLine()))
1373     {
1374         while (isspace(*line)) line++;
1375         if (!strncmp(line,"end",3))
1376             break;
1377         if (! cmds )
1378         {
1379             cmds = Safe_strdup(line);
1380         }
1381         else
1382         {
1383             cmds = Safe_realloc( cmds, strlen(cmds) + 1 + strlen(line));
1384             strcat(cmds,line);
1385         }
1386     }
1387     setUserbpCommand(bpnum,cmds);
1388     return 0;
1389 }
1390
1391 /*-----------------------------------------------------------------*/
1392 /* cmdDelUserBp - delete user break point                          */
1393 /*-----------------------------------------------------------------*/
1394 int cmdDelUserBp (char *s, context *cctxt)
1395 {
1396     int bpnum ;
1397     while (isspace(*s)) s++;
1398     
1399     if (!*s ) {
1400         if (userBpPresent) {
1401             char buffer[10];
1402             fprintf (stdout,"Delete all breakpoints? (y or n) ");
1403             fflush(stdout);
1404             fgets(buffer,sizeof(buffer),stdin);
1405             if (toupper(buffer[0]) == 'Y')
1406                 deleteUSERbp(-1);          
1407         }
1408         return 0;
1409     }
1410     
1411     /* determine the break point number */
1412     if (sscanf(s,"%d",&bpnum) == 1)
1413         deleteUSERbp(bpnum);
1414
1415     return 0;
1416 }
1417
1418 /*-----------------------------------------------------------------*/
1419 /* cmdStepi - single step exactly one instruction                   */
1420 /*-----------------------------------------------------------------*/
1421 int cmdStepi (char *s, context *cctxt)
1422 {
1423
1424     if (STACK_EMPTY(callStack))
1425         fprintf(stdout,"The program is not being run.\n");
1426     else 
1427     {
1428         doingSteps = 2;
1429             simGo(2);   
1430         doingSteps = 0;
1431         showfull = 1;
1432     }
1433     return 0;
1434 }
1435
1436 /*-----------------------------------------------------------------*/
1437 /* cmdStep - single step thru C source file                        */
1438 /*-----------------------------------------------------------------*/
1439 int cmdStep (char *s, context *cctxt)
1440 {
1441     function *func = NULL;
1442
1443     if (STACK_EMPTY(callStack))
1444         fprintf(stdout,"The program is not being run.\n");
1445     else {
1446         /* if we are @ the end of a function then set
1447            break points at execution points of the
1448            function in the call stack... */
1449         if (cctxt->addr == cctxt->func->sym->eaddr) {
1450             if ((func = STACK_PEEK(callStack))) {
1451                 if (srcMode == SRC_CMODE)
1452                     applyToSet (func->cfpoints,setStepEPBp,STEP,
1453                                 func->mod->c_name);     
1454                 else
1455                     applyToSet (func->afpoints,setStepEPBp,STEP,
1456                                 func->mod->asm_name);
1457             }
1458         } else {
1459             /* set breakpoints at all function entry points
1460                and all exepoints of this functions & for
1461                all functions one up in the call stack */
1462             
1463             /* all function entry points */
1464             applyToSet(functions,setStepBp); 
1465             
1466             if (srcMode == SRC_CMODE) {
1467                 /* for all execution points in this function */
1468                 applyToSet(cctxt->func->cfpoints,setStepEPBp,STEP,
1469                            cctxt->func->mod->c_name);
1470                 
1471                 /* set a break point @ the current function's
1472                    exit */
1473                 setBreakPoint (cctxt->func->sym->eaddr, CODE, STEP , 
1474                                stepBpCB, cctxt->func->mod->c_name, 
1475                                cctxt->func->exitline);
1476                 
1477                 /* now break point @ callers execution points */
1478                 if ((func = STACK_PPEEK(callStack))) {
1479                     applyToSet (func->cfpoints,setStepEPBp,STEP,
1480                                 func->mod->c_name);     
1481                     /* set bp @ callers exit point */
1482                     setBreakPoint (func->sym->eaddr, CODE, STEP , 
1483                                    stepBpCB, func->mod->c_name, 
1484                                    func->exitline);
1485                 }
1486             } else {
1487                 /* for all execution points in this function */
1488                 applyToSet(cctxt->func->afpoints,setStepEPBp,STEP,
1489                            cctxt->func->mod->asm_name);
1490                 
1491                 /* set a break point @ the current function's
1492                    exit */
1493                 setBreakPoint (cctxt->func->sym->eaddr, CODE, STEP , 
1494                                stepBpCB, cctxt->func->mod->asm_name, 
1495                                cctxt->func->aexitline);
1496                 
1497                 /* now break point @ callers execution points */
1498                 if ((func = STACK_PPEEK(callStack))) {
1499                     
1500                     applyToSet (func->afpoints,setStepEPBp,STEP,
1501                                 func->mod->asm_name);   
1502                     
1503                     /* set bp @ callers exit point */
1504                     setBreakPoint (func->sym->eaddr, CODE, STEP , 
1505                                    stepBpCB, func->mod->asm_name, 
1506                                    func->aexitline);
1507                 }
1508             }
1509         }
1510
1511         doingSteps = 1;
1512         simGo(2);
1513         doingSteps = 0;
1514         showfull = 1;
1515     }
1516     return 0;
1517 }
1518
1519 /*-----------------------------------------------------------------*/
1520 /* cmdNexti - next instruction but proceed function call           */
1521 /*-----------------------------------------------------------------*/
1522 int cmdNexti (char *s, context *cctxt)
1523 {
1524     if (STACK_EMPTY(callStack))
1525         fprintf(stdout,"The program is not being run.\n");
1526     else 
1527     {
1528         doingSteps = 2;
1529             simGo(1);   
1530         doingSteps = 0;
1531         showfull = 1;
1532     }   
1533     return 0;
1534 }
1535
1536 /*-----------------------------------------------------------------*/
1537 /* cmdNext - next executable C statement file                      */
1538 /*-----------------------------------------------------------------*/
1539 int cmdNext (char *s, context *cctxt)
1540 {
1541     function *func = NULL;
1542     /* next is almost the same as step except we don't
1543        we don't set break point for all function entry
1544        points */
1545     if (STACK_EMPTY(callStack))
1546         fprintf(stdout,"The program is not being run.\n");
1547     else {
1548         /* if we are @ the end of a function then set
1549            break points at execution points of the
1550            function in the call stack... */
1551         if (cctxt->addr == cctxt->func->sym->eaddr) {
1552             if ((func = STACK_PEEK(callStack))) {
1553                 if (srcMode == SRC_CMODE)
1554                     applyToSet (func->cfpoints,setStepEPBp,NEXT,
1555                                 func->mod->c_name);     
1556                 else
1557                     applyToSet (func->afpoints,setStepEPBp,NEXT,
1558                                 func->mod->asm_name);
1559             }
1560         } else {
1561             if (srcMode == SRC_CMODE) {
1562                 /* for all execution points in this function */
1563                 applyToSet(cctxt->func->cfpoints,setNextEPBp,NEXT,
1564                            cctxt->func->mod->c_name);
1565                 /* set a break point @ the current function's
1566                    exit */
1567                 setBreakPoint (cctxt->func->sym->eaddr, CODE, NEXT , 
1568                                nextBpCB, cctxt->func->mod->c_name, 
1569                                cctxt->func->exitline);
1570                 
1571                 /* now break point @ callers execution points */        
1572                 if ((func = STACK_PPEEK(callStack))) {
1573                     applyToSet (func->cfpoints,setNextEPBp,NEXT ,
1574                                 func->mod->c_name);     
1575                     /* set bp @ callers exit point */
1576                     setBreakPoint (func->sym->eaddr, CODE, NEXT , 
1577                                    stepBpCB, func->mod->c_name, 
1578                                    func->exitline);
1579                 }
1580             } else {
1581                 /* for all execution points in this function */
1582                 applyToSet(cctxt->func->afpoints,setNextEPBp,NEXT,
1583                            cctxt->func->mod->asm_name);
1584                 /* set a break point @ the current function's
1585                    exit */
1586                 setBreakPoint (cctxt->func->sym->eaddr, CODE, NEXT , 
1587                                nextBpCB, cctxt->func->mod->asm_name, 
1588                                cctxt->func->aexitline);
1589                 
1590                 /* now break point @ callers execution points */        
1591                 if ((func = STACK_PPEEK(callStack))) {
1592                     applyToSet (func->cfpoints,setNextEPBp,NEXT ,
1593                                 func->mod->asm_name);   
1594                     /* set bp @ callers exit point */
1595                     setBreakPoint (func->sym->eaddr, CODE, NEXT , 
1596                                    stepBpCB, func->mod->asm_name, 
1597                                    func->aexitline);
1598                 }
1599             }
1600         }
1601         doingSteps = 1;
1602         simGo(1);       
1603         doingSteps = 0;
1604         showfull = 1;
1605     }    
1606     return 0;
1607 }
1608
1609 /*-----------------------------------------------------------------*/
1610 /* cmdRun  - run till next break point                             */
1611 /*-----------------------------------------------------------------*/
1612 int cmdRun (char *s, context *cctxt)
1613 {
1614     char buff[10];
1615     if (STACK_EMPTY(callStack)) {
1616         fprintf(stdout,"Starting program\n");
1617     if ( ! simactive )
1618     {
1619         fprintf(stdout,"No executable file specified.\nUse the \"file\" command.\n");
1620         return 0;
1621     }
1622     resetHitCount();
1623         simGo(0);
1624     } else {
1625         
1626         fprintf(stdout,
1627                 "The program being debugged has been started already.\n");
1628         fprintf(stdout,"Start it from the beginning? (y or n) ");
1629         fflush(stdout);
1630
1631         fgets(buff,sizeof(buff),stdin);
1632         if (toupper(buff[0]) == 'Y') {
1633             simReset();
1634         resetHitCount();
1635             simGo(0);
1636         }
1637     }
1638     showfull = 1;
1639     return 0;
1640 }
1641
1642 /*-----------------------------------------------------------------
1643  cmdListSymbols - list symbols
1644 |-----------------------------------------------------------------*/
1645 int cmdListSymbols (char *s, context *cctxt)
1646 {
1647     int our_verbose = 0;
1648     symbol *sy;
1649     int i;
1650
1651     if (strstr(s, "v1")) {
1652       our_verbose = 1;
1653     } else if (strstr(s, "v2")) {
1654       our_verbose = 2;
1655     }
1656
1657     printf("[symbols]\n");
1658     sy = setFirstItem(symbols);
1659     i = 0;
1660     for (;;) {
1661       if (sy == NULL)
1662         break;
1663       if (our_verbose <= 1)
1664         printf("<%s>", sy->name);
1665
1666       if (our_verbose > 1) {
1667         printf("  %d) name:%s, size:%d, level:%d block:%d\n", i,
1668           sy->name, sy->size, sy->level, sy->block);
1669         printf("    isonstack:%d, isfunc:%d, offset:%d addr:%d\n",
1670           sy->isonstack, sy->isfunc, sy->offset, sy->addr);
1671         printf("    eaddr:%d, addr_type:%c, type:%x etype:%x\n",
1672           sy->eaddr, sy->addr_type, sy->type, sy->etype);
1673         printf("    scopetype:%c, sname:%s, rname:%s addrspace:%c\n",
1674           sy->scopetype, sy->sname, sy->rname, sy->addrspace);
1675         printf("    next:%x\n", sy->next);
1676       }
1677       ++i;
1678       sy = setNextItem(symbols);
1679     }
1680     printf("   %d symbols\n", i);
1681     return 0;
1682 }
1683
1684 /*-----------------------------------------------------------------
1685  cmdListFunctions - list functions.
1686 |-----------------------------------------------------------------*/
1687 int cmdListFunctions (char *s, context *cctxt)
1688 {
1689     function *f;
1690     int i;
1691     int our_verbose = 0;
1692
1693     if (strstr(s, "v1")) {
1694       our_verbose = 1;
1695     } else if (strstr(s, "v2")) {
1696       our_verbose = 2;
1697     }
1698
1699     printf("[functions]\n");
1700     f = setFirstItem(functions);
1701     i = 0;
1702     for (;;) {
1703       if (f == NULL)
1704         break;
1705       if (our_verbose) {
1706         printf("  %d) sym:%x, fname:%s, modName:%s, mod:%x\n", i,
1707           f->sym, f->sym->name, f->modName, f->mod);
1708         printf("    entryline:%d, aentryline:%d, exitline:%d, aexitline:%d\n",
1709                 f->entryline, f->aentryline, f->exitline, f->aexitline);
1710         printf("    cfpoints:%x, afpoints:%x, laddr:%x, lline:%d\n",
1711                 f->cfpoints, f->afpoints, f->laddr, f->lline);
1712       }
1713       else {
1714         printf("<%s>", f->modName);
1715       }
1716       ++i;
1717       f = setNextItem(functions);
1718     }
1719     printf("   %d functions\n", i);
1720     return 0;
1721 }
1722
1723 /*-----------------------------------------------------------------
1724  cmdListModules - list functions.
1725 |-----------------------------------------------------------------*/
1726 int cmdListModules (char *s, context *cctxt)
1727 {
1728     module *m;
1729     srcLine *cs, *as;
1730     int i, mi;
1731     int our_verbose = 0;
1732
1733     if (strstr(s, "v1")) {
1734       our_verbose = 1;
1735     } else if (strstr(s, "v2")) {
1736       our_verbose = 2;
1737     }
1738
1739     printf("[modules]\n");
1740     m = setFirstItem(modules);
1741     mi = 0;
1742     for (;;) {
1743       if (m == NULL)
1744         break;
1745
1746       if (our_verbose >= 0) {
1747       printf("  %d) cfullname:%s, afullname:%s, name:%s\n", ++mi,
1748         m->cfullname, m->afullname, m->name);
1749       printf("    c_name:%s, asm_name:%s, ncLines:%d, nasmLines:%d\n",
1750               m->c_name, m->asm_name, m->ncLines, m->nasmLines);
1751       printf("    cLines:%x, asmLines:%x\n",
1752               m->cLines, m->asmLines);
1753       }
1754       if (our_verbose >= 2) {
1755         if (m->ncLines) {
1756           printf("    [cLines] ");
1757           if ( our_verbose)
1758           for (i=0; i<m->ncLines; i++ ) {
1759               cs = m->cLines[i];
1760               printf("   (%d) addr:%x, block:%d, level:%d, src:%s\n",
1761                  i, cs->addr, cs->block, cs->level, cs->src);
1762           }
1763           if (!our_verbose)
1764               printf("%d records", i);
1765         }
1766         if (m->nasmLines) {
1767           printf("    [asmLines] ");
1768           if ( our_verbose)
1769           for (i=0; i<m->nasmLines; i++ ) {
1770               as = m->asmLines[i];
1771               printf("   (%d) addr:%x, block:%d, level:%d, src:%s\n",
1772                  i, as->addr, as->block, as->level, as->src);
1773           }
1774           if (!our_verbose)
1775               printf("%d records", i);
1776         }
1777         printf("\n");
1778       }
1779
1780       m = setNextItem(modules);
1781     }
1782     return 0;
1783 }
1784
1785 /*-----------------------------------------------------------------
1786  infoSymbols - This is really just a tool to dump all these
1787    huge program structures out into human readable form.
1788 |-----------------------------------------------------------------*/
1789 static void infoSymbols(context *ctxt)
1790 {
1791   int our_verbose = 0;
1792
1793   printf("[context:%x] func:%x modName:%s addr:%x\n",
1794     ctxt, ctxt->func, ctxt->modName, ctxt->addr);
1795
1796   printf("  cline:%d asmline:%d block:%d level:%d\n",
1797     ctxt->cline, ctxt->asmline, ctxt->level);
1798
1799   printf("[globals] currCtxt:%x, modules:%x, functions:%x symbols:%x\n",
1800     currCtxt, modules, functions, symbols);
1801   printf("  nStructs:%d, structs:%x, ssdirl:%s\n",
1802     nStructs, structs, ssdirl);
1803
1804   /**************** modules *******************/
1805   {
1806     module *m;
1807     srcLine *cs, *as;
1808     int i, mi;
1809     printf("[modules]\n");
1810     m = setFirstItem(modules);
1811     mi = 0;
1812     for (;;) {
1813       if (m == NULL)
1814         break;
1815       printf("  %d) cfullname:%s, afullname:%s, name:%s\n", ++mi,
1816         m->cfullname, m->afullname, m->name);
1817       printf("    c_name:%s, asm_name:%s, ncLines:%d, nasmLines:%d\n",
1818               m->c_name, m->asm_name, m->ncLines, m->nasmLines);
1819       printf("    cLines:%x, asmLines:%x\n",
1820               m->cLines, m->asmLines);
1821       i = 0;
1822       if (m->cLines) {
1823         cs = m->cLines[i++];
1824         printf("    [cLines] ");
1825         while (cs) {
1826           if (our_verbose)
1827             printf("   (%d) addr:%x, block:%d, level:%d, src:%s\n",
1828                i, cs->addr, cs->block, cs->level, cs->src);
1829           cs = m->cLines[i++];
1830         }
1831         if (!our_verbose)
1832             printf("%d records", i);
1833       }
1834       i = 0;
1835       if (m->asmLines) {
1836         as = m->asmLines[i++];
1837         printf("    [asmLines] ");
1838         while (as) {
1839           if (our_verbose)
1840             printf("   (%d) addr:%x, block:%d, level:%d, src:%s\n",
1841                i, as->addr, as->block, as->level, as->src);
1842           as = m->asmLines[i++];
1843         }
1844         if (!our_verbose)
1845             printf("%d records", i);
1846       }
1847       printf("\n");
1848
1849       m = setNextItem(modules);
1850     }
1851   }
1852
1853   /**************** functions *******************/
1854   {
1855     function *f;
1856     int i;
1857     printf("[functions]\n");
1858     f = setFirstItem(functions);
1859     i = 0;
1860     for (;;) {
1861       if (f == NULL)
1862         break;
1863       if (our_verbose) {
1864         printf("  %d) sym:%x, modName:%s, mod:%x\n", i,
1865           f->sym, f->modName, f->mod);
1866         printf("    entryline:%d, aentryline:%d, exitline:%d, aexitline:%d\n",
1867                 f->entryline, f->aentryline, f->exitline, f->aexitline);
1868         printf("    cfpoints:%x, afpoints:%x, laddr:%x, lline:%d\n",
1869                 f->cfpoints, f->afpoints, f->laddr, f->lline);
1870       }
1871       ++i;
1872       f = setNextItem(functions);
1873     }
1874     if (!our_verbose)
1875       printf("   %d functions\n", i);
1876   }
1877
1878   /**************** symbols *******************/
1879   {
1880     symbol *s;
1881     int i;
1882     printf("[symbols]\n");
1883     s = setFirstItem(symbols);
1884     i = 0;
1885     for (;;) {
1886       if (s == NULL)
1887         break;
1888       if (our_verbose) {
1889         printf("  %d) name:%s, size:%d, level:%d block:%d\n", i,
1890           s->name, s->size, s->level, s->block);
1891         printf("    isonstack:%d, isfunc:%d, offset:%d addr:%d\n",
1892           s->isonstack, s->isfunc, s->offset, s->addr);
1893         printf("    eaddr:%d, addr_type:%c, type:%x etype:%x\n",
1894           s->eaddr, s->addr_type, s->type, s->etype);
1895         printf("    scopetype:%c, sname:%s, rname:%s addrspace:%c\n",
1896           s->scopetype, s->sname, s->rname, s->addrspace);
1897         printf("    next:%x\n", s->next);
1898       }
1899       ++i;
1900       s = setNextItem(symbols);
1901     }
1902     if (!our_verbose)
1903       printf("   %d symbols\n", i);
1904   }
1905
1906 }
1907
1908 /*-----------------------------------------------------------------*/
1909 /* infoRegisters - print register information                      */
1910 /*-----------------------------------------------------------------*/
1911 static void infoRegisters( int all, context *ctxt)
1912 {
1913     static unsigned int regaddrs[] = {0x81,0x82,0x83,0xb8,0xd0,0xe0,0xf0,0};
1914     unsigned long val;
1915     int i,j,*r;
1916
1917     i   = simGetValue (0xd0,'I',1);
1918     fprintf(stdout,"IP  : 0x%04X  RegisterBank %d:\nR0-7:",ctxt->addr,(i>>3)&3);
1919     for ( j = 0; j < 8 ; j++ )
1920     {
1921         val = simGetValue (j ,'R',1);
1922         fprintf(stdout," 0x%02X",val);
1923     }
1924     fprintf(stdout,"\n");
1925     val = simGetValue (0xe0,'I',1);
1926     fprintf(stdout,"ACC : 0x%02X %d %c\n",val,val,(isprint(val) ? val : '.'));
1927     val = simGetValue (0xf0,'I',1);
1928     fprintf(stdout,"B   : 0x%02X %d %c\n",val,val,(isprint(val) ? val : '.'));
1929     val = simGetValue (0x82,'I',2);
1930     fprintf(stdout,"DPTR: 0x%04X %d\n",val,val);
1931     val = simGetValue (0x81,'I',1);
1932     fprintf(stdout,"SP  : 0x%02X\n",val);
1933     fprintf(stdout,"PSW : 0x%02X | CY : %c | AC : %c | OV : %c | P : %c\n",
1934             i,(i&0x80)?'1':'0',(i&0x40)?'1':'0',(i&4)?'1':'0',(i&1)?'1':'0');
1935     if ( all )
1936     {
1937         fprintf(stdout,"Special Function Registers:\n");
1938         r = regaddrs;
1939         for ( i = 0x80 ; i < 0x100 ; i++ )
1940         {
1941             symbol *sym = NULL;
1942             if ( *r && *r == i )
1943             {
1944                 /* skip normal registers */
1945                 r++ ;
1946                 continue;
1947             }
1948             if (applyToSetFTrue(sfrsymbols,symWithAddr,i,'I',&sym))
1949             {
1950                 val = simGetValue (sym->addr,sym->addrspace,sym->size);
1951                 fprintf(stdout,"%s : 0x%02x",sym->name,val);
1952                 if ( !(i & 0x07 ))
1953                 {
1954                     for ( j = 0 ; j < 8 ; j++ )
1955                     {
1956                         sym = NULL;
1957                         if (applyToSetFTrue(sfrsymbols,symWithAddr,i+j,'J',&sym))
1958                         {
1959                             //val = simGetValue (sym->addr,sym->addrspace,sym->size);
1960                             fprintf(stdout," %s=%c",sym->name,(val&1)? '1':'0');
1961                         }
1962                         val >>= 1;
1963                     }
1964                 }
1965                 fprintf(stdout,"\n");
1966             }
1967         }
1968     }
1969 }
1970
1971 /*-----------------------------------------------------------------*/
1972 /* infoStack - print call stack information                        */
1973 /*-----------------------------------------------------------------*/
1974 static void infoStack(context *ctxt)
1975 {
1976     function *func ;
1977     int i = 0 ;
1978
1979     STACK_STARTWALK(callStack) ;
1980     while ((func = STACK_WALK(callStack))) {
1981     Dprintf(D_break, ("break: infoStack: %s %p (%p)\n",func->sym->name, w_callStack,p_callStack));
1982
1983         fprintf(stdout,"#%d  0x%08x in %s () at %s:%d\n",i++,
1984                 func->laddr,func->sym->name,
1985                 func->mod->c_name,func->lline+1);
1986     }
1987     if ( !i )
1988         fprintf(stdout,"no stack.\n");
1989 }
1990
1991 /*-----------------------------------------------------------------*/
1992 /* cmdWhere -  where command                                       */
1993 /*-----------------------------------------------------------------*/
1994 int cmdWhere(char *s, context *cctxt)
1995 {
1996         infoStack(cctxt);
1997         return 0;
1998 }
1999
2000
2001 static int infomode = 0;
2002 /*-----------------------------------------------------------------*/
2003 /* cmdInfo - info command                                          */
2004 /*-----------------------------------------------------------------*/
2005 int cmdInfo (char *s, context *cctxt)
2006 {
2007     while (isspace(*s)) s++;
2008
2009     /* list all break points */
2010     if (strncmp(s,"break",5) == 0) {
2011         listUSERbp();
2012         return 0;
2013     }
2014
2015     /* info frame same as frame */
2016     if (strcmp(s,"frame") == 0) {
2017         cmdFrame (s,cctxt);
2018         return 0;
2019     }
2020
2021     if (strncmp(s,"line",4) == 0) {
2022     infomode=1;
2023         cmdListSrc (s+4,cctxt);
2024         return 0;
2025     }
2026     if (strncmp(s,"source",6) == 0) 
2027     {
2028         module *m;
2029         if ( s[6] == 's' )
2030         {
2031             int k = 0;
2032             fprintf(stdout,"Source files for which symbols have been read in:\n\n");
2033             for (m = setFirstItem(modules); m ; m = setNextItem(modules))
2034             {
2035                 fprintf(stdout,"%s%s, %s",k ? ", ":"",m->cfullname, m->afullname); 
2036                 k = 1;
2037             }
2038             fprintf(stdout,"\n"); 
2039         }
2040         else
2041         {
2042             if (!cctxt || !cctxt->func || !cctxt->func->mod) 
2043             {
2044                 fprintf(stdout,"No source file loaded\n");
2045                 return 0;
2046             }
2047             m = cctxt->func->mod;
2048             fprintf(stdout,"Current source file is %s\n",m->c_name);
2049             fprintf(stdout,"Located in %s\n",m->cfullname);
2050             fprintf(stdout,"Contains %d lines.\nSource language is c.\n",
2051                     m->ncLines);
2052         }
2053         return 0;
2054     }
2055     if (strncmp(s,"functions",7) == 0) 
2056     {
2057         function *f;
2058         module *m = NULL;
2059         fprintf(stdout,"All defined functions:\n");
2060         for ( f = setFirstItem(functions); f ; f = setNextItem(functions))
2061         {
2062             if ( f->mod != m )
2063             {
2064                 m = f->mod;
2065                 fprintf(stdout,"\nFile %s\n", m->c_name);
2066             }
2067             fprintf(stdout,"%s();\n",f->sym->name);
2068         }
2069         return 0;
2070     }
2071     /* info stack display call stack */
2072     if (strcmp(s,"stack") == 0) {
2073         infoStack(cctxt);
2074     showfull = 1;
2075         return 0;
2076     }
2077
2078     /* info stack display call stack */
2079     if (strcmp(s,"registers") == 0) {
2080         infoRegisters(0,cctxt);
2081             return 0;
2082     }
2083
2084     /* info stack display call stack */
2085     if (strcmp(s,"all-registers") == 0) 
2086     {
2087         infoRegisters(1,cctxt);
2088         return 0;
2089     }
2090
2091     /* info stack display call stack */
2092     if (strcmp(s,"symbols") == 0) {
2093       /* dump out symbols we have read in */
2094       fprintf(stdout,"Dumping symbols...\n");
2095       infoSymbols(cctxt);
2096       return 0;
2097     }
2098
2099     if (strcmp(s,"variables") == 0) {
2100       /* dump out symbols we have read in */
2101       fprintf(stdout,"Dumping symbols...\n");
2102       infoSymbols(cctxt);
2103       return 0;
2104     }
2105
2106     fprintf(stdout,"Undefined info command: \"%s\".  Try \"help\n",s);
2107     return 0;
2108
2109 }
2110
2111 /*-----------------------------------------------------------------*/
2112 /* cmdQuit  - quit debugging                                       */
2113 /*-----------------------------------------------------------------*/
2114 int cmdQuit (char *s, context *cctxt)
2115 {   
2116     if (simactive)
2117         closeSimulator();
2118     return 1;
2119 }
2120
2121 /*-----------------------------------------------------------------*/
2122 /* cmdListSrc  - list src                                          */
2123 /*-----------------------------------------------------------------*/
2124 int cmdListSrc (char *s, context *cctxt)
2125 {   
2126     static int currline = 0;
2127     int i =0 ;
2128     int pline = 0;
2129     int llines = listlines;
2130     function *func = NULL;
2131
2132
2133     while (*s && isspace(*s)) s++;
2134     
2135     /* if the user has spcified line numer then the line number
2136        can be of the following formats
2137        LINE          - just line number
2138        FILE:LINE     - filename line number
2139        FILE:LINE,LASTLINE  + last line
2140        FUNCTION      - list a function
2141        FILE:FUNCTION - function in file */
2142
2143     if (*s) {
2144         /* case a) LINE */
2145         if (isdigit(*s)) {
2146             if (!cctxt || !cctxt->func || !cctxt->func->mod) {
2147               if (!list_mod) {
2148                 fprintf(stdout,"Sdcdb fails to have a proper context at %d.\n", __LINE__);
2149                 return 0;
2150               }
2151             }
2152             else
2153               list_mod = cctxt->func->mod;
2154         pline = strtol(s,&s,10) - 1;
2155         if (s && (s = strchr(s,','))) 
2156         {
2157             /* LINE,LASTLINE */
2158             llines = strtol(s+1,0,10); 
2159             if ( llines > 0 )
2160                 llines -= pline+1;
2161             else
2162                 llines = listlines;
2163         }
2164         }
2165         else {
2166             char *bp;
2167             
2168             /* if ':' present then FILE:LINE || FILE:FUNCTION */
2169             if ((bp = strchr(s,':'))) {
2170                 *bp = '\0';
2171                 bp ++;
2172                 if (isdigit(*bp)) {
2173                     /* FILE:LINE */
2174                     list_mod=NULL;  /* bug fix 2-09-02, moduleWithCName expects mod to be null */
2175                     if (srcMode == SRC_CMODE) {
2176                         if (!applyToSet(modules,moduleWithCName,s,&list_mod)) {
2177                             fprintf (stderr,"No c source file named %s.\n",s);
2178                             return 0;
2179                         }
2180                     } else {
2181                         if (!applyToSet(modules,moduleWithAsmName,s,&list_mod)) {
2182                             fprintf (stderr,"No source file named %s.\n",s);
2183                             return 0;
2184                         }
2185                     }
2186                     pline = strtol(bp,&bp,10) - 1;
2187             if (bp && (bp = strchr(bp,','))) 
2188             {
2189                 /* FILE:LINE,LASTLINE */
2190                 llines = strtol(bp+1,0,10); 
2191                 if ( llines > 0 )
2192                     llines -= pline+1;
2193                 else
2194                     llines = listlines;
2195             }
2196                 } else {
2197                     /* FILE:FUCTION */
2198                     if (!applyToSet(functions,funcWithNameModule,bp,s,&func)) {
2199                         fprintf(stdout,"Function \"%s\" not defined.\n",bp);
2200                         return 0;
2201                     }
2202                     list_mod = func->mod;
2203                     if (srcMode == SRC_CMODE) {
2204                         pline = func->entryline;
2205                         llines = func->exitline - func->entryline + 1;
2206                     } else {
2207                         pline = func->aentryline;
2208                         llines = func->aexitline - func->aentryline + 1;
2209                     }
2210                 }
2211             }
2212             else {
2213                 /* FUNCTION */
2214             if (*s == '\'') 
2215             {
2216                 /* 'FUNCTION' */
2217                 s++ ;
2218                 if ((bp = strrchr(s,'\''))) 
2219                 {
2220                     *bp = '\0';
2221                 }
2222                 
2223             }
2224                 if (!applyToSet(functions,funcWithName,s,&func)) {
2225                     fprintf(stderr,"Function \"%s\" not defined.\n",s); 
2226                     return 0;
2227                 }
2228                 else {
2229                     list_mod = func->mod;
2230                     if (srcMode == SRC_CMODE) {
2231                         pline = func->entryline;
2232                         llines = func->exitline - func->entryline + 1; 
2233                     } else {
2234                         pline = func->aentryline;
2235                         llines = func->aexitline - func->aentryline + 1; 
2236                     }
2237                 }
2238             }
2239         }
2240     } else {
2241         /* if no line specified & we had listed
2242            before then continue from that listing */
2243         if (currline)
2244             pline = currline ;
2245         else {
2246             if (!cctxt || !cctxt->func || !cctxt->func->mod) {
2247               fprintf(stdout,"Missing context at %d. Try list filename:lineno\n", __LINE__);
2248               return 0;
2249             }
2250             list_mod = cctxt->func->mod;
2251             if (srcMode == SRC_CMODE)
2252                 pline = cctxt->cline;
2253             else
2254                 pline = cctxt->asmline;
2255         }
2256     }
2257
2258     if (!list_mod) {
2259       fprintf(stdout,"Sdcdb fails to have a valid module context at %d.\n", __LINE__);
2260       return 0;
2261     }
2262
2263     if ( pline < 0 )
2264         return 0;
2265     if ( infomode )
2266     {
2267         int firstaddr , lastaddr ;
2268             if ( pline  >= list_mod->ncLines )
2269             pline = cctxt->cline;
2270         firstaddr = lastaddr = list_mod->cLines[pline]->addr;
2271         if (!func && cctxt && cctxt->func )
2272             func = cctxt->func;
2273             fprintf(stdout,"Line %d of \"%s\" starts at address 0x%08x <%s+%d>", 
2274                 pline+1,
2275                 list_mod->c_name, lastaddr,
2276                 func ? func->sym->name : "?",
2277                 func ? lastaddr -func->sym->addr : 0);
2278         llines = pline +1;
2279         while ( pline < list_mod->ncLines )
2280         {
2281             pline++;
2282             if ( list_mod->cLines[pline]->addr > lastaddr )
2283             {
2284                 lastaddr = list_mod->cLines[pline]->addr -1;
2285                 break;
2286             }
2287         }
2288         fprintf(stdout," and ends at 0x%08x <%s+%d>.\n", 
2289                 lastaddr,
2290                 func ? func->sym->name : "?",
2291                 func ? lastaddr -func->sym->addr : 0);
2292         infomode=0;
2293         if ( func )
2294             fprintf(stdout,"\032\032%s:%d:1:beg:0x%08x\n",
2295                     func->mod->cfullname,
2296                     llines,firstaddr);
2297         else
2298             showfull=1;
2299         return 0;
2300     }
2301     for ( i = 0 ; i < llines ; i++ ) {
2302         if (srcMode == SRC_CMODE) {
2303             if ( (pline + i) >= list_mod->ncLines )
2304                 break;
2305             fprintf(stdout,"%d\t%s",pline + i,
2306                     list_mod->cLines[pline +i]->src);
2307         } else {
2308             if ( (pline + i) >= list_mod->nasmLines )
2309                 break;
2310             fprintf(stdout,"%d\t%s",pline + i,
2311                     list_mod->asmLines[pline +i]->src);
2312         }
2313     }
2314     currline = pline + i ;
2315     return 0;
2316 }
2317
2318 static unsigned long getValBasic(symbol *sym, link *type, char *val)
2319 {
2320     char *s;
2321     union 
2322     {   
2323         float f;     
2324         unsigned long val;
2325         long         sval;
2326         struct {
2327             unsigned short    lo;
2328             unsigned short    hi;
2329         } i;
2330         unsigned char b[4];
2331     }v;
2332
2333     if (IS_FLOAT(type))         
2334         v.f = strtod(val,NULL);    
2335     else
2336         if (IS_PTR(type))
2337             v.val = strtol(val,NULL,0);
2338         else
2339     {
2340             if (IS_INTEGRAL(type)) 
2341         {
2342             link *etype;
2343             if ( type->next )
2344                 etype = type->next;
2345             else
2346                 etype = type;
2347             if (IS_CHAR(etype))
2348             {
2349                 if (( s = strchr(val,'\'')))
2350                 {
2351                     if ( s[1] == '\\' )
2352                         v.b[0] = strtol(s+2,NULL,8);
2353                     else 
2354                         v.b[0] = s[1];
2355                 }
2356                 else
2357                 {
2358                     v.b[0] = strtol(val,NULL,0);
2359                 }
2360             }
2361             else
2362                 if (IS_INT(etype)) 
2363                     if (IS_LONG(etype))
2364                         v.val = strtol(val,NULL,0);
2365                     else
2366                         v.i.lo = strtol(val,NULL,0);
2367                 else
2368                     v.val = strtol(val,NULL,0);
2369             } 
2370         else
2371             v.val = strtol(val,NULL,0);
2372     }
2373     return v.val;
2374 }
2375
2376 /*-----------------------------------------------------------------*/
2377 /* printFmtInteger - print value in bin,oct,dez or hex             */
2378 /*-----------------------------------------------------------------*/
2379 static void printFmtInteger(char *deffmt,int fmt, long val, 
2380                             int sign, int size)
2381 {
2382     static char digits[] = 
2383     {
2384         '0' , '1' , '2' , '3' , '4' , '5' ,
2385         '6' , '7' , '8' , '9' , 'a' , 'b' ,
2386         'c' , 'd' , 'e' , 'f' , 'g' , 'h' 
2387     };
2388     static int radixOfFormat[] = { 0 , 2, 8 ,10, 16  };
2389     static int olenOfSize[]    = { 0 , 3, 6 , 8, 11  };
2390         char buf[40];
2391         char negative = 0;
2392         int charPos = 38;
2393     int radix;
2394
2395     if ( fmt == FMT_NON || fmt == FMT_DEZ )
2396     {
2397         fprintf(stdout,deffmt,val);
2398         return;
2399     }
2400     radix = radixOfFormat[fmt];
2401
2402     /*
2403     if ( sign && val < 0 )
2404         negative = 1;
2405     */
2406
2407         if (!negative)
2408             val = -val;
2409
2410         buf[39] = '\0';
2411     while (val <= -radix) 
2412     {
2413             buf[charPos--] = digits[-(val % radix)];
2414             val = val / radix;
2415         }
2416         buf[charPos] = digits[-val];
2417
2418     switch ( fmt )
2419     {
2420         case FMT_OCT:
2421             radix = olenOfSize[size];
2422             break;
2423         case FMT_HEX:
2424             radix = size << 1;
2425             break;
2426         case FMT_BIN:
2427             radix = size << 3;
2428             break;
2429     }
2430
2431     while (charPos > 39 - radix )
2432     {
2433         buf[--charPos] = '0';
2434     } 
2435     switch ( fmt )
2436     {
2437         case FMT_OCT:
2438             if ( buf[charPos] != '0' )
2439                 buf[--charPos] = '0';
2440             break;
2441         case FMT_HEX:
2442             buf[--charPos] = 'x';
2443             buf[--charPos] = '0';
2444             break;
2445     }
2446         if (negative) {
2447             buf[--charPos] = '-';
2448         }
2449     fputs(&buf[charPos],stdout);
2450 }
2451
2452 /*-----------------------------------------------------------------*/
2453 /* printValBasic - print value of basic types                      */
2454 /*-----------------------------------------------------------------*/
2455 static void printValBasic(symbol *sym, link *type,
2456                           char mem, unsigned addr,int size, int fmt)
2457 {
2458     union {     
2459         float f;     
2460         unsigned long val;
2461         long         sval;
2462         struct {
2463             unsigned short    lo;
2464             unsigned short    hi;
2465         } i;
2466         unsigned char b[4];
2467     }v;
2468     union {
2469         unsigned char b[4];
2470     }v1;
2471     
2472     v.val = simGetValue(addr,mem,size);
2473     /* if this a floating point number then */
2474     if (IS_FLOAT(type))         
2475         fprintf(stdout,"%f",v.f);    
2476     else
2477         if (IS_PTR(type))
2478             fprintf(stdout,"0x%*x",size<<1,v.val);
2479         else
2480         if (IS_INTEGRAL(type)) 
2481         {
2482             link *etype;
2483             if ( type->next )
2484                 etype = type->next;
2485             else
2486                 etype = type;
2487             if (IS_CHAR(etype))
2488             { 
2489                 if ( isprint(v.val))
2490                     printFmtInteger((SPEC_USIGN(etype)?"0x%02x":"'%c'"),
2491                                     fmt,(long)v.val,0,size);
2492                 else
2493                     printFmtInteger((SPEC_USIGN(etype)?"0x%02x":"'\\%o'"),
2494                                     fmt,(long)v.val,0,size);
2495             }
2496             else
2497             {
2498                 if (IS_INT(etype)) 
2499                     if (IS_LONG(etype))
2500                         if (SPEC_USIGN(etype))
2501                             printFmtInteger("%u",fmt,(long)v.val,0,size);
2502                         else
2503                             printFmtInteger("%d",fmt,(long)v.sval,1,size);
2504                     else
2505                         if (SPEC_USIGN(etype))
2506                             printFmtInteger("%u",fmt,(long)v.i.lo,0,size);
2507                         else
2508                             printFmtInteger("%d",fmt,(long)v.i.lo,1,size);
2509                 else
2510                 {
2511                     if (IS_BITVAR(etype))
2512                         fprintf(stdout,"%c",(v.val?'1':'0'));
2513                     else
2514                         fprintf(stdout,"0x%0*x",size<<1,v.val);
2515                 }
2516             }
2517             } else
2518             fprintf(stdout,"0x%0*x",size<<1,v.val);  
2519 }
2520
2521 /*-----------------------------------------------------------------*/
2522 /* printValFunc  - prints function values                          */
2523 /*-----------------------------------------------------------------*/
2524 static void printValFunc (symbol *sym, int fmt)
2525 {
2526     fprintf(stdout,"print function not yet implemented");
2527 }
2528
2529 /*-----------------------------------------------------------------*/
2530 /* printArrayValue - will print the values of array elements       */
2531 /*-----------------------------------------------------------------*/
2532 static void printArrayValue (symbol *sym,  link *type,
2533                              char space, unsigned int addr, int fmt)
2534 {
2535         link *elem_type = type->next;
2536         int i;
2537         
2538         fprintf(stdout,"{");
2539         for (i = 0 ; i < DCL_ELEM(type) ; i++) {                
2540                 if (IS_AGGREGATE(elem_type)) {
2541                         printValAggregates(sym,elem_type,space,addr,fmt);                      
2542                 } else {
2543                         printValBasic(sym,elem_type,space,addr,getSize(elem_type),fmt);
2544                 }
2545                 addr += getSize(elem_type);
2546                 if (i != DCL_ELEM(type) -1)
2547                         fprintf(stdout,",");
2548         }
2549
2550         fprintf(stdout,"}");            
2551 }
2552
2553 /*-----------------------------------------------------------------*/
2554 /* printStructValue - prints structures elements                   */
2555 /*-----------------------------------------------------------------*/
2556 static void printStructValue (symbol *sym, link *type, 
2557                               char space, unsigned int addr, int fmt) 
2558 {
2559         symbol *fields = SPEC_STRUCT(type)->fields;
2560     int first = 1;
2561         fprintf(stdout," { ");
2562         while (fields) {
2563                 fprintf(stdout,"%s%s = ",(first ? "": ", "),fields->name);
2564                 first = 0;
2565         if (IS_AGGREGATE(fields->type)) {
2566                         printValAggregates(fields,fields->type,space, addr, fmt);
2567                 } else {
2568                         printValBasic(fields,fields->type,space,addr,getSize(fields->type), fmt);
2569                 }
2570                 addr += getSize(fields->type);
2571                 fields = fields->next;
2572         }
2573         fprintf(stdout,"}");
2574 }
2575
2576 /*-----------------------------------------------------------------*/
2577 /* printValAggregates - print value of aggregates                  */
2578 /*-----------------------------------------------------------------*/
2579 static void printValAggregates (symbol *sym, link *type,
2580                                 char space,unsigned int addr, int fmt)
2581 {
2582
2583         if (IS_ARRAY(type)) {
2584                 printArrayValue(sym, type, space, addr, fmt);
2585                 return ;
2586         }
2587
2588         if (IS_STRUCT(type)) { 
2589                 printStructValue(sym, type, space, addr, fmt); 
2590                 return; 
2591         } 
2592 }
2593
2594 /*-----------------------------------------------------------------*/
2595 /* printOrSetSymValue - print or set value of a symbol             */
2596 /*-----------------------------------------------------------------*/
2597 static int printOrSetSymValue (symbol *sym, context *cctxt, 
2598                                 int flg, int dnum, int fmt, char *rs, 
2599                                 char *val, char cmp )
2600 {
2601     static char fmtChar[] = " todx ";
2602     static int stack = 1;
2603         symbol *fields;
2604     link *type;
2605     unsigned int  addr; 
2606     int size, n;
2607     char *s, *s2;
2608     char save_ch, save_ch2;
2609
2610     /* if it is on stack then compute address & fall thru */
2611     if (sym->isonstack) 
2612     {
2613         symbol *bp = symLookup("bp",cctxt);
2614         if (!bp) 
2615         {
2616             fprintf(stdout,"cannot determine stack frame\n");
2617             return 1;
2618         }
2619
2620         sym->addr = simGetValue(bp->addr,bp->addrspace,bp->size)
2621             + sym->offset ;      
2622     }
2623     
2624     /* get the value from the simulator and
2625        print it */
2626     switch (flg)
2627     {
2628         case 0: 
2629         default:
2630             break;
2631         case 1: 
2632             fprintf(stdout,"$%d = ",stack++);
2633             break;
2634         case 2: 
2635             fprintf(stdout,"%d: ", dnum);
2636             if ( fmt != FMT_NON )
2637                 fprintf(stdout,"/%c ",fmtChar[fmt]);
2638             fprintf(stdout,"%s%s = ",sym->name,rs);
2639             break;
2640     }
2641
2642     addr = sym->addr;
2643     type = sym->type;
2644     size = sym->size;
2645
2646     while ( *rs )
2647     {
2648         if ( *rs == '[' && IS_ARRAY(type))
2649         {
2650             s = rs+1;
2651             while ( *rs && *rs != ']' ) rs++ ;
2652             save_ch = *rs;
2653             *rs = '\0' ;
2654             if ( ! isdigit(*s ))
2655             {
2656                 /* index seems a variable */
2657                 for ( s2 = s; *s2 && ( isalnum( *s2 ) || *s2 == '_'); s2++ );
2658                 save_ch2 = *s2;
2659                 if ( *s2 )
2660                     *s2 = '\0';
2661                 fields = symLookup(s,cctxt);
2662                 *s2 = save_ch2;
2663                 if ( ! fields )
2664                 {
2665                     fprintf(stdout,"Unknown variable \"%s\" for index.\n", s);
2666                     return 1;                    
2667                 }
2668                 /* arrays & structures first */
2669                 if (! IS_INTEGRAL(fields->type))
2670                 {
2671                     fprintf(stdout,"Wrong type of variable \"%s\" for index \n", s);
2672                     return 1;                    
2673                 }
2674                 n = simGetValue(fields->addr,fields->addrspace,getSize(fields->type));
2675             }
2676             else
2677             {
2678                 n = strtol(s,0,0);
2679             }
2680             if ( n < 0 || n >= DCL_ELEM(type))
2681             {
2682                 fprintf(stdout,"Wrong index %d.\n", n);
2683                 return 1;                    
2684             }
2685             type = type->next;
2686             size = getSize(type);
2687             addr += size * n;
2688             *rs++ = save_ch;
2689         }
2690         else if ( *rs == '.' && IS_STRUCT(type))
2691         {
2692             s = rs+1;
2693             /* search structure element */
2694             for ( rs = s; *rs && ( isalnum( *rs ) || *rs == '_'); rs++ );
2695             save_ch = *rs;
2696             if ( *rs )
2697                 *rs = '\0';
2698             for (fields = SPEC_STRUCT(type)->fields; fields; fields = fields->next) 
2699             {
2700                 if (!(strcmp(s,fields->name)))
2701                     break;
2702             }
2703             *rs = save_ch;
2704             if ( ! fields )
2705             {
2706                 fprintf(stdout,"Unknown field \"%s\" of structure\n", s);
2707                 return 1;                    
2708             }
2709             type = fields->type;
2710             size = getSize(type);
2711             addr += fields->offset;
2712         }
2713         else
2714             break;
2715     }
2716
2717     /* arrays & structures first */
2718     if (IS_AGGREGATE(type))
2719     {
2720             if ( val )
2721         {
2722             fprintf(stdout,"Cannot set/compare aggregate variable\n");
2723             return 1;
2724         }
2725         else
2726             printValAggregates(sym,type,sym->addrspace,addr,fmt);
2727     }
2728     else
2729         /* functions */
2730         if (IS_FUNC(type))
2731     {
2732             if ( !val )
2733             printValFunc(sym,fmt);
2734         else
2735             return 1;
2736     }
2737         else
2738     { 
2739             if ( val )
2740         {
2741             unsigned long newval;
2742             newval = getValBasic(sym,type,val);
2743
2744             if ( cmp )
2745             {
2746                 unsigned long lval;
2747                 lval = simGetValue(addr,sym->addrspace,size);
2748                 switch ( cmp )
2749                 {
2750                     case '<' : return ( lval <  newval ? 1:0 ); break;
2751                     case '>' : return ( lval >  newval ? 1:0 ); break;
2752                     case 'l' : return ( lval <= newval ? 1:0 ); break;
2753                     case 'g' : return ( lval >= newval ? 1:0 ); break;
2754                     case '=' : return ( lval == newval ? 1:0 ); break;
2755                     case '!' : return ( lval != newval ? 1:0 ); break;
2756                 }
2757             }
2758             else
2759             {
2760                 if ( sym->addrspace == 'I' && addr == 0xb8 )
2761                 {
2762                     /* Symbol with address of IP */
2763                     if ( cctxt ) cctxt->addr = newval;
2764                     simSetPC(cctxt->addr); 
2765                 }
2766                 else
2767                     simSetValue(addr,sym->addrspace,size,newval);       
2768                 return 1;
2769             }
2770         }
2771         else
2772             printValBasic(sym,type,sym->addrspace,addr,size,fmt);
2773     }
2774     if ( flg > 0 ) fprintf(stdout,"\n");
2775         return 0;
2776 }
2777
2778 /*-----------------------------------------------------------------*/
2779 /* printStructInfo - print out structure information               */
2780 /*-----------------------------------------------------------------*/
2781 static void printStructInfo (structdef *sdef)
2782 {
2783     symbol *field = sdef->fields ;
2784     int i = 0 ;
2785     
2786     while (field) {
2787         i += field->offset;
2788         field = field->next;
2789     }
2790
2791     fprintf(stdout,"%s %s {\n",(i ? "struct" : "union" ), sdef->tag);
2792     field = sdef->fields;
2793     while (field) {
2794         printTypeInfo (field->type);
2795         fprintf(stdout," %s ;\n",field->name);
2796         field = field->next ;
2797     }
2798
2799     fprintf(stdout,"}\n");
2800
2801 }
2802
2803 /*-----------------------------------------------------------------*/
2804 /* printTypeInfo - print out the type information                  */
2805 /*-----------------------------------------------------------------*/
2806 static void printTypeInfo(link *p)
2807 {
2808     if (!p)
2809         return ;
2810
2811     if (IS_DECL(p)) {
2812         switch (DCL_TYPE(p))  {
2813         case FUNCTION:
2814             printTypeInfo (p->next);
2815             fprintf(stdout,"()");
2816             break;
2817         case ARRAY:
2818             printTypeInfo (p->next);
2819             fprintf(stdout,"[%d]",DCL_ELEM(p));
2820             break;
2821         
2822         case IPOINTER:
2823         case PPOINTER:
2824         case POINTER:
2825             printTypeInfo (p->next);
2826             fprintf(stdout,"(_near *)");
2827             break;
2828
2829         case FPOINTER:
2830             printTypeInfo (p->next);
2831             fprintf(stdout,"(_xdata *)");
2832             break;
2833
2834         case CPOINTER:
2835             printTypeInfo( p->next);
2836             fprintf(stdout,"(_code *)");
2837             break;
2838             
2839         case GPOINTER:
2840             printTypeInfo( p->next);
2841             fprintf(stdout,"(_generic *)");
2842             break;                   
2843         }
2844     } else {
2845         switch (SPEC_NOUN(p)) { /* depending on the specifier type */
2846         case V_INT:
2847             (IS_LONG(p) ? fputs("long ",stdout) : 
2848              ( IS_SHORT(p) ? fputs("short ",stdout) : 
2849                fputs("int ",stdout))) ;
2850             break;
2851         case V_FLOAT:
2852              fputs("float ",stdout);
2853              break;
2854
2855         case V_CHAR:
2856             fputs ("char ",stdout);
2857             break;
2858
2859         case V_VOID:
2860             fputs("void ",stdout);
2861             break;
2862
2863         case V_STRUCT:
2864             printStructInfo (SPEC_STRUCT(p));
2865             break;
2866
2867         case V_SBIT:
2868             fputs("sbit ",stdout);
2869             break;
2870
2871         case V_BIT:
2872             fprintf(stdout,": %d" ,SPEC_BLEN(p));       
2873             break;
2874         }
2875     }
2876 }
2877
2878 /*-----------------------------------------------------------------*/
2879 /* conditionIsTrue - compare variable with constant value        */
2880 /*-----------------------------------------------------------------*/
2881 int conditionIsTrue( char *s, context *cctxt)
2882 {   
2883     symbol *sym = NULL;
2884     int fmt;
2885     char *rs, *dup, cmp_char;
2886     dup = s = Safe_strdup(s);
2887     if ( !( rs = preparePrint(s, cctxt, &fmt, &sym )) || !sym)
2888         fmt = 1;
2889     else if (!( s =  strpbrk(rs,"<>=!")))
2890         fmt = 1;
2891     else
2892     {
2893         cmp_char = *s;    
2894         *s++ = '\0';
2895         if ( *s == '=' )
2896         {
2897             /* if <= or >= an other char is used 
2898              * == or !=  not checked in switch 
2899              */
2900             switch( cmp_char )
2901             {
2902                 case '>': cmp_char = 'g' ; break;
2903                 case '<': cmp_char = 'l' ; break;
2904             }
2905             s++ ;
2906         }
2907         while (isspace(*s)) *s++ = '\0';
2908         fmt = printOrSetSymValue(sym,cctxt,0,0,0,rs,s,cmp_char);
2909     }
2910     Safe_free(dup);
2911     return fmt;
2912 }
2913
2914 /*-----------------------------------------------------------------*/
2915 /* cmdPrint - print value of variable                              */
2916 /*-----------------------------------------------------------------*/
2917 int cmdPrint (char *s, context *cctxt)
2918 {   
2919     symbol *sym ;
2920     int fmt;
2921     char *rs;
2922     if ( !( rs = preparePrint(s, cctxt, &fmt, &sym )))
2923         return 0;
2924
2925     if ( sym ) 
2926     {
2927         printOrSetSymValue(sym,cctxt,1,0,fmt,rs,NULL,'\0');
2928     } 
2929     return 0;
2930 }
2931
2932 /*-----------------------------------------------------------------*/
2933 /* cmdOutput - print value of variable without number and newline  */
2934 /*-----------------------------------------------------------------*/
2935 int cmdOutput (char *s, context *cctxt)
2936 {   
2937     symbol *sym ;
2938     int fmt;
2939     char *rs;
2940     if ( !( rs = preparePrint(s, cctxt, &fmt, &sym )))
2941         return 0;
2942
2943     if ( sym ) 
2944     {
2945         printOrSetSymValue(sym,cctxt,0,0,fmt,rs,NULL,'\0');
2946     } 
2947     return 0;
2948 }
2949
2950 /** find display entry with this number */
2951
2952 DEFSETFUNC(dsymWithNumber)
2953 {
2954     dsymbol *dsym = item;
2955     V_ARG(int , dnum);
2956     V_ARG(dsymbol **,dsymp);
2957
2958     if ( dsym->dnum == dnum )
2959     {
2960         *dsymp = dsym;
2961         return 1;
2962     }
2963     return 0;
2964 }
2965
2966 /*-----------------------------------------------------------------*/
2967 /* displayAll  - display all valid variables                       */
2968 /*-----------------------------------------------------------------*/
2969 void displayAll(context *cctxt)
2970 {
2971     dsymbol *dsym;
2972     symbol  *sym;
2973     if ( !dispsymbols )
2974         return;
2975     for (dsym = setFirstItem(dispsymbols);
2976          dsym ;
2977          dsym = setNextItem(dispsymbols)) 
2978     {
2979         if ( (sym = symLookup(dsym->name,cctxt)))
2980             printOrSetSymValue(sym,cctxt,2,dsym->dnum,dsym->fmt,
2981                                dsym->rs,NULL,'\0');
2982     }
2983 }
2984
2985 /*-----------------------------------------------------------------*/
2986 /* cmdDisplay  - display value of variable                         */
2987 /*-----------------------------------------------------------------*/
2988 int cmdDisplay (char *s, context *cctxt)
2989 {   
2990     static int dnum = 1;
2991     symbol *sym ;
2992     int fmt;
2993     char *rs;
2994     if ( !( rs = preparePrint(s, cctxt, &fmt, &sym )))
2995     {
2996         displayAll(cctxt);
2997         return 0;
2998     }
2999
3000     if ( sym ) 
3001     {
3002         dsymbol *dsym = (dsymbol *)Safe_calloc(1,sizeof(dsymbol));
3003         dsym->dnum = dnum++ ;
3004         dsym->name = sym->name;
3005         dsym->fmt  = fmt;
3006         dsym->rs   = gc_strdup(rs);
3007         addSetHead(&dispsymbols,dsym);
3008     }
3009     return 0;
3010 }
3011
3012 /*-----------------------------------------------------------------*/
3013 /* cmdUnDisplay  - undisplay value of variable                              */
3014 /*-----------------------------------------------------------------*/
3015 int cmdUnDisplay (char *s, context *cctxt)
3016 {   
3017     dsymbol *dsym;
3018     int dnum;
3019
3020     while (isspace(*s)) s++;
3021     if (!*s)
3022     {
3023         for (dsym = setFirstItem(dispsymbols);
3024              dsym;
3025              dsym = setNextItem(dispsymbols))
3026         {
3027             Safe_free(dsym->rs);
3028             Safe_free(dsym); 
3029         }
3030         deleteSet(&dispsymbols);
3031         return 0;
3032     }
3033     while ( s && *s )
3034     {
3035         dnum = strtol(s,&s,10);
3036         if (applyToSetFTrue(dispsymbols,dsymWithNumber,dnum,&dsym)) 
3037         {
3038             deleteSetItem(&dispsymbols,dsym);
3039             Safe_free(dsym->rs);
3040             Safe_free(dsym); 
3041         } 
3042         else
3043         {
3044             fprintf(stdout,"Arguments must be display numbers.\n");    
3045         }
3046     }
3047     return 0;
3048 }
3049
3050 /*-----------------------------------------------------------------*/
3051 /* cmdPrintType - print type of a variable                         */
3052 /*-----------------------------------------------------------------*/
3053 int cmdPrintType (char *s, context *cctxt)
3054 {   
3055         symbol *sym ;
3056     char *bp = s+strlen(s) -1;
3057
3058     while (isspace(*s)) s++;
3059     if (!*s) return 0;
3060     while (isspace(*bp)) bp--;
3061     bp++ ;
3062     *bp = '\0';
3063
3064     if ((sym = symLookup(s,cctxt))) {
3065         printTypeInfo(sym->type);
3066         fprintf(stdout,"\n");
3067     } else {
3068         fprintf(stdout,
3069                 "No symbol \"%s\" in current context.\n",
3070                 s);
3071     }
3072     return 0;   
3073 }
3074
3075 /*-----------------------------------------------------------------*/
3076 /* cmdClrUserBp - clear user break point                           */
3077 /*-----------------------------------------------------------------*/
3078 int cmdClrUserBp (char *s, context *cctxt)
3079 {   
3080     char *bp ;    
3081     function *func = NULL;
3082         
3083     /* clear break point location specification can be of the following
3084        forms
3085        a) <nothing>        - break point at current location
3086        b) lineno           - number of the current module
3087        c) filename:lineno  - line number of the given file
3088        e) filename:function- function X in file Y (useful for static functions)
3089        f) function         - function entry point
3090     */
3091
3092     if (!cctxt) {
3093         fprintf(stdout,"No symbol table is loaded.  Use the \"file\" command.\n");
3094         return 0;
3095     }
3096
3097     /* white space skip */
3098     while (*s && isspace(*s)) s++;
3099     
3100     /* null terminate it after stripping trailing blanks*/
3101     bp = s + strlen(s);
3102     while (bp != s && isspace(*bp)) bp--;
3103     *bp = '\0';
3104
3105     /* case a) nothing */
3106     /* if nothing given then current location : we know
3107        the current execution location from the currentContext */
3108     if (! *s ) {
3109
3110         /* if current context is known */
3111         if (cctxt->func) 
3112             /* clear the break point @ current location */
3113             clearUSERbp (cctxt->addr);
3114         else
3115             fprintf(stderr,"No default breakpoint address now.\n");
3116                         
3117         goto ret ;
3118     }
3119
3120     /* case b) lineno */
3121     /* check if line number */
3122     if (isdigit(*s)) {
3123         /* get the lineno */
3124         int line = atoi(s);
3125
3126         /* if current context not present then we must get the module
3127            which has main & set the break point @ line number provided
3128            of that module : if current context known then set the bp 
3129            at the line number given for the current module 
3130         */
3131         if (cctxt->func) {
3132             if (!cctxt->func->mod) {
3133                 if (!applyToSet(functions,funcWithName,"main"))
3134                     fprintf(stderr,"Function \"main\" not defined.\n");
3135                 else 
3136                     clearBPatModLine(func->mod,line);
3137             } else 
3138                 clearBPatModLine(cctxt->func->mod,line);                        
3139         }
3140         
3141         goto ret;
3142     }
3143
3144     if ((bp = strchr(s,':'))) {
3145         
3146         module *mod = NULL;
3147         *bp = '\0';
3148         
3149         if (!applyToSet(modules,moduleWithCName,s,&mod)) {
3150             fprintf (stderr,"No source file named %s.\n",s);
3151             goto ret;
3152         }
3153
3154         /* case c) filename:lineno */
3155         if (isdigit(*(bp +1))) {                    
3156          
3157             clearBPatModLine (mod,atoi(bp+1));      
3158             goto ret;
3159             
3160         }
3161         /* case d) filename:function */
3162         if (!applyToSet(functions,funcWithNameModule,bp+1,s,&func)) 
3163             fprintf(stderr,"Function \"%s\" not defined.\n",bp+1); 
3164         else
3165             clearBPatModLine (mod,func->entryline);
3166         
3167         goto ret;
3168     }
3169             
3170     /* case e) function */
3171     if (!applyToSet(functions,funcWithName,s,&func))
3172         fprintf(stderr,"Function \"%s\" not defined.\n",s); 
3173     else
3174         clearBPatModLine(func->mod,func->entryline);
3175
3176  ret:    
3177     return 0;        
3178 }
3179
3180 /*-----------------------------------------------------------------*/
3181 /* cmdSimulator - send command to simulator                        */
3182 /*-----------------------------------------------------------------*/
3183 int cmdSimulator (char *s, context *cctxt)
3184 {   
3185   char tmpstr[82];
3186
3187     if (strlen(s) > 80) {
3188       printf("error 3A\n");
3189       exit(1);
3190     }
3191     strcpy(tmpstr, s);
3192     strcat(tmpstr, "\n");
3193     sendSim(tmpstr);
3194     waitForSim(200,NULL);
3195     fprintf(stdout,"%s",simResponse());
3196     return 0;
3197 }
3198
3199 void setMainContext()
3200 {
3201     function *func = NULL;
3202     currentFrame = 0; 
3203     if (!applyToSet(functions,funcWithName,"main",&func) &&
3204         !applyToSet(functions,funcWithName,"_main",&func))
3205         return;
3206
3207     discoverContext (func->sym->addr, func);
3208 }
3209     
3210 static void printFrame()
3211 {
3212     int i;
3213     function *func     = NULL;
3214     function *lastfunc = NULL;
3215
3216     if ( currentFrame < 0 )
3217     {
3218         currentFrame = 0;
3219         fprintf(stdout,"Bottom (i.e., innermost) frame selected; you cannot go down.\n");
3220         return;
3221     }
3222     STACK_STARTWALK(callStack) ;
3223     for ( i = 0; i <= currentFrame ; i++ )
3224     {
3225         func = STACK_WALK(callStack);
3226         if ( !func )
3227         {
3228             currentFrame = i-1;
3229             fprintf(stdout,"Initial frame selected; you cannot go up.\n");
3230             return;
3231         }
3232     }
3233     fprintf(stdout,"#%d  0x%08x in %s () at %s:%d\n",
3234             currentFrame,func->laddr,func->sym->name,func->mod->c_name,func->lline+1);
3235     fprintf(stdout,"\032\032%s:%d:1:beg:0x%08x\n",
3236             func->mod->cfullname,func->lline+1,func->laddr);
3237
3238     discoverContext (func->laddr, func);
3239 }
3240
3241
3242 /*-----------------------------------------------------------------*/
3243 /* cmdUp -  Up command                                             */
3244 /*-----------------------------------------------------------------*/
3245 int cmdUp(char *s, context *cctxt)
3246 {
3247     while (isspace(*s)) s++;
3248     if ( *s )
3249         currentFrame += strtol(s,0,10);
3250     else
3251         currentFrame++ ;
3252
3253     printFrame();
3254         return 0;
3255 }
3256
3257 /*-----------------------------------------------------------------*/
3258 /* cmdDown - down command                                          */
3259 /*-----------------------------------------------------------------*/
3260 int cmdDown(char *s, context *cctxt)
3261 {
3262     while (isspace(*s)) s++;
3263     if ( *s )
3264         currentFrame -= strtol(s,0,10);
3265     else
3266         currentFrame-- ;
3267
3268     printFrame();
3269         return 0;
3270 }
3271 /*-----------------------------------------------------------------*/
3272 /* cmdFrame - Frame command                                        */
3273 /*-----------------------------------------------------------------*/
3274 int cmdFrame (char *s, context *cctxt)
3275 {   
3276     function *func = NULL;
3277     int i, framenr = 0;
3278
3279     while (isspace(*s)) s++;
3280     if ( *s )
3281         currentFrame = strtol(s,0,10);
3282     printFrame();
3283     return 0;
3284 }
3285
3286 /*-----------------------------------------------------------------*/
3287 /* cmdFinish - exec till end of current function                   */
3288 /*-----------------------------------------------------------------*/
3289 int cmdFinish (char *s, context *ctxt)
3290 {
3291     if (STACK_EMPTY(callStack)) {
3292         fprintf(stdout,"The program is not running.\n");
3293         return 0;
3294     }
3295
3296     if (srcMode == SRC_CMODE) {
3297         setBreakPoint (ctxt->func->sym->eaddr, CODE, STEP, 
3298                        stepBpCB, ctxt->func->mod->c_name, 
3299                        ctxt->func->exitline);
3300     } else {
3301         setBreakPoint (ctxt->func->sym->eaddr, CODE, STEP, 
3302                        stepBpCB, ctxt->func->mod->asm_name, 
3303                        ctxt->func->aexitline);
3304     }
3305
3306     simGo(-1);
3307     showfull = 1;
3308     return 0;
3309     
3310 }
3311
3312
3313 /*-----------------------------------------------------------------*/
3314 /* cmdShow - show command                                          */
3315 /*-----------------------------------------------------------------*/
3316 int cmdShow (char *s, context *cctxt)
3317 {
3318     /* skip white space */
3319     while (*s && isspace(*s)) s++ ;
3320
3321     if (strcmp(s,"copying") == 0) {
3322         fputs(copying,stdout);
3323         return 0;
3324     }
3325     
3326     if (strcmp(s,"warranty") == 0) {
3327         fputs(warranty,stdout);
3328         return 0;
3329     }
3330
3331     return 0;
3332 }
3333