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