version 0.5.2
[fw/sdcc] / 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
61 int
62 cl_sim::init(void)
63 {
64   cl_base::init();
65   build_cmdset(app->get_commander()->cmdset);
66   if (!(uc= mk_controller()))
67     return(1);
68   uc->init();
69   return(0);
70 }
71
72 cl_sim::~cl_sim(void)
73 {
74   if (uc)
75     delete uc;
76 }
77
78 class cl_uc *
79 cl_sim::mk_controller(void)
80 {
81   return(new cl_uc(this));
82 }
83
84
85 /*
86  * Main cycle of the simulator
87  */
88
89 int
90 cl_sim::main(void)
91 {
92   int done= 0;
93
94   while (!done &&
95          (state & SIM_QUIT) == 0)
96     {
97       if (state & SIM_GO)
98         {
99           uc->do_inst(-1);
100           if (app->get_commander()->input_avail())
101             {
102               done= app->get_commander()->proc_input();
103             }
104         }
105       else
106         {
107           app->get_commander()->wait_input();
108           done= app->get_commander()->proc_input();
109         }
110     }
111   return(0);
112 }
113
114 int
115 cl_sim::step(void)
116 {
117   if (state & SIM_GO)
118     uc->do_inst(1);
119   return(0);
120 }
121
122 /*int
123 cl_sim::do_cmd(char *cmdstr, class cl_console *console)
124 {
125   class cl_cmdline *cmdline;
126   class cl_cmd *cm;
127   int retval= 0;
128
129   cmdline= new cl_cmdline(cmdstr, console);
130   cmdline->init();
131   cm= cmd->cmdset->get_cmd(cmdline);
132   if (cm)
133     retval= cm->work(cmdline, console);
134   delete cmdline;
135   if (cm)
136     return(retval);
137   return(console->interpret(cmdstr));
138 }*/
139
140 void
141 cl_sim::start(class cl_console *con)
142 {
143   state|= SIM_GO;
144   con->flags|= CONS_FROZEN;
145   app->get_commander()->frozen_console= con;
146   app->get_commander()->set_fd_set();
147 }
148
149 void
150 cl_sim::stop(int reason)
151 {
152   class cl_commander *cmd= app->get_commander();
153
154   state&= ~SIM_GO;
155   if (cmd->frozen_console)
156     {
157       if (reason == resUSER &&
158           cmd->frozen_console->input_avail())
159         cmd->frozen_console->read_line();
160       cmd->frozen_console->dd_printf("Stop at 0x%06x: (%d) ", uc->PC, reason);
161       switch (reason)
162         {
163         case resHALT:
164           cmd->frozen_console->dd_printf("Halted\n");
165           break;
166         case resINV_ADDR:
167           cmd->frozen_console->dd_printf("Invalid address\n");
168           break;
169         case resSTACK_OV:
170           cmd->frozen_console->dd_printf("Stack overflow\n");
171           break;
172         case resBREAKPOINT:
173           cmd->frozen_console->dd_printf("Breakpoint\n");
174           uc->print_regs(cmd->frozen_console);
175           break;
176         case resINTERRUPT:
177           cmd->frozen_console->dd_printf("Interrupt\n");
178           break;
179         case resWDTRESET:
180           cmd->frozen_console->dd_printf("Watchdog reset\n");
181           break;
182         case resUSER:
183           cmd->frozen_console->dd_printf("User stopped\n");
184           break;
185         case resINV_INST:
186           {
187             cmd->frozen_console->dd_printf("Invalid instruction");
188             if (uc->rom)
189               cmd->frozen_console->dd_printf(" 0x%04x\n",
190                                              uc->rom->get(uc->PC));
191           }
192          break;
193         case resERROR:
194           // uc::check_error prints error messages...
195           break;
196         default:
197           cmd->frozen_console->dd_printf("Unknown reason\n");
198           break;
199         }
200       cmd->frozen_console->dd_printf("F 0x%06x\n", uc->PC); // for sdcdb
201       //if (cmd->actual_console != cmd->frozen_console)
202       cmd->frozen_console->flags&= ~CONS_FROZEN;
203       cmd->frozen_console->print_prompt();
204       cmd->frozen_console= 0;
205     }
206   cmd->set_fd_set();
207 }
208
209 void
210 cl_sim::stop(class cl_ev_brk *brk)
211 {
212   class cl_commander *cmd= app->get_commander();
213
214   state&= ~SIM_GO;
215   if (cmd->frozen_console)
216     {
217       class cl_console *con= cmd->frozen_console;
218       /*
219       if (reason == resUSER &&
220           cmd->frozen_console->input_avail())
221         cmd->frozen_console->read_line();
222       */
223       //con->dd_printf("Stop at 0x%06x\n", uc->PC);
224       con->dd_printf("Event `%s' at %s[0x%"_A_"x]: 0x%"_A_"x %s\n",
225                      brk->id, brk->get_mem()->get_name(), brk->addr,
226                      uc->instPC,
227                      uc->disass(uc->instPC, " "));
228       //con->flags&= ~CONS_FROZEN;
229       //con->print_prompt();
230       //cmd->frozen_console= 0;
231     }
232 }
233
234
235 /*
236  */
237
238 void
239 cl_sim::build_cmdset(class cl_cmdset *cmdset)
240 {
241   class cl_cmd *cmd;
242   class cl_cmdset *cset;
243
244   cmdset->add(cmd= new cl_run_cmd("run", 0,
245 "run [start [stop]] Go",
246 "long help of run"));
247   cmd->init();
248   cmd->add_name("go");
249   cmd->add_name("r");
250
251   cmdset->add(cmd= new cl_stop_cmd("stop", 0,
252 "stop               Stop",
253 "long help of stop"));
254   cmd->init();
255
256   cmdset->add(cmd= new cl_step_cmd("step", DD_TRUE,
257 "step               Step",
258 "long help of step"));
259   cmd->init();
260   cmd->add_name("s");
261
262   cmdset->add(cmd= new cl_next_cmd("next", DD_TRUE,
263 "next               Next",
264 "long help of next"));
265   cmd->init();
266   cmd->add_name("n");
267
268   {
269     cset= new cl_cmdset();
270     cset->init();
271     cset->add(cmd= new cl_gui_start_cmd("start", 0, 
272 "gui start          Start interfacing with GUI tool",
273 "long help of gui start"));
274     cmd->init();
275     cset->add(cmd= new cl_gui_stop_cmd("stop", 0, 
276 "gui stop           Stop interfacing with GUI tool",
277 "long help of gui stop"));
278     cmd->init();
279   }
280   cmdset->add(cmd= new cl_super_cmd("gui", 0,
281 "gui subcommand     Operations to support GUI tools",
282 "long help of gui", cset));
283   cmd->init();
284 }
285
286
287 /*
288  * Messages to broadcast
289  */
290 /*
291 void
292 cl_sim::mem_cell_changed(class cl_address_space *mem, t_addr addr)
293 {
294   if (uc)
295     uc->mem_cell_changed(mem, addr);
296   else
297     printf("JAJ sim\n");
298 }
299 */
300
301 /* End of sim.src/sim.cc */