4 * Copyright 1996 Alexandre Julliard
7 #include "wine/winbase16.h"
8 #include "wine/winuser16.h"
10 #include "debugtools.h"
12 DEFAULT_DEBUG_CHANNEL(system)
16 SYSTEMTIMERPROC callback; /* NULL if not in use */
21 #define NB_SYS_TIMERS 8
22 #define SYS_TIMER_RATE 54925
24 static SYSTEM_TIMER SYS_Timers[NB_SYS_TIMERS];
25 static int SYS_NbTimers = 0;
26 static HANDLE SYS_Service = INVALID_HANDLE_VALUE;
29 /***********************************************************************
32 static void CALLBACK SYSTEM_TimerTick( ULONG_PTR arg )
36 for (i = 0; i < NB_SYS_TIMERS; i++)
38 if (!SYS_Timers[i].callback) continue;
39 if ((SYS_Timers[i].ticks -= SYS_TIMER_RATE) <= 0)
41 SYS_Timers[i].ticks += SYS_Timers[i].rate;
42 SYS_Timers[i].callback( i+1 );
47 /**********************************************************************
50 * Start the system tick timer.
52 static void SYSTEM_StartTicks(void)
54 if ( SYS_Service == INVALID_HANDLE_VALUE )
55 SYS_Service = SERVICE_AddTimer( SYS_TIMER_RATE, SYSTEM_TimerTick, 0L );
59 /**********************************************************************
62 * Stop the system tick timer.
64 static void SYSTEM_StopTicks(void)
66 if ( SYS_Service != INVALID_HANDLE_VALUE )
68 SERVICE_Delete( SYS_Service );
69 SYS_Service = INVALID_HANDLE_VALUE;
74 /***********************************************************************
75 * InquireSystem (SYSTEM.1)
77 * Note: the function always takes 2 WORD arguments, contrary to what
78 * "Undocumented Windows" says.
80 DWORD WINAPI InquireSystem16( WORD code, WORD arg )
86 case 0: /* Get timer resolution */
87 return SYS_TIMER_RATE;
89 case 1: /* Get drive type */
90 drivetype = GetDriveType16( arg );
91 return MAKELONG( drivetype, drivetype );
93 case 2: /* Enable one-drive logic */
94 FIXME("Case %d: set single-drive %d not supported\n", code, arg );
97 WARN("Unknown code %d\n", code );
102 /***********************************************************************
103 * CreateSystemTimer (SYSTEM.2)
105 WORD WINAPI CreateSystemTimer( WORD rate, SYSTEMTIMERPROC callback )
108 for (i = 0; i < NB_SYS_TIMERS; i++)
109 if (!SYS_Timers[i].callback) /* Found one */
111 SYS_Timers[i].rate = (UINT)rate * 1000;
112 if (SYS_Timers[i].rate < SYS_TIMER_RATE)
113 SYS_Timers[i].rate = SYS_TIMER_RATE;
114 SYS_Timers[i].ticks = SYS_Timers[i].rate;
115 SYS_Timers[i].callback = callback;
116 if (++SYS_NbTimers == 1) SYSTEM_StartTicks();
117 return i + 1; /* 0 means error */
123 /***********************************************************************
124 * KillSystemTimer (SYSTEM.3)
126 * Note: do not confuse this function with USER.182
128 WORD WINAPI SYSTEM_KillSystemTimer( WORD timer )
130 if (!timer || (timer > NB_SYS_TIMERS)) return timer; /* Error */
131 SYS_Timers[timer-1].callback = NULL;
132 if (!--SYS_NbTimers) SYSTEM_StopTicks();
137 /***********************************************************************
138 * EnableSystemTimers (SYSTEM.4)
140 void WINAPI EnableSystemTimers16(void)
142 if ( SYS_Service != INVALID_HANDLE_VALUE )
143 SERVICE_Enable( SYS_Service );
147 /***********************************************************************
148 * DisableSystemTimers (SYSTEM.5)
150 void WINAPI DisableSystemTimers16(void)
152 if ( SYS_Service != INVALID_HANDLE_VALUE )
153 SERVICE_Disable( SYS_Service );
157 /***********************************************************************
158 * Get80x87SaveSize16 (SYSTEM.7)
160 WORD WINAPI Get80x87SaveSize16(void)
166 /***********************************************************************
167 * Save80x87State16 (SYSTEM.8)
169 void WINAPI Save80x87State16( char *ptr )
172 __asm__(".byte 0x66; fsave %0; fwait" : "=m" (ptr) );
177 /***********************************************************************
178 * Restore80x87State16 (SYSTEM.9)
180 void WINAPI Restore80x87State16( const char *ptr )
183 __asm__(".byte 0x66; frstor %0" : : "m" (ptr) );