This partially reverts commit ed6bdb3c51cd4b8c94f9839806321703e7aa9765 and commit 526b245237b9571beebac8a4653e7dd74c62c7de.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=56225
-- v2: krnl386: Restore simulated real mode interrupts.
From: Alex Henrie alexhenrie24@gmail.com
This partially reverts commit ed6bdb3c51cd4b8c94f9839806321703e7aa9765 and commit 526b245237b9571beebac8a4653e7dd74c62c7de.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=56225 --- dlls/krnl386.exe16/dosexe.h | 9 +++- dlls/krnl386.exe16/int31.c | 80 ++++++++++++++++++++++++++++++++- dlls/krnl386.exe16/interrupts.c | 2 +- 3 files changed, 88 insertions(+), 3 deletions(-)
diff --git a/dlls/krnl386.exe16/dosexe.h b/dlls/krnl386.exe16/dosexe.h index f2064c2b758..89fac53db72 100644 --- a/dlls/krnl386.exe16/dosexe.h +++ b/dlls/krnl386.exe16/dosexe.h @@ -41,8 +41,12 @@ typedef void (WINAPI *INTPROC)(CONTEXT*); extern WORD DOSVM_psp; /* psp of current DOS task */ extern WORD int16_sel;
+#define V86_FLAG 0x00020000 + #define ADD_LOWORD(dw,val) ((dw) = ((dw) & 0xffff0000) | LOWORD((DWORD)(dw)+(val)))
+#define PTR_REAL_TO_LIN(seg,off) ((void*)(((unsigned int)(seg) << 4) + LOWORD(off))) + /* NOTE: Interrupts might get called from four modes: real mode, 16-bit, * 32-bit segmented (DPMI32) and 32-bit linear (via DeviceIoControl). * For automatic conversion of pointer @@ -62,7 +66,8 @@ extern WORD int16_sel; * segmented mode is recognized by checking whether 'seg' is 32-bit * selector which is neither system selector nor zero. */ -#define CTX_SEG_OFF_TO_LIN(context,seg,off) (ldt_get_ptr((seg),(off))) +#define CTX_SEG_OFF_TO_LIN(context,seg,off) \ + (ISV86(context) ? PTR_REAL_TO_LIN((seg),(off)) : ldt_get_ptr((seg),(off)))
#define INT_BARF(context,num) \ ERR( "int%x: unknown/not implemented parameters:\n" \ @@ -99,6 +104,7 @@ extern WORD int16_sel; #define RESET_CFLAG(context) ((context)->EFlags &= ~0x0001) #define SET_ZFLAG(context) ((context)->EFlags |= 0x0040) #define RESET_ZFLAG(context) ((context)->EFlags &= ~0x0040) +#define ISV86(context) ((context)->EFlags & 0x00020000)
#define SET_AX(context,val) ((void)((context)->Eax = ((context)->Eax & ~0xffff) | (WORD)(val))) #define SET_BX(context,val) ((void)((context)->Ebx = ((context)->Ebx & ~0xffff) | (WORD)(val))) @@ -236,6 +242,7 @@ extern void WINAPI DOSVM_Int31Handler(CONTEXT*);
/* interrupts.c */ extern void WINAPI __wine_call_int_handler16( BYTE, CONTEXT * ); +extern void DOSVM_CallBuiltinHandler( CONTEXT *, BYTE ); extern BOOL DOSVM_EmulateInterruptPM( CONTEXT *, BYTE ); extern FARPROC16 DOSVM_GetPMHandler16( BYTE ); extern void DOSVM_SetPMHandler16( BYTE, FARPROC16 ); diff --git a/dlls/krnl386.exe16/int31.c b/dlls/krnl386.exe16/int31.c index b5af832f4f2..841f73368ea 100644 --- a/dlls/krnl386.exe16/int31.c +++ b/dlls/krnl386.exe16/int31.c @@ -35,6 +35,74 @@ WINE_DEFAULT_DEBUG_CHANNEL(int31);
static void* lastvalloced = NULL;
+/* Structure for real-mode callbacks */ +typedef struct +{ + DWORD edi; + DWORD esi; + DWORD ebp; + DWORD reserved; + DWORD ebx; + DWORD edx; + DWORD ecx; + DWORD eax; + WORD fl; + WORD es; + WORD ds; + WORD fs; + WORD gs; + WORD ip; + WORD cs; + WORD sp; + WORD ss; +} REALMODECALL; + +/********************************************************************** + * INT_GetRealModeContext + */ +static void INT_GetRealModeContext( REALMODECALL *call, CONTEXT *context ) +{ + context->Eax = call->eax; + context->Ebx = call->ebx; + context->Ecx = call->ecx; + context->Edx = call->edx; + context->Esi = call->esi; + context->Edi = call->edi; + context->Ebp = call->ebp; + context->EFlags = call->fl | V86_FLAG; + context->Eip = call->ip; + context->Esp = call->sp; + context->SegCs = call->cs; + context->SegDs = call->ds; + context->SegEs = call->es; + context->SegFs = call->fs; + context->SegGs = call->gs; + context->SegSs = call->ss; +} + +/********************************************************************** + * INT_SetRealModeContext + */ +static void INT_SetRealModeContext( REALMODECALL *call, CONTEXT *context ) +{ + call->eax = context->Eax; + call->ebx = context->Ebx; + call->ecx = context->Ecx; + call->edx = context->Edx; + call->esi = context->Esi; + call->edi = context->Edi; + call->ebp = context->Ebp; + call->fl = LOWORD(context->EFlags); + call->ip = LOWORD(context->Eip); + call->sp = LOWORD(context->Esp); + call->cs = context->SegCs; + call->ds = context->SegDs; + call->es = context->SegEs; + call->fs = context->SegFs; + call->gs = context->SegGs; + call->ss = context->SegSs; +} + /********************************************************************** * DPMI_xalloc * special virtualalloc, allocates linearly monoton growing memory. @@ -395,7 +463,17 @@ void WINAPI DOSVM_Int31Handler( CONTEXT *context ) break;
case 0x0300: /* Simulate real mode interrupt */ - TRACE( "Simulate real mode interrupt %02x - not supported\n", BL_reg(context)); + TRACE( "Simulate real mode interrupt %02x\n", BL_reg(context) ); + { + CONTEXT realmode_ctx; + REALMODECALL *call = CTX_SEG_OFF_TO_LIN( context, + context->SegEs, + context->Edi ); + INT_GetRealModeContext( call, &realmode_ctx ); + RESET_CFLAG( context ); + DOSVM_CallBuiltinHandler( &realmode_ctx, BL_reg(context) ); + INT_SetRealModeContext( call, &realmode_ctx ); + } break;
case 0x0301: /* Call real mode procedure with far return */ diff --git a/dlls/krnl386.exe16/interrupts.c b/dlls/krnl386.exe16/interrupts.c index 5087d1b7a03..02faf419480 100644 --- a/dlls/krnl386.exe16/interrupts.c +++ b/dlls/krnl386.exe16/interrupts.c @@ -383,7 +383,7 @@ void DOSVM_SetPMHandler16( BYTE intnum, FARPROC16 handler ) * * Execute Wine interrupt handler procedure. */ -static void DOSVM_CallBuiltinHandler( CONTEXT *context, BYTE intnum ) +void DOSVM_CallBuiltinHandler( CONTEXT *context, BYTE intnum ) { /* * FIXME: Make all builtin interrupt calls go via this routine.
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=146866
Your paranoid android.
=== debian11b (64 bit WoW report) ===
user32: win.c:4037: Test failed: Expected active window 00000000027A0174, got 000000000514017A. win.c:4038: Test failed: Expected focus window 00000000027A0174, got 000000000514017A.
ws2_32: protocol.c:2479: Test succeeded inside todo block: IPv6 address is returned. protocol.c:2497: Test succeeded inside todo block: Test 0: IPv6 address is returned. protocol.c:2497: Test succeeded inside todo block: Test 1: IPv6 address is returned. protocol.c:2497: Test succeeded inside todo block: Test 2: IPv6 address is returned. protocol.c:2497: Test succeeded inside todo block: Test 3: IPv6 address is returned. protocol.c:2497: Test succeeded inside todo block: Test 4: IPv6 address is returned. protocol.c:2497: Test succeeded inside todo block: Test 5: IPv6 address is returned. protocol.c:2497: Test succeeded inside todo block: Test 12: IPv6 address is returned. protocol.c:2497: Test succeeded inside todo block: Test 13: IPv6 address is returned. protocol.c:2497: Test succeeded inside todo block: Test 14: IPv6 address is returned. protocol.c:2497: Test succeeded inside todo block: Test 15: IPv6 address is returned. protocol.c:2497: Test succeeded inside todo block: Test 16: IPv6 address is returned. protocol.c:2497: Test succeeded inside todo block: Test 28: IPv6 address is returned. protocol.c:2497: Test succeeded inside todo block: Test 29: IPv6 address is returned.