fix DOL loader
This commit is contained in:
@@ -227,7 +227,7 @@ shared_ptr<const Menu> FunctionCodeIndex::patch_menu(uint32_t specific_version)
|
|||||||
auto suffix = string_printf("-%08" PRIX32, specific_version);
|
auto suffix = string_printf("-%08" PRIX32, specific_version);
|
||||||
|
|
||||||
shared_ptr<Menu> ret(new Menu(MenuID::PATCHES, u"Patches"));
|
shared_ptr<Menu> 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) {
|
for (const auto& it : this->name_and_specific_version_to_patch_function) {
|
||||||
const auto& fn = it.second;
|
const auto& fn = it.second;
|
||||||
if (!fn->hide_from_patches_menu && ends_with(it.first, suffix)) {
|
if (!fn->hide_from_patches_menu && ends_with(it.first, suffix)) {
|
||||||
@@ -259,7 +259,7 @@ DOLFileIndex::DOLFileIndex(const string& directory) {
|
|||||||
|
|
||||||
shared_ptr<Menu> menu(new Menu(MenuID::PROGRAMS, u"Programs"));
|
shared_ptr<Menu> menu(new Menu(MenuID::PROGRAMS, u"Programs"));
|
||||||
this->menu = menu;
|
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;
|
uint32_t next_menu_item_id = 0;
|
||||||
for (const auto& filename : list_directory(directory)) {
|
for (const auto& filename : list_directory(directory)) {
|
||||||
|
|||||||
+13
-3
@@ -1733,6 +1733,13 @@ static void on_10(shared_ptr<ServerState> s, shared_ptr<Client> c,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case MainMenuItemID::PROGRAMS:
|
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);
|
send_menu(c, s->dol_file_index->menu);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -2243,7 +2250,11 @@ static void send_dol_file_chunk(shared_ptr<ServerState> s, shared_ptr<Client> c,
|
|||||||
if (offset >= c->loading_dol_file->data.size()) {
|
if (offset >= c->loading_dol_file->data.size()) {
|
||||||
throw logic_error("DOL file offset beyond end of data");
|
throw logic_error("DOL file offset beyond end of data");
|
||||||
}
|
}
|
||||||
size_t bytes_to_send = min<size_t>(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<size_t>(0x1000, c->loading_dol_file->data.size() - offset);
|
||||||
string data_to_send = c->loading_dol_file->data.substr(offset, bytes_to_send);
|
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");
|
auto fn = s->function_code_index->name_to_function.at("WriteMemory");
|
||||||
@@ -2252,8 +2263,7 @@ static void send_dol_file_chunk(shared_ptr<ServerState> s, shared_ptr<Client> c,
|
|||||||
send_function_call(c, fn, label_writes, data_to_send);
|
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();
|
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",
|
string info = string_printf("%zu%%%%", progress_percent);
|
||||||
c->loading_dol_file->name.c_str(), progress_percent);
|
|
||||||
send_ship_info(c, decode_sjis(info));
|
send_ship_info(c, decode_sjis(info));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ reloc0:
|
|||||||
.offsetof start
|
.offsetof start
|
||||||
|
|
||||||
start:
|
start:
|
||||||
|
mflr r12
|
||||||
bl read
|
bl read
|
||||||
address:
|
address:
|
||||||
.zero
|
.zero
|
||||||
|
|||||||
+2
-3
@@ -8,7 +8,6 @@ reloc0:
|
|||||||
.offsetof start
|
.offsetof start
|
||||||
|
|
||||||
start:
|
start:
|
||||||
|
|
||||||
disable_interrupts:
|
disable_interrupts:
|
||||||
mfmsr r3
|
mfmsr r3
|
||||||
rlwinm r3, r3, 0, 17, 15
|
rlwinm r3, r3, 0, 17, 15
|
||||||
@@ -21,7 +20,7 @@ get_current_addr:
|
|||||||
mflr r31
|
mflr r31
|
||||||
# TODO: It'd be nice to be able to use an expression for the immediate value
|
# 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
|
# 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
|
# If this code is not running from low memory (80001800-80003000), then copy
|
||||||
# it there and branch to it
|
# it there and branch to it
|
||||||
@@ -54,7 +53,7 @@ copy_code_to_low_memory__again:
|
|||||||
|
|
||||||
|
|
||||||
run_dol:
|
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
|
# 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
|
# sections, and a BSS section and an entrypoint. No imports or other fancy
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ reloc0:
|
|||||||
.offsetof start
|
.offsetof start
|
||||||
|
|
||||||
start:
|
start:
|
||||||
|
mflr r12
|
||||||
bl get_block_ptr
|
bl get_block_ptr
|
||||||
mr r6, r3 # r6 = address of dest_addr label
|
mr r6, r3 # r6 = address of dest_addr label
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user