Fixing GetTickCount.
There's likely a better way to do this (on demand), but this works for now.
This commit is contained in:
parent
3454d1bdf5
commit
cfcd6118c2
|
@ -24,7 +24,8 @@ namespace xe {
|
||||||
namespace kernel {
|
namespace kernel {
|
||||||
|
|
||||||
XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state)
|
XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state)
|
||||||
: XKernelModule(kernel_state, "xe:\\xboxkrnl.exe") {
|
: XKernelModule(kernel_state, "xe:\\xboxkrnl.exe"),
|
||||||
|
timestamp_timer_(nullptr) {
|
||||||
// Build the export table used for resolution.
|
// Build the export table used for resolution.
|
||||||
#include "xenia/kernel/util/export_table_pre.inc"
|
#include "xenia/kernel/util/export_table_pre.inc"
|
||||||
static KernelExport xboxkrnl_export_table[] = {
|
static KernelExport xboxkrnl_export_table[] = {
|
||||||
|
@ -72,11 +73,13 @@ XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state)
|
||||||
// 0x00000000, 0x06, 0x00, 0x00, 0x00, 0x00000000, 0x0000, 0x0000
|
// 0x00000000, 0x06, 0x00, 0x00, 0x00, 0x00000000, 0x0000, 0x0000
|
||||||
// Games seem to check if bit 26 (0x20) is set, which at least for xbox1
|
// Games seem to check if bit 26 (0x20) is set, which at least for xbox1
|
||||||
// was whether an HDD was present. Not sure what the other flags are.
|
// was whether an HDD was present. Not sure what the other flags are.
|
||||||
|
//
|
||||||
|
// aomega08 says the value is 0x02000817, bit 27: debug mode on.
|
||||||
|
// When that is set, though, allocs crash in weird ways.
|
||||||
uint32_t pXboxHardwareInfo = (uint32_t)memory_->HeapAlloc(0, 16, 0);
|
uint32_t pXboxHardwareInfo = (uint32_t)memory_->HeapAlloc(0, 16, 0);
|
||||||
export_resolver_->SetVariableMapping(
|
export_resolver_->SetVariableMapping(
|
||||||
"xboxkrnl.exe", ordinals::XboxHardwareInfo, pXboxHardwareInfo);
|
"xboxkrnl.exe", ordinals::XboxHardwareInfo, pXboxHardwareInfo);
|
||||||
poly::store_and_swap<uint32_t>(mem + pXboxHardwareInfo + 0,
|
poly::store_and_swap<uint32_t>(mem + pXboxHardwareInfo + 0, 0); // flags
|
||||||
0x00000000); // flags
|
|
||||||
poly::store_and_swap<uint8_t>(mem + pXboxHardwareInfo + 4,
|
poly::store_and_swap<uint8_t>(mem + pXboxHardwareInfo + 4,
|
||||||
0x06); // cpu count
|
0x06); // cpu count
|
||||||
// Remaining 11b are zeroes?
|
// Remaining 11b are zeroes?
|
||||||
|
@ -120,18 +123,34 @@ XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state)
|
||||||
poly::store_and_swap<uint16_t>(mem + pXboxKrnlVersion + 0, 2);
|
poly::store_and_swap<uint16_t>(mem + pXboxKrnlVersion + 0, 2);
|
||||||
poly::store_and_swap<uint16_t>(mem + pXboxKrnlVersion + 2, 0xFFFF);
|
poly::store_and_swap<uint16_t>(mem + pXboxKrnlVersion + 2, 0xFFFF);
|
||||||
poly::store_and_swap<uint16_t>(mem + pXboxKrnlVersion + 4, 0xFFFF);
|
poly::store_and_swap<uint16_t>(mem + pXboxKrnlVersion + 4, 0xFFFF);
|
||||||
poly::store_and_swap<uint16_t>(mem + pXboxKrnlVersion + 6, 0xFFFF);
|
poly::store_and_swap<uint8_t>(mem + pXboxKrnlVersion + 6, 0x80);
|
||||||
|
poly::store_and_swap<uint8_t>(mem + pXboxKrnlVersion + 7, 0x00);
|
||||||
|
|
||||||
// KeTimeStampBundle (ad)
|
// KeTimeStampBundle (ad)
|
||||||
|
// This must be updated during execution, at 1ms intevals.
|
||||||
|
// We setup a system timer here to do that.
|
||||||
uint32_t pKeTimeStampBundle = (uint32_t)memory_->HeapAlloc(0, 24, 0);
|
uint32_t pKeTimeStampBundle = (uint32_t)memory_->HeapAlloc(0, 24, 0);
|
||||||
export_resolver_->SetVariableMapping(
|
export_resolver_->SetVariableMapping(
|
||||||
"xboxkrnl.exe", ordinals::KeTimeStampBundle, pKeTimeStampBundle);
|
"xboxkrnl.exe", ordinals::KeTimeStampBundle, pKeTimeStampBundle);
|
||||||
poly::store_and_swap<uint64_t>(mem + pKeTimeStampBundle + 0, 0);
|
poly::store_and_swap<uint64_t>(mem + pKeTimeStampBundle + 0, 0);
|
||||||
poly::store_and_swap<uint64_t>(mem + pKeTimeStampBundle + 8, 0);
|
poly::store_and_swap<uint64_t>(mem + pKeTimeStampBundle + 8, 0);
|
||||||
poly::store_and_swap<uint32_t>(mem + pKeTimeStampBundle + 12, 0);
|
poly::store_and_swap<uint32_t>(mem + pKeTimeStampBundle + 16, GetTickCount());
|
||||||
|
poly::store_and_swap<uint32_t>(mem + pKeTimeStampBundle + 20, 0);
|
||||||
|
CreateTimerQueueTimer(×tamp_timer_, nullptr,
|
||||||
|
[](PVOID param, BOOLEAN timer_or_wait_fired) {
|
||||||
|
auto timestamp_bundle =
|
||||||
|
reinterpret_cast<uint8_t*>(param);
|
||||||
|
poly::store_and_swap<uint32_t>(timestamp_bundle + 16,
|
||||||
|
GetTickCount());
|
||||||
|
},
|
||||||
|
mem + pKeTimeStampBundle, 0,
|
||||||
|
1, // 1ms
|
||||||
|
WT_EXECUTEINTIMERTHREAD);
|
||||||
}
|
}
|
||||||
|
|
||||||
XboxkrnlModule::~XboxkrnlModule() {}
|
XboxkrnlModule::~XboxkrnlModule() {
|
||||||
|
DeleteTimerQueueTimer(nullptr, timestamp_timer_, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
int XboxkrnlModule::LaunchModule(const char* path) {
|
int XboxkrnlModule::LaunchModule(const char* path) {
|
||||||
// Create and register the module. We keep it local to this function and
|
// Create and register the module. We keep it local to this function and
|
||||||
|
|
|
@ -31,6 +31,7 @@ class XboxkrnlModule : public XKernelModule {
|
||||||
int LaunchModule(const char* path);
|
int LaunchModule(const char* path);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
HANDLE timestamp_timer_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace kernel
|
} // namespace kernel
|
||||||
|
|
|
@ -277,6 +277,8 @@ SHIM_CALL KeQueryPerformanceFrequency_shim(PPCContext* ppc_state,
|
||||||
// XELOGD(
|
// XELOGD(
|
||||||
// "KeQueryPerformanceFrequency()");
|
// "KeQueryPerformanceFrequency()");
|
||||||
|
|
||||||
|
// TODO(benvanik): return fixed 50000000?
|
||||||
|
|
||||||
uint64_t result = 0;
|
uint64_t result = 0;
|
||||||
LARGE_INTEGER frequency;
|
LARGE_INTEGER frequency;
|
||||||
if (QueryPerformanceFrequency(&frequency)) {
|
if (QueryPerformanceFrequency(&frequency)) {
|
||||||
|
|
Loading…
Reference in New Issue