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