diff --git a/Core/Core.vcxproj b/Core/Core.vcxproj
index e6eeadcc..22dd06e1 100644
--- a/Core/Core.vcxproj
+++ b/Core/Core.vcxproj
@@ -443,6 +443,7 @@
+
diff --git a/Core/Core.vcxproj.filters b/Core/Core.vcxproj.filters
index 7b1e39b2..adaa6f77 100644
--- a/Core/Core.vcxproj.filters
+++ b/Core/Core.vcxproj.filters
@@ -832,6 +832,9 @@
Nes\Mappers\Unnamed
+
+ Nes\Mappers\Unnamed
+
diff --git a/Core/Mapper103.h b/Core/Mapper103.h
new file mode 100644
index 00000000..08616964
--- /dev/null
+++ b/Core/Mapper103.h
@@ -0,0 +1,77 @@
+#pragma once
+#include "stdafx.h"
+#include "BaseMapper.h"
+
+class Mapper103 : public BaseMapper
+{
+private:
+ bool _prgRamDisabled;
+ uint8_t _prgReg;
+
+protected:
+ virtual uint16_t GetPRGPageSize() { return 0x2000; }
+ virtual uint16_t GetCHRPageSize() { return 0x2000; }
+ virtual uint32_t GetWorkRamSize() { return 0x4000; }
+ virtual uint32_t GetWorkRamPageSize() { return 0x2000; }
+ virtual uint16_t RegisterStartAddress() { return 0x6000; }
+ virtual uint16_t EndStartAddress() { return 0xFFFF; }
+
+ void InitMapper()
+ {
+ _prgRamDisabled = false;
+ _prgReg = 0;
+ SelectCHRPage(0, 0);
+ UpdateState();
+ }
+
+ void StreamState(bool saving)
+ {
+ BaseMapper::StreamState(saving);
+ Stream(_prgRamDisabled, _prgReg);
+ if(!saving) {
+ UpdateState();
+ }
+ }
+
+ void UpdateState()
+ {
+ SelectPrgPage4x(0, -4);
+ if(_prgRamDisabled) {
+ SetCpuMemoryMapping(0x6000, 0x7FFF, _prgReg, PrgMemoryType::PrgRom);
+ } else {
+ SetCpuMemoryMapping(0x6000, 0x7FFF, 0, PrgMemoryType::WorkRam);
+ SetCpuMemoryMapping(0xB800, 0xD7FF, 1, PrgMemoryType::WorkRam);
+ }
+ }
+
+ void WriteRegister(uint16_t addr, uint8_t value)
+ {
+ switch(addr & 0xF000) {
+ case 0x6000: case 0x7000:
+ //Workram is always writeable, even when PRG ROM is mapped to $6000
+ _workRam[addr - 0x6000] = value;
+ break;
+
+ case 0x8000:
+ _prgReg = value & 0x0F;
+ UpdateState();
+ break;
+
+ case 0xB000: case 0xC000: case 0xD000:
+ //Workram is always writeable, even when PRG ROM is mapped to $B800-$D7FF
+ if(addr >= 0xB800 && addr < 0xD800) {
+ _workRam[0x2000 + addr - 0xB800] = value;
+ }
+ break;
+
+ case 0xE000:
+ SetMirroringType(value & 0x08 ? MirroringType::Horizontal : MirroringType::Vertical);
+ break;
+
+ case 0xF000:
+ _prgRamDisabled = (value & 0x10) == 0x10;
+ UpdateState();
+ break;
+ }
+ }
+};
\ No newline at end of file
diff --git a/Core/MapperFactory.cpp b/Core/MapperFactory.cpp
index 456fb152..4c15c803 100644
--- a/Core/MapperFactory.cpp
+++ b/Core/MapperFactory.cpp
@@ -49,6 +49,7 @@
#include "Mapper61.h"
#include "Mapper62.h"
#include "Mapper91.h"
+#include "Mapper103.h"
#include "Mapper107.h"
#include "Mapper108.h"
#include "Mapper112.h"
@@ -163,7 +164,7 @@ Supported mappers:
| 48| 49| 50| 51| 52| 53| | | 56| 57| 58|===| 60| 61| 62| 63|
| 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|===| | | | |107|108|===|===|===|
+| 96| 97|===| 99|...|101|===|103| | | |107|108|===|===|===|
|112|113| |115| | |118|119| | |===| |===| | |===|
|===|===|===|===|132|133| |===| |137|138|139|140|141|142|143|
|144|145|146|147|148|149|150|151|152|153|154|155|156|157| |159|
@@ -280,6 +281,7 @@ BaseMapper* MapperFactory::GetMapperFromID(RomData &romData)
case 97: return new IremTamS1();
case 99: return new VsSystem();
case 101: return new JalecoJfxx(true);
+ case 103: return new Mapper103();
case 105: break; //NES World Champ - has dip switches
case 107: return new Mapper107();
case 108: return new Mapper108();