diff --git a/Core/Core.vcxproj b/Core/Core.vcxproj index 961733404..f6214c724 100644 --- a/Core/Core.vcxproj +++ b/Core/Core.vcxproj @@ -775,6 +775,8 @@ + + @@ -800,6 +802,7 @@ + diff --git a/Core/Core.vcxproj.filters b/Core/Core.vcxproj.filters index 288ec2e5c..25775a2e8 100644 --- a/Core/Core.vcxproj.filters +++ b/Core/Core.vcxproj.filters @@ -982,6 +982,12 @@ Nes\Mappers\Unnamed + + Nes\Mappers\Unnamed + + + Nes\Mappers\Unnamed + Nes\Mappers\Sachen @@ -1555,6 +1561,9 @@ Nes\Mappers\Unnamed + + Nes\Mappers\Unnamed + Nes\Mappers\Unnamed diff --git a/Core/Mapper272.h b/Core/Mapper272.h new file mode 100644 index 000000000..449c651cc --- /dev/null +++ b/Core/Mapper272.h @@ -0,0 +1,108 @@ +#pragma once +#include "stdafx.h" +#include "BaseMapper.h" + +class Mapper272 : public BaseMapper +{ +private: + uint8_t _chrBanks[8]; + uint8_t _irqCounter; + bool _irqEnabled; + uint16_t _lastPpuAddr; + +protected: + virtual uint16_t GetPRGPageSize() override { return 0x2000; } + virtual uint16_t GetCHRPageSize() override { return 0x0400; } + + void InitMapper() override + { + memset(_chrBanks, 0, sizeof(_chrBanks)); + + _irqEnabled = false; + _irqCounter = 0; + + SelectPRGPage(2, -2); + SelectPRGPage(3, -1); + } + + void StreamState(bool saving) override + { + BaseMapper::StreamState(saving); + ArrayInfo chrBanks = { _chrBanks, 8 }; + Stream(_irqEnabled, _irqCounter, chrBanks); + } + + void WriteRegister(uint16_t addr, uint8_t value) override + { + if((addr >= 0xB000) && (addr <= 0xE003)) { + uint8_t index = ((((addr >> 12) & 0x07) - 3) << 1) + ((addr >> 1) & 0x01); + bool lowBits = (addr & 0x01) == 0x00; + if (lowBits) { + _chrBanks[index] = (_chrBanks[index] & 0xF0) | (value & 0x0F); + } else { + _chrBanks[index] = (_chrBanks[index] & 0x0F) | (value << 4); + } + SelectCHRPage(index, _chrBanks[index]); + } else { + switch(addr & 0xF000) { + case 0x8000: + SelectPRGPage(0, value); + break; + + case 0xA000: + SelectPRGPage(1, value); + break; + + case 0x9000: + switch(value & 0x01) { + case 0: SetMirroringType(MirroringType::Vertical); break; + case 1: SetMirroringType(MirroringType::Horizontal); break; + } + break; + } + } + + switch(addr & 0xC00C) { + case 0x8004: + switch(value & 0x03) { + case 2: SetMirroringType(MirroringType::ScreenAOnly); break; + case 3: SetMirroringType(MirroringType::ScreenBOnly); break; + } + break; + + case 0x800C: + _console->GetCpu()->SetIrqSource(IRQSource::External); + break; + + case 0xC004: + _console->GetCpu()->ClearIrqSource(IRQSource::External); + break; + + case 0xC008: + _irqEnabled = true; + break; + + case 0xC00C: + _irqEnabled = false; + _irqCounter = 0; + _console->GetCpu()->ClearIrqSource(IRQSource::External); + break; + } + } + + void NotifyVRAMAddressChange(uint16_t addr) override + { + if ((_lastPpuAddr & 0x2000) && !(addr & 0x2000)) { + if(_irqEnabled) { + _irqCounter++; + if(_irqCounter == 84) { + _irqCounter = 0; + _console->GetCpu()->SetIrqSource(IRQSource::External); + } + } + } + + _lastPpuAddr = addr; + } +}; + diff --git a/Core/Mapper277.h b/Core/Mapper277.h new file mode 100644 index 000000000..b0befafa4 --- /dev/null +++ b/Core/Mapper277.h @@ -0,0 +1,49 @@ +#pragma once +#include "stdafx.h" +#include "BaseMapper.h" + +class Mapper277 : public BaseMapper +{ +private: + bool _locked; + +protected: + uint16_t GetPRGPageSize() override { return 0x4000; } + uint16_t GetCHRPageSize() override { return 0x2000; } + + void InitMapper() override + { + WriteRegister(0, 0x08); + } + + void Reset(bool softReset) override + { + _locked = false; + WriteRegister(0, 0x08); + } + + void WriteRegister(uint16_t addr, uint8_t value) override + { + if(!_locked) { + uint8_t prgBank = value & 0x0F; + + _locked = (value & 0x20) == 0x20; + + if(value & 0x08) { + if(value & 0x01) { + SelectPRGPage(0, prgBank); + SelectPRGPage(1, prgBank); + } else { + SelectPrgPage2x(0, prgBank & 0xFE); + } + } else { + SelectPRGPage(0, prgBank); + SelectPRGPage(1, prgBank | 0x07); + } + + SelectCHRPage(0, 0); + SetMirroringType(value & 0x10 ? MirroringType::Horizontal : MirroringType::Vertical); + } + } +}; + diff --git a/Core/Mapper368.h b/Core/Mapper368.h new file mode 100644 index 000000000..6ced0acbd --- /dev/null +++ b/Core/Mapper368.h @@ -0,0 +1,79 @@ +#pragma once +#include "stdafx.h" +#include "BaseMapper.h" + +// YUNG-08 + +class Mapper368 : public BaseMapper +{ +private: + uint8_t _latch; + + bool _irqEnabled; + uint16_t _irqCounter; + +protected: + uint16_t GetPRGPageSize() override { return 0x2000; } + uint16_t GetCHRPageSize() override { return 0x2000; } + uint16_t RegisterStartAddress() override { return 0x4022; } + uint16_t RegisterEndAddress() override { return 0x4FFF; } + bool AllowRegisterRead() override { return true; } + + void InitMapper() override + { + _irqEnabled = false; + _irqCounter = 0; + _latch = 0; + + SetCpuMemoryMapping(0x6000, 0x7FFF, 0x02, PrgMemoryType::PrgRom); + + SelectPRGPage(0, 1); + SelectPRGPage(1, 0); + SelectPRGPage(3, 8); + + SelectCHRPage(0, 0); + } + + void StreamState(bool saving) override + { + BaseMapper::StreamState(saving); + Stream(_latch, _irqEnabled, _irqCounter); + } + + void ProcessCpuClock() override + { + if(_irqEnabled) { + _irqCounter++; + if((_irqCounter & 0xFFF) == 0) { + _console->GetCpu()->SetIrqSource(IRQSource::External); + } + } + } + + uint8_t ReadRegister(uint16_t addr) override + { + if((addr & 0x1FF) == 0x122) { + return (0x8A | (_latch & 0x35)); + } + return InternalReadRam(addr); + } + + void WriteRegister(uint16_t addr, uint8_t value) override + { + switch(addr & 0x1FF) { + case 0x022: + // bank order = { 4, 3, 5, 3, 6, 3, 7, 3 }; + SelectPRGPage(2, (value & 0x01) ? 0x03 : (0x04 | value >> 1)); + break; + + case 0x122: + _latch = value; + _irqEnabled = (value & 0x01) != 0; + if(!_irqEnabled) { + _irqCounter = 0; + _console->GetCpu()->ClearIrqSource(IRQSource::External); + } + break; + } + } +}; diff --git a/Core/MapperFactory.cpp b/Core/MapperFactory.cpp index 1b0b9e9ca..b132bcfe0 100644 --- a/Core/MapperFactory.cpp +++ b/Core/MapperFactory.cpp @@ -167,6 +167,8 @@ #include "Mapper246.h" #include "Mapper253.h" #include "Mapper271.h" +#include "Mapper272.h" +#include "Mapper277.h" #include "Mapper319.h" #include "Mapper326.h" #include "Mapper330.h" @@ -174,6 +176,7 @@ #include "Mapper357.h" #include "Mapper360.h" #include "Mapper362.h" +#include "Mapper368.h" #include "Mapper375.h" #include "Mapper380.h" #include "Mapper382.h" @@ -712,9 +715,11 @@ BaseMapper* MapperFactory::GetMapperFromID(RomData &romData) return new MMC3_269(); //269-270 case 271: return new Mapper271(); - //272-273 + case 272: return new Mapper272(); + //273 case 274: return new Bmc80013B(); //275-282 + case 277: return new Mapper277(); case 281: return new JyCompany(); case 282: return new JyCompany(); case 283: return new Gs2004_Gs2013(); @@ -792,6 +797,7 @@ BaseMapper* MapperFactory::GetMapperFromID(RomData &romData) case 362: return new Mapper362(); case 364: return new MMC3_364(); case 366: return new BmcGn45(); + case 368: return new Mapper368(); case 369: return new MMC3_369(); case 370: return new MMC3_370(); case 372: return new MMC3_372();