Author: aandrejevic
Date: Tue May 27 21:10:45 2014
New Revision: 63482
URL:
http://svn.reactos.org/svn/reactos?rev=63482&view=rev
Log:
[FAST486][NTVDM]
Several fixes in fast486 and ntvdm:
DosCopyEnvironmentBlock - prepend the program name tag (0x0001) to the program name.
Fast486OpcodePushByteImm, Fast486OpcodePushImm - sign-extend instead of zero-extending.
Fast486InterruptInternal - The parameter is supposed to be the type of the gate, not a
boolean.
GET_SEGMENT_RPL will not work on real-mode selectors, use a special field for the RPL.
Loading a data segment with the NULL selector should never generate an exception.
Mask out the highest-order byte of the physical address when loading a descriptor table in
16-bit mode.
Fast486InterruptInternal - The interrupt gate type determines the size.
CORE-8257 #resolve #comment Fixed in revision r63482.
Modified:
trunk/reactos/include/reactos/libs/fast486/fast486.h
trunk/reactos/lib/fast486/common.c
trunk/reactos/lib/fast486/common.h
trunk/reactos/lib/fast486/common.inl
trunk/reactos/lib/fast486/opcodes.c
trunk/reactos/lib/fast486/opgroups.c
trunk/reactos/subsystems/ntvdm/dos/dos32krnl/dos.c
trunk/reactos/subsystems/ntvdm/dos/dos32krnl/dos.h
Modified: trunk/reactos/include/reactos/libs/fast486/fast486.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/libs/fast4…
==============================================================================
--- trunk/reactos/include/reactos/libs/fast486/fast486.h [iso-8859-1] (original)
+++ trunk/reactos/include/reactos/libs/fast486/fast486.h [iso-8859-1] Tue May 27 21:10:45
2014
@@ -251,6 +251,7 @@
ULONG DirConf : 1;
ULONG Executable : 1;
ULONG SystemType : 1;
+ ULONG Rpl : 2;
ULONG Dpl : 2;
ULONG Present : 1;
ULONG Size : 1;
Modified: trunk/reactos/lib/fast486/common.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/fast486/common.c?rev=6…
==============================================================================
--- trunk/reactos/lib/fast486/common.c [iso-8859-1] (original)
+++ trunk/reactos/lib/fast486/common.c [iso-8859-1] Tue May 27 21:10:45 2014
@@ -65,7 +65,7 @@
return FALSE;
}
- if ((!InstFetch && (GET_SEGMENT_RPL(CachedDescriptor->Selector) >
CachedDescriptor->Dpl))
+ if ((!InstFetch && (CachedDescriptor->Rpl >
CachedDescriptor->Dpl))
|| (Fast486GetCurrentPrivLevel(State) > CachedDescriptor->Dpl))
{
Fast486Exception(State, FAST486_EXCEPTION_GP);
@@ -132,7 +132,7 @@
return FALSE;
}
- if ((GET_SEGMENT_RPL(CachedDescriptor->Selector) >
CachedDescriptor->Dpl)
+ if ((CachedDescriptor->Rpl > CachedDescriptor->Dpl)
|| (Fast486GetCurrentPrivLevel(State) > CachedDescriptor->Dpl))
{
Fast486Exception(State, FAST486_EXCEPTION_GP);
@@ -164,14 +164,26 @@
Fast486InterruptInternal(PFAST486_STATE State,
USHORT SegmentSelector,
ULONG Offset,
- BOOLEAN InterruptGate)
+ ULONG GateType)
{
+ BOOLEAN GateSize = (GateType == FAST486_IDT_INT_GATE_32)
+ || (GateType == FAST486_IDT_TRAP_GATE_32);
+
/* Check for protected mode */
if (State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE)
{
FAST486_TSS Tss;
USHORT OldSs = State->SegmentRegs[FAST486_REG_SS].Selector;
ULONG OldEsp = State->GeneralRegs[FAST486_REG_ESP].Long;
+
+ if (GateSize != (State->SegmentRegs[FAST486_REG_CS].Size))
+ {
+ /*
+ * The gate size doesn't match the current operand size, so toggle
+ * the OPSIZE flag.
+ */
+ State->PrefixFlags ^= FAST486_PREFIX_OPSIZE;
+ }
/* Check if the interrupt handler is more privileged */
if (Fast486GetCurrentPrivLevel(State) > GET_SEGMENT_RPL(SegmentSelector))
@@ -257,7 +269,7 @@
/* Push the instruction pointer */
if (!Fast486StackPush(State, State->InstPtr.Long)) return FALSE;
- if (InterruptGate)
+ if ((GateType == FAST486_IDT_INT_GATE) || (GateType == FAST486_IDT_INT_GATE_32))
{
/* Disable interrupts after a jump to an interrupt gate handler */
State->Flags.If = FALSE;
@@ -270,7 +282,7 @@
return FALSE;
}
- if (State->SegmentRegs[FAST486_REG_CS].Size)
+ if (GateSize)
{
/* 32-bit code segment, use EIP */
State->InstPtr.Long = Offset;
Modified: trunk/reactos/lib/fast486/common.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/fast486/common.h?rev=6…
==============================================================================
--- trunk/reactos/lib/fast486/common.h [iso-8859-1] (original)
+++ trunk/reactos/lib/fast486/common.h [iso-8859-1] Tue May 27 21:10:45 2014
@@ -159,7 +159,7 @@
PFAST486_STATE State,
USHORT SegmentSelector,
ULONG Offset,
- BOOLEAN InterruptGate
+ ULONG GateType
);
VOID
Modified: trunk/reactos/lib/fast486/common.inl
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/fast486/common.inl?rev…
==============================================================================
--- trunk/reactos/lib/fast486/common.inl [iso-8859-1] (original)
+++ trunk/reactos/lib/fast486/common.inl [iso-8859-1] Tue May 27 21:10:45 2014
@@ -542,24 +542,32 @@
{
/* Loading a data segment */
- if (!GdtEntry.SystemType)
- {
- /* This is a special descriptor */
- Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_GP, Selector);
- return FALSE;
- }
-
- if ((GET_SEGMENT_RPL(Selector) > GdtEntry.Dpl)
- || (Fast486GetCurrentPrivLevel(State) > GdtEntry.Dpl))
- {
- Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_GP, Selector);
- return FALSE;
- }
-
- if (!GdtEntry.Present)
- {
- Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_NP, Selector);
- return FALSE;
+ if (GET_SEGMENT_INDEX(Selector) != 0)
+ {
+ if (!GdtEntry.SystemType)
+ {
+ /* This is a special descriptor */
+ Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_GP,
Selector);
+ return FALSE;
+ }
+
+ if ((GET_SEGMENT_RPL(Selector) > GdtEntry.Dpl)
+ || (Fast486GetCurrentPrivLevel(State) > GdtEntry.Dpl))
+ {
+ Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_GP,
Selector);
+ return FALSE;
+ }
+
+ if (!GdtEntry.Present)
+ {
+ Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_NP,
Selector);
+ return FALSE;
+ }
+ }
+ else
+ {
+ /* This is a NULL selector */
+ RtlZeroMemory(&GdtEntry, sizeof(GdtEntry));
}
}
@@ -572,6 +580,7 @@
CachedDescriptor->DirConf = GdtEntry.DirConf;
CachedDescriptor->Executable = GdtEntry.Executable;
CachedDescriptor->SystemType = GdtEntry.SystemType;
+ CachedDescriptor->Rpl = GET_SEGMENT_RPL(Selector);
CachedDescriptor->Dpl = GdtEntry.Dpl;
CachedDescriptor->Present = GdtEntry.Present;
CachedDescriptor->Size = GdtEntry.Size;
Modified: trunk/reactos/lib/fast486/opcodes.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/fast486/opcodes.c?rev=…
==============================================================================
--- trunk/reactos/lib/fast486/opcodes.c [iso-8859-1] (original)
+++ trunk/reactos/lib/fast486/opcodes.c [iso-8859-1] Tue May 27 21:10:45 2014
@@ -3702,9 +3702,9 @@
}
else
{
- USHORT Data;
-
- if (!Fast486FetchWord(State, &Data))
+ SHORT Data;
+
+ if (!Fast486FetchWord(State, (PUSHORT)&Data))
{
/* Exception occurred */
return FALSE;
@@ -3837,12 +3837,12 @@
FAST486_OPCODE_HANDLER(Fast486OpcodePushByteImm)
{
- UCHAR Data;
+ CHAR Data;
/* Make sure this is the right instruction */
ASSERT(Opcode == 0x6A);
- if (!Fast486FetchByte(State, &Data))
+ if (!Fast486FetchByte(State, (PUCHAR)&Data))
{
/* Exception occurred */
return FALSE;
Modified: trunk/reactos/lib/fast486/opgroups.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/fast486/opgroups.c?rev…
==============================================================================
--- trunk/reactos/lib/fast486/opgroups.c [iso-8859-1] (original)
+++ trunk/reactos/lib/fast486/opgroups.c [iso-8859-1] Tue May 27 21:10:45 2014
@@ -2018,10 +2018,13 @@
{
UCHAR TableReg[6];
FAST486_MOD_REG_RM ModRegRm;
- BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
+ BOOLEAN OperandSize, AddressSize;
FAST486_SEG_REGS Segment = FAST486_REG_DS;
+ OperandSize = AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
+
NO_LOCK_PREFIX();
+ TOGGLE_OPSIZE(OperandSize);
TOGGLE_ADSIZE(AddressSize);
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
@@ -2117,6 +2120,9 @@
State->Gdtr.Size = *((PUSHORT)TableReg);
State->Gdtr.Address = *((PULONG)&TableReg[sizeof(USHORT)]);
+ /* In 16-bit mode the highest byte is masked out */
+ if (!OperandSize) State->Gdtr.Address &= 0x00FFFFFF;
+
return TRUE;
}
@@ -2153,6 +2159,9 @@
State->Idtr.Size = *((PUSHORT)TableReg);
State->Idtr.Address = *((PULONG)&TableReg[sizeof(USHORT)]);
+ /* In 16-bit mode the highest byte is masked out */
+ if (!OperandSize) State->Idtr.Address &= 0x00FFFFFF;
+
return TRUE;
}
Modified: trunk/reactos/subsystems/ntvdm/dos/dos32krnl/dos.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/ntvdm/dos/dos32…
==============================================================================
--- trunk/reactos/subsystems/ntvdm/dos/dos32krnl/dos.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/ntvdm/dos/dos32krnl/dos.c [iso-8859-1] Tue May 27 21:10:45
2014
@@ -441,6 +441,10 @@
/* Set the final zero */
*(DestBuffer++) = 0;
+
+ /* Store the special program name tag */
+ *(DestBuffer++) = LOWORD(DOS_PROGRAM_NAME_TAG);
+ *(DestBuffer++) = HIWORD(DOS_PROGRAM_NAME_TAG);
/* Copy the program name after the environment block */
strcpy(DestBuffer, ProgramName);
Modified: trunk/reactos/subsystems/ntvdm/dos/dos32krnl/dos.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/ntvdm/dos/dos32…
==============================================================================
--- trunk/reactos/subsystems/ntvdm/dos/dos32krnl/dos.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/ntvdm/dos/dos32krnl/dos.h [iso-8859-1] Tue May 27 21:10:45
2014
@@ -47,6 +47,7 @@
#define DOS_DIR_LENGTH 64
#define NUM_DRIVES ('Z' - 'A' + 1)
#define DOS_CHAR_ATTRIBUTE 0x07
+#define DOS_PROGRAM_NAME_TAG 0x0001
enum DOS_ALLOC_STRATEGY
{