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) );