--- /dev/null
+#ifndef UAE_TIME_H
+#define UAE_TIME_H
+
+#include "uae/types.h"
+
+/* frame_time_t is often cast to int in the code so we use int for now... */
+typedef uae_u32 uae_time_t;
+
+void uae_time_init(void);
+void uae_time_calibrate(void);
+uae_time_t uae_time(void);
+
+#ifdef _WIN32
+void uae_time_use_rdtsc(bool enable);
+uae_u32 read_system_time(void);
+#endif
+
+typedef uae_time_t frame_time_t;
+
+static inline frame_time_t read_processor_time(void)
+{
+ return uae_time();
+}
+
+#endif /* UAE_TIME_H */
-/*
- * UAE - The Un*x Amiga Emulator
- *
- * Definitions for accessing cycle counters on a given machine, if possible.
- *
- * Copyright 1997, 1998 Bernd Schmidt
- * Copyright 1999 Brian King - Win32 specific
- */
-#ifndef _RPT_H_
-#define _RPT_H_
-
-typedef unsigned long frame_time_t;
-extern frame_time_t read_processor_time (void);
-extern uae_u32 read_system_time (void);
-
-#endif
+#include "uae/time.h"
#endif
#include "uae/ppc.h"
#include "fsdb.h"
+#include "uae/time.h"
extern int harddrive_dangerous, do_rdbdump;
extern int no_rawinput, no_directinput, no_windowsmouse;
static int console_started;
void *globalipc;
-int qpcdivisor = 0;
int cpu_mmx = 1;
-static int userdtsc = 0;
int D3DEX = 1;
int d3ddebug = 0;
int max_uae_width;
#endif
}
-frame_time_t read_processor_time_qpf (void)
-{
- LARGE_INTEGER counter;
- frame_time_t t;
- QueryPerformanceCounter (&counter);
- if (qpcdivisor == 0)
- t = (frame_time_t)(counter.LowPart);
- else
- t = (frame_time_t)(counter.QuadPart >> qpcdivisor);
- if (!t)
- t++;
- return t;
-}
-frame_time_t read_processor_time_rdtsc (void)
-{
- frame_time_t foo = 0;
-#if defined(X86_MSVC_ASSEMBLY)
- frame_time_t bar;
- __asm
- {
- rdtsc
- mov foo, eax
- mov bar, edx
- }
- /* very high speed CPU's RDTSC might overflow without this.. */
- foo >>= 6;
- foo |= bar << 26;
- if (!foo)
- foo++;
-#endif
- return foo;
-}
-frame_time_t read_processor_time (void)
-{
- frame_time_t t;
-#if 0
- static int cnt;
-
- cnt++;
- if (cnt > 1000000) {
- write_log (_T("**************\n"));
- cnt = 0;
- }
-#endif
- if (userdtsc)
- t = read_processor_time_rdtsc ();
- else
- t = read_processor_time_qpf ();
- return t;
-}
-
-uae_u32 read_system_time (void)
-{
- return GetTickCount ();
-}
-
-#include <process.h>
-static volatile int dummythread_die;
-static void _cdecl dummythread (void *dummy)
-{
- SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_LOWEST);
- while (!dummythread_die);
-}
-static uae_u64 win32_read_processor_time (void)
-{
-#if defined(X86_MSVC_ASSEMBLY)
- uae_u32 foo, bar;
- __asm
- {
- cpuid
- rdtsc
- mov foo, eax
- mov bar, edx
- }
- return (((uae_u64)bar) << 32) | foo;
-#else
- return 0;
-#endif
-}
-static void figure_processor_speed_rdtsc (void)
-{
- static int freqset;
- uae_u64 clockrate;
- int oldpri;
- HANDLE th;
-
- if (freqset)
- return;
- th = GetCurrentThread ();
- freqset = 1;
- oldpri = GetThreadPriority (th);
- SetThreadPriority (th, THREAD_PRIORITY_HIGHEST);
- dummythread_die = -1;
- _beginthread (&dummythread, 0, 0);
- sleep_millis (500);
- clockrate = win32_read_processor_time ();
- sleep_millis (500);
- clockrate = (win32_read_processor_time () - clockrate) * 2;
- dummythread_die = 0;
- SetThreadPriority (th, oldpri);
- write_log (_T("CLOCKFREQ: RDTSC %.2fMHz\n"), clockrate / 1000000.0);
- syncbase = clockrate >> 6;
-}
-
-static void figure_processor_speed_qpf (void)
-{
- LARGE_INTEGER freq;
- static LARGE_INTEGER freq2;
- uae_u64 qpfrate;
-
- if (!QueryPerformanceFrequency (&freq))
- return;
- if (freq.QuadPart == freq2.QuadPart)
- return;
- freq2.QuadPart = freq.QuadPart;
- qpfrate = freq.QuadPart;
- /* limit to 10MHz */
- qpcdivisor = 0;
- while (qpfrate >= 10000000) {
- qpfrate >>= 1;
- qpcdivisor++;
- }
- write_log (_T("CLOCKFREQ: QPF %.2fMHz (%.2fMHz, DIV=%d)\n"), freq.QuadPart / 1000000.0,
- qpfrate / 1000000.0, 1 << qpcdivisor);
- syncbase = (int)qpfrate;
-}
-
-static void figure_processor_speed (void)
-{
- if (SystemInfo.dwNumberOfProcessors > 1)
- userdtsc = 0;
- if (userdtsc)
- figure_processor_speed_rdtsc ();
- if (!userdtsc)
- figure_processor_speed_qpf ();
-}
-
static int windowmouse_max_w;
static int windowmouse_max_h;
}
cnt1--;
if (cnt1 <= 0) {
- figure_processor_speed ();
+ uae_time_calibrate();
flush_log ();
cnt1 = 50 * 5;
cnt2--;
pre_gui_message (_T("No QueryPerformanceFrequency() supported, exiting..\n"));
return 0;
}
- figure_processor_speed ();
+ uae_time_init();
if (!timebegin ()) {
pre_gui_message (_T("MMTimer second initialization failed, exiting.."));
return 0;
return 1;
}
if (!_tcscmp (arg, _T("forcerdtsc"))) {
- userdtsc = 1;
+ uae_time_use_rdtsc(true);
return 1;
}
if (!_tcscmp (arg, _T("ddsoftwarecolorkey"))) {
<ClCompile Include="..\..\sndboard.cpp" />
<ClCompile Include="..\..\specialmonitors.cpp" />
<ClCompile Include="..\..\statusline.cpp" />
+ <ClCompile Include="..\..\support\time.cpp" />
<ClCompile Include="..\..\tabletlibrary.cpp" />
<ClCompile Include="..\..\test_card.cpp" />
<ClCompile Include="..\..\uaenative.cpp" />
<Filter Include="x86">
<UniqueIdentifier>{c9a4aeea-c63c-40e4-9da2-371acd5ea8fe}</UniqueIdentifier>
</Filter>
+ <Filter Include="support">
+ <UniqueIdentifier>{fe9d96c8-c5ef-4f92-b9dc-79b5d3e4145c}</UniqueIdentifier>
+ </Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\ahidsound_dsonly.cpp">
<ClCompile Include="..\..\cpuemu_50.cpp">
<Filter>common</Filter>
</ClCompile>
+ <ClCompile Include="..\..\support\time.cpp">
+ <Filter>support</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\resources\35floppy.ico">
--- /dev/null
+#include "sysconfig.h"
+#include "sysdeps.h"
+#include "uae/time.h"
+#include "options.h"
+#include "events.h"
+#include "uae.h"
+
+#ifdef _WIN32
+
+#include <process.h>
+
+static int userdtsc = 0;
+static int qpcdivisor = 0;
+static SYSTEM_INFO si;
+
+static frame_time_t read_processor_time_qpf(void)
+{
+ LARGE_INTEGER counter;
+ frame_time_t t;
+ QueryPerformanceCounter(&counter);
+ if (qpcdivisor == 0)
+ t = (frame_time_t) (counter.LowPart);
+ else
+ t = (frame_time_t) (counter.QuadPart >> qpcdivisor);
+ if (!t)
+ t++;
+ return t;
+}
+
+static frame_time_t read_processor_time_rdtsc(void)
+{
+ frame_time_t foo = 0;
+#if defined(X86_MSVC_ASSEMBLY)
+ frame_time_t bar;
+ __asm
+ {
+ rdtsc
+ mov foo, eax
+ mov bar, edx
+ }
+ /* very high speed CPU's RDTSC might overflow without this.. */
+ foo >>= 6;
+ foo |= bar << 26;
+ if (!foo)
+ foo++;
+#endif
+ return foo;
+}
+
+uae_time_t uae_time(void)
+{
+ uae_time_t t;
+#if 0
+ static int cnt;
+
+ cnt++;
+ if (cnt > 1000000) {
+ write_log(_T("**************\n"));
+ cnt = 0;
+ }
+#endif
+ if (userdtsc)
+ t = read_processor_time_rdtsc();
+ else
+ t = read_processor_time_qpf();
+ return t;
+}
+
+uae_u32 read_system_time(void)
+{
+ return GetTickCount();
+}
+
+static volatile int dummythread_die;
+
+static void _cdecl dummythread(void *dummy)
+{
+ SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST);
+ while (!dummythread_die);
+}
+
+static uae_u64 win32_read_processor_time(void)
+{
+#if defined(X86_MSVC_ASSEMBLY)
+ uae_u32 foo, bar;
+ __asm
+ {
+ cpuid
+ rdtsc
+ mov foo, eax
+ mov bar, edx
+ }
+ return (((uae_u64)bar) << 32) | foo;
+#else
+ return 0;
+#endif
+}
+
+static void figure_processor_speed_rdtsc(void)
+{
+ static int freqset;
+ uae_u64 clockrate;
+ int oldpri;
+ HANDLE th;
+
+ if (freqset)
+ return;
+ th = GetCurrentThread ();
+ freqset = 1;
+ oldpri = GetThreadPriority(th);
+ SetThreadPriority(th, THREAD_PRIORITY_HIGHEST);
+ dummythread_die = -1;
+ _beginthread(&dummythread, 0, 0);
+ sleep_millis(500);
+ clockrate = win32_read_processor_time();
+ sleep_millis(500);
+ clockrate = (win32_read_processor_time() - clockrate) * 2;
+ dummythread_die = 0;
+ SetThreadPriority(th, oldpri);
+ write_log(_T("CLOCKFREQ: RDTSC %.2fMHz\n"), clockrate / 1000000.0);
+ syncbase = clockrate >> 6;
+}
+
+static void figure_processor_speed_qpf(void)
+{
+ LARGE_INTEGER freq;
+ static LARGE_INTEGER freq2;
+ uae_u64 qpfrate;
+
+ if (!QueryPerformanceFrequency (&freq))
+ return;
+ if (freq.QuadPart == freq2.QuadPart)
+ return;
+ freq2.QuadPart = freq.QuadPart;
+ qpfrate = freq.QuadPart;
+ /* limit to 10MHz */
+ qpcdivisor = 0;
+ while (qpfrate >= 10000000) {
+ qpfrate >>= 1;
+ qpcdivisor++;
+ }
+ write_log(_T("CLOCKFREQ: QPF %.2fMHz (%.2fMHz, DIV=%d)\n"),
+ freq.QuadPart / 1000000.0,
+ qpfrate / 1000000.0, 1 << qpcdivisor);
+ syncbase = (int) qpfrate;
+}
+
+void uae_time_calibrate(void)
+{
+ if (si.dwNumberOfProcessors > 1) {
+ userdtsc = 0;
+ }
+ if (userdtsc) {
+ figure_processor_speed_rdtsc();
+ }
+ if (!userdtsc) {
+ figure_processor_speed_qpf();
+ }
+}
+
+void uae_time_use_rdtsc(bool enable)
+{
+ userdtsc = enable;
+}
+
+#elif defined(USE_GLIB)
+
+#include <glib.h>
+
+static gint64 epoch;
+
+uae_time_t uae_time(void)
+{
+ return (uae_time_t) g_get_monotonic_time();
+}
+
+void uae_time_calibrate(void)
+{
+
+}
+
+#endif
+
+void uae_time_init(void)
+{
+ static bool initialized = false;
+ if (initialized) {
+ return;
+ }
+#ifdef _WIN32
+ GetSystemInfo(&si);
+#endif
+ uae_time_calibrate();
+ initialized = true;
+}