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