mirror of
https://github.com/libretro/Mesen.git
synced 2024-11-27 02:50:28 +00:00
GTROM: Added self flash support
This commit is contained in:
parent
b5a0f9a4f1
commit
bf6a8a2de2
@ -1,31 +1,91 @@
|
||||
#pragma once
|
||||
#include "stdafx.h"
|
||||
#include "BaseMapper.h"
|
||||
#include "FlashSST39SF040.h"
|
||||
#include "../Utilities/IpsPatcher.h"
|
||||
|
||||
//Missing Flash rom support, and only tested via a test rom
|
||||
class Cheapocabra : public BaseMapper
|
||||
{
|
||||
private:
|
||||
unique_ptr<FlashSST39SF040> _flash;
|
||||
uint8_t _prgReg = 0;
|
||||
vector<uint8_t> _orgPrgRom;
|
||||
|
||||
protected:
|
||||
virtual uint16_t GetPRGPageSize() override { return 0x8000; }
|
||||
virtual uint16_t GetCHRPageSize() override { return 0x2000; }
|
||||
virtual uint16_t RegisterStartAddress() override { return 0x5000; }
|
||||
virtual uint16_t RegisterEndAddress() override { return 0x5FFF; }
|
||||
virtual uint32_t GetChrRamSize() override { return 0x8000; }
|
||||
uint16_t GetPRGPageSize() override { return 0x8000; }
|
||||
uint16_t GetCHRPageSize() override { return 0x2000; }
|
||||
uint32_t GetWorkRamSize() override { return 0; }
|
||||
uint32_t GetSaveRamSize() override { return 0; }
|
||||
uint16_t RegisterStartAddress() override { return 0x5000; }
|
||||
uint16_t RegisterEndAddress() override { return 0x5FFF; }
|
||||
uint32_t GetChrRamSize() override { return 0x4000; }
|
||||
bool AllowRegisterRead() override { return true; }
|
||||
|
||||
void InitMapper() override
|
||||
{
|
||||
AddRegisterRange(0x7000, 0x7FFF, MemoryOperation::Write);
|
||||
|
||||
_flash.reset(new FlashSST39SF040(_prgRom, _prgSize));
|
||||
AddRegisterRange(0x8000, 0xFFFF, MemoryOperation::Any);
|
||||
RemoveRegisterRange(0x5000, 0x5FFF, MemoryOperation::Read);
|
||||
|
||||
WriteRegister(0x5000, GetPowerOnByte());
|
||||
|
||||
_orgPrgRom = vector<uint8_t>(_prgRom, _prgRom + _prgSize);
|
||||
ApplySaveData();
|
||||
}
|
||||
|
||||
void StreamState(bool saving) override
|
||||
{
|
||||
BaseMapper::StreamState(saving);
|
||||
|
||||
SnapshotInfo flash { _flash.get() };
|
||||
Stream(_prgReg, flash);
|
||||
}
|
||||
|
||||
void ApplySaveData()
|
||||
{
|
||||
//Apply save data (saved as an IPS file), if found
|
||||
vector<uint8_t> ipsData = _console->GetBatteryManager()->LoadBattery(".ips");
|
||||
if(!ipsData.empty()) {
|
||||
vector<uint8_t> patchedPrgRom;
|
||||
if(IpsPatcher::PatchBuffer(ipsData, _orgPrgRom, patchedPrgRom)) {
|
||||
memcpy(_prgRom, patchedPrgRom.data(), _prgSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SaveBattery() override
|
||||
{
|
||||
vector<uint8_t> prgRom = vector<uint8_t>(_prgRom, _prgRom + _prgSize);
|
||||
vector<uint8_t> ipsData = IpsPatcher::CreatePatch(_orgPrgRom, prgRom);
|
||||
if(ipsData.size() > 8) {
|
||||
_console->GetBatteryManager()->SaveBattery(".ips", ipsData.data(), (uint32_t)ipsData.size());
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t ReadRegister(uint16_t addr) override
|
||||
{
|
||||
int16_t value = _flash->Read(addr);
|
||||
if(value >= 0) {
|
||||
return (uint8_t)value;
|
||||
}
|
||||
|
||||
return BaseMapper::InternalReadRam(addr);
|
||||
}
|
||||
|
||||
void WriteRegister(uint16_t addr, uint8_t value) override
|
||||
{
|
||||
SelectPRGPage(0, value & 0x0F);
|
||||
SelectCHRPage(0, (value >> 4) & 0x01);
|
||||
if(value & 0x20) {
|
||||
SetNametables(4, 5, 6, 7);
|
||||
if(addr < 0x8000) {
|
||||
_prgReg = value & 0x0F;
|
||||
SelectPRGPage(0, _prgReg);
|
||||
|
||||
SelectCHRPage(0, (value >> 4) & 0x01);
|
||||
for(int i = 0; i < 8; i++) {
|
||||
SetNametable(i, ((value & 0x20) ? 8 : 0) + i);
|
||||
}
|
||||
} else {
|
||||
SetNametables(0, 1, 2, 3);
|
||||
_flash->Write((_prgReg << 15) | (addr & 0x7FFF), value);
|
||||
}
|
||||
}
|
||||
};
|
@ -54,7 +54,7 @@ public:
|
||||
|
||||
void Write(uint32_t addr, uint8_t value)
|
||||
{
|
||||
uint16_t cmd = addr & 0xFFFF;
|
||||
uint16_t cmd = addr & 0x7FFF;
|
||||
if(_mode == ChipMode::WaitingForCommand) {
|
||||
if(_cycle == 0) {
|
||||
if(cmd == 0x5555 && value == 0xAA) {
|
||||
|
Loading…
Reference in New Issue
Block a user