winedos / Convert timer IRQ handler

Jukka Heinonen jhei at iki.fi
Fri Jun 27 14:34:09 CDT 2003


Timer IRQ need to be called from real and protected mode.
The simplest way to do this is to convert it into normal
builtin handler. This is actually faster in real mode
than the original handler was because we make less transitions
between VM86 and linear mode.

There are still 1 or 2 small patches left before IRQs really work
in protected mode. I have been too busy lately so I haven't
been able to submit them earlier...




Changelog:
  Make timer IRQ handler regular builtin interrupt handler
  instead of using an assembler stub.




Index: dlls/winedos/dosexe.h
===================================================================
RCS file: /home/wine/wine/dlls/winedos/dosexe.h,v
retrieving revision 1.27
diff -u -r1.27 dosexe.h
--- dlls/winedos/dosexe.h	23 Jun 2003 03:35:51 -0000	1.27
+++ dlls/winedos/dosexe.h	27 Jun 2003 19:23:11 -0000
@@ -264,6 +264,9 @@
 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*);
 




Index: dlls/winedos/interrupts.c
===================================================================
RCS file: /home/wine/wine/dlls/winedos/interrupts.c,v
retrieving revision 1.15
diff -u -r1.15 interrupts.c
--- dlls/winedos/interrupts.c	13 Apr 2003 01:06:36 -0000	1.15
+++ dlls/winedos/interrupts.c	27 Jun 2003 19:23:21 -0000
@@ -45,7 +45,7 @@
 {
   /* 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,




Index: dlls/winedos/module.c
===================================================================
RCS file: /home/wine/wine/dlls/winedos/module.c,v
retrieving revision 1.34
diff -u -r1.34 module.c
--- dlls/winedos/module.c	2 May 2003 20:11:52 -0000	1.34
+++ dlls/winedos/module.c	27 Jun 2003 19:23:29 -0000
@@ -152,37 +152,6 @@
     /* 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 @@
     DOSMEM_Init(TRUE);
     DOSDEV_InstallDOSDevices();
 
-    MZ_InitHandlers();
     return TRUE;
 }
 




Index: dlls/winedos/timer.c
===================================================================
RCS file: /home/wine/wine/dlls/winedos/timer.c,v
retrieving revision 1.1
diff -u -r1.1 timer.c
--- dlls/winedos/timer.c	13 Jun 2003 16:28:49 -0000	1.1
+++ dlls/winedos/timer.c	27 Jun 2003 19:23:33 -0000
@@ -124,3 +124,44 @@
     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 );
+}




-- 
Jukka Heinonen <http://www.iki.fi/jhei/>



More information about the wine-patches mailing list