Should get win16drv AbortProc working. Hopefully.
[wine.git] / misc / system.c
blobb9588fc55ecdbc96595add60a4ec7b5e3a8bb116
1 /*
2 * SYSTEM DLL routines
4 * Copyright 1996 Alexandre Julliard
5 */
7 #include <stdlib.h>
8 #include <signal.h>
9 #include <time.h>
10 #include <sys/time.h>
11 #include <sys/timeb.h>
12 #include <sys/types.h>
13 #include <sys/wait.h>
15 #include "callback.h"
16 #include "windows.h"
17 #include "miscemu.h"
18 #include "dosexe.h"
19 #include "vga.h"
20 #include "selectors.h"
21 #include "sig_context.h"
22 #include "debug.h"
24 typedef struct
26 FARPROC16 callback; /* NULL if not in use */
27 INT32 rate;
28 INT32 ticks;
29 } SYSTEM_TIMER;
31 #define NB_SYS_TIMERS 8
32 #define SYS_TIMER_RATE 54925
34 static SYSTEM_TIMER SYS_Timers[NB_SYS_TIMERS];
35 static int SYS_NbTimers = 0;
36 static BOOL32 SYS_TimersDisabled = FALSE;
38 /***********************************************************************
39 * SYSTEM_TimerTick
40 * FIXME: It is a very bad idea to call 16bit code in a signal handler:
41 * If the signal reached us in 16 bit code, we could have a broken
42 * %FS, which is in turned saved into the single global
43 * CALLTO16_Current_fs temporary storage, so a single misplaced
44 * signal crashes the whole WINE process.
45 * This needs more thought. -MM
47 static HANDLER_DEF(SYSTEM_TimerTick)
49 int i;
50 HANDLER_INIT();
52 for (i = 0; i < NB_SYS_TIMERS; i++)
54 if (!SYS_Timers[i].callback) continue;
55 if ((SYS_Timers[i].ticks -= SYS_TIMER_RATE) <= 0)
57 SYS_Timers[i].ticks += SYS_Timers[i].rate;
59 if (SYS_Timers[i].callback == (FARPROC16)DOSMEM_Tick) {
60 DOSMEM_Tick();
61 } else
62 if (SYS_Timers[i].callback == (FARPROC16)MZ_Tick) {
63 MZ_Tick(i+1);
64 } else
65 if (SYS_Timers[i].callback == (FARPROC16)VGA_Poll) {
66 VGA_Poll();
67 } else
68 Callbacks->CallSystemTimerProc( SYS_Timers[i].callback );
73 /**********************************************************************
74 * SYSTEM_StartTicks
76 * Start the system tick timer.
78 static void SYSTEM_StartTicks(void)
80 static BOOL32 handler_installed = FALSE;
82 if (!handler_installed)
84 handler_installed = TRUE;
85 SIGNAL_SetHandler( SIGALRM, SYSTEM_TimerTick, 1 );
87 #ifndef __EMX__ /* FIXME: Time don't work... Use BIOS directly instead */
89 struct itimerval vt_timer;
91 vt_timer.it_interval.tv_sec = 0;
92 vt_timer.it_interval.tv_usec = 54929;
93 vt_timer.it_value = vt_timer.it_interval;
94 setitimer( ITIMER_REAL, &vt_timer, NULL );
96 #endif
100 /**********************************************************************
101 * SYSTEM_StopTicks
103 * Stop the system tick timer.
105 static void SYSTEM_StopTicks(void)
107 #ifndef __EMX__ /* FIXME: Time don't work... Use BIOS directly instead */
108 struct itimerval vt_timer;
110 vt_timer.it_interval.tv_sec = 0;
111 vt_timer.it_interval.tv_usec = 0;
112 vt_timer.it_value = vt_timer.it_interval;
113 setitimer( ITIMER_REAL, &vt_timer, NULL );
114 #endif
118 /***********************************************************************
119 * InquireSystem (SYSTEM.1)
121 * Note: the function always takes 2 WORD arguments, contrary to what
122 * "Undocumented Windows" says.
124 DWORD WINAPI InquireSystem( WORD code, WORD arg )
126 WORD drivetype;
128 switch(code)
130 case 0: /* Get timer resolution */
131 return SYS_TIMER_RATE;
133 case 1: /* Get drive type */
134 drivetype = GetDriveType16( arg );
135 return MAKELONG( drivetype, drivetype );
137 case 2: /* Enable one-drive logic */
138 FIXME(system, "Case %d: set single-drive %d not supported\n", code, arg );
139 return 0;
141 WARN(system, "Unknown code %d\n", code );
142 return 0;
146 /***********************************************************************
147 * CreateSystemTimer (SYSTEM.2)
149 WORD WINAPI CreateSystemTimer( WORD rate, FARPROC16 callback )
151 int i;
153 /* FIXME: HACK: do not create system timers due to problems mentioned
154 * above, except DOSMEM_Tick(), MZ_Tick(), and VGA_Poll().
156 if ((callback!=(FARPROC16)DOSMEM_Tick)&&
157 (callback!=(FARPROC16)MZ_Tick)&&
158 (callback!=(FARPROC16)VGA_Poll)) {
159 FIXME(system,"are currently broken, returning 0.\n");
160 return 0;
163 for (i = 0; i < NB_SYS_TIMERS; i++)
164 if (!SYS_Timers[i].callback) /* Found one */
166 SYS_Timers[i].rate = (UINT32)rate * 1000;
167 if (SYS_Timers[i].rate < SYS_TIMER_RATE)
168 SYS_Timers[i].rate = SYS_TIMER_RATE;
169 SYS_Timers[i].ticks = SYS_Timers[i].rate;
170 SYS_Timers[i].callback = callback;
171 if ((++SYS_NbTimers == 1) && !SYS_TimersDisabled)
172 SYSTEM_StartTicks();
173 return i + 1; /* 0 means error */
175 return 0;
179 /***********************************************************************
180 * KillSystemTimer (SYSTEM.3)
182 * Note: do not confuse this function with USER.182
184 WORD WINAPI SYSTEM_KillSystemTimer( WORD timer )
186 if (!timer || (timer > NB_SYS_TIMERS)) return timer; /* Error */
187 SYS_Timers[timer-1].callback = NULL;
188 if ((!--SYS_NbTimers) && !SYS_TimersDisabled) SYSTEM_StopTicks();
189 return 0;
193 /***********************************************************************
194 * EnableSystemTimers (SYSTEM.4)
196 void WINAPI EnableSystemTimers(void)
198 SYS_TimersDisabled = FALSE;
199 if (SYS_NbTimers) SYSTEM_StartTicks();
203 /***********************************************************************
204 * DisableSystemTimers (SYSTEM.5)
206 void WINAPI DisableSystemTimers(void)
208 SYS_TimersDisabled = TRUE;
209 if (SYS_NbTimers) SYSTEM_StopTicks();