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

View file

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

View file

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