Author: aandrejevic Date: Sat Nov 22 16:33:47 2014 New Revision: 65447
URL: http://svn.reactos.org/svn/reactos?rev=65447&view=rev Log: [FAST486] - Fix interrupts in V86 mode. - CLI and STI should call Fast486GetCurrentPrivLevel in their IOPL check, since it always returns 3 if the VM flag is set.
Modified: trunk/reactos/lib/fast486/common.c trunk/reactos/lib/fast486/opcodes.c
Modified: trunk/reactos/lib/fast486/common.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/fast486/common.c?rev=65... ============================================================================== --- trunk/reactos/lib/fast486/common.c [iso-8859-1] (original) +++ trunk/reactos/lib/fast486/common.c [iso-8859-1] Sat Nov 22 16:33:47 2014 @@ -294,8 +294,9 @@ State->PrefixFlags |= FAST486_PREFIX_OPSIZE; }
- /* Check if the interrupt handler is more privileged */ - if (Fast486GetCurrentPrivLevel(State) > GET_SEGMENT_RPL(SegmentSelector)) + /* Check if the interrupt handler is more privileged or if we're in V86 mode */ + if ((Fast486GetCurrentPrivLevel(State) > GET_SEGMENT_RPL(SegmentSelector)) + || State->Flags.Vm) { /* Read the TSS */ if (!Fast486ReadLinearMemory(State, @@ -309,6 +310,24 @@
/* Switch to the new privilege level */ State->Cpl = GET_SEGMENT_RPL(SegmentSelector); + + if (State->Flags.Vm) + { + /* Clear the VM flag */ + State->Flags.Vm = FALSE; + + /* Push GS, FS, DS and ES */ + if (!Fast486StackPush(State, State->SegmentRegs[FAST486_REG_GS].Selector)) goto Cleanup; + if (!Fast486StackPush(State, State->SegmentRegs[FAST486_REG_FS].Selector)) goto Cleanup; + if (!Fast486StackPush(State, State->SegmentRegs[FAST486_REG_DS].Selector)) goto Cleanup; + if (!Fast486StackPush(State, State->SegmentRegs[FAST486_REG_ES].Selector)) goto Cleanup; + + /* Now load them with NULL selectors, since they are useless in protected mode */ + if (!Fast486LoadSegment(State, FAST486_REG_GS, 0)) goto Cleanup; + if (!Fast486LoadSegment(State, FAST486_REG_FS, 0)) goto Cleanup; + if (!Fast486LoadSegment(State, FAST486_REG_DS, 0)) goto Cleanup; + if (!Fast486LoadSegment(State, FAST486_REG_ES, 0)) goto Cleanup; + }
/* Check the new (higher) privilege level */ switch (State->Cpl)
Modified: trunk/reactos/lib/fast486/opcodes.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/fast486/opcodes.c?rev=6... ============================================================================== --- trunk/reactos/lib/fast486/opcodes.c [iso-8859-1] (original) +++ trunk/reactos/lib/fast486/opcodes.c [iso-8859-1] Sat Nov 22 16:33:47 2014 @@ -754,7 +754,7 @@ if (State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE) { /* Check IOPL */ - if (State->Flags.Iopl >= State->SegmentRegs[FAST486_REG_CS].Dpl) + if (State->Flags.Iopl >= Fast486GetCurrentPrivLevel(State)) { /* Clear the interrupt flag */ State->Flags.If = FALSE; @@ -789,7 +789,7 @@ if (State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE) { /* Check IOPL */ - if (State->Flags.Iopl >= State->SegmentRegs[FAST486_REG_CS].Dpl) + if (State->Flags.Iopl >= Fast486GetCurrentPrivLevel(State)) { /* Set the interrupt flag */ State->Flags.If = TRUE; @@ -4547,6 +4547,14 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeInt) { UCHAR IntNum; + + /* Check for V86 mode */ + if (State->Flags.Vm && (State->Flags.Iopl != 3)) + { + /* Call the V86 monitor */ + Fast486Exception(State, FAST486_EXCEPTION_GP); + return; + }
switch (Opcode) {