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