winedos / Fix BIOS segment address under Win16

Jukka Heinonen jhei at iki.fi
Sat Sep 27 14:47:51 CDT 2003


BIOS data area is not necessarily at a fixed location.
Win16 programs that do not jump into real mode code
may have NULL pointer catching block at low linear memory
and BIOS data area has been moved elsewhere. This patch
should make sure that correct linear pointer is used
for accessing BIOS data area.

This should fix bug 1732 and I have also seen this bug with
some Win16 programs.

Pending stuff that I should be fixing when I have more time:

- DPMI async event handling is subject to stalls and deadlocks
  because instruction emulation is no longer protected
  from signals.
- DPMI/RM performance is poor because the number of exceptions has
  dramatically increased. This is due to send_debug_event
  calling server during each exception.
- Fixes to mouse driver (hide/show, virtual size, mouse range).
  These are ready but require cleaning and synchronizing with CVS.
- RMCB calls. Working thing exists but it uses interrupt hooks.
  Perhaps fixing WOWCallback16Ex return path to support more
  registers would be better...




Changelog:
    Use correct linear pointer when accessing BIOS data area.




Index: dlls/winedos/devices.c
===================================================================
RCS file: /home/wine/wine/dlls/winedos/devices.c,v
retrieving revision 1.9
diff -u -r1.9 devices.c
--- dlls/winedos/devices.c	25 Aug 2003 01:01:01 -0000	1.9
+++ dlls/winedos/devices.c	27 Sep 2003 19:22:16 -0000
@@ -219,7 +219,7 @@
 {
   int *scan;
   REQUEST_HEADER *hdr = get_hdr(SYSTEM_STRATEGY_CON,(void **)&scan);
-  BIOSDATA *bios = BIOS_DATA;
+  BIOSDATA *bios = DOSVM_BiosData();
   WORD CurOfs = bios->NextKbdCharPtr;
   DOS_LISTOFLISTS *lol = DOSMEM_LOL();
   DOS_DATASEG *dataseg = (DOS_DATASEG *)lol;




Index: dlls/winedos/dosexe.h
===================================================================
RCS file: /home/wine/wine/dlls/winedos/dosexe.h,v
retrieving revision 1.32
diff -u -r1.32 dosexe.h
--- dlls/winedos/dosexe.h	17 Sep 2003 22:45:46 -0000	1.32
+++ dlls/winedos/dosexe.h	27 Sep 2003 19:33:42 -0000
@@ -100,8 +100,6 @@
 #define VIF_MASK 0x00080000
 #define VIP_MASK 0x00100000
 
-#define BIOS_DATA ((void *)0x400)
-
 #define ADD_LOWORD(dw,val)  ((dw) = ((dw) & 0xffff0000) | LOWORD((DWORD)(dw)+(val)))
 
 /* module.c */
@@ -123,6 +121,7 @@
 extern void WINAPI DOSVM_PIC_ioport_out( WORD port, BYTE val );
 extern void WINAPI DOSVM_SetTimer( UINT ticks );
 extern UINT WINAPI DOSVM_GetTimer( void );
+extern BIOSDATA   *DOSVM_BiosData( void );
 
 /* devices.c */
 extern void DOSDEV_InstallDOSDevices(void);




Index: dlls/winedos/dosvm.c
===================================================================
RCS file: /home/wine/wine/dlls/winedos/dosvm.c,v
retrieving revision 1.52
diff -u -r1.52 dosvm.c
--- dlls/winedos/dosvm.c	17 Sep 2003 20:23:33 -0000	1.52
+++ dlls/winedos/dosvm.c	27 Sep 2003 19:22:28 -0000
@@ -707,6 +707,26 @@
 
 
 /**********************************************************************
+ *         DOSVM_BiosData
+ *
+ * Get pointer to BIOS data area. This is not at fixed location
+ * because those Win16 programs that do not use any real mode code have
+ * protected NULL pointer catching block at low linear memory and
+ * BIOS data has been moved to another location.
+ */
+BIOSDATA *DOSVM_BiosData( void )
+{
+    LDT_ENTRY entry;
+    FARPROC16 proc;
+
+    proc = GetProcAddress16( GetModuleHandle16( "KERNEL" ), 
+                             (LPCSTR)(ULONG_PTR)193 );
+    wine_ldt_get_entry( LOWORD(proc), &entry );
+    return (BIOSDATA *)wine_ldt_get_base( &entry );
+}
+
+
+/**********************************************************************
  *	    DllMain  (DOSVM.Init)
  */
 BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved )




Index: dlls/winedos/int09.c
===================================================================
RCS file: /home/wine/wine/dlls/winedos/int09.c,v
retrieving revision 1.8
diff -u -r1.8 int09.c
--- dlls/winedos/int09.c	5 Sep 2003 23:08:28 -0000	1.8
+++ dlls/winedos/int09.c	27 Sep 2003 19:22:32 -0000
@@ -150,7 +150,7 @@
  */
 void WINAPI DOSVM_Int09Handler( CONTEXT86 *context )
 {
-  BIOSDATA *data = BIOS_DATA;
+  BIOSDATA *data = DOSVM_BiosData();
   BYTE ascii, scan = DOSVM_Int09ReadScan(&ascii);
   BYTE realscan = scan & 0x7f; /* remove 0x80 make/break flag */
   BOOL modifier = FALSE;




Index: dlls/winedos/int10.c
===================================================================
RCS file: /home/wine/wine/dlls/winedos/int10.c,v
retrieving revision 1.31
diff -u -r1.31 int10.c
--- dlls/winedos/int10.c	8 Apr 2003 19:41:03 -0000	1.31
+++ dlls/winedos/int10.c	27 Sep 2003 19:22:37 -0000
@@ -789,7 +789,7 @@
  */
 static void INT10_HandleVESA( CONTEXT86 *context )
 {
-    BIOSDATA *data = BIOS_DATA;
+    BIOSDATA *data = DOSVM_BiosData();
 
     switch(AL_reg(context)) {
 
@@ -954,7 +954,7 @@
  */
 void WINAPI DOSVM_Int10Handler( CONTEXT86 *context )
 {
-    BIOSDATA *data = BIOS_DATA;
+    BIOSDATA *data = DOSVM_BiosData();
 
     INT10_InitializeVideoMode( data );
 
@@ -1403,7 +1403,7 @@
  */
 void WINAPI DOSVM_PutChar( BYTE ascii )
 {
-  BIOSDATA *data = BIOS_DATA;
+  BIOSDATA *data = DOSVM_BiosData();
   unsigned  xpos, ypos;
 
   TRACE("char: 0x%02x(%c)\n", ascii, ascii);




Index: dlls/winedos/int16.c
===================================================================
RCS file: /home/wine/wine/dlls/winedos/int16.c,v
retrieving revision 1.11
diff -u -r1.11 int16.c
--- dlls/winedos/int16.c	2 May 2003 20:12:52 -0000	1.11
+++ dlls/winedos/int16.c	27 Sep 2003 19:22:40 -0000
@@ -87,7 +87,7 @@
    case 0x02: /* Get Shift Flags */
 
       /* read value from BIOS data segment's keyboard status flags field */
-      data = BIOS_DATA;
+      data = DOSVM_BiosData();
       SET_AL( context, data->KbdFlags1 );
 
       TRACE("Get Shift Flags: returning 0x%02x\n", AL_reg(context));
@@ -159,7 +159,7 @@
  */
 int WINAPI DOSVM_Int16ReadChar(BYTE *ascii, BYTE *scan, CONTEXT86 *waitctx)
 {
-    BIOSDATA *data = BIOS_DATA;
+    BIOSDATA *data = DOSVM_BiosData();
     WORD CurOfs = data->NextKbdCharPtr;
 
     /* check if there's data in buffer */
@@ -194,7 +194,7 @@
 
 int WINAPI DOSVM_Int16AddChar(BYTE ascii,BYTE scan)
 {
-  BIOSDATA *data = BIOS_DATA;
+  BIOSDATA *data = DOSVM_BiosData();
   WORD CurOfs = data->FirstKbdCharPtr;
   WORD NextOfs = CurOfs + 2;
 




Index: dlls/winedos/int1a.c
===================================================================
RCS file: /home/wine/wine/dlls/winedos/int1a.c,v
retrieving revision 1.3
diff -u -r1.3 int1a.c
--- dlls/winedos/int1a.c	15 Jul 2003 20:50:34 -0000	1.3
+++ dlls/winedos/int1a.c	27 Sep 2003 19:22:44 -0000
@@ -40,7 +40,7 @@
     {
     case 0x00: /* GET SYSTEM TIME */
         {
-            BIOSDATA *data = BIOS_DATA;
+            BIOSDATA *data = DOSVM_BiosData();
             SET_CX( context, HIWORD(data->Ticks) );
             SET_DX( context, LOWORD(data->Ticks) );
             SET_AL( context, 0 ); /* FIXME: midnight flag is unsupported */




Index: dlls/winedos/timer.c
===================================================================
RCS file: /home/wine/wine/dlls/winedos/timer.c,v
retrieving revision 1.3
diff -u -r1.3 timer.c
--- dlls/winedos/timer.c	17 Sep 2003 22:45:46 -0000	1.3
+++ dlls/winedos/timer.c	27 Sep 2003 19:22:48 -0000
@@ -131,7 +131,7 @@
  */
 void WINAPI DOSVM_Int08Handler( CONTEXT86 *context )
 {
-    BIOSDATA *bios_data      = BIOS_DATA;
+    BIOSDATA *bios_data      = DOSVM_BiosData();
     CONTEXT86 nested_context = *context;
     FARPROC16 int1c_proc     = DOSVM_GetRMHandler( 0x1c );
     



-- 
Jukka Heinonen <http://www.iki.fi/jhei/>



More information about the wine-patches mailing list