mirror of
https://github.com/reactos/reactos.git
synced 2025-08-10 22:55:38 +00:00
Sync with trunk r63192.
svn path=/branches/condrv_restructure/; revision=63193
This commit is contained in:
commit
7a0c3bde06
192 changed files with 39769 additions and 5166 deletions
|
@ -58,7 +58,6 @@ VOID Usage(VOID)
|
|||
int _tmain (int argc, TCHAR *argv[])
|
||||
{
|
||||
INT i;
|
||||
INT LineLen1, LineLen2;
|
||||
FILE *fp1, *fp2; // file pointers
|
||||
PTCHAR Line1 = (TCHAR *)malloc(STRBUF * sizeof(TCHAR));
|
||||
PTCHAR Line2 = (TCHAR *)malloc(STRBUF * sizeof(TCHAR));
|
||||
|
@ -156,8 +155,8 @@ int _tmain (int argc, TCHAR *argv[])
|
|||
|
||||
_tprintf(_T("Comparing %s and %s...\n"), File1, File2);
|
||||
|
||||
while ((LineLen1 = GetLine(Line1, fp1) != 0) &&
|
||||
(LineLen2 = GetLine(Line2, fp2) != 0))
|
||||
while ((GetLine(Line1, fp1) != 0) &&
|
||||
(GetLine(Line2, fp2) != 0))
|
||||
{
|
||||
// LineCount++;
|
||||
while ((*Line1 != '\0') && (*Line2 != '\0'))
|
||||
|
|
|
@ -268,7 +268,7 @@ UpdateViewMenu(PMAIN_WND_INFO Info)
|
|||
|
||||
CheckMenuItem(hMenu,
|
||||
IDC_SHOWHIDDEN,
|
||||
MF_BYCOMMAND | (Info->bShowHidden) ? MF_CHECKED : MF_UNCHECKED);
|
||||
MF_BYCOMMAND | (Info->bShowHidden ? MF_CHECKED : MF_UNCHECKED));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1303,13 +1303,13 @@ void shell(int argc, const char *argv[])
|
|||
|
||||
if (argc > 1)
|
||||
{
|
||||
strncat(CmdLine, " /C", MAX_PATH);
|
||||
strncat(CmdLine, " /C", MAX_PATH - strlen(CmdLine) - 1);
|
||||
}
|
||||
|
||||
for (i=1; i<argc; i++)
|
||||
{
|
||||
strncat(CmdLine, " ", MAX_PATH);
|
||||
strncat(CmdLine, argv[i], MAX_PATH);
|
||||
strncat(CmdLine, " ", MAX_PATH - strlen(CmdLine) - 1);
|
||||
strncat(CmdLine, argv[i], MAX_PATH - strlen(CmdLine) - 1);
|
||||
}
|
||||
|
||||
StartupInfo.cb = sizeof( StartupInfo );
|
||||
|
|
|
@ -333,8 +333,8 @@ LPTSTR GetConnectionDescription(LPTSTR lpClass)
|
|||
(PBYTE)lpKeyClass,
|
||||
&dwDataSize) != ERROR_SUCCESS)
|
||||
{
|
||||
lpKeyClass = NULL;
|
||||
HeapFree(ProcessHeap, 0, lpKeyClass);
|
||||
lpKeyClass = NULL;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -709,7 +709,7 @@ char* TANSIParser::ParseEscapeANSI(char* pszBuffer, char* pszBufferEnd)
|
|||
case 'n':
|
||||
if (iCurrentParam == 1 && iParam[0]==5) {
|
||||
// report the cursor position
|
||||
Network.WriteString("\x1B[0n", 6);
|
||||
Network.WriteString("\x1B[0n", 4);
|
||||
break;
|
||||
}
|
||||
if (iCurrentParam == 1 && iParam[0]==6){
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -30,116 +30,116 @@
|
|||
|
||||
typedef enum _FORMATSTATE
|
||||
{
|
||||
Unformatted,
|
||||
UnformattedOrDamaged,
|
||||
UnknownFormat,
|
||||
Preformatted,
|
||||
Formatted
|
||||
Unformatted,
|
||||
UnformattedOrDamaged,
|
||||
UnknownFormat,
|
||||
Preformatted,
|
||||
Formatted
|
||||
} FORMATSTATE, *PFORMATSTATE;
|
||||
|
||||
|
||||
typedef struct _PARTENTRY
|
||||
{
|
||||
LIST_ENTRY ListEntry;
|
||||
LIST_ENTRY ListEntry;
|
||||
|
||||
CHAR DriveLetter[4];
|
||||
CHAR VolumeLabel[17];
|
||||
CHAR FileSystemName[9];
|
||||
CHAR DriveLetter[4];
|
||||
CHAR VolumeLabel[17];
|
||||
CHAR FileSystemName[9];
|
||||
|
||||
/* Partition is unused disk space */
|
||||
BOOLEAN Unpartitioned;
|
||||
/* Partition is unused disk space */
|
||||
BOOLEAN Unpartitioned;
|
||||
|
||||
/* Partition is new. Table does not exist on disk yet */
|
||||
BOOLEAN New;
|
||||
/* Partition is new. Table does not exist on disk yet */
|
||||
BOOLEAN New;
|
||||
|
||||
/* Partition was created automatically. */
|
||||
BOOLEAN AutoCreate;
|
||||
/* Partition was created automatically. */
|
||||
BOOLEAN AutoCreate;
|
||||
|
||||
FORMATSTATE FormatState;
|
||||
FORMATSTATE FormatState;
|
||||
|
||||
/*
|
||||
* Raw offset and length of the unpartitioned disk space.
|
||||
* Includes the leading, not yet existing, partition table.
|
||||
*/
|
||||
ULONGLONG UnpartitionedOffset;
|
||||
ULONGLONG UnpartitionedLength;
|
||||
/*
|
||||
* Raw offset and length of the unpartitioned disk space.
|
||||
* Includes the leading, not yet existing, partition table.
|
||||
*/
|
||||
ULONGLONG UnpartitionedOffset;
|
||||
ULONGLONG UnpartitionedLength;
|
||||
|
||||
PARTITION_INFORMATION PartInfo[4];
|
||||
PARTITION_INFORMATION PartInfo[4];
|
||||
|
||||
} PARTENTRY, *PPARTENTRY;
|
||||
|
||||
|
||||
typedef struct _BIOSDISKENTRY
|
||||
{
|
||||
LIST_ENTRY ListEntry;
|
||||
ULONG DiskNumber;
|
||||
ULONG Signature;
|
||||
ULONG Checksum;
|
||||
BOOLEAN Recognized;
|
||||
CM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry;
|
||||
CM_INT13_DRIVE_PARAMETER Int13DiskData;
|
||||
LIST_ENTRY ListEntry;
|
||||
ULONG DiskNumber;
|
||||
ULONG Signature;
|
||||
ULONG Checksum;
|
||||
BOOLEAN Recognized;
|
||||
CM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry;
|
||||
CM_INT13_DRIVE_PARAMETER Int13DiskData;
|
||||
} BIOSDISKENTRY, *PBIOSDISKENTRY;
|
||||
|
||||
|
||||
typedef struct _DISKENTRY
|
||||
{
|
||||
LIST_ENTRY ListEntry;
|
||||
LIST_ENTRY ListEntry;
|
||||
|
||||
ULONGLONG Cylinders;
|
||||
ULONGLONG TracksPerCylinder;
|
||||
ULONGLONG SectorsPerTrack;
|
||||
ULONGLONG BytesPerSector;
|
||||
ULONGLONG Cylinders;
|
||||
ULONGLONG TracksPerCylinder;
|
||||
ULONGLONG SectorsPerTrack;
|
||||
ULONGLONG BytesPerSector;
|
||||
|
||||
ULONGLONG DiskSize;
|
||||
ULONGLONG CylinderSize;
|
||||
ULONGLONG TrackSize;
|
||||
ULONGLONG DiskSize;
|
||||
ULONGLONG CylinderSize;
|
||||
ULONGLONG TrackSize;
|
||||
|
||||
BOOLEAN BiosFound;
|
||||
ULONG BiosDiskNumber;
|
||||
ULONG Signature;
|
||||
ULONG Checksum;
|
||||
BOOLEAN BiosFound;
|
||||
ULONG BiosDiskNumber;
|
||||
ULONG Signature;
|
||||
ULONG Checksum;
|
||||
|
||||
ULONG DiskNumber;
|
||||
USHORT Port;
|
||||
USHORT Bus;
|
||||
USHORT Id;
|
||||
ULONG DiskNumber;
|
||||
USHORT Port;
|
||||
USHORT Bus;
|
||||
USHORT Id;
|
||||
|
||||
/* Has the partition list been modified? */
|
||||
BOOLEAN Modified;
|
||||
/* Has the partition list been modified? */
|
||||
BOOLEAN Modified;
|
||||
|
||||
BOOLEAN NewDisk;
|
||||
BOOLEAN NoMbr; /* MBR is absent */
|
||||
BOOLEAN NewDisk;
|
||||
BOOLEAN NoMbr; /* MBR is absent */
|
||||
|
||||
UNICODE_STRING DriverName;
|
||||
UNICODE_STRING DriverName;
|
||||
|
||||
LIST_ENTRY PartListHead;
|
||||
LIST_ENTRY PartListHead;
|
||||
|
||||
} DISKENTRY, *PDISKENTRY;
|
||||
|
||||
|
||||
typedef struct _PARTLIST
|
||||
{
|
||||
SHORT Left;
|
||||
SHORT Top;
|
||||
SHORT Right;
|
||||
SHORT Bottom;
|
||||
SHORT Left;
|
||||
SHORT Top;
|
||||
SHORT Right;
|
||||
SHORT Bottom;
|
||||
|
||||
SHORT Line;
|
||||
SHORT Offset;
|
||||
SHORT Line;
|
||||
SHORT Offset;
|
||||
|
||||
ULONG TopDisk;
|
||||
ULONG TopPartition;
|
||||
ULONG TopDisk;
|
||||
ULONG TopPartition;
|
||||
|
||||
PDISKENTRY CurrentDisk;
|
||||
PPARTENTRY CurrentPartition;
|
||||
UCHAR CurrentPartitionNumber;
|
||||
PDISKENTRY CurrentDisk;
|
||||
PPARTENTRY CurrentPartition;
|
||||
UCHAR CurrentPartitionNumber;
|
||||
|
||||
PDISKENTRY ActiveBootDisk;
|
||||
PPARTENTRY ActiveBootPartition;
|
||||
UCHAR ActiveBootPartitionNumber;
|
||||
PDISKENTRY ActiveBootDisk;
|
||||
PPARTENTRY ActiveBootPartition;
|
||||
UCHAR ActiveBootPartitionNumber;
|
||||
|
||||
LIST_ENTRY DiskListHead;
|
||||
LIST_ENTRY BiosDiskListHead;
|
||||
LIST_ENTRY DiskListHead;
|
||||
LIST_ENTRY BiosDiskListHead;
|
||||
|
||||
} PARTLIST, *PPARTLIST;
|
||||
|
||||
|
@ -149,76 +149,90 @@ typedef struct _PARTLIST
|
|||
|
||||
typedef struct _PARTITION
|
||||
{
|
||||
unsigned char BootFlags; /* bootable? 0=no, 128=yes */
|
||||
unsigned char StartingHead; /* beginning head number */
|
||||
unsigned char StartingSector; /* beginning sector number */
|
||||
unsigned char StartingCylinder; /* 10 bit nmbr, with high 2 bits put in begsect */
|
||||
unsigned char PartitionType; /* Operating System type indicator code */
|
||||
unsigned char EndingHead; /* ending head number */
|
||||
unsigned char EndingSector; /* ending sector number */
|
||||
unsigned char EndingCylinder; /* also a 10 bit nmbr, with same high 2 bit trick */
|
||||
unsigned int StartingBlock; /* first sector relative to start of disk */
|
||||
unsigned int SectorCount; /* number of sectors in partition */
|
||||
unsigned char BootFlags; /* bootable? 0=no, 128=yes */
|
||||
unsigned char StartingHead; /* beginning head number */
|
||||
unsigned char StartingSector; /* beginning sector number */
|
||||
unsigned char StartingCylinder; /* 10 bit nmbr, with high 2 bits put in begsect */
|
||||
unsigned char PartitionType; /* Operating System type indicator code */
|
||||
unsigned char EndingHead; /* ending head number */
|
||||
unsigned char EndingSector; /* ending sector number */
|
||||
unsigned char EndingCylinder; /* also a 10 bit nmbr, with same high 2 bit trick */
|
||||
unsigned int StartingBlock; /* first sector relative to start of disk */
|
||||
unsigned int SectorCount; /* number of sectors in partition */
|
||||
} PARTITION, *PPARTITION;
|
||||
|
||||
typedef struct _PARTITION_SECTOR
|
||||
{
|
||||
UCHAR BootCode[440]; /* 0x000 */
|
||||
ULONG Signature; /* 0x1B8 */
|
||||
UCHAR Reserved[2]; /* 0x1BC */
|
||||
PARTITION Partition[PARTITION_TBL_SIZE]; /* 0x1BE */
|
||||
USHORT Magic; /* 0x1FE */
|
||||
UCHAR BootCode[440]; /* 0x000 */
|
||||
ULONG Signature; /* 0x1B8 */
|
||||
UCHAR Reserved[2]; /* 0x1BC */
|
||||
PARTITION Partition[PARTITION_TBL_SIZE]; /* 0x1BE */
|
||||
USHORT Magic; /* 0x1FE */
|
||||
} PARTITION_SECTOR, *PPARTITION_SECTOR;
|
||||
|
||||
#include <poppack.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
LIST_ENTRY ListEntry;
|
||||
ULONG DiskNumber;
|
||||
ULONG Idendifier;
|
||||
ULONG Signature;
|
||||
LIST_ENTRY ListEntry;
|
||||
ULONG DiskNumber;
|
||||
ULONG Idendifier;
|
||||
ULONG Signature;
|
||||
} BIOS_DISK, *PBIOS_DISK;
|
||||
|
||||
PPARTLIST
|
||||
CreatePartitionList (SHORT Left,
|
||||
SHORT Top,
|
||||
SHORT Right,
|
||||
SHORT Bottom);
|
||||
CreatePartitionList(
|
||||
SHORT Left,
|
||||
SHORT Top,
|
||||
SHORT Right,
|
||||
SHORT Bottom);
|
||||
|
||||
VOID
|
||||
DestroyPartitionList (PPARTLIST List);
|
||||
DestroyPartitionList(
|
||||
PPARTLIST List);
|
||||
|
||||
VOID
|
||||
DrawPartitionList (PPARTLIST List);
|
||||
DrawPartitionList(
|
||||
PPARTLIST List);
|
||||
|
||||
DWORD
|
||||
SelectPartition(PPARTLIST List, ULONG DiskNumber, ULONG PartitionNumber);
|
||||
SelectPartition(
|
||||
PPARTLIST List,
|
||||
ULONG DiskNumber,
|
||||
ULONG PartitionNumber);
|
||||
|
||||
BOOL
|
||||
SetMountedDeviceValues(PPARTLIST List);
|
||||
SetMountedDeviceValues(
|
||||
PPARTLIST List);
|
||||
|
||||
VOID
|
||||
ScrollDownPartitionList (PPARTLIST List);
|
||||
ScrollDownPartitionList(
|
||||
PPARTLIST List);
|
||||
|
||||
VOID
|
||||
ScrollUpPartitionList (PPARTLIST List);
|
||||
ScrollUpPartitionList(
|
||||
PPARTLIST List);
|
||||
|
||||
VOID
|
||||
CreateNewPartition (PPARTLIST List,
|
||||
ULONGLONG PartitionSize,
|
||||
BOOLEAN AutoCreate);
|
||||
CreateNewPartition(
|
||||
PPARTLIST List,
|
||||
ULONGLONG PartitionSize,
|
||||
BOOLEAN AutoCreate);
|
||||
|
||||
VOID
|
||||
DeleteCurrentPartition (PPARTLIST List);
|
||||
DeleteCurrentPartition(
|
||||
PPARTLIST List);
|
||||
|
||||
VOID
|
||||
CheckActiveBootPartition (PPARTLIST List);
|
||||
CheckActiveBootPartition(
|
||||
PPARTLIST List);
|
||||
|
||||
BOOLEAN
|
||||
CheckForLinuxFdiskPartitions (PPARTLIST List);
|
||||
CheckForLinuxFdiskPartitions(
|
||||
PPARTLIST List);
|
||||
|
||||
BOOLEAN
|
||||
WritePartitionsToDisk (PPARTLIST List);
|
||||
WritePartitionsToDisk(
|
||||
PPARTLIST List);
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -397,13 +397,13 @@ Execute(LPTSTR Full, LPTSTR First, LPTSTR Rest, PARSED_COMMAND *Cmd)
|
|||
/* build command line for CreateProcess(): FullName + " " + rest */
|
||||
BOOL quoted = !!_tcschr(First, ' ');
|
||||
_tcscpy(szFullCmdLine, quoted ? _T("\"") : _T(""));
|
||||
_tcsncat(szFullCmdLine, First, CMDLINE_LENGTH - _tcslen(szFullCmdLine));
|
||||
_tcsncat(szFullCmdLine, quoted ? _T("\"") : _T(""), CMDLINE_LENGTH - _tcslen(szFullCmdLine));
|
||||
_tcsncat(szFullCmdLine, First, CMDLINE_LENGTH - _tcslen(szFullCmdLine) - 1);
|
||||
_tcsncat(szFullCmdLine, quoted ? _T("\"") : _T(""), CMDLINE_LENGTH - _tcslen(szFullCmdLine) - 1);
|
||||
|
||||
if (*rest)
|
||||
{
|
||||
_tcsncat(szFullCmdLine, _T(" "), CMDLINE_LENGTH - _tcslen(szFullCmdLine));
|
||||
_tcsncat(szFullCmdLine, rest, CMDLINE_LENGTH - _tcslen(szFullCmdLine));
|
||||
_tcsncat(szFullCmdLine, _T(" "), CMDLINE_LENGTH - _tcslen(szFullCmdLine) - 1);
|
||||
_tcsncat(szFullCmdLine, rest, CMDLINE_LENGTH - _tcslen(szFullCmdLine) - 1);
|
||||
}
|
||||
|
||||
TRACE ("[EXEC: %s]\n", debugstr_aw(szFullCmdLine));
|
||||
|
|
|
@ -1636,7 +1636,8 @@ HKCU,"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\HideDesktopIcons",,0x00
|
|||
HKCU,"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\HideDesktopIcons\ClassicStartMenu",,0x00000012
|
||||
HKCU,"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\HideDesktopIcons\ClassicStartMenu","{208D2C60-3AEA-1069-A2D7-08002B30309D}",0x00010001,0x00000000
|
||||
HKCU,"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\CLSID\{20D04FE0-3AEA-1069-A2D8-08002B30309D}",,0x00000012
|
||||
HKCU,"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced","ListviewShadow",0x00010001,0x1
|
||||
HKCU,"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced","ListviewShadow",0x00010001,0x00000001
|
||||
HKCU,"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced","HideFileExt",0x00010001,0x00000000
|
||||
|
||||
; default shell
|
||||
HKCU,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon",,0x00000012
|
||||
|
|
|
@ -36,6 +36,9 @@ if(CMAKE_C_COMPILER_ID STREQUAL "Clang")
|
|||
add_compile_flags("-Wno-microsoft")
|
||||
endif()
|
||||
|
||||
if(DBG)
|
||||
add_compile_flags_language("-Wold-style-declaration -Wdeclaration-after-statement" "C")
|
||||
endif()
|
||||
add_compile_flags_language("-fno-rtti -fno-exceptions" "CXX")
|
||||
|
||||
#bug
|
||||
|
|
|
@ -56,7 +56,8 @@ add_compile_flags("/wd4290")
|
|||
# - C4163: 'identifier': not available as an intrinsic function
|
||||
# - C4229: modifiers on data are ignored
|
||||
# - C4700: uninitialized variable usage
|
||||
add_compile_flags("/we4013 /we4020 /we4022 /we4047 /we4098 /we4113 /we4129 /we4163 /we4229 /we4700")
|
||||
# - C4603: macro is not defined or definition is different after precompiled header use
|
||||
add_compile_flags("/we4013 /we4020 /we4022 /we4047 /we4098 /we4113 /we4129 /we4163 /we4229 /we4700 /we4603")
|
||||
|
||||
# Enable warnings above the default level, but don't treat them as errors:
|
||||
# - C4115: named type definition in parentheses
|
||||
|
|
|
@ -59,6 +59,6 @@ echo Preparing reactos...
|
|||
cd ../reactos
|
||||
rm -f CMakeCache.txt
|
||||
|
||||
cmake -G "$CMAKE_GENERATOR" -DENABLE_CCACHE:BOOL=1 -DCMAKE_TOOLCHAIN_FILE:FILEPATH=toolchain-gcc.cmake -DARCH:STRING=$ARCH -DREACTOS_BUILD_TOOLS_DIR:PATH="$REACTOS_BUILD_TOOLS_DIR" $ROS_CMAKEOPTS "$REACTOS_SOURCE_DIR"
|
||||
cmake -G "$CMAKE_GENERATOR" -DENABLE_CCACHE:BOOL=0 -DCMAKE_TOOLCHAIN_FILE:FILEPATH=toolchain-gcc.cmake -DARCH:STRING=$ARCH -DREACTOS_BUILD_TOOLS_DIR:PATH="$REACTOS_BUILD_TOOLS_DIR" $ROS_CMAKEOPTS "$REACTOS_SOURCE_DIR"
|
||||
|
||||
echo Configure script complete! Enter directories and execute appropriate build commands \(ex: ninja, make, makex, etc...\).
|
||||
|
|
|
@ -607,9 +607,9 @@ static HRESULT WINAPI IEnumDMO_fnNext(
|
|||
hres = RegQueryValueExW(hkey, NULL, NULL, NULL, (LPBYTE) szValue, &len);
|
||||
if (ERROR_SUCCESS == hres)
|
||||
{
|
||||
Names[count] = HeapAlloc(GetProcessHeap(), 0, strlenW(szValue) + 1);
|
||||
Names[count] = HeapAlloc(GetProcessHeap(), 0, (strlenW(szValue) + 1) * sizeof(WCHAR));
|
||||
if (Names[count])
|
||||
strcmpW(Names[count], szValue);
|
||||
strcpyW(Names[count], szValue);
|
||||
}
|
||||
wsprintfW(szGuidKey,szToGuidFmt,szNextKey);
|
||||
CLSIDFromString(szGuidKey, &pCLSID[count]);
|
||||
|
|
|
@ -40,6 +40,7 @@ add_library(ntdll SHARED
|
|||
${SOURCE}
|
||||
${ntdll_asm}
|
||||
def/ntdll.rc
|
||||
${CMAKE_CURRENT_BINARY_DIR}/ntdll_stubs.c
|
||||
${CMAKE_CURRENT_BINARY_DIR}/ntdll.def)
|
||||
|
||||
set_module_type(ntdll win32dll HOTPATCHABLE ENTRYPOINT 0)
|
||||
|
|
|
@ -101,6 +101,9 @@ CsrAllocateCaptureBuffer(IN ULONG ArgumentCount,
|
|||
/* Align it to a 4-byte boundary */
|
||||
BufferSize = (BufferSize + 3) & ~3;
|
||||
|
||||
/* Add the size of the alignment padding for each argument */
|
||||
BufferSize += ArgumentCount * 3;
|
||||
|
||||
/* Allocate memory from the port heap */
|
||||
CaptureBuffer = RtlAllocateHeap(CsrPortHeap, HEAP_ZERO_MEMORY, BufferSize);
|
||||
if (CaptureBuffer == NULL) return NULL;
|
||||
|
|
|
@ -175,7 +175,7 @@
|
|||
@ stdcall NtGetCurrentProcessorNumber() ; 5.2 and higher
|
||||
@ stdcall NtGetDevicePowerState(ptr ptr)
|
||||
@ stdcall NtGetPlugPlayEvent(long long ptr long)
|
||||
;@ stdcall NtGetTickCount()
|
||||
@ stdcall -stub NtGetTickCount()
|
||||
@ stdcall NtGetWriteWatch(long long ptr long ptr ptr ptr)
|
||||
@ stdcall NtImpersonateAnonymousToken(ptr)
|
||||
@ stdcall NtImpersonateClientOfPort(ptr ptr)
|
||||
|
|
|
@ -82,8 +82,8 @@ LdrAlternateResourcesEnabled(VOID)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
ULONG_PTR
|
||||
FORCEINLINE
|
||||
ULONG_PTR
|
||||
LdrpMakeCookie(VOID)
|
||||
{
|
||||
/* Generate a cookie */
|
||||
|
|
|
@ -221,7 +221,7 @@ GetDeviceCapabilities(
|
|||
caps->vDriverVersion = 0x0100;
|
||||
|
||||
memset(caps->szPname, 0, sizeof(caps->szPname));
|
||||
memcpy(caps->szPname, L"PC speaker\0", strlen("PC speaker\0") * 2);
|
||||
wcscpy(caps->szPname, L"PC speaker");
|
||||
|
||||
caps->wTechnology = MOD_SQSYNTH;
|
||||
|
||||
|
|
|
@ -2301,7 +2301,7 @@ CreateProcessInternalW(IN HANDLE hUserToken,
|
|||
BOOLEAN InJob, SaferNeeded, UseLargePages, HavePrivilege;
|
||||
BOOLEAN QuerySection, SkipSaferAndAppCompat;
|
||||
CONTEXT Context;
|
||||
BASE_API_MESSAGE CsrMsg;
|
||||
BASE_API_MESSAGE CsrMsg[2];
|
||||
PBASE_CREATE_PROCESS CreateProcessMsg;
|
||||
PCSR_CAPTURE_BUFFER CaptureBuffer;
|
||||
PVOID BaseAddress, PrivilegeState, RealTimePrivilegeState;
|
||||
|
@ -2431,8 +2431,8 @@ CreateProcessInternalW(IN HANDLE hUserToken,
|
|||
IsWowApp = FALSE;
|
||||
|
||||
/* Set message structures */
|
||||
CreateProcessMsg = &CsrMsg.Data.CreateProcessRequest;
|
||||
CheckVdmMsg = &CsrMsg.Data.CheckVDMRequest;
|
||||
CreateProcessMsg = &CsrMsg[0].Data.CreateProcessRequest;
|
||||
CheckVdmMsg = &CsrMsg[1].Data.CheckVDMRequest;
|
||||
|
||||
/* Clear the more complex structures by zeroing out their entire memory */
|
||||
RtlZeroMemory(&Context, sizeof(Context));
|
||||
|
@ -3197,7 +3197,7 @@ StartScan:
|
|||
/* Pick which kind of WOW mode we want to run in */
|
||||
VdmBinaryType = (dwCreationFlags &
|
||||
CREATE_SEPARATE_WOW_VDM) ?
|
||||
BINARY_TYPE_WOW : BINARY_TYPE_SEPARATE_WOW;
|
||||
BINARY_TYPE_SEPARATE_WOW : BINARY_TYPE_WOW;
|
||||
|
||||
/* Get all the VDM settings and current status */
|
||||
Status = BaseCheckVDM(VdmBinaryType,
|
||||
|
@ -3205,7 +3205,7 @@ StartScan:
|
|||
lpCommandLine,
|
||||
lpCurrentDirectory,
|
||||
&VdmAnsiEnv,
|
||||
&CsrMsg,
|
||||
&CsrMsg[1],
|
||||
&VdmTask,
|
||||
dwCreationFlags,
|
||||
&StartupInfo,
|
||||
|
@ -3342,7 +3342,7 @@ StartScan:
|
|||
lpCommandLine,
|
||||
lpCurrentDirectory,
|
||||
&VdmAnsiEnv,
|
||||
&CsrMsg,
|
||||
&CsrMsg[1],
|
||||
&VdmTask,
|
||||
dwCreationFlags,
|
||||
&StartupInfo,
|
||||
|
@ -3966,6 +3966,8 @@ StartScan:
|
|||
&VdmWaitObject,
|
||||
VdmTask,
|
||||
VdmBinaryType);
|
||||
|
||||
if (!Result)
|
||||
{
|
||||
/* Bail out on failure */
|
||||
DPRINT1("Failed to update VDM with wait object\n");
|
||||
|
@ -4335,7 +4337,7 @@ StartScan:
|
|||
}
|
||||
|
||||
/* We are finally ready to call CSRSS to tell it about our new process! */
|
||||
CsrClientCallServer((PCSR_API_MESSAGE)&CsrMsg,
|
||||
CsrClientCallServer((PCSR_API_MESSAGE)&CsrMsg[0],
|
||||
CaptureBuffer,
|
||||
CSR_CREATE_API_NUMBER(BASESRV_SERVERDLL_INDEX,
|
||||
BasepCreateProcess),
|
||||
|
@ -4349,12 +4351,12 @@ StartScan:
|
|||
}
|
||||
|
||||
/* Check if CSRSS failed to accept ownership of the new Windows process */
|
||||
if (!NT_SUCCESS(CsrMsg.Status))
|
||||
if (!NT_SUCCESS(CsrMsg[0].Status))
|
||||
{
|
||||
/* Terminate the process and enter failure path with the CSRSS status */
|
||||
DPRINT1("Failed to tell csrss about new process\n");
|
||||
BaseSetLastNTError(CsrMsg.Status);
|
||||
NtTerminateProcess(ProcessHandle, CsrMsg.Status);
|
||||
BaseSetLastNTError(CsrMsg[0].Status);
|
||||
NtTerminateProcess(ProcessHandle, CsrMsg[0].Status);
|
||||
Result = FALSE;
|
||||
goto Quickie;
|
||||
}
|
||||
|
|
|
@ -64,7 +64,7 @@ BaseIsDosApplication(IN PUNICODE_STRING PathName,
|
|||
return 0;
|
||||
}
|
||||
|
||||
BOOL
|
||||
NTSTATUS
|
||||
WINAPI
|
||||
BaseCheckVDM(IN ULONG BinaryType,
|
||||
IN PCWCH ApplicationName,
|
||||
|
@ -77,9 +77,354 @@ BaseCheckVDM(IN ULONG BinaryType,
|
|||
IN LPSTARTUPINFOW StartupInfo,
|
||||
IN HANDLE hUserToken OPTIONAL)
|
||||
{
|
||||
/* This is not supported */
|
||||
UNIMPLEMENTED;
|
||||
return FALSE;
|
||||
NTSTATUS Status;
|
||||
PBASE_CHECK_VDM CheckVdm = &ApiMessage->Data.CheckVDMRequest;
|
||||
PCSR_CAPTURE_BUFFER CaptureBuffer;
|
||||
PWCHAR CurrentDir = NULL;
|
||||
PWCHAR ShortAppName = NULL;
|
||||
PWCHAR ShortCurrentDir = NULL;
|
||||
ULONG Length;
|
||||
PCHAR AnsiCmdLine = NULL;
|
||||
PCHAR AnsiAppName = NULL;
|
||||
PCHAR AnsiCurDirectory = NULL;
|
||||
PCHAR AnsiDesktop = NULL;
|
||||
PCHAR AnsiTitle = NULL;
|
||||
PCHAR AnsiReserved = NULL;
|
||||
STARTUPINFOA AnsiStartupInfo;
|
||||
ULONG NumStrings = 5;
|
||||
|
||||
if (CurrentDirectory == NULL)
|
||||
{
|
||||
/* Allocate memory for the current directory path */
|
||||
Length = GetCurrentDirectoryW(0, NULL);
|
||||
CurrentDir = (PWCHAR)RtlAllocateHeap(RtlGetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY,
|
||||
Length * sizeof(WCHAR));
|
||||
if (CurrentDir == NULL)
|
||||
{
|
||||
Status = STATUS_NO_MEMORY;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
/* Get the current directory */
|
||||
GetCurrentDirectoryW(Length, CurrentDir);
|
||||
CurrentDirectory = CurrentDir;
|
||||
}
|
||||
|
||||
/* Calculate the size of the short application name */
|
||||
Length = GetShortPathNameW(ApplicationName, NULL, 0);
|
||||
|
||||
/* Allocate memory for the short application name */
|
||||
ShortAppName = (PWCHAR)RtlAllocateHeap(RtlGetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY,
|
||||
Length * sizeof(WCHAR));
|
||||
if (!ShortAppName)
|
||||
{
|
||||
Status = STATUS_NO_MEMORY;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
/* Get the short application name */
|
||||
if (!GetShortPathNameW(ApplicationName, ShortAppName, Length))
|
||||
{
|
||||
/* Try to determine which error occurred */
|
||||
switch (GetLastError())
|
||||
{
|
||||
case ERROR_NOT_ENOUGH_MEMORY:
|
||||
{
|
||||
Status = STATUS_NO_MEMORY;
|
||||
break;
|
||||
}
|
||||
|
||||
case ERROR_INVALID_PARAMETER:
|
||||
{
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
Status = STATUS_OBJECT_PATH_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
/* Calculate the size of the short current directory path */
|
||||
Length = GetShortPathNameW(CurrentDirectory, NULL, 0);
|
||||
|
||||
/* Allocate memory for the short current directory path */
|
||||
ShortCurrentDir = (PWCHAR)RtlAllocateHeap(RtlGetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY,
|
||||
Length * sizeof(WCHAR));
|
||||
if (!ShortCurrentDir)
|
||||
{
|
||||
Status = STATUS_NO_MEMORY;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
/* Get the short current directory path */
|
||||
if (!GetShortPathNameW(CurrentDirectory, ShortCurrentDir, Length))
|
||||
{
|
||||
/* Try to determine which error occurred */
|
||||
switch (GetLastError())
|
||||
{
|
||||
case ERROR_NOT_ENOUGH_MEMORY:
|
||||
{
|
||||
Status = STATUS_NO_MEMORY;
|
||||
break;
|
||||
}
|
||||
|
||||
case ERROR_INVALID_PARAMETER:
|
||||
{
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
Status = STATUS_OBJECT_PATH_INVALID;
|
||||
}
|
||||
}
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
/* Setup the input parameters */
|
||||
CheckVdm->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
|
||||
CheckVdm->BinaryType = BinaryType;
|
||||
CheckVdm->CodePage = CP_ACP;
|
||||
CheckVdm->dwCreationFlags = CreationFlags;
|
||||
CheckVdm->CurDrive = CurrentDirectory[0] - L'A';
|
||||
CheckVdm->CmdLen = wcslen(CommandLine) + 1;
|
||||
CheckVdm->AppLen = wcslen(ShortAppName) + 1;
|
||||
CheckVdm->PifLen = 0; // TODO: PIF file support!
|
||||
CheckVdm->CurDirectoryLen = wcslen(ShortCurrentDir) + 1;
|
||||
CheckVdm->EnvLen = AnsiEnvironment->Length;
|
||||
CheckVdm->DesktopLen = (StartupInfo->lpDesktop != NULL) ? (wcslen(StartupInfo->lpDesktop) + 1) : 0;
|
||||
CheckVdm->TitleLen = (StartupInfo->lpTitle != NULL) ? (wcslen(StartupInfo->lpTitle) + 1) : 0;
|
||||
CheckVdm->ReservedLen = (StartupInfo->lpReserved != NULL) ? (wcslen(StartupInfo->lpReserved) + 1) : 0;
|
||||
|
||||
if (StartupInfo->dwFlags & STARTF_USESTDHANDLES)
|
||||
{
|
||||
/* Set the standard handles */
|
||||
CheckVdm->StdIn = StartupInfo->hStdInput;
|
||||
CheckVdm->StdOut = StartupInfo->hStdOutput;
|
||||
CheckVdm->StdErr = StartupInfo->hStdError;
|
||||
}
|
||||
|
||||
/* Allocate memory for the ANSI strings */
|
||||
AnsiCmdLine = (PCHAR)RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, CheckVdm->CmdLen);
|
||||
AnsiAppName = (PCHAR)RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, CheckVdm->AppLen);
|
||||
AnsiCurDirectory = (PCHAR)RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, CheckVdm->CurDirectoryLen);
|
||||
if (StartupInfo->lpDesktop) AnsiDesktop = (PCHAR)RtlAllocateHeap(RtlGetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY,
|
||||
CheckVdm->DesktopLen);
|
||||
if (StartupInfo->lpTitle) AnsiTitle = (PCHAR)RtlAllocateHeap(RtlGetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY,
|
||||
CheckVdm->TitleLen);
|
||||
if (StartupInfo->lpReserved) AnsiReserved = (PCHAR)RtlAllocateHeap(RtlGetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY,
|
||||
CheckVdm->ReservedLen);
|
||||
|
||||
if (!AnsiCmdLine
|
||||
|| !AnsiAppName
|
||||
|| !AnsiCurDirectory
|
||||
|| (StartupInfo->lpDesktop && !AnsiDesktop)
|
||||
|| (StartupInfo->lpTitle && !AnsiTitle)
|
||||
|| (StartupInfo->lpReserved && !AnsiReserved))
|
||||
{
|
||||
Status = STATUS_NO_MEMORY;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
/* Convert the command line into an ANSI string */
|
||||
WideCharToMultiByte(CP_ACP,
|
||||
0,
|
||||
CommandLine,
|
||||
CheckVdm->CmdLen,
|
||||
AnsiCmdLine,
|
||||
CheckVdm->CmdLen,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
/* Convert the short application name into an ANSI string */
|
||||
WideCharToMultiByte(CP_ACP,
|
||||
0,
|
||||
ShortAppName,
|
||||
CheckVdm->AppLen,
|
||||
AnsiAppName,
|
||||
CheckVdm->AppLen,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
/* Convert the short current directory path into an ANSI string */
|
||||
WideCharToMultiByte(CP_ACP,
|
||||
0,
|
||||
ShortCurrentDir,
|
||||
CheckVdm->CurDirectoryLen,
|
||||
AnsiCurDirectory,
|
||||
CheckVdm->CurDirectoryLen,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
if (StartupInfo->lpDesktop)
|
||||
{
|
||||
/* Convert the desktop name into an ANSI string */
|
||||
WideCharToMultiByte(CP_ACP,
|
||||
0,
|
||||
StartupInfo->lpDesktop,
|
||||
CheckVdm->DesktopLen,
|
||||
AnsiDesktop,
|
||||
CheckVdm->DesktopLen,
|
||||
NULL,
|
||||
NULL);
|
||||
NumStrings++;
|
||||
}
|
||||
|
||||
if (StartupInfo->lpTitle)
|
||||
{
|
||||
/* Convert the title into an ANSI string */
|
||||
WideCharToMultiByte(CP_ACP,
|
||||
0,
|
||||
StartupInfo->lpTitle,
|
||||
CheckVdm->TitleLen,
|
||||
AnsiTitle,
|
||||
CheckVdm->TitleLen,
|
||||
NULL,
|
||||
NULL);
|
||||
NumStrings++;
|
||||
}
|
||||
|
||||
if (StartupInfo->lpReserved)
|
||||
{
|
||||
/* Convert the reserved value into an ANSI string */
|
||||
WideCharToMultiByte(CP_ACP,
|
||||
0,
|
||||
StartupInfo->lpReserved,
|
||||
CheckVdm->ReservedLen,
|
||||
AnsiReserved,
|
||||
CheckVdm->ReservedLen,
|
||||
NULL,
|
||||
NULL);
|
||||
NumStrings++;
|
||||
}
|
||||
|
||||
/* Fill the ANSI startup info structure */
|
||||
RtlCopyMemory(&AnsiStartupInfo, StartupInfo, sizeof(STARTUPINFO));
|
||||
AnsiStartupInfo.lpReserved = AnsiReserved;
|
||||
AnsiStartupInfo.lpDesktop = AnsiDesktop;
|
||||
AnsiStartupInfo.lpTitle = AnsiTitle;
|
||||
|
||||
/* Allocate the capture buffer */
|
||||
CaptureBuffer = CsrAllocateCaptureBuffer(NumStrings,
|
||||
CheckVdm->CmdLen
|
||||
+ CheckVdm->AppLen
|
||||
+ CheckVdm->PifLen
|
||||
+ CheckVdm->CurDirectoryLen
|
||||
+ CheckVdm->DesktopLen
|
||||
+ CheckVdm->TitleLen
|
||||
+ CheckVdm->ReservedLen
|
||||
+ CheckVdm->EnvLen
|
||||
+ sizeof(STARTUPINFOA));
|
||||
if (CaptureBuffer == NULL)
|
||||
{
|
||||
Status = STATUS_NO_MEMORY;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
/* Capture the command line */
|
||||
CsrCaptureMessageBuffer(CaptureBuffer,
|
||||
AnsiCmdLine,
|
||||
CheckVdm->CmdLen,
|
||||
(PVOID*)&CheckVdm->CmdLine);
|
||||
|
||||
/* Capture the application name */
|
||||
CsrCaptureMessageBuffer(CaptureBuffer,
|
||||
AnsiAppName,
|
||||
CheckVdm->AppLen,
|
||||
(PVOID*)&CheckVdm->AppName);
|
||||
|
||||
CheckVdm->PifFile = NULL; // TODO: PIF file support!
|
||||
|
||||
/* Capture the current directory */
|
||||
CsrCaptureMessageBuffer(CaptureBuffer,
|
||||
AnsiCurDirectory,
|
||||
CheckVdm->CurDirectoryLen,
|
||||
(PVOID*)&CheckVdm->CurDirectory);
|
||||
|
||||
/* Capture the environment */
|
||||
CsrCaptureMessageBuffer(CaptureBuffer,
|
||||
AnsiEnvironment->Buffer,
|
||||
CheckVdm->EnvLen,
|
||||
(PVOID*)&CheckVdm->Env);
|
||||
|
||||
/* Capture the startup info structure */
|
||||
CsrCaptureMessageBuffer(CaptureBuffer,
|
||||
&AnsiStartupInfo,
|
||||
sizeof(STARTUPINFOA),
|
||||
(PVOID*)&CheckVdm->StartupInfo);
|
||||
|
||||
if (StartupInfo->lpDesktop)
|
||||
{
|
||||
/* Capture the desktop name */
|
||||
CsrCaptureMessageBuffer(CaptureBuffer,
|
||||
AnsiDesktop,
|
||||
CheckVdm->DesktopLen,
|
||||
(PVOID*)&CheckVdm->Desktop);
|
||||
}
|
||||
else CheckVdm->Desktop = NULL;
|
||||
|
||||
if (StartupInfo->lpTitle)
|
||||
{
|
||||
/* Capture the title */
|
||||
CsrCaptureMessageBuffer(CaptureBuffer,
|
||||
AnsiTitle,
|
||||
CheckVdm->TitleLen,
|
||||
(PVOID*)&CheckVdm->Title);
|
||||
}
|
||||
else CheckVdm->Title = NULL;
|
||||
|
||||
if (StartupInfo->lpReserved)
|
||||
{
|
||||
/* Capture the reserved parameter */
|
||||
CsrCaptureMessageBuffer(CaptureBuffer,
|
||||
AnsiReserved,
|
||||
CheckVdm->ReservedLen,
|
||||
(PVOID*)&CheckVdm->Reserved);
|
||||
}
|
||||
else CheckVdm->Reserved = NULL;
|
||||
|
||||
/* Send the message to CSRSS */
|
||||
Status = CsrClientCallServer((PCSR_API_MESSAGE)ApiMessage,
|
||||
CaptureBuffer,
|
||||
CSR_CREATE_API_NUMBER(BASESRV_SERVERDLL_INDEX, BasepCheckVDM),
|
||||
sizeof(BASE_CHECK_VDM));
|
||||
|
||||
/* Write back the task ID */
|
||||
*iTask = CheckVdm->iTask;
|
||||
|
||||
Cleanup:
|
||||
|
||||
/* Free the ANSI strings */
|
||||
if (AnsiCmdLine) RtlFreeHeap(RtlGetProcessHeap(), 0, AnsiCmdLine);
|
||||
if (AnsiAppName) RtlFreeHeap(RtlGetProcessHeap(), 0, AnsiAppName);
|
||||
if (AnsiCurDirectory) RtlFreeHeap(RtlGetProcessHeap(), 0, AnsiCurDirectory);
|
||||
if (AnsiDesktop) RtlFreeHeap(RtlGetProcessHeap(), 0, AnsiDesktop);
|
||||
if (AnsiTitle) RtlFreeHeap(RtlGetProcessHeap(), 0, AnsiTitle);
|
||||
if (AnsiReserved) RtlFreeHeap(RtlGetProcessHeap(), 0, AnsiReserved);
|
||||
|
||||
/* Free the capture buffer */
|
||||
CsrFreeCaptureBuffer(CaptureBuffer);
|
||||
|
||||
/* Free the short paths */
|
||||
if (ShortAppName) RtlFreeHeap(RtlGetProcessHeap(), 0, ShortAppName);
|
||||
if (ShortCurrentDir) RtlFreeHeap(RtlGetProcessHeap(), 0, ShortCurrentDir);
|
||||
|
||||
/* Free the current directory, if it was allocated here */
|
||||
if (CurrentDir) RtlFreeHeap(RtlGetProcessHeap(), 0, CurrentDir);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
BOOL
|
||||
|
@ -89,10 +434,9 @@ BaseUpdateVDMEntry(IN ULONG UpdateIndex,
|
|||
IN ULONG IndexInfo,
|
||||
IN ULONG BinaryType)
|
||||
{
|
||||
#if 0 // Unimplemented in BASESRV
|
||||
NTSTATUS Status;
|
||||
BASE_API_MESSAGE ApiMessage;
|
||||
PBASE_UPDATE_VDM_ENTRY UpdateVdmEntry = &ApiMessage.Data.UpdateVdmEntry;
|
||||
PBASE_UPDATE_VDM_ENTRY UpdateVdmEntry = &ApiMessage.Data.UpdateVDMEntryRequest;
|
||||
|
||||
/* Check what update is being sent */
|
||||
switch (UpdateIndex)
|
||||
|
@ -155,7 +499,7 @@ BaseUpdateVDMEntry(IN ULONG UpdateIndex,
|
|||
/* Return it to the caller */
|
||||
*WaitHandle = UpdateVdmEntry->WaitObjectForParent;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* We made it */
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -165,11 +509,10 @@ WINAPI
|
|||
BaseCheckForVDM(IN HANDLE ProcessHandle,
|
||||
OUT LPDWORD ExitCode)
|
||||
{
|
||||
#if 0 // Unimplemented in BASESRV
|
||||
NTSTATUS Status;
|
||||
EVENT_BASIC_INFORMATION EventBasicInfo;
|
||||
BASE_API_MESSAGE ApiMessage;
|
||||
PBASE_GET_VDM_EXIT_CODE GetVdmExitCode = &ApiMessage.Data.GetVdmExitCode;
|
||||
PBASE_GET_VDM_EXIT_CODE GetVdmExitCode = &ApiMessage.Data.GetVDMExitCodeRequest;
|
||||
|
||||
/* It's VDM if the process is actually a wait handle (an event) */
|
||||
Status = NtQueryEvent(ProcessHandle,
|
||||
|
@ -192,7 +535,6 @@ BaseCheckForVDM(IN HANDLE ProcessHandle,
|
|||
|
||||
/* Get the exit code from the reply */
|
||||
*ExitCode = GetVdmExitCode->ExitCode;
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -335,7 +677,7 @@ BaseCreateVDMEnvironment(IN PWCHAR lpEnvironment,
|
|||
if (!lpEnvironment)
|
||||
{
|
||||
/* Nope, create one */
|
||||
Status = RtlCreateEnvironment(TRUE, (PWCHAR*)&Environment);
|
||||
Status = RtlCreateEnvironment(TRUE, &Environment);
|
||||
if (!NT_SUCCESS(Status)) goto Quickie;
|
||||
}
|
||||
else
|
||||
|
@ -376,6 +718,7 @@ BaseCreateVDMEnvironment(IN PWCHAR lpEnvironment,
|
|||
p = NewEnvironment;
|
||||
|
||||
/* FIXME: Code here */
|
||||
DPRINT1("BaseCreateVDMEnvironment is half-plemented!\n");
|
||||
|
||||
/* Terminate it */
|
||||
*p++ = UNICODE_NULL;
|
||||
|
@ -574,7 +917,7 @@ InternalGetBinaryType(HANDLE hFile)
|
|||
return BINARY_PE_EXE32;
|
||||
}
|
||||
|
||||
if(!memcmp(magic, "NE", 1))
|
||||
if(!memcmp(magic, "NE", 2))
|
||||
{
|
||||
/* This is a Windows executable (NE) header. This can
|
||||
* mean either a 16-bit OS/2 or a 16-bit Windows or even a
|
||||
|
@ -755,46 +1098,399 @@ CmdBatNotification (
|
|||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
* @implemented
|
||||
*/
|
||||
DWORD
|
||||
VOID
|
||||
WINAPI
|
||||
ExitVDM (
|
||||
DWORD Unknown0,
|
||||
DWORD Unknown1
|
||||
)
|
||||
ExitVDM(BOOL IsWow, ULONG iWowTask)
|
||||
{
|
||||
STUB;
|
||||
return 0;
|
||||
BASE_API_MESSAGE ApiMessage;
|
||||
PBASE_EXIT_VDM ExitVdm = &ApiMessage.Data.ExitVDMRequest;
|
||||
|
||||
/* Setup the input parameters */
|
||||
ExitVdm->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
|
||||
ExitVdm->iWowTask = IsWow ? iWowTask : 0; /* Always zero for DOS tasks */
|
||||
ExitVdm->WaitObjectForVDM = NULL;
|
||||
|
||||
/* Call CSRSS */
|
||||
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
|
||||
NULL,
|
||||
CSR_CREATE_API_NUMBER(BASESRV_SERVERDLL_INDEX, BasepExitVDM),
|
||||
sizeof(BASE_EXIT_VDM));
|
||||
|
||||
/* Close the returned wait object handle, if any */
|
||||
if (NT_SUCCESS(ApiMessage.Status) && (ExitVdm->WaitObjectForVDM != NULL))
|
||||
{
|
||||
CloseHandle(ExitVdm->WaitObjectForVDM);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
WINAPI
|
||||
GetNextVDMCommand(PVDM_COMMAND_INFO CommandData)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
BOOL Result = FALSE;
|
||||
BASE_API_MESSAGE ApiMessage;
|
||||
PBASE_GET_NEXT_VDM_COMMAND GetNextVdmCommand = &ApiMessage.Data.GetNextVDMCommandRequest;
|
||||
PBASE_IS_FIRST_VDM IsFirstVdm = &ApiMessage.Data.IsFirstVDMRequest;
|
||||
PBASE_SET_REENTER_COUNT SetReenterCount = &ApiMessage.Data.SetReenterCountRequest;
|
||||
PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
|
||||
ULONG NumStrings = 0;
|
||||
|
||||
if (CommandData != NULL)
|
||||
{
|
||||
if (CommandData->VDMState & (VDM_NOT_LOADED | VDM_NOT_READY | VDM_READY))
|
||||
{
|
||||
/* Clear the structure */
|
||||
ZeroMemory(GetNextVdmCommand, sizeof(*GetNextVdmCommand));
|
||||
|
||||
/* Setup the input parameters */
|
||||
GetNextVdmCommand->iTask = CommandData->TaskId;
|
||||
GetNextVdmCommand->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
|
||||
GetNextVdmCommand->CmdLen = CommandData->CmdLen;
|
||||
GetNextVdmCommand->AppLen = CommandData->AppLen;
|
||||
GetNextVdmCommand->PifLen = CommandData->PifLen;
|
||||
GetNextVdmCommand->CurDirectoryLen = CommandData->CurDirectoryLen;
|
||||
GetNextVdmCommand->EnvLen = CommandData->EnvLen;
|
||||
GetNextVdmCommand->DesktopLen = CommandData->DesktopLen;
|
||||
GetNextVdmCommand->TitleLen = CommandData->TitleLen;
|
||||
GetNextVdmCommand->ReservedLen = CommandData->ReservedLen;
|
||||
GetNextVdmCommand->VDMState = CommandData->VDMState;
|
||||
|
||||
/* Count the number of strings */
|
||||
if (CommandData->CmdLen) NumStrings++;
|
||||
if (CommandData->AppLen) NumStrings++;
|
||||
if (CommandData->PifLen) NumStrings++;
|
||||
if (CommandData->CurDirectoryLen) NumStrings++;
|
||||
if (CommandData->EnvLen) NumStrings++;
|
||||
if (CommandData->DesktopLen) NumStrings++;
|
||||
if (CommandData->TitleLen) NumStrings++;
|
||||
if (CommandData->ReservedLen) NumStrings++;
|
||||
|
||||
/* Allocate the capture buffer */
|
||||
CaptureBuffer = CsrAllocateCaptureBuffer(NumStrings + 1,
|
||||
GetNextVdmCommand->CmdLen
|
||||
+ GetNextVdmCommand->AppLen
|
||||
+ GetNextVdmCommand->PifLen
|
||||
+ GetNextVdmCommand->CurDirectoryLen
|
||||
+ GetNextVdmCommand->EnvLen
|
||||
+ GetNextVdmCommand->DesktopLen
|
||||
+ GetNextVdmCommand->TitleLen
|
||||
+ GetNextVdmCommand->ReservedLen
|
||||
+ sizeof(STARTUPINFOA));
|
||||
if (CaptureBuffer == NULL)
|
||||
{
|
||||
BaseSetLastNTError(STATUS_NO_MEMORY);
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
/* Allocate memory for the startup info */
|
||||
CsrAllocateMessagePointer(CaptureBuffer,
|
||||
sizeof(STARTUPINFOA),
|
||||
(PVOID*)&GetNextVdmCommand->StartupInfo);
|
||||
|
||||
if (CommandData->CmdLen)
|
||||
{
|
||||
/* Allocate memory for the command line */
|
||||
CsrAllocateMessagePointer(CaptureBuffer,
|
||||
CommandData->CmdLen,
|
||||
(PVOID*)&GetNextVdmCommand->CmdLine);
|
||||
}
|
||||
|
||||
if (CommandData->AppLen)
|
||||
{
|
||||
/* Allocate memory for the application name */
|
||||
CsrAllocateMessagePointer(CaptureBuffer,
|
||||
CommandData->AppLen,
|
||||
(PVOID*)&GetNextVdmCommand->AppName);
|
||||
}
|
||||
|
||||
if (CommandData->PifLen)
|
||||
{
|
||||
/* Allocate memory for the PIF file name */
|
||||
CsrAllocateMessagePointer(CaptureBuffer,
|
||||
CommandData->PifLen,
|
||||
(PVOID*)&GetNextVdmCommand->PifFile);
|
||||
}
|
||||
|
||||
if (CommandData->CurDirectoryLen)
|
||||
{
|
||||
/* Allocate memory for the current directory */
|
||||
CsrAllocateMessagePointer(CaptureBuffer,
|
||||
CommandData->CurDirectoryLen,
|
||||
(PVOID*)&GetNextVdmCommand->CurDirectory);
|
||||
}
|
||||
|
||||
if (CommandData->EnvLen)
|
||||
{
|
||||
/* Allocate memory for the environment */
|
||||
CsrAllocateMessagePointer(CaptureBuffer,
|
||||
CommandData->EnvLen,
|
||||
(PVOID*)&GetNextVdmCommand->Env);
|
||||
}
|
||||
|
||||
if (CommandData->DesktopLen)
|
||||
{
|
||||
/* Allocate memory for the desktop name */
|
||||
CsrAllocateMessagePointer(CaptureBuffer,
|
||||
CommandData->DesktopLen,
|
||||
(PVOID*)&GetNextVdmCommand->Desktop);
|
||||
}
|
||||
|
||||
if (CommandData->TitleLen)
|
||||
{
|
||||
/* Allocate memory for the title */
|
||||
CsrAllocateMessagePointer(CaptureBuffer,
|
||||
CommandData->TitleLen,
|
||||
(PVOID*)&GetNextVdmCommand->Title);
|
||||
}
|
||||
|
||||
if (CommandData->ReservedLen)
|
||||
{
|
||||
/* Allocate memory for the reserved parameter */
|
||||
CsrAllocateMessagePointer(CaptureBuffer,
|
||||
CommandData->ReservedLen,
|
||||
(PVOID*)&GetNextVdmCommand->Reserved);
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
/* Call CSRSS */
|
||||
Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
|
||||
CaptureBuffer,
|
||||
CSR_CREATE_API_NUMBER(BASESRV_SERVERDLL_INDEX, BasepGetNextVDMCommand),
|
||||
sizeof(BASE_GET_NEXT_VDM_COMMAND));
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
BaseSetLastNTError(Status);
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
/* Did we receive an event handle? */
|
||||
if (GetNextVdmCommand->WaitObjectForVDM != NULL)
|
||||
{
|
||||
/* Wait for the event to become signaled and try again */
|
||||
Status = NtWaitForSingleObject(GetNextVdmCommand->WaitObjectForVDM,
|
||||
FALSE,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
BaseSetLastNTError(Status);
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
/* Set the retry flag and clear the exit code */
|
||||
GetNextVdmCommand->VDMState |= VDM_FLAG_RETRY;
|
||||
GetNextVdmCommand->ExitCode = 0;
|
||||
}
|
||||
}
|
||||
while (GetNextVdmCommand->WaitObjectForVDM != NULL);
|
||||
|
||||
/* Write back the standard handles */
|
||||
CommandData->StdIn = GetNextVdmCommand->StdIn;
|
||||
CommandData->StdOut = GetNextVdmCommand->StdOut;
|
||||
CommandData->StdErr = GetNextVdmCommand->StdErr;
|
||||
|
||||
/* Write back the startup info */
|
||||
RtlMoveMemory(&CommandData->StartupInfo,
|
||||
GetNextVdmCommand->StartupInfo,
|
||||
sizeof(STARTUPINFOA));
|
||||
|
||||
if (CommandData->CmdLen)
|
||||
{
|
||||
/* Write back the command line */
|
||||
RtlMoveMemory(CommandData->CmdLine,
|
||||
GetNextVdmCommand->CmdLine,
|
||||
GetNextVdmCommand->CmdLen);
|
||||
|
||||
/* Set the actual length */
|
||||
CommandData->CmdLen = GetNextVdmCommand->CmdLen;
|
||||
}
|
||||
|
||||
if (CommandData->AppLen)
|
||||
{
|
||||
/* Write back the application name */
|
||||
RtlMoveMemory(CommandData->AppName,
|
||||
GetNextVdmCommand->AppName,
|
||||
GetNextVdmCommand->AppLen);
|
||||
|
||||
/* Set the actual length */
|
||||
CommandData->AppLen = GetNextVdmCommand->AppLen;
|
||||
}
|
||||
|
||||
if (CommandData->PifLen)
|
||||
{
|
||||
/* Write back the PIF file name */
|
||||
RtlMoveMemory(CommandData->PifFile,
|
||||
GetNextVdmCommand->PifFile,
|
||||
GetNextVdmCommand->PifLen);
|
||||
|
||||
/* Set the actual length */
|
||||
CommandData->PifLen = GetNextVdmCommand->PifLen;
|
||||
}
|
||||
|
||||
if (CommandData->CurDirectoryLen)
|
||||
{
|
||||
/* Write back the current directory */
|
||||
RtlMoveMemory(CommandData->CurDirectory,
|
||||
GetNextVdmCommand->CurDirectory,
|
||||
GetNextVdmCommand->CurDirectoryLen);
|
||||
|
||||
/* Set the actual length */
|
||||
CommandData->CurDirectoryLen = GetNextVdmCommand->CurDirectoryLen;
|
||||
}
|
||||
|
||||
if (CommandData->EnvLen)
|
||||
{
|
||||
/* Write back the environment */
|
||||
RtlMoveMemory(CommandData->Env,
|
||||
GetNextVdmCommand->Env,
|
||||
GetNextVdmCommand->EnvLen);
|
||||
|
||||
/* Set the actual length */
|
||||
CommandData->EnvLen = GetNextVdmCommand->EnvLen;
|
||||
}
|
||||
|
||||
if (CommandData->DesktopLen)
|
||||
{
|
||||
/* Write back the desktop name */
|
||||
RtlMoveMemory(CommandData->Desktop,
|
||||
GetNextVdmCommand->Desktop,
|
||||
GetNextVdmCommand->DesktopLen);
|
||||
|
||||
/* Set the actual length */
|
||||
CommandData->DesktopLen = GetNextVdmCommand->DesktopLen;
|
||||
}
|
||||
|
||||
if (CommandData->TitleLen)
|
||||
{
|
||||
/* Write back the title */
|
||||
RtlMoveMemory(CommandData->Title,
|
||||
GetNextVdmCommand->Title,
|
||||
GetNextVdmCommand->TitleLen);
|
||||
|
||||
/* Set the actual length */
|
||||
CommandData->TitleLen = GetNextVdmCommand->TitleLen;
|
||||
}
|
||||
|
||||
if (CommandData->ReservedLen)
|
||||
{
|
||||
/* Write back the reserved parameter */
|
||||
RtlMoveMemory(CommandData->Reserved,
|
||||
GetNextVdmCommand->Reserved,
|
||||
GetNextVdmCommand->ReservedLen);
|
||||
|
||||
/* Set the actual length */
|
||||
CommandData->ReservedLen = GetNextVdmCommand->ReservedLen;
|
||||
}
|
||||
|
||||
/* Write the remaining output parameters */
|
||||
CommandData->TaskId = GetNextVdmCommand->iTask;
|
||||
CommandData->CreationFlags = GetNextVdmCommand->dwCreationFlags;
|
||||
CommandData->CodePage = GetNextVdmCommand->CodePage;
|
||||
CommandData->ExitCode = GetNextVdmCommand->ExitCode;
|
||||
CommandData->CurrentDrive = GetNextVdmCommand->CurrentDrive;
|
||||
CommandData->VDMState = GetNextVdmCommand->VDMState;
|
||||
CommandData->ComingFromBat = GetNextVdmCommand->fComingFromBat;
|
||||
|
||||
/* It was successful */
|
||||
Result = TRUE;
|
||||
}
|
||||
else if ((CommandData->VDMState == VDM_INC_REENTER_COUNT)
|
||||
|| (CommandData->VDMState == VDM_DEC_REENTER_COUNT))
|
||||
{
|
||||
/* Setup the input parameters */
|
||||
SetReenterCount->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
|
||||
SetReenterCount->fIncDec = CommandData->VDMState;
|
||||
|
||||
/* Call CSRSS */
|
||||
Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
|
||||
NULL,
|
||||
CSR_CREATE_API_NUMBER(BASESRV_SERVERDLL_INDEX, BasepSetReenterCount),
|
||||
sizeof(BASE_SET_REENTER_COUNT));
|
||||
BaseSetLastNTError(Status);
|
||||
Result = NT_SUCCESS(Status);
|
||||
}
|
||||
else
|
||||
{
|
||||
BaseSetLastNTError(STATUS_INVALID_PARAMETER);
|
||||
Result = FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Call CSRSS */
|
||||
Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
|
||||
NULL,
|
||||
CSR_CREATE_API_NUMBER(BASESRV_SERVERDLL_INDEX, BasepIsFirstVDM),
|
||||
sizeof(BASE_IS_FIRST_VDM));
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
BaseSetLastNTError(Status);
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
/* Return TRUE if this is the first VDM */
|
||||
Result = IsFirstVdm->FirstVDM;
|
||||
}
|
||||
|
||||
Cleanup:
|
||||
if (CaptureBuffer != NULL) CsrFreeCaptureBuffer(CaptureBuffer);
|
||||
return Result;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
* @implemented
|
||||
*/
|
||||
DWORD
|
||||
WINAPI
|
||||
GetNextVDMCommand (
|
||||
DWORD Unknown0
|
||||
)
|
||||
GetVDMCurrentDirectories(DWORD cchCurDirs, PCHAR lpszzCurDirs)
|
||||
{
|
||||
STUB;
|
||||
return 0;
|
||||
}
|
||||
BASE_API_MESSAGE ApiMessage;
|
||||
PBASE_GETSET_VDM_CURDIRS VDMCurrentDirsRequest = &ApiMessage.Data.VDMCurrentDirsRequest;
|
||||
PCSR_CAPTURE_BUFFER CaptureBuffer;
|
||||
|
||||
/* Allocate the capture buffer */
|
||||
CaptureBuffer = CsrAllocateCaptureBuffer(1, cchCurDirs);
|
||||
if (CaptureBuffer == NULL)
|
||||
{
|
||||
BaseSetLastNTError(STATUS_NO_MEMORY);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
DWORD
|
||||
WINAPI
|
||||
GetVDMCurrentDirectories (
|
||||
DWORD Unknown0,
|
||||
DWORD Unknown1
|
||||
)
|
||||
{
|
||||
STUB;
|
||||
return 0;
|
||||
/* Setup the input parameters */
|
||||
VDMCurrentDirsRequest->cchCurDirs = cchCurDirs;
|
||||
CsrAllocateMessagePointer(CaptureBuffer,
|
||||
cchCurDirs,
|
||||
(PVOID*)&VDMCurrentDirsRequest->lpszzCurDirs);
|
||||
|
||||
/* Call CSRSS */
|
||||
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
|
||||
CaptureBuffer,
|
||||
CSR_CREATE_API_NUMBER(BASESRV_SERVERDLL_INDEX, BasepGetVDMCurDirs),
|
||||
sizeof(BASE_GETSET_VDM_CURDIRS));
|
||||
|
||||
/* Set the last error */
|
||||
BaseSetLastNTError(ApiMessage.Status);
|
||||
|
||||
if (NT_SUCCESS(ApiMessage.Status))
|
||||
{
|
||||
/* Copy the result */
|
||||
RtlMoveMemory(lpszzCurDirs, VDMCurrentDirsRequest->lpszzCurDirs, cchCurDirs);
|
||||
}
|
||||
|
||||
/* Free the capture buffer */
|
||||
CsrFreeCaptureBuffer(CaptureBuffer);
|
||||
|
||||
/* Return the size if it was successful, or if the buffer was too small */
|
||||
return (NT_SUCCESS(ApiMessage.Status) || (ApiMessage.Status == STATUS_BUFFER_TOO_SMALL))
|
||||
? VDMCurrentDirsRequest->cchCurDirs : 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -851,17 +1547,44 @@ RegisterWowExec (
|
|||
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
WINAPI
|
||||
SetVDMCurrentDirectories (
|
||||
DWORD Unknown0,
|
||||
DWORD Unknown1
|
||||
)
|
||||
SetVDMCurrentDirectories(DWORD cchCurDirs, PCHAR lpszzCurDirs)
|
||||
{
|
||||
STUB;
|
||||
return FALSE;
|
||||
BASE_API_MESSAGE ApiMessage;
|
||||
PBASE_GETSET_VDM_CURDIRS VDMCurrentDirsRequest = &ApiMessage.Data.VDMCurrentDirsRequest;
|
||||
PCSR_CAPTURE_BUFFER CaptureBuffer;
|
||||
|
||||
/* Allocate the capture buffer */
|
||||
CaptureBuffer = CsrAllocateCaptureBuffer(1, cchCurDirs);
|
||||
if (CaptureBuffer == NULL)
|
||||
{
|
||||
BaseSetLastNTError(STATUS_NO_MEMORY);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Setup the input parameters */
|
||||
VDMCurrentDirsRequest->cchCurDirs = cchCurDirs;
|
||||
CsrCaptureMessageBuffer(CaptureBuffer,
|
||||
lpszzCurDirs,
|
||||
cchCurDirs,
|
||||
(PVOID*)&VDMCurrentDirsRequest->lpszzCurDirs);
|
||||
|
||||
/* Call CSRSS */
|
||||
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
|
||||
CaptureBuffer,
|
||||
CSR_CREATE_API_NUMBER(BASESRV_SERVERDLL_INDEX, BasepSetVDMCurDirs),
|
||||
sizeof(BASE_GETSET_VDM_CURDIRS));
|
||||
|
||||
/* Free the capture buffer */
|
||||
CsrFreeCaptureBuffer(CaptureBuffer);
|
||||
|
||||
/* Set the last error */
|
||||
BaseSetLastNTError(ApiMessage.Status);
|
||||
|
||||
return NT_SUCCESS(ApiMessage.Status) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -882,12 +1605,15 @@ VDMConsoleOperation (
|
|||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
DWORD
|
||||
BOOL
|
||||
WINAPI
|
||||
VDMOperationStarted (
|
||||
DWORD Unknown0
|
||||
)
|
||||
VDMOperationStarted(IN ULONG Unknown0)
|
||||
{
|
||||
STUB;
|
||||
return 0;
|
||||
DPRINT1("VDMOperationStarted(%d)\n", Unknown0);
|
||||
|
||||
return
|
||||
BaseUpdateVDMEntry(VdmEntryUpdateControlCHandler,
|
||||
NULL,
|
||||
0,
|
||||
Unknown0);
|
||||
}
|
||||
|
|
|
@ -8,42 +8,6 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
/* CONSTANTS ******************************************************************/
|
||||
|
||||
typedef enum _VDM_ENTRY_CODE
|
||||
{
|
||||
VdmEntryUndo,
|
||||
VdmEntryUpdateProcess,
|
||||
VdmEntryUpdateControlCHandler
|
||||
} VDM_ENTRY_CODE;
|
||||
|
||||
//
|
||||
// Undo States
|
||||
//
|
||||
#define VDM_UNDO_PARTIAL 0x01
|
||||
#define VDM_UNDO_FULL 0x02
|
||||
#define VDM_UNDO_REUSE 0x04
|
||||
#define VDM_UNDO_COMPLETED 0x08
|
||||
|
||||
//
|
||||
// Binary Types to share with VDM
|
||||
//
|
||||
#define BINARY_TYPE_EXE 0x01
|
||||
#define BINARY_TYPE_COM 0x02
|
||||
#define BINARY_TYPE_PIF 0x03
|
||||
#define BINARY_TYPE_DOS 0x10
|
||||
#define BINARY_TYPE_SEPARATE_WOW 0x20
|
||||
#define BINARY_TYPE_WOW 0x40
|
||||
#define BINARY_TYPE_WOW_EX 0x80
|
||||
|
||||
//
|
||||
// VDM States
|
||||
//
|
||||
#define VDM_NOT_LOADED 0x01
|
||||
#define VDM_NOT_READY 0x02
|
||||
#define VDM_READY 0x04
|
||||
|
||||
|
||||
/* FUNCTION PROTOTYPES ********************************************************/
|
||||
|
||||
BOOL
|
||||
|
@ -87,7 +51,7 @@ BaseCheckForVDM(
|
|||
OUT LPDWORD ExitCode
|
||||
);
|
||||
|
||||
BOOL
|
||||
NTSTATUS
|
||||
WINAPI
|
||||
BaseCheckVDM(
|
||||
IN ULONG BinaryType,
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#include <win/basemsg.h>
|
||||
#include <win/console.h>
|
||||
#include <win/conmsg.h>
|
||||
#include <win/vdm.h>
|
||||
|
||||
/* DDK Driver Headers */
|
||||
#include <mountmgr.h>
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
* Samuel Serapión
|
||||
*/
|
||||
|
||||
/* synched with wine 1.1.26 */
|
||||
/* Partly synched with Wine 1.7.17 */
|
||||
|
||||
#include <k32.h>
|
||||
|
||||
|
@ -178,11 +178,15 @@ BOOL WINAPI FindActCtxSectionGuid(DWORD dwFlags, const GUID* lpExtGuid,
|
|||
ULONG ulId, const GUID* lpSearchGuid,
|
||||
PACTCTX_SECTION_KEYED_DATA pInfo)
|
||||
{
|
||||
FIXME("%08x %s %u %s %p\n", dwFlags, debugstr_guid(lpExtGuid),
|
||||
ulId, debugstr_guid(lpSearchGuid), pInfo);
|
||||
SetLastError( ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return FALSE;
|
||||
NTSTATUS status;
|
||||
|
||||
if ((status = RtlFindActivationContextSectionGuid(dwFlags, lpExtGuid, ulId, lpSearchGuid, pInfo)))
|
||||
{
|
||||
SetLastError(RtlNtStatusToDosError(status));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -480,8 +480,8 @@ SockReenableAsyncSelectEvent (
|
|||
|
||||
typedef VOID (*PASYNC_COMPLETION_ROUTINE)(PVOID Context, PIO_STATUS_BLOCK IoStatusBlock);
|
||||
|
||||
DWORD
|
||||
FORCEINLINE
|
||||
DWORD
|
||||
MsafdReturnWithErrno(NTSTATUS Status,
|
||||
LPINT Errno,
|
||||
DWORD Received,
|
||||
|
|
|
@ -25,12 +25,12 @@
|
|||
struct NBCmdQueue;
|
||||
|
||||
/* Allocates a new command queue from heap. */
|
||||
struct NBCmdQueue *NBCmdQueueCreate(HANDLE heap);
|
||||
struct NBCmdQueue *NBCmdQueueCreate(HANDLE heap) DECLSPEC_HIDDEN;
|
||||
|
||||
/* Adds ncb to queue. Assumes queue is not NULL, and ncb is not already in the
|
||||
* queue. If ncb is already in the queue, returns NRC_TOOMANY.
|
||||
*/
|
||||
UCHAR NBCmdQueueAdd(struct NBCmdQueue *queue, PNCB ncb);
|
||||
UCHAR NBCmdQueueAdd(struct NBCmdQueue *queue, PNCB ncb) DECLSPEC_HIDDEN;
|
||||
|
||||
/* Cancels the given ncb. Blocks until the command completes. Implicitly
|
||||
* removes ncb from the queue. Assumes queue and ncb are not NULL, and that
|
||||
|
@ -39,23 +39,23 @@ UCHAR NBCmdQueueAdd(struct NBCmdQueue *queue, PNCB ncb);
|
|||
* completed before it could be cancelled, and various other return values for
|
||||
* different failures.
|
||||
*/
|
||||
UCHAR NBCmdQueueCancel(struct NBCmdQueue *queue, PNCB ncb);
|
||||
UCHAR NBCmdQueueCancel(struct NBCmdQueue *queue, PNCB ncb) DECLSPEC_HIDDEN;
|
||||
|
||||
/* Sets the return code of the given ncb, and implicitly removes the command
|
||||
* from the queue. Assumes queue and ncb are not NULL, and that ncb has been
|
||||
* added to queue previously.
|
||||
* Returns NRC_GOODRET on success.
|
||||
*/
|
||||
UCHAR NBCmdQueueComplete(struct NBCmdQueue *queue, PNCB ncb, UCHAR retcode);
|
||||
UCHAR NBCmdQueueComplete(struct NBCmdQueue *queue, PNCB ncb, UCHAR retcode) DECLSPEC_HIDDEN;
|
||||
|
||||
/* Cancels all pending commands in the queue (useful for a RESET or a shutdown).
|
||||
* Returns when all commands have been completed.
|
||||
*/
|
||||
UCHAR NBCmdQueueCancelAll(struct NBCmdQueue *queue);
|
||||
UCHAR NBCmdQueueCancelAll(struct NBCmdQueue *queue) DECLSPEC_HIDDEN;
|
||||
|
||||
/* Frees all memory associated with the queue. Blocks until all commands
|
||||
* pending in the queue have been completed.
|
||||
*/
|
||||
void NBCmdQueueDestroy(struct NBCmdQueue *queue);
|
||||
void NBCmdQueueDestroy(struct NBCmdQueue *queue) DECLSPEC_HIDDEN;
|
||||
|
||||
#endif /* __NBCMDQUEUE_H__ */
|
||||
|
|
|
@ -45,7 +45,7 @@ typedef struct _NBNameCacheEntry
|
|||
/* Allocates a new name cache from heap, and sets the expire time on new
|
||||
* entries to entryExpireTimeMS after a cache entry is added.
|
||||
*/
|
||||
struct NBNameCache *NBNameCacheCreate(HANDLE heap, DWORD entryExpireTimeMS);
|
||||
struct NBNameCache *NBNameCacheCreate(HANDLE heap, DWORD entryExpireTimeMS) DECLSPEC_HIDDEN;
|
||||
|
||||
/* Adds an entry to the cache. The entry is assumed to have been allocated
|
||||
* from the same heap as the name cache; the name cache will own the entry
|
||||
|
@ -54,14 +54,14 @@ struct NBNameCache *NBNameCacheCreate(HANDLE heap, DWORD entryExpireTimeMS);
|
|||
* same name was in the cache, the entry is replaced. Returns TRUE on success
|
||||
* or FALSE on failure.
|
||||
*/
|
||||
BOOL NBNameCacheAddEntry(struct NBNameCache *cache, NBNameCacheEntry *entry);
|
||||
BOOL NBNameCacheAddEntry(struct NBNameCache *cache, NBNameCacheEntry *entry) DECLSPEC_HIDDEN;
|
||||
|
||||
/* Finds the entry with name name in the cache and returns a pointer to it, or
|
||||
* NULL if it isn't found.
|
||||
*/
|
||||
const NBNameCacheEntry *NBNameCacheFindEntry(struct NBNameCache *cache,
|
||||
const UCHAR name[NCBNAMSZ]);
|
||||
const UCHAR name[NCBNAMSZ]) DECLSPEC_HIDDEN;
|
||||
|
||||
void NBNameCacheDestroy(struct NBNameCache *cache);
|
||||
void NBNameCacheDestroy(struct NBNameCache *cache) DECLSPEC_HIDDEN;
|
||||
|
||||
#endif /* ndef __WINE_NBNAMECACHE_H */
|
||||
|
|
|
@ -289,7 +289,7 @@ static UCHAR NetBTWaitForNameResponse(const NetBTAdapter *adapter, SOCKET fd,
|
|||
if (fd == INVALID_SOCKET) return NRC_BADDR;
|
||||
if (!answerCallback) return NRC_BADDR;
|
||||
|
||||
while (!found && ret == NRC_GOODRET && (now = GetTickCount()) < waitUntil)
|
||||
while (!found && ret == NRC_GOODRET && (int)((now = GetTickCount()) - waitUntil) < 0)
|
||||
{
|
||||
DWORD msToWait = waitUntil - now;
|
||||
struct fd_set fds;
|
||||
|
@ -399,9 +399,8 @@ static BOOL NetBTFindNameAnswerCallback(void *pVoid, WORD answerCount,
|
|||
{
|
||||
if (queryData->cacheEntry == NULL)
|
||||
{
|
||||
queryData->cacheEntry = HeapAlloc(
|
||||
GetProcessHeap(), 0, sizeof(NBNameCacheEntry) +
|
||||
(answerCount - 1) * sizeof(DWORD));
|
||||
queryData->cacheEntry = HeapAlloc(GetProcessHeap(), 0,
|
||||
FIELD_OFFSET(NBNameCacheEntry, addresses[answerCount]));
|
||||
if (queryData->cacheEntry)
|
||||
queryData->cacheEntry->numAddresses = 0;
|
||||
else
|
||||
|
@ -533,8 +532,8 @@ static UCHAR NetBTinetResolve(const UCHAR name[NCBNAMSZ],
|
|||
|
||||
if (addr != INADDR_NONE)
|
||||
{
|
||||
*cacheEntry = HeapAlloc(GetProcessHeap(),
|
||||
0, sizeof(NBNameCacheEntry));
|
||||
*cacheEntry = HeapAlloc(GetProcessHeap(), 0,
|
||||
FIELD_OFFSET(NBNameCacheEntry, addresses[1]));
|
||||
if (*cacheEntry)
|
||||
{
|
||||
memcpy((*cacheEntry)->name, name, NCBNAMSZ);
|
||||
|
@ -558,9 +557,8 @@ static UCHAR NetBTinetResolve(const UCHAR name[NCBNAMSZ],
|
|||
;
|
||||
if (host->h_addr_list && host->h_addr_list[0])
|
||||
{
|
||||
*cacheEntry = HeapAlloc(
|
||||
GetProcessHeap(), 0, sizeof(NBNameCacheEntry) +
|
||||
(i - 1) * sizeof(DWORD));
|
||||
*cacheEntry = HeapAlloc(GetProcessHeap(), 0,
|
||||
FIELD_OFFSET(NBNameCacheEntry, addresses[i]));
|
||||
if (*cacheEntry)
|
||||
{
|
||||
memcpy((*cacheEntry)->name, name, NCBNAMSZ);
|
||||
|
@ -569,7 +567,7 @@ static UCHAR NetBTinetResolve(const UCHAR name[NCBNAMSZ],
|
|||
(*cacheEntry)->numAddresses = i;
|
||||
for (i = 0; i < (*cacheEntry)->numAddresses; i++)
|
||||
(*cacheEntry)->addresses[i] =
|
||||
(DWORD)host->h_addr_list[i];
|
||||
*(DWORD*)host->h_addr_list[i];
|
||||
}
|
||||
else
|
||||
ret = NRC_OSRESNOTAV;
|
||||
|
@ -995,7 +993,7 @@ static UCHAR NetBTCall(void *adapt, PNCB ncb, void **sess)
|
|||
setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout,
|
||||
sizeof(timeout));
|
||||
}
|
||||
if (ncb->ncb_rto > 0)
|
||||
if (ncb->ncb_sto > 0)
|
||||
{
|
||||
timeout = ncb->ncb_sto * 500;
|
||||
setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (char*)&timeout,
|
||||
|
@ -1489,13 +1487,17 @@ void NetBTInit(void)
|
|||
NetBTNameEncode */
|
||||
char *ptr, *lenPtr;
|
||||
|
||||
for (ptr = gScopeID + 1; ptr - gScopeID < sizeof(gScopeID) && *ptr; )
|
||||
for (ptr = gScopeID + 1, lenPtr = gScopeID; ptr - gScopeID < sizeof(gScopeID) && *ptr; ++ptr)
|
||||
{
|
||||
for (lenPtr = ptr - 1, *lenPtr = 0;
|
||||
ptr - gScopeID < sizeof(gScopeID) && *ptr && *ptr != '.';
|
||||
ptr++)
|
||||
*lenPtr += 1;
|
||||
ptr++;
|
||||
if (*ptr == '.')
|
||||
{
|
||||
lenPtr = ptr;
|
||||
*lenPtr = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
++*lenPtr;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (RegQueryValueExW(hKey, CacheTimeoutW, NULL, NULL,
|
||||
|
|
|
@ -20,9 +20,7 @@
|
|||
|
||||
#include <lmserver.h>
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(netbios);
|
||||
|
||||
static HMODULE NETAPI32_hModule;
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(netapi32);
|
||||
|
||||
BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||
{
|
||||
|
@ -30,18 +28,14 @@ BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
|||
|
||||
switch (fdwReason) {
|
||||
case DLL_PROCESS_ATTACH:
|
||||
{
|
||||
DisableThreadLibraryCalls(hinstDLL);
|
||||
NETAPI32_hModule = hinstDLL;
|
||||
NetBIOSInit();
|
||||
NetBTInit();
|
||||
break;
|
||||
}
|
||||
case DLL_PROCESS_DETACH:
|
||||
{
|
||||
if (lpvReserved) break;
|
||||
NetBIOSShutdown();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
@ -83,10 +77,28 @@ NET_API_STATUS WINAPI NetServerEnumEx(
|
|||
LMCSTR domain,
|
||||
LMCSTR FirstNameToReturn)
|
||||
{
|
||||
FIXME("Stub (%s %d %p %d %p %p %d %s %p)\n", debugstr_w(ServerName),
|
||||
Level, Bufptr, PrefMaxlen, EntriesRead, totalentries, servertype,
|
||||
debugstr_w(domain), debugstr_w(FirstNameToReturn));
|
||||
|
||||
FIXME("Stub (%s %d %p %d %p %p %d %s %s)\n",
|
||||
debugstr_w(ServerName), Level, Bufptr, PrefMaxlen, EntriesRead, totalentries,
|
||||
servertype, debugstr_w(domain), debugstr_w(FirstNameToReturn));
|
||||
|
||||
return ERROR_NO_BROWSER_SERVERS_FOUND;
|
||||
}
|
||||
|
||||
/************************************************************
|
||||
* NetServerDiskEnum (NETAPI32.@)
|
||||
*/
|
||||
NET_API_STATUS WINAPI NetServerDiskEnum(
|
||||
LMSTR ServerName,
|
||||
DWORD Level,
|
||||
LPBYTE *Bufptr,
|
||||
DWORD PrefMaxlen,
|
||||
LPDWORD EntriesRead,
|
||||
LPDWORD totalentries,
|
||||
LPDWORD Resume_Handle)
|
||||
{
|
||||
FIXME("Stub (%s %d %p %d %p %p %p)\n", debugstr_w(ServerName),
|
||||
Level, Bufptr, PrefMaxlen, EntriesRead, totalentries, Resume_Handle);
|
||||
|
||||
return ERROR_NO_BROWSER_SERVERS_FOUND;
|
||||
}
|
||||
|
||||
|
@ -162,51 +174,6 @@ NET_API_STATUS WINAPI NetStatisticsGet(LMSTR server, LMSTR service,
|
|||
return NERR_InternalError;
|
||||
}
|
||||
|
||||
DWORD WINAPI NetpNetBiosStatusToApiStatus(DWORD nrc)
|
||||
{
|
||||
DWORD ret;
|
||||
|
||||
switch (nrc)
|
||||
{
|
||||
case NRC_GOODRET:
|
||||
ret = NO_ERROR;
|
||||
break;
|
||||
case NRC_NORES:
|
||||
ret = NERR_NoNetworkResource;
|
||||
break;
|
||||
case NRC_DUPNAME:
|
||||
ret = NERR_AlreadyExists;
|
||||
break;
|
||||
case NRC_NAMTFUL:
|
||||
ret = NERR_TooManyNames;
|
||||
break;
|
||||
case NRC_ACTSES:
|
||||
ret = NERR_DeleteLater;
|
||||
break;
|
||||
case NRC_REMTFUL:
|
||||
ret = ERROR_REM_NOT_LIST;
|
||||
break;
|
||||
case NRC_NOCALL:
|
||||
ret = NERR_NameNotFound;
|
||||
break;
|
||||
case NRC_NOWILD:
|
||||
ret = ERROR_INVALID_PARAMETER;
|
||||
break;
|
||||
case NRC_INUSE:
|
||||
ret = NERR_DuplicateName;
|
||||
break;
|
||||
case NRC_NAMERR:
|
||||
ret = ERROR_INVALID_PARAMETER;
|
||||
break;
|
||||
case NRC_NAMCONF:
|
||||
ret = NERR_DuplicateName;
|
||||
break;
|
||||
default:
|
||||
ret = NERR_NetworkError;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
NET_API_STATUS
|
||||
WINAPI
|
||||
NetpNtStatusToApiStatus(NTSTATUS Status)
|
||||
|
@ -242,3 +209,31 @@ NET_API_STATUS WINAPI NetUseEnum(LMSTR server, DWORD level, LPBYTE* bufptr, DWOR
|
|||
entriesread, totalentries, resumehandle);
|
||||
return ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
NET_API_STATUS WINAPI NetScheduleJobAdd(LPCWSTR server, LPBYTE bufptr, LPDWORD jobid)
|
||||
{
|
||||
FIXME("stub (%s, %p, %p)\n", debugstr_w(server), bufptr, jobid);
|
||||
return NERR_Success;
|
||||
}
|
||||
|
||||
NET_API_STATUS WINAPI NetScheduleJobDel(LPCWSTR server, DWORD minjobid, DWORD maxjobid)
|
||||
{
|
||||
FIXME("stub (%s, %d, %d)\n", debugstr_w(server), minjobid, maxjobid);
|
||||
return NERR_Success;
|
||||
}
|
||||
|
||||
NET_API_STATUS WINAPI NetScheduleJobEnum(LPCWSTR server, LPBYTE* bufptr, DWORD prefmaxsize, LPDWORD entriesread,
|
||||
LPDWORD totalentries, LPDWORD resumehandle)
|
||||
{
|
||||
FIXME("stub (%s, %p, %d, %p, %p, %p)\n", debugstr_w(server), bufptr, prefmaxsize, entriesread, totalentries, resumehandle);
|
||||
*entriesread = 0;
|
||||
*totalentries = 0;
|
||||
return NERR_Success;
|
||||
}
|
||||
|
||||
NET_API_STATUS WINAPI NetUseGetInfo(LMSTR server, LMSTR name, DWORD level, LPBYTE *bufptr)
|
||||
{
|
||||
FIXME("stub (%p, %p, %d, %p)\n", server, name, level, bufptr);
|
||||
return ERROR_NOT_SUPPORTED;
|
||||
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <iphlpapi.h>
|
||||
|
||||
#include <wine/debug.h>
|
||||
#include <wine/unicode.h>
|
||||
|
||||
#define NTOS_MODE_USER
|
||||
#include <ndk/rtlfuncs.h>
|
||||
|
|
|
@ -201,13 +201,13 @@
|
|||
@ stub NetReplImportDirLock
|
||||
@ stub NetReplImportDirUnlock
|
||||
@ stub NetReplSetInfo
|
||||
@ stub NetScheduleJobAdd
|
||||
@ stub NetScheduleJobDel
|
||||
@ stub NetScheduleJobEnum
|
||||
@ stdcall NetScheduleJobAdd(wstr ptr ptr)
|
||||
@ stdcall NetScheduleJobDel(wstr long long)
|
||||
@ stdcall NetScheduleJobEnum(wstr ptr long ptr ptr ptr)
|
||||
@ stub NetScheduleJobGetInfo
|
||||
@ stub NetServerComputerNameAdd
|
||||
@ stub NetServerComputerNameDel
|
||||
@ stub NetServerDiskEnum
|
||||
@ stdcall NetServerDiskEnum(wstr long ptr long ptr ptr ptr)
|
||||
@ stdcall NetServerEnum(wstr long ptr long ptr ptr long wstr ptr)
|
||||
@ stdcall NetServerEnumEx(wstr long ptr long ptr ptr long wstr wstr)
|
||||
@ stdcall NetServerGetInfo(wstr long ptr)
|
||||
|
@ -238,7 +238,7 @@
|
|||
@ stdcall NetUseAdd(wstr long ptr ptr)
|
||||
@ stub NetUseDel
|
||||
@ stdcall NetUseEnum(wstr long ptr long ptr ptr ptr)
|
||||
@ stub NetUseGetInfo
|
||||
@ stdcall NetUseGetInfo(ptr ptr long ptr)
|
||||
@ stdcall NetUserAdd(wstr long ptr ptr)
|
||||
@ stdcall NetUserChangePassword(wstr wstr wstr wstr)
|
||||
@ stdcall NetUserDel(wstr wstr)
|
||||
|
|
|
@ -49,7 +49,7 @@ typedef struct _NetBIOSSession
|
|||
* is not NULL, the adapter is considered valid. (transport is a pointer to
|
||||
* an entry in a NetBIOSTransportTableEntry.) data has data for the callers of
|
||||
* NetBIOSEnumAdapters to be able to see. The lana is repeated there, even
|
||||
* though I don't use it internally--it's for transports to use reenabling
|
||||
* though I don't use it internally--it's for transports to use re-enabling
|
||||
* adapters using NetBIOSEnableAdapter.
|
||||
*/
|
||||
typedef struct _NetBIOSAdapter
|
||||
|
@ -858,3 +858,48 @@ UCHAR WINAPI Netbios(PNCB ncb)
|
|||
TRACE("returning 0x%02x\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
DWORD WINAPI NetpNetBiosStatusToApiStatus(DWORD nrc)
|
||||
{
|
||||
DWORD ret;
|
||||
|
||||
switch (nrc)
|
||||
{
|
||||
case NRC_GOODRET:
|
||||
ret = NO_ERROR;
|
||||
break;
|
||||
case NRC_NORES:
|
||||
ret = NERR_NoNetworkResource;
|
||||
break;
|
||||
case NRC_DUPNAME:
|
||||
ret = NERR_AlreadyExists;
|
||||
break;
|
||||
case NRC_NAMTFUL:
|
||||
ret = NERR_TooManyNames;
|
||||
break;
|
||||
case NRC_ACTSES:
|
||||
ret = NERR_DeleteLater;
|
||||
break;
|
||||
case NRC_REMTFUL:
|
||||
ret = ERROR_REM_NOT_LIST;
|
||||
break;
|
||||
case NRC_NOCALL:
|
||||
ret = NERR_NameNotFound;
|
||||
break;
|
||||
case NRC_NOWILD:
|
||||
ret = ERROR_INVALID_PARAMETER;
|
||||
break;
|
||||
case NRC_INUSE:
|
||||
ret = NERR_DuplicateName;
|
||||
break;
|
||||
case NRC_NAMERR:
|
||||
ret = ERROR_INVALID_PARAMETER;
|
||||
break;
|
||||
case NRC_NAMCONF:
|
||||
ret = NERR_DuplicateName;
|
||||
break;
|
||||
default:
|
||||
ret = NERR_NetworkError;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -26,8 +26,8 @@
|
|||
* Public functions
|
||||
*/
|
||||
|
||||
void NetBIOSInit(void);
|
||||
void NetBIOSShutdown(void);
|
||||
void NetBIOSInit(void) DECLSPEC_HIDDEN;
|
||||
void NetBIOSShutdown(void) DECLSPEC_HIDDEN;
|
||||
|
||||
struct _NetBIOSTransport;
|
||||
|
||||
|
@ -35,7 +35,7 @@ struct _NetBIOSTransport;
|
|||
* a unique id (the transport_id of ACTION_HEADER, for example) and an
|
||||
* implementation. Returns TRUE on success, and FALSE on failure.
|
||||
*/
|
||||
BOOL NetBIOSRegisterTransport(ULONG id, struct _NetBIOSTransport *transport);
|
||||
BOOL NetBIOSRegisterTransport(ULONG id, struct _NetBIOSTransport *transport) DECLSPEC_HIDDEN;
|
||||
|
||||
/* Registers an adapter with the given transport and ifIndex with NetBIOS.
|
||||
* ifIndex is an interface index usable by the IpHlpApi. ifIndex is not
|
||||
|
@ -45,21 +45,21 @@ BOOL NetBIOSRegisterTransport(ULONG id, struct _NetBIOSTransport *transport);
|
|||
* FIXME: need functions for retrieving the name and hardware index, rather
|
||||
* than assuming a correlation with IpHlpApi.
|
||||
*/
|
||||
BOOL NetBIOSRegisterAdapter(ULONG transport, DWORD ifIndex, void *adapter);
|
||||
BOOL NetBIOSRegisterAdapter(ULONG transport, DWORD ifIndex, void *adapter) DECLSPEC_HIDDEN;
|
||||
|
||||
/* During enumeration, all adapters from your transport are disabled
|
||||
* internally. If an adapter is still valid, reenable it with this function.
|
||||
* internally. If an adapter is still valid, re-enable it with this function.
|
||||
* Adapters you don't enable will have their transport's NetBIOSCleanupAdapter
|
||||
* function (see below) called on them, and will be removed from the table.
|
||||
* (This is to deal with lack of plug-and-play--sorry.)
|
||||
*/
|
||||
void NetBIOSEnableAdapter(UCHAR lana);
|
||||
void NetBIOSEnableAdapter(UCHAR lana) DECLSPEC_HIDDEN;
|
||||
|
||||
/* Gets a quick count of the number of NetBIOS adapters. Not guaranteed not
|
||||
* to change from one call to the next, depending on what's been enumerated
|
||||
* lately. See also NetBIOSEnumAdapters.
|
||||
*/
|
||||
UCHAR NetBIOSNumAdapters(void);
|
||||
UCHAR NetBIOSNumAdapters(void) DECLSPEC_HIDDEN;
|
||||
|
||||
typedef struct _NetBIOSAdapterImpl {
|
||||
UCHAR lana;
|
||||
|
@ -78,7 +78,7 @@ typedef BOOL (*NetBIOSEnumAdaptersCallback)(UCHAR totalLANAs, UCHAR lanaIndex,
|
|||
* Your callback should return FALSE if it no longer wishes to be called.
|
||||
*/
|
||||
void NetBIOSEnumAdapters(ULONG transport, NetBIOSEnumAdaptersCallback cb,
|
||||
void *closure);
|
||||
void *closure) DECLSPEC_HIDDEN;
|
||||
|
||||
/* Hangs up the session identified in the NCB; the NCB need not be a NCBHANGUP.
|
||||
* Will result in the transport's hangup function being called, so release any
|
||||
|
@ -86,7 +86,7 @@ void NetBIOSEnumAdapters(ULONG transport, NetBIOSEnumAdaptersCallback cb,
|
|||
* This function is intended for use by a transport, if the session is closed
|
||||
* by some error in the transport layer.
|
||||
*/
|
||||
void NetBIOSHangupSession(const NCB *ncb);
|
||||
void NetBIOSHangupSession(const NCB *ncb) DECLSPEC_HIDDEN;
|
||||
|
||||
/**
|
||||
* Functions a transport implementation must implement
|
||||
|
@ -172,6 +172,6 @@ typedef struct _NetBIOSTransport
|
|||
/* Not defined by MS, so make my own private define: */
|
||||
#define TRANSPORT_NBT "MNBT"
|
||||
|
||||
void NetBTInit(void);
|
||||
void NetBTInit(void) DECLSPEC_HIDDEN;
|
||||
|
||||
#endif /* ndef __WINE_NETBIOS_H__ */
|
||||
|
|
|
@ -30,29 +30,17 @@ WINE_DEFAULT_DEBUG_CHANNEL(netapi32);
|
|||
*
|
||||
* Checks whether the server name indicates local machine.
|
||||
*/
|
||||
BOOL NETAPI_IsLocalComputer(LMCSTR ServerName)
|
||||
DECLSPEC_HIDDEN BOOL NETAPI_IsLocalComputer( LMCSTR name )
|
||||
{
|
||||
if (!ServerName)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
else if (ServerName[0] == '\0')
|
||||
return TRUE;
|
||||
else
|
||||
{
|
||||
DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
|
||||
BOOL Result;
|
||||
LPWSTR buf;
|
||||
WCHAR buf[MAX_COMPUTERNAME_LENGTH + 1];
|
||||
DWORD size = sizeof(buf) / sizeof(buf[0]);
|
||||
BOOL ret;
|
||||
|
||||
NetApiBufferAllocate(dwSize * sizeof(WCHAR), (LPVOID *) &buf);
|
||||
Result = GetComputerNameW(buf, &dwSize);
|
||||
if (Result && (ServerName[0] == '\\') && (ServerName[1] == '\\'))
|
||||
ServerName += 2;
|
||||
Result = Result && !lstrcmpW(ServerName, buf);
|
||||
NetApiBufferFree(buf);
|
||||
if (!name || !name[0]) return TRUE;
|
||||
|
||||
return Result;
|
||||
}
|
||||
ret = GetComputerNameW( buf, &size );
|
||||
if (ret && name[0] == '\\' && name[1] == '\\') name += 2;
|
||||
return ret && !strcmpiW( name, buf );
|
||||
}
|
||||
|
||||
static void wprint_mac(WCHAR* buffer, int len, const MIB_IFROW *ifRow)
|
||||
|
|
|
@ -3515,7 +3515,7 @@ BOOL WINAPI PathRelativePathToW(LPWSTR lpszPath, LPCWSTR lpszFrom, DWORD dwAttrF
|
|||
|
||||
if(!(dwAttrFrom & FILE_ATTRIBUTE_DIRECTORY))
|
||||
PathRemoveFileSpecW(szFrom);
|
||||
if(!(dwAttrFrom & FILE_ATTRIBUTE_DIRECTORY))
|
||||
if(!(dwAttrTo & FILE_ATTRIBUTE_DIRECTORY))
|
||||
PathRemoveFileSpecW(szTo);
|
||||
|
||||
/* Paths can only be relative if they have a common root */
|
||||
|
|
|
@ -22,7 +22,7 @@ static INT SCROLL_TrackingBar = 0;
|
|||
static INT SCROLL_TrackingPos = 0;
|
||||
static INT SCROLL_TrackingVal = 0;
|
||||
|
||||
void static ScreenToWindow( HWND hWnd, POINT* pt)
|
||||
static void ScreenToWindow( HWND hWnd, POINT* pt)
|
||||
{
|
||||
RECT rcWnd;
|
||||
GetWindowRect(hWnd, &rcWnd);
|
||||
|
|
|
@ -45,8 +45,8 @@ typedef VLONG *PVLONG;
|
|||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
VOID
|
||||
static __inline
|
||||
VOID
|
||||
AcquireReadLock(IN PWAH_SEARCH_TABLE Table,
|
||||
IN PVLONG *Count)
|
||||
{
|
||||
|
@ -70,8 +70,8 @@ AcquireReadLock(IN PWAH_SEARCH_TABLE Table,
|
|||
} while (TRUE);
|
||||
}
|
||||
|
||||
VOID
|
||||
static __inline
|
||||
VOID
|
||||
ReleaseReadLock(IN PWAH_SEARCH_TABLE Table,
|
||||
IN PVLONG Count)
|
||||
{
|
||||
|
@ -139,8 +139,8 @@ DoWaitForReaders(IN PWAH_SEARCH_TABLE Table,
|
|||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
static __inline
|
||||
VOID
|
||||
TryWaitForReaders(IN PWAH_SEARCH_TABLE Table)
|
||||
{
|
||||
PVLONG OldCount = Table->CurrentCount;
|
||||
|
|
|
@ -95,8 +95,8 @@ ReadWriteMode(UCHAR Mode)
|
|||
}
|
||||
|
||||
|
||||
VOID
|
||||
FORCEINLINE
|
||||
VOID
|
||||
SetPixel(IN ULONG Left,
|
||||
IN ULONG Top,
|
||||
IN UCHAR Color)
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
|
||||
PCHAR NmiBegin = "NMI4NMI@";
|
||||
|
||||
VOID
|
||||
FORCEINLINE
|
||||
VOID
|
||||
NmiClearFlag(VOID)
|
||||
{
|
||||
((PCHAR)&KiBugCheckData[4])[0] -= (NmiBegin[3] | NmiBegin[7]);
|
||||
|
|
|
@ -351,8 +351,8 @@ NpReleaseVcb(VOID)
|
|||
// Function to process deferred IRPs outside the VCB lock but still within the
|
||||
// critical region
|
||||
//
|
||||
VOID
|
||||
FORCEINLINE
|
||||
VOID
|
||||
NpCompleteDeferredIrps(IN PLIST_ENTRY DeferredList)
|
||||
{
|
||||
PLIST_ENTRY ThisEntry, NextEntry;
|
||||
|
|
|
@ -23,6 +23,10 @@ _Dispatch_type_(IRP_MJ_DEVICE_CONTROL)
|
|||
static DRIVER_DISPATCH i8042DeviceControl;
|
||||
_Dispatch_type_(IRP_MJ_INTERNAL_DEVICE_CONTROL)
|
||||
static DRIVER_DISPATCH i8042InternalDeviceControl;
|
||||
_Dispatch_type_(IRP_MJ_SYSTEM_CONTROL)
|
||||
static DRIVER_DISPATCH i8042SystemControl;
|
||||
_Dispatch_type_(IRP_MJ_POWER)
|
||||
static DRIVER_DISPATCH i8042Power;
|
||||
DRIVER_INITIALIZE DriverEntry;
|
||||
|
||||
NTSTATUS NTAPI
|
||||
|
@ -468,6 +472,27 @@ i8042InternalDeviceControl(
|
|||
return Status;
|
||||
}
|
||||
|
||||
static NTSTATUS NTAPI
|
||||
i8042Power(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
PFDO_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
|
||||
PDEVICE_OBJECT LowerDevice = DeviceExtension->LowerDevice;
|
||||
|
||||
PoStartNextPowerIrp(Irp);
|
||||
IoSkipCurrentIrpStackLocation(Irp);
|
||||
return PoCallDriver(LowerDevice, Irp);
|
||||
}
|
||||
|
||||
static NTSTATUS NTAPI
|
||||
i8042SystemControl(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
return ForwardIrpAndForget(DeviceObject, Irp);
|
||||
}
|
||||
|
||||
NTSTATUS NTAPI
|
||||
DriverEntry(
|
||||
IN PDRIVER_OBJECT DriverObject,
|
||||
|
@ -531,6 +556,8 @@ DriverEntry(
|
|||
DriverObject->MajorFunction[IRP_MJ_CLOSE] = i8042Close;
|
||||
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = i8042DeviceControl;
|
||||
DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = i8042InternalDeviceControl;
|
||||
DriverObject->MajorFunction[IRP_MJ_POWER] = i8042Power;
|
||||
DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = i8042SystemControl;
|
||||
DriverObject->MajorFunction[IRP_MJ_PNP] = i8042Pnp;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
static KDEFERRED_ROUTINE i8042MouDpcRoutine;
|
||||
static KDEFERRED_ROUTINE i8042DpcRoutineMouseTimeout;
|
||||
|
||||
/*
|
||||
* These functions are callbacks for filter driver custom interrupt
|
||||
|
@ -346,7 +347,6 @@ i8042MouDpcRoutine(
|
|||
* I'll just send the 'disable mouse port' command to the controller
|
||||
* and say the mouse doesn't exist.
|
||||
*/
|
||||
static KDEFERRED_ROUTINE i8042DpcRoutineMouseTimeout;
|
||||
static VOID NTAPI
|
||||
i8042DpcRoutineMouseTimeout(
|
||||
IN PKDPC Dpc,
|
||||
|
|
|
@ -479,7 +479,10 @@ StartProcedure(
|
|||
|
||||
/* Start the mouse */
|
||||
Irql = KeAcquireInterruptSpinLock(DeviceExtension->HighestDIRQLInterrupt);
|
||||
i8042IsrWritePort(DeviceExtension, MOU_CMD_RESET, CTRL_WRITE_MOUSE);
|
||||
/* HACK: the mouse has already been reset in i8042DetectMouse. This second
|
||||
reset prevents some touchpads/mice from working (Dell D531, D600).
|
||||
See CORE-6901
|
||||
i8042IsrWritePort(DeviceExtension, MOU_CMD_RESET, CTRL_WRITE_MOUSE); */
|
||||
KeReleaseInterruptSpinLock(DeviceExtension->HighestDIRQLInterrupt, Irql);
|
||||
}
|
||||
|
||||
|
@ -682,21 +685,8 @@ i8042Pnp(
|
|||
{
|
||||
case BusRelations:
|
||||
{
|
||||
PDEVICE_RELATIONS DeviceRelations;
|
||||
|
||||
TRACE_(I8042PRT, "IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations\n");
|
||||
DeviceRelations = ExAllocatePoolWithTag(PagedPool,
|
||||
sizeof(DEVICE_RELATIONS),
|
||||
I8042PRT_TAG);
|
||||
if (DeviceRelations)
|
||||
{
|
||||
DeviceRelations->Count = 0;
|
||||
Information = (ULONG_PTR)DeviceRelations;
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
break;
|
||||
return ForwardIrpAndForget(DeviceObject, Irp);
|
||||
}
|
||||
case RemovalRelations:
|
||||
{
|
||||
|
@ -706,7 +696,6 @@ i8042Pnp(
|
|||
default:
|
||||
ERR_(I8042PRT, "IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unknown type 0x%lx\n",
|
||||
Stack->Parameters.QueryDeviceRelations.Type);
|
||||
ASSERT(FALSE);
|
||||
return ForwardIrpAndForget(DeviceObject, Irp);
|
||||
}
|
||||
break;
|
||||
|
@ -714,17 +703,12 @@ i8042Pnp(
|
|||
case IRP_MN_FILTER_RESOURCE_REQUIREMENTS: /* (optional) 0x0d */
|
||||
{
|
||||
TRACE_(I8042PRT, "IRP_MJ_PNP / IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n");
|
||||
/* Nothing to do */
|
||||
Status = Irp->IoStatus.Status;
|
||||
break;
|
||||
return ForwardIrpAndForget(DeviceObject, Irp);
|
||||
}
|
||||
case IRP_MN_QUERY_PNP_DEVICE_STATE: /* 0x14 */
|
||||
{
|
||||
TRACE_(I8042PRT, "IRP_MJ_PNP / IRP_MN_QUERY_PNP_DEVICE_STATE\n");
|
||||
/* Nothing much to tell */
|
||||
Information = 0;
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
return ForwardIrpAndForget(DeviceObject, Irp);
|
||||
}
|
||||
default:
|
||||
{
|
||||
|
|
|
@ -89,8 +89,8 @@ HalVectorToIRQL[16] =
|
|||
|
||||
/* PRIVATE FUNCTIONS **********************************************************/
|
||||
|
||||
ULONG
|
||||
FORCEINLINE
|
||||
ULONG
|
||||
IOApicRead(UCHAR Register)
|
||||
{
|
||||
/* Select the register, then do the read */
|
||||
|
@ -98,8 +98,8 @@ IOApicRead(UCHAR Register)
|
|||
return *(volatile ULONG *)(IOAPIC_BASE + IOAPIC_IOWIN);
|
||||
}
|
||||
|
||||
VOID
|
||||
FORCEINLINE
|
||||
VOID
|
||||
IOApicWrite(UCHAR Register, ULONG Value)
|
||||
{
|
||||
/* Select the register, then do the write */
|
||||
|
@ -107,8 +107,8 @@ IOApicWrite(UCHAR Register, ULONG Value)
|
|||
*(volatile ULONG *)(IOAPIC_BASE + IOAPIC_IOWIN) = Value;
|
||||
}
|
||||
|
||||
VOID
|
||||
FORCEINLINE
|
||||
VOID
|
||||
ApicWriteIORedirectionEntry(
|
||||
UCHAR Index,
|
||||
IOAPIC_REDIRECTION_REGISTER ReDirReg)
|
||||
|
@ -117,8 +117,8 @@ ApicWriteIORedirectionEntry(
|
|||
IOApicWrite(IOAPIC_REDTBL + 2 * Index + 1, ReDirReg.Long1);
|
||||
}
|
||||
|
||||
IOAPIC_REDIRECTION_REGISTER
|
||||
FORCEINLINE
|
||||
IOAPIC_REDIRECTION_REGISTER
|
||||
ApicReadIORedirectionEntry(
|
||||
UCHAR Index)
|
||||
{
|
||||
|
@ -130,8 +130,8 @@ ApicReadIORedirectionEntry(
|
|||
return ReDirReg;
|
||||
}
|
||||
|
||||
VOID
|
||||
FORCEINLINE
|
||||
VOID
|
||||
ApicRequestInterrupt(IN UCHAR Vector, UCHAR TriggerMode)
|
||||
{
|
||||
APIC_COMMAND_REGISTER CommandRegister;
|
||||
|
@ -147,24 +147,24 @@ ApicRequestInterrupt(IN UCHAR Vector, UCHAR TriggerMode)
|
|||
ApicWrite(APIC_ICR0, CommandRegister.Long0);
|
||||
}
|
||||
|
||||
VOID
|
||||
FORCEINLINE
|
||||
VOID
|
||||
ApicSendEOI(void)
|
||||
{
|
||||
//ApicWrite(APIC_EOI, 0);
|
||||
HackEoi();
|
||||
}
|
||||
|
||||
KIRQL
|
||||
FORCEINLINE
|
||||
KIRQL
|
||||
ApicGetProcessorIrql(VOID)
|
||||
{
|
||||
/* Read the TPR and convert it to an IRQL */
|
||||
return TprToIrql(ApicRead(APIC_PPR));
|
||||
}
|
||||
|
||||
KIRQL
|
||||
FORCEINLINE
|
||||
KIRQL
|
||||
ApicGetCurrentIrql(VOID)
|
||||
{
|
||||
#ifdef _M_AMD64
|
||||
|
@ -184,8 +184,8 @@ ApicGetCurrentIrql(VOID)
|
|||
#endif
|
||||
}
|
||||
|
||||
VOID
|
||||
FORCEINLINE
|
||||
VOID
|
||||
ApicSetIrql(KIRQL Irql)
|
||||
{
|
||||
#ifdef _M_AMD64
|
||||
|
@ -200,8 +200,8 @@ ApicSetIrql(KIRQL Irql)
|
|||
#define ApicRaiseIrql ApicSetIrql
|
||||
|
||||
#ifdef APIC_LAZY_IRQL
|
||||
VOID
|
||||
FORCEINLINE
|
||||
VOID
|
||||
ApicLowerIrql(KIRQL Irql)
|
||||
{
|
||||
__writefsbyte(FIELD_OFFSET(KPCR, Irql), Irql);
|
||||
|
|
|
@ -258,15 +258,15 @@ typedef union _IOAPIC_REDIRECTION_REGISTER
|
|||
};
|
||||
} IOAPIC_REDIRECTION_REGISTER;
|
||||
|
||||
ULONG
|
||||
FORCEINLINE
|
||||
ULONG
|
||||
ApicRead(ULONG Offset)
|
||||
{
|
||||
return *(volatile ULONG *)(APIC_BASE + Offset);
|
||||
}
|
||||
|
||||
VOID
|
||||
FORCEINLINE
|
||||
VOID
|
||||
ApicWrite(ULONG Offset, ULONG Value)
|
||||
{
|
||||
*(volatile ULONG *)(APIC_BASE + Offset) = Value;
|
||||
|
|
|
@ -25,8 +25,8 @@ static UCHAR RtcMinimumClockRate = 6; /* Minimum rate 6: 16 Hz / 62.5 ms */
|
|||
static UCHAR RtcMaximumClockRate = 10; /* Maximum rate 10: 256 Hz / 3.9 ms */
|
||||
|
||||
|
||||
ULONG
|
||||
FORCEINLINE
|
||||
ULONG
|
||||
RtcClockRateToIncrement(UCHAR Rate)
|
||||
{
|
||||
ULONG Freqency = ((32768 << 1) >> Rate);
|
||||
|
|
|
@ -782,8 +782,8 @@ HalpEndSoftwareInterrupt(IN KIRQL OldIrql,
|
|||
|
||||
/* EDGE INTERRUPT DISMISSAL FUNCTIONS *****************************************/
|
||||
|
||||
BOOLEAN
|
||||
FORCEINLINE
|
||||
BOOLEAN
|
||||
_HalpDismissIrqGeneric(IN KIRQL Irql,
|
||||
IN ULONG Irq,
|
||||
OUT PKIRQL OldIrql)
|
||||
|
@ -925,8 +925,8 @@ HalpDismissIrq07(IN KIRQL Irql,
|
|||
|
||||
/* LEVEL INTERRUPT DISMISSAL FUNCTIONS ****************************************/
|
||||
|
||||
BOOLEAN
|
||||
FORCEINLINE
|
||||
BOOLEAN
|
||||
_HalpDismissIrqLevel(IN KIRQL Irql,
|
||||
IN ULONG Irq,
|
||||
OUT PKIRQL OldIrql)
|
||||
|
@ -1248,8 +1248,8 @@ HalEndSystemInterrupt(IN KIRQL OldIrql,
|
|||
|
||||
/* SOFTWARE INTERRUPT TRAPS ***************************************************/
|
||||
|
||||
VOID
|
||||
FORCEINLINE
|
||||
VOID
|
||||
DECLSPEC_NORETURN
|
||||
_HalpApcInterruptHandler(IN PKTRAP_FRAME TrapFrame)
|
||||
{
|
||||
|
@ -1304,8 +1304,8 @@ HalpApcInterruptHandler(IN PKTRAP_FRAME TrapFrame)
|
|||
_HalpApcInterruptHandler(TrapFrame);
|
||||
}
|
||||
|
||||
KIRQL
|
||||
FORCEINLINE
|
||||
KIRQL
|
||||
_HalpDispatchInterruptHandler(VOID)
|
||||
{
|
||||
KIRQL CurrentIrql;
|
||||
|
|
51
include/ddk/isvbop.h
Normal file
51
include/ddk/isvbop.h
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* isvbop.h
|
||||
*
|
||||
* Windows NT Device Driver Kit
|
||||
*
|
||||
* This file is part of the ReactOS DDK package.
|
||||
*
|
||||
* Contributors:
|
||||
* Hermes Belusca-Maito (hermes.belusca@sfr.fr)
|
||||
*
|
||||
* THIS SOFTWARE IS NOT COPYRIGHTED
|
||||
*
|
||||
* This source code is offered for use in the public domain. You may
|
||||
* use, modify or distribute it freely.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful but
|
||||
* WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
|
||||
* DISCLAIMED. This includes but is not limited to warranties of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* The corresponding ASM header of this file is isvbop.inc.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
/* BOP Identifiers */
|
||||
#define BOP_3RDPARTY 0x58 // 3rd-party VDD BOP
|
||||
#define BOP_UNSIMULATE 0xFE // Stop execution
|
||||
|
||||
#if defined(__GNUC__)
|
||||
|
||||
#define RegisterModule() __asm__(".byte 0xC4, 0xC4, %c0, 0" : : "i"(BOP_3RDPARTY))
|
||||
#define UnRegisterModule() __asm__(".byte 0xC4, 0xC4, %c0, 1" : : "i"(BOP_3RDPARTY))
|
||||
#define DispatchCall() __asm__(".byte 0xC4, 0xC4, %c0, 2" : : "i"(BOP_3RDPARTY))
|
||||
#define VDDUnSimulate16() __asm__(".byte 0xC4, 0xC4, %c0" : : "i"(BOP_UNSIMULATE))
|
||||
|
||||
#elif defined(_MSC_VER)
|
||||
|
||||
#define RegisterModule() _asm _emit 0xC4 _asm _emit 0xC4 _asm _emit BOP_3RDPARTY _asm _emit 0
|
||||
#define UnRegisterModule() _asm _emit 0xC4 _asm _emit 0xC4 _asm _emit BOP_3RDPARTY _asm _emit 1
|
||||
#define DispatchCall() _asm _emit 0xC4 _asm _emit 0xC4 _asm _emit BOP_3RDPARTY _asm _emit 2
|
||||
#define VDDUnSimulate16() _asm _emit 0xC4 _asm _emit 0xC4 _asm _emit BOP_UNSIMULATE
|
||||
|
||||
#else
|
||||
#error Unknown compiler for inline assembler
|
||||
#endif
|
||||
|
||||
/* EOF */
|
49
include/ddk/isvbop.inc
Normal file
49
include/ddk/isvbop.inc
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* isvbop.inc
|
||||
*
|
||||
* Windows NT Device Driver Kit
|
||||
*
|
||||
* This file is part of the ReactOS DDK package.
|
||||
*
|
||||
* Contributors:
|
||||
* Hermes Belusca-Maito (hermes.belusca@sfr.fr)
|
||||
*
|
||||
* THIS SOFTWARE IS NOT COPYRIGHTED
|
||||
*
|
||||
* This source code is offered for use in the public domain. You may
|
||||
* use, modify or distribute it freely.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful but
|
||||
* WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
|
||||
* DISCLAIMED. This includes but is not limited to warranties of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is the corresponding ASM header for isvbop.h.
|
||||
* Please refer to isvbop.h for information about these interfaces.
|
||||
*/
|
||||
|
||||
#include <asm.inc>
|
||||
|
||||
BOP_3RDPARTY = HEX(58)
|
||||
BOP_UNSIMULATE = HEX(FE)
|
||||
|
||||
MACRO(RegisterModule)
|
||||
.byte HEX(C4), HEX(C4), BOP_3RDPARTY, 0
|
||||
ENDM
|
||||
|
||||
MACRO(UnRegisterModule)
|
||||
.byte HEX(C4), HEX(C4), BOP_3RDPARTY, 1
|
||||
ENDM
|
||||
|
||||
MACRO(DispatchCall)
|
||||
.byte HEX(C4), HEX(C4), BOP_3RDPARTY, 2
|
||||
ENDM
|
||||
|
||||
MACRO(VDDUnSimulate16)
|
||||
.byte HEX(C4), HEX(C4), BOP_UNSIMULATE
|
||||
ENDM
|
||||
|
||||
/* EOF */
|
161
include/ddk/nt_vdd.h
Normal file
161
include/ddk/nt_vdd.h
Normal file
|
@ -0,0 +1,161 @@
|
|||
/*
|
||||
* nt_vdd.h
|
||||
*
|
||||
* Windows NT Device Driver Kit
|
||||
*
|
||||
* This file is part of the ReactOS DDK package.
|
||||
*
|
||||
* Contributors:
|
||||
* Hermes Belusca-Maito (hermes.belusca@sfr.fr)
|
||||
*
|
||||
* THIS SOFTWARE IS NOT COPYRIGHTED
|
||||
*
|
||||
* This source code is offered for use in the public domain. You may
|
||||
* use, modify or distribute it freely.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful but
|
||||
* WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
|
||||
* DISCLAIMED. This includes but is not limited to warranties of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define _NT_VDD
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* VDM Control
|
||||
*/
|
||||
|
||||
VOID
|
||||
WINAPI
|
||||
VDDSimulate16(VOID);
|
||||
|
||||
VOID
|
||||
WINAPI
|
||||
VDDTerminateVDM(VOID);
|
||||
|
||||
|
||||
/*
|
||||
* I/O Port services
|
||||
*/
|
||||
|
||||
typedef VOID (*PFNVDD_INB) (WORD iport, PBYTE data);
|
||||
typedef VOID (*PFNVDD_INW) (WORD iport, PWORD data);
|
||||
typedef VOID (*PFNVDD_INSB) (WORD iport, PBYTE data, WORD count);
|
||||
typedef VOID (*PFNVDD_INSW) (WORD iport, PWORD data, WORD count);
|
||||
typedef VOID (*PFNVDD_OUTB) (WORD iport, BYTE data);
|
||||
typedef VOID (*PFNVDD_OUTW) (WORD iport, WORD data);
|
||||
typedef VOID (*PFNVDD_OUTSB) (WORD iport, PBYTE data, WORD count);
|
||||
typedef VOID (*PFNVDD_OUTSW) (WORD iport, PWORD data, WORD count);
|
||||
|
||||
typedef struct _VDD_IO_HANDLERS
|
||||
{
|
||||
PFNVDD_INB inb_handler;
|
||||
PFNVDD_INW inw_handler;
|
||||
PFNVDD_INSB insb_handler;
|
||||
PFNVDD_INSW insw_handler;
|
||||
PFNVDD_OUTB outb_handler;
|
||||
PFNVDD_OUTW outw_handler;
|
||||
PFNVDD_OUTSB outsb_handler;
|
||||
PFNVDD_OUTSW outsw_handler;
|
||||
} VDD_IO_HANDLERS, *PVDD_IO_HANDLERS;
|
||||
|
||||
typedef struct _VDD_IO_PORTRANGE
|
||||
{
|
||||
WORD First;
|
||||
WORD Last;
|
||||
} VDD_IO_PORTRANGE, *PVDD_IO_PORTRANGE;
|
||||
|
||||
BOOL
|
||||
WINAPI
|
||||
VDDInstallIOHook
|
||||
(
|
||||
HANDLE hVdd,
|
||||
WORD cPortRange,
|
||||
PVDD_IO_PORTRANGE pPortRange,
|
||||
PVDD_IO_HANDLERS IOhandler
|
||||
);
|
||||
|
||||
VOID
|
||||
WINAPI
|
||||
VDDDeInstallIOHook
|
||||
(
|
||||
HANDLE hVdd,
|
||||
WORD cPortRange,
|
||||
PVDD_IO_PORTRANGE pPortRange
|
||||
);
|
||||
|
||||
|
||||
/*
|
||||
* Memory services
|
||||
*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
VDM_V86,
|
||||
VDM_PM
|
||||
} VDM_MODE;
|
||||
|
||||
#ifndef MSW_PE
|
||||
#define MSW_PE 0x0001
|
||||
#endif
|
||||
|
||||
#define getMODE() ((getMSW() & MSW_PE) ? VDM_PM : VDM_V86)
|
||||
|
||||
PBYTE
|
||||
WINAPI
|
||||
Sim32pGetVDMPointer
|
||||
(
|
||||
IN ULONG Address,
|
||||
IN BOOLEAN ProtectedMode
|
||||
);
|
||||
|
||||
PBYTE
|
||||
WINAPI
|
||||
MGetVdmPointer
|
||||
(
|
||||
IN ULONG Address,
|
||||
IN ULONG Size,
|
||||
IN BOOLEAN ProtectedMode
|
||||
);
|
||||
|
||||
PVOID
|
||||
WINAPI
|
||||
VdmMapFlat
|
||||
(
|
||||
IN USHORT Segment,
|
||||
IN ULONG Offset,
|
||||
IN VDM_MODE Mode
|
||||
);
|
||||
|
||||
BOOL
|
||||
WINAPI
|
||||
VdmFlushCache
|
||||
(
|
||||
IN USHORT Segment,
|
||||
IN ULONG Offset,
|
||||
IN ULONG Size,
|
||||
IN VDM_MODE Mode
|
||||
);
|
||||
|
||||
BOOL
|
||||
WINAPI
|
||||
VdmUnmapFlat
|
||||
(
|
||||
IN USHORT Segment,
|
||||
IN ULONG Offset,
|
||||
IN PVOID Buffer,
|
||||
IN VDM_MODE Mode
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/* EOF */
|
254
include/ddk/vddsvc.h
Normal file
254
include/ddk/vddsvc.h
Normal file
|
@ -0,0 +1,254 @@
|
|||
/*
|
||||
* vddsvc.h
|
||||
*
|
||||
* Windows NT Device Driver Kit
|
||||
*
|
||||
* This file is part of the ReactOS DDK package.
|
||||
*
|
||||
* Contributors:
|
||||
* Hermes Belusca-Maito (hermes.belusca@sfr.fr)
|
||||
*
|
||||
* THIS SOFTWARE IS NOT COPYRIGHTED
|
||||
*
|
||||
* This source code is offered for use in the public domain. You may
|
||||
* use, modify or distribute it freely.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful but
|
||||
* WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
|
||||
* DISCLAIMED. This includes but is not limited to warranties of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef _NT_VDD
|
||||
#include <nt_vdd.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Interrupts services
|
||||
*/
|
||||
#define ICA_MASTER 0
|
||||
#define ICA_SLAVE 1
|
||||
|
||||
VOID
|
||||
WINAPI
|
||||
call_ica_hw_interrupt
|
||||
(
|
||||
INT ms,
|
||||
BYTE line,
|
||||
INT count
|
||||
);
|
||||
|
||||
#define VDDSimulateInterrupt(ms, line, count) \
|
||||
call_ica_hw_interrupt((ms), (line), (count)) // Windows specifies a count of 1 ...
|
||||
|
||||
|
||||
/*
|
||||
* Registers manipulation
|
||||
*/
|
||||
PVOID WINAPI getIntelRegistersPointer(VOID);
|
||||
|
||||
#ifdef __i386__
|
||||
|
||||
ULONG WINAPI getEAX(VOID);
|
||||
VOID WINAPI setEAX(ULONG);
|
||||
USHORT WINAPI getAX(VOID);
|
||||
VOID WINAPI setAX(USHORT);
|
||||
UCHAR WINAPI getAH(VOID);
|
||||
VOID WINAPI setAH(UCHAR);
|
||||
UCHAR WINAPI getAL(VOID);
|
||||
VOID WINAPI setAL(UCHAR);
|
||||
|
||||
ULONG WINAPI getEBX(VOID);
|
||||
VOID WINAPI setEBX(ULONG);
|
||||
USHORT WINAPI getBX(VOID);
|
||||
VOID WINAPI setBX(USHORT);
|
||||
UCHAR WINAPI getBH(VOID);
|
||||
VOID WINAPI setBH(UCHAR);
|
||||
UCHAR WINAPI getBL(VOID);
|
||||
VOID WINAPI setBL(UCHAR);
|
||||
|
||||
ULONG WINAPI getECX(VOID);
|
||||
VOID WINAPI setECX(ULONG);
|
||||
USHORT WINAPI getCX(VOID);
|
||||
VOID WINAPI setCX(USHORT);
|
||||
UCHAR WINAPI getCH(VOID);
|
||||
VOID WINAPI setCH(UCHAR);
|
||||
UCHAR WINAPI getCL(VOID);
|
||||
VOID WINAPI setCL(UCHAR);
|
||||
|
||||
ULONG WINAPI getEDX(VOID);
|
||||
VOID WINAPI setEDX(ULONG);
|
||||
USHORT WINAPI getDX(VOID);
|
||||
VOID WINAPI setDX(USHORT);
|
||||
UCHAR WINAPI getDH(VOID);
|
||||
VOID WINAPI setDH(UCHAR);
|
||||
UCHAR WINAPI getDL(VOID);
|
||||
VOID WINAPI setDL(UCHAR);
|
||||
|
||||
|
||||
|
||||
ULONG WINAPI getESP(VOID);
|
||||
VOID WINAPI setESP(ULONG);
|
||||
USHORT WINAPI getSP(VOID);
|
||||
VOID WINAPI setSP(USHORT);
|
||||
|
||||
ULONG WINAPI getEBP(VOID);
|
||||
VOID WINAPI setEBP(ULONG);
|
||||
USHORT WINAPI getBP(VOID);
|
||||
VOID WINAPI setBP(USHORT);
|
||||
|
||||
ULONG WINAPI getESI(VOID);
|
||||
VOID WINAPI setESI(ULONG);
|
||||
USHORT WINAPI getSI(VOID);
|
||||
VOID WINAPI setSI(USHORT);
|
||||
|
||||
ULONG WINAPI getEDI(VOID);
|
||||
VOID WINAPI setEDI(ULONG);
|
||||
USHORT WINAPI getDI(VOID);
|
||||
VOID WINAPI setDI(USHORT);
|
||||
|
||||
ULONG WINAPI getEIP(VOID);
|
||||
VOID WINAPI setEIP(ULONG);
|
||||
USHORT WINAPI getIP(VOID);
|
||||
VOID WINAPI setIP(USHORT);
|
||||
|
||||
USHORT WINAPI getCS(VOID);
|
||||
VOID WINAPI setCS(USHORT);
|
||||
USHORT WINAPI getSS(VOID);
|
||||
VOID WINAPI setSS(USHORT);
|
||||
USHORT WINAPI getDS(VOID);
|
||||
VOID WINAPI setDS(USHORT);
|
||||
USHORT WINAPI getES(VOID);
|
||||
VOID WINAPI setES(USHORT);
|
||||
USHORT WINAPI getFS(VOID);
|
||||
VOID WINAPI setFS(USHORT);
|
||||
USHORT WINAPI getGS(VOID);
|
||||
VOID WINAPI setGS(USHORT);
|
||||
|
||||
ULONG WINAPI getCF(VOID);
|
||||
VOID WINAPI setCF(ULONG);
|
||||
ULONG WINAPI getPF(VOID);
|
||||
VOID WINAPI setPF(ULONG);
|
||||
ULONG WINAPI getAF(VOID);
|
||||
VOID WINAPI setAF(ULONG);
|
||||
ULONG WINAPI getZF(VOID);
|
||||
VOID WINAPI setZF(ULONG);
|
||||
ULONG WINAPI getSF(VOID);
|
||||
VOID WINAPI setSF(ULONG);
|
||||
ULONG WINAPI getIF(VOID);
|
||||
VOID WINAPI setIF(ULONG);
|
||||
ULONG WINAPI getDF(VOID);
|
||||
VOID WINAPI setDF(ULONG);
|
||||
ULONG WINAPI getOF(VOID);
|
||||
VOID WINAPI setOF(ULONG);
|
||||
|
||||
ULONG WINAPI getEFLAGS(VOID);
|
||||
VOID WINAPI setEFLAGS(ULONG);
|
||||
|
||||
USHORT WINAPI getMSW(VOID);
|
||||
VOID WINAPI setMSW(USHORT);
|
||||
|
||||
#else
|
||||
|
||||
ULONG WINAPI c_getEAX(VOID);
|
||||
VOID WINAPI c_setEAX(ULONG);
|
||||
USHORT WINAPI c_getAX(VOID);
|
||||
VOID WINAPI c_setAX(USHORT);
|
||||
UCHAR WINAPI c_getAH(VOID);
|
||||
VOID WINAPI c_setAH(UCHAR);
|
||||
UCHAR WINAPI c_getAL(VOID);
|
||||
VOID WINAPI c_setAL(UCHAR);
|
||||
|
||||
ULONG WINAPI c_getEBX(VOID);
|
||||
VOID WINAPI c_setEBX(ULONG);
|
||||
USHORT WINAPI c_getBX(VOID);
|
||||
VOID WINAPI c_setBX(USHORT);
|
||||
UCHAR WINAPI c_getBH(VOID);
|
||||
VOID WINAPI c_setBH(UCHAR);
|
||||
UCHAR WINAPI c_getBL(VOID);
|
||||
VOID WINAPI c_setBL(UCHAR);
|
||||
|
||||
ULONG WINAPI c_getECX(VOID);
|
||||
VOID WINAPI c_setECX(ULONG);
|
||||
USHORT WINAPI c_getCX(VOID);
|
||||
VOID WINAPI c_setCX(USHORT);
|
||||
UCHAR WINAPI c_getCH(VOID);
|
||||
VOID WINAPI c_setCH(UCHAR);
|
||||
UCHAR WINAPI c_getCL(VOID);
|
||||
VOID WINAPI c_setCL(UCHAR);
|
||||
|
||||
ULONG WINAPI c_getEDX(VOID);
|
||||
VOID WINAPI c_setEDX(ULONG);
|
||||
USHORT WINAPI c_getDX(VOID);
|
||||
VOID WINAPI c_setDX(USHORT);
|
||||
UCHAR WINAPI c_getDH(VOID);
|
||||
VOID WINAPI c_setDH(UCHAR);
|
||||
UCHAR WINAPI c_getDL(VOID);
|
||||
VOID WINAPI c_setDL(UCHAR);
|
||||
|
||||
|
||||
|
||||
ULONG WINAPI c_getESP(VOID);
|
||||
VOID WINAPI c_setESP(ULONG);
|
||||
USHORT WINAPI c_getSP(VOID);
|
||||
VOID WINAPI c_setSP(USHORT);
|
||||
|
||||
ULONG WINAPI c_getEBP(VOID);
|
||||
VOID WINAPI c_setEBP(ULONG);
|
||||
USHORT WINAPI c_getBP(VOID);
|
||||
VOID WINAPI c_setBP(USHORT);
|
||||
|
||||
ULONG WINAPI c_getESI(VOID);
|
||||
VOID WINAPI c_setESI(ULONG);
|
||||
USHORT WINAPI c_getSI(VOID);
|
||||
VOID WINAPI c_setSI(USHORT);
|
||||
|
||||
ULONG WINAPI c_getEDI(VOID);
|
||||
VOID WINAPI c_setEDI(ULONG);
|
||||
USHORT WINAPI c_getDI(VOID);
|
||||
VOID WINAPI c_setDI(USHORT);
|
||||
|
||||
ULONG WINAPI c_getEIP(VOID);
|
||||
VOID WINAPI c_setEIP(ULONG);
|
||||
USHORT WINAPI c_getIP(VOID);
|
||||
VOID WINAPI c_setIP(USHORT);
|
||||
|
||||
USHORT WINAPI c_getCS(VOID);
|
||||
VOID WINAPI c_setCS(USHORT);
|
||||
USHORT WINAPI c_getSS(VOID);
|
||||
VOID WINAPI c_setSS(USHORT);
|
||||
USHORT WINAPI c_getDS(VOID);
|
||||
VOID WINAPI c_setDS(USHORT);
|
||||
USHORT WINAPI c_getES(VOID);
|
||||
VOID WINAPI c_setES(USHORT);
|
||||
USHORT WINAPI c_getFS(VOID);
|
||||
VOID WINAPI c_setFS(USHORT);
|
||||
USHORT WINAPI c_getGS(VOID);
|
||||
VOID WINAPI c_setGS(USHORT);
|
||||
|
||||
ULONG WINAPI c_getCF(VOID);
|
||||
VOID WINAPI c_setCF(ULONG);
|
||||
ULONG WINAPI c_getPF(VOID);
|
||||
VOID WINAPI c_setPF(ULONG);
|
||||
ULONG WINAPI c_getAF(VOID);
|
||||
VOID WINAPI c_setAF(ULONG);
|
||||
ULONG WINAPI c_getZF(VOID);
|
||||
VOID WINAPI c_setZF(ULONG);
|
||||
ULONG WINAPI c_getSF(VOID);
|
||||
VOID WINAPI c_setSF(ULONG);
|
||||
ULONG WINAPI c_getIF(VOID);
|
||||
VOID WINAPI c_setIF(ULONG);
|
||||
ULONG WINAPI c_getDF(VOID);
|
||||
VOID WINAPI c_setDF(ULONG);
|
||||
ULONG WINAPI c_getOF(VOID);
|
||||
VOID WINAPI c_setOF(ULONG);
|
||||
|
||||
USHORT WINAPI c_getMSW(VOID);
|
||||
VOID WINAPI c_setMSW(USHORT);
|
||||
|
||||
#endif
|
||||
|
||||
/* EOF */
|
|
@ -3654,7 +3654,7 @@ RtlFindActivationContextSectionString(
|
|||
_In_ ULONG dwFlags,
|
||||
_In_ const GUID *ExtensionGuid,
|
||||
_In_ ULONG SectionType,
|
||||
_In_ PUNICODE_STRING SectionName,
|
||||
_In_ const UNICODE_STRING *SectionName,
|
||||
_Inout_ PVOID ReturnedData
|
||||
);
|
||||
|
||||
|
@ -4419,6 +4419,17 @@ RtlCloneMemoryStream(
|
|||
|
||||
#endif // NTOS_MODE_USER
|
||||
|
||||
NTSYSAPI
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
RtlFindActivationContextSectionGuid(
|
||||
ULONG flags,
|
||||
const GUID *extguid,
|
||||
ULONG section_kind,
|
||||
const GUID *guid,
|
||||
void *ptr
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -5,30 +5,30 @@
|
|||
|
||||
#if 0
|
||||
|
||||
VOID
|
||||
FORCEINLINE
|
||||
VOID
|
||||
KdRosDumpAllThreads(VOID)
|
||||
{
|
||||
KdSystemDebugControl(' soR', (PVOID)DumpAllThreads, 0, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
VOID
|
||||
FORCEINLINE
|
||||
VOID
|
||||
KdRosDumpUserThreads(VOID)
|
||||
{
|
||||
KdSystemDebugControl(' soR', (PVOID)DumpUserThreads, 0, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
VOID
|
||||
FORCEINLINE
|
||||
VOID
|
||||
KdRosDumpArmPfnDatabase(VOID)
|
||||
{
|
||||
KdSystemDebugControl(' soR', (PVOID)KdSpare3, 0, 0, 0, 0, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
VOID
|
||||
FORCEINLINE
|
||||
VOID
|
||||
KdRosSetDebugCallback(
|
||||
ULONG Id,
|
||||
PVOID Callback)
|
||||
|
@ -36,8 +36,8 @@ KdRosSetDebugCallback(
|
|||
KdSystemDebugControl('CsoR', Callback, Id, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
VOID
|
||||
FORCEINLINE
|
||||
VOID
|
||||
KdRosDumpStackFrames(
|
||||
ULONG Count,
|
||||
PULONG_PTR Backtrace)
|
||||
|
@ -46,16 +46,16 @@ KdRosDumpStackFrames(
|
|||
}
|
||||
|
||||
#if KDBG
|
||||
VOID
|
||||
FORCEINLINE
|
||||
VOID
|
||||
KdRosRegisterCliCallback(
|
||||
PVOID Callback)
|
||||
{
|
||||
KdSystemDebugControl('RbdK', Callback, FALSE, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
VOID
|
||||
FORCEINLINE
|
||||
VOID
|
||||
KdRosDeregisterCliCallback(
|
||||
PVOID Callback)
|
||||
{
|
||||
|
|
562
include/reactos/libs/fast486/fast486.h
Normal file
562
include/reactos/libs/fast486/fast486.h
Normal file
|
@ -0,0 +1,562 @@
|
|||
/*
|
||||
* Fast486 386/486 CPU Emulation Library
|
||||
* fast486.h
|
||||
*
|
||||
* Copyright (C) 2013 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef _FAST486_H_
|
||||
#define _FAST486_H_
|
||||
|
||||
#pragma once
|
||||
|
||||
/* DEFINES ********************************************************************/
|
||||
|
||||
#ifndef FASTCALL
|
||||
#define FASTCALL __fastcall
|
||||
#endif
|
||||
|
||||
#define FAST486_NUM_GEN_REGS 8
|
||||
#define FAST486_NUM_SEG_REGS 6
|
||||
#define FAST486_NUM_CTRL_REGS 3
|
||||
#define FAST486_NUM_DBG_REGS 6
|
||||
#define FAST486_NUM_FPU_REGS 8
|
||||
|
||||
#define FAST486_CR0_PE (1 << 0)
|
||||
#define FAST486_CR0_MP (1 << 1)
|
||||
#define FAST486_CR0_EM (1 << 2)
|
||||
#define FAST486_CR0_TS (1 << 3)
|
||||
#define FAST486_CR0_ET (1 << 4)
|
||||
#define FAST486_CR0_NE (1 << 5)
|
||||
#define FAST486_CR0_WP (1 << 16)
|
||||
#define FAST486_CR0_AM (1 << 18)
|
||||
#define FAST486_CR0_NW (1 << 29)
|
||||
#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
|
||||
#define FAST486_IDT_INT_GATE_32 0xE
|
||||
#define FAST486_IDT_TRAP_GATE_32 0xF
|
||||
|
||||
#define FAST486_LDT_SIGNATURE 0x02
|
||||
#define FAST486_TSS_SIGNATURE 0x09
|
||||
|
||||
#define FAST486_PREFIX_SEG (1 << 0)
|
||||
#define FAST486_PREFIX_OPSIZE (1 << 1)
|
||||
#define FAST486_PREFIX_ADSIZE (1 << 2)
|
||||
#define FAST486_PREFIX_LOCK (1 << 3)
|
||||
#define FAST486_PREFIX_REPNZ (1 << 4)
|
||||
#define FAST486_PREFIX_REP (1 << 5)
|
||||
|
||||
struct _FAST486_STATE;
|
||||
typedef struct _FAST486_STATE FAST486_STATE, *PFAST486_STATE;
|
||||
|
||||
typedef enum _FAST486_GEN_REGS
|
||||
{
|
||||
FAST486_REG_EAX,
|
||||
FAST486_REG_ECX,
|
||||
FAST486_REG_EDX,
|
||||
FAST486_REG_EBX,
|
||||
FAST486_REG_ESP,
|
||||
FAST486_REG_EBP,
|
||||
FAST486_REG_ESI,
|
||||
FAST486_REG_EDI
|
||||
} FAST486_GEN_REGS, *PFAST486_GEN_REGS;
|
||||
|
||||
typedef enum _FAST486_SEG_REGS
|
||||
{
|
||||
FAST486_REG_ES,
|
||||
FAST486_REG_CS,
|
||||
FAST486_REG_SS,
|
||||
FAST486_REG_DS,
|
||||
FAST486_REG_FS,
|
||||
FAST486_REG_GS
|
||||
} FAST486_SEG_REGS, *PFAST486_SEG_REGS;
|
||||
|
||||
typedef enum _FAST486_CTRL_REGS
|
||||
{
|
||||
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 = 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
|
||||
{
|
||||
FAST486_EXCEPTION_DE = 0x00,
|
||||
FAST486_EXCEPTION_DB = 0x01,
|
||||
FAST486_EXCEPTION_BP = 0x03,
|
||||
FAST486_EXCEPTION_OF = 0x04,
|
||||
FAST486_EXCEPTION_BR = 0x05,
|
||||
FAST486_EXCEPTION_UD = 0x06,
|
||||
FAST486_EXCEPTION_NM = 0x07,
|
||||
FAST486_EXCEPTION_DF = 0x08,
|
||||
FAST486_EXCEPTION_TS = 0x0A,
|
||||
FAST486_EXCEPTION_NP = 0x0B,
|
||||
FAST486_EXCEPTION_SS = 0x0C,
|
||||
FAST486_EXCEPTION_GP = 0x0D,
|
||||
FAST486_EXCEPTION_PF = 0x0E,
|
||||
FAST486_EXCEPTION_MF = 0x10,
|
||||
FAST486_EXCEPTION_AC = 0x11,
|
||||
FAST486_EXCEPTION_MC = 0x12
|
||||
} FAST486_EXCEPTIONS, *PFAST486_EXCEPTIONS;
|
||||
|
||||
typedef enum _FAST486_INT_STATUS
|
||||
{
|
||||
FAST486_INT_NONE = 0,
|
||||
FAST486_INT_EXECUTE = 1,
|
||||
FAST486_INT_SIGNAL = 2
|
||||
} FAST486_INT_STATUS, *PFAST486_INT_STATUS;
|
||||
|
||||
typedef
|
||||
VOID
|
||||
(NTAPI *FAST486_MEM_READ_PROC)
|
||||
(
|
||||
PFAST486_STATE State,
|
||||
ULONG Address,
|
||||
PVOID Buffer,
|
||||
ULONG Size
|
||||
);
|
||||
|
||||
typedef
|
||||
VOID
|
||||
(NTAPI *FAST486_MEM_WRITE_PROC)
|
||||
(
|
||||
PFAST486_STATE State,
|
||||
ULONG Address,
|
||||
PVOID Buffer,
|
||||
ULONG Size
|
||||
);
|
||||
|
||||
typedef
|
||||
VOID
|
||||
(NTAPI *FAST486_IO_READ_PROC)
|
||||
(
|
||||
PFAST486_STATE State,
|
||||
ULONG Port,
|
||||
PVOID Buffer,
|
||||
ULONG DataCount,
|
||||
UCHAR DataSize
|
||||
);
|
||||
|
||||
typedef
|
||||
VOID
|
||||
(NTAPI *FAST486_IO_WRITE_PROC)
|
||||
(
|
||||
PFAST486_STATE State,
|
||||
ULONG Port,
|
||||
PVOID Buffer,
|
||||
ULONG DataCount,
|
||||
UCHAR DataSize
|
||||
);
|
||||
|
||||
typedef
|
||||
VOID
|
||||
(NTAPI *FAST486_IDLE_PROC)
|
||||
(
|
||||
PFAST486_STATE State
|
||||
);
|
||||
|
||||
typedef
|
||||
VOID
|
||||
(NTAPI *FAST486_BOP_PROC)
|
||||
(
|
||||
PFAST486_STATE State,
|
||||
UCHAR BopCode
|
||||
);
|
||||
|
||||
typedef
|
||||
UCHAR
|
||||
(NTAPI *FAST486_INT_ACK_PROC)
|
||||
(
|
||||
PFAST486_STATE State
|
||||
);
|
||||
|
||||
typedef union _FAST486_REG
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
UCHAR LowByte;
|
||||
UCHAR HighByte;
|
||||
};
|
||||
USHORT LowWord;
|
||||
};
|
||||
ULONG Long;
|
||||
} FAST486_REG, *PFAST486_REG;
|
||||
|
||||
typedef struct _FAST486_SEG_REG
|
||||
{
|
||||
USHORT Selector;
|
||||
|
||||
/* Descriptor cache */
|
||||
ULONG Accessed : 1;
|
||||
ULONG ReadWrite : 1;
|
||||
ULONG DirConf : 1;
|
||||
ULONG Executable : 1;
|
||||
ULONG SystemType : 1;
|
||||
ULONG Dpl : 2;
|
||||
ULONG Present : 1;
|
||||
ULONG Size : 1;
|
||||
ULONG Limit;
|
||||
ULONG Base;
|
||||
} FAST486_SEG_REG, *PFAST486_SEG_REG;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
USHORT Selector;
|
||||
ULONG Base;
|
||||
ULONG Limit;
|
||||
} FAST486_LDT_REG;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
USHORT Selector;
|
||||
ULONG Base;
|
||||
ULONG Limit;
|
||||
BOOLEAN Busy;
|
||||
} FAST486_TASK_REG, *PFAST486_TASK_REG;
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ULONG Limit : 16;
|
||||
ULONG Base : 16;
|
||||
ULONG BaseMid : 8;
|
||||
ULONG Accessed : 1;
|
||||
ULONG ReadWrite : 1;
|
||||
ULONG DirConf : 1;
|
||||
ULONG Executable : 1;
|
||||
ULONG SystemType : 1;
|
||||
ULONG Dpl : 2;
|
||||
ULONG Present : 1;
|
||||
ULONG LimitHigh : 4;
|
||||
ULONG Avl : 1;
|
||||
ULONG Reserved : 1;
|
||||
ULONG Size : 1;
|
||||
ULONG Granularity : 1;
|
||||
ULONG BaseHigh : 8;
|
||||
} FAST486_GDT_ENTRY, *PFAST486_GDT_ENTRY;
|
||||
|
||||
/* Verify the structure size */
|
||||
C_ASSERT(sizeof(FAST486_GDT_ENTRY) == sizeof(ULONGLONG));
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ULONG Limit : 16;
|
||||
ULONG Base : 16;
|
||||
ULONG BaseMid : 8;
|
||||
ULONG Signature : 5;
|
||||
ULONG Dpl : 2;
|
||||
ULONG Present : 1;
|
||||
ULONG LimitHigh : 4;
|
||||
ULONG Avl : 1;
|
||||
ULONG Reserved : 2;
|
||||
ULONG Granularity : 1;
|
||||
ULONG BaseHigh : 8;
|
||||
} FAST486_SYSTEM_DESCRIPTOR, *PFAST486_SYSTEM_DESCRIPTOR;
|
||||
|
||||
/* Verify the structure size */
|
||||
C_ASSERT(sizeof(FAST486_SYSTEM_DESCRIPTOR) == sizeof(ULONGLONG));
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ULONG Offset : 16;
|
||||
ULONG Selector : 16;
|
||||
ULONG ParamCount : 5;
|
||||
ULONG Reserved : 3;
|
||||
ULONG Type : 4;
|
||||
ULONG SystemType : 1;
|
||||
ULONG Dpl : 2;
|
||||
ULONG Present : 1;
|
||||
ULONG OffsetHigh : 16;
|
||||
} FAST486_CALL_GATE, *PFAST486_CALL_GATE;
|
||||
|
||||
/* Verify the structure size */
|
||||
C_ASSERT(sizeof(FAST486_CALL_GATE) == sizeof(ULONGLONG));
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ULONG Offset : 16;
|
||||
ULONG Selector : 16;
|
||||
ULONG Zero : 8;
|
||||
ULONG Type : 4;
|
||||
ULONG Storage : 1;
|
||||
ULONG Dpl : 2;
|
||||
ULONG Present : 1;
|
||||
ULONG OffsetHigh : 16;
|
||||
} FAST486_IDT_ENTRY, *PFAST486_IDT_ENTRY;
|
||||
|
||||
/* Verify the structure size */
|
||||
C_ASSERT(sizeof(FAST486_IDT_ENTRY) == sizeof(ULONGLONG));
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
typedef struct _FAST486_TABLE_REG
|
||||
{
|
||||
USHORT Size;
|
||||
ULONG Address;
|
||||
} FAST486_TABLE_REG, *PFAST486_TABLE_REG;
|
||||
|
||||
typedef union _FAST486_FLAGS_REG
|
||||
{
|
||||
USHORT LowWord;
|
||||
ULONG Long;
|
||||
|
||||
struct
|
||||
{
|
||||
ULONG Cf : 1;
|
||||
ULONG AlwaysSet : 1;
|
||||
ULONG Pf : 1;
|
||||
ULONG Reserved0 : 1;
|
||||
ULONG Af : 1;
|
||||
ULONG Reserved1 : 1;
|
||||
ULONG Zf : 1;
|
||||
ULONG Sf : 1;
|
||||
ULONG Tf : 1;
|
||||
ULONG If : 1;
|
||||
ULONG Df : 1;
|
||||
ULONG Of : 1;
|
||||
ULONG Iopl : 2;
|
||||
ULONG Nt : 1;
|
||||
ULONG Reserved2 : 1;
|
||||
ULONG Rf : 1;
|
||||
ULONG Vm : 1;
|
||||
ULONG Ac : 1;
|
||||
|
||||
// ULONG Reserved : 13;
|
||||
};
|
||||
} FAST486_FLAGS_REG, *PFAST486_FLAGS_REG;
|
||||
|
||||
typedef struct _FAST486_TSS
|
||||
{
|
||||
ULONG Link;
|
||||
ULONG Esp0;
|
||||
ULONG Ss0;
|
||||
ULONG Esp1;
|
||||
ULONG Ss1;
|
||||
ULONG Esp2;
|
||||
ULONG Ss2;
|
||||
ULONG Cr3;
|
||||
ULONG Eip;
|
||||
ULONG Eflags;
|
||||
ULONG Eax;
|
||||
ULONG Ecx;
|
||||
ULONG Edx;
|
||||
ULONG Ebx;
|
||||
ULONG Esp;
|
||||
ULONG Ebp;
|
||||
ULONG Esi;
|
||||
ULONG Edi;
|
||||
ULONG Es;
|
||||
ULONG Cs;
|
||||
ULONG Ss;
|
||||
ULONG Ds;
|
||||
ULONG Fs;
|
||||
ULONG Gs;
|
||||
ULONG Ldtr;
|
||||
ULONG IopbOffset;
|
||||
} FAST486_TSS, *PFAST486_TSS;
|
||||
|
||||
typedef struct _FAST486_FPU_DATA_REG
|
||||
{
|
||||
ULONGLONG Mantissa;
|
||||
USHORT Exponent;
|
||||
} FAST486_FPU_DATA_REG, *PFAST486_FPU_DATA_REG;
|
||||
|
||||
typedef union _FAST486_FPU_STATUS_REG
|
||||
{
|
||||
USHORT Value;
|
||||
|
||||
struct
|
||||
{
|
||||
ULONG Ie : 1;
|
||||
ULONG De : 1;
|
||||
ULONG Ze : 1;
|
||||
ULONG Oe : 1;
|
||||
ULONG Ue : 1;
|
||||
ULONG Pe : 1;
|
||||
ULONG Sf : 1;
|
||||
ULONG Es : 1;
|
||||
ULONG Code0 : 1;
|
||||
ULONG Code1 : 1;
|
||||
ULONG Code2 : 1;
|
||||
ULONG Top : 3;
|
||||
ULONG Code3 : 1;
|
||||
ULONG Busy : 1;
|
||||
};
|
||||
} FAST486_FPU_STATUS_REG, *PFAST486_FPU_STATUS_REG;
|
||||
|
||||
typedef union _FAST486_FPU_CONTROL_REG
|
||||
{
|
||||
USHORT Value;
|
||||
|
||||
struct
|
||||
{
|
||||
ULONG Im : 1;
|
||||
ULONG Dm : 1;
|
||||
ULONG Zm : 1;
|
||||
ULONG Om : 1;
|
||||
ULONG Um : 1;
|
||||
ULONG Pm : 1;
|
||||
ULONG Reserved : 2;
|
||||
ULONG Pc : 2;
|
||||
ULONG Rc : 2;
|
||||
ULONG Inf : 1;
|
||||
// ULONG Reserved1 : 3;
|
||||
};
|
||||
} FAST486_FPU_CONTROL_REG, *PFAST486_FPU_CONTROL_REG;
|
||||
|
||||
struct _FAST486_STATE
|
||||
{
|
||||
FAST486_MEM_READ_PROC MemReadCallback;
|
||||
FAST486_MEM_WRITE_PROC MemWriteCallback;
|
||||
FAST486_IO_READ_PROC IoReadCallback;
|
||||
FAST486_IO_WRITE_PROC IoWriteCallback;
|
||||
FAST486_IDLE_PROC IdleCallback;
|
||||
FAST486_BOP_PROC BopCallback;
|
||||
FAST486_INT_ACK_PROC IntAckCallback;
|
||||
FAST486_REG GeneralRegs[FAST486_NUM_GEN_REGS];
|
||||
FAST486_SEG_REG SegmentRegs[FAST486_NUM_SEG_REGS];
|
||||
FAST486_REG InstPtr, SavedInstPtr;
|
||||
FAST486_FLAGS_REG Flags;
|
||||
FAST486_TABLE_REG Gdtr, Idtr;
|
||||
FAST486_LDT_REG Ldtr;
|
||||
FAST486_TASK_REG TaskReg;
|
||||
UCHAR Cpl;
|
||||
ULONG ControlRegisters[FAST486_NUM_CTRL_REGS];
|
||||
ULONG DebugRegisters[FAST486_NUM_DBG_REGS];
|
||||
ULONG ExceptionCount;
|
||||
ULONG PrefixFlags;
|
||||
FAST486_SEG_REGS SegmentOverride;
|
||||
FAST486_INT_STATUS IntStatus;
|
||||
UCHAR PendingIntNum;
|
||||
PULONG Tlb;
|
||||
FAST486_FPU_DATA_REG FpuRegisters[FAST486_NUM_FPU_REGS];
|
||||
FAST486_FPU_STATUS_REG FpuStatus;
|
||||
FAST486_FPU_CONTROL_REG FpuControl;
|
||||
USHORT FpuTag;
|
||||
};
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
Fast486Initialize(PFAST486_STATE State,
|
||||
FAST486_MEM_READ_PROC MemReadCallback,
|
||||
FAST486_MEM_WRITE_PROC MemWriteCallback,
|
||||
FAST486_IO_READ_PROC IoReadCallback,
|
||||
FAST486_IO_WRITE_PROC IoWriteCallback,
|
||||
FAST486_IDLE_PROC IdleCallback,
|
||||
FAST486_BOP_PROC BopCallback,
|
||||
FAST486_INT_ACK_PROC IntAckCallback,
|
||||
PULONG Tlb);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
Fast486Reset(PFAST486_STATE State);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
Fast486Continue(PFAST486_STATE State);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
Fast486StepInto(PFAST486_STATE State);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
Fast486StepOver(PFAST486_STATE State);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
Fast486StepOut(PFAST486_STATE State);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
Fast486DumpState(PFAST486_STATE State);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
Fast486Interrupt(PFAST486_STATE State, UCHAR Number);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
Fast486InterruptSignal(PFAST486_STATE State);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
Fast486ExecuteAt(PFAST486_STATE State, USHORT Segment, ULONG Offset);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
Fast486SetStack(PFAST486_STATE State, USHORT Segment, ULONG Offset);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
Fast486SetSegment
|
||||
(
|
||||
PFAST486_STATE State,
|
||||
FAST486_SEG_REGS Segment,
|
||||
USHORT Selector
|
||||
);
|
||||
|
||||
#endif // _FAST486_H_
|
||||
|
||||
/* EOF */
|
|
@ -283,10 +283,13 @@ _SEH3$_AutoCleanup(
|
|||
#define _SEH3$_DEFINE_FILTER_FUNC(_Name, expression) \
|
||||
_SEH3$_NESTED_FUNC_OPEN(_Name) \
|
||||
/* Declare the intrinsics for exception filters */ \
|
||||
_Pragma("GCC diagnostic push") \
|
||||
_Pragma("GCC diagnostic ignored \"-Wshadow\"") \
|
||||
inline __attribute__((always_inline, gnu_inline)) \
|
||||
unsigned long _exception_code() { return _SEH3$_TrylevelFrame.ExceptionPointers->ExceptionRecord->ExceptionCode; } \
|
||||
inline __attribute__((always_inline, gnu_inline)) \
|
||||
void * _exception_info() { return _SEH3$_TrylevelFrame.ExceptionPointers; } \
|
||||
_Pragma("GCC diagnostic pop") \
|
||||
\
|
||||
/* Now handle the actual filter expression */ \
|
||||
return (expression); \
|
||||
|
@ -345,6 +348,9 @@ _SEH3$_AutoCleanup(
|
|||
(void)&&_SEH3$_l_OnException; \
|
||||
(void)&&_SEH3$_l_BeforeFilterOrFinally; \
|
||||
(void)&&_SEH3$_l_FilterOrFinally; \
|
||||
\
|
||||
_Pragma("GCC diagnostic push") \
|
||||
_Pragma("GCC diagnostic ignored \"-Wdeclaration-after-statement\"") \
|
||||
\
|
||||
/* Count the try level. Outside of any __try, _SEH3$_TryLevel is 0 */ \
|
||||
enum { \
|
||||
|
@ -357,6 +363,8 @@ _SEH3$_AutoCleanup(
|
|||
\
|
||||
/* Allocate a registration frame */ \
|
||||
volatile SEH3$_REGISTRATION_FRAME _SEH3$_AUTO_CLEANUP _SEH3$_TrylevelFrame; \
|
||||
\
|
||||
_Pragma("GCC diagnostic pop") \
|
||||
\
|
||||
goto _SEH3$_l_BeforeTry; \
|
||||
/* Silence warning */ goto _SEH3$_l_AfterTry; \
|
||||
|
@ -373,6 +381,9 @@ _SEH3$_AutoCleanup(
|
|||
\
|
||||
_SEH3$_l_BeforeTry: (void)0; \
|
||||
_SEH3$_ASM_GOTO(_SEH3$_l_OnException); \
|
||||
\
|
||||
_Pragma("GCC diagnostic push") \
|
||||
_Pragma("GCC diagnostic ignored \"-Wdeclaration-after-statement\"") \
|
||||
\
|
||||
/* Forward declaration of the filter function */ \
|
||||
_SEH3$_DECLARE_FILTER_FUNC(_SEH3$_FilterFunction); \
|
||||
|
@ -421,6 +432,9 @@ _SEH3$_AutoCleanup(
|
|||
\
|
||||
_SEH3$_l_BeforeTry: (void)0; \
|
||||
_SEH3$_ASM_GOTO(_SEH3$_l_OnException); \
|
||||
\
|
||||
_Pragma("GCC diagnostic push") \
|
||||
_Pragma("GCC diagnostic ignored \"-Wdeclaration-after-statement\"") \
|
||||
\
|
||||
/* Forward declaration of the finally function */ \
|
||||
_SEH3$_DECLARE_FILTER_FUNC(_SEH3$_FinallyFunction); \
|
||||
|
@ -458,6 +472,8 @@ _SEH3$_AutoCleanup(
|
|||
\
|
||||
/* Implementation of the auto cleanup function */ \
|
||||
_SEH3$_DEFINE_CLEANUP_FUNC(_SEH3$_AutoCleanup); \
|
||||
\
|
||||
_Pragma("GCC diagnostic pop") \
|
||||
\
|
||||
/* Close the outer scope */ \
|
||||
} while (0);
|
||||
|
|
|
@ -429,14 +429,14 @@ typedef struct
|
|||
|
||||
typedef struct
|
||||
{
|
||||
HANDLE OutputHandle;
|
||||
|
||||
BOOL Unicode;
|
||||
HANDLE ConsoleHandle;
|
||||
HANDLE OutputHandle;
|
||||
SMALL_RECT ScrollRectangle;
|
||||
BOOL UseClipRectangle;
|
||||
SMALL_RECT ClipRectangle;
|
||||
COORD DestinationOrigin;
|
||||
CHAR_INFO Fill;
|
||||
BOOL UseClipRectangle;
|
||||
COORD DestinationOrigin;
|
||||
CHAR_INFO Fill;
|
||||
BOOLEAN Unicode;
|
||||
} CONSOLE_SCROLLSCREENBUFFER, *PCONSOLE_SCROLLSCREENBUFFER;
|
||||
|
||||
|
||||
|
@ -674,20 +674,27 @@ typedef struct
|
|||
|
||||
typedef struct
|
||||
{
|
||||
DWORD Length;
|
||||
DWORD ExeLength;
|
||||
LPWSTR ExeName;
|
||||
HANDLE ConsoleHandle;
|
||||
USHORT ExeLength;
|
||||
PVOID ExeName;
|
||||
ULONG Length;
|
||||
BOOLEAN Unicode;
|
||||
BOOLEAN Unicode2;
|
||||
} CONSOLE_GETALLALIASESLENGTH, *PCONSOLE_GETALLALIASESLENGTH;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
DWORD Length;
|
||||
LPWSTR ExeNames;
|
||||
HANDLE ConsoleHandle;
|
||||
ULONG Length ; // ExeLength; // ExesLength
|
||||
PVOID ExeNames;
|
||||
BOOLEAN Unicode;
|
||||
} CONSOLE_GETALIASESEXES, *PCONSOLE_GETALIASESEXES;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
DWORD Length;
|
||||
HANDLE ConsoleHandle;
|
||||
ULONG Length;
|
||||
BOOLEAN Unicode;
|
||||
} CONSOLE_GETALIASESEXESLENGTH, *PCONSOLE_GETALIASESEXESLENGTH;
|
||||
|
||||
|
||||
|
@ -710,6 +717,13 @@ typedef struct
|
|||
UNICODE_STRING ExeName;
|
||||
} CONSOLE_EXPUNGECOMMANDHISTORY, *PCONSOLE_EXPUNGECOMMANDHISTORY;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UINT HistoryBufferSize;
|
||||
UINT NumberOfHistoryBuffers;
|
||||
DWORD dwFlags;
|
||||
} CONSOLE_GETSETHISTORYINFO, *PCONSOLE_GETSETHISTORYINFO;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UNICODE_STRING ExeName;
|
||||
|
@ -718,10 +732,9 @@ typedef struct
|
|||
|
||||
typedef struct
|
||||
{
|
||||
UINT HistoryBufferSize;
|
||||
UINT NumberOfHistoryBuffers;
|
||||
DWORD dwFlags;
|
||||
} CONSOLE_GETSETHISTORYINFO, *PCONSOLE_GETSETHISTORYINFO;
|
||||
HANDLE ConsoleHandle;
|
||||
ULONG Mode;
|
||||
} CONSOLE_SETHISTORYMODE, *PCONSOLE_SETHISTORYMODE;
|
||||
|
||||
|
||||
|
||||
|
@ -841,8 +854,9 @@ typedef struct _CONSOLE_API_MESSAGE
|
|||
CONSOLE_GETCOMMANDHISTORY GetCommandHistoryRequest;
|
||||
CONSOLE_GETCOMMANDHISTORYLENGTH GetCommandHistoryLengthRequest;
|
||||
CONSOLE_EXPUNGECOMMANDHISTORY ExpungeCommandHistoryRequest;
|
||||
CONSOLE_SETHISTORYNUMBERCOMMANDS SetHistoryNumberCommandsRequest;
|
||||
CONSOLE_GETSETHISTORYINFO HistoryInfoRequest;
|
||||
CONSOLE_SETHISTORYNUMBERCOMMANDS SetHistoryNumberCommandsRequest;
|
||||
CONSOLE_SETHISTORYMODE SetHistoryModeRequest;
|
||||
|
||||
/* Input and Output Code Pages */
|
||||
CONSOLE_GETINPUTOUTPUTCP GetConsoleCPRequest;
|
||||
|
|
117
include/reactos/subsys/win/vdm.h
Normal file
117
include/reactos/subsys/win/vdm.h
Normal file
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Base API Server DLL
|
||||
* FILE: include/reactos/subsys/win/vdm.h
|
||||
* PURPOSE: Public definitions for the Virtual Dos Machine
|
||||
* PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||
* Alex Ionescu (alex.ionescu@reactos.org)
|
||||
*/
|
||||
|
||||
#ifndef _VDM_H
|
||||
#define _VDM_H
|
||||
|
||||
#pragma once
|
||||
|
||||
/* CONSTANTS & TYPES **********************************************************/
|
||||
|
||||
typedef enum _VDM_ENTRY_CODE
|
||||
{
|
||||
VdmEntryUndo,
|
||||
VdmEntryUpdateProcess,
|
||||
VdmEntryUpdateControlCHandler
|
||||
} VDM_ENTRY_CODE;
|
||||
|
||||
//
|
||||
// Undo States
|
||||
//
|
||||
#define VDM_UNDO_PARTIAL 0x01
|
||||
#define VDM_UNDO_FULL 0x02
|
||||
#define VDM_UNDO_REUSE 0x04
|
||||
#define VDM_UNDO_COMPLETED 0x08
|
||||
|
||||
//
|
||||
// Binary Types to share with VDM
|
||||
//
|
||||
#define BINARY_TYPE_EXE 0x01
|
||||
#define BINARY_TYPE_COM 0x02
|
||||
#define BINARY_TYPE_PIF 0x03
|
||||
#define BINARY_TYPE_DOS 0x10
|
||||
#define BINARY_TYPE_SEPARATE_WOW 0x20
|
||||
#define BINARY_TYPE_WOW 0x40
|
||||
#define BINARY_TYPE_WOW_EX 0x80
|
||||
|
||||
//
|
||||
// VDM States
|
||||
//
|
||||
#define VDM_NOT_LOADED 0x01
|
||||
#define VDM_NOT_READY 0x02
|
||||
#define VDM_READY 0x04
|
||||
|
||||
//
|
||||
// VDM Flags
|
||||
//
|
||||
#define VDM_FLAG_FIRST_TASK 0x01
|
||||
#define VDM_FLAG_WOW 0x02
|
||||
#define VDM_FLAG_DOS 0x04
|
||||
#define VDM_FLAG_RETRY 0x08
|
||||
#define VDM_INC_REENTER_COUNT 0x10
|
||||
#define VDM_DEC_REENTER_COUNT 0x20
|
||||
#define VDM_FLAG_NESTED_TASK 0x40
|
||||
#define VDM_FLAG_DONT_WAIT 0x80
|
||||
#define VDM_GET_FIRST_COMMAND 0x100
|
||||
#define VDM_GET_ENVIRONMENT 0x400
|
||||
#define VDM_FLAG_SEPARATE_WOW 0x800
|
||||
#define VDM_LIST_WOW_PROCESSES 0x1000
|
||||
#define VDM_LIST_WOW_TASKS 0x4000
|
||||
#define VDM_ADD_WOW_TASK 0x8000
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ULONG TaskId;
|
||||
ULONG CreationFlags;
|
||||
ULONG ExitCode;
|
||||
ULONG CodePage;
|
||||
HANDLE StdIn;
|
||||
HANDLE StdOut;
|
||||
HANDLE StdErr;
|
||||
LPSTR CmdLine;
|
||||
LPSTR AppName;
|
||||
LPSTR PifFile;
|
||||
LPSTR CurDirectory;
|
||||
LPSTR Env;
|
||||
ULONG EnvLen;
|
||||
STARTUPINFOA StartupInfo;
|
||||
LPSTR Desktop;
|
||||
ULONG DesktopLen;
|
||||
LPSTR Title;
|
||||
ULONG TitleLen;
|
||||
LPVOID Reserved;
|
||||
ULONG ReservedLen;
|
||||
USHORT CmdLen;
|
||||
USHORT AppLen;
|
||||
USHORT PifLen;
|
||||
USHORT CurDirectoryLen;
|
||||
USHORT VDMState;
|
||||
USHORT CurrentDrive;
|
||||
BOOLEAN ComingFromBat;
|
||||
} VDM_COMMAND_INFO, *PVDM_COMMAND_INFO;
|
||||
|
||||
|
||||
/* FUNCTION PROTOTYPES ********************************************************/
|
||||
|
||||
BOOL
|
||||
WINAPI
|
||||
GetNextVDMCommand(
|
||||
IN OUT PVDM_COMMAND_INFO CommandData OPTIONAL
|
||||
);
|
||||
|
||||
VOID
|
||||
WINAPI
|
||||
ExitVDM(
|
||||
IN BOOL IsWow,
|
||||
IN ULONG iWowTask
|
||||
);
|
||||
|
||||
#endif // _VDM_H
|
||||
|
||||
/* EOF */
|
|
@ -343,9 +343,9 @@ extern int spawnvp(int mode, const char *cmdname, const char * const argv[]);
|
|||
#if defined(_MSC_VER) || (defined(__i386__) && defined(__GNUC__) && !defined(WINE_PORT_NO_INTERLOCKED))
|
||||
|
||||
#define interlocked_cmpxchg InterlockedCompareExchange
|
||||
#define interlocked_cmpxchg_ptr InterlockedCompareExchangePtr
|
||||
#define interlocked_cmpxchg_ptr InterlockedCompareExchangePointer
|
||||
#define interlocked_xchg InterlockedExchange
|
||||
#define interlocked_xchg_ptr InterlockedExchangePtr
|
||||
#define interlocked_xchg_ptr InterlockedExchangePointer
|
||||
#define interlocked_xchg_add InterlockedExchangeAdd
|
||||
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ add_subdirectory(cryptlib)
|
|||
#add_subdirectory(dnslib) Nothing links to this lib.
|
||||
add_subdirectory(drivers)
|
||||
add_subdirectory(epsapi)
|
||||
add_subdirectory(fast486)
|
||||
add_subdirectory(fslib)
|
||||
add_subdirectory(lsalib)
|
||||
add_subdirectory(ppcmmu)
|
||||
|
|
12
lib/fast486/CMakeLists.txt
Normal file
12
lib/fast486/CMakeLists.txt
Normal file
|
@ -0,0 +1,12 @@
|
|||
|
||||
include_directories(${REACTOS_SOURCE_DIR}/include/reactos/libs/fast486)
|
||||
|
||||
list(APPEND SOURCE
|
||||
fast486.c
|
||||
opcodes.c
|
||||
opgroups.c
|
||||
extraops.c
|
||||
common.c
|
||||
fpu.c)
|
||||
|
||||
add_library(fast486 ${SOURCE})
|
339
lib/fast486/COPYING
Normal file
339
lib/fast486/COPYING
Normal file
|
@ -0,0 +1,339 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
356
lib/fast486/common.c
Normal file
356
lib/fast486/common.c
Normal file
|
@ -0,0 +1,356 @@
|
|||
/*
|
||||
* Fast486 386/486 CPU Emulation Library
|
||||
* common.c
|
||||
*
|
||||
* Copyright (C) 2013 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/* INCLUDES *******************************************************************/
|
||||
|
||||
#include <windef.h>
|
||||
|
||||
// #define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
#include <fast486.h>
|
||||
#include "common.h"
|
||||
|
||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||
|
||||
BOOLEAN
|
||||
Fast486ReadMemory(PFAST486_STATE State,
|
||||
FAST486_SEG_REGS SegmentReg,
|
||||
ULONG Offset,
|
||||
BOOLEAN InstFetch,
|
||||
PVOID Buffer,
|
||||
ULONG Size)
|
||||
{
|
||||
ULONG LinearAddress;
|
||||
PFAST486_SEG_REG CachedDescriptor;
|
||||
|
||||
ASSERT(SegmentReg < FAST486_NUM_SEG_REGS);
|
||||
|
||||
/* Get the cached descriptor */
|
||||
CachedDescriptor = &State->SegmentRegs[SegmentReg];
|
||||
|
||||
if ((Offset + Size - 1) > CachedDescriptor->Limit)
|
||||
{
|
||||
/* Read beyond limit */
|
||||
Fast486Exception(State, FAST486_EXCEPTION_GP);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Check for protected mode */
|
||||
if (State->ControlRegisters[0] & FAST486_CR0_PE)
|
||||
{
|
||||
/* Privilege checks */
|
||||
|
||||
if (!CachedDescriptor->Present)
|
||||
{
|
||||
Fast486Exception(State, FAST486_EXCEPTION_NP);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((!InstFetch && (GET_SEGMENT_RPL(CachedDescriptor->Selector) > CachedDescriptor->Dpl))
|
||||
|| (Fast486GetCurrentPrivLevel(State) > CachedDescriptor->Dpl))
|
||||
{
|
||||
Fast486Exception(State, FAST486_EXCEPTION_GP);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (InstFetch)
|
||||
{
|
||||
if (!CachedDescriptor->Executable)
|
||||
{
|
||||
/* Data segment not executable */
|
||||
Fast486Exception(State, FAST486_EXCEPTION_GP);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (CachedDescriptor->Executable && (!CachedDescriptor->ReadWrite))
|
||||
{
|
||||
/* Code segment not readable */
|
||||
Fast486Exception(State, FAST486_EXCEPTION_GP);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Find the linear address */
|
||||
LinearAddress = CachedDescriptor->Base + Offset;
|
||||
|
||||
/* Read from the linear address */
|
||||
return Fast486ReadLinearMemory(State, LinearAddress, Buffer, Size);
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
Fast486WriteMemory(PFAST486_STATE State,
|
||||
FAST486_SEG_REGS SegmentReg,
|
||||
ULONG Offset,
|
||||
PVOID Buffer,
|
||||
ULONG Size)
|
||||
{
|
||||
ULONG LinearAddress;
|
||||
PFAST486_SEG_REG CachedDescriptor;
|
||||
|
||||
ASSERT(SegmentReg < FAST486_NUM_SEG_REGS);
|
||||
|
||||
/* Get the cached descriptor */
|
||||
CachedDescriptor = &State->SegmentRegs[SegmentReg];
|
||||
|
||||
if ((Offset + Size - 1) > CachedDescriptor->Limit)
|
||||
{
|
||||
/* Write beyond limit */
|
||||
Fast486Exception(State, FAST486_EXCEPTION_GP);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Check for protected mode */
|
||||
if (State->ControlRegisters[0] & FAST486_CR0_PE)
|
||||
{
|
||||
/* Privilege checks */
|
||||
|
||||
if (!CachedDescriptor->Present)
|
||||
{
|
||||
Fast486Exception(State, FAST486_EXCEPTION_NP);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((GET_SEGMENT_RPL(CachedDescriptor->Selector) > CachedDescriptor->Dpl)
|
||||
|| (Fast486GetCurrentPrivLevel(State) > CachedDescriptor->Dpl))
|
||||
{
|
||||
Fast486Exception(State, FAST486_EXCEPTION_GP);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (CachedDescriptor->Executable)
|
||||
{
|
||||
/* Code segment not writable */
|
||||
Fast486Exception(State, FAST486_EXCEPTION_GP);
|
||||
return FALSE;
|
||||
}
|
||||
else if (!CachedDescriptor->ReadWrite)
|
||||
{
|
||||
/* Data segment not writeable */
|
||||
Fast486Exception(State, FAST486_EXCEPTION_GP);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Find the linear address */
|
||||
LinearAddress = CachedDescriptor->Base + Offset;
|
||||
|
||||
/* Write to the linear address */
|
||||
return Fast486WriteLinearMemory(State, LinearAddress, Buffer, Size);
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
Fast486InterruptInternal(PFAST486_STATE State,
|
||||
USHORT SegmentSelector,
|
||||
ULONG Offset,
|
||||
BOOLEAN InterruptGate)
|
||||
{
|
||||
/* 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;
|
||||
|
||||
/* Check if the interrupt handler is more privileged */
|
||||
if (Fast486GetCurrentPrivLevel(State) > GET_SEGMENT_RPL(SegmentSelector))
|
||||
{
|
||||
/* Read the TSS */
|
||||
if (!Fast486ReadLinearMemory(State,
|
||||
State->TaskReg.Base,
|
||||
&Tss,
|
||||
sizeof(Tss)))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Check the new (higher) privilege level */
|
||||
switch (GET_SEGMENT_RPL(SegmentSelector))
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
if (!Fast486LoadSegment(State, FAST486_REG_SS, Tss.Ss0))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return FALSE;
|
||||
}
|
||||
State->GeneralRegs[FAST486_REG_ESP].Long = Tss.Esp0;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 1:
|
||||
{
|
||||
if (!Fast486LoadSegment(State, FAST486_REG_SS, Tss.Ss1))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return FALSE;
|
||||
}
|
||||
State->GeneralRegs[FAST486_REG_ESP].Long = Tss.Esp1;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
if (!Fast486LoadSegment(State, FAST486_REG_SS, Tss.Ss2))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return FALSE;
|
||||
}
|
||||
State->GeneralRegs[FAST486_REG_ESP].Long = Tss.Esp2;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
/* Should never reach here! */
|
||||
ASSERT(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
/* Push SS selector */
|
||||
if (!Fast486StackPush(State, OldSs)) return FALSE;
|
||||
|
||||
/* Push stack pointer */
|
||||
if (!Fast486StackPush(State, OldEsp)) return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (State->SegmentRegs[FAST486_REG_CS].Size)
|
||||
{
|
||||
/* Set OPSIZE, because INT always pushes 16-bit values in real mode */
|
||||
State->PrefixFlags |= FAST486_PREFIX_OPSIZE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Push EFLAGS */
|
||||
if (!Fast486StackPush(State, State->Flags.Long)) return FALSE;
|
||||
|
||||
/* Push CS selector */
|
||||
if (!Fast486StackPush(State, State->SegmentRegs[FAST486_REG_CS].Selector)) return FALSE;
|
||||
|
||||
/* Push the instruction pointer */
|
||||
if (!Fast486StackPush(State, State->InstPtr.Long)) return FALSE;
|
||||
|
||||
if (InterruptGate)
|
||||
{
|
||||
/* Disable interrupts after a jump to an interrupt gate handler */
|
||||
State->Flags.If = FALSE;
|
||||
}
|
||||
|
||||
/* Load new CS */
|
||||
if (!Fast486LoadSegment(State, FAST486_REG_CS, SegmentSelector))
|
||||
{
|
||||
/* An exception occurred during the jump */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (State->SegmentRegs[FAST486_REG_CS].Size)
|
||||
{
|
||||
/* 32-bit code segment, use EIP */
|
||||
State->InstPtr.Long = Offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 16-bit code segment, use IP */
|
||||
State->InstPtr.LowWord = LOWORD(Offset);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
VOID
|
||||
FASTCALL
|
||||
Fast486ExceptionWithErrorCode(PFAST486_STATE State,
|
||||
FAST486_EXCEPTIONS ExceptionCode,
|
||||
ULONG ErrorCode)
|
||||
{
|
||||
FAST486_IDT_ENTRY IdtEntry;
|
||||
|
||||
/* Increment the exception count */
|
||||
State->ExceptionCount++;
|
||||
|
||||
/* Check if the exception occurred more than once */
|
||||
if (State->ExceptionCount > 1)
|
||||
{
|
||||
/* Then this is a double fault */
|
||||
ExceptionCode = FAST486_EXCEPTION_DF;
|
||||
}
|
||||
|
||||
/* Check if this is a triple fault */
|
||||
if (State->ExceptionCount == 3)
|
||||
{
|
||||
/* Reset the CPU */
|
||||
Fast486Reset(State);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Restore the IP to the saved IP */
|
||||
State->InstPtr = State->SavedInstPtr;
|
||||
|
||||
if (!Fast486GetIntVector(State, ExceptionCode, &IdtEntry))
|
||||
{
|
||||
/*
|
||||
* If this function failed, that means Fast486Exception
|
||||
* was called again, so just return in this case.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
/* Perform the interrupt */
|
||||
if (!Fast486InterruptInternal(State,
|
||||
IdtEntry.Selector,
|
||||
MAKELONG(IdtEntry.Offset, IdtEntry.OffsetHigh),
|
||||
IdtEntry.Type))
|
||||
{
|
||||
/*
|
||||
* If this function failed, that means Fast486Exception
|
||||
* was called again, so just return in this case.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
if (EXCEPTION_HAS_ERROR_CODE(ExceptionCode)
|
||||
&& (State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE))
|
||||
{
|
||||
/* Push the error code */
|
||||
if (!Fast486StackPush(State, ErrorCode))
|
||||
{
|
||||
/*
|
||||
* If this function failed, that means Fast486Exception
|
||||
* was called again, so just return in this case.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Reset the exception count */
|
||||
State->ExceptionCount = 0;
|
||||
}
|
||||
|
||||
/* EOF */
|
180
lib/fast486/common.h
Normal file
180
lib/fast486/common.h
Normal file
|
@ -0,0 +1,180 @@
|
|||
/*
|
||||
* Fast486 386/486 CPU Emulation Library
|
||||
* common.h
|
||||
*
|
||||
* Copyright (C) 2013 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef _COMMON_H_
|
||||
#define _COMMON_H_
|
||||
|
||||
#pragma once
|
||||
|
||||
/* DEFINES ********************************************************************/
|
||||
|
||||
#define SIGN_FLAG_BYTE 0x80
|
||||
#define SIGN_FLAG_WORD 0x8000
|
||||
#define SIGN_FLAG_LONG 0x80000000
|
||||
#define REAL_MODE_FLAGS_MASK 0x57FD5
|
||||
#define PROT_MODE_FLAGS_MASK 0x50DD5
|
||||
|
||||
/* Block size for string operations */
|
||||
#define STRING_BLOCK_SIZE 4096
|
||||
|
||||
#define GET_SEGMENT_RPL(s) ((s) & 3)
|
||||
#define GET_SEGMENT_INDEX(s) ((s) & 0xFFF8)
|
||||
#define SEGMENT_TABLE_INDICATOR (1 << 2)
|
||||
#define EXCEPTION_HAS_ERROR_CODE(x) (((x) == 8) || ((x) >= 10 && (x) <= 14))
|
||||
|
||||
#define NO_LOCK_PREFIX()\
|
||||
if (State->PrefixFlags & FAST486_PREFIX_LOCK)\
|
||||
{\
|
||||
Fast486Exception(State, FAST486_EXCEPTION_UD);\
|
||||
return FALSE;\
|
||||
}
|
||||
|
||||
#define TOGGLE_OPSIZE(x)\
|
||||
if (State->PrefixFlags & FAST486_PREFIX_OPSIZE) x = !x;
|
||||
|
||||
#define TOGGLE_ADSIZE(x)\
|
||||
if (State->PrefixFlags & FAST486_PREFIX_ADSIZE) x = !x;
|
||||
|
||||
#define SWAP(x, y) { (x) ^= (y); (y) ^= (x); (x) ^= (y); }
|
||||
|
||||
#define ALIGNMENT_CHECK(x, a) if (State->Flags.Ac \
|
||||
&& (State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_AM)\
|
||||
&& (State->Cpl == 3)\
|
||||
&& (((x) % (a)) != 0))\
|
||||
{\
|
||||
Fast486Exception(State, FAST486_EXCEPTION_AC);\
|
||||
return FALSE;\
|
||||
}
|
||||
|
||||
#define PAGE_ALIGN(x) ((x) & 0xFFFFF000)
|
||||
#define PAGE_OFFSET(x) ((x) & 0x00000FFF)
|
||||
#define GET_ADDR_PDE(x) ((x) >> 22)
|
||||
#define GET_ADDR_PTE(x) (((x) >> 12) & 0x3FF)
|
||||
#define INVALID_TLB_FIELD 0xFFFFFFFF
|
||||
|
||||
#ifndef PAGE_SIZE
|
||||
#define PAGE_SIZE 4096
|
||||
#endif
|
||||
|
||||
typedef struct _FAST486_MOD_REG_RM
|
||||
{
|
||||
FAST486_GEN_REGS Register;
|
||||
BOOLEAN Memory;
|
||||
union
|
||||
{
|
||||
FAST486_GEN_REGS SecondRegister;
|
||||
ULONG MemoryAddress;
|
||||
};
|
||||
} FAST486_MOD_REG_RM, *PFAST486_MOD_REG_RM;
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
typedef union _FAST486_PAGE_DIR
|
||||
{
|
||||
struct
|
||||
{
|
||||
ULONG Present : 1;
|
||||
ULONG Writeable : 1;
|
||||
ULONG Usermode : 1;
|
||||
ULONG WriteThrough : 1;
|
||||
ULONG NoCache : 1;
|
||||
ULONG Accessed : 1;
|
||||
ULONG AlwaysZero : 1;
|
||||
ULONG Size : 1;
|
||||
ULONG Unused : 4;
|
||||
ULONG TableAddress : 20;
|
||||
};
|
||||
ULONG Value;
|
||||
} FAST486_PAGE_DIR, *PFAST486_PAGE_DIR;
|
||||
|
||||
C_ASSERT(sizeof(FAST486_PAGE_DIR) == sizeof(ULONG));
|
||||
|
||||
typedef union _FAST486_PAGE_TABLE
|
||||
{
|
||||
struct
|
||||
{
|
||||
ULONG Present : 1;
|
||||
ULONG Writeable : 1;
|
||||
ULONG Usermode : 1;
|
||||
ULONG WriteThrough : 1;
|
||||
ULONG NoCache : 1;
|
||||
ULONG Accessed : 1;
|
||||
ULONG Dirty : 1;
|
||||
ULONG AlwaysZero : 1;
|
||||
ULONG Global : 1;
|
||||
ULONG Unused : 3;
|
||||
ULONG Address : 20;
|
||||
};
|
||||
ULONG Value;
|
||||
} FAST486_PAGE_TABLE, *PFAST486_PAGE_TABLE;
|
||||
|
||||
C_ASSERT(sizeof(FAST486_PAGE_DIR) == sizeof(ULONG));
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
BOOLEAN
|
||||
Fast486ReadMemory
|
||||
(
|
||||
PFAST486_STATE State,
|
||||
FAST486_SEG_REGS SegmentReg,
|
||||
ULONG Offset,
|
||||
BOOLEAN InstFetch,
|
||||
PVOID Buffer,
|
||||
ULONG Size
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
Fast486WriteMemory
|
||||
(
|
||||
PFAST486_STATE State,
|
||||
FAST486_SEG_REGS SegmentReg,
|
||||
ULONG Offset,
|
||||
PVOID Buffer,
|
||||
ULONG Size
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
Fast486InterruptInternal
|
||||
(
|
||||
PFAST486_STATE State,
|
||||
USHORT SegmentSelector,
|
||||
ULONG Offset,
|
||||
BOOLEAN InterruptGate
|
||||
);
|
||||
|
||||
VOID
|
||||
FASTCALL
|
||||
Fast486ExceptionWithErrorCode
|
||||
(
|
||||
PFAST486_STATE State,
|
||||
FAST486_EXCEPTIONS ExceptionCode,
|
||||
ULONG ErrorCode
|
||||
);
|
||||
|
||||
/* INLINED FUNCTIONS **********************************************************/
|
||||
|
||||
#include "common.inl"
|
||||
|
||||
#endif // _COMMON_H_
|
||||
|
||||
/* EOF */
|
1324
lib/fast486/common.inl
Normal file
1324
lib/fast486/common.inl
Normal file
File diff suppressed because it is too large
Load diff
2387
lib/fast486/extraops.c
Normal file
2387
lib/fast486/extraops.c
Normal file
File diff suppressed because it is too large
Load diff
67
lib/fast486/extraops.h
Normal file
67
lib/fast486/extraops.h
Normal file
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Fast486 386/486 CPU Emulation Library
|
||||
* extraops.h
|
||||
*
|
||||
* Copyright (C) 2013 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef _EXTRAOPS_H_
|
||||
#define _EXTRAOPS_H_
|
||||
|
||||
#pragma once
|
||||
|
||||
/* DEFINES ********************************************************************/
|
||||
|
||||
FAST486_OPCODE_HANDLER(Fast486ExtOpcodeLar);
|
||||
FAST486_OPCODE_HANDLER(Fast486ExtOpcodeLsl);
|
||||
FAST486_OPCODE_HANDLER(Fast486ExtOpcodeClts);
|
||||
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);
|
||||
FAST486_OPCODE_HANDLER(Fast486ExtOpcodeShld);
|
||||
FAST486_OPCODE_HANDLER(Fast486ExtOpcodePushGs);
|
||||
FAST486_OPCODE_HANDLER(Fast486ExtOpcodePopGs);
|
||||
FAST486_OPCODE_HANDLER(Fast486ExtOpcodeBts);
|
||||
FAST486_OPCODE_HANDLER(Fast486ExtOpcodeShrd);
|
||||
FAST486_OPCODE_HANDLER(Fast486ExtOpcodeImul);
|
||||
FAST486_OPCODE_HANDLER(Fast486ExtOpcodeCmpXchgByte);
|
||||
FAST486_OPCODE_HANDLER(Fast486ExtOpcodeCmpXchg);
|
||||
FAST486_OPCODE_HANDLER(Fast486ExtOpcodeLss);
|
||||
FAST486_OPCODE_HANDLER(Fast486ExtOpcodeBtr);
|
||||
FAST486_OPCODE_HANDLER(Fast486ExtOpcodeLfsLgs);
|
||||
FAST486_OPCODE_HANDLER(Fast486ExtOpcodeMovzxByte);
|
||||
FAST486_OPCODE_HANDLER(Fast486ExtOpcodeMovzxWord);
|
||||
FAST486_OPCODE_HANDLER(Fast486ExtOpcodeBtc);
|
||||
FAST486_OPCODE_HANDLER(Fast486ExtOpcodeBsf);
|
||||
FAST486_OPCODE_HANDLER(Fast486ExtOpcodeBsr);
|
||||
FAST486_OPCODE_HANDLER(Fast486ExtOpcodeMovsxByte);
|
||||
FAST486_OPCODE_HANDLER(Fast486ExtOpcodeMovsxWord);
|
||||
FAST486_OPCODE_HANDLER(Fast486ExtOpcodeConditionalJmp);
|
||||
FAST486_OPCODE_HANDLER(Fast486ExtOpcodeConditionalSet);
|
||||
FAST486_OPCODE_HANDLER(Fast486ExtOpcodeXaddByte);
|
||||
FAST486_OPCODE_HANDLER(Fast486ExtOpcodeXadd);
|
||||
FAST486_OPCODE_HANDLER(Fast486ExtOpcodeBswap);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeExtended);
|
||||
|
||||
#endif // _EXTRAOPS_H_
|
||||
|
||||
/* EOF */
|
||||
|
463
lib/fast486/fast486.c
Normal file
463
lib/fast486/fast486.c
Normal file
|
@ -0,0 +1,463 @@
|
|||
/*
|
||||
* Fast486 386/486 CPU Emulation Library
|
||||
* fast486.c
|
||||
*
|
||||
* Copyright (C) 2013 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/* INCLUDES *******************************************************************/
|
||||
|
||||
#include <windef.h>
|
||||
|
||||
// #define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
#include <fast486.h>
|
||||
#include "common.h"
|
||||
#include "opcodes.h"
|
||||
|
||||
/* DEFINES ********************************************************************/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
FAST486_STEP_INTO,
|
||||
FAST486_STEP_OVER,
|
||||
FAST486_STEP_OUT,
|
||||
FAST486_CONTINUE
|
||||
} FAST486_EXEC_CMD;
|
||||
|
||||
/* PRIVATE FUNCTIONS **********************************************************/
|
||||
|
||||
static
|
||||
inline
|
||||
VOID
|
||||
NTAPI
|
||||
Fast486ExecutionControl(PFAST486_STATE State, FAST486_EXEC_CMD Command)
|
||||
{
|
||||
UCHAR Opcode;
|
||||
INT ProcedureCallCount = 0;
|
||||
|
||||
/* Main execution loop */
|
||||
do
|
||||
{
|
||||
/* Check if this is a new instruction */
|
||||
if (State->PrefixFlags == 0) State->SavedInstPtr = State->InstPtr;
|
||||
|
||||
/* Perform an instruction fetch */
|
||||
if (!Fast486FetchByte(State, &Opcode))
|
||||
{
|
||||
/* Exception occurred */
|
||||
State->PrefixFlags = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
// TODO: Check for CALL/RET to update ProcedureCallCount.
|
||||
|
||||
if (Fast486OpcodeHandlers[Opcode] != NULL)
|
||||
{
|
||||
/* Call the opcode handler */
|
||||
Fast486OpcodeHandlers[Opcode](State, Opcode);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This is not a valid opcode */
|
||||
Fast486Exception(State, FAST486_EXCEPTION_UD);
|
||||
}
|
||||
|
||||
if (Fast486OpcodeHandlers[Opcode] == Fast486OpcodePrefix)
|
||||
{
|
||||
/* This is a prefix, go to the next instruction immediately */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* A non-prefix opcode has been executed, reset the prefix flags */
|
||||
State->PrefixFlags = 0;
|
||||
|
||||
/*
|
||||
* Check if there is an interrupt to execute, or a hardware interrupt signal
|
||||
* while interrupts are enabled.
|
||||
*/
|
||||
if (State->IntStatus == FAST486_INT_EXECUTE)
|
||||
{
|
||||
FAST486_IDT_ENTRY IdtEntry;
|
||||
|
||||
/* Get the interrupt vector */
|
||||
if (Fast486GetIntVector(State, State->PendingIntNum, &IdtEntry))
|
||||
{
|
||||
/* Perform the interrupt */
|
||||
Fast486InterruptInternal(State,
|
||||
IdtEntry.Selector,
|
||||
MAKELONG(IdtEntry.Offset, IdtEntry.OffsetHigh),
|
||||
IdtEntry.Type);
|
||||
|
||||
/* Restore the prefix flags, which would be set to OPSIZE for 32-bit real mode */
|
||||
State->PrefixFlags = 0;
|
||||
}
|
||||
|
||||
/* Clear the interrupt status */
|
||||
State->IntStatus = FAST486_INT_NONE;
|
||||
}
|
||||
else if (State->Flags.If
|
||||
&& (State->IntAckCallback != NULL)
|
||||
&& (State->IntStatus == FAST486_INT_SIGNAL))
|
||||
{
|
||||
/* Acknowledge the interrupt to get the number */
|
||||
State->PendingIntNum = State->IntAckCallback(State);
|
||||
|
||||
/* Set the interrupt status to execute on the next instruction */
|
||||
State->IntStatus = FAST486_INT_EXECUTE;
|
||||
}
|
||||
}
|
||||
while ((Command == FAST486_CONTINUE)
|
||||
|| (Command == FAST486_STEP_OVER && ProcedureCallCount > 0)
|
||||
|| (Command == FAST486_STEP_OUT && ProcedureCallCount >= 0)
|
||||
|| (Fast486OpcodeHandlers[Opcode] == Fast486OpcodePrefix));
|
||||
}
|
||||
|
||||
/* DEFAULT CALLBACKS **********************************************************/
|
||||
|
||||
static VOID
|
||||
NTAPI
|
||||
Fast486MemReadCallback(PFAST486_STATE State, ULONG Address, PVOID Buffer, ULONG Size)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(State);
|
||||
|
||||
RtlMoveMemory(Buffer, (PVOID)Address, Size);
|
||||
}
|
||||
|
||||
static VOID
|
||||
NTAPI
|
||||
Fast486MemWriteCallback(PFAST486_STATE State, ULONG Address, PVOID Buffer, ULONG Size)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(State);
|
||||
|
||||
RtlMoveMemory((PVOID)Address, Buffer, Size);
|
||||
}
|
||||
|
||||
static VOID
|
||||
NTAPI
|
||||
Fast486IoReadCallback(PFAST486_STATE State, ULONG Port, PVOID Buffer, ULONG DataCount, UCHAR DataSize)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(State);
|
||||
UNREFERENCED_PARAMETER(Port);
|
||||
UNREFERENCED_PARAMETER(Buffer);
|
||||
UNREFERENCED_PARAMETER(DataCount);
|
||||
UNREFERENCED_PARAMETER(DataSize);
|
||||
}
|
||||
|
||||
static VOID
|
||||
NTAPI
|
||||
Fast486IoWriteCallback(PFAST486_STATE State, ULONG Port, PVOID Buffer, ULONG DataCount, UCHAR DataSize)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(State);
|
||||
UNREFERENCED_PARAMETER(Port);
|
||||
UNREFERENCED_PARAMETER(Buffer);
|
||||
UNREFERENCED_PARAMETER(DataCount);
|
||||
UNREFERENCED_PARAMETER(DataSize);
|
||||
}
|
||||
|
||||
static VOID
|
||||
NTAPI
|
||||
Fast486IdleCallback(PFAST486_STATE State)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(State);
|
||||
}
|
||||
|
||||
static VOID
|
||||
NTAPI
|
||||
Fast486BopCallback(PFAST486_STATE State, UCHAR BopCode)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(State);
|
||||
UNREFERENCED_PARAMETER(BopCode);
|
||||
}
|
||||
|
||||
static UCHAR
|
||||
NTAPI
|
||||
Fast486IntAckCallback(PFAST486_STATE State)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(State);
|
||||
|
||||
/* Return something... */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
Fast486Initialize(PFAST486_STATE State,
|
||||
FAST486_MEM_READ_PROC MemReadCallback,
|
||||
FAST486_MEM_WRITE_PROC MemWriteCallback,
|
||||
FAST486_IO_READ_PROC IoReadCallback,
|
||||
FAST486_IO_WRITE_PROC IoWriteCallback,
|
||||
FAST486_IDLE_PROC IdleCallback,
|
||||
FAST486_BOP_PROC BopCallback,
|
||||
FAST486_INT_ACK_PROC IntAckCallback,
|
||||
PULONG Tlb)
|
||||
{
|
||||
/* Set the callbacks (or use default ones if some are NULL) */
|
||||
State->MemReadCallback = (MemReadCallback ? MemReadCallback : Fast486MemReadCallback );
|
||||
State->MemWriteCallback = (MemWriteCallback ? MemWriteCallback : Fast486MemWriteCallback);
|
||||
State->IoReadCallback = (IoReadCallback ? IoReadCallback : Fast486IoReadCallback );
|
||||
State->IoWriteCallback = (IoWriteCallback ? IoWriteCallback : Fast486IoWriteCallback );
|
||||
State->IdleCallback = (IdleCallback ? IdleCallback : Fast486IdleCallback );
|
||||
State->BopCallback = (BopCallback ? BopCallback : Fast486BopCallback );
|
||||
State->IntAckCallback = (IntAckCallback ? IntAckCallback : Fast486IntAckCallback );
|
||||
|
||||
/* Set the TLB (if given) */
|
||||
State->Tlb = Tlb;
|
||||
|
||||
/* Reset the CPU */
|
||||
Fast486Reset(State);
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
Fast486Reset(PFAST486_STATE State)
|
||||
{
|
||||
FAST486_SEG_REGS i;
|
||||
|
||||
FAST486_MEM_READ_PROC MemReadCallback = State->MemReadCallback;
|
||||
FAST486_MEM_WRITE_PROC MemWriteCallback = State->MemWriteCallback;
|
||||
FAST486_IO_READ_PROC IoReadCallback = State->IoReadCallback;
|
||||
FAST486_IO_WRITE_PROC IoWriteCallback = State->IoWriteCallback;
|
||||
FAST486_IDLE_PROC IdleCallback = State->IdleCallback;
|
||||
FAST486_BOP_PROC BopCallback = State->BopCallback;
|
||||
FAST486_INT_ACK_PROC IntAckCallback = State->IntAckCallback;
|
||||
PULONG Tlb = State->Tlb;
|
||||
|
||||
/* Clear the entire structure */
|
||||
RtlZeroMemory(State, sizeof(*State));
|
||||
|
||||
/* Initialize the registers */
|
||||
State->Flags.AlwaysSet = 1;
|
||||
State->InstPtr.LowWord = 0xFFF0;
|
||||
|
||||
/* Set the CPL to 0 */
|
||||
State->Cpl = 0;
|
||||
|
||||
/* Initialize segments */
|
||||
for (i = 0; i < FAST486_NUM_SEG_REGS; i++)
|
||||
{
|
||||
State->SegmentRegs[i].Selector = 0;
|
||||
State->SegmentRegs[i].Base = 0;
|
||||
State->SegmentRegs[i].Limit = 0xFFFF;
|
||||
State->SegmentRegs[i].Present = TRUE;
|
||||
State->SegmentRegs[i].ReadWrite = TRUE;
|
||||
State->SegmentRegs[i].Executable = FALSE;
|
||||
State->SegmentRegs[i].DirConf = FALSE;
|
||||
State->SegmentRegs[i].SystemType = 1; // Segment descriptor
|
||||
State->SegmentRegs[i].Dpl = 0;
|
||||
State->SegmentRegs[i].Size = FALSE; // 16-bit
|
||||
}
|
||||
|
||||
/* Initialize the code segment */
|
||||
State->SegmentRegs[FAST486_REG_CS].Executable = TRUE;
|
||||
State->SegmentRegs[FAST486_REG_CS].Selector = 0xF000;
|
||||
State->SegmentRegs[FAST486_REG_CS].Base = 0xFFFF0000;
|
||||
|
||||
/* Initialize the IDT */
|
||||
State->Idtr.Size = 0x3FF;
|
||||
State->Idtr.Address = 0;
|
||||
|
||||
#ifndef FAST486_NO_FPU
|
||||
/* Initialize CR0 */
|
||||
State->ControlRegisters[FAST486_REG_CR0] |= FAST486_CR0_ET;
|
||||
#endif
|
||||
|
||||
/* Restore the callbacks and TLB */
|
||||
State->MemReadCallback = MemReadCallback;
|
||||
State->MemWriteCallback = MemWriteCallback;
|
||||
State->IoReadCallback = IoReadCallback;
|
||||
State->IoWriteCallback = IoWriteCallback;
|
||||
State->IdleCallback = IdleCallback;
|
||||
State->BopCallback = BopCallback;
|
||||
State->IntAckCallback = IntAckCallback;
|
||||
State->Tlb = Tlb;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
Fast486DumpState(PFAST486_STATE State)
|
||||
{
|
||||
DPRINT1("\nCPU currently executing in %s mode at %04X:%08X\n",
|
||||
(State->ControlRegisters[0] & FAST486_CR0_PE) ? "protected" : "real",
|
||||
State->SegmentRegs[FAST486_REG_CS].Selector,
|
||||
State->InstPtr.Long);
|
||||
DPRINT1("\nGeneral purpose registers:\n"
|
||||
"EAX = %08X\tECX = %08X\tEDX = %08X\tEBX = %08X\n"
|
||||
"ESP = %08X\tEBP = %08X\tESI = %08X\tEDI = %08X\n",
|
||||
State->GeneralRegs[FAST486_REG_EAX].Long,
|
||||
State->GeneralRegs[FAST486_REG_ECX].Long,
|
||||
State->GeneralRegs[FAST486_REG_EDX].Long,
|
||||
State->GeneralRegs[FAST486_REG_EBX].Long,
|
||||
State->GeneralRegs[FAST486_REG_ESP].Long,
|
||||
State->GeneralRegs[FAST486_REG_EBP].Long,
|
||||
State->GeneralRegs[FAST486_REG_ESI].Long,
|
||||
State->GeneralRegs[FAST486_REG_EDI].Long);
|
||||
DPRINT1("\nSegment registers:\n"
|
||||
"ES = %04X (Base: %08X, Limit: %08X, Dpl: %u)\n"
|
||||
"CS = %04X (Base: %08X, Limit: %08X, Dpl: %u)\n"
|
||||
"SS = %04X (Base: %08X, Limit: %08X, Dpl: %u)\n"
|
||||
"DS = %04X (Base: %08X, Limit: %08X, Dpl: %u)\n"
|
||||
"FS = %04X (Base: %08X, Limit: %08X, Dpl: %u)\n"
|
||||
"GS = %04X (Base: %08X, Limit: %08X, Dpl: %u)\n",
|
||||
State->SegmentRegs[FAST486_REG_ES].Selector,
|
||||
State->SegmentRegs[FAST486_REG_ES].Base,
|
||||
State->SegmentRegs[FAST486_REG_ES].Limit,
|
||||
State->SegmentRegs[FAST486_REG_ES].Dpl,
|
||||
State->SegmentRegs[FAST486_REG_CS].Selector,
|
||||
State->SegmentRegs[FAST486_REG_CS].Base,
|
||||
State->SegmentRegs[FAST486_REG_CS].Limit,
|
||||
State->SegmentRegs[FAST486_REG_CS].Dpl,
|
||||
State->SegmentRegs[FAST486_REG_SS].Selector,
|
||||
State->SegmentRegs[FAST486_REG_SS].Base,
|
||||
State->SegmentRegs[FAST486_REG_SS].Limit,
|
||||
State->SegmentRegs[FAST486_REG_SS].Dpl,
|
||||
State->SegmentRegs[FAST486_REG_DS].Selector,
|
||||
State->SegmentRegs[FAST486_REG_DS].Base,
|
||||
State->SegmentRegs[FAST486_REG_DS].Limit,
|
||||
State->SegmentRegs[FAST486_REG_DS].Dpl,
|
||||
State->SegmentRegs[FAST486_REG_FS].Selector,
|
||||
State->SegmentRegs[FAST486_REG_FS].Base,
|
||||
State->SegmentRegs[FAST486_REG_FS].Limit,
|
||||
State->SegmentRegs[FAST486_REG_FS].Dpl,
|
||||
State->SegmentRegs[FAST486_REG_GS].Selector,
|
||||
State->SegmentRegs[FAST486_REG_GS].Base,
|
||||
State->SegmentRegs[FAST486_REG_GS].Limit,
|
||||
State->SegmentRegs[FAST486_REG_GS].Dpl);
|
||||
DPRINT1("\nFlags: %08X (%s %s %s %s %s %s %s %s %s %s %s %s) Iopl: %u\n",
|
||||
State->Flags.Long,
|
||||
State->Flags.Cf ? "CF" : "cf",
|
||||
State->Flags.Pf ? "PF" : "pf",
|
||||
State->Flags.Af ? "AF" : "af",
|
||||
State->Flags.Zf ? "ZF" : "zf",
|
||||
State->Flags.Sf ? "SF" : "sf",
|
||||
State->Flags.Tf ? "TF" : "tf",
|
||||
State->Flags.If ? "IF" : "if",
|
||||
State->Flags.Df ? "DF" : "df",
|
||||
State->Flags.Of ? "OF" : "of",
|
||||
State->Flags.Nt ? "NT" : "nt",
|
||||
State->Flags.Rf ? "RF" : "rf",
|
||||
State->Flags.Vm ? "VM" : "vm",
|
||||
State->Flags.Iopl);
|
||||
DPRINT1("\nControl Registers:\n"
|
||||
"CR0 = %08X\tCR2 = %08X\tCR3 = %08X\n",
|
||||
State->ControlRegisters[FAST486_REG_CR0],
|
||||
State->ControlRegisters[FAST486_REG_CR2],
|
||||
State->ControlRegisters[FAST486_REG_CR3]);
|
||||
DPRINT1("\nDebug Registers:\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]);
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
Fast486Continue(PFAST486_STATE State)
|
||||
{
|
||||
/* Call the internal function */
|
||||
Fast486ExecutionControl(State, FAST486_CONTINUE);
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
Fast486StepInto(PFAST486_STATE State)
|
||||
{
|
||||
/* Call the internal function */
|
||||
Fast486ExecutionControl(State, FAST486_STEP_INTO);
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
Fast486StepOver(PFAST486_STATE State)
|
||||
{
|
||||
/* Call the internal function */
|
||||
Fast486ExecutionControl(State, FAST486_STEP_OVER);
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
Fast486StepOut(PFAST486_STATE State)
|
||||
{
|
||||
/* Call the internal function */
|
||||
Fast486ExecutionControl(State, FAST486_STEP_OUT);
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
Fast486Interrupt(PFAST486_STATE State, UCHAR Number)
|
||||
{
|
||||
/* Set the interrupt status and the number */
|
||||
State->IntStatus = FAST486_INT_EXECUTE;
|
||||
State->PendingIntNum = Number;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
Fast486InterruptSignal(PFAST486_STATE State)
|
||||
{
|
||||
/* Set the interrupt status */
|
||||
State->IntStatus = FAST486_INT_SIGNAL;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
Fast486ExecuteAt(PFAST486_STATE State, USHORT Segment, ULONG Offset)
|
||||
{
|
||||
/* Load the new CS */
|
||||
if (!Fast486LoadSegment(State, FAST486_REG_CS, Segment))
|
||||
{
|
||||
/* An exception occurred, let the handler execute instead */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set the new IP */
|
||||
State->InstPtr.Long = Offset;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
Fast486SetStack(PFAST486_STATE State, USHORT Segment, ULONG Offset)
|
||||
{
|
||||
/* Load the new SS */
|
||||
if (!Fast486LoadSegment(State, FAST486_REG_SS, Segment))
|
||||
{
|
||||
/* An exception occurred, let the handler execute instead */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set the new SP */
|
||||
State->GeneralRegs[FAST486_REG_ESP].Long = Offset;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
Fast486SetSegment(PFAST486_STATE State,
|
||||
FAST486_SEG_REGS Segment,
|
||||
USHORT Selector)
|
||||
{
|
||||
/* Call the internal function */
|
||||
Fast486LoadSegment(State, Segment, Selector);
|
||||
}
|
||||
|
||||
/* EOF */
|
236
lib/fast486/fpu.c
Normal file
236
lib/fast486/fpu.c
Normal file
|
@ -0,0 +1,236 @@
|
|||
/*
|
||||
* Fast486 386/486 CPU Emulation Library
|
||||
* fpu.c
|
||||
*
|
||||
* Copyright (C) 2013 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/* INCLUDES *******************************************************************/
|
||||
|
||||
#include <windef.h>
|
||||
|
||||
// #define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
#include <fast486.h>
|
||||
#include "common.h"
|
||||
#include "opcodes.h"
|
||||
#include "fpu.h"
|
||||
|
||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||
|
||||
FAST486_OPCODE_HANDLER(Fast486FpuOpcodeD8)
|
||||
{
|
||||
FAST486_MOD_REG_RM ModRegRm;
|
||||
BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
|
||||
|
||||
/* Get the operands */
|
||||
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
FPU_CHECK();
|
||||
|
||||
#ifndef FAST486_NO_FPU
|
||||
// TODO: NOT IMPLEMENTED
|
||||
UNIMPLEMENTED;
|
||||
|
||||
return FALSE;
|
||||
#else
|
||||
/* Do nothing */
|
||||
return TRUE;
|
||||
#endif
|
||||
}
|
||||
|
||||
FAST486_OPCODE_HANDLER(Fast486FpuOpcodeD9)
|
||||
{
|
||||
FAST486_MOD_REG_RM ModRegRm;
|
||||
BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
|
||||
|
||||
/* Get the operands */
|
||||
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
FPU_CHECK();
|
||||
|
||||
#ifndef FAST486_NO_FPU
|
||||
// TODO: NOT IMPLEMENTED
|
||||
UNIMPLEMENTED;
|
||||
|
||||
return FALSE;
|
||||
#else
|
||||
/* Do nothing */
|
||||
return TRUE;
|
||||
#endif
|
||||
}
|
||||
|
||||
FAST486_OPCODE_HANDLER(Fast486FpuOpcodeDA)
|
||||
{
|
||||
FAST486_MOD_REG_RM ModRegRm;
|
||||
BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
|
||||
|
||||
/* Get the operands */
|
||||
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
FPU_CHECK();
|
||||
|
||||
#ifndef FAST486_NO_FPU
|
||||
// TODO: NOT IMPLEMENTED
|
||||
UNIMPLEMENTED;
|
||||
|
||||
return FALSE;
|
||||
#else
|
||||
/* Do nothing */
|
||||
return TRUE;
|
||||
#endif
|
||||
}
|
||||
|
||||
FAST486_OPCODE_HANDLER(Fast486FpuOpcodeDB)
|
||||
{
|
||||
FAST486_MOD_REG_RM ModRegRm;
|
||||
BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
|
||||
|
||||
/* Get the operands */
|
||||
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
FPU_CHECK();
|
||||
|
||||
#ifndef FAST486_NO_FPU
|
||||
// TODO: NOT IMPLEMENTED
|
||||
UNIMPLEMENTED;
|
||||
|
||||
return FALSE;
|
||||
#else
|
||||
/* Do nothing */
|
||||
return TRUE;
|
||||
#endif
|
||||
}
|
||||
|
||||
FAST486_OPCODE_HANDLER(Fast486FpuOpcodeDC)
|
||||
{
|
||||
FAST486_MOD_REG_RM ModRegRm;
|
||||
BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
|
||||
|
||||
/* Get the operands */
|
||||
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
FPU_CHECK();
|
||||
|
||||
#ifndef FAST486_NO_FPU
|
||||
// TODO: NOT IMPLEMENTED
|
||||
UNIMPLEMENTED;
|
||||
|
||||
return FALSE;
|
||||
#else
|
||||
/* Do nothing */
|
||||
return TRUE;
|
||||
#endif
|
||||
}
|
||||
|
||||
FAST486_OPCODE_HANDLER(Fast486FpuOpcodeDD)
|
||||
{
|
||||
FAST486_MOD_REG_RM ModRegRm;
|
||||
BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
|
||||
|
||||
/* Get the operands */
|
||||
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
FPU_CHECK();
|
||||
|
||||
#ifndef FAST486_NO_FPU
|
||||
// TODO: NOT IMPLEMENTED
|
||||
UNIMPLEMENTED;
|
||||
|
||||
return FALSE;
|
||||
#else
|
||||
/* Do nothing */
|
||||
return TRUE;
|
||||
#endif
|
||||
}
|
||||
|
||||
FAST486_OPCODE_HANDLER(Fast486FpuOpcodeDE)
|
||||
{
|
||||
FAST486_MOD_REG_RM ModRegRm;
|
||||
BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
|
||||
|
||||
/* Get the operands */
|
||||
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
FPU_CHECK();
|
||||
|
||||
#ifndef FAST486_NO_FPU
|
||||
// TODO: NOT IMPLEMENTED
|
||||
UNIMPLEMENTED;
|
||||
|
||||
return FALSE;
|
||||
#else
|
||||
/* Do nothing */
|
||||
return TRUE;
|
||||
#endif
|
||||
}
|
||||
|
||||
FAST486_OPCODE_HANDLER(Fast486FpuOpcodeDF)
|
||||
{
|
||||
FAST486_MOD_REG_RM ModRegRm;
|
||||
BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
|
||||
|
||||
/* Get the operands */
|
||||
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
FPU_CHECK();
|
||||
|
||||
#ifndef FAST486_NO_FPU
|
||||
// TODO: NOT IMPLEMENTED
|
||||
UNIMPLEMENTED;
|
||||
|
||||
return FALSE;
|
||||
#else
|
||||
/* Do nothing */
|
||||
return TRUE;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* EOF */
|
62
lib/fast486/fpu.h
Normal file
62
lib/fast486/fpu.h
Normal file
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Fast486 386/486 CPU Emulation Library
|
||||
* fpu.h
|
||||
*
|
||||
* Copyright (C) 2013 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef _FPU_H_
|
||||
#define _FPU_H_
|
||||
|
||||
#pragma once
|
||||
|
||||
/* DEFINES ********************************************************************/
|
||||
|
||||
#define FPU_CHECK() if (State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_EM) \
|
||||
{ \
|
||||
Fast486Exception(State, FAST486_EXCEPTION_NM); \
|
||||
return FALSE; \
|
||||
}
|
||||
#define FPU_ST(i) State->FpuRegisters[(State->FpuStatus.Top + (i)) % FAST486_NUM_FPU_REGS]
|
||||
|
||||
enum
|
||||
{
|
||||
FPU_SINGLE_PRECISION = 0,
|
||||
FPU_DOUBLE_PRECISION = 2,
|
||||
FPU_DOUBLE_EXT_PRECISION = 3
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
FPU_TAG_VALID = 0,
|
||||
FPU_TAG_ZERO = 1,
|
||||
FPU_TAG_SPECIAL = 2,
|
||||
FPU_TAG_EMPTY = 3
|
||||
};
|
||||
|
||||
FAST486_OPCODE_HANDLER(Fast486FpuOpcodeD8);
|
||||
FAST486_OPCODE_HANDLER(Fast486FpuOpcodeD9);
|
||||
FAST486_OPCODE_HANDLER(Fast486FpuOpcodeDA);
|
||||
FAST486_OPCODE_HANDLER(Fast486FpuOpcodeDB);
|
||||
FAST486_OPCODE_HANDLER(Fast486FpuOpcodeDC);
|
||||
FAST486_OPCODE_HANDLER(Fast486FpuOpcodeDD);
|
||||
FAST486_OPCODE_HANDLER(Fast486FpuOpcodeDE);
|
||||
FAST486_OPCODE_HANDLER(Fast486FpuOpcodeDF);
|
||||
|
||||
#endif // _FPU_H_
|
||||
|
||||
/* EOF */
|
6312
lib/fast486/opcodes.c
Normal file
6312
lib/fast486/opcodes.c
Normal file
File diff suppressed because it is too large
Load diff
157
lib/fast486/opcodes.h
Normal file
157
lib/fast486/opcodes.h
Normal file
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
* Fast486 386/486 CPU Emulation Library
|
||||
* opcodes.h
|
||||
*
|
||||
* Copyright (C) 2013 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef _OPCODES_H_
|
||||
#define _OPCODES_H_
|
||||
|
||||
#pragma once
|
||||
|
||||
/* DEFINES ********************************************************************/
|
||||
|
||||
#define FAST486_NUM_OPCODE_HANDLERS 256
|
||||
#define FAST486_OPCODE_WRITE_REG (1 << 1)
|
||||
#define FAST486_OPCODE_HANDLER(x) \
|
||||
BOOLEAN FASTCALL x(PFAST486_STATE State, UCHAR Opcode)
|
||||
|
||||
typedef BOOLEAN (FASTCALL *FAST486_OPCODE_HANDLER_PROC)(PFAST486_STATE, UCHAR);
|
||||
|
||||
extern
|
||||
FAST486_OPCODE_HANDLER_PROC
|
||||
Fast486OpcodeHandlers[FAST486_NUM_OPCODE_HANDLERS];
|
||||
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodePrefix);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeIncrement);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeDecrement);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodePushReg);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodePopReg);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeNop);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeExchangeEax);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeShortConditionalJmp);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeClearCarry);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeSetCarry);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeComplCarry);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeClearInt);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeSetInt);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeClearDir);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeSetDir);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeHalt);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeInByte);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeIn);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeOutByte);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeOut);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeShortJump);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeMovRegImm);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeMovByteRegImm);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeAddByteModrm);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeAddModrm);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeAddAl);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeAddEax);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeOrByteModrm);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeOrModrm);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeOrAl);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeOrEax);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeAndByteModrm);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeAndModrm);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeAndAl);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeAndEax);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeXorByteModrm);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeXorModrm);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeXorAl);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeXorEax);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeTestByteModrm);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeTestModrm);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeTestAl);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeTestEax);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeXchgByteModrm);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeXchgModrm);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodePushEs);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodePopEs);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodePushCs);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeAdcByteModrm);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeAdcModrm);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeAdcAl);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeAdcEax);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodePushSs);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodePopSs);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeSbbByteModrm);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeSbbModrm);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeSbbAl);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeSbbEax);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodePushDs);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodePopDs);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeDaa);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeCmpSubByteModrm);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeCmpSubModrm);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeCmpSubAl);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeCmpSubEax);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeDas);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeAaa);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeAas);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodePushAll);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodePopAll);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeBound);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeArpl);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodePushImm);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeImulModrmImm);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodePushByteImm);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeMovByteModrm);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeMovModrm);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeMovStoreSeg);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeLea);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeMovLoadSeg);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeCwde);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeCdq);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeCallAbs);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeWait);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodePushFlags);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodePopFlags);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeSahf);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeLahf);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeRet);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeLdsLes);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeEnter);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeLeave);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeRetFarImm);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeRetFar);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeInt);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeIret);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeAam);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeAad);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeXlat);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeLoop);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeJecxz);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeCall);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeJmp);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeJmpAbs);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeMovAlOffset);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeMovEaxOffset);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeMovOffsetAl);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeMovOffsetEax);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeSalc);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeMovs);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeCmps);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeStos);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeLods);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeScas);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeIns);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeOuts);
|
||||
|
||||
#endif // _OPCODES_H_
|
2370
lib/fast486/opgroups.c
Normal file
2370
lib/fast486/opgroups.c
Normal file
File diff suppressed because it is too large
Load diff
53
lib/fast486/opgroups.h
Normal file
53
lib/fast486/opgroups.h
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Fast486 386/486 CPU Emulation Library
|
||||
* opgroups.h
|
||||
*
|
||||
* Copyright (C) 2013 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef _OPGROUPS_H_
|
||||
#define _OPGROUPS_H_
|
||||
|
||||
#pragma once
|
||||
|
||||
/* DEFINES ********************************************************************/
|
||||
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeGroup8082);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeGroup81);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeGroup83);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeGroup8F);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeGroupC0);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeGroupC1);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeGroupC6);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeGroupC7);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeGroupD0);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeGroupD1);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeGroupD2);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeGroupD3);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeGroupF6);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeGroupF7);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeGroupFE);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeGroupFF);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeGroup0F00);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeGroup0F01);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeGroup0FB9);
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeGroup0FBA);
|
||||
|
||||
#endif // _OPGROUPS_H_
|
||||
|
||||
/* EOF */
|
||||
|
2440
lib/rtl/actctx.c
2440
lib/rtl/actctx.c
File diff suppressed because it is too large
Load diff
|
@ -39,7 +39,8 @@ struct __thread_data {
|
|||
struct tm *time_buffer; /* buffer for localtime/gmtime */
|
||||
char *efcvt_buffer; /* buffer for ecvt/fcvt */
|
||||
int unk3[2];
|
||||
void *unk4[4];
|
||||
void *unk4[3];
|
||||
EXCEPTION_POINTERS *xcptinfo;
|
||||
int fpecode;
|
||||
struct MSVCRT_threadmbcinfostruct *mbcinfo;
|
||||
struct MSVCRT_threadlocaleinfostruct *locinfo;
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#include <stdlib.h>
|
||||
#include <precomp.h>
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
* @implemented
|
||||
*/
|
||||
void **__pxcptinfoptrs (void)
|
||||
void** __pxcptinfoptrs(void)
|
||||
{
|
||||
return NULL;
|
||||
return (void**)&msvcrt_get_thread_data()->xcptinfo;
|
||||
}
|
||||
|
|
|
@ -258,7 +258,7 @@ gdi32 -
|
|||
reactos/dll/win32/gdi32/objects/linedda.c # Synced at 20090410
|
||||
|
||||
kernel32 -
|
||||
reactos/dll/win32/kernel32/wine/actctx.c # Partly synced
|
||||
reactos/dll/win32/kernel32/wine/actctx.c # Partly synced with Wine 1.7.17
|
||||
reactos/dll/win32/kernel32/wine/comm.c # Synced in r52754
|
||||
reactos/dll/win32/kernel32/wine/lzexpand.c # Synced in r52754
|
||||
reactos/dll/win32/kernel32/wine/profile.c # Synced in r52754
|
||||
|
@ -275,6 +275,7 @@ kernel32 -
|
|||
msvcrt -
|
||||
reactos/lib/sdk/crt/except/cpp.c # Synced at 20080528
|
||||
reactos/lib/sdk/crt/except/cppexcept.c # Synced at 20071111
|
||||
reactos/lib/sdk/crt/signal/xcptinfo.c # Synced to Wine-1.7.17
|
||||
reactos/lib/sdk/crt/string/scanf.c/h # Synced to Wine-1_1_27
|
||||
reactos/lib/sdk/crt/strings/wcs.c # Synced at 20080611
|
||||
reactos/lib/sdk/crt/wine/heap.c # Synced at 20080529
|
||||
|
|
|
@ -180,6 +180,11 @@ KiExitTrapDebugChecks(IN PKTRAP_FRAME TrapFrame,
|
|||
StopChecking = FALSE;
|
||||
}
|
||||
|
||||
#else
|
||||
#define KiExitTrapDebugChecks(x, y)
|
||||
#define KiFillTrapFrameDebug(x)
|
||||
#endif
|
||||
|
||||
FORCEINLINE
|
||||
VOID
|
||||
KiExitSystemCallDebugChecks(IN ULONG SystemCall,
|
||||
|
@ -219,11 +224,6 @@ KiExitSystemCallDebugChecks(IN ULONG SystemCall,
|
|||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define KiExitTrapDebugChecks(x, y)
|
||||
#define KiFillTrapFrameDebug(x)
|
||||
#define KiExitSystemCallDebugChecks(x, y)
|
||||
#endif
|
||||
|
||||
//
|
||||
// Generic Exit Routine
|
||||
|
|
|
@ -280,7 +280,14 @@ l_ReadHeaderFromFile:
|
|||
nStatus = ReadFileCb(File, &lnOffset, sizeof(IMAGE_NT_HEADERS64), &pData, &pBuffer, &cbReadSize);
|
||||
|
||||
if(!NT_SUCCESS(nStatus))
|
||||
DIE(("ReadFile failed, status %08X\n", nStatus));
|
||||
{
|
||||
NTSTATUS ReturnedStatus = nStatus;
|
||||
|
||||
/* If it attempted to read past the end of the file, it means e_lfanew is invalid */
|
||||
if (ReturnedStatus == STATUS_END_OF_FILE) nStatus = STATUS_ROS_EXEFMT_UNKNOWN_FORMAT;
|
||||
|
||||
DIE(("ReadFile failed, status %08X\n", ReturnedStatus));
|
||||
}
|
||||
|
||||
ASSERT(pData);
|
||||
ASSERT(pBuffer);
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
|
||||
if(ARCH STREQUAL "i386")
|
||||
add_subdirectory(ntvdm)
|
||||
endif()
|
||||
add_subdirectory(ntvdm)
|
||||
add_subdirectory(win)
|
||||
add_subdirectory(win32)
|
||||
|
|
|
@ -1,11 +1,42 @@
|
|||
|
||||
include_directories(.)
|
||||
include_directories(
|
||||
${REACTOS_SOURCE_DIR}/include/reactos/libs/fast486
|
||||
ntvdm)
|
||||
|
||||
add_executable(ntvdm
|
||||
spec2def(ntvdm.exe ntvdm.spec)
|
||||
|
||||
list(APPEND SOURCE
|
||||
bios/bios32/bios32.c
|
||||
bios/bios32/kbdbios32.c
|
||||
bios/bios32/vidbios32.c
|
||||
bios/bios.c
|
||||
bios/kbdbios.c
|
||||
bios/rom.c
|
||||
bios/vidbios.c
|
||||
hardware/cmos.c
|
||||
hardware/pic.c
|
||||
hardware/ps2.c
|
||||
hardware/speaker.c
|
||||
hardware/timer.c
|
||||
hardware/vga.c
|
||||
dos/dos32krnl/bios.c
|
||||
dos/dos32krnl/dos.c
|
||||
dos/dem.c
|
||||
bop.c
|
||||
callback.c
|
||||
clock.c
|
||||
emulator.c
|
||||
io.c
|
||||
registers.c
|
||||
utils.c
|
||||
vddsup.c
|
||||
ntvdm.c
|
||||
ntvdm.rc)
|
||||
ntvdm.rc
|
||||
${CMAKE_CURRENT_BINARY_DIR}/ntvdm.def)
|
||||
|
||||
set_module_type(ntvdm win32cui)
|
||||
add_importlibs(ntvdm ntdll user32 gdi32 advapi32 msvcrt kernel32)
|
||||
add_dependencies(ntvdm ndk bugcodes)
|
||||
add_executable(ntvdm ${SOURCE})
|
||||
set_module_type(ntvdm win32cui UNICODE)
|
||||
set_image_base(ntvdm 0x0F000000)
|
||||
target_link_libraries(ntvdm fast486)
|
||||
add_importlibs(ntvdm user32 gdi32 advapi32 msvcrt kernel32 ntdll)
|
||||
add_cd_file(TARGET ntvdm DESTINATION reactos/system32 FOR all)
|
||||
|
|
211
subsystems/ntvdm/bios/bios.c
Normal file
211
subsystems/ntvdm/bios/bios.c
Normal file
|
@ -0,0 +1,211 @@
|
|||
/*
|
||||
* COPYRIGHT: GPL - See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Virtual DOS Machine
|
||||
* FILE: bios.c
|
||||
* PURPOSE: VDM BIOS Support Library
|
||||
* PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr)
|
||||
*/
|
||||
|
||||
/* INCLUDES *******************************************************************/
|
||||
|
||||
#define NDEBUG
|
||||
|
||||
#include "emulator.h"
|
||||
#include "callback.h"
|
||||
#include "bop.h"
|
||||
|
||||
#include "bios.h"
|
||||
#include "bios32/bios32.h"
|
||||
|
||||
#include "rom.h"
|
||||
|
||||
#include "io.h"
|
||||
#include "hardware/cmos.h"
|
||||
|
||||
/* DEFINES ********************************************************************/
|
||||
|
||||
/* BOP Identifiers */
|
||||
#define BOP_BIOSINIT 0x00 // Windows NTVDM (SoftPC) BIOS calls BOP 0x00
|
||||
// to let the virtual machine initialize itself
|
||||
// the IVT and its hardware.
|
||||
#define BOP_EQUIPLIST 0x11
|
||||
#define BOP_GETMEMSIZE 0x12
|
||||
|
||||
/* PRIVATE VARIABLES **********************************************************/
|
||||
|
||||
static BOOLEAN Bios32Loaded = FALSE;
|
||||
|
||||
static CALLBACK16 __BiosContext;
|
||||
PBIOS_DATA_AREA Bda;
|
||||
|
||||
/* PRIVATE FUNCTIONS **********************************************************/
|
||||
|
||||
static VOID WINAPI BiosInitBop(LPWORD Stack)
|
||||
{
|
||||
BOOLEAN Success;
|
||||
|
||||
/* Load the second part of the Windows NTVDM BIOS image */
|
||||
LPCSTR BiosFileName = "bios1.rom";
|
||||
PVOID BiosLocation = (PVOID)TO_LINEAR(BIOS_SEGMENT, 0x0000);
|
||||
DWORD BiosSize = 0;
|
||||
|
||||
/* Disable interrupts */
|
||||
setIF(0);
|
||||
|
||||
DisplayMessage(L"You are loading Windows NTVDM BIOS!\n");
|
||||
|
||||
/* Initialize a private callback context */
|
||||
InitializeContext(&__BiosContext, BIOS_SEGMENT, 0x0000);
|
||||
|
||||
Success = LoadRom(BiosFileName, BiosLocation, &BiosSize);
|
||||
DPRINT1("BIOS loading %s ; GetLastError() = %u\n", Success ? "succeeded" : "failed", GetLastError());
|
||||
|
||||
if (Success == FALSE)
|
||||
{
|
||||
/* Stop the VDM */
|
||||
EmulatorTerminate();
|
||||
return;
|
||||
}
|
||||
|
||||
// DisplayMessage(L"First bytes at 0x%p: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n"
|
||||
// L"3 last bytes at 0x%p: 0x%02x 0x%02x 0x%02x",
|
||||
// BiosLocation,
|
||||
// *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 0),
|
||||
// *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 1),
|
||||
// *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 2),
|
||||
// *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 3),
|
||||
// *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 4),
|
||||
// *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 5),
|
||||
// *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 6),
|
||||
// *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 7),
|
||||
// *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 8),
|
||||
// *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 9),
|
||||
|
||||
// (PVOID)((ULONG_PTR)BiosLocation + BiosSize - 2),
|
||||
// *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + BiosSize - 2),
|
||||
// *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + BiosSize - 1),
|
||||
// *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + BiosSize - 0));
|
||||
|
||||
/* Initialize IVT and hardware */
|
||||
|
||||
/* Initialize the Keyboard and Video BIOS */
|
||||
if (!KbdBiosInitialize() || !VidBiosInitialize())
|
||||
{
|
||||
/* Stop the VDM */
|
||||
EmulatorTerminate();
|
||||
return;
|
||||
}
|
||||
|
||||
/* Load VGA BIOS */
|
||||
// Success = LoadRom("v7vga.rom", (PVOID)0xC0000, &BiosSize);
|
||||
// DPRINT1("VGA BIOS loading %s ; GetLastError() = %u\n", Success ? "succeeded" : "failed", GetLastError());
|
||||
|
||||
/* Enable interrupts */
|
||||
setIF(1);
|
||||
|
||||
///////////// MUST BE DONE AFTER IVT INITIALIZATION !! /////////////////////
|
||||
|
||||
/* Load some ROMs */
|
||||
// Success = LoadRom("boot.bin", (PVOID)0xE0000, &BiosSize);
|
||||
// DPRINT1("Test ROM loading %s ; GetLastError() = %u\n", Success ? "succeeded" : "failed", GetLastError());
|
||||
|
||||
SearchAndInitRoms(&__BiosContext);
|
||||
}
|
||||
|
||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||
|
||||
VOID WINAPI BiosEquipmentService(LPWORD Stack)
|
||||
{
|
||||
/* Return the equipment list */
|
||||
setAX(Bda->EquipmentList);
|
||||
}
|
||||
|
||||
VOID WINAPI BiosGetMemorySize(LPWORD Stack)
|
||||
{
|
||||
/* Return the conventional memory size in kB, typically 640 kB */
|
||||
setAX(Bda->MemorySize);
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
BiosInitialize(IN LPCSTR BiosFileName)
|
||||
{
|
||||
BOOLEAN Success = FALSE;
|
||||
|
||||
/* Disable interrupts */
|
||||
setIF(0);
|
||||
|
||||
/* Initialize the BDA pointer */
|
||||
Bda = (PBIOS_DATA_AREA)SEG_OFF_TO_PTR(BDA_SEGMENT, 0);
|
||||
|
||||
/* Register the BIOS support BOPs */
|
||||
RegisterBop(BOP_BIOSINIT , BiosInitBop);
|
||||
RegisterBop(BOP_EQUIPLIST , BiosEquipmentService);
|
||||
RegisterBop(BOP_GETMEMSIZE, BiosGetMemorySize);
|
||||
|
||||
if (BiosFileName)
|
||||
{
|
||||
PVOID BiosLocation = NULL;
|
||||
DWORD BiosSize = 0;
|
||||
|
||||
Success = LoadBios(BiosFileName, &BiosLocation, &BiosSize);
|
||||
DPRINT1("BIOS loading %s ; GetLastError() = %u\n", Success ? "succeeded" : "failed", GetLastError());
|
||||
|
||||
if (!Success) return FALSE;
|
||||
|
||||
DisplayMessage(L"First bytes at 0x%p: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n"
|
||||
L"3 last bytes at 0x%p: 0x%02x 0x%02x 0x%02x",
|
||||
BiosLocation,
|
||||
*(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 0),
|
||||
*(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 1),
|
||||
*(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 2),
|
||||
*(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 3),
|
||||
*(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 4),
|
||||
*(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 5),
|
||||
*(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 6),
|
||||
*(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 7),
|
||||
*(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 8),
|
||||
*(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 9),
|
||||
|
||||
(PVOID)((ULONG_PTR)BiosLocation + BiosSize - 2),
|
||||
*(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + BiosSize - 2),
|
||||
*(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + BiosSize - 1),
|
||||
*(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + BiosSize - 0));
|
||||
|
||||
DisplayMessage(L"POST at 0x%p: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x",
|
||||
TO_LINEAR(getCS(), getIP()),
|
||||
*(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(getCS(), getIP()) + 0),
|
||||
*(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(getCS(), getIP()) + 1),
|
||||
*(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(getCS(), getIP()) + 2),
|
||||
*(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(getCS(), getIP()) + 3),
|
||||
*(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(getCS(), getIP()) + 4));
|
||||
|
||||
/* Boot it up */
|
||||
|
||||
/*
|
||||
* The CPU is already in reset-mode so that
|
||||
* CS:IP points to F000:FFF0 as required.
|
||||
*/
|
||||
DisplayMessage(L"CS=0x%p ; IP=0x%p", getCS(), getIP());
|
||||
// setCS(0xF000);
|
||||
// setIP(0xFFF0);
|
||||
|
||||
Success = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
Success = Bios32Loaded = Bios32Initialize();
|
||||
}
|
||||
|
||||
/* Enable interrupts */
|
||||
setIF(1);
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
VOID
|
||||
BiosCleanup(VOID)
|
||||
{
|
||||
if (Bios32Loaded) Bios32Cleanup();
|
||||
}
|
||||
|
||||
/* EOF */
|
118
subsystems/ntvdm/bios/bios.h
Normal file
118
subsystems/ntvdm/bios/bios.h
Normal file
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* COPYRIGHT: GPL - See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Virtual DOS Machine
|
||||
* FILE: bios.h
|
||||
* PURPOSE: VDM BIOS Support Library
|
||||
* PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr)
|
||||
*/
|
||||
|
||||
#ifndef _BIOS_H_
|
||||
#define _BIOS_H_
|
||||
|
||||
/* INCLUDES *******************************************************************/
|
||||
|
||||
#include "ntvdm.h"
|
||||
#include "kbdbios.h"
|
||||
#include "vidbios.h"
|
||||
|
||||
/* DEFINES ********************************************************************/
|
||||
|
||||
#define BDA_SEGMENT 0x40
|
||||
#define BIOS_SEGMENT 0xF000
|
||||
|
||||
#define BIOS_EQUIPMENT_LIST 0x2C // HACK: Disable FPU for now
|
||||
|
||||
/*
|
||||
* BIOS Data Area at 0040:XXXX
|
||||
*
|
||||
* See: http://webpages.charter.net/danrollins/techhelp/0093.HTM
|
||||
* and: http://www.bioscentral.com/misc/bda.htm
|
||||
* for more information.
|
||||
*/
|
||||
#pragma pack(push, 1)
|
||||
typedef struct
|
||||
{
|
||||
WORD SerialPorts[4]; // 0x00
|
||||
WORD ParallelPorts[3]; // 0x08
|
||||
WORD EbdaSegment; // 0x0e - ParallelPort in PC/XT
|
||||
WORD EquipmentList; // 0x10
|
||||
BYTE Reserved0; // 0x12 - Errors in PCjr infrared keyboard link
|
||||
WORD MemorySize; // 0x13
|
||||
WORD Reserved1; // 0x15 - Scratch pad for manufacturing error tests
|
||||
WORD KeybdShiftFlags; // 0x17
|
||||
BYTE AlternateKeypad; // 0x19
|
||||
WORD KeybdBufferHead; // 0x1a
|
||||
WORD KeybdBufferTail; // 0x1c
|
||||
WORD KeybdBuffer[BIOS_KBD_BUFFER_SIZE]; // 0x1e
|
||||
BYTE DriveRecalibrate; // 0x3e
|
||||
BYTE DriveMotorStatus; // 0x3f
|
||||
BYTE MotorShutdownCounter; // 0x40
|
||||
BYTE LastDisketteOperation; // 0x41
|
||||
BYTE Reserved2[7]; // 0x42
|
||||
BYTE VideoMode; // 0x49
|
||||
WORD ScreenColumns; // 0x4a
|
||||
WORD VideoPageSize; // 0x4c
|
||||
WORD VideoPageOffset; // 0x4e
|
||||
WORD CursorPosition[BIOS_MAX_PAGES]; // 0x50
|
||||
BYTE CursorEndLine; // 0x60
|
||||
BYTE CursorStartLine; // 0x61
|
||||
BYTE VideoPage; // 0x62
|
||||
WORD CrtBasePort; // 0x63
|
||||
BYTE CrtModeControl; // 0x65
|
||||
BYTE CrtColorPaletteMask; // 0x66
|
||||
BYTE CassetteData[5]; // 0x67
|
||||
DWORD TickCounter; // 0x6c
|
||||
BYTE MidnightPassed; // 0x70
|
||||
BYTE BreakFlag; // 0x71
|
||||
WORD SoftReset; // 0x72
|
||||
BYTE LastDiskOperation; // 0x74
|
||||
BYTE NumDisks; // 0x75
|
||||
BYTE DriveControlByte; // 0x76
|
||||
BYTE DiskPortOffset; // 0x77
|
||||
BYTE LptTimeOut[4]; // 0x78
|
||||
BYTE ComTimeOut[4]; // 0x7c
|
||||
WORD KeybdBufferStart; // 0x80
|
||||
WORD KeybdBufferEnd; // 0x82
|
||||
BYTE ScreenRows; // 0x84
|
||||
WORD CharacterHeight; // 0x85
|
||||
BYTE EGAFlags[2]; // 0x87
|
||||
BYTE VGAFlags[2]; // 0x89
|
||||
DWORD Reserved3; // 0x8b
|
||||
BYTE Reserved4; // 0x8f
|
||||
BYTE Reserved5[2]; // 0x90
|
||||
BYTE Reserved6[2]; // 0x92
|
||||
BYTE Reserved7[2]; // 0x94
|
||||
WORD Reserved8; // 0x96
|
||||
DWORD Reserved9; // 0x98
|
||||
DWORD Reserved10; // 0x9c
|
||||
DWORD Reserved11[2]; // 0xa0
|
||||
DWORD EGAPtr; // 0xa8
|
||||
BYTE Reserved12[68]; // 0xac
|
||||
BYTE Reserved13[16]; // 0xf0
|
||||
|
||||
DWORD Reserved14; // 0x100
|
||||
BYTE Reserved15[12]; // 0x104
|
||||
BYTE Reserved16[17]; // 0x110
|
||||
BYTE Reserved17[15]; // 0x121
|
||||
BYTE Reserved18[3]; // 0x130
|
||||
} BIOS_DATA_AREA, *PBIOS_DATA_AREA;
|
||||
#pragma pack(pop)
|
||||
|
||||
C_ASSERT(sizeof(BIOS_DATA_AREA) == 0x133);
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
extern PBIOS_DATA_AREA Bda;
|
||||
|
||||
VOID WINAPI BiosEquipmentService(LPWORD Stack);
|
||||
VOID WINAPI BiosGetMemorySize(LPWORD Stack);
|
||||
|
||||
BOOLEAN
|
||||
BiosInitialize(IN LPCSTR BiosFileName);
|
||||
|
||||
VOID
|
||||
BiosCleanup(VOID);
|
||||
|
||||
#endif // _BIOS_H_
|
||||
|
||||
/* EOF */
|
403
subsystems/ntvdm/bios/bios32/bios32.c
Normal file
403
subsystems/ntvdm/bios/bios32/bios32.c
Normal file
|
@ -0,0 +1,403 @@
|
|||
/*
|
||||
* COPYRIGHT: GPL - See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Virtual DOS Machine
|
||||
* FILE: bios32.c
|
||||
* PURPOSE: VDM 32-bit BIOS
|
||||
* PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||
*/
|
||||
|
||||
/* INCLUDES *******************************************************************/
|
||||
|
||||
#define NDEBUG
|
||||
|
||||
#include "emulator.h"
|
||||
#include "callback.h"
|
||||
#include "bop.h"
|
||||
|
||||
#include "../bios.h"
|
||||
#include "../rom.h"
|
||||
#include "bios32.h"
|
||||
#include "bios32p.h"
|
||||
#include "kbdbios32.h"
|
||||
#include "vidbios32.h"
|
||||
|
||||
#include "io.h"
|
||||
#include "hardware/cmos.h"
|
||||
#include "hardware/pic.h"
|
||||
#include "hardware/timer.h"
|
||||
|
||||
/* PRIVATE VARIABLES **********************************************************/
|
||||
|
||||
CALLBACK16 BiosContext;
|
||||
|
||||
/* PRIVATE FUNCTIONS **********************************************************/
|
||||
|
||||
static VOID WINAPI BiosException(LPWORD Stack)
|
||||
{
|
||||
/* Get the exception number and call the emulator API */
|
||||
BYTE ExceptionNumber = LOBYTE(Stack[STACK_INT_NUM]);
|
||||
EmulatorException(ExceptionNumber, Stack);
|
||||
}
|
||||
|
||||
static VOID WINAPI BiosMiscService(LPWORD Stack)
|
||||
{
|
||||
switch (getAH())
|
||||
{
|
||||
/* Wait */
|
||||
case 0x86:
|
||||
{
|
||||
/*
|
||||
* Interval in microseconds in CX:DX
|
||||
* See Ralf Brown: http://www.ctyme.com/intr/rb-1525.htm
|
||||
* for more information.
|
||||
*/
|
||||
Sleep(MAKELONG(getDX(), getCX()));
|
||||
|
||||
/* Clear CF */
|
||||
Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* Copy Extended Memory */
|
||||
case 0x87:
|
||||
{
|
||||
DWORD Count = (DWORD)getCX() * 2;
|
||||
PFAST486_GDT_ENTRY Gdt = (PFAST486_GDT_ENTRY)SEG_OFF_TO_PTR(getES(), getSI());
|
||||
DWORD SourceBase = Gdt[2].Base + (Gdt[2].BaseMid << 16) + (Gdt[2].BaseHigh << 24);
|
||||
DWORD SourceLimit = Gdt[2].Limit + (Gdt[2].LimitHigh << 16);
|
||||
DWORD DestBase = Gdt[3].Base + (Gdt[3].BaseMid << 16) + (Gdt[3].BaseHigh << 24);
|
||||
DWORD DestLimit = Gdt[3].Limit + (Gdt[3].LimitHigh << 16);
|
||||
|
||||
/* Check for flags */
|
||||
if (Gdt[2].Granularity) SourceLimit = (SourceLimit << 12) | 0xFFF;
|
||||
if (Gdt[3].Granularity) DestLimit = (DestLimit << 12) | 0xFFF;
|
||||
|
||||
if ((Count > SourceLimit) || (Count > DestLimit))
|
||||
{
|
||||
setAX(0x80);
|
||||
Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* Copy */
|
||||
RtlMoveMemory((PVOID)((ULONG_PTR)BaseAddress + DestBase),
|
||||
(PVOID)((ULONG_PTR)BaseAddress + SourceBase),
|
||||
Count);
|
||||
|
||||
setAX(ERROR_SUCCESS);
|
||||
Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Get Extended Memory Size */
|
||||
case 0x88:
|
||||
{
|
||||
UCHAR Low, High;
|
||||
|
||||
/*
|
||||
* Return the (usable) extended memory (after 1 MB)
|
||||
* size in kB from CMOS.
|
||||
*/
|
||||
IOWriteB(CMOS_ADDRESS_PORT, CMOS_REG_ACTUAL_EXT_MEMORY_LOW);
|
||||
Low = IOReadB(CMOS_DATA_PORT);
|
||||
IOWriteB(CMOS_ADDRESS_PORT, CMOS_REG_ACTUAL_EXT_MEMORY_HIGH);
|
||||
High = IOReadB(CMOS_DATA_PORT);
|
||||
setAX(MAKEWORD(Low, High));
|
||||
|
||||
/* Clear CF */
|
||||
Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
DPRINT1("BIOS Function INT 15h, AH = 0x%02X NOT IMPLEMENTED\n",
|
||||
getAH());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static VOID WINAPI BiosTimeService(LPWORD Stack)
|
||||
{
|
||||
switch (getAH())
|
||||
{
|
||||
case 0x00:
|
||||
{
|
||||
/* Set AL to 1 if midnight had passed, 0 otherwise */
|
||||
setAL(Bda->MidnightPassed ? 0x01 : 0x00);
|
||||
|
||||
/* Return the tick count in CX:DX */
|
||||
setCX(HIWORD(Bda->TickCounter));
|
||||
setDX(LOWORD(Bda->TickCounter));
|
||||
|
||||
/* Reset the midnight flag */
|
||||
Bda->MidnightPassed = FALSE;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x01:
|
||||
{
|
||||
/* Set the tick count to CX:DX */
|
||||
Bda->TickCounter = MAKELONG(getDX(), getCX());
|
||||
|
||||
/* Reset the midnight flag */
|
||||
Bda->MidnightPassed = FALSE;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
DPRINT1("BIOS Function INT 1Ah, AH = 0x%02X NOT IMPLEMENTED\n",
|
||||
getAH());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static VOID WINAPI BiosSystemTimerInterrupt(LPWORD Stack)
|
||||
{
|
||||
/* Increase the system tick count */
|
||||
Bda->TickCounter++;
|
||||
}
|
||||
|
||||
|
||||
// From SeaBIOS
|
||||
static VOID PicSetIRQMask(USHORT off, USHORT on)
|
||||
{
|
||||
UCHAR pic1off = off, pic1on = on, pic2off = off>>8, pic2on = on>>8;
|
||||
IOWriteB(PIC_MASTER_DATA, (IOReadB(PIC_MASTER_DATA) & ~pic1off) | pic1on);
|
||||
IOWriteB(PIC_SLAVE_DATA , (IOReadB(PIC_SLAVE_DATA ) & ~pic2off) | pic2on);
|
||||
}
|
||||
|
||||
// From SeaBIOS
|
||||
VOID EnableHwIRQ(UCHAR hwirq, EMULATOR_INT32_PROC func)
|
||||
{
|
||||
UCHAR vector;
|
||||
|
||||
PicSetIRQMask(1 << hwirq, 0);
|
||||
if (hwirq < 8)
|
||||
vector = BIOS_PIC_MASTER_INT + hwirq;
|
||||
else
|
||||
vector = BIOS_PIC_SLAVE_INT + hwirq - 8;
|
||||
|
||||
RegisterBiosInt32(vector, func);
|
||||
}
|
||||
|
||||
|
||||
VOID PicIRQComplete(LPWORD Stack)
|
||||
{
|
||||
/* Get the interrupt number */
|
||||
BYTE IntNum = LOBYTE(Stack[STACK_INT_NUM]);
|
||||
|
||||
/*
|
||||
* If this was a PIC IRQ, send an End-of-Interrupt to the PIC.
|
||||
*/
|
||||
|
||||
if (IntNum >= BIOS_PIC_MASTER_INT && IntNum < BIOS_PIC_MASTER_INT + 8)
|
||||
{
|
||||
/* It was an IRQ from the master PIC */
|
||||
IOWriteB(PIC_MASTER_CMD, PIC_OCW2_EOI);
|
||||
}
|
||||
else if (IntNum >= BIOS_PIC_SLAVE_INT && IntNum < BIOS_PIC_SLAVE_INT + 8)
|
||||
{
|
||||
/* It was an IRQ from the slave PIC */
|
||||
IOWriteB(PIC_SLAVE_CMD , PIC_OCW2_EOI);
|
||||
IOWriteB(PIC_MASTER_CMD, PIC_OCW2_EOI);
|
||||
}
|
||||
}
|
||||
|
||||
static VOID WINAPI BiosHandleMasterPicIRQ(LPWORD Stack)
|
||||
{
|
||||
BYTE IrqNumber;
|
||||
|
||||
IOWriteB(PIC_MASTER_CMD, PIC_OCW3_READ_ISR /* == 0x0B */);
|
||||
IrqNumber = IOReadB(PIC_MASTER_CMD);
|
||||
|
||||
DPRINT("Master - IrqNumber = 0x%x\n", IrqNumber);
|
||||
|
||||
PicIRQComplete(Stack);
|
||||
}
|
||||
|
||||
static VOID WINAPI BiosHandleSlavePicIRQ(LPWORD Stack)
|
||||
{
|
||||
BYTE IrqNumber;
|
||||
|
||||
IOWriteB(PIC_SLAVE_CMD, PIC_OCW3_READ_ISR /* == 0x0B */);
|
||||
IrqNumber = IOReadB(PIC_SLAVE_CMD);
|
||||
|
||||
DPRINT("Slave - IrqNumber = 0x%x\n", IrqNumber);
|
||||
|
||||
PicIRQComplete(Stack);
|
||||
}
|
||||
|
||||
// Timer IRQ 0
|
||||
static VOID WINAPI BiosTimerIrq(LPWORD Stack)
|
||||
{
|
||||
/*
|
||||
* Perform the system timer interrupt.
|
||||
*
|
||||
* Do not call directly BiosSystemTimerInterrupt(Stack);
|
||||
* because some programs may hook only BIOS_SYS_TIMER_INTERRUPT
|
||||
* for their purpose...
|
||||
*/
|
||||
/** EmulatorInterrupt(BIOS_SYS_TIMER_INTERRUPT); **/
|
||||
Int32Call(&BiosContext, BIOS_SYS_TIMER_INTERRUPT);
|
||||
PicIRQComplete(Stack);
|
||||
}
|
||||
|
||||
|
||||
static VOID BiosHwSetup(VOID)
|
||||
{
|
||||
/* Initialize the master and the slave PICs (cascade mode) */
|
||||
IOWriteB(PIC_MASTER_CMD, PIC_ICW1 | PIC_ICW1_ICW4);
|
||||
IOWriteB(PIC_SLAVE_CMD , PIC_ICW1 | PIC_ICW1_ICW4);
|
||||
|
||||
/*
|
||||
* Set the interrupt vector offsets for each PIC
|
||||
* (base IRQs: 0x08-0x0F for IRQ 0-7, 0x70-0x77 for IRQ 8-15)
|
||||
*/
|
||||
IOWriteB(PIC_MASTER_DATA, BIOS_PIC_MASTER_INT);
|
||||
IOWriteB(PIC_SLAVE_DATA , BIOS_PIC_SLAVE_INT );
|
||||
|
||||
/* Tell the master PIC that there is a slave PIC at IRQ 2 */
|
||||
IOWriteB(PIC_MASTER_DATA, 1 << 2);
|
||||
/* Tell the slave PIC its cascade identity */
|
||||
IOWriteB(PIC_SLAVE_DATA , 2);
|
||||
|
||||
/* Make sure both PICs are in 8086 mode */
|
||||
IOWriteB(PIC_MASTER_DATA, PIC_ICW4_8086);
|
||||
IOWriteB(PIC_SLAVE_DATA , PIC_ICW4_8086);
|
||||
|
||||
/* Clear the masks for both PICs */
|
||||
// IOWriteB(PIC_MASTER_DATA, 0x00);
|
||||
// IOWriteB(PIC_SLAVE_DATA , 0x00);
|
||||
/* Disable all IRQs */
|
||||
IOWriteB(PIC_MASTER_DATA, 0xFF);
|
||||
IOWriteB(PIC_SLAVE_DATA , 0xFF);
|
||||
|
||||
|
||||
/* Initialize PIT Counter 0 */
|
||||
IOWriteB(PIT_COMMAND_PORT, 0x34);
|
||||
IOWriteB(PIT_DATA_PORT(0), 0x00);
|
||||
IOWriteB(PIT_DATA_PORT(0), 0x00);
|
||||
|
||||
/* Initialize PIT Counter 1 */
|
||||
IOWriteB(PIT_COMMAND_PORT, 0x74);
|
||||
IOWriteB(PIT_DATA_PORT(1), 0x00);
|
||||
IOWriteB(PIT_DATA_PORT(1), 0x00);
|
||||
|
||||
/* Initialize PIT Counter 2 */
|
||||
IOWriteB(PIT_COMMAND_PORT, 0xB4);
|
||||
IOWriteB(PIT_DATA_PORT(2), 0x00);
|
||||
IOWriteB(PIT_DATA_PORT(2), 0x00);
|
||||
|
||||
EnableHwIRQ(0, BiosTimerIrq);
|
||||
}
|
||||
|
||||
static VOID InitializeBiosInt32(VOID)
|
||||
{
|
||||
USHORT i;
|
||||
// USHORT Offset = 0;
|
||||
|
||||
/* Initialize the callback context */
|
||||
InitializeContext(&BiosContext, BIOS_SEGMENT, 0x0000);
|
||||
|
||||
/* Register the BIOS 32-bit Interrupts */
|
||||
for (i = 0x00; i <= 0xFF; i++)
|
||||
{
|
||||
// Offset += RegisterInt32(MAKELONG(Offset, BIOS_SEGMENT), i, NULL, NULL);
|
||||
BiosContext.NextOffset += RegisterInt32(MAKELONG(BiosContext.NextOffset,
|
||||
BiosContext.Segment),
|
||||
i, NULL, NULL);
|
||||
}
|
||||
|
||||
/* Initialize the exception vector interrupts to a default Exception handler */
|
||||
for (i = 0; i < 8; i++)
|
||||
RegisterBiosInt32(i, BiosException);
|
||||
|
||||
/* Initialize HW vector interrupts to a default HW handler */
|
||||
for (i = BIOS_PIC_MASTER_INT; i < BIOS_PIC_MASTER_INT + 8; i++)
|
||||
RegisterBiosInt32(i, BiosHandleMasterPicIRQ);
|
||||
for (i = BIOS_PIC_SLAVE_INT ; i < BIOS_PIC_SLAVE_INT + 8; i++)
|
||||
RegisterBiosInt32(i, BiosHandleSlavePicIRQ);
|
||||
|
||||
/* Initialize software vector handlers */
|
||||
RegisterBiosInt32(BIOS_EQUIPMENT_INTERRUPT, BiosEquipmentService );
|
||||
RegisterBiosInt32(BIOS_MEMORY_SIZE , BiosGetMemorySize );
|
||||
RegisterBiosInt32(BIOS_MISC_INTERRUPT , BiosMiscService );
|
||||
RegisterBiosInt32(BIOS_TIME_INTERRUPT , BiosTimeService );
|
||||
RegisterBiosInt32(BIOS_SYS_TIMER_INTERRUPT, BiosSystemTimerInterrupt);
|
||||
|
||||
/* Some interrupts are in fact addresses to tables */
|
||||
((PULONG)BaseAddress)[0x1E] = (ULONG)NULL;
|
||||
((PULONG)BaseAddress)[0x41] = (ULONG)NULL;
|
||||
((PULONG)BaseAddress)[0x46] = (ULONG)NULL;
|
||||
((PULONG)BaseAddress)[0x48] = (ULONG)NULL;
|
||||
((PULONG)BaseAddress)[0x49] = (ULONG)NULL;
|
||||
}
|
||||
|
||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||
|
||||
/*
|
||||
* The BIOS POST (Power On-Self Test)
|
||||
*/
|
||||
BOOLEAN Bios32Initialize(VOID)
|
||||
{
|
||||
BOOLEAN Success;
|
||||
UCHAR Low, High;
|
||||
|
||||
/* Initialize the stack */
|
||||
// That's what says IBM... (stack at 30:00FF going downwards)
|
||||
// setSS(0x0000);
|
||||
// setSP(0x0400);
|
||||
setSS(0x0050); // Stack at 50:0400, going downwards
|
||||
setSP(0x0400);
|
||||
|
||||
/* Set data segment */
|
||||
setDS(BDA_SEGMENT);
|
||||
|
||||
/* Initialize the BDA contents */
|
||||
Bda->EquipmentList = BIOS_EQUIPMENT_LIST;
|
||||
|
||||
/*
|
||||
* Retrieve the conventional memory size
|
||||
* in kB from CMOS, typically 640 kB.
|
||||
*/
|
||||
IOWriteB(CMOS_ADDRESS_PORT, CMOS_REG_BASE_MEMORY_LOW);
|
||||
Low = IOReadB(CMOS_DATA_PORT);
|
||||
IOWriteB(CMOS_ADDRESS_PORT, CMOS_REG_BASE_MEMORY_HIGH);
|
||||
High = IOReadB(CMOS_DATA_PORT);
|
||||
Bda->MemorySize = MAKEWORD(Low, High);
|
||||
|
||||
/* Register the BIOS 32-bit Interrupts */
|
||||
InitializeBiosInt32();
|
||||
|
||||
/* Initialize platform hardware (PIC/PIT chips, ...) */
|
||||
BiosHwSetup();
|
||||
|
||||
/* Initialize the Keyboard and Video BIOS */
|
||||
if (!KbdBios32Initialize() || !VidBios32Initialize()) return FALSE;
|
||||
|
||||
///////////// MUST BE DONE AFTER IVT INITIALIZATION !! /////////////////////
|
||||
|
||||
/* Load some ROMs */
|
||||
Success = LoadRom("boot.bin", (PVOID)0xE0000, NULL);
|
||||
DPRINT1("Test ROM loading %s ; GetLastError() = %u\n", Success ? "succeeded" : "failed", GetLastError());
|
||||
|
||||
SearchAndInitRoms(&BiosContext);
|
||||
|
||||
/* We are done */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
VOID Bios32Cleanup(VOID)
|
||||
{
|
||||
VidBios32Cleanup();
|
||||
KbdBios32Cleanup();
|
||||
}
|
||||
|
||||
/* EOF */
|
32
subsystems/ntvdm/bios/bios32/bios32.h
Normal file
32
subsystems/ntvdm/bios/bios32/bios32.h
Normal file
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* COPYRIGHT: GPL - See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Virtual DOS Machine
|
||||
* FILE: bios32.h
|
||||
* PURPOSE: VDM 32-bit BIOS
|
||||
* PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||
*/
|
||||
|
||||
#ifndef _BIOS32_H_
|
||||
#define _BIOS32_H_
|
||||
|
||||
/* INCLUDES *******************************************************************/
|
||||
|
||||
#include "ntvdm.h"
|
||||
// #include "../bios.h"
|
||||
|
||||
/* DEFINES ********************************************************************/
|
||||
|
||||
// #define BIOS_EQUIPMENT_INTERRUPT 0x11
|
||||
// #define BIOS_MEMORY_SIZE 0x12
|
||||
// #define BIOS_MISC_INTERRUPT 0x15
|
||||
// #define BIOS_TIME_INTERRUPT 0x1A
|
||||
// #define BIOS_SYS_TIMER_INTERRUPT 0x1C
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
BOOLEAN Bios32Initialize(VOID);
|
||||
VOID Bios32Cleanup(VOID);
|
||||
|
||||
#endif // _BIOS32_H_
|
||||
|
||||
/* EOF */
|
45
subsystems/ntvdm/bios/bios32/bios32p.h
Normal file
45
subsystems/ntvdm/bios/bios32/bios32p.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* COPYRIGHT: GPL - See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Virtual DOS Machine
|
||||
* FILE: bios32.h
|
||||
* PURPOSE: VDM 32-bit BIOS
|
||||
* PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||
*/
|
||||
|
||||
#ifndef _BIOS32P_H_
|
||||
#define _BIOS32P_H_
|
||||
|
||||
/* INCLUDES *******************************************************************/
|
||||
|
||||
#include "ntvdm.h"
|
||||
#include "../bios.h"
|
||||
|
||||
/**/ #include "callback.h" /**/
|
||||
|
||||
/* DEFINES ********************************************************************/
|
||||
|
||||
#define BIOS_PIC_MASTER_INT 0x08
|
||||
#define BIOS_PIC_SLAVE_INT 0x70
|
||||
|
||||
#define BIOS_EQUIPMENT_INTERRUPT 0x11
|
||||
#define BIOS_MEMORY_SIZE 0x12
|
||||
#define BIOS_MISC_INTERRUPT 0x15
|
||||
#define BIOS_TIME_INTERRUPT 0x1A
|
||||
#define BIOS_SYS_TIMER_INTERRUPT 0x1C
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
extern CALLBACK16 BiosContext;
|
||||
#define RegisterBiosInt32(IntNumber, IntHandler) \
|
||||
do { \
|
||||
BiosContext.NextOffset += RegisterInt32(MAKELONG(BiosContext.NextOffset, \
|
||||
BiosContext.Segment), \
|
||||
(IntNumber), (IntHandler), NULL); \
|
||||
} while(0);
|
||||
|
||||
VOID EnableHwIRQ(UCHAR hwirq, EMULATOR_INT32_PROC func);
|
||||
VOID PicIRQComplete(LPWORD Stack);
|
||||
|
||||
#endif // _BIOS32P_H_
|
||||
|
||||
/* EOF */
|
293
subsystems/ntvdm/bios/bios32/kbdbios32.c
Normal file
293
subsystems/ntvdm/bios/bios32/kbdbios32.c
Normal file
|
@ -0,0 +1,293 @@
|
|||
/*
|
||||
* COPYRIGHT: GPL - See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Virtual DOS Machine
|
||||
* FILE: kbdbios32.c
|
||||
* PURPOSE: VDM Keyboard 32-bit BIOS
|
||||
* PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||
*/
|
||||
|
||||
/* INCLUDES *******************************************************************/
|
||||
|
||||
#define NDEBUG
|
||||
|
||||
#include "emulator.h"
|
||||
#include "callback.h"
|
||||
|
||||
#include "kbdbios32.h"
|
||||
#include "../kbdbios.h"
|
||||
#include "bios32p.h"
|
||||
|
||||
#include "io.h"
|
||||
#include "hardware/ps2.h"
|
||||
|
||||
/* PRIVATE VARIABLES **********************************************************/
|
||||
|
||||
static BYTE BiosKeyboardMap[256];
|
||||
|
||||
/* PRIVATE FUNCTIONS **********************************************************/
|
||||
|
||||
static BOOLEAN BiosKbdBufferPush(WORD Data)
|
||||
{
|
||||
/* Get the location of the element after the tail */
|
||||
WORD NextElement = Bda->KeybdBufferTail + sizeof(WORD);
|
||||
|
||||
/* Wrap it around if it's at or beyond the end */
|
||||
if (NextElement >= Bda->KeybdBufferEnd) NextElement = Bda->KeybdBufferStart;
|
||||
|
||||
/* If it's full, fail */
|
||||
if (NextElement == Bda->KeybdBufferHead) return FALSE;
|
||||
|
||||
/* Put the value in the queue */
|
||||
*((LPWORD)((ULONG_PTR)Bda + Bda->KeybdBufferTail)) = Data;
|
||||
Bda->KeybdBufferTail += sizeof(WORD);
|
||||
|
||||
/* Check if we are at, or have passed, the end of the buffer */
|
||||
if (Bda->KeybdBufferTail >= Bda->KeybdBufferEnd)
|
||||
{
|
||||
/* Return it to the beginning */
|
||||
Bda->KeybdBufferTail = Bda->KeybdBufferStart;
|
||||
}
|
||||
|
||||
/* Return success */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOLEAN BiosKbdBufferTop(LPWORD Data)
|
||||
{
|
||||
/* If it's empty, fail */
|
||||
if (Bda->KeybdBufferHead == Bda->KeybdBufferTail) return FALSE;
|
||||
|
||||
/* Otherwise, get the value and return success */
|
||||
*Data = *((LPWORD)((ULONG_PTR)Bda + Bda->KeybdBufferHead));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOLEAN BiosKbdBufferPop(VOID)
|
||||
{
|
||||
/* If it's empty, fail */
|
||||
if (Bda->KeybdBufferHead == Bda->KeybdBufferTail) return FALSE;
|
||||
|
||||
/* Remove the value from the queue */
|
||||
Bda->KeybdBufferHead += sizeof(WORD);
|
||||
|
||||
/* Check if we are at, or have passed, the end of the buffer */
|
||||
if (Bda->KeybdBufferHead >= Bda->KeybdBufferEnd)
|
||||
{
|
||||
/* Return it to the beginning */
|
||||
Bda->KeybdBufferHead = Bda->KeybdBufferStart;
|
||||
}
|
||||
|
||||
/* Return success */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static WORD BiosPeekCharacter(VOID)
|
||||
{
|
||||
WORD CharacterData = 0;
|
||||
|
||||
/* Get the key from the queue, but don't remove it */
|
||||
if (BiosKbdBufferTop(&CharacterData)) return CharacterData;
|
||||
else return 0xFFFF;
|
||||
}
|
||||
|
||||
WORD BiosGetCharacter(VOID)
|
||||
{
|
||||
WORD CharacterData = 0;
|
||||
|
||||
/* Check if there is a key available */
|
||||
if (BiosKbdBufferTop(&CharacterData))
|
||||
{
|
||||
/* A key was available, remove it from the queue */
|
||||
BiosKbdBufferPop();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No key available. Set the handler CF to repeat the BOP */
|
||||
setCF(1);
|
||||
// CharacterData = 0xFFFF;
|
||||
}
|
||||
|
||||
return CharacterData;
|
||||
}
|
||||
|
||||
static VOID WINAPI BiosKeyboardService(LPWORD Stack)
|
||||
{
|
||||
switch (getAH())
|
||||
{
|
||||
/* Wait for keystroke and read */
|
||||
case 0x00:
|
||||
/* Wait for extended keystroke and read */
|
||||
case 0x10: // FIXME: Temporarily do the same as INT 16h, 00h
|
||||
{
|
||||
/* Read the character (and wait if necessary) */
|
||||
setAX(BiosGetCharacter());
|
||||
break;
|
||||
}
|
||||
|
||||
/* Get keystroke status */
|
||||
case 0x01:
|
||||
/* Get extended keystroke status */
|
||||
case 0x11: // FIXME: Temporarily do the same as INT 16h, 01h
|
||||
{
|
||||
WORD Data = BiosPeekCharacter();
|
||||
|
||||
if (Data != 0xFFFF)
|
||||
{
|
||||
/* There is a character, clear ZF and return it */
|
||||
Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_ZF;
|
||||
setAX(Data);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No character, set ZF */
|
||||
Stack[STACK_FLAGS] |= EMULATOR_FLAG_ZF;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* Get shift status */
|
||||
case 0x02:
|
||||
{
|
||||
/* Return the lower byte of the keyboard shift status word */
|
||||
setAL(LOBYTE(Bda->KeybdShiftFlags));
|
||||
break;
|
||||
}
|
||||
|
||||
/* Reserved */
|
||||
case 0x04:
|
||||
{
|
||||
DPRINT1("BIOS Function INT 16h, AH = 0x04 is RESERVED\n");
|
||||
break;
|
||||
}
|
||||
|
||||
/* Push keystroke */
|
||||
case 0x05:
|
||||
{
|
||||
/* Return 0 if success, 1 if failure */
|
||||
setAL(BiosKbdBufferPush(getCX()) == FALSE);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Get extended shift status */
|
||||
case 0x12:
|
||||
{
|
||||
/*
|
||||
* Be careful! The returned word is similar to Bda->KeybdShiftFlags
|
||||
* but the high byte is organized differently:
|
||||
* the bytes 2 and 3 of the high byte are not the same...
|
||||
*/
|
||||
WORD KeybdShiftFlags = (Bda->KeybdShiftFlags & 0xF3FF);
|
||||
|
||||
/* Return the extended keyboard shift status word */
|
||||
setAX(KeybdShiftFlags);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
DPRINT1("BIOS Function INT 16h, AH = 0x%02X NOT IMPLEMENTED\n",
|
||||
getAH());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Keyboard IRQ 1
|
||||
static VOID WINAPI BiosKeyboardIrq(LPWORD Stack)
|
||||
{
|
||||
BYTE ScanCode, VirtualKey;
|
||||
WORD Character;
|
||||
|
||||
/* Get the scan code and virtual key code */
|
||||
ScanCode = IOReadB(PS2_DATA_PORT);
|
||||
VirtualKey = MapVirtualKey(ScanCode & 0x7F, MAPVK_VSC_TO_VK);
|
||||
|
||||
/* Check if this is a key press or release */
|
||||
if (!(ScanCode & (1 << 7)))
|
||||
{
|
||||
/* Key press */
|
||||
if (VirtualKey == VK_NUMLOCK ||
|
||||
VirtualKey == VK_CAPITAL ||
|
||||
VirtualKey == VK_SCROLL ||
|
||||
VirtualKey == VK_INSERT)
|
||||
{
|
||||
/* For toggle keys, toggle the lowest bit in the keyboard map */
|
||||
BiosKeyboardMap[VirtualKey] ^= ~(1 << 0);
|
||||
}
|
||||
|
||||
/* Set the highest bit */
|
||||
BiosKeyboardMap[VirtualKey] |= (1 << 7);
|
||||
|
||||
/* Find out which character this is */
|
||||
Character = 0;
|
||||
if (ToAscii(VirtualKey, ScanCode, BiosKeyboardMap, &Character, 0) == 0)
|
||||
{
|
||||
/* Not ASCII */
|
||||
Character = 0;
|
||||
}
|
||||
|
||||
/* Push it onto the BIOS keyboard queue */
|
||||
BiosKbdBufferPush(MAKEWORD(Character, ScanCode));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Key release, unset the highest bit */
|
||||
BiosKeyboardMap[VirtualKey] &= ~(1 << 7);
|
||||
}
|
||||
|
||||
/* Clear the keyboard flags */
|
||||
Bda->KeybdShiftFlags = 0;
|
||||
|
||||
/* Set the appropriate flags based on the state */
|
||||
if (BiosKeyboardMap[VK_RSHIFT] & (1 << 7)) Bda->KeybdShiftFlags |= BDA_KBDFLAG_RSHIFT;
|
||||
if (BiosKeyboardMap[VK_LSHIFT] & (1 << 7)) Bda->KeybdShiftFlags |= BDA_KBDFLAG_LSHIFT;
|
||||
if (BiosKeyboardMap[VK_CONTROL] & (1 << 7)) Bda->KeybdShiftFlags |= BDA_KBDFLAG_CTRL;
|
||||
if (BiosKeyboardMap[VK_MENU] & (1 << 7)) Bda->KeybdShiftFlags |= BDA_KBDFLAG_ALT;
|
||||
if (BiosKeyboardMap[VK_SCROLL] & (1 << 0)) Bda->KeybdShiftFlags |= BDA_KBDFLAG_SCROLL_ON;
|
||||
if (BiosKeyboardMap[VK_NUMLOCK] & (1 << 0)) Bda->KeybdShiftFlags |= BDA_KBDFLAG_NUMLOCK_ON;
|
||||
if (BiosKeyboardMap[VK_CAPITAL] & (1 << 0)) Bda->KeybdShiftFlags |= BDA_KBDFLAG_CAPSLOCK_ON;
|
||||
if (BiosKeyboardMap[VK_INSERT] & (1 << 0)) Bda->KeybdShiftFlags |= BDA_KBDFLAG_INSERT_ON;
|
||||
if (BiosKeyboardMap[VK_RMENU] & (1 << 7)) Bda->KeybdShiftFlags |= BDA_KBDFLAG_RALT;
|
||||
if (BiosKeyboardMap[VK_LMENU] & (1 << 7)) Bda->KeybdShiftFlags |= BDA_KBDFLAG_LALT;
|
||||
if (BiosKeyboardMap[VK_SNAPSHOT] & (1 << 7)) Bda->KeybdShiftFlags |= BDA_KBDFLAG_SYSRQ;
|
||||
if (BiosKeyboardMap[VK_PAUSE] & (1 << 7)) Bda->KeybdShiftFlags |= BDA_KBDFLAG_PAUSE;
|
||||
if (BiosKeyboardMap[VK_SCROLL] & (1 << 7)) Bda->KeybdShiftFlags |= BDA_KBDFLAG_SCROLL;
|
||||
if (BiosKeyboardMap[VK_NUMLOCK] & (1 << 7)) Bda->KeybdShiftFlags |= BDA_KBDFLAG_NUMLOCK;
|
||||
if (BiosKeyboardMap[VK_CAPITAL] & (1 << 7)) Bda->KeybdShiftFlags |= BDA_KBDFLAG_CAPSLOCK;
|
||||
if (BiosKeyboardMap[VK_INSERT] & (1 << 7)) Bda->KeybdShiftFlags |= BDA_KBDFLAG_INSERT;
|
||||
|
||||
PicIRQComplete(Stack);
|
||||
}
|
||||
|
||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||
|
||||
BOOLEAN KbdBios32Initialize(VOID)
|
||||
{
|
||||
/* Initialize the common Keyboard BIOS Support Library */
|
||||
if (!KbdBiosInitialize()) return FALSE;
|
||||
|
||||
/* Initialize the BDA */
|
||||
Bda->KeybdBufferStart = FIELD_OFFSET(BIOS_DATA_AREA, KeybdBuffer);
|
||||
Bda->KeybdBufferEnd = Bda->KeybdBufferStart + BIOS_KBD_BUFFER_SIZE * sizeof(WORD);
|
||||
Bda->KeybdBufferHead = Bda->KeybdBufferTail = 0;
|
||||
|
||||
/* Register the BIOS 32-bit Interrupts */
|
||||
|
||||
/* Initialize software vector handlers */
|
||||
RegisterBiosInt32(BIOS_KBD_INTERRUPT, BiosKeyboardService);
|
||||
|
||||
/* Set up the HW vector interrupts */
|
||||
EnableHwIRQ(1, BiosKeyboardIrq);
|
||||
// EnableHwIRQ(12, BiosMouseIrq);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
VOID KbdBios32Cleanup(VOID)
|
||||
{
|
||||
/* Cleanup the common Keyboard BIOS Support Library */
|
||||
KbdBiosCleanup();
|
||||
}
|
||||
|
||||
/* EOF */
|
46
subsystems/ntvdm/bios/bios32/kbdbios32.h
Normal file
46
subsystems/ntvdm/bios/bios32/kbdbios32.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* COPYRIGHT: GPL - See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Virtual DOS Machine
|
||||
* FILE: kbdbios32.h
|
||||
* PURPOSE: VDM Keyboard 32-bit BIOS
|
||||
* PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||
*/
|
||||
|
||||
#ifndef _KBDBIOS32_H_
|
||||
#define _KBDBIOS32_H_
|
||||
|
||||
/* INCLUDES *******************************************************************/
|
||||
|
||||
#include "ntvdm.h"
|
||||
|
||||
/* DEFINES ********************************************************************/
|
||||
|
||||
// #define BIOS_KBD_INTERRUPT 0x16
|
||||
|
||||
#define BIOS_KBD_BUFFER_SIZE 16
|
||||
|
||||
#define BDA_KBDFLAG_RSHIFT (1 << 0)
|
||||
#define BDA_KBDFLAG_LSHIFT (1 << 1)
|
||||
#define BDA_KBDFLAG_CTRL (1 << 2)
|
||||
#define BDA_KBDFLAG_ALT (1 << 3)
|
||||
#define BDA_KBDFLAG_SCROLL_ON (1 << 4)
|
||||
#define BDA_KBDFLAG_NUMLOCK_ON (1 << 5)
|
||||
#define BDA_KBDFLAG_CAPSLOCK_ON (1 << 6)
|
||||
#define BDA_KBDFLAG_INSERT_ON (1 << 7)
|
||||
#define BDA_KBDFLAG_RALT (1 << 8)
|
||||
#define BDA_KBDFLAG_LALT (1 << 9)
|
||||
#define BDA_KBDFLAG_SYSRQ (1 << 10)
|
||||
#define BDA_KBDFLAG_PAUSE (1 << 11)
|
||||
#define BDA_KBDFLAG_SCROLL (1 << 12)
|
||||
#define BDA_KBDFLAG_NUMLOCK (1 << 13)
|
||||
#define BDA_KBDFLAG_CAPSLOCK (1 << 14)
|
||||
#define BDA_KBDFLAG_INSERT (1 << 15)
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
BOOLEAN KbdBios32Initialize(VOID);
|
||||
VOID KbdBios32Cleanup(VOID);
|
||||
|
||||
#endif // _KBDBIOS32_H_
|
||||
|
||||
/* EOF */
|
41
subsystems/ntvdm/bios/bios32/vidbios32.c
Normal file
41
subsystems/ntvdm/bios/bios32/vidbios32.c
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* COPYRIGHT: GPL - See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Virtual DOS Machine
|
||||
* FILE: vidbios32.c
|
||||
* PURPOSE: VDM Video 32-bit BIOS
|
||||
* PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr)
|
||||
*
|
||||
* NOTE: All of the real code is in bios/vidbios.c
|
||||
*/
|
||||
|
||||
/* INCLUDES *******************************************************************/
|
||||
|
||||
#define NDEBUG
|
||||
|
||||
#include "emulator.h"
|
||||
#include "callback.h"
|
||||
|
||||
#include "vidbios32.h"
|
||||
#include "../vidbios.h"
|
||||
#include "bios32p.h"
|
||||
|
||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||
|
||||
BOOLEAN VidBios32Initialize(VOID)
|
||||
{
|
||||
/* Initialize the common Video BIOS Support Library */
|
||||
if (!VidBiosInitialize()) return FALSE;
|
||||
|
||||
/* Register the BIOS 32-bit Interrupts */
|
||||
RegisterBiosInt32(BIOS_VIDEO_INTERRUPT, VidBiosVideoService);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
VOID VidBios32Cleanup(VOID)
|
||||
{
|
||||
/* Cleanup the common Video BIOS Support Library */
|
||||
VidBiosCleanup();
|
||||
}
|
||||
|
||||
/* EOF */
|
29
subsystems/ntvdm/bios/bios32/vidbios32.h
Normal file
29
subsystems/ntvdm/bios/bios32/vidbios32.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* COPYRIGHT: GPL - See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Virtual DOS Machine
|
||||
* FILE: vidbios32.h
|
||||
* PURPOSE: VDM Video 32-bit BIOS
|
||||
* PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr)
|
||||
*
|
||||
* NOTE: All of the real code is in bios/vidbios.c
|
||||
*/
|
||||
|
||||
#ifndef _VIDBIOS32_H_
|
||||
#define _VIDBIOS32_H_
|
||||
|
||||
/* INCLUDES *******************************************************************/
|
||||
|
||||
#include "ntvdm.h"
|
||||
|
||||
/* DEFINES ********************************************************************/
|
||||
|
||||
// #define BIOS_VIDEO_INTERRUPT 0x10
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
BOOLEAN VidBios32Initialize(VOID);
|
||||
VOID VidBios32Cleanup(VOID);
|
||||
|
||||
#endif // _VIDBIOS32_H_
|
||||
|
||||
/* EOF */
|
51
subsystems/ntvdm/bios/kbdbios.c
Normal file
51
subsystems/ntvdm/bios/kbdbios.c
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* COPYRIGHT: GPL - See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Virtual DOS Machine
|
||||
* FILE: kbdbios.c
|
||||
* PURPOSE: VDM Keyboard BIOS Support Library
|
||||
* PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr)
|
||||
*/
|
||||
|
||||
/* INCLUDES *******************************************************************/
|
||||
|
||||
#define NDEBUG
|
||||
|
||||
#include "emulator.h"
|
||||
#include "callback.h"
|
||||
#include "bop.h"
|
||||
|
||||
#include "bios.h"
|
||||
// #include "kbdbios.h"
|
||||
|
||||
/* DEFINES ********************************************************************/
|
||||
|
||||
/* BOP Identifiers */
|
||||
#define BOP_KBD_IRQ 0x09
|
||||
#define BOP_KBD_INT 0x16
|
||||
|
||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||
|
||||
static VOID WINAPI KbdBiosIRQ(LPWORD Stack)
|
||||
{
|
||||
DPRINT1("KbdBiosIRQ is UNIMPLEMENTED\n");
|
||||
}
|
||||
|
||||
static VOID WINAPI KbdBiosINT(LPWORD Stack)
|
||||
{
|
||||
DPRINT1("KbdBiosINT is UNIMPLEMENTED\n");
|
||||
}
|
||||
|
||||
BOOLEAN KbdBiosInitialize(VOID)
|
||||
{
|
||||
/* Register the BIOS support BOPs */
|
||||
RegisterBop(BOP_KBD_IRQ, KbdBiosIRQ);
|
||||
RegisterBop(BOP_KBD_INT, KbdBiosINT);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
VOID KbdBiosCleanup(VOID)
|
||||
{
|
||||
}
|
||||
|
||||
/* EOF */
|
31
subsystems/ntvdm/bios/kbdbios.h
Normal file
31
subsystems/ntvdm/bios/kbdbios.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* COPYRIGHT: GPL - See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Virtual DOS Machine
|
||||
* FILE: kbdbios.h
|
||||
* PURPOSE: VDM Keyboard BIOS Support Library
|
||||
* PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr)
|
||||
*/
|
||||
|
||||
#ifndef _KBDBIOS_H_
|
||||
#define _KBDBIOS_H_
|
||||
|
||||
/* INCLUDES *******************************************************************/
|
||||
|
||||
#include "ntvdm.h"
|
||||
|
||||
/* DEFINES ********************************************************************/
|
||||
|
||||
#define BIOS_KBD_INTERRUPT 0x16
|
||||
|
||||
#define BIOS_KBD_BUFFER_SIZE 16
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
WORD BiosGetCharacter(VOID);
|
||||
|
||||
BOOLEAN KbdBiosInitialize(VOID);
|
||||
VOID KbdBiosCleanup(VOID);
|
||||
|
||||
#endif // _KBDBIOS_H_
|
||||
|
||||
/* EOF */
|
227
subsystems/ntvdm/bios/rom.c
Normal file
227
subsystems/ntvdm/bios/rom.c
Normal file
|
@ -0,0 +1,227 @@
|
|||
/*
|
||||
* COPYRIGHT: GPL - See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Virtual DOS Machine
|
||||
* FILE: rom.c
|
||||
* PURPOSE: ROM Support Functions
|
||||
* PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr)
|
||||
*/
|
||||
|
||||
/* INCLUDES *******************************************************************/
|
||||
|
||||
#define NDEBUG
|
||||
|
||||
#include "emulator.h"
|
||||
#include "callback.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include "rom.h"
|
||||
|
||||
/* PRIVATE FUNCTIONS **********************************************************/
|
||||
|
||||
static HANDLE
|
||||
OpenRomFile(IN PCSTR RomFileName,
|
||||
OUT PULONG RomSize OPTIONAL)
|
||||
{
|
||||
HANDLE hRomFile;
|
||||
ULONG ulRomSize = 0;
|
||||
|
||||
/* Open the ROM image file */
|
||||
hRomFile = FileOpen(RomFileName, &ulRomSize);
|
||||
|
||||
/* If we failed, bail out */
|
||||
if (hRomFile == NULL) return NULL;
|
||||
|
||||
/*
|
||||
* The size of the ROM image file is at most 256kB. For instance,
|
||||
* the SeaBIOS image, which includes also expansion ROMs inside it,
|
||||
* covers the range C000:0000 to F000:FFFF .
|
||||
*/
|
||||
if (ulRomSize > 0x40000)
|
||||
{
|
||||
/* We failed, bail out */
|
||||
DPRINT1("ROM image size 0x%lx too large, expected at most 0x40000 (256kB)", ulRomSize);
|
||||
FileClose(hRomFile);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Success, return file handle and size if needed */
|
||||
if (RomSize) *RomSize = ulRomSize;
|
||||
return hRomFile;
|
||||
}
|
||||
|
||||
static BOOLEAN
|
||||
LoadRomFileByHandle(IN HANDLE RomFileHandle,
|
||||
IN PVOID RomLocation,
|
||||
IN ULONG RomSize,
|
||||
OUT PULONG BytesRead)
|
||||
{
|
||||
/*
|
||||
* The size of the ROM image file is at most 256kB. For instance,
|
||||
* the SeaBIOS image, which includes also expansion ROMs inside it,
|
||||
* covers the range C000:0000 to F000:FFFF .
|
||||
*/
|
||||
if (RomSize > 0x40000)
|
||||
{
|
||||
DPRINT1("ROM image size 0x%lx too large, expected at most 0x40000 (256kB)", RomSize);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Attempt to load the ROM image file into memory */
|
||||
return FileLoadByHandle(RomFileHandle,
|
||||
REAL_TO_PHYS(RomLocation),
|
||||
RomSize,
|
||||
BytesRead);
|
||||
}
|
||||
|
||||
static UCHAR
|
||||
ComputeChecksum(IN ULONG RomLocation,
|
||||
IN ULONG RomSize)
|
||||
{
|
||||
ULONG RomLastAddress = RomLocation + RomSize;
|
||||
UCHAR Sum = 0x00; // Using a UCHAR guarantees that we wrap at 0xFF i.e. we do a sum modulo 0x100.
|
||||
|
||||
while (RomLocation < RomLastAddress)
|
||||
{
|
||||
Sum += *(PUCHAR)REAL_TO_PHYS(RomLocation);
|
||||
++RomLocation;
|
||||
}
|
||||
|
||||
return Sum;
|
||||
}
|
||||
|
||||
static VOID
|
||||
InitRomRange(IN PCALLBACK16 Context,
|
||||
IN ULONG Start,
|
||||
IN ULONG End,
|
||||
IN ULONG Increment)
|
||||
{
|
||||
ULONG Address, AddressBoot;
|
||||
ULONG RomSize;
|
||||
UCHAR Checksum;
|
||||
|
||||
for (Address = Start; Address < End; Address += Increment)
|
||||
{
|
||||
/* Does the ROM have a valid signature? */
|
||||
if (*(PUSHORT)REAL_TO_PHYS(Address) == OPTION_ROM_SIGNATURE)
|
||||
{
|
||||
/* Check the control sum of the ROM */
|
||||
|
||||
/*
|
||||
* If this is an adapter ROM (Start: C8000, End: E0000), its
|
||||
* reported size is stored in byte 2 of the ROM.
|
||||
*
|
||||
* If this is an expansion ROM (Start: E0000, End: F0000),
|
||||
* its real length is 64kB.
|
||||
*/
|
||||
RomSize = *(PUCHAR)REAL_TO_PHYS(Address + 2) * 512;
|
||||
if (Address >= 0xE0000) RomSize = 0x10000;
|
||||
|
||||
Checksum = ComputeChecksum(Address, RomSize);
|
||||
if (Checksum == 0x00)
|
||||
{
|
||||
AddressBoot = Address + 3;
|
||||
DPRINT1("Going to run @ address 0x%p\n", AddressBoot);
|
||||
|
||||
AddressBoot = MAKELONG((AddressBoot & 0xFFFF), (AddressBoot & 0xF0000) >> 4);
|
||||
// setDS((Address & 0xF0000) >> 4);
|
||||
setDS((Address & 0xFF000) >> 4);
|
||||
RunCallback16(Context, AddressBoot);
|
||||
// Call16((AddressBoot & 0xF0000) >> 4, (AddressBoot & 0xFFFF));
|
||||
|
||||
DPRINT1("Rom @ address 0x%p initialized\n", Address);
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT1("Rom @ address 0x%p has invalid checksum of 0x%02x\n", Address, Checksum);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||
|
||||
BOOLEAN
|
||||
LoadBios(IN PCSTR BiosFileName,
|
||||
OUT PVOID* BiosLocation OPTIONAL,
|
||||
OUT PULONG BiosSize OPTIONAL)
|
||||
{
|
||||
BOOLEAN Success;
|
||||
HANDLE hBiosFile;
|
||||
ULONG ulBiosSize = 0;
|
||||
PVOID pBiosLocation;
|
||||
|
||||
/* Open the BIOS image file */
|
||||
hBiosFile = OpenRomFile(BiosFileName, &ulBiosSize);
|
||||
|
||||
/* If we failed, bail out */
|
||||
if (hBiosFile == NULL) return FALSE;
|
||||
|
||||
/* BIOS location needs to be aligned on 32-bit boundary */
|
||||
// (PVOID)((ULONG_PTR)BaseAddress + ROM_AREA_END + 1 - ulBiosSize)
|
||||
pBiosLocation = MEM_ALIGN_DOWN(TO_LINEAR(0xF000, 0xFFFF) + 1 - ulBiosSize, sizeof(ULONG));
|
||||
|
||||
/* Attempt to load the BIOS image file into memory */
|
||||
Success = LoadRomFileByHandle(hBiosFile,
|
||||
pBiosLocation,
|
||||
ulBiosSize,
|
||||
&ulBiosSize);
|
||||
DPRINT1("BIOS loading %s ; GetLastError() = %u\n", Success ? "succeeded" : "failed", GetLastError());
|
||||
|
||||
/* Close the BIOS image file */
|
||||
FileClose(hBiosFile);
|
||||
|
||||
/* In case of success, return BIOS location and size if needed */
|
||||
if (Success)
|
||||
{
|
||||
if (BiosLocation) *BiosLocation = pBiosLocation;
|
||||
if (BiosSize) *BiosSize = ulBiosSize;
|
||||
}
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
LoadRom(IN PCSTR RomFileName,
|
||||
IN PVOID RomLocation,
|
||||
OUT PULONG RomSize OPTIONAL)
|
||||
{
|
||||
BOOLEAN Success;
|
||||
HANDLE hRomFile;
|
||||
ULONG ulRomSize = 0;
|
||||
|
||||
/* Open the ROM image file */
|
||||
hRomFile = OpenRomFile(RomFileName, &ulRomSize);
|
||||
|
||||
/* If we failed, bail out */
|
||||
if (hRomFile == NULL) return FALSE;
|
||||
|
||||
/* Attempt to load the ROM image file into memory */
|
||||
Success = LoadRomFileByHandle(hRomFile,
|
||||
RomLocation,
|
||||
ulRomSize,
|
||||
&ulRomSize);
|
||||
DPRINT1("ROM loading %s ; GetLastError() = %u\n", Success ? "succeeded" : "failed", GetLastError());
|
||||
|
||||
/* Close the ROM image file and return */
|
||||
FileClose(hRomFile);
|
||||
|
||||
/* In case of success, return ROM size if needed */
|
||||
if (Success)
|
||||
{
|
||||
if (RomSize) *RomSize = ulRomSize;
|
||||
}
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
VOID
|
||||
SearchAndInitRoms(IN PCALLBACK16 Context)
|
||||
{
|
||||
/* Adapters ROMs -- Start: C8000, End: E0000, 2kB blocks */
|
||||
InitRomRange(Context, 0xC8000, 0xE0000, 0x0800);
|
||||
|
||||
/* Expansion ROM -- Start: E0000, End: F0000, 64kB block */
|
||||
InitRomRange(Context, 0xE0000, 0xEFFFF, 0x10000);
|
||||
}
|
||||
|
||||
/* EOF */
|
40
subsystems/ntvdm/bios/rom.h
Normal file
40
subsystems/ntvdm/bios/rom.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* COPYRIGHT: GPL - See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Virtual DOS Machine
|
||||
* FILE: rom.h
|
||||
* PURPOSE: ROM Support Functions
|
||||
* PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr)
|
||||
*/
|
||||
|
||||
#ifndef _ROM_H_
|
||||
#define _ROM_H_
|
||||
|
||||
/* INCLUDES *******************************************************************/
|
||||
|
||||
#include "ntvdm.h"
|
||||
|
||||
/* DEFINES ********************************************************************/
|
||||
|
||||
#define ROM_AREA_START 0xE0000
|
||||
#define ROM_AREA_END 0xFFFFF
|
||||
|
||||
#define OPTION_ROM_SIGNATURE 0xAA55
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
BOOLEAN
|
||||
LoadBios(IN PCSTR BiosFileName,
|
||||
OUT PVOID* BiosLocation OPTIONAL,
|
||||
OUT PULONG BiosSize OPTIONAL);
|
||||
|
||||
BOOLEAN
|
||||
LoadRom(IN PCSTR RomFileName,
|
||||
IN PVOID RomLocation,
|
||||
OUT PULONG RomSize OPTIONAL);
|
||||
|
||||
VOID
|
||||
SearchAndInitRoms(IN PCALLBACK16 Context);
|
||||
|
||||
#endif // _ROM_H_
|
||||
|
||||
/* EOF */
|
1560
subsystems/ntvdm/bios/vidbios.c
Normal file
1560
subsystems/ntvdm/bios/vidbios.c
Normal file
File diff suppressed because it is too large
Load diff
49
subsystems/ntvdm/bios/vidbios.h
Normal file
49
subsystems/ntvdm/bios/vidbios.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* COPYRIGHT: GPL - See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Virtual DOS Machine
|
||||
* FILE: vidbios.h
|
||||
* PURPOSE: VDM Video BIOS Support Library
|
||||
* PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||
* Hermes Belusca-Maito (hermes.belusca@sfr.fr)
|
||||
*/
|
||||
|
||||
#ifndef _VIDBIOS_H_
|
||||
#define _VIDBIOS_H_
|
||||
|
||||
/* INCLUDES *******************************************************************/
|
||||
|
||||
#include "ntvdm.h"
|
||||
|
||||
/* DEFINES ********************************************************************/
|
||||
|
||||
#define BIOS_VIDEO_INTERRUPT 0x10
|
||||
|
||||
#define CONSOLE_FONT_HEIGHT 8
|
||||
#define BIOS_DEFAULT_VIDEO_MODE 0x03
|
||||
#define BIOS_MAX_PAGES 8
|
||||
#define BIOS_MAX_VIDEO_MODE 0x13
|
||||
#define DEFAULT_ATTRIBUTE 0x07
|
||||
|
||||
#define GRAPHICS_VIDEO_SEG 0xA000
|
||||
#define TEXT_VIDEO_SEG 0xB800
|
||||
|
||||
enum
|
||||
{
|
||||
SCROLL_DIRECTION_UP,
|
||||
SCROLL_DIRECTION_DOWN,
|
||||
SCROLL_DIRECTION_LEFT,
|
||||
SCROLL_DIRECTION_RIGHT
|
||||
};
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
VOID WINAPI VidBiosVideoService(LPWORD Stack);
|
||||
|
||||
VOID VidBiosSyncCursorPosition(VOID);
|
||||
|
||||
BOOLEAN VidBiosInitialize(VOID);
|
||||
VOID VidBiosCleanup(VOID);
|
||||
|
||||
#endif // _VIDBIOS_H_
|
||||
|
||||
/* EOF */
|
50
subsystems/ntvdm/bop.c
Normal file
50
subsystems/ntvdm/bop.c
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* COPYRIGHT: GPL - See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Virtual DOS Machine
|
||||
* FILE: bop.c
|
||||
* PURPOSE: BIOS Operation Handlers
|
||||
* PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||
* Hermes Belusca-Maito (hermes.belusca@sfr.fr)
|
||||
*/
|
||||
|
||||
/* INCLUDES *******************************************************************/
|
||||
|
||||
// #define NDEBUG
|
||||
|
||||
#include "emulator.h"
|
||||
#include "bop.h"
|
||||
|
||||
/* PRIVATE VARIABLES **********************************************************/
|
||||
|
||||
/*
|
||||
* This is the list of registered BOP handlers.
|
||||
*/
|
||||
EMULATOR_BOP_PROC BopProc[EMULATOR_MAX_BOP_NUM] = { NULL };
|
||||
|
||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||
|
||||
VOID RegisterBop(BYTE BopCode, EMULATOR_BOP_PROC BopHandler)
|
||||
{
|
||||
BopProc[BopCode] = BopHandler;
|
||||
}
|
||||
|
||||
VOID WINAPI EmulatorBiosOperation(PFAST486_STATE State, UCHAR BopCode)
|
||||
{
|
||||
WORD StackSegment, StackPointer;
|
||||
LPWORD Stack;
|
||||
|
||||
/* Get the SS:SP */
|
||||
StackSegment = State->SegmentRegs[FAST486_REG_SS].Selector;
|
||||
StackPointer = State->GeneralRegs[FAST486_REG_ESP].LowWord;
|
||||
|
||||
/* Get the stack */
|
||||
Stack = (LPWORD)SEG_OFF_TO_PTR(StackSegment, StackPointer);
|
||||
|
||||
/* Call the BOP handler */
|
||||
if (BopProc[BopCode] != NULL)
|
||||
BopProc[BopCode](Stack);
|
||||
else
|
||||
DPRINT("Invalid BOP code: 0x%02X\n", BopCode);
|
||||
}
|
||||
|
||||
/* EOF */
|
28
subsystems/ntvdm/bop.h
Normal file
28
subsystems/ntvdm/bop.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* COPYRIGHT: GPL - See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Virtual DOS Machine
|
||||
* FILE: bop.h
|
||||
* PURPOSE: BIOS Operation Handlers
|
||||
* PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||
* Hermes Belusca-Maito (hermes.belusca@sfr.fr)
|
||||
*/
|
||||
|
||||
#ifndef _BOP_H_
|
||||
#define _BOP_H_
|
||||
|
||||
/* DEFINES ********************************************************************/
|
||||
|
||||
/* BOP Identifiers */
|
||||
#define EMULATOR_BOP 0xC4C4
|
||||
#define EMULATOR_MAX_BOP_NUM 0xFF + 1
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
typedef VOID (WINAPI *EMULATOR_BOP_PROC)(LPWORD Stack);
|
||||
|
||||
VOID RegisterBop(BYTE BopCode, EMULATOR_BOP_PROC BopHandler);
|
||||
VOID WINAPI EmulatorBiosOperation(PFAST486_STATE State, UCHAR BopCode);
|
||||
|
||||
#endif // _BOP_H_
|
||||
|
||||
/* EOF */
|
293
subsystems/ntvdm/callback.c
Normal file
293
subsystems/ntvdm/callback.c
Normal file
|
@ -0,0 +1,293 @@
|
|||
/*
|
||||
* COPYRIGHT: GPL - See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Virtual DOS Machine
|
||||
* FILE: callback.c
|
||||
* PURPOSE: 16 and 32-bit Callbacks Support
|
||||
* PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||
* Hermes Belusca-Maito (hermes.belusca@sfr.fr)
|
||||
*/
|
||||
|
||||
/* INCLUDES *******************************************************************/
|
||||
|
||||
#define NDEBUG
|
||||
|
||||
#include "emulator.h"
|
||||
#include "callback.h"
|
||||
|
||||
#include "bop.h"
|
||||
#include <isvbop.h>
|
||||
|
||||
/* PRIVATE VARIABLES **********************************************************/
|
||||
|
||||
/*
|
||||
* This is the list of registered 32-bit Interrupt handlers.
|
||||
*/
|
||||
EMULATOR_INT32_PROC Int32Proc[EMULATOR_MAX_INT32_NUM] = { NULL };
|
||||
|
||||
/* BOP Identifiers */
|
||||
#define BOP_CONTROL 0xFF // Control BOP Handler
|
||||
#define BOP_CONTROL_DEFFUNC 0x00 // Default Control BOP Function
|
||||
|
||||
/* 32-bit Interrupt dispatcher function code for the Control BOP Handler */
|
||||
#define BOP_CONTROL_INT32 0xFF
|
||||
|
||||
|
||||
#define BOP(num) LOBYTE(EMULATOR_BOP), HIBYTE(EMULATOR_BOP), (num)
|
||||
#define UnSimulate16(trap) \
|
||||
do { \
|
||||
*(PUSHORT)(trap) = EMULATOR_BOP; \
|
||||
(trap) += sizeof(USHORT); \
|
||||
*(trap) = BOP_UNSIMULATE; \
|
||||
} while(0)
|
||||
// #define UnSimulate16 MAKELONG(EMULATOR_BOP, BOP_UNSIMULATE) // BOP(BOP_UNSIMULATE)
|
||||
|
||||
#define CALL16_TRAMPOLINE_SIZE (1 * sizeof(ULONGLONG))
|
||||
#define INT16_TRAMPOLINE_SIZE (1 * sizeof(ULONGLONG))
|
||||
|
||||
/* 16-bit generic interrupt code for calling a 32-bit interrupt handler */
|
||||
BYTE Int16To32[] =
|
||||
{
|
||||
0xFA, // cli
|
||||
|
||||
/* Push the value of the interrupt to be called */
|
||||
0x6A, 0xFF, // push i (patchable to 0x6A, 0xIntNum)
|
||||
|
||||
/* The counter variable (initialized to 0) */
|
||||
0x6A, 0x00, // push 0
|
||||
|
||||
/* Stack variables */
|
||||
0x83, 0xEC, 0x04, // sub sp, 4
|
||||
|
||||
/* The BOP Sequence */
|
||||
// BOP_SEQ:
|
||||
0xF8, // clc
|
||||
BOP(BOP_CONTROL), // Control BOP
|
||||
BOP_CONTROL_INT32, // 32-bit Interrupt dispatcher
|
||||
|
||||
0x73, 0x04, // jnc EXIT (offset +4)
|
||||
|
||||
0xFB, // sti
|
||||
|
||||
// HACK: The following instruction should be HLT!
|
||||
0x90, // nop
|
||||
|
||||
0xEB, 0xF5, // jmp BOP_SEQ (offset -11)
|
||||
|
||||
// EXIT:
|
||||
0x83, 0xC4, 0x08, // add sp, 8
|
||||
0xCF, // iret
|
||||
};
|
||||
|
||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||
|
||||
VOID
|
||||
InitializeContext(IN PCALLBACK16 Context,
|
||||
IN USHORT Segment,
|
||||
IN USHORT Offset)
|
||||
{
|
||||
Context->TrampolineFarPtr = MAKELONG(Offset, Segment);
|
||||
Context->Segment = Segment;
|
||||
Context->NextOffset = Offset + max(CALL16_TRAMPOLINE_SIZE,
|
||||
INT16_TRAMPOLINE_SIZE);
|
||||
}
|
||||
|
||||
VOID
|
||||
Call16(IN USHORT Segment,
|
||||
IN USHORT Offset)
|
||||
{
|
||||
/* Save CS:IP */
|
||||
USHORT OrgCS = getCS();
|
||||
USHORT OrgIP = getIP();
|
||||
|
||||
/* Set the new CS:IP */
|
||||
setCS(Segment);
|
||||
setIP(Offset);
|
||||
|
||||
DPRINT("Call16(%04X:%04X)\n", Segment, Offset);
|
||||
|
||||
/* Start CPU simulation */
|
||||
EmulatorSimulate();
|
||||
|
||||
/* Restore CS:IP */
|
||||
setCS(OrgCS);
|
||||
setIP(OrgIP);
|
||||
}
|
||||
|
||||
|
||||
|
||||
ULONG
|
||||
RegisterCallback16(IN ULONG FarPtr,
|
||||
IN LPBYTE CallbackCode,
|
||||
IN SIZE_T CallbackSize,
|
||||
OUT PSIZE_T CodeSize OPTIONAL)
|
||||
{
|
||||
LPBYTE CodeStart = (LPBYTE)FAR_POINTER(FarPtr);
|
||||
LPBYTE Code = CodeStart;
|
||||
|
||||
SIZE_T OurCodeSize = CallbackSize;
|
||||
|
||||
if (CallbackCode == NULL) CallbackSize = 0;
|
||||
|
||||
if (CallbackCode)
|
||||
{
|
||||
/* 16-bit interrupt code */
|
||||
RtlCopyMemory(Code, CallbackCode, CallbackSize);
|
||||
Code += CallbackSize;
|
||||
}
|
||||
|
||||
/* Return the real size of the code if needed */
|
||||
if (CodeSize) *CodeSize = OurCodeSize; // == (ULONG_PTR)Code - (ULONG_PTR)CodeStart;
|
||||
|
||||
// /* Return the entry-point address for 32-bit calls */
|
||||
// return (ULONG_PTR)(CodeStart + CallbackSize);
|
||||
return OurCodeSize;
|
||||
}
|
||||
|
||||
VOID
|
||||
RunCallback16(IN PCALLBACK16 Context,
|
||||
IN ULONG FarPtr)
|
||||
{
|
||||
PUCHAR TrampolineBase = (PUCHAR)FAR_POINTER(Context->TrampolineFarPtr);
|
||||
PUCHAR Trampoline = TrampolineBase;
|
||||
UCHAR OldTrampoline[CALL16_TRAMPOLINE_SIZE];
|
||||
|
||||
/* Save the old trampoline */
|
||||
((PULONGLONG)&OldTrampoline)[0] = ((PULONGLONG)TrampolineBase)[0];
|
||||
|
||||
DPRINT1("RunCallback16(0x%p)\n", FarPtr);
|
||||
|
||||
/* Build the generic entry-point for 16-bit far calls */
|
||||
*Trampoline++ = 0x9A; // Call far seg:off
|
||||
*(PULONG)Trampoline = FarPtr;
|
||||
Trampoline += sizeof(ULONG);
|
||||
UnSimulate16(Trampoline);
|
||||
|
||||
/* Perform the call */
|
||||
Call16(HIWORD(Context->TrampolineFarPtr),
|
||||
LOWORD(Context->TrampolineFarPtr));
|
||||
|
||||
/* Restore the old trampoline */
|
||||
((PULONGLONG)TrampolineBase)[0] = ((PULONGLONG)&OldTrampoline)[0];
|
||||
}
|
||||
|
||||
|
||||
|
||||
ULONG
|
||||
RegisterInt16(IN ULONG FarPtr,
|
||||
IN BYTE IntNumber,
|
||||
IN LPBYTE CallbackCode,
|
||||
IN SIZE_T CallbackSize,
|
||||
OUT PSIZE_T CodeSize OPTIONAL)
|
||||
{
|
||||
/* Get a pointer to the IVT and set the corresponding entry (far pointer) */
|
||||
LPDWORD IntVecTable = (LPDWORD)SEG_OFF_TO_PTR(0x0000, 0x0000);
|
||||
IntVecTable[IntNumber] = FarPtr;
|
||||
|
||||
/* Register the 16-bit callback */
|
||||
return RegisterCallback16(FarPtr,
|
||||
CallbackCode,
|
||||
CallbackSize,
|
||||
CodeSize);
|
||||
}
|
||||
|
||||
ULONG
|
||||
RegisterInt32(IN ULONG FarPtr,
|
||||
IN BYTE IntNumber,
|
||||
IN EMULATOR_INT32_PROC IntHandler,
|
||||
OUT PSIZE_T CodeSize OPTIONAL)
|
||||
{
|
||||
/* Array for holding our copy of the 16-bit interrupt callback */
|
||||
BYTE IntCallback[sizeof(Int16To32)/sizeof(BYTE)];
|
||||
|
||||
/* Check whether the 32-bit interrupt was already registered */
|
||||
// if (Int32Proc[IntNumber] != NULL)
|
||||
// {
|
||||
// DPRINT1("RegisterInt32: Interrupt 0x%X already registered!\n", IntNumber);
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
/* Register the 32-bit interrupt handler */
|
||||
Int32Proc[IntNumber] = IntHandler;
|
||||
|
||||
/* Copy the generic 16-bit interrupt callback and patch it */
|
||||
RtlCopyMemory(IntCallback, Int16To32, sizeof(Int16To32));
|
||||
IntCallback[2] = IntNumber;
|
||||
|
||||
/* Register the 16-bit interrupt callback */
|
||||
return RegisterInt16(FarPtr,
|
||||
IntNumber,
|
||||
IntCallback,
|
||||
sizeof(IntCallback),
|
||||
CodeSize);
|
||||
}
|
||||
|
||||
VOID
|
||||
Int32Call(IN PCALLBACK16 Context,
|
||||
IN BYTE IntNumber)
|
||||
{
|
||||
PUCHAR TrampolineBase = (PUCHAR)FAR_POINTER(Context->TrampolineFarPtr);
|
||||
PUCHAR Trampoline = TrampolineBase;
|
||||
UCHAR OldTrampoline[INT16_TRAMPOLINE_SIZE];
|
||||
|
||||
DPRINT("Int32Call(0x%X)\n", IntNumber);
|
||||
|
||||
/* Save the old trampoline */
|
||||
((PULONGLONG)&OldTrampoline)[0] = ((PULONGLONG)TrampolineBase)[0];
|
||||
|
||||
/* Build the generic entry-point for 16-bit calls */
|
||||
if (IntNumber == 0x03)
|
||||
{
|
||||
/* We are redefining for INT 03h */
|
||||
*Trampoline++ = 0xCC; // Call INT 03h
|
||||
/** *Trampoline++ = 0x90; // nop **/
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Normal interrupt */
|
||||
*Trampoline++ = 0xCD; // Call INT XXh
|
||||
*Trampoline++ = IntNumber;
|
||||
}
|
||||
UnSimulate16(Trampoline);
|
||||
|
||||
/* Perform the call */
|
||||
Call16(HIWORD(Context->TrampolineFarPtr),
|
||||
LOWORD(Context->TrampolineFarPtr));
|
||||
|
||||
/* Restore the old trampoline */
|
||||
((PULONGLONG)TrampolineBase)[0] = ((PULONGLONG)&OldTrampoline)[0];
|
||||
}
|
||||
|
||||
|
||||
|
||||
VOID WINAPI Int32Dispatch(LPWORD Stack)
|
||||
{
|
||||
/* Get the interrupt number */
|
||||
BYTE IntNum = LOBYTE(Stack[STACK_INT_NUM]);
|
||||
|
||||
/* Call the 32-bit Interrupt handler */
|
||||
if (Int32Proc[IntNum] != NULL)
|
||||
Int32Proc[IntNum](Stack);
|
||||
else
|
||||
DPRINT1("Unhandled 32-bit interrupt: 0x%02X, AX = 0x%04X\n", IntNum, getAX());
|
||||
}
|
||||
|
||||
static VOID WINAPI ControlBop(LPWORD Stack)
|
||||
{
|
||||
/* Get the Function Number and skip it */
|
||||
BYTE FuncNum = *(PBYTE)SEG_OFF_TO_PTR(getCS(), getIP());
|
||||
setIP(getIP() + 1);
|
||||
|
||||
if (FuncNum == BOP_CONTROL_INT32)
|
||||
Int32Dispatch(Stack);
|
||||
else
|
||||
// DPRINT1("Unassigned Control BOP Function: 0x%02X\n", FuncNum);
|
||||
DisplayMessage(L"Unassigned Control BOP Function: 0x%02X\n", FuncNum);
|
||||
}
|
||||
|
||||
VOID InitializeCallbacks(VOID)
|
||||
{
|
||||
/* Register the Control BOP */
|
||||
RegisterBop(BOP_CONTROL, ControlBop);
|
||||
}
|
||||
|
||||
/* EOF */
|
75
subsystems/ntvdm/callback.h
Normal file
75
subsystems/ntvdm/callback.h
Normal file
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* COPYRIGHT: GPL - See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Virtual DOS Machine
|
||||
* FILE: callback.h
|
||||
* PURPOSE: 32-bit Interrupt Handlers
|
||||
* PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||
* Hermes Belusca-Maito (hermes.belusca@sfr.fr)
|
||||
*/
|
||||
|
||||
#ifndef _CALLBACK_H_
|
||||
#define _CALLBACK_H_
|
||||
|
||||
/* DEFINES ********************************************************************/
|
||||
|
||||
/* 32-bit Interrupt Identifiers */
|
||||
#define EMULATOR_MAX_INT32_NUM 0xFF + 1
|
||||
|
||||
#define INT_HANDLER_OFFSET 0x1000
|
||||
#define COMMON_STUB_OFFSET 0x2000
|
||||
|
||||
|
||||
typedef struct _CALLBACK16
|
||||
{
|
||||
ULONG TrampolineFarPtr; // Where the trampoline zone is placed
|
||||
USHORT Segment;
|
||||
USHORT NextOffset;
|
||||
} CALLBACK16, *PCALLBACK16;
|
||||
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
typedef VOID (WINAPI *EMULATOR_INT32_PROC)(LPWORD Stack);
|
||||
|
||||
VOID
|
||||
InitializeContext(IN PCALLBACK16 Context,
|
||||
IN USHORT Segment,
|
||||
IN USHORT Offset);
|
||||
|
||||
VOID
|
||||
Call16(IN USHORT Segment,
|
||||
IN USHORT Offset);
|
||||
|
||||
ULONG
|
||||
RegisterCallback16(IN ULONG FarPtr,
|
||||
IN LPBYTE CallbackCode,
|
||||
IN SIZE_T CallbackSize,
|
||||
OUT PSIZE_T CodeSize OPTIONAL);
|
||||
|
||||
VOID
|
||||
RunCallback16(IN PCALLBACK16 Context,
|
||||
IN ULONG FarPtr);
|
||||
|
||||
ULONG
|
||||
RegisterInt16(IN ULONG FarPtr,
|
||||
IN BYTE IntNumber,
|
||||
IN LPBYTE CallbackCode,
|
||||
IN SIZE_T CallbackSize,
|
||||
OUT PSIZE_T CodeSize OPTIONAL);
|
||||
|
||||
ULONG
|
||||
RegisterInt32(IN ULONG FarPtr,
|
||||
IN BYTE IntNumber,
|
||||
IN EMULATOR_INT32_PROC IntHandler,
|
||||
OUT PSIZE_T CodeSize OPTIONAL);
|
||||
|
||||
VOID
|
||||
Int32Call(IN PCALLBACK16 Context,
|
||||
IN BYTE IntNumber);
|
||||
|
||||
VOID WINAPI Int32Dispatch(LPWORD Stack);
|
||||
VOID InitializeCallbacks(VOID);
|
||||
|
||||
#endif // _CALLBACK_H_
|
||||
|
||||
/* EOF */
|
173
subsystems/ntvdm/clock.c
Normal file
173
subsystems/ntvdm/clock.c
Normal file
|
@ -0,0 +1,173 @@
|
|||
/*
|
||||
* COPYRIGHT: GPL - See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Virtual DOS Machine
|
||||
* FILE: clock.c
|
||||
* PURPOSE: Clock for VDM
|
||||
* PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||
* Hermes Belusca-Maito (hermes.belusca@sfr.fr)
|
||||
*/
|
||||
|
||||
/* INCLUDES *******************************************************************/
|
||||
|
||||
#define NDEBUG
|
||||
|
||||
#include "emulator.h"
|
||||
|
||||
// #include "clock.h"
|
||||
|
||||
#include "hardware/cmos.h"
|
||||
#include "hardware/ps2.h"
|
||||
#include "hardware/timer.h"
|
||||
#include "hardware/vga.h"
|
||||
|
||||
/* DEFINES ********************************************************************/
|
||||
|
||||
/*
|
||||
* Activate IPS_DISPLAY if you want to display the
|
||||
* number of instructions per second, as well as
|
||||
* the computed number of ticks for the PIT.
|
||||
*/
|
||||
// #define IPS_DISPLAY
|
||||
|
||||
/*
|
||||
* Activate WORKING_TIMER when the PIT timing problem is fixed.
|
||||
*/
|
||||
// #define WORKING_TIMER
|
||||
|
||||
|
||||
/* Processor speed */
|
||||
#define STEPS_PER_CYCLE 256
|
||||
#define KBD_INT_CYCLES 16
|
||||
|
||||
/* VARIABLES ******************************************************************/
|
||||
|
||||
LARGE_INTEGER StartPerfCount, Frequency;
|
||||
|
||||
LARGE_INTEGER LastTimerTick, LastRtcTick, Counter;
|
||||
LONGLONG TimerTicks;
|
||||
DWORD StartTickCount, CurrentTickCount;
|
||||
DWORD LastClockUpdate;
|
||||
DWORD LastVerticalRefresh;
|
||||
INT KeyboardIntCounter = 0;
|
||||
|
||||
#ifdef IPS_DISPLAY
|
||||
DWORD LastCyclePrintout;
|
||||
DWORD Cycles = 0;
|
||||
#endif
|
||||
|
||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||
|
||||
VOID ClockUpdate(VOID)
|
||||
{
|
||||
extern BOOLEAN CpuSimulate;
|
||||
UINT i;
|
||||
|
||||
#ifdef WORKING_TIMER
|
||||
DWORD PitResolution = PitGetResolution();
|
||||
#endif
|
||||
DWORD RtcFrequency = RtcGetTicksPerSecond();
|
||||
|
||||
/* Get the current number of ticks */
|
||||
CurrentTickCount = GetTickCount();
|
||||
|
||||
#ifdef WORKING_TIMER
|
||||
if ((PitResolution <= 1000) && (RtcFrequency <= 1000))
|
||||
{
|
||||
/* Calculate the approximate performance counter value instead */
|
||||
Counter.QuadPart = StartPerfCount.QuadPart
|
||||
+ (CurrentTickCount - StartTickCount)
|
||||
* (Frequency.QuadPart / 1000);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* Get the current performance counter value */
|
||||
QueryPerformanceCounter(&Counter);
|
||||
}
|
||||
|
||||
/* Get the number of PIT ticks that have passed */
|
||||
TimerTicks = ((Counter.QuadPart - LastTimerTick.QuadPart)
|
||||
* PIT_BASE_FREQUENCY) / Frequency.QuadPart;
|
||||
|
||||
/* Update the PIT */
|
||||
if (TimerTicks > 0)
|
||||
{
|
||||
PitClock(TimerTicks);
|
||||
LastTimerTick = Counter;
|
||||
}
|
||||
|
||||
/* Check for RTC update */
|
||||
if ((CurrentTickCount - LastClockUpdate) >= 1000)
|
||||
{
|
||||
RtcTimeUpdate();
|
||||
LastClockUpdate = CurrentTickCount;
|
||||
}
|
||||
|
||||
/* Check for RTC periodic tick */
|
||||
if ((Counter.QuadPart - LastRtcTick.QuadPart)
|
||||
>= (Frequency.QuadPart / (LONGLONG)RtcFrequency))
|
||||
{
|
||||
RtcPeriodicTick();
|
||||
LastRtcTick = Counter;
|
||||
}
|
||||
|
||||
/* Check for vertical retrace */
|
||||
if ((CurrentTickCount - LastVerticalRefresh) >= 15)
|
||||
{
|
||||
VgaRefreshDisplay();
|
||||
LastVerticalRefresh = CurrentTickCount;
|
||||
}
|
||||
|
||||
if (++KeyboardIntCounter == KBD_INT_CYCLES)
|
||||
{
|
||||
GenerateKeyboardInterrupts();
|
||||
KeyboardIntCounter = 0;
|
||||
}
|
||||
|
||||
/* Horizontal retrace occurs as fast as possible */
|
||||
VgaHorizontalRetrace();
|
||||
|
||||
/* Continue CPU emulation */
|
||||
for (i = 0; VdmRunning && CpuSimulate && (i < STEPS_PER_CYCLE); i++)
|
||||
{
|
||||
EmulatorStep();
|
||||
#ifdef IPS_DISPLAY
|
||||
Cycles++;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef IPS_DISPLAY
|
||||
if ((CurrentTickCount - LastCyclePrintout) >= 1000)
|
||||
{
|
||||
DPRINT1("NTVDM: %lu Instructions Per Second; TimerTicks = %I64d\n", Cycles, TimerTicks);
|
||||
LastCyclePrintout = CurrentTickCount;
|
||||
Cycles = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOLEAN ClockInitialize(VOID)
|
||||
{
|
||||
/* Initialize the performance counter (needed for hardware timers) */
|
||||
if (!QueryPerformanceFrequency(&Frequency))
|
||||
{
|
||||
wprintf(L"FATAL: Performance counter not available\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Find the starting performance and tick count */
|
||||
StartTickCount = GetTickCount();
|
||||
QueryPerformanceCounter(&StartPerfCount);
|
||||
|
||||
/* Set the different last counts to the starting count */
|
||||
LastClockUpdate = LastVerticalRefresh =
|
||||
#ifdef IPS_DISPLAY
|
||||
LastCyclePrintout =
|
||||
#endif
|
||||
StartTickCount;
|
||||
|
||||
/* Set the last timer ticks to the current time */
|
||||
LastTimerTick = LastRtcTick = StartPerfCount;
|
||||
|
||||
return TRUE;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue