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