9979fe7159f4ccc6827d17311fa1b1963860a5cd
[fw/sdcc] / sim / ucsim / s51.src / sim51.cc
1 /*
2  * Simulator of microcontrollers (sim51.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 <ctype.h>
33 #include <errno.h>
34 #include "i_string.h"
35
36 #include "globals.h"
37 #include "utils.h"
38
39 #include "sim51cl.h"
40 #include "cmd51cl.h"
41 #include "uc51cl.h"
42 #include "uc52cl.h"
43 #include "uc51rcl.h"
44 #include "uc89c51rcl.h"
45 #include "uc251cl.h"
46 #include "glob.h"
47
48
49 cl_sim51::cl_sim51(int iargc, char *iargv[]):
50   cl_sim("t:s:S:hH", iargc, iargv)
51 {}
52
53 static void
54 print_help(char *name)
55 {
56   printf("%s: %s\n", name, VERSIONSTR);
57   printf("Usage: %s [-hHVvP] [-p prompt] [-t CPU] [-X freq[k|M]]\n"
58          "       [-c file] [-s file] [-S optionlist]"
59 #ifdef SOCKET_AVAIL
60          " [-Z portnum]"
61 #endif
62          "\n"
63          "       [files...]\n", name);
64   printf
65     (
66      "Options:\n"
67      "  -t CPU       Type of CPU: 51, C52, 251, etc.\n"
68      "  -X freq[k|M] XTAL frequency\n"
69      "  -c file      Open command console on `file'\n"
70 #ifdef SOCKET_AVAIL
71      "  -Z portnum   Use localhost:portnumber for command console\n"
72 #endif
73      "  -s file      Connect serial interface to `file'\n"
74      "  -S options   `options' is a comma separated list of options\n"
75      "               according to serial interface. Know options are:\n"
76      "                  in=file   serial input will be read from file named `file'\n"
77      "                  out=file  serial output will be written to `file'\n"
78      "  -p prompt    Specify string for prompt\n"
79      "  -P           Prompt is a null ('\\0') character\n"
80      "  -V           Verbose mode\n"
81      "  -v           Print out version number\n"
82      "  -H           Print out types of known CPUs\n"
83      "  -h           Print out this help\n"
84      );
85 }
86
87 enum {
88   SOPT_IN= 0,
89   SOPT_OUT
90 };
91
92 static const char *S_opts[]= {
93   /*[SOPT_IN]=*/ "in",
94   /*[SOPT_OUT]=*/ "out",
95   NULL
96 };
97
98 int
99 cl_sim51::proc_arg(char optopt, char *optarg)
100 {
101   char *cpu_type= NULL, *cp;
102   int i;
103   char *subopts, *value;
104
105   switch (optopt)
106     {
107
108     case 't':
109
110       if (cpu_type)
111         free(cpu_type);
112       cpu_type= strdup(optarg);
113       for (cp= cpu_type; *cp; *cp= toupper(*cp), cp++);
114       arguments->add(new cl_prg_arg('t', 0, cpu_type));
115       break;
116
117     case 's':
118       {
119         FILE *Ser_in, *Ser_out;
120         if (arg_avail('s'))
121           {
122             fprintf(stderr, "-s option can not be used more than once.\n");
123             break;
124           }
125         arguments->add(new cl_prg_arg('s', 0, (long long)1));
126         if ((Ser_in= fopen(optarg, "r")) == NULL)
127           {
128             fprintf(stderr,
129                     "Can't open `%s': %s\n", optarg, strerror(errno));
130             return(4);
131           }
132         arguments->add(new cl_prg_arg(0, "Ser_in", Ser_in));
133         if ((Ser_out= fopen(optarg, "w")) == NULL)
134           {
135             fprintf(stderr,
136                     "Can't open `%s': %s\n", optarg, strerror(errno));
137             return(4);
138           }
139         arguments->add(new cl_prg_arg(0, "Ser_out", Ser_out));
140         break;
141       }
142
143     case 'S':
144
145       subopts= optarg;
146       while (*subopts != '\0')
147         switch (get_sub_opt(&subopts, S_opts, &value))
148           {
149             FILE *Ser_in, *Ser_out;
150           case SOPT_IN:
151             if (value == NULL) {
152               fprintf(stderr, "No value for -S in\n");
153               exit(1);
154             }
155             if (arg_avail("Ser_in"))
156               {
157                 fprintf(stderr, "Serial input specified more than once.\n");
158                 break;
159               }
160             if ((Ser_in= fopen(value, "r")) == NULL)
161               {
162                 fprintf(stderr,
163                         "Can't open `%s': %s\n", value, strerror(errno));
164                 exit(4);
165               }
166             arguments->add(new cl_prg_arg(0, "Ser_in", Ser_in));
167             break;
168           case SOPT_OUT:
169             if (value == NULL) {
170               fprintf(stderr, "No value for -S out\n");
171               exit(1);
172             }
173             if (arg_avail("Ser_out"))
174               {
175                 fprintf(stderr, "Serial output specified more than once.\n");
176                 break;
177               }
178             if ((Ser_out= fopen(value, "w")) == NULL)
179               {
180                 fprintf(stderr,
181                         "Can't open `%s': %s\n", value, strerror(errno));
182                 exit(4);
183               }
184             arguments->add(new cl_prg_arg(0, "Ser_out", Ser_out));
185             break;
186           default:
187             /* Unknown suboption. */
188             fprintf(stderr, "Unknown suboption `%s' for -S\n", value);
189             exit(1);
190             break;
191           }
192       break;
193
194     case 'h':
195
196       print_help("s51");
197       exit(0);
198       break;
199       
200     case 'H':
201       i= 0;
202       while (cpus_51[i].type_str != NULL)
203         {
204           printf("%s\n", cpus_51[i].type_str);
205           i++;
206         }
207       exit(0);
208       break;
209       
210     case '?':
211
212       if (isprint(optopt))
213         fprintf(stderr, "Unknown option `-%c'.\n", optopt);
214       else
215         fprintf(stderr, "Unknown option character `\\x%x'.\n", optopt);
216       return(1);
217       break;
218       
219     default:
220       // should never happen...
221       abort();
222     }
223   return(0);
224 }
225
226 class cl_commander *
227 cl_sim51::mk_commander(void)
228 {
229   class cl_commander *cmd= new cl_51cmd(this);
230   return(cmd);
231 }
232
233 class cl_uc *
234 cl_sim51::mk_controller(void)
235 {
236   int i;
237
238   i= 0;
239   if (get_sarg('t', 0) == NULL)
240     simulator->arguments->add(new cl_prg_arg('t', 0, "C51"));
241   while ((cpus_51[i].type_str != NULL) &&
242          (strcmp(get_sarg('t', 0), cpus_51[i].type_str) != 0))
243     i++;
244   if (cpus_51[i].type_str == NULL)
245     {
246       fprintf(stderr, "Unknown processor type. "
247               "Use -H option to see known types.\n");
248       return(NULL);
249     }
250   switch (cpus_51[i].type)
251     {
252     case CPU_51: case CPU_31:
253       return(new t_uc51(cpus_51[i].type, cpus_51[i].technology, this));
254     case CPU_52: case CPU_32:
255       return(new t_uc52(cpus_51[i].type, cpus_51[i].technology, this));
256     case CPU_51R:
257       return(new t_uc51r(cpus_51[i].type, cpus_51[i].technology, this));
258     case CPU_89C51R:
259       return(new t_uc89c51r(cpus_51[i].type, cpus_51[i].technology, this));
260     case CPU_251:
261       return(new t_uc251(cpus_51[i].type, cpus_51[i].technology, this));
262     }
263   return(NULL);
264 }
265
266 void
267 cl_sim51::build_cmd_set(void)
268 {
269   cl_sim::build_cmd_set();
270   cmdset->del("ds");
271 }
272
273
274 /* End of s51.src/sim51.cc */