| 225 | |
| 226 | |
| 227 | void MapTLB(const tlbs& t, int i) |
| 228 | { |
| 229 | u32 mask, addr; |
| 230 | u32 saddr, eaddr; |
| 231 | |
| 232 | COP0_LOG("MAP TLB %d: 0x%08X-> [0x%08X 0x%08X] S=%d G=%d ASID=%d Mask=0x%03X EntryLo0 PFN=%x EntryLo0 Cache=%x EntryLo1 PFN=%x EntryLo1 Cache=%x VPN2=%x", |
| 233 | i, t.VPN2(), t.PFN0(), t.PFN1(), t.isSPR() >> 31, t.isGlobal(), t.EntryHi.ASID, |
| 234 | t.Mask(), t.EntryLo0.PFN, t.EntryLo0.C, t.EntryLo1.PFN, t.EntryLo1.C, t.VPN2()); |
| 235 | |
| 236 | // According to the manual |
| 237 | // 'It [SPR] must be mapped into a contiguous 16 KB of virtual address space that is |
| 238 | // aligned on a 16KB boundary.Results are not guaranteed if this restriction is not followed.' |
| 239 | // Assume that the game isn't doing anything less-than-ideal with the scratchpad mapping and map it directly to eeMem->Scratch. |
| 240 | if (t.isSPR()) |
| 241 | { |
| 242 | if (t.VPN2() != 0x70000000) |
| 243 | Console.Warning("COP0: Mapping Scratchpad to non-default address 0x%08X", t.VPN2()); |
| 244 | |
| 245 | vtlb_VMapBuffer(t.VPN2(), eeMem->Scratch, Ps2MemSize::Scratch); |
| 246 | } |
| 247 | else |
| 248 | { |
| 249 | if (t.EntryLo0.V) |
| 250 | { |
| 251 | mask = ((~t.Mask()) << 1) & 0xfffff; |
| 252 | saddr = t.VPN2() >> 12; |
| 253 | eaddr = saddr + t.Mask() + 1; |
| 254 | |
| 255 | for (addr = saddr; addr < eaddr; addr++) |
| 256 | { |
| 257 | if ((addr & mask) == ((t.VPN2() >> 12) & mask)) |
| 258 | { //match |
| 259 | memSetPageAddr(addr << 12, t.PFN0() + ((addr - saddr) << 12)); |
| 260 | Cpu->Clear(addr << 12, 0x400); |
| 261 | } |
| 262 | } |
| 263 | } |
| 264 | |
| 265 | if (t.EntryLo1.V) |
| 266 | { |
| 267 | mask = ((~t.Mask()) << 1) & 0xfffff; |
| 268 | saddr = (t.VPN2() >> 12) + t.Mask() + 1; |
| 269 | eaddr = saddr + t.Mask() + 1; |
| 270 | |
| 271 | for (addr = saddr; addr < eaddr; addr++) |
| 272 | { |
| 273 | if ((addr & mask) == ((t.VPN2() >> 12) & mask)) |
| 274 | { //match |
| 275 | memSetPageAddr(addr << 12, t.PFN1() + ((addr - saddr) << 12)); |
| 276 | Cpu->Clear(addr << 12, 0x400); |
| 277 | } |
| 278 | } |
| 279 | } |
| 280 | } |
| 281 | } |
| 282 | |
| 283 | __inline u32 ConvertPageMask(const u32 PageMask) |
| 284 | { |
no test coverage detected