mirror of
https://github.com/N64Recomp/N64ModernRuntime.git
synced 2026-05-10 19:01:53 +00:00
Allow registering sections and overlays
This commit is contained in:
parent
1d26501fe9
commit
9c3da3844a
3 changed files with 45 additions and 23 deletions
|
|
@ -4,12 +4,28 @@
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include "sections.h"
|
#include "sections.h"
|
||||||
|
|
||||||
extern "C" SectionTableEntry* get_section_table();
|
namespace recomp {
|
||||||
extern "C" size_t get_num_sections();
|
namespace overlays {
|
||||||
extern "C" int* get_overlay_sections_by_index();
|
struct section_table_data_t {
|
||||||
|
SectionTableEntry* code_sections;
|
||||||
|
size_t num_code_sections;
|
||||||
|
size_t total_num_sections;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct overlays_by_index_t {
|
||||||
|
int* table;
|
||||||
|
size_t len;
|
||||||
|
};
|
||||||
|
|
||||||
|
void register_overlays(const section_table_data_t& sections, const overlays_by_index_t& overlays);
|
||||||
|
|
||||||
|
extern section_table_data_t sections_info;
|
||||||
|
extern overlays_by_index_t overlays_info;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" void load_overlays(uint32_t rom, int32_t ram_addr, uint32_t size);
|
extern "C" void load_overlays(uint32_t rom, int32_t ram_addr, uint32_t size);
|
||||||
extern "C" void unload_overlays(int32_t ram_addr, uint32_t size);
|
extern "C" void unload_overlays(int32_t ram_addr, uint32_t size);
|
||||||
void init_overlays();
|
void init_overlays();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,19 @@
|
||||||
#include <unordered_map>
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "recomp.h"
|
#include "recomp.h"
|
||||||
#include "recomp_overlays.h"
|
#include "recomp_overlays.h"
|
||||||
#include "sections.h"
|
#include "sections.h"
|
||||||
|
|
||||||
constexpr size_t num_code_sections = ARRLEN(get_section_table());
|
recomp::overlays::section_table_data_t recomp::overlays::sections_info {};
|
||||||
|
recomp::overlays::overlays_by_index_t recomp::overlays::overlays_info {};
|
||||||
|
|
||||||
// SectionTableEntry sections[] defined in recomp_overlays.inl
|
void recomp::overlays::register_overlays(const section_table_data_t& sections, const overlays_by_index_t& overlays) {
|
||||||
|
recomp::overlays::sections_info = sections;
|
||||||
|
recomp::overlays::overlays_info = overlays;
|
||||||
|
}
|
||||||
|
|
||||||
struct LoadedSection {
|
struct LoadedSection {
|
||||||
int32_t loaded_ram_addr;
|
int32_t loaded_ram_addr;
|
||||||
|
|
@ -27,11 +33,13 @@ std::vector<LoadedSection> loaded_sections{};
|
||||||
std::unordered_map<int32_t, recomp_func_t*> func_map{};
|
std::unordered_map<int32_t, recomp_func_t*> func_map{};
|
||||||
|
|
||||||
void load_overlay(size_t section_table_index, int32_t ram) {
|
void load_overlay(size_t section_table_index, int32_t ram) {
|
||||||
const SectionTableEntry& section = get_section_table()[section_table_index];
|
const SectionTableEntry& section = recomp::overlays::sections_info.code_sections[section_table_index];
|
||||||
|
|
||||||
for (size_t function_index = 0; function_index < section.num_funcs; function_index++) {
|
for (size_t function_index = 0; function_index < section.num_funcs; function_index++) {
|
||||||
const FuncEntry& func = section.funcs[function_index];
|
const FuncEntry& func = section.funcs[function_index];
|
||||||
func_map[ram + func.offset] = func.func;
|
func_map[ram + func.offset] = func.func;
|
||||||
}
|
}
|
||||||
|
|
||||||
loaded_sections.emplace_back(ram, section_table_index);
|
loaded_sections.emplace_back(ram, section_table_index);
|
||||||
section_addresses[section.index] = ram;
|
section_addresses[section.index] = ram;
|
||||||
}
|
}
|
||||||
|
|
@ -51,27 +59,25 @@ int32_t* section_addresses = nullptr;
|
||||||
extern "C" void load_overlays(uint32_t rom, int32_t ram_addr, uint32_t size) {
|
extern "C" void load_overlays(uint32_t rom, int32_t ram_addr, uint32_t size) {
|
||||||
// Search for the first section that's included in the loaded rom range
|
// Search for the first section that's included in the loaded rom range
|
||||||
// Sections were sorted by `init_overlays` so we can use the bounds functions
|
// Sections were sorted by `init_overlays` so we can use the bounds functions
|
||||||
auto lower = std::lower_bound(&get_section_table()[0], &get_section_table()[num_code_sections], rom,
|
auto lower = std::lower_bound(&recomp::overlays::sections_info.code_sections[0], &recomp::overlays::sections_info.code_sections[recomp::overlays::sections_info.num_code_sections], rom,
|
||||||
[](const SectionTableEntry& entry, uint32_t addr) {
|
[](const SectionTableEntry& entry, uint32_t addr) {
|
||||||
return entry.rom_addr < addr;
|
return entry.rom_addr < addr;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
auto upper = std::upper_bound(&get_section_table()[0], &get_section_table()[num_code_sections], (uint32_t)(rom + size),
|
auto upper = std::upper_bound(&recomp::overlays::sections_info.code_sections[0], &recomp::overlays::sections_info.code_sections[recomp::overlays::sections_info.num_code_sections], (uint32_t)(rom + size),
|
||||||
[](uint32_t addr, const SectionTableEntry& entry) {
|
[](uint32_t addr, const SectionTableEntry& entry) {
|
||||||
return addr < entry.size + entry.rom_addr;
|
return addr < entry.size + entry.rom_addr;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
// Load the overlays that were found
|
// Load the overlays that were found
|
||||||
for (auto it = lower; it != upper; ++it) {
|
for (auto it = lower; it != upper; ++it) {
|
||||||
load_overlay(std::distance(&get_section_table()[0], it), it->rom_addr - rom + ram_addr);
|
load_overlay(std::distance(&recomp::overlays::sections_info.code_sections[0], it), it->rom_addr - rom + ram_addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void unload_overlays(int32_t ram_addr, uint32_t size);
|
|
||||||
|
|
||||||
extern "C" void unload_overlay_by_id(uint32_t id) {
|
extern "C" void unload_overlay_by_id(uint32_t id) {
|
||||||
uint32_t section_table_index = get_overlay_sections_by_index()[id];
|
uint32_t section_table_index = recomp::overlays::overlays_info.table[id];
|
||||||
const SectionTableEntry& section = get_section_table()[section_table_index];
|
const SectionTableEntry& section = recomp::overlays::sections_info.code_sections[section_table_index];
|
||||||
|
|
||||||
auto find_it = std::find_if(loaded_sections.begin(), loaded_sections.end(), [section_table_index](const LoadedSection& s) { return s.section_table_index == section_table_index; });
|
auto find_it = std::find_if(loaded_sections.begin(), loaded_sections.end(), [section_table_index](const LoadedSection& s) { return s.section_table_index == section_table_index; });
|
||||||
|
|
||||||
|
|
@ -90,8 +96,8 @@ extern "C" void unload_overlay_by_id(uint32_t id) {
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void load_overlay_by_id(uint32_t id, uint32_t ram_addr) {
|
extern "C" void load_overlay_by_id(uint32_t id, uint32_t ram_addr) {
|
||||||
uint32_t section_table_index = get_overlay_sections_by_index()[id];
|
uint32_t section_table_index = recomp::overlays::overlays_info.table[id];
|
||||||
const SectionTableEntry& section = get_section_table()[section_table_index];
|
const SectionTableEntry& section = recomp::overlays::sections_info.code_sections[section_table_index];
|
||||||
int32_t prev_address = section_addresses[section.index];
|
int32_t prev_address = section_addresses[section.index];
|
||||||
if (/*ram_addr >= 0x80000000 && ram_addr < 0x81000000) {*/ prev_address == section.ram_addr) {
|
if (/*ram_addr >= 0x80000000 && ram_addr < 0x81000000) {*/ prev_address == section.ram_addr) {
|
||||||
load_overlay(section_table_index, ram_addr);
|
load_overlay(section_table_index, ram_addr);
|
||||||
|
|
@ -105,7 +111,7 @@ extern "C" void load_overlay_by_id(uint32_t id, uint32_t ram_addr) {
|
||||||
|
|
||||||
extern "C" void unload_overlays(int32_t ram_addr, uint32_t size) {
|
extern "C" void unload_overlays(int32_t ram_addr, uint32_t size) {
|
||||||
for (auto it = loaded_sections.begin(); it != loaded_sections.end();) {
|
for (auto it = loaded_sections.begin(); it != loaded_sections.end();) {
|
||||||
const auto& section = get_section_table()[it->section_table_index];
|
const auto& section = recomp::overlays::sections_info.code_sections[it->section_table_index];
|
||||||
|
|
||||||
// Check if the unloaded region overlaps with the loaded section
|
// Check if the unloaded region overlaps with the loaded section
|
||||||
if (ram_addr < (it->loaded_ram_addr + section.size) && (ram_addr + size) >= it->loaded_ram_addr) {
|
if (ram_addr < (it->loaded_ram_addr + section.size) && (ram_addr + size) >= it->loaded_ram_addr) {
|
||||||
|
|
@ -139,14 +145,14 @@ extern "C" void unload_overlays(int32_t ram_addr, uint32_t size) {
|
||||||
void load_patch_functions();
|
void load_patch_functions();
|
||||||
|
|
||||||
void init_overlays() {
|
void init_overlays() {
|
||||||
section_addresses = (int32_t *)malloc(get_num_sections() * sizeof(int32_t));
|
section_addresses = (int32_t *)malloc(recomp::overlays::sections_info.total_num_sections * sizeof(int32_t));
|
||||||
|
|
||||||
for (size_t section_index = 0; section_index < get_num_sections(); section_index++) {
|
for (size_t section_index = 0; section_index < recomp::overlays::sections_info.total_num_sections; section_index++) {
|
||||||
section_addresses[get_section_table()[section_index].index] = get_section_table()[section_index].ram_addr;
|
section_addresses[recomp::overlays::sections_info.code_sections[section_index].index] = recomp::overlays::sections_info.code_sections[section_index].ram_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort the executable sections by rom address
|
// Sort the executable sections by rom address
|
||||||
std::sort(&get_section_table()[0], &get_section_table()[num_code_sections],
|
std::sort(&recomp::overlays::sections_info.code_sections[0], &recomp::overlays::sections_info.code_sections[recomp::overlays::sections_info.num_code_sections],
|
||||||
[](const SectionTableEntry& a, const SectionTableEntry& b) {
|
[](const SectionTableEntry& a, const SectionTableEntry& b) {
|
||||||
return a.rom_addr < b.rom_addr;
|
return a.rom_addr < b.rom_addr;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,5 +8,5 @@
|
||||||
void load_special_overlay(const SectionTableEntry& section, int32_t ram);
|
void load_special_overlay(const SectionTableEntry& section, int32_t ram);
|
||||||
|
|
||||||
void load_patch_functions() {
|
void load_patch_functions() {
|
||||||
load_special_overlay(get_section_table()[0], get_section_table()[0].ram_addr);
|
load_special_overlay(recomp::overlays::sections_info.code_sections[0], recomp::overlays::sections_info.code_sections[0].ram_addr);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue