ReactOS  0.4.13-dev-982-g9853eab
int32.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/int32.c
5  * PURPOSE: 32-bit Interrupt Handlers
6  * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
7  * Hermes Belusca-Maito (hermes.belusca@sfr.fr)
8  */
9 
10 /* INCLUDES *******************************************************************/
11 
12 #include "ntvdm.h"
13 
14 #define NDEBUG
15 #include <debug.h>
16 
17 #include "emulator.h"
18 #include "int32.h"
19 
20 #include "cpu/bop.h"
21 #include <isvbop.h>
22 
23 /* PRIVATE VARIABLES **********************************************************/
24 
25 /*
26  * This is the list of registered 32-bit Interrupt handlers.
27  */
29 
30 /* BOP Identifiers */
31 #define BOP_CONTROL 0xFF // Control BOP Handler
32  #define BOP_CONTROL_DEFFUNC 0x00 // Default Control BOP Function
33  #define BOP_CONTROL_INT32 0xFF // 32-bit Interrupt dispatcher
34 
35 #define INT16_TRAMPOLINE_SIZE sizeof(ULONGLONG) // == TRAMPOLINE_SIZE
36 
37 /* 16-bit generic interrupt code for calling a 32-bit interrupt handler */
38 static BYTE Int16To32[] =
39 {
40  0xFA, // cli
41 
42  /* Push the value of the interrupt to be called */
43  0x6A, 0xFF, // push i (patchable to 0x6A, 0xIntNum)
44 
45  0xF8, // clc
46 
47  /* The BOP Sequence */
48 // BOP_SEQ:
49  BOP(BOP_CONTROL), // Control BOP
50  BOP_CONTROL_INT32, // 32-bit Interrupt dispatcher
51 
52  0x73, 0x04, // jnc EXIT (offset +4)
53 
54  0xFB, // sti
55 
56  0xF4, // hlt
57 
58  0xEB, 0xF6, // jmp BOP_SEQ (offset -10)
59 
60 // EXIT:
61  0x44, 0x44, // inc sp, inc sp
62  0xCF, // iret
63 };
65 
66 /* PUBLIC FUNCTIONS ***********************************************************/
67 
69 {
70  /* Get the interrupt number */
71  BYTE IntNum = LOBYTE(Stack[STACK_INT_NUM]);
72 
73  /* Call the 32-bit Interrupt handler */
74  if (Int32Proc[IntNum] != NULL)
75  Int32Proc[IntNum](Stack);
76  else
77  DPRINT1("Unhandled 32-bit interrupt: 0x%02X, AX = 0x%04X\n", IntNum, getAX());
78 }
79 
81 {
82  /* Get the Function Number and skip it */
83  BYTE FuncNum = *(PBYTE)SEG_OFF_TO_PTR(getCS(), getIP());
84  setIP(getIP() + 1);
85 
86  switch (FuncNum)
87  {
88  case BOP_CONTROL_INT32:
89  Int32Dispatch(Stack);
90  break;
91 
92  default:
93  // DPRINT1("Unassigned Control BOP Function: 0x%02X\n", FuncNum);
94  DisplayMessage(L"Unassigned Control BOP Function: 0x%02X", FuncNum);
95  break;
96  }
97 }
98 
99 ULONG
101  IN BYTE IntNumber,
102  IN LPBYTE CallbackCode,
103  IN SIZE_T CallbackSize,
104  OUT PSIZE_T CodeSize OPTIONAL)
105 {
106  /* Get a pointer to the IVT and set the corresponding entry (far pointer) */
107  LPDWORD IntVecTable = (LPDWORD)SEG_OFF_TO_PTR(0x0000, 0x0000);
108  IntVecTable[IntNumber] = FarPtr;
109 
110  /* Register the 16-bit callback */
111  return RegisterCallback16(FarPtr,
112  CallbackCode,
113  CallbackSize,
114  CodeSize);
115 }
116 
117 ULONG
119  IN BYTE IntNumber,
120  IN EMULATOR_INT32_PROC IntHandler,
121  OUT PSIZE_T CodeSize OPTIONAL)
122 {
123  /* Array for holding our copy of the 16-bit interrupt callback */
124  BYTE IntCallback[sizeof(Int16To32)/sizeof(BYTE)];
125 
126  /* Check whether the 32-bit interrupt was already registered */
127 #if 0
128  if (Int32Proc[IntNumber] != NULL)
129  {
130  DPRINT1("RegisterInt32: Interrupt 0x%02X already registered!\n", IntNumber);
131  return 0;
132  }
133 #endif
134 
135  /* Register the 32-bit interrupt handler */
136  Int32Proc[IntNumber] = IntHandler;
137 
138  /* Copy the generic 16-bit interrupt callback and patch it */
139  RtlCopyMemory(IntCallback, Int16To32, sizeof(Int16To32));
140  IntCallback[2] = IntNumber;
141 
142  /* Register the 16-bit interrupt callback */
143  return RegisterInt16(FarPtr,
144  IntNumber,
145  IntCallback,
146  sizeof(IntCallback),
147  CodeSize);
148 }
149 
150 VOID
152  IN BYTE IntNumber)
153 {
154  /*
155  * TODO: This function has almost the same code as RunCallback16.
156  * Something that may be nice is to have a common interface to
157  * build the trampoline...
158  */
159 
160  PUCHAR TrampolineBase = (PUCHAR)FAR_POINTER(Context->TrampolineFarPtr);
161  PUCHAR Trampoline = TrampolineBase;
162  UCHAR OldTrampoline[INT16_TRAMPOLINE_SIZE];
163 
164  DPRINT("Int32Call(0x%02X)\n", IntNumber);
165 
166  ASSERT(Context->TrampolineSize == INT16_TRAMPOLINE_SIZE);
167 
168  /* Save the old trampoline */
169  ((PULONGLONG)&OldTrampoline)[0] = ((PULONGLONG)TrampolineBase)[0];
170 
171  /* Build the generic entry-point for 16-bit calls */
172  if (IntNumber == 0x03)
173  {
174  /* We are redefining for INT 03h */
175  *Trampoline++ = 0xCC; // Call INT 03h
177  }
178  else
179  {
180  /* Normal interrupt */
181  *Trampoline++ = 0xCD; // Call INT XXh
182  *Trampoline++ = IntNumber;
183  }
184  UnSimulate16(Trampoline);
185 
186  /* Perform the call */
187  Call16(HIWORD(Context->TrampolineFarPtr),
188  LOWORD(Context->TrampolineFarPtr));
189 
190  /* Restore the old trampoline */
191  ((PULONGLONG)TrampolineBase)[0] = ((PULONGLONG)&OldTrampoline)[0];
192 }
193 
195 {
196  /* Register the Control BOP */
198 }
199 
200 /* EOF */
#define STACK_INT_NUM
Definition: int32.h:30
#define IN
Definition: typedefs.h:38
VOID WINAPI setIP(USHORT)
Definition: registers.c:471
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define LOBYTE(W)
Definition: jmemdos.c:487
VOID RegisterBop(BYTE BopCode, EMULATOR_BOP_PROC BopHandler)
Definition: bop.c:29
unsigned char * PUCHAR
Definition: retypes.h:3
VOID Int32Call(IN PCALLBACK16 Context, IN BYTE IntNumber)
Definition: int32.c:151
ULONG RegisterCallback16(IN ULONG FarPtr, IN LPBYTE CallbackCode, IN SIZE_T CallbackSize, OUT PSIZE_T CodeSize OPTIONAL)
Definition: callback.c:120
#define SEG_OFF_TO_PTR(seg, off)
Definition: emulator.h:28
static EMULATOR_INT32_PROC Int32Proc[EMULATOR_MAX_INT32_NUM]
Definition: int32.c:28
static BYTE Int16To32[]
Definition: int32.c:38
unsigned char * LPBYTE
Definition: typedefs.h:52
static VOID WINAPI ControlBop(LPWORD Stack)
Definition: int32.c:80
ULONG_PTR * PSIZE_T
Definition: typedefs.h:78
ULONG RegisterInt32(IN ULONG FarPtr, IN BYTE IntNumber, IN EMULATOR_INT32_PROC IntHandler, OUT PSIZE_T CodeSize OPTIONAL)
Definition: int32.c:118
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
#define Int16To32StubSize
Definition: int32.h:38
#define FAR_POINTER(x)
Definition: emulator.h:31
USHORT WINAPI getIP(VOID)
Definition: registers.c:464
#define WINAPI
Definition: msvc.h:8
C_ASSERT(sizeof(Int16To32)==Int16To32StubSize)
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define BOP_CONTROL_INT32
Definition: int32.c:33
unsigned char UCHAR
Definition: xmlstorage.h:181
static VOID WINAPI Int32Dispatch(LPWORD Stack)
Definition: int32.c:68
#define LPDWORD
Definition: nt_native.h:46
static const WCHAR L[]
Definition: oid.c:1250
USHORT WINAPI getAX(VOID)
Definition: registers.c:114
unsigned char BYTE
Definition: mem.h:68
#define BOP(num)
Definition: callback.h:15
uint16_t * LPWORD
Definition: typedefs.h:54
#define INT16_TRAMPOLINE_SIZE
Definition: int32.c:35
ULONG_PTR SIZE_T
Definition: typedefs.h:78
#define UnSimulate16(trap)
Definition: callback.h:16
#define DPRINT1
Definition: precomp.h:8
VOID(WINAPI * EMULATOR_INT32_PROC)(LPWORD Stack)
Definition: int32.h:42
#define OUT
Definition: typedefs.h:39
VOID InitializeInt32(VOID)
Definition: int32.c:194
__GNU_EXTENSION typedef unsigned __int64 * PULONGLONG
Definition: ntbasedef.h:390
uint32_t * LPDWORD
Definition: typedefs.h:57
#define HIWORD(l)
Definition: typedefs.h:246
unsigned int ULONG
Definition: retypes.h:1
void DisplayMessage(BOOL bConsole, BOOL bSilent, LPCTSTR lpMessage, LPCTSTR lpTitle, UINT uType)
Definition: regsvr32.c:239
VOID Call16(IN USHORT Segment, IN USHORT Offset)
Definition: callback.c:71
USHORT WINAPI getCS(VOID)
Definition: registers.c:480
BYTE * PBYTE
Definition: pedump.c:66
#define LOWORD(l)
Definition: pedump.c:82
#define EMULATOR_MAX_INT32_NUM
Definition: int32.h:20
ULONG RegisterInt16(IN ULONG FarPtr, IN BYTE IntNumber, IN LPBYTE CallbackCode, IN SIZE_T CallbackSize, OUT PSIZE_T CodeSize OPTIONAL)
Definition: int32.c:100
#define BOP_CONTROL
Definition: int32.c:31
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68