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();
}
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)

View file

@ -232,7 +232,7 @@ public:
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 DebugProcessPpuCycle();

View file

@ -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) {

View file

@ -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) {

View file

@ -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);
}
}

View file

@ -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) {

View file

@ -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);
}
}
}

View file

@ -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;
}
}