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