Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  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 <stdlib.h>
  34. #include <float.h>
  35. #if defined( __OS2__ )
  36. #endif
  37. #if defined( __WINDOWS__ )
  38.   #include <i86.h>
  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. {
  273.     _RWD_real87 = 3;    //387+     ;    //__x87id();
  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, &regs, &regs );
  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
  345.