Imported Upstream version 2.9.0
[debian/cc1111] / sim / ucsim / sim.src / sim.cc
1 /*
2  * Simulator of microcontrollers (sim.cc)
3  *
4  * Copyright (C) 1999,99 Drotos Daniel, Talker Bt.
5  *
6  * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
7  *
8  */
9
10 /* This file is part of microcontroller simulator: ucsim.
11
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.
16
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.
21
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
25 02111-1307, USA. */
26 /*@1@*/
27
28 #include "ddconfig.h"
29
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <unistd.h>
33 #include "i_string.h"
34
35 // prj
36 #include "globals.h"
37
38 // cmd
39 #include "cmdsetcl.h"
40 #include "cmdguicl.h"
41
42 // local, sim.src
43 #include "simcl.h"
44 #include "appcl.h"
45
46
47 /*
48  * Simulator
49  */
50
51 cl_sim::cl_sim(class cl_app *the_app):
52   cl_base()
53 {
54   app= the_app;
55   uc= 0;
56   //arguments= new cl_list(2, 2);
57   //accept_args= more_args?strdup(more_args):0;
58   gui= new cl_gui(this);
59
60   state = SIM_QUIT;
61   argc = 0;
62   argv = 0;
63 }
64
65 int
66 cl_sim::init(void)
67 {
68   cl_base::init();
69   build_cmdset(app->get_commander()->cmdset);
70   if (!(uc= mk_controller()))
71     return(1);
72   uc->init();
73   return(0);
74 }
75
76 cl_sim::~cl_sim(void)
77 {
78   if (uc)
79     delete uc;
80 }
81
82 class cl_uc *
83 cl_sim::mk_controller(void)
84 {
85   return(new cl_uc(this));
86 }
87
88
89 /*
90  * Main cycle of the simulator
91  */
92
93 int
94 cl_sim::main(void)
95 {
96   int done= 0;
97
98   while (!done &&
99          (state & SIM_QUIT) == 0)
100     {
101       if (state & SIM_GO)
102         {
103           uc->do_inst(-1);
104           if (app->get_commander()->input_avail())
105             {
106               done= app->get_commander()->proc_input();
107             }
108         }
109       else
110         {
111           app->get_commander()->wait_input();
112           done= app->get_commander()->proc_input();
113         }
114     }
115   return(0);
116 }
117
118 int
119 cl_sim::step(void)
120 {
121   if (state & SIM_GO)
122     uc->do_inst(1);
123   return(0);
124 }
125
126 /*int
127 cl_sim::do_cmd(char *cmdstr, class cl_console_base *console)
128 {
129   class cl_cmdline *cmdline;
130   class cl_cmd *cm;
131   int retval= 0;
132
133   cmdline= new cl_cmdline(cmdstr, console);
134   cmdline->init();
135   cm= cmd->cmdset->get_cmd(cmdline);
136   if (cm)
137     retval= cm->work(cmdline, console);
138   delete cmdline;
139   if (cm)
140     return(retval);
141   return(console->interpret(cmdstr));
142 }*/
143
144 void
145 cl_sim::start(class cl_console_base *con)
146 {
147   state|= SIM_GO;
148   con->flags|= CONS_FROZEN;
149   app->get_commander()->frozen_console= con;
150   app->get_commander()->set_fd_set();
151 }
152
153 void
154 cl_sim::stop(int reason)
155 {
156   class cl_commander_base *cmd= app->get_commander();
157
158   state&= ~SIM_GO;
159   if (cmd->frozen_console)
160     {
161       if (reason == resUSER &&
162           cmd->frozen_console->input_avail())
163         cmd->frozen_console->read_line();
164       cmd->frozen_console->dd_printf("Stop at 0x%06x: (%d) ", uc->PC, reason);
165       switch (reason)
166         {
167         case resHALT:
168           cmd->frozen_console->dd_printf("Halted\n");
169           break;
170         case resINV_ADDR:
171           cmd->frozen_console->dd_printf("Invalid address\n");
172           break;
173         case resSTACK_OV:
174           cmd->frozen_console->dd_printf("Stack overflow\n");
175           break;
176         case resBREAKPOINT:
177           cmd->frozen_console->dd_printf("Breakpoint\n");
178           uc->print_regs(cmd->frozen_console);
179           break;
180         case resINTERRUPT:
181           cmd->frozen_console->dd_printf("Interrupt\n");
182           break;
183         case resWDTRESET:
184           cmd->frozen_console->dd_printf("Watchdog reset\n");
185           break;
186         case resUSER:
187           cmd->frozen_console->dd_printf("User stopped\n");
188           break;
189         case resINV_INST:
190           {
191             cmd->frozen_console->dd_printf("Invalid instruction");
192             if (uc->rom)
193               cmd->frozen_console->dd_printf(" 0x%04x\n",
194                                              uc->rom->get(uc->PC));
195           }
196          break;
197         case resERROR:
198           // uc::check_error prints error messages...
199           break;
200         default:
201           cmd->frozen_console->dd_printf("Unknown reason\n");
202           break;
203         }
204       cmd->frozen_console->dd_printf("F 0x%06x\n", uc->PC); // for sdcdb
205       //if (cmd->actual_console != cmd->frozen_console)
206       cmd->frozen_console->flags&= ~CONS_FROZEN;
207       cmd->frozen_console->print_prompt();
208       cmd->frozen_console= 0;
209     }
210   cmd->set_fd_set();
211 }
212
213 void
214 cl_sim::stop(class cl_ev_brk *brk)
215 {
216   class cl_commander_base *cmd= app->get_commander();
217
218   state&= ~SIM_GO;
219   if (cmd->frozen_console)
220     {
221       class cl_console_base *con= cmd->frozen_console;
222       /*
223       if (reason == resUSER &&
224           cmd->frozen_console->input_avail())
225         cmd->frozen_console->read_line();
226       */
227       //con->dd_printf("Stop at 0x%06x\n", uc->PC);
228       con->dd_printf("Event `%s' at %s[0x%"_A_"x]: 0x%"_A_"x %s\n",
229                      brk->id, brk->get_mem()->get_name(), brk->addr,
230                      uc->instPC,
231                      uc->disass(uc->instPC, " "));
232       //con->flags&= ~CONS_FROZEN;
233       //con->print_prompt();
234       //cmd->frozen_console= 0;
235     }
236 }
237
238
239 /*
240  */
241
242 void
243 cl_sim::build_cmdset(class cl_cmdset *cmdset)
244 {
245   class cl_cmd *cmd;
246   class cl_cmdset *cset;
247
248   cmdset->add(cmd= new cl_run_cmd("run", 0,
249 "run [start [stop]] Go",
250 "long help of run"));
251   cmd->init();
252   cmd->add_name("go");
253   cmd->add_name("r");
254
255   cmdset->add(cmd= new cl_stop_cmd("stop", 0,
256 "stop               Stop",
257 "long help of stop"));
258   cmd->init();
259
260   cmdset->add(cmd= new cl_step_cmd("step", DD_TRUE,
261 "step               Step",
262 "long help of step"));
263   cmd->init();
264   cmd->add_name("s");
265
266   cmdset->add(cmd= new cl_next_cmd("next", DD_TRUE,
267 "next               Next",
268 "long help of next"));
269   cmd->init();
270   cmd->add_name("n");
271
272   {
273     cset= new cl_cmdset();
274     cset->init();
275     cset->add(cmd= new cl_gui_start_cmd("start", 0,
276 "gui start          Start interfacing with GUI tool",
277 "long help of gui start"));
278     cmd->init();
279     cset->add(cmd= new cl_gui_stop_cmd("stop", 0,
280 "gui stop           Stop interfacing with GUI tool",
281 "long help of gui stop"));
282     cmd->init();
283   }
284   cmdset->add(cmd= new cl_super_cmd("gui", 0,
285 "gui subcommand     Operations to support GUI tools",
286 "long help of gui", cset));
287   cmd->init();
288 }
289
290
291 /*
292  * Messages to broadcast
293  */
294 /*
295 void
296 cl_sim::mem_cell_changed(class cl_address_space *mem, t_addr addr)
297 {
298   if (uc)
299     uc->mem_cell_changed(mem, addr);
300   else
301     printf("JAJ sim\n");
302 }
303 */
304
305 /* End of sim.src/sim.cc */