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