Fixed issues with Sunsoft-4 emulation (Mapper 68) - Nantettatte roms with external PRG now work properly

This commit is contained in:
Sour 2018-06-17 11:28:41 -04:00
parent ff9322dee0
commit 6a59bb52c9
3 changed files with 74 additions and 10 deletions

View file

@ -400,6 +400,16 @@ void BaseMapper::InitializeChrRam(int32_t chrRamSize)
}
}
void BaseMapper::SetupDefaultWorkRam()
{
//Setup a default work/save ram in 0x6000-0x7FFF space
if(HasBattery() && _saveRamSize > 0) {
SetCpuMemoryMapping(0x6000, 0x7FFF, 0, PrgMemoryType::SaveRam);
} else if(_workRamSize > 0) {
SetCpuMemoryMapping(0x6000, 0x7FFF, 0, PrgMemoryType::WorkRam);
}
}
bool BaseMapper::HasChrRam()
{
return _chrRamSize > 0;
@ -586,12 +596,7 @@ void BaseMapper::Initialize(RomData &romData)
}
}
//Setup a default work/save ram in 0x6000-0x7FFF space
if(HasBattery() && _saveRamSize > 0) {
SetCpuMemoryMapping(0x6000, 0x7FFF, 0, PrgMemoryType::SaveRam);
} else if(_workRamSize > 0) {
SetCpuMemoryMapping(0x6000, 0x7FFF, 0, PrgMemoryType::WorkRam);
}
SetupDefaultWorkRam();
InitMapper();
InitMapper(romData);

View file

@ -136,6 +136,8 @@ protected:
uint8_t GetPowerOnByte(uint8_t defaultValue = 0);
void SetupDefaultWorkRam();
void RestoreOriginalPrgRam();
void InitializeChrRam(int32_t chrRamSize = -1);

View file

@ -8,6 +8,10 @@ class Sunsoft4 : public BaseMapper
private:
uint8_t _ntRegs[2];
bool _useChrForNametables;
bool _prgRamEnabled;
uint32_t _licensingTimer;
bool _usingExternalRom;
uint8_t _externalPage = 0;
void UpdateNametables()
{
@ -35,24 +39,66 @@ protected:
{
_useChrForNametables = false;
_ntRegs[0] = _ntRegs[1] = 0;
_licensingTimer = 0;
_usingExternalRom = false;
_prgRamEnabled = false;
//Bank 0's initial state is undefined, but some roms expect it to be the first page
SelectPRGPage(0, 0);
SelectPRGPage(1, 7);
SelectPRGPage(1, -1);
UpdateState();
}
void StreamState(bool saving) override
{
BaseMapper::StreamState(saving);
Stream(_ntRegs[0], _ntRegs[1], _useChrForNametables);
Stream(_ntRegs[0], _ntRegs[1], _useChrForNametables, _prgRamEnabled, _usingExternalRom, _externalPage);
if(!saving) {
UpdateNametables();
UpdateState();
}
}
void UpdateState()
{
if(!_prgRamEnabled) {
RemoveCpuMemoryMapping(0x6000, 0x7FFF);
} else {
SetupDefaultWorkRam();
}
if(_usingExternalRom) {
if(_licensingTimer == 0) {
RemoveCpuMemoryMapping(0x8000, 0xBFFF);
} else {
SelectPRGPage(0, _externalPage);
}
}
}
void ProcessCpuClock() override
{
if(_licensingTimer) {
_licensingTimer--;
if(_licensingTimer == 0) {
UpdateState();
}
}
}
void WriteRAM(uint16_t addr, uint8_t value) override
{
if(addr >= 0x6000 && addr <= 0x7FFF) {
_licensingTimer = 1024 * 105;
UpdateState();
}
BaseMapper::WriteRAM(addr, value);
}
void WriteRegister(uint16_t addr, uint8_t value) override
{
switch(addr & 0xF000) {
@ -79,8 +125,19 @@ protected:
UpdateNametables();
break;
case 0xF000:
SelectPRGPage(0, value & 0x0F);
//_prgRamEnabled = (value & 0x10) == 0x10;
bool externalPrg = (value & 0x08) == 0;
if(externalPrg && GetPRGPageCount() > 8) {
_usingExternalRom = true;
_externalPage = 0x08 | ((value & 0x07) % (GetPRGPageCount() - 0x08));
SelectPRGPage(0, _externalPage);
} else {
_usingExternalRom = false;
SelectPRGPage(0, value & 0x07);
}
_prgRamEnabled = (value & 0x10) == 0x10;
UpdateState();
break;
}
}