ReactOS  0.4.14-dev-317-g96040ec
callback.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: GPL - See COPYING in the top level directory
3  * PROJECT: ReactOS Virtual DOS Machine
4  * FILE: subsystems/mvdm/ntvdm/cpu/callback.c
5  * PURPOSE: 16 and 32-bit Callbacks Support
6  * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
7  * Hermes Belusca-Maito (hermes.belusca@sfr.fr)
8  */
9 
10 /******************************************************************************\
11 | WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING!
12 |
13 | Callbacks support supposes implicitly that the callbacks are used
14 | in the SAME thread as the CPU thread, otherwise messing in parallel
15 | with the CPU registers is 100% prone to bugs!!
16 \******************************************************************************/
17 
18 /* INCLUDES *******************************************************************/
19 
20 #include "ntvdm.h"
21 
22 #define NDEBUG
23 #include <debug.h>
24 
25 #include "emulator.h"
26 #include "callback.h"
27 
28 #include "cpu.h"
29 #include "bop.h"
30 #include <isvbop.h>
31 
32 /* PRIVATE VARIABLES **********************************************************/
33 
34 #if 0
35 /* FIXME: Are we going to use this somewhere? */
36 static BYTE Yield[] =
37 {
38  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
39  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, // 13x nop
40  BOP(BOP_UNSIMULATE), // UnSimulate16 BOP
41 };
42 C_ASSERT(sizeof(Yield) == 16 * sizeof(BYTE));
43 #endif
44 
45 /* PUBLIC FUNCTIONS ***********************************************************/
46 
47 VOID
49  IN ULONG TrampolineSize,
52 {
53  Context->TrampolineFarPtr = MAKELONG(Offset, Segment);
54  Context->TrampolineSize = max(TRAMPOLINE_SIZE, TrampolineSize);
55  Context->Segment = Segment;
56  Context->NextOffset = Offset + Context->TrampolineSize;
57 }
58 
59 VOID
63 {
66  Segment,
67  Offset);
68 }
69 
70 VOID
73 {
74  /* Save CS:IP */
75  USHORT OrgCS = getCS();
76  USHORT OrgIP = getIP();
77 
78  /* Set the new CS:IP */
79  setCS(Segment);
80  setIP(Offset);
81 
82  DPRINT("Call16(%04X:%04X)\n", Segment, Offset);
83 
84  /* Start CPU simulation */
85  CpuSimulate();
86 
87  /* Restore CS:IP */
88  setCS(OrgCS);
89  setIP(OrgIP);
90 }
91 
92 VOID
94  IN ULONG FarPtr)
95 {
96  PUCHAR TrampolineBase = (PUCHAR)FAR_POINTER(Context->TrampolineFarPtr);
97  PUCHAR Trampoline = TrampolineBase;
98  UCHAR OldTrampoline[TRAMPOLINE_SIZE];
99 
100  /* Save the old trampoline */
101  ((PULONGLONG)&OldTrampoline)[0] = ((PULONGLONG)TrampolineBase)[0];
102 
103  DPRINT("RunCallback16(0x%p)\n", FarPtr);
104 
105  /* Build the generic entry-point for 16-bit far calls */
106  *Trampoline++ = 0x9A; // Call far seg:off
107  *(PULONG)Trampoline = FarPtr;
108  Trampoline += sizeof(ULONG);
109  UnSimulate16(Trampoline);
110 
111  /* Perform the call */
112  Call16(HIWORD(Context->TrampolineFarPtr),
113  LOWORD(Context->TrampolineFarPtr));
114 
115  /* Restore the old trampoline */
116  ((PULONGLONG)TrampolineBase)[0] = ((PULONGLONG)&OldTrampoline)[0];
117 }
118 
119 ULONG
121  IN LPBYTE CallbackCode,
122  IN SIZE_T CallbackSize,
123  OUT PSIZE_T CodeSize OPTIONAL)
124 {
125  LPBYTE CodeStart = (LPBYTE)FAR_POINTER(FarPtr);
126  LPBYTE Code = CodeStart;
127 
128  SIZE_T OurCodeSize = CallbackSize;
129 
130  if (CallbackCode == NULL) CallbackSize = 0;
131 
132  if (CallbackCode)
133  {
134  /* 16-bit interrupt code */
135  RtlCopyMemory(Code, CallbackCode, CallbackSize);
136  Code += CallbackSize;
137  }
138 
139  /* Return the real size of the code if needed */
140  if (CodeSize) *CodeSize = OurCodeSize; // == (ULONG_PTR)Code - (ULONG_PTR)CodeStart;
141 
142  // /* Return the entry-point address for 32-bit calls */
143  // return (ULONG_PTR)(CodeStart + CallbackSize);
144  return OurCodeSize;
145 }
146 
147 /* EOF */
#define Yield()
Definition: winbase.h:3294
#define IN
Definition: typedefs.h:38
#define max(a, b)
Definition: svc.c:63
VOID WINAPI setIP(USHORT)
Definition: registers.c:471
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
unsigned char * PUCHAR
Definition: retypes.h:3
VOID InitializeContext(IN PCALLBACK16 Context, IN USHORT Segment, IN USHORT Offset)
Definition: callback.c:60
#define BOP_UNSIMULATE
Definition: isvbop.h:31
ULONG RegisterCallback16(IN ULONG FarPtr, IN LPBYTE CallbackCode, IN SIZE_T CallbackSize, OUT PSIZE_T CodeSize OPTIONAL)
Definition: callback.c:120
VOID CpuSimulate(VOID)
Definition: cpu.c:167
unsigned char * LPBYTE
Definition: typedefs.h:52
ULONG_PTR * PSIZE_T
Definition: typedefs.h:78
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define MAKELONG(a, b)
Definition: typedefs.h:248
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
#define FAR_POINTER(x)
Definition: emulator.h:31
#define C_ASSERT(e)
Definition: intsafe.h:79
_Inout_ PVOID Segment
Definition: exfuncs.h:893
#define Code
Definition: deflate.h:80
USHORT WINAPI getIP(VOID)
Definition: registers.c:464
unsigned char UCHAR
Definition: xmlstorage.h:181
unsigned char BYTE
Definition: mem.h:68
#define BOP(num)
Definition: callback.h:15
VOID WINAPI setCS(USHORT)
Definition: registers.c:487
ULONG_PTR SIZE_T
Definition: typedefs.h:78
unsigned short USHORT
Definition: pedump.c:61
unsigned int * PULONG
Definition: retypes.h:1
#define UnSimulate16(trap)
Definition: callback.h:16
VOID RunCallback16(IN PCALLBACK16 Context, IN ULONG FarPtr)
Definition: callback.c:93
VOID InitializeContextEx(IN PCALLBACK16 Context, IN ULONG TrampolineSize, IN USHORT Segment, IN USHORT Offset)
Definition: callback.c:48
#define OUT
Definition: typedefs.h:39
__GNU_EXTENSION typedef unsigned __int64 * PULONGLONG
Definition: ntbasedef.h:390
#define HIWORD(l)
Definition: typedefs.h:246
unsigned int ULONG
Definition: retypes.h:1
#define TRAMPOLINE_SIZE
Definition: callback.h:24
VOID Call16(IN USHORT Segment, IN USHORT Offset)
Definition: callback.c:71
USHORT WINAPI getCS(VOID)
Definition: registers.c:480
#define LOWORD(l)
Definition: pedump.c:82
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68