akmenu-next/arm9/source/exptools.cpp
2024-10-04 22:35:39 -07:00

371 lines
9.2 KiB
C++

/*
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 <http://www.gnu.org/licenses/>.
*/
#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<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 cExpansion::WritePSRAM(u32 address,const u8* buffer,u32 size)
{
u16* addr=(u16*)(address+_PSRAM);
u16* pData=(u16*)buffer;
for(u32 i=0;i<size;i+=2)
{
addr[i>>1]=pData[i>>1];
}
}
void cExpansion::WriteSram(uint32 address,const u8* data,uint32 size)
{
for(u32 i=0;i<size;i++)
*(u8*)(address+i)=data[i];
}
void cExpansion::ReadSram(uint32 address,u8* data,uint32 size)
{
u16* pData=(u16*)data;
for(u32 i=0;i<size;i+=2)
{
pData[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;
}
}