From 049f3700d6ae5f543e2df312a358ff4e54e3948e Mon Sep 17 00:00:00 2001 From: ApacheThunder Date: Sun, 19 May 2024 02:24:34 -0500 Subject: [PATCH] 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. ;) --- Makefile | 2 +- arm9/Makefile | 1 - arm9/source/dsCard.cpp | 388 -------------- arm9/source/dsCard.h | 4 +- arm9/source/dsCard.itcm.cpp | 529 ++++++++++++++++++++ arm9/source/{gbaldr.cpp => gbaldr.itcm.cpp} | 40 +- arm9/source/main.c | 42 +- arm9/source/maindef.h | 2 +- arm9/source/ret_menu9_Gen.c | 18 +- arm9/source/skin.cpp | 4 +- 10 files changed, 579 insertions(+), 451 deletions(-) delete mode 100644 arm9/source/dsCard.cpp create mode 100644 arm9/source/dsCard.itcm.cpp rename arm9/source/{gbaldr.cpp => gbaldr.itcm.cpp} (97%) diff --git a/Makefile b/Makefile index bda4bc9..631886d 100644 --- a/Makefile +++ b/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 diff --git a/arm9/Makefile b/arm9/Makefile index b047ba2..7924fda 100644 --- a/arm9/Makefile +++ b/arm9/Makefile @@ -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 diff --git a/arm9/source/dsCard.cpp b/arm9/source/dsCard.cpp deleted file mode 100644 index c6cbe79..0000000 --- a/arm9/source/dsCard.cpp +++ /dev/null @@ -1,388 +0,0 @@ -/************************************************************************************************************** - * 此文件为 dsCard.cpp 文件的第二版 - * 日期:2006年11月27日11点33分 第一版 version 1.0 - * 作者:aladdin - * CopyRight : EZFlash Group - * - **************************************************************************************************************/ -#include - -#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=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>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>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 - diff --git a/arm9/source/dsCard.h b/arm9/source/dsCard.h index b5246db..ae92f82 100644 --- a/arm9/source/dsCard.h +++ b/arm9/source/dsCard.h @@ -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 ); diff --git a/arm9/source/dsCard.itcm.cpp b/arm9/source/dsCard.itcm.cpp new file mode 100644 index 0000000..7381e2b --- /dev/null +++ b/arm9/source/dsCard.itcm.cpp @@ -0,0 +1,529 @@ +/************************************************************************************************************** + * 此文件为 dsCard.cpp 文件的第二版 + * 日期:2006年11月27日11点33分 第一版 version 1.0 + * 作者:aladdin + * CopyRight : EZFlash Group + * + **************************************************************************************************************/ +#include + +#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= 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>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>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 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; diff --git a/arm9/source/main.c b/arm9/source/main.c index 84612a0..f30ed37 100644 --- a/arm9/source/main.c +++ b/arm9/source/main.c @@ -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); - } diff --git a/arm9/source/maindef.h b/arm9/source/maindef.h index d6172f1..ae366f3 100644 --- a/arm9/source/maindef.h +++ b/arm9/source/maindef.h @@ -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 diff --git a/arm9/source/ret_menu9_Gen.c b/arm9/source/ret_menu9_Gen.c index 631620a..222addc 100644 --- a/arm9/source/ret_menu9_Gen.c +++ b/arm9/source/ret_menu9_Gen.c @@ -5,7 +5,6 @@ ***************************************************************/ #include -//#include // devkitPror20 #include #include @@ -13,10 +12,11 @@ #include #include -// 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; diff --git a/arm9/source/skin.cpp b/arm9/source/skin.cpp index b17bf0b..0183326 100644 --- a/arm9/source/skin.cpp +++ b/arm9/source/skin.cpp @@ -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;