diff --git a/src/xenia/cpu/backend/x64/x64_tracers.cc b/src/xenia/cpu/backend/x64/x64_tracers.cc index 404f4ecac..325589bad 100644 --- a/src/xenia/cpu/backend/x64/x64_tracers.cc +++ b/src/xenia/cpu/backend/x64/x64_tracers.cc @@ -30,7 +30,7 @@ namespace x64 { bool trace_enabled = true; #define THREAD_MATCH \ - (!TARGET_THREAD || thread_state->thread_id() == TARGET_THREAD) + (!TARGET_THREAD || ppc_context->thread_id == TARGET_THREAD) #define IFLUSH() #define IPRINT(s) \ if (trace_enabled && THREAD_MATCH) \ @@ -52,41 +52,41 @@ uint32_t GetTracingMode() { } void TraceString(void* raw_context, const char* str) { - auto thread_state = *reinterpret_cast(raw_context); + auto ppc_context = reinterpret_cast(raw_context); IPRINT(str); IFLUSH(); } void TraceContextLoadI8(void* raw_context, uint64_t offset, uint8_t value) { - auto thread_state = *reinterpret_cast(raw_context); + auto ppc_context = reinterpret_cast(raw_context); DPRINT("{} ({:X}) = ctx i8 +{}\n", (int8_t)value, value, offset); } void TraceContextLoadI16(void* raw_context, uint64_t offset, uint16_t value) { - auto thread_state = *reinterpret_cast(raw_context); + auto ppc_context = reinterpret_cast(raw_context); DPRINT("{} ({:X}) = ctx i16 +{}\n", (int16_t)value, value, offset); } void TraceContextLoadI32(void* raw_context, uint64_t offset, uint32_t value) { - auto thread_state = *reinterpret_cast(raw_context); + auto ppc_context = reinterpret_cast(raw_context); DPRINT("{} ({:X}) = ctx i32 +{}\n", (int32_t)value, value, offset); } void TraceContextLoadI64(void* raw_context, uint64_t offset, uint64_t value) { - auto thread_state = *reinterpret_cast(raw_context); + auto ppc_context = reinterpret_cast(raw_context); DPRINT("{} ({:X}) = ctx i64 +{}\n", (int64_t)value, value, offset); } void TraceContextLoadF32(void* raw_context, uint64_t offset, __m128 value) { - auto thread_state = *reinterpret_cast(raw_context); + auto ppc_context = reinterpret_cast(raw_context); DPRINT("{} ({:X}) = ctx f32 +{}\n", xe::m128_f32<0>(value), xe::m128_i32<0>(value), offset); } void TraceContextLoadF64(void* raw_context, uint64_t offset, const double* value) { - auto thread_state = *reinterpret_cast(raw_context); + auto ppc_context = reinterpret_cast(raw_context); auto v = _mm_loadu_pd(value); DPRINT("{} ({:X}) = ctx f64 +{}\n", xe::m128_f64<0>(v), xe::m128_i64<0>(v), offset); } void TraceContextLoadV128(void* raw_context, uint64_t offset, __m128 value) { - auto thread_state = *reinterpret_cast(raw_context); + auto ppc_context = reinterpret_cast(raw_context); DPRINT("[{}, {}, {}, {}] [{:08X}, {:08X}, {:08X}, {:08X}] = ctx v128 +{}\n", xe::m128_f32<0>(value), xe::m128_f32<1>(value), xe::m128_f32<2>(value), xe::m128_f32<3>(value), xe::m128_i32<0>(value), xe::m128_i32<1>(value), @@ -94,35 +94,35 @@ void TraceContextLoadV128(void* raw_context, uint64_t offset, __m128 value) { } void TraceContextStoreI8(void* raw_context, uint64_t offset, uint8_t value) { - auto thread_state = *reinterpret_cast(raw_context); + auto ppc_context = reinterpret_cast(raw_context); DPRINT("ctx i8 +{} = {} ({:X})\n", offset, (int8_t)value, value); } void TraceContextStoreI16(void* raw_context, uint64_t offset, uint16_t value) { - auto thread_state = *reinterpret_cast(raw_context); + auto ppc_context = reinterpret_cast(raw_context); DPRINT("ctx i16 +{} = {} ({:X})\n", offset, (int16_t)value, value); } void TraceContextStoreI32(void* raw_context, uint64_t offset, uint32_t value) { - auto thread_state = *reinterpret_cast(raw_context); + auto ppc_context = reinterpret_cast(raw_context); DPRINT("ctx i32 +{} = {} ({:X})\n", offset, (int32_t)value, value); } void TraceContextStoreI64(void* raw_context, uint64_t offset, uint64_t value) { - auto thread_state = *reinterpret_cast(raw_context); + auto ppc_context = reinterpret_cast(raw_context); DPRINT("ctx i64 +{} = {} ({:X})\n", offset, (int64_t)value, value); } void TraceContextStoreF32(void* raw_context, uint64_t offset, __m128 value) { - auto thread_state = *reinterpret_cast(raw_context); + auto ppc_context = reinterpret_cast(raw_context); DPRINT("ctx f32 +{} = {} ({:X})\n", offset, xe::m128_f32<0>(value), xe::m128_i32<0>(value)); } void TraceContextStoreF64(void* raw_context, uint64_t offset, const double* value) { - auto thread_state = *reinterpret_cast(raw_context); + auto ppc_context = reinterpret_cast(raw_context); auto v = _mm_loadu_pd(value); DPRINT("ctx f64 +{} = {} ({:X})\n", offset, xe::m128_f64<0>(v), xe::m128_i64<0>(v)); } void TraceContextStoreV128(void* raw_context, uint64_t offset, __m128 value) { - auto thread_state = *reinterpret_cast(raw_context); + auto ppc_context = reinterpret_cast(raw_context); DPRINT("ctx v128 +{} = [{}, {}, {}, {}] [{:08X}, {:08X}, {:08X}, {:08X}]\n", offset, xe::m128_f32<0>(value), xe::m128_f32<1>(value), xe::m128_f32<2>(value), xe::m128_f32<3>(value), xe::m128_i32<0>(value), @@ -131,33 +131,33 @@ void TraceContextStoreV128(void* raw_context, uint64_t offset, __m128 value) { } void TraceMemoryLoadI8(void* raw_context, uint32_t address, uint8_t value) { - auto thread_state = *reinterpret_cast(raw_context); + auto ppc_context = reinterpret_cast(raw_context); DPRINT("{} ({:X}) = load.i8 {:08X}\n", (int8_t)value, value, address); } void TraceMemoryLoadI16(void* raw_context, uint32_t address, uint16_t value) { - auto thread_state = *reinterpret_cast(raw_context); + auto ppc_context = reinterpret_cast(raw_context); DPRINT("{} ({:X}) = load.i16 {:08X}\n", (int16_t)value, value, address); } void TraceMemoryLoadI32(void* raw_context, uint32_t address, uint32_t value) { - auto thread_state = *reinterpret_cast(raw_context); + auto ppc_context = reinterpret_cast(raw_context); DPRINT("{} ({:X}) = load.i32 {:08X}\n", (int32_t)value, value, address); } void TraceMemoryLoadI64(void* raw_context, uint32_t address, uint64_t value) { - auto thread_state = *reinterpret_cast(raw_context); + auto ppc_context = reinterpret_cast(raw_context); DPRINT("{} ({:X}) = load.i64 {:08X}\n", (int64_t)value, value, address); } void TraceMemoryLoadF32(void* raw_context, uint32_t address, __m128 value) { - auto thread_state = *reinterpret_cast(raw_context); + auto ppc_context = reinterpret_cast(raw_context); DPRINT("{} ({:X}) = load.f32 {:08X}\n", xe::m128_f32<0>(value), xe::m128_i32<0>(value), address); } void TraceMemoryLoadF64(void* raw_context, uint32_t address, __m128 value) { - auto thread_state = *reinterpret_cast(raw_context); + auto ppc_context = reinterpret_cast(raw_context); DPRINT("{} ({:X}) = load.f64 {:08X}\n", xe::m128_f64<0>(value), xe::m128_i64<0>(value), address); } void TraceMemoryLoadV128(void* raw_context, uint32_t address, __m128 value) { - auto thread_state = *reinterpret_cast(raw_context); + auto ppc_context = reinterpret_cast(raw_context); DPRINT( "[{}, {}, {}, {}] [{:08X}, {:08X}, {:08X}, {:08X}] = load.v128 {:08X}\n", xe::m128_f32<0>(value), xe::m128_f32<1>(value), xe::m128_f32<2>(value), @@ -166,33 +166,33 @@ void TraceMemoryLoadV128(void* raw_context, uint32_t address, __m128 value) { } void TraceMemoryStoreI8(void* raw_context, uint32_t address, uint8_t value) { - auto thread_state = *reinterpret_cast(raw_context); + auto ppc_context = reinterpret_cast(raw_context); DPRINT("store.i8 {:08X} = {} ({:X})\n", address, (int8_t)value, value); } void TraceMemoryStoreI16(void* raw_context, uint32_t address, uint16_t value) { - auto thread_state = *reinterpret_cast(raw_context); + auto ppc_context = reinterpret_cast(raw_context); DPRINT("store.i16 {:08X} = {} ({:X})\n", address, (int16_t)value, value); } void TraceMemoryStoreI32(void* raw_context, uint32_t address, uint32_t value) { - auto thread_state = *reinterpret_cast(raw_context); + auto ppc_context = reinterpret_cast(raw_context); DPRINT("store.i32 {:08X} = {} ({:X})\n", address, (int32_t)value, value); } void TraceMemoryStoreI64(void* raw_context, uint32_t address, uint64_t value) { - auto thread_state = *reinterpret_cast(raw_context); + auto ppc_context = reinterpret_cast(raw_context); DPRINT("store.i64 {:08X} = {} ({:X})\n", address, (int64_t)value, value); } void TraceMemoryStoreF32(void* raw_context, uint32_t address, __m128 value) { - auto thread_state = *reinterpret_cast(raw_context); + auto ppc_context = reinterpret_cast(raw_context); DPRINT("store.f32 {:08X} = {} ({:X})\n", address, xe::m128_f32<0>(value), xe::m128_i32<0>(value)); } void TraceMemoryStoreF64(void* raw_context, uint32_t address, __m128 value) { - auto thread_state = *reinterpret_cast(raw_context); + auto ppc_context = reinterpret_cast(raw_context); DPRINT("store.f64 {:08X} = {} ({:X})\n", address, xe::m128_f64<0>(value), xe::m128_i64<0>(value)); } void TraceMemoryStoreV128(void* raw_context, uint32_t address, __m128 value) { - auto thread_state = *reinterpret_cast(raw_context); + auto ppc_context = reinterpret_cast(raw_context); DPRINT( "store.v128 {:08X} = [{}, {}, {}, {}] [{:08X}, {:08X}, {:08X}, {:08X}]\n", address, xe::m128_f32<0>(value), xe::m128_f32<1>(value), @@ -202,7 +202,7 @@ void TraceMemoryStoreV128(void* raw_context, uint32_t address, __m128 value) { void TraceMemset(void* raw_context, uint32_t address, uint8_t value, uint32_t length) { - auto thread_state = *reinterpret_cast(raw_context); + auto ppc_context = reinterpret_cast(raw_context); DPRINT("memset {:08X}-{:08X} ({}) = {:02X}", address, address + length, length, value); } diff --git a/src/xenia/kernel/kernel_module.cc b/src/xenia/kernel/kernel_module.cc index ebf0d64ba..b8bfd6ce4 100644 --- a/src/xenia/kernel/kernel_module.cc +++ b/src/xenia/kernel/kernel_module.cc @@ -21,7 +21,7 @@ namespace kernel { KernelModule::KernelModule(KernelState* kernel_state, const std::string_view path) - : XModule(kernel_state, ModuleType::kKernelModule) { + : XModule(kernel_state, ModuleType::kKernelModule, true) { emulator_ = kernel_state->emulator(); memory_ = emulator_->memory(); export_resolver_ = kernel_state->emulator()->export_resolver(); @@ -29,9 +29,6 @@ KernelModule::KernelModule(KernelState* kernel_state, path_ = path; name_ = utf8::find_base_name_from_guest_path(path); - // Persist this object through reloads. - host_object_ = true; - // HACK: Allocates memory where xboxkrnl.exe would be! // TODO: Need to free this memory when necessary. auto heap = memory()->LookupHeap(0x80040000); diff --git a/src/xenia/kernel/util/object_table.cc b/src/xenia/kernel/util/object_table.cc index d6efa32c4..a95320710 100644 --- a/src/xenia/kernel/util/object_table.cc +++ b/src/xenia/kernel/util/object_table.cc @@ -35,26 +35,37 @@ void ObjectTable::Reset() { entry.object->Release(); } } + for (uint32_t n = 0; n < host_table_capacity_; n++) { + ObjectTableEntry& entry = host_table_[n]; + if (entry.object) { + entry.object->Release(); + } + } table_capacity_ = 0; + host_table_capacity_ = 0; last_free_entry_ = 0; + last_free_host_entry_ = 0; free(table_); table_ = nullptr; + free(host_table_); + host_table_ = nullptr; } -X_STATUS ObjectTable::FindFreeSlot(uint32_t* out_slot) { +X_STATUS ObjectTable::FindFreeSlot(uint32_t* out_slot, bool host) { // Find a free slot. - uint32_t slot = last_free_entry_; + uint32_t slot = host ? last_free_host_entry_ : last_free_entry_; + uint32_t capacity = host ? host_table_capacity_ : table_capacity_; uint32_t scan_count = 0; - while (scan_count < table_capacity_) { - ObjectTableEntry& entry = table_[slot]; + while (scan_count < capacity) { + ObjectTableEntry& entry = host ? host_table_[slot] : table_[slot]; if (!entry.object) { *out_slot = slot; return X_STATUS_SUCCESS; } scan_count++; - slot = (slot + 1) % table_capacity_; - if (slot == 0) { + slot = (slot + 1) % capacity; + if (slot == 0 && host) { // Never allow 0 handles. scan_count++; slot++; @@ -62,23 +73,24 @@ X_STATUS ObjectTable::FindFreeSlot(uint32_t* out_slot) { } // Table out of slots, expand. - uint32_t new_table_capacity = std::max(16 * 1024u, table_capacity_ * 2); - if (!Resize(new_table_capacity)) { + uint32_t new_table_capacity = std::max(16 * 1024u, capacity * 2); + if (!Resize(new_table_capacity, host)) { return X_STATUS_NO_MEMORY; } - // Never allow 0 handles. - slot = ++last_free_entry_; + // Never allow 0 handles on host. + slot = host ? ++last_free_host_entry_ : last_free_entry_++; *out_slot = slot; return X_STATUS_SUCCESS; } -bool ObjectTable::Resize(uint32_t new_capacity) { +bool ObjectTable::Resize(uint32_t new_capacity, bool host) { + uint32_t capacity = host ? host_table_capacity_ : table_capacity_; uint32_t new_size = new_capacity * sizeof(ObjectTableEntry); - uint32_t old_size = table_capacity_ * sizeof(ObjectTableEntry); - auto new_table = - reinterpret_cast(realloc(table_, new_size)); + uint32_t old_size = capacity * sizeof(ObjectTableEntry); + auto new_table = reinterpret_cast( + realloc(host ? host_table_ : table_, new_size)); if (!new_table) { return false; } @@ -89,9 +101,15 @@ bool ObjectTable::Resize(uint32_t new_capacity) { new_size - old_size); } - last_free_entry_ = table_capacity_; - table_capacity_ = new_capacity; - table_ = new_table; + if (host) { + last_free_host_entry_ = capacity; + host_table_capacity_ = new_capacity; + host_table_ = new_table; + } else { + last_free_entry_ = capacity; + table_capacity_ = new_capacity; + table_ = new_table; + } return true; } @@ -105,14 +123,16 @@ X_STATUS ObjectTable::AddHandle(XObject* object, X_HANDLE* out_handle) { // Find a free slot. uint32_t slot = 0; - result = FindFreeSlot(&slot); + bool host_object = object->is_host_object(); + result = FindFreeSlot(&slot, host_object); // Stash. if (XSUCCEEDED(result)) { - ObjectTableEntry& entry = table_[slot]; + ObjectTableEntry& entry = host_object ? host_table_[slot] : table_[slot]; entry.object = object; entry.handle_ref_count = 1; - handle = XObject::kHandleBase + (slot << 2); + handle = slot << 2; + if (!host_object) handle += XObject::kHandleBase; object->handles().push_back(handle); // Retain so long as the object is in the table. @@ -222,6 +242,14 @@ std::vector> ObjectTable::GetAllObjects() { auto lock = global_critical_region_.Acquire(); std::vector> results; + for (uint32_t slot = 0; slot < host_table_capacity_; slot++) { + auto& entry = host_table_[slot]; + if (entry.object && std::find(results.begin(), results.end(), + entry.object) == results.end()) { + entry.object->Retain(); + results.push_back(object_ref(entry.object)); + } + } for (uint32_t slot = 0; slot < table_capacity_; slot++) { auto& entry = table_[slot]; if (entry.object && std::find(results.begin(), results.end(), @@ -238,7 +266,7 @@ void ObjectTable::PurgeAllObjects() { auto lock = global_critical_region_.Acquire(); for (uint32_t slot = 0; slot < table_capacity_; slot++) { auto& entry = table_[slot]; - if (entry.object && !entry.object->is_host_object()) { + if (entry.object) { entry.handle_ref_count = 0; entry.object->Release(); @@ -259,8 +287,13 @@ ObjectTable::ObjectTableEntry* ObjectTable::LookupTableInLock(X_HANDLE handle) { } // Lower 2 bits are ignored. - uint32_t slot = GetHandleSlot(handle); - if (slot <= table_capacity_) { + bool host = (handle < XObject::kHandleBase); + uint32_t slot = GetHandleSlot(handle, host); + if (host) { + if (slot <= host_table_capacity_) { + return &host_table_[slot]; + } + } else if (slot <= table_capacity_) { return &table_[slot]; } @@ -288,10 +321,18 @@ XObject* ObjectTable::LookupObject(X_HANDLE handle, bool already_locked) { } // Lower 2 bits are ignored. - uint32_t slot = GetHandleSlot(handle); + bool host = (handle < XObject::kHandleBase); + uint32_t slot = GetHandleSlot(handle, host); // Verify slot. - if (slot < table_capacity_) { + if (host) { + if (slot < host_table_capacity_) { + ObjectTableEntry& entry = host_table_[slot]; + if (entry.object) { + object = entry.object; + } + } + } else if (slot < table_capacity_) { ObjectTableEntry& entry = table_[slot]; if (entry.object) { object = entry.object; @@ -313,6 +354,15 @@ XObject* ObjectTable::LookupObject(X_HANDLE handle, bool already_locked) { void ObjectTable::GetObjectsByType(XObject::Type type, std::vector>* results) { auto global_lock = global_critical_region_.Acquire(); + for (uint32_t slot = 0; slot < host_table_capacity_; ++slot) { + auto& entry = host_table_[slot]; + if (entry.object) { + if (entry.object->type() == type) { + entry.object->Retain(); + results->push_back(object_ref(entry.object)); + } + } + } for (uint32_t slot = 0; slot < table_capacity_; ++slot) { auto& entry = table_[slot]; if (entry.object) { @@ -377,6 +427,12 @@ X_STATUS ObjectTable::GetObjectByName(const std::string_view name, } bool ObjectTable::Save(ByteStream* stream) { + stream->Write(host_table_capacity_); + for (uint32_t i = 0; i < host_table_capacity_; i++) { + auto& entry = host_table_[i]; + stream->Write(entry.handle_ref_count); + } + stream->Write(table_capacity_); for (uint32_t i = 0; i < table_capacity_; i++) { auto& entry = table_[i]; @@ -387,7 +443,14 @@ bool ObjectTable::Save(ByteStream* stream) { } bool ObjectTable::Restore(ByteStream* stream) { - Resize(stream->Read()); + Resize(stream->Read(), true); + for (uint32_t i = 0; i < host_table_capacity_; i++) { + auto& entry = host_table_[i]; + // entry.object = nullptr; + entry.handle_ref_count = stream->Read(); + } + + Resize(stream->Read(), false); for (uint32_t i = 0; i < table_capacity_; i++) { auto& entry = table_[i]; // entry.object = nullptr; @@ -398,11 +461,13 @@ bool ObjectTable::Restore(ByteStream* stream) { } X_STATUS ObjectTable::RestoreHandle(X_HANDLE handle, XObject* object) { - uint32_t slot = GetHandleSlot(handle); - assert_true(table_capacity_ >= slot); + bool host = (handle < XObject::kHandleBase); + uint32_t slot = GetHandleSlot(handle, host); + uint32_t capacity = host ? host_table_capacity_ : table_capacity_; + assert_true(capacity >= slot); - if (table_capacity_ >= slot) { - auto& entry = table_[slot]; + if (capacity >= slot) { + auto& entry = host ? host_table_[slot] : table_[slot]; entry.object = object; object->Retain(); } diff --git a/src/xenia/kernel/util/object_table.h b/src/xenia/kernel/util/object_table.h index aced0ea60..040d07d4e 100644 --- a/src/xenia/kernel/util/object_table.h +++ b/src/xenia/kernel/util/object_table.h @@ -49,10 +49,10 @@ class ObjectTable { X_STATUS RestoreHandle(X_HANDLE handle, XObject* object); template object_ref LookupObject(X_HANDLE handle, bool already_locked = false) { - auto object = LookupObject(handle, already_locked); if (T::kObjectType == XObject::Type::Socket) { - object = LookupObject((handle | 0xF8000000), false); + handle |= XObject::kHandleBase; } + auto object = LookupObject(handle, already_locked); if (object) { assert_true(object->type() == T::kObjectType); } @@ -95,16 +95,20 @@ class ObjectTable { std::vector>* results); X_HANDLE TranslateHandle(X_HANDLE handle); - static constexpr uint32_t GetHandleSlot(X_HANDLE handle) { - return (handle - XObject::kHandleBase) >> 2; + static constexpr uint32_t GetHandleSlot(X_HANDLE handle, bool host) { + if (!host) handle -= XObject::kHandleBase; + return handle >> 2; } - X_STATUS FindFreeSlot(uint32_t* out_slot); - bool Resize(uint32_t new_capacity); + X_STATUS FindFreeSlot(uint32_t* out_slot, bool host); + bool Resize(uint32_t new_capacity, bool host); xe::global_critical_region global_critical_region_; uint32_t table_capacity_ = 0; + uint32_t host_table_capacity_ = 0; ObjectTableEntry* table_ = nullptr; + ObjectTableEntry* host_table_ = nullptr; uint32_t last_free_entry_ = 0; + uint32_t last_free_host_entry_ = 0; std::unordered_map name_table_; }; diff --git a/src/xenia/kernel/xam/xam_info.cc b/src/xenia/kernel/xam/xam_info.cc index 9c6dd0611..ec4acc082 100644 --- a/src/xenia/kernel/xam/xam_info.cc +++ b/src/xenia/kernel/xam/xam_info.cc @@ -26,6 +26,7 @@ #include "third_party/fmt/include/fmt/format.h" DEFINE_int32(avpack, 8, "Video modes", "Video"); +DECLARE_int32(user_country); DECLARE_int32(user_language); namespace xe { @@ -206,7 +207,25 @@ dword_result_t XGetAVPack_entry() { } DECLARE_XAM_EXPORT1(XGetAVPack, kNone, kStub); -uint32_t xeXGetGameRegion() { return 0xFFFFu; } +uint32_t xeXGetGameRegion() { + static uint32_t const table[] = { + 0xFFFFu, 0x03FFu, 0x02FEu, 0x02FEu, 0x03FFu, 0x02FEu, 0x0201u, 0x03FFu, + 0x02FEu, 0x02FEu, 0x03FFu, 0x03FFu, 0x03FFu, 0x03FFu, 0x02FEu, 0x03FFu, + 0x00FFu, 0xFFFFu, 0x02FEu, 0x03FFu, 0x0102u, 0x03FFu, 0x03FFu, 0x02FEu, + 0x02FEu, 0x02FEu, 0x03FFu, 0x03FFu, 0x03FFu, 0x02FEu, 0x03FFu, 0x02FEu, + 0x02FEu, 0x02FEu, 0x02FEu, 0x02FEu, 0x02FEu, 0x02FEu, 0x03FFu, 0x03FFu, + 0x03FFu, 0x02FEu, 0x02FEu, 0x03FFu, 0x02FEu, 0x02FEu, 0x03FFu, 0x03FFu, + 0x03FFu, 0x02FEu, 0x02FEu, 0x03FFu, 0x03FFu, 0x0101u, 0x03FFu, 0x03FFu, + 0x03FFu, 0x03FFu, 0x03FFu, 0x03FFu, 0x02FEu, 0x02FEu, 0x02FEu, 0x02FEu, + 0x03FFu, 0x03FFu, 0x02FEu, 0x02FEu, 0x03FFu, 0x0102u, 0x03FFu, 0x00FFu, + 0x03FFu, 0x03FFu, 0x02FEu, 0x02FEu, 0x0201u, 0x03FFu, 0x03FFu, 0x03FFu, + 0x03FFu, 0x03FFu, 0x02FEu, 0x03FFu, 0x02FEu, 0x03FFu, 0x03FFu, 0x02FEu, + 0x02FEu, 0x03FFu, 0x02FEu, 0x03FFu, 0x02FEu, 0x02FEu, 0xFFFFu, 0x03FFu, + 0x03FFu, 0x03FFu, 0x03FFu, 0x02FEu, 0x03FFu, 0x03FFu, 0x02FEu, 0x00FFu, + 0x03FFu, 0x03FFu, 0x03FFu, 0x03FFu, 0x03FFu, 0x03FFu, 0x03FFu}; + auto country = static_cast(cvars::user_country); + return country < xe::countof(table) ? table[country] : 0xFFFFu; +} dword_result_t XGetGameRegion_entry() { return xeXGetGameRegion(); } DECLARE_XAM_EXPORT1(XGetGameRegion, kNone, kStub); diff --git a/src/xenia/kernel/xmodule.cc b/src/xenia/kernel/xmodule.cc index 96880958c..665e5a43e 100644 --- a/src/xenia/kernel/xmodule.cc +++ b/src/xenia/kernel/xmodule.cc @@ -19,8 +19,9 @@ namespace xe { namespace kernel { -XModule::XModule(KernelState* kernel_state, ModuleType module_type) - : XObject(kernel_state, kObjectType), +XModule::XModule(KernelState* kernel_state, ModuleType module_type, + bool host_object) + : XObject(kernel_state, kObjectType, host_object), module_type_(module_type), processor_module_(nullptr), hmodule_ptr_(0) { diff --git a/src/xenia/kernel/xmodule.h b/src/xenia/kernel/xmodule.h index 0a937a73b..28e860da3 100644 --- a/src/xenia/kernel/xmodule.h +++ b/src/xenia/kernel/xmodule.h @@ -61,7 +61,8 @@ class XModule : public XObject { static const XObject::Type kObjectType = XObject::Type::Module; - XModule(KernelState* kernel_state, ModuleType module_type); + XModule(KernelState* kernel_state, ModuleType module_type, + bool host_object = false); virtual ~XModule(); ModuleType module_type() const { return module_type_; } diff --git a/src/xenia/kernel/xobject.cc b/src/xenia/kernel/xobject.cc index bd7374b74..cee06c07a 100644 --- a/src/xenia/kernel/xobject.cc +++ b/src/xenia/kernel/xobject.cc @@ -34,12 +34,13 @@ XObject::XObject(Type type) handles_.reserve(10); } -XObject::XObject(KernelState* kernel_state, Type type) +XObject::XObject(KernelState* kernel_state, Type type, bool host_object) : kernel_state_(kernel_state), type_(type), pointer_ref_count_(1), guest_object_ptr_(0), - allocated_guest_object_(false) { + allocated_guest_object_(false), + host_object_(host_object) { handles_.reserve(10); // TODO: Assert kernel_state != nullptr in this constructor. diff --git a/src/xenia/kernel/xobject.h b/src/xenia/kernel/xobject.h index df067b55d..1647fa193 100644 --- a/src/xenia/kernel/xobject.h +++ b/src/xenia/kernel/xobject.h @@ -136,7 +136,7 @@ class XObject { }; XObject(Type type); - XObject(KernelState* kernel_state, Type type); + XObject(KernelState* kernel_state, Type type, bool host_object = false); virtual ~XObject(); Emulator* emulator() const; diff --git a/src/xenia/kernel/xthread.cc b/src/xenia/kernel/xthread.cc index df5991d09..63dfc0bd8 100644 --- a/src/xenia/kernel/xthread.cc +++ b/src/xenia/kernel/xthread.cc @@ -60,7 +60,7 @@ XThread::XThread(KernelState* kernel_state, uint32_t stack_size, uint32_t xapi_thread_startup, uint32_t start_address, uint32_t start_context, uint32_t creation_flags, bool guest_thread, bool main_thread) - : XObject(kernel_state, kObjectType), + : XObject(kernel_state, kObjectType, !guest_thread), thread_id_(++next_xthread_id_), guest_thread_(guest_thread), main_thread_(main_thread), @@ -79,10 +79,6 @@ XThread::XThread(KernelState* kernel_state, uint32_t stack_size, creation_params_.stack_size = 16 * 1024; } - if (!guest_thread_) { - host_object_ = true; - } - // The kernel does not take a reference. We must unregister in the dtor. kernel_state_->RegisterThread(this); }