8777353cc9c41308ad2dd7b4b081464ccc81cdcc
[fw/sdcc] / sim / ucsim / sim.src / arg.cc
1 /*
2  * Simulator of microcontrollers (arg.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 <stdio.h>
31 #include <stdlib.h>
32 #include "i_string.h"
33
34 // prj
35 #include "globals.h"
36
37 // sim
38 #include "simcl.h"
39
40 // cmd
41 #include "cmdutil.h"
42
43 // local
44 #include "argcl.h"
45
46
47 /*
48  * Making the argument
49  */
50
51 cl_arg::cl_arg(long lv):
52   cl_base()
53 {
54   i_value= lv;
55   s_value= 0;
56 }
57
58 cl_arg::cl_arg(char *sv):
59   cl_base()
60 {
61   s_value= sv?strdup(sv):0;
62 }
63
64 cl_arg::cl_arg(double fv):
65   cl_base()
66 {
67   f_value= fv;
68   s_value= 0;
69 }
70
71 cl_arg::cl_arg(void *pv):
72   cl_base()
73 {
74   p_value= pv;
75   s_value= 0;
76 }
77
78 cl_arg::~cl_arg(void)
79 {
80   if (s_value)
81     free(s_value);
82 }
83
84
85 /*
86  * Getting value of the argument
87  */
88
89 bool
90 cl_arg::get_ivalue(long *value)
91 {
92   if (value)
93     *value= i_value;
94   return(DD_TRUE);
95 }
96
97 char *
98 cl_arg::get_svalue(void)
99 {
100   return(s_value);
101 }
102
103 double
104 cl_arg::get_fvalue(void)
105 {
106   return(f_value);
107 }
108
109 void *
110 cl_arg::get_pvalue(void)
111 {
112   return(p_value);
113 }
114
115
116 /*
117  * Command parameters
118  *----------------------------------------------------------------------------
119  */
120
121 cl_cmd_arg::~cl_cmd_arg(void)
122 {
123   if (interpreted_as_string)
124     {
125       if (value.string.string)
126         free(value.string.string);
127     }
128 }
129
130 bool
131 cl_cmd_arg::as_address(class cl_uc *uc)
132 {
133   bool b= get_address(uc, &(value.address));
134   return(b);
135 }
136
137 bool
138 cl_cmd_arg::as_number(void)
139 {
140   return(get_ivalue(&(value.number)));
141 }
142
143 bool
144 cl_cmd_arg::as_data(void)
145 {
146   long l;
147   bool ret= get_ivalue(&l);
148   value.data= l;
149   return(ret);
150 }
151
152 bool
153 cl_cmd_arg::as_memory(class cl_uc *uc)
154 {
155   value.memory= uc->mem(s_value);
156   return(value.memory != 0);
157 }
158
159 bool
160 cl_cmd_arg::as_hw(class cl_uc *uc)
161 {
162   return(DD_FALSE);
163 }
164
165 bool
166 cl_cmd_arg::as_string(void)
167 {
168   char *s= get_svalue();
169   if (!s)
170     return(DD_FALSE);
171   if (is_string())
172     value.string.string= proc_escape(s, &value.string.len);
173   else
174     {
175       value.string.string= strdup(s);
176       value.string.len= strlen(s);
177     }
178   return(interpreted_as_string= value.string.string != NULL);
179 }
180
181 bool
182 cl_cmd_arg::as_bit(class cl_uc *uc)
183 {
184   return(get_bit_address(uc,
185                          &(value.bit.mem),
186                          &(value.bit.mem_address),
187                          &(value.bit.mask)));
188 }
189
190
191 /* Interger number */
192
193 cl_cmd_int_arg::cl_cmd_int_arg(/*class cl_uc *iuc,*/ long addr):
194   cl_cmd_arg(/*iuc,*/ addr)
195 {}
196
197 bool
198 cl_cmd_int_arg::get_address(class cl_uc *uc, t_addr *addr)
199 {
200   long iv;
201
202   bool b= get_ivalue(&iv);
203   if (addr)
204     *addr= iv;
205   return(b);
206 }
207
208 bool
209 cl_cmd_int_arg::get_bit_address(class cl_uc *uc, // input
210                                 class cl_mem **mem, // outputs
211                                 t_addr *mem_addr,
212                                 t_mem *bit_mask)
213 {
214   t_addr bit_addr;
215
216   if (!get_address(uc, &bit_addr))
217     return(DD_FALSE);
218   
219   if (mem)
220     *mem= uc->bit2mem(bit_addr, mem_addr, bit_mask);
221   return(mem && *mem);
222 }
223
224 bool
225 cl_cmd_int_arg::as_string(void)
226 {
227   value.string.string= (char*)malloc(100);
228   sprintf(value.string.string, "%ld", i_value);
229   value.string.len= strlen(value.string.string);
230   return(interpreted_as_string= value.string.string != NULL);
231 }
232
233
234 /* Symbol */
235
236 cl_cmd_sym_arg::cl_cmd_sym_arg(/*class cl_uc *iuc,*/ char *sym):
237   cl_cmd_arg(/*iuc,*/ sym)
238 {}
239
240 bool
241 cl_cmd_sym_arg::as_string(void)
242 {
243   char *s= get_svalue();
244   if (!s)
245     return(DD_FALSE);
246   value.string.string= strdup(s);
247   value.string.len= strlen(s);
248   return(interpreted_as_string= value.string.string != NULL);
249 }
250
251 bool
252 cl_cmd_sym_arg::get_address(class cl_uc *uc, t_addr *addr)
253 {
254   struct name_entry *ne;
255
256   if ((ne= get_name_entry(uc->sfr_tbl(),
257                           get_svalue(),
258                           uc)) != NULL)
259     {
260       if (addr)
261         *addr= ne->addr;
262       return(1);
263     }
264   return(0);
265 }
266
267 bool
268 cl_cmd_sym_arg::get_bit_address(class cl_uc *uc, // input
269                                 class cl_mem **mem, // outputs
270                                 t_addr *mem_addr,
271                                 t_mem *bit_mask)
272 {
273   struct name_entry *ne;
274
275   if ((ne= get_name_entry(uc->bit_tbl(),
276                           get_svalue(),
277                           uc)) == NULL)
278     return(DD_FALSE);
279   if (mem)
280     *mem= uc->bit2mem(ne->addr, mem_addr, bit_mask);
281   return(mem && *mem);
282 }
283
284 bool
285 cl_cmd_sym_arg::as_address(class cl_uc *uc)
286 {
287   struct name_entry *ne;
288   //printf("SYM %s as addr?\n",get_svalue());
289   if ((ne= get_name_entry(uc->sfr_tbl(), get_svalue(), uc)) != NULL)
290     {
291       value.address= ne->addr;
292       return(DD_TRUE);
293     }
294   return(DD_FALSE);
295 }
296
297 bool
298 cl_cmd_sym_arg::as_hw(class cl_uc *uc)
299 {
300   cl_hw *hw, *found;
301   int i= 0;
302
303   hw= found= uc->get_hw(get_svalue(), &i);
304   if (!hw)
305     return(DD_FALSE);
306   i++;
307   found= uc->get_hw(get_svalue(), &i);
308   if (found)
309     return(DD_FALSE);
310   value.hw= hw;
311   return(DD_TRUE);
312 }
313
314
315 /* String */
316
317 cl_cmd_str_arg::cl_cmd_str_arg(/*class cl_uc *iuc,*/ char *str):
318   cl_cmd_arg(/*iuc,*/ str)
319 {}
320
321
322 /* Bit */
323
324 cl_cmd_bit_arg::cl_cmd_bit_arg(/*class cl_uc *iuc,*/
325                                class cl_cmd_arg *asfr, class cl_cmd_arg *abit):
326   cl_cmd_arg(/*iuc,*/ (long)0)
327 {
328   sfr= asfr;
329   bit= abit;
330 }
331
332 cl_cmd_bit_arg::~cl_cmd_bit_arg(void)
333 {
334   if (sfr)
335     delete sfr;
336   if (bit)
337     delete bit;
338 }
339
340 bool
341 cl_cmd_bit_arg::get_address(class cl_uc *uc, t_addr *addr)
342 {
343   if (sfr)
344     return(sfr->get_address(uc, addr));
345   return(0);
346 }
347
348 bool
349 cl_cmd_bit_arg::get_bit_address(class cl_uc *uc, // input
350                                 class cl_mem **mem, // outputs
351                                 t_addr *mem_addr,
352                                 t_mem *bit_mask)
353 {
354   if (mem)
355     *mem= uc->mem(MEM_SFR);
356   if (mem_addr)
357     {
358       if (!sfr ||
359           !sfr->get_address(uc, mem_addr))
360         return(DD_FALSE);
361     }
362   if (bit_mask)
363     {
364       if (!bit)
365         return(DD_FALSE);
366       long l;
367       if (!bit->get_ivalue(&l) ||
368           l > 7)
369         return(DD_FALSE);
370       *bit_mask= 1 << l;
371     }
372   return(DD_TRUE);
373 }
374
375
376 /* Array */
377
378 cl_cmd_array_arg::cl_cmd_array_arg(/*class cl_uc *iuc,*/
379                                    class cl_cmd_arg *aname,
380                                    class cl_cmd_arg *aindex):
381   cl_cmd_arg(/*iuc,*/ (long)0)
382 {
383   name_arg= aname;
384   index= aindex;
385 }
386
387 cl_cmd_array_arg::~cl_cmd_array_arg(void)
388 {
389   if (name_arg)
390     delete name_arg;
391   if (index)
392     delete index;
393 }
394
395 bool
396 cl_cmd_array_arg::as_hw(class cl_uc *uc)
397 {
398   char *n;
399   t_addr a;
400
401   if (name_arg == 0 ||
402       index == 0 ||
403       (n= name_arg->get_svalue()) == NULL ||
404       !index->get_address(uc, &a))
405     return(DD_FALSE);
406   
407   value.hw= uc->get_hw(n, a, NULL);
408   return(value.hw != NULL);
409 }
410
411
412 /*
413  * Program arguments
414  *----------------------------------------------------------------------------
415  */
416
417 cl_prg_arg::cl_prg_arg(char sn, char *ln, long lv):
418   cl_arg(lv)
419 {
420   short_name= sn;
421   long_name = ln?strdup(ln):0;
422 }
423
424 cl_prg_arg::cl_prg_arg(char sn, char *ln, char *sv):
425   cl_arg(sv)
426 {
427   short_name= sn;
428   long_name = ln?strdup(ln):0;
429 }
430
431 cl_prg_arg::cl_prg_arg(char sn, char *ln, double fv):
432   cl_arg(fv)
433 {
434   short_name= sn;
435   long_name = ln?strdup(ln):0;
436 }
437
438 cl_prg_arg::cl_prg_arg(char sn, char *ln, void *pv):
439   cl_arg(pv)
440 {
441   short_name= sn;
442   long_name = ln?strdup(ln):0;
443 }
444
445 cl_prg_arg::~cl_prg_arg(void)
446 {
447   if (long_name)
448     free(long_name);
449 }
450
451
452 /*
453  * List of arguments
454  *----------------------------------------------------------------------------
455  */
456
457 int
458 cl_arguments::arg_avail(char nam)
459 {
460   class cl_prg_arg *a;
461   int i;
462
463   for (i= 0; i < count; i++)
464     {
465       a= (class cl_prg_arg *)(at(i));
466       if (a->short_name == nam)
467         return(1);
468     }
469   return(0);
470 }
471
472 int
473 cl_arguments::arg_avail(char *nam)
474 {
475   class cl_prg_arg *a;
476   int i;
477
478   for (i= 0; i < count; i++)
479     {
480       a= (class cl_prg_arg *)(at(i));
481       if (a->long_name &&
482           strcmp(a->long_name, nam) == 0)
483         return(1);
484     }
485   return(0);
486 }
487
488 long
489 cl_arguments::get_iarg(char sname, char *lname)
490 {
491   class cl_prg_arg *a;
492   int i;
493
494   for (i= 0; i < count; i++)
495     {
496       a= (class cl_prg_arg *)(at(i));
497       if ((sname && a->short_name == sname) ||
498           (lname && a->long_name && strcmp(a->long_name, lname) == 0))
499         {
500           long iv;
501           if (a->get_ivalue(&iv))
502             return(iv);
503           else
504             //FIXME
505             return(0);
506         }
507     }
508   return(0);
509 }
510
511 char *
512 cl_arguments::get_sarg(char sname, char *lname)
513 {
514   class cl_prg_arg *a;
515   int i;
516
517   for (i= 0; i < count; i++)
518     {
519       a= (class cl_prg_arg *)(at(i));
520       if ((sname && a->short_name == sname) ||
521           (lname && a->long_name && strcmp(a->long_name, lname) == 0))
522         return(a->get_svalue());
523     }
524   return(0);
525 }
526
527
528 double
529 cl_arguments::get_farg(char sname, char *lname)
530 {
531   class cl_prg_arg *a;
532   int i;
533
534   for (i= 0; i < count; i++)
535     {
536       a= (class cl_prg_arg *)(at(i));
537       if ((sname && a->short_name == sname) ||
538           (lname && a->long_name && strcmp(a->long_name, lname) == 0))
539         return(a->get_fvalue());
540     }
541   return(0);
542 }
543
544 void *
545 cl_arguments::get_parg(char sname, char *lname)
546 {
547   class cl_prg_arg *a;
548   int i;
549
550   for (i= 0; i < count; i++)
551     {
552       a= (class cl_prg_arg *)(at(i));
553       if ((sname && a->short_name == sname) ||
554           (lname && a->long_name && strcmp(a->long_name, lname) == 0))
555         return(a->get_pvalue());
556     }
557   return(0);
558 }
559
560
561 /* End of arg.cc */