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_