142 lines
3.8 KiB
C++
142 lines
3.8 KiB
C++
//---------------------------------------------------------------------------//
|
|
// 1100101 |_ mov #0, r4 __ //
|
|
// 11 |_ <0xb380 %5c4> / _|_ _____ ___ //
|
|
// 0110 |_ 3.50 -> 3.60 | _\ \ / _ (_-< //
|
|
// |_ base# + offset |_| /_\_\___/__/ //
|
|
//---------------------------------------------------------------------------//
|
|
|
|
#include <fxos/memory.h>
|
|
#include <stdexcept>
|
|
#include <array>
|
|
|
|
namespace FxOS {
|
|
|
|
MemoryArea MemoryArea::U0 = {0x00000000, 0x7fffffff, "U0"};
|
|
MemoryArea MemoryArea::P0 = {0x00000000, 0x7fffffff, "P0"};
|
|
MemoryArea MemoryArea::P1 = {0x80000000, 0x9fffffff, "P1"};
|
|
MemoryArea MemoryArea::P2 = {0xa0000000, 0xbfffffff, "P2"};
|
|
MemoryArea MemoryArea::P3 = {0xc0000000, 0xdfffffff, "P3"};
|
|
MemoryArea MemoryArea::P4 = {0xe0000000, 0xffffffff, "P4"};
|
|
|
|
//---
|
|
// Fine memory region management
|
|
//---
|
|
|
|
MemoryRegion::MemoryRegion():
|
|
name {"null"}, start {0x00000000}, end {0x00000000}, writable {false}
|
|
{
|
|
}
|
|
|
|
MemoryRegion::MemoryRegion(
|
|
std::string name, uint32_t start, uint32_t end, bool writable):
|
|
name {name},
|
|
start {start}, end {end}, writable {writable}
|
|
{
|
|
this->guess_flags();
|
|
}
|
|
|
|
uint32_t MemoryRegion::size() const noexcept
|
|
{
|
|
return end - start;
|
|
}
|
|
|
|
MemoryArea MemoryRegion::area() const noexcept
|
|
{
|
|
using Area = MemoryArea;
|
|
static Area areas[5] = {Area::P4, Area::P3, Area::P2, Area::P1, Area::P0};
|
|
|
|
for(int i = 0; i < 5; i++) {
|
|
if(start >= areas[i].start)
|
|
return areas[i];
|
|
}
|
|
|
|
return Area::P0;
|
|
}
|
|
|
|
void MemoryRegion::guess_flags() noexcept
|
|
{
|
|
MemoryArea area = this->area();
|
|
|
|
if(area == MemoryArea::U0 || area == MemoryArea::P0
|
|
|| area == MemoryArea::P3) {
|
|
cacheable = true;
|
|
mappable = true;
|
|
}
|
|
else if(area == MemoryArea::P1) {
|
|
cacheable = true;
|
|
mappable = false;
|
|
}
|
|
else if(area == MemoryArea::P2 || area == MemoryArea::P4) {
|
|
cacheable = false;
|
|
mappable = false;
|
|
}
|
|
else {
|
|
cacheable = false;
|
|
mappable = false;
|
|
}
|
|
}
|
|
|
|
using R = MemoryRegion;
|
|
|
|
/* Basic memory regions */
|
|
// clang-format off
|
|
R const R::ROM ("ROM", 0x80000000, 0x81ffffff, false);
|
|
R const R::ROM_P2 ("ROM_P2", 0xa0000000, 0xa07fffff, false);
|
|
R const R::RAM ("RAM", 0x88000000, 0x881fffff, true);
|
|
R const R::RAM_P2 ("RAM_P2", 0xa8000000, 0xa81fffff, true);
|
|
R const R::RAM_8C ("RAM_8C", 0x8c000000, 0x8c7fffff, true);
|
|
R const R::RAM_8C_P2("RAM_8C_P2", 0xac000000, 0xac7fffff, true);
|
|
R const R::RS ("RS", 0xfd800000, 0xfd8007ff, true);
|
|
R const R::ILRAM ("ILRAM", 0xe5200000, 0xe5203fff, true);
|
|
R const R::XRAM ("XRAM", 0xe5007000, 0xe5008fff, true);
|
|
R const R::YRAM ("YRAM", 0xe5017000, 0xe5018fff, true);
|
|
// clang-format on
|
|
|
|
std::array<MemoryRegion const *, 10> const MemoryRegion::m_all = {
|
|
&R::ROM,
|
|
&R::ROM_P2,
|
|
&R::RAM,
|
|
&R::RAM_P2,
|
|
&R::RAM_8C,
|
|
&R::RAM_8C_P2,
|
|
&R::RS,
|
|
&R::ILRAM,
|
|
&R::XRAM,
|
|
&R::YRAM,
|
|
};
|
|
|
|
std::array<MemoryRegion const *, 10> const &MemoryRegion::all()
|
|
{
|
|
return m_all;
|
|
}
|
|
|
|
MemoryRegion const *MemoryRegion::region_for(uint32_t address)
|
|
{
|
|
for(auto r: MemoryRegion::all()) {
|
|
if(r->start <= address && address < r->end)
|
|
return r;
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
MemoryRegion const *MemoryRegion::region_for(MemoryRegion region)
|
|
{
|
|
for(auto r: MemoryRegion::all()) {
|
|
if(r->start <= region.start && region.end <= r->end)
|
|
return r;
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
MemoryRegion::MemoryRegion(std::string name): MemoryRegion()
|
|
{
|
|
for(auto r: MemoryRegion::all()) {
|
|
if(r->name == name) {
|
|
*this = *r;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
} /* namespace FxOS */
|