From 418a5a1d9f17f0e334f6ad99bec5d842d7df06ec Mon Sep 17 00:00:00 2001 From: skidau Date: Fri, 27 Mar 2015 22:50:11 +0000 Subject: [PATCH] Added E-Reader scan support by CaitSith2. One thing it does, is correct any raw files scanned, if they are correctable. (usually, uncorrectable raw files come up with a read error.) There is also bin support included as well. (Note, if you open a valid dotcode bin, it will encode it to raw, and save the freshly encoded raw file if it has been set in the menu. If the dotcode save file has not been set, the bin will still load.) Currently, part of the GBA emulation breaks the E-Reader scan code. The reader always returns a Region Error. git-svn-id: https://svn.code.sf.net/p/vbam/code/trunk@1255 a31d4220-a93d-0410-bf67-fe4944624d44 --- CMakeLists.txt | 1 + project/vc2008_mfc/VBA2008.vcproj | 8 + project/vs2010_mfc/VBA2010.sln | 2 +- project/vs2010_mfc/VBA2010.vcxproj | 4 +- project/vs2010_mfc/VBA2010.vcxproj.filters | 6 + project/vs2013_mfc/VBA2013.vcxproj | 2 + project/vs2013_mfc/VBA2013.vcxproj.filters | 6 + src/gba/GBA.cpp | 62 +- src/gba/GBA.h | 5 + src/gba/ereader.cpp | 670 +++++++++++++++++++++ src/gba/ereader.h | 11 + src/libretro/jni/Android.mk | 1 + src/win32/Commands.cpp | 2 + src/win32/MainWnd.cpp | 49 +- src/win32/MainWnd.h | 4 + src/win32/MainWndOptions.cpp | 11 + src/win32/VBA.cpp | 7 + src/win32/VBA.h | 3 + src/win32/VBA.rc | 6 +- src/win32/resource.h | 3 + 20 files changed, 857 insertions(+), 6 deletions(-) create mode 100644 src/gba/ereader.cpp create mode 100644 src/gba/ereader.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 6960c96f..e726bfbd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -200,6 +200,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 46e483a8..f7200b0d 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 9ca2dec7..16733b6b 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 @@ + @@ -296,6 +297,7 @@ + diff --git a/project/vs2010_mfc/VBA2010.vcxproj.filters b/project/vs2010_mfc/VBA2010.vcxproj.filters index 70ddff39..42e79aec 100644 --- a/project/vs2010_mfc/VBA2010.vcxproj.filters +++ b/project/vs2010_mfc/VBA2010.vcxproj.filters @@ -109,6 +109,9 @@ Core\GBA + + Core\GBA + Core\GBA @@ -487,6 +490,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 aebffcdb..6009dbbf 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 @@ -159,6 +160,9 @@ u8 memoryWaitSeq32[16] = u8 biosProtected[4]; +const char *loadDotCodeFile; +const char *saveDotCodeFile; + #ifdef WORDS_BIGENDIAN bool cpuBiosSwapped = false; #endif @@ -1616,6 +1620,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) { @@ -1931,8 +1955,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 { @@ -2160,6 +2195,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 @@ -3271,6 +3317,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 4912c621..179df3ed 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" @@ -1413,6 +1414,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); @@ -2512,6 +2517,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 00537d6e..fb6d1fe9 100644 --- a/src/win32/VBA.h +++ b/src/win32/VBA.h @@ -206,6 +206,9 @@ class VBA : public CWinApp CString filename; CString dir; + CString loadDotCodeFile; + CString saveDotCodeFile; + CString wndClass; int linkTimeout; diff --git a/src/win32/VBA.rc b/src/win32/VBA.rc index 16d25850..be520a08 100644 --- a/src/win32/VBA.rc +++ b/src/win32/VBA.rc @@ -1600,7 +1600,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 MENUITEM "&Link with...", ID_OPTIONS_LINK_OPTIONS MENUITEM SEPARATOR POPUP "Recent" @@ -1872,6 +1875,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 951345e0..74bd2097 100644 --- a/src/win32/resource.h +++ b/src/win32/resource.h @@ -779,6 +779,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 @@ -874,6 +875,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