home *** CD-ROM | disk | FTP | other *** search
/ PC Extra Super CD 1998 January / PCPLUS131.iso / DJGPP / V2 / DJLSR201.ZIP / src / libc / emu387 / npxsetup.c < prev   
Encoding:
C/C++ Source or Header  |  1996-04-26  |  3.4 KB  |  123 lines

  1. /* Copyright (C) 1994, 1995 Charles Sandmann (sandmann@clio.rice.edu)
  2.  * FPU setup and emulation hooks for DJGPP V2.0
  3.  * This file maybe freely distributed, no warranty. */
  4.  
  5. /* Note:  If this file is built with IMBED_EMU387 defined, the application 
  6.    should be linked with -lemu to imbed the code in the image.  This 
  7.    makes it easier to distribute an application with a single file.
  8.    The alternate behavior is to dynamically load the image. */
  9.  
  10. #include <ctype.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <io.h>
  14. #include <signal.h>
  15. #include <setjmp.h>
  16. #include <dpmi.h>
  17. #include <libc/internal.h>
  18. #include <sys/exceptn.h>
  19. #include <float.h>
  20. #ifndef IMBED_EMU387
  21. #include <sys/dxe.h>
  22. static int (*_emu_entry)(jmp_buf exc);
  23. #else
  24. int _emu_entry(jmp_buf exc);
  25. #endif
  26.  
  27. /* crt0.o references __emu387_load_hook just to pull in this object in libemu.a.
  28.    Using -lemu -lc brings in the static objects instead of a dynamic link. */
  29.  
  30. int __emu387_load_hook;
  31.  
  32. /* The environment variable 387 can be used to disable a 387 which is present
  33.    (for testing) by setting it to "n".  The presence can be reported to 
  34.    stderr by setting 387 to "q" (query).  Unlike GO32, "y" is not supported
  35.    since it can hang the machine if a coprocessor is not really present.
  36.    If a 387 is not present under DPMI, we call a V1.0 DPMI extension to ask 
  37.    that Exception 7 be sent to our process.  If we don't have a 387, we 
  38.    attempt to load the EMU387.DXE and call it from the signal.
  39.  */
  40.  
  41. static void nofpsig(int sig)
  42. {
  43.   if(_emu_entry(__djgpp_exception_state))
  44.   {
  45.     raise(SIGFPE);
  46.     return;
  47.   }
  48.   longjmp(__djgpp_exception_state, __djgpp_exception_state->__eax);
  49. }
  50.  
  51. #ifdef RESTORE_FPU
  52. static void restore_DPMI_fpu_state(void)
  53. {
  54.   __dpmi_set_coprocessor_emulation(1);    /* Enable Coprocessor, no exceptions */
  55. }
  56. #endif
  57.  
  58. extern int _detect_80387(void);
  59.  
  60. void _npxsetup(char *argv0)
  61. {
  62.   char *cp;
  63.   char have_80387;
  64. #ifdef RESTORE_FPU
  65.   static int veryfirst = 1;
  66. #endif
  67.  
  68.   cp = getenv("387");
  69.   if (cp && (tolower(cp[0]) == 'n'))
  70.     have_80387 = 0;
  71.   else
  72.   {
  73.     /* This next function may fail, but that's OK.  This may fix the
  74.        nested FPU client fault - DJ */
  75.     __dpmi_set_coprocessor_emulation(1);
  76.     have_80387 = _detect_80387();
  77.   }
  78.  
  79.   if (cp && (tolower(cp[0]) == 'q')) {
  80.     if (!have_80387)
  81.       _write(2, "No ", 3);
  82.     _write(2, "80387 detected.\r\n", 17);
  83.   }
  84.  
  85.   if(have_80387) {
  86.     /* mask all exceptions, except invalid operation */
  87.     _control87(0x033e, 0xffff);
  88.  
  89.   } else {
  90.     /* Flags value 3 means coprocessor emulation, exceptions to us */
  91.     if (__dpmi_set_coprocessor_emulation(3)) {
  92.       _write(2, "Warning: Coprocessor not present and DPMI setup failed!\r\n", 57);
  93.       _write(2, "         If application attempts floating operations system may hang!\r\n", 71);
  94.     } else {
  95. #ifndef IMBED_EMU387
  96.       char emuname[512];
  97.       cp = getenv("EMU387");
  98.       if (!cp) {
  99.         char *last, c;
  100.         cp = last = emuname;
  101.         while((c = *cp++ = *argv0++))
  102.           if(c == '/' || c == '\\')
  103.             last = cp;
  104.         *last = 0;
  105.         strcat(emuname,"emu387.dxe");
  106.         cp = emuname;
  107.       }
  108.       _emu_entry = _dxe_load(cp);
  109.       if (_emu_entry == 0)
  110.         return;
  111. #endif
  112. #ifdef RESTORE_FPU
  113.       if (veryfirst)
  114.     {
  115.       veryfirst = 0;
  116.       atexit(restore_DPMI_fpu_state);
  117.     }
  118. #endif
  119.       signal(SIGNOFP, nofpsig);
  120.     }
  121.   }
  122. }
  123.