Commit 16df50ef authored by Eric Pouech's avatar Eric Pouech Committed by Alexandre Julliard

Moved DOS memory handling to winedos.

parent e6267369
......@@ -40,7 +40,6 @@
#include "wine/winbase16.h"
#include "ntstatus.h"
#include "toolhelp.h"
#include "miscemu.h"
#include "stackframe.h"
#include "kernel_private.h"
#include "wine/debug.h"
......@@ -77,6 +76,23 @@ static int globalArenaSize;
#define VALID_HANDLE(handle) (((handle)>>__AHSHIFT)<globalArenaSize)
#define GET_ARENA_PTR(handle) (pGlobalArena + ((handle) >> __AHSHIFT))
static inline void* DOSMEM_AllocBlock(UINT size, UINT16* pseg)
{
if (!winedos.AllocDosBlock) load_winedos();
return winedos.AllocDosBlock ? winedos.AllocDosBlock(size, pseg) : NULL;
}
static inline BOOL DOSMEM_FreeBlock(void* ptr)
{
if (!winedos.FreeDosBlock) load_winedos();
return winedos.FreeDosBlock ? winedos.FreeDosBlock( ptr ) : FALSE;
}
static inline UINT DOSMEM_ResizeBlock(void *ptr, UINT size, BOOL exact)
{
if (!winedos.ResizeDosBlock) load_winedos();
return winedos.ResizeDosBlock ? winedos.ResizeDosBlock(ptr, size, TRUE) : 0;
}
/***********************************************************************
* GLOBAL_GetArena
......@@ -336,7 +352,7 @@ HGLOBAL16 WINAPI GlobalReAlloc16(
newptr = 0;
else
{
newptr = DOSMEM_GetBlock( size, 0 );
newptr = DOSMEM_AllocBlock( size, 0 );
if (newptr)
{
memcpy( newptr, ptr, oldsize );
......@@ -757,7 +773,7 @@ DWORD WINAPI GlobalDOSAlloc16(
DWORD size /* [in] Number of bytes to be allocated */
) {
UINT16 uParagraph;
LPVOID lpBlock = DOSMEM_GetBlock( size, &uParagraph );
LPVOID lpBlock = DOSMEM_AllocBlock( size, &uParagraph );
if( lpBlock )
{
......
......@@ -30,7 +30,6 @@
#include "wine/winuser16.h"
#include "excpt.h"
#include "module.h"
#include "miscemu.h"
#include "wine/debug.h"
#include "kernel_private.h"
#include "thread.h"
......@@ -67,34 +66,6 @@ inline static void *get_stack( CONTEXT86 *context )
return wine_ldt_get_ptr( context->SegSs, context->Esp );
}
static void (WINAPI *DOS_EmulateInterruptPM)( CONTEXT86 *context, BYTE intnum );
static void (WINAPI *DOS_CallBuiltinHandler)( CONTEXT86 *context, BYTE intnum );
static DWORD (WINAPI *DOS_inport)( int port, int size );
static void (WINAPI *DOS_outport)( int port, int size, DWORD val );
static void init_winedos(void)
{
static HMODULE module;
if (module) return;
module = LoadLibraryA( "winedos.dll" );
if (!module)
{
ERR("could not load winedos.dll, DOS subsystem unavailable\n");
module = (HMODULE)1; /* don't try again */
return;
}
#define GET_ADDR(func) DOS_##func = (void *)GetProcAddress(module, #func);
GET_ADDR(inport);
GET_ADDR(outport);
GET_ADDR(EmulateInterruptPM);
GET_ADDR(CallBuiltinHandler);
#undef GET_ADDR
}
/***********************************************************************
* INSTR_ReplaceSelector
*
......@@ -112,7 +83,11 @@ static BOOL INSTR_ReplaceSelector( CONTEXT86 *context, WORD *sel )
{
static WORD sys_timer = 0;
if (!sys_timer)
sys_timer = CreateSystemTimer( 55, DOSMEM_Tick );
{
if (!winedos.BiosTick) load_winedos();
if (winedos.BiosTick)
sys_timer = CreateSystemTimer( 55, winedos.BiosTick );
}
*sel = DOSMEM_BiosDataSeg;
return TRUE;
}
......@@ -367,8 +342,8 @@ static DWORD INSTR_inport( WORD port, int size, CONTEXT86 *context )
{
DWORD res = ~0U;
if (!DOS_inport) init_winedos();
if (DOS_inport) res = DOS_inport( port, size );
if (!winedos.inport) load_winedos();
if (winedos.inport) res = winedos.inport( port, size );
if (TRACE_ON(io))
{
......@@ -399,8 +374,8 @@ static DWORD INSTR_inport( WORD port, int size, CONTEXT86 *context )
*/
static void INSTR_outport( WORD port, int size, DWORD val, CONTEXT86 *context )
{
if (!DOS_outport) init_winedos();
if (DOS_outport) DOS_outport( port, size, val );
if (!winedos.outport) load_winedos();
if (winedos.outport) winedos.outport( port, size, val );
if (TRACE_ON(io))
{
......@@ -733,11 +708,11 @@ DWORD INSTR_EmulateInstruction( EXCEPTION_RECORD *rec, CONTEXT86 *context )
case 0xcd: /* int <XX> */
if (wine_ldt_is_system(context->SegCs)) break; /* don't emulate it in 32-bit code */
if (!DOS_EmulateInterruptPM) init_winedos();
if (DOS_EmulateInterruptPM)
if (!winedos.EmulateInterruptPM) load_winedos();
if (winedos.EmulateInterruptPM)
{
context->Eip += prefixlen + 2;
DOS_EmulateInterruptPM( context, instr[1] );
winedos.EmulateInterruptPM( context, instr[1] );
return ExceptionContinueExecution;
}
break; /* Unable to emulate it */
......@@ -839,8 +814,8 @@ DWORD INSTR_EmulateInstruction( EXCEPTION_RECORD *rec, CONTEXT86 *context )
*/
void INSTR_CallBuiltinHandler( CONTEXT86 *context, BYTE intnum )
{
if (!DOS_CallBuiltinHandler) init_winedos();
if (DOS_CallBuiltinHandler) DOS_CallBuiltinHandler( context, intnum );
if (!winedos.CallBuiltinHandler) load_winedos();
if (winedos.CallBuiltinHandler) winedos.CallBuiltinHandler( context, intnum );
}
......
......@@ -1167,11 +1167,6 @@
# Wine dll separation hacks, these will go away, don't use them
#
@ cdecl DOSMEM_AllocSelector(long)
@ cdecl DOSMEM_Available()
@ cdecl DOSMEM_FreeBlock(ptr)
@ cdecl DOSMEM_GetBlock(long ptr)
@ cdecl DOSMEM_InitDosMem(long)
@ cdecl DOSMEM_ResizeBlock(ptr long long)
@ cdecl LOCAL_Alloc(long long long)
@ cdecl LOCAL_Compact(long long long)
@ cdecl LOCAL_CountFree(long)
......
......@@ -90,5 +90,30 @@ typedef struct
WORD stackbottom; /* Bottom of the stack */
} INSTANCEDATA;
#include "poppack.h"
extern WORD DOSMEM_0000H;
extern WORD DOSMEM_BiosDataSeg;
extern WORD DOSMEM_BiosSysSeg;
/* msdos/dosmem.c */
extern BOOL DOSMEM_Init(void);
extern WORD DOSMEM_AllocSelector(WORD);
extern LPVOID DOSMEM_MapRealToLinear(DWORD); /* real-mode to linear */
extern LPVOID DOSMEM_MapDosToLinear(UINT); /* linear DOS to Wine */
extern UINT DOSMEM_MapLinearToDos(LPVOID); /* linear Wine to DOS */
extern void load_winedos(void);
extern struct winedos_exports
{
/* for global16.c */
void* (*AllocDosBlock)(UINT size, UINT16* pseg);
BOOL (*FreeDosBlock)(void* ptr);
UINT (*ResizeDosBlock)(void *ptr, UINT size, BOOL exact);
/* for instr.c */
void (WINAPI *EmulateInterruptPM)( CONTEXT86 *context, BYTE intnum );
void (WINAPI *CallBuiltinHandler)( CONTEXT86 *context, BYTE intnum );
DWORD (WINAPI *inport)( int port, int size );
void (WINAPI *outport)( int port, int size, DWORD val );
void (* BiosTick)(WORD timer);
} winedos;
#endif
......@@ -14,6 +14,7 @@ C_SRCS = \
dma.c \
dosaspi.c \
dosconf.c \
dosmem.c \
dosvm.c \
fpu.c \
himem.c \
......
......@@ -24,11 +24,11 @@
#include <stdarg.h>
#include "windef.h"
#include "wine/library.h"
#include "wine/windef16.h"
#include "winbase.h"
#include "winnt.h" /* for PCONTEXT */
#include "wincon.h" /* for MOUSE_EVENT_RECORD */
#include "miscemu.h"
#define MAX_DOS_DRIVES 26
......@@ -182,6 +182,68 @@ extern struct DPMI_segments *DOSVM_dpmi_segments;
#define SET_CH(context,val) ((void)((context)->Ecx = ((context)->Ecx & ~0xff00) | (((BYTE)(val)) << 8)))
#define SET_DH(context,val) ((void)((context)->Edx = ((context)->Edx & ~0xff00) | (((BYTE)(val)) << 8)))
#include <pshpack1.h>
typedef struct
{
WORD Com1Addr; /* 00: COM1 I/O address */
WORD Com2Addr; /* 02: COM2 I/O address */
WORD Com3Addr; /* 04: COM3 I/O address */
WORD Com4Addr; /* 06: COM4 I/O address */
WORD Lpt1Addr; /* 08: LPT1 I/O address */
WORD Lpt2Addr; /* 0a: LPT2 I/O address */
WORD Lpt3Addr; /* 0c: LPT3 I/O address */
WORD Lpt4Addr; /* 0e: LPT4 I/O address */
WORD InstalledHardware; /* 10: Installed hardware flags */
BYTE POSTstatus; /* 12: Power-On Self Test status */
WORD MemSize; /* 13: Base memory size in Kb */
WORD unused1; /* 15: Manufacturing test scratch pad */
BYTE KbdFlags1; /* 17: Keyboard flags 1 */
BYTE KbdFlags2; /* 18: Keyboard flags 2 */
BYTE unused2; /* 19: Keyboard driver workspace */
WORD NextKbdCharPtr; /* 1a: Next character in kbd buffer */
WORD FirstKbdCharPtr; /* 1c: First character in kbd buffer */
WORD KbdBuffer[16]; /* 1e: Keyboard buffer */
BYTE DisketteStatus1; /* 3e: Diskette recalibrate status */
BYTE DisketteStatus2; /* 3f: Diskette motor status */
BYTE DisketteStatus3; /* 40: Diskette motor timeout */
BYTE DisketteStatus4; /* 41: Diskette last operation status */
BYTE DiskStatus[7]; /* 42: Disk status/command bytes */
BYTE VideoMode; /* 49: Video mode */
WORD VideoColumns; /* 4a: Number of columns */
WORD VideoPageSize; /* 4c: Video page size in bytes */
WORD VideoPageStartAddr; /* 4e: Video page start address */
BYTE VideoCursorPos[16]; /* 50: Cursor position for 8 pages, column/row order */
WORD VideoCursorType; /* 60: Video cursor type */
BYTE VideoCurPage; /* 62: Video current page */
WORD VideoCtrlAddr; /* 63: Video controller address */
BYTE VideoReg1; /* 65: Video mode select register */
BYTE VideoReg2; /* 66: Video CGA palette register */
DWORD ResetEntry; /* 67: Warm reset entry point */
BYTE LastIRQ; /* 6b: Last unexpected interrupt */
DWORD Ticks; /* 6c: Ticks since midnight */
BYTE TicksOverflow; /* 70: Timer overflow if past midnight */
BYTE CtrlBreakFlag; /* 71: Ctrl-Break flag */
WORD ResetFlag; /* 72: POST Reset flag */
BYTE DiskOpStatus; /* 74: Last hard-disk operation status */
BYTE NbHardDisks; /* 75: Number of hard disks */
BYTE DiskCtrlByte; /* 76: Disk control byte */
BYTE DiskIOPort; /* 77: Disk I/O port offset */
BYTE LptTimeout[4]; /* 78: Timeouts for parallel ports */
BYTE ComTimeout[4]; /* 7c: Timeouts for serial ports */
WORD KbdBufferStart; /* 80: Keyboard buffer start */
WORD KbdBufferEnd; /* 82: Keyboard buffer end */
BYTE RowsOnScreenMinus1; /* 84: EGA only */
WORD BytesPerChar; /* 85: EGA only */
BYTE ModeOptions; /* 87: EGA only */
BYTE FeatureBitsSwitches; /* 88: EGA only */
BYTE VGASettings; /* 89: VGA misc settings */
BYTE DisplayCombination; /* 8A: VGA display combinations */
BYTE DiskDataRate; /* 8B: Last disk data rate selected */
} BIOSDATA;
#include <poppack.h>
/* module.c */
extern void WINAPI MZ_LoadImage( LPCSTR filename, HANDLE hFile );
extern BOOL WINAPI MZ_Exec( CONTEXT86 *context, LPCSTR filename, BYTE func, LPVOID paramblk );
......@@ -201,7 +263,6 @@ extern void WINAPI DOSVM_QueueEvent( INT irq, INT priority, DOSRELAY relay, LPVO
extern void WINAPI DOSVM_PIC_ioport_out( WORD port, BYTE val );
extern void WINAPI DOSVM_SetTimer( UINT ticks );
extern UINT WINAPI DOSVM_GetTimer( void );
extern BIOSDATA *DOSVM_BiosData( void );
/* devices.c */
extern void DOSDEV_InstallDOSDevices(void);
......@@ -221,10 +282,20 @@ extern void DMA_ioport_out( WORD port, BYTE val );
extern BYTE DMA_ioport_in( WORD port );
/* dosaspi.c */
void WINAPI DOSVM_ASPIHandler(CONTEXT86*);
extern void WINAPI DOSVM_ASPIHandler(CONTEXT86*);
/* dosconf.c */
DOSCONF *DOSCONF_GetConfig( void );
extern DOSCONF *DOSCONF_GetConfig( void );
/* dosmem.c */
extern void DOSMEM_InitDosMemory(void);
extern BOOL DOSMEM_MapDosLayout(void);
extern WORD DOSMEM_AllocSelector(WORD); /* FIXME: to be removed */
extern LPVOID DOSMEM_AllocBlock(UINT size, WORD* p);
extern BOOL DOSMEM_FreeBlock(void* ptr);
extern UINT DOSMEM_ResizeBlock(void* ptr, UINT size, BOOL exact);
extern UINT DOSMEM_Available(void);
extern BIOSDATA *DOSVM_BiosData( void );
/* fpu.c */
extern void WINAPI DOSVM_Int34Handler(CONTEXT86*);
......
......@@ -694,26 +694,6 @@ void WINAPI DOSVM_AcknowledgeIRQ( CONTEXT86 *context )
/**********************************************************************
* DOSVM_BiosData
*
* Get pointer to BIOS data area. This is not at fixed location
* because those Win16 programs that do not use any real mode code have
* protected NULL pointer catching block at low linear memory and
* BIOS data has been moved to another location.
*/
BIOSDATA *DOSVM_BiosData( void )
{
LDT_ENTRY entry;
FARPROC16 proc;
proc = GetProcAddress16( GetModuleHandle16( "KERNEL" ),
(LPCSTR)(ULONG_PTR)193 );
wine_ldt_get_entry( LOWORD(proc), &entry );
return (BIOSDATA *)wine_ldt_get_base( &entry );
}
/**********************************************************************
* DllMain (DOSVM.0)
*/
BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved )
......@@ -723,6 +703,7 @@ BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved )
if (fdwReason == DLL_PROCESS_ATTACH)
{
DisableThreadLibraryCalls(hinstDLL);
DOSMEM_InitDosMemory();
DOSVM_InitSegments();
event_notifier = CreateEventW(NULL, FALSE, FALSE, NULL);
......
......@@ -4904,7 +4904,7 @@ void WINAPI DOSVM_Int21Handler( CONTEXT86 *context )
selector = LOWORD( rv );
}
else
DOSMEM_GetBlock( bytes, &selector );
DOSMEM_AllocBlock( bytes, &selector );
if (selector)
{
......@@ -4934,7 +4934,7 @@ void WINAPI DOSVM_Int21Handler( CONTEXT86 *context )
context->SegEs = 0;
}
else
ok = DOSMEM_FreeBlock( (void*)((DWORD)context->SegEs << 4) );
ok = DOSMEM_FreeBlock( PTR_REAL_TO_LIN(context->SegEs, 0) );
if (!ok)
{
......
......@@ -470,7 +470,7 @@ callrmproc_again:
if (!already) {
if (!context->SegSs) {
alloc = 1; /* allocate default stack */
stack16 = addr = DOSMEM_GetBlock( 64, (UINT16 *)&(context->SegSs) );
stack16 = addr = DOSMEM_AllocBlock( 64, (UINT16 *)&(context->SegSs) );
context->Esp = 64-2;
stack16 += 32-1;
if (!addr) {
......@@ -649,7 +649,7 @@ static RMCB *DPMI_AllocRMCB( void )
if (NewRMCB)
{
LPVOID RMCBmem = DOSMEM_GetBlock(4, &uParagraph);
LPVOID RMCBmem = DOSMEM_AllocBlock(4, &uParagraph);
LPBYTE p = RMCBmem;
*p++ = 0xcd; /* RMCB: */
......@@ -968,7 +968,7 @@ void WINAPI DOSVM_Int31Handler( CONTEXT86 *context )
/* check if Win16 app wants to access lower 64K of DOS memory */
if (base < 0x10000 && DOSVM_IsWin16())
DOSMEM_InitDosMem();
DOSMEM_MapDosLayout();
SetSelectorBase( sel, base );
}
......
......@@ -169,7 +169,7 @@ static WORD MZ_InitEnvironment( LPCSTR env, LPCSTR name )
while (env[sz++]) sz+=strlen(env+sz)+1;
} else sz++;
/* allocate it */
envblk=DOSMEM_GetBlock(sz+sizeof(WORD)+strlen(name)+1,&seg);
envblk=DOSMEM_AllocBlock(sz+sizeof(WORD)+strlen(name)+1,&seg);
/* fill it */
if (env) {
memcpy(envblk,env,sz);
......@@ -195,7 +195,7 @@ static BOOL MZ_InitMemory(void)
{
/* initialize the memory */
TRACE("Initializing DOS memory structures\n");
DOSMEM_InitDosMem();
DOSMEM_MapDosLayout();
DOSDEV_InstallDOSDevices();
return TRUE;
......@@ -283,7 +283,7 @@ static BOOL MZ_DoLoadImage( HANDLE hFile, LPCSTR filename, OverlayBlock *oblk, W
goto load_error;
}
if (avail>max_size) avail=max_size;
psp_start=DOSMEM_GetBlock(avail,&DOSVM_psp);
psp_start=DOSMEM_AllocBlock(avail,&DOSVM_psp);
if (!psp_start) {
ERR("error allocating DOS memory\n");
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
......
......@@ -6,3 +6,11 @@
# I/O functions
@ stdcall inport(long long) DOSVM_inport
@ stdcall outport(long long long) DOSVM_outport
# DOS memory functions
@ cdecl FreeDosBlock(ptr) DOSMEM_FreeBlock
@ cdecl AllocDosBlock(long ptr) DOSMEM_AllocBlock
@ cdecl ResizeDosBlock(ptr long long) DOSMEM_ResizeBlock
# BIOS functions
@ cdecl BiosTick(long)
......@@ -26,83 +26,5 @@
#include <wine/windef16.h>
/* msdos/dosmem.c */
#include <pshpack1.h>
typedef struct
{
WORD Com1Addr; /* 00: COM1 I/O address */
WORD Com2Addr; /* 02: COM2 I/O address */
WORD Com3Addr; /* 04: COM3 I/O address */
WORD Com4Addr; /* 06: COM4 I/O address */
WORD Lpt1Addr; /* 08: LPT1 I/O address */
WORD Lpt2Addr; /* 0a: LPT2 I/O address */
WORD Lpt3Addr; /* 0c: LPT3 I/O address */
WORD Lpt4Addr; /* 0e: LPT4 I/O address */
WORD InstalledHardware; /* 10: Installed hardware flags */
BYTE POSTstatus; /* 12: Power-On Self Test status */
WORD MemSize; /* 13: Base memory size in Kb */
WORD unused1; /* 15: Manufacturing test scratch pad */
BYTE KbdFlags1; /* 17: Keyboard flags 1 */
BYTE KbdFlags2; /* 18: Keyboard flags 2 */
BYTE unused2; /* 19: Keyboard driver workspace */
WORD NextKbdCharPtr; /* 1a: Next character in kbd buffer */
WORD FirstKbdCharPtr; /* 1c: First character in kbd buffer */
WORD KbdBuffer[16]; /* 1e: Keyboard buffer */
BYTE DisketteStatus1; /* 3e: Diskette recalibrate status */
BYTE DisketteStatus2; /* 3f: Diskette motor status */
BYTE DisketteStatus3; /* 40: Diskette motor timeout */
BYTE DisketteStatus4; /* 41: Diskette last operation status */
BYTE DiskStatus[7]; /* 42: Disk status/command bytes */
BYTE VideoMode; /* 49: Video mode */
WORD VideoColumns; /* 4a: Number of columns */
WORD VideoPageSize; /* 4c: Video page size in bytes */
WORD VideoPageStartAddr; /* 4e: Video page start address */
BYTE VideoCursorPos[16]; /* 50: Cursor position for 8 pages, column/row order */
WORD VideoCursorType; /* 60: Video cursor type */
BYTE VideoCurPage; /* 62: Video current page */
WORD VideoCtrlAddr; /* 63: Video controller address */
BYTE VideoReg1; /* 65: Video mode select register */
BYTE VideoReg2; /* 66: Video CGA palette register */
DWORD ResetEntry; /* 67: Warm reset entry point */
BYTE LastIRQ; /* 6b: Last unexpected interrupt */
DWORD Ticks; /* 6c: Ticks since midnight */
BYTE TicksOverflow; /* 70: Timer overflow if past midnight */
BYTE CtrlBreakFlag; /* 71: Ctrl-Break flag */
WORD ResetFlag; /* 72: POST Reset flag */
BYTE DiskOpStatus; /* 74: Last hard-disk operation status */
BYTE NbHardDisks; /* 75: Number of hard disks */
BYTE DiskCtrlByte; /* 76: Disk control byte */
BYTE DiskIOPort; /* 77: Disk I/O port offset */
BYTE LptTimeout[4]; /* 78: Timeouts for parallel ports */
BYTE ComTimeout[4]; /* 7c: Timeouts for serial ports */
WORD KbdBufferStart; /* 80: Keyboard buffer start */
WORD KbdBufferEnd; /* 82: Keyboard buffer end */
BYTE RowsOnScreenMinus1; /* 84: EGA only */
WORD BytesPerChar; /* 85: EGA only */
BYTE ModeOptions; /* 87: EGA only */
BYTE FeatureBitsSwitches; /* 88: EGA only */
BYTE VGASettings; /* 89: VGA misc settings */
BYTE DisplayCombination; /* 8A: VGA display combinations */
BYTE DiskDataRate; /* 8B: Last disk data rate selected */
} BIOSDATA;
#include <poppack.h>
extern WORD DOSMEM_0000H;
extern WORD DOSMEM_BiosDataSeg;
extern WORD DOSMEM_BiosSysSeg;
/* msdos/dosmem.c */
extern BOOL DOSMEM_Init(void);
extern BOOL DOSMEM_InitDosMem(void);
extern void DOSMEM_Tick(WORD timer);
extern WORD DOSMEM_AllocSelector(WORD);
extern LPVOID DOSMEM_GetBlock(UINT size, WORD* p);
extern BOOL DOSMEM_FreeBlock(void* ptr);
extern UINT DOSMEM_ResizeBlock(void* ptr, UINT size, BOOL exact);
extern UINT DOSMEM_Available(void);
extern LPVOID DOSMEM_MapRealToLinear(DWORD); /* real-mode to linear */
extern LPVOID DOSMEM_MapDosToLinear(UINT); /* linear DOS to Wine */
extern UINT DOSMEM_MapLinearToDos(LPVOID); /* linear Wine to DOS */
#endif /* __WINE_MISCEMU_H */
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