diff --git a/src/xenia/gpu/pm4_command_processor_implement.h b/src/xenia/gpu/pm4_command_processor_implement.h index 668b106f0..abcd78e01 100644 --- a/src/xenia/gpu/pm4_command_processor_implement.h +++ b/src/xenia/gpu/pm4_command_processor_implement.h @@ -897,7 +897,17 @@ bool COMMAND_PROCESSOR::ExecutePacketType3_EVENT_WRITE_SHD( auto endianness = static_cast(address & 0x3); address &= ~0x3; data_value = GpuSwap(data_value, endianness); - xe::store(memory_->TranslatePhysical(address), data_value); + uint8_t* write_destination = memory_->TranslatePhysical(address); + if (address > 0x1FFFFFFF) { + uint32_t writeback_base = register_file_->values[XE_GPU_REG_WRITEBACK_BASE].u32; + uint32_t writeback_size = register_file_->values[XE_GPU_REG_WRITEBACK_SIZE].u32; + uint32_t writeback_offset = address - writeback_base; + //check whether the guest has written writeback base. if they haven't, skip the offset check + if (writeback_base != 0 && writeback_offset < writeback_size) { + write_destination = memory_->TranslateVirtual(0x7F000000 + writeback_offset); + } + } + xe::store(write_destination, data_value); trace_writer_.WriteMemoryWrite(CpuToGpu(address), 4); return true; } diff --git a/src/xenia/gpu/register_table.inc b/src/xenia/gpu/register_table.inc index 2ea5bf93f..6226437b7 100644 --- a/src/xenia/gpu/register_table.inc +++ b/src/xenia/gpu/register_table.inc @@ -72,10 +72,14 @@ XE_GPU_REGISTER(0x0855, kDword, MC1_PERFCOUNTER0_SELECT) XE_GPU_REGISTER(0x0856, kDword, MC1_PERFCOUNTER0_HI) XE_GPU_REGISTER(0x0857, kDword, MC1_PERFCOUNTER0_LOW) -XE_GPU_REGISTER(0x0A02, kDword, UNKNOWN_0A02) -XE_GPU_REGISTER(0x0A03, kDword, UNKNOWN_0A03) -XE_GPU_REGISTER(0x0A04, kDword, UNKNOWN_0A04) -XE_GPU_REGISTER(0x0A05, kDword, UNKNOWN_0A05) +//base GPU virtual address of the xps region. Most guests write 0xC0100000 here +XE_GPU_REGISTER(0x0A02, kDword, XPS_BASE) +//will usually be set higher, but is effectively 0x700000 bytes long +XE_GPU_REGISTER(0x0A03, kDword, XPS_SIZE) +//usually 0xC0000000 +XE_GPU_REGISTER(0x0A04, kDword, WRITEBACK_BASE) +//usually 0x0100000 +XE_GPU_REGISTER(0x0A05, kDword, WRITEBACK_SIZE) XE_GPU_REGISTER(0x0A18, kDword, MH_PERFCOUNTER0_SELECT) XE_GPU_REGISTER(0x0A19, kDword, MH_PERFCOUNTER0_HI)