diff --git a/include/dosexe.h b/include/dosexe.h
index 0b96cc4fde1b2fc4a69b5428f9fbd01f07529522..d443a476f63949d3b0dc46ec5c09f037b91950e8 100644
--- a/include/dosexe.h
+++ b/include/dosexe.h
@@ -20,7 +20,6 @@ typedef struct _DOSTASK {
  WORD init_cs,init_ip,init_ss,init_sp;
  WORD xms_seg;
  WORD dpmi_seg,dpmi_sel,dpmi_flag;
- DWORD wrap_ofs,call_ofs;
  WORD system_timer;
  HMODULE16 hModule;
  char mm_name[128];
diff --git a/loader/dos/dosvm.c b/loader/dos/dosvm.c
index 5b11561fe567821774fec36530fa25007ccce575..0ade52ae9b4a75c8fbf917a0d41431bc66ab676f 100644
--- a/loader/dos/dosvm.c
+++ b/loader/dos/dosvm.c
@@ -76,12 +76,12 @@ static void DOSVM_Dump( LPDOSTASK lpDosTask, int fn,
 
 static int DOSVM_Int( int vect, PCONTEXT context, LPDOSTASK lpDosTask )
 {
+ extern UINT16 DPMI_wrap_seg;
+
  if (vect==0x31) {
-  if (CS_reg(context)==lpDosTask->dpmi_sel) {
-   if (IP_reg(context)>=lpDosTask->wrap_ofs) {
-    /* exit from real-mode wrapper */
-    return -1;
-   }
+  if (CS_reg(context)==DPMI_wrap_seg) {
+   /* exit from real-mode wrapper */
+   return -1;
   }
   /* we could probably move some other dodgy stuff here too from dpmi.c */
  }
diff --git a/loader/dos/module.c b/loader/dos/module.c
index 5508e7c9d91fe08e398becefe064bd5cf444028e..c0b5f47872bf94c95d5d4928d663e420bde0079c 100644
--- a/loader/dos/module.c
+++ b/loader/dos/module.c
@@ -135,22 +135,14 @@ static char enter_pm[]={
  0xCB                 /* lret */
 };
 
-static char wrap_rm[]={
- 0xCD,0x31,           /* int $0x31 */
- 0xCB                 /* lret */
-};
-
 static void MZ_InitDPMI( LPDOSTASK lpDosTask )
 {
- unsigned size=sizeof(enter_pm)+sizeof(wrap_rm);
+ unsigned size=sizeof(enter_pm);
  LPBYTE start=DOSMEM_GetBlock(lpDosTask->hModule,size,&(lpDosTask->dpmi_seg));
  
  lpDosTask->dpmi_sel = SELECTOR_AllocBlock( start, size, SEGMENT_CODE, FALSE, FALSE );
- lpDosTask->wrap_ofs = size-sizeof(wrap_rm);
- lpDosTask->call_ofs = size-1;
 
  memcpy(start,enter_pm,sizeof(enter_pm));
- memcpy(start+sizeof(enter_pm),wrap_rm,sizeof(wrap_rm));
 }
 
 static WORD MZ_InitEnvironment( LPDOSTASK lpDosTask, LPCSTR env, LPCSTR name )
diff --git a/msdos/dosmem.c b/msdos/dosmem.c
index fc91bacb8bc66462096461f5ffb631f080c175c3..eaf67b5cae7d610cfc1c10e1fbb88f12b2d339d7 100644
--- a/msdos/dosmem.c
+++ b/msdos/dosmem.c
@@ -181,6 +181,23 @@ static void DOSMEM_FillIsrTable(HMODULE16 hModule)
     for (x=0; x<256; x++) stub[x]=VM_STUB(x);
 } 
 
+/***********************************************************************
+ *           DOSMEM_InitDPMI
+ *
+ * Allocate the global DPMI RMCB wrapper.
+ */
+static void DOSMEM_InitDPMI(void)
+{
+    extern UINT16 DPMI_wrap_seg;
+    static char wrap_code[]={
+     0xCD,0x31, /* int $0x31 */
+     0xCB       /* lret */
+    };
+    LPSTR wrapper = (LPSTR)DOSMEM_GetBlock(0, sizeof(wrap_code), &DPMI_wrap_seg);
+
+    memcpy(wrapper, wrap_code, sizeof(wrap_code));
+}
+
 /***********************************************************************
  *           DOSMEM_FillBiosSegment
  *
@@ -343,6 +360,7 @@ BOOL32 DOSMEM_Init(HMODULE16 hModule)
         DOSMEM_InitMemory(0);
         DOSMEM_InitCollateTable();
         DOSMEM_InitErrorTable();
+        DOSMEM_InitDPMI();
     }
     else
     {
diff --git a/msdos/dpmi.c b/msdos/dpmi.c
index 03f550b93a819a267dbf8965a25f72c4bb7fe055..d49bc540484d942622b3272f46329c8920958de6 100644
--- a/msdos/dpmi.c
+++ b/msdos/dpmi.c
@@ -63,6 +63,8 @@ typedef struct tagRMCB {
 
 static RMCB *FirstRMCB = NULL;
 
+UINT16 DPMI_wrap_seg;
+
 /**********************************************************************
  *	    DPMI_xalloc
  * special virtualalloc, allocates lineary monoton growing memory.
@@ -154,6 +156,7 @@ static void INT_GetRealModeContext( REALMODECALL *call, CONTEXT *context )
     ES_reg(context)  = call->es;
     FS_reg(context)  = call->fs;
     GS_reg(context)  = call->gs;
+    SS_reg(context)  = call->ss;
     (char*)V86BASE(context) = DOSMEM_MemoryBase(0);
 }
 
@@ -178,6 +181,7 @@ static void INT_SetRealModeContext( REALMODECALL *call, CONTEXT *context )
     call->es  = ES_reg(context);
     call->fs  = FS_reg(context);
     call->gs  = GS_reg(context);
+    call->ss  = SS_reg(context);
 }
 
 
@@ -269,7 +273,7 @@ int DPMI_CallRMProc( CONTEXT *context, LPWORD stack, int args, int iret )
 
     TRACE(int31, "EAX=%08lx EBX=%08lx ECX=%08lx EDX=%08lx\n",
                  EAX_reg(context), EBX_reg(context), ECX_reg(context), EDX_reg(context) );
-    TRACE(int31, "ESI=%08lx EDI=%08lx ES=%04x DS=%04x CS:IP=%04x:%04x, %d WORD arguments, %s\n",
+    TRACE(int31, "ESI=%08lx EDI=%08lx ES=%04lx DS=%04lx CS:IP=%04lx:%04x, %d WORD arguments, %s\n",
                  ESI_reg(context), EDI_reg(context), ES_reg(context), DS_reg(context),
                  CS_reg(context), IP_reg(context), args, iret?"IRET":"FAR" );
 
@@ -298,7 +302,7 @@ callrmproc_again:
     if (!already) {
         if (!SS_reg(context)) {
             alloc = 1; /* allocate default stack */
-            stack16 = addr = DOSMEM_GetBlock( pModule->self, 64, &(SS_reg(context)) );
+            stack16 = addr = DOSMEM_GetBlock( pModule->self, 64, (UINT16 *)&(SS_reg(context)) );
             SP_reg(context) = 64-2;
             stack16 += 32-1;
             if (!addr) {
@@ -322,8 +326,8 @@ callrmproc_again:
         }
 #ifdef MZ_SUPPORTED
         /* push return address (return to interrupt wrapper) */
-        *(--stack16) = pModule->lpDosTask->dpmi_seg;
-        *(--stack16) = pModule->lpDosTask->wrap_ofs;
+        *(--stack16) = DPMI_wrap_seg;
+        *(--stack16) = 0;
         /* adjust stack */
         SP_reg(context) -= 2*sizeof(WORD);
 #endif
@@ -334,8 +338,8 @@ callrmproc_again:
         /* RMCB call, invoke protected-mode handler directly */
         DPMI_CallRMCBProc(context, CurrRMCB, pModule->lpDosTask?pModule->lpDosTask->dpmi_flag:0);
         /* check if we returned to where we thought we would */
-        if ((CS_reg(context) != pModule->lpDosTask->dpmi_seg) ||
-            (IP_reg(context) != pModule->lpDosTask->wrap_ofs)) {
+        if ((CS_reg(context) != DPMI_wrap_seg) ||
+            (IP_reg(context) != 0)) {
             /* we need to continue at different address in real-mode space,
                so we need to set it all up for real mode again */
             goto callrmproc_again;
@@ -349,8 +353,8 @@ callrmproc_again:
         /* adjust stack */
         SP_reg(context) -= 2*sizeof(WORD);
         /* set initial CS:IP to the wrapper's "lret" */
-        CS_reg(context) = pModule->lpDosTask->dpmi_seg;
-        IP_reg(context) = pModule->lpDosTask->call_ofs;
+        CS_reg(context) = DPMI_wrap_seg;
+        IP_reg(context) = 2;
 #endif
         TRACE(int31,"entering real mode...\n");
         DOSVM_Enter( context );
@@ -414,10 +418,6 @@ static void CallRMProc( CONTEXT *context, int iret )
 {
     REALMODECALL *p = (REALMODECALL *)PTR_SEG_OFF_TO_LIN( ES_reg(context), DI_reg(context) );
     CONTEXT context16;
-    THDB *thdb = THREAD_Current();
-    WORD argsize, sel;
-    LPVOID addr;
-    SEGPTR seg_addr;
 
     TRACE(int31, "RealModeCall: EAX=%08lx EBX=%08lx ECX=%08lx EDX=%08lx\n",
 	p->eax, p->ebx, p->ecx, p->edx);
@@ -488,7 +488,6 @@ static RMCB *DPMI_AllocRMCB( void )
 static void AllocRMCB( CONTEXT *context )
 {
     RMCB *NewRMCB = DPMI_AllocRMCB();
-    REALMODECALL *p = (REALMODECALL *)PTR_SEG_OFF_TO_LIN( ES_reg(context), DI_reg(context) );
 
     TRACE(int31, "Function to call: %04x:%04x\n", (WORD)DS_reg(context), SI_reg(context) );