Modify winedos interrupt handlers so that they work with PM

interrupts.
Add forwarding functions for handlers in other DLLs.
Make DOSVM_GetBuiltinHandler use static table instead of
GetProcAddress.
This commit is contained in:
Jukka Heinonen 2002-10-29 23:09:30 +00:00 committed by Alexandre Julliard
parent d9310e76c4
commit 6f6abac4f1
6 changed files with 171 additions and 52 deletions

View File

@ -1049,6 +1049,7 @@ init MAIN_KernelInit
@ stdcall INT_Int15Handler(ptr) INT_Int15Handler @ stdcall INT_Int15Handler(ptr) INT_Int15Handler
@ stdcall INT_Int1aHandler(ptr) INT_Int1aHandler @ stdcall INT_Int1aHandler(ptr) INT_Int1aHandler
@ stdcall INT_Int25Handler(ptr) INT_Int25Handler @ stdcall INT_Int25Handler(ptr) INT_Int25Handler
@ stdcall INT_Int26Handler(ptr) INT_Int26Handler
@ stdcall INT_Int2aHandler(ptr) INT_Int2aHandler @ stdcall INT_Int2aHandler(ptr) INT_Int2aHandler
@ stdcall INT_Int2fHandler(ptr) INT_Int2fHandler @ stdcall INT_Int2fHandler(ptr) INT_Int2fHandler
@ stdcall INT_Int31Handler(ptr) INT_Int31Handler @ stdcall INT_Int31Handler(ptr) INT_Int31Handler
@ -1063,6 +1064,9 @@ init MAIN_KernelInit
@ stdcall INT_Int3cHandler(ptr) INT_Int3cHandler @ stdcall INT_Int3cHandler(ptr) INT_Int3cHandler
@ stdcall INT_Int3dHandler(ptr) INT_Int3dHandler @ stdcall INT_Int3dHandler(ptr) INT_Int3dHandler
@ stdcall INT_Int3eHandler(ptr) INT_Int3eHandler @ stdcall INT_Int3eHandler(ptr) INT_Int3eHandler
@ stdcall INT_Int41Handler(ptr) INT_Int41Handler
@ stdcall INT_Int4bHandler(ptr) INT_Int4bHandler
@ stdcall NetBIOSCall16(ptr) NetBIOSCall16
@ cdecl INT_SetPMHandler(long long) INT_SetPMHandler @ cdecl INT_SetPMHandler(long long) INT_SetPMHandler
@ cdecl LOCAL_Alloc(long long long) LOCAL_Alloc @ cdecl LOCAL_Alloc(long long long) LOCAL_Alloc
@ cdecl LOCAL_Compact(long long long) LOCAL_Compact @ cdecl LOCAL_Compact(long long long) LOCAL_Compact

View File

@ -30,5 +30,9 @@
*/ */
void WINAPI DOSVM_Int20Handler( CONTEXT86 *context ) void WINAPI DOSVM_Int20Handler( CONTEXT86 *context )
{ {
/* FIXME: Is this correct in DOS DPMI? */
if (ISV86(context))
MZ_Exit( context, TRUE, 0 ); MZ_Exit( context, TRUE, 0 );
else
ExitThread(0);
} }

View File

@ -72,11 +72,17 @@ void WINAPI DOSVM_Int21Handler_Ioctl( CONTEXT86 *context )
/*********************************************************************** /***********************************************************************
* DOSVM_Int21Handler * DOSVM_Int21Handler
* *
* int 21h real-mode handler. Most calls are passed directly to DOS3Call. * int 21h handler. Most calls are passed directly to DOS3Call.
*/ */
void WINAPI DOSVM_Int21Handler( CONTEXT86 *context ) void WINAPI DOSVM_Int21Handler( CONTEXT86 *context )
{ {
BYTE ascii; BYTE ascii;
if (DOSVM_IsWin16()) {
DOS3Call( context );
return;
}
RESET_CFLAG(context); /* Not sure if this is a good idea */ RESET_CFLAG(context); /* Not sure if this is a good idea */
if(AH_reg(context) == 0x0c) /* FLUSH BUFFER AND READ STANDARD INPUT */ if(AH_reg(context) == 0x0c) /* FLUSH BUFFER AND READ STANDARD INPUT */

View File

@ -614,26 +614,37 @@ void WINAPI DOSVM_FreeRMCB( CONTEXT86 *context )
} }
} }
/********************************************************************** /**********************************************************************
* DOSVM_Int31Handler * DOSVM_CheckWrappers
* *
* Handler for real-mode int 31h (DPMI). * Check if this was really a wrapper call instead of an interrupt.
* FIXME: Protected mode stuff does not work in 32-bit DPMI.
* FIXME: If int31 is called asynchronously (unlikely)
* wrapper checks are wrong (CS/IP must not be used).
*/ */
void WINAPI DOSVM_Int31Handler( CONTEXT86 *context ) static BOOL DOSVM_CheckWrappers( CONTEXT86 *context )
{ {
/* Handle protected mode interrupts. */
if (!ISV86(context)) {
if (context->SegCs == DOSVM_dpmi_segments->dpmi_sel) {
INT_Int31Handler( context ); /* FIXME: Call RawModeSwitch */
return TRUE;
}
return FALSE;
}
/* check if it's our wrapper */ /* check if it's our wrapper */
TRACE("called from real mode\n"); TRACE("called from real mode\n");
if (context->SegCs==DOSVM_dpmi_segments->dpmi_seg) { if (context->SegCs==DOSVM_dpmi_segments->dpmi_seg) {
/* This is the protected mode switch */ /* This is the protected mode switch */
StartPM(context); StartPM(context);
return; return TRUE;
} }
else if (context->SegCs==DOSVM_dpmi_segments->xms_seg) else if (context->SegCs==DOSVM_dpmi_segments->xms_seg)
{ {
/* This is the XMS driver entry point */ /* This is the XMS driver entry point */
XMS_Handler(context); XMS_Handler(context);
return; return TRUE;
} }
else else
{ {
@ -646,10 +657,57 @@ void WINAPI DOSVM_Int31Handler( CONTEXT86 *context )
if (CurrRMCB) { if (CurrRMCB) {
/* RMCB call, propagate to protected-mode handler */ /* RMCB call, propagate to protected-mode handler */
DPMI_CallRMCBProc(context, CurrRMCB, dpmi_flag); DPMI_CallRMCBProc(context, CurrRMCB, dpmi_flag);
return; return TRUE;
} }
} }
/* chain to protected mode handler */ return FALSE;
INT_Int31Handler( context ); }
/**********************************************************************
* DOSVM_Int31Handler
*
* Handler for int 31h (DPMI).
*/
void WINAPI DOSVM_Int31Handler( CONTEXT86 *context )
{
if (DOSVM_CheckWrappers(context))
return;
RESET_CFLAG(context);
switch(AX_reg(context))
{
case 0x0204: /* Get protected mode interrupt vector */
TRACE("get protected mode interrupt handler (0x%02x)\n",
BL_reg(context));
if (DOSVM_IsDos32()) {
FARPROC48 handler = DOSVM_GetPMHandler48( BL_reg(context) );
SET_CX( context, handler.selector );
context->Edx = handler.offset;
} else {
FARPROC16 handler = DOSVM_GetPMHandler16( BL_reg(context) );
SET_CX( context, SELECTOROF(handler) );
SET_DX( context, OFFSETOF(handler) );
}
break;
case 0x0205: /* Set protected mode interrupt vector */
TRACE("set protected mode interrupt handler (0x%02x,0x%04x:0x%08lx)\n",
BL_reg(context), CX_reg(context), context->Edx);
if (DOSVM_IsDos32()) {
FARPROC48 handler;
handler.selector = CX_reg(context);
handler.offset = context->Edx;
DOSVM_SetPMHandler48( BL_reg(context), handler );
} else {
FARPROC16 handler;
handler = (FARPROC16)MAKESEGPTR( CX_reg(context), DX_reg(context));
DOSVM_SetPMHandler16( BL_reg(context), handler );
}
break;
default:
/* chain to protected mode handler */
INT_Int31Handler( context ); /* FIXME: move DPMI code here */
}
} }

View File

@ -24,13 +24,80 @@
WINE_DEFAULT_DEBUG_CHANNEL(int); WINE_DEFAULT_DEBUG_CHANNEL(int);
/*
* FIXME: Interrupt handlers for interrupts implemented in other DLLs.
* These functions should be removed when the interrupt handlers have
* been moved to winedos.
*/
void WINAPI DOSVM_Int11Handler( CONTEXT86 *context ) { INT_Int11Handler(context); }
void WINAPI DOSVM_Int12Handler( CONTEXT86 *context ) { INT_Int12Handler(context); }
void WINAPI DOSVM_Int13Handler( CONTEXT86 *context ) { INT_Int13Handler(context); }
void WINAPI DOSVM_Int15Handler( CONTEXT86 *context ) { INT_Int15Handler(context); }
void WINAPI DOSVM_Int1aHandler( CONTEXT86 *context ) { INT_Int1aHandler(context); }
void WINAPI DOSVM_Int25Handler( CONTEXT86 *context ) { INT_Int25Handler(context); }
void WINAPI DOSVM_Int26Handler( CONTEXT86 *context ) { INT_Int26Handler(context); }
void WINAPI DOSVM_Int2aHandler( CONTEXT86 *context ) { INT_Int2aHandler(context); }
void WINAPI DOSVM_Int2fHandler( CONTEXT86 *context ) { INT_Int2fHandler(context); }
void WINAPI DOSVM_Int34Handler( CONTEXT86 *context ) { INT_Int34Handler(context); }
void WINAPI DOSVM_Int35Handler( CONTEXT86 *context ) { INT_Int35Handler(context); }
void WINAPI DOSVM_Int36Handler( CONTEXT86 *context ) { INT_Int36Handler(context); }
void WINAPI DOSVM_Int37Handler( CONTEXT86 *context ) { INT_Int37Handler(context); }
void WINAPI DOSVM_Int38Handler( CONTEXT86 *context ) { INT_Int38Handler(context); }
void WINAPI DOSVM_Int39Handler( CONTEXT86 *context ) { INT_Int39Handler(context); }
void WINAPI DOSVM_Int3aHandler( CONTEXT86 *context ) { INT_Int3aHandler(context); }
void WINAPI DOSVM_Int3bHandler( CONTEXT86 *context ) { INT_Int3bHandler(context); }
void WINAPI DOSVM_Int3cHandler( CONTEXT86 *context ) { INT_Int3cHandler(context); }
void WINAPI DOSVM_Int3dHandler( CONTEXT86 *context ) { INT_Int3dHandler(context); }
void WINAPI DOSVM_Int3eHandler( CONTEXT86 *context ) { INT_Int3eHandler(context); }
void WINAPI DOSVM_Int41Handler( CONTEXT86 *context ) { INT_Int41Handler(context); }
void WINAPI DOSVM_Int4bHandler( CONTEXT86 *context ) { INT_Int4bHandler(context); }
void WINAPI DOSVM_Int5cHandler( CONTEXT86 *context ) { NetBIOSCall16(context); }
static FARPROC16 DOSVM_Vectors16[256]; static FARPROC16 DOSVM_Vectors16[256];
static FARPROC48 DOSVM_Vectors48[256]; static FARPROC48 DOSVM_Vectors48[256];
static INTPROC DOSVM_VectorsBuiltin[256]; static const INTPROC DOSVM_VectorsBuiltin[] =
{
/* 00 */ 0, 0, 0, 0,
/* 04 */ 0, 0, 0, 0,
/* 08 */ 0, DOSVM_Int09Handler, 0, 0,
/* 0C */ 0, 0, 0, 0,
/* 10 */ DOSVM_Int10Handler, DOSVM_Int11Handler, DOSVM_Int12Handler, DOSVM_Int13Handler,
/* 14 */ 0, DOSVM_Int15Handler, DOSVM_Int16Handler, DOSVM_Int17Handler,
/* 18 */ 0, 0, DOSVM_Int1aHandler, 0,
/* 1C */ 0, 0, 0, 0,
/* 20 */ DOSVM_Int20Handler, DOSVM_Int21Handler, 0, 0,
/* 24 */ 0, DOSVM_Int25Handler, DOSVM_Int26Handler, 0,
/* 28 */ 0, DOSVM_Int29Handler, DOSVM_Int2aHandler, 0,
/* 2C */ 0, 0, 0, DOSVM_Int2fHandler,
/* 30 */ 0, DOSVM_Int31Handler, 0, DOSVM_Int33Handler,
/* 34 */ DOSVM_Int34Handler, DOSVM_Int35Handler, DOSVM_Int36Handler, DOSVM_Int37Handler,
/* 38 */ DOSVM_Int38Handler, DOSVM_Int39Handler, DOSVM_Int3aHandler, DOSVM_Int3bHandler,
/* 3C */ DOSVM_Int3cHandler, DOSVM_Int3dHandler, DOSVM_Int3eHandler, 0,
/* 40 */ 0, DOSVM_Int41Handler, 0, 0,
/* 44 */ 0, 0, 0, 0,
/* 48 */ 0, 0, 0, DOSVM_Int4bHandler,
/* 4C */ 0, 0, 0, 0,
/* 50 */ 0, 0, 0, 0,
/* 54 */ 0, 0, 0, 0,
/* 58 */ 0, 0, 0, 0,
/* 5C */ DOSVM_Int5cHandler, 0, 0, 0,
/* 60 */ 0, 0, 0, 0,
/* 64 */ 0, 0, 0, DOSVM_Int67Handler
};
/* Ordinal number for interrupt 0 handler in winedos.dll and winedos16.dll */ /* Ordinal number for interrupt 0 handler in winedos16.dll */
#define FIRST_INTERRUPT 100 #define FIRST_INTERRUPT 100
/**********************************************************************
* 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 )
{
}
/********************************************************************** /**********************************************************************
* DOSVM_EmulateInterruptPM * DOSVM_EmulateInterruptPM
* *
@ -143,11 +210,11 @@ FARPROC16 DOSVM_GetPMHandler16( BYTE intnum )
/********************************************************************** /**********************************************************************
* DOSVM_SetPMHandler * DOSVM_SetPMHandler16
* *
* Set the protected mode interrupt handler for a given interrupt. * Set the protected mode interrupt handler for a given interrupt.
*/ */
void DOSVM_SetPMHandler( BYTE intnum, FARPROC16 handler ) void DOSVM_SetPMHandler16( BYTE intnum, FARPROC16 handler )
{ {
TRACE("Set protected mode interrupt vector %02x <- %04x:%04x\n", TRACE("Set protected mode interrupt vector %02x <- %04x:%04x\n",
intnum, HIWORD(handler), LOWORD(handler) ); intnum, HIWORD(handler), LOWORD(handler) );
@ -190,41 +257,12 @@ void DOSVM_SetPMHandler48( BYTE intnum, FARPROC48 handler )
*/ */
INTPROC DOSVM_GetBuiltinHandler( BYTE intnum ) INTPROC DOSVM_GetBuiltinHandler( BYTE intnum )
{ {
static HMODULE procs; if (intnum < sizeof(DOSVM_VectorsBuiltin)/sizeof(INTPROC)) {
INTPROC handler = DOSVM_VectorsBuiltin[intnum]; INTPROC proc = DOSVM_VectorsBuiltin[intnum];
if(proc)
if (!handler) return proc;
{
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 ); WARN("int%x not implemented, returning dummy handler\n", intnum );
handler = (INTPROC)GetProcAddress( procs, return DOSVM_DefaultHandler;
(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 )
{
} }

View File

@ -240,6 +240,15 @@ extern void WINAPI INT_Int2aHandler(CONTEXT86*);
/* msdos/int2f.c */ /* msdos/int2f.c */
extern void WINAPI INT_Int2fHandler(CONTEXT86*); extern void WINAPI INT_Int2fHandler(CONTEXT86*);
/* msdos/int41.c */
extern void WINAPI INT_Int41Handler(CONTEXT86*);
/* msdos/int4b.c */
extern void WINAPI INT_Int4bHandler(CONTEXT86*);
/* msdos/int5c.c */
extern void WINAPI NetBIOSCall16(CONTEXT86*);
/* fpu.c */ /* fpu.c */
extern void WINAPI INT_Int34Handler(CONTEXT86*); extern void WINAPI INT_Int34Handler(CONTEXT86*);
extern void WINAPI INT_Int35Handler(CONTEXT86*); extern void WINAPI INT_Int35Handler(CONTEXT86*);