Added DPMI segments structure and related function to avoid direct

references to dosmem internal variables.
Determine BIOS system offsets at compile time.
This commit is contained in:
Alexandre Julliard 2002-09-04 18:52:22 +00:00
parent 8551a8f3fb
commit 65ea73fedf
8 changed files with 64 additions and 66 deletions

View File

@ -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 );

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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));

View File

@ -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 */

View File

@ -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;
}