Release 950817

Thu Aug 17 19:30:14 1995  Alexandre Julliard  <julliard@sunsite.unc.edu>

	* [*/Makefile.in]
	Removed winelibclean target, as it doesn't work anyway.

	* [controls/button.c]
	Avoid drawing the focus rectangle outside of the button.

	* [controls/widgets.c]
	Fixed bug with the size of the reserved bytes for the Edit
	control (caused Eudora to crash).

	* [debugger/*] [include/debugger.h]
	Unified debugger address handling. Segmented and linear addresses
	are no grouped in a single type DBG_ADDR.
	All commands now accept seg:off addresses.
	Module entry points are now loaded upon first entry to the
	debugger, so that entry points of the loaded executable also
	appear in the symbol table.

	* [include/registers.h] [miscemu/*.c]
	Register macros are now of the form 'AX_reg(context)' instead of 'AX'.
	This makes code less readable, but will prevent a lot of name
	clashes with other definitions. It also avoids a hidden reference
	to the 'context' variable.

	* [ipc/dde_atom.c] [misc/atom.c]
	All *AddAtom and *FindAtom functions now take a SEGPTR parameter,
	to allow supporting integer atoms.
	Moved atom.c to memory/ directory.

	* [loader/task.c]
	Fixed environment allocation to compute the size dynamically.
	Added 'windir' environment variable.
	Fixed GetDOSEnvironment() to return the current task environment.

	* [windows/message.c]
	Fixed bug in MSG_GetWindowForEvent().

Wed Aug  9 11:40:43 1995  Marcus Meissner  <msmeissn@faui01.informatik.uni-erlangen.de>

	* [include/ole.h]
	Added a lot of structures  from my Borland Manual. Neither complete,
	nor 100% right (check please)
	
	* [misc/shell.c]
	Fixed some of the Reg* functions.
	Enhanced ShellExecute.
	Please test: wine "regedit.exe /v" mplayer.exe soundrec.exe
	Do YOU know the format of \WINDOWS\REG.DAT? Mail me please :)

	* [misc/dos_fs.c]
	Make umsdos mounted windows dirs work again.

	* [miscemu/emulate.c]
	Added some comments, preimplementation of subfunction 7.

	* [multimedia/mmsystem.c]
	Implemented mciSendString. not complete, not clean, not
	necessarily working (only checked with a program which uses
 	'cdaudio' (one working program is cool.exe, a shareware waveditor
 	with cdaudio play facilities.)

	* [multimedia/mcicda.c]
	Segptr fixes in DriverProc
	Default cdrom drive in Linux is /dev/cdrom ... usually a symbolic
 	link to your real cdrom device.

Tue Aug  8 19:41:50 CDT 1995 Daniel Schepler <dks2@cec.wustl.edu>

	* [loader/resource.c]
	Don't crash in a LoadString to NULL

	* [loader/resource.c]
	Fixed accelerators to work with modifiers.  (ALT-x modifiers still
 	won't work unless the ALT keypress exited the menu.)

	* [misc/file.c]
	Expand a file to the current offset with an _lwrite of size zero.

	* [misc/file.c]
	Set a newly created file to read-write instead of write-only.
	
Sun Aug  6 20:28:35 1995  Anand Kumria <akumria@ozemail.com.au>

	* [misc/main.c] [include/msdos.h]
	Fixed to return DOS version 6.22, and the correct byte order
	for Windows programs.

Wed Aug  2 12:36:33 1995   Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>

	* [include/options.h] [memory/global.c] [misc/main.c]
	Make the new IPC run-time selectible, disabling it by default.
	(I think it's only useful for libwine, anyway.)

	* [loader/task.c] [memory/selector.c]
	In FreeSelector(), walk up the stack and fix the frames.

	* [objects/dib.c]
	Missing break statement in DIB_SetImageBits_RLE8().
	In GetDIBits(), set the compression flag in the bitmap info to zero.

	* [windows/dialog.c]
	GetNextDlgGroupItem() needs to treat the first child as if it had
	an implicit WS_GROUP bit set.

Mon Jul 31 15:44:47 EDT 1995 Louis-D. Dubeau <ldd@step.polymtl.ca>

	* [misc/dos_fs.c]
	Quick'n dirty fix for the initialisation of the Z: information
	structure.
diff --git a/ANNOUNCE b/ANNOUNCE
index a8b38b9..137878f 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -1,15 +1,14 @@
-This is release 950727 of Wine the MS Windows emulator.  This is still a
+This is release 950817 of Wine the MS Windows emulator.  This is still a
 developer's only release.  There are many bugs and many unimplemented API
 features.  Most applications still do not work.
 
 Patches should be submitted to "wine-new@amscons.com".  Please don't forget
 to include a ChangeLog entry.  I'll make a new release every other Sunday.
 
-WHAT'S NEW with Wine-950727: (see ChangeLog for details)
-	- New configuration scheme based on autoconf (please test it).
-	- DDE communication between separate Wine processes.
-	- Lots of file handling fixes.
-	- Fixes to built-in WINSOCK.DLL.
+WHAT'S NEW with Wine-950817: (see ChangeLog for details)
+	- Built-in debugger improvements.
+	- Multimedia fixes.
+	- IPC can be disabled at run-time.
 	- Lots of bug fixes.
 
 See the README file in the distribution for installation instructions.
@@ -18,11 +17,11 @@
 the release is available at the ftp sites.  The sources will be available
 from the following locations:
 
-    sunsite.unc.edu:/pub/Linux/ALPHA/wine/Wine-950727.tar.gz
-    tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-950727.tar.gz
-    ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-950727.tar.gz
-    ftp.funet.fi:/pub/OS/Linux/ALPHA/Wine/Wine-950727.tar.gz
-    aris.com:/pub/linux/ALPHA/Wine/development/Wine-950727.tar.gz
+    sunsite.unc.edu:/pub/Linux/ALPHA/wine/Wine-950817.tar.gz
+    tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-950817.tar.gz
+    ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-950817.tar.gz
+    ftp.funet.fi:/pub/OS/Linux/ALPHA/Wine/Wine-950817.tar.gz
+    aris.com:/pub/linux/ALPHA/Wine/development/Wine-950817.tar.gz
 
 It should also be available from any site that mirrors tsx-11 or sunsite.
 
diff --git a/ChangeLog b/ChangeLog
index b093b41..29c8497 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,117 @@
 ----------------------------------------------------------------------
+Thu Aug 17 19:30:14 1995  Alexandre Julliard  <julliard@sunsite.unc.edu>
+
+	* [*/Makefile.in]
+	Removed winelibclean target, as it doesn't work anyway.
+
+	* [controls/button.c]
+	Avoid drawing the focus rectangle outside of the button.
+
+	* [controls/widgets.c]
+	Fixed bug with the size of the reserved bytes for the Edit
+	control (caused Eudora to crash).
+
+	* [debugger/*] [include/debugger.h]
+	Unified debugger address handling. Segmented and linear addresses
+	are no grouped in a single type DBG_ADDR.
+	All commands now accept seg:off addresses.
+	Module entry points are now loaded upon first entry to the
+	debugger, so that entry points of the loaded executable also
+	appear in the symbol table.
+
+	* [include/registers.h] [miscemu/*.c]
+	Register macros are now of the form 'AX_reg(context)' instead of 'AX'.
+	This makes code less readable, but will prevent a lot of name
+	clashes with other definitions. It also avoids a hidden reference
+	to the 'context' variable.
+
+	* [ipc/dde_atom.c] [misc/atom.c]
+	All *AddAtom and *FindAtom functions now take a SEGPTR parameter,
+	to allow supporting integer atoms.
+	Moved atom.c to memory/ directory.
+
+	* [loader/task.c]
+	Fixed environment allocation to compute the size dynamically.
+	Added 'windir' environment variable.
+	Fixed GetDOSEnvironment() to return the current task environment.
+
+	* [windows/message.c]
+	Fixed bug in MSG_GetWindowForEvent().
+
+Wed Aug  9 11:40:43 1995  Marcus Meissner  <msmeissn@faui01.informatik.uni-erlangen.de>
+
+	* [include/ole.h]
+	Added a lot of structures  from my Borland Manual. Neither complete,
+	nor 100% right (check please)
+	
+	* [misc/shell.c]
+	Fixed some of the Reg* functions.
+	Enhanced ShellExecute.
+	Please test: wine "regedit.exe /v" mplayer.exe soundrec.exe
+	Do YOU know the format of \WINDOWS\REG.DAT? Mail me please :)
+
+	* [misc/dos_fs.c]
+	Make umsdos mounted windows dirs work again.
+
+	* [miscemu/emulate.c]
+	Added some comments, preimplementation of subfunction 7.
+
+	* [multimedia/mmsystem.c]
+	Implemented mciSendString. not complete, not clean, not
+	necessarily working (only checked with a program which uses
+ 	'cdaudio' (one working program is cool.exe, a shareware waveditor
+ 	with cdaudio play facilities.)
+
+	* [multimedia/mcicda.c]
+	Segptr fixes in DriverProc
+	Default cdrom drive in Linux is /dev/cdrom ... usually a symbolic
+ 	link to your real cdrom device.
+
+Tue Aug  8 19:41:50 CDT 1995 Daniel Schepler <dks2@cec.wustl.edu>
+
+	* [loader/resource.c]
+	Don't crash in a LoadString to NULL
+
+	* [loader/resource.c]
+	Fixed accelerators to work with modifiers.  (ALT-x modifiers still
+ 	won't work unless the ALT keypress exited the menu.)
+
+	* [misc/file.c]
+	Expand a file to the current offset with an _lwrite of size zero.
+
+	* [misc/file.c]
+	Set a newly created file to read-write instead of write-only.
+	
+Sun Aug  6 20:28:35 1995  Anand Kumria <akumria@ozemail.com.au>
+
+	* [misc/main.c] [include/msdos.h]
+	Fixed to return DOS version 6.22, and the correct byte order
+	for Windows programs.
+
+Wed Aug  2 12:36:33 1995   Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>
+
+	* [include/options.h] [memory/global.c] [misc/main.c]
+	Make the new IPC run-time selectible, disabling it by default.
+	(I think it's only useful for libwine, anyway.)
+
+	* [loader/task.c] [memory/selector.c]
+	In FreeSelector(), walk up the stack and fix the frames.
+
+	* [objects/dib.c]
+	Missing break statement in DIB_SetImageBits_RLE8().
+	In GetDIBits(), set the compression flag in the bitmap info to zero.
+
+	* [windows/dialog.c]
+	GetNextDlgGroupItem() needs to treat the first child as if it had
+	an implicit WS_GROUP bit set.
+
+Mon Jul 31 15:44:47 EDT 1995 Louis-D. Dubeau <ldd@step.polymtl.ca>
+
+	* [misc/dos_fs.c]
+	Quick'n dirty fix for the initialisation of the Z: information
+	structure.
+
+----------------------------------------------------------------------
 Sat Jul 22 22:39:09 IDT 1995 Michael Veksler <e1678223@tochnapc2.technion.ac.il>
 
 	* [ipc/*]
@@ -48,7 +161,7 @@
         Added LoadIconHandler. It doesn't do anything yet, but now you
         can use borland help files with winhelp.exe.
 
-Sun Jul 16 11:58:45 1996  Anand Kumria <akumria@ozemail.com.au>
+Sun Jul 16 11:58:45 1995 Anand Kumria <akumria@ozemail.com.au>
 
 	* [misc/main.c]
 	Fixed to return 386 Enhanced mode correctly. Also return the same
diff --git a/Makefile.in b/Makefile.in
index bec1f10..59cd6cb 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -5,8 +5,6 @@
 # distclean:		also remove all files created by configure
 # countryclean:		remove all files which have to be remade if
 #			a different LANGuage is selected
-# winelibclean:		remove all files which differ for the emulator
-#			and the library
 # depend:		create the dependencies
 #
 # Author: Michael Patra   <micky@marie.physik.tu-berlin.de>
@@ -41,47 +39,41 @@
 LIBOBJS = toolkit/toolkit.o
  
 
-
 SUBDIRS = $(COMMONSUBDIRS) $(EMUSUBDIRS)
 
 OBJS = $(COMMONOBJS) $(EMUOBJS)
 
 
-all:
-	for i in $(SUBDIRS); do \
-	( cd $(TOPSRC)/$$i; $(MAKE) 'CC=$(CC)' 'CFLAGS=$(CFLAGS)' 'LD=$(LD)' 'LDCOMBINEFLAGS=$(LDCOMBINEFLAGS)' 'LANG=$(LANG)'); \
-	done
-	$(CC) -o wine $(OBJS) $(LDOPTIONS) $(XDIR) $(XPM_LIB) $(XLIB) $(LDLIBS)
+all: wine wine.sym
+
+wine.sym: wine
 	nm wine | grep -v _compiled | sort >wine.sym
 
+wine: $(SUBDIRS) dummy
+	$(CC) -o wine $(OBJS) $(LDOPTIONS) $(XDIR) $(XPM_LIB) $(XLIB) $(LDLIBS)
+
+$(SUBDIRS): dummy
+	@cd $@; $(MAKE) 'CC=$(CC)' 'CFLAGS=$(CFLAGS)' 'LD=$(LD)' 'LDCOMBINEFLAGS=$(LDCOMBINEFLAGS)' 'LANG=$(LANG)'
+
 depend:
-	for i in $(SUBDIRS); do \
-	( cd $(TOPSRC)/$$i; $(MAKE) depend); \
-	done
+	for i in $(SUBDIRS); do (cd $$i; $(MAKE) depend); done
+
+etags:
+	etags `find . -name '*.[chS]' -print`
 
 clean:
-	for i in $(SUBDIRS); do \
-        ( cd $(TOPSRC)/$$i; $(MAKE) clean); \
-	done
-	rm -f *.o \#*\# *~ wine wine.sym
+	for i in $(SUBDIRS); do (cd $$i; $(MAKE) clean); done
+	rm -f *.o \#*\# *~ wine wine.sym TAGS
 
 distclean:
-	for i in $(SUBDIRS); do \
-	( cd $(TOPSRC)/$$i; $(MAKE) distclean); \
-	done
+	for i in $(SUBDIRS); do (cd $$i; $(MAKE) distclean); done
 	echo "/* autoconf.h generated automatically.  Run Configure */" >autoconf.h
 	echo "#error You must run Configure before you can build the makefiles." >>autoconf.h
 	rm -f *.o \#*\# *~ wine wine.sym
 	rm -f stamp-config config.* include/config.h Makefile
 
 countryclean:
-	for i in $(SUBDIRS); do \
-	( cd $(TOPSRC)/$$i; $(MAKE) countryclean); \
-	done
+	for i in $(SUBDIRS); do (cd $$i; $(MAKE) countryclean); done
 	rm -f wine wine.sym
-
-winelibclean:
-	for i in $(SUBDIRS); do \
-	( cd $(TOPSRC)/$$i; $(MAKE) winelibclean); \
-	done
 	
+dummy:
diff --git a/configure.in b/configure.in
index 9912fa9..eded50a 100644
--- a/configure.in
+++ b/configure.in
@@ -32,7 +32,6 @@
 
 AC_CHECK_FUNCS(tcgetattr)
 AC_CHECK_HEADERS(stdlib.h)
-AC_HEADER_DIRENT()
 AC_HEADER_STAT()
 AC_C_CONST()
 AC_TYPE_SIZE_T()
diff --git a/controls/Makefile.in b/controls/Makefile.in
index 5bdd7a9..9aa20c7 100644
--- a/controls/Makefile.in
+++ b/controls/Makefile.in
@@ -24,26 +24,16 @@
 depend:
 	sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
 	$(CC) $(DIVINCL) $(XINCL) -MM *.c >> tmp_make
-	cp tmp_make Makefile
-	rm tmp_make
+	mv tmp_make Makefile
 
 clean:
 	rm -f *.o \#*\# *~ tmp_make
 
 distclean: clean
-	rm Makefile
+	rm -f Makefile
 
 countryclean:
 
-NAMES = $(SRCS:.c=)
-
-winelibclean:
-	for i in $(NAMES); do \
-	if test `grep -c WINELIB $$i.c` -ne 0; then \
-	rm $$i.o; \
-	fi; \
-	done
- 
 dummy:
 
 ### Dependencies:
diff --git a/controls/button.c b/controls/button.c
index 63fae08..9e29e54 100644
--- a/controls/button.c
+++ b/controls/button.c
@@ -313,14 +313,15 @@
         /* do we have the focus? */
         if (infoPtr->state & BUTTON_HASFOCUS)
         {
-            dwTextSize = GetTextExtent(hDC, text, strlen(text) );
-            delta = ((rc.right - rc.left) - LOWORD(dwTextSize) - 1) >> 1;
-            rc.left += delta;
-            rc.right -= delta;
-            GetTextMetrics(hDC, &tm);
-            delta = ((rc.bottom - rc.top) - tm.tmHeight - 1) >> 1;
-            rc.top += delta; 	rc.bottom -= delta;
-            DrawFocusRect(hDC, &rc);
+            short xdelta, ydelta;
+            dwTextSize = GetTextExtent( hDC, text, strlen(text) );
+            GetTextMetrics( hDC, &tm );
+            xdelta = ((rc.right - rc.left) - LOWORD(dwTextSize) - 1) / 2;
+            ydelta = ((rc.bottom - rc.top) - tm.tmHeight - 1) / 2;
+            if (xdelta < 0) xdelta = 0;
+            if (ydelta < 0) ydelta = 0;
+            InflateRect( &rc, -xdelta, -ydelta );
+            DrawFocusRect( hDC, &rc );
         }
     }
 
@@ -378,10 +379,13 @@
         ((action == ODA_DRAWENTIRE) && (infoPtr->state & BUTTON_HASFOCUS)))
     {
         GetTextExtentPoint(hDC, text, textlen, &size);
-        rc.top += delta - 1;
-        rc.bottom -= delta + 1;
+        if (delta > 1)
+        {
+            rc.top += delta - 1;
+            rc.bottom -= delta + 1;
+        }
         rc.left--;
-        rc.right = rc.left + size.cx + 2;
+        rc.right = min( rc.left + size.cx + 2, rc.right );
         DrawFocusRect(hDC, &rc);
     }
 }
diff --git a/controls/combo.c b/controls/combo.c
index 1967926..1600a23 100644
--- a/controls/combo.c
+++ b/controls/combo.c
@@ -105,6 +105,8 @@
   LONG         style = 0;
   LONG         cstyle = GetWindowLong(hwnd,GWL_STYLE);
   RECT         rect,lboxrect;
+  char className[] = "COMBOLBOX";  /* Hack so that class names are > 0x10000 */
+  char editName[] = "EDIT";
 
   /* translate combo into listbox styles */
   if (cstyle & CBS_OWNERDRAWFIXED) style |= LBS_OWNERDRAWFIXED;
@@ -125,7 +127,7 @@
     dprintf_combo(stddeb,"CBS_SIMPLE\n");
     SetRectEmpty(&lphc->RectButton);
     lphc->LBoxTop = lphl->StdItemHeight;
-    lphc->hWndEdit = CreateWindow("EDIT", "", 
+    lphc->hWndEdit = CreateWindow(editName, "", 
 				  WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | SS_LEFT,
 				  0, 0, rect.right, lphl->StdItemHeight,
 				  hwnd, 1, GetWindowWord(hwnd,GWW_HINSTANCE), 0L);
@@ -139,7 +141,7 @@
     SetWindowPos(hwnd, 0, 0, 0, rect.right - rect.left + 2*SYSMETRICS_CXBORDER,
 		 lphl->StdItemHeight + 2*SYSMETRICS_CYBORDER,
 		 SWP_NOMOVE | SWP_NOZORDER);
-    lphc->hWndEdit = CreateWindow("EDIT", "",
+    lphc->hWndEdit = CreateWindow(editName, "",
 				  WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | SS_LEFT,
 				  0, 0, lphc->RectButton.left, lphl->StdItemHeight,
 				  hwnd, 1, GetWindowWord(hwnd,GWW_HINSTANCE), 0L);
@@ -159,7 +161,7 @@
   /* FIXME: WinSight says these should be CHILD windows with the TOPMOST flag
    * set. Wine doesn't support TOPMOST, and simply setting the WS_CHILD
    * flag doesn't work. */
-  lphc->hWndLBox = CreateWindow("COMBOLBOX", "", 
+  lphc->hWndLBox = CreateWindow(className, "", 
 				WS_POPUP | WS_BORDER | WS_VSCROLL,
 				lboxrect.left, lboxrect.top,
 				lboxrect.right - lboxrect.left, 
diff --git a/controls/edit.c b/controls/edit.c
index d860e84..943321f 100644
--- a/controls/edit.c
+++ b/controls/edit.c
@@ -14,6 +14,7 @@
 #include "local.h"
 #include "win.h"
 #include "class.h"
+#include "stackframe.h" /* for MAKE_SEGPTR */
 #include "user.h"
 #include "stddebug.h"
 #include "debug.h"
@@ -2303,8 +2304,11 @@
     es->BlankLine[(es->ClientWidth / es->CharWidths[32]) + 1] = 0;
 
     /* set up text cursor for edit class */
-    CLASS_FindClassByName("EDIT", 0, &classPtr);
-    classPtr->wc.hCursor = LoadCursor(0, IDC_IBEAM);
+    {
+        char editname[] = "EDIT";
+        CLASS_FindClassByName( MAKE_SEGPTR(editname), 0, &classPtr);
+        classPtr->wc.hCursor = LoadCursor(0, IDC_IBEAM);
+    }
 
     /* paint background on first WM_PAINT */
     es->PaintBkgd = TRUE;
diff --git a/controls/menu.c b/controls/menu.c
index d838e49..88c4c15 100644
--- a/controls/menu.c
+++ b/controls/menu.c
@@ -673,7 +673,7 @@
     {
 	WND *wndPtr = WIN_FindWndPtr( hwndOwner );
 	if (!wndPtr) return FALSE;
-	menu->hWnd = CreateWindow( POPUPMENU_CLASS_NAME, "",
+	menu->hWnd = CreateWindow( (LPSTR)POPUPMENU_CLASS_ATOM, "",
 				   WS_POPUP | WS_BORDER, x, y, 
 				   menu->Width + 2*SYSMETRICS_CXBORDER,
 				   menu->Height + 2*SYSMETRICS_CYBORDER,
diff --git a/controls/widgets.c b/controls/widgets.c
index f816c76..cd04b2b 100644
--- a/controls/widgets.c
+++ b/controls/widgets.c
@@ -15,31 +15,30 @@
 #include "selectors.h"
 #include "stackframe.h"
 
-
 static WNDCLASS WIDGETS_BuiltinClasses[] =
 {
     { CS_GLOBALCLASS | CS_PARENTDC, (WNDPROC)"ButtonWndProc", 0,
-      sizeof(BUTTONINFO), 0, 0, 0, 0, NULL, "BUTTON" },
+          sizeof(BUTTONINFO), 0, 0, 0, 0, 0, (SEGPTR)"BUTTON" },
     { CS_GLOBALCLASS | CS_PARENTDC, (WNDPROC)"StaticWndProc", 0,
-      sizeof(STATICINFO), 0, 0, 0, 0, NULL, "STATIC" },
+          sizeof(STATICINFO), 0, 0, 0, 0, 0, (SEGPTR)"STATIC" },
     { CS_GLOBALCLASS | CS_PARENTDC, (WNDPROC)"ScrollBarWndProc", 0,
-      sizeof(SCROLLINFO), 0, 0, 0, 0, NULL, "SCROLLBAR" },
+          sizeof(SCROLLINFO), 0, 0, 0, 0, 0, (SEGPTR)"SCROLLBAR" },
     { CS_GLOBALCLASS | CS_PARENTDC | CS_DBLCLKS, (WNDPROC)"ListBoxWndProc", 0,
-      8, 0, 0, 0, 0, NULL, "LISTBOX" },
-    { CS_GLOBALCLASS | CS_PARENTDC, (WNDPROC)"ComboBoxWndProc", 0,
-      8, 0, 0, 0, 0, NULL, "COMBOBOX" },
-    { CS_GLOBALCLASS | CS_PARENTDC | CS_DBLCLKS, (WNDPROC)"ComboLBoxWndProc", 0,
-      8, 0, 0, 0, 0, NULL, "COMBOLBOX" },
-    { CS_GLOBALCLASS, (WNDPROC)"EditWndProc", 0,
-      sizeof(WORD), 0, 0, 0, 0, NULL, "EDIT" },
-    { CS_GLOBALCLASS | CS_SAVEBITS, (WNDPROC)"PopupMenuWndProc", 0,
-      8, 0, 0, 0, 0, NULL, POPUPMENU_CLASS_NAME },
-    { CS_GLOBALCLASS, (WNDPROC)"DesktopWndProc", 0,
-      sizeof(DESKTOPINFO), 0, 0, 0, 0, NULL, DESKTOP_CLASS_NAME },
-    { CS_GLOBALCLASS | CS_SAVEBITS, (WNDPROC)"DefDlgProc", 0,
-      DLGWINDOWEXTRA, 0, 0, 0, 0, NULL, DIALOG_CLASS_NAME },
-    { CS_GLOBALCLASS, (WNDPROC)"MDIClientWndProc", 0,
-      sizeof(MDICLIENTINFO), 0, 0, 0, STOCK_LTGRAY_BRUSH, NULL, "MDICLIENT" }
+          8, 0, 0, 0, 0, 0, (SEGPTR)"LISTBOX" },
+    { CS_GLOBALCLASS | CS_PARENTDC, (WNDPROC)"ComboBoxWndProc", 0, 8,
+          0, 0, 0, 0, 0, (SEGPTR)"COMBOBOX" },
+    { CS_GLOBALCLASS | CS_PARENTDC | CS_DBLCLKS, (WNDPROC)"ComboLBoxWndProc",
+          0, 8, 0, 0, 0, 0, 0, (SEGPTR)"COMBOLBOX" },
+    { CS_GLOBALCLASS, (WNDPROC)"EditWndProc", 0, sizeof(DWORD),
+          0, 0, 0, 0, 0, (SEGPTR)"EDIT" },
+    { CS_GLOBALCLASS | CS_SAVEBITS, (WNDPROC)"PopupMenuWndProc", 0, 8,
+          0, 0, 0, 0, 0, (SEGPTR)POPUPMENU_CLASS_NAME },
+    { CS_GLOBALCLASS, (WNDPROC)"DesktopWndProc", 0, sizeof(DESKTOPINFO),
+          0, 0, 0, 0, 0, (SEGPTR)DESKTOP_CLASS_NAME },
+    { CS_GLOBALCLASS | CS_SAVEBITS, (WNDPROC)"DefDlgProc", 0, DLGWINDOWEXTRA,
+          0, 0, 0, 0, 0, (SEGPTR)DIALOG_CLASS_NAME },
+    { CS_GLOBALCLASS, (WNDPROC)"MDIClientWndProc", 0, sizeof(MDICLIENTINFO),
+          0, 0, 0, STOCK_LTGRAY_BRUSH, 0, (SEGPTR)"MDICLIENT" }
 };
 
 #define NB_BUILTIN_CLASSES \
@@ -59,8 +58,8 @@
 
     for (i = 0; i < NB_BUILTIN_CLASSES; i++, class++)
     {
-        strcpy( name, class->lpszClassName );
-        class->lpszClassName = (LPSTR)MAKE_SEGPTR(name);
+        strcpy( name, (char *)class->lpszClassName );
+        class->lpszClassName = MAKE_SEGPTR(name);
 	class->hCursor = LoadCursor( 0, IDC_ARROW );
         class->lpfnWndProc = GetWndProcEntry16( (char *)class->lpfnWndProc );
 	if (!RegisterClass( class )) return FALSE;
diff --git a/debugger/Imakefile b/debugger/Imakefile
index 39c46f4..766a9c7 100644
--- a/debugger/Imakefile
+++ b/debugger/Imakefile
@@ -17,6 +17,7 @@
 	hash.c \
 	info.c \
 	lex.yy.c \
+	memory.c \
 	registers.c \
 	stack.c
 
diff --git a/debugger/Makefile.in b/debugger/Makefile.in
index 39cada3..ed50f1b 100644
--- a/debugger/Makefile.in
+++ b/debugger/Makefile.in
@@ -13,53 +13,42 @@
 
 MODULE	= debugger
 
-SRCS	= break.c db_disasm.c hash.c info.c registers.c stack.c
+SRCS	= break.c db_disasm.c hash.c info.c memory.c registers.c stack.c
 
 OBJS = $(SRCS:.c=.o) dbg.tab.o lex.yy.o
 
 all: $(MODULE).o dbg.tab.o lex.yy.o
 
-dbg.tab.c: dbg.y
+dbg.tab.c dbg.tab.h: dbg.y
 	$(BISON) -b dbg -d dbg.y
 
-dbg.tab.h: dbg.y
-	$(BISON) -b dbg -d dbg.y
-
-lex.yy.c: debug.l dbg.tab.h dbg.tab.h
+lex.yy.c: debug.l dbg.tab.h
 	$(FLEX) -8 -I debug.l
 
 .c.o:
 	$(COMPILE) -c -o $*.o $<
  
-$(MODULE).o: $(OBJS)
-	(cd readline; $(MAKE) 'CC=$(CC)' 'CFLAGS=$(CFLAGS)' 'LD=$(LD)' 'LDCOMBINEFLAGS=$(LDCOMBINEFLAGS)')
+$(MODULE).o: $(OBJS) readline
 	$(LD) $(LDCOMBINEFLAGS) $(OBJS) readline/readline.o -o $(MODULE).o
 
+readline: dummy
+	cd readline; $(MAKE) 'CC=$(CC)' 'CFLAGS=$(CFLAGS)' 'LD=$(LD)' 'LDCOMBINEFLAGS=$(LDCOMBINEFLAGS)'
+
 depend:
 	sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
 	$(CC) $(DIVINCL) $(XINCL) -MM *.c >> tmp_make
-	cp tmp_make Makefile
-	rm tmp_make
+	mv tmp_make Makefile
 
 clean:
 	(cd readline; $(MAKE) clean)
 	rm -f *.o \#*\# *~ dbg.tab.c dbg.tab.h lex.yy.c y.tab.c y.tab.h tmp_make
 
-distclean: clean
+distclean:
 	(cd readline; $(MAKE) distclean)
-	rm Makefile
+	rm -f *.o \#*\# *~ dbg.tab.c dbg.tab.h lex.yy.c y.tab.c y.tab.h tmp_make Makefile
 
 countryclean:
 
-NAMES = $(SRCS:.c=)
-
-winelibclean:
-	for i in $(NAMES); do \
-	if test `grep -c WINELIB $$i.c` -ne 0; then \
-	rm $$i.o; \
-	fi; \
-	done
- 
 dbg.tab.o: dbg.tab.c
 lex.yy.o: lex.yy.c
  
diff --git a/debugger/break.c b/debugger/break.c
index e143669..b237ce0 100644
--- a/debugger/break.c
+++ b/debugger/break.c
@@ -8,9 +8,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <sys/mman.h>
-#ifdef linux
-#include <sys/utsname.h>
-#endif
 #include "windows.h"
 #include "debugger.h"
 
@@ -21,15 +18,14 @@
 
 typedef struct
 {
-    unsigned int  segment;
-    unsigned int  addr;
-    BYTE          addrlen;
-    BYTE          opcode;
-    BOOL          enabled;
-    BOOL          in_use;
+    DBG_ADDR    addr;
+    BYTE        addrlen;
+    BYTE        opcode;
+    BOOL        enabled;
+    BOOL        in_use;
 } BREAKPOINT;
 
-static BREAKPOINT breakpoints[MAX_BREAKPOINTS] = { { 0, }, };
+static BREAKPOINT breakpoints[MAX_BREAKPOINTS];
 
 static int next_bp = 1;  /* breakpoint 0 is reserved for step-over */
 
@@ -39,11 +35,11 @@
  *
  * Change the opcode at segment:addr.
  */
-static void DEBUG_SetOpcode( unsigned int segment, unsigned int addr, BYTE op )
+static void DEBUG_SetOpcode( const DBG_ADDR *addr, BYTE op )
 {
-    if (segment)
+    if (addr->seg)
     {
-        *(BYTE *)PTR_SEG_OFF_TO_LIN( segment, addr ) = op;
+        *(BYTE *)PTR_SEG_OFF_TO_LIN( addr->seg, addr->off ) = op;
     }
     else  /* 32-bit code, so we have to change the protection first */
     {
@@ -56,14 +52,15 @@
            Not that portability matters, this code is i386 only anyways...
            How do I get the old protection in order to restore it later on?
         */
-        if (mprotect((caddr_t)(addr & (~4095)), 4096,
-                     PROT_READ|PROT_WRITE|PROT_EXEC) == -1)
+        if (mprotect((caddr_t)(addr->off & (~4095)), 4096,
+                     PROT_READ | PROT_WRITE | PROT_EXEC) == -1)
         {
             perror( "Can't set break point" );
             return;
 	}
-        *(BYTE *)addr = op;
-	mprotect((caddr_t)(addr & ~4095), 4096, PROT_READ|PROT_EXEC);
+        *(BYTE *)addr->off = op;
+	mprotect((caddr_t)(addr->off & ~4095), 4096,
+                  PROT_READ | PROT_EXEC );
     }
 }
 
@@ -80,7 +77,7 @@
     for (i = 0; i < MAX_BREAKPOINTS; i++)
     {
         if (breakpoints[i].in_use && breakpoints[i].enabled)
-            DEBUG_SetOpcode( breakpoints[i].segment, breakpoints[i].addr,
+            DEBUG_SetOpcode( &breakpoints[i].addr,
                              set ? INT3 : breakpoints[i].opcode );
     }
 }
@@ -92,15 +89,15 @@
  * Find the breakpoint for a given address. Return the breakpoint
  * number or -1 if none.
  */
-int DEBUG_FindBreakpoint( unsigned int segment, unsigned int addr )
+int DEBUG_FindBreakpoint( const DBG_ADDR *addr )
 {
     int i;
 
     for (i = 0; i < MAX_BREAKPOINTS; i++)
     {
         if (breakpoints[i].in_use && breakpoints[i].enabled &&
-            breakpoints[i].segment == segment && breakpoints[i].addr == addr)
-            return i;
+            breakpoints[i].addr.seg == addr->seg &&
+            breakpoints[i].addr.off == addr->off) return i;
     }
     return -1;
 }
@@ -111,13 +108,13 @@
  *
  * Add a breakpoint.
  */
-void DEBUG_AddBreakpoint( unsigned int segment, unsigned int addr )
+void DEBUG_AddBreakpoint( const DBG_ADDR *address )
 {
+    DBG_ADDR addr = *address;
     int num;
     BYTE *p;
 
-    if (segment == 0xffffffff) segment = CS;
-    if (segment == WINE_CODE_SELECTOR) segment = 0;
+    DBG_FIX_ADDR_SEG( &addr, CS_reg(DEBUG_context) );
 
     if (next_bp < MAX_BREAKPOINTS)
         num = next_bp++;
@@ -131,16 +128,15 @@
             return;
         }
     }
-    p = segment ? (BYTE *)PTR_SEG_OFF_TO_LIN( segment, addr ) : (BYTE *)addr;
-    breakpoints[num].segment = segment;
+    p = DBG_ADDR_TO_LIN( &addr );
     breakpoints[num].addr    = addr;
-    breakpoints[num].addrlen = !segment ? 32 :
-                          (GET_SEL_FLAGS(segment) & LDT_FLAGS_32BIT) ? 32 : 16;
+    breakpoints[num].addrlen = !addr.seg ? 32 :
+                         (GET_SEL_FLAGS(addr.seg) & LDT_FLAGS_32BIT) ? 32 : 16;
     breakpoints[num].opcode  = *p;
     breakpoints[num].enabled = TRUE;
     breakpoints[num].in_use  = TRUE;
     fprintf( stderr, "Breakpoint %d at ", num );
-    print_address( segment, addr, breakpoints[num].addrlen );
+    DEBUG_PrintAddress( &breakpoints[num].addr, breakpoints[num].addrlen );
     fprintf( stderr, "\n" );
 }
 
@@ -193,8 +189,7 @@
         if (breakpoints[i].in_use)
         {
             fprintf( stderr, "%d: %c ", i, breakpoints[i].enabled ? 'y' : 'n');
-            print_address( breakpoints[i].segment, breakpoints[i].addr,
-                           breakpoints[i].addrlen );
+            DEBUG_PrintAddress( &breakpoints[i].addr, breakpoints[i].addrlen );
             fprintf( stderr, "\n" );
         }
     }
@@ -210,22 +205,24 @@
 BOOL DEBUG_ShouldContinue( struct sigcontext_struct *context,
                            enum exec_mode mode )
 {
-    unsigned int segment, addr;
+    DBG_ADDR addr;
     int bpnum;
 
       /* If not single-stepping, back up over the int3 instruction */
-    if (!(EFL & STEP_FLAG)) EIP--;
+    if (!(EFL_reg(DEBUG_context) & STEP_FLAG)) EIP_reg(DEBUG_context)--;
 
-    segment = (CS == WINE_CODE_SELECTOR) ? 0 : CS;
-    addr    = EIP;
-    bpnum  = DEBUG_FindBreakpoint( segment, addr );
+    addr.seg = (CS_reg(DEBUG_context) == WINE_CODE_SELECTOR) ? 
+                0 : CS_reg(DEBUG_context);
+    addr.off = EIP_reg(DEBUG_context);
+        
+    bpnum  = DEBUG_FindBreakpoint( &addr );
     breakpoints[0].enabled = 0;  /* disable the step-over breakpoint */
 
     if ((bpnum != 0) && (bpnum != -1))
     {
         fprintf( stderr, "Stopped on breakpoint %d at ", bpnum );
-        print_address( breakpoints[bpnum].segment, breakpoints[bpnum].addr,
-                       breakpoints[bpnum].addrlen );
+        DEBUG_PrintAddress( &breakpoints[bpnum].addr,
+                            breakpoints[bpnum].addrlen );
         fprintf( stderr, "\n" );
         return FALSE;
     }
@@ -243,34 +240,34 @@
 void DEBUG_RestartExecution( struct sigcontext_struct *context,
                              enum exec_mode mode, int instr_len )
 {
-    unsigned int segment, addr;
+    DBG_ADDR addr;
 
-    segment = (CS == WINE_CODE_SELECTOR) ? 0 : CS;
-    addr    = EIP;
+    addr.seg = (CS_reg(DEBUG_context) == WINE_CODE_SELECTOR) ?
+                0 : CS_reg(DEBUG_context);
+    addr.off = EIP_reg(DEBUG_context);
 
-    if (DEBUG_FindBreakpoint( segment, addr ) != -1)
+    if (DEBUG_FindBreakpoint( &addr ) != -1)
         mode = EXEC_STEP_INSTR;  /* If there's a breakpoint, skip it */
 
     switch(mode)
     {
     case EXEC_CONT: /* Continuous execution */
-        EFL &= ~STEP_FLAG;
+        EFL_reg(DEBUG_context) &= ~STEP_FLAG;
         DEBUG_SetBreakpoints( TRUE );
         break;
 
     case EXEC_STEP_OVER:  /* Stepping over a call */
-        EFL &= ~STEP_FLAG;
-        breakpoints[0].segment = segment;
-        breakpoints[0].addr    = addr + instr_len;
+        EFL_reg(DEBUG_context) &= ~STEP_FLAG;
+        addr.off += instr_len;
+        breakpoints[0].addr    = addr;
         breakpoints[0].enabled = TRUE;
         breakpoints[0].in_use  = TRUE;
-        breakpoints[0].opcode  = segment ?
-           *(BYTE *)PTR_SEG_OFF_TO_LIN(segment,addr+instr_len) : *(BYTE *)addr;
+        breakpoints[0].opcode  = *(BYTE *)DBG_ADDR_TO_LIN( &addr );
         DEBUG_SetBreakpoints( TRUE );
         break;
 
     case EXEC_STEP_INSTR: /* Single-stepping an instruction */
-        EFL |= STEP_FLAG;
+        EFL_reg(DEBUG_context) |= STEP_FLAG;
         break;
     }
 }
diff --git a/debugger/db_disasm.c b/debugger/db_disasm.c
index 50474d6..7ffd2a8 100644
--- a/debugger/db_disasm.c
+++ b/debugger/db_disasm.c
@@ -64,7 +64,7 @@
 
 #include <stdio.h>
 #include "windows.h"
-#include "ldt.h"
+#include "debugger.h"
 
 /*
  * Switch to disassemble 16-bit code.
@@ -881,52 +881,46 @@
 	10,	/* EXTR */
 };
 
-static unsigned int db_get_task_value( unsigned int segment, unsigned int loc,
-                                       int size, int is_signed)
+static unsigned int db_get_task_value( const DBG_ADDR *addr,
+                                       int size, int is_signed )
 {
-  unsigned int result;
-  if (segment) loc = (unsigned int)PTR_SEG_OFF_TO_LIN( segment, loc );
-  switch(size)
+    unsigned int result;
+    unsigned char *p = DBG_ADDR_TO_LIN( addr );
+
+    switch(size)
     {
     case 4:
-      if (is_signed)
-	result = (unsigned int) *((int *) loc);
-      else
-	result = (unsigned int) *((unsigned int *) loc);
-      break;
+        if (is_signed) result = (unsigned int) *(int *)p;
+        else result = *(unsigned int *)p;
+        break;
     case 2:
-      if (is_signed)
-	result = (unsigned int) *((short int *) loc);
-      else
-	result = *((unsigned short int *) loc);
-      break;
+        if (is_signed) result = (unsigned int) *(short int *)p;
+        else result = *(unsigned short int *)p;
+        break;
     case 1:
-      if (is_signed)
-	result = (unsigned int) *((char *) loc);
-      else
-	result = *((unsigned char *) loc);
-      break;
+        if (is_signed) result = (unsigned int) *(char *)p;
+        else result = *(unsigned char *)p;
+        break;
     default:
-      fprintf(stderr, "Illegal size specified\n");
-      result = 0;
-      break;
+        fprintf(stderr, "Illegal size specified\n");
+        result = 0;
+        break;
     }
-  return result;
+    return result;
 }
 
-#define	get_value_inc(result, segment, loc, size, is_signed) \
-	result = db_get_task_value((segment), (loc), (size), (is_signed)); \
-        if (!db_disasm_16) (loc) += (size); \
-        else (loc) = ((loc) & 0xffff0000) | (((loc) + (size)) & 0xffff);
+#define	get_value_inc(result, addr, size, is_signed) \
+    result = db_get_task_value((addr), (size), (is_signed)); \
+    if (!db_disasm_16) (addr)->off += (size); \
+    else (addr)->off = ((addr)->off + (size)) & 0xffff;
 
 /*
  * Read address at location and return updated location.
  */
-unsigned int db_read_address( unsigned int segment, unsigned int loc,
-                              int short_addr, int regmodrm,
-                              struct i_addr *addrp )
+void db_read_address( DBG_ADDR *addr, int short_addr, int regmodrm,
+                      struct i_addr *addrp )
 {
-	int		mod, rm, sib, index, disp;
+	int mod, rm, sib, index, disp;
 
 	mod = f_mod(regmodrm);
 	rm  = f_rm(regmodrm);
@@ -934,7 +928,7 @@
 	if (mod == 3) {
 	    addrp->is_reg = TRUE;
 	    addrp->disp = rm;
-	    return (loc);
+            return;
 	}
 	addrp->is_reg = FALSE;
 	addrp->index = 0;
@@ -945,7 +939,7 @@
 	    switch (mod) {
 		case 0:
 		    if (rm == 6) {
-			get_value_inc(disp, segment, loc, 2, TRUE);
+			get_value_inc(disp, addr, 2, TRUE);
 			addrp->disp = disp;
 			addrp->base = 0;
 		    }
@@ -955,12 +949,12 @@
 		    }
 		    break;
 		case 1:
-		    get_value_inc(disp, segment, loc, 1, TRUE);
+		    get_value_inc(disp, addr, 1, TRUE);
 		    addrp->disp = disp;
 		    addrp->base = db_index_reg_16[rm];
 		    break;
 		case 2:
-		    get_value_inc(disp, segment, loc, 2, TRUE);
+		    get_value_inc(disp, addr, 2, TRUE);
 		    addrp->disp = disp;
 		    addrp->base = db_index_reg_16[rm];
 		    break;
@@ -968,7 +962,7 @@
 	}
 	else {
 	    if (mod != 3 && rm == 4) {
-		get_value_inc(sib, segment, loc, 1, FALSE);
+		get_value_inc(sib, addr, 1, FALSE);
 		rm = sib_base(sib);
 		index = sib_index(sib);
 		if (index != 4)
@@ -979,7 +973,7 @@
 	    switch (mod) {
 		case 0:
 		    if (rm == 5) {
-			get_value_inc(addrp->disp, segment, loc, 4, FALSE);
+			get_value_inc(addrp->disp, addr, 4, FALSE);
 			addrp->base = 0;
 		    }
 		    else {
@@ -989,19 +983,18 @@
 		    break;
 
 		case 1:
-		    get_value_inc(disp, segment, loc, 1, TRUE);
+		    get_value_inc(disp, addr, 1, TRUE);
 		    addrp->disp = disp;
 		    addrp->base = db_reg[LONG][rm];
 		    break;
 
 		case 2:
-		    get_value_inc(disp, segment, loc, 4, FALSE);
+		    get_value_inc(disp, addr, 4, FALSE);
 		    addrp->disp = disp;
 		    addrp->base = db_reg[LONG][rm];
 		    break;
 	    }
 	}
-	return (loc);
 }
 
 static void db_task_printsym(unsigned int addr, int size)
@@ -1015,7 +1008,10 @@
         fprintf(stderr, "0x%4.4x", addr & 0xffff );
         break;
     case LONG:
-        print_address(0, addr, db_disasm_16 ? 16 : 32);
+        {
+            DBG_ADDR address = { 0, addr };
+            DEBUG_PrintAddress( &address, db_disasm_16 ? 16 : 32 );
+        }
         break;
     }
 }
@@ -1051,8 +1047,8 @@
  * Disassemble floating-point ("escape") instruction
  * and return updated location.
  */
-unsigned int db_disasm_esc( unsigned int segment, unsigned int loc,
-                            int inst, int short_addr, int size, char *seg )
+void db_disasm_esc( DBG_ADDR *addr, int inst, int short_addr,
+                    int size, char *seg )
 {
 	int		regmodrm;
 	struct finst	*fp;
@@ -1060,14 +1056,14 @@
 	struct i_addr	address;
 	char *		name;
 
-	get_value_inc(regmodrm, segment, loc, 1, FALSE);
+	get_value_inc(regmodrm, addr, 1, FALSE);
 	fp = &db_Esc_inst[inst - 0xd8][f_reg(regmodrm)];
 	mod = f_mod(regmodrm);
 	if (mod != 3) {
 	    /*
 	     * Normal address modes.
 	     */
-	    loc = db_read_address(segment,loc, short_addr, regmodrm, &address);
+	    db_read_address( addr, short_addr, regmodrm, &address);
 	    fprintf(stderr,fp->f_name);
 	    switch(fp->f_size) {
 		case SNGL:
@@ -1123,15 +1119,16 @@
 		    break;
 	    }
 	}
-
-	return (loc);
 }
 
-/*
- * Disassemble instruction at 'loc'.  Return address of start of
- * next instruction.
+
+/***********************************************************************
+ *           DEBUG_Disasm
+ *
+ * Disassemble instruction at 'addr'.  addr is changed to point to the
+ * start of the next instruction.
  */
-unsigned int db_disasm( unsigned int segment, unsigned int loc )
+void DEBUG_Disasm( DBG_ADDR *addr )
 {
 	int	inst;
 	int	size;
@@ -1146,14 +1143,13 @@
 	int	displ;
 	int	prefix;
 	int	imm;
-	int	imm2;
 	int	len;
 	struct i_addr	address;
 
-        if (!segment) db_disasm_16 = FALSE;
-        else db_disasm_16 = !(GET_SEL_FLAGS(segment) & LDT_FLAGS_32BIT);
+        if (!addr->seg) db_disasm_16 = FALSE;
+        else db_disasm_16 = !(GET_SEL_FLAGS(addr->seg) & LDT_FLAGS_32BIT);
 
-	get_value_inc(inst, segment, loc, 1, FALSE);
+	get_value_inc( inst, addr, 1, FALSE );
 
 	if (db_disasm_16) {
 	    short_addr = TRUE;
@@ -1212,18 +1208,18 @@
 		    break;
 	    }
 	    if (prefix) {
-		get_value_inc(inst, segment, loc, 1, FALSE);
+		get_value_inc(inst, addr, 1, FALSE);
 	    }
 	} while (prefix);
 
-	if (inst >= 0xd8 && inst <= 0xdf) {
-	    loc = db_disasm_esc(segment, loc, inst, short_addr, size, seg);
-	    fprintf(stderr,"\n");
-	    return (loc);
-	}
+	if (inst >= 0xd8 && inst <= 0xdf)
+        {
+	    db_disasm_esc( addr, inst, short_addr, size, seg);
+            return;
+        }
 
 	if (inst == 0x0f) {
-	    get_value_inc(inst, segment, loc, 1, FALSE);
+	    get_value_inc(inst, addr, 1, FALSE);
 	    ip = db_inst_0f[inst>>4];
 	    if (ip == 0) {
 		ip = &db_bad_inst;
@@ -1236,8 +1232,8 @@
 	    ip = &db_inst_table[inst];
 
 	if (ip->i_has_modrm) {
-	    get_value_inc(regmodrm, segment, loc, 1, FALSE);
-	    loc = db_read_address(segment,loc, short_addr, regmodrm, &address);
+	    get_value_inc(regmodrm, addr, 1, FALSE);
+	    db_read_address( addr, short_addr, regmodrm, &address);
 	}
 
 	i_name = ip->i_name;
@@ -1378,42 +1374,42 @@
 
 		case I:
 		    len = db_lengths[size];
-		    get_value_inc(imm, segment, loc, len, FALSE);/* unsigned */
+		    get_value_inc(imm, addr, len, FALSE);/* unsigned */
 		    fprintf(stderr,"$0x%x", imm);
 		    break;
 
 		case Is:
 		    len = db_lengths[size];
-		    get_value_inc(imm, segment, loc, len, TRUE); /* signed */
+		    get_value_inc(imm, addr, len, TRUE); /* signed */
 		    fprintf(stderr,"$%d", imm);
 		    break;
 
 		case Ib:
-		    get_value_inc(imm, segment, loc, 1, FALSE); /* unsigned */
+		    get_value_inc(imm, addr, 1, FALSE); /* unsigned */
 		    fprintf(stderr,"$0x%x", imm);
 		    break;
 
 		case Ibs:
-		    get_value_inc(imm, segment, loc, 1, TRUE); /* signed */
+		    get_value_inc(imm, addr, 1, TRUE); /* signed */
 		    fprintf(stderr,"$%d", imm);
 		    break;
 
 		case Iw:
-		    get_value_inc(imm, segment, loc, 2, FALSE); /* unsigned */
+		    get_value_inc(imm, addr, 2, FALSE); /* unsigned */
 		    fprintf(stderr,"$0x%x", imm);
 		    break;
 
 		case Il:
-		    get_value_inc(imm, segment, loc, 4, FALSE);
+		    get_value_inc(imm, addr, 4, FALSE);
 		    fprintf(stderr,"$0x%x", imm);
 		    break;
 
 		case O:
 		    if (short_addr) {
-			get_value_inc(displ, segment, loc, 2, TRUE);
+			get_value_inc(displ, addr, 2, TRUE);
 		    }
 		    else {
-			get_value_inc(displ, segment, loc, 4, TRUE);
+			get_value_inc(displ, addr, 4, TRUE);
 		    }
 		    if (seg)
 			fprintf(stderr,"%s:%d",seg, displ);
@@ -1422,27 +1418,26 @@
 		    break;
 
 		case Db:
-		    get_value_inc(displ, segment, loc, 1, TRUE);
+		    get_value_inc(displ, addr, 1, TRUE);
 		    if (short_addr) {
 			/* offset only affects low 16 bits */
-		        displ = (loc & 0xffff0000)
-			      | ((loc + displ) & 0xffff);
+		        displ = (addr->off & 0xffff0000)
+			      | ((addr->off + displ) & 0xffff);
 		    }
-		    else
-			displ = displ + loc;
+		    else displ += addr->off;
 		    db_task_printsym(displ, short_addr ? WORD : LONG);
 		    break;
 
 		case Dl:
 		    if (short_addr) {
-			get_value_inc(displ, segment, loc, 2, TRUE);
+			get_value_inc(displ, addr, 2, TRUE);
 			/* offset only affects low 16 bits */
-		        displ = (loc & 0xffff0000)
-			      | ((loc + displ) & 0xffff);
+		        displ = (addr->off & 0xffff0000)
+			      | ((addr->off + displ) & 0xffff);
 		    }
 		    else {
-			get_value_inc(displ, segment, loc, 4, TRUE);
-			displ = displ + loc;
+			get_value_inc(displ, addr, 4, TRUE);
+			displ += addr->off;
 		    }
 		    db_task_printsym( displ, short_addr ? WORD : LONG);
 		    break;
@@ -1456,18 +1451,15 @@
 		    break;
 
 		case OS:
-		    if (short_addr) {
-			get_value_inc(imm, segment, loc, 2, FALSE);/* offset */
-		    }
-		    else {
-			get_value_inc(imm, segment, loc, 4, FALSE);/* offset */
-		    }
-		    get_value_inc(imm2, segment, loc, 2, FALSE); /* segment */
-                    print_address( imm2, imm, short_addr ? 16 : 32 );
+                    {
+                        DBG_ADDR address;
+                        get_value_inc( address.off, addr,  /* offset */
+                                       short_addr ? 2 : 4, FALSE );
+                        get_value_inc( address.seg, addr,  /* segment */
+                                       2, FALSE );
+                        DEBUG_PrintAddress( &address, short_addr ? 16 : 32 );
+                    }
 		    break;
 	    }
 	}
-
-	return (loc);
 }
-
diff --git a/debugger/dbg.y b/debugger/dbg.y
index 7d0022f..24bde0c 100644
--- a/debugger/dbg.y
+++ b/debugger/dbg.y
@@ -1,11 +1,9 @@
 
 %{
-
-/* Parser for command lines in the Wine debugger
+/*
+ * Parser for command lines in the Wine debugger
  *
- * Version 1.0
- * Eric Youngdale
- * 9/93
+ * Copyright 1993 Eric Youngdale
  */
 
 #include <stdio.h>
@@ -14,8 +12,6 @@
 #include "windows.h"
 #include "debugger.h"
 
-#define YYSTYPE int
-
 extern FILE * yyin;
 unsigned int dbg_mode = 0;
 
@@ -23,35 +19,31 @@
 
 void issue_prompt(void);
 void mode_command(int);
+void flush_symbols(void);
+int yylex(void);
+int yyerror(char *);
+
 %}
 
+%union
+{
+    DBG_ADDR         address;
+    enum debug_regs  reg;
+    char *           string;
+    int              integer;
+}
 
-%token CONT
-%token STEP
-%token NEXT
-%token QUIT
-%token HELP
-%token BACKTRACE
-%token INFO
-%token STACK
-%token SEGMENTS
-%token REG
-%token REGS
-%token NUM
-%token ENABLE
-%token DISABLE
-%token BREAK
-%token DELETE
-%token SET
-%token MODE
-%token PRINT
-%token EXAM
-%token IDENTIFIER
-%token FORMAT
+%token CONT STEP NEXT QUIT HELP BACKTRACE INFO STACK SEGMENTS REGS
+%token ENABLE DISABLE BREAK DELETE SET MODE PRINT EXAM DEFINE ABORT
 %token NO_SYMBOL
 %token SYMBOLFILE
-%token DEFINE
-%token ABORT
+
+%token <string> IDENTIFIER
+%token <integer> NUM FORMAT
+%token <reg> REG
+
+%type <integer> expr
+%type <address> addr symbol
 
 %%
 
@@ -62,19 +54,21 @@
 	| infocmd '\n'
 	| error '\n'       { yyerrok; }
 	| QUIT  '\n'       { exit(0); }
-	| HELP  '\n'       { dbg_help(); }
+	| HELP  '\n'       { DEBUG_Help(); }
 	| CONT '\n'        { dbg_exec_mode = EXEC_CONT; return 0; }
 	| STEP '\n'        { dbg_exec_mode = EXEC_STEP_INSTR; return 0; }
 	| NEXT '\n'        { dbg_exec_mode = EXEC_STEP_OVER; return 0; }
 	| ABORT '\n'       { kill(getpid(), SIGABRT); }
- 	| SYMBOLFILE IDENTIFIER '\n'   { read_symboltable($2); }
-	| DEFINE IDENTIFIER expr '\n'  { add_hash($2, 0, $3); }
+ 	| SYMBOLFILE IDENTIFIER '\n'  { DEBUG_ReadSymbolTable( $2 ); }
+	| DEFINE IDENTIFIER addr '\n' { DEBUG_AddSymbol( $2, &$3 ); }
 	| MODE NUM '\n'         { mode_command($2); }
 	| ENABLE NUM '\n'       { DEBUG_EnableBreakpoint( $2, TRUE ); }
 	| DISABLE NUM '\n'      { DEBUG_EnableBreakpoint( $2, FALSE ); }
-	| BREAK '*' expr '\n'       { DEBUG_AddBreakpoint( 0xffffffff, $3 ); }
-	| BREAK '*' expr ':' expr '\n'	{ DEBUG_AddBreakpoint( $3, $5); }
-        | BREAK '\n'            { DEBUG_AddBreakpoint( 0xffffffff, EIP ); }
+	| BREAK '*' addr '\n'   { DEBUG_AddBreakpoint( &$3 ); }
+        | BREAK '\n'            { DBG_ADDR addr = { CS_reg(DEBUG_context),
+                                                    EIP_reg(DEBUG_context) };
+                                  DEBUG_AddBreakpoint( &addr );
+                                }
         | DELETE BREAK NUM '\n' { DEBUG_DelBreakpoint( $3 ); }
 	| BACKTRACE '\n'        { DEBUG_BackTrace(); }
 	| x_command
@@ -82,38 +76,41 @@
 	| deposit_command
 
 deposit_command:
-	SET REG '=' expr '\n'        { DEBUG_SetRegister( $2, $4 ); }
-	| SET '*' expr '=' expr '\n' { *((unsigned int *) $3) = $5; }
-	| SET symbol '=' expr '\n'   { *((unsigned int *) $2) = $4; }
+	SET REG '=' expr '\n'          { DEBUG_SetRegister( $2, $4 ); }
+	| SET '*' addr '=' expr '\n'   { DEBUG_WriteMemory( &$3, $5 ); }
+	| SET IDENTIFIER '=' addr '\n' { if (!DEBUG_SetSymbolValue( $2, &$4 ))
+                                         {
+                                           fprintf( stderr, "Symbol %s not found\n", $2 );
+                                           YYERROR;
+                                         }
+                                       }
 
 
 x_command:
-	  EXAM expr  '\n' { examine_memory( 0xffffffff, $2, 1, 'x'); }
-	| EXAM FORMAT expr  '\n' { examine_memory( 0xffffffff, $3,
-                                                  $2 >> 8, $2 & 0xff ); }
-	| EXAM expr ':' expr '\n' { examine_memory( $2, $4, 1, 'x' ); }
-	| EXAM FORMAT expr ':' expr'\n'  { examine_memory( $3, $5, 
-	                                              $2 >> 8,  $2 & 0xff ); }
+	  EXAM addr '\n' { DEBUG_ExamineMemory( &$2, 1, 'x'); }
+	| EXAM FORMAT addr '\n' { DEBUG_ExamineMemory( &$3, $2>>8, $2&0xff ); }
 
  print_command:
-	  PRINT expr '\n' { examine_memory( 0, ((unsigned int) &$2 ), 1,'x'); }
-	| PRINT FORMAT expr '\n' { examine_memory( 0, (unsigned int)&$3,
-                                                   $2 >> 8, $2 & 0xff ); }
+	  PRINT addr '\n'        { DEBUG_Print( &$2, 1, 'x' ); }
+	| PRINT FORMAT addr '\n' { DEBUG_Print( &$3, $2 >> 8, $2 & 0xff ); }
 
- symbol: IDENTIFIER   { if (($$ = find_hash($1)) == 0xffffffff)
+ symbol: IDENTIFIER   { if (!DEBUG_GetSymbolValue( $1, &$$ ))
                         {
-                           fprintf(stderr,"Symbol %s not found\n", (char *)$1);
+                           fprintf( stderr, "Symbol %s not found\n", $1 );
                            YYERROR;
                         }
                       } 
 
+ addr: expr                     { $$.seg = 0xffffffff; $$.off = $1; }
+       | expr ':' expr          { $$.seg = $1; $$.off = $3; }
+       | symbol   		{ $$ = $1; }
+
  expr:  NUM			{ $$ = $1;	}
 	| REG			{ $$ = DEBUG_GetRegister($1); }
-	| symbol   		{ $$ = $1; }
 	| expr '+' NUM		{ $$ = $1 + $3; }
 	| expr '-' NUM		{ $$ = $1 - $3; }
 	| '(' expr ')'		{ $$ = $2; }
-	| '*' expr		{ $$ = *((unsigned int *) $2); }
+	| '*' addr		{ $$ = DEBUG_ReadMemory( &$2 ); }
 	
  infocmd: INFO REGS     { DEBUG_InfoRegisters(); }
 	| INFO STACK    { DEBUG_InfoStack(); }
@@ -147,33 +144,39 @@
 #endif
 
     yyin = stdin;
-    context = (struct sigcontext_struct *)regs;
+    DEBUG_context = (struct sigcontext_struct *)regs;
 
-    if (CS == WINE_CODE_SELECTOR) newmode = 32;
-    else newmode = (GET_SEL_FLAGS(CS) & LDT_FLAGS_32BIT) ? 32 : 16;
+    DEBUG_SetBreakpoints( FALSE );
 
-    if (newmode != dbg_mode)
-        fprintf(stderr,"In %d bit mode.\n", dbg_mode = newmode);
-
-    if(dbg_mode == 32 && !loaded_symbols)
+    if (!loaded_symbols)
     {
         loaded_symbols++;
         GetPrivateProfileString("wine", "SymbolTableFile", "wine.sym",
                           SymbolTableFile, sizeof(SymbolTableFile), WINE_INI);
-        read_symboltable(SymbolTableFile);
+        DEBUG_ReadSymbolTable( SymbolTableFile );
+        DEBUG_LoadEntryPoints();
     }
 
-    DEBUG_SetBreakpoints( FALSE );
-
     if ((signal != SIGTRAP) || !DEBUG_ShouldContinue( regs, dbg_exec_mode ))
     {
-        unsigned int segment = (CS == WINE_CODE_SELECTOR) ? 0 : CS;
+        DBG_ADDR addr;
+
+        addr.seg = (CS_reg(DEBUG_context) == WINE_CODE_SELECTOR) ?
+                    0 : CS_reg(DEBUG_context);
+        addr.off = EIP_reg(DEBUG_context);
+
+        if (!addr.seg) newmode = 32;
+        else newmode = (GET_SEL_FLAGS(addr.seg) & LDT_FLAGS_32BIT) ? 32 : 16;
+
+        if (newmode != dbg_mode)
+            fprintf(stderr,"In %d bit mode.\n", dbg_mode = newmode);
 
         /* Show where we crashed */
-        print_address( segment, EIP, dbg_mode );
+        DEBUG_PrintAddress( &addr, dbg_mode );
         fprintf(stderr,":  ");
-        instr_len = db_disasm( segment, EIP ) - EIP;
+        DEBUG_Disasm( &addr );
         fprintf(stderr,"\n");
+        instr_len = addr.off - EIP_reg(DEBUG_context);
         
         issue_prompt();
         yyparse();
diff --git a/debugger/debug.l b/debugger/debug.l
index 862c1f8..af11db4 100644
--- a/debugger/debug.l
+++ b/debugger/debug.l
@@ -9,8 +9,8 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include "dbg.tab.h"
 #include "debugger.h"
+#include "dbg.tab.h"
 
 #ifdef USE_READLINE
 #undef YY_INPUT
@@ -25,7 +25,6 @@
 static char * make_symbol(char *);
 void flush_symbols();
 static int syntax_error;
-extern int yylval;
 %}
 
 DIGIT	   [0-9]
@@ -39,37 +38,39 @@
 
 [-+=()*:]       { return *yytext; }
 
-"0x"{HEXDIGIT}+      { sscanf(yytext, "%x", &yylval); return NUM; }
-{DIGIT}+             { sscanf(yytext, "%d", &yylval); return NUM; }
+"0x"{HEXDIGIT}+      { sscanf(yytext, "%x", &yylval.integer); return NUM; }
+{DIGIT}+             { sscanf(yytext, "%d", &yylval.integer); return NUM; }
 
-"/"{DIGIT}+{FORMAT}  { char *last; yylval = strtol( yytext+1, &last, NULL );
-                       yylval = (yylval << 8) | *last; return FORMAT; }
-"/"{FORMAT}          { yylval = (1 << 8) | yytext[1]; return FORMAT; }
+"/"{DIGIT}+{FORMAT}  { char * last;
+                       yylval.integer = strtol( yytext+1, &last, NULL );
+                       yylval.integer = (yylval.integer << 8) | *last;
+                       return FORMAT; }
+"/"{FORMAT}          { yylval.integer = (1 << 8) | yytext[1]; return FORMAT; }
 
-$pc     { yylval = REG_EIP; return REG; }
-$flags  { yylval = REG_EFL; return REG; }
-$eip    { yylval = REG_EIP; return REG; }
-$ip     { yylval = REG_IP;  return REG; }
-$esp    { yylval = REG_ESP; return REG; }
-$sp     { yylval = REG_SP;  return REG; }
-$eax    { yylval = REG_EAX; return REG; }
-$ebx    { yylval = REG_EBX; return REG; }
-$ecx    { yylval = REG_ECX; return REG; }
-$edx    { yylval = REG_EDX; return REG; }
-$esi    { yylval = REG_ESI; return REG; }
-$edi    { yylval = REG_EDI; return REG; }
-$ebp    { yylval = REG_EBP; return REG; }
-$ax     { yylval = REG_AX;  return REG; }
-$bx     { yylval = REG_BX;  return REG; }
-$cx     { yylval = REG_CX;  return REG; }
-$dx     { yylval = REG_DX;  return REG; }
-$si     { yylval = REG_SI;  return REG; }
-$di     { yylval = REG_DI;  return REG; }
-$bp     { yylval = REG_BP;  return REG; }
-$es     { yylval = REG_ES;  return REG; }
-$ds     { yylval = REG_DS;  return REG; }
-$cs     { yylval = REG_CS;  return REG; }
-$ss     { yylval = REG_SS;  return REG; }
+$pc     { yylval.reg = REG_EIP; return REG; }
+$flags  { yylval.reg = REG_EFL; return REG; }
+$eip    { yylval.reg = REG_EIP; return REG; }
+$ip     { yylval.reg = REG_IP;  return REG; }
+$esp    { yylval.reg = REG_ESP; return REG; }
+$sp     { yylval.reg = REG_SP;  return REG; }
+$eax    { yylval.reg = REG_EAX; return REG; }
+$ebx    { yylval.reg = REG_EBX; return REG; }
+$ecx    { yylval.reg = REG_ECX; return REG; }
+$edx    { yylval.reg = REG_EDX; return REG; }
+$esi    { yylval.reg = REG_ESI; return REG; }
+$edi    { yylval.reg = REG_EDI; return REG; }
+$ebp    { yylval.reg = REG_EBP; return REG; }
+$ax     { yylval.reg = REG_AX;  return REG; }
+$bx     { yylval.reg = REG_BX;  return REG; }
+$cx     { yylval.reg = REG_CX;  return REG; }
+$dx     { yylval.reg = REG_DX;  return REG; }
+$si     { yylval.reg = REG_SI;  return REG; }
+$di     { yylval.reg = REG_DI;  return REG; }
+$bp     { yylval.reg = REG_BP;  return REG; }
+$es     { yylval.reg = REG_ES;  return REG; }
+$ds     { yylval.reg = REG_DS;  return REG; }
+$cs     { yylval.reg = REG_CS;  return REG; }
+$ss     { yylval.reg = REG_SS;  return REG; }
 
 info|inf|in		      { return INFO; }
 segments|segm                 { return SEGMENTS; }
@@ -103,14 +104,14 @@
 
 stack|stac|sta|st     	{ return STACK; }
 
-{IDENTIFIER}	{yylval = (int) make_symbol(yytext); 
-	          return IDENTIFIER;
-	         }
+{IDENTIFIER}	{ yylval.string = make_symbol(yytext); return IDENTIFIER; }
 
 [ \t]+        /* Eat up whitespace */
 
-.		{ if(syntax_error == 0) {
-		syntax_error ++; fprintf(stderr, "Syntax Error\n"); }
+.		{ if (syntax_error == 0)
+                  {
+		    syntax_error ++; fprintf(stderr, "Syntax Error\n");
+                  }
 		}
 
 %%
@@ -124,11 +125,6 @@
 #define whitespace(c) (((c) == ' ') || ((c) == '\t'))
 #endif
 
-#if 0
-/* Used only with GNU readline */
-#include "readline/readline.h"
-#include "readline/chardefs.h"
-#endif
 
 /* Strip whitespace from the start and end of STRING. */
 static void stripwhite (char *string)
@@ -161,18 +157,22 @@
         line = readline ("Wine-dbg>");
         if (!line) exit(0);
 
-        /* Remove leading and trailing whitespace from the line.
-           Then, if there is anything left, add it to the history list
-           and execute it. */
+        /* Remove leading and trailing whitespace from the line */
+
         stripwhite (line);
 
+        /* If there is anything left, add it to the history list
+           and execute it. Otherwise, re-execute last command. */
+
         if (*line)
         {
             add_history( line );
             strncpy( last_line, line, 255 );
             last_line[255] = '\0'; 
        }
-        else line = last_line;  /* Repeat previous command */
+
+        free( line );
+        line = last_line;
 
         if ((len = strlen(line)) > 0)
         {
@@ -184,7 +184,6 @@
             strcpy(buf, line);
             buf[len] = '\n';
             buf[len+1] = 0;
-            free(line);
             return len + 1;
         }
     }
diff --git a/debugger/hash.c b/debugger/hash.c
index bca6553..f6569c8 100644
--- a/debugger/hash.c
+++ b/debugger/hash.c
@@ -12,182 +12,248 @@
 #include <neexe.h>
 #include "module.h"
 #include "selectors.h"
-#include "wine.h"
+#include "debugger.h"
+#include "toolhelp.h"
 
-struct  name_hash{
-	struct name_hash * next;
-        unsigned int segment;
-	unsigned int address;
-	char * name;
+struct name_hash
+{
+    struct name_hash * next;
+    char *             name;
+    DBG_ADDR           addr;
 };
 
 #define NR_NAME_HASH 128
 
 static struct name_hash * name_hash_table[NR_NAME_HASH] = {0,};
 
-static  unsigned int name_hash(const char * name){
-	unsigned int hash = 0;
-	const char * p;
-
-	p = name;
-
-	while (*p) hash = (hash << 15) + (hash << 3) + (hash >> 3) + *p++;
-	return hash % NR_NAME_HASH;
-
-}
-
-
-void add_hash(char * name, unsigned int segment, unsigned int address)
+static unsigned int name_hash( const char * name )
 {
-	struct name_hash  * new;
-	int hash;
+    unsigned int hash = 0;
+    const char * p;
 
-	new = (struct  name_hash *) malloc(sizeof(struct name_hash));
-        new->segment = segment;
-	new->address = address;
-	new->name = strdup(name);
-	new->next = NULL;
-	hash = name_hash(name);
+    p = name;
 
-	/* Now insert into the hash table */
-	new->next = name_hash_table[hash];
-	name_hash_table[hash] = new;
+    while (*p) hash = (hash << 15) + (hash << 3) + (hash >> 3) + *p++;
+    return hash % NR_NAME_HASH;
 }
 
-unsigned int find_hash(char * name)
+
+/***********************************************************************
+ *           DEBUG_AddSymbol
+ *
+ * Add a symbol to the table.
+ */
+void DEBUG_AddSymbol( const char * name, const DBG_ADDR *addr )
 {
-	char buffer[256];
-	struct name_hash  * nh;
+    struct name_hash  * new;
+    int hash;
 
-	for(nh = name_hash_table[name_hash(name)]; nh; nh = nh->next)
-		if(strcmp(nh->name, name) == 0) return nh->address;
+    new = (struct name_hash *) malloc(sizeof(struct name_hash));
+    new->addr = *addr;
+    new->name = strdup(name);
+    new->next = NULL;
+    hash = name_hash(name);
 
-	if(name[0] != '_'){
-		buffer[0] = '_';
-		strcpy(buffer+1, name);
-		for(nh = name_hash_table[name_hash(buffer)]; nh; nh = nh->next)
-			if(strcmp(nh->name, buffer) == 0) return nh->address;
-	};
-
-
-	return 0xffffffff;
+    /* Now insert into the hash table */
+    new->next = name_hash_table[hash];
+    name_hash_table[hash] = new;
 }
 
 
-static char name_buffer[256];
-
-char * find_nearest_symbol(unsigned int segment, unsigned int address)
-{
-	struct name_hash * nearest;
-	struct name_hash  * nh;
-        unsigned int nearest_address;
-	int i;
-	
-	nearest = NULL;
-        nearest_address = 0;
-	
-	for(i=0; i<NR_NAME_HASH; i++) {
-		for(nh = name_hash_table[i]; nh; nh = nh->next)
-			if (nh->segment == segment &&
-                            nh->address <= address &&
-                            nh->address >= nearest_address)
-                        {
-                            nearest_address = nh->address;
-                            nearest = nh;
-                        }
-	}
-        if (!nearest) return NULL;
-
-        if (address == nearest->address)
-            sprintf( name_buffer, "%s", nearest->name );
-	else
-            sprintf( name_buffer, "%s+0x%x", nearest->name,
-                     address - nearest->address );
-	return name_buffer;
-}
-
-
-void
-read_symboltable(char * filename){
-	FILE * symbolfile;
-	unsigned int addr;
-	int nargs;
-	char type;
-	char * cpnt;
-	char buffer[256];
-	char name[256];
-
-	symbolfile = fopen(filename, "r");
-	if(!symbolfile) {
-		fprintf(stderr,"Unable to open symbol table %s\n", filename);
-		return;
-	};
-
-	fprintf(stderr,"Reading symbols from file %s\n", filename);
-
-
-	while (1)
-	{
-		fgets(buffer, sizeof(buffer),  symbolfile);
-		if (feof(symbolfile)) break;
-		
-		/* Strip any text after a # sign (i.e. comments) */
-		cpnt = buffer;
-		while(*cpnt){
-			if(*cpnt == '#') {*cpnt = 0; break; };
-			cpnt++;
-		};
-		
-		/* Quietly ignore any lines that have just whitespace */
-		cpnt = buffer;
-		while(*cpnt){
-			if(*cpnt != ' ' && *cpnt != '\t') break;
-			cpnt++;
-		};
-		if (!(*cpnt) || *cpnt == '\n') {
-			continue;
-		};
-		
-		nargs = sscanf(buffer, "%x %c %s", &addr, &type, name);
-		add_hash(name, 0, addr);
-      };
-      fclose(symbolfile);
-}
-
-
-
-void load_entrypoints( HMODULE hModule )
+/***********************************************************************
+ *           DEBUG_GetSymbolValue
+ *
+ * Get the address of a named symbol.
+ */
+BOOL DEBUG_GetSymbolValue( const char * name, DBG_ADDR *addr )
 {
     char buffer[256];
-    unsigned char *cpnt, *name;
-    NE_MODULE *pModule;
-    unsigned int address;
+    struct name_hash *nh;
 
-    if (!(pModule = (NE_MODULE *)GlobalLock( hModule ))) return;
-    name = (unsigned char *)pModule + pModule->name_table;
+    for(nh = name_hash_table[name_hash(name)]; nh; nh = nh->next)
+        if (!strcmp(nh->name, name)) break;
 
-      /* First search the resident names */
-
-    cpnt = (unsigned char *)pModule + pModule->name_table;
-    while (*cpnt)
+    if (!nh && (name[0] != '_'))
     {
-        cpnt += *cpnt + 1 + sizeof(WORD);
-        sprintf( buffer, "%*.*s.%*.*s", *name, *name, name + 1,
-                 *cpnt, *cpnt, cpnt + 1 );
-        address = MODULE_GetEntryPoint( hModule, *(WORD *)(cpnt + *cpnt + 1) );
-        if (address) add_hash( buffer, HIWORD(address), LOWORD(address) );
+        buffer[0] = '_';
+        strcpy(buffer+1, name);
+        for(nh = name_hash_table[name_hash(buffer)]; nh; nh = nh->next)
+            if (!strcmp(nh->name, buffer)) break;
     }
 
-      /* Now search the non-resident names table */
+    if (!nh) return FALSE;
+    *addr = nh->addr;
+    return TRUE;
+}
 
-    if (!pModule->nrname_handle) return;  /* No non-resident table */
-    cpnt = (char *)GlobalLock( pModule->nrname_handle );
-    while (*cpnt)
+
+/***********************************************************************
+ *           DEBUG_SetSymbolValue
+ *
+ * Set the address of a named symbol.
+ */
+BOOL DEBUG_SetSymbolValue( const char * name, const DBG_ADDR *addr )
+{
+    char buffer[256];
+    struct name_hash *nh;
+
+    for(nh = name_hash_table[name_hash(name)]; nh; nh = nh->next)
+        if (!strcmp(nh->name, name)) break;
+
+    if (!nh && (name[0] != '_'))
     {
-        cpnt += *cpnt + 1 + sizeof(WORD);
-        sprintf( buffer, "%*.*s.%*.*s", *name, *name, name + 1,
-                 *cpnt, *cpnt, cpnt + 1 );
-        address = MODULE_GetEntryPoint( hModule, *(WORD *)(cpnt + *cpnt + 1) );
-        if (address) add_hash( buffer, HIWORD(address), LOWORD(address) );
+        buffer[0] = '_';
+        strcpy(buffer+1, name);
+        for(nh = name_hash_table[name_hash(buffer)]; nh; nh = nh->next)
+            if (!strcmp(nh->name, buffer)) break;
+    }
+
+    if (!nh) return FALSE;
+    nh->addr = *addr;
+    DBG_FIX_ADDR_SEG( &nh->addr, DS_reg(DEBUG_context) );
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           DEBUG_FindNearestSymbol
+ *
+ * Find the symbol nearest to a given address.
+ */
+const char * DEBUG_FindNearestSymbol( const DBG_ADDR *addr )
+{
+    static char name_buffer[256];
+    struct name_hash * nearest = NULL;
+    struct name_hash * nh;
+    unsigned int nearest_address = 0;
+    int i;
+
+    for(i=0; i<NR_NAME_HASH; i++)
+    {
+        for (nh = name_hash_table[i]; nh; nh = nh->next)
+            if (nh->addr.seg == addr->seg &&
+                nh->addr.off <= addr->off &&
+                nh->addr.off >= nearest_address)
+            {
+                nearest_address = nh->addr.off;
+                nearest = nh;
+            }
+    }
+    if (!nearest) return NULL;
+
+    if (addr->off == nearest->addr.off)
+        sprintf( name_buffer, "%s", nearest->name );
+    else
+        sprintf( name_buffer, "%s+0x%lx", nearest->name,
+                addr->off - nearest->addr.off );
+    return name_buffer;
+}
+
+
+/***********************************************************************
+ *           DEBUG_ReadSymbolTable
+ *
+ * Read a symbol file into the hash table.
+ */
+void DEBUG_ReadSymbolTable( const char * filename )
+{
+    FILE * symbolfile;
+    DBG_ADDR addr = { 0, 0 };
+    int nargs;
+    char type;
+    char * cpnt;
+    char buffer[256];
+    char name[256];
+
+    if (!(symbolfile = fopen(filename, "r")))
+    {
+        fprintf( stderr, "Unable to open symbol table %s\n", filename );
+        return;
+    }
+
+    fprintf( stderr, "Reading symbols from file %s\n", filename );
+
+    while (1)
+    {
+        fgets( buffer, sizeof(buffer), symbolfile );
+        if (feof(symbolfile)) break;
+		
+        /* Strip any text after a # sign (i.e. comments) */
+        cpnt = buffer;
+        while (*cpnt)
+            if(*cpnt++ == '#') { *cpnt = 0; break; }
+		
+        /* Quietly ignore any lines that have just whitespace */
+        cpnt = buffer;
+        while(*cpnt)
+        {
+            if(*cpnt != ' ' && *cpnt != '\t') break;
+            cpnt++;
+        }
+        if (!(*cpnt) || *cpnt == '\n') continue;
+		
+        nargs = sscanf(buffer, "%lx %c %s", &addr.off, &type, name);
+        DEBUG_AddSymbol( name, &addr );
+    }
+    fclose(symbolfile);
+}
+
+
+/***********************************************************************
+ *           DEBUG_LoadEntryPoints
+ *
+ * Load the entry points of all the modules into the hash table.
+ */
+void DEBUG_LoadEntryPoints(void)
+{
+    MODULEENTRY entry;
+    NE_MODULE *pModule;
+    DBG_ADDR addr;
+    char buffer[256];
+    unsigned char *cpnt, *name;
+    unsigned int address;
+    BOOL ok;
+
+    fprintf( stderr, "Adding symbols from loaded modules\n" );
+    for (ok = ModuleFirst(&entry); ok; ok = ModuleNext(&entry))
+    {
+        if (!(pModule = (NE_MODULE *)GlobalLock( entry.hModule ))) continue;
+
+        name = (unsigned char *)pModule + pModule->name_table;
+
+        /* First search the resident names */
+
+        cpnt = (unsigned char *)pModule + pModule->name_table;
+        while (*cpnt)
+        {
+            cpnt += *cpnt + 1 + sizeof(WORD);
+            sprintf( buffer, "%*.*s.%*.*s", *name, *name, name + 1,
+                     *cpnt, *cpnt, cpnt + 1 );
+            if ((address = MODULE_GetEntryPoint( entry.hModule,
+                                            *(WORD *)(cpnt + *cpnt + 1) )))
+            {
+                addr.seg = HIWORD(address);
+                addr.off = LOWORD(address);
+                DEBUG_AddSymbol( buffer, &addr );
+            }
+        }
+
+        /* Now search the non-resident names table */
+
+        if (!pModule->nrname_handle) continue;  /* No non-resident table */
+        cpnt = (char *)GlobalLock( pModule->nrname_handle );
+        while (*cpnt)
+        {
+            cpnt += *cpnt + 1 + sizeof(WORD);
+            sprintf( buffer, "%*.*s.%*.*s", *name, *name, name + 1,
+                     *cpnt, *cpnt, cpnt + 1 );
+            if ((address = MODULE_GetEntryPoint( entry.hModule,
+                                                *(WORD *)(cpnt + *cpnt + 1) )))
+            {
+                addr.seg = HIWORD(address);
+                addr.off = LOWORD(address);
+                DEBUG_AddSymbol( buffer, &addr );
+            }
+        }
     }
 }
diff --git a/debugger/info.c b/debugger/info.c
index 109161d..4914a15 100644
--- a/debugger/info.c
+++ b/debugger/info.c
@@ -1,161 +1,115 @@
 /*
  * Wine debugger utility routines
- * Eric Youngdale
- * 9/93
+ *
+ * Copyright 1993 Eric Youngdale
+ * Copyright 1995 Alexandre Julliard
  */
 
 #include <stdio.h>
 #include <stdlib.h>
 #include "debugger.h"
 
-extern char * find_nearest_symbol( unsigned int seg, unsigned int addr );
 
-void print_address( unsigned int segment, unsigned int addr, int addrlen )
+/***********************************************************************
+ *           DEBUG_Print
+ *
+ * Implementation of the 'print' command.
+ */
+void DEBUG_Print( const DBG_ADDR *addr, int count, char format )
 {
-    char *name = find_nearest_symbol( segment, addr );
+    if (count != 1)
+    {
+        fprintf( stderr, "Count other than 1 is meaningless in 'print' command\n" );
+        return;
+    }
 
-    if (segment) fprintf( stderr, "0x%04x:", segment );
-    if (addrlen == 16) fprintf( stderr, "0x%04x", addr );
-    else fprintf( stderr, "0x%08x", addr );
+    if (addr->seg && (addr->seg != 0xffffffff))
+    {
+        switch(format)
+        {
+	case 'x':
+            fprintf( stderr, "0x%04lx:", addr->seg );
+            break;
+
+	case 'd':
+            fprintf( stderr, "%ld:", addr->seg );
+            break;
+
+	case 'c':
+            break;  /* No segment to print */
+
+	case 'i':
+	case 's':
+	case 'w':
+	case 'b':
+            break;  /* Meaningless format */
+        }
+    }
+
+    switch(format)
+    {
+    case 'x':
+        if (addr->seg) fprintf( stderr, "0x%04lx\n", addr->off );
+        else fprintf( stderr, "0x%08lx\n", addr->off );
+        break;
+
+    case 'd':
+        fprintf( stderr, "%ld\n", addr->off );
+        break;
+
+    case 'c':
+        fprintf( stderr, "%d = '%c'\n",
+                 (char)(addr->off & 0xff), (char)(addr->off & 0xff) );
+        break;
+
+    case 'i':
+    case 's':
+    case 'w':
+    case 'b':
+        fprintf( stderr, "Format specifier '%c' is meaningless in 'print' command\n", format );
+        break;
+    }
+}
+
+
+/***********************************************************************
+ *           DEBUG_PrintAddress
+ *
+ * Print an 16- or 32-bit address, with the nearest symbol if any.
+ */
+void DEBUG_PrintAddress( const DBG_ADDR *addr, int addrlen )
+{
+    const char *name = DEBUG_FindNearestSymbol( addr );
+
+    if (addr->seg) fprintf( stderr, "0x%04lx:", addr->seg );
+    if (addrlen == 16) fprintf( stderr, "0x%04lx", addr->off );
+    else fprintf( stderr, "0x%08lx", addr->off );
     if (name) fprintf( stderr, " (%s)", name );
 }
 
 
-void examine_memory( unsigned int segment, unsigned int addr,
-                     int count, char format )
+/***********************************************************************
+ *           DEBUG_Help
+ *
+ * Implementation of the 'help' command.
+ */
+void DEBUG_Help(void)
 {
-    char * pnt;
-    unsigned int * dump;
-    unsigned short int * wdump;
-    int i;
-
-    if (segment == 0xffffffff) segment = (format == 'i' ? CS : DS);
-    if ((segment == WINE_CODE_SELECTOR) || (segment == WINE_DATA_SELECTOR))
-        segment = 0;
-
-    if (format != 'i' && count > 1)
-    {
-        print_address( segment, addr, dbg_mode );
-        fprintf(stderr,":  ");
-    }
-
-    pnt = segment ? (char *)PTR_SEG_OFF_TO_LIN(segment,addr) : (char *)addr;
-
-    switch(format)
-    {
-	case 's':
-		if (count == 1) count = 256;
-	        while(*pnt && count) {
-			fputc( *pnt++, stderr);
-			count--;
-		};
-		fprintf(stderr,"\n");
-		return;
-
-	case 'i':
-		for(i=0; i<count; i++) {
-			print_address( segment, addr, dbg_mode );
-			fprintf(stderr,":  ");
-			addr = db_disasm( segment, addr );
-			fprintf(stderr,"\n");
-		};
-		return;
-	case 'x':
-		dump = (unsigned int *)pnt;
-		for(i=0; i<count; i++) 
-		{
-			fprintf(stderr," %8.8x", *dump++);
-                        addr += 4;
-			if ((i % 8) == 7) {
-				fprintf(stderr,"\n");
-				print_address( segment, addr, dbg_mode );
-				fprintf(stderr,":  ");
-			};
-		}
-		fprintf(stderr,"\n");
-		return;
-	
-	case 'd':
-		dump = (unsigned int *)pnt;
-		for(i=0; i<count; i++) 
-		{
-			fprintf(stderr," %d", *dump++);
-                        addr += 4;
-			if ((i % 8) == 7) {
-				fprintf(stderr,"\n");
-				print_address( segment, addr, dbg_mode );
-				fprintf(stderr,":  ");
-			};
-		}
-		fprintf(stderr,"\n");
-		return;
-	
-	case 'w':
-		wdump = (unsigned short *)pnt;
-		for(i=0; i<count; i++) 
-		{
-			fprintf(stderr," %04x", *wdump++);
-                        addr += 2;
-			if ((i % 10) == 7) {
-				fprintf(stderr,"\n");
-				print_address( segment, addr, dbg_mode );
-				fprintf(stderr,":  ");
-			};
-		}
-		fprintf(stderr,"\n");
-		return;
-	
-	case 'c':
-		for(i=0; i<count; i++) 
-		{
-			if(*pnt < 0x20) {
-				fprintf(stderr,"  ");
-				pnt++;
-			} else
-				fprintf(stderr," %c", *pnt++);
-                        addr++;
-			if ((i % 32) == 7) {
-				fprintf(stderr,"\n");
-				print_address( segment, addr, dbg_mode );
-				fprintf(stderr,":  ");
-			};
-		}
-		fprintf(stderr,"\n");
-		return;
-	
-	case 'b':
-		for(i=0; i<count; i++) 
-		{
-			fprintf(stderr," %02x", (*pnt++) & 0xff);
-                        addr++;
-			if ((i % 32) == 7) {
-				fprintf(stderr,"\n");
-				print_address( segment, addr, dbg_mode );
-				fprintf(stderr,":  ");
-			};
-		}
-		fprintf(stderr,"\n");
-		return;
-	};
-	
-	/* The rest are fairly straightforward */
-
-	fprintf(stderr,"examine mem: %x %d %c\n", addr, count, format);
-}
-
-char * helptext[] = {
+    int i = 0;
+    static const char * helptext[] =
+{
 "The commands accepted by the Wine debugger are a small subset",
 "of the commands that gdb would accept.  The commands currently",
 "are:\n",
 "  break [*<addr>]                      delete break bpnum",
 "  disable bpnum                        enable bpnum",
 "  help                                 quit",
-"  x <expr>                             cont",
+"  x <addr>                             cont",
 "  step                                 next",
 "  mode [16,32]                         print <expr>",
-"  set <reg> = <expr>                   set *<expr> = <expr>",
+"  set <reg> = <expr>                   set *<addr> = <expr>",
 "  info [reg,stack,break,segments]      bt",
-"  symbolfile <filename>                define <identifier> <expr>",
+"  symbolfile <filename>                define <identifier> <addr>",
 "",
 "The 'x' command accepts repeat counts and formats (including 'i') in the",
 "same way that gdb does.",
@@ -166,10 +120,8 @@
 " symbolfile command.  Symbols can also be defined individually with",
 " the define command.",
 "",
-NULL};
+NULL
+};
 
-void dbg_help(){
-	int i;
-	i = 0;
-	while(helptext[i]) fprintf(stderr,"%s\n", helptext[i++]);
+    while(helptext[i]) fprintf(stderr,"%s\n", helptext[i++]);
 }
diff --git a/debugger/memory.c b/debugger/memory.c
new file mode 100644
index 0000000..80dfcd3
--- /dev/null
+++ b/debugger/memory.c
@@ -0,0 +1,159 @@
+/*
+ * Debugger memory handling
+ *
+ * Copyright 1993 Eric Youngdale
+ * Copyright 1995 Alexandre Julliard
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "debugger.h"
+
+
+/***********************************************************************
+ *           DEBUG_ReadMemory
+ *
+ * Read a memory value.
+ */
+int DEBUG_ReadMemory( const DBG_ADDR *address )
+{
+    DBG_ADDR addr = *address;
+
+    DBG_FIX_ADDR_SEG( &addr, DS_reg(DEBUG_context) );
+    return *(int *)DBG_ADDR_TO_LIN( &addr );
+}
+
+
+/***********************************************************************
+ *           DEBUG_WriteMemory
+ *
+ * Store a value in memory.
+ */
+void DEBUG_WriteMemory( const DBG_ADDR *address, int value )
+{
+    DBG_ADDR addr = *address;
+
+    DBG_FIX_ADDR_SEG( &addr, DS_reg(DEBUG_context) );
+    *(int *)DBG_ADDR_TO_LIN( &addr ) = value;
+}
+
+
+/***********************************************************************
+ *           DEBUG_ExamineMemory
+ *
+ * Implementation of the 'x' command.
+ */
+void DEBUG_ExamineMemory( const DBG_ADDR *address, int count, char format )
+{
+    DBG_ADDR addr = *address;
+    unsigned char * pnt;
+    unsigned int * dump;
+    unsigned short int * wdump;
+    int i;
+
+    DBG_FIX_ADDR_SEG( &addr, (format == 'i') ?
+                             CS_reg(DEBUG_context) : DS_reg(DEBUG_context) );
+
+    if (format != 'i' && count > 1)
+    {
+        DEBUG_PrintAddress( &addr, dbg_mode );
+        fprintf(stderr,":  ");
+    }
+
+    pnt = DBG_ADDR_TO_LIN( &addr );
+
+    switch(format)
+    {
+	case 's':
+		if (count == 1) count = 256;
+	        while(*pnt && count--) fputc( *pnt++, stderr );
+		fprintf(stderr,"\n");
+		return;
+
+	case 'i':
+		while (count--)
+                {
+                    DEBUG_PrintAddress( &addr, dbg_mode );
+                    fprintf(stderr,":  ");
+                    DEBUG_Disasm( &addr );
+                    fprintf(stderr,"\n");
+		}
+		return;
+	case 'x':
+		dump = (unsigned int *)pnt;
+		for(i=0; i<count; i++) 
+		{
+			fprintf(stderr," %8.8x", *dump++);
+                        addr.off += 4;
+			if ((i % 8) == 7) {
+				fprintf(stderr,"\n");
+				DEBUG_PrintAddress( &addr, dbg_mode );
+				fprintf(stderr,":  ");
+			};
+		}
+		fprintf(stderr,"\n");
+		return;
+	
+	case 'd':
+		dump = (unsigned int *)pnt;
+		for(i=0; i<count; i++) 
+		{
+			fprintf(stderr," %d", *dump++);
+                        addr.off += 4;
+			if ((i % 8) == 7) {
+				fprintf(stderr,"\n");
+				DEBUG_PrintAddress( &addr, dbg_mode );
+				fprintf(stderr,":  ");
+			};
+		}
+		fprintf(stderr,"\n");
+		return;
+	
+	case 'w':
+		wdump = (unsigned short *)pnt;
+		for(i=0; i<count; i++) 
+		{
+			fprintf(stderr," %04x", *wdump++);
+                        addr.off += 2;
+			if ((i % 10) == 7) {
+				fprintf(stderr,"\n");
+				DEBUG_PrintAddress( &addr, dbg_mode );
+				fprintf(stderr,":  ");
+			};
+		}
+		fprintf(stderr,"\n");
+		return;
+	
+	case 'c':
+		for(i=0; i<count; i++) 
+		{
+			if(*pnt < 0x20) {
+				fprintf(stderr,"  ");
+				pnt++;
+			} else
+				fprintf(stderr," %c", *pnt++);
+                        addr.off++;
+			if ((i % 32) == 7) {
+				fprintf(stderr,"\n");
+				DEBUG_PrintAddress( &addr, dbg_mode );
+				fprintf(stderr,":  ");
+			};
+		}
+		fprintf(stderr,"\n");
+		return;
+	
+	case 'b':
+		for(i=0; i<count; i++) 
+		{
+			fprintf(stderr," %02x", (*pnt++) & 0xff);
+                        addr.off++;
+			if ((i % 32) == 7) {
+				fprintf(stderr,"\n");
+				DEBUG_PrintAddress( &addr, dbg_mode );
+				fprintf(stderr,":  ");
+			};
+		}
+		fprintf(stderr,"\n");
+		return;
+	}
+}
diff --git a/debugger/readline/Makefile.in b/debugger/readline/Makefile.in
index 9f2023e..5f32753 100644
--- a/debugger/readline/Makefile.in
+++ b/debugger/readline/Makefile.in
@@ -5,7 +5,7 @@
 DIVINCL = -I$(TOPSRC)/include
 LD	= @LD@
 LDCOMBINEFLAGS = @LDCOMBINEFLAGS@
-DIVDEFS	= -DHIDE -DANSI_ARROWS
+DIVDEFS	= @DEFS@ -DHIDE -DANSI_ARROWS
 
 
 MODULE 	= readline
@@ -25,26 +25,16 @@
 depend:
 	sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
 	$(CC) $(DIVINCL) $(XINCL) -MM *.c >> tmp_make
-	cp tmp_make Makefile
-	rm tmp_make
+	mv tmp_make Makefile
 
 clean:
 	rm -f *.o \#*\# *~ tmp_make
 
 distclean: clean
-	rm Makefile
+	rm -f Makefile
 
 countryclean:
 
-NAMES = $(SRCS:.c=)
-
-winelibclean:
-	for i in $(NAMES); do \
-	if test `grep -c WINELIB $$i.c` -ne 0; then \
-	rm $$i.o; \
-	fi; \
-	done
- 
 dummy:
 
 ### Dependencies:
diff --git a/debugger/readline/sysunix.c b/debugger/readline/sysunix.c
index e2b72e1..fdc8d2d 100644
--- a/debugger/readline/sysunix.c
+++ b/debugger/readline/sysunix.c
@@ -3,7 +3,10 @@
 **  Unix system-dependant routines for editline library.
 */
 #include "editline.h"
+
+#ifdef HAVE_CONFIG_H
 #include "config.h"
+#endif
 
 #if	defined(HAVE_TCGETATTR)
 #include <termios.h>
diff --git a/debugger/registers.c b/debugger/registers.c
index 4d948e9..a8b66a5 100644
--- a/debugger/registers.c
+++ b/debugger/registers.c
@@ -8,7 +8,7 @@
 #include "debugger.h"
 
 
-struct sigcontext_struct *context;
+struct sigcontext_struct *DEBUG_context;
 
 
 
@@ -21,30 +21,30 @@
 {
     switch(reg)
     {
-        case REG_EAX: EAX = val; break;
-        case REG_EBX: EBX = val; break;
-        case REG_ECX: ECX = val; break;
-        case REG_EDX: EDX = val; break;
-        case REG_ESI: ESI = val; break;
-        case REG_EDI: EDI = val; break;
-        case REG_EBP: EBP = val; break;
-        case REG_EFL: EFL = val; break;
-        case REG_EIP: EIP = val; break;
-        case REG_ESP: ESP = val; break;
-        case REG_AX:  AX  = val; break;
-        case REG_BX:  BX  = val; break;
-        case REG_CX:  CX  = val; break;
-        case REG_DX:  DX  = val; break;
-        case REG_SI:  SI  = val; break;
-        case REG_DI:  DI  = val; break;
-        case REG_BP:  BP  = val; break;
-        case REG_FL:  FL  = val; break;
-        case REG_IP:  IP  = val; break;
-        case REG_SP:  SP  = val; break;
-        case REG_CS:  CS  = val; break;
-        case REG_DS:  DS  = val; break;
-        case REG_ES:  ES  = val; break;
-        case REG_SS:  SS  = val; break;
+        case REG_EAX: EAX_reg(DEBUG_context) = val; break;
+        case REG_EBX: EBX_reg(DEBUG_context) = val; break;
+        case REG_ECX: ECX_reg(DEBUG_context) = val; break;
+        case REG_EDX: EDX_reg(DEBUG_context) = val; break;
+        case REG_ESI: ESI_reg(DEBUG_context) = val; break;
+        case REG_EDI: EDI_reg(DEBUG_context) = val; break;
+        case REG_EBP: EBP_reg(DEBUG_context) = val; break;
+        case REG_EFL: EFL_reg(DEBUG_context) = val; break;
+        case REG_EIP: EIP_reg(DEBUG_context) = val; break;
+        case REG_ESP: ESP_reg(DEBUG_context) = val; break;
+        case REG_AX:  AX_reg(DEBUG_context)  = val; break;
+        case REG_BX:  BX_reg(DEBUG_context)  = val; break;
+        case REG_CX:  CX_reg(DEBUG_context)  = val; break;
+        case REG_DX:  DX_reg(DEBUG_context)  = val; break;
+        case REG_SI:  SI_reg(DEBUG_context)  = val; break;
+        case REG_DI:  DI_reg(DEBUG_context)  = val; break;
+        case REG_BP:  BP_reg(DEBUG_context)  = val; break;
+        case REG_FL:  FL_reg(DEBUG_context)  = val; break;
+        case REG_IP:  IP_reg(DEBUG_context)  = val; break;
+        case REG_SP:  SP_reg(DEBUG_context)  = val; break;
+        case REG_CS:  CS_reg(DEBUG_context)  = val; break;
+        case REG_DS:  DS_reg(DEBUG_context)  = val; break;
+        case REG_ES:  ES_reg(DEBUG_context)  = val; break;
+        case REG_SS:  SS_reg(DEBUG_context)  = val; break;
     }
 }
 
@@ -58,30 +58,30 @@
 {
     switch(reg)
     {
-        case REG_EAX: return EAX;
-        case REG_EBX: return EBX;
-        case REG_ECX: return ECX;
-        case REG_EDX: return EDX;
-        case REG_ESI: return ESI;
-        case REG_EDI: return EDI;
-        case REG_EBP: return EBP;
-        case REG_EFL: return EFL;
-        case REG_EIP: return EIP;
-        case REG_ESP: return ESP;
-        case REG_AX:  return AX;
-        case REG_BX:  return BX;
-        case REG_CX:  return CX;
-        case REG_DX:  return DX;
-        case REG_SI:  return SI;
-        case REG_DI:  return DI;
-        case REG_BP:  return BP;
-        case REG_FL:  return FL;
-        case REG_IP:  return IP;
-        case REG_SP:  return SP;
-        case REG_CS:  return CS;
-        case REG_DS:  return DS;
-        case REG_ES:  return ES;
-        case REG_SS:  return SS;
+        case REG_EAX: return EAX_reg(DEBUG_context);
+        case REG_EBX: return EBX_reg(DEBUG_context);
+        case REG_ECX: return ECX_reg(DEBUG_context);
+        case REG_EDX: return EDX_reg(DEBUG_context);
+        case REG_ESI: return ESI_reg(DEBUG_context);
+        case REG_EDI: return EDI_reg(DEBUG_context);
+        case REG_EBP: return EBP_reg(DEBUG_context);
+        case REG_EFL: return EFL_reg(DEBUG_context);
+        case REG_EIP: return EIP_reg(DEBUG_context);
+        case REG_ESP: return ESP_reg(DEBUG_context);
+        case REG_AX:  return AX_reg(DEBUG_context);
+        case REG_BX:  return BX_reg(DEBUG_context);
+        case REG_CX:  return CX_reg(DEBUG_context);
+        case REG_DX:  return DX_reg(DEBUG_context);
+        case REG_SI:  return SI_reg(DEBUG_context);
+        case REG_DI:  return DI_reg(DEBUG_context);
+        case REG_BP:  return BP_reg(DEBUG_context);
+        case REG_FL:  return FL_reg(DEBUG_context);
+        case REG_IP:  return IP_reg(DEBUG_context);
+        case REG_SP:  return SP_reg(DEBUG_context);
+        case REG_CS:  return CS_reg(DEBUG_context);
+        case REG_DS:  return DS_reg(DEBUG_context);
+        case REG_ES:  return ES_reg(DEBUG_context);
+        case REG_SS:  return SS_reg(DEBUG_context);
     }
     return 0;  /* should not happen */
 }
@@ -98,22 +98,30 @@
     fprintf(stderr,"Register dump:\n");
 
     /* First get the segment registers out of the way */
-    fprintf( stderr," CS:%04x SS:%04x DS:%04x ES:%04x\n", CS, SS, DS, ES );
+    fprintf( stderr," CS:%04x SS:%04x DS:%04x ES:%04x\n",
+             CS_reg(DEBUG_context), SS_reg(DEBUG_context),
+             DS_reg(DEBUG_context), ES_reg(DEBUG_context) );
 
     if (dbg_mode == 16)
     {
         fprintf( stderr," IP:%04x SP:%04x BP:%04x FLAGS:%04x\n",
-                 IP, SP, BP, FL );
+                 IP_reg(DEBUG_context), SP_reg(DEBUG_context),
+                 BP_reg(DEBUG_context), FL_reg(DEBUG_context) );
 	fprintf( stderr," AX:%04x BX:%04x CX:%04x DX:%04x SI:%04x DI:%04x\n",
-                 AX, BX, CX, DX, SI, DI );
+                 AX_reg(DEBUG_context), BX_reg(DEBUG_context),
+                 CX_reg(DEBUG_context), DX_reg(DEBUG_context),
+                 SI_reg(DEBUG_context), DI_reg(DEBUG_context) );
     }
     else  /* 32-bit mode */
     {
         fprintf( stderr, " EIP:%08lx ESP:%08lx EBP:%08lx EFLAGS:%08lx\n", 
-                 EIP, ESP, EBP, EFL );
+                 EIP_reg(DEBUG_context), ESP_reg(DEBUG_context),
+                 EBP_reg(DEBUG_context), EFL_reg(DEBUG_context) );
 	fprintf( stderr, " EAX:%08lx EBX:%08lx ECX:%08lx EDX:%08lx\n", 
-		 EAX, EBX, ECX, EDX);
-	fprintf( stderr, " ESI:%08lx EDI:%08lx\n", ESI, EDI);
+		 EAX_reg(DEBUG_context), EBX_reg(DEBUG_context),
+                 ECX_reg(DEBUG_context), EDX_reg(DEBUG_context) );
+	fprintf( stderr, " ESI:%08lx EDI:%08lx\n",
+                 ESI_reg(DEBUG_context), EDI_reg(DEBUG_context) );
     }
 }
 
diff --git a/debugger/stack.c b/debugger/stack.c
index 16a4b62..73fcacf 100644
--- a/debugger/stack.c
+++ b/debugger/stack.c
@@ -32,15 +32,21 @@
  */
 void DEBUG_InfoStack(void)
 {
+    DBG_ADDR addr;
+
     fprintf(stderr,"Stack dump:\n");
-    if ((SS == WINE_DATA_SELECTOR) ||
-        (GET_SEL_FLAGS(SS) & LDT_FLAGS_32BIT))  /* 32-bit mode */
-    {
-        examine_memory( 0, ESP, 10, 'x' );
+    if ((SS_reg(DEBUG_context) == WINE_DATA_SELECTOR) ||
+        (GET_SEL_FLAGS(SS_reg(DEBUG_context)) & LDT_FLAGS_32BIT))
+    {  /* 32-bit mode */
+        addr.seg = 0;
+        addr.off = ESP_reg(DEBUG_context);
+        DEBUG_ExamineMemory( &addr, 10, 'x' );
     }
     else  /* 16-bit mode */
     {
-        examine_memory( SS, SP, 10, 'w' );
+        addr.seg = SS_reg(DEBUG_context);
+        addr.off = SP_reg(DEBUG_context);
+        DEBUG_ExamineMemory( &addr, 10, 'w' );
     }
     fprintf(stderr,"\n");
 }
@@ -53,25 +59,29 @@
  */
 void DEBUG_BackTrace(void)
 {
-  int frameno = 0;
+    DBG_ADDR addr;
+    int frameno = 0;
 
   fprintf(stderr,"Backtrace:\n");
-  if (SS == WINE_DATA_SELECTOR)  /* 32-bit mode */
+  if (SS_reg(DEBUG_context) == WINE_DATA_SELECTOR)  /* 32-bit mode */
   {
-      FRAME32 *frame = (FRAME32 *)EBP;
+      FRAME32 *frame = (FRAME32 *)EBP_reg(DEBUG_context);
+      addr.seg = 0;
       while (frame->ip)
       {
           fprintf(stderr,"%d ",frameno++);
-          print_address( 0, frame->ip, 32 );
+          addr.off = frame->ip;
+          DEBUG_PrintAddress( &addr, 32 );
           fprintf( stderr, "\n" );
           frame = (FRAME32 *)frame->bp;
       }
   }
   else  /* 16-bit mode */
   {
-      FRAME16 *frame = (FRAME16 *)PTR_SEG_OFF_TO_LIN( SS, BP & ~1 );
-      WORD cs = CS;
-      if (GET_SEL_FLAGS(SS) & LDT_FLAGS_32BIT)
+      FRAME16 *frame = (FRAME16 *)PTR_SEG_OFF_TO_LIN( SS_reg(DEBUG_context),
+                                                  BP_reg(DEBUG_context) & ~1 );
+      WORD cs = CS_reg(DEBUG_context);
+      if (GET_SEL_FLAGS(SS_reg(DEBUG_context)) & LDT_FLAGS_32BIT)
       {
           fprintf( stderr, "Not implemented: 32-bit backtrace on a different stack segment.\n" );
           return;
@@ -80,9 +90,12 @@
       {
           if (frame->bp & 1) cs = frame->cs;
           fprintf( stderr,"%d ", frameno++ );
-          print_address( cs, frame->ip, 16 );
+          addr.seg = cs;
+          addr.off = frame->ip;
+          DEBUG_PrintAddress( &addr, 16 );
           fprintf( stderr, "\n" );
-          frame = (FRAME16 *)PTR_SEG_OFF_TO_LIN( SS, frame->bp & ~1 );
+          frame = (FRAME16 *)PTR_SEG_OFF_TO_LIN( SS_reg(DEBUG_context),
+                                                 frame->bp & ~1 );
       }
   }
   fprintf( stderr, "\n" );
diff --git a/if1632/Makefile.in b/if1632/Makefile.in
index 71ea491..225d5fb 100644
--- a/if1632/Makefile.in
+++ b/if1632/Makefile.in
@@ -31,31 +31,21 @@
 .c.o:
 	$(CC) -c $(CFLAGS) $(XINCL) $(DIVINCL) -o $*.o $<
 
-.spec.S:
-	$(BUILD) -spec16 $< > $*.S
-
 .S.o:
 	$(CC) -c -o $*.o $<  
 
+.spec.S:
+	$(BUILD) -spec16 $< > $*.S
+
+.spec.c:
+	$(BUILD) -spec32 $< > $*.c
+
 all: checkbuild $(MODULE).o
 
-gdi32.c: gdi32.spec
-	$(BUILD) -spec32 gdi32.spec > gdi32.c
-
-kernel32.c: kernel32.spec
-	$(BUILD) -spec32 kernel32.spec > kernel32.c
-
-shell32.c: shell32.spec
-	$(BUILD) -spec32 shell32.spec > shell32.c
-
-user32.c: user32.spec
-	$(BUILD) -spec32 user32.spec > user32.c
-
-winprocs32.c: winprocs32.spec
-	$(BUILD) -spec32 winprocs32.spec > winprocs32.c
+$(SFILES): $(TOPSRC)/tools/build
 
 checkbuild:
-	(cd $(TOPSRC)/tools; $(MAKE) 'CC=$(CC)' 'CFLAGS=$(CFLAGS)' 'LD=$(LD)' 'LDCOMBINEFLAGS=$(LDCOMBINEFLAGS)')
+	cd $(TOPSRC)/tools; $(MAKE) 'CC=$(CC)' 'CFLAGS=$(CFLAGS)' 'LD=$(LD)' 'LDCOMBINEFLAGS=$(LDCOMBINEFLAGS)' build
 
 call16.S: $(TOPSRC)/include/callback.h
 	$(TOPSRC)/tools/build -call16 `cat $(TOPSRC)/include/callback.h | grep "extern.*CallTo16_" | sed 's/.*CallTo16_\(.*\)(.*/\1/' | sort | uniq` > call16.S
@@ -63,26 +53,23 @@
 call32.S: $(SFILES)
 	$(BUILD) -call32 `cat $(SFILES) | grep CallTo32_ | sed 's/.*CallTo32_\(.*\)/\1/' | sort | uniq` > call32.S
 
-
 $(MODULE).o: $(OBJS)
 	$(LD) $(LDCOMBINEFLAGS) $(OBJS) -o $(MODULE).o
 
 depend:
 	sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
-	$(CC) $(DIVINCL) $(XINCL) -MM callback.c relay32.c relay.c >> tmp_make
-	cp tmp_make Makefile
-	rm tmp_make
+	$(CC) $(DIVINCL) $(XINCL) -MM $(SRCS) >> tmp_make
+	mv tmp_make Makefile
 
 clean:
-	rm -f *.o \#*\# *~ *.S gdi32.c kernel32.c shell32.c user32.c winprocs32.c tmp_make
+	rm -f *.o \#*\# *~ tmp_make
+	rm -f $(DLLS16:.spec=.S) $(DLLS32:.spec=.c) call32.S call16.S
 
 distclean: clean
-	rm Makefile
+	rm -f Makefile
 
 countryclean:
 
-winelibclean:
- 
 dummy:
 
 ### Dependencies:
diff --git a/if1632/callback.c b/if1632/callback.c
index 2587ee6..c60f46a 100644
--- a/if1632/callback.c
+++ b/if1632/callback.c
@@ -76,6 +76,7 @@
     pFrame->bp         = lpbuf[6];
     pFrame->ip         = lpbuf[7];
     pFrame->cs         = lpbuf[8];
+    pFrame->es         = 0;
     return retval;
 }
 
diff --git a/if1632/kernel.spec b/if1632/kernel.spec
index a351242..a08132b 100644
--- a/if1632/kernel.spec
+++ b/if1632/kernel.spec
@@ -64,8 +64,8 @@
 66  pascal16 AllocResource(word word long) AllocResource
 67  stub SetResourceHandler
 68  pascal16 InitAtomTable(word) InitAtomTable
-69  pascal16 FindAtom(ptr) FindAtom
-70  pascal16 AddAtom(ptr) AddAtom
+69  pascal16 FindAtom(segptr) FindAtom
+70  pascal16 AddAtom(segptr) AddAtom
 71  pascal16 DeleteAtom(word) DeleteAtom
 72  pascal16 GetAtomName(word ptr word) GetAtomName
 73  pascal16 GetAtomHandle(word) GetAtomHandle
diff --git a/if1632/relay.c b/if1632/relay.c
index 72de966..9322a25 100644
--- a/if1632/relay.c
+++ b/if1632/relay.c
@@ -156,7 +156,9 @@
     {
         struct sigcontext_struct *context = (struct sigcontext_struct *)args16;
         printf( "     AX=%04x BX=%04x CX=%04x DX=%04x SI=%04x DI=%04x ES=%04x EFL=%08lx\n",
-                AX, BX, CX, DX, SI, DI, ES, EFL );
+                AX_reg(context), BX_reg(context), CX_reg(context),
+                DX_reg(context), SI_reg(context), DI_reg(context),
+                ES_reg(context), EFL_reg(context) );
     }
 }
 
diff --git a/if1632/user.spec b/if1632/user.spec
index 8be2aa3..72f2b7f 100644
--- a/if1632/user.spec
+++ b/if1632/user.spec
@@ -49,7 +49,7 @@
 47  pascal16 IsWindow(word) IsWindow
 48  pascal16 IsChild(word word) IsChild
 49  pascal16 IsWindowVisible(word) IsWindowVisible
-50  pascal16 FindWindow(ptr ptr) FindWindow
+50  pascal16 FindWindow(segptr ptr) FindWindow
 #51 BEAR51
 52  pascal16 AnyPopup() AnyPopup
 53  pascal16 DestroyWindow(word) DestroyWindow
@@ -115,7 +115,7 @@
 114 pascal   DispatchMessage(ptr) DispatchMessage
 115 stub ReplyMessage
 116 pascal16 PostAppMessage(word word word long) PostAppMessage
-118 pascal16 RegisterWindowMessage(ptr) RegisterWindowMessage
+118 pascal16 RegisterWindowMessage(long) RegisterWindowMessage
 119 pascal   GetMessagePos() GetMessagePos
 120 pascal   GetMessageTime() GetMessageTime
 121 pascal   SetWindowsHook(s_word segptr) SetWindowsHook
@@ -269,9 +269,9 @@
 265 pascal16 ShowOwnedPopups(word word) ShowOwnedPopups
 266 pascal16 SetMessageQueue(word) SetMessageQueue
 267 pascal16 ShowScrollBar(word word word) ShowScrollBar
-268 pascal16 GlobalAddAtom(ptr) GlobalAddAtom
+268 pascal16 GlobalAddAtom(segptr) GlobalAddAtom
 269 pascal16 GlobalDeleteAtom(word) GlobalDeleteAtom
-270 pascal16 GlobalFindAtom(ptr) GlobalFindAtom
+270 pascal16 GlobalFindAtom(segptr) GlobalFindAtom
 271 pascal16 GlobalGetAtomName(word ptr s_word) GlobalGetAtomName
 272 pascal16 IsZoomed(word) IsZoomed
 273 stub ControlPanelInfo
@@ -334,7 +334,7 @@
 400 stub FinalUserInit
 402 pascal16 GetPriorityClipboardFormat(word ptr s_word)
              GetPriorityClipboardFormat
-403 pascal16 UnregisterClass(ptr word) UnregisterClass
+403 pascal16 UnregisterClass(segptr word) UnregisterClass
 404 pascal16 GetClassInfo(word segptr ptr) GetClassInfo
 406 pascal16 CreateCursor(word word word word word ptr ptr) CreateCursor
 407 pascal16 CreateIcon(word word word byte byte ptr ptr) CreateIcon
diff --git a/include/atom.h b/include/atom.h
index 631f185..706b709 100644
--- a/include/atom.h
+++ b/include/atom.h
@@ -25,20 +25,10 @@
     HANDLE      entries[1];
 } ATOMTABLE;
 
-#ifdef WINELIB
-#define LocalAlign(flags,bytes) LocalAlloc (flags|LMEM_WINE_ALIGN,bytes)
-#else
-#define LocalAlign(flags,bytes) LocalAlloc((flags),(bytes))
-#endif
 
-ATOM LocalAddAtom( LPCSTR str );
+ATOM LocalAddAtom( SEGPTR str );
 ATOM LocalDeleteAtom( ATOM atom );
-ATOM LocalFindAtom( LPCSTR str );
-WORD LocalGetAtomName( ATOM atom, LPSTR buffer, short count );
-
-ATOM LocalAddAtom( LPCSTR str );
-ATOM LocalDeleteAtom( ATOM atom );
-ATOM LocalFindAtom( LPCSTR str );
+ATOM LocalFindAtom( SEGPTR str );
 WORD LocalGetAtomName( ATOM atom, LPSTR buffer, short count );
 
 #endif  /* ATOM_H */
diff --git a/include/class.h b/include/class.h
index 5c99d1d..8e27cd3 100644
--- a/include/class.h
+++ b/include/class.h
@@ -32,7 +32,7 @@
 #endif
 
 
-HCLASS CLASS_FindClassByName( char * name, WORD hinstance, CLASS **ptr );
+HCLASS CLASS_FindClassByName( SEGPTR name, WORD hinstance, CLASS **ptr );
 CLASS * CLASS_FindClassPtr( HCLASS hclass );
 
 
diff --git a/include/config.h.in b/include/config.h.in
deleted file mode 100644
index 10c6b69..0000000
--- a/include/config.h.in
+++ /dev/null
@@ -1,6 +0,0 @@
-#undef HAVE_STDLIB_H
-#undef HAVE_TCGETATTR
-#undef HAVE_DIRENT_H
-#undef HAVE_SYS_NDIR_H
-#undef HAVE_NDIR_H
-#undef STAT_MACROS_BROKEN
diff --git a/include/debugger.h b/include/debugger.h
index 1955620..3311825 100644
--- a/include/debugger.h
+++ b/include/debugger.h
@@ -11,6 +11,20 @@
 #include "registers.h"
 #include "wine.h"
 
+typedef struct
+{
+    DWORD seg;  /* 0xffffffff means current default segment (cs or ds) */
+    DWORD off;
+} DBG_ADDR;
+
+#define DBG_FIX_ADDR_SEG(addr,default) \
+    { if ((addr)->seg == 0xffffffff) (addr)->seg = (default); \
+      if (((addr)->seg == WINE_CODE_SELECTOR) || \
+           (addr)->seg == WINE_DATA_SELECTOR) (addr)->seg = 0; }
+
+#define DBG_ADDR_TO_LIN(addr) \
+    ((addr)->seg ? (char *)PTR_SEG_OFF_TO_LIN((addr)->seg,(addr)->off) \
+                 : (char *)(addr)->off)
 
 enum debug_regs
 {
@@ -29,13 +43,13 @@
     EXEC_STEP_INSTR  /* Single-stepping an instruction */
 };
 
-extern struct sigcontext_struct *context;  /* debugger/registers.c */
+extern struct sigcontext_struct *DEBUG_context;  /* debugger/registers.c */
 extern unsigned int dbg_mode;
 
   /* debugger/break.c */
 extern void DEBUG_SetBreakpoints( BOOL set );
-extern int DEBUG_FindBreakpoint( unsigned int segment, unsigned int addr );
-extern void DEBUG_AddBreakpoint( unsigned int segment, unsigned int addr );
+extern int DEBUG_FindBreakpoint( const DBG_ADDR *addr );
+extern void DEBUG_AddBreakpoint( const DBG_ADDR *addr );
 extern void DEBUG_DelBreakpoint( int num );
 extern void DEBUG_EnableBreakpoint( int num, BOOL enable );
 extern void DEBUG_InfoBreakpoints(void);
@@ -45,6 +59,27 @@
 extern void DEBUG_RestartExecution( struct sigcontext_struct *context,
                                     enum exec_mode mode, int instr_len );
 
+  /* debugger/db_disasm.c */
+extern void DEBUG_Disasm( DBG_ADDR *addr );
+
+  /* debugger/hash.c */
+extern void DEBUG_AddSymbol( const char *name, const DBG_ADDR *addr );
+extern BOOL DEBUG_GetSymbolValue( const char * name, DBG_ADDR *addr );
+extern BOOL DEBUG_SetSymbolValue( const char * name, const DBG_ADDR *addr );
+extern const char * DEBUG_FindNearestSymbol( const DBG_ADDR *addr );
+extern void DEBUG_ReadSymbolTable( const char * filename );
+extern void DEBUG_LoadEntryPoints(void);
+
+  /* debugger/info.c */
+extern void DEBUG_Print( const DBG_ADDR *addr, int count, char format );
+extern void DEBUG_PrintAddress( const DBG_ADDR *addr, int addrlen );
+extern void DEBUG_Help(void);
+
+  /* debugger/memory.c */
+extern int DEBUG_ReadMemory( const DBG_ADDR *address );
+extern void DEBUG_WriteMemory( const DBG_ADDR *address, int value );
+extern void DEBUG_ExamineMemory( const DBG_ADDR *addr, int count, char format);
+
   /* debugger/registers.c */
 extern void DEBUG_SetRegister( enum debug_regs reg, int val );
 extern int DEBUG_GetRegister( enum debug_regs reg );
@@ -57,7 +92,4 @@
   /* debugger/dbg.y */
 extern void wine_debug( int signal, struct sigcontext_struct * regs );
 
-extern void print_address( unsigned int seg, unsigned int addr, int addrlen );
-extern unsigned int db_disasm( unsigned int segment, unsigned int loc );
-
 #endif  /* DEBUGGER_H */
diff --git a/include/miscemu.h b/include/miscemu.h
index 2507a80..2309274 100644
--- a/include/miscemu.h
+++ b/include/miscemu.h
@@ -2,7 +2,7 @@
 #define __WINE_MISCEMU_H
 
 #include "wintypes.h"
-#include "wine.h"
+#include "registers.h"
 
 extern BOOL INSTR_EmulateInstruction( struct sigcontext_struct *context );
 
@@ -16,10 +16,12 @@
 extern void INT21_Init(void);
 
 
-#define INT_BARF(num) \
+#define INT_BARF(context,num) \
     fprintf( stderr, "int%x: unknown/not implemented parameters:\n" \
                      "int%x: AX %04x, BX %04x, CX %04x, DX %04x, " \
                      "SI %04x, DI %04x, DS %04x, ES %04x\n", \
-             (num), (num), AX, BX, CX, DX, SI, DI, DS, ES )
+             (num), (num), AX_reg(context), BX_reg(context), CX_reg(context), \
+             DX_reg(context), SI_reg(context), DI_reg(context), \
+             DS_reg(context), ES_reg(context) )
 
 #endif /* __WINE_MISCEMU_H */
diff --git a/include/msdos.h b/include/msdos.h
index 636ae22..2922d13 100644
--- a/include/msdos.h
+++ b/include/msdos.h
@@ -31,7 +31,9 @@
 	BYTE dummy2[9];
 };
 
-#define DOSVERSION 0x0005      /* Major version in low byte: DOS 5.00 */
+
+#define DOSVERSION 0x1606      /* Major version in low byte: DOS 6.22 */
+#define WINDOSVER  0x0616      /* Windows reports the DOS version reversed */
 #define WINVERSION 0x0a03      /* Windows version 3.10 */
 
 #define MAX_DOS_DRIVES	26
diff --git a/include/ole.h b/include/ole.h
index 7da0a78..fd87acf 100644
--- a/include/ole.h
+++ b/include/ole.h
@@ -2,9 +2,11 @@
  *	ole.h	-	Declarations for OLESVR and OLECLI
  */
 
+typedef LPCSTR	OLE_LPCSTR;
+
 typedef enum
 {
-    OLE_OK,
+    OLE_OK=0, /* Yes Sir! */
     OLE_WAIT_FOR_RELEASE,
     OLE_BUSY,
     OLE_ERROR_PROTECT_ONLY,
@@ -66,19 +68,141 @@
 typedef enum{
 	OLE_SERVER_MULTI,
 	OLE_SERVER_SINGLE
-}OLE_SERVER_USE;
+} OLE_SERVER_USE;
+/* dunno if the values are correct, somebody please check */
+typedef enum {
+	OLE_CHANGED,
+	OLE_CLOSED,
+	OLE_QUERY_PAINT,
+	OLE_QUERY_RETRY,
+	OLE_RELEASE,
+	OLE_RENAMED,
+	OLE_SAVED
+} OLE_NOTIFICATION;
 
 typedef	LONG	LHSERVER;
 typedef LONG	LHSERVERDOC;
 typedef LONG	LHCLIENTDOC;
+typedef LONG	OLECLIPFORMAT;/* dunno about this type, please change/add */
+typedef LONG	OLEOPT_UPDATE;/* dunno about this type, please change/add */
+typedef OLEOPT_UPDATE*	LPOLEOPT_UPDATE;/* dunno about this type, please change/add */
+typedef LONG	*OLE_RELEASE_METHOD;/* dunno */
+
+typedef struct _OLETARGETDEVICE {
+	UINT	otdDeviceNameOffset;
+	UINT	otdDriverNameOffset;
+	UINT	otdPortNameOffset;
+	UINT	otdExtDevmodeOffset;
+	UINT	otdExtDevmodeSize;
+	UINT	otdEnvironmentOffset;
+	UINT	otdEnvironmentSize;
+	BYTE	otdData[1];
+	/* ... */
+} OLETARGETDEVICE;
+typedef struct _OLESTREAM* LPOLESTREAM;
+typedef struct _OLESTREAMVTBL {
+	DWORD	(CALLBACK* Get)(LPOLESTREAM,LPSTR,DWORD);
+	DWORD	(CALLBACK* Put)(LPOLESTREAM,LPSTR,DWORD);
+} OLESTREAMVTBL;
+typedef OLESTREAMVTBL*	LPOLESTREAMVTBL;
+typedef struct _OLESTREAM {
+	LPOLESTREAMVTBL	lpstbl;
+} OLESTREAM;
+typedef struct _OLESERVERDOC*	LPOLESERVERDOC;
+typedef struct _OLEOBJECT*	LPOLEOBJECT;
+typedef struct _OLECLIENT*	LPOLECLIENT;
+typedef struct _OLESERVERDOCVTBL {
+	OLESTATUS	(CALLBACK* Save)(LPOLESERVERDOC);
+	OLESTATUS	(CALLBACK* Close)(LPOLESERVERDOC);
+	OLESTATUS	(CALLBACK* SetHostNames)(LPOLESERVERDOC,OLE_LPCSTR,OLE_LPCSTR);
+	OLESTATUS	(CALLBACK* SetDocDimensions)(LPOLESERVERDOC,LPRECT);
+	OLESTATUS	(CALLBACK* GetObject)(LPOLESERVERDOC,OLE_LPCSTR,LPOLEOBJECT*,LPOLECLIENT);
+	OLESTATUS	(CALLBACK* Release)(LPOLESERVERDOC);
+	OLESTATUS	(CALLBACK* SetColorScheme)(LPOLESERVERDOC,LPLOGPALETTE);
+	OLESTATUS	(CALLBACK* Execute)(LPOLESERVERDOC,HGLOBAL);
+} OLESERVERDOCVTBL;
+typedef OLESERVERDOCVTBL*	LPOLESERVERDOCVTBL;
+typedef struct _OLESERVERDOC {
+	LPOLESERVERDOCVTBL	lpvtbl;
+	/* server provided state info */
+} OLESERVERDOC;
 
 typedef struct _OLESERVER*	LPOLESERVER;
-typedef struct _OLESERVERDOC*	LPOLESERVERDOC;
+typedef struct _OLESERVERVTBL {
+	OLESTATUS	(CALLBACK* Open)(LPOLESERVER,LHSERVERDOC,OLE_LPCSTR,LPOLESERVERDOC *);
+	OLESTATUS	(CALLBACK* Create)(LPOLESERVER,LHSERVERDOC,OLE_LPCSTR,OLE_LPCSTR,LPOLESERVERDOC FAR*);
+	OLESTATUS	(CALLBACK* CreateFromTemplate)(LPOLESERVER,LHSERVERDOC,OLE_LPCSTR,OLE_LPCSTR,OLE_LPCSTR,LPOLESERVERDOC *);
+	OLESTATUS	(CALLBACK* Edit)(LPOLESERVER,LHSERVERDOC,OLE_LPCSTR,OLE_LPCSTR,LPOLESERVERDOC *);
+	OLESTATUS	(CALLBACK* Exit)(LPOLESERVER);
+	OLESTATUS	(CALLBACK* Release)(LPOLESERVER); 
+	OLESTATUS	(CALLBACK* Execute)(LPOLESERVER); 
+} OLESERVERVTBL; 
+typedef OLESERVERVTBL	*LPOLESERVERVTBL;
+typedef struct _OLESERVER {
+	LPOLESERVERVTBL	lpvtbl;
+	/* server specific data */
+} OLESERVER;
+typedef struct _OLECLIENTVTBL {
+	int (CALLBACK* CallBack)(LPOLECLIENT,OLE_NOTIFICATION,LPOLEOBJECT);
+} OLECLIENTVTBL;
+typedef OLECLIENTVTBL	*LPOLECLIENTVTBL;
 
-OLESTATUS WINAPI OleRegisterServer(LPCSTR,LPOLESERVER,LHSERVER FAR*,HINSTANCE,OLE_SERVER_USE);
-OLESTATUS WINAPI OleUnblockServer(LHSERVER,BOOL FAR*);
-OLESTATUS WINAPI OleRegisterServerDoc(LHSERVER,LPCSTR,LPOLESERVERDOC,LHSERVERDOC FAR*);
-OLESTATUS WINAPI OleRegisterClientDoc(LPCSTR,LPCSTR,LONG,LHCLIENTDOC FAR*);
+typedef struct _OLECLIENT {
+	LPOLECLIENTVTBL	lpvtbl;
+	/* client data... */
+} OLECLIENT;
+
+typedef struct _OLEOBJECTVTBL {
+	void *	(CALLBACK* QueryProtocol)(LPOLEOBJECT,OLE_LPCSTR);
+	OLESTATUS	(CALLBACK* Release)(LPOLEOBJECT);
+	OLESTATUS	(CALLBACK* Show)(LPOLEOBJECT,BOOL);
+	OLESTATUS	(CALLBACK* DoVerb)(LPOLEOBJECT,UINT,BOOL,BOOL);
+	OLESTATUS	(CALLBACK* GetData)(LPOLEOBJECT,OLECLIPFORMAT,HANDLE *);
+	OLESTATUS	(CALLBACK* SetData)(LPOLEOBJECT,OLECLIPFORMAT,HANDLE);
+	OLESTATUS	(CALLBACK* SetTargetDevice)(LPOLEOBJECT,HGLOBAL);
+	OLESTATUS	(CALLBACK* SetBounds)(LPOLEOBJECT,LPRECT);
+	OLESTATUS	(CALLBACK* EnumFormats)(LPOLEOBJECT,OLECLIPFORMAT);
+	OLESTATUS	(CALLBACK* SetColorScheme)(LPOLEOBJECT,LPLOGPALETTE);
+	OLESTATUS	(CALLBACK* Delete)(LPOLEOBJECT);
+	OLESTATUS	(CALLBACK* SetHostNames)(LPOLEOBJECT,OLE_LPCSTR,OLE_LPCSTR);
+	OLESTATUS	(CALLBACK* SaveToStream)(LPOLEOBJECT,LPOLESTREAM);
+	OLESTATUS	(CALLBACK* Clone)(LPOLEOBJECT,LPOLECLIENT,LHCLIENTDOC,OLE_LPCSTR,LPOLEOBJECT *);
+	OLESTATUS	(CALLBACK* CopyFromLink)(LPOLEOBJECT,LPOLECLIENT,LHCLIENTDOC,OLE_LPCSTR,LPOLEOBJECT *);
+	OLESTATUS	(CALLBACK* Equal)(LPOLEOBJECT,LPOLEOBJECT);
+	OLESTATUS	(CALLBACK* CopyToClipBoard)(LPOLEOBJECT);
+	OLESTATUS	(CALLBACK* Draw)(LPOLEOBJECT,HDC,LPRECT,LPRECT,HDC);
+	OLESTATUS	(CALLBACK* Activate)(LPOLEOBJECT,UINT,BOOL,BOOL,HWND,LPRECT);
+	OLESTATUS	(CALLBACK* Execute)(LPOLEOBJECT,HGLOBAL,UINT);
+	OLESTATUS	(CALLBACK* Close)(LPOLEOBJECT);
+	OLESTATUS	(CALLBACK* Update)(LPOLEOBJECT);
+	OLESTATUS	(CALLBACK* Reconnect)(LPOLEOBJECT);
+	OLESTATUS	(CALLBACK* ObjectConvert)(LPOLEOBJECT,OLE_LPCSTR,LPOLECLIENT,LHCLIENTDOC,OLE_LPCSTR,LPOLEOBJECT*);
+	OLESTATUS	(CALLBACK* GetLinkUpdateOptions)(LPOLEOBJECT,LPOLEOPT_UPDATE);
+	OLESTATUS	(CALLBACK* SetLinkUpdateOptions)(LPOLEOBJECT,OLEOPT_UPDATE);
+	OLESTATUS	(CALLBACK* Rename)(LPOLEOBJECT,OLE_LPCSTR);
+	OLESTATUS	(CALLBACK* QueryName)(LPOLEOBJECT,LPSTR,LPUINT);
+	OLESTATUS	(CALLBACK* QueryType)(LPOLEOBJECT,LPLONG);
+	OLESTATUS	(CALLBACK* QueryBounds)(LPOLEOBJECT,LPRECT);
+	OLESTATUS	(CALLBACK* QuerySize)(LPOLEOBJECT,LPDWORD);
+	OLESTATUS	(CALLBACK* QueryOpen)(LPOLEOBJECT);
+	OLESTATUS	(CALLBACK* QueryOutOfDate)(LPOLEOBJECT);
+	OLESTATUS	(CALLBACK* QueryReleaseStatus)(LPOLEOBJECT);
+	OLESTATUS	(CALLBACK* QueryReleaseError)(LPOLEOBJECT);
+	OLE_RELEASE_METHOD	(CALLBACK* QueryReleaseMethod)(LPOLEOBJECT);
+	OLESTATUS	(CALLBACK* RequestData)(LPOLEOBJECT,OLECLIPFORMAT);
+	OLESTATUS	(CALLBACK* ObjectLong)(LPOLEOBJECT,UINT,LPLONG);
+} OLEOBJECTVTBL;
+typedef OLEOBJECTVTBL*	LPOLEOBJECTVTBL;
+
+typedef struct _OLEOBJECT {
+	LPOLEOBJECTVTBL	lpvtbl;
+} OLEOBJECT;
+
+
+OLESTATUS WINAPI OleRegisterServer(LPCSTR,LPOLESERVER,LHSERVER *,HINSTANCE,OLE_SERVER_USE);
+OLESTATUS WINAPI OleUnblockServer(LHSERVER,BOOL *);
+OLESTATUS WINAPI OleRegisterServerDoc(LHSERVER,LPCSTR,LPOLESERVERDOC,LHSERVERDOC *);
+OLESTATUS WINAPI OleRegisterClientDoc(LPCSTR,LPCSTR,LONG,LHCLIENTDOC *);
 OLESTATUS WINAPI OleRenameClientDoc(LHCLIENTDOC,LPCSTR);
 OLESTATUS WINAPI OleRevokeServerDoc(LHSERVERDOC);
 OLESTATUS WINAPI OleRevokeClientDoc(LHCLIENTDOC);
diff --git a/include/options.h b/include/options.h
index a19ae57..ee1e3dc 100644
--- a/include/options.h
+++ b/include/options.h
@@ -18,7 +18,8 @@
     int    debug;
     int    allowReadOnly;   /* Opening a read only file will succeed even
 			       if write access is requested */
-    int    enhanced;        /* Start Wine in enhanced mode */ 
+    int    enhanced;        /* Start Wine in enhanced mode */
+    int    ipc;             /* Use IPC mechanisms */
 };
 
 extern struct options Options;
diff --git a/include/registers.h b/include/registers.h
index e6253f3..7e2e4e4 100644
--- a/include/registers.h
+++ b/include/registers.h
@@ -1,73 +1,68 @@
+/*
+ * Register definitions
+ *
+ * Copyright 1995 Alexandre Julliard
+ */
+
 #ifndef __WINE_REGISTERS_H
 #define __WINE_REGISTERS_H
 
 #include <windows.h>
-
-#ifndef PROCEMU
-
 #include "wine.h"
 
-#define EAX (context->sc_eax)
-#define EBX (context->sc_ebx)
-#define ECX (context->sc_ecx)
-#define EDX (context->sc_edx)
-#define ESI (context->sc_esi)
-#define EDI (context->sc_edi)
-#define EBP (context->sc_ebp)
-
-#define AX (*(WORD*)&context->sc_eax)
-#define BX (*(WORD*)&context->sc_ebx)
-#define CX (*(WORD*)&context->sc_ecx)
-#define DX (*(WORD*)&context->sc_edx)
-#define SI (*(WORD*)&context->sc_esi)
-#define DI (*(WORD*)&context->sc_edi)
-#define BP (*(WORD*)&context->sc_ebp)
-
-#define AL (*(BYTE*)&context->sc_eax)
-#define AH (*(((BYTE*)&context->sc_eax)+1))
-#define BL (*(BYTE*)&context->sc_ebx)
-#define BH (*(((BYTE*)&context->sc_ebx)+1))
-#define CL (*(BYTE*)&context->sc_ecx)
-#define CH (*(((BYTE*)&context->sc_ecx)+1))
-#define DL (*(BYTE*)&context->sc_edx)
-#define DH (*(((BYTE*)&context->sc_edx)+1))
-
-#define CS (context->sc_cs)
-#define DS (context->sc_ds)
-#define ES (context->sc_es)
-#define SS (context->sc_ss)
-
-#ifdef linux
-#define FS (context->sc_fs)
-#define GS (context->sc_gs)
+#define EAX_reg(context)     ((context)->sc_eax)
+#define EBX_reg(context)     ((context)->sc_ebx)
+#define ECX_reg(context)     ((context)->sc_ecx)
+#define EDX_reg(context)     ((context)->sc_edx)
+#define ESI_reg(context)     ((context)->sc_esi)
+#define EDI_reg(context)     ((context)->sc_edi)
+#define EBP_reg(context)     ((context)->sc_ebp)
+                            
+#define AX_reg(context)      (*(WORD*)&((context)->sc_eax))
+#define BX_reg(context)      (*(WORD*)&((context)->sc_ebx))
+#define CX_reg(context)      (*(WORD*)&((context)->sc_ecx))
+#define DX_reg(context)      (*(WORD*)&((context)->sc_edx))
+#define SI_reg(context)      (*(WORD*)&((context)->sc_esi))
+#define DI_reg(context)      (*(WORD*)&((context)->sc_edi))
+#define BP_reg(context)      (*(WORD*)&((context)->sc_ebp))
+                            
+#define AL_reg(context)      (*(BYTE*)(&(context)->sc_eax))
+#define AH_reg(context)      (*(((BYTE*)(&(context)->sc_eax)+1)))
+#define BL_reg(context)      (*(BYTE*)(&(context)->sc_ebx))
+#define BH_reg(context)      (*(((BYTE*)(&(context)->sc_ebx)+1)))
+#define CL_reg(context)      (*(BYTE*)(&(context)->sc_ecx))
+#define CH_reg(context)      (*(((BYTE*)(&(context)->sc_ecx)+1)))
+#define DL_reg(context)      (*(BYTE*)(&(context)->sc_edx))
+#define DH_reg(context)      (*(((BYTE*)(&(context)->sc_edx)+1)))
+                            
+#define CS_reg(context)      ((context)->sc_cs)
+#define DS_reg(context)      ((context)->sc_ds)
+#define ES_reg(context)      ((context)->sc_es)
+#define SS_reg(context)      ((context)->sc_ss)
+                            
+#ifdef linux                
+#define FS_reg(context)      ((context)->sc_fs)
+#define GS_reg(context)      ((context)->sc_gs)
 #else  /* FIXME: are fs and gs supported under *BSD? */
-#define FS  0
-#define GS  0
-#endif
+#define FS_reg(context)      0
+#define GS_reg(context)      0
+#endif                      
+                            
+#ifndef __FreeBSD__         
+#define EFL_reg(context)     ((context)->sc_eflags)
+#define FL_reg(context)      (*(WORD*)(&(context)->sc_eflags))
+#else                       
+#define EFL_reg(context)     ((context)->sc_efl)
+#define FL_reg(context)      (*(WORD*)(&(context)->sc_efl))
+#endif                      
+                            
+#define EIP_reg(context)     ((context)->sc_eip)
+#define ESP_reg(context)     ((context)->sc_esp)
+                            
+#define IP_reg(context)      (*(WORD*)(&(context)->sc_eip))
+#define SP_reg(context)      (*(WORD*)(&(context)->sc_esp))
+                            
+#define SET_CFLAG(context)   (EFL_reg(context) |= 0x0001)
+#define RESET_CFLAG(context) (EFL_reg(context) &= 0xfffffffe)
 
-#ifndef __FreeBSD__
-#define EFL (context->sc_eflags)
-#define FL (*(WORD*)&context->sc_eflags)
-#else
-#define EFL (context->sc_efl)
-#define FL (*(WORD*)&context->sc_efl)
-#endif
-
-#define EIP (context->sc_eip)
-#define ESP (context->sc_esp)
-
-#define IP  (*(WORD*)&context->sc_eip)
-#define SP  (*(WORD*)&context->sc_esp)
-
-#define SetCflag	(EFL |= 0x00000001)
-#define ResetCflag	(EFL &= 0xfffffffe)
-
-#else
-
-#include "bx_bochs.h"
-
-#define SetCflag	bx_STC()
-#define ResetCflag	bx_CLC()
-
-#endif /* PROCEMU */
 #endif /* __WINE_REGISTERS_H */
diff --git a/include/win.h b/include/win.h
index 2322240..6b614aa 100644
--- a/include/win.h
+++ b/include/win.h
@@ -21,6 +21,12 @@
 #define WINSWITCH_CLASS_NAME "#32771"  /* WinSwitch */
 #define ICONTITLE_CLASS_NAME "#32772"  /* IconTitle */
 
+#define POPUPMENU_CLASS_ATOM MAKEINTATOM(32768)  /* PopupMenu */
+#define DESKTOP_CLASS_ATOM   MAKEINTATOM(32769)  /* Desktop */
+#define DIALOG_CLASS_ATOM    MAKEINTATOM(32770)  /* Dialog */
+#define WINSWITCH_CLASS_ATOM MAKEINTATOM(32771)  /* WinSwitch */
+#define ICONTITLE_CLASS_ATOM MAKEINTATOM(32772)  /* IconTitle */
+
 typedef struct tagWND
 {
     HWND         hwndNext;       /* Next sibling */
diff --git a/include/windows.h b/include/windows.h
index eb2f910..61a7618 100644
--- a/include/windows.h
+++ b/include/windows.h
@@ -56,8 +56,8 @@
 	HICON	hIcon;
 	HCURSOR	hCursor;
 	HBRUSH	hbrBackground;
-	LPSTR	lpszMenuName WINE_PACKED;
-	LPSTR   lpszClassName WINE_PACKED;
+	SEGPTR  lpszMenuName WINE_PACKED;
+	SEGPTR  lpszClassName WINE_PACKED;
 } WNDCLASS, *LPWNDCLASS;
 
 #define CS_VREDRAW          0x0001
@@ -429,8 +429,7 @@
 	
 typedef WORD ATOM;
 
-#define MAKEINTATOM(i)     ((LPCSTR)MAKELP(0, (i)))
-
+#define MAKEINTATOM(i)   ((SEGPTR)MAKELONG((i),0))
 
   /* Raster operations */
 
@@ -2399,12 +2398,12 @@
 F(void,ValidateCodeSegments)
 F(void,WaitMessage)
 F(void,Yield)
-Fa(ATOM,AddAtom,LPCSTR,a)
+Fa(ATOM,AddAtom,SEGPTR,a)
 Fa(ATOM,DeleteAtom,ATOM,a)
-Fa(ATOM,FindAtom,LPCSTR,a)
-Fa(ATOM,GlobalAddAtom,LPCSTR,a)
+Fa(ATOM,FindAtom,SEGPTR,a)
+Fa(ATOM,GlobalAddAtom,SEGPTR,a)
 Fa(ATOM,GlobalDeleteAtom,ATOM,a)
-Fa(ATOM,GlobalFindAtom,LPCSTR,a)
+Fa(ATOM,GlobalFindAtom,SEGPTR,a)
 Fa(ATOM,RegisterClass,LPWNDCLASS,a) 
 Fa(BOOL,BringWindowToTop,HWND,a)
 Fa(BOOL,DeleteDC,HDC,a)
@@ -2559,7 +2558,7 @@
 Fa(WORD,LocalSize,HLOCAL,a)
 Fa(WORD,RealizeDefaultPalette,HDC,a)
 Fa(WORD,RegisterClipboardFormat,LPCSTR,a)
-Fa(WORD,RegisterWindowMessage,LPCSTR,a)
+Fa(WORD,RegisterWindowMessage,SEGPTR,a)
 Fa(WORD,SetHandleCount,WORD,a)
 Fa(WORD,VkKeyScan,WORD,a)
 Fa(int,AddFontResource,LPSTR,a)
@@ -2651,7 +2650,7 @@
 Fb(BOOL,ShowWindow,HWND,a,int,b) 
 Fb(BOOL,TranslateMDISysAccel,HWND,a,LPMSG,b)
 Fb(BOOL,UnhookWindowsHook,short,a,FARPROC,b)
-Fb(BOOL,UnregisterClass,LPSTR,a,HANDLE,b)
+Fb(BOOL,UnregisterClass,SEGPTR,a,HANDLE,b)
 Fb(DWORD,GetNearestColor,HDC,a,DWORD,b)
 Fb(DWORD,SetBkColor,HDC,a,COLORREF,b)
 Fb(DWORD,SetMapperFlags,HDC,a,DWORD,b)
@@ -2683,7 +2682,7 @@
 Fb(HMENU,LookupMenuHandle,HMENU,a,INT,b)
 Fb(HPALETTE,GDISelectPalette,HDC,a,HPALETTE,b)
 Fb(HWND,ChildWindowFromPoint,HWND,a,POINT,b)
-Fb(HWND,FindWindow,LPSTR,a,LPSTR,b)
+Fb(HWND,FindWindow,SEGPTR,a,LPSTR,b)
 Fb(HWND,GetDlgItem,HWND,a,WORD,b)
 Fb(HWND,GetNextWindow,HWND,a,WORD,b)
 Fb(HWND,GetWindow,HWND,a,WORD,b)
diff --git a/ipc/Makefile.in b/ipc/Makefile.in
index fea89fe..fd2dfae 100644
--- a/ipc/Makefile.in
+++ b/ipc/Makefile.in
@@ -32,26 +32,16 @@
 depend:
 	sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
 	$(CC) $(DIVINCL) $(XINCL) -MM *.c >> tmp_make
-	cp tmp_make Makefile
-	rm tmp_make
+	mv tmp_make Makefile
 
 clean:
 	rm -f *.o \#*\# *~ tmp_make
 
 distclean: clean
-	rm Makefile
+	rm -f Makefile
 
 countryclean:
 
-NAMES = $(SRCS:.c=)
-
-winelibclean:
-	for i in $(NAMES); do \
-	if test `grep -c WINELIB $$i.c` -ne 0; then \
-	rm $$i.o; \
-	fi; \
-	done
- 
 dummy:
 
 ### Dependencies:
diff --git a/ipc/bit_array.c b/ipc/bit_array.c
index d4cede8..14d72e9 100644
--- a/ipc/bit_array.c
+++ b/ipc/bit_array.c
@@ -29,8 +29,9 @@
 #include <assert.h>
 
 #include "bit_array.h"
-#if defined(HAS_BITOPS)
-#  include <asm/bitops.h>
+#ifdef HAS_BITOPS
+#define inline __inline__  /* So we can compile with -ansi */
+#include <asm/bitops.h>
 #else
 static __inline__ int clear_bit(int bit, int *mem);
 static __inline__ int set_bit(int bit, int *mem);
diff --git a/ipc/dde_atom.c b/ipc/dde_atom.c
index c6ca2aa..e07690c 100644
--- a/ipc/dde_atom.c
+++ b/ipc/dde_atom.c
@@ -14,6 +14,7 @@
 #include "dde_atom.h"
 #include "shm_main_blk.h"
 #include "shm_fragment.h"
+#include "ldt.h"
 #include "stddebug.h"
 #include "debug.h"
 
@@ -109,20 +110,25 @@
  */
 
 /* important! don't forget to unlock semaphores before return */
-ATOM GlobalAddAtom( LPCSTR str )
+ATOM GlobalAddAtom( SEGPTR name )
 {
   int atom_idx;
   int atom_ofs;
   AtomData_ptr ptr;
   ATOM atom;
+  char *str;
 
-  dprintf_atom(stddeb,"GlobalAddAtom(%p)\n", str);
-  if ((unsigned) str < MIN_STR_ATOM)	   /* MS-windows convention */
-     return (ATOM) (unsigned) str;
-  if (str[0] == '#') {		   /* wine convention */
-     atom= (ATOM) atoi(&str[1]);
+  /* First check for integer atom */
+
+  if (!HIWORD(name)) return (ATOM)LOWORD(name);
+
+  str = (char *)PTR_SEG_TO_LIN( name );
+  if (str[0] == '#')
+  {
+     ATOM atom= (ATOM) atoi(&str[1]);
      return (atom<MIN_STR_ATOM) ? atom : 0;
   }
+
   dprintf_atom(stddeb,"GlobalAddAtom(\"%s\")\n",str);
 
   DDE_IPC_init();		/* will initialize only if needed */
@@ -199,15 +205,21 @@
 /***********************************************************************
  *           GlobalFindAtom   (USER.270)
  */
-ATOM GlobalFindAtom( LPCSTR str )
+ATOM GlobalFindAtom( SEGPTR name )
 {
   int atom_idx;
   int atom_ofs;
+  char *str;
 
-  dprintf_atom(stddeb,"GlobalFindAtom(%p)\n", str );
-  if ((unsigned) str < MIN_STR_ATOM) /* MS-windows convention */
-     return (ATOM) (unsigned) str;
-  if (str[0] == '#') {		   /* wine convention */
+  dprintf_atom(stddeb,"GlobalFindAtom(%08lx)\n", name );
+
+  /* First check for integer atom */
+
+  if (!HIWORD(name)) return (ATOM)LOWORD(name);
+
+  str = (char *)PTR_SEG_TO_LIN( name );
+  if (str[0] == '#')
+  {
      ATOM atom= (ATOM) atoi(&str[1]);
      return (atom<MIN_STR_ATOM) ? atom : 0;
   }
diff --git a/ipc/generic_hash.c b/ipc/generic_hash.c
index 6cee5d3..f5e0f44 100644
--- a/ipc/generic_hash.c
+++ b/ipc/generic_hash.c
@@ -5,6 +5,7 @@
  * Purpose :  dynamically growing hash, may use shared or local memory.
  ***************************************************************************
  */
+#include <sys/types.h>
 #include <stdlib.h>
 #include <assert.h>
 #include "generic_hash.h"
diff --git a/ipc/shm_block.c b/ipc/shm_block.c
index 057c981..77ff766 100644
--- a/ipc/shm_block.c
+++ b/ipc/shm_block.c
@@ -9,6 +9,7 @@
  */
 
 #define inline __inline__
+#include <sys/types.h>
 #include <sys/sem.h>
 #include <stdio.h>
 #include <assert.h>
diff --git a/ipc/shm_main_blk.c b/ipc/shm_main_blk.c
index 3fb798e..96b4681 100644
--- a/ipc/shm_main_blk.c
+++ b/ipc/shm_main_blk.c
@@ -8,6 +8,7 @@
  ***************************************************************************
  */
 #define inline __inline__
+#include <sys/types.h>
 #include <sys/sem.h>
 #include <stdio.h>
 #include <time.h>
@@ -62,7 +63,7 @@
 
 }
 
-int proc_exist(__pid_t pid)
+int proc_exist(pid_t pid)
 {
   if ( kill(pid,0) == 0)	   /* dummy signal to test existence */
      return 1;
@@ -189,7 +190,9 @@
 	 }
        } else {
 	  switch(errno) {
+#ifdef EIDRM
 	    case EIDRM:		   /* segment destroyed */
+#endif
 	    case EACCES:	   /* no user permision */
 	      break;
 
diff --git a/loader/Imakefile b/loader/Imakefile
index 3ec199f..848d137 100644
--- a/loader/Imakefile
+++ b/loader/Imakefile
@@ -9,7 +9,6 @@
 	ne_resource.c \
 	pe_image.c \
 	pe_resource.c \
-	selector.c \
 	signal.c \
 	resource.c \
 	task.c 
diff --git a/loader/Makefile.in b/loader/Makefile.in
index b9cd285..f250120 100644
--- a/loader/Makefile.in
+++ b/loader/Makefile.in
@@ -10,7 +10,7 @@
 MODULE 	= loader
 
 SRCS 	= main.c module.c ne_image.c ne_resource.c pe_image.c \
-	pe_resource.c selector.c signal.c resource.c task.c
+	pe_resource.c signal.c resource.c task.c
  
 OBJS = $(SRCS:.c=.o)
 
@@ -25,26 +25,16 @@
 depend:
 	sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
 	$(CC) $(DIVINCL) $(XINCL) -MM *.c >> tmp_make
-	cp tmp_make Makefile
-	rm tmp_make
+	mv tmp_make Makefile
 
 clean:
 	rm -f *.o \#*\# *~ tmp_make
 
 distclean: clean
-	rm Makefile
+	rm -f Makefile
 
 countryclean:
 
-NAMES = $(SRCS:.c=)
-
-winelibclean:
-	for i in $(NAMES); do \
-	if test `grep -c WINELIB $$i.c` -ne 0; then \
-	rm $$i.o; \
-	fi; \
-	done
- 
 dummy:
 
 ### Dependencies:
diff --git a/loader/main.c b/loader/main.c
index 0e301df..384e3f3 100644
--- a/loader/main.c
+++ b/loader/main.c
@@ -57,18 +57,15 @@
       /* Create built-in modules */
     if (!MODULE_Init()) return 0;
 
+      /* Initialize the DOS file system */
+    DOS_InitFS();
+
       /* Initialize tasks */
     if (!TASK_Init()) return 0;
 
       /* Initialize interrupt vectors */
     if (!INT_Init()) return 0;
 
-      /* Initialize the DOS file system */
-    DOS_InitFS();
-
-      /* Create DOS environment */
-    CreateSelectors();
-
       /* Initialize signal handling */
     init_wine_signals();
 
diff --git a/loader/module.c b/loader/module.c
index 12cf6ba..45891b3 100644
--- a/loader/module.c
+++ b/loader/module.c
@@ -35,8 +35,6 @@
  */
 BOOL MODULE_Init(void)
 {
-    extern void load_entrypoints( HMODULE );
-
     HMODULE hModule;
     NE_MODULE *pModule;
     SEGTABLEENTRY *pSegTable;
@@ -82,7 +80,6 @@
 
         pModule->next = hFirstModule;
         hFirstModule = hModule;
-        load_entrypoints( hModule );
     }
 
       /* Initialize some KERNEL exported values */
@@ -1169,6 +1166,22 @@
 }
 
 
+/***********************************************************************
+ *           GetWndProcEntry16 (not a Windows API function)
+ *
+ * Return an entry point from the WINPROCS dll.
+ */
+WNDPROC GetWndProcEntry16( char *name )
+{
+    WORD ordinal;
+    static HMODULE hModule = 0;
+
+    if (!hModule) hModule = GetModuleHandle( "WINPROCS" );
+    ordinal = MODULE_GetOrdinal( hModule, name );
+    return MODULE_GetEntryPoint( hModule, ordinal );
+}
+
+
 /**********************************************************************
  *	    ModuleFirst    (TOOLHELP.59)
  */
diff --git a/loader/resource.c b/loader/resource.c
index 4e6bbfc..90e9216 100644
--- a/loader/resource.c
+++ b/loader/resource.c
@@ -549,36 +549,33 @@
     if (hAccel == 0 || msg == NULL) return 0;
     if (msg->message != WM_KEYDOWN &&
     	msg->message != WM_KEYUP &&
+	msg->message != WM_SYSKEYDOWN &&
+	msg->message != WM_SYSKEYUP &&
     	msg->message != WM_CHAR) return 0;
 
     dprintf_accel(stddeb, "TranslateAccelerators hAccel=%04X !\n", hAccel);
 
     lpAccelTbl = (LPACCELHEADER)GlobalLock(hAccel);
     for (i = 0; i < lpAccelTbl->wCount; i++) {
-	if (lpAccelTbl->tbl[i].type & VIRTKEY_ACCEL) {
-	    if (msg->wParam == lpAccelTbl->tbl[i].wEvent &&
-		msg->message == WM_KEYDOWN) {
-		if ((lpAccelTbl->tbl[i].type & SHIFT_ACCEL) &&
-		    !(GetKeyState(VK_SHIFT) & 0xf)) {
+	if(lpAccelTbl->tbl[i].type & VIRTKEY_ACCEL) {
+	    if(msg->wParam == lpAccelTbl->tbl[i].wEvent &&
+	       (msg->message == WM_KEYDOWN || msg->message == WM_SYSKEYDOWN)) {
+		INT mask = 0;
+
+		if(GetKeyState(VK_SHIFT) & 0xf) mask |= SHIFT_ACCEL;
+		if(GetKeyState(VK_CONTROL) & 0xf) mask |= CONTROL_ACCEL;
+		if(GetKeyState(VK_MENU) & 0xf) mask |= ALT_ACCEL;
+		if(mask == (lpAccelTbl->tbl[i].type &
+			    (SHIFT_ACCEL | CONTROL_ACCEL | ALT_ACCEL))) {
+		    SendMessage(hWnd, WM_COMMAND, lpAccelTbl->tbl[i].wIDval,
+				0x00010000L);
 		    GlobalUnlock(hAccel);
-		    return 0;
-		}
-		if ((lpAccelTbl->tbl[i].type & CONTROL_ACCEL) &&
-		    !(GetKeyState(VK_CONTROL) & 0xf)) {
-		    GlobalUnlock(hAccel);
-		    return 0;
-		}
-		if ((lpAccelTbl->tbl[i].type & ALT_ACCEL) &&
-		    !(GetKeyState(VK_MENU) & 0xf)) {
-		    GlobalUnlock(hAccel);
-		    return 0;
-		}
-		SendMessage(hWnd, WM_COMMAND, lpAccelTbl->tbl[i].wIDval, 0x00010000L);
-		GlobalUnlock(hAccel);
-		return 1;
-		}
-	    if (msg->message == WM_KEYUP) return 1;
+		    return 1;
+	        }
+		if (msg->message == WM_KEYUP || msg->message == WM_SYSKEYUP)
+		    return 1;
 	    }
+	}
 	else {
 	    if (msg->wParam == lpAccelTbl->tbl[i].wEvent &&
 		msg->message == WM_CHAR) {
@@ -619,6 +616,8 @@
     dprintf_resource( stddeb, "strlen = %d\n", (int)*p );
     
     i = min(buflen - 1, *p);
+    if (buffer == NULL)
+	return i;
     if (i > 0) {
 	memcpy(buffer, p + 1, i);
 	buffer[i] = '\0';
diff --git a/loader/selector.c b/loader/selector.c
deleted file mode 100644
index ab211bd..0000000
--- a/loader/selector.c
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Selector manipulation functions
- *
- * Copyright 1993 Robert J. Amstadt
- * Copyright 1995 Alexandre Julliard
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#ifndef WINELIB
-
-#include "windows.h"
-#include "global.h"
-#include "module.h"
-#include "stddebug.h"
-/* #define DEBUG_SELECTORS */
-#include "debug.h"
-
-
-#define MAX_ENV_SIZE 16384  /* Max. environment size (ought to be dynamic) */
-
-static HANDLE EnvironmentHandle = 0;
-
-
-extern char WindowsPath[256];
-
-extern char **environ;
-
-
-
-WNDPROC GetWndProcEntry16( char *name )
-{
-    WORD ordinal;
-    static HMODULE hModule = 0;
-
-    if (!hModule) hModule = GetModuleHandle( "WINPROCS" );
-    ordinal = MODULE_GetOrdinal( hModule, name );
-    return MODULE_GetEntryPoint( hModule, ordinal );
-}
-
-
-/***********************************************************************
- *           GetDOSEnvironment   (KERNEL.131)
- */
-SEGPTR GetDOSEnvironment(void)
-{
-    return WIN16_GlobalLock( EnvironmentHandle );
-}
-
-
-/**********************************************************************
- *           CreateEnvironment
- */
-static HANDLE CreateEnvironment(void)
-{
-    HANDLE handle;
-    char **e;
-    char *p;
-
-    handle = GlobalAlloc( GMEM_MOVEABLE, MAX_ENV_SIZE );
-    if (!handle) return 0;
-    p = (char *) GlobalLock( handle );
-
-    /*
-     * Fill environment with Windows path, the Unix environment,
-     * and program name.
-     */
-    strcpy(p, "PATH=");
-    strcat(p, WindowsPath);
-    p += strlen(p) + 1;
-
-    for (e = environ; *e; e++)
-    {
-	if (strncasecmp(*e, "path", 4))
-	{
-	    strcpy(p, *e);
-	    p += strlen(p) + 1;
-	}
-    }
-
-    *p++ = '\0';
-
-    /*
-     * Display environment
-     */
-    p = (char *) GlobalLock( handle );
-    dprintf_selectors(stddeb, "Environment at %p\n", p);
-    for (; *p; p += strlen(p) + 1) dprintf_selectors(stddeb, "    %s\n", p);
-
-    return handle;
-}
-
-
-
-/**********************************************************************
- *					CreateSelectors
- */
-void CreateSelectors(void)
-{
-    if(!EnvironmentHandle) EnvironmentHandle = CreateEnvironment();
-}
-
-
-#endif /* ifndef WINELIB */
diff --git a/loader/signal.c b/loader/signal.c
index 4ede072..82d9651 100644
--- a/loader/signal.c
+++ b/loader/signal.c
@@ -55,13 +55,15 @@
 #endif
     if (signal != SIGTRAP)
     {
-        if (CS == WINE_CODE_SELECTOR)
+        if (CS_reg(context) == WINE_CODE_SELECTOR)
         {
             fprintf(stderr, "Segmentation fault in Wine program (%x:%lx)."
-                            "  Please debug\n", CS, EIP );
+                            "  Please debug\n",
+                            CS_reg(context), EIP_reg(context) );
         }
         else if (INSTR_EmulateInstruction( context )) return;
-        fprintf(stderr,"In win_fault %x:%lx\n", CS, EIP );
+        fprintf( stderr,"In win_fault %x:%lx\n",
+                 CS_reg(context), EIP_reg(context) );
     }
     XUngrabPointer(display, CurrentTime);
     XUngrabServer(display);
diff --git a/loader/task.c b/loader/task.c
index 53d1006..7350965 100644
--- a/loader/task.c
+++ b/loader/task.c
@@ -10,6 +10,7 @@
 #include "windows.h"
 #include "task.h"
 #include "callback.h"
+#include "dos_fs.h"
 #include "debugger.h"
 #include "global.h"
 #include "instance.h"
@@ -36,6 +37,7 @@
 static HTASK hTaskToKill = 0;
 static HTASK hLockedTask = 0;
 static WORD nTaskCount = 0;
+static HANDLE hDOSEnvironment = 0;
 
   /* TASK_Reschedule() 16-bit entry point */
 static FARPROC TASK_RescheduleProc;
@@ -43,13 +45,122 @@
 #define TASK_SCHEDULE()  CallTo16_word_(TASK_RescheduleProc,0)
 
 
+static HANDLE TASK_CreateDOSEnvironment(void);
+
+
 /***********************************************************************
  *           TASK_Init
  */
 BOOL TASK_Init(void)
 {
     TASK_RescheduleProc = (FARPROC)GetWndProcEntry16( "TASK_Reschedule" );
-    return TRUE;
+    if (!(hDOSEnvironment = TASK_CreateDOSEnvironment()))
+        fprintf( stderr, "Not enough memory for DOS Environment\n" );
+    return (hDOSEnvironment != 0);
+}
+
+
+/***********************************************************************
+ *           TASK_CreateDOSEnvironment
+ *
+ * Create the original DOS environment.
+ */
+static HANDLE TASK_CreateDOSEnvironment(void)
+{
+    static const char program_name[] = "KRNL386.EXE";
+    char **e, *p;
+    int initial_size, size;
+    HANDLE handle;
+
+    extern char **environ;
+    extern char WindowsDirectory[], SystemDirectory[];
+
+    /* DOS environment format:
+     * ASCIIZ   string 1
+     * ASCIIZ   string 2
+     * ...
+     * ASCIIZ   string n
+     * ASCIIZ   PATH=xxx
+     * ASCIIZ   windir=xxx
+     * BYTE     0
+     * WORD     1
+     * ASCIIZ   program name (e.g. C:\WINDOWS\SYSTEM\KRNL386.EXE)
+     */
+
+    /* First compute the size of the fixed part of the environment */
+
+    initial_size = 5 +                            /* PATH= */
+                   strlen(WindowsPath) + 1 +      /* path value */
+                   7 +                            /* windir= */
+                   strlen(WindowsDirectory) + 1 + /* windir value */
+                   1 +                            /* BYTE 0 at end */
+                   sizeof(WORD) +                 /* WORD 1 */
+                   strlen(SystemDirectory) + 1 +  /* program directory */
+                   strlen(program_name) + 1;      /* program name */
+
+    /* Compute the total size of the Unix environment (except path) */
+
+    for (e = environ, size = initial_size; *e; e++)
+    {
+	if (strncasecmp(*e, "path=", 5))
+	{
+            int len = strlen(*e) + 1;
+            if (size + len >= 32767)
+            {
+                fprintf( stderr, "Warning: environment larger than 32k.\n" );
+                break;
+            }
+            size += len;
+	}
+    }
+
+
+    /* Now allocate the environment */
+
+    if (!(handle = GlobalAlloc( GMEM_FIXED, size ))) return 0;
+    p = (char *)GlobalLock( handle );
+
+    /* And fill it with the Unix environment */
+
+    for (e = environ, size = initial_size; *e; e++)
+    {
+	if (strncasecmp(*e, "path=", 5))
+	{
+            int len = strlen(*e) + 1;
+            if (size + len >= 32767) break;
+            strcpy( p, *e );
+            size += len;
+            p    += len;
+	}
+    }
+
+    /* Now add the path and Windows directory */
+
+    strcpy( p, "PATH=" );
+    strcat( p, WindowsPath );
+    p += strlen(p) + 1;
+
+    strcpy( p, "windir=" );
+    strcat( p, WindowsDirectory );
+    p += strlen(p) + 1;
+
+    /* Now add the program name */
+
+    *p++ = '\0';
+    *(WORD *)p = 1;
+    p += sizeof(WORD);
+    strcpy( p, SystemDirectory );
+    strcat( p, "\\" );
+    strcat( p, program_name );
+
+    /* Display it */
+
+    p = (char *) GlobalLock( handle );
+    dprintf_task(stddeb, "Master DOS environment at %p\n", p);
+    for (; *p; p += strlen(p) + 1) dprintf_task(stddeb, "    %s\n", p);
+    dprintf_task( stddeb, "Progname: %s\n", p+3 );
+
+    return handle;
 }
 
 
@@ -229,7 +340,7 @@
                    0 /*dx*/, 0 /*si*/, ds_reg /*di*/ );
     /* This should never return */
     fprintf( stderr, "TASK_CallToStart: Main program returned!\n" );
-    exit(1);
+    TASK_KillCurrentTask( 1 );
 }
 
 
@@ -241,6 +352,7 @@
 {
     HTASK hTask;
     TDB *pTask;
+    HANDLE hParentEnv;
     NE_MODULE *pModule;
     SEGTABLEENTRY *pSegTable;
     LPSTR name;
@@ -260,7 +372,24 @@
     if (!hTask) return 0;
     pTask = (TDB *)GlobalLock( hTask );
 
-      /* get current directory */
+      /* Allocate the new environment block */
+
+    if (!(hParentEnv = hEnvironment))
+    {
+        TDB *pParent = (TDB *)GlobalLock( hCurrentTask );
+        hParentEnv = pParent ? pParent->pdb.environment : hDOSEnvironment;
+    }
+    /* FIXME: do we really need to make a copy also when */
+    /*        we don't use the parent environment? */
+    if (!(hEnvironment = GlobalAlloc( GMEM_FIXED, GlobalSize( hParentEnv ) )))
+    {
+        GlobalFree( hTask );
+        return 0;
+    }
+    memcpy( GlobalLock( hEnvironment ), GlobalLock( hParentEnv ),
+            GlobalSize( hParentEnv ) );
+
+      /* Get current directory */
     
     GetModuleFileName( hModule, filename, sizeof(filename) );
     name = strrchr(filename, '\\');
@@ -355,8 +484,8 @@
                  pSegTable[pModule->ss-1].minsize + pModule->stack_size) & ~1;
     stack16Top = (char *)PTR_SEG_OFF_TO_LIN( pTask->ss, pTask->sp );
     frame16 = (STACK16FRAME *)stack16Top - 1;
-    frame16->saved_ss = pTask->ss;
-    frame16->saved_sp = pTask->sp;
+    frame16->saved_ss = 0; /*pTask->ss;*/
+    frame16->saved_sp = 0; /*pTask->sp;*/
     frame16->ds = frame16->es = pTask->hInstance;
     frame16->entry_point = 0;
     frame16->ordinal_number = 24;  /* WINPROCS.24 is TASK_Reschedule */
@@ -380,8 +509,9 @@
 
     if (Options.debug)
     {
+        DBG_ADDR addr = { pSegTable[pModule->cs-1].selector, pModule->ip };
         fprintf( stderr, "Task '%s': ", name );
-        DEBUG_AddBreakpoint( pSegTable[pModule->cs-1].selector, pModule->ip );
+        DEBUG_AddBreakpoint( &addr );
     }
 
       /* Add the task to the linked list */
@@ -844,6 +974,18 @@
 
 
 /***********************************************************************
+ *           GetDOSEnvironment   (KERNEL.131)
+ */
+SEGPTR GetDOSEnvironment(void)
+{
+    TDB *pTask;
+
+    if (!(pTask = (TDB *)GlobalLock( hCurrentTask ))) return 0;
+    return WIN16_GlobalLock( pTask->pdb.environment );
+}
+
+
+/***********************************************************************
  *           GetNumTasks   (KERNEL.152)
  */
 WORD GetNumTasks(void)
diff --git a/memory/Imakefile b/memory/Imakefile
index 8dbf16f..5d738d1 100644
--- a/memory/Imakefile
+++ b/memory/Imakefile
@@ -3,10 +3,11 @@
 MODULE = memory
 
 SRCS = \
-	selector.c \
+	atom.c \
 	global.c \
 	ldt.c \
-	local.c
+	local.c \
+	selector.c
 
 OBJS = $(SRCS:.c=.o)
 
diff --git a/memory/Makefile.in b/memory/Makefile.in
index 80be79a..e056dce 100644
--- a/memory/Makefile.in
+++ b/memory/Makefile.in
@@ -9,7 +9,12 @@
 
 MODULE 	= memory
 
-SRCS	= selector.c global.c ldt.c local.c
+SRCS = \
+	atom.c \
+	global.c \
+	ldt.c \
+	local.c \
+	selector.c
  
 OBJS = $(SRCS:.c=.o)
 
@@ -24,26 +29,16 @@
 depend:
 	sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
 	$(CC) $(DIVINCL) $(XINCL) -MM *.c >> tmp_make
-	cp tmp_make Makefile
-	rm tmp_make
+	mv tmp_make Makefile
 
 clean:
 	rm -f *.o \#*\# *~ tmp_make
 
 distclean: clean
-	rm Makefile
+	rm -f Makefile
 
 countryclean:
 
-NAMES = $(SRCS:.c=)
-
-winelibclean:
-	for i in $(NAMES); do \
-	if test `grep -c WINELIB $$i.c` -ne 0; then \
-	rm $$i.o; \
-	fi; \
-	done
- 
 dummy:
 
 ### Dependencies:
diff --git a/misc/atom.c b/memory/atom.c
similarity index 86%
rename from misc/atom.c
rename to memory/atom.c
index f3286cd..db76863 100644
--- a/misc/atom.c
+++ b/memory/atom.c
@@ -5,22 +5,10 @@
  */
 
 /*
- * Current limitations:
- *
- * - The code assumes that LocalAlloc() returns a block aligned on a
- * 4-bytes boundary (because of the shifting done in HANDLETOATOM).
- * If this is not the case, the allocation code will have to be changed.
- *
- * - Integer atoms created with MAKEINTATOM are not supported.  This is
- * because they can't generally be differentiated from string constants
- * located below 0x10000 in the emulation library.  If you need
- * integer atoms, use the "#1234" form.
- *
- * 13/Feb, miguel
- * Changed the calls to LocalAlloc to LocalAlign. When compiling WINELIB
- * you call a special version of LocalAlloc that would do the alignement.
- * When compiling the emulator we depend on LocalAlloc returning the
- * aligned block. Needed to test the Library.
+ * Warning: The code assumes that LocalAlloc() returns a block aligned
+ * on a 4-bytes boundary (because of the shifting done in
+ * HANDLETOATOM).  If this is not the case, the allocation code will
+ * have to be changed.
  */
 
 #include <stdlib.h>
@@ -130,20 +118,22 @@
 /***********************************************************************
  *           ATOM_AddAtom
  */
-static ATOM ATOM_AddAtom( WORD selector, LPCSTR str )
+static ATOM ATOM_AddAtom( WORD selector, SEGPTR name )
 {
     WORD hash;
     HANDLE entry;
     ATOMENTRY * entryPtr;
     ATOMTABLE * table;
     int len;
-    
-    if ((len = strlen( str )) > 255) len = 255;
+    char *str;
 
-      /* Check for integer atom */
-/*    if (!((int)str & 0xffff0000)) return (ATOM)((int)str & 0xffff); */
+    /* Check for integer atom */
+
+    if (!HIWORD(name)) return (ATOM)LOWORD(name);
+    str = PTR_SEG_TO_LIN( name );
     if (str[0] == '#') return atoi( &str[1] );
 
+    if ((len = strlen( str )) > 255) len = 255;
     if (!(table = ATOM_GetTable( selector, TRUE ))) return 0;
     hash = ATOM_Hash( table->size, str, len );
     entry = table->entries[hash];
@@ -210,19 +200,21 @@
 /***********************************************************************
  *           ATOM_FindAtom
  */
-static ATOM ATOM_FindAtom( WORD selector, LPCSTR str )
+static ATOM ATOM_FindAtom( WORD selector, SEGPTR name )
 {
     ATOMTABLE * table;
     WORD hash;
     HANDLE entry;
     int len;
-    
-    if ((len = strlen( str )) > 255) len = 255;
-    
-      /* Check for integer atom */
-/*    if (!((int)str & 0xffff0000)) return (ATOM)((int)str & 0xffff); */
+    char *str;
+
+    /* Check for integer atom */
+
+    if (!HIWORD(name)) return (ATOM)LOWORD(name);
+    str = PTR_SEG_TO_LIN( name );
     if (str[0] == '#') return atoi( &str[1] );
 
+    if ((len = strlen( str )) > 255) len = 255;
     if (!(table = ATOM_GetTable( selector, FALSE ))) return 0;
     hash = ATOM_Hash( table->size, str, len );
     entry = table->entries[hash];
@@ -295,7 +287,7 @@
 /***********************************************************************
  *           AddAtom   (KERNEL.70)
  */
-ATOM AddAtom( LPCSTR str )
+ATOM AddAtom( SEGPTR str )
 {
     return ATOM_AddAtom( CURRENT_DS, str );
 }
@@ -313,7 +305,7 @@
 /***********************************************************************
  *           FindAtom   (KERNEL.69)
  */
-ATOM FindAtom( LPCSTR str )
+ATOM FindAtom( SEGPTR str )
 {
     return ATOM_FindAtom( CURRENT_DS, str );
 }
@@ -331,7 +323,7 @@
 /***********************************************************************
  *           LocalAddAtom   (USER.268)
  */
-ATOM LocalAddAtom( LPCSTR str )
+ATOM LocalAddAtom( SEGPTR str )
 {
     return ATOM_AddAtom( USER_HeapSel, str );
 }
@@ -349,7 +341,7 @@
 /***********************************************************************
  *           LocalFindAtom   (USER.270)
  */
-ATOM LocalFindAtom( LPCSTR str )
+ATOM LocalFindAtom( SEGPTR str )
 {
     return ATOM_FindAtom( USER_HeapSel, str );
 }
diff --git a/memory/global.c b/memory/global.c
index 83c3213..704fe9d 100644
--- a/memory/global.c
+++ b/memory/global.c
@@ -4,6 +4,7 @@
  * Copyright 1995 Alexandre Julliard
  */
 
+#include <sys/types.h>
 #include <stdlib.h>
 #include <string.h>
 
@@ -13,6 +14,7 @@
 #include "selectors.h"
 #include "dde_mem.h"
 #include "stackframe.h"
+#include "options.h"
 #include "stddebug.h"
 #include "debug.h"
 
@@ -128,7 +130,7 @@
 
     pArena->base = (DWORD)ptr;
     pArena->size = GET_SEL_LIMIT(sel) + 1;
-    if (flags & GMEM_DDESHARE)
+    if ((flags & GMEM_DDESHARE) && Options.ipc)
     {
 	pArena->handle = shmdata->handle;
 	pArena->shmid  = shmdata->shmid;
@@ -194,7 +196,7 @@
 
       /* Allocate the linear memory */
 
-    if (flags & GMEM_DDESHARE) 
+    if ((flags & GMEM_DDESHARE) && Options.ipc)
         ptr= DDE_malloc(flags, size, &shmdata);
     else 
 	ptr = malloc( size );
@@ -266,7 +268,7 @@
                     handle, size, flags );
     if (!handle) return 0;
     
-    if (flags & GMEM_DDESHARE || is_dde_handle(handle)) {
+    if (Options.ipc && (flags & GMEM_DDESHARE || is_dde_handle(handle))) {
 	fprintf(stdnimp,
 		"GlobalReAlloc: shared memory reallocating unimplemented\n"); 
 	return 0;
diff --git a/memory/selector.c b/memory/selector.c
index 1959c71..4be163d 100644
--- a/memory/selector.c
+++ b/memory/selector.c
@@ -66,6 +66,7 @@
 {
     WORD i, count;
     ldt_entry entry;
+    STACK16FRAME *frame;
 
     dprintf_selector( stddeb, "FreeSelector(%04x)\n", sel );
     if (IS_SELECTOR_FREE(sel)) return sel;  /* error */
@@ -80,11 +81,12 @@
 
     /* Clear the saved 16-bit selector */
 #ifndef WINELIB
-    if (CURRENT_STACK16)
+    frame = CURRENT_STACK16;
+    while (frame)
     {
-        /* FIXME: maybe we ought to walk up the stack and fix all frames */
-        if (CURRENT_STACK16->ds == sel) CURRENT_STACK16->ds = 0;
-        if (CURRENT_STACK16->es == sel) CURRENT_STACK16->es = 0;
+        if (frame->ds == sel) frame->ds = 0;
+        if (frame->es == sel) frame->es = 0;
+	frame = PTR_SEG_OFF_TO_LIN(frame->saved_ss, frame->saved_sp);
     }
 #endif
     return 0;
diff --git a/misc/Imakefile b/misc/Imakefile
index 9e52608..1470bad 100644
--- a/misc/Imakefile
+++ b/misc/Imakefile
@@ -3,7 +3,6 @@
 MODULE = misc
 
 SRCS = \
-	atom.c \
 	clipboard.c \
 	comm.c \
 	commdlg.c \
diff --git a/misc/Makefile.in b/misc/Makefile.in
index 84afd90..c2bdaa7 100644
--- a/misc/Makefile.in
+++ b/misc/Makefile.in
@@ -11,7 +11,7 @@
 
 MODULE 	= misc
 
-SRCS 	= atom.c clipboard.c comm.c commdlg.c compobj.c dos_fs.c \
+SRCS 	= clipboard.c comm.c commdlg.c compobj.c dos_fs.c \
 	driver.c exec.c escape.c file.c keyboard.c kernel32.c lstr.c \
 	main.c ole2.c ole2disp.c ole2nls.c olecli.c olesvr.c network.c \
 	profile.c rect.c shell.c sound.c spy.c stress.c user.c \
@@ -24,8 +24,8 @@
 
 all: checkrc $(MODULE).o
 
-checkrc:
-	(cd $(TOPSRC)/rc; $(MAKE) 'CC=$(CC)' 'CFLAGS=$(CFLAGS)' 'LD=$(LD)' 'LDCOMBINEFLAGS=$(LDCOMBINEFLAGS)')
+checkrc: dummy
+	cd $(TOPSRC)/rc; $(MAKE) 'CC=$(CC)' 'CFLAGS=$(CFLAGS)' 'LD=$(LD)' 'LDCOMBINEFLAGS=$(LDCOMBINEFLAGS)'
 
 $(MODULE).o: $(OBJS)
 	$(LD) $(LDCOMBINEFLAGS) $(OBJS) -o $(MODULE).o
@@ -33,27 +33,17 @@
 depend:
 	sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
 	$(CC) $(DIVINCL) $(XINCL) -MM *.c >> tmp_make
-	cp tmp_make Makefile
-	rm tmp_make
+	mv tmp_make Makefile
 
 clean:
 	rm -f *.o \#*\# *~ tmp_make
 
 distclean: clean
-	rm Makefile
+	rm -f Makefile
 
 countryclean:
 	rm -f ole2nls.o shell.o commdlg.o
 
-NAMES = $(SRCS:.c=)
-
-winelibclean:
-	for i in $(NAMES); do \
-	if test `grep -c WINELIB $$i.c` -ne 0; then \
-	rm $$i.o; \
-	fi; \
-	done
- 
 dummy:
 
 ### Dependencies:
diff --git a/misc/commdlg.c b/misc/commdlg.c
index f660674..79cfb69 100644
--- a/misc/commdlg.c
+++ b/misc/commdlg.c
@@ -368,7 +368,7 @@
   else
     *tmpstr = 0;
   if (!FILEDLG_ScanDir(hWnd, tmpstr))
-    fprintf(stderr, "FileDlg: couldn't read initial directory!\n");
+    fprintf(stderr, "FileDlg: couldn't read initial directory %s!\n", tmpstr);
   /* select current drive in combo 2 */
   n = DOS_GetDefaultDrive();
   SendDlgItemMessage(hWnd, cmb2, CB_SETCURSEL, n - 1, 0);
diff --git a/misc/dos_fs.c b/misc/dos_fs.c
index c1fd240..322ddab 100644
--- a/misc/dos_fs.c
+++ b/misc/dos_fs.c
@@ -124,6 +124,7 @@
 {
     while(*s){
 	if (*s == '\\') *s = '/';
+	*s=tolower(*s); /* umsdos fs can't read files without :( */
 	s++;
     }
 }
@@ -188,7 +189,6 @@
 	DosDrives[x].disabled = 0;
     }
     DosDrives[25].rootdir = "/";
-    strcpy(DosDrives[25].cwd, "/");
     strcpy(DosDrives[25].label, "UNIX-FS");
     DosDrives[25].serialnumber = 0x12345678;
     DosDrives[25].disabled = 0;
@@ -206,6 +206,7 @@
 
     getcwd(temp, 254);
     strcat(temp, "/");      /* For DOS_GetDosFileName */
+    strcpy(DosDrives[25].cwd, temp );
     strcpy(temp, DOS_GetDosFileName(temp));
     if(temp[0] != 'Z')
     {
diff --git a/misc/file.c b/misc/file.c
index 3581ce3..895e180 100644
--- a/misc/file.c
+++ b/misc/file.c
@@ -72,8 +72,8 @@
 {
   int result;
 
-  dprintf_file(stddeb, "_lread: handle %d, buffer = %ld, length = %d\n",
-	  		hFile, (long) lpBuffer, wBytes);
+  dprintf_file(stddeb, "_lread: handle %d, buffer = %p, length = %d\n",
+	  		hFile, lpBuffer, wBytes);
   
   result = wBytes == 0 ? 0 : read (hFile, lpBuffer, wBytes);
 
@@ -90,10 +90,28 @@
 {
     int result;
 
-    dprintf_file(stddeb, "_lwrite: handle %d, buffer = %ld, length = %d\n",
-		 hFile, (long) lpBuffer, wBytes);
+    dprintf_file(stddeb, "_lwrite: handle %d, buffer = %p, length = %d\n",
+		 hFile, lpBuffer, wBytes);
 
-    result = wBytes == 0 ? 0 : write (hFile, lpBuffer, wBytes);
+    if(wBytes == 0) {  /* Expand the file size if necessary */
+	char toWrite = 0;
+	off_t prev, end;
+	
+	prev = lseek(hFile, 0, SEEK_CUR);
+	if(prev == -1) return HFILE_ERROR;
+	end = lseek(hFile, 0, SEEK_END);
+	if(end == -1) return HFILE_ERROR;
+	if(prev > end) {
+	    lseek(hFile, prev-1, SEEK_SET);
+	    result = write(hFile, &toWrite, 1) - 1;
+	    if(result == -2) ++result;
+	}
+	else {
+	    lseek(hFile, prev, SEEK_SET);
+	    result = 0;
+	}
+    }
+    else result = write (hFile, lpBuffer, wBytes);
 
     if (result == -1)
         return HFILE_ERROR;
@@ -325,7 +343,7 @@
 		lpszFilename, fnAttribute);
 	if ((UnixFileName = DOS_GetUnixFileName(lpszFilename)) == NULL)
   		return HFILE_ERROR;
-	handle =  open (UnixFileName, O_CREAT | O_TRUNC | O_WRONLY, 0666);
+	handle =  open (UnixFileName, O_CREAT | O_TRUNC | O_RDWR, 0666);
 
 	if (handle == -1)
 		return HFILE_ERROR;
diff --git a/misc/lstr.c b/misc/lstr.c
index 7ba113e..a37b6de 100644
--- a/misc/lstr.c
+++ b/misc/lstr.c
@@ -109,7 +109,7 @@
 /* IsCharAlphanumeric USER 434 */
 BOOL IsCharAlphanumeric(char ch)
 {
-  return (ch<'0')?0:(ch<'9');
+  return (ch < '0') ? 0 : (ch <= '9');
 }
 
 /* IsCharUpper USER 435 */
diff --git a/misc/main.c b/misc/main.c
index 3528df5..1eb750c 100644
--- a/misc/main.c
+++ b/misc/main.c
@@ -69,7 +69,8 @@
     SW_SHOWNORMAL,  /* cmdShow */
     FALSE,
     FALSE,          /* AllowReadOnly */
-    FALSE           /* Enhanced mode */
+    FALSE,          /* Enhanced mode */
+    FALSE           /* IPC enabled */
 };
 
 
@@ -80,6 +81,7 @@
     { "-depth",         ".depth",           XrmoptionSepArg, (caddr_t)NULL },
     { "-display",       ".display",         XrmoptionSepArg, (caddr_t)NULL },
     { "-iconic",        ".iconic",          XrmoptionNoArg,  (caddr_t)"on" },
+    { "-ipc",           ".ipc",             XrmoptionNoArg,  (caddr_t)"off"},
     { "-name",          ".name",            XrmoptionSepArg, (caddr_t)NULL },
     { "-privatemap",    ".privatemap",      XrmoptionNoArg,  (caddr_t)"on" },
     { "-synchronous",   ".synchronous",     XrmoptionNoArg,  (caddr_t)"on" },
@@ -100,6 +102,7 @@
   "    -desktop geom   Use a desktop window of the given geometry\n" \
   "    -display name   Use the specified display\n" \
   "    -iconic         Start as an icon\n" \
+  "    -ipc            Enable IPC facilities\n" \
   "    -debug          Enter debugger before starting application\n" \
   "    -name name      Set the application name\n" \
   "    -privatemap     Use a private color map\n" \
@@ -309,6 +312,8 @@
         Options.allowReadOnly = TRUE;
     if (MAIN_GetResource( db, ".enhanced", &value ))
         Options.enhanced = TRUE;
+    if (MAIN_GetResource( db, ".ipc", &value ))
+        Options.ipc = TRUE;
     if (MAIN_GetResource( db, ".depth", &value))
 	screenDepth = atoi( value.addr );
     if (MAIN_GetResource( db, ".desktop", &value))
@@ -558,7 +563,7 @@
  */
 LONG GetVersion(void)
 {
-    return MAKELONG( WINVERSION, DOSVERSION );
+    return MAKELONG( WINVERSION, WINDOSVER );
 }
 
 /***********************************************************************
diff --git a/misc/profile.c b/misc/profile.c
index 0c3df91..3a400d7 100644
--- a/misc/profile.c
+++ b/misc/profile.c
@@ -134,6 +134,7 @@
 
 
     state = FirstBrace;
+    next = CharBuffer;
     while ((c = fgetc (f)) != EOF){
 	if (c == '\r')		/* Ignore Carriage Return */
 	    continue;
diff --git a/misc/shell.c b/misc/shell.c
index ebdfd91..2157470 100644
--- a/misc/shell.c
+++ b/misc/shell.c
@@ -5,6 +5,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <unistd.h>
+#include <ctype.h>
 #include "windows.h"
 #include "shell.h"
 #include "neexe.h"
@@ -17,7 +18,7 @@
 
 LPKEYSTRUCT	lphRootKey = NULL,lphTopKey = NULL;
 
-static char RootKeyName[]=".classes", TopKeyName[] = "(null)";
+static char RootKeyName[]=".classes", TopKeyName[] = "[top-null]";
 
 /*************************************************************************
  *                        SHELL_RegCheckForRoot()     internal use only
@@ -62,7 +63,7 @@
  */
 LONG RegOpenKey(HKEY hKey, LPCSTR lpSubKey, HKEY FAR *lphKey)
 {
-	LPKEYSTRUCT	lpKey;
+	LPKEYSTRUCT	lpKey,lpNextKey;
 	LPCSTR		ptr;
 	char		str[128];
 	LONG            dwRet;
@@ -71,18 +72,21 @@
         if (dwRet != ERROR_SUCCESS) return dwRet;
 	dprintf_reg(stddeb, "RegOpenKey(%08lX, %p='%s', %p)\n",
 						hKey, lpSubKey, lpSubKey, lphKey);
-	if (lpSubKey == NULL) return ERROR_INVALID_PARAMETER;
 	if (lphKey == NULL) return ERROR_INVALID_PARAMETER;
         switch(hKey) {
 	case 0: 
 	  lpKey = lphTopKey; break;
         case HKEY_CLASSES_ROOT: /* == 1 */
+        case 0x80000000:
           lpKey = lphRootKey; break;
         default: 
 	  dprintf_reg(stddeb,"RegOpenKey // specific key = %08lX !\n", hKey);
 	  lpKey = (LPKEYSTRUCT)GlobalLock(hKey);
         }
-        if (!*lpSubKey)  { *lphKey = hKey; return ERROR_SUCCESS; }
+	if (lpSubKey == NULL || !*lpSubKey)  { 
+	  *lphKey = hKey; 
+	  return ERROR_SUCCESS; 
+	}
         while(*lpSubKey) {
           ptr = strchr(lpSubKey,'\\');
           if (!ptr) ptr = lpSubKey + strlen(lpSubKey);
@@ -91,8 +95,11 @@
           lpSubKey = ptr; 
           if (*lpSubKey) lpSubKey++;
 	  
-	  lpKey = lpKey->lpSubLvl;
-          while(lpKey != NULL && strcmp(lpKey->lpSubKey, str) != 0) { lpKey = lpKey->lpNextKey; }
+	  lpNextKey = lpKey->lpSubLvl;
+          while(lpKey != NULL && strcmp(lpKey->lpSubKey, str) != 0) { 
+          	lpKey = lpNextKey;
+          	if (lpKey) lpNextKey = lpKey->lpNextKey;
+          }
           if (lpKey == NULL) {
 	    dprintf_reg(stddeb,"RegOpenKey: key %s not found!\n",str);
 	    return ERROR_BADKEY;
@@ -119,18 +126,21 @@
 	dwRet = SHELL_RegCheckForRoot();
         if (dwRet != ERROR_SUCCESS) return dwRet;
 	dprintf_reg(stddeb, "RegCreateKey(%08lX, '%s', %p)\n",	hKey, lpSubKey, lphKey);
-	if (lpSubKey == NULL) return ERROR_INVALID_PARAMETER;
 	if (lphKey == NULL) return ERROR_INVALID_PARAMETER;
         switch(hKey) {
 	case 0: 
 	  lpKey = lphTopKey; break;
         case HKEY_CLASSES_ROOT: /* == 1 */
+        case 0x80000000:
           lpKey = lphRootKey; break;
         default: 
 	  dprintf_reg(stddeb,"RegCreateKey // specific key = %08lX !\n", hKey);
 	  lpKey = (LPKEYSTRUCT)GlobalLock(hKey);
         }
-        if (!*lpSubKey)  { *lphKey = hKey; return ERROR_SUCCESS; }
+	if (lpSubKey == NULL || !*lpSubKey)  { 
+	  *lphKey = hKey; 
+	  return ERROR_SUCCESS;
+	}
         while (*lpSubKey) {
           dprintf_reg(stddeb, "RegCreateKey: Looking for subkey %s\n", lpSubKey);
           ptr = strchr(lpSubKey,'\\');
@@ -210,7 +220,7 @@
     LONG       	dwRet;
     dprintf_reg(stddeb, "RegSetValue(%08lX, '%s', %08lX, '%s', %08lX);\n",
 		hKey, lpSubKey, dwType, lpVal, dwIgnored);
-    if (lpSubKey == NULL) return ERROR_INVALID_PARAMETER;
+    /*if (lpSubKey == NULL) return ERROR_INVALID_PARAMETER;*/
     if (lpVal == NULL) return ERROR_INVALID_PARAMETER;
     if ((dwRet = RegOpenKey(hKey, lpSubKey, &hRetKey)) != ERROR_SUCCESS) {
 	dprintf_reg(stddeb, "RegSetValue // key not found ... so create it !\n");
@@ -240,7 +250,7 @@
 	int			size;
 	dprintf_reg(stddeb, "RegQueryValue(%08lX, '%s', %p, %p);\n",
 							hKey, lpSubKey, lpVal, lpcb);
-	if (lpSubKey == NULL) return ERROR_INVALID_PARAMETER;
+	/*if (lpSubKey == NULL) return ERROR_INVALID_PARAMETER;*/
 	if (lpVal == NULL) return ERROR_INVALID_PARAMETER;
 	if (lpcb == NULL) return ERROR_INVALID_PARAMETER;
         if (!*lpcb) return ERROR_INVALID_PARAMETER;
@@ -285,12 +295,12 @@
 	case 0: 
 	  lpKey = lphTopKey; break;
         case HKEY_CLASSES_ROOT: /* == 1 */
+        case 0x80000000:
           lpKey = lphRootKey; break;
         default: 
 	  dprintf_reg(stddeb,"RegEnumKey // specific key = %08lX !\n", hKey);
 	  lpKey = (LPKEYSTRUCT)GlobalLock(hKey);
         }
-
         lpKey = lpKey->lpSubLvl;
         while(lpKey != NULL){
           if (!dwSubKey){
@@ -301,7 +311,7 @@
 	    return ERROR_SUCCESS;
 	  }
           dwSubKey--;
-	  lpKey = lpKey->lpNextKey;
+          lpKey = lpKey->lpNextKey;
         }
 	dprintf_reg(stddeb, "RegEnumKey: key not found!\n");
 	return ERROR_INVALID_PARAMETER;
@@ -351,30 +361,75 @@
 HINSTANCE ShellExecute(HWND hWnd, LPCSTR lpOperation, LPCSTR lpFile, LPCSTR lpParameters, LPCSTR lpDirectory, int iShowCmd)
 {
     char cmd[400];
+    char *p,*x;
+    long len;
+    char subclass[200];
+    /* OK. We are supposed to lookup the program associated with lpFile,
+     * then to execute it using that program. If lpFile is a program,
+     * we have to pass the parameters. If an instance is already running,
+     * we might have to send DDE commands.
+     */
     dprintf_exec(stddeb, "ShellExecute(%4X,'%s','%s','%s','%s',%x)\n",
 		hWnd, lpOperation ? lpOperation:"<null>", lpFile ? lpFile:"<null>",
 		lpParameters ? lpParameters : "<null>", 
 		lpDirectory ? lpDirectory : "<null>", iShowCmd);
-    if(lpOperation && !strcasecmp(lpOperation,"print"))
-    {
-        fprintf(stderr, "Shell print %s: not supported\n", lpFile);
-    	return 2; /* file not found */
+    if (lpFile==NULL) return 0; /* should not happen */
+    if (lpOperation==NULL) /* default is open */
+      lpOperation="open";
+    p=strrchr(lpFile,'.');
+    if (p!=NULL) {
+      x=p; /* the suffixes in the register database are lowercased */
+      while (*x) {*x=tolower(*x);x++;}
     }
-    if(lpOperation && !strcasecmp(lpOperation,"open"))
-    {
-        fprintf(stderr, "ShellExecute: Unknown operation %s\n",lpOperation);
-        return 2;
-    }
-    /* OK. We are supposed to lookup the program associated with lpFile,
-       then to execute it using that program. If lpFile is a program,
-       we have to pass the parameters. If an instance is already running,
-       we might have to send DDE commands.
-       This implementation does none of that. It assumes lpFile is a program.
-       Plain WinExec will do what we need */
-    if(lpParameters)
+    if (p==NULL || !strcmp(p,".exe")) {
+      p=".exe";
+      if (lpParameters) {
         sprintf(cmd,"%s %s",lpFile,lpParameters);
-    else
+      } else {
         strcpy(cmd,lpFile);
+      }
+    } else {
+      len=200;
+      if (RegQueryValue(HKEY_CLASSES_ROOT,p,subclass,&len)==ERROR_SUCCESS) {
+	if (len>20)
+	  fprintf(stddeb,"ShellExecute:subclass with len %ld? (%s), please report.\n",len,subclass);
+	subclass[len]='\0';
+	strcat(subclass,"\\shell\\");
+	strcat(subclass,lpOperation);
+	strcat(subclass,"\\command");
+	dprintf_exec(stddeb,"ShellExecute:looking for %s.\n",subclass);
+	len=400;
+	if (RegQueryValue(HKEY_CLASSES_ROOT,subclass,cmd,&len)==ERROR_SUCCESS) {
+	  char *t;
+	  dprintf_exec(stddeb,"ShellExecute:...got %s\n",cmd);
+	  cmd[len]='\0';
+	  t=strstr(cmd,"%1");
+	  if (t==NULL) {
+	    strcat(cmd," ");
+	    strcat(cmd,lpFile);
+	  } else {
+	    char *s;
+	    s=malloc(len+strlen(lpFile)+10);
+	    strncpy(s,cmd,t-cmd);
+	    strcat(s,lpFile);
+	    strcat(s,t+2);
+	    strcpy(cmd,s);
+	    free(s);
+	  }
+	  /* does this use %x magic too? */
+	  if (lpParameters) {
+	    strcat(cmd," ");
+	    strcat(cmd,lpParameters);
+	  }
+	} else {
+	  fprintf(stddeb,"ShellExecute: No %s\\shell\\%s\\command found for \"%s\" suffix.\n",subclass,lpOperation,p);
+	  return 14; /* unknown type */
+	}
+      } else {
+	fprintf(stddeb,"ShellExecute: No operation found for \"%s\" suffix.\n",p);
+	return 14; /* file not found */
+      }
+    }
     return WinExec(cmd,iShowCmd);
 }
 
diff --git a/miscemu/Makefile.in b/miscemu/Makefile.in
index 8cf8cce..c9af5ea 100644
--- a/miscemu/Makefile.in
+++ b/miscemu/Makefile.in
@@ -26,26 +26,16 @@
 depend:
 	sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
 	$(CC) $(DIVINCL) $(XINCL) -MM *.c >> tmp_make
-	cp tmp_make Makefile
-	rm tmp_make
+	mv tmp_make Makefile
 
 clean:
 	rm -f *.o \#*\# *~ tmp_make
 
 distclean: clean
-	rm Makefile
+	rm -f Makefile
 
 countryclean:
 
-NAMES = $(SRCS:.c=)
-
-winelibclean:
-	for i in $(NAMES); do \
-	if test `grep -c WINELIB $$i.c` -ne 0; then \
-	rm $$i.o; \
-	fi; \
-	done
- 
 dummy:
 
 ### Dependencies:
diff --git a/miscemu/dpmi.c b/miscemu/dpmi.c
index 2b63159..1c787e9 100644
--- a/miscemu/dpmi.c
+++ b/miscemu/dpmi.c
@@ -22,147 +22,153 @@
  *
  * Handler for int 31h (DPMI).
  */
-void INT_Int31Handler( struct sigcontext_struct sigcontext )
+void INT_Int31Handler( struct sigcontext_struct context )
 {
-#define context (&sigcontext)
     DWORD dw;
     BYTE *ptr;
 
-    ResetCflag;
-    switch(AX)
+    RESET_CFLAG(&context);
+    switch(AX_reg(&context))
     {
     case 0x0000:  /* Allocate LDT descriptors */
-        if (!(AX = AllocSelectorArray( CX )))
+        if (!(AX_reg(&context) = AllocSelectorArray( CX_reg(&context) )))
         {
-            AX = 0x8011;  /* descriptor unavailable */
-            SetCflag;
+            AX_reg(&context) = 0x8011;  /* descriptor unavailable */
+            SET_CFLAG(&context);
         }
         break;
 
     case 0x0001:  /* Free LDT descriptor */
-        if (FreeSelector( BX ))
+        if (FreeSelector( BX_reg(&context) ))
         {
-            AX = 0x8022;  /* invalid selector */
-            SetCflag;
+            AX_reg(&context) = 0x8022;  /* invalid selector */
+            SET_CFLAG(&context);
         }
         break;
 
     case 0x0003:  /* Get next selector increment */
-        AX = __AHINCR;
+        AX_reg(&context) = __AHINCR;
         break;
 
     case 0x0004:  /* Lock selector (not supported) */
-        AX = 0;  /* FIXME: is this a correct return value? */
+        AX_reg(&context) = 0;  /* FIXME: is this a correct return value? */
         break;
 
     case 0x0005:  /* Unlock selector (not supported) */
-        AX = 0;  /* FIXME: is this a correct return value? */
+        AX_reg(&context) = 0;  /* FIXME: is this a correct return value? */
         break;
 
     case 0x0006:  /* Get selector base address */
-        if (!(dw = GetSelectorBase( BX )))
+        if (!(dw = GetSelectorBase( BX_reg(&context) )))
         {
-            AX = 0x8022;  /* invalid selector */
-            SetCflag;
+            AX_reg(&context) = 0x8022;  /* invalid selector */
+            SET_CFLAG(&context);
         }
         else
         {
-            CX = HIWORD(dw);
-            DX = LOWORD(dw);
+            CX_reg(&context) = HIWORD(dw);
+            DX_reg(&context) = LOWORD(dw);
         }
         break;
 
     case 0x0007:  /* Set selector base address */
-        SetSelectorBase( BX, MAKELONG( DX, CX ) );
+        SetSelectorBase( BX_reg(&context),
+                         MAKELONG( DX_reg(&context), CX_reg(&context) ) );
         break;
 
     case 0x0008:  /* Set selector limit */
-        SetSelectorLimit( BX, MAKELONG( DX, CX ) );
+        SetSelectorLimit( BX_reg(&context),
+                          MAKELONG( DX_reg(&context), CX_reg(&context) ) );
         break;
 
     case 0x0009:  /* Set selector access rights */
-        SelectorAccessRights( BX, 1, CX );
+        SelectorAccessRights( BX_reg(&context), 1, CX_reg(&context) );
 
     case 0x000a:  /* Allocate selector alias */
-        if (!(AX = AllocCStoDSAlias( BX )))
+        if (!(AX_reg(&context) = AllocCStoDSAlias( BX_reg(&context) )))
         {
-            AX = 0x8011;  /* descriptor unavailable */
-            SetCflag;
+            AX_reg(&context) = 0x8011;  /* descriptor unavailable */
+            SET_CFLAG(&context);
         }
         break;
 
     case 0x000b:  /* Get descriptor */
         {
             ldt_entry entry;
-            LDT_GetEntry( SELECTOR_TO_ENTRY(BX), &entry );
+            LDT_GetEntry( SELECTOR_TO_ENTRY( BX_reg(&context) ), &entry );
             /* FIXME: should use ES:EDI for 32-bit clients */
-            LDT_EntryToBytes( PTR_SEG_OFF_TO_LIN( ES, DI ), &entry );
+            LDT_EntryToBytes( PTR_SEG_OFF_TO_LIN( ES_reg(&context),
+                                                  DI_reg(&context) ), &entry );
         }
         break;
 
     case 0x000c:  /* Set descriptor */
         {
             ldt_entry entry;
-            LDT_BytesToEntry( PTR_SEG_OFF_TO_LIN( ES, DI ), &entry );
-            LDT_GetEntry( SELECTOR_TO_ENTRY(BX), &entry );
+            LDT_BytesToEntry( PTR_SEG_OFF_TO_LIN( ES_reg(&context),
+                                                  DI_reg(&context) ), &entry );
+            LDT_GetEntry( SELECTOR_TO_ENTRY( BX_reg(&context) ), &entry );
         }
         break;
 
     case 0x000d:  /* Allocate specific LDT descriptor */
-        AX = 0x8011; /* descriptor unavailable */
-        SetCflag;
+        AX_reg(&context) = 0x8011; /* descriptor unavailable */
+        SET_CFLAG(&context);
         break;
 
     case 0x0204:  /* Get protected mode interrupt vector */
-	dw = (DWORD)INT_GetHandler( BL );
-	CX = HIWORD(dw);
-	DX = LOWORD(dw);
+	dw = (DWORD)INT_GetHandler( BL_reg(&context) );
+	CX_reg(&context) = HIWORD(dw);
+	DX_reg(&context) = LOWORD(dw);
 	break;
 
     case 0x0205:  /* Set protected mode interrupt vector */
-	INT_SetHandler( BL, (SEGPTR)MAKELONG( DX, CX ) );
+	INT_SetHandler( BL_reg(&context),
+                       (SEGPTR)MAKELONG( DX_reg(&context), CX_reg(&context) ));
 	break;
 
     case 0x0400:  /* Get DPMI version */
-        AX = 0x005a;  /* DPMI version 0.90 */
-        BX = 0x0005;  /* Flags: 32-bit, virtual memory */
-        CL = 3;       /* CPU type: 386 */
-        DX = 0x0102;  /* Master and slave interrupt controller base */
+        AX_reg(&context) = 0x005a;  /* DPMI version 0.90 */
+        BX_reg(&context) = 0x0005;  /* Flags: 32-bit, virtual memory */
+        CL_reg(&context) = 3;       /* CPU type: 386 */
+        DX_reg(&context) = 0x0102;  /* Master/slave interrupt controller base*/
         break;
 
     case 0x0500:  /* Get free memory information */
-        ptr = (BYTE *)PTR_SEG_OFF_TO_LIN( ES, DI );
+        ptr = (BYTE *)PTR_SEG_OFF_TO_LIN( ES_reg(&context), DI_reg(&context) );
         *(DWORD *)ptr = 0x00ff0000; /* Largest block available */
         memset( ptr + 4, 0xff, 0x2c );  /* No other information supported */
         break;
 
     case 0x0501:  /* Allocate memory block */
-        if (!(ptr = (BYTE *)malloc( MAKELONG( CX, BX ) )))
+        if (!(ptr = (BYTE *)malloc( MAKELONG( CX_reg(&context),
+                                              BX_reg(&context) ) )))
         {
-            AX = 0x8012;  /* linear memory not available */
-            SetCflag;
+            AX_reg(&context) = 0x8012;  /* linear memory not available */
+            SET_CFLAG(&context);
         }
         else
         {
-            BX = SI = HIWORD(ptr);
-            CX = DI = LOWORD(ptr);
+            BX_reg(&context) = SI_reg(&context) = HIWORD(ptr);
+            CX_reg(&context) = DI_reg(&context) = LOWORD(ptr);
         }
         break;
 
     case 0x0502:  /* Free memory block */
-        free( (void *)MAKELONG( DI, SI ) );
+        free( (void *)MAKELONG( DI_reg(&context), SI_reg(&context) ) );
         break;
 
     case 0x0503:  /* Resize memory block */
-        if (!(ptr = (BYTE *)realloc( (void *)MAKELONG(DI,SI),MAKELONG(CX,BX))))
+        if (!(ptr = (BYTE *)realloc( (void *)MAKELONG(DI_reg(&context),SI_reg(&context)),
+                                     MAKELONG(CX_reg(&context),BX_reg(&context)))))
         {
-            AX = 0x8012;  /* linear memory not available */
-            SetCflag;
+            AX_reg(&context) = 0x8012;  /* linear memory not available */
+            SET_CFLAG(&context);
         }
         else
         {
-            BX = SI = HIWORD(ptr);
-            CX = DI = LOWORD(ptr);
+            BX_reg(&context) = SI_reg(&context) = HIWORD(ptr);
+            CX_reg(&context) = DI_reg(&context) = LOWORD(ptr);
         }
         break;
 
@@ -173,10 +179,9 @@
         break;  /* Just ignore it */
 
     default:
-        INT_BARF( 0x31 );
-        AX = 0x8001;  /* unsupported function */
-        SetCflag;
+        INT_BARF( &context, 0x31 );
+        AX_reg(&context) = 0x8001;  /* unsupported function */
+        SET_CFLAG(&context);
         break;
     }
-#undef context
 }
diff --git a/miscemu/emulate.c b/miscemu/emulate.c
index 03de983..a8b40f3 100644
--- a/miscemu/emulate.c
+++ b/miscemu/emulate.c
@@ -1,39 +1,112 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include "wine.h"
+#include "miscemu.h"
 #include "registers.h"
 #include "stddebug.h"
 /* #define DEBUG_INT */
 #include "debug.h"
 
-struct Win87EmInfoStruct {
-  unsigned short Version;
-  unsigned short SizeSaveArea;
-  unsigned short WinDataSeg;
-  unsigned short WinCodeSeg;
-  unsigned short Have80x87;
-  unsigned short Unused;
+struct Win87EmInfoStruct
+{
+    unsigned short Version;
+    unsigned short SizeSaveArea;
+    unsigned short WinDataSeg;
+    unsigned short WinCodeSeg;
+    unsigned short Have80x87;
+    unsigned short Unused;
 };
 
-void
-WIN87_fpmath( struct sigcontext_struct sigcontext )
+/* Implementing this is easy cause Linux and *BSD* ALWAYS have a numerical
+ * coprocessor. (either real or emulated on kernellevel)
+ */
+/* win87em.dll also sets interrupt vectors: 2 (NMI), 0x34 - 0x3f (emulator
+ * calls of standard libraries, see Ralph Browns interrupt list), 0x75
+ * (int13 error reporting of coprocessor)
+ */
+
+/* have a look at /usr/src/linux/arch/i386/math-emu/ *.[ch] for more info 
+ * especially control_w.h and status_w.h
+ */
+/* FIXME: Only skeletal implementation for now */
+
+void WIN87_fpmath( struct sigcontext_struct context )
 {
-    /* Declare a context pointer so that registers macros work */
-    struct sigcontext_struct *context = &sigcontext;
+    dprintf_int(stddeb, "_fpmath: (cs:eip=%x:%lx es=%x bx=%04x ax=%04x dx==%04x)\n",
+                 CS_reg(&context), EIP_reg(&context),
+                 ES_reg(&context), BX_reg(&context),
+                 AX_reg(&context), DX_reg(&context) );
 
-    dprintf_int(stddeb, "_fpmath: (%x:%lx %x %x)\n", CS, EIP, ES, BX );
-
-    switch(BX)
+    switch(BX_reg(&context))
     {
-    case 11:
-        AX = 1;
+    case 0: /* install (increase instanceref) emulator, install NMI vector */
+        AX_reg(&context) = 0;
         break;
-    default:
-        AX = 0;
+
+    case 1: /* Init Emulator */
+        AX_reg(&context) = 0;
+        break;
+
+    case 2: /* deinstall emulator (decrease instanceref), deinstall NMI vector	
+             * if zero. Every '0' call should have a matching '2' call.
+             */
+        AX_reg(&context) = 0;   	
+        break;
+
+    case 3:
+        /*INT_SetHandler(0x3E,MAKELONG(AX,DX));*/
+        break;
+
+    case 4: /* set control word (& ~(CW_Denormal|CW_Invalid)) */
+        /* OUT: newset control word in AX */
+        break;
+
+    case 5: /* return internal control word in AX */
+        break;
+
+    case 6: /* round top of stack to integer using method AX & 0x0C00 */
+        /* returns current controlword */
+        break;
+
+    case 7: /* POP top of stack as integer into DX:AX */
+        /* IN: AX&0x0C00 rounding protocol */
+        /* OUT: DX:AX variable popped */
+        {
+            DWORD dw,junk;
+            /* I don't know much about asm() programming. This could be 
+             * wrong. 
+             */
+            __asm__("fistp %1\nwait":"=m" (junk):"m" (dw):"memory");
+            dprintf_int(stddeb,"emulate.c:On top of stack was %ld\n",dw);
+            AX_reg(&context) = LOWORD(dw);
+            DX_reg(&context) = HIWORD(dw);
+        }
+        break;
+
+    case 8: /* restore internal control words from emulator control word */
+        break;
+
+    case 9: /* clear emu control word and some other things */
+        break;
+
+    case 10: /* dunno. but looks like returning nr. of things on stack in AX */
+        break;
+
+    case 11: /* just returns the installed flag in DX:AX */
+        DX_reg(&context) = 0;
+        AX_reg(&context) = 1;
+        break;
+
+    case 12: /* save AX in some internal state var */
+        break;
+
+    default: /* error. Say that loud and clear */
+        AX_reg(&context) = DX_reg(&context) = 0xFFFF;
         break;
     }
 }
 
+
 void
 WIN87_WinEm87Info(struct Win87EmInfoStruct *pWIS, int cbWin87EmInfoStruct)
 {
diff --git a/miscemu/instr.c b/miscemu/instr.c
index 3be1990..55388da 100644
--- a/miscemu/instr.c
+++ b/miscemu/instr.c
@@ -21,8 +21,8 @@
     int prefix, segprefix, repX, long_op, long_addr;
     BYTE *instr;
 
-    long_op = long_addr = (GET_SEL_FLAGS(CS) & LDT_FLAGS_32BIT) != 0;
-    instr = (BYTE *) PTR_SEG_OFF_TO_LIN( CS, long_op ? EIP : IP );
+    long_op = long_addr = (GET_SEL_FLAGS(CS_reg(context)) & LDT_FLAGS_32BIT) != 0;
+    instr = (BYTE *) PTR_SEG_OFF_TO_LIN( CS_reg(context), EIP_reg(context) );
 
     /* First handle any possible prefix */
 
@@ -34,22 +34,22 @@
         switch(*instr)
         {
         case 0x2e:
-            segprefix = CS;
+            segprefix = CS_reg(context);
             break;
         case 0x36:
-            segprefix = SS;
+            segprefix = SS_reg(context);
             break;
         case 0x3e:
-            segprefix = DS;
+            segprefix = DS_reg(context);
             break;
         case 0x26:
-            segprefix = ES;
+            segprefix = ES_reg(context);
             break;
         case 0x64:
-            segprefix = FS;
+            segprefix = FS_reg(context);
             break;
         case 0x65:
-            segprefix = GS;
+            segprefix = GS_reg(context);
             break;
         case 0x66:
             long_op = !long_op;  /* opcode size prefix */
@@ -72,7 +72,7 @@
         if (prefix)
         {
             instr++;
-            EIP++;
+            EIP_reg(context)++;
         }
     }
 
@@ -90,15 +90,16 @@
             {
                 SEGPTR addr = INT_GetHandler( instr[1] );
                 /* FIXME: should check the stack 'big' bit */
-                WORD *stack = (WORD *)PTR_SEG_OFF_TO_LIN( SS, SP );
+                WORD *stack = (WORD *)PTR_SEG_OFF_TO_LIN( SS_reg(context),
+                                                          SP_reg(context) );
                 /* Push the flags and return address on the stack */
-                *(--stack) = FL;
-                *(--stack) = CS;
-                *(--stack) = IP + 2;
-                SP -= 3 * sizeof(WORD);
+                *(--stack) = FL_reg(context);
+                *(--stack) = CS_reg(context);
+                *(--stack) = IP_reg(context) + 2;
+                SP_reg(context) -= 3 * sizeof(WORD);
                 /* Jump to the interrupt handler */
-                CS  = HIWORD(addr);
-                EIP = LOWORD(addr);
+                CS_reg(context)  = HIWORD(addr);
+                EIP_reg(context) = LOWORD(addr);
             }
             break;
 
@@ -106,73 +107,75 @@
             if (long_op)
             {
                 /* FIXME: should check the stack 'big' bit */
-                DWORD *stack = (DWORD *)PTR_SEG_OFF_TO_LIN( SS, SP );
-                EIP = *stack++;
-                CS  = *stack++;
-                EFL = *stack;
-                SP += 3*sizeof(DWORD);  /* Pop the return address and flags */
+                DWORD *stack = (DWORD *)PTR_SEG_OFF_TO_LIN( SS_reg(context),
+                                                            SP_reg(context) );
+                EIP_reg(context) = *stack++;
+                CS_reg(context)  = *stack++;
+                EFL_reg(context) = *stack;
+                SP_reg(context) += 3*sizeof(DWORD);  /* Pop the return address and flags */
             }
             else
             {
                 /* FIXME: should check the stack 'big' bit */
-                WORD *stack = (WORD *)PTR_SEG_OFF_TO_LIN( SS, SP );
-                EIP = *stack++;
-                CS  = *stack++;
-                FL  = *stack;
-                SP += 3*sizeof(WORD);  /* Pop the return address and flags */
+                WORD *stack = (WORD *)PTR_SEG_OFF_TO_LIN( SS_reg(context),
+                                                          SP_reg(context) );
+                EIP_reg(context) = *stack++;
+                CS_reg(context)  = *stack++;
+                FL_reg(context)  = *stack;
+                SP_reg(context) += 3*sizeof(WORD);  /* Pop the return address and flags */
             }
             break;
 
         case 0xe4: /* inb al,XX */
-            AL = inport( instr[1], 1 );
-	    EIP += 2;
+            AL_reg(context) = inport( instr[1], 1 );
+	    EIP_reg(context) += 2;
             break;
 
         case 0xe5: /* in (e)ax,XX */
-            if (long_op) EAX = inport( instr[1], 4 );
-            else AX = inport( instr[1], 2 );
-	    EIP += 2;
+            if (long_op) EAX_reg(context) = inport( instr[1], 4 );
+            else AX_reg(context) = inport( instr[1], 2 );
+	    EIP_reg(context) += 2;
             break;
 
         case 0xe6: /* outb XX,al */
-            outport( instr[1], 1, AL );
-	    EIP += 2;
+            outport( instr[1], 1, AL_reg(context) );
+	    EIP_reg(context) += 2;
             break;
 
         case 0xe7: /* out XX,(e)ax */
-            if (long_op) outport( instr[1], 4, EAX );
-            else outport( instr[1], 2, AX );
-  	    EIP += 2;
+            if (long_op) outport( instr[1], 4, EAX_reg(context) );
+            else outport( instr[1], 2, AX_reg(context) );
+  	    EIP_reg(context) += 2;
             break;
 
         case 0xec: /* inb al,dx */
-            AL = inport( DX, 1 );
-	    EIP++;
+            AL_reg(context) = inport( DX_reg(context), 1 );
+	    EIP_reg(context)++;
             break;
 
         case 0xed: /* in (e)ax,dx */
-            if (long_op) EAX = inport( DX, 4 );
-            else AX = inport( DX, 2 );
-	    EIP++;  
+            if (long_op) EAX_reg(context) = inport( DX_reg(context), 4 );
+            else AX_reg(context) = inport( DX_reg(context), 2 );
+	    EIP_reg(context)++;  
             break;
 
         case 0xee: /* outb dx,al */
-            outport( DX, 1, AL );
-	    EIP++;
+            outport( DX_reg(context), 1, AL_reg(context) );
+	    EIP_reg(context)++;
             break;
       
         case 0xef: /* out dx,(e)ax */
-            if (long_op) outport( DX, 4, EAX );
-            else outport( DX, 2, AX );
-	    EIP++;
+            if (long_op) outport( DX_reg(context), 4, EAX_reg(context) );
+            else outport( DX_reg(context), 2, AX_reg(context) );
+	    EIP_reg(context)++;
             break;
 
         case 0xfa: /* cli, ignored */
-	    EIP++;
+	    EIP_reg(context)++;
             break;
 
         case 0xfb: /* sti, ignored */
-	    EIP++;
+	    EIP_reg(context)++;
             break;
 
         case 0x6c: /* insb     */
@@ -182,11 +185,12 @@
 	    {
 	      int typ = *instr;  /* Just in case it's overwritten.  */
 	      int outp = (typ >= 0x6e);
-	      unsigned long count = repX ? (long_addr ? ECX : CX) : 1;
+	      unsigned long count = repX ?
+                          (long_addr ? ECX_reg(context) : CX_reg(context)) : 1;
 	      int opsize = (typ & 1) ? (long_op ? 4 : 2) : 1;
-	      int step = (EFL & 0x400) ? -opsize : +opsize;
-	      /* FIXME: Check this, please.  */
-	      int seg = outp ? (segprefix >= 0 ? segprefix : DS) : ES;
+	      int step = (EFL_reg(context) & 0x400) ? -opsize : +opsize;
+	      int seg = outp ? (segprefix >= 0 ? segprefix : DS_reg(context))
+                             : ES_reg(context);
 
 	      if (outp)
 		/* FIXME: Check segment readable.  */
@@ -197,53 +201,51 @@
 
 	      if (repX)
 		if (long_addr)
-		  ECX = 0;
+		  ECX_reg(context) = 0;
 		else
-		  CX = 0;
+		  CX_reg(context) = 0;
 
 	      while (count-- > 0)
 		{
 		  void *data;
 		  if (outp)
-		    {
-		      data = PTR_SEG_OFF_TO_LIN (seg, long_addr ? ESI : SI);
-		      if (long_addr)
-			ESI += step;
-		      else
-			SI += step;
-		    }
+                  {
+		      data = PTR_SEG_OFF_TO_LIN (seg,
+                               long_addr ? ESI_reg(context) : SI_reg(context));
+		      if (long_addr) ESI_reg(context) += step;
+		      else SI_reg(context) += step;
+                  }
 		  else
-		    {
-		      data = PTR_SEG_OFF_TO_LIN (seg, long_addr ? EDI : DI);
-		      if (long_addr)
-			EDI += step;
-		      else
-			DI += step;
-		    }
-
+                  {
+		      data = PTR_SEG_OFF_TO_LIN (seg,
+                               long_addr ? EDI_reg(context) : DI_reg(context));
+		      if (long_addr) EDI_reg(context) += step;
+		      else DI_reg(context) += step;
+                  }
+                  
 		  switch (typ)
-		    {
+                  {
 		    case 0x6c:
-		      *((BYTE *)data) = inport (DX, 1);
+		      *((BYTE *)data) = inport( DX_reg(context), 1);
 		      break;
 		    case 0x6d:
 		      if (long_op)
-			*((DWORD *)data) = inport (DX, 4);
+			*((DWORD *)data) = inport( DX_reg(context), 4);
 		      else
-			*((WORD *)data) = inport (DX, 2);
+			*((WORD *)data) = inport( DX_reg(context), 2);
 		      break;
 		    case 0x6e:
-		      outport (DX, 1, *((BYTE *)data));
+		      outport( DX_reg(context), 1, *((BYTE *)data));
 		      break;
 		    case 0x6f:
 		      if (long_op)
-			outport (DX, 4, *((DWORD *)data));
+			outport( DX_reg(context), 4, *((DWORD *)data));
 		      else
-			outport (DX, 2, *((WORD *)data));
+			outport( DX_reg(context), 2, *((WORD *)data));
 		      break;
 		    }
 		}
-	      EIP++;
+	      EIP_reg(context)++;
 	      break;
 	    }
 
diff --git a/miscemu/int10.c b/miscemu/int10.c
index 04a1a87..3d93812 100644
--- a/miscemu/int10.c
+++ b/miscemu/int10.c
@@ -13,29 +13,27 @@
  *
  * Handler for int 10h (video).
  */
-void INT_Int10Handler( struct sigcontext_struct sigcontext )
+void INT_Int10Handler( struct sigcontext_struct context )
 {
-#define context (&sigcontext)
-    switch(AH)
+    switch(AH_reg(&context))
     {
     case 0x0f:
-        AL = 0x5b;
+        AL_reg(&context) = 0x5b;
         break;
 
     case 0x12:
-        if (BL == 0x10)
+        if (BL_reg(&context) == 0x10)
         {
-            BX = 0x0003;
-            CX = 0x0009;
+            BX_reg(&context) = 0x0003;
+            CX_reg(&context) = 0x0009;
         }
         break;
 			
     case 0x1a:
-        BX = 0x0008;
+        BX_reg(&context) = 0x0008;
         break;
 
     default:
-        INT_BARF( 0x10 );
+        INT_BARF( &context, 0x10 );
     }
-#undef context
 }
diff --git a/miscemu/int13.c b/miscemu/int13.c
index d570768..f867a92 100644
--- a/miscemu/int13.c
+++ b/miscemu/int13.c
@@ -13,29 +13,28 @@
  *
  * Handler for int 13h (disk I/O).
  */
-void INT_Int13Handler( struct sigcontext_struct sigcontext )
+void INT_Int13Handler( struct sigcontext_struct context )
 {
-#define context (&sigcontext)
-    switch(AH)
+    switch(AH_reg(&context))
     {
 	case 0x00:                            /* RESET DISK SYSTEM     */
 	case 0x04:                            /* VERIFY DISK SECTOR(S) */
-		AH = 0;
+		AH_reg(&context) = 0;
 		break;
 	       
 	case 0x05:                                     /* FORMAT TRACK */
-		AH = 0x0c;
-		SetCflag;
+		AH_reg(&context) = 0x0c;
+                SET_CFLAG(&context);
 		break;
 
 	case 0x06:             /* FORMAT TRACK AND SET BAD SECTOR FLAGS */
 	case 0x07:             /* FORMAT DRIVE STARTING AT GIVEN TRACK  */ 
-		AH = 0x0c;
+		AH_reg(&context) = 0x0c;
 		break;
 
 	case 0x08:                              /* GET DRIVE PARAMETERS  */
-		AH = (DL & 0x80) ? 0x07 : 0x01;
-		SetCflag;
+		AH_reg(&context) = (DL_reg(&context) & 0x80) ? 0x07 : 0x01;
+                SET_CFLAG(&context);
 		break;
 
         case 0x09:         /* INITIALIZE CONTROLLER WITH DRIVE PARAMETERS */
@@ -44,19 +43,18 @@
 	case 0x10:         /* CHECK IF DRIVE READY                        */
 	case 0x11:         /* RECALIBRATE DRIVE                           */
 	case 0x14:         /* CONTROLLER INTERNAL DIAGNOSTIC              */
-		AH = 0;
+		AH_reg(&context) = 0;
 		break;
 
 	case 0x0e:                    /* READ SECTOR BUFFER (XT only)      */
 	case 0x0f:                    /* WRITE SECTOR BUFFER (XT only)     */
         case 0x12:                    /* CONTROLLER RAM DIAGNOSTIC (XT,PS) */
 	case 0x13:                    /* DRIVE DIAGNOSTIC (XT,PS)          */
-		AH = 0x01;
-		SetCflag;
+		AH_reg(&context) = 0x01;
+                SET_CFLAG(&context);
 		break;
 
 	default:
-		INT_BARF( 0x13 );
+		INT_BARF( &context, 0x13 );
     }
-#undef context
 }
diff --git a/miscemu/int1a.c b/miscemu/int1a.c
index 60cf634..7e17e42 100644
--- a/miscemu/int1a.c
+++ b/miscemu/int1a.c
@@ -19,15 +19,15 @@
  *
  * Handler for int 1ah (date and time).
  */
-void INT_Int1aHandler( struct sigcontext_struct sigcontext )
+void INT_Int1aHandler( struct sigcontext_struct context )
 {
-#define context (&sigcontext)
-	time_t ltime;
-        DWORD ticks;
-	struct tm *bdtime;
-        struct timeval tvs;
+    time_t ltime;
+    DWORD ticks;
+    struct tm *bdtime;
+    struct timeval tvs;
 
-	switch(AH) {
+    switch(AH_reg(&context))
+    {
 	case 0:
                 /* This should give us the (approximately) correct
                  * 18.206 clock ticks per second since midnight
@@ -38,9 +38,9 @@
                 ticks = (((bdtime->tm_hour * 3600 + bdtime->tm_min * 60 +
                         bdtime->tm_sec) * 18206) / 1000) +
                         (tvs.tv_usec / 54927);
-		CX = ticks >> 16;
-		DX = ticks & 0x0000FFFF;
-		AX = 0;  /* No midnight rollover */
+		CX_reg(&context) = HIWORD(ticks);
+		DX_reg(&context) = LOWORD(ticks);
+		AX_reg(&context) = 0;  /* No midnight rollover */
 		dprintf_int(stddeb,"int1a_00 // ticks=%ld\n", ticks);
 		break;
 		
@@ -48,14 +48,17 @@
 		ltime = time(NULL);
 		bdtime = localtime(&ltime);
 		
-		CX = (BIN_TO_BCD(bdtime->tm_hour)<<8) | BIN_TO_BCD(bdtime->tm_min);
-		DX = (BIN_TO_BCD(bdtime->tm_sec)<<8);
+		CX_reg(&context) = (BIN_TO_BCD(bdtime->tm_hour)<<8) |
+                                    BIN_TO_BCD(bdtime->tm_min);
+		DX_reg(&context) = (BIN_TO_BCD(bdtime->tm_sec)<<8);
 
 	case 4:
 		ltime = time(NULL);
 		bdtime = localtime(&ltime);
-		CX = (BIN_TO_BCD(bdtime->tm_year/100)<<8) | BIN_TO_BCD((bdtime->tm_year-1900)%100);
-		DX = (BIN_TO_BCD(bdtime->tm_mon)<<8) | BIN_TO_BCD(bdtime->tm_mday);
+		CX_reg(&context) = (BIN_TO_BCD(bdtime->tm_year/100)<<8) |
+                                    BIN_TO_BCD((bdtime->tm_year-1900)%100);
+		DX_reg(&context) = (BIN_TO_BCD(bdtime->tm_mon)<<8) |
+                                    BIN_TO_BCD(bdtime->tm_mday);
 		break;
 
 		/* setting the time,date or RTC is not allow -EB */
@@ -72,7 +75,6 @@
 		break;
 
 	default:
-		INT_BARF( 0x1a );
-	}
-#undef context
+		INT_BARF( &context, 0x1a );
+    }
 }
diff --git a/miscemu/int21.c b/miscemu/int21.c
index 25b2f8c..b0a05e7 100644
--- a/miscemu/int21.c
+++ b/miscemu/int21.c
@@ -178,28 +178,26 @@
 	int drive;
 	long size,available;
 
-	if (DL == 0)
-		drive = DOS_GetDefaultDrive();
-	else
-		drive = DL - 1;
+	if (DL_reg(context) == 0) drive = DOS_GetDefaultDrive();
+	else drive = DL_reg(context) - 1;
 	
 	if (!DOS_ValidDrive(drive)) {
 		Error(InvalidDrive, EC_MediaError , EL_Disk);
-		AX = 0xffff;
+		AX_reg(context) = 0xffff;
 		return;
 	}
 	
 	if (!DOS_GetFreeSpace(drive, &size, &available)) {
 		Error(GeneralFailure, EC_MediaError , EL_Disk);
-		AX = 0xffff;
+		AX_reg(context) = 0xffff;
 		return;
 	}
 
-	AX = (drive < 2) ? 1 : 64;  /* 64 for hard-disks, 1 for diskettes */
-	CX = 512;
+	AX_reg(context) = (drive < 2) ? 1 : 64;  /* 64 for hard-disks, 1 for diskettes */
+	CX_reg(context) = 512;
 
-	BX = (available / (CX * AX));
-	DX = (size / (CX * AX));
+	BX_reg(context) = (available / (CX_reg(context) * AX_reg(context)));
+	DX_reg(context) = (size / (CX_reg(context) * AX_reg(context)));
 	Error (0,0,0);
 }
 
@@ -208,33 +206,32 @@
         int drive;
 	long size, available;
 	
-	if (DL == 0)
-		drive = DOS_GetDefaultDrive();
-	else
-		drive = DL - 1;
+	if (DL_reg(context) == 0) drive = DOS_GetDefaultDrive();
+	else drive = DL_reg(context) - 1;
 
-	if (!DOS_ValidDrive(DL)) {
-		AX = 4;
-		CX = 512;
-		DX = 0;
+	if (!DOS_ValidDrive(drive))
+        {
+		AX_reg(context) = 4;
+		CX_reg(context) = 512;
+		DX_reg(context) = 0;
 		Error (InvalidDrive, EC_MediaError, EL_Disk);
 		return;
 	}
 
-	if (!DOS_GetFreeSpace(DL, &size, &available)) {
+	if (!DOS_GetFreeSpace(drive, &size, &available)) {
 		Error(GeneralFailure, EC_MediaError , EL_Disk);
-		AX = 0xffff;
+		AX_reg(context) = 0xffff;
 		return;
 	}
 	
-	AX = (drive < 2) ? 1 : 64;  /* 64 for hard-disks, 1 for diskettes */
-	CX = 512;
-	DX = (size / (CX * AX));
+	AX_reg(context) = (drive < 2) ? 1 : 64;  /* 64 for hard-disks, 1 for diskettes */
+	CX_reg(context) = 512;
+	DX_reg(context) = (size / (CX_reg(context) * AX_reg(context)));
 
 	heap->mediaID = 0xf0;
 
-	DS = DosHeapHandle;
-	BX = (int)&heap->mediaID - (int)heap;
+	DS_reg(context) = DosHeapHandle;
+	BX_reg(context) = (int)&heap->mediaID - (int)heap;
 	Error (0,0,0);
 }
 
@@ -243,7 +240,7 @@
         if(!DOS_ValidDrive(drive))
         {
 	        Error (InvalidDrive, EC_MediaError, EL_Disk);
-                AX = 0x00ff;
+                AX_reg(context) = 0x00ff;
         }
         else
         {
@@ -274,9 +271,9 @@
                 dpb->free_search = 0;
                 dpb->free_clusters = 0xFFFF;    /* unknown */
 
-                AL = 0x00;
-                DS = SELECTOROF(dpbsegptr);
-                BX = OFFSETOF(dpbsegptr);
+                AL_reg(context) = 0x00;
+                DS_reg(context) = SELECTOROF(dpbsegptr);
+                BX_reg(context) = OFFSETOF(dpbsegptr);
         }
 }
 
@@ -286,38 +283,37 @@
 	int size;
 
 	/* can't read from stdout / stderr */
-	if ((BX == 1) || (BX == 2)) {
+	if ((BX_reg(context) == 1) || (BX_reg(context) == 2)) {
 		Error (InvalidHandle, EL_Unknown, EC_Unknown);
-		AX = InvalidHandle;
-		SetCflag;
-        	dprintf_int(stddeb,
-			"int21: read (%d, void *, 0x%x) = EBADF\n", BX, CX);
+		AX_reg(context) = InvalidHandle;
+		SET_CFLAG(context);
+        	dprintf_int(stddeb, "int21: read (%d, void *, 0x%x) = EBADF\n",
+                            BX_reg(context), CX_reg(context));
 		return;
 	}
 
-	ptr = PTR_SEG_OFF_TO_LIN (DS,DX);
-	if (BX == 0) {
+	ptr = PTR_SEG_OFF_TO_LIN (DS_reg(context),DX_reg(context));
+	if (BX_reg(context) == 0) {
 		*ptr = EOF;
 		Error (0,0,0);
-		AX = 1;
-		ResetCflag;
-        	dprintf_int(stddeb,
-			"int21: read (%d, void *, 0x%x) = EOF\n", BX, CX);
+		AX_reg(context) = 1;
+		RESET_CFLAG(context);
+        	dprintf_int(stddeb, "int21: read (%d, void *, 0x%x) = EOF\n",
+                            BX_reg(context), CX_reg(context));
 		return;
 	} else {
-		size = read(BX, ptr, CX);
-        	dprintf_int(stddeb,
-			"int21: read (%d, void *, 0x%x) = 0x%x\n",
-			BX, CX, size);
+		size = read(BX_reg(context), ptr, CX_reg(context));
+        	dprintf_int(stddeb, "int21: read (%d, void *, 0x%x) = 0x%x\n",
+                            BX_reg(context), CX_reg(context), size);
 		if (size == -1) {
 			errno_to_doserr();
-			AX = ExtendedError;
-			SetCflag;
+			AX_reg(context) = ExtendedError;
+			SET_CFLAG(context);
 			return;
 		}		
 		Error (0,0,0);
-		AX = size;
-		ResetCflag;
+		AX_reg(context) = size;
+		RESET_CFLAG(context);
 	}
 }
 
@@ -326,41 +322,41 @@
 	char *ptr;
 	int x,size;
 	
-	ptr = PTR_SEG_OFF_TO_LIN (DS,DX);
+	ptr = PTR_SEG_OFF_TO_LIN (DS_reg(context),DX_reg(context));
 	
-	if (BX == 0) {
+	if (BX_reg(context) == 0) {
 		Error (InvalidHandle, EC_Unknown, EL_Unknown);
-		EAX = InvalidHandle;
-		SetCflag;
+		EAX_reg(context) = InvalidHandle;
+		SET_CFLAG(context);
 		return;
 	}
 
-	if (BX < 3) {
-		for (x = 0;x != CX;x++) {
+	if (BX_reg(context) < 3) {
+		for (x = 0;x != CX_reg(context);x++) {
 			dprintf_int(stddeb, "%c", *ptr++);
 		}
 		fflush(stddeb);
 
 		Error (0,0,0);
-		AX = CX;
-		ResetCflag;
+		AX_reg(context) = CX_reg(context);
+		RESET_CFLAG(context);
 	} else {
-		size = write(BX, ptr , CX);
+		size = write(BX_reg(context), ptr , CX_reg(context));
 		if (size == 0) {
 			Error (WriteFault, EC_Unknown, EL_Unknown);
-			AX = ExtendedError;
+			AX_reg(context) = ExtendedError;
 			return;
 		}
 
 		if (size == -1) {
 			errno_to_doserr();
-			AX = ExtendedError;
-			SetCflag;
+			AX_reg(context) = ExtendedError;
+			SET_CFLAG(context);
 			return;
 		}		
 		Error (0,0,0);
-		AX = size;
-		ResetCflag;
+		AX_reg(context) = size;
+		RESET_CFLAG(context);
 	}
 }
 
@@ -368,7 +364,8 @@
 {
 	off_t status, fileoffset;
 	
-	switch (AL) {
+	switch (AL_reg(context))
+        {
 		case 1: fileoffset = SEEK_CUR;
 			break;
 		case 2: fileoffset = SEEK_END;
@@ -376,77 +373,79 @@
 		default:
 		case 0: fileoffset = SEEK_SET;
 			break;
-		}
-        status = lseek(BX, (CX << 16) + DX, fileoffset);
+	}
+        status = lseek(BX_reg(context), (CX_reg(context) << 16) + DX_reg(context), fileoffset);
 
 	dprintf_int (stddeb, "int21: seek (%d, 0x%x, %d) = 0x%lx\n",
-			BX, (CX << 16) + DX, AL, status);
+			BX_reg(context), (CX_reg(context) << 16) + DX_reg(context), AL_reg(context), status);
 
-	if (status == -1) {
+	if (status == -1)
+        {
 		errno_to_doserr();
-		AX = ExtendedError;
-                SetCflag;
+		AX_reg(context) = ExtendedError;
+                SET_CFLAG(context);
 		return;
 	}		
 	Error (0,0,0);
-	AX = LOWORD(status);
-	DX = HIWORD(status);
-	ResetCflag;
+	AX_reg(context) = LOWORD(status);
+	DX_reg(context) = HIWORD(status);
+	RESET_CFLAG(context);
 }
 
 static void ioctlGetDeviceInfo(struct sigcontext_struct *context)
 {
 
-	dprintf_int (stddeb, "int21: ioctl (%d, GetDeviceInfo)\n", BX);
+	dprintf_int (stddeb, "int21: ioctl (%d, GetDeviceInfo)\n", BX_reg(context));
 
-	switch (BX) {
+	switch (BX_reg(context))
+        {
 		case 0:
 		case 1:
 		case 2:
-			DX = 0x80d0 | (1 << (BX != 0));
-                        ResetCflag;
+			DX_reg(context) = 0x80d0 | (1 << (BX_reg(context) != 0));
+                        RESET_CFLAG(context);
 			break;
 
 		default:
 		{
 		    struct stat sbuf;
 	    
-		    if (fstat(BX, &sbuf) < 0)
+		    if (fstat(BX_reg(context), &sbuf) < 0)
 		    {
-                        INT_BARF( 0x21 );
-			SetCflag;
+                        INT_BARF( context, 0x21 );
+			SET_CFLAG(context);
 			return;
 		    }
 	    
 		    /* This isn't the right answer, but should be close enough. */
-		    DX = 0x0943;
+		    DX_reg(context) = 0x0943;
 		}
 	}
-	ResetCflag;
+	RESET_CFLAG(context);
 }
 
 static void ioctlGenericBlkDevReq(struct sigcontext_struct *context)
 {
-	BYTE *dataptr = PTR_SEG_OFF_TO_LIN(DS, DX);
+	BYTE *dataptr = PTR_SEG_OFF_TO_LIN(DS_reg(context), DX_reg(context));
 	int drive;
 
-	if (BL == 0)
-		drive = DOS_GetDefaultDrive();
-	else
-		drive = BL - 1;
+	if (BL_reg(context) == 0) drive = DOS_GetDefaultDrive();
+	else drive = BL_reg(context) - 1;
 
-	if (!DOS_ValidDrive(drive)) {
+	if (!DOS_ValidDrive(drive))
+        {
                 Error( FileNotFound, EC_NotFound, EL_Disk );
-                AX = FileNotFound;
-		SetCflag;
+                AX_reg(context) = FileNotFound;
+		SET_CFLAG(context);
 		return;
 	}
 
-	if (CH != 0x08) {
-            INT_BARF( 0x21 );
+	if (CH_reg(context) != 0x08)
+        {
+            INT_BARF( context, 0x21 );
             return;
 	}
-	switch (CL) {
+	switch (CL_reg(context)) {
 		case 0x60: /* get device parameters */
 			   /* used by w4wgrp's winfile */
 			memset(dataptr, 0, 0x26);
@@ -465,10 +464,10 @@
 				setword(&dataptr[4], 80); /* # of cylinders */
 			}
 			CreateBPB(drive, &dataptr[7]);			
-			ResetCflag;
+			RESET_CFLAG(context);
 			return;
 		default:
-                        INT_BARF( 0x21 );
+                        INT_BARF( context, 0x21 );
 	}
 }
 
@@ -480,9 +479,9 @@
 	ltime = time(NULL);
 	now = localtime(&ltime);
 
-	CX = now->tm_year + 1900;
-	DX = ((now->tm_mon + 1) << 8) | now->tm_mday;
-	AX = now->tm_wday;
+	CX_reg(context) = now->tm_year + 1900;
+	DX_reg(context) = ((now->tm_mon + 1) << 8) | now->tm_mday;
+	AX_reg(context) = now->tm_wday;
 }
 
 static void GetSystemTime(struct sigcontext_struct *context)
@@ -493,32 +492,33 @@
 	gettimeofday(&tv,NULL);		/* Note use of gettimeofday(), instead of time() */
 	now = localtime(&tv.tv_sec);
 	 
-	CX = (now->tm_hour<<8) | now->tm_min;
-	DX = (now->tm_sec<<8) | tv.tv_usec/10000;
+	CX_reg(context) = (now->tm_hour<<8) | now->tm_min;
+	DX_reg(context) = (now->tm_sec<<8) | tv.tv_usec/10000;
 					/* Note hundredths of seconds */
 }
 
 static void GetExtendedErrorInfo(struct sigcontext_struct *context)
 {
-	AX = ExtendedError;
-	BX = (ErrorClass << 8) | Action;
-	CH = ErrorLocus;
+	AX_reg(context) = ExtendedError;
+	BX_reg(context) = (ErrorClass << 8) | Action;
+	CH_reg(context) = ErrorLocus;
 }
 
 static void CreateFile(struct sigcontext_struct *context)
 {
     int handle;
-    handle = open(DOS_GetUnixFileName( PTR_SEG_OFF_TO_LIN(DS,DX)), 
+    handle = open(DOS_GetUnixFileName( PTR_SEG_OFF_TO_LIN(DS_reg(context),
+                                                          DX_reg(context))), 
 		  O_CREAT | O_TRUNC | O_RDWR, 0666 );
     if (handle == -1) {
 	errno_to_doserr();
-	AX = ExtendedError;
-	SetCflag;
+	AX_reg(context) = ExtendedError;
+	SET_CFLAG(context);
 	return;
     }
     Error (0,0,0);
-    AX = handle;
-    ResetCflag;
+    AX_reg(context) = handle;
+    RESET_CFLAG(context);
 }
 
 void OpenExistingFile(struct sigcontext_struct *context)
@@ -527,7 +527,7 @@
 	int mode;
 	int lock;
 	
-	switch (AX & 0x0007)
+	switch (AX_reg(context) & 0x0007)
 	{
 	  case 0:
 	    mode = O_RDONLY;
@@ -542,27 +542,28 @@
 	    break;
 	}
 
-	if ((handle = open(DOS_GetUnixFileName(PTR_SEG_OFF_TO_LIN(DS,DX)),
+	if ((handle = open(DOS_GetUnixFileName(PTR_SEG_OFF_TO_LIN(DS_reg(context),DX_reg(context))),
                            mode)) == -1)
         {
             if( Options.allowReadOnly )
-                handle = open( DOS_GetUnixFileName(PTR_SEG_OFF_TO_LIN(DS,DX)),
+                handle = open( DOS_GetUnixFileName(PTR_SEG_OFF_TO_LIN(DS_reg(context),DX_reg(context))),
                                O_RDONLY );
             if( handle == -1 )
             {
 		dprintf_int (stddeb, "int21: open (%s, %d) = -1\n",
-			DOS_GetUnixFileName(PTR_SEG_OFF_TO_LIN(DS,DX)), mode);
+			DOS_GetUnixFileName(PTR_SEG_OFF_TO_LIN(DS_reg(context),DX_reg(context))), mode);
                 errno_to_doserr();
-                AX = ExtendedError;
-                SetCflag;
+                AX_reg(context) = ExtendedError;
+                SET_CFLAG(context);
                 return;
             }
 	}		
 
 	dprintf_int (stddeb, "int21: open (%s, %d) = %d\n",
-		DOS_GetUnixFileName(PTR_SEG_OFF_TO_LIN(DS,DX)), mode, handle);
+		DOS_GetUnixFileName(PTR_SEG_OFF_TO_LIN(DS_reg(context),
+                                             DX_reg(context))), mode, handle);
 
-        switch (AX & 0x0070)
+        switch (AX_reg(context) & 0x0070)
 	{
 	  case 0x00:    /* compatability mode */
 	  case 0x40:    /* DENYNONE */
@@ -572,7 +573,7 @@
 	  case 0x30:    /* DENYREAD */
 	    dprintf_int(stddeb,
 	      "OpenExistingFile (%s): DENYREAD changed to DENYALL\n",
-	      (char *)PTR_SEG_OFF_TO_LIN(DS,DX));
+	      (char *)PTR_SEG_OFF_TO_LIN(DS_reg(context),DX_reg(context)));
 	  case 0x10:    /* DENYALL */  
 	    lock = LOCK_EX;
 	    break;
@@ -605,32 +606,33 @@
 	  if(result)  
 	  {
 	    errno_to_doserr();
-	    AX = ExtendedError;
+	    AX_reg(context) = ExtendedError;
 	    close(handle);
-	    SetCflag;
+	    SET_CFLAG(context);
 	    return;
 	  }
 
         }
 
 	Error (0,0,0);
-	AX = handle;
-	ResetCflag;
+	AX_reg(context) = handle;
+	RESET_CFLAG(context);
 }
 
 static void CloseFile(struct sigcontext_struct *context)
 {
-	dprintf_int (stddeb, "int21: close (%d)\n", BX);
+	dprintf_int (stddeb, "int21: close (%d)\n", BX_reg(context));
 
-	if (close(BX) == -1) {
+	if (close(BX_reg(context)) == -1)
+        {
 		errno_to_doserr();
-		AX = ExtendedError;
-		SetCflag;
+		AX_reg(context) = ExtendedError;
+		SET_CFLAG(context);
 		return;
 	}
 	Error (0,0,0);
-	AX = NoError;
-	ResetCflag;
+	AX_reg(context) = NoError;
+	RESET_CFLAG(context);
 }
 
 static void RenameFile(struct sigcontext_struct *context)
@@ -639,13 +641,16 @@
 
         /* FIXME: should not rename over an existing file */
 	dprintf_int(stddeb,"int21: renaming %s to %s\n",
-			(char *)PTR_SEG_OFF_TO_LIN(DS,DX), (char *)PTR_SEG_OFF_TO_LIN(ES,DI) );
+                  (char *)PTR_SEG_OFF_TO_LIN(DS_reg(context),DX_reg(context)),
+                  (char *)PTR_SEG_OFF_TO_LIN(ES_reg(context),DI_reg(context)));
 	
-	oldname = DOS_GetUnixFileName( PTR_SEG_OFF_TO_LIN(DS,DX) );
-	newname = DOS_GetUnixFileName( PTR_SEG_OFF_TO_LIN(ES,DI) );
+	oldname = DOS_GetUnixFileName( PTR_SEG_OFF_TO_LIN(DS_reg(context),
+                                                          DX_reg(context)) );
+	newname = DOS_GetUnixFileName( PTR_SEG_OFF_TO_LIN(ES_reg(context),
+                                                          DI_reg(context)) );
 
 	rename( oldname, newname);
-	ResetCflag;
+	RESET_CFLAG(context);
 }
 
 
@@ -653,28 +658,30 @@
 {
 	char *dirname;
 
-	dprintf_int(stddeb,"int21: makedir %s\n", (char *)PTR_SEG_OFF_TO_LIN(DS,DX) );
+	dprintf_int(stddeb,"int21: makedir %s\n", (char *)PTR_SEG_OFF_TO_LIN(DS_reg(context),DX_reg(context)) );
 	
-	if ((dirname = DOS_GetUnixFileName( PTR_SEG_OFF_TO_LIN(DS,DX) ))== NULL) {
+	if ((dirname = DOS_GetUnixFileName( PTR_SEG_OFF_TO_LIN(DS_reg(context),
+                                                               DX_reg(context)) ))== NULL) {
             Error( CanNotMakeDir, EC_AccessDenied, EL_Disk );
-            AX = CanNotMakeDir;
-            SetCflag;
+            AX_reg(context) = CanNotMakeDir;
+            SET_CFLAG(context);
             return;
 	}
 
-	if (mkdir(dirname,0) == -1) {
+	if (mkdir(dirname,0) == -1)
+        {
             Error( CanNotMakeDir, EC_AccessDenied, EL_Disk );
-            AX = CanNotMakeDir;
-            SetCflag;
+            AX_reg(context) = CanNotMakeDir;
+            SET_CFLAG(context);
             return;
 	}
-	ResetCflag;
+	RESET_CFLAG(context);
 }
 
 static void ChangeDir(struct sigcontext_struct *context)
 {
 	int drive;
-	char *dirname = PTR_SEG_OFF_TO_LIN(DS,DX);
+	char *dirname = PTR_SEG_OFF_TO_LIN(DS_reg(context),DX_reg(context));
 	drive = DOS_GetDefaultDrive();
 	dprintf_int(stddeb,"int21: changedir %s\n", dirname);
 	if (dirname != NULL && dirname[1] == ':') {
@@ -683,8 +690,8 @@
 		}
 	if (!DOS_ChangeDir(drive, dirname))
 	{
-		SetCflag;
-		AX=0x03;
+		SET_CFLAG(context);
+		AX_reg(context)=0x03;
 	}
 }
 
@@ -692,28 +699,28 @@
 {
 	char *dirname;
 
-	dprintf_int(stddeb,"int21: removedir %s\n", (char *)PTR_SEG_OFF_TO_LIN(DS,DX) );
+	dprintf_int(stddeb,"int21: removedir %s\n", (char *)PTR_SEG_OFF_TO_LIN(DS_reg(context),DX_reg(context)) );
 
-	if ((dirname = DOS_GetUnixFileName( PTR_SEG_OFF_TO_LIN(DS,DX) ))== NULL) {
+	if ((dirname = DOS_GetUnixFileName( PTR_SEG_OFF_TO_LIN(DS_reg(context),DX_reg(context)) ))== NULL) {
             Error( PathNotFound, EC_NotFound, EL_Disk );
-            AX = PathNotFound;
-            SetCflag;
+            AX_reg(context) = PathNotFound;
+            SET_CFLAG(context);
             return;
 	}
 
 /*
 	if (strcmp(unixname,DosDrives[drive].CurrentDirectory)) {
 		AL = CanNotRemoveCwd;
-		SetCflag;
+		SET_CFLAG(context);
 	}
 */	
 	if (rmdir(dirname) == -1) {
             Error( AccessDenied, EC_AccessDenied, EL_Disk );
-            AX = AccessDenied;
-            SetCflag;
+            AX_reg(context) = AccessDenied;
+            SET_CFLAG(context);
             return;
 	} 
-	ResetCflag;
+	RESET_CFLAG(context);
 }
 
 static void FindNext(struct sigcontext_struct *context)
@@ -728,8 +735,8 @@
 	do {
 		if ((dp = DOS_readdir(dp)) == NULL) {
 			Error(NoMoreFiles, EC_MediaError , EL_Disk);
-			AX = NoMoreFiles;
-			SetCflag;
+			AX_reg(context) = NoMoreFiles;
+			SET_CFLAG(context);
 			return;
 		}
 	} /* while (*(dta + 0x0c) != dp->attribute);*/
@@ -746,8 +753,8 @@
 	setdword(&dta[0x1a], dp->filesize);
 	strncpy(dta + 0x1e, dp->filename, 13);
 
-	AX = 0;
-	ResetCflag;
+	AX_reg(context) = 0;
+	RESET_CFLAG(context);
 
         dprintf_int(stddeb, "int21: FindNext -- (%s) index=%d size=%ld\n", dp->filename, dp->entnum, dp->filesize);
 	return;
@@ -755,7 +762,8 @@
 
 static void FindFirst(struct sigcontext_struct *context)
 {
-	BYTE drive, *path = PTR_SEG_OFF_TO_LIN(DS, DX);
+	BYTE drive, *path = PTR_SEG_OFF_TO_LIN(DS_reg(context),
+                                               DX_reg(context));
 	struct dosdirent *dp;
 
 	BYTE *dta = GetCurrentDTA();
@@ -767,8 +775,8 @@
 
 		if (!DOS_ValidDrive(drive)) {
 			Error(InvalidDrive, EC_MediaError , EL_Disk);
-			AX = InvalidDrive;
-			SetCflag;
+			AX_reg(context) = InvalidDrive;
+			SET_CFLAG(context);
 			return;
 		}
 	} else
@@ -776,16 +784,16 @@
 
 	*dta = drive;
 	memset(dta + 1 , '?', 11);
-	*(dta + 0x0c) = ECX & (FA_LABEL | FA_DIREC);
+	*(dta + 0x0c) = ECX_reg(context) & (FA_LABEL | FA_DIREC);
 
 	if ((dp = DOS_opendir(path)) == NULL) {
 		Error(PathNotFound, EC_MediaError, EL_Disk);
-		AX = FileNotFound;
-		SetCflag;
+		AX_reg(context) = FileNotFound;
+		SET_CFLAG(context);
 		return;
 	}
 
-	dp->search_attribute = ECX & (FA_LABEL | FA_DIREC);
+	dp->search_attribute = ECX_reg(context) & (FA_LABEL | FA_DIREC);
 	memcpy(dta + 0x11, &dp, sizeof(dp));
 	FindNext(context);
 }
@@ -795,14 +803,14 @@
 	struct stat filestat;
 	struct tm *now;
 
-        fstat( BX, &filestat );	
+        fstat( BX_reg(context), &filestat );
 	now = localtime (&filestat.st_mtime);
 	
-	CX = ((now->tm_hour * 0x2000) + (now->tm_min * 0x20) + now->tm_sec/2);
-	DX = (((now->tm_year + 1900 - 1980) * 0x200) +
+	CX_reg(context) = ((now->tm_hour * 0x2000) + (now->tm_min * 0x20) + now->tm_sec/2);
+	DX_reg(context) = (((now->tm_year + 1900 - 1980) * 0x200) +
               (now->tm_mon * 0x20) + now->tm_mday);
 
-	ResetCflag;
+	RESET_CFLAG(context);
 }
 
 static void SetFileDateTime(struct sigcontext_struct *context)
@@ -812,13 +820,14 @@
 	
         /* FIXME: Argument isn't the name of the file in DS:DX,
            but the file handle in BX */
-	filename = DOS_GetUnixFileName( PTR_SEG_OFF_TO_LIN(DS,DX) );
+	filename = DOS_GetUnixFileName( PTR_SEG_OFF_TO_LIN(DS_reg(context),
+                                                           DX_reg(context)) );
 
 	filetime.actime = 0L;
 	filetime.modtime = filetime.actime;
 
 	utime(filename, &filetime);
-	ResetCflag;
+	RESET_CFLAG(context);
 }
 
 static void CreateTempFile(struct sigcontext_struct *context)
@@ -834,67 +843,68 @@
 
 	if (handle == -1) {
             Error( WriteProtected, EC_AccessDenied, EL_Disk );
-            AX = WriteProtected;
-            SetCflag;
+            AX_reg(context) = WriteProtected;
+            SET_CFLAG(context);
             return;
 	}
 
-	strcpy(PTR_SEG_OFF_TO_LIN(DS,DX), temp);
+	strcpy(PTR_SEG_OFF_TO_LIN(DS_reg(context),DX_reg(context)), temp);
 	
-	AX = handle;
-	ResetCflag;
+	AX_reg(context) = handle;
+	RESET_CFLAG(context);
 }
 
 static void CreateNewFile(struct sigcontext_struct *context)
 {
 	int handle;
 	
-	if ((handle = open(DOS_GetUnixFileName( PTR_SEG_OFF_TO_LIN(DS,DX) ), O_CREAT | O_EXCL | O_RDWR, 0666)) == -1) {
+	if ((handle = open(DOS_GetUnixFileName( PTR_SEG_OFF_TO_LIN(DS_reg(context),DX_reg(context)) ),
+                           O_CREAT | O_EXCL | O_RDWR, 0666)) == -1)
+        {
             Error( WriteProtected, EC_AccessDenied, EL_Disk );
-            AX = WriteProtected;
-            SetCflag;
+            AX_reg(context) = WriteProtected;
+            SET_CFLAG(context);
             return;
 	}
 
-	AX = handle;
-	ResetCflag;
+	AX_reg(context) = handle;
+	RESET_CFLAG(context);
 }
 
 static void GetCurrentDirectory(struct sigcontext_struct *context)
 {
 	int drive;
 
-	if (DL == 0)
-		drive = DOS_GetDefaultDrive();
-	else
-		drive = DL - 1;
+	if (DL_reg(context) == 0) drive = DOS_GetDefaultDrive();
+	else drive = DL_reg(context) - 1;
 
-	if (!DOS_ValidDrive(drive)) {
+	if (!DOS_ValidDrive(drive))
+        {
             Error( InvalidDrive, EC_NotFound, EL_Disk );
-            AX = InvalidDrive;
-            SetCflag;
+            AX_reg(context) = InvalidDrive;
+            SET_CFLAG(context);
             return;
 	}
 
-	strcpy(PTR_SEG_OFF_TO_LIN(DS,SI), DOS_GetCurrentDir(drive) );
-	ResetCflag;
+	strcpy(PTR_SEG_OFF_TO_LIN(DS_reg(context),SI_reg(context)),
+               DOS_GetCurrentDir(drive) );
+	RESET_CFLAG(context);
 }
 
 static void GetDiskSerialNumber(struct sigcontext_struct *context)
 {
 	int drive;
-	BYTE *dataptr = PTR_SEG_OFF_TO_LIN(DS, DX);
+	BYTE *dataptr = PTR_SEG_OFF_TO_LIN(DS_reg(context), DX_reg(context));
 	DWORD serialnumber;
 	
-	if (BL == 0)
-		drive = DOS_GetDefaultDrive();
-	else
-		drive = BL - 1;
+	if (BL_reg(context) == 0) drive = DOS_GetDefaultDrive();
+	else drive = BL_reg(context) - 1;
 
-	if (!DOS_ValidDrive(drive)) {
+	if (!DOS_ValidDrive(drive))
+        {
             Error( InvalidDrive, EC_NotFound, EL_Disk );
-            AX = InvalidDrive;
-            SetCflag;
+            AX_reg(context) = InvalidDrive;
+            SET_CFLAG(context);
             return;
 	}
 
@@ -905,25 +915,24 @@
 	strncpy(dataptr + 6, DOS_GetVolumeLabel(drive), 8);
 	strncpy(dataptr + 0x11, "FAT16   ", 8);
 	
-	AX = 0;
-	ResetCflag;
+	AX_reg(context) = 0;
+	RESET_CFLAG(context);
 }
 
 static void SetDiskSerialNumber(struct sigcontext_struct *context)
 {
 	int drive;
-	BYTE *dataptr = PTR_SEG_OFF_TO_LIN(DS, DX);
+	BYTE *dataptr = PTR_SEG_OFF_TO_LIN(DS_reg(context), DX_reg(context));
 	DWORD serialnumber;
 
-	if (BL == 0)
-		drive = DOS_GetDefaultDrive();
-	else
-		drive = BL - 1;
+	if (BL_reg(context) == 0) drive = DOS_GetDefaultDrive();
+	else drive = BL_reg(context) - 1;
 
-	if (!DOS_ValidDrive(drive)) {
+	if (!DOS_ValidDrive(drive))
+        {
             Error( InvalidDrive, EC_NotFound, EL_Disk );
-            AX = InvalidDrive;
-            SetCflag;
+            AX_reg(context) = InvalidDrive;
+            SET_CFLAG(context);
             return;
 	}
 
@@ -931,8 +940,8 @@
 			(dataptr[4] << 24);
 
 	DOS_SetSerialNumber(drive, serialnumber);
-	AX = 1;
-	ResetCflag;
+	AX_reg(context) = 1;
+	RESET_CFLAG(context);
 }
 
 static void DumpFCB(BYTE *fcb)
@@ -953,7 +962,7 @@
 
 static void FindFirstFCB(struct sigcontext_struct *context)
 {
-	BYTE *fcb = PTR_SEG_OFF_TO_LIN(DS, DX);
+	BYTE *fcb = PTR_SEG_OFF_TO_LIN(DS_reg(context), DX_reg(context));
 	struct fcb *standard_fcb;
 	struct fcb *output_fcb;
 	int drive;
@@ -981,7 +990,7 @@
 	    if (!DOS_ValidDrive(drive))
 	      {
 		Error (InvalidDrive, EC_MediaError, EL_Disk);
-		AX = 0xff;
+		AX_reg(context) = 0xff;
 		return;
 	      }
 	  }
@@ -999,7 +1008,7 @@
 		if (DOS_GetVolumeLabel(drive) != NULL) 
 		  {
 		    strncpy(output_fcb->name, DOS_GetVolumeLabel(drive), 11);
-		    AX = 0x00;
+		    AX_reg(context) = 0x00;
 		    return;
 		  }
 	      }
@@ -1013,7 +1022,7 @@
 	if ((output_fcb->directory = DOS_opendir(path))==NULL)
 	  {
 	    Error (PathNotFound, EC_MediaError, EL_Disk);
-	    AX = 0xff;
+	    AX_reg(context) = 0xff;
 	    return;
 	  }
 	
@@ -1022,7 +1031,7 @@
 
 static void DeleteFileFCB(struct sigcontext_struct *context)
 {
-	BYTE *fcb = PTR_SEG_OFF_TO_LIN(DS, DX);
+	BYTE *fcb = PTR_SEG_OFF_TO_LIN(DS_reg(context), DX_reg(context));
 	int drive;
 	struct dosdirent *dp;
 	char temp[256], *ptr;
@@ -1043,7 +1052,7 @@
 
 	if ((dp = DOS_opendir(temp)) == NULL) {
 		Error(InvalidDrive, EC_MediaError , EL_Disk);
-		AX = 0xff;
+		AX_reg(context) = 0xff;
 		return;
 	}
 
@@ -1059,12 +1068,12 @@
 		/* unlink(DOS_GetUnixFileName(temp)); */
 	}
 	DOS_closedir(dp);
-	AX = 0;
+	AX_reg(context) = 0;
 }
 
 static void RenameFileFCB(struct sigcontext_struct *context)
 {
-	BYTE *fcb = PTR_SEG_OFF_TO_LIN(DS, DX);
+	BYTE *fcb = PTR_SEG_OFF_TO_LIN(DS_reg(context), DX_reg(context));
 	int drive;
 	struct dosdirent *dp;
 	char temp[256], oldname[256], newname[256], *oldnameptr, *newnameptr;
@@ -1085,7 +1094,7 @@
 
 	if ((dp = DOS_opendir(temp)) == NULL) {
 		Error(InvalidDrive, EC_MediaError , EL_Disk);
-		AX = 0xff;
+		AX_reg(context) = 0xff;
 		return;
 	}
 
@@ -1105,7 +1114,7 @@
 			oldname, newname);
 	}
 	DOS_closedir(dp);
-	AX = 0;
+	AX_reg(context) = 0;
 }
 
 
@@ -1115,12 +1124,12 @@
     struct flock f;
     int result,retries=sharing_retries;
 
-    f.l_start = MAKELONG(DX,CX);
-    f.l_len   = MAKELONG(DI,SI);
+    f.l_start = MAKELONG(DX_reg(context),CX_reg(context));
+    f.l_len   = MAKELONG(DI_reg(context),SI_reg(context));
     f.l_whence = 0;
     f.l_pid = 0;
 
-    switch ( AX & 0xff )
+    switch ( AX_reg(context) & 0xff )
     {
         case 0x00: /* LOCK */
 	  f.l_type = F_WRLCK;
@@ -1131,13 +1140,13 @@
 	  break;
 
 	default:
-	  AX = 0x0001;
-	  SetCflag;
+	  AX_reg(context) = 0x0001;
+	  SET_CFLAG(context);
 	  return;
      }
  
      {
-          result = fcntl(BX,F_SETLK,&f); 
+          result = fcntl(BX_reg(context),F_SETLK,&f); 
           if ( retries && (!result) )
           {
               int i;
@@ -1152,19 +1161,19 @@
       if(result)  
       {
          errno_to_doserr();
-         AX = ExtendedError;
-         SetCflag;
+         AX_reg(context) = ExtendedError;
+         SET_CFLAG(context);
          return;
       }
 
        Error (0,0,0);
-       ResetCflag;
+       RESET_CFLAG(context);
 } 
 
 
 static void GetFileAttribute (struct sigcontext_struct * context)
 {
-  char *filename = PTR_SEG_OFF_TO_LIN (DS,DX);
+  char *filename = PTR_SEG_OFF_TO_LIN (DS_reg(context),DX_reg(context));
   struct stat s;
   int res;
 
@@ -1172,21 +1181,21 @@
   if (res==-1)
   {
     errno_to_doserr();
-    AX = ExtendedError;
-    SetCflag;
+    AX_reg(context) = ExtendedError;
+    SET_CFLAG(context);
     return;
   }
   
-  CX = 0;
+  CX_reg(context) = 0;
   if (S_ISDIR(s.st_mode))
-    CX |= 0x10;
+    CX_reg(context) |= 0x10;
   if ((S_IWRITE & s.st_mode) != S_IWRITE)
-    CX |= 0x01;
+    CX_reg(context) |= 0x01;
 
   dprintf_int (stddeb, "int21: GetFileAttributes (%s) = 0x%x\n",
-		filename, CX );
+		filename, CX_reg(context) );
 
-  ResetCflag;
+  RESET_CFLAG(context);
   Error (0,0,0); 
 }
 
@@ -1196,20 +1205,19 @@
 /***********************************************************************
  *           DOS3Call  (KERNEL.102)
  */
-void DOS3Call( struct sigcontext_struct sigcontext )
+void DOS3Call( struct sigcontext_struct context )
 {
-#define context (&sigcontext)
     int drive;
 
-    if (AH == 0x59) 
+    if (AH_reg(&context) == 0x59) 
     {
-	GetExtendedErrorInfo(context);
+	GetExtendedErrorInfo(&context);
 	return;
     } 
     else 
     {
 	Error (0,0,0);
-	switch(AH) 
+	switch(AH_reg(&context)) 
 	{
 	  case 0x00: /* TERMINATE PROGRAM */
             TASK_KillCurrentTask( 0 );
@@ -1242,16 +1250,14 @@
 	  case 0x28: /* RANDOM BLOCK WRITE TO FCB FILE */
 	  case 0x29: /* PARSE FILENAME INTO FCB */
 	  case 0x2e: /* SET VERIFY FLAG */
-            INT_BARF( 0x21 );
+            INT_BARF( &context, 0x21 );
 	    break;
 
-	  case 0x2b: /* SET SYSTEM DATE */
-	  case 0x2d: /* SET SYSTEM TIME */
 	  case 0x37: /* "SWITCHAR" - GET SWITCH CHARACTER
 			"SWITCHAR" - SET SWITCH CHARACTER
 			"AVAILDEV" - SPECIFY \DEV\ PREFIX USE */
 	  case 0x54: /* GET VERIFY FLAG */
-            INT_BARF( 0x21 );
+            INT_BARF( &context, 0x21 );
 	    break;
 
 	  case 0x18: /* NULL FUNCTIONS FOR CP/M COMPATIBILITY */
@@ -1259,473 +1265,494 @@
 	  case 0x1e:
 	  case 0x20:
 	  case 0x6b: /* NULL FUNCTION */
-            AL = 0;
+            AL_reg(&context) = 0;
 	    break;
 	
 	  case 0x5c: /* "FLOCK" - RECORD LOCKING */
-	    fLock(context);
+	    fLock(&context);
 	    break;
 
 	  case 0x0d: /* DISK BUFFER FLUSH */
-            ResetCflag; /* dos 6+ only */
+            RESET_CFLAG(&context); /* dos 6+ only */
             break;
 
 	  case 0x0e: /* SELECT DEFAULT DRIVE */
-		if (!DOS_ValidDrive(DL))
+		if (!DOS_ValidDrive(DL_reg(&context)))
                     Error (InvalidDrive, EC_MediaError, EL_Disk);
 		else
                 {
-                    DOS_SetDefaultDrive(DL);
+                    DOS_SetDefaultDrive(DL_reg(&context));
                     Error(0,0,0);
 		}
-                AL = MAX_DOS_DRIVES;
+                AL_reg(&context) = MAX_DOS_DRIVES;
 		break;
 
 	  case 0x11: /* FIND FIRST MATCHING FILE USING FCB */
-            FindFirstFCB(context);
+            FindFirstFCB(&context);
             break;
 
 	  case 0x13: /* DELETE FILE USING FCB */
-            DeleteFileFCB(context);
+            DeleteFileFCB(&context);
             break;
             
 	  case 0x17: /* RENAME FILE USING FCB */
-            RenameFileFCB(context);
+            RenameFileFCB(&context);
             break;
 
 	  case 0x19: /* GET CURRENT DEFAULT DRIVE */
-		AL = DOS_GetDefaultDrive();
+		AL_reg(&context) = DOS_GetDefaultDrive();
 		Error (0,0,0);
 	    break;
 
 	  case 0x1a: /* SET DISK TRANSFER AREA ADDRESS */
             {
                 TDB *pTask = (TDB *)GlobalLock( GetCurrentTask() );
-                pTask->dta = MAKELONG( DX, DS );
+                pTask->dta = MAKELONG( DX_reg(&context), DS_reg(&context) );
                 dprintf_int(stddeb, "int21: Set DTA: %08lx\n", pTask->dta);
             }
             break;
 
 	  case 0x1b: /* GET ALLOCATION INFORMATION FOR DEFAULT DRIVE */
-            DL = 0;
-	    GetDriveAllocInfo(context);
+            DL_reg(&context) = 0;
+	    GetDriveAllocInfo(&context);
 	    break;
 	
 	  case 0x1c: /* GET ALLOCATION INFORMATION FOR SPECIFIC DRIVE */
-	    GetDriveAllocInfo(context);
+	    GetDriveAllocInfo(&context);
 	    break;
 
 	  case 0x1f: /* GET DRIVE PARAMETER BLOCK FOR DEFAULT DRIVE */
-	    GetDrivePB(context, DOS_GetDefaultDrive());
+	    GetDrivePB(&context, DOS_GetDefaultDrive());
 	    break;
 		
 	  case 0x25: /* SET INTERRUPT VECTOR */
-            INT_SetHandler( AL, MAKELONG( DX, DS ) );
+            INT_SetHandler( AL_reg(&context),
+                            MAKELONG( DX_reg(&context), DS_reg(&context) ) );
             break;
 
 	  case 0x2a: /* GET SYSTEM DATE */
-	    GetSystemDate(context);
+	    GetSystemDate(&context);
+            break;
+
+          case 0x2b: /* SET SYSTEM DATE */
+            fprintf( stdnimp, "SetSystemDate(%02d/%02d/%04d): not allowed\n",
+                     DL_reg(&context), DH_reg(&context), CX_reg(&context) );
+            AL_reg(&context) = 0;  /* Let's pretend we succeeded */
             break;
 
 	  case 0x2c: /* GET SYSTEM TIME */
-	    GetSystemTime(context);
+	    GetSystemTime(&context);
 	    break;
 
+          case 0x2d: /* SET SYSTEM TIME */
+            fprintf( stdnimp, "SetSystemTime(%02d:%02d:%02d.%02d): not allowed\n",
+                     CH_reg(&context), CL_reg(&context),
+                     DH_reg(&context), DL_reg(&context) );
+            AL_reg(&context) = 0;  /* Let's pretend we succeeded */
+            break;
+
 	  case 0x2f: /* GET DISK TRANSFER AREA ADDRESS */
             {
                 TDB *pTask = (TDB *)GlobalLock( GetCurrentTask() );
-                ES = SELECTOROF( pTask->dta );
-                BX = OFFSETOF( pTask->dta );
+                ES_reg(&context) = SELECTOROF( pTask->dta );
+                BX_reg(&context) = OFFSETOF( pTask->dta );
             }
             break;
             
 	  case 0x30: /* GET DOS VERSION */
-	    AX = DOSVERSION;
-	    BX = 0x0012;     /* 0x123456 is Wine's serial # */
-	    CX = 0x3456;
+	    AX_reg(&context) = DOSVERSION;
+	    BX_reg(&context) = 0x0012;     /* 0x123456 is Wine's serial # */
+	    CX_reg(&context) = 0x3456;
 	    break;
 
 	  case 0x31: /* TERMINATE AND STAY RESIDENT */
-            INT_BARF( 0x21 );
+            INT_BARF( &context, 0x21 );
 	    break;
 
 	  case 0x32: /* GET DOS DRIVE PARAMETER BLOCK FOR SPECIFIC DRIVE */
-	    GetDrivePB(context, (DL == 0) ? (DOS_GetDefaultDrive()) : (DL-1));
+	    GetDrivePB(&context, (DL_reg(&context) == 0) ?
+                                (DOS_GetDefaultDrive()) : (DL_reg(&context)-1));
 	    break;
 
 	  case 0x33: /* MULTIPLEXED */
-	    switch (AL) {
+	    switch (AL_reg(&context))
+            {
 	      case 0x00: /* GET CURRENT EXTENDED BREAK STATE */
-                DL = 0;
+                DL_reg(&context) = 0;
 		break;
 
 	      case 0x01: /* SET EXTENDED BREAK STATE */
 		break;		
 		
 	      case 0x02: /* GET AND SET EXTENDED CONTROL-BREAK CHECKING STATE*/
-		DL = 0;
+		DL_reg(&context) = 0;
 		break;
 
 	      case 0x05: /* GET BOOT DRIVE */
-		DL = 2;
+		DL_reg(&context) = 2;
 		/* c: is Wine's bootdrive */
 		break;
 				
 	      case 0x06: /* GET TRUE VERSION NUMBER */
-		BX = DOSVERSION;
-		DX = 0x00;
+		BX_reg(&context) = DOSVERSION;
+		DX_reg(&context) = 0x00;
 		break;
 
 	      default:
-                INT_BARF( 0x21 );
+                INT_BARF( &context, 0x21 );
 		break;			
 	    }
 	    break;	
 	    
 	  case 0x34: /* GET ADDRESS OF INDOS FLAG */
-		ES = DosHeapHandle;
-		BX = (int)&heap->InDosFlag - (int)heap;
+		ES_reg(&context) = DosHeapHandle;
+		BX_reg(&context) = (int)&heap->InDosFlag - (int)heap;
 	    break;
 
 	  case 0x35: /* GET INTERRUPT VECTOR */
             {
-                SEGPTR addr = INT_GetHandler( AL );
-                ES = SELECTOROF(addr);
-                BX = OFFSETOF(addr);
+                SEGPTR addr = INT_GetHandler( AL_reg(&context) );
+                ES_reg(&context) = SELECTOROF(addr);
+                BX_reg(&context) = OFFSETOF(addr);
             }
 	    break;
 
 	  case 0x36: /* GET FREE DISK SPACE */
-	    GetFreeDiskSpace(context);
+	    GetFreeDiskSpace(&context);
 	    break;
 
 	  case 0x38: /* GET COUNTRY-SPECIFIC INFORMATION */
-	    AX = 0x02; /* no country support available */
-	    SetCflag;
+	    AX_reg(&context) = 0x02; /* no country support available */
+	    SET_CFLAG(&context);
 	    break;
 		
 	  case 0x39: /* "MKDIR" - CREATE SUBDIRECTORY */
-	    MakeDir(context);
+	    MakeDir(&context);
 	    break;
 	
 	  case 0x3a: /* "RMDIR" - REMOVE SUBDIRECTORY */
-	    RemoveDir(context);
+	    RemoveDir(&context);
 	    break;
 	
 	  case 0x3b: /* "CHDIR" - SET CURRENT DIRECTORY */
-	    ChangeDir(context);
+	    ChangeDir(&context);
 	    break;
 	
 	  case 0x3c: /* "CREAT" - CREATE OR TRUNCATE FILE */
-	    CreateFile(context);
+	    CreateFile(&context);
 	    break;
 
 	  case 0x3d: /* "OPEN" - OPEN EXISTING FILE */
-	    OpenExistingFile(context);
+	    OpenExistingFile(&context);
 	    break;
 	
 	  case 0x3e: /* "CLOSE" - CLOSE FILE */
-	    CloseFile(context);
+	    CloseFile(&context);
 	    break;
 	
 	  case 0x3f: /* "READ" - READ FROM FILE OR DEVICE */
-	    ReadFile(context);
+	    ReadFile(&context);
 	    break;
 	
 	  case 0x40: /* "WRITE" - WRITE TO FILE OR DEVICE */
-	    WriteFile(context);
+	    WriteFile(&context);
 	    break;
 	
 	  case 0x41: /* "UNLINK" - DELETE FILE */
-		if (unlink( DOS_GetUnixFileName( PTR_SEG_OFF_TO_LIN(DS,DX)) ) == -1) {
+		if (unlink( DOS_GetUnixFileName( PTR_SEG_OFF_TO_LIN(DS_reg(&context),DX_reg(&context))) ) == -1) {
 			errno_to_doserr();
-			AX = ExtendedError;
-			SetCflag;
+			AX_reg(&context) = ExtendedError;
+			SET_CFLAG(&context);
 			break;
 		}		
 		Error(0,0,0);
-		ResetCflag;
+		RESET_CFLAG(&context);
 		break;
 	
 	  case 0x42: /* "LSEEK" - SET CURRENT FILE POSITION */
-	    SeekFile(context);
+	    SeekFile(&context);
 	    break;
 	    
 	  case 0x43: /* FILE ATTRIBUTES */
-	    switch (AL) 
+	    switch (AL_reg(&context))
 	    {
 	      case 0x00:
-                        GetFileAttribute(context);
+                        GetFileAttribute(&context);
 		break;
 	      case 0x01:
-			ResetCflag;
+			RESET_CFLAG(&context);
 		break;
 	    }
 	    break;
 		
 	  case 0x44: /* IOCTL */
-	    switch (AL) 
+	    switch (AL_reg(&context))
 	    {
               case 0x00:
-                ioctlGetDeviceInfo(context);
+                ioctlGetDeviceInfo(&context);
 		break;
 
               case 0x08:   /* Check if drive is removable. */
-                drive = BL ? (BL - 1) : DOS_GetDefaultDrive();
+                drive = BL_reg(&context) ? (BL_reg(&context) - 1)
+                                        : DOS_GetDefaultDrive();
                 if(!DOS_ValidDrive(drive))
                 {
                     Error( InvalidDrive, EC_NotFound, EL_Disk );
-                    AX = InvalidDrive;
-                    SetCflag;
+                    AX_reg(&context) = InvalidDrive;
+                    SET_CFLAG(&context);
                 }
                 else
                 {
                     if (drive > 1)
-                        AX = 1;   /* not removable */
+                        AX_reg(&context) = 1;   /* not removable */
                     else
-                        AX = 0;      /* removable */
-                    ResetCflag;
+                        AX_reg(&context) = 0;      /* removable */
+                    RESET_CFLAG(&context);
                 }
                 break;
 		   
 	      case 0x09:   /* CHECK IF BLOCK DEVICE REMOTE */
-                drive = BL ? (BL - 1) : DOS_GetDefaultDrive();
+                drive = BL_reg(&context) ? (BL_reg(&context) - 1)
+                                        : DOS_GetDefaultDrive();
                 if(!DOS_ValidDrive(drive))
                 {
                     Error( InvalidDrive, EC_NotFound, EL_Disk );
-                    AX = InvalidDrive;
-                    SetCflag;
+                    AX_reg(&context) = InvalidDrive;
+                    SET_CFLAG(&context);
                 }
                 else
                 {
-		    DX = (1<<9) | (1<<12) | (1<<15);
-		    ResetCflag;
+		    DX_reg(&context) = (1<<9) | (1<<12) | (1<<15);
+		    RESET_CFLAG(&context);
                 }
 		break;
 
 	      case 0x0b:   /* SET SHARING RETRY COUNT */
-		if (!CX)
+		if (!CX_reg(&context))
 		{ 
-		  AX = 1;
-		  SetCflag;
+		  AX_reg(&context) = 1;
+		  SET_CFLAG(&context);
 		  break;
 		}
-		sharing_pause = CX;
-		if (!DX)
-		  sharing_retries = DX;
-		ResetCflag;
+		sharing_pause = CX_reg(&context);
+		if (!DX_reg(&context))
+		  sharing_retries = DX_reg(&context);
+		RESET_CFLAG(&context);
 		break;
 
               case 0x0d:
-                ioctlGenericBlkDevReq(context);
+                ioctlGenericBlkDevReq(&context);
                 break;
 
               case 0x0F:   /* Set logical drive mapping */
                 /* FIXME: Not implemented at the moment, always returns error
                  */
-                AX = 0x0001; /* invalid function */
-                SetCflag;
+                AX_reg(&context) = 0x0001; /* invalid function */
+                SET_CFLAG(&context);
                 break;
                 
 	      default:
-                INT_BARF( 0x21 );
+                INT_BARF( &context, 0x21 );
 		break;
 	    }
 	    break;
 
 	  case 0x45: /* "DUP" - DUPLICATE FILE HANDLE */
-            if ((AX = dup(BX)) == 0xffff)
+            if ((AX_reg(&context) = dup(BX_reg(&context))) == 0xffff)
             {
                 errno_to_doserr();
-                AX = ExtendedError;
-                SetCflag;
+                AX_reg(&context) = ExtendedError;
+                SET_CFLAG(&context);
             }
-            else ResetCflag;
+            else RESET_CFLAG(&context);
 	    break;
 
 	  case 0x46: /* "DUP2", "FORCEDUP" - FORCE DUPLICATE FILE HANDLE */
-            if (dup2( BX, CX ) == -1)
+            if (dup2( BX_reg(&context), CX_reg(&context) ) == -1)
             {
                 errno_to_doserr();
-                AX = ExtendedError;
-                SetCflag;
+                AX_reg(&context) = ExtendedError;
+                SET_CFLAG(&context);
             }
-            else ResetCflag;
+            else RESET_CFLAG(&context);
             break;
 
 	  case 0x47: /* "CWD" - GET CURRENT DIRECTORY */
-	    GetCurrentDirectory(context);
-	    AX = 0x0100; 
+	    GetCurrentDirectory(&context);
+	    AX_reg(&context) = 0x0100; 
 	    /* intlist: many Microsoft products for Windows rely on this */
 	    break;
 	
 	  case 0x48: /* ALLOCATE MEMORY */
 	  case 0x49: /* FREE MEMORY */
 	  case 0x4a: /* RESIZE MEMORY BLOCK */
-            INT_BARF( 0x21 );
+            INT_BARF( &context, 0x21 );
             break;
 	
 	  case 0x4b: /* "EXEC" - LOAD AND/OR EXECUTE PROGRAM */
-            WinExec( PTR_SEG_OFF_TO_LIN(DS,DX), SW_NORMAL );
+            WinExec( PTR_SEG_OFF_TO_LIN(DS_reg(&context),DX_reg(&context)),
+                     SW_NORMAL );
 	    break;		
 	
 	  case 0x4c: /* "EXIT" - TERMINATE WITH RETURN CODE */
-            TASK_KillCurrentTask( AL );
+            TASK_KillCurrentTask( AL_reg(&context) );
 	    break;
 
 	  case 0x4d: /* GET RETURN CODE */
-	    AX = NoError; /* normal exit */
+	    AX_reg(&context) = NoError; /* normal exit */
 	    break;
 
 	  case 0x4e: /* "FINDFIRST" - FIND FIRST MATCHING FILE */
-	    FindFirst(context);
+	    FindFirst(&context);
 	    break;
 
 	  case 0x4f: /* "FINDNEXT" - FIND NEXT MATCHING FILE */
-	    FindNext(context);
+	    FindNext(&context);
 	    break;
 
 	  case 0x51: /* GET PSP ADDRESS */
 	  case 0x62: /* GET PSP ADDRESS */
 	    /* FIXME: should we return the original DOS PSP upon */
 	    /*        Windows startup ? */
-	    BX = GetCurrentPDB();
+	    BX_reg(&context) = GetCurrentPDB();
 	    break;
 
 	  case 0x52: /* "SYSVARS" - GET LIST OF LISTS */
-            ES = 0x0;
-            BX = 0x0;
-            INT_BARF( 0x21 );
+            ES_reg(&context) = 0x0;
+            BX_reg(&context) = 0x0;
+            INT_BARF( &context, 0x21 );
             break;
 		
 	  case 0x56: /* "RENAME" - RENAME FILE */
-	    RenameFile(context);
+	    RenameFile(&context);
 	    break;
 	
 	  case 0x57: /* FILE DATE AND TIME */
-	    switch (AL) 
+	    switch (AL_reg(&context))
 	    {
 	      case 0x00:
-		GetFileDateTime(context);
+		GetFileDateTime(&context);
 		break;
 	      case 0x01:
-		SetFileDateTime(context);
+		SetFileDateTime(&context);
 		break;
 	    }
 	    break;
 
 	  case 0x58: /* GET OR SET MEMORY/UMB ALLOCATION STRATEGY */
-	    switch (AL) 
+	    switch (AL_reg(&context))
 	    {
 	      case 0x00:
-		AX = 1;
+		AX_reg(&context) = 1;
 		break;
 	      case 0x02:
-		AX = 0;
+		AX_reg(&context) = 0;
 		break;
 	      case 0x01:
 	      case 0x03:
 		break;
 	    }
-	    ResetCflag;
+	    RESET_CFLAG(&context);
 	    break;
 	
 	  case 0x5a: /* CREATE TEMPORARY FILE */
-	    CreateTempFile(context);
+	    CreateTempFile(&context);
 	    break;
 	
 	  case 0x5b: /* CREATE NEW FILE */
-	    CreateNewFile(context);
+	    CreateNewFile(&context);
 	    break;
 	
 	  case 0x5d: /* NETWORK */
 	  case 0x5e:
 	    /* network software not installed */
-	    AX = NoNetwork;
-	    SetCflag;
+	    AX_reg(&context) = NoNetwork;
+	    SET_CFLAG(&context);
 	    break;
 	
 	  case 0x5f: /* NETWORK */
-	    switch (AL) 
+	    switch (AL_reg(&context))
 	    {
 	      case 0x07: /* ENABLE DRIVE */
-		if (!DOS_EnableDrive(DL)) 
+		if (!DOS_EnableDrive(DL_reg(&context))) 
 		{
 		    Error(InvalidDrive, EC_MediaError , EL_Disk);
-		    AX = InvalidDrive;
-		    SetCflag;
+		    AX_reg(&context) = InvalidDrive;
+		    SET_CFLAG(&context);
 		    break;
 		}
 		else 
 		{
-		    ResetCflag;
+		    RESET_CFLAG(&context);
 		    break;
 		}
 	      case 0x08: /* DISABLE DRIVE */
-		if (!DOS_DisableDrive(DL)) 
+		if (!DOS_DisableDrive(DL_reg(&context)))
 		{
 		    Error(InvalidDrive, EC_MediaError , EL_Disk);
-		    AX = InvalidDrive;
-		    SetCflag;
+		    AX_reg(&context) = InvalidDrive;
+		    SET_CFLAG(&context);
 		    break;
 		} 
 		else 
 		{
-		    ResetCflag;
+		    RESET_CFLAG(&context);
 		    break;
 		}
 	      default:
 		/* network software not installed */
-		AX = NoNetwork; 
-		SetCflag;
+		AX_reg(&context) = NoNetwork; 
+		SET_CFLAG(&context);
 		break;
 	    }
 	    break;
 
 	  case 0x60: /* "TRUENAME" - CANONICALIZE FILENAME OR PATH */
-		strncpy(PTR_SEG_OFF_TO_LIN(ES,DI), PTR_SEG_OFF_TO_LIN(DS,SI), strlen(PTR_SEG_OFF_TO_LIN(DS,SI)) & 0x7f);
-		ResetCflag;
+		strncpy(PTR_SEG_OFF_TO_LIN(ES_reg(&context),DI_reg(&context)),
+                        PTR_SEG_OFF_TO_LIN(DS_reg(&context),SI_reg(&context)),
+                        strlen(PTR_SEG_OFF_TO_LIN(DS_reg(&context),SI_reg(&context))) & 0x7f);
+		RESET_CFLAG(&context);
 	    break;
 
 	  case 0x61: /* UNUSED */
 	  case 0x63: /* UNUSED */
 	  case 0x64: /* OS/2 DOS BOX */
 	  case 0x65: /* GET EXTENDED COUNTRY INFORMATION */
-            INT_BARF( 0x21 );
+            INT_BARF( &context, 0x21 );
             break;
 	
 	  case 0x66: /* GLOBAL CODE PAGE TABLE */
-	    switch (AL) {
+	    switch (AL_reg(&context))
+            {
 	      case 0x01:
-		BX = CodePage;
-		DX = BX;
-		ResetCflag;
+		DX_reg(&context) = BX_reg(&context) = CodePage;
+		RESET_CFLAG(&context);
 		break;			
 	      case 0x02: 
-		CodePage = BX;
-		ResetCflag;
+		CodePage = BX_reg(&context);
+		RESET_CFLAG(&context);
 		break;
 	    }
 	    break;
 
 	  case 0x67: /* SET HANDLE COUNT */			
-	    ResetCflag;
+	    RESET_CFLAG(&context);
 	    break;
 
 	  case 0x68: /* "FFLUSH" - COMMIT FILE */
 	  case 0x6a: /* COMMIT FILE */
-            fsync( BX );
-	    ResetCflag;
+            fsync( BX_reg(&context) );
+	    RESET_CFLAG(&context);
 	    break;		
 	
 	  case 0x69: /* DISK SERIAL NUMBER */
-	    switch (AL) 
+	    switch (AL_reg(&context))
 	    {
 	      case 0x00:
-		GetDiskSerialNumber(context);
+		GetDiskSerialNumber(&context);
 		break;			
 	      case 0x01: 
-		SetDiskSerialNumber(context);
+		SetDiskSerialNumber(&context);
 		break;
 	    }
 	    break;
@@ -1734,15 +1761,15 @@
 	    break;
 
 	  default:
-            INT_BARF( 0x21 );
+            INT_BARF( &context, 0x21 );
             break;
 	}
     }
     dprintf_int(stddeb,"ret21: AX %04x, BX %04x, CX %04x, DX %04x, "
-           "SI %04x, DI %04x, DS %04x, ES %04x EFL %08lx\n",
-           AX, BX, CX, DX, SI, DI, DS, ES, EFL);
-
-#undef context
+                "SI %04x, DI %04x, DS %04x, ES %04x EFL %08lx\n",
+                AX_reg(&context), BX_reg(&context), CX_reg(&context),
+                DX_reg(&context), SI_reg(&context), DI_reg(&context),
+                DS_reg(&context), ES_reg(&context), EFL_reg(&context));
 }
 
 
diff --git a/miscemu/int25.c b/miscemu/int25.c
index 5427075..58b3858 100644
--- a/miscemu/int25.c
+++ b/miscemu/int25.c
@@ -16,39 +16,38 @@
  *
  * Handler for int 25h (absolute disk read).
  */
-void INT_Int25Handler( struct sigcontext_struct sigcontext )
+void INT_Int25Handler( struct sigcontext_struct context )
 {
-#define context (&sigcontext)
-	BYTE *dataptr = PTR_SEG_OFF_TO_LIN(DS, BX);
-	DWORD begin, length;
+    BYTE *dataptr = PTR_SEG_OFF_TO_LIN( DS_reg(&context), BX_reg(&context) );
+    DWORD begin, length;
 
-        if(!DOS_ValidDrive(AL))
-        {
-            SetCflag;
-            AX = 0x0101;        /* unknown unit */
-            return;
-        }
+    if (!DOS_ValidDrive(AL_reg(&context)))
+    {
+        SET_CFLAG(&context);
+        AX_reg(&context) = 0x0101;        /* unknown unit */
+        return;
+    }
 
-	if (CX == 0xffff) {
-		begin = getdword(dataptr);
-		length = getword(&dataptr[4]);
-		dataptr = (BYTE *) PTR_SEG_TO_LIN(getdword(&dataptr[6]));
-			
-	} else {
-		begin = DX;
-		length = CX;
-	}
-	dprintf_int(stdnimp, "int25: abs diskread, drive %d, sector %ld, "
-	"count %ld, buffer %d\n", AL, begin, length, (int) dataptr);
+    if (CX_reg(&context) == 0xffff)
+    {
+        begin = getdword(dataptr);
+        length = getword(&dataptr[4]);
+        dataptr = (BYTE *) PTR_SEG_TO_LIN(getdword(&dataptr[6]));
+    }
+    else
+    {
+        begin = DX_reg(&context);
+        length = CX_reg(&context);
+    }
+    dprintf_int( stdnimp, "int25: abs diskread, drive %d, sector %ld, "
+                 "count %ld, buffer %d\n",
+                 AL_reg(&context), begin, length, (int) dataptr);
 
-	memset(dataptr, 0, length * 512);
+    memset(dataptr, 0, length * 512);
 
-	if (begin == 0 && length > 1) 
-		*(dataptr + 512) = 0xf8;
+    if (begin == 0 && length > 1) *(dataptr + 512) = 0xf8;
 
-	if (begin == 1) 
-		*dataptr = 0xf8;
+    if (begin == 1) *dataptr = 0xf8;
 
-	ResetCflag;
-#undef context
+    RESET_CFLAG(&context);
 }
diff --git a/miscemu/int26.c b/miscemu/int26.c
index aa281d7..06f70ed 100644
--- a/miscemu/int26.c
+++ b/miscemu/int26.c
@@ -15,32 +15,33 @@
  *
  * Handler for int 26h (absolute disk read).
  */
-void INT_Int26Handler( struct sigcontext_struct sigcontext )
+void INT_Int26Handler( struct sigcontext_struct context )
 {
-#define context (&sigcontext)
-	BYTE *dataptr = PTR_SEG_OFF_TO_LIN(DS, BX);
-	DWORD begin, length;
+    BYTE *dataptr = PTR_SEG_OFF_TO_LIN( DS_reg(&context), BX_reg(&context) );
+    DWORD begin, length;
 
-        if(!DOS_ValidDrive(AL))
-        {
-            SetCflag;
-            AX = 0x0101;        /* unknown unit */
-            return;
-        }
+    if (!DOS_ValidDrive(AL_reg(&context)))
+    {
+        SET_CFLAG(&context);
+        AX_reg(&context) = 0x0101;        /* unknown unit */
+        return;
+    }
 
-	if (CX == 0xffff) {
-		begin = getdword(dataptr);
-		length = getword(&dataptr[4]);
-		dataptr = (BYTE *) PTR_SEG_TO_LIN(getdword(&dataptr[6]));
-			
-	} else {
-		begin = DX;
-		length = CX;
-	}
+    if (CX_reg(&context) == 0xffff)
+    {
+        begin = getdword(dataptr);
+        length = getword(&dataptr[4]);
+        dataptr = (BYTE *) PTR_SEG_TO_LIN(getdword(&dataptr[6]));
+    }
+    else
+    {
+        begin = DX_reg(&context);
+        length = CX_reg(&context);
+    }
 		
-	dprintf_int(stdnimp,"int26: abs diskwrite, drive %d, sector %ld, "
-	"count %ld, buffer %d\n", AL, begin, length, (int) dataptr);
+    dprintf_int( stdnimp,"int26: abs diskwrite, drive %d, sector %ld, "
+                 "count %ld, buffer %d\n",
+                 AL_reg(&context), begin, length, (int) dataptr );
 
-	ResetCflag;
-#undef context
+    RESET_CFLAG(&context);
 }
diff --git a/miscemu/int2a.c b/miscemu/int2a.c
index 35921fb..13de9ff 100644
--- a/miscemu/int2a.c
+++ b/miscemu/int2a.c
@@ -13,16 +13,14 @@
  *
  * Handler for int 2ah (network).
  */
-void INT_Int2aHandler( struct sigcontext_struct sigcontext )
+void INT_Int2aHandler( struct sigcontext_struct context )
 {
-#define context (&sigcontext)
-    switch(AH)
+    switch(AH_reg(&context))
     {
     case 0x00:                             /* NETWORK INSTALLATION CHECK */
         break;
 		
     default:
-	INT_BARF( 0x2a );
+	INT_BARF( &context, 0x2a );
     }
-#undef context
 }
diff --git a/miscemu/int2f.c b/miscemu/int2f.c
index 88bd229..3a9cad4 100644
--- a/miscemu/int2f.c
+++ b/miscemu/int2f.c
@@ -16,13 +16,12 @@
  *
  * Handler for int 2fh (multiplex).
  */
-void INT_Int2fHandler( struct sigcontext_struct sigcontext )
+void INT_Int2fHandler( struct sigcontext_struct context )
 {
-#define context (&sigcontext)
-    switch(AH)
+    switch(AH_reg(&context))
     {
 	case 0x10:
-                AL = 0xff; /* share is installed */
+                AL_reg(&context) = 0xff; /* share is installed */
 		break;
 
 	case 0x15: /* mscdex */
@@ -30,48 +29,47 @@
 		break;
 
 	case 0x16:
-		do_int2f_16( context );
+		do_int2f_16( &context );
                 break;
 	default:
-		INT_BARF( 0x2f );
+		INT_BARF( &context, 0x2f );
             }
-#undef context
 }
 
 
 static void do_int2f_16(struct sigcontext_struct *context)
 {
-    switch(AL)
+    switch(AL_reg(context))
     {
     case 0x00:  /* Windows enhanced mode installation check */
-        AX = Options.enhanced ? WINVERSION : 0;
+        AX_reg(context) = Options.enhanced ? WINVERSION : 0;
         break;
 
     case 0x0a:  /* Get Windows version and type */
-        AX = 0;
-        BX = (WINVERSION >> 8) | ((WINVERSION << 8) & 0xff00);
-        CX = Options.enhanced ? 3 : 2;
+        AX_reg(context) = 0;
+        BX_reg(context) = (WINVERSION >> 8) | ((WINVERSION << 8) & 0xff00);
+        CX_reg(context) = Options.enhanced ? 3 : 2;
         break;
 
     case 0x80:  /* Release time-slice */
         break;  /* nothing to do */
 
     case 0x86:  /* DPMI detect mode */
-        AX = 0;  /* Running under DPMI */
+        AX_reg(context) = 0;  /* Running under DPMI */
         break;
 
     case 0x87:  /* DPMI installation check */
-        AX = 0x0000;  /* DPMI Installed */
-        BX = 0x0001;  /* 32bits available */
-        CL = 0x03;    /* processor 386 */
-        DX = 0x005a;  /* DPMI major/minor 0.90 */
-        SI = 0;       /* # of para. of DOS extended private data */
-        ES = 0;       /* ES:DI is DPMI switch entry point */
-        DI = 0;
+        AX_reg(context) = 0x0000; /* DPMI Installed */
+        BX_reg(context) = 0x0001; /* 32bits available */
+        CL_reg(context) = 0x03;   /* processor 386 */
+        DX_reg(context) = 0x005a; /* DPMI major/minor 0.90 */
+        SI_reg(context) = 0;      /* # of para. of DOS extended private data */
+        ES_reg(context) = 0;      /* ES:DI is DPMI switch entry point */
+        DI_reg(context) = 0;
         break;
 
     default:
-        INT_BARF( 0x2f );
+        INT_BARF( context, 0x2f );
     }
 }
 
diff --git a/miscemu/int5c.c b/miscemu/int5c.c
index ad94c25..f2794b7 100644
--- a/miscemu/int5c.c
+++ b/miscemu/int5c.c
@@ -17,9 +17,7 @@
  *
  * Also handler for interrupt 5c.
  */
-void NetBIOSCall( struct sigcontext_struct sigcontext )
+void NetBIOSCall( struct sigcontext_struct context )
 {
-#define context (&sigcontext)
-    INT_BARF( 0x5c );
-#undef context
+    INT_BARF( &context, 0x5c );
 }
diff --git a/miscemu/interrupts.c b/miscemu/interrupts.c
index b576424..a9b8b8a 100644
--- a/miscemu/interrupts.c
+++ b/miscemu/interrupts.c
@@ -67,11 +67,10 @@
 /**********************************************************************
  *	    INT_DummyHandler
  */
-void INT_DummyHandler( struct sigcontext_struct sigcontext )
+void INT_DummyHandler( struct sigcontext_struct context )
 {
-#define context (&sigcontext)
-    INT_BARF( CURRENT_STACK16->ordinal_number - FIRST_INTERRUPT_ORDINAL );
-#undef context
+    INT_BARF( &context,
+              CURRENT_STACK16->ordinal_number - FIRST_INTERRUPT_ORDINAL );
 }
 
 
@@ -80,11 +79,9 @@
  *
  * Handler for int 11h (get equipment list).
  */
-void INT_Int11Handler( struct sigcontext_struct sigcontext )
+void INT_Int11Handler( struct sigcontext_struct context )
 {
-#define context (&sigcontext)
-    AX = DOS_GetEquipment();
-#undef context
+    AX_reg(&context) = DOS_GetEquipment();
 }
 
 
@@ -93,11 +90,9 @@
  *
  * Handler for int 12h (get memory size).
  */
-void INT_Int12Handler( struct sigcontext_struct sigcontext )
+void INT_Int12Handler( struct sigcontext_struct context )
 {
-#define context (&sigcontext)
-    AX = 640;
-#undef context
+    AX_reg(&context) = 640;
 }
 
 
@@ -106,11 +101,9 @@
  *
  * Handler for int 15h.
  */
-void INT_Int15Handler( struct sigcontext_struct sigcontext )
+void INT_Int15Handler( struct sigcontext_struct context )
 {
-#define context (&sigcontext)
-    INT_BARF( 0x15 );
-#undef context
+    INT_BARF( &context, 0x15 );
 }
 
 
@@ -119,9 +112,7 @@
  *
  * Handler for int 16h (keyboard).
  */
-void INT_Int16Handler( struct sigcontext_struct sigcontext )
+void INT_Int16Handler( struct sigcontext_struct context )
 {
-#define context (&sigcontext)
-    INT_BARF( 0x16 );
-#undef context
+    INT_BARF( &context, 0x16 );
 }
diff --git a/multimedia/Makefile.in b/multimedia/Makefile.in
index ceec464..17ea1c7 100644
--- a/multimedia/Makefile.in
+++ b/multimedia/Makefile.in
@@ -26,26 +26,16 @@
 depend:
 	sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
 	$(CC) $(DIVINCL) $(XINCL) -MM *.c >> tmp_make
-	cp tmp_make Makefile
-	rm tmp_make
+	mv tmp_make Makefile
 
 clean:
 	rm -f *.o \#*\# *~ tmp_make
 
 distclean: clean
-	rm Makefile
+	rm -f Makefile
 
 countryclean:
 
-NAMES = $(SRCS:.c=)
-
-winelibclean:
-	for i in $(NAMES); do \
-	if test `grep -c WINELIB $$i.c` -ne 0; then \
-	rm $$i.o; \
-	fi; \
-	done
- 
 dummy:
 
 ### Dependencies:
diff --git a/multimedia/mcicda.c b/multimedia/mcicda.c
index f1e125c..e517fe6 100644
--- a/multimedia/mcicda.c
+++ b/multimedia/mcicda.c
@@ -29,7 +29,7 @@
 #endif
 
 #define SOUND_DEV "/dev/dsp"
-#define CDAUDIO_DEV "/dev/sbpcd"
+#define CDAUDIO_DEV "/dev/cdrom"
 
 #ifdef SOUND_VERSION
 #define IOCTL(a,b,c)		ioctl(a,b,&c)
@@ -566,7 +566,7 @@
 					lpParms->dwReturn = CDADev[wDevID].lpdwTrackPos[lpParms->dwTrack - 1];
                     			dprintf_cdaudio(stddeb,"CDAUDIO_mciStatus // get MCI_TRACK #%lu !\n", lpParms->dwTrack);
 					}
-				lpParms->dwReturn = CDAUDIO_CalcTime(wDevID, 
+				lpParms->dwReturn = CDAUDIO_CalcTime(wDevID,
 					CDADev[wDevID].dwTimeFormat, lpParms->dwReturn);
                 			dprintf_cdaudio(stddeb,"CDAUDIO_mciStatus // MCI_STATUS_POSITION=%08lX !\n",
 														lpParms->dwReturn);
@@ -577,14 +577,14 @@
 			 	return 0;
 			case MCI_STATUS_TIME_FORMAT:
                 		dprintf_cdaudio(stddeb,"CDAUDIO_mciStatus // MCI_STATUS_TIME_FORMAT !\n");
-				lpParms->dwReturn = MCI_FORMAT_MILLISECONDS;
+				lpParms->dwReturn = CDADev[wDevID].dwTimeFormat;
 			 	return 0;
 			default:
                 		dprintf_cdaudio(stddeb,"CDAUDIO_mciStatus // unknown command %08lX !\n", lpParms->dwItem);
 				return MCIERR_UNRECOGNIZED_COMMAND;
 			}
 		}
-    dprintf_cdaudio(stddeb,"CDAUDIO_mciStatus // not MCI_STATUS_ITEM !\n");
+	dprintf_cdaudio(stddeb,"CDAUDIO_mciStatus // not MCI_STATUS_ITEM !\n");
  	return 0;
 #else
 	return MMSYSERR_NOTENABLED;
@@ -842,12 +842,11 @@
 		case DRV_OPEN:
 		case MCI_OPEN_DRIVER:
 		case MCI_OPEN:
-			return CDAUDIO_mciOpen(dwDevID, dwParam1, (LPMCI_OPEN_PARMS)dwParam2); 
+			return CDAUDIO_mciOpen(dwDevID, dwParam1, (LPMCI_OPEN_PARMS)PTR_SEG_TO_LIN(dwParam2)); 
 		case DRV_CLOSE:
 		case MCI_CLOSE_DRIVER:
 		case MCI_CLOSE:
-			return CDAUDIO_mciClose(dwDevID, dwParam1, 
-					(LPMCI_GENERIC_PARMS)dwParam2);
+			return CDAUDIO_mciClose(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
 		case DRV_ENABLE:
 			return 1;
 		case DRV_DISABLE:
diff --git a/multimedia/mmsystem.c b/multimedia/mmsystem.c
index 0d130a0..7827c1d 100644
--- a/multimedia/mmsystem.c
+++ b/multimedia/mmsystem.c
@@ -3,6 +3,9 @@
  *
  * Copyright 1993 Martin Ayotte
  */
+/* FIXME: I think there are some segmented vs. linear pointer weirdnesses 
+ *        and long term pointers to 16 bit space in here
+ */
 
 #ifndef WINELIB
 
@@ -26,6 +29,10 @@
 static LPSTR	lpInstallNames = NULL;
 
 static MCI_OPEN_DRIVER_PARMS	mciDrv[MAXMCIDRIVERS];
+/* FIXME: I need to remember the aliasname of a spec. driver. 
+ *        and this is the easiest way. *sigh*
+ */
+static MCI_OPEN_PARMS		mciOpenDrv[MAXMCIDRIVERS];
 
 UINT midiGetErrorText(UINT uError, LPSTR lpText, UINT uSize);
 UINT waveGetErrorText(UINT uError, LPSTR lpText, UINT uSize);
@@ -47,6 +54,7 @@
 int MMSYSTEM_WEP(HANDLE hInstance, WORD wDataSeg,
 		 WORD cbHeapSize, LPSTR lpCmdLine)
 {
+	/* isn't WEP the Windows Exit Procedure ? */
 	printf("MMSYSTEM DLL INIT ... hInst=%04X \n", hInstance);
 	return(TRUE);
 }
@@ -790,15 +798,774 @@
 	return 0;
 }
 
+/* someone was just short of a crisis seeing me putting xxx lines of code
+ * in a single define. Well. What does the code hope for if not for the
+ * care of the optimizer? (Stolen by Terry Pratchett, ok ;)
+ */
+#define _MCI_STR(s) do {\
+	int __l__;\
+	dprintf_mci(stddeb,"->returns \"%s\"",s);\
+	if (lpstrReturnString) {\
+		__l__=strlen(s);\
+		if(__l__>uReturnLength) {\
+			strncpy(lpstrReturnString,s,uReturnLength-1);\
+			lpstrReturnString[uReturnLength-1]='\0';\
+		} else\
+			strcpy(lpstrReturnString,s);\
+		dprintf_mci(stddeb,"-->\"%s\"\n",lpstrReturnString);\
+	}\
+} while(0)
+/* calling DriverProc. We need to pass the struct as SEGMENTED POINTER. */
+#define _MCI_CALL_DRIVER(cmd,params) {\
+	DWORD	xparams;\
+	xparams=MAKE_SEGPTR(&params);\
+	switch(uDevTyp) {\
+	case MCI_DEVTYPE_CD_AUDIO:\
+		res=CDAUDIO_DriverProc(mciDrv[wDevID].wDeviceID,0,cmd,dwFlags, xparams);\
+		break;\
+	case MCI_DEVTYPE_WAVEFORM_AUDIO:\
+		res=WAVE_DriverProc(mciDrv[wDevID].wDeviceID,0,cmd,dwFlags,xparams);\
+		break;\
+	case MCI_DEVTYPE_SEQUENCER:\
+		res=MIDI_DriverProc(mciDrv[wDevID].wDeviceID,0,cmd,dwFlags,xparams);\
+		break;\
+	case MCI_DEVTYPE_ANIMATION:\
+		res=ANIM_DriverProc(mciDrv[wDevID].wDeviceID,0,cmd,dwFlags,xparams);\
+		break;\
+	case MCI_DEVTYPE_DIGITAL_VIDEO:\
+		dprintf_mci(stddeb,"_MCI_CALL_DRIVER //No DIGITAL_VIDEO yet !\n");\
+		res=MCIERR_DEVICE_NOT_INSTALLED;\
+		break;\
+	default:\
+		dprintf_mci(stddeb,"_MCI_CALL_DRIVER //Invalid Device Name '%s' !\n",dev);\
+		res=MCIERR_INVALID_DEVICE_NAME;\
+		break;\
+	}\
+}
+/* yeah, I know this is BAD. but we have to do that for MCI_OPEN_PARMS 
+ * strings.
+ */
+#define	_MCI_STRDUP_TO_SEG(dest,source) {\
+	HANDLE	x;\
+	x=USER_HEAP_ALLOC(strlen(source));\
+	dest=(LPSTR)MAKELONG(x,USER_HeapSel);\
+	strcpy(PTR_SEG_TO_LIN(dest),source);\
+}
+
 /**************************************************************************
 * 				mciSendString			[MMSYSTEM.702]
 */
-DWORD mciSendString (LPCSTR lpstrCommand,
-    LPSTR lpstrReturnString, UINT uReturnLength, HWND hwndCallback)
+/* Well, it's easy. The usercode sends a string with a command (and flags)
+ * expressed in words in it... We do our best to call approbiate drivers,
+ * and return a errorcode AND a readable string (if lpstrRS!=NULL)
+ * Info taken by watching cool134.exe and from Borland's mcistrwh.hlp
+ */
+DWORD mciSendString (LPCSTR lpstrCommand, LPSTR lpstrReturnString, 
+	UINT uReturnLength, HWND hwndCallback)
 {
-	dprintf_mci(stddeb, "mciSendString('%s', %p, %u, %X)\n", 
-			lpstrCommand, lpstrReturnString, 
-			uReturnLength, hwndCallback);
+	char	*cmd,*dev,*args,**keywords;
+	WORD	uDevTyp,wDevID;
+	DWORD	dwFlags;
+	int	track,i,nrofkeywords,res,timef;
+
+	dprintf_mci(stdnimp,"mciSendString('%s', %p, %d, %X)\n", lpstrCommand, 
+		lpstrReturnString, uReturnLength, hwndCallback
+	);
+	/* format is <command> <device> <optargs> */
+	cmd=strdup(lpstrCommand);
+	dev=strchr(cmd,' ');
+	if (dev==NULL) {
+		free(cmd);
+		return MCIERR_MISSING_DEVICE_NAME;
+	}
+	*dev++='\0';
+	args=strchr(dev,' ');
+	if (args!=NULL) *args++='\0';
+	AnsiUpper(dev);
+	AnsiUpper(cmd);
+	if (args!=NULL) {
+		char	*s;
+		AnsiUpper(args);
+		i=1;/* nrofkeywords = nrofspaces+1 */
+		s=args;
+		while ((s=strchr(s,' '))!=NULL) i++,s++;
+		keywords=(char**)malloc(sizeof(char*)*(i+2));
+		nrofkeywords=i;
+		s=args;i=0;
+		while (s && i<nrofkeywords) {
+			keywords[i++]=s;
+			s=strchr(s,' ');
+			if (s) *s++='\0';
+		}
+		keywords[i]=NULL;
+	} else {
+		nrofkeywords=0;
+		keywords=(char**)malloc(sizeof(char*));
+	}
+	dwFlags = 0; /* default flags */
+	i=0;
+	while (i<nrofkeywords) {
+		if (!strcmp(keywords[i],"WAIT")) {
+			dwFlags |= MCI_WAIT;
+			i++;
+			continue;
+		}
+		if (!strcmp(keywords[i],"NOTIFY")) {
+			/* how should we callback?  I don't know. */
+			/*dwFlags |= MCI_NOTIFY;*/
+			i++;
+			continue;
+		}
+		if (!strcmp(keywords[i],"TRACK")) {
+			if (i+1<nrofkeywords) {
+				sscanf(keywords[i+1],"%d",&track);
+				dwFlags |= MCI_TRACK;
+				i++;
+				/*FALLTHROUGH*/
+			}
+			i++;
+			continue;
+		}
+		i++;
+	}
+	if (!strcmp(cmd,"OPEN")) {
+		char	*s;
+		MCI_OPEN_PARMS	openParams;
+
+		openParams.lpstrElementName = NULL;
+		s=strchr(dev,'!');
+		if (s!=NULL) {
+			*s++='\0';
+			_MCI_STRDUP_TO_SEG(openParams.lpstrElementName,s);
+		}
+		if (!strcmp(dev,"CDAUDIO")) {
+			uDevTyp=MCI_DEVTYPE_CD_AUDIO;
+		} else if (!strcmp(dev,"WAVEAUDIO")) {
+			uDevTyp=MCI_DEVTYPE_WAVEFORM_AUDIO;
+		} else if (!strcmp(dev,"SEQUENCER")) {
+			uDevTyp=MCI_DEVTYPE_SEQUENCER;
+		} else if (!strcmp(dev,"ANIMATION1")) {
+			uDevTyp=MCI_DEVTYPE_ANIMATION;
+		} else if (!strcmp(dev,"AVIVIDEO")) {
+			uDevTyp=MCI_DEVTYPE_DIGITAL_VIDEO;
+		} else {
+			free(keywords);free(cmd);
+			return MCIERR_INVALID_DEVICE_NAME;
+		}
+		wDevID=0;
+		while(mciDrv[wDevID].wType) {
+			if (++wDevID>=MAXMCIDRIVERS) {
+				dprintf_mci(stddeb, "MCI_OPEN // MAXMCIDRIVERS reached !\n");
+				free(keywords);free(cmd);
+				return MCIERR_INTERNAL;
+			}
+		}
+		mciDrv[wDevID].wType		= uDevTyp;
+		mciDrv[wDevID].wDeviceID	= wDevID;
+		openParams.dwCallback		= 0;
+		openParams.wDeviceID		= wDevID;
+		/* all strings must be copied */
+		_MCI_STRDUP_TO_SEG(openParams.lpstrDeviceType,dev);
+		openParams.lpstrAlias		= NULL;
+		dwFlags |= MCI_OPEN_TYPE;
+		i=0;
+		while (i<nrofkeywords) {
+			if (!strcmp(keywords[i],"SHAREABLE")) {
+				dwFlags|=MCI_OPEN_SHAREABLE;
+				i++;
+				continue;
+			}
+			if (!strcmp(keywords[i],"ALIAS") && (i+1<nrofkeywords)) {
+				dwFlags|=MCI_OPEN_ALIAS;
+				_MCI_STRDUP_TO_SEG(openParams.lpstrAlias,keywords[i]);
+				i+=2;
+				continue;
+			}
+			if (!strcmp(keywords[i],"ELEMENT") && (i+1<nrofkeywords)) {
+				dwFlags|=MCI_OPEN_ELEMENT;
+				_MCI_STRDUP_TO_SEG(openParams.lpstrElementName,keywords[i]);
+				i+=2;
+				continue;
+			}
+			i++;
+		}
+		_MCI_CALL_DRIVER(MCI_OPEN,openParams);
+		if (res==0)
+			memcpy(&mciOpenDrv[wDevID],&openParams,sizeof(MCI_OPEN_PARMS));
+		free(keywords);free(cmd);
+		return res;
+	}
+	/* all other commands use the alias set in MCI_OPEN or (if not set) 
+	 * the devicetype
+	 */
+	wDevID=0;
+	while(1) {
+		SEGPTR	dname;
+		dname=(SEGPTR)mciOpenDrv[wDevID].lpstrAlias;
+		if (dname==NULL) 
+			dname=(SEGPTR)mciOpenDrv[wDevID].lpstrDeviceType;
+		if (!strcasecmp(PTR_SEG_TO_LIN(dname),dev))
+			break;
+		if (++wDevID >= MAXMCIDRIVERS) {
+			dprintf_mci(stddeb, "mciSendString // MAXMCIDRIVERS reached !\n");
+			free(keywords);free(cmd);
+			return MCIERR_INTERNAL;
+		}
+	}
+	uDevTyp=mciDrv[wDevID].wType;
+
+	if (!strcmp(cmd,"STATUS")) {
+		MCI_STATUS_PARMS statusParams;
+
+		if (args==NULL) {
+			free(keywords);free(cmd);
+			return MCIERR_MISSING_STRING_ARGUMENT;
+		}
+		statusParams.dwCallback = 0;
+		if (dwFlags & MCI_TRACK)
+			statusParams.dwTrack = track;
+		dwFlags |= MCI_STATUS_ITEM;
+		/* we need that later for printing... */
+		statusParams.dwItem = MCI_STATUS_TIME_FORMAT;
+		_MCI_CALL_DRIVER(MCI_STATUS,statusParams);
+		timef=statusParams.dwReturn;
+		statusParams.dwReturn=0;
+		statusParams.dwItem=0;
+		i=0;
+		while (i<nrofkeywords) {
+			if (	!strcmp(keywords[i],"CURRENT") &&
+				(i+1<nrofkeywords) &&
+				!strcmp(keywords[i+1],"TRACK")
+			) {
+				statusParams.dwItem=MCI_STATUS_CURRENT_TRACK;
+				i+=2;
+				continue;
+			}
+			if (	!strcmp(keywords[i],"TIME") &&
+				(i+1<nrofkeywords) &&
+				!strcmp(keywords[i+1],"FORMAT")
+			) {
+				statusParams.dwItem=MCI_STATUS_TIME_FORMAT;
+				i+=2;
+				continue;
+			}
+			if (!strcmp(keywords[i],"READY")) {
+				statusParams.dwItem=MCI_STATUS_READY;
+				i++;
+				continue;
+			}
+			if (!strcmp(keywords[i],"MODE")) {
+				statusParams.dwItem=MCI_STATUS_MODE;
+				i++;
+				continue;
+			}
+			if (	!strcmp(keywords[i],"NUMBER") && 
+				(i+2<nrofkeywords) &&
+				!strcmp(keywords[i+1],"OF") &&
+				!strcmp(keywords[i+2],"TRACKS")
+			) {
+				statusParams.dwItem = MCI_STATUS_NUMBER_OF_TRACKS;
+				i+=3;
+				continue;
+			}
+			if (!strcmp(keywords[i],"LENGTH")) {
+				statusParams.dwItem = MCI_STATUS_LENGTH;
+				i++;
+				continue;
+			}
+			if (!strcmp(keywords[i],"POSITION")) {
+				statusParams.dwItem = MCI_STATUS_POSITION;
+				i++;
+				continue;
+			}
+			if (	!strcmp(keywords[i],"MEDIA") && 
+				(i+1<nrofkeywords) &&
+				!strcmp(keywords[i+1],"PRESENT")
+			) {
+				statusParams.dwItem = MCI_STATUS_MEDIA_PRESENT;
+				i+=2;
+				continue;
+			}
+			i++;
+		}
+		_MCI_CALL_DRIVER(MCI_STATUS,statusParams);
+		if (res==0) {
+			switch (statusParams.dwItem) {
+			case MCI_STATUS_MODE:
+				switch (statusParams.dwReturn) {
+				case MCI_MODE_NOT_READY:_MCI_STR("not ready");break;
+				case MCI_MODE_STOP:_MCI_STR("stopped");break;
+				case MCI_MODE_PLAY:_MCI_STR("playing");break;
+				case MCI_MODE_RECORD:_MCI_STR("recording");break;
+				case MCI_MODE_SEEK:_MCI_STR("seeking");break;
+				case MCI_MODE_PAUSE:_MCI_STR("paused");break;
+				case MCI_MODE_OPEN:_MCI_STR("open");break;
+				default:break;
+				}
+				break;
+			case MCI_STATUS_MEDIA_PRESENT:
+				if (statusParams.dwReturn)
+					_MCI_STR("true");
+				else
+					_MCI_STR("false");
+				break;
+			case MCI_STATUS_NUMBER_OF_TRACKS:
+			case MCI_STATUS_CURRENT_TRACK:
+			{	char	buf[16];
+				sprintf(buf,"%ld",statusParams.dwReturn);
+				_MCI_STR(buf);
+				break;
+			}
+			case MCI_STATUS_POSITION:
+			case MCI_STATUS_LENGTH:
+			{	char	buf[100];
+				switch (timef) {
+				case MCI_FORMAT_MILLISECONDS:
+				case MCI_FORMAT_FRAMES:
+				case MCI_FORMAT_BYTES:
+				case MCI_FORMAT_SAMPLES:
+					sprintf(buf,"%ld",statusParams.dwReturn);
+					_MCI_STR(buf);
+					break;
+				case MCI_FORMAT_HMS:
+					/* well, the macros have the same content*/
+					/*FALLTRHOUGH*/
+				case MCI_FORMAT_MSF:
+					sprintf(buf,"%d:%d:%d",
+						MCI_HMS_HOUR(statusParams.dwReturn),
+						MCI_HMS_MINUTE(statusParams.dwReturn),
+						MCI_HMS_SECOND(statusParams.dwReturn)
+					);
+					_MCI_STR(buf);
+					break;
+				case MCI_FORMAT_TMSF:
+					sprintf(buf,"%d:%d:%d:%d",
+						MCI_TMSF_TRACK(statusParams.dwReturn),
+						MCI_TMSF_MINUTE(statusParams.dwReturn),
+						MCI_TMSF_SECOND(statusParams.dwReturn),
+						MCI_TMSF_FRAME(statusParams.dwReturn)
+					);
+					_MCI_STR(buf);
+					break;
+				default:
+					fprintf(stdnimp,"mciSendString:STATUS:missing timeformat for %d, report.\n",timef);
+					break;
+				}
+				break;
+			}
+			case MCI_STATUS_TIME_FORMAT:
+				switch (timef) {
+				case MCI_FORMAT_MILLISECONDS:_MCI_STR("milliseconds");break;
+				case MCI_FORMAT_FRAMES:_MCI_STR("frames");break;
+				case MCI_FORMAT_BYTES:_MCI_STR("bytes");break;
+				case MCI_FORMAT_SAMPLES:_MCI_STR("samples");break;
+				case MCI_FORMAT_HMS:_MCI_STR("hms");break;
+				case MCI_FORMAT_MSF:_MCI_STR("msf");break;
+				case MCI_FORMAT_TMSF:_MCI_STR("tmsf");break;
+				default:
+					fprintf(stdnimp,"mciSendString:STATUS:missing timeformat for %d, report.\n",timef);
+					break;
+				}
+				break;
+			default:
+				fprintf(stdnimp,"mciSendString:STATUS:missing result for %ld, report.\n",statusParams.dwItem);
+				break;
+			}
+		}
+		free(keywords);free(cmd);
+		return res;
+	}
+	if (!strcmp(cmd,"SET")) {
+		MCI_SET_PARMS	setParams;
+
+		if (args==NULL) {
+			free(keywords);free(cmd);
+			return MCIERR_MISSING_STRING_ARGUMENT;
+		}
+		setParams.dwCallback = 0;
+		i=0;
+		while (i<nrofkeywords) {
+			if (!strcmp(keywords[i],"DOOR") && i+1<nrofkeywords) {
+				if (!strcmp(keywords[i+1],"OPEN"))
+					dwFlags |= MCI_SET_DOOR_OPEN;
+				if (!strcmp(keywords[i+1],"CLOSED"))
+					dwFlags |= MCI_SET_DOOR_CLOSED;
+				i+=2;
+				continue;
+			}
+			if (	!strcmp(keywords[i],"TIME") && 
+				(i+2<nrofkeywords) &&
+				!strcmp(keywords[i+1],"FORMAT")
+			) {
+				dwFlags |= MCI_SET_TIME_FORMAT;
+				if (!strcmp(keywords[i+2],"MS"))
+					setParams.dwTimeFormat = MCI_FORMAT_MSF;
+				if (!strcmp(keywords[i+2],"MILLISECONDS"))
+					setParams.dwTimeFormat = MCI_FORMAT_MILLISECONDS;
+				if (!strcmp(keywords[i+2],"MSF"))
+					setParams.dwTimeFormat = MCI_FORMAT_MSF;
+				if (!strcmp(keywords[i+2],"HMS")) /* untested */
+					setParams.dwTimeFormat = MCI_FORMAT_HMS;
+				if (!strcmp(keywords[i+2],"FRAMES")) /* untested */
+					setParams.dwTimeFormat = MCI_FORMAT_FRAMES;
+				if (!strcmp(keywords[i+2],"BYTES")) /* untested */
+					setParams.dwTimeFormat = MCI_FORMAT_BYTES;
+				if (!strcmp(keywords[i+2],"SAMPLES")) /* untested */
+					setParams.dwTimeFormat = MCI_FORMAT_SAMPLES;
+				if (!strcmp(keywords[i+2],"TMSF")) /* untested */
+					setParams.dwTimeFormat = MCI_FORMAT_TMSF;
+				if (!strcmp(keywords[i+2],"SMPTE") && (i+3<nrofkeywords)) {
+					/* all untested */
+					if (!strcmp(keywords[i+3],"24"))
+						setParams.dwTimeFormat = MCI_FORMAT_SMPTE_24;
+					if (!strcmp(keywords[i+3],"25"))
+						setParams.dwTimeFormat = MCI_FORMAT_SMPTE_25;
+					if (!strcmp(keywords[i+3],"30"))
+						setParams.dwTimeFormat = MCI_FORMAT_SMPTE_30;
+					if (!strcmp(keywords[i+3],"30DROP"))
+						setParams.dwTimeFormat = MCI_FORMAT_SMPTE_30DROP;
+					i++;
+					/*FALLTHROUGH*/
+				}
+				i+=3;
+				continue;
+			}
+			if (!strcmp(args,"AUDIO") && (i+1<nrofkeywords)) {
+				dwFlags |= MCI_SET_AUDIO;
+				/* I'm not sure if those belong to the flags...
+				 * they could belong to setParams.dwAudio
+				 */
+				if (!strcmp(args,"ALL"))
+					dwFlags |= MCI_SET_AUDIO_ALL;
+				if (!strcmp(args,"LEFT"))
+					dwFlags |= MCI_SET_AUDIO_LEFT;
+				if (!strcmp(args,"RIGHT"))
+					dwFlags |= MCI_SET_AUDIO_RIGHT;
+				i++;
+				continue;
+			}
+			if (!strcmp(args,"VIDEO")) {
+				/* how to handle those? */
+				i++;
+				continue;
+			}
+			if (!strcmp(args,"ON")) {
+				dwFlags |= MCI_SET_ON;
+				i++;
+				continue;
+			}
+			if (!strcmp(args,"OFF")) {
+				dwFlags |= MCI_SET_ON;
+				i++;
+				continue;
+			}
+			i++;
+		}
+		_MCI_CALL_DRIVER(MCI_SET,setParams);
+		if (res==0) { /* does set return data? */ }
+		free(keywords);free(cmd);
+		return res;
+	}
+	if (!strcmp(cmd,"CAPABILITY")) {
+		MCI_GETDEVCAPS_PARMS	gdcParams;
+
+		gdcParams.dwCallback = 0;
+		if (args==NULL) {
+			free(keywords);free(cmd);
+			return MCIERR_MISSING_STRING_ARGUMENT;
+		}
+		dwFlags |= MCI_GETDEVCAPS_ITEM;
+		gdcParams.dwItem = 0;
+		i=0;
+		while (i<nrofkeywords) {
+			if (	!strcmp(keywords[i],"DEVICE") && 
+				(i+1<nrofkeywords) &&
+				!strcmp(keywords[i+1],"TYPE")
+			) {
+				gdcParams.dwItem = MCI_GETDEVCAPS_DEVICE_TYPE;	
+				i+=2;
+				continue;
+			}
+			if (	!strcmp(keywords[i],"HAS") &&
+				(i+1<nrofkeywords) &&
+				!strcmp(keywords[i+1],"AUDIO")
+			) {
+				gdcParams.dwItem = MCI_GETDEVCAPS_HAS_AUDIO;	
+				i+=2;
+				continue;
+			}
+			if (	!strcmp(keywords[i],"HAS") &&
+				(i+1<nrofkeywords) &&
+				!strcmp(keywords[i+1],"VIDEO")
+			) {
+				gdcParams.dwItem = MCI_GETDEVCAPS_HAS_VIDEO;	
+				i+=2;
+				continue;
+			}
+			if (	!strcmp(keywords[i],"USES") &&
+				(i+1<nrofkeywords) &&
+				!strcmp(keywords[i+1],"FILES")
+			) {
+				gdcParams.dwItem = MCI_GETDEVCAPS_HAS_VIDEO;	
+				i+=2;
+				continue;
+			}
+			if (	!strcmp(keywords[i],"COMPOUND") &&
+				(i+1<nrofkeywords) &&
+				!strcmp(keywords[i+1],"DEVICE")
+			) {
+				gdcParams.dwItem = MCI_GETDEVCAPS_COMPOUND_DEVICE;	
+				i+=2;
+				continue;
+			}
+			if (!strcmp(keywords[i],"CAN") && (i+1<nrofkeywords)) {
+				if (!strcmp(keywords[i+1],"RECORD"))
+					gdcParams.dwItem = MCI_GETDEVCAPS_CAN_RECORD;	
+				if (!strcmp(keywords[i+1],"PLAY"))
+					gdcParams.dwItem = MCI_GETDEVCAPS_CAN_PLAY;	
+				if (!strcmp(keywords[i+1],"EJECT"))
+					gdcParams.dwItem = MCI_GETDEVCAPS_CAN_EJECT;	
+				if (!strcmp(keywords[i+1],"SAVE"))
+					gdcParams.dwItem = MCI_GETDEVCAPS_CAN_SAVE;	
+				i+=2;
+				continue;
+			}
+			i++;
+		}
+		res=-1;
+		_MCI_CALL_DRIVER(MCI_GETDEVCAPS,gdcParams);
+		fprintf(stderr,"GETDEVCAPS returned res=%d\n",res);
+		if (res==0) {
+			switch (gdcParams.dwItem) {
+			case MCI_GETDEVCAPS_DEVICE_TYPE:
+				switch (gdcParams.dwReturn) {
+				case MCI_DEVTYPE_VCR:_MCI_STR("vcr");break;
+				case MCI_DEVTYPE_VIDEODISC:_MCI_STR("videodisc");break;
+				case MCI_DEVTYPE_CD_AUDIO:_MCI_STR("cd audio");break;
+				case MCI_DEVTYPE_OVERLAY:_MCI_STR("overlay");break;
+				case MCI_DEVTYPE_DAT:_MCI_STR("dat");break;
+				case MCI_DEVTYPE_SCANNER:_MCI_STR("scanner");break;
+				case MCI_DEVTYPE_ANIMATION:_MCI_STR("animation");break;
+				case MCI_DEVTYPE_DIGITAL_VIDEO:_MCI_STR("digital video");break;
+				case MCI_DEVTYPE_OTHER:_MCI_STR("other");break;
+				case MCI_DEVTYPE_WAVEFORM_AUDIO:_MCI_STR("waveform audio");break;
+				case MCI_DEVTYPE_SEQUENCER:_MCI_STR("sequencer");break;
+				default:fprintf(stdnimp,"mciSendString:GETCAPS_DEVTYPE:unknown type %ld, report.\n",gdcParams.dwReturn);break;
+				}
+				break;
+			case MCI_GETDEVCAPS_CAN_PLAY:
+			case MCI_GETDEVCAPS_CAN_EJECT:
+			case MCI_GETDEVCAPS_CAN_RECORD:
+			case MCI_GETDEVCAPS_CAN_SAVE:
+			case MCI_GETDEVCAPS_HAS_AUDIO:
+			case MCI_GETDEVCAPS_HAS_VIDEO:
+			case MCI_GETDEVCAPS_COMPOUND_DEVICE:
+			case MCI_GETDEVCAPS_USES_FILES:
+				/* well, is this right? no example here */
+				if (gdcParams.dwReturn)
+					_MCI_STR("true");
+				else
+					_MCI_STR("false");
+				break;
+			default:fprintf(stdnimp,"mciSendString:GETDEVCAPS:unknown type %ld, report.\n",gdcParams.dwItem);break;
+			}
+		}
+		free(keywords);free(cmd);
+		return res;
+	}
+	if (!strcmp(cmd,"PAUSE")) {
+		MCI_GENERIC_PARMS	genParams;
+		genParams.dwCallback=0;
+		_MCI_CALL_DRIVER(MCI_PAUSE,genParams);
+		free(keywords);free(cmd);
+		return res;
+	}
+	if (!strcmp(cmd,"PLAY")) {
+		int	nrargs,j,k,a[4];
+		char	*parsestr;
+		MCI_PLAY_PARMS		playParams;
+		MCI_STATUS_PARMS	statusParams;
+
+		statusParams.dwCallback=0;
+		statusParams.dwItem=MCI_STATUS_TIME_FORMAT;
+		dwFlags |= MCI_STATUS_ITEM;
+		_MCI_CALL_DRIVER(MCI_STATUS,statusParams);
+		dwFlags &= ~MCI_STATUS_ITEM;
+		timef=statusParams.dwReturn;
+		switch (timef) {
+		case MCI_FORMAT_MILLISECONDS:
+		case MCI_FORMAT_FRAMES:
+		case MCI_FORMAT_BYTES:
+		case MCI_FORMAT_SAMPLES:
+			nrargs=1;
+			parsestr="%d";
+			break;
+		case MCI_FORMAT_HMS:
+		case MCI_FORMAT_MSF:
+			parsestr="%d:%d:%d";
+			nrargs=3;
+			break;
+		case MCI_FORMAT_TMSF:
+			parsestr="%d:%d:%d:%d";
+			nrargs=4;
+			break;
+		default:fprintf(stdnimp,"mciSendString:PLAY:unknown timeformat %d, please report.\n",timef);
+			parsestr="%d";
+			nrargs=1;
+			break;
+		}
+		playParams.dwCallback=0;
+		i=0;
+		while (i<nrofkeywords) {
+			if (	!strcmp(keywords[i],"TO") &&
+				(i+1<nrofkeywords)
+			) {
+				dwFlags |= MCI_TO;
+				a[0]=a[1]=a[2]=a[3]=0;
+				j=sscanf(keywords[i+1],parsestr,&a[0],&a[1],&a[2],&a[3]);
+				/* add up all integers we got, if we have more 
+				 * shift them. (Well I should use the macros in 
+				 * mmsystem.h, right).
+				 */
+				playParams.dwTo=0;
+				for (k=0;k<j;k++)
+					playParams.dwTo+=a[k]<<(8*(nrargs-k));
+				i+=2;
+				continue;
+			}
+			if (	!strcmp(keywords[i],"FROM") &&
+				(i+1<nrofkeywords)
+			) {
+				dwFlags |= MCI_FROM;
+				a[0]=a[1]=a[2]=a[3]=0;
+				j=sscanf(keywords[i+1],parsestr,&a[0],&a[1],&a[2],&a[3]);
+				/* dito. */
+				playParams.dwFrom=0;
+				for (k=0;k<j;k++)
+					playParams.dwFrom+=a[k]<<(8*(nrargs-k));
+				i+=2;
+				continue;
+			}
+			i++;
+		}
+		_MCI_CALL_DRIVER(MCI_PLAY,playParams);
+		free(keywords);free(cmd);
+		return res;
+	}
+	if (!strcmp(cmd,"STOP")) {
+		MCI_GENERIC_PARMS	genParams;
+		genParams.dwCallback=0;
+		_MCI_CALL_DRIVER(MCI_STOP,genParams);
+		free(keywords);free(cmd);
+		return res;
+	}
+	if (!strcmp(cmd,"SEEK")) {
+		int	nrargs,j,k,a[4];
+		char	*parsestr;
+		MCI_STATUS_PARMS	statusParams;
+		MCI_SEEK_PARMS	seekParams;
+
+		statusParams.dwCallback=0;
+		statusParams.dwItem=MCI_STATUS_TIME_FORMAT;
+		dwFlags |= MCI_STATUS_ITEM;
+		_MCI_CALL_DRIVER(MCI_STATUS,statusParams);
+		dwFlags &= ~MCI_STATUS_ITEM;
+		timef=statusParams.dwReturn;
+		switch (timef) {
+		case MCI_FORMAT_MILLISECONDS:
+		case MCI_FORMAT_FRAMES:
+		case MCI_FORMAT_BYTES:
+		case MCI_FORMAT_SAMPLES:
+			nrargs=1;
+			parsestr="%d";
+			break;
+		case MCI_FORMAT_HMS:
+		case MCI_FORMAT_MSF:
+			parsestr="%d:%d:%d";
+			nrargs=3;
+			break;
+		case MCI_FORMAT_TMSF:
+			parsestr="%d:%d:%d:%d";
+			nrargs=4;
+			break;
+		default:fprintf(stdnimp,"mciSendString:SEEK:unknown timeformat %d, please report.\n",timef);
+			parsestr="%d";
+			nrargs=1;
+			break;
+		}
+		seekParams.dwCallback=0;
+		i=0;
+		while (i<nrofkeywords) {
+			if (	!strcmp(keywords[i],"TO") &&
+				(i+1<nrofkeywords)
+			) {
+				if (!strcmp(keywords[i+1],"START")) {
+					dwFlags=MCI_SEEK_TO_START;
+					seekParams.dwTo=0;
+					i+=2;
+					continue;
+				}
+				if (!strcmp(keywords[i+1],"END")) {
+					dwFlags=MCI_SEEK_TO_END;
+					seekParams.dwTo=0;
+					i+=2;
+					continue;
+				}
+				dwFlags=MCI_TO;
+				i+=2;
+				a[0]=a[1]=a[2]=a[3]=0;
+				j=sscanf(keywords[i+1],parsestr,&a[0],&a[1],&a[2],&a[3]);
+				seekParams.dwTo=0;
+				for (k=0;k<j;k++)
+					seekParams.dwTo+=a[k]<<(8*(nrargs-k));
+				continue;
+			}
+			i++;
+		}
+		_MCI_CALL_DRIVER(MCI_SEEK,seekParams);
+		free(keywords);free(cmd);
+		return res;
+	}
+	if (!strcmp(cmd,"CLOSE")) {
+		MCI_GENERIC_PARMS	closeParams;
+
+		closeParams.dwCallback=0;
+		_MCI_CALL_DRIVER(MCI_CLOSE,closeParams);
+		free(keywords);free(cmd);
+		return res;
+	}
+	if (!strcmp(cmd,"INFO")) {
+		MCI_INFO_PARMS	infoParams;
+
+		dwFlags=-1;
+		while (i<nrofkeywords) {
+			if (!strcmp(keywords[i],"PRODUCT")) {
+				dwFlags=MCI_INFO_PRODUCT;
+				i++;
+				continue;
+			}
+			if (!strcmp(keywords[i],"FILE")) {
+				dwFlags=MCI_INFO_FILE;
+				i++;
+				continue;
+			}
+			i++;
+		}
+		if (dwFlags==-1) {
+			free(keywords);free(cmd);
+			return MCIERR_MISSING_STRING_ARGUMENT;
+		}
+		_MCI_CALL_DRIVER(MCI_INFO,infoParams);
+		if (res==0) {
+			_MCI_STR(infoParams.lpstrReturn);
+		}
+		free(cmd);free(keywords);
+		return res;
+	}
+	fprintf(stdnimp, "mciSendString('%s', %p, %u, %X) // unimplemented, please report.\n", lpstrCommand, 
+		lpstrReturnString, uReturnLength, hwndCallback
+	);
+	free(keywords);free(cmd);
 	return MCIERR_MISSING_COMMAND_STRING;
 }
 
diff --git a/objects/Makefile.in b/objects/Makefile.in
index 4196d0a..659c7ce 100644
--- a/objects/Makefile.in
+++ b/objects/Makefile.in
@@ -26,26 +26,14 @@
 depend:
 	sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
 	$(CC) $(DIVINCL) $(XINCL) -MM *.c >> tmp_make
-	cp tmp_make Makefile
-	rm tmp_make
+	mv tmp_make Makefile
 
 clean:
 	rm -f *.o \#*\# *~ tmp_make
 
 distclean: clean
-	rm Makefile
+	rm -f Makefile
 
 countryclean:
 
-NAMES = $(SRCS:.c=)
-
-winelibclean:
-	for i in $(NAMES); do \
-	if test `grep -c WINELIB $$i.c` -ne 0; then \
-	rm $$i.o; \
-	fi; \
-	done
- 
-dummy:
-
 ### Dependencies:
diff --git a/objects/dib.c b/objects/dib.c
index c2538b4..a023280 100644
--- a/objects/dib.c
+++ b/objects/dib.c
@@ -347,6 +347,7 @@
 			   * fail.			[JAY]
 			   */
 			  line=0; /* Cause exit from do loop. */
+			  break;
 		      }
 		      
 		    case RleDelta: /* =2, a delta */
@@ -666,6 +667,7 @@
 	XDestroyImage( dibImage );
 	XDestroyImage( bmpImage );
     }
+    info->bmiHeader.biCompression = 0;
     return lines;
 }
 
diff --git a/rc/Makefile.in b/rc/Makefile.in
index b276281..92bc5f8 100644
--- a/rc/Makefile.in
+++ b/rc/Makefile.in
@@ -9,10 +9,7 @@
 
 all: rc.o
 
-y.tab.c: parser.y
-	$(BISON) -d -t parser.y
-
-y.tab.h: parser.y
+y.tab.c y.tab.h: parser.y
 	$(BISON) -d -t parser.y
 
 lex.yy.c: parser.l parser.h y.tab.h
@@ -26,11 +23,7 @@
 	echo WINDOWS_H_ENDS_HERE >>sysres.rct
 	cat sysres.rc >>sysres.rct
 
-sysres.c: sysres.rct winerc
-	$(COMPILE) -E -x c -P sysres.rct > sysres.tmp
-	cat sysres.tmp | sed -e '1,/^WINDOWS_H_ENDS_HERE/d' | ./winerc -o sysres -v -p sysres
-
-sysres.h: sysres.rct winerc
+sysres.c sysres.h: sysres.rct winerc
 	$(COMPILE) -E -x c -P sysres.rct > sysres.tmp
 	cat sysres.tmp | sed -e '1,/^WINDOWS_H_ENDS_HERE/d' | ./winerc -o sysres -v -p sysres
 
@@ -45,12 +38,10 @@
 	y.tab.h sysres.c sysres.h tmp_make
 
 distclean: clean
-	rm Makefile
+	rm -f Makefile
 
 countryclean:
 
-winelibclean: clean
-
 depend: sysres.h
 
 y.tab.o: y.tab.c
diff --git a/tools/Makefile.in b/tools/Makefile.in
index e5b6a7b..8935970 100644
--- a/tools/Makefile.in
+++ b/tools/Makefile.in
@@ -16,8 +16,7 @@
 depend:
 	sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
 	$(CC) $(DIVINCL) $(XINCL) -MM *.c >> tmp_make
-	cp tmp_make Makefile
-	rm tmp_make
+	mv tmp_make Makefile
 
 clean:
 	rm -f *.o \#*\# *~ build tmp_make
@@ -27,15 +26,6 @@
 
 countryclean:
 
-NAMES = $(SRCS:.c=)
-
-winelibclean:
-	for i in $(NAMES); do \
-	if test `grep -c WINELIB $$i.c` -ne 0; then \
-	rm $$i.o; \
-	fi; \
-	done
- 
 dummy:
 
 ### Dependencies:
diff --git a/windows/Makefile.in b/windows/Makefile.in
index 3b0d318..bc1ed67 100644
--- a/windows/Makefile.in
+++ b/windows/Makefile.in
@@ -29,8 +29,7 @@
 depend:
 	sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
 	$(CC) $(DIVINCL) $(XINCL) -MM *.c >> tmp_make
-	cp tmp_make Makefile
-	rm tmp_make
+	mv tmp_make Makefile
 
 clean:
 	rm -f *.o \#*\# *~ tmp_make
@@ -40,15 +39,6 @@
 
 countryclean:
 
-NAMES = $(SRCS:.c=)
-
-winelibclean:
-	for i in $(NAMES); do \
-	if test `grep -c WINELIB $$i.c` -ne 0; then \
-	rm $$i.o; \
-	fi; \
-	done
- 
 dummy:
 
 ### Dependencies:
diff --git a/windows/class.c b/windows/class.c
index 4c60a79..09071bd 100644
--- a/windows/class.c
+++ b/windows/class.c
@@ -12,6 +12,7 @@
 #include "win.h"
 #include "dce.h"
 #include "atom.h"
+#include "ldt.h"
 #include "toolhelp.h"
 #include "stddebug.h"
 /* #define DEBUG_CLASS */
@@ -27,7 +28,7 @@
  * Return a handle and a pointer to the class.
  * 'ptr' can be NULL if the pointer is not needed.
  */
-HCLASS CLASS_FindClassByName( char * name, WORD hinstance, CLASS **ptr )
+HCLASS CLASS_FindClassByName( SEGPTR name, WORD hinstance, CLASS **ptr )
 {
     ATOM atom;
     HCLASS class;
@@ -90,17 +91,21 @@
     CLASS * newClass, * prevClassPtr;
     HCLASS handle, prevClass;
     int classExtra;
-    char *name = PTR_SEG_TO_LIN( class->lpszClassName );
 
-    dprintf_class(stddeb, "RegisterClass: wndproc=%08lx hinst=%04x name='%s' background %04x\n",
-	    (DWORD)class->lpfnWndProc, class->hInstance, name, class->hbrBackground );
-    dprintf_class(stddeb, "               style %04x\n",class->style);
+    dprintf_class( stddeb, "RegisterClass: wndproc=%08lx hinst=%04x name='%s' background %04x\n",
+                 (DWORD)class->lpfnWndProc, class->hInstance,
+                 HIWORD(class->lpszClassName) ?
+                  (char *)PTR_SEG_TO_LIN(class->lpszClassName) : "(int)",
+                 class->hbrBackground );
+    dprintf_class(stddeb,"               style=%04x clsExtra=%d winExtra=%d\n",
+                  class->style, class->cbClsExtra, class->cbWndExtra );
     
       /* Window classes are owned by modules, not instances */
     class->hInstance = GetExePtr( class->hInstance );
     
       /* Check if a class with this name already exists */
-    prevClass = CLASS_FindClassByName( name, class->hInstance, &prevClassPtr );
+    prevClass = CLASS_FindClassByName( class->lpszClassName,
+                                       class->hInstance, &prevClassPtr );
     if (prevClass)
     {
 	  /* Class can be created only if it is local and */
@@ -123,8 +128,8 @@
     newClass->wc.cbWndExtra = (class->cbWndExtra < 0) ? 0 : class->cbWndExtra;
     newClass->wc.cbClsExtra = classExtra;
 
-    newClass->atomName = LocalAddAtom( name );
-    newClass->wc.lpszClassName = NULL; 
+    newClass->atomName = LocalAddAtom( class->lpszClassName );
+    newClass->wc.lpszClassName = 0;
 
     if (newClass->wc.style & CS_CLASSDC)
 	newClass->hdce = DCE_AllocDCE( DCE_CLASS_DC );
@@ -132,13 +137,13 @@
 
       /* Make a copy of the menu name (only if it is a string) */
 
-    if ((int)class->lpszMenuName & 0xffff0000)
+    if (HIWORD(class->lpszMenuName))
     {
         char *menuname = PTR_SEG_TO_LIN( class->lpszMenuName );
 	HANDLE hname = USER_HEAP_ALLOC( strlen(menuname)+1 );
 	if (hname)
 	{
-	    newClass->wc.lpszMenuName = (char *)USER_HEAP_SEG_ADDR( hname );
+	    newClass->wc.lpszMenuName = USER_HEAP_SEG_ADDR( hname );
 	    strcpy( USER_HEAP_LIN_ADDR( hname ), menuname );
 	}
     }
@@ -152,7 +157,7 @@
 /***********************************************************************
  *           UnregisterClass    (USER.403)
  */
-BOOL UnregisterClass( LPSTR className, HANDLE hinstance )
+BOOL UnregisterClass( SEGPTR className, HANDLE hinstance )
 {
     HANDLE class, prevClass;
     CLASS * classPtr, * prevClassPtr;
@@ -186,8 +191,8 @@
     if (classPtr->wc.hbrBackground) DeleteObject( classPtr->wc.hbrBackground );
     /*if (classPtr->wc.style & CS_GLOBALCLASS)*/ LocalDeleteAtom( classPtr->atomName );
     /*else DeleteAtom( classPtr->atomName );*/
-    if ((int)classPtr->wc.lpszMenuName & 0xffff0000)
-	USER_HEAP_FREE( (int)classPtr->wc.lpszMenuName & 0xffff );
+    if (HIWORD(classPtr->wc.lpszMenuName))
+	USER_HEAP_FREE( LOWORD(classPtr->wc.lpszMenuName) );
     USER_HEAP_FREE( class );
     return TRUE;
 }
@@ -272,36 +277,17 @@
 /***********************************************************************
  *           GetClassInfo      (USER.404)
  */
-BOOL GetClassInfo(HANDLE hInstance, SEGPTR ClassName, 
-		                    LPWNDCLASS lpWndClass)
+BOOL GetClassInfo( HANDLE hInstance, SEGPTR name, LPWNDCLASS lpWndClass )
 {
     CLASS *classPtr;
-    LPSTR lpClassName = 0;
-    char  temp[10];
-    if (HIWORD(ClassName)) {
-      lpClassName = PTR_SEG_TO_LIN(ClassName);
-    } else  {
-      sprintf(temp,"#%d",(int)LOWORD(ClassName));
-      lpClassName = temp;
-    }
-    dprintf_class(stddeb, "GetClassInfo   hInstance=%04x  lpClassName=%s\n",
-		  hInstance, lpClassName);
 
-    hInstance = GetExePtr(hInstance);
+    dprintf_class( stddeb, "GetClassInfo: hInstance=%04x className=%s\n",
+		   hInstance,
+                   HIWORD(name) ? (char *)PTR_SEG_TO_LIN(name) : "(int)" );
+
+    hInstance = GetExePtr( hInstance );
     
-    /* if (!(CLASS_FindClassByName(lpClassName, &classPtr))) return FALSE; */
-    if (!(CLASS_FindClassByName(lpClassName, hInstance, &classPtr)))
-    {
-/*        if (!HIWORD(lpClassName))
-        {
-            char temp[10];
-            sprintf(temp, "#%d", (int)lpClassName);
-            if (!(CLASS_FindClassByName(temp, hInstance, &classPtr))) return FALSE;
-
-        }
-        else */return FALSE;
-    }
-
+    if (!(CLASS_FindClassByName( name, hInstance, &classPtr))) return FALSE;
     if (hInstance && (hInstance != classPtr->wc.hInstance)) return FALSE;
 
     memcpy(lpWndClass, &(classPtr->wc), sizeof(WNDCLASS));
diff --git a/windows/dialog.c b/windows/dialog.c
index 79116d4..1b28dab 100644
--- a/windows/dialog.c
+++ b/windows/dialog.c
@@ -819,20 +819,6 @@
         if (!(wndPtr->dwStyle & WS_GROUP)) return ctrlPtr->hwndNext;
     }
 
-    if (ctrlPtr->dwStyle & WS_GROUP)  /* Control is the first of the group */
-    {
-        if (!fPrevious) return hwndCtrl;  /* Control is alone in his group */
-        hwnd = ctrlPtr->hwndNext;
-        while(hwnd)  /* Find last control of the group */
-        {
-            wndPtr = WIN_FindWndPtr( hwnd );
-            if (wndPtr->dwStyle & WS_GROUP) break;
-            hwndCtrl = hwnd;
-            hwnd = wndPtr->hwndNext;
-        }
-        return hwndCtrl;
-    }
-    
       /* Now we will have to find the start of the group */
 
     hwndStart = hwnd = dlgPtr->hwndChild;
@@ -840,22 +826,26 @@
     {
 	wndPtr = WIN_FindWndPtr( hwnd );
         if (wndPtr->dwStyle & WS_GROUP) hwndStart = hwnd;  /*Start of a group*/
-        if (hwnd == hwndCtrl)
-        {
-            /* We found the control -> hwndStart is the first of the group */
-            if (!fPrevious) return hwndStart;
-
-            while(hwndStart)  /* Find the control placed before hwndCtrl */
-            {
-                wndPtr = WIN_FindWndPtr( hwndStart );
-                if (wndPtr->hwndNext == hwndCtrl) return hwndStart;
-                hwndStart = wndPtr->hwndNext;
-            }
-            break;
-        }
+	if (hwnd == hwndCtrl) break;
 	hwnd = wndPtr->hwndNext;
     }
-    return hwndCtrl;  /* Not found -> return original control */
+
+    if (!hwnd) fprintf(stderr, "GetNextDlgGroupItem: hwnd not in dialog!\n");
+
+      /* only case left for forward search: wraparound */
+    if (!fPrevious) return hwndStart;
+    
+    hwnd = hwndStart;
+    wndPtr = WIN_FindWndPtr( hwnd );
+    hwnd = wndPtr->hwndNext;
+    while (hwnd && (hwnd != hwndCtrl))
+    {
+	wndPtr = WIN_FindWndPtr( hwnd );
+	if (wndPtr->dwStyle & WS_GROUP) break;
+	hwndStart = hwnd;
+	hwnd = wndPtr->hwndNext;
+    }
+    return hwndStart;
 }
 
 
diff --git a/windows/event.c b/windows/event.c
index 9803e0a..837d284 100644
--- a/windows/event.c
+++ b/windows/event.c
@@ -539,6 +539,7 @@
                      GrabModeAsync, GrabModeAsync,
                      None, None, CurrentTime ) == GrabSuccess)
     {
+	dprintf_win(stddeb, "SetCapture: %04x\n", hwnd);
 	captureWnd   = hwnd;
 	return old_capture_wnd;
     }
@@ -554,6 +555,7 @@
     if (captureWnd == 0) return;
     XUngrabPointer( display, CurrentTime );
     captureWnd = 0;
+    dprintf_win(stddeb, "ReleaseCapture\n");
 }
 
 /**********************************************************************
diff --git a/windows/message.c b/windows/message.c
index 957f611..0457e36 100644
--- a/windows/message.c
+++ b/windows/message.c
@@ -236,6 +236,11 @@
 	else hwnd = wndPtr->hwndNext;
     }
 
+    /* Make point relative to parent again */
+
+    wndPtr = WIN_FindWndPtr( *phwnd );
+    x += wndPtr->rectClient.left;
+    y += wndPtr->rectClient.top;
 
     /* Send the WM_NCHITTEST message */
 
@@ -249,18 +254,18 @@
         hwnd = wndPtr->hwndNext;
         while (hwnd)
         {
-            wndPtr = WIN_FindWndPtr( hwnd );
-            if ((wndPtr->dwStyle & WS_VISIBLE) &&
-                (x >= wndPtr->rectWindow.left) &&
-                (x < wndPtr->rectWindow.right) &&
-                (y >= wndPtr->rectWindow.top) &&
-                (y < wndPtr->rectWindow.bottom)) break;
-            hwnd = wndPtr->hwndNext;
+            WND *nextPtr = WIN_FindWndPtr( hwnd );
+            if ((nextPtr->dwStyle & WS_VISIBLE) &&
+                (x >= nextPtr->rectWindow.left) &&
+                (x < nextPtr->rectWindow.right) &&
+                (y >= nextPtr->rectWindow.top) &&
+                (y < nextPtr->rectWindow.bottom)) break;
+            hwnd = nextPtr->hwndNext;
         }
         if (hwnd) *phwnd = hwnd; /* Found a suitable sibling */
         else  /* Go back to the parent */
         {
-            *phwnd = WIN_FindWndPtr( *phwnd )->hwndParent;
+            if (!(*phwnd = wndPtr->hwndParent)) break;
             wndPtr = WIN_FindWndPtr( *phwnd );
             x += wndPtr->rectClient.left;
             y += wndPtr->rectClient.top;
@@ -1189,12 +1194,10 @@
 /***********************************************************************
  *           RegisterWindowMessage   (USER.118)
  */
-WORD RegisterWindowMessage( LPCSTR str )
+WORD RegisterWindowMessage( SEGPTR str )
 {
-	WORD	wRet;
-    dprintf_msg(stddeb, "RegisterWindowMessage: '%s'\n", str );
-	wRet = LocalAddAtom( str );
-    return wRet;
+    dprintf_msg(stddeb, "RegisterWindowMessage: '%08lx'\n", str );
+    return LocalAddAtom( str );
 }
 
 
diff --git a/windows/win.c b/windows/win.c
index de84af9..054df8c 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -224,7 +224,7 @@
     CLASS *classPtr;
     HDC hdc;
 
-    if (!(hclass = CLASS_FindClassByName( DESKTOP_CLASS_NAME, 0, &classPtr )))
+    if (!(hclass = CLASS_FindClassByName( DESKTOP_CLASS_ATOM, 0, &classPtr )))
 	return FALSE;
 
     hwndDesktop = USER_HEAP_ALLOC( sizeof(WND)+classPtr->wc.cbWndExtra );
@@ -302,17 +302,23 @@
     int wmcreate;
     XSetWindowAttributes win_attr;
 
-    if (windowName != NULL && HIWORD(windowName) == 0) {
-	dprintf_win(stddeb,"CreateWindowEx: %04x ", LOWORD(windowName));
-    } else {
-	dprintf_win(stddeb,"CreateWindowEx: '%s' ", windowName);
-    }
-    dprintf_win(stddeb, "%08lX '%s' %08lX %d,%d %dx%d %04X %04X %04X %08lx\n",
-		exStyle, className, style, x, y, width, height,
+    /* FIXME: windowName and className should be SEGPTRs */
+
+    if (HIWORD(windowName))
+	dprintf_win( stddeb, "CreateWindowEx: '%s' ", windowName );
+    else
+	dprintf_win( stddeb, "CreateWindowEx: %04x ", LOWORD(windowName) );
+    if (HIWORD(className))
+        dprintf_win( stddeb, "'%s' ", className );
+    else
+        dprintf_win( stddeb, "%04x ", LOWORD(className) );
+
+    dprintf_win(stddeb, "%08lx %08lx %d,%d %dx%d %04x %04x %04x %08lx\n",
+		exStyle, style, x, y, width, height,
 		parent, menu, instance, data);
     /* 'soundrec.exe' has negative position ! 
        Why ? For now, here a patch : */
-    if (!strcmp(className, "SoundRec"))
+    if (HIWORD(className) && !strcmp(className, "SoundRec"))
     {
 	if (x < 0) x = 0;
 	if (y < 0) y = 0;
@@ -330,7 +336,7 @@
     {
 	/* Make sure parent is valid */
         if (!IsWindow( parent )) {
-	    dprintf_win(stddeb,"CreateWindowEx: Parent %x is not a windows\n", parent);
+	    dprintf_win(stddeb,"CreateWindowEx: Parent %x is not a window\n", parent);
 	    return 0;
 	}
     }
@@ -342,9 +348,15 @@
 	}
     }
 
-    if (!(class = CLASS_FindClassByName( className, GetExePtr( instance ), &classPtr ))) {
-	fprintf(stderr,"CreateWindow BAD CLASSNAME '%s' !\n", className);
-	return 0;
+    {
+        /* FIXME!! */
+        char buff[256];
+        if (HIWORD(className)) strcpy( buff, className );
+        if (!(class = CLASS_FindClassByName( HIWORD(className) ? MAKE_SEGPTR(buff) : (SEGPTR)className,
+                                         GetExePtr( instance ), &classPtr ))) {
+            fprintf(stderr,"CreateWindow BAD CLASSNAME '%s' !\n", className);
+            return 0;
+        }
     }
 
       /* Correct the window style */
@@ -457,14 +469,12 @@
     {
         if (menu) SetMenu(hwnd, menu);
         else if (classPtr->wc.lpszMenuName)
-            SetMenu(hwnd,LoadMenu(instance,(SEGPTR)classPtr->wc.lpszMenuName));
+            SetMenu( hwnd, LoadMenu( instance, classPtr->wc.lpszMenuName ) );
     }
     else wndPtr->wIDmenu = menu;
 
       /* Send the WM_CREATE message */
 
-    hclassName = USER_HEAP_ALLOC( strlen(className)+1 );
-    strcpy( USER_HEAP_LIN_ADDR(hclassName), className );
     createStruct.lpCreateParams = (LPSTR)data;
     createStruct.hInstance      = instance;
     createStruct.hMenu          = menu;
@@ -474,24 +484,29 @@
     createStruct.x              = x;
     createStruct.y              = y;
     createStruct.style          = style;
-    createStruct.lpszClass      = (LPSTR)USER_HEAP_SEG_ADDR(hclassName);
     createStruct.dwExStyle      = 0;
-    if (windowName)
+    if (HIWORD(className))
     {
-	if (HIWORD(windowName) == 0) {
-	    /* Hack for SS_ICON controls */
-	    createStruct.lpszName = windowName;
-	    hwinName = 0;
-	} else  {
-	    hwinName = USER_HEAP_ALLOC( strlen(windowName)+1 );
-	    strcpy( USER_HEAP_LIN_ADDR(hwinName), windowName );
-	    createStruct.lpszName = (LPSTR)USER_HEAP_SEG_ADDR(hwinName);
-	}
+        hclassName = USER_HEAP_ALLOC( strlen(className)+1 );
+        strcpy( USER_HEAP_LIN_ADDR(hclassName), className );
+        createStruct.lpszClass = (LPSTR)USER_HEAP_SEG_ADDR(hclassName);
+    }
+    else
+    {
+        hclassName = 0;
+        createStruct.lpszClass = className;
+    }
+
+    if (HIWORD(windowName))
+    {
+        hwinName = USER_HEAP_ALLOC( strlen(windowName)+1 );
+        strcpy( USER_HEAP_LIN_ADDR(hwinName), windowName );
+        createStruct.lpszName = (LPSTR)USER_HEAP_SEG_ADDR(hwinName);
     }
     else
     {
         hwinName = 0;
-        createStruct.lpszName = NULL;
+        createStruct.lpszName = windowName;
     }
 
     wmcreate = SendMessage( hwnd, WM_NCCREATE, 0, MAKE_SEGPTR(&createStruct) );
@@ -506,7 +521,7 @@
 	wmcreate = SendMessage(hwnd, WM_CREATE, 0, MAKE_SEGPTR(&createStruct));
     }
 
-    USER_HEAP_FREE( hclassName );
+    if (hclassName) USER_HEAP_FREE( hclassName );
     if (hwinName) USER_HEAP_FREE( hwinName );
 
     if (wmcreate == -1)
@@ -609,7 +624,7 @@
 /***********************************************************************
  *           FindWindow   (USER.50)
  */
-HWND FindWindow(LPSTR ClassMatch, LPSTR TitleMatch)
+HWND FindWindow( SEGPTR ClassMatch, LPSTR TitleMatch )
 {
     HCLASS hclass;
     CLASS *classPtr;