- Moved GetUrlCacheEntryInfoA and CommitUrlCacheEntryA to urlcache.c.
[wine/testsucceed.git] / dlls / winedos / interrupts.c
blob8013f0f2dd44858eafdf97da6b90e99677445559
1 /*
2 * Interrupt emulation
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
21 #include "dosexe.h"
22 #include "wine/debug.h"
23 #include "wine/winbase16.h"
25 WINE_DEFAULT_DEBUG_CHANNEL(int);
27 static FARPROC16 DOSVM_Vectors16[256];
28 static FARPROC48 DOSVM_Vectors48[256];
29 static const INTPROC DOSVM_VectorsBuiltin[] =
31 /* 00 */ 0, 0, 0, 0,
32 /* 04 */ 0, 0, 0, 0,
33 /* 08 */ 0, DOSVM_Int09Handler, 0, 0,
34 /* 0C */ 0, 0, 0, 0,
35 /* 10 */ DOSVM_Int10Handler, DOSVM_Int11Handler, DOSVM_Int12Handler, DOSVM_Int13Handler,
36 /* 14 */ 0, DOSVM_Int15Handler, DOSVM_Int16Handler, DOSVM_Int17Handler,
37 /* 18 */ 0, 0, DOSVM_Int1aHandler, 0,
38 /* 1C */ 0, 0, 0, 0,
39 /* 20 */ DOSVM_Int20Handler, DOSVM_Int21Handler, 0, 0,
40 /* 24 */ 0, DOSVM_Int25Handler, DOSVM_Int26Handler, 0,
41 /* 28 */ 0, DOSVM_Int29Handler, DOSVM_Int2aHandler, 0,
42 /* 2C */ 0, 0, 0, DOSVM_Int2fHandler,
43 /* 30 */ 0, DOSVM_Int31Handler, 0, DOSVM_Int33Handler,
44 /* 34 */ DOSVM_Int34Handler, DOSVM_Int35Handler, DOSVM_Int36Handler, DOSVM_Int37Handler,
45 /* 38 */ DOSVM_Int38Handler, DOSVM_Int39Handler, DOSVM_Int3aHandler, DOSVM_Int3bHandler,
46 /* 3C */ DOSVM_Int3cHandler, DOSVM_Int3dHandler, DOSVM_Int3eHandler, 0,
47 /* 40 */ 0, DOSVM_Int41Handler, 0, 0,
48 /* 44 */ 0, 0, 0, 0,
49 /* 48 */ 0, 0, 0, DOSVM_Int4bHandler,
50 /* 4C */ 0, 0, 0, 0,
51 /* 50 */ 0, 0, 0, 0,
52 /* 54 */ 0, 0, 0, 0,
53 /* 58 */ 0, 0, 0, 0,
54 /* 5C */ DOSVM_Int5cHandler, 0, 0, 0,
55 /* 60 */ 0, 0, 0, 0,
56 /* 64 */ 0, 0, 0, DOSVM_Int67Handler
59 /* Ordinal number for interrupt 0 handler in winedos16.dll */
60 #define FIRST_INTERRUPT 100
62 /**********************************************************************
63 * DOSVM_DefaultHandler (WINEDOS16.356)
65 * Default interrupt handler. This will be used to emulate all
66 * interrupts that don't have their own interrupt handler.
68 void WINAPI DOSVM_DefaultHandler( CONTEXT86 *context )
72 /**********************************************************************
73 * DOSVM_EmulateInterruptPM
75 * Emulate software interrupt in 16-bit or 32-bit protected mode.
76 * Called from signal handler when intXX opcode is executed.
78 * Pushes interrupt frame to stack and changes instruction
79 * pointer to interrupt handler.
81 void WINAPI DOSVM_EmulateInterruptPM( CONTEXT86 *context, BYTE intnum )
83 BOOL islong;
85 if(context->SegCs == DOSVM_dpmi_segments->int48_sel)
86 islong = FALSE;
87 else if(context->SegCs == DOSVM_dpmi_segments->dpmi_sel)
88 islong = FALSE;
89 else if(DOSVM_IsDos32())
90 islong = TRUE;
91 else if(IS_SELECTOR_32BIT(context->SegCs)) {
92 WARN("Interrupt in 32-bit code and mode is not DPMI32\n");
93 islong = TRUE;
94 } else
95 islong = FALSE;
97 if(islong)
99 FARPROC48 addr = DOSVM_GetPMHandler48( intnum );
100 DWORD *stack = CTX_SEG_OFF_TO_LIN(context, context->SegSs, context->Esp);
101 /* Push the flags and return address on the stack */
102 *(--stack) = context->EFlags;
103 *(--stack) = context->SegCs;
104 *(--stack) = context->Eip;
105 /* Jump to the interrupt handler */
106 context->SegCs = addr.selector;
107 context->Eip = addr.offset;
109 else
111 FARPROC16 addr = DOSVM_GetPMHandler16( intnum );
112 WORD *stack = CTX_SEG_OFF_TO_LIN(context, context->SegSs, context->Esp);
113 /* Push the flags and return address on the stack */
114 *(--stack) = LOWORD(context->EFlags);
115 *(--stack) = context->SegCs;
116 *(--stack) = LOWORD(context->Eip);
117 /* Jump to the interrupt handler */
118 context->SegCs = HIWORD(addr);
119 context->Eip = LOWORD(addr);
122 if (IS_SELECTOR_32BIT(context->SegSs))
123 context->Esp += islong ? -12 : -6;
124 else
125 ADD_LOWORD( context->Esp, islong ? -12 : -6 );
128 /**********************************************************************
129 * DOSVM_GetRMHandler
131 * Return the real mode interrupt vector for a given interrupt.
133 FARPROC16 DOSVM_GetRMHandler( BYTE intnum )
135 return ((FARPROC16*)0)[intnum];
138 /**********************************************************************
139 * DOSVM_SetRMHandler
141 * Set the real mode interrupt handler for a given interrupt.
143 void DOSVM_SetRMHandler( BYTE intnum, FARPROC16 handler )
145 TRACE("Set real mode interrupt vector %02x <- %04x:%04x\n",
146 intnum, HIWORD(handler), LOWORD(handler) );
147 ((FARPROC16*)0)[intnum] = handler;
150 /**********************************************************************
151 * DOSVM_GetPMHandler16
153 * Return the protected mode interrupt vector for a given interrupt.
155 FARPROC16 DOSVM_GetPMHandler16( BYTE intnum )
157 static HMODULE16 procs;
158 FARPROC16 handler = DOSVM_Vectors16[intnum];
160 if (!handler)
162 if (!procs &&
163 (procs = GetModuleHandle16( "winedos16" )) < 32 &&
164 (procs = LoadLibrary16( "winedos16" )) < 32)
166 ERR("could not load winedos16.dll\n");
167 procs = 0;
168 return 0;
171 handler = GetProcAddress16( procs, (LPCSTR)(FIRST_INTERRUPT + intnum));
172 if (!handler)
174 WARN("int%x not implemented, returning dummy handler\n", intnum );
175 handler = GetProcAddress16( procs, (LPCSTR)(FIRST_INTERRUPT + 256));
178 DOSVM_Vectors16[intnum] = handler;
181 return handler;
185 /**********************************************************************
186 * DOSVM_SetPMHandler16
188 * Set the protected mode interrupt handler for a given interrupt.
190 void DOSVM_SetPMHandler16( BYTE intnum, FARPROC16 handler )
192 TRACE("Set protected mode interrupt vector %02x <- %04x:%04x\n",
193 intnum, HIWORD(handler), LOWORD(handler) );
194 DOSVM_Vectors16[intnum] = handler;
197 /**********************************************************************
198 * DOSVM_GetPMHandler48
200 * Return the protected mode interrupt vector for a given interrupt.
201 * Used to get 48-bit pointer for 32-bit interrupt handlers in DPMI32.
203 FARPROC48 DOSVM_GetPMHandler48( BYTE intnum )
205 if (!DOSVM_Vectors48[intnum].selector)
207 DOSVM_Vectors48[intnum].selector = DOSVM_dpmi_segments->int48_sel;
208 DOSVM_Vectors48[intnum].offset = 6 * intnum;
210 return DOSVM_Vectors48[intnum];
213 /**********************************************************************
214 * DOSVM_SetPMHandler48
216 * Set the protected mode interrupt handler for a given interrupt.
217 * Used to set 48-bit pointer for 32-bit interrupt handlers in DPMI32.
219 void DOSVM_SetPMHandler48( BYTE intnum, FARPROC48 handler )
221 TRACE("Set 32-bit protected mode interrupt vector %02x <- %04x:%08lx\n",
222 intnum, handler.selector, handler.offset );
223 DOSVM_Vectors48[intnum] = handler;
226 /**********************************************************************
227 * DOSVM_GetBuiltinHandler
229 * Return Wine interrupt handler procedure for a given interrupt.
231 INTPROC DOSVM_GetBuiltinHandler( BYTE intnum )
233 if (intnum < sizeof(DOSVM_VectorsBuiltin)/sizeof(INTPROC)) {
234 INTPROC proc = DOSVM_VectorsBuiltin[intnum];
235 if(proc)
236 return proc;
239 WARN("int%x not implemented, returning dummy handler\n", intnum );
240 return DOSVM_DefaultHandler;
243 /**********************************************************************
244 * DOSVM_CallBuiltinHandler
246 * Execute Wine interrupt handler procedure.
248 void WINAPI DOSVM_CallBuiltinHandler( CONTEXT86 *context, BYTE intnum )
250 INTPROC proc = DOSVM_GetBuiltinHandler( intnum );
251 proc( context );