Libretro: Fixed memory map for WRAM/SRAM-based achievements

This commit is contained in:
Sour 2020-06-23 13:58:59 -04:00
parent 67b9ba3290
commit 3154f19467
8 changed files with 66 additions and 93 deletions

View file

@ -1463,29 +1463,22 @@ void Console::CopyRewindData(shared_ptr<Console> sourceConsole)
sourceConsole->Resume(); 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. //Only used by libretro port for achievements - should not be used by anything else.
switch(memoryType) { AddressTypeInfo addrInfo;
default: break; _mapper->GetAbsoluteAddressAndType(address, &addrInfo);
case DebugMemoryType::InternalRam: if(addrInfo.Address >= 0) {
size = MemoryManager::InternalRAMSize; if(addrInfo.Type == AddressType::InternalRam) {
startAddr = 0; return _memoryManager->GetInternalRAM() + addrInfo.Address;
return _memoryManager->GetInternalRAM(); } else if(addrInfo.Type == AddressType::WorkRam) {
return _mapper->GetWorkRam() + addrInfo.Address;
case DebugMemoryType::SaveRam: } else if(addrInfo.Type == AddressType::SaveRam) {
size = _mapper->GetMemorySize(DebugMemoryType::SaveRam); return _mapper->GetSaveRam() + addrInfo.Address;
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();
} }
return nullptr;
throw std::runtime_error("unsupported memory type");
} }
void Console::DebugAddTrace(const char * log) void Console::DebugAddTrace(const char * log)

View file

@ -232,7 +232,7 @@ public:
void CopyRewindData(shared_ptr<Console> sourceConsole); void CopyRewindData(shared_ptr<Console> sourceConsole);
uint8_t* GetRamBuffer(DebugMemoryType memoryType, uint32_t &size, int32_t &startAddr); uint8_t* GetRamBuffer(uint16_t address);
void DebugAddTrace(const char *log); void DebugAddTrace(const char *log);
void DebugProcessPpuCycle(); void DebugProcessPpuCycle();

View file

@ -119,24 +119,22 @@ class MMC1 : public BaseMapper
prgBankSelect = extraReg & 0x10; prgBankSelect = extraReg & 0x10;
} }
if(_wramDisable && !_forceWramOn) { MemoryAccessType access = _wramDisable && !_forceWramOn ? MemoryAccessType::NoAccess : MemoryAccessType::ReadWrite;
RemoveCpuMemoryMapping(0x6000, 0x7FFF); PrgMemoryType memType = HasBattery() ? PrgMemoryType::SaveRam : PrgMemoryType::WorkRam;
} else { if(_saveRamSize + _workRamSize > 0x4000) {
if(_saveRamSize + _workRamSize > 0x4000) { //SXROM, 32kb of save ram
//SXROM, 32kb of save ram SetCpuMemoryMapping(0x6000, 0x7FFF, (extraReg >> 2) & 0x03, memType, access);
SetCpuMemoryMapping(0x6000, 0x7FFF, (extraReg >> 2) & 0x03, HasBattery() ? PrgMemoryType::SaveRam : PrgMemoryType::WorkRam); } else if(_saveRamSize + _workRamSize > 0x2000) {
} else if(_saveRamSize + _workRamSize > 0x2000) { if(_saveRamSize == 0x2000 && _workRamSize == 0x2000) {
if(_saveRamSize == 0x2000 && _workRamSize == 0x2000) { //SOROM, half of the 16kb ram is battery backed
//SOROM, half of the 16kb ram is battery backed SetCpuMemoryMapping(0x6000, 0x7FFF, 0, (extraReg >> 3) & 0x01 ? PrgMemoryType::WorkRam : PrgMemoryType::SaveRam, access);
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);
}
} else { } else {
//Everything else - 8kb of work or save ram //Unknown, shouldn't happen
SetCpuMemoryMapping(0x6000, 0x7FFF, 0, HasBattery() ? PrgMemoryType::SaveRam : PrgMemoryType::WorkRam); 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) { if(_romInfo.SubMapperID == 5) {

View file

@ -62,11 +62,8 @@ protected:
case 3: SetMirroringType(MirroringType::Horizontal); break; case 3: SetMirroringType(MirroringType::Horizontal); break;
} }
if(_state.RegE000 & 0x10) { MemoryAccessType access = (_state.RegE000 & 0x10) ? MemoryAccessType::NoAccess : MemoryAccessType::ReadWrite;
RemoveCpuMemoryMapping(0x6000, 0x7FFF); SetCpuMemoryMapping(0x6000, 0x7FFF, 0, HasBattery() ? PrgMemoryType::SaveRam : PrgMemoryType::WorkRam, access);
} else {
SetCpuMemoryMapping(0x6000, 0x7FFF, 0, HasBattery() ? PrgMemoryType::SaveRam : PrgMemoryType::WorkRam);
}
if(_initState == 2) { if(_initState == 2) {
if(_state.RegA000 & 0x08) { if(_state.RegA000 & 0x08) {

View file

@ -150,11 +150,15 @@ class MMC3 : public BaseMapper
_prgMode = (_state.Reg8000 & 0x40) >> 6; _prgMode = (_state.Reg8000 & 0x40) >> 6;
if(_romInfo.MapperID == 4 && _romInfo.SubMapperID == 1) { if(_romInfo.MapperID == 4 && _romInfo.SubMapperID == 1) {
//bool wramEnabled = (_state.Reg8000 & 0x20) == 0x20; //MMC6
RemoveCpuMemoryMapping(0x6000, 0x7000); bool wramEnabled = (_state.Reg8000 & 0x20) == 0x20;
uint8_t firstBankAccess = (_state.RegA001 & 0x10 ? MemoryAccessType::Write : 0) | (_state.RegA001 & 0x20 ? MemoryAccessType::Read : 0); 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); 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++) { for(int i = 0; i < 4; i++) {
SetCpuMemoryMapping(0x7000 + i * 0x400, 0x71FF + i * 0x400, 0, PrgMemoryType::SaveRam, firstBankAccess); SetCpuMemoryMapping(0x7000 + i * 0x400, 0x71FF + i * 0x400, 0, PrgMemoryType::SaveRam, firstBankAccess);
@ -165,11 +169,13 @@ class MMC3 : public BaseMapper
_wramWriteProtected = (_state.RegA001 & 0x40) == 0x40; _wramWriteProtected = (_state.RegA001 & 0x40) == 0x40;
if(_romInfo.SubMapperID == 0) { if(_romInfo.SubMapperID == 0) {
MemoryAccessType access;
if(_wramEnabled) { if(_wramEnabled) {
SetCpuMemoryMapping(0x6000, 0x7FFF, 0, HasBattery() ? PrgMemoryType::SaveRam : PrgMemoryType::WorkRam, CanWriteToWorkRam() ? MemoryAccessType::ReadWrite : MemoryAccessType::Read); access = CanWriteToWorkRam() ? MemoryAccessType::ReadWrite : MemoryAccessType::Read;
} else { } else {
RemoveCpuMemoryMapping(0x6000, 0x7FFF); access = MemoryAccessType::NoAccess;
} }
SetCpuMemoryMapping(0x6000, 0x7FFF, 0, HasBattery() ? PrgMemoryType::SaveRam : PrgMemoryType::WorkRam, access);
} }
} }

View file

@ -63,11 +63,8 @@ protected:
void UpdateState() void UpdateState()
{ {
if(!_prgRamEnabled) { MemoryAccessType access = _prgRamEnabled ? MemoryAccessType::ReadWrite : MemoryAccessType::NoAccess;
RemoveCpuMemoryMapping(0x6000, 0x7FFF); SetCpuMemoryMapping(0x6000, 0x7FFF, 0, HasBattery() ? PrgMemoryType::SaveRam : PrgMemoryType::WorkRam);
} else {
SetupDefaultWorkRam();
}
if(_usingExternalRom) { if(_usingExternalRom) {
if(_licensingTimer == 0) { if(_licensingTimer == 0) {

View file

@ -28,7 +28,7 @@ public:
{ {
if(!_skipMode && _sendAudioSample) { if(!_skipMode && _sendAudioSample) {
for(uint32_t total = 0; total < sampleCount; ) { for(uint32_t total = 0; total < sampleCount; ) {
total += _sendAudioSample(soundBuffer + total*2, sampleCount - total); total += (uint32_t)_sendAudioSample(soundBuffer + total*2, sampleCount - total);
} }
} }
} }

View file

@ -10,6 +10,8 @@
#include "../Core/Console.h" #include "../Core/Console.h"
#include "../Core/VideoDecoder.h" #include "../Core/VideoDecoder.h"
#include "../Core/VideoRenderer.h" #include "../Core/VideoRenderer.h"
#include "../Core/MemoryManager.h"
#include "../Core/BaseMapper.h"
#include "../Core/EmulationSettings.h" #include "../Core/EmulationSettings.h"
#include "../Core/CheatManager.h" #include "../Core/CheatManager.h"
#include "../Core/HdData.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 bool _hdPacksEnabled = false;
static string _mesenVersion = ""; static string _mesenVersion = "";
static int32_t _saveStateSize = -1; static int32_t _saveStateSize = -1;
static struct retro_memory_descriptor _descriptors[3];
static struct retro_memory_map _memoryMap;
static bool _shiftButtonsClockwise = false; static bool _shiftButtonsClockwise = false;
static int32_t _audioSampleRate = 44100; static int32_t _audioSampleRate = 44100;
@ -971,40 +971,24 @@ extern "C" {
void retro_set_memory_maps() void retro_set_memory_maps()
{ {
//Expose internal RAM and work/save RAM for retroachievements //Expose internal RAM and work/save RAM for retroachievements
memset(_descriptors, 0, sizeof(_descriptors)); retro_memory_descriptor descriptors[256] = {};
memset(&_memoryMap, 0, sizeof(_memoryMap)); retro_memory_map memoryMap = {};
uint32_t i = 0; int count = 0;
uint32_t size = 0; for(int i = 0; i <= 0xFFFF; i += 0x100) {
int32_t startAddr = 0; uint8_t* ram = _console->GetRamBuffer(i);
uint8_t* internalRam = _console->GetRamBuffer(DebugMemoryType::InternalRam, size, startAddr); if(ram) {
_descriptors[i].ptr = internalRam; descriptors[count].ptr = ram;
_descriptors[i].start = startAddr; descriptors[count].start = i;
_descriptors[i].len = size; descriptors[count].len = 0x100;
_descriptors[i].select = 0; count++;
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++;
} }
uint8_t* workRam = _console->GetRamBuffer(DebugMemoryType::WorkRam, size, startAddr); memoryMap.descriptors = descriptors;
if(size > 0 && startAddr > 0) { memoryMap.num_descriptors = count;
_descriptors[i].ptr = workRam;
_descriptors[i].start = startAddr;
_descriptors[i].len = size;
_descriptors[i].select = 0;
i++;
}
_memoryMap.descriptors = _descriptors; retroEnv(RETRO_ENVIRONMENT_SET_MEMORY_MAPS, &memoryMap);
_memoryMap.num_descriptors = i;
retroEnv(RETRO_ENVIRONMENT_SET_MEMORY_MAPS, &_memoryMap);
} }
RETRO_API void retro_set_controller_port_device(unsigned port, unsigned device) 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) RETRO_API void *retro_get_memory_data(unsigned id)
{ {
uint32_t size; BaseMapper* mapper = _console->GetMapper();
int32_t startAddr;
switch(id) { switch(id) {
case RETRO_MEMORY_SAVE_RAM: return _console->GetRamBuffer(DebugMemoryType::SaveRam, size, startAddr); case RETRO_MEMORY_SAVE_RAM: return mapper->GetSaveRam();
case RETRO_MEMORY_SYSTEM_RAM: return _console->GetRamBuffer(DebugMemoryType::InternalRam, size, startAddr); case RETRO_MEMORY_SYSTEM_RAM: return _console->GetMemoryManager()->GetInternalRAM();
} }
return nullptr; return nullptr;
} }
RETRO_API size_t retro_get_memory_size(unsigned id) RETRO_API size_t retro_get_memory_size(unsigned id)
{ {
uint32_t size = 0; BaseMapper* mapper = _console->GetMapper();
int32_t startAddr;
switch(id) { switch(id) {
case RETRO_MEMORY_SAVE_RAM: _console->GetRamBuffer(DebugMemoryType::SaveRam, size, startAddr); break; case RETRO_MEMORY_SAVE_RAM: return mapper->GetMemorySize(DebugMemoryType::SaveRam);
case RETRO_MEMORY_SYSTEM_RAM: _console->GetRamBuffer(DebugMemoryType::InternalRam, size, startAddr); break; case RETRO_MEMORY_SYSTEM_RAM: return MemoryManager::InternalRAMSize;
} }
return size; return 0;
} }
} }