blob: 264ba77f5b403dd83c809b0dc6a4018bbe8f2c19 [file] [log] [blame]
Admiral Coeyman9cb2b212002-07-10 23:22:29 +00001/*
2 * DOS interrupt 34->3e handlers. All FPU interrupt code should be
3 * moved into this file.
Admiral Coeyman9cb2b212002-07-10 23:22:29 +00004 *
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>
Alexandre Julliarde9836522003-11-15 00:13:20 +000023#include "dosexe.h"
Admiral Coeyman9cb2b212002-07-10 23:22:29 +000024#include "wine/debug.h"
25
26WINE_DEFAULT_DEBUG_CHANNEL(int);
27
28/*
29 * The actual work is done by a single routine.
30 */
31
32static void FPU_ModifyCode(CONTEXT86 *context, BYTE Opcode);
33
34
Admiral Coeyman9cb2b212002-07-10 23:22:29 +000035/**********************************************************************
Jukka Heinonen416c2ae2002-11-12 23:29:48 +000036 * DOSVM_Int34Handler (WINEDOS16.152)
Admiral Coeyman9cb2b212002-07-10 23:22:29 +000037 *
38 * Handler for int 34 (FLOATING POINT EMULATION - Opcode 0xd8).
39 *
40 * The interrupt list isn't specific about what this interrupt
41 * actually does. [ interrup.m ]
42 */
Jukka Heinonen416c2ae2002-11-12 23:29:48 +000043void WINAPI DOSVM_Int34Handler(CONTEXT86 *context)
Admiral Coeyman9cb2b212002-07-10 23:22:29 +000044{
Alexandre Julliardef94e402003-08-18 20:04:27 +000045 TRACE("Int 0x34 called-- FP opcode 0xd8\n");
Jukka Heinonen416c2ae2002-11-12 23:29:48 +000046 FPU_ModifyCode(context, 0xd8);
Admiral Coeyman9cb2b212002-07-10 23:22:29 +000047}
48
Jukka Heinonen416c2ae2002-11-12 23:29:48 +000049
Admiral Coeyman9cb2b212002-07-10 23:22:29 +000050/**********************************************************************
Jukka Heinonen416c2ae2002-11-12 23:29:48 +000051 * DOSVM_Int35Handler (WINEDOS16.153)
Admiral Coeyman9cb2b212002-07-10 23:22:29 +000052 *
53 * Handler for int 35 (FLOATING POINT EMULATION - Opcode 0xd9).
54 *
55 * The interrupt list isn't specific about what this interrupt
56 * actually does. [ interrup.m ]
57 */
Jukka Heinonen416c2ae2002-11-12 23:29:48 +000058void WINAPI DOSVM_Int35Handler(CONTEXT86 *context)
Admiral Coeyman9cb2b212002-07-10 23:22:29 +000059{
Alexandre Julliardef94e402003-08-18 20:04:27 +000060 TRACE("Int 0x35 called-- FP opcode 0xd9\n");
Jukka Heinonen416c2ae2002-11-12 23:29:48 +000061 FPU_ModifyCode(context, 0xd9);
Admiral Coeyman9cb2b212002-07-10 23:22:29 +000062}
63
64
65/**********************************************************************
Jukka Heinonen416c2ae2002-11-12 23:29:48 +000066 * DOSVM_Int36Handler (WINEDOS16.154)
Admiral Coeyman9cb2b212002-07-10 23:22:29 +000067 *
68 * Handler for int 36 (FLOATING POINT EMULATION - Opcode 0xda).
69 *
70 * The interrupt list isn't specific about what this interrupt
71 * actually does. [ interrup.m ]
72 */
Jukka Heinonen416c2ae2002-11-12 23:29:48 +000073void WINAPI DOSVM_Int36Handler(CONTEXT86 *context)
Admiral Coeyman9cb2b212002-07-10 23:22:29 +000074{
Alexandre Julliardef94e402003-08-18 20:04:27 +000075 TRACE("Int 0x36 called-- FP opcode 0xda\n");
Jukka Heinonen416c2ae2002-11-12 23:29:48 +000076 FPU_ModifyCode(context, 0xda);
Admiral Coeyman9cb2b212002-07-10 23:22:29 +000077}
78
Jukka Heinonen416c2ae2002-11-12 23:29:48 +000079
Admiral Coeyman9cb2b212002-07-10 23:22:29 +000080/**********************************************************************
Jukka Heinonen416c2ae2002-11-12 23:29:48 +000081 * DOSVM_Int37Handler (WINEDOS16.155)
Admiral Coeyman9cb2b212002-07-10 23:22:29 +000082 *
83 * Handler for int 37 (FLOATING POINT EMULATION - Opcode 0xdb).
84 *
85 * The interrupt list isn't specific about what this interrupt
86 * actually does. [ interrup.m ]
87 */
Jukka Heinonen416c2ae2002-11-12 23:29:48 +000088void WINAPI DOSVM_Int37Handler(CONTEXT86 *context)
Admiral Coeyman9cb2b212002-07-10 23:22:29 +000089{
Alexandre Julliardef94e402003-08-18 20:04:27 +000090 TRACE("Int 0x37 called-- FP opcode 0xdb\n");
Jukka Heinonen416c2ae2002-11-12 23:29:48 +000091 FPU_ModifyCode(context, 0xdb);
Admiral Coeyman9cb2b212002-07-10 23:22:29 +000092}
93
Jukka Heinonen416c2ae2002-11-12 23:29:48 +000094
Admiral Coeyman9cb2b212002-07-10 23:22:29 +000095/**********************************************************************
Jukka Heinonen416c2ae2002-11-12 23:29:48 +000096 * DOSVM_Int38Handler (WINEDOS16.156)
Admiral Coeyman9cb2b212002-07-10 23:22:29 +000097 *
98 * Handler for int 38 (FLOATING POINT EMULATION - Opcode 0xdc).
99 *
100 * Between versions 3.0 and 5.01, the original PC-MOS API call that
101 * was here was moved to int 0xd4.
102 *
103 * The interrupt list isn't specific about what this interrupt
104 * actually does. [ interrup.m ]
105 */
Jukka Heinonen416c2ae2002-11-12 23:29:48 +0000106void WINAPI DOSVM_Int38Handler(CONTEXT86 *context)
Admiral Coeyman9cb2b212002-07-10 23:22:29 +0000107{
Alexandre Julliardef94e402003-08-18 20:04:27 +0000108 TRACE("Int 0x38 called-- FP opcode 0xdc\n");
Jukka Heinonen416c2ae2002-11-12 23:29:48 +0000109 FPU_ModifyCode(context, 0xdc);
Admiral Coeyman9cb2b212002-07-10 23:22:29 +0000110}
111
Jukka Heinonen416c2ae2002-11-12 23:29:48 +0000112
Admiral Coeyman9cb2b212002-07-10 23:22:29 +0000113/**********************************************************************
Jukka Heinonen416c2ae2002-11-12 23:29:48 +0000114 * DOSVM_Int39Handler (WINEDOS16.157)
Admiral Coeyman9cb2b212002-07-10 23:22:29 +0000115 *
116 * Handler for int 39 (FLOATING POINT EMULATION - Opcode 0xdd).
117 *
118 * The interrupt list isn't specific about what this interrupt
119 * actually does. [ interrup.m ]
120 */
Jukka Heinonen416c2ae2002-11-12 23:29:48 +0000121void WINAPI DOSVM_Int39Handler(CONTEXT86 *context)
Admiral Coeyman9cb2b212002-07-10 23:22:29 +0000122{
Alexandre Julliardef94e402003-08-18 20:04:27 +0000123 TRACE("Int 0x39 called-- FP opcode 0xdd\n");
Jukka Heinonen416c2ae2002-11-12 23:29:48 +0000124 FPU_ModifyCode(context, 0xdd);
Admiral Coeyman9cb2b212002-07-10 23:22:29 +0000125}
126
Jukka Heinonen416c2ae2002-11-12 23:29:48 +0000127
Admiral Coeyman9cb2b212002-07-10 23:22:29 +0000128/**********************************************************************
Jukka Heinonen416c2ae2002-11-12 23:29:48 +0000129 * DOSVM_Int3aHandler (WINEDOS16.158)
Admiral Coeyman9cb2b212002-07-10 23:22:29 +0000130 *
131 * Handler for int 3a (FLOATING POINT EMULATION - Opcode 0xde).
132 *
133 * The interrupt list isn't specific about what this interrupt
134 * actually does. [ interrup.m ]
135 */
Jukka Heinonen416c2ae2002-11-12 23:29:48 +0000136void WINAPI DOSVM_Int3aHandler(CONTEXT86 *context)
Admiral Coeyman9cb2b212002-07-10 23:22:29 +0000137{
Alexandre Julliardef94e402003-08-18 20:04:27 +0000138 TRACE("Int 0x3a called-- FP opcode 0xde\n");
Jukka Heinonen416c2ae2002-11-12 23:29:48 +0000139 FPU_ModifyCode(context, 0xde);
Admiral Coeyman9cb2b212002-07-10 23:22:29 +0000140}
141
Jukka Heinonen416c2ae2002-11-12 23:29:48 +0000142
Admiral Coeyman9cb2b212002-07-10 23:22:29 +0000143/**********************************************************************
Jukka Heinonen416c2ae2002-11-12 23:29:48 +0000144 * DOSVM_Int3bHandler (WINEDOS16.159)
Admiral Coeyman9cb2b212002-07-10 23:22:29 +0000145 *
146 * Handler for int 3B (FLOATING POINT EMULATION - Opcode 0xdf).
147 *
148 * The interrupt list isn't specific about what this interrupt
149 * actually does. [ interrup.m ]
150 */
Jukka Heinonen416c2ae2002-11-12 23:29:48 +0000151void WINAPI DOSVM_Int3bHandler(CONTEXT86 *context)
Admiral Coeyman9cb2b212002-07-10 23:22:29 +0000152{
Alexandre Julliardef94e402003-08-18 20:04:27 +0000153 TRACE("Int 0x3b called-- FP opcode 0xdf\n");
Jukka Heinonen416c2ae2002-11-12 23:29:48 +0000154 FPU_ModifyCode(context, 0xdf);
Admiral Coeyman9cb2b212002-07-10 23:22:29 +0000155}
156
157
Admiral Coeyman9cb2b212002-07-10 23:22:29 +0000158/**********************************************************************
Jukka Heinonen416c2ae2002-11-12 23:29:48 +0000159 * DOSVM_Int3cHandler (WINEDOS16.160)
Admiral Coeyman9cb2b212002-07-10 23:22:29 +0000160 *
161 * Handler for int 3C (FLOATING POINT EMULATION - INSTRUCTIONS WITH SEGMENT OVERRIDE).
162 *
163 * Generated code is CD 3C xy mm ... (CD = int | 3C = this interrupt)
164 * xy is a modified ESC code and mm is the modR/M byte.
165 * xy byte seems to be encoded as ss011xxx or ss000xxx
166 * ss= segment override.
Jukka Heinonen416c2ae2002-11-12 23:29:48 +0000167 * 00 -> DS
168 * 01 -> SS
169 * 10 -> CS
170 * 11 -> ES
Admiral Coeyman9cb2b212002-07-10 23:22:29 +0000171 *
172 * 11011xxx should be the opcode instruction.
173 */
Jukka Heinonen416c2ae2002-11-12 23:29:48 +0000174void WINAPI DOSVM_Int3cHandler(CONTEXT86 *context)
Admiral Coeyman9cb2b212002-07-10 23:22:29 +0000175{
Alexandre Julliardef94e402003-08-18 20:04:27 +0000176 FIXME("Int 3C NOT Implemented\n");
Jukka Heinonen416c2ae2002-11-12 23:29:48 +0000177 INT_BARF(context, 0x3c);
Admiral Coeyman9cb2b212002-07-10 23:22:29 +0000178}
179
Jukka Heinonen416c2ae2002-11-12 23:29:48 +0000180
Admiral Coeyman9cb2b212002-07-10 23:22:29 +0000181/**********************************************************************
Jukka Heinonen416c2ae2002-11-12 23:29:48 +0000182 * DOSVM_Int3dHandler (WINEDOS16.161)
Admiral Coeyman9cb2b212002-07-10 23:22:29 +0000183 *
184 * Handler for int 3D (FLOATING POINT EMULATION - Standalone FWAIT).
185 *
186 * Opcode 0x90 is a NOP. It just fills space where the 3D was.
187 */
Jukka Heinonen416c2ae2002-11-12 23:29:48 +0000188void WINAPI DOSVM_Int3dHandler(CONTEXT86 *context)
Admiral Coeyman9cb2b212002-07-10 23:22:29 +0000189{
Alexandre Julliardef94e402003-08-18 20:04:27 +0000190 TRACE("Int 0x3d called-- Standalone FWAIT\n");
Jukka Heinonen416c2ae2002-11-12 23:29:48 +0000191 FPU_ModifyCode(context, 0x90);
Admiral Coeyman9cb2b212002-07-10 23:22:29 +0000192}
193
194
Admiral Coeyman9cb2b212002-07-10 23:22:29 +0000195/**********************************************************************
Jukka Heinonen416c2ae2002-11-12 23:29:48 +0000196 * DOSVM_Int3eHandler (WINEDOS16.162)
Admiral Coeyman9cb2b212002-07-10 23:22:29 +0000197 *
198 * FLOATING POINT EMULATION -- Borland "Shortcut" call.
199 * The two bytes following the int 3E instruction are
200 * the subcode and a NOP ( 0x90 ), except for subcodes DC and DE
201 * where the second byte is the register count.
202 *
203 * Direct access 4.0 modifies and does not restore this vector.
204 *
205 */
Jukka Heinonen416c2ae2002-11-12 23:29:48 +0000206void WINAPI DOSVM_Int3eHandler(CONTEXT86 *context)
Admiral Coeyman9cb2b212002-07-10 23:22:29 +0000207{
Alexandre Julliardef94e402003-08-18 20:04:27 +0000208 FIXME("Int 3E NOT Implemented\n");
Jukka Heinonen416c2ae2002-11-12 23:29:48 +0000209 INT_BARF(context, 0x3e);
Admiral Coeyman9cb2b212002-07-10 23:22:29 +0000210}
211
Jukka Heinonen416c2ae2002-11-12 23:29:48 +0000212
Admiral Coeyman9cb2b212002-07-10 23:22:29 +0000213/**********************************************************************
214 * FPU_ModifyCode
215 *
216 * This is the function that inserts the 0x9b fwait instruction
217 * and the actual FPU opcode into the program.
218 * -A.C.
219 *
220 * Code thanks to Ove Kaaven
221 */
222static void FPU_ModifyCode(CONTEXT86 *context, BYTE Opcode)
223{
Jukka Heinonenfbbe6a42003-08-20 18:17:39 +0000224 BYTE *code = CTX_SEG_OFF_TO_LIN(context, context->SegCs, context->Eip);
Admiral Coeyman9cb2b212002-07-10 23:22:29 +0000225
Jukka Heinonen416c2ae2002-11-12 23:29:48 +0000226 /*
227 * All *NIX systems should have a real or kernel emulated FPU.
228 */
Admiral Coeyman9cb2b212002-07-10 23:22:29 +0000229
Jukka Heinonen416c2ae2002-11-12 23:29:48 +0000230 code[-2] = 0x9b; /* The fwait instruction */
231 code[-1] = Opcode; /* Insert the opcode */
Admiral Coeyman9cb2b212002-07-10 23:22:29 +0000232
Jukka Heinonenfbbe6a42003-08-20 18:17:39 +0000233 if ( ISV86(context) && LOWORD(context->Eip) < 2 )
234 FIXME("Backed up over a real mode segment boundary in FPU code.\n");
Admiral Coeyman9cb2b212002-07-10 23:22:29 +0000235
Jukka Heinonenfbbe6a42003-08-20 18:17:39 +0000236 context->Eip -= 2; /* back up the return address 2 bytes */
Admiral Coeyman9cb2b212002-07-10 23:22:29 +0000237
Alexandre Julliardef94e402003-08-18 20:04:27 +0000238 TRACE("Modified code in FPU int call to 0x9b 0x%x\n",Opcode);
Admiral Coeyman9cb2b212002-07-10 23:22:29 +0000239}