diff options
| author | 2015-02-18 17:19:38 -0500 | |
|---|---|---|
| committer | 2015-02-18 17:19:38 -0500 | |
| commit | 4a48b017ca7fe8fe68dfc84d70864ef6aea6a266 (patch) | |
| tree | dcd7914a3a2147790d384ce0992f70d40bce8704 /src/core/hw/gpu.cpp | |
| parent | Merge pull request #570 from purpasmart96/config_mem (diff) | |
| parent | Pica/Rasterizer: Replace exit() calls with UNIMPLEMENTED(). (diff) | |
| download | yuzu-4a48b017ca7fe8fe68dfc84d70864ef6aea6a266.tar.gz yuzu-4a48b017ca7fe8fe68dfc84d70864ef6aea6a266.tar.xz yuzu-4a48b017ca7fe8fe68dfc84d70864ef6aea6a266.zip | |
Merge pull request #562 from neobrain/pica_progress3
More PICA200 Emulation Fixes
Diffstat (limited to 'src/core/hw/gpu.cpp')
| -rw-r--r-- | src/core/hw/gpu.cpp | 41 |
1 files changed, 28 insertions, 13 deletions
diff --git a/src/core/hw/gpu.cpp b/src/core/hw/gpu.cpp index aad0e5d0d..bd7d92cd1 100644 --- a/src/core/hw/gpu.cpp +++ b/src/core/hw/gpu.cpp | |||
| @@ -67,23 +67,38 @@ inline void Write(u32 addr, const T data) { | |||
| 67 | switch (index) { | 67 | switch (index) { |
| 68 | 68 | ||
| 69 | // Memory fills are triggered once the fill value is written. | 69 | // Memory fills are triggered once the fill value is written. |
| 70 | // NOTE: This is not verified. | 70 | case GPU_REG_INDEX_WORKAROUND(memory_fill_config[0].trigger, 0x00004 + 0x3): |
| 71 | case GPU_REG_INDEX_WORKAROUND(memory_fill_config[0].value, 0x00004 + 0x3): | 71 | case GPU_REG_INDEX_WORKAROUND(memory_fill_config[1].trigger, 0x00008 + 0x3): |
| 72 | case GPU_REG_INDEX_WORKAROUND(memory_fill_config[1].value, 0x00008 + 0x3): | ||
| 73 | { | 72 | { |
| 74 | const bool is_second_filler = (index != GPU_REG_INDEX(memory_fill_config[0].value)); | 73 | const bool is_second_filler = (index != GPU_REG_INDEX(memory_fill_config[0].trigger)); |
| 75 | const auto& config = g_regs.memory_fill_config[is_second_filler]; | 74 | auto& config = g_regs.memory_fill_config[is_second_filler]; |
| 76 | 75 | ||
| 77 | // TODO: Not sure if this check should be done at GSP level instead | 76 | if (config.address_start && config.trigger) { |
| 78 | if (config.address_start) { | 77 | u8* start = Memory::GetPointer(Memory::PhysicalToVirtualAddress(config.GetStartAddress())); |
| 79 | // TODO: Not sure if this algorithm is correct, particularly because it doesn't use the size member at all | 78 | u8* end = Memory::GetPointer(Memory::PhysicalToVirtualAddress(config.GetEndAddress())); |
| 80 | u32* start = (u32*)Memory::GetPointer(Memory::PhysicalToVirtualAddress(config.GetStartAddress())); | 79 | |
| 81 | u32* end = (u32*)Memory::GetPointer(Memory::PhysicalToVirtualAddress(config.GetEndAddress())); | 80 | if (config.fill_24bit) { |
| 82 | for (u32* ptr = start; ptr < end; ++ptr) | 81 | // fill with 24-bit values |
| 83 | *ptr = bswap32(config.value); // TODO: This is just a workaround to missing framebuffer format emulation | 82 | for (u8* ptr = start; ptr < end; ptr += 3) { |
| 83 | ptr[0] = config.value_24bit_b; | ||
| 84 | ptr[1] = config.value_24bit_g; | ||
| 85 | ptr[2] = config.value_24bit_r; | ||
| 86 | } | ||
| 87 | } else if (config.fill_32bit) { | ||
| 88 | // fill with 32-bit values | ||
| 89 | for (u32* ptr = (u32*)start; ptr < (u32*)end; ++ptr) | ||
| 90 | *ptr = config.value_32bit; | ||
| 91 | } else { | ||
| 92 | // fill with 16-bit values | ||
| 93 | for (u16* ptr = (u16*)start; ptr < (u16*)end; ++ptr) | ||
| 94 | *ptr = config.value_16bit; | ||
| 95 | } | ||
| 84 | 96 | ||
| 85 | LOG_TRACE(HW_GPU, "MemoryFill from 0x%08x to 0x%08x", config.GetStartAddress(), config.GetEndAddress()); | 97 | LOG_TRACE(HW_GPU, "MemoryFill from 0x%08x to 0x%08x", config.GetStartAddress(), config.GetEndAddress()); |
| 86 | 98 | ||
| 99 | config.trigger = 0; | ||
| 100 | config.finished = 1; | ||
| 101 | |||
| 87 | if (!is_second_filler) { | 102 | if (!is_second_filler) { |
| 88 | GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PSC0); | 103 | GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PSC0); |
| 89 | } else { | 104 | } else { |