Commit d25e0399 authored by Jukka Heinonen's avatar Jukka Heinonen Committed by Alexandre Julliard

Add support for interrupts in 32-bit code.

Remove some unnecessary code from 16-bit interrupt emulation.
parent 783bab61
......@@ -171,8 +171,16 @@ struct DPMI_segments
WORD xms_seg;
WORD dpmi_seg;
WORD dpmi_sel;
WORD int48_seg;
WORD int48_sel;
};
/* 48-bit segmented pointers for DOS DPMI32 */
typedef struct {
WORD selector;
DWORD offset;
} SEGPTR48, FARPROC48;
extern struct DPMI_segments DOSMEM_dpmi_segments;
extern const struct DPMI_segments *DOSMEM_GetDPMISegments(void);
......@@ -194,6 +202,8 @@ extern BOOL INSTR_EmulateInstruction( CONTEXT86 *context );
typedef void (WINAPI *INTPROC)(CONTEXT86*);
extern FARPROC16 INT_GetPMHandler( BYTE intnum );
extern void INT_SetPMHandler( BYTE intnum, FARPROC16 handler );
extern FARPROC48 INT_GetPMHandler48( BYTE intnum );
extern void INT_SetPMHandler48( BYTE intnum, FARPROC48 handler );
/* msdos/ioports.c */
extern DWORD IO_inport( int port, int count );
......
......@@ -686,19 +686,22 @@ BOOL INSTR_EmulateInstruction( CONTEXT86 *context )
case 0xcd: /* int <XX> */
if (long_op)
{
ERR("int xx from 32-bit code is not supported.\n");
break; /* Unable to emulate it */
FARPROC48 addr = INT_GetPMHandler48( instr[1] );
DWORD *stack = get_stack( context );
/* Push the flags and return address on the stack */
*(--stack) = context->EFlags;
*(--stack) = context->SegCs;
*(--stack) = context->Eip + prefixlen + 2;
add_stack(context, -3 * sizeof(DWORD));
/* Jump to the interrupt handler */
context->SegCs = addr.selector;
context->Eip = addr.offset;
return TRUE;
}
else
{
FARPROC16 addr = INT_GetPMHandler( instr[1] );
WORD *stack = get_stack( context );
if (!addr)
{
FIXME("no handler for interrupt %02x, ignoring it\n", instr[1]);
context->Eip += prefixlen + 2;
return TRUE;
}
/* Push the flags and return address on the stack */
*(--stack) = LOWORD(context->EFlags);
*(--stack) = context->SegCs;
......
......@@ -161,6 +161,7 @@ static void DOSMEM_MakeIsrStubs(void)
static void DOSMEM_InitDPMI(void)
{
LPSTR ptr;
int i;
static const char wrap_code[]={
0xCD,0x31, /* int $0x31 */
......@@ -210,6 +211,20 @@ static void DOSMEM_InitDPMI(void)
ptr = DOSMEM_GetBlock( sizeof(enter_pm), &DOSMEM_dpmi_segments.dpmi_seg );
memcpy( ptr, enter_pm, sizeof(enter_pm) );
DOSMEM_dpmi_segments.dpmi_sel = SELECTOR_AllocBlock( ptr, sizeof(enter_pm), WINE_LDT_FLAGS_CODE );
ptr = DOSMEM_GetBlock( 4 * 256, &DOSMEM_dpmi_segments.int48_seg );
for(i=0; i<256; i++) {
/*
* Each 32-bit interrupt handler is 4 bytes:
* 0xCD,<i> = int <i> (nested 16-bit interrupt)
* 0x66,0xCF = iretd (32-bit interrupt return)
*/
ptr[i * 4 + 0] = 0xCD;
ptr[i * 4 + 1] = i;
ptr[i * 4 + 2] = 0x66;
ptr[i * 4 + 3] = 0xCF;
}
DOSMEM_dpmi_segments.int48_sel = SELECTOR_AllocBlock( ptr, 4 * 256, WINE_LDT_FLAGS_CODE );
}
static BIOSDATA * DOSMEM_BiosData(void)
......
......@@ -29,6 +29,7 @@
WINE_DEFAULT_DEBUG_CHANNEL(int);
static FARPROC16 INT_Vectors[256];
static FARPROC48 INT_Vectors48[256];
/* Ordinal number for interrupt 0 handler in WPROCS.DLL */
#define FIRST_INTERRUPT 100
......@@ -77,6 +78,37 @@ void INT_SetPMHandler( BYTE intnum, FARPROC16 handler )
/**********************************************************************
* INT_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 INT_GetPMHandler48( BYTE intnum )
{
if (!INT_Vectors48[intnum].selector)
{
INT_Vectors48[intnum].selector = DOSMEM_dpmi_segments.int48_sel;
INT_Vectors48[intnum].offset = 4 * intnum;
}
return INT_Vectors48[intnum];
}
/**********************************************************************
* INT_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 INT_SetPMHandler48( BYTE intnum, FARPROC48 handler )
{
TRACE("Set 32-bit protected mode interrupt vector %02x <- %04x:%08x\n",
intnum, handler.selector, handler.offset );
INT_Vectors48[intnum] = handler;
}
/**********************************************************************
* INT_DefaultHandler (WPROCS.356)
*
* Default interrupt handler.
......
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