diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6051cf9e..1d855eef 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -217,6 +217,7 @@ SET(SRC_GBA
src/gba/Cheats.cpp
src/gba/CheatSearch.cpp
src/gba/EEprom.cpp
+ src/gba/ereader.cpp
src/gba/Flash.cpp
src/gba/GBA.cpp
src/gba/GBAGfx.cpp
diff --git a/project/vc2008_mfc/VBA2008.vcproj b/project/vc2008_mfc/VBA2008.vcproj
index 7dcbc0ee..ee0e758e 100644
--- a/project/vc2008_mfc/VBA2008.vcproj
+++ b/project/vc2008_mfc/VBA2008.vcproj
@@ -430,6 +430,14 @@
RelativePath="..\..\src\gba\agbprint.h"
>
+
+
+
+
diff --git a/project/vs2010_mfc/VBA2010.sln b/project/vs2010_mfc/VBA2010.sln
index e5211571..59df2772 100644
--- a/project/vs2010_mfc/VBA2010.sln
+++ b/project/vs2010_mfc/VBA2010.sln
@@ -6,7 +6,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VisualBoyAdvance-M", "VBA20
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "..\..\..\dependencies\zlib\project\vs2010\zlib.vcxproj", "{3E03C179-8251-46E4-81F4-466F114BAC63}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SFML_Network", "..\..\..\dependencies\SFML\build\vc2010\sfml-network.vcxproj", "{823DDC98-42D5-4A38-88CF-9DC06C788AE4}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SFML", "..\..\..\dependencies\SFML\build\vc2010\sfml-network.vcxproj", "{823DDC98-42D5-4A38-88CF-9DC06C788AE4}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libpng", "..\..\..\dependencies\libpng\project\vs2010\libpng.vcxproj", "{0008960E-E0DD-41A6-8265-00B31DDB4C21}"
EndProject
diff --git a/project/vs2010_mfc/VBA2010.vcxproj b/project/vs2010_mfc/VBA2010.vcxproj
index 6ed18df8..ef232c28 100644
--- a/project/vs2010_mfc/VBA2010.vcxproj
+++ b/project/vs2010_mfc/VBA2010.vcxproj
@@ -110,7 +110,7 @@
AnySuitable
Speed
..\..\src;..\..\fex;..\..\..\dependencies\libpng;..\..\..\dependencies\msvc;..\..\..\dependencies\SFML\include;..\..\..\dependencies\SubWCRev;..\..\..\dependencies\zlib;%(AdditionalIncludeDirectories)
- WIN32;_WINDOWS;NDEBUG;GBA_LOGGING;OEMRESOURCE;MMX;ASM;FINAL_VERSION;BKPT_SUPPORT;_CRT_SECURE_NO_DEPRECATE;HAS_FILE_EXTRACTOR;%(PreprocessorDefinitions)
+ WIN32;_WINDOWS;NO_OAL;NDEBUG;GBA_LOGGING;OEMRESOURCE;MMX;ASM;FINAL_VERSION;BKPT_SUPPORT;_CRT_SECURE_NO_DEPRECATE;HAS_FILE_EXTRACTOR;%(PreprocessorDefinitions)
MultiThreaded
StreamingSIMDExtensions
Fast
@@ -166,6 +166,7 @@
+
@@ -295,6 +296,7 @@
+
diff --git a/project/vs2010_mfc/VBA2010.vcxproj.filters b/project/vs2010_mfc/VBA2010.vcxproj.filters
index 689f593f..0af12e8f 100644
--- a/project/vs2010_mfc/VBA2010.vcxproj.filters
+++ b/project/vs2010_mfc/VBA2010.vcxproj.filters
@@ -106,6 +106,9 @@
Core\GBA
+
+ Core\GBA
+
Core\GBA
@@ -481,6 +484,9 @@
Core\GBA
+
+ Core\GBA
+
Core\GBA
diff --git a/project/vs2013_mfc/VBA2013.vcxproj b/project/vs2013_mfc/VBA2013.vcxproj
index 70d3d60d..fa2ffe80 100644
--- a/project/vs2013_mfc/VBA2013.vcxproj
+++ b/project/vs2013_mfc/VBA2013.vcxproj
@@ -176,6 +176,7 @@
+
@@ -303,6 +304,7 @@
+
diff --git a/project/vs2013_mfc/VBA2013.vcxproj.filters b/project/vs2013_mfc/VBA2013.vcxproj.filters
index 70ddff39..d4a40f95 100644
--- a/project/vs2013_mfc/VBA2013.vcxproj.filters
+++ b/project/vs2013_mfc/VBA2013.vcxproj.filters
@@ -118,6 +118,9 @@
Core\GBA
+
+ Core\GBA
+
Core\GBA
@@ -487,6 +490,9 @@
Core\GBA
+
+ Core\GBA
+
Core\GBA
diff --git a/src/gba/GBA.cpp b/src/gba/GBA.cpp
index 2cb4f075..71494e34 100644
--- a/src/gba/GBA.cpp
+++ b/src/gba/GBA.cpp
@@ -20,6 +20,7 @@
#include "../common/Port.h"
#include "../System.h"
#include "agbprint.h"
+#include "ereader.h"
#include "GBALink.h"
#ifdef PROFILING
@@ -161,6 +162,9 @@ u8 memoryWaitSeq32[16] =
u8 biosProtected[4];
+const char *loadDotCodeFile;
+const char *saveDotCodeFile;
+
#ifdef WORDS_BIGENDIAN
bool cpuBiosSwapped = false;
#endif
@@ -1618,6 +1622,26 @@ void doMirroring (bool b)
}
}
+const char* GetLoadDotCodeFile()
+{
+ return loadDotCodeFile;
+}
+
+const char* GetSaveDotCodeFile()
+{
+ return saveDotCodeFile;
+}
+
+void SetLoadDotCodeFile(const char *szFile)
+{
+ loadDotCodeFile = szFile;
+}
+
+void SetSaveDotCodeFile(const char *szFile)
+{
+ saveDotCodeFile = szFile;
+}
+
void CPUUpdateRender()
{
switch(DISPCNT & 7) {
@@ -1933,8 +1957,19 @@ void CPUSoftwareInterrupt(int comment)
VCOUNT);
}
#endif
- CPUSoftwareInterrupt();
- return;
+ if ((comment & 0xF8) != 0xE0)
+ {
+ CPUSoftwareInterrupt();
+ return;
+ }
+ else
+ {
+ if (CheckEReaderRegion())
+ BIOS_EReader_ScanCard(comment);
+ else
+ CPUSoftwareInterrupt();
+ return;
+ }
}
// This would be correct, but it causes problems if uncommented
// else {
@@ -2162,6 +2197,17 @@ void CPUSoftwareInterrupt(int comment)
case 0x1F:
BIOS_MidiKey2Freq();
break;
+ case 0xE0:
+ case 0xE1:
+ case 0xE2:
+ case 0xE3:
+ case 0xE4:
+ case 0xE5:
+ case 0xE6:
+ case 0xE7:
+ if (CheckEReaderRegion())
+ BIOS_EReader_ScanCard(comment);
+ break;
case 0x2A:
BIOS_SndDriverJmpTableCopy();
// let it go, because we don't really emulate this function
@@ -3272,6 +3318,18 @@ void CPUReset()
break;
}
}
+ switch (CheckEReaderRegion())
+ {
+ case 1: //US
+ EReaderWriteMemory(0x8009134, 0x46C0DFE0);
+ break;
+ case 2:
+ EReaderWriteMemory(0x8008A8C, 0x46C0DFE0);
+ break;
+ case 3:
+ EReaderWriteMemory(0x80091A8, 0x46C0DFE0);
+ break;
+ }
rtcReset();
// clean registers
memset(®[0], 0, sizeof(reg));
diff --git a/src/gba/GBA.h b/src/gba/GBA.h
index 7da9df11..5feca67c 100644
--- a/src/gba/GBA.h
+++ b/src/gba/GBA.h
@@ -114,6 +114,11 @@ extern void cpuProfil(profile_segment *seg);
extern void cpuEnableProfiling(int hz);
#endif
+const char* GetLoadDotCodeFile();
+const char* GetSaveDotCodeFile();
+void SetLoadDotCodeFile(const char *szFile);
+void SetSaveDotCodeFile(const char *szFile);
+
extern struct EmulatedSystem GBASystem;
#define R13_IRQ 18
diff --git a/src/gba/ereader.cpp b/src/gba/ereader.cpp
new file mode 100644
index 00000000..64197a92
--- /dev/null
+++ b/src/gba/ereader.cpp
@@ -0,0 +1,670 @@
+#include
+#include
+#include
+#include
+
+#include "GBA.h"
+#include "GBAinline.h"
+#include "Globals.h"
+#include "ereader.h"
+
+
+//#include "win32/stdafx.h"
+//#include "win32/vba.h"
+//#include "win32/MainWnd.h"
+//#include "win32/FileDlg.h"
+//#include "win32/WinResUtil.h"
+//#include "win32/MainWnd.h"
+
+
+int eReaderSaveRAW = 1;
+
+char US_Ereader[19] = "CARDE READERPSAE01";
+char JAP_Ereader[19] = "CARDE READERPEAJ01";
+char JAP_Ereader_plus[19] = "CARDEREADER+PSAJ01";
+char rom_info[19];
+
+char Signature[0x29] = "E-Reader Dotcode -Created- by CaitSith2";
+
+
+unsigned char ShortDotCodeHeader[0x30] = {
+ 0x00, 0x30, 0x01, 0x01,
+ 0x00, 0x01, 0x05, 0x10,
+ 0x00, 0x00, 0x10, 0x12, //Constant data
+
+ 0x00, 0x00, //Header First 2 bytes
+
+ 0x02, 0x00, //Constant data
+
+ 0x00, 0x00, //Header Second 2 bytes
+
+ 0x10, 0x47, 0xEF, //Global Checksum 1
+
+ 0x19, 0x00, 0x00, 0x00, 0x08, 0x4E, 0x49,
+ 0x4E, 0x54, 0x45, 0x4E, 0x44, 0x4F, 0x00, 0x22,
+ 0x00, 0x09, //Constant data
+
+ 0x00, 0x00, //Header, last 8 bytes
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00,
+ 0x00, //Header Checksum
+ 0x57 //Global Checksum 2
+};
+
+unsigned char LongDotCodeHeader[0x30] = {
+ 0x00, 0x30, 0x01, 0x02,
+ 0x00, 0x01, 0x08, 0x10,
+ 0x00, 0x00, 0x10, 0x12, //Constant Data
+
+ 0x00, 0x00, //Header, first 2 bytes
+
+ 0x01, 0x00, //Constant data
+
+ 0x00, 0x00, //Header, second 2 bytes
+ 0x10, 0x9A, 0x99, //Global Checksum 1
+
+ 0x19, 0x00, 0x00, 0x00, 0x08, 0x4E, 0x49,
+ 0x4E, 0x54, 0x45, 0x4E, 0x44, 0x4F, 0x00, 0x22,
+ 0x00, 0x09, //Constant data
+
+
+ 0x00, 0x00, //Header, last 8 bytes
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00,
+ 0x00, //Header Checksum
+ 0x57 //Global Checksum 2
+};
+
+unsigned char shortheader[0x18] = {
+ 0x00, 0x02, 0x00, 0x01, 0x40, 0x10, 0x00, 0x1C,
+ 0x10, 0x6F, 0x40, 0xDA, 0x39, 0x25, 0x8E, 0xE0,
+ 0x7B, 0xB5, 0x98, 0xB6, 0x5B, 0xCF, 0x7F, 0x72
+};
+unsigned char longheader[0x18] = {
+ 0x00, 0x03, 0x00, 0x19, 0x40, 0x10, 0x00, 0x2C,
+ 0x0E, 0x88, 0xED, 0x82, 0x50, 0x67, 0xFB, 0xD1,
+ 0x43, 0xEE, 0x03, 0xC6, 0xC6, 0x2B, 0x2C, 0x93
+};
+
+unsigned char dotcodeheader[0x48];
+unsigned char dotcodedata[0xB38];
+unsigned char dotcodetemp[0xB00];
+int dotcodepointer;
+int dotcodeinterleave;
+int decodestate;
+
+u32 GFpow;
+
+unsigned char *DotCodeData;
+char filebuffer[2048];
+
+int dotcodesize;
+
+int CheckEReaderRegion(void) //US = 1, JAP = 2, JAP+ = 3
+{
+ int i;
+ for(i=0;i<18;i++)
+ rom_info[i] = rom[0xA0+i];
+ rom_info[i] = 0;
+
+ if (std::tolower(*rom_info, std::locale()) == std::tolower(*US_Ereader, std::locale()))
+ return 1;
+ if (std::tolower(*rom_info, std::locale()) == std::tolower(*JAP_Ereader, std::locale()))
+ return 2;
+ if (std::tolower(*rom_info, std::locale()) == std::tolower(*JAP_Ereader_plus, std::locale()))
+ return 3;
+
+ return 0;
+}
+
+int LoadDotCodeData(int size, u32* DCdata, unsigned long MEM1, unsigned long MEM2, int loadraw)
+{
+ u32 temp1;
+ int i,j;
+
+ unsigned char scanmap[28];
+ int scantotal=0;
+
+ for(i=0;i<28;i++)
+ scanmap[i] = 0;
+
+ unsigned char longdotcodescan[28] = {
+ 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
+ 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
+ 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
+ 0xF1, 0xF2, 0xB1, 0xB1
+ };
+ unsigned char shortdotcodescan[18] = {
+ 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
+ 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
+ 0xF1, 0xF1, 0xF1, 0xF2, 0xB1, 0xB1
+ };
+
+ temp1 = CPUReadMemory(MEM1-4);
+ for(i=0;i<0x60;i+=4)
+ CPUWriteMemory((MEM2-8)+i,0);
+ for(i=0;i<0x1860;i+=4)
+ CPUWriteMemory(temp1+i,0);
+ if(DCdata != NULL)
+ {
+ if(size==0xB60)
+ {
+ for(i=0;i<28;i++)
+ {
+ for(j=0,scantotal=0;j<0x68;j+=4)
+ {
+ scantotal += DCdata[((i*0x68)+j)>>2];
+ }
+ if(scantotal)
+ scanmap[i] = longdotcodescan[i];
+ }
+ for(i=0;i>2]);
+ }
+ }
+ else if (size==0x750)
+ {
+ for(i=0;i<18;i++)
+ {
+ if((DCdata[0] == 0x02011394) && (DCdata[1] == 0x0203E110) && (i == 0))
+ continue;
+ for(j=0,scantotal=0;j<0x68;j+=4)
+ {
+ scantotal += DCdata[((i*0x68)+j)>>2];
+ }
+ if(scantotal)
+ scanmap[i] = longdotcodescan[i];
+ }
+ for(i=0;i>2]);
+ }
+ }
+ }
+ CPUWriteMemory(MEM2-8,0x1860);
+ CPUWriteMemory(MEM2-4,temp1);
+
+
+ if(size==0xB60)
+ {
+ if(loadraw)
+ {
+ for(i=0;i<28;i++)
+ CPUWriteByte(MEM2+0x18+i,scanmap[i]);
+ }
+ else
+ {
+ CPUWriteMemory(MEM2+0x18,0xF1F1F1F1);
+ CPUWriteMemory(MEM2+0x18+4,0xF1F1F1F1);
+ CPUWriteMemory(MEM2+0x18+8,0xF1F1F1F1);
+ CPUWriteMemory(MEM2+0x18+12,0xF1F1F1F1);
+ CPUWriteMemory(MEM2+0x18+16,0xF1F1F1F1);
+ CPUWriteMemory(MEM2+0x18+20,0xF1F1F1F1);
+ CPUWriteMemory(MEM2+0x18+24,0xB1B1F2F1);
+ }
+ CPUWriteMemory(MEM2+0x40,0x19);
+ CPUWriteMemory(MEM2+0x44,0x34);
+ }
+ else if (size==0x750)
+ {
+ if(loadraw)
+ {
+ for(i=0;i<18;i++)
+ CPUWriteByte(MEM2+i,scanmap[i]);
+ }
+ else
+ {
+ CPUWriteMemory(MEM2,0xF1F1F1F1);
+ CPUWriteMemory(MEM2+4,0xF1F1F1F1);
+ CPUWriteMemory(MEM2+8,0xF1F1F1F1);
+ CPUWriteMemory(MEM2+12,0xF2F1F1F1);
+ CPUWriteMemory(MEM2+16,0xB1B1);
+ }
+ CPUWriteMemory(MEM2+0x40,0x01);
+ CPUWriteMemory(MEM2+0x44,0x12);
+ }
+ CPUWriteMemory(MEM2+0x48,0x3C);
+ CPUWriteMemory(MEM2+0x4C,MEM2);
+
+ return 0;
+}
+
+void EReaderWriteMemory(u32 address, u32 value)
+{
+ switch(address >> 24)
+ {
+ case 2:
+ WRITE32LE(((u32 *)&workRAM[address & 0x3FFFF]), value);
+ break;
+ case 3:
+ WRITE32LE(((u32 *)&internalRAM[address & 0x7FFF]), value);
+ break;
+ default:
+ WRITE32LE(((u32 *)&rom[address & 0x1FFFFFF]), value);
+ //rom[address & 0x1FFFFFF] = data;
+ break;
+ }
+}
+
+
+void BIOS_EReader_ScanCard(int swi_num)
+{
+
+ int i,j,k;
+ int dotcodetype;
+
+ int global1, global2;
+
+ FILE *f;
+
+ //Open dotcode bin/raw
+
+ if(swi_num == 0xE0)
+ {
+ dotcodepointer = 0;
+ dotcodeinterleave = 0;
+ decodestate = 0;
+
+ const char* loadDotCodeFile = GetLoadDotCodeFile();
+
+ if (loadDotCodeFile == 0)
+ {
+ reg[0].I = 0x301;
+ return;
+ }
+ f=fopen(loadDotCodeFile,"rb");
+ //f=fopen(filebuffer,"rb");
+ //f=fopen("dotcode4.raw","rb");
+ if(f==NULL)
+ {
+ reg[0].I = 0x303;
+ return;
+ }
+ fseek(f,0,SEEK_END);
+ i=ftell(f);
+ fseek(f,0,SEEK_SET);
+ if((i==0xB60) || (i==0x750))
+ {
+ dotcodetype = 0;
+ }
+ else if ((i==0x81C) || (i==0x51C))
+ {
+ dotcodetype = 1;
+ }
+ else
+ {
+ fclose(f);
+ reg[0].I = 0x303;
+ return;
+ }
+ DotCodeData = (unsigned char*)malloc(i);
+ if(DotCodeData == NULL)
+ {
+ reg[0].I = 0x303;
+ return;
+ }
+ fread(DotCodeData,1,i,f);
+ fclose(f);
+
+ if(dotcodetype == 0)
+ {
+
+ switch(CheckEReaderRegion())
+ {
+ case 1: //US
+ LoadDotCodeData(i,(u32 *)DotCodeData,0x2032D14,0x2028B28,1);
+ EReaderWriteMemory(0x80091BA,0x46C0DFE2);
+ break;
+ case 2:
+ LoadDotCodeData(i,(u32 *)DotCodeData,0x2006EC4,0x2002478,1);
+ EReaderWriteMemory(0x8008B12,0x46C0DFE2);
+ break;
+ case 3:
+ LoadDotCodeData(i,(u32 *)DotCodeData,0x202F8A4,0x2031034,1);
+ EReaderWriteMemory(0x800922E,0x46C0DFE2);
+ break;
+ }
+ reg[0].I = 0;
+ free(DotCodeData);
+ }
+ else
+ {
+ //dotcodesize = i;
+ if(i==0x81C)
+ dotcodesize = 0xB60;
+ else
+ dotcodesize = 0x750;
+
+
+ switch(CheckEReaderRegion())
+ {
+ case 1: //US
+ LoadDotCodeData(dotcodesize,(u32 *)NULL,0x2032D14,0x2028B28,0);
+ EReaderWriteMemory(0x80091BA,0x46C0DFE1);
+ break;
+ case 2:
+ LoadDotCodeData(dotcodesize,(u32 *)NULL,0x2006EC4,0x2002478,0);
+ EReaderWriteMemory(0x8008B12,0x46C0DFE1);
+ break;
+ case 3:
+ LoadDotCodeData(dotcodesize,(u32 *)NULL,0x202F8A4,0x2031034,0);
+ EReaderWriteMemory(0x800922E,0x46C0DFE1);
+ break;
+ }
+ reg[0].I = 0;
+ dotcodesize = i;
+ }
+ }
+ else if (swi_num == 0xE1)
+ {
+
+ switch(CheckEReaderRegion())
+ {
+ case 1: //US
+ EReaderWriteMemory(0x80091BA,0xF8A5F03B);
+ EReaderWriteMemory(0x3002F7C,0xEFE40000); //Beginning of Reed-Solomon decoder
+ EReaderWriteMemory(0x3003144,0xCA00002F); //Fix required to Correct 16 "Erasures"
+ EReaderWriteMemory(0x300338C,0xEFE50000); //End of Reed-Solomon decoder
+ GFpow = 0x3000A6C;
+ break;
+ case 2:
+ EReaderWriteMemory(0x8008B12,0xFB0BF035);
+ EReaderWriteMemory(0x3002F88,0xEFE40000);
+ EReaderWriteMemory(0x3003150,0xCA00002F);
+ EReaderWriteMemory(0x3003398,0xEFE50000);
+ GFpow = 0x3000A78;
+ break;
+ case 3:
+ EReaderWriteMemory(0x800922E,0xF94BF04B);
+ EReaderWriteMemory(0x3002F7C,0xEFE40000);
+ EReaderWriteMemory(0x3003144,0xCA00002F);
+ EReaderWriteMemory(0x300338C,0xEFE50000);
+ GFpow = 0x3000A6C;
+ break;
+ }
+ armNextPC -= 2;
+ reg[15].I -= 2;
+
+ for(i=0,j=0;i<12;i++)
+ j ^= DotCodeData[i];
+ if(dotcodesize == 0x81C)
+ {
+ LongDotCodeHeader[0x2E] = j;
+ LongDotCodeHeader[0x0D] = DotCodeData[0];
+ LongDotCodeHeader[0x0C] = DotCodeData[1];
+ LongDotCodeHeader[0x11] = DotCodeData[2];
+ LongDotCodeHeader[0x10] = DotCodeData[3];
+
+ LongDotCodeHeader[0x26] = DotCodeData[4];
+ LongDotCodeHeader[0x27] = DotCodeData[5];
+ LongDotCodeHeader[0x28] = DotCodeData[6];
+ LongDotCodeHeader[0x29] = DotCodeData[7];
+ LongDotCodeHeader[0x2A] = DotCodeData[8];
+ LongDotCodeHeader[0x2B] = DotCodeData[9];
+ LongDotCodeHeader[0x2C] = DotCodeData[10];
+ LongDotCodeHeader[0x2D] = DotCodeData[11];
+
+
+ LongDotCodeHeader[0x12] = 0x10; //calculate Global Checksum 1
+ LongDotCodeHeader[0x02] = 1; //Do not calculate Global Checksum 2
+
+ for(i=0x0C,j=0;i<0x81C;i++)
+ {
+ if(i&1)
+ j += DotCodeData[i];
+ else
+ j += (DotCodeData[i] << 8);
+ }
+ j &= 0xFFFF;
+ j ^= 0xFFFF;
+ LongDotCodeHeader[0x13] = (j & 0xFF00) >> 8;
+ LongDotCodeHeader[0x14] = (j & 0x00FF);
+
+ for(i=0,j=0;i<0x2F;i++)
+ j+=LongDotCodeHeader[i];
+ j &= 0xFF;
+ for(i=1,global2=0;i<0x2C;i++)
+ {
+ for(k=0,global1=0;k<0x30;k++)
+ {
+ global1 ^= DotCodeData[((i-1)*0x30)+k+0x0C];
+ }
+ global2 += global1;
+ }
+ global2 += j;
+ global2 &= 0xFF;
+ global2 ^= 0xFF;
+ LongDotCodeHeader[0x2F] = global2;
+
+
+ }
+ else
+ {
+ ShortDotCodeHeader[0x2E] = j;
+ ShortDotCodeHeader[0x0D] = DotCodeData[0];
+ ShortDotCodeHeader[0x0C] = DotCodeData[1];
+ ShortDotCodeHeader[0x11] = DotCodeData[2];
+ ShortDotCodeHeader[0x10] = DotCodeData[3];
+
+ ShortDotCodeHeader[0x26] = DotCodeData[4];
+ ShortDotCodeHeader[0x27] = DotCodeData[5];
+ ShortDotCodeHeader[0x28] = DotCodeData[6];
+ ShortDotCodeHeader[0x29] = DotCodeData[7];
+ ShortDotCodeHeader[0x2A] = DotCodeData[8];
+ ShortDotCodeHeader[0x2B] = DotCodeData[9];
+ ShortDotCodeHeader[0x2C] = DotCodeData[10];
+ ShortDotCodeHeader[0x2D] = DotCodeData[11];
+
+ ShortDotCodeHeader[0x12] = 0x10; //calculate Global Checksum 1
+ ShortDotCodeHeader[0x02] = 1; //Do not calculate Global Checksum 2
+
+ for(i=0x0C,j=0;i<0x51C;i++)
+ {
+ if(i&1)
+ j += DotCodeData[i];
+ else
+ j += (DotCodeData[i] << 8);
+ }
+ j &= 0xFFFF;
+ j ^= 0xFFFF;
+ ShortDotCodeHeader[0x13] = (j & 0xFF00) >> 8;
+ ShortDotCodeHeader[0x14] = (j & 0x00FF);
+
+ for(i=0,j=0;i<0x2F;i++)
+ j+=ShortDotCodeHeader[i];
+ j &= 0xFF;
+ for(i=1,global2=0;i<0x1C;i++)
+ {
+ for(k=0,global1=0;k<0x30;k++)
+ {
+ global1 ^= DotCodeData[((i-1)*0x30)+k+0x0C];
+ }
+ global2 += global1;
+ }
+ global2 += j;
+ global2 &= 0xFF;
+ global2 ^= 0xFF;
+ ShortDotCodeHeader[0x2F] = global2;
+ }
+
+ }
+ else if (swi_num == 0xE2) //Header
+ {
+ switch(CheckEReaderRegion())
+ {
+ case 1: //US
+ EReaderWriteMemory(0x80091BA,0xF8A5F03B);
+ EReaderWriteMemory(0x300338C,0xEFE30000);
+ GFpow = 0x3000A6C;
+ break;
+ case 2:
+ EReaderWriteMemory(0x8008B12,0xFB0BF035);
+ EReaderWriteMemory(0x3003398,0xEFE30000);
+ GFpow = 0x3000A78;
+ break;
+ case 3:
+ EReaderWriteMemory(0x800922E,0xF94BF04B);
+ EReaderWriteMemory(0x300338C,0xEFE30000);
+ GFpow = 0x3000A6C;
+ break;
+ }
+ armNextPC -= 2;
+ reg[15].I -= 2;
+ }
+ else if ((swi_num == 0xE3) || (swi_num == 0xE5)) //Dotcode data
+ {
+ if((reg[0].I >= 0) && (reg[0].I <= 0x10))
+ {
+ if(decodestate == 0)
+ {
+ for(i=0x17;i>=0;i--)
+ {
+ if((0x17 - i) < 8)
+ j=CPUReadByte(GFpow + CPUReadByte(GFpow+0x200+i));
+ else
+ j=CPUReadByte(GFpow + CPUReadByte(GFpow+0x200+i)) ^ 0xFF;
+
+ dotcodeheader[(0x17-i)] = j;
+ dotcodeheader[(0x17-i)+0x18] = j;
+ dotcodeheader[(0x17-i)+0x30] = j;
+ }
+ for(i=0;i<28;i++)
+ for(j=0;j<2;j++)
+ dotcodedata[(i*0x68)+j] = dotcodeheader[(i*2)+j];
+ dotcodeinterleave = dotcodeheader[7];
+ decodestate = 1;
+ }
+ else
+ {
+ for(i=0x3F;i>=0;i--)
+ {
+ if((0x3F - i) < 0x30)
+ j=CPUReadByte(GFpow + CPUReadByte(GFpow+0x200+i));
+ else
+ j=CPUReadByte(GFpow + CPUReadByte(GFpow+0x200+i)) ^ 0xFF;
+ dotcodetemp[((0x3F-i)*dotcodeinterleave)+dotcodepointer] = j;
+ }
+ dotcodepointer++;
+
+ if((dotcodepointer == dotcodeinterleave))
+ {
+ switch(dotcodeinterleave)
+ {
+ case 0x1C:
+ j = 0x724;
+ k = 0x750 - j;
+ break;
+ case 0x2C:
+ j = 0xB38;
+ k = 0xB60 - j;
+ break;
+ }
+ dotcodepointer = 0;
+ for(i=2;iSetCheck(agbPrintIsEnabled());
}
+void MainWnd::OnOptionsEmulatorEreader()
+{
+ eReaderSaveRAW = !eReaderSaveRAW;
+}
+
+void MainWnd::OnUpdateOptionsEmulatorEreader(CCmdUI* pCmdUI)
+{
+ pCmdUI->SetCheck(eReaderSaveRAW == 1);
+}
+
void MainWnd::OnOptionsEmulatorRealtimeclock()
{
theApp.winRtcEnable = !theApp.winRtcEnable;
diff --git a/src/win32/VBA.cpp b/src/win32/VBA.cpp
index 69411a00..4a5e199d 100644
--- a/src/win32/VBA.cpp
+++ b/src/win32/VBA.cpp
@@ -25,6 +25,7 @@
#include "../System.h"
#include "../gba/agbprint.h"
+#include "../gba/ereader.h"
#include "../gba/cheatSearch.h"
#include "../gba/GBA.h"
#include "../gba/Globals.h"
@@ -1396,6 +1397,10 @@ void VBA::loadSettings()
{
CString buffer;
+ eReaderSaveRAW = regQueryDwordValue("eReaderSaveRAW", 1);
+ if (eReaderSaveRAW < 0 || eReaderSaveRAW > 1)
+ eReaderSaveRAW = 1;
+
lastFullscreen = (VIDEO_SIZE)regQueryDwordValue("lastFullscreen", VIDEO_1024x768);
languageOption = regQueryDwordValue("language", 1);
@@ -2492,6 +2497,8 @@ void VBA::movieReadNext()
void VBA::saveSettings()
{
+ regSetDwordValue("eReaderSaveRAW", eReaderSaveRAW);
+
regSetDwordValue("language", languageOption);
regSetStringValue("languageName", languageName);
diff --git a/src/win32/VBA.h b/src/win32/VBA.h
index 86cc4166..086e22a4 100644
--- a/src/win32/VBA.h
+++ b/src/win32/VBA.h
@@ -202,6 +202,9 @@ class VBA : public CWinApp
CString filename;
CString dir;
+ CString loadDotCodeFile;
+ CString saveDotCodeFile;
+
CString wndClass;
public:
diff --git a/src/win32/VBA.rc b/src/win32/VBA.rc
index 41a25e76..441cd8da 100644
--- a/src/win32/VBA.rc
+++ b/src/win32/VBA.rc
@@ -202,7 +202,7 @@ FONT 8, "MS Sans Serif", 0, 0, 0x1
BEGIN
ICON IDI_MAINICON,IDC_STATIC,6,6,20,20
CTEXT "VisualBoyAdvance-M Emulator",IDC_STATIC,36,6,138,8
- CTEXT "Copyright © 2008 VBA-M development team",IDC_STATIC,6,48,168,8
+ CTEXT "Copyright � 2008 VBA-M development team",IDC_STATIC,6,48,168,8
CTEXT "http://vba-m.com",IDC_URL,7,138,168,8
RTEXT "Version:",IDC_STATIC,36,18,54,8
LTEXT "",IDC_VERSION,96,18,78,8,SS_NOPREFIX
@@ -1626,7 +1626,7 @@ BEGIN
VALUE "FileDescription", "VisualBoyAdvance-M"
VALUE "FileVersion", "1, 8, 0, 0"
VALUE "InternalName", "VBA-M"
- VALUE "LegalCopyright", "Copyright © 2008-2009 VBA-M development team"
+ VALUE "LegalCopyright", "Copyright � 2008-2009 VBA-M development team"
VALUE "OriginalFilename", "VisualBoyAdvance-M.exe"
VALUE "ProductName", "GB/C/A emulator for Windows"
VALUE "ProductVersion", "1, 8, 0, 0"
@@ -1652,7 +1652,10 @@ BEGIN
MENUITEM "Open GBC...", ID_FILE_OPEN_GBC
MENUITEM "Open GB...", ID_FILE_OPEN_GB
MENUITEM "Close", ID_FILE_CLOSE
- MENUITEM SEPARATOR
+ MENUITEM SEPARATOR
+ MENUITEM "Load E-Reader DotCode...", ID_FILE_LOAD_DOTCODE
+ MENUITEM "Save E-Reader DotCode...", ID_FILE_SAVE_DOTCODE
+ MENUITEM SEPARATOR
POPUP "Recent"
BEGIN
MENUITEM "&Reset", ID_FILE_RECENT_RESET
@@ -1915,6 +1918,7 @@ BEGIN
MENUITEM "Auto-apply IPS/UPS/PPF", ID_OPTIONS_EMULATOR_AUTOMATICALLYAPPLYPATCHFILES
MENUITEM "Pause when inactive", ID_OPTIONS_EMULATOR_PAUSEWHENINACTIVE
MENUITEM "AGB Print", ID_OPTIONS_EMULATOR_AGBPRINT
+ MENUITEM "E-Reader", ID_OPTIONS_EMULATOR_EREADER
MENUITEM "Real Time Clock", ID_OPTIONS_EMULATOR_REALTIMECLOCK
MENUITEM "&Game Overrides...", ID_OPTIONS_EMULATOR_GAMEOVERRIDES
POPUP "Show speed"
diff --git a/src/win32/resource.h b/src/win32/resource.h
index 493aaba5..aaf88322 100644
--- a/src/win32/resource.h
+++ b/src/win32/resource.h
@@ -775,6 +775,7 @@
#define ID_OPTIONS_VIDEO_RENDEROPTIONS_GLTRIANGLE 40239
#define ID_OPTIONS_VIDEO_RENDEROPTIONS_GLQUADS 40240
#define ID_OPTIONS_EMULATOR_AGBPRINT 40247
+#define ID_OPTIONS_EMULATOR_EREADER 40280
#define ID_OPTIONS_EMULATOR_REALTIMECLOCK 40248
#define ID_OPTIONS_GAMEBOY_SGB2 40249
#define ID_SYSTEM_MINIMIZE 40250
@@ -877,6 +878,8 @@
#define ID_AUDIO_CORE_SETTINGS 40365
#define ID_FILE_OPEN_GBA 40366
#define ID_OPTIONS_VIDEO_LAYERS_RESET 40367
+#define ID_FILE_LOAD_DOTCODE 40368
+#define ID_FILE_SAVE_DOTCODE 40369
#define ID_LOADGAME_DONOTCHANGECHEATLIST 40371
#define ID_OPTIONS_EMULATOR_SAVETYPE_DETECTNOW 40372
#define ID_FILE_PAUSE 40373