diff --git a/src/FunctionCompiler.cc b/src/FunctionCompiler.cc index 0d52ccc8..b6f58047 100644 --- a/src/FunctionCompiler.cc +++ b/src/FunctionCompiler.cc @@ -227,7 +227,7 @@ shared_ptr FunctionCodeIndex::patch_menu(uint32_t specific_version) auto suffix = string_printf("-%08" PRIX32, specific_version); shared_ptr ret(new Menu(MenuID::PATCHES, u"Patches")); - ret->items.emplace_back(PatchesMenuItemID::GO_BACK, u"Go back", u"", 0); + ret->items.emplace_back(PatchesMenuItemID::GO_BACK, u"Go back", u"Return to the\nmain menu", 0); for (const auto& it : this->name_and_specific_version_to_patch_function) { const auto& fn = it.second; if (!fn->hide_from_patches_menu && ends_with(it.first, suffix)) { @@ -259,7 +259,7 @@ DOLFileIndex::DOLFileIndex(const string& directory) { shared_ptr menu(new Menu(MenuID::PROGRAMS, u"Programs")); this->menu = menu; - menu->items.emplace_back(ProgramsMenuItemID::GO_BACK, u"Go back", u"", 0); + menu->items.emplace_back(ProgramsMenuItemID::GO_BACK, u"Go back", u"Return to the\nmain menu", 0); uint32_t next_menu_item_id = 0; for (const auto& filename : list_directory(directory)) { diff --git a/src/ReceiveCommands.cc b/src/ReceiveCommands.cc index 20e3ad77..7027219a 100644 --- a/src/ReceiveCommands.cc +++ b/src/ReceiveCommands.cc @@ -1733,6 +1733,13 @@ static void on_10(shared_ptr s, shared_ptr c, break; case MainMenuItemID::PROGRAMS: + if (!function_compiler_available()) { + throw runtime_error("function compiler not available"); + } + if (c->flags & Client::Flag::NO_SEND_FUNCTION_CALL) { + throw runtime_error("client does not support send_function_call"); + } + send_cache_patch_if_needed(s, c); send_menu(c, s->dol_file_index->menu); break; @@ -2243,7 +2250,11 @@ static void send_dol_file_chunk(shared_ptr s, shared_ptr c, if (offset >= c->loading_dol_file->data.size()) { throw logic_error("DOL file offset beyond end of data"); } - size_t bytes_to_send = min(0x7800, c->loading_dol_file->data.size() - offset); + // Note: The protocol allows commands to be up to 0x7C00 bytes in size, but + // sending large B2 commands can cause the client to crash or softlock. To + // avoid this, we limit the payload to 4KB, which results in a B2 command + // 0x10D0 bytes in size. + size_t bytes_to_send = min(0x1000, c->loading_dol_file->data.size() - offset); string data_to_send = c->loading_dol_file->data.substr(offset, bytes_to_send); auto fn = s->function_code_index->name_to_function.at("WriteMemory"); @@ -2252,8 +2263,7 @@ static void send_dol_file_chunk(shared_ptr s, shared_ptr c, send_function_call(c, fn, label_writes, data_to_send); size_t progress_percent = ((offset + bytes_to_send) * 100) / c->loading_dol_file->data.size(); - string info = string_printf("Loading $C6%s$C7\n%zu%%%% complete", - c->loading_dol_file->name.c_str(), progress_percent); + string info = string_printf("%zu%%%%", progress_percent); send_ship_info(c, decode_sjis(info)); } diff --git a/system/ppc/ReadMemoryWord.s b/system/ppc/ReadMemoryWord.s index aaed8109..d56eacda 100644 --- a/system/ppc/ReadMemoryWord.s +++ b/system/ppc/ReadMemoryWord.s @@ -8,6 +8,7 @@ reloc0: .offsetof start start: + mflr r12 bl read address: .zero diff --git a/system/ppc/RunDOL.s b/system/ppc/RunDOL.s index 19282483..445ffed7 100644 --- a/system/ppc/RunDOL.s +++ b/system/ppc/RunDOL.s @@ -8,7 +8,6 @@ reloc0: .offsetof start start: - disable_interrupts: mfmsr r3 rlwinm r3, r3, 0, 17, 15 @@ -21,7 +20,7 @@ get_current_addr: mflr r31 # TODO: It'd be nice to be able to use an expression for the immediate value # here - something like (dol_base_ptr - start), for example - subi r31, r31, 0x38 # r31 = base of data to copy to low memory (start label) + subi r31, r31, 0x10 # r31 = base of data to copy to low memory (start label) # If this code is not running from low memory (80001800-80003000), then copy # it there and branch to it @@ -54,7 +53,7 @@ copy_code_to_low_memory__again: run_dol: - lwz r30, [r31 + 0x38] # r30 = DOL base ptr + lwz r30, [r31 + 0x10] # r30 = DOL base ptr # DOL files are very simple: they have up to 7 text sections, up to 11 data # sections, and a BSS section and an entrypoint. No imports or other fancy diff --git a/system/ppc/WriteMemory.s b/system/ppc/WriteMemory.s index 8aa09ca5..763c3eee 100644 --- a/system/ppc/WriteMemory.s +++ b/system/ppc/WriteMemory.s @@ -59,6 +59,7 @@ reloc0: .offsetof start start: + mflr r12 bl get_block_ptr mr r6, r3 # r6 = address of dest_addr label