Merged DOSVM_Int with DOSVM_SimulateInt, and made it handle apps that

purposefully shuffle the interrupt vectors around.
This commit is contained in:
Ove Kaaven 2000-10-13 20:14:49 +00:00 committed by Alexandre Julliard
parent 036ae0b6b3
commit dfa4130804
1 changed files with 24 additions and 21 deletions

View File

@ -126,27 +126,29 @@ static void DOSVM_Dump( int fn, int sig, struct vm86plus_struct*VM86 )
printf("\n"); printf("\n");
} }
static int DOSVM_Int( int vect, CONTEXT86 *context ) static int DOSVM_SimulateInt( int vect, CONTEXT86 *context )
{
if (vect==0x31) {
if (context->SegCs==DOSMEM_wrap_seg) {
/* exit from real-mode wrapper */
return -1;
}
/* we could probably move some other dodgy stuff here too from dpmi.c */
}
INT_RealModeInterrupt(vect,context);
return 0;
}
static void DOSVM_SimulateInt( int vect, CONTEXT86 *context )
{ {
FARPROC16 handler=INT_GetRMHandler(vect); FARPROC16 handler=INT_GetRMHandler(vect);
if (SELECTOROF(handler)==0xf000) { /* check for our real-mode hooks */
/* if internal interrupt, call it directly */ if (vect==0x31) {
INT_RealModeInterrupt(vect,context); if (context->SegCs==DOSMEM_wrap_seg) {
} else { /* exit from real-mode wrapper */
return -1;
}
/* we could probably move some other dodgy stuff here too from dpmi.c */
}
/* check if the call is from our fake BIOS interrupt stubs */
if (context->SegCs==0xf000) {
INT_RealModeInterrupt(vect, context);
}
/* check if the call goes to an unhooked interrupt */
else if (SELECTOROF(handler)==0xf000) {
/* if so, call it directly */
INT_RealModeInterrupt(OFFSETOF(handler)/4, context);
}
/* the interrupt is hooked, simulate interrupt in DOS space */
else {
WORD*stack= PTR_REAL_TO_LIN( context->SegSs, context->Esp ); WORD*stack= PTR_REAL_TO_LIN( context->SegSs, context->Esp );
WORD flag=LOWORD(context->EFlags); WORD flag=LOWORD(context->EFlags);
@ -161,6 +163,7 @@ static void DOSVM_SimulateInt( int vect, CONTEXT86 *context )
context->Eip=OFFSETOF(handler); context->Eip=OFFSETOF(handler);
IF_CLR(context); IF_CLR(context);
} }
return 0;
} }
#define SHOULD_PEND(x) \ #define SHOULD_PEND(x) \
@ -316,7 +319,7 @@ static int DOSVM_Process( int fn, int sig, struct vm86plus_struct*VM86 )
case VM86_INTx: case VM86_INTx:
if (TRACE_ON(relay)) if (TRACE_ON(relay))
DPRINTF("Call DOS int 0x%02x (EAX=%08lx) ret=%04lx:%04lx\n",VM86_ARG(fn),context.Eax,context.SegCs,context.Eip); DPRINTF("Call DOS int 0x%02x (EAX=%08lx) ret=%04lx:%04lx\n",VM86_ARG(fn),context.Eax,context.SegCs,context.Eip);
ret=DOSVM_Int(VM86_ARG(fn),&context); ret=DOSVM_SimulateInt(VM86_ARG(fn),&context);
if (TRACE_ON(relay)) if (TRACE_ON(relay))
DPRINTF("Ret DOS int 0x%02x (EAX=%08lx) ret=%04lx:%04lx\n",VM86_ARG(fn),context.Eax,context.SegCs,context.Eip); DPRINTF("Ret DOS int 0x%02x (EAX=%08lx) ret=%04lx:%04lx\n",VM86_ARG(fn),context.Eax,context.SegCs,context.Eip);
break; break;
@ -561,7 +564,7 @@ void DOSVM_SetTimer( unsigned ticks )
if (MZ_Current()) { if (MZ_Current()) {
/* the PC clocks ticks at 1193180 Hz */ /* the PC clocks ticks at 1193180 Hz */
tim.tv_sec=0; tim.tv_sec=0;
tim.tv_usec=((unsigned long long)ticks*1000000)/1193180; tim.tv_usec=MulDiv(ticks,1000000,1193180);
/* sanity check */ /* sanity check */
if (!tim.tv_usec) tim.tv_usec=1; if (!tim.tv_usec) tim.tv_usec=1;
@ -594,7 +597,7 @@ unsigned DOSVM_GetTimer( void )
ERR_(module)("dosmod sync lost, errno=%d\n",errno); ERR_(module)("dosmod sync lost, errno=%d\n",errno);
return 0; return 0;
} }
return ((unsigned long long)tim.tv_usec*1193180)/1000000; return MulDiv(tim.tv_usec,1193180,1000000);
} }
return 0; return 0;
} }