ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/Windows/timer_windows.cpp
Revision: 1.5
Committed: 2005-06-30T10:20:18Z (19 years, 5 months ago) by gbeauche
Branch: MAIN
CVS Tags: nigel-build-17
Changes since 1.4: +19 -0 lines
Log Message:
Add system-specific implementations of idle_{wait,resume} functions.

File Contents

# User Rev Content
1 gbeauche 1.1 /*
2     * timer_windows.cpp - Time Manager emulation, Windows specific stuff
3     *
4 gbeauche 1.4 * Basilisk II (C) 1997-2005 Christian Bauer
5 gbeauche 1.1 *
6     * This program is free software; you can redistribute it and/or modify
7     * it under the terms of the GNU General Public License as published by
8     * the Free Software Foundation; either version 2 of the License, or
9     * (at your option) any later version.
10     *
11     * This program is distributed in the hope that it will be useful,
12     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU General Public License for more details.
15     *
16     * You should have received a copy of the GNU General Public License
17     * along with this program; if not, write to the Free Software
18     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19     */
20    
21     #include "sysdeps.h"
22    
23     #define WIN32_LEAN_AND_MEAN
24     #include <windows.h>
25    
26     #include "main.h"
27     #include "macos_util.h"
28     #include "timer.h"
29    
30     #define DEBUG 0
31     #include "debug.h"
32    
33    
34     // Helper time functions
35     #define MSECS2TICKS(MSECS) (((uint64)(MSECS) * frequency) / 1000)
36     #define USECS2TICKS(USECS) (((uint64)(USECS) * frequency) / 1000000)
37     #define TICKS2USECS(TICKS) (((uint64)(TICKS) * 1000000) / frequency)
38    
39     // Global variables
40     static uint32 frequency; // CPU frequency in Hz (< 4 GHz)
41     static tm_time_t mac_boot_ticks;
42     static tm_time_t mac_1904_ticks;
43     static tm_time_t mac_now_diff;
44    
45    
46     /*
47     * Initialize native Windows timers
48     */
49    
50 gbeauche 1.3 void timer_init(void)
51 gbeauche 1.1 {
52     D(bug("SysTimerInit\n"));
53    
54     LARGE_INTEGER tt;
55     if (!QueryPerformanceFrequency(&tt)) {
56     ErrorAlert("No high resolution timers available\n");
57     QuitEmulator();
58     }
59     frequency = tt.LowPart;
60     D(bug(" frequency %d\n", frequency));
61    
62     // mac_boot_ticks is 1.18 us since Basilisk II was started
63     QueryPerformanceCounter(&tt);
64     mac_boot_ticks = tt.QuadPart;
65    
66     // mac_1904_ticks is 1.18 us since Mac time started 1904
67     mac_1904_ticks = time(NULL) * frequency;
68     mac_now_diff = mac_1904_ticks - mac_boot_ticks;
69     }
70    
71    
72     /*
73     * Return microseconds since boot (64 bit)
74     */
75    
76     void Microseconds(uint32 &hi, uint32 &lo)
77     {
78     D(bug("Microseconds\n"));
79     LARGE_INTEGER tt;
80     QueryPerformanceCounter(&tt);
81     tt.QuadPart = TICKS2USECS(tt.QuadPart - mac_boot_ticks);
82     hi = tt.HighPart;
83     lo = tt.LowPart;
84     }
85    
86    
87     /*
88     * Return local date/time in Mac format (seconds since 1.1.1904)
89     */
90    
91     uint32 TimerDateTime(void)
92     {
93     return TimeToMacTime(time(NULL));
94     }
95    
96    
97     /*
98     * Get current time
99     */
100    
101     void timer_current_time(tm_time_t &t)
102     {
103     LARGE_INTEGER tt;
104     QueryPerformanceCounter(&tt);
105     t = tt.QuadPart + mac_now_diff;
106     }
107    
108    
109     /*
110     * Add times
111     */
112    
113     void timer_add_time(tm_time_t &res, tm_time_t a, tm_time_t b)
114     {
115     res = a + b;
116     }
117    
118    
119     /*
120     * Subtract times
121     */
122    
123     void timer_sub_time(tm_time_t &res, tm_time_t a, tm_time_t b)
124     {
125     res = a - b;
126     }
127    
128    
129     /*
130     * Compare times (<0: a < b, =0: a = b, >0: a > b)
131     */
132    
133     int timer_cmp_time(tm_time_t a, tm_time_t b)
134     {
135     tm_time_t r = a - b;
136     return r < 0 ? -1 : (r > 0 ? 1 : 0);
137     }
138    
139    
140     /*
141     * Convert Mac time value (>0: microseconds, <0: microseconds) to tm_time_t
142     */
143    
144     void timer_mac2host_time(tm_time_t &res, int32 mactime)
145     {
146     if (mactime > 0) {
147     // Time in milliseconds
148     res = MSECS2TICKS(mactime);
149     } else {
150     // Time in negative microseconds
151     res = USECS2TICKS(-mactime);
152     }
153     }
154    
155    
156     /*
157     * Convert positive tm_time_t to Mac time value (>0: microseconds, <0: microseconds)
158     * A negative input value for hosttime results in a zero return value
159     * As long as the microseconds value fits in 32 bit, it must not be converted to milliseconds!
160     */
161    
162     int32 timer_host2mac_time(tm_time_t hosttime)
163     {
164     if (hosttime < 0)
165     return 0;
166     else {
167 gbeauche 1.2 uint64 t = TICKS2USECS(hosttime);
168 gbeauche 1.1 if (t > 0x7fffffff)
169     return t / 1000; // Time in milliseconds
170     else
171     return -t; // Time in negative microseconds
172     }
173     }
174    
175    
176     /*
177     * Get current value of microsecond timer
178     */
179    
180     uint64 GetTicks_usec(void)
181     {
182     LARGE_INTEGER tt;
183     QueryPerformanceCounter(&tt);
184     return TICKS2USECS(tt.QuadPart - mac_boot_ticks);
185     }
186    
187    
188     /*
189     * Delay by specified number of microseconds (<1 second)
190     */
191    
192     void Delay_usec(uint32 usec)
193     {
194     // FIXME: fortunately, Delay_usec() is generally used with
195     // millisecond resolution anyway
196     Sleep(usec / 1000);
197     }
198 gbeauche 1.5
199    
200     /*
201     * Suspend emulator thread, virtual CPU in idle mode
202     */
203    
204     void idle_wait(void)
205     {
206     Delay_usec(10000);
207     }
208    
209    
210     /*
211     * Resume execution of emulator thread, events just arrived
212     */
213    
214     void idle_resume(void)
215     {
216     }