Allow dipswitches to be manually configured for mappers that use them (instead of incrementing the value on reset)

This commit is contained in:
Sour 2019-02-08 19:39:35 -05:00
parent c5e4de9542
commit 72fc0de383
24 changed files with 92 additions and 114 deletions

View file

@ -405,6 +405,12 @@ uint8_t BaseMapper::GetPowerOnByte(uint8_t defaultValue)
return defaultValue; return defaultValue;
} }
} }
uint32_t BaseMapper::GetDipSwitches()
{
uint32_t mask = (1 << GetDipSwitchCount()) - 1;
return _console->GetSettings()->GetDipSwitches() & mask;
}
bool BaseMapper::HasBattery() bool BaseMapper::HasBattery()
{ {
@ -768,6 +774,11 @@ RomInfo BaseMapper::GetRomInfo()
return _romInfo; return _romInfo;
} }
uint32_t BaseMapper::GetMapperDipSwitchCount()
{
return GetDipSwitchCount();
}
MirroringType BaseMapper::GetMirroringType() MirroringType BaseMapper::GetMirroringType()
{ {
return _mirroringType; return _mirroringType;

View file

@ -97,6 +97,8 @@ protected:
virtual uint16_t RegisterEndAddress() { return 0xFFFF; } virtual uint16_t RegisterEndAddress() { return 0xFFFF; }
virtual bool AllowRegisterRead() { return false; } virtual bool AllowRegisterRead() { return false; }
virtual uint32_t GetDipSwitchCount() { return 0; }
virtual bool HasBusConflicts() { return false; } virtual bool HasBusConflicts() { return false; }
uint8_t InternalReadRam(uint16_t addr); uint8_t InternalReadRam(uint16_t addr);
@ -129,7 +131,8 @@ protected:
uint32_t GetCHRPageCount(); uint32_t GetCHRPageCount();
uint8_t GetPowerOnByte(uint8_t defaultValue = 0); uint8_t GetPowerOnByte(uint8_t defaultValue = 0);
uint32_t GetDipSwitches();
void SetupDefaultWorkRam(); void SetupDefaultWorkRam();
void RestoreOriginalPrgRam(); void RestoreOriginalPrgRam();
@ -151,7 +154,7 @@ protected:
public: public:
static constexpr uint32_t NametableCount = 0x10; static constexpr uint32_t NametableCount = 0x10;
static constexpr uint32_t NametableSize = 0x400; static constexpr uint32_t NametableSize = 0x400;
void Initialize(RomData &romData); void Initialize(RomData &romData);
virtual ~BaseMapper(); virtual ~BaseMapper();
@ -173,6 +176,7 @@ public:
shared_ptr<BaseControlDevice> GetMapperControlDevice(); shared_ptr<BaseControlDevice> GetMapperControlDevice();
RomInfo GetRomInfo(); RomInfo GetRomInfo();
uint32_t GetMapperDipSwitchCount();
__forceinline uint8_t ReadRAM(uint16_t addr) override; __forceinline uint8_t ReadRAM(uint16_t addr) override;
uint8_t PeekRAM(uint16_t addr) override; uint8_t PeekRAM(uint16_t addr) override;

View file

@ -9,10 +9,10 @@ private:
uint8_t _outerBank; uint8_t _outerBank;
uint8_t _prgReg; uint8_t _prgReg;
uint8_t _chrReg; uint8_t _chrReg;
uint8_t _dipSwitch;
bool _useOuterBank; bool _useOuterBank;
protected: protected:
uint32_t GetDipSwitchCount() override { return 4; }
uint16_t GetPRGPageSize() override { return 0x4000; } uint16_t GetPRGPageSize() override { return 0x4000; }
uint16_t GetCHRPageSize() override { return 0x2000; } uint16_t GetCHRPageSize() override { return 0x2000; }
bool AllowRegisterRead() override { return true; } bool AllowRegisterRead() override { return true; }
@ -24,10 +24,8 @@ protected:
if(HasChrRom()) { if(HasChrRom()) {
_useOuterBank = false; _useOuterBank = false;
_dipSwitch = 0x0C;
} else { } else {
_useOuterBank = true; _useOuterBank = true;
_dipSwitch = 0x05;
} }
SelectCHRPage(0, 0); SelectCHRPage(0, 0);
@ -37,7 +35,7 @@ protected:
void StreamState(bool saving) override void StreamState(bool saving) override
{ {
BaseMapper::StreamState(saving); BaseMapper::StreamState(saving);
Stream(_bankMode, _outerBank, _prgReg, _chrReg, _dipSwitch); Stream(_bankMode, _outerBank, _prgReg, _chrReg);
} }
void Reset(bool softReset) override void Reset(bool softReset) override
@ -46,7 +44,6 @@ protected:
_bankMode = 0; _bankMode = 0;
_outerBank = 0; _outerBank = 0;
_dipSwitch = (_dipSwitch + 1) & 0x0F;
} }
void UpdateState() void UpdateState()
@ -75,7 +72,7 @@ protected:
uint8_t ReadRegister(uint16_t addr) override uint8_t ReadRegister(uint16_t addr) override
{ {
if(_bankMode == 0x10) { if(_bankMode == 0x10) {
return InternalReadRam((addr & 0xFFF0) | _dipSwitch); return InternalReadRam((addr & 0xFFF0) | GetDipSwitches());
} else { } else {
return InternalReadRam(addr); return InternalReadRam(addr);
} }

View file

@ -7,9 +7,9 @@ class Bmc8157 : public BaseMapper
{ {
private: private:
uint16_t _lastAddr; uint16_t _lastAddr;
bool _dipSwitch;
protected: protected:
uint32_t GetDipSwitchCount() override { return 1; }
uint16_t GetPRGPageSize() override { return 0x4000; } uint16_t GetPRGPageSize() override { return 0x4000; }
uint16_t GetCHRPageSize() override { return 0x2000; } uint16_t GetCHRPageSize() override { return 0x2000; }
@ -20,15 +20,10 @@ protected:
SelectCHRPage(0, 0); SelectCHRPage(0, 0);
} }
void Reset(bool softReset) override
{
_dipSwitch = !_dipSwitch;
}
void StreamState(bool saving) override void StreamState(bool saving) override
{ {
BaseMapper::StreamState(saving); BaseMapper::StreamState(saving);
Stream(_lastAddr, _dipSwitch); Stream(_lastAddr);
if(!saving) { if(!saving) {
UpdateState(); UpdateState();
@ -51,7 +46,7 @@ protected:
baseBank = 7; baseBank = 7;
} }
if(outer512Prg && _prgSize <= 1024 * 512 && _dipSwitch) { if(outer512Prg && _prgSize <= 1024 * 512 && GetDipSwitches() != 0) {
RemoveCpuMemoryMapping(0x8000, 0xFFFF); RemoveCpuMemoryMapping(0x8000, 0xFFFF);
} else { } else {
SelectPRGPage(0, (outer512Prg << 6) | (outer128Prg << 3) | innerPrg0); SelectPRGPage(0, (outer512Prg << 6) | (outer128Prg << 3) | innerPrg0);

View file

@ -7,16 +7,15 @@ class BmcHpxx : public MMC3
private: private:
uint8_t _exRegs[5]; uint8_t _exRegs[5];
bool _locked; bool _locked;
uint8_t _dipSwitch;
protected: protected:
uint32_t GetDipSwitchCount() override { return 4; }
bool AllowRegisterRead() override { return true; } bool AllowRegisterRead() override { return true; }
void InitMapper() override void InitMapper() override
{ {
memset(_exRegs, 0, sizeof(_exRegs)); memset(_exRegs, 0, sizeof(_exRegs));
_locked = false; _locked = false;
_dipSwitch = 0;
MMC3::InitMapper(); MMC3::InitMapper();
AddRegisterRange(0x5000, 0x5FFF, MemoryOperation::Any); AddRegisterRange(0x5000, 0x5FFF, MemoryOperation::Any);
@ -28,7 +27,6 @@ protected:
MMC3::Reset(softReset); MMC3::Reset(softReset);
memset(_exRegs, 0, sizeof(_exRegs)); memset(_exRegs, 0, sizeof(_exRegs));
_locked = false; _locked = false;
_dipSwitch = (_dipSwitch + 1) & 0x0F;
MMC3::ResetMmc3(); MMC3::ResetMmc3();
UpdateState(); UpdateState();
} }
@ -36,7 +34,7 @@ protected:
void StreamState(bool saving) override void StreamState(bool saving) override
{ {
MMC3::StreamState(saving); MMC3::StreamState(saving);
Stream(_exRegs[0], _exRegs[1], _exRegs[2], _exRegs[3], _exRegs[4], _locked, _dipSwitch); Stream(_exRegs[0], _exRegs[1], _exRegs[2], _exRegs[3], _exRegs[4], _locked);
} }
void SelectCHRPage(uint16_t slot, uint16_t page, ChrMemoryType memoryType = ChrMemoryType::Default) override void SelectCHRPage(uint16_t slot, uint16_t page, ChrMemoryType memoryType = ChrMemoryType::Default) override
@ -94,7 +92,7 @@ protected:
uint8_t ReadRegister(uint16_t addr) override uint8_t ReadRegister(uint16_t addr) override
{ {
return _dipSwitch; return GetDipSwitches();
} }
void WriteRegister(uint16_t addr, uint8_t value) override void WriteRegister(uint16_t addr, uint8_t value) override

View file

@ -4,10 +4,8 @@
class Bs5 : public BaseMapper class Bs5 : public BaseMapper
{ {
private:
uint8_t _dipSwitch = 0;
protected: protected:
uint32_t GetDipSwitchCount() override { return 2; }
uint16_t GetPRGPageSize() override { return 0x2000; } uint16_t GetPRGPageSize() override { return 0x2000; }
uint16_t GetCHRPageSize() override { return 0x800; } uint16_t GetCHRPageSize() override { return 0x800; }
@ -19,19 +17,6 @@ protected:
} }
} }
void StreamState(bool saving) override
{
BaseMapper::StreamState(saving);
Stream(_dipSwitch);
}
void Reset(bool softReset) override
{
if(softReset) {
_dipSwitch = (_dipSwitch + 1) & 0x03;
}
}
void WriteRegister(uint16_t addr, uint8_t value) override void WriteRegister(uint16_t addr, uint8_t value) override
{ {
int bank = (addr >> 10) & 0x03; int bank = (addr >> 10) & 0x03;
@ -41,7 +26,7 @@ protected:
break; break;
case 0xA000: case 0xA000:
if(addr & (1 << (_dipSwitch + 4))) { if(addr & (1 << (GetDipSwitches() + 4))) {
SelectPRGPage(bank, addr & 0x0F); SelectPRGPage(bank, addr & 0x0F);
} }
break; break;

View file

@ -395,13 +395,15 @@ void CPU::StreamState(bool saving)
bool overclockAdjustApu = settings->GetOverclockAdjustApu(); bool overclockAdjustApu = settings->GetOverclockAdjustApu();
uint32_t extraScanlinesBeforeNmi = settings->GetPpuExtraScanlinesBeforeNmi(); uint32_t extraScanlinesBeforeNmi = settings->GetPpuExtraScanlinesBeforeNmi();
uint32_t extraScanlinesAfterNmi = settings->GetPpuExtraScanlinesAfterNmi(); uint32_t extraScanlinesAfterNmi = settings->GetPpuExtraScanlinesAfterNmi();
uint32_t dipSwitches = _console->GetSettings()->GetDipSwitches();
Stream(_state.PC, _state.SP, _state.PS, _state.A, _state.X, _state.Y, _cycleCount, _state.NMIFlag, Stream(_state.PC, _state.SP, _state.PS, _state.A, _state.X, _state.Y, _cycleCount, _state.NMIFlag,
_state.IRQFlag, _dmcCounter, _dmcDmaRunning, _spriteDmaCounter, _spriteDmaTransfer, _state.IRQFlag, _dmcCounter, _dmcDmaRunning, _spriteDmaCounter, _spriteDmaTransfer,
overclockRate, overclockAdjustApu, extraScanlinesBeforeNmi, extraScanlinesBeforeNmi); overclockRate, overclockAdjustApu, extraScanlinesBeforeNmi, extraScanlinesBeforeNmi, dipSwitches);
if(!saving) { if(!saving) {
settings->SetOverclockRate(overclockRate, overclockAdjustApu); settings->SetOverclockRate(overclockRate, overclockAdjustApu);
settings->SetPpuNmiConfig(extraScanlinesBeforeNmi, extraScanlinesAfterNmi); settings->SetPpuNmiConfig(extraScanlinesBeforeNmi, extraScanlinesAfterNmi);
settings->SetDipSwitches(dipSwitches);
} }
} }

View file

@ -1243,6 +1243,20 @@ bool Console::UpdateHdPackMode()
return modeChanged; return modeChanged;
} }
uint32_t Console::GetDipSwitchCount()
{
shared_ptr<ControlManager> controlManager = _controlManager;
shared_ptr<BaseMapper> mapper = _mapper;
if(std::dynamic_pointer_cast<VsControlManager>(controlManager)) {
return IsDualSystem() ? 16 : 8;
} else if(mapper) {
return mapper->GetMapperDipSwitchCount();
}
return 0;
}
ConsoleFeatures Console::GetAvailableFeatures() ConsoleFeatures Console::GetAvailableFeatures()
{ {
ConsoleFeatures features = ConsoleFeatures::None; ConsoleFeatures features = ConsoleFeatures::None;

View file

@ -164,6 +164,7 @@ public:
return std::dynamic_pointer_cast<T>(_systemActionManager); return std::dynamic_pointer_cast<T>(_systemActionManager);
} }
uint32_t GetDipSwitchCount();
ConsoleFeatures GetAvailableFeatures(); ConsoleFeatures GetAvailableFeatures();
void InputBarcode(uint64_t barcode, uint32_t digitCount); void InputBarcode(uint64_t barcode, uint32_t digitCount);

View file

@ -5,37 +5,35 @@
class Eh8813A : public BaseMapper class Eh8813A : public BaseMapper
{ {
private: private:
uint8_t _dipSwitch;
bool _alterReadAddress; bool _alterReadAddress;
protected: protected:
uint32_t GetDipSwitchCount() override { return 4; }
uint16_t GetPRGPageSize() override { return 0x4000; } uint16_t GetPRGPageSize() override { return 0x4000; }
uint16_t GetCHRPageSize() override { return 0x2000; } uint16_t GetCHRPageSize() override { return 0x2000; }
bool AllowRegisterRead() override { return true; } bool AllowRegisterRead() override { return true; }
void InitMapper() override void InitMapper() override
{ {
_dipSwitch = -1;
SetMirroringType(MirroringType::Vertical); SetMirroringType(MirroringType::Vertical);
} }
void Reset(bool softReset) override void Reset(bool softReset) override
{ {
WriteRegister(0x8000, 0); WriteRegister(0x8000, 0);
_dipSwitch++;
_alterReadAddress = false; _alterReadAddress = false;
} }
void StreamState(bool saving) override void StreamState(bool saving) override
{ {
BaseMapper::StreamState(saving); BaseMapper::StreamState(saving);
Stream(_dipSwitch, _alterReadAddress); Stream(_alterReadAddress);
} }
uint8_t ReadRegister(uint16_t addr) override uint8_t ReadRegister(uint16_t addr) override
{ {
if(_alterReadAddress) { if(_alterReadAddress) {
addr = (addr & 0xFFF0) + _dipSwitch; addr = (addr & 0xFFF0) + GetDipSwitches();
} }
return InternalReadRam(addr); return InternalReadRam(addr);
} }

View file

@ -9,11 +9,11 @@ class FamicomBox : public BaseMapper
{ {
private: private:
uint8_t _regs[8]; uint8_t _regs[8];
uint8_t _dipSwitches;
uint8_t _extInternalRam[0x2000]; uint8_t _extInternalRam[0x2000];
InternalRamHandler<0x1FFF> _extendedRamHandler; InternalRamHandler<0x1FFF> _extendedRamHandler;
protected: protected:
uint32_t GetDipSwitchCount() override { return 8; }
uint16_t RegisterStartAddress() override { return 0x5000; } uint16_t RegisterStartAddress() override { return 0x5000; }
uint16_t RegisterEndAddress() override { return 0x5FFF; } uint16_t RegisterEndAddress() override { return 0x5FFF; }
uint16_t GetPRGPageSize() override { return 0x4000; } uint16_t GetPRGPageSize() override { return 0x4000; }
@ -23,7 +23,6 @@ protected:
void InitMapper() override void InitMapper() override
{ {
_regs[7] = 0xFF; _regs[7] = 0xFF;
_dipSwitches = 0xC0;
SelectPRGPage(0, 0); SelectPRGPage(0, 0);
SelectPRGPage(1, 1); SelectPRGPage(1, 1);
@ -38,7 +37,7 @@ protected:
BaseMapper::StreamState(saving); BaseMapper::StreamState(saving);
ArrayInfo<uint8_t> regs { _regs, 8 }; ArrayInfo<uint8_t> regs { _regs, 8 };
ArrayInfo<uint8_t> extRam { _extInternalRam, 0x2000 }; ArrayInfo<uint8_t> extRam { _extInternalRam, 0x2000 };
Stream(_dipSwitches, regs, extRam); Stream(regs, extRam);
} }
void Reset(bool softReset) override void Reset(bool softReset) override
@ -95,7 +94,7 @@ protected:
10: Coin Mode 10: Coin Mode
11: Free Play 11: Free Play
*/ */
return _dipSwitches; return GetDipSwitches();
case 3: case 3:
/*5003R /*5003R

View file

@ -9,6 +9,8 @@ private:
bool _irqEnabled; bool _irqEnabled;
protected: protected:
uint32_t GetDipSwitchCount() override { return 4; }
void InitMapper() override void InitMapper() override
{ {
MMC1::InitMapper(); MMC1::InitMapper();
@ -28,8 +30,9 @@ protected:
{ {
if(_irqEnabled) { if(_irqEnabled) {
_irqCounter++; _irqCounter++;
//TODO: Counter hardcoded - should be based on dip switches
if(_irqCounter == 0x28000000) { uint32_t maxCounter = 0x20000000 | (GetDipSwitches() << 25);
if(_irqCounter >= maxCounter) {
_console->GetCpu()->SetIrqSource(IRQSource::External); _console->GetCpu()->SetIrqSource(IRQSource::External);
_irqEnabled = false; _irqEnabled = false;
} }

View file

@ -6,14 +6,14 @@ class MMC3_Bmc411120C : public MMC3
{ {
private: private:
uint8_t _exReg; uint8_t _exReg;
uint8_t _dipSwitch;
protected: protected:
uint32_t GetDipSwitchCount() { return 1; }
void InitMapper() override void InitMapper() override
{ {
AddRegisterRange(0x6000, 0xFFFF, MemoryOperation::Write); AddRegisterRange(0x6000, 0xFFFF, MemoryOperation::Write);
_exReg = 0; _exReg = 0;
_dipSwitch = 0x04;
MMC3::InitMapper(); MMC3::InitMapper();
} }
@ -21,15 +21,9 @@ protected:
void StreamState(bool saving) override void StreamState(bool saving) override
{ {
MMC3::StreamState(saving); MMC3::StreamState(saving);
Stream(_exReg, _dipSwitch); Stream(_exReg);
} }
void Reset(bool softReset) override
{
BaseMapper::Reset(softReset);
_dipSwitch ^= 0x04;
}
void SelectCHRPage(uint16_t slot, uint16_t page, ChrMemoryType memoryType = ChrMemoryType::Default) override void SelectCHRPage(uint16_t slot, uint16_t page, ChrMemoryType memoryType = ChrMemoryType::Default) override
{ {
MMC3::SelectCHRPage(slot, page | ((_exReg & 0x03) << 7), memoryType); MMC3::SelectCHRPage(slot, page | ((_exReg & 0x03) << 7), memoryType);
@ -37,7 +31,7 @@ protected:
void SelectPRGPage(uint16_t slot, uint16_t page, PrgMemoryType memoryType = PrgMemoryType::PrgRom) override void SelectPRGPage(uint16_t slot, uint16_t page, PrgMemoryType memoryType = PrgMemoryType::PrgRom) override
{ {
if(_exReg & (0x08 | _dipSwitch)) { if(_exReg & (0x08 | (GetDipSwitches() << 2))) {
MMC3::SelectPrgPage4x(0, (((_exReg >> 4) & 0x03) | 0x0C) << 2); MMC3::SelectPrgPage4x(0, (((_exReg >> 4) & 0x03) | 0x0C) << 2);
} else { } else {
MMC3::SelectPRGPage(slot, (page & 0x0F) | ((_exReg & 0x03) << 4)); MMC3::SelectPRGPage(slot, (page & 0x0F) | ((_exReg & 0x03) << 4));

View file

@ -14,12 +14,12 @@ class Mapper83 : public BaseMapper
uint8_t _bank; uint8_t _bank;
uint16_t _irqCounter; uint16_t _irqCounter;
bool _irqEnabled; bool _irqEnabled;
uint8_t _resetBit;
protected: protected:
virtual uint16_t GetPRGPageSize() override { return 0x2000; } uint32_t GetDipSwitchCount() override { return 2; }
virtual uint16_t GetCHRPageSize() override { return 0x400; } uint16_t GetPRGPageSize() override { return 0x2000; }
virtual bool AllowRegisterRead() override { return true; } uint16_t GetCHRPageSize() override { return 0x400; }
bool AllowRegisterRead() override { return true; }
void InitMapper() override void InitMapper() override
{ {
@ -31,7 +31,6 @@ protected:
_bank = 0; _bank = 0;
_irqCounter = 0; _irqCounter = 0;
_irqEnabled = false; _irqEnabled = false;
_resetBit = 0;
AddRegisterRange(0x5000, 0x5000, MemoryOperation::Read); AddRegisterRange(0x5000, 0x5000, MemoryOperation::Read);
AddRegisterRange(0x5100, 0x5103, MemoryOperation::Any); AddRegisterRange(0x5100, 0x5103, MemoryOperation::Any);
@ -46,14 +45,7 @@ protected:
ArrayInfo<uint8_t> regs{ _regs, 11 }; ArrayInfo<uint8_t> regs{ _regs, 11 };
ArrayInfo<uint8_t> exRegs{ _exRegs, 4 }; ArrayInfo<uint8_t> exRegs{ _exRegs, 4 };
Stream(regs, exRegs, _is2kBank, _isNot2kBank, _mode, _bank, _irqCounter, _irqEnabled, _resetBit); Stream(regs, exRegs, _is2kBank, _isNot2kBank, _mode, _bank, _irqCounter, _irqEnabled);
}
void Reset(bool softReset) override
{
if(softReset) {
_resetBit ^= 1;
}
} }
void ProcessCpuClock() override void ProcessCpuClock() override
@ -102,7 +94,7 @@ protected:
uint8_t ReadRegister(uint16_t addr) override uint8_t ReadRegister(uint16_t addr) override
{ {
if(addr == 0x5000) { if(addr == 0x5000) {
return (_console->GetMemoryManager()->GetOpenBus() & 0xFC) | _resetBit; return (_console->GetMemoryManager()->GetOpenBus() & 0xFC) | GetDipSwitches();
} else { } else {
return _exRegs[addr & 0x03]; return _exRegs[addr & 0x03];
} }

View file

@ -261,7 +261,6 @@ void MesenMovie::ApplySettings()
settings->SetFlagState(EmulationFlags::EnableOamDecay, LoadBool(_settings, MovieKeys::EnableOamDecay)); settings->SetFlagState(EmulationFlags::EnableOamDecay, LoadBool(_settings, MovieKeys::EnableOamDecay));
settings->SetFlagState(EmulationFlags::DisablePpuReset, LoadBool(_settings, MovieKeys::DisablePpuReset)); settings->SetFlagState(EmulationFlags::DisablePpuReset, LoadBool(_settings, MovieKeys::DisablePpuReset));
//VS System flags
settings->SetDipSwitches(HexUtilities::FromHex(LoadString(_settings, MovieKeys::DipSwitches))); settings->SetDipSwitches(HexUtilities::FromHex(LoadString(_settings, MovieKeys::DipSwitches)));
LoadCheats(); LoadCheats();

View file

@ -130,8 +130,7 @@ void MovieRecorder::GetGameSettings(stringstream &out)
case RamPowerOnState::Random: WriteInt(out, MovieKeys::RamPowerOnState, -1); break; //TODO: Shouldn't be used for movies case RamPowerOnState::Random: WriteInt(out, MovieKeys::RamPowerOnState, -1); break; //TODO: Shouldn't be used for movies
} }
//VS System flags if(_console->GetDipSwitchCount() > 0) {
if(_console->GetAvailableFeatures() == ConsoleFeatures::VsSystem) {
WriteString(out, MovieKeys::DipSwitches, HexUtilities::ToHex(settings->GetDipSwitches())); WriteString(out, MovieKeys::DipSwitches, HexUtilities::ToHex(settings->GetDipSwitches()));
} }

View file

@ -5,37 +5,30 @@
class UnlD1038 : public BaseMapper class UnlD1038 : public BaseMapper
{ {
private: private:
uint8_t _dipSwitch;
bool _returnDipSwitch; bool _returnDipSwitch;
protected: protected:
uint32_t GetDipSwitchCount() override { return 2; }
uint16_t GetPRGPageSize() override { return 0x4000; } uint16_t GetPRGPageSize() override { return 0x4000; }
uint16_t GetCHRPageSize() override { return 0x2000; } uint16_t GetCHRPageSize() override { return 0x2000; }
bool AllowRegisterRead() override { return true; } bool AllowRegisterRead() override { return true; }
void InitMapper() override void InitMapper() override
{ {
_dipSwitch = 0; _returnDipSwitch = false;
WriteRegister(0x8000, 0); WriteRegister(0x8000, 0);
} }
void Reset(bool softReset) override
{
if(softReset) {
_dipSwitch = (_dipSwitch + 1) & 0x03;
}
}
void StreamState(bool saving) override void StreamState(bool saving) override
{ {
BaseMapper::StreamState(saving); BaseMapper::StreamState(saving);
Stream(_dipSwitch, _returnDipSwitch); Stream(_returnDipSwitch);
} }
uint8_t ReadRegister(uint16_t addr) override uint8_t ReadRegister(uint16_t addr) override
{ {
if(_returnDipSwitch) { if(_returnDipSwitch) {
return _dipSwitch; return GetDipSwitches();
} else { } else {
return InternalReadRam(addr); return InternalReadRam(addr);
} }

View file

@ -14,9 +14,9 @@ private:
bool _irqEnabled; bool _irqEnabled;
bool _extAttributesEnabled; bool _extAttributesEnabled;
bool _wramWriteEnabled; bool _wramWriteEnabled;
bool _dipSwitch;
protected: protected:
uint32_t GetDipSwitchCount() override { return 1; }
uint16_t GetPRGPageSize() override { return 0x4000; } uint16_t GetPRGPageSize() override { return 0x4000; }
uint16_t GetCHRPageSize() override { return 0x800; } uint16_t GetCHRPageSize() override { return 0x800; }
bool AllowRegisterRead() override { return true; } bool AllowRegisterRead() override { return true; }
@ -33,7 +33,6 @@ protected:
_irqEnabled = false; _irqEnabled = false;
_extAttributesEnabled = false; _extAttributesEnabled = false;
_wramWriteEnabled = false; _wramWriteEnabled = false;
_dipSwitch = false;
_lastNametableFetchAddr = 0; _lastNametableFetchAddr = 0;
InitializeRam(_extendedAttributes[0], 0x400); InitializeRam(_extendedAttributes[0], 0x400);
@ -55,7 +54,7 @@ protected:
SnapshotInfo audioChannel2 { _audioChannels[1].get() }; SnapshotInfo audioChannel2 { _audioChannels[1].get() };
Stream(extAttributes1, extAttributes2, audioChannel1, audioChannel2, _lowByteIrqCounter, _irqCounter, _irqEnabled, Stream(extAttributes1, extAttributes2, audioChannel1, audioChannel2, _lowByteIrqCounter, _irqCounter, _irqEnabled,
_extAttributesEnabled, _wramWriteEnabled, _dipSwitch); _extAttributesEnabled, _wramWriteEnabled);
if(!saving) { if(!saving) {
UpdateWorkRamState(); UpdateWorkRamState();
@ -114,7 +113,7 @@ protected:
uint8_t ReadRegister(uint16_t addr) override uint8_t ReadRegister(uint16_t addr) override
{ {
switch(addr & 0x5800) { switch(addr & 0x5800) {
case 0x4800: return (_dipSwitch ? 0x80 : 0) | 0x64; case 0x4800: return (GetDipSwitches() ? 0x80 : 0) | 0x64;
case 0x5000: return _audioChannels[0]->ReadRegister(); case 0x5000: return _audioChannels[0]->ReadRegister();
case 0x5800: return _audioChannels[1]->ReadRegister(); case 0x5800: return _audioChannels[1]->ReadRegister();
} }

View file

@ -31,13 +31,7 @@ void VsControlManager::Reset(bool softReset)
void VsControlManager::StreamState(bool saving) void VsControlManager::StreamState(bool saving)
{ {
ControlManager::StreamState(saving); ControlManager::StreamState(saving);
Stream(_prgChrSelectBit, _protectionCounter, _refreshState);
uint32_t dipSwitches = _console->GetSettings()->GetDipSwitches();
Stream(_prgChrSelectBit, _protectionCounter, _refreshState, dipSwitches);
if(!saving) {
_console->GetSettings()->SetDipSwitches(dipSwitches);
}
} }
void VsControlManager::GetMemoryRanges(MemoryRanges &ranges) void VsControlManager::GetMemoryRanges(MemoryRanges &ranges)

View file

@ -12,14 +12,14 @@ class Yoko : public BaseMapper
uint8_t _bank; uint8_t _bank;
uint16_t _irqCounter; uint16_t _irqCounter;
bool _irqEnabled; bool _irqEnabled;
uint8_t _dipSwitch;
protected: protected:
virtual uint16_t RegisterStartAddress() override { return 0x5000; } uint32_t GetDipSwitchCount() override { return 2; }
virtual uint16_t RegisterEndAddress() override { return 0x5FFF; } uint16_t RegisterStartAddress() override { return 0x5000; }
virtual uint16_t GetPRGPageSize() override { return 0x2000; } uint16_t RegisterEndAddress() override { return 0x5FFF; }
virtual uint16_t GetCHRPageSize() override { return 0x800; } uint16_t GetPRGPageSize() override { return 0x2000; }
virtual bool AllowRegisterRead() override { return true; } uint16_t GetCHRPageSize() override { return 0x800; }
bool AllowRegisterRead() override { return true; }
void InitMapper() override void InitMapper() override
{ {
@ -29,7 +29,6 @@ protected:
_bank = 0; _bank = 0;
_irqCounter = 0; _irqCounter = 0;
_irqEnabled = false; _irqEnabled = false;
_dipSwitch = 3;
RemoveRegisterRange(0x5000, 0x53FF, MemoryOperation::Write); RemoveRegisterRange(0x5000, 0x53FF, MemoryOperation::Write);
AddRegisterRange(0x8000, 0xFFFF, MemoryOperation::Write); AddRegisterRange(0x8000, 0xFFFF, MemoryOperation::Write);
@ -43,13 +42,12 @@ protected:
ArrayInfo<uint8_t> regs { _regs, 7 }; ArrayInfo<uint8_t> regs { _regs, 7 };
ArrayInfo<uint8_t> exRegs { _exRegs, 4 }; ArrayInfo<uint8_t> exRegs { _exRegs, 4 };
Stream(regs, exRegs, _mode, _bank, _irqCounter, _irqEnabled, _dipSwitch); Stream(regs, exRegs, _mode, _bank, _irqCounter, _irqEnabled);
} }
void Reset(bool softReset) override void Reset(bool softReset) override
{ {
if(softReset) { if(softReset) {
_dipSwitch = (_dipSwitch + 1) & 0x03;
_mode = 0; _mode = 0;
_bank = 0; _bank = 0;
} }
@ -93,7 +91,7 @@ protected:
uint8_t ReadRegister(uint16_t addr) override uint8_t ReadRegister(uint16_t addr) override
{ {
if(addr <= 0x53FF) { if(addr <= 0x53FF) {
return (_console->GetMemoryManager()->GetOpenBus() & 0xFC) | _dipSwitch; return (_console->GetMemoryManager()->GetOpenBus() & 0xFC) | GetDipSwitches();
} else { } else {
return _exRegs[addr & 0x03]; return _exRegs[addr & 0x03];
} }

View file

@ -30,7 +30,7 @@ namespace Mesen.GUI.Forms.Config
_dipSwitches = dipswitchDefinition.DipSwitches; _dipSwitches = dipswitchDefinition.DipSwitches;
} else { } else {
_dipSwitches = new List<List<string>>(); _dipSwitches = new List<List<string>>();
for(int i = 0; i < (InteropEmu.IsVsDualSystem() ? 16 : 8); i++) { for(int i = 0, len = (int)InteropEmu.GetDipSwitchCount(); i < len; i++) {
_dipSwitches.Add(new List<string>(new string[] { "Dipswitch #" + i.ToString(), "Off", "On" })); _dipSwitches.Add(new List<string>(new string[] { "Dipswitch #" + i.ToString(), "Off", "On" }));
} }
} }
@ -147,11 +147,11 @@ namespace Mesen.GUI.Forms.Config
protected override void OnFormClosed(FormClosedEventArgs e) protected override void OnFormClosed(FormClosedEventArgs e)
{ {
base.OnFormClosed(e);
if(this.DialogResult == DialogResult.OK) { if(this.DialogResult == DialogResult.OK) {
GameSpecificInfo.AddGameSpecificConfig((GameSpecificInfo)Entity); GameSpecificInfo.AddGameSpecificConfig((GameSpecificInfo)Entity);
GameSpecificInfo.ApplyGameSpecificConfig(); GameSpecificInfo.ApplyGameSpecificConfig();
} }
base.OnFormClosed(e);
} }
private void btnReset_Click(object sender, EventArgs e) private void btnReset_Click(object sender, EventArgs e)

View file

@ -53,12 +53,12 @@ namespace Mesen.GUI.Forms
private void InitializeVsSystemMenu() private void InitializeVsSystemMenu()
{ {
sepVsSystem.Visible = InteropEmu.IsVsSystem(); sepVsSystem.Visible = InteropEmu.IsVsSystem() || InteropEmu.GetDipSwitchCount() > 0;
mnuInsertCoin1.Visible = InteropEmu.IsVsSystem(); mnuInsertCoin1.Visible = InteropEmu.IsVsSystem();
mnuInsertCoin2.Visible = InteropEmu.IsVsSystem(); mnuInsertCoin2.Visible = InteropEmu.IsVsSystem();
mnuInsertCoin3.Visible = InteropEmu.IsVsDualSystem(); mnuInsertCoin3.Visible = InteropEmu.IsVsDualSystem();
mnuInsertCoin4.Visible = InteropEmu.IsVsDualSystem(); mnuInsertCoin4.Visible = InteropEmu.IsVsDualSystem();
mnuGameConfig.Visible = InteropEmu.IsVsSystem(); mnuGameConfig.Visible = InteropEmu.GetDipSwitchCount() > 0;
} }
private void ShowGameConfig() private void ShowGameConfig()

View file

@ -162,6 +162,7 @@ namespace Mesen.GUI
[DllImport(DLLPath)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool IsVsDualSystem(); [DllImport(DLLPath)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool IsVsDualSystem();
[DllImport(DLLPath)] public static extern void VsInsertCoin(UInt32 port); [DllImport(DLLPath)] public static extern void VsInsertCoin(UInt32 port);
[DllImport(DLLPath)] public static extern UInt32 GetDipSwitchCount();
[DllImport(DLLPath)] public static extern void SetDipSwitches(UInt32 dipSwitches); [DllImport(DLLPath)] public static extern void SetDipSwitches(UInt32 dipSwitches);
[DllImport(DLLPath)] public static extern void InputBarcode(UInt64 barcode, Int32 digitCount); [DllImport(DLLPath)] public static extern void InputBarcode(UInt64 barcode, Int32 digitCount);

View file

@ -750,6 +750,8 @@ namespace InteropEmu {
} }
} }
DllExport uint32_t __stdcall GetDipSwitchCount() { return _console->GetDipSwitchCount(); }
DllExport void __stdcall SetDipSwitches(uint32_t dipSwitches) DllExport void __stdcall SetDipSwitches(uint32_t dipSwitches)
{ {
_settings->SetDipSwitches(dipSwitches); _settings->SetDipSwitches(dipSwitches);