Refactor code for memory mappings
This commit is contained in:
parent
17ec59d0e4
commit
add1523e31
6 changed files with 87 additions and 97 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue