64 lines
2.5 KiB
C++
64 lines
2.5 KiB
C++
#include <loaders/dol.hpp>
|
|
#include <mem.hpp>
|
|
#include <ircolib/file.hpp>
|
|
#include <ircolib/mem_access.hpp>
|
|
#include <array>
|
|
#include <print>
|
|
|
|
namespace weee::core {
|
|
bool load_dol(const std::string &path, mem &mem) {
|
|
auto bin = ircolib::read_file_binary(path);
|
|
if (bin.size() <= 0)
|
|
return false;
|
|
|
|
struct header {
|
|
struct section {
|
|
ircolib::u32 offset, addr, size;
|
|
};
|
|
std::array<section, 7> text;
|
|
std::array<section, 11> data;
|
|
ircolib::u32 bss_address, bss_size, entry_point;
|
|
} hdr;
|
|
|
|
for (size_t bin_index = 0; bin_index < 0xD8; bin_index += 4) {
|
|
if (ircolib::is_inside_range_ext(bin_index, 0, 0x1c)) // text file offsets
|
|
hdr.text[bin_index / 4].offset = std::byteswap(ircolib::read_access<ircolib::u32>(bin, bin_index));
|
|
|
|
if (ircolib::is_inside_range_ext(bin_index, 0x1c, 0x48)) // data file offsets
|
|
hdr.data[(bin_index - 0x1c) / 4].offset = std::byteswap(ircolib::read_access<ircolib::u32>(bin, bin_index));
|
|
|
|
if (ircolib::is_inside_range_ext(bin_index, 0x48, 0x64)) // text loading addresses
|
|
hdr.text[(bin_index - 0x48) / 4].addr = std::byteswap(ircolib::read_access<ircolib::u32>(bin, bin_index));
|
|
|
|
if (ircolib::is_inside_range_ext(bin_index, 0x64, 0x90)) // data loading addresses
|
|
hdr.data[(bin_index - 0x64) / 4].addr = std::byteswap(ircolib::read_access<ircolib::u32>(bin, bin_index));
|
|
|
|
if (ircolib::is_inside_range_ext(bin_index, 0x90, 0xac)) // text sizes
|
|
hdr.text[(bin_index - 0x90) / 4].size = std::byteswap(ircolib::read_access<ircolib::u32>(bin, bin_index));
|
|
|
|
if (ircolib::is_inside_range_ext(bin_index, 0xac, 0xd8)) // data sizes
|
|
hdr.data[(bin_index - 0xac) / 4].size = std::byteswap(ircolib::read_access<ircolib::u32>(bin, bin_index));
|
|
}
|
|
|
|
hdr.bss_address = std::byteswap(ircolib::read_access<ircolib::u32>(bin, 0xD8));
|
|
hdr.bss_size = std::byteswap(ircolib::read_access<ircolib::u32>(bin, 0xDC));
|
|
mem.set(0, hdr.bss_size, hdr.bss_address & 0x0FFFFFFF);
|
|
|
|
hdr.entry_point = std::byteswap(ircolib::read_access<ircolib::u32>(bin, 0xE0));
|
|
|
|
for (const auto §ion : hdr.text) {
|
|
if (section.offset == 0)
|
|
continue;
|
|
mem.copy(&bin[section.offset], section.size, section.addr & 0x0FFFFFFF);
|
|
}
|
|
|
|
for (const auto §ion : hdr.data) {
|
|
if (section.offset == 0)
|
|
continue;
|
|
mem.copy(&bin[section.offset], section.size, section.addr & 0x0FFFFFFF);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
} // namespace weee::core
|