diff --git a/arm9/Makefile b/arm9/Makefile
index e61ced5..3a318f1 100644
--- a/arm9/Makefile
+++ b/arm9/Makefile
@@ -37,8 +37,8 @@ endif
#---------------------------------------------------------------------------------
TARGET := GodMode9i
BUILD := build
-SOURCES := source source/graphics dldi-include mbedtls
-INCLUDES := include dldi-include source source/graphics
+SOURCES := source source/flashcard source/graphics dldi-include mbedtls
+INCLUDES := include dldi-include source source/flashcard source/graphics
DATA := ../data
GRAPHICS := ../gfx
diff --git a/arm9/source/driveOperations.cpp b/arm9/source/driveOperations.cpp
index 5511872..1829f69 100644
--- a/arm9/source/driveOperations.cpp
+++ b/arm9/source/driveOperations.cpp
@@ -17,6 +17,11 @@
#include "tonccpy.h"
#include "language.h"
+#include "io_m3_common.h"
+#include "io_g6_common.h"
+#include "io_sc_common.h"
+#include "exptools.h"
+
static sNDSHeader nds;
u8 stored_SCFG_MC = 0;
@@ -320,13 +325,61 @@ void flashcardUnmount(void) {
}
void ramdriveMount(bool ram32MB) {
- if(isDSiMode()) {
+ if(REG_SCFG_EXT != 0) {
ramdSectors = ram32MB ? 0xC800 : 0x4800;
- } else {
+
+ fatMountSimple("ram", &io_ram_drive);
+ } else if (isRegularDS) {
ramdSectors = 0x8 + 0x4000;
+ ramdLocMep = (u8*)0x09000000;
+
+ if (*(u16*)(0x020000C0) != 0x334D && *(u16*)(0x020000C0) != 0x3647 && *(u16*)(0x020000C0) != 0x4353 && *(u16*)(0x020000C0) != 0x5A45) {
+ *(u16*)(0x020000C0) = 0; // Clear Slot-2 flashcard flag
+ }
+
+ if (*(u16*)(0x020000C0) == 0) {
+ *(vu16*)(0x08000000) = 0x4D54; // Write test
+ if (*(vu16*)(0x08000000) != 0x4D54) { // If not writeable
+ _M3_changeMode(M3_MODE_RAM); // Try again with M3
+ *(u16*)(0x020000C0) = 0x334D;
+ *(vu16*)(0x08000000) = 0x4D54;
+ }
+ if (*(vu16*)(0x08000000) != 0x4D54) {
+ _G6_SelectOperation(G6_MODE_RAM); // Try again with G6
+ *(u16*)(0x020000C0) = 0x3647;
+ *(vu16*)(0x08000000) = 0x4D54;
+ }
+ if (*(vu16*)(0x08000000) != 0x4D54) {
+ _SC_changeMode(SC_MODE_RAM); // Try again with SuperCard
+ *(u16*)(0x020000C0) = 0x4353;
+ *(vu16*)(0x08000000) = 0x4D54;
+ }
+ if (*(vu16*)(0x08000000) != 0x4D54) {
+ cExpansion::SetRompage(381); // Try again with EZ Flash
+ cExpansion::OpenNorWrite();
+ cExpansion::SetSerialMode();
+ *(u16*)(0x020000C0) = 0x5A45;
+ *(vu16*)(0x08000000) = 0x4D54;
+ }
+ if (*(vu16*)(0x08000000) != 0x4D54) {
+ *(u16*)(0x020000C0) = 0;
+ *(vu16*)(0x08240000) = 1; // Try again with Nintendo Memory Expansion Pak
+ }
+ }
+
+ if (*(u16*)(0x020000C0) == 0x334D || *(u16*)(0x020000C0) == 0x3647 || *(u16*)(0x020000C0) == 0x4353) {
+ ramdLocMep = (u8*)0x08000000;
+ ramdSectors = 0x8 + 0x10000;
+ } else if (*(u16*)(0x020000C0) == 0x5A45) {
+ ramdLocMep = (u8*)0x08000000;
+ ramdSectors = 0x8 + 0x8000;
+ }
+
+ if (*(u16*)(0x020000C0) != 0 || *(vu16*)(0x08240000) == 1) {
+ fatMountSimple("ram", &io_ram_drive);
+ }
}
- fatMountSimple("ram", &io_ram_drive);
ramdriveMounted = (access("ram:/", F_OK) == 0);
if (ramdriveMounted) {
diff --git a/arm9/source/flashcard/exptools.cpp b/arm9/source/flashcard/exptools.cpp
new file mode 100644
index 0000000..15d89e7
--- /dev/null
+++ b/arm9/source/flashcard/exptools.cpp
@@ -0,0 +1,362 @@
+/*
+ exptools.cpp
+ Copyright (C) 2007-2009 somebody
+ Copyright (C) 2009 yellow wood goblin
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+#include "exptools.h"
+
+#define _PSRAM 0x08060000 // an offset into PSRAM to write to so stuff doesn't get lost...
+
+void cExpansion::OpenNorWrite(void)
+{
+ *(vu16*)0x9fe0000=0xd200;
+ *(vu16*)0x8000000=0x1500;
+ *(vu16*)0x8020000=0xd200;
+ *(vu16*)0x8040000=0x1500;
+ *(vu16*)0x9c40000=0x1500;
+ *(vu16*)0x9fc0000=0x1500;
+}
+
+void cExpansion::CloseNorWrite(void)
+{
+ *(vu16*)0x9fe0000=0xd200;
+ *(vu16*)0x8000000=0x1500;
+ *(vu16*)0x8020000=0xd200;
+ *(vu16*)0x8040000=0x1500;
+ *(vu16*)0x9c40000=0xd200;
+ *(vu16*)0x9fc0000=0x1500;
+}
+
+void cExpansion::SetRompage(u16 page)
+{
+ *(vu16*)0x9fe0000=0xd200;
+ *(vu16*)0x8000000=0x1500;
+ *(vu16*)0x8020000=0xd200;
+ *(vu16*)0x8040000=0x1500;
+ *(vu16*)0x9880000=page;
+ *(vu16*)0x9fc0000=0x1500;
+}
+
+void cExpansion::SetRampage(u16 page)
+{
+ *(vu16*)0x9fe0000=0xd200;
+ *(vu16*)0x8000000=0x1500;
+ *(vu16*)0x8020000=0xd200;
+ *(vu16*)0x8040000=0x1500;
+ *(vu16*)0x9c00000=page;
+ *(vu16*)0x9fc0000=0x1500;
+ iRamPage=page;
+}
+
+u16 cExpansion::Rampage(void)
+{
+ return iRamPage;
+}
+
+void cExpansion::SetSerialMode(void)
+{
+ *(vu16*)0x9fe0000=0xd200;
+ *(vu16*)0x8000000=0x1500;
+ *(vu16*)0x8020000=0xd200;
+ *(vu16*)0x8040000=0x1500;
+ *(vu16*)0x9a40000=0xe200;
+ *(vu16*)0x9fc0000=0x1500;
+}
+
+void cExpansion::SetShake(u16 data)
+{
+ *(vu16*)0x9fe0000=0xd200;
+ *(vu16*)0x8000000=0x1500;
+ *(vu16*)0x8020000=0xd200;
+ *(vu16*)0x8040000=0x1500;
+ *(vu16*)0x9e20000=data;
+ *(vu16*)0x9fc0000=0x1500;
+}
+
+void cExpansion::EnableBrowser(void)
+{
+ for(u32 i=0;i<0x100;i+=4)
+ {
+ *(vu32*)(0x9000000+i)=0xffffffff;
+ *(vu32*)(0x8000000+i)=0xffffffff;
+ }
+ *(vu32*)0x90000b0=0xffff;
+ *(vu32*)0x90000b4=0x24242400;
+ *(vu32*)0x90000b8=0xffffffff;
+ *(vu32*)0x90000bc=0x7fffffff;
+ *(vu32*)0x901fffc=0x7fffffff;
+ *(vu16*)0x9240002=1;
+}
+
+
+void cExpansion::Block_Erase(u32 blockAdd)
+{
+ vu16 v1,v2;
+ u32 Address;
+ u32 loop;
+ u32 off=0;
+ if((blockAdd>=0x1000000)&&(iId==0x227E2202))
+ {
+ off=0x1000000;
+ *((vu16*)(FlashBase+off+0x555*2))=0xF0;
+ *((vu16*)(FlashBase+off+0x1555*2))=0xF0;
+ }
+ else
+ off=0;
+ Address=blockAdd;
+ *((vu16*)(FlashBase+0x555*2))=0xF0;
+ *((vu16*)(FlashBase+0x1555*2))=0xF0;
+ if((blockAdd==0)||(blockAdd==0x1FC0000)||(blockAdd==0xFC0000)||(blockAdd==0x1000000))
+ {
+ for(loop=0;loop<0x40000;loop+=0x8000)
+ {
+ *((vu16*)(FlashBase+off+0x555*2))=0xAA;
+ *((vu16*)(FlashBase+off+0x2AA*2))=0x55;
+ *((vu16*)(FlashBase+off+0x555*2))=0x80;
+ *((vu16*)(FlashBase+off+0x555*2))=0xAA;
+ *((vu16*)(FlashBase+off+0x2AA*2))=0x55;
+ *((vu16*)(FlashBase+Address+loop))=0x30;
+
+ *((vu16*)(FlashBase+off+0x1555*2))=0xAA;
+ *((vu16*)(FlashBase+off+0x12AA*2))=0x55;
+ *((vu16*)(FlashBase+off+0x1555*2))=0x80;
+ *((vu16*)(FlashBase+off+0x1555*2))=0xAA;
+ *((vu16*)(FlashBase+off+0x12AA*2))=0x55;
+ *((vu16*)(FlashBase+Address+loop+0x2000))=0x30;
+
+ *((vu16*)(FlashBase+off+0x2555*2))=0xAA;
+ *((vu16*)(FlashBase+off+0x22AA*2))=0x55;
+ *((vu16*)(FlashBase+off+0x2555*2))=0x80;
+ *((vu16*)(FlashBase+off+0x2555*2))=0xAA;
+ *((vu16*)(FlashBase+off+0x22AA*2))=0x55;
+ *((vu16*)(FlashBase+Address+loop+0x4000))=0x30;
+
+ *((vu16*)(FlashBase+off+0x3555*2))=0xAA;
+ *((vu16*)(FlashBase+off+0x32AA*2))=0x55;
+ *((vu16*)(FlashBase+off+0x3555*2))=0x80;
+ *((vu16*)(FlashBase+off+0x3555*2))=0xAA;
+ *((vu16*)(FlashBase+off+0x32AA*2))=0x55;
+ *((vu16*)(FlashBase+Address+loop+0x6000))=0x30;
+ do
+ {
+ v1=*((vu16*)(FlashBase+Address+loop));
+ v2=*((vu16*)(FlashBase+Address+loop));
+ } while(v1!=v2);
+ do
+ {
+ v1=*((vu16*)(FlashBase+Address+loop+0x2000));
+ v2=*((vu16*)(FlashBase+Address+loop+0x2000));
+ } while(v1!=v2);
+ do
+ {
+ v1=*((vu16*)(FlashBase+Address+loop+0x4000));
+ v2=*((vu16*)(FlashBase+Address+loop+0x4000));
+ }while(v1!=v2);
+ do
+ {
+ v1=*((vu16*)(FlashBase+Address+loop+0x6000));
+ v2=*((vu16*)(FlashBase+Address+loop+0x6000));
+ }while(v1!=v2);
+ }
+ }
+ else
+ {
+ *((vu16*)(FlashBase+off+0x555*2))=0xAA;
+ *((vu16*)(FlashBase+off+0x2AA*2))=0x55;
+ *((vu16*)(FlashBase+off+0x555*2))=0x80;
+ *((vu16*)(FlashBase+off+0x555*2))=0xAA;
+ *((vu16*)(FlashBase+off+0x2AA*2))=0x55;
+ *((vu16*)(FlashBase+Address))=0x30;
+
+ *((vu16*)(FlashBase+off+0x1555*2))=0xAA;
+ *((vu16*)(FlashBase+off+0x12AA*2))=0x55;
+ *((vu16*)(FlashBase+off+0x1555*2))=0x80;
+ *((vu16*)(FlashBase+off+0x1555*2))=0xAA;
+ *((vu16*)(FlashBase+off+0x12AA*2))=0x55;
+ *((vu16*)(FlashBase+Address+0x2000))=0x30;
+
+ do
+ {
+ v1=*((vu16*)(FlashBase+Address));
+ v2=*((vu16*)(FlashBase+Address));
+ }while(v1!=v2);
+ do
+ {
+ v1=*((vu16*)(FlashBase+Address+0x2000));
+ v2=*((vu16*)(FlashBase+Address+0x2000));
+ }while(v1!=v2);
+
+ *((vu16*)(FlashBase+off+0x555*2))=0xAA;
+ *((vu16*)(FlashBase+off+0x2AA*2))=0x55;
+ *((vu16*)(FlashBase+off+0x555*2))=0x80;
+ *((vu16*)(FlashBase+off+0x555*2))=0xAA;
+ *((vu16*)(FlashBase+off+0x2AA*2))=0x55;
+ *((vu16*)(FlashBase+Address+0x20000))=0x30;
+
+ *((vu16*)(FlashBase+off+0x1555*2))=0xAA;
+ *((vu16*)(FlashBase+off+0x12AA*2))=0x55;
+ *((vu16*)(FlashBase+off+0x1555*2))=0x80;
+ *((vu16*)(FlashBase+off+0x1555*2))=0xAA;
+ *((vu16*)(FlashBase+off+0x12AA*2))=0x55;
+ *((vu16*)(FlashBase+Address+0x2000+0x20000))=0x30;
+
+ do
+ {
+ v1=*((vu16*)(FlashBase+Address+0x20000));
+ v2=*((vu16*)(FlashBase+Address+0x20000));
+ } while(v1!=v2);
+ do
+ {
+ v1=*((vu16*)(FlashBase+Address+0x2000+0x20000));
+ v2=*((vu16*)(FlashBase+Address+0x2000+0x20000));
+ } while(v1!=v2);
+ }
+}
+
+void cExpansion::WriteNorFlash(u32 address,const u8* buffer,u32 size)
+{
+ vu16 v1,v2;
+ /*register*/ u32 loopwrite;
+ vu16* buf=(vu16*)buffer;
+ u32 size2,lop;
+ u32 mapaddress;
+ u32 j;
+ v1=0;v2=1;
+ u32 off=0;
+ if((address>=0x1000000)&&(iId==0x227E2202))
+ {
+ off=0x1000000;
+ }
+ else
+ off=0;
+ if(size>0x4000)
+ {
+ size2=size>>1;
+ lop=2;
+ }
+ else
+ {
+ size2=size;
+ lop=1;
+ }
+ mapaddress=address;
+ for(j=0;j>2);loopwrite++)
+ {
+ *((vu16*)(FlashBase+off+0x555*2))=0xAA;
+ *((vu16*)(FlashBase+off+0x2AA*2))=0x55;
+ *((vu16*)(FlashBase+off+0x555*2))=0xA0;
+ *((vu16*)(FlashBase+mapaddress+loopwrite*2))=buf[loopwrite];
+
+ *((vu16*)(FlashBase+off+0x1555*2))=0xAA;
+ *((vu16*)(FlashBase+off+0x12AA*2))=0x55;
+ *((vu16*)(FlashBase+off+0x1555*2))=0xA0;
+ *((vu16*)(FlashBase+mapaddress+0x2000+loopwrite*2))=buf[0x1000+loopwrite];
+ do
+ {
+ v1=*((vu16*)(FlashBase+mapaddress+loopwrite*2));
+ v2=*((vu16*)(FlashBase+mapaddress+loopwrite*2));
+ }while(v1!=v2);
+ do
+ {
+ v1=*((vu16*)(FlashBase+mapaddress+0x2000+loopwrite*2));
+ v2=*((vu16*)(FlashBase+mapaddress+0x2000+loopwrite*2));
+ }while(v1!=v2);
+ }
+ }
+}
+
+void cExpansion::WritePSRAM(u32 address,const u8* buffer,u32 size)
+{
+ u16* addr=(u16*)(address+_PSRAM);
+ u16* pData=(u16*)buffer;
+ for(u32 i=0;i>1]=pData[i>>1];
+ }
+}
+
+void cExpansion::WriteSram(uint32 address,const u8* data,uint32 size)
+{
+ for(u32 i=0;i>1]=*(u8*)(address+i)+(*(u8*)(address+i+1)*0x100);
+ }
+}
+
+void cExpansion::SoftReset(void)
+{
+ CloseNorWrite();
+ SetRompage(0);
+ SetRampage(16);
+ SetShake(8);
+}
+
+void cExpansion::ReadNorFlashID(void)
+{
+ vu16 id1,id2;
+ *((vu16*)(FlashBase+0x555*2))=0xAA;
+ *((vu16*)(FlashBase+0x2AA*2))=0x55;
+ *((vu16*)(FlashBase+0x555*2))=0x90;
+
+ *((vu16*)(FlashBase+0x1555*2))=0xAA;
+ *((vu16*)(FlashBase+0x12AA*2))=0x55;
+ *((vu16*)(FlashBase+0x1555*2))=0x90;
+
+ id1=*((vu16*)(FlashBase+0x2));
+ id2=*((vu16*)(FlashBase+0x2002));
+ if((id1!=0x227E)||(id2!=0x227E)) return;
+
+ id1=*((vu16*)(FlashBase+0xE*2));
+ id2=*((vu16*)(FlashBase+0x100e*2));
+ if(id1==0x2218&&id2==0x2218) //H6H6
+ {
+ iId=0x227E2218;
+ return;
+ }
+ if((id1==0x2202&&id2==0x2202)
+ ||(id1==0x2202&&id2==0x2220)
+ ||(id1==0x2202&&id2==0x2215)) //VZ064
+ {
+ iId=0x227E2202;
+ return;
+ }
+}
+
+void cExpansion::ChipReset(void)
+{
+ *((vu16*)(FlashBase))=0xF0;
+ *((vu16*)(FlashBase+0x1000*2))=0xF0;
+ if(iId==0x227E2202)
+ {
+ *((vu16*)(FlashBase+0x1000000))=0xF0 ;
+ *((vu16*)(FlashBase+0x1000000+0x1000*2))=0xF0;
+ }
+}
diff --git a/arm9/source/flashcard/exptools.h b/arm9/source/flashcard/exptools.h
new file mode 100644
index 0000000..8c8aaf1
--- /dev/null
+++ b/arm9/source/flashcard/exptools.h
@@ -0,0 +1,69 @@
+/*
+ exptools.h
+ Copyright (C) 2007-2009 somebody
+ Copyright (C) 2009 yellow wood goblin
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+#ifndef __EXPTOOLS_H__
+#define __EXPTOOLS_H__
+
+#include
+#include "singleton.h"
+
+class cExpansion
+{
+ public:
+ enum TPages
+ {
+ ENorPage=16,
+ EPsramPage=96
+ };
+ public:
+ static void OpenNorWrite(void);
+ static void CloseNorWrite(void);
+ static void SetRompage(u16 page);
+ void SetRampage(u16 page);
+ u16 Rampage(void);
+ static void SetSerialMode(void);
+ static void SetShake(u16 data);
+ static void EnableBrowser(void);
+ static void WritePSRAM(u32 address,const u8* buffer,u32 size);
+ static void WriteSram(uint32 address,const u8* data,uint32 size);
+ static void ReadSram(uint32 address,u8* data,uint32 size);
+ public:
+ void SoftReset(void);
+ public:
+ cExpansion(): iId(0),iRamPage(ENorPage) {SetShake(8);OpenNorWrite();ReadNorFlashID();ChipReset();CloseNorWrite();};
+ void Block_Erase(u32 blockAdd);
+ void WriteNorFlash(u32 address,const u8* buffer,u32 size);
+ bool IsValid(void) {return iId;};
+ private:
+ void ReadNorFlashID(void);
+ void ChipReset(void);
+ private:
+ enum
+ {
+ FlashBase=0x08000000
+ };
+ private:
+ u32 iId;
+ u16 iRamPage;
+};
+
+typedef singleton cExpansion_s;
+inline cExpansion& expansion() {return cExpansion_s::instance();}
+
+#endif
diff --git a/arm9/source/flashcard/io_g6_common.c b/arm9/source/flashcard/io_g6_common.c
new file mode 100644
index 0000000..4e2e177
--- /dev/null
+++ b/arm9/source/flashcard/io_g6_common.c
@@ -0,0 +1,114 @@
+/*
+ iointerface.c for G6 flash card
+
+Written by Viruseb (viruseb@hotmail.com)
+ Many thanks to Puyo for his help in the reading code and ecc generation
+ and Theli for remote debbuging.
+
+ Copyright (c) 2006 Michael "Chishm" Chisholm
+
+ Redistribution and use in source and binary forms, with or without modification,
+ are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation and/or
+ other materials provided with the distribution.
+ 3. The name of the author may not be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+If you wish to understand how the code works, I encourage you reading
+the datasheet of K9K4G08U0M nand flash device from Samsung before.
+
+Just some figures to keep in mind :
+ 1 page = 4 sectors + 64byte
+ 1 block = 64 pages = 256 sectors
+ 1 4G device = 4096 blocks
+
+The spare 64byte in page are use :
+ - to store the ECC. There is 3bytes ecc per 256bytes (bytes 8...15+numsector*16).
+ - to store lookuptable values (bytes 4..7).
+
+04/12/06 : Version 0.10
+ Just freshly written. Not tested on real G6L thought.
+ Extreme caution have to be taken when testing WriteBlockFunction
+ since it may brick your G6L or more likely corrupt your data
+ and formating can be necessary.
+
+05/12/06 : Version 0.11
+ Thank to Theli, a lot of stupid mistakes removed, a lot of debugging done.
+ Reading code checked against Puyo's code.
+ Device and FAT table is recognised by Fat_InitFiles()
+ Known issues : DMA read (G6_ReadDMA) is malfunctionning
+ Strange things append when trying to read more than 1 sectors at a time
+ Have to check LookUpTable values against Puyo's LookUpTable they seems differents after 512values
+
+19/12/06 : Version 0.12
+ Reading code ok
+
+20/12/06 : Version 0.13
+ Some reading bugs corrected
+
+07/01/07 : Version 0.14
+ Writing code finaly working. Need some optimizations.
+
+10/01/07 : Version 0.15
+ Code cleaning. Need to add DMA R/W and use of cache programming in later version.
+
+03/02/07 : Version 0.16
+ Unaligned R/W supported.
+ Write code rewritten, using cache programming now.
+
+04/03/07 : Version 0.17
+ VerifyBlockFunc corrected (no more in use now)
+
+23/03/07 : Version 0.18
+ a bug corrected in make_ecc_256
+
+25/03/07 : Version 0.19
+ Improved writing speed
+*/
+
+#include "io_g6_common.h"
+
+static u16 _G6_readHalfword (u32 addr) {
+ return *((vu16*)addr);
+}
+
+/*-----------------------------------------------------------------
+SelectOperation
+??
+u16 op IN : Operation to select
+-----------------------------------------------------------------*/
+void _G6_SelectOperation(u16 op)
+{
+ _G6_readHalfword (0x09000000);
+ _G6_readHalfword (0x09FFFFE0);
+
+ _G6_readHalfword (0x09FFFFEC);
+ _G6_readHalfword (0x09FFFFEC);
+ _G6_readHalfword (0x09FFFFEC);
+
+ _G6_readHalfword (0x09FFFFFC);
+ _G6_readHalfword (0x09FFFFFC);
+ _G6_readHalfword (0x09FFFFFC);
+
+ _G6_readHalfword (0x09FFFF4A);
+ _G6_readHalfword (0x09FFFF4A);
+ _G6_readHalfword (0x09FFFF4A);
+
+ _G6_readHalfword (0x09200000 + (op<<1));
+ _G6_readHalfword (0x09FFFFF0);
+ _G6_readHalfword (0x09FFFFE8);
+}
diff --git a/arm9/source/flashcard/io_g6_common.h b/arm9/source/flashcard/io_g6_common.h
new file mode 100644
index 0000000..16dfe4f
--- /dev/null
+++ b/arm9/source/flashcard/io_g6_common.h
@@ -0,0 +1,103 @@
+/*
+ iointerface.c for G6 flash card
+
+Written by Viruseb (viruseb@hotmail.com)
+ Many thanks to Puyo for his help in the reading code and ecc generation
+ and Theli for remote debbuging.
+
+ Copyright (c) 2006 Michael "Chishm" Chisholm
+
+ Redistribution and use in source and binary forms, with or without modification,
+ are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation and/or
+ other materials provided with the distribution.
+ 3. The name of the author may not be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+If you wish to understand how the code works, I encourage you reading
+the datasheet of K9K4G08U0M nand flash device from Samsung before.
+
+Just some figures to keep in mind :
+ 1 page = 4 sectors + 64byte
+ 1 block = 64 pages = 256 sectors
+ 1 4G device = 4096 blocks
+
+The spare 64byte in page are use :
+ - to store the ECC. There is 3bytes ecc per 256bytes (bytes 8...15+numsector*16).
+ - to store lookuptable values (bytes 4..7).
+
+04/12/06 : Version 0.10
+ Just freshly written. Not tested on real G6L thought.
+ Extreme caution have to be taken when testing WriteBlockFunction
+ since it may brick your G6L or more likely corrupt your data
+ and formating can be necessary.
+
+05/12/06 : Version 0.11
+ Thank to Theli, a lot of stupid mistakes removed, a lot of debugging done.
+ Reading code checked against Puyo's code.
+ Device and FAT table is recognised by Fat_InitFiles()
+ Known issues : DMA read (G6_ReadDMA) is malfunctionning
+ Strange things append when trying to read more than 1 sectors at a time
+ Have to check LookUpTable values against Puyo's LookUpTable they seems differents after 512values
+
+19/12/06 : Version 0.12
+ Reading code ok
+
+20/12/06 : Version 0.13
+ Some reading bugs corrected
+
+07/01/07 : Version 0.14
+ Writing code finaly working. Need some optimizations.
+
+10/01/07 : Version 0.15
+ Code cleaning. Need to add DMA R/W and use of cache programming in later version.
+
+03/02/07 : Version 0.16
+ Unaligned R/W supported.
+ Write code rewritten, using cache programming now.
+
+04/03/07 : Version 0.17
+ VerifyBlockFunc corrected (no more in use now)
+
+23/03/07 : Version 0.18
+ a bug corrected in make_ecc_256
+
+25/03/07 : Version 0.19
+ Improved writing speed
+*/
+
+#ifndef IO_G6_COMMON_H
+#define IO_G6_COMMON_H
+
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Values for changing mode
+#define G6_MODE_RAM 6
+#define G6_MODE_MEDIA 3
+
+extern void _G6_SelectOperation(u16 op);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // IO_G6_COMMON_H
+
diff --git a/arm9/source/flashcard/io_m3_common.c b/arm9/source/flashcard/io_m3_common.c
new file mode 100644
index 0000000..ab2c143
--- /dev/null
+++ b/arm9/source/flashcard/io_m3_common.c
@@ -0,0 +1,60 @@
+/*
+ io_m3_common.c
+
+ Routines common to all version of the M3
+
+ Some code based on M3 SD drivers supplied by M3Adapter.
+ Some code written by SaTa may have been unknowingly used.
+
+ Copyright (c) 2006 Michael "Chishm" Chisholm
+
+ Redistribution and use in source and binary forms, with or without modification,
+ are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation and/or
+ other materials provided with the distribution.
+ 3. The name of the author may not be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "io_m3_common.h"
+
+static u16 _M3_readHalfword (u32 addr) {
+ return *((vu16*)addr);
+}
+
+void _M3_changeMode (u32 mode) {
+ _M3_readHalfword (0x08e00002);
+ _M3_readHalfword (0x0800000e);
+ _M3_readHalfword (0x08801ffc);
+ _M3_readHalfword (0x0800104a);
+ _M3_readHalfword (0x08800612);
+ _M3_readHalfword (0x08000000);
+ _M3_readHalfword (0x08801b66);
+ _M3_readHalfword (0x08000000 + (mode << 1));
+ _M3_readHalfword (0x0800080e);
+ _M3_readHalfword (0x08000000);
+
+ if ((mode & 0x0f) != 4) {
+ _M3_readHalfword (0x09000000);
+ } else {
+ _M3_readHalfword (0x080001e4);
+ _M3_readHalfword (0x080001e4);
+ _M3_readHalfword (0x08000188);
+ _M3_readHalfword (0x08000188);
+ }
+}
+
diff --git a/arm9/source/flashcard/io_m3_common.h b/arm9/source/flashcard/io_m3_common.h
new file mode 100644
index 0000000..1dbfe52
--- /dev/null
+++ b/arm9/source/flashcard/io_m3_common.h
@@ -0,0 +1,57 @@
+/*
+ io_m3_common.h
+
+ Routines common to all version of the M3
+
+ Some code based on M3 SD drivers supplied by M3Adapter.
+ Some code written by SaTa may have been unknowingly used.
+
+ Copyright (c) 2006 Michael "Chishm" Chisholm
+
+ Redistribution and use in source and binary forms, with or without modification,
+ are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation and/or
+ other materials provided with the distribution.
+ 3. The name of the author may not be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ 2006-07-11 - Chishm
+ * Original release
+*/
+
+#ifndef IO_M3_COMMON_H
+#define IO_M3_COMMON_H
+
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Values for changing mode
+#define M3_MODE_RAM 0x00400006
+#define M3_MODE_ROM 0x00400004
+#define M3_MODE_MEDIA 0x00400003
+
+extern void _M3_changeMode (u32 mode);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // IO_M3_COMMON_H
+
diff --git a/arm9/source/flashcard/io_sc_common.c b/arm9/source/flashcard/io_sc_common.c
new file mode 100644
index 0000000..7035e12
--- /dev/null
+++ b/arm9/source/flashcard/io_sc_common.c
@@ -0,0 +1,47 @@
+/*
+ io_m3_common.h
+
+ Routines common to all version of the Super Card
+
+ Copyright (c) 2006 Michael "Chishm" Chisholm
+
+ Redistribution and use in source and binary forms, with or without modification,
+ are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation and/or
+ other materials provided with the distribution.
+ 3. The name of the author may not be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "io_sc_common.h"
+
+/*-----------------------------------------------------------------
+_SC_changeMode (was SC_Unlock)
+Added by MightyMax
+Modified by Chishm
+Modified again by loopy
+1=ram(readonly), 5=ram, 3=SD interface?
+-----------------------------------------------------------------*/
+void _SC_changeMode(u8 mode) {
+ vu16 *unlockAddress = (vu16*)0x09FFFFFE;
+ *unlockAddress = 0xA55A ;
+ *unlockAddress = 0xA55A ;
+ *unlockAddress = mode ;
+ *unlockAddress = mode ;
+}
+
+
diff --git a/arm9/source/flashcard/io_sc_common.h b/arm9/source/flashcard/io_sc_common.h
new file mode 100644
index 0000000..3041bfa
--- /dev/null
+++ b/arm9/source/flashcard/io_sc_common.h
@@ -0,0 +1,53 @@
+/*
+ io_sc_common.h
+
+ Routines common to all version of the Super Card
+
+ Copyright (c) 2006 Michael "Chishm" Chisholm
+
+ Redistribution and use in source and binary forms, with or without modification,
+ are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation and/or
+ other materials provided with the distribution.
+ 3. The name of the author may not be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ 2006-07-11 - Chishm
+ * Original release
+*/
+
+#ifndef IO_SC_COMMON_H
+#define IO_SC_COMMON_H
+
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Values for changing mode
+#define SC_MODE_RAM 0x5
+#define SC_MODE_MEDIA 0x3
+#define SC_MODE_RAM_RO 0x1
+
+extern void _SC_changeMode (u8 mode);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // IO_SC_COMMON_H
diff --git a/arm9/source/main.cpp b/arm9/source/main.cpp
index c8da100..3e38049 100644
--- a/arm9/source/main.cpp
+++ b/arm9/source/main.cpp
@@ -54,7 +54,6 @@ bool screenSwapped = false;
bool arm7SCFGLocked = false;
bool isRegularDS = true;
-bool expansionPakFound = false;
bool is3DS = false;
int ownNitroFSMounted;
@@ -170,11 +169,12 @@ int main(int argc, char **argv) {
/*FILE* cidFile = fopen("sd:/gm9i/ConsoleID.bin", "wb");
fwrite((void*)0x2FFFD00, 1, 8, cidFile);
fclose(cidFile);*/
+ } else if (REG_SCFG_EXT != 0) {
+ *(vu32*)(0x0DFFFE0C) = 0x474D3969; // Check for 32MB of RAM
+ bool ram32MB = *(vu32*)(0x0DFFFE0C) == 0x474D3969;
+ ramdriveMount(ram32MB);
} else if (isRegularDS && (io_dldi_data->ioInterface.features & FEATURE_SLOT_NDS)) {
- *(vu32*)(0x08240000) = 1;
- expansionPakFound = ((*(vu32*)(0x08240000) == 1));
- if(expansionPakFound)
- ramdriveMount(false);
+ ramdriveMount(false);
}
if (!isDSiMode() || !yHeld) {
flashcardMounted = flashcardMount();
diff --git a/arm9/source/ramd.c b/arm9/source/ramd.c
index 47de021..015a63b 100644
--- a/arm9/source/ramd.c
+++ b/arm9/source/ramd.c
@@ -18,11 +18,10 @@ u8* ramdLoc = (u8*)NULL;
u8* ramdLocMep = (u8*)NULL;
bool ramd_startup() {
- if(isDSiMode()) {
+ if(REG_SCFG_EXT != 0) {
ramdLoc = (u8*)malloc(0x4800 * SECTOR_SIZE);
} else {
ramdLoc = (u8*)malloc(0x8 * SECTOR_SIZE);
- ramdLocMep = (u8*)0x09000000;
}
tonccpy(ramdLoc, bootSector, sizeof(bootSector));
@@ -37,7 +36,7 @@ bool ramd_is_inserted() {
}
bool ramd_read_sectors(sec_t sector, sec_t numSectors, void *buffer) {
- if(isDSiMode()) {
+ if(REG_SCFG_EXT != 0) {
if(sector < 0x4800) {
tonccpy(buffer, ramdLoc + (sector << 9), numSectors << 9);
return true;
@@ -57,7 +56,7 @@ bool ramd_read_sectors(sec_t sector, sec_t numSectors, void *buffer) {
}
bool ramd_write_sectors(sec_t sector, sec_t numSectors, const void *buffer) {
- if(isDSiMode()) {
+ if(REG_SCFG_EXT != 0) {
if(sector < 0x4800) {
tonccpy(ramdLoc + (sector << 9), buffer, numSectors << 9);
return true;
@@ -81,7 +80,7 @@ bool ramd_clear_status() {
}
bool ramd_shutdown() {
- if(isDSiMode() && ramdLoc) {
+ if((REG_SCFG_EXT != 0) && ramdLoc) {
free(ramdLoc);
ramdLoc = NULL;
}
diff --git a/arm9/source/ramd.h b/arm9/source/ramd.h
index 99f0a48..63f4633 100644
--- a/arm9/source/ramd.h
+++ b/arm9/source/ramd.h
@@ -5,5 +5,6 @@
#include
extern u32 ramdSectors;
+extern u8* ramdLocMep;
extern const DISC_INTERFACE io_ram_drive;
diff --git a/arm9/source/singleton.h b/arm9/source/singleton.h
new file mode 100644
index 0000000..1621902
--- /dev/null
+++ b/arm9/source/singleton.h
@@ -0,0 +1,66 @@
+/*
+ common/singleton.h
+ Copyright (c) 2018 chyyran
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all
+ copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+*/
+
+#pragma once
+#ifndef _SINGLETON_H_
+#define _SINGLETON_H_
+#include
+#include
+#include // std::nothrow
+
+template
+class singleton
+{
+
+ public:
+ static inline T &instance(Args &&... args)
+ {
+ if (!_instance)
+ make(std::forward(args)...);
+ return *_instance;
+ }
+
+ private:
+ static inline void make(Args... args)
+ {
+ if (!_instance)
+ _instance = new (std::nothrow) T(std::forward(args)...);
+ }
+
+ static inline void reset()
+ {
+ if (_instance)
+ {
+ delete _instance;
+ _instance = NULL;
+ }
+ }
+
+ private:
+ static T *_instance;
+};
+
+template
+T * singleton::_instance = NULL;
+
+#endif //_SINGLETON_H_