diff options
| author | 2020-04-08 23:03:25 -0400 | |
|---|---|---|
| committer | 2020-04-17 00:59:34 -0400 | |
| commit | ff5d5b6f41c9c7e65dd1027e6f843470f06f49d6 (patch) | |
| tree | ca4fe258eb52516152a3694f51e6887226004829 /src/core/memory.cpp | |
| parent | video_core: memory_manager: Updates for Common::PageTable changes. (diff) | |
| download | yuzu-ff5d5b6f41c9c7e65dd1027e6f843470f06f49d6.tar.gz yuzu-ff5d5b6f41c9c7e65dd1027e6f843470f06f49d6.tar.xz yuzu-ff5d5b6f41c9c7e65dd1027e6f843470f06f49d6.zip | |
core: memory: Fix memory access on page boundaries.
- Fixes Super Smash Bros. Ultimate.
Diffstat (limited to 'src/core/memory.cpp')
| -rw-r--r-- | src/core/memory.cpp | 45 |
1 files changed, 39 insertions, 6 deletions
diff --git a/src/core/memory.cpp b/src/core/memory.cpp index fd892b762..9d87045a0 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp | |||
| @@ -119,15 +119,33 @@ struct Memory::Impl { | |||
| 119 | } | 119 | } |
| 120 | 120 | ||
| 121 | u16 Read16(const VAddr addr) { | 121 | u16 Read16(const VAddr addr) { |
| 122 | return Read<u16_le>(addr); | 122 | if ((addr & 1) == 0) { |
| 123 | return Read<u16_le>(addr); | ||
| 124 | } else { | ||
| 125 | const u8 a{Read<u8>(addr)}; | ||
| 126 | const u8 b{Read<u8>(addr + sizeof(u8))}; | ||
| 127 | return (static_cast<u16>(b) << 8) | a; | ||
| 128 | } | ||
| 123 | } | 129 | } |
| 124 | 130 | ||
| 125 | u32 Read32(const VAddr addr) { | 131 | u32 Read32(const VAddr addr) { |
| 126 | return Read<u32_le>(addr); | 132 | if ((addr & 3) == 0) { |
| 133 | return Read<u32_le>(addr); | ||
| 134 | } else { | ||
| 135 | const u16 a{Read16(addr)}; | ||
| 136 | const u16 b{Read16(addr + sizeof(u16))}; | ||
| 137 | return (static_cast<u32>(b) << 16) | a; | ||
| 138 | } | ||
| 127 | } | 139 | } |
| 128 | 140 | ||
| 129 | u64 Read64(const VAddr addr) { | 141 | u64 Read64(const VAddr addr) { |
| 130 | return Read<u64_le>(addr); | 142 | if ((addr & 7) == 0) { |
| 143 | return Read<u64_le>(addr); | ||
| 144 | } else { | ||
| 145 | const u32 a{Read32(addr)}; | ||
| 146 | const u32 b{Read32(addr + sizeof(u32))}; | ||
| 147 | return (static_cast<u64>(b) << 32) | a; | ||
| 148 | } | ||
| 131 | } | 149 | } |
| 132 | 150 | ||
| 133 | void Write8(const VAddr addr, const u8 data) { | 151 | void Write8(const VAddr addr, const u8 data) { |
| @@ -135,15 +153,30 @@ struct Memory::Impl { | |||
| 135 | } | 153 | } |
| 136 | 154 | ||
| 137 | void Write16(const VAddr addr, const u16 data) { | 155 | void Write16(const VAddr addr, const u16 data) { |
| 138 | Write<u16_le>(addr, data); | 156 | if ((addr & 1) == 0) { |
| 157 | Write<u16_le>(addr, data); | ||
| 158 | } else { | ||
| 159 | Write<u8>(addr, static_cast<u8>(data)); | ||
| 160 | Write<u8>(addr + sizeof(u8), static_cast<u8>(data >> 8)); | ||
| 161 | } | ||
| 139 | } | 162 | } |
| 140 | 163 | ||
| 141 | void Write32(const VAddr addr, const u32 data) { | 164 | void Write32(const VAddr addr, const u32 data) { |
| 142 | Write<u32_le>(addr, data); | 165 | if ((addr & 3) == 0) { |
| 166 | Write<u32_le>(addr, data); | ||
| 167 | } else { | ||
| 168 | Write16(addr, static_cast<u16>(data)); | ||
| 169 | Write16(addr + sizeof(u16), static_cast<u16>(data >> 16)); | ||
| 170 | } | ||
| 143 | } | 171 | } |
| 144 | 172 | ||
| 145 | void Write64(const VAddr addr, const u64 data) { | 173 | void Write64(const VAddr addr, const u64 data) { |
| 146 | Write<u64_le>(addr, data); | 174 | if ((addr & 7) == 0) { |
| 175 | Write<u64_le>(addr, data); | ||
| 176 | } else { | ||
| 177 | Write32(addr, static_cast<u32>(data)); | ||
| 178 | Write32(addr + sizeof(u32), static_cast<u32>(data >> 32)); | ||
| 179 | } | ||
| 147 | } | 180 | } |
| 148 | 181 | ||
| 149 | std::string ReadCString(VAddr vaddr, std::size_t max_length) { | 182 | std::string ReadCString(VAddr vaddr, std::size_t max_length) { |