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
38 #include <sys/socket.h>
56 #include "cmdconfcl.h"
66 /*cl_option::cl_option(int atype, char sn, char *ln)
73 long_name= strdup(ln);
74 values= new cl_ustrings(1, 1);
77 cl_option::~cl_option(void)
85 cl_option::add_value(char *value)
88 return(values->count - 1);
92 cl_option::get_value(int index)
94 if (index > values->count - 1)
96 return((char*)(values->at(index)));
101 /*cl_options::cl_options(void):
109 ****************************************************************************
115 in_files= new cl_ustrings(2, 2, "input files");
116 options= new cl_options();
120 cl_app::~cl_app(void)
129 cl_app::init(int argc, char *argv[])
132 set_name("application");
134 proc_arguments(argc, argv);
135 class cl_cmdset *cmdset= new cl_cmdset();
137 build_cmdset(cmdset);
138 commander= new cl_commander(this, cmdset/*, sim*/);
155 if (sim->state & SIM_GO)
157 if (commander->input_avail())
158 done= commander->proc_input();
164 commander->wait_input();
165 done= commander->proc_input();
170 commander->wait_input();
171 done= commander->proc_input();
184 * Interpretation of parameters
188 print_help(char *name)
190 printf("%s: %s\n", name, VERSIONSTR);
191 printf("Usage: %s [-hHVvP] [-p prompt] [-t CPU] [-X freq[k|M]]\n"
192 " [-c file] [-s file] [-S optionlist]"
194 " [-Z portnum] [-k portnum]"
197 " [files...]\n", name);
201 " -t CPU Type of CPU: 51, C52, 251, etc.\n"
202 " -X freq[k|M] XTAL frequency\n"
203 " -c file Open command console on `file'\n"
205 " -Z portnum Use localhost:portnumber for command console\n"
206 " -k portnum Use localhost:portnum for serial I/O\n"
208 " -s file Connect serial interface to `file'\n"
209 " -S options `options' is a comma separated list of options according to\n"
210 " serial interface. Know options are:\n"
211 " in=file serial input will be read from file named `file'\n"
212 " out=file serial output will be written to `file'\n"
213 " -p prompt Specify string for prompt\n"
214 " -P Prompt is a null ('\\0') character\n"
216 " -v Print out version number\n"
217 " -H Print out types of known CPUs\n"
218 " -h Print out this help\n"
227 static const char *S_opts[]= {
229 /*[SOPT_OUT]=*/ "out",
234 cl_app::proc_arguments(int argc, char *argv[])
237 char opts[100], *cp, *subopts, *value;
238 char *cpu_type= NULL;
239 bool s_done= DD_FALSE, k_done= DD_FALSE;
240 bool S_i_done= DD_FALSE, S_o_done= DD_FALSE;
242 strcpy(opts, "c:C:p:PX:vVt:s:S:hHk:");
244 strcat(opts, "Z:r:");
247 while((c= getopt(argc, argv, opts)) != -1)
251 if (!options->set_value("console_on", this, optarg))
252 fprintf(stderr, "Warning: No \"console_on\" option found "
256 if (!options->set_value("config_file", this, optarg))
257 fprintf(stderr, "Warning: No \"config_file\" option found to set "
258 "parameter of -C as config file\n");
266 options->new_option(o= new cl_number_option(this, "port_number",
267 "Listen on port (-Z)"));
270 if (!options->set_value("port_number", this, strtol(optarg, NULL, 0)))
271 fprintf(stderr, "Warning: No \"port_number\" option found"
272 " to set parameter of -Z as pot number to listen on\n");
277 if (!options->set_value("prompt", this, optarg))
278 fprintf(stderr, "Warning: No \"prompt\" option found to set "
279 "parameter of -p as default prompt\n");
283 if (!options->set_value("null_prompt", this, bool(DD_TRUE)))
284 fprintf(stderr, "Warning: No \"null_prompt\" option found\n");
289 for (cp= optarg; *cp; *cp= toupper(*cp), cp++);
290 XTAL= strtod(optarg, &cp);
297 fprintf(stderr, "Xtal frequency must be greather than 0\n");
300 if (!options->set_value("xtal", this, XTAL))
301 fprintf(stderr, "Warning: No \"xtal\" option found to set "
302 "parameter of -X as XTAL frequency\n");
306 printf("%s: %s\n", argv[0], VERSIONSTR);
310 if (!options->set_value("debug", this, (bool)DD_TRUE))
311 fprintf(stderr, "Warning: No \"debug\" option found to set "
312 "by -V parameter\n");
318 cpu_type= case_string(case_upper, optarg);
319 if (!options->set_value("cpu_type", this, /*optarg*/cpu_type))
320 fprintf(stderr, "Warning: No \"cpu_type\" option found to set "
321 "parameter of -t as type of controller\n");
326 FILE *Ser_in, *Ser_out;
329 fprintf(stderr, "-s option can not be used more than once.\n");
333 if ((Ser_in= fopen(optarg, "r")) == NULL)
336 "Can't open `%s': %s\n", optarg, strerror(errno));
339 if (!options->set_value("serial_in_file", this, (void*)Ser_in))
340 fprintf(stderr, "Warning: No \"serial_in_file\" option found to set "
341 "parameter of -s as serial input file\n");
342 if ((Ser_out= fopen(optarg, "w")) == NULL)
345 "Can't open `%s': %s\n", optarg, strerror(errno));
348 if (!options->set_value("serial_out_file", this, Ser_out))
349 fprintf(stderr, "Warning: No \"serial_out_file\" option found "
350 "to set parameter of -s as serial output file\n");
354 // socket serial I/O by Alexandre Frey <Alexandre.Frey@trusted-logic.fr>
357 FILE *Ser_in, *Ser_out;
359 unsigned short serverport;
363 fprintf(stderr, "Serial input specified more than once.\n");
367 serverport = atoi(optarg);
368 sock= make_server_socket(serverport);
369 if (listen(sock, 1) < 0) {
370 fprintf(stderr, "Listen on port %d: %s\n", serverport,
374 fprintf(stderr, "Listening on port %d for a serial connection.\n",
376 if ((client_sock= accept(sock, NULL, NULL)) < 0) {
377 fprintf(stderr, "accept: %s\n", strerror(errno));
379 fprintf(stderr, "Serial connection established.\n");
381 if ((Ser_in= fdopen(client_sock, "r")) == NULL) {
382 fprintf(stderr, "Can't create input stream: %s\n", strerror(errno));
385 if (!options->set_value("serial_in_file", this, (void*)Ser_in))
386 fprintf(stderr, "Warning: No \"serial_in_file\" option found to "
387 "set parameter of -s as serial input file\n");
388 if ((Ser_out= fdopen(client_sock, "w")) == NULL) {
389 fprintf(stderr, "Can't create output stream: %s\n", strerror(errno));
392 if (!options->set_value("serial_out_file", this, Ser_out))
393 fprintf(stderr, "Warning: No \"serial_out_file\" option found "
394 "to set parameter of -s as serial output file\n");
400 while (*subopts != '\0')
401 switch (get_sub_opt(&subopts, S_opts, &value))
403 FILE *Ser_in, *Ser_out;
406 fprintf(stderr, "No value for -S in\n");
411 fprintf(stderr, "Serial input specified more than once.\n");
415 if ((Ser_in= fopen(value, "r")) == NULL)
418 "Can't open `%s': %s\n", value, strerror(errno));
421 if (!options->set_value("serial_in_file", this, (void*)Ser_in))
422 fprintf(stderr, "Warning: No \"serial_in_file\" option found "
423 "to set parameter of -s as serial input file\n");
427 fprintf(stderr, "No value for -S out\n");
432 fprintf(stderr, "Serial output specified more than once.\n");
435 if ((Ser_out= fopen(value, "w")) == NULL)
438 "Can't open `%s': %s\n", value, strerror(errno));
441 if (!options->set_value("serial_out_file", this, Ser_out))
442 fprintf(stderr, "Warning: No \"serial_out_file\" option found "
443 "to set parameter of -s as serial output file\n");
446 /* Unknown suboption. */
447 fprintf(stderr, "Unknown suboption `%s' for -S\n", value);
460 fprintf(stderr, "CPU type is not selectable\n");
464 while (cpus[i].type_str != NULL)
466 printf("%s\n", cpus[i].type_str);
474 fprintf(stderr, "Unknown option `-%c'.\n", optopt);
476 fprintf(stderr, "Unknown option character `\\x%x'.\n", optopt);
483 for (i= optind; i < argc; i++)
484 in_files->add(argv[i]);
495 return(sim->get_uc());
499 /* Command handling */
502 cl_app::get_cmd(class cl_cmdline *cmdline)
509 * Messages to broadcast
514 cl_app::mem_cell_changed(class cl_m *mem, t_addr addr)
517 sim->mem_cell_changed(mem, addr);
522 /* Adding and removing components */
525 cl_app::set_simulator(class cl_sim *simulator)
534 cl_app::remove_simulator(void)
543 cl_app::build_cmdset(class cl_cmdset *cmdset)
546 class cl_super_cmd *super_cmd;
547 class cl_cmdset *cset;
550 cset= new cl_cmdset();
552 cset->add(cmd= new cl_conf_cmd("_no_parameters_", 0,
553 "conf Configuration",
554 "long help of conf"));
556 cset->add(cmd= new cl_conf_objects_cmd("objects", 0,
557 "conf objects Show object tree",
558 "long help of conf objects"));
561 cmdset->add(cmd= new cl_super_cmd("conf", 0,
562 "conf subcommand Information, see `conf' command for more help",
563 "long help of conf", cset));
566 cmd= new cl_help_cmd("help", 0,
567 "help [command] Help about command(s)",
568 "long help of help");
573 cmdset->add(cmd= new cl_quit_cmd("quit", 0,
575 "long help of quit"));
578 cmdset->add(cmd= new cl_kill_cmd("kill", 0,
579 "kill Shutdown simulator",
580 "long help of kill"));
583 cmdset->add(cmd= new cl_exec_cmd("exec", 0,
584 "exec file Execute commands from file",
585 "long help of exec"));
588 cmdset->add(cmd= new cl_expression_cmd("expression", 0,
589 "expression expr Evaluate the expression",
590 "long help of expression "));
592 cmd->add_name("let");
595 super_cmd= (class cl_super_cmd *)(cmdset->get_cmd("show"));
597 cset= super_cmd->commands;
599 cset= new cl_cmdset();
602 cset->add(cmd= new cl_show_copying_cmd("copying", 0,
603 "show copying Conditions for redistributing copies of uCsim",
604 "long help of show copying"));
606 cset->add(cmd= new cl_show_warranty_cmd("warranty", 0,
607 "show warranty Various kinds of warranty you do not have",
608 "long help of show warranty"));
610 cset->add(cmd= new cl_show_option_cmd("option", 0,
611 "show option [name] Show internal data of options",
612 "long help of show option"));
614 cset->add(cmd= new cl_show_error_cmd("error", 0,
615 "show error Show class of errors",
616 "long help of show error"));
621 cmdset->add(cmd= new cl_super_cmd("show", 0,
622 "show subcommand Generic command for showing things about the uCsim",
623 "long help of show", cset));
628 super_cmd= (class cl_super_cmd *)(cmdset->get_cmd("get"));
630 cset= super_cmd->commands;
632 cset= new cl_cmdset();
635 cset->add(cmd= new cl_get_option_cmd("option", 0,
636 "get option [name] Get value of an option",
637 "long help of get option"));
642 cmdset->add(cmd= new cl_super_cmd("get", 0,
643 "get subcommand Get, see `get' command for more help",
644 "long help of get", cset));
649 super_cmd= (class cl_super_cmd *)(cmdset->get_cmd("set"));
651 cset= super_cmd->commands;
653 cset= new cl_cmdset();
656 cset->add(cmd= new cl_set_option_cmd("option", 0,
657 "set option name|nr value\n"
658 " Set value of an option",
659 "long help of set option"));
661 cset->add(cmd= new cl_set_error_cmd("error", 0,
662 "set error error_name on|off|unset\n"
663 " Set value of an error",
664 "long help of set error"));
669 cmdset->add(cmd= new cl_super_cmd("set", 0,
670 "set subcommand Set, see `set' command for more help",
671 "long help of set", cset));
677 cl_app::mk_options(void)
681 options->new_option(o= new cl_bool_option(this, "null_prompt",
682 "Use \\0 as prompt (-P)"));
685 options->new_option(o= new cl_pointer_option(this, "serial_in_file",
686 "Input file for serial line (-s)"));
690 options->new_option(o= new cl_pointer_option(this, "serial_out_file",
691 "Output file for serial line (-s)"));
695 options->new_option(o= new cl_string_option(this, "prompt",
696 "String of prompt (-p)"));
699 options->new_option(o= new cl_bool_option(this, "debug",
700 "Print debug messages (-V)"));
703 options->new_option(o= new cl_string_option(this, "console_on",
704 "Open console on this file (-c)"));
708 options->new_option(o= new cl_string_option(this, "config_file",
709 "Execute this file at startup (-C)"));
713 options->new_option(o= new cl_float_option(this, "xtal",
714 "Frequency of XTAL in Hz"));
716 o->set_value(11059200.0);
718 options->new_option(o= new cl_string_option(this, "cpu_type",
719 "Type of controller (-t)"));
726 cl_app::dd_printf(char *format, ...)
733 va_start(ap, format);
734 int i= commander->dd_printf(format, ap);
740 cl_app::debug(char *format, ...)
747 va_start(ap, format);
748 int i= commander->debug(format, ap);