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