mirror of
https://github.com/ApacheThunder/GBA-Exploader.git
synced 2025-06-18 11:35:38 -04:00
Fix 3 in 1 Plus NorFlash
* NorFlash read/write now working for 3 in 1 Plus! Big thanks to cory1492 for he had managed to make available the version of source code of gbaldr that had the code needed to make this work. Also thanks to stl25 for helping test 3in1 Plus support as I do not own a 3 in 1 Plus myself. * 64MB roms appear to write to NorFlash correctly with 3 in 1 Plus however note that this does not mean retail roms that used that size will work (not without patching anyways). 3 in 1 Plus had 64MB NorFlash but doen't use normal page switch commands so retail roms will need patching to use this. * r4tf bool set to false for SuperCard and Rumble menu disabled for SuperCard. Program would crash if user attempts to use R shoulder button to access rumble menu if a SuperCard is inserted and a NDS file for soft reset was available. This has been fixed by disabling this menu for SuperCard. The rumble menu will not work as intended for SuperCards anyways. * Soft Reset for rumble menu is currently broken. (has been since initial rebuild). The method the program uses for loading NDS files likely needs to be rewritten. * Hitting X after flashing a game to NorFlash on 3 in 1 Plus may cause hang. The game flashed will still be bootable provided the user power cycles the console and boots the card as normal. No plans to fix as I'm unsure why it's happening and it's a minor issue. Hitting X after switching to NorFlash without flashing anything seems to still work though. Feel free to create a push request if you managed to fix this. ;)
This commit is contained in:
parent
1c87b5c272
commit
049f3700d6
2
Makefile
2
Makefile
@ -9,7 +9,7 @@ export TARGET := GBA_ExpLoader
|
||||
export TOPDIR := $(CURDIR)
|
||||
|
||||
export VERSION_MAJOR := 0
|
||||
export VERSION_MINOR := 59
|
||||
export VERSION_MINOR := 60
|
||||
export VERSTRING := $(VERSION_MAJOR).$(VERSION_MINOR)
|
||||
|
||||
# GMAE_ICON is the image used to create the game icon, leave blank to use default rule
|
||||
|
@ -23,7 +23,6 @@ STATICLIBS :=
|
||||
#---------------------------------------------------------------------------------
|
||||
# options for code generation
|
||||
#---------------------------------------------------------------------------------
|
||||
# $(ARCH) $(INCLUDE) -DARM9 -D_LegacyCardLib
|
||||
ARCH := -mthumb -mthumb-interwork -march=armv5te -mtune=arm946e-s
|
||||
CFLAGS := -g -Wall -Wno-format-overflow -O2 \
|
||||
$(ARCH) $(INCLUDE) -DARM9
|
||||
|
@ -1,388 +0,0 @@
|
||||
/**************************************************************************************************************
|
||||
* 此文件为 dsCard.cpp 文件的第二版
|
||||
* 日期:2006年11月27日11点33分 第一版 version 1.0
|
||||
* 作者:aladdin
|
||||
* CopyRight : EZFlash Group
|
||||
*
|
||||
**************************************************************************************************************/
|
||||
#include <stdio.h>
|
||||
|
||||
#include "dscard.h"
|
||||
#include "string.h"
|
||||
#include "io_sc_common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static u32 ID = 0x227E2218;
|
||||
|
||||
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
|
||||
//---------------------------------------------------
|
||||
//DS 卡 基本操作
|
||||
/************
|
||||
void Enable_Arm9DS()
|
||||
{
|
||||
WAIT_CR &= ~0x0800;
|
||||
}
|
||||
|
||||
void Enable_Arm7DS()
|
||||
{
|
||||
WAIT_CR |= 0x0800;
|
||||
}
|
||||
*************/
|
||||
void OpenNorWrite() {
|
||||
*(vuint16 *)0x9fe0000 = 0xd200;
|
||||
*(vuint16 *)0x8000000 = 0x1500;
|
||||
*(vuint16 *)0x8020000 = 0xd200;
|
||||
*(vuint16 *)0x8040000 = 0x1500;
|
||||
*(vuint16 *)0x9C40000 = 0x1500;
|
||||
*(vuint16 *)0x9fc0000 = 0x1500;
|
||||
}
|
||||
|
||||
|
||||
void CloseNorWrite() {
|
||||
*(vuint16 *)0x9fe0000 = 0xd200;
|
||||
*(vuint16 *)0x8000000 = 0x1500;
|
||||
*(vuint16 *)0x8020000 = 0xd200;
|
||||
*(vuint16 *)0x8040000 = 0x1500;
|
||||
*(vuint16 *)0x9C40000 = 0xd200;
|
||||
*(vuint16 *)0x9fc0000 = 0x1500;
|
||||
}
|
||||
|
||||
void SetRompage(u16 page) {
|
||||
*(vuint16 *)0x9fe0000 = 0xd200;
|
||||
*(vuint16 *)0x8000000 = 0x1500;
|
||||
*(vuint16 *)0x8020000 = 0xd200;
|
||||
*(vuint16 *)0x8040000 = 0x1500;
|
||||
*(vuint16 *)0x9880000 = page;
|
||||
*(vuint16 *)0x9fc0000 = 0x1500;
|
||||
}
|
||||
|
||||
void SetRampage(u16 page) {
|
||||
*(vu16 *)0x9fe0000 = 0xd200;
|
||||
*(vu16 *)0x8000000 = 0x1500;
|
||||
*(vu16 *)0x8020000 = 0xd200;
|
||||
*(vu16 *)0x8040000 = 0x1500;
|
||||
*(vu16 *)0x9c00000 = page;
|
||||
*(vu16 *)0x9fc0000 = 0x1500;
|
||||
}
|
||||
|
||||
void SetSerialMode() {
|
||||
|
||||
*(vu16 *)0x9fe0000 = 0xd200;
|
||||
*(vu16 *)0x8000000 = 0x1500;
|
||||
*(vu16 *)0x8020000 = 0xd200;
|
||||
*(vu16 *)0x8040000 = 0x1500;
|
||||
*(vu16 *)0x9A40000 = 0xe200;
|
||||
*(vu16 *)0x9fc0000 = 0x1500;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static bool checkForSuperCard() {
|
||||
_SC_changeMode(SC_MODE_RAM); // Try again with SuperCard
|
||||
// _SC_changeMode16(0x1510);
|
||||
*(vu16*)(0x08000000) = 0x4D54;
|
||||
if (*(vu16*)(0x08000000) == 0x4D54)return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool checkFor3in1Plus() {
|
||||
SetRompage(381); // Try again with EZ Flash
|
||||
OpenNorWrite();
|
||||
*(vu16*)(0x08060000) = 0x4D54;
|
||||
if (*(vu16*)(0x08060000) == 0x4D54)return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 ReadNorFlashID() {
|
||||
vuint16 id1,id2; //,id3,id4;
|
||||
ID = 0;
|
||||
*((vuint16 *)(FlashBase+0x555*2)) = 0xAA;
|
||||
*((vuint16 *)(FlashBase+0x2AA*2)) = 0x55;
|
||||
*((vuint16 *)(FlashBase+0x555*2)) = 0x90;
|
||||
|
||||
*((vuint16 *)(FlashBase+0x1555*2)) = 0xAA;
|
||||
*((vuint16 *)(FlashBase+0x12AA*2)) = 0x55;
|
||||
*((vuint16 *)(FlashBase+0x1555*2)) = 0x90;
|
||||
|
||||
id1 = *((vuint16 *)(FlashBase+0x2));
|
||||
id2 = *((vuint16 *)(FlashBase+0x2002));
|
||||
|
||||
if ((id1!=0x227E) || (id2!=0x227E)) {
|
||||
if (checkFor3in1Plus()) {
|
||||
ID = 0x227E2202;
|
||||
return 0x227E2222;
|
||||
}
|
||||
if (checkForSuperCard()) {
|
||||
ID = 0x227E2202;
|
||||
return 0x227E0000;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
id1 = *((vuint16 *)(FlashBase+0xE*2));
|
||||
id2 = *((vuint16 *)(FlashBase+0x100e*2));
|
||||
|
||||
/*FILE *testFile = fopen("/gbacardID.bin", "wb");
|
||||
if (testFile) {
|
||||
fwrite((void*)FlashBase+0xE*2, 2, 1, testFile);
|
||||
fwrite((void*)FlashBase+0x100e*2, 2, 1, testFile);
|
||||
fclose(testFile);
|
||||
}*/
|
||||
|
||||
// H6H6
|
||||
if(id1==0x2218 && id2==0x2218) {
|
||||
ID = 0x227E2218;
|
||||
return 0x227E2218;
|
||||
}
|
||||
|
||||
// VZ064
|
||||
if(id1==0x2202 && id2==0x2202) {
|
||||
ID = 0x227E2202;
|
||||
return 0x227E2202;
|
||||
}
|
||||
// VZ064
|
||||
if(id1==0x2202 && id2==0x2220) {
|
||||
ID = 0x227E2202;
|
||||
return 0x227E2202;
|
||||
}
|
||||
// VZ064
|
||||
if(id1==0x2202 && id2==0x2215) {
|
||||
ID = 0x227E2202;
|
||||
return 0x227E2202;
|
||||
}
|
||||
// 3in1 Plus
|
||||
/*if(id1==0x8916 && id2==0x8916) {
|
||||
ID = 0x227E2202;
|
||||
return 0x227E2222;
|
||||
}*/
|
||||
return 0x227E2220;
|
||||
}
|
||||
|
||||
void chip_reset() {
|
||||
*((vu16 *)(FlashBase)) = 0xF0 ;
|
||||
*((vu16 *)(FlashBase+0x1000*2)) = 0xF0 ;
|
||||
|
||||
if(ID==0x227E2202) {
|
||||
*((vu16 *)(FlashBase+0x1000000)) = 0xF0 ;
|
||||
*((vu16 *)(FlashBase+0x1000000+0x1000*2)) = 0xF0 ;
|
||||
}
|
||||
}
|
||||
|
||||
void Block_Erase(u32 blockAdd) {
|
||||
vu16 v1,v2;
|
||||
u32 Address;
|
||||
u32 loop;
|
||||
u32 off=0;
|
||||
if( (blockAdd>=0x1000000) && (ID==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 ReadNorFlash(u8* pBuf,u32 address,u16 len) {
|
||||
vu16 *p = (vu16 *)pBuf;
|
||||
u32 loop;
|
||||
for(loop=0;loop<len/2;loop++)p[loop] = *((vu16 *)(FlashBase+address+loop*2));
|
||||
}
|
||||
|
||||
void WriteNorFlash(u32 address,u8 *buffer,u32 size) {
|
||||
vu16 v1,v2;
|
||||
u32 loopwrite;
|
||||
vu16* buf = (vu16*)buffer ;
|
||||
u32 size2,lop;
|
||||
u32 mapaddress;
|
||||
u32 j;
|
||||
v1=0;v2=1;
|
||||
u32 off=0;
|
||||
if( (address>=0x1000000) && (ID==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<lop;j++) {
|
||||
if(j!=0) {
|
||||
mapaddress += 0x4000;
|
||||
buf = (vu16*)(buffer+0x4000);
|
||||
}
|
||||
for(loopwrite=0;loopwrite<(size2>>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 WriteSram(uint32 address, u8* data , uint32 size ) {
|
||||
uint32 i ;
|
||||
for(i=0;i<size;i++)*(u8*)(address+i)=data[i];
|
||||
}
|
||||
|
||||
void ReadSram(uint32 address, u8* data , uint32 size ) {
|
||||
uint32 i ;
|
||||
|
||||
for(i=0;i<size;i++)data[i] = *(u8*)(address+i);
|
||||
|
||||
/***
|
||||
u16* pData = (u16*)data;
|
||||
|
||||
for(i=0;i<size;i+=2)
|
||||
{
|
||||
pData[i>>1]=*(u8*)(address+i)+(*(u8*)(address+i+1)*0x100);
|
||||
}
|
||||
**/
|
||||
}
|
||||
void OpenRamWrite() {
|
||||
*(vu16 *)0x9fe0000 = 0xd200;
|
||||
*(vu16 *)0x8000000 = 0x1500;
|
||||
*(vu16 *)0x8020000 = 0xd200;
|
||||
*(vu16 *)0x8040000 = 0x1500;
|
||||
*(vu16 *)0x9C40000 = 0xA500;
|
||||
*(vu16 *)0x9fc0000 = 0x1500;
|
||||
}
|
||||
|
||||
void CloseRamWrite() {
|
||||
*(vu16 *)0x9fe0000 = 0xd200;
|
||||
*(vu16 *)0x8000000 = 0x1500;
|
||||
*(vu16 *)0x8020000 = 0xd200;
|
||||
*(vu16 *)0x8040000 = 0x1500;
|
||||
*(vu16 *)0x9C40000 = 0xA200;
|
||||
*(vu16 *)0x9fc0000 = 0x1500;
|
||||
}
|
||||
void SetShake(u16 data) {
|
||||
*(vuint16 *)0x9fe0000 = 0xd200;
|
||||
*(vuint16 *)0x8000000 = 0x1500;
|
||||
*(vuint16 *)0x8020000 = 0xd200;
|
||||
*(vuint16 *)0x8040000 = 0x1500;
|
||||
*(vuint16 *)0x9E20000 = data;
|
||||
*(vuint16 *)0x9fc0000 = 0x1500;
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -56,8 +56,10 @@ typedef bool BOOL ;
|
||||
void SetSerialMode();
|
||||
uint32 ReadNorFlashID();
|
||||
void chip_reset();
|
||||
void Block_EraseIntel(u32 blockAdd);
|
||||
void Block_Erase(u32 blockAdd);
|
||||
void ReadNorFlash(u8* pBuf,u32 address,u16 len);
|
||||
// void ReadNorFlash(u8* pBuf,u32 address,u16 len);
|
||||
void WriteNorFlashINTEL(u32 address,u8 *buffer,u32 size);
|
||||
void WriteNorFlash(u32 address,u8 *buffer,u32 size);
|
||||
void WriteSram(uint32 address, u8* data , uint32 size );
|
||||
void ReadSram(uint32 address, u8* data , uint32 size );
|
||||
|
529
arm9/source/dsCard.itcm.cpp
Normal file
529
arm9/source/dsCard.itcm.cpp
Normal file
@ -0,0 +1,529 @@
|
||||
/**************************************************************************************************************
|
||||
* 此文件为 dsCard.cpp 文件的第二版
|
||||
* 日期:2006年11月27日11点33分 第一版 version 1.0
|
||||
* 作者:aladdin
|
||||
* CopyRight : EZFlash Group
|
||||
*
|
||||
**************************************************************************************************************/
|
||||
#include <stdio.h>
|
||||
|
||||
#include "dscard.h"
|
||||
#include "string.h"
|
||||
#include "io_sc_common.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static u32 ID = 0x227E2218;
|
||||
|
||||
static bool checkForSuperCard() {
|
||||
_SC_changeMode(SC_MODE_RAM); // Try again with SuperCard
|
||||
// _SC_changeMode16(0x1510);
|
||||
*(vu16*)(0x08000000) = 0x4D54;
|
||||
if (*(vu16*)(0x08000000) == 0x4D54)return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
|
||||
//---------------------------------------------------
|
||||
//DS 卡 基本操作
|
||||
/************
|
||||
void Enable_Arm9DS()
|
||||
{
|
||||
WAIT_CR &= ~0x0800;
|
||||
}
|
||||
|
||||
void Enable_Arm7DS()
|
||||
{
|
||||
WAIT_CR |= 0x0800;
|
||||
}
|
||||
*************/
|
||||
void OpenNorWrite() {
|
||||
*(vu16*)0x9fe0000 = 0xd200;
|
||||
*(vu16*)0x8000000 = 0x1500;
|
||||
*(vu16*)0x8020000 = 0xd200;
|
||||
*(vu16*)0x8040000 = 0x1500;
|
||||
*(vu16*)0x9C40000 = 0x1500;
|
||||
*(vu16*)0x9fc0000 = 0x1500;
|
||||
}
|
||||
|
||||
void CloseNorWrite() {
|
||||
*(vu16*)0x9fe0000 = 0xd200;
|
||||
*(vu16*)0x8000000 = 0x1500;
|
||||
*(vu16*)0x8020000 = 0xd200;
|
||||
*(vu16*)0x8040000 = 0x1500;
|
||||
*(vu16*)0x9C40000 = 0xd200;
|
||||
*(vu16*)0x9fc0000 = 0x1500;
|
||||
}
|
||||
|
||||
|
||||
void SetRompage(u16 page) {
|
||||
*(vu16*)0x9fe0000 = 0xd200;
|
||||
*(vu16*)0x8000000 = 0x1500;
|
||||
*(vu16*)0x8020000 = 0xd200;
|
||||
*(vu16*)0x8040000 = 0x1500;
|
||||
*(vu16*)0x9880000 = page;
|
||||
*(vu16*)0x9fc0000 = 0x1500;
|
||||
}
|
||||
|
||||
void SetRampage(u16 page) {
|
||||
*(vu16*)0x9fe0000 = 0xd200;
|
||||
*(vu16*)0x8000000 = 0x1500;
|
||||
*(vu16*)0x8020000 = 0xd200;
|
||||
*(vu16*)0x8040000 = 0x1500;
|
||||
*(vu16*)0x9c00000 = page;
|
||||
*(vu16*)0x9fc0000 = 0x1500;
|
||||
}
|
||||
|
||||
void SetSerialMode() {
|
||||
*(vu16*)0x9fe0000 = 0xd200;
|
||||
*(vu16*)0x8000000 = 0x1500;
|
||||
*(vu16*)0x8020000 = 0xd200;
|
||||
*(vu16*)0x8040000 = 0x1500;
|
||||
*(vu16*)0x9A40000 = 0xe200;
|
||||
*(vu16*)0x9fc0000 = 0x1500;
|
||||
}
|
||||
|
||||
u32 ReadNorFlashID() {
|
||||
vu16 id1, id2, id3, id4;
|
||||
ID = 0;
|
||||
//check intel 512M 3in1 card
|
||||
*((vu16*)(FlashBase+0)) = 0xFF ;
|
||||
*((vu16*)(FlashBase+0x1000*2)) = 0xFF ;
|
||||
*((vu16*)(FlashBase+0)) = 0x90 ;
|
||||
*((vu16*)(FlashBase+0x1000*2)) = 0x90 ;
|
||||
id1 = *((vu16*)(FlashBase+0)) ;
|
||||
id2 = *((vu16*)(FlashBase+0x1000*2)) ;
|
||||
id3 = *((vu16*)(FlashBase+1*2)) ;
|
||||
id4 = *((vu16*)(FlashBase+0x1001*2)) ;
|
||||
if((id1==0x89) && (id2==0x89)) {
|
||||
if(((id3==0x8816)||(id3 ==0x8810))&&((id4==0x8816)||(id4==0x8810))) {
|
||||
ID = 0x89168916;
|
||||
return 0x89168916;
|
||||
}
|
||||
}
|
||||
// check original version chips
|
||||
*((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)) {
|
||||
if (checkForSuperCard()) {
|
||||
ID = 0x227E2202;
|
||||
return 0x227E0000;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
id1 = *((vu16*)(FlashBase+0xE*2));
|
||||
id2 = *((vu16*)(FlashBase+0x100e*2));
|
||||
|
||||
/*FILE *testFile = fopen("/gbacardID.bin", "wb");
|
||||
if (testFile) {
|
||||
fwrite((void*)FlashBase+0xE*2, 2, 1, testFile);
|
||||
fwrite((void*)FlashBase+0x100e*2, 2, 1, testFile);
|
||||
fclose(testFile);
|
||||
}*/
|
||||
|
||||
if(id1 == 0x2202) {
|
||||
if ((id2 == 0x2202) || (id2 == 0x2220) || (id2 == 0x2215)) { // VZ064
|
||||
ID = 0x227E2202;
|
||||
return 0x227E2202;
|
||||
}
|
||||
} else if(id1 == 0x2218) {
|
||||
if (id2 == 0x2218) { // H6H6
|
||||
ID = 0x227E2218;
|
||||
return 0x227E2218;
|
||||
}
|
||||
}
|
||||
return 0x227E2220;
|
||||
}
|
||||
|
||||
void chip_reset() {
|
||||
if(ID == 0x89168916) {
|
||||
*((vu16*)(FlashBase+0)) = 0x50;
|
||||
*((vu16*)(FlashBase+0x1000*2)) = 0x50;
|
||||
*((vu16*)(FlashBase+0)) = 0xFF;
|
||||
*((vu16*)(FlashBase+0x1000*2)) = 0xFF;
|
||||
} else {
|
||||
*((vu16*)(FlashBase)) = 0xF0;
|
||||
*((vu16*)(FlashBase+0x1000*2)) = 0xF0;
|
||||
if(ID==0x227E2202) {
|
||||
*((vu16*)(FlashBase+0x1000000)) = 0xF0;
|
||||
*((vu16*)(FlashBase+0x1000000+0x1000*2)) = 0xF0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Block_EraseIntel(u32 blockAdd) {
|
||||
u32 loop;
|
||||
vu16 v1,v2;
|
||||
bool b512 = false;
|
||||
vu32 blockAddress = blockAdd;
|
||||
if(blockAddress >= 0x2000000) {
|
||||
// blockAdd-=0x2000000;
|
||||
blockAddress -= 0x2000000;
|
||||
CloseNorWrite();
|
||||
SetRompage(768);
|
||||
OpenNorWrite();
|
||||
b512=true;
|
||||
}
|
||||
if(blockAddress == 0) {
|
||||
for(loop=0;loop<0x40000;loop+=0x10000) {
|
||||
*((vu16 *)(FlashBase+loop)) = 0x50;
|
||||
*((vu16 *)(FlashBase+loop+0x2000)) = 0x50;
|
||||
*((vu16 *)(FlashBase+loop)) = 0xFF;
|
||||
*((vu16 *)(FlashBase+loop+0x2000)) = 0xFF;
|
||||
*((vu16 *)(FlashBase+loop)) = 0x60;
|
||||
*((vu16 *)(FlashBase+loop+0x2000)) = 0x60;
|
||||
*((vu16 *)(FlashBase+loop)) = 0xD0;
|
||||
*((vu16 *)(FlashBase+loop+0x2000)) = 0xD0;
|
||||
*((vu16 *)(FlashBase+loop)) = 0x20;
|
||||
*((vu16 *)(FlashBase+loop+0x2000)) = 0x20;
|
||||
*((vu16 *)(FlashBase+loop)) = 0xD0;
|
||||
*((vu16 *)(FlashBase+loop+0x2000)) = 0xD0;
|
||||
do {
|
||||
v1 = *((vu16 *)(FlashBase+loop));
|
||||
v2 = *((vu16 *)(FlashBase+loop+0x2000));
|
||||
}
|
||||
while((v1!=0x80)||(v2!=0x80));
|
||||
}
|
||||
} else {
|
||||
*((vu16 *)(FlashBase+blockAddress)) = 0xFF;
|
||||
*((vu16 *)(FlashBase+blockAddress+0x2000)) = 0xFF;
|
||||
*((vu16 *)(FlashBase+blockAddress)) = 0x60;
|
||||
*((vu16 *)(FlashBase+blockAddress+0x2000)) = 0x60;
|
||||
*((vu16 *)(FlashBase+blockAddress)) = 0xD0;
|
||||
*((vu16 *)(FlashBase+blockAddress+0x2000)) = 0xD0;
|
||||
*((vu16 *)(FlashBase+blockAddress)) = 0x20;
|
||||
*((vu16 *)(FlashBase+blockAddress+0x2000)) = 0x20;
|
||||
*((vu16 *)(FlashBase+blockAddress)) = 0xD0 ;
|
||||
*((vu16 *)(FlashBase+blockAddress+0x2000)) = 0xD0;
|
||||
do {
|
||||
v1 = *((vu16 *)(FlashBase+blockAddress));
|
||||
v2 = *((vu16 *)(FlashBase+blockAddress+0x2000));
|
||||
}
|
||||
while((v1!=0x80)||(v2!=0x80));
|
||||
}
|
||||
if(b512) {
|
||||
CloseNorWrite();
|
||||
SetRompage(0);
|
||||
OpenNorWrite();
|
||||
b512= true;
|
||||
}
|
||||
}
|
||||
|
||||
void Block_Erase(u32 blockAdd) {
|
||||
vu16 v1,v2;
|
||||
u32 Address;
|
||||
u32 loop;
|
||||
u32 off=0;
|
||||
if((blockAdd>=0x1000000) && (ID==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 ReadNorFlash(u8* pBuf,u32 address,u16 len) {
|
||||
vu16 *p = (vu16 *)pBuf;
|
||||
u32 loop;
|
||||
u32 mapAddress = address;
|
||||
bool b512 = false;
|
||||
if(mapAddress >= 0x2000000) { //256M
|
||||
CloseNorWrite();
|
||||
SetRompage(768);
|
||||
// address-=0x2000000;
|
||||
mapAddress -= 0x2000000;
|
||||
b512 = true;
|
||||
OpenNorWrite();
|
||||
}
|
||||
if(ID==0x89168916) {
|
||||
*((vu16*)(FlashBase+mapAddress)) = 0x50;
|
||||
*((vu16*)(FlashBase+mapAddress+0x1000*2)) = 0x50;
|
||||
*((vu16*)(FlashBase+mapAddress)) = 0xFF;
|
||||
*((vu16*)(FlashBase+mapAddress+0x1000*2)) = 0xFF;
|
||||
}
|
||||
for(loop=0;loop<len/2;loop++)p[loop]=*((vu16*)(FlashBase+mapAddress+loop*2));
|
||||
// if (ID==0x89168916)CloseNorWrite();
|
||||
if(b512)SetRompage(0);
|
||||
}*/
|
||||
|
||||
void WriteNorFlashINTEL(u32 address,u8 *buffer,u32 size) {
|
||||
u32 mapaddress;
|
||||
u32 size2,lop,j;
|
||||
vu16* buf = (vu16*)buffer;
|
||||
u32 loopwrite,i;
|
||||
vu16 v1,v2;
|
||||
vu32 offset = 0;
|
||||
|
||||
bool b512 = false;
|
||||
|
||||
if(address >= 0x2000000) {
|
||||
// address-=0x2000000;
|
||||
offset = 0x2000000;
|
||||
CloseNorWrite();
|
||||
SetRompage(768);
|
||||
OpenNorWrite();
|
||||
b512 = true;
|
||||
} else {
|
||||
CloseNorWrite();
|
||||
SetRompage(0);
|
||||
OpenNorWrite();
|
||||
}
|
||||
|
||||
if(size>0x4000) {
|
||||
size2 = size >>1;
|
||||
lop = 2;
|
||||
} else {
|
||||
size2 = size;
|
||||
lop = 1;
|
||||
}
|
||||
|
||||
mapaddress = (address - offset);
|
||||
|
||||
for(j=0;j<lop;j++) {
|
||||
if(j!=0) {
|
||||
mapaddress += 0x4000;
|
||||
buf = (vu16*)(buffer+0x4000);
|
||||
}
|
||||
for(loopwrite=0;loopwrite<(size2);loopwrite+=64) {
|
||||
*((vu16*)(FlashBase+mapaddress+(loopwrite>>1))) = 0x50;
|
||||
*((vu16*)(FlashBase+mapaddress+(loopwrite>>1)+0x2000)) = 0x50;
|
||||
*((vu16*)(FlashBase+mapaddress+(loopwrite>>1))) = 0xFF;
|
||||
*((vu16*)(FlashBase+mapaddress+(loopwrite>>1)+0x2000)) = 0xFF;
|
||||
*((vu16*)(FlashBase+mapaddress+(loopwrite>>1))) = 0xE8;
|
||||
*((vu16*)(FlashBase+mapaddress+(loopwrite>>1)+0x2000)) = 0xE8;
|
||||
*((vu16*)(FlashBase+mapaddress+(loopwrite>>1))) = 0x70;
|
||||
*((vu16*)(FlashBase+mapaddress+(loopwrite>>1)+0x2000)) = 0x70;
|
||||
v1=v2=0;
|
||||
while((v1!= 0x80) || (v2 != 0x80)) {
|
||||
v1 = *((vu16 *)(FlashBase+mapaddress+(loopwrite>>1)));
|
||||
v2 = *((vu16 *)(FlashBase+mapaddress+(loopwrite>>1)+0x2000));
|
||||
}
|
||||
*((vu16 *)(FlashBase+mapaddress+(loopwrite>>1))) = 0x0F;
|
||||
*((vu16 *)(FlashBase+mapaddress+(loopwrite>>1)+0x2000)) = 0x0F;
|
||||
for(i=0;i<0x10;i++) {
|
||||
*((vu16 *)(FlashBase+mapaddress+(loopwrite>>1)+i*2)) = buf[(loopwrite>>2)+i];
|
||||
*((vu16 *)(FlashBase+mapaddress+0x2000+(loopwrite>>1)+i*2)) = buf[0x1000+(loopwrite>>2)+i];
|
||||
}
|
||||
*((vu16*)(FlashBase+mapaddress+(loopwrite>>1))) = 0xD0;
|
||||
*((vu16*)(FlashBase+mapaddress+(loopwrite>>1)+0x2000)) = 0xD0;
|
||||
v1=v2=0;
|
||||
while((v1!= 0x80) || (v2 != 0x80)) {
|
||||
v1 = *((vu16*)(FlashBase+mapaddress+(loopwrite>>1)));
|
||||
v2 = *((vu16*)(FlashBase+mapaddress+(loopwrite>>1)+0x2000));
|
||||
if((v1==0x90) || (v2==0x90)) { // error response, hopefully this never actually happens?
|
||||
WriteSram(0xA000000,(u8 *)buf,0x8000);
|
||||
while(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(b512) {
|
||||
CloseNorWrite();
|
||||
SetRompage(0);
|
||||
OpenNorWrite();
|
||||
}
|
||||
}
|
||||
|
||||
void WriteNorFlash(u32 address,u8 *buffer,u32 size) {
|
||||
if(ID == 0x89168916) {
|
||||
WriteNorFlashINTEL(address,buffer,size);
|
||||
return;
|
||||
}
|
||||
vu16 v1,v2;
|
||||
u32 loopwrite;
|
||||
vu16* buf = (vu16*)buffer;
|
||||
u32 size2,lop;
|
||||
u32 mapaddress;
|
||||
u32 j;
|
||||
v1=0;v2=1;
|
||||
u32 off=0;
|
||||
|
||||
if((address >= 0x1000000) && (ID == 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<lop;j++) {
|
||||
if(j!=0) {
|
||||
mapaddress += 0x4000;
|
||||
buf = (vu16*)(buffer+0x4000);
|
||||
}
|
||||
for(loopwrite=0;loopwrite<(size2>>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 WriteSram(uint32 address, u8* data , uint32 size ) {
|
||||
uint32 i ;
|
||||
for(i=0;i<size;i++)*(u8*)(address+i)=data[i];
|
||||
}
|
||||
|
||||
void ReadSram(uint32 address, u8* data , uint32 size ) {
|
||||
uint32 i;
|
||||
for(i=0;i<size;i++)data[i] = *(u8*)(address+i);
|
||||
}
|
||||
|
||||
void OpenRamWrite() {
|
||||
*(vu16*)0x9fe0000 = 0xd200;
|
||||
*(vu16*)0x8000000 = 0x1500;
|
||||
*(vu16*)0x8020000 = 0xd200;
|
||||
*(vu16*)0x8040000 = 0x1500;
|
||||
*(vu16*)0x9C40000 = 0xA500;
|
||||
*(vu16*)0x9fc0000 = 0x1500;
|
||||
}
|
||||
|
||||
void CloseRamWrite() {
|
||||
*(vu16*)0x9fe0000 = 0xd200;
|
||||
*(vu16*)0x8000000 = 0x1500;
|
||||
*(vu16*)0x8020000 = 0xd200;
|
||||
*(vu16*)0x8040000 = 0x1500;
|
||||
*(vu16*)0x9C40000 = 0xA200;
|
||||
*(vu16*)0x9fc0000 = 0x1500;
|
||||
}
|
||||
|
||||
void SetShake(u16 data) {
|
||||
*(vu16*)0x9fe0000 = 0xd200;
|
||||
*(vu16*)0x8000000 = 0x1500;
|
||||
*(vu16*)0x8020000 = 0xd200;
|
||||
*(vu16*)0x8040000 = 0x1500;
|
||||
*(vu16*)0x9E20000 = data;
|
||||
*(vu16*)0x9fc0000 = 0x1500;
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -30,7 +30,7 @@
|
||||
|
||||
#define MAX_NOR 0x2000000 // 32MByte
|
||||
#define MAX_NORPLUS 0x4000000 // 64MByte (3 in 1 Plus)
|
||||
#define MAX_PSRAM 0x1000000 // 16MByte
|
||||
#define MAX_PSRAM 0x1000000 // 16MByte
|
||||
#define SRAM_PAGE_SIZE 0x1000 // SRAM Page Size
|
||||
#define MAX_SRAM 0x80000 // 4MBit/512KByte total SRAM
|
||||
|
||||
@ -450,17 +450,17 @@ int checkFlashID() {
|
||||
return carttype;
|
||||
case 0x227E2218: carttype = 1; return carttype; // 3in1
|
||||
case 0x227E2202: carttype = 2; return carttype; // New3in1
|
||||
case 0x227E2222:
|
||||
is3in1Plus = true;
|
||||
isSuperCard = false;
|
||||
carttype = 2; // 3in1 Plus
|
||||
return carttype;
|
||||
case 0x227E2220: carttype = 3; return carttype; // EZ4
|
||||
case 0x227E0000: // SuperCard
|
||||
carttype = 6;
|
||||
is3in1Plus = false;
|
||||
isSuperCard = true;
|
||||
return carttype; // SuperCard
|
||||
return carttype;
|
||||
case 0x89168916: // 3in1 Plus
|
||||
is3in1Plus = true;
|
||||
isSuperCard = false;
|
||||
carttype = 1;
|
||||
return carttype;
|
||||
default: return 0; // Unsupported/Unimplemented Cart ID
|
||||
}
|
||||
}
|
||||
@ -638,27 +638,23 @@ void writeSramToFile(char *savename) {
|
||||
ReadSram(SRAM_ADDR, rwbuf, USE_SRAM / 2);
|
||||
if(saver != NULL) {
|
||||
len = USE_SRAM / 2;
|
||||
if(len > savesize)
|
||||
len = savesize;
|
||||
if(len > savesize)len = savesize;
|
||||
fwrite(rwbuf, 1, len, saver);
|
||||
}
|
||||
if(savesize > USE_SRAM / 2) {
|
||||
_RamSave(1);
|
||||
ReadSram(SRAM_ADDR, rwbuf, USE_SRAM / 2);
|
||||
if(saver != NULL)
|
||||
fwrite(rwbuf, 1, USE_SRAM / 2, saver);
|
||||
if(saver != NULL)fwrite(rwbuf, 1, USE_SRAM / 2, saver);
|
||||
}
|
||||
fclose(saver);
|
||||
|
||||
ctrl.save_flg[GBAmode] = 0xFF;
|
||||
|
||||
if(carttype < 4)
|
||||
OpenNorWrite();
|
||||
if(carttype < 4)OpenNorWrite();
|
||||
|
||||
ctrl_set();
|
||||
|
||||
if(carttype < 4)
|
||||
CloseNorWrite();
|
||||
if(carttype < 4)CloseNorWrite();
|
||||
}
|
||||
|
||||
void _WritePSram(uint32 address, u8* data , uint32 size );
|
||||
@ -852,7 +848,6 @@ int writeFileToNor(int sel) {
|
||||
strcpy(savName, fs[sel].filename);
|
||||
cmd = save_sel(0, savName);
|
||||
|
||||
|
||||
SetRompage(0);
|
||||
OpenNorWrite();
|
||||
SetSerialMode();
|
||||
@ -860,8 +855,9 @@ int writeFileToNor(int sel) {
|
||||
|
||||
for(siz = 0; siz < fs[sel].filesize; siz += 0x40000) {
|
||||
dsp_bar(0, siz * 100 / fs[sel].filesize);
|
||||
Block_Erase(siz);
|
||||
if (is3in1Plus) { Block_EraseIntel(siz); } else { Block_Erase(siz); }
|
||||
}
|
||||
|
||||
dsp_bar(0, 100);
|
||||
|
||||
chip_reset();
|
||||
@ -901,11 +897,7 @@ int writeFileToNor(int sel) {
|
||||
CloseNorWrite();
|
||||
|
||||
// getSaveFilename(sel, savName);
|
||||
if(cmd >= 0) {
|
||||
writeSramFromFile(savName);
|
||||
} else {
|
||||
blankSRAM(savName);
|
||||
}
|
||||
if(cmd >= 0) { writeSramFromFile(savName); } else { blankSRAM(savName); }
|
||||
|
||||
dsp_bar(-1, 100);
|
||||
// SetRampage(USE_SRAM_NOR);
|
||||
@ -914,8 +906,8 @@ int writeFileToNor(int sel) {
|
||||
|
||||
|
||||
int writeFileToRam(int sel) {
|
||||
FILE *gbaFile;
|
||||
char savName[512];
|
||||
FILE *gbaFile;
|
||||
char savName[512];
|
||||
u32 siz;
|
||||
u32 exp, exps;
|
||||
u32 fsz;
|
@ -51,7 +51,7 @@ extern uint16* SubScreen;
|
||||
|
||||
#define BG_256_COLOR (BIT(7))
|
||||
|
||||
#define VERSTRING "v0.59"
|
||||
#define VERSTRING "v0.60"
|
||||
|
||||
int numFiles = 0;
|
||||
int numGames = 0;
|
||||
@ -75,7 +75,7 @@ u8 *rwbuf;
|
||||
extern int carttype;
|
||||
extern bool isSuperCard;
|
||||
extern bool is3in1Plus;
|
||||
|
||||
extern bool finishedNorFlash;
|
||||
|
||||
u32 inp_key() {
|
||||
u32 ky;
|
||||
@ -195,7 +195,7 @@ static void resetToSlot2() {
|
||||
swiSoftReset();
|
||||
}
|
||||
|
||||
ITCM_CODE void gbaMode() {
|
||||
void gbaMode() {
|
||||
|
||||
if(strncmp(GBA_HEADER.gamecode, "PASS", 4) == 0) {
|
||||
// resetARM9Memory();
|
||||
@ -847,7 +847,7 @@ int gba_sel() {
|
||||
}
|
||||
|
||||
|
||||
if(ky & KEY_L) {
|
||||
if((ky & KEY_L) && !isSuperCard) {
|
||||
if(GBAmode > 0) {
|
||||
GBAmode--;
|
||||
setGBAmode();
|
||||
@ -856,8 +856,8 @@ int gba_sel() {
|
||||
// break;
|
||||
}
|
||||
}
|
||||
if(ky & KEY_R) {
|
||||
if(r4tf && carttype > 2) {
|
||||
if((ky & KEY_R) && !isSuperCard) {
|
||||
if(r4tf && (carttype > 2)) {
|
||||
cmd = 3;
|
||||
break;
|
||||
}
|
||||
@ -1047,14 +1047,14 @@ REG_EXMEMCNT = (reg & 0xFFE0) | (1 << 4) | (1 << 2) | 1;
|
||||
turn_off(r4tf);
|
||||
break;
|
||||
case 1:
|
||||
ShinoPrint_SUB( SubScreen, 23*6, 1*12-2, (u8*)" [ 3in1 ]", 0, 0, 0 ); break; // SetRampage(16); // SetShake(0x08);
|
||||
case 2:
|
||||
if (is3in1Plus) {
|
||||
ShinoPrint_SUB( SubScreen, 23*6, 1*12-2, (u8*)"[3in1Plus]", 0, 0, 0 );
|
||||
ShinoPrint_SUB( SubScreen, 23*6, 1*12-2, (u8*)"[3in1Pls]", 0, 0, 0 );
|
||||
} else {
|
||||
ShinoPrint_SUB( SubScreen, 23*6, 1*12-2, (u8*)"[New3in1]", 0, 0, 0 );
|
||||
ShinoPrint_SUB( SubScreen, 23*6, 1*12-2, (u8*)" [ 3in1 ]", 0, 0, 0 );
|
||||
}
|
||||
break;
|
||||
break; // SetRampage(16); // SetShake(0x08);
|
||||
case 2:
|
||||
ShinoPrint_SUB( SubScreen, 23*6, 1*12-2, (u8*)"[New3in1]", 0, 0, 0 ); break;
|
||||
case 3:
|
||||
SetRompage(0x300);
|
||||
ShinoPrint_SUB( SubScreen, 23*6, 1*12-2, (u8*)" [ EZ4 ]", 0, 0, 0 );
|
||||
@ -1083,26 +1083,25 @@ REG_EXMEMCNT = (reg & 0xFFE0) | (1 << 4) | (1 << 2) | 1;
|
||||
r4tf = 3;
|
||||
} else {
|
||||
r4tf = 0;
|
||||
if(io_dldi_data->ioInterface.ioType == 0x46543452) { // R4TF
|
||||
/*if(_io_dldi == 0x46543452) { // R4TF
|
||||
if((*(vu32*)0x027FFE18) == 0x00000000) {
|
||||
/*r4dt = fopen("/_DS_MENU.DAT", "rb");
|
||||
r4dt = fopen("/_DS_MENU.DAT", "rb");
|
||||
if(r4dt != NULL) {
|
||||
handle = (__handle *)r4dt->_file;
|
||||
// handle = (_handle*)r4dt->_file;
|
||||
// file = (_FILE_STRUCT*)handle->fileStruct;
|
||||
file = (FILE*)handle->fileStruct;
|
||||
// part = file->partition;
|
||||
// (*(vu32*)0x027FFE18) = (part->rootDirStart + file->dirEntryStart.sector) * 512 + file->dirEntryStart.offset * 32;
|
||||
file = (FILE_STRUCT *)handle->fileStruct;
|
||||
part = file->partition;
|
||||
(*(vu32*)0x027FFE18) = (part->rootDirStart + file->dirEntryStart.sector) * 512 + file->dirEntryStart.offset * 32;
|
||||
fclose(r4dt);
|
||||
r4tf = 1;
|
||||
}*/
|
||||
}
|
||||
} else {
|
||||
r4tf = 1;
|
||||
}
|
||||
}
|
||||
|
||||
}*/
|
||||
if(io_dldi_data->ioInterface.ioType == 0x534D4C44)r4tf = 2; // DLMS
|
||||
}
|
||||
|
||||
if (isSuperCard)r4tf = 0;
|
||||
|
||||
/******************************
|
||||
sprintf(tbuf, "0x27FFE18 = %08X", (*(vu32*)0x027FFE18));
|
||||
@ -1186,7 +1185,6 @@ inp_key();
|
||||
}
|
||||
|
||||
turn_off(r4tf);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
#define maindef_h
|
||||
|
||||
#define ROMTITLE "GBA ExpLoader"
|
||||
#define ROMVERSION "Version 0.58 by Rudolph."
|
||||
#define ROMVERSION "Version 0.60 by Rudolph."
|
||||
#define ROMDATE ""__DATE__" "__TIME__
|
||||
|
||||
#endif
|
||||
|
@ -5,7 +5,6 @@
|
||||
***************************************************************/
|
||||
|
||||
#include <nds.h>
|
||||
//#include <nds/registers_alt.h> // devkitPror20
|
||||
#include <nds/arm9/dldi.h>
|
||||
|
||||
#include <fat.h>
|
||||
@ -13,10 +12,11 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
// extern u32 _io_dldi;
|
||||
static char *menu_nam;
|
||||
static char name[32];
|
||||
|
||||
static char *menu_nam;
|
||||
static char name[32];
|
||||
static ALIGN(4) u32 hed[16];
|
||||
static ALIGN(4) u8 *ldrBuf;
|
||||
|
||||
bool ret_menu_chk() {
|
||||
FILE *fp;
|
||||
@ -39,7 +39,7 @@ bool ret_menu_chk() {
|
||||
|
||||
switch (io_dldi_data->ioInterface.ioType) {
|
||||
case 0x53444353: menu_nam = "/MSFORSC.NDS"; break; // SCDS
|
||||
// case 0x4F49524E: menu_nam = "/udisk.nds"; break; // N-Card and Clones
|
||||
case 0x4F49524E: menu_nam = "/udisk.dat"; break; // N-Card and Clones
|
||||
case 0x4E475052: menu_nam = "/akmenu4.nds"; break; // AK.R.P.G NAND
|
||||
case 0x53475052: menu_nam = "/akmenu4.nds"; break; // AK.R.P.G SD
|
||||
case 0x44533958: menu_nam = "/loader.nds"; break; // X9 SD
|
||||
@ -61,11 +61,8 @@ bool ret_menu_chk() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool ret_menu9_Gen() {
|
||||
u32 hed[16];
|
||||
u8 *ldrBuf;
|
||||
FILE *ldr;
|
||||
ITCM_CODE bool ret_menu9_Gen() {
|
||||
FILE *ldr;
|
||||
u32 siz;
|
||||
|
||||
ldr = fopen(menu_nam, "rb");
|
||||
@ -90,7 +87,6 @@ bool ret_menu9_Gen() {
|
||||
|
||||
fclose(ldr);
|
||||
|
||||
|
||||
(*(vu32*)0x027FFDF4) = (u32)ldrBuf;
|
||||
|
||||
return true;
|
||||
|
@ -281,9 +281,9 @@ static bool intLoadBM(const char *bmpfn,u16 *pbm,const u32 bmw,const u32 bmh) {
|
||||
}
|
||||
|
||||
|
||||
DTCM_DATA ALIGN(4) static u16 *pBuf;
|
||||
ALIGN(4) static u16 *pBuf;
|
||||
|
||||
ITCM_CODE bool LoadSkin(int mod, char *Name) {
|
||||
bool LoadSkin(int mod, char *Name) {
|
||||
|
||||
u16 *pDstBuf1;
|
||||
u16 *pDstBuf2;
|
||||
|
Loading…
Reference in New Issue
Block a user