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)
10 /******************************************************************************\
11 | WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING!
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 \******************************************************************************/
18 /* INCLUDES *******************************************************************/
32 /* PRIVATE VARIABLES **********************************************************/
35 /* FIXME: Are we going to use this somewhere? */
38 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
39 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, // 13x nop
40 BOP(BOP_UNSIMULATE
), // UnSimulate16 BOP
42 C_ASSERT(sizeof(Yield
) == 16 * sizeof(BYTE
));
45 /* PUBLIC FUNCTIONS ***********************************************************/
48 InitializeContextEx(IN PCALLBACK16 Context
,
49 IN ULONG TrampolineSize
,
53 Context
->TrampolineFarPtr
= MAKELONG(Offset
, Segment
);
54 Context
->TrampolineSize
= max(TRAMPOLINE_SIZE
, TrampolineSize
);
55 Context
->Segment
= Segment
;
56 Context
->NextOffset
= Offset
+ Context
->TrampolineSize
;
60 InitializeContext(IN PCALLBACK16 Context
,
64 InitializeContextEx(Context
,
71 Call16(IN USHORT Segment
,
75 USHORT OrgCS
= getCS();
76 USHORT OrgIP
= getIP();
78 /* Set the new CS:IP */
82 DPRINT("Call16(%04X:%04X)\n", Segment
, Offset
);
84 /* Start CPU simulation */
93 RunCallback16(IN PCALLBACK16 Context
,
96 PUCHAR TrampolineBase
= (PUCHAR
)FAR_POINTER(Context
->TrampolineFarPtr
);
97 PUCHAR Trampoline
= TrampolineBase
;
98 UCHAR OldTrampoline
[TRAMPOLINE_SIZE
];
100 /* Save the old trampoline */
101 ((PULONGLONG
)&OldTrampoline
)[0] = ((PULONGLONG
)TrampolineBase
)[0];
103 DPRINT("RunCallback16(0x%p)\n", FarPtr
);
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
);
111 /* Perform the call */
112 Call16(HIWORD(Context
->TrampolineFarPtr
),
113 LOWORD(Context
->TrampolineFarPtr
));
115 /* Restore the old trampoline */
116 ((PULONGLONG
)TrampolineBase
)[0] = ((PULONGLONG
)&OldTrampoline
)[0];
120 RegisterCallback16(IN ULONG FarPtr
,
121 IN LPBYTE CallbackCode
,
122 IN SIZE_T CallbackSize
,
123 OUT PSIZE_T CodeSize OPTIONAL
)
125 LPBYTE CodeStart
= (LPBYTE
)FAR_POINTER(FarPtr
);
126 LPBYTE Code
= CodeStart
;
128 SIZE_T OurCodeSize
= CallbackSize
;
130 if (CallbackCode
== NULL
) CallbackSize
= 0;
134 /* 16-bit interrupt code */
135 RtlCopyMemory(Code
, CallbackCode
, CallbackSize
);
136 Code
+= CallbackSize
;
139 /* Return the real size of the code if needed */
140 if (CodeSize
) *CodeSize
= OurCodeSize
; // == (ULONG_PTR)Code - (ULONG_PTR)CodeStart;
142 // /* Return the entry-point address for 32-bit calls */
143 // return (ULONG_PTR)(CodeStart + CallbackSize);