Refactor code for memory mappings

This commit is contained in:
Sour 2019-07-15 18:30:13 -04:00
parent 17ec59d0e4
commit add1523e31
6 changed files with 87 additions and 97 deletions

View file

@ -262,35 +262,6 @@ void BaseCartridge::SaveBattery()
}
}
void BaseCartridge::MapBanks(MemoryManager &mm, vector<unique_ptr<IMemoryHandler>> &handlers, uint8_t startBank, uint8_t endBank, uint16_t startPage, uint16_t endPage, uint16_t pageIncrement, bool mirror, uint16_t startPageNumber)
{
if(handlers.empty()) {
return;
}
while(startPageNumber >= handlers.size()) {
startPageNumber -= (uint32_t)handlers.size();
}
uint32_t pageNumber = startPageNumber;
for(uint32_t i = startBank; i <= endBank; i++) {
uint32_t baseAddress = i << 16;
pageNumber += pageIncrement;
for(uint32_t j = startPage; j <= endPage; j++) {
mm.RegisterHandler(baseAddress + (j * 0x1000), (baseAddress + (j * 0x1000)) | 0xFFF, handlers[pageNumber].get());
//MessageManager::Log("Map [$" + HexUtilities::ToHex(i) + ":" + HexUtilities::ToHex(j)[1] + "xxx] to page number " + HexUtilities::ToHex(pageNumber));
pageNumber++;
if(pageNumber >= handlers.size()) {
if(mirror) {
pageNumber = 0;
} else {
return;
}
}
}
}
}
void BaseCartridge::RegisterHandlers(MemoryManager &mm)
{
for(uint32_t i = 0; i < _prgRomSize; i += 0x1000) {
@ -320,41 +291,41 @@ void BaseCartridge::RegisterHandlers(MemoryManager &mm)
}
if(_flags & CartFlags::LoRom) {
MapBanks(mm, _prgRomHandlers, 0x00, 0x7D, 0x08, 0x0F, 0, true);
MapBanks(mm, _prgRomHandlers, 0x80, 0xFF, 0x08, 0x0F, 0, true);
mm.RegisterHandler(0x00, 0x7D, 0x8000, 0xFFFF, _prgRomHandlers);
mm.RegisterHandler(0x80, 0xFF, 0x8000, 0xFFFF, _prgRomHandlers);
if(_saveRamSize > 0) {
if(_prgRomSize >= 1024 * 1024 * 2) {
//For games >= 2mb in size, put ROM at 70-7D/F0-FF:0000-7FFF (e.g: Fire Emblem: Thracia 776)
MapBanks(mm, _saveRamHandlers, 0x70, 0x7D, 0x00, 0x07, 0, true);
MapBanks(mm, _saveRamHandlers, 0xF0, 0xFF, 0x00, 0x07, 0, true);
mm.RegisterHandler(0x70, 0x7D, 0x0000, 0x7FFF, _saveRamHandlers);
mm.RegisterHandler(0xF0, 0xFF, 0x0000, 0x7FFF, _saveRamHandlers);
} else {
//For games < 2mb in size, put save RAM at 70-7D/F0-FF:0000-FFFF (e.g: Wanderers from Ys)
MapBanks(mm, _saveRamHandlers, 0x70, 0x7D, 0x00, 0x0F, 0, true);
MapBanks(mm, _saveRamHandlers, 0xF0, 0xFF, 0x00, 0x0F, 0, true);
mm.RegisterHandler(0x70, 0x7D, 0x0000, 0xFFFF, _saveRamHandlers);
mm.RegisterHandler(0xF0, 0xFF, 0x0000, 0xFFFF, _saveRamHandlers);
}
}
} else if(_flags & CartFlags::HiRom) {
MapBanks(mm, _prgRomHandlers, 0x00, 0x3F, 0x08, 0x0F, 8, true);
MapBanks(mm, _prgRomHandlers, 0x40, 0x7D, 0x00, 0x0F, 0, true);
MapBanks(mm, _prgRomHandlers, 0x80, 0xBF, 0x08, 0x0F, 8, true);
MapBanks(mm, _prgRomHandlers, 0xC0, 0xFF, 0x00, 0x0F, 0, true);
mm.RegisterHandler(0x00, 0x3F, 0x8000, 0xFFFF, _prgRomHandlers, 8);
mm.RegisterHandler(0x40, 0x7D, 0x0000, 0xFFFF, _prgRomHandlers, 0);
mm.RegisterHandler(0x80, 0xBF, 0x8000, 0xFFFF, _prgRomHandlers, 8);
mm.RegisterHandler(0xC0, 0xFF, 0x0000, 0xFFFF, _prgRomHandlers, 0);
MapBanks(mm, _saveRamHandlers, 0x20, 0x3F, 0x06, 0x07, 0, true);
MapBanks(mm, _saveRamHandlers, 0xA0, 0xBF, 0x06, 0x07, 0, true);
mm.RegisterHandler(0x20, 0x3F, 0x6000, 0x7FFF, _saveRamHandlers);
mm.RegisterHandler(0xA0, 0xBF, 0x6000, 0x7FFF, _saveRamHandlers);
} else if(_flags & CartFlags::ExHiRom) {
//First half is at the end
MapBanks(mm, _prgRomHandlers, 0xC0, 0xFF, 0x00, 0x0F, 0, true);
MapBanks(mm, _prgRomHandlers, 0x80, 0xBF, 0x08, 0x0F, 8, true); //mirror
mm.RegisterHandler(0xC0, 0xFF, 0x0000, 0xFFFF, _prgRomHandlers, 0);
mm.RegisterHandler(0x80, 0xBF, 0x8000, 0xFFFF, _prgRomHandlers, 8); //mirror
//Last part of the ROM is at the start
MapBanks(mm, _prgRomHandlers, 0x40, 0x7D, 0x00, 0x0F, 0, true, 0x400);
MapBanks(mm, _prgRomHandlers, 0x00, 0x3F, 0x08, 0x0F, 8, true, 0x400); //mirror
mm.RegisterHandler(0x40, 0x7D, 0x0000, 0xFFFF, _prgRomHandlers, 0, 0x400);
mm.RegisterHandler(0x00, 0x3F, 0x8000, 0xFFFF, _prgRomHandlers, 8, 0x400); //mirror
//Save RAM
MapBanks(mm, _saveRamHandlers, 0x20, 0x3F, 0x06, 0x07, 0, true);
MapBanks(mm, _saveRamHandlers, 0x70, 0x7D, 0x00, 0x07, 0, true);
MapBanks(mm, _saveRamHandlers, 0xA0, 0xBF, 0x06, 0x07, 0, true);
mm.RegisterHandler(0x20, 0x3F, 0x6000, 0x7FFF, _saveRamHandlers);
mm.RegisterHandler(0x70, 0x7D, 0x0000, 0x7FFF, _saveRamHandlers);
mm.RegisterHandler(0xA0, 0xBF, 0x6000, 0x7FFF, _saveRamHandlers);
}
InitCoprocessor(mm);
@ -372,26 +343,26 @@ bool BaseCartridge::MapSpecificCarts(MemoryManager &mm)
string code = GetGameCode();
if(GetCartName() == "DEZAEMON") {
//LOROM with mirrored SRAM?
MapBanks(mm, _prgRomHandlers, 0x00, 0x7D, 0x08, 0x0F, 0, true);
MapBanks(mm, _prgRomHandlers, 0x80, 0xFF, 0x08, 0x0F, 0, true);
mm.RegisterHandler(0x00, 0x7D, 0x8000, 0xFFFF, _prgRomHandlers);
mm.RegisterHandler(0x80, 0xFF, 0x8000, 0xFFFF, _prgRomHandlers);
MapBanks(mm, _saveRamHandlers, 0x70, 0x7D, 0x00, 0x07, 0, true);
MapBanks(mm, _saveRamHandlers, 0xF0, 0xFF, 0x08, 0x0F, 0, true);
mm.RegisterHandler(0x70, 0x7D, 0x0000, 0x7FFF, _saveRamHandlers);
mm.RegisterHandler(0xF0, 0xFF, 0x8000, 0xFFFF, _saveRamHandlers);
//Mirrors
MapBanks(mm, _saveRamHandlers, 0x70, 0x7D, 0x08, 0x0F, 0, true);
MapBanks(mm, _saveRamHandlers, 0xF0, 0xFF, 0x00, 0x07, 0, true);
mm.RegisterHandler(0x70, 0x7D, 0x8000, 0xFFFF, _saveRamHandlers);
mm.RegisterHandler(0xF0, 0xFF, 0x0000, 0x7FFF, _saveRamHandlers);
return true;
} else if(code == "ZDBJ" || code == "ZR2J" || code == "ZSNJ") {
//BSC-1A5M-02, BSC-1A7M-01
//Games: Sound Novel Tsukuuru, RPG Tsukuuru, Derby Stallion 96
MapBanks(mm, _prgRomHandlers, 0x00, 0x3F, 0x08, 0x0F, 0, true);
MapBanks(mm, _prgRomHandlers, 0x80, 0x9F, 0x08, 0x0F, 0, true, 0x200);
MapBanks(mm, _prgRomHandlers, 0xA0, 0xBF, 0x08, 0x0F, 0, true, 0x100);
mm.RegisterHandler(0x00, 0x3F, 0x8000, 0xFFFF, _prgRomHandlers);
mm.RegisterHandler(0x80, 0x9F, 0x8000, 0xFFFF, _prgRomHandlers, 0, 0x200);
mm.RegisterHandler(0xA0, 0xBF, 0x8000, 0xFFFF, _prgRomHandlers, 0, 0x100);
if(_saveRamSize > 0) {
MapBanks(mm, _saveRamHandlers, 0x70, 0x7D, 0x00, 0x07, 0, true);
MapBanks(mm, _saveRamHandlers, 0xF0, 0xFF, 0x00, 0x07, 0, true);
mm.RegisterHandler(0x70, 0x7D, 0x0000, 0x7FFF, _saveRamHandlers);
mm.RegisterHandler(0xF0, 0xFF, 0x0000, 0x7FFF, _saveRamHandlers);
}
return true;
}

View file

@ -34,8 +34,6 @@ private:
uint32_t _prgRomSize = 0;
uint32_t _saveRamSize = 0;
void MapBanks(MemoryManager &mm, vector<unique_ptr<IMemoryHandler>> &handlers, uint8_t startBank, uint8_t endBank, uint16_t startPage = 0, uint16_t endPage = 0x0F, uint16_t pageIncrement = 0, bool mirror = false, uint16_t startPageNumber = 0);
void LoadBattery();
int32_t GetHeaderScore(uint32_t addr);

View file

@ -485,11 +485,15 @@
<ClCompile Include="ScriptManager.cpp">
<Filter>Debugger\Scripts</Filter>
</ClCompile>
<ClCompile Include="AluMulDiv.cpp" />
<ClCompile Include="NecDspDisUtils.cpp" />
<ClCompile Include="NecDsp.cpp">
<Filter>SNES\Coprocessors</Filter>
</ClCompile>
<ClCompile Include="AluMulDiv.cpp">
<Filter>SNES</Filter>
</ClCompile>
<ClCompile Include="NecDspDisUtils.cpp">
<Filter>Debugger\Disassembler</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Filter Include="SNES">

View file

@ -51,26 +51,20 @@ void MemoryManager::Initialize(Console *console)
for(uint32_t i = 0; i < 128 * 1024; i += 0x1000) {
_workRamHandlers.push_back(unique_ptr<RamHandler>(new RamHandler(_workRam, i, MemoryManager::WorkRamSize, SnesMemoryType::WorkRam)));
RegisterHandler(0x7E0000 | i, 0x7E0000 | (i + 0xFFF), _workRamHandlers[_workRamHandlers.size() - 1].get());
}
for(int i = 0; i <= 0x3F; i++) {
RegisterHandler((i << 16) | 0x2000, (i << 16) | 0x2FFF, _registerHandlerB.get());
RegisterHandler(((i | 0x80) << 16) | 0x2000, ((i | 0x80) << 16) | 0x2FFF, _registerHandlerB.get());
RegisterHandler(0x7E, 0x7F, 0x0000, 0xFFFF, _workRamHandlers);
RegisterHandler((i << 16) | 0x4000, (i << 16) | 0x4FFF, _registerHandlerA.get());
RegisterHandler(((i | 0x80) << 16) | 0x4000, ((i | 0x80) << 16) | 0x4FFF, _registerHandlerA.get());
}
RegisterHandler(0x00, 0x3F, 0x2000, 0x2FFF, _registerHandlerB.get());
RegisterHandler(0x80, 0xBF, 0x2000, 0x2FFF, _registerHandlerB.get());
for(int i = 0; i <= 0x3F; i++) {
RegisterHandler((i << 16) | 0x0000, (i << 16) | 0x0FFF, _workRamHandlers[0].get());
RegisterHandler((i << 16) | 0x1000, (i << 16) | 0x1FFF, _workRamHandlers[1].get());
}
RegisterHandler(0x00, 0x3F, 0x4000, 0x4FFF, _registerHandlerA.get());
RegisterHandler(0x80, 0xBF, 0x4000, 0x4FFF, _registerHandlerA.get());
for(int i = 0x80; i <= 0xBF; i++) {
RegisterHandler((i << 16) | 0x0000, (i << 16) | 0x0FFF, _workRamHandlers[0].get());
RegisterHandler((i << 16) | 0x1000, (i << 16) | 0x1FFF, _workRamHandlers[1].get());
}
RegisterHandler(0x00, 0x3F, 0x0000, 0x0FFF, _workRamHandlers[0].get());
RegisterHandler(0x80, 0xBF, 0x0000, 0x0FFF, _workRamHandlers[0].get());
RegisterHandler(0x00, 0x3F, 0x1000, 0x1FFF, _workRamHandlers[1].get());
RegisterHandler(0x80, 0xBF, 0x1000, 0x1FFF, _workRamHandlers[1].get());
console->GetCartridge()->RegisterHandlers(*this);
@ -90,18 +84,46 @@ void MemoryManager::Reset()
UpdateEvents();
}
void MemoryManager::RegisterHandler(uint32_t startAddr, uint32_t endAddr, IMemoryHandler * handler)
void MemoryManager::RegisterHandler(uint8_t startBank, uint8_t endBank, uint16_t startPage, uint16_t endPage, vector<unique_ptr<IMemoryHandler>> &handlers, uint16_t pageIncrement, uint16_t startPageNumber)
{
if((startAddr & 0xFFF) != 0 || (endAddr & 0xFFF) != 0xFFF) {
if(handlers.empty()) {
return;
}
while(startPageNumber >= handlers.size()) {
startPageNumber -= (uint32_t)handlers.size();
}
uint32_t pageNumber = startPageNumber;
for(uint32_t i = startBank; i <= endBank; i++) {
uint32_t baseAddress = i << 16;
pageNumber += pageIncrement;
for(uint32_t j = startPage; j <= endPage; j+=0x1000) {
_handlers[(i << 4) | (j >> 12)] = handlers[pageNumber].get();
//MessageManager::Log("Map [$" + HexUtilities::ToHex(i) + ":" + HexUtilities::ToHex(j)[1] + "xxx] to page number " + HexUtilities::ToHex(pageNumber));
pageNumber++;
if(pageNumber >= handlers.size()) {
pageNumber = 0;
}
}
}
}
void MemoryManager::RegisterHandler(uint8_t startBank, uint8_t endBank, uint16_t startAddr, uint16_t endAddr, IMemoryHandler* handler)
{
if((startAddr & 0xFFF) != 0 || (endAddr & 0xFFF) != 0xFFF || startBank > endBank || startAddr > endAddr) {
throw std::runtime_error("invalid start/end address");
}
for(uint32_t addr = startAddr; addr < endAddr; addr += 0x1000) {
/*if(_handlers[addr >> 12]) {
throw std::runtime_error("handler already set");
}*/
for(uint32_t bank = startBank; bank <= endBank; bank++) {
for(uint32_t addr = startAddr; addr < endAddr; addr += 0x1000) {
/*if(_handlers[addr >> 12]) {
throw std::runtime_error("handler already set");
}*/
_handlers[addr >> 12] = handler;
_handlers[(bank << 4) | (addr >> 12)] = handler;
}
}
}

View file

@ -29,7 +29,7 @@ private:
Cpu* _cpu;
IMemoryHandler* _handlers[0x100 * 0x10];
vector<unique_ptr<RamHandler>> _workRamHandlers;
vector<unique_ptr<IMemoryHandler>> _workRamHandlers;
uint8_t *_workRam;
uint64_t _masterClock = 0;
@ -51,7 +51,8 @@ public:
void Reset();
void RegisterHandler(uint32_t startAddr, uint32_t endAddr, IMemoryHandler* handler);
void RegisterHandler(uint8_t startBank, uint8_t endBank, uint16_t startPage, uint16_t endPage, vector<unique_ptr<IMemoryHandler>>& handlers, uint16_t pageIncrement = 0, uint16_t startPageNumber = 0);
void RegisterHandler(uint8_t startBank, uint8_t endBank, uint16_t startAddr, uint16_t endAddr, IMemoryHandler* handler);
void GenerateMasterClockTable();

View file

@ -66,18 +66,12 @@ NecDsp* NecDsp::InitCoprocessor(CoprocessorType type, Console *console)
MemoryManager* mm = console->GetMemoryManager().get();
if(console->GetCartridge()->GetCartFlags() & CartFlags::LoRom) {
dsp = new NecDsp(console, biosData, 0x4000);
for(int i = 0x30; i <= 0x3F; i++) {
mm->RegisterHandler((i << 16) | 0x8000, (i << 16) | 0xFFFF, dsp);
mm->RegisterHandler(((i + 0x80) << 16) | 0x8000, ((i + 0x80) << 16) | 0xFFFF, dsp);
}
mm->RegisterHandler(0x30, 0x3F, 0x8000, 0xFFFF, dsp);
mm->RegisterHandler(0xB0, 0xBF, 0x8000, 0xFFFF, dsp);
} else if(console->GetCartridge()->GetCartFlags() & CartFlags::HiRom) {
dsp = new NecDsp(console, biosData, 0x1000);
for(int i = 0; i <= 0x1F; i++) {
mm->RegisterHandler((i << 16) | 0x6000, (i << 16) | 0x7FFF, dsp);
mm->RegisterHandler(((i + 0x80) << 16) | 0x6000, ((i + 0x80) << 16) | 0x7FFF, dsp);
}
mm->RegisterHandler(0x00, 0x1F, 0x6000, 0x7FFF, dsp);
mm->RegisterHandler(0x80, 0x9F, 0x6000, 0x7FFF, dsp);
}
return dsp;
}