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:
parent
8551a8f3fb
commit
65ea73fedf
|
@ -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,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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue