BS-X: Allow memory packs in other cartridges
This commit is contained in:
parent
5978e89a6c
commit
3da787b88f
6 changed files with 69 additions and 18 deletions
|
@ -57,7 +57,7 @@ shared_ptr<BaseCartridge> BaseCartridge::CreateCartridge(Console* console, Virtu
|
|||
cart->_romPath = romFile;
|
||||
|
||||
if(FolderUtilities::GetExtension(romFile.GetFileName()) == ".bs") {
|
||||
cart->_bsxMemPack.reset(new BsxMemoryPack(romData));
|
||||
cart->_bsxMemPack.reset(new BsxMemoryPack(console, romData, false));
|
||||
if(!FirmwareHelper::LoadBsxFirmware(console, &cart->_prgRom, cart->_prgRomSize)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -329,6 +329,10 @@ void BaseCartridge::SaveBattery()
|
|||
if(_coprocessor && _hasBattery) {
|
||||
_coprocessor->SaveBattery();
|
||||
}
|
||||
|
||||
if(_bsxMemPack) {
|
||||
_bsxMemPack->SaveBattery();
|
||||
}
|
||||
}
|
||||
|
||||
void BaseCartridge::Init(MemoryMappings &mm)
|
||||
|
@ -363,6 +367,7 @@ void BaseCartridge::Init(MemoryMappings &mm)
|
|||
void BaseCartridge::RegisterHandlers(MemoryMappings &mm)
|
||||
{
|
||||
if(MapSpecificCarts(mm) || _coprocessorType == CoprocessorType::GSU || _coprocessorType == CoprocessorType::SDD1 || _coprocessorType == CoprocessorType::SPC7110 || _coprocessorType == CoprocessorType::CX4) {
|
||||
MapBsxMemoryPack(mm);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -403,6 +408,8 @@ void BaseCartridge::RegisterHandlers(MemoryMappings &mm)
|
|||
mm.RegisterHandler(0x70, 0x7D, 0x0000, 0x7FFF, _saveRamHandlers);
|
||||
mm.RegisterHandler(0xA0, 0xBF, 0x6000, 0x7FFF, _saveRamHandlers);
|
||||
}
|
||||
|
||||
MapBsxMemoryPack(mm);
|
||||
}
|
||||
|
||||
void BaseCartridge::LoadEmbeddedFirmware()
|
||||
|
@ -444,7 +451,7 @@ void BaseCartridge::InitCoprocessor()
|
|||
if(!_bsxMemPack) {
|
||||
//Create an empty memory pack if the BIOS was loaded directly (instead of a .bs file)
|
||||
vector<uint8_t> emptyMemPack;
|
||||
_bsxMemPack.reset(new BsxMemoryPack(emptyMemPack));
|
||||
_bsxMemPack.reset(new BsxMemoryPack(_console, emptyMemPack, false));
|
||||
}
|
||||
|
||||
_coprocessor.reset(new BsxCart(_console, _bsxMemPack.get()));
|
||||
|
@ -489,6 +496,32 @@ bool BaseCartridge::MapSpecificCarts(MemoryMappings &mm)
|
|||
return false;
|
||||
}
|
||||
|
||||
void BaseCartridge::MapBsxMemoryPack(MemoryMappings& mm)
|
||||
{
|
||||
string code = GetGameCode();
|
||||
if(!_bsxMemPack && code.size() == 4 && code[0] == 'Z' && _cartInfo.DeveloperId == 0x33) {
|
||||
//Game with data pack slot (e.g Sound Novel Tsukuuru, etc.)
|
||||
vector<uint8_t> saveData = _console->GetBatteryManager()->LoadBattery(".bs");
|
||||
if(saveData.empty()) {
|
||||
//Make a 1 megabyte flash cartridge by default (use $FF for all bytes)
|
||||
saveData.resize(0x100000, 0xFF);
|
||||
}
|
||||
_bsxMemPack.reset(new BsxMemoryPack(_console, saveData, true));
|
||||
|
||||
if(_flags & CartFlags::LoRom) {
|
||||
mm.RegisterHandler(0xC0, 0xEF, 0x0000, 0x7FFF, _bsxMemPack->GetMemoryHandlers());
|
||||
mm.RegisterHandler(0xC0, 0xEF, 0x8000, 0xFFFF, _bsxMemPack->GetMemoryHandlers());
|
||||
} else {
|
||||
mm.RegisterHandler(0x20, 0x3F, 0x8000, 0xFFFF, _bsxMemPack->GetMemoryHandlers(), 8);
|
||||
mm.RegisterHandler(0x60, 0x7D, 0x0000, 0xFFFF, _bsxMemPack->GetMemoryHandlers());
|
||||
mm.RegisterHandler(0xA0, 0xBF, 0x8000, 0xFFFF, _bsxMemPack->GetMemoryHandlers(), 8);
|
||||
mm.RegisterHandler(0xE0, 0xFF, 0x0000, 0xFFFF, _bsxMemPack->GetMemoryHandlers());
|
||||
}
|
||||
|
||||
//TODO: SA-1 cartridges, etc.
|
||||
}
|
||||
}
|
||||
|
||||
void BaseCartridge::ApplyConfigOverrides()
|
||||
{
|
||||
string name = GetCartName();
|
||||
|
@ -539,16 +572,16 @@ void BaseCartridge::Serialize(Serializer &s)
|
|||
string BaseCartridge::GetGameCode()
|
||||
{
|
||||
string code;
|
||||
if(_cartInfo.GameCode[0] >= ' ') {
|
||||
if(_cartInfo.GameCode[0] > ' ') {
|
||||
code += _cartInfo.GameCode[0];
|
||||
}
|
||||
if(_cartInfo.GameCode[1] >= ' ') {
|
||||
if(_cartInfo.GameCode[1] > ' ') {
|
||||
code += _cartInfo.GameCode[1];
|
||||
}
|
||||
if(_cartInfo.GameCode[2] >= ' ') {
|
||||
if(_cartInfo.GameCode[2] > ' ') {
|
||||
code += _cartInfo.GameCode[2];
|
||||
}
|
||||
if(_cartInfo.GameCode[3] >= ' ') {
|
||||
if(_cartInfo.GameCode[3] > ' ') {
|
||||
code += _cartInfo.GameCode[3];
|
||||
}
|
||||
return code;
|
||||
|
|
|
@ -62,7 +62,8 @@ private:
|
|||
CoprocessorType GetSt01xVersion();
|
||||
CoprocessorType GetDspVersion();
|
||||
|
||||
bool MapSpecificCarts(MemoryMappings &mm);
|
||||
bool MapSpecificCarts(MemoryMappings& mm);
|
||||
void MapBsxMemoryPack(MemoryMappings& mm);
|
||||
void ApplyConfigOverrides();
|
||||
|
||||
void LoadRom();
|
||||
|
|
|
@ -1,12 +1,16 @@
|
|||
#include "stdafx.h"
|
||||
#include "BsxMemoryPack.h"
|
||||
#include "Console.h"
|
||||
#include "BatteryManager.h"
|
||||
#include "../Utilities/IpsPatcher.h"
|
||||
|
||||
BsxMemoryPack::BsxMemoryPack(vector<uint8_t>& data)
|
||||
BsxMemoryPack::BsxMemoryPack(Console* console, vector<uint8_t>& data, bool persistFlash)
|
||||
{
|
||||
_console = console;
|
||||
_orgData = data;
|
||||
_dataSize = (uint32_t)data.size();
|
||||
_data = new uint8_t[_dataSize];
|
||||
_persistFlash = persistFlash;
|
||||
memcpy(_data, data.data(), _dataSize);
|
||||
|
||||
_calculatedSize = std::min<uint8_t>(0x0C, (uint8_t)log2(_dataSize >> 10));
|
||||
|
@ -21,6 +25,13 @@ BsxMemoryPack::~BsxMemoryPack()
|
|||
delete[] _data;
|
||||
}
|
||||
|
||||
void BsxMemoryPack::SaveBattery()
|
||||
{
|
||||
if(_persistFlash) {
|
||||
_console->GetBatteryManager()->SaveBattery(".bs", _data, _dataSize);
|
||||
}
|
||||
}
|
||||
|
||||
void BsxMemoryPack::Serialize(Serializer& s)
|
||||
{
|
||||
s.Stream(_enableCsr, _enableEsr, _enableVendorInfo, _writeByte, _command);
|
||||
|
@ -105,12 +116,10 @@ BsxMemoryPack::BsxMemoryPackHandler::BsxMemoryPackHandler(BsxMemoryPack* memPack
|
|||
|
||||
uint8_t BsxMemoryPack::BsxMemoryPackHandler::Read(uint32_t addr)
|
||||
{
|
||||
if(addr >= 0xC00000) {
|
||||
if(_memPack->_enableEsr) {
|
||||
switch(addr & 0xFFFF) {
|
||||
case 0x0002: return 0xC0;
|
||||
case 0x0004: return 0x82;
|
||||
}
|
||||
if(_offset == 0 && _memPack->_enableEsr) {
|
||||
switch(addr & 0xFFF) {
|
||||
case 0x0002: return 0xC0;
|
||||
case 0x0004: return 0x82;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -143,7 +152,7 @@ void BsxMemoryPack::BsxMemoryPackHandler::Write(uint32_t addr, uint8_t value)
|
|||
uint8_t currentByte = RamHandler::Read(addr);
|
||||
RamHandler::Write(addr, value & currentByte);
|
||||
_memPack->_writeByte = false;
|
||||
} else if(addr == 0xC00000) {
|
||||
} else if(_offset == 0 && (addr & 0xFFF) == 0) {
|
||||
_memPack->ProcessCommand(value, _page);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,9 +5,12 @@
|
|||
#include "../Utilities/ISerializable.h"
|
||||
|
||||
class BsxMemoryPackHandler;
|
||||
class Console;
|
||||
|
||||
class BsxMemoryPack : public ISerializable
|
||||
{
|
||||
private:
|
||||
Console* _console = nullptr;
|
||||
vector<uint8_t> _orgData;
|
||||
uint8_t* _data = nullptr;
|
||||
uint32_t _dataSize = 0;
|
||||
|
@ -15,6 +18,7 @@ class BsxMemoryPack : public ISerializable
|
|||
|
||||
uint8_t _calculatedSize = 0x0C;
|
||||
|
||||
bool _persistFlash = false;
|
||||
bool _enableCsr = false;
|
||||
bool _enableEsr = false;
|
||||
bool _enableVendorInfo = false;
|
||||
|
@ -22,9 +26,11 @@ class BsxMemoryPack : public ISerializable
|
|||
uint16_t _command = 0;
|
||||
|
||||
public:
|
||||
BsxMemoryPack(vector<uint8_t>& data);
|
||||
BsxMemoryPack(Console* console, vector<uint8_t>& data, bool persistFlash);
|
||||
virtual ~BsxMemoryPack();
|
||||
|
||||
void SaveBattery();
|
||||
|
||||
void Serialize(Serializer& s) override;
|
||||
|
||||
void ProcessCommand(uint8_t value, uint32_t page);
|
||||
|
|
|
@ -18,7 +18,7 @@ struct SnesCartInformation
|
|||
uint8_t SramSize;
|
||||
|
||||
uint8_t DestinationCode;
|
||||
uint8_t Reserved2;
|
||||
uint8_t DeveloperId;
|
||||
uint8_t Version;
|
||||
|
||||
uint8_t ChecksumComplement[2];
|
||||
|
|
|
@ -7,9 +7,11 @@ class RamHandler : public IMemoryHandler
|
|||
{
|
||||
private:
|
||||
uint8_t * _ram;
|
||||
uint32_t _offset;
|
||||
uint32_t _mask;
|
||||
|
||||
protected:
|
||||
uint32_t _offset;
|
||||
|
||||
public:
|
||||
RamHandler(uint8_t *ram, uint32_t offset, uint32_t size, SnesMemoryType memoryType)
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue