Skip to content

Commit

Permalink
Fix to Expand MSSB Gecko Space
Browse files Browse the repository at this point in the history
I copied this method from faster melee https://github.com/FasterMelee/Ishiiruka/blob/master/Source/Core/Core/GeckoCode.cpp#L147

it works well. thanks!
  • Loading branch information
LittleCoaks committed Mar 5, 2024
1 parent ee1fcd8 commit dfdc2c8
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 48 deletions.
2 changes: 1 addition & 1 deletion Source/Core/Core/Core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1820,7 +1820,7 @@ std::optional<u32> getGameFreeMemory()
{
switch (mGameBeingPlayed) {
case GameName::MarioBaseball:
return 0x802edb10;
return 0x802ed200;
case GameName::ToadstoolTour:
return std::nullopt;
case GameName::UnknownGame:
Expand Down
86 changes: 39 additions & 47 deletions Source/Core/Core/GeckoCode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
#include <mutex>
#include <tuple>
#include <vector>
#include <iostream>

#include "Common/ChunkFile.h"
#include "Common/CommonPaths.h"
Expand Down Expand Up @@ -168,37 +167,9 @@ static Installation InstallCodeHandlerLocked(const Core::CPUThreadGuard& guard)
mmio_addr = 0xCD;
}

// Gets the free memory location for the current game. If game has not specified a
auto free_memory_base_address = Core::getGameFreeMemory();
bool use_free_memory = Core::getGameFreeMemory().has_value();
const u32 memory_base_address = use_free_memory ? free_memory_base_address.value() : INSTALLER_BASE_ADDRESS + static_cast<u32>(data.size()) - CODE_SIZE;

// Install code handler
for (u32 i = 0; i < data.size(); ++i) {
//We need to change one small part of the binary to point at the free memory location
// codehandler.bin
// ...
// 000000f0: 3fe0 8000 3e80 cc00 a394 4010 6395 00ff ?...>[email protected]...
// 00000100: b2b4 4010 3de0 8000 61ef 2338 63e7 1808 ..@.=...a.#8c... Notes: 3de0 8000 -> 3de0 <Free Space Addr ABCD>, 61ef 2338 -> 61ef <Free Space Addr EFGH>
// 00000110: 3cc0 8000 7cd0 3378 3900 0000 3c60 00d0 <...|.3x9...<`..
// ...

if (i==262 && use_free_memory){
PowerPC::MMU::HostWrite_U8(guard, (memory_base_address & 0xFF000000) >> 24, INSTALLER_BASE_ADDRESS + i);
}
else if (i==263 && use_free_memory) {
PowerPC::MMU::HostWrite_U8(guard, (memory_base_address & 0x00FF0000) >> 16, INSTALLER_BASE_ADDRESS + i);
}
else if (i==266 && use_free_memory) {
PowerPC::MMU::HostWrite_U8(guard, (memory_base_address & 0x0000FF00) >> 8, INSTALLER_BASE_ADDRESS + i);
}
else if (i==267 && use_free_memory) {
PowerPC::MMU::HostWrite_U8(guard, (memory_base_address & 0x000000FF), INSTALLER_BASE_ADDRESS + i);
}
else { //Just write the binary as is
PowerPC::MMU::HostWrite_U8(guard, data[i], INSTALLER_BASE_ADDRESS + i);
}
}
for (u32 i = 0; i < data.size(); ++i)
PowerPC::MMU::HostWrite_U8(guard, data[i], INSTALLER_BASE_ADDRESS + i);

// Patch the code handler to the current system type (Gamecube/Wii)
for (u32 h = 0; h < data.length(); h += 4)
Expand All @@ -212,40 +183,61 @@ static Installation InstallCodeHandlerLocked(const Core::CPUThreadGuard& guard)
}
}

u32 codelist_base_address = INSTALLER_BASE_ADDRESS + static_cast<u32>(data.size()) - CODE_SIZE;
u32 codelist_end_address = INSTALLER_END_ADDRESS;

auto free_memory_base_address = Core::getGameFreeMemory();
bool use_free_memory = free_memory_base_address.has_value();
if (use_free_memory)
{
// Move Gecko code handler to the free mem region
codelist_base_address = free_memory_base_address.value();
codelist_end_address = codelist_base_address + 0xA700;
PowerPC::MMU::HostWrite_U32(guard, ((codelist_base_address & 0xFFFF0000) >> 16 ) + 0x3DE00000, 0x80001904);
PowerPC::MMU::HostWrite_U32(guard, (codelist_base_address & 0x0000FFFF) + 0x61EF0000, 0x80001908);
}

// Write a magic value to 'gameid' (codehandleronly does not actually read this).
// This value will be read back and modified over time by HLE_Misc::GeckoCodeHandlerICacheFlush.
PowerPC::MMU::HostWrite_U32(guard, MAGIC_GAMEID, INSTALLER_BASE_ADDRESS);

// Create GCT in free memory (Preamble)
PowerPC::MMU::HostWrite_U32(guard, 0x00d0c0de, memory_base_address);
PowerPC::MMU::HostWrite_U32(guard, 0x00d0c0de, memory_base_address + 4);
// Create GCT in memory
PowerPC::MMU::HostWrite_U32(guard, 0x00d0c0de, codelist_base_address);
PowerPC::MMU::HostWrite_U32(guard, 0x00d0c0de, codelist_base_address + 4);

// Each code is 8 bytes (2 words) wide. There is a starter code and an end code.
u32 memory_next_addr = memory_base_address + CODE_SIZE;
const u32 start_address = codelist_base_address + CODE_SIZE;
const u32 end_address = codelist_end_address - CODE_SIZE;
u32 next_address = start_address;

// NOTE: Only active codes are in the list
for (const GeckoCode& active_code : s_active_codes)
{
// If the code is not going to fit in the space we have left then we have to skip it
if (next_address + active_code.codes.size() * CODE_SIZE > end_address)
{
NOTICE_LOG_FMT(ACTIONREPLAY,
"Too many GeckoCodes! Ran out of storage space in Game RAM. Could "
"not write: \"{}\". Need {} bytes, only {} remain.",
active_code.name, active_code.codes.size() * CODE_SIZE,
end_address - next_address);
continue;
}

// Always write to the free memory address regardless of size
// TODO: Add check on upper bound of free memory
for (const GeckoCode::Code& code : active_code.codes)
{
PowerPC::MMU::HostWrite_U32(guard, code.address, memory_next_addr);
PowerPC::MMU::HostWrite_U32(guard, code.data, memory_next_addr + 4);
memory_next_addr += CODE_SIZE;
PowerPC::MMU::HostWrite_U32(guard, code.address, next_address);
PowerPC::MMU::HostWrite_U32(guard, code.data, next_address + 4);
next_address += CODE_SIZE;
}

// TODO optional boundary checking for the free memory
}

// WARN_LOG_FMT(ACTIONREPLAY, "GeckoCodes: Using {} of {} bytes", next_address - start_address,
// end_address - start_address);
WARN_LOG_FMT(ACTIONREPLAY, "GeckoCodes: Using {} of {} bytes", next_address - start_address,
end_address - start_address);

// Free Memory EOF
// Stop code. Tells the handler that this is the end of the list.
PowerPC::MMU::HostWrite_U32(guard, 0xF0000000, memory_next_addr);
PowerPC::MMU::HostWrite_U32(guard, 0x00000000, memory_next_addr + 4);
PowerPC::MMU::HostWrite_U32(guard, 0xF0000000, next_address);
PowerPC::MMU::HostWrite_U32(guard, 0x00000000, next_address + 4);
PowerPC::MMU::HostWrite_U32(guard, 0, HLE_TRAMPOLINE_ADDRESS);

// Turn on codes
Expand Down

0 comments on commit dfdc2c8

Please sign in to comment.