Release 980913

Fri Sep 11 13:14:35 1998  Andreas Mohr <100.30936@germany.net>

	* [files/file.c] [include/file.h]
	Fixed SetFilePointer to allow negative positions as in DOS.

	* [graphics/ddraw.c]
	Added some methods to IDirect3D.

	* [ole/compobj.c] [if1632/compobj.spec]
	Added/implemented CoCreateStandardMalloc16,
	CoGetClassObject, CoCreateInstance,
	LookupETask, SetETask, CoGetState16.

	* [loader/task.c]
	MakeProcInstance: return 0 if func == NULL.

	* [*/*] [tools/winapi-check]
	Added zillions of missing WINAPI's and __cdecl's.
	(oops, several caused by myself)
	Wrote script for automated checking.

	* [if1632/compobj.spec]
	Many stub names.

	* [misc/ddeml.c] [ole/compobj.c]
	Some stubs.

Tue Sep  9 21:36:48 1998  Anders Carlsson <anders.carlsson@linux.nu>

	* [dlls/comctl32/Makefile.in] [dlls/comctl32/commctrl.c]
	  [dlls/comctl32/tab.c] [include/commctrl.h] [include/tab.h]
        Added preliminary tab control support.

Sat Sep  5 16:27:20 1998  Huw D M Davies <daviesh@abacus.physics.ox.ac.uk>

	* [graphics/psdrv/*]
	More changes to the PostScript driver:
	Implemented pens and solid brushes.
	Colour/greyscale for fonts, pens and brushes.
	To get coloured output you need to have *ColorDevice set to true
	in your PPD, otherwise you'll get greyscale.
	Landscape mode now works, as does non-A4 page sizes.
	Encoding of fonts to ANSI is better, Symbol works again.

	* [objects/dc.c] [include/gdi.h] [*/*]
	Moved dc->w.{text,background}Pixel to X11DRV_PDEVICE where they
	belong.

Sat Sep  5 05:12:09 1998  Ove Kaaven <ovek@arcticnet.no>

	* [include/dosexe.h] [include/miscemu.h] [include/msdos.h]
	  [loader/dos/dosvm.c] [loader/dos/module.c] [msdos/dpmi.c]
	  [msdos/int2f.c] [msdos/interrupts.c]
	Fixed portability. Adapted some code to make it easier to
	integrate the DOS subsystem with the DPMI subsystem, made
	the DPMI simulated real-mode interrupts be handled the V86
	way. Added support for .COM files. Made int2f DPMI check
	fail, to avoid pkunzip crashing in attempting to use DPMI.
	Generally moved stuff around a little.
	It is now technically possible to load several DOS programs
	into the same memory space. Not tested, though.

Fri Sep  4 21:40:45 1998  Marcus Meissner <marcus@jet.franken.de>

	* [if1632/kernel.spec]
	Changed 500-53x stubnames accordingly to nt3.51 krnl386.exe.

	* [win32/except.c]
	Fixed one bad program behaviour, (deleting SEH while in 
	first walk). RtlUnwind is broken too I think (it should unwind
	on success, not while walking the exception chain).

	* [ole/ole2nls.c]
	Get*DefaultLCID  returns 0x400|id. expected by one application.

	* [if1632/snoop.c]
	Handle non-standard SP returns more graceful.

	* [windows/class.c]
	hinstances are mostly irrelevant for win32.

	* [memory/string.c] [misc/registry.c]
	lstrcmpi32W: use toupper for characters < 0x100. (speedup hack
	for registry.c)
	Some small speedup hacks for registry.c

Thu Sep  3 20:40:16 1998  Eric Kohl <ekohl@abo.rhein-zeitung.de>

	* [Makefile.in][configure][configure.in][dlls/Makefile.in]
	  [dlls/comctl32/Makefile.in]
	Created dlls/comctl32 and moved the common controls stuff to it.

	* [misc/version.c]
	Removed COMCTL32_DllGetVersion. The fixed function is part
	of the common controls stuff.

	* [dlls/comctl32/*.c][include/commctrl.h]
	Added structure size tests.

	* [dlls/comctl32/toolbar.c]
	Fixed a bug in TOOLBAR_GetMaxWidth().

	* [dlls/comctl32/animate.c][include/animate.h]
	  [dlls/comctl32/comboex.c][include/comboex.h]
	  [dlls/comctl32/hotkey.c][include/hotkey.h]
	  [dlls/comctl32/listview.c][include/listview.h]
	  [dlls/comctl32/commctrl.c][include/commctrl.h]
	New files. Added Animation, ComboBoxEx, Hotkey and
	Listview control dummies.

	* [dlls/comctl32/tooltips.c]
	Fixed a display bug and font selection.

	* [dlls/comctl32/comctl32undoc.c][include/commctrl.h]
	Added missing DPA functions. Fixed bugs and published the
	function prototypes.

	* [documentation/common_controls]
	Updated.

Wed Sep  2 15:43:45 1998  Patrik Stridvall <ps@leissner.se>

	* [AUTHORS] [include/authors.h]
	Added myself as a Wine author.

	* [memory/virtual.c] [objects/dc.c]
	Fixed runtime errors for Solaris.

	* [misc/ddeml.c] [objects/gdiobj.c]
	Minor fixes.

	* [win32/device.c]
	Added stubs for IFSMgr VxDCall and
	a partial implementation of IFSMgr DeviceIo.

	* [relay32/Makefile.in] [relay32/builtin32.c] [relay32/imm32.spec] 
	  [relay32/msnet32.spec] [relay32/oledlg.spec]
	Added new spec files for IMM32.DLL, MSNET32.DLL, OLEDLG.DLL.

	* [misc/Makefile.in] [misc/imm.c] [include/imm.h]
	Added news files for implementation of IMM32.DLL. 
	All functions return 0 as is correct for all Western Languages.

	* [ole/Makefile.in] [ole/oledlg.c] [include/oledlg.h]
	Added new files for implementation of OLEDLG.DLL.
	Added stubs with FIXME:s for all functions.

Wed Sep  2 10:50:00 1998  Juergen Schmied <juergen.schmied@metronet.de>

	* [dlls/shell32/contmenu.c][dlls/shell32/shellole.c]
	  [dlls/shell32/shlfolder.c][dlls/shell32/shlview.c]
	  [documentation/shell32][include/shell.h]
	Clean up, bugfixes.
	
	* [dlls/shell32/enumidlist.c]
	Fileattributes implemented.
	
	* [dlls/shell32/pidl.c]
	Class pidlmgr splited into functions, structures changed, 
	some functions rewritten.

	* [dlls/shell32/shell32_main.c]
	Small changes and bugfixes SHGetFileInfoA, SHGetSpecialFolderLocation.
	
	* [dlls/shell32/shellord.c][relay32/shell32.spec]
	Parameter documented, implemented SHCloneSpecialIDList.
	Stub improved ShellExecuteEx32A.
	New stubs SHFind_InitMenuPopup, FileMenu_InitMenuPopup, 
	FileMenu_Create, FileMenu_TrackPopupMenuEx, SHWinHelp,
	SHRunConrolPanel, DAD_ShowDragImage, FileMenu_Destroy,
	SHGetDataFromIDListA, SHFileOperationA.
	
	* [include/winnls.h][include/ole2nls.c]
	TIME_FORCE24HOURFORMAT, TIME_NOTIMEMARKER implemented
	in OLE_GetFormatA, GetTimeFormat32A.
	
	* [win32/code_page.c]
	WideCharToMultiByte: parameter checking and returning of strlen
	implemented.
	
	* [windows/keyboard.c][windows/defwnd.c]
	Debug messages added.
	
	* [windows/win.c]
	WIN_SetWindowLong GWL_STYLE and GWL_EXSTYLE implemented.

	* [controls/menu.c]
	Missing line added.

	* [include/winerror.h]
	Macros for SUCCEEDED and FAILED added.

Mon Aug 31 00:55:31 1998  Ulrich Weigand <weigand@informatik.uni-erlangen.de>

	* [loader/module.c]
	Bugfix: LoadModule16 should *not* call LoadModule32.

	* [files/dos_fs.c]
	Bugfix: don't crash if given directory doesn't exist.

Sat Aug 29 15:00:49 1998  Turchanov Sergey <turchanov@usa.net>

	* [include/mmsystem.h][multimedia/mmsystem.c][relay32/winmm.spec]
	Almost completed implementation of [snd]PlaySound (except
	flags SND_ALIAS_ID and SND_APPLICATION).

	* [if1632/user.spec][windows/winpos.c]
	Added SetWindowRgn16 stub.

Sat Aug 29 02:53:31 1998  Alexander Lukyanov <lav@long.yar.ru>

	* [files/drive.c]
	GetDriveType32A: return DRIVE_DOESNOTEXIST in case of non
	existent drive.

	* [msdos/int21.c]
	INT21_FindFirstFCB: check drive validity to prevent oops.

	* [win32/file.c]
	CreateFile32A: duplicate STD_{INPUT,OUTPUT}_HANDLE.

	* [files/dos_fs.c]
	Make DOSFS_OpenDir treat "" as "/".
	DOSFS_OpenDevice: duplicate STD_{INPUT,OUTPUT}_HANDLE.

	* [windows/dialog.c]
	GetNextDlgTabItem32: use last/first item instead of first/last
	when hwndCtrl==0. This fixes initial focus.

Sat Aug 29 02:46:32 1998  Adrian Harvey <adrian@select.com.au>

	* [include/process.h] [include/process.c]
	Renamed PROCESS_SELF to CURRENT_PROCESS_PSEUDOHANDLE in line
	with thread constant, and Win32 documentation (which calls it
	a pseudohandle.)  Made GetCurrentProcess actually use this
	constant instead of the value.

	* [include/process.h] [include/thread.h] [scheduler/thread.c]
	  [scheduler/process.c] [scheduler/handle.c]
	Modify HANDLE_GetObjPtr to understand about
	CURRENT_THREAD_PSEUDOHANDLE and CURRENT_PROCESS_PSEUDOHANDLE.
	This allows DuplicateHandle to do the correct thing with these
	handles.  Removed now duplicate functionality from THREAD_GetPtr
	and PROCESS_GetPtr.

	* [loader/ne/segment.c]
	Fixed two places where HFILE32s were being created and passed to
	16-bit code. This should unbreak NE self-loading code.
	Added two casts to remove compile time warnings.

Fri Aug 28 21:04:13 1998  Joseph Pranevich <knight@baltimore.wwaves.com>

	* [msdos/dosmem.c] [msdos/int2f.c]
	Added beginnings of DOS error table.

	* [msdos/int1a.c]
	Stub for subfunction 0xb0.

	* [msdos/int10.c] [loader/dos/dosvm.c]
	INT 10 support completely rewritten and lots of debugging
	added. Now, DOS apps that use INT 10 to write to the screen will
	work. (Beyond Zork does, at least. Somewhat.)

	* [include/miscemu.h] [msdos/dosmem.c] [msdos/int21.c]
	Another shot at getting MS's generic error message facility
	right.

	* [msdos/int21.c]
	Command.Com wanted to set its own PSP address. I let it.

Wed Aug 26 12:26:20 1998  Matthew Toseland <Matthew.Toseland@btinternet.com>

	* [include/file.h] [misc/lzexpand.c]
	Fixed LZCopy16 by fixing HFILE16/HFILE32 convertor macros so don't
	convert lzw handles.

Tue Aug 25 22:22:55 1998  Uwe Bonnes <bon@elektron.ikp.physik.tu-darmstadt.de>

	* [misc/registry.c]
	In RegEnumvalue, ivalue == 0 is a legal request and should
	return the first entry.

	* [msdos/int21.c]
	Add handling for Int21-48/49 in Win16. Makes blinker demo work.

	* [windows/winproc.c]
	Add Msg32A<->Msg32W translation for LB_ADDSTRING.

Tue Aug 25 21:03:31 1998  Kristian Nielsen  <kristian.nielsen@risoe.dk>

	* [windows/win.c]
	Fix for SetParent(): MS Windows 3.11 does not clear the WS_CHILD
	flag when a child window is reparented to the desktop window.

Mon Aug 24 20:55:22 1998  Berend Reitsma <berend at asset-control dot com>

	* [controls/menu.c]
	Menus created with SetMenuItemInfo and InsertMenuItem should
	work now.

Sun Aug 23 23:23:23 1998  Alex Korobka <korobka@ams.sunysb.edu>

	* [controls/combo.c]
	Added CB_GETITEMHEIGHT.

	* [windows/winpos.c] 
	WM_NCHITTEST, SWP_FRAMECHANGED bugfixes.

Sat Aug 22 21:15:29 1998 Alex Priem <alexp@sci.kun.nl>

	* [files/profile.c] [include/windows.h]
	Added GetPrivateProfileSectionNames[AW],GetPrivateProfileSectionW,
	GetPrivateProfileStructW, GetProfileSectionW,
	WriteProfileSection[AW], WritePrivateProfileStructW. 
diff --git a/msdos/dosmem.c b/msdos/dosmem.c
index 1affb0a..85ee94d 100644
--- a/msdos/dosmem.c
+++ b/msdos/dosmem.c
@@ -79,6 +79,9 @@
 
        DWORD 	 DOSMEM_CollateTable;
 
+       DWORD	 DOSMEM_ErrorCall;
+       DWORD	 DOSMEM_ErrorBuffer;
+
 /* use 2 low bits of 'size' for the housekeeping */
 
 #define DM_BLOCK_DEBUG		0xABE00000
@@ -186,6 +189,60 @@
 }
 
 /***********************************************************************
+ *           DOSMEM_InitErrorTable
+ *
+ * Initialises the error tables (DOS 5+)
+ */
+static void DOSMEM_InitErrorTable()
+{
+	DWORD		x;
+	char 		*call;
+
+        /* We will use a snippet of real mode code that calls */
+        /* a WINE-only interrupt to handle moving the requested */
+        /* message into the buffer... */
+
+        /* FIXME - There is still something wrong... */
+
+        /* FIXME - Find hex values for opcodes...
+           
+           (On call, AX contains message number
+                     DI contains 'offset' (??)
+            Resturn, ES:DI points to counted string )
+
+           PUSH BX
+           MOV BX, AX
+           MOV AX, (arbitrary subfunction number)
+           INT (WINE-only interrupt)
+           POP BX
+           RET
+
+        */
+           
+        const int	code = 4;	
+        const int	buffer = 80; 
+        const int 	SIZE_TO_ALLOCATE = code + buffer;
+
+        /* FIXME - Complete rewrite of the table system to save */
+        /* precious DOS space. Now, we return the 0001:???? as */
+        /* DOS 4+ (??, it seems to be the case in MS 7.10) treats that */
+        /* as a special case and programs will use the alternate */
+        /* interface (a farcall returned with INT 24 (AX = 0x122e, DL = */
+        /* 0x08) which lets us have a smaller memory footprint anyway. */
+ 
+ 	x = GlobalDOSAlloc(SIZE_TO_ALLOCATE);  
+
+	DOSMEM_ErrorCall = MAKELONG(0,(x>>16));
+        DOSMEM_ErrorBuffer = DOSMEM_ErrorCall + code;
+
+	call = DOSMEM_MapRealToLinear(DOSMEM_ErrorCall);
+
+        memset(call, 0, SIZE_TO_ALLOCATE);
+
+        /* Fixme - Copy assembly into buffer here */        
+}
+
+/***********************************************************************
  *           DOSMEM_InitMemory
  *
  * Initialises the DOS memory structures.
@@ -245,6 +302,7 @@
         DOSMEM_FillBiosSegment();
         DOSMEM_InitMemory(0);
         DOSMEM_InitCollateTable();
+        DOSMEM_InitErrorTable();
     }
     else
         DOSMEM_InitMemory(hModule);
diff --git a/msdos/dpmi.c b/msdos/dpmi.c
index ebcfca1..48ae756 100644
--- a/msdos/dpmi.c
+++ b/msdos/dpmi.c
@@ -143,7 +143,7 @@
     ESI_reg(context) = call->esi;
     EDI_reg(context) = call->edi;
     EBP_reg(context) = call->ebp;
-    EFL_reg(context) = call->fl;
+    EFL_reg(context) = call->fl | 0x00020000; /* V86 */
     EIP_reg(context) = call->ip;
     ESP_reg(context) = call->sp;
     CS_reg(context)  = call->cs;
@@ -151,6 +151,7 @@
     ES_reg(context)  = call->es;
     FS_reg(context)  = call->fs;
     GS_reg(context)  = call->gs;
+    (char*)V86BASE(context) = DOSMEM_MemoryBase(0);
 }
 
 
@@ -188,160 +189,8 @@
     INT_GetRealModeContext( call, &realmode_ctx );
 
     RESET_CFLAG(context);
-    switch (BL_reg(context))
-    {
-    case 0x2f:	/* int2f */
-        switch (AH_reg(&realmode_ctx))
-        {
-        case 0x15:
-            /* MSCDEX hook */
-            do_mscdex( &realmode_ctx, 1 );
-            break;
-        case 0x7a:
-            /* NOVELL NetWare */
-            switch (AL_reg(&realmode_ctx))
-	    {
-                case 0x20:  /* Get VLM Call Address */
-                    /* return nothing -> NetWare not installed */
-                    break;
-                default:
-                    SET_CFLAG(context);
-                    break;
-            }
-	    break;
-        default:
-            SET_CFLAG(context);
-            break;
-        }
-        break;
-    case 0x21:	/* int21 */
-        switch (AH_reg(&realmode_ctx))
-        {
-        case 0x52:
-            ES_reg(&realmode_ctx) = 0;
-            EBX_reg(&realmode_ctx) = 0;
-            break;
-        case 0x65:
-            switch (AL_reg(&realmode_ctx))
-            {
-            case 0x06:
-                {/* get collate table */
-                    /* ES:DI is a REALMODE pointer to 5 byte dosmem 
-                     * we fill that with 0x6, realmode pointer to collateTB
-                     */
-                    char *table = DOSMEM_MapRealToLinear(
-                       MAKELONG(EDI_reg(&realmode_ctx),ES_reg(&realmode_ctx)));
-                    *(BYTE*)table      = 0x06;
-                    *(DWORD*)(table+1) = DOSMEM_CollateTable;
-                    CX_reg(&realmode_ctx) = 258;/*FIXME: size of table?*/
-                    break;
-                }
-            default:
-                SET_CFLAG(context);
-                break;
-            }
-            break;
-        case 0x44:
-            switch (AL_reg(&realmode_ctx))
-            {
-            case 0x0D:
-                {/* generic block device request */
-                    BYTE *dataptr = DOSMEM_MapRealToLinear(
-                       MAKELONG(EDX_reg(&realmode_ctx),DS_reg(&realmode_ctx)));
-                    int drive = DOS_GET_DRIVE(BL_reg(&realmode_ctx));
-                    if (CH_reg(&realmode_ctx) != 0x08)
-                    {
-                        SET_CFLAG(context);
-                        break;
-                    }
-                    switch (CL_reg(&realmode_ctx))
-                    {
-                    case 0x66:
-                        {
-			    char    label[12],fsname[9],path[4];
-			    DWORD   serial;
-
-			    strcpy(path,"x:\\");path[0]=drive+'A';
-			    GetVolumeInformation32A(path,label,12,&serial,NULL,NULL,fsname,9);
-			    *(WORD*)dataptr         = 0;
-			    memcpy(dataptr+2,&serial,4);
-			    memcpy(dataptr+6,label  ,11);
-			    memcpy(dataptr+17,fsname,8);
-			    break;
-                        }
-                    case 0x60:	/* get device parameters */
-                                /* used by defrag.exe of win95 */
-                        memset(dataptr, 0, 0x26);
-                        dataptr[0] = 0x04;
-                        dataptr[6] = 0; /* media type */
-                        if (drive > 1)
-                        {
-                            dataptr[1] = 0x05; /* fixed disk */
-                            setword(&dataptr[2], 0x01); /* non removable */
-                            setword(&dataptr[4], 0x300); /* # of cylinders */
-                        }
-                        else
-                        {
-                            dataptr[1] = 0x07; /* block dev, floppy */
-                            setword(&dataptr[2], 0x02); /* removable */
-                            setword(&dataptr[4], 80); /* # of cylinders */
-                        }
-                        CreateBPB(drive, &dataptr[7], FALSE);
-                        break;
-                    default:
-                        SET_CFLAG(context);
-                        break;
-                    }
-                }
-                break;
-            default:
-                SET_CFLAG(context);
-                break;
-            }
-            break;
-        case 0x58: /* GET OR SET MEMORY/UMB ALLOCATION STRATEGY */
-            TRACE(int31,"GET OR SET MEMORY/UMB ALLOCATION STRATEGY subfunction %d\n",
-                  AL_reg(context));
-            switch (AL_reg(context))
-            {
-            case 0x00:
-                AX_reg(context) = 1;
-                break;
-            case 0x02:
-                AX_reg(context) = 0;
-                break;
-            case 0x01:
-            case 0x03:
-                break;
-            }
-            RESET_CFLAG(context);
-            break;
-	case 0x60: {/* CANONICALIZE PATH */
-		LPCSTR path = (LPCSTR)DOSMEM_MapRealToLinear((DS_reg(&realmode_ctx)<<16)+SI_reg(&realmode_ctx));
-
-		TRACE(int31,"TRUENAME %s\n",path);
-		if (!GetFullPathName32A( 
-		    path,
-		    128,
-		    (LPSTR)DOSMEM_MapRealToLinear(
-		    (ES_reg(&realmode_ctx)<<16)+DI_reg(&realmode_ctx)),
-		    NULL
-		))
-		    SET_CFLAG(context);
-		else
-		    AX_reg(&realmode_ctx) = 0;
-	    }
-	    break;
-        default:
-            SET_CFLAG(context);
-            break;
-        }
-        break;
-    default:
-        SET_CFLAG(context);
-        break;
-    }
-
+    if (INT_RealModeInterrupt( BL_reg(context), context ))
+      SET_CFLAG(context);
     if (EFL_reg(context)&1) {
       FIXME(int31,"%02x: EAX=%08lx EBX=%08lx ECX=%08lx EDX=%08lx\n",
 	    BL_reg(context), EAX_reg(&realmode_ctx), EBX_reg(&realmode_ctx), 
diff --git a/msdos/int10.c b/msdos/int10.c
index d58c29e..5017e01 100644
--- a/msdos/int10.c
+++ b/msdos/int10.c
@@ -7,33 +7,300 @@
 /* #define DEBUG_INT */
 #include "debug.h"
 
-
 /**********************************************************************
  *	    INT_Int10Handler
  *
  * Handler for int 10h (video).
+ * 
+ * NOTE:
+ *    Most INT 10 functions for text-mode, CGA, EGA, and VGA cards
+ *    are present in this list. (SVGA and XGA are not) That is not
+ *    to say that all these functions should be supported, but if
+ *    anyone is braindamaged enough to want to emulate one of these
+ *    beasts then this should get you started. 
+ *
+ * NOTE:
+ *    Several common graphical extensions used by Microsoft hook
+ *    off of here. I have *not* added them to this list (yet). They
+ *    include:
+ *
+ *    MSHERC.COM - More functionality for Hercules cards.
+ *    EGA.SYS (also MOUSE.COM) - More for EGA cards.
+ *    
+ *    Yes, MS also added this support into their mouse driver. Don't
+ *    ask me, I don't work for them.
+ *
+ * Joseph Pranevich - 9/98 
  */
+
 void WINAPI INT_Int10Handler( CONTEXT *context )
 {
     switch(AH_reg(context))
     {
-    case 0x0f:
-        AL_reg(context) = 0x5b;
+    case 0x00: /* SET VIDEO MODE */
+        /* If the mode is 0x02 or 0x07 then we are still in
+           80x25 text and can ignore the request */
+        if ((AL_reg(context) == 0x02) || (AL_reg(context) == 0x07))
+           break;
+
+        FIXME(int10, "Set Video Mode - Not Supported\n");
         break;
 
-    case 0x12:
-        if (BL_reg(context) == 0x10)
-        {
-            BX_reg(context) = 0x0003;
-            CX_reg(context) = 0x0009;
+    case 0x01: /* SET CURSOR SHAPE */
+        FIXME(int10, "Set Cursor Shape - Not Supported\n");
+        break;
+
+    case 0x02: /* SET CURSOR POSITION */
+        FIXME(int10, "Set Cursor Position - Not Supported\n");
+        break;
+
+    case 0x03: /* GET CURSOR POSITION AND SIZE */
+        FIXME(int10, "Get Cursor Position and Size - Not Supported\n");
+        CX_reg(context) = 0x0000; /* Bogus cursor data */
+        DX_reg(context) = 0x0000;
+        break;
+
+    case 0x04: /* READ LIGHT PEN POSITION */
+        FIXME(int10, "Read Light Pen Position - Not Supported\n");
+        AH_reg(context) = 0x00; /* Not down */
+        break;
+
+    case 0x05: /* SELECT ACTIVE DISPLAY PAGE */
+        FIXME(int10, "Select Active Display Page - Not Supported\n");
+        break;
+
+    case 0x06: /* SCROLL UP WINDOW */
+        FIXME(int10, "Scroll Up Window - Not Supported\n");
+        break;
+
+    case 0x07: /* SCROLL DOWN WINDOW */
+        FIXME(int10, "Scroll Down Window - Not Supported\n");
+        break;
+
+    case 0x08: /* READ CHARACTER AND ATTRIBUTE AT CURSOR POSITION */
+        FIXME(int10, 
+          "Read Character and Attribute at Cursor Position - Not Supported\n");
+        break;
+
+    case 0x09: /* WRITE CHARACTER AND ATTRIBUTE AT CURSOR POSITION */
+    case 0x0a: /* WRITE CHARACTER ONLY AT CURSOR POSITION */ 
+       while (CX_reg(context)) {
+           _lwrite16(1, &AL_reg(context), 1);
+           (CX_reg(context))--;
         }
         break;
-			
-    case 0x1a:
-        BX_reg(context) = 0x0008;
+
+    case 0x0b: 
+        switch BH_reg(context) {
+        case 0x00: /* SET BACKGROUND/BORDER COLOR */
+            FIXME(int10, "Set Background/Border Color - Not Supported\n");
+            break;
+        case 0x01: /* SET PALETTE */
+            FIXME(int10, "Set Palette - Not Supported\n");
+            break;
+        default:
+            FIXME(int10, "INT 10 AH = 0x0b BH = 0x%x - Unknown\n", 
+               BH_reg(context));
+            break;
+        }
+        break;
+
+    case 0x0c: /* WRITE GRAPHICS PIXEL */
+        /* Not in graphics mode, can ignore w/o error */
+        FIXME(int10, "Write Graphics Pixel - Not Supported\n");
+        break;
+        
+    case 0x0d: /* READ GRAPHICS PIXEL */
+        /* Not in graphics mode, can ignore w/o error */
+        FIXME(int10, "Read Graphics Pixel - Not Supported\n");
+        break;
+              
+    case 0x0e: /* TELETYPE OUTPUT */
+        _lwrite16(1, &AL_reg(context), 1);
+        break;
+
+    case 0x0f: /* GET CURRENT VIDEO MODE */
+        AL_reg(context) = 0x5b; /* WHY ARE WE RETURNING THIS? */
+        break;
+
+    case 0x10: 
+        switch AL_reg(context) {
+        case 0x00: /* SET SINGLE PALETTE REGISTER */
+            FIXME(int10, "Set Single Palette Register - Not Supported\n");
+            break;
+        case 0x01: /* SET BORDER (OVERSCAN) */
+            FIXME(int10, "Set Border (Overscan) - Not Supported\n");
+            break;
+        case 0x02: /* SET ALL PALETTE REGISTERS */
+            FIXME(int10, "Set all palette registers - Not Supported\n");
+            break;
+        case 0x03: /* TOGGLE INTENSITY/BLINKING BIT */
+            FIXME(int10, "Toggle Intensity/Blinking Bit - Not Supported\n");
+            break;
+        case 0x07: /* GET INDIVIDUAL PALETTE REGISTER */
+            FIXME(int10, "Get Individual Palette Register - Not Supported\n");
+            break;
+        case 0x08: /* READ OVERSCAN (BORDER COLOR) REGISTER */
+            FIXME(int10, 
+               "Read Overscan (Border Color) Register - Not Supported\n");
+            break;
+        case 0x09: /* READ ALL PALETTE REGISTERS AND OVERSCAN REGISTER */
+            FIXME(int10, 
+               "Read All Palette Registers and Overscan Register "
+               " - Not Supported\n");
+            break;
+        case 0x10: /* SET INDIVIDUAL DAC REGISTER */
+            FIXME(int10, "Set Individual DAC register - Not Supported\n");
+            break;
+        case 0x12: /* SET BLOCK OF DAC REGISTERS */
+            FIXME(int10, "Set Block of DAC registers - Not Supported\n");
+            break;
+        case 0x13: /* SELECT VIDEO DAC COLOR PAGE */
+            FIXME(int10, "Select video DAC color page - Not Supported\n");
+            break;
+        case 0x15: /* READ INDIVIDUAL DAC REGISTER */
+            FIXME(int10, "Read individual DAC register - Not Supported\n");
+            break;
+        case 0x17: /* READ BLOCK OF DAC REGISTERS */
+            FIXME(int10, "Read block of DAC registers - Not Supported\n");
+            break;
+        case 0x18: /* SET PEL MASK */
+            FIXME(int10, "Set PEL mask - Not Supported\n");
+            break;
+        case 0x19: /* READ PEL MASK */
+            FIXME(int10, "Read PEL mask - Not Supported\n");
+            break;
+        case 0x1a: /* GET VIDEO DAC COLOR PAGE STATE */
+            FIXME(int10, "Get video DAC color page state - Not Supported\n");
+            break;
+        case 0x1b: /* PERFORM GRAY-SCALE SUMMING */
+            FIXME(int10, "Perform Gray-scale summing - Not Supported\n");
+            break;
+        default:
+            FIXME(int10, "INT 10 AH = 0x10 AL = 0x%x - Unknown\n", 
+               AL_reg(context));
+            break;
+        }
+        break;
+
+    case 0x11: /* TEXT MODE CHARGEN */
+        /* Note that second subfunction is *almost* identical. */
+        /* See INTERRUPT.A for details. */
+        switch AH_reg(context) {
+        case 0x00: /* LOAD USER SPECIFIED PATTERNS */
+        case 0x10:
+            FIXME(int10, "Load User Specified Patterns - Not Supported\n");
+            break;
+        case 0x01: /* LOAD ROM MONOCHROME PATTERNS */
+        case 0x11:
+            FIXME(int10, "Load ROM Monochrome Patterns - Not Suppoted\n");
+            break;
+        case 0x02: /* LOAD ROM 8x8 DOUBLE-DOT PATTERNS */
+        case 0x12:
+            FIXME(int10, 
+                "Load ROM 8x8 Double Dot Patterns - Not Supported\n");       
+            break;
+        case 0x03: /* SET BLOCK SPECIFIER */
+            FIXME(int10, "Set Block Specifier - Not Supported\n");
+            break;
+        case 0x04: /* LOAD ROM 8x16 CHARACTER SET */
+        case 0x14:
+            FIXME(int10, "Load ROM 8x16 Character Set - Not Supported\n");
+            break;
+        case 0x20: /* SET USER 8x16 GRAPHICS CHARS */
+            FIXME(int10, "Set User 8x16 Graphics Chars - Not Supported\n");
+            break;
+        case 0x21: /* SET USER GRAPICS CHARACTERS */
+            FIXME(int10, "Set User Graphics Characters - Not Supported\n");
+            break;
+        case 0x22: /* SET ROM 8x14 GRAPHICS CHARS */
+            FIXME(int10, "Set ROM 8x14 Graphics Chars - Not Supported\n");
+            break;
+        case 0x23: /* SET ROM 8x8 DBL DOT CHARS */
+            FIXME(int10, 
+                "Set ROM 8x8 Dbl Dot Chars (Graphics) - Not Supported\n");
+            break;
+        case 0x24: /* LOAD 8x16 GRAPHIC CHARS */
+            FIXME(int10, "Load 8x16 Graphic Chars - Not Supported\n");
+            break;
+        case 0x30: /* GET FONT INFORMATION */
+            FIXME(int10, "Get Font Information - Not Supported\n");
+            break;
+        default:
+            FIXME(int10, "INT 10 AH = 0x11 AL = 0x%x - Unknown\n", 
+               AL_reg(context));
+            break;
+        }
+        break;
+        
+    case 0x12: /* ALTERNATE FUNCTION SELECT */
+        switch BL_reg(context) {
+        case 0x10: /* GET EGA INFO */
+            TRACE(int10, "EGA Info Requested");
+            BX_reg(context) = 0x0003;
+            CX_reg(context) = 0x0009;
+            break;
+        case 0x20: /* ALTERNATE PRTSC */
+            FIXME(int10, "Install Alternate Print Screen - Not Supported\n");
+            break;
+        case 0x30: /* SELECT VERTICAL RESOULTION */
+            FIXME(int10, "Select Vertical Resoultion - Not Supported\n");
+            break;
+        case 0x31: /* ENABLE/DISABLE PALETTE LOADING */
+            FIXME(int10, "Palette Loading - Not Supported\n");
+            break;
+        case 0x32: /* ENABLE/DISABLE VIDEO ADDRERSSING */
+            FIXME(int10, "Video Addressing - Not Supported\n");
+            break;
+        case 0x33: /* ENABLE/DISABLE GRAY SCALE SUMMING */
+            FIXME(int10, "Gray Scale Summing - Not Supported\n");
+            break;
+        case 0x34: /* ENABLE/DISABLE CURSOR EMULATION */
+            FIXME(int10, "Cursor Emulation - Not Supported\n");
+            break;
+        case 0x36: /* VIDEO ADDRESS CONTROL */
+            FIXME(int10, "Video Address Control - Not Supported\n");
+            break;
+        default:
+            FIXME(int10, "INT 10 AH = 0x11 AL = 0x%x - Unknown\n", 
+               AL_reg(context));
+            break;
+        }
+        break;
+
+    case 0x13: /* WRITE STRING */
+        /* This one does not imply that string be at cursor. */
+        FIXME(int10, "Write String - Not Supported\n");
+        break;
+                             
+    case 0x1a: 
+        switch AL_reg(context) {
+        case 0x00: /* GET DISPLAY COMBINATION CODE */
+            TRACE(int10, "Get Display Combination Code");
+            /* Why are we saying this? */
+            /* Do we need to check if we are in a windows or text app? */
+            BX_reg(context) = 0x0008; /* VGA w/ color analog display */
+            break;
+        case 0x01: /* SET DISPLAY COMBINATION CODE */
+            FIXME(int10, "Set Display Combination Code - Not Supported\n");
+            break;
+        default:
+            FIXME(int10, "INT 10 AH = 0x1a AL = 0x%x - Unknown\n", 
+               AL_reg(context));
+            break;
+        }
+    break;
+
+    case 0x1b: /* FUNCTIONALITY/STATE INFORMATION */
+        FIXME(int10, "Get Functionality/State Information - Not Supported\n");
+        break;
+
+    case 0x1c: /* SAVE/RESTORE VIDEO STATE */
+        FIXME(int10, "Save/Restore Video State - Not Supported\n");
         break;
 
     default:
+        FIXME(int10, "Unknown - 0x%x\n", AH_reg(context));
         INT_BARF( context, 0x10 );
     }
 }
diff --git a/msdos/int1a.c b/msdos/int1a.c
index 1436bb3..3504f67 100644
--- a/msdos/int1a.c
+++ b/msdos/int1a.c
@@ -39,8 +39,10 @@
 /**********************************************************************
  *	    INT_Int1aHandler
  *
- * Handler for int 1ah (date and time).
- */
+ * Handler for int 1ah 
+ *     0x00 - 0x07 - date and time
+ *     0x?? - 0x?? - Microsoft Real Time Compression Interface
+ */ 
 void WINAPI INT_Int1aHandler( CONTEXT *context )
 {
     time_t ltime;
@@ -49,7 +51,7 @@
 
     switch(AH_reg(context))
     {
-	case 0:
+	case 0x00:
             ticks = INT1A_GetTicksSinceMidnight();
             CX_reg(context) = HIWORD(ticks);
             DX_reg(context) = LOWORD(ticks);
@@ -57,7 +59,7 @@
             TRACE(int,"int1a: AH=00 -- ticks=%ld\n", ticks);
             break;
 		
-	case 2: 
+	case 0x02: 
 		ltime = time(NULL);
 		bdtime = localtime(&ltime);
 		
@@ -65,7 +67,7 @@
                                    BIN_TO_BCD(bdtime->tm_min);
 		DX_reg(context) = (BIN_TO_BCD(bdtime->tm_sec)<<8);
 
-	case 4:
+	case 0x04:
 		ltime = time(NULL);
 		bdtime = localtime(&ltime);
 		CX_reg(context) = (BIN_TO_BCD(bdtime->tm_year/100)<<8) |
@@ -75,18 +77,29 @@
 		break;
 
 		/* setting the time,date or RTC is not allow -EB */
-	case 1:
+	case 0x01:
 		/* set system time */
-	case 3: 
+	case 0x03: 
 		/* set RTC time */
-	case 5:
+	case 0x05:
 		/* set RTC date */
-	case 6:
+	case 0x06:
 		/* set ALARM */
-	case 7:
+	case 0x07:
 		/* cancel ALARM */
 		break;
 
+        case 0xb0: /* Microsoft Real Time Compression */
+                switch AL_reg(context)
+                {
+                    case 0x01:
+                        /* not present */
+                        break;
+                    default:
+                        INT_BARF(context, 0x1a);
+                }
+                break;
+                
 	default:
 		INT_BARF( context, 0x1a );
     }
diff --git a/msdos/int21.c b/msdos/int21.c
index a4e95f1..a17b630 100644
--- a/msdos/int21.c
+++ b/msdos/int21.c
@@ -732,6 +732,7 @@
     if (*fcb == 0xff) pFCB = (FINDFILE_FCB *)(fcb + 7);
     else pFCB = (FINDFILE_FCB *)fcb;
     drive = DOS_GET_DRIVE( pFCB->drive );
+    if (!DRIVE_IsValid( drive )) return 0;
     root = DRIVE_GetRoot( drive );
     cwd  = DRIVE_GetUnixCwd( drive );
     pFCB->unixPath = HeapAlloc( GetProcessHeap(), 0,
@@ -894,6 +895,21 @@
      }
 }
 
+static void INT21_SetCurrentPSP(CONTEXT *context)
+{
+/* FIXME - What is this MZ stuff and what if it isn't supported?? */
+#ifdef MZ_SUPPORTED
+    TDB *pTask = hModule ? NULL : (TDB *)GlobalLock16( GetCurrentTask() );
+    NE_MODULE *pModule = (hModule || pTask) ? NE_GetPtr( hModule ? hModule : pTask->hModule ) : NULL;
+    
+    GlobalUnlock16( GetCurrentTask() );
+    if (pModule->lpDosTask)
+        pModule->lpDosTask->psp_seg = BX_reg(context);
+#else
+    FIXME(int21, "MZ Not Supported.\n");
+#endif
+}
+    
 static WORD INT21_GetCurrentPSP()
 {
 #ifdef MZ_SUPPORTED
@@ -1189,8 +1205,13 @@
 	      (AL_reg(context) == 0x00)?"OEM number":"version flag");
         AX_reg(context) = (HIWORD(GetVersion16()) >> 8) |
                           (HIWORD(GetVersion16()) << 8);
-        BX_reg(context) = 0x0012;     /* 0x123456 is Wine's serial # */
-        CX_reg(context) = 0x3456;
+#if 0
+        AH_reg(context) = 0x7;
+        AL_reg(context) = 0xA;
+#endif
+
+        BX_reg(context) = 0x00FF;     /* 0x123456 is Wine's serial # */
+        CX_reg(context) = 0x0000;
         break;
 
     case 0x31: /* TERMINATE AND STAY RESIDENT */
@@ -1554,10 +1575,21 @@
     case 0x48: /* ALLOCATE MEMORY */
         TRACE(int21,"ALLOCATE MEMORY for %d paragraphs\n", BX_reg(context));
         {
-            LPVOID *mem = DOSMEM_GetBlock(0,BX_reg(context)<<4,NULL);
+            LPVOID *mem; 
+	    if (ISV86(context))
+	      {
+		mem= DOSMEM_GetBlock(0,(DWORD)BX_reg(context)<<4,NULL);
             if (mem)
                 AX_reg(context) = DOSMEM_MapLinearToDos(mem)>>4;
-            else {
+	      }
+	    else
+	      {
+		mem = (LPVOID)GlobalDOSAlloc(BX_reg(context)<<4);
+		if (mem)
+		  AX_reg(context) = (DWORD)mem&0xffff;
+	      }
+	    if (!mem)
+	      {
                 SET_CFLAG(context);
                 AX_reg(context) = 0x0008; /* insufficient memory */
                 BX_reg(context) = DOSMEM_Available(0)>>4;
@@ -1567,15 +1599,29 @@
 
     case 0x49: /* FREE MEMORY */
         TRACE(int21,"FREE MEMORY segment %04lX\n", ES_reg(context));
-        if (!DOSMEM_FreeBlock(0,DOSMEM_MapDosToLinear(ES_reg(context)<<4)))
         {
+	  BOOL32 ret;
+	  if (ISV86(context))
+	    ret= DOSMEM_FreeBlock(0,DOSMEM_MapDosToLinear(ES_reg(context)<<4));
+	  else
+	    {
+	      ret = !GlobalDOSFree(ES_reg(context));
+	      /* If we don't reset ES_reg, we will fail in the relay code */
+	      ES_reg(context)=ret;
+	    }
+	  if (!ret)
+	    {
+	      TRACE(int21,"FREE MEMORY failed\n");
             SET_CFLAG(context);
             AX_reg(context) = 0x0009; /* memory block address invalid */
         }
+	}
         break;
 
     case 0x4a: /* RESIZE MEMORY BLOCK */
         TRACE(int21,"RESIZE MEMORY segment %04lX to %d paragraphs\n", ES_reg(context), BX_reg(context));
+	if (!ISV86(context))
+	  FIXME(int21,"RESIZE MEMORY probably insufficent implementation. Expect crash soon\n");
 	{
 	    LPVOID *mem = DOSMEM_ResizeBlock(0,DOSMEM_MapDosToLinear(ES_reg(context)<<4),
 					       BX_reg(context)<<4,NULL);
@@ -1624,7 +1670,11 @@
         }
         else AX_reg(context) = 0;  /* OK */
         break;
-
+    case 0x50: /* SET CURRENT PROCESS ID (SET PSP ADDRESS) */
+        TRACE(int21, "SET CURRENT PROCESS ID (GET PSP ADDRESS)\n");
+        /* FIXME: Is this right? */
+        INT21_SetCurrentPSP(context);
+        break;
     case 0x51: /* GET PSP ADDRESS */
         TRACE(int21,"GET CURRENT PROCESS ID (GET PSP ADDRESS)\n");
         /* FIXME: should we return the original DOS PSP upon */
diff --git a/msdos/int2f.c b/msdos/int2f.c
index 914333a..0559fff 100644
--- a/msdos/int2f.c
+++ b/msdos/int2f.c
@@ -26,19 +26,61 @@
  */
 void WINAPI INT_Int2fHandler( CONTEXT *context )
 {
+    TRACE(int,"Subfunction 0x%X\n", AH_reg(context));
+
     switch(AH_reg(context))
     {
     case 0x10:
         AL_reg(context) = 0xff; /* share is installed */
         break;
 
+    case 0x12:
+        switch (AL_reg(context))
+        {
+        case 0x2e: /* get or set DOS error table address */
+            switch (DL_reg(context))
+            {
+            /* Four tables: even commands are 'get', odd are 'set' */
+            /* DOS 5.0+ ignores "set" commands */
+            case 0x01:
+            case 0x03:
+            case 0x05:
+            case 0x07:
+            case 0x09:
+                break; 
+            /* Instead of having a message table in DOS-space, */
+            /* we can use a special case for MS-DOS to force   */
+            /* the secondary interface.			       */
+            case 0x00:
+            case 0x02:
+            case 0x04:
+            case 0x06: 
+                ES_reg(context) = 0x0001;
+                DI_reg(context) = 0x0000;
+                break;
+            case 0x08:
+                FIXME(int, "No real-mode handler for errors yet! (bye!)");
+                break;
+            default:
+                INT_BARF(context, 0x2f);
+            }
+            break;
+        default:
+           INT_BARF(context, 0x2f);
+        }  
+        break;
+   
     case 0x15: /* mscdex */
-        do_mscdex(context, FALSE );
+        do_mscdex(context);
         break;
 
     case 0x16:
         do_int2f_16( context );
         break;
+    case 0x43:
+    	FIXME(int,"check for XMS (not supported)\n");
+	AL_reg(context) = 0x42; /* != 0x80 */
+    	break;
 
     case 0x45:
        switch (AL_reg(context)) 
@@ -82,6 +124,17 @@
 	    INT_BARF( context, 0x2f );
 	}
 	break;
+    case 0x7a:  /* NOVELL NetWare */
+        switch (AL_reg(context))
+        {
+        case 0x20:  /* Get VLM Call Address */
+            /* return nothing -> NetWare not installed */
+            break;
+        default:
+            SET_CFLAG(context);
+            break;
+        }
+        break;
     case 0xb7:  /* append */
         AL_reg(context) = 0; /* not installed */
         break;
@@ -162,7 +215,9 @@
 
     /* FIXME: is this right?  Specs say that this should only be callable
        in real (v86) mode which we never enter.  */
+    /* FIXME: we do now, and this breaks pkunzip */
     case 0x87: /* DPMI installation check */
+        if (ISV86(context)) break; /* so bail out for now if in v86 mode */
         {
 	    SYSTEM_INFO si;
 
@@ -185,7 +240,7 @@
     }
 }
 
-void do_mscdex( CONTEXT *context, int dorealmode )
+void do_mscdex( CONTEXT *context )
 {
     int drive, count;
     char *p;
@@ -218,10 +273,7 @@
             break;
 
         case 0x0D: /* get drive letters */
-	    if (dorealmode)
-	    	p = DOSMEM_MapRealToLinear(MAKELONG(BX_reg(context),ES_reg(context)));
-	    else
-		p = PTR_SEG_OFF_TO_LIN(ES_reg(context), BX_reg(context));
+	    p = CTX_SEG_OFF_TO_LIN(context, ES_reg(context), BX_reg(context));
             memset( p, 0, MAX_DOS_DRIVES );
             for (drive = 0; drive < MAX_DOS_DRIVES; drive++)
             {
@@ -230,8 +282,11 @@
             break;
 
 #ifdef linux
+        /* FIXME: why a new linux-only CDROM drive access, for crying out loud?
+         * There are pretty complete routines in multimedia/mcicda.c already! */
 	case 0x10: /* direct driver acces */
-	    do_mscdex_dd(context,dorealmode);
+            FIXME(cdaudio,"mscdex should use multimedia/mcicda.c");
+	    do_mscdex_dd(context,ISV86(context));
 	    break;
 
 #endif
diff --git a/msdos/interrupts.c b/msdos/interrupts.c
index da6ff2a..79c7144 100644
--- a/msdos/interrupts.c
+++ b/msdos/interrupts.c
@@ -39,3 +39,35 @@
                  intnum, HIWORD(handler), LOWORD(handler) );
     INT_Vectors[intnum] = handler;
 }
+
+
+/**********************************************************************
+ *	    INT_RealModeInterrupt
+ *
+ * Handle real mode interrupts
+ */
+int INT_RealModeInterrupt( BYTE intnum, PCONTEXT context )
+{
+    /* we should really map to if1632/wprocs.spec, but not all
+     * interrupt handlers are adapted to support real mode yet */
+    switch (intnum) {
+        case 0x10:
+            INT_Int10Handler(context);
+            break;
+        case 0x1a:
+            INT_Int1aHandler(context);
+            break;
+        case 0x20:
+            INT_Int20Handler(context);
+            break;
+        case 0x21:
+            DOS3Call(context);
+            break;
+        case 0x2f:
+            INT_Int2fHandler(context);
+            break;
+        default:
+            return 1;
+    }
+    return 0;
+}