Cores/Nds/NDS.DirectBoot.cs
namespace Emulotl.Nds;
public sealed partial class NDS
{
private uint RomU16( uint offset )
{
if ( _rom == null || offset + 1 >= _rom.Length ) return 0;
return (uint)(_rom[offset] | (_rom[offset + 1] << 8));
}
private uint RomU32( uint offset )
{
if ( _rom == null || offset + 3 >= _rom.Length ) return 0;
return (uint)(_rom[offset] | (_rom[offset + 1] << 8) | (_rom[offset + 2] << 16) | (_rom[offset + 3] << 24));
}
private void DirectBoot()
{
if ( _rom == null || _rom.Length < NdsConstants.HeaderSize )
return;
uint arm9RomOff = RomU32( 0x20 );
uint arm9Entry = RomU32( 0x24 );
uint arm9Ram = RomU32( 0x28 );
uint arm9Size = RomU32( 0x2C );
uint arm7RomOff = RomU32( 0x30 );
uint arm7Entry = RomU32( 0x34 );
uint arm7Ram = RomU32( 0x38 );
uint arm7Size = RomU32( 0x3C );
MapSharedWRAM( 3 );
for ( uint i = 0; i < 0x9C; i++ )
ARM9BIOS[0x20 + i] = _rom[0xC0 + i];
for ( uint i = 0; i < 0x170; i += 4 )
ARM9Write32( 0x027FFE00 + i, RomU32( i ) );
CmdEncMode = 2;
uint cartid = ChipID;
ARM9Write32( 0x027FF800, cartid );
ARM9Write32( 0x027FF804, cartid );
ARM9Write16( 0x027FF808, (ushort)RomU16( 0x15E ) );
ARM9Write16( 0x027FF80A, (ushort)RomU16( 0x6C ) );
ARM9Write16( 0x027FF850, 0x5835 );
ARM9Write32( 0x027FFC00, cartid );
ARM9Write32( 0x027FFC04, cartid );
ARM9Write16( 0x027FFC08, (ushort)RomU16( 0x15E ) );
ARM9Write16( 0x027FFC0A, (ushort)RomU16( 0x6C ) );
ARM9Write16( 0x027FFC10, 0x5835 );
ARM9Write16( 0x027FFC30, 0xFFFF );
ARM9Write16( 0x027FFC40, 0x0001 );
uint arm9start = 0;
if ( arm9RomOff >= 0x4000 && arm9RomOff < 0x8000 )
{
ProcessSecureArea();
byte[] securearea = new byte[0x800];
DecryptSecureArea( securearea );
for ( uint i = 0; i < 0x800; i += 4 )
{
ARM9Write32( arm9Ram + i, Read32( securearea, i ) );
arm9start += 4;
}
}
for ( uint i = arm9start; i < arm9Size; i += 4 )
ARM9Write32( arm9Ram + i, RomU32( arm9RomOff + i ) );
for ( uint i = 0; i < arm7Size; i += 4 )
ARM7Write32( arm7Ram + i, RomU32( arm7RomOff + i ) );
ARM7BIOSProt = 0x1204;
SetupFirmwareDirectBoot();
ARM9.CP15Write( 0x100, 0x00052078 );
ARM9.CP15Write( 0x200, 0x00000042 );
ARM9.CP15Write( 0x201, 0x00000042 );
ARM9.CP15Write( 0x300, 0x00000002 );
ARM9.CP15Write( 0x502, 0x15111011 );
ARM9.CP15Write( 0x503, 0x05100011 );
ARM9.CP15Write( 0x600, 0x04000033 );
ARM9.CP15Write( 0x601, 0x04000033 );
ARM9.CP15Write( 0x610, 0x0200002B );
ARM9.CP15Write( 0x611, 0x0200002B );
ARM9.CP15Write( 0x620, 0x00000000 );
ARM9.CP15Write( 0x621, 0x00000000 );
ARM9.CP15Write( 0x630, 0x08000035 );
ARM9.CP15Write( 0x631, 0x08000035 );
ARM9.CP15Write( 0x640, 0x0300001B );
ARM9.CP15Write( 0x641, 0x0300001B );
ARM9.CP15Write( 0x650, 0x00000000 );
ARM9.CP15Write( 0x651, 0x00000000 );
ARM9.CP15Write( 0x660, 0xFFFF001D );
ARM9.CP15Write( 0x661, 0xFFFF001D );
ARM9.CP15Write( 0x670, 0x027FF017 );
ARM9.CP15Write( 0x671, 0x027FF017 );
ARM9.CP15Write( 0x910, 0x0300000A );
ARM9.CP15Write( 0x911, 0x00000020 );
ARM9.R[12] = arm9Entry;
ARM9.R[13] = 0x03002F7C;
ARM9.R[14] = arm9Entry;
ARM9.R_IRQ[0] = 0x03003F80;
ARM9.R_SVC[0] = 0x03003FC0;
ARM7.R[12] = arm7Entry;
ARM7.R[13] = 0x0380FD80;
ARM7.R[14] = arm7Entry;
ARM7.R_IRQ[0] = 0x0380FF80;
ARM7.R_SVC[0] = 0x0380FFC0;
ARM9.JumpTo( arm9Entry );
ARM7.JumpTo( arm7Entry );
ExMemCnt[0] = 0xE880;
ExMemCnt[1] = 0x0080;
PostFlag9 = 0x01;
PostFlag7 = 0x01;
PowerControl9 = 0x820F;
GPU.SetPowerCnt( PowerControl9 );
PowerControl7 = 0x0001;
SPU.SetPowerCnt( PowerControl7 & 0x0001 );
WriteAuxSpiCnt( 0, 0x8000, 0xFFFF );
WriteAuxSpiCnt( 1, 0x8000, 0xFFFF );
}
}