Author: aandrejevic
Date: Fri Nov 1 22:39:43 2013
New Revision: 60824
URL:
http://svn.reactos.org/svn/reactos?rev=60824&view=rev
Log:
[FAST486]
Implement opcode group 0x0F, 0x01 (SGDT, SIDT, LGDT, LIDT, SMSW and LMSW).
Only INVLPG is not implemented yet.
Modified:
branches/ntvdm/lib/fast486/extraops.c
branches/ntvdm/lib/fast486/opgroups.c
branches/ntvdm/lib/fast486/opgroups.h
Modified: branches/ntvdm/lib/fast486/extraops.c
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/lib/fast486/extraops.c?re…
==============================================================================
--- branches/ntvdm/lib/fast486/extraops.c [iso-8859-1] (original)
+++ branches/ntvdm/lib/fast486/extraops.c [iso-8859-1] Fri Nov 1 22:39:43 2013
@@ -38,7 +38,7 @@
Fast486ExtendedHandlers[FAST486_NUM_OPCODE_HANDLERS] =
{
NULL, // TODO: OPCODE 0x00 NOT IMPLEMENTED
- NULL, // TODO: OPCODE 0x01 NOT IMPLEMENTED
+ Fast486OpcodeGroup0F01,
NULL, // TODO: OPCODE 0x02 NOT IMPLEMENTED
NULL, // TODO: OPCODE 0x03 NOT IMPLEMENTED
NULL, // TODO: OPCODE 0x04 NOT IMPLEMENTED
Modified: branches/ntvdm/lib/fast486/opgroups.c
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/lib/fast486/opgroups.c?re…
==============================================================================
--- branches/ntvdm/lib/fast486/opgroups.c [iso-8859-1] (original)
+++ branches/ntvdm/lib/fast486/opgroups.c [iso-8859-1] Fri Nov 1 22:39:43 2013
@@ -1657,6 +1657,208 @@
return TRUE;
}
+FAST486_OPCODE_HANDLER(Fast486OpcodeGroup0F01)
+{
+ UCHAR TableReg[6];
+ FAST486_MOD_REG_RM ModRegRm;
+ BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
+ FAST486_SEG_REGS Segment = FAST486_REG_DS;
+
+ NO_LOCK_PREFIX();
+ TOGGLE_ADSIZE(AddressSize);
+
+ /* Check for the segment override */
+ if (State->PrefixFlags & FAST486_PREFIX_SEG)
+ {
+ /* Use the override segment instead */
+ Segment = State->SegmentOverride;
+ }
+
+ if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
+ {
+ /* Exception occurred */
+ return FALSE;
+ }
+
+ /* Check which operation this is */
+ switch (ModRegRm.Register)
+ {
+ /* SGDT */
+ case 0:
+ {
+ if (!ModRegRm.Memory)
+ {
+ /* The second operand must be a memory location */
+ Fast486Exception(State, FAST486_EXCEPTION_UD);
+ return FALSE;
+ }
+
+ /* Fill the 6-byte table register */
+ RtlCopyMemory(TableReg, &State->Gdtr.Size, sizeof(USHORT));
+ RtlCopyMemory(&TableReg[sizeof(USHORT)], &State->Gdtr.Address,
sizeof(ULONG));
+
+ /* Store the GDTR */
+ return Fast486WriteMemory(State,
+ Segment,
+ ModRegRm.MemoryAddress,
+ TableReg,
+ sizeof(TableReg));
+ }
+
+ /* SIDT */
+ case 1:
+ {
+ if (!ModRegRm.Memory)
+ {
+ /* The second operand must be a memory location */
+ Fast486Exception(State, FAST486_EXCEPTION_UD);
+ return FALSE;
+ }
+
+ /* Fill the 6-byte table register */
+ RtlCopyMemory(TableReg, &State->Idtr.Size, sizeof(USHORT));
+ RtlCopyMemory(&TableReg[sizeof(USHORT)], &State->Idtr.Address,
sizeof(ULONG));
+
+ /* Store the IDTR */
+ return Fast486WriteMemory(State,
+ Segment,
+ ModRegRm.MemoryAddress,
+ TableReg,
+ sizeof(TableReg));
+ }
+
+ /* LGDT */
+ case 2:
+ {
+ /* This is a privileged instruction */
+ if (Fast486GetCurrentPrivLevel(State) != 0)
+ {
+ Fast486Exception(State, FAST486_EXCEPTION_GP);
+ return FALSE;
+ }
+
+ if (!ModRegRm.Memory)
+ {
+ /* The second operand must be a memory location */
+ Fast486Exception(State, FAST486_EXCEPTION_UD);
+ return FALSE;
+ }
+
+ /* Read the new GDTR */
+ if (!Fast486ReadMemory(State,
+ Segment,
+ ModRegRm.MemoryAddress,
+ FALSE,
+ TableReg,
+ sizeof(TableReg)))
+ {
+ /* Exception occurred */
+ return FALSE;
+ }
+
+ /* Load the new GDT */
+ State->Gdtr.Size = *((PUSHORT)TableReg);
+ State->Gdtr.Address = *((PULONG)&TableReg[sizeof(USHORT)]);
+
+ return TRUE;
+ }
+
+ /* LIDT */
+ case 3:
+ {
+ /* This is a privileged instruction */
+ if (Fast486GetCurrentPrivLevel(State) != 0)
+ {
+ Fast486Exception(State, FAST486_EXCEPTION_GP);
+ return FALSE;
+ }
+
+ if (!ModRegRm.Memory)
+ {
+ /* The second operand must be a memory location */
+ Fast486Exception(State, FAST486_EXCEPTION_UD);
+ return FALSE;
+ }
+
+ /* Read the new IDTR */
+ if (!Fast486ReadMemory(State,
+ Segment,
+ ModRegRm.MemoryAddress,
+ FALSE,
+ TableReg,
+ sizeof(TableReg)))
+ {
+ /* Exception occurred */
+ return FALSE;
+ }
+
+ /* Load the new IDT */
+ State->Idtr.Size = *((PUSHORT)TableReg);
+ State->Idtr.Address = *((PULONG)&TableReg[sizeof(USHORT)]);
+
+ return TRUE;
+ }
+
+ /* SMSW */
+ case 4:
+ {
+ /* Store the lower 16 bits of CR0 */
+ return Fast486WriteModrmWordOperands(State,
+ &ModRegRm,
+ FALSE,
+
LOWORD(State->ControlRegisters[FAST486_REG_CR0]));
+ }
+
+ /* LMSW */
+ case 6:
+ {
+ USHORT MasterStatusWord, Dummy;
+
+ /* This is a privileged instruction */
+ if (Fast486GetCurrentPrivLevel(State) != 0)
+ {
+ Fast486Exception(State, FAST486_EXCEPTION_GP);
+ return FALSE;
+ }
+
+ /* Read the new master status word */
+ if (!Fast486ReadModrmWordOperands(State, &ModRegRm, &Dummy,
&MasterStatusWord))
+ {
+ /* Exception occurred */
+ return FALSE;
+ }
+
+ /* This instruction cannot be used to return to real mode */
+ if ((State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE)
+ && !(MasterStatusWord & FAST486_CR0_PE))
+ {
+ Fast486Exception(State, FAST486_EXCEPTION_GP);
+ return FALSE;
+ }
+
+ /* Set the lowest 4 bits */
+ State->ControlRegisters[FAST486_REG_CR0] &= 0xFFFFFFF0;
+ State->ControlRegisters[FAST486_REG_CR0] |= MasterStatusWord & 0x0F;
+
+ return TRUE;
+ }
+
+ /* INVLPG */
+ case 7:
+ {
+ UNIMPLEMENTED;
+ return FALSE;
+ }
+
+ /* Invalid */
+ default:
+ {
+ Fast486Exception(State, FAST486_EXCEPTION_UD);
+ return FALSE;
+ }
+ }
+}
+
FAST486_OPCODE_HANDLER(Fast486OpcodeGroup0FB9)
{
FAST486_MOD_REG_RM ModRegRm;
Modified: branches/ntvdm/lib/fast486/opgroups.h
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/lib/fast486/opgroups.h?re…
==============================================================================
--- branches/ntvdm/lib/fast486/opgroups.h [iso-8859-1] (original)
+++ branches/ntvdm/lib/fast486/opgroups.h [iso-8859-1] Fri Nov 1 22:39:43 2013
@@ -42,6 +42,7 @@
FAST486_OPCODE_HANDLER(Fast486OpcodeGroupF7);
FAST486_OPCODE_HANDLER(Fast486OpcodeGroupFE);
FAST486_OPCODE_HANDLER(Fast486OpcodeGroupFF);
+FAST486_OPCODE_HANDLER(Fast486OpcodeGroup0F01);
FAST486_OPCODE_HANDLER(Fast486OpcodeGroup0FB9);
FAST486_OPCODE_HANDLER(Fast486OpcodeGroup0FBA);