mirror of
https://github.com/ApacheThunder/GBA-Exploader.git
synced 2025-06-18 19:45:39 -04:00

* Fixed remaining save issues for most SuperCards. * Patching system from SCFW implemented for SuperCards. Prepatched roms no longer required for use with GBA-Exploader for SuperCards! * Initial EZ Flash Omega/Omega DE support! Note that there are still save issues right now. DE has partial saves working with just 128KB saves not working. (so Pokemon games do not hold saves currently)
650 lines
18 KiB
C++
650 lines
18 KiB
C++
/**************************************************************************************************************
|
||
* 此文件为 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"
|
||
#include "tonccpy.h"
|
||
|
||
#ifdef __cplusplus
|
||
extern "C" {
|
||
#endif
|
||
|
||
#define NOR_info_offset 0x7A0000
|
||
#define SET_info_offset 0x7B0000
|
||
|
||
static u32 ID = 0x227E2218;
|
||
|
||
u16 gl_ingame_RTC_open_status = 0;
|
||
|
||
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;
|
||
}
|
||
|
||
|
||
// EZ Flash Omega only
|
||
void SetSDControl(u16 control) {
|
||
*(u16 *)0x9fe0000 = 0xd200;
|
||
*(u16 *)0x8000000 = 0x1500;
|
||
*(u16 *)0x8020000 = 0xd200;
|
||
*(u16 *)0x8040000 = 0x1500;
|
||
*(u16 *)0x9400000 = control;
|
||
*(u16 *)0x9fc0000 = 0x1500;
|
||
}
|
||
|
||
void Set_AUTO_save(u16 mode) {
|
||
*(u16*)0x9fe0000 = 0xd200;
|
||
*(u16*)0x8000000 = 0x1500;
|
||
*(u16*)0x8020000 = 0xd200;
|
||
*(u16*)0x8040000 = 0x1500;
|
||
*(u16*)0x96C0000 = mode;
|
||
*(u16*)0x9fc0000 = 0x1500;
|
||
}
|
||
|
||
u16 Read_S71NOR_ID() {
|
||
*((vu16*)(FlashBase)) = 0xF0;
|
||
*((vu16*)(FlashBase+0x555*2)) = 0xAA;
|
||
*((vu16*)(FlashBase+0x2AA*2)) = 0x55;
|
||
*((vu16*)(FlashBase+0x555*2)) = 0x90;
|
||
u16 ID1 = *((vu16*)(FlashBase+0xE*2));
|
||
*((vu16*)(FlashBase)) = 0xF0;
|
||
return ID1;
|
||
}
|
||
|
||
u16 Read_S98NOR_ID() {
|
||
*((vu16*)(FlashBase_S98)) = 0xF0;
|
||
*((vu16*)(FlashBase_S98+0x555*2)) = 0xAA;
|
||
*((vu16*)(FlashBase_S98+0x2AA*2)) = 0x55;
|
||
*((vu16*)(FlashBase_S98+0x555*2)) = 0x90;
|
||
return *((vu16*)(FlashBase_S98+0xE*2));
|
||
}
|
||
|
||
// EZFlash Omega uses this
|
||
void SetPSRampage(u16 page) {
|
||
*(vu16*)0x9fe0000 = 0xd200;
|
||
*(vu16*)0x8000000 = 0x1500;
|
||
*(vu16*)0x8020000 = 0xd200;
|
||
*(vu16*)0x8040000 = 0x1500;
|
||
*(vu16*)0x9860000 = page; //C3
|
||
*(vu16*)0x9fc0000 = 0x1500;
|
||
}
|
||
|
||
u16 Read_SET_info(u32 offset) { return *((vu16 *)(FlashBase+SET_info_offset+offset*2)); }
|
||
|
||
// EZFlash Omega RTC thingy
|
||
void Set_RTC_status(u16 status) {
|
||
*(u16*)0x9fe0000 = 0xd200;
|
||
*(u16*)0x8000000 = 0x1500;
|
||
*(u16*)0x8020000 = 0xd200;
|
||
*(u16*)0x8040000 = 0x1500;
|
||
*(u16*)0x96A0000 = status;
|
||
*(u16*)0x9fc0000 = 0x1500;
|
||
}
|
||
|
||
void rtc_toggle(bool enable) {
|
||
if (enable) { *RTC_ENABLE = 1; } else { *RTC_ENABLE = 0; }
|
||
}
|
||
|
||
void Omega_Bank_Switching(u8 bank) {
|
||
*((vu8*)(SRAM_ADDR_OMEGA+0x5555)) = 0xAA;
|
||
*((vu8*)(SRAM_ADDR_OMEGA+0x2AAA)) = 0x55;
|
||
*((vu8*)(SRAM_ADDR_OMEGA+0x5555)) = 0xB0;
|
||
*((vu8*)SRAM_ADDR_OMEGA) = bank;
|
||
}
|
||
|
||
void SetbufferControl(u16 control) {
|
||
*(u16*)0x9fe0000 = 0xd200;
|
||
*(u16*)0x8000000 = 0x1500;
|
||
*(u16*)0x8020000 = 0xd200;
|
||
*(u16*)0x8040000 = 0x1500;
|
||
*(u16*)0x9420000 = control; //A1
|
||
*(u16*)0x9fc0000 = 0x1500;
|
||
}
|
||
|
||
static u32 FAT_table_buffer[0x400/4];
|
||
|
||
void Omega_InitFatBuffer(BYTE saveMODE) {
|
||
toncset((void*)FAT_table_buffer, 0, (0x400/4));
|
||
FAT_table_buffer[2] = 0xFFFFFFFF;
|
||
// FAT_table_buffer[0x1F0/4] = 0; //size
|
||
FAT_table_buffer[0x1F4/4] = 0x2; // 0x1 == rom copy to psram // 0x2 == copy mode
|
||
// FAT_table_buffer[0x1F8/4] = 0; // secort of cluster
|
||
// FAT_table_buffer[0x1FC/4] = (0x31<<24) | 0x20000; // save mode and save file size
|
||
FAT_table_buffer[0x1FC/4] = (saveMODE<<24) | 0x10000; // save mode and save file size
|
||
SetbufferControl(1);
|
||
// tonccpy((void*)0x9E00000, FAT_table_buffer, 0x400);
|
||
// dmaCopy(FAT_table_buffer, (void*)0x9E00000, 0x400);
|
||
tonccpy((void*)0x9E00000, FAT_table_buffer, 0x400);
|
||
SetbufferControl(3);
|
||
SetbufferControl(0);
|
||
}
|
||
|
||
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));
|
||
|
||
/*FILE *testFile = fopen("/gbacardID.bin", "wb");
|
||
if (testFile) {
|
||
fwrite((void*)(FlashBase+0x2), 2, 1, testFile);
|
||
fwrite((void*)(FlashBase+0x2002), 2, 1, testFile);
|
||
fclose(testFile);
|
||
}*/
|
||
|
||
if ((id1 != 0x227E) || (id2 != 0x227E)) {
|
||
if (checkForSuperCard()) {
|
||
ID = 0x227E2202;
|
||
return 0x227E0000;
|
||
}
|
||
// Check For EZ Flash Omega
|
||
SetRompage(0x8000);
|
||
id1 = Read_S98NOR_ID();
|
||
if ((id1 == 0x223D)) {
|
||
ID = 0x227EEA00;
|
||
return 0x227EEA00;
|
||
}
|
||
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; // EZFlash IV or EWIN
|
||
}
|
||
|
||
void chip_reset() {
|
||
if (ID == 0x227EEA00) {
|
||
*((vu16*)(FlashBase_S98)) = 0xF0;
|
||
return;
|
||
} else 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(SRAM_ADDR,(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
|
||
|