/* exptools.cpp Copyright (C) 2007-2009 somebody Copyright (C) 2009 yellow wood goblin This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "exptools.h" #define _PSRAM 0x08060000 // an offset into PSRAM to write to so stuff doesn't get lost... void cExpansion::OpenNorWrite(void) { *(vu16*)0x9fe0000=0xd200; *(vu16*)0x8000000=0x1500; *(vu16*)0x8020000=0xd200; *(vu16*)0x8040000=0x1500; *(vu16*)0x9c40000=0x1500; *(vu16*)0x9fc0000=0x1500; } void cExpansion::CloseNorWrite(void) { *(vu16*)0x9fe0000=0xd200; *(vu16*)0x8000000=0x1500; *(vu16*)0x8020000=0xd200; *(vu16*)0x8040000=0x1500; *(vu16*)0x9c40000=0xd200; *(vu16*)0x9fc0000=0x1500; } void cExpansion::SetRompage(u16 page) { *(vu16*)0x9fe0000=0xd200; *(vu16*)0x8000000=0x1500; *(vu16*)0x8020000=0xd200; *(vu16*)0x8040000=0x1500; *(vu16*)0x9880000=page; *(vu16*)0x9fc0000=0x1500; } void cExpansion::SetRampage(u16 page) { *(vu16*)0x9fe0000=0xd200; *(vu16*)0x8000000=0x1500; *(vu16*)0x8020000=0xd200; *(vu16*)0x8040000=0x1500; *(vu16*)0x9c00000=page; *(vu16*)0x9fc0000=0x1500; iRamPage=page; } u16 cExpansion::Rampage(void) { return iRamPage; } void cExpansion::SetSerialMode(void) { *(vu16*)0x9fe0000=0xd200; *(vu16*)0x8000000=0x1500; *(vu16*)0x8020000=0xd200; *(vu16*)0x8040000=0x1500; *(vu16*)0x9a40000=0xe200; *(vu16*)0x9fc0000=0x1500; } void cExpansion::SetShake(u16 data) { *(vu16*)0x9fe0000=0xd200; *(vu16*)0x8000000=0x1500; *(vu16*)0x8020000=0xd200; *(vu16*)0x8040000=0x1500; *(vu16*)0x9e20000=data; *(vu16*)0x9fc0000=0x1500; } void cExpansion::EnableBrowser(void) { for(u32 i=0;i<0x100;i+=4) { *(vu32*)(0x9000000+i)=0xffffffff; *(vu32*)(0x8000000+i)=0xffffffff; } *(vu32*)0x90000b0=0xffff; *(vu32*)0x90000b4=0x24242400; *(vu32*)0x90000b8=0xffffffff; *(vu32*)0x90000bc=0x7fffffff; *(vu32*)0x901fffc=0x7fffffff; *(vu16*)0x9240002=1; } void cExpansion::Block_Erase(u32 blockAdd) { vu16 v1,v2; u32 Address; u32 loop; u32 off=0; if((blockAdd>=0x1000000)&&(iId==0x227E2202)) { off=0x1000000; *((vu16*)(FlashBase+off+0x555*2))=0xF0; *((vu16*)(FlashBase+off+0x1555*2))=0xF0; } else off=0; Address=blockAdd; *((vu16*)(FlashBase+0x555*2))=0xF0; *((vu16*)(FlashBase+0x1555*2))=0xF0; if((blockAdd==0)||(blockAdd==0x1FC0000)||(blockAdd==0xFC0000)||(blockAdd==0x1000000)) { for(loop=0;loop<0x40000;loop+=0x8000) { *((vu16*)(FlashBase+off+0x555*2))=0xAA; *((vu16*)(FlashBase+off+0x2AA*2))=0x55; *((vu16*)(FlashBase+off+0x555*2))=0x80; *((vu16*)(FlashBase+off+0x555*2))=0xAA; *((vu16*)(FlashBase+off+0x2AA*2))=0x55; *((vu16*)(FlashBase+Address+loop))=0x30; *((vu16*)(FlashBase+off+0x1555*2))=0xAA; *((vu16*)(FlashBase+off+0x12AA*2))=0x55; *((vu16*)(FlashBase+off+0x1555*2))=0x80; *((vu16*)(FlashBase+off+0x1555*2))=0xAA; *((vu16*)(FlashBase+off+0x12AA*2))=0x55; *((vu16*)(FlashBase+Address+loop+0x2000))=0x30; *((vu16*)(FlashBase+off+0x2555*2))=0xAA; *((vu16*)(FlashBase+off+0x22AA*2))=0x55; *((vu16*)(FlashBase+off+0x2555*2))=0x80; *((vu16*)(FlashBase+off+0x2555*2))=0xAA; *((vu16*)(FlashBase+off+0x22AA*2))=0x55; *((vu16*)(FlashBase+Address+loop+0x4000))=0x30; *((vu16*)(FlashBase+off+0x3555*2))=0xAA; *((vu16*)(FlashBase+off+0x32AA*2))=0x55; *((vu16*)(FlashBase+off+0x3555*2))=0x80; *((vu16*)(FlashBase+off+0x3555*2))=0xAA; *((vu16*)(FlashBase+off+0x32AA*2))=0x55; *((vu16*)(FlashBase+Address+loop+0x6000))=0x30; do { v1=*((vu16*)(FlashBase+Address+loop)); v2=*((vu16*)(FlashBase+Address+loop)); } while(v1!=v2); do { v1=*((vu16*)(FlashBase+Address+loop+0x2000)); v2=*((vu16*)(FlashBase+Address+loop+0x2000)); } while(v1!=v2); do { v1=*((vu16*)(FlashBase+Address+loop+0x4000)); v2=*((vu16*)(FlashBase+Address+loop+0x4000)); }while(v1!=v2); do { v1=*((vu16*)(FlashBase+Address+loop+0x6000)); v2=*((vu16*)(FlashBase+Address+loop+0x6000)); }while(v1!=v2); } } else { *((vu16*)(FlashBase+off+0x555*2))=0xAA; *((vu16*)(FlashBase+off+0x2AA*2))=0x55; *((vu16*)(FlashBase+off+0x555*2))=0x80; *((vu16*)(FlashBase+off+0x555*2))=0xAA; *((vu16*)(FlashBase+off+0x2AA*2))=0x55; *((vu16*)(FlashBase+Address))=0x30; *((vu16*)(FlashBase+off+0x1555*2))=0xAA; *((vu16*)(FlashBase+off+0x12AA*2))=0x55; *((vu16*)(FlashBase+off+0x1555*2))=0x80; *((vu16*)(FlashBase+off+0x1555*2))=0xAA; *((vu16*)(FlashBase+off+0x12AA*2))=0x55; *((vu16*)(FlashBase+Address+0x2000))=0x30; do { v1=*((vu16*)(FlashBase+Address)); v2=*((vu16*)(FlashBase+Address)); }while(v1!=v2); do { v1=*((vu16*)(FlashBase+Address+0x2000)); v2=*((vu16*)(FlashBase+Address+0x2000)); }while(v1!=v2); *((vu16*)(FlashBase+off+0x555*2))=0xAA; *((vu16*)(FlashBase+off+0x2AA*2))=0x55; *((vu16*)(FlashBase+off+0x555*2))=0x80; *((vu16*)(FlashBase+off+0x555*2))=0xAA; *((vu16*)(FlashBase+off+0x2AA*2))=0x55; *((vu16*)(FlashBase+Address+0x20000))=0x30; *((vu16*)(FlashBase+off+0x1555*2))=0xAA; *((vu16*)(FlashBase+off+0x12AA*2))=0x55; *((vu16*)(FlashBase+off+0x1555*2))=0x80; *((vu16*)(FlashBase+off+0x1555*2))=0xAA; *((vu16*)(FlashBase+off+0x12AA*2))=0x55; *((vu16*)(FlashBase+Address+0x2000+0x20000))=0x30; do { v1=*((vu16*)(FlashBase+Address+0x20000)); v2=*((vu16*)(FlashBase+Address+0x20000)); } while(v1!=v2); do { v1=*((vu16*)(FlashBase+Address+0x2000+0x20000)); v2=*((vu16*)(FlashBase+Address+0x2000+0x20000)); } while(v1!=v2); } } void cExpansion::WriteNorFlash(u32 address,const u8* buffer,u32 size) { vu16 v1,v2; register u32 loopwrite; vu16* buf=(vu16*)buffer; u32 size2,lop; u32 mapaddress; u32 j; v1=0;v2=1; u32 off=0; if((address>=0x1000000)&&(iId==0x227E2202)) { off=0x1000000; } else off=0; if(size>0x4000) { size2=size>>1; lop=2; } else { size2=size; lop=1; } mapaddress=address; for(j=0;j>2);loopwrite++) { *((vu16*)(FlashBase+off+0x555*2))=0xAA; *((vu16*)(FlashBase+off+0x2AA*2))=0x55; *((vu16*)(FlashBase+off+0x555*2))=0xA0; *((vu16*)(FlashBase+mapaddress+loopwrite*2))=buf[loopwrite]; *((vu16*)(FlashBase+off+0x1555*2))=0xAA; *((vu16*)(FlashBase+off+0x12AA*2))=0x55; *((vu16*)(FlashBase+off+0x1555*2))=0xA0; *((vu16*)(FlashBase+mapaddress+0x2000+loopwrite*2))=buf[0x1000+loopwrite]; do { v1=*((vu16*)(FlashBase+mapaddress+loopwrite*2)); v2=*((vu16*)(FlashBase+mapaddress+loopwrite*2)); }while(v1!=v2); do { v1=*((vu16*)(FlashBase+mapaddress+0x2000+loopwrite*2)); v2=*((vu16*)(FlashBase+mapaddress+0x2000+loopwrite*2)); }while(v1!=v2); } } } void cExpansion::WritePSRAM(u32 address,const u8* buffer,u32 size) { u16* addr=(u16*)(address+_PSRAM); u16* pData=(u16*)buffer; for(u32 i=0;i>1]=pData[i>>1]; } } void cExpansion::WriteSram(uint32 address,const u8* data,uint32 size) { for(u32 i=0;i>1]=*(u8*)(address+i)+(*(u8*)(address+i+1)*0x100); } } void cExpansion::SoftReset(void) { CloseNorWrite(); SetRompage(0); SetRampage(16); SetShake(8); } void cExpansion::ReadNorFlashID(void) { vu16 id1,id2; *((vu16*)(FlashBase+0x555*2))=0xAA; *((vu16*)(FlashBase+0x2AA*2))=0x55; *((vu16*)(FlashBase+0x555*2))=0x90; *((vu16*)(FlashBase+0x1555*2))=0xAA; *((vu16*)(FlashBase+0x12AA*2))=0x55; *((vu16*)(FlashBase+0x1555*2))=0x90; id1=*((vu16*)(FlashBase+0x2)); id2=*((vu16*)(FlashBase+0x2002)); if((id1!=0x227E)||(id2!=0x227E)) return; id1=*((vu16*)(FlashBase+0xE*2)); id2=*((vu16*)(FlashBase+0x100e*2)); if(id1==0x2218&&id2==0x2218) //H6H6 { iId=0x227E2218; return; } if(id1==0x2202&&id2==0x2202) //VZ064 { iId=0x227E2202; return; } if(id1==0x2202&&id2==0x2220) //VZ064 { iId=0x227E2202; return; } if(id1==0x2202&&id2==0x2215) //VZ064 { iId=0x227E2202; return; } } void cExpansion::ChipReset(void) { *((vu16*)(FlashBase))=0xF0; *((vu16*)(FlashBase+0x1000*2))=0xF0; if(iId==0x227E2202) { *((vu16*)(FlashBase+0x1000000))=0xF0 ; *((vu16*)(FlashBase+0x1000000+0x1000*2))=0xF0; } }