Commit 6f6abac4 authored by Jukka Heinonen's avatar Jukka Heinonen Committed by Alexandre Julliard

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.
parent d9310e76
......@@ -1049,6 +1049,7 @@ init MAIN_KernelInit
@ stdcall INT_Int15Handler(ptr) INT_Int15Handler
@ stdcall INT_Int1aHandler(ptr) INT_Int1aHandler
@ stdcall INT_Int25Handler(ptr) INT_Int25Handler
@ stdcall INT_Int26Handler(ptr) INT_Int26Handler
@ stdcall INT_Int2aHandler(ptr) INT_Int2aHandler
@ stdcall INT_Int2fHandler(ptr) INT_Int2fHandler
@ stdcall INT_Int31Handler(ptr) INT_Int31Handler
......@@ -1063,6 +1064,9 @@ init MAIN_KernelInit
@ stdcall INT_Int3cHandler(ptr) INT_Int3cHandler
@ stdcall INT_Int3dHandler(ptr) INT_Int3dHandler
@ 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 LOCAL_Alloc(long long long) LOCAL_Alloc
@ cdecl LOCAL_Compact(long long long) LOCAL_Compact
......
......@@ -30,5 +30,9 @@
*/
void WINAPI DOSVM_Int20Handler( CONTEXT86 *context )
{
MZ_Exit( context, TRUE, 0 );
/* FIXME: Is this correct in DOS DPMI? */
if (ISV86(context))
MZ_Exit( context, TRUE, 0 );
else
ExitThread(0);
}
......@@ -72,11 +72,17 @@ void WINAPI DOSVM_Int21Handler_Ioctl( CONTEXT86 *context )
/***********************************************************************
* 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 )
{
BYTE ascii;
if (DOSVM_IsWin16()) {
DOS3Call( context );
return;
}
RESET_CFLAG(context); /* Not sure if this is a good idea */
if(AH_reg(context) == 0x0c) /* FLUSH BUFFER AND READ STANDARD INPUT */
......
......@@ -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 */
TRACE("called from real mode\n");
if (context->SegCs==DOSVM_dpmi_segments->dpmi_seg) {
/* This is the protected mode switch */
StartPM(context);
return;
return TRUE;
}
else if (context->SegCs==DOSVM_dpmi_segments->xms_seg)
{
/* This is the XMS driver entry point */
XMS_Handler(context);
return;
return TRUE;
}
else
{
......@@ -646,10 +657,57 @@ void WINAPI DOSVM_Int31Handler( CONTEXT86 *context )
if (CurrRMCB) {
/* RMCB call, propagate to protected-mode handler */
DPMI_CallRMCBProc(context, CurrRMCB, dpmi_flag);
return;
return TRUE;
}
}
/* chain to protected mode handler */
INT_Int31Handler( context );
return FALSE;
}
/**********************************************************************
* 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 */
}
}
......@@ -24,14 +24,81 @@
WINE_DEFAULT_DEBUG_CHANNEL(int);
static FARPROC16 DOSVM_Vectors16[256];
static FARPROC48 DOSVM_Vectors48[256];
static INTPROC DOSVM_VectorsBuiltin[256];
/*
* 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); }
/* Ordinal number for interrupt 0 handler in winedos.dll and winedos16.dll */
static FARPROC16 DOSVM_Vectors16[256];
static FARPROC48 DOSVM_Vectors48[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 winedos16.dll */
#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
*
* Emulate software interrupt in 16-bit or 32-bit protected mode.
......@@ -143,11 +210,11 @@ FARPROC16 DOSVM_GetPMHandler16( BYTE intnum )
/**********************************************************************
* DOSVM_SetPMHandler
* DOSVM_SetPMHandler16
*
* 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",
intnum, HIWORD(handler), LOWORD(handler) );
......@@ -190,41 +257,12 @@ void DOSVM_SetPMHandler48( BYTE intnum, FARPROC48 handler )
*/
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;
if (intnum < sizeof(DOSVM_VectorsBuiltin)/sizeof(INTPROC)) {
INTPROC proc = DOSVM_VectorsBuiltin[intnum];
if(proc)
return proc;
}
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 )
{
WARN("int%x not implemented, returning dummy handler\n", intnum );
return DOSVM_DefaultHandler;
}
......@@ -240,6 +240,15 @@ extern void WINAPI INT_Int2aHandler(CONTEXT86*);
/* msdos/int2f.c */
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 */
extern void WINAPI INT_Int34Handler(CONTEXT86*);
extern void WINAPI INT_Int35Handler(CONTEXT86*);
......
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