From 32486cded4e978ca8937510a30b18617c493b522 Mon Sep 17 00:00:00 2001 From: Ove Kaaven Date: Sun, 11 Oct 1998 12:16:56 +0000 Subject: [PATCH] Implemented basic XMS functions. wcb.exe (Win16 disassembler) now seems to work fine under Wine. --- msdos/Makefile.in | 1 + msdos/int2f.c | 26 ++++++++++++++ msdos/xms.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 118 insertions(+) create mode 100644 msdos/xms.c diff --git a/msdos/Makefile.in b/msdos/Makefile.in index 6ec0f26af54..9c9cbcbbd6c 100644 --- a/msdos/Makefile.in +++ b/msdos/Makefile.in @@ -9,6 +9,7 @@ C_SRCS = \ cdrom.c \ dosmem.c \ dpmi.c \ + xms.c \ int10.c \ int11.c \ int12.c \ diff --git a/msdos/int2f.c b/msdos/int2f.c index 7a88d80e574..4d6186ab6fc 100644 --- a/msdos/int2f.c +++ b/msdos/int2f.c @@ -95,8 +95,34 @@ void WINAPI INT_Int2fHandler( CONTEXT *context ) do_int2f_16( context ); break; case 0x43: +#if 1 + switch (AL_reg(context)) + { + case 0x00: /* XMS v2+ installation check */ + WARN(int,"XMS is not fully implemented\n"); + AL_reg(context) = 0x80; + break; + case 0x10: /* XMS v2+ get driver address */ + { + TDB *pTask = (TDB *)GlobalLock16( GetCurrentTask() ); + NE_MODULE *pModule = pTask ? NE_GetPtr( pTask->hModule ) : NULL; + GlobalUnlock16( GetCurrentTask() ); +#ifdef MZ_SUPPORTED + if (pModule && pModule->lpDosTask) + ES_reg(context) = pModule->lpDosTask->xms_seg; + else +#endif + ES_reg(context) = 0; + BX_reg(context) = 0; + break; + } + default: + INT_BARF( context, 0x2f ); + } +#else FIXME(int,"check for XMS (not supported)\n"); AL_reg(context) = 0x42; /* != 0x80 */ +#endif break; case 0x45: diff --git a/msdos/xms.c b/msdos/xms.c new file mode 100644 index 00000000000..3a18ebcb813 --- /dev/null +++ b/msdos/xms.c @@ -0,0 +1,91 @@ +/* + * XMS v2+ emulation + * + * Copyright 1998 Ove Kåven + * + * This XMS emulation is hooked through the DPMI interrupt. + */ + +#include +#include +#include "windows.h" +#include "module.h" +#include "miscemu.h" +#include "toolhelp.h" +#include "debug.h" +#include "selectors.h" + +typedef struct { + WORD Handle; + DWORD Offset; +} WINE_PACKED MOVEOFS; + +typedef struct { + DWORD Length; + MOVEOFS Source; + MOVEOFS Dest; +} WINE_PACKED MOVESTRUCT; + +static BYTE * XMS_Offset( MOVEOFS *ofs ) +{ + if (ofs->Handle) return (BYTE*)GlobalLock16(ofs->Handle)+ofs->Offset; + else return (BYTE*)DOSMEM_MapRealToLinear(ofs->Offset); +} + +/********************************************************************** + * XMS_Handler + */ + +void WINAPI XMS_Handler( CONTEXT *context ) +{ + switch(AH_reg(context)) + { + case 0x00: /* Get XMS version number */ + TRACE(int31, "get XMS version number\n"); + AX_reg(context) = 0x0200; /* 2.0 */ + BX_reg(context) = 0x0000; /* internal revision */ + DX_reg(context) = 0x0001; /* HMA exists */ + break; + case 0x08: /* Query Free Extended Memory */ + { + MEMMANINFO mmi; + + TRACE(int31, "query free extended memory\n"); + mmi.dwSize = sizeof(mmi); + MemManInfo(&mmi); + AX_reg(context) = mmi.dwFreePages>>10; + DX_reg(context) = mmi.dwLargestFreeBlock>>10; + break; + } + case 0x09: /* Allocate Extended Memory Block */ + TRACE(int31, "allocate extended memory block (%dK)\n", + DX_reg(context)); + DX_reg(context) = GlobalAlloc16(GMEM_MOVEABLE, + (DWORD)DX_reg(context)<<10); + AX_reg(context) = DX_reg(context) ? 1 : 0; + if (!DX_reg(context)) BL_reg(context) = 0xA0; /* out of memory */ + break; + case 0x0a: /* Free Extended Memory Block */ + TRACE(int31, "free extended memory block %04x\n",DX_reg(context)); + GlobalFree16(DX_reg(context)); + break; + case 0x0b: /* Move Extended Memory Block */ + { + MOVESTRUCT*move=CTX_SEG_OFF_TO_LIN(context, + DS_reg(context),SI_reg(context)); + BYTE*src,*dst; + TRACE(int31, "move extended memory block\n"); + src=XMS_Offset(&move->Source); + dst=XMS_Offset(&move->Dest); + memcpy(dst,src,move->Length); + if (move->Source.Handle) GlobalUnlock16(move->Source.Handle); + if (move->Dest.Handle) GlobalUnlock16(move->Dest.Handle); + break; + } + default: + INT_BARF( context, 0x31 ); + AX_reg(context) = 0x0000; /* failure */ + BL_reg(context) = 0x80; /* function not implemented */ + break; + } +}