Ported Dxbx PerformanceCounter implementation

This seems a better approach, since it bases it's performance counter on
a value that starts at the start of emulation, plus it returns values
scaled back to the real Xbox frequency.
This commit is contained in:
PatrickvL 2016-12-31 19:54:33 +01:00
parent 9459a2d04f
commit 74b13b7d65
3 changed files with 40 additions and 8 deletions

View File

@ -366,6 +366,8 @@ extern "C" CXBXKRNL_API void CxbxKrnlInit
g_CurrentProcessHandle = GetCurrentProcess();
CxbxInitPerformanceCounters();
#ifdef _DEBUG
// MessageBoxA(NULL, "Attach a Debugger", "DEBUG", 0);
// Debug child processes using https://marketplace.visualstudio.com/items?itemName=GreggMiskelly.MicrosoftChildProcessDebuggingPowerTool

View File

@ -82,6 +82,8 @@ CXBXKRNL_API void CxbxKrnlPanic();
/*! empty function */
CXBXKRNL_API void CxbxKrnlNoFunc();
CXBXKRNL_API void CxbxInitPerformanceCounters(); // Implemented in EmuKrnlKe.cpp
/*! kernel thunk table */
extern CXBXKRNL_API uint32 CxbxKrnl_KernelThunkTable[379];

View File

@ -424,6 +424,27 @@ XBSYSAPI EXPORTNUM(125) xboxkrnl::ULONGLONG NTAPI xboxkrnl::KeQueryInterruptTime
RETURN(InterruptTime);
}
// Xbox Performance Counter Frequency = 337F98 = ACPI timer frequency (3.375000 Mhz)
#define XBOX_PERFORMANCE_FREQUENCY 3375000
LARGE_INTEGER NativePerformanceCounter = { 0 };
LARGE_INTEGER NativePerformanceFrequency = { 0 };
double NativeToXbox_FactorForPerformanceFrequency;
CXBXKRNL_API void CxbxInitPerformanceCounters()
{
//BootTickCount = GetTickCount();
// Measure current host performance counter and frequency
QueryPerformanceCounter(&NativePerformanceCounter);
QueryPerformanceFrequency(&NativePerformanceFrequency);
// TODO : If anything like speed-stepping influences this, prevent or fix it here
// Calculate the host-to-xbox performance frequency factor,
// used the return Xbox-like results in KeQueryPerformanceCounter:
NativeToXbox_FactorForPerformanceFrequency = (double)XBOX_PERFORMANCE_FREQUENCY / NativePerformanceFrequency.QuadPart;
}
// ******************************************************************
// * 0x007E - KeQueryPerformanceCounter()
// ******************************************************************
@ -431,11 +452,19 @@ XBSYSAPI EXPORTNUM(126) xboxkrnl::ULONGLONG NTAPI xboxkrnl::KeQueryPerformanceCo
{
LOG_FUNC();
::LARGE_INTEGER Counter;
::LARGE_INTEGER PerformanceCounter;
QueryPerformanceCounter(&Counter);
// Dxbx note : Xbox actually uses the RDTSC machine code instruction for this,
// and we we're bound to a single core, so we could do that too, but on Windows
// rdtsc is not a very stable counter, so instead, we'll use the native PeformanceCounter :
QueryPerformanceCounter(&PerformanceCounter);
RETURN(Counter.QuadPart);
// Re-base the performance counter to increase accuracy of the following conversion :
PerformanceCounter.QuadPart -= NativePerformanceCounter.QuadPart;
// We appy a conversion factor here, to fake Xbox1-like increment-speed behaviour :
PerformanceCounter.QuadPart = (ULONGLONG)(NativeToXbox_FactorForPerformanceFrequency * PerformanceCounter.QuadPart);
RETURN(PerformanceCounter.QuadPart);
}
// ******************************************************************
@ -445,12 +474,11 @@ XBSYSAPI EXPORTNUM(127) xboxkrnl::ULONGLONG NTAPI xboxkrnl::KeQueryPerformanceFr
{
LOG_FUNC();
// Xbox Performance Counter Frequency := 337F98h
::LARGE_INTEGER Frequency;
// Dxbx note : We return the real Xbox1 frequency here,
// to make subsequent calculations behave the same as on the real Xbox1 :
ULONGLONG ret = XBOX_PERFORMANCE_FREQUENCY;
QueryPerformanceFrequency(&Frequency);
RETURN(Frequency.QuadPart);
RETURN(ret);
}
// ******************************************************************