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