1 |
2 |
alfik |
/////////////////////////////////////////////////////////////////////////
|
2 |
|
|
// $Id: siminterface.h 11612 2013-02-04 18:51:07Z vruppert $
|
3 |
|
|
/////////////////////////////////////////////////////////////////////////
|
4 |
|
|
//
|
5 |
|
|
// Copyright (C) 2001-2013 The Bochs Project
|
6 |
|
|
//
|
7 |
|
|
// This library is free software; you can redistribute it and/or
|
8 |
|
|
// modify it under the terms of the GNU Lesser General Public
|
9 |
|
|
// License as published by the Free Software Foundation; either
|
10 |
|
|
// version 2 of the License, or (at your option) any later version.
|
11 |
|
|
//
|
12 |
|
|
// This library is distributed in the hope that it will be useful,
|
13 |
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14 |
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
15 |
|
|
// Lesser General Public License for more details.
|
16 |
|
|
//
|
17 |
|
|
// You should have received a copy of the GNU Lesser General Public
|
18 |
|
|
// License along with this library; if not, write to the Free Software
|
19 |
|
|
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
20 |
|
|
//
|
21 |
|
|
/////////////////////////////////////////////////////////////////////////
|
22 |
|
|
//
|
23 |
|
|
// Intro to siminterface by Bryce Denney:
|
24 |
|
|
//
|
25 |
|
|
// Before I can describe what this file is for, I have to make the
|
26 |
|
|
// distinction between a configuration interface (CI) and the VGA display
|
27 |
|
|
// window (VGAW). I will try to avoid the term 'GUI' because it is unclear
|
28 |
|
|
// if that means CI or VGAW, and because not all interfaces are graphical
|
29 |
|
|
// anyway.
|
30 |
|
|
//
|
31 |
|
|
// The traditional Bochs screen is a window with a large VGA display panel and
|
32 |
|
|
// a series of buttons (floppy, cdrom, snapshot, power). Over the years, we
|
33 |
|
|
// have collected many implementations of the VGAW for different environments
|
34 |
|
|
// and platforms; each implementation is in a separate file under gui/*:
|
35 |
|
|
// x.cc, win32.cc, macintosh.cc, etc. The files gui.h and gui.cc
|
36 |
|
|
// define the platform independent part of the VGAW, leaving about 15 methods
|
37 |
|
|
// of the bx_gui_c class undefined. The platform dependent file must
|
38 |
|
|
// implement the remaining 15 methods.
|
39 |
|
|
//
|
40 |
|
|
// The configuration interface is relatively new, started by Bryce Denney in
|
41 |
|
|
// June 2001. The CI is intended to allow the user to edit a variety of
|
42 |
|
|
// configuration and runtime options. Some options, such as memory size or
|
43 |
|
|
// enabling the ethernet card, should only be changed before the simulation
|
44 |
|
|
// begins; others, such as floppy disk image, instructions per second, and
|
45 |
|
|
// logging options can be safely changed at runtime. The CI allows the user to
|
46 |
|
|
// make these changes. Before the CI existed, only a few things could be
|
47 |
|
|
// changed at runtime, all linked to clicking on the VGAW buttons.
|
48 |
|
|
//
|
49 |
|
|
// At the time that the CI was conceived, we were still debating what form the
|
50 |
|
|
// user interface part would take: stdin/stdout menus, a graphical application
|
51 |
|
|
// with menus and dialogs running in a separate thread, or even a tiny web
|
52 |
|
|
// server that you can connect to with a web browser. As a result the
|
53 |
|
|
// interface to the CI was designed so that the user interface of the CI
|
54 |
|
|
// could be replaced easily at compile time, or maybe even at runtime via
|
55 |
|
|
// a plugin architecture. To this end, we kept a clear separation between
|
56 |
|
|
// the user interface code and the siminterface, the code that interfaces with
|
57 |
|
|
// the simulator. The same siminterface is used all the time, while
|
58 |
|
|
// different implementations of the CI can be switched in reasonably easily.
|
59 |
|
|
// Only the CI code uses library specific graphics and I/O functions; the
|
60 |
|
|
// siminterface deals in portable abstractions and callback functions.
|
61 |
|
|
// The first CI implementation was a series of text mode menus implemented in
|
62 |
|
|
// textconfig.cc.
|
63 |
|
|
//
|
64 |
|
|
// The configuration interface MUST use the siminterface methods to access the
|
65 |
|
|
// simulator. It should not modify settings in some device with code like
|
66 |
|
|
// bx_floppy.s.media[2].heads = 17. If such access is needed, then a
|
67 |
|
|
// siminterface method should be written to make the change on the CI's behalf.
|
68 |
|
|
// This separation is enforced by the fact that the CI does not even include
|
69 |
|
|
// bochs.h. You'll notice that textconfig.cc includes osdep.h, textconfig.h,
|
70 |
|
|
// and siminterface.h, so it doesn't know what bx_floppy or bx_cpu_c are.
|
71 |
|
|
// I'm sure some people will say is overly restrictive and/or annoying. When I
|
72 |
|
|
// set it up this way, we were still talking about making the CI in a seperate
|
73 |
|
|
// process, where direct method calls would be impossible. Also, we have been
|
74 |
|
|
// considering turning devices into plugin modules which are dynamically
|
75 |
|
|
// linked. Any direct references to something like bx_floppy.s.media[2].heads
|
76 |
|
|
// would have to be reworked before a plugin interface was possible as well.
|
77 |
|
|
//
|
78 |
|
|
// The siminterface is the glue between the CI and the simulator. There is
|
79 |
|
|
// just one global instance of the siminterface object, which can be referred
|
80 |
|
|
// to by the global variable bx_simulator_interface_c *SIM. The base class
|
81 |
|
|
// bx_simulator_interface_c, contains only virtual functions and it defines the
|
82 |
|
|
// interface that the CI is allowed to use. In siminterface.cc, a class
|
83 |
|
|
// called bx_real_sim_c is defined with bx_simulator_interface_c as its parent
|
84 |
|
|
// class. Bx_real_sim_c implements each of the functions. The separation into
|
85 |
|
|
// parent class and child class leaves the possibility of making a different
|
86 |
|
|
// child class that talks to the simulator in a different way (networking for
|
87 |
|
|
// example). If you were writing a user interface in a separate process, you
|
88 |
|
|
// could define a subclass of bx_simulator_interface_c called
|
89 |
|
|
// bx_siminterface_proxy_c which opens up a network port and turns all method
|
90 |
|
|
// calls into network sends and receives. Because the interface is defined
|
91 |
|
|
// entirely by the base class, the code that calls the methods would not know
|
92 |
|
|
// the difference.
|
93 |
|
|
//
|
94 |
|
|
// An important part of the siminterface implementation is the use of parameter
|
95 |
|
|
// classes, or bx_param_*. The parameter classes are described below, where
|
96 |
|
|
// they are declared. Search for "parameter classes" below for details.
|
97 |
|
|
//
|
98 |
|
|
// Also this header file declares data structures for certain events that pass
|
99 |
|
|
// between the siminterface and the CI. Search for "event structures" below.
|
100 |
|
|
|
101 |
|
|
|
102 |
|
|
//////////////////////////////////////////////////////
|
103 |
|
|
// BX_USE_TEXTCONFIG should be set to 1 when the text mode configuration interface
|
104 |
|
|
// is compiled in. This gives each type of parameter a text_print and text_ask
|
105 |
|
|
// method (defined in gui/textconfig.cc) so that you can call text_ask() on any
|
106 |
|
|
// kind of parameter to ask the user to edit the value.
|
107 |
|
|
//
|
108 |
|
|
// I have been considering whether to use the same strategy for the
|
109 |
|
|
// wxWidgets interface, but I'm not sure if I like it. One problem is
|
110 |
|
|
// that in order to declare member functions that are useful for
|
111 |
|
|
// wxWidgets, the wxWidgets header files would have to be included
|
112 |
|
|
// before the param object definitions. That means that all the
|
113 |
|
|
// wxWidgets headers would have be included when compiling every
|
114 |
|
|
// single bochs file. One of the things I like about the separation
|
115 |
|
|
// between the simulator and CI is that the two parts can be
|
116 |
|
|
// compiled without any knowledge of the other. Bochs doesn't include
|
117 |
|
|
// <wx.h>, and the wxWidgets CI (wxmain.cc) doesn't need to include <bochs.h>.
|
118 |
|
|
// Aside from making compiles faster, this enforces the use of the siminterface
|
119 |
|
|
// so it keeps the interface clean (important when we may have multiple UI
|
120 |
|
|
// implementations for example). This argues for keeping UI-specific
|
121 |
|
|
// structures out of the simulator interface. It certainly works ok for the
|
122 |
|
|
// text interface, but that's because FILE* is standard and portable.
|
123 |
|
|
|
124 |
|
|
//////////////////////////////////////////////////////
|
125 |
|
|
|
126 |
|
|
// base value for generated new parameter id
|
127 |
|
|
#define BXP_NEW_PARAM_ID 1001
|
128 |
|
|
|
129 |
|
|
enum {
|
130 |
|
|
#define bx_define_cpudb(model) bx_cpudb_##model,
|
131 |
|
|
#include "cpudb.h"
|
132 |
|
|
bx_cpudb_model_last
|
133 |
|
|
};
|
134 |
|
|
#undef bx_define_cpudb
|
135 |
|
|
|
136 |
|
|
#if BX_SUPPORT_SMP
|
137 |
|
|
#define BX_SMP_PROCESSORS (bx_cpu_count)
|
138 |
|
|
#else
|
139 |
|
|
#define BX_SMP_PROCESSORS 1
|
140 |
|
|
#endif
|
141 |
|
|
|
142 |
|
|
typedef enum {
|
143 |
|
|
BX_TOOLBAR_UNDEFINED,
|
144 |
|
|
BX_TOOLBAR_FLOPPYA,
|
145 |
|
|
BX_TOOLBAR_FLOPPYB,
|
146 |
|
|
BX_TOOLBAR_CDROM1,
|
147 |
|
|
BX_TOOLBAR_RESET,
|
148 |
|
|
BX_TOOLBAR_POWER,
|
149 |
|
|
BX_TOOLBAR_SAVE_RESTORE,
|
150 |
|
|
BX_TOOLBAR_COPY,
|
151 |
|
|
BX_TOOLBAR_PASTE,
|
152 |
|
|
BX_TOOLBAR_SNAPSHOT,
|
153 |
|
|
BX_TOOLBAR_CONFIG,
|
154 |
|
|
BX_TOOLBAR_MOUSE_EN,
|
155 |
|
|
BX_TOOLBAR_USER
|
156 |
|
|
} bx_toolbar_buttons;
|
157 |
|
|
|
158 |
|
|
// Log level defines
|
159 |
|
|
typedef enum {
|
160 |
|
|
LOGLEV_DEBUG = 0,
|
161 |
|
|
LOGLEV_INFO,
|
162 |
|
|
LOGLEV_ERROR,
|
163 |
|
|
LOGLEV_PANIC,
|
164 |
|
|
N_LOGLEV
|
165 |
|
|
} bx_log_levels;
|
166 |
|
|
|
167 |
|
|
// Log action defines
|
168 |
|
|
typedef enum {
|
169 |
|
|
ACT_IGNORE = 0,
|
170 |
|
|
ACT_REPORT,
|
171 |
|
|
ACT_ASK,
|
172 |
|
|
ACT_FATAL,
|
173 |
|
|
N_ACT
|
174 |
|
|
} bx_log_actions;
|
175 |
|
|
|
176 |
|
|
// normally all action choices are available for all event types. The exclude
|
177 |
|
|
// expression allows some choices to be eliminated if they don't make any
|
178 |
|
|
// sense. For example, it would be stupid to ignore a panic.
|
179 |
|
|
#define BX_LOG_OPTS_EXCLUDE(type, choice) ( \
|
180 |
|
|
/* can't die or ask, on debug or info events */ \
|
181 |
|
|
(type <= LOGLEV_INFO && (choice == ACT_ASK || choice == ACT_FATAL)) \
|
182 |
|
|
/* can't ignore panics */ \
|
183 |
|
|
|| (type == LOGLEV_PANIC && choice == ACT_IGNORE) \
|
184 |
|
|
)
|
185 |
|
|
|
186 |
|
|
// floppy / cdrom media status
|
187 |
|
|
#define BX_EJECTED 0
|
188 |
|
|
#define BX_INSERTED 1
|
189 |
|
|
|
190 |
|
|
// boot devices (using the same values as the rombios)
|
191 |
|
|
enum {
|
192 |
|
|
BX_BOOT_NONE,
|
193 |
|
|
BX_BOOT_FLOPPYA,
|
194 |
|
|
BX_BOOT_DISKC,
|
195 |
|
|
BX_BOOT_CDROM,
|
196 |
|
|
BX_BOOT_NETWORK
|
197 |
|
|
};
|
198 |
|
|
|
199 |
|
|
// loader hack
|
200 |
|
|
#define Load32bitOSNone 0
|
201 |
|
|
#define Load32bitOSLinux 1
|
202 |
|
|
#define Load32bitOSNullKernel 2 // being developed for plex86
|
203 |
|
|
#define Load32bitOSLast 2
|
204 |
|
|
|
205 |
|
|
///////////////////////////////////////////////////////////////////
|
206 |
|
|
// event structures for communication between simulator and CI
|
207 |
|
|
///////////////////////////////////////////////////////////////////
|
208 |
|
|
// Because the CI (configuration interface) might be in a different
|
209 |
|
|
// thread or even a different process, we pass events encoded in data
|
210 |
|
|
// structures to it instead of just calling functions. Each type of
|
211 |
|
|
// event is declared as a different structure, and then all those
|
212 |
|
|
// structures are squished into a union in BxEvent. (BTW, this is
|
213 |
|
|
// almost exactly how X windows event structs work.)
|
214 |
|
|
//
|
215 |
|
|
// These are simple structs, unblemished by C++ methods and tricks.
|
216 |
|
|
// No matter what event type it is, we allocate a BxEvent for each
|
217 |
|
|
// one, as opposed to trying to save a few bytes on small events by
|
218 |
|
|
// allocating only the bytes necessary for it. This makes it easy and
|
219 |
|
|
// fast to store events in a queue, like this
|
220 |
|
|
// BxEvent event_queue[MAX_EVENTS];
|
221 |
|
|
//
|
222 |
|
|
// Events come in two varieties: synchronous and asynchronous. We
|
223 |
|
|
// have to worry about sync and async events because the CI and the
|
224 |
|
|
// simulation may be running in different threads. An async event is
|
225 |
|
|
// the simplest. Whichever thread originates the event just builds
|
226 |
|
|
// the data structure, sends it, and then continues with its business.
|
227 |
|
|
// Async events can go in either direction. Synchronous events
|
228 |
|
|
// require the other thread to "respond" before the originating thread
|
229 |
|
|
// can continue. It's like a function with a return value; you can't
|
230 |
|
|
// continue until you get the return value back.
|
231 |
|
|
//
|
232 |
|
|
// Examples:
|
233 |
|
|
//
|
234 |
|
|
// async event: In the wxWidgets implementation, both the CI and the
|
235 |
|
|
// VGAW operate in the wxWidgets GUI thread. When the user presses a
|
236 |
|
|
// key, wxWidgets sends a wxKeyEvent to the VGAW event handler code in
|
237 |
|
|
// wx.cc. The VGAW handler then builds a BxEvent with
|
238 |
|
|
// type=BX_ASYNC_EVT_KEY, and fills in the bx_key and raw_scancode
|
239 |
|
|
// fields. The asynchronous event is placed on the event_queue for
|
240 |
|
|
// the simulator, then the VGAW handler returns. (With wxWidgets and
|
241 |
|
|
// many other graphical libaries, the event handler must return
|
242 |
|
|
// quickly because the window will not be updated until it's done.)
|
243 |
|
|
// Some time later, the simulator reaches the point where it checks
|
244 |
|
|
// for new events from the user (actually controlled by
|
245 |
|
|
// bx_devices_c::timer() in iodev/devices.cc) and calls
|
246 |
|
|
// bx_gui->handle_events(). Then all the events in the queue are
|
247 |
|
|
// processed by the simulator. There is no "response" sent back to
|
248 |
|
|
// the originating thread.
|
249 |
|
|
//
|
250 |
|
|
// sync event: Sometimes the simulator reaches a point where it needs
|
251 |
|
|
// to ask the user how to proceed. In this case, the simulator sends
|
252 |
|
|
// a synchronous event because it requires a response before it can
|
253 |
|
|
// continue. It builds an event structure, perhaps with type
|
254 |
|
|
// BX_SYNC_EVT_ASK_PARAM, sends it to the user interface
|
255 |
|
|
// using the event handler function defined by set_notify_callback(),
|
256 |
|
|
// and pauses the simulation. The user interface asks the user the
|
257 |
|
|
// question, and puts the answer into the BxEvent.retcode field. The
|
258 |
|
|
// event handler function returns the modified BxEvent with retcode
|
259 |
|
|
// filled in, and the simulation continues. The details of this
|
260 |
|
|
// transaction can be complicated if the simulation and CI are not
|
261 |
|
|
// in the same thread, but the behavior is as described.
|
262 |
|
|
//
|
263 |
|
|
|
264 |
|
|
///// types and definitions used in event structures
|
265 |
|
|
|
266 |
|
|
#define BX_EVT_IS_ASYNC(type) ((type) > __ALL_EVENTS_BELOW_ARE_ASYNC__)
|
267 |
|
|
|
268 |
|
|
typedef enum {
|
269 |
|
|
__ALL_EVENTS_BELOW_ARE_SYNCHRONOUS__ = 2000,
|
270 |
|
|
BX_SYNC_EVT_GET_PARAM, // CI -> simulator -> CI
|
271 |
|
|
BX_SYNC_EVT_ASK_PARAM, // simulator -> CI -> simulator
|
272 |
|
|
BX_SYNC_EVT_TICK, // simulator -> CI, wait for response.
|
273 |
|
|
BX_SYNC_EVT_LOG_ASK, // simulator -> CI, wait for response.
|
274 |
|
|
BX_SYNC_EVT_GET_DBG_COMMAND, // simulator -> CI, wait for response.
|
275 |
|
|
__ALL_EVENTS_BELOW_ARE_ASYNC__,
|
276 |
|
|
BX_ASYNC_EVT_KEY, // vga window -> simulator
|
277 |
|
|
BX_ASYNC_EVT_MOUSE, // vga window -> simulator
|
278 |
|
|
BX_ASYNC_EVT_SET_PARAM, // CI -> simulator
|
279 |
|
|
BX_ASYNC_EVT_LOG_MSG, // simulator -> CI
|
280 |
|
|
BX_ASYNC_EVT_DBG_MSG, // simulator -> CI
|
281 |
|
|
BX_ASYNC_EVT_VALUE_CHANGED, // simulator -> CI
|
282 |
|
|
BX_ASYNC_EVT_TOOLBAR, // CI -> simulator
|
283 |
|
|
BX_ASYNC_EVT_REFRESH, // simulator -> CI
|
284 |
|
|
BX_ASYNC_EVT_QUIT_SIM // simulator -> CI
|
285 |
|
|
} BxEventType;
|
286 |
|
|
|
287 |
|
|
typedef union {
|
288 |
|
|
Bit32s s32;
|
289 |
|
|
char *charptr;
|
290 |
|
|
} AnyParamVal;
|
291 |
|
|
|
292 |
|
|
// Define substructures which make up the interior of BxEvent. The
|
293 |
|
|
// substructures, such as BxKeyEvent or BxMouseEvent, should never be
|
294 |
|
|
// allocated on their own. They are only intended to be used within
|
295 |
|
|
// the union in the BxEvent structure.
|
296 |
|
|
|
297 |
|
|
// Event type: BX_SYNC_EVT_TICK
|
298 |
|
|
//
|
299 |
|
|
// A tick event is synchronous, sent from the simulator to the GUI. The
|
300 |
|
|
// event doesn't do anything visible. Primarily it gives the GUI a chance
|
301 |
|
|
// to tell the simulator to quit, if necessary. There may be other uses
|
302 |
|
|
// for the tick in the future, such as giving some kind of regular
|
303 |
|
|
// status report or mentioning watched values that changed, but so far
|
304 |
|
|
// it's just for that one thing. There is no data associated with a
|
305 |
|
|
// tick event.
|
306 |
|
|
|
307 |
|
|
// Event type: BX_ASYNC_EVT_KEY
|
308 |
|
|
//
|
309 |
|
|
// A key event can be sent from the VGA window to the Bochs simulator.
|
310 |
|
|
// It is asynchronous.
|
311 |
|
|
typedef struct {
|
312 |
|
|
// what was pressed? This is a BX_KEY_* value. For key releases,
|
313 |
|
|
// BX_KEY_RELEASED is ORed with the base BX_KEY_*.
|
314 |
|
|
Bit32u bx_key;
|
315 |
|
|
bx_bool raw_scancode;
|
316 |
|
|
} BxKeyEvent;
|
317 |
|
|
|
318 |
|
|
// Event type: BX_ASYNC_EVT_MOUSE
|
319 |
|
|
//
|
320 |
|
|
// A mouse event can be sent from the VGA window to the Bochs
|
321 |
|
|
// simulator. It is asynchronous.
|
322 |
|
|
typedef struct {
|
323 |
|
|
// type is BX_EVT_MOUSE
|
324 |
|
|
Bit16s dx, dy, dz; // mouse motion delta
|
325 |
|
|
Bit8u buttons; // which buttons are pressed.
|
326 |
|
|
// bit 0: 1=left button down, 0=up
|
327 |
|
|
// bit 1: 1=right button down, 0=up
|
328 |
|
|
// bit 2: 1=middle button down, 0=up
|
329 |
|
|
} BxMouseEvent;
|
330 |
|
|
|
331 |
|
|
// Event type: BX_SYNC_EVT_GET_PARAM, BX_ASYNC_EVT_SET_PARAM
|
332 |
|
|
//
|
333 |
|
|
// Parameter set/get events are initiated by the CI, since Bochs can
|
334 |
|
|
// always access the parameters directly. So far, I haven't used
|
335 |
|
|
// these event types. In the CI I just call
|
336 |
|
|
// SIM->get_param(parameter_id) to get a pointer to the bx_param_c
|
337 |
|
|
// object and then call the get/set methods. This is okay for
|
338 |
|
|
// configuration since bochs is not running. However it could be
|
339 |
|
|
// dangerous for the GUI thread to poke around in Bochs structures
|
340 |
|
|
// while the thread is running. For these cases, I may have to be
|
341 |
|
|
// more careful and actually build get/set events and place them on
|
342 |
|
|
// Bochs's event queue to be processed during SIM->periodic() or
|
343 |
|
|
// something.
|
344 |
|
|
typedef struct {
|
345 |
|
|
// type is BX_EVT_GET_PARAM, BX_EVT_SET_PARAM
|
346 |
|
|
class bx_param_c *param; // pointer to param structure
|
347 |
|
|
AnyParamVal val;
|
348 |
|
|
} BxParamEvent;
|
349 |
|
|
|
350 |
|
|
// Event type: BX_SYNC_EVT_ASK_PARAM
|
351 |
|
|
// Synchronous event sent from the simulator to the CI. This tells the
|
352 |
|
|
// CI to ask the user to choose the value of a parameter. The CI may
|
353 |
|
|
// need to discover the type of parameter so that it can use the right
|
354 |
|
|
// kind of graphical display. The BxParamEvent is used for these events
|
355 |
|
|
// too.
|
356 |
|
|
// FIXME: at the moment the GUI implements the ASK_PARAM event for just
|
357 |
|
|
// a few parameter types. I need to implement the event for all parameter
|
358 |
|
|
// types.
|
359 |
|
|
|
360 |
|
|
// Event type: BX_ASYNC_EVT_VALUE_CHANGED
|
361 |
|
|
//
|
362 |
|
|
// Asynchronous event sent from the simulator to the CI, telling it that
|
363 |
|
|
// some value that it (hopefully) cares about has changed. This isn't
|
364 |
|
|
// being used yet, but a good example is in a debugger interface, you might
|
365 |
|
|
// want to maintain a reasonably current display of the PC or some other
|
366 |
|
|
// simulation state. The CI would set some kind of event mask (which
|
367 |
|
|
// doesn't exist now of course) and then when certain values change, the
|
368 |
|
|
// simulator would send this event so that the CI can update. We may need
|
369 |
|
|
// some kind of "flow control" since the simulator will be able to produce
|
370 |
|
|
// new events much faster than the gui can accept them.
|
371 |
|
|
|
372 |
|
|
// Event type: BX_ASYNC_EVT_LOG_MSG (unused)
|
373 |
|
|
//
|
374 |
|
|
// Asynchronous event from the simulator to the CI. When a BX_PANIC,
|
375 |
|
|
// BX_ERROR, BX_INFO, or BX_DEBUG is found in the simulator code, this
|
376 |
|
|
// event type can be used to inform the CI of the condition. There is
|
377 |
|
|
// no point in sending messages to the CI that will not be displayed; these
|
378 |
|
|
// would only slow the simulation. So we will need some mechanism for
|
379 |
|
|
// choosing what kinds of events will be delivered to the CI. Normally,
|
380 |
|
|
// you wouldn't want to look at the log unless something is going wrong.
|
381 |
|
|
// At that point, you might want to open up a window to watch the debug
|
382 |
|
|
// messages from one or two devices only.
|
383 |
|
|
//
|
384 |
|
|
// Idea: Except for panics that require user attention to continue, it
|
385 |
|
|
// might be most efficient to just append log messages to a file.
|
386 |
|
|
// When the user wants to look at the log messages, the gui can reopen
|
387 |
|
|
// the file (read only), skip to the end, and look backward for a
|
388 |
|
|
// reasonable number of lines to display (200?). This allows it to
|
389 |
|
|
// skip over huge bursts of log entries without allocating memory,
|
390 |
|
|
// synchronizing threads, etc. for each.
|
391 |
|
|
typedef struct {
|
392 |
|
|
Bit8u level;
|
393 |
|
|
const char *prefix;
|
394 |
|
|
const char *msg;
|
395 |
|
|
} BxLogMsgEvent;
|
396 |
|
|
|
397 |
|
|
// Event type: BX_ASYNC_EVT_DBG_MSG
|
398 |
|
|
//
|
399 |
|
|
// Also uses BxLogMsgEvent, but this is a message to be displayed in
|
400 |
|
|
// the debugger history window.
|
401 |
|
|
|
402 |
|
|
// Event type: BX_SYNC_EVT_LOG_ASK
|
403 |
|
|
//
|
404 |
|
|
// This is a synchronous version of BX_ASYNC_EVT_LOG_MSG, which is used
|
405 |
|
|
// when the "action=ask" setting is used. If the simulator runs into a
|
406 |
|
|
// panic, it sends a synchronous BX_SYNC_EVT_LOG_ASK to the CI to be
|
407 |
|
|
// displayed. The CI shows a dialog that asks if the user wants to
|
408 |
|
|
// continue, quit, etc. and sends the answer back to the simulator.
|
409 |
|
|
// This event also uses BxLogMsgEvent.
|
410 |
|
|
enum {
|
411 |
|
|
BX_LOG_ASK_CHOICE_CONTINUE,
|
412 |
|
|
BX_LOG_ASK_CHOICE_CONTINUE_ALWAYS,
|
413 |
|
|
BX_LOG_ASK_CHOICE_DIE,
|
414 |
|
|
BX_LOG_ASK_CHOICE_DUMP_CORE,
|
415 |
|
|
BX_LOG_ASK_CHOICE_ENTER_DEBUG,
|
416 |
|
|
BX_LOG_ASK_N_CHOICES,
|
417 |
|
|
BX_LOG_NOTIFY_FAILED
|
418 |
|
|
};
|
419 |
|
|
|
420 |
|
|
// Event type: BX_SYNC_EVT_GET_DBG_COMMAND
|
421 |
|
|
//
|
422 |
|
|
// This is a synchronous event sent from the simulator to the debugger
|
423 |
|
|
// requesting the next action. In a text mode debugger, this would prompt
|
424 |
|
|
// the user for the next command. When a new command is ready, the
|
425 |
|
|
// synchronous event is sent back with its fields filled in.
|
426 |
|
|
typedef struct {
|
427 |
|
|
char *command; // null terminated string. allocated by debugger interface
|
428 |
|
|
// with new operator, freed by simulator with delete.
|
429 |
|
|
} BxDebugCommand;
|
430 |
|
|
|
431 |
|
|
|
432 |
|
|
|
433 |
|
|
// Event type: BX_EVT_TOOLBAR
|
434 |
|
|
// Asynchronous event from the VGAW to the simulator, sent when the user
|
435 |
|
|
// clicks on a toolbar button. This may one day become something more
|
436 |
|
|
// general, like a command event, but at the moment it's only needed for
|
437 |
|
|
// the toolbar events.
|
438 |
|
|
typedef struct {
|
439 |
|
|
bx_toolbar_buttons button;
|
440 |
|
|
bx_bool on; // for toggling buttons, on=true means the toolbar button is
|
441 |
|
|
// pressed. on=false means it is not pressed.
|
442 |
|
|
} BxToolbarEvent;
|
443 |
|
|
|
444 |
|
|
// The BxEvent structure should be used for all events. Every event has
|
445 |
|
|
// a type and a spot for a return code (only used for synchronous events).
|
446 |
|
|
typedef struct {
|
447 |
|
|
BxEventType type; // what kind is this?
|
448 |
|
|
Bit32s retcode; // sucess or failure. only used for synchronous events.
|
449 |
|
|
union {
|
450 |
|
|
BxKeyEvent key;
|
451 |
|
|
BxMouseEvent mouse;
|
452 |
|
|
BxParamEvent param;
|
453 |
|
|
BxLogMsgEvent logmsg;
|
454 |
|
|
BxToolbarEvent toolbar;
|
455 |
|
|
BxDebugCommand debugcmd;
|
456 |
|
|
} u;
|
457 |
|
|
} BxEvent;
|
458 |
|
|
|
459 |
|
|
#include "paramtree.h"
|
460 |
|
|
|
461 |
|
|
// These are the different start modes.
|
462 |
|
|
enum {
|
463 |
|
|
// Just start the simulation without running the configuration interface
|
464 |
|
|
// at all, unless something goes wrong.
|
465 |
|
|
BX_QUICK_START = 200,
|
466 |
|
|
// Run the configuration interface. The default action will be to load a
|
467 |
|
|
// configuration file. This makes sense if a config file could not be
|
468 |
|
|
// loaded, either because it wasn't found or because it had errors.
|
469 |
|
|
BX_LOAD_START,
|
470 |
|
|
// Run the configuration interface. The default action will be to
|
471 |
|
|
// edit the configuration.
|
472 |
|
|
BX_EDIT_START,
|
473 |
|
|
// Run the configuration interface, but make the default action be to
|
474 |
|
|
// start the simulation.
|
475 |
|
|
BX_RUN_START
|
476 |
|
|
};
|
477 |
|
|
|
478 |
|
|
enum {
|
479 |
|
|
BX_MOUSE_TYPE_NONE,
|
480 |
|
|
BX_MOUSE_TYPE_PS2,
|
481 |
|
|
BX_MOUSE_TYPE_IMPS2,
|
482 |
|
|
#if BX_SUPPORT_BUSMOUSE
|
483 |
|
|
BX_MOUSE_TYPE_BUS,
|
484 |
|
|
#endif
|
485 |
|
|
BX_MOUSE_TYPE_SERIAL,
|
486 |
|
|
BX_MOUSE_TYPE_SERIAL_WHEEL,
|
487 |
|
|
BX_MOUSE_TYPE_SERIAL_MSYS
|
488 |
|
|
};
|
489 |
|
|
|
490 |
|
|
enum {
|
491 |
|
|
BX_MOUSE_TOGGLE_CTRL_MB,
|
492 |
|
|
BX_MOUSE_TOGGLE_CTRL_F10,
|
493 |
|
|
BX_MOUSE_TOGGLE_CTRL_ALT,
|
494 |
|
|
BX_MOUSE_TOGGLE_F12
|
495 |
|
|
};
|
496 |
|
|
|
497 |
|
|
#define BX_FDD_NONE 0 // floppy not present
|
498 |
|
|
#define BX_FDD_525DD 1 // 360K 5.25"
|
499 |
|
|
#define BX_FDD_525HD 2 // 1.2M 5.25"
|
500 |
|
|
#define BX_FDD_350DD 3 // 720K 3.5"
|
501 |
|
|
#define BX_FDD_350HD 4 // 1.44M 3.5"
|
502 |
|
|
#define BX_FDD_350ED 5 // 2.88M 3.5"
|
503 |
|
|
|
504 |
|
|
#define BX_FLOPPY_NONE 10 // media not present
|
505 |
|
|
#define BX_FLOPPY_1_2 11 // 1.2M 5.25"
|
506 |
|
|
#define BX_FLOPPY_1_44 12 // 1.44M 3.5"
|
507 |
|
|
#define BX_FLOPPY_2_88 13 // 2.88M 3.5"
|
508 |
|
|
#define BX_FLOPPY_720K 14 // 720K 3.5"
|
509 |
|
|
#define BX_FLOPPY_360K 15 // 360K 5.25"
|
510 |
|
|
#define BX_FLOPPY_160K 16 // 160K 5.25"
|
511 |
|
|
#define BX_FLOPPY_180K 17 // 180K 5.25"
|
512 |
|
|
#define BX_FLOPPY_320K 18 // 320K 5.25"
|
513 |
|
|
#define BX_FLOPPY_LAST 18 // last legal value of floppy type
|
514 |
|
|
|
515 |
|
|
#define BX_FLOPPY_AUTO 19 // autodetect image size
|
516 |
|
|
#define BX_FLOPPY_UNKNOWN 20 // image size doesn't match one of the types above
|
517 |
|
|
|
518 |
|
|
#define BX_ATA_DEVICE_NONE 0
|
519 |
|
|
#define BX_ATA_DEVICE_DISK 1
|
520 |
|
|
#define BX_ATA_DEVICE_CDROM 2
|
521 |
|
|
|
522 |
|
|
#define BX_ATA_BIOSDETECT_NONE 0
|
523 |
|
|
#define BX_ATA_BIOSDETECT_AUTO 1
|
524 |
|
|
#define BX_ATA_BIOSDETECT_CMOS 2
|
525 |
|
|
|
526 |
|
|
enum {
|
527 |
|
|
BX_ATA_TRANSLATION_NONE,
|
528 |
|
|
BX_ATA_TRANSLATION_LBA,
|
529 |
|
|
BX_ATA_TRANSLATION_LARGE,
|
530 |
|
|
BX_ATA_TRANSLATION_RECHS,
|
531 |
|
|
BX_ATA_TRANSLATION_AUTO
|
532 |
|
|
};
|
533 |
|
|
#define BX_ATA_TRANSLATION_LAST BX_ATA_TRANSLATION_AUTO
|
534 |
|
|
|
535 |
|
|
enum {
|
536 |
|
|
BX_HDIMAGE_MODE_FLAT,
|
537 |
|
|
BX_HDIMAGE_MODE_CONCAT,
|
538 |
|
|
BX_HDIMAGE_MODE_EXTDISKSIM,
|
539 |
|
|
BX_HDIMAGE_MODE_DLL_HD,
|
540 |
|
|
BX_HDIMAGE_MODE_SPARSE,
|
541 |
|
|
BX_HDIMAGE_MODE_VMWARE3,
|
542 |
|
|
BX_HDIMAGE_MODE_VMWARE4,
|
543 |
|
|
BX_HDIMAGE_MODE_UNDOABLE,
|
544 |
|
|
BX_HDIMAGE_MODE_GROWING,
|
545 |
|
|
BX_HDIMAGE_MODE_VOLATILE,
|
546 |
|
|
BX_HDIMAGE_MODE_VVFAT,
|
547 |
|
|
BX_HDIMAGE_MODE_VPC
|
548 |
|
|
};
|
549 |
|
|
#define BX_HDIMAGE_MODE_LAST BX_HDIMAGE_MODE_VPC
|
550 |
|
|
#define BX_HDIMAGE_MODE_UNKNOWN -1
|
551 |
|
|
|
552 |
|
|
enum {
|
553 |
|
|
BX_CLOCK_SYNC_NONE,
|
554 |
|
|
BX_CLOCK_SYNC_REALTIME,
|
555 |
|
|
BX_CLOCK_SYNC_SLOWDOWN,
|
556 |
|
|
BX_CLOCK_SYNC_BOTH
|
557 |
|
|
};
|
558 |
|
|
#define BX_CLOCK_SYNC_LAST BX_CLOCK_SYNC_BOTH
|
559 |
|
|
|
560 |
|
|
enum {
|
561 |
|
|
BX_PCI_CHIPSET_I430FX,
|
562 |
|
|
BX_PCI_CHIPSET_I440FX
|
563 |
|
|
};
|
564 |
|
|
|
565 |
|
|
enum {
|
566 |
|
|
BX_CPUID_SUPPORT_NOSSE,
|
567 |
|
|
BX_CPUID_SUPPORT_SSE,
|
568 |
|
|
BX_CPUID_SUPPORT_SSE2,
|
569 |
|
|
BX_CPUID_SUPPORT_SSE3,
|
570 |
|
|
BX_CPUID_SUPPORT_SSSE3,
|
571 |
|
|
BX_CPUID_SUPPORT_SSE4_1,
|
572 |
|
|
BX_CPUID_SUPPORT_SSE4_2
|
573 |
|
|
};
|
574 |
|
|
|
575 |
|
|
enum {
|
576 |
|
|
BX_CPUID_SUPPORT_LEGACY_APIC,
|
577 |
|
|
BX_CPUID_SUPPORT_XAPIC,
|
578 |
|
|
#if BX_CPU_LEVEL >= 6
|
579 |
|
|
BX_CPUID_SUPPORT_XAPIC_EXT,
|
580 |
|
|
BX_CPUID_SUPPORT_X2APIC
|
581 |
|
|
#endif
|
582 |
|
|
};
|
583 |
|
|
|
584 |
|
|
#define BX_CLOCK_TIME0_LOCAL 1
|
585 |
|
|
#define BX_CLOCK_TIME0_UTC 2
|
586 |
|
|
|
587 |
|
|
BOCHSAPI extern const char *floppy_devtype_names[];
|
588 |
|
|
BOCHSAPI extern const char *floppy_type_names[];
|
589 |
|
|
BOCHSAPI extern int floppy_type_n_sectors[];
|
590 |
|
|
BOCHSAPI extern const char *media_status_names[];
|
591 |
|
|
BOCHSAPI extern const char *bochs_bootdisk_names[];
|
592 |
|
|
BOCHSAPI extern const char *hdimage_mode_names[];
|
593 |
|
|
|
594 |
|
|
////////////////////////////////////////////////////////////////////
|
595 |
|
|
// base class simulator interface, contains just virtual functions.
|
596 |
|
|
// I'm not longer sure that having a base class is going to be of any
|
597 |
|
|
// use... -Bryce
|
598 |
|
|
|
599 |
|
|
#include <setjmp.h>
|
600 |
|
|
|
601 |
|
|
enum ci_command_t { CI_START, CI_RUNTIME_CONFIG, CI_SHUTDOWN };
|
602 |
|
|
enum ci_return_t {
|
603 |
|
|
CI_OK, // normal return value
|
604 |
|
|
CI_ERR_NO_TEXT_CONSOLE // err: can't work because there's no text console
|
605 |
|
|
};
|
606 |
|
|
typedef int (*config_interface_callback_t)(void *userdata, ci_command_t command);
|
607 |
|
|
typedef BxEvent* (*bxevent_handler)(void *theclass, BxEvent *event);
|
608 |
|
|
typedef void (*rt_conf_handler_t)(void *this_ptr);
|
609 |
|
|
typedef Bit32s (*addon_option_parser_t)(const char *context, int num_params, char *params[]);
|
610 |
|
|
typedef Bit32s (*addon_option_save_t)(FILE *fp);
|
611 |
|
|
|
612 |
|
|
// bx_gui->set_display_mode() changes the mode between the configuration
|
613 |
|
|
// interface and the simulation. This is primarily intended for display
|
614 |
|
|
// libraries which have a full-screen mode such as SDL, term, and svgalib. The
|
615 |
|
|
// display mode is set to DISP_MODE_CONFIG before displaying any configuration
|
616 |
|
|
// menus, for panics that requires user input, when entering the debugger, etc.
|
617 |
|
|
// It is set to DISP_MODE_SIM when the Bochs simulation resumes. The constants
|
618 |
|
|
// are defined here so that configuration interfaces can use them with the
|
619 |
|
|
// bx_simulator_interface_c::set_display_mode() method.
|
620 |
|
|
enum disp_mode_t { DISP_MODE_CONFIG=100, DISP_MODE_SIM };
|
621 |
|
|
|
622 |
|
|
class BOCHSAPI bx_simulator_interface_c {
|
623 |
|
|
public:
|
624 |
|
|
bx_simulator_interface_c() {}
|
625 |
|
|
virtual ~bx_simulator_interface_c() {}
|
626 |
|
|
virtual void set_quit_context(jmp_buf *context) {}
|
627 |
|
|
virtual int get_init_done() { return -1; }
|
628 |
|
|
virtual int set_init_done(int n) {return -1;}
|
629 |
|
|
virtual void reset_all_param() {}
|
630 |
|
|
// new param methods
|
631 |
|
|
virtual bx_param_c *get_param(const char *pname, bx_param_c *base=NULL) {return NULL;}
|
632 |
|
|
virtual bx_param_num_c *get_param_num(const char *pname, bx_param_c *base=NULL) {return NULL;}
|
633 |
|
|
virtual bx_param_string_c *get_param_string(const char *pname, bx_param_c *base=NULL) {return NULL;}
|
634 |
|
|
virtual bx_param_bool_c *get_param_bool(const char *pname, bx_param_c *base=NULL) {return NULL;}
|
635 |
|
|
virtual bx_param_enum_c *get_param_enum(const char *pname, bx_param_c *base=NULL) {return NULL;}
|
636 |
|
|
virtual unsigned gen_param_id() {return 0;}
|
637 |
|
|
virtual int get_n_log_modules() {return -1;}
|
638 |
|
|
virtual const char *get_logfn_name(int mod) {return 0;}
|
639 |
|
|
virtual int get_logfn_id(const char *name) {return -1;}
|
640 |
|
|
virtual const char *get_prefix(int mod) {return 0;}
|
641 |
|
|
virtual int get_log_action(int mod, int level) {return -1;}
|
642 |
|
|
virtual void set_log_action(int mod, int level, int action) {}
|
643 |
|
|
virtual int get_default_log_action(int level) {return -1;}
|
644 |
|
|
virtual void set_default_log_action(int level, int action) {}
|
645 |
|
|
virtual const char *get_action_name(int action) {return 0;}
|
646 |
|
|
virtual const char *get_log_level_name(int level) {return 0;}
|
647 |
|
|
virtual int get_max_log_level() {return -1;}
|
648 |
|
|
|
649 |
|
|
// exiting is somewhat complicated! The preferred way to exit bochs is
|
650 |
|
|
// to call BX_EXIT(exitcode). That is defined to call
|
651 |
|
|
// SIM->quit_sim(exitcode). The quit_sim function first calls
|
652 |
|
|
// the cleanup functions in bochs so that it can destroy windows
|
653 |
|
|
// and free up memory, then sends a notify message to the CI
|
654 |
|
|
// telling it that bochs has stopped.
|
655 |
|
|
virtual void quit_sim(int code) {}
|
656 |
|
|
|
657 |
|
|
virtual int get_exit_code() { return 0; }
|
658 |
|
|
|
659 |
|
|
virtual int get_default_rc(char *path, int len) {return -1;}
|
660 |
|
|
virtual int read_rc(const char *path) {return -1;}
|
661 |
|
|
virtual int write_rc(const char *rc, int overwrite) {return -1;}
|
662 |
|
|
virtual int get_log_file(char *path, int len) {return -1;}
|
663 |
|
|
virtual int set_log_file(char *path) {return -1;}
|
664 |
|
|
virtual int get_log_prefix(char *prefix, int len) {return -1;}
|
665 |
|
|
virtual int set_log_prefix(char *prefix) {return -1;}
|
666 |
|
|
virtual int get_debugger_log_file(char *path, int len) {return -1;}
|
667 |
|
|
virtual int set_debugger_log_file(char *path) {return -1;}
|
668 |
|
|
virtual int get_cdrom_options(int drive, bx_list_c **out, int *where = NULL) {return -1;}
|
669 |
|
|
virtual int hdimage_get_mode(const char *mode) {return -1;}
|
670 |
|
|
|
671 |
|
|
// The CI calls set_notify_callback to register its event handler function.
|
672 |
|
|
// This event handler function is called whenever the simulator needs to
|
673 |
|
|
// send an event to the CI. For example, if the simulator hits a panic and
|
674 |
|
|
// wants to ask the user how to proceed, it would call the CI event handler
|
675 |
|
|
// to ask the CI to display a dialog.
|
676 |
|
|
//
|
677 |
|
|
// NOTE: At present, the standard VGAW buttons (floppy, snapshot, power,
|
678 |
|
|
// etc.) are displayed and handled by gui.cc, not by the CI or siminterface.
|
679 |
|
|
// gui.cc uses its own callback functions to implement the behavior of
|
680 |
|
|
// the buttons. Some of these implementations call the siminterface.
|
681 |
|
|
virtual void set_notify_callback(bxevent_handler func, void *arg) {}
|
682 |
|
|
virtual void get_notify_callback(bxevent_handler *func, void **arg) {}
|
683 |
|
|
|
684 |
|
|
// send an event from the simulator to the CI.
|
685 |
|
|
virtual BxEvent* sim_to_ci_event(BxEvent *event) {return NULL;}
|
686 |
|
|
|
687 |
|
|
// called from simulator when it hits serious errors, to ask if the user
|
688 |
|
|
// wants to continue or not
|
689 |
|
|
virtual int log_msg(const char *prefix, int level, const char *msg) {return -1;}
|
690 |
|
|
|
691 |
|
|
// tell the CI to ask the user for the value of a parameter.
|
692 |
|
|
virtual int ask_param(bx_param_c *param) {return -1;}
|
693 |
|
|
virtual int ask_param(const char *pname) {return -1;}
|
694 |
|
|
|
695 |
|
|
// ask the user for a pathname
|
696 |
|
|
virtual int ask_filename(const char *filename, int maxlen, const char *prompt, const char *the_default, int flags) {return -1;}
|
697 |
|
|
// yes/no dialog
|
698 |
|
|
virtual int ask_yes_no(const char *title, const char *prompt, bx_bool the_default) {return -1;}
|
699 |
|
|
// called at a regular interval, currently by the bx_devices_c::timer()
|
700 |
|
|
virtual void periodic() {}
|
701 |
|
|
virtual int create_disk_image(const char *filename, int sectors, bx_bool overwrite) {return -3;}
|
702 |
|
|
// Tell the configuration interface (CI) that some parameter values have
|
703 |
|
|
// changed. The CI will reread the parameters and change its display if it's
|
704 |
|
|
// appropriate. Maybe later: mention which params have changed to save time.
|
705 |
|
|
virtual void refresh_ci() {}
|
706 |
|
|
// forces a vga update. This was added so that a debugger can force
|
707 |
|
|
// a vga update when single stepping, without having to wait thousands
|
708 |
|
|
// of cycles for the normal vga refresh triggered by the vga timer handler..
|
709 |
|
|
virtual void refresh_vga() {}
|
710 |
|
|
// forces a call to bx_gui.handle_events. This was added so that a debugger
|
711 |
|
|
// can force the gui events to be handled, so that interactive things such
|
712 |
|
|
// as a toolbar click will be processed.
|
713 |
|
|
virtual void handle_events() {}
|
714 |
|
|
// return first hard disk in ATA interface
|
715 |
|
|
virtual bx_param_c *get_first_cdrom() {return NULL;}
|
716 |
|
|
// return first cdrom in ATA interface
|
717 |
|
|
virtual bx_param_c *get_first_hd() {return NULL;}
|
718 |
|
|
// return 1 if device is connected to a PCI slot
|
719 |
|
|
virtual bx_bool is_pci_device(const char *name) {return 0;}
|
720 |
|
|
#if BX_DEBUGGER
|
721 |
|
|
// for debugger: same behavior as pressing control-C
|
722 |
|
|
virtual void debug_break() {}
|
723 |
|
|
virtual void debug_interpret_cmd(char *cmd) {}
|
724 |
|
|
virtual char *debug_get_next_command() {return NULL;}
|
725 |
|
|
virtual void debug_puts(const char *text) {}
|
726 |
|
|
#endif
|
727 |
|
|
virtual void register_configuration_interface(
|
728 |
|
|
const char* name,
|
729 |
|
|
config_interface_callback_t callback,
|
730 |
|
|
void *userdata) {}
|
731 |
|
|
virtual int configuration_interface(const char* name, ci_command_t command) {return -1; }
|
732 |
|
|
virtual int begin_simulation(int argc, char *argv[]) {return -1;}
|
733 |
|
|
virtual bx_bool register_runtime_config_handler(void *dev, rt_conf_handler_t handler) {return 0;}
|
734 |
|
|
virtual void update_runtime_options() {}
|
735 |
|
|
typedef bx_bool (*is_sim_thread_func_t)();
|
736 |
|
|
is_sim_thread_func_t is_sim_thread_func;
|
737 |
|
|
virtual void set_sim_thread_func(is_sim_thread_func_t func) {
|
738 |
|
|
is_sim_thread_func = func;
|
739 |
|
|
}
|
740 |
|
|
virtual bx_bool is_sim_thread() {return 1;}
|
741 |
|
|
virtual bx_bool is_wx_selected() const {return 0;}
|
742 |
|
|
virtual void set_debug_gui(bx_bool val) {}
|
743 |
|
|
virtual bx_bool has_debug_gui() const {return 0;}
|
744 |
|
|
// provide interface to bx_gui->set_display_mode() method for config
|
745 |
|
|
// interfaces to use.
|
746 |
|
|
virtual void set_display_mode(disp_mode_t newmode) {}
|
747 |
|
|
virtual bx_bool test_for_text_console() {return 1;}
|
748 |
|
|
// add-on config option support
|
749 |
|
|
virtual bx_bool register_addon_option(const char *keyword, addon_option_parser_t parser, addon_option_save_t save_func) {return 0;}
|
750 |
|
|
virtual bx_bool unregister_addon_option(const char *keyword) {return 0;}
|
751 |
|
|
virtual bx_bool is_addon_option(const char *keyword) {return 0;}
|
752 |
|
|
virtual Bit32s parse_addon_option(const char *context, int num_params, char *params []) {return -1;}
|
753 |
|
|
virtual Bit32s save_addon_options(FILE *fp) {return -1;}
|
754 |
|
|
// save/restore support
|
755 |
|
|
virtual void init_save_restore() {}
|
756 |
|
|
virtual void cleanup_save_restore() {}
|
757 |
|
|
virtual bx_bool save_state(const char *checkpoint_path) {return 0;}
|
758 |
|
|
virtual bx_bool restore_config() {return 0;}
|
759 |
|
|
virtual bx_bool restore_logopts() {return 0;}
|
760 |
|
|
virtual bx_bool restore_hardware() {return 0;}
|
761 |
|
|
virtual bx_list_c *get_bochs_root() {return NULL;}
|
762 |
|
|
virtual bx_bool restore_bochs_param(bx_list_c *root, const char *sr_path, const char *restore_name) { return 0; }
|
763 |
|
|
// special config parameter and options functions for plugins
|
764 |
|
|
virtual bx_bool opt_plugin_ctrl(const char *plugname, bx_bool load) {return 0;}
|
765 |
|
|
virtual void init_std_nic_options(const char *name, bx_list_c *menu) {}
|
766 |
|
|
virtual void init_usb_options(const char *usb_name, const char *pname, int maxports) {}
|
767 |
|
|
virtual int parse_param_from_list(const char *context, const char *param, bx_list_c *base) {return 0;}
|
768 |
|
|
virtual int parse_nic_params(const char *context, const char *param, bx_list_c *base) {return 0;}
|
769 |
|
|
virtual int parse_usb_port_params(const char *context, bx_bool devopt,
|
770 |
|
|
const char *param, int maxports, bx_list_c *base) {return 0;}
|
771 |
|
|
virtual int write_param_list(FILE *fp, bx_list_c *base, const char *optname, bx_bool multiline) {return 0;}
|
772 |
|
|
virtual int write_usb_options(FILE *fp, int maxports, bx_list_c *base) {return 0;}
|
773 |
|
|
};
|
774 |
|
|
|
775 |
|
|
BOCHSAPI extern bx_simulator_interface_c *SIM;
|
776 |
|
|
|
777 |
|
|
BOCHSAPI extern void bx_init_siminterface();
|
778 |
|
|
BOCHSAPI extern int bx_init_main(int argc, char *argv[]);
|
779 |
|
|
|
780 |
|
|
#if defined(__WXMSW__) || defined(WIN32)
|
781 |
|
|
// Just to provide HINSTANCE, etc. in files that have not included bochs.h.
|
782 |
|
|
// I don't like this at all, but I don't see a way around it.
|
783 |
|
|
#include <windows.h>
|
784 |
|
|
#endif
|
785 |
|
|
|
786 |
|
|
// define structure to hold data that is passed into our main function.
|
787 |
|
|
typedef struct BOCHSAPI {
|
788 |
|
|
// standard argc,argv
|
789 |
|
|
int argc;
|
790 |
|
|
char **argv;
|
791 |
|
|
#ifdef WIN32
|
792 |
|
|
char initial_dir[MAX_PATH];
|
793 |
|
|
#endif
|
794 |
|
|
#ifdef __WXMSW__
|
795 |
|
|
// these are only used when compiling with wxWidgets. This gives us a
|
796 |
|
|
// place to store the data that was passed to WinMain.
|
797 |
|
|
HINSTANCE hInstance;
|
798 |
|
|
HINSTANCE hPrevInstance;
|
799 |
|
|
LPSTR m_lpCmdLine;
|
800 |
|
|
int nCmdShow;
|
801 |
|
|
#endif
|
802 |
|
|
} bx_startup_flags_t;
|
803 |
|
|
|
804 |
|
|
BOCHSAPI extern bx_startup_flags_t bx_startup_flags;
|
805 |
|
|
BOCHSAPI extern bx_bool bx_user_quit;
|
806 |
|
|
BOCHSAPI extern Bit8u bx_cpu_count;
|