FPU patch for bug 586

admiral coeyman admiral at corner.net
Wed Jun 12 01:15:17 CDT 2002


Ove Kaaven,
> 
> > >       I was unsure of the memory handling functions.  Both of these functions report
> > that they return linear addresses, but I read one as a dos linear address and
> > the other as a wine linear address.  It was a mistake on my part.  I read it as
> > though I had to convert the seg:offset code to a dos linear address, then
> > convert it to a wine linear address.  It may have made more sense to me if I
> > hadn't been worried about the addresses being in the wrong order.
> 
> Well, the meanings of these address types are, if I remember right:
> 
> Real = 16-bit real mode seg:ofs address
> Dos = 32-bit offset from DOSMEM_dosmem (aka DOSMEM_MemoryBase()) (unless
> it's above 1MB, then it's considered a linear pointer) (after the DOS
> restructure, DOSMEM_dosmem is always 0, which is probably why it worked
> for you)
> Linear = 32-bit linear pointer that you can dereference in Wine code
> 
	Thank you.  I'm almost certain that I'm not alone in not knowing that.

> I consider the "Dos" memory type pretty useless, there's almost never a
> reason to use it instead of linear memory or something...
>
	Since we're not working inside of the dos VM, there's not much use for the Dos
memory type.  I just didn't know that I could directly convert without all of
the steps.  I've made minor modifications to the patch to clean it up as you
suggested.  That's how I would have done it in assembly.

> >       What I read says that the stack's lowest address contains IP and the word
> > above that is the code segment for the return.  IP:CS  I'm not sure that I
> > could just point a segment:offset converting function at an address in that
> > format and get the linear address.
> 
> Well, you can, as long as we stick to x86 (might be trickier if we were to
> write a CPU emulator, but I guess there would be lots of places to change
> then anyway).
>
	The code that we're trying to run is x86 code.  If the stack isn't right
inside of the virtual machine, many things that rely on the structure of the
stack will fail.  It may be a future project, however, it's not a minor
undertaking.
 
> >       I've done the reverse conversion be backing IP up 2 bytes.
> 
> You have two versions of the Int3dHandler in your patch. One of them isn't
> changed...
>
	Yes--I moved the copy in the msdos directory out of the way to find out where
it was being compiled from.  I kept it there, after putting it back, in case I
needed to restore it.  It's no longer there so it's not in this copy of the
patch.
 
> Anyway, if it helps, here's how I might have written your routine (without
> the error checking), if I thought that perhaps these interrupts are also
> used by win16 apps (otherwise the second CTX_SEG_OFF_TO_LIN(...) can be
> replaced with PTR_REAL_TO_LIN(stack[1], stack[0]))
>
	win16 apps may use these interrupts because Dos lived under win16.  You could
count on it being there and use it for things not supported under the windows
API.  From what I'm reading, these interrupts are used by a compiler and would
be there under any win/dos operating system. 

> void FPU_ModifyCode(CONTEXT86 *context, BYTE Opcode)
> {
>   WORD *stack = CTX_SEG_OFF_TO_LIN(context, context->SegSs, context->Esp)
>   BYTE *code = CTX_SEG_OFF_TO_LIN(context, stack[1], stack[0]);
>   code[-2] = 0x9b;
>   code[-1] = Opcode;
>   stack[0] -= 2;
> }

	I'm sorry to have been so much trouble.

	God Bless,
	--Robert 'Admiral' Coeyman

-- 
---
May you live as long as you wish and age but a single day.
http://www.dotguy.net/                 admiral at corner.net
Webmaster/ Linux Administrator         Computer Co-Op/CornerNet
-------------- next part --------------
Index: dlls/kernel/wprocs.spec
===================================================================
RCS file: /home/wine/wine/dlls/kernel/wprocs.spec,v
retrieving revision 1.7
diff -u -u -r1.7 wprocs.spec
--- dlls/kernel/wprocs.spec	14 Dec 2001 23:14:23 -0000	1.7
+++ dlls/kernel/wprocs.spec	12 Jun 2002 05:58:11 -0000
@@ -17,7 +17,6 @@
 142 pascal -interrupt INT_Int2aHandler() INT_Int2aHandler
 147 pascal -interrupt INT_Int2fHandler() INT_Int2fHandler
 149 pascal -interrupt INT_Int31Handler() INT_Int31Handler
-161 pascal -interrupt INT_Int3dHandler() INT_Int3dHandler
 165 pascal -interrupt INT_Int41Handler() INT_Int41Handler
 175 pascal -interrupt INT_Int4bHandler() INT_Int4bHandler
 192 pascal -interrupt INT_Int5cHandler() NetBIOSCall16
Index: dlls/ntdll/Makefile.in
===================================================================
RCS file: /home/wine/wine/dlls/ntdll/Makefile.in,v
retrieving revision 1.27
diff -u -u -r1.27 Makefile.in
--- dlls/ntdll/Makefile.in	14 May 2002 20:55:01 -0000	1.27
+++ dlls/ntdll/Makefile.in	12 Jun 2002 05:58:11 -0000
@@ -62,7 +62,6 @@
 	$(TOPOBJDIR)/msdos/int26.c \
 	$(TOPOBJDIR)/msdos/int2a.c \
 	$(TOPOBJDIR)/msdos/int2f.c \
-	$(TOPOBJDIR)/msdos/int3d.c \
 	$(TOPOBJDIR)/msdos/int41.c \
 	$(TOPOBJDIR)/msdos/int4b.c \
 	$(TOPOBJDIR)/msdos/int5c.c \
@@ -115,6 +114,9 @@
 	sync.c \
 	time.c \
 	wcstring.c
+
+###	$(TOPOBJDIR)/msdos/int3d.c \
+
 
 GEN_ASM_SRCS = \
 	relay16.s \
Index: dlls/winedos/Makefile.in
===================================================================
RCS file: /home/wine/wine/dlls/winedos/Makefile.in,v
retrieving revision 1.13
diff -u -u -r1.13 Makefile.in
--- dlls/winedos/Makefile.in	23 May 2002 02:46:10 -0000	1.13
+++ dlls/winedos/Makefile.in	12 Jun 2002 05:58:11 -0000
@@ -22,6 +22,7 @@
 	int31.c \
 	int33.c \
 	int67.c \
+	fpu.c \
 	ioports.c \
 	module.c \
 	soundblaster.c \
Index: dlls/winedos/dosexe.h
===================================================================
RCS file: /home/wine/wine/dlls/winedos/dosexe.h,v
retrieving revision 1.7
diff -u -u -r1.7 dosexe.h
--- dlls/winedos/dosexe.h	16 May 2002 18:34:48 -0000	1.7
+++ dlls/winedos/dosexe.h	12 Jun 2002 05:58:11 -0000
@@ -114,6 +114,19 @@
 extern void WINAPI DOSVM_Int33Message(UINT,WPARAM,LPARAM);
 extern void WINAPI DOSVM_Int33Console(MOUSE_EVENT_RECORD*);
 
+/* fpu.c */
+extern void WINAPI INT_Int34Handler(CONTEXT86*);
+extern void WINAPI INT_Int35Handler(CONTEXT86*);
+extern void WINAPI INT_Int36Handler(CONTEXT86*);
+extern void WINAPI INT_Int37Handler(CONTEXT86*);
+extern void WINAPI INT_Int38Handler(CONTEXT86*);
+extern void WINAPI INT_Int39Handler(CONTEXT86*);
+extern void WINAPI INT_Int3aHandler(CONTEXT86*);
+extern void WINAPI INT_Int3bHandler(CONTEXT86*);
+extern void WINAPI INT_Int3cHandler(CONTEXT86*);
+extern void WINAPI INT_Int3dHandler(CONTEXT86*); 
+extern void WINAPI INT_Int3eHandler(CONTEXT86*);
+
 /* int67.c */
 extern void WINAPI DOSVM_Int67Handler(CONTEXT86*);
 extern void WINAPI EMS_Ioctl_Handler(CONTEXT86*);
Index: dlls/winedos/dosvm.c
===================================================================
RCS file: /home/wine/wine/dlls/winedos/dosvm.c,v
retrieving revision 1.19
diff -u -u -r1.19 dosvm.c
--- dlls/winedos/dosvm.c	31 May 2002 23:40:54 -0000	1.19
+++ dlls/winedos/dosvm.c	12 Jun 2002 05:58:12 -0000
@@ -652,8 +652,8 @@
     /* 18 */ 0, 0, INT_Int1aHandler, 0, 0, 0, 0, 0,
     /* 20 */ DOSVM_Int20Handler, DOSVM_Int21Handler, 0, 0, 0, INT_Int25Handler, 0, 0,
     /* 28 */ 0, DOSVM_Int29Handler, INT_Int2aHandler, 0, 0, 0, 0, INT_Int2fHandler,
-    /* 30 */ 0, DOSVM_Int31Handler, 0, DOSVM_Int33Handler, 0, 0, 0, 0,
-    /* 38 */ 0, 0, 0, 0, 0, 0, 0, 0,
+    /* 30 */ 0, DOSVM_Int31Handler, 0, DOSVM_Int33Handler, INT_Int34Handler, INT_Int35Handler, INT_Int36Handler, INT_Int37Handler,
+    /* 38 */ INT_Int38Handler, INT_Int39Handler, INT_Int3aHandler, INT_Int3bHandler, INT_Int3cHandler, INT_Int3dHandler, INT_Int3eHandler, 0,
     /* 40 */ 0, 0, 0, 0, 0, 0, 0, 0,
     /* 48 */ 0, 0, 0, 0, 0, 0, 0, 0,
     /* 50 */ 0, 0, 0, 0, 0, 0, 0, 0,
--- /dev/null	Sun Jul 17 19:46:18 1994
+++ dlls/winedos/fpu.c	Wed Jun 12 01:58:57 2002
@@ -0,0 +1,252 @@
+/*
+ * DOS interrupt 34->3e handlers.  All FPU interrupt code should be
+ * moved into this file.
+ *  int 3d is not activated yet...
+ *
+ * Copyright 2002 Robert 'Admiral' Coeyman
+ *
+ * X11 Friendly.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <stdlib.h>
+#include "msdos.h"
+#include "miscemu.h"
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(int);
+
+/*
+ *  The actual work is done by a single routine.
+ */
+
+void FPU_ModifyCode(CONTEXT86 *context, BYTE Opcode);
+
+
+
+/**********************************************************************
+ *          INT_Int34Handler (WPROCS.152)
+ *
+ * Handler for int 34 (FLOATING POINT EMULATION - Opcode 0xd8).
+ *
+ *  The interrupt list isn't specific about what this interrupt
+ *  actually does. [ interrup.m ] 
+ */
+void WINAPI INT_Int34Handler(CONTEXT86 *context)
+{
+
+	TRACE("Int 0x34 called-- FP opcode 0xd8");
+	FPU_ModifyCode(context, 0xd8);
+
+}
+
+/**********************************************************************
+ *          INT_Int35Handler (WPROCS.153)
+ *
+ * Handler for int 35 (FLOATING POINT EMULATION - Opcode 0xd9).
+ *
+ *  The interrupt list isn't specific about what this interrupt
+ *  actually does. [ interrup.m ] 
+ */
+void WINAPI INT_Int35Handler(CONTEXT86 *context)
+{
+	TRACE("Int 0x35 called-- FP opcode 0xd9");
+	FPU_ModifyCode(context, 0xd9);
+
+}
+
+
+/**********************************************************************
+ *          INT_Int36Handler (WPROCS.154)
+ *
+ * Handler for int 36 (FLOATING POINT EMULATION - Opcode 0xda).
+ *
+ *  The interrupt list isn't specific about what this interrupt
+ *  actually does. [ interrup.m ] 
+ */
+void WINAPI INT_Int36Handler(CONTEXT86 *context)
+{
+	TRACE("Int 0x36 called-- FP opcode 0xda");
+	FPU_ModifyCode(context, 0xda);
+
+}
+
+/**********************************************************************
+ *          INT_Int37Handler (WPROCS.155)
+ *
+ * Handler for int 37 (FLOATING POINT EMULATION - Opcode 0xdb).
+ *
+ *  The interrupt list isn't specific about what this interrupt
+ *  actually does. [ interrup.m ] 
+ */
+void WINAPI INT_Int37Handler(CONTEXT86 *context)
+{
+	TRACE("Int 0x37 called-- FP opcode 0xdb");
+	FPU_ModifyCode(context, 0xdb);
+
+}
+
+/**********************************************************************
+ *          INT_Int38Handler (WPROCS.156)
+ *
+ * Handler for int 38 (FLOATING POINT EMULATION - Opcode 0xdc).
+ *
+ *  Between versions 3.0 and 5.01, the original PC-MOS API call that
+ *  was here was moved to int 0xd4.
+ *
+ *  The interrupt list isn't specific about what this interrupt
+ *  actually does. [ interrup.m ] 
+ */
+void WINAPI INT_Int38Handler(CONTEXT86 *context)
+{
+	TRACE("Int 0x38 called-- FP opcode 0xdc");
+	FPU_ModifyCode(context, 0xdc);
+
+}
+
+/**********************************************************************
+ *          INT_Int39Handler (WPROCS.157)
+ *
+ * Handler for int 39 (FLOATING POINT EMULATION - Opcode 0xdd).
+ *
+ *  The interrupt list isn't specific about what this interrupt
+ *  actually does. [ interrup.m ] 
+ */
+void WINAPI INT_Int39Handler(CONTEXT86 *context)
+{
+	TRACE("Int 0x39 called-- FP opcode 0xdd");
+	FPU_ModifyCode(context, 0xdd);
+
+}
+
+/**********************************************************************
+ *          INT_Int3aHandler (WPROCS.158)
+ *
+ * Handler for int 3a (FLOATING POINT EMULATION - Opcode 0xde).
+ *
+ *  The interrupt list isn't specific about what this interrupt
+ *  actually does. [ interrup.m ] 
+ */
+void WINAPI INT_Int3aHandler(CONTEXT86 *context)
+{
+	TRACE("Int 0x3a called-- FP opcode 0xde");
+	FPU_ModifyCode(context, 0xde);
+
+}
+
+/**********************************************************************
+ *          INT_Int3bHandler (WPROCS.159)
+ *
+ * Handler for int 3B (FLOATING POINT EMULATION - Opcode 0xdf).
+ *
+ *  The interrupt list isn't specific about what this interrupt
+ *  actually does. [ interrup.m ] 
+ */
+void WINAPI INT_Int3bHandler(CONTEXT86 *context)
+{
+	TRACE("Int 0x3b called-- FP opcode 0xdf");
+	FPU_ModifyCode(context, 0xdf);
+
+}
+
+
+
+/**********************************************************************
+ *          INT_Int3cHandler (WPROCS.160)
+ *
+ * Handler for int 3C (FLOATING POINT EMULATION - INSTRUCTIONS WITH SEGMENT OVERRIDE).
+ *
+ *  Generated code is CD 3C xy mm ... (CD = int | 3C = this interrupt)
+ *   xy is a modified ESC code and mm is the modR/M byte.
+ *   xy byte seems to be encoded as ss011xxx  or ss000xxx
+ *   ss= segment override.
+ *	00 -> DS
+ *	01 -> SS
+ *	10 -> CS
+ *	11 -> ES
+ *
+ *  11011xxx should be the opcode instruction.
+ */
+void WINAPI INT_Int3cHandler(CONTEXT86 *context)
+{
+	FIXME("Int 3C NOT Implemented");
+	INT_BARF(context, 0x3c);
+}
+
+/**********************************************************************
+ *          INT_Int3dHandler (WPROCS.161)
+ *
+ * Handler for int 3D (FLOATING POINT EMULATION - Standalone FWAIT).
+ *
+ *  Opcode 0x90 is a NOP.  It just fills space where the 3D was.
+ */
+void WINAPI INT_Int3dHandler(CONTEXT86 *context)
+{
+	TRACE("Int 0x3d called-- Standalone FWAIT");
+	FPU_ModifyCode(context, 0x90);
+
+}
+
+
+
+/**********************************************************************
+ *          INT_Int3eHandler (WPROCS.162)
+ *
+ * FLOATING POINT EMULATION -- Borland "Shortcut" call.
+ *  The two bytes following the int 3E instruction are
+ *  the subcode and a NOP ( 0x90 ), except for subcodes DC and DE
+ *  where the second byte is the register count.
+ *
+ *  Direct access 4.0 modifies and does not restore this vector.
+ *
+ */
+void WINAPI INT_Int3eHandler(CONTEXT86 *context)
+{
+	FIXME("Int 3E NOT Implemented");
+	INT_BARF(context, 0x3e);
+}
+
+/**********************************************************************
+ *          FPU_ModifyCode
+ *
+ *   This is the function that inserts the 0x9b fwait instruction
+ *   and the actual FPU opcode into the program.
+ *           -A.C.
+ *
+ *               Code thanks to Ove Kaaven
+ */
+
+void FPU_ModifyCode(CONTEXT86 *context, BYTE Opcode)
+{
+  WORD *stack = CTX_SEG_OFF_TO_LIN(context, context->SegSs, context->Esp);
+  BYTE *code =  CTX_SEG_OFF_TO_LIN(context, stack[1], stack[0]);
+
+/* 
+ * All *NIX systems should have a real or kernel emulated FPU. 
+ */
+
+  code[-2] = 0x9b;          /* The fwait instruction */
+  code[-1] = Opcode;        /* Insert the opcode     */
+
+if ( stack[0] < 2 ) FIXME("Backed up over a segment boundry in FPU code.");
+
+  stack[0] -= 2;             /* back up the return address 2 bytes */
+
+
+	TRACE("Modified code in FPU int call to 0x9b 0x%x",Opcode);
+}
+
+


More information about the wine-patches mailing list