www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/1999/08/30/05:52:45

Date: Mon, 30 Aug 1999 09:59:49 +0300 (IDT)
From: Eli Zaretskii <eliz AT is DOT elta DOT co DOT il>
X-Sender: eliz AT is
To: DJ Delorie <dj AT delorie DOT com>, Charles Sandmann <sandmann AT clio DOT rice DOT edu>
cc: djgpp-workers AT delorie DOT com, Morten Welinder <terra AT diku DOT dk>
Subject: FWAIT emulation in emu387.cc
Message-ID: <Pine.SUN.3.91.990830095710.3558J-100000@is>
MIME-Version: 1.0
Reply-To: djgpp-workers AT delorie DOT com

The main function of the emu387 emulator is attached below (I removed
the ifdef'ed away debug code, for clarity).

Why is the line marked with "<<<<<<<<<<" commented out?  It doesn't
seem right to me.

I actually traced a bug (reported on c.o.m.d. some 2 years ago ;-) to
this line: on Windows, any program that uses FWAIT gets stuck in an
endless loop (when emulation is used), because EIP isn't being
incremented.  The test program posted with the bug report just called 
`floor', and that was enough to get it wedged.

How come it works on DOS, you ask?  Well, it seems that on DOS, FWAIT
never gets into the emulator!

Charles, is this expected behavior?  Intel manuals say that FWAIT
generates the coprocessor not present exception when the MP and TS
flags in CR0 are set.  I guess Windows sets these flags (although
Intel recommends to leave it cleared) while on plain DOS they remain
unset, right?

Anyway, I tested this on DOS, with and without a memory manager, with
CWSDPMI and QDPMI, and never saw FWAIT inside the emulator.  But on
Windows, both 95 and 3.1, FWAIT gets into the emulator.

The Intel manual says the EIP points to FWAIT when it generates the
exception.  So it seems like we need to resurrect that line.  Does
anyone remember why it was commented out?


    int _emu_entry(jmp_buf _exception_state)
    {
      int jmpval;
      eip = (unsigned char *) _exception_state->__eip;
      eax = _exception_state->__eax;
      ebx = _exception_state->__ebx;
      ecx = _exception_state->__ecx;
      edx = _exception_state->__edx;
      esi = _exception_state->__esi;
      edi = _exception_state->__edi;
      ebp = _exception_state->__ebp;
      esp = _exception_state->__esp;
      if (*eip == 0x66) // operand size - we know what size we need
	eip++;
      if (*eip == 0x9b) // fwait
      {
    //    _exception_state->__eip++;   <<<<<<<<<<<<<<<<
	return 0;
      }
      jmpval = setjmp(jumpbuf);
      if(jmpval)
	return 1;           /* Emulator failed for some reason */
      int esc_value = *eip++ & 7;
      modrm = *eip++;
      esc_value |= (modrm & 070);
      (esc_table[esc_value])();
    //  emu_printall();
      _exception_state->__eip = (unsigned long) eip;
      _exception_state->__eax = eax;
      return 0;
    }

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019