Okay, I forgot one header file from the previous version of this patch. This patch is otherwise the same as the previous patch except that file include/msdos.h has been added. Changelog: Move int08 stub and LOL to upper memory. Move simple int21 functions to winedos. Index: dlls/winedos/int21.c =================================================================== RCS file: /home/wine/wine/dlls/winedos/int21.c,v retrieving revision 1.17 diff -u -r1.17 int21.c --- dlls/winedos/int21.c 3 Dec 2002 19:11:50 -0000 1.17 +++ dlls/winedos/int21.c 6 Dec 2002 21:53:46 -0000 @@ -45,7 +45,29 @@ /*********************************************************************** + * INT21_GetPSP + * + * Handler for functions 0x51 and 0x62. + */ +static void INT21_GetPSP( CONTEXT86 *context ) +{ + TRACE( "GET CURRENT PSP ADDRESS (%02x)\n", AH_reg(context) ); + + /* + * FIXME: should we return the original DOS PSP upon + * Windows startup ? + */ + if (!ISV86(context) && DOSVM_IsWin16()) + SET_BX( context, LOWORD(GetCurrentPDB16()) ); + else + SET_BX( context, DOSVM_psp ); +} + + +/*********************************************************************** * INT21_Ioctl + * + * Handler for function 0x44. */ static void INT21_Ioctl( CONTEXT86 *context ) { @@ -347,7 +369,6 @@ case 0x0d: /* DISK BUFFER FLUSH */ TRACE("DISK BUFFER FLUSH ignored\n"); - RESET_CFLAG( context ); /* dos 6+ only */ break; case 0x0e: /* SELECT DEFAULT DRIVE */ @@ -410,7 +431,7 @@ TRACE("SET INTERRUPT VECTOR 0x%02x\n",AL_reg(context)); { FARPROC16 ptr = (FARPROC16)MAKESEGPTR( context->SegDs, DX_reg(context) ); - if (DOSVM_IsWin16()) + if (!ISV86(context) && DOSVM_IsWin16()) DOSVM_SetPMHandler16( AL_reg(context), ptr ); else DOSVM_SetRMHandler( AL_reg(context), ptr ); @@ -424,10 +445,21 @@ break; case 0x29: /* PARSE FILENAME INTO FCB */ - case 0x2a: /* GET SYSTEM DATE */ INT_Int21Handler( context ); break; + case 0x2a: /* GET SYSTEM DATE */ + TRACE( "GET SYSTEM DATE\n" ); + { + SYSTEMTIME systime; + GetLocalTime( &systime ); + SET_CX( context, systime.wYear ); + SET_DH( context, systime.wMonth ); + SET_DL( context, systime.wDay ); + SET_AL( context, systime.wDayOfWeek ); + } + break; + case 0x2b: /* SET SYSTEM DATE */ FIXME("SetSystemDate(%02d/%02d/%04d): not allowed\n", DL_reg(context), DH_reg(context), CX_reg(context) ); @@ -435,7 +467,15 @@ break; case 0x2c: /* GET SYSTEM TIME */ - INT_Int21Handler( context ); + TRACE( "GET SYSTEM TIME\n" ); + { + SYSTEMTIME systime; + GetLocalTime( &systime ); + SET_CL( context, systime.wHour ); + SET_CH( context, systime.wMinute ); + SET_DH( context, systime.wSecond ); + SET_DL( context, systime.wMilliseconds / 10 ); + } break; case 0x2d: /* SET SYSTEM TIME */ @@ -469,7 +509,7 @@ TRACE("GET INTERRUPT VECTOR 0x%02x\n",AL_reg(context)); { FARPROC16 addr; - if (DOSVM_IsWin16()) + if (!ISV86(context) && DOSVM_IsWin16()) addr = DOSVM_GetPMHandler16( AL_reg(context) ); else addr = DOSVM_GetRMHandler( AL_reg(context) ); @@ -527,8 +567,59 @@ case 0x45: /* "DUP" - DUPLICATE FILE HANDLE */ case 0x46: /* "DUP2", "FORCEDUP" - FORCE DUPLICATE FILE HANDLE */ case 0x47: /* "CWD" - GET CURRENT DIRECTORY */ + INT_Int21Handler( context ); + break; + case 0x48: /* ALLOCATE MEMORY */ + TRACE( "ALLOCATE MEMORY for %d paragraphs\n", BX_reg(context) ); + { + WORD selector = 0; + DWORD bytes = (DWORD)BX_reg(context) << 4; + + if (!ISV86(context) && DOSVM_IsWin16()) + { + DWORD rv = GlobalDOSAlloc16( bytes ); + selector = LOWORD( rv ); + } + else + DOSMEM_GetBlock( bytes, &selector ); + + if (selector) + SET_AX( context, selector ); + else + { + SET_CFLAG(context); + SET_AX( context, 0x0008 ); /* insufficient memory */ + SET_BX( context, DOSMEM_Available() >> 4 ); + } + } + break; + case 0x49: /* FREE MEMORY */ + TRACE( "FREE MEMORY segment %04lX\n", context->SegEs ); + { + BOOL ok; + + if (!ISV86(context) && DOSVM_IsWin16()) + { + ok = !GlobalDOSFree16( context->SegEs ); + + /* If we don't reset ES_reg, we will fail in the relay code */ + if (ok) + context->SegEs = 0; + } + else + ok = DOSMEM_FreeBlock( (void*)((DWORD)context->SegEs << 4) ); + + if (!ok) + { + TRACE("FREE MEMORY failed\n"); + SET_CFLAG(context); + SET_AX( context, 0x0009 ); /* memory block address invalid */ + } + } + break; + case 0x4a: /* RESIZE MEMORY BLOCK */ INT_Int21Handler( context ); break; @@ -573,29 +664,21 @@ break; case 0x51: /* GET PSP ADDRESS */ - if (DOSVM_IsWin16()) { - INT_Int21Handler( context ); - break; - } - - TRACE("GET CURRENT PROCESS ID (GET PSP ADDRESS)\n"); - /* FIXME: should we return the original DOS PSP upon */ - /* Windows startup ? */ - SET_BX( context, DOSVM_psp ); + INT21_GetPSP( context ); break; case 0x52: /* "SYSVARS" - GET LIST OF LISTS */ - TRACE("SYSVARS - GET LIST OF LISTS\n"); - if (DOSVM_IsWin16()) + if (!ISV86(context) && DOSVM_IsWin16()) { - FIXME("LOLSeg broken for now\n"); - context->SegEs = 0; - SET_BX( context, 0 ); + SEGPTR ptr = DOSMEM_LOL()->wine_pm_lol; + context->SegEs = SELECTOROF(ptr); + SET_BX( context, OFFSETOF(ptr) ); } else { - context->SegEs = HIWORD(DOS_LOLSeg); - SET_BX( context, FIELD_OFFSET(DOS_LISTOFLISTS, ptr_first_DPB) ); + SEGPTR ptr = DOSMEM_LOL()->wine_rm_lol; + context->SegEs = SELECTOROF(ptr); + SET_BX( context, OFFSETOF(ptr) ); } break; @@ -606,10 +689,29 @@ case 0x56: /* "RENAME" - RENAME FILE */ case 0x57: /* FILE DATE AND TIME */ - case 0x58: /* GET OR SET MEMORY/UMB ALLOCATION STRATEGY */ INT_Int21Handler( context ); break; + case 0x58: /* GET OR SET MEMORY ALLOCATION STRATEGY */ + TRACE( "GET OR SET MEMORY ALLOCATION STRATEGY, subfunction %d\n", + AL_reg(context) ); + switch (AL_reg(context)) + { + case 0x00: /* GET ALLOCATION STRATEGY */ + SET_AX( context, 1 ); /* low memory best fit */ + break; + + case 0x01: /* SET ALLOCATION STRATEGY */ + TRACE( "Set allocation strategy to %d - ignored\n", + BL_reg(context) ); + break; + + default: + INT_BARF( context, 0x21 ); + break; + } + break; + case 0x59: /* GET EXTENDED ERROR INFO */ INT21_GetExtendedError( context ); break; @@ -626,22 +728,29 @@ break; case 0x62: /* GET PSP ADDRESS */ - if (DOSVM_IsWin16()) { - INT_Int21Handler( context ); - break; - } - - TRACE("GET CURRENT PSP ADDRESS\n"); - /* FIXME: should we return the original DOS PSP upon */ - /* Windows startup ? */ - SET_BX( context, DOSVM_psp ); + INT21_GetPSP( context ); break; case 0x63: /* MISC. LANGUAGE SUPPORT */ + INT_Int21Handler( context ); + break; + case 0x64: /* OS/2 DOS BOX */ + INT_BARF( context, 0x21 ); + SET_CFLAG(context); + break; + case 0x65: /* GET EXTENDED COUNTRY INFORMATION */ case 0x66: /* GLOBAL CODE PAGE TABLE */ + INT_Int21Handler( context ); + break; + case 0x67: /* SET HANDLE COUNT */ + TRACE( "SET HANDLE COUNT to %d\n", BX_reg(context) ); + if (SetHandleCount( BX_reg(context) ) < BX_reg(context) ) + bSetDOSExtendedError = TRUE; + break; + case 0x68: /* "FFLUSH" - COMMIT FILE */ case 0x69: /* DISK SERIAL NUMBER */ case 0x6a: /* COMMIT FILE */ Index: dlls/winedos/dosexe.h =================================================================== RCS file: /home/wine/wine/dlls/winedos/dosexe.h,v retrieving revision 1.19 diff -u -r1.19 dosexe.h --- dlls/winedos/dosexe.h 2 Dec 2002 21:39:58 -0000 1.19 +++ dlls/winedos/dosexe.h 6 Dec 2002 21:54:04 -0000 @@ -57,7 +57,6 @@ extern WORD DOSVM_psp; /* psp of current DOS task */ extern WORD DOSVM_retval; /* return value of previous DOS task */ -extern DWORD DOS_LOLSeg; extern struct DPMI_segments *DOSVM_dpmi_segments; #if defined(linux) && defined(__i386__) && defined(HAVE_SYS_VM86_H) @@ -118,6 +117,9 @@ /* himem.c */ extern void DOSVM_InitSegments(void); +extern LPVOID DOSVM_AllocUMB(DWORD); +extern LPVOID DOSVM_AllocCodeUMB(DWORD, WORD *, WORD *); +extern LPVOID DOSVM_AllocDataUMB(DWORD, WORD *, WORD *); /* int09.c */ extern void WINAPI DOSVM_Int09Handler(CONTEXT86*); Index: dlls/winedos/himem.c =================================================================== RCS file: /home/wine/wine/dlls/winedos/himem.c,v retrieving revision 1.1 diff -u -r1.1 himem.c --- dlls/winedos/himem.c 2 Dec 2002 21:39:58 -0000 1.1 +++ dlls/winedos/himem.c 6 Dec 2002 21:54:42 -0000 @@ -66,7 +66,7 @@ * overhead. Use of this routine also preserves precious DOS * conventional memory. */ -static LPVOID DOSVM_AllocUMB( DWORD size ) +LPVOID DOSVM_AllocUMB( DWORD size ) { LPVOID ptr = (LPVOID)DOSVM_umb_free; @@ -89,7 +89,7 @@ * Initializes real mode segment and 16-bit protected mode selector * for the allocated code block. */ -static LPVOID DOSVM_AllocCodeUMB( DWORD size, WORD *segment, WORD *selector ) +LPVOID DOSVM_AllocCodeUMB( DWORD size, WORD *segment, WORD *selector ) { LPVOID ptr = DOSVM_AllocUMB( size ); @@ -98,6 +98,27 @@ if (selector) *selector = SELECTOR_AllocBlock( ptr, size, WINE_LDT_FLAGS_CODE ); + + return ptr; +} + + +/*********************************************************************** + * DOSVM_AllocDataUMB + * + * Allocate upper memory block for storing data. + * Initializes real mode segment and 16-bit protected mode selector + * for the allocated data block. + */ +LPVOID DOSVM_AllocDataUMB( DWORD size, WORD *segment, WORD *selector ) +{ + LPVOID ptr = DOSVM_AllocUMB( size ); + + if (segment) + *segment = (DWORD)ptr >> 4; + + if (selector) + *selector = SELECTOR_AllocBlock( ptr, size, WINE_LDT_FLAGS_DATA ); return ptr; } Index: dlls/winedos/devices.c =================================================================== RCS file: /home/wine/wine/dlls/winedos/devices.c,v retrieving revision 1.6 diff -u -r1.6 devices.c --- dlls/winedos/devices.c 31 Aug 2002 18:47:00 -0000 1.6 +++ dlls/winedos/devices.c 6 Dec 2002 21:54:48 -0000 @@ -456,13 +456,18 @@ void DOSDEV_InstallDOSDevices(void) { DOS_DATASEG *dataseg; - UINT16 seg; + WORD seg; + WORD selector; unsigned int n; /* allocate DOS data segment or something */ - DOS_LOLSeg = GlobalDOSAlloc16(sizeof(DOS_DATASEG)); - seg = HIWORD(DOS_LOLSeg); - dataseg = MapSL( MAKESEGPTR(LOWORD(DOS_LOLSeg), 0) ); + dataseg = DOSVM_AllocDataUMB( sizeof(DOS_DATASEG), &seg, &selector ); + + DOS_LOLSeg = MAKESEGPTR( seg, 0 ); + DOSMEM_LOL()->wine_rm_lol = + MAKESEGPTR( seg, FIELD_OFFSET(DOS_LISTOFLISTS, ptr_first_DPB) ); + DOSMEM_LOL()->wine_pm_lol = + MAKESEGPTR( selector, FIELD_OFFSET(DOS_LISTOFLISTS, ptr_first_DPB) ); /* initialize the magnificent List Of Lists */ InitListOfLists(&dataseg->lol); Index: dlls/winedos/module.c =================================================================== RCS file: /home/wine/wine/dlls/winedos/module.c,v retrieving revision 1.27 diff -u -r1.27 module.c --- dlls/winedos/module.c 28 Oct 2002 20:12:40 -0000 1.27 +++ dlls/winedos/module.c 6 Dec 2002 21:54:54 -0000 @@ -174,7 +174,7 @@ static void MZ_InitHandlers(void) { WORD seg; - LPBYTE start=DOSMEM_GetBlock(sizeof(int08),&seg); + LPBYTE start = DOSVM_AllocCodeUMB( sizeof(int08), &seg, 0 ); memcpy(start,int08,sizeof(int08)); /* INT 08: point it at our tick-incrementing handler */ ((SEGPTR*)0)[0x08]=MAKESEGPTR(seg,0); Index: msdos/int21.c =================================================================== RCS file: /home/wine/wine/msdos/int21.c,v retrieving revision 1.80 diff -u -r1.80 int21.c --- msdos/int21.c 3 Dec 2002 23:21:20 -0000 1.80 +++ msdos/int21.c 6 Dec 2002 21:55:00 -0000 @@ -468,22 +468,6 @@ SET_SI( context, context->Esi + (int)s - (int)filename ); } -static void INT21_GetSystemDate( CONTEXT86 *context ) -{ - SYSTEMTIME systime; - GetLocalTime( &systime ); - SET_CX( context, systime.wYear ); - SET_DX( context, (systime.wMonth << 8) | systime.wDay ); - SET_AX( context, systime.wDayOfWeek ); -} - -static void INT21_GetSystemTime( CONTEXT86 *context ) -{ - SYSTEMTIME systime; - GetLocalTime( &systime ); - SET_CX( context, (systime.wHour << 8) | systime.wMinute ); - SET_DX( context, (systime.wSecond << 8) | (systime.wMilliseconds / 10) ); -} /* Many calls translate a drive argument like this: drive number (00h = default, 01h = A:, etc) @@ -1106,14 +1090,6 @@ INT21_ParseFileNameIntoFCB(context); break; - case 0x2a: /* GET SYSTEM DATE */ - INT21_GetSystemDate(context); - break; - - case 0x2c: /* GET SYSTEM TIME */ - INT21_GetSystemTime(context); - break; - case 0x2f: /* GET DISK TRANSFER AREA ADDRESS */ TRACE("GET DISK TRANSFER AREA ADDRESS\n"); { @@ -1510,52 +1486,6 @@ bSetDOSExtendedError = !INT21_GetCurrentDirectory(context); break; - case 0x48: /* ALLOCATE MEMORY */ - TRACE("ALLOCATE MEMORY for %d paragraphs\n", BX_reg(context)); - { - LPVOID *mem; - if (ISV86(context)) - { - mem= DOSMEM_GetBlock((DWORD)BX_reg(context)<<4,NULL); - if (mem) - SET_AX( context, DOSMEM_MapLinearToDos(mem)>>4 ); - } - else - { - mem = (LPVOID)GlobalDOSAlloc16(BX_reg(context)<<4); - if (mem) - SET_AX( context, (DWORD)mem&0xffff ); - } - if (!mem) - { - SET_CFLAG(context); - SET_AX( context, 0x0008 ); /* insufficient memory */ - SET_BX( context, DOSMEM_Available()>>4 ); - } - } - break; - - case 0x49: /* FREE MEMORY */ - TRACE("FREE MEMORY segment %04lX\n", context->SegEs); - { - BOOL ret; - if (ISV86(context)) - ret= DOSMEM_FreeBlock(DOSMEM_MapDosToLinear(context->SegEs<<4)); - else - { - ret = !GlobalDOSFree16(context->SegEs); - /* If we don't reset ES_reg, we will fail in the relay code */ - context->SegEs=ret; - } - if (!ret) - { - TRACE("FREE MEMORY failed\n"); - SET_CFLAG(context); - SET_AX( context, 0x0009 ); /* memory block address invalid */ - } - } - break; - case 0x4a: /* RESIZE MEMORY BLOCK */ TRACE("RESIZE MEMORY segment %04lX to %d paragraphs\n", context->SegEs, BX_reg(context)); if (!ISV86(context)) @@ -1596,17 +1526,6 @@ } else SET_AX( context, 0 ); /* OK */ break; - case 0x51: /* GET PSP ADDRESS */ - TRACE("GET CURRENT PROCESS ID (GET PSP ADDRESS)\n"); - /* FIXME: should we return the original DOS PSP upon */ - /* Windows startup ? */ - SET_BX( context, GetCurrentPDB16() ); - break; - case 0x62: /* GET PSP ADDRESS */ - /* FIXME: should we return the original DOS PSP upon */ - /* Windows startup ? */ - SET_BX( context, GetCurrentPDB16() ); - break; case 0x56: /* "RENAME" - RENAME FILE */ TRACE("RENAME %s to %s\n", @@ -1652,24 +1571,6 @@ } break; - case 0x58: /* GET OR SET MEMORY/UMB ALLOCATION STRATEGY */ - TRACE("GET OR SET MEMORY/UMB ALLOCATION STRATEGY subfunction %d\n", - AL_reg(context)); - switch (AL_reg(context)) - { - case 0x00: - SET_AX( context, 1 ); - break; - case 0x02: - SET_AX( context, 0 ); - break; - case 0x01: - case 0x03: - break; - } - RESET_CFLAG(context); - break; - case 0x5a: /* CREATE TEMPORARY FILE */ TRACE("CREATE TEMPORARY FILE\n"); bSetDOSExtendedError = !INT21_CreateTempFile(context); @@ -1746,10 +1647,6 @@ break; } break; - case 0x64: /* OS/2 DOS BOX */ - INT_BARF( context, 0x21 ); - SET_CFLAG(context); - break; case 0x65:{/* GET EXTENDED COUNTRY INFORMATION */ BYTE *dataptr=CTX_SEG_OFF_TO_LIN(context, context->SegEs,context->Edi); @@ -1810,12 +1707,6 @@ RESET_CFLAG(context); break; } - break; - - case 0x67: /* SET HANDLE COUNT */ - TRACE("SET HANDLE COUNT to %d\n",BX_reg(context) ); - SetHandleCount16( BX_reg(context) ); - if (GetLastError()) bSetDOSExtendedError = TRUE; break; case 0x68: /* "FFLUSH" - COMMIT FILE */ Index: dlls/kernel/kernel32.spec =================================================================== RCS file: /home/wine/wine/dlls/kernel/kernel32.spec,v retrieving revision 1.82 diff -u -r1.82 kernel32.spec --- dlls/kernel/kernel32.spec 2 Dec 2002 21:39:59 -0000 1.82 +++ dlls/kernel/kernel32.spec 6 Dec 2002 21:55:04 -0000 @@ -992,6 +992,7 @@ @ stdcall FindResource16(long str str) FindResource16 @ stdcall FreeResource16(long) FreeResource16 @ stdcall FreeSelector16(long) FreeSelector16 +@ stdcall GetCurrentPDB16() GetCurrentPDB16 @ stdcall GetCurrentTask() GetCurrentTask @ stdcall GetDOSEnvironment16() GetDOSEnvironment16 @ stdcall GetExePtr(long) GetExePtr Index: include/msdos.h =================================================================== RCS file: /home/wine/wine/include/msdos.h,v retrieving revision 1.11 diff -u -r1.11 msdos.h --- include/msdos.h 31 May 2002 23:06:48 -0000 1.11 +++ include/msdos.h 7 Dec 2002 08:33:51 -0000 @@ -20,7 +20,7 @@ #ifndef __WINE_MSDOS_H #define __WINE_MSDOS_H -#include "winnt.h" +#include "wine/windef16.h" #include "pshpack1.h" @@ -117,6 +117,8 @@ BYTE boot_drive; /* 43 */ BYTE flag_DWORD_moves; /* 44 01h for 386+, 00h otherwise */ WORD size_extended_mem; /* 45 size of extended mem in KB */ + SEGPTR wine_rm_lol; /* -- wine: Real mode pointer to LOL */ + SEGPTR wine_pm_lol; /* -- wine: Protected mode pointer to LOL */ } DOS_LISTOFLISTS; #include "poppack.h" @@ -208,8 +210,6 @@ #define EL_Network 0x03 #define EL_Serial 0x04 #define EL_Memory 0x05 - -void WINAPI DOS3Call( CONTEXT86 *context ); #define DOSCONF_MEM_HIGH 0x0001 #define DOSCONF_MEM_UMB 0x0002 -- Jukka Heinonen <http://www.iki.fi/jhei/>