Commit 65ea73fe authored by Alexandre Julliard's avatar Alexandre Julliard

Added DPMI segments structure and related function to avoid direct

references to dosmem internal variables. Determine BIOS system offsets at compile time.
parent 8551a8f3
......@@ -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 );
......
......@@ -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);
......
......@@ -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;
......
......@@ -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);
......
......@@ -144,13 +144,20 @@ typedef struct
DWORD StaticModeList;
} VESAINFO;
#include "poppack.h"
/* 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;
/* Index for bios structures stored at f000:e000 */
enum {OFF_VIDEOSTATE,OFF_VIDEOFUNCTIONALITY,OFF_VESAINFO,OFF_VESASTRING,OFF_VESAMODELIST};
#define BIOS_EXTRA_PTR ((BIOS_EXTRA *)0xfe000)
#define BIOS_EXTRA_SEGPTR MAKESEGPTR(0xf000,0xe000)
extern WORD DOSMEM_AddBiosSysStruct(int,int);
extern WORD DOSMEM_GetBiosSysStructOffset(int);
#include "poppack.h"
extern WORD DOSMEM_0000H;
extern WORD DOSMEM_BiosDataSeg;
......@@ -158,10 +165,16 @@ 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);
......
......@@ -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));
......
......@@ -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 */
......
......@@ -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;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment