diff --git a/Core/Core.vcxproj b/Core/Core.vcxproj
index 035fd73a..f068284c 100644
--- a/Core/Core.vcxproj
+++ b/Core/Core.vcxproj
@@ -477,6 +477,7 @@
+
diff --git a/Core/Core.vcxproj.filters b/Core/Core.vcxproj.filters
index 1dbe4065..12272225 100644
--- a/Core/Core.vcxproj.filters
+++ b/Core/Core.vcxproj.filters
@@ -937,6 +937,9 @@
Nes\Mappers\Unnamed
+
+ Nes\Mappers\MMC
+
diff --git a/Core/MMC3_123.h b/Core/MMC3_123.h
new file mode 100644
index 00000000..e30616f1
--- /dev/null
+++ b/Core/MMC3_123.h
@@ -0,0 +1,58 @@
+#pragma once
+#include "stdafx.h"
+#include "MMC3.h"
+
+class MMC3_123 : public MMC3
+{
+private:
+ const uint8_t _security[8] = { 0,3,1,5,6,7,2,4 };
+ uint8_t _exReg[2];
+
+ void UpdatePrgMapping() override
+ {
+ if(_exReg[0] & 0x40) {
+ uint8_t bank = (_exReg[0] & 0x05) | ((_exReg[0] & 0x08) >> 2) | ((_exReg[0] & 0x20) >> 2);
+ if(_exReg[0] & 0x02) {
+ SelectPrgPage4x(0, (bank & 0xFE) << 1);
+ } else {
+ SelectPrgPage2x(0, bank << 1);
+ SelectPrgPage2x(1, bank << 1);
+ }
+ } else {
+ MMC3::UpdatePrgMapping();
+ }
+ }
+
+ void InitMapper() override
+ {
+ MMC3::InitMapper();
+
+ _exReg[0] = _exReg[1] = 0;
+ AddRegisterRange(0x5001, 0x5FFF, MemoryOperation::Write);
+ }
+
+ void StreamState(bool saving) override
+ {
+ MMC3::StreamState(saving);
+ Stream(_exReg[0], _exReg[1]);
+ }
+
+ void WriteRegister(uint16_t addr, uint8_t value) override
+ {
+ if(addr < 0x8000 && addr & 0x0800) {
+ if(addr & 0x01) {
+ _exReg[1] = value;
+ } else {
+ _exReg[0] = value;
+ }
+ UpdatePrgMapping();
+ } else if(addr < 0xA000) {
+ switch(addr & 0x8001) {
+ case 0x8000: MMC3::WriteRegister(0x8000, (value & 0xC0) | (_security[value & 0x07])); break;
+ case 0x8001: MMC3::WriteRegister(0x8001, value); break;
+ }
+ } else {
+ MMC3::WriteRegister(addr, value);
+ }
+ }
+};
\ No newline at end of file
diff --git a/Core/MapperFactory.cpp b/Core/MapperFactory.cpp
index 492c0f30..83349e5b 100644
--- a/Core/MapperFactory.cpp
+++ b/Core/MapperFactory.cpp
@@ -102,6 +102,7 @@
#include "MMC3_114.h"
#include "MMC3_115.h"
#include "MMC3_121.h"
+#include "MMC3_123.h"
#include "MMC3_134.h"
#include "MMC3_165.h"
#include "MMC3_182.h"
@@ -193,7 +194,7 @@ Supported mappers:
| 64| 65| 66| 67| 68| 69| 70| 71| 72| 73| 74| 75| 76| 77| 78| 79|
| 80|===| 82| |===| 85| 86| 87| 88| 89| 90| 91| 92| 93| 94| 95|
| 96| 97|===| 99|...|101|===|103| |105|106|107|108|===|===|===|
-|112|113|114|115| |117|118|119|120|121|===| |===| | |===|
+|112|113|114|115| |117|118|119|120|121|===|123|===| | |===|
|===|===|===|===|132|133|134|===|136|137|138|139|140|141|142|143|
|144|145|146|147|148|149|150|151|152|153|154|155|156|157| |159|
|---|===|162|163|164|165|166|167|168|===|170|171|172|173|===|175|
@@ -325,6 +326,7 @@ BaseMapper* MapperFactory::GetMapperFromID(RomData &romData)
case 119: return new MMC3_ChrRam(0x40, 0x7F, 8);
case 120: return new Mapper120();
case 121: return new MMC3_121();
+ case 123: return new MMC3_123();
case 132: return new Txc22211A();
case 133: return new Sachen_133();
case 134: return new MMC3_134();