akmenu-next/arm9/source/exptools.cpp
2024-10-13 02:11:12 -07:00

327 lines
11 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;
}
}