summaryrefslogtreecommitdiff
path: root/sim/ucsim/sim.src/sim.cc
diff options
context:
space:
mode:
authorXavier ASUS <xavi92psx@gmail.com>2019-10-18 00:31:54 +0200
committerXavier ASUS <xavi92psx@gmail.com>2019-10-18 00:31:54 +0200
commit268a53de823a6750d6256ee1fb1e7707b4b45740 (patch)
tree42c1799a9a82b2f7d9790ee9fe181d72a7274751 /sim/ucsim/sim.src/sim.cc
downloadsdcc-gas-268a53de823a6750d6256ee1fb1e7707b4b45740.tar.gz
sdcc-3.9.0 fork implementing GNU assembler syntax
This fork aims to provide better support for stm8-binutils
Diffstat (limited to 'sim/ucsim/sim.src/sim.cc')
-rw-r--r--sim/ucsim/sim.src/sim.cc372
1 files changed, 372 insertions, 0 deletions
diff --git a/sim/ucsim/sim.src/sim.cc b/sim/ucsim/sim.src/sim.cc
new file mode 100644
index 0000000..9b71c3c
--- /dev/null
+++ b/sim/ucsim/sim.src/sim.cc
@@ -0,0 +1,372 @@
+/*
+ * Simulator of microcontrollers (sim.cc)
+ *
+ * Copyright (C) 1999,99 Drotos Daniel, Talker Bt.
+ *
+ * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
+ *
+ */
+
+/* This file is part of microcontroller simulator: ucsim.
+
+UCSIM is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+UCSIM is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with UCSIM; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+/*@1@*/
+
+#include "ddconfig.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "i_string.h"
+
+// prj
+#include "globals.h"
+#include "utils.h"
+
+// cmd
+#include "cmd_execcl.h"
+#include "cmd_guicl.h"
+
+// local, sim.src
+#include "simcl.h"
+#include "appcl.h"
+#include "simifcl.h"
+
+
+/*
+ * Simulator
+ */
+
+cl_sim::cl_sim(class cl_app *the_app):
+ cl_base()
+{
+ app= the_app;
+ uc= 0;
+ state= SIM_NONE;
+ //arguments= new cl_list(2, 2);
+ //accept_args= more_args?strdup(more_args):0;
+ gui= new cl_gui(this);
+}
+
+int
+cl_sim::init(void)
+{
+ cl_base::init();
+ build_cmdset(app->get_commander()->cmdset);
+ if (!(uc= mk_controller()))
+ return(1);
+ uc->init();
+ simif= uc->get_hw(cchars("simif"), 0);
+ return(0);
+}
+
+cl_sim::~cl_sim(void)
+{
+ if (uc)
+ delete uc;
+}
+
+class cl_uc *
+cl_sim::mk_controller(void)
+{
+ return(new cl_uc(this));
+}
+
+
+int
+cl_sim::step(void)
+{
+ if (state & SIM_GO)
+ {
+ if (steps_done == 0)
+ {
+ start_at= dnow();
+ }
+ if (uc->do_inst(1) == resGO)
+ steps_done++;
+ if ((steps_todo > 0) &&
+ (steps_done >= steps_todo))
+ stop(resSTEP);
+ }
+ return(0);
+}
+
+/*int
+cl_sim::do_cmd(char *cmdstr, class cl_console *console)
+{
+ class cl_cmdline *cmdline;
+ class cl_cmd *cm;
+ int retval= 0;
+
+ cmdline= new cl_cmdline(cmdstr, console);
+ cmdline->init();
+ cm= cmd->cmdset->get_cmd(cmdline);
+ if (cm)
+ retval= cm->work(cmdline, console);
+ delete cmdline;
+ if (cm)
+ return(retval);
+ return(console->interpret(cmdstr));
+}*/
+
+void
+cl_sim::start(class cl_console_base *con, unsigned long steps_to_do)
+{
+ state|= SIM_GO;
+ if (con)
+ {
+ con->set_flag(CONS_FROZEN, true);
+ app->get_commander()->frozen_console= con;
+ app->get_commander()->update_active();
+ }
+ if (uc)
+ start_tick= uc->ticks->ticks;
+ steps_done= 0;
+ steps_todo= steps_to_do;
+}
+
+void
+cl_sim::stop(int reason, class cl_ev_brk *ebrk)
+{
+ class cl_commander_base *cmd= app->get_commander();
+ class cl_option *o= app->options->get_option("quit");
+ bool q_opt= false;
+
+ if (o)
+ o->get_value(&q_opt);
+
+ state&= ~SIM_GO;
+ stop_at= dnow();
+ if (simif)
+ simif->cfg_set(simif_reason, reason);
+
+ class cl_brk *b= NULL;
+ if (reason == resBREAKPOINT)
+ {
+ b= uc->fbrk_at(uc->PC);
+ }
+ else if (ebrk != NULL)
+ {
+ b= ebrk;
+ }
+ if (b)
+ {
+ if (!(b->commands.empty()))
+ {
+ class cl_option *o= app->options->get_option("echo_script");
+ bool e= false;
+ if (o) o->get_value(&e);
+ if (e)
+ cmd->dd_printf("%s\n", (char*)(b->commands));
+ application->exec(b->commands);
+ steps_done= 0;
+ }
+ }
+
+ if (!(state & SIM_GO) &&
+ cmd->frozen_console)
+ {
+ if (reason == resUSER &&
+ cmd->frozen_console->input_avail())
+ cmd->frozen_console->read_line();
+ cmd->frozen_console->un_redirect();
+ cmd->frozen_console->dd_color("debug");
+ cmd->frozen_console->dd_printf("Stop at 0x%06x: (%d) ", AU(uc->PC), reason);
+ switch (reason)
+ {
+ case resHALT:
+ cmd->frozen_console->dd_printf("Halted\n");
+ break;
+ case resINV_ADDR:
+ cmd->frozen_console->dd_printf("Invalid address\n");
+ break;
+ case resSTACK_OV:
+ cmd->frozen_console->dd_printf("Stack overflow\n");
+ break;
+ case resBREAKPOINT:
+ cmd->frozen_console->dd_printf("Breakpoint\n");
+ if (cmd->frozen_console)
+ uc->print_regs(cmd->frozen_console);
+ break;
+ case resEVENTBREAK:
+ cmd->frozen_console->dd_printf("Event break\n");
+ //uc->print_regs(cmd->frozen_console);
+ if (b)
+ {
+ class cl_ev_brk *eb= (cl_ev_brk*)b;
+ class cl_address_space *m= eb->get_mem();
+ cmd->frozen_console->dd_printf("Event `%s' at %s[0x%x]: 0x%x %s\n",
+ eb->id, m?(m->get_name()):"mem?",
+ AU(eb->addr),
+ AU(uc->instPC),
+ uc->disass(uc->instPC, " "));
+ }
+ break;
+ case resINTERRUPT:
+ cmd->frozen_console->dd_printf("Interrupt\n");
+ break;
+ case resWDTRESET:
+ cmd->frozen_console->dd_printf("Watchdog reset\n");
+ break;
+ case resUSER:
+ cmd->frozen_console->dd_printf("User stopped\n");
+ break;
+ case resINV_INST:
+ {
+ cmd->frozen_console->dd_printf("Invalid instruction");
+ if (uc->rom)
+ cmd->frozen_console->dd_printf(" 0x%04x\n",
+ MU32(uc->rom->get(uc->PC)));
+ }
+ break;
+ case resSTEP:
+ cmd->frozen_console->dd_printf("\n");
+ uc->print_regs(cmd->frozen_console);
+ break;
+ case resERROR:
+ // uc::check_error prints error messages...
+ break;
+ case resSIMIF:
+ cmd->frozen_console->dd_printf("Program stopped itself\n");
+ break;
+ default:
+ cmd->frozen_console->dd_printf("Unknown reason\n");
+ break;
+ }
+ cmd->frozen_console->dd_printf("F 0x%06x\n", AU(uc->PC)); // for sdcdb
+ unsigned long dt= uc?(uc->ticks->ticks - start_tick):0;
+ if ((reason != resSTEP) ||
+ (steps_done > 1))
+ cmd->frozen_console->dd_printf("Simulated %lu ticks in %f sec, rate=%f\n",
+ dt,
+ stop_at - start_at,
+ (dt*(1/uc->xtal)) / (stop_at - start_at));
+ //if (cmd->actual_console != cmd->frozen_console)
+ cmd->frozen_console->set_flag(CONS_FROZEN, false);
+ //cmd->frozen_console->dd_printf("_s_");
+ cmd->frozen_console->print_prompt();
+ cmd->frozen_console= 0;
+ }
+ if (!(state & SIM_GO) &&
+ q_opt)
+ state|= SIM_QUIT;
+ cmd->update_active();
+}
+/*
+void
+cl_sim::stop(class cl_ev_brk *brk)
+{
+ class cl_commander_base *cmd= app->get_commander();
+ class cl_option *o= app->options->get_option("quit");
+ bool q_opt= false;
+
+ if (o)
+ o->get_value(&q_opt);
+
+ //state&= ~SIM_GO;
+ if (simif)
+ simif->cfg_set(simif_reason, resEVENTBREAK);
+
+ if (brk)
+ {
+ if (!(brk->commands.empty()))
+ {
+ application->exec(brk->commands);
+ steps_done= 0;
+ printf("event brk PC=%ld, simgo=%d\n",uc->PC,state&SIM_GO);
+ }
+ }
+
+ if (!(state & SIM_GO) &&
+ cmd->frozen_console)
+ {
+ class cl_console_base *con= cmd->frozen_console;
+ con->dd_printf("Event `%s' at %s[0x%x]: 0x%x %s\n",
+ brk->id, brk->get_mem()->get_name(), (int)brk->addr,
+ (int)uc->instPC,
+ uc->disass(uc->instPC, " "));
+ }
+ if (!(state & SIM_GO) &&
+ q_opt)
+ state|= SIM_QUIT;
+}
+*/
+
+void
+cl_sim::change_run(int reason)
+{
+ if (state & SIM_GO)
+ stop(reason);
+ else
+ start(0, 0);
+}
+
+/*
+ */
+
+void
+cl_sim::build_cmdset(class cl_cmdset *cmdset)
+{
+ class cl_cmd *cmd;
+ //class cl_cmdset *cset;
+
+ cmdset->add(cmd= new cl_run_cmd("run", 0));
+ cmd->init();
+ cmd->add_name("go");
+ cmd->add_name("r");
+ cmd->add_name("continue");
+
+ cmdset->add(cmd= new cl_stop_cmd("stop", 0));
+ cmd->init();
+
+ cmdset->add(cmd= new cl_step_cmd("step", true));
+ cmd->init();
+ cmd->add_name("s");
+
+ cmdset->add(cmd= new cl_next_cmd("next", true));
+ cmd->init();
+ cmd->add_name("n");
+
+ /*{
+ cset= new cl_cmdset();
+ cset->init();
+ cset->add(cmd= new cl_gui_start_cmd("start", 0));
+ cmd->init();
+ cset->add(cmd= new cl_gui_stop_cmd("stop", 0));
+ cmd->init();
+ }
+ cmdset->add(cmd= new cl_super_cmd("gui", 0, cset));
+ cmd->init();
+ set_gui_help();
+ */
+}
+
+
+/*
+ * Messages to broadcast
+ */
+/*
+void
+cl_sim::mem_cell_changed(class cl_address_space *mem, t_addr addr)
+{
+ if (uc)
+ uc->mem_cell_changed(mem, addr);
+ else
+ printf("JAJ sim\n");
+}
+*/
+
+/* End of sim.src/sim.cc */