mirror of
https://github.com/reactos/reactos.git
synced 2024-08-19 18:02:55 +00:00
148 lines
4.1 KiB
C
148 lines
4.1 KiB
C
/*
|
|
* COPYRIGHT: GPL - See COPYING in the top level directory
|
|
* PROJECT: ReactOS Virtual DOS Machine
|
|
* FILE: subsystems/mvdm/ntvdm/cpu/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)
|
|
*/
|
|
|
|
/******************************************************************************\
|
|
| WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING!
|
|
|
|
|
| Callbacks support supposes implicitly that the callbacks are used
|
|
| in the SAME thread as the CPU thread, otherwise messing in parallel
|
|
| with the CPU registers is 100% prone to bugs!!
|
|
\******************************************************************************/
|
|
|
|
/* INCLUDES *******************************************************************/
|
|
|
|
#include "ntvdm.h"
|
|
|
|
#define NDEBUG
|
|
#include <debug.h>
|
|
|
|
#include "emulator.h"
|
|
#include "callback.h"
|
|
|
|
#include "cpu.h"
|
|
#include "bop.h"
|
|
#include <isvbop.h>
|
|
|
|
/* PRIVATE VARIABLES **********************************************************/
|
|
|
|
#if 0
|
|
/* FIXME: Are we going to use this somewhere? */
|
|
static BYTE Yield[] =
|
|
{
|
|
0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
|
|
0x90, 0x90, 0x90, 0x90, 0x90, 0x90, // 13x nop
|
|
BOP(BOP_UNSIMULATE), // UnSimulate16 BOP
|
|
};
|
|
C_ASSERT(sizeof(Yield) == 16 * sizeof(BYTE));
|
|
#endif
|
|
|
|
/* PUBLIC FUNCTIONS ***********************************************************/
|
|
|
|
VOID
|
|
InitializeContextEx(IN PCALLBACK16 Context,
|
|
IN ULONG TrampolineSize,
|
|
IN USHORT Segment,
|
|
IN USHORT Offset)
|
|
{
|
|
Context->TrampolineFarPtr = MAKELONG(Offset, Segment);
|
|
Context->TrampolineSize = max(TRAMPOLINE_SIZE, TrampolineSize);
|
|
Context->Segment = Segment;
|
|
Context->NextOffset = Offset + Context->TrampolineSize;
|
|
}
|
|
|
|
VOID
|
|
InitializeContext(IN PCALLBACK16 Context,
|
|
IN USHORT Segment,
|
|
IN USHORT Offset)
|
|
{
|
|
InitializeContextEx(Context,
|
|
TRAMPOLINE_SIZE,
|
|
Segment,
|
|
Offset);
|
|
}
|
|
|
|
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 */
|
|
CpuSimulate();
|
|
|
|
/* Restore CS:IP */
|
|
setCS(OrgCS);
|
|
setIP(OrgIP);
|
|
}
|
|
|
|
VOID
|
|
RunCallback16(IN PCALLBACK16 Context,
|
|
IN ULONG FarPtr)
|
|
{
|
|
PUCHAR TrampolineBase = (PUCHAR)FAR_POINTER(Context->TrampolineFarPtr);
|
|
PUCHAR Trampoline = TrampolineBase;
|
|
UCHAR OldTrampoline[TRAMPOLINE_SIZE];
|
|
|
|
/* Save the old trampoline */
|
|
((PULONGLONG)&OldTrampoline)[0] = ((PULONGLONG)TrampolineBase)[0];
|
|
|
|
DPRINT("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
|
|
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;
|
|
}
|
|
|
|
/* EOF */
|