diff -urN qemu-0.10.4/Makefile qemu-0.10.4-haiku/Makefile
--- qemu-0.10.4/Makefile	2009-05-18 03:18:37.000000000 +0000
+++ qemu-0.10.4-haiku/Makefile	2009-05-18 07:50:17.000000000 +0000
@@ -108,6 +108,9 @@
 AUDIO_OBJS += coreaudio.o
 AUDIO_PT = yes
 endif
+ifdef CONFIG_HAIKU
+AUDIO_OBJS += haikuaudio.o
+endif
 ifdef CONFIG_ALSA
 AUDIO_OBJS += alsaaudio.o
 endif
@@ -149,6 +152,10 @@
 OBJS+=cocoa.o
 endif
 
+ifdef CONFIG_HAIKU
+OBJS+=haiku.o
+endif
+
 ifdef CONFIG_SLIRP
 CPPFLAGS+=-I$(SRC_PATH)/slirp
 SLIRP_OBJS=cksum.o if.o ip_icmp.o ip_input.o ip_output.o \
@@ -240,12 +247,14 @@
 		$(INSTALL) -m 644 $(SRC_PATH)/pc-bios/$$x "$(DESTDIR)$(datadir)"; \
 	done
 endif
+ifndef CONFIG_HAIKU
 ifndef CONFIG_WIN32
 	mkdir -p "$(DESTDIR)$(datadir)/keymaps"
 	set -e; for x in $(KEYMAPS); do \
 		$(INSTALL) -m 644 $(SRC_PATH)/keymaps/$$x "$(DESTDIR)$(datadir)/keymaps"; \
 	done
 endif
+endif
 	for d in $(TARGET_DIRS); do \
 	$(MAKE) -C $$d $@ || exit 1 ; \
         done
diff -urN qemu-0.10.4/Makefile.target qemu-0.10.4-haiku/Makefile.target
--- qemu-0.10.4/Makefile.target	2009-05-18 03:18:36.000000000 +0000
+++ qemu-0.10.4-haiku/Makefile.target	2009-05-18 06:40:30.000000000 +0000
@@ -117,7 +117,9 @@
 LDFLAGS+=$(OS_LDFLAGS) $(ARCH_LDFLAGS)
 
 CPPFLAGS+=-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
+ifndef CONFIG_HAIKU
 LIBS+=-lm
+endif
 ifdef CONFIG_WIN32
 LIBS+=-lwinmm -lws2_32 -liphlpapi
 endif
@@ -700,11 +702,13 @@
 ifndef CONFIG_WIN32
 ifndef CONFIG_SOLARIS
 ifndef CONFIG_AIX
+ifndef CONFIG_HAIKU
 LIBS+=-lutil
 endif
 endif
 endif
 endif
+endif
 ifdef TARGET_GPROF
 vl.o: CFLAGS+=-p
 LDFLAGS+=-p
diff -urN qemu-0.10.4/audio/audio.h qemu-0.10.4-haiku/audio/audio.h
--- qemu-0.10.4/audio/audio.h	2009-05-18 03:18:38.000000000 +0000
+++ qemu-0.10.4-haiku/audio/audio.h	2009-05-18 08:15:16.000000000 +0000
@@ -146,7 +146,7 @@
 
 static inline void *advance (void *p, int incr)
 {
-    uint8_t *d = p;
+    uint8_t *d = (uint8_t *)p;
     return (d + incr);
 }
 
diff -urN qemu-0.10.4/audio/audio_int.h qemu-0.10.4-haiku/audio/audio_int.h
--- qemu-0.10.4/audio/audio_int.h	2009-05-18 03:18:38.000000000 +0000
+++ qemu-0.10.4-haiku/audio/audio_int.h	2009-05-18 08:10:01.000000000 +0000
@@ -205,6 +205,7 @@
 extern struct audio_driver dsound_audio_driver;
 extern struct audio_driver esd_audio_driver;
 extern struct audio_driver pa_audio_driver;
+extern struct audio_driver haiku_audio_driver;
 extern struct mixeng_volume nominal_volume;
 
 void audio_pcm_init_info (struct audio_pcm_info *info, struct audsettings *as);
diff -urN qemu-0.10.4/audio/haikuaudio.cpp qemu-0.10.4-haiku/audio/haikuaudio.cpp
--- qemu-0.10.4/audio/haikuaudio.cpp	1970-01-01 00:00:00.000000000 +0000
+++ qemu-0.10.4-haiku/audio/haikuaudio.cpp	2009-05-18 08:18:42.000000000 +0000
@@ -0,0 +1,304 @@
+/*
+ * QEMU Haiku audio output driver
+ * 
+ * Copyright (c) 2005-2009 Michael Lotz
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+extern "C" {
+#include "qemu-common.h"
+#include "audio/audio.h"
+#define AUDIO_CAP "haiku"
+#include "audio_int.h"
+
+static	int		haiku_run_out(HWVoiceOut *hw);
+static	int		haiku_write(SWVoiceOut *sw, void *buf, int len);
+static	int		haiku_init_out(HWVoiceOut *hw, struct audsettings *as);
+static	void	haiku_fini_out(HWVoiceOut *hw);
+static	int		haiku_ctl_out(HWVoiceOut *hw, int cmd, ...);
+
+static	int		haiku_init_in(HWVoiceIn *hw, struct audsettings *as);
+static	void	haiku_fini_in(HWVoiceIn *hw);
+static	int		haiku_run_in(HWVoiceIn *hw);
+static	int		haiku_read(SWVoiceIn *sw, void *buf, int size);
+static	int		haiku_ctl_in(HWVoiceIn *hw, int cmd, ...);
+
+static	void *	haiku_audio_init(void);
+static	void	haiku_audio_fini(void *opaque);
+}
+
+// name conflict
+#define load_image _b_load_image
+#include <SoundPlayer.h>
+
+typedef struct BufferInfo {
+	uint8 *buffer;
+	uint32 size;
+	uint32 read_position;
+	uint32 write_position;
+	uint32 valid;
+} BufferInfo;
+
+typedef struct HaikuVoiceOut {
+	HWVoiceOut hw;
+	BufferInfo *buffer;
+	BSoundPlayer *player;
+} HaikuVoiceOut;
+
+
+typedef struct HaikuVoiceIn {
+	HWVoiceIn hw;
+	BufferInfo *buffer;
+} HaikuVoiceIn;
+
+
+void
+PlayBuffer(void *cookie, void *buffer, size_t size, const media_raw_audio_format &format)
+{
+	BufferInfo *info = (BufferInfo *)cookie;
+	if (info->valid == 0) {
+		memset(buffer, 0, size);
+		return;
+	}
+
+	uint32 max = 0;
+	uint32 location = 0;
+	bool wrapped = (info->read_position + info->valid) > info->size;
+	if (wrapped) {
+		max = MIN(MIN(info->size - info->read_position, info->valid), size);
+		memcpy(buffer, info->buffer + info->read_position, max);
+		info->read_position = (info->read_position + max) % info->size;
+		info->valid -= max;
+		location += max;
+
+		if (max >= size)
+			return;
+	}
+
+	max = MIN(info->valid, size - location);
+	memcpy((uint8 *)buffer + location, info->buffer + info->read_position, max);
+	info->read_position = (info->read_position + max) % info->size;
+	info->valid -= max;
+	location += max;
+
+	if (location < size)
+		memset((uint8 *)buffer + location, 0, size - location);
+}
+
+
+static int
+haiku_run_out(HWVoiceOut *hw)
+{
+	HaikuVoiceOut *voice = (HaikuVoiceOut *)hw;
+	BufferInfo *info = voice->buffer;
+	if (!info)
+		return 0;
+
+	int live = audio_pcm_hw_get_live_out(hw);
+	if (live <= 0)
+		return 0;
+
+	int position = hw->rpos;
+	int available = hw->samples - position;
+	int bufferAvailable = MIN(info->size - info->valid, info->size - info->write_position);
+	int samples = MIN(MIN(live, available), bufferAvailable >> hw->info.shift);
+
+	if (samples > 0) {
+		struct st_sample *src = hw->mix_buf + position;
+		uint8 *dst = (uint8 *)advance(info->buffer, info->write_position);
+		hw->clip(dst, src, samples);
+		mixeng_clear(src, samples);
+		hw->rpos = (position + samples) % hw->samples;
+		info->write_position += samples << hw->info.shift;
+		info->write_position %= info->size;
+		info->valid += samples << hw->info.shift;
+	}
+
+	return samples;
+}
+
+
+static int
+haiku_write(SWVoiceOut *sw, void *buf, int len)
+{
+	return audio_pcm_sw_write(sw, buf, len);
+}
+
+
+static int
+haiku_init_out(HWVoiceOut *hw, struct audsettings *as)
+{
+	media_raw_audio_format format;
+	format.frame_rate = as->freq;
+	format.channel_count = as->nchannels;
+	format.byte_order = B_MEDIA_LITTLE_ENDIAN;
+	format.buffer_size = 2048;
+
+	switch (as->fmt) {
+		case AUD_FMT_U8:
+			format.format = media_raw_audio_format::B_AUDIO_UCHAR;
+			break;
+		case AUD_FMT_S8:
+			format.format = media_raw_audio_format::B_AUDIO_CHAR;
+			break;
+		case AUD_FMT_S16:
+			format.format = media_raw_audio_format::B_AUDIO_SHORT;
+			break;
+		case AUD_FMT_U16:
+			printf("Audio Format not supported!\n");
+			return 1;
+	}
+
+	audio_pcm_init_info(&hw->info, as);
+	hw->samples = (format.buffer_size * 10) >> hw->info.shift;
+	hw->rpos = 0;
+
+	BufferInfo *info = new BufferInfo;
+	//info->size = hw->samples * (format.format & 0x0f) * format.channel_count;
+	info->size = (hw->samples << hw->info.shift) * 4;
+	info->buffer = (uint8 *)qemu_malloc(info->size);
+	info->read_position = 0;
+	info->write_position = 0;
+	info->valid = 0;
+
+	HaikuVoiceOut *voice = (HaikuVoiceOut *)hw;
+	voice->buffer = info;
+	voice->player = new BSoundPlayer(&format, "QEMU", PlayBuffer, NULL, info);
+	voice->player->Start();
+	voice->player->SetHasData(true);
+	return 0;
+}
+
+
+static void
+haiku_fini_out(HWVoiceOut *hw)
+{
+	HaikuVoiceOut *voice = (HaikuVoiceOut *)hw;
+
+	voice->player->Stop();
+	voice->player = NULL;
+
+	free(voice->buffer->buffer);
+	delete voice->buffer;
+	voice->buffer = NULL;
+
+	delete voice->player;
+}
+
+
+static int
+haiku_ctl_out(HWVoiceOut *hw, int cmd, ...)
+{
+	HaikuVoiceOut *voice = (HaikuVoiceOut *)hw;
+	if (!voice->player)
+		return 0;
+
+	switch (cmd) {
+		case VOICE_ENABLE:
+			voice->player->SetHasData(true);
+			break;
+
+		case VOICE_DISABLE:
+			//voice->player->SetHasData(false);
+			break;
+	}
+
+	return 0;
+}
+
+
+static int
+haiku_init_in(HWVoiceIn *hw, struct audsettings *as)
+{
+	audio_pcm_init_info(&hw->info, as);
+	hw->samples = 1024;
+	return 0;
+}
+
+
+static void
+haiku_fini_in(HWVoiceIn *hw)
+{
+}
+
+
+static int
+haiku_run_in(HWVoiceIn *hw)
+{
+	return 0;
+}
+
+
+static int
+haiku_read(SWVoiceIn *sw, void *buf, int size)
+{
+	return 0;
+}
+
+
+static int
+haiku_ctl_in(HWVoiceIn *hw, int cmd, ...)
+{
+	return 0;
+}
+
+
+static void *
+haiku_audio_init(void)
+{
+	// just an opaque handle, doesn't matter, we don't use it
+	return (void *)&haiku_audio_init;
+}
+
+
+static void
+haiku_audio_fini(void *opaque)
+{
+}
+
+
+struct audio_pcm_ops haiku_pcm_ops = {
+	haiku_init_out,
+	haiku_fini_out,
+	haiku_run_out,
+	haiku_write,
+	haiku_ctl_out,
+
+	haiku_init_in,
+	haiku_fini_in,
+	haiku_run_in,
+	haiku_read,
+	haiku_ctl_in
+};
+
+
+struct audio_driver haiku_audio_driver = {
+	"haiku",
+	"Haiku Native Audio",
+	NULL,
+	haiku_audio_init,
+	haiku_audio_fini,
+	&haiku_pcm_ops,
+	1,
+	1,
+	1,
+	sizeof(HaikuVoiceOut),
+	sizeof(HaikuVoiceIn)
+};
diff -urN qemu-0.10.4/configure qemu-0.10.4-haiku/configure
--- qemu-0.10.4/configure	2009-05-18 03:18:38.000000000 +0000
+++ qemu-0.10.4-haiku/configure	2009-05-18 08:23:46.000000000 +0000
@@ -188,6 +188,7 @@
 blobs="yes"
 fdt="yes"
 sdl_x11="no"
+haiku="no"
 
 # OS specific
 if check_define __linux__ ; then
@@ -298,6 +299,21 @@
 aix="yes"
 make="gmake"
 ;;
+Haiku)
+haiku="yes"
+kvm="no"
+curses="no"
+aio="no"
+sdl="no"
+bluez="no"
+audio_drv_list="haiku"
+audio_possible_drivers="haiku"
+OS_CFLAGS="-fno-pic"
+OS_LDFLAGS="-lnetwork -lbe -lgame -lmedia"
+if [ "$cpu" = "i386" -o "$cpu" = "x86_64" ] ; then
+    kqemu="yes"
+fi
+;;
 *)
 audio_drv_list="oss"
 audio_possible_drivers="oss alsa sdl esd pa"
@@ -910,7 +926,7 @@
         "pa_simple *s = NULL; pa_simple_free(s); return 0;"
     ;;
 
-    oss|sdl|core|wav|dsound)
+    oss|sdl|core|wav|dsound|haiku)
     # XXX: Probes for CoreAudio, DirectSound, SDL(?)
     ;;
 
@@ -1098,6 +1114,14 @@
   datasuffix=""
   docsuffix=""
   binsuffix=""
+elif test "$haiku" = "yes" ; then
+  if test -z "$prefix" ; then
+      prefix="/boot/apps/QEMU"
+  fi
+  mansuffix="/share/man"
+  datasuffix="/share/qemu"
+  docsuffix="/share/doc/qemu"
+  binsuffix=""
 else
   if test -z "$prefix" ; then
       prefix="/usr/local"
@@ -1323,6 +1347,11 @@
   echo "#define CONFIG_AIX 1" >> $config_h
 fi
 
+if test "$haiku" = "yes" ; then
+  echo "CONFIG_HAIKU=yes" >> $config_mak
+  echo "#define CONFIG_HAIKU 1" >> $config_h
+fi
+
 if test "$solaris" = "yes" ; then
   echo "CONFIG_SOLARIS=yes" >> $config_mak
   echo "#define HOST_SOLARIS $solarisrev" >> $config_h
@@ -1535,8 +1564,8 @@
 esac
 
 if test "$target_user_only" = "no" -a "$check_gfx" = "yes" \
-        -a "$sdl" = "no" -a "$cocoa" = "no" ; then
-    echo "ERROR: QEMU requires SDL or Cocoa for graphical output"
+        -a "$sdl" = "no" -a "$cocoa" = "no" -a "$haiku" = "no" ; then
+    echo "ERROR: QEMU requires SDL, Cocoa or Haiku for graphical output"
     echo "To build QEMU without graphical output configure with --disable-gfx-check"
     echo "Note that this will disable all output from the virtual graphics card"
     echo "except through VNC or curses."
diff -urN qemu-0.10.4/console.h qemu-0.10.4-haiku/console.h
--- qemu-0.10.4/console.h	2009-05-18 03:18:35.000000000 +0000
+++ qemu-0.10.4-haiku/console.h	2009-05-18 01:50:34.000000000 +0000
@@ -282,6 +282,9 @@
 /* cocoa.m */
 void cocoa_display_init(DisplayState *ds, int full_screen);
 
+/* haiku.cpp */
+void haiku_display_init(DisplayState *ds, int full_screen);
+
 /* vnc.c */
 void vnc_display_init(DisplayState *ds);
 void vnc_display_close(DisplayState *ds);
diff -urN qemu-0.10.4/fpu/softfloat-native.h qemu-0.10.4-haiku/fpu/softfloat-native.h
--- qemu-0.10.4/fpu/softfloat-native.h	2009-05-18 03:18:38.000000000 +0000
+++ qemu-0.10.4-haiku/fpu/softfloat-native.h	2009-05-17 22:41:10.000000000 +0000
@@ -8,6 +8,27 @@
 #include <fenv.h>
 #endif
 
+#ifdef __HAIKU__
+#ifndef isgreater
+#define isgreater(x, y)		__builtin_isgreater(x, y)
+#endif
+#ifndef isgreaterequal
+#define isgreaterequal(x, y)	__builtin_isgreaterequal(x, y)
+#endif
+#ifndef isless
+#define isless(x, y)		__builtin_isless(x, y)
+#endif
+#ifndef islessequal
+#define islessequal(x, y)	__builtin_islessequal(x, y)
+#endif
+#ifndef isunordered
+#define isunordered(x, y)	__builtin_isunordered(x, y)
+#endif
+#ifndef fabsl
+#define fabsl(x) __builtin_fabsl(x)
+#endif
+#endif
+
 #if defined(__OpenBSD__) || defined(__NetBSD__)
 #include <sys/param.h>
 #endif
diff -urN qemu-0.10.4/fpu/softfloat.c qemu-0.10.4-haiku/fpu/softfloat.c
--- qemu-0.10.4/fpu/softfloat.c	2009-05-18 03:18:38.000000000 +0000
+++ qemu-0.10.4-haiku/fpu/softfloat.c	2009-05-18 07:13:29.000000000 +0000
@@ -5373,17 +5373,17 @@
 #endif
 
 /* misc functions */
-float32 uint32_to_float32( unsigned int a STATUS_PARAM )
+float32 uint32_to_float32( uint32 a STATUS_PARAM )
 {
     return int64_to_float32(a STATUS_VAR);
 }
 
-float64 uint32_to_float64( unsigned int a STATUS_PARAM )
+float64 uint32_to_float64( uint32 a STATUS_PARAM )
 {
     return int64_to_float64(a STATUS_VAR);
 }
 
-unsigned int float32_to_uint32( float32 a STATUS_PARAM )
+uint32 float32_to_uint32( float32 a STATUS_PARAM )
 {
     int64_t v;
     unsigned int res;
@@ -5401,7 +5401,7 @@
     return res;
 }
 
-unsigned int float32_to_uint32_round_to_zero( float32 a STATUS_PARAM )
+uint32 float32_to_uint32_round_to_zero( float32 a STATUS_PARAM )
 {
     int64_t v;
     unsigned int res;
@@ -5419,7 +5419,7 @@
     return res;
 }
 
-unsigned int float64_to_uint32( float64 a STATUS_PARAM )
+uint32 float64_to_uint32( float64 a STATUS_PARAM )
 {
     int64_t v;
     unsigned int res;
@@ -5437,7 +5437,7 @@
     return res;
 }
 
-unsigned int float64_to_uint32_round_to_zero( float64 a STATUS_PARAM )
+uint32 float64_to_uint32_round_to_zero( float64 a STATUS_PARAM )
 {
     int64_t v;
     unsigned int res;
diff -urN qemu-0.10.4/fpu/softfloat.h qemu-0.10.4-haiku/fpu/softfloat.h
--- qemu-0.10.4/fpu/softfloat.h	2009-05-18 03:18:38.000000000 +0000
+++ qemu-0.10.4-haiku/fpu/softfloat.h	2009-05-18 13:09:27.000000000 +0000
@@ -48,6 +48,7 @@
 | to the same as `int'.
 *----------------------------------------------------------------------------*/
 typedef uint8_t flag;
+#ifndef __HAIKU__
 typedef uint8_t uint8;
 typedef int8_t int8;
 #ifndef _AIX
@@ -58,6 +59,17 @@
 typedef signed int int32;
 typedef uint64_t uint64;
 typedef int64_t int64;
+#else
+// Haiku types
+typedef signed char int8;
+typedef unsigned char uint8;
+typedef short int16;
+typedef unsigned short uint16;
+typedef long int32;
+typedef unsigned long uint32;
+typedef long long int64;
+typedef unsigned long long uint64;
+#endif
 
 /*----------------------------------------------------------------------------
 | Each of the following `typedef's defines a type that holds integers
@@ -221,15 +233,15 @@
 /*----------------------------------------------------------------------------
 | Software IEC/IEEE integer-to-floating-point conversion routines.
 *----------------------------------------------------------------------------*/
-float32 int32_to_float32( int STATUS_PARAM );
-float64 int32_to_float64( int STATUS_PARAM );
-float32 uint32_to_float32( unsigned int STATUS_PARAM );
-float64 uint32_to_float64( unsigned int STATUS_PARAM );
+float32 int32_to_float32( int32 STATUS_PARAM );
+float64 int32_to_float64( int32 STATUS_PARAM );
+float32 uint32_to_float32( uint32 STATUS_PARAM );
+float64 uint32_to_float64( uint32 STATUS_PARAM );
 #ifdef FLOATX80
-floatx80 int32_to_floatx80( int STATUS_PARAM );
+floatx80 int32_to_floatx80( int32 STATUS_PARAM );
 #endif
 #ifdef FLOAT128
-float128 int32_to_float128( int STATUS_PARAM );
+float128 int32_to_float128( int32 STATUS_PARAM );
 #endif
 float32 int64_to_float32( int64_t STATUS_PARAM );
 float32 uint64_to_float32( uint64_t STATUS_PARAM );
@@ -245,10 +257,10 @@
 /*----------------------------------------------------------------------------
 | Software IEC/IEEE single-precision conversion routines.
 *----------------------------------------------------------------------------*/
-int float32_to_int32( float32 STATUS_PARAM );
-int float32_to_int32_round_to_zero( float32 STATUS_PARAM );
-unsigned int float32_to_uint32( float32 STATUS_PARAM );
-unsigned int float32_to_uint32_round_to_zero( float32 STATUS_PARAM );
+int32 float32_to_int32( float32 STATUS_PARAM );
+int32 float32_to_int32_round_to_zero( float32 STATUS_PARAM );
+uint32 float32_to_uint32( float32 STATUS_PARAM );
+uint32 float32_to_uint32_round_to_zero( float32 STATUS_PARAM );
 int64_t float32_to_int64( float32 STATUS_PARAM );
 int64_t float32_to_int64_round_to_zero( float32 STATUS_PARAM );
 float64 float32_to_float64( float32 STATUS_PARAM );
@@ -313,10 +325,10 @@
 /*----------------------------------------------------------------------------
 | Software IEC/IEEE double-precision conversion routines.
 *----------------------------------------------------------------------------*/
-int float64_to_int32( float64 STATUS_PARAM );
-int float64_to_int32_round_to_zero( float64 STATUS_PARAM );
-unsigned int float64_to_uint32( float64 STATUS_PARAM );
-unsigned int float64_to_uint32_round_to_zero( float64 STATUS_PARAM );
+int32 float64_to_int32( float64 STATUS_PARAM );
+int32 float64_to_int32_round_to_zero( float64 STATUS_PARAM );
+uint32 float64_to_uint32( float64 STATUS_PARAM );
+uint32 float64_to_uint32_round_to_zero( float64 STATUS_PARAM );
 int64_t float64_to_int64( float64 STATUS_PARAM );
 int64_t float64_to_int64_round_to_zero( float64 STATUS_PARAM );
 uint64_t float64_to_uint64 (float64 a STATUS_PARAM);
@@ -386,8 +398,8 @@
 /*----------------------------------------------------------------------------
 | Software IEC/IEEE extended double-precision conversion routines.
 *----------------------------------------------------------------------------*/
-int floatx80_to_int32( floatx80 STATUS_PARAM );
-int floatx80_to_int32_round_to_zero( floatx80 STATUS_PARAM );
+int32 floatx80_to_int32( floatx80 STATUS_PARAM );
+int32 floatx80_to_int32_round_to_zero( floatx80 STATUS_PARAM );
 int64_t floatx80_to_int64( floatx80 STATUS_PARAM );
 int64_t floatx80_to_int64_round_to_zero( floatx80 STATUS_PARAM );
 float32 floatx80_to_float32( floatx80 STATUS_PARAM );
@@ -450,8 +462,8 @@
 /*----------------------------------------------------------------------------
 | Software IEC/IEEE quadruple-precision conversion routines.
 *----------------------------------------------------------------------------*/
-int float128_to_int32( float128 STATUS_PARAM );
-int float128_to_int32_round_to_zero( float128 STATUS_PARAM );
+int32 float128_to_int32( float128 STATUS_PARAM );
+int32 float128_to_int32_round_to_zero( float128 STATUS_PARAM );
 int64_t float128_to_int64( float128 STATUS_PARAM );
 int64_t float128_to_int64_round_to_zero( float128 STATUS_PARAM );
 float32 float128_to_float32( float128 STATUS_PARAM );
diff -urN qemu-0.10.4/haiku.cpp qemu-0.10.4-haiku/haiku.cpp
--- qemu-0.10.4/haiku.cpp	1970-01-01 00:00:00.000000000 +0000
+++ qemu-0.10.4-haiku/haiku.cpp	2009-05-18 02:06:51.000000000 +0000
@@ -0,0 +1,634 @@
+/*
+ * QEMU Haiku display driver
+ * 
+ * Copyright (c) 2005-2009 Michael Lotz
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+// Haiku declaration collides with QEMU load_image
+#define load_image	haiku_load_image
+#include "haiku.h"
+#undef load_image
+
+#include <Path.h>
+#include <Screen.h>
+#include <WindowScreen.h>
+
+#include <stdio.h>
+
+
+QEMUApplication *gApplication;
+QEMUWindow *gWindow;
+QEMUView *gView;
+bool gFullScreen;
+int gWidth = 100;
+int gHeight = 100;
+BPoint gCenter;
+BPoint gPreviousLocation;
+
+
+// Required functions into QEMU
+extern "C" {
+void	kbd_put_keycode(int keycode);
+void	kbd_mouse_event(int dx, int dy, int dz, int buttons_state);
+void	qemu_system_shutdown_request(void);
+int		qemu_main(int argc, char *argv[]);
+int		is_graphic_console(void);
+void	console_select(unsigned int index);
+void	vga_hw_update(void);
+void	vga_hw_invalidate(void);
+void	kbd_put_keysym(int keysym);
+
+extern const char *bios_dir;
+}
+
+
+// Haiku keycode to scancode table
+static const uint8
+haiku_to_pc_key[] = {
+	0x00,	/* 0x00 */						0x01,	/* 0x01 Esc */
+	0x3b,	/* 0x02 F1 */					0x3c,	/* 0x03 F2 */
+	0x3d,	/* 0x04 F3 */					0x3e,	/* 0x05 F4 */
+	0x3f,	/* 0x06 F5 */					0x40,	/* 0x07 F6 */
+	0x41,	/* 0x08 F7 */					0x42,	/* 0x09 F8 */
+	0x43,	/* 0x0a F9 */					0x44,	/* 0x0b F10 */
+	0x57,	/* 0x0c F11 */					0x58,	/* 0x0d F12 */
+	0xb7,	/* 0x0e Print Screen */			0x46,	/* 0x0f Scroll Lock */
+	0xc5,	/* 0x10 Pause */				0x29,	/* 0x11 Grave */
+	0x02,	/* 0x12 1 */					0x03,	/* 0x13 2 */
+	0x04,	/* 0x14 3 */					0x05,	/* 0x15 4 */
+	0x06,	/* 0x16 5 */					0x07,	/* 0x17 6 */
+	0x08,	/* 0x18 7 */					0x09,	/* 0x19 8 */
+	0x0a,	/* 0x1a 9 */					0x0b,	/* 0x1b 0 */
+	0x0c,	/* 0x1c Minus */				0x0d,	/* 0x1d Equals */
+	0x0e,	/* 0x1e Backspace */			0xd2,	/* 0x1f Insert */
+	0xc7,	/* 0x20 Home */					0xc9,	/* 0x21 Page Up */
+	0x45,	/* 0x22 Num Lock */				0xb5,	/* 0x23 KP Divide */
+	0x37,	/* 0x24 KP Multiply */			0x4a,	/* 0x25 KP Subtract */
+	0x0f,	/* 0x26 Tab */					0x10,	/* 0x27 Q */
+	0x11,	/* 0x28 W */					0x12,	/* 0x29 E */
+	0x13,	/* 0x2a R */					0x14,	/* 0x2b T */
+	0x15,	/* 0x2c Y */					0x16,	/* 0x2d U */
+	0x17,	/* 0x2e I */					0x18,	/* 0x2f O */
+	0x19,	/* 0x30 P */					0x1a,	/* 0x31 Left Bracket */
+	0x1b,	/* 0x32 Right Bracket */		0x2b,	/* 0x33 Backslash */
+	0xd3,	/* 0x34 Delete */				0xcf,	/* 0x35 End */
+	0xd1,	/* 0x36 Page Down */			0x47,	/* 0x37 KP 7 */
+	0x48,	/* 0x38 KP 8 */					0x49,	/* 0x39 KP 9 */
+	0x4e,	/* 0x3a KP Add */				0x3a,	/* 0x3b Caps Lock */
+	0x1e,	/* 0x3c A */					0x1f,	/* 0x3d S */
+	0x20,	/* 0x3e D */					0x21,	/* 0x3f F */
+	0x22,	/* 0x40 G */					0x23,	/* 0x41 H */
+	0x24,	/* 0x42 J */					0x25,	/* 0x43 K */
+	0x26,	/* 0x44 L */					0x27,	/* 0x45 Semicolon */
+	0x28,	/* 0x46 Single Quote */			0x1c,	/* 0x47 Enter */
+	0x4b,	/* 0x48 KP 4 */					0x4c,	/* 0x49 KP 5 */
+	0x4d,	/* 0x4a KP 6 */					0x2a,	/* 0x4b Left Shift */
+	0x2c,	/* 0x4c Z */					0x2d,	/* 0x4d X */
+	0x2e,	/* 0x4e C */					0x2f,	/* 0x4f V */
+	0x30,	/* 0x50 B */					0x31,	/* 0x51 N */
+	0x32,	/* 0x52 M */					0x33,	/* 0x53 Comma */
+	0x34,	/* 0x54 Period */				0x35,	/* 0x55 Slash */
+	0x36,	/* 0x56 Right Shift */			0xc8,	/* 0x57 Up */
+	0x4f,	/* 0x58 KP 1 */					0x50,	/* 0x59 KP 2 */
+	0x51,	/* 0x5a KP 3 */					0x9c,	/* 0x5b KP Enter */
+	0x1d,	/* 0x5c Left Control */			0x38,	/* 0x5d Left Alt */
+	0x39,	/* 0x5e Space */				0xb8,	/* 0x5f Right Alt */
+	0x9d,	/* 0x60 Right Control */		0xcb,	/* 0x61 Left */
+	0xd0,	/* 0x62 Down */					0xcd,	/* 0x63 Right */
+	0x52,	/* 0x64 KP 0 */					0x53,	/* 0x65 KP . */
+	0xdb,	/* 0x66 Left Windows */			0xdc,	/* 0x67 Right Windows */
+	0xdd,	/* 0x68 Menu */					0x56,	/* 0x69 */
+	0x7d,	/* 0x6a Macron */				0x73,	/* 0x6b Backslash */
+	0x7b,	/* 0x6c Muhenkan */				0x79,	/* 0x6d Henkan */
+	0x70,	/* 0x6e Hiragana Katakana */	0x00,	/* 0x6f */
+	0x00,	/* 0x70 */						0x00,	/* 0x71 */
+	0x00,	/* 0x72 */						0x00,	/* 0x73 */
+	0x00,	/* 0x74 */						0x00,	/* 0x75 */
+	0x00,	/* 0x76 */						0x00,	/* 0x77 */
+	0x00,	/* 0x78 */						0x00,	/* 0x79 */
+	0x00,	/* 0x7a */						0x00,	/* 0x7b */
+	0x00,	/* 0x7c */						0x00,	/* 0x7d */
+	0x54,	/* 0x7e Alt SysRq */			0xc6,	/* 0x7f Control Break */	
+};
+
+
+// Key constants from vl.h
+#define QEMU_KEY_ESC1(c) ((c) | 0xe100)
+#define QEMU_KEY_BACKSPACE  0x007f
+#define QEMU_KEY_UP         QEMU_KEY_ESC1('A')
+#define QEMU_KEY_DOWN       QEMU_KEY_ESC1('B')
+#define QEMU_KEY_RIGHT      QEMU_KEY_ESC1('C')
+#define QEMU_KEY_LEFT       QEMU_KEY_ESC1('D')
+#define QEMU_KEY_HOME       QEMU_KEY_ESC1(1)
+#define QEMU_KEY_END        QEMU_KEY_ESC1(4)
+#define QEMU_KEY_PAGEUP     QEMU_KEY_ESC1(5)
+#define QEMU_KEY_PAGEDOWN   QEMU_KEY_ESC1(6)
+#define QEMU_KEY_DELETE     QEMU_KEY_ESC1(3)
+
+#define QEMU_KEY_CTRL_UP         0xe400
+#define QEMU_KEY_CTRL_DOWN       0xe401
+#define QEMU_KEY_CTRL_LEFT       0xe402
+#define QEMU_KEY_CTRL_RIGHT      0xe403
+#define QEMU_KEY_CTRL_HOME       0xe404
+#define QEMU_KEY_CTRL_END        0xe405
+#define QEMU_KEY_CTRL_PAGEUP     0xe406
+#define QEMU_KEY_CTRL_PAGEDOWN   0xe407
+
+
+int
+main(int argc, char **argv)
+{
+	BPath path = argv[0];
+	path.GetParent(&path);
+	path.Append("share/qemu");
+	bios_dir = path.Path();
+
+	QEMUApplication *app = new QEMUApplication(argc, argv);
+	app->Run();
+	delete app;
+	return 0;
+}
+
+
+QEMUApplication::QEMUApplication(int argc, char **argv)
+	:	BApplication("application/x-vnd.mmlr.QEMU"),
+		fThread(0),
+		fWindow(NULL)
+{
+	gApplication = this;
+
+	fArgC = argc;
+	fArgV = argv;
+
+	fThread = spawn_thread(&RunQEMUMain, "qemu_main", B_LOW_PRIORITY, this);
+	resume_thread(fThread);
+}
+
+
+bool
+QEMUApplication::QuitRequested()
+{
+	qemu_system_shutdown_request();
+	return true;
+}
+
+
+void
+QEMUApplication::InitDisplay()
+{
+	fWindow = new QEMUWindow();
+	fWindow->Show();
+}
+
+
+int32
+QEMUApplication::RunQEMUMain(void *arg)
+{
+	QEMUApplication *app = (QEMUApplication *)arg;
+	qemu_main(app->fArgC, app->fArgV);
+	app->PostMessage(B_QUIT_REQUESTED);
+	return B_OK;
+}
+
+
+QEMUWindow::QEMUWindow()
+	:	BWindow(BRect(100, 100, 150, 150), "QEMU", B_TITLED_WINDOW,
+			B_QUIT_ON_WINDOW_CLOSE | B_NOT_RESIZABLE)
+{
+	gWindow = this;
+	fView = new QEMUView(Bounds());
+	AddChild(fView);
+	fView->MakeFocus();
+}
+
+
+QEMUView::QEMUView(BRect frame)
+	:	BView(frame, "fView", B_FOLLOW_ALL, B_WILL_DRAW),
+		fBitmap(NULL)
+{
+	gView = this;
+	fBitmap = new BBitmap(frame, 0, B_RGBA32);
+	AddFilter(new BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE, &MessageFilter));
+}
+
+
+QEMUView::~QEMUView()
+{
+	if (gFullScreen)
+		BScreen().SetMode(&fDisplayMode);
+}
+
+
+void
+QEMUView::UpdateFullScreen()
+{
+	if (!gFullScreen)
+		return;
+
+	BScreen screen;
+	display_mode current;
+	display_mode *modes;
+	display_mode *mode;
+	uint32 count;
+
+	screen.GetMode(&current);
+	screen.GetModeList(&modes, &count);
+
+	for (uint32 i = 0; i < count; i++) {
+		mode = &modes[i];
+		if (mode->virtual_width == gWidth
+			&& mode->virtual_height == gHeight
+			&& mode->space == current.space) {
+			screen.SetMode(mode);
+			break;
+		}
+	}
+
+	gWindow->MoveTo(0, 0);
+}
+
+
+void
+QEMUView::CenterMouse(bool &warp)
+{
+	BRect window = gWindow->Frame();
+	BPoint center = window.LeftTop() + gCenter;
+	set_mouse_position((int32)center.x, (int32)center.y);
+	warp = true;
+}
+
+
+void
+QEMUView::StartGrab(bool &grab)
+{
+	gApplication->HideCursor();
+	gWindow->SetTitle("QEMU - Press Ctrl-Alt to exit grab");
+	grab = true;
+}
+
+
+void
+QEMUView::EndGrab(bool &grab, int32 modifiers)
+{
+	gApplication->ShowCursor();
+	gWindow->SetTitle("QEMU");
+	grab = false;
+
+	// reset any set modifiers
+	if (modifiers & B_LEFT_SHIFT_KEY)
+		kbd_put_keycode(0xaa);
+	if (modifiers & B_RIGHT_SHIFT_KEY)
+		kbd_put_keycode(0xb6);
+
+	if (modifiers & B_LEFT_COMMAND_KEY)
+		kbd_put_keycode(0xb8);
+	if (modifiers & B_RIGHT_COMMAND_KEY) {
+		kbd_put_keycode(0xe0);
+		kbd_put_keycode(0xb8);
+	}
+
+	if (modifiers & B_LEFT_CONTROL_KEY)
+		kbd_put_keycode(0x9d);
+	if (modifiers & B_RIGHT_CONTROL_KEY) {
+		kbd_put_keycode(0xe0);
+		kbd_put_keycode(0x9d);
+	}
+
+	if (modifiers & B_LEFT_OPTION_KEY) {
+		kbd_put_keycode(0xe0);
+		kbd_put_keycode(0xdb);
+	}
+	if (modifiers & B_RIGHT_OPTION_KEY) {
+		kbd_put_keycode(0xe0);
+		kbd_put_keycode(0xdc);
+	}
+}
+
+
+filter_result
+QEMUView::MessageFilter(BMessage *message, BHandler **target,
+	BMessageFilter *filter)
+{
+	static bool sGrabInput = false;
+	static bool sMouseWarp = false;
+	static int32 sMouseButtons = 0;
+	bool keyDown = false;
+
+	switch (message->what) {
+		case B_KEY_DOWN:
+		case B_UNMAPPED_KEY_DOWN:
+			keyDown = true;
+			// fall
+
+		case B_KEY_UP:
+		case B_UNMAPPED_KEY_UP: {
+			int32 modifiers;
+			message->FindInt32("modifiers", &modifiers);
+
+			int32 key;
+			message->FindInt32("key", &key);
+			uint8 keycode = haiku_to_pc_key[(uint8)key];
+
+			int32 mask = (B_COMMAND_KEY | B_CONTROL_KEY);
+			if (!keyDown && sGrabInput && modifiers & mask
+				&& (key == 0x5d || key == 0x5c)) {
+					EndGrab(sGrabInput, modifiers);
+					return B_SKIP_MESSAGE;
+			}
+
+			if (keyDown && (modifiers & mask) == mask) {
+				switch (key) {
+					case 0x3f: { /* f - fullscreen */
+						BScreen screen;
+						if (!gFullScreen) {
+							screen.GetMode(&gView->fDisplayMode);
+							gWindow->MoveTo(0, 0);
+							gFullScreen = true;
+						} else {
+							screen.SetMode(&gView->fDisplayMode);
+							gWindow->MoveTo(gView->fWindowLocation);
+							gFullScreen = false;
+						}
+
+						UpdateFullScreen();
+						if (is_graphic_console()) {
+							vga_hw_invalidate();
+							vga_hw_update();
+						}
+
+						return B_SKIP_MESSAGE;
+					} break;
+
+					case 0x52: { /* m - pseudo fullscreen */
+						BPoint location = gWindow->Frame().LeftTop();
+						if (location.x == 0 && location.y == 0)
+							gWindow->MoveTo(gPreviousLocation);
+						else {
+							gPreviousLocation = location;
+							gWindow->MoveTo(0, 0);
+						}
+
+						if (is_graphic_console()) {
+							vga_hw_invalidate();
+							vga_hw_update();
+						}
+
+						return B_SKIP_MESSAGE;
+					} break;
+
+					case 0x12 ... 0x1a: { /* 1 to 9 - switch console */
+						console_select(key - 0x12);
+						if (is_graphic_console()) {
+							vga_hw_invalidate();
+							vga_hw_update();
+						}
+
+						return B_SKIP_MESSAGE;
+					} break;
+				}
+			} else if (!is_graphic_console()) {
+				if (!keyDown)
+					return B_SKIP_MESSAGE;
+
+				int32 rawChar;
+				message->FindInt32("raw_char", &rawChar);
+
+				int keysym = 0;
+				if (modifiers & (B_LEFT_CONTROL_KEY | B_RIGHT_CONTROL_KEY)) {
+					switch(rawChar) {
+						case B_UP_ARROW: keysym = QEMU_KEY_CTRL_UP; break;
+						case B_DOWN_ARROW: keysym = QEMU_KEY_CTRL_DOWN; break;
+						case B_LEFT_ARROW: keysym = QEMU_KEY_CTRL_LEFT; break;
+						case B_RIGHT_ARROW: keysym = QEMU_KEY_CTRL_RIGHT; break;
+						case B_HOME: keysym = QEMU_KEY_CTRL_HOME; break;
+						case B_END: keysym = QEMU_KEY_CTRL_END; break;
+						case B_PAGE_UP: keysym = QEMU_KEY_CTRL_PAGEUP; break;
+						case B_PAGE_DOWN: keysym = QEMU_KEY_CTRL_PAGEDOWN; break;
+					}
+				} else {
+					switch(rawChar) {
+						case B_UP_ARROW: keysym = QEMU_KEY_UP; break;
+						case B_DOWN_ARROW: keysym = QEMU_KEY_DOWN; break;
+						case B_LEFT_ARROW: keysym = QEMU_KEY_LEFT; break;
+						case B_RIGHT_ARROW: keysym = QEMU_KEY_RIGHT; break;
+						case B_HOME: keysym = QEMU_KEY_HOME; break;
+						case B_END: keysym = QEMU_KEY_END; break;
+						case B_PAGE_UP: keysym = QEMU_KEY_PAGEUP; break;
+						case B_PAGE_DOWN: keysym = QEMU_KEY_PAGEDOWN; break;
+						case B_BACKSPACE: keysym = QEMU_KEY_BACKSPACE; break;
+						case B_DELETE: keysym = QEMU_KEY_DELETE; break;
+					}
+				}
+
+				if (keysym)
+					kbd_put_keysym(keysym);
+				else {
+					const char *bytes;
+					if (message->FindString("bytes", &bytes) == B_OK && bytes[0] != 0)
+						kbd_put_keysym(bytes[0]);
+				}
+				return B_SKIP_MESSAGE;
+			}
+
+			if (keycode & 0x80)
+				kbd_put_keycode(0xe0);
+
+			if (keyDown)
+				kbd_put_keycode(keycode & 0x7f);
+			else
+				kbd_put_keycode(keycode | 0x80);
+
+			return B_SKIP_MESSAGE;
+		} break;
+
+		case B_MOUSE_MOVED: {
+			if (!sGrabInput)
+				break;
+
+			if (sMouseWarp) {
+				sMouseWarp = false;
+				return B_SKIP_MESSAGE;
+			}
+
+			BPoint where;
+			message->FindPoint("where", &where);
+			BPoint delta = where - gCenter;
+
+			// Haiku buttons are the same as QEMU
+			kbd_mouse_event((int)delta.x, (int)delta.y, 0, sMouseButtons);
+
+			CenterMouse(sMouseWarp);
+			return B_SKIP_MESSAGE;
+		} break;
+
+		case B_MOUSE_DOWN:
+		case B_MOUSE_UP: {
+			int32 buttons;
+			message->FindInt32("buttons", &buttons);
+
+			if (!sGrabInput) {
+				if (message->what == B_MOUSE_DOWN
+					&& (buttons & B_PRIMARY_MOUSE_BUTTON)) {
+					CenterMouse(sMouseWarp);
+					StartGrab(sGrabInput);
+				}
+				break;
+			}
+
+			sMouseButtons = buttons;
+			// Haiku buttons are the same as QEMU
+			kbd_mouse_event(0, 0, 0, sMouseButtons);
+			return B_SKIP_MESSAGE;
+		} break;
+
+		case B_MOUSE_WHEEL_CHANGED: {
+			if (!sGrabInput)
+				break;
+
+			float delta;
+			message->FindFloat("be:wheel_delta_y", &delta);
+			kbd_mouse_event(0, 0, (int)delta, sMouseButtons);
+			return B_SKIP_MESSAGE;
+		} break;
+	}
+
+	return B_DISPATCH_MESSAGE;
+}
+
+
+void
+QEMUView::Update(BPoint point, int width, int height)
+{
+	LockLooper();
+	fBitmap->ImportBits(fFrameBuffer, fFrameBufferSize, fBytesPerRow,
+		fColorSpace, point, point, width, height);
+
+	Draw(BRect(point.x, point.y, point.x + width, point.y + height));
+	UnlockLooper();
+}
+
+
+void
+QEMUView::Draw(BRect updateRect)
+{
+	if (fBitmap == NULL)
+		return;
+
+	DrawBitmap(fBitmap, updateRect, updateRect);
+}
+
+
+void
+QEMUView::UpdateFrameBuffer(int width, int height, uchar *bits,
+	int bytesPerRow, int bitsPerPixel)
+{
+	if (LockLooper()) {
+		delete fBitmap;
+		fBitmap = new BBitmap(BRect(0, 0, width - 1, height - 1), 0, B_RGBA32);
+		fFrameBuffer = bits;
+		fFrameBufferSize = bytesPerRow * height;
+		fBytesPerRow = bytesPerRow;
+
+		switch (bitsPerPixel) {
+			case 32:
+				fColorSpace = B_RGB32;
+				break;
+			case 24:
+				fColorSpace = B_RGB24;
+				break;
+			case 16:
+				fColorSpace = B_RGB16;
+				break;
+			case 15:
+				fColorSpace = B_RGB15;
+				break;
+			case 8:
+				fColorSpace = B_CMAP8;
+				break;
+			default:
+				printf("unsupported display depth %ld\n", bitsPerPixel);
+				break;
+		}
+
+		UnlockLooper();
+	}
+}
+
+
+// QEMU C interface
+extern "C" {
+#include "qemu-common.h"
+#include "sysemu.h"
+#include "console.h"
+
+static	void	haiku_update(DisplayState *ds, int x, int y, int w, int h);
+static	void	haiku_resize(DisplayState *ds);
+static	void	haiku_refresh(DisplayState *ds);
+		void	haiku_display_init(DisplayState *ds, int fullScreen);
+};
+
+
+static void
+haiku_update(DisplayState *ds, int x, int y, int w, int h)
+{
+	//printf("updating x=%d y=%d w=%d h=%d\n", x, y, w, h);
+	gView->Update(BPoint(x, y), w, h);
+}
+
+
+static void
+haiku_resize(DisplayState *ds)
+{
+	//printf("resizing\n");
+	gWidth = ds_get_width(ds);
+	gHeight = ds_get_height(ds);
+	gCenter.x = (int32)(gWidth / 2);
+	gCenter.y = (int32)(gHeight / 2);
+	gWindow->ResizeTo(gWidth - 1, gHeight - 1);
+	gWindow->SetZoomLimits(gWidth, gHeight);
+	gView->UpdateFrameBuffer(ds_get_width(ds), ds_get_height(ds),
+		ds_get_data(ds), ds_get_linesize(ds), ds_get_bits_per_pixel(ds));
+	gView->UpdateFullScreen();
+}
+
+
+static void
+haiku_refresh(DisplayState *ds)
+{
+	//printf("refreshing\n");
+	if (is_graphic_console())
+		vga_hw_update();
+}
+
+
+void
+haiku_display_init(DisplayState *ds, int fullScreen)
+{
+	gApplication->InitDisplay();
+	gFullScreen = fullScreen != 0;
+
+	DisplayChangeListener *displayChangeListener
+		= (DisplayChangeListener *)qemu_mallocz(sizeof(DisplayChangeListener));
+	displayChangeListener->dpy_update = haiku_update;
+	displayChangeListener->dpy_resize = haiku_resize;
+	displayChangeListener->dpy_refresh = haiku_refresh;
+	register_displaychangelistener(ds, displayChangeListener);
+}
diff -urN qemu-0.10.4/haiku.h qemu-0.10.4-haiku/haiku.h
--- qemu-0.10.4/haiku.h	1970-01-01 00:00:00.000000000 +0000
+++ qemu-0.10.4-haiku/haiku.h	2009-05-18 02:05:03.000000000 +0000
@@ -0,0 +1,95 @@
+/*
+ * QEMU Haiku display driver
+ * 
+ * Copyright (c) 2005-2009 Michael Lotz
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef _HAIKU_H_
+#define _HAIKU_H_
+#include <Accelerant.h>
+#include <Application.h>
+#include <Bitmap.h>
+#include <MessageFilter.h>
+#include <View.h>
+#include <Window.h>
+
+class QEMUWindow;
+class QEMUView;
+
+class QEMUApplication : public BApplication {
+public:
+							QEMUApplication(int argc, char **argv);
+
+virtual	bool				QuitRequested();
+		void				InitDisplay();
+
+private:
+static	int32				RunQEMUMain(void *arg);
+
+		int					fArgC;
+		char **				fArgV;
+
+		thread_id			fThread;
+		QEMUWindow *		fWindow;
+};
+
+
+class QEMUWindow : public BWindow {
+public:
+							QEMUWindow();
+
+private:
+		QEMUView *			fView;
+};
+
+
+class QEMUView : public BView {
+public:
+							QEMUView(BRect frame);
+virtual						~QEMUView();
+
+		void				Update(BPoint point, int width, int height);
+virtual	void				Draw(BRect updateRect);
+
+		void				UpdateFrameBuffer(int width, int height,
+								uchar *bits, int bytesPerRow,
+								int bitsPerPixel);
+
+static	void				UpdateFullScreen();
+static	void				CenterMouse(bool &warp);
+static	void				StartGrab(bool &grab);
+static	void				EndGrab(bool &grab, int32 modifiers);
+
+private:
+static	filter_result		MessageFilter(BMessage *message, BHandler **target,
+								BMessageFilter *filter);
+
+		BBitmap *			fBitmap;
+		BPoint				fWindowLocation;
+		display_mode		fDisplayMode;
+
+		uint8 *				fFrameBuffer;
+		uint32				fFrameBufferSize;
+		uint32				fBytesPerRow;
+		color_space			fColorSpace;
+};
+
+#endif
diff -urN qemu-0.10.4/kqemu/Makefile qemu-0.10.4-haiku/kqemu/Makefile
--- qemu-0.10.4/kqemu/Makefile	2009-05-18 13:07:20.000000000 +0000
+++ qemu-0.10.4-haiku/kqemu/Makefile	2009-05-18 04:05:48.000000000 +0000
@@ -44,6 +44,7 @@
       install.sh kqemu-linux.c kqemu.h \
       kqemu-kernel.h \
       kqemu-freebsd.c Makefile.freebsd \
+      kqemu-haiku.c Makefile.haiku \
       kqemu-win32.c kqemu.sys kqemu.inf Makefile.winnt \
       kqemu-doc.texi kqemu-doc.html kqemu-tech.texi kqemu-tech.html
 FILES+=common/Makefile common/insn_table.h  common/kqemu_int.h \
diff -urN qemu-0.10.4/kqemu/Makefile.haiku qemu-0.10.4-haiku/kqemu/Makefile.haiku
--- qemu-0.10.4/kqemu/Makefile.haiku	1970-01-01 00:00:00.000000000 +0000
+++ qemu-0.10.4-haiku/kqemu/Makefile.haiku	2009-05-18 04:11:00.000000000 +0000
@@ -0,0 +1,27 @@
+OBJECTS = kqemu-haiku.o kqemu-mod-i386.o
+TARGET = kqemu
+CFLAGS = -O2 -D_KERNEL_MODE=1 -fomit-frame-pointer -fno-strict-aliasing -fno-pic
+
+all: $(OBJECTS) $(TARGET)
+
+clean:
+	rm -f $(OBJECTS) $(TARGET)
+	make -C common clean
+
+install: $(OBJECTS) $(TARGET)
+	copyattr -d kqemu /boot/home/config/add-ons/kernel/drivers/bin
+	ln -sf /boot/home/config/add-ons/kernel/drivers/bin/kqemu /boot/home/config/add-ons/kernel/drivers/dev/misc/kqemu
+	rm kqemu-mod-i386.o
+	sync
+
+kqemu-mod-i386.o:
+	make -C common all
+
+%.o: %.c
+	gcc $(CFLAGS) -c $< -o $@
+
+%.o: %.S
+	gcc -c $< -o $@
+
+$(TARGET): $(OBJECTS)
+	gcc -Wall -nostart -nostdlib /boot/develop/lib/x86/_KERNEL_ $(OBJECTS) -o $(TARGET)
diff -urN qemu-0.10.4/kqemu/common/Makefile qemu-0.10.4-haiku/kqemu/common/Makefile
--- qemu-0.10.4/kqemu/common/Makefile	2009-05-18 13:07:20.000000000 +0000
+++ qemu-0.10.4-haiku/kqemu/common/Makefile	2009-05-18 04:01:43.000000000 +0000
@@ -47,6 +47,11 @@
 ifeq ($(ARCH), x86_64)
 COMMON_CFLAGS+=-mno-red-zone
 endif
+
+ifdef CONFIG_HAIKU
+COMMON_CFLAGS+=-fno-pic
+endif
+
 CFLAGS=$(COMMON_CFLAGS)
 MON_CFLAGS=$(COMMON_CFLAGS)
 KERNEL_CFLAGS=$(COMMON_CFLAGS)
diff -urN qemu-0.10.4/kqemu/common/kqemu_int.h qemu-0.10.4-haiku/kqemu/common/kqemu_int.h
--- qemu-0.10.4/kqemu/common/kqemu_int.h	2009-05-18 13:07:20.000000000 +0000
+++ qemu-0.10.4-haiku/kqemu/common/kqemu_int.h	2009-05-18 03:50:09.000000000 +0000
@@ -61,6 +61,9 @@
 //#define PROFILE_INTERP2
 //#define PROFILE_INSN
 
+#ifdef PAGE_SIZE
+#undef PAGE_SIZE
+#endif
 
 #define PAGE_SHIFT 12
 #define PAGE_SIZE  (1 << PAGE_SHIFT)
diff -urN qemu-0.10.4/kqemu/configure qemu-0.10.4-haiku/kqemu/configure
--- qemu-0.10.4/kqemu/configure	2009-05-18 13:07:20.000000000 +0000
+++ qemu-0.10.4-haiku/kqemu/configure	2009-05-18 04:02:56.000000000 +0000
@@ -82,6 +82,7 @@
 fmod_lib=""
 fmod_inc=""
 linux="no"
+haiku="no"
 kqemu="no"
 kernel_path=""
 cocoa="no"
@@ -117,6 +118,13 @@
 bsd="yes"
 darwin="yes"
 ;;
+Haiku)
+haiku="yes"
+CFLAGS="-O2 -fno-pic -fomit-frame-pointer"
+if [ "$cpu" = "i386" -o "$cpu" = "x86_64" ] ; then
+    kqemu="yes"
+fi
+;;
 *)
 oss="yes"
 linux="yes"
@@ -349,6 +357,10 @@
     echo "CONFIG_KBUILD26=yes" >> $config_mak
   fi
 fi
+if test $haiku = "yes" ; then
+  echo "CONFIG_HAIKU=yes" >> $config_mak
+  echo "#define CONFIG_HAIKU 1" >> config_h
+fi
 echo "SRC_PATH=$source_path" >> $config_mak
 
 rm -f $TMPO $TMPC $TMPE $TMPS
diff -urN qemu-0.10.4/kqemu/kqemu-haiku.c qemu-0.10.4-haiku/kqemu/kqemu-haiku.c
--- qemu-0.10.4/kqemu/kqemu-haiku.c	1970-01-01 00:00:00.000000000 +0000
+++ qemu-0.10.4-haiku/kqemu/kqemu-haiku.c	2009-05-18 11:42:56.000000000 +0000
@@ -0,0 +1,466 @@
+/*
+ * Haiku kernel wrapper for KQEMU
+ *
+ * Copyright (C) 2007-2009 Michael Lotz
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <SupportDefs.h>
+#include <drivers/Drivers.h>
+#include <drivers/KernelExport.h>
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define IS_USER_ADDRESS(x)	true
+
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef signed int int32_t;
+typedef unsigned int uint32_t;
+typedef unsigned long long uint64_t;
+
+#include "kqemu-kernel.h"
+
+#define DEVICE_NAME "misc/kqemu"
+#define MAX_LOCKED_PAGES (524288 / 4)
+#define PAGE_SHIFT 12
+
+
+struct kqemu_user_page {
+	team_id	team;
+	void *	address;
+};
+
+
+team_id
+find_current_team()
+{
+	thread_info info;
+	get_thread_info(find_thread(NULL), &info);
+	return info.team;
+}
+
+
+/* Lock the page at virtual address 'userAddress' and return its
+   physical address (page index). Return a host OS private user page
+   identifier or NULL if error */
+struct kqemu_user_page *
+kqemu_lock_user_page(unsigned long *pageIndex, unsigned long userAddress)
+{
+	physical_entry entries[2];
+	struct kqemu_user_page *userPage
+		= (struct kqemu_user_page *)malloc(sizeof(struct kqemu_user_page));
+	if (userPage == NULL) {
+		kqemu_log("kqemu: failed to allocate user page when trying to lock\n");
+		return NULL;
+	}
+
+	if (lock_memory((void *)userAddress, B_PAGE_SIZE, 0) != B_OK) {
+		kqemu_log("kqemu: failed to lock memory for address 0x%08lx\n",
+			userAddress);
+		free(userPage);
+		return NULL;
+	}
+
+	if (get_memory_map((void *)userAddress, B_PAGE_SIZE, entries, 2) != B_OK) {
+		kqemu_log("kqemu: failed to get memory map for 0x%08lx\n", userAddress);
+		unlock_memory((void *)userAddress, B_PAGE_SIZE, 0);
+		free(userPage);
+		return NULL;
+	}
+
+	userPage->team = find_current_team();
+	userPage->address = (void *)userAddress;
+	*pageIndex = (unsigned long)entries[0].address >> PAGE_SHIFT;
+	return userPage;
+}
+
+
+void
+kqemu_unlock_user_page(struct kqemu_user_page *page)
+{
+	if (unlock_memory_etc(page->team, page->address, B_PAGE_SIZE, 0) != B_OK) {
+		kqemu_log("kqemu: failed to unlock memory for address 0x%08lx\n", page);
+		dprintf("unlocking user page from team: %ld\n", find_current_team());
+		panic("fail");
+	}
+
+	free(page);
+}
+
+
+/* Allocate a new page and return its physical address (page
+   index). Return a host OS private page identifier or NULL if
+   error */
+struct kqemu_page *
+kqemu_alloc_zeroed_page(unsigned long *pageIndex)
+{
+	void *page = NULL;
+	physical_entry entries[2];
+
+	if (create_area("kqemu alloc area", &page, B_ANY_KERNEL_ADDRESS,
+		B_PAGE_SIZE, B_FULL_LOCK, B_KERNEL_READ_AREA
+		| B_KERNEL_WRITE_AREA) < B_OK || page == NULL) {
+		kqemu_log("kqemu: failed to create area for zeroed page\n");
+		return NULL;
+	}
+
+	memset(page, 0, B_PAGE_SIZE);
+	get_memory_map(page, B_PAGE_SIZE, entries, 2);
+	*pageIndex = (unsigned long)entries[0].address >> PAGE_SHIFT;
+	return (struct kqemu_page *)page;
+}
+
+
+void
+kqemu_free_page(struct kqemu_page *page)
+{
+	delete_area(area_for(page));
+}
+
+
+/* Return a host kernel address of the physical page whose private
+   identifier is 'page' */
+void *
+kqemu_page_kaddr(struct kqemu_page *page)
+{
+	return (void *)page;
+}
+
+
+/* Allocate 'size' bytes of memory in host kernel address space (size
+   is a multiple of 4 KB) and return the address or NULL if error. The
+   allocated memory must be marked as executable by the host kernel
+   and must be page aligned. On i386 with PAE (but not on x86_64), it
+   must be allocated in the first 4 GB of physical memory. */
+void *
+kqemu_vmalloc(unsigned int size)
+{
+	void *memory = NULL;
+	if (create_area("kqemu alloc area", &memory, B_ANY_KERNEL_ADDRESS,
+		size, B_FULL_LOCK, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA) < B_OK
+		|| memory == NULL) {
+		kqemu_log("kqemu: failed to create area for kernel memory\n");
+		return NULL;
+	}
+
+	return memory;
+}
+
+
+void
+kqemu_vfree(void *pointer)
+{
+	delete_area(area_for(pointer));
+}
+
+
+/* Convert a page aligned address inside a memory area allocated by
+   kqemu_vmalloc() to a physical address (page index) */
+unsigned long
+kqemu_vmalloc_to_phys(const void *address)
+{
+	physical_entry entries[2];
+	get_memory_map(address, B_PAGE_SIZE, entries, 2);
+	return (unsigned long)entries[0].address >> PAGE_SHIFT;
+}
+
+
+/* Map a IO area in the kernel address space and return its
+   address. Return NULL if error or not implemented. This function is
+   only used if an APIC is detected on the host CPU. */
+void *
+kqemu_io_map(unsigned long pageIndex, unsigned int size)
+{
+	return NULL;
+}
+
+
+/* Unmap the IO area */
+void
+kqemu_io_unmap(void *pointer, unsigned int size)
+{
+}
+
+
+/* return TRUE if a signal is pending (i.e. the guest must stop
+   execution) */
+int
+kqemu_schedule(void)
+{
+	return (has_signals_pending(NULL) != 0);
+}
+
+
+char log_buf[B_PAGE_SIZE];
+
+void
+kqemu_log(const char *fmt, ...)
+{
+    va_list ap;
+    va_start(ap, fmt);
+    vsprintf(log_buf, fmt, ap);
+    dprintf(log_buf);
+    va_end(ap);
+}
+
+
+/* Driver Interface */
+
+static struct kqemu_global_state *sKQEMUGlobalState;
+
+struct kqemu_instance {
+	sem_id				lock;
+	struct kqemu_state *state;
+};
+
+
+static status_t
+kqemu_open(const char *name, uint32 mode, void **cookie)
+{
+	unsigned long dummy;
+	struct kqemu_instance *instance;
+	instance = (struct kqemu_instance *)kqemu_vmalloc(B_PAGE_SIZE);
+	if (!instance)
+		return B_NO_MEMORY;
+
+	instance->lock = create_sem(1, "kqemu lock");
+	instance->state = NULL;
+	*cookie = (void *)instance;
+	return 0;
+}
+
+
+static status_t
+kqemu_close(void *cookie)
+{
+	(void)cookie;
+	return B_OK;
+}
+
+
+static status_t
+kqemu_free(void *cookie)
+{
+	struct kqemu_instance *instance = (struct kqemu_instance *)cookie;
+
+	acquire_sem(instance->lock);
+	if (instance->state) {
+		kqemu_delete(instance->state);
+		instance->state = NULL;
+	}
+
+	delete_sem(instance->lock);
+	kqemu_vfree(instance);
+	return B_OK;
+}
+
+
+static status_t
+kqemu_control(void *cookie, uint32 op, void *data, size_t length)
+{
+	struct kqemu_instance *instance = (struct kqemu_instance *)cookie;
+	struct kqemu_state *state = instance->state;
+	status_t result = B_ERROR;
+
+	if (acquire_sem(instance->lock) != B_OK)
+		return B_ERROR;
+
+	switch (op) {
+		case KQEMU_INIT:
+		{
+			struct kqemu_init initData;
+			if (state != NULL) {
+				result = B_BUSY;
+				break;
+			}
+
+			if (!IS_USER_ADDRESS(data) || user_memcpy(&initData, data,
+				sizeof(struct kqemu_init)) != B_OK) {
+				result = B_BAD_ADDRESS;
+				break;
+			}
+
+			state = kqemu_init(&initData, sKQEMUGlobalState);
+			if (state == NULL) {
+				result = B_NO_MEMORY;
+				break;
+			}
+
+			instance->state = state;
+			result = B_OK;
+			break;
+		}
+
+		case KQEMU_SET_PHYS_MEM:
+		{
+			struct kqemu_phys_mem physicalMemory;
+			if (state == NULL) {
+				result = B_NO_INIT;
+				break;
+			}
+
+			if (!IS_USER_ADDRESS(data) || user_memcpy(&physicalMemory, data,
+				sizeof(struct kqemu_phys_mem)) != B_OK) {
+				result = B_BAD_ADDRESS;
+				break;
+			}
+
+			result = kqemu_set_phys_mem(state, &physicalMemory);
+			break;
+		}
+
+		case KQEMU_EXEC:
+		{
+			struct kqemu_cpu_state *cpuState;
+			if (state == NULL) {
+				result = B_NO_INIT;
+				break;
+			}
+
+			if (!IS_USER_ADDRESS(data)) {
+				result = B_BAD_ADDRESS;
+				break;
+			}
+
+			cpuState = kqemu_get_cpu_state(state);
+			if (user_memcpy(cpuState, data,
+				sizeof(struct kqemu_cpu_state)) != B_OK) {
+				result = B_BAD_ADDRESS;
+				break;
+			}
+
+			result = kqemu_exec(state);
+
+			if (user_memcpy(data, cpuState,
+				sizeof(struct kqemu_cpu_state)) != B_OK) {
+				result = B_BAD_ADDRESS;
+				break;
+			}
+
+			break;
+		}
+
+		case KQEMU_GET_VERSION:
+		{
+			int version = KQEMU_VERSION;
+			if (!IS_USER_ADDRESS(data) || user_memcpy(data, &version,
+				sizeof(int)) != B_OK)
+				result = B_BAD_ADDRESS;
+			else
+				result = B_OK;
+
+			break;
+		}
+	}
+
+	release_sem_etc(instance->lock, 1, B_DO_NOT_RESCHEDULE);
+	return result;
+}
+
+
+static status_t
+kqemu_read(void *cookie, off_t pos, void *buffer, size_t *len)
+{
+	(void)cookie;
+	(void)pos;
+	(void)buffer;
+	(void)len;
+	return B_OK;
+}
+
+
+static status_t
+kqemu_write(void *cookie, off_t pos, const void *buffer, size_t *len)
+{
+	(void)cookie;
+	(void)pos;
+	(void)buffer;
+	(void)len;
+	return B_OK;
+}
+
+
+/* Haiku driver API */
+int32 api_version = B_CUR_DRIVER_API_VERSION;
+
+
+status_t
+init_hardware(void)
+{
+	return B_OK;
+}
+
+
+const char **
+publish_devices(void)
+{
+	static const char *devices[] = {
+		DEVICE_NAME,
+		NULL
+	};
+
+	return devices;
+}
+
+
+device_hooks *
+find_device(const char *name)
+{
+	static device_hooks hooks = {
+		&kqemu_open,
+		&kqemu_close,
+		&kqemu_free,
+		&kqemu_control,
+		&kqemu_read,
+		&kqemu_write,
+		NULL,
+		NULL,
+		NULL,
+		NULL
+	};
+
+	if (strcmp(name, DEVICE_NAME) == 0)
+		return &hooks;
+
+	return NULL;
+}
+
+
+status_t
+init_driver(void)
+{
+	dprintf("QEMU Accelerator Module version %d.%d.%d\n",
+		(KQEMU_VERSION >> 16), (KQEMU_VERSION >> 8) & 0xff,
+		(KQEMU_VERSION) & 0xff);
+
+	sKQEMUGlobalState = kqemu_global_init(MAX_LOCKED_PAGES);
+	if (!sKQEMUGlobalState)
+		return B_NO_MEMORY;
+
+	return B_OK;
+}
+
+
+void
+uninit_driver(void)
+{
+	if (sKQEMUGlobalState) {
+		kqemu_global_delete(sKQEMUGlobalState);
+		sKQEMUGlobalState = NULL;
+	}
+}
diff -urN qemu-0.10.4/kqemu/kqemu.h qemu-0.10.4-haiku/kqemu/kqemu.h
--- qemu-0.10.4/kqemu/kqemu.h	2009-05-18 13:07:20.000000000 +0000
+++ qemu-0.10.4-haiku/kqemu/kqemu.h	2009-05-18 04:36:44.000000000 +0000
@@ -143,6 +143,12 @@
 #define KQEMU_GET_VERSION      CTL_CODE(FILE_DEVICE_UNKNOWN, 3, METHOD_BUFFERED, FILE_READ_ACCESS)
 #define KQEMU_MODIFY_RAM_PAGES CTL_CODE(FILE_DEVICE_UNKNOWN, 4, METHOD_BUFFERED, FILE_WRITE_ACCESS)
 #define KQEMU_SET_PHYS_MEM     CTL_CODE(FILE_DEVICE_UNKNOWN, 5, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+#elif defined(__HAIKU__)
+#define KQEMU_EXEC             'kqex'
+#define KQEMU_INIT             'kqin'
+#define KQEMU_GET_VERSION      'kqgv'
+#define KQEMU_MODIFY_RAM_PAGES 'kqmr'
+#define KQEMU_SET_PHYS_MEM     'kqsp'
 #else
 #define KQEMU_EXEC             _IOWR('q', 1, struct kqemu_cpu_state)
 #define KQEMU_INIT             _IOW('q', 2, struct kqemu_init)
diff -urN qemu-0.10.4/kqemu.c qemu-0.10.4-haiku/kqemu.c
--- qemu-0.10.4/kqemu.c	2009-05-18 03:18:38.000000000 +0000
+++ qemu-0.10.4-haiku/kqemu.c	2009-05-18 04:49:07.000000000 +0000
@@ -62,6 +62,8 @@
 
 #ifdef _WIN32
 #define KQEMU_DEVICE "\\\\.\\kqemu"
+#elif defined(__HAIKU__)
+#define KQEMU_DEVICE "/dev/misc/kqemu"
 #else
 #define KQEMU_DEVICE "/dev/kqemu"
 #endif
diff -urN qemu-0.10.4/kqemu.h qemu-0.10.4-haiku/kqemu.h
--- qemu-0.10.4/kqemu.h	2009-05-18 03:18:36.000000000 +0000
+++ qemu-0.10.4-haiku/kqemu.h	2009-05-18 04:41:08.000000000 +0000
@@ -143,6 +143,12 @@
 #define KQEMU_GET_VERSION      CTL_CODE(FILE_DEVICE_UNKNOWN, 3, METHOD_BUFFERED, FILE_READ_ACCESS)
 #define KQEMU_MODIFY_RAM_PAGES CTL_CODE(FILE_DEVICE_UNKNOWN, 4, METHOD_BUFFERED, FILE_WRITE_ACCESS)
 #define KQEMU_SET_PHYS_MEM     CTL_CODE(FILE_DEVICE_UNKNOWN, 5, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+#elif defined(__HAIKU__)
+#define KQEMU_EXEC             'kqex'
+#define KQEMU_INIT             'kqin'
+#define KQEMU_GET_VERSION      'kqgv'
+#define KQEMU_MODIFY_RAM_PAGES 'kqmr'
+#define KQEMU_SET_PHYS_MEM     'kqsp'
 #else
 #define KQEMU_EXEC             _IOWR('q', 1, struct kqemu_cpu_state)
 #define KQEMU_INIT             _IOW('q', 2, struct kqemu_init)
diff -urN qemu-0.10.4/nbd.c qemu-0.10.4-haiku/nbd.c
--- qemu-0.10.4/nbd.c	2009-05-18 03:18:35.000000000 +0000
+++ qemu-0.10.4-haiku/nbd.c	2009-05-17 22:19:55.000000000 +0000
@@ -341,7 +341,7 @@
         return 0;
 }
 
-#ifndef _WIN32
+#if !defined(_WIN32) && !defined(__HAIKU__)
 int nbd_init(int fd, int csock, off_t size, size_t blocksize)
 {
 	TRACE("Setting block size to %lu", (unsigned long)blocksize);
diff -urN qemu-0.10.4/net.c qemu-0.10.4-haiku/net.c
--- qemu-0.10.4/net.c	2009-05-18 03:18:39.000000000 +0000
+++ qemu-0.10.4-haiku/net.c	2009-05-17 22:23:35.000000000 +0000
@@ -943,6 +943,12 @@
     fprintf (stderr, "no tap on AIX\n");
     return -1;
 }
+#elif defined(__HAIKU__)
+static int tap_open(char *ifname, int ifname_size)
+{
+    fprintf(stderr, "no tap on Haiku\n");
+    return -1;
+}
 #else
 static int tap_open(char *ifname, int ifname_size)
 {
diff -urN qemu-0.10.4/osdep.c qemu-0.10.4-haiku/osdep.c
--- qemu-0.10.4/osdep.c	2009-05-18 03:18:37.000000000 +0000
+++ qemu-0.10.4-haiku/osdep.c	2009-05-18 13:05:41.000000000 +0000
@@ -309,3 +309,77 @@
     fcntl(fd, F_SETFL, f | O_NONBLOCK);
 }
 #endif
+
+
+#ifdef __HAIKU__
+/*
+ The reason for the following mess is that somehow large allocations seem
+ to cause memory curruption. Most likely this is a bug in either Haiku or
+ QEMU. Since I wasn't able to repoduce the issue with other Haiku software
+ my first guess would go to QEMU, but who knows. In any case the hack below
+ makes larger allocations (>= 1MB) using areas instead of using the heap
+ to work around said issue. TODO: remove this when the reason is found/fixed!
+*/
+
+#include <OS.h>
+
+#undef malloc
+#undef realloc
+#undef free
+
+static area_id sHeapArea = 0;
+
+void *
+checked_malloc(size_t size)
+{
+	void *result = NULL;
+	if (size >= 1024 * 1024) {
+		if (create_area("qemu large alloc area", &result, B_ANY_ADDRESS,
+			((size + B_PAGE_SIZE - 1) / B_PAGE_SIZE) * B_PAGE_SIZE, B_NO_LOCK,
+			B_READ_AREA | B_WRITE_AREA) < B_OK)
+			result = NULL;
+	} else {
+		result = malloc(size);
+		if (sHeapArea == 0)
+			sHeapArea = area_for(result);
+	}
+
+	return result;
+}
+
+
+void *
+checked_realloc(void *original, size_t newSize)
+{
+	area_id area;
+	void *result = NULL;
+	if (original == NULL)
+		return checked_malloc(newSize);
+
+	area = area_for(original);
+	if (area == sHeapArea)
+		result = realloc(original, newSize);
+	else {
+		if (resize_area(area,
+			((newSize + B_PAGE_SIZE - 1) / B_PAGE_SIZE) * B_PAGE_SIZE) == B_OK)
+			result = original;
+	}
+
+	return result;
+}
+
+
+void
+checked_free(void *pointer)
+{
+	area_id area;
+	if (pointer == NULL)
+		return;
+
+	area = area_for(pointer);
+	if (area == sHeapArea)
+		free(pointer);
+	else
+		delete_area(area);
+}
+#endif
diff -urN qemu-0.10.4/osdep.h qemu-0.10.4-haiku/osdep.h
--- qemu-0.10.4/osdep.h	2009-05-18 03:18:37.000000000 +0000
+++ qemu-0.10.4-haiku/osdep.h	2009-05-17 23:31:19.000000000 +0000
@@ -94,4 +94,19 @@
 #define qemu_gettimeofday(tp) gettimeofday(tp, NULL);
 #endif /* !_WIN32 */
 
+#ifdef __HAIKU__
+// until Haiku has proper ipv6 support
+#ifndef INET6_ADDRSTRLEN
+#define INET6_ADDRSTRLEN 46
+#endif
+
+void *checked_malloc(size_t size);
+void *checked_realloc(void *original, size_t newSize);
+void checked_free(void *pointer);
+
+#define malloc(x)		checked_malloc(x)
+#define realloc(x, y)	checked_realloc(x, y)
+#define free(x)			checked_free(x)
+#endif
+
 #endif
diff -urN qemu-0.10.4/rules.mak qemu-0.10.4-haiku/rules.mak
--- qemu-0.10.4/rules.mak	2009-05-18 03:18:39.000000000 +0000
+++ qemu-0.10.4-haiku/rules.mak	2009-05-18 08:22:21.000000000 +0000
@@ -1,3 +1,5 @@
+%.o: %.cpp
+	$(CC) -I. -c -o $@ $<
 
 %.o: %.c
 	$(call quiet-command,$(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $<,"  CC    $(TARGET_DIR)$@")
diff -urN qemu-0.10.4/vl.c qemu-0.10.4-haiku/vl.c
--- qemu-0.10.4/vl.c	2009-05-18 03:18:35.000000000 +0000
+++ qemu-0.10.4-haiku/vl.c	2009-05-18 01:52:07.000000000 +0000
@@ -4574,6 +4574,10 @@
 
 #endif
 
+#ifdef __HAIKU__
+#define main	qemu_main
+#endif
+
 int main(int argc, char **argv, char **envp)
 {
 #ifdef CONFIG_GDBSTUB
@@ -5646,6 +5650,9 @@
 #elif defined(CONFIG_COCOA)
                 if (sdl || !vnc_display)
                     cocoa_display_init(ds, full_screen);
+#elif defined(CONFIG_HAIKU)
+				if (!vnc_display)
+					haiku_display_init(ds, full_screen);
 #endif
             }
     }
