From 65ea73fedf4a6fbe8d9cd59bc1ac5920f304f65d Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Wed, 4 Sep 2002 18:52:22 +0000 Subject: [PATCH] Added DPMI segments structure and related function to avoid direct references to dosmem internal variables. Determine BIOS system offsets at compile time. --- dlls/winedos/dosexe.h | 4 ++- dlls/winedos/dosvm.c | 4 ++- dlls/winedos/int10.c | 5 ++-- dlls/winedos/int31.c | 10 +++---- include/miscemu.h | 33 ++++++++++++++++------- msdos/dosmem.c | 62 +++++++++++++++---------------------------- msdos/dpmi.c | 8 +++--- msdos/int2f.c | 4 +-- 8 files changed, 64 insertions(+), 66 deletions(-) diff --git a/dlls/winedos/dosexe.h b/dlls/winedos/dosexe.h index 8705e4ef03f..be2ec5b4ca3 100644 --- a/dlls/winedos/dosexe.h +++ b/dlls/winedos/dosexe.h @@ -25,8 +25,10 @@ #include "winbase.h" /* for LPSTARTUPINFO32A */ #include "winnt.h" /* for PCONTEXT */ #include "wincon.h" /* for MOUSE_EVENT_RECORD */ +#include "miscemu.h" struct _DOSEVENT; +struct DPMI_segments; typedef void (*DOSRELAY)(CONTEXT86*,void*); @@ -39,6 +41,7 @@ typedef void (*DOSRELAY)(CONTEXT86*,void*); extern WORD DOSVM_psp; /* psp of current DOS task */ extern WORD DOSVM_retval; /* return value of previous DOS task */ extern DWORD DOS_LOLSeg; +extern const struct DPMI_segments *DOSVM_dpmi_segments; #if defined(linux) && defined(__i386__) #define MZ_SUPPORTED @@ -47,7 +50,6 @@ extern DWORD DOS_LOLSeg; #define V86_FLAG 0x00020000 #define BIOS_DATA ((void *)0x400) -#define BIOS_SYS ((void *)0xf0000) extern void WINAPI MZ_LoadImage( LPCSTR filename, HANDLE hFile ); extern BOOL WINAPI MZ_Exec( CONTEXT86 *context, LPCSTR filename, BYTE func, LPVOID paramblk ); diff --git a/dlls/winedos/dosvm.c b/dlls/winedos/dosvm.c index 064aeea17a4..b134020a179 100644 --- a/dlls/winedos/dosvm.c +++ b/dlls/winedos/dosvm.c @@ -60,6 +60,7 @@ WINE_DECLARE_DEBUG_CHANNEL(relay); WORD DOSVM_psp = 0; WORD DOSVM_retval = 0; +const struct DPMI_segments *DOSVM_dpmi_segments = NULL; #ifdef MZ_SUPPORTED @@ -98,7 +99,7 @@ static int DOSVM_SimulateInt( int vect, CONTEXT86 *context, BOOL inwine ) /* check for our real-mode hooks */ if (vect==0x31) { - if (context->SegCs==DOSMEM_wrap_seg) { + if (context->SegCs==DOSVM_dpmi_segments->wrap_seg) { /* exit from real-mode wrapper */ return -1; } @@ -699,6 +700,7 @@ BOOL WINAPI DOSVM_Init( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved TRACE("Initializing DOS memory structures\n"); DOSMEM_Init( TRUE ); DOSDEV_InstallDOSDevices(); + DOSVM_dpmi_segments = DOSMEM_GetDPMISegments(); #ifdef MZ_SUPPORTED event_notifier = CreateEventA(NULL, FALSE, FALSE, NULL); diff --git a/dlls/winedos/int10.c b/dlls/winedos/int10.c index 3cc2b37178e..3e336a5f682 100644 --- a/dlls/winedos/int10.c +++ b/dlls/winedos/int10.c @@ -91,8 +91,7 @@ static void DOSVM_Int10Handler_VESA( CONTEXT86 *context ) case 0x00: /* GET SuperVGA INFORMATION */ TRACE("VESA GET SuperVGA INFORMATION\n"); memcpy(CTX_SEG_OFF_TO_LIN(context,context->SegEs,context->Edi), - (char *)BIOS_SYS + DOSMEM_GetBiosSysStructOffset(OFF_VESAINFO), - sizeof(VESAINFO)); + &BIOS_EXTRA_PTR->vesa_info, sizeof(VESAINFO)); SET_AL( context, 0x4f ); SET_AH( context, 0x00 ); /* 0x00 = successful 0x01 = failed */ break; @@ -789,7 +788,7 @@ void WINAPI DOSVM_Int10Handler( CONTEXT86 *context ) SET_AL( context, 0x1b ); /* Copy state information structure to ES:DI */ memcpy(CTX_SEG_OFF_TO_LIN(context,context->SegEs,context->Edi), - (char *)BIOS_SYS + DOSMEM_GetBiosSysStructOffset(OFF_VIDEOSTATE),sizeof(VIDEOSTATE)); + &BIOS_EXTRA_PTR->vid_state,sizeof(VIDEOSTATE)); } break; diff --git a/dlls/winedos/int31.c b/dlls/winedos/int31.c index 62d0c08bbf1..e8903b6d74e 100644 --- a/dlls/winedos/int31.c +++ b/dlls/winedos/int31.c @@ -310,7 +310,7 @@ callrmproc_again: *stack16 = LOWORD(context->EFlags); } /* push return address (return to interrupt wrapper) */ - *(--stack16) = DOSMEM_wrap_seg; + *(--stack16) = DOSVM_dpmi_segments->wrap_seg; *(--stack16) = 0; /* adjust stack */ context->Esp -= 2*sizeof(WORD); @@ -321,7 +321,7 @@ callrmproc_again: /* RMCB call, invoke protected-mode handler directly */ DPMI_CallRMCBProc(context, CurrRMCB, dpmi_flag); /* check if we returned to where we thought we would */ - if ((context->SegCs != DOSMEM_wrap_seg) || + if ((context->SegCs != DOSVM_dpmi_segments->wrap_seg) || (LOWORD(context->Eip) != 0)) { /* we need to continue at different address in real-mode space, so we need to set it all up for real mode again */ @@ -418,7 +418,7 @@ static void StartPM( CONTEXT86 *context ) psp->environment = SELECTOR_AllocBlock( (void *)(env_seg<<4), 0x10000, WINE_LDT_FLAGS_DATA ); pm_ctx = *context; - pm_ctx.SegCs = DOSMEM_dpmi_sel; + pm_ctx.SegCs = DOSVM_dpmi_segments->dpmi_sel; /* our mode switch wrapper expects the new CS in DX, and the new SS in AX */ pm_ctx.Eax = ss; pm_ctx.Edx = cs; @@ -613,12 +613,12 @@ void WINAPI DOSVM_Int31Handler( CONTEXT86 *context ) { /* check if it's our wrapper */ TRACE("called from real mode\n"); - if (context->SegCs==DOSMEM_dpmi_seg) { + if (context->SegCs==DOSVM_dpmi_segments->dpmi_seg) { /* This is the protected mode switch */ StartPM(context); return; } - else if (context->SegCs==DOSMEM_xms_seg) + else if (context->SegCs==DOSVM_dpmi_segments->xms_seg) { /* This is the XMS driver entry point */ XMS_Handler(context); diff --git a/include/miscemu.h b/include/miscemu.h index 9892f614ac8..8c8367e4f29 100644 --- a/include/miscemu.h +++ b/include/miscemu.h @@ -144,24 +144,37 @@ typedef struct DWORD StaticModeList; } VESAINFO; +/* layout of BIOS extra data starting at f000:e000 */ +typedef struct +{ + VIDEOFUNCTIONALITY vid_func; + VIDEOSTATE vid_state; + VESAINFO vesa_info; + char vesa_string[32]; + WORD vesa_modes[40]; +} BIOS_EXTRA; + +#define BIOS_EXTRA_PTR ((BIOS_EXTRA *)0xfe000) +#define BIOS_EXTRA_SEGPTR MAKESEGPTR(0xf000,0xe000) + #include "poppack.h" -/* Index for bios structures stored at f000:e000 */ -enum {OFF_VIDEOSTATE,OFF_VIDEOFUNCTIONALITY,OFF_VESAINFO,OFF_VESASTRING,OFF_VESAMODELIST}; - -extern WORD DOSMEM_AddBiosSysStruct(int,int); -extern WORD DOSMEM_GetBiosSysStructOffset(int); - extern WORD DOSMEM_0000H; extern WORD DOSMEM_BiosDataSeg; extern WORD DOSMEM_BiosSysSeg; extern DWORD DOSMEM_CollateTable; /* various real-mode code stubs */ -extern WORD DOSMEM_wrap_seg; -extern WORD DOSMEM_xms_seg; -extern WORD DOSMEM_dpmi_seg; -extern WORD DOSMEM_dpmi_sel; +struct DPMI_segments +{ + WORD wrap_seg; + WORD xms_seg; + WORD dpmi_seg; + WORD dpmi_sel; +}; + +extern struct DPMI_segments DOSMEM_dpmi_segments; +extern const struct DPMI_segments *DOSMEM_GetDPMISegments(void); extern BOOL DOSMEM_Init(BOOL); extern void DOSMEM_Tick(WORD timer); diff --git a/msdos/dosmem.c b/msdos/dosmem.c index c2395b38d6b..8b361fcfae8 100644 --- a/msdos/dosmem.c +++ b/msdos/dosmem.c @@ -47,9 +47,6 @@ WORD DOSMEM_BiosSysSeg; /* BIOS ROM segment at 0xf000:0 */ DWORD DOSMEM_CollateTable; -static int StructOffset[256]; /* Offsets for all structures at f000:e000*/ -static int CurrentStructOffset = 0xe000; /* Current free offset */ - /* use 2 low bits of 'size' for the housekeeping */ #define DM_BLOCK_DEBUG 0xABE00000 @@ -86,10 +83,15 @@ static char *DOSMEM_dosmem; static char *DOSMEM_sysmem; /* various real-mode code stubs */ -WORD DOSMEM_wrap_seg; -WORD DOSMEM_xms_seg; -WORD DOSMEM_dpmi_seg; -WORD DOSMEM_dpmi_sel; +struct DPMI_segments DOSMEM_dpmi_segments; + +/*********************************************************************** + * DOSMEM_GetDPMISegments + */ +const struct DPMI_segments *DOSMEM_GetDPMISegments(void) +{ + return &DOSMEM_dpmi_segments; +} /*********************************************************************** * DOSMEM_MemoryTop @@ -201,13 +203,13 @@ static void DOSMEM_InitDPMI(void) 0xCB /* lret */ }; - ptr = DOSMEM_GetBlock( sizeof(wrap_code), &DOSMEM_wrap_seg ); + ptr = DOSMEM_GetBlock( sizeof(wrap_code), &DOSMEM_dpmi_segments.wrap_seg ); memcpy( ptr, wrap_code, sizeof(wrap_code) ); - ptr = DOSMEM_GetBlock( sizeof(enter_xms), &DOSMEM_xms_seg ); + ptr = DOSMEM_GetBlock( sizeof(enter_xms), &DOSMEM_dpmi_segments.xms_seg ); memcpy( ptr, enter_xms, sizeof(enter_xms) ); - ptr = DOSMEM_GetBlock( sizeof(enter_pm), &DOSMEM_dpmi_seg ); + ptr = DOSMEM_GetBlock( sizeof(enter_pm), &DOSMEM_dpmi_segments.dpmi_seg ); memcpy( ptr, enter_pm, sizeof(enter_pm) ); - DOSMEM_dpmi_sel = SELECTOR_AllocBlock( ptr, sizeof(enter_pm), WINE_LDT_FLAGS_CODE ); + DOSMEM_dpmi_segments.dpmi_sel = SELECTOR_AllocBlock( ptr, sizeof(enter_pm), WINE_LDT_FLAGS_CODE ); } static BIOSDATA * DOSMEM_BiosData(void) @@ -215,22 +217,6 @@ static BIOSDATA * DOSMEM_BiosData(void) return (BIOSDATA *)(DOSMEM_sysmem + 0x400); } -/* Add a structure in the BiosSys area (with size and index) and - return its offset */ -WORD DOSMEM_AddBiosSysStruct(int size,int index) -{ - int Offset = CurrentStructOffset; - StructOffset[index]= CurrentStructOffset; - CurrentStructOffset += size; - return Offset; -} - -/* Return the offset of a structure specified by the index */ -WORD DOSMEM_GetBiosSysStructOffset(int index) -{ - return StructOffset[index]; -} - /*********************************************************************** * DOSMEM_FillBiosSegments @@ -241,6 +227,7 @@ static void DOSMEM_FillBiosSegments(void) { BYTE *pBiosSys = DOSMEM_dosmem + 0xf0000; BYTE *pBiosROMTable = pBiosSys+0xe6f5; + BIOS_EXTRA *extra = (BIOS_EXTRA *)(DOSMEM_dosmem + (int)BIOS_EXTRA_PTR); BIOSDATA *pBiosData = DOSMEM_BiosData(); /* Supported VESA mode, see int10.c */ @@ -251,16 +238,11 @@ static void DOSMEM_FillBiosSegments(void) char * ConstVesaString = "WINE SVGA BOARD"; int i; - VIDEOFUNCTIONALITY *pVidFunc = (VIDEOFUNCTIONALITY *) - (pBiosSys+DOSMEM_AddBiosSysStruct(sizeof(VIDEOFUNCTIONALITY),OFF_VIDEOFUNCTIONALITY)); - VIDEOSTATE *pVidState = (VIDEOSTATE *) - (pBiosSys+DOSMEM_AddBiosSysStruct(sizeof(VIDEOSTATE),OFF_VIDEOSTATE)); - VESAINFO *pVesaInfo = (VESAINFO *) - (pBiosSys+DOSMEM_AddBiosSysStruct(sizeof(VESAINFO),OFF_VESAINFO)); - char * VesaString = (char *) - (pBiosSys+DOSMEM_AddBiosSysStruct(strlen(ConstVesaString)+1,OFF_VESASTRING)); - WORD * VesaModeList = (WORD *) - (pBiosSys+DOSMEM_AddBiosSysStruct(sizeof(ConstVesaModeList),OFF_VESAMODELIST)); + VIDEOFUNCTIONALITY *pVidFunc = &extra->vid_func; + VIDEOSTATE *pVidState = &extra->vid_state; + VESAINFO *pVesaInfo = &extra->vesa_info; + char * VesaString = extra->vesa_string; + WORD * VesaModeList = extra->vesa_modes; /* Clear all unused values */ memset( pBiosData, 0, sizeof(*pBiosData) ); @@ -317,7 +299,7 @@ static void DOSMEM_FillBiosSegments(void) pVidFunc->SavePointerFlags = 0x3f; /* FIXME: always real mode ? */ - pVidState->StaticFuncTable = (0xf000<<16)+DOSMEM_GetBiosSysStructOffset(OFF_VIDEOFUNCTIONALITY); + pVidState->StaticFuncTable = BIOS_EXTRA_SEGPTR + offsetof(BIOS_EXTRA,vid_func); pVidState->VideoMode = pBiosData->VideoMode; /* needs updates! */ pVidState->NumberColumns = pBiosData->VideoColumns; /* needs updates! */ pVidState->RegenBufLen = 0; @@ -353,10 +335,10 @@ static void DOSMEM_FillBiosSegments(void) pVesaInfo->Major = 2; pVesaInfo->Minor = 0; /* FIXME: always real mode ? */ - pVesaInfo->StaticVendorString = (0xF000<<16)+DOSMEM_GetBiosSysStructOffset(OFF_VESASTRING); + pVesaInfo->StaticVendorString = BIOS_EXTRA_SEGPTR + offsetof(BIOS_EXTRA,vesa_string); pVesaInfo->CapabilitiesFlags = 0xfffffffd; /* FIXME: not really supported */ /* FIXME: always real mode ? */ - pVesaInfo->StaticModeList = (0xF000<<16)+DOSMEM_GetBiosSysStructOffset(OFF_VESAMODELIST); + pVesaInfo->StaticModeList = BIOS_EXTRA_SEGPTR + offsetof(BIOS_EXTRA,vesa_modes); strcpy(VesaString,ConstVesaString); memcpy(VesaModeList,ConstVesaModeList,sizeof(ConstVesaModeList)); diff --git a/msdos/dpmi.c b/msdos/dpmi.c index 0e5cd985de4..fdbdc7cd579 100644 --- a/msdos/dpmi.c +++ b/msdos/dpmi.c @@ -258,7 +258,7 @@ void WINAPI INT_Int31Handler( CONTEXT86 *context ) DWORD dw; BYTE *ptr; - if (context->SegCs == DOSMEM_dpmi_sel) { + if (context->SegCs == DOSMEM_dpmi_segments.dpmi_sel) { RawModeSwitch( context ); return; } @@ -472,7 +472,7 @@ void WINAPI INT_Int31Handler( CONTEXT86 *context ) /* we probably won't need this kind of state saving */ SET_AX( context, 0 ); /* real mode: just point to the lret */ - SET_BX( context, DOSMEM_wrap_seg ); + SET_BX( context, DOSMEM_dpmi_segments.wrap_seg ); context->Ecx = 2; /* protected mode: don't have any handler yet... */ FIXME("no protected-mode dummy state save/restore handler yet\n"); @@ -483,10 +483,10 @@ void WINAPI INT_Int31Handler( CONTEXT86 *context ) case 0x0306: /* Get Raw Mode Switch Addresses */ TRACE("get raw mode switch addresses\n"); /* real mode, point to standard DPMI return wrapper */ - SET_BX( context, DOSMEM_wrap_seg ); + SET_BX( context, DOSMEM_dpmi_segments.wrap_seg ); context->Ecx = 0; /* protected mode, point to DPMI call wrapper */ - SET_SI( context, DOSMEM_dpmi_sel ); + SET_SI( context, DOSMEM_dpmi_segments.dpmi_sel ); context->Edi = 8; /* offset of the INT 0x31 call */ break; case 0x0400: /* Get DPMI version */ diff --git a/msdos/int2f.c b/msdos/int2f.c index ddef2ef1efd..9adc43dcaea 100644 --- a/msdos/int2f.c +++ b/msdos/int2f.c @@ -129,7 +129,7 @@ void WINAPI INT_Int2fHandler( CONTEXT86 *context ) break; case 0x10: /* XMS v2+ get driver address */ { - context->SegEs = DOSMEM_xms_seg; + context->SegEs = DOSMEM_dpmi_segments.xms_seg; SET_BX( context, 0 ); break; } @@ -374,7 +374,7 @@ static void do_int2f_16( CONTEXT86 *context ) SET_CL( context, si.wProcessorLevel ); SET_DX( context, 0x005a ); /* DPMI major/minor 0.90 */ SET_SI( context, 0 ); /* # of para. of DOS extended private data */ - context->SegEs = DOSMEM_dpmi_seg; + context->SegEs = DOSMEM_dpmi_segments.dpmi_seg; SET_DI( context, 0 ); /* ES:DI is DPMI switch entry point */ break; }