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 "winbase.h" /* for LPSTARTUPINFO32A */
#include "winnt.h" /* for PCONTEXT */ #include "winnt.h" /* for PCONTEXT */
#include "wincon.h" /* for MOUSE_EVENT_RECORD */ #include "wincon.h" /* for MOUSE_EVENT_RECORD */
#include "miscemu.h"
struct _DOSEVENT; struct _DOSEVENT;
struct DPMI_segments;
typedef void (*DOSRELAY)(CONTEXT86*,void*); 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_psp; /* psp of current DOS task */
extern WORD DOSVM_retval; /* return value of previous DOS task */ extern WORD DOSVM_retval; /* return value of previous DOS task */
extern DWORD DOS_LOLSeg; extern DWORD DOS_LOLSeg;
extern const struct DPMI_segments *DOSVM_dpmi_segments;
#if defined(linux) && defined(__i386__) #if defined(linux) && defined(__i386__)
#define MZ_SUPPORTED #define MZ_SUPPORTED
@ -47,7 +50,6 @@ extern DWORD DOS_LOLSeg;
#define V86_FLAG 0x00020000 #define V86_FLAG 0x00020000
#define BIOS_DATA ((void *)0x400) #define BIOS_DATA ((void *)0x400)
#define BIOS_SYS ((void *)0xf0000)
extern void WINAPI MZ_LoadImage( LPCSTR filename, HANDLE hFile ); extern void WINAPI MZ_LoadImage( LPCSTR filename, HANDLE hFile );
extern BOOL WINAPI MZ_Exec( CONTEXT86 *context, LPCSTR filename, BYTE func, LPVOID paramblk ); 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_psp = 0;
WORD DOSVM_retval = 0; WORD DOSVM_retval = 0;
const struct DPMI_segments *DOSVM_dpmi_segments = NULL;
#ifdef MZ_SUPPORTED #ifdef MZ_SUPPORTED
@ -98,7 +99,7 @@ static int DOSVM_SimulateInt( int vect, CONTEXT86 *context, BOOL inwine )
/* check for our real-mode hooks */ /* check for our real-mode hooks */
if (vect==0x31) { if (vect==0x31) {
if (context->SegCs==DOSMEM_wrap_seg) { if (context->SegCs==DOSVM_dpmi_segments->wrap_seg) {
/* exit from real-mode wrapper */ /* exit from real-mode wrapper */
return -1; return -1;
} }
@ -699,6 +700,7 @@ BOOL WINAPI DOSVM_Init( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved
TRACE("Initializing DOS memory structures\n"); TRACE("Initializing DOS memory structures\n");
DOSMEM_Init( TRUE ); DOSMEM_Init( TRUE );
DOSDEV_InstallDOSDevices(); DOSDEV_InstallDOSDevices();
DOSVM_dpmi_segments = DOSMEM_GetDPMISegments();
#ifdef MZ_SUPPORTED #ifdef MZ_SUPPORTED
event_notifier = CreateEventA(NULL, FALSE, FALSE, NULL); 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 */ case 0x00: /* GET SuperVGA INFORMATION */
TRACE("VESA GET SuperVGA INFORMATION\n"); TRACE("VESA GET SuperVGA INFORMATION\n");
memcpy(CTX_SEG_OFF_TO_LIN(context,context->SegEs,context->Edi), memcpy(CTX_SEG_OFF_TO_LIN(context,context->SegEs,context->Edi),
(char *)BIOS_SYS + DOSMEM_GetBiosSysStructOffset(OFF_VESAINFO), &BIOS_EXTRA_PTR->vesa_info, sizeof(VESAINFO));
sizeof(VESAINFO));
SET_AL( context, 0x4f ); SET_AL( context, 0x4f );
SET_AH( context, 0x00 ); /* 0x00 = successful 0x01 = failed */ SET_AH( context, 0x00 ); /* 0x00 = successful 0x01 = failed */
break; break;
@ -789,7 +788,7 @@ void WINAPI DOSVM_Int10Handler( CONTEXT86 *context )
SET_AL( context, 0x1b ); SET_AL( context, 0x1b );
/* Copy state information structure to ES:DI */ /* Copy state information structure to ES:DI */
memcpy(CTX_SEG_OFF_TO_LIN(context,context->SegEs,context->Edi), 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; break;

View File

@ -310,7 +310,7 @@ callrmproc_again:
*stack16 = LOWORD(context->EFlags); *stack16 = LOWORD(context->EFlags);
} }
/* push return address (return to interrupt wrapper) */ /* push return address (return to interrupt wrapper) */
*(--stack16) = DOSMEM_wrap_seg; *(--stack16) = DOSVM_dpmi_segments->wrap_seg;
*(--stack16) = 0; *(--stack16) = 0;
/* adjust stack */ /* adjust stack */
context->Esp -= 2*sizeof(WORD); context->Esp -= 2*sizeof(WORD);
@ -321,7 +321,7 @@ callrmproc_again:
/* RMCB call, invoke protected-mode handler directly */ /* RMCB call, invoke protected-mode handler directly */
DPMI_CallRMCBProc(context, CurrRMCB, dpmi_flag); DPMI_CallRMCBProc(context, CurrRMCB, dpmi_flag);
/* check if we returned to where we thought we would */ /* 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)) { (LOWORD(context->Eip) != 0)) {
/* we need to continue at different address in real-mode space, /* we need to continue at different address in real-mode space,
so we need to set it all up for real mode again */ 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 ); psp->environment = SELECTOR_AllocBlock( (void *)(env_seg<<4), 0x10000, WINE_LDT_FLAGS_DATA );
pm_ctx = *context; 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 */ /* our mode switch wrapper expects the new CS in DX, and the new SS in AX */
pm_ctx.Eax = ss; pm_ctx.Eax = ss;
pm_ctx.Edx = cs; pm_ctx.Edx = cs;
@ -613,12 +613,12 @@ void WINAPI DOSVM_Int31Handler( CONTEXT86 *context )
{ {
/* check if it's our wrapper */ /* check if it's our wrapper */
TRACE("called from real mode\n"); 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 */ /* This is the protected mode switch */
StartPM(context); StartPM(context);
return; return;
} }
else if (context->SegCs==DOSMEM_xms_seg) else if (context->SegCs==DOSVM_dpmi_segments->xms_seg)
{ {
/* This is the XMS driver entry point */ /* This is the XMS driver entry point */
XMS_Handler(context); XMS_Handler(context);

View File

@ -144,24 +144,37 @@ typedef struct
DWORD StaticModeList; DWORD StaticModeList;
} VESAINFO; } 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" #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_0000H;
extern WORD DOSMEM_BiosDataSeg; extern WORD DOSMEM_BiosDataSeg;
extern WORD DOSMEM_BiosSysSeg; extern WORD DOSMEM_BiosSysSeg;
extern DWORD DOSMEM_CollateTable; extern DWORD DOSMEM_CollateTable;
/* various real-mode code stubs */ /* various real-mode code stubs */
extern WORD DOSMEM_wrap_seg; struct DPMI_segments
extern WORD DOSMEM_xms_seg; {
extern WORD DOSMEM_dpmi_seg; WORD wrap_seg;
extern WORD DOSMEM_dpmi_sel; 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 BOOL DOSMEM_Init(BOOL);
extern void DOSMEM_Tick(WORD timer); extern void DOSMEM_Tick(WORD timer);

View File

@ -47,9 +47,6 @@ WORD DOSMEM_BiosSysSeg; /* BIOS ROM segment at 0xf000:0 */
DWORD DOSMEM_CollateTable; 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 */ /* use 2 low bits of 'size' for the housekeeping */
#define DM_BLOCK_DEBUG 0xABE00000 #define DM_BLOCK_DEBUG 0xABE00000
@ -86,10 +83,15 @@ static char *DOSMEM_dosmem;
static char *DOSMEM_sysmem; static char *DOSMEM_sysmem;
/* various real-mode code stubs */ /* various real-mode code stubs */
WORD DOSMEM_wrap_seg; struct DPMI_segments DOSMEM_dpmi_segments;
WORD DOSMEM_xms_seg;
WORD DOSMEM_dpmi_seg; /***********************************************************************
WORD DOSMEM_dpmi_sel; * DOSMEM_GetDPMISegments
*/
const struct DPMI_segments *DOSMEM_GetDPMISegments(void)
{
return &DOSMEM_dpmi_segments;
}
/*********************************************************************** /***********************************************************************
* DOSMEM_MemoryTop * DOSMEM_MemoryTop
@ -201,13 +203,13 @@ static void DOSMEM_InitDPMI(void)
0xCB /* lret */ 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) ); 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) ); 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) ); 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) static BIOSDATA * DOSMEM_BiosData(void)
@ -215,22 +217,6 @@ static BIOSDATA * DOSMEM_BiosData(void)
return (BIOSDATA *)(DOSMEM_sysmem + 0x400); 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 * DOSMEM_FillBiosSegments
@ -241,6 +227,7 @@ static void DOSMEM_FillBiosSegments(void)
{ {
BYTE *pBiosSys = DOSMEM_dosmem + 0xf0000; BYTE *pBiosSys = DOSMEM_dosmem + 0xf0000;
BYTE *pBiosROMTable = pBiosSys+0xe6f5; BYTE *pBiosROMTable = pBiosSys+0xe6f5;
BIOS_EXTRA *extra = (BIOS_EXTRA *)(DOSMEM_dosmem + (int)BIOS_EXTRA_PTR);
BIOSDATA *pBiosData = DOSMEM_BiosData(); BIOSDATA *pBiosData = DOSMEM_BiosData();
/* Supported VESA mode, see int10.c */ /* Supported VESA mode, see int10.c */
@ -251,16 +238,11 @@ static void DOSMEM_FillBiosSegments(void)
char * ConstVesaString = "WINE SVGA BOARD"; char * ConstVesaString = "WINE SVGA BOARD";
int i; int i;
VIDEOFUNCTIONALITY *pVidFunc = (VIDEOFUNCTIONALITY *) VIDEOFUNCTIONALITY *pVidFunc = &extra->vid_func;
(pBiosSys+DOSMEM_AddBiosSysStruct(sizeof(VIDEOFUNCTIONALITY),OFF_VIDEOFUNCTIONALITY)); VIDEOSTATE *pVidState = &extra->vid_state;
VIDEOSTATE *pVidState = (VIDEOSTATE *) VESAINFO *pVesaInfo = &extra->vesa_info;
(pBiosSys+DOSMEM_AddBiosSysStruct(sizeof(VIDEOSTATE),OFF_VIDEOSTATE)); char * VesaString = extra->vesa_string;
VESAINFO *pVesaInfo = (VESAINFO *) WORD * VesaModeList = extra->vesa_modes;
(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));
/* Clear all unused values */ /* Clear all unused values */
memset( pBiosData, 0, sizeof(*pBiosData) ); memset( pBiosData, 0, sizeof(*pBiosData) );
@ -317,7 +299,7 @@ static void DOSMEM_FillBiosSegments(void)
pVidFunc->SavePointerFlags = 0x3f; pVidFunc->SavePointerFlags = 0x3f;
/* FIXME: always real mode ? */ /* 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->VideoMode = pBiosData->VideoMode; /* needs updates! */
pVidState->NumberColumns = pBiosData->VideoColumns; /* needs updates! */ pVidState->NumberColumns = pBiosData->VideoColumns; /* needs updates! */
pVidState->RegenBufLen = 0; pVidState->RegenBufLen = 0;
@ -353,10 +335,10 @@ static void DOSMEM_FillBiosSegments(void)
pVesaInfo->Major = 2; pVesaInfo->Major = 2;
pVesaInfo->Minor = 0; pVesaInfo->Minor = 0;
/* FIXME: always real mode ? */ /* 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 */ pVesaInfo->CapabilitiesFlags = 0xfffffffd; /* FIXME: not really supported */
/* FIXME: always real mode ? */ /* 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); strcpy(VesaString,ConstVesaString);
memcpy(VesaModeList,ConstVesaModeList,sizeof(ConstVesaModeList)); memcpy(VesaModeList,ConstVesaModeList,sizeof(ConstVesaModeList));

View File

@ -258,7 +258,7 @@ void WINAPI INT_Int31Handler( CONTEXT86 *context )
DWORD dw; DWORD dw;
BYTE *ptr; BYTE *ptr;
if (context->SegCs == DOSMEM_dpmi_sel) { if (context->SegCs == DOSMEM_dpmi_segments.dpmi_sel) {
RawModeSwitch( context ); RawModeSwitch( context );
return; return;
} }
@ -472,7 +472,7 @@ void WINAPI INT_Int31Handler( CONTEXT86 *context )
/* we probably won't need this kind of state saving */ /* we probably won't need this kind of state saving */
SET_AX( context, 0 ); SET_AX( context, 0 );
/* real mode: just point to the lret */ /* real mode: just point to the lret */
SET_BX( context, DOSMEM_wrap_seg ); SET_BX( context, DOSMEM_dpmi_segments.wrap_seg );
context->Ecx = 2; context->Ecx = 2;
/* protected mode: don't have any handler yet... */ /* protected mode: don't have any handler yet... */
FIXME("no protected-mode dummy state save/restore handler yet\n"); 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 */ case 0x0306: /* Get Raw Mode Switch Addresses */
TRACE("get raw mode switch addresses\n"); TRACE("get raw mode switch addresses\n");
/* real mode, point to standard DPMI return wrapper */ /* 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; context->Ecx = 0;
/* protected mode, point to DPMI call wrapper */ /* 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 */ context->Edi = 8; /* offset of the INT 0x31 call */
break; break;
case 0x0400: /* Get DPMI version */ case 0x0400: /* Get DPMI version */

View File

@ -129,7 +129,7 @@ void WINAPI INT_Int2fHandler( CONTEXT86 *context )
break; break;
case 0x10: /* XMS v2+ get driver address */ case 0x10: /* XMS v2+ get driver address */
{ {
context->SegEs = DOSMEM_xms_seg; context->SegEs = DOSMEM_dpmi_segments.xms_seg;
SET_BX( context, 0 ); SET_BX( context, 0 );
break; break;
} }
@ -374,7 +374,7 @@ static void do_int2f_16( CONTEXT86 *context )
SET_CL( context, si.wProcessorLevel ); SET_CL( context, si.wProcessorLevel );
SET_DX( context, 0x005a ); /* DPMI major/minor 0.90 */ SET_DX( context, 0x005a ); /* DPMI major/minor 0.90 */
SET_SI( context, 0 ); /* # of para. of DOS extended private data */ 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 */ SET_DI( context, 0 ); /* ES:DI is DPMI switch entry point */
break; break;
} }