- commit patch.wxwindows.gz in the main branch. Now you can try out

the wxwindows interface by just "configure --with-wx; make"

  Modified Files:
    Makefile.in bochs.h config.h.in configure configure.in
    load32bitOShack.cc logio.cc main.cc cpu/cpu.cc cpu/cpu.h
    debug/dbg_main.cc gui/Makefile.in gui/control.cc gui/gui.cc
    gui/siminterface.cc gui/siminterface.h gui/x.cc iodev/cdrom.cc
    iodev/keyboard.cc memory/misc_mem.cc
  Added Files:
    README-wxWindows wxbochs.rc gui/wx.cc gui/wxmain.cc
    gui/wxmain.h gui/bitmaps/cdromd.xpm
    gui/bitmaps/configbutton.xpm gui/bitmaps/copy.xpm
    gui/bitmaps/floppya.xpm gui/bitmaps/floppyb.xpm
    gui/bitmaps/mouse.xpm gui/bitmaps/paste.xpm
    gui/bitmaps/power.xpm gui/bitmaps/reset.xpm
    gui/bitmaps/snapshot.xpm
  Removed Files:
    patches/patch.wxwindows.gz
This commit is contained in:
Bryce Denney 2002-04-18 00:22:20 +00:00
parent 13bb61838e
commit 30aaf4088e
36 changed files with 8361 additions and 2081 deletions

View File

@ -96,6 +96,7 @@ GUI_LINK_OPTS_MACOS =
GUI_LINK_OPTS_CARBON = -framework Carbon
GUI_LINK_OPTS_NOGUI =
GUI_LINK_OPTS_TERM = @GUI_LINK_OPTS_TERM@
GUI_LINK_OPTS_WX = `wx-config --libs`
GUI_LINK_OPTS = @GUI_LINK_OPTS@
RANLIB = @RANLIB@
@ -187,7 +188,7 @@ $(BX_OBJS): $(BX_INCLUDES)
bxversion.h:
$(RM) -f bxversion.h
echo '/////////////////////////////////////////////////////////////////////////' > bxversion.h
echo '// $$Id: Makefile.in,v 1.67 2002-03-28 00:28:41 bdenney Exp $$' >> bxversion.h
echo '// $$Id: Makefile.in,v 1.68 2002-04-18 00:22:18 bdenney Exp $$' >> bxversion.h
echo '/////////////////////////////////////////////////////////////////////////' >> bxversion.h
echo '// This file is generated by "make bxversion.h"' >> bxversion.h
echo "#define VER_STRING \"$(VER_STRING)\"" >> bxversion.h

442
bochs/README-wxWindows Normal file
View File

@ -0,0 +1,442 @@
Readme for wxWindows Interface
updated Wed Apr 17 19:59:17 EDT 2002
Bryce Denney
-------------
April 17, 2002: The wxwindows interface is now checked into the main
branch. Known problems
TO DO:
- disk change dialogs for floppy and cdrom need work.
http://sourceforge.net/tracker/index.php?func=detail&aid=545414&group_id=12580&atid=112580
- with --with-wx and debugger, control-C in the terminal window kills the
process instead of just interrupting the simulation.
- tons of dialogs need to be written
- debugger interface
-------------
wxWindows Configuration Interface
The wxWindows port began in June 2001 around the time of Bochs 1.2.1. Dave
Poirier and Bryce Denney started adding a wxWindows configuration interface.
We made some progress, but stopped after a while. Then in March/April 2002
Bryce and Psyon revived the wxWindows branch and turned it into a (mostly)
usable interface. Psyon did most of the work to get text and graphics
working, and Bryce worked on event passing between threads, and keyboard
mapping.
The wxWindows window appears first. This WILL BE where you can choose a preset
configuration or create one from scratch, then edit the bochsrc options using
the GUI. Then, by clicking on Simulate:Start, you can start up the Bochs
simulation. The VGA display is implemented in wxWindows.
WARNING: Don't expect perfect code yet!
Bryce has tested in linux, where a "configure --with-wx;make" should work fine.
To build in VC++:
- in cygwin, do "sh .conf.win32-vcpp". If you want different configure
options from the default, edit .conf.win32-vcpp first.
- in cygwin, do "unzip build/win32/workspace.zip", or use winzip. Now
you should have bochs.dsw and bochs.dsp in the main directory.
- open up bochs.dsw, the workspace file.
- edit project settings so that VC++ can find the wxWindows include
files and libraries on your system. I installed them in
d:/wx/wx232/include and d:/wx/wx232/lib. Specifically, edit
- Project>Settings>C/C++>Preprocessor: include directories.
- Project>Settings>Link>Input: additional library path.
- build
Note that the project is set up for wxWindows 2.3.2, and the only
configuration that I've used is called Win32 Debug. To use on
other wxwindows versions, you will have to change some of the names
of the libraries to include. Use the samples that came with that
version of wxwindows for reference.
What works right now:
- cd to a directory with a bochsrc and disk images in it (I use dlxlinux)
- start up bochs. You get a small wxwindows window with a File menu.
- choose "Start" on the Simulate menu.
- a new window pops up with is the normal bochs window. Bochs starts running.
You can pause it, resume it, or kill it on the Simulate menu.
- the only visible change is that I've made several of the toolbar
icons bring up wxwindows dialog boxes. There is a lot going on behind
the scenes to make this possible--trust me! The 2 floppy icons, CDROM
icon, and snapshot icon all bring up appropriate dialog boxes to let
you choose a file.
- That's all. The other menu options are not implemented except for quit.
To do:
- sketch the GUI pieces that need to be made, with text description of
basically what they should do. See README.gui-sketch for latest ideas.
- have a few people look over the sketches so that we don't waste lots of
time building dialogs that people will hate.
- code some dialog boxes in wxwindows. Just get it looking right at first, and
Bryce can help you to get it connected to the simulator using the event
infrastructure that he has made. Again, after one or two is done there will
be some good examples to look at.
- implement ASK_PARAM gui event for all types of parameters. Currently only
string params are supported, meaning that when you call ask_param() on
a string parameter, the GUI gives the user a chance to edit that parameter's
value. We will need to implement boolean, enum, numerical parameters, and
lists. Lists should probably be displayed as a table or a dialog box
with several things to select.
- debugger interface. There's lots of demand for a debugger interface
to Bochs: possibly more demand than for a configuration interface. We
should talk about what this will look like, and when we have a plan we
can start sketching and coding dialogs for the debugger interface too.
- clean up the biggest memory leaks and init/cleanup code. The gui allows you
to kill the simulator and restart, but it doesn't do well after the first
time. Valgrind should help with memory leak debugging, though it doesn't run
multithreaded programes.
------------------------------------------------------
Random notes follow
Added some sketches in README.gui-sketch. I'm thinking that the control
panel will be able to basically show one of these screens at a time. When
you first start you would see ChooseConfigScreen which chooses between the
configurations that you have loaded recently (which it would remember
by the pathname of their bochsrc). Whether you choose an existing
configuration to be loaded or a new one, when you click Ok you go to
the first configuration screen, ConfigDiskScreen.
Each of the configuration screens takes up the whole control panel window.
We could use tabs on the top and/or "<-Prev" and "Next->" buttons to make
it quick to navigate the configuration screens. Each screen should
probably have a Prev, Next, Revert to Saved, and Accept button.
The menu choices like Disk..., VGA..., etc. just switch directly to
that tab.
------------------------------------------------------
Notes:
events from gui to sim:
- [async] key pressed or released
- [async] mouse motion with button state
- [sync] query parameter
- [sync] change parameter
- [async] start, pause, stop, reset simulation. Can be implemented
as changing a parameter.
- [async] request notification when some param changes
events from sim to gui:
- [async] log message to be displayed (or not)
- [async] ask user how to proceed (like panic: action=ask)
- [async] param value changed
- make my thread sleep for X microseconds (call wxThread::sleep then return)
In a synchronous event, the event object will contain space for the entire
response. The sender allocates memory for the event and builds it. The
receiver fills in blanks in the event structure (or could overwrite parts)
and returns the same event pointer as a response. For async events, probably
the sender will allocate and the receiver will have to delete it.
implement the floppyA and floppyB change buttons using new event
structure. How should it work?
vga gui detects a click on floppyA bitmap
construct a BxEvent type BX_EVT_ASK_PARAM
post the event to the wxwindows gui thread (somehow) and block for response
when it arrives in the gui thread, show a modal dialog box
get the answer back to the simulator thread
right now, this is working ok within the simulator thread using
wxMutexGuiEnter/Leave. Still I'm going to change it so that the
siminterface.cc code builds an event structure and the gui code
fills in the blank in the structure, instead of the stupid
notify_get_int_arg stuff.
Starting and Killing Threads
When a detachable (default) thread finishes (returns from its Entry()
function), wxwindows frees the memory associated with that thread.
Unless the thread is never going to end, it is potentially dangerous to have a
pointer to it at all. Even if you try to "check if it's alive" first, you may
be dereferencing the pointer after it has already been deleted, leading to it
claiming to be alive when it's not, or a segfault. To solve this, the approach
used in the wxwindows threads example is to have code in the thread's OnExit()
method remove the thread's pointer from the list of usable threads. In
addition, any references or changes to the list of threads is controlled by a
critical section to ensure that it stays correct. This post finally
explained what I was seeing.
+-----------------------
| From: Pieter van der Meulen (pgmvdm@yahoo.com)
| Subject: Re: Thread Sample program - bug
| Newsgroups: comp.soft-sys.wxwindows
| Date: 2001-06-28 17:51:35 PST
|
|
| At 06:24 PM 6/28/2001, you wrote:
| >Hi,
| >I have wxWindows 2.2.7 (wxMSW) installed.
| >
| >I just found in the thread.cpp sample code this section:
| >
| ><code>
| >void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event) )
| >{
| > size_t count = wxGetApp().m_threads.Count();
| > for ( size_t i = 0; i < count; i++ )
| > {
| >===> wxGetApp().m_threads[0]->Delete(); <=====
| > }
| >
| > Close(TRUE);
| >}
| ></code>
| >The indecated line should probably rather have a
| >m_threads[i] rather than m_threads[0] .
|
| No, it should not, although it is not immediately obvious. When Delete() is
| called, the thread will eventually delete itself, but not before it calls
| MyThread::Exit(), which will remove itself from m_threads[] using
| wxArray::Remove(this). wxArray::Remove (RemoveAt) will compact the array to
| remove the element, it is now size-1. After this wxThread::Delete() returns.
|
|
| >I have have a further question to this:
| >Does this mean that a detached thread created with new
| >HAS to be deleted manually ? Or is this only in case it might still
| >be running?
|
| Firstly, you must create every detached thread using new since it will
| delete itself, literally calling delete this.
| Calling wxThread::Delete() is a correct way to terminate a thread, but
| manually deleting (using delete) a detached wxThread object is not.
| wxThread::Delete() will ask the thread to exit, the thread should check for
| this in wxThread::Entry() regularly using wxThread::TestDestroy() and exit
| when asked to do so.
|
| >(In general I have a unsatisfied felling about when delete is
| >neccessary and when not -- "I only know, it's not , if the class is
| >derived from wxWindows")
|
| For wxThreads: joinable threads must be deleted (when allocated on the
| heap), detached threads may never be deleted. For other classes, consult
| the documentation ;)
|
|
| >Thanks for some feedback,
| >Sebastian
|
| Regards,
|
| Pieter.
+-----------------------
tracking some kind of deadlock bug in Linux.
seems to be in ReadMailcap, src/unix/mimetypes.cpp in wxwindows sources
src/unix/mimetype.cpp:2312
SOLUTION: compile with -pthread on every compile and link line.
---------------------------------------------------------------------------
Here are some quick ASCII sketches of what different parts of the interface
look like. Nothing is implemented yet, and everything is open for debate.
Whoever writes the wxwindows code for any of these screens gets several
thousand votes.
Menus:
- Configuration
+----------------------+
| New Configuration |
| Read Configuration |
| Save Configuration |
+----------------------+
| Quit |
+----------------------+
- Edit
+----------------------+
| Disks... |
| Boot -----------> Floppy, Hard disk, or Cdrom
| VGA... |
| Memory... |
| Sound... |
| Networking... |
| Keyboard... |
| Other... |
+----------------------+
- Simulate
+----------------------+
| Start |
| Pause/Resume |
| Stop |
+----------------------+
| Speed... |
+----------------------|
- Debug
+----------------------|
| Show CPU |
| Show Memory |
| ? what else ? |
+----------------------|
- Event Log
+----------------------+
| View |
| Preferences... |
| By Device... |
+----------------------+
- Help
+----------------------+
| About Bochs... |
+----------------------+
What should show up on the control panel when it first comes up?
I think the standard thing should be to choose a configuration and
start simulating.
ChooseConfigScreen:
+--------------------------------------------------------+
| |
| Choose a configuration for the Bochs simulator: |
| |
| +---+ |
| | O | DLX Linux Demo |
| | | | Boot 10MB Hard Disk |
| +---+ |
| |
| +---+ |
| | O | Redhat Linux Image |
| | | | Boot 10MB Hard Disk |
| +---+ |
| |
| +---+ |
| | O | FreeDOS |
| | | | Boot 40MB Hard Disk |
| +---+ |
| |
| |
| ?? Create new configuration |
| |
| |
| [ |
+--------------------------------------------------------+
ConfigDisksScreen:
+---------------------------------------------------------------+
| |
| /----+ |
| |= =| A Drive +----+ |
| [ ] | __ | Raw Floppy Drive |Edit| |
| || || A: +----+ |
| ++--++ |
| |
| /----+ |
| |= =| B Drive +----+ |
| [ ] | __ | Floppy Disk Image |Edit| |
| || || C:\Bochs\Images\A.img +----+ |
| ++--++ |
| |
| +-----+ C Drive |
| |=====| Hard Disk Image +----+ |
| [BOOT] | o| C:\Bochs\Images\HD30meg.img |Edit| |
| +-----+ +----+ |
| |
| ___ |
| / \ D Drive +----+ |
| [ ] | O | ISO CD Image |Edit| |
| \___/ C:\Bochs\Images\BootCD.img +----+ |
| |
| |
+---------------------------------------------------------------+
EditFloppyScreen:
+---------------------------------------------------------------+
| |
| Bochs can use a real floppy drive as Disk A, or use an |
| image file. |
| |
| [X] Physical A: drive |
| [ ] Physical B: drive |
| [ ] Disk image: [_____________________________] [Browse] |
| Capacity: [1.44 MB] |
| |
| Hint: To create a disk image, choose the name and capacity |
| above, then click Ok. |
| |
| [ Cancel ] [ Ok ] |
+---------------------------------------------------------------+
ConfigVgaScreen:
FIXME
ConfigMemoryScreen:
romimage: file=bios/BIOS-bochs-latest, address=0xf0000
megs: 32
vgaromimage: bios/VGABIOS-elpin-2.40
FIXME
ConfigSoundScreen:
sb16: midimode=1, midi=/dev/midi00, wavemode=1, wave=/dev/dsp, loglevel=2, log=sb16.log, dmatimer=600000
FIXME
ConfigNetworkingScreen:
+---------------------------------------------------------------+
| |
| Bochs can emulate an NE2000-compatible network card. Would |
| you like to enable it? |
| |
| Enable networking? [X] |
| |
| NE2000 I/O address: [ 0x280 ] |
| IRQ: [ 9 ] |
| MAC address: [ b0:c4:00:00:00:00 ] |
| Connection to the OS: [ Linux Packet Filter ] |
| Physical NIC to use: [ eth0 ] |
| NE2000 Debug messages: [ ] |
| |
+---------------------------------------------------------------+
ConfigKeyboardScreen:
keyboard_mapping: enabled=1, map=US,France,Germany,Spain
keyboard_type: xt,at,mf
keyboard_serial_delay: 250
FIXME
ConfigOtherScreen:
FIXME
ConfigSpeedScreen:
explain what the heck ips is
adjust ips with a slider?
FIXME
EventLogPreferences:
FIXME
panic: action=ignore,report,fatal,ask
error: action=ignore,report,fatal,ask
info: action=ignore,report,fatal,ask
debug: action=ignore,report,fatal,ask
EventLogPrefByDevice:
FIXME
keyboard panic=ask error=report info=report debug=ignore
vga panic=ask error=report info=report debug=ignore
network panic=ask error=report info=report debug=ignore
cpu panic=ask error=report info=report debug=ignore
sound panic=ask error=report info=report debug=ignore
etc. for about 20 devices.
DebugShowCpuRegisters:
show standard cpu registers and state
values will update in real time
this is sort of the start of the debugger interface
when debugging, maybe highlight values that change between sim steps
DebugShowMemory:
let use choose memory ranges to display
when debugging, maybe highlight values that change between sim steps
--------------------------------------------------------------------

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: bochs.h,v 1.61 2002-03-26 13:59:35 bdenney Exp $
// $Id: bochs.h,v 1.62 2002-04-18 00:22:18 bdenney Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -222,13 +222,6 @@ extern Bit8u DTPageDirty[];
#define MAGIC_LOGNUM 0x12345678
// Log Level defines
#define LOGLEV_DEBUG 0
#define LOGLEV_INFO 1
#define LOGLEV_ERROR 2
#define LOGLEV_PANIC 3
#define N_LOGLEV 4
typedef class logfunctions {
char *prefix;
int type;
@ -463,7 +456,7 @@ typedef struct {
#define BX_ASSERT(x) do {if (!(x)) BX_PANIC(("failed assertion \"%s\" at %s:%d\n", #x, __FILE__, __LINE__));} while (0)
void bx_signal_handler (int signum);
void bx_atexit(void);
int bx_atexit(void);
extern bx_debug_t bx_dbg;
@ -516,6 +509,8 @@ extern bx_devices_c bx_devices;
#define BX_RESET_SOFTWARE 10
#define BX_RESET_HARDWARE 11
void bx_init_before_control_panel ();
// This value controls how often each I/O device's periodic() method
// gets called. The timer is set up in iodev/devices.cc.
#define BX_IODEV_HANDLER_PERIOD 100 // microseconds

View File

@ -40,6 +40,15 @@
// USER CONFIGURABLE OPTIONS : EDIT ONLY OPTIONS IN THIS SECTION //
///////////////////////////////////////////////////////////////////
#if 1
// quit_sim is defined in gui/siminterface.h
#define BX_EXIT(x) SIM->quit_sim (x)
#else
// provide the real main and the usual exit.
#define BX_EXIT(x) ::exit(x)
#endif
#define BX_USE_CONTROL_PANEL 1
// I have tested the following combinations:
@ -340,6 +349,7 @@
#define BX_WITH_RFB 0
#define BX_WITH_AMIGAOS 0
#define BX_WITH_SDL 0
#define BX_WITH_WX 0
// Roland Mainz's idle hack is presently specific to X11. If people try to

6152
bochs/configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -69,6 +69,7 @@ if (test "$with_sdl" != yes) && \
(test "$with_rfb" != yes) && \
(test "$with_amigaos" != yes) && \
(test "$with_carbon" != yes) && \
(test "$with_wx" != yes) && \
(test "$with_macos" != yes); then
# use DEFAULT_GUI. Set the appropriate variable.
# DEFAULT_GUI must be set to one of the names above. Otherwise, no
@ -1029,6 +1030,10 @@ AC_ARG_WITH(sdl,
[ --with-sdl use SDL libraries],
)
AC_ARG_WITH(wx,
[ --with-wx use wxWindows libraries],
)
dnl // DASH is option prefix for your platform
dnl // SLASH is directory for your platform
dnl // CXXFP is C++ File Prefix; the flag that tells the compiler
@ -1068,34 +1073,34 @@ if test "$with_x11" = yes; then
exit 1
fi
AC_DEFINE(BX_WITH_X11, 1)
GUI_OBJS='$(GUI_OBJS_X11)'
GUI_OBJS='$(GUI_OBJS_X11) control.o'
GUI_LINK_OPTS='$(GUI_LINK_OPTS_X)'
INSTALL_LIST_FOR_PLATFORM='$(INSTALL_LIST_X11)'
elif test "$with_beos" = yes; then
AC_MSG_RESULT(beos)
AC_DEFINE(BX_WITH_BEOS, 1)
GUI_OBJS='$(GUI_OBJS_BEOS)'
GUI_OBJS='$(GUI_OBJS_BEOS) control.o'
GUI_LINK_OPTS='$(GUI_LINK_OPTS_BEOS)'
elif test "$with_sdl" = yes; then
AC_MSG_RESULT(sdl)
CFLAGS="$CFLAGS \`sdl-config --cflags\`"
AC_DEFINE(BX_WITH_SDL, 1)
GUI_OBJS='$(GUI_OBJS_SDL)'
GUI_OBJS='$(GUI_OBJS_SDL) control.o'
GUI_LINK_OPTS='$(GUI_LINK_OPTS_SDL)'
elif test "$with_rfb" = yes; then
AC_MSG_RESULT(rfb)
AC_DEFINE(BX_WITH_RFB, 1)
GUI_OBJS='$(GUI_OBJS_RFB)'
GUI_OBJS='$(GUI_OBJS_RFB) control.o'
GUI_LINK_OPTS='$(GUI_LINK_OPTS_RFB)'
elif test "$with_amigaos" = yes; then
AC_MSG_RESULT(amigaos)
AC_DEFINE(BX_WITH_AMIGAOS, 1)
GUI_OBJS='$(GUI_OBJS_AMIGAOS)'
GUI_OBJS='$(GUI_OBJS_AMIGAOS) control.o'
GUI_LINK_OPTS='$(GUI_LINK_OPTS_AMIGAOS)'
elif test "$with_win32" = yes; then
AC_MSG_RESULT(win32)
AC_DEFINE(BX_WITH_WIN32, 1)
GUI_OBJS='$(GUI_OBJS_WIN32)'
GUI_OBJS='$(GUI_OBJS_WIN32) control.o'
case $target in
*-pc-windows*)
GUI_LINK_OPTS='$(GUI_LINK_OPTS_WIN32_VCPP)' # native libs for win gui
@ -1109,24 +1114,39 @@ elif test "$with_win32" = yes; then
elif test "$with_macos" = yes; then
AC_MSG_RESULT(macos)
AC_DEFINE(BX_WITH_MACOS, 1)
GUI_OBJS='$(GUI_OBJS_MACOS)'
GUI_OBJS='$(GUI_OBJS_MACOS) control.o'
GUI_LINK_OPTS='$(GUI_LINK_OPTS_MACOS)'
elif test "$with_carbon" = yes; then
AC_MSG_RESULT(carbon)
AC_DEFINE(BX_WITH_CARBON, 1)
GUI_OBJS='$(GUI_OBJS_CARBON)'
GUI_OBJS='$(GUI_OBJS_CARBON) control.o'
GUI_LINK_OPTS='$(GUI_LINK_OPTS_CARBON)'
PRIMARY_TARGET=bochs.app/.build # only for carbon application
elif test "$with_term" = yes; then
AC_MSG_RESULT(term)
AC_DEFINE(BX_WITH_TERM, 1)
GUI_OBJS='$(GUI_OBJS_TERM)'
GUI_OBJS='$(GUI_OBJS_TERM) control.o'
GUI_LINK_OPTS='$(GUI_LINK_OPTS_TERM)'
use_curses=yes
elif test "$with_wx" = yes; then
AC_MSG_RESULT(wxWindows)
AC_DEFINE(BX_WITH_WX, 1)
CFLAGS="$CFLAGS `wx-config --cflags`"
CXXFLAGS="$CFLAGS `wx-config --cxxflags`"
# if gtk-config exists, then add it to the cflags.
gtkconf=`gtk-config --cflags`
if test $? = 0; then
# gtk-config was found and returned 0, so it must return valid output
CFLAGS="$CFLAGS `gtk-config --cflags`"
CXXFLAGS="$CXXFLAGS `gtk-config --cflags`"
fi
# wxwindows is the only one without control.o in GUI_OBJS
GUI_OBJS='$(GUI_OBJS_WX)'
GUI_LINK_OPTS='$(GUI_LINK_OPTS_WX)'
else
AC_MSG_RESULT(none)
AC_DEFINE(BX_WITH_NOGUI, 1)
GUI_OBJS='$(GUI_OBJS_NOGUI)'
GUI_OBJS='$(GUI_OBJS_NOGUI) control.o'
GUI_LINK_OPTS='$(GUI_LINK_OPTS_NOGUI)'
fi
@ -1184,32 +1204,232 @@ if test "$use_curses" = yes; then
fi
fi
# The ACX_PTHREAD function was written by
# Steven G. Johnson <stevenj@alum.mit.edu> and
# Alejandro Forero Cuervo <bachue@bachue.com>
# I found it in the ac-archive project on Source Forge.
AC_DEFUN([ACX_PTHREAD], [
AC_REQUIRE([AC_CANONICAL_HOST])
acx_pthread_ok=no
# First, check if the POSIX threads header, pthread.h, is available.
# If it isn't, don't bother looking for the threads libraries.
AC_CHECK_HEADER(pthread.h, , acx_pthread_ok=noheader)
# We must check for the threads library under a number of different
# names; the ordering is very important because some systems
# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
# libraries is broken (non-POSIX).
# First of all, check if the user has set any of the PTHREAD_LIBS,
# etcetera environment variables, and if threads linking works using
# them:
if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
save_LIBS="$LIBS"
LIBS="$PTHREAD_LIBS $LIBS"
AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes)
AC_MSG_RESULT($acx_pthread_ok)
if test x"$acx_pthread_ok" = xno; then
PTHREAD_LIBS=""
PTHREAD_CFLAGS=""
fi
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
fi
# Create a list of thread flags to try. Items starting with a "-" are
# C compiler flags, and other items are library names, except for "none"
# which indicates that we try without any flags at all.
acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt"
# The ordering *is* (sometimes) important. Some notes on the
# individual items follow:
# pthreads: AIX (must check this before -lpthread)
# none: in case threads are in libc; should be tried before -Kthread and
# other compiler flags to prevent continual compiler warnings
# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
# -pthreads: Solaris/gcc
# -mthreads: Mingw32/gcc, Lynx/gcc
# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
# doesn't hurt to check since this sometimes defines pthreads too;
# also defines -D_REENTRANT)
# pthread: Linux, etcetera
# --thread-safe: KAI C++
case "${host_cpu}-${host_os}" in
*solaris*)
# On Solaris (at least, for some versions), libc contains stubbed
# (non-functional) versions of the pthreads routines, so link-based
# tests will erroneously succeed. (We need to link with -pthread or
# -lpthread.) (The stubs are missing pthread_cleanup_push, or rather
# a function called by this macro, so we could check for that, but
# who knows whether they'll stub that too in a future libc.) So,
# we'll just look for -pthreads and -lpthread first:
acx_pthread_flags="-pthread -pthreads pthread -mt $acx_pthread_flags"
;;
esac
if test x"$acx_pthread_ok" = xno; then
for flag in $acx_pthread_flags; do
case $flag in
none)
AC_MSG_CHECKING([whether pthreads work without any flags])
;;
-*)
AC_MSG_CHECKING([whether pthreads work with $flag])
PTHREAD_CFLAGS="$flag"
;;
*)
AC_MSG_CHECKING([for the pthreads library -l$flag])
PTHREAD_LIBS="-l$flag"
;;
esac
save_LIBS="$LIBS"
save_CFLAGS="$CFLAGS"
LIBS="$PTHREAD_LIBS $LIBS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
# Check for various functions. We must include pthread.h,
# since some functions may be macros. (On the Sequent, we
# need a special flag -Kthread to make this header compile.)
# We check for pthread_join because it is in -lpthread on IRIX
# while pthread_create is in libc. We check for pthread_attr_init
# due to DEC craziness with -lpthreads. We check for
# pthread_cleanup_push because it is one of the few pthread
# functions on Solaris that doesn't have a non-functional libc stub.
# We try pthread_create on general principles.
AC_TRY_LINK([#include <pthread.h>],
[pthread_t th; pthread_join(th, 0);
pthread_attr_init(0); pthread_cleanup_push(0, 0);
pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
[acx_pthread_ok=yes])
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
AC_MSG_RESULT($acx_pthread_ok)
if test "x$acx_pthread_ok" = xyes; then
break;
fi
PTHREAD_LIBS=""
PTHREAD_CFLAGS=""
done
fi
# Various other checks:
if test "x$acx_pthread_ok" = xyes; then
save_LIBS="$LIBS"
LIBS="$PTHREAD_LIBS $LIBS"
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
# Detect AIX lossage: threads are created detached by default
# and the JOINABLE attribute has a nonstandard name (UNDETACHED).
AC_MSG_CHECKING([for joinable pthread attribute])
AC_TRY_LINK([#include <pthread.h>],
[int attr=PTHREAD_CREATE_JOINABLE;],
ok=PTHREAD_CREATE_JOINABLE, ok=unknown)
if test x"$ok" = xunknown; then
AC_TRY_LINK([#include <pthread.h>],
[int attr=PTHREAD_CREATE_UNDETACHED;],
ok=PTHREAD_CREATE_UNDETACHED, ok=unknown)
fi
if test x"$ok" != xPTHREAD_CREATE_JOINABLE; then
AC_DEFINE(PTHREAD_CREATE_JOINABLE, $ok,
[Define to the necessary symbol if this constant
uses a non-standard name on your system.])
fi
AC_MSG_RESULT(${ok})
if test x"$ok" = xunknown; then
AC_MSG_WARN([we do not know how to create joinable pthreads])
fi
AC_MSG_CHECKING([if more special flags are required for pthreads])
flag=no
case "${host_cpu}-${host_os}" in
*-aix* | *-freebsd*) flag="-D_THREAD_SAFE";;
*solaris* | alpha*-osf*) flag="-D_REENTRANT";;
esac
AC_MSG_RESULT(${flag})
if test "x$flag" != xno; then
PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
fi
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
# More AIX lossage: must compile with cc_r
AC_CHECK_PROG(PTHREAD_CC, cc_r, cc_r, ${CC})
else
PTHREAD_CC="$CC"
fi
AC_SUBST(PTHREAD_LIBS)
AC_SUBST(PTHREAD_CFLAGS)
AC_SUBST(PTHREAD_CC)
# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
if test x"$acx_pthread_ok" = xyes; then
ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1])
:
else
acx_pthread_ok=no
$2
fi
])dnl ACX_PTHREAD
pthread_ok=no
ACX_PTHREAD([
pthread_ok=yes
#echo Using PTHREAD_LIBS=$PTHREAD_LIBS
#echo Using PTHREAD_CFLAGS=$PTHREAD_CFLAGS
#echo Using PTHREAD_CC=$PTHREAD_CC
])
if test "$with_rfb" = yes; then
# first see if compiler takes "-pthread" argument
AC_MSG_CHECKING(for -pthread arg to compiler)
CFLAGS_SAVE="$CFLAGS"
CFLAGS="$CFLAGS -pthread"
AC_TRY_LINK([ #include <pthread.h> ],
[ pthread_create(0,0,0,0); ],
[
# it compiles with -pthread
AC_MSG_RESULT(yes)
CXXFLAGS="$CXXFLAGS -pthread"
],
[
AC_MSG_RESULT(no)
# now try with -lpthread
CFLAGS="$CFLAGS_SAVE"
AC_CHECK_LIB(pthread,
pthread_create,
[
# it compiles with -lpthread
RFB_LIBS='-lpthread'
],
[
echo ERROR: --with-rfb requires the pthread library, which could not be found.; exit 1
])
])
if test "$pthread_ok" = yes; then
RFB_LIBS="$PTHREAD_LIBS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
CC="$PTHREAD_CC"
else
echo ERROR: --with-rfb requires the pthread library, which could not be found.; exit 1
fi
fi
if test "$with_wx" = yes; then
if test "$pthread_ok" = yes; then
GUI_LINK_OPTS="$PTHREAD_LIBS $GUI_LINK_OPTS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS"
CC="$PTHREAD_CC"
else
case "$target" in
*-pc-windows* | *-pc-winnt*)
# pthread not needed for win32
;;
*)
echo ERROR: --with-wx requires the pthread library, which could not be found.; exit 1
esac
fi
fi
# Create some subdirectories for when you run configure from some other

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: cpu.cc,v 1.27 2002-04-01 13:14:37 instinc Exp $
// $Id: cpu.cc,v 1.28 2002-04-18 00:22:19 bdenney Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -469,6 +469,9 @@ handle_async_event:
return;
}
#endif
} else if (BX_CPU_THIS_PTR kill_bochs_request) {
// setting kill_bochs_request causes the cpu loop to return ASAP.
return;
}

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: cpu.h,v 1.18 2002-04-01 04:42:43 instinc Exp $
// $Id: cpu.h,v 1.19 2002-04-18 00:22:19 bdenney Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -819,6 +819,7 @@ public: // for now...
Bit32u debug_trap; // holds DR6 value to be set as well
volatile Boolean async_event;
volatile Boolean INTR;
volatile Boolean kill_bochs_request;
/* wether this CPU is the BSP always set for UP */
Boolean bsp;

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: dbg_main.cc,v 1.42 2002-04-01 04:44:15 instinc Exp $
// $Id: dbg_main.cc,v 1.43 2002-04-18 00:22:19 bdenney Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -285,7 +285,7 @@ bx_dbg_main(int argc, char *argv[])
BX_ERROR(( "%s: -rc option used, but no path specified.",
argv[0] ));
bx_dbg_usage();
exit(1);
BX_EXIT(1);
}
strncpy(bx_debug_rc_fname, argv[2], BX_MAX_PATH-1);
i += 2; // skip past "-rc" and filename

View File

@ -33,7 +33,7 @@ SHELL = /bin/sh
@SET_MAKE@
CXX = @CXX@
CXXFLAGS = @CXXFLAGS@
CXXFLAGS = @CXXFLAGS@ `wx-config --cxxflags`
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
@ -53,7 +53,9 @@ GUI_OBJS_NOGUI = nogui.o
GUI_OBJS_TERM = term.o
GUI_OBJS_RFB = rfb.o
GUI_OBJS_AMIGAOS = amigaos.o
GUI_OBJS = keymap.o gui.o control.o siminterface.o @GUI_OBJS@
GUI_OBJS_WX = wx.o wxmain.o
GUI_OBJS = keymap.o gui.o siminterface.o @GUI_OBJS@
BX_INCDIRS = -I.. -I$(srcdir)/.. -I../iodev -I$(srcdir)/../iodev -I../@INSTRUMENT_DIR@ -I$(srcdir)/../@INSTRUMENT_DIR@
LOCAL_CXXFLAGS =
@ -224,3 +226,5 @@ x.o: x.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h ../debug/debug.h \
../iodev/unmapped.h ../iodev/eth.h ../iodev/ne2k.h \
../iodev/guest2host.h ../iodev/slowdown_timer.h \
../instrument/stubs/instrument.h icon_bochs.h
wx.o: wxmain.h
wxmain.o: wxmain.h

View File

@ -0,0 +1,41 @@
/* XPM */
static char *cdromd_xpm[] = {
/* width height num_colors chars_per_pixel */
" 32 32 2 1",
/* colors */
". c #ffffff",
"# c #000000",
/* pixels */
"................................",
".............##..###............",
"............#....#..#...........",
"............#....#..#...........",
"............#....#..#...........",
".............##..###............",
"................................",
"............########............",
"..........##........##..........",
".........#...######...#.........",
"........#..##......##..#........",
".......#.##..######..##.#.......",
"......#.#..##......##..#.#......",
".....#..#.#..######..#.#..#.....",
".....#.#.#..#......#..#.#.#.....",
"....#..#.#.#..####..#.#.#..#....",
"....#.#.#.#..#....#..#.#.#.#....",
"....#.#.#.#.#......#.#.#.#.#....",
"....#.#.#.#.#......#.#.#.#.#....",
"....#.#.#.#.#......#.#.#.#.#....",
"....#.#.#.#.#......#.#.#.#.#....",
"....#.#.#.#..#....#..#.#.#.#....",
"....#..#.#.#..####..#.#.#..#....",
".....#.#.#..#......#..#.#.#.....",
".....#..#.#..######..#.#..#.....",
"......#.#..##......##..#.#......",
".......#.##..######..##.#.......",
"........#..##......##..#........",
".........#...######...#.........",
"..........##........##..........",
"............########............",
"................................"
};

View File

@ -0,0 +1,41 @@
/* XPM */
static char *configbutton_xpm[] = {
/* width height num_colors chars_per_pixel */
" 32 32 2 1",
/* colors */
". c #ffffff",
"# c #000000",
/* pixels */
"................................",
"..#....................##.......",
"..#############.......####......",
"..###############.....####......",
"..###############.....####......",
"..#############.......####......",
"..#....####...........####......",
".......####...........####......",
".......####...........####......",
".......####...........####......",
".......####...........####......",
".......####...........####......",
".......####...........####......",
".......####...........####......",
".......####...........####......",
".......####...........####......",
".......####...........####......",
".......####...........####......",
".......####...........####......",
".......####..........######.....",
".......####.........########....",
".......####.........###..###....",
".......####.........##....##....",
".......####.........##....##....",
".......####..........#....#.....",
"................................",
"...###..###..#...#.###.#..###...",
"..#....#...#.##..#.#...#.#......",
"..#....#...#.#.#.#.###.#.#..##..",
"..#....#...#.#..##.#...#.#...#..",
"...###..###..#...#.#...#..###...",
"................................"
};

View File

@ -0,0 +1,41 @@
/* XPM */
static char *copy_xpm[] = {
/* width height num_colors chars_per_pixel */
" 32 32 2 1",
/* colors */
". c #ffffff",
"# c #000000",
/* pixels */
"................................",
"........####....................",
".......#........................",
".......#.....##..###..#..#......",
".......#....#..#.#..#.#..#......",
".......#....#..#.#..#.#..#......",
"........####.##..###...###......",
".................#.......#......",
"...###########...#.......#......",
"...#.........#........###.......",
"...#.#####.#.#..................",
"...#.........#..................",
"...#.###.###.#..................",
"...#.........#..................",
"...#.####..###..................",
"...#......#..#..................",
"...#...#.....#..................",
"...#.#######.#.###########......",
"...#.........#.#.........#......",
"...###########.#.#####.#.#......",
"...............#.........#......",
".......#...#...#.###.###.#......",
".......#....#..#.........#......",
"........######.#.####..###......",
"............#..#......#..#......",
"...........#...#...#.....#......",
"...............#.#######.#......",
"...............#.........#......",
"...............###########......",
"................................",
"................................",
"................................"
};

View File

@ -0,0 +1,41 @@
/* XPM */
static char *floppya_xpm[] = {
/* width height num_colors chars_per_pixel */
" 32 32 2 1",
/* colors */
". c #ffffff",
"# c #000000",
/* pixels */
"...............#................",
"..............#.#...............",
"..............#.#...#...........",
"..............###...............",
".............##.##..#...........",
".............##.##..............",
"................................",
".....######################.....",
".....####..............####.....",
".....#..#.############.#..#.....",
".....#..#..............#..#.....",
".....####.############.####.....",
".....####..............####.....",
".....####.############.####.....",
".....####..............####.....",
".....####.############.####.....",
".....####..............####.....",
".....####.############.####.....",
".....####..............####.....",
".....####.############.####.....",
".....####..............####.....",
".....######################.....",
".....######################.....",
".....######################.....",
".....######################.....",
".....#######.#.#.#.#.######.....",
".....######.#####.#.#.#####.....",
".....#######.###.#.#.######.....",
".....######.#####.#.#.#####.....",
"......######.###.#.#.######.....",
".......####.#.#.#.#.#.#####.....",
"........####.#.#.#.#.######....."
};

View File

@ -0,0 +1,41 @@
/* XPM */
static char *floppyb_xpm[] = {
/* width height num_colors chars_per_pixel */
" 32 32 2 1",
/* colors */
". c #ffffff",
"# c #000000",
/* pixels */
".............###................",
".............#..#...............",
".............###...#............",
".............#..#...............",
".............#..#..#............",
".............###................",
"................................",
".....######################.....",
".....####..............####.....",
".....#..#.############.#..#.....",
".....#..#..............#..#.....",
".....####.############.####.....",
".....####..............####.....",
".....####.############.####.....",
".....####..............####.....",
".....####.############.####.....",
".....####..............####.....",
".....####.############.####.....",
".....####..............####.....",
".....####.############.####.....",
".....####..............####.....",
".....######################.....",
".....######################.....",
".....######################.....",
".....######################.....",
".....#######.#.#.#.#.######.....",
".....######.#####.#.#.#####.....",
".....#######.###.#.#.######.....",
".....######.#####.#.#.#####.....",
"......######.###.#.#.######.....",
".......####.#.#.#.#.#.#####.....",
"........####.#.#.#.#.######....."
};

View File

@ -0,0 +1,41 @@
/* XPM */
static char *mouse_xpm[] = {
/* width height num_colors chars_per_pixel */
" 32 32 2 1",
/* colors */
". c #ffffff",
"# c #000000",
/* pixels */
"................................",
".............######.............",
"...........##########...........",
"..........##........##..........",
".........##..........##.........",
".........##...........#.........",
"...#############......##........",
"..##...........##.....##........",
"..#..#...#...#..#.....##........",
"..#.###.###.###.#......#........",
"..#.###.###.###.#......##.......",
"..#.###.###.###.#......##.......",
"..#.###.###.###.#.......#.......",
"..#.###.###.###.#.......##......",
"..#.###.###.###.#........##.....",
"..#..#...#...#..#.........##....",
"..##...........##..........###..",
"..#.............#...............",
"..##...........##...............",
"..#.............#...............",
"..##...........##...............",
"..#.............#...............",
"..##...........##...............",
"..#.............#...............",
"..##...........##...............",
"..#.#.........#.#...............",
"..##.#.......#.##...............",
"..#.#.#.#.#.#.#.#...............",
"..##.#.#.#.#.#.##...............",
"...#############................",
"................................",
"................................"
};

View File

@ -0,0 +1,41 @@
/* XPM */
static char *paste_xpm[] = {
/* width height num_colors chars_per_pixel */
" 32 32 2 1",
/* colors */
". c #ffffff",
"# c #000000",
/* pixels */
"................................",
".....####...........#...........",
".....#...#.##..###..#..###......",
".....#...##..##....####...#.....",
".....####.#..#.###..#.#####.....",
".....#....#..#....#.#.#.........",
".....#.....##.####..#..###......",
"...............##...............",
"..............##.#..............",
"..........#####.######..........",
"......####.....##.....####......",
".....#...#............#...#.....",
".....#..#..............#..#.....",
".....#..#..............#..#.....",
".....#.##################.#.....",
".....#....................#.....",
".....#....................#.....",
".....#.....###########....#.....",
".....#.....#.........#....#.....",
".....#.....#.#####.#.#....#.....",
".....#.....#.........#....#.....",
".....#.....#.###.###.#....#.....",
".....#.....#.........#....#.....",
".....#.....#.####..###....#.....",
".....#.....#......#..#....#.....",
".....#.....#...#.....#....#.....",
".....#.....#.#######.#....#.....",
".....#.....#.........#....#.....",
".....#.....###########....#.....",
".....#....................#.....",
"......####################......",
"................................"
};

View File

@ -0,0 +1,41 @@
/* XPM */
static char *power_xpm[] = {
/* width height num_colors chars_per_pixel */
" 32 32 2 1",
/* colors */
". c #ffffff",
"# c #000000",
/* pixels */
"................................",
"................................",
".####...........................",
"..#..#..###..##..##..##...#.##..",
"..#..#.#...#.#...#..#..#...#..#.",
".#.##..#...#.#.#.#.#####..#.....",
".#.....#..#..##.#..#......#.....",
"###.....##...#.#....###..###....",
"................................",
"...........#######..............",
".........###########............",
"........####.....####...........",
".......###.........###..........",
"......##.............##.........",
".....###.....###.....###........",
".....##......###......##........",
"....###......###......###.......",
"....##.......###.......##.......",
"....##.......###.......##.......",
"....##.......###.......##.......",
"....##.......###.......##.......",
"....##.......###.......##.......",
"....###......###......###.......",
".....##......###......##........",
".....###.....###.....###........",
"......##.............##.........",
".......###.........###..........",
"........####.....####...........",
".........###########............",
"...........#######..............",
"................................",
"................................"
};

View File

@ -0,0 +1,41 @@
/* XPM */
static char *reset_xpm[] = {
/* width height num_colors chars_per_pixel */
" 32 32 2 1",
/* colors */
". c #ffffff",
"# c #000000",
/* pixels */
"................................",
".............................#..",
"..####......................#...",
"...#..#...##....###...##..#####.",
"...#..#..#..#..#.....#..#...#...",
"..#.##..#####...##..#####..#....",
"..#..#..#.....#..#..#......#..#.",
".###.##..###..###....###....##..",
"................................",
"................................",
"................................",
"................................",
"................................",
"...............#................",
"..............##................",
".............#######............",
"............#########...........",
".............#########..........",
"........###...##...###..........",
"........###....#...###..........",
"........###........###..........",
"........###........###..........",
"........###........###..........",
"........###........###..........",
"........###........###..........",
"........##############..........",
".........############...........",
"..........##########............",
"................................",
"................................",
"................................",
"................................"
};

View File

@ -0,0 +1,41 @@
/* XPM */
static char *snapshot_xpm[] = {
/* width height num_colors chars_per_pixel */
" 32 32 2 1",
/* colors */
". c #ffffff",
"# c #000000",
/* pixels */
".....................#........#.",
"###.###..##..###.###.###..##.###",
"#...#..#...#.#.#.#...#.#.#..#.#.",
".##.#..#..##.#.#..##.#.#.#..#.#.",
"..#.#..#.#.#.#.#...#.#.#.#..#.#.",
"###.##.#.###.###.###.#.#..##..##",
".............#..................",
"............########............",
"...........#........#...........",
"..#####.####........#...#####...",
".#.########..........#.#.###.#..",
".#....#.###..........#.#....#.#.",
"##...#.###............##.....###",
"########.###.######.###.######.#",
"#.......#..##########..#......#.",
"#.......#.###......###.#.....#.#",
"#########.#..######..#.#########",
"########.#.###.#.#.##.#.########",
"#########.#.#.#.#.#.##.#########",
"#########.##...#.#.#.#.#########",
"########.##.#...#.#.#.#.########",
"########.#...#.#.#.#.##.########",
"########.##...#.#.#.#.#.########",
"########.#.#.#.#.#.#.##.########",
"########.##.#.#.#.#.#.#.########",
".#######.###.#.#.#.#.##.#######.",
"........#.#.#.#.#.#.##.#........",
"........#.####.#.#.###.#........",
".........#.##########.#.........",
"..........#..######..#..........",
"...........##......##...........",
".............######............."
};

View File

@ -1,10 +1,10 @@
/////////////////////////////////////////////////////////////////////////
// $Id: control.cc,v 1.46 2002-04-08 00:11:52 bdenney Exp $
// $Id: control.cc,v 1.47 2002-04-18 00:22:19 bdenney Exp $
/////////////////////////////////////////////////////////////////////////
//
/*
* gui/control.cc
* $Id: control.cc,v 1.46 2002-04-08 00:11:52 bdenney Exp $
* $Id: control.cc,v 1.47 2002-04-18 00:22:19 bdenney Exp $
*
* This is code for a text-mode control panel. Note that this file
* does NOT include bochs.h. Instead, it does all of its contact with
@ -614,24 +614,32 @@ int bx_write_rc (char *rc)
char *log_action_ask_choices[] = { "cont", "alwayscont", "die", "abort", "debug" };
int log_action_n_choices = 4 + (BX_DEBUGGER?1:0);
int control_panel_notify_callback (int code)
BxEvent *
control_panel_notify_callback (void *unused, BxEvent *event)
{
switch (code)
event->retcode = -1;
switch (event->type)
{
case NOTIFY_CODE_LOGMSG:
case BX_SYNC_EVT_TICK:
event->retcode = 0;
return event;
case BX_SYNC_EVT_ASK_PARAM:
fprintf (stderr, "BX_SYNC_EVT_ASK_PARAM\n");
return event;
case BX_ASYNC_EVT_SHUTDOWN_GUI:
fprintf (stderr, "BX_ASYNC_EVT_SHUTDOWN_GUI\n");
return event;
case BX_ASYNC_EVT_LOG_MSG:
{
int level;
char prefix[512], msg[512];
int retval = SIM->log_msg_2 (prefix, &level, msg, sizeof(msg)) >= 0;
assert (retval);
int level = event->u.logmsg.level;
fprintf (stderr, "========================================================================\n");
fprintf (stderr, "Event type: %s\n", SIM->get_log_level_name (level));
fprintf (stderr, "Device: %s\n", prefix);
fprintf (stderr, "Message: %s\n\n", msg);
fprintf (stderr, "Device: %s\n", event->u.logmsg.prefix);
fprintf (stderr, "Message: %s\n\n", event->u.logmsg.msg);
fprintf (stderr, "A %s has occurred. Do you want to:\n", SIM->get_log_level_name (level));
fprintf (stderr, " cont - continue execution\n");
fprintf (stderr, " alwayscont - continue execution, and don't ask again.\n");
fprintf (stderr, " This affects only %s events from device %s\n", SIM->get_log_level_name (level), prefix);
fprintf (stderr, " This affects only %s events from device %s\n", SIM->get_log_level_name (level), event->u.logmsg.prefix);
fprintf (stderr, " die - stop execution now\n");
fprintf (stderr, " abort - dump core %s\n",
BX_HAVE_ABORT ? "" : "(Disabled)");
@ -642,24 +650,24 @@ int control_panel_notify_callback (int code)
ask:
if (ask_menu ("Choose one of the actions above: [%s] ",
log_action_n_choices, log_action_ask_choices, 2, &choice) < 0)
return SIM->notify_return(-1);
event->retcode = -1;
// return 0 for continue, 1 for alwayscontinue, 2 for die, 3 for debug.
if (!BX_HAVE_ABORT && choice==3) goto ask;
fflush(stdout);
fflush(stderr);
SIM->notify_return(choice);
event->retcode = choice;
}
break;
return event;
default:
fprintf (stderr, "Control panel: notify callback called with unknown code %04x\n", code);
fprintf (stderr, "Control panel: notify callback called with event type %04x\n", event->type);
return event;
}
// error if we fall through the case
return -1;
assert (0); // switch statement should return
}
void bx_control_panel_init () {
//fprintf (stderr, "bx_control_panel_init()\n");
SIM->set_notify_callback (control_panel_notify_callback);
SIM->set_notify_callback (control_panel_notify_callback, NULL);
}
/////////////////////////////////////////////////////////////////////

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: gui.cc,v 1.40 2002-03-30 06:45:30 vruppert Exp $
// $Id: gui.cc,v 1.41 2002-04-18 00:22:19 bdenney Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002 MandrakeSoft S.A.
@ -192,24 +192,66 @@ bx_gui_c::update_drive_status_buttons (void) {
void
bx_gui_c::floppyA_handler(void)
{
#if BX_WITH_WX
// instead of just toggling the status, call wxWindows to bring up
// a dialog asking what disk image you want to switch to.
int ret = SIM->ask_param (BXP_FLOPPYA_PATH);
// eject and then insert the disk. If the new path is invalid,
// the status will return 0.
unsigned new_status = bx_devices.floppy->set_media_status(0, 0);
printf ("eject disk, new_status is %d\n", new_status);
new_status = bx_devices.floppy->set_media_status(0, 1);
printf ("insert disk, new_status is %d\n", new_status);
fflush (stdout);
BX_GUI_THIS floppyA_status = new_status;
#else
BX_GUI_THIS floppyA_status = !BX_GUI_THIS floppyA_status;
bx_devices.floppy->set_media_status(0, BX_GUI_THIS floppyA_status);
#endif
BX_GUI_THIS update_drive_status_buttons ();
}
void
bx_gui_c::floppyB_handler(void)
{
#if BX_WITH_WX
// instead of just toggling the status, call wxWindows to bring up
// a dialog asking what disk image you want to switch to.
int ret = SIM->ask_param (BXP_FLOPPYB_PATH);
// eject and then insert the disk. If the new path is invalid,
// the status will return 0.
unsigned new_status = bx_devices.floppy->set_media_status(1, 0);
printf ("eject disk, new_status is %d\n", new_status);
new_status = bx_devices.floppy->set_media_status(1, 1);
printf ("insert disk, new_status is %d\n", new_status);
fflush (stdout);
BX_GUI_THIS floppyB_status = new_status;
#else
BX_GUI_THIS floppyB_status = !BX_GUI_THIS floppyB_status;
bx_devices.floppy->set_media_status(1, BX_GUI_THIS floppyB_status);
#endif
BX_GUI_THIS update_drive_status_buttons ();
}
void
bx_gui_c::cdromD_handler(void)
{
#if BX_WITH_WX
// instead of just toggling the status, call wxWindows to bring up
// a dialog asking what disk image you want to switch to.
int ret = SIM->ask_param (BXP_CDROM_PATH);
// eject and then insert the disk. If the new path is invalid,
// the status will return 0.
unsigned status = bx_devices.hard_drive->set_cd_media_status(0);
printf ("eject disk, new_status is %d\n", status);
status = bx_devices.hard_drive->set_cd_media_status(1);
printf ("insert disk, new_status is %d\n", status);
fflush (stdout);
BX_GUI_THIS cdromD_status = status;
#else
BX_GUI_THIS cdromD_status =
bx_devices.hard_drive->set_cd_media_status(!BX_GUI_THIS cdromD_status);
#endif
BX_GUI_THIS update_drive_status_buttons ();
}
@ -231,7 +273,7 @@ bx_gui_c::power_handler(void)
BX_PANIC (("POWER button turned off."));
// shouldn't reach this point, but if you do, QUIT!!!
fprintf (stderr, "Bochs is exiting because you pressed the power button.\n");
::exit (1);
BX_EXIT (1);
}
Bit32s
@ -290,24 +332,24 @@ bx_gui_c::snapshot_handler(void)
{
char *text_snapshot;
Bit32u len;
char filename[BX_PATHNAME_LEN];
int flag;
if (make_text_snapshot (&text_snapshot, &len) < 0) {
BX_ERROR(( "snapshot button failed, mode not implemented"));
return;
}
// I wish I had a dialog box!!!
flag = 0; // 0 = no dialog present / 1 = OK / -1 = Cancel
if (!flag) { // use standard filename if dialog is not present
strcpy(filename, "snapshot.txt");
flag = 1;
}
if (flag == 1) {
FILE *fp = fopen(filename, "wb");
fwrite(text_snapshot, 1, strlen(text_snapshot), fp);
fclose(fp);
BX_INFO (("copied text snapshot to %s", filename));
}
//FIXME
char filename[BX_PATHNAME_LEN];
#if BX_WITH_WX
int ret = SIM->ask_filename (filename, sizeof(filename),
"Save snapshot as...", "snapshot.txt",
bx_param_string_c::BX_SAVE_FILE_DIALOG);
if (ret < 0) return; // cancelled
#else
strcpy (filename, "snapshot.txt");
#endif
FILE *fp = fopen(filename, "w");
fwrite(text_snapshot, 1, strlen(text_snapshot), fp);
fclose(fp);
free(text_snapshot);
}
@ -334,7 +376,7 @@ bx_gui_c::paste_handler(void)
void
bx_gui_c::config_handler(void)
{
#if BX_USE_CONTROL_PANEL
#if BX_USE_CONTROL_PANEL && !BX_WITH_WX
bx_control_panel (BX_CPANEL_RUNTIME);
#else
BX_ERROR(( "# CONFIG callback (unimplemented)." ));

View File

@ -1,14 +1,14 @@
/////////////////////////////////////////////////////////////////////////
// $Id: siminterface.cc,v 1.39 2002-01-30 10:30:52 cbothamy Exp $
// $Id: siminterface.cc,v 1.40 2002-04-18 00:22:19 bdenney Exp $
/////////////////////////////////////////////////////////////////////////
//
/*
* gui/siminterface.cc
* $Id: siminterface.cc,v 1.39 2002-01-30 10:30:52 cbothamy Exp $
* $Id: siminterface.cc,v 1.40 2002-04-18 00:22:19 bdenney Exp $
*
* Defines the actual link between bx_simulator_interface_c methods
* and the simulator. This file includes bochs.h because it needs
* access to bx_options and other simulator objecst and methods.
* access to bx_options and other simulator objects and methods.
*
*/
@ -18,10 +18,23 @@ bx_simulator_interface_c *SIM = NULL;
logfunctions *siminterface_log = NULL;
#define LOG_THIS siminterface_log->
// bx_simulator_interface just defines the interface that the Bochs simulator
// and the gui will use to talk to each other. None of the methods of
// bx_simulator_interface are implemented; they are all virtual. The
// bx_real_sim_c class is a child of bx_simulator_interface_c, and it
// implements all the methods. The idea is that a gui needs to know only
// definition of bx_simulator_interface to talk to Bochs. The gui should
// not need to include bochs.h.
//
// I made this separation to ensure that all guis use the siminterface to do
// access bochs internals, instead of accessing things like
// bx_keyboard.s.internal_buffer[4] (or whatever) directly. -Bryce
//
class bx_real_sim_c : public bx_simulator_interface_c {
sim_interface_callback_t callback;
void *callback_ptr;
#define BX_NOTIFY_MAX_ARGS 10
int notify_return_val;
int notify_int_args[BX_NOTIFY_MAX_ARGS];
char *notify_string_args[BX_NOTIFY_MAX_ARGS];
#define NOTIFY_TYPE_INT
@ -35,6 +48,10 @@ public:
virtual ~bx_real_sim_c ();
virtual int get_init_done () { return init_done; }
virtual int set_init_done (int n) { init_done = n; return 0;}
virtual void get_param_id_range (int *min, int *max) {
*min = BXP_NULL;
*max = BXP_THIS_IS_THE_LAST-1;
}
virtual int register_param (bx_id id, bx_param_c *it);
virtual bx_param_c *get_param (bx_id id);
virtual bx_param_num_c *get_param_num (bx_id id);
@ -46,7 +63,7 @@ public:
virtual char *get_action_name (int action);
virtual const char *get_log_level_name (int level);
virtual int get_max_log_level ();
virtual void quit_sim (int clean);
virtual void quit_sim (int code);
virtual int get_default_rc (char *path, int len);
virtual int read_rc (char *path);
virtual int write_rc (char *path, int overwrite);
@ -55,13 +72,16 @@ public:
virtual int get_floppy_options (int drive, bx_floppy_options *out);
virtual int get_cdrom_options (int drive, bx_cdrom_options *out);
virtual char *get_floppy_type_name (int type);
virtual void set_notify_callback (sim_interface_callback_t func);
virtual int notify_return (int retcode);
virtual int LOCAL_notify (int code);
virtual int LOCAL_log_msg (const char *prefix, int level, char *msg);
virtual int log_msg_2 (char *prefix, int *level, char *msg, int len);
virtual void set_notify_callback (sim_interface_callback_t func, void *arg);
virtual BxEvent* sim_to_gui_event (BxEvent *event);
virtual int log_msg (const char *prefix, int level, char *msg);
virtual int ask_param (bx_id which);
virtual int get_enabled () { return enabled; }
virtual void set_enabled (int enabled) { this->enabled = enabled; }
// ask the user for a pathname
virtual int ask_filename (char *filename, int maxlen, char *prompt, char *the_default, int flags);
// called at a regular interval, currently by the keyboard handler.
virtual void periodic ();
};
bx_param_c *
@ -70,8 +90,8 @@ bx_real_sim_c::get_param (bx_id id)
BX_ASSERT (id >= BXP_NULL && id < BXP_THIS_IS_THE_LAST);
int index = (int)id - BXP_NULL;
bx_param_c *retval = param_registry[index];
if (!retval)
BX_PANIC (("get_param can't find id %u", id));
if (!retval)
BX_INFO (("get_param can't find id %u", id));
return retval;
}
@ -102,7 +122,7 @@ bx_real_sim_c::get_param_string (bx_id id) {
return NULL;
}
void init_siminterface ()
void bx_init_siminterface ()
{
siminterface_log = new logfunctions ();
siminterface_log->put ("CTRL");
@ -118,16 +138,24 @@ bx_simulator_interface_c::bx_simulator_interface_c ()
bx_real_sim_c::bx_real_sim_c ()
{
callback = NULL;
notify_return_val = -1;
for (int i=0; i<BX_NOTIFY_MAX_ARGS; i++) {
callback_ptr = NULL;
enabled = 1;
int i;
for (i=0; i<BX_NOTIFY_MAX_ARGS; i++) {
notify_int_args[i] = -1;
notify_string_args[i] = NULL;
}
init_done = 0;
registry_alloc_size = BXP_THIS_IS_THE_LAST - BXP_NULL;
param_registry = new bx_param_c* [registry_alloc_size];
for (i=0; i<registry_alloc_size; i++)
param_registry[i] = NULL;
}
// called by constructor of bx_param_c, so that every parameter that is
// initialized gets registered. This builds a list of all parameters
// which can be used to look them up by number (get_param).
bx_real_sim_c::~bx_real_sim_c ()
{
if ( param_registry != NULL )
@ -140,8 +168,12 @@ bx_real_sim_c::~bx_real_sim_c ()
int
bx_real_sim_c::register_param (bx_id id, bx_param_c *it)
{
if (id == BXP_NULL) return 0;
BX_ASSERT (id >= BXP_NULL && id < BXP_THIS_IS_THE_LAST);
int index = (int)id - BXP_NULL;
if (this->param_registry[index] != NULL) {
BX_INFO (("register_param is overwriting parameter id %d", id));
}
this->param_registry[index] = it;
return 0;
}
@ -192,10 +224,34 @@ bx_real_sim_c::get_max_log_level ()
}
void
bx_real_sim_c::quit_sim (int clean) {
if (!clean)
bx_real_sim_c::quit_sim (int code) {
#if 0
if (!code)
BX_PANIC (("Quit simulation command"));
// tell bochs to shut down (includes vga screen)
bx_atexit ();
// tell the control panel to shut down
BxEvent *event = new BxEvent ();
event->type = BX_ASYNC_EVT_SHUTDOWN_GUI;
sim_to_gui_event (event);
// set something that will cause the cpu loop to exit.
// or use setjmp/longjmp, or something.
//FIXME!
#endif
BX_INFO (("quit_sim called"));
#if BX_WITH_WX
// in wxWindows, the whole simulator is running in a separate thread.
// our only job is to end the thread as soon as possible, NOT to shut
// down the whole application with an exit.
BX_CPU_THIS_PTR async_event = 1;
BX_CPU_THIS_PTR kill_bochs_request = 1;
// the cpu loop will exit very soon after this condition is set.
#else
// just a single thread. Use exit() to stop the application.
if (!code)
BX_PANIC (("Quit simulation command"));
::exit (0);
#endif
}
int
@ -272,54 +328,35 @@ bx_real_sim_c::get_floppy_type_name (int type)
}
void
bx_real_sim_c::set_notify_callback (sim_interface_callback_t func)
bx_real_sim_c::set_notify_callback (sim_interface_callback_t func, void *arg)
{
callback = func;
callback_ptr = arg;
}
int
bx_real_sim_c::notify_return (int retcode)
{
notify_return_val = retcode;
return 0;
}
int
bx_real_sim_c::LOCAL_notify (int code)
BxEvent *
bx_real_sim_c::sim_to_gui_event (BxEvent *event)
{
if (callback == NULL) {
BX_ERROR (("notify called, but no callback function is registered"));
return -1;
return NULL;
} else {
notify_return_val = -999;
(*callback)(code);
if (notify_return_val == -999)
BX_ERROR (("notify callback returned without setting the return value"));
return notify_return_val;
return (*callback)(callback_ptr, event);
}
}
// returns 0 for continue, 1 for alwayscontinue, 2 for die.
int
bx_real_sim_c::LOCAL_log_msg (const char *prefix, int level, char *msg)
bx_real_sim_c::log_msg (const char *prefix, int level, char *msg)
{
BxEvent *be = new BxEvent ();
be->type = BX_ASYNC_EVT_LOG_MSG;
be->u.logmsg.prefix = (char *)prefix;
be->u.logmsg.level = level;
be->u.logmsg.msg = msg;
//fprintf (stderr, "calling notify.\n");
notify_string_args[0] = strdup(prefix);
notify_int_args[1] = level;
notify_string_args[2] = msg;
int val = LOCAL_notify (NOTIFY_CODE_LOGMSG);
//fprintf (stderr, "notify returned %d\n", val);
return val;
}
// called by control.cc
int
bx_real_sim_c::log_msg_2 (char *prefix, int *level, char *msg, int len)
{
strncpy (prefix, notify_string_args[0], len);
*level= notify_int_args[1];
strncpy (msg, notify_string_args[2], len);
return 0;
BxEvent *response = sim_to_gui_event (be);
return response? response->retcode : -1;
}
/////////////////////////////////////////////////////////////////////////
@ -332,8 +369,8 @@ bx_object_c::bx_object_c (bx_id id)
this->type = BXT_OBJECT;
}
void
bx_object_c::set_type (Bit8u type)
void
bx_object_c::set_type (bx_objtype type)
{
this->type = type;
}
@ -459,6 +496,16 @@ bx_param_string_c::bx_param_string_c (bx_id id,
set (initial_val);
}
bx_param_filename_c::bx_param_filename_c (bx_id id,
char *name,
char *description,
char *initial_val,
int maxsize)
: bx_param_string_c (id, name, description, initial_val, maxsize)
{
get_options()->set (BX_IS_FILENAME);
}
bx_param_string_c::~bx_param_string_c ()
{
if ( this->val != NULL )
@ -608,3 +655,62 @@ bx_list_c::set_parent (bx_param_c *parent)
{
this->parent = parent;
}
// Called by simulator whenever it needs the user to choose a new value
// for a registered parameter. Create a synchronous ASK_PARAM event,
// send it to the GUI, and wait for the response. The GUI will call the
// set() method on the parameter if the user changes the value.
int
bx_real_sim_c::ask_param (bx_id param)
{
bx_param_c *paramptr = SIM->get_param(param);
BX_ASSERT (paramptr != NULL);
// create appropriate event
BxEvent *event = new BxEvent ();
event->type = BX_SYNC_EVT_ASK_PARAM;
event->u.param.param = paramptr;
BxEvent *response = sim_to_gui_event (event);
return response->retcode;
}
int
bx_real_sim_c::ask_filename (char *filename, int maxlen, char *prompt, char *the_default, int flags)
{
// implement using ASK_PARAM on a newly created param. I can't use
// ask_param because I don't intend to register this param.
BxEvent event;
bx_param_string_c param (BXP_NULL, "filename", prompt, the_default, maxlen);
flags |= param.BX_IS_FILENAME;
param.get_options()->set (flags);
event.type = BX_SYNC_EVT_ASK_PARAM;
event.u.param.param = &param;
BxEvent *response = sim_to_gui_event (&event);
BX_ASSERT ((response == &event));
if (event.retcode >= 0)
memcpy (filename, param.getptr(), maxlen);
return event.retcode;
}
void
bx_real_sim_c::periodic ()
{
// give the GUI a chance to do periodic things on the bochs thread. in
// particular, notice if the thread has been asked to die.
BxEvent *tick = new BxEvent ();
tick->type = BX_SYNC_EVT_TICK;
BxEvent *response = sim_to_gui_event (tick);
int retcode = response->retcode;
BX_ASSERT (response == tick);
delete tick;
if (retcode < 0) {
BX_INFO (("Bochs thread has been asked to quit."));
quit_sim (0);
}
#if 0
// watch for memory leaks. Allocate a small block of memory, print the
// pointer that is returned, then free.
BxEvent *memcheck = new BxEvent ();
BX_INFO(("memory allocation at %p", memcheck));
delete memcheck;
#endif
}

View File

@ -1,10 +1,10 @@
/////////////////////////////////////////////////////////////////////////
// $Id: siminterface.h,v 1.34 2002-03-26 13:51:48 bdenney Exp $
// $Id: siminterface.h,v 1.35 2002-04-18 00:22:19 bdenney Exp $
/////////////////////////////////////////////////////////////////////////
//
/*
* gui/siminterface.h
* $Id: siminterface.h,v 1.34 2002-03-26 13:51:48 bdenney Exp $
* $Id: siminterface.h,v 1.35 2002-04-18 00:22:19 bdenney Exp $
*
* Interface to the simulator, currently only used by control.cc.
* The base class bx_simulator_interface_c, contains only virtual functions
@ -18,10 +18,40 @@
*
*/
#define BX_UI_TEXT 1
// BX_UI_TEXT should be set to 1 when the text mode configuration interface
// is compiled in. This gives each type of parameter a text_print and text_ask
// method (defined in gui/control.cc) so that you can call text_ask() on any
// kind of parameter to ask the user to edit the value.
//
// I have been considering whether to use the same strategy for the wxWindows
// interface, but I'm not sure if I like it. One problem is that in order to
// declare member functions that are useful for wxWindows, the wxWindows header
// files would have to be included before the param object definitions. That
// means that all the wxwindows headers would have be included when compiling
// every single bochs file. One of the things I like about the separation
// between the simulator and GUI is that the two halves can be compiled without
// any knowledge of the other. Bochs doesn't include <wx.h>, and the wxwindows
// code doesn't include <bochs.h>. Aside from making compiles faster, this
// enforces the use of the interface so it keeps the interface clean (important
// when we may have multiple GUI implementations for example). This argues
// for keeping GUI-specific structures out of the simulator interface. It
// certainly works well for the text interface, but that's because FILE* is
// standard and portable.
#define BX_UI_TEXT (!BX_WITH_WX)
//////////////////////////////////////////////////////
// list of possible types for bx_param_c and descendant objects
typedef enum {
BXT_OBJECT = 201,
BXT_PARAM,
BXT_PARAM_NUM,
BXT_PARAM_BOOL,
BXT_PARAM_ENUM,
BXT_PARAM_STRING,
BXT_LIST
} bx_objtype;
typedef enum {
BXP_NULL = 101,
BXP_IPS,
@ -115,27 +145,194 @@ typedef enum {
BXP_KEYBOARD_USEMAPPING,
BXP_KEYBOARD_MAP,
BXP_KEYBOARD,
BXP_ASK_FOR_PATHNAME, // for general file selection dialog
BXP_THIS_IS_THE_LAST // used to determine length of list
} bx_id;
typedef enum {
BXT_OBJECT = 201,
BXT_NODE,
BXT_PARAM,
BXT_PARAM_NUM,
BXT_PARAM_BOOL,
BXT_PARAM_ENUM,
BXT_PARAM_STRING,
BXT_LIST
} bx_objtype;
BX_TOOLBAR_UNDEFINED,
BX_TOOLBAR_FLOPPYA,
BX_TOOLBAR_FLOPPYB,
BX_TOOLBAR_CDROMD,
BX_TOOLBAR_RESET,
BX_TOOLBAR_POWER,
BX_TOOLBAR_COPY,
BX_TOOLBAR_PASTE,
BX_TOOLBAR_SNAPSHOT,
BX_TOOLBAR_CONFIG,
BX_TOOLBAR_MOUSE_EN
} bx_toolbar_buttons;
// Log level defines
typedef enum {
LOGLEV_DEBUG = 0,
LOGLEV_INFO,
LOGLEV_ERROR,
LOGLEV_PANIC,
N_LOGLEV
} bx_log_levels;
///////////////////////////////////////////////////////////////////
// event structure for communication between simulator and gui
///////////////////////////////////////////////////////////////////
///// types and definitions used in event structures
#define BX_EVT_IS_ASYNC(type) ((type) > __ALL_EVENTS_BELOW_ARE_ASYNC__)
typedef enum {
__ALL_EVENTS_BELOW_ARE_SYNCHRONOUS__ = 2000,
BX_SYNC_EVT_GET_PARAM, // cpanel -> simulator -> cpanel
BX_SYNC_EVT_ASK_PARAM, // simulator -> cpanel -> simulator
BX_SYNC_EVT_TICK, // simulator -> cpanel, wait for response.
__ALL_EVENTS_BELOW_ARE_ASYNC__,
BX_ASYNC_EVT_KEY, // vga gui -> simulator
BX_ASYNC_EVT_MOUSE, // vga gui -> simulator
BX_ASYNC_EVT_SET_PARAM, // cpanel -> simulator
BX_ASYNC_EVT_LOG_MSG, // simulator -> cpanel
BX_ASYNC_EVT_VALUE_CHANGED, // simulator -> cpanel
BX_ASYNC_EVT_SHUTDOWN_GUI, // simulator -> cpanel
BX_ASYNC_EVT_TOOLBAR // cpanel -> simulator
} BxEventType;
typedef union {
Bit32s s32;
char *charptr;
} AnyParamVal;
// Define substructures which make up the interior of BxEvent. The
// substructures, such as BxKeyEvent or BxMouseEvent, should never be allocated
// on their own. They are only intended to be used within the union in the
// BxEvent structure.
// Event type: BX_SYNC_EVT_TICK
// A tick event is synchronous, sent from the simulator to the GUI. The
// event doesn't do anything visible. Primarily it gives the GUI a chance
// to tell the simulator to quit, if necessary. There may be other uses
// for the tick, such as giving some kind of regular status report or
// mentioning watched values that changed, but so far it's just for
// that one thing. There is no data associated with a tick event.
// Event type: BX_ASYNC_EVT_KEY
// (unused)
// A key event can be sent from the GUI to the Bochs simulator. It is
// asynchronous.
typedef struct {
// what was pressed? This is a BX_KEY_* value. For key releases,
// BX_KEY_RELEASED is ORed with the base BX_KEY_*.
Bit32u bx_key;
Boolean raw_scancode;
} BxKeyEvent;
// Event type: BX_ASYNC_EVT_MOUSE
// (unused)
// A mouse event can be sent from the GUI to the Bochs simulator. It is
// asynchronous. Currently not used, but when Psyon's wxwindows gui is
// integrated, we will need mouse events.
typedef struct {
// type is BX_EVT_MOUSE
Bit16u x, y; // coordinate (vga screen?)
Bit8u buttons; // which buttons are pressed.
// bit 0: 1=left button down, 0=up
// bit 1: 1=right button down, 0=up
} BxMouseEvent;
// Event type: BX_SYNC_EVT_GET_PARAM, BX_ASYNC_EVT_SET_PARAM
// (unused)
// Parameter set/get events are initiated by the GUI, since Bochs can always
// access the parameters directly. So far, I haven't used this type. In
// the GUI I just call SIM->get_param(parameter_id) to get a pointer to the
// bx_param_c object and then call the get/set methods. This is okay for
// configuration since bochs is not running. However it could be dangerous
// for the GUI thread to poke around in Bochs structures while the thread is
// running. For these cases, I may have to be more careful: build parameter
// change events in the GUI and place them on Bochs's event queue to be
// processed during SIM->periodic() or something.
typedef struct {
// type is BX_EVT_GET_PARAM, BX_EVT_SET_PARAM
class bx_param_c *param; // pointer to param structure
AnyParamVal val;
} BxParamEvent;
// Event type: BX_SYNC_EVT_ASK_PARAM
// Syncronous event sent from the simulator to the GUI. This tells the
// GUI to ask the user to choose the value of a parameter. The GUI may
// need to discover the type of parameter so that it can use the right
// kind of graphical display. The BxParamEvent is used for these events
// too.
// FIXME: at the moment the GUI implements the ASK_PARAM event for just
// a few parameter types. I need to implement the event for all parameter
// types.
// Event type: BX_ASYNC_EVT_VALUE_CHANGED
// (unused)
// Asynchronous event sent from the simulator to the GUI, telling it that
// some value that it (hopefully) cares about has changed. This isn't
// being used yet, but a good example is in a debugger interface, you might
// want to maintain a reasonably current display of the PC or some other
// simulation state. The GUI would set some kind of event mask (which
// doesn't exist now of course) and then when certain values change, the
// simulator would send this event so that the GUI can update. We may need
// some kind of "flow control" since the simulator will be able to produce
// new events much faster than the gui can handle them.
// Event type: BX_ASYNC_EVT_LOG_MSG
// Asynchronous event from the simulator to the GUI. When a BX_PANIC,
// BX_ERROR, BX_INFO, or BX_DEBUG is found in the simulator code, this
// event type can be used to inform the GUI of the condition. There is
// no point in sending messages to the GUI that will not be displayed; these
// would only slow the simulation. So we will need some mechanism for
// choosing what kinds of events will be delivered to the GUI. Normally,
// you wouldn't want to look at the log unless something is going wrong.
// At that point, you might want to open up a window to watch the debug
// messages from one device only.
//
// Idea: Except for panics that require user attention to continue, it might be
// most efficient to just append log messages to a file. When the user wants
// to look at the log messages, the gui can reopen the file (read only), skip
// to the end, and look backward for a reasonable number of lines to display
// (200?). This allows it to skip over huge bursts of log entries without
// allocating memory, synchronizing threads, etc. for each.
typedef struct {
// type is BX_EVT_LOG_MSG
Bit8u level;
char *prefix;
char *msg;
} BxLogMsgEvent;
// Event type: BX_EVT_TOOLBAR
// Asynchronous event from the GUI to the simulator, sent when the user
// clicks on a toolbar button. This may one day become something more
// general, like a command event, but at the moment it's only needed for
// the toolbar events.
typedef struct {
bx_toolbar_buttons button;
bool on; // for toggling buttons, on=true means the toolbar button is
// pressed. on=false means it is not pressed.
} BxToolbarEvent;
// The BxEvent structure should be used for all events. Every event has
// a type and a spot for a return code (only used for synchronous events).
typedef struct {
BxEventType type; // what kind is this?
Bit32s retcode; // sucess or failure. only used for synchronous events.
union {
BxKeyEvent key;
BxMouseEvent mouse;
BxParamEvent param;
BxLogMsgEvent logmsg;
BxToolbarEvent toolbar;
} u;
} BxEvent;
////////////////////////////////////////////////////////////////////
class bx_object_c {
private:
bx_id id;
Bit8u type;
bx_objtype type;
protected:
void set_type (Bit8u type);
void set_type (bx_objtype type);
public:
bx_object_c (bx_id id);
bx_id get_id () { return id; }
@ -151,9 +348,7 @@ protected:
int runtime_param;
int enabled;
public:
bx_param_c (bx_id id,
char *name,
char *description);
bx_param_c (bx_id id, char *name, char *description);
void set_format (char *format) {text_format = format;}
char *get_format () {return text_format;}
void set_ask_format (char *format) {ask_format = format; }
@ -188,6 +383,9 @@ public:
Bit32s get ();
void set (Bit32s val);
void set_base (int base) { this->base = base; }
int get_base () { return base; }
Bit32s get_min () { return min; }
Bit32s get_max () { return max; }
#if BX_UI_TEXT
virtual void text_print (FILE *fp);
virtual int text_ask (FILE *fpin, FILE *fpout);
@ -215,6 +413,7 @@ public:
char **choices,
Bit32s initial_val,
Bit32s value_base = 0);
char *get_choice (int n) { return choices[n]; }
#if BX_UI_TEXT
virtual void text_print (FILE *fp);
virtual int text_ask (FILE *fpin, FILE *fpout);
@ -231,7 +430,10 @@ class bx_param_string_c : public bx_param_c {
char separator;
public:
enum {
BX_RAW_BYTES = 1,
BX_RAW_BYTES = 1, // need binary text editor, like MAC addr
BX_IS_FILENAME = 2, // 1=yes it's a filename, 0=not a filename.
// Some guis have a file browser.
BX_SAVE_FILE_DIALOG = 4, // Use save dialog opposed to open file dialog
} bx_string_opt_bits;
bx_param_string_c (bx_id id,
char *name,
@ -252,6 +454,18 @@ public:
#endif
};
// declare a filename class. It is identical to a string, except that
// it initializes the options differently. This is just a shortcut
// for declaring a string param and setting the options with BX_IS_FILENAME.
class bx_param_filename_c : public bx_param_string_c {
public:
bx_param_filename_c (bx_id id,
char *name,
char *description,
char *initial_val,
int maxsize=-1);
};
class bx_list_c : public bx_param_c {
private:
// just a list of bx_param_c objects. size tells current number of
@ -347,12 +561,14 @@ struct bx_cdrom_options
////////////////////////////////////////////////////////////////////
extern int bx_main (int argc, char *argv[]);
class bx_simulator_interface_c {
public:
bx_simulator_interface_c ();
virtual int get_init_done () { return -1; }
virtual int set_init_done (int n) {return -1;}
virtual void get_param_id_range (int *min, int *max) {}
virtual int register_param (bx_id id, bx_param_c *it) {return -1;}
virtual bx_param_c *get_param (bx_id id) {return NULL;}
virtual bx_param_num_c *get_param_num (bx_id id) {return NULL;}
@ -364,7 +580,15 @@ public:
virtual char *get_action_name (int action) {return 0;}
virtual const char *get_log_level_name (int level) {return 0;}
virtual int get_max_log_level () {return -1;}
virtual void quit_sim (int clean) {}
// exiting is somewhat complicated! The preferred way to exit bochs is
// to call BX_EXIT(exitcode). That is defined to call
// SIM->quit_sim(exitcode). The quit_sim function first calls
// the cleanup functions in bochs so that it can destroy windows
// and free up memory, then sends a notify message to the control
// panel telling it that bochs has stopped.
virtual void quit_sim (int code) {}
virtual int get_default_rc (char *path, int len) {return -1;}
virtual int read_rc (char *path) {return -1;}
virtual int write_rc (char *rc, int overwrite) {return -1;}
@ -373,19 +597,36 @@ public:
virtual int get_floppy_options (int drive, bx_floppy_options *out) {return -1;}
virtual int get_cdrom_options (int drive, bx_cdrom_options *out) {return -1;}
virtual char *get_floppy_type_name (int type) {return NULL;}
typedef int (*sim_interface_callback_t)(int code);
virtual void set_notify_callback (sim_interface_callback_t func) {}
virtual int notify_return (int retcode) {return -1;}
// methods marked LOCAL should only be called by the simulator, not
// from the control panel.
#define NOTIFY_CODE_LOGMSG 0x101
virtual int LOCAL_notify (int code) {return -1;}
virtual int LOCAL_log_msg (const char *prefix, int level, char *msg) {return -1;}
virtual int log_msg_2 (char *prefix, int *level, char *msg, int len) {return -1;}
// The control panel calls set_notify_callback to register an event
// handler. This handler is for events which are generated by Bochs
// or the Bochs controller vga screen. For example, if the simulator
// hits a panic and wants a dialog box to appear, it would use the
// sim_interface_callback to ask the control panel to display a dialog.
// At present, the standard floppy disk buttons, power button, etc are under
// control of Bochs, NOT the control panel. Bochs uses the callback to tell
// the control panel that one of these buttons has been pressed.
typedef BxEvent* (*sim_interface_callback_t)(void *theclass, BxEvent *event);
virtual void set_notify_callback (sim_interface_callback_t func, void *arg) {}
// send an event from the simulator to the GUI.
virtual BxEvent* sim_to_gui_event (BxEvent *event) {return NULL;}
// this "notify arg" passing is very ugly and Bryce needs to clean it up!
virtual int log_msg (const char *prefix, int level, char *msg) {return -1;}
// called by gui.cc event handler when a button is pressed.
virtual int ask_param (bx_id param) {return -1;}
virtual int get_enabled () {return -1;}
virtual void set_enabled (int enabled) {}
// ask the user for a pathname
virtual int ask_filename (char *filename, int maxlen, char *prompt, char *the_default, int flags) {return -1;}
// called at a regular interval, currently by the keyboard handler.
virtual void periodic () {}
};
extern bx_simulator_interface_c *SIM;
extern void init_siminterface ();
extern void bx_init_siminterface ();
extern void bx_init_main ();
extern int bx_continue_after_control_panel (int argc, char *argv[]);

1547
bochs/gui/wx.cc Normal file

File diff suppressed because it is too large Load Diff

670
bochs/gui/wxmain.cc Normal file
View File

@ -0,0 +1,670 @@
//
// gui/wxmain.cc
// $Id: wxmain.cc,v 1.2 2002-04-18 00:22:19 bdenney Exp $
//
// wxmain.cc implements the wxWindows frame, toolbar, menus, and dialogs.
// When the application starts, the user is given a chance to choose/edit/save
// a configuration. When they decide to start the simulation, functions in
// main.cc are called in a separate thread to initialize and run the Bochs
// simulator.
//
// The wxWindows port of the VGA display is implemented in wx.cc. The
// separation between wxmain.cc and wx.cc is as follows:
// - wxmain.cc implements a Bochs configuration interface, which is
// the wxWindows equivalent of control.cc. wxmain creates a
// frame with several menus and a toolbar, and allows the user to
// choose the machine configuration and start the simulation.
// - wx.cc implements a VGA display screen using wxWindows. It is
// is the wxWindows equivalent of x.cc, win32.cc, macos.cc, etc.
// wx.cc includes bochs.h and has access to all Bochs devices.
// The VGA panel accepts only paint, key, and mouse events. As it
// receives events, it builds BxEvents and places them into a
// thread-safe BxEvent queue. The simulation thread periodically
// processes events from the BxEvent queue (bx_gui_c::handle_events)
// and notifies the appropriate emulated I/O device.
//
//////////////////////////////////////////////////////////////////////
// includes
//////////////////////////////////////////////////////////////////////
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include "wx/image.h"
#include "config.h" // definitions based on configure script
#include "osdep.h" // workarounds for missing stuff
#include "gui/siminterface.h" // interface to the simulator
#include "bxversion.h" // get version string
#include "wxmain.h" // interface to the gui
// include XPM icons
#include "bitmaps/cdromd.xpm"
#include "bitmaps/copy.xpm"
#include "bitmaps/floppya.xpm"
#include "bitmaps/floppyb.xpm"
#include "bitmaps/paste.xpm"
#include "bitmaps/power.xpm"
#include "bitmaps/reset.xpm"
#include "bitmaps/snapshot.xpm"
#include "bitmaps/mouse.xpm"
#include "bitmaps/configbutton.xpm"
// FIXME: ugly global variables that the bx_gui_c object in wx.cc can use
// to access the MyFrame and the MyPanel.
MyFrame *theFrame = NULL;
MyPanel *thePanel = NULL;
enum
{
ID_Quit = 1,
ID_Config_New,
ID_Config_Read,
ID_Config_Save,
ID_Edit_Disks,
ID_Edit_Boot,
ID_Edit_Vga,
ID_Edit_Memory,
ID_Edit_Sound,
ID_Edit_Network,
ID_Edit_Keyboard,
ID_Edit_Other,
ID_Simulate_Start,
ID_Simulate_PauseResume,
ID_Simulate_Stop,
ID_Simulate_Speed,
ID_Debug_ShowCpu,
ID_Debug_ShowMemory,
ID_Log_View,
ID_Log_Prefs,
ID_Log_PrefsDevice,
ID_Help_About,
ID_Sim2Gui_Event,
// ids for Bochs toolbar
ID_Toolbar_FloppyA,
ID_Toolbar_FloppyB,
ID_Toolbar_CdromD,
ID_Toolbar_Reset,
ID_Toolbar_Power,
ID_Toolbar_Copy,
ID_Toolbar_Paste,
ID_Toolbar_Snapshot,
ID_Toolbar_Config,
ID_Toolbar_Mouse_en
};
//////////////////////////////////////////////////////////////////////
// class declarations
//////////////////////////////////////////////////////////////////////
class MyApp: public wxApp
{
virtual bool OnInit();
};
class SimThread: public wxThread
{
MyFrame *frame;
// when the sim thread sends a synchronous event to the GUI thread, the
// response is stored in sim2gui_mailbox.
// FIXME: this would be cleaner and more reusable if I made a general
// thread-safe mailbox class.
BxEvent *sim2gui_mailbox;
wxCriticalSection sim2gui_mailbox_lock;
public:
SimThread (MyFrame *_frame) { frame = _frame; sim2gui_mailbox = NULL; }
virtual ExitCode Entry ();
void OnExit ();
// called by the siminterface code, with the pointer to the sim thread
// in the thisptr arg.
static BxEvent *SiminterfaceCallback (void *thisptr, BxEvent *event);
BxEvent *SiminterfaceCallback2 (BxEvent *event);
// methods to coordinate synchronous response mailbox
void ClearSyncResponse ();
void SendSyncResponse (BxEvent *);
BxEvent *GetSyncResponse ();
};
//////////////////////////////////////////////////////////////////////
// MyApp: the wxWindows application
//////////////////////////////////////////////////////////////////////
IMPLEMENT_APP(MyApp)
bool MyApp::OnInit()
{
//wxLog::AddTraceMask (_T("mime"));
bx_init_siminterface ();
bx_init_main ();
MyFrame *frame = new MyFrame( "Bochs x86 Emulator", wxPoint(50,50), wxSize(450,340), wxMINIMIZE_BOX | wxSYSTEM_MENU | wxCAPTION );
theFrame = frame; // hack alert
frame->Show( TRUE );
SetTopWindow( frame );
return TRUE;
}
//////////////////////////////////////////////////////////////////////
// MyFrame: the main frame for the Bochs application
//////////////////////////////////////////////////////////////////////
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_MENU(ID_Quit, MyFrame::OnQuit)
EVT_MENU(ID_Help_About, MyFrame::OnAbout)
EVT_MENU(ID_Simulate_Start, MyFrame::OnStartSim)
EVT_MENU(ID_Simulate_PauseResume, MyFrame::OnPauseResumeSim)
EVT_MENU(ID_Simulate_Stop, MyFrame::OnKillSim)
EVT_MENU(ID_Sim2Gui_Event, MyFrame::OnSim2GuiEvent)
// toolbar events
EVT_TOOL(ID_Toolbar_FloppyA, MyFrame::OnToolbarClick)
EVT_TOOL(ID_Toolbar_FloppyB, MyFrame::OnToolbarClick)
EVT_TOOL(ID_Toolbar_CdromD, MyFrame::OnToolbarClick)
EVT_TOOL(ID_Toolbar_Reset, MyFrame::OnToolbarClick)
EVT_TOOL(ID_Toolbar_Power, MyFrame::OnToolbarClick)
EVT_TOOL(ID_Toolbar_Copy, MyFrame::OnToolbarClick)
EVT_TOOL(ID_Toolbar_Paste, MyFrame::OnToolbarClick)
EVT_TOOL(ID_Toolbar_Snapshot, MyFrame::OnToolbarClick)
EVT_TOOL(ID_Toolbar_Config, MyFrame::OnToolbarClick)
EVT_TOOL(ID_Toolbar_Mouse_en, MyFrame::OnToolbarClick)
END_EVENT_TABLE()
MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size, const long style)
: wxFrame((wxFrame *)NULL, -1, title, pos, size, style)
{
// init variables
sim_thread = NULL;
start_bochs_times = 0;
// set up the gui
menuConfiguration = new wxMenu;
menuConfiguration->Append( ID_Config_New, "&New Configuration" );
menuConfiguration->Append( ID_Config_Read, "&Read Configuration" );
menuConfiguration->Append( ID_Config_Save, "&Save Configuration" );
menuConfiguration->AppendSeparator ();
menuConfiguration->Append (ID_Quit, "&Quit");
menuEdit = new wxMenu;
menuEdit->Append( ID_Edit_Disks, "&Disks..." );
menuEdit->Append( ID_Edit_Boot, "&Boot..." );
menuEdit->Append( ID_Edit_Vga, "&VGA..." );
menuEdit->Append( ID_Edit_Memory, "&Memory..." );
menuEdit->Append( ID_Edit_Sound, "&Sound..." );
menuEdit->Append( ID_Edit_Network, "&Network..." );
menuEdit->Append( ID_Edit_Keyboard, "&Keyboard..." );
menuEdit->Append( ID_Edit_Other, "&Other..." );
menuSimulate = new wxMenu;
menuSimulate->Append( ID_Simulate_Start, "&Start...");
menuSimulate->Append( ID_Simulate_PauseResume, "&Pause...");
menuSimulate->Append( ID_Simulate_Stop, "S&top...");
menuSimulate->AppendSeparator ();
menuSimulate->Append( ID_Simulate_Speed, "S&peed...");
menuSimulate->Enable (ID_Simulate_PauseResume, FALSE);
menuSimulate->Enable (ID_Simulate_Stop, FALSE);
menuDebug = new wxMenu;
menuDebug->Append (ID_Debug_ShowCpu, "Show &CPU");
menuDebug->Append (ID_Debug_ShowMemory, "Show &memory");
menuLog = new wxMenu;
menuLog->Append (ID_Log_View, "&View");
menuLog->Append (ID_Log_Prefs, "&Preferences...");
menuLog->Append (ID_Log_PrefsDevice, "By &Device...");
menuHelp = new wxMenu;
menuHelp->Append( ID_Help_About, "&About..." );
wxMenuBar *menuBar = new wxMenuBar;
menuBar->Append( menuConfiguration, "&File" );
menuBar->Append( menuEdit, "&Edit" );
menuBar->Append( menuSimulate, "&Simulate" );
menuBar->Append( menuDebug, "&Debug" );
menuBar->Append( menuLog, "&Log" );
menuBar->Append( menuHelp, "&Help" );
SetMenuBar( menuBar );
CreateStatusBar();
SetStatusText( "Welcome to wxWindows!" );
CreateToolBar(wxNO_BORDER|wxHORIZONTAL|wxTB_FLAT);
wxToolBar *tb = GetToolBar();
tb->SetToolBitmapSize(wxSize(16, 16));
int currentX = 5;
#define BX_ADD_TOOL(id, xpm_name, tooltip) \
do {tb->AddTool(id, wxBitmap(xpm_name), wxNullBitmap, FALSE, currentX, -1, (wxObject *)NULL, tooltip); currentX += 34; } while (0)
BX_ADD_TOOL(ID_Toolbar_FloppyA, floppya_xpm, "Change Floppy A");
BX_ADD_TOOL(ID_Toolbar_FloppyB, floppyb_xpm, "Change Floppy B");
BX_ADD_TOOL(ID_Toolbar_CdromD, cdromd_xpm, "Change CDROM");
BX_ADD_TOOL(ID_Toolbar_Reset, reset_xpm, "Reset the system");
BX_ADD_TOOL(ID_Toolbar_Power, power_xpm, "Turn power on/off");
BX_ADD_TOOL(ID_Toolbar_Copy, copy_xpm, "Copy to clipboard");
BX_ADD_TOOL(ID_Toolbar_Paste, paste_xpm, "Paste from clipboard");
BX_ADD_TOOL(ID_Toolbar_Snapshot, snapshot_xpm, "Save screen snapshot");
BX_ADD_TOOL(ID_Toolbar_Config, configbutton_xpm, "Runtime Configuration");
BX_ADD_TOOL(ID_Toolbar_Mouse_en, mouse_xpm, "Mouse Enable/Disable");
tb->Realize();
// create a MyPanel that covers the whole frame
panel = new MyPanel (this, -1);
panel->SetBackgroundColour (wxColour (0,0,0));
wxGridSizer *sz = new wxGridSizer (1, 1);
sz->Add (panel, 0, wxGROW);
SetAutoLayout (TRUE);
SetSizer (sz);
thePanel = panel;
}
void MyFrame::OnQuit(wxCommandEvent& event)
{
Close( TRUE );
OnKillSim (event);
#if 0
if (SIM)
SIM->quit_sim(0); // give bochs a chance to shut down
#endif
}
void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
{
wxString str;
str.Printf ("Bochs x86 Emulator version %s (wxWindows port)", VER_STRING);
wxMessageBox( str, "About Bochs", wxOK | wxICON_INFORMATION );
}
void MyFrame::OnStartSim(wxCommandEvent& WXUNUSED(event))
{
wxCriticalSectionLocker lock(sim_thread_lock);
if (sim_thread != NULL) {
wxMessageBox (
"Can't start Bochs simulator, because it is already running",
"Already Running", wxOK | wxICON_ERROR);
return;
}
wxLogStatus ("Starting a Bochs simulation");
start_bochs_times++;
if (start_bochs_times>1) {
wxMessageBox (
"You have already started the simulator once this session. Due to memory leaks, you may get unstable behavior.",
"2nd time warning", wxOK | wxICON_WARNING);
}
num_events = 0; // clear the queue of events for bochs to handle
sim_thread = new SimThread (this);
sim_thread->Create ();
sim_thread->Run ();
wxLogDebug ("Simulator thread has started.");
// set up callback for events from simulator thread
SIM->set_notify_callback (&SimThread::SiminterfaceCallback, sim_thread);
// fix up menu choices
menuSimulate->Enable (ID_Simulate_Start, FALSE);
menuSimulate->Enable (ID_Simulate_PauseResume, TRUE);
menuSimulate->Enable (ID_Simulate_Stop, TRUE);
menuSimulate->SetLabel (ID_Simulate_PauseResume, "&Pause");
}
void MyFrame::OnPauseResumeSim(wxCommandEvent& WXUNUSED(event))
{
wxCriticalSectionLocker lock(sim_thread_lock);
if (sim_thread) {
if (sim_thread->IsPaused ()) {
SetStatusText ("Resuming the Bochs simulation");
sim_thread->Resume ();
menuSimulate->SetLabel (ID_Simulate_PauseResume, "&Pause");
} else {
SetStatusText ("Pausing the Bochs simulation");
sim_thread->Pause ();
menuSimulate->SetLabel (ID_Simulate_PauseResume, "&Resume");
}
}
}
void MyFrame::OnKillSim(wxCommandEvent& WXUNUSED(event))
{
// DON'T use a critical section here. Delete implicitly calls
// OnSimThreadExit, which also tries to lock sim_thread_lock.
// If we grab the lock at this level, deadlock results.
if (sim_thread) {
SetStatusText ("Killing the Bochs simulation");
sim_thread->Delete ();
menuSimulate->Enable (ID_Simulate_Start, TRUE);
menuSimulate->Enable (ID_Simulate_PauseResume, FALSE);
menuSimulate->Enable (ID_Simulate_Stop, FALSE);
menuSimulate->SetLabel (ID_Simulate_PauseResume, "&Pause");
}
}
void
MyFrame::OnSimThreadExit () {
wxCriticalSectionLocker lock (sim_thread_lock);
sim_thread = NULL;
}
int
MyFrame::HandleAskParamString (bx_param_string_c *param)
{
wxLogDebug ("HandleAskParamString start");
bx_param_num_c *opt = param->get_options ();
wxASSERT (opt != NULL);
int n_opt = opt->get ();
char *msg = param->get_ask_format ();
if (!msg) msg = param->get_description ();
char *newval = NULL;
wxDialog *dialog = NULL;
if (n_opt & param->BX_IS_FILENAME) {
// use file open dialog
long style =
(n_opt & param->BX_SAVE_FILE_DIALOG) ? wxSAVE|wxOVERWRITE_PROMPT : wxOPEN;
wxLogDebug ("HandleAskParamString: create dialog");
wxFileDialog *fdialog = new wxFileDialog (this, msg, "", "", "*.*", style);
wxLogDebug ("HandleAskParamString: before showmodal");
if (fdialog->ShowModal() == wxID_OK)
newval = (char *)fdialog->GetPath().c_str ();
wxLogDebug ("HandleAskParamString: after showmodal");
dialog = fdialog; // so I can delete it
} else {
// use simple string dialog
long style = wxOK|wxCANCEL;
wxTextEntryDialog *tdialog = new wxTextEntryDialog (this, msg, "Enter new value", wxString(param->getptr ()), style);
if (tdialog->ShowModal() == wxID_OK)
newval = (char *)tdialog->GetValue().c_str ();
dialog = tdialog; // so I can delete it
}
// newval points to memory inside the dialg. As soon as dialog is deleted, newval points
// to junk. So be sure to copy the text out before deleting it!
if (newval && strlen(newval)>0) {
// change floppy path to this value.
wxLogDebug ("Setting param %s to '%s'", param->get_name (), newval);
param->set (newval);
delete dialog;
return 1;
}
delete dialog;
return -1;
}
// This is called when the simulator needs to ask the user to choose
// a value or setting. For example, when the user indicates that he wants
// to change the floppy disk image for drive A, an ask-param event is created
// with the parameter id set to BXP_FLOPPYA_PATH. The simulator blocks until
// the gui has displayed a dialog and received a selection from the user.
// In the current implemention, the GUI will look up the parameter's
// data structure using SIM->get_param() and then call the set method on the
// parameter to change the param. The return value only needs to return
// success or failure (failure = cancelled, or not implemented).
// Returns 1 if the user chose a value and the param was modified.
// Returns 0 if the user cancelled.
// Returns -1 if the gui doesn't know how to ask for that param.
int
MyFrame::HandleAskParam (BxEvent *event)
{
wxASSERT (event->type == BX_SYNC_EVT_ASK_PARAM);
bx_param_c *param = event->u.param.param;
Raise (); // bring control panel to front so that you will see the dialog
switch (param->get_type ())
{
case BXT_PARAM_STRING:
return HandleAskParamString ((bx_param_string_c *)param);
default:
{
wxString msg;
msg.Printf ("ask param for parameter type %d is not implemented in wxWindows");
wxMessageBox( msg, "not implemented", wxOK | wxICON_ERROR );
return -1;
}
}
#if 0
switch (param) {
case BXP_FLOPPYA_PATH:
case BXP_FLOPPYB_PATH:
case BXP_DISKC_PATH:
case BXP_DISKD_PATH:
case BXP_CDROM_PATH:
{
Raise(); // bring the control panel to front so dialog shows
char *msg;
if (param==BXP_FLOPPYA_PATH || param==BXP_FLOPPYB_PATH)
msg = "Choose new floppy disk image file";
else if (param==BXP_DISKC_PATH || param==BXP_DISKD_PATH)
msg = "Choose new hard disk image file";
else if (param==BXP_CDROM_PATH)
msg = "Choose new CDROM image file";
else
msg = "Choose new image file";
wxFileDialog dialog(this, msg, "", "", "*.*", 0);
int ret = dialog.ShowModal();
if (ret == wxID_OK)
{
char *newpath = (char *)dialog.GetPath().c_str ();
if (newpath && strlen(newpath)>0) {
// change floppy path to this value.
bx_param_string_c *Opath = SIM->get_param_string (param);
assert (Opath != NULL);
wxLogDebug ("Setting floppy %c path to '%s'",
param == BXP_FLOPPYA_PATH ? 'A' : 'B',
newpath);
Opath->set (newpath);
return 1;
}
}
return 0;
}
default:
wxLogError ("HandleAskParam: parameter %d, not implemented", event->u.param.id);
}
#endif
return -1; // could not display
}
// This is called when a Sim2Gui event is discovered on the GUI thread's
// event queue. (It got there via wxPostEvent in SiminterfaceCallback2,
// which is executed in the simulator Thread.)
void
MyFrame::OnSim2GuiEvent (wxCommandEvent& event)
{
wxLogDebug ("received a bochs event in the GUI thread");
BxEvent *be = (BxEvent *) event.GetEventObject ();
wxLogDebug ("event type = %d", (int) be->type);
// all cases should return. sync event handlers MUST send back a
// response.
switch (be->type) {
case BX_SYNC_EVT_ASK_PARAM:
wxLogDebug ("before HandleAskParam");
be->retcode = HandleAskParam (be);
wxLogDebug ("after HandleAskParam");
// sync must return something; just return a copy of the event.
sim_thread->SendSyncResponse(be);
wxLogDebug ("after SendSyncResponse");
return;
case BX_ASYNC_EVT_SHUTDOWN_GUI:
wxLogDebug ("control panel is exiting");
Close (TRUE);
wxExit ();
return;
case BX_ASYNC_EVT_LOG_MSG:
wxLogDebug ("log msg: level=%d, prefix='%s', msg='%s'",
be->u.logmsg.level,
be->u.logmsg.prefix,
be->u.logmsg.msg);
return;
default:
wxLogDebug ("OnSim2GuiEvent: event type %d ignored", (int)be->type);
// assume it's a synchronous event and send back a response, to avoid
// potential deadlock.
sim_thread->SendSyncResponse(be);
return;
}
// it is critical to send a response back eventually since the sim thread
// is blocking.
wxASSERT_MSG (0, "switch stmt should have returned");
}
void MyFrame::OnToolbarClick(wxCommandEvent& event)
{
wxLogDebug ("clicked toolbar thingy");
bx_toolbar_buttons which = BX_TOOLBAR_UNDEFINED;
int id = event.GetId ();
switch (id) {
case ID_Toolbar_Power:which = BX_TOOLBAR_POWER; break;
case ID_Toolbar_Reset: which = BX_TOOLBAR_RESET; break;
case ID_Toolbar_FloppyA: which = BX_TOOLBAR_FLOPPYA; break;
case ID_Toolbar_FloppyB: which = BX_TOOLBAR_FLOPPYB; break;
case ID_Toolbar_CdromD: which = BX_TOOLBAR_CDROMD; break;
case ID_Toolbar_Copy: which = BX_TOOLBAR_COPY; break;
case ID_Toolbar_Paste: which = BX_TOOLBAR_PASTE; break;
case ID_Toolbar_Snapshot: which = BX_TOOLBAR_SNAPSHOT; break;
case ID_Toolbar_Config: which = BX_TOOLBAR_CONFIG; break;
case ID_Toolbar_Mouse_en: which = BX_TOOLBAR_MOUSE_EN; break;
default:
wxLogError ("unknown toolbar id %d", id);
}
if (num_events < MAX_EVENTS) {
event_queue[num_events].type = BX_ASYNC_EVT_TOOLBAR;
event_queue[num_events].u.toolbar.button = which;
num_events++;
}
}
//////////////////////////////////////////////////////////////////////
// Simulation Thread
//////////////////////////////////////////////////////////////////////
void *
SimThread::Entry (void)
{
int argc=1;
char *argv[] = {"bochs"};
wxLogDebug ("in SimThread, starting at bx_continue_after_control_panel");
// run all the rest of the Bochs simulator code. This function will
// run forever, unless a "kill_bochs_request" is issued. The procedure
// is as follows:
// - user selects "Kill Simulation" or GUI decides to kill bochs
// - GUI calls sim_thread->Delete ()
// - sim continues to run until the next time it reaches SIM->periodic().
// - SIM->periodic() sends a synchronous tick event to the GUI, which
// finally calls TestDestroy() and realizes it needs to stop. It
// sets the sync event return code to -1. SIM->periodic() sets the
// kill_bochs_request flag in cpu #0.
// - cpu loop notices kill_bochs_request and returns to main.cc:
// bx_continue_after_control_panel(), which notices the
// kill_bochs_request and returns back to this Entry() function.
// - Entry() exits and the thread stops. Whew.
bx_continue_after_control_panel (argc, argv);
wxLogDebug ("in SimThread, bx_continue_after_control_panel exited");
return NULL;
}
void
SimThread::OnExit ()
{
// notify the MyFrame that the bochs thread has died. I can't adjust
// the sim_thread directly because it's private.
frame->OnSimThreadExit ();
// don't use this SimThread's callback function anymore.
SIM->set_notify_callback (NULL, NULL);
}
// This function is declared static so that I can get a usable function
// pointer for it. The function pointer is passed to SIM->set_notify_callback
// so that the siminterface can call this function when it needs to contact
// the gui. It will always be called with a pointer to the SimThread
// as the first argument.
BxEvent *
SimThread::SiminterfaceCallback (void *thisptr, BxEvent *event)
{
SimThread *me = (SimThread *)thisptr;
// call the normal non-static method now that we know the this pointer.
return me->SiminterfaceCallback2 (event);
}
// callback function for sim thread events. This is called from
// the sim thread, not the GUI thread. So any GUI actions must be
// thread safe. Most events are handled by packaging up the event
// in a wxEvent of some kind, and posting it to the GUI thread for
// processing.
BxEvent *
SimThread::SiminterfaceCallback2 (BxEvent *event)
{
//wxLogDebug ("SiminterfaceCallback with event type=%d", (int)event->type);
event->retcode = 0; // default return code
int async = BX_EVT_IS_ASYNC(event->type);
if (!async) {
// for synchronous events, clear away any previous response. There
// can only be one synchronous event pending at a time.
ClearSyncResponse ();
event->retcode = -1; // default to error
}
// tick event must be handled right here in the bochs thread.
if (event->type == BX_SYNC_EVT_TICK) {
if (TestDestroy ()) {
// tell simulator to quit
event->retcode = -1;
} else {
event->retcode = 0;
}
return event;
}
//encapsulate the bxevent in a wxwindows event
wxCommandEvent wxevent (wxEVT_COMMAND_MENU_SELECTED, ID_Sim2Gui_Event);
wxevent.SetEventObject ((wxEvent *)event);
wxLogDebug ("Sending an event to the window");
wxPostEvent (frame, wxevent);
// if it is an asynchronous event, return immediately
if (async) return NULL;
wxLogDebug ("SiminterfaceCallback2: synchronous event; waiting for response");
// now wait forever for the GUI to post a response.
BxEvent *response = NULL;
while (response == NULL) {
response = GetSyncResponse ();
if (!response) {
wxLogDebug ("no sync response yet, waiting");
this->Sleep(500);
}
}
wxASSERT (response != NULL);
return response;
}
void
SimThread::ClearSyncResponse ()
{
wxCriticalSectionLocker lock(sim2gui_mailbox_lock);
if (sim2gui_mailbox != NULL) {
wxLogDebug ("WARNING: ClearSyncResponse is throwing away an event that was previously in the mailbox");
}
sim2gui_mailbox = NULL;
}
void
SimThread::SendSyncResponse (BxEvent *event)
{
wxCriticalSectionLocker lock(sim2gui_mailbox_lock);
if (sim2gui_mailbox != NULL) {
wxLogDebug ("WARNING: SendSyncResponse is throwing away an event that was previously in the mailbox");
}
sim2gui_mailbox = event;
}
BxEvent *
SimThread::GetSyncResponse ()
{
wxCriticalSectionLocker lock(sim2gui_mailbox_lock);
BxEvent *event = sim2gui_mailbox;
sim2gui_mailbox = NULL;
return event;
}

76
bochs/gui/wxmain.h Normal file
View File

@ -0,0 +1,76 @@
// this file should be included only by wx.cc and wxmain.cc.
// forward class declaration so that each class can have a pointer to
// the others.
class MyFrame;
class MyPanel;
class SimThread;
//hack alert; yuck; FIXME
extern MyFrame *theFrame;
extern MyPanel *thePanel;
#define MAX_EVENTS 256
extern unsigned long num_events;
extern BxEvent event_queue[MAX_EVENTS];
// to show debug messages, change these defines to x. To hide them,
// change the defines to return nothing.
#define IFDBG_VGA(x) /* nothing */
//#define IFDBG_VGA(x) x
#define IFDBG_KEY(x) /* nothing */
//#define IFDBG_KEY(x) x
/// the MyPanel methods are defined in wx.cc
class MyPanel: public wxPanel
{
Boolean fillBxKeyEvent (wxKeyEvent& event, BxKeyEvent& bxev, Boolean release); // for all platforms
Boolean fillBxKeyEvent_MSW (wxKeyEvent& event, BxKeyEvent& bxev, Boolean release);
Boolean fillBxKeyEvent_GTK (wxKeyEvent& event, BxKeyEvent& bxev, Boolean release);
public:
MyPanel(wxWindow* parent, wxWindowID id, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxTAB_TRAVERSAL, const wxString& name = "panel")
: wxPanel (parent, id, pos, size, style, name)
{ wxLogDebug ("MyPanel constructor"); }
void OnKeyDown(wxKeyEvent& event);
void OnKeyUp(wxKeyEvent& event);
void OnPaint(wxPaintEvent& event);
void MyRefresh ();
private:
DECLARE_EVENT_TABLE()
};
/// the MyFrame methods are defined in wxmain.cc
class MyFrame: public wxFrame
{
MyPanel *panel;
public:
MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size, const long style);
void OnQuit(wxCommandEvent& event);
void OnAbout(wxCommandEvent& event);
void OnStartSim(wxCommandEvent& event);
void OnPauseResumeSim(wxCommandEvent& event);
void OnKillSim(wxCommandEvent& event);
void OnSim2GuiEvent(wxCommandEvent& event);
void OnToolbarClick(wxCommandEvent& event);
int HandleAskParam (BxEvent *event);
int HandleAskParamString (bx_param_string_c *param);
// called from the sim thread's OnExit() method.
void OnSimThreadExit ();
private:
wxCriticalSection sim_thread_lock;
SimThread *sim_thread; // get the lock before accessing sim_thread
int start_bochs_times;
wxMenu *menuConfiguration;
wxMenu *menuEdit;
wxMenu *menuSimulate;
wxMenu *menuDebug;
wxMenu *menuLog;
wxMenu *menuHelp;
DECLARE_EVENT_TABLE()
};

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: x.cc,v 1.40 2002-04-05 12:10:50 cbothamy Exp $
// $Id: x.cc,v 1.41 2002-04-18 00:22:19 bdenney Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002 MandrakeSoft S.A.
@ -1337,6 +1337,7 @@ headerbar_click(int x, int y)
void
bx_gui_c::exit(void)
{
XCloseDisplay (bx_x_display);
BX_INFO(("Exit."));
}

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: cdrom.cc,v 1.31 2002-04-10 05:38:34 bdenney Exp $
// $Id: cdrom.cc,v 1.32 2002-04-18 00:22:19 bdenney Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002 MandrakeSoft S.A.
@ -203,7 +203,7 @@ cdrom_interface::cdrom_interface(char *dev)
void
cdrom_interface::init(void) {
BX_DEBUG(("Init $Id: cdrom.cc,v 1.31 2002-04-10 05:38:34 bdenney Exp $"));
BX_DEBUG(("Init $Id: cdrom.cc,v 1.32 2002-04-18 00:22:19 bdenney Exp $"));
BX_INFO(("file = '%s'",path));
}
@ -250,7 +250,7 @@ cdrom_interface::insert_cdrom(char *dev)
{
strcpy(drive,path);
using_file = 1;
bUseASPI = FALSE;
bUseASPI = FALSE;
BX_INFO (("Opening image file as a cd"));
}
if(bUseASPI) {

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: keyboard.cc,v 1.54 2002-04-11 00:28:55 instinc Exp $
// $Id: keyboard.cc,v 1.55 2002-04-18 00:22:19 bdenney Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002 MandrakeSoft S.A.
@ -70,7 +70,7 @@ bx_keyb_c::bx_keyb_c(void)
memset( &s, 0, sizeof(s) );
BX_KEY_THIS put("KBD");
BX_KEY_THIS settype(KBDLOG);
BX_DEBUG(("Init $Id: keyboard.cc,v 1.54 2002-04-11 00:28:55 instinc Exp $"));
BX_DEBUG(("Init $Id: keyboard.cc,v 1.55 2002-04-18 00:22:19 bdenney Exp $"));
}
bx_keyb_c::~bx_keyb_c(void)
@ -110,7 +110,7 @@ bx_keyb_c::resetinternals(Boolean powerup)
void
bx_keyb_c::init(bx_devices_c *d, bx_cmos_c *cmos)
{
BX_DEBUG(("Init $Id: keyboard.cc,v 1.54 2002-04-11 00:28:55 instinc Exp $"));
BX_DEBUG(("Init $Id: keyboard.cc,v 1.55 2002-04-18 00:22:19 bdenney Exp $"));
Bit32u i;
BX_KEY_THIS devices = d;
@ -1099,6 +1099,8 @@ bx_keyb_c::periodic( Bit32u usec_delta )
if ( ++multiple==10)
{
multiple=0;
SIM->periodic ();
if (BX_CPU_THIS_PTR kill_bochs_request) return 0;
bx_gui.handle_events();
}

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: load32bitOShack.cc,v 1.7 2001-10-03 13:10:37 bdenney Exp $
// $Id: load32bitOShack.cc,v 1.8 2002-04-18 00:22:19 bdenney Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -268,12 +268,12 @@ bx_load_kernel_image(char *path, Bit32u paddr)
);
if (fd < 0) {
BX_INFO(( "load_kernel_image: couldn't open image file '%s'.", path ));
exit(1);
BX_EXIT(1);
}
ret = fstat(fd, &stat_buf);
if (ret) {
BX_INFO(( "load_kernel_image: couldn't stat image file '%s'.", path ));
exit(1);
BX_EXIT(1);
}
size = stat_buf.st_size;
@ -282,7 +282,7 @@ bx_load_kernel_image(char *path, Bit32u paddr)
BX_MEM_C *mem = BX_MEM(0);
if ( (paddr + size) > mem->len ) {
BX_INFO(( "load_kernel_image: address range > physical memsize!" ));
exit(1);
BX_EXIT(1);
}
offset = 0;
@ -290,7 +290,7 @@ bx_load_kernel_image(char *path, Bit32u paddr)
ret = read(fd, (bx_ptr_t) &mem->vector[paddr + offset], size);
if (ret <= 0) {
BX_INFO(( "load_kernel_image: read failed on image" ));
exit(1);
BX_EXIT(1);
}
size -= ret;
offset += ret;

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: logio.cc,v 1.16 2002-01-07 16:10:11 bdenney Exp $
// $Id: logio.cc,v 1.17 2002-04-18 00:22:19 bdenney Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -363,7 +363,7 @@ logfunctions::ask (int level, const char *prefix, const char *fmt, va_list ap)
vsprintf (buf1, fmt, ap);
sprintf (buf2, "%s %s", prefix, buf1);
// FIXME: facility set to 0 because it's unknown.
int val = SIM->LOCAL_log_msg (prefix, level, buf2);
int val = SIM->log_msg (prefix, level, buf2);
switch (val)
{
case 0: // user chose continue
@ -398,7 +398,7 @@ logfunctions::ask (int level, const char *prefix, const char *fmt, va_list ap)
default:
// this happens if panics happen before the callback is initialized
// in gui/control.cc.
fprintf (stderr, "WARNING: LOCAL_log_msg returned unexpected value %d\n", val);
fprintf (stderr, "WARNING: log_msg returned unexpected value %d\n", val);
}
}
@ -424,7 +424,7 @@ logfunctions::fatal (const char *prefix, const char *fmt, va_list ap)
fgets (buf, 8, stdin);
#endif
#if !BX_DEBUGGER
exit(1);
BX_EXIT(1);
#else
static Boolean dbg_exit_called = 0;
if (dbg_exit_called == 0) {

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: main.cc,v 1.96 2002-03-29 23:37:07 instinc Exp $
// $Id: main.cc,v 1.97 2002-04-18 00:22:19 bdenney Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -109,6 +109,7 @@ bx_options_t bx_options = {
static void parse_line_unformatted(char *context, char *line);
static void parse_line_formatted(char *context, int num_params, char *params[]);
static int parse_bochsrc(char *rcfile);
static void bx_do_text_config_interface (int argc, char *argv[]);
static Bit32s
bx_param_handler (bx_param_c *param, int set, Bit32s val)
@ -319,11 +320,15 @@ void bx_init_options ()
bx_list_c *menu;
// floppya
bx_options.floppya.Opath = new bx_param_string_c (BXP_FLOPPYA_PATH,
bx_options.floppya.Opath = new bx_param_filename_c (BXP_FLOPPYA_PATH,
"Floppy A image",
"Pathname of first floppy image file or device. If you're booting from floppy, this should be a bootable floppy.",
"", BX_PATHNAME_LEN);
#if BX_WITH_WX
bx_options.floppya.Opath->set_ask_format ("Filename of first floppy image");
#else
bx_options.floppya.Opath->set_ask_format ("Enter new filename, or 'none' for no disk: [%s] ");
#endif
bx_options.floppya.Otype = new bx_param_enum_c (BXP_FLOPPYA_TYPE,
"floppya:type",
"Type of floppy disk",
@ -353,11 +358,15 @@ void bx_init_options ()
bx_options.floppya.Opath->set ("none");
bx_options.floppya.Oinitial_status->set_handler (bx_param_handler);
bx_options.floppyb.Opath = new bx_param_string_c (BXP_FLOPPYB_PATH,
bx_options.floppyb.Opath = new bx_param_filename_c (BXP_FLOPPYB_PATH,
"floppyb:path",
"Pathname of second floppy image file or device.",
"", BX_PATHNAME_LEN);
#if BX_WITH_WX
bx_options.floppyb.Opath->set_ask_format ("Filename of second floppy image");
#else
bx_options.floppyb.Opath->set_ask_format ("Enter new filename, or 'none' for no disk: [%s] ");
#endif
bx_options.floppyb.Otype = new bx_param_enum_c (BXP_FLOPPYB_TYPE,
"floppyb:type",
"Type of floppy disk",
@ -393,7 +402,7 @@ void bx_init_options ()
"diskc:present",
"Controls whether diskc is installed or not",
0);
bx_options.diskc.Opath = new bx_param_string_c (BXP_DISKC_PATH,
bx_options.diskc.Opath = new bx_param_filename_c (BXP_DISKC_PATH,
"",
"Pathname of the hard drive image",
"", BX_PATHNAME_LEN);
@ -439,7 +448,7 @@ void bx_init_options ()
"diskd:present",
"Controls whether diskd is installed or not",
0);
bx_options.diskd.Opath = new bx_param_string_c (BXP_DISKD_PATH,
bx_options.diskd.Opath = new bx_param_filename_c (BXP_DISKD_PATH,
"diskd:path",
"Pathname of the hard drive image",
"", BX_PATHNAME_LEN);
@ -484,7 +493,7 @@ void bx_init_options ()
"",
0);
bx_options.com1.Odev = new bx_param_string_c (BXP_COM1_PATH,
bx_options.com1.Odev = new bx_param_filename_c (BXP_COM1_PATH,
"Pathname of the serial device for COM1",
"",
"", BX_PATHNAME_LEN);
@ -496,7 +505,7 @@ void bx_init_options ()
"Controls whether com2 is installed or not",
0);
bx_options.com2.Odev = new bx_param_string_c (BXP_COM2_PATH,
bx_options.com2.Odev = new bx_param_filename_c (BXP_COM2_PATH,
"",
"",
"", BX_PATHNAME_LEN);
@ -507,7 +516,7 @@ void bx_init_options ()
"",
0);
bx_options.com3.Odev = new bx_param_string_c (BXP_COM3_PATH,
bx_options.com3.Odev = new bx_param_filename_c (BXP_COM3_PATH,
"Pathname of the serial device for COM3",
"",
"", BX_PATHNAME_LEN);
@ -518,7 +527,7 @@ void bx_init_options ()
"",
0);
bx_options.com4.Odev = new bx_param_string_c (BXP_COM4_PATH,
bx_options.com4.Odev = new bx_param_filename_c (BXP_COM4_PATH,
"Pathname of the serial device for COM4",
"",
"", BX_PATHNAME_LEN);
@ -530,12 +539,14 @@ void bx_init_options ()
"CDROM is present",
"Controls whether cdromd is installed or not",
0);
bx_options.cdromd.Opath = new bx_param_string_c (BXP_CDROM_PATH,
bx_options.cdromd.Opath = new bx_param_filename_c (BXP_CDROM_PATH,
"CDROM image filename",
"Pathname of the cdrom device or image",
"", BX_PATHNAME_LEN);
bx_options.cdromd.Opath->set_format ("%s");
#if BX_UI_TEXT
bx_options.cdromd.Opath->set_ask_format ("Enter new filename, or 'none' for no CDROM: [%s] ");
#endif
bx_options.cdromd.Oinserted = new bx_param_enum_c (BXP_CDROM_INSERTED,
"Is the CDROM inserted or ejected",
"Inserted or ejected",
@ -596,7 +607,7 @@ void bx_init_options ()
"Enables the first parallel port",
0);
bx_options.par1.Oenable->set_handler (bx_param_handler);
bx_options.par1.Ooutfile = new bx_param_string_c (BXP_PARPORT1_OUTFILE,
bx_options.par1.Ooutfile = new bx_param_filename_c (BXP_PARPORT1_OUTFILE,
"Parallel port #1 output file",
"Data written to parport#1 by the guest OS is written to this file",
"parport.out", BX_PATHNAME_LEN);
@ -606,7 +617,7 @@ void bx_init_options ()
"Enables the second parallel port",
0);
bx_options.par2.Oenable->set_handler (bx_param_handler);
bx_options.par2.Ooutfile = new bx_param_string_c (BXP_PARPORT2_OUTFILE,
bx_options.par2.Ooutfile = new bx_param_filename_c (BXP_PARPORT2_OUTFILE,
"Parallel port #2 output file",
"Data written to parport#2 by the guest OS is written to this file",
"parport2.out", BX_PATHNAME_LEN);
@ -629,7 +640,7 @@ void bx_init_options ()
menu = new bx_list_c (BXP_MENU_SERIAL_PARALLEL, "Serial and Parallel Port Options", "serial_parallel_menu", parport_init_list);
menu->get_options ()->set (menu->BX_SHOW_PARENT);
bx_options.rom.Opath = new bx_param_string_c (BXP_ROM_PATH,
bx_options.rom.Opath = new bx_param_filename_c (BXP_ROM_PATH,
"romimage",
"Pathname of ROM image to load",
"", BX_PATHNAME_LEN);
@ -641,7 +652,7 @@ void bx_init_options ()
0);
bx_options.rom.Oaddress->set_format ("ROM BIOS address: 0x%05x");
bx_options.rom.Oaddress->set_base (16);
bx_options.vgarom.Opath = new bx_param_string_c (BXP_VGA_ROM_PATH,
bx_options.vgarom.Opath = new bx_param_filename_c (BXP_VGA_ROM_PATH,
"vgaromimage",
"Pathname of VGA ROM image to load",
"", BX_PATHNAME_LEN);
@ -752,15 +763,15 @@ void bx_init_options ()
"SB16 is present",
"to be written",
0);
bx_options.sb16.Omidifile = new bx_param_string_c (BXP_SB16_MIDIFILE,
bx_options.sb16.Omidifile = new bx_param_filename_c (BXP_SB16_MIDIFILE,
"Midi file",
"to be written",
"", BX_PATHNAME_LEN);
bx_options.sb16.Owavefile = new bx_param_string_c (BXP_SB16_WAVEFILE,
bx_options.sb16.Owavefile = new bx_param_filename_c (BXP_SB16_WAVEFILE,
"Wave file",
"to be written",
"", BX_PATHNAME_LEN);
bx_options.sb16.Ologfile = new bx_param_string_c (BXP_SB16_LOGFILE,
bx_options.sb16.Ologfile = new bx_param_filename_c (BXP_SB16_LOGFILE,
"Log file",
"to be written",
"", BX_PATHNAME_LEN);
@ -800,7 +811,7 @@ void bx_init_options ()
bx_options.sb16.Opresent->set_handler (bx_param_handler);
bx_options.sb16.Opresent->set (0);
bx_options.log.Ofilename = new bx_param_string_c (BXP_LOG_FILENAME,
bx_options.log.Ofilename = new bx_param_filename_c (BXP_LOG_FILENAME,
"log:filename",
"Pathname of bochs log file",
"-", BX_PATHNAME_LEN);
@ -813,15 +824,15 @@ void bx_init_options ()
loader_os_names,
Load32bitOSNone,
Load32bitOSNone);
bx_options.load32bitOSImage.Opath = new bx_param_string_c (BXP_LOAD32BITOS_PATH,
bx_options.load32bitOSImage.Opath = new bx_param_filename_c (BXP_LOAD32BITOS_PATH,
"Pathname of OS to load",
NULL,
"", BX_PATHNAME_LEN);
bx_options.load32bitOSImage.Oiolog = new bx_param_string_c (BXP_LOAD32BITOS_IOLOG,
bx_options.load32bitOSImage.Oiolog = new bx_param_filename_c (BXP_LOAD32BITOS_IOLOG,
"Pathname of I/O log file",
NULL,
"", BX_PATHNAME_LEN);
bx_options.load32bitOSImage.Oinitrd = new bx_param_string_c (BXP_LOAD32BITOS_INITRD,
bx_options.load32bitOSImage.Oinitrd = new bx_param_filename_c (BXP_LOAD32BITOS_INITRD,
"Pathname of initrd",
NULL,
"", BX_PATHNAME_LEN);
@ -870,7 +881,7 @@ void bx_init_options ()
"Use a CMOS image",
NULL,
0);
bx_options.cmos.Opath = new bx_param_string_c (BXP_CMOS_PATH,
bx_options.cmos.Opath = new bx_param_filename_c (BXP_CMOS_PATH,
"Pathname of CMOS image",
NULL,
"", BX_PATHNAME_LEN);
@ -885,7 +896,7 @@ void bx_init_options ()
"Use keyboard mapping",
NULL,
0);
bx_options.keyboard.Okeymap = new bx_param_string_c (BXP_KEYBOARD_MAP,
bx_options.keyboard.Okeymap = new bx_param_filename_c (BXP_KEYBOARD_MAP,
"Keymap filename",
NULL,
"", BX_PATHNAME_LEN);
@ -967,10 +978,22 @@ static void setupWorkingDirectory (char *path)
}
#endif
int
main(int argc, char *argv[])
#if !BX_WITH_WX
// main() is the entry point for all configurations, except for
// wxWindows.
int main (int argc, char *argv[])
{
bx_init_siminterface ();
bx_init_main ();
bx_do_text_config_interface (argc, argv);
bx_control_panel (BX_CPANEL_INIT);
bx_continue_after_control_panel (argc, argv);
}
#endif
void
bx_init_main ()
{
int arg = 1;
// To deal with initialization order problems inherent in C++, use the macros
// SAFE_GET_IOFUNC and SAFE_GET_GENLOG to retrieve "io" and "genlog" in all
// constructors or functions called by constructors. The macros test for
@ -982,7 +1005,7 @@ main(int argc, char *argv[])
bx_print_header ();
bx_init_bx_dbg ();
bx_init_options ();
#if BX_WITH_CARBON
/* "-psn" is passed if we are launched by double-clicking */
if ( argc >= 2 && strncmp (argv[1], "-psn", 4) == 0 ) {
@ -1004,12 +1027,13 @@ main(int argc, char *argv[])
getwd (cwd);
BX_INFO (("Now my working directory is %s", cwd));
#endif
}
init_siminterface ();
bx_control_panel (BX_CPANEL_INIT);
bx_init_options ();
static void
bx_do_text_config_interface (int argc, char *argv[])
{
// detect -nocontrolpanel or -nocp argument before anything else
int arg = 1;
if (argc > 1 &&
((!strcmp ("-nocontrolpanel", argv[1]))
|| (!strcmp ("-nocp", argv[1])))) {
@ -1022,8 +1046,8 @@ main(int argc, char *argv[])
enable_control_panel = 0;
#endif
if (!enable_control_panel) {
// if we don't intend to run the control panel, parse the .bochsrc now.
if (!enable_control_panel || BX_WITH_WX) {
/* parse configuration file and command line arguments */
char *bochsrc = bx_find_bochsrc ();
if (bochsrc)
bx_read_configuration (bochsrc);
@ -1045,7 +1069,7 @@ main(int argc, char *argv[])
fprintf (stderr, " cd /usr/local/bochs/dlxlinux\n");
fprintf (stderr, " bochs\n");
#endif
exit(1);
BX_EXIT(1);
}
}
@ -1064,8 +1088,29 @@ main(int argc, char *argv[])
}
// Display the pre-simulation control panel.
SIM->set_enabled (1);
#if !BX_WITH_WX
// unless wxwindows interface in use, show the control panel now
bx_control_panel (BX_CPANEL_START_MENU);
#endif
}
}
int
bx_continue_after_control_panel (int argc, char *argv[])
{
#if BX_WITH_WX
// FIXME: load default bochsrc right now. When the wxWindows interface
// is more complete, you will be able to load a bochsrc using the
// interface.
char *bochsrc = bx_find_bochsrc ();
if (bochsrc) {
bx_read_configuration (bochsrc);
free (bochsrc);
} else {
BX_PANIC (("Could not load a .bochsrc"));
}
#endif
#if BX_DEBUGGER
// If using the debugger, it will take control and call
@ -1092,7 +1137,8 @@ main(int argc, char *argv[])
// only one processor, run as fast as possible by not messing with
// quantums and loops.
BX_CPU(0)->cpu_loop(1);
BX_PANIC (("cpu_loop should never return in a single-processor simulation"));
// for one processor, the only reason for cpu_loop to return is
// that kill_bochs_request was set by the GUI interface.
} else {
// SMP simulation: do a few instructions on each processor, then switch
// to another. Increasing quantum speeds up overall performance, but
@ -1103,15 +1149,19 @@ main(int argc, char *argv[])
// do some instructions in each processor
BX_CPU(processor)->cpu_loop(quantum);
processor = (processor+1) % BX_SMP_PROCESSORS;
if (BX_CPU(0)->kill_bochs_request)
break;
if (processor == 0)
BX_TICKN(quantum);
BX_TICKN(quantum);
}
}
#endif
BX_INFO (("cpu loop quit, shutting down simulator"));
bx_atexit ();
return(0);
}
int
bx_read_configuration (char *rcfile)
{
@ -1254,16 +1304,15 @@ bx_init_bx_dbg (void)
}
void
int
bx_atexit(void)
{
static Boolean been_here = 0;
if (been_here) return 1; // protect from reentry
been_here = 1;
#if BX_PROVIDE_DEVICE_MODELS==1
if (been_here == 0) {
bx_pc_system.exit();
}
bx_pc_system.exit();
#endif
#if BX_DEBUGGER == 0
@ -1276,6 +1325,7 @@ bx_atexit(void)
bx_devices.pci->print_i440fx_state();
}
#endif
return 0;
}
#if (BX_PROVIDE_CPU_MEMORY==1) && (BX_EMULATE_HGA_DUMPS>0)

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: misc_mem.cc,v 1.18 2002-04-09 20:12:39 bdenney Exp $
// $Id: misc_mem.cc,v 1.19 2002-04-18 00:22:20 bdenney Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -90,7 +90,7 @@ BX_MEM_C::~BX_MEM_C(void)
void
BX_MEM_C::init_memory(int memsize)
{
BX_DEBUG(("Init $Id: misc_mem.cc,v 1.18 2002-04-09 20:12:39 bdenney Exp $"));
BX_DEBUG(("Init $Id: misc_mem.cc,v 1.19 2002-04-18 00:22:20 bdenney Exp $"));
// you can pass 0 if memory has been allocated already through
// the constructor, or the desired size of memory if it hasn't
@ -137,19 +137,19 @@ BX_MEM_C::load_ROM(const char *path, Bit32u romaddress)
);
if (fd < 0) {
BX_INFO(( "ROM: couldn't open ROM image file '%s'.", path));
exit(1);
BX_EXIT(1);
}
ret = fstat(fd, &stat_buf);
if (ret) {
BX_INFO(( "ROM: couldn't stat ROM image file '%s'.", path));
exit(1);
BX_EXIT(1);
}
size = stat_buf.st_size;
if ( (romaddress + size) > BX_MEM_THIS len ) {
BX_INFO(( "ROM: ROM address range > physical memsize!"));
exit(1);
BX_EXIT(1);
}
offset = 0;

Binary file not shown.

1
bochs/wxbochs.rc Normal file
View File

@ -0,0 +1 @@
#include "wx/msw/wx.rc"