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();