version 0.5.2
[fw/sdcc] / sim / ucsim / cmd.src / cmdset.cc
1 /*
2  * Simulator of microcontrollers (cmd.src/cmdset.cc)
3  *
4  * Copyright (C) 1999,99 Drotos Daniel, Talker Bt.
5  * 
6  * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
7  *
8  */
9
10 /* This file is part of microcontroller simulator: ucsim.
11
12 UCSIM is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
16
17 UCSIM is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with UCSIM; see the file COPYING.  If not, write to the Free
24 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
25 02111-1307, USA. */
26 /*@1@*/
27
28 #include "ddconfig.h"
29
30 #include "cmdlexcl.h"
31 #include "cmdpars.h"
32
33 // prj
34 #include "i_string.h"
35 #include "utils.h"
36 #include "globals.h"
37
38 // sim.src
39 #include "simcl.h"
40
41 // local, cmd.src
42 #include "cmdsetcl.h"
43 #include "cmdutil.h"
44
45
46 /*
47  * Command: run
48  *----------------------------------------------------------------------------
49  */
50
51 //int
52 //cl_run_cmd::do_work(class cl_sim *sim,
53 //                  class cl_cmdline *cmdline, class cl_console *con)
54 COMMAND_DO_WORK_SIM(cl_run_cmd)
55 {
56   class cl_brk *b;
57   t_addr start, end;
58   class cl_cmd_arg *params[4]= { cmdline->param(0),
59                                  cmdline->param(1),
60                                  cmdline->param(2),
61                                  cmdline->param(3) };
62
63   if (params[0])
64     if (!(params[0]->get_address(sim->uc, &start)))
65       {
66         con->dd_printf("Error: wrong start address\n");
67         return(DD_FALSE);
68       }
69   if (params[1])
70     if (!(params[1]->get_address(sim->uc, &end)))
71       {
72         con->dd_printf("Error: wromg end address\n");
73         return(DD_FALSE);
74       }
75   if (params[0])
76     {
77       if (!sim->uc->inst_at(start))
78         con->dd_printf("Warning: maybe not instruction at 0x%06lx\n", start);
79       sim->uc->PC= start;
80       if (params[1])
81         {
82           if (start == end)
83             {
84               con->dd_printf("Addresses must be different.\n");
85               return(DD_FALSE);
86             }
87           if ((b= sim->uc->fbrk_at(end)))
88             {
89             }
90           else
91             {
92               b= new cl_fetch_brk(sim->uc->address_space(MEM_ROM_ID),
93                                   sim->uc->make_new_brknr(), end,
94                                   brkDYNAMIC, 1);
95               sim->uc->fbrk->add_bp(b);
96             }
97         }
98     }
99   con->dd_printf("Simulation started, PC=0x%06x\n", sim->uc->PC);
100   if (sim->uc->fbrk_at(sim->uc->PC))
101     sim->uc->do_inst(1);
102
103   sim->start(con);
104   return(DD_FALSE);
105 }
106
107
108 /*
109  * Command: stop
110  *----------------------------------------------------------------------------
111  */
112
113 //int
114 //cl_stop_cmd::do_work(class cl_sim *sim,
115 //                   class cl_cmdline *cmdline, class cl_console *con)
116 COMMAND_DO_WORK_SIM(cl_stop_cmd)
117 {
118   sim->stop(resUSER);
119   sim->uc->print_disass(sim->uc->PC, con);
120   return(DD_FALSE);
121 }
122
123
124 /*
125  * Command: step
126  *----------------------------------------------------------------------------
127  */
128
129 //int
130 //cl_step_cmd::do_work(class cl_sim *sim,
131 //                   class cl_cmdline *cmdline, class cl_console *con)
132 COMMAND_DO_WORK_UC(cl_step_cmd)
133 {
134   //printf("step %x\n",uc->PC);
135   uc->do_inst(1);
136   //printf("step done %x\n",uc->PC);
137   uc->print_regs(con);
138   return(0);
139 }
140
141
142 /*
143  * Command: next
144  *----------------------------------------------------------------------------
145  */
146
147 //int
148 //cl_next_cmd::do_work(class cl_sim *sim,
149 //                   class cl_cmdline *cmdline, class cl_console *con)
150 COMMAND_DO_WORK_SIM(cl_next_cmd)
151 {
152   class cl_brk *b;
153   t_addr next;
154   int branch;
155   int inst_len;
156
157 #if 0
158   struct dis_entry *de;
159   t_mem code= sim->uc->get_mem(MEM_ROM, sim->uc->PC);
160   int i= 0;
161   de= &(sim->uc->dis_tbl()[i]);
162   while ((code & de->mask) != de->code &&
163          de->mnemonic)
164     {
165       i++;
166       de= &(sim->uc->dis_tbl()[i]);
167     }
168 #endif
169
170   branch = sim->uc->inst_branch(sim->uc->PC);
171   inst_len = sim->uc->inst_length(sim->uc->PC);
172
173   if ((branch == 'a') || (branch == 'l'))
174     {
175       next= sim->uc->PC + inst_len;
176       if (!sim->uc->fbrk_at(next))
177         {
178           b= new cl_fetch_brk(sim->uc->address_space(MEM_ROM_ID),
179                               sim->uc->make_new_brknr(),
180                               next, brkDYNAMIC, 1);
181
182           b->init();
183 //        sim->uc->fbrk->add_bp(b);
184
185           sim->uc->fbrk->add(b);
186           b->activate();
187         }
188       if (sim->uc->fbrk_at(sim->uc->PC))
189         sim->uc->do_inst(1);
190       sim->start(con);
191       //sim->uc->do_inst(-1);
192     }
193   else {
194     sim->uc->do_inst(1);
195     sim->uc->print_regs(con);
196   }
197   return(DD_FALSE);
198 }
199
200
201 /*
202  * Command: help
203  *----------------------------------------------------------------------------
204  */
205
206 //int
207 //cl_help_cmd::do_work(class cl_sim *sim,
208 //                   class cl_cmdline *cmdline, class cl_console *con)
209 COMMAND_DO_WORK_APP(cl_help_cmd)
210 {
211   class cl_sim *sim;
212   class cl_commander *commander;
213   class cl_cmdset *cmdset= 0;
214   int i;
215   class cl_cmd_arg *parm= cmdline->param(0);
216
217   sim= app->get_sim();
218   if ((commander= app->get_commander()) != 0)
219     cmdset= commander->cmdset;
220   if (!cmdset)
221     return(DD_FALSE);
222   if (!parm) {
223     for (i= 0; i < cmdset->count; i++)
224       {
225         class cl_cmd *c= (class cl_cmd *)(cmdset->at(i));
226         if (c->short_help)
227           con->dd_printf("%s\n", c->short_help);
228         else
229           con->dd_printf("%s\n", (char*)(c->names->at(0)));
230       }
231   }
232   else
233     {
234       matches= 0;
235       do_set(cmdline, 0, cmdset, con);
236       if (matches == 1 &&
237           cmd_found)
238         {
239           int names;
240           con->dd_printf("Names of command:");
241           for (names= 0; names < cmd_found->names->count; names++)
242             con->dd_printf(" %s", (char*)(cmd_found->names->at(names)));
243           con->dd_printf("\n");
244           class cl_cmdset *subset= cmd_found->get_subcommands();
245           if (subset)
246             {
247               con->dd_printf("\"%s\" must be followed by the name of a "
248                              "subcommand\nList of subcommands:\n",
249                              (char*)(cmd_found->names->at(0)));
250               for (i= 0; i < subset->count; i++)
251                 {
252                   class cl_cmd *c=
253                     dynamic_cast<class cl_cmd *>(subset->object_at(i));
254                   con->dd_printf("%s\n", c->short_help);
255                 }
256             }
257           if (cmd_found->long_help)
258             con->dd_printf("%s\n", cmd_found->long_help);
259         }
260       if (!matches ||
261           !cmd_found)
262         con->dd_printf("No such command.\n");
263       //return(DD_FALSE);
264       /*
265       int pari;
266       for (pari= 0; pari < cmdline->nuof_params(); pari++)
267         {
268           class cl_cmd_arg *act_param;
269           act_param= (class cl_cmd_arg *)(cmdline->param(pari));
270           for (i= 0; i < cmdset->count; i++)
271             {
272               class cl_cmd *c= (class cl_cmd *)(cmdset->at(i));
273               if (!c->name_match(act_param->s_value, DD_FALSE))
274                 continue;
275               if (c->short_help)
276                 con->dd_printf("%s\n", c->short_help);
277               else
278                 con->dd_printf("%s\n", (char*)(c->names->at(0)));
279               if (pari < cmdline->nuof_params()-1)
280                 continue;
281               cmdset= c->get_subcommands();
282               if (!cmdset)
283                 return(DD_FALSE);
284             }
285         }
286       return(DD_FALSE);
287       */
288     }
289   return(DD_FALSE);
290   /*
291   if (cmdline->syntax_match(0, STRING)) {
292     matches= 0;
293     for (i= 0; i < cmdset->count; i++)
294       {
295         c= (class cl_cmd *)(cmdset->at(i));
296         if (c->name_match(parm->value.string.string, DD_FALSE))
297           matches++;
298       }
299     if (!matches)
300       con->dd_printf("No such command\n");
301     else if (matches > 1)
302       for (i= 0; i < cmdset->count; i++)
303         {
304           c= (class cl_cmd *)(cmdset->at(i));
305           if (!c->name_match(parm->value.string.string, DD_FALSE))
306             continue;
307           if (c->short_help)
308             con->dd_printf("%s\n", c->short_help);
309           else
310             con->dd_printf("%s\n", (char*)(c->names->at(0)));
311         }
312     else
313       for (i= 0; i < cmdset->count; i++)
314         {
315           c= (class cl_cmd *)(cmdset->at(i));
316           if (!c->name_match(parm->value.string.string, DD_FALSE))
317             continue;
318           if (c->short_help)
319             con->dd_printf("%s\n", c->short_help);
320           else
321             con->dd_printf("%s\n", (char*)(c->names->at(0)));
322           int names;
323           con->dd_printf("Names of command:");
324           for (names= 0; names < c->names->count; names++)
325             con->dd_printf(" %s", (char*)(c->names->at(names)));
326           con->dd_printf("\n");
327           if (c->long_help)
328             con->dd_printf("%s\n", c->long_help);
329           else
330             con->dd_printf("%s\n", (char*)(c->names->at(0)));
331         }
332   }
333   else
334     con->dd_printf("%s\n", short_help?short_help:"Error: wrong syntax");
335
336   return(0);
337   */
338 }
339
340 bool
341 cl_help_cmd::do_set(class cl_cmdline *cmdline, int pari,
342                     class cl_cmdset *cmdset,
343                     class cl_console *con)
344 {
345   int i;
346   for (i= 0; i < cmdset->count; i++)
347     {
348       class cl_cmd *cmd= dynamic_cast<class cl_cmd *>(cmdset->object_at(i));
349       if (!cmd)
350         continue;
351       if (pari >= cmdline->nuof_params())
352         return(DD_FALSE);
353       class cl_cmd_arg *param= cmdline->param(pari);
354       if (!param)
355         return(DD_FALSE);
356       class cl_cmdset *next_set= cmd->get_subcommands();
357       if (cmd->name_match(param->s_value, DD_FALSE))
358         {
359           if (pari+1 >= cmdline->nuof_params())
360             {
361               matches++;
362               cmd_found= cmd;
363               if (cmd->short_help)
364                 con->dd_printf("%s\n", cmd->short_help);
365               else
366                 con->dd_printf("%s\n", (char*)(cmd->names->at(0)));
367               //continue;
368             }
369           else
370             if (next_set)
371               do_set(cmdline, pari+1, next_set, con);
372         }
373     }
374   return(DD_TRUE);
375 }
376
377
378 /*
379  * Command: quit
380  *----------------------------------------------------------------------------
381  */
382
383 //int
384 //cl_quit_cmd::do_work(class cl_sim *sim,
385 //                   class cl_cmdline */*cmdline*/, class cl_console */*con*/)
386 COMMAND_DO_WORK(cl_quit_cmd)
387 {
388   return(1);
389 }
390
391
392 /*
393  * Command: kill
394  *----------------------------------------------------------------------------
395  */
396
397 //int
398 //cl_kill_cmd::do_work(class cl_sim *sim,
399 //                   class cl_cmdline */*cmdline*/, class cl_console */*con*/)
400 COMMAND_DO_WORK_APP(cl_kill_cmd)
401 {
402   app->going= 0;
403   if (app->sim)
404     app->sim->state|= SIM_QUIT;
405   return(1);
406 }
407
408
409 /*
410  * EXEC file
411  */
412
413 COMMAND_DO_WORK_APP(cl_exec_cmd)
414 {
415   class cl_cmd_arg *parm= cmdline->param(0);
416   char *fn= 0;
417
418   if (cmdline->syntax_match(0, STRING)) {
419     fn= parm->value.string.string; 
420   }
421   else
422     con->dd_printf("%s\n", short_help?short_help:"Error: wrong syntax\n");
423
424   class cl_commander *c= app->get_commander();
425   class cl_console *cons= con->clone_for_exec(fn);
426   if (cons)
427     {
428       cons->flags|= CONS_NOWELCOME;
429       c->add_console(cons);
430     }
431
432   return(DD_FALSE);
433 }
434
435
436 /*
437  * expression expression
438  */
439
440 COMMAND_DO_WORK_APP(cl_expression_cmd)
441 {
442   //con->dd_printf("\"%s\"\n", cmdline->cmd);
443   char *s= cmdline->cmd;
444   if (!s ||
445       !*s)
446     return(DD_FALSE);
447   int i= strspn(s, " \t\v\n");
448   s+= i;
449   //con->dd_printf("\"%s\"\n", s);
450   i= strspn(s, "abcdefghijklmnopqrstuvwxyz");
451   s+= i;
452   //con->dd_printf("\"%s\"\n", s);
453   class YY_cl_ucsim_parser_CLASS *pars;
454   class cl_ucsim_lexer *lexer;
455   lexer= new cl_ucsim_lexer(s);
456   pars= new YY_cl_ucsim_parser_CLASS(lexer);
457   pars->yyparse();
458   delete pars;
459   return(DD_FALSE);
460 }
461
462
463 /* End of cmd.src/cmdset.cc */