Moved the few remaining functions in wprocs.dll to kernel.dll.
No longer load wprocs.dll unconditionally.
Restored default interrupt handler behavior (reported by Andreas Mohr).

diff --git a/dlls/kernel/kernel.spec b/dlls/kernel/kernel.spec
index 2a51f67..feb965d 100644
--- a/dlls/kernel/kernel.spec
+++ b/dlls/kernel/kernel.spec
@@ -515,6 +515,12 @@
 652 stub IsThreadId
 653 stub OkWithKernelToChangeUsers
 
+# Extra Wine internal functions for thunking and self-loader
+
+666 pascal UTGlue16(ptr long ptr long) UTGlue16
+667 pascal EntryAddrProc(word word) EntryAddrProc16
+668 pascal MyAlloc(word word word) MyAlloc16
+ 
 
 # 700-704 are Win95 only
 
diff --git a/dlls/kernel/kernel_main.c b/dlls/kernel/kernel_main.c
index 11f3529..ec2b0e9 100644
--- a/dlls/kernel/kernel_main.c
+++ b/dlls/kernel/kernel_main.c
@@ -8,7 +8,6 @@
 #include "winbase.h"
 #include "wine/winbase16.h"
 
-#include "neexe.h"
 #include "module.h"
 #include "task.h"
 #include "selectors.h"
@@ -50,7 +49,7 @@
     NE_SetEntryPoint( hModule, 455, __get_ds() );
 
     /* Initialize KERNEL.THHOOK */
-    TASK_InstallTHHook((THHOOK *)PTR_SEG_TO_LIN((SEGPTR)NE_GetEntryPoint( hModule, 332 )));
+    TASK_InstallTHHook((THHOOK *)PTR_SEG_TO_LIN((SEGPTR)GetProcAddress16( hModule, (LPCSTR)332 )));
 
     /* Initialize the real-mode selector entry points */
 #define SET_ENTRY_POINT( num, addr ) \
@@ -72,7 +71,6 @@
 
     /* Force loading of some dlls */
     if (LoadLibrary16( "system" ) < 32) return FALSE;
-    if (LoadLibrary16( "wprocs" ) < 32) return FALSE;
 
     /* Initialize communications */
     COMM_Init();
diff --git a/dlls/kernel/utthunk.c b/dlls/kernel/utthunk.c
index a4ff965..2888449 100644
--- a/dlls/kernel/utthunk.c
+++ b/dlls/kernel/utthunk.c
@@ -65,7 +65,7 @@
 /* ### stop build ### */
 
 /****************************************************************************
- *		UTGlue16     (WPROCS.*)
+ *		UTGlue16     (KERNEL Wine-specific export)
  */
 DWORD WINAPI UTGlue16( LPVOID lpBuff, DWORD dwUserDefined, SEGPTR *translationList,
 		       UTGLUEPROC target )
@@ -148,11 +148,8 @@
 
     if ( !UTGlue16_Segptr )
     {
-        HMODULE16 hModule = GetModuleHandle16( "WPROCS" );
-        int       ordinal = NE_GetOrdinal( hModule, "UTGlue16" );
-        if ( hModule && ordinal )
-            UTGlue16_Segptr = NE_GetEntryPoint( hModule, ordinal );
-
+        HMODULE16 hModule = GetModuleHandle16( "KERNEL" );
+        UTGlue16_Segptr = GetProcAddress16( hModule, "UTGlue16" );
         if ( !UTGlue16_Segptr ) return NULL;
     }
 
diff --git a/dlls/kernel/wprocs.spec b/dlls/kernel/wprocs.spec
index d2ceb29..8af24f0 100644
--- a/dlls/kernel/wprocs.spec
+++ b/dlls/kernel/wprocs.spec
@@ -2,10 +2,6 @@
 type	win16
 owner	kernel32
 
-23 pascal UTGlue16(ptr long ptr long) UTGlue16
-27 pascal EntryAddrProc(word word) WIN16_NE_GetEntryPoint
-28 pascal MyAlloc(word word word) NE_AllocateSegment
- 
 # Interrupt vectors 0-255 are ordinals 100-355
 # The 'interrupt' keyword takes care of the flags pushed on the stack by the interrupt
 116 interrupt INT_Int10Handler() INT_Int10Handler
@@ -26,6 +22,8 @@
 165 interrupt INT_Int41Handler() INT_Int41Handler
 175 interrupt INT_Int4bHandler() INT_Int4bHandler
 192 interrupt INT_Int5cHandler() NetBIOSCall16
+# default handler for unimplemented interrupts
+356 interrupt INT_DefaultHandler() INT_DefaultHandler
 
 # VxDs. The first Vxd is at 400
 #
diff --git a/loader/ne/module.c b/loader/ne/module.c
index a292389..ec4bce9 100644
--- a/loader/ne/module.c
+++ b/loader/ne/module.c
@@ -13,7 +13,6 @@
 #include "wine/winbase16.h"
 #include "winerror.h"
 #include "module.h"
-#include "neexe.h"
 #include "toolhelp.h"
 #include "file.h"
 #include "ldt.h"
@@ -30,6 +29,17 @@
 
 DEFAULT_DEBUG_CHANNEL(module);
 
+/*
+ * Segment table entry
+ */
+struct ne_segment_table_entry_s
+{
+    WORD seg_data_offset;   /* Sector offset of segment data	*/
+    WORD seg_data_length;   /* Length of segment data		*/
+    WORD seg_flags;         /* Flags associated with this segment	*/
+    WORD min_alloc;         /* Minimum allocation size for this	*/
+};
+
 #define hFirstModule (pThhook->hExeHead)
 
 static NE_MODULE *pCachedModule = 0;  /* Module cached by NE_OpenFile */
@@ -111,8 +121,8 @@
         DPRINTF( "Alignment: %d\n", *pword++ );
         while (*pword)
         {
-            struct resource_typeinfo_s *ptr = (struct resource_typeinfo_s *)pword;
-            struct resource_nameinfo_s *pname = (struct resource_nameinfo_s *)(ptr + 1);
+            NE_TYPEINFO *ptr = (NE_TYPEINFO *)pword;
+            NE_NAMEINFO *pname = (NE_NAMEINFO *)(ptr + 1);
             DPRINTF( "id=%04x count=%d\n", ptr->type_id, ptr->count );
             for (i = 0; i < ptr->count; i++, pname++)
                 DPRINTF( "offset=%d len=%d id=%04x\n",
@@ -284,11 +294,11 @@
 
 
 /***********************************************************************
- *           NE_GetEntryPoint   (WPROCS.27)
+ *           NE_GetEntryPoint / EntryAddrProc16   (KERNEL Wine-specific export)
  *
  * Return the entry point for a given ordinal.
  */
-FARPROC16 WINAPI WIN16_NE_GetEntryPoint( HMODULE16 hModule, WORD ordinal )
+FARPROC16 WINAPI EntryAddrProc16( HMODULE16 hModule, WORD ordinal )
 {
     FARPROC16 ret = NE_GetEntryPointEx( hModule, ordinal, TRUE );
     CURRENT_STACK16->ecx = hModule; /* FIXME: might be incorrect value */
@@ -1215,15 +1225,8 @@
  */
 static BOOL16 MODULE_CallWEP( HMODULE16 hModule )
 {
-    FARPROC16 WEP = (FARPROC16)0;
-    WORD ordinal = NE_GetOrdinal( hModule, "WEP" );
-
-    if (ordinal) WEP = NE_GetEntryPoint( hModule, ordinal );
-    if (!WEP)
-    {
-	WARN("module %04x doesn't have a WEP\n", hModule );
-	return FALSE;
-    }
+    FARPROC16 WEP = GetProcAddress16( hModule, "WEP" );
+    if (!WEP) return FALSE;
     return NE_CallTo16_word_w( WEP, WEP_FREE_DLL );
 }
 
diff --git a/loader/ne/segment.c b/loader/ne/segment.c
index a50664c..2b780db 100644
--- a/loader/ne/segment.c
+++ b/loader/ne/segment.c
@@ -16,7 +16,6 @@
 #include <string.h>
 
 #include "wine/winbase16.h"
-#include "neexe.h"
 #include "global.h"
 #include "task.h"
 #include "file.h"
@@ -30,6 +29,37 @@
 DECLARE_DEBUG_CHANNEL(module);
 DECLARE_DEBUG_CHANNEL(segment);
 
+/*
+ * Relocation table entry
+ */
+struct relocation_entry_s
+{
+    BYTE address_type;    /* Relocation address type */
+    BYTE relocation_type; /* Relocation type */
+    WORD offset;          /* Offset in segment to fixup */
+    WORD target1;         /* Target specification */
+    WORD target2;         /* Target specification */
+};
+
+/*
+ * Relocation address types
+ */
+#define NE_RADDR_LOWBYTE      0
+#define NE_RADDR_SELECTOR     2
+#define NE_RADDR_POINTER32    3
+#define NE_RADDR_OFFSET16     5
+#define NE_RADDR_POINTER48    11
+#define NE_RADDR_OFFSET32     13
+
+/*
+ * Relocation types
+ */
+#define NE_RELTYPE_INTERNAL  0
+#define NE_RELTYPE_ORDINAL   1
+#define NE_RELTYPE_NAME      2
+#define NE_RELTYPE_OSFIXUP   3
+#define NE_RELFLAG_ADDITIVE  4
+
 #define SEL(x) ((x)|1)
 
 static void NE_FixupSegmentPrologs(NE_MODULE *pModule, WORD segnum);
@@ -398,7 +428,7 @@
         HFILE16 hFile16;
         /* Handle self-loading modules */
         SELFLOADHEADER *selfloadheader;
-        HMODULE16 hselfload = GetModuleHandle16("WPROCS");
+        HMODULE16 mod = GetModuleHandle16("KERNEL");
         DWORD oldstack;
 
         TRACE_(module)("%.*s is a self-loading module!\n",
@@ -407,9 +437,9 @@
         if (!NE_LoadSegment( pModule, 1 )) return FALSE;
         selfloadheader = (SELFLOADHEADER *)
                           PTR_SEG_OFF_TO_LIN(SEL(pSegTable->hSeg), 0);
-        selfloadheader->EntryAddrProc = NE_GetEntryPoint(hselfload,27);
-        selfloadheader->MyAlloc  = NE_GetEntryPoint(hselfload,28);
-        selfloadheader->SetOwner = NE_GetEntryPoint(GetModuleHandle16("KERNEL"),403);
+        selfloadheader->EntryAddrProc = GetProcAddress16(mod,"EntryAddrProc");
+        selfloadheader->MyAlloc       = GetProcAddress16(mod,"MyAlloc");
+        selfloadheader->SetOwner      = GetProcAddress16(mod,"FarSetOwner");
         pModule->self_loading_sel = SEL(GLOBAL_Alloc(GMEM_ZEROINIT, 0xFF00, pModule->self, WINE_LDT_FLAGS_DATA));
         oldstack = NtCurrentTeb()->cur_stack;
         NtCurrentTeb()->cur_stack = PTR_SEG_OFF_TO_SEGPTR(pModule->self_loading_sel,
@@ -671,12 +701,10 @@
 {
     WORD hInst, ds, heap;
     FARPROC16 entryPoint;
-    WORD ordinal;
 
     if (!(pModule->flags & NE_FFLAGS_LIBMODULE)) return;
     if (!(pModule->flags & NE_FFLAGS_BUILTIN) && pModule->expected_version < 0x0400) return;
-    if (!(ordinal = NE_GetOrdinal( pModule->self, "DllEntryPoint" ))) return;
-    if (!(entryPoint = NE_GetEntryPoint( pModule->self, ordinal ))) return;
+    if (!(entryPoint = GetProcAddress16( pModule->self, "DllEntryPoint" ))) return;
 
     NE_GetDLLInitParams( pModule, &hInst, &ds, &heap );
 
@@ -796,11 +824,11 @@
 }
 
 /***********************************************************************
- *           NE_AllocateSegment (WPROCS.26)
+ *           MyAlloc16   (KERNEL Wine-specific export)
  *
  * MyAlloc() function for self-loading apps.
  */
-DWORD WINAPI NE_AllocateSegment( WORD wFlags, WORD wSize, WORD wElem )
+DWORD WINAPI MyAlloc16( WORD wFlags, WORD wSize, WORD wElem )
 {
     WORD size = wSize << wElem;
     HANDLE16 hMem = 0;
diff --git a/msdos/int2f.c b/msdos/int2f.c
index da254c9..70fc4b7 100644
--- a/msdos/int2f.c
+++ b/msdos/int2f.c
@@ -326,15 +326,15 @@
 	break;
 
     case 0x84:  /* Get device API entry point */
-        addr = (DWORD)NE_GetEntryPoint( GetModuleHandle16("WPROCS"),
-                                        VXD_BASE + BX_reg(context) );
-        if (!addr)  /* not supported */
         {
-	    ERR("Accessing unknown VxD %04x - Expect a failure now.\n",
-                     BX_reg(context) );
+            HMODULE16 mod = GetModuleHandle16("wprocs");
+            if (mod < 32) mod = LoadLibrary16( "wprocs" );
+            addr = (DWORD)GetProcAddress16( mod, (LPCSTR)(VXD_BASE + BX_reg(context)) );
+            if (!addr)  /* not supported */
+                ERR("Accessing unknown VxD %04x - Expect a failure now.\n", BX_reg(context) );
+            context->SegEs = SELECTOROF(addr);
+            DI_reg(context) = OFFSETOF(addr);
         }
-	context->SegEs = SELECTOROF(addr);
-	DI_reg(context) = OFFSETOF(addr);
 	break;
 
     case 0x86:  /* DPMI detect mode */
diff --git a/msdos/interrupts.c b/msdos/interrupts.c
index c8662e5..cea83b4 100644
--- a/msdos/interrupts.c
+++ b/msdos/interrupts.c
@@ -32,13 +32,18 @@
         static HMODULE16 wprocs;
         if (!wprocs)
         {
-            if ((wprocs = GetModuleHandle16( "wprocs" )) < 32)
+            if (((wprocs = GetModuleHandle16( "wprocs" )) < 32) &&
+                ((wprocs = LoadLibrary16( "wprocs" )) < 32))
             {
                 ERR("could not load wprocs.dll\n");
                 return 0;
             }
         }
-        INT_Vectors[intnum] = NE_GetEntryPoint( wprocs, FIRST_INTERRUPT + intnum );
+        if (!(INT_Vectors[intnum] = GetProcAddress16( wprocs, (LPCSTR)(FIRST_INTERRUPT + intnum))))
+        {
+            WARN("int%x not implemented, returning dummy handler\n", intnum );
+            INT_Vectors[intnum] = GetProcAddress16( wprocs, (LPCSTR)(FIRST_INTERRUPT + 256) );
+        }
     }
     return INT_Vectors[intnum];
 }
@@ -176,3 +181,13 @@
     }
     return 0;
 }
+
+
+/**********************************************************************
+ *         INT_DefaultHandler
+ *
+ * Default interrupt handler.
+ */
+void WINAPI INT_DefaultHandler( CONTEXT86 *context )
+{
+}