Replace calls to WaitForMultipleObjects with a 0 count by calls to
[wine] / dlls / winedos / fpu.c
1 /*
2  * DOS interrupt 34->3e handlers.  All FPU interrupt code should be
3  * moved into this file.
4  *
5  * Copyright 2002 Robert 'Admiral' Coeyman
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 #include <stdlib.h>
23 #include "msdos.h"
24 #include "miscemu.h"
25 #include "wine/debug.h"
26
27 WINE_DEFAULT_DEBUG_CHANNEL(int);
28
29 /*
30  *  The actual work is done by a single routine.
31  */
32
33 static void FPU_ModifyCode(CONTEXT86 *context, BYTE Opcode);
34
35
36 /**********************************************************************
37  *          DOSVM_Int34Handler (WINEDOS16.152)
38  *
39  * Handler for int 34 (FLOATING POINT EMULATION - Opcode 0xd8).
40  *
41  *  The interrupt list isn't specific about what this interrupt
42  *  actually does. [ interrup.m ]
43  */
44 void WINAPI DOSVM_Int34Handler(CONTEXT86 *context)
45 {
46     TRACE("Int 0x34 called-- FP opcode 0xd8");
47     FPU_ModifyCode(context, 0xd8);
48 }
49
50
51 /**********************************************************************
52  *          DOSVM_Int35Handler (WINEDOS16.153)
53  *
54  * Handler for int 35 (FLOATING POINT EMULATION - Opcode 0xd9).
55  *
56  *  The interrupt list isn't specific about what this interrupt
57  *  actually does. [ interrup.m ]
58  */
59 void WINAPI DOSVM_Int35Handler(CONTEXT86 *context)
60 {
61     TRACE("Int 0x35 called-- FP opcode 0xd9");
62     FPU_ModifyCode(context, 0xd9);
63 }
64
65
66 /**********************************************************************
67  *          DOSVM_Int36Handler (WINEDOS16.154)
68  *
69  * Handler for int 36 (FLOATING POINT EMULATION - Opcode 0xda).
70  *
71  *  The interrupt list isn't specific about what this interrupt
72  *  actually does. [ interrup.m ]
73  */
74 void WINAPI DOSVM_Int36Handler(CONTEXT86 *context)
75 {
76     TRACE("Int 0x36 called-- FP opcode 0xda");
77     FPU_ModifyCode(context, 0xda);
78 }
79
80
81 /**********************************************************************
82  *          DOSVM_Int37Handler (WINEDOS16.155)
83  *
84  * Handler for int 37 (FLOATING POINT EMULATION - Opcode 0xdb).
85  *
86  *  The interrupt list isn't specific about what this interrupt
87  *  actually does. [ interrup.m ]
88  */
89 void WINAPI DOSVM_Int37Handler(CONTEXT86 *context)
90 {
91     TRACE("Int 0x37 called-- FP opcode 0xdb");
92     FPU_ModifyCode(context, 0xdb);
93 }
94
95
96 /**********************************************************************
97  *          DOSVM_Int38Handler (WINEDOS16.156)
98  *
99  * Handler for int 38 (FLOATING POINT EMULATION - Opcode 0xdc).
100  *
101  *  Between versions 3.0 and 5.01, the original PC-MOS API call that
102  *  was here was moved to int 0xd4.
103  *
104  *  The interrupt list isn't specific about what this interrupt
105  *  actually does. [ interrup.m ]
106  */
107 void WINAPI DOSVM_Int38Handler(CONTEXT86 *context)
108 {
109     TRACE("Int 0x38 called-- FP opcode 0xdc");
110     FPU_ModifyCode(context, 0xdc);
111 }
112
113
114 /**********************************************************************
115  *          DOSVM_Int39Handler (WINEDOS16.157)
116  *
117  * Handler for int 39 (FLOATING POINT EMULATION - Opcode 0xdd).
118  *
119  *  The interrupt list isn't specific about what this interrupt
120  *  actually does. [ interrup.m ]
121  */
122 void WINAPI DOSVM_Int39Handler(CONTEXT86 *context)
123 {
124     TRACE("Int 0x39 called-- FP opcode 0xdd");
125     FPU_ModifyCode(context, 0xdd);
126 }
127
128
129 /**********************************************************************
130  *          DOSVM_Int3aHandler (WINEDOS16.158)
131  *
132  * Handler for int 3a (FLOATING POINT EMULATION - Opcode 0xde).
133  *
134  *  The interrupt list isn't specific about what this interrupt
135  *  actually does. [ interrup.m ]
136  */
137 void WINAPI DOSVM_Int3aHandler(CONTEXT86 *context)
138 {
139     TRACE("Int 0x3a called-- FP opcode 0xde");
140     FPU_ModifyCode(context, 0xde);
141 }
142
143
144 /**********************************************************************
145  *          DOSVM_Int3bHandler (WINEDOS16.159)
146  *
147  * Handler for int 3B (FLOATING POINT EMULATION - Opcode 0xdf).
148  *
149  *  The interrupt list isn't specific about what this interrupt
150  *  actually does. [ interrup.m ]
151  */
152 void WINAPI DOSVM_Int3bHandler(CONTEXT86 *context)
153 {
154     TRACE("Int 0x3b called-- FP opcode 0xdf");
155     FPU_ModifyCode(context, 0xdf);
156 }
157
158
159 /**********************************************************************
160  *          DOSVM_Int3cHandler (WINEDOS16.160)
161  *
162  * Handler for int 3C (FLOATING POINT EMULATION - INSTRUCTIONS WITH SEGMENT OVERRIDE).
163  *
164  *  Generated code is CD 3C xy mm ... (CD = int | 3C = this interrupt)
165  *   xy is a modified ESC code and mm is the modR/M byte.
166  *   xy byte seems to be encoded as ss011xxx  or ss000xxx
167  *   ss= segment override.
168  *     00 -> DS
169  *     01 -> SS
170  *     10 -> CS
171  *     11 -> ES
172  *
173  *  11011xxx should be the opcode instruction.
174  */
175 void WINAPI DOSVM_Int3cHandler(CONTEXT86 *context)
176 {
177     FIXME("Int 3C NOT Implemented");
178     INT_BARF(context, 0x3c);
179 }
180
181
182 /**********************************************************************
183  *          DOSVM_Int3dHandler (WINEDOS16.161)
184  *
185  * Handler for int 3D (FLOATING POINT EMULATION - Standalone FWAIT).
186  *
187  *  Opcode 0x90 is a NOP.  It just fills space where the 3D was.
188  */
189 void WINAPI DOSVM_Int3dHandler(CONTEXT86 *context)
190 {
191     TRACE("Int 0x3d called-- Standalone FWAIT");
192     FPU_ModifyCode(context, 0x90);
193 }
194
195
196 /**********************************************************************
197  *          DOSVM_Int3eHandler (WINEDOS16.162)
198  *
199  * FLOATING POINT EMULATION -- Borland "Shortcut" call.
200  *  The two bytes following the int 3E instruction are
201  *  the subcode and a NOP ( 0x90 ), except for subcodes DC and DE
202  *  where the second byte is the register count.
203  *
204  *  Direct access 4.0 modifies and does not restore this vector.
205  *
206  */
207 void WINAPI DOSVM_Int3eHandler(CONTEXT86 *context)
208 {
209     FIXME("Int 3E NOT Implemented");
210     INT_BARF(context, 0x3e);
211 }
212
213
214 /**********************************************************************
215  *          FPU_ModifyCode
216  *
217  *   This is the function that inserts the 0x9b fwait instruction
218  *   and the actual FPU opcode into the program.
219  *           -A.C.
220  *
221  *               Code thanks to Ove Kaaven
222  */
223 static void FPU_ModifyCode(CONTEXT86 *context, BYTE Opcode)
224 {
225     WORD *stack = CTX_SEG_OFF_TO_LIN(context, context->SegSs, context->Esp);
226     BYTE *code =  CTX_SEG_OFF_TO_LIN(context, stack[1], stack[0]);
227
228     /*
229      * All *NIX systems should have a real or kernel emulated FPU.
230      */
231
232     code[-2] = 0x9b;          /* The fwait instruction */
233     code[-1] = Opcode;        /* Insert the opcode     */
234
235     if ( stack[0] < 2 ) FIXME("Backed up over a segment boundry in FPU code.");
236
237     stack[0] -= 2;             /* back up the return address 2 bytes */
238
239     TRACE("Modified code in FPU int call to 0x9b 0x%x",Opcode);
240 }