2 * Simulator of microcontrollers (app.cc)
4 * Copyright (C) 2001,01 Drotos Daniel, Talker Bt.
6 * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
10 /* This file is part of microcontroller simulator: ucsim.
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.
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.
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
40 # include HEADER_SOCKET
58 #include "cmdconfcl.h"
63 #include "newcmdwin32cl.h"
65 #include "newcmdposixcl.h"
73 /*cl_option::cl_option(int atype, char sn, char *ln)
80 long_name= strdup(ln);
81 values= new cl_ustrings(1, 1);
84 cl_option::~cl_option(void)
92 cl_option::add_value(char *value)
95 return(values->count - 1);
99 cl_option::get_value(int index)
101 if (index > values->count - 1)
103 return((char*)(values->at(index)));
106 /* List of options */
108 /*cl_options::cl_options(void):
116 ****************************************************************************
122 in_files= new cl_ustrings(2, 2, "input files");
123 options= new cl_options();
127 cl_app::~cl_app(void)
136 cl_app::init(int argc, char *argv[])
139 set_name("application");
141 proc_arguments(argc, argv);
142 class cl_cmdset *cmdset= new cl_cmdset();
144 build_cmdset(cmdset);
145 commander= new cl_commander(this, cmdset/*, sim*/);
162 if (sim->state & SIM_GO)
164 if (commander->input_avail())
165 done= commander->proc_input();
171 commander->wait_input();
172 done= commander->proc_input();
177 commander->wait_input();
178 done= commander->proc_input();
191 * Interpretation of parameters
195 print_help(const char *name)
197 printf("%s: %s\n", name, VERSIONSTR);
198 printf("Usage: %s [-hHVvP] [-p prompt] [-t CPU] [-X freq[k|M]]\n"
199 " [-c file] [-s file] [-S optionlist]"
201 " [-Z portnum] [-k portnum]"
204 " [files...]\n", name);
208 " -t CPU Type of CPU: 51, C52, 251, etc.\n"
209 " -X freq[k|M] XTAL frequency\n"
210 " -c file Open command console on `file'\n"
212 " -Z portnum Use localhost:portnumber for command console\n"
213 " -k portnum Use localhost:portnum for serial I/O\n"
215 " -s file Connect serial interface to `file'\n"
216 " -S options `options' is a comma separated list of options according to\n"
217 " serial interface. Know options are:\n"
218 " in=file serial input will be read from file named `file'\n"
219 " out=file serial output will be written to `file'\n"
220 " -p prompt Specify string for prompt\n"
221 " -P Prompt is a null ('\\0') character\n"
223 " -v Print out version number\n"
224 " -H Print out types of known CPUs\n"
225 " -h Print out this help\n"
234 static const char *S_opts[]= {
236 /*[SOPT_OUT]=*/ "out",
241 cl_app::proc_arguments(int argc, char *argv[])
244 char opts[100], *cp, *subopts, *value;
245 char *cpu_type= NULL;
246 bool s_done= DD_FALSE, k_done= DD_FALSE;
247 bool S_i_done= DD_FALSE, S_o_done= DD_FALSE;
249 strcpy(opts, "c:C:p:PX:vVt:s:S:hHk:");
251 strcat(opts, "Z:r:");
254 while((c= getopt(argc, argv, opts)) != -1)
258 if (!options->set_value("console_on", this, optarg))
259 fprintf(stderr, "Warning: No \"console_on\" option found "
263 if (!options->set_value("config_file", this, optarg))
264 fprintf(stderr, "Warning: No \"config_file\" option found to set "
265 "parameter of -C as config file\n");
273 options->new_option(o= new cl_number_option(this, "port_number",
274 "Listen on port (-Z)"));
277 if (!options->set_value("port_number", this, strtol(optarg, NULL, 0)))
278 fprintf(stderr, "Warning: No \"port_number\" option found"
279 " to set parameter of -Z as pot number to listen on\n");
284 if (!options->set_value("prompt", this, optarg))
285 fprintf(stderr, "Warning: No \"prompt\" option found to set "
286 "parameter of -p as default prompt\n");
290 if (!options->set_value("null_prompt", this, bool(DD_TRUE)))
291 fprintf(stderr, "Warning: No \"null_prompt\" option found\n");
296 for (cp= optarg; *cp; *cp= toupper(*cp), cp++);
297 XTAL= strtod(optarg, &cp);
304 fprintf(stderr, "Xtal frequency must be greather than 0\n");
307 if (!options->set_value("xtal", this, XTAL))
308 fprintf(stderr, "Warning: No \"xtal\" option found to set "
309 "parameter of -X as XTAL frequency\n");
313 printf("%s: %s\n", argv[0], VERSIONSTR);
317 if (!options->set_value("debug", this, (bool)DD_TRUE))
318 fprintf(stderr, "Warning: No \"debug\" option found to set "
319 "by -V parameter\n");
325 cpu_type= case_string(case_upper, optarg);
326 if (!options->set_value("cpu_type", this, /*optarg*/cpu_type))
327 fprintf(stderr, "Warning: No \"cpu_type\" option found to set "
328 "parameter of -t as type of controller\n");
334 /* TODO: this code should be probably used for all platforms? */
338 fprintf(stderr, "-s option can not be used more than once.\n");
342 if ((Ser= fopen(optarg, "r+")) == NULL)
345 "Can't open `%s': %s\n", optarg, strerror(errno));
348 if (!options->set_value("serial_in_file", this, Ser))
349 fprintf(stderr, "Warning: No \"serial_in_file\" option found to set "
350 "parameter of -s as serial input file\n");
351 if (!options->set_value("serial_out_file", this, Ser))
352 fprintf(stderr, "Warning: No \"serial_out_file\" option found "
353 "to set parameter of -s as serial output file\n");
355 FILE *Ser_in, *Ser_out;
358 fprintf(stderr, "-s option can not be used more than once.\n");
362 if ((Ser_in= fopen(optarg, "r")) == NULL)
365 "Can't open `%s': %s\n", optarg, strerror(errno));
368 if (!options->set_value("serial_in_file", this, Ser_in))
369 fprintf(stderr, "Warning: No \"serial_in_file\" option found to set "
370 "parameter of -s as serial input file\n");
371 if ((Ser_out= fopen(optarg, "w")) == NULL)
374 "Can't open `%s': %s\n", optarg, strerror(errno));
377 if (!options->set_value("serial_out_file", this, Ser_out))
378 fprintf(stderr, "Warning: No \"serial_out_file\" option found "
379 "to set parameter of -s as serial output file\n");
384 // socket serial I/O by Alexandre Frey <Alexandre.Frey@trusted-logic.fr>
387 FILE *Ser_in, *Ser_out;
389 unsigned short serverport;
390 UCSOCKET_T client_sock;
394 fprintf(stderr, "Serial input specified more than once.\n");
398 serverport = atoi(optarg);
399 sock = make_server_socket(serverport);
401 if (SOCKET_ERROR == listen((SOCKET)sock, 1))
403 fprintf(stderr, "Listen on port %d: %d\n", serverport,
407 fprintf(stderr, "Listening on port %d for a serial connection.\n",
409 if (INVALID_SOCKET == (client_sock = accept(sock, NULL, NULL)))
411 fprintf(stderr, "accept: %d\n", WSAGetLastError());
414 fprintf(stderr, "Serial connection established.\n");
416 int fh = _open_osfhandle((intptr_t)client_sock, 0);
419 perror("_open_osfhandle");
422 if (NULL == (Ser_in = fdopen(fh, "r")))
424 fprintf(stderr, "Can't create input stream: %s\n", strerror(errno));
428 fh = _open_osfhandle((intptr_t)client_sock, 0);
431 perror("_open_osfhandle");
433 if (NULL == (Ser_out = fdopen(fh, "w"))) {
434 fprintf(stderr, "Can't create output stream: %s\n", strerror(errno));
438 if (listen(sock, 1) < 0) {
439 fprintf(stderr, "Listen on port %d: %s\n", serverport,
443 fprintf(stderr, "Listening on port %d for a serial connection.\n",
445 if ((client_sock= accept(sock, NULL, NULL)) < 0) {
446 fprintf(stderr, "accept: %s\n", strerror(errno));
448 fprintf(stderr, "Serial connection established.\n");
450 if ((Ser_in= fdopen(client_sock, "r")) == NULL) {
451 fprintf(stderr, "Can't create input stream: %s\n", strerror(errno));
454 if ((Ser_out= fdopen(client_sock, "w")) == NULL) {
455 fprintf(stderr, "Can't create output stream: %s\n", strerror(errno));
459 if (!options->set_value("serial_in_file", this, (void*)Ser_in))
460 fprintf(stderr, "Warning: No \"serial_in_file\" option found to "
461 "set parameter of -s as serial input file\n");
462 if (!options->set_value("serial_out_file", this, Ser_out))
463 fprintf(stderr, "Warning: No \"serial_out_file\" option found "
464 "to set parameter of -s as serial output file\n");
470 while (*subopts != '\0')
471 switch (get_sub_opt(&subopts, S_opts, &value))
473 FILE *Ser_in, *Ser_out;
476 fprintf(stderr, "No value for -S in\n");
481 fprintf(stderr, "Serial input specified more than once.\n");
485 if ((Ser_in= fopen(value, "r")) == NULL)
488 "Can't open `%s': %s\n", value, strerror(errno));
491 if (!options->set_value("serial_in_file", this, (void*)Ser_in))
492 fprintf(stderr, "Warning: No \"serial_in_file\" option found "
493 "to set parameter of -s as serial input file\n");
497 fprintf(stderr, "No value for -S out\n");
502 fprintf(stderr, "Serial output specified more than once.\n");
505 if ((Ser_out= fopen(value, "w")) == NULL)
508 "Can't open `%s': %s\n", value, strerror(errno));
511 if (!options->set_value("serial_out_file", this, Ser_out))
512 fprintf(stderr, "Warning: No \"serial_out_file\" option found "
513 "to set parameter of -s as serial output file\n");
516 /* Unknown suboption. */
517 fprintf(stderr, "Unknown suboption `%s' for -S\n", value);
530 fprintf(stderr, "CPU type is not selectable\n");
534 while (cpus[i].type_str != NULL)
536 printf("%s\n", cpus[i].type_str);
544 fprintf(stderr, "Unknown option `-%c'.\n", optopt);
546 fprintf(stderr, "Unknown option character `\\x%x'.\n", optopt);
553 for (i= optind; i < argc; i++)
554 in_files->add(argv[i]);
565 return(sim->get_uc());
569 /* Command handling */
572 cl_app::get_cmd(class cl_cmdline *cmdline)
579 * Messages to broadcast
584 cl_app::mem_cell_changed(class cl_m *mem, t_addr addr)
587 sim->mem_cell_changed(mem, addr);
592 /* Adding and removing components */
595 cl_app::set_simulator(class cl_sim *simulator)
604 cl_app::remove_simulator(void)
613 cl_app::build_cmdset(class cl_cmdset *cmdset)
616 class cl_super_cmd *super_cmd;
617 class cl_cmdset *cset;
620 cset= new cl_cmdset();
622 cset->add(cmd= new cl_conf_cmd("_no_parameters_", 0,
623 "conf Configuration",
624 "long help of conf"));
626 cset->add(cmd= new cl_conf_objects_cmd("objects", 0,
627 "conf objects Show object tree",
628 "long help of conf objects"));
631 cmdset->add(cmd= new cl_super_cmd("conf", 0,
632 "conf subcommand Information, see `conf' command for more help",
633 "long help of conf", cset));
636 cmd= new cl_help_cmd("help", 0,
637 "help [command] Help about command(s)",
638 "long help of help");
643 cmdset->add(cmd= new cl_quit_cmd("quit", 0,
645 "long help of quit"));
648 cmdset->add(cmd= new cl_kill_cmd("kill", 0,
649 "kill Shutdown simulator",
650 "long help of kill"));
653 cmdset->add(cmd= new cl_exec_cmd("exec", 0,
654 "exec file Execute commands from file",
655 "long help of exec"));
658 cmdset->add(cmd= new cl_expression_cmd("expression", 0,
659 "expression expr Evaluate the expression",
660 "long help of expression "));
662 cmd->add_name("let");
665 super_cmd= (class cl_super_cmd *)(cmdset->get_cmd("show"));
667 cset= super_cmd->commands;
669 cset= new cl_cmdset();
672 cset->add(cmd= new cl_show_copying_cmd("copying", 0,
673 "show copying Conditions for redistributing copies of uCsim",
674 "long help of show copying"));
676 cset->add(cmd= new cl_show_warranty_cmd("warranty", 0,
677 "show warranty Various kinds of warranty you do not have",
678 "long help of show warranty"));
680 cset->add(cmd= new cl_show_option_cmd("option", 0,
681 "show option [name] Show internal data of options",
682 "long help of show option"));
684 cset->add(cmd= new cl_show_error_cmd("error", 0,
685 "show error Show class of errors",
686 "long help of show error"));
691 cmdset->add(cmd= new cl_super_cmd("show", 0,
692 "show subcommand Generic command for showing things about the uCsim",
693 "long help of show", cset));
698 super_cmd= (class cl_super_cmd *)(cmdset->get_cmd("get"));
700 cset= super_cmd->commands;
702 cset= new cl_cmdset();
705 cset->add(cmd= new cl_get_option_cmd("option", 0,
706 "get option [name] Get value of an option",
707 "long help of get option"));
712 cmdset->add(cmd= new cl_super_cmd("get", 0,
713 "get subcommand Get, see `get' command for more help",
714 "long help of get", cset));
719 super_cmd= (class cl_super_cmd *)(cmdset->get_cmd("set"));
721 cset= super_cmd->commands;
723 cset= new cl_cmdset();
726 cset->add(cmd= new cl_set_option_cmd("option", 0,
727 "set option name|nr value\n"
728 " Set value of an option",
729 "long help of set option"));
731 cset->add(cmd= new cl_set_error_cmd("error", 0,
732 "set error error_name on|off|unset\n"
733 " Set value of an error",
734 "long help of set error"));
739 cmdset->add(cmd= new cl_super_cmd("set", 0,
740 "set subcommand Set, see `set' command for more help",
741 "long help of set", cset));
747 cl_app::mk_options(void)
751 options->new_option(o= new cl_bool_option(this, "null_prompt",
752 "Use \\0 as prompt (-P)"));
755 options->new_option(o= new cl_pointer_option(this, "serial_in_file",
756 "Input file for serial line (-s)"));
760 options->new_option(o= new cl_pointer_option(this, "serial_out_file",
761 "Output file for serial line (-s)"));
765 options->new_option(o= new cl_string_option(this, "prompt",
766 "String of prompt (-p)"));
769 options->new_option(o= new cl_bool_option(this, "debug",
770 "Print debug messages (-V)"));
773 options->new_option(o= new cl_string_option(this, "console_on",
774 "Open console on this file (-c)"));
778 options->new_option(o= new cl_string_option(this, "config_file",
779 "Execute this file at startup (-C)"));
783 options->new_option(o= new cl_float_option(this, "xtal",
784 "Frequency of XTAL in Hz"));
786 o->set_value(11059200.0);
788 options->new_option(o= new cl_string_option(this, "cpu_type",
789 "Type of controller (-t)"));
796 cl_app::dd_printf(const char *format, ...)
803 va_start(ap, format);
804 int i= commander->dd_printf(format, ap);
810 cl_app::debug(const char *format, ...)
817 va_start(ap, format);
818 int i= commander->debug(format, ap);