diff --git a/dlls/winedos/dosexe.h b/dlls/winedos/dosexe.h index 19f601a2a58..9e90dc76b19 100644 --- a/dlls/winedos/dosexe.h +++ b/dlls/winedos/dosexe.h @@ -264,6 +264,9 @@ void DOSVM_BuildCallFrame( CONTEXT86 *, DOSRELAY, LPVOID ); extern void SB_ioport_out( WORD port, BYTE val ); extern BYTE SB_ioport_in( WORD port ); +/* timer.c */ +extern void WINAPI DOSVM_Int08Handler(CONTEXT86*); + /* xms.c */ extern void WINAPI XMS_Handler(CONTEXT86*); diff --git a/dlls/winedos/interrupts.c b/dlls/winedos/interrupts.c index 52b4cdb07b1..11973836fa8 100644 --- a/dlls/winedos/interrupts.c +++ b/dlls/winedos/interrupts.c @@ -45,7 +45,7 @@ static const INTPROC DOSVM_VectorsBuiltin[] = { /* 00 */ 0, 0, 0, 0, /* 04 */ 0, 0, 0, 0, - /* 08 */ 0, DOSVM_Int09Handler, 0, 0, + /* 08 */ DOSVM_Int08Handler, 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, diff --git a/dlls/winedos/module.c b/dlls/winedos/module.c index f8b92dca91c..0ed2584d9a0 100644 --- a/dlls/winedos/module.c +++ b/dlls/winedos/module.c @@ -152,37 +152,6 @@ static void MZ_FillPSP( LPVOID lpPSP, LPCSTR cmdtail, int length ) /* FIXME: more PSP stuff */ } -/* default INT 08 handler: increases timer tick counter but not much more */ -static char int08[]={ - 0xCD,0x1C, /* int $0x1c */ - 0x50, /* pushw %ax */ - 0x1E, /* pushw %ds */ - 0xB8,0x40,0x00, /* movw $0x40,%ax */ - 0x8E,0xD8, /* movw %ax,%ds */ -#if 0 - 0x83,0x06,0x6C,0x00,0x01, /* addw $1,(0x6c) */ - 0x83,0x16,0x6E,0x00,0x00, /* adcw $0,(0x6e) */ -#else - 0x66,0xFF,0x06,0x6C,0x00, /* incl (0x6c) */ -#endif - 0xB0,0x20, /* movb $0x20,%al */ - 0xE6,0x20, /* outb %al,$0x20 */ - 0x1F, /* popw %ax */ - 0x58, /* popw %ax */ - 0xCF /* iret */ -}; - -static void MZ_InitHandlers(void) -{ - WORD seg; - LPBYTE start = DOSVM_AllocCodeUMB( sizeof(int08), &seg, 0 ); - memcpy(start,int08,sizeof(int08)); -/* INT 08: point it at our tick-incrementing handler */ - ((SEGPTR*)0)[0x08]=MAKESEGPTR(seg,0); -/* INT 1C: just point it to IRET, we don't want to handle it ourselves */ - ((SEGPTR*)0)[0x1C]=MAKESEGPTR(seg,sizeof(int08)-1); -} - static WORD MZ_InitEnvironment( LPCSTR env, LPCSTR name ) { unsigned sz=0; @@ -213,7 +182,6 @@ static BOOL MZ_InitMemory(void) DOSMEM_Init(TRUE); DOSDEV_InstallDOSDevices(); - MZ_InitHandlers(); return TRUE; } diff --git a/dlls/winedos/timer.c b/dlls/winedos/timer.c index c1fda0c6373..37a038568cf 100644 --- a/dlls/winedos/timer.c +++ b/dlls/winedos/timer.c @@ -124,3 +124,44 @@ void WINAPI DOSVM_SetTimer( UINT ticks ) if (!DOSVM_IsWin16()) MZ_RunInThread( TIMER_DoSetTimer, ticks ); } + + +/*********************************************************************** + * DOSVM_Int08Handler + * + * DOS interrupt 08h handler (IRQ0 - TIMER). + */ +void WINAPI DOSVM_Int08Handler( CONTEXT86 *context ) +{ + BIOSDATA *bios_data = BIOS_DATA; + CONTEXT86 nested_context = *context; + FARPROC16 int1c_proc = DOSVM_GetRMHandler( 0x1c ); + + nested_context.SegCs = SELECTOROF(int1c_proc); + nested_context.Eip = OFFSETOF(int1c_proc); + + /* + * Update BIOS ticks since midnight. + * + * FIXME: What to do when number of ticks exceeds ticks per day? + */ + bios_data->Ticks++; + + /* + * If IRQ is called from protected mode, convert + * context into VM86 context. Stack is invalidated so + * that DPMI_CallRMProc allocates a new stack. + */ + if (!ISV86(&nested_context)) + { + nested_context.EFlags |= V86_FLAG; + nested_context.SegSs = 0; + } + + /* + * Call interrupt 0x1c. + */ + DPMI_CallRMProc( &nested_context, NULL, 0, TRUE ); + + DOSVM_AcknowledgeIRQ( context ); +}