Recent instruction emulation changes broke DOS protected mode. This is a quick and dirty fix for that problem. STI is now emulated in two places. I don't think it is safe to remove STI emulation from generic instruction emulation code because Win16 programs may use that instruction. Interface of the INSTR_EmulateInstruction function has changed so its description before the function is no longer correct. Changelog: Make STI work again in DOS protected mode. Index: dlls/kernel/instr.c =================================================================== RCS file: /home/wine/wine/dlls/kernel/instr.c,v retrieving revision 1.1 diff -u -r1.1 instr.c --- dlls/kernel/instr.c 17 Sep 2003 04:34:31 -0000 1.1 +++ dlls/kernel/instr.c 17 Sep 2003 10:41:35 -0000 @@ -773,13 +773,10 @@ return 0; case 0xfb: /* sti */ + if (NtCurrentTeb()->vm86_pending) + break; /* Unable to emulate sti if there are any pending events */ NtCurrentTeb()->dpmi_vif = 1; context->Eip += prefixlen + 1; - if (NtCurrentTeb()->vm86_pending) - { - NtCurrentTeb()->vm86_pending = 0; - return EXCEPTION_VM86_STI; - } return 0; } return ret; /* Unable to emulate it */ Index: dlls/winedos/int31.c =================================================================== RCS file: /home/wine/wine/dlls/winedos/int31.c,v retrieving revision 1.34 diff -u -r1.34 int31.c --- dlls/winedos/int31.c 5 Sep 2003 23:08:28 -0000 1.34 +++ dlls/winedos/int31.c 17 Sep 2003 10:41:41 -0000 @@ -88,8 +88,7 @@ /********************************************************************** * dpmi_exception_handler * - * Handle EXCEPTION_VM86_STI exceptions generated - * when there are pending asynchronous events. + * Handle exceptions generated in DOS protected mode. */ static WINE_EXCEPTION_FILTER(dpmi_exception_handler) { @@ -99,6 +98,9 @@ if (rec->ExceptionCode == EXCEPTION_VM86_STI) { + /* + * Pending asynchronous event has been queued. + */ if (ISV86(context)) ERR( "Real mode STI caught by protected mode handler!\n" ); DOSVM_SendQueuedEvents(context); @@ -106,10 +108,30 @@ } else if (rec->ExceptionCode == EXCEPTION_VM86_INTx) { + /* + * Exit from protected mode due to int21 subfunction 0x4c. + * Return back to StartPM function. + */ if (ISV86(context)) ERR( "Real mode INTx caught by protected mode handler!\n" ); DPMI_retval = (BYTE)rec->ExceptionInformation[0]; return EXCEPTION_EXECUTE_HANDLER; + } + else if (rec->ExceptionCode == EXCEPTION_PRIV_INSTRUCTION) + { + BYTE *ptr = CTX_SEG_OFF_TO_LIN(context, context->SegCs, context->Eip); + + if(*ptr == 0xfb) + { + /* + * Emulate sti instruction. + */ + NtCurrentTeb()->dpmi_vif = 1; + NtCurrentTeb()->vm86_pending = 0; + context->Eip += 1; + DOSVM_SendQueuedEvents(context); + return EXCEPTION_CONTINUE_EXECUTION; + } } #endif -- Jukka Heinonen <http://www.iki.fi/jhei/>