This patch includes a bunch of latent infrastructure improvements. Changelog: Add routines for manipulating protected mode interrupt handlers to winedos dll. Add routine for checking if process is Windows process. Fix DOSVM_IsDos32 interface. Move real mode interrupt handler manipulation routines to interrupts.c. Index: dlls/winedos/dosexe.h =================================================================== RCS file: /home/wine/wine/dlls/winedos/dosexe.h,v retrieving revision 1.11 diff -u -r1.11 dosexe.h --- dlls/winedos/dosexe.h 23 Oct 2002 22:24:10 -0000 1.11 +++ dlls/winedos/dosexe.h 27 Oct 2002 15:46:29 -0000 @@ -64,9 +64,8 @@ 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 FARPROC16 DOSVM_GetRMHandler( BYTE intnum ); -extern void DOSVM_SetRMHandler( BYTE intnum, FARPROC16 handler ); extern void DOSVM_RealModeInterrupt( BYTE intnum, CONTEXT86 *context ); +extern BOOL DOSVM_IsWin16(void); /* devices.c */ extern void DOSDEV_InstallDOSDevices(void); @@ -115,7 +114,7 @@ /* int31.c */ extern void WINAPI DOSVM_Int31Handler(CONTEXT86*); -extern BOOL WINAPI DOSVM_IsDos32(); +extern BOOL DOSVM_IsDos32(void); /* int33.c */ extern void WINAPI DOSVM_Int33Handler(CONTEXT86*); @@ -125,6 +124,15 @@ /* int67.c */ extern void WINAPI DOSVM_Int67Handler(CONTEXT86*); extern void WINAPI EMS_Ioctl_Handler(CONTEXT86*); + +/* interrupts.c */ +extern FARPROC16 DOSVM_GetRMHandler( BYTE intnum ); +extern void DOSVM_SetRMHandler( BYTE intnum, FARPROC16 handler ); +extern FARPROC16 DOSVM_GetPMHandler16( BYTE intnum ); +extern void DOSVM_SetPMHandler16( BYTE intnum, FARPROC16 handler ); +extern FARPROC48 DOSVM_GetPMHandler48( BYTE intnum ); +extern void DOSVM_SetPMHandler48( BYTE intnum, FARPROC48 handler ); +extern INTPROC DOSVM_GetBuiltinHandler( BYTE intnum ); /* soundblaster.c */ extern void SB_ioport_out( WORD port, BYTE val ); Index: dlls/winedos/dosvm.c =================================================================== RCS file: /home/wine/wine/dlls/winedos/dosvm.c,v retrieving revision 1.26 diff -u -r1.26 dosvm.c --- dlls/winedos/dosvm.c 23 Oct 2002 22:24:10 -0000 1.26 +++ dlls/winedos/dosvm.c 27 Oct 2002 15:47:40 -0000 @@ -624,30 +624,6 @@ #endif -/********************************************************************** - * DOSVM_GetRMHandler - * - * Return the real mode interrupt vector for a given interrupt. - */ -FARPROC16 DOSVM_GetRMHandler( BYTE intnum ) -{ - return ((FARPROC16*)0)[intnum]; -} - - -/********************************************************************** - * DOSVM_SetRMHandler - * - * Set the real mode interrupt handler for a given interrupt. - */ -void DOSVM_SetRMHandler( BYTE intnum, FARPROC16 handler ) -{ - TRACE("Set real mode interrupt vector %02x <- %04x:%04x\n", - intnum, HIWORD(handler), LOWORD(handler) ); - ((FARPROC16*)0)[intnum] = handler; -} - - static const INTPROC real_mode_handlers[] = { /* 00 */ 0, 0, 0, 0, 0, 0, 0, 0, Index: dlls/winedos/int31.c =================================================================== RCS file: /home/wine/wine/dlls/winedos/int31.c,v retrieving revision 1.9 diff -u -r1.9 int31.c --- dlls/winedos/int31.c 23 Oct 2002 22:24:10 -0000 1.9 +++ dlls/winedos/int31.c 27 Oct 2002 15:48:05 -0000 @@ -69,7 +69,7 @@ * * Return TRUE if we are in 32-bit protected mode DOS process. */ -BOOL DOSVM_IsDos32() +BOOL DOSVM_IsDos32(void) { return (dpmi_flag & 1) ? TRUE : FALSE; } Index: dlls/winedos/interrupts.c =================================================================== RCS file: /home/wine/wine/dlls/winedos/interrupts.c,v retrieving revision 1.1 diff -u -r1.1 interrupts.c --- dlls/winedos/interrupts.c 23 Oct 2002 22:24:10 -0000 1.1 +++ dlls/winedos/interrupts.c 27 Oct 2002 15:48:48 -0000 @@ -20,9 +20,17 @@ #include "dosexe.h" #include "wine/debug.h" +#include "wine/winbase16.h" WINE_DEFAULT_DEBUG_CHANNEL(int); +static FARPROC16 DOSVM_Vectors16[256]; +static FARPROC48 DOSVM_Vectors48[256]; +static INTPROC DOSVM_VectorsBuiltin[256]; + +/* Ordinal number for interrupt 0 handler in winedos.dll and winedos16.dll */ +#define FIRST_INTERRUPT 100 + /********************************************************************** * DOSVM_EmulateInterruptPM * @@ -46,15 +54,9 @@ } else islong = FALSE; - /* FIXME: Remove this check when DPMI32 support has been added */ - if(islong) { - ERR("Interrupts not supported in 32-bit DPMI\n"); - islong = FALSE; - } - if(islong) { - FARPROC48 addr = {0,0}; /* FIXME: INT_GetPMHandler48( intnum ); */ + FARPROC48 addr = DOSVM_GetPMHandler48( intnum ); DWORD *stack = CTX_SEG_OFF_TO_LIN(context, context->SegSs, context->Esp); /* Push the flags and return address on the stack */ *(--stack) = context->EFlags; @@ -66,7 +68,7 @@ } else { - FARPROC16 addr = INT_GetPMHandler( intnum ); + FARPROC16 addr = INT_GetPMHandler( intnum ); // FIXME: DOSVM_GetPMHandler16 WORD *stack = CTX_SEG_OFF_TO_LIN(context, context->SegSs, context->Esp); /* Push the flags and return address on the stack */ *(--stack) = LOWORD(context->EFlags); @@ -81,4 +83,148 @@ context->Esp += islong ? -12 : -6; else ADD_LOWORD( context->Esp, islong ? -12 : -6 ); +} + +/********************************************************************** + * DOSVM_GetRMHandler + * + * Return the real mode interrupt vector for a given interrupt. + */ +FARPROC16 DOSVM_GetRMHandler( BYTE intnum ) +{ + return ((FARPROC16*)0)[intnum]; +} + +/********************************************************************** + * DOSVM_SetRMHandler + * + * Set the real mode interrupt handler for a given interrupt. + */ +void DOSVM_SetRMHandler( BYTE intnum, FARPROC16 handler ) +{ + TRACE("Set real mode interrupt vector %02x <- %04x:%04x\n", + intnum, HIWORD(handler), LOWORD(handler) ); + ((FARPROC16*)0)[intnum] = handler; +} + +/********************************************************************** + * DOSVM_GetPMHandler16 + * + * Return the protected mode interrupt vector for a given interrupt. + */ +FARPROC16 DOSVM_GetPMHandler16( BYTE intnum ) +{ + static HMODULE16 procs; + FARPROC16 handler = DOSVM_Vectors16[intnum]; + + if (!handler) + { + if (!procs && + (procs = GetModuleHandle16( "winedos16" )) < 32 && + (procs = LoadLibrary16( "winedos16" )) < 32) + { + ERR("could not load winedos16.dll\n"); + procs = 0; + return 0; + } + + handler = GetProcAddress16( procs, (LPCSTR)(FIRST_INTERRUPT + intnum)); + if (!handler) + { + WARN("int%x not implemented, returning dummy handler\n", intnum ); + handler = GetProcAddress16( procs, (LPCSTR)(FIRST_INTERRUPT + 256)); + } + + DOSVM_Vectors16[intnum] = handler; + } + + return handler; +} + + +/********************************************************************** + * DOSVM_SetPMHandler + * + * Set the protected mode interrupt handler for a given interrupt. + */ +void DOSVM_SetPMHandler( BYTE intnum, FARPROC16 handler ) +{ + TRACE("Set protected mode interrupt vector %02x <- %04x:%04x\n", + intnum, HIWORD(handler), LOWORD(handler) ); + DOSVM_Vectors16[intnum] = handler; +} + +/********************************************************************** + * DOSVM_GetPMHandler48 + * + * Return the protected mode interrupt vector for a given interrupt. + * Used to get 48-bit pointer for 32-bit interrupt handlers in DPMI32. + */ +FARPROC48 DOSVM_GetPMHandler48( BYTE intnum ) +{ + if (!DOSVM_Vectors48[intnum].selector) + { + DOSVM_Vectors48[intnum].selector = DOSVM_dpmi_segments->int48_sel; + DOSVM_Vectors48[intnum].offset = 4 * intnum; + } + return DOSVM_Vectors48[intnum]; +} + +/********************************************************************** + * DOSVM_SetPMHandler48 + * + * Set the protected mode interrupt handler for a given interrupt. + * Used to set 48-bit pointer for 32-bit interrupt handlers in DPMI32. + */ +void DOSVM_SetPMHandler48( BYTE intnum, FARPROC48 handler ) +{ + TRACE("Set 32-bit protected mode interrupt vector %02x <- %04x:%08lx\n", + intnum, handler.selector, handler.offset ); + DOSVM_Vectors48[intnum] = handler; +} + +/********************************************************************** + * DOSVM_GetBuiltinHandler + * + * Return Wine interrupt handler procedure for a given interrupt. + */ +INTPROC DOSVM_GetBuiltinHandler( BYTE intnum ) +{ + static HMODULE procs; + INTPROC handler = DOSVM_VectorsBuiltin[intnum]; + + if (!handler) + { + if (!procs) + procs = LoadLibraryA( "winedos.dll" ); + + if (!procs) + { + ERR("could not load winedos.dll\n"); + return 0; + } + + handler = (INTPROC)GetProcAddress( procs, + (LPCSTR)(FIRST_INTERRUPT + intnum)); + if (!handler) + { + WARN("int%x not implemented, returning dummy handler\n", intnum ); + handler = (INTPROC)GetProcAddress( procs, + (LPCSTR)(FIRST_INTERRUPT + 256)); + } + + DOSVM_VectorsBuiltin[intnum] = handler; + } + + return handler; +} + +/********************************************************************** + * DOSVM_DefaultHandler + * + * Default interrupt handler. This will be used to emulate all + * interrupts that don't have their own interrupt handler. + */ +void WINAPI DOSVM_DefaultHandler( CONTEXT86 *context ) +{ } Index: dlls/winedos/module.c =================================================================== RCS file: /home/wine/wine/dlls/winedos/module.c,v retrieving revision 1.26 diff -u -r1.26 module.c --- dlls/winedos/module.c 23 Oct 2002 23:35:34 -0000 1.26 +++ dlls/winedos/module.c 27 Oct 2002 15:50:05 -0000 @@ -53,6 +53,18 @@ WINE_DEFAULT_DEBUG_CHANNEL(module); +static BOOL DOSVM_isdosexe; + +/********************************************************************** + * DOSVM_IsWin16 + * + * Return TRUE if we are in Windows process. + */ +BOOL DOSVM_IsWin16(void) +{ + return DOSVM_isdosexe ? FALSE : TRUE; +} + #ifdef MZ_SUPPORTED #ifdef HAVE_SYS_MMAN_H @@ -332,9 +344,13 @@ /*********************************************************************** * LoadDosExe (WINEDOS.@) + * + * Called from Wine loader when a new real-mode DOS process is started. + * Loads DOS program into memory and executes the program. */ void WINAPI MZ_LoadImage( LPCSTR filename, HANDLE hFile ) { + DOSVM_isdosexe = TRUE; if (MZ_DoLoadImage( hFile, filename, NULL )) MZ_Launch(); } -- Jukka Heinonen <http://www.iki.fi/jhei/>