1 /*
2 Copyright (C) 1998 T. Scott Dattalo
3
4 This file is part of the libgpsim library of gpsim
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with this library; if not, see
18 <http://www.gnu.org/licenses/lgpl-2.1.html>.
19 */
20
21 #ifndef SRC_GPSIM_INTERFACE_H_
22 #define SRC_GPSIM_INTERFACE_H_
23
24 #include "gpsim_classes.h"
25 #include "interface.h"
26 #include "trigger.h"
27
28 #include <list>
29 #include <string>
30
31 #include <glib.h>
32
33 class Stimulus;
34 class Stimulus_Node;
35 class ISimConsole;
36 class Processor;
37 class Module;
38
39 //---------------------------------------------------------------------------
40 //
41 // struct Interface
42 //
43 // Here's a structure containing all of the information for gpsim
44 // and an external interface like the GUI to communicate. There are
45 // two major functions. First, a GUI can provide pointers to callback
46 // functions that the simulator can invoke upon certain conditions.
47 // For example, if the contents of a register change, the simulator
48 // can notify the GUI and thus save the gui having to continuously
49 // poll. (This may occur when the command line interface changes
50 // something; such changes need to be propogated up to the gui.)
51 //
52 // FIXME -- shouldn't this be a pure virtual class?
53
54 class Interface
55 {
56 public:
57
58 unsigned int interface_id;
59 gpointer objectPTR;
60
61 /*
62 * UpdateObject - Invoked when an object changes
63 *
64 * If an object, like the contents of a register, changes then this function
65 * will be called. There are two parameters:
66 * xref - this is a pointer to some structure in the client's data space.
67 * new_value - this is the new value to which the object has changed.
68 *
69 */
70
UpdateObject(gpointer,int)71 virtual void UpdateObject(gpointer /* xref */, int /* new_value */) {}
72
73 /*
74 * remove_object - Invoked when gpsim has removed something.
75 *
76 * If an object, like a register, is deleted then this function
77 * will be called. There is one parameter:
78 * xref - this is a pointer to some structure in the client's data space.
79 *
80 */
81
RemoveObject(gpointer)82 virtual void RemoveObject(gpointer /* xref */) {}
83
84
85 /*
86 * simulation_has_stopped - invoked when gpsim has stopped simulating (e.g.
87 * when a breakpoint is encountered).
88 *
89 * Some interfaces have more than one instance, so the 'object' parameter
90 * allows the interface to uniquely identify the particular one.
91 */
92
SimulationHasStopped(gpointer)93 virtual void SimulationHasStopped(gpointer /* object */) {}
94
95
96 /*
97 * new_processor - Invoked when a new processor is added to gpsim
98 */
99
NewProcessor(Processor *)100 virtual void NewProcessor(Processor *) {}
101
102
103 /*
104 * new_module - Invoked when a new module is instantiated.
105 *
106 */
107
NewModule(Module *)108 virtual void NewModule(Module *) {}
109
110 /*
111 * node_configuration_changed - invoked when stimulus configuration has changed
112 */
113
NodeConfigurationChanged(Stimulus_Node *)114 virtual void NodeConfigurationChanged(Stimulus_Node *) {}
115
116
117 /*
118 * new_program - Invoked when a new program is loaded into gpsim
119 *
120 */
121
NewProgram(Processor *)122 virtual void NewProgram(Processor *) {}
123
124 /*
125 * Update - Invoked when the interface should update itself
126 */
127
Update(gpointer)128 virtual void Update(gpointer /* object */) {}
129
130 /*
131 * destructor - called when the interface is destroyed - this gives
132 * the interface object a chance to save state information.
133 */
~Interface()134 virtual ~Interface()
135 {
136 }
137
get_id()138 unsigned int get_id() { return interface_id;}
set_id(unsigned int new_id)139 void set_id(unsigned int new_id) { interface_id = new_id;}
140 explicit Interface(gpointer new_object = nullptr);
141 };
142
143
144 class gpsimInterface : public TriggerObject
145 {
146 public:
147
148 gpsimInterface();
149
150 /*
151 * start_simulation -begin simulating. Simulation stops whenever
152 * a breakpoint is encountered or the specified duration has expired.
153 */
154 void start_simulation(double duration = 0.0);
155
156 /*
157 * step_simulation - run the simulation for one or more simulation cycles.
158 */
159 void step_simulation(int nSteps);
160
161 /*
162 * advance_simulation - run simulation until advancement condition is met.
163 */
164 enum eAdvancementModes {
165 eAdvanceNextInstruction, // processors - step over call instructions
166 eAdvanceNextCycle, // system -
167 eAdvanceNextCall, // processors - run until call instruction
168 eAdvanceNextReturn, // processors - run until next return
169 };
170 void advance_simulation(eAdvancementModes nAdvancement);
171 void reset(RESET_TYPE resetType = SIM_RESET);
172 void simulation_has_stopped();
173 bool bSimulating();
174 bool bUsingGUI();
175 void setGUImode(bool);
176 // gpsim will call these functions to notify gui and/or modules
177 // that something has changed.
178
179 void update_object(gpointer xref, int new_value);
180 void remove_object(gpointer xref);
181 void update();
182 void new_processor(Processor *);
183 void new_module(Module *module);
184 void node_configuration_changed(Stimulus_Node *node);
185 void new_program(Processor *);
186 void set_update_rate(guint64 rate);
187 guint64 get_update_rate();
188
189 unsigned int add_interface(Interface *new_interface);
190 unsigned int prepend_interface(Interface *new_interface);
191 unsigned int add_socket_interface(Interface *new_interface);
get_socket_interface()192 Interface *get_socket_interface() { return socket_interface;}
193 void remove_interface(unsigned int interface_id);
194
195
set_break()196 virtual bool set_break() {return false;}
197 virtual void callback();
198 virtual void callback_print();
199 virtual void print();
200 virtual void clear();
bpName()201 virtual char const * bpName() { return "gpsim interface"; }
202 virtual ISimConsole &GetConsole();
203
204 private:
205 GSList *interfaces;
206 Interface *socket_interface;
207
208 unsigned int interface_seq_number;
209
210 guint64 update_rate;
211 guint64 future_cycle;
212
213 bool mbSimulating; // Set true if the simulation is running.
214 bool mbUseGUI; // Set true if gui is being used.
215 };
216
217 #if defined(IN_MODULE) && defined(_WIN32)
218 // we are in a module: don't access gi object directly!
219 LIBGPSIM_EXPORT gpsimInterface & get_interface();
220 #else
221 // we are in gpsim: use of get_interface() is recommended,
222 // even if gi object can be accessed directly.
223 extern gpsimInterface gi;
224
get_interface()225 inline gpsimInterface &get_interface()
226 {
227 return gi;
228 }
229 #endif
230
231 //------------------------------------------------------------------------
232
233 class ModuleInterface
234 {
235 public:
236 Module *module; // The module we're interfacing with.
237
238 explicit ModuleInterface(Module *new_module);
239 };
240
241 //------------------------------------------------------------------------
242
243 class Processor;
244
245 class ProcessorInterface : public ModuleInterface
246 {
247 public:
248 explicit ProcessorInterface(Processor *cpu);
249 };
250
251 class ISimConsole;
252
253 #define CMD_ERR_OK 0
254 #define CMD_ERR_ABORTED 1
255 #define CMD_ERR_ERROR 2
256 #define CMD_ERR_PROCESSORDEFINED 3
257 #define CMD_ERR_PROCESSORNOTDEFINED 4
258 #define CMD_ERR_COMMANDNOTDEFINED 5
259 #define CMD_ERR_NOTIMPLEMENTED 6
260
261 #define GPSIM_GETCOMMANDHANDLER "GetCommandHandler"
262
263 class ICommandHandler {
264 public:
~ICommandHandler()265 virtual ~ICommandHandler()
266 {
267 }
268
269 virtual const char *GetName() = 0;
270 // Fixme: should Execute be renamed ExecuteCommand?
271 virtual int Execute(const char * commandline, ISimConsole *out) = 0;
272 virtual int ExecuteScript(std::list<std::string *> &script, ISimConsole *out) = 0;
273 };
274
275 #endif // SRC_GPSIM_INTERFACE_H_
276