diff --git a/src/GPU.cpp b/src/GPU.cpp
index 35ebaba1..ed73e297 100644
--- a/src/GPU.cpp
+++ b/src/GPU.cpp
@@ -142,6 +142,9 @@ u8 VRAMFlat_BOBJExtPal[8*1024];
 u8 VRAMFlat_Texture[512*1024];
 u8 VRAMFlat_TexPal[128*1024];
 
+u32 OAMDirty;
+u32 PaletteDirty;
+
 bool Init()
 {
     GPU2D_A = new GPU2D_Soft(0);
@@ -272,6 +275,9 @@ void Reset()
     ResetRenderer();
 
     ResetVRAMCache();
+
+    OAMDirty = 0x3;
+    PaletteDirty = 0xF;
 }
 
 void Stop()
diff --git a/src/GPU.h b/src/GPU.h
index cc62e1ea..377bd9e2 100644
--- a/src/GPU.h
+++ b/src/GPU.h
@@ -147,6 +147,9 @@ bool MakeVRAMFlat_TexPalCoherent(NonStupidBitField<128*1024/VRAMDirtyGranularity
 
 void SyncDirtyFlags();
 
+extern u32 OAMDirty;
+extern u32 PaletteDirty;
+
 typedef struct
 {
     bool Soft_Threaded;
@@ -509,6 +512,35 @@ T ReadVRAM_TexPal(u32 addr)
     return ret;
 }
 
+template<typename T>
+T ReadPalette(u32 addr)
+{
+    return *(T*)&Palette[addr & 0x7FF];
+}
+
+template<typename T>
+void WritePalette(u32 addr, T val)
+{
+    addr &= 0x7FF;
+
+    *(T*)&Palette[addr] = val;
+    PaletteDirty |= 1 << (addr / VRAMDirtyGranularity);
+}
+
+template<typename T>
+T ReadOAM(u32 addr)
+{
+    return *(T*)&OAM[addr & 0x7FF];
+}
+
+template<typename T>
+void WriteOAM(u32 addr, T val)
+{
+    addr &= 0x7FF;
+
+    *(T*)&OAM[addr] = val;
+    OAMDirty |= 1 << (addr / 1024);
+}
 
 void SetPowerCnt(u32 val);
 
diff --git a/src/NDS.cpp b/src/NDS.cpp
index 8b49328f..896af866 100644
--- a/src/NDS.cpp
+++ b/src/NDS.cpp
@@ -1881,7 +1881,7 @@ u8 ARM9Read8(u32 addr)
 
     case 0x05000000:
         if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return 0;
-        return *(u8*)&GPU::Palette[addr & 0x7FF];
+        return GPU::ReadPalette<u8>(addr);
 
     case 0x06000000:
         switch (addr & 0x00E00000)
@@ -1895,7 +1895,7 @@ u8 ARM9Read8(u32 addr)
 
     case 0x07000000:
         if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return 0;
-        return *(u8*)&GPU::OAM[addr & 0x7FF];
+        return GPU::ReadOAM<u8>(addr);
 
     case 0x08000000:
     case 0x09000000:
@@ -1946,7 +1946,7 @@ u16 ARM9Read16(u32 addr)
 
     case 0x05000000:
         if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return 0;
-        return *(u16*)&GPU::Palette[addr & 0x7FF];
+        return GPU::ReadPalette<u16>(addr);
 
     case 0x06000000:
         switch (addr & 0x00E00000)
@@ -1960,7 +1960,7 @@ u16 ARM9Read16(u32 addr)
 
     case 0x07000000:
         if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return 0;
-        return *(u16*)&GPU::OAM[addr & 0x7FF];
+        return GPU::ReadOAM<u16>(addr);
 
     case 0x08000000:
     case 0x09000000:
@@ -2011,7 +2011,7 @@ u32 ARM9Read32(u32 addr)
 
     case 0x05000000:
         if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return 0;
-        return *(u32*)&GPU::Palette[addr & 0x7FF];
+        return GPU::ReadPalette<u32>(addr);
 
     case 0x06000000:
         switch (addr & 0x00E00000)
@@ -2025,7 +2025,7 @@ u32 ARM9Read32(u32 addr)
 
     case 0x07000000:
         if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return 0;
-        return *(u32*)&GPU::OAM[addr & 0x7FF];
+        return GPU::ReadOAM<u32>(addr & 0x7FF);
 
     case 0x08000000:
     case 0x09000000:
@@ -2132,7 +2132,7 @@ void ARM9Write16(u32 addr, u16 val)
 
     case 0x05000000:
         if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return;
-        *(u16*)&GPU::Palette[addr & 0x7FF] = val;
+        GPU::WritePalette<u16>(addr, val);
         return;
 
     case 0x06000000:
@@ -2150,7 +2150,7 @@ void ARM9Write16(u32 addr, u16 val)
 
     case 0x07000000:
         if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return;
-        *(u16*)&GPU::OAM[addr & 0x7FF] = val;
+        GPU::WriteOAM<u16>(addr, val);
         return;
 
     case 0x08000000:
@@ -2207,7 +2207,7 @@ void ARM9Write32(u32 addr, u32 val)
 
     case 0x05000000:
         if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return;
-        *(u32*)&GPU::Palette[addr & 0x7FF] = val;
+        GPU::WritePalette(addr, val);
         return;
 
     case 0x06000000:
@@ -2225,7 +2225,7 @@ void ARM9Write32(u32 addr, u32 val)
 
     case 0x07000000:
         if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return;
-        *(u32*)&GPU::OAM[addr & 0x7FF] = val;
+        GPU::WriteOAM<u32>(addr, val);
         return;
 
     case 0x08000000: