[SOFT386]

Add checks for illegal prefixes.
Implement HLT and PAUSE.


svn path=/branches/ntvdm/; revision=59890
This commit is contained in:
Aleksandar Andrejevic 2013-08-29 22:07:53 +00:00
parent 5a14da958f
commit c0a39279ae
3 changed files with 83 additions and 1 deletions

View file

@ -150,6 +150,13 @@ VOID
ULONG Size
);
typedef
VOID
(NTAPI *SOFT386_IDLE_PROC)
(
PSOFT386_STATE State
);
typedef union _SOFT386_REG
{
struct
@ -280,6 +287,7 @@ struct _SOFT386_STATE
SOFT386_MEM_WRITE_PROC MemWriteCallback;
SOFT386_IO_READ_PROC IoReadCallback;
SOFT386_IO_WRITE_PROC IoWriteCallback;
SOFT386_IDLE_PROC IdleCallback;
SOFT386_REG GeneralRegs[SOFT386_NUM_GEN_REGS];
SOFT386_SEG_REG SegmentRegs[SOFT386_NUM_SEG_REGS];
SOFT386_REG InstPtr;
@ -291,6 +299,7 @@ struct _SOFT386_STATE
ULONG ExceptionCount;
ULONG PrefixFlags;
INT SegmentOverride;
BOOLEAN HardwareInt;
};
/* FUNCTIONS ******************************************************************/

View file

@ -600,7 +600,8 @@ Soft386OpcodeNop(PSOFT386_STATE State, UCHAR Opcode)
if (State->PrefixFlags & SOFT386_PREFIX_REP)
{
// TODO: Handle PAUSE instruction.
/* Idle cycle */
State->IdleCallback(State);
}
return TRUE;
@ -748,6 +749,13 @@ Soft386OpcodeClearCarry(PSOFT386_STATE State, UCHAR Opcode)
/* Make sure this is the right instruction */
ASSERT(Opcode == 0xF8);
/* No prefixes allowed */
if (State->PrefixFlags)
{
Soft386Exception(State, SOFT386_EXCEPTION_UD);
return FALSE;
}
/* Clear CF and return success */
State->Flags.Cf = FALSE;
return TRUE;
@ -760,6 +768,13 @@ Soft386OpcodeSetCarry(PSOFT386_STATE State, UCHAR Opcode)
/* Make sure this is the right instruction */
ASSERT(Opcode == 0xF9);
/* No prefixes allowed */
if (State->PrefixFlags)
{
Soft386Exception(State, SOFT386_EXCEPTION_UD);
return FALSE;
}
/* Set CF and return success*/
State->Flags.Cf = TRUE;
return TRUE;
@ -772,6 +787,13 @@ Soft386OpcodeClearInt(PSOFT386_STATE State, UCHAR Opcode)
/* Make sure this is the right instruction */
ASSERT(Opcode == 0xFA);
/* No prefixes allowed */
if (State->PrefixFlags)
{
Soft386Exception(State, SOFT386_EXCEPTION_UD);
return FALSE;
}
/* Check for protected mode */
if (State->ControlRegisters[SOFT386_REG_CR0] & SOFT386_CR0_PE)
{
@ -805,6 +827,13 @@ Soft386OpcodeSetInt(PSOFT386_STATE State, UCHAR Opcode)
/* Make sure this is the right instruction */
ASSERT(Opcode == 0xFB);
/* No prefixes allowed */
if (State->PrefixFlags)
{
Soft386Exception(State, SOFT386_EXCEPTION_UD);
return FALSE;
}
/* Check for protected mode */
if (State->ControlRegisters[SOFT386_REG_CR0] & SOFT386_CR0_PE)
{
@ -838,6 +867,13 @@ Soft386OpcodeClearDir(PSOFT386_STATE State, UCHAR Opcode)
/* Make sure this is the right instruction */
ASSERT(Opcode == 0xFC);
/* No prefixes allowed */
if (State->PrefixFlags)
{
Soft386Exception(State, SOFT386_EXCEPTION_UD);
return FALSE;
}
/* Clear DF and return success */
State->Flags.Df = FALSE;
return TRUE;
@ -850,7 +886,42 @@ Soft386OpcodeSetDir(PSOFT386_STATE State, UCHAR Opcode)
/* Make sure this is the right instruction */
ASSERT(Opcode == 0xFD);
/* No prefixes allowed */
if (State->PrefixFlags)
{
Soft386Exception(State, SOFT386_EXCEPTION_UD);
return FALSE;
}
/* Set DF and return success*/
State->Flags.Df = TRUE;
return TRUE;
}
BOOLEAN
FASTCALL
Soft386OpcodeHalt(PSOFT386_STATE State, UCHAR Opcode)
{
/* Make sure this is the right instruction */
ASSERT(Opcode == 0xF4);
/* No prefixes allowed */
if (State->PrefixFlags)
{
Soft386Exception(State, SOFT386_EXCEPTION_UD);
return FALSE;
}
/* Privileged instructions can only be executed under CPL = 0 */
if (State->SegmentRegs[SOFT386_REG_CS].Dpl != 0)
{
Soft386Exception(State, SOFT386_EXCEPTION_GP);
return FALSE;
}
/* Halt */
while (!State->HardwareInt) State->IdleCallback(State);
/* Return success */
return TRUE;
}

View file

@ -201,6 +201,7 @@ Soft386Reset(PSOFT386_STATE State)
SOFT386_MEM_WRITE_PROC MemWriteCallback = State->MemWriteCallback;
SOFT386_IO_READ_PROC IoReadCallback = State->IoReadCallback;
SOFT386_IO_WRITE_PROC IoWriteCallback = State->IoWriteCallback;
SOFT386_IDLE_PROC IdleCallback = State->IdleCallback;
/* Clear the entire structure */
RtlZeroMemory(State, sizeof(*State));
@ -234,6 +235,7 @@ Soft386Reset(PSOFT386_STATE State)
State->MemWriteCallback = MemWriteCallback;
State->IoReadCallback = IoReadCallback;
State->IoWriteCallback = IoWriteCallback;
State->IdleCallback = IdleCallback;
}
VOID