check now pop stack result
[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 = -1;
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     if ( gaddr == 0 )
711     {
712         function *func = NULL;;
713         if (applyToSet(functions,funcInAddr,gaddr,&func))
714             STACK_PUSH(callStack,func);
715     }
716     addr = simGoTillBp (gaddr);
717
718     /* got the pc for the break point now first
719        discover the program context i.e. module, function 
720        linenumber of the source etc, etc etc */
721     currentFrame = 0; 
722     ctxt = discoverContext (addr, NULL);
723     
724     /* dispatch all the break point call back functions */
725     rv = dispatchCB (addr,ctxt);    
726  ret:    
727
728     /* the dispatch call back function will return
729        non-zero if an user break point has been hit
730        if not then we continue with the execution 
731        of the program */
732     if (!rv) 
733     {
734         if ( gaddr == 0 )
735             gaddr = -1;
736         if ( gaddr == -1 || doingSteps == 1 )
737             goto top ;
738     }
739     
740 }
741
742 /*-----------------------------------------------------------------*/
743 /* preparePrint - common parse function for  set variable,         */
744 /*                output, print and display                        */
745 /*-----------------------------------------------------------------*/
746 static char *preparePrint(char *s, context *cctxt, int *fmt, symbol **sym)
747 {
748     char *bp = s+strlen(s) -1;
749     char save_ch ;
750
751     *fmt = FMT_NON;
752     *sym = NULL;
753
754     while (isspace(*s)) s++;
755     if (!*s) 
756         return (char *)0;
757
758     while (isspace(*bp)) bp--;
759     bp++ ;
760     *bp = '\0';
761
762     if ( *s == '/' )
763     {
764         /* format of printout */
765         switch ( *++s )
766         {
767             case 'x':
768                 *fmt = FMT_HEX ;
769                 break;
770             case 'o':
771                 *fmt = FMT_OCT ;
772                 break;
773             default:
774             case 'd':
775                 *fmt = FMT_DEZ ;
776                 break;
777             case 't':
778                 *fmt = FMT_BIN ;
779                 break;
780         }
781         s++;
782         while (isspace(*s)) s++;
783     }
784     for ( bp = s; *bp && ( isalnum( *bp ) || *bp == '_' || *bp == '$'); bp++ );
785     save_ch = *bp;
786     if ( *bp )
787         *bp = '\0';
788
789     if ( *s )
790         *sym = symLookup(s,cctxt);
791     *bp = save_ch;
792
793     if ( ! *sym )
794         fprintf(stdout,"No symbol \"%s\" in current context.\n", s);
795     return bp;
796 }
797
798 static int printAsmLine( function *func, module *m, long saddr, long eaddr)
799 {
800     int i,j,delta;
801     int symaddr;
802     int lastaddr = saddr+1;
803     char *symname;
804
805     if ( func )
806     {
807         symaddr = func->sym->addr;
808         symname = func->sym->name;
809     }
810     else
811     {
812         symaddr = saddr;
813         symname = "" ;
814     }
815     for (j=0,i=0; i < m->nasmLines; i++ ) 
816     {
817         if ( saddr >= 0 && m->asmLines[i]->addr < saddr)
818         {
819                 continue;
820         }
821         if ( eaddr >= 0 && m->asmLines[i]->addr > eaddr)
822         {
823                 continue;
824         }
825         if ( func && 
826             (m->asmLines[i]->addr < func->sym->addr ||
827              m->asmLines[i]->addr > func->sym->eaddr ))
828         {
829             continue;
830         } 
831         delta = m->asmLines[i]->addr - symaddr;
832         if ( delta >= 0 )
833         {
834             j++;
835             lastaddr = m->asmLines[i]->addr;
836             printf("0x%08x <%s",lastaddr,symname);
837             if (delta > 0) printf("+%d",delta);
838             printf(">:\t%s",m->asmLines[i]->src);            
839         }
840     }
841     return lastaddr;
842 }
843
844 /*-----------------------------------------------------------------*/
845 /* cmdDisasm - disassemble  asm instruction                        */
846 /*-----------------------------------------------------------------*/
847 static int cmdDisasm (char *s, context *cctxt, int args)
848 {
849     function *func = NULL;
850     long  saddr = -1;
851     long  eaddr = -1;
852     int   found = 0;
853     module *modul;
854     /* white space skip */
855
856     if ( args > 0 )
857     {
858         while (*s && isspace(*s)) s++;
859
860         if ( isdigit(*s))
861         {
862             saddr = strtol(s,&s,0);
863             if ( args > 1 )
864             {
865                 while (*s && isspace(*s)) s++;
866
867                 if ( isdigit(*s))
868                     eaddr = strtol(s,0,0);
869             }
870             else
871                 eaddr = saddr+1;
872         }
873     }
874
875     if ( eaddr == -1 )
876     {       
877         /* no start or only start so dump function */
878         if ( saddr == -1 )
879         {
880             func = cctxt->func;
881         }
882         else
883         {
884             applyToSet(functions,funcInAddr,saddr,&func);
885         }
886         if ( func )
887         {
888             printf("Dump of assembler code for function %s:\n",func->sym->name);
889             printAsmLine(func,func->mod,-1,-1);
890             printf("End of assembler dump.\n");
891             return 0; 
892         }
893         else
894         {
895             if (applyToSet(modules,moduleLineWithAddr,saddr,&modul,NULL))
896             {
897                 eaddr = saddr + 5;
898                 printf("Dump of assembler code:\n");
899                 printAsmLine(NULL,modul,saddr,eaddr);
900                 printf("End of assembler dump.\n");
901                 return 0; 
902             }
903         }
904     }
905     else
906     {
907         if ( args > 1 )
908             printf("Dump of assembler code from 0x%08x to 0x%08x:\n",saddr,eaddr);
909         found = 0;
910         while ( saddr < eaddr )
911         {
912             func = NULL;
913             if (applyToSet(functions,funcInAddr,saddr,&func))
914             {
915                 found = 1;
916                 modul = func->mod;
917             }
918             else
919             {
920                 if ( found )
921                     break;
922                 if (!applyToSet(modules,moduleLineWithAddr,saddr,&modul,NULL))
923                     break;
924             }
925             saddr = printAsmLine(func,modul,saddr,eaddr) + 1;
926         }
927         if( saddr >= eaddr)
928         {
929             if ( args > 1 )
930                 printf("End of assembler dump.\n");
931             return 0; 
932         }
933         
934     }
935     fprintf(stderr,"No function contains specified address.\n");
936     return 0; 
937 }
938 /*-----------------------------------------------------------------*/
939 /* cmdDisasm1 - disassemble one asm instruction                    */
940 /*-----------------------------------------------------------------*/
941 int cmdDisasm1 (char *s, context *cctxt)
942 {
943     return cmdDisasm( s, cctxt, 1);
944 }
945
946 /*-----------------------------------------------------------------*/
947 /* cmdDisasmF - disassemble asm instructions                       */
948 /*-----------------------------------------------------------------*/
949 int cmdDisasmF(char *s, context *cctxt)
950 {
951     return cmdDisasm( s, cctxt, 2);
952 }
953
954 static int commonSetUserBp(char *s, context *cctxt, char bpType)
955 {
956     char *bp ;
957     function *func = NULL;
958         
959     /* user break point location specification can be of the following
960        forms
961        a) <nothing>        - break point at current location
962        b) lineno           - number of the current module
963        c) filename:lineno  - line number of the given file
964        e) filename:function- function X in file Y (useful for static functions)
965        f) function         - function entry point
966        g) *addr            - break point at address 
967     */
968
969     if (!cctxt) {
970         fprintf(stdout,"No symbol table is loaded.  Use the \"file\" command.\n");
971         return 0;
972     }
973     /* white space skip */
974     while (*s && isspace(*s)) s++;
975     
976     /* null terminate it after stripping trailing blanks*/
977     bp = s + strlen(s);
978     while (bp != s && isspace(*bp)) bp--;
979     *bp = '\0';
980
981     /* case a) nothing */
982     /* if nothing given then current location : we know
983        the current execution location from the currentContext */
984     if (! *s ) {
985
986         /* if current context is known */
987         if (cctxt->func) {
988         Dprintf(D_break, ("commonSetUserBp: a) cctxtaddr:%x \n",cctxt->addr));
989             if (srcMode == SRC_CMODE)
990                 /* set the break point */
991                 setBreakPoint ( cctxt->addr , CODE , bpType , userBpCB ,
992                                 cctxt->func->mod->c_name, cctxt->cline);
993             else
994                 setBreakPoint ( cctxt->addr , CODE , bpType , userBpCB ,
995                                 cctxt->func->mod->asm_name, cctxt->asmline);
996                 
997         }
998         else
999             fprintf(stderr,"No default breakpoint address now.\n");
1000                         
1001         goto ret ;
1002     }
1003     /* case g) *addr */
1004     if ( *s == '*' && isdigit(*(s+1)))
1005     {
1006         int  line   = 0;
1007         long braddr = strtol(s+1,0,0);
1008         if (!applyToSet(functions,funcInAddr,braddr,&func))
1009         {
1010             module *modul;
1011             if (!applyToSet(modules,moduleLineWithAddr,braddr,&modul,&line))
1012             {
1013                 fprintf(stderr,"Address 0x%08x not exists in code.\n",braddr); 
1014             }
1015             else
1016             {
1017                 Dprintf(D_break, ("commonSetUserBp: g) addr:%x \n",braddr));
1018                 setBreakPoint ( braddr , CODE , bpType , userBpCB ,
1019                             modul->c_name,line);
1020             }
1021             goto ret ;
1022         }
1023                 else
1024         {
1025             int line = func->exitline;
1026             if ( !applyToSet(func->cfpoints,lineAtAddr,braddr,
1027                                   &line,NULL,NULL))
1028                 applyToSet(func->cfpoints,lineNearAddr,braddr,&line,NULL,NULL);
1029             setBreakPoint ( braddr , CODE , bpType , userBpCB ,
1030                             func->mod->c_name,line);
1031         }
1032         goto ret ;
1033     }
1034     /* case b) lineno */
1035     /* check if line number */
1036     if ( !strchr(s,':') && isdigit(*s)) {
1037         /* get the lineno */
1038         int line = atoi(s) -1;
1039     Dprintf(D_break, ("commonSetUserBp: b) line:%d \n",line));
1040
1041         /* if current context not present then we must get the module
1042            which has main & set the break point @ line number provided
1043            of that module : if current context known then set the bp 
1044            at the line number given for the current module 
1045         */
1046         if (cctxt->func) {
1047             if (!cctxt->func->mod) {
1048                 if (!applyToSet(functions,funcWithName,"main"))
1049                     fprintf(stderr,"Function \"main\" not defined.\n");
1050                 else 
1051                     setBPatModLine(func->mod,line, bpType);
1052             } else 
1053                 setBPatModLine(cctxt->func->mod,line, bpType);
1054         } else {
1055                 if (list_mod) {
1056                         setBPatModLine(list_mod,line, bpType);
1057                 } else {
1058                   fprintf(stdout,"Sdcdb fails to have module symbol context at %d\n", __LINE__);
1059                 }
1060         }
1061         
1062         goto ret;
1063     }
1064
1065     if ((bp = strchr(s,':'))) {
1066         
1067         module *mod = NULL;
1068         *bp = '\0';
1069         
1070         if (srcMode == SRC_CMODE) {
1071             if (!applyToSet(modules,moduleWithCName,s,&mod)) {
1072                 fprintf (stderr,"No source file named %s.\n",s);
1073                 goto ret;
1074             }
1075         } else {
1076             if (!applyToSet(modules,moduleWithAsmName,s,&mod)) {
1077                 fprintf (stderr,"No source file named %s.\n",s);
1078                 goto ret;
1079             }
1080         }
1081                 
1082         /* case c) filename:lineno */
1083         if (isdigit(*(bp +1))) {                         
1084         Dprintf(D_break, ("commonSetUserBp: c) line:%d \n",atoi(bp+1)));
1085             setBPatModLine (mod,atoi(bp+1)-1,bpType);       
1086             goto ret;
1087             
1088         }
1089         /* case d) filename:function */
1090         if (!applyToSet(functions,funcWithNameModule,bp+1,s,&func)) 
1091             fprintf(stderr,"Function \"%s\" not defined.\n",bp+1); 
1092         else        
1093         Dprintf(D_break, ("commonSetUserBp: d) \n"));
1094             setBPatModLine (mod,
1095                             (srcMode == SRC_CMODE ? 
1096                              func->entryline :
1097                              func->aentryline),bpType);
1098         
1099         goto ret;
1100     }
1101             
1102     /* case e) function */
1103     Dprintf(D_break, ("commonSetUserBp: e) \n"));
1104     if (!applyToSet(functions,funcWithName,s,&func))
1105         fprintf(stderr,"Function \"%s\" not defined.\n",s); 
1106     else
1107         setBPatModLine(func->mod,
1108                        (srcMode == SRC_CMODE ?
1109                         func->entryline :
1110                         func->aentryline),bpType);
1111
1112  ret:    
1113     return 0;
1114 }
1115
1116 /*-----------------------------------------------------------------*/
1117 /* cmdSetTmpUserBp - settempory break point at the user specified location   */
1118 /*-----------------------------------------------------------------*/
1119 int cmdSetTmpUserBp (char *s, context *cctxt)
1120 {
1121     return commonSetUserBp(s, cctxt, TMPUSER );
1122 }
1123
1124 /*-----------------------------------------------------------------*/
1125 /* cmdSetUserBp - set break point at the user specified location   */
1126 /*-----------------------------------------------------------------*/
1127 int cmdSetUserBp (char *s, context *cctxt)
1128 {
1129     return commonSetUserBp(s, cctxt, USER );
1130 }
1131
1132 /*-----------------------------------------------------------------*/
1133 /* cmdJump - set program counter                                   */
1134 /*-----------------------------------------------------------------*/
1135 int cmdJump (char *s, context *cctxt)
1136 {
1137     char *bp ;
1138     function *func = NULL;
1139     if (STACK_EMPTY(callStack)) 
1140     {
1141         fprintf(stdout,"The program is not running.\n");
1142         return 0;
1143     } 
1144
1145     /* white space skip */
1146     while (*s && isspace(*s)) s++;
1147     
1148     /* null terminate it after stripping trailing blanks*/
1149     bp = s + strlen(s);
1150     while (bp != s && isspace(*bp)) bp--;
1151     *bp = '\0';
1152     if (! *s ) 
1153     {
1154         fprintf(stdout,"No argument: need line or *addr.\n");
1155         return 0;
1156     }
1157     if ( *s == '*' && isdigit(*(s+1)))
1158     {
1159         unsigned int addr = atoi(s);
1160         if (cctxt && cctxt->func &&
1161             cctxt->func->sym->addr <= addr &&
1162             cctxt->func->sym->eaddr >= addr)
1163         {
1164             simSetPC(addr);
1165             return 0;
1166         }
1167         fprintf(stdout,"Warning addr 0x%x outside actual function.\n",addr);
1168         simSetPC(addr);
1169         return 0;
1170     }
1171     if (isdigit(*s)) 
1172     {
1173         /* get the lineno */
1174         int line = atoi(s) -1;
1175         if (!cctxt || !cctxt->func || !cctxt->func->mod) 
1176         {
1177                     fprintf(stderr,"Function not defined.\n");
1178             return 0;
1179         }
1180         if (line >= cctxt->func->entryline &&
1181             line <= cctxt->func->exitline )
1182         {
1183             simSetPC(cctxt->func->mod->cLines[line]->addr);
1184             return 0;
1185         }
1186         if (line >= cctxt->func->mod->ncLines )
1187         {
1188                     fprintf(stderr,"line not in module.\n");
1189             return 0;
1190         }
1191         fprintf(stdout,"Warning line %d outside actual function.\n",line+1);
1192         simSetPC(cctxt->func->mod->cLines[line]->addr);
1193         return 0;
1194     }
1195     if ((bp = strchr(s,':'))) 
1196     {
1197         int line;
1198         module *mod = NULL;
1199         *bp++ = '\0';
1200         if (!applyToSet(modules,moduleWithCName,s,&mod)) 
1201         {
1202             fprintf (stderr,"No source file named %s.\n",s);
1203             return 0;
1204         } 
1205         if (!isdigit(*bp)) 
1206         {                        
1207             fprintf (stderr,"No line number.\n");
1208             return 0;       
1209         }
1210         line = atoi(bp) -1;
1211         if (line >= mod->ncLines )
1212         {
1213                     fprintf(stderr,"line not in module.\n");
1214             return 0;
1215         }
1216         if ( mod != cctxt->func->mod ||
1217              line < cctxt->func->entryline ||
1218              line > cctxt->func->exitline )
1219         {
1220             fprintf(stdout,"Warning line %d outside actual function.\n",
1221                     line+1);
1222         }             
1223         simSetPC(mod->cLines[line]->addr);
1224     }
1225     return 0;
1226 }
1227
1228 /*-----------------------------------------------------------------*/
1229 /* cmdListAsm - list assembler source code                         */
1230 /*-----------------------------------------------------------------*/
1231 int cmdListAsm (char *s, context *cctxt)
1232 {
1233     if (  cctxt && cctxt->func) 
1234     {
1235         /* actual line */
1236         if (printAsmLine(cctxt->func,cctxt->func->mod,
1237                          (long)cctxt->addr,(long)cctxt->addr))
1238             return 0; 
1239     }
1240     return 0;
1241 }
1242
1243 /*-----------------------------------------------------------------*/
1244 /* cmdSetOption - set debugger options                             */
1245 /*-----------------------------------------------------------------*/
1246 int cmdSetOption (char *s, context *cctxt)
1247 {
1248     while (*s && isspace(*s)) s++;
1249     if (strncmp(s,"srcmode",7) == 0 ) {
1250         if (srcMode == SRC_CMODE)
1251             srcMode = SRC_AMODE;
1252         else
1253             srcMode = SRC_CMODE;
1254         fprintf(stderr,"source mode set to '%s'\n", 
1255                 (srcMode == SRC_CMODE ? "C" : "asm"));
1256         return 0;
1257     }
1258
1259     if (strncmp(s,"listsize ",9) == 0) 
1260     {
1261         listlines = strtol(s+9,0,0);
1262         if ( listlines < LISTLINES )
1263             listlines = LISTLINES;
1264         return 0;
1265     }
1266
1267 #ifdef SDCDB_DEBUG
1268     if (strncmp(s,"debug ",6) == 0) 
1269     {
1270         sdcdbDebug = strtol(s+6,0,0);
1271         return 0;
1272     }
1273 #endif
1274     if (strncmp(s,"variable ",9) == 0) 
1275     {
1276         symbol *sym ;
1277         int fmt;
1278         char *rs;
1279         s += 9;
1280         if ( !( rs = preparePrint(s, cctxt, &fmt, &sym )))
1281             return 0;
1282         s = rs;
1283         while (*s && *s != '=') s++;
1284         *s++ = '\0';
1285         while (isspace(*s)) *s++ = '\0';
1286         if (*s && sym)
1287         {
1288             printOrSetSymValue(sym,cctxt,0,0,0,rs,s,'\0');
1289             return 0;
1290         }
1291         else
1292             fprintf(stdout,"No new value for \"%s\".\n",s);
1293         return 0;       
1294     }
1295
1296  
1297     fprintf(stderr,"'set %s' command not yet implemented\n",s);
1298     return 0;
1299 }
1300
1301 /*-----------------------------------------------------------------*/
1302 /* cmdContinue - continue till next break point                    */
1303 /*-----------------------------------------------------------------*/
1304 int cmdContinue (char *s, context *cctxt)
1305 {
1306     if (STACK_EMPTY(callStack)) {
1307         fprintf(stdout,"The program is not being run.\n");
1308         return 0;
1309     }
1310
1311     fprintf(stdout,"Continuing.\n");
1312     simGo(-1);
1313     showfull = 1;
1314     return 0;
1315 }
1316
1317 /*-----------------------------------------------------------------*/
1318 /* cmdIgnore - set ignorecount for breakpoint                      */
1319 /*-----------------------------------------------------------------*/
1320 int cmdIgnore (char *s, context *cctxt)
1321 {   
1322     int bpnum, cnt ;
1323     while (isspace(*s)) s++;
1324     if (!*s ) 
1325     {
1326         fprintf(stdout,"Argument required (breakpoint number).\n");
1327         return 0;
1328     }
1329     bpnum = strtol(s,&s,10);
1330     while (isspace(*s)) s++;
1331     if (!*s ) 
1332     {
1333         fprintf(stdout,"Second argument (specified ignore-count) is missing.");
1334         return 0;
1335     }
1336     cnt = strtol(s,0,10);
1337     setUserbpIgnCount(bpnum,cnt);
1338     return 0;
1339 }
1340
1341 /*-----------------------------------------------------------------*/
1342 /* cmdCondition - set condition for breakpoint                     */
1343 /*-----------------------------------------------------------------*/
1344 int cmdCondition (char *s, context *cctxt)
1345 {   
1346     int bpnum ;
1347     while (isspace(*s)) s++;
1348     if (!*s ) 
1349     {
1350         fprintf(stdout,"Argument required (breakpoint number).\n");
1351         return 0;
1352     }
1353     bpnum = strtol(s,&s,10);
1354     while (isspace(*s)) s++;
1355     if (*s)
1356         s = Safe_strdup(s);
1357     else
1358         s = NULL;
1359     setUserbpCondition(bpnum,s);
1360     return 0;
1361 }
1362
1363 /*-----------------------------------------------------------------*/
1364 /* cmdCommands - set commands for breakpoint                       */
1365 /*-----------------------------------------------------------------*/
1366 int cmdCommands (char *s, context *cctxt)
1367 {   
1368     int bpnum ;
1369     char *cmds,*line;
1370     while (isspace(*s)) s++;
1371     
1372     if (!*s ) 
1373         bpnum = getLastBreakptNumber();
1374     else
1375         bpnum = strtol(s,0,10);
1376
1377     cmds = NULL;
1378     while ((line = getNextCmdLine()))
1379     {
1380         while (isspace(*line)) line++;
1381         if (!strncmp(line,"end",3))
1382             break;
1383         if (! cmds )
1384         {
1385             cmds = Safe_strdup(line);
1386         }
1387         else
1388         {
1389             cmds = Safe_realloc( cmds, strlen(cmds) + 1 + strlen(line));
1390             strcat(cmds,line);
1391         }
1392     }
1393     setUserbpCommand(bpnum,cmds);
1394     return 0;
1395 }
1396
1397 /*-----------------------------------------------------------------*/
1398 /* cmdDelUserBp - delete user break point                          */
1399 /*-----------------------------------------------------------------*/
1400 int cmdDelUserBp (char *s, context *cctxt)
1401 {
1402     int bpnum ;
1403     while (isspace(*s)) s++;
1404     
1405     if (!*s ) {
1406         if (userBpPresent) {
1407             char buffer[10];
1408             fprintf (stdout,"Delete all breakpoints? (y or n) ");
1409             fflush(stdout);
1410             fgets(buffer,sizeof(buffer),stdin);
1411             if (toupper(buffer[0]) == 'Y')
1412                 deleteUSERbp(-1);          
1413         }
1414         return 0;
1415     }
1416     
1417     /* determine the break point number */
1418     if (sscanf(s,"%d",&bpnum) == 1)
1419         deleteUSERbp(bpnum);
1420
1421     return 0;
1422 }
1423
1424 /*-----------------------------------------------------------------*/
1425 /* cmdStepi - single step exactly one instruction                   */
1426 /*-----------------------------------------------------------------*/
1427 int cmdStepi (char *s, context *cctxt)
1428 {
1429
1430     if (STACK_EMPTY(callStack))
1431         fprintf(stdout,"The program is not being run.\n");
1432     else 
1433     {
1434         doingSteps = 2;
1435             simGo(2);   
1436         doingSteps = 0;
1437         showfull = 1;
1438     }
1439     return 0;
1440 }
1441
1442 /*-----------------------------------------------------------------*/
1443 /* cmdStep - single step thru C source file                        */
1444 /*-----------------------------------------------------------------*/
1445 int cmdStep (char *s, context *cctxt)
1446 {
1447     function *func = NULL;
1448
1449     if (STACK_EMPTY(callStack))
1450         fprintf(stdout,"The program is not being run.\n");
1451     else {
1452         /* if we are @ the end of a function then set
1453            break points at execution points of the
1454            function in the call stack... */
1455         if (cctxt->addr == cctxt->func->sym->eaddr) {
1456             if ((func = STACK_PEEK(callStack))) {
1457                 if (srcMode == SRC_CMODE)
1458                     applyToSet (func->cfpoints,setStepEPBp,STEP,
1459                                 func->mod->c_name);     
1460                 else
1461                     applyToSet (func->afpoints,setStepEPBp,STEP,
1462                                 func->mod->asm_name);
1463             }
1464         } else {
1465             /* set breakpoints at all function entry points
1466                and all exepoints of this functions & for
1467                all functions one up in the call stack */
1468             
1469             /* all function entry points */
1470             applyToSet(functions,setStepBp); 
1471             
1472             if (srcMode == SRC_CMODE) {
1473                 /* for all execution points in this function */
1474                 applyToSet(cctxt->func->cfpoints,setStepEPBp,STEP,
1475                            cctxt->func->mod->c_name);
1476                 
1477                 /* set a break point @ the current function's
1478                    exit */
1479                 setBreakPoint (cctxt->func->sym->eaddr, CODE, STEP , 
1480                                stepBpCB, cctxt->func->mod->c_name, 
1481                                cctxt->func->exitline);
1482                 
1483                 /* now break point @ callers execution points */
1484                 if ((func = STACK_PPEEK(callStack))) {
1485                     applyToSet (func->cfpoints,setStepEPBp,STEP,
1486                                 func->mod->c_name);     
1487                     /* set bp @ callers exit point */
1488                     setBreakPoint (func->sym->eaddr, CODE, STEP , 
1489                                    stepBpCB, func->mod->c_name, 
1490                                    func->exitline);
1491                 }
1492             } else {
1493                 /* for all execution points in this function */
1494                 applyToSet(cctxt->func->afpoints,setStepEPBp,STEP,
1495                            cctxt->func->mod->asm_name);
1496                 
1497                 /* set a break point @ the current function's
1498                    exit */
1499                 setBreakPoint (cctxt->func->sym->eaddr, CODE, STEP , 
1500                                stepBpCB, cctxt->func->mod->asm_name, 
1501                                cctxt->func->aexitline);
1502                 
1503                 /* now break point @ callers execution points */
1504                 if ((func = STACK_PPEEK(callStack))) {
1505                     
1506                     applyToSet (func->afpoints,setStepEPBp,STEP,
1507                                 func->mod->asm_name);   
1508                     
1509                     /* set bp @ callers exit point */
1510                     setBreakPoint (func->sym->eaddr, CODE, STEP , 
1511                                    stepBpCB, func->mod->asm_name, 
1512                                    func->aexitline);
1513                 }
1514             }
1515         }
1516
1517         doingSteps = 1;
1518         simGo(2);
1519         doingSteps = 0;
1520         showfull = 1;
1521     }
1522     return 0;
1523 }
1524
1525 /*-----------------------------------------------------------------*/
1526 /* cmdNexti - next instruction but proceed function call           */
1527 /*-----------------------------------------------------------------*/
1528 int cmdNexti (char *s, context *cctxt)
1529 {
1530     if (STACK_EMPTY(callStack))
1531         fprintf(stdout,"The program is not being run.\n");
1532     else 
1533     {
1534         doingSteps = 2;
1535             simGo(1);   
1536         doingSteps = 0;
1537         showfull = 1;
1538     }   
1539     return 0;
1540 }
1541
1542 /*-----------------------------------------------------------------*/
1543 /* cmdNext - next executable C statement file                      */
1544 /*-----------------------------------------------------------------*/
1545 int cmdNext (char *s, context *cctxt)
1546 {
1547     function *func = NULL;
1548     /* next is almost the same as step except we don't
1549        we don't set break point for all function entry
1550        points */
1551     if (STACK_EMPTY(callStack))
1552         fprintf(stdout,"The program is not being run.\n");
1553     else {
1554         /* if we are @ the end of a function then set
1555            break points at execution points of the
1556            function in the call stack... */
1557         if (cctxt->addr == cctxt->func->sym->eaddr) {
1558             if ((func = STACK_PEEK(callStack))) {
1559                 if (srcMode == SRC_CMODE)
1560                     applyToSet (func->cfpoints,setStepEPBp,NEXT,
1561                                 func->mod->c_name);     
1562                 else
1563                     applyToSet (func->afpoints,setStepEPBp,NEXT,
1564                                 func->mod->asm_name);
1565             }
1566         } else {
1567             if (srcMode == SRC_CMODE) {
1568                 /* for all execution points in this function */
1569                 applyToSet(cctxt->func->cfpoints,setNextEPBp,NEXT,
1570                            cctxt->func->mod->c_name);
1571                 /* set a break point @ the current function's
1572                    exit */
1573                 setBreakPoint (cctxt->func->sym->eaddr, CODE, NEXT , 
1574                                nextBpCB, cctxt->func->mod->c_name, 
1575                                cctxt->func->exitline);
1576                 
1577                 /* now break point @ callers execution points */        
1578                 if ((func = STACK_PPEEK(callStack))) {
1579                     applyToSet (func->cfpoints,setNextEPBp,NEXT ,
1580                                 func->mod->c_name);     
1581                     /* set bp @ callers exit point */
1582                     setBreakPoint (func->sym->eaddr, CODE, NEXT , 
1583                                    stepBpCB, func->mod->c_name, 
1584                                    func->exitline);
1585                 }
1586             } else {
1587                 /* for all execution points in this function */
1588                 applyToSet(cctxt->func->afpoints,setNextEPBp,NEXT,
1589                            cctxt->func->mod->asm_name);
1590                 /* set a break point @ the current function's
1591                    exit */
1592                 setBreakPoint (cctxt->func->sym->eaddr, CODE, NEXT , 
1593                                nextBpCB, cctxt->func->mod->asm_name, 
1594                                cctxt->func->aexitline);
1595                 
1596                 /* now break point @ callers execution points */        
1597                 if ((func = STACK_PPEEK(callStack))) {
1598                     applyToSet (func->cfpoints,setNextEPBp,NEXT ,
1599                                 func->mod->asm_name);   
1600                     /* set bp @ callers exit point */
1601                     setBreakPoint (func->sym->eaddr, CODE, NEXT , 
1602                                    stepBpCB, func->mod->asm_name, 
1603                                    func->aexitline);
1604                 }
1605             }
1606         }
1607         doingSteps = 1;
1608         simGo(1);       
1609         doingSteps = 0;
1610         showfull = 1;
1611     }    
1612     return 0;
1613 }
1614
1615 /*-----------------------------------------------------------------*/
1616 /* cmdRun  - run till next break point                             */
1617 /*-----------------------------------------------------------------*/
1618 int cmdRun (char *s, context *cctxt)
1619 {
1620     char buff[10];
1621     if (STACK_EMPTY(callStack)) {
1622         fprintf(stdout,"Starting program\n");
1623     if ( ! simactive )
1624     {
1625         fprintf(stdout,"No executable file specified.\nUse the \"file\" command.\n");
1626         return 0;
1627     }
1628     resetHitCount();
1629         simGo(0);
1630     } else {
1631         
1632         fprintf(stdout,
1633                 "The program being debugged has been started already.\n");
1634         fprintf(stdout,"Start it from the beginning? (y or n) ");
1635         fflush(stdout);
1636
1637         fgets(buff,sizeof(buff),stdin);
1638         if (toupper(buff[0]) == 'Y') {
1639             simReset();
1640         resetHitCount();
1641             simGo(0);
1642         }
1643     }
1644     showfull = 1;
1645     return 0;
1646 }
1647
1648 /*-----------------------------------------------------------------
1649  cmdListSymbols - list symbols
1650 |-----------------------------------------------------------------*/
1651 int cmdListSymbols (char *s, context *cctxt)
1652 {
1653     int our_verbose = 0;
1654     symbol *sy;
1655     int i;
1656
1657     if (strstr(s, "v1")) {
1658       our_verbose = 1;
1659     } else if (strstr(s, "v2")) {
1660       our_verbose = 2;
1661     }
1662
1663     printf("[symbols]\n");
1664     sy = setFirstItem(symbols);
1665     i = 0;
1666     for (;;) {
1667       if (sy == NULL)
1668         break;
1669       if (our_verbose <= 1)
1670         printf("<%s>", sy->name);
1671
1672       if (our_verbose > 1) {
1673         printf("  %d) name:%s, size:%d, level:%d block:%d\n", i,
1674           sy->name, sy->size, sy->level, sy->block);
1675         printf("    isonstack:%d, isfunc:%d, offset:%d addr:%d\n",
1676           sy->isonstack, sy->isfunc, sy->offset, sy->addr);
1677         printf("    eaddr:%d, addr_type:%c, type:%x etype:%x\n",
1678           sy->eaddr, sy->addr_type, sy->type, sy->etype);
1679         printf("    scopetype:%c, sname:%s, rname:%s addrspace:%c\n",
1680           sy->scopetype, sy->sname, sy->rname, sy->addrspace);
1681         printf("    next:%x\n", sy->next);
1682       }
1683       ++i;
1684       sy = setNextItem(symbols);
1685     }
1686     printf("   %d symbols\n", i);
1687     return 0;
1688 }
1689
1690 /*-----------------------------------------------------------------
1691  cmdListFunctions - list functions.
1692 |-----------------------------------------------------------------*/
1693 int cmdListFunctions (char *s, context *cctxt)
1694 {
1695     function *f;
1696     int i;
1697     int our_verbose = 0;
1698
1699     if (strstr(s, "v1")) {
1700       our_verbose = 1;
1701     } else if (strstr(s, "v2")) {
1702       our_verbose = 2;
1703     }
1704
1705     printf("[functions]\n");
1706     f = setFirstItem(functions);
1707     i = 0;
1708     for (;;) {
1709       if (f == NULL)
1710         break;
1711       if (our_verbose) {
1712         printf("  %d) sym:%x, fname:%s, modName:%s, mod:%x\n", i,
1713           f->sym, f->sym->name, f->modName, f->mod);
1714         printf("    entryline:%d, aentryline:%d, exitline:%d, aexitline:%d\n",
1715                 f->entryline, f->aentryline, f->exitline, f->aexitline);
1716         printf("    cfpoints:%x, afpoints:%x, laddr:%x, lline:%d\n",
1717                 f->cfpoints, f->afpoints, f->laddr, f->lline);
1718       }
1719       else {
1720         printf("<%s>", f->modName);
1721       }
1722       ++i;
1723       f = setNextItem(functions);
1724     }
1725     printf("   %d functions\n", i);
1726     return 0;
1727 }
1728
1729 /*-----------------------------------------------------------------
1730  cmdListModules - list functions.
1731 |-----------------------------------------------------------------*/
1732 int cmdListModules (char *s, context *cctxt)
1733 {
1734     module *m;
1735     srcLine *cs, *as;
1736     int i, mi;
1737     int our_verbose = 0;
1738
1739     if (strstr(s, "v1")) {
1740       our_verbose = 1;
1741     } else if (strstr(s, "v2")) {
1742       our_verbose = 2;
1743     }
1744
1745     printf("[modules]\n");
1746     m = setFirstItem(modules);
1747     mi = 0;
1748     for (;;) {
1749       if (m == NULL)
1750         break;
1751
1752       if (our_verbose >= 0) {
1753       printf("  %d) cfullname:%s, afullname:%s, name:%s\n", ++mi,
1754         m->cfullname, m->afullname, m->name);
1755       printf("    c_name:%s, asm_name:%s, ncLines:%d, nasmLines:%d\n",
1756               m->c_name, m->asm_name, m->ncLines, m->nasmLines);
1757       printf("    cLines:%x, asmLines:%x\n",
1758               m->cLines, m->asmLines);
1759       }
1760       if (our_verbose >= 2) {
1761         if (m->ncLines) {
1762           printf("    [cLines] ");
1763           if ( our_verbose)
1764           for (i=0; i<m->ncLines; i++ ) {
1765               cs = m->cLines[i];
1766               printf("   (%d) addr:%x, block:%d, level:%d, src:%s\n",
1767                  i, cs->addr, cs->block, cs->level, cs->src);
1768           }
1769           if (!our_verbose)
1770               printf("%d records", i);
1771         }
1772         if (m->nasmLines) {
1773           printf("    [asmLines] ");
1774           if ( our_verbose)
1775           for (i=0; i<m->nasmLines; i++ ) {
1776               as = m->asmLines[i];
1777               printf("   (%d) addr:%x, block:%d, level:%d, src:%s\n",
1778                  i, as->addr, as->block, as->level, as->src);
1779           }
1780           if (!our_verbose)
1781               printf("%d records", i);
1782         }
1783         printf("\n");
1784       }
1785
1786       m = setNextItem(modules);
1787     }
1788     return 0;
1789 }
1790
1791 /*-----------------------------------------------------------------
1792  infoSymbols - This is really just a tool to dump all these
1793    huge program structures out into human readable form.
1794 |-----------------------------------------------------------------*/
1795 static void infoSymbols(context *ctxt)
1796 {
1797   int our_verbose = 0;
1798
1799   printf("[context:%x] func:%x modName:%s addr:%x\n",
1800     ctxt, ctxt->func, ctxt->modName, ctxt->addr);
1801
1802   printf("  cline:%d asmline:%d block:%d level:%d\n",
1803     ctxt->cline, ctxt->asmline, ctxt->level);
1804
1805   printf("[globals] currCtxt:%x, modules:%x, functions:%x symbols:%x\n",
1806     currCtxt, modules, functions, symbols);
1807   printf("  nStructs:%d, structs:%x, ssdirl:%s\n",
1808     nStructs, structs, ssdirl);
1809
1810   /**************** modules *******************/
1811   {
1812     module *m;
1813     srcLine *cs, *as;
1814     int i, mi;
1815     printf("[modules]\n");
1816     m = setFirstItem(modules);
1817     mi = 0;
1818     for (;;) {
1819       if (m == NULL)
1820         break;
1821       printf("  %d) cfullname:%s, afullname:%s, name:%s\n", ++mi,
1822         m->cfullname, m->afullname, m->name);
1823       printf("    c_name:%s, asm_name:%s, ncLines:%d, nasmLines:%d\n",
1824               m->c_name, m->asm_name, m->ncLines, m->nasmLines);
1825       printf("    cLines:%x, asmLines:%x\n",
1826               m->cLines, m->asmLines);
1827       i = 0;
1828       if (m->cLines) {
1829         cs = m->cLines[i++];
1830         printf("    [cLines] ");
1831         while (cs) {
1832           if (our_verbose)
1833             printf("   (%d) addr:%x, block:%d, level:%d, src:%s\n",
1834                i, cs->addr, cs->block, cs->level, cs->src);
1835           cs = m->cLines[i++];
1836         }
1837         if (!our_verbose)
1838             printf("%d records", i);
1839       }
1840       i = 0;
1841       if (m->asmLines) {
1842         as = m->asmLines[i++];
1843         printf("    [asmLines] ");
1844         while (as) {
1845           if (our_verbose)
1846             printf("   (%d) addr:%x, block:%d, level:%d, src:%s\n",
1847                i, as->addr, as->block, as->level, as->src);
1848           as = m->asmLines[i++];
1849         }
1850         if (!our_verbose)
1851             printf("%d records", i);
1852       }
1853       printf("\n");
1854
1855       m = setNextItem(modules);
1856     }
1857   }
1858
1859   /**************** functions *******************/
1860   {
1861     function *f;
1862     int i;
1863     printf("[functions]\n");
1864     f = setFirstItem(functions);
1865     i = 0;
1866     for (;;) {
1867       if (f == NULL)
1868         break;
1869       if (our_verbose) {
1870         printf("  %d) sym:%x, modName:%s, mod:%x\n", i,
1871           f->sym, f->modName, f->mod);
1872         printf("    entryline:%d, aentryline:%d, exitline:%d, aexitline:%d\n",
1873                 f->entryline, f->aentryline, f->exitline, f->aexitline);
1874         printf("    cfpoints:%x, afpoints:%x, laddr:%x, lline:%d\n",
1875                 f->cfpoints, f->afpoints, f->laddr, f->lline);
1876       }
1877       ++i;
1878       f = setNextItem(functions);
1879     }
1880     if (!our_verbose)
1881       printf("   %d functions\n", i);
1882   }
1883
1884   /**************** symbols *******************/
1885   {
1886     symbol *s;
1887     int i;
1888     printf("[symbols]\n");
1889     s = setFirstItem(symbols);
1890     i = 0;
1891     for (;;) {
1892       if (s == NULL)
1893         break;
1894       if (our_verbose) {
1895         printf("  %d) name:%s, size:%d, level:%d block:%d\n", i,
1896           s->name, s->size, s->level, s->block);
1897         printf("    isonstack:%d, isfunc:%d, offset:%d addr:%d\n",
1898           s->isonstack, s->isfunc, s->offset, s->addr);
1899         printf("    eaddr:%d, addr_type:%c, type:%x etype:%x\n",
1900           s->eaddr, s->addr_type, s->type, s->etype);
1901         printf("    scopetype:%c, sname:%s, rname:%s addrspace:%c\n",
1902           s->scopetype, s->sname, s->rname, s->addrspace);
1903         printf("    next:%x\n", s->next);
1904       }
1905       ++i;
1906       s = setNextItem(symbols);
1907     }
1908     if (!our_verbose)
1909       printf("   %d symbols\n", i);
1910   }
1911
1912 }
1913
1914 /*-----------------------------------------------------------------*/
1915 /* infoRegisters - print register information                      */
1916 /*-----------------------------------------------------------------*/
1917 static void infoRegisters( int all, context *ctxt)
1918 {
1919     static unsigned int regaddrs[] = {0x81,0x82,0x83,0xb8,0xd0,0xe0,0xf0,0};
1920     unsigned long val;
1921     int i,j,*r;
1922
1923     i   = simGetValue (0xd0,'I',1);
1924     fprintf(stdout,"IP  : 0x%04X  RegisterBank %d:\nR0-7:",ctxt->addr,(i>>3)&3);
1925     for ( j = 0; j < 8 ; j++ )
1926     {
1927         val = simGetValue (j ,'R',1);
1928         fprintf(stdout," 0x%02X",val);
1929     }
1930     fprintf(stdout,"\n");
1931     val = simGetValue (0xe0,'I',1);
1932     fprintf(stdout,"ACC : 0x%02X %d %c\n",val,val,(isprint(val) ? val : '.'));
1933     val = simGetValue (0xf0,'I',1);
1934     fprintf(stdout,"B   : 0x%02X %d %c\n",val,val,(isprint(val) ? val : '.'));
1935     val = simGetValue (0x82,'I',2);
1936     fprintf(stdout,"DPTR: 0x%04X %d\n",val,val);
1937     val = simGetValue (0x81,'I',1);
1938     fprintf(stdout,"SP  : 0x%02X\n",val);
1939     fprintf(stdout,"PSW : 0x%02X | CY : %c | AC : %c | OV : %c | P : %c\n",
1940             i,(i&0x80)?'1':'0',(i&0x40)?'1':'0',(i&4)?'1':'0',(i&1)?'1':'0');
1941     if ( all )
1942     {
1943         fprintf(stdout,"Special Function Registers:\n");
1944         r = regaddrs;
1945         for ( i = 0x80 ; i < 0x100 ; i++ )
1946         {
1947             symbol *sym = NULL;
1948             if ( *r && *r == i )
1949             {
1950                 /* skip normal registers */
1951                 r++ ;
1952                 continue;
1953             }
1954             if (applyToSetFTrue(sfrsymbols,symWithAddr,i,'I',&sym))
1955             {
1956                 val = simGetValue (sym->addr,sym->addrspace,sym->size);
1957                 fprintf(stdout,"%s : 0x%02x",sym->name,val);
1958                 if ( !(i & 0x07 ))
1959                 {
1960                     for ( j = 0 ; j < 8 ; j++ )
1961                     {
1962                         sym = NULL;
1963                         if (applyToSetFTrue(sfrsymbols,symWithAddr,i+j,'J',&sym))
1964                         {
1965                             //val = simGetValue (sym->addr,sym->addrspace,sym->size);
1966                             fprintf(stdout," %s=%c",sym->name,(val&1)? '1':'0');
1967                         }
1968                         val >>= 1;
1969                     }
1970                 }
1971                 fprintf(stdout,"\n");
1972             }
1973         }
1974     }
1975 }
1976
1977 /*-----------------------------------------------------------------*/
1978 /* infoStack - print call stack information                        */
1979 /*-----------------------------------------------------------------*/
1980 static void infoStack(context *ctxt)
1981 {
1982     function *func ;
1983     int i = 0 ;
1984
1985     STACK_STARTWALK(callStack) ;
1986     while ((func = STACK_WALK(callStack))) {
1987     Dprintf(D_break, ("break: infoStack: %s %p (%p)\n",func->sym->name, w_callStack,p_callStack));
1988
1989         fprintf(stdout,"#%d  0x%08x in %s () at %s:%d\n",i++,
1990                 func->laddr,func->sym->name,
1991                 func->mod->c_name,func->lline+1);
1992     }
1993     if ( !i )
1994         fprintf(stdout,"no stack.\n");
1995 }
1996
1997 /*-----------------------------------------------------------------*/
1998 /* cmdWhere -  where command                                       */
1999 /*-----------------------------------------------------------------*/
2000 int cmdWhere(char *s, context *cctxt)
2001 {
2002         infoStack(cctxt);
2003         return 0;
2004 }
2005
2006
2007 static int infomode = 0;
2008 /*-----------------------------------------------------------------*/
2009 /* cmdInfo - info command                                          */
2010 /*-----------------------------------------------------------------*/
2011 int cmdInfo (char *s, context *cctxt)
2012 {
2013     while (isspace(*s)) s++;
2014
2015     /* list all break points */
2016     if (strncmp(s,"break",5) == 0) {
2017         listUSERbp();
2018         return 0;
2019     }
2020
2021     /* info frame same as frame */
2022     if (strcmp(s,"frame") == 0) {
2023         cmdFrame (s,cctxt);
2024         return 0;
2025     }
2026
2027     if (strncmp(s,"line",4) == 0) {
2028     infomode=1;
2029         cmdListSrc (s+4,cctxt);
2030         return 0;
2031     }
2032     if (strncmp(s,"source",6) == 0) 
2033     {
2034         module *m;
2035         if ( s[6] == 's' )
2036         {
2037             int k = 0;
2038             fprintf(stdout,"Source files for which symbols have been read in:\n\n");
2039             for (m = setFirstItem(modules); m ; m = setNextItem(modules))
2040             {
2041                 fprintf(stdout,"%s%s, %s",k ? ", ":"",m->cfullname, m->afullname); 
2042                 k = 1;
2043             }
2044             fprintf(stdout,"\n"); 
2045         }
2046         else
2047         {
2048             if (!cctxt || !cctxt->func || !cctxt->func->mod) 
2049             {
2050                 fprintf(stdout,"No source file loaded\n");
2051                 return 0;
2052             }
2053             m = cctxt->func->mod;
2054             fprintf(stdout,"Current source file is %s\n",m->c_name);
2055             fprintf(stdout,"Located in %s\n",m->cfullname);
2056             fprintf(stdout,"Contains %d lines.\nSource language is c.\n",
2057                     m->ncLines);
2058         }
2059         return 0;
2060     }
2061     if (strncmp(s,"functions",7) == 0) 
2062     {
2063         function *f;
2064         module *m = NULL;
2065         fprintf(stdout,"All defined functions:\n");
2066         for ( f = setFirstItem(functions); f ; f = setNextItem(functions))
2067         {
2068             if ( f->mod != m )
2069             {
2070                 m = f->mod;
2071                 fprintf(stdout,"\nFile %s\n", m->c_name);
2072             }
2073             fprintf(stdout,"%s();\n",f->sym->name);
2074         }
2075         return 0;
2076     }
2077     /* info stack display call stack */
2078     if (strcmp(s,"stack") == 0) {
2079         infoStack(cctxt);
2080     showfull = 1;
2081         return 0;
2082     }
2083
2084     /* info stack display call stack */
2085     if (strcmp(s,"registers") == 0) {
2086         infoRegisters(0,cctxt);
2087             return 0;
2088     }
2089
2090     /* info stack display call stack */
2091     if (strcmp(s,"all-registers") == 0) 
2092     {
2093         infoRegisters(1,cctxt);
2094         return 0;
2095     }
2096
2097     /* info stack display call stack */
2098     if (strcmp(s,"symbols") == 0) {
2099       /* dump out symbols we have read in */
2100       fprintf(stdout,"Dumping symbols...\n");
2101       infoSymbols(cctxt);
2102       return 0;
2103     }
2104
2105     if (strcmp(s,"variables") == 0) {
2106       /* dump out symbols we have read in */
2107       fprintf(stdout,"Dumping symbols...\n");
2108       infoSymbols(cctxt);
2109       return 0;
2110     }
2111
2112     fprintf(stdout,"Undefined info command: \"%s\".  Try \"help\n",s);
2113     return 0;
2114
2115 }
2116
2117 /*-----------------------------------------------------------------*/
2118 /* cmdQuit  - quit debugging                                       */
2119 /*-----------------------------------------------------------------*/
2120 int cmdQuit (char *s, context *cctxt)
2121 {   
2122     if (simactive)
2123         closeSimulator();
2124     return 1;
2125 }
2126
2127 /*-----------------------------------------------------------------*/
2128 /* cmdListSrc  - list src                                          */
2129 /*-----------------------------------------------------------------*/
2130 int cmdListSrc (char *s, context *cctxt)
2131 {   
2132     static int currline = 0;
2133     int i =0 ;
2134     int pline = 0;
2135     int llines = listlines;
2136     function *func = NULL;
2137
2138
2139     while (*s && isspace(*s)) s++;
2140     
2141     /* if the user has spcified line numer then the line number
2142        can be of the following formats
2143        LINE          - just line number
2144        FILE:LINE     - filename line number
2145        FILE:LINE,LASTLINE  + last line
2146        FUNCTION      - list a function
2147        FILE:FUNCTION - function in file */
2148
2149     if (*s) {
2150         /* case a) LINE */
2151         if (isdigit(*s)) {
2152             if (!cctxt || !cctxt->func || !cctxt->func->mod) {
2153               if (!list_mod) {
2154                 fprintf(stdout,"Sdcdb fails to have a proper context at %d.\n", __LINE__);
2155                 return 0;
2156               }
2157             }
2158             else
2159               list_mod = cctxt->func->mod;
2160         pline = strtol(s,&s,10) - 1;
2161         if (s && (s = strchr(s,','))) 
2162         {
2163             /* LINE,LASTLINE */
2164             llines = strtol(s+1,0,10); 
2165             if ( llines > 0 )
2166                 llines -= pline+1;
2167             else
2168                 llines = listlines;
2169         }
2170         }
2171         else {
2172             char *bp;
2173             
2174             /* if ':' present then FILE:LINE || FILE:FUNCTION */
2175             if ((bp = strchr(s,':'))) {
2176                 *bp = '\0';
2177                 bp ++;
2178                 if (isdigit(*bp)) {
2179                     /* FILE:LINE */
2180                     list_mod=NULL;  /* bug fix 2-09-02, moduleWithCName expects mod to be null */
2181                     if (srcMode == SRC_CMODE) {
2182                         if (!applyToSet(modules,moduleWithCName,s,&list_mod)) {
2183                             fprintf (stderr,"No c source file named %s.\n",s);
2184                             return 0;
2185                         }
2186                     } else {
2187                         if (!applyToSet(modules,moduleWithAsmName,s,&list_mod)) {
2188                             fprintf (stderr,"No source file named %s.\n",s);
2189                             return 0;
2190                         }
2191                     }
2192                     pline = strtol(bp,&bp,10) - 1;
2193             if (bp && (bp = strchr(bp,','))) 
2194             {
2195                 /* FILE:LINE,LASTLINE */
2196                 llines = strtol(bp+1,0,10); 
2197                 if ( llines > 0 )
2198                     llines -= pline+1;
2199                 else
2200                     llines = listlines;
2201             }
2202                 } else {
2203                     /* FILE:FUCTION */
2204                     if (!applyToSet(functions,funcWithNameModule,bp,s,&func)) {
2205                         fprintf(stdout,"Function \"%s\" not defined.\n",bp);
2206                         return 0;
2207                     }
2208                     list_mod = func->mod;
2209                     if (srcMode == SRC_CMODE) {
2210                         pline = func->entryline;
2211                         llines = func->exitline - func->entryline + 1;
2212                     } else {
2213                         pline = func->aentryline;
2214                         llines = func->aexitline - func->aentryline + 1;
2215                     }
2216                 }
2217             }
2218             else {
2219                 /* FUNCTION */
2220             if (*s == '\'') 
2221             {
2222                 /* 'FUNCTION' */
2223                 s++ ;
2224                 if ((bp = strrchr(s,'\''))) 
2225                 {
2226                     *bp = '\0';
2227                 }
2228                 
2229             }
2230                 if (!applyToSet(functions,funcWithName,s,&func)) {
2231                     fprintf(stderr,"Function \"%s\" not defined.\n",s); 
2232                     return 0;
2233                 }
2234                 else {
2235                     list_mod = func->mod;
2236                     if (srcMode == SRC_CMODE) {
2237                         pline = func->entryline;
2238                         llines = func->exitline - func->entryline + 1; 
2239                     } else {
2240                         pline = func->aentryline;
2241                         llines = func->aexitline - func->aentryline + 1; 
2242                     }
2243                 }
2244             }
2245         }
2246     } else {
2247         /* if no line specified & we had listed
2248            before then continue from that listing */
2249         if (currline)
2250             pline = currline ;
2251         else {
2252             if (!cctxt || !cctxt->func || !cctxt->func->mod) {
2253               fprintf(stdout,"Missing context at %d. Try list filename:lineno\n", __LINE__);
2254               return 0;
2255             }
2256             list_mod = cctxt->func->mod;
2257             if (srcMode == SRC_CMODE)
2258                 pline = cctxt->cline;
2259             else
2260                 pline = cctxt->asmline;
2261         }
2262     }
2263
2264     if (!list_mod) {
2265       fprintf(stdout,"Sdcdb fails to have a valid module context at %d.\n", __LINE__);
2266       return 0;
2267     }
2268
2269     if ( pline < 0 )
2270         return 0;
2271     if ( infomode )
2272     {
2273         int firstaddr , lastaddr ;
2274             if ( pline  >= list_mod->ncLines )
2275             pline = cctxt->cline;
2276         firstaddr = lastaddr = list_mod->cLines[pline]->addr;
2277         if (!func && cctxt && cctxt->func )
2278             func = cctxt->func;
2279             fprintf(stdout,"Line %d of \"%s\" starts at address 0x%08x <%s+%d>", 
2280                 pline+1,
2281                 list_mod->c_name, lastaddr,
2282                 func ? func->sym->name : "?",
2283                 func ? lastaddr -func->sym->addr : 0);
2284         llines = pline +1;
2285         for ( ; pline < list_mod->ncLines; pline++ )
2286         {
2287             if ( list_mod->cLines[pline]->addr > lastaddr )
2288             {
2289                 lastaddr = list_mod->cLines[pline]->addr -1;
2290                 break;
2291             }
2292         }
2293         fprintf(stdout," and ends at 0x%08x <%s+%d>.\n", 
2294                 lastaddr,
2295                 func ? func->sym->name : "?",
2296                 func ? lastaddr -func->sym->addr : 0);
2297         infomode=0;
2298         if ( func )
2299             fprintf(stdout,"\032\032%s:%d:1:beg:0x%08x\n",
2300                     func->mod->cfullname,
2301                     llines,firstaddr);
2302         else
2303             showfull=1;
2304         return 0;
2305     }
2306     for ( i = 0 ; i < llines ; i++ ) {
2307         if (srcMode == SRC_CMODE) {
2308             if ( (pline + i) >= list_mod->ncLines )
2309                 break;
2310             fprintf(stdout,"%d\t%s",pline + i,
2311                     list_mod->cLines[pline +i]->src);
2312         } else {
2313             if ( (pline + i) >= list_mod->nasmLines )
2314                 break;
2315             fprintf(stdout,"%d\t%s",pline + i,
2316                     list_mod->asmLines[pline +i]->src);
2317         }
2318     }
2319     currline = pline + i ;
2320     return 0;
2321 }
2322
2323 static unsigned long getValBasic(symbol *sym, link *type, char *val)
2324 {
2325     char *s;
2326     union 
2327     {   
2328         float f;     
2329         unsigned long val;
2330         long         sval;
2331         struct {
2332             unsigned short    lo;
2333             unsigned short    hi;
2334         } i;
2335         unsigned char b[4];
2336     }v;
2337
2338     if (IS_FLOAT(type))         
2339         v.f = strtod(val,NULL);    
2340     else
2341         if (IS_PTR(type))
2342             v.val = strtol(val,NULL,0);
2343         else
2344     {
2345             if (IS_INTEGRAL(type)) 
2346         {
2347             link *etype;
2348             if ( type->next )
2349                 etype = type->next;
2350             else
2351                 etype = type;
2352             if (IS_CHAR(etype))
2353             {
2354                 if (( s = strchr(val,'\'')))
2355                 {
2356                     if ( s[1] == '\\' )
2357                         v.b[0] = strtol(s+2,NULL,8);
2358                     else 
2359                         v.b[0] = s[1];
2360                 }
2361                 else
2362                 {
2363                     v.b[0] = strtol(val,NULL,0);
2364                 }
2365             }
2366             else
2367                 if (IS_INT(etype)) 
2368                     if (IS_LONG(etype))
2369                         v.val = strtol(val,NULL,0);
2370                     else
2371                         v.i.lo = strtol(val,NULL,0);
2372                 else
2373                     v.val = strtol(val,NULL,0);
2374             } 
2375         else
2376             v.val = strtol(val,NULL,0);
2377     }
2378     return v.val;
2379 }
2380
2381 /*-----------------------------------------------------------------*/
2382 /* printFmtInteger - print value in bin,oct,dez or hex             */
2383 /*-----------------------------------------------------------------*/
2384 static void printFmtInteger(char *deffmt,int fmt, long val, 
2385                             int sign, int size)
2386 {
2387     static char digits[] = 
2388     {
2389         '0' , '1' , '2' , '3' , '4' , '5' ,
2390         '6' , '7' , '8' , '9' , 'a' , 'b' ,
2391         'c' , 'd' , 'e' , 'f' , 'g' , 'h' 
2392     };
2393     static int radixOfFormat[] = { 0 , 2, 8 ,10, 16  };
2394     static int olenOfSize[]    = { 0 , 3, 6 , 8, 11  };
2395         char buf[40];
2396         char negative = 0;
2397         int charPos = 38;
2398     int radix;
2399
2400     if ( fmt == FMT_NON || fmt == FMT_DEZ )
2401     {
2402         fprintf(stdout,deffmt,val);
2403         return;
2404     }
2405     radix = radixOfFormat[fmt];
2406
2407     /*
2408     if ( sign && val < 0 )
2409         negative = 1;
2410     */
2411
2412         if (!negative)
2413             val = -val;
2414
2415         buf[39] = '\0';
2416     while (val <= -radix) 
2417     {
2418             buf[charPos--] = digits[-(val % radix)];
2419             val = val / radix;
2420         }
2421         buf[charPos] = digits[-val];
2422
2423     switch ( fmt )
2424     {
2425         case FMT_OCT:
2426             radix = olenOfSize[size];
2427             break;
2428         case FMT_HEX:
2429             radix = size << 1;
2430             break;
2431         case FMT_BIN:
2432             radix = size << 3;
2433             break;
2434     }
2435
2436     while (charPos > 39 - radix )
2437     {
2438         buf[--charPos] = '0';
2439     } 
2440     switch ( fmt )
2441     {
2442         case FMT_OCT:
2443             if ( buf[charPos] != '0' )
2444                 buf[--charPos] = '0';
2445             break;
2446         case FMT_HEX:
2447             buf[--charPos] = 'x';
2448             buf[--charPos] = '0';
2449             break;
2450     }
2451         if (negative) {
2452             buf[--charPos] = '-';
2453         }
2454     fputs(&buf[charPos],stdout);
2455 }
2456
2457 /*-----------------------------------------------------------------*/
2458 /* printValBasic - print value of basic types                      */
2459 /*-----------------------------------------------------------------*/
2460 static void printValBasic(symbol *sym, link *type,
2461                           char mem, unsigned addr,int size, int fmt)
2462 {
2463     union {     
2464         float f;     
2465         unsigned long val;
2466         long         sval;
2467         struct {
2468             unsigned short    lo;
2469             unsigned short    hi;
2470         } i;
2471         unsigned char b[4];
2472     }v;
2473     union {
2474         unsigned char b[4];
2475     }v1;
2476     
2477     v.val = simGetValue(addr,mem,size);
2478     /* if this a floating point number then */
2479     if (IS_FLOAT(type))         
2480         fprintf(stdout,"%f",v.f);    
2481     else
2482         if (IS_PTR(type))
2483             fprintf(stdout,"0x%*x",size<<1,v.val);
2484         else
2485         if (IS_INTEGRAL(type)) 
2486         {
2487             link *etype;
2488             if ( type->next )
2489                 etype = type->next;
2490             else
2491                 etype = type;
2492             if (IS_CHAR(etype))
2493             { 
2494                 if ( isprint(v.val))
2495                     printFmtInteger((SPEC_USIGN(etype)?"0x%02x":"'%c'"),
2496                                     fmt,(long)v.val,0,size);
2497                 else
2498                     printFmtInteger((SPEC_USIGN(etype)?"0x%02x":"'\\%o'"),
2499                                     fmt,(long)v.val,0,size);
2500             }
2501             else
2502             {
2503                 if (IS_INT(etype)) 
2504                     if (IS_LONG(etype))
2505                         if (SPEC_USIGN(etype))
2506                             printFmtInteger("%u",fmt,(long)v.val,0,size);
2507                         else
2508                             printFmtInteger("%d",fmt,(long)v.sval,1,size);
2509                     else
2510                         if (SPEC_USIGN(etype))
2511                             printFmtInteger("%u",fmt,(long)v.i.lo,0,size);
2512                         else
2513                             printFmtInteger("%d",fmt,(long)v.i.lo,1,size);
2514                 else
2515                 {
2516                     if (IS_BITVAR(etype))
2517                         fprintf(stdout,"%c",(v.val?'1':'0'));
2518                     else
2519                         fprintf(stdout,"0x%0*x",size<<1,v.val);
2520                 }
2521             }
2522             } else
2523             fprintf(stdout,"0x%0*x",size<<1,v.val);  
2524 }
2525
2526 /*-----------------------------------------------------------------*/
2527 /* printValFunc  - prints function values                          */
2528 /*-----------------------------------------------------------------*/
2529 static void printValFunc (symbol *sym, int fmt)
2530 {
2531     fprintf(stdout,"print function not yet implemented");
2532 }
2533
2534 /*-----------------------------------------------------------------*/
2535 /* printArrayValue - will print the values of array elements       */
2536 /*-----------------------------------------------------------------*/
2537 static void printArrayValue (symbol *sym,  link *type,
2538                              char space, unsigned int addr, int fmt)
2539 {
2540         link *elem_type = type->next;
2541         int i;
2542         
2543         fprintf(stdout,"{");
2544         for (i = 0 ; i < DCL_ELEM(type) ; i++) {                
2545                 if (IS_AGGREGATE(elem_type)) {
2546                         printValAggregates(sym,elem_type,space,addr,fmt);                      
2547                 } else {
2548                         printValBasic(sym,elem_type,space,addr,getSize(elem_type),fmt);
2549                 }
2550                 addr += getSize(elem_type);
2551                 if (i != DCL_ELEM(type) -1)
2552                         fprintf(stdout,",");
2553         }
2554
2555         fprintf(stdout,"}");            
2556 }
2557
2558 /*-----------------------------------------------------------------*/
2559 /* printStructValue - prints structures elements                   */
2560 /*-----------------------------------------------------------------*/
2561 static void printStructValue (symbol *sym, link *type, 
2562                               char space, unsigned int addr, int fmt) 
2563 {
2564         symbol *fields = SPEC_STRUCT(type)->fields;
2565     int first = 1;
2566         fprintf(stdout," { ");
2567         while (fields) {
2568                 fprintf(stdout,"%s%s = ",(first ? "": ", "),fields->name);
2569                 first = 0;
2570         if (IS_AGGREGATE(fields->type)) {
2571                         printValAggregates(fields,fields->type,space, addr, fmt);
2572                 } else {
2573                         printValBasic(fields,fields->type,space,addr,getSize(fields->type), fmt);
2574                 }
2575                 addr += getSize(fields->type);
2576                 fields = fields->next;
2577         }
2578         fprintf(stdout,"}");
2579 }
2580
2581 /*-----------------------------------------------------------------*/
2582 /* printValAggregates - print value of aggregates                  */
2583 /*-----------------------------------------------------------------*/
2584 static void printValAggregates (symbol *sym, link *type,
2585                                 char space,unsigned int addr, int fmt)
2586 {
2587
2588         if (IS_ARRAY(type)) {
2589                 printArrayValue(sym, type, space, addr, fmt);
2590                 return ;
2591         }
2592
2593         if (IS_STRUCT(type)) { 
2594                 printStructValue(sym, type, space, addr, fmt); 
2595                 return; 
2596         } 
2597 }
2598
2599 /*-----------------------------------------------------------------*/
2600 /* printOrSetSymValue - print or set value of a symbol             */
2601 /*-----------------------------------------------------------------*/
2602 static int printOrSetSymValue (symbol *sym, context *cctxt, 
2603                                 int flg, int dnum, int fmt, char *rs, 
2604                                 char *val, char cmp )
2605 {
2606     static char fmtChar[] = " todx ";
2607     static int stack = 1;
2608         symbol *fields;
2609     link *type;
2610     unsigned int  addr; 
2611     int size, n;
2612     char *s, *s2;
2613     char save_ch, save_ch2;
2614
2615     /* if it is on stack then compute address & fall thru */
2616     if (sym->isonstack) 
2617     {
2618         symbol *bp = symLookup("bp",cctxt);
2619         if (!bp) 
2620         {
2621             fprintf(stdout,"cannot determine stack frame\n");
2622             return 1;
2623         }
2624
2625         sym->addr = simGetValue(bp->addr,bp->addrspace,bp->size)
2626             + sym->offset ;      
2627     }
2628     
2629     /* get the value from the simulator and
2630        print it */
2631     switch (flg)
2632     {
2633         case 0: 
2634         default:
2635             break;
2636         case 1: 
2637             fprintf(stdout,"$%d = ",stack++);
2638             break;
2639         case 2: 
2640             fprintf(stdout,"%d: ", dnum);
2641             if ( fmt != FMT_NON )
2642                 fprintf(stdout,"/%c ",fmtChar[fmt]);
2643             fprintf(stdout,"%s%s = ",sym->name,rs);
2644             break;
2645     }
2646
2647     addr = sym->addr;
2648     type = sym->type;
2649     size = sym->size;
2650
2651     while ( *rs )
2652     {
2653         if ( *rs == '[' && IS_ARRAY(type))
2654         {
2655             s = rs+1;
2656             while ( *rs && *rs != ']' ) rs++ ;
2657             save_ch = *rs;
2658             *rs = '\0' ;
2659             if ( ! isdigit(*s ))
2660             {
2661                 /* index seems a variable */
2662                 for ( s2 = s; *s2 && ( isalnum( *s2 ) || *s2 == '_'); s2++ );
2663                 save_ch2 = *s2;
2664                 if ( *s2 )
2665                     *s2 = '\0';
2666                 fields = symLookup(s,cctxt);
2667                 *s2 = save_ch2;
2668                 if ( ! fields )
2669                 {
2670                     fprintf(stdout,"Unknown variable \"%s\" for index.\n", s);
2671                     return 1;                    
2672                 }
2673                 /* arrays & structures first */
2674                 if (! IS_INTEGRAL(fields->type))
2675                 {
2676                     fprintf(stdout,"Wrong type of variable \"%s\" for index \n", s);
2677                     return 1;                    
2678                 }
2679                 n = simGetValue(fields->addr,fields->addrspace,getSize(fields->type));
2680             }
2681             else
2682             {
2683                 n = strtol(s,0,0);
2684             }
2685             if ( n < 0 || n >= DCL_ELEM(type))
2686             {
2687                 fprintf(stdout,"Wrong index %d.\n", n);
2688                 return 1;                    
2689             }
2690             type = type->next;
2691             size = getSize(type);
2692             addr += size * n;
2693             *rs++ = save_ch;
2694         }
2695         else if ( *rs == '.' && IS_STRUCT(type))
2696         {
2697             s = rs+1;
2698             /* search structure element */
2699             for ( rs = s; *rs && ( isalnum( *rs ) || *rs == '_'); rs++ );
2700             save_ch = *rs;
2701             if ( *rs )
2702                 *rs = '\0';
2703             for (fields = SPEC_STRUCT(type)->fields; fields; fields = fields->next) 
2704             {
2705                 if (!(strcmp(s,fields->name)))
2706                     break;
2707             }
2708             *rs = save_ch;
2709             if ( ! fields )
2710             {
2711                 fprintf(stdout,"Unknown field \"%s\" of structure\n", s);
2712                 return 1;                    
2713             }
2714             type = fields->type;
2715             size = getSize(type);
2716             addr += fields->offset;
2717         }
2718         else
2719             break;
2720     }
2721
2722     /* arrays & structures first */
2723     if (IS_AGGREGATE(type))
2724     {
2725             if ( val )
2726         {
2727             fprintf(stdout,"Cannot set/compare aggregate variable\n");
2728             return 1;
2729         }
2730         else
2731             printValAggregates(sym,type,sym->addrspace,addr,fmt);
2732     }
2733     else
2734         /* functions */
2735         if (IS_FUNC(type))
2736     {
2737             if ( !val )
2738             printValFunc(sym,fmt);
2739         else
2740             return 1;
2741     }
2742         else
2743     { 
2744             if ( val )
2745         {
2746             unsigned long newval;
2747             newval = getValBasic(sym,type,val);
2748
2749             if ( cmp )
2750             {
2751                 unsigned long lval;
2752                 lval = simGetValue(addr,sym->addrspace,size);
2753                 switch ( cmp )
2754                 {
2755                     case '<' : return ( lval <  newval ? 1:0 ); break;
2756                     case '>' : return ( lval >  newval ? 1:0 ); break;
2757                     case 'l' : return ( lval <= newval ? 1:0 ); break;
2758                     case 'g' : return ( lval >= newval ? 1:0 ); break;
2759                     case '=' : return ( lval == newval ? 1:0 ); break;
2760                     case '!' : return ( lval != newval ? 1:0 ); break;
2761                 }
2762             }
2763             else
2764             {
2765                 if ( sym->addrspace == 'I' && addr == 0xb8 )
2766                 {
2767                     /* Symbol with address of IP */
2768                     if ( cctxt ) cctxt->addr = newval;
2769                     simSetPC(cctxt->addr); 
2770                 }
2771                 else
2772                     simSetValue(addr,sym->addrspace,size,newval);       
2773                 return 1;
2774             }
2775         }
2776         else
2777             printValBasic(sym,type,sym->addrspace,addr,size,fmt);
2778     }
2779     if ( flg > 0 ) fprintf(stdout,"\n");
2780         return 0;
2781 }
2782
2783 /*-----------------------------------------------------------------*/
2784 /* printStructInfo - print out structure information               */
2785 /*-----------------------------------------------------------------*/
2786 static void printStructInfo (structdef *sdef)
2787 {
2788     symbol *field = sdef->fields ;
2789     int i = 0 ;
2790     
2791     while (field) {
2792         i += field->offset;
2793         field = field->next;
2794     }
2795
2796     fprintf(stdout,"%s %s {\n",(i ? "struct" : "union" ), sdef->tag);
2797     field = sdef->fields;
2798     while (field) {
2799         printTypeInfo (field->type);
2800         fprintf(stdout," %s ;\n",field->name);
2801         field = field->next ;
2802     }
2803
2804     fprintf(stdout,"}\n");
2805
2806 }
2807
2808 /*-----------------------------------------------------------------*/
2809 /* printTypeInfo - print out the type information                  */
2810 /*-----------------------------------------------------------------*/
2811 static void printTypeInfo(link *p)
2812 {
2813     if (!p)
2814         return ;
2815
2816     if (IS_DECL(p)) {
2817         switch (DCL_TYPE(p))  {
2818         case FUNCTION:
2819             printTypeInfo (p->next);
2820             fprintf(stdout,"()");
2821             break;
2822         case ARRAY:
2823             printTypeInfo (p->next);
2824             fprintf(stdout,"[%d]",DCL_ELEM(p));
2825             break;
2826         
2827         case IPOINTER:
2828         case PPOINTER:
2829         case POINTER:
2830             printTypeInfo (p->next);
2831             fprintf(stdout,"(_near *)");
2832             break;
2833
2834         case FPOINTER:
2835             printTypeInfo (p->next);
2836             fprintf(stdout,"(_xdata *)");
2837             break;
2838
2839         case CPOINTER:
2840             printTypeInfo( p->next);
2841             fprintf(stdout,"(_code *)");
2842             break;
2843             
2844         case GPOINTER:
2845             printTypeInfo( p->next);
2846             fprintf(stdout,"(_generic *)");
2847             break;                   
2848         }
2849     } else {
2850         switch (SPEC_NOUN(p)) { /* depending on the specifier type */
2851         case V_INT:
2852             (IS_LONG(p) ? fputs("long ",stdout) : 
2853              ( IS_SHORT(p) ? fputs("short ",stdout) : 
2854                fputs("int ",stdout))) ;
2855             break;
2856         case V_FLOAT:
2857              fputs("float ",stdout);
2858              break;
2859
2860         case V_CHAR:
2861             fputs ("char ",stdout);
2862             break;
2863
2864         case V_VOID:
2865             fputs("void ",stdout);
2866             break;
2867
2868         case V_STRUCT:
2869             printStructInfo (SPEC_STRUCT(p));
2870             break;
2871
2872         case V_SBIT:
2873             fputs("sbit ",stdout);
2874             break;
2875
2876         case V_BIT:
2877             fprintf(stdout,": %d" ,SPEC_BLEN(p));       
2878             break;
2879         }
2880     }
2881 }
2882
2883 /*-----------------------------------------------------------------*/
2884 /* conditionIsTrue - compare variable with constant value        */
2885 /*-----------------------------------------------------------------*/
2886 int conditionIsTrue( char *s, context *cctxt)
2887 {   
2888     symbol *sym = NULL;
2889     int fmt;
2890     char *rs, *dup, cmp_char;
2891     dup = s = Safe_strdup(s);
2892     if ( !( rs = preparePrint(s, cctxt, &fmt, &sym )) || !sym)
2893         fmt = 1;
2894     else if (!( s =  strpbrk(rs,"<>=!")))
2895         fmt = 1;
2896     else
2897     {
2898         cmp_char = *s;    
2899         *s++ = '\0';
2900         if ( *s == '=' )
2901         {
2902             /* if <= or >= an other char is used 
2903              * == or !=  not checked in switch 
2904              */
2905             switch( cmp_char )
2906             {
2907                 case '>': cmp_char = 'g' ; break;
2908                 case '<': cmp_char = 'l' ; break;
2909             }
2910             s++ ;
2911         }
2912         while (isspace(*s)) *s++ = '\0';
2913         fmt = printOrSetSymValue(sym,cctxt,0,0,0,rs,s,cmp_char);
2914     }
2915     Safe_free(dup);
2916     return fmt;
2917 }
2918
2919 /*-----------------------------------------------------------------*/
2920 /* cmdPrint - print value of variable                              */
2921 /*-----------------------------------------------------------------*/
2922 int cmdPrint (char *s, context *cctxt)
2923 {   
2924     symbol *sym ;
2925     int fmt;
2926     char *rs;
2927     if ( !( rs = preparePrint(s, cctxt, &fmt, &sym )))
2928         return 0;
2929
2930     if ( sym ) 
2931     {
2932         printOrSetSymValue(sym,cctxt,1,0,fmt,rs,NULL,'\0');
2933     } 
2934     return 0;
2935 }
2936
2937 /*-----------------------------------------------------------------*/
2938 /* cmdOutput - print value of variable without number and newline  */
2939 /*-----------------------------------------------------------------*/
2940 int cmdOutput (char *s, context *cctxt)
2941 {   
2942     symbol *sym ;
2943     int fmt;
2944     char *rs;
2945     if ( !( rs = preparePrint(s, cctxt, &fmt, &sym )))
2946         return 0;
2947
2948     if ( sym ) 
2949     {
2950         printOrSetSymValue(sym,cctxt,0,0,fmt,rs,NULL,'\0');
2951     } 
2952     return 0;
2953 }
2954
2955 /** find display entry with this number */
2956
2957 DEFSETFUNC(dsymWithNumber)
2958 {
2959     dsymbol *dsym = item;
2960     V_ARG(int , dnum);
2961     V_ARG(dsymbol **,dsymp);
2962
2963     if ( dsym->dnum == dnum )
2964     {
2965         *dsymp = dsym;
2966         return 1;
2967     }
2968     return 0;
2969 }
2970
2971 /*-----------------------------------------------------------------*/
2972 /* displayAll  - display all valid variables                       */
2973 /*-----------------------------------------------------------------*/
2974 void displayAll(context *cctxt)
2975 {
2976     dsymbol *dsym;
2977     symbol  *sym;
2978     if ( !dispsymbols )
2979         return;
2980     for (dsym = setFirstItem(dispsymbols);
2981          dsym ;
2982          dsym = setNextItem(dispsymbols)) 
2983     {
2984         if ( (sym = symLookup(dsym->name,cctxt)))
2985             printOrSetSymValue(sym,cctxt,2,dsym->dnum,dsym->fmt,
2986                                dsym->rs,NULL,'\0');
2987     }
2988 }
2989
2990 /*-----------------------------------------------------------------*/
2991 /* cmdDisplay  - display value of variable                         */
2992 /*-----------------------------------------------------------------*/
2993 int cmdDisplay (char *s, context *cctxt)
2994 {   
2995     static int dnum = 1;
2996     symbol *sym ;
2997     int fmt;
2998     char *rs;
2999     if ( !( rs = preparePrint(s, cctxt, &fmt, &sym )))
3000     {
3001         displayAll(cctxt);
3002         return 0;
3003     }
3004
3005     if ( sym ) 
3006     {
3007         dsymbol *dsym = (dsymbol *)Safe_calloc(1,sizeof(dsymbol));
3008         dsym->dnum = dnum++ ;
3009         dsym->name = sym->name;
3010         dsym->fmt  = fmt;
3011         dsym->rs   = gc_strdup(rs);
3012         addSetHead(&dispsymbols,dsym);
3013     }
3014     return 0;
3015 }
3016
3017 /*-----------------------------------------------------------------*/
3018 /* cmdUnDisplay  - undisplay value of variable                              */
3019 /*-----------------------------------------------------------------*/
3020 int cmdUnDisplay (char *s, context *cctxt)
3021 {   
3022     dsymbol *dsym;
3023     int dnum;
3024
3025     while (isspace(*s)) s++;
3026     if (!*s)
3027     {
3028         for (dsym = setFirstItem(dispsymbols);
3029              dsym;
3030              dsym = setNextItem(dispsymbols))
3031         {
3032             Safe_free(dsym->rs);
3033             Safe_free(dsym); 
3034         }
3035         deleteSet(&dispsymbols);
3036         return 0;
3037     }
3038     while ( s && *s )
3039     {
3040         dnum = strtol(s,&s,10);
3041         if (applyToSetFTrue(dispsymbols,dsymWithNumber,dnum,&dsym)) 
3042         {
3043             deleteSetItem(&dispsymbols,dsym);
3044             Safe_free(dsym->rs);
3045             Safe_free(dsym); 
3046         } 
3047         else
3048         {
3049             fprintf(stdout,"Arguments must be display numbers.\n");    
3050         }
3051     }
3052     return 0;
3053 }
3054
3055 /*-----------------------------------------------------------------*/
3056 /* cmdPrintType - print type of a variable                         */
3057 /*-----------------------------------------------------------------*/
3058 int cmdPrintType (char *s, context *cctxt)
3059 {   
3060         symbol *sym ;
3061     char *bp = s+strlen(s) -1;
3062
3063     while (isspace(*s)) s++;
3064     if (!*s) return 0;
3065     while (isspace(*bp)) bp--;
3066     bp++ ;
3067     *bp = '\0';
3068
3069     if ((sym = symLookup(s,cctxt))) {
3070         printTypeInfo(sym->type);
3071         fprintf(stdout,"\n");
3072     } else {
3073         fprintf(stdout,
3074                 "No symbol \"%s\" in current context.\n",
3075                 s);
3076     }
3077     return 0;   
3078 }
3079
3080 /*-----------------------------------------------------------------*/
3081 /* cmdClrUserBp - clear user break point                           */
3082 /*-----------------------------------------------------------------*/
3083 int cmdClrUserBp (char *s, context *cctxt)
3084 {   
3085     char *bp ;    
3086     function *func = NULL;
3087         
3088     /* clear break point location specification can be of the following
3089        forms
3090        a) <nothing>        - break point at current location
3091        b) lineno           - number of the current module
3092        c) filename:lineno  - line number of the given file
3093        e) filename:function- function X in file Y (useful for static functions)
3094        f) function         - function entry point
3095     */
3096
3097     if (!cctxt) {
3098         fprintf(stdout,"No symbol table is loaded.  Use the \"file\" command.\n");
3099         return 0;
3100     }
3101
3102     /* white space skip */
3103     while (*s && isspace(*s)) s++;
3104     
3105     /* null terminate it after stripping trailing blanks*/
3106     bp = s + strlen(s);
3107     while (bp != s && isspace(*bp)) bp--;
3108     *bp = '\0';
3109
3110     /* case a) nothing */
3111     /* if nothing given then current location : we know
3112        the current execution location from the currentContext */
3113     if (! *s ) {
3114
3115         /* if current context is known */
3116         if (cctxt->func) 
3117             /* clear the break point @ current location */
3118             clearUSERbp (cctxt->addr);
3119         else
3120             fprintf(stderr,"No default breakpoint address now.\n");
3121                         
3122         goto ret ;
3123     }
3124
3125     /* case b) lineno */
3126     /* check if line number */
3127     if (isdigit(*s)) {
3128         /* get the lineno */
3129         int line = atoi(s);
3130
3131         /* if current context not present then we must get the module
3132            which has main & set the break point @ line number provided
3133            of that module : if current context known then set the bp 
3134            at the line number given for the current module 
3135         */
3136         if (cctxt->func) {
3137             if (!cctxt->func->mod) {
3138                 if (!applyToSet(functions,funcWithName,"main"))
3139                     fprintf(stderr,"Function \"main\" not defined.\n");
3140                 else 
3141                     clearBPatModLine(func->mod,line);
3142             } else 
3143                 clearBPatModLine(cctxt->func->mod,line);                        
3144         }
3145         
3146         goto ret;
3147     }
3148
3149     if ((bp = strchr(s,':'))) {
3150         
3151         module *mod = NULL;
3152         *bp = '\0';
3153         
3154         if (!applyToSet(modules,moduleWithCName,s,&mod)) {
3155             fprintf (stderr,"No source file named %s.\n",s);
3156             goto ret;
3157         }
3158
3159         /* case c) filename:lineno */
3160         if (isdigit(*(bp +1))) {                    
3161          
3162             clearBPatModLine (mod,atoi(bp+1));      
3163             goto ret;
3164             
3165         }
3166         /* case d) filename:function */
3167         if (!applyToSet(functions,funcWithNameModule,bp+1,s,&func)) 
3168             fprintf(stderr,"Function \"%s\" not defined.\n",bp+1); 
3169         else
3170             clearBPatModLine (mod,func->entryline);
3171         
3172         goto ret;
3173     }
3174             
3175     /* case e) function */
3176     if (!applyToSet(functions,funcWithName,s,&func))
3177         fprintf(stderr,"Function \"%s\" not defined.\n",s); 
3178     else
3179         clearBPatModLine(func->mod,func->entryline);
3180
3181  ret:    
3182     return 0;        
3183 }
3184
3185 /*-----------------------------------------------------------------*/
3186 /* cmdSimulator - send command to simulator                        */
3187 /*-----------------------------------------------------------------*/
3188 int cmdSimulator (char *s, context *cctxt)
3189 {   
3190   char tmpstr[82];
3191
3192     if (strlen(s) > 80) {
3193       printf("error 3A\n");
3194       exit(1);
3195     }
3196     strcpy(tmpstr, s);
3197     strcat(tmpstr, "\n");
3198     sendSim(tmpstr);
3199     waitForSim(200,NULL);
3200     fprintf(stdout,"%s",simResponse());
3201     return 0;
3202 }
3203
3204 void setMainContext()
3205 {
3206     function *func = NULL;
3207     currentFrame = 0; 
3208     if (!applyToSet(functions,funcWithName,"_main",&func) &&
3209         !applyToSet(functions,funcWithName,"main",&func))
3210             return;
3211
3212     discoverContext (func->sym->addr, func);
3213 }
3214
3215 function *needExtraMainFunction()
3216 {
3217     function *func = NULL;
3218     if (!applyToSet(functions,funcWithName,"_main",&func))
3219     {
3220         if (applyToSet(functions,funcWithName,"main",&func))
3221         {
3222             return func;
3223         }
3224     }
3225     return NULL;
3226 }
3227     
3228 static void printFrame()
3229 {
3230     int i;
3231     function *func     = NULL;
3232     function *lastfunc = NULL;
3233
3234     if ( currentFrame < 0 )
3235     {
3236         currentFrame = 0;
3237         fprintf(stdout,"Bottom (i.e., innermost) frame selected; you cannot go down.\n");
3238         return;
3239     }
3240     STACK_STARTWALK(callStack) ;
3241     for ( i = 0; i <= currentFrame ; i++ )
3242     {
3243         func = STACK_WALK(callStack);
3244         if ( !func )
3245         {
3246             currentFrame = i-1;
3247             fprintf(stdout,"Initial frame selected; you cannot go up.\n");
3248             return;
3249         }
3250     }
3251     fprintf(stdout,"#%d  0x%08x in %s () at %s:%d\n",
3252             currentFrame,func->laddr,func->sym->name,func->mod->c_name,func->lline+1);
3253     fprintf(stdout,"\032\032%s:%d:1:beg:0x%08x\n",
3254             func->mod->cfullname,func->lline+1,func->laddr);
3255
3256     discoverContext (func->laddr, func);
3257 }
3258
3259
3260 /*-----------------------------------------------------------------*/
3261 /* cmdUp -  Up command                                             */
3262 /*-----------------------------------------------------------------*/
3263 int cmdUp(char *s, context *cctxt)
3264 {
3265     while (isspace(*s)) s++;
3266     if ( *s )
3267         currentFrame += strtol(s,0,10);
3268     else
3269         currentFrame++ ;
3270
3271     printFrame();
3272         return 0;
3273 }
3274
3275 /*-----------------------------------------------------------------*/
3276 /* cmdDown - down command                                          */
3277 /*-----------------------------------------------------------------*/
3278 int cmdDown(char *s, context *cctxt)
3279 {
3280     while (isspace(*s)) s++;
3281     if ( *s )
3282         currentFrame -= strtol(s,0,10);
3283     else
3284         currentFrame-- ;
3285
3286     printFrame();
3287         return 0;
3288 }
3289 /*-----------------------------------------------------------------*/
3290 /* cmdFrame - Frame command                                        */
3291 /*-----------------------------------------------------------------*/
3292 int cmdFrame (char *s, context *cctxt)
3293 {   
3294     function *func = NULL;
3295     int i, framenr = 0;
3296
3297     while (isspace(*s)) s++;
3298     if ( *s )
3299         currentFrame = strtol(s,0,10);
3300     printFrame();
3301     return 0;
3302 }
3303
3304 /*-----------------------------------------------------------------*/
3305 /* cmdFinish - exec till end of current function                   */
3306 /*-----------------------------------------------------------------*/
3307 int cmdFinish (char *s, context *ctxt)
3308 {
3309     if (STACK_EMPTY(callStack)) {
3310         fprintf(stdout,"The program is not running.\n");
3311         return 0;
3312     }
3313
3314     if (srcMode == SRC_CMODE) {
3315         setBreakPoint (ctxt->func->sym->eaddr, CODE, STEP, 
3316                        stepBpCB, ctxt->func->mod->c_name, 
3317                        ctxt->func->exitline);
3318     } else {
3319         setBreakPoint (ctxt->func->sym->eaddr, CODE, STEP, 
3320                        stepBpCB, ctxt->func->mod->asm_name, 
3321                        ctxt->func->aexitline);
3322     }
3323
3324     simGo(-1);
3325     showfull = 1;
3326     return 0;
3327     
3328 }
3329
3330
3331 /*-----------------------------------------------------------------*/
3332 /* cmdShow - show command                                          */
3333 /*-----------------------------------------------------------------*/
3334 int cmdShow (char *s, context *cctxt)
3335 {
3336     /* skip white space */
3337     while (*s && isspace(*s)) s++ ;
3338
3339     if (strcmp(s,"copying") == 0) {
3340         fputs(copying,stdout);
3341         return 0;
3342     }
3343     
3344     if (strcmp(s,"warranty") == 0) {
3345         fputs(warranty,stdout);
3346         return 0;
3347     }
3348
3349     return 0;
3350 }
3351