From 3154f19467aa606493591687070e1bdd6fd867ab Mon Sep 17 00:00:00 2001 From: Sour Date: Tue, 23 Jun 2020 13:58:59 -0400 Subject: [PATCH] Libretro: Fixed memory map for WRAM/SRAM-based achievements --- Core/Console.cpp | 33 +++++++---------- Core/Console.h | 2 +- Core/MMC1.h | 30 ++++++++-------- Core/MMC1_105.h | 7 ++-- Core/MMC3.h | 14 +++++--- Core/Sunsoft4.h | 7 ++-- Libretro/LibretroSoundManager.h | 2 +- Libretro/libretro.cpp | 64 ++++++++++++--------------------- 8 files changed, 66 insertions(+), 93 deletions(-) diff --git a/Core/Console.cpp b/Core/Console.cpp index 10d2cb1d..e2a5c721 100644 --- a/Core/Console.cpp +++ b/Core/Console.cpp @@ -1463,29 +1463,22 @@ void Console::CopyRewindData(shared_ptr sourceConsole) sourceConsole->Resume(); } -uint8_t* Console::GetRamBuffer(DebugMemoryType memoryType, uint32_t &size, int32_t &startAddr) +uint8_t* Console::GetRamBuffer(uint16_t address) { //Only used by libretro port for achievements - should not be used by anything else. - switch(memoryType) { - default: break; - - case DebugMemoryType::InternalRam: - size = MemoryManager::InternalRAMSize; - startAddr = 0; - return _memoryManager->GetInternalRAM(); - - case DebugMemoryType::SaveRam: - size = _mapper->GetMemorySize(DebugMemoryType::SaveRam); - startAddr = _mapper->FromAbsoluteAddress(0, AddressType::SaveRam); - return _mapper->GetSaveRam(); - - case DebugMemoryType::WorkRam: - size = _mapper->GetMemorySize(DebugMemoryType::WorkRam); - startAddr = _mapper->FromAbsoluteAddress(0, AddressType::WorkRam); - return _mapper->GetWorkRam(); + AddressTypeInfo addrInfo; + _mapper->GetAbsoluteAddressAndType(address, &addrInfo); + + if(addrInfo.Address >= 0) { + if(addrInfo.Type == AddressType::InternalRam) { + return _memoryManager->GetInternalRAM() + addrInfo.Address; + } else if(addrInfo.Type == AddressType::WorkRam) { + return _mapper->GetWorkRam() + addrInfo.Address; + } else if(addrInfo.Type == AddressType::SaveRam) { + return _mapper->GetSaveRam() + addrInfo.Address; + } } - - throw std::runtime_error("unsupported memory type"); + return nullptr; } void Console::DebugAddTrace(const char * log) diff --git a/Core/Console.h b/Core/Console.h index 16b0fe79..eac08c4b 100644 --- a/Core/Console.h +++ b/Core/Console.h @@ -232,7 +232,7 @@ public: void CopyRewindData(shared_ptr sourceConsole); - uint8_t* GetRamBuffer(DebugMemoryType memoryType, uint32_t &size, int32_t &startAddr); + uint8_t* GetRamBuffer(uint16_t address); void DebugAddTrace(const char *log); void DebugProcessPpuCycle(); diff --git a/Core/MMC1.h b/Core/MMC1.h index 050c4872..7ff7b5d4 100644 --- a/Core/MMC1.h +++ b/Core/MMC1.h @@ -119,24 +119,22 @@ class MMC1 : public BaseMapper prgBankSelect = extraReg & 0x10; } - if(_wramDisable && !_forceWramOn) { - RemoveCpuMemoryMapping(0x6000, 0x7FFF); - } else { - if(_saveRamSize + _workRamSize > 0x4000) { - //SXROM, 32kb of save ram - SetCpuMemoryMapping(0x6000, 0x7FFF, (extraReg >> 2) & 0x03, HasBattery() ? PrgMemoryType::SaveRam : PrgMemoryType::WorkRam); - } else if(_saveRamSize + _workRamSize > 0x2000) { - if(_saveRamSize == 0x2000 && _workRamSize == 0x2000) { - //SOROM, half of the 16kb ram is battery backed - SetCpuMemoryMapping(0x6000, 0x7FFF, 0, (extraReg >> 3) & 0x01 ? PrgMemoryType::WorkRam : PrgMemoryType::SaveRam); - } else { - //Unknown, shouldn't happen - SetCpuMemoryMapping(0x6000, 0x7FFF, (extraReg >> 2) & 0x01, HasBattery() ? PrgMemoryType::SaveRam : PrgMemoryType::WorkRam); - } + MemoryAccessType access = _wramDisable && !_forceWramOn ? MemoryAccessType::NoAccess : MemoryAccessType::ReadWrite; + PrgMemoryType memType = HasBattery() ? PrgMemoryType::SaveRam : PrgMemoryType::WorkRam; + if(_saveRamSize + _workRamSize > 0x4000) { + //SXROM, 32kb of save ram + SetCpuMemoryMapping(0x6000, 0x7FFF, (extraReg >> 2) & 0x03, memType, access); + } else if(_saveRamSize + _workRamSize > 0x2000) { + if(_saveRamSize == 0x2000 && _workRamSize == 0x2000) { + //SOROM, half of the 16kb ram is battery backed + SetCpuMemoryMapping(0x6000, 0x7FFF, 0, (extraReg >> 3) & 0x01 ? PrgMemoryType::WorkRam : PrgMemoryType::SaveRam, access); } else { - //Everything else - 8kb of work or save ram - SetCpuMemoryMapping(0x6000, 0x7FFF, 0, HasBattery() ? PrgMemoryType::SaveRam : PrgMemoryType::WorkRam); + //Unknown, shouldn't happen + SetCpuMemoryMapping(0x6000, 0x7FFF, (extraReg >> 2) & 0x01, memType, access); } + } else { + //Everything else - 8kb of work or save ram + SetCpuMemoryMapping(0x6000, 0x7FFF, 0, memType, access); } if(_romInfo.SubMapperID == 5) { diff --git a/Core/MMC1_105.h b/Core/MMC1_105.h index 8a9b0dbd..af25551b 100644 --- a/Core/MMC1_105.h +++ b/Core/MMC1_105.h @@ -62,11 +62,8 @@ protected: case 3: SetMirroringType(MirroringType::Horizontal); break; } - if(_state.RegE000 & 0x10) { - RemoveCpuMemoryMapping(0x6000, 0x7FFF); - } else { - SetCpuMemoryMapping(0x6000, 0x7FFF, 0, HasBattery() ? PrgMemoryType::SaveRam : PrgMemoryType::WorkRam); - } + MemoryAccessType access = (_state.RegE000 & 0x10) ? MemoryAccessType::NoAccess : MemoryAccessType::ReadWrite; + SetCpuMemoryMapping(0x6000, 0x7FFF, 0, HasBattery() ? PrgMemoryType::SaveRam : PrgMemoryType::WorkRam, access); if(_initState == 2) { if(_state.RegA000 & 0x08) { diff --git a/Core/MMC3.h b/Core/MMC3.h index ac4e9a9d..f47926fa 100644 --- a/Core/MMC3.h +++ b/Core/MMC3.h @@ -150,11 +150,15 @@ class MMC3 : public BaseMapper _prgMode = (_state.Reg8000 & 0x40) >> 6; if(_romInfo.MapperID == 4 && _romInfo.SubMapperID == 1) { - //bool wramEnabled = (_state.Reg8000 & 0x20) == 0x20; - RemoveCpuMemoryMapping(0x6000, 0x7000); + //MMC6 + bool wramEnabled = (_state.Reg8000 & 0x20) == 0x20; uint8_t firstBankAccess = (_state.RegA001 & 0x10 ? MemoryAccessType::Write : 0) | (_state.RegA001 & 0x20 ? MemoryAccessType::Read : 0); uint8_t lastBankAccess = (_state.RegA001 & 0x40 ? MemoryAccessType::Write : 0) | (_state.RegA001 & 0x80 ? MemoryAccessType::Read : 0); + if(!wramEnabled) { + firstBankAccess = MemoryAccessType::NoAccess; + lastBankAccess = MemoryAccessType::NoAccess; + } for(int i = 0; i < 4; i++) { SetCpuMemoryMapping(0x7000 + i * 0x400, 0x71FF + i * 0x400, 0, PrgMemoryType::SaveRam, firstBankAccess); @@ -165,11 +169,13 @@ class MMC3 : public BaseMapper _wramWriteProtected = (_state.RegA001 & 0x40) == 0x40; if(_romInfo.SubMapperID == 0) { + MemoryAccessType access; if(_wramEnabled) { - SetCpuMemoryMapping(0x6000, 0x7FFF, 0, HasBattery() ? PrgMemoryType::SaveRam : PrgMemoryType::WorkRam, CanWriteToWorkRam() ? MemoryAccessType::ReadWrite : MemoryAccessType::Read); + access = CanWriteToWorkRam() ? MemoryAccessType::ReadWrite : MemoryAccessType::Read; } else { - RemoveCpuMemoryMapping(0x6000, 0x7FFF); + access = MemoryAccessType::NoAccess; } + SetCpuMemoryMapping(0x6000, 0x7FFF, 0, HasBattery() ? PrgMemoryType::SaveRam : PrgMemoryType::WorkRam, access); } } diff --git a/Core/Sunsoft4.h b/Core/Sunsoft4.h index daa8d3c5..69112fde 100644 --- a/Core/Sunsoft4.h +++ b/Core/Sunsoft4.h @@ -63,11 +63,8 @@ protected: void UpdateState() { - if(!_prgRamEnabled) { - RemoveCpuMemoryMapping(0x6000, 0x7FFF); - } else { - SetupDefaultWorkRam(); - } + MemoryAccessType access = _prgRamEnabled ? MemoryAccessType::ReadWrite : MemoryAccessType::NoAccess; + SetCpuMemoryMapping(0x6000, 0x7FFF, 0, HasBattery() ? PrgMemoryType::SaveRam : PrgMemoryType::WorkRam); if(_usingExternalRom) { if(_licensingTimer == 0) { diff --git a/Libretro/LibretroSoundManager.h b/Libretro/LibretroSoundManager.h index a545830d..37e25f72 100644 --- a/Libretro/LibretroSoundManager.h +++ b/Libretro/LibretroSoundManager.h @@ -28,7 +28,7 @@ public: { if(!_skipMode && _sendAudioSample) { for(uint32_t total = 0; total < sampleCount; ) { - total += _sendAudioSample(soundBuffer + total*2, sampleCount - total); + total += (uint32_t)_sendAudioSample(soundBuffer + total*2, sampleCount - total); } } } diff --git a/Libretro/libretro.cpp b/Libretro/libretro.cpp index b32a293b..b2623ae6 100644 --- a/Libretro/libretro.cpp +++ b/Libretro/libretro.cpp @@ -10,6 +10,8 @@ #include "../Core/Console.h" #include "../Core/VideoDecoder.h" #include "../Core/VideoRenderer.h" +#include "../Core/MemoryManager.h" +#include "../Core/BaseMapper.h" #include "../Core/EmulationSettings.h" #include "../Core/CheatManager.h" #include "../Core/HdData.h" @@ -45,8 +47,6 @@ static unsigned _inputDevices[5] = { DEVICE_AUTO, DEVICE_AUTO, DEVICE_AUTO, DEVI static bool _hdPacksEnabled = false; static string _mesenVersion = ""; static int32_t _saveStateSize = -1; -static struct retro_memory_descriptor _descriptors[3]; -static struct retro_memory_map _memoryMap; static bool _shiftButtonsClockwise = false; static int32_t _audioSampleRate = 44100; @@ -971,40 +971,24 @@ extern "C" { void retro_set_memory_maps() { //Expose internal RAM and work/save RAM for retroachievements - memset(_descriptors, 0, sizeof(_descriptors)); - memset(&_memoryMap, 0, sizeof(_memoryMap)); + retro_memory_descriptor descriptors[256] = {}; + retro_memory_map memoryMap = {}; - uint32_t i = 0; - uint32_t size = 0; - int32_t startAddr = 0; - uint8_t* internalRam = _console->GetRamBuffer(DebugMemoryType::InternalRam, size, startAddr); - _descriptors[i].ptr = internalRam; - _descriptors[i].start = startAddr; - _descriptors[i].len = size; - _descriptors[i].select = 0; - i++; - - uint8_t* saveRam = _console->GetRamBuffer(DebugMemoryType::SaveRam, size, startAddr); - if(size > 0 && startAddr > 0) { - _descriptors[i].ptr = saveRam; - _descriptors[i].start = startAddr; - _descriptors[i].len = size; - _descriptors[i].select = 0; - i++; + int count = 0; + for(int i = 0; i <= 0xFFFF; i += 0x100) { + uint8_t* ram = _console->GetRamBuffer(i); + if(ram) { + descriptors[count].ptr = ram; + descriptors[count].start = i; + descriptors[count].len = 0x100; + count++; + } } - uint8_t* workRam = _console->GetRamBuffer(DebugMemoryType::WorkRam, size, startAddr); - if(size > 0 && startAddr > 0) { - _descriptors[i].ptr = workRam; - _descriptors[i].start = startAddr; - _descriptors[i].len = size; - _descriptors[i].select = 0; - i++; - } + memoryMap.descriptors = descriptors; + memoryMap.num_descriptors = count; - _memoryMap.descriptors = _descriptors; - _memoryMap.num_descriptors = i; - retroEnv(RETRO_ENVIRONMENT_SET_MEMORY_MAPS, &_memoryMap); + retroEnv(RETRO_ENVIRONMENT_SET_MEMORY_MAPS, &memoryMap); } RETRO_API void retro_set_controller_port_device(unsigned port, unsigned device) @@ -1132,23 +1116,21 @@ extern "C" { RETRO_API void *retro_get_memory_data(unsigned id) { - uint32_t size; - int32_t startAddr; + BaseMapper* mapper = _console->GetMapper(); switch(id) { - case RETRO_MEMORY_SAVE_RAM: return _console->GetRamBuffer(DebugMemoryType::SaveRam, size, startAddr); - case RETRO_MEMORY_SYSTEM_RAM: return _console->GetRamBuffer(DebugMemoryType::InternalRam, size, startAddr); + case RETRO_MEMORY_SAVE_RAM: return mapper->GetSaveRam(); + case RETRO_MEMORY_SYSTEM_RAM: return _console->GetMemoryManager()->GetInternalRAM(); } return nullptr; } RETRO_API size_t retro_get_memory_size(unsigned id) { - uint32_t size = 0; - int32_t startAddr; + BaseMapper* mapper = _console->GetMapper(); switch(id) { - case RETRO_MEMORY_SAVE_RAM: _console->GetRamBuffer(DebugMemoryType::SaveRam, size, startAddr); break; - case RETRO_MEMORY_SYSTEM_RAM: _console->GetRamBuffer(DebugMemoryType::InternalRam, size, startAddr); break; + case RETRO_MEMORY_SAVE_RAM: return mapper->GetMemorySize(DebugMemoryType::SaveRam); + case RETRO_MEMORY_SYSTEM_RAM: return MemoryManager::InternalRAMSize; } - return size; + return 0; } }