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:
parent
d9310e76c4
commit
6f6abac4f1
|
@ -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,13 +24,80 @@
|
|||
|
||||
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
|
||||
*
|
||||
|
@ -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*);
|
||||
|
|
Loading…
Reference in New Issue