2 * Simulator of microcontrollers (sim.cc)
4 * Copyright (C) 1999,99 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
55 cl_sim::cl_sim(char *more_args, int iargc, char *iargv[]):
58 argc= iargc; argv= iargv;
61 arguments= new cl_list(2, 2);
62 accept_args= more_args?strdup(more_args):0;
63 in_files= new cl_ustrings(2, 2);
72 proc_arguments(argc, argv);
76 if (!(uc= mk_controller()))
81 if (cmd->cons->get_count() == 0)
83 fprintf(stderr, "No command console available.\n");
86 for (i= 0; i < in_files->count; i++)
88 char *fname= (char *)(in_files->at(i));
90 if ((l= uc->read_hex_file(fname)) >= 0)
92 cmd->all_printf("%ld words read from %s\n", l, fname);
93 fprintf(stderr, "%ld words read from %s\n", l, fname);
97 cmd->all_print("\0", 1);
99 cmd->all_printf("%s", (prompt= get_sarg(0, "prompt"))?prompt:"> ") ;
104 cl_sim::~cl_sim(void)
111 cl_sim::proc_arguments(int argc, char *argv[])
116 opts= (char*)malloc((accept_args?strlen(accept_args):0)+100);
117 strcpy(opts, "c:p:PX:vV");
119 strcat(opts, "Z:r:");
122 strcat(opts, accept_args);
124 while((c= getopt(argc, argv, opts)) != -1)
129 arguments->add(new cl_prg_arg('c', 0, optarg));
135 arguments->add(new cl_prg_arg('Z', 0, (long long)1));
136 if (!optarg || !isdigit(*optarg))
137 fprintf(stderr, "expected portnumber to follow -Z\n");
140 long long l= strtol(optarg, &p, 0);
141 arguments->add(new cl_prg_arg(0, "Zport", l));
147 arguments->add(new cl_prg_arg(0, "prompt", optarg));
151 arguments->add(new cl_prg_arg('P', 0, (long long)1));
156 arguments->add(new cl_prg_arg('r', 0,
157 (long long)strtol(optarg, NULL, 0)));
164 for (cp= optarg; *cp; *cp= toupper(*cp), cp++);
165 XTAL= strtod(optarg, &cp);
172 fprintf(stderr, "Xtal frequency must be greather than 0\n");
175 arguments->add(new cl_prg_arg('X', 0, XTAL));
180 printf("%s: %s\n", argv[0], VERSIONSTR);
185 arguments->add(new cl_prg_arg('V', 0, (long long)1));
189 if ((c= proc_arg(c, optarg)))
194 if ((c= proc_arg(c, optarg)))
197 if (!arg_avail("prompt"))
198 arguments->add(new cl_prg_arg(0, "prompt", "> "));
200 for (i= optind; i < argc; i++)
201 in_files->add(argv[i]);
208 cl_sim::proc_arg(char arg, char *optarg)
214 cl_sim::arg_avail(char name)
219 for (i= 0; i < arguments->count; i++)
221 a= (class cl_prg_arg *)(arguments->at(i));
222 if (a->short_name == name)
229 cl_sim::arg_avail(char *name)
234 for (i= 0; i < arguments->count; i++)
236 a= (class cl_prg_arg *)(arguments->at(i));
238 strcmp(a->long_name, name) == 0)
245 cl_sim::get_iarg(char sname, char *lname)
250 for (i= 0; i < arguments->count; i++)
252 a= (class cl_prg_arg *)(arguments->at(i));
253 if ((sname && a->short_name == sname) ||
254 (lname && a->long_name && strcmp(a->long_name, lname) == 0))
255 return(a->get_ivalue());
261 cl_sim::get_sarg(char sname, char *lname)
266 for (i= 0; i < arguments->count; i++)
268 a= (class cl_prg_arg *)(arguments->at(i));
269 if ((sname && a->short_name == sname) ||
270 (lname && a->long_name && strcmp(a->long_name, lname) == 0))
271 return(a->get_svalue());
278 cl_sim::get_farg(char sname, char *lname)
283 for (i= 0; i < arguments->count; i++)
285 a= (class cl_prg_arg *)(arguments->at(i));
286 if ((sname && a->short_name == sname) ||
287 (lname && a->long_name && strcmp(a->long_name, lname) == 0))
288 return(a->get_fvalue());
294 cl_sim::get_parg(char sname, char *lname)
299 for (i= 0; i < arguments->count; i++)
301 a= (class cl_prg_arg *)(arguments->at(i));
302 if ((sname && a->short_name == sname) ||
303 (lname && a->long_name && strcmp(a->long_name, lname) == 0))
304 return(a->get_pvalue());
310 cl_sim::mk_commander()
312 class cl_commander *cmd= new cl_commander(this);
317 cl_sim::mk_controller(void)
319 return(new cl_uc(this));
323 cl_sim::mk_cmdset(void)
325 return(new cl_cmdset(this));
329 cl_sim::mk_cmd_int_arg(long long i)
331 class cl_cmd_arg *arg= new cl_cmd_int_arg(i);
337 cl_sim::mk_cmd_sym_arg(char *s)
339 class cl_cmd_arg *arg= new cl_cmd_sym_arg(s);
345 cl_sim::mk_cmd_str_arg(char *s)
347 class cl_cmd_arg *arg= new cl_cmd_str_arg(s);
353 cl_sim::mk_cmd_bit_arg(class cl_cmd_arg *sfr, class cl_cmd_arg *bit)
355 class cl_cmd_arg *arg= new cl_cmd_bit_arg(sfr, bit);
362 * Main cycle of the simulator
371 (state & SIM_QUIT) == 0)
376 if (cmd->input_avail())
377 done= cmd->proc_input();
382 done= cmd->proc_input();
389 cl_sim::do_cmd(char *cmdstr, class cl_console *console)
391 class cl_cmdline *cmdline;
395 cmdline= new cl_cmdline(cmdstr);
397 if (console->old_command(cmdline))
398 return(console->interpret(cmdstr));
399 cmd= cmdset->get_cmd(cmdline);
401 retval= cmd->work(cmdline, console);
405 return(console->interpret(cmdstr));
409 cl_sim::start(class cl_console *con)
412 con->flags|= CONS_FROZEN;
413 cmd->frozen_console= con;
417 cl_sim::stop(int reason)
420 if (cmd->frozen_console)
422 if (reason == resUSER &&
423 cmd->frozen_console->input_avail())
424 cmd->frozen_console->read_line();
425 cmd->frozen_console->printf("Stop at 0x%06x: (%d) ", uc->PC, reason);
429 cmd->frozen_console->printf("Halted\n");
432 cmd->frozen_console->printf("Invalid address\n");
435 cmd->frozen_console->printf("Stack overflow\n");
438 cmd->frozen_console->printf("Breakpoint\n");
441 cmd->frozen_console->printf("Interrupt\n");
444 cmd->frozen_console->printf("Watchdog reset\n");
447 cmd->frozen_console->printf("User stopped\n");
450 cmd->frozen_console->printf("Invalid instruction 0x%04x\n",
451 uc->get_mem(MEM_ROM, uc->PC));
454 cmd->frozen_console->printf("Unknown reason\n");
457 cmd->frozen_console->printf("F 0x%06x\n", uc->PC); // for sdcdb
458 //if (cmd->actual_console != cmd->frozen_console)
459 cmd->frozen_console->flags&= ~CONS_FROZEN;
460 cmd->frozen_console->print_prompt();
461 cmd->frozen_console= 0;
467 * Obsolete methods for old commander
474 cmd->cons->get_count() == 0)
476 if (cmd->actual_console)
477 return(cmd->actual_console->in?cmd->actual_console->in:stdin);
478 class cl_console *con= (class cl_console *)(cmd->cons->at(0));
479 return(con->in?con->in:stdin);
483 cl_sim::cmd_out(void)
486 cmd->cons->get_count() == 0)
488 if (cmd->actual_console)
489 return(cmd->actual_console->out?cmd->actual_console->out:stdout);
490 class cl_console *con= (class cl_console *)(cmd->cons->at(0));
491 return(con->out?con->out:stdout);
499 cl_sim::build_cmd_set(void)
502 class cl_cmdset *cset;
504 cmdset->add(cmd= new cl_conf_cmd(this, "conf", 0,
505 "conf Configuration",
506 "long help of conf"));
509 cmdset->add(cmd= new cl_state_cmd(this, "state", 0,
510 "state State of simulator",
511 "long help of state"));
514 cmdset->add(cmd= new cl_file_cmd(this, "file", 0,
515 "file \"FILE\" Load FILE into ROM",
516 "long help of file"));
518 cmd->add_name("load");
520 cmdset->add(cmd= new cl_dl_cmd(this, "download", 0,
521 "download,dl Load (intel.hex) data",
522 "long help of download"));
526 cset= new cl_cmdset(this);
528 cset->add(cmd= new cl_info_bp_cmd(this, "breakpoints", 0,
529 "info breakpoints Status of user-settable breakpoints",
530 "long help of info breakpoints"));
533 cset->add(cmd= new cl_info_reg_cmd(this, "registers", 0,
534 "info registers List of integer registers and their contents",
535 "long help of info registers"));
537 cset->add(cmd= new cl_info_hw_cmd(this, "hardware", 0,
538 "info hardware cathegory\n"
539 " Status of hardware elements of the CPU",
540 "long help of info hardware"));
544 cmdset->add(cmd= new cl_super_cmd(this, "info", 0,
545 "info subcommand Information, see `info' command for more help",
546 "long help of info", cset));
549 cmdset->add(cmd= new cl_get_cmd(this, "get", 0,
551 "long help of get"));
554 cmdset->add(cmd= new cl_set_cmd(this, "set", 0,
556 "long help of set"));
559 cmdset->add(cmd= new cl_timer_cmd(this, "timer", 0,
560 "timer a|d|g|r|s|v id [direction|value]\n"
561 " Timer add|del|get|run|stop|value",
562 "timer add|create|make id [direction] -- create a new timer\n"
563 "timer del id -- delete a timer\n"
564 "timer get id -- list timers\n"
565 "timer run id -- turn a timer ON\n"
566 "timer stop id -- turn a timer OFF\n"
567 "timer value id val -- set value of a timer to `val'"));
570 cmdset->add(cmd= new cl_run_cmd(this, "run", 0,
572 "long help of run"));
574 //cmd->add_name("g");
576 cmdset->add(cmd= new cl_step_cmd(this, "step", 0,
578 "long help of step"));
582 cmdset->add(cmd= new cl_reset_cmd(this, "reset", 0,
584 "long help of reset"));
587 cmdset->add(cmd= new cl_dump_cmd(this, "dump", 0,
588 "dump i|x|r|s [start [stop]]\n"
590 "long help of dump"));
593 cmdset->add(cmd= new cl_di_cmd(this, "di", 0,
594 "di [start [stop]] Dump Internal RAM",
598 cmdset->add(cmd= new cl_dx_cmd(this, "dx", 0,
599 "dx [start [stop]] Dump External RAM",
603 cmdset->add(cmd= new cl_ds_cmd(this, "ds", 0,
604 "ds [start [stop]] Dump SFR",
608 cmdset->add(cmd= new cl_dch_cmd(this, "dch", 0,
609 "dch [start [stop]] Dump code in hex form",
610 "long help of dch"));
613 cmdset->add(cmd= new cl_dc_cmd(this, "dc", 0,
614 "dc [start [stop]] Dump code in disass form",
618 cmdset->add(cmd= new cl_break_cmd(this, "break", 0,
619 "break addr [hit] Set fix breakpoint",
620 "long help of break"));
623 cmdset->add(cmd= new cl_tbreak_cmd(this, "tbreak", 0,
624 "tbreak addr [hit] Set temporary breakpoint",
625 "long help of tbreak"));
628 cmdset->add(cmd= new cl_clear_cmd(this, "clear", 0,
629 "clear [addr...] Clear fix breakpoint",
630 "long help of clear"));
633 cmdset->add(cmd= new cl_help_cmd(this, "help", 0,
635 "long help of help"));
639 cmdset->add(cmd= new cl_quit_cmd(this, "quit", 0,
641 "long help of quit"));
644 cmdset->add(cmd= new cl_kill_cmd(this, "kill", 0,
645 "kill Shutdown simulator",
646 "long help of kill"));
651 /* End of sim.src/sim.cc */