Skip to content

Commit

Permalink
Merge pull request #2040 from magumagu/gc-memmap
Browse files Browse the repository at this point in the history
Try to fix our memory map to match the GameCube.
  • Loading branch information
magumagu committed Feb 19, 2015
2 parents fbbbad9 + 314b241 commit 0360e01
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 12 deletions.
21 changes: 17 additions & 4 deletions Source/Core/Core/HW/Memmap.cpp
Expand Up @@ -118,7 +118,8 @@ bool IsInitialized()
// with address translation turned off. (This is only used by the CPU;
// other devices, like the GPU, use other rules, approximated by
// Memory::GetPointer.) This memory is laid out as follows:
// [0x00000000, 0x01800000) - 24MB RAM
// [0x00000000, 0x02000000) - 32MB RAM
// [0x02000000, 0x08000000) - Mirrors of 32MB RAM
// [0x08000000, 0x0C000000) - EFB "mapping" (not handled here)
// [0x0C000000, 0x0E000000) - MMIO etc. (not handled here)
// [0x10000000, 0x14000000) - 64MB RAM (Wii-only; slightly slower)
Expand All @@ -127,13 +128,16 @@ bool IsInitialized()
// with address translation turned on. Instead of changing the mapping
// based on the BAT registers, we approximate the common BAT configuration
// used by games:
// [0x00000000, 0x01800000) - 24MB RAM, cached access, normally only mapped
// [0x00000000, 0x02000000) - 32MB RAM, cached access, normally only mapped
// during startup by Wii WADs
// [0x02000000, 0x08000000) - Mirrors of 32MB RAM (not implemented here)
// [0x40000000, 0x50000000) - FakeVMEM
// [0x70000000, 0x80000000) - FakeVMEM
// [0x80000000, 0x81800000) - 24MB RAM, cached access
// [0x80000000, 0x82000000) - 32MB RAM, cached access
// [0x82000000, 0x88000000) - Mirrors of 32MB RAM (not implemented here)
// [0x90000000, 0x94000000) - 64MB RAM, Wii-only, cached access
// [0xC0000000, 0xC1800000) - 24MB RAM, uncached access
// [0xC0000000, 0xC2000000) - 32MB RAM, uncached access
// [0xC2000000, 0xC8000000) - Mirrors of 32MB RAM (not implemented here)
// [0xC8000000, 0xCC000000) - EFB "mapping" (not handled here)
// [0xCC000000, 0xCE000000) - MMIO etc. (not handled here)
// [0xD0000000, 0xD4000000) - 64MB RAM, Wii-only, uncached access
Expand All @@ -145,7 +149,16 @@ bool IsInitialized()
// Each of these 4GB regions is followed by 4GB of empty space so overflows
// in address computation in the JIT don't access the wrong memory.
//
// The neighboring mirrors of RAM ([0x02000000, 0x08000000), etc.) exist because
// the bus masks off the bits in question for RAM accesses; using them is a
// terrible idea because the CPU cache won't handle them correctly, but a
// few buggy games (notably Rogue Squadron 2) use them by accident. They
// aren't backed by memory mappings because they are used very rarely.
//
// Dolphin doesn't emulate the difference between cached and uncached access.
//
// TODO: The actual size of RAM is REALRAM_SIZE (24MB); the other 8MB shouldn't
// be backed by actual memory.
static MemoryView views[] =
{
{&m_pRAM, 0x00000000, RAM_SIZE, 0},
Expand Down
32 changes: 24 additions & 8 deletions Source/Core/Core/PowerPC/MMU.cpp
Expand Up @@ -136,12 +136,17 @@ __forceinline static T ReadFromHardware(const u32 em_address)
else
return (T)Memory::mmio_mapping->Read<typename std::make_unsigned<T>::type>(em_address);
}
if ((segment == 0x0 || segment == 0x8 || segment == 0xC) && (em_address & 0x0FFFFFFF) < Memory::REALRAM_SIZE)
if (segment == 0x0 || segment == 0x8 || segment == 0xC)
{
return bswap((*(const T*)&Memory::m_pRAM[em_address & 0x0FFFFFFF]));
// Handle RAM; the masking intentionally discards bits (essentially creating
// mirrors of memory).
// TODO: Only the first REALRAM_SIZE is supposed to be backed by actual memory.
return bswap((*(const T*)&Memory::m_pRAM[em_address & Memory::RAM_MASK]));
}
if (Memory::m_pEXRAM && (segment == 0x9 || segment == 0xD) && (em_address & 0x0FFFFFFF) < Memory::EXRAM_SIZE)
{
// Handle EXRAM.
// TODO: Is this supposed to be mirrored like main RAM?
return bswap((*(const T*)&Memory::m_pEXRAM[em_address & 0x0FFFFFFF]));
}
if (segment == 0xE && (em_address < (0xE0000000 + Memory::L1_CACHE_SIZE)))
Expand All @@ -165,9 +170,12 @@ __forceinline static T ReadFromHardware(const u32 em_address)
else
return (T)Memory::mmio_mapping->Read<typename std::make_unsigned<T>::type>(em_address | 0xC0000000);
}
if (em_address < Memory::REALRAM_SIZE)
if (segment == 0x0)
{
return bswap((*(const T*)&Memory::m_pRAM[em_address]));
// Handle RAM; the masking intentionally discards bits (essentially creating
// mirrors of memory).
// TODO: Only the first REALRAM_SIZE is supposed to be backed by actual memory.
return bswap((*(const T*)&Memory::m_pRAM[em_address & Memory::RAM_MASK]));
}
if (Memory::m_pEXRAM && segment == 0x1 && (em_address & 0x0FFFFFFF) < Memory::EXRAM_SIZE)
{
Expand Down Expand Up @@ -254,13 +262,18 @@ __forceinline static void WriteToHardware(u32 em_address, const T data)
return;
}
}
if ((segment == 0x8 || segment == 0xC) && (em_address & 0x0FFFFFFF) < Memory::REALRAM_SIZE)
if (segment == 0x0 || segment == 0x8 || segment == 0xC)
{
*(T*)&Memory::m_pRAM[em_address & 0x0FFFFFFF] = bswap(data);
// Handle RAM; the masking intentionally discards bits (essentially creating
// mirrors of memory).
// TODO: Only the first REALRAM_SIZE is supposed to be backed by actual memory.
*(T*)&Memory::m_pRAM[em_address & Memory::RAM_MASK] = bswap(data);
return;
}
if (Memory::m_pEXRAM && (segment == 0x9 || segment == 0xD) && (em_address & 0x0FFFFFFF) < Memory::EXRAM_SIZE)
{
// Handle EXRAM.
// TODO: Is this supposed to be mirrored like main RAM?
*(T*)&Memory::m_pEXRAM[em_address & 0x0FFFFFFF] = bswap(data);
return;
}
Expand Down Expand Up @@ -304,9 +317,12 @@ __forceinline static void WriteToHardware(u32 em_address, const T data)
return;
}
}
if (em_address < Memory::REALRAM_SIZE)
if (segment == 0x0)
{
*(T*)&Memory::m_pRAM[em_address] = bswap(data);
// Handle RAM; the masking intentionally discards bits (essentially creating
// mirrors of memory).
// TODO: Only the first REALRAM_SIZE is supposed to be backed by actual memory.
*(T*)&Memory::m_pRAM[em_address & Memory::RAM_MASK] = bswap(data);
return;
}
if (Memory::m_pEXRAM && segment == 0x1 && (em_address & 0x0FFFFFFF) < Memory::EXRAM_SIZE)
Expand Down

0 comments on commit 0360e01

Please sign in to comment.