Author: aandrejevic
Date: Sat Aug 17 15:20:47 2013
New Revision: 59760
URL:
http://svn.reactos.org/svn/reactos?rev=59760&view=rev
Log:
[SOFT386]
Implement Soft386ReadMemory, Soft386WriteMemory, Soft386StackPush and Soft386StackPop.
Added:
branches/ntvdm/lib/soft386/common.c (with props)
branches/ntvdm/lib/soft386/common.h (with props)
Modified:
branches/ntvdm/lib/soft386/CMakeLists.txt
branches/ntvdm/lib/soft386/soft386.c
Modified: branches/ntvdm/lib/soft386/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/lib/soft386/CMakeLists.tx…
==============================================================================
--- branches/ntvdm/lib/soft386/CMakeLists.txt [iso-8859-1] (original)
+++ branches/ntvdm/lib/soft386/CMakeLists.txt [iso-8859-1] Sat Aug 17 15:20:47 2013
@@ -1,6 +1,7 @@
include_directories(${REACTOS_SOURCE_DIR}/include/reactos/libs/soft386)
list(APPEND SOURCE
- soft386.c)
+ soft386.c
+ common.c)
add_library(soft386 ${SOURCE})
Added: branches/ntvdm/lib/soft386/common.c
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/lib/soft386/common.c?rev=…
==============================================================================
--- branches/ntvdm/lib/soft386/common.c (added)
+++ branches/ntvdm/lib/soft386/common.c [iso-8859-1] Sat Aug 17 15:20:47 2013
@@ -0,0 +1,302 @@
+/*
+ * COPYRIGHT: GPL - See COPYING in the top level directory
+ * PROJECT: 386/486 CPU Emulation Library
+ * FILE: common.c
+ * PURPOSE: Common functions used internally by Soft386.
+ * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include "common.h"
+
+/* PUBLIC FUNCTIONS ***********************************************************/
+
+inline
+BOOLEAN
+Soft386ReadMemory(PSOFT386_STATE State,
+ INT SegmentReg,
+ ULONG Offset,
+ BOOLEAN InstFetch,
+ PVOID Buffer,
+ ULONG Size)
+{
+ ULONG LinearAddress;
+ PSOFT386_SEG_REG CachedDescriptor;
+
+ ASSERT(SegmentReg < SOFT386_NUM_SEG_REGS);
+
+ /* Get the cached descriptor */
+ CachedDescriptor = &State->SegmentRegs[SegmentReg];
+
+ if ((Offset + Size) >= CachedDescriptor->Limit)
+ {
+ /* Read beyond limit */
+ // TODO: Generate exception #GP
+
+ return FALSE;
+ }
+
+ /* Check for protected mode */
+ if (State->ControlRegisters[0] & SOFT386_CR0_PE)
+ {
+ /* Privilege checks */
+
+ if (!CachedDescriptor->Present)
+ {
+ // TODO: Generate exception #NP
+ return FALSE;
+ }
+
+ if (GET_SEGMENT_DPL(CachedDescriptor->Selector) >
CachedDescriptor->Dpl)
+ {
+ // TODO: Generate exception #GP
+ return FALSE;
+ }
+
+ if (InstFetch)
+ {
+ if (!CachedDescriptor->Executable)
+ {
+ /* Data segment not executable */
+
+ // TODO: Generate exception #GP
+ return FALSE;
+ }
+ }
+ else
+ {
+ if (CachedDescriptor->Executable &&
(!CachedDescriptor->ReadWrite))
+ {
+ /* Code segment not readable */
+
+ // TODO: Generate exception #GP
+ return FALSE;
+ }
+ }
+ }
+
+ /* Find the linear address */
+ LinearAddress = CachedDescriptor->Base + Offset;
+
+ // TODO: Paging support!
+
+ /* Did the host provide a memory hook? */
+ if (State->MemReadCallback)
+ {
+ /* Yes, call the host */
+ State->MemReadCallback(State, LinearAddress, Buffer, Size);
+ }
+ else
+ {
+ /* Read the memory directly */
+ RtlMoveMemory(Buffer, (LPVOID)LinearAddress, Size);
+ }
+
+ return TRUE;
+}
+
+inline
+BOOLEAN
+Soft386WriteMemory(PSOFT386_STATE State,
+ INT SegmentReg,
+ ULONG Offset,
+ PVOID Buffer,
+ ULONG Size)
+{
+ ULONG LinearAddress;
+ PSOFT386_SEG_REG CachedDescriptor;
+
+ ASSERT(SegmentReg < SOFT386_NUM_SEG_REGS);
+
+ /* Get the cached descriptor */
+ CachedDescriptor = &State->SegmentRegs[SegmentReg];
+
+ if ((Offset + Size) >= CachedDescriptor->Limit)
+ {
+ /* Write beyond limit */
+ // TODO: Generate exception #GP
+
+ return FALSE;
+ }
+
+ /* Check for protected mode */
+ if (State->ControlRegisters[0] & SOFT386_CR0_PE)
+ {
+ /* Privilege checks */
+
+ if (!CachedDescriptor->Present)
+ {
+ // TODO: Generate exception #NP
+ return FALSE;
+ }
+
+ if (GET_SEGMENT_DPL(CachedDescriptor->Selector) >
CachedDescriptor->Dpl)
+ {
+ // TODO: Generate exception #GP
+ return FALSE;
+ }
+
+ if (CachedDescriptor->Executable)
+ {
+ /* Code segment not writable */
+
+ // TODO: Generate exception #GP
+ return FALSE;
+ }
+ else if (!CachedDescriptor->ReadWrite)
+ {
+ /* Data segment not writeable */
+
+ // TODO: Generate exception #GP
+ return FALSE;
+ }
+ }
+
+ /* Find the linear address */
+ LinearAddress = CachedDescriptor->Base + Offset;
+
+ // TODO: Paging support!
+
+ /* Did the host provide a memory hook? */
+ if (State->MemWriteCallback)
+ {
+ /* Yes, call the host */
+ State->MemWriteCallback(State, LinearAddress, Buffer, Size);
+ }
+ else
+ {
+ /* Write the memory directly */
+ RtlMoveMemory((LPVOID)LinearAddress, Buffer, Size);
+ }
+
+ return TRUE;
+}
+
+inline
+BOOLEAN
+Soft386StackPush(PSOFT386_STATE State, ULONG Value)
+{
+ BOOLEAN Size = State->SegmentRegs[SOFT386_REG_SS].Size;
+
+ // TODO: Handle OPSIZE prefix.
+
+ if (Size)
+ {
+ /* 32-bit size */
+
+ /* Check if ESP is between 1 and 3 */
+ if (State->GeneralRegs[SOFT386_REG_ESP].Long >= 1
+ && State->GeneralRegs[SOFT386_REG_ESP].Long <= 3)
+ {
+ // TODO: Exception #SS
+ return FALSE;
+ }
+
+ /* Subtract ESP by 4 */
+ State->GeneralRegs[SOFT386_REG_ESP].Long -= 4;
+
+ /* Store the value in SS:ESP */
+ return Soft386WriteMemory(State,
+ SOFT386_REG_SS,
+ State->GeneralRegs[SOFT386_REG_ESP].Long,
+ &Value,
+ sizeof(ULONG));
+ }
+ else
+ {
+ /* 16-bit size */
+ USHORT ShortValue = LOWORD(Value);
+
+ /* Check if SP is 1 */
+ if (State->GeneralRegs[SOFT386_REG_ESP].Long == 1)
+ {
+ // TODO: Exception #SS
+ return FALSE;
+ }
+
+ /* Subtract SP by 2 */
+ State->GeneralRegs[SOFT386_REG_ESP].LowWord -= 2;
+
+ /* Store the value in SS:SP */
+ return Soft386WriteMemory(State,
+ SOFT386_REG_SS,
+ State->GeneralRegs[SOFT386_REG_ESP].LowWord,
+ &ShortValue,
+ sizeof(USHORT));
+ }
+}
+
+inline
+BOOLEAN
+Soft386StackPop(PSOFT386_STATE State, PULONG Value)
+{
+ ULONG LongValue;
+ USHORT ShortValue;
+ BOOLEAN Size = State->SegmentRegs[SOFT386_REG_SS].Size;
+
+ // TODO: Handle OPSIZE prefix.
+
+ if (Size)
+ {
+ /* 32-bit size */
+
+ /* Check if ESP is 0xFFFFFFFF */
+ if (State->GeneralRegs[SOFT386_REG_ESP].Long == 0xFFFFFFFF)
+ {
+ // TODO: Exception #SS
+ return FALSE;
+ }
+
+ /* Read the value from SS:ESP */
+ if (!Soft386ReadMemory(State,
+ SOFT386_REG_SS,
+ State->GeneralRegs[SOFT386_REG_ESP].Long,
+ FALSE,
+ &LongValue,
+ sizeof(LongValue)))
+ {
+ /* An exception occurred */
+ return FALSE;
+ }
+
+ /* Increment ESP by 4 */
+ State->GeneralRegs[SOFT386_REG_ESP].Long += 4;
+
+ /* Store the value in the result */
+ *Value = LongValue;
+ }
+ else
+ {
+ /* 16-bit size */
+
+ /* Check if SP is 0xFFFF */
+ if (State->GeneralRegs[SOFT386_REG_ESP].LowWord == 0xFFFF)
+ {
+ // TODO: Exception #SS
+ return FALSE;
+ }
+
+ /* Read the value from SS:SP */
+ if (!Soft386ReadMemory(State,
+ SOFT386_REG_SS,
+ State->GeneralRegs[SOFT386_REG_ESP].LowWord,
+ FALSE,
+ &ShortValue,
+ sizeof(ShortValue)))
+ {
+ /* An exception occurred */
+ return FALSE;
+ }
+
+ /* Increment SP by 2 */
+ State->GeneralRegs[SOFT386_REG_ESP].Long += 2;
+
+ /* Store the value in the result */
+ *Value = ShortValue;
+ }
+
+ return TRUE;
+}
+
+/* EOF */
Propchange: branches/ntvdm/lib/soft386/common.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: branches/ntvdm/lib/soft386/common.h
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/lib/soft386/common.h?rev=…
==============================================================================
--- branches/ntvdm/lib/soft386/common.h (added)
+++ branches/ntvdm/lib/soft386/common.h [iso-8859-1] Sat Aug 17 15:20:47 2013
@@ -0,0 +1,63 @@
+/*
+ * COPYRIGHT: GPL - See COPYING in the top level directory
+ * PROJECT: 386/486 CPU Emulation Library
+ * FILE: common.h
+ * PURPOSE: Common functions used internally by Soft386 (header file).
+ * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
+ */
+
+#ifndef _COMMON_H_
+#define _COMMON_H_
+
+/* INCLUDES *******************************************************************/
+
+#include <soft386.h>
+
+/* DEFINES ********************************************************************/
+
+#define GET_SEGMENT_DPL(s) ((s) & 3)
+
+/* FUNCTIONS ******************************************************************/
+
+inline
+BOOLEAN
+Soft386ReadMemory
+(
+ PSOFT386_STATE State,
+ INT SegmentReg,
+ ULONG Offset,
+ BOOLEAN InstFetch,
+ PVOID Buffer,
+ ULONG Size
+);
+
+inline
+BOOLEAN
+Soft386WriteMemory
+(
+ PSOFT386_STATE State,
+ INT SegmentReg,
+ ULONG Offset,
+ PVOID Buffer,
+ ULONG Size
+);
+
+inline
+BOOLEAN
+Soft386StackPush
+(
+ PSOFT386_STATE State,
+ ULONG Value
+);
+
+inline
+BOOLEAN
+Soft386StackPop
+(
+ PSOFT386_STATE State,
+ PULONG Value
+);
+
+#endif // _COMMON_H_
+
+/* EOF */
Propchange: branches/ntvdm/lib/soft386/common.h
------------------------------------------------------------------------------
svn:eol-style = native
Modified: branches/ntvdm/lib/soft386/soft386.c
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/lib/soft386/soft386.c?rev…
==============================================================================
--- branches/ntvdm/lib/soft386/soft386.c [iso-8859-1] (original)
+++ branches/ntvdm/lib/soft386/soft386.c [iso-8859-1] Sat Aug 17 15:20:47 2013
@@ -8,7 +8,7 @@
/* INCLUDES *******************************************************************/
-#include "soft386.h"
+#include "common.h"
/* DEFINES ********************************************************************/
@@ -23,6 +23,7 @@
/* PRIVATE FUNCTIONS **********************************************************/
static
+inline
VOID
NTAPI
Soft386ExecutionControl(PSOFT386_STATE State, INT Command)
@@ -210,3 +211,5 @@
// TODO: NOT IMPLEMENTED!!!
UNIMPLEMENTED;
}
+
+/* EOF */