add xbox patch support

This commit is contained in:
Martin Michelsen
2024-01-21 21:56:48 -08:00
parent db3cecdd2b
commit 80a57f9d3e
147 changed files with 584 additions and 198 deletions
+8 -6
View File
@@ -19,7 +19,7 @@ See TODO.md for a list of known issues and future work I've curated, or go to th
* [Item tables and drop modes](#item-tables-and-drop-modes)
* [Cross-version play](#cross-version-play)
* [Episode 3 features](#episode-3-features)
* [Memory patches and DOL files for GC](#memory-patches-and-dol-files)
* [Memory patches, client functions, and DOL files](#memory-patches-client-functions-and-dol-files)
* [Using newserv as a proxy](#using-newserv-as-a-proxy)
* [Chat commands](#chat-commands)
* [Non-server features](#non-server-features)
@@ -291,9 +291,9 @@ There is no public editor for Episode 3 maps and quests, but the format is descr
Like quests, Episode 3 card definitions, maps, and quests are cached in memory. If you've changed any of these files, you can run `reload ep3-data` in the interactive shell to make the changes take effect without restarting the server.
## Memory patches and DOL files
## Memory patches, client functions, and DOL files
Everything in this section requires resource_dasm to be installed, so newserv can use the PowerPC assembler and disassembler from its libresource_file library. If resource_dasm is not installed, newserv will still build and run, but these features will not be available.
Everything in this section requires resource_dasm to be installed, so newserv can use the assemblers and disassemblers from its libresource_file library. If resource_dasm is not installed, newserv will still build and run, but these features will not be available.
In addition, these features are only supported for the following game versions:
* PSO GameCube Episodes 1&2 JP, USA, and EU (not Plus)
@@ -301,12 +301,14 @@ In addition, these features are only supported for the following game versions:
* PSO GameCube Episode 3 Trial Edition
* PSO GameCube Episode 3 JP
* PSO GameCube Episode 3 USA (experimental; must be manually enabled in config.json)
* PSO Xbox (all versions)
* PSO BB
You can put memory patches in the system/ppc directory with filenames like PatchName.patch.s and they will appear in the Patches menu for PSO GC clients that support patching. Memory patches are written in PowerPC assembly and are compiled when newserv is started. The PowerPC assembly system's features are documented in the comments in system/ppc/WriteMemory.s - this file is not a memory patch itself, but it describes how memory patches may be written and the restrictions that apply to them.
You can put memory patches in the system/client-functions directory with filenames like PatchName.patch.s and they will appear in the Patches menu for PSO GC, XB, and BB clients that support patching. Memory patches are written in PowerPC or x86 assembly and are compiled when newserv is started. The assembly system's features are documented in the comments in system/client-functions/WriteMemory.ppc.s.
newserv comes with a set of patches for Episodes 1&2 based on AR codes originally made by Ralf at GC-Forever. Many of them were originally posted in [this thread](https://www.gc-forever.com/forums/viewtopic.php?f=38&t=2050).
newserv comes with a set of patches for GC Episodes 1&2 based on AR codes originally made by Ralf at GC-Forever. Many of them were originally posted in [this thread](https://www.gc-forever.com/forums/viewtopic.php?f=38&t=2050).
You can also put DOL files in the system/dol directory, and they will appear in the Programs menu. Selecting a DOL file there will load the file into the GameCube's memory and run it, just like the old homebrew loaders (PSUL and PSOload) did. For this to work, ReadMemoryWord.s, WriteMemory.s, and RunDOL.s must be present in the system/ppc directory. This has been tested on Dolphin but not on a real GameCube, so results may vary.
You can also put DOL files in the system/dol directory, and they will appear in the Programs menu for GC clients. Selecting a DOL file there will load the file into the GameCube's memory and run it, just like the old homebrew loaders (PSUL and PSOload) did. For this to work, ReadMemoryWord.ppc.s, WriteMemory.ppc.s, and RunDOL.ppc.s must be present in the system/client-functions directory. This has been tested on Dolphin but not on a real GameCube, so results may vary.
Like other kinds of data, functions and DOL files are cached in memory. If you've changed any of these files, you can run `reload functions` or `reload dol-files` in the interactive shell to make the changes take effect without restarting the server.
+1 -1
View File
@@ -72,7 +72,7 @@ def write_patches_for_code(
f.write("reloc0:\n")
f.write(" .offsetof start\n")
f.write("start:\n")
f.write(" .include WriteCodeBlocks\n")
f.write(" .include WriteCodeBlocksGC\n")
for region in write_regions:
f.write(
f" # region @ {region.address:08X} ({len(region.data) * 4} bytes)\n"
+4 -2
View File
@@ -555,13 +555,15 @@ static void proxy_command_patch(shared_ptr<ProxyServer::LinkedSession> ses, cons
};
auto send_version_detect_or_send_call = [args, ses, send_call]() {
if (is_gc(ses->version()) &&
bool is_gc = ::is_gc(ses->version());
bool is_xb = (ses->version() == Version::XB_V3);
if ((is_gc || is_xb) &&
ses->config.specific_version == default_specific_version_for_version(ses->version(), -1)) {
auto s = ses->require_server_state();
send_function_call(
ses->client_channel,
ses->config,
s->function_code_index->name_to_function.at("VersionDetect"));
s->function_code_index->name_to_function.at(is_xb ? "VersionDetectXB" : "VersionDetectGC"));
ses->function_call_return_handler_queue.emplace_back(send_call);
} else {
send_call(ses->config.specific_version, 0);
+2 -1
View File
@@ -2177,7 +2177,8 @@ struct S_ServerTime_B1 {
// newserv supports exploiting a bug in the USA version of Episode 3, which
// re-enables the use of this command on that version of the game. See
// system/ppc/Episode3USAQuestBufferOverflow.s for further details.
// system/client-functions/Episode3USAQuestBufferOverflow.ppc.s for further
// details.
struct S_ExecuteCode_B2 {
// If code_size == 0, no code is executed, but checksumming may still occur.
+117 -43
View File
@@ -10,6 +10,7 @@
#ifdef HAVE_RESOURCE_FILE
#include <resource_file/Emulators/PPC32Emulator.hh>
#include <resource_file/Emulators/X86Emulator.hh>
#endif
#include "CommandFormats.hh"
@@ -133,28 +134,74 @@ shared_ptr<CompiledFunctionCode> compile_function_code(
ret->index = 0;
ret->hide_from_patches_menu = false;
if (arch == CompiledFunctionCode::Architecture::POWERPC) {
auto assembled = PPC32Emulator::assemble(text, {directory});
ret->code = std::move(assembled.code);
ret->label_offsets = std::move(assembled.label_offsets);
for (const auto& it : assembled.metadata_keys) {
if (it.first == "hide_from_patches_menu") {
ret->hide_from_patches_menu = true;
} else if (it.first == "index") {
if (it.second.size() != 1) {
throw runtime_error("invalid index value in .meta directive");
}
ret->index = it.second[0];
} else if (it.first == "name") {
ret->long_name = it.second;
} else if (it.first == "description") {
ret->description = it.second;
} else {
throw runtime_error("unknown metadata key: " + it.first);
}
unordered_set<string> get_include_stack;
function<string(const string&)> get_include = [&](const string& name) -> string {
const char* arch_name_token;
switch (arch) {
case CompiledFunctionCode::Architecture::POWERPC:
arch_name_token = "ppc";
break;
case CompiledFunctionCode::Architecture::X86:
arch_name_token = "x86";
break;
case CompiledFunctionCode::Architecture::SH4:
arch_name_token = "sh4";
break;
default:
throw runtime_error("unknown architecture");
}
string asm_filename = string_printf("%s/%s.%s.inc.s", directory.c_str(), name.c_str(), arch_name_token);
if (isfile(asm_filename)) {
if (!get_include_stack.emplace(name).second) {
throw runtime_error("mutual recursion between includes: " + name);
}
EmulatorBase::AssembleResult ret;
switch (arch) {
case CompiledFunctionCode::Architecture::POWERPC:
ret = PPC32Emulator::assemble(load_file(asm_filename), get_include);
break;
case CompiledFunctionCode::Architecture::X86:
ret = X86Emulator::assemble(load_file(asm_filename), get_include);
break;
case CompiledFunctionCode::Architecture::SH4:
throw runtime_error("cannot compuile SH-4 assembly");
default:
throw runtime_error("unknown architecture");
}
get_include_stack.erase(name);
return ret.code;
}
string bin_filename = directory + "/" + name + ".inc.bin";
if (isfile(bin_filename)) {
return load_file(bin_filename);
}
throw runtime_error("data not found for include: " + name + " (from " + asm_filename + " or " + bin_filename + ")");
};
EmulatorBase::AssembleResult assembled;
if (arch == CompiledFunctionCode::Architecture::POWERPC) {
assembled = PPC32Emulator::assemble(text, get_include);
} else if (arch == CompiledFunctionCode::Architecture::X86) {
throw runtime_error("x86 assembler is not implemented");
assembled = X86Emulator::assemble(text, get_include);
}
ret->code = std::move(assembled.code);
ret->label_offsets = std::move(assembled.label_offsets);
for (const auto& it : assembled.metadata_keys) {
if (it.first == "hide_from_patches_menu") {
ret->hide_from_patches_menu = true;
} else if (it.first == "index") {
if (it.second.size() != 1) {
throw runtime_error("invalid index value in .meta directive");
}
ret->index = it.second[0];
} else if (it.first == "name") {
ret->long_name = it.second;
} else if (it.first == "description") {
ret->description = it.second;
} else {
throw runtime_error("unknown metadata key: " + it.first);
}
}
set<uint32_t> reloc_indexes;
@@ -191,31 +238,57 @@ FunctionCodeIndex::FunctionCodeIndex(const string& directory) {
}
uint32_t next_menu_item_id = 0;
for (const auto& filename : list_directory(directory)) {
if (!ends_with(filename, ".s") || ends_with(filename, ".inc.s")) {
continue;
}
bool is_patch = ends_with(filename, ".patch.s");
string name = filename.substr(0, filename.size() - (is_patch ? 8 : 2));
// Check for specific_version token
uint32_t specific_version = 0;
string short_name = name;
if (is_patch &&
(filename.size() >= 13) &&
(filename[filename.size() - 13] == '.') &&
isdigit(filename[filename.size() - 12]) &&
(filename[filename.size() - 11] == 'O' || filename[filename.size() - 11] == 'S') &&
(filename[filename.size() - 10] == 'E' || filename[filename.size() - 10] == 'J' || filename[filename.size() - 10] == 'P') &&
(isdigit(filename[filename.size() - 9]) || filename[filename.size() - 9] == 'T')) {
specific_version = 0x33000000 | (filename[filename.size() - 11] << 16) | (filename[filename.size() - 10] << 8) | filename[filename.size() - 9];
short_name = filename.substr(0, filename.size() - 13);
}
for (const auto& filename : list_directory_sorted(directory)) {
try {
if (!ends_with(filename, ".s")) {
continue;
}
string name = filename.substr(0, filename.size() - 2);
if (ends_with(name, ".inc")) {
continue;
}
bool is_patch = ends_with(name, ".patch");
if (is_patch) {
name.resize(name.size() - 6);
}
// Figure out the version or specific_version
CompiledFunctionCode::Architecture arch = CompiledFunctionCode::Architecture::UNKNOWN;
uint32_t specific_version = 0;
string short_name = name;
if (ends_with(name, ".ppc")) {
arch = CompiledFunctionCode::Architecture::POWERPC;
name.resize(name.size() - 4);
short_name = name;
} else if (ends_with(name, ".x86")) {
arch = CompiledFunctionCode::Architecture::X86;
name.resize(name.size() - 4);
short_name = name;
} else if (ends_with(name, ".sh4")) {
arch = CompiledFunctionCode::Architecture::SH4;
name.resize(name.size() - 4);
short_name = name;
} else if (is_patch && (name.size() >= 5) && (name[name.size() - 5] == '.')) {
specific_version = (name[name.size() - 4] << 24) | (name[name.size() - 3] << 16) | (name[name.size() - 2] << 8) | name[name.size() - 1];
if (specific_version_is_gc(specific_version)) {
arch = CompiledFunctionCode::Architecture::POWERPC;
} else if (specific_version_is_xb(specific_version) || specific_version_is_bb(specific_version)) {
arch = CompiledFunctionCode::Architecture::X86;
} else {
throw runtime_error("unable to determine architecture from specific_version");
}
short_name = name.substr(0, name.size() - 5);
}
if (arch == CompiledFunctionCode::Architecture::UNKNOWN) {
throw runtime_error("unable to determine architecture");
}
string path = directory + "/" + filename;
string text = load_file(path);
auto code = compile_function_code(CompiledFunctionCode::Architecture::POWERPC, directory, name, text);
auto code = compile_function_code(arch, directory, name, text);
if (code->index != 0) {
if (!this->index_to_function.emplace(code->index, code).second) {
throw runtime_error(string_printf(
@@ -240,7 +313,7 @@ FunctionCodeIndex::FunctionCodeIndex(const string& directory) {
index_prefix.c_str(), patch_prefix.c_str(), name.c_str(), name_for_architecture(code->arch));
} catch (const exception& e) {
function_compiler_log.warning("Failed to compile function %s: %s", name.c_str(), e.what());
function_compiler_log.warning("Failed to compile function %s: %s", filename.c_str(), e.what());
}
}
}
@@ -252,6 +325,7 @@ shared_ptr<const Menu> FunctionCodeIndex::patch_menu(uint32_t specific_version)
ret->items.emplace_back(PatchesMenuItemID::GO_BACK, "Go back", "Return to the\nmain menu", 0);
for (const auto& it : this->name_and_specific_version_to_patch_function) {
const auto& fn = it.second;
fprintf(stderr, "patch: [%s] vs [%s]\n", it.first.c_str(), suffix.c_str());
if (!fn->hide_from_patches_menu && ends_with(it.first, suffix)) {
ret->items.emplace_back(
fn->menu_item_id,
+2 -1
View File
@@ -18,7 +18,8 @@ void set_function_compiler_available(bool is_available);
struct CompiledFunctionCode {
enum class Architecture {
POWERPC = 0, // GC
UNKNOWN = 0,
POWERPC, // GC
X86, // PC, XB, BB
SH4, // Dreamcast
};
+9 -5
View File
@@ -1324,10 +1324,10 @@ Action a_assemble_quest_script(
Action a_assemble_all_patches(
"assemble-all-patches", "\
assemble-all-patches\n\
Assemble all patches in the system/ppc directory, and produce two compiled\n\
.bin files for each patch (one unencrypted, for most PSO versions, and one\n\
encrypted, for PSO JP v1.04, JP Ep3, and Ep3 Trial Edition). The output\n\
files are written to the system/ppc directory.\n",
Assemble all patches in the system/client-functions directory, and produce\n\
two compiled .bin files for each patch (one unencrypted, for most PSO\n\
versions, and one encrypted, for PSO GC JP v1.04, JP Ep3, and Ep3 Trial\n\
Edition). The output files are saved in system/client-functions.\n",
+[](Arguments&) {
ServerState s;
s.load_objects_and_upstream_dependents("functions");
@@ -1351,7 +1351,11 @@ Action a_assemble_all_patches(
process_code(it.second, 0, 0, 0);
}
try {
process_code(s.function_code_index->name_to_function.at("VersionDetect"), 0, 0, 0);
process_code(s.function_code_index->name_to_function.at("VersionDetectGC"), 0, 0, 0);
} catch (const out_of_range&) {
}
try {
process_code(s.function_code_index->name_to_function.at("VersionDetectXB"), 0, 0, 0);
} catch (const out_of_range&) {
}
try {
+5 -5
View File
@@ -240,7 +240,7 @@ static void send_main_menu(shared_ptr<Client> c) {
if (!s->is_replay) {
if (!s->function_code_index->patch_menu_empty(c->config.specific_version)) {
main_menu->items.emplace_back(MainMenuItemID::PATCHES, "Patches",
"Change game\nbehaviors", MenuItem::Flag::GC_ONLY | MenuItem::Flag::REQUIRES_SEND_FUNCTION_CALL);
"Change game\nbehaviors", MenuItem::Flag::INVISIBLE_ON_DC | MenuItem::Flag::INVISIBLE_ON_PC | MenuItem::Flag::REQUIRES_SEND_FUNCTION_CALL);
}
if (!s->dol_file_index->empty()) {
main_menu->items.emplace_back(MainMenuItemID::PROGRAMS, "Programs",
@@ -877,10 +877,10 @@ static void on_9D_9E(shared_ptr<Client> c, uint16_t command, uint32_t, string& d
c->channel.language = base_cmd->language;
set_console_client_flags(c, base_cmd->sub_version);
// See system/ppc/Episode3USAQuestBufferOverflow.s for where this value gets
// set. We use this to determine if the client has already run the code or
// not; sending it again when the client has already run it will likely cause
// the client to crash.
// See system/client-functions/Episode3USAQuestBufferOverflow.ppc.s for where
// this value gets set. We use this to determine if the client has already run
// the code or not; sending it again when the client has already run it will
// likely cause the client to crash.
if (base_cmd->unused1 == 0x5F5CA297) {
c->config.clear_flag(Client::Flag::USE_OVERFLOW_FOR_SEND_FUNCTION_CALL);
c->config.clear_flag(Client::Flag::NO_SEND_FUNCTION_CALL);
+5 -3
View File
@@ -322,7 +322,7 @@ void send_update_client_config(shared_ptr<Client> c, bool always_send) {
void send_quest_buffer_overflow(shared_ptr<Client> c) {
// PSO Episode 3 USA doesn't natively support the B2 command, but we can add
// it back to the game with some tricky commands. For details on how this
// works, see system/ppc/Episode3USAQuestBufferOverflow.s.
// works, see system/client-functions/Episode3USAQuestBufferOverflow.ppc.s.
auto fn = c->require_server_state()->function_code_index->name_to_function.at("Episode3USAQuestBufferOverflow");
if (fn->code.size() > 0x400) {
throw runtime_error("Episode 3 buffer overflow code must be a single segment");
@@ -355,9 +355,11 @@ void prepare_client_for_patches(shared_ptr<Client> c, function<void()> on_comple
if (!c) {
return;
}
if (is_gc(c->version()) &&
bool is_gc = ::is_gc(c->version());
bool is_xb = (c->version() == Version::XB_V3);
if ((is_gc || is_xb) &&
c->config.specific_version == default_specific_version_for_version(c->version(), -1)) {
send_function_call(c, s->function_code_index->name_to_function.at("VersionDetect"));
send_function_call(c, s->function_code_index->name_to_function.at(is_xb ? "VersionDetectXB" : "VersionDetectGC"));
c->function_call_response_queue.emplace_back([wc = weak_ptr<Client>(c), on_complete](uint32_t specific_version, uint32_t) -> void {
auto c = wc.lock();
if (!c) {
+1 -1
View File
@@ -1427,7 +1427,7 @@ void ServerState::load_quest_index() {
void ServerState::compile_functions() {
config_log.info("Compiling client functions");
this->function_code_index = make_shared<FunctionCodeIndex>("system/ppc");
this->function_code_index = make_shared<FunctionCodeIndex>("system/client-functions");
}
void ServerState::load_dol_files() {
+42 -1
View File
@@ -204,7 +204,7 @@ uint32_t default_specific_version_for_version(Version version, int64_t sub_versi
// to set the specific_version based on sub_version. Fortunately, all
// versions that share sub_version values also support send_function_call,
// so for those versions we get the specific_version later by sending the
// VersionDetect call.
// VersionDetectGC or VersionDetectXB call.
switch (version) {
case Version::GC_NTE:
return 0x334F4A54; // 3OJT
@@ -242,11 +242,52 @@ uint32_t default_specific_version_for_version(Version version, int64_t sub_versi
default:
return 0x33000000;
}
case Version::XB_V3:
return 0x344F0000;
case Version::BB_V4:
return 0x354F3030;
default:
return 0x00000000;
}
}
bool specific_version_is_gc(uint32_t specific_version) {
// GC specific_versions are 3GRV, where G is [OE], R is [JEP], V is [0-9T]
if ((specific_version & 0xFF000000) != 0x33000000) {
return false;
}
char game = specific_version >> 16;
if ((game != 'O') && (game != 'S')) {
return false;
}
char region = specific_version >> 8;
if ((region != 'J') && (region != 'E') && (region != 'P')) {
return false;
}
char revision = specific_version;
return (isdigit(revision) || (revision == 'T'));
}
bool specific_version_is_xb(uint32_t specific_version) {
// XB specific_versions are 4ORV, where R is [JEP], V is [BDU]
if ((specific_version & 0xFFFF0000) != 0x344F0000) {
return false;
}
char region = specific_version >> 8;
if ((region != 'J') && (region != 'E') && (region != 'P')) {
return false;
}
char revision = specific_version;
return ((revision == 'B') || (revision == 'D') || (revision == 'U'));
}
bool specific_version_is_bb(uint32_t specific_version) {
// TODO: We should actually find a way to determine BB specific_versions, but
// there are so many mods out there, and there's a patch server anyway, so it
// seems not worth the effort
return specific_version == 0x35303030;
}
const char* file_path_token_for_version(Version version) {
switch (version) {
case Version::PC_PATCH:
+3
View File
@@ -139,6 +139,9 @@ inline bool uses_utf16(Version version) {
}
uint32_t default_specific_version_for_version(Version version, int64_t sub_version);
bool specific_version_is_gc(uint32_t specific_version);
bool specific_version_is_xb(uint32_t specific_version);
bool specific_version_is_bb(uint32_t specific_version);
enum class ServerBehavior {
PC_CONSOLE_DETECT = 0,
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 8000B088 (88 bytes)
.data 0x8000B088 # address
.data 0x00000058 # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 8000B088 (88 bytes)
.data 0x8000B088 # address
.data 0x00000058 # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 8000B088 (88 bytes)
.data 0x8000B088 # address
.data 0x00000058 # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 8000B088 (88 bytes)
.data 0x8000B088 # address
.data 0x00000058 # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 8000B088 (88 bytes)
.data 0x8000B088 # address
.data 0x00000058 # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 8000B088 (88 bytes)
.data 0x8000B088 # address
.data 0x00000058 # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 8000B088 (88 bytes)
.data 0x8000B088 # address
.data 0x00000058 # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 8000B088 (88 bytes)
.data 0x8000B088 # address
.data 0x00000058 # size
@@ -18,7 +18,7 @@ patch:
mfctr r6
mr r3, r6
li r4, 0x7C00
.include FlushCachedCode
.include FlushCachedCode-GC
mtctr r6
bctr
patch_end:
@@ -67,7 +67,7 @@ location_ok:
# r5 = patch size in bytes
# r6 = destination location
# r7 = saved LR
.include CopyCode
.include CopyCode-GC
setup_branch:
# Replace the bctrl opcode that led to this call with a bl opcode that
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 8000D6A0 (28 bytes)
.data 0x8000D6A0 # address
.data 0x0000001C # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 8000D6A0 (28 bytes)
.data 0x8000D6A0 # address
.data 0x0000001C # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 8000D6A0 (28 bytes)
.data 0x8000D6A0 # address
.data 0x0000001C # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 8000D6A0 (28 bytes)
.data 0x8000D6A0 # address
.data 0x0000001C # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 8000D6A0 (28 bytes)
.data 0x8000D6A0 # address
.data 0x0000001C # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 8000D6A0 (28 bytes)
.data 0x8000D6A0 # address
.data 0x0000001C # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 8000D6A0 (28 bytes)
.data 0x8000D6A0 # address
.data 0x0000001C # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 8000D6A0 (28 bytes)
.data 0x8000D6A0 # address
.data 0x0000001C # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 8000BAB4 (156 bytes)
.data 0x8000BAB4 # address
.data 0x0000009C # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 8000BAB4 (156 bytes)
.data 0x8000BAB4 # address
.data 0x0000009C # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 8000BAB4 (156 bytes)
.data 0x8000BAB4 # address
.data 0x0000009C # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 8000BAB4 (156 bytes)
.data 0x8000BAB4 # address
.data 0x0000009C # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 8000BAB4 (156 bytes)
.data 0x8000BAB4 # address
.data 0x0000009C # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 8000BAB4 (156 bytes)
.data 0x8000BAB4 # address
.data 0x0000009C # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 8000BAB4 (156 bytes)
.data 0x8000BAB4 # address
.data 0x0000009C # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 8000BAB4 (156 bytes)
.data 0x8000BAB4 # address
.data 0x0000009C # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 802ABDB8 (4 bytes)
.data 0x802ABDB8 # address
.data 0x00000004 # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 802ABDFC (4 bytes)
.data 0x802ABDFC # address
.data 0x00000004 # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 802AD338 (4 bytes)
.data 0x802AD338 # address
.data 0x00000004 # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 802AB3FC (4 bytes)
.data 0x802AB3FC # address
.data 0x00000004 # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 802AC2A4 (4 bytes)
.data 0x802AC2A4 # address
.data 0x00000004 # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 802AD3D0 (4 bytes)
.data 0x802AD3D0 # address
.data 0x00000004 # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 802AD184 (4 bytes)
.data 0x802AD184 # address
.data 0x00000004 # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 802ACACC (4 bytes)
.data 0x802ACACC # address
.data 0x00000004 # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 803515F4 (152 bytes)
.data 0x803515F4 # address
.data 0x00000098 # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 80351638 (152 bytes)
.data 0x80351638 # address
.data 0x00000098 # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 80353220 (152 bytes)
.data 0x80353220 # address
.data 0x00000098 # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 80350740 (152 bytes)
.data 0x80350740 # address
.data 0x00000098 # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 80351B44 (152 bytes)
.data 0x80351B44 # address
.data 0x00000098 # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 803530A0 (152 bytes)
.data 0x803530A0 # address
.data 0x00000098 # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 80352E54 (152 bytes)
.data 0x80352E54 # address
.data 0x00000098 # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 80352614 (152 bytes)
.data 0x80352614 # address
.data 0x00000098 # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 8000DFA0 (64 bytes)
.data 0x8000DFA0 # address
.data 0x00000040 # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 8000DFA0 (64 bytes)
.data 0x8000DFA0 # address
.data 0x00000040 # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 8000DFA0 (64 bytes)
.data 0x8000DFA0 # address
.data 0x00000040 # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 8000DFA0 (64 bytes)
.data 0x8000DFA0 # address
.data 0x00000040 # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 8000DFA0 (64 bytes)
.data 0x8000DFA0 # address
.data 0x00000040 # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 8000DFA0 (64 bytes)
.data 0x8000DFA0 # address
.data 0x00000040 # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 8000DFA0 (64 bytes)
.data 0x8000DFA0 # address
.data 0x00000040 # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 8000DFA0 (64 bytes)
.data 0x8000DFA0 # address
.data 0x00000040 # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 80261B9C (4 bytes)
.data 0x80261B9C # address
.data 0x00000004 # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 80261B9C (4 bytes)
.data 0x80261B9C # address
.data 0x00000004 # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 80262F5C (4 bytes)
.data 0x80262F5C # address
.data 0x00000004 # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 802612C4 (4 bytes)
.data 0x802612C4 # address
.data 0x00000004 # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 80261E9C (4 bytes)
.data 0x80261E9C # address
.data 0x00000004 # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 80262EE4 (4 bytes)
.data 0x80262EE4 # address
.data 0x00000004 # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 80262C98 (4 bytes)
.data 0x80262C98 # address
.data 0x00000004 # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 802627A4 (4 bytes)
.data 0x802627A4 # address
.data 0x00000004 # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 8000BF30 (44 bytes)
.data 0x8000BF30 # address
.data 0x0000002C # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 8000BF30 (44 bytes)
.data 0x8000BF30 # address
.data 0x0000002C # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 8000BF30 (44 bytes)
.data 0x8000BF30 # address
.data 0x0000002C # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 8000BF30 (44 bytes)
.data 0x8000BF30 # address
.data 0x0000002C # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 8000BF30 (44 bytes)
.data 0x8000BF30 # address
.data 0x0000002C # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 8000BF30 (44 bytes)
.data 0x8000BF30 # address
.data 0x0000002C # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 8000BF30 (44 bytes)
.data 0x8000BF30 # address
.data 0x0000002C # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 8000BF30 (44 bytes)
.data 0x8000BF30 # address
.data 0x0000002C # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 801151A8 (4 bytes)
.data 0x801151A8 # address
.data 0x00000004 # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 801151A8 (4 bytes)
.data 0x801151A8 # address
.data 0x00000004 # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 801150C0 (4 bytes)
.data 0x801150C0 # address
.data 0x00000004 # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 80114F04 (4 bytes)
.data 0x80114F04 # address
.data 0x00000004 # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 80115118 (4 bytes)
.data 0x80115118 # address
.data 0x00000004 # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 8011521C (4 bytes)
.data 0x8011521C # address
.data 0x00000004 # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 801150B0 (4 bytes)
.data 0x801150B0 # address
.data 0x00000004 # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 80115298 (4 bytes)
.data 0x80115298 # address
.data 0x00000004 # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 801D381C (4 bytes)
.data 0x801D381C # address
.data 0x00000004 # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 801D381C (4 bytes)
.data 0x801D381C # address
.data 0x00000004 # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 801D3A1C (4 bytes)
.data 0x801D3A1C # address
.data 0x00000004 # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 801D33E4 (4 bytes)
.data 0x801D33E4 # address
.data 0x00000004 # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 801D38EC (4 bytes)
.data 0x801D38EC # address
.data 0x00000004 # size
@@ -6,7 +6,7 @@ entry_ptr:
reloc0:
.offsetof start
start:
.include WriteCodeBlocks
.include WriteCodeBlocksGC
# region @ 801D3CC4 (4 bytes)
.data 0x801D3CC4 # address
.data 0x00000004 # size

Some files were not shown because too many files have changed in this diff Show More