Use the virtual real-mode interrupt table if low DOS memory isn't
[wine] / msdos / interrupts.c
1 /*
2  * Interrupt vectors emulation
3  *
4  * Copyright 1995 Alexandre Julliard
5  */
6
7 #include <sys/types.h>
8 #include "windef.h"
9 #include "wine/winbase16.h"
10 #include "miscemu.h"
11 #include "msdos.h"
12 #include "module.h"
13 #include "debugtools.h"
14
15 DEFAULT_DEBUG_CHANNEL(int);
16
17 static FARPROC16 INT_Vectors[256];
18
19 /* Ordinal number for interrupt 0 handler in WPROCS.DLL */
20 #define FIRST_INTERRUPT 100
21
22
23 /**********************************************************************
24  *          INT_GetPMHandler
25  *
26  * Return the protected mode interrupt vector for a given interrupt.
27  */
28 FARPROC16 INT_GetPMHandler( BYTE intnum )
29 {
30     if (!INT_Vectors[intnum])
31     {
32         static HMODULE16 wprocs;
33         if (!wprocs)
34         {
35             if ((wprocs = GetModuleHandle16( "wprocs" )) < 32)
36             {
37                 ERR("could not load wprocs.dll\n");
38                 return 0;
39             }
40         }
41         INT_Vectors[intnum] = NE_GetEntryPoint( wprocs, FIRST_INTERRUPT + intnum );
42     }
43     return INT_Vectors[intnum];
44 }
45
46
47 /**********************************************************************
48  *          INT_SetPMHandler
49  *
50  * Set the protected mode interrupt handler for a given interrupt.
51  */
52 void INT_SetPMHandler( BYTE intnum, FARPROC16 handler )
53 {
54     TRACE("Set protected mode interrupt vector %02x <- %04x:%04x\n",
55                  intnum, HIWORD(handler), LOWORD(handler) );
56     INT_Vectors[intnum] = handler;
57 }
58
59
60 /**********************************************************************
61  *          INT_GetRMHandler
62  *
63  * Return the real mode interrupt vector for a given interrupt.
64  */
65 FARPROC16 INT_GetRMHandler( BYTE intnum )
66 {
67     return ((FARPROC16*)DOSMEM_SystemBase())[intnum];
68 }
69
70
71 /**********************************************************************
72  *          INT_SetRMHandler
73  *
74  * Set the real mode interrupt handler for a given interrupt.
75  */
76 void INT_SetRMHandler( BYTE intnum, FARPROC16 handler )
77 {
78     TRACE("Set real mode interrupt vector %02x <- %04x:%04x\n",
79                  intnum, HIWORD(handler), LOWORD(handler) );
80     ((FARPROC16*)DOSMEM_SystemBase())[intnum] = handler;
81 }
82
83
84 /**********************************************************************
85  *          INT_CtxGetHandler
86  *
87  * Return the interrupt vector for a given interrupt.
88  */
89 FARPROC16 INT_CtxGetHandler( CONTEXT86 *context, BYTE intnum )
90 {
91     if (ISV86(context))
92         return INT_GetRMHandler(intnum);
93     else
94         return INT_GetPMHandler(intnum);
95 }
96
97
98 /**********************************************************************
99  *          INT_CtxSetHandler
100  *
101  * Set the interrupt handler for a given interrupt.
102  */
103 void INT_CtxSetHandler( CONTEXT86 *context, BYTE intnum, FARPROC16 handler )
104 {
105     if (ISV86(context))
106         INT_SetRMHandler(intnum, handler);
107     else
108         INT_SetPMHandler(intnum, handler);
109 }
110
111
112 /**********************************************************************
113  *          INT_RealModeInterrupt
114  *
115  * Handle real mode interrupts
116  */
117 int INT_RealModeInterrupt( BYTE intnum, CONTEXT86 *context )
118 {
119     /* we should really map to if1632/wprocs.spec, but not all
120      * interrupt handlers are adapted to support real mode yet */
121     switch (intnum) {
122         case 0x09:
123             INT_Int09Handler(context);
124             break;
125         case 0x10:
126             INT_Int10Handler(context);
127             break;
128         case 0x11:
129             INT_Int11Handler(context);
130             break;
131         case 0x12:
132             INT_Int12Handler(context);
133             break;
134         case 0x13:
135             INT_Int13Handler(context);
136             break;
137         case 0x15:
138             INT_Int15Handler(context);
139             break;
140         case 0x16:
141             INT_Int16Handler(context);
142             break;
143         case 0x17:
144             INT_Int17Handler(context);
145             break;
146         case 0x1a:
147             INT_Int1aHandler(context);
148             break;
149         case 0x20:
150             INT_Int20Handler(context);
151             break;
152         case 0x21:
153             DOS3Call(context);
154             break;
155         case 0x25:
156             INT_Int25Handler(context);
157             break;
158         case 0x29:
159             INT_Int29Handler(context);
160             break;
161         case 0x2a:
162             INT_Int2aHandler(context);
163             break; 
164         case 0x2f:
165             INT_Int2fHandler(context);
166             break;
167         case 0x31:
168             INT_Int31Handler(context);
169             break;
170         case 0x33:
171             INT_Int33Handler(context);
172             break;
173         default:
174             FIXME("Unknown Interrupt in DOS mode: 0x%x\n", intnum);
175             return 1;
176     }
177     return 0;
178 }