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);
28 * FIXME: Interrupt handlers for interrupts implemented in other DLLs.
29 * These functions should be removed when the interrupt handlers have
30 * been moved to winedos.
32 void WINAPI DOSVM_Int11Handler( CONTEXT86 *context ) { INT_Int11Handler(context); }
33 void WINAPI DOSVM_Int12Handler( CONTEXT86 *context ) { INT_Int12Handler(context); }
34 void WINAPI DOSVM_Int13Handler( CONTEXT86 *context ) { INT_Int13Handler(context); }
35 void WINAPI DOSVM_Int15Handler( CONTEXT86 *context ) { INT_Int15Handler(context); }
36 void WINAPI DOSVM_Int1aHandler( CONTEXT86 *context ) { INT_Int1aHandler(context); }
37 void WINAPI DOSVM_Int25Handler( CONTEXT86 *context ) { INT_Int25Handler(context); }
38 void WINAPI DOSVM_Int26Handler( CONTEXT86 *context ) { INT_Int26Handler(context); }
39 void WINAPI DOSVM_Int2aHandler( CONTEXT86 *context ) { INT_Int2aHandler(context); }
40 void WINAPI DOSVM_Int2fHandler( CONTEXT86 *context ) { INT_Int2fHandler(context); }
41 void WINAPI DOSVM_Int34Handler( CONTEXT86 *context ) { INT_Int34Handler(context); }
42 void WINAPI DOSVM_Int35Handler( CONTEXT86 *context ) { INT_Int35Handler(context); }
43 void WINAPI DOSVM_Int36Handler( CONTEXT86 *context ) { INT_Int36Handler(context); }
44 void WINAPI DOSVM_Int37Handler( CONTEXT86 *context ) { INT_Int37Handler(context); }
45 void WINAPI DOSVM_Int38Handler( CONTEXT86 *context ) { INT_Int38Handler(context); }
46 void WINAPI DOSVM_Int39Handler( CONTEXT86 *context ) { INT_Int39Handler(context); }
47 void WINAPI DOSVM_Int3aHandler( CONTEXT86 *context ) { INT_Int3aHandler(context); }
48 void WINAPI DOSVM_Int3bHandler( CONTEXT86 *context ) { INT_Int3bHandler(context); }
49 void WINAPI DOSVM_Int3cHandler( CONTEXT86 *context ) { INT_Int3cHandler(context); }
50 void WINAPI DOSVM_Int3dHandler( CONTEXT86 *context ) { INT_Int3dHandler(context); }
51 void WINAPI DOSVM_Int3eHandler( CONTEXT86 *context ) { INT_Int3eHandler(context); }
52 void WINAPI DOSVM_Int41Handler( CONTEXT86 *context ) { INT_Int41Handler(context); }
53 void WINAPI DOSVM_Int4bHandler( CONTEXT86 *context ) { INT_Int4bHandler(context); }
54 void WINAPI DOSVM_Int5cHandler( CONTEXT86 *context ) { NetBIOSCall16(context); }
56 static FARPROC16 DOSVM_Vectors16[256];
57 static FARPROC48 DOSVM_Vectors48[256];
58 static const INTPROC DOSVM_VectorsBuiltin[] =
62 /* 08 */ 0, DOSVM_Int09Handler, 0, 0,
64 /* 10 */ DOSVM_Int10Handler, DOSVM_Int11Handler, DOSVM_Int12Handler, DOSVM_Int13Handler,
65 /* 14 */ 0, DOSVM_Int15Handler, DOSVM_Int16Handler, DOSVM_Int17Handler,
66 /* 18 */ 0, 0, DOSVM_Int1aHandler, 0,
68 /* 20 */ DOSVM_Int20Handler, DOSVM_Int21Handler, 0, 0,
69 /* 24 */ 0, DOSVM_Int25Handler, DOSVM_Int26Handler, 0,
70 /* 28 */ 0, DOSVM_Int29Handler, DOSVM_Int2aHandler, 0,
71 /* 2C */ 0, 0, 0, DOSVM_Int2fHandler,
72 /* 30 */ 0, DOSVM_Int31Handler, 0, DOSVM_Int33Handler,
73 /* 34 */ DOSVM_Int34Handler, DOSVM_Int35Handler, DOSVM_Int36Handler, DOSVM_Int37Handler,
74 /* 38 */ DOSVM_Int38Handler, DOSVM_Int39Handler, DOSVM_Int3aHandler, DOSVM_Int3bHandler,
75 /* 3C */ DOSVM_Int3cHandler, DOSVM_Int3dHandler, DOSVM_Int3eHandler, 0,
76 /* 40 */ 0, DOSVM_Int41Handler, 0, 0,
78 /* 48 */ 0, 0, 0, DOSVM_Int4bHandler,
83 /* 5C */ DOSVM_Int5cHandler, 0, 0, 0,
85 /* 64 */ 0, 0, 0, DOSVM_Int67Handler
88 /* Ordinal number for interrupt 0 handler in winedos16.dll */
89 #define FIRST_INTERRUPT 100
91 /**********************************************************************
92 * DOSVM_DefaultHandler
94 * Default interrupt handler. This will be used to emulate all
95 * interrupts that don't have their own interrupt handler.
97 void WINAPI DOSVM_DefaultHandler( CONTEXT86 *context )
101 /**********************************************************************
102 * DOSVM_EmulateInterruptPM
104 * Emulate software interrupt in 16-bit or 32-bit protected mode.
105 * Called from signal handler when intXX opcode is executed.
107 * Pushes interrupt frame to stack and changes instruction
108 * pointer to interrupt handler.
110 void WINAPI DOSVM_EmulateInterruptPM( CONTEXT86 *context, BYTE intnum )
114 if(context->SegCs == DOSVM_dpmi_segments->int48_sel)
116 else if(DOSVM_IsDos32())
118 else if(IS_SELECTOR_32BIT(context->SegCs)) {
119 WARN("Interrupt in 32-bit code and mode is not DPMI32\n");
126 FARPROC48 addr = DOSVM_GetPMHandler48( intnum );
127 DWORD *stack = CTX_SEG_OFF_TO_LIN(context, context->SegSs, context->Esp);
128 /* Push the flags and return address on the stack */
129 *(--stack) = context->EFlags;
130 *(--stack) = context->SegCs;
131 *(--stack) = context->Eip;
132 /* Jump to the interrupt handler */
133 context->SegCs = addr.selector;
134 context->Eip = addr.offset;
138 FARPROC16 addr = INT_GetPMHandler( intnum ); /* FIXME: DOSVM_GetPMHandler16 */
139 WORD *stack = CTX_SEG_OFF_TO_LIN(context, context->SegSs, context->Esp);
140 /* Push the flags and return address on the stack */
141 *(--stack) = LOWORD(context->EFlags);
142 *(--stack) = context->SegCs;
143 *(--stack) = LOWORD(context->Eip);
144 /* Jump to the interrupt handler */
145 context->SegCs = HIWORD(addr);
146 context->Eip = LOWORD(addr);
149 if (IS_SELECTOR_32BIT(context->SegSs))
150 context->Esp += islong ? -12 : -6;
152 ADD_LOWORD( context->Esp, islong ? -12 : -6 );
155 /**********************************************************************
158 * Return the real mode interrupt vector for a given interrupt.
160 FARPROC16 DOSVM_GetRMHandler( BYTE intnum )
162 return ((FARPROC16*)0)[intnum];
165 /**********************************************************************
168 * Set the real mode interrupt handler for a given interrupt.
170 void DOSVM_SetRMHandler( BYTE intnum, FARPROC16 handler )
172 TRACE("Set real mode interrupt vector %02x <- %04x:%04x\n",
173 intnum, HIWORD(handler), LOWORD(handler) );
174 ((FARPROC16*)0)[intnum] = handler;
177 /**********************************************************************
178 * DOSVM_GetPMHandler16
180 * Return the protected mode interrupt vector for a given interrupt.
182 FARPROC16 DOSVM_GetPMHandler16( BYTE intnum )
184 static HMODULE16 procs;
185 FARPROC16 handler = DOSVM_Vectors16[intnum];
190 (procs = GetModuleHandle16( "winedos16" )) < 32 &&
191 (procs = LoadLibrary16( "winedos16" )) < 32)
193 ERR("could not load winedos16.dll\n");
198 handler = GetProcAddress16( procs, (LPCSTR)(FIRST_INTERRUPT + intnum));
201 WARN("int%x not implemented, returning dummy handler\n", intnum );
202 handler = GetProcAddress16( procs, (LPCSTR)(FIRST_INTERRUPT + 256));
205 DOSVM_Vectors16[intnum] = handler;
212 /**********************************************************************
213 * DOSVM_SetPMHandler16
215 * Set the protected mode interrupt handler for a given interrupt.
217 void DOSVM_SetPMHandler16( BYTE intnum, FARPROC16 handler )
219 TRACE("Set protected mode interrupt vector %02x <- %04x:%04x\n",
220 intnum, HIWORD(handler), LOWORD(handler) );
221 DOSVM_Vectors16[intnum] = handler;
224 /**********************************************************************
225 * DOSVM_GetPMHandler48
227 * Return the protected mode interrupt vector for a given interrupt.
228 * Used to get 48-bit pointer for 32-bit interrupt handlers in DPMI32.
230 FARPROC48 DOSVM_GetPMHandler48( BYTE intnum )
232 if (!DOSVM_Vectors48[intnum].selector)
234 DOSVM_Vectors48[intnum].selector = DOSVM_dpmi_segments->int48_sel;
235 DOSVM_Vectors48[intnum].offset = 4 * intnum;
237 return DOSVM_Vectors48[intnum];
240 /**********************************************************************
241 * DOSVM_SetPMHandler48
243 * Set the protected mode interrupt handler for a given interrupt.
244 * Used to set 48-bit pointer for 32-bit interrupt handlers in DPMI32.
246 void DOSVM_SetPMHandler48( BYTE intnum, FARPROC48 handler )
248 TRACE("Set 32-bit protected mode interrupt vector %02x <- %04x:%08lx\n",
249 intnum, handler.selector, handler.offset );
250 DOSVM_Vectors48[intnum] = handler;
253 /**********************************************************************
254 * DOSVM_GetBuiltinHandler
256 * Return Wine interrupt handler procedure for a given interrupt.
258 INTPROC DOSVM_GetBuiltinHandler( BYTE intnum )
260 if (intnum < sizeof(DOSVM_VectorsBuiltin)/sizeof(INTPROC)) {
261 INTPROC proc = DOSVM_VectorsBuiltin[intnum];
266 WARN("int%x not implemented, returning dummy handler\n", intnum );
267 return DOSVM_DefaultHandler;