#include #include #include namespace FxOS { //--- // Overview of the memory areas //--- uint32_t MemoryArea::start() const noexcept { switch(m_name) { case U0: return 0x00000000; case P0: return 0x00000000; case P1: return 0x80000000; case P2: return 0xa0000000; case P3: return 0xc0000000; case P4: return 0xe0000000; } return 0; } uint32_t MemoryArea::end() const noexcept { switch(m_name) { case U0: return 0x7fffffff; case P0: return 0x7fffffff; case P1: return 0x9fffffff; case P2: return 0xbfffffff; case P3: return 0xdfffffff; case P4: return 0xffffffff; } return -1; } uint32_t MemoryArea::size() const noexcept { return this->end() - this->start() + 1; } //--- // 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; 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 { switch(this->area()) { case MemoryArea::U0: case MemoryArea::P0: case MemoryArea::P3: cacheable = true; mappable = true; break; case MemoryArea::P1: cacheable = true; mappable = false; break; case MemoryArea::P2: case MemoryArea::P4: cacheable = false; mappable = false; break; } } using R = MemoryRegion; /* Basic memory regions */ R const &R::ROM = MemoryRegion("ROM", 0x80000000, 0x81ffffff, false); R const &R::RAM = MemoryRegion("RAM", 0x88000000, 0x88040000, true); R const &R::ROM_P2 = MemoryRegion("ROM_P2", 0xa0000000, 0xa07fffff, false); R const &R::RAM_P2 = MemoryRegion("RAM_P2", 0xa8000000, 0xa8040000, true); R const &R::RS = MemoryRegion("RS", 0xfd800000, 0xfd8007ff, true); R const &R::ILRAM = MemoryRegion("ILRAM", 0xe5200000, 0xe5203fff, true); R const &R::XRAM = MemoryRegion("XRAM", 0xe5007000, 0xe5008fff, true); R const &R::YRAM = MemoryRegion("YRAM", 0xe5017000, 0xe5018fff, true); MemoryRegion const *MemoryRegion::region_for(uint32_t address) { MemoryRegion const *regs[8] = { &R::ROM, &R::RAM, &R::ROM_P2, &R::RAM_P2, &R::RS, &R::ILRAM, &R::XRAM, &R::YRAM }; for(int i = 0; i < 8; i++) { if(regs[i]->start <= address && address < regs[i]->end) return regs[i]; } return nullptr; } MemoryRegion::MemoryRegion(std::string name) { MemoryRegion const *regs[8] = { &R::ROM, &R::RAM, &R::ROM_P2, &R::RAM_P2, &R::RS, &R::ILRAM, &R::XRAM, &R::YRAM }; for(int i = 0; i < 8; i++) { if(regs[i]->name == name) { *this = *regs[i]; return; } } throw std::runtime_error("No standard region named '" + name + "'"); } } /* namespace FxOS */