Author: aandrejevic
Date: Sat Oct 26 00:56:11 2013
New Revision: 60747
URL:
http://svn.reactos.org/svn/reactos?rev=60747&view=rev
Log:
[FAST486]
Implement the MOV instruction for control and debug registers.
Remove definitions for non-existant registers CR1, CR4, CR5, CR6 and CR7.
The standard 80486 doesn't have a CR4 register (although some implementations
of the 80486 had large page support and CR4, it was not reliable).
As for the debug registers, DR4 is the same as DR6, and DR5 is the same as DR7.
Modified:
branches/ntvdm/include/reactos/libs/fast486/fast486.h
branches/ntvdm/lib/fast486/extraops.c
branches/ntvdm/lib/fast486/extraops.h
branches/ntvdm/lib/fast486/fast486.c
Modified: branches/ntvdm/include/reactos/libs/fast486/fast486.h
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/include/reactos/libs/fast…
==============================================================================
--- branches/ntvdm/include/reactos/libs/fast486/fast486.h [iso-8859-1] (original)
+++ branches/ntvdm/include/reactos/libs/fast486/fast486.h [iso-8859-1] Sat Oct 26 00:56:11
2013
@@ -26,8 +26,8 @@
#define FAST486_NUM_GEN_REGS 8
#define FAST486_NUM_SEG_REGS 6
-#define FAST486_NUM_CTRL_REGS 8
-#define FAST486_NUM_DBG_REGS 8
+#define FAST486_NUM_CTRL_REGS 3
+#define FAST486_NUM_DBG_REGS 6
#define FAST486_CR0_PE (1 << 0)
#define FAST486_CR0_MP (1 << 1)
@@ -41,6 +41,33 @@
#define FAST486_CR0_CD (1 << 30)
#define FAST486_CR0_PG (1 << 31)
+#define FAST486_DR4_B0 (1 << 0)
+#define FAST486_DR4_B1 (1 << 1)
+#define FAST486_DR4_B2 (1 << 2)
+#define FAST486_DR4_B3 (1 << 3)
+#define FAST486_DR4_BD (1 << 13)
+#define FAST486_DR4_BS (1 << 14)
+#define FAST486_DR4_BT (1 << 15)
+
+#define FAST486_DR5_L0 (1 << 0)
+#define FAST486_DR5_G0 (1 << 1)
+#define FAST486_DR5_L1 (1 << 2)
+#define FAST486_DR5_G1 (1 << 3)
+#define FAST486_DR5_L2 (1 << 4)
+#define FAST486_DR5_G2 (1 << 5)
+#define FAST486_DR5_L3 (1 << 6)
+#define FAST486_DR5_G3 (1 << 7)
+#define FAST486_DR5_LE (1 << 8)
+#define FAST486_DR5_GE (1 << 9)
+#define FAST486_DR5_GD (1 << 13)
+
+#define FAST486_DBG_BREAK_EXEC 0
+#define FAST486_DBG_BREAK_WRITE 1
+#define FAST486_DBG_BREAK_READWRITE 3
+
+#define FAST486_DR4_RESERVED 0xFFFF1FF0
+#define FAST486_DR5_RESERVED 0x0000DC00
+
#define FAST486_IDT_TASK_GATE 0x5
#define FAST486_IDT_INT_GATE 0x6
#define FAST486_IDT_TRAP_GATE 0x7
@@ -81,26 +108,21 @@
typedef enum _FAST486_CTRL_REGS
{
- FAST486_REG_CR0,
- FAST486_REG_CR1,
- FAST486_REG_CR2,
- FAST486_REG_CR3,
- FAST486_REG_CR4,
- FAST486_REG_CR5,
- FAST486_REG_CR6,
- FAST486_REG_CR7
+ FAST486_REG_CR0 = 0,
+ FAST486_REG_CR2 = 1,
+ FAST486_REG_CR3 = 2,
} FAST486_CTRL_REGS, *PFAST486_CTRL_REGS;
typedef enum _FAST486_DBG_REGS
{
- FAST486_REG_DR0,
- FAST486_REG_DR1,
- FAST486_REG_DR2,
- FAST486_REG_DR3,
- FAST486_REG_DR4,
- FAST486_REG_DR5,
- FAST486_REG_DR6,
- FAST486_REG_DR7
+ FAST486_REG_DR0 = 0,
+ FAST486_REG_DR1 = 1,
+ FAST486_REG_DR2 = 2,
+ FAST486_REG_DR3 = 3,
+ FAST486_REG_DR4 = 4,
+ FAST486_REG_DR5 = 5,
+ FAST486_REG_DR6 = 4, // alias to DR4
+ FAST486_REG_DR7 = 5 // alias to DR5
} FAST486_DBG_REGS, *PFAST486_DBG_REGS;
typedef enum _FAST486_EXCEPTIONS
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] Sat Oct 26 00:56:11 2013
@@ -71,10 +71,10 @@
NULL, // Invalid
NULL, // Invalid
NULL, // Invalid
- NULL, // TODO: OPCODE 0x20 NOT IMPLEMENTED
- NULL, // TODO: OPCODE 0x21 NOT IMPLEMENTED
- NULL, // TODO: OPCODE 0x22 NOT IMPLEMENTED
- NULL, // TODO: OPCODE 0x23 NOT IMPLEMENTED
+ Fast486ExtOpcodeStoreControlReg,
+ Fast486ExtOpcodeStoreDebugReg,
+ Fast486ExtOpcodeLoadControlReg,
+ Fast486ExtOpcodeLoadDebugReg,
NULL, // TODO: OPCODE 0x24 NOT IMPLEMENTED
NULL, // Invalid
NULL, // TODO: OPCODE 0x26 NOT IMPLEMENTED
@@ -209,7 +209,7 @@
NULL, // Invalid
Fast486ExtOpcodePushGs,
Fast486ExtOpcodePopGs,
- NULL, // TODO: OPCODE 0xAA NOT IMPLEMENTED
+ NULL, // Invalid
Fast486ExtOpcodeBts,
NULL, // TODO: OPCODE 0xAC NOT IMPLEMENTED
NULL, // TODO: OPCODE 0xAD NOT IMPLEMENTED
@@ -299,6 +299,202 @@
/* PUBLIC FUNCTIONS ***********************************************************/
+FAST486_OPCODE_HANDLER(Fast486ExtOpcodeStoreControlReg)
+{
+ BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
+ FAST486_MOD_REG_RM ModRegRm;
+
+ NO_LOCK_PREFIX();
+ TOGGLE_ADSIZE(AddressSize);
+
+ /* Get the operands */
+ if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
+ {
+ /* Exception occurred */
+ return FALSE;
+ }
+
+ /* The current privilege level must be zero */
+ if (Fast486GetCurrentPrivLevel(State) != 0)
+ {
+ Fast486Exception(State, FAST486_EXCEPTION_GP);
+ return FALSE;
+ }
+
+ if ((ModRegRm.Register == 1) || (ModRegRm.Register > 3))
+ {
+ /* CR1, CR4, CR5, CR6 and CR7 don't exist */
+ Fast486Exception(State, FAST486_EXCEPTION_UD);
+ return FALSE;
+ }
+
+ if (ModRegRm.Register != 0)
+ {
+ /* CR2 and CR3 and are stored in array indexes 1 and 2 */
+ ModRegRm.Register--;
+ }
+
+ /* Store the value of the control register */
+ State->GeneralRegs[ModRegRm.SecondRegister].Long =
State->ControlRegisters[ModRegRm.Register];
+
+ /* Return success */
+ return TRUE;
+}
+
+FAST486_OPCODE_HANDLER(Fast486ExtOpcodeStoreDebugReg)
+{
+ BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
+ FAST486_MOD_REG_RM ModRegRm;
+
+ NO_LOCK_PREFIX();
+ TOGGLE_ADSIZE(AddressSize);
+
+ /* Get the operands */
+ if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
+ {
+ /* Exception occurred */
+ return FALSE;
+ }
+
+ /* The current privilege level must be zero */
+ if (Fast486GetCurrentPrivLevel(State) != 0)
+ {
+ Fast486Exception(State, FAST486_EXCEPTION_GP);
+ return FALSE;
+ }
+
+ if ((ModRegRm.Register == 6) || (ModRegRm.Register == 7))
+ {
+ /* DR6 and DR7 are aliases to DR4 and DR5 */
+ ModRegRm.Register -= 2;
+ }
+
+ if (State->DebugRegisters[FAST486_REG_DR5] & FAST486_DR5_GD)
+ {
+ /* Disallow access to debug registers */
+ Fast486Exception(State, FAST486_EXCEPTION_GP);
+ return FALSE;
+ }
+
+ /* Store the value of the debug register */
+ State->GeneralRegs[ModRegRm.SecondRegister].Long =
State->DebugRegisters[ModRegRm.Register];
+
+ /* Return success */
+ return TRUE;
+}
+
+FAST486_OPCODE_HANDLER(Fast486ExtOpcodeLoadControlReg)
+{
+ ULONG Value;
+ BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
+ FAST486_MOD_REG_RM ModRegRm;
+
+ NO_LOCK_PREFIX();
+ TOGGLE_ADSIZE(AddressSize);
+
+ /* Get the operands */
+ if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
+ {
+ /* Exception occurred */
+ return FALSE;
+ }
+
+ /* The current privilege level must be zero */
+ if (Fast486GetCurrentPrivLevel(State) != 0)
+ {
+ Fast486Exception(State, FAST486_EXCEPTION_GP);
+ return FALSE;
+ }
+
+ if ((ModRegRm.Register == 1) || (ModRegRm.Register > 3))
+ {
+ /* CR1, CR4, CR5, CR6 and CR7 don't exist */
+ Fast486Exception(State, FAST486_EXCEPTION_UD);
+ return FALSE;
+ }
+
+ if (ModRegRm.Register != 0)
+ {
+ /* CR2 and CR3 and are stored in array indexes 1 and 2 */
+ ModRegRm.Register--;
+ }
+
+ /* Get the value */
+ Value = State->GeneralRegs[ModRegRm.SecondRegister].Long;
+
+ if (ModRegRm.Register == (INT)FAST486_REG_CR0)
+ {
+ /* CR0 checks */
+
+ if (((Value & (FAST486_CR0_PG | FAST486_CR0_PE)) == FAST486_CR0_PG)
+ || ((Value & (FAST486_CR0_CD | FAST486_CR0_NW)) == FAST486_CR0_NW))
+ {
+ /* Invalid value */
+ Fast486Exception(State, FAST486_EXCEPTION_GP);
+ return FALSE;
+ }
+ }
+
+ /* Load a value to the control register */
+ State->ControlRegisters[ModRegRm.Register] = Value;
+
+ /* Return success */
+ return TRUE;
+}
+
+FAST486_OPCODE_HANDLER(Fast486ExtOpcodeLoadDebugReg)
+{
+ BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
+ FAST486_MOD_REG_RM ModRegRm;
+
+ NO_LOCK_PREFIX();
+ TOGGLE_ADSIZE(AddressSize);
+
+ /* Get the operands */
+ if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
+ {
+ /* Exception occurred */
+ return FALSE;
+ }
+
+ /* The current privilege level must be zero */
+ if (Fast486GetCurrentPrivLevel(State) != 0)
+ {
+ Fast486Exception(State, FAST486_EXCEPTION_GP);
+ return FALSE;
+ }
+
+ if ((ModRegRm.Register == 6) || (ModRegRm.Register == 7))
+ {
+ /* DR6 and DR7 are aliases to DR4 and DR5 */
+ ModRegRm.Register -= 2;
+ }
+
+ if (State->DebugRegisters[FAST486_REG_DR5] & FAST486_DR5_GD)
+ {
+ /* Disallow access to debug registers */
+ Fast486Exception(State, FAST486_EXCEPTION_GP);
+ return FALSE;
+ }
+
+ /* Load a value to the debug register */
+ State->DebugRegisters[ModRegRm.Register] =
State->GeneralRegs[ModRegRm.SecondRegister].Long;
+
+ if (ModRegRm.Register == (INT)FAST486_REG_DR4)
+ {
+ /* The reserved bits are 1 */
+ State->DebugRegisters[ModRegRm.Register] |= FAST486_DR4_RESERVED;
+ }
+ else if (ModRegRm.Register == (INT)FAST486_REG_DR5)
+ {
+ /* The reserved bits are 0 */
+ State->DebugRegisters[ModRegRm.Register] &= ~FAST486_DR5_RESERVED;
+ }
+
+ /* Return success */
+ return TRUE;
+}
+
FAST486_OPCODE_HANDLER(Fast486ExtOpcodePushFs)
{
/* Call the internal API */
@@ -1062,3 +1258,4 @@
return FALSE;
}
}
+
Modified: branches/ntvdm/lib/fast486/extraops.h
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/lib/fast486/extraops.h?re…
==============================================================================
--- branches/ntvdm/lib/fast486/extraops.h [iso-8859-1] (original)
+++ branches/ntvdm/lib/fast486/extraops.h [iso-8859-1] Sat Oct 26 00:56:11 2013
@@ -23,6 +23,10 @@
#define _EXTRAOPS_H_
/* DEFINES ********************************************************************/
+FAST486_OPCODE_HANDLER(Fast486ExtOpcodeStoreControlReg);
+FAST486_OPCODE_HANDLER(Fast486ExtOpcodeStoreDebugReg);
+FAST486_OPCODE_HANDLER(Fast486ExtOpcodeLoadControlReg);
+FAST486_OPCODE_HANDLER(Fast486ExtOpcodeLoadDebugReg);
FAST486_OPCODE_HANDLER(Fast486ExtOpcodePushFs);
FAST486_OPCODE_HANDLER(Fast486ExtOpcodePopFs);
FAST486_OPCODE_HANDLER(Fast486ExtOpcodeBitTest);
Modified: branches/ntvdm/lib/fast486/fast486.c
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/lib/fast486/fast486.c?rev…
==============================================================================
--- branches/ntvdm/lib/fast486/fast486.c [iso-8859-1] (original)
+++ branches/ntvdm/lib/fast486/fast486.c [iso-8859-1] Sat Oct 26 00:56:11 2013
@@ -217,27 +217,19 @@
State->Flags.Vip ? "VIP" : "vip",
State->Flags.Iopl);
DPRINT1("\nControl Registers:\n"
- "CR0 = %08X\tCR1 = %08X\tCR2 = %08X\tCR3 = %08X\n"
- "CR4 = %08X\tCR5 = %08X\tCR6 = %08X\tCR7 = %08X\n",
+ "CR0 = %08X\tCR2 = %08X\tCR3 = %08X\n",
State->ControlRegisters[FAST486_REG_CR0],
- State->ControlRegisters[FAST486_REG_CR1],
State->ControlRegisters[FAST486_REG_CR2],
- State->ControlRegisters[FAST486_REG_CR3],
- State->ControlRegisters[FAST486_REG_CR4],
- State->ControlRegisters[FAST486_REG_CR5],
- State->ControlRegisters[FAST486_REG_CR6],
- State->ControlRegisters[FAST486_REG_CR7]);
+ State->ControlRegisters[FAST486_REG_CR3]);
DPRINT1("\nDebug Registers:\n"
- "DR0 = %08X\tDR1 = %08X\tDR2 = %08X\tDR3 = %08X\n"
- "DR4 = %08X\tDR5 = %08X\tDR6 = %08X\tDR7 = %08X\n",
+ "DR0 = %08X\tDR1 = %08X\tDR2 = %08X\n"
+ "DR3 = %08X\tDR4 = %08X\tDR5 = %08X\n",
State->DebugRegisters[FAST486_REG_DR0],
State->DebugRegisters[FAST486_REG_DR1],
State->DebugRegisters[FAST486_REG_DR2],
State->DebugRegisters[FAST486_REG_DR3],
State->DebugRegisters[FAST486_REG_DR4],
- State->DebugRegisters[FAST486_REG_DR5],
- State->DebugRegisters[FAST486_REG_DR6],
- State->DebugRegisters[FAST486_REG_DR7]);
+ State->DebugRegisters[FAST486_REG_DR5]);
}
VOID