4 * Copyright 2002 Jukka Heinonen
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "wine/debug.h"
23 #include "wine/winbase16.h"
25 WINE_DEFAULT_DEBUG_CHANNEL(int);
27 /***********************************************************************
28 * DOSVM_Int11Handler (WINEDOS16.117)
29 * DOSVM_Int12Handler (WINEDOS16.118)
30 * DOSVM_Int13Handler (WINEDOS16.119)
31 * DOSVM_Int15Handler (WINEDOS16.121)
32 * DOSVM_Int1aHandler (WINEDOS16.126)
33 * DOSVM_Int25Handler (WINEDOS16.137)
34 * DOSVM_Int26Handler (WINEDOS16.138)
35 * DOSVM_Int2aHandler (WINEDOS16.142)
36 * DOSVM_Int2fHandler (WINEDOS16.147)
37 * DOSVM_Int34Handler (WINEDOS16.152)
38 * DOSVM_Int35Handler (WINEDOS16.153)
39 * DOSVM_Int36Handler (WINEDOS16.154)
40 * DOSVM_Int37Handler (WINEDOS16.155)
41 * DOSVM_Int38Handler (WINEDOS16.156)
42 * DOSVM_Int39Handler (WINEDOS16.157)
43 * DOSVM_Int3aHandler (WINEDOS16.158)
44 * DOSVM_Int3bHandler (WINEDOS16.159)
45 * DOSVM_Int3cHandler (WINEDOS16.160)
46 * DOSVM_Int3dHandler (WINEDOS16.161)
47 * DOSVM_Int3eHandler (WINEDOS16.162)
48 * DOSVM_Int41Handler (WINEDOS16.165)
49 * DOSVM_Int4bHandler (WINEDOS16.175)
50 * DOSVM_Int5cHandler (WINEDOS16.192)
52 * FIXME: Interrupt handlers for interrupts implemented in other DLLs.
53 * These functions should be removed when the interrupt handlers have
54 * been moved to winedos.
56 void WINAPI DOSVM_Int11Handler( CONTEXT86 *context ) { INT_Int11Handler(context); }
57 void WINAPI DOSVM_Int12Handler( CONTEXT86 *context ) { INT_Int12Handler(context); }
58 void WINAPI DOSVM_Int13Handler( CONTEXT86 *context ) { INT_Int13Handler(context); }
59 void WINAPI DOSVM_Int15Handler( CONTEXT86 *context ) { INT_Int15Handler(context); }
60 void WINAPI DOSVM_Int1aHandler( CONTEXT86 *context ) { INT_Int1aHandler(context); }
61 void WINAPI DOSVM_Int25Handler( CONTEXT86 *context ) { INT_Int25Handler(context); }
62 void WINAPI DOSVM_Int26Handler( CONTEXT86 *context ) { INT_Int26Handler(context); }
63 void WINAPI DOSVM_Int2aHandler( CONTEXT86 *context ) { INT_Int2aHandler(context); }
64 void WINAPI DOSVM_Int2fHandler( CONTEXT86 *context ) { INT_Int2fHandler(context); }
65 void WINAPI DOSVM_Int34Handler( CONTEXT86 *context ) { INT_Int34Handler(context); }
66 void WINAPI DOSVM_Int35Handler( CONTEXT86 *context ) { INT_Int35Handler(context); }
67 void WINAPI DOSVM_Int36Handler( CONTEXT86 *context ) { INT_Int36Handler(context); }
68 void WINAPI DOSVM_Int37Handler( CONTEXT86 *context ) { INT_Int37Handler(context); }
69 void WINAPI DOSVM_Int38Handler( CONTEXT86 *context ) { INT_Int38Handler(context); }
70 void WINAPI DOSVM_Int39Handler( CONTEXT86 *context ) { INT_Int39Handler(context); }
71 void WINAPI DOSVM_Int3aHandler( CONTEXT86 *context ) { INT_Int3aHandler(context); }
72 void WINAPI DOSVM_Int3bHandler( CONTEXT86 *context ) { INT_Int3bHandler(context); }
73 void WINAPI DOSVM_Int3cHandler( CONTEXT86 *context ) { INT_Int3cHandler(context); }
74 void WINAPI DOSVM_Int3dHandler( CONTEXT86 *context ) { INT_Int3dHandler(context); }
75 void WINAPI DOSVM_Int3eHandler( CONTEXT86 *context ) { INT_Int3eHandler(context); }
76 void WINAPI DOSVM_Int41Handler( CONTEXT86 *context ) { INT_Int41Handler(context); }
77 void WINAPI DOSVM_Int4bHandler( CONTEXT86 *context ) { INT_Int4bHandler(context); }
78 void WINAPI DOSVM_Int5cHandler( CONTEXT86 *context ) { NetBIOSCall16(context); }
80 static FARPROC16 DOSVM_Vectors16[256];
81 static FARPROC48 DOSVM_Vectors48[256];
82 static const INTPROC DOSVM_VectorsBuiltin[] =
86 /* 08 */ 0, DOSVM_Int09Handler, 0, 0,
88 /* 10 */ DOSVM_Int10Handler, DOSVM_Int11Handler, DOSVM_Int12Handler, DOSVM_Int13Handler,
89 /* 14 */ 0, DOSVM_Int15Handler, DOSVM_Int16Handler, DOSVM_Int17Handler,
90 /* 18 */ 0, 0, DOSVM_Int1aHandler, 0,
92 /* 20 */ DOSVM_Int20Handler, DOSVM_Int21Handler, 0, 0,
93 /* 24 */ 0, DOSVM_Int25Handler, DOSVM_Int26Handler, 0,
94 /* 28 */ 0, DOSVM_Int29Handler, DOSVM_Int2aHandler, 0,
95 /* 2C */ 0, 0, 0, DOSVM_Int2fHandler,
96 /* 30 */ 0, DOSVM_Int31Handler, 0, DOSVM_Int33Handler,
97 /* 34 */ DOSVM_Int34Handler, DOSVM_Int35Handler, DOSVM_Int36Handler, DOSVM_Int37Handler,
98 /* 38 */ DOSVM_Int38Handler, DOSVM_Int39Handler, DOSVM_Int3aHandler, DOSVM_Int3bHandler,
99 /* 3C */ DOSVM_Int3cHandler, DOSVM_Int3dHandler, DOSVM_Int3eHandler, 0,
100 /* 40 */ 0, DOSVM_Int41Handler, 0, 0,
102 /* 48 */ 0, 0, 0, DOSVM_Int4bHandler,
107 /* 5C */ DOSVM_Int5cHandler, 0, 0, 0,
109 /* 64 */ 0, 0, 0, DOSVM_Int67Handler
112 /* Ordinal number for interrupt 0 handler in winedos16.dll */
113 #define FIRST_INTERRUPT 100
115 /**********************************************************************
116 * DOSVM_DefaultHandler (WINEDOS16.356)
118 * Default interrupt handler. This will be used to emulate all
119 * interrupts that don't have their own interrupt handler.
121 void WINAPI DOSVM_DefaultHandler( CONTEXT86 *context )
125 /**********************************************************************
126 * DOSVM_EmulateInterruptPM
128 * Emulate software interrupt in 16-bit or 32-bit protected mode.
129 * Called from signal handler when intXX opcode is executed.
131 * Pushes interrupt frame to stack and changes instruction
132 * pointer to interrupt handler.
134 void WINAPI DOSVM_EmulateInterruptPM( CONTEXT86 *context, BYTE intnum )
138 if(context->SegCs == DOSVM_dpmi_segments->int48_sel)
140 else if(DOSVM_IsDos32())
142 else if(IS_SELECTOR_32BIT(context->SegCs)) {
143 WARN("Interrupt in 32-bit code and mode is not DPMI32\n");
150 FARPROC48 addr = DOSVM_GetPMHandler48( intnum );
151 DWORD *stack = CTX_SEG_OFF_TO_LIN(context, context->SegSs, context->Esp);
152 /* Push the flags and return address on the stack */
153 *(--stack) = context->EFlags;
154 *(--stack) = context->SegCs;
155 *(--stack) = context->Eip;
156 /* Jump to the interrupt handler */
157 context->SegCs = addr.selector;
158 context->Eip = addr.offset;
162 FARPROC16 addr = INT_GetPMHandler( intnum ); /* FIXME: DOSVM_GetPMHandler16 */
163 WORD *stack = CTX_SEG_OFF_TO_LIN(context, context->SegSs, context->Esp);
164 /* Push the flags and return address on the stack */
165 *(--stack) = LOWORD(context->EFlags);
166 *(--stack) = context->SegCs;
167 *(--stack) = LOWORD(context->Eip);
168 /* Jump to the interrupt handler */
169 context->SegCs = HIWORD(addr);
170 context->Eip = LOWORD(addr);
173 if (IS_SELECTOR_32BIT(context->SegSs))
174 context->Esp += islong ? -12 : -6;
176 ADD_LOWORD( context->Esp, islong ? -12 : -6 );
179 /**********************************************************************
182 * Return the real mode interrupt vector for a given interrupt.
184 FARPROC16 DOSVM_GetRMHandler( BYTE intnum )
186 return ((FARPROC16*)0)[intnum];
189 /**********************************************************************
192 * Set the real mode interrupt handler for a given interrupt.
194 void DOSVM_SetRMHandler( BYTE intnum, FARPROC16 handler )
196 TRACE("Set real mode interrupt vector %02x <- %04x:%04x\n",
197 intnum, HIWORD(handler), LOWORD(handler) );
198 ((FARPROC16*)0)[intnum] = handler;
201 /**********************************************************************
202 * DOSVM_GetPMHandler16
204 * Return the protected mode interrupt vector for a given interrupt.
206 FARPROC16 DOSVM_GetPMHandler16( BYTE intnum )
208 static HMODULE16 procs;
209 FARPROC16 handler = DOSVM_Vectors16[intnum];
214 (procs = GetModuleHandle16( "winedos16" )) < 32 &&
215 (procs = LoadLibrary16( "winedos16" )) < 32)
217 ERR("could not load winedos16.dll\n");
222 handler = GetProcAddress16( procs, (LPCSTR)(FIRST_INTERRUPT + intnum));
225 WARN("int%x not implemented, returning dummy handler\n", intnum );
226 handler = GetProcAddress16( procs, (LPCSTR)(FIRST_INTERRUPT + 256));
229 DOSVM_Vectors16[intnum] = handler;
236 /**********************************************************************
237 * DOSVM_SetPMHandler16
239 * Set the protected mode interrupt handler for a given interrupt.
241 void DOSVM_SetPMHandler16( BYTE intnum, FARPROC16 handler )
243 TRACE("Set protected mode interrupt vector %02x <- %04x:%04x\n",
244 intnum, HIWORD(handler), LOWORD(handler) );
245 DOSVM_Vectors16[intnum] = handler;
248 /**********************************************************************
249 * DOSVM_GetPMHandler48
251 * Return the protected mode interrupt vector for a given interrupt.
252 * Used to get 48-bit pointer for 32-bit interrupt handlers in DPMI32.
254 FARPROC48 DOSVM_GetPMHandler48( BYTE intnum )
256 if (!DOSVM_Vectors48[intnum].selector)
258 DOSVM_Vectors48[intnum].selector = DOSVM_dpmi_segments->int48_sel;
259 DOSVM_Vectors48[intnum].offset = 6 * intnum;
261 return DOSVM_Vectors48[intnum];
264 /**********************************************************************
265 * DOSVM_SetPMHandler48
267 * Set the protected mode interrupt handler for a given interrupt.
268 * Used to set 48-bit pointer for 32-bit interrupt handlers in DPMI32.
270 void DOSVM_SetPMHandler48( BYTE intnum, FARPROC48 handler )
272 TRACE("Set 32-bit protected mode interrupt vector %02x <- %04x:%08lx\n",
273 intnum, handler.selector, handler.offset );
274 DOSVM_Vectors48[intnum] = handler;
277 /**********************************************************************
278 * DOSVM_GetBuiltinHandler
280 * Return Wine interrupt handler procedure for a given interrupt.
282 INTPROC DOSVM_GetBuiltinHandler( BYTE intnum )
284 if (intnum < sizeof(DOSVM_VectorsBuiltin)/sizeof(INTPROC)) {
285 INTPROC proc = DOSVM_VectorsBuiltin[intnum];
290 WARN("int%x not implemented, returning dummy handler\n", intnum );
291 return DOSVM_DefaultHandler;