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