Index: ke/i386/traphdlr.c =================================================================== --- ntoskrnl/ke/i386/traphdlr.c (revision 74238) +++ ntoskrnl/ke/i386/traphdlr.c (working copy) @@ -424,6 +424,21 @@ FASTCALL KiTrap01Handler(IN PKTRAP_FRAME TrapFrame) { + /* Check for V86 debug event */ + if (__builtin_expect(KiV86Trap(TrapFrame), 1)) + { + /* Enter V86 trap */ + KiEnterV86Trap(TrapFrame); + + /* Must be a VDM process */ + ASSERT(PsGetCurrentProcess()->VdmObjects); + + DPRINT1("V86: %x:%x\n", TrapFrame->SegCs, TrapFrame->Eip); + + /* Do a quick V86 exit if possible */ + KiExitV86Trap(TrapFrame); + } + /* Save trap frame */ KiEnterTrap(TrapFrame); Index: ke/i386/v86vdm.c =================================================================== --- ntoskrnl/ke/i386/v86vdm.c (revision 74238) +++ ntoskrnl/ke/i386/v86vdm.c (working copy) @@ -23,6 +23,7 @@ PVOID Ki386IopmSaveArea; BOOLEAN KeI386VirtualIntExtensions = FALSE; const PULONG KiNtVdmState = (PULONG)FIXED_NTVDMSTATE_LINEAR_PC_AT; +static BOOLEAN in_int; /* UNHANDLED OPCODES **********************************************************/ @@ -53,6 +54,8 @@ { ULONG Esp, V86EFlags, TrapEFlags; + if (in_int) DPRINT1("%x:%x PUSHF\n", TrapFrame->SegCs, TrapFrame->Eip); + /* Get current V8086 flags and mask out interrupt flag */ V86EFlags = *KiNtVdmState; V86EFlags &= ~EFLAGS_INTERRUPT_MASK; @@ -106,6 +109,8 @@ { ULONG Esp, V86EFlags, EFlags, TrapEFlags; + if (in_int) DPRINT1("%x:%x POPF\n", TrapFrame->SegCs, TrapFrame->Eip); + /* Build flat ESP */ Esp = (TrapFrame->HardwareSegSs << 4) + (USHORT)TrapFrame->HardwareEsp; @@ -180,6 +185,8 @@ { ULONG Esp, V86EFlags, TrapEFlags, Eip, Interrupt; + if (in_int) DPRINT1("%x:%x INT 0x%x, ax=%x\n", TrapFrame->SegCs, TrapFrame->Eip, *(PUCHAR)(TrapFrame->Eip + 1), TrapFrame->Eax); + /* Read trap frame EFlags */ TrapEFlags = TrapFrame->EFlags; @@ -197,7 +204,7 @@ V86EFlags |= (TrapEFlags & ~EFLAGS_INTERRUPT_MASK); /* And mask out the VIF, nested task and TF flag from the trap flags */ - TrapFrame->EFlags = TrapEFlags &~ (EFLAGS_VIF | EFLAGS_NESTED_TASK | EFLAGS_TF); + TrapFrame->EFlags = TrapEFlags &~ (EFLAGS_VIF | EFLAGS_NESTED_TASK);// | EFLAGS_TF); /* Add the IOPL flag to the local trap flags */ V86EFlags |= EFLAGS_IOPL; @@ -258,6 +265,8 @@ TrapFrame->SegCs = Interrupt; } + if (in_int) DPRINT1("Interrupt jumping to %x:%x\n", TrapFrame->SegCs, TrapFrame->Eip); + /* We're done */ return TRUE; } @@ -269,6 +278,8 @@ { ULONG Esp, V86EFlags, EFlags, TrapEFlags, Eip; + if (in_int) DPRINT1("%x:%x IRET\n", TrapFrame->SegCs, TrapFrame->Eip); + /* Build flat ESP */ Esp = (TrapFrame->HardwareSegSs << 4) + TrapFrame->HardwareEsp; @@ -341,6 +352,8 @@ KiVdmOpcodeCLI(IN PKTRAP_FRAME TrapFrame, IN ULONG Flags) { + if (in_int) DPRINT1("%x:%x CLI\n", TrapFrame->SegCs, TrapFrame->Eip); + /* Check for VME support */ ASSERT(KeI386VirtualIntExtensions == FALSE); @@ -359,6 +372,8 @@ KiVdmOpcodeSTI(IN PKTRAP_FRAME TrapFrame, IN ULONG Flags) { + if (in_int) DPRINT1("%x:%x STI\n", TrapFrame->SegCs, TrapFrame->Eip); + /* Check for VME support */ ASSERT(KeI386VirtualIntExtensions == FALSE); @@ -493,7 +508,7 @@ /* Restore TEB addresses */ Thread->Teb = V86Frame->ThreadTeb; KiSetTebBase(KeGetPcr(), V86Frame->ThreadTeb); - +in_int = FALSE; /* Enable interrupts and return a pointer to the trap frame */ _enable(); return StackFrameUnaligned; @@ -621,6 +636,8 @@ PVDM_PROCESS_OBJECTS VdmProcessObjects; USHORT OldOffset, OldBase; + DPRINT1("Ke386CallBios for int 0x%lx, Eax=%lx, Ebx=%lx, Ecx=%lx, Edx=%lx, Ebp=%lx, Edi=%lx, Esi=%lx, Ds=%x, Es=%x\n", + Int, Context->Eax, Context->Ebx, Context->Ecx, Context->Edx, Context->Ebp, Context->Edi, Context->Esi, Context->SegDs, Context->SegEs); /* Start with a clean TEB */ RtlZeroMemory(VdmTeb, sizeof(TEB)); @@ -629,6 +646,11 @@ *Trampoline++ = (UCHAR)Int; *(PULONG)Trampoline = TRAMPOLINE_BOP; + if (Int == 0x10 && Context->Eax == 0x4f15) + { + in_int = TRUE; + } + /* Setup the VDM TEB and TIB */ VdmTeb->Vdm = (PVOID)TRAMPOLINE_TIB; RtlZeroMemory(VdmTib, sizeof(VDM_TIB)); @@ -646,6 +668,11 @@ VdmTib->VdmContext.EFlags |= EFLAGS_V86_MASK | EFLAGS_INTERRUPT_MASK; VdmTib->VdmContext.ContextFlags = CONTEXT_FULL; + if (in_int) + { + VdmTib->VdmContext.EFlags |= EFLAGS_TF; + } + /* This can't be a real VDM process */ ASSERT(PsGetCurrentProcess()->VdmObjects == NULL); Index: vdm/vdmexec.c =================================================================== --- ntoskrnl/vdm/vdmexec.c (revision 74238) +++ ntoskrnl/vdm/vdmexec.c (working copy) @@ -231,6 +231,18 @@ VdmTib->VdmContext.EFlags |= EFLAGS_INTERRUPT_MASK; } + //if (VdmTib->VdmContext.EFlags & EFLAGS_TF) + //{ + // /* Enable them as well */ + // InterlockedOr((PLONG)VdmState, EFLAGS_TF); + //} + //else + //{ + // /* Disable them */ + // InterlockedAnd((PLONG)VdmState, ~EFLAGS_TF); + //} + //VdmTib->VdmContext.EFlags &= ~EFLAGS_TF; + /* Get the VDM context and make sure it's not an edited frame */ VdmContext = VdmTib->VdmContext; if (!(VdmContext.SegCs & FRAME_EDITED)) Index: vdm/vdmmain.c =================================================================== --- ntoskrnl/vdm/vdmmain.c (revision 74238) +++ ntoskrnl/vdm/vdmmain.c (working copy) @@ -71,7 +71,7 @@ if (!NT_SUCCESS(Status)) { /* Not present, so check if the CPU supports VME */ - if (KeGetPcr()->Prcb->FeatureBits & KF_V86_VIS) + if (0 && KeGetPcr()->Prcb->FeatureBits & KF_V86_VIS) { /* Enable them. FIXME: Use IPI */ Ki386VdmEnablePentiumExtentions(TRUE);