diff --git a/Core/BaseCartridge.cpp b/Core/BaseCartridge.cpp index 2035cbf..767c626 100644 --- a/Core/BaseCartridge.cpp +++ b/Core/BaseCartridge.cpp @@ -262,35 +262,6 @@ void BaseCartridge::SaveBattery() } } -void BaseCartridge::MapBanks(MemoryManager &mm, vector> &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; } diff --git a/Core/BaseCartridge.h b/Core/BaseCartridge.h index 8a6b0cc..83074d0 100644 --- a/Core/BaseCartridge.h +++ b/Core/BaseCartridge.h @@ -34,8 +34,6 @@ private: uint32_t _prgRomSize = 0; uint32_t _saveRamSize = 0; - void MapBanks(MemoryManager &mm, vector> &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); diff --git a/Core/Core.vcxproj.filters b/Core/Core.vcxproj.filters index 01ed89f..e30af12 100644 --- a/Core/Core.vcxproj.filters +++ b/Core/Core.vcxproj.filters @@ -485,11 +485,15 @@ Debugger\Scripts - - SNES\Coprocessors + + SNES + + + Debugger\Disassembler + diff --git a/Core/MemoryManager.cpp b/Core/MemoryManager.cpp index 172cbf3..18539a4 100644 --- a/Core/MemoryManager.cpp +++ b/Core/MemoryManager.cpp @@ -51,26 +51,20 @@ void MemoryManager::Initialize(Console *console) for(uint32_t i = 0; i < 128 * 1024; i += 0x1000) { _workRamHandlers.push_back(unique_ptr(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> &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; + } } } diff --git a/Core/MemoryManager.h b/Core/MemoryManager.h index 9ff59e5..38fff8b 100644 --- a/Core/MemoryManager.h +++ b/Core/MemoryManager.h @@ -29,7 +29,7 @@ private: Cpu* _cpu; IMemoryHandler* _handlers[0x100 * 0x10]; - vector> _workRamHandlers; + vector> _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>& 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(); diff --git a/Core/NecDsp.cpp b/Core/NecDsp.cpp index 5e15e8a..292184e 100644 --- a/Core/NecDsp.cpp +++ b/Core/NecDsp.cpp @@ -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; }