forked from Mirror/GodMode9
152 lines
3.6 KiB
C
152 lines
3.6 KiB
C
// Copyright 2014 Normmatt
|
|
// Licensed under GPLv2 or any later version
|
|
// Refer to the license.txt file included.
|
|
//
|
|
// modifyed by osilloscopion (2 Jul 2016)
|
|
//
|
|
|
|
#include "command_ntr.h"
|
|
#include "command_ak2i.h"
|
|
#include "protocol_ntr.h"
|
|
#include "card_ntr.h"
|
|
#include "delay.h"
|
|
|
|
u32 AK2I_CmdGetHardwareVersion(void)
|
|
{
|
|
u32 cmd[2] = {0xD1000000, 0x00000000};
|
|
u32 ver = 0;
|
|
|
|
NTR_SendCommand(cmd, 4, 0, &ver);
|
|
return ver & 0xFF;
|
|
}
|
|
|
|
void AK2I_CmdReadRom(u32 address, u8 *buffer, u32 length)
|
|
{
|
|
length &= ~(0x03);
|
|
u32 cmd[2] = {0xB7000000 | (address >> 8), (address & 0xff) << 24};
|
|
NTR_SendCommand(cmd, length, 2, buffer);
|
|
}
|
|
|
|
void AK2I_CmdReadFlash(u32 address, u8 *buffer, u32 length)
|
|
{
|
|
length &= ~(0x03);
|
|
u32 cmd[2] = { 0xB7000000 | (address >> 8), (address & 0xff) << 24 | 0x00100000 };
|
|
NTR_SendCommand(cmd, length, 2, buffer);
|
|
}
|
|
|
|
void AK2I_CmdSetMapTableAddress(u32 tableName, u32 tableInRamAddress)
|
|
{
|
|
tableName &= 0x0F;
|
|
u32 cmd[2] = {0xD0000000 | (tableInRamAddress >> 8),
|
|
((tableInRamAddress & 0xff) << 24) | ((u8)tableName << 16) };
|
|
|
|
NTR_SendCommand(cmd, 0, 0, NULL);
|
|
}
|
|
|
|
void AK2I_CmdSetFlash1681_81(void)
|
|
{
|
|
u32 cmd[2] = {0xD8000000 , 0x0000c606};
|
|
NTR_SendCommand(cmd, 0, 20, NULL);
|
|
}
|
|
|
|
void AK2I_CmdUnlockFlash(void)
|
|
{
|
|
u32 cmd[2] = {0xC2AA55AA, 0x55000000};
|
|
NTR_SendCommand(cmd, 0, 0, NULL);
|
|
}
|
|
|
|
void AK2I_CmdUnlockASIC(void)
|
|
{
|
|
u32 cmd[2] = { 0xC2AA5555, 0xAA000000 };
|
|
NTR_SendCommand(cmd, 4, 0, NULL);
|
|
}
|
|
|
|
void AK2i_CmdLockFlash(void) {
|
|
u32 cmd[2] = { 0xC2AAAA55, 0x55000000 };
|
|
NTR_SendCommand(cmd, 0, 0, NULL);
|
|
}
|
|
|
|
void AK2I_CmdActiveFatMap(void)
|
|
{
|
|
u32 cmd[2] = {0xC255AA55, 0xAA000000};
|
|
NTR_SendCommand(cmd, 4, 0, NULL);
|
|
}
|
|
|
|
static void waitFlashBusy()
|
|
{
|
|
u32 state = 0;
|
|
u32 cmd[2] = {0xC0000000, 0x00000000};
|
|
do {
|
|
//ioAK2Delay( 16 * 10 );
|
|
NTR_SendCommand(cmd, 4, 4, &state);
|
|
state &= 1;
|
|
} while(state != 0);
|
|
}
|
|
|
|
void AK2I_CmdEraseFlashBlock_44(u32 address)
|
|
{
|
|
u32 cmd[2] = {0xD4000000 | (address & 0x001fffff), (u32)(1<<16)};
|
|
NTR_SendCommand(cmd, 0, 0, NULL);
|
|
waitFlashBusy();
|
|
}
|
|
|
|
void AK2I_CmdEraseFlashBlock_81(u32 address)
|
|
{
|
|
u32 cmd[2] = {0xD4000000 | (address & 0x001fffff), (u32)((0x30<<24) | (0x80<<16) | (0<<8) | (0x35))};
|
|
NTR_SendCommand(cmd, 0, 20, NULL);
|
|
waitFlashBusy();
|
|
}
|
|
|
|
void AK2I_CmdWriteFlashByte_44(u32 address, u8 data)
|
|
{
|
|
u32 cmd[2] = {0xD4000000 | (address & 0x001fffff), (u32)((data<<24) | (3<<16))};
|
|
NTR_SendCommand(cmd, 0, 20, NULL);
|
|
waitFlashBusy();
|
|
}
|
|
|
|
void AK2I_CmdWriteFlash_44(u32 address, const void *data, u32 length)
|
|
{
|
|
u8 * pbuffer = (u8 *)data;
|
|
for(u32 i = 0; i < length; ++i)
|
|
{
|
|
AK2I_CmdWriteFlashByte_44(address, *(pbuffer + i));
|
|
address++;
|
|
}
|
|
}
|
|
|
|
void AK2I_CmdWriteFlashByte_81(u32 address, u8 data)
|
|
{
|
|
u32 cmd[2] = { 0xD4000000 | (address & 0x001fffff), (u32)((data<<24) | (0xa0<<16) | (0<<8) | (0x63)) };
|
|
NTR_SendCommand(cmd, 0, 20, NULL);
|
|
waitFlashBusy();
|
|
}
|
|
|
|
void AK2I_CmdWriteFlash_81(u32 address, const void *data, u32 length)
|
|
{
|
|
u8 * pbuffer = (u8 *)data;
|
|
for (u32 i = 0; i < length; ++i)
|
|
{
|
|
AK2I_CmdWriteFlashByte_81(address, *(pbuffer + i));
|
|
address++;
|
|
}
|
|
}
|
|
|
|
bool AK2I_CmdVerifyFlash(void *src, u32 dest, u32 length)
|
|
{
|
|
u8 verifyBuffer[512];
|
|
u8 * pSrc = (u8 *)src;
|
|
for (u32 i = 0; i < length; i += 512) {
|
|
u32 toRead = 512;
|
|
if (toRead > length - i)
|
|
toRead = length - i;
|
|
AK2I_CmdReadFlash(dest + i, verifyBuffer, toRead);
|
|
|
|
for (u32 j = 0; j < toRead; ++j) {
|
|
if(verifyBuffer[j] != *(pSrc + i + j))
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|