Subversion Repositories Kolibri OS

Rev

Rev 548 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
548 serge 1
/****************************************************************************
2
*
3
*                            Open Watcom Project
4
*
5
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
6
*
7
*  ========================================================================
8
*
9
*    This file contains Original Code and/or Modifications of Original
10
*    Code as defined in and that are subject to the Sybase Open Watcom
11
*    Public License version 1.0 (the 'License'). You may not use this file
12
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
13
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
14
*    provided with the Original Code and Modifications, and is also
15
*    available at www.sybase.com/developer/opensource.
16
*
17
*    The Original Code and all software distributed under the License are
18
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
19
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
20
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
21
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
22
*    NON-INFRINGEMENT. Please see the License for the specific language
23
*    governing rights and limitations under the License.
24
*
25
*  ========================================================================
26
*
27
* Description:  __chk8087 and other FPU related functions.
28
*
29
****************************************************************************/
30
 
31
 
32
#include "variety.h"
33
#include 
34
#include 
35
#if defined( __OS2__ )
36
#endif
37
#if defined( __WINDOWS__ )
38
  #include 
39
#endif
40
 
41
#include "rtdata.h"
42
#include "exitwmsg.h"
43
#include "87state.h"
44
 
45
extern void __GrabFP87( void );
46
 
47
extern unsigned short __8087cw;
48
#pragma aux __8087cw "*";
49
 
50
#if defined( __DOS_086__ )
51
extern unsigned char __dos87real;
52
#pragma aux __dos87real "*";
53
 
54
extern unsigned short __dos87emucall;
55
#pragma aux __dos87emucall "*";
56
#endif
57
 
58
extern void __init_80x87( void );
59
#if defined( __DOS_086__ )
60
#pragma aux __init_80x87 "*" = \
61
        ".8087" \
62
        "cmp    __dos87real,0" \
63
        "jz     l1" \
64
        "finit" \
65
        "fldcw  __8087cw" \
66
"l1:     cmp    __dos87emucall,0" \
67
        "jz     l2" \
68
        "mov    ax,1" \
69
        "call   __dos87emucall" \
70
"l2:" ;
71
#else
72
#pragma aux __init_80x87 "*" = \
73
        ".8087" \
74
        "finit" \
75
        "fldcw  __8087cw" ;
76
#endif
77
 
78
/* 0 => no 8087; 2 => 8087,287; 3=>387 */
79
extern unsigned char _WCI86NEAR __x87id( void );
80
#pragma aux __x87id "*";
81
 
82
#if !defined( __UNIX__ ) && !defined( __OS2_386__ )
83
 
84
extern void __fsave( _87state * );
85
extern void __frstor( _87state * );
86
 
87
#if defined( __386__ )
88
 
89
    #pragma aux __fsave =                                           \
90
    0x9b 0xdd 0x30  /* fsave    [eax]   ; save the 8087 state */    \
91
    0x9b            /* wait                                   */    \
92
    parm routine [eax];
93
 
94
    #pragma aux __frstor =                                          \
95
    0xdd 0x20       /* frstor   [eax]   ; restore the 8087 */       \
96
    0x9b            /* wait             ; wait             */       \
97
    parm routine [eax];
98
 
99
#else   /* __286__ */
100
 
101
  #if defined( __BIG_DATA__ )
102
    #pragma aux __fsave =                                           \
103
    0x53            /* push    bx                           */      \
104
    0x1e            /* push    ds                           */      \
105
    0x8e 0xda       /* mov     ds,dx                        */      \
106
    0x8b 0xd8       /* mov     bx,ax                        */      \
107
    0x9b 0xdd 0x37  /* fsave   [bx]                         */      \
108
    0x90 0x9b       /* fwait                                */      \
109
    0x1f            /* pop     ds                           */      \
110
    0x5b            /* pop     bx                           */      \
111
    parm routine [dx ax];
112
  #else
113
    #pragma aux __fsave =                                           \
114
    0x53            /* push    bx                           */      \
115
    0x8b 0xd8       /* mov     bx,ax                        */      \
116
    0x9b 0xdd 0x37  /* fsave   [bx]                         */      \
117
    0x90 0x9b       /* fwait                                */      \
118
    0x5b            /* pop     bx                           */      \
119
    parm routine [ax];
120
  #endif
121
 
122
  #if defined( __BIG_DATA__ )
123
    #pragma aux __frstor =                                          \
124
    0x53            /* push    bx                           */      \
125
    0x1e            /* push    ds                           */      \
126
    0x8e 0xda       /* mov     ds,dx                        */      \
127
    0x8b 0xd8       /* mov     bx,ax                        */      \
128
    0x9b 0xdd 0x27  /* frstor  [bx]                         */      \
129
    0x90 0x9b       /* fwait                                */      \
130
    0x1f            /* pop     ds                           */      \
131
    0x5b            /* pop     bx                           */      \
132
    parm routine [dx ax];
133
  #else
134
    #pragma aux __frstor =                                          \
135
    0x53            /* push    bx                           */      \
136
    0x8b 0xd8       /* mov     bx,ax                        */      \
137
    0x9b 0xdd 0x27  /* frstor  [bx]                         */      \
138
    0x90 0x9b       /* fwait                                */      \
139
    0x5b            /* pop     bx                           */      \
140
    parm routine [ax];
141
  #endif
142
 
143
#endif
144
 
145
static void __save_8087( _87state * __fs )
146
{
147
    __fsave( __fs );
148
}
149
 
150
static void __rest_8087( _87state * __fs )
151
{
152
    __frstor( __fs );
153
}
154
#endif  /* !__UNIX__ && && !__OS2__ */
155
 
156
_WCRTLINK void _fpreset( void )
157
{
158
    if( _RWD_8087 != 0 ) {
159
        __init_80x87();
160
    }
161
}
162
 
163
void __init_8087( void )
164
{
165
#if !defined( __UNIX__ ) && !defined( __OS2_386__ )
166
    if( _RWD_real87 != 0 )
167
    {            /* if our emulator, don't worry */
168
        _RWD_Save8087 = __save_8087;    /* point to real save 8087 routine */
169
        _RWD_Rest8087 = __rest_8087;    /* point to real restore 8087 routine */
170
    }
171
#endif
172
    _fpreset();
173
}
174
 
175
#if defined( __DOS__ ) || defined( __OS2_286__ )
176
 
177
void _WCI86FAR __default_sigfpe_handler( int fpe_sig )
178
{
179
    __fatal_runtime_error( "Floating point exception\r\n", EXIT_FAILURE );
180
}
181
#endif
182
 
183
#if defined( __OS2__ )
184
 
185
void __chk8087( void )
186
/********************/
187
{
188
    char    devinfo;
189
 
190
#if defined( __386__ )
191
    DosDevConfig( &devinfo, DEVINFO_COPROCESSOR );
192
    if( devinfo == 0 ) {
193
        _RWD_real87 = 0;
194
    } else {
195
        _RWD_real87 = __x87id();
196
    }
197
    _RWD_8087 = _RWD_real87;
198
#else
199
    if( _RWD_8087 == 0 ) {
200
        DosDevConfig( &devinfo, 3, 0 );
201
        if( devinfo == 0 ) {
202
            _RWD_real87 = 0;
203
        } else {
204
            _RWD_real87 = __x87id();
205
        }
206
        _RWD_8087 = _RWD_real87;
207
    }
208
    if( _RWD_real87 ) {
209
        __GrabFP87();
210
    }
211
    if( _RWD_8087 ) {
212
        _RWD_FPE_handler = __default_sigfpe_handler;
213
    }
214
#endif
215
    _fpreset();
216
}
217
 
218
#elif defined( __QNX__ )
219
 
220
void __chk8087( void )
221
/********************/
222
{
223
    extern      char    __87;
224
    extern      char    __r87;
225
 
226
    _RWD_real87 = __r87;
227
    _RWD_8087 = __87;
228
    _fpreset();
229
}
230
 
231
#elif defined( __LINUX__ )
232
 
233
void __chk8087( void )
234
/********************/
235
{
236
    // TODO: We really need to call Linux and determine if the machine
237
    //       has a real FPU or not, so we can properly work with an FPU
238
    //       emulator.
239
    _RWD_real87 = __x87id();
240
    _RWD_8087 = _RWD_real87;
241
    _fpreset();
242
}
243
 
244
#elif defined( __NETWARE__ )
245
 
246
extern short __87present( void );
247
#pragma aux __87present =       \
248
    "smsw  ax           ",      \
249
    "test  ax, 4        ",      \
250
    "jne   no_emu       ",      \
251
    "xor   ax, ax       ",      \
252
    "no_emu:            ",      \
253
    "mov   ax, 1        "       \
254
value [ ax ];
255
 
256
extern void __chk8087( void )
257
/*****************************/
258
{
259
    if( _RWD_8087 == 0 ) {
260
        if( __87present() ) {
261
            _RWD_8087 = 3;      /* 387 */
262
            _RWD_real87 = 3;
263
        }
264
        __init_80x87();
265
    }
266
}
267
 
268
#elif defined( __NT__ )
269
 
270
void __chk8087( void )
271
/********************/
272
{
702 serge 273
    _RWD_real87 = __x87id();
548 serge 274
    _RWD_8087 = _RWD_real87;
275
    __init_8087();
276
}
277
 
278
#elif defined( __DOS__ )
279
 
280
void __chk8087( void )
281
/********************/
282
{
283
    if( _RWD_8087 != 0 ) {          /* if we already know we have an 80x87 */
284
#if !defined( __386__ )
285
        if( __dos87real )
286
            __GrabFP87();
287
#endif
288
        _RWD_FPE_handler = __default_sigfpe_handler;
289
        return;                    /* this prevents real87 from being set */
290
    }                               /* when we have an emulator */
291
    _RWD_real87 = __x87id();        /* if a coprocessor is present then we */
292
    _RWD_8087 = _RWD_real87;        /* initialize even when NO87 is defined */
293
#if !defined( __386__ )
294
    __dos87real = _RWD_real87;
295
#endif
296
    __init_8087();                  /* this handles the fpi87 and NO87 case */
297
    if( _RWD_no87 != 0 ) {          /* if NO87 environment var is defined */
298
        _RWD_8087 = 0;              /* then we want to pretend that the */
299
        _RWD_real87 = 0;            /* coprocessor doesn't exist */
300
    }
301
    if( _RWD_real87 ) {
302
        __GrabFP87();
303
    }
304
    if( _RWD_8087 ) {
305
        _RWD_FPE_handler = __default_sigfpe_handler;
306
    }
307
}
308
 
309
#elif defined( __WINDOWS__ )
310
 
311
void __chk8087( void )
312
/********************/
313
{
314
    if( _RWD_8087 != 0 )             /* if we already know we have an 80x87 */
315
        return;                      /* this prevents real87 from being set */
316
                                     /* when we have an emulator */
317
    if( GetWinFlags() & WF_80x87 ) { /* if a coprocessor is present then we */
318
  #if defined( __386__ )
319
        extern void pascal _FloatingPoint( void );
320
        _FloatingPoint();
321
  #endif
322
        _RWD_real87 = __x87id();     /* initialize even when NO87 is defined */
323
        _RWD_8087 = _RWD_real87;     /* this handles the fpi87 and NO87 case */
324
        __init_8087();
325
    } else {
326
  #if defined( __386__ )
327
        // check to see if emulator is loaded
328
        union REGS regs;
329
        regs.w.ax = 0xfa00;
330
        int86( 0x2f, ®s, ®s );
331
        if( regs.w.ax == 0x0666 ) {  /* check for emulator present */
332
            _RWD_real87 = __x87id(); /* initialize even when NO87 is defined */
333
            _RWD_8087 = _RWD_real87; /* this handles the fpi87 and NO87 case */
334
            __init_8087();
335
        }
336
  #endif
337
    }
338
    if( _RWD_no87 != 0 ) {           /* if NO87 environment var is defined */
339
        _RWD_8087 = 0;               /* then we want to pretend that the */
340
        _RWD_real87 = 0;             /* coprocessor doesn't exist */
341
    }
342
}
343
 
344
#endif