diff --git a/desmume/src/GPU.cpp b/desmume/src/GPU.cpp
index 40e6a21fc..7db750613 100644
--- a/desmume/src/GPU.cpp
+++ b/desmume/src/GPU.cpp
@@ -53,6 +53,7 @@
 #include "GPU_osd.h"
 #include "debug.h"
 #include "NDSSystem.h"
+#include "readwrite.h"
 
 ARM9_struct ARM9Mem;
 
@@ -2794,6 +2795,7 @@ static void GPU_ligne_layer(NDS_Screen * screen, u16 l)
 							continue;
 						}
 					}
+					//if(gpu->core == 1 && i16 != 1) continue;
 					gpu->modeRender(i16);
 				} //layer enabled
 			}
@@ -3212,12 +3214,40 @@ void GPU_ligne(NDS_Screen * screen, u16 l)
 
 void gpu_savestate(std::ostream* os)
 {
+	//version
+	write32le(0,os);
+	
 	os->write((char*)GPU_tempScreen,sizeof(GPU_tempScreen));
+	
+	write32le(MainScreen.gpu->affineInfo[0].x,os);
+	write32le(MainScreen.gpu->affineInfo[0].y,os);
+	write32le(MainScreen.gpu->affineInfo[1].x,os);
+	write32le(MainScreen.gpu->affineInfo[1].y,os);
+	write32le(SubScreen.gpu->affineInfo[0].x,os);
+	write32le(SubScreen.gpu->affineInfo[0].y,os);
+	write32le(SubScreen.gpu->affineInfo[1].x,os);
+	write32le(SubScreen.gpu->affineInfo[1].y,os);
 }
 
 bool gpu_loadstate(std::istream* is)
 {
+	//read version
+	int version;
+	if(read32le(&version,is) != 1) return false;
+	if(version != 0) return false;
+
 	is->read((char*)GPU_tempScreen,sizeof(GPU_tempScreen));
+	read32le(&MainScreen.gpu->affineInfo[0].x,is);
+	read32le(&MainScreen.gpu->affineInfo[0].y,is);
+	read32le(&MainScreen.gpu->affineInfo[1].x,is);
+	read32le(&MainScreen.gpu->affineInfo[1].y,is);
+	read32le(&SubScreen.gpu->affineInfo[0].x,is);
+	read32le(&SubScreen.gpu->affineInfo[0].y,is);
+	read32le(&SubScreen.gpu->affineInfo[1].x,is);
+	read32le(&SubScreen.gpu->affineInfo[1].y,is);
+
+	MainScreen.gpu->refreshAffineStartRegs();
+	SubScreen.gpu->refreshAffineStartRegs();
 	MainScreen.gpu->updateBLDALPHA();
 	SubScreen.gpu->updateBLDALPHA();
 	return !is->fail();
diff --git a/desmume/src/MMU.cpp b/desmume/src/MMU.cpp
index 4cd0c0edc..bada17171 100644
--- a/desmume/src/MMU.cpp
+++ b/desmume/src/MMU.cpp
@@ -430,6 +430,10 @@ FORCEINLINE void* MMU_gpu_map(u32 vram_addr)
 	//it could also potentially go through a different LUT than vram_arm9_map in case we discover
 	//that it needs to be set up with different or no mirroring
 	//(I think it is a reasonable possibility that only the cpu has the nutty mirroring rules)
+	//
+	//if this system isn't used, Fantasy Aquarium displays garbage in the first ingame screen
+	//due to it storing 0x0F0F or somesuch in screen memory which points to a ridiculously big tile
+	//which should contain all 0 pixels
 
 	u32 vram_page = (vram_addr>>14)&(VRAM_ARM9_PAGES-1);
 	u32 ofs = vram_addr & 0x3FFF;
@@ -532,6 +536,11 @@ static inline u8* MMU_vram_physical(const int page)
 //todo - templateize
 //note: it doesnt seem right to me to map LCDC whenever a bank is allocated to BG/OBJ but thats how it is
 //(in FF4, when entering a town from worldmap, the subscreen tiles are via LCDC while mapped to sub BG)
+//UPDATED: i had to take them out in order to fix tetris DS music mode.
+//since then, other issues fixed FF4's problems, so they are staying out for now
+//as further, almost definitive proof that these should remain unmapped,
+//making them mapped permit's spiderman2's legal screens / intro FMV to render garbage
+//on top of the studio logo if you interrupt it by pressing enter. 
 static inline void MMU_VRAMmapRefreshBank(const int bank)
 {
 	int block = bank;
@@ -557,7 +566,7 @@ static inline void MMU_VRAMmapRefreshBank(const int bank)
 				break;
 			case 1: //ABG
 				vramConfiguration.banks[bank].purpose = VramConfiguration::ABG;
-				MMU_vram_lcdc(bank);
+				//MMU_vram_lcdc(bank);
 				MMU_vram_arm9(bank,VRAM_PAGE_ABG+ofs*8);
 				break;
 			case 2: //AOBJ
@@ -565,7 +574,7 @@ static inline void MMU_VRAMmapRefreshBank(const int bank)
 				switch(ofs) {
 				case 0:
 				case 1:
-					MMU_vram_lcdc(bank);
+					//MMU_vram_lcdc(bank);
 					MMU_vram_arm9(bank,VRAM_PAGE_AOBJ+ofs*8);
 					break;
 				default:
@@ -591,7 +600,7 @@ static inline void MMU_VRAMmapRefreshBank(const int bank)
 				break;
 			case 1: //ABG
 				vramConfiguration.banks[bank].purpose = VramConfiguration::ABG;
-				MMU_vram_lcdc(bank);
+				//MMU_vram_lcdc(bank);
 				MMU_vram_arm9(bank,VRAM_PAGE_ABG+ofs*8);
 				break;
 			case 2: //arm7
@@ -613,7 +622,7 @@ static inline void MMU_VRAMmapRefreshBank(const int bank)
 				ARM9Mem.texInfo.textureSlotAddr[ofs] = MMU_vram_physical(vram_bank_info[bank].page_addr);
 				break;
 			case 4: //BGB or BOBJ
-				MMU_vram_lcdc(bank);
+				//MMU_vram_lcdc(bank);
 				if(bank == VRAM_BANK_C)  {
 					vramConfiguration.banks[bank].purpose = VramConfiguration::BBG;
 					MMU_vram_arm9(bank,VRAM_PAGE_BBG); //BBG
@@ -635,11 +644,11 @@ static inline void MMU_VRAMmapRefreshBank(const int bank)
 				break;
 			case 1: //ABG
 				vramConfiguration.banks[bank].purpose = VramConfiguration::ABG;
-				MMU_vram_lcdc(bank);
+				//MMU_vram_lcdc(bank);
 				MMU_vram_arm9(bank,VRAM_PAGE_ABG);
 				break;
 			case 2: //AOBJ
-				MMU_vram_lcdc(bank);
+				//MMU_vram_lcdc(bank);
 				vramConfiguration.banks[bank].purpose = VramConfiguration::AOBJ;
 				MMU_vram_arm9(bank,VRAM_PAGE_AOBJ);
 				break;
@@ -675,13 +684,13 @@ static inline void MMU_VRAMmapRefreshBank(const int bank)
 				break;
 			case 1: //ABG
 				vramConfiguration.banks[bank].purpose = VramConfiguration::ABG;
-				MMU_vram_lcdc(bank);
+				//MMU_vram_lcdc(bank);
 				MMU_vram_arm9(bank,VRAM_PAGE_ABG+pageofs);
 				MMU_vram_arm9(bank,VRAM_PAGE_ABG+pageofs+2); //unexpected mirroring (required by spyro eternal night)
 				break;
 			case 2: //AOBJ
 				vramConfiguration.banks[bank].purpose = VramConfiguration::AOBJ;
-				MMU_vram_lcdc(bank);
+				//MMU_vram_lcdc(bank);
 				MMU_vram_arm9(bank,VRAM_PAGE_AOBJ+pageofs);
 				MMU_vram_arm9(bank,VRAM_PAGE_AOBJ+pageofs+2); //unexpected mirroring - I have no proof, but it is inferred from the ABG above
 				break;
@@ -723,7 +732,7 @@ static inline void MMU_VRAMmapRefreshBank(const int bank)
 				break;
 			case 1: //BBG
 				vramConfiguration.banks[bank].purpose = VramConfiguration::BBG;
-				MMU_vram_lcdc(bank);
+				//MMU_vram_lcdc(bank);
 				MMU_vram_arm9(bank,VRAM_PAGE_BBG);
 				MMU_vram_arm9(bank,VRAM_PAGE_BBG + 4); //unexpected mirroring
 				break;
@@ -748,13 +757,13 @@ static inline void MMU_VRAMmapRefreshBank(const int bank)
 				break;
 			case 1: //BBG
 				vramConfiguration.banks[bank].purpose = VramConfiguration::BBG;
-				MMU_vram_lcdc(bank);
+				//MMU_vram_lcdc(bank);
 				MMU_vram_arm9(bank,VRAM_PAGE_BBG+2);
 				MMU_vram_arm9(bank,VRAM_PAGE_BBG+3); //unexpected mirroring
 				break;
 			case 2: //BOBJ
 				vramConfiguration.banks[bank].purpose = VramConfiguration::BOBJ;
-				MMU_vram_lcdc(bank);
+				//MMU_vram_lcdc(bank);
 				MMU_vram_arm9(bank,VRAM_PAGE_BOBJ);
 				break;
 			case 3: //B OBJ extended palette
diff --git a/desmume/src/gfx3d.h b/desmume/src/gfx3d.h
index 2481c73a2..eb65084c6 100644
--- a/desmume/src/gfx3d.h
+++ b/desmume/src/gfx3d.h
@@ -61,6 +61,9 @@
 void gfx3d_init();
 void gfx3d_reset();
 
+#define OSWRITE(x) os->write((char*)&(x),sizeof((x)));
+#define OSREAD(x) is->read((char*)&(x),sizeof((x)));
+
 struct POLY {
 	int type; //tri or quad
 	u16 vertIndexes[4]; //up to four verts can be referenced by this poly
diff --git a/desmume/src/windows/DeSmuME_2005.sln b/desmume/src/windows/DeSmuME_2005.sln
index c1443642b..a5a94fd92 100644
--- a/desmume/src/windows/DeSmuME_2005.sln
+++ b/desmume/src/windows/DeSmuME_2005.sln
@@ -17,4 +17,7 @@ Global
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
 	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		AMDCaProjectFile = C:\svn\desmume\trunk\desmume\src\windows\CodeAnalyst\DeSmuME_2005.caw
+	EndGlobalSection
 EndGlobal