Files
ircolib/core/loaders/dol.cpp
T

65 lines
2.6 KiB
C++

#include <loaders/dol.hpp>
#include <mem.hpp>
#include <broadway.hpp>
#include <ircolib/file.hpp>
#include <ircolib/mem_access.hpp>
#include <array>
namespace weee::core {
bool load_dol(const std::string &path, mem &mem, broadway &broadway) {
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(bin_index, 0, 0x1b)) // text file offsets
hdr.text[bin_index / 4].offset = std::byteswap(ircolib::read_access<ircolib::u32>(bin, bin_index));
if (ircolib::is_inside_range(bin_index, 0x1c, 0x47)) // 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(bin_index, 0x48, 0x63)) // 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(bin_index, 0x64, 0x8f)) // 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(bin_index, 0x90, 0xab)) // text sizes
hdr.text[(bin_index - 0x90) / 4].size = std::byteswap(ircolib::read_access<ircolib::u32>(bin, bin_index));
if (ircolib::is_inside_range(bin_index, 0xac, 0xd7)) // 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));
broadway.set_pc(hdr.entry_point);
for (const auto &section : hdr.text) {
if (section.offset == 0)
continue;
mem.copy(&bin[section.offset], section.size, section.addr & 0x0FFFFFFF);
}
for (const auto &section : hdr.data) {
if (section.offset == 0)
continue;
mem.copy(&bin[section.offset], section.size, section.addr & 0x0FFFFFFF);
}
return true;
}
} // namespace weee::core