diff --git a/Core/AXROM.h b/Core/AXROM.h
new file mode 100644
index 00000000..a3b9c5be
--- /dev/null
+++ b/Core/AXROM.h
@@ -0,0 +1,24 @@
+#pragma once
+#include "stdafx.h"
+#include "BaseMapper.h"
+
+class AXROM : public BaseMapper
+{
+ protected:
+ virtual uint32_t GetPRGPageSize() { return 0x8000; }
+ virtual uint32_t GetCHRPageSize() { return 0x2000; }
+
+ void InitMapper()
+ {
+ SelectPRGPage(0, 0);
+ SelectCHRPage(0, 0);
+ }
+
+ public:
+ void WriteRAM(uint16_t addr, uint8_t value)
+ {
+ SelectPRGPage(0, value & 0x07);
+
+ _mirroringType = ((value & 0x10) == 0x10) ? MirroringType::ScreenBOnly : MirroringType::ScreenAOnly;
+ }
+};
\ No newline at end of file
diff --git a/Core/Core.vcxproj b/Core/Core.vcxproj
index e68e9e99..c6203628 100644
--- a/Core/Core.vcxproj
+++ b/Core/Core.vcxproj
@@ -88,6 +88,7 @@
+
diff --git a/Core/Core.vcxproj.filters b/Core/Core.vcxproj.filters
index 79b97663..a4d2e148 100644
--- a/Core/Core.vcxproj.filters
+++ b/Core/Core.vcxproj.filters
@@ -120,6 +120,9 @@
Header Files\Interfaces
+
+ Header Files\Mappers
+
diff --git a/Core/MapperFactory.h b/Core/MapperFactory.h
index 45d9ff71..20773766 100644
--- a/Core/MapperFactory.h
+++ b/Core/MapperFactory.h
@@ -1,5 +1,6 @@
#include "stdafx.h"
#include "ROMLoader.h"
+#include "AXROM.h"
#include "CNROM.h"
#include "MMC1.h"
#include "MMC3.h"
@@ -8,6 +9,22 @@
class MapperFactory
{
+ private:
+ static BaseMapper* GetMapperFromID(uint8_t mapperID)
+ {
+ switch(mapperID) {
+ case 0: return new NROM();
+ case 1: return new MMC1();
+ case 2: return new UNROM();
+ case 3: return new CNROM();
+ case 4: return new MMC3();
+ case 7: return new AXROM();
+ }
+
+ throw std::exception("Unsupported mapper");
+ return nullptr;
+ }
+
public:
static shared_ptr InitializeFromFile(wstring filename)
{
@@ -15,19 +32,7 @@ class MapperFactory
uint8_t mapperID = loader.GetMapperID();
- BaseMapper* mapper = nullptr;
- switch(mapperID) {
- case 0: mapper = new NROM(); break;
- case 1: mapper = new MMC1(); break;
- case 2: mapper = new UNROM(); break;
- case 3: mapper = new CNROM(); break;
- case 4: mapper = new MMC3(); break;
- }
-
- if(!mapper) {
- throw std::exception("Unsupported mapper");
- }
-
+ BaseMapper* mapper = GetMapperFromID(mapperID);
mapper->Initialize(loader);
return shared_ptr(mapper);
}
diff --git a/Core/MemoryManager.cpp b/Core/MemoryManager.cpp
index e3b79f11..a0a2c6a4 100644
--- a/Core/MemoryManager.cpp
+++ b/Core/MemoryManager.cpp
@@ -147,7 +147,21 @@ uint8_t MemoryManager::ReadVRAM(uint16_t addr)
if(addr >= 0x3000) {
addr -= 0x1000;
}
- return _videoRAM[addr & 0x3FFF];
+
+ switch(_mapper->GetMirroringType()) {
+ case MirroringType::Vertical:
+ case MirroringType::Horizontal:
+ case MirroringType::FourScreens:
+ default:
+ return _videoRAM[addr & 0x3FFF];
+
+ case MirroringType::ScreenAOnly:
+ return _videoRAM[addr & 0x33FF];
+
+ case MirroringType::ScreenBOnly:
+ return _videoRAM[addr & 0x33FF | 0x400];
+ }
+
}
}
@@ -163,52 +177,27 @@ void MemoryManager::WriteVRAM(uint16_t addr, uint8_t value)
addr -= 0x1000;
}
- _videoRAM[addr] = value;
-
switch(_mapper->GetMirroringType()) {
case MirroringType::Vertical:
- if(addr >= 0x2000 && addr < 0x2400) {
- _videoRAM[addr + 0x800] = value;
- } else if(addr >= 0x2400 && addr < 0x2800) {
- _videoRAM[addr + 0x800] = value;
- } else if(addr >= 0x2800 && addr < 0x2C00) {
- _videoRAM[addr - 0x800] = value;
- } else if(addr >= 0x2C00 && addr < 0x3000) {
- _videoRAM[addr - 0x800] = value;
- }
+ _videoRAM[addr] = value;
+ _videoRAM[addr ^ 0x800] = value;
break;
case MirroringType::Horizontal:
- if(addr >= 0x2000 && addr < 0x2400) {
- _videoRAM[addr + 0x400] = value;
- } else if(addr >= 0x2400 && addr < 0x2800) {
- _videoRAM[addr - 0x400] = value;
- } else if(addr >= 0x2800 && addr < 0x2C00) {
- _videoRAM[addr + 0x400] = value;
- } else if(addr >= 0x2C00 && addr < 0x3000) {
- _videoRAM[addr - 0x400] = value;
- }
+ _videoRAM[addr] = value;
+ _videoRAM[addr ^ 0x400] = value;
break;
- case MirroringType::ScreenAOnly:
- case MirroringType::ScreenBOnly:
- if(addr >= 0x2000 && addr < 0x2400) {
- _videoRAM[addr + 0x400] = value;
- _videoRAM[addr + 0x800] = value;
- _videoRAM[addr + 0xC00] = value;
- } else if(addr >= 0x2400 && addr < 0x2800) {
- _videoRAM[addr - 0x400] = value;
- _videoRAM[addr + 0x400] = value;
- _videoRAM[addr + 0x800] = value;
- } else if(addr >= 0x2800 && addr < 0x2C00) {
- _videoRAM[addr + 0x400] = value;
- _videoRAM[addr - 0x400] = value;
- _videoRAM[addr - 0x800] = value;
- } else if(addr >= 0x2C00 && addr < 0x3000) {
- _videoRAM[addr - 0x400] = value;
- _videoRAM[addr - 0x800] = value;
- _videoRAM[addr - 0xC00] = value;
- }
+ case MirroringType::ScreenAOnly: //Always write to 0x2000
+ _videoRAM[addr & ~0xC00] = value;
+ break;
+
+ case MirroringType::ScreenBOnly: //Always write to 0x2400
+ _videoRAM[addr & ~0x800 | 0x400] = value;
+ break;
+
+ case MirroringType::FourScreens:
+ _videoRAM[addr] = value;
break;
default: