[ucsim] Update email and file info, fix stm8 flash controller
[sdcc.git] / sdcc / sim / ucsim / src / sims / pblaze.src / apppblaze.cc
blobff15122fffc92ec50769fa13f7cb02667a559309
1 /*
2 * Copyright (C) 2012-2013 Jiří Šimek
3 * Copyright (C) 2013 Zbyněk Křivka <krivka@fit.vutbr.cz>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
22 #include "ddconfig.h"
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <stdarg.h>
27 #ifdef HAVE_UNISTD_H
28 # include <unistd.h>
29 #endif
30 #ifdef HAVE_GETOPT_H
31 # include <getopt.h>
32 #endif
33 #ifdef SOCKET_AVAIL
34 # include HEADER_SOCKET
35 #endif
36 #include <ctype.h>
37 #include <errno.h>
38 #include "i_string.h"
40 // prj
41 #include "utils.h"
42 #include "apppblazecl.h"
43 #include "optioncl.h"
44 #include "globals.h"
46 // sim.src
47 #include "simcl.h"
49 // cmd.src
50 #include "newcmdcl.h"
51 #include "cmdutil.h"
52 #include "cmd_confcl.h"
53 #include "cmd_showcl.h"
54 #include "cmd_getcl.h"
55 #include "cmd_setcl.h"
56 //#ifdef _WIN32
57 //#include "newcmdwin32cl.h"
58 //#else
59 #include "newcmdposixcl.h"
60 //#endif
62 /* XXX */
63 #define PORTVERSION "0.2.0"
65 * Interpretation of parameters
68 static void
69 print_help(const char *name)
71 printf("%s: %s (uCsim %s)\n", name, PORTVERSION, VERSIONSTR);
72 printf("Usage: %s [-hHVvP] [-p prompt] [-t CPU] [-X freq[k|M]]\n"
73 " [-c file] [-s file] [-S optionlist]"
74 #ifdef SOCKET_AVAIL
75 " [-Z portnum] [-k portnum]"
76 #endif
77 "\n"
78 " [files...]\n", name);
79 printf
81 "Options:\n"
82 " -t CPU Type of CPU: kcpsm3 or kcpsm6\n"
83 " -X freq[k|M] XTAL frequency\n"
84 " -c file Open command console on `file'\n"
85 #ifdef SOCKET_AVAIL
86 " -Z portnum Use localhost:portnumber for command console\n"
87 " -k portnum Use localhost:portnum for serial I/O\n"
88 #endif
89 " -s file Connect serial interface to `file'\n"
90 " -S options `options' is a comma separated list of options according to\n"
91 " serial interface. Know options are:\n"
92 " in=file serial input will be read from file named `file'\n"
93 " out=file serial output will be written to `file'\n"
94 " -p prompt Specify string for prompt\n"
95 " -P Prompt is a null ('\\0') character\n"
96 " -V Verbose mode\n"
97 " -v Print out version number\n"
98 " -H Print out types of known CPUs\n"
99 " -h Print out this help\n"
101 " -x Input file format isn't Intel HEX file, but raw HEX file for PicoBlaze\n"
102 " -i file Read file with interrupts\n"
103 " -I value Address of interrupt vector\n"
104 " -m value Size of RAM (only for KCPSM6). Valid values are 64, 128 and 256.\n"
105 " -M value Size of ROM (only for KCPSM6). Valid values are 1024, 2048 and 4096.\n"
106 " -n file Loads file with inputs.\n"
107 " -w value Built-in hardware constant (only for KCPSM6).\n"
108 " -o file At the end of simulation saves PicoBlaze state and PicoBlaze outputs into files <file>_state.xml and <file>_outputs.xml.\n"
109 "\n"
110 "Authors: Jiri Simek and Zbynek Krivka (krivka@fit.vutbr.cz)\n"
111 "\n"
112 "Acknowledgement: This software tool has been elaborated in the\n"
113 "framework of the IT4Innovations Centre of Excellence project, \n"
114 "reg. no. CZ.1.05/1.1.00/02.0070 supported by Operational Programme\n"
115 "'Research and Development for Innovations' funded by Structural Funds\n"
116 "of the European Union and state budget of the Czech Republic.\n"
120 enum {
121 SOPT_IN= 0,
122 SOPT_OUT
125 static const char *S_opts[]= {
126 /*[SOPT_IN]=*/ "in",
127 /*[SOPT_OUT]=*/ "out",
128 NULL
133 cl_apppblaze::proc_arguments(int argc, char *argv[])
135 int i, c;
136 char opts[100], *cp, *subopts, *value;
137 char *cpu_type= NULL;
138 bool s_done= false, k_done= false;
139 bool S_i_done= false, S_o_done= false;
141 strcpy(opts, "c:C:p:PX:vVt:s:S:hHk:xi:I:m:M:w:n:o:");
142 #ifdef SOCKET_AVAIL
143 strcat(opts, "Z:r:");
144 #endif
146 while((c= getopt(argc, argv, opts)) != -1)
147 switch (c)
149 /* ADDED by Jiri Simek */
150 case 'x':
153 class cl_option *o;
154 options->new_option(o= new cl_bool_option(this, "pblaze_hex","Read pblaze hex file"));
155 o->init();
157 if (!options->set_value("pblaze_hex", this, (bool)true))
158 fprintf(stderr, "Warning: Cannot set option -x");
160 o = options->get_option("pblaze_hex");
161 bool v;
162 o->get_value(&v);
163 break;
165 case 'i':
167 class cl_option *o;
168 options->new_option(o= new cl_string_option(this, "pblaze_interrupt_file","File with interrupts is specified"));
169 o->init();
171 if (!options->set_value("pblaze_interrupt_file", this, optarg))
172 fprintf(stderr, "Warning: No \"pblaze_interrupt_file\" option found to set "
173 "parameter of -i as interrupt file\n");
174 break;
176 case 'I':
178 class cl_option *o;
179 options->new_option(o= new cl_number_option(this, "pblaze_interrupt_vector","Address of interrupt vector"));
180 o->init();
182 if (!options->set_value("pblaze_interrupt_vector", this, optarg))
183 fprintf(stderr, "Warning: No \"pblaze_interrupt_vector\" option found to set "
184 "parameter of -I as interrupt vector\n");
185 break;
187 case 'm':
189 class cl_option *o;
190 options->new_option(o= new cl_number_option(this, "pblaze_ram_size","Set RAM size"));
191 o->init();
193 if (!options->set_value("pblaze_ram_size", this, strtol(optarg, NULL, 0)))
194 fprintf(stderr, "Warning: No \"pblaze_ram_size\" option found to set "
195 "parameter of -m as RAM size\n");
196 break;
198 case 'n':
200 class cl_option *o;
201 options->new_option(o= new cl_string_option(this, "pblaze_input_file","File with inputs is specified"));
202 o->init();
204 if (!options->set_value("pblaze_input_file", this, optarg))
205 fprintf(stderr, "Warning: No \"pblaze_input_file\" option found to set "
206 "parameter of -i as interrupt file\n");
207 break;
209 case 'M':
211 class cl_option *o;
212 options->new_option(o= new cl_number_option(this, "pblaze_rom_size","Set ROM size"));
213 o->init();
215 if (!options->set_value("pblaze_rom_size", this, strtol(optarg, NULL, 0)))
216 fprintf(stderr, "Warning: No \"pblaze_rom_size\" option found to set "
217 "parameter of -M as ROM size\n");
218 break;
220 case 'w':
222 class cl_option *o;
223 options->new_option(o= new cl_number_option(this, "pblaze_hw_const","Builtin hardware constant"));
224 o->init();
226 if (!options->set_value("pblaze_hw_const", this, strtol(optarg, NULL, 0)))
227 fprintf(stderr, "Warning: No \"pblaze_hw_const\" option found to set "
228 "parameter of -w as builtin hardware constant\n");
229 break;
231 case 'o':
233 class cl_option *o;
234 options->new_option(o= new cl_string_option(this, "pblaze_output_file","Part of file names with PicoBlaze state and outputs at the end of simulation"));
235 o->init();
237 if (!options->set_value("pblaze_output_file", this, optarg))
238 fprintf(stderr, "Warning: No \"pblaze_output_file\" option found to set "
239 "parameter of -o as output files\n");
240 break;
245 // default parameters
246 case 'c':
247 if (!options->set_value("console_on", this, optarg))
248 fprintf(stderr, "Warning: No \"console_on\" option found "
249 "to set by -c\n");
250 break;
251 case 'C':
252 if (!options->set_value("config_file", this, optarg))
253 fprintf(stderr, "Warning: No \"config_file\" option found to set "
254 "parameter of -C as config file\n");
255 break;
256 #ifdef SOCKET_AVAIL
257 case 'Z': case 'r':
259 // By Sandeep
260 // Modified by DD
261 class cl_option *o;
262 options->new_option(o= new cl_number_option(this, "port_number",
263 "Listen on port (-Z)"));
264 o->init();
265 o->hide();
266 if (!options->set_value("port_number", this, strtol(optarg, NULL, 0)))
267 fprintf(stderr, "Warning: No \"port_number\" option found"
268 " to set parameter of -Z as pot number to listen on\n");
269 break;
271 #endif
272 case 'p': {
273 if (!options->set_value("prompt", this, optarg))
274 fprintf(stderr, "Warning: No \"prompt\" option found to set "
275 "parameter of -p as default prompt\n");
276 break;
278 case 'P':
279 if (!options->set_value("null_prompt", this, bool(true)))
280 fprintf(stderr, "Warning: No \"null_prompt\" option found\n");
281 break;
282 case 'X':
284 double XTAL;
285 for (cp= optarg; *cp; *cp= toupper(*cp), cp++);
286 XTAL= strtod(optarg, &cp);
287 if (*cp == 'K')
288 XTAL*= 1e3;
289 if (*cp == 'M')
290 XTAL*= 1e6;
291 if (XTAL == 0)
293 fprintf(stderr, "Xtal frequency must be greater than 0\n");
294 exit(1);
296 if (!options->set_value("xtal", this, XTAL))
297 fprintf(stderr, "Warning: No \"xtal\" option found to set "
298 "parameter of -X as XTAL frequency\n");
299 break;
301 case 'v':
302 printf("%s: %s\n", argv[0], VERSIONSTR);
303 exit(0);
304 break;
305 case 'V':
306 if (!options->set_value("debug", this, (bool)true))
307 fprintf(stderr, "Warning: No \"debug\" option found to set "
308 "by -V parameter\n");
309 break;
310 case 't':
312 if (cpu_type)
313 free(cpu_type);
314 cpu_type= case_string(case_upper, optarg);
315 if (!options->set_value("cpu_type", this, /*optarg*/cpu_type))
316 fprintf(stderr, "Warning: No \"cpu_type\" option found to set "
317 "parameter of -t as type of controller\n");
318 break;
320 case 's':
322 #ifdef _WIN32
323 /* TODO: this code should be probably used for all platforms? */
324 FILE *Ser;
325 if (s_done)
327 fprintf(stderr, "-s option can not be used more than once.\n");
328 break;
330 s_done= true;
331 if ((Ser= fopen(optarg, "r+")) == NULL)
333 fprintf(stderr,
334 "Can't open `%s': %s\n", optarg, strerror(errno));
335 return(4);
337 if (!options->set_value("serial_in_file", this, Ser))
338 fprintf(stderr, "Warning: No \"serial_in_file\" option found to set "
339 "parameter of -s as serial input file\n");
340 if (!options->set_value("serial_out_file", this, Ser))
341 fprintf(stderr, "Warning: No \"serial_out_file\" option found "
342 "to set parameter of -s as serial output file\n");
343 #else
344 FILE *Ser_in, *Ser_out;
345 if (s_done)
347 fprintf(stderr, "-s option can not be used more than once.\n");
348 break;
350 s_done= true;
351 if ((Ser_in= fopen(optarg, "r")) == NULL)
353 fprintf(stderr,
354 "Can't open `%s': %s\n", optarg, strerror(errno));
355 return(4);
357 if (!options->set_value("serial_in_file", this, Ser_in))
358 fprintf(stderr, "Warning: No \"serial_in_file\" option found to set "
359 "parameter of -s as serial input file\n");
360 if ((Ser_out= fopen(optarg, "w")) == NULL)
362 fprintf(stderr,
363 "Can't open `%s': %s\n", optarg, strerror(errno));
364 return(4);
366 if (!options->set_value("serial_out_file", this, Ser_out))
367 fprintf(stderr, "Warning: No \"serial_out_file\" option found "
368 "to set parameter of -s as serial output file\n");
369 #endif
370 break;
372 #ifdef SOCKET_AVAIL
373 // socket serial I/O by Alexandre Frey <Alexandre.Frey@trusted-logic.fr>
374 case 'k':
376 FILE *Ser_in, *Ser_out;
377 UCSOCKET_T sock;
378 unsigned short serverport;
379 UCSOCKET_T client_sock;
381 if (k_done)
383 fprintf(stderr, "Serial input specified more than once.\n");
385 k_done= true;
387 serverport = atoi(optarg);
388 sock = make_server_socket(serverport);
389 #ifdef _WIN32
390 if (SOCKET_ERROR == listen((SOCKET)sock, 1))
392 fprintf(stderr, "Listen on port %d: %d\n", serverport,
393 WSAGetLastError());
394 return (4);
396 fprintf(stderr, "Listening on port %d for a serial connection.\n",
397 serverport);
398 if (INVALID_SOCKET == (client_sock = accept(sock, NULL, NULL)))
400 fprintf(stderr, "accept: %d\n", WSAGetLastError());
401 return (4);
403 fprintf(stderr, "Serial connection established.\n");
405 int fh = _open_osfhandle((intptr_t)client_sock, 0);
406 if (-1 == fh)
408 perror("_open_osfhandle");
409 return (4);
411 if (NULL == (Ser_in = fdopen(fh, "r")))
413 fprintf(stderr, "Can't create input stream: %s\n", strerror(errno));
414 return (4);
417 fh = _open_osfhandle((intptr_t)client_sock, 0);
418 if (-1 == fh)
420 perror("_open_osfhandle");
422 if (NULL == (Ser_out = fdopen(fh, "w"))) {
423 fprintf(stderr, "Can't create output stream: %s\n", strerror(errno));
424 return (4);
426 #else
427 if (listen(sock, 1) < 0) {
428 fprintf(stderr, "Listen on port %d: %s\n", serverport,
429 strerror(errno));
430 return (4);
432 fprintf(stderr, "Listening on port %d for a serial connection.\n",
433 serverport);
434 if ((client_sock= accept(sock, NULL, NULL)) < 0) {
435 fprintf(stderr, "accept: %s\n", strerror(errno));
437 fprintf(stderr, "Serial connection established.\n");
439 if ((Ser_in= fdopen(client_sock, "r")) == NULL) {
440 fprintf(stderr, "Can't create input stream: %s\n", strerror(errno));
441 return (4);
443 if ((Ser_out= fdopen(client_sock, "w")) == NULL) {
444 fprintf(stderr, "Can't create output stream: %s\n", strerror(errno));
445 return (4);
447 #endif
448 if (!options->set_value("serial_in_file", this, (void*)Ser_in))
449 fprintf(stderr, "Warning: No \"serial_in_file\" option found to "
450 "set parameter of -s as serial input file\n");
451 if (!options->set_value("serial_out_file", this, Ser_out))
452 fprintf(stderr, "Warning: No \"serial_out_file\" option found "
453 "to set parameter of -s as serial output file\n");
454 break;
456 #endif
457 case 'S':
458 subopts= optarg;
459 while (*subopts != '\0')
460 switch (get_sub_opt(&subopts, S_opts, &value))
462 FILE *Ser_in, *Ser_out;
463 case SOPT_IN:
464 if (value == NULL) {
465 fprintf(stderr, "No value for -S in\n");
466 exit(1);
468 if (S_i_done)
470 fprintf(stderr, "Serial input specified more than once.\n");
471 break;
473 S_i_done= true;
474 if ((Ser_in= fopen(value, "r")) == NULL)
476 fprintf(stderr,
477 "Can't open `%s': %s\n", value, strerror(errno));
478 exit(4);
480 if (!options->set_value("serial_in_file", this, (void*)Ser_in))
481 fprintf(stderr, "Warning: No \"serial_in_file\" option found "
482 "to set parameter of -s as serial input file\n");
483 break;
484 case SOPT_OUT:
485 if (value == NULL) {
486 fprintf(stderr, "No value for -S out\n");
487 exit(1);
489 if (S_o_done)
491 fprintf(stderr, "Serial output specified more than once.\n");
492 break;
494 if ((Ser_out= fopen(value, "w")) == NULL)
496 fprintf(stderr,
497 "Can't open `%s': %s\n", value, strerror(errno));
498 exit(4);
500 if (!options->set_value("serial_out_file", this, Ser_out))
501 fprintf(stderr, "Warning: No \"serial_out_file\" option found "
502 "to set parameter of -s as serial output file\n");
503 break;
504 default:
505 /* Unknown suboption. */
506 fprintf(stderr, "Unknown suboption `%s' for -S\n", value);
507 exit(1);
508 break;
510 break;
511 case 'h':
512 print_help("spblaze");
513 exit(0);
514 break;
515 case 'H':
517 if (!cpus)
519 fprintf(stderr, "CPU type is not selectable\n");
520 exit(0);
522 i= 0;
523 while (cpus[i].type_str != NULL)
525 printf("%s\n", cpus[i].type_str);
526 i++;
528 exit(0);
529 break;
531 case '?':
532 if (isprint(optopt))
533 fprintf(stderr, "Unknown option `-%c'.\n", optopt);
534 else
535 fprintf(stderr, "Unknown option character `\\x%x'.\n", optopt);
536 return(1);
537 break;
538 default:
539 exit(c);
542 for (i= optind; i < argc; i++)
543 in_files->add(argv[i]);
545 return(0);
548 /* End of pblaze.src/apppblaze.cc */