mirror of
https://github.com/ApacheThunder/nitrohaxTWL.git
synced 2025-06-19 03:55:45 -04:00
DSi/3DS Support, add second bootloader for TWL
* Original bootloader doesn't currently support TWL carts so a second one is used in those cases. (still unknown if cheat engine will work for them however) * Main code and bootloader updated to account for DSi/3DS consoles.
This commit is contained in:
parent
c5b68b31a8
commit
0872e70084
5
.gitignore
vendored
5
.gitignore
vendored
@ -1,8 +1,13 @@
|
||||
BootLoader/build
|
||||
BootLoader/load.bin
|
||||
BootLoaderTWL/build
|
||||
BootLoaderTWL/load.bin
|
||||
title/
|
||||
arm7/build
|
||||
arm9/build/
|
||||
arm9/data/
|
||||
arm9/source/version.h
|
||||
*.nds
|
||||
*.dsi
|
||||
*.app
|
||||
*.elf
|
@ -208,6 +208,23 @@ void arm7_main (void) {
|
||||
// Get ARM7 to clear RAM
|
||||
arm7_resetMemory();
|
||||
|
||||
if (REG_SNDEXTCNT != 0) {
|
||||
if ((REG_SCFG_EXT & BIT(31))) {
|
||||
*((vu32*)REG_MBK1)=0x8D898581;
|
||||
*((vu32*)REG_MBK2)=0x8C888480;
|
||||
*((vu32*)REG_MBK3)=0x9C989490;
|
||||
*((vu32*)REG_MBK4)=0x8C888480;
|
||||
*((vu32*)REG_MBK5)=0x9C989490;
|
||||
REG_MBK6=0x09403900;
|
||||
REG_MBK7=0x09803940;
|
||||
REG_MBK8=0x09C03980;
|
||||
REG_MBK9=0xFCFFFF0F;
|
||||
REG_SCFG_ROM = 0x703;
|
||||
REG_SCFG_CLK = 0x100;
|
||||
REG_SCFG_EXT = 0x12A00000;
|
||||
}
|
||||
}
|
||||
|
||||
ipcSendState(ARM7_LOADBIN);
|
||||
|
||||
// Load the NDS file
|
||||
@ -215,7 +232,7 @@ void arm7_main (void) {
|
||||
if (errorCode) {
|
||||
errorOutput(errorCode);
|
||||
}
|
||||
|
||||
|
||||
ipcSendState(ARM7_HOOKBIN);
|
||||
|
||||
// Load the cheat engine and hook it into the ARM7 binary
|
||||
@ -223,7 +240,7 @@ void arm7_main (void) {
|
||||
if (errorCode != ERR_NONE && errorCode != ERR_NOCHEAT) {
|
||||
errorOutput(errorCode);
|
||||
}
|
||||
|
||||
|
||||
ipcSendState(ARM7_BOOTBIN);
|
||||
|
||||
arm7_reset();
|
||||
|
@ -28,11 +28,8 @@
|
||||
#include "encryption.h"
|
||||
#include "common.h"
|
||||
|
||||
typedef union
|
||||
{
|
||||
char title[4];
|
||||
u32 key;
|
||||
} GameCode;
|
||||
|
||||
typedef union { char title[4]; u32 key; } GameCode;
|
||||
|
||||
static u32 portFlags = 0;
|
||||
static u32 secureAreaData[CARD_SECURE_AREA_SIZE/sizeof(u32)];
|
||||
@ -44,18 +41,12 @@ static u32 getRandomNumber(void) {
|
||||
// guaranteed to be random.
|
||||
}
|
||||
|
||||
static void decryptSecureArea (u32 gameCode, u32* secureArea)
|
||||
{
|
||||
static void decryptSecureArea (u32 gameCode, u32* secureArea) {
|
||||
int i;
|
||||
|
||||
init_keycode (gameCode, 2, 8);
|
||||
crypt_64bit_down (secureArea);
|
||||
|
||||
init_keycode (gameCode, 3, 8);
|
||||
|
||||
for (i = 0; i < 0x200; i+= 2) {
|
||||
crypt_64bit_down (secureArea + i);
|
||||
}
|
||||
for (i = 0; i < 0x200; i+= 2) { crypt_64bit_down (secureArea + i); }
|
||||
}
|
||||
|
||||
static struct {
|
||||
@ -87,14 +78,11 @@ static void initKey1Encryption (u8* cmdData) {
|
||||
}
|
||||
|
||||
// Note: cmdData must be aligned on a word boundary
|
||||
static void createEncryptedCommand (u8 command, u8* cmdData, u32 block)
|
||||
{
|
||||
static void createEncryptedCommand (u8 command, u8* cmdData, u32 block) {
|
||||
unsigned long iii, jjj;
|
||||
|
||||
if (command != CARD_CMD_SECURE_READ) {
|
||||
block = key1data.llll;
|
||||
}
|
||||
|
||||
if (command != CARD_CMD_SECURE_READ)block = key1data.llll;
|
||||
|
||||
if (command == CARD_CMD_ACTIVATE_SEC) {
|
||||
iii = key1data.mmm;
|
||||
jjj = key1data.nnn;
|
||||
@ -133,8 +121,7 @@ static void cardDelay (u16 readTimeout) {
|
||||
}
|
||||
|
||||
|
||||
int cardInit (tNDSHeader* ndsHeader, u32* chipID)
|
||||
{
|
||||
int cardInit (tNDSHeader* ndsHeader, u32* chipID) {
|
||||
u32 portFlagsKey1, portFlagsSecRead;
|
||||
bool normalChip; // As defined by GBAtek, normal chip secure area is accessed in blocks of 0x200, other chip in blocks of 0x1000
|
||||
u32* secureArea;
|
||||
@ -142,11 +129,9 @@ int cardInit (tNDSHeader* ndsHeader, u32* chipID)
|
||||
int i;
|
||||
u8 cmdData[8] __attribute__ ((aligned));
|
||||
GameCode* gameCode;
|
||||
|
||||
|
||||
// Dummy command sent after card reset
|
||||
cardParamCommand (CARD_CMD_DUMMY, 0,
|
||||
CARD_ACTIVATE | CARD_nRESET | CARD_CLK_SLOW | CARD_BLK_SIZE(1) | CARD_DELAY1(0x1FFF) | CARD_DELAY2(0x3F),
|
||||
NULL, 0);
|
||||
cardParamCommand (CARD_CMD_DUMMY, 0, CARD_ACTIVATE | CARD_nRESET | CARD_CLK_SLOW | CARD_BLK_SIZE(1) | CARD_DELAY1(0x1FFF) | CARD_DELAY2(0x3F), NULL, 0);
|
||||
|
||||
// Verify that the ndsHeader is packed correctly, now that it's no longer __packed__
|
||||
static_assert(sizeof(tNDSHeader) == 0x160, "tNDSHeader not packed properly");
|
||||
|
118
BootLoaderTWL/Makefile
Normal file
118
BootLoaderTWL/Makefile
Normal file
@ -0,0 +1,118 @@
|
||||
#---------------------------------------------------------------------------------
|
||||
.SUFFIXES:
|
||||
#---------------------------------------------------------------------------------
|
||||
ifeq ($(strip $(DEVKITARM)),)
|
||||
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM)
|
||||
endif
|
||||
|
||||
-include $(DEVKITARM)/ds_rules
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# BUILD is the directory where object files & intermediate files will be placed
|
||||
# SOURCES is a list of directories containing source code
|
||||
# INCLUDES is a list of directories containing extra header files
|
||||
#---------------------------------------------------------------------------------
|
||||
export TARGET := loadtwl
|
||||
BUILD := build
|
||||
SOURCES := source source/patches
|
||||
INCLUDES := build
|
||||
SPECS := specs
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# options for code generation
|
||||
#---------------------------------------------------------------------------------
|
||||
ARCH := -mthumb-interwork -march=armv4t -mtune=arm7tdmi
|
||||
|
||||
CFLAGS := -g -Wall -O2\
|
||||
-fomit-frame-pointer\
|
||||
-ffast-math \
|
||||
-Wall -Wextra \
|
||||
$(ARCH)
|
||||
|
||||
CFLAGS += $(INCLUDE) -DARM7 -std=gnu99
|
||||
|
||||
ASFLAGS := -g $(ARCH) $(INCLUDE)
|
||||
LDFLAGS := -nostartfiles -T$(CURDIR)/../loadtwl.ld -g $(ARCH) -Wl,-Map,$(TARGET).map
|
||||
|
||||
LIBS := -lnds7
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# list of directories containing libraries, this must be the top level containing
|
||||
# include and lib
|
||||
#---------------------------------------------------------------------------------
|
||||
LIBDIRS := $(LIBNDS)
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# no real need to edit anything past this point unless you need to add additional
|
||||
# rules for different file extensions
|
||||
#---------------------------------------------------------------------------------
|
||||
ifneq ($(BUILD),$(notdir $(CURDIR)))
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
export TARGETBIN := $(CURDIR)/$(TARGET).bin
|
||||
export ARM7ELF := $(CURDIR)/$(BUILD)/$(TARGET).arm7.elf
|
||||
export DEPSDIR := $(CURDIR)/$(BUILD)
|
||||
|
||||
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir))
|
||||
|
||||
export CC := $(PREFIX)gcc
|
||||
export CXX := $(PREFIX)g++
|
||||
export AR := $(PREFIX)ar
|
||||
export OBJCOPY := $(PREFIX)objcopy
|
||||
|
||||
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
|
||||
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
|
||||
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
|
||||
|
||||
export OFILES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
|
||||
|
||||
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
|
||||
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
|
||||
-I$(CURDIR)/$(BUILD)
|
||||
|
||||
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# use CC for linking standard C
|
||||
#---------------------------------------------------------------------------------
|
||||
export LD := $(CC)
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
.PHONY: $(BUILD) clean
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
$(BUILD):
|
||||
@[ -d $@ ] || mkdir -p $@
|
||||
@make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
clean:
|
||||
@echo clean ...
|
||||
@rm -fr $(BUILD) *.elf loadtwl.bin
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
else
|
||||
|
||||
DEPENDS := $(OFILES:.o=.d)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# main targets
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
$(TARGETBIN) : $(ARM7ELF)
|
||||
@$(OBJCOPY) -O binary $< $@
|
||||
@echo built ... $(notdir $@)
|
||||
|
||||
|
||||
$(ARM7ELF) : $(OFILES)
|
||||
@echo linking $(notdir $@)
|
||||
@$(LD) $(LDFLAGS) $(OFILES) $(LIBPATHS) $(LIBS) -o $@
|
||||
|
||||
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------------
|
||||
endif
|
||||
#---------------------------------------------------------------------------------------
|
226
BootLoaderTWL/loadtwl.ld
Normal file
226
BootLoaderTWL/loadtwl.ld
Normal file
@ -0,0 +1,226 @@
|
||||
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
|
||||
OUTPUT_ARCH(arm)
|
||||
ENTRY(_start)
|
||||
|
||||
MEMORY {
|
||||
|
||||
vram : ORIGIN = 0x06020000, LENGTH = 128K
|
||||
arm9ram : ORIGIN = 0x023FE000, LENGTH = 8K /* Used for the ARM9's functions */
|
||||
}
|
||||
|
||||
__vram_start = ORIGIN(vram);
|
||||
__vram_top = ORIGIN(vram)+ LENGTH(vram);
|
||||
__sp_irq = __vram_top - 0x60;
|
||||
__sp_svc = __sp_irq - 0x100;
|
||||
__sp_usr = __sp_svc - 0x100;
|
||||
|
||||
__irq_flags = __vram_top - 8;
|
||||
__irq_flagsaux = __vram_top - 0x40; /*__irq_flagsaux = 0x04000000 - 0x40;*/
|
||||
__irq_vector = __vram_top - 4;
|
||||
|
||||
|
||||
__arm9ram_start = ORIGIN(arm9ram);
|
||||
__arm9ram_top = ORIGIN(arm9ram)+ LENGTH(arm9ram);
|
||||
__arm9_sp_irq = __arm9ram_top - 0x60;
|
||||
__arm9_sp_svc = __arm9_sp_irq - 0x100;
|
||||
__arm9_sp_usr = __arm9_sp_svc - 0x100;
|
||||
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.init :
|
||||
{
|
||||
__text_start = . ;
|
||||
KEEP (*(.init))
|
||||
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
|
||||
} >vram = 0xff
|
||||
|
||||
.plt :
|
||||
{
|
||||
*(.plt)
|
||||
} >vram = 0xff
|
||||
|
||||
__arm9_source_start = . ;
|
||||
.arm9 :
|
||||
{
|
||||
__arm9_start = . ;
|
||||
*.arm9.*(.text*)
|
||||
*.arm9.*(.data*)
|
||||
__arm9_bss_start = ABSOLUTE(.);
|
||||
*.arm9.*(.bss*)
|
||||
__arm9_bss_end = ABSOLUTE(.);
|
||||
__arm9_end = . ;
|
||||
} >arm9ram AT>vram =0xff
|
||||
__arm9_source_end = __arm9_source_start + SIZEOF(.arm9);
|
||||
|
||||
. = __arm9_source_end;
|
||||
. = ALIGN(4);
|
||||
|
||||
.text ALIGN(4) : /* ALIGN (4): */
|
||||
{
|
||||
*(.text)
|
||||
*(.stub)
|
||||
*(.text.*)
|
||||
/* .gnu.warning sections are handled specially by elf32.em. */
|
||||
*(.gnu.warning)
|
||||
*(.gnu.linkonce.t*)
|
||||
*(.glue_7)
|
||||
*(.glue_7t)
|
||||
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
|
||||
} >vram = 0xff
|
||||
|
||||
.fini :
|
||||
{
|
||||
KEEP (*(.fini))
|
||||
} >vram =0xff
|
||||
|
||||
__text_end = . ;
|
||||
|
||||
|
||||
.rodata :
|
||||
{
|
||||
*(.rodata)
|
||||
*all.rodata*(*)
|
||||
*(.roda)
|
||||
*(.rodata.*)
|
||||
*(.gnu.linkonce.r*)
|
||||
SORT(CONSTRUCTORS)
|
||||
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
|
||||
} >vram = 0xff
|
||||
|
||||
.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >vram
|
||||
__exidx_start = .;
|
||||
.ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } >vram
|
||||
__exidx_end = .;
|
||||
|
||||
/* Ensure the __preinit_array_start label is properly aligned. We
|
||||
could instead move the label definition inside the section, but
|
||||
the linker would then create the section even if it turns out to
|
||||
be empty, which isn't pretty. */
|
||||
. = ALIGN(32 / 8);
|
||||
PROVIDE (__preinit_array_start = .);
|
||||
.preinit_array : { KEEP (*(.preinit_array)) } >vram = 0xff
|
||||
PROVIDE (__preinit_array_end = .);
|
||||
PROVIDE (__init_array_start = .);
|
||||
.init_array : { KEEP (*(.init_array)) } >vram = 0xff
|
||||
PROVIDE (__init_array_end = .);
|
||||
PROVIDE (__fini_array_start = .);
|
||||
.fini_array : { KEEP (*(.fini_array)) } >vram = 0xff
|
||||
PROVIDE (__fini_array_end = .);
|
||||
|
||||
.ctors :
|
||||
{
|
||||
/* gcc uses crtbegin.o to find the start of the constructors, so
|
||||
we make sure it is first. Because this is a wildcard, it
|
||||
doesn't matter if the user does not actually link against
|
||||
crtbegin.o; the linker won't look for a file to match a
|
||||
wildcard. The wildcard also means that it doesn't matter which
|
||||
directory crtbegin.o is in. */
|
||||
KEEP (*crtbegin.o(.ctors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*(.ctors))
|
||||
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
|
||||
} >vram = 0xff
|
||||
|
||||
.dtors :
|
||||
{
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(.dtors))
|
||||
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
|
||||
} >vram = 0xff
|
||||
|
||||
.eh_frame :
|
||||
{
|
||||
KEEP (*(.eh_frame))
|
||||
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
|
||||
} >vram = 0xff
|
||||
|
||||
.gcc_except_table :
|
||||
{
|
||||
*(.gcc_except_table)
|
||||
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
|
||||
} >vram = 0xff
|
||||
.jcr : { KEEP (*(.jcr)) } >vram = 0
|
||||
.got : { *(.got.plt) *(.got) } >vram = 0
|
||||
|
||||
|
||||
.vram ALIGN(4) :
|
||||
{
|
||||
__vram_start = ABSOLUTE(.) ;
|
||||
*(.vram)
|
||||
*vram.*(.text)
|
||||
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
|
||||
__vram_end = ABSOLUTE(.) ;
|
||||
} >vram = 0xff
|
||||
|
||||
|
||||
.data ALIGN(4) : {
|
||||
__data_start = ABSOLUTE(.);
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
*(.gnu.linkonce.d*)
|
||||
CONSTRUCTORS
|
||||
. = ALIGN(4);
|
||||
__data_end = ABSOLUTE(.) ;
|
||||
} >vram = 0xff
|
||||
|
||||
|
||||
|
||||
.bss ALIGN(4) :
|
||||
{
|
||||
__bss_start = ABSOLUTE(.);
|
||||
__bss_start__ = ABSOLUTE(.);
|
||||
*(.dynbss)
|
||||
*(.gnu.linkonce.b*)
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
|
||||
} >vram
|
||||
|
||||
__bss_end = . ;
|
||||
__bss_end__ = . ;
|
||||
|
||||
_end = . ;
|
||||
__end__ = . ;
|
||||
PROVIDE (end = _end);
|
||||
|
||||
/* Stabs debugging sections. */
|
||||
.stab 0 : { *(.stab) }
|
||||
.stabstr 0 : { *(.stabstr) }
|
||||
.stab.excl 0 : { *(.stab.excl) }
|
||||
.stab.exclstr 0 : { *(.stab.exclstr) }
|
||||
.stab.index 0 : { *(.stab.index) }
|
||||
.stab.indexstr 0 : { *(.stab.indexstr) }
|
||||
.comment 0 : { *(.comment) }
|
||||
/* DWARF debug sections.
|
||||
Symbols in the DWARF debugging sections are relative to the beginning
|
||||
of the section so we begin them at 0. */
|
||||
/* DWARF 1 */
|
||||
.debug 0 : { *(.debug) }
|
||||
.line 0 : { *(.line) }
|
||||
/* GNU DWARF 1 extensions */
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||
/* DWARF 1.1 and DWARF 2 */
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
/* DWARF 2 */
|
||||
.debug_info 0 : { *(.debug_info) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_line 0 : { *(.debug_line) }
|
||||
.debug_frame 0 : { *(.debug_frame) }
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
/* SGI/MIPS DWARF 2 extensions */
|
||||
.debug_weaknames 0 : { *(.debug_weaknames) }
|
||||
.debug_funcnames 0 : { *(.debug_funcnames) }
|
||||
.debug_typenames 0 : { *(.debug_typenames) }
|
||||
.debug_varnames 0 : { *(.debug_varnames) }
|
||||
.stack 0x80000 : { _stack = .; *(.stack) }
|
||||
/* These must appear regardless of . */
|
||||
}
|
||||
|
43
BootLoaderTWL/source/bios7.s
Normal file
43
BootLoaderTWL/source/bios7.s
Normal file
@ -0,0 +1,43 @@
|
||||
/*---------------------------------------------------------------------------------
|
||||
|
||||
Copyright (C) 2009
|
||||
Dave Murphy (WinterMute)
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any
|
||||
purpose, including commercial applications, and to alter it and
|
||||
redistribute it freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you
|
||||
must not claim that you wrote the original software. If you use
|
||||
this software in a product, an acknowledgment in the product
|
||||
documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and
|
||||
must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
|
||||
---------------------------------------------------------------------------------*/
|
||||
|
||||
.text
|
||||
.align 4
|
||||
|
||||
.arm
|
||||
@---------------------------------------------------------------------------------
|
||||
.global swiSoftResetarm7
|
||||
.type swiSoftResetarm7 STT_FUNC
|
||||
@---------------------------------------------------------------------------------
|
||||
swiSoftResetarm7:
|
||||
@---------------------------------------------------------------------------------
|
||||
REG_IME = 0;
|
||||
|
||||
ldr r0,=0x2FFFE34
|
||||
|
||||
|
||||
ldr r0,[r0]
|
||||
bx r0
|
||||
|
||||
.pool
|
56
BootLoaderTWL/source/bios9.s
Normal file
56
BootLoaderTWL/source/bios9.s
Normal file
@ -0,0 +1,56 @@
|
||||
/*---------------------------------------------------------------------------------
|
||||
|
||||
Copyright (C) 2009
|
||||
Dave Murphy (WinterMute)
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any
|
||||
purpose, including commercial applications, and to alter it and
|
||||
redistribute it freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you
|
||||
must not claim that you wrote the original software. If you use
|
||||
this software in a product, an acknowledgment in the product
|
||||
documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and
|
||||
must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
|
||||
---------------------------------------------------------------------------------*/
|
||||
|
||||
.text
|
||||
.align 4
|
||||
|
||||
.arm
|
||||
@---------------------------------------------------------------------------------
|
||||
.global swiSoftResetarm9
|
||||
.type swiSoftResetarm9 STT_FUNC
|
||||
@---------------------------------------------------------------------------------
|
||||
swiSoftResetarm9:
|
||||
@---------------------------------------------------------------------------------
|
||||
REG_IME = 0;
|
||||
|
||||
|
||||
.arch armv5te
|
||||
.cpu arm946e-s
|
||||
ldr r1, =0x00002078 @ disable TCM and protection unit
|
||||
mcr p15, 0, r1, c1, c0
|
||||
@ Disable cache
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c7, c5, 0 @ Instruction cache
|
||||
mcr p15, 0, r0, c7, c6, 0 @ Data cache
|
||||
|
||||
@ Wait for write buffer to empty
|
||||
mcr p15, 0, r0, c7, c10, 4
|
||||
|
||||
ldr r0,=0x2FFFE24
|
||||
|
||||
|
||||
ldr r0,[r0]
|
||||
bx r0
|
||||
|
||||
.pool
|
167
BootLoaderTWL/source/card.h
Normal file
167
BootLoaderTWL/source/card.h
Normal file
@ -0,0 +1,167 @@
|
||||
/*---------------------------------------------------------------------------------
|
||||
|
||||
Copyright (C) 2005
|
||||
Michael Noland (joat)
|
||||
Jason Rogers (dovoto)
|
||||
Dave Murphy (WinterMute)
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any
|
||||
purpose, including commercial applications, and to alter it and
|
||||
redistribute it freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you
|
||||
must not claim that you wrote the original software. If you use
|
||||
this software in a product, an acknowledgment in the product
|
||||
documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and
|
||||
must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
|
||||
---------------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef NDS_CARD_INCLUDE
|
||||
#define NDS_CARD_INCLUDE
|
||||
|
||||
|
||||
#include "ndstypes.h"
|
||||
|
||||
// Card bus
|
||||
#define REG_CARD_DATA_RD (*(vu32*)0x04100010)
|
||||
|
||||
#define REG_AUXSPICNT (*(vu16*)0x040001A0)
|
||||
#define REG_AUXSPICNTH (*(vu8*)0x040001A1)
|
||||
#define REG_AUXSPIDATA (*(vu8*)0x040001A2)
|
||||
#define REG_ROMCTRL (*(vu32*)0x040001A4)
|
||||
|
||||
#define REG_CARD_COMMAND ((vu8*)0x040001A8)
|
||||
|
||||
#define REG_CARD_1B0 (*(vu32*)0x040001B0)
|
||||
#define REG_CARD_1B4 (*(vu32*)0x040001B4)
|
||||
#define REG_CARD_1B8 (*(vu16*)0x040001B8)
|
||||
#define REG_CARD_1BA (*(vu16*)0x040001BA)
|
||||
|
||||
#define CARD_CR1_ENABLE 0x80 // in byte 1, i.e. 0x8000
|
||||
#define CARD_CR1_IRQ 0x40 // in byte 1, i.e. 0x4000
|
||||
|
||||
// SPI EEPROM COMMANDS
|
||||
#define SPI_EEPROM_WRSR 0x01
|
||||
#define SPI_EEPROM_PP 0x02 // Page Program
|
||||
#define SPI_EEPROM_READ 0x03
|
||||
#define SPI_EEPROM_WRDI 0x04 // Write disable
|
||||
#define SPI_EEPROM_RDSR 0x05 // Read status register
|
||||
#define SPI_EEPROM_WREN 0x06 // Write enable
|
||||
#define SPI_EEPROM_PW 0x0a // Page Write
|
||||
#define SPI_EEPROM_FAST 0x0b // Fast Read
|
||||
#define SPI_EEPROM_RDID 0x9f
|
||||
#define SPI_EEPROM_RDP 0xab // Release from deep power down
|
||||
#define SPI_EEPROM_DPD 0xb9 // Deep power down
|
||||
|
||||
#define CARD_ACTIVATE (1<<31) // when writing, get the ball rolling
|
||||
#define CARD_WR (1<<30) // Card write enable
|
||||
#define CARD_nRESET (1<<29) // value on the /reset pin (1 = high out, not a reset state, 0 = low out = in reset)
|
||||
#define CARD_SEC_LARGE (1<<28) // Use "other" secure area mode, which tranfers blocks of 0x1000 bytes at a time
|
||||
#define CARD_CLK_SLOW (1<<27) // Transfer clock rate (0 = 6.7MHz, 1 = 4.2MHz)
|
||||
#define CARD_BLK_SIZE(n) (((n)&0x7)<<24) // Transfer block size, (0 = None, 1..6 = (0x100 << n) bytes, 7 = 4 bytes)
|
||||
#define CARD_SEC_CMD (1<<22) // The command transfer will be hardware encrypted (KEY2)
|
||||
#define CARD_DELAY2(n) (((n)&0x3F)<<16) // Transfer delay length part 2
|
||||
#define CARD_SEC_SEED (1<<15) // Apply encryption (KEY2) seed to hardware registers
|
||||
#define CARD_SEC_EN (1<<14) // Security enable
|
||||
#define CARD_SEC_DAT (1<<13) // The data transfer will be hardware encrypted (KEY2)
|
||||
#define CARD_DELAY1(n) ((n)&0x1FFF) // Transfer delay length part 1
|
||||
|
||||
// 3 bits in b10..b8 indicate something
|
||||
// read bits
|
||||
#define CARD_BUSY (1<<31) // when reading, still expecting incomming data?
|
||||
#define CARD_DATA_READY (1<<23) // when reading, CARD_DATA_RD or CARD_DATA has another word of data and is good to go
|
||||
|
||||
// Card commands
|
||||
#define CARD_CMD_DUMMY 0x9F
|
||||
#define CARD_CMD_HEADER_READ 0x00
|
||||
#define CARD_CMD_HEADER_CHIPID 0x90
|
||||
#define CARD_CMD_ACTIVATE_BF 0x3C // Go into blowfish (KEY1) encryption mode
|
||||
#define CARD_CMD_ACTIVATE_SEC 0x40 // Go into hardware (KEY2) encryption mode
|
||||
#define CARD_CMD_SECURE_CHIPID 0x10
|
||||
#define CARD_CMD_SECURE_READ 0x20
|
||||
#define CARD_CMD_DISABLE_SEC 0x60 // Leave hardware (KEY2) encryption mode
|
||||
#define CARD_CMD_DATA_MODE 0xA0
|
||||
#define CARD_CMD_DATA_READ 0xB7
|
||||
#define CARD_CMD_DATA_CHIPID 0xB8
|
||||
|
||||
//REG_AUXSPICNT
|
||||
#define CARD_ENABLE (1<<15)
|
||||
#define CARD_SPI_ENABLE (1<<13)
|
||||
#define CARD_SPI_BUSY (1<<7)
|
||||
#define CARD_SPI_HOLD (1<<6)
|
||||
|
||||
#define CARD_SPICNTH_ENABLE (1<<7) // in byte 1, i.e. 0x8000
|
||||
#define CARD_SPICNTH_IRQ (1<<6) // in byte 1, i.e. 0x4000
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
void enableSlot1();
|
||||
void disableSlot1();
|
||||
|
||||
void cardWriteCommand(const u8 *command);
|
||||
void cardPolledTransfer(u32 flags, u32 *destination, u32 length, const u8 *command);
|
||||
void cardStartTransfer(const u8 *command, u32 *destination, int channel, u32 flags);
|
||||
uint32 cardWriteAndRead(const u8 *command, u32 flags);
|
||||
void cardParamCommand (u8 command, u32 parameter, u32 flags, u32 *destination, u32 length);
|
||||
|
||||
// These commands require the cart to not be initialized yet, which may mean the user
|
||||
// needs to eject and reinsert the cart or they will return random data.
|
||||
void cardReadHeader(u8 *header);
|
||||
u32 cardReadID(u32 flags);
|
||||
void cardReset();
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
static inline void eepromWaitBusy() {
|
||||
//---------------------------------------------------------------------------------
|
||||
while (REG_AUXSPICNT & CARD_SPI_BUSY);
|
||||
}
|
||||
|
||||
// Reads from the EEPROM
|
||||
void cardReadEeprom(u32 address, u8 *data, u32 length, u32 addrtype);
|
||||
|
||||
// Writes to the EEPROM. TYPE 3 EEPROM must be erased first (I think?)
|
||||
void cardWriteEeprom(u32 address, u8 *data, u32 length, u32 addrtype);
|
||||
|
||||
// Returns the ID of the EEPROM chip? Doesn't work well, most chips give ff,ff
|
||||
// i = 0 or 1
|
||||
u32 cardEepromReadID();
|
||||
|
||||
// Sends a command to the EEPROM
|
||||
u8 cardEepromCommand(u8 command);
|
||||
|
||||
/*
|
||||
* -1:no card or no EEPROM
|
||||
* 0:unknown PassMe?
|
||||
* 1:TYPE 1 4Kbit(512Byte) EEPROM
|
||||
* 2:TYPE 2 64Kbit(8KByte)or 512kbit(64Kbyte) EEPROM
|
||||
* 3:TYPE 3 2Mbit(256KByte) FLASH MEMORY (some rare 4Mbit and 8Mbit chips also)
|
||||
*/
|
||||
int cardEepromGetType(void);
|
||||
|
||||
// Returns the size in bytes of EEPROM
|
||||
u32 cardEepromGetSize();
|
||||
|
||||
// Erases the entire chip. TYPE 3 chips MUST be erased before writing to them. (I think?)
|
||||
void cardEepromChipErase(void);
|
||||
|
||||
// Erases a single sector of the TYPE 3 chip
|
||||
void cardEepromSectorErase(u32 address);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
148
BootLoaderTWL/source/cheat.c
Normal file
148
BootLoaderTWL/source/cheat.c
Normal file
@ -0,0 +1,148 @@
|
||||
/*
|
||||
NitroHax -- Cheat tool for the Nintendo DS
|
||||
Copyright (C) 2008 Michael "Chishm" Chisholm
|
||||
|
||||
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 "cheat.h"
|
||||
#include "common.h"
|
||||
|
||||
extern unsigned long cheat_engine_size;
|
||||
extern unsigned long intr_orig_return_offset;
|
||||
|
||||
extern const u8 cheat_engine_start[];
|
||||
#define CHEAT_CODE_END 0xCF000000
|
||||
#define CHEAT_ENGINE_RELOCATE 0xCF000001
|
||||
#define CHEAT_ENGINE_HOOK 0xCF000002
|
||||
|
||||
static const u32 handlerStartSig[5] = {
|
||||
0xe92d4000, // push {lr}
|
||||
0xe3a0c301, // mov ip, #0x4000000
|
||||
0xe28cce21, // add ip, ip, #0x210
|
||||
0xe51c1008, // ldr r1, [ip, #-8]
|
||||
0xe3510000 // cmp r1, #0
|
||||
};
|
||||
|
||||
static const u32 handlerEndSig[4] = {
|
||||
0xe59f1008, // ldr r1, [pc, #8] (IRQ Vector table address)
|
||||
0xe7910100, // ldr r0, [r1, r0, lsl #2]
|
||||
0xe59fe004, // ldr lr, [pc, #4] (IRQ return address)
|
||||
0xe12fff10 // bx r0
|
||||
};
|
||||
|
||||
static const int MAX_HANDLER_SIZE = 50;
|
||||
|
||||
static u32* hookInterruptHandler (u32* addr, size_t size) {
|
||||
u32* end = addr + size/sizeof(u32);
|
||||
int i;
|
||||
|
||||
// Find the start of the handler
|
||||
while (addr < end) {
|
||||
if ((addr[0] == handlerStartSig[0]) &&
|
||||
(addr[1] == handlerStartSig[1]) &&
|
||||
(addr[2] == handlerStartSig[2]) &&
|
||||
(addr[3] == handlerStartSig[3]) &&
|
||||
(addr[4] == handlerStartSig[4]))
|
||||
{
|
||||
break;
|
||||
}
|
||||
addr++;
|
||||
}
|
||||
|
||||
if (addr >= end) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Find the end of the handler
|
||||
for (i = 0; i < MAX_HANDLER_SIZE; i++) {
|
||||
if ((addr[i+0] == handlerEndSig[0]) &&
|
||||
(addr[i+1] == handlerEndSig[1]) &&
|
||||
(addr[i+2] == handlerEndSig[2]) &&
|
||||
(addr[i+3] == handlerEndSig[3]))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i >= MAX_HANDLER_SIZE) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Now find the IRQ vector table
|
||||
// Make addr point to the vector table address pointer within the IRQ handler
|
||||
addr = addr + i + sizeof(handlerEndSig)/sizeof(handlerEndSig[0]);
|
||||
|
||||
// Use relative and absolute addresses to find the location of the table in RAM
|
||||
u32 tableAddr = addr[0];
|
||||
u32 returnAddr = addr[1];
|
||||
u32* actualReturnAddr = addr + 2;
|
||||
u32* actualTableAddr = actualReturnAddr + (tableAddr - returnAddr)/sizeof(u32);
|
||||
|
||||
// The first entry in the table is for the Vblank handler, which is what we want
|
||||
return actualTableAddr;
|
||||
}
|
||||
|
||||
int arm7_hookGame (const tNDSHeader* ndsHeader, const u32* cheatData, u32* cheatEngineLocation) {
|
||||
u32 oldReturn;
|
||||
u32 cheatWord1, cheatWord2;
|
||||
u32* cheatDest;
|
||||
u32* hookLocation = NULL;
|
||||
|
||||
if (cheatData[0] == CHEAT_CODE_END) {
|
||||
return ERR_NOCHEAT;
|
||||
}
|
||||
|
||||
if (cheatData[0] == CHEAT_ENGINE_RELOCATE) {
|
||||
cheatWord1 = *cheatData++;
|
||||
cheatWord2 = *cheatData++;
|
||||
cheatEngineLocation = (u32*)cheatWord2;
|
||||
}
|
||||
|
||||
if (cheatData[0] == CHEAT_ENGINE_HOOK) {
|
||||
cheatWord1 = *cheatData++;
|
||||
cheatWord2 = *cheatData++;
|
||||
hookLocation = (u32*)cheatWord2;
|
||||
}
|
||||
|
||||
if (!hookLocation) {
|
||||
hookLocation = hookInterruptHandler ((u32*)ndsHeader->arm7destination, ndsHeader->arm7binarySize);
|
||||
}
|
||||
|
||||
if (!hookLocation) {
|
||||
return ERR_HOOK;
|
||||
}
|
||||
|
||||
oldReturn = *hookLocation;
|
||||
|
||||
*hookLocation = (u32)cheatEngineLocation;
|
||||
|
||||
copyLoop (cheatEngineLocation, (u32*)cheat_engine_start, cheat_engine_size);
|
||||
|
||||
cheatEngineLocation [intr_orig_return_offset/sizeof(u32)] = oldReturn;
|
||||
|
||||
cheatDest = cheatEngineLocation + (cheat_engine_size/sizeof(u32));
|
||||
|
||||
// Copy cheat data across
|
||||
do {
|
||||
cheatWord1 = *cheatData++;
|
||||
cheatWord2 = *cheatData++;
|
||||
*cheatDest++ = cheatWord1;
|
||||
*cheatDest++ = cheatWord2;
|
||||
} while (cheatWord1 != CHEAT_CODE_END);
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
|
27
BootLoaderTWL/source/cheat.h
Normal file
27
BootLoaderTWL/source/cheat.h
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
NitroHax -- Cheat tool for the Nintendo DS
|
||||
Copyright (C) 2008 Michael "Chishm" Chisholm
|
||||
|
||||
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 <nds/memory.h>
|
||||
#include <nds/ndstypes.h>
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
arm7_hookGame
|
||||
Adds a hook in the game's ARM7 binary to our own code
|
||||
-------------------------------------------------------------------------*/
|
||||
int arm7_hookGame (const tNDSHeader* ndsHeader, const u32* cheatData, u32* cheatEngineLocation);
|
||||
|
485
BootLoaderTWL/source/cheat_engine.s
Normal file
485
BootLoaderTWL/source/cheat_engine.s
Normal file
@ -0,0 +1,485 @@
|
||||
@ NitroHax -- Cheat tool for the Nintendo DS
|
||||
@ Copyright (C) 2008 Michael "Chishm" Chisholm
|
||||
@
|
||||
@ 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 <nds/asminc.h>
|
||||
.arm
|
||||
|
||||
.global cheat_engine_start
|
||||
.global cheat_engine_end
|
||||
.global intr_orig_return_offset
|
||||
.global cheat_engine_size
|
||||
|
||||
|
||||
cheat_engine_size:
|
||||
.word cheat_engine_end - cheat_engine_start
|
||||
|
||||
intr_orig_return_offset:
|
||||
.word intr_orig_return - cheat_engine_start
|
||||
|
||||
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
|
||||
BEGIN_ASM_FUNC cheat_engine_start
|
||||
@ Hook the return address, then go back to the original function
|
||||
stmdb sp!, {lr}
|
||||
adr lr, code_handler_start
|
||||
ldr r0, intr_orig_return
|
||||
bx r0
|
||||
|
||||
code_handler_start:
|
||||
stmdb sp!, {r0-r12}
|
||||
mov r9, #0x00000000 @ offset register
|
||||
mov r8, #0x00000000 @ execution status. bit0: 1 = no exec, 0 = exec. allows nested ifs 32 deep
|
||||
mov r7, #0x00000000 @ Dx loop start
|
||||
mov r6, #0x00000000 @ Dx repeat ammount
|
||||
mov r5, #0x00000000 @ DX data
|
||||
mov r4, #0x00000000 @ Dx execution status
|
||||
|
||||
@ increment counter
|
||||
ldrh r0, counter_value
|
||||
add r0, r0, #1
|
||||
strh r0, counter_value
|
||||
|
||||
@ r0-r3 are generic registers for the code processor to use
|
||||
@ 0xCF000000 0x00000000 indicates the end of the code list
|
||||
@ r12 points to the next code to load
|
||||
|
||||
adr r12, cheat_data
|
||||
|
||||
main_loop:
|
||||
ldmia r12!, {r10, r11} @ load a code
|
||||
cmp r10, #0xCF000000
|
||||
beq exit
|
||||
|
||||
mov r0, r10, lsr #28
|
||||
cmp r0, #0xE
|
||||
beq patch_code
|
||||
cmp r0, #0xD
|
||||
beq dx_codes
|
||||
cmp r0, #0xC
|
||||
beq type_c
|
||||
|
||||
@ check execution status
|
||||
tst r8, #0x00000001
|
||||
bne main_loop
|
||||
|
||||
@ check code group
|
||||
cmp r0, #0x3
|
||||
blt raw_write
|
||||
cmp r0, #0x6
|
||||
ble if_32bit
|
||||
cmp r0, #0xB
|
||||
blt if_16bit_mask
|
||||
beq offset_load
|
||||
b mem_copy_code
|
||||
|
||||
|
||||
counter_value:
|
||||
.word 0x00000000
|
||||
|
||||
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@ type 0-2
|
||||
|
||||
raw_write:
|
||||
cmp r0, #0x1
|
||||
bic r10, r10, #0xf0000000
|
||||
strlt r11, [r10, r9] @ type 0
|
||||
streqh r11, [r10, r9] @ type 1
|
||||
strgtb r11, [r10, r9] @ type 2
|
||||
b main_loop
|
||||
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@ type 3-6
|
||||
@ r0 still contains the code type
|
||||
|
||||
if_32bit:
|
||||
bic r1, r10, #0xf0000001
|
||||
tst r10, #0x00000001
|
||||
addne r1, r1, r9 @ add offset to the address if the lowest bit is set
|
||||
cmp r1, #0x00000000
|
||||
moveq r1, r9 @ if address is 0, set address to offset
|
||||
ldr r1, [r1] @ load word from [0XXXXXXX]
|
||||
mov r8, r8, lsl #1 @ push execution status
|
||||
cmp r0, #0x3
|
||||
beq if_32bit_bhi
|
||||
cmp r0, #0x5
|
||||
blt if_32bit_bcc
|
||||
beq if_32bit_beq
|
||||
@ fall through to if_32bit_bne
|
||||
|
||||
@ type 6
|
||||
if_32bit_bne:
|
||||
cmp r11, r1
|
||||
orreq r8, r8, #0x00000001
|
||||
b main_loop
|
||||
|
||||
@ type 3
|
||||
if_32bit_bhi:
|
||||
cmp r11, r1
|
||||
orrls r8, r8, #0x00000001
|
||||
b main_loop
|
||||
|
||||
@ type 4
|
||||
if_32bit_bcc:
|
||||
cmp r11, r1
|
||||
orrcs r8, r8, #0x00000001
|
||||
b main_loop
|
||||
|
||||
@ type 5
|
||||
if_32bit_beq:
|
||||
cmp r11, r1
|
||||
orrne r8, r8, #0x00000001
|
||||
b main_loop
|
||||
|
||||
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@ type 7-A
|
||||
@ r0 still contains the code type
|
||||
|
||||
if_16bit_mask:
|
||||
bic r1, r10, #0xf0000001
|
||||
tst r10, #0x00000001
|
||||
addne r1, r1, r9 @ add offset to the address if the lowest bit is set
|
||||
cmp r1, #0x00000000
|
||||
moveq r1, r9 @ if address is 0, set address to offset
|
||||
ldrh r1, [r1] @ load halfword from [0XXXXXXX]
|
||||
mov r2, r11, lsr #16 @ bit mask
|
||||
mov r3, r11, lsl #16 @ compare data
|
||||
mov r3, r3, lsr #16
|
||||
bic r1, r1, r2 @ clear any bit that is set in the mask
|
||||
|
||||
mov r8, r8, lsl #1 @ push execution status
|
||||
cmp r0, #0x7
|
||||
beq if_16bit_bhi
|
||||
cmp r0, #0x9
|
||||
blt if_16bit_bcc
|
||||
beq if_16bit_beq
|
||||
@ fall through to if_16bit_bne
|
||||
|
||||
@ type A
|
||||
if_16bit_bne:
|
||||
cmp r3, r1
|
||||
orreq r8, r8, #0x00000001
|
||||
b main_loop
|
||||
|
||||
@ type 7
|
||||
if_16bit_bhi:
|
||||
cmp r3, r1
|
||||
orrls r8, r8, #0x00000001
|
||||
b main_loop
|
||||
|
||||
@ type 8
|
||||
if_16bit_bcc:
|
||||
cmp r3, r1
|
||||
orrcs r8, r8, #0x00000001
|
||||
b main_loop
|
||||
|
||||
@ type 9
|
||||
if_16bit_beq:
|
||||
cmp r3, r1
|
||||
orrne r8, r8, #0x00000001
|
||||
b main_loop
|
||||
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@ type B
|
||||
|
||||
offset_load:
|
||||
bic r10, r10, #0xf0000000
|
||||
ldr r9, [r10, r9]
|
||||
b main_loop
|
||||
|
||||
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@ type C
|
||||
|
||||
type_c:
|
||||
mov r0, r10, lsr #24
|
||||
cmp r0, #0xC1
|
||||
beq exec_remote_function
|
||||
cmp r0, #0xC2
|
||||
beq exec_custom_function
|
||||
|
||||
tst r8, #0x00000001 @ make sure execution is enabled
|
||||
bne main_loop
|
||||
|
||||
cmp r0, #0xC0
|
||||
beq loop_start
|
||||
cmp r0, #0xC5
|
||||
beq execution_counter @ type C5
|
||||
|
||||
offset_data_store: @ type C4
|
||||
sublt r9, r12, #0x08 @ Offset = Two words back from current code pointer (ie, word at C4000000 code)
|
||||
|
||||
save_offset: @ type C6
|
||||
strgt r9, [r11] @ Save offset to [XXXXXXXX] in C6000000 XXXXXXXX
|
||||
b main_loop
|
||||
|
||||
loop_start:
|
||||
mov r4, r8 @ execution status
|
||||
mov r6, r11 @ loop repeat amount
|
||||
mov r7, r12 @ loop start
|
||||
b main_loop
|
||||
|
||||
exec_remote_function:
|
||||
ldmia r12, {r0, r1, r2, r3} @ load arguments
|
||||
and r10, r10, #0x00000007
|
||||
add r12, r12, r10 @ move code pointer to where it should be
|
||||
tst r8, #0x00000001
|
||||
bne align_cheat_list @ execution disabled
|
||||
stmdb sp!, {r12}
|
||||
adr lr, exec_function_return
|
||||
bx r11
|
||||
|
||||
exec_custom_function:
|
||||
and r0, r10, #0x00000001 @ thumb mode?
|
||||
add r0, r0, r12 @ custom function location
|
||||
add r12, r12, r11
|
||||
tst r8, #0x00000001
|
||||
bne align_cheat_list @ execution disabled
|
||||
stmdb sp!, {r12}
|
||||
adr lr, exec_function_return
|
||||
bx r0
|
||||
|
||||
exec_function_return:
|
||||
ldmia sp!, {r12}
|
||||
b align_cheat_list
|
||||
|
||||
|
||||
execution_counter:
|
||||
ldr r0, counter_value @ we only need the low 16 bits but counter_value is out of immediate range for ldrh
|
||||
mov r1, r11, lsl #16
|
||||
and r0, r0, r1, lsr #16 @ mask off counter
|
||||
mov r8, r8, lsl #1 @ push execution status
|
||||
cmp r0, r11, lsr #16 @ Compare against compare value component of code
|
||||
orrne r8, r8, #0x00000001 @ set execution to false
|
||||
b main_loop
|
||||
|
||||
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@ type D
|
||||
|
||||
dx_codes:
|
||||
mov r0, r10, lsr #24
|
||||
cmp r0, #0xD3
|
||||
bcs dx_conditional_exec
|
||||
|
||||
cmp r0, #0xD1
|
||||
bgt end_loop_clear
|
||||
beq end_loop_no_clear
|
||||
@ fall through to end_if
|
||||
|
||||
@ type D0
|
||||
end_if:
|
||||
mov r8, r8, lsr #1 @ pop exec status
|
||||
b main_loop
|
||||
|
||||
@ type D2
|
||||
end_loop_clear:
|
||||
mov r8, r4 @ restore the old execution status
|
||||
cmp r6, #0 @ end of a loop?
|
||||
@ no
|
||||
subgt r6, r6, #1
|
||||
movgt r12, r7 @ load the Dx loop start
|
||||
bgt main_loop
|
||||
@ yes
|
||||
mov r5, #0 @ clear Dx data register
|
||||
mov r8, #0 @ clear execution status
|
||||
mov r9, #0 @ clear offset
|
||||
b main_loop
|
||||
|
||||
@ type D1
|
||||
end_loop_no_clear:
|
||||
mov r8, r4 @ restore the old execution status
|
||||
cmp r6, #0 @ end of a loop?
|
||||
@ no
|
||||
subgt r6, r6, #1
|
||||
movgt r12, r7 @ load the Dx loop start
|
||||
@ yes
|
||||
b main_loop
|
||||
|
||||
dx_conditional_exec:
|
||||
tst r8, #0x00000001
|
||||
bne main_loop
|
||||
|
||||
cmp r0, #0xD6
|
||||
bcs dx_write
|
||||
|
||||
cmp r0, #0xD4
|
||||
@ type D3 - Offset Set
|
||||
movlt r9, r11
|
||||
beq dx_data_op
|
||||
@ type D5 - Dx Data set
|
||||
movgt r5, r11
|
||||
b main_loop
|
||||
|
||||
dx_write:
|
||||
cmp r0, #0xD9
|
||||
bcs dx_load
|
||||
|
||||
cmp r0, #0xD7
|
||||
@ type D6 - Dx Data write 32 bits
|
||||
strlt r5, [r11, r9]
|
||||
addlt r9, r9, #4
|
||||
@ type D7 - Dx Data write 16 bits
|
||||
streqh r5, [r11, r9]
|
||||
addeq r9, r9, #2
|
||||
@ type D8 - Dx Data write 8 bits
|
||||
strgtb r5, [r11, r9]
|
||||
addgt r9, r9, #1
|
||||
b main_loop
|
||||
|
||||
dx_load:
|
||||
cmp r0, #0xDC
|
||||
bcs dx_offset_add_addr
|
||||
|
||||
cmp r0, #0xDA
|
||||
@ type D9 - Dx Data load 32 bits
|
||||
ldrlt r5, [r11, r9]
|
||||
@ type DA - Dx Data load 16 bits
|
||||
ldreqh r5, [r11, r9]
|
||||
@ type DB - Dx Data load 8 bits
|
||||
ldrgtb r5, [r11, r9]
|
||||
b main_loop
|
||||
|
||||
@ type DC
|
||||
dx_offset_add_addr:
|
||||
add r9, r9, r11
|
||||
b main_loop
|
||||
|
||||
@ type D4
|
||||
dx_data_op:
|
||||
and r0, r10, #0x000000ff
|
||||
cmp r0, #0x01
|
||||
@ type D4000000 - add, use negative values for sub
|
||||
addlt r5, r5, r11
|
||||
@ type D4000001 - or
|
||||
orreq r5, r5, r11
|
||||
ble main_loop
|
||||
|
||||
cmp r0, #0x03
|
||||
@ type D4000002 - and
|
||||
andlt r5, r5, r11
|
||||
@ type D4000003 - xor
|
||||
eoreq r5, r5, r11
|
||||
ble main_loop
|
||||
|
||||
cmp r0, #0x05
|
||||
@ type D4000004 - lsl
|
||||
movlt r5, r5, lsl r11
|
||||
@ type D4000005 - lsr
|
||||
moveq r5, r5, lsr r11
|
||||
ble main_loop
|
||||
|
||||
cmp r0, #0x07
|
||||
@ type D4000006 - ror
|
||||
movlt r5, r5, ror r11
|
||||
@ type D4000007 - asr
|
||||
moveq r5, r5, asr r11
|
||||
ble main_loop
|
||||
|
||||
cmp r0, #0x09
|
||||
@ type D4000008 - mul
|
||||
mullt r5, r11, r5
|
||||
|
||||
b main_loop
|
||||
|
||||
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@ type E
|
||||
|
||||
patch_code:
|
||||
@ check execution status
|
||||
tst r8, #0x00000001
|
||||
addne r12, r12, r11 @ skip the data section
|
||||
bne align_cheat_list
|
||||
|
||||
bic r10, r10, #0xf0000000 @ destination address
|
||||
add r10, r10, r9 @ add offset to dest
|
||||
@ r11 is bytes remaining
|
||||
@ r12 is source
|
||||
|
||||
patch_code_word_loop:
|
||||
cmp r11, #4
|
||||
blt patch_code_byte_loop
|
||||
ldr r1, [r12], #4
|
||||
str r1, [r10], #4
|
||||
sub r11, r11, #4
|
||||
b patch_code_word_loop
|
||||
|
||||
patch_code_byte_loop:
|
||||
cmp r11, #1
|
||||
blt align_cheat_list @ patch_code_end
|
||||
ldrb r1, [r12], #1
|
||||
strb r1, [r10], #1
|
||||
sub r11, r11, #1
|
||||
b patch_code_byte_loop
|
||||
|
||||
align_cheat_list:
|
||||
add r12, r12, #0x7
|
||||
bic r12, r12, #0x00000007 @ round up to nearest multiple of 8
|
||||
b main_loop
|
||||
|
||||
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@ type F
|
||||
|
||||
mem_copy_code:
|
||||
bic r10, r10, #0xf0000000 @ destination address
|
||||
@ r11 is bytes remaining
|
||||
mov r2, r9 @ source address
|
||||
|
||||
mem_copy_code_word_loop:
|
||||
cmp r11, #4
|
||||
blt mem_copy_code_byte_loop
|
||||
ldr r1, [r2], #4
|
||||
str r1, [r10], #4
|
||||
sub r11, r11, #4
|
||||
b mem_copy_code_word_loop
|
||||
|
||||
mem_copy_code_byte_loop:
|
||||
cmp r11, #1
|
||||
blt main_loop @ mem_copy_code_end
|
||||
ldrb r1, [r2], #1
|
||||
strb r1, [r10], #1
|
||||
sub r11, r11, #1
|
||||
b mem_copy_code_byte_loop
|
||||
|
||||
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
|
||||
exit:
|
||||
ldmia sp!, {r0-r12}
|
||||
ldmia sp!, {lr}
|
||||
bx lr
|
||||
|
||||
intr_orig_return:
|
||||
.word 0x00000000
|
||||
|
||||
.pool
|
||||
|
||||
cheat_data:
|
||||
|
||||
cheat_engine_end:
|
||||
|
||||
@ Cheat data goes here
|
||||
|
||||
.word 0xCF000000, 0x00000000
|
||||
.word 0x00000000, 0x00000000
|
||||
.word 0x00000000, 0x00000000
|
||||
.word 0x00000000, 0x00000000
|
||||
|
||||
|
68
BootLoaderTWL/source/clear_cache.arm9.s
Normal file
68
BootLoaderTWL/source/clear_cache.arm9.s
Normal file
@ -0,0 +1,68 @@
|
||||
@ NitroHax -- Cheat tool for the Nintendo DS
|
||||
@ Copyright (C) 2008 Michael "Chishm" Chisholm
|
||||
@
|
||||
@ 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/>.
|
||||
|
||||
@ Clears ICache and Dcache, and resets the protection units
|
||||
@ Originally written by Darkain, modified by Chishm
|
||||
|
||||
#include <nds/asminc.h>
|
||||
|
||||
.arm
|
||||
|
||||
BEGIN_ASM_FUNC arm9_clearCache
|
||||
@ Clean and flush cache
|
||||
mov r1, #0
|
||||
outer_loop:
|
||||
mov r0, #0
|
||||
inner_loop:
|
||||
orr r2, r1, r0
|
||||
mcr p15, 0, r2, c7, c14, 2
|
||||
add r0, r0, #0x20
|
||||
cmp r0, #0x400
|
||||
bne inner_loop
|
||||
add r1, r1, #0x40000000
|
||||
cmp r1, #0x0
|
||||
bne outer_loop
|
||||
|
||||
mov r3, #0
|
||||
mcr p15, 0, r3, c7, c5, 0 @ Flush ICache
|
||||
mcr p15, 0, r3, c7, c6, 0 @ Flush DCache
|
||||
mcr p15, 0, r3, c7, c10, 4 @ empty write buffer
|
||||
|
||||
mcr p15, 0, r3, c3, c0, 0 @ disable write buffer (def = 0)
|
||||
|
||||
mcr p15, 0, r3, c2, c0, 0 @ disable DTCM and protection unit
|
||||
|
||||
mcr p15, 0, r3, c6, c0, 0 @ disable protection unit 0 (def = 0)
|
||||
mcr p15, 0, r3, c6, c1, 0 @ disable protection unit 1 (def = 0)
|
||||
mcr p15, 0, r3, c6, c2, 0 @ disable protection unit 2 (def = 0)
|
||||
mcr p15, 0, r3, c6, c3, 0 @ disable protection unit 3 (def = 0)
|
||||
mcr p15, 0, r3, c6, c4, 0 @ disable protection unit 4 (def = ?)
|
||||
mcr p15, 0, r3, c6, c5, 0 @ disable protection unit 5 (def = ?)
|
||||
mcr p15, 0, r3, c6, c6, 0 @ disable protection unit 6 (def = ?)
|
||||
mcr p15, 0, r3, c6, c7, 0 @ disable protection unit 7 (def = ?)
|
||||
|
||||
mcr p15, 0, r3, c5, c0, 3 @ IAccess
|
||||
mcr p15, 0, r3, c5, c0, 2 @ DAccess
|
||||
|
||||
mov r3, #0x00800000
|
||||
add r3, r3, #0x00A
|
||||
mcr p15, 0, r3, c9, c1, 0 @ DTCM base (def = 0x0080000A) ???
|
||||
|
||||
mov r3, #0x0000000C
|
||||
mcr p15, 0, r3, c9, c1, 1 @ ITCM base (def = 0x0000000C) ???
|
||||
|
||||
bx lr
|
||||
|
44
BootLoaderTWL/source/clear_mem.s
Normal file
44
BootLoaderTWL/source/clear_mem.s
Normal file
@ -0,0 +1,44 @@
|
||||
@ NitroHax -- Cheat tool for the Nintendo DS
|
||||
@ Copyright (C) 2008 Michael "Chishm" Chisholm
|
||||
@
|
||||
@ 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/>.
|
||||
|
||||
@ void arm7_clearmem (void* loc, size_t len);
|
||||
@ Clears memory using an stmia loop
|
||||
|
||||
#include <nds/asminc.h>
|
||||
|
||||
.arm
|
||||
|
||||
|
||||
BEGIN_ASM_FUNC arm7_clearmem
|
||||
add r1, r0, r1
|
||||
stmfd sp!, {r4-r9}
|
||||
mov r2, #0
|
||||
mov r3, #0
|
||||
mov r4, #0
|
||||
mov r5, #0
|
||||
mov r6, #0
|
||||
mov r7, #0
|
||||
mov r8, #0
|
||||
mov r9, #0
|
||||
|
||||
clearmem_loop:
|
||||
stmia r0!, {r2-r9}
|
||||
cmp r0, r1
|
||||
blt clearmem_loop
|
||||
|
||||
ldmfd sp!, {r4-r9}
|
||||
bx lr
|
||||
|
63
BootLoaderTWL/source/common.h
Normal file
63
BootLoaderTWL/source/common.h
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
NitroHax -- Cheat tool for the Nintendo DS
|
||||
Copyright (C) 2008 Michael "Chishm" Chisholm
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
#ifndef _COMMON_H
|
||||
#define _COMMON_H
|
||||
|
||||
#include <nds/dma.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define resetCpu() \
|
||||
__asm volatile("swi 0x000000")
|
||||
|
||||
typedef enum { ERR_NONE=0x00, ERR_STS_CLR_MEM=0x01, ERR_STS_LOAD_BIN=0x02, ERR_STS_HOOK_BIN=0x03, ERR_STS_START=0x04,
|
||||
// initCard error codes:
|
||||
ERR_LOAD_NORM=0x11, ERR_LOAD_OTHR=0x12, ERR_SEC_NORM=0x13, ERR_SEC_OTHR=0x14, ERR_LOGO_CRC=0x15, ERR_HEAD_CRC=0x16,
|
||||
// hookARM7Binary error codes:
|
||||
ERR_NOCHEAT=0x21, ERR_HOOK=0x22,
|
||||
} ERROR_CODES;
|
||||
|
||||
typedef enum {ARM9_BOOT, ARM9_START, ARM9_MEMCLR, ARM9_READY, ARM9_BOOTBIN, ARM9_DISPERR, ARM9_SETSCFG} ARM9_STATE;
|
||||
extern tNDSHeader* ndsHeader;
|
||||
|
||||
extern bool arm9_dsiModeConfirmed;
|
||||
extern bool arm9_ExtendRam;
|
||||
extern bool arm9_boostVram;
|
||||
extern bool arm9_scfgUnlock;
|
||||
extern bool arm9_TWLClockSpeeds;
|
||||
extern bool arm9_DebugMode;
|
||||
|
||||
extern volatile int arm9_stateFlag;
|
||||
extern volatile u32 arm9_errorCode;
|
||||
extern volatile bool arm9_errorClearBG;
|
||||
|
||||
static inline void dmaFill(const void* src, void* dest, uint32 size) {
|
||||
DMA_SRC(3) = (uint32)src;
|
||||
DMA_DEST(3) = (uint32)dest;
|
||||
DMA_CR(3) = DMA_COPY_WORDS | DMA_SRC_FIX | (size>>2);
|
||||
while(DMA_CR(3) & DMA_BUSY);
|
||||
}
|
||||
|
||||
static inline void copyLoop (u32* dest, const u32* src, size_t size) {
|
||||
do {
|
||||
*dest++ = *src++;
|
||||
} while (size -= 4);
|
||||
}
|
||||
|
||||
#endif // _COMMON_H
|
||||
|
62
BootLoaderTWL/source/crt0.arm9.s
Normal file
62
BootLoaderTWL/source/crt0.arm9.s
Normal file
@ -0,0 +1,62 @@
|
||||
@---------------------------------------------------------------------------------
|
||||
.global _arm9_start
|
||||
@---------------------------------------------------------------------------------
|
||||
.align 4
|
||||
.arm
|
||||
@---------------------------------------------------------------------------------
|
||||
_arm9_start:
|
||||
@---------------------------------------------------------------------------------
|
||||
mov r0, #0x04000000 @ IME = 0;
|
||||
add r0, r0, #0x208
|
||||
strh r0, [r0]
|
||||
|
||||
mov r0, #0x12 @ Switch to IRQ Mode
|
||||
msr cpsr, r0
|
||||
ldr sp, =__arm9_sp_irq @ Set IRQ stack
|
||||
|
||||
mov r0, #0x13 @ Switch to SVC Mode
|
||||
msr cpsr, r0
|
||||
ldr sp, =__arm9_sp_svc @ Set SVC stack
|
||||
|
||||
mov r0, #0x1F @ Switch to System Mode
|
||||
msr cpsr, r0
|
||||
ldr sp, =__arm9_sp_usr @ Set user stack
|
||||
|
||||
ldr r0, =__arm9_bss_start @ Clear BSS section to 0x00
|
||||
ldr r1, =__arm9_bss_end
|
||||
sub r1, r1, r0
|
||||
bl ClearMem
|
||||
|
||||
mov r0, #0 @ int argc
|
||||
mov r1, #0 @ char *argv[]
|
||||
ldr r3, =arm9_main
|
||||
bl _blx_r3_stub @ jump to user code
|
||||
|
||||
@ If the user ever returns, restart
|
||||
b _arm9_start
|
||||
|
||||
@---------------------------------------------------------------------------------
|
||||
_blx_r3_stub:
|
||||
@---------------------------------------------------------------------------------
|
||||
bx r3
|
||||
|
||||
|
||||
@---------------------------------------------------------------------------------
|
||||
@ Clear memory to 0x00 if length != 0
|
||||
@ r0 = Start Address
|
||||
@ r1 = Length
|
||||
@---------------------------------------------------------------------------------
|
||||
ClearMem:
|
||||
@---------------------------------------------------------------------------------
|
||||
mov r2, #3 @ Round down to nearest word boundary
|
||||
add r1, r1, r2 @ Shouldn't be needed
|
||||
bics r1, r1, r2 @ Clear 2 LSB (and set Z)
|
||||
bxeq lr @ Quit if copy size is 0
|
||||
|
||||
mov r2, #0
|
||||
ClrLoop:
|
||||
stmia r0!, {r2}
|
||||
subs r1, r1, #4
|
||||
bne ClrLoop
|
||||
bx lr
|
||||
|
151
BootLoaderTWL/source/decompress.c
Normal file
151
BootLoaderTWL/source/decompress.c
Normal file
@ -0,0 +1,151 @@
|
||||
/*
|
||||
Copyright (C) 2008 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 <nds/ndstypes.h>
|
||||
#include <nds/memory.h> // tNDSHeader
|
||||
#include <stddef.h>
|
||||
#include "module_params.h"
|
||||
|
||||
/*static void decompressLZ77Backwards(u8* addr, u32 size) {
|
||||
u32 len = *(u32*)(addr + size - 4) + size;
|
||||
|
||||
if(len == size) {
|
||||
size -= 12;
|
||||
}
|
||||
|
||||
len = *(u32*)(addr + size - 4) + size;
|
||||
|
||||
//byte[] Result = new byte[len];
|
||||
//Array.Copy(Data, Result, Data.Length);
|
||||
|
||||
u32 end = *(u32*)(addr + size - 8) & 0xFFFFFF;
|
||||
|
||||
u8* result = addr;
|
||||
|
||||
int Offs = (int)(size - (*(u32*)(addr + size - 8) >> 24));
|
||||
int dstoffs = (int)len;
|
||||
while (true) {
|
||||
u8 header = result[--Offs];
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if ((header & 0x80) == 0) {
|
||||
result[--dstoffs] = result[--Offs];
|
||||
} else {
|
||||
u8 a = result[--Offs];
|
||||
u8 b = result[--Offs];
|
||||
int offs = (((a & 0xF) << 8) | b) + 2;//+ 1;
|
||||
int length = (a >> 4) + 2;
|
||||
do {
|
||||
result[dstoffs - 1] = result[dstoffs + offs];
|
||||
dstoffs--;
|
||||
length--;
|
||||
} while (length >= 0);
|
||||
}
|
||||
|
||||
if (Offs <= size - end) {
|
||||
return;
|
||||
}
|
||||
|
||||
header <<= 1;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
//static u32 iUncompressedSize = 0;
|
||||
static u32 iFixedAddr = 0;
|
||||
static u32 iFixedData = 0;
|
||||
|
||||
static u32 decompressBinary(u8 *aMainMemory, u32 aCodeLength, u32 aMemOffset) {
|
||||
u8 *ADDR1 = NULL;
|
||||
u8 *ADDR1_END = NULL;
|
||||
u8 *ADDR2 = NULL;
|
||||
u8 *ADDR3 = NULL;
|
||||
|
||||
u8 *pBuffer32 = (u8 *)(aMainMemory);
|
||||
u8 *pBuffer32End = (u8 *)(aMainMemory + aCodeLength);
|
||||
|
||||
while (pBuffer32 < pBuffer32End) {
|
||||
if (0xDEC00621 == *(u32 *)pBuffer32 && 0x2106C0DE == *(u32 *)(pBuffer32 + 4)) {
|
||||
ADDR1 = (u8 *)(*(u32 *)(pBuffer32 - 8));
|
||||
iFixedAddr = (u32)(pBuffer32 - 8);
|
||||
iFixedData = *(u32 *)(pBuffer32 - 8);
|
||||
*(u32 *)(pBuffer32 - 8) = 0;
|
||||
break;
|
||||
}
|
||||
pBuffer32 += 4;
|
||||
}
|
||||
if (0 == ADDR1) {
|
||||
iFixedAddr = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 A = *(u32 *)(ADDR1 + aMemOffset - 4);
|
||||
u32 B = *(u32 *)(ADDR1 + aMemOffset - 8);
|
||||
ADDR1_END = ADDR1 + A;
|
||||
ADDR2 = ADDR1 - (B >> 24);
|
||||
B &= ~0xff000000;
|
||||
ADDR3 = ADDR1 - B;
|
||||
u32 uncompressEnd = ((u32)ADDR1_END) - ((u32)aMainMemory);
|
||||
|
||||
while (!(ADDR2 <= ADDR3)) {
|
||||
u32 marku8 = *(--ADDR2 + aMemOffset);
|
||||
//ADDR2-=1;
|
||||
int count = 8;
|
||||
while (true) {
|
||||
count--;
|
||||
if (count < 0)
|
||||
break;
|
||||
if (0 == (marku8 & 0x80)) {
|
||||
*(--ADDR1_END + aMemOffset) = *(--ADDR2 + aMemOffset);
|
||||
} else {
|
||||
int u8_r12 = *(--ADDR2 + aMemOffset);
|
||||
int u8_r7 = *(--ADDR2 + aMemOffset);
|
||||
u8_r7 |= (u8_r12 << 8);
|
||||
u8_r7 &= ~0xf000;
|
||||
u8_r7 += 2;
|
||||
u8_r12 += 0x20;
|
||||
do
|
||||
{
|
||||
u8 realu8 = *(ADDR1_END + aMemOffset + u8_r7);
|
||||
*(--ADDR1_END + aMemOffset) = realu8;
|
||||
u8_r12 -= 0x10;
|
||||
} while (u8_r12 >= 0);
|
||||
}
|
||||
marku8 <<= 1;
|
||||
if (ADDR2 <= ADDR3) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return uncompressEnd;
|
||||
}
|
||||
|
||||
void ensureBinaryDecompressed(const tNDSHeader* ndsHeader, module_params_t* moduleParams) {
|
||||
//const char* romTid = getRomTid(ndsHeader);
|
||||
|
||||
if (
|
||||
moduleParams->compressed_static_end
|
||||
/*|| strcmp(romTid, "YQUJ") == 0 // Chrono Trigger (Japan)
|
||||
|| strcmp(romTid, "YQUE") == 0 // Chrono Trigger (USA)
|
||||
|| strcmp(romTid, "YQUP") == 0 // Chrono Trigger (Europe)*/
|
||||
) {
|
||||
// Compressed
|
||||
//dbg_printf("This rom is compressed\n");
|
||||
//decompressLZ77Backwards((u8*)ndsHeader->arm9destination, ndsHeader->arm9binarySize);
|
||||
decompressBinary((u8*)ndsHeader->arm9destination, ndsHeader->arm9binarySize, 0);
|
||||
moduleParams->compressed_static_end = 0;
|
||||
}/* else {
|
||||
// Not compressed
|
||||
dbg_printf("This rom is not compressed\n");
|
||||
}*/
|
||||
}
|
112
BootLoaderTWL/source/encryption.c
Normal file
112
BootLoaderTWL/source/encryption.c
Normal file
@ -0,0 +1,112 @@
|
||||
/*
|
||||
NitroHax -- Cheat tool for the Nintendo DS
|
||||
Copyright (C) 2008 Michael "Chishm" Chisholm
|
||||
|
||||
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 <string.h>
|
||||
#include "encryption.h"
|
||||
#include "key1.h"
|
||||
#include "key2.h"
|
||||
#include "tonccpy.h"
|
||||
|
||||
#define KEYSIZE 0x1048
|
||||
|
||||
static u32 keycode [3];
|
||||
static u32 keybuf [KEYSIZE/sizeof(u32)];
|
||||
|
||||
void crypt_64bit_up (u32* ptr) {
|
||||
u32 x = ptr[1];
|
||||
u32 y = ptr[0];
|
||||
u32 z;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 0x10; i++) {
|
||||
z = keybuf[i] ^ x;
|
||||
x = keybuf[0x012 + ((z>>24)&0xff)];
|
||||
x = keybuf[0x112 + ((z>>16)&0xff)] + x;
|
||||
x = keybuf[0x212 + ((z>> 8)&0xff)] ^ x;
|
||||
x = keybuf[0x312 + ((z>> 0)&0xff)] + x;
|
||||
x = y ^ x;
|
||||
y = z;
|
||||
}
|
||||
|
||||
ptr[0] = x ^ keybuf[0x10];
|
||||
ptr[1] = y ^ keybuf[0x11];
|
||||
}
|
||||
|
||||
void crypt_64bit_down (u32* ptr) {
|
||||
u32 x = ptr[1];
|
||||
u32 y = ptr[0];
|
||||
u32 z;
|
||||
int i;
|
||||
|
||||
for (i = 0x11; i > 0x01; i--) {
|
||||
z = keybuf[i] ^ x;
|
||||
x = keybuf[0x012 + ((z>>24)&0xff)];
|
||||
x = keybuf[0x112 + ((z>>16)&0xff)] + x;
|
||||
x = keybuf[0x212 + ((z>> 8)&0xff)] ^ x;
|
||||
x = keybuf[0x312 + ((z>> 0)&0xff)] + x;
|
||||
x = y ^ x;
|
||||
y = z;
|
||||
}
|
||||
|
||||
ptr[0] = x ^ keybuf[0x01];
|
||||
ptr[1] = y ^ keybuf[0x00];
|
||||
}
|
||||
|
||||
static u32 bswap_32bit (u32 in) {
|
||||
u8 a,b,c,d;
|
||||
a = (u8)((in >> 0) & 0xff);
|
||||
b = (u8)((in >> 8) & 0xff);
|
||||
c = (u8)((in >> 16) & 0xff);
|
||||
d = (u8)((in >> 24) & 0xff);
|
||||
|
||||
u32 out = (a << 24) | (b << 16) | (c << 8) | (d << 0);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
void apply_keycode (u32 modulo) {
|
||||
u32 scratch[2];
|
||||
int i;
|
||||
modulo = modulo / sizeof(*keycode);
|
||||
|
||||
crypt_64bit_up (&keycode[1]);
|
||||
crypt_64bit_up (&keycode[0]);
|
||||
toncset (scratch, 0, 8);
|
||||
|
||||
for (i = 0; i < 0x12; i+=1) {
|
||||
keybuf[i] = keybuf[i] ^ bswap_32bit (keycode[i % modulo]);
|
||||
}
|
||||
for (i = 0; i < 0x412; i+=2) {
|
||||
crypt_64bit_up (scratch);
|
||||
keybuf[i] = scratch[1];
|
||||
keybuf[i+1] = scratch[0];
|
||||
}
|
||||
}
|
||||
|
||||
void init_keycode (u32 idcode, u32 level, u32 modulo, int iCardDevice) {
|
||||
tonccpy ((u8*)keybuf, (iCardDevice ? gEncrDataTwl : gEncrData), KEYSIZE);
|
||||
keycode[0] = idcode;
|
||||
keycode[1] = idcode/2;
|
||||
keycode[2] = idcode*2;
|
||||
|
||||
if (level >= 1) apply_keycode (modulo); // first apply (always)
|
||||
if (level >= 2) apply_keycode (modulo); // second apply (optional)
|
||||
keycode[1] = keycode[1] * 2;
|
||||
keycode[2] = keycode[2] / 2;
|
||||
if (level >= 3) apply_keycode (modulo); // third apply (optional)
|
||||
}
|
27
BootLoaderTWL/source/encryption.h
Normal file
27
BootLoaderTWL/source/encryption.h
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
NitroHax -- Cheat tool for the Nintendo DS
|
||||
Copyright (C) 2008 Michael "Chishm" Chisholm
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
#ifndef ENCRYPTION_H
|
||||
#define ENCRYPTION_H
|
||||
|
||||
#include <nds/ndstypes.h>
|
||||
void init_keycode (u32 idcode, u32 level, u32 modulo, int iCardDevice);
|
||||
void crypt_64bit_down (u32* ptr);
|
||||
void crypt_64bit_up (u32* ptr);
|
||||
|
||||
#endif
|
32
BootLoaderTWL/source/find.h
Normal file
32
BootLoaderTWL/source/find.h
Normal file
@ -0,0 +1,32 @@
|
||||
#ifndef FIND_H
|
||||
#define FIND_H
|
||||
|
||||
#include <nds/ndstypes.h>
|
||||
#include <nds/memory.h> // tNDSHeader
|
||||
#include "module_params.h"
|
||||
|
||||
// COMMON
|
||||
//u8* memsearch(const u8* start, u32 dataSize, const u8* find, u32 findSize);
|
||||
u32* memsearch32(const u32* start, u32 dataSize, const u32* find, u32 findSize, bool forward);
|
||||
u16* memsearch16(const u16* start, u32 dataSize, const u16* find, u32 findSize, bool forward);
|
||||
|
||||
inline u32* findOffset(const u32* start, u32 dataSize, const u32* find, u32 findLen) {
|
||||
return memsearch32(start, dataSize, find, findLen*sizeof(u32), true);
|
||||
}
|
||||
inline u32* findOffsetBackwards(const u32* start, u32 dataSize, const u32* find, u32 findLen) {
|
||||
return memsearch32(start, dataSize, find, findLen*sizeof(u32), false);
|
||||
}
|
||||
inline u16* findOffsetThumb(const u16* start, u32 dataSize, const u16* find, u32 findLen) {
|
||||
return memsearch16(start, dataSize, find, findLen*sizeof(u16), true);
|
||||
}
|
||||
inline u16* findOffsetBackwardsThumb(const u16* start, u32 dataSize, const u16* find, u32 findLen) {
|
||||
return memsearch16(start, dataSize, find, findLen*sizeof(u16), false);
|
||||
}
|
||||
|
||||
const u32* getMpuInitRegionSignature(u32 patchMpuRegion);
|
||||
u32* findMpuStartOffset(const tNDSHeader* ndsHeader, u32 patchMpuRegion);
|
||||
u32* findMpuDataOffset(const module_params_t* moduleParams, u32 patchMpuRegion, const u32* mpuStartOffset);
|
||||
u32* findMpuInitCacheOffset(const u32* mpuStartOffset);
|
||||
|
||||
#endif // FIND_H
|
||||
|
141
BootLoaderTWL/source/find_arm9.c
Normal file
141
BootLoaderTWL/source/find_arm9.c
Normal file
@ -0,0 +1,141 @@
|
||||
#include <stddef.h> // NULL
|
||||
#include "patch.h"
|
||||
#include "find.h"
|
||||
|
||||
//#define memset __builtin_memset
|
||||
|
||||
//
|
||||
// Subroutine function signatures ARM9
|
||||
//
|
||||
|
||||
// Mpu cache
|
||||
static const u32 mpuInitRegion0Signature[1] = {0xEE060F10};
|
||||
static const u32 mpuInitRegion0Data[1] = {0x4000033};
|
||||
static const u32 mpuInitRegion1Signature[1] = {0xEE060F11};
|
||||
static const u32 mpuInitRegion1Data1[1] = {0x200002D}; // SDK <= 3
|
||||
static const u32 mpuInitRegion1Data4[1] = {0x200002D}; // SDK >= 4
|
||||
//static const u32 mpuInitRegion1DataAlt[1] = {0x200002B};
|
||||
static const u32 mpuInitRegion2Signature[1] = {0xEE060F12};
|
||||
static const u32 mpuInitRegion2Data1[1] = {0x27C0023}; // SDK != 3 (Previously: SDK <= 2)
|
||||
static const u32 mpuInitRegion2Data3[1] = {0x27E0021}; // SDK 3 (Previously: SDK >= 3)
|
||||
static const u32 mpuInitRegion3Signature[1] = {0xEE060F13};
|
||||
static const u32 mpuInitRegion3Data[1] = {0x8000035};
|
||||
|
||||
// Mpu cache init
|
||||
static const u32 mpuInitCache[1] = {0xE3A00042};
|
||||
|
||||
const u32* getMpuInitRegionSignature(u32 patchMpuRegion) {
|
||||
switch (patchMpuRegion) {
|
||||
case 0: return mpuInitRegion0Signature;
|
||||
case 1: return mpuInitRegion1Signature;
|
||||
case 2: return mpuInitRegion2Signature;
|
||||
case 3: return mpuInitRegion3Signature;
|
||||
}
|
||||
return mpuInitRegion1Signature;
|
||||
}
|
||||
|
||||
u32* findMpuStartOffset(const tNDSHeader* ndsHeader, u32 patchMpuRegion) {
|
||||
// dbg_printf("findMpuStartOffset:\n");
|
||||
|
||||
const u32* mpuInitRegionSignature = getMpuInitRegionSignature(patchMpuRegion);
|
||||
|
||||
u32* mpuStartOffset = findOffset(
|
||||
(u32*)ndsHeader->arm9destination, ndsHeader->arm9binarySize,
|
||||
mpuInitRegionSignature, 1
|
||||
);
|
||||
if (mpuStartOffset) {
|
||||
// dbg_printf("Mpu init found: ");
|
||||
} else {
|
||||
// dbg_printf("Mpu init not found\n");
|
||||
}
|
||||
|
||||
if (mpuStartOffset) {
|
||||
// dbg_hexa((u32)mpuStartOffset);
|
||||
// dbg_printf("\n");
|
||||
}
|
||||
|
||||
// dbg_printf("\n");
|
||||
return mpuStartOffset;
|
||||
}
|
||||
|
||||
u32* findMpuDataOffset(const module_params_t* moduleParams, u32 patchMpuRegion, const u32* mpuStartOffset) {
|
||||
if (!mpuStartOffset) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// dbg_printf("findMpuDataOffset:\n");
|
||||
|
||||
const u32* mpuInitRegion1Data = mpuInitRegion1Data1;
|
||||
const u32* mpuInitRegion2Data = mpuInitRegion2Data1;
|
||||
if (moduleParams->sdk_version > 0x3000000 && moduleParams->sdk_version < 0x4000000) {
|
||||
mpuInitRegion2Data = mpuInitRegion2Data3;
|
||||
} else if (moduleParams->sdk_version > 0x4000000) {
|
||||
mpuInitRegion1Data = mpuInitRegion1Data4;
|
||||
}
|
||||
|
||||
const u32* mpuInitRegionData = mpuInitRegion1Data;
|
||||
switch (patchMpuRegion) {
|
||||
case 0:
|
||||
mpuInitRegionData = mpuInitRegion0Data;
|
||||
break;
|
||||
case 1:
|
||||
mpuInitRegionData = mpuInitRegion1Data;
|
||||
break;
|
||||
case 2:
|
||||
mpuInitRegionData = mpuInitRegion2Data;
|
||||
break;
|
||||
case 3:
|
||||
mpuInitRegionData = mpuInitRegion3Data;
|
||||
break;
|
||||
}
|
||||
|
||||
u32* mpuDataOffset = findOffset(
|
||||
mpuStartOffset, 0x100,
|
||||
mpuInitRegionData, 1
|
||||
);
|
||||
if (!mpuDataOffset) {
|
||||
// Try to find it
|
||||
for (int i = 0; i < 0x100; i++) {
|
||||
mpuDataOffset += i;
|
||||
if ((*mpuDataOffset & 0xFFFFFF00) == 0x02000000) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mpuDataOffset) {
|
||||
// dbg_printf("Mpu data found: ");
|
||||
} else {
|
||||
// dbg_printf("Mpu data not found\n");
|
||||
}
|
||||
|
||||
if (mpuDataOffset) {
|
||||
// dbg_hexa((u32)mpuDataOffset);
|
||||
// dbg_printf("\n");
|
||||
}
|
||||
|
||||
// dbg_printf("\n");
|
||||
return mpuDataOffset;
|
||||
}
|
||||
|
||||
u32* findMpuInitCacheOffset(const u32* mpuStartOffset) {
|
||||
// dbg_printf("findMpuInitCacheOffset:\n");
|
||||
|
||||
u32* mpuInitCacheOffset = findOffset(
|
||||
mpuStartOffset, 0x100,
|
||||
mpuInitCache, 1
|
||||
);
|
||||
if (mpuInitCacheOffset) {
|
||||
// dbg_printf("Mpu init cache found: ");
|
||||
} else {
|
||||
// dbg_printf("Mpu init cache not found\n");
|
||||
}
|
||||
|
||||
if (mpuInitCacheOffset) {
|
||||
// dbg_hexa((u32)mpuInitCacheOffset);
|
||||
// dbg_printf("\n");
|
||||
}
|
||||
|
||||
// dbg_printf("\n");
|
||||
return mpuInitCacheOffset;
|
||||
}
|
||||
|
117
BootLoaderTWL/source/find_common.c
Normal file
117
BootLoaderTWL/source/find_common.c
Normal file
@ -0,0 +1,117 @@
|
||||
//#include <string.h> // memcmp
|
||||
#include <stddef.h> // NULL
|
||||
#include <nds/ndstypes.h>
|
||||
//#include <limits.h>
|
||||
#include "find.h"
|
||||
|
||||
// (memcmp is slower)
|
||||
//#define memcmp __builtin_memcmp
|
||||
|
||||
//#define TABLE_SIZE (UCHAR_MAX + 1) // 256
|
||||
|
||||
extern inline u32* findOffset(const u32* start, u32 dataLen, const u32* find, u32 findLen);
|
||||
extern inline u32* findOffsetBackwards(const u32* start, u32 dataLen, const u32* find, u32 findLen);
|
||||
extern inline u16* findOffsetThumb(const u16* start, u32 dataLen, const u16* find, u32 findLen);
|
||||
extern inline u16* findOffsetBackwardsThumb(const u16* start, u32 dataLen, const u16* find, u32 findLen);
|
||||
|
||||
/*
|
||||
* Look for @find and return the position of it.
|
||||
* Brute Force algorithm
|
||||
*/
|
||||
u32* memsearch32(const u32* start, u32 dataSize, const u32* find, u32 findSize, bool forward) {
|
||||
u32 dataLen = dataSize/sizeof(u32);
|
||||
u32 findLen = findSize/sizeof(u32);
|
||||
|
||||
const u32* end = forward ? (start + dataLen) : (start - dataLen);
|
||||
for (u32* addr = (u32*)start; addr != end; forward ? ++addr : --addr) {
|
||||
bool found = true;
|
||||
for (u32 j = 0; j < findLen; ++j) {
|
||||
if (addr[j] != find[j]) {
|
||||
found = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
return (u32*)addr;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
u16* memsearch16(const u16* start, u32 dataSize, const u16* find, u32 findSize, bool forward) {
|
||||
u32 dataLen = dataSize/sizeof(u16);
|
||||
u32 findLen = findSize/sizeof(u16);
|
||||
|
||||
const u16* end = forward ? (start + dataLen) : (start - dataLen);
|
||||
for (u16* addr = (u16*)start; addr != end; forward ? ++addr : --addr) {
|
||||
bool found = true;
|
||||
for (u32 j = 0; j < findLen; ++j) {
|
||||
if (addr[j] != find[j]) {
|
||||
found = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
return (u16*)addr;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Boyer-Moore Horspool algorithm
|
||||
*/
|
||||
/*u8* memsearch(const u8* start, u32 dataSize, const u8* find, u32 findSize) {
|
||||
u32 dataLen = dataSize/sizeof(u8);
|
||||
u32 findLen = findSize/sizeof(u8);
|
||||
|
||||
u32 table[TABLE_SIZE];
|
||||
|
||||
// Preprocessing
|
||||
for (u32 i = 0; i < TABLE_SIZE; ++i) {
|
||||
table[i] = findLen;
|
||||
}
|
||||
for (u32 i = 0; i < findLen - 1; ++i) {
|
||||
table[find[i]] = findLen - i - 1;
|
||||
}
|
||||
|
||||
// Searching
|
||||
u32 j = 0;
|
||||
while (j <= dataLen - findLen) {
|
||||
u8 c = start[j + findLen - 1];
|
||||
if (find[findLen - 1] == c && memcmp(find, start + j, findLen - 1) == 0) {
|
||||
return (u8*)start + j;
|
||||
}
|
||||
j += table[c];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}*/
|
||||
|
||||
/*
|
||||
* Quick Search algorithm
|
||||
*/
|
||||
/*u8* memsearch(const u8* start, u32 dataSize, const u8* find, u32 findSize) {
|
||||
u32 dataLen = dataSize/sizeof(u8);
|
||||
u32 findLen = findSize/sizeof(u8);
|
||||
|
||||
u32 table[TABLE_SIZE];
|
||||
|
||||
// Preprocessing
|
||||
for (u32 i = 0; i < TABLE_SIZE; ++i) {
|
||||
table[i] = findLen + 1;
|
||||
}
|
||||
for (u32 i = 0; i < findLen; ++i) {
|
||||
table[find[i]] = findLen - i;
|
||||
}
|
||||
|
||||
// Searching
|
||||
u32 j = 0;
|
||||
while (j <= dataLen - findLen) {
|
||||
if (memcmp(find, start + j, findLen) == 0) {
|
||||
return (u8*)start + j;
|
||||
}
|
||||
j += table[start[j + findLen]];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}*/
|
264
BootLoaderTWL/source/key1.h
Normal file
264
BootLoaderTWL/source/key1.h
Normal file
@ -0,0 +1,264 @@
|
||||
const unsigned char gEncrData[] =
|
||||
{
|
||||
0x99,0xD5,0x20,0x5F,0x57,0x44,0xF5,0xB9,0x6E,0x19,0xA4,0xD9,0x9E,0x6A,0x5A,0x94,
|
||||
0xD8,0xAE,0xF1,0xEB,0x41,0x75,0xE2,0x3A,0x93,0x82,0xD0,0x32,0x33,0xEE,0x31,0xD5,
|
||||
0xCC,0x57,0x61,0x9A,0x37,0x06,0xA2,0x1B,0x79,0x39,0x72,0xF5,0x55,0xAE,0xF6,0xBE,
|
||||
0x5F,0x1B,0x69,0xFB,0xE5,0x9D,0xF1,0xE9,0xCE,0x2C,0xD9,0xA1,0x5E,0x32,0x05,0xE6,
|
||||
0xFE,0xD3,0xFE,0xCF,0xD4,0x62,0x04,0x0D,0x8B,0xF5,0xEC,0xB7,0x2B,0x60,0x79,0xBB,
|
||||
0x12,0x95,0x31,0x0D,0x6E,0x3F,0xDA,0x2B,0x88,0x84,0xF0,0xF1,0x3D,0x12,0x7E,0x25,
|
||||
0x45,0x22,0xF1,0xBB,0x24,0x06,0x1A,0x06,0x11,0xAD,0xDF,0x28,0x8B,0x64,0x81,0x34,
|
||||
0x2B,0xEB,0x33,0x29,0x99,0xAA,0xF2,0xBD,0x9C,0x14,0x95,0x9D,0x9F,0xF7,0xF5,0x8C,
|
||||
0x72,0x97,0xA1,0x29,0x9D,0xD1,0x5F,0xCF,0x66,0x4D,0x07,0x1A,0xDE,0xD3,0x4A,0x4B,
|
||||
0x85,0xC9,0xA7,0xA3,0x17,0x95,0x05,0x3A,0x3D,0x49,0x0A,0xBF,0x0A,0x89,0x8B,0xA2,
|
||||
0x4A,0x82,0x49,0xDD,0x27,0x90,0xF1,0x0B,0xE9,0xEB,0x1C,0x6A,0x83,0x76,0x45,0x05,
|
||||
0xBA,0x81,0x70,0x61,0x17,0x3F,0x4B,0xDE,0xAE,0xCF,0xAB,0x39,0x57,0xF2,0x3A,0x56,
|
||||
0x48,0x11,0xAD,0x8A,0x40,0xE1,0x45,0x3F,0xFA,0x9B,0x02,0x54,0xCA,0xA6,0x93,0xFB,
|
||||
0xEF,0x4D,0xFE,0x6F,0xA3,0xD8,0x87,0x9C,0x08,0xBA,0xD5,0x48,0x6A,0x8D,0x2D,0xFD,
|
||||
0x6E,0x15,0xF8,0x74,0xBD,0xBE,0x52,0x8B,0x18,0x22,0x8A,0x9E,0xFB,0x74,0x37,0x07,
|
||||
0x1B,0x36,0x6C,0x4A,0x19,0xBA,0x42,0x62,0xB9,0x79,0x91,0x10,0x7B,0x67,0x65,0x96,
|
||||
0xFE,0x02,0x23,0xE8,0xEE,0x99,0x8C,0x77,0x3E,0x5C,0x86,0x64,0x4D,0x6D,0x78,0x86,
|
||||
0xA5,0x4F,0x65,0xE2,0x1E,0xB2,0xDF,0x5A,0x0A,0xD0,0x7E,0x08,0x14,0xB0,0x71,0xAC,
|
||||
0xBD,0xDB,0x83,0x1C,0xB9,0xD7,0xA1,0x62,0xCD,0xC6,0x63,0x7C,0x52,0x69,0xC3,0xE6,
|
||||
0xBF,0x75,0xCE,0x12,0x44,0x5D,0x21,0x04,0xFA,0xFB,0xD3,0x3C,0x38,0x11,0x63,0xD4,
|
||||
0x95,0x85,0x41,0x49,0x46,0x09,0xF2,0x08,0x43,0x11,0xDC,0x1F,0x76,0xC0,0x15,0x6D,
|
||||
0x1F,0x3C,0x63,0x70,0xEA,0x87,0x80,0x6C,0xC3,0xBD,0x63,0x8B,0xC2,0x37,0x21,0x37,
|
||||
0xDC,0xEE,0x09,0x23,0x2E,0x37,0x6A,0x4D,0x73,0x90,0xF7,0x50,0x30,0xAC,0x1C,0x92,
|
||||
0x04,0x10,0x23,0x91,0x4F,0xD2,0x07,0xAA,0x68,0x3E,0x4F,0x9A,0xC9,0x64,0x60,0x6A,
|
||||
0xC8,0x14,0x21,0xF3,0xD6,0x22,0x41,0x12,0x44,0x24,0xCF,0xE6,0x8A,0x56,0xDD,0x0D,
|
||||
0x53,0x4D,0xE1,0x85,0x1E,0x8C,0x52,0x5A,0x9C,0x19,0x84,0xC2,0x03,0x57,0xF1,0x6F,
|
||||
0xE3,0x00,0xBE,0x58,0xF6,0x4C,0xED,0xD5,0x21,0x64,0x9C,0x1F,0xBE,0x55,0x03,0x3C,
|
||||
0x4A,0xDC,0xFF,0xAA,0xC9,0xDA,0xE0,0x5D,0x5E,0xBF,0xE6,0xDE,0xF5,0xD8,0xB1,0xF8,
|
||||
0xFF,0x36,0xB3,0xB9,0x62,0x67,0x95,0xDB,0x31,0x5F,0x37,0xED,0x4C,0x70,0x67,0x99,
|
||||
0x90,0xB5,0x18,0x31,0x6C,0x3D,0x99,0x99,0xE4,0x42,0xDA,0xD3,0x25,0x42,0x13,0xA0,
|
||||
0xAE,0xD7,0x70,0x6C,0xB1,0x55,0xCF,0xC7,0xD7,0x46,0xD5,0x43,0x61,0x17,0x3D,0x44,
|
||||
0x28,0xE9,0x33,0x85,0xD5,0xD0,0xA2,0x93,0xAA,0x25,0x12,0x1F,0xFB,0xC5,0x0B,0x46,
|
||||
0xF5,0x97,0x76,0x56,0x45,0xA6,0xBE,0x87,0xB1,0x94,0x6B,0xE8,0xB1,0xFE,0x33,0x99,
|
||||
0xAE,0x1F,0x3E,0x6C,0x39,0x71,0x1D,0x09,0x00,0x90,0x37,0xE4,0x10,0x3E,0x75,0x74,
|
||||
0xFF,0x8C,0x83,0x3B,0xB0,0xF1,0xB0,0xF9,0x01,0x05,0x47,0x42,0x95,0xF1,0xD6,0xAC,
|
||||
0x7E,0x38,0xE6,0x9E,0x95,0x74,0x26,0x3F,0xB4,0x68,0x50,0x18,0xD0,0x43,0x30,0xB4,
|
||||
0x4C,0x4B,0xE3,0x68,0xBF,0xE5,0x4D,0xB6,0x95,0x8B,0x0A,0xA0,0x74,0x25,0x32,0x77,
|
||||
0xCF,0xA1,0xF7,0x2C,0xD8,0x71,0x13,0x5A,0xAB,0xEA,0xC9,0x51,0xE8,0x0D,0xEE,0xEF,
|
||||
0xE9,0x93,0x7E,0x19,0xA7,0x1E,0x43,0x38,0x81,0x16,0x2C,0xA1,0x48,0xE3,0x73,0xCC,
|
||||
0x29,0x21,0x6C,0xD3,0x5D,0xCE,0xA0,0xD9,0x61,0x71,0x43,0xA0,0x15,0x13,0xB5,0x64,
|
||||
0x92,0xCF,0x2A,0x19,0xDC,0xAD,0xB7,0xA5,0x9F,0x86,0x65,0xF8,0x1A,0x9F,0xE7,0xFB,
|
||||
0xF7,0xFD,0xB8,0x13,0x6C,0x27,0xDB,0x6F,0xDF,0x35,0x1C,0xF7,0x8D,0x2C,0x5B,0x9B,
|
||||
0x12,0xAB,0x38,0x64,0x06,0xCC,0xDE,0x31,0xE8,0x4E,0x75,0x11,0x64,0xE3,0xFA,0xEA,
|
||||
0xEB,0x34,0x54,0xC2,0xAD,0x3F,0x34,0xEB,0x93,0x2C,0x7D,0x26,0x36,0x9D,0x56,0xF3,
|
||||
0x5A,0xE1,0xF6,0xB3,0x98,0x63,0x4A,0x9E,0x32,0x83,0xE4,0x9A,0x84,0x60,0x7D,0x90,
|
||||
0x2E,0x13,0x0E,0xEE,0x93,0x4B,0x36,0xA2,0x85,0xEC,0x16,0x38,0xE8,0x88,0x06,0x02,
|
||||
0xBF,0xF0,0xA0,0x3A,0xED,0xD7,0x6A,0x9A,0x73,0xE1,0x57,0xCF,0xF8,0x44,0xB8,0xDC,
|
||||
0x2E,0x23,0x59,0xD1,0xDF,0x95,0x52,0x71,0x99,0x61,0xA0,0x4B,0xD5,0x7F,0x6E,0x78,
|
||||
0xBA,0xA9,0xC5,0x30,0xD3,0x40,0x86,0x32,0x9D,0x32,0x0C,0x9C,0x37,0xB7,0x02,0x2F,
|
||||
0xBA,0x54,0x98,0xA9,0xC4,0x13,0x04,0xC9,0x8D,0xBE,0xC8,0xE7,0x5D,0x97,0x50,0x2E,
|
||||
0x93,0xD6,0x22,0x59,0x0C,0x27,0xBC,0x22,0x92,0xE0,0xA7,0x20,0x0F,0x93,0x6F,0x7F,
|
||||
0x4C,0x9F,0xD3,0xB5,0xA6,0x2A,0x0B,0x74,0x67,0x49,0x7D,0x10,0x26,0xCB,0xD1,0xC5,
|
||||
0x86,0x71,0xE7,0x8C,0xA0,0x9C,0xE9,0x5B,0xB2,0x1A,0xF6,0x01,0xEE,0x8C,0x9E,0x5E,
|
||||
0x83,0xF2,0x1A,0xDB,0xE6,0xE5,0xEA,0x84,0x59,0x76,0xD2,0x7C,0xF6,0x8D,0xA5,0x49,
|
||||
0x36,0x48,0xC2,0x16,0x52,0xBB,0x83,0xA3,0x74,0xB9,0x07,0x0C,0x3B,0xFF,0x61,0x28,
|
||||
0xE1,0x61,0xE9,0xE4,0xEF,0x6E,0x15,0xAA,0x4E,0xBA,0xE8,0x5D,0x05,0x96,0xBB,0x32,
|
||||
0x56,0xB0,0xFB,0x72,0x52,0x0F,0x0E,0xC8,0x42,0x25,0x65,0x76,0x89,0xAF,0xF2,0xDE,
|
||||
0x10,0x27,0xF0,0x01,0x4B,0x74,0xA7,0x97,0x07,0xD5,0x26,0x54,0x54,0x09,0x1F,0x82,
|
||||
0x0A,0x86,0x7D,0x30,0x39,0x0E,0xB3,0x26,0x9B,0x0B,0x57,0xBB,0x36,0x06,0x31,0xAF,
|
||||
0xFD,0x79,0xFC,0xD9,0x30,0x10,0x2B,0x0C,0xB3,0xE1,0x9B,0xD7,0x7B,0xDC,0x5F,0xEF,
|
||||
0xD2,0xF8,0x13,0x45,0x4D,0x47,0x75,0xBD,0x46,0x96,0x3C,0x7E,0x75,0xF3,0x3E,0xB5,
|
||||
0x67,0xC5,0x9A,0x3B,0xB0,0x5B,0x29,0x6B,0xDE,0x80,0x5B,0xC8,0x15,0x05,0xB1,0x31,
|
||||
0xB6,0xCE,0x49,0xDD,0xAD,0x84,0xB5,0xAE,0x60,0xDC,0x67,0x31,0x34,0x30,0xFE,0x4E,
|
||||
0xBD,0x80,0x2F,0xA6,0xBF,0x63,0x39,0x21,0x86,0xD9,0x35,0x7F,0x16,0x68,0x22,0x05,
|
||||
0x54,0xE9,0x90,0x26,0x8C,0x07,0x6C,0x51,0xA4,0x31,0x55,0xD7,0x09,0x07,0xA8,0x3E,
|
||||
0x2E,0x53,0x66,0xC1,0xF8,0xF2,0x7B,0xC4,0xF2,0x58,0xCF,0xF1,0x87,0xC5,0xA2,0xE7,
|
||||
0x27,0x8F,0x30,0x87,0x58,0xA0,0x64,0x62,0x23,0x18,0xB9,0x88,0x7C,0xFA,0xCE,0xC4,
|
||||
0x98,0xAE,0xAD,0x17,0xCC,0x4A,0x5B,0xF3,0xE9,0x48,0xD5,0x56,0xD3,0x0D,0xF2,0xC8,
|
||||
0x92,0x73,0x8C,0xDB,0xD7,0x2F,0x56,0xAC,0x81,0xF9,0x92,0x69,0x4D,0xC6,0x32,0xF6,
|
||||
0xE6,0xC0,0x8D,0x21,0xE2,0x76,0x80,0x61,0x11,0xBC,0xDC,0x6C,0x93,0xAF,0x19,0x69,
|
||||
0x9B,0xD0,0xBF,0xB9,0x31,0x9F,0x02,0x67,0xA3,0x51,0xEE,0x83,0x06,0x22,0x7B,0x0C,
|
||||
0xAB,0x49,0x42,0x40,0xB8,0xD5,0x01,0x7D,0xCE,0x5E,0xF7,0x55,0x53,0x39,0xC5,0x99,
|
||||
0x46,0xD8,0x87,0x9F,0xBA,0xF7,0x64,0xB4,0xE3,0x9A,0xFA,0xA1,0x6D,0x90,0x68,0x10,
|
||||
0x30,0xCA,0x8A,0x54,0xA7,0x9F,0x60,0xC3,0x19,0xF5,0x6B,0x0D,0x7A,0x51,0x98,0xE6,
|
||||
0x98,0x43,0x51,0xB4,0xD6,0x35,0xE9,0x4F,0xC3,0xDF,0x0F,0x7B,0xD6,0x2F,0x5C,0xBD,
|
||||
0x3A,0x15,0x61,0x19,0xF1,0x4B,0xCB,0xAA,0xDC,0x6D,0x64,0xC9,0xD3,0xC6,0x1E,0x56,
|
||||
0xEF,0x38,0x4C,0x50,0x71,0x86,0x75,0xCC,0x0D,0x0D,0x4E,0xE9,0x28,0xF6,0x06,0x5D,
|
||||
0x70,0x1B,0xAA,0xD3,0x45,0xCF,0xA8,0x39,0xAC,0x95,0xA6,0x2E,0xB4,0xE4,0x22,0xD4,
|
||||
0x74,0xA8,0x37,0x5F,0x48,0x7A,0x04,0xCC,0xA5,0x4C,0x40,0xD8,0x28,0xB4,0x28,0x08,
|
||||
0x0D,0x1C,0x72,0x52,0x41,0xF0,0x7D,0x47,0x19,0x3A,0x53,0x4E,0x58,0x84,0x62,0x6B,
|
||||
0x93,0xB5,0x8A,0x81,0x21,0x4E,0x0D,0xDC,0xB4,0x3F,0xA2,0xC6,0xFC,0xC9,0x2B,0x40,
|
||||
0xDA,0x38,0x04,0xE9,0x5E,0x5A,0x86,0x6B,0x0C,0x22,0x25,0x85,0x68,0x11,0x8D,0x7C,
|
||||
0x92,0x1D,0x95,0x55,0x4D,0xAB,0x8E,0xBB,0xDA,0xA6,0xE6,0xB7,0x51,0xB6,0x32,0x5A,
|
||||
0x05,0x41,0xDD,0x05,0x2A,0x0A,0x56,0x50,0x91,0x17,0x47,0xCC,0xC9,0xE6,0x7E,0xB5,
|
||||
0x61,0x4A,0xDB,0x73,0x67,0x51,0xC8,0x33,0xF5,0xDA,0x6E,0x74,0x2E,0x54,0xC3,0x37,
|
||||
0x0D,0x6D,0xAF,0x08,0xE8,0x15,0x8A,0x5F,0xE2,0x59,0x21,0xCD,0xA8,0xDE,0x0C,0x06,
|
||||
0x5A,0x77,0x6B,0x5F,0xDB,0x18,0x65,0x3E,0xC8,0x50,0xDE,0x78,0xE0,0xB8,0x82,0xB3,
|
||||
0x5D,0x4E,0x72,0x32,0x07,0x4F,0xC1,0x34,0x23,0xBA,0x96,0xB7,0x67,0x4E,0xA4,0x28,
|
||||
0x1E,0x34,0x62,0xEB,0x2D,0x6A,0x70,0xE9,0x2F,0x42,0xC4,0x70,0x4E,0x5A,0x31,0x9C,
|
||||
0xF9,0x5B,0x47,0x28,0xAA,0xDA,0x71,0x6F,0x38,0x1F,0xB3,0x78,0xC4,0x92,0x6B,0x1C,
|
||||
0x9E,0xF6,0x35,0x9A,0xB7,0x4D,0x0E,0xBF,0xCC,0x18,0x29,0x41,0x03,0x48,0x35,0x5D,
|
||||
0x55,0xD0,0x2B,0xC6,0x29,0xAF,0x5C,0x60,0x74,0x69,0x8E,0x5E,0x9B,0x7C,0xD4,0xBD,
|
||||
0x7B,0x44,0x64,0x7D,0x3F,0x92,0x5D,0x69,0xB6,0x1F,0x00,0x4B,0xD4,0x83,0x35,0xCF,
|
||||
0x7E,0x64,0x4E,0x17,0xAE,0x8D,0xD5,0x2E,0x9A,0x28,0x12,0x4E,0x2E,0x2B,0x49,0x08,
|
||||
0x5C,0xAE,0xC6,0x46,0x85,0xAE,0x41,0x61,0x1E,0x6F,0x82,0xD2,0x51,0x37,0x16,0x1F,
|
||||
0x0B,0xF6,0x59,0xA4,0x9A,0xCA,0x5A,0xAF,0x0D,0xD4,0x33,0x8B,0x20,0x63,0xF1,0x84,
|
||||
0x80,0x5C,0xCB,0xCF,0x08,0xB4,0xB9,0xD3,0x16,0x05,0xBD,0x62,0x83,0x31,0x9B,0x56,
|
||||
0x51,0x98,0x9F,0xBA,0xB2,0x5B,0xAA,0xB2,0x22,0x6B,0x2C,0xB5,0xD4,0x48,0xFA,0x63,
|
||||
0x2B,0x5F,0x58,0xFA,0x61,0xFA,0x64,0x09,0xBB,0x38,0xE0,0xB8,0x9D,0x92,0x60,0xA8,
|
||||
0x0D,0x67,0x6F,0x0E,0x37,0xF5,0x0D,0x01,0x9F,0xC2,0x77,0xD4,0xFE,0xEC,0xF1,0x73,
|
||||
0x30,0x39,0xE0,0x7D,0xF5,0x61,0x98,0xE4,0x2C,0x28,0x55,0x04,0x56,0x55,0xDB,0x2F,
|
||||
0x6B,0xEC,0xE5,0x58,0x06,0xB6,0x64,0x80,0x6A,0x2A,0x1A,0x4E,0x5B,0x0F,0xD8,0xC4,
|
||||
0x0A,0x2E,0x52,0x19,0xD9,0x62,0xF5,0x30,0x48,0xBE,0x8C,0x7B,0x4F,0x38,0x9B,0xA2,
|
||||
0xC3,0xAF,0xC9,0xD3,0xC7,0xC1,0x62,0x41,0x86,0xB9,0x61,0x21,0x57,0x6F,0x99,0x4F,
|
||||
0xC1,0xBA,0xCE,0x7B,0xB5,0x3B,0x4D,0x5E,0x8A,0x8B,0x44,0x57,0x5F,0x13,0x5F,0x70,
|
||||
0x6D,0x5B,0x29,0x47,0xDC,0x38,0xE2,0xEC,0x04,0x55,0x65,0x12,0x2A,0xE8,0x17,0x43,
|
||||
0xE1,0x8E,0xDD,0x2A,0xB3,0xE2,0x94,0xF7,0x09,0x6E,0x5C,0xE6,0xEB,0x8A,0xF8,0x6D,
|
||||
0x89,0x49,0x54,0x48,0xF5,0x2F,0xAD,0xBF,0xEA,0x94,0x4B,0xCA,0xFC,0x39,0x87,0x82,
|
||||
0x5F,0x8A,0x01,0xF2,0x75,0xF2,0xE6,0x71,0xD6,0xD8,0x42,0xDE,0xF1,0x2D,0x1D,0x28,
|
||||
0xA6,0x88,0x7E,0xA3,0xA0,0x47,0x1D,0x30,0xD9,0xA3,0x71,0xDF,0x49,0x1C,0xCB,0x01,
|
||||
0xF8,0x36,0xB1,0xF2,0xF0,0x22,0x58,0x5D,0x45,0x6B,0xBD,0xA0,0xBB,0xB2,0x88,0x42,
|
||||
0xC7,0x8C,0x28,0xCE,0x93,0xE8,0x90,0x63,0x08,0x90,0x7C,0x89,0x3C,0xF5,0x7D,0xB7,
|
||||
0x04,0x2D,0x4F,0x55,0x51,0x16,0xFD,0x7E,0x79,0xE8,0xBE,0xC1,0xF2,0x12,0xD4,0xF8,
|
||||
0xB4,0x84,0x05,0x23,0xA0,0xCC,0xD2,0x2B,0xFD,0xE1,0xAB,0xAD,0x0D,0xD1,0x55,0x6C,
|
||||
0x23,0x41,0x94,0x4D,0x77,0x37,0x4F,0x05,0x28,0x0C,0xBF,0x17,0xB3,0x12,0x67,0x6C,
|
||||
0x8C,0xC3,0x5A,0xF7,0x41,0x84,0x2A,0x6D,0xD0,0x94,0x12,0x27,0x2C,0xB4,0xED,0x9C,
|
||||
0x4D,0xEC,0x47,0x82,0x97,0xD5,0x67,0xB9,0x1B,0x9D,0xC0,0x55,0x07,0x7E,0xE5,0x8E,
|
||||
0xE2,0xA8,0xE7,0x3E,0x12,0xE4,0x0E,0x3A,0x2A,0x45,0x55,0x34,0xA2,0xF9,0x2D,0x5A,
|
||||
0x1B,0xAB,0x52,0x7C,0x83,0x10,0x5F,0x55,0xD2,0xF1,0x5A,0x43,0x2B,0xC6,0xA7,0xA4,
|
||||
0x89,0x15,0x95,0xE8,0xB4,0x4B,0x9D,0xF8,0x75,0xE3,0x9F,0x60,0x78,0x5B,0xD6,0xE6,
|
||||
0x0D,0x44,0xE6,0x21,0x06,0xBD,0x47,0x22,0x53,0xA4,0x00,0xAD,0x8D,0x43,0x13,0x85,
|
||||
0x39,0xF7,0xAA,0xFC,0x38,0xAF,0x7B,0xED,0xFC,0xE4,0x2B,0x54,0x50,0x98,0x4C,0xFC,
|
||||
0x85,0x80,0xF7,0xDF,0x3C,0x80,0x22,0xE1,0x94,0xDA,0xDE,0x24,0xC6,0xB0,0x7A,0x39,
|
||||
0x38,0xDC,0x0F,0xA1,0xA7,0xF4,0xF9,0x6F,0x63,0x18,0x57,0x8B,0x84,0x41,0x2A,0x2E,
|
||||
0xD4,0x53,0xF2,0xD9,0x00,0x0F,0xD0,0xDD,0x99,0x6E,0x19,0xA6,0x0A,0xD0,0xEC,0x5B,
|
||||
0x58,0x24,0xAB,0xC0,0xCB,0x06,0x65,0xEC,0x1A,0x13,0x38,0x94,0x0A,0x67,0x03,0x2F,
|
||||
0x3F,0xF7,0xE3,0x77,0x44,0x77,0x33,0xC6,0x14,0x39,0xD0,0xE3,0xC0,0xA2,0x08,0x79,
|
||||
0xBB,0x40,0x99,0x57,0x41,0x0B,0x01,0x90,0xCD,0xE1,0xCC,0x48,0x67,0xDB,0xB3,0xAF,
|
||||
0x88,0x74,0xF3,0x4C,0x82,0x8F,0x72,0xB1,0xB5,0x23,0x29,0xC4,0x12,0x6C,0x19,0xFC,
|
||||
0x8E,0x46,0xA4,0x9C,0xC4,0x25,0x65,0x87,0xD3,0x6D,0xBE,0x8A,0x93,0x11,0x03,0x38,
|
||||
0xED,0x83,0x2B,0xF3,0x46,0xA4,0x93,0xEA,0x3B,0x53,0x85,0x1D,0xCE,0xD4,0xF1,0x08,
|
||||
0x83,0x27,0xED,0xFC,0x9B,0x1A,0x18,0xBC,0xF9,0x8B,0xAE,0xDC,0x24,0xAB,0x50,0x38,
|
||||
0xE9,0x72,0x4B,0x10,0x22,0x17,0x7B,0x46,0x5D,0xAB,0x59,0x64,0xF3,0x40,0xAE,0xF8,
|
||||
0xBB,0xE5,0xC8,0xF9,0x26,0x03,0x4E,0x55,0x7D,0xEB,0xEB,0xFE,0xF7,0x39,0xE6,0xE0,
|
||||
0x0A,0x11,0xBE,0x2E,0x28,0xFF,0x98,0xED,0xC0,0xC9,0x42,0x56,0x42,0xC3,0xFD,0x00,
|
||||
0xF6,0xAF,0x87,0xA2,0x5B,0x01,0x3F,0x32,0x92,0x47,0x95,0x9A,0x72,0xA5,0x32,0x3D,
|
||||
0xAE,0x6B,0xD0,0x9B,0x07,0xD2,0x49,0x92,0xE3,0x78,0x4A,0xFA,0xA1,0x06,0x7D,0xF2,
|
||||
0x41,0xCF,0x77,0x74,0x04,0x14,0xB2,0x0C,0x86,0x84,0x64,0x16,0xD5,0xBB,0x51,0xA1,
|
||||
0xE5,0x6F,0xF1,0xD1,0xF2,0xE2,0xF7,0x5F,0x58,0x20,0x4D,0xB8,0x57,0xC7,0xCF,0xDD,
|
||||
0xC5,0xD8,0xBE,0x76,0x3D,0xF6,0x5F,0x7E,0xE7,0x2A,0x8B,0x88,0x24,0x1B,0x38,0x3F,
|
||||
0x0E,0x41,0x23,0x77,0xF5,0xF0,0x4B,0xD4,0x0C,0x1F,0xFA,0xA4,0x0B,0x80,0x5F,0xCF,
|
||||
0x45,0xF6,0xE0,0xDA,0x2F,0x34,0x59,0x53,0xFB,0x20,0x3C,0x52,0x62,0x5E,0x35,0xB5,
|
||||
0x62,0xFE,0x8B,0x60,0x63,0xE3,0x86,0x5A,0x15,0x1A,0x6E,0xD1,0x47,0x45,0xBC,0x32,
|
||||
0xB4,0xEB,0x67,0x38,0xAB,0xE4,0x6E,0x33,0x3A,0xB5,0xED,0xA3,0xAD,0x67,0xE0,0x4E,
|
||||
0x41,0x95,0xEE,0x62,0x62,0x71,0x26,0x1D,0x31,0xEF,0x62,0x30,0xAF,0xD7,0x82,0xAC,
|
||||
0xC2,0xDC,0x05,0x04,0xF5,0x97,0x07,0xBF,0x11,0x59,0x23,0x07,0xC0,0x64,0x02,0xE8,
|
||||
0x97,0xE5,0x3E,0xAF,0x18,0xAC,0x59,0xA6,0x8B,0x4A,0x33,0x90,0x1C,0x6E,0x7C,0x9C,
|
||||
0x20,0x7E,0x4C,0x3C,0x3E,0x61,0x64,0xBB,0xC5,0x6B,0x7C,0x7E,0x3E,0x9F,0xC5,0x4C,
|
||||
0x9F,0xEA,0x73,0xF5,0xD7,0x89,0xC0,0x4C,0xF4,0xFB,0xF4,0x2D,0xEC,0x14,0x1B,0x51,
|
||||
0xD5,0xC1,0x12,0xC8,0x10,0xDF,0x0B,0x4A,0x8B,0x9C,0xBC,0x93,0x45,0x6A,0x3E,0x3E,
|
||||
0x7D,0xC1,0xA9,0xBA,0xCD,0xC1,0xB4,0x07,0xE4,0xE1,0x68,0x86,0x43,0xB2,0x6D,0x38,
|
||||
0xF3,0xFB,0x0C,0x5C,0x66,0x37,0x71,0xDE,0x56,0xEF,0x6E,0xA0,0x10,0x40,0x65,0xA7,
|
||||
0x98,0xF7,0xD0,0xBE,0x0E,0xC8,0x37,0x36,0xEC,0x10,0xCA,0x7C,0x9C,0xAB,0x84,0x1E,
|
||||
0x05,0x17,0x76,0x02,0x1C,0x4F,0x52,0xAA,0x5F,0xC1,0xC6,0xA0,0x56,0xB9,0xD8,0x04,
|
||||
0x84,0x44,0x4D,0xA7,0x59,0xD8,0xDE,0x60,0xE6,0x38,0x0E,0x05,0x8F,0x03,0xE1,0x3B,
|
||||
0x6D,0x81,0x04,0x33,0x6F,0x30,0x0B,0xCE,0x69,0x05,0x21,0x33,0xFB,0x26,0xBB,0x89,
|
||||
0x7D,0xB6,0xAE,0x87,0x7E,0x51,0x07,0xE0,0xAC,0xF7,0x96,0x0A,0x6B,0xF9,0xC4,0x5C,
|
||||
0x1D,0xE4,0x44,0x47,0xB8,0x5E,0xFA,0xE3,0x78,0x84,0x55,0x42,0x4B,0x48,0x5E,0xF7,
|
||||
0x7D,0x47,0x35,0x86,0x1D,0x2B,0x43,0x05,0x03,0xEC,0x8A,0xB8,0x1E,0x06,0x3C,0x76,
|
||||
0x0C,0x48,0x1A,0x43,0xA7,0xB7,0x8A,0xED,0x1E,0x13,0xC6,0x43,0xEE,0x10,0xEF,0xDB,
|
||||
0xEC,0xFB,0x3C,0x83,0xB2,0x95,0x44,0xEF,0xD8,0x54,0x51,0x4E,0x2D,0x11,0x44,0x1D,
|
||||
0xFB,0x36,0x59,0x1E,0x7A,0x34,0xC1,0xC3,0xCA,0x57,0x00,0x61,0xEA,0x67,0xA5,0x16,
|
||||
0x9B,0x55,0xD0,0x55,0xE1,0x7F,0xD9,0x36,0xD2,0x40,0x76,0xAE,0xDC,0x01,0xCE,0xB0,
|
||||
0x7A,0x83,0xD5,0xCB,0x20,0x98,0xEC,0x6B,0xC1,0x72,0x92,0x34,0xF3,0x82,0x57,0x37,
|
||||
0x62,0x8A,0x32,0x36,0x0C,0x90,0x43,0xAE,0xAE,0x5C,0x9B,0x78,0x8E,0x13,0x65,0x02,
|
||||
0xFD,0x68,0x71,0xC1,0xFE,0xB0,0x31,0xA0,0x24,0x82,0xB0,0xC3,0xB1,0x79,0x69,0xA7,
|
||||
0xF5,0xD2,0xEB,0xD0,0x82,0xC0,0x32,0xDC,0x9E,0xC7,0x26,0x3C,0x6D,0x8D,0x98,0xC1,
|
||||
0xBB,0x22,0xD4,0xD0,0x0F,0x33,0xEC,0x3E,0xB9,0xCC,0xE1,0xDC,0x6A,0x4C,0x77,0x36,
|
||||
0x14,0x1C,0xF9,0xBF,0x81,0x9F,0x28,0x5F,0x71,0x85,0x32,0x29,0x90,0x75,0x48,0xC4,
|
||||
0xB3,0x4A,0xCE,0xD8,0x44,0x8F,0x14,0x2F,0xFD,0x40,0x57,0xEF,0xAA,0x08,0x75,0xD9,
|
||||
0x46,0xD1,0xD6,0x6E,0x32,0x55,0x1F,0xC3,0x18,0xFE,0x84,0x1F,0xFC,0x84,0xD5,0xFF,
|
||||
0x71,0x5E,0x1B,0x48,0xC3,0x86,0x95,0x0E,0x28,0x08,0x27,0xD3,0x38,0x83,0x71,0x7B,
|
||||
0x4C,0x80,0x63,0x54,0x9A,0x56,0xB0,0xAC,0xCF,0x80,0xCA,0x31,0x09,0xEF,0xFE,0xF3,
|
||||
0xBE,0xAF,0x24,0x7E,0xA6,0xFE,0x53,0x3F,0xC2,0x8D,0x4A,0x33,0x68,0xD1,0x22,0xA6,
|
||||
0x66,0xAD,0x7B,0xEA,0xDE,0xB6,0x43,0xB0,0xA1,0x25,0x95,0x00,0xA3,0x3F,0x75,0x46,
|
||||
0x14,0x11,0x44,0xEC,0xD7,0x95,0xBC,0x92,0xF0,0x4F,0xA9,0x16,0x53,0x62,0x97,0x60,
|
||||
0x2A,0x0F,0x41,0xF1,0x71,0x24,0xBE,0xEE,0x94,0x7F,0x08,0xCD,0x60,0x93,0xB3,0x85,
|
||||
0x5B,0x07,0x00,0x3F,0xD8,0x0F,0x28,0x83,0x9A,0xD1,0x69,0x9F,0xD1,0xDA,0x2E,0xC3,
|
||||
0x90,0x01,0xA2,0xB9,0x6B,0x4E,0x2A,0x66,0x9D,0xDA,0xAE,0xA6,0xEA,0x2A,0xD3,0x68,
|
||||
0x2F,0x0C,0x0C,0x9C,0xD2,0x8C,0x4A,0xED,0xE2,0x9E,0x57,0x65,0x9D,0x09,0x87,0xA3,
|
||||
0xB4,0xC4,0x32,0x5D,0xC9,0xD4,0x32,0x2B,0xB1,0xE0,0x71,0x1E,0x64,0x4D,0xE6,0x90,
|
||||
0x71,0xE3,0x1E,0x40,0xED,0x7D,0xF3,0x84,0x0E,0xED,0xC8,0x78,0x76,0xAE,0xC0,0x71,
|
||||
0x27,0x72,0xBB,0x05,0xEA,0x02,0x64,0xFB,0xF3,0x48,0x6B,0xB5,0x42,0x93,0x3F,0xED,
|
||||
0x9F,0x13,0x53,0xD2,0xF7,0xFE,0x2A,0xEC,0x1D,0x47,0x25,0xDB,0x3C,0x91,0x86,0xC6,
|
||||
0x8E,0xF0,0x11,0xFD,0x23,0x74,0x36,0xF7,0xA4,0xF5,0x9E,0x7A,0x7E,0x53,0x50,0x44,
|
||||
0xD4,0x47,0xCA,0xD3,0xEB,0x38,0x6D,0xE6,0xD9,0x71,0x94,0x7F,0x4A,0xC6,0x69,0x4B,
|
||||
0x11,0xF4,0x52,0xEA,0x22,0xFE,0x8A,0xB0,0x36,0x67,0x8B,0x59,0xE8,0xE6,0x80,0x2A,
|
||||
0xEB,0x65,0x04,0x13,0xEE,0xEC,0xDC,0x9E,0x5F,0xB1,0xEC,0x05,0x6A,0x59,0xE6,0x9F,
|
||||
0x5E,0x59,0x6B,0x89,0xBF,0xF7,0x1A,0xCA,0x44,0xF9,0x5B,0x6A,0x71,0x85,0x03,0xE4,
|
||||
0x29,0x62,0xE0,0x70,0x6F,0x41,0xC4,0xCF,0xB2,0xB1,0xCC,0xE3,0x7E,0xA6,0x07,0xA8,
|
||||
0x87,0xE7,0x7F,0x84,0x93,0xDB,0x52,0x4B,0x6C,0xEC,0x7E,0xDD,0xD4,0x24,0x48,0x10,
|
||||
0x69,0x9F,0x04,0x60,0x74,0xE6,0x48,0x18,0xF3,0xE4,0x2C,0xB9,0x4F,0x2E,0x50,0x7A,
|
||||
0xDF,0xD4,0x54,0x69,0x2B,0x8B,0xA7,0xF3,0xCE,0xFF,0x1F,0xF3,0x3E,0x26,0x01,0x39,
|
||||
0x17,0x95,0x84,0x89,0xB0,0xF0,0x4C,0x4B,0x82,0x91,0x9F,0xC4,0x4B,0xAC,0x9D,0xA5,
|
||||
0x74,0xAF,0x17,0x25,0xC9,0xCA,0x32,0xD3,0xBC,0x89,0x8A,0x84,0x89,0xCC,0x0D,0xAE,
|
||||
0x7C,0xA2,0xDB,0x9C,0x6A,0x78,0x91,0xEE,0xEA,0x76,0x5D,0x4E,0x87,0x60,0xF5,0x69,
|
||||
0x15,0x67,0xD4,0x02,0xCF,0xAF,0x48,0x36,0x07,0xEA,0xBF,0x6F,0x66,0x2D,0x06,0x8F,
|
||||
0xC4,0x9A,0xFE,0xF9,0xF6,0x90,0x87,0x75,0xB8,0xF7,0xAD,0x0F,0x76,0x10,0x5A,0x3D,
|
||||
0x59,0xB0,0x2E,0xB3,0xC7,0x35,0x2C,0xCC,0x70,0x56,0x2B,0xCB,0xE3,0x37,0x96,0xC5,
|
||||
0x2F,0x46,0x1B,0x8A,0x22,0x46,0xC7,0x88,0xA7,0x26,0x32,0x98,0x61,0xDF,0x86,0x22,
|
||||
0x8A,0xF4,0x1C,0x2F,0x87,0xA1,0x09,0xAA,0xCC,0xA9,0xAE,0xD3,0xBD,0x00,0x45,0x1C,
|
||||
0x9A,0x54,0x87,0x86,0x52,0x87,0xEF,0xFF,0x1E,0x8F,0xA1,0x8F,0xC1,0x89,0x5C,0x35,
|
||||
0x1B,0xDA,0x2D,0x3A,0x2C,0x16,0xB2,0xC2,0xF1,0x56,0xE2,0x78,0xC1,0x6B,0x63,0x97,
|
||||
0xC5,0x56,0x8F,0xC9,0x32,0x7F,0x2C,0xAA,0xAF,0xA6,0xA8,0xAC,0x20,0x91,0x22,0x88,
|
||||
0xDE,0xE4,0x60,0x8B,0xF9,0x4B,0x42,0x25,0x1A,0xE3,0x7F,0x9C,0x2C,0x19,0x89,0x3A,
|
||||
0x7E,0x05,0xD4,0x36,0xCC,0x69,0x58,0xC2,0xC1,0x32,0x8B,0x2F,0x90,0x85,0xEB,0x7A,
|
||||
0x39,0x50,0xA5,0xA1,0x27,0x92,0xC5,0x66,0xB0,0x20,0x4F,0x58,0x7E,0x55,0x83,0x43,
|
||||
0x2B,0x45,0xE2,0x9C,0xE4,0xD8,0x12,0x90,0x2C,0x16,0x83,0x56,0x16,0x79,0x03,0xB3,
|
||||
0xAD,0x2D,0x61,0x18,0x1A,0x13,0x1F,0x37,0xE2,0xE1,0x9C,0x73,0x7B,0x80,0xD5,0xFD,
|
||||
0x2D,0x51,0x87,0xFC,0x7B,0xAA,0xD7,0x1F,0x2C,0x7A,0x8E,0xAF,0xF4,0x8D,0xBB,0xCD,
|
||||
0x95,0x11,0x7C,0x72,0x0B,0xEE,0x6F,0xE2,0xB9,0xAF,0xDE,0x37,0x83,0xDE,0x8C,0x8D,
|
||||
0x62,0x05,0x67,0xB7,0x96,0xC6,0x8D,0x56,0xB6,0x0D,0xD7,0x62,0xBA,0xD6,0x46,0x36,
|
||||
0xBD,0x8E,0xC8,0xE6,0xEA,0x2A,0x6C,0x10,0x14,0xFF,0x6B,0x5B,0xFA,0x82,0x3C,0x46,
|
||||
0xB1,0x30,0x43,0x46,0x51,0x8A,0x7D,0x9B,0x92,0x3E,0x83,0x79,0x5B,0x55,0x5D,0xB2,
|
||||
0x6C,0x5E,0xCE,0x90,0x62,0x8E,0x53,0x98,0xC9,0x0D,0x6D,0xE5,0x2D,0x57,0xCD,0xC5,
|
||||
0x81,0x57,0xBA,0xE1,0xE8,0xB8,0x8F,0x72,0xE5,0x4F,0x13,0xDC,0xEA,0x9D,0x71,0x15,
|
||||
0x10,0xB2,0x11,0x88,0xD5,0x09,0xD4,0x7F,0x5B,0x65,0x7F,0x2C,0x3B,0x38,0x4C,0x11,
|
||||
0x68,0x50,0x8D,0xFB,0x9E,0xB0,0x59,0xBF,0x94,0x80,0x89,0x4A,0xC5,0x1A,0x18,0x12,
|
||||
0x89,0x53,0xD1,0x4A,0x10,0x29,0xE8,0x8C,0x1C,0xEC,0xB6,0xEA,0x46,0xC7,0x17,0x8B,
|
||||
0x25,0x15,0x31,0xA8,0xA2,0x6B,0x43,0xB1,0x9D,0xE2,0xDB,0x0B,0x87,0x9B,0xB0,0x11,
|
||||
0x04,0x0E,0x71,0xD2,0x29,0x77,0x89,0x82,0x0A,0x66,0x41,0x7F,0x1D,0x0B,0x48,0xFF,
|
||||
0x72,0xBB,0x24,0xFD,0xC2,0x48,0xA1,0x9B,0xFE,0x7B,0x7F,0xCE,0x88,0xDB,0x86,0xD9,
|
||||
0x85,0x3B,0x1C,0xB0,0xDC,0xA8,0x33,0x07,0xBF,0x51,0x2E,0xE3,0x0E,0x9A,0x00,0x97,
|
||||
0x1E,0x06,0xC0,0x97,0x43,0x9D,0xD8,0xB6,0x45,0xC4,0x86,0x67,0x5F,0x00,0xF8,0x88,
|
||||
0x9A,0xA4,0x52,0x9E,0xC7,0xAA,0x8A,0x83,0x75,0xEC,0xC5,0x18,0xAE,0xCE,0xC3,0x2F,
|
||||
0x1A,0x2B,0xF9,0x18,0xFF,0xAE,0x1A,0xF5,0x53,0x0B,0xB5,0x33,0x51,0xA7,0xFD,0xE8,
|
||||
0xA8,0xE1,0xA2,0x64,0xB6,0x22,0x17,0x43,0x80,0xCC,0x0A,0xD8,0xAE,0x3B,0xBA,0x40,
|
||||
0xD7,0xD9,0x92,0x4A,0x89,0xDF,0x04,0x10,0xEE,0x9B,0x18,0x2B,0x6A,0x77,0x69,0x8A,
|
||||
0x68,0xF4,0xF9,0xB9,0xA2,0x21,0x15,0x6E,0xE6,0x1E,0x3B,0x03,0x62,0x30,0x9B,0x60,
|
||||
0x41,0x7E,0x25,0x9B,0x9E,0x8F,0xC5,0x52,0x10,0x08,0xF8,0xC2,0x69,0xA1,0x21,0x11,
|
||||
0x88,0x37,0x5E,0x79,0x35,0x66,0xFF,0x10,0x42,0x18,0x6E,0xED,0x97,0xB6,0x6B,0x1C,
|
||||
0x4E,0x36,0xE5,0x6D,0x7D,0xB4,0xE4,0xBF,0x20,0xB9,0xE0,0x05,0x3A,0x69,0xD5,0xB8,
|
||||
0xE3,0xD5,0xDC,0xE0,0xB9,0xAC,0x53,0x3E,0x07,0xA4,0x57,0xAD,0x77,0xFF,0x48,0x18,
|
||||
0x76,0x2A,0xAC,0x49,0x2A,0x8E,0x47,0x75,0x6D,0x9F,0x67,0x63,0x30,0x35,0x8C,0x39,
|
||||
0x05,0x39,0xD5,0x6F,0x64,0x3A,0x5B,0xAD,0xCA,0x0B,0xBB,0x82,0x52,0x99,0x45,0xB1,
|
||||
0x93,0x36,0x36,0x99,0xAF,0x13,0x20,0x44,0x36,0xD8,0x02,0x44,0x09,0x39,0x92,0x85,
|
||||
0xFF,0x4A,0x4A,0x97,0x87,0xA6,0x63,0xD7,0xC7,0xB5,0xB5,0x24,0xED,0x0F,0xB4,0x6F,
|
||||
0x0C,0x58,0x52,0x14,0xD9,0xA6,0x7B,0xD3,0x79,0xBC,0x38,0x58,0xA1,0xBD,0x3B,0x84,
|
||||
0x06,0xD8,0x1A,0x06,0xFD,0x6B,0xA8,0xEA,0x4B,0x69,0x28,0x04,0x37,0xAD,0x82,0x99,
|
||||
0xFB,0x0E,0x1B,0x85,0xBD,0xA8,0x5D,0x73,0xCD,0xDC,0x58,0x75,0x0A,0xBE,0x63,0x6C,
|
||||
0x48,0xE7,0x4C,0xE4,0x30,0x2B,0x04,0x60,0xB9,0x15,0xD8,0xDA,0x86,0x81,0x75,0x8F,
|
||||
0x96,0xD4,0x8D,0x1C,0x5D,0x70,0x85,0x7C,0x1C,0x67,0x7B,0xD5,0x08,0x67,0xA6,0xCE,
|
||||
0x4B,0x0A,0x66,0x70,0xB7,0xE5,0x63,0xD4,0x5B,0x8A,0x82,0xEA,0x10,0x67,0xCA,0xE2,
|
||||
0xF4,0xEF,0x17,0x85,0x2F,0x2A,0x5F,0x8A,0x97,0x82,0xF8,0x6A,0xD6,0x34,0x10,0xEA,
|
||||
0xEB,0xC9,0x5C,0x3C,0xE1,0x49,0xF8,0x46,0xEB,0xDE,0xBD,0xF6,0xA9,0x92,0xF1,0xAA,
|
||||
0xA6,0xA0,0x18,0xB0,0x3A,0xD3,0x0F,0x1F,0xF3,0x6F,0xFF,0x31,0x45,0x43,0x44,0xD3,
|
||||
0x50,0x9A,0xF7,0x88,0x09,0x96,0xC1,0xCE,0x76,0xCC,0xF2,0x2C,0x2C,0xBA,0xAD,0x82,
|
||||
0x77,0x8F,0x18,0x84,0xC0,0xD2,0x07,0x9C,0x36,0x90,0x83,0x4E,0x0B,0xA5,0x4F,0x43,
|
||||
0x3E,0x04,0xAB,0x78,0x4F,0xD6,0xFB,0x09,0x01,0x24,0x90,0xDA,0x6F,0x3C,0x3A,0x61,
|
||||
0x0D,0x7F,0x69,0x4A,0xEB,0x2B,0x30,0x02,0xB4,0xDB,0xE0,0x84,0xA9,0xEC,0xD7,0x35,
|
||||
0xBF,0x37,0x7D,0x85,0x58,0xCE,0xA9,0x4E,0xE4,0x80,0xC7,0xA8,0xD3,0x30,0x67,0x48,
|
||||
0xEB,0x29,0xAF,0x2F,0x74,0x6A,0xB4,0xA7,0x3F,0x0F,0x3F,0x92,0xAF,0xF3,0xCA,0xAC,
|
||||
0xAF,0x4B,0xD9,0x94,0xC0,0x43,0xCA,0x81,0x0D,0x2F,0x48,0xA1,0xB0,0x27,0xD5,0xD2,
|
||||
0xEF,0x4B,0x05,0x85,0xA3,0xDE,0x4D,0x93,0x30,0x3C,0xF0,0xBB,0x4A,0x8F,0x30,0x27,
|
||||
0x4C,0xEB,0xE3,0x3E,0x64,0xED,0x9A,0x2F,0x3B,0xF1,0x82,0xF0,0xBA,0xF4,0xCF,0x7F,
|
||||
0x40,0xCB,0xB0,0xE1,0x7F,0xBC,0xAA,0x57,0xD3,0xC9,0x74,0xF2,0xFA,0x43,0x0D,0x22,
|
||||
0xD0,0xF4,0x77,0x4E,0x93,0xD7,0x85,0x70,0x1F,0x99,0xBF,0xB6,0xDE,0x35,0xF1,0x30,
|
||||
0xA7,0x5E,0x71,0xF0,0x6B,0x01,0x2D,0x7B,0x64,0xF0,0x33,0x53,0x0A,0x39,0x88,0xF3,
|
||||
0x6B,0x3A,0xA6,0x6B,0x35,0xD2,0x2F,0x43,0xCD,0x02,0xFD,0xB5,0xE9,0xBC,0x5B,0xAA,
|
||||
0xD8,0xA4,0x19,0x7E,0x0E,0x5D,0x94,0x81,0x9E,0x6F,0x77,0xAD,0xD6,0x0E,0x74,0x93,
|
||||
0x96,0xE7,0xC4,0x18,0x5F,0xAD,0xF5,0x19,
|
||||
};
|
350
BootLoaderTWL/source/key2.h
Normal file
350
BootLoaderTWL/source/key2.h
Normal file
@ -0,0 +1,350 @@
|
||||
const unsigned char gEncrDataTwl[] = {
|
||||
0x59, 0xaa, 0x56, 0x8e, 0x90, 0xd7, 0x11, 0x55, 0x4d, 0xea, 0xbf, 0xfe,
|
||||
0xbd, 0x0d, 0x75, 0x91, 0xf7, 0x85, 0x39, 0x98, 0xd0, 0x9c, 0xc3, 0x58,
|
||||
0xc4, 0x15, 0x6f, 0xf1, 0x90, 0xf9, 0xe4, 0xc3, 0x8e, 0xc0, 0x9b, 0x0e,
|
||||
0x5d, 0xe1, 0x87, 0x94, 0xb9, 0x07, 0x2c, 0xba, 0xa6, 0x4f, 0x75, 0x74,
|
||||
0xc1, 0xe3, 0x1c, 0x86, 0xe6, 0xed, 0xf8, 0x09, 0x3b, 0xbb, 0x37, 0x7a,
|
||||
0x4e, 0xf0, 0xf0, 0x92, 0xf6, 0x55, 0xfa, 0x47, 0xfb, 0x1b, 0xc5, 0x16,
|
||||
0x06, 0x74, 0x4e, 0x56, 0x20, 0xdd, 0xb6, 0xd1, 0x42, 0xcf, 0xcf, 0xf1,
|
||||
0x55, 0x7e, 0x17, 0x18, 0xa1, 0x93, 0xff, 0x09, 0xda, 0x36, 0xa6, 0x9a,
|
||||
0x43, 0x3d, 0xf4, 0x65, 0xed, 0x40, 0x97, 0x6c, 0xd5, 0xa6, 0xdd, 0x6d,
|
||||
0x6c, 0x23, 0xbf, 0x94, 0xe7, 0x51, 0xa6, 0x68, 0x3c, 0xe8, 0xe6, 0x65,
|
||||
0xd6, 0xbc, 0x9e, 0x92, 0x78, 0x26, 0x46, 0xa1, 0x73, 0xdc, 0xe5, 0x36,
|
||||
0x8e, 0xcd, 0xec, 0xa1, 0xf1, 0xee, 0x8b, 0x68, 0xf4, 0xac, 0xc1, 0xdc,
|
||||
0xc8, 0x84, 0x95, 0x31, 0xe8, 0xed, 0xc7, 0x5e, 0xe4, 0x5a, 0x37, 0xca,
|
||||
0xec, 0x55, 0xbe, 0x2a, 0xfc, 0xf6, 0x45, 0x67, 0xa9, 0xb4, 0x7d, 0x7d,
|
||||
0x9b, 0x6e, 0xe9, 0x2c, 0xff, 0x3f, 0xeb, 0x69, 0xb7, 0x2e, 0x68, 0xa8,
|
||||
0x94, 0xef, 0x7b, 0xbd, 0x88, 0x93, 0x15, 0x66, 0x3a, 0xb7, 0x7f, 0xfe,
|
||||
0x1d, 0xc3, 0x89, 0x08, 0xd7, 0x74, 0x59, 0xfa, 0xaf, 0x91, 0x41, 0x9e,
|
||||
0x57, 0xd5, 0x67, 0x84, 0xba, 0x00, 0xe9, 0x63, 0x58, 0x07, 0x4d, 0xec,
|
||||
0xdf, 0xc6, 0xda, 0x1e, 0x62, 0x52, 0xd9, 0x14, 0xbc, 0x03, 0xc3, 0xb0,
|
||||
0xa5, 0xfd, 0xb7, 0x27, 0xde, 0xb1, 0x6f, 0x1b, 0x7c, 0x72, 0x4a, 0xcd,
|
||||
0x09, 0xe5, 0x82, 0x70, 0xd3, 0x9f, 0xb6, 0xd6, 0xa4, 0x6a, 0x2f, 0xc2,
|
||||
0x32, 0xbd, 0xb5, 0x39, 0xe4, 0xea, 0xb9, 0x71, 0x1c, 0x70, 0x67, 0x21,
|
||||
0x92, 0x21, 0xac, 0xf4, 0x9e, 0x63, 0xe8, 0x5e, 0x83, 0x02, 0xcc, 0x0c,
|
||||
0xf8, 0xf8, 0x9e, 0x87, 0x89, 0xfc, 0x03, 0x85, 0xfa, 0xcc, 0x77, 0x07,
|
||||
0x44, 0x5f, 0x4d, 0xe5, 0x19, 0xd3, 0x12, 0xee, 0xca, 0xe1, 0xe0, 0xbf,
|
||||
0x1e, 0xbe, 0xe7, 0x12, 0x1f, 0x6a, 0x93, 0x1e, 0x38, 0x4b, 0xa7, 0x9f,
|
||||
0x81, 0xa9, 0x77, 0x85, 0x0c, 0xc6, 0x39, 0x02, 0x55, 0xd2, 0x62, 0x56,
|
||||
0x19, 0x85, 0xa6, 0x38, 0x85, 0xe1, 0x2d, 0x3c, 0x38, 0x3b, 0x5b, 0xa0,
|
||||
0x24, 0x18, 0xe9, 0x29, 0x6c, 0x9f, 0xe4, 0x4d, 0x4e, 0x23, 0x5f, 0xb1,
|
||||
0xe2, 0xa0, 0x6f, 0x97, 0xb2, 0x41, 0xd1, 0xea, 0xdb, 0xa7, 0x37, 0x81,
|
||||
0xeb, 0x06, 0x8d, 0x77, 0xc2, 0x68, 0xfc, 0x5a, 0x65, 0x97, 0x33, 0x58,
|
||||
0xa1, 0xb8, 0x35, 0x0f, 0xf4, 0x25, 0xbc, 0x3b, 0x4f, 0x18, 0x0f, 0x0e,
|
||||
0x60, 0x25, 0x3d, 0xd8, 0x77, 0x1a, 0xd0, 0x8a, 0xb0, 0x61, 0x57, 0x16,
|
||||
0x0b, 0x55, 0xf2, 0x58, 0xb9, 0x91, 0x52, 0x30, 0x33, 0xab, 0x29, 0x9b,
|
||||
0x03, 0x62, 0xe5, 0xcc, 0xdf, 0x6e, 0x62, 0x86, 0x9d, 0x76, 0xe5, 0xdd,
|
||||
0x6f, 0xca, 0x3e, 0x75, 0xd8, 0x88, 0x58, 0x06, 0x8d, 0xa4, 0x58, 0xf5,
|
||||
0xaa, 0x7c, 0xce, 0x17, 0xdd, 0xde, 0xca, 0x0a, 0x72, 0x87, 0x6f, 0x29,
|
||||
0x6c, 0x0c, 0xe9, 0xc0, 0x3d, 0x32, 0x2e, 0x55, 0xf3, 0xa7, 0x27, 0xda,
|
||||
0xfc, 0x86, 0x0c, 0x9e, 0x33, 0x83, 0xb5, 0x47, 0xeb, 0xe8, 0xf6, 0xc9,
|
||||
0xf4, 0x24, 0x72, 0xee, 0xaf, 0xf8, 0xb5, 0x59, 0x70, 0x06, 0x85, 0x71,
|
||||
0xbb, 0x3c, 0xbe, 0xbb, 0x2c, 0x24, 0xad, 0x67, 0xba, 0x42, 0xb9, 0xee,
|
||||
0x68, 0xec, 0x0b, 0xe6, 0x5b, 0x26, 0x0f, 0x2b, 0xb6, 0x3a, 0x93, 0x4f,
|
||||
0x9f, 0xe6, 0x9f, 0xb9, 0x1a, 0xa0, 0xb9, 0x51, 0x1c, 0x8d, 0x66, 0x37,
|
||||
0xd2, 0x50, 0xcc, 0xae, 0x10, 0x30, 0x16, 0x60, 0x56, 0x3b, 0x99, 0x0e,
|
||||
0x90, 0x7b, 0x28, 0xde, 0x93, 0xf4, 0x16, 0x87, 0x1f, 0xd0, 0x9b, 0xc2,
|
||||
0x33, 0x42, 0x2c, 0x2c, 0xf1, 0x36, 0xc3, 0x39, 0xf8, 0x4f, 0xa4, 0x1e,
|
||||
0x00, 0x43, 0xb1, 0xac, 0xdf, 0x08, 0xbb, 0xfe, 0x5e, 0x2a, 0xdc, 0x2a,
|
||||
0x10, 0xf3, 0x7b, 0xc5, 0x2f, 0x96, 0xc9, 0x1d, 0x51, 0x4f, 0xc0, 0xde,
|
||||
0x6e, 0x93, 0x9a, 0x35, 0x19, 0xb8, 0x58, 0xb5, 0x19, 0xba, 0xaf, 0x2a,
|
||||
0xb1, 0xb5, 0xb2, 0xff, 0xc1, 0x89, 0xbc, 0x3f, 0xd8, 0x8f, 0x34, 0x07,
|
||||
0x63, 0x60, 0xa5, 0xed, 0xdb, 0xff, 0x9e, 0xf5, 0x5b, 0x23, 0xc0, 0x1b,
|
||||
0x13, 0x96, 0xd4, 0x2f, 0x07, 0x51, 0x1b, 0xac, 0x90, 0x72, 0x71, 0x28,
|
||||
0x65, 0x98, 0xe1, 0xff, 0x6a, 0x9d, 0xe7, 0x30, 0x6d, 0xb1, 0x2c, 0x21,
|
||||
0xfa, 0xcb, 0xbc, 0x6a, 0x3c, 0x25, 0xe8, 0x50, 0x5c, 0x53, 0xd8, 0xd5,
|
||||
0xcb, 0xa2, 0x53, 0x53, 0xa5, 0x64, 0x3f, 0x78, 0x61, 0x77, 0x1d, 0x8d,
|
||||
0x16, 0xe4, 0xe4, 0xa1, 0x32, 0x9c, 0x00, 0x52, 0x5f, 0x2a, 0xd7, 0xf5,
|
||||
0x3c, 0xfd, 0x09, 0xd7, 0x1b, 0x3b, 0x99, 0x01, 0x4d, 0xdc, 0x91, 0xe4,
|
||||
0x6d, 0xe8, 0x9e, 0xa3, 0x18, 0xad, 0x43, 0x27, 0xba, 0xc1, 0x5f, 0x37,
|
||||
0xa6, 0x12, 0x61, 0xf5, 0x1c, 0x63, 0x0c, 0x25, 0x2d, 0x90, 0xf8, 0x52,
|
||||
0xcb, 0x2c, 0x37, 0x4b, 0xde, 0x1e, 0x6c, 0x36, 0x1d, 0x47, 0xf5, 0xdf,
|
||||
0x87, 0xca, 0x79, 0x98, 0x80, 0x09, 0x59, 0xd7, 0x14, 0xfd, 0xf7, 0xf9,
|
||||
0xf4, 0xce, 0x69, 0x23, 0xd2, 0xf8, 0xc4, 0xee, 0xa0, 0x7e, 0xf8, 0x36,
|
||||
0x8e, 0x35, 0x93, 0x45, 0x82, 0xae, 0x0d, 0xfc, 0x65, 0xbc, 0xaa, 0xf5,
|
||||
0x58, 0xa9, 0x65, 0xba, 0xc6, 0x08, 0x4b, 0x63, 0xc3, 0x3f, 0xa6, 0x8a,
|
||||
0xf4, 0xc1, 0x9b, 0x8f, 0x02, 0x45, 0x1b, 0x13, 0x78, 0x28, 0x9f, 0xd6,
|
||||
0x53, 0xb1, 0xc2, 0x7e, 0x4e, 0x71, 0x17, 0xe7, 0x55, 0x09, 0x62, 0xc7,
|
||||
0xad, 0xd5, 0x91, 0x1a, 0xc0, 0xfa, 0x49, 0x4a, 0xef, 0x00, 0xd6, 0xf6,
|
||||
0xf1, 0xd0, 0xc9, 0x40, 0x1b, 0xb1, 0xfd, 0x0e, 0xd3, 0x95, 0xf1, 0xcd,
|
||||
0x95, 0x60, 0x08, 0x73, 0xd2, 0xe0, 0x56, 0xfa, 0xd0, 0x65, 0x51, 0xfd,
|
||||
0xc4, 0x48, 0xd1, 0xaa, 0x5a, 0xba, 0xcb, 0x8f, 0x76, 0x22, 0xe3, 0x60,
|
||||
0x6f, 0x4a, 0x3c, 0x86, 0x35, 0xee, 0xe9, 0x88, 0x9a, 0x4a, 0x36, 0x34,
|
||||
0x74, 0xe3, 0x6d, 0x3f, 0xe4, 0x2a, 0x93, 0x0b, 0xe2, 0xc6, 0x47, 0x4d,
|
||||
0xf2, 0xb6, 0x8e, 0x78, 0x14, 0x91, 0x61, 0xcf, 0xfa, 0xb6, 0x1b, 0x39,
|
||||
0xca, 0x88, 0x0c, 0x04, 0x65, 0xd3, 0x3b, 0xd1, 0xc6, 0xda, 0xe5, 0xf4,
|
||||
0xe9, 0x1a, 0x38, 0x0f, 0xa5, 0xca, 0x32, 0x29, 0x78, 0x6c, 0x91, 0x9d,
|
||||
0xd8, 0xc1, 0x8c, 0x3d, 0x6e, 0x82, 0x49, 0x10, 0x38, 0x4c, 0x95, 0xe3,
|
||||
0xf1, 0x69, 0x30, 0x2e, 0x3e, 0xbf, 0xaf, 0x7d, 0x5e, 0x51, 0x3c, 0x6a,
|
||||
0x15, 0x04, 0xbd, 0x8f, 0xcf, 0xeb, 0x3f, 0xe0, 0xe0, 0xa7, 0xb3, 0x3e,
|
||||
0xf3, 0xf7, 0xd8, 0x1d, 0x15, 0x74, 0xef, 0x4e, 0x5b, 0xa0, 0x1e, 0x3a,
|
||||
0x45, 0xec, 0x98, 0x8b, 0xe4, 0x0c, 0xfb, 0x77, 0xfd, 0xcf, 0xde, 0x88,
|
||||
0x4d, 0x42, 0x18, 0x81, 0x14, 0x0d, 0xe2, 0x20, 0x4e, 0xcf, 0x0d, 0x3b,
|
||||
0xc8, 0x41, 0x36, 0x9d, 0x99, 0xab, 0x47, 0xcb, 0x55, 0xf0, 0x79, 0x77,
|
||||
0x32, 0x85, 0xa4, 0xe4, 0x11, 0x14, 0x42, 0x8d, 0x03, 0x8c, 0x76, 0xba,
|
||||
0x05, 0xcf, 0xe8, 0x40, 0x47, 0xcf, 0xbd, 0xe7, 0x22, 0xe6, 0x72, 0xce,
|
||||
0xa0, 0x13, 0xe4, 0x59, 0x5e, 0x68, 0xc2, 0x53, 0x7a, 0x4d, 0x4b, 0x4c,
|
||||
0xcd, 0xbf, 0xe2, 0xb0, 0xa3, 0x63, 0x77, 0xf2, 0x1e, 0xc3, 0x21, 0xca,
|
||||
0xd2, 0xb6, 0x7b, 0x01, 0x79, 0x02, 0x43, 0xec, 0x6d, 0x98, 0x97, 0x86,
|
||||
0x27, 0x41, 0x67, 0xe7, 0x04, 0xcf, 0x71, 0x0e, 0xfc, 0xc8, 0x3d, 0x32,
|
||||
0x99, 0x35, 0x4d, 0x2c, 0x94, 0xd7, 0x82, 0xb5, 0x2e, 0x20, 0x73, 0xd8,
|
||||
0xa4, 0xf9, 0xae, 0x6c, 0xd6, 0x12, 0x57, 0xe9, 0x44, 0x86, 0x6a, 0x9e,
|
||||
0xe0, 0x72, 0x84, 0x97, 0xb3, 0x8d, 0x56, 0x28, 0x66, 0xdb, 0xec, 0x25,
|
||||
0xbf, 0x01, 0x11, 0x76, 0x9b, 0xe1, 0x43, 0x8d, 0x6d, 0x0b, 0xfa, 0x3d,
|
||||
0x45, 0x15, 0x4a, 0xb4, 0xac, 0x76, 0x2a, 0x4a, 0xfb, 0x8d, 0xa5, 0x03,
|
||||
0xe4, 0x36, 0xe6, 0xd9, 0xfd, 0xc1, 0x20, 0x63, 0xe3, 0x5c, 0x9a, 0x0e,
|
||||
0x0f, 0x99, 0x49, 0xc6, 0x10, 0x9a, 0x08, 0x47, 0xff, 0x3d, 0xaa, 0x0c,
|
||||
0x9f, 0x46, 0x57, 0x5a, 0xe5, 0xc5, 0x24, 0xc5, 0xf1, 0xca, 0x1a, 0xa2,
|
||||
0xb0, 0x29, 0x78, 0xdd, 0x7a, 0x72, 0x49, 0x54, 0xac, 0xc4, 0x22, 0x04,
|
||||
0x97, 0xa2, 0xa1, 0x1a, 0x2f, 0x57, 0xfd, 0x9b, 0xaf, 0xc9, 0x30, 0x10,
|
||||
0x4a, 0xf4, 0x5e, 0x52, 0xf8, 0x25, 0x32, 0x48, 0xcb, 0x02, 0x6c, 0x3b,
|
||||
0xa7, 0xe3, 0xbd, 0xe9, 0x54, 0xd5, 0xbe, 0x46, 0x6b, 0xea, 0x0b, 0x43,
|
||||
0x13, 0x1d, 0x6f, 0x9c, 0xf5, 0xeb, 0x0e, 0xba, 0x28, 0x4f, 0x98, 0x84,
|
||||
0xb2, 0x19, 0x9c, 0xfe, 0xa0, 0x4a, 0xf6, 0x07, 0xcc, 0x0c, 0x8f, 0x75,
|
||||
0x6a, 0x16, 0xa1, 0x1c, 0x4e, 0x42, 0x51, 0xdc, 0x17, 0xb0, 0xa4, 0x2c,
|
||||
0x86, 0x87, 0x55, 0xf5, 0x7a, 0x5a, 0xd0, 0x0d, 0x4b, 0x9f, 0xb9, 0xcb,
|
||||
0xf3, 0x23, 0x5b, 0xaa, 0x81, 0x0e, 0x74, 0x56, 0x96, 0xbb, 0x65, 0x14,
|
||||
0x3e, 0xb2, 0x17, 0x53, 0x7e, 0x71, 0xf1, 0x9b, 0xfd, 0x1c, 0x5c, 0xfe,
|
||||
0xee, 0x6b, 0x58, 0xc7, 0xb5, 0x82, 0xed, 0x14, 0x47, 0xb0, 0x62, 0xe8,
|
||||
0xad, 0x34, 0x9c, 0xe6, 0x12, 0x29, 0x3b, 0x91, 0x2b, 0x83, 0xe6, 0x5c,
|
||||
0xd4, 0xf1, 0x5b, 0x7f, 0xe0, 0x58, 0xc8, 0x29, 0xa4, 0x17, 0x76, 0xa0,
|
||||
0x95, 0x9d, 0xb1, 0xad, 0xa1, 0x01, 0xa2, 0xce, 0xd0, 0xa3, 0x14, 0x1e,
|
||||
0xb7, 0x22, 0x98, 0x9d, 0xcd, 0x7f, 0x8c, 0xb8, 0x0f, 0x5b, 0x5b, 0x36,
|
||||
0x3f, 0xce, 0xca, 0xce, 0x5b, 0x54, 0x8b, 0xbd, 0xde, 0x82, 0x7e, 0xf1,
|
||||
0xf9, 0xa0, 0x30, 0xfe, 0xbd, 0xe7, 0x35, 0x84, 0x29, 0x1e, 0x41, 0x8e,
|
||||
0x55, 0x3f, 0xf7, 0x40, 0x23, 0xaa, 0x2d, 0x5a, 0xe5, 0xc4, 0x32, 0x9e,
|
||||
0xbf, 0x22, 0xb0, 0xc1, 0xe7, 0x8c, 0x7d, 0x5d, 0x0b, 0x28, 0xb4, 0x57,
|
||||
0x8e, 0xe7, 0x56, 0x3d, 0x1f, 0x35, 0x1e, 0x98, 0xa9, 0x0d, 0xd7, 0xb7,
|
||||
0x20, 0xe2, 0x89, 0x90, 0x04, 0xa7, 0x56, 0xea, 0x84, 0x16, 0x6f, 0xff,
|
||||
0xa9, 0x38, 0x5e, 0xa0, 0xaf, 0x2d, 0xc1, 0xb6, 0xc1, 0x77, 0x72, 0xe1,
|
||||
0x21, 0xc7, 0x2f, 0x3f, 0x85, 0x51, 0x4b, 0x83, 0xca, 0x33, 0x50, 0xb1,
|
||||
0x4c, 0x58, 0x0c, 0x54, 0x7c, 0x70, 0xfe, 0x23, 0xef, 0xc7, 0xc7, 0xaf,
|
||||
0xaf, 0xbf, 0xe5, 0x7b, 0x05, 0x90, 0x6c, 0x7a, 0x9f, 0x66, 0xb9, 0xc6,
|
||||
0x44, 0xd5, 0x99, 0x6c, 0xd5, 0xac, 0x74, 0xce, 0x00, 0x49, 0x4b, 0xcf,
|
||||
0x51, 0x01, 0xda, 0x24, 0xc5, 0x42, 0xba, 0x6f, 0x8a, 0x73, 0x20, 0x11,
|
||||
0xbc, 0x4a, 0x4f, 0xdb, 0xa6, 0x40, 0x27, 0xbc, 0x93, 0xa3, 0x30, 0xb2,
|
||||
0xcc, 0x6e, 0x78, 0xa0, 0x28, 0x7d, 0xe7, 0x34, 0x11, 0x4c, 0x00, 0x8b,
|
||||
0x04, 0x3d, 0x93, 0x7f, 0x2a, 0x3c, 0x67, 0x56, 0xad, 0xc5, 0xdd, 0x2a,
|
||||
0x75, 0xe1, 0x96, 0x02, 0x8d, 0x66, 0x0e, 0xd8, 0xc1, 0x83, 0xdf, 0x27,
|
||||
0x42, 0xc4, 0x47, 0x18, 0x24, 0xac, 0x99, 0x8b, 0x22, 0x28, 0x68, 0x74,
|
||||
0xb2, 0x7e, 0x58, 0x19, 0x19, 0xda, 0xd4, 0x96, 0x36, 0x26, 0xc7, 0x53,
|
||||
0x37, 0xdb, 0x53, 0xa5, 0xd3, 0x98, 0xb4, 0x65, 0x80, 0xde, 0x73, 0xcb,
|
||||
0x97, 0x7e, 0x59, 0x80, 0xf6, 0x25, 0x60, 0x6f, 0x77, 0x20, 0x4c, 0xc7,
|
||||
0x35, 0xc6, 0x80, 0xe3, 0x56, 0x2c, 0xba, 0x62, 0xf7, 0x56, 0xf9, 0x63,
|
||||
0x3e, 0xf9, 0x91, 0x7b, 0x9c, 0x35, 0x02, 0x04, 0xd8, 0x3d, 0x35, 0xfd,
|
||||
0xb7, 0x85, 0xba, 0x04, 0x19, 0x7f, 0xb9, 0xe6, 0x6a, 0x65, 0x51, 0x9e,
|
||||
0xde, 0x21, 0xec, 0xf0, 0x6b, 0xfd, 0x41, 0x90, 0xdc, 0x32, 0x08, 0x4d,
|
||||
0x9b, 0x43, 0x2a, 0x61, 0x5b, 0x35, 0x61, 0xc1, 0xfd, 0xa2, 0xde, 0x30,
|
||||
0xd3, 0x93, 0xc6, 0x0d, 0xad, 0x76, 0xac, 0xfb, 0xb0, 0xee, 0x85, 0x5f,
|
||||
0xde, 0x4e, 0x2b, 0xe8, 0x8f, 0x67, 0xa0, 0x12, 0x00, 0x3f, 0xcf, 0x04,
|
||||
0xe4, 0xb1, 0x2b, 0xa0, 0xda, 0xbb, 0x33, 0x5a, 0x58, 0x9b, 0x7c, 0x05,
|
||||
0xea, 0x2b, 0x7b, 0x40, 0x9c, 0xc3, 0xe0, 0x99, 0x9e, 0xe0, 0x91, 0x67,
|
||||
0xa5, 0x63, 0x6b, 0x9f, 0x15, 0xb6, 0x3c, 0xda, 0x17, 0x90, 0x8f, 0x05,
|
||||
0x7e, 0x61, 0x7c, 0xc7, 0x25, 0xdf, 0xbb, 0xd6, 0x96, 0xba, 0x45, 0xa8,
|
||||
0x84, 0xa0, 0x7d, 0x0f, 0x41, 0xdd, 0xba, 0xe5, 0x5a, 0x09, 0x3d, 0xe7,
|
||||
0x20, 0x22, 0xc6, 0x8e, 0x0d, 0xd5, 0xc5, 0x75, 0x38, 0x8c, 0x6e, 0x4f,
|
||||
0xa0, 0x42, 0xf7, 0x5e, 0xb1, 0x35, 0xe5, 0xfc, 0x93, 0x13, 0x58, 0x2b,
|
||||
0xa7, 0xe0, 0xfe, 0xff, 0x1a, 0xdd, 0x30, 0x27, 0x9e, 0x69, 0xdd, 0x05,
|
||||
0x18, 0xf7, 0x23, 0x5d, 0x9c, 0x64, 0xbe, 0x47, 0xf0, 0xa8, 0xe1, 0xf5,
|
||||
0xde, 0x67, 0x8a, 0xcc, 0x18, 0xed, 0x4a, 0x76, 0xa0, 0x23, 0x96, 0x55,
|
||||
0xd0, 0x84, 0x22, 0xce, 0xe1, 0xe2, 0x11, 0x80, 0x95, 0x61, 0x0d, 0x75,
|
||||
0x12, 0x86, 0xb9, 0x3c, 0x10, 0x9d, 0x4d, 0x39, 0x93, 0x42, 0x7d, 0x83,
|
||||
0xa5, 0xf4, 0xe4, 0xaa, 0x9b, 0x59, 0x22, 0x5e, 0xd3, 0xfd, 0xad, 0xf9,
|
||||
0xa0, 0xf2, 0xb2, 0x70, 0x86, 0x29, 0xcd, 0x71, 0x61, 0x98, 0xb8, 0x21,
|
||||
0x15, 0x5d, 0xf5, 0xde, 0x4d, 0x65, 0x27, 0x09, 0x8c, 0xed, 0xd0, 0xc8,
|
||||
0xe7, 0xed, 0x0b, 0x0c, 0x13, 0x9e, 0x78, 0xea, 0xf8, 0x3c, 0x10, 0xda,
|
||||
0xcd, 0xfc, 0xaf, 0x33, 0x96, 0x62, 0x31, 0x9c, 0xb6, 0x9d, 0xc8, 0x7a,
|
||||
0x35, 0xe6, 0xff, 0x75, 0xa8, 0x30, 0x98, 0xd4, 0xaa, 0xcf, 0x9c, 0xef,
|
||||
0xda, 0xb9, 0x64, 0xe8, 0x3b, 0xa6, 0x2f, 0xc1, 0xbd, 0x7e, 0x6b, 0xfc,
|
||||
0x1a, 0xef, 0x62, 0xad, 0x90, 0x5e, 0x7d, 0x29, 0x12, 0x4d, 0x76, 0x86,
|
||||
0x5c, 0x29, 0x7c, 0x61, 0x1d, 0x1e, 0x63, 0x97, 0x21, 0xcd, 0x77, 0xbd,
|
||||
0xc2, 0x32, 0x45, 0xca, 0x7a, 0xdc, 0x0b, 0x16, 0xa4, 0x10, 0xac, 0x37,
|
||||
0xba, 0xf5, 0xf6, 0xbc, 0x26, 0x66, 0x67, 0x2b, 0xb8, 0x2e, 0x22, 0xc0,
|
||||
0xea, 0x90, 0x78, 0xf0, 0x0d, 0x0f, 0x80, 0x69, 0x60, 0xd2, 0x89, 0xa5,
|
||||
0x1a, 0xb0, 0xcf, 0x5e, 0x57, 0x6f, 0x79, 0xdc, 0xd8, 0x2c, 0x51, 0x92,
|
||||
0xd6, 0x62, 0x41, 0xf9, 0xf7, 0x26, 0xf0, 0x59, 0x93, 0xe2, 0x76, 0x82,
|
||||
0x21, 0xf6, 0xab, 0x7a, 0xd2, 0x7b, 0x81, 0xcb, 0x8c, 0xe8, 0x87, 0x77,
|
||||
0x76, 0xce, 0xf2, 0xaa, 0x00, 0xdc, 0xec, 0xd1, 0xc1, 0x8d, 0xf8, 0x42,
|
||||
0x41, 0x8c, 0x35, 0xd1, 0x70, 0x97, 0xf4, 0x82, 0x2f, 0x3a, 0x2f, 0x4a,
|
||||
0x18, 0x8f, 0xac, 0x41, 0xfa, 0x29, 0xc2, 0x9d, 0x0a, 0xfa, 0x0c, 0x44,
|
||||
0xdd, 0xea, 0xc6, 0x2b, 0xd3, 0x2e, 0x28, 0xee, 0xca, 0x6e, 0x84, 0x90,
|
||||
0xec, 0xaf, 0xf4, 0x8f, 0xbd, 0xc7, 0xd1, 0x2d, 0xf6, 0x9a, 0xd2, 0x00,
|
||||
0xaa, 0x5c, 0x38, 0xc5, 0x11, 0x43, 0x7c, 0xf4, 0x0d, 0xbd, 0x57, 0x6d,
|
||||
0x42, 0x62, 0xa5, 0xd8, 0x05, 0xa7, 0xe9, 0x30, 0xc0, 0x81, 0x9b, 0xfc,
|
||||
0x30, 0xda, 0x16, 0x2f, 0x54, 0x61, 0x08, 0xaa, 0xf7, 0xc0, 0x1e, 0x4d,
|
||||
0xf2, 0xd4, 0xed, 0x5c, 0x96, 0x30, 0xad, 0x9f, 0xc5, 0xe3, 0xf0, 0x91,
|
||||
0xff, 0xf0, 0xb1, 0xe4, 0x93, 0x7b, 0x67, 0x11, 0xba, 0xef, 0xb7, 0xf4,
|
||||
0x29, 0x93, 0x6d, 0x32, 0x1f, 0x88, 0xd1, 0x6c, 0x7c, 0x5a, 0x7e, 0x0a,
|
||||
0xef, 0x6a, 0xe9, 0x23, 0x2c, 0xde, 0x4c, 0x68, 0x36, 0xcb, 0xaa, 0x1f,
|
||||
0xd3, 0x71, 0xce, 0x31, 0x8b, 0x2b, 0x51, 0x16, 0xe6, 0x65, 0xd1, 0x30,
|
||||
0xaf, 0xb8, 0xbe, 0x02, 0x21, 0x61, 0x36, 0xbc, 0x19, 0x7c, 0x0e, 0x9d,
|
||||
0x9c, 0xd6, 0xa9, 0xc7, 0x5c, 0x2f, 0xb6, 0x23, 0x4b, 0x64, 0x3b, 0x99,
|
||||
0x74, 0x83, 0x51, 0xda, 0x3e, 0xf8, 0xcf, 0x0f, 0xa3, 0x7a, 0xfb, 0xaa,
|
||||
0xd1, 0xe2, 0x09, 0x05, 0x3a, 0xf5, 0xa8, 0x61, 0x51, 0x59, 0xf6, 0xb3,
|
||||
0x3d, 0xe9, 0xa3, 0xc7, 0x3a, 0xe6, 0xff, 0x2d, 0x96, 0xaf, 0xe4, 0x41,
|
||||
0xb8, 0x7d, 0xca, 0xdf, 0x42, 0x16, 0x5c, 0xee, 0xd0, 0x9d, 0xa3, 0x74,
|
||||
0xa9, 0xae, 0xfd, 0x6d, 0x3b, 0x15, 0xb9, 0x89, 0x19, 0xa8, 0xf8, 0x48,
|
||||
0xfe, 0x3a, 0xf6, 0xd7, 0x44, 0x4b, 0x96, 0x07, 0x37, 0x4b, 0xf9, 0x33,
|
||||
0x62, 0x4f, 0x08, 0x38, 0xfc, 0x02, 0xfc, 0x8d, 0x3d, 0x65, 0x83, 0x02,
|
||||
0xed, 0xd7, 0x48, 0x40, 0x51, 0x99, 0x0a, 0x20, 0xb2, 0xda, 0x9d, 0xca,
|
||||
0xbf, 0xb7, 0xcf, 0xa8, 0x32, 0x67, 0x2f, 0x31, 0xa3, 0x00, 0xe3, 0xcb,
|
||||
0x09, 0x7e, 0x0a, 0xb0, 0x7a, 0x34, 0x7b, 0xfc, 0x1d, 0x97, 0x8c, 0xa6,
|
||||
0x17, 0xcb, 0x62, 0xc7, 0x28, 0xf4, 0xb8, 0x21, 0xdb, 0x51, 0xc9, 0xef,
|
||||
0x69, 0xb6, 0xac, 0x36, 0x90, 0x74, 0x90, 0xb7, 0xdb, 0xcb, 0xfd, 0xdb,
|
||||
0x17, 0x81, 0xed, 0x94, 0x4d, 0xe5, 0x4e, 0xe5, 0xf6, 0x01, 0x4a, 0x99,
|
||||
0x9f, 0x5e, 0xe0, 0x45, 0x70, 0x41, 0x45, 0xa2, 0x2b, 0x4e, 0xd6, 0xab,
|
||||
0xdc, 0x06, 0x15, 0x2d, 0x48, 0x88, 0x17, 0x43, 0x39, 0x94, 0xb4, 0x3a,
|
||||
0x23, 0xce, 0xbb, 0xda, 0x0e, 0xb0, 0x5c, 0x1e, 0x0d, 0x0b, 0x31, 0x8e,
|
||||
0x9b, 0x04, 0x80, 0x78, 0x75, 0x1c, 0x9b, 0x97, 0xac, 0xc7, 0xad, 0xde,
|
||||
0x2b, 0x7f, 0x48, 0xb2, 0x29, 0xae, 0x76, 0x59, 0x27, 0xee, 0x79, 0xb8,
|
||||
0x8e, 0x30, 0xe7, 0xf2, 0x84, 0x44, 0x40, 0x79, 0x25, 0xce, 0x13, 0x87,
|
||||
0x8e, 0xfa, 0x08, 0x18, 0x8d, 0x71, 0xac, 0xeb, 0xf2, 0x7c, 0xa6, 0x69,
|
||||
0x29, 0x1b, 0xd8, 0x02, 0xea, 0x64, 0x40, 0x7d, 0xa1, 0xb2, 0x05, 0xd3,
|
||||
0x2b, 0x9d, 0x98, 0xa4, 0x2c, 0xee, 0xc9, 0x2c, 0x52, 0x5a, 0xd9, 0x3e,
|
||||
0xd4, 0xcc, 0x6b, 0xf5, 0x11, 0x4a, 0x0a, 0x84, 0x4b, 0x6e, 0xa4, 0xab,
|
||||
0x16, 0x46, 0x31, 0xb2, 0x84, 0x32, 0x43, 0x43, 0xe3, 0x21, 0x09, 0x33,
|
||||
0x53, 0x9d, 0x93, 0x60, 0xd4, 0x18, 0xef, 0x71, 0xc8, 0xd1, 0x97, 0x2b,
|
||||
0x2d, 0xa0, 0xe3, 0xc3, 0xb7, 0x54, 0x5b, 0xa2, 0xbf, 0x92, 0xa0, 0x48,
|
||||
0x15, 0xef, 0x8e, 0x25, 0x02, 0x49, 0x35, 0x20, 0x9e, 0x1b, 0x52, 0xfa,
|
||||
0xf9, 0x33, 0x99, 0x31, 0x2c, 0x1b, 0x04, 0x92, 0x8d, 0x19, 0xdb, 0x7d,
|
||||
0xad, 0x61, 0x29, 0xe3, 0x5c, 0xb7, 0x94, 0xa6, 0x8b, 0x2e, 0xc5, 0x2e,
|
||||
0xbd, 0xe0, 0x60, 0xae, 0xea, 0x93, 0x08, 0x64, 0x98, 0x9e, 0x8e, 0xa1,
|
||||
0x2e, 0xf1, 0xe0, 0x31, 0x57, 0x87, 0xd4, 0x77, 0x81, 0x6d, 0xf5, 0xa6,
|
||||
0x4c, 0x9b, 0x89, 0x8d, 0x08, 0x96, 0xc5, 0x96, 0xbe, 0x59, 0xcc, 0xbd,
|
||||
0x58, 0x7b, 0x21, 0x08, 0x19, 0xc0, 0x55, 0x33, 0x80, 0x44, 0x0d, 0x8e,
|
||||
0x59, 0xf9, 0xe8, 0x00, 0x50, 0x98, 0xa2, 0x30, 0xa6, 0xfd, 0xa8, 0x46,
|
||||
0xc5, 0x05, 0x65, 0x59, 0xe7, 0x25, 0x1a, 0x17, 0x32, 0x8a, 0xc0, 0x2a,
|
||||
0x15, 0x7e, 0x69, 0x11, 0xe9, 0x6d, 0xff, 0x96, 0x52, 0x98, 0xa3, 0xfa,
|
||||
0x43, 0x7b, 0x33, 0x79, 0x56, 0xc4, 0xe3, 0x27, 0x40, 0xd6, 0x33, 0xea,
|
||||
0xac, 0x87, 0x4e, 0x74, 0xbb, 0xe0, 0x52, 0xab, 0x56, 0x8a, 0xed, 0x3e,
|
||||
0xd2, 0x25, 0xb2, 0xbe, 0x58, 0x4c, 0xdf, 0x0e, 0x8f, 0xca, 0x57, 0xdc,
|
||||
0x00, 0xfa, 0xb0, 0xc0, 0xf3, 0x7b, 0x6e, 0x41, 0x17, 0x07, 0xcb, 0x08,
|
||||
0xe3, 0xd8, 0xa5, 0x04, 0xdb, 0x42, 0x99, 0x67, 0x73, 0xd5, 0xd7, 0x1f,
|
||||
0x22, 0x9e, 0xea, 0x66, 0x5f, 0x44, 0x7d, 0xf4, 0xbf, 0x50, 0xb2, 0x3e,
|
||||
0x2f, 0x9f, 0x7a, 0xca, 0x80, 0x95, 0x59, 0x83, 0x69, 0x05, 0xec, 0x70,
|
||||
0x71, 0x12, 0x97, 0xaf, 0xdb, 0xfd, 0xe8, 0x11, 0x44, 0x8a, 0x6e, 0x09,
|
||||
0x90, 0xd5, 0x59, 0x8c, 0x6a, 0x65, 0xf9, 0xa9, 0x3d, 0x3c, 0x0c, 0xf3,
|
||||
0x2f, 0xa0, 0xb1, 0x8e, 0xf0, 0x3f, 0x16, 0x63, 0xf6, 0xe8, 0x80, 0x27,
|
||||
0x64, 0x56, 0x99, 0x94, 0x93, 0xc8, 0x36, 0x00, 0x21, 0xeb, 0x7c, 0x41,
|
||||
0x86, 0xae, 0xb2, 0x4b, 0x7d, 0xac, 0xac, 0x90, 0x8b, 0x99, 0x18, 0x25,
|
||||
0xa4, 0x0d, 0x9c, 0x96, 0x53, 0x0c, 0xfa, 0x7e, 0x61, 0xba, 0x7f, 0xca,
|
||||
0x61, 0x7b, 0xba, 0x2f, 0x96, 0x2f, 0x75, 0x29, 0x84, 0xb7, 0x32, 0xca,
|
||||
0x3b, 0x1f, 0xe6, 0x57, 0x34, 0xf3, 0xf1, 0x58, 0x61, 0xc9, 0x04, 0xa2,
|
||||
0x20, 0xea, 0x77, 0xa7, 0x83, 0xed, 0x3e, 0x14, 0x87, 0x8f, 0x82, 0x86,
|
||||
0x88, 0xc3, 0xf9, 0x10, 0x7e, 0x03, 0xa4, 0x33, 0xe0, 0x4e, 0x97, 0xef,
|
||||
0x66, 0x91, 0x9f, 0xce, 0x85, 0xc8, 0xca, 0x04, 0x3a, 0x8b, 0xf6, 0xc7,
|
||||
0xdf, 0xeb, 0x75, 0x31, 0xf4, 0x1a, 0x9a, 0x67, 0xc7, 0xb1, 0xd0, 0x33,
|
||||
0x97, 0xea, 0xd2, 0x52, 0xc3, 0x81, 0xdb, 0x63, 0x64, 0x31, 0x0f, 0x9e,
|
||||
0x75, 0x5f, 0xde, 0xe7, 0x46, 0x01, 0x19, 0x03, 0xe5, 0x0b, 0xf8, 0x9f,
|
||||
0xab, 0x4f, 0x1a, 0x1f, 0xe0, 0xb0, 0x75, 0x96, 0xf2, 0x15, 0x49, 0x63,
|
||||
0xa7, 0xae, 0x26, 0xe5, 0x41, 0x82, 0x1b, 0x1e, 0xd0, 0x8b, 0x2e, 0xcc,
|
||||
0xf7, 0x30, 0xb3, 0xb5, 0x1b, 0xd9, 0xe7, 0x65, 0x1e, 0x60, 0x3b, 0x74,
|
||||
0xfa, 0x52, 0x03, 0xe9, 0x0f, 0x45, 0x87, 0x8c, 0x1a, 0x4d, 0x0d, 0xb9,
|
||||
0x90, 0xec, 0xa3, 0x59, 0xad, 0xa2, 0x33, 0xfb, 0xd3, 0xac, 0xf0, 0x58,
|
||||
0x0c, 0x6f, 0x27, 0xa9, 0x1b, 0x18, 0xcb, 0x5d, 0x70, 0xcd, 0x14, 0xd9,
|
||||
0xe3, 0x9f, 0x42, 0xf7, 0x82, 0x3e, 0x47, 0x39, 0xe4, 0xa2, 0x9e, 0x03,
|
||||
0x7c, 0x2f, 0x5d, 0x18, 0x55, 0x20, 0x63, 0x68, 0x38, 0xc8, 0x0b, 0x3d,
|
||||
0xf3, 0xc7, 0x91, 0x72, 0x70, 0x4c, 0x8a, 0x0d, 0xc0, 0x80, 0x7d, 0xde,
|
||||
0xa3, 0x7f, 0x0a, 0x54, 0xb5, 0xd0, 0x49, 0x42, 0xc3, 0x27, 0x69, 0x19,
|
||||
0x1c, 0xbc, 0xf9, 0x5e, 0x16, 0x19, 0xab, 0xdb, 0x99, 0x1e, 0x90, 0x8c,
|
||||
0x6e, 0xb9, 0x17, 0x95, 0xad, 0xde, 0x70, 0x93, 0x7f, 0x5f, 0x26, 0xb0,
|
||||
0x9f, 0x86, 0xb3, 0x82, 0x9d, 0x30, 0x24, 0x19, 0x83, 0x7d, 0x20, 0x70,
|
||||
0x29, 0xe1, 0xb3, 0x22, 0x99, 0xb5, 0xef, 0x8f, 0x7a, 0x66, 0xbc, 0x86,
|
||||
0x18, 0x85, 0x39, 0x56, 0x9b, 0x5f, 0xf6, 0x63, 0xc8, 0x24, 0xbc, 0x54,
|
||||
0xc3, 0xc3, 0xa3, 0x27, 0xad, 0x80, 0xa9, 0x8f, 0x3b, 0x4b, 0xa0, 0x08,
|
||||
0xcc, 0xf9, 0xde, 0x0b, 0x92, 0xa3, 0x26, 0x79, 0x42, 0xa2, 0xd0, 0x7c,
|
||||
0xd4, 0x2e, 0x8f, 0x63, 0x4b, 0xaf, 0x6b, 0x7a, 0x58, 0x99, 0xb2, 0xb4,
|
||||
0x01, 0x55, 0x75, 0x4a, 0xca, 0x9d, 0xd7, 0x85, 0xa8, 0x28, 0x97, 0x3d,
|
||||
0xa6, 0x3c, 0xd1, 0xf6, 0x97, 0xd4, 0x15, 0x45, 0xc4, 0x25, 0x48, 0xd5,
|
||||
0xa6, 0x10, 0x00, 0xa4, 0x3e, 0xc4, 0xb4, 0x1d, 0x08, 0xf0, 0xf7, 0x6d,
|
||||
0x91, 0xc9, 0xc4, 0x4e, 0xb5, 0xd5, 0x45, 0x07, 0x3e, 0x05, 0x34, 0x44,
|
||||
0x14, 0xe1, 0x11, 0x1e, 0xa2, 0xba, 0x37, 0x18, 0xea, 0x16, 0x78, 0x58,
|
||||
0x83, 0xfd, 0x98, 0x42, 0xd3, 0x83, 0xac, 0x77, 0x65, 0xc9, 0x5b, 0x36,
|
||||
0x8b, 0x9d, 0x76, 0x25, 0x5d, 0xfc, 0x80, 0x21, 0x0e, 0xd8, 0xcb, 0xc4,
|
||||
0xcc, 0x59, 0x4e, 0x85, 0x51, 0x3b, 0xc0, 0xa8, 0x0b, 0x5d, 0x60, 0xa2,
|
||||
0xc3, 0x2f, 0x2e, 0x8a, 0x18, 0x3c, 0x9d, 0x18, 0x0d, 0xd5, 0xa7, 0x32,
|
||||
0x72, 0xf0, 0xef, 0xdf, 0xa4, 0x35, 0x09, 0x75, 0x2f, 0xb0, 0xe0, 0xec,
|
||||
0xb2, 0x2d, 0x54, 0xeb, 0x22, 0x01, 0x67, 0x73, 0x61, 0x2d, 0x00, 0x8e,
|
||||
0x2a, 0x59, 0xc5, 0xa0, 0xf1, 0xb4, 0x20, 0x15, 0xeb, 0xe5, 0x0b, 0x7d,
|
||||
0x6b, 0x70, 0x45, 0x64, 0x3a, 0xc6, 0xbf, 0x34, 0x6a, 0x33, 0x35, 0xf2,
|
||||
0x88, 0x47, 0x4d, 0x95, 0x3d, 0x76, 0x7c, 0x56, 0x7a, 0x6a, 0x72, 0x48,
|
||||
0xa9, 0x28, 0x32, 0xf6, 0x25, 0xf5, 0x2a, 0x52, 0x40, 0x70, 0x46, 0x93,
|
||||
0x4e, 0x86, 0x58, 0xde, 0x11, 0x66, 0x2f, 0xa6, 0x75, 0xbd, 0x24, 0x05,
|
||||
0x3c, 0x5e, 0xf4, 0xbc, 0x88, 0xda, 0x69, 0xd0, 0x9d, 0x7f, 0xfa, 0x6b,
|
||||
0xf4, 0x50, 0x51, 0x03, 0x26, 0xf6, 0xaa, 0x11, 0xa6, 0x3d, 0x2a, 0xa3,
|
||||
0x18, 0x0e, 0xb1, 0x0b, 0x8c, 0x5a, 0x3a, 0xc4, 0x14, 0xd3, 0x9b, 0xea,
|
||||
0x2f, 0xf9, 0x5f, 0xbc, 0x9a, 0x94, 0x92, 0x2b, 0xaa, 0xf7, 0x62, 0x0c,
|
||||
0xf0, 0xf9, 0xcc, 0x20, 0x1b, 0x5b, 0x56, 0xed, 0xe4, 0x5f, 0xef, 0xa0,
|
||||
0x5d, 0xe2, 0xe7, 0x50, 0x0d, 0x13, 0x92, 0x7f, 0x70, 0x68, 0x81, 0x3c,
|
||||
0x5d, 0x71, 0x12, 0x14, 0xba, 0xe9, 0xf1, 0x24, 0x70, 0xc3, 0xea, 0x3a,
|
||||
0x8e, 0x19, 0xab, 0x4f, 0x5f, 0x20, 0x38, 0xcb, 0xd8, 0x91, 0x3d, 0x47,
|
||||
0x8a, 0xb8, 0xe0, 0x81, 0x73, 0x57, 0x19, 0xc4, 0xb6, 0xd7, 0x6e, 0x01,
|
||||
0xad, 0xb7, 0x80, 0xb2, 0x44, 0xe7, 0x77, 0x3a, 0x55, 0x9f, 0x36, 0x77,
|
||||
0x4c, 0x88, 0x69, 0x6b, 0xc6, 0x67, 0x2f, 0xbd, 0x37, 0x0c, 0xf2, 0x9f,
|
||||
0x88, 0x6e, 0xa6, 0xa0, 0xd7, 0x5a, 0x53, 0xf3, 0xc0, 0xaa, 0x7b, 0xca,
|
||||
0xc3, 0x07, 0xf4, 0x08, 0xc9, 0x84, 0x0c, 0x36, 0x49, 0x15, 0x71, 0x8c,
|
||||
0x60, 0x6f, 0xd5, 0x91, 0xc5, 0x3a, 0x33, 0x3b, 0xde, 0x8c, 0xe0, 0xf4,
|
||||
0x08, 0x42, 0x6d, 0xf7, 0x3b, 0xae, 0xd0, 0x06, 0xe5, 0x1b, 0x60, 0x24,
|
||||
0xc4, 0xaa, 0xcf, 0x54, 0x0e, 0x78, 0xa6, 0xf9, 0x40, 0x3b, 0xca, 0xed,
|
||||
0x5f, 0xa4, 0xd3, 0x13, 0x6e, 0x0a, 0x59, 0x3c, 0xda, 0xdb, 0xc6, 0x6f,
|
||||
0x8f, 0x89, 0x31, 0x8c, 0x87, 0x1e, 0xfe, 0x01, 0x16, 0x5b, 0xac, 0x1a,
|
||||
0x62, 0x85, 0x39, 0x61, 0xe1, 0x4c, 0xae, 0xae, 0x85, 0xd9, 0x5d, 0x9c,
|
||||
0x2a, 0x6e, 0x6b, 0xec, 0xef, 0x2b, 0xc6, 0x32, 0xd6, 0x62, 0x7e, 0x46,
|
||||
0x67, 0xe8, 0x6f, 0x4a, 0x50, 0x05, 0x75, 0xda, 0xe0, 0x6b, 0x47, 0xb6,
|
||||
0x2a, 0x48, 0x56, 0x3e, 0x22, 0x18, 0xfb, 0xf5, 0x66, 0xf1, 0x42, 0xd6,
|
||||
0xf3, 0x3d, 0x26, 0xc8, 0x44, 0xea, 0xa7, 0x9f, 0x90, 0xd8, 0x8f, 0xeb,
|
||||
0x45, 0x50, 0x99, 0xf8, 0x86, 0x5f, 0x70, 0x03, 0x89, 0x06, 0x08, 0x92,
|
||||
0x02, 0x6a, 0x93, 0x90, 0xce, 0xf2, 0xb5, 0x06, 0x78, 0x1e, 0x96, 0x1d,
|
||||
0xa2, 0x20, 0x27, 0x90, 0xfc, 0x07, 0x50, 0x84, 0xf8, 0x19, 0xd0, 0xb1,
|
||||
0x0c, 0x75, 0xb6, 0x3b, 0xb2, 0xaa, 0x73, 0x34, 0x49, 0xc9, 0xb2, 0xc2,
|
||||
0x58, 0x7e, 0x40, 0x19, 0xa6, 0x08, 0x6b, 0x9e, 0x87, 0xce, 0x7a, 0x27,
|
||||
0x3d, 0x7e, 0xe3, 0xe4, 0x12, 0x7c, 0x39, 0x24, 0x16, 0x80, 0x97, 0xbb,
|
||||
0x94, 0x9e, 0xa6, 0x0f, 0x5f, 0x42, 0xa1, 0xca, 0x37, 0xa0, 0xbe, 0x1c,
|
||||
0x4f, 0x62, 0x68, 0x6a, 0x50, 0x1e, 0x77, 0xe2, 0xb6, 0xdf, 0xa8, 0x89,
|
||||
0xdf, 0x98, 0x9b, 0x80, 0xc2, 0x00, 0x21, 0x6a, 0xf6, 0x82, 0xb3, 0x5f,
|
||||
0x8b, 0x98, 0x68, 0xe1, 0x76, 0xef, 0x06, 0x8c, 0x24, 0x07, 0xd2, 0xe5,
|
||||
0x86, 0xc1, 0xc0, 0x26, 0x94, 0x2d, 0x96, 0xb1, 0xa4, 0x77, 0x11, 0xcb,
|
||||
0xa9, 0xf9, 0x46, 0xe8, 0xfd, 0x91, 0x61, 0x9d, 0xce, 0xd1, 0x24, 0x27,
|
||||
0xbb, 0xae, 0x68, 0x04, 0x44, 0xc9, 0x44, 0x69, 0x52, 0x05, 0x10, 0x4d,
|
||||
0x96, 0x56, 0x98, 0x69, 0x46, 0x49, 0xc2, 0x75, 0xb9, 0xd8, 0x1c, 0x46,
|
||||
0xdc, 0x71, 0x86, 0x71, 0x07, 0xea, 0x18, 0x5d, 0x7c, 0x3f, 0x81, 0x97,
|
||||
0xfc, 0xc8, 0x88, 0xe4, 0xe7, 0x5e, 0xb2, 0xf8, 0x04, 0x17, 0x14, 0xcf,
|
||||
0x24, 0x4c, 0x35, 0x1e, 0x0d, 0xba, 0xf6, 0x0d, 0x29, 0x1c, 0x3c, 0x5a,
|
||||
0x0f, 0xd0, 0xf8, 0xf8, 0xdb, 0xa6, 0xa5, 0xf2, 0x83, 0x3d, 0xa0, 0x16,
|
||||
0x5d, 0xf4, 0xb7, 0xc0, 0xc5, 0xf1, 0x0f, 0x09, 0x7d, 0x6a, 0x24, 0xf0,
|
||||
0x94, 0x03, 0x7d, 0xc0, 0x96, 0x61, 0xa7, 0x44, 0xe2, 0xa3, 0x40, 0xa5,
|
||||
0x00, 0x06, 0x13, 0x45, 0xba, 0x60, 0xc3, 0x15, 0x75, 0x6a, 0xe6, 0xd9,
|
||||
0x21, 0x37, 0x15, 0x80, 0xfd, 0x68, 0xdf, 0xab, 0x9f, 0xde, 0xcf, 0x4a,
|
||||
0x98, 0xf8, 0xa9, 0x27, 0xd3, 0x2d, 0x3d, 0x5c, 0xdc, 0xff, 0x8c, 0x61,
|
||||
0x4d, 0x25, 0xc8, 0xdf, 0x66, 0xf6, 0xde, 0xf0, 0x21, 0x5a, 0x27, 0x36,
|
||||
0x38, 0x1f, 0xfe, 0x89, 0x33, 0x52, 0x4e, 0x99, 0x55, 0x9b, 0xd0, 0x4f,
|
||||
0x15, 0xba, 0x91, 0xdd, 0x95, 0xeb, 0x57, 0x18, 0xc4, 0x21, 0x86, 0x24,
|
||||
0x67, 0x38, 0xf0, 0x2f, 0xd2, 0x66, 0x0b, 0x92, 0xb9, 0xc3, 0xcb, 0x8e,
|
||||
0x7f, 0x6c, 0x44, 0xbc, 0xcb, 0x45, 0x71, 0x51, 0x61, 0x35, 0xf2, 0x9f,
|
||||
0xbf, 0xf2, 0x8f, 0x5a, 0xdb, 0xaa, 0x54, 0x20, 0x1d, 0x52, 0xce, 0x89,
|
||||
0xd4, 0xe7, 0x79, 0x75, 0xa7, 0xff, 0x1f, 0x6a, 0xfd, 0xb9, 0x56, 0xee,
|
||||
0xca, 0x2c, 0x9f, 0xf3, 0x6d, 0xdf, 0xce, 0x96, 0x0c, 0xaf, 0x2c, 0x2c,
|
||||
0x7d, 0x35, 0x79, 0x5d, 0x43, 0xbb, 0x27, 0xaf, 0x07, 0x17, 0x9a, 0x67,
|
||||
0xde, 0x3b, 0x35, 0xf1, 0xd9, 0x98, 0x92, 0xf8, 0x3d, 0x35, 0xf1, 0x25,
|
||||
0xf8, 0x15, 0xcc, 0x6f, 0x49, 0x9e, 0xba, 0x52, 0xd8, 0x76, 0x71, 0x8d,
|
||||
0x90, 0x2c, 0x73, 0x3f, 0xef, 0xa2, 0xef, 0x43, 0x19, 0x2d, 0x83, 0xb9,
|
||||
0xde, 0xc6, 0x33, 0x00, 0xd9, 0x9d, 0x50, 0x58, 0xa7, 0xaa, 0x07, 0xa6,
|
||||
0x81, 0x8c, 0x1b, 0xe7, 0x9a, 0x3f, 0x11, 0x4c, 0xef, 0x96, 0x07, 0xb3,
|
||||
0x48, 0x3e, 0x95, 0x2e, 0xb1, 0x27, 0x2d, 0xf9, 0x50, 0x49, 0x91, 0x7e,
|
||||
0x91, 0xd2, 0xcc, 0xf0, 0x36, 0xe8, 0xcd, 0x69, 0x05, 0x68, 0x50, 0xe6,
|
||||
0x4d, 0xbe, 0xd7, 0x55, 0xd5, 0xd2, 0xe4, 0x96, 0xd0, 0xa8, 0x1b, 0x4b,
|
||||
0x28, 0x54, 0xcb, 0x95, 0x4c, 0xb5, 0xe7, 0x1c, 0x95, 0x2e, 0x11, 0xda,
|
||||
0x30, 0x0e, 0x87, 0xfe, 0x5e, 0x34, 0x80, 0x59, 0x9d, 0x70, 0x09, 0x48,
|
||||
0x9e, 0xe8, 0x31, 0x12, 0x3f, 0xe2, 0x07, 0x35, 0x74, 0x79, 0x43, 0x68,
|
||||
0x42, 0x85, 0x09, 0x85, 0x42, 0x99, 0x5a, 0x92, 0x8c, 0xe9, 0x14, 0x6c,
|
||||
0xf3, 0x06, 0x50, 0x2a, 0x6d, 0xd8, 0xd5, 0x06, 0xdc, 0x8c, 0x4d, 0x60,
|
||||
0x84, 0x98, 0x6a, 0xf6, 0x30, 0xb9, 0x06, 0xe3, 0xcd, 0x75, 0xd7, 0xaa,
|
||||
0xbc, 0x56, 0x8d, 0x2f, 0x6b, 0x0d, 0x2e, 0x26, 0x40, 0x86, 0x08, 0xf5,
|
||||
0xc6, 0xee, 0x12, 0xd6, 0x06, 0x59, 0x7f, 0xa6, 0xac, 0x3f, 0xef, 0x15,
|
||||
0xd6, 0x20, 0x55, 0x21, 0xa9, 0x29, 0xdb, 0xf4, 0x1f, 0xa6, 0x79, 0x3c,
|
||||
0x13, 0xf0, 0x32, 0x7f, 0x25, 0x27, 0x7a, 0x64, 0xe1, 0x64, 0x3b, 0x86,
|
||||
0x14, 0x4e, 0xfd, 0x29, 0xbc, 0x6e, 0x9f, 0x1b, 0xaa, 0xdf, 0xe3, 0x77,
|
||||
0xd7, 0xb8, 0x7f, 0x61, 0x2f, 0xbc, 0xea, 0xfe, 0x18, 0xc6, 0x54, 0x91,
|
||||
0x85, 0xaa, 0x55, 0xa7, 0xca, 0x00, 0x8f, 0x56, 0xaf, 0xa8, 0x49, 0x02,
|
||||
0xcb, 0xbe, 0x20, 0x5a
|
||||
};
|
111
BootLoaderTWL/source/launch_ds_crt0.s
Normal file
111
BootLoaderTWL/source/launch_ds_crt0.s
Normal file
@ -0,0 +1,111 @@
|
||||
@---------------------------------------------------------------------------------
|
||||
.section ".init"
|
||||
.global _start
|
||||
@---------------------------------------------------------------------------------
|
||||
.align 4
|
||||
.arm
|
||||
@---------------------------------------------------------------------------------
|
||||
_start:
|
||||
@---------------------------------------------------------------------------------
|
||||
b startUp
|
||||
|
||||
startUp:
|
||||
mov r0, #0x04000000 @ IME = 0;
|
||||
add r0, r0, #0x208
|
||||
strh r0, [r0]
|
||||
|
||||
mov r0, #0x12 @ Switch to IRQ Mode
|
||||
msr cpsr, r0
|
||||
ldr sp, =__sp_irq @ Set IRQ stack
|
||||
|
||||
mov r0, #0x13 @ Switch to SVC Mode
|
||||
msr cpsr, r0
|
||||
ldr sp, =__sp_svc @ Set SVC stack
|
||||
|
||||
mov r0, #0x1F @ Switch to System Mode
|
||||
msr cpsr, r0
|
||||
ldr sp, =__sp_usr @ Set user stack
|
||||
|
||||
ldr r0, =__bss_start @ Clear BSS section to 0x00
|
||||
ldr r1, =__bss_end
|
||||
sub r1, r1, r0
|
||||
bl ClearMem
|
||||
|
||||
@ Load ARM9 region into main RAM
|
||||
ldr r1, =__arm9_source_start
|
||||
ldr r2, =__arm9_start
|
||||
ldr r3, =__arm9_source_end
|
||||
sub r3, r3, r1
|
||||
bl CopyMem
|
||||
|
||||
@ Start ARM9 binary
|
||||
ldr r0, =0x02FFFE24
|
||||
ldr r1, =_arm9_start
|
||||
str r1, [r0]
|
||||
|
||||
mov r0, #0 @ int argc
|
||||
mov r1, #0 @ char *argv[]
|
||||
ldr r3, =arm7_main
|
||||
bl _blx_r3_stub @ jump to user code
|
||||
|
||||
@ If the user ever returns, restart
|
||||
b _start
|
||||
|
||||
@---------------------------------------------------------------------------------
|
||||
_blx_r3_stub:
|
||||
@---------------------------------------------------------------------------------
|
||||
bx r3
|
||||
|
||||
|
||||
@---------------------------------------------------------------------------------
|
||||
@ Clear memory to 0x00 if length != 0
|
||||
@ r0 = Start Address
|
||||
@ r1 = Length
|
||||
@---------------------------------------------------------------------------------
|
||||
ClearMem:
|
||||
@---------------------------------------------------------------------------------
|
||||
mov r2, #3 @ Round down to nearest word boundary
|
||||
add r1, r1, r2 @ Shouldn't be needed
|
||||
bics r1, r1, r2 @ Clear 2 LSB (and set Z)
|
||||
bxeq lr @ Quit if copy size is 0
|
||||
|
||||
mov r2, #0
|
||||
ClrLoop:
|
||||
stmia r0!, {r2}
|
||||
subs r1, r1, #4
|
||||
bne ClrLoop
|
||||
bx lr
|
||||
|
||||
@---------------------------------------------------------------------------------
|
||||
@ Copy memory if length != 0
|
||||
@ r1 = Source Address
|
||||
@ r2 = Dest Address
|
||||
@ r4 = Dest Address + Length
|
||||
@---------------------------------------------------------------------------------
|
||||
CopyMemCheck:
|
||||
@---------------------------------------------------------------------------------
|
||||
sub r3, r4, r2 @ Is there any data to copy?
|
||||
@---------------------------------------------------------------------------------
|
||||
@ Copy memory
|
||||
@ r1 = Source Address
|
||||
@ r2 = Dest Address
|
||||
@ r3 = Length
|
||||
@---------------------------------------------------------------------------------
|
||||
CopyMem:
|
||||
@---------------------------------------------------------------------------------
|
||||
mov r0, #3 @ These commands are used in cases where
|
||||
add r3, r3, r0 @ the length is not a multiple of 4,
|
||||
bics r3, r3, r0 @ even though it should be.
|
||||
bxeq lr @ Length is zero, so exit
|
||||
CIDLoop:
|
||||
ldmia r1!, {r0}
|
||||
stmia r2!, {r0}
|
||||
subs r3, r3, #4
|
||||
bne CIDLoop
|
||||
bx lr
|
||||
|
||||
@---------------------------------------------------------------------------------
|
||||
.align
|
||||
.pool
|
||||
.end
|
||||
@---------------------------------------------------------------------------------
|
367
BootLoaderTWL/source/main.arm7.c
Normal file
367
BootLoaderTWL/source/main.arm7.c
Normal file
@ -0,0 +1,367 @@
|
||||
/*
|
||||
main.arm7.c
|
||||
|
||||
By Michael Chisholm (Chishm)
|
||||
|
||||
All resetMemory and startBinary functions are based
|
||||
on the MultiNDS loader by Darkain.
|
||||
Original source available at:
|
||||
http://cvs.sourceforge.net/viewcvs.py/ndslib/ndslib/examples/loader/boot/main.cpp
|
||||
|
||||
License:
|
||||
NitroHax -- Cheat tool for the Nintendo DS
|
||||
Copyright (C) 2008 Michael "Chishm" Chisholm
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
#ifndef ARM7
|
||||
# define ARM7
|
||||
#endif
|
||||
#include <nds/ndstypes.h>
|
||||
#include <nds/arm7/codec.h>
|
||||
#include <nds/system.h>
|
||||
#include <nds/interrupts.h>
|
||||
#include <nds/timers.h>
|
||||
#include <nds/dma.h>
|
||||
#include <nds/arm7/audio.h>
|
||||
#include <nds/ipc.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
#include "common.h"
|
||||
#include "tonccpy.h"
|
||||
#include "read_card.h"
|
||||
#include "module_params.h"
|
||||
#include "find.h"
|
||||
#include "cheat.h"
|
||||
|
||||
void arm7_clearmem (void* loc, size_t len);
|
||||
extern void ensureBinaryDecompressed(const tNDSHeader* ndsHeader, module_params_t* moduleParams);
|
||||
|
||||
// Module params
|
||||
static const u32 moduleParamsSignature[2] = {0xDEC00621, 0x2106C0DE};
|
||||
|
||||
static u32 chipID;
|
||||
|
||||
static module_params_t* moduleParams;
|
||||
|
||||
u32* findModuleParamsOffset(const tNDSHeader* ndsHeader) {
|
||||
u32* moduleParamsOffset = findOffset((u32*)ndsHeader->arm9destination, ndsHeader->arm9binarySize, moduleParamsSignature, 2);
|
||||
return moduleParamsOffset;
|
||||
}
|
||||
|
||||
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// Important things
|
||||
#define NDS_HEADER 0x027FFE00
|
||||
#define NDS_HEADER_SDK5 0x02FFFE00 // __NDSHeader
|
||||
#define NDS_HEADER_POKEMON 0x027FF000
|
||||
|
||||
#define DSI_HEADER 0x027FE000
|
||||
#define DSI_HEADER_SDK5 0x02FFE000 // __DSiHeader
|
||||
|
||||
// #define CHEAT_ENGINE_LOCATION 0x027FE000
|
||||
#define CHEAT_ENGINE_LOCATION 0x023FE800
|
||||
#define CHEAT_DATA_LOCATION 0x06030000
|
||||
|
||||
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// Used for debugging purposes
|
||||
static void debugOutput (u32 code) {
|
||||
// Wait until the ARM9 is ready
|
||||
while (arm9_stateFlag != ARM9_READY);
|
||||
// Set the error code, then tell ARM9 to display it
|
||||
arm9_errorCode = code;
|
||||
arm9_stateFlag = ARM9_DISPERR;
|
||||
// Wait for completion
|
||||
while (arm9_stateFlag != ARM9_READY);
|
||||
}
|
||||
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// Firmware stuff
|
||||
|
||||
static void my_readUserSettings(tNDSHeader* ndsHeader) {
|
||||
PERSONAL_DATA slot1;
|
||||
PERSONAL_DATA slot2;
|
||||
|
||||
short slot1count, slot2count; //u8
|
||||
short slot1CRC, slot2CRC;
|
||||
|
||||
u32 userSettingsBase;
|
||||
|
||||
// Get settings location
|
||||
readFirmware(0x20, &userSettingsBase, 2);
|
||||
|
||||
u32 slot1Address = userSettingsBase * 8;
|
||||
u32 slot2Address = userSettingsBase * 8 + 0x100;
|
||||
|
||||
// Reload DS Firmware settings
|
||||
readFirmware(slot1Address, &slot1, sizeof(PERSONAL_DATA)); //readFirmware(slot1Address, personalData, 0x70);
|
||||
readFirmware(slot2Address, &slot2, sizeof(PERSONAL_DATA)); //readFirmware(slot2Address, personalData, 0x70);
|
||||
readFirmware(slot1Address + 0x70, &slot1count, 2); //readFirmware(slot1Address + 0x70, &slot1count, 1);
|
||||
readFirmware(slot2Address + 0x70, &slot2count, 2); //readFirmware(slot1Address + 0x70, &slot2count, 1);
|
||||
readFirmware(slot1Address + 0x72, &slot1CRC, 2);
|
||||
readFirmware(slot2Address + 0x72, &slot2CRC, 2);
|
||||
|
||||
// Default to slot 1 user settings
|
||||
void *currentSettings = &slot1;
|
||||
|
||||
short calc1CRC = swiCRC16(0xFFFF, &slot1, sizeof(PERSONAL_DATA));
|
||||
short calc2CRC = swiCRC16(0xFFFF, &slot2, sizeof(PERSONAL_DATA));
|
||||
|
||||
// Bail out if neither slot is valid
|
||||
if (calc1CRC != slot1CRC && calc2CRC != slot2CRC)return;
|
||||
|
||||
// If both slots are valid pick the most recent
|
||||
if (calc1CRC == slot1CRC && calc2CRC == slot2CRC) {
|
||||
currentSettings = (slot2count == ((slot1count + 1) & 0x7f) ? &slot2 : &slot1);
|
||||
//if ((slot1count & 0x7F) == ((slot2count + 1) & 0x7F)) {
|
||||
} else {
|
||||
if (calc2CRC == slot2CRC)currentSettings = &slot2;
|
||||
}
|
||||
|
||||
PERSONAL_DATA* personalData = (PERSONAL_DATA*)((u32)__NDSHeader - (u32)ndsHeader + (u32)PersonalData); //(u8*)((u32)ndsHeader - 0x180)
|
||||
|
||||
tonccpy(PersonalData, currentSettings, sizeof(PERSONAL_DATA));
|
||||
|
||||
if (personalData->language != 6 && ndsHeader->reserved1[8] == 0x80) {
|
||||
ndsHeader->reserved1[8] = 0; // Patch iQue game to be region-free
|
||||
ndsHeader->headerCRC16 = swiCRC16(0xFFFF, ndsHeader, 0x15E); // Fix CRC
|
||||
}
|
||||
}
|
||||
|
||||
void memset_addrs_arm7(u32 start, u32 end) { toncset((u32*)start, 0, ((int)end - (int)start)); }
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
arm7_resetMemory
|
||||
Clears all of the NDS's RAM that is visible to the ARM7
|
||||
Written by Darkain.
|
||||
Modified by Chishm:
|
||||
* Added STMIA clear mem loop
|
||||
--------------------------------------------------------------------------*/
|
||||
void arm7_resetMemory (void) {
|
||||
int i, reg;
|
||||
|
||||
REG_IME = 0;
|
||||
|
||||
for (i=0; i<16; i++) {
|
||||
SCHANNEL_CR(i) = 0;
|
||||
SCHANNEL_TIMER(i) = 0;
|
||||
SCHANNEL_SOURCE(i) = 0;
|
||||
SCHANNEL_LENGTH(i) = 0;
|
||||
}
|
||||
REG_SOUNDCNT = 0;
|
||||
|
||||
// Clear out ARM7 DMA channels and timers
|
||||
for (i=0; i<4; i++) {
|
||||
DMA_CR(i) = 0;
|
||||
DMA_SRC(i) = 0;
|
||||
DMA_DEST(i) = 0;
|
||||
TIMER_CR(i) = 0;
|
||||
TIMER_DATA(i) = 0;
|
||||
if ((REG_SCFG_EXT & BIT(31)))for(reg=0; reg<0x1c; reg+=4)*((u32*)(0x04004104 + ((i*0x1c)+reg))) = 0; //Reset NDMA.
|
||||
}
|
||||
// Clear out FIFO
|
||||
REG_IPC_SYNC = 0;
|
||||
REG_IPC_FIFO_CR = IPC_FIFO_ENABLE | IPC_FIFO_SEND_CLEAR;
|
||||
REG_IPC_FIFO_CR = 0;
|
||||
// clear IWRAM - 037F:8000 to 0380:FFFF, total 96KiB
|
||||
toncset ((void*)0x037F8000, 0, 96*1024);
|
||||
memset_addrs_arm7(0x03000000, 0x0380FFC0);
|
||||
memset_addrs_arm7(0x0380FFD0, 0x03800000 + 0x10000);
|
||||
// clear most of EXRAM - except before 0x023F0000, which has the cheat data
|
||||
toncset ((void*)0x02004000, 0, 0x3EC000);
|
||||
// clear more of EXRAM, skipping the cheat data section
|
||||
toncset ((void*)0x023F8000, 0, 0x6000);
|
||||
// clear last part of EXRAM
|
||||
toncset ((void*)0x02400000, 0, 0xC00000);
|
||||
REG_IE = 0;
|
||||
REG_IF = ~0;
|
||||
REG_AUXIE = 0;
|
||||
REG_AUXIF = ~0;
|
||||
(*(vu32*)(0x04000000-4)) = 0; //IRQ_HANDLER ARM7 version
|
||||
(*(vu32*)(0x04000000-8)) = ~0; //VBLANK_INTR_WAIT_FLAGS, ARM7 version
|
||||
REG_POWERCNT = 1; //turn off power to stuffs
|
||||
}
|
||||
|
||||
// SDK 5
|
||||
static bool ROMsupportsDSiMode(const tNDSHeader* ndsHeader) { return (ndsHeader->unitCode > 0); }
|
||||
|
||||
// SDK 5
|
||||
static bool ROMisDSiEnhanced(const tNDSHeader* ndsHeader) { return (ndsHeader->unitCode == 0x02); }
|
||||
|
||||
// SDK 5
|
||||
static bool ROMisDSiExclusive(const tNDSHeader* ndsHeader) { return (ndsHeader->unitCode == 0x03); }
|
||||
|
||||
int arm7_loadBinary (const tDSiHeader* dsiHeaderTemp) {
|
||||
u32 errorCode;
|
||||
// Init card
|
||||
errorCode = cardInit((sNDSHeaderExt*)dsiHeaderTemp, &chipID);
|
||||
if (errorCode)return errorCode;
|
||||
// Fix Pokemon games needing header data.
|
||||
tonccpy((u32*)NDS_HEADER_POKEMON, (u32*)NDS_HEADER, 0x170);
|
||||
char* romTid = (char*)NDS_HEADER_POKEMON+0xC;
|
||||
if (
|
||||
memcmp(romTid, "ADA", 3) == 0 // Diamond
|
||||
|| memcmp(romTid, "APA", 3) == 0 // Pearl
|
||||
|| memcmp(romTid, "CPU", 3) == 0 // Platinum
|
||||
|| memcmp(romTid, "IPK", 3) == 0 // HG
|
||||
|| memcmp(romTid, "IPG", 3) == 0 // SS
|
||||
) {
|
||||
// Make the Pokemon game code ADAJ.
|
||||
const char gameCodePokemon[] = { 'A', 'D', 'A', 'J' };
|
||||
tonccpy((char*)NDS_HEADER_POKEMON+0xC, gameCodePokemon, 4);
|
||||
}
|
||||
cardRead(dsiHeaderTemp->ndshdr.arm9romOffset, (u32*)dsiHeaderTemp->ndshdr.arm9destination, dsiHeaderTemp->ndshdr.arm9binarySize);
|
||||
cardRead(dsiHeaderTemp->ndshdr.arm7romOffset, (u32*)dsiHeaderTemp->ndshdr.arm7destination, dsiHeaderTemp->ndshdr.arm7binarySize);
|
||||
moduleParams = (module_params_t*)findModuleParamsOffset(&dsiHeaderTemp->ndshdr);
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
static tNDSHeader* loadHeader(tDSiHeader* dsiHeaderTemp) {
|
||||
tNDSHeader* ndsHeader = (tNDSHeader*)(isSdk5(moduleParams) ? NDS_HEADER_SDK5 : NDS_HEADER);
|
||||
*ndsHeader = dsiHeaderTemp->ndshdr;
|
||||
return ndsHeader;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
arm7_startBinary
|
||||
Jumps to the ARM7 NDS binary in sync with the display and ARM9
|
||||
Written by Darkain, modified by Chishm.
|
||||
--------------------------------------------------------------------------*/
|
||||
void arm7_startBinary (void) {
|
||||
REG_IME = 0;
|
||||
// Get the ARM9 to boot
|
||||
arm9_stateFlag = ARM9_BOOTBIN;
|
||||
while(REG_VCOUNT!=191);
|
||||
while(REG_VCOUNT==191);
|
||||
// Start ARM7
|
||||
VoidFn arm7code = (VoidFn)ndsHeader->arm7executeAddress;
|
||||
arm7code();
|
||||
}
|
||||
|
||||
static void setMemoryAddress(const tNDSHeader* ndsHeader) {
|
||||
if (ROMsupportsDSiMode(ndsHeader)) {
|
||||
tonccpy((u32*)0x02FFFA80, (u32*)NDS_HEADER_SDK5, 0x160); // Make a duplicate of DS header
|
||||
*(u32*)(0x02FFA680) = 0x02FD4D80;
|
||||
*(u32*)(0x02FFA684) = 0x00000000;
|
||||
*(u32*)(0x02FFA688) = 0x00001980;
|
||||
*(u32*)(0x02FFF00C) = 0x0000007F;
|
||||
*(u32*)(0x02FFF010) = 0x550E25B8;
|
||||
*(u32*)(0x02FFF014) = 0x02FF4000;
|
||||
}
|
||||
|
||||
// Set memory values expected by loaded NDS
|
||||
// from NitroHax, thanks to Chism
|
||||
*((u32*)(isSdk5(moduleParams) ? 0x02fff800 : 0x027ff800)) = chipID; // CurrentCardID
|
||||
*((u32*)(isSdk5(moduleParams) ? 0x02fff804 : 0x027ff804)) = chipID; // Command10CardID
|
||||
*((u16*)(isSdk5(moduleParams) ? 0x02fff808 : 0x027ff808)) = ndsHeader->headerCRC16; // Header Checksum, CRC-16 of [000h-15Dh]
|
||||
*((u16*)(isSdk5(moduleParams) ? 0x02fff80a : 0x027ff80a)) = ndsHeader->secureCRC16; // Secure Area Checksum, CRC-16 of [ [20h]..7FFFh]
|
||||
|
||||
// Copies of above
|
||||
*((u32*)(isSdk5(moduleParams) ? 0x02fffc00 : 0x027ffc00)) = chipID; // CurrentCardID
|
||||
*((u32*)(isSdk5(moduleParams) ? 0x02fffc04 : 0x027ffc04)) = chipID; // Command10CardID
|
||||
*((u16*)(isSdk5(moduleParams) ? 0x02fffc08 : 0x027ffc08)) = ndsHeader->headerCRC16; // Header Checksum, CRC-16 of [000h-15Dh]
|
||||
*((u16*)(isSdk5(moduleParams) ? 0x02fffc0a : 0x027ffc0a)) = ndsHeader->secureCRC16; // Secure Area Checksum, CRC-16 of [ [20h]..7FFFh]
|
||||
|
||||
*((u16*)(isSdk5(moduleParams) ? 0x02fffc40 : 0x027ffc40)) = 0x1; // Boot Indicator (Booted from card for SDK5) -- EXTREMELY IMPORTANT!!! Thanks to cReDiAr
|
||||
}
|
||||
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// Main function
|
||||
|
||||
void arm7_main (void) {
|
||||
|
||||
if (REG_SNDEXTCNT != 0) {
|
||||
if ((REG_SCFG_EXT & BIT(31))) {
|
||||
REG_MBK9=0xFCFFFF0F;
|
||||
*((vu32*)REG_MBK1)=0x8D898581;
|
||||
*((vu32*)REG_MBK2)=0x8C888480;
|
||||
*((vu32*)REG_MBK3)=0x9C989490;
|
||||
*((vu32*)REG_MBK4)=0x8C888480;
|
||||
*((vu32*)REG_MBK5)=0x9C989490;
|
||||
REG_MBK6=0x09403900;
|
||||
REG_MBK7=0x09803940;
|
||||
REG_MBK8=0x09C03980;
|
||||
}
|
||||
}
|
||||
|
||||
int errorCode;
|
||||
|
||||
// Wait for ARM9 to at least start
|
||||
while (arm9_stateFlag < ARM9_START);
|
||||
|
||||
// debugOutput (ERR_STS_CLR_MEM);
|
||||
|
||||
// Get ARM7 to clear RAM
|
||||
arm7_resetMemory();
|
||||
|
||||
// debugOutput (ERR_STS_LOAD_BIN);
|
||||
|
||||
if ((REG_SCFG_EXT & BIT(31)))REG_SCFG_ROM = 0x703;
|
||||
|
||||
tDSiHeader* dsiHeaderTemp = (tDSiHeader*)0x02FFC000;
|
||||
|
||||
// Load the NDS file
|
||||
errorCode = arm7_loadBinary(dsiHeaderTemp);
|
||||
if (errorCode)debugOutput(errorCode);
|
||||
|
||||
// Override some settings depending on if DSi Enhanced cart or DSi Exclusive cart is inserted
|
||||
// if (ROMisDSiEnhanced(&dsiHeaderTemp->ndshdr)) { extendRam = true; } // Required for TWL carts to boot properly. Disabled by default for NTR carts to allow WoodR4 to operate correctly.
|
||||
|
||||
/*if (twlMode) {
|
||||
if (dsiHeaderTemp->arm9ibinarySize > 0) {
|
||||
cardRead((u32)dsiHeaderTemp->arm9iromOffset, (u32*)dsiHeaderTemp->arm9idestination, dsiHeaderTemp->arm9ibinarySize);
|
||||
}
|
||||
if (dsiHeaderTemp->arm7ibinarySize > 0) {
|
||||
cardRead((u32)dsiHeaderTemp->arm7iromOffset, (u32*)dsiHeaderTemp->arm7idestination, dsiHeaderTemp->arm7ibinarySize);
|
||||
}
|
||||
}*/
|
||||
|
||||
ndsHeader = loadHeader(dsiHeaderTemp);
|
||||
|
||||
if (!ROMisDSiExclusive(&dsiHeaderTemp->ndshdr)) { tonccpy((u32*)0x023FF000, (u32*)(isSdk5(moduleParams) ? 0x02FFF000 : 0x027FF000), 0x1000); }
|
||||
|
||||
my_readUserSettings(ndsHeader); // Header has to be loaded first
|
||||
|
||||
toncset ((void*)0x023F0000, 0, 0x8000); // Clear cheat data from main memory
|
||||
|
||||
// debugOutput (ERR_STS_START);
|
||||
|
||||
if (ROMisDSiExclusive(&dsiHeaderTemp->ndshdr)) { REG_SCFG_CLK = 0x0184; } else { REG_SCFG_CLK = 0x0100; }
|
||||
|
||||
if (REG_SNDEXTCNT != 0) {
|
||||
if ((REG_SCFG_EXT & BIT(31)))REG_SCFG_EXT = 0x12A00000;
|
||||
//REG_SCFG_EXT &= ~(1UL << 31);
|
||||
}
|
||||
|
||||
while (arm9_stateFlag != ARM9_READY);
|
||||
arm9_stateFlag = ARM9_SETSCFG;
|
||||
while (arm9_stateFlag != ARM9_READY);
|
||||
|
||||
setMemoryAddress(ndsHeader);
|
||||
|
||||
// Load the cheat engine and hook it into the ARM7 binary
|
||||
errorCode = arm7_hookGame(ndsHeader, (const u32*)CHEAT_DATA_LOCATION, (u32*)CHEAT_ENGINE_LOCATION);
|
||||
if (errorCode != ERR_NONE && errorCode != ERR_NOCHEAT)debugOutput(errorCode);
|
||||
|
||||
arm7_startBinary();
|
||||
|
||||
while (1);
|
||||
}
|
||||
|
323
BootLoaderTWL/source/main.arm9.c
Normal file
323
BootLoaderTWL/source/main.arm9.c
Normal file
@ -0,0 +1,323 @@
|
||||
/*
|
||||
main.arm9.c
|
||||
|
||||
By Michael Chisholm (Chishm)
|
||||
|
||||
All resetMemory and startBinary functions are based
|
||||
on the MultiNDS loader by Darkain.
|
||||
Original source available at:
|
||||
http://cvs.sourceforge.net/viewcvs.py/ndslib/ndslib/examples/loader/boot/main.cpp
|
||||
|
||||
License:
|
||||
NitroHax -- Cheat tool for the Nintendo DS
|
||||
Copyright (C) 2008 Michael "Chishm" Chisholm
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
#define ARM9
|
||||
#undef ARM7
|
||||
#include <nds/memory.h>
|
||||
#include <nds/arm9/video.h>
|
||||
#include <nds/arm9/input.h>
|
||||
#include <nds/interrupts.h>
|
||||
#include <nds/dma.h>
|
||||
#include <nds/timers.h>
|
||||
#include <nds/system.h>
|
||||
#include <nds/ipc.h>
|
||||
|
||||
#include <nds/dma.h>
|
||||
#include <stddef.h> // NULL
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
tNDSHeader* ndsHeader = NULL;
|
||||
|
||||
volatile int arm9_stateFlag = ARM9_BOOT;
|
||||
volatile u32 arm9_errorCode = 0xFFFFFFFF;
|
||||
volatile u32 arm9_BLANK_RAM = 0;
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
External functions
|
||||
--------------------------------------------------------------------------*/
|
||||
extern void arm9_clearCache (void);
|
||||
|
||||
void SetBrightness(u8 screen, s8 bright) {
|
||||
|
||||
u16 mode = 1 << 14;
|
||||
|
||||
if (bright < 0) {
|
||||
mode = 2 << 14;
|
||||
bright = -bright;
|
||||
}
|
||||
|
||||
if (bright > 31) { bright = 31; }
|
||||
|
||||
*(u16*)(0x0400006C + (0x1000 * screen)) = bright + mode;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
arm9_errorOutput
|
||||
Displays an error code on screen.
|
||||
Written by Chishm
|
||||
--------------------------------------------------------------------------*/
|
||||
static void arm9_errorOutput (u32 code) {
|
||||
int i, j, k;
|
||||
u16 colour;
|
||||
vu16 *const vram_a = (vu16*)VRAM_A;
|
||||
|
||||
REG_POWERCNT = (u16)(POWER_LCD | POWER_2D_A);
|
||||
REG_DISPCNT = MODE_FB0;
|
||||
VRAM_A_CR = VRAM_ENABLE;
|
||||
|
||||
// Clear display
|
||||
for (i = 0; i < 256*192; i++)vram_a[i] = 0x0000;
|
||||
|
||||
// Draw boxes of colour, signifying error codes
|
||||
|
||||
if ((code >> 16) != 0) {
|
||||
// high 16 bits
|
||||
for (i = 0; i < 8; i++) { // Pair of bits to use
|
||||
if (((code>>(30-2*i))&3) == 0) {
|
||||
colour = 0x001F; // Red
|
||||
} else if (((code>>(30-2*i))&3) == 1) {
|
||||
colour = 0x03FF; // Yellow
|
||||
} else if (((code>>(30-2*i))&3) == 2) {
|
||||
colour = 0x03E0; // Green
|
||||
} else {
|
||||
colour = 0x7C00; // Blue
|
||||
}
|
||||
for (j = 71; j < 87; j++) { // Row
|
||||
for (k = 32*i+8; k < 32*i+24; k++) { // Column
|
||||
vram_a[j*256+k] = colour;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Low 16 bits
|
||||
for (i = 0; i < 8; i++) { // Pair of bits to use
|
||||
if (((code>>(14-2*i))&3) == 0) {
|
||||
colour = 0x001F; // Red
|
||||
} else if (((code>>(14-2*i))&3) == 1) {
|
||||
colour = 0x03FF; // Yellow
|
||||
} else if (((code>>(14-2*i))&3) == 2) {
|
||||
colour = 0x03E0; // Green
|
||||
} else {
|
||||
colour = 0x7C00; // Blue
|
||||
}
|
||||
for (j = 103; j < 119; j++) { // Row
|
||||
for (k = 32*i+8; k < 32*i+24; k++) { // Column
|
||||
vram_a[j*256+k] = colour;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*static void arm9_errorOutput (u32 code) {
|
||||
int i, j, k;
|
||||
u16 colour;
|
||||
|
||||
REG_POWERCNT = (u16)(POWER_LCD | POWER_2D_A);
|
||||
REG_DISPCNT = MODE_FB0;
|
||||
VRAM_A_CR = VRAM_ENABLE;
|
||||
|
||||
// Clear display
|
||||
for (i = 0; i < 256*192; i++) { VRAM_A[i] = 0xFFFF; }
|
||||
|
||||
// Draw boxes of colour, signifying error codes
|
||||
|
||||
if ((code >> 16) != 0) {
|
||||
// high 16 bits
|
||||
for (i = 0; i < 8; i++) { // Pair of bits to use
|
||||
if (((code>>(30-2*i))&3) == 0) {
|
||||
colour = 0x001F; // Red
|
||||
} else if (((code>>(30-2*i))&3) == 1) {
|
||||
colour = 0x03FF; // Yellow
|
||||
} else if (((code>>(30-2*i))&3) == 2) {
|
||||
colour = 0x03E0; // Green
|
||||
} else {
|
||||
colour = 0x7C00; // Blue
|
||||
}
|
||||
for (j = 71; j < 87; j++) { // Row
|
||||
for (k = 32*i+8; k < 32*i+24; k++) { // Column
|
||||
VRAM_A[j*256+k] = colour;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((code >> 8) != 0) {
|
||||
// Low 16 bits
|
||||
for (i = 0; i < 8; i++) { // Pair of bits to use
|
||||
if (((code>>(14-2*i))&3) == 0) {
|
||||
colour = 0x001F; // Red
|
||||
} else if (((code>>(14-2*i))&3) == 1) {
|
||||
colour = 0x03FF; // Yellow
|
||||
} else if (((code>>(14-2*i))&3) == 2) {
|
||||
colour = 0x03E0; // Green
|
||||
} else {
|
||||
colour = 0x7C00; // Blue
|
||||
}
|
||||
for (j = 103; j < 119; j++) { // Row
|
||||
for (k = 32*i+8; k < 32*i+24; k++) { // Column
|
||||
VRAM_A[j*256+k] = colour;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Low 8 bits
|
||||
for (i = 0; i < 4; i++) { // Pair of bits to use
|
||||
if (((code>>(6-2*i))&3) == 0) {
|
||||
colour = 0x001F; // Red
|
||||
} else if (((code>>(6-2*i))&3) == 1) {
|
||||
colour = 0x03FF; // Yellow
|
||||
} else if (((code>>(6-2*i))&3) == 2) {
|
||||
colour = 0x03E0; // Green
|
||||
} else {
|
||||
colour = 0x7C00; // Blue
|
||||
}
|
||||
for (j = 87; j < 103; j++) { // Row
|
||||
for (k = 32*i+72; k < 32*i+88; k++) { // Column
|
||||
VRAM_A[j*256+k] = colour;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
arm9_main
|
||||
Clears the ARM9's icahce and dcache
|
||||
Clears the ARM9's DMA channels and resets video memory
|
||||
Jumps to the ARM9 NDS binary in sync with the display and ARM7
|
||||
Written by Darkain, modified by Chishm
|
||||
--------------------------------------------------------------------------*/
|
||||
void __attribute__((target("arm"))) arm9_main (void) {
|
||||
|
||||
// MBK settings for NTR mode games
|
||||
REG_MBK6=0x00003000;
|
||||
REG_MBK7=0x00003000;
|
||||
REG_MBK8=0x00003000;
|
||||
REG_MBK9=0xFCFFFF0F;
|
||||
|
||||
register int i;
|
||||
|
||||
//set shared ram to ARM7
|
||||
WRAM_CR = 0x03;
|
||||
REG_EXMEMCNT = 0xE880;
|
||||
|
||||
arm9_stateFlag = ARM9_START;
|
||||
|
||||
REG_IME = 0;
|
||||
REG_IE = 0;
|
||||
REG_IF = ~0;
|
||||
|
||||
arm9_clearCache();
|
||||
|
||||
for (i=0; i<16*1024; i+=4) { //first 16KB
|
||||
(*(vu32*)(i+0x00000000)) = 0x00000000; //clear ITCM
|
||||
(*(vu32*)(i+0x00800000)) = 0x00000000; //clear DTCM
|
||||
}
|
||||
|
||||
for (i=16*1024; i<32*1024; i+=4) { //second 16KB
|
||||
(*(vu32*)(i+0x00000000)) = 0x00000000; //clear ITCM
|
||||
}
|
||||
|
||||
arm9_stateFlag = ARM9_MEMCLR;
|
||||
|
||||
(*(vu32*)0x00803FFC) = 0; //IRQ_HANDLER ARM9 version
|
||||
(*(vu32*)0x00803FF8) = ~0; //VBLANK_INTR_WAIT_FLAGS ARM9 version
|
||||
|
||||
//clear out ARM9 DMA channels
|
||||
for (i=0; i<4; i++) {
|
||||
DMA_CR(i) = 0;
|
||||
DMA_SRC(i) = 0;
|
||||
DMA_DEST(i) = 0;
|
||||
TIMER_CR(i) = 0;
|
||||
TIMER_DATA(i) = 0;
|
||||
}
|
||||
|
||||
// Clear out FIFO
|
||||
REG_IPC_SYNC = 0;
|
||||
REG_IPC_FIFO_CR = IPC_FIFO_ENABLE | IPC_FIFO_SEND_CLEAR;
|
||||
REG_IPC_FIFO_CR = 0;
|
||||
|
||||
VRAM_A_CR = 0x80;
|
||||
VRAM_B_CR = 0x80;
|
||||
VRAM_C_CR = 0x80;
|
||||
// Don't mess with the VRAM used for execution
|
||||
// VRAM_D_CR = 0x80;
|
||||
VRAM_E_CR = 0x80;
|
||||
VRAM_F_CR = 0x80;
|
||||
VRAM_G_CR = 0x80;
|
||||
VRAM_H_CR = 0x80;
|
||||
VRAM_I_CR = 0x80;
|
||||
BG_PALETTE[0] = 0xFFFF;
|
||||
dmaFill((u16*)&arm9_BLANK_RAM, BG_PALETTE+1, (2*1024)-2);
|
||||
dmaFill((u16*)&arm9_BLANK_RAM, OAM, 2*1024);
|
||||
dmaFill((u16*)&arm9_BLANK_RAM, (u16*)0x04000000, 0x56); // Clear main display registers
|
||||
dmaFill((u16*)&arm9_BLANK_RAM, (u16*)0x04001000, 0x56); // Clear sub display registers
|
||||
dmaFill((u16*)&arm9_BLANK_RAM, VRAM_A, 0x20000*3); // Banks A, B, C
|
||||
dmaFill((u16*)&arm9_BLANK_RAM, VRAM_D, 272*1024); // Banks D (excluded), E, F, G, H, I
|
||||
|
||||
REG_DISPSTAT = 0;
|
||||
//videoSetMode(0);
|
||||
//videoSetModeSub(0);
|
||||
VRAM_A_CR = 0;
|
||||
VRAM_B_CR = 0;
|
||||
VRAM_C_CR = 0;
|
||||
// Don't mess with the ARM7's VRAM
|
||||
//VRAM_D_CR = 0;
|
||||
VRAM_E_CR = 0;
|
||||
VRAM_F_CR = 0;
|
||||
VRAM_G_CR = 0;
|
||||
VRAM_H_CR = 0;
|
||||
VRAM_I_CR = 0;
|
||||
REG_POWERCNT = 0x820F;
|
||||
|
||||
*(u16*)0x0400006C |= BIT(14);
|
||||
*(u16*)0x0400006C &= BIT(15);
|
||||
SetBrightness(0, 0);
|
||||
SetBrightness(1, 0);
|
||||
|
||||
// set ARM9 state to ready and wait for it to change again
|
||||
arm9_stateFlag = ARM9_READY;
|
||||
while (arm9_stateFlag != ARM9_BOOTBIN) {
|
||||
if (arm9_stateFlag == ARM9_DISPERR) {
|
||||
// Re-enable for debugging
|
||||
arm9_errorOutput(arm9_errorCode);
|
||||
if (arm9_stateFlag == ARM9_DISPERR) { arm9_stateFlag = ARM9_READY; }
|
||||
}
|
||||
|
||||
if (arm9_stateFlag == ARM9_SETSCFG) { arm9_stateFlag = ARM9_READY; }
|
||||
}
|
||||
|
||||
VoidFn arm9code = (VoidFn)ndsHeader->arm9executeAddress;
|
||||
|
||||
while(REG_VCOUNT!=191);
|
||||
while(REG_VCOUNT==191);
|
||||
|
||||
if ((REG_SCFG_EXT & BIT(31))) {
|
||||
REG_SCFG_EXT = 0x8200E000;
|
||||
REG_SCFG_CLK = 0x81;
|
||||
}
|
||||
|
||||
// wait for vblank then boot
|
||||
while(REG_VCOUNT!=191);
|
||||
while(REG_VCOUNT==191);
|
||||
|
||||
arm9code();
|
||||
}
|
||||
|
23
BootLoaderTWL/source/module_params.h
Normal file
23
BootLoaderTWL/source/module_params.h
Normal file
@ -0,0 +1,23 @@
|
||||
#ifndef MODULE_PARAMS_H
|
||||
#define MODULE_PARAMS_H
|
||||
|
||||
#include <nds/ndstypes.h>
|
||||
|
||||
typedef struct {
|
||||
u32 auto_load_list_offset;
|
||||
u32 auto_load_list_end;
|
||||
u32 auto_load_start;
|
||||
u32 static_bss_start;
|
||||
u32 static_bss_end;
|
||||
u32 compressed_static_end;
|
||||
u32 sdk_version;
|
||||
u32 nitro_code_be;
|
||||
u32 nitro_code_le;
|
||||
} module_params_t;
|
||||
|
||||
inline bool isSdk5(const module_params_t* moduleParams) {
|
||||
return (moduleParams->sdk_version > 0x5000000);
|
||||
}
|
||||
|
||||
#endif // MODULE_PARAMS_H
|
||||
|
139
BootLoaderTWL/source/ndsheaderbanner.h
Normal file
139
BootLoaderTWL/source/ndsheaderbanner.h
Normal file
@ -0,0 +1,139 @@
|
||||
/*---------------------------------------------------------------------------------
|
||||
|
||||
memory.h -- Declaration of memory regions
|
||||
|
||||
|
||||
Copyright (C) 2005 Michael Noland (joat) and Jason Rogers (dovoto)
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any
|
||||
purpose, including commercial applications, and to alter it and
|
||||
redistribute it freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you
|
||||
must not claim that you wrote the original software. If you use
|
||||
this software in a product, an acknowledgment in the product
|
||||
documentation would be appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and
|
||||
must not be misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
|
||||
---------------------------------------------------------------------------------*/
|
||||
/*! \file ndsheaderbanner.h
|
||||
\brief Defines the Nintendo DS file header and icon/title structs.
|
||||
*/
|
||||
|
||||
#ifndef NDS_HEADER2
|
||||
#define NDS_HEADER2
|
||||
|
||||
#include <nds.h>
|
||||
|
||||
/*!
|
||||
\brief the NDS file header format
|
||||
See gbatek for more info.
|
||||
*/
|
||||
typedef struct {
|
||||
char gameTitle[12]; //!< 12 characters for the game title.
|
||||
char gameCode[4]; //!< 4 characters for the game code.
|
||||
char makercode[2]; //!< identifies the (commercial) developer.
|
||||
u8 unitCode; //!< identifies the required hardware.
|
||||
u8 deviceType; //!< type of device in the game card
|
||||
u8 deviceSize; //!< capacity of the device (1 << n Mbit)
|
||||
u8 reserved1[9];
|
||||
u8 romversion; //!< version of the ROM.
|
||||
u8 flags; //!< bit 2: auto-boot flag.
|
||||
|
||||
u32 arm9romOffset; //!< offset of the arm9 binary in the nds file.
|
||||
u32 arm9executeAddress; //!< adress that should be executed after the binary has been copied.
|
||||
u32 arm9destination; //!< destination address to where the arm9 binary should be copied.
|
||||
u32 arm9binarySize; //!< size of the arm9 binary.
|
||||
|
||||
u32 arm7romOffset; //!< offset of the arm7 binary in the nds file.
|
||||
u32 arm7executeAddress; //!< adress that should be executed after the binary has been copied.
|
||||
u32 arm7destination; //!< destination address to where the arm7 binary should be copied.
|
||||
u32 arm7binarySize; //!< size of the arm7 binary.
|
||||
|
||||
u32 filenameOffset; //!< File Name Table (FNT) offset.
|
||||
u32 filenameSize; //!< File Name Table (FNT) size.
|
||||
u32 fatOffset; //!< File Allocation Table (FAT) offset.
|
||||
u32 fatSize; //!< File Allocation Table (FAT) size.
|
||||
|
||||
u32 arm9overlaySource; //!< File arm9 overlay offset.
|
||||
u32 arm9overlaySize; //!< File arm9 overlay size.
|
||||
u32 arm7overlaySource; //!< File arm7 overlay offset.
|
||||
u32 arm7overlaySize; //!< File arm7 overlay size.
|
||||
|
||||
u32 cardControl13; //!< Port 40001A4h setting for normal commands (used in modes 1 and 3)
|
||||
u32 cardControlBF; //!< Port 40001A4h setting for KEY1 commands (used in mode 2)
|
||||
u32 bannerOffset; //!< offset to the banner with icon and titles etc.
|
||||
|
||||
u16 secureCRC16; //!< Secure Area Checksum, CRC-16.
|
||||
|
||||
u16 readTimeout; //!< Secure Area Loading Timeout.
|
||||
|
||||
u32 unknownRAM1; //!< ARM9 Auto Load List RAM Address (?)
|
||||
u32 unknownRAM2; //!< ARM7 Auto Load List RAM Address (?)
|
||||
|
||||
u32 bfPrime1; //!< Secure Area Disable part 1.
|
||||
u32 bfPrime2; //!< Secure Area Disable part 2.
|
||||
u32 romSize; //!< total size of the ROM.
|
||||
|
||||
u32 headerSize; //!< ROM header size.
|
||||
u32 zeros88[14];
|
||||
u8 gbaLogo[156]; //!< Nintendo logo needed for booting the game.
|
||||
u16 logoCRC16; //!< Nintendo Logo Checksum, CRC-16.
|
||||
u16 headerCRC16; //!< header checksum, CRC-16.
|
||||
|
||||
u32 debugRomSource; //!< debug ROM offset.
|
||||
u32 debugRomSize; //!< debug size.
|
||||
u32 debugRomDestination; //!< debug RAM destination.
|
||||
u32 offset_0x16C; //reserved?
|
||||
|
||||
u8 zero[0x40];
|
||||
u32 region;
|
||||
u32 accessControl;
|
||||
u32 arm7SCFGSettings;
|
||||
u16 dsi_unk1;
|
||||
u8 dsi_unk2;
|
||||
u8 dsi_flags;
|
||||
|
||||
u32 arm9iromOffset; //!< offset of the arm9 binary in the nds file.
|
||||
u32 arm9iexecuteAddress;
|
||||
u32 arm9idestination; //!< destination address to where the arm9 binary should be copied.
|
||||
u32 arm9ibinarySize; //!< size of the arm9 binary.
|
||||
|
||||
u32 arm7iromOffset; //!< offset of the arm7 binary in the nds file.
|
||||
u32 deviceListDestination;
|
||||
u32 arm7idestination; //!< destination address to where the arm7 binary should be copied.
|
||||
u32 arm7ibinarySize; //!< size of the arm7 binary.
|
||||
|
||||
u8 zero2[0x20];
|
||||
|
||||
// 0x200
|
||||
// TODO: More DSi-specific fields.
|
||||
u32 dsi1[0x10/4];
|
||||
u32 twlRomSize;
|
||||
u32 dsi_unk3;
|
||||
u32 dsi_unk4;
|
||||
u32 dsi_unk5;
|
||||
u8 dsi2[0x10];
|
||||
u32 dsi_tid;
|
||||
u32 dsi_tid2;
|
||||
u32 pubSavSize;
|
||||
u32 prvSavSize;
|
||||
u8 dsi3[0x174];
|
||||
} sNDSHeaderExt;
|
||||
|
||||
//#define __NDSHeader ((tNDSHeader *)0x02FFFE00)
|
||||
|
||||
// Make sure the header size is correct.
|
||||
//static_assert(sizeof(sNDSHeaderExt) == 0x3B4, "sizeof(sNDSHeaderExt) is not 0x3B4 bytes");
|
||||
|
||||
#endif // NDS_HEADER2
|
||||
|
48
BootLoaderTWL/source/patch.h
Normal file
48
BootLoaderTWL/source/patch.h
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
NitroHax -- Cheat tool for the Nintendo DS
|
||||
Copyright (C) 2008 Michael "Chishm" Chisholm
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
#ifndef PATCH_H
|
||||
#define PATCH_H
|
||||
|
||||
//#include <stddef.h>
|
||||
#include <nds/ndstypes.h>
|
||||
#include <nds/memory.h> // tNDSHeader
|
||||
|
||||
#define PAGE_4K (0b01011 << 1)
|
||||
#define PAGE_8K (0b01100 << 1)
|
||||
#define PAGE_16K (0b01101 << 1)
|
||||
#define PAGE_32K (0b01110 << 1)
|
||||
#define PAGE_64K (0b01111 << 1)
|
||||
#define PAGE_128K (0b10000 << 1)
|
||||
#define PAGE_256K (0b10001 << 1)
|
||||
#define PAGE_512K (0b10010 << 1)
|
||||
#define PAGE_1M (0b10011 << 1)
|
||||
#define PAGE_2M (0b10100 << 1)
|
||||
#define PAGE_4M (0b10101 << 1)
|
||||
#define PAGE_8M (0b10110 << 1)
|
||||
#define PAGE_16M (0b10111 << 1)
|
||||
#define PAGE_32M (0b11000 << 1)
|
||||
#define PAGE_64M (0b11001 << 1)
|
||||
#define PAGE_128M (0b11010 << 1)
|
||||
#define PAGE_256M (0b11011 << 1)
|
||||
#define PAGE_512M (0b11100 << 1)
|
||||
#define PAGE_1G (0b11101 << 1)
|
||||
#define PAGE_2G (0b11110 << 1)
|
||||
#define PAGE_4G (0b11111 << 1)
|
||||
|
||||
#endif // PATCH_H
|
94
BootLoaderTWL/source/patch_arm9.c
Normal file
94
BootLoaderTWL/source/patch_arm9.c
Normal file
@ -0,0 +1,94 @@
|
||||
#include <string.h>
|
||||
#include <nds/system.h>
|
||||
#include "module_params.h"
|
||||
#include "patch.h"
|
||||
#include "find.h"
|
||||
#include "common.h"
|
||||
|
||||
//#define memcpy __builtin_memcpy // memcpy
|
||||
|
||||
void patchMpu(const tNDSHeader* ndsHeader, const module_params_t* moduleParams) {
|
||||
u32 patchMpuRegion = 0;
|
||||
u32 patchMpuSize = 0;
|
||||
|
||||
// Find the mpu init
|
||||
u32* mpuStartOffset = findMpuStartOffset(ndsHeader, patchMpuRegion);
|
||||
u32* mpuDataOffset = findMpuDataOffset(moduleParams, patchMpuRegion, mpuStartOffset);
|
||||
if (mpuDataOffset) {
|
||||
// Change the region 1 configuration
|
||||
|
||||
u32 mpuInitRegionNewData = PAGE_32M | 0x02000000 | 1;
|
||||
u32 mpuNewDataAccess = 0;
|
||||
u32 mpuNewInstrAccess = 0;
|
||||
int mpuAccessOffset = 0;
|
||||
switch (patchMpuRegion) {
|
||||
case 0:
|
||||
mpuInitRegionNewData = PAGE_128M | 0x00000000 | 1;
|
||||
break;
|
||||
case 2:
|
||||
mpuNewDataAccess = 0x15111111;
|
||||
mpuNewInstrAccess = 0x5111111;
|
||||
mpuAccessOffset = 6;
|
||||
break;
|
||||
case 3:
|
||||
mpuInitRegionNewData = PAGE_8M | 0x03000000 | 1;
|
||||
mpuNewInstrAccess = 0x5111111;
|
||||
mpuAccessOffset = 5;
|
||||
break;
|
||||
}
|
||||
|
||||
*mpuDataOffset = mpuInitRegionNewData;
|
||||
|
||||
if (mpuAccessOffset) {
|
||||
if (mpuNewInstrAccess) {
|
||||
mpuDataOffset[mpuAccessOffset] = mpuNewInstrAccess;
|
||||
}
|
||||
if (mpuNewDataAccess) {
|
||||
mpuDataOffset[mpuAccessOffset + 1] = mpuNewDataAccess;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Find the mpu cache init
|
||||
u32* mpuInitCacheOffset = findMpuInitCacheOffset(mpuStartOffset);
|
||||
if (mpuInitCacheOffset) {
|
||||
*mpuInitCacheOffset = 0xE3A00046;
|
||||
}
|
||||
|
||||
// Patch out all further mpu reconfiguration
|
||||
// dbg_printf("patchMpuSize: ");
|
||||
// dbg_hexa(patchMpuSize);
|
||||
// dbg_printf("\n\n");
|
||||
const u32* mpuInitRegionSignature = getMpuInitRegionSignature(patchMpuRegion);
|
||||
u32* mpuInitOffset = mpuStartOffset;
|
||||
while (mpuInitOffset && patchMpuSize) {
|
||||
u32 patchSize = ndsHeader->arm9binarySize;
|
||||
if (patchMpuSize > 1) {
|
||||
patchSize = patchMpuSize;
|
||||
}
|
||||
mpuInitOffset = findOffset(
|
||||
//(u32*)((u32)mpuStartOffset + 4), patchSize,
|
||||
mpuInitOffset + 1, patchSize,
|
||||
mpuInitRegionSignature, 1
|
||||
);
|
||||
if (mpuInitOffset) {
|
||||
// dbg_printf("Mpu init: ");
|
||||
// dbg_hexa((u32)mpuInitOffset);
|
||||
// dbg_printf("\n\n");
|
||||
|
||||
*mpuInitOffset = 0xE1A00000; // nop
|
||||
|
||||
// Try to find it
|
||||
/*for (int i = 0; i < 0x100; i++) {
|
||||
mpuDataOffset += i;
|
||||
if ((*mpuDataOffset & 0xFFFFFF00) == 0x02000000) {
|
||||
*mpuDataOffset = PAGE_32M | 0x02000000 | 1;
|
||||
break;
|
||||
}
|
||||
if (i == 100) {
|
||||
*mpuStartOffset = 0xE1A00000;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
20
BootLoaderTWL/source/read_bios.h
Normal file
20
BootLoaderTWL/source/read_bios.h
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
NitroHax -- Cheat tool for the Nintendo DS
|
||||
Copyright (C) 2008 Michael "Chishm" Chisholm
|
||||
|
||||
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 <nds/ndstypes.h>
|
||||
|
||||
void readBios (u8* dest, u32 src, u32 size);
|
54
BootLoaderTWL/source/read_bios.s
Normal file
54
BootLoaderTWL/source/read_bios.s
Normal file
@ -0,0 +1,54 @@
|
||||
#include <nds/asminc.h>
|
||||
|
||||
@This code comes from a post by CaitSith2 at gbadev.org - THANKS!!
|
||||
@
|
||||
@Code to dump the complete Nintendo DS ARM7 bios, including the
|
||||
@first 0x1204 bytes residing in the secure area.
|
||||
@
|
||||
@The ARM7 bios has read protection where 0x(Word)[FFFF(Half word)[FF(Byte)[FF]]]
|
||||
@is returned, if any reads are attempted while PC is outside the arm7 bios range.
|
||||
@
|
||||
@Additionally, if the PC is outside the 0x0000 - 0x1204 range, that range of the bios
|
||||
@is completely locked out from reading.
|
||||
|
||||
|
||||
@ void readBios (u8* dest, u32 src, u32 size)
|
||||
|
||||
.arm
|
||||
|
||||
BEGIN_ASM_FUNC readBios
|
||||
adr r3,bios_dump+1
|
||||
bx r3
|
||||
.thumb
|
||||
|
||||
bios_dump:
|
||||
push {r4-r7,lr} @Even though we don't use R7, the code we are jumping to is going
|
||||
@trash R7, therefore, we must save it.
|
||||
mov r5, r1 @ src
|
||||
sub r1, r2, #1 @ size
|
||||
mov r2, r0 @ dest
|
||||
ldr r0,=0x5ED @The code that will be made to read the full bios resides here.
|
||||
|
||||
loop:
|
||||
mov r6,#0x12 @We Subtract 12 from the location we wish to read
|
||||
sub r3,r1,r6 @because the code at 0x5EC is LDRB R3, [R3,#0x12]
|
||||
add r3, r3, r5
|
||||
adr r6,ret
|
||||
push {r2-r6} @The line of code at 0x5EE is POP {R2,R4,R6,R7,PC}
|
||||
bx r0
|
||||
.align
|
||||
|
||||
ret:
|
||||
strb r3,[r2,r1] @Store the read byte contained in r3, to SRAM.
|
||||
sub r1,#1 @Subtract 1
|
||||
bpl loop @And branch as long as R1 doesn't roll into -1 (0xFFFFFFFF).
|
||||
|
||||
pop {r4-r7} @Restore the saved registers
|
||||
pop {r3} @and return.
|
||||
bx r3
|
||||
|
||||
.END
|
||||
|
||||
@The exact code that resides at 0x5EC (secure area range) of the arm7 bios.
|
||||
@ROM:000005EC 9B 7C LDRB R3, [R3,#0x12]
|
||||
@ROM:000005EE D4 BD POP {R2,R4,R6,R7,PC}
|
427
BootLoaderTWL/source/read_card.c
Normal file
427
BootLoaderTWL/source/read_card.c
Normal file
@ -0,0 +1,427 @@
|
||||
/*
|
||||
NitroHax -- Cheat tool for the Nintendo DS
|
||||
Copyright (C) 2008 Michael "Chishm" Chisholm
|
||||
|
||||
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 "read_card.h"
|
||||
|
||||
#include <nds.h>
|
||||
#include <nds/arm9/cache.h>
|
||||
#include <nds/dma.h>
|
||||
#include <nds/card.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "tonccpy.h"
|
||||
#include "encryption.h"
|
||||
#include "common.h"
|
||||
|
||||
typedef union {
|
||||
char title[4];
|
||||
u32 key;
|
||||
} GameCode;
|
||||
|
||||
static bool twlBlowfish = false;
|
||||
|
||||
static bool normalChip = false; // As defined by GBAtek, normal chip secure area is accessed in blocks of 0x200, other chip in blocks of 0x1000
|
||||
static u32 portFlags = 0;
|
||||
static u32 headerData[0x1000/sizeof(u32)] = {0};
|
||||
static u32 secureArea[CARD_SECURE_AREA_SIZE/sizeof(u32)];
|
||||
|
||||
static const u8 cardSeedBytes[] = {0xE8, 0x4D, 0x5A, 0xB1, 0x17, 0x8F, 0x99, 0xD5};
|
||||
|
||||
static u32 getRandomNumber(void) {
|
||||
return 4; // chosen by fair dice roll.
|
||||
// guaranteed to be random.
|
||||
}
|
||||
|
||||
static void decryptSecureArea (u32 gameCode, u32* secureArea, int iCardDevice) {
|
||||
init_keycode (gameCode, 2, 8, iCardDevice);
|
||||
crypt_64bit_down (secureArea);
|
||||
|
||||
init_keycode (gameCode, 3, 8, iCardDevice);
|
||||
|
||||
for (int i = 0; i < 0x200; i+= 2) { crypt_64bit_down (secureArea + i); }
|
||||
}
|
||||
|
||||
static struct {
|
||||
unsigned int iii;
|
||||
unsigned int jjj;
|
||||
unsigned int kkkkk;
|
||||
unsigned int llll;
|
||||
unsigned int mmm;
|
||||
unsigned int nnn;
|
||||
} key1data;
|
||||
|
||||
|
||||
static void initKey1Encryption (u8* cmdData, int iCardDevice) {
|
||||
key1data.iii = getRandomNumber() & 0x00000fff;
|
||||
key1data.jjj = getRandomNumber() & 0x00000fff;
|
||||
key1data.kkkkk = getRandomNumber() & 0x000fffff;
|
||||
key1data.llll = getRandomNumber() & 0x0000ffff;
|
||||
key1data.mmm = getRandomNumber() & 0x00000fff;
|
||||
key1data.nnn = getRandomNumber() & 0x00000fff;
|
||||
|
||||
if(iCardDevice) { //DSi
|
||||
cmdData[7]=0x3D; // CARD_CMD_ACTIVATE_BF2
|
||||
} else {
|
||||
cmdData[7]=CARD_CMD_ACTIVATE_BF;
|
||||
}
|
||||
|
||||
cmdData[6] = (u8) (key1data.iii >> 4);
|
||||
cmdData[5] = (u8) ((key1data.iii << 4) | (key1data.jjj >> 8));
|
||||
cmdData[4] = (u8) key1data.jjj;
|
||||
cmdData[3] = (u8) (key1data.kkkkk >> 16);
|
||||
cmdData[2] = (u8) (key1data.kkkkk >> 8);
|
||||
cmdData[1] = (u8) key1data.kkkkk;
|
||||
cmdData[0] = (u8) getRandomNumber();
|
||||
}
|
||||
|
||||
// Note: cmdData must be aligned on a word boundary
|
||||
static void createEncryptedCommand (u8 command, u8* cmdData, u32 block) {
|
||||
unsigned long iii, jjj;
|
||||
|
||||
if (command != CARD_CMD_SECURE_READ) { block = key1data.llll; }
|
||||
|
||||
if (command == CARD_CMD_ACTIVATE_SEC) {
|
||||
iii = key1data.mmm;
|
||||
jjj = key1data.nnn;
|
||||
} else {
|
||||
iii = key1data.iii;
|
||||
jjj = key1data.jjj;
|
||||
}
|
||||
|
||||
cmdData[7] = (u8) (command | (block >> 12));
|
||||
cmdData[6] = (u8) (block >> 4);
|
||||
cmdData[5] = (u8) ((block << 4) | (iii >> 8));
|
||||
cmdData[4] = (u8) iii;
|
||||
cmdData[3] = (u8) (jjj >> 4);
|
||||
cmdData[2] = (u8) ((jjj << 4) | (key1data.kkkkk >> 16));
|
||||
cmdData[1] = (u8) (key1data.kkkkk >> 8);
|
||||
cmdData[0] = (u8) key1data.kkkkk;
|
||||
|
||||
crypt_64bit_up ((u32*)cmdData);
|
||||
|
||||
key1data.kkkkk += 1;
|
||||
}
|
||||
|
||||
static void cardDelay (u16 readTimeout) {
|
||||
/* Using a while loop to check the timeout,
|
||||
so we have to wait until one before overflow.
|
||||
This also requires an extra 1 for the timer data.
|
||||
See GBATek for the normal formula used for card timeout.
|
||||
*/
|
||||
TIMER_DATA(0) = 0 - (((readTimeout & 0x3FFF) + 3));
|
||||
TIMER_CR(0) = TIMER_DIV_256 | TIMER_ENABLE;
|
||||
while (TIMER_DATA(0) != 0xFFFF);
|
||||
|
||||
// Clear out the timer registers
|
||||
TIMER_CR(0) = 0;
|
||||
TIMER_DATA(0) = 0;
|
||||
}
|
||||
|
||||
static void switchToTwlBlowfish(sNDSHeaderExt* ndsHeader) {
|
||||
if (twlBlowfish || ndsHeader->unitCode == 0) return;
|
||||
|
||||
// Used for dumping the DSi arm9i/7i binaries
|
||||
|
||||
u32 portFlagsKey1, portFlagsSecRead;
|
||||
int secureBlockNumber;
|
||||
int i;
|
||||
u8 cmdData[8] __attribute__ ((aligned));
|
||||
GameCode* gameCode;
|
||||
|
||||
// Reset card slot
|
||||
disableSlot1();
|
||||
for(int i = 0; i < 25; i++) {
|
||||
while(REG_VCOUNT!=191);
|
||||
while(REG_VCOUNT==191);
|
||||
}
|
||||
enableSlot1();
|
||||
for(int i = 0; i < 15; i++) {
|
||||
while(REG_VCOUNT!=191);
|
||||
while(REG_VCOUNT==191);
|
||||
}
|
||||
|
||||
// Dummy command sent after card reset
|
||||
cardParamCommand (CARD_CMD_DUMMY, 0,
|
||||
CARD_ACTIVATE | CARD_nRESET | CARD_CLK_SLOW | CARD_BLK_SIZE(1) | CARD_DELAY1(0x1FFF) | CARD_DELAY2(0x3F),
|
||||
NULL, 0);
|
||||
|
||||
//int iCardDevice = 1;
|
||||
|
||||
// Initialise blowfish encryption for KEY1 commands and decrypting the secure area
|
||||
gameCode = (GameCode*)ndsHeader->gameCode;
|
||||
init_keycode (gameCode->key, 1, 8, 1);
|
||||
|
||||
// Port 40001A4h setting for normal reads (command B7)
|
||||
portFlags = ndsHeader->cardControl13 & ~CARD_BLK_SIZE(7);
|
||||
// Port 40001A4h setting for KEY1 commands (usually 001808F8h)
|
||||
portFlagsKey1 = CARD_ACTIVATE | CARD_nRESET | (ndsHeader->cardControl13 & (CARD_WR|CARD_CLK_SLOW)) |
|
||||
((ndsHeader->cardControlBF & (CARD_CLK_SLOW|CARD_DELAY1(0x1FFF))) + ((ndsHeader->cardControlBF & CARD_DELAY2(0x3F)) >> 16));
|
||||
|
||||
// Adjust card transfer method depending on the most significant bit of the chip ID
|
||||
if (!normalChip) { portFlagsKey1 |= CARD_SEC_LARGE; }
|
||||
|
||||
// 3Ciiijjj xkkkkkxx - Activate KEY1 Encryption Mode
|
||||
initKey1Encryption (cmdData, 1);
|
||||
cardPolledTransfer((ndsHeader->cardControl13 & (CARD_WR|CARD_nRESET|CARD_CLK_SLOW)) | CARD_ACTIVATE, NULL, 0, cmdData);
|
||||
|
||||
// 4llllmmm nnnkkkkk - Activate KEY2 Encryption Mode
|
||||
createEncryptedCommand (CARD_CMD_ACTIVATE_SEC, cmdData, 0);
|
||||
|
||||
if (normalChip) {
|
||||
cardPolledTransfer(portFlagsKey1, NULL, 0, cmdData);
|
||||
cardDelay(ndsHeader->readTimeout);
|
||||
}
|
||||
cardPolledTransfer(portFlagsKey1, NULL, 0, cmdData);
|
||||
|
||||
// Set the KEY2 encryption registers
|
||||
REG_ROMCTRL = 0;
|
||||
REG_CARD_1B0 = cardSeedBytes[ndsHeader->deviceType & 0x07] | (key1data.nnn << 15) | (key1data.mmm << 27) | 0x6000;
|
||||
REG_CARD_1B4 = 0x879b9b05;
|
||||
REG_CARD_1B8 = key1data.mmm >> 5;
|
||||
REG_CARD_1BA = 0x5c;
|
||||
REG_ROMCTRL = CARD_nRESET | CARD_SEC_SEED | CARD_SEC_EN | CARD_SEC_DAT;
|
||||
|
||||
// Update the DS card flags to suit KEY2 encryption
|
||||
portFlagsKey1 |= CARD_SEC_EN | CARD_SEC_DAT;
|
||||
|
||||
// 1lllliii jjjkkkkk - 2nd Get ROM Chip ID / Get KEY2 Stream
|
||||
createEncryptedCommand (CARD_CMD_SECURE_CHIPID, cmdData, 0);
|
||||
|
||||
if (normalChip) {
|
||||
cardPolledTransfer(portFlagsKey1, NULL, 0, cmdData);
|
||||
cardDelay(ndsHeader->readTimeout);
|
||||
}
|
||||
cardPolledTransfer(portFlagsKey1 | CARD_BLK_SIZE(7), NULL, 0, cmdData);
|
||||
|
||||
// 2bbbbiii jjjkkkkk - Get Secure Area Block
|
||||
portFlagsSecRead = (ndsHeader->cardControlBF & (CARD_CLK_SLOW|CARD_DELAY1(0x1FFF)|CARD_DELAY2(0x3F)))
|
||||
| CARD_ACTIVATE | CARD_nRESET | CARD_SEC_EN | CARD_SEC_DAT;
|
||||
|
||||
int secureAreaOffset = 0;
|
||||
for (secureBlockNumber = 4; secureBlockNumber < 8; secureBlockNumber++) {
|
||||
createEncryptedCommand (CARD_CMD_SECURE_READ, cmdData, secureBlockNumber);
|
||||
|
||||
if (normalChip) {
|
||||
cardPolledTransfer(portFlagsSecRead, NULL, 0, cmdData);
|
||||
cardDelay(ndsHeader->readTimeout);
|
||||
for (i = 8; i > 0; i--) {
|
||||
cardPolledTransfer(portFlagsSecRead | CARD_BLK_SIZE(1), secureArea + secureAreaOffset, 0x200, cmdData);
|
||||
secureAreaOffset += 0x200/sizeof(u32);
|
||||
}
|
||||
} else {
|
||||
cardPolledTransfer(portFlagsSecRead | CARD_BLK_SIZE(4) | CARD_SEC_LARGE, secureArea + secureAreaOffset, 0x1000, cmdData);
|
||||
secureAreaOffset += 0x1000/sizeof(u32);
|
||||
}
|
||||
}
|
||||
|
||||
// Alllliii jjjkkkkk - Enter Main Data Mode
|
||||
createEncryptedCommand (CARD_CMD_DATA_MODE, cmdData, 0);
|
||||
|
||||
if (normalChip) {
|
||||
cardPolledTransfer(portFlagsKey1, NULL, 0, cmdData);
|
||||
cardDelay(ndsHeader->readTimeout);
|
||||
}
|
||||
cardPolledTransfer(portFlagsKey1, NULL, 0, cmdData);
|
||||
|
||||
// The 0x800 bytes are modcrypted, so this function isn't ran
|
||||
//decryptSecureArea (gameCode->key, secureArea, 1);
|
||||
|
||||
twlBlowfish = true;
|
||||
}
|
||||
|
||||
|
||||
int cardInit (sNDSHeaderExt* ndsHeader, u32* chipID) {
|
||||
u32 portFlagsKey1, portFlagsSecRead;
|
||||
normalChip = false; // As defined by GBAtek, normal chip secure area is accessed in blocks of 0x200, other chip in blocks of 0x1000
|
||||
int secureBlockNumber;
|
||||
int i;
|
||||
u8 cmdData[8] __attribute__ ((aligned));
|
||||
GameCode* gameCode;
|
||||
|
||||
// Dummy command sent after card reset
|
||||
cardParamCommand (CARD_CMD_DUMMY, 0,
|
||||
CARD_ACTIVATE | CARD_nRESET | CARD_CLK_SLOW | CARD_BLK_SIZE(1) | CARD_DELAY1(0x1FFF) | CARD_DELAY2(0x3F),
|
||||
NULL, 0);
|
||||
|
||||
// Read the header
|
||||
cardParamCommand (CARD_CMD_HEADER_READ, 0,
|
||||
CARD_ACTIVATE | CARD_nRESET | CARD_CLK_SLOW | CARD_BLK_SIZE(1) | CARD_DELAY1(0x1FFF) | CARD_DELAY2(0x3F),
|
||||
(void*)headerData, 0x200/sizeof(u32));
|
||||
|
||||
tonccpy(ndsHeader, headerData, 0x200);
|
||||
|
||||
if ((ndsHeader->unitCode != 0) || (ndsHeader->dsi_flags != 0)) {
|
||||
// Extended header found
|
||||
cardParamCommand (CARD_CMD_HEADER_READ, 0,
|
||||
CARD_ACTIVATE | CARD_nRESET | CARD_CLK_SLOW | CARD_BLK_SIZE(4) | CARD_DELAY1(0x1FFF) | CARD_DELAY2(0x3F),
|
||||
(void*)headerData, 0x1000/sizeof(u32));
|
||||
if (ndsHeader->dsi1[0]==0xFFFFFFFF && ndsHeader->dsi1[1]==0xFFFFFFFF
|
||||
&& ndsHeader->dsi1[2]==0xFFFFFFFF && ndsHeader->dsi1[3]==0xFFFFFFFF)
|
||||
{
|
||||
toncset((u8*)headerData+0x200, 0, 0xE00); // Clear out FFs
|
||||
}
|
||||
tonccpy(ndsHeader, headerData, 0x1000);
|
||||
}
|
||||
|
||||
// Check header CRC
|
||||
if (ndsHeader->headerCRC16 != swiCRC16(0xFFFF, (void*)ndsHeader, 0x15E)) { return ERR_HEAD_CRC; }
|
||||
|
||||
/*
|
||||
// Check logo CRC
|
||||
if (ndsHeader->logoCRC16 != 0xCF56) {
|
||||
return ERR_LOGO_CRC;
|
||||
}
|
||||
*/
|
||||
|
||||
// Initialise blowfish encryption for KEY1 commands and decrypting the secure area
|
||||
gameCode = (GameCode*)ndsHeader->gameCode;
|
||||
init_keycode (gameCode->key, 2, 8, 0);
|
||||
|
||||
// Port 40001A4h setting for normal reads (command B7)
|
||||
portFlags = ndsHeader->cardControl13 & ~CARD_BLK_SIZE(7);
|
||||
// Port 40001A4h setting for KEY1 commands (usually 001808F8h)
|
||||
portFlagsKey1 = CARD_ACTIVATE | CARD_nRESET | (ndsHeader->cardControl13 & (CARD_WR|CARD_CLK_SLOW)) |
|
||||
((ndsHeader->cardControlBF & (CARD_CLK_SLOW|CARD_DELAY1(0x1FFF))) + ((ndsHeader->cardControlBF & CARD_DELAY2(0x3F)) >> 16));
|
||||
|
||||
// 1st Get ROM Chip ID
|
||||
cardParamCommand (CARD_CMD_HEADER_CHIPID, 0,
|
||||
(ndsHeader->cardControl13 & (CARD_WR|CARD_nRESET|CARD_CLK_SLOW)) | CARD_ACTIVATE | CARD_BLK_SIZE(7),
|
||||
chipID, sizeof(u32));
|
||||
|
||||
// Adjust card transfer method depending on the most significant bit of the chip ID
|
||||
normalChip = ((*chipID) & 0x80000000) != 0; // ROM chip ID MSB
|
||||
if (!normalChip) { portFlagsKey1 |= CARD_SEC_LARGE; }
|
||||
|
||||
// 3Ciiijjj xkkkkkxx - Activate KEY1 Encryption Mode
|
||||
initKey1Encryption (cmdData, 0);
|
||||
cardPolledTransfer((ndsHeader->cardControl13 & (CARD_WR|CARD_nRESET|CARD_CLK_SLOW)) | CARD_ACTIVATE, NULL, 0, cmdData);
|
||||
|
||||
// 4llllmmm nnnkkkkk - Activate KEY2 Encryption Mode
|
||||
createEncryptedCommand (CARD_CMD_ACTIVATE_SEC, cmdData, 0);
|
||||
|
||||
if (normalChip) {
|
||||
cardPolledTransfer(portFlagsKey1, NULL, 0, cmdData);
|
||||
cardDelay(ndsHeader->readTimeout);
|
||||
}
|
||||
cardPolledTransfer(portFlagsKey1, NULL, 0, cmdData);
|
||||
|
||||
// Set the KEY2 encryption registers
|
||||
REG_ROMCTRL = 0;
|
||||
REG_CARD_1B0 = cardSeedBytes[ndsHeader->deviceType & 0x07] | (key1data.nnn << 15) | (key1data.mmm << 27) | 0x6000;
|
||||
REG_CARD_1B4 = 0x879b9b05;
|
||||
REG_CARD_1B8 = key1data.mmm >> 5;
|
||||
REG_CARD_1BA = 0x5c;
|
||||
REG_ROMCTRL = CARD_nRESET | CARD_SEC_SEED | CARD_SEC_EN | CARD_SEC_DAT;
|
||||
|
||||
// Update the DS card flags to suit KEY2 encryption
|
||||
portFlagsKey1 |= CARD_SEC_EN | CARD_SEC_DAT;
|
||||
|
||||
// 1lllliii jjjkkkkk - 2nd Get ROM Chip ID / Get KEY2 Stream
|
||||
createEncryptedCommand (CARD_CMD_SECURE_CHIPID, cmdData, 0);
|
||||
|
||||
if (normalChip) {
|
||||
cardPolledTransfer(portFlagsKey1, NULL, 0, cmdData);
|
||||
cardDelay(ndsHeader->readTimeout);
|
||||
}
|
||||
cardPolledTransfer(portFlagsKey1 | CARD_BLK_SIZE(7), NULL, 0, cmdData);
|
||||
|
||||
// 2bbbbiii jjjkkkkk - Get Secure Area Block
|
||||
portFlagsSecRead = (ndsHeader->cardControlBF & (CARD_CLK_SLOW|CARD_DELAY1(0x1FFF)|CARD_DELAY2(0x3F)))
|
||||
| CARD_ACTIVATE | CARD_nRESET | CARD_SEC_EN | CARD_SEC_DAT;
|
||||
|
||||
u32* secureAreaOffset = secureArea;
|
||||
for (secureBlockNumber = 4; secureBlockNumber < 8; secureBlockNumber++) {
|
||||
createEncryptedCommand (CARD_CMD_SECURE_READ, cmdData, secureBlockNumber);
|
||||
|
||||
if (normalChip) {
|
||||
cardPolledTransfer(portFlagsSecRead, NULL, 0, cmdData);
|
||||
cardDelay(ndsHeader->readTimeout);
|
||||
for (i = 8; i > 0; i--) {
|
||||
cardPolledTransfer(portFlagsSecRead | CARD_BLK_SIZE(1), secureAreaOffset, 0x200, cmdData);
|
||||
secureAreaOffset += 0x200/sizeof(u32);
|
||||
}
|
||||
} else {
|
||||
cardPolledTransfer(portFlagsSecRead | CARD_BLK_SIZE(4) | CARD_SEC_LARGE, secureAreaOffset, 0x1000, cmdData);
|
||||
secureAreaOffset += 0x1000/sizeof(u32);
|
||||
}
|
||||
}
|
||||
|
||||
// Alllliii jjjkkkkk - Enter Main Data Mode
|
||||
createEncryptedCommand (CARD_CMD_DATA_MODE, cmdData, 0);
|
||||
|
||||
if (normalChip) {
|
||||
cardPolledTransfer(portFlagsKey1, NULL, 0, cmdData);
|
||||
cardDelay(ndsHeader->readTimeout);
|
||||
}
|
||||
cardPolledTransfer(portFlagsKey1, NULL, 0, cmdData);
|
||||
|
||||
//CycloDS doesn't like the dsi secure area being decrypted
|
||||
if((ndsHeader->arm9romOffset != 0x4000) || secureArea[0] || secureArea[1]) {
|
||||
decryptSecureArea (gameCode->key, secureArea, 0);
|
||||
}
|
||||
|
||||
if (secureArea[0] == 0x72636e65 /*'encr'*/ && secureArea[1] == 0x6a624f79 /*'yObj'*/) {
|
||||
// Secure area exists, so just clear the tag
|
||||
secureArea[0] = 0xe7ffdeff;
|
||||
secureArea[1] = 0xe7ffdeff;
|
||||
} else {
|
||||
// Secure area tag is not there, so destroy the entire secure area
|
||||
for (i = 0; i < 0x200; i ++) { secureArea[i] = 0xe7ffdeff; }
|
||||
// Disabled error checks on secure area. This was able to boot a DS-Xtreme. May increase flashcart compatiblity drastically.
|
||||
// return normalChip ? ERR_SEC_NORM : ERR_SEC_OTHR;
|
||||
}
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
void cardRead (u32 src, u32* dest, size_t size) {
|
||||
sNDSHeaderExt* ndsHeader = (sNDSHeaderExt*)headerData;
|
||||
|
||||
size_t readSize;
|
||||
|
||||
if (src > ndsHeader->romSize) { switchToTwlBlowfish(ndsHeader); }
|
||||
|
||||
if (src < CARD_SECURE_AREA_OFFSET) {
|
||||
return;
|
||||
} else if (src < CARD_DATA_OFFSET) {
|
||||
// Read data from secure area
|
||||
readSize = src + size < CARD_DATA_OFFSET ? size : CARD_DATA_OFFSET - src;
|
||||
tonccpy (dest, (u8*)secureArea + src - CARD_SECURE_AREA_OFFSET, readSize);
|
||||
src += readSize;
|
||||
dest += readSize/sizeof(*dest);
|
||||
size -= readSize;
|
||||
} else if ((ndsHeader->unitCode != 0) && (src >= ndsHeader->arm9iromOffset) && (src < ndsHeader->arm9iromOffset+CARD_SECURE_AREA_SIZE)) {
|
||||
// Read data from secure area
|
||||
readSize = src + size < (ndsHeader->arm9iromOffset+CARD_SECURE_AREA_SIZE) ? size : (ndsHeader->arm9iromOffset+CARD_SECURE_AREA_SIZE) - src;
|
||||
tonccpy (dest, (u8*)secureArea + src - ndsHeader->arm9iromOffset, readSize);
|
||||
src += readSize;
|
||||
dest += readSize/sizeof(*dest);
|
||||
size -= readSize;
|
||||
}
|
||||
|
||||
while (size > 0) {
|
||||
readSize = size < CARD_DATA_BLOCK_SIZE ? size : CARD_DATA_BLOCK_SIZE;
|
||||
cardParamCommand (CARD_CMD_DATA_READ, src,
|
||||
portFlags | CARD_ACTIVATE | CARD_nRESET | CARD_BLK_SIZE(1),
|
||||
dest, readSize);
|
||||
src += readSize;
|
||||
dest += readSize/sizeof(*dest);
|
||||
size -= readSize;
|
||||
}
|
||||
}
|
||||
|
39
BootLoaderTWL/source/read_card.h
Normal file
39
BootLoaderTWL/source/read_card.h
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
NitroHax -- Cheat tool for the Nintendo DS
|
||||
Copyright (C) 2008 Michael "Chishm" Chisholm
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
#ifndef READ_CARD_H
|
||||
#define READ_CARD_H
|
||||
|
||||
#include <nds/ndstypes.h>
|
||||
#include <nds/memory.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "ndsheaderbanner.h"
|
||||
|
||||
#define CARD_NDS_HEADER_SIZE (0x200)
|
||||
#define CARD_SECURE_AREA_OFFSET (0x4000)
|
||||
#define CARD_SECURE_AREA_SIZE (0x4000)
|
||||
#define CARD_DATA_OFFSET (0x8000)
|
||||
#define CARD_DATA_BLOCK_SIZE (0x200)
|
||||
|
||||
int cardInit (sNDSHeaderExt* ndsHeader, u32* chipID);
|
||||
|
||||
void cardRead (u32 src, u32* dest, size_t size);
|
||||
|
||||
#endif // READ_CARD_H
|
||||
|
124
BootLoaderTWL/source/tonccpy.c
Normal file
124
BootLoaderTWL/source/tonccpy.c
Normal file
@ -0,0 +1,124 @@
|
||||
#include <stddef.h>
|
||||
#include "tonccpy.h"
|
||||
//# tonccpy.c
|
||||
|
||||
//! VRAM-safe cpy.
|
||||
/*! This version mimics memcpy in functionality, with
|
||||
the benefit of working for VRAM as well. It is also
|
||||
slightly faster than the original memcpy, but faster
|
||||
implementations can be made.
|
||||
\param dst Destination pointer.
|
||||
\param src Source pointer.
|
||||
\param size Fill-length in bytes.
|
||||
\note The pointers and size need not be word-aligned.
|
||||
*/
|
||||
void tonccpy(void *dst, const void *src, uint size) {
|
||||
|
||||
if(size==0 || dst==NULL || src==NULL) { return; }
|
||||
|
||||
uint count;
|
||||
u16 *dst16; // hword destination
|
||||
u8 *src8; // byte source
|
||||
|
||||
// Ideal case: copy by 4x words. Leaves tail for later.
|
||||
if( ((u32)src|(u32)dst)%4==0 && size>=4) {
|
||||
u32 *src32= (u32*)src, *dst32= (u32*)dst;
|
||||
|
||||
count= size/4;
|
||||
uint tmp= count&3;
|
||||
count /= 4;
|
||||
|
||||
// Duff's Device, good friend!
|
||||
switch(tmp) {
|
||||
do { *dst32++ = *src32++;
|
||||
case 3: *dst32++ = *src32++;
|
||||
case 2: *dst32++ = *src32++;
|
||||
case 1: *dst32++ = *src32++;
|
||||
case 0: ; } while(count--);
|
||||
}
|
||||
|
||||
// Check for tail
|
||||
size &= 3;
|
||||
if(size == 0) { return; }
|
||||
src8= (u8*)src32;
|
||||
dst16= (u16*)dst32;
|
||||
} else {
|
||||
// Unaligned.
|
||||
uint dstOfs= (u32)dst&1;
|
||||
src8= (u8*)src;
|
||||
dst16= (u16*)(dst-dstOfs);
|
||||
|
||||
// Head: 1 byte.
|
||||
if(dstOfs != 0) {
|
||||
*dst16= (*dst16 & 0xFF) | *src8++<<8;
|
||||
dst16++;
|
||||
if(--size==0) { return; }
|
||||
}
|
||||
}
|
||||
|
||||
// Unaligned main: copy by 2x byte.
|
||||
count= size/2;
|
||||
while(count--) {
|
||||
*dst16++ = src8[0] | src8[1]<<8;
|
||||
src8 += 2;
|
||||
}
|
||||
|
||||
// Tail: 1 byte.
|
||||
if(size&1) { *dst16= (*dst16 &~ 0xFF) | *src8; }
|
||||
}
|
||||
//# toncset.c
|
||||
|
||||
//! VRAM-safe memset, internal routine.
|
||||
/*! This version mimics memset in functionality, with
|
||||
the benefit of working for VRAM as well. It is also
|
||||
slightly faster than the original memset.
|
||||
\param dst Destination pointer.
|
||||
\param fill Word to fill with.
|
||||
\param size Fill-length in bytes.
|
||||
\note The \a dst pointer and \a size need not be
|
||||
word-aligned. In the case of unaligned fills, \a fill
|
||||
will be masked off to match the situation.
|
||||
*/
|
||||
void __toncset(void *dst, u32 fill, uint size) {
|
||||
if(size==0 || dst==NULL) { return; }
|
||||
|
||||
uint left= (u32)dst&3;
|
||||
u32 *dst32= (u32*)(dst-left);
|
||||
u32 count, mask;
|
||||
|
||||
// Unaligned head.
|
||||
if(left != 0) {
|
||||
// Adjust for very small stint.
|
||||
if(left+size<4) {
|
||||
mask= BIT_MASK(size*8)<<(left*8);
|
||||
*dst32= (*dst32 &~ mask) | (fill & mask);
|
||||
return;
|
||||
}
|
||||
|
||||
mask= BIT_MASK(left*8);
|
||||
*dst32= (*dst32 & mask) | (fill&~mask);
|
||||
dst32++;
|
||||
size -= 4-left;
|
||||
}
|
||||
|
||||
// Main stint.
|
||||
count= size/4;
|
||||
uint tmp= count&3;
|
||||
count /= 4;
|
||||
|
||||
switch(tmp) {
|
||||
do { *dst32++ = fill;
|
||||
case 3: *dst32++ = fill;
|
||||
case 2: *dst32++ = fill;
|
||||
case 1: *dst32++ = fill;
|
||||
case 0: ; } while(count--);
|
||||
}
|
||||
|
||||
// Tail
|
||||
size &= 3;
|
||||
if(size) {
|
||||
mask= BIT_MASK(size*8);
|
||||
*dst32= (*dst32 &~ mask) | (fill & mask);
|
||||
}
|
||||
}
|
||||
|
43
BootLoaderTWL/source/tonccpy.h
Normal file
43
BootLoaderTWL/source/tonccpy.h
Normal file
@ -0,0 +1,43 @@
|
||||
//# Stuff you may not have yet.
|
||||
|
||||
#ifndef TONCCPY_H
|
||||
#define TONCCPY_H
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <nds/ndstypes.h>
|
||||
|
||||
typedef unsigned int uint;
|
||||
#define BIT_MASK(len) ( (1<<(len))-1 )
|
||||
static inline u32 quad8(u8 x) { x |= x<<8; return x | x<<16; }
|
||||
|
||||
|
||||
//# Declarations and inlines.
|
||||
|
||||
void tonccpy(void *dst, const void *src, uint size);
|
||||
|
||||
void __toncset(void *dst, u32 fill, uint size);
|
||||
static inline void toncset(void *dst, u8 src, uint size);
|
||||
static inline void toncset16(void *dst, u16 src, uint size);
|
||||
static inline void toncset32(void *dst, u32 src, uint size);
|
||||
|
||||
|
||||
//! VRAM-safe memset, byte version. Size in bytes.
|
||||
static inline void toncset(void *dst, u8 src, uint size)
|
||||
{ __toncset(dst, quad8(src), size); }
|
||||
|
||||
//! VRAM-safe memset, halfword version. Size in hwords.
|
||||
static inline void toncset16(void *dst, u16 src, uint size)
|
||||
{ __toncset(dst, src|src<<16, size*2); }
|
||||
|
||||
//! VRAM-safe memset, word version. Size in words.
|
||||
static inline void toncset32(void *dst, u32 src, uint size)
|
||||
{ __toncset(dst, src, size*4); }
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
152
LICENSE
152
LICENSE
@ -1,23 +1,21 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
Version 3, 19 November 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
The GNU Affero General Public License is a free, copyleft license for
|
||||
software and other kinds of works, specifically designed to ensure
|
||||
cooperation with the community in the case of network server software.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
our General Public Licenses are intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
software for all its users.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
@ -26,44 +24,34 @@ them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
Developers that use our General Public Licenses protect your rights
|
||||
with two steps: (1) assert copyright on the software, and (2) offer
|
||||
you this License which gives you legal permission to copy, distribute
|
||||
and/or modify the software.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
A secondary benefit of defending all users' freedom is that
|
||||
improvements made in alternate versions of the program, if they
|
||||
receive widespread use, become available for other developers to
|
||||
incorporate. Many developers of free software are heartened and
|
||||
encouraged by the resulting cooperation. However, in the case of
|
||||
software used on network servers, this result may fail to come about.
|
||||
The GNU General Public License permits making a modified version and
|
||||
letting the public access it on a server without ever releasing its
|
||||
source code to the public.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
The GNU Affero General Public License is designed specifically to
|
||||
ensure that, in such cases, the modified source code becomes available
|
||||
to the community. It requires the operator of a network server to
|
||||
provide the source code of the modified version running there to the
|
||||
users of that server. Therefore, public use of a modified version, on
|
||||
a publicly accessible server, gives the public access to the source
|
||||
code of the modified version.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
An older license, called the Affero General Public License and
|
||||
published by Affero, was designed to accomplish similar goals. This is
|
||||
a different license, not a version of the Affero GPL, but Affero has
|
||||
released a new version of the Affero GPL which permits relicensing under
|
||||
this license.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
@ -72,7 +60,7 @@ modification follow.
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
"This License" refers to version 3 of the GNU Affero General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
@ -549,35 +537,45 @@ to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
13. Remote Network Interaction; Use with the GNU General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, if you modify the
|
||||
Program, your modified version must prominently offer all users
|
||||
interacting with it remotely through a computer network (if your version
|
||||
supports such interaction) an opportunity to receive the Corresponding
|
||||
Source of your version by providing access to the Corresponding Source
|
||||
from a network server at no charge, through some standard or customary
|
||||
means of facilitating copying of software. This Corresponding Source
|
||||
shall include the Corresponding Source for any work covered by version 3
|
||||
of the GNU General Public License that is incorporated pursuant to the
|
||||
following paragraph.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
under version 3 of the GNU General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
but the work with which it is combined will remain governed by version
|
||||
3 of the GNU General Public License.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
the GNU Affero General Public License from time to time. Such new versions
|
||||
will be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Program specifies that a certain numbered version of the GNU Affero General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
GNU Affero General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
versions of the GNU Affero General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
@ -618,4 +616,46 @@ an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If your software can interact with users remotely through a computer
|
||||
network, you should also make sure that it provides a way for users to
|
||||
get its source. For example, if your program is a web application, its
|
||||
interface could display a "Source" link that leads users to an archive
|
||||
of the code. There are many ways you could offer source, and different
|
||||
solutions will be better for different programs; see section 13 for the
|
||||
specific requirements.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU AGPL, see
|
||||
<https://www.gnu.org/licenses/>.
|
||||
|
32
Makefile
32
Makefile
@ -11,16 +11,16 @@ export TARGET := NitroHax
|
||||
export TOPDIR := $(CURDIR)
|
||||
|
||||
export VERSION_MAJOR := 0
|
||||
export VERSION_MINOR := 94
|
||||
export VERSION_MINOR := 95
|
||||
export VERSTRING := $(VERSION_MAJOR).$(VERSION_MINOR)
|
||||
|
||||
|
||||
.PHONY: checkarm7 checkarm9
|
||||
.PHONY: dsi checkarm7 checkarm9
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# main targets
|
||||
#---------------------------------------------------------------------------------
|
||||
all: $(TARGET).nds checkarm7 checkarm9
|
||||
all: $(TARGET).nds $(TARGET).dsi checkarm7 checkarm9
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
checkarm7:
|
||||
@ -34,16 +34,31 @@ $(TARGET).nds : arm7/$(TARGET).elf arm9/$(TARGET).elf
|
||||
ndstool -c $(TARGET).nds -7 arm7/$(TARGET).elf -9 arm9/$(TARGET).elf \
|
||||
-b $(CURDIR)/icon.bmp "Nitro Hax;DS Game Cheat Tool;Created by Chishm"
|
||||
|
||||
|
||||
$(TARGET).dsi : arm7/$(TARGET).elf arm9/$(TARGET).elf
|
||||
ndstool -c $(TARGET).dsi -7 arm7/$(TARGET).elf -9 arm9/$(TARGET).elf \
|
||||
-b $(CURDIR)/icon.bmp "Nitro Hax for DSi;DS Game Cheat Tool;Created by Chishm" \
|
||||
-g CHTE 01 "NITROHAXTWL" -z 80040000 -u 00030004 -a 00000038 -p 0000
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# Create boot loader and link raw binary into ARM9 ELF
|
||||
#---------------------------------------------------------------------------------
|
||||
BootLoader/load.bin : BootLoader/source/*
|
||||
$(MAKE) -C BootLoader
|
||||
|
||||
BootLoaderTWL/loadtwl.bin : BootLoaderTWL/source/*
|
||||
$(MAKE) -C BootLoaderTWL
|
||||
|
||||
|
||||
arm9/data/load.bin : BootLoader/load.bin
|
||||
mkdir -p $(@D)
|
||||
cp $< $@
|
||||
|
||||
|
||||
arm9/data/loadtwl.bin : BootLoaderTWL/loadtwl.bin
|
||||
mkdir -p $(@D)
|
||||
cp $< $@
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
arm9/source/version.h : Makefile
|
||||
@echo "#ifndef VERSION_H" > $@
|
||||
@ -58,11 +73,11 @@ arm7/$(TARGET).elf:
|
||||
$(MAKE) -C arm7
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
arm9/$(TARGET).elf : arm9/data/load.bin arm9/source/version.h
|
||||
arm9/$(TARGET).elf : arm9/data/load.bin arm9/data/loadtwl.bin arm9/source/version.h
|
||||
$(MAKE) -C arm9
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
dist-bin : $(TARGET).nds README.md LICENSE
|
||||
dist-bin : $(TARGET).nds $(TARGET).dsi README.md LICENSE
|
||||
zip -X -9 $(TARGET)_v$(VERSTRING).zip $^
|
||||
|
||||
dist-src :
|
||||
@ -71,7 +86,8 @@ dist-src :
|
||||
Makefile icon.bmp LICENSE README.md \
|
||||
arm7/Makefile arm7/source \
|
||||
arm9/Makefile arm9/source arm9/graphics \
|
||||
BootLoader/Makefile BootLoader/load.ld BootLoader/source
|
||||
BootLoader/Makefile BootLoader/load.ld BootLoader/source \
|
||||
BootLoaderTWL/Makefile BootLoaderTWL/loadtwl.ld BootLoaderTWL/source
|
||||
|
||||
dist : dist-bin dist-src
|
||||
|
||||
@ -80,5 +96,7 @@ clean:
|
||||
$(MAKE) -C arm9 clean
|
||||
$(MAKE) -C arm7 clean
|
||||
$(MAKE) -C BootLoader clean
|
||||
$(MAKE) -C BootLoaderTWL clean
|
||||
rm -f arm9/data/load.bin
|
||||
rm -f $(TARGET).ds.gba $(TARGET).nds $(TARGET).arm7 $(TARGET).arm9
|
||||
rm -f arm9/data/loadtwl.bin
|
||||
rm -f $(TARGET).ds.gba $(TARGET).nds $(TARGET).dsi $(TARGET).arm7 $(TARGET).arm9
|
||||
|
11
README.md
11
README.md
@ -1,4 +1,4 @@
|
||||
Nitro Hax
|
||||
Nitro Hax (TWL Build by Apache Thunder)
|
||||
=========
|
||||
|
||||
By Chishm
|
||||
@ -13,6 +13,10 @@ The newest release is available to
|
||||
Usage
|
||||
=====
|
||||
|
||||
Note: For DSi users able to use Unlaunch to launch NitroHax from DSi SD, the step
|
||||
of replacing the cart with the game during 5 and 6 are not required.
|
||||
Cheats will be stored on DSi SD instead of flashcart.
|
||||
|
||||
1. Patch NitroHax.nds with a DLDI file if you need to.
|
||||
2. Copy the NitroHax.nds file to your media device.
|
||||
3. Place an Action Replay XML file on your media device.
|
||||
@ -24,9 +28,10 @@ Usage
|
||||
* "/data/NitroHax/cheats.xml"
|
||||
* "/cheats.xml"
|
||||
2. If no file is found, browse for and select a file to open.
|
||||
5. Remove your media device if you want to.
|
||||
6. Remove any card that is in Slot-1
|
||||
5. Remove your media device if you want to. (Not applicable on DSi)
|
||||
6. Remove any card that is in Slot-1 (Not applicable on DSi)
|
||||
7. Insert the DS game into Slot-1
|
||||
(Not applicable on DSi. Program will wait for user to insert game if booted up with slot empty)
|
||||
8. Choose the cheats you want to enable.
|
||||
1. Some cheats are enabled by default and others may be always on. This is
|
||||
specified in the XML file.
|
||||
|
@ -22,13 +22,9 @@
|
||||
|
||||
#include "cheat_engine_arm7.h"
|
||||
|
||||
void VcountHandler() { inputGetAndSend(); }
|
||||
|
||||
void VcountHandler() {
|
||||
inputGetAndSend();
|
||||
}
|
||||
|
||||
void VblankHandler(void) {
|
||||
}
|
||||
void VblankHandler(void) { }
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
int main(void) {
|
||||
@ -52,6 +48,11 @@ int main(void) {
|
||||
|
||||
irqEnable( IRQ_VBLANK | IRQ_VCOUNT);
|
||||
|
||||
if (REG_SNDEXTCNT != 0) {
|
||||
i2cWriteRegister(0x4A, 0x12, 0x00); // Press power-button for auto-reset
|
||||
i2cWriteRegister(0x4A, 0x70, 0x01); // Bootflag = Warmboot/SkipHealthSafety
|
||||
}
|
||||
|
||||
// Keep the ARM7 mostly idle
|
||||
while (1) {
|
||||
runCheatEngineCheck();
|
||||
|
@ -28,7 +28,7 @@ ARCH := -march=armv5te -mtune=arm946e-s -mthumb -mthumb-interwork
|
||||
CFLAGS := -g -Wall -O2\
|
||||
-fomit-frame-pointer\
|
||||
-ffast-math \
|
||||
-Wall -Wextra -Werror \
|
||||
-Wall -Wextra \
|
||||
$(ARCH)
|
||||
|
||||
CFLAGS += $(INCLUDE) -DARM9
|
||||
@ -36,7 +36,7 @@ CXXFLAGS := $(CFLAGS)
|
||||
|
||||
ASFLAGS := -g $(ARCH) $(INCLUDE)
|
||||
|
||||
LDFLAGS = -specs=ds_arm9.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
|
||||
LDFLAGS = -specs=dsi_arm9.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# any extra libraries we wish to link with the project
|
||||
@ -128,6 +128,12 @@ bgtop.s : ../$(IMAGES)/bgtop.bmp
|
||||
bgsub.s : ../$(IMAGES)/bgsub.bmp
|
||||
grit $< -gB4 -gzl -fts -o $@ -q
|
||||
|
||||
bgtopTWL.s : ../$(IMAGES)/bgtopTWL.bmp
|
||||
grit $< -gB4 -gzl -fts -o $@ -q
|
||||
|
||||
bgsubTWL.s : ../$(IMAGES)/bgsubTWL.bmp
|
||||
grit $< -gB4 -gzl -fts -o $@ -q
|
||||
|
||||
cursor.s : ../$(IMAGES)/cursor.bmp
|
||||
grit $< -gB4 -fts -Mw8 -Mh4 -o $@ -q
|
||||
|
||||
|
BIN
arm9/graphics/bgsubTWL.bmp
Normal file
BIN
arm9/graphics/bgsubTWL.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 144 KiB |
BIN
arm9/graphics/bgtopTWL.bmp
Normal file
BIN
arm9/graphics/bgtopTWL.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 144 KiB |
@ -20,10 +20,14 @@
|
||||
#include <nds.h>
|
||||
|
||||
#include "load_bin.h"
|
||||
#include "loadtwl_bin.h"
|
||||
#include "cheat_engine.h"
|
||||
|
||||
#define LCDC_BANK_C (vu16*)0x06840000
|
||||
#define LCDC_BANK_D (vu16*)0x06860000
|
||||
|
||||
#define CHEAT_DATA_LOCATION ((u32*)0x06850000)
|
||||
#define CHEAT_DATA_LOCATIONTWL ((u32*)0x06870000)
|
||||
#define CHEAT_CODE_END 0xCF000000
|
||||
|
||||
static void vramset (volatile void* dst, u16 val, int len)
|
||||
@ -46,30 +50,56 @@ static void vramcpy (volatile void* dst, const void* src, int len)
|
||||
}
|
||||
}
|
||||
|
||||
void runCheatEngine (void* cheats, int cheatLength)
|
||||
void runCheatEngine (void* cheats, int cheatLength, bool isTWLCart)
|
||||
{
|
||||
irqDisable(IRQ_ALL);
|
||||
|
||||
|
||||
// Direct CPU access to VRAM bank C
|
||||
VRAM_C_CR = VRAM_ENABLE | VRAM_C_LCD;
|
||||
// Clear VRAM
|
||||
vramset (LCDC_BANK_C, 0x0000, 128 * 1024);
|
||||
// Load the loader/patcher into the correct address
|
||||
vramcpy (LCDC_BANK_C, load_bin, load_bin_size);
|
||||
// Put the codes 64KiB after the start of the loader
|
||||
vramcpy (CHEAT_DATA_LOCATION, cheats, cheatLength);
|
||||
// Mark the end of the code list
|
||||
CHEAT_DATA_LOCATION[cheatLength/sizeof(u32)] = CHEAT_CODE_END;
|
||||
CHEAT_DATA_LOCATION[cheatLength/sizeof(u32) + 1] = 0;
|
||||
|
||||
// Give the VRAM to the ARM7
|
||||
VRAM_C_CR = VRAM_ENABLE | VRAM_C_ARM7_0x06000000;
|
||||
// The original bootloader fails to boot TWL carts. Using an alternate for those for now.
|
||||
// With new bootloader Arm9 SCFG settings occur there instead.
|
||||
if (isTWLCart) {
|
||||
VRAM_D_CR = VRAM_ENABLE | VRAM_D_LCD;
|
||||
vramset (LCDC_BANK_D, 0x0000, 128 * 1024);
|
||||
vramcpy (LCDC_BANK_D, loadtwl_bin, loadtwl_bin_size);
|
||||
vramcpy (CHEAT_DATA_LOCATIONTWL, cheats, cheatLength);
|
||||
CHEAT_DATA_LOCATIONTWL[cheatLength/sizeof(u32)] = CHEAT_CODE_END;
|
||||
CHEAT_DATA_LOCATIONTWL[cheatLength/sizeof(u32) + 1] = 0;
|
||||
VRAM_D_CR = VRAM_ENABLE | VRAM_D_ARM7_0x06020000;
|
||||
REG_EXMEMCNT = 0xffff;
|
||||
*(vu32*)0x02FFFFFC = 0;
|
||||
*(vu32*)0x02FFFE04 = (u32)0xE59FF018; // ldr pc, 0x02FFFE24
|
||||
*(vu32*)0x02FFFE24 = (u32)0x02FFFE04; // Set ARM9 Loop address --> resetARM9(0x02FFFE04);
|
||||
resetARM7(0x06020000);
|
||||
} else {
|
||||
// Direct CPU access to VRAM bank C
|
||||
VRAM_C_CR = VRAM_ENABLE | VRAM_C_LCD;
|
||||
// Clear VRAM
|
||||
vramset (LCDC_BANK_C, 0x0000, 128 * 1024);
|
||||
// Load the loader/patcher into the correct address
|
||||
vramcpy (LCDC_BANK_C, load_bin, load_bin_size);
|
||||
// Put the codes 64KiB after the start of the loader
|
||||
vramcpy (CHEAT_DATA_LOCATION, cheats, cheatLength);
|
||||
// Mark the end of the code list
|
||||
CHEAT_DATA_LOCATION[cheatLength/sizeof(u32)] = CHEAT_CODE_END;
|
||||
CHEAT_DATA_LOCATION[cheatLength/sizeof(u32) + 1] = 0;
|
||||
|
||||
// Reset into a passme loop
|
||||
REG_EXMEMCNT = 0xffff;
|
||||
*((vu32*)0x027FFFFC) = 0;
|
||||
*((vu32*)0x027FFE04) = (u32)0xE59FF018;
|
||||
*((vu32*)0x027FFE24) = (u32)0x027FFE04;
|
||||
// Give the VRAM to the ARM7
|
||||
VRAM_C_CR = VRAM_ENABLE | VRAM_C_ARM7_0x06000000;
|
||||
|
||||
// Set MBK and lock SCFG_EXT registers and if not a TWL enhanced cart. (must be locked later in bootloader if TWL cart)
|
||||
// Set standard NTR configuration for SCFG and MBK registers. (MBK 1-5 set only on Arm7. Done in bootloader for now)
|
||||
if (REG_SCFG_EXT & BIT(31)) {
|
||||
REG_MBK6 = 0x00003000;
|
||||
REG_MBK7 = 0x00003000;
|
||||
REG_MBK8 = 0x00003000;
|
||||
REG_SCFG_CLK = 0x80;
|
||||
REG_SCFG_EXT = 0x03000000;
|
||||
}
|
||||
|
||||
// Reset into a passme loop
|
||||
REG_EXMEMCNT = 0xffff;
|
||||
*((vu32*)0x027FFFFC) = 0;
|
||||
*((vu32*)0x027FFE04) = (u32)0xE59FF018;
|
||||
*((vu32*)0x027FFE24) = (u32)0x027FFE04;
|
||||
}
|
||||
swiSoftReset();
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
void runCheatEngine (void* cheats, int cheatLength);
|
||||
void runCheatEngine (void* cheats, int cheatLength, bool isTWLCart);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
112
arm9/source/encryption.c
Normal file
112
arm9/source/encryption.c
Normal file
@ -0,0 +1,112 @@
|
||||
/*
|
||||
NitroHax -- Cheat tool for the Nintendo DS
|
||||
Copyright (C) 2008 Michael "Chishm" Chisholm
|
||||
|
||||
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 <string.h>
|
||||
#include "encryption.h"
|
||||
#include "key1.h"
|
||||
#include "key2.h"
|
||||
#include "tonccpy.h"
|
||||
|
||||
#define KEYSIZE 0x1048
|
||||
|
||||
static u32 keycode [3];
|
||||
static u32 keybuf [KEYSIZE/sizeof(u32)];
|
||||
|
||||
void crypt_64bit_up (u32* ptr) {
|
||||
u32 x = ptr[1];
|
||||
u32 y = ptr[0];
|
||||
u32 z;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 0x10; i++) {
|
||||
z = keybuf[i] ^ x;
|
||||
x = keybuf[0x012 + ((z>>24)&0xff)];
|
||||
x = keybuf[0x112 + ((z>>16)&0xff)] + x;
|
||||
x = keybuf[0x212 + ((z>> 8)&0xff)] ^ x;
|
||||
x = keybuf[0x312 + ((z>> 0)&0xff)] + x;
|
||||
x = y ^ x;
|
||||
y = z;
|
||||
}
|
||||
|
||||
ptr[0] = x ^ keybuf[0x10];
|
||||
ptr[1] = y ^ keybuf[0x11];
|
||||
}
|
||||
|
||||
void crypt_64bit_down (u32* ptr) {
|
||||
u32 x = ptr[1];
|
||||
u32 y = ptr[0];
|
||||
u32 z;
|
||||
int i;
|
||||
|
||||
for (i = 0x11; i > 0x01; i--) {
|
||||
z = keybuf[i] ^ x;
|
||||
x = keybuf[0x012 + ((z>>24)&0xff)];
|
||||
x = keybuf[0x112 + ((z>>16)&0xff)] + x;
|
||||
x = keybuf[0x212 + ((z>> 8)&0xff)] ^ x;
|
||||
x = keybuf[0x312 + ((z>> 0)&0xff)] + x;
|
||||
x = y ^ x;
|
||||
y = z;
|
||||
}
|
||||
|
||||
ptr[0] = x ^ keybuf[0x01];
|
||||
ptr[1] = y ^ keybuf[0x00];
|
||||
}
|
||||
|
||||
static u32 bswap_32bit (u32 in) {
|
||||
u8 a,b,c,d;
|
||||
a = (u8)((in >> 0) & 0xff);
|
||||
b = (u8)((in >> 8) & 0xff);
|
||||
c = (u8)((in >> 16) & 0xff);
|
||||
d = (u8)((in >> 24) & 0xff);
|
||||
|
||||
u32 out = (a << 24) | (b << 16) | (c << 8) | (d << 0);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
void apply_keycode (u32 modulo) {
|
||||
u32 scratch[2];
|
||||
int i;
|
||||
modulo = modulo / sizeof(*keycode);
|
||||
|
||||
crypt_64bit_up (&keycode[1]);
|
||||
crypt_64bit_up (&keycode[0]);
|
||||
toncset (scratch, 0, 8);
|
||||
|
||||
for (i = 0; i < 0x12; i+=1) {
|
||||
keybuf[i] = keybuf[i] ^ bswap_32bit (keycode[i % modulo]);
|
||||
}
|
||||
for (i = 0; i < 0x412; i+=2) {
|
||||
crypt_64bit_up (scratch);
|
||||
keybuf[i] = scratch[1];
|
||||
keybuf[i+1] = scratch[0];
|
||||
}
|
||||
}
|
||||
|
||||
void init_keycode (u32 idcode, u32 level, u32 modulo, int iCardDevice) {
|
||||
tonccpy ((u8*)keybuf, (iCardDevice ? gEncrDataTwl : gEncrData), KEYSIZE);
|
||||
keycode[0] = idcode;
|
||||
keycode[1] = idcode/2;
|
||||
keycode[2] = idcode*2;
|
||||
|
||||
if (level >= 1) apply_keycode (modulo); // first apply (always)
|
||||
if (level >= 2) apply_keycode (modulo); // second apply (optional)
|
||||
keycode[1] = keycode[1] * 2;
|
||||
keycode[2] = keycode[2] / 2;
|
||||
if (level >= 3) apply_keycode (modulo); // third apply (optional)
|
||||
}
|
27
arm9/source/encryption.h
Normal file
27
arm9/source/encryption.h
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
NitroHax -- Cheat tool for the Nintendo DS
|
||||
Copyright (C) 2008 Michael "Chishm" Chisholm
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
#ifndef ENCRYPTION_H
|
||||
#define ENCRYPTION_H
|
||||
|
||||
#include <nds/ndstypes.h>
|
||||
void init_keycode (u32 idcode, u32 level, u32 modulo, int iCardDevice);
|
||||
void crypt_64bit_down (u32* ptr);
|
||||
void crypt_64bit_up (u32* ptr);
|
||||
|
||||
#endif
|
264
arm9/source/key1.h
Normal file
264
arm9/source/key1.h
Normal file
@ -0,0 +1,264 @@
|
||||
const unsigned char gEncrData[] =
|
||||
{
|
||||
0x99,0xD5,0x20,0x5F,0x57,0x44,0xF5,0xB9,0x6E,0x19,0xA4,0xD9,0x9E,0x6A,0x5A,0x94,
|
||||
0xD8,0xAE,0xF1,0xEB,0x41,0x75,0xE2,0x3A,0x93,0x82,0xD0,0x32,0x33,0xEE,0x31,0xD5,
|
||||
0xCC,0x57,0x61,0x9A,0x37,0x06,0xA2,0x1B,0x79,0x39,0x72,0xF5,0x55,0xAE,0xF6,0xBE,
|
||||
0x5F,0x1B,0x69,0xFB,0xE5,0x9D,0xF1,0xE9,0xCE,0x2C,0xD9,0xA1,0x5E,0x32,0x05,0xE6,
|
||||
0xFE,0xD3,0xFE,0xCF,0xD4,0x62,0x04,0x0D,0x8B,0xF5,0xEC,0xB7,0x2B,0x60,0x79,0xBB,
|
||||
0x12,0x95,0x31,0x0D,0x6E,0x3F,0xDA,0x2B,0x88,0x84,0xF0,0xF1,0x3D,0x12,0x7E,0x25,
|
||||
0x45,0x22,0xF1,0xBB,0x24,0x06,0x1A,0x06,0x11,0xAD,0xDF,0x28,0x8B,0x64,0x81,0x34,
|
||||
0x2B,0xEB,0x33,0x29,0x99,0xAA,0xF2,0xBD,0x9C,0x14,0x95,0x9D,0x9F,0xF7,0xF5,0x8C,
|
||||
0x72,0x97,0xA1,0x29,0x9D,0xD1,0x5F,0xCF,0x66,0x4D,0x07,0x1A,0xDE,0xD3,0x4A,0x4B,
|
||||
0x85,0xC9,0xA7,0xA3,0x17,0x95,0x05,0x3A,0x3D,0x49,0x0A,0xBF,0x0A,0x89,0x8B,0xA2,
|
||||
0x4A,0x82,0x49,0xDD,0x27,0x90,0xF1,0x0B,0xE9,0xEB,0x1C,0x6A,0x83,0x76,0x45,0x05,
|
||||
0xBA,0x81,0x70,0x61,0x17,0x3F,0x4B,0xDE,0xAE,0xCF,0xAB,0x39,0x57,0xF2,0x3A,0x56,
|
||||
0x48,0x11,0xAD,0x8A,0x40,0xE1,0x45,0x3F,0xFA,0x9B,0x02,0x54,0xCA,0xA6,0x93,0xFB,
|
||||
0xEF,0x4D,0xFE,0x6F,0xA3,0xD8,0x87,0x9C,0x08,0xBA,0xD5,0x48,0x6A,0x8D,0x2D,0xFD,
|
||||
0x6E,0x15,0xF8,0x74,0xBD,0xBE,0x52,0x8B,0x18,0x22,0x8A,0x9E,0xFB,0x74,0x37,0x07,
|
||||
0x1B,0x36,0x6C,0x4A,0x19,0xBA,0x42,0x62,0xB9,0x79,0x91,0x10,0x7B,0x67,0x65,0x96,
|
||||
0xFE,0x02,0x23,0xE8,0xEE,0x99,0x8C,0x77,0x3E,0x5C,0x86,0x64,0x4D,0x6D,0x78,0x86,
|
||||
0xA5,0x4F,0x65,0xE2,0x1E,0xB2,0xDF,0x5A,0x0A,0xD0,0x7E,0x08,0x14,0xB0,0x71,0xAC,
|
||||
0xBD,0xDB,0x83,0x1C,0xB9,0xD7,0xA1,0x62,0xCD,0xC6,0x63,0x7C,0x52,0x69,0xC3,0xE6,
|
||||
0xBF,0x75,0xCE,0x12,0x44,0x5D,0x21,0x04,0xFA,0xFB,0xD3,0x3C,0x38,0x11,0x63,0xD4,
|
||||
0x95,0x85,0x41,0x49,0x46,0x09,0xF2,0x08,0x43,0x11,0xDC,0x1F,0x76,0xC0,0x15,0x6D,
|
||||
0x1F,0x3C,0x63,0x70,0xEA,0x87,0x80,0x6C,0xC3,0xBD,0x63,0x8B,0xC2,0x37,0x21,0x37,
|
||||
0xDC,0xEE,0x09,0x23,0x2E,0x37,0x6A,0x4D,0x73,0x90,0xF7,0x50,0x30,0xAC,0x1C,0x92,
|
||||
0x04,0x10,0x23,0x91,0x4F,0xD2,0x07,0xAA,0x68,0x3E,0x4F,0x9A,0xC9,0x64,0x60,0x6A,
|
||||
0xC8,0x14,0x21,0xF3,0xD6,0x22,0x41,0x12,0x44,0x24,0xCF,0xE6,0x8A,0x56,0xDD,0x0D,
|
||||
0x53,0x4D,0xE1,0x85,0x1E,0x8C,0x52,0x5A,0x9C,0x19,0x84,0xC2,0x03,0x57,0xF1,0x6F,
|
||||
0xE3,0x00,0xBE,0x58,0xF6,0x4C,0xED,0xD5,0x21,0x64,0x9C,0x1F,0xBE,0x55,0x03,0x3C,
|
||||
0x4A,0xDC,0xFF,0xAA,0xC9,0xDA,0xE0,0x5D,0x5E,0xBF,0xE6,0xDE,0xF5,0xD8,0xB1,0xF8,
|
||||
0xFF,0x36,0xB3,0xB9,0x62,0x67,0x95,0xDB,0x31,0x5F,0x37,0xED,0x4C,0x70,0x67,0x99,
|
||||
0x90,0xB5,0x18,0x31,0x6C,0x3D,0x99,0x99,0xE4,0x42,0xDA,0xD3,0x25,0x42,0x13,0xA0,
|
||||
0xAE,0xD7,0x70,0x6C,0xB1,0x55,0xCF,0xC7,0xD7,0x46,0xD5,0x43,0x61,0x17,0x3D,0x44,
|
||||
0x28,0xE9,0x33,0x85,0xD5,0xD0,0xA2,0x93,0xAA,0x25,0x12,0x1F,0xFB,0xC5,0x0B,0x46,
|
||||
0xF5,0x97,0x76,0x56,0x45,0xA6,0xBE,0x87,0xB1,0x94,0x6B,0xE8,0xB1,0xFE,0x33,0x99,
|
||||
0xAE,0x1F,0x3E,0x6C,0x39,0x71,0x1D,0x09,0x00,0x90,0x37,0xE4,0x10,0x3E,0x75,0x74,
|
||||
0xFF,0x8C,0x83,0x3B,0xB0,0xF1,0xB0,0xF9,0x01,0x05,0x47,0x42,0x95,0xF1,0xD6,0xAC,
|
||||
0x7E,0x38,0xE6,0x9E,0x95,0x74,0x26,0x3F,0xB4,0x68,0x50,0x18,0xD0,0x43,0x30,0xB4,
|
||||
0x4C,0x4B,0xE3,0x68,0xBF,0xE5,0x4D,0xB6,0x95,0x8B,0x0A,0xA0,0x74,0x25,0x32,0x77,
|
||||
0xCF,0xA1,0xF7,0x2C,0xD8,0x71,0x13,0x5A,0xAB,0xEA,0xC9,0x51,0xE8,0x0D,0xEE,0xEF,
|
||||
0xE9,0x93,0x7E,0x19,0xA7,0x1E,0x43,0x38,0x81,0x16,0x2C,0xA1,0x48,0xE3,0x73,0xCC,
|
||||
0x29,0x21,0x6C,0xD3,0x5D,0xCE,0xA0,0xD9,0x61,0x71,0x43,0xA0,0x15,0x13,0xB5,0x64,
|
||||
0x92,0xCF,0x2A,0x19,0xDC,0xAD,0xB7,0xA5,0x9F,0x86,0x65,0xF8,0x1A,0x9F,0xE7,0xFB,
|
||||
0xF7,0xFD,0xB8,0x13,0x6C,0x27,0xDB,0x6F,0xDF,0x35,0x1C,0xF7,0x8D,0x2C,0x5B,0x9B,
|
||||
0x12,0xAB,0x38,0x64,0x06,0xCC,0xDE,0x31,0xE8,0x4E,0x75,0x11,0x64,0xE3,0xFA,0xEA,
|
||||
0xEB,0x34,0x54,0xC2,0xAD,0x3F,0x34,0xEB,0x93,0x2C,0x7D,0x26,0x36,0x9D,0x56,0xF3,
|
||||
0x5A,0xE1,0xF6,0xB3,0x98,0x63,0x4A,0x9E,0x32,0x83,0xE4,0x9A,0x84,0x60,0x7D,0x90,
|
||||
0x2E,0x13,0x0E,0xEE,0x93,0x4B,0x36,0xA2,0x85,0xEC,0x16,0x38,0xE8,0x88,0x06,0x02,
|
||||
0xBF,0xF0,0xA0,0x3A,0xED,0xD7,0x6A,0x9A,0x73,0xE1,0x57,0xCF,0xF8,0x44,0xB8,0xDC,
|
||||
0x2E,0x23,0x59,0xD1,0xDF,0x95,0x52,0x71,0x99,0x61,0xA0,0x4B,0xD5,0x7F,0x6E,0x78,
|
||||
0xBA,0xA9,0xC5,0x30,0xD3,0x40,0x86,0x32,0x9D,0x32,0x0C,0x9C,0x37,0xB7,0x02,0x2F,
|
||||
0xBA,0x54,0x98,0xA9,0xC4,0x13,0x04,0xC9,0x8D,0xBE,0xC8,0xE7,0x5D,0x97,0x50,0x2E,
|
||||
0x93,0xD6,0x22,0x59,0x0C,0x27,0xBC,0x22,0x92,0xE0,0xA7,0x20,0x0F,0x93,0x6F,0x7F,
|
||||
0x4C,0x9F,0xD3,0xB5,0xA6,0x2A,0x0B,0x74,0x67,0x49,0x7D,0x10,0x26,0xCB,0xD1,0xC5,
|
||||
0x86,0x71,0xE7,0x8C,0xA0,0x9C,0xE9,0x5B,0xB2,0x1A,0xF6,0x01,0xEE,0x8C,0x9E,0x5E,
|
||||
0x83,0xF2,0x1A,0xDB,0xE6,0xE5,0xEA,0x84,0x59,0x76,0xD2,0x7C,0xF6,0x8D,0xA5,0x49,
|
||||
0x36,0x48,0xC2,0x16,0x52,0xBB,0x83,0xA3,0x74,0xB9,0x07,0x0C,0x3B,0xFF,0x61,0x28,
|
||||
0xE1,0x61,0xE9,0xE4,0xEF,0x6E,0x15,0xAA,0x4E,0xBA,0xE8,0x5D,0x05,0x96,0xBB,0x32,
|
||||
0x56,0xB0,0xFB,0x72,0x52,0x0F,0x0E,0xC8,0x42,0x25,0x65,0x76,0x89,0xAF,0xF2,0xDE,
|
||||
0x10,0x27,0xF0,0x01,0x4B,0x74,0xA7,0x97,0x07,0xD5,0x26,0x54,0x54,0x09,0x1F,0x82,
|
||||
0x0A,0x86,0x7D,0x30,0x39,0x0E,0xB3,0x26,0x9B,0x0B,0x57,0xBB,0x36,0x06,0x31,0xAF,
|
||||
0xFD,0x79,0xFC,0xD9,0x30,0x10,0x2B,0x0C,0xB3,0xE1,0x9B,0xD7,0x7B,0xDC,0x5F,0xEF,
|
||||
0xD2,0xF8,0x13,0x45,0x4D,0x47,0x75,0xBD,0x46,0x96,0x3C,0x7E,0x75,0xF3,0x3E,0xB5,
|
||||
0x67,0xC5,0x9A,0x3B,0xB0,0x5B,0x29,0x6B,0xDE,0x80,0x5B,0xC8,0x15,0x05,0xB1,0x31,
|
||||
0xB6,0xCE,0x49,0xDD,0xAD,0x84,0xB5,0xAE,0x60,0xDC,0x67,0x31,0x34,0x30,0xFE,0x4E,
|
||||
0xBD,0x80,0x2F,0xA6,0xBF,0x63,0x39,0x21,0x86,0xD9,0x35,0x7F,0x16,0x68,0x22,0x05,
|
||||
0x54,0xE9,0x90,0x26,0x8C,0x07,0x6C,0x51,0xA4,0x31,0x55,0xD7,0x09,0x07,0xA8,0x3E,
|
||||
0x2E,0x53,0x66,0xC1,0xF8,0xF2,0x7B,0xC4,0xF2,0x58,0xCF,0xF1,0x87,0xC5,0xA2,0xE7,
|
||||
0x27,0x8F,0x30,0x87,0x58,0xA0,0x64,0x62,0x23,0x18,0xB9,0x88,0x7C,0xFA,0xCE,0xC4,
|
||||
0x98,0xAE,0xAD,0x17,0xCC,0x4A,0x5B,0xF3,0xE9,0x48,0xD5,0x56,0xD3,0x0D,0xF2,0xC8,
|
||||
0x92,0x73,0x8C,0xDB,0xD7,0x2F,0x56,0xAC,0x81,0xF9,0x92,0x69,0x4D,0xC6,0x32,0xF6,
|
||||
0xE6,0xC0,0x8D,0x21,0xE2,0x76,0x80,0x61,0x11,0xBC,0xDC,0x6C,0x93,0xAF,0x19,0x69,
|
||||
0x9B,0xD0,0xBF,0xB9,0x31,0x9F,0x02,0x67,0xA3,0x51,0xEE,0x83,0x06,0x22,0x7B,0x0C,
|
||||
0xAB,0x49,0x42,0x40,0xB8,0xD5,0x01,0x7D,0xCE,0x5E,0xF7,0x55,0x53,0x39,0xC5,0x99,
|
||||
0x46,0xD8,0x87,0x9F,0xBA,0xF7,0x64,0xB4,0xE3,0x9A,0xFA,0xA1,0x6D,0x90,0x68,0x10,
|
||||
0x30,0xCA,0x8A,0x54,0xA7,0x9F,0x60,0xC3,0x19,0xF5,0x6B,0x0D,0x7A,0x51,0x98,0xE6,
|
||||
0x98,0x43,0x51,0xB4,0xD6,0x35,0xE9,0x4F,0xC3,0xDF,0x0F,0x7B,0xD6,0x2F,0x5C,0xBD,
|
||||
0x3A,0x15,0x61,0x19,0xF1,0x4B,0xCB,0xAA,0xDC,0x6D,0x64,0xC9,0xD3,0xC6,0x1E,0x56,
|
||||
0xEF,0x38,0x4C,0x50,0x71,0x86,0x75,0xCC,0x0D,0x0D,0x4E,0xE9,0x28,0xF6,0x06,0x5D,
|
||||
0x70,0x1B,0xAA,0xD3,0x45,0xCF,0xA8,0x39,0xAC,0x95,0xA6,0x2E,0xB4,0xE4,0x22,0xD4,
|
||||
0x74,0xA8,0x37,0x5F,0x48,0x7A,0x04,0xCC,0xA5,0x4C,0x40,0xD8,0x28,0xB4,0x28,0x08,
|
||||
0x0D,0x1C,0x72,0x52,0x41,0xF0,0x7D,0x47,0x19,0x3A,0x53,0x4E,0x58,0x84,0x62,0x6B,
|
||||
0x93,0xB5,0x8A,0x81,0x21,0x4E,0x0D,0xDC,0xB4,0x3F,0xA2,0xC6,0xFC,0xC9,0x2B,0x40,
|
||||
0xDA,0x38,0x04,0xE9,0x5E,0x5A,0x86,0x6B,0x0C,0x22,0x25,0x85,0x68,0x11,0x8D,0x7C,
|
||||
0x92,0x1D,0x95,0x55,0x4D,0xAB,0x8E,0xBB,0xDA,0xA6,0xE6,0xB7,0x51,0xB6,0x32,0x5A,
|
||||
0x05,0x41,0xDD,0x05,0x2A,0x0A,0x56,0x50,0x91,0x17,0x47,0xCC,0xC9,0xE6,0x7E,0xB5,
|
||||
0x61,0x4A,0xDB,0x73,0x67,0x51,0xC8,0x33,0xF5,0xDA,0x6E,0x74,0x2E,0x54,0xC3,0x37,
|
||||
0x0D,0x6D,0xAF,0x08,0xE8,0x15,0x8A,0x5F,0xE2,0x59,0x21,0xCD,0xA8,0xDE,0x0C,0x06,
|
||||
0x5A,0x77,0x6B,0x5F,0xDB,0x18,0x65,0x3E,0xC8,0x50,0xDE,0x78,0xE0,0xB8,0x82,0xB3,
|
||||
0x5D,0x4E,0x72,0x32,0x07,0x4F,0xC1,0x34,0x23,0xBA,0x96,0xB7,0x67,0x4E,0xA4,0x28,
|
||||
0x1E,0x34,0x62,0xEB,0x2D,0x6A,0x70,0xE9,0x2F,0x42,0xC4,0x70,0x4E,0x5A,0x31,0x9C,
|
||||
0xF9,0x5B,0x47,0x28,0xAA,0xDA,0x71,0x6F,0x38,0x1F,0xB3,0x78,0xC4,0x92,0x6B,0x1C,
|
||||
0x9E,0xF6,0x35,0x9A,0xB7,0x4D,0x0E,0xBF,0xCC,0x18,0x29,0x41,0x03,0x48,0x35,0x5D,
|
||||
0x55,0xD0,0x2B,0xC6,0x29,0xAF,0x5C,0x60,0x74,0x69,0x8E,0x5E,0x9B,0x7C,0xD4,0xBD,
|
||||
0x7B,0x44,0x64,0x7D,0x3F,0x92,0x5D,0x69,0xB6,0x1F,0x00,0x4B,0xD4,0x83,0x35,0xCF,
|
||||
0x7E,0x64,0x4E,0x17,0xAE,0x8D,0xD5,0x2E,0x9A,0x28,0x12,0x4E,0x2E,0x2B,0x49,0x08,
|
||||
0x5C,0xAE,0xC6,0x46,0x85,0xAE,0x41,0x61,0x1E,0x6F,0x82,0xD2,0x51,0x37,0x16,0x1F,
|
||||
0x0B,0xF6,0x59,0xA4,0x9A,0xCA,0x5A,0xAF,0x0D,0xD4,0x33,0x8B,0x20,0x63,0xF1,0x84,
|
||||
0x80,0x5C,0xCB,0xCF,0x08,0xB4,0xB9,0xD3,0x16,0x05,0xBD,0x62,0x83,0x31,0x9B,0x56,
|
||||
0x51,0x98,0x9F,0xBA,0xB2,0x5B,0xAA,0xB2,0x22,0x6B,0x2C,0xB5,0xD4,0x48,0xFA,0x63,
|
||||
0x2B,0x5F,0x58,0xFA,0x61,0xFA,0x64,0x09,0xBB,0x38,0xE0,0xB8,0x9D,0x92,0x60,0xA8,
|
||||
0x0D,0x67,0x6F,0x0E,0x37,0xF5,0x0D,0x01,0x9F,0xC2,0x77,0xD4,0xFE,0xEC,0xF1,0x73,
|
||||
0x30,0x39,0xE0,0x7D,0xF5,0x61,0x98,0xE4,0x2C,0x28,0x55,0x04,0x56,0x55,0xDB,0x2F,
|
||||
0x6B,0xEC,0xE5,0x58,0x06,0xB6,0x64,0x80,0x6A,0x2A,0x1A,0x4E,0x5B,0x0F,0xD8,0xC4,
|
||||
0x0A,0x2E,0x52,0x19,0xD9,0x62,0xF5,0x30,0x48,0xBE,0x8C,0x7B,0x4F,0x38,0x9B,0xA2,
|
||||
0xC3,0xAF,0xC9,0xD3,0xC7,0xC1,0x62,0x41,0x86,0xB9,0x61,0x21,0x57,0x6F,0x99,0x4F,
|
||||
0xC1,0xBA,0xCE,0x7B,0xB5,0x3B,0x4D,0x5E,0x8A,0x8B,0x44,0x57,0x5F,0x13,0x5F,0x70,
|
||||
0x6D,0x5B,0x29,0x47,0xDC,0x38,0xE2,0xEC,0x04,0x55,0x65,0x12,0x2A,0xE8,0x17,0x43,
|
||||
0xE1,0x8E,0xDD,0x2A,0xB3,0xE2,0x94,0xF7,0x09,0x6E,0x5C,0xE6,0xEB,0x8A,0xF8,0x6D,
|
||||
0x89,0x49,0x54,0x48,0xF5,0x2F,0xAD,0xBF,0xEA,0x94,0x4B,0xCA,0xFC,0x39,0x87,0x82,
|
||||
0x5F,0x8A,0x01,0xF2,0x75,0xF2,0xE6,0x71,0xD6,0xD8,0x42,0xDE,0xF1,0x2D,0x1D,0x28,
|
||||
0xA6,0x88,0x7E,0xA3,0xA0,0x47,0x1D,0x30,0xD9,0xA3,0x71,0xDF,0x49,0x1C,0xCB,0x01,
|
||||
0xF8,0x36,0xB1,0xF2,0xF0,0x22,0x58,0x5D,0x45,0x6B,0xBD,0xA0,0xBB,0xB2,0x88,0x42,
|
||||
0xC7,0x8C,0x28,0xCE,0x93,0xE8,0x90,0x63,0x08,0x90,0x7C,0x89,0x3C,0xF5,0x7D,0xB7,
|
||||
0x04,0x2D,0x4F,0x55,0x51,0x16,0xFD,0x7E,0x79,0xE8,0xBE,0xC1,0xF2,0x12,0xD4,0xF8,
|
||||
0xB4,0x84,0x05,0x23,0xA0,0xCC,0xD2,0x2B,0xFD,0xE1,0xAB,0xAD,0x0D,0xD1,0x55,0x6C,
|
||||
0x23,0x41,0x94,0x4D,0x77,0x37,0x4F,0x05,0x28,0x0C,0xBF,0x17,0xB3,0x12,0x67,0x6C,
|
||||
0x8C,0xC3,0x5A,0xF7,0x41,0x84,0x2A,0x6D,0xD0,0x94,0x12,0x27,0x2C,0xB4,0xED,0x9C,
|
||||
0x4D,0xEC,0x47,0x82,0x97,0xD5,0x67,0xB9,0x1B,0x9D,0xC0,0x55,0x07,0x7E,0xE5,0x8E,
|
||||
0xE2,0xA8,0xE7,0x3E,0x12,0xE4,0x0E,0x3A,0x2A,0x45,0x55,0x34,0xA2,0xF9,0x2D,0x5A,
|
||||
0x1B,0xAB,0x52,0x7C,0x83,0x10,0x5F,0x55,0xD2,0xF1,0x5A,0x43,0x2B,0xC6,0xA7,0xA4,
|
||||
0x89,0x15,0x95,0xE8,0xB4,0x4B,0x9D,0xF8,0x75,0xE3,0x9F,0x60,0x78,0x5B,0xD6,0xE6,
|
||||
0x0D,0x44,0xE6,0x21,0x06,0xBD,0x47,0x22,0x53,0xA4,0x00,0xAD,0x8D,0x43,0x13,0x85,
|
||||
0x39,0xF7,0xAA,0xFC,0x38,0xAF,0x7B,0xED,0xFC,0xE4,0x2B,0x54,0x50,0x98,0x4C,0xFC,
|
||||
0x85,0x80,0xF7,0xDF,0x3C,0x80,0x22,0xE1,0x94,0xDA,0xDE,0x24,0xC6,0xB0,0x7A,0x39,
|
||||
0x38,0xDC,0x0F,0xA1,0xA7,0xF4,0xF9,0x6F,0x63,0x18,0x57,0x8B,0x84,0x41,0x2A,0x2E,
|
||||
0xD4,0x53,0xF2,0xD9,0x00,0x0F,0xD0,0xDD,0x99,0x6E,0x19,0xA6,0x0A,0xD0,0xEC,0x5B,
|
||||
0x58,0x24,0xAB,0xC0,0xCB,0x06,0x65,0xEC,0x1A,0x13,0x38,0x94,0x0A,0x67,0x03,0x2F,
|
||||
0x3F,0xF7,0xE3,0x77,0x44,0x77,0x33,0xC6,0x14,0x39,0xD0,0xE3,0xC0,0xA2,0x08,0x79,
|
||||
0xBB,0x40,0x99,0x57,0x41,0x0B,0x01,0x90,0xCD,0xE1,0xCC,0x48,0x67,0xDB,0xB3,0xAF,
|
||||
0x88,0x74,0xF3,0x4C,0x82,0x8F,0x72,0xB1,0xB5,0x23,0x29,0xC4,0x12,0x6C,0x19,0xFC,
|
||||
0x8E,0x46,0xA4,0x9C,0xC4,0x25,0x65,0x87,0xD3,0x6D,0xBE,0x8A,0x93,0x11,0x03,0x38,
|
||||
0xED,0x83,0x2B,0xF3,0x46,0xA4,0x93,0xEA,0x3B,0x53,0x85,0x1D,0xCE,0xD4,0xF1,0x08,
|
||||
0x83,0x27,0xED,0xFC,0x9B,0x1A,0x18,0xBC,0xF9,0x8B,0xAE,0xDC,0x24,0xAB,0x50,0x38,
|
||||
0xE9,0x72,0x4B,0x10,0x22,0x17,0x7B,0x46,0x5D,0xAB,0x59,0x64,0xF3,0x40,0xAE,0xF8,
|
||||
0xBB,0xE5,0xC8,0xF9,0x26,0x03,0x4E,0x55,0x7D,0xEB,0xEB,0xFE,0xF7,0x39,0xE6,0xE0,
|
||||
0x0A,0x11,0xBE,0x2E,0x28,0xFF,0x98,0xED,0xC0,0xC9,0x42,0x56,0x42,0xC3,0xFD,0x00,
|
||||
0xF6,0xAF,0x87,0xA2,0x5B,0x01,0x3F,0x32,0x92,0x47,0x95,0x9A,0x72,0xA5,0x32,0x3D,
|
||||
0xAE,0x6B,0xD0,0x9B,0x07,0xD2,0x49,0x92,0xE3,0x78,0x4A,0xFA,0xA1,0x06,0x7D,0xF2,
|
||||
0x41,0xCF,0x77,0x74,0x04,0x14,0xB2,0x0C,0x86,0x84,0x64,0x16,0xD5,0xBB,0x51,0xA1,
|
||||
0xE5,0x6F,0xF1,0xD1,0xF2,0xE2,0xF7,0x5F,0x58,0x20,0x4D,0xB8,0x57,0xC7,0xCF,0xDD,
|
||||
0xC5,0xD8,0xBE,0x76,0x3D,0xF6,0x5F,0x7E,0xE7,0x2A,0x8B,0x88,0x24,0x1B,0x38,0x3F,
|
||||
0x0E,0x41,0x23,0x77,0xF5,0xF0,0x4B,0xD4,0x0C,0x1F,0xFA,0xA4,0x0B,0x80,0x5F,0xCF,
|
||||
0x45,0xF6,0xE0,0xDA,0x2F,0x34,0x59,0x53,0xFB,0x20,0x3C,0x52,0x62,0x5E,0x35,0xB5,
|
||||
0x62,0xFE,0x8B,0x60,0x63,0xE3,0x86,0x5A,0x15,0x1A,0x6E,0xD1,0x47,0x45,0xBC,0x32,
|
||||
0xB4,0xEB,0x67,0x38,0xAB,0xE4,0x6E,0x33,0x3A,0xB5,0xED,0xA3,0xAD,0x67,0xE0,0x4E,
|
||||
0x41,0x95,0xEE,0x62,0x62,0x71,0x26,0x1D,0x31,0xEF,0x62,0x30,0xAF,0xD7,0x82,0xAC,
|
||||
0xC2,0xDC,0x05,0x04,0xF5,0x97,0x07,0xBF,0x11,0x59,0x23,0x07,0xC0,0x64,0x02,0xE8,
|
||||
0x97,0xE5,0x3E,0xAF,0x18,0xAC,0x59,0xA6,0x8B,0x4A,0x33,0x90,0x1C,0x6E,0x7C,0x9C,
|
||||
0x20,0x7E,0x4C,0x3C,0x3E,0x61,0x64,0xBB,0xC5,0x6B,0x7C,0x7E,0x3E,0x9F,0xC5,0x4C,
|
||||
0x9F,0xEA,0x73,0xF5,0xD7,0x89,0xC0,0x4C,0xF4,0xFB,0xF4,0x2D,0xEC,0x14,0x1B,0x51,
|
||||
0xD5,0xC1,0x12,0xC8,0x10,0xDF,0x0B,0x4A,0x8B,0x9C,0xBC,0x93,0x45,0x6A,0x3E,0x3E,
|
||||
0x7D,0xC1,0xA9,0xBA,0xCD,0xC1,0xB4,0x07,0xE4,0xE1,0x68,0x86,0x43,0xB2,0x6D,0x38,
|
||||
0xF3,0xFB,0x0C,0x5C,0x66,0x37,0x71,0xDE,0x56,0xEF,0x6E,0xA0,0x10,0x40,0x65,0xA7,
|
||||
0x98,0xF7,0xD0,0xBE,0x0E,0xC8,0x37,0x36,0xEC,0x10,0xCA,0x7C,0x9C,0xAB,0x84,0x1E,
|
||||
0x05,0x17,0x76,0x02,0x1C,0x4F,0x52,0xAA,0x5F,0xC1,0xC6,0xA0,0x56,0xB9,0xD8,0x04,
|
||||
0x84,0x44,0x4D,0xA7,0x59,0xD8,0xDE,0x60,0xE6,0x38,0x0E,0x05,0x8F,0x03,0xE1,0x3B,
|
||||
0x6D,0x81,0x04,0x33,0x6F,0x30,0x0B,0xCE,0x69,0x05,0x21,0x33,0xFB,0x26,0xBB,0x89,
|
||||
0x7D,0xB6,0xAE,0x87,0x7E,0x51,0x07,0xE0,0xAC,0xF7,0x96,0x0A,0x6B,0xF9,0xC4,0x5C,
|
||||
0x1D,0xE4,0x44,0x47,0xB8,0x5E,0xFA,0xE3,0x78,0x84,0x55,0x42,0x4B,0x48,0x5E,0xF7,
|
||||
0x7D,0x47,0x35,0x86,0x1D,0x2B,0x43,0x05,0x03,0xEC,0x8A,0xB8,0x1E,0x06,0x3C,0x76,
|
||||
0x0C,0x48,0x1A,0x43,0xA7,0xB7,0x8A,0xED,0x1E,0x13,0xC6,0x43,0xEE,0x10,0xEF,0xDB,
|
||||
0xEC,0xFB,0x3C,0x83,0xB2,0x95,0x44,0xEF,0xD8,0x54,0x51,0x4E,0x2D,0x11,0x44,0x1D,
|
||||
0xFB,0x36,0x59,0x1E,0x7A,0x34,0xC1,0xC3,0xCA,0x57,0x00,0x61,0xEA,0x67,0xA5,0x16,
|
||||
0x9B,0x55,0xD0,0x55,0xE1,0x7F,0xD9,0x36,0xD2,0x40,0x76,0xAE,0xDC,0x01,0xCE,0xB0,
|
||||
0x7A,0x83,0xD5,0xCB,0x20,0x98,0xEC,0x6B,0xC1,0x72,0x92,0x34,0xF3,0x82,0x57,0x37,
|
||||
0x62,0x8A,0x32,0x36,0x0C,0x90,0x43,0xAE,0xAE,0x5C,0x9B,0x78,0x8E,0x13,0x65,0x02,
|
||||
0xFD,0x68,0x71,0xC1,0xFE,0xB0,0x31,0xA0,0x24,0x82,0xB0,0xC3,0xB1,0x79,0x69,0xA7,
|
||||
0xF5,0xD2,0xEB,0xD0,0x82,0xC0,0x32,0xDC,0x9E,0xC7,0x26,0x3C,0x6D,0x8D,0x98,0xC1,
|
||||
0xBB,0x22,0xD4,0xD0,0x0F,0x33,0xEC,0x3E,0xB9,0xCC,0xE1,0xDC,0x6A,0x4C,0x77,0x36,
|
||||
0x14,0x1C,0xF9,0xBF,0x81,0x9F,0x28,0x5F,0x71,0x85,0x32,0x29,0x90,0x75,0x48,0xC4,
|
||||
0xB3,0x4A,0xCE,0xD8,0x44,0x8F,0x14,0x2F,0xFD,0x40,0x57,0xEF,0xAA,0x08,0x75,0xD9,
|
||||
0x46,0xD1,0xD6,0x6E,0x32,0x55,0x1F,0xC3,0x18,0xFE,0x84,0x1F,0xFC,0x84,0xD5,0xFF,
|
||||
0x71,0x5E,0x1B,0x48,0xC3,0x86,0x95,0x0E,0x28,0x08,0x27,0xD3,0x38,0x83,0x71,0x7B,
|
||||
0x4C,0x80,0x63,0x54,0x9A,0x56,0xB0,0xAC,0xCF,0x80,0xCA,0x31,0x09,0xEF,0xFE,0xF3,
|
||||
0xBE,0xAF,0x24,0x7E,0xA6,0xFE,0x53,0x3F,0xC2,0x8D,0x4A,0x33,0x68,0xD1,0x22,0xA6,
|
||||
0x66,0xAD,0x7B,0xEA,0xDE,0xB6,0x43,0xB0,0xA1,0x25,0x95,0x00,0xA3,0x3F,0x75,0x46,
|
||||
0x14,0x11,0x44,0xEC,0xD7,0x95,0xBC,0x92,0xF0,0x4F,0xA9,0x16,0x53,0x62,0x97,0x60,
|
||||
0x2A,0x0F,0x41,0xF1,0x71,0x24,0xBE,0xEE,0x94,0x7F,0x08,0xCD,0x60,0x93,0xB3,0x85,
|
||||
0x5B,0x07,0x00,0x3F,0xD8,0x0F,0x28,0x83,0x9A,0xD1,0x69,0x9F,0xD1,0xDA,0x2E,0xC3,
|
||||
0x90,0x01,0xA2,0xB9,0x6B,0x4E,0x2A,0x66,0x9D,0xDA,0xAE,0xA6,0xEA,0x2A,0xD3,0x68,
|
||||
0x2F,0x0C,0x0C,0x9C,0xD2,0x8C,0x4A,0xED,0xE2,0x9E,0x57,0x65,0x9D,0x09,0x87,0xA3,
|
||||
0xB4,0xC4,0x32,0x5D,0xC9,0xD4,0x32,0x2B,0xB1,0xE0,0x71,0x1E,0x64,0x4D,0xE6,0x90,
|
||||
0x71,0xE3,0x1E,0x40,0xED,0x7D,0xF3,0x84,0x0E,0xED,0xC8,0x78,0x76,0xAE,0xC0,0x71,
|
||||
0x27,0x72,0xBB,0x05,0xEA,0x02,0x64,0xFB,0xF3,0x48,0x6B,0xB5,0x42,0x93,0x3F,0xED,
|
||||
0x9F,0x13,0x53,0xD2,0xF7,0xFE,0x2A,0xEC,0x1D,0x47,0x25,0xDB,0x3C,0x91,0x86,0xC6,
|
||||
0x8E,0xF0,0x11,0xFD,0x23,0x74,0x36,0xF7,0xA4,0xF5,0x9E,0x7A,0x7E,0x53,0x50,0x44,
|
||||
0xD4,0x47,0xCA,0xD3,0xEB,0x38,0x6D,0xE6,0xD9,0x71,0x94,0x7F,0x4A,0xC6,0x69,0x4B,
|
||||
0x11,0xF4,0x52,0xEA,0x22,0xFE,0x8A,0xB0,0x36,0x67,0x8B,0x59,0xE8,0xE6,0x80,0x2A,
|
||||
0xEB,0x65,0x04,0x13,0xEE,0xEC,0xDC,0x9E,0x5F,0xB1,0xEC,0x05,0x6A,0x59,0xE6,0x9F,
|
||||
0x5E,0x59,0x6B,0x89,0xBF,0xF7,0x1A,0xCA,0x44,0xF9,0x5B,0x6A,0x71,0x85,0x03,0xE4,
|
||||
0x29,0x62,0xE0,0x70,0x6F,0x41,0xC4,0xCF,0xB2,0xB1,0xCC,0xE3,0x7E,0xA6,0x07,0xA8,
|
||||
0x87,0xE7,0x7F,0x84,0x93,0xDB,0x52,0x4B,0x6C,0xEC,0x7E,0xDD,0xD4,0x24,0x48,0x10,
|
||||
0x69,0x9F,0x04,0x60,0x74,0xE6,0x48,0x18,0xF3,0xE4,0x2C,0xB9,0x4F,0x2E,0x50,0x7A,
|
||||
0xDF,0xD4,0x54,0x69,0x2B,0x8B,0xA7,0xF3,0xCE,0xFF,0x1F,0xF3,0x3E,0x26,0x01,0x39,
|
||||
0x17,0x95,0x84,0x89,0xB0,0xF0,0x4C,0x4B,0x82,0x91,0x9F,0xC4,0x4B,0xAC,0x9D,0xA5,
|
||||
0x74,0xAF,0x17,0x25,0xC9,0xCA,0x32,0xD3,0xBC,0x89,0x8A,0x84,0x89,0xCC,0x0D,0xAE,
|
||||
0x7C,0xA2,0xDB,0x9C,0x6A,0x78,0x91,0xEE,0xEA,0x76,0x5D,0x4E,0x87,0x60,0xF5,0x69,
|
||||
0x15,0x67,0xD4,0x02,0xCF,0xAF,0x48,0x36,0x07,0xEA,0xBF,0x6F,0x66,0x2D,0x06,0x8F,
|
||||
0xC4,0x9A,0xFE,0xF9,0xF6,0x90,0x87,0x75,0xB8,0xF7,0xAD,0x0F,0x76,0x10,0x5A,0x3D,
|
||||
0x59,0xB0,0x2E,0xB3,0xC7,0x35,0x2C,0xCC,0x70,0x56,0x2B,0xCB,0xE3,0x37,0x96,0xC5,
|
||||
0x2F,0x46,0x1B,0x8A,0x22,0x46,0xC7,0x88,0xA7,0x26,0x32,0x98,0x61,0xDF,0x86,0x22,
|
||||
0x8A,0xF4,0x1C,0x2F,0x87,0xA1,0x09,0xAA,0xCC,0xA9,0xAE,0xD3,0xBD,0x00,0x45,0x1C,
|
||||
0x9A,0x54,0x87,0x86,0x52,0x87,0xEF,0xFF,0x1E,0x8F,0xA1,0x8F,0xC1,0x89,0x5C,0x35,
|
||||
0x1B,0xDA,0x2D,0x3A,0x2C,0x16,0xB2,0xC2,0xF1,0x56,0xE2,0x78,0xC1,0x6B,0x63,0x97,
|
||||
0xC5,0x56,0x8F,0xC9,0x32,0x7F,0x2C,0xAA,0xAF,0xA6,0xA8,0xAC,0x20,0x91,0x22,0x88,
|
||||
0xDE,0xE4,0x60,0x8B,0xF9,0x4B,0x42,0x25,0x1A,0xE3,0x7F,0x9C,0x2C,0x19,0x89,0x3A,
|
||||
0x7E,0x05,0xD4,0x36,0xCC,0x69,0x58,0xC2,0xC1,0x32,0x8B,0x2F,0x90,0x85,0xEB,0x7A,
|
||||
0x39,0x50,0xA5,0xA1,0x27,0x92,0xC5,0x66,0xB0,0x20,0x4F,0x58,0x7E,0x55,0x83,0x43,
|
||||
0x2B,0x45,0xE2,0x9C,0xE4,0xD8,0x12,0x90,0x2C,0x16,0x83,0x56,0x16,0x79,0x03,0xB3,
|
||||
0xAD,0x2D,0x61,0x18,0x1A,0x13,0x1F,0x37,0xE2,0xE1,0x9C,0x73,0x7B,0x80,0xD5,0xFD,
|
||||
0x2D,0x51,0x87,0xFC,0x7B,0xAA,0xD7,0x1F,0x2C,0x7A,0x8E,0xAF,0xF4,0x8D,0xBB,0xCD,
|
||||
0x95,0x11,0x7C,0x72,0x0B,0xEE,0x6F,0xE2,0xB9,0xAF,0xDE,0x37,0x83,0xDE,0x8C,0x8D,
|
||||
0x62,0x05,0x67,0xB7,0x96,0xC6,0x8D,0x56,0xB6,0x0D,0xD7,0x62,0xBA,0xD6,0x46,0x36,
|
||||
0xBD,0x8E,0xC8,0xE6,0xEA,0x2A,0x6C,0x10,0x14,0xFF,0x6B,0x5B,0xFA,0x82,0x3C,0x46,
|
||||
0xB1,0x30,0x43,0x46,0x51,0x8A,0x7D,0x9B,0x92,0x3E,0x83,0x79,0x5B,0x55,0x5D,0xB2,
|
||||
0x6C,0x5E,0xCE,0x90,0x62,0x8E,0x53,0x98,0xC9,0x0D,0x6D,0xE5,0x2D,0x57,0xCD,0xC5,
|
||||
0x81,0x57,0xBA,0xE1,0xE8,0xB8,0x8F,0x72,0xE5,0x4F,0x13,0xDC,0xEA,0x9D,0x71,0x15,
|
||||
0x10,0xB2,0x11,0x88,0xD5,0x09,0xD4,0x7F,0x5B,0x65,0x7F,0x2C,0x3B,0x38,0x4C,0x11,
|
||||
0x68,0x50,0x8D,0xFB,0x9E,0xB0,0x59,0xBF,0x94,0x80,0x89,0x4A,0xC5,0x1A,0x18,0x12,
|
||||
0x89,0x53,0xD1,0x4A,0x10,0x29,0xE8,0x8C,0x1C,0xEC,0xB6,0xEA,0x46,0xC7,0x17,0x8B,
|
||||
0x25,0x15,0x31,0xA8,0xA2,0x6B,0x43,0xB1,0x9D,0xE2,0xDB,0x0B,0x87,0x9B,0xB0,0x11,
|
||||
0x04,0x0E,0x71,0xD2,0x29,0x77,0x89,0x82,0x0A,0x66,0x41,0x7F,0x1D,0x0B,0x48,0xFF,
|
||||
0x72,0xBB,0x24,0xFD,0xC2,0x48,0xA1,0x9B,0xFE,0x7B,0x7F,0xCE,0x88,0xDB,0x86,0xD9,
|
||||
0x85,0x3B,0x1C,0xB0,0xDC,0xA8,0x33,0x07,0xBF,0x51,0x2E,0xE3,0x0E,0x9A,0x00,0x97,
|
||||
0x1E,0x06,0xC0,0x97,0x43,0x9D,0xD8,0xB6,0x45,0xC4,0x86,0x67,0x5F,0x00,0xF8,0x88,
|
||||
0x9A,0xA4,0x52,0x9E,0xC7,0xAA,0x8A,0x83,0x75,0xEC,0xC5,0x18,0xAE,0xCE,0xC3,0x2F,
|
||||
0x1A,0x2B,0xF9,0x18,0xFF,0xAE,0x1A,0xF5,0x53,0x0B,0xB5,0x33,0x51,0xA7,0xFD,0xE8,
|
||||
0xA8,0xE1,0xA2,0x64,0xB6,0x22,0x17,0x43,0x80,0xCC,0x0A,0xD8,0xAE,0x3B,0xBA,0x40,
|
||||
0xD7,0xD9,0x92,0x4A,0x89,0xDF,0x04,0x10,0xEE,0x9B,0x18,0x2B,0x6A,0x77,0x69,0x8A,
|
||||
0x68,0xF4,0xF9,0xB9,0xA2,0x21,0x15,0x6E,0xE6,0x1E,0x3B,0x03,0x62,0x30,0x9B,0x60,
|
||||
0x41,0x7E,0x25,0x9B,0x9E,0x8F,0xC5,0x52,0x10,0x08,0xF8,0xC2,0x69,0xA1,0x21,0x11,
|
||||
0x88,0x37,0x5E,0x79,0x35,0x66,0xFF,0x10,0x42,0x18,0x6E,0xED,0x97,0xB6,0x6B,0x1C,
|
||||
0x4E,0x36,0xE5,0x6D,0x7D,0xB4,0xE4,0xBF,0x20,0xB9,0xE0,0x05,0x3A,0x69,0xD5,0xB8,
|
||||
0xE3,0xD5,0xDC,0xE0,0xB9,0xAC,0x53,0x3E,0x07,0xA4,0x57,0xAD,0x77,0xFF,0x48,0x18,
|
||||
0x76,0x2A,0xAC,0x49,0x2A,0x8E,0x47,0x75,0x6D,0x9F,0x67,0x63,0x30,0x35,0x8C,0x39,
|
||||
0x05,0x39,0xD5,0x6F,0x64,0x3A,0x5B,0xAD,0xCA,0x0B,0xBB,0x82,0x52,0x99,0x45,0xB1,
|
||||
0x93,0x36,0x36,0x99,0xAF,0x13,0x20,0x44,0x36,0xD8,0x02,0x44,0x09,0x39,0x92,0x85,
|
||||
0xFF,0x4A,0x4A,0x97,0x87,0xA6,0x63,0xD7,0xC7,0xB5,0xB5,0x24,0xED,0x0F,0xB4,0x6F,
|
||||
0x0C,0x58,0x52,0x14,0xD9,0xA6,0x7B,0xD3,0x79,0xBC,0x38,0x58,0xA1,0xBD,0x3B,0x84,
|
||||
0x06,0xD8,0x1A,0x06,0xFD,0x6B,0xA8,0xEA,0x4B,0x69,0x28,0x04,0x37,0xAD,0x82,0x99,
|
||||
0xFB,0x0E,0x1B,0x85,0xBD,0xA8,0x5D,0x73,0xCD,0xDC,0x58,0x75,0x0A,0xBE,0x63,0x6C,
|
||||
0x48,0xE7,0x4C,0xE4,0x30,0x2B,0x04,0x60,0xB9,0x15,0xD8,0xDA,0x86,0x81,0x75,0x8F,
|
||||
0x96,0xD4,0x8D,0x1C,0x5D,0x70,0x85,0x7C,0x1C,0x67,0x7B,0xD5,0x08,0x67,0xA6,0xCE,
|
||||
0x4B,0x0A,0x66,0x70,0xB7,0xE5,0x63,0xD4,0x5B,0x8A,0x82,0xEA,0x10,0x67,0xCA,0xE2,
|
||||
0xF4,0xEF,0x17,0x85,0x2F,0x2A,0x5F,0x8A,0x97,0x82,0xF8,0x6A,0xD6,0x34,0x10,0xEA,
|
||||
0xEB,0xC9,0x5C,0x3C,0xE1,0x49,0xF8,0x46,0xEB,0xDE,0xBD,0xF6,0xA9,0x92,0xF1,0xAA,
|
||||
0xA6,0xA0,0x18,0xB0,0x3A,0xD3,0x0F,0x1F,0xF3,0x6F,0xFF,0x31,0x45,0x43,0x44,0xD3,
|
||||
0x50,0x9A,0xF7,0x88,0x09,0x96,0xC1,0xCE,0x76,0xCC,0xF2,0x2C,0x2C,0xBA,0xAD,0x82,
|
||||
0x77,0x8F,0x18,0x84,0xC0,0xD2,0x07,0x9C,0x36,0x90,0x83,0x4E,0x0B,0xA5,0x4F,0x43,
|
||||
0x3E,0x04,0xAB,0x78,0x4F,0xD6,0xFB,0x09,0x01,0x24,0x90,0xDA,0x6F,0x3C,0x3A,0x61,
|
||||
0x0D,0x7F,0x69,0x4A,0xEB,0x2B,0x30,0x02,0xB4,0xDB,0xE0,0x84,0xA9,0xEC,0xD7,0x35,
|
||||
0xBF,0x37,0x7D,0x85,0x58,0xCE,0xA9,0x4E,0xE4,0x80,0xC7,0xA8,0xD3,0x30,0x67,0x48,
|
||||
0xEB,0x29,0xAF,0x2F,0x74,0x6A,0xB4,0xA7,0x3F,0x0F,0x3F,0x92,0xAF,0xF3,0xCA,0xAC,
|
||||
0xAF,0x4B,0xD9,0x94,0xC0,0x43,0xCA,0x81,0x0D,0x2F,0x48,0xA1,0xB0,0x27,0xD5,0xD2,
|
||||
0xEF,0x4B,0x05,0x85,0xA3,0xDE,0x4D,0x93,0x30,0x3C,0xF0,0xBB,0x4A,0x8F,0x30,0x27,
|
||||
0x4C,0xEB,0xE3,0x3E,0x64,0xED,0x9A,0x2F,0x3B,0xF1,0x82,0xF0,0xBA,0xF4,0xCF,0x7F,
|
||||
0x40,0xCB,0xB0,0xE1,0x7F,0xBC,0xAA,0x57,0xD3,0xC9,0x74,0xF2,0xFA,0x43,0x0D,0x22,
|
||||
0xD0,0xF4,0x77,0x4E,0x93,0xD7,0x85,0x70,0x1F,0x99,0xBF,0xB6,0xDE,0x35,0xF1,0x30,
|
||||
0xA7,0x5E,0x71,0xF0,0x6B,0x01,0x2D,0x7B,0x64,0xF0,0x33,0x53,0x0A,0x39,0x88,0xF3,
|
||||
0x6B,0x3A,0xA6,0x6B,0x35,0xD2,0x2F,0x43,0xCD,0x02,0xFD,0xB5,0xE9,0xBC,0x5B,0xAA,
|
||||
0xD8,0xA4,0x19,0x7E,0x0E,0x5D,0x94,0x81,0x9E,0x6F,0x77,0xAD,0xD6,0x0E,0x74,0x93,
|
||||
0x96,0xE7,0xC4,0x18,0x5F,0xAD,0xF5,0x19
|
||||
};
|
350
arm9/source/key2.h
Normal file
350
arm9/source/key2.h
Normal file
@ -0,0 +1,350 @@
|
||||
const unsigned char gEncrDataTwl[] = {
|
||||
0x59, 0xaa, 0x56, 0x8e, 0x90, 0xd7, 0x11, 0x55, 0x4d, 0xea, 0xbf, 0xfe,
|
||||
0xbd, 0x0d, 0x75, 0x91, 0xf7, 0x85, 0x39, 0x98, 0xd0, 0x9c, 0xc3, 0x58,
|
||||
0xc4, 0x15, 0x6f, 0xf1, 0x90, 0xf9, 0xe4, 0xc3, 0x8e, 0xc0, 0x9b, 0x0e,
|
||||
0x5d, 0xe1, 0x87, 0x94, 0xb9, 0x07, 0x2c, 0xba, 0xa6, 0x4f, 0x75, 0x74,
|
||||
0xc1, 0xe3, 0x1c, 0x86, 0xe6, 0xed, 0xf8, 0x09, 0x3b, 0xbb, 0x37, 0x7a,
|
||||
0x4e, 0xf0, 0xf0, 0x92, 0xf6, 0x55, 0xfa, 0x47, 0xfb, 0x1b, 0xc5, 0x16,
|
||||
0x06, 0x74, 0x4e, 0x56, 0x20, 0xdd, 0xb6, 0xd1, 0x42, 0xcf, 0xcf, 0xf1,
|
||||
0x55, 0x7e, 0x17, 0x18, 0xa1, 0x93, 0xff, 0x09, 0xda, 0x36, 0xa6, 0x9a,
|
||||
0x43, 0x3d, 0xf4, 0x65, 0xed, 0x40, 0x97, 0x6c, 0xd5, 0xa6, 0xdd, 0x6d,
|
||||
0x6c, 0x23, 0xbf, 0x94, 0xe7, 0x51, 0xa6, 0x68, 0x3c, 0xe8, 0xe6, 0x65,
|
||||
0xd6, 0xbc, 0x9e, 0x92, 0x78, 0x26, 0x46, 0xa1, 0x73, 0xdc, 0xe5, 0x36,
|
||||
0x8e, 0xcd, 0xec, 0xa1, 0xf1, 0xee, 0x8b, 0x68, 0xf4, 0xac, 0xc1, 0xdc,
|
||||
0xc8, 0x84, 0x95, 0x31, 0xe8, 0xed, 0xc7, 0x5e, 0xe4, 0x5a, 0x37, 0xca,
|
||||
0xec, 0x55, 0xbe, 0x2a, 0xfc, 0xf6, 0x45, 0x67, 0xa9, 0xb4, 0x7d, 0x7d,
|
||||
0x9b, 0x6e, 0xe9, 0x2c, 0xff, 0x3f, 0xeb, 0x69, 0xb7, 0x2e, 0x68, 0xa8,
|
||||
0x94, 0xef, 0x7b, 0xbd, 0x88, 0x93, 0x15, 0x66, 0x3a, 0xb7, 0x7f, 0xfe,
|
||||
0x1d, 0xc3, 0x89, 0x08, 0xd7, 0x74, 0x59, 0xfa, 0xaf, 0x91, 0x41, 0x9e,
|
||||
0x57, 0xd5, 0x67, 0x84, 0xba, 0x00, 0xe9, 0x63, 0x58, 0x07, 0x4d, 0xec,
|
||||
0xdf, 0xc6, 0xda, 0x1e, 0x62, 0x52, 0xd9, 0x14, 0xbc, 0x03, 0xc3, 0xb0,
|
||||
0xa5, 0xfd, 0xb7, 0x27, 0xde, 0xb1, 0x6f, 0x1b, 0x7c, 0x72, 0x4a, 0xcd,
|
||||
0x09, 0xe5, 0x82, 0x70, 0xd3, 0x9f, 0xb6, 0xd6, 0xa4, 0x6a, 0x2f, 0xc2,
|
||||
0x32, 0xbd, 0xb5, 0x39, 0xe4, 0xea, 0xb9, 0x71, 0x1c, 0x70, 0x67, 0x21,
|
||||
0x92, 0x21, 0xac, 0xf4, 0x9e, 0x63, 0xe8, 0x5e, 0x83, 0x02, 0xcc, 0x0c,
|
||||
0xf8, 0xf8, 0x9e, 0x87, 0x89, 0xfc, 0x03, 0x85, 0xfa, 0xcc, 0x77, 0x07,
|
||||
0x44, 0x5f, 0x4d, 0xe5, 0x19, 0xd3, 0x12, 0xee, 0xca, 0xe1, 0xe0, 0xbf,
|
||||
0x1e, 0xbe, 0xe7, 0x12, 0x1f, 0x6a, 0x93, 0x1e, 0x38, 0x4b, 0xa7, 0x9f,
|
||||
0x81, 0xa9, 0x77, 0x85, 0x0c, 0xc6, 0x39, 0x02, 0x55, 0xd2, 0x62, 0x56,
|
||||
0x19, 0x85, 0xa6, 0x38, 0x85, 0xe1, 0x2d, 0x3c, 0x38, 0x3b, 0x5b, 0xa0,
|
||||
0x24, 0x18, 0xe9, 0x29, 0x6c, 0x9f, 0xe4, 0x4d, 0x4e, 0x23, 0x5f, 0xb1,
|
||||
0xe2, 0xa0, 0x6f, 0x97, 0xb2, 0x41, 0xd1, 0xea, 0xdb, 0xa7, 0x37, 0x81,
|
||||
0xeb, 0x06, 0x8d, 0x77, 0xc2, 0x68, 0xfc, 0x5a, 0x65, 0x97, 0x33, 0x58,
|
||||
0xa1, 0xb8, 0x35, 0x0f, 0xf4, 0x25, 0xbc, 0x3b, 0x4f, 0x18, 0x0f, 0x0e,
|
||||
0x60, 0x25, 0x3d, 0xd8, 0x77, 0x1a, 0xd0, 0x8a, 0xb0, 0x61, 0x57, 0x16,
|
||||
0x0b, 0x55, 0xf2, 0x58, 0xb9, 0x91, 0x52, 0x30, 0x33, 0xab, 0x29, 0x9b,
|
||||
0x03, 0x62, 0xe5, 0xcc, 0xdf, 0x6e, 0x62, 0x86, 0x9d, 0x76, 0xe5, 0xdd,
|
||||
0x6f, 0xca, 0x3e, 0x75, 0xd8, 0x88, 0x58, 0x06, 0x8d, 0xa4, 0x58, 0xf5,
|
||||
0xaa, 0x7c, 0xce, 0x17, 0xdd, 0xde, 0xca, 0x0a, 0x72, 0x87, 0x6f, 0x29,
|
||||
0x6c, 0x0c, 0xe9, 0xc0, 0x3d, 0x32, 0x2e, 0x55, 0xf3, 0xa7, 0x27, 0xda,
|
||||
0xfc, 0x86, 0x0c, 0x9e, 0x33, 0x83, 0xb5, 0x47, 0xeb, 0xe8, 0xf6, 0xc9,
|
||||
0xf4, 0x24, 0x72, 0xee, 0xaf, 0xf8, 0xb5, 0x59, 0x70, 0x06, 0x85, 0x71,
|
||||
0xbb, 0x3c, 0xbe, 0xbb, 0x2c, 0x24, 0xad, 0x67, 0xba, 0x42, 0xb9, 0xee,
|
||||
0x68, 0xec, 0x0b, 0xe6, 0x5b, 0x26, 0x0f, 0x2b, 0xb6, 0x3a, 0x93, 0x4f,
|
||||
0x9f, 0xe6, 0x9f, 0xb9, 0x1a, 0xa0, 0xb9, 0x51, 0x1c, 0x8d, 0x66, 0x37,
|
||||
0xd2, 0x50, 0xcc, 0xae, 0x10, 0x30, 0x16, 0x60, 0x56, 0x3b, 0x99, 0x0e,
|
||||
0x90, 0x7b, 0x28, 0xde, 0x93, 0xf4, 0x16, 0x87, 0x1f, 0xd0, 0x9b, 0xc2,
|
||||
0x33, 0x42, 0x2c, 0x2c, 0xf1, 0x36, 0xc3, 0x39, 0xf8, 0x4f, 0xa4, 0x1e,
|
||||
0x00, 0x43, 0xb1, 0xac, 0xdf, 0x08, 0xbb, 0xfe, 0x5e, 0x2a, 0xdc, 0x2a,
|
||||
0x10, 0xf3, 0x7b, 0xc5, 0x2f, 0x96, 0xc9, 0x1d, 0x51, 0x4f, 0xc0, 0xde,
|
||||
0x6e, 0x93, 0x9a, 0x35, 0x19, 0xb8, 0x58, 0xb5, 0x19, 0xba, 0xaf, 0x2a,
|
||||
0xb1, 0xb5, 0xb2, 0xff, 0xc1, 0x89, 0xbc, 0x3f, 0xd8, 0x8f, 0x34, 0x07,
|
||||
0x63, 0x60, 0xa5, 0xed, 0xdb, 0xff, 0x9e, 0xf5, 0x5b, 0x23, 0xc0, 0x1b,
|
||||
0x13, 0x96, 0xd4, 0x2f, 0x07, 0x51, 0x1b, 0xac, 0x90, 0x72, 0x71, 0x28,
|
||||
0x65, 0x98, 0xe1, 0xff, 0x6a, 0x9d, 0xe7, 0x30, 0x6d, 0xb1, 0x2c, 0x21,
|
||||
0xfa, 0xcb, 0xbc, 0x6a, 0x3c, 0x25, 0xe8, 0x50, 0x5c, 0x53, 0xd8, 0xd5,
|
||||
0xcb, 0xa2, 0x53, 0x53, 0xa5, 0x64, 0x3f, 0x78, 0x61, 0x77, 0x1d, 0x8d,
|
||||
0x16, 0xe4, 0xe4, 0xa1, 0x32, 0x9c, 0x00, 0x52, 0x5f, 0x2a, 0xd7, 0xf5,
|
||||
0x3c, 0xfd, 0x09, 0xd7, 0x1b, 0x3b, 0x99, 0x01, 0x4d, 0xdc, 0x91, 0xe4,
|
||||
0x6d, 0xe8, 0x9e, 0xa3, 0x18, 0xad, 0x43, 0x27, 0xba, 0xc1, 0x5f, 0x37,
|
||||
0xa6, 0x12, 0x61, 0xf5, 0x1c, 0x63, 0x0c, 0x25, 0x2d, 0x90, 0xf8, 0x52,
|
||||
0xcb, 0x2c, 0x37, 0x4b, 0xde, 0x1e, 0x6c, 0x36, 0x1d, 0x47, 0xf5, 0xdf,
|
||||
0x87, 0xca, 0x79, 0x98, 0x80, 0x09, 0x59, 0xd7, 0x14, 0xfd, 0xf7, 0xf9,
|
||||
0xf4, 0xce, 0x69, 0x23, 0xd2, 0xf8, 0xc4, 0xee, 0xa0, 0x7e, 0xf8, 0x36,
|
||||
0x8e, 0x35, 0x93, 0x45, 0x82, 0xae, 0x0d, 0xfc, 0x65, 0xbc, 0xaa, 0xf5,
|
||||
0x58, 0xa9, 0x65, 0xba, 0xc6, 0x08, 0x4b, 0x63, 0xc3, 0x3f, 0xa6, 0x8a,
|
||||
0xf4, 0xc1, 0x9b, 0x8f, 0x02, 0x45, 0x1b, 0x13, 0x78, 0x28, 0x9f, 0xd6,
|
||||
0x53, 0xb1, 0xc2, 0x7e, 0x4e, 0x71, 0x17, 0xe7, 0x55, 0x09, 0x62, 0xc7,
|
||||
0xad, 0xd5, 0x91, 0x1a, 0xc0, 0xfa, 0x49, 0x4a, 0xef, 0x00, 0xd6, 0xf6,
|
||||
0xf1, 0xd0, 0xc9, 0x40, 0x1b, 0xb1, 0xfd, 0x0e, 0xd3, 0x95, 0xf1, 0xcd,
|
||||
0x95, 0x60, 0x08, 0x73, 0xd2, 0xe0, 0x56, 0xfa, 0xd0, 0x65, 0x51, 0xfd,
|
||||
0xc4, 0x48, 0xd1, 0xaa, 0x5a, 0xba, 0xcb, 0x8f, 0x76, 0x22, 0xe3, 0x60,
|
||||
0x6f, 0x4a, 0x3c, 0x86, 0x35, 0xee, 0xe9, 0x88, 0x9a, 0x4a, 0x36, 0x34,
|
||||
0x74, 0xe3, 0x6d, 0x3f, 0xe4, 0x2a, 0x93, 0x0b, 0xe2, 0xc6, 0x47, 0x4d,
|
||||
0xf2, 0xb6, 0x8e, 0x78, 0x14, 0x91, 0x61, 0xcf, 0xfa, 0xb6, 0x1b, 0x39,
|
||||
0xca, 0x88, 0x0c, 0x04, 0x65, 0xd3, 0x3b, 0xd1, 0xc6, 0xda, 0xe5, 0xf4,
|
||||
0xe9, 0x1a, 0x38, 0x0f, 0xa5, 0xca, 0x32, 0x29, 0x78, 0x6c, 0x91, 0x9d,
|
||||
0xd8, 0xc1, 0x8c, 0x3d, 0x6e, 0x82, 0x49, 0x10, 0x38, 0x4c, 0x95, 0xe3,
|
||||
0xf1, 0x69, 0x30, 0x2e, 0x3e, 0xbf, 0xaf, 0x7d, 0x5e, 0x51, 0x3c, 0x6a,
|
||||
0x15, 0x04, 0xbd, 0x8f, 0xcf, 0xeb, 0x3f, 0xe0, 0xe0, 0xa7, 0xb3, 0x3e,
|
||||
0xf3, 0xf7, 0xd8, 0x1d, 0x15, 0x74, 0xef, 0x4e, 0x5b, 0xa0, 0x1e, 0x3a,
|
||||
0x45, 0xec, 0x98, 0x8b, 0xe4, 0x0c, 0xfb, 0x77, 0xfd, 0xcf, 0xde, 0x88,
|
||||
0x4d, 0x42, 0x18, 0x81, 0x14, 0x0d, 0xe2, 0x20, 0x4e, 0xcf, 0x0d, 0x3b,
|
||||
0xc8, 0x41, 0x36, 0x9d, 0x99, 0xab, 0x47, 0xcb, 0x55, 0xf0, 0x79, 0x77,
|
||||
0x32, 0x85, 0xa4, 0xe4, 0x11, 0x14, 0x42, 0x8d, 0x03, 0x8c, 0x76, 0xba,
|
||||
0x05, 0xcf, 0xe8, 0x40, 0x47, 0xcf, 0xbd, 0xe7, 0x22, 0xe6, 0x72, 0xce,
|
||||
0xa0, 0x13, 0xe4, 0x59, 0x5e, 0x68, 0xc2, 0x53, 0x7a, 0x4d, 0x4b, 0x4c,
|
||||
0xcd, 0xbf, 0xe2, 0xb0, 0xa3, 0x63, 0x77, 0xf2, 0x1e, 0xc3, 0x21, 0xca,
|
||||
0xd2, 0xb6, 0x7b, 0x01, 0x79, 0x02, 0x43, 0xec, 0x6d, 0x98, 0x97, 0x86,
|
||||
0x27, 0x41, 0x67, 0xe7, 0x04, 0xcf, 0x71, 0x0e, 0xfc, 0xc8, 0x3d, 0x32,
|
||||
0x99, 0x35, 0x4d, 0x2c, 0x94, 0xd7, 0x82, 0xb5, 0x2e, 0x20, 0x73, 0xd8,
|
||||
0xa4, 0xf9, 0xae, 0x6c, 0xd6, 0x12, 0x57, 0xe9, 0x44, 0x86, 0x6a, 0x9e,
|
||||
0xe0, 0x72, 0x84, 0x97, 0xb3, 0x8d, 0x56, 0x28, 0x66, 0xdb, 0xec, 0x25,
|
||||
0xbf, 0x01, 0x11, 0x76, 0x9b, 0xe1, 0x43, 0x8d, 0x6d, 0x0b, 0xfa, 0x3d,
|
||||
0x45, 0x15, 0x4a, 0xb4, 0xac, 0x76, 0x2a, 0x4a, 0xfb, 0x8d, 0xa5, 0x03,
|
||||
0xe4, 0x36, 0xe6, 0xd9, 0xfd, 0xc1, 0x20, 0x63, 0xe3, 0x5c, 0x9a, 0x0e,
|
||||
0x0f, 0x99, 0x49, 0xc6, 0x10, 0x9a, 0x08, 0x47, 0xff, 0x3d, 0xaa, 0x0c,
|
||||
0x9f, 0x46, 0x57, 0x5a, 0xe5, 0xc5, 0x24, 0xc5, 0xf1, 0xca, 0x1a, 0xa2,
|
||||
0xb0, 0x29, 0x78, 0xdd, 0x7a, 0x72, 0x49, 0x54, 0xac, 0xc4, 0x22, 0x04,
|
||||
0x97, 0xa2, 0xa1, 0x1a, 0x2f, 0x57, 0xfd, 0x9b, 0xaf, 0xc9, 0x30, 0x10,
|
||||
0x4a, 0xf4, 0x5e, 0x52, 0xf8, 0x25, 0x32, 0x48, 0xcb, 0x02, 0x6c, 0x3b,
|
||||
0xa7, 0xe3, 0xbd, 0xe9, 0x54, 0xd5, 0xbe, 0x46, 0x6b, 0xea, 0x0b, 0x43,
|
||||
0x13, 0x1d, 0x6f, 0x9c, 0xf5, 0xeb, 0x0e, 0xba, 0x28, 0x4f, 0x98, 0x84,
|
||||
0xb2, 0x19, 0x9c, 0xfe, 0xa0, 0x4a, 0xf6, 0x07, 0xcc, 0x0c, 0x8f, 0x75,
|
||||
0x6a, 0x16, 0xa1, 0x1c, 0x4e, 0x42, 0x51, 0xdc, 0x17, 0xb0, 0xa4, 0x2c,
|
||||
0x86, 0x87, 0x55, 0xf5, 0x7a, 0x5a, 0xd0, 0x0d, 0x4b, 0x9f, 0xb9, 0xcb,
|
||||
0xf3, 0x23, 0x5b, 0xaa, 0x81, 0x0e, 0x74, 0x56, 0x96, 0xbb, 0x65, 0x14,
|
||||
0x3e, 0xb2, 0x17, 0x53, 0x7e, 0x71, 0xf1, 0x9b, 0xfd, 0x1c, 0x5c, 0xfe,
|
||||
0xee, 0x6b, 0x58, 0xc7, 0xb5, 0x82, 0xed, 0x14, 0x47, 0xb0, 0x62, 0xe8,
|
||||
0xad, 0x34, 0x9c, 0xe6, 0x12, 0x29, 0x3b, 0x91, 0x2b, 0x83, 0xe6, 0x5c,
|
||||
0xd4, 0xf1, 0x5b, 0x7f, 0xe0, 0x58, 0xc8, 0x29, 0xa4, 0x17, 0x76, 0xa0,
|
||||
0x95, 0x9d, 0xb1, 0xad, 0xa1, 0x01, 0xa2, 0xce, 0xd0, 0xa3, 0x14, 0x1e,
|
||||
0xb7, 0x22, 0x98, 0x9d, 0xcd, 0x7f, 0x8c, 0xb8, 0x0f, 0x5b, 0x5b, 0x36,
|
||||
0x3f, 0xce, 0xca, 0xce, 0x5b, 0x54, 0x8b, 0xbd, 0xde, 0x82, 0x7e, 0xf1,
|
||||
0xf9, 0xa0, 0x30, 0xfe, 0xbd, 0xe7, 0x35, 0x84, 0x29, 0x1e, 0x41, 0x8e,
|
||||
0x55, 0x3f, 0xf7, 0x40, 0x23, 0xaa, 0x2d, 0x5a, 0xe5, 0xc4, 0x32, 0x9e,
|
||||
0xbf, 0x22, 0xb0, 0xc1, 0xe7, 0x8c, 0x7d, 0x5d, 0x0b, 0x28, 0xb4, 0x57,
|
||||
0x8e, 0xe7, 0x56, 0x3d, 0x1f, 0x35, 0x1e, 0x98, 0xa9, 0x0d, 0xd7, 0xb7,
|
||||
0x20, 0xe2, 0x89, 0x90, 0x04, 0xa7, 0x56, 0xea, 0x84, 0x16, 0x6f, 0xff,
|
||||
0xa9, 0x38, 0x5e, 0xa0, 0xaf, 0x2d, 0xc1, 0xb6, 0xc1, 0x77, 0x72, 0xe1,
|
||||
0x21, 0xc7, 0x2f, 0x3f, 0x85, 0x51, 0x4b, 0x83, 0xca, 0x33, 0x50, 0xb1,
|
||||
0x4c, 0x58, 0x0c, 0x54, 0x7c, 0x70, 0xfe, 0x23, 0xef, 0xc7, 0xc7, 0xaf,
|
||||
0xaf, 0xbf, 0xe5, 0x7b, 0x05, 0x90, 0x6c, 0x7a, 0x9f, 0x66, 0xb9, 0xc6,
|
||||
0x44, 0xd5, 0x99, 0x6c, 0xd5, 0xac, 0x74, 0xce, 0x00, 0x49, 0x4b, 0xcf,
|
||||
0x51, 0x01, 0xda, 0x24, 0xc5, 0x42, 0xba, 0x6f, 0x8a, 0x73, 0x20, 0x11,
|
||||
0xbc, 0x4a, 0x4f, 0xdb, 0xa6, 0x40, 0x27, 0xbc, 0x93, 0xa3, 0x30, 0xb2,
|
||||
0xcc, 0x6e, 0x78, 0xa0, 0x28, 0x7d, 0xe7, 0x34, 0x11, 0x4c, 0x00, 0x8b,
|
||||
0x04, 0x3d, 0x93, 0x7f, 0x2a, 0x3c, 0x67, 0x56, 0xad, 0xc5, 0xdd, 0x2a,
|
||||
0x75, 0xe1, 0x96, 0x02, 0x8d, 0x66, 0x0e, 0xd8, 0xc1, 0x83, 0xdf, 0x27,
|
||||
0x42, 0xc4, 0x47, 0x18, 0x24, 0xac, 0x99, 0x8b, 0x22, 0x28, 0x68, 0x74,
|
||||
0xb2, 0x7e, 0x58, 0x19, 0x19, 0xda, 0xd4, 0x96, 0x36, 0x26, 0xc7, 0x53,
|
||||
0x37, 0xdb, 0x53, 0xa5, 0xd3, 0x98, 0xb4, 0x65, 0x80, 0xde, 0x73, 0xcb,
|
||||
0x97, 0x7e, 0x59, 0x80, 0xf6, 0x25, 0x60, 0x6f, 0x77, 0x20, 0x4c, 0xc7,
|
||||
0x35, 0xc6, 0x80, 0xe3, 0x56, 0x2c, 0xba, 0x62, 0xf7, 0x56, 0xf9, 0x63,
|
||||
0x3e, 0xf9, 0x91, 0x7b, 0x9c, 0x35, 0x02, 0x04, 0xd8, 0x3d, 0x35, 0xfd,
|
||||
0xb7, 0x85, 0xba, 0x04, 0x19, 0x7f, 0xb9, 0xe6, 0x6a, 0x65, 0x51, 0x9e,
|
||||
0xde, 0x21, 0xec, 0xf0, 0x6b, 0xfd, 0x41, 0x90, 0xdc, 0x32, 0x08, 0x4d,
|
||||
0x9b, 0x43, 0x2a, 0x61, 0x5b, 0x35, 0x61, 0xc1, 0xfd, 0xa2, 0xde, 0x30,
|
||||
0xd3, 0x93, 0xc6, 0x0d, 0xad, 0x76, 0xac, 0xfb, 0xb0, 0xee, 0x85, 0x5f,
|
||||
0xde, 0x4e, 0x2b, 0xe8, 0x8f, 0x67, 0xa0, 0x12, 0x00, 0x3f, 0xcf, 0x04,
|
||||
0xe4, 0xb1, 0x2b, 0xa0, 0xda, 0xbb, 0x33, 0x5a, 0x58, 0x9b, 0x7c, 0x05,
|
||||
0xea, 0x2b, 0x7b, 0x40, 0x9c, 0xc3, 0xe0, 0x99, 0x9e, 0xe0, 0x91, 0x67,
|
||||
0xa5, 0x63, 0x6b, 0x9f, 0x15, 0xb6, 0x3c, 0xda, 0x17, 0x90, 0x8f, 0x05,
|
||||
0x7e, 0x61, 0x7c, 0xc7, 0x25, 0xdf, 0xbb, 0xd6, 0x96, 0xba, 0x45, 0xa8,
|
||||
0x84, 0xa0, 0x7d, 0x0f, 0x41, 0xdd, 0xba, 0xe5, 0x5a, 0x09, 0x3d, 0xe7,
|
||||
0x20, 0x22, 0xc6, 0x8e, 0x0d, 0xd5, 0xc5, 0x75, 0x38, 0x8c, 0x6e, 0x4f,
|
||||
0xa0, 0x42, 0xf7, 0x5e, 0xb1, 0x35, 0xe5, 0xfc, 0x93, 0x13, 0x58, 0x2b,
|
||||
0xa7, 0xe0, 0xfe, 0xff, 0x1a, 0xdd, 0x30, 0x27, 0x9e, 0x69, 0xdd, 0x05,
|
||||
0x18, 0xf7, 0x23, 0x5d, 0x9c, 0x64, 0xbe, 0x47, 0xf0, 0xa8, 0xe1, 0xf5,
|
||||
0xde, 0x67, 0x8a, 0xcc, 0x18, 0xed, 0x4a, 0x76, 0xa0, 0x23, 0x96, 0x55,
|
||||
0xd0, 0x84, 0x22, 0xce, 0xe1, 0xe2, 0x11, 0x80, 0x95, 0x61, 0x0d, 0x75,
|
||||
0x12, 0x86, 0xb9, 0x3c, 0x10, 0x9d, 0x4d, 0x39, 0x93, 0x42, 0x7d, 0x83,
|
||||
0xa5, 0xf4, 0xe4, 0xaa, 0x9b, 0x59, 0x22, 0x5e, 0xd3, 0xfd, 0xad, 0xf9,
|
||||
0xa0, 0xf2, 0xb2, 0x70, 0x86, 0x29, 0xcd, 0x71, 0x61, 0x98, 0xb8, 0x21,
|
||||
0x15, 0x5d, 0xf5, 0xde, 0x4d, 0x65, 0x27, 0x09, 0x8c, 0xed, 0xd0, 0xc8,
|
||||
0xe7, 0xed, 0x0b, 0x0c, 0x13, 0x9e, 0x78, 0xea, 0xf8, 0x3c, 0x10, 0xda,
|
||||
0xcd, 0xfc, 0xaf, 0x33, 0x96, 0x62, 0x31, 0x9c, 0xb6, 0x9d, 0xc8, 0x7a,
|
||||
0x35, 0xe6, 0xff, 0x75, 0xa8, 0x30, 0x98, 0xd4, 0xaa, 0xcf, 0x9c, 0xef,
|
||||
0xda, 0xb9, 0x64, 0xe8, 0x3b, 0xa6, 0x2f, 0xc1, 0xbd, 0x7e, 0x6b, 0xfc,
|
||||
0x1a, 0xef, 0x62, 0xad, 0x90, 0x5e, 0x7d, 0x29, 0x12, 0x4d, 0x76, 0x86,
|
||||
0x5c, 0x29, 0x7c, 0x61, 0x1d, 0x1e, 0x63, 0x97, 0x21, 0xcd, 0x77, 0xbd,
|
||||
0xc2, 0x32, 0x45, 0xca, 0x7a, 0xdc, 0x0b, 0x16, 0xa4, 0x10, 0xac, 0x37,
|
||||
0xba, 0xf5, 0xf6, 0xbc, 0x26, 0x66, 0x67, 0x2b, 0xb8, 0x2e, 0x22, 0xc0,
|
||||
0xea, 0x90, 0x78, 0xf0, 0x0d, 0x0f, 0x80, 0x69, 0x60, 0xd2, 0x89, 0xa5,
|
||||
0x1a, 0xb0, 0xcf, 0x5e, 0x57, 0x6f, 0x79, 0xdc, 0xd8, 0x2c, 0x51, 0x92,
|
||||
0xd6, 0x62, 0x41, 0xf9, 0xf7, 0x26, 0xf0, 0x59, 0x93, 0xe2, 0x76, 0x82,
|
||||
0x21, 0xf6, 0xab, 0x7a, 0xd2, 0x7b, 0x81, 0xcb, 0x8c, 0xe8, 0x87, 0x77,
|
||||
0x76, 0xce, 0xf2, 0xaa, 0x00, 0xdc, 0xec, 0xd1, 0xc1, 0x8d, 0xf8, 0x42,
|
||||
0x41, 0x8c, 0x35, 0xd1, 0x70, 0x97, 0xf4, 0x82, 0x2f, 0x3a, 0x2f, 0x4a,
|
||||
0x18, 0x8f, 0xac, 0x41, 0xfa, 0x29, 0xc2, 0x9d, 0x0a, 0xfa, 0x0c, 0x44,
|
||||
0xdd, 0xea, 0xc6, 0x2b, 0xd3, 0x2e, 0x28, 0xee, 0xca, 0x6e, 0x84, 0x90,
|
||||
0xec, 0xaf, 0xf4, 0x8f, 0xbd, 0xc7, 0xd1, 0x2d, 0xf6, 0x9a, 0xd2, 0x00,
|
||||
0xaa, 0x5c, 0x38, 0xc5, 0x11, 0x43, 0x7c, 0xf4, 0x0d, 0xbd, 0x57, 0x6d,
|
||||
0x42, 0x62, 0xa5, 0xd8, 0x05, 0xa7, 0xe9, 0x30, 0xc0, 0x81, 0x9b, 0xfc,
|
||||
0x30, 0xda, 0x16, 0x2f, 0x54, 0x61, 0x08, 0xaa, 0xf7, 0xc0, 0x1e, 0x4d,
|
||||
0xf2, 0xd4, 0xed, 0x5c, 0x96, 0x30, 0xad, 0x9f, 0xc5, 0xe3, 0xf0, 0x91,
|
||||
0xff, 0xf0, 0xb1, 0xe4, 0x93, 0x7b, 0x67, 0x11, 0xba, 0xef, 0xb7, 0xf4,
|
||||
0x29, 0x93, 0x6d, 0x32, 0x1f, 0x88, 0xd1, 0x6c, 0x7c, 0x5a, 0x7e, 0x0a,
|
||||
0xef, 0x6a, 0xe9, 0x23, 0x2c, 0xde, 0x4c, 0x68, 0x36, 0xcb, 0xaa, 0x1f,
|
||||
0xd3, 0x71, 0xce, 0x31, 0x8b, 0x2b, 0x51, 0x16, 0xe6, 0x65, 0xd1, 0x30,
|
||||
0xaf, 0xb8, 0xbe, 0x02, 0x21, 0x61, 0x36, 0xbc, 0x19, 0x7c, 0x0e, 0x9d,
|
||||
0x9c, 0xd6, 0xa9, 0xc7, 0x5c, 0x2f, 0xb6, 0x23, 0x4b, 0x64, 0x3b, 0x99,
|
||||
0x74, 0x83, 0x51, 0xda, 0x3e, 0xf8, 0xcf, 0x0f, 0xa3, 0x7a, 0xfb, 0xaa,
|
||||
0xd1, 0xe2, 0x09, 0x05, 0x3a, 0xf5, 0xa8, 0x61, 0x51, 0x59, 0xf6, 0xb3,
|
||||
0x3d, 0xe9, 0xa3, 0xc7, 0x3a, 0xe6, 0xff, 0x2d, 0x96, 0xaf, 0xe4, 0x41,
|
||||
0xb8, 0x7d, 0xca, 0xdf, 0x42, 0x16, 0x5c, 0xee, 0xd0, 0x9d, 0xa3, 0x74,
|
||||
0xa9, 0xae, 0xfd, 0x6d, 0x3b, 0x15, 0xb9, 0x89, 0x19, 0xa8, 0xf8, 0x48,
|
||||
0xfe, 0x3a, 0xf6, 0xd7, 0x44, 0x4b, 0x96, 0x07, 0x37, 0x4b, 0xf9, 0x33,
|
||||
0x62, 0x4f, 0x08, 0x38, 0xfc, 0x02, 0xfc, 0x8d, 0x3d, 0x65, 0x83, 0x02,
|
||||
0xed, 0xd7, 0x48, 0x40, 0x51, 0x99, 0x0a, 0x20, 0xb2, 0xda, 0x9d, 0xca,
|
||||
0xbf, 0xb7, 0xcf, 0xa8, 0x32, 0x67, 0x2f, 0x31, 0xa3, 0x00, 0xe3, 0xcb,
|
||||
0x09, 0x7e, 0x0a, 0xb0, 0x7a, 0x34, 0x7b, 0xfc, 0x1d, 0x97, 0x8c, 0xa6,
|
||||
0x17, 0xcb, 0x62, 0xc7, 0x28, 0xf4, 0xb8, 0x21, 0xdb, 0x51, 0xc9, 0xef,
|
||||
0x69, 0xb6, 0xac, 0x36, 0x90, 0x74, 0x90, 0xb7, 0xdb, 0xcb, 0xfd, 0xdb,
|
||||
0x17, 0x81, 0xed, 0x94, 0x4d, 0xe5, 0x4e, 0xe5, 0xf6, 0x01, 0x4a, 0x99,
|
||||
0x9f, 0x5e, 0xe0, 0x45, 0x70, 0x41, 0x45, 0xa2, 0x2b, 0x4e, 0xd6, 0xab,
|
||||
0xdc, 0x06, 0x15, 0x2d, 0x48, 0x88, 0x17, 0x43, 0x39, 0x94, 0xb4, 0x3a,
|
||||
0x23, 0xce, 0xbb, 0xda, 0x0e, 0xb0, 0x5c, 0x1e, 0x0d, 0x0b, 0x31, 0x8e,
|
||||
0x9b, 0x04, 0x80, 0x78, 0x75, 0x1c, 0x9b, 0x97, 0xac, 0xc7, 0xad, 0xde,
|
||||
0x2b, 0x7f, 0x48, 0xb2, 0x29, 0xae, 0x76, 0x59, 0x27, 0xee, 0x79, 0xb8,
|
||||
0x8e, 0x30, 0xe7, 0xf2, 0x84, 0x44, 0x40, 0x79, 0x25, 0xce, 0x13, 0x87,
|
||||
0x8e, 0xfa, 0x08, 0x18, 0x8d, 0x71, 0xac, 0xeb, 0xf2, 0x7c, 0xa6, 0x69,
|
||||
0x29, 0x1b, 0xd8, 0x02, 0xea, 0x64, 0x40, 0x7d, 0xa1, 0xb2, 0x05, 0xd3,
|
||||
0x2b, 0x9d, 0x98, 0xa4, 0x2c, 0xee, 0xc9, 0x2c, 0x52, 0x5a, 0xd9, 0x3e,
|
||||
0xd4, 0xcc, 0x6b, 0xf5, 0x11, 0x4a, 0x0a, 0x84, 0x4b, 0x6e, 0xa4, 0xab,
|
||||
0x16, 0x46, 0x31, 0xb2, 0x84, 0x32, 0x43, 0x43, 0xe3, 0x21, 0x09, 0x33,
|
||||
0x53, 0x9d, 0x93, 0x60, 0xd4, 0x18, 0xef, 0x71, 0xc8, 0xd1, 0x97, 0x2b,
|
||||
0x2d, 0xa0, 0xe3, 0xc3, 0xb7, 0x54, 0x5b, 0xa2, 0xbf, 0x92, 0xa0, 0x48,
|
||||
0x15, 0xef, 0x8e, 0x25, 0x02, 0x49, 0x35, 0x20, 0x9e, 0x1b, 0x52, 0xfa,
|
||||
0xf9, 0x33, 0x99, 0x31, 0x2c, 0x1b, 0x04, 0x92, 0x8d, 0x19, 0xdb, 0x7d,
|
||||
0xad, 0x61, 0x29, 0xe3, 0x5c, 0xb7, 0x94, 0xa6, 0x8b, 0x2e, 0xc5, 0x2e,
|
||||
0xbd, 0xe0, 0x60, 0xae, 0xea, 0x93, 0x08, 0x64, 0x98, 0x9e, 0x8e, 0xa1,
|
||||
0x2e, 0xf1, 0xe0, 0x31, 0x57, 0x87, 0xd4, 0x77, 0x81, 0x6d, 0xf5, 0xa6,
|
||||
0x4c, 0x9b, 0x89, 0x8d, 0x08, 0x96, 0xc5, 0x96, 0xbe, 0x59, 0xcc, 0xbd,
|
||||
0x58, 0x7b, 0x21, 0x08, 0x19, 0xc0, 0x55, 0x33, 0x80, 0x44, 0x0d, 0x8e,
|
||||
0x59, 0xf9, 0xe8, 0x00, 0x50, 0x98, 0xa2, 0x30, 0xa6, 0xfd, 0xa8, 0x46,
|
||||
0xc5, 0x05, 0x65, 0x59, 0xe7, 0x25, 0x1a, 0x17, 0x32, 0x8a, 0xc0, 0x2a,
|
||||
0x15, 0x7e, 0x69, 0x11, 0xe9, 0x6d, 0xff, 0x96, 0x52, 0x98, 0xa3, 0xfa,
|
||||
0x43, 0x7b, 0x33, 0x79, 0x56, 0xc4, 0xe3, 0x27, 0x40, 0xd6, 0x33, 0xea,
|
||||
0xac, 0x87, 0x4e, 0x74, 0xbb, 0xe0, 0x52, 0xab, 0x56, 0x8a, 0xed, 0x3e,
|
||||
0xd2, 0x25, 0xb2, 0xbe, 0x58, 0x4c, 0xdf, 0x0e, 0x8f, 0xca, 0x57, 0xdc,
|
||||
0x00, 0xfa, 0xb0, 0xc0, 0xf3, 0x7b, 0x6e, 0x41, 0x17, 0x07, 0xcb, 0x08,
|
||||
0xe3, 0xd8, 0xa5, 0x04, 0xdb, 0x42, 0x99, 0x67, 0x73, 0xd5, 0xd7, 0x1f,
|
||||
0x22, 0x9e, 0xea, 0x66, 0x5f, 0x44, 0x7d, 0xf4, 0xbf, 0x50, 0xb2, 0x3e,
|
||||
0x2f, 0x9f, 0x7a, 0xca, 0x80, 0x95, 0x59, 0x83, 0x69, 0x05, 0xec, 0x70,
|
||||
0x71, 0x12, 0x97, 0xaf, 0xdb, 0xfd, 0xe8, 0x11, 0x44, 0x8a, 0x6e, 0x09,
|
||||
0x90, 0xd5, 0x59, 0x8c, 0x6a, 0x65, 0xf9, 0xa9, 0x3d, 0x3c, 0x0c, 0xf3,
|
||||
0x2f, 0xa0, 0xb1, 0x8e, 0xf0, 0x3f, 0x16, 0x63, 0xf6, 0xe8, 0x80, 0x27,
|
||||
0x64, 0x56, 0x99, 0x94, 0x93, 0xc8, 0x36, 0x00, 0x21, 0xeb, 0x7c, 0x41,
|
||||
0x86, 0xae, 0xb2, 0x4b, 0x7d, 0xac, 0xac, 0x90, 0x8b, 0x99, 0x18, 0x25,
|
||||
0xa4, 0x0d, 0x9c, 0x96, 0x53, 0x0c, 0xfa, 0x7e, 0x61, 0xba, 0x7f, 0xca,
|
||||
0x61, 0x7b, 0xba, 0x2f, 0x96, 0x2f, 0x75, 0x29, 0x84, 0xb7, 0x32, 0xca,
|
||||
0x3b, 0x1f, 0xe6, 0x57, 0x34, 0xf3, 0xf1, 0x58, 0x61, 0xc9, 0x04, 0xa2,
|
||||
0x20, 0xea, 0x77, 0xa7, 0x83, 0xed, 0x3e, 0x14, 0x87, 0x8f, 0x82, 0x86,
|
||||
0x88, 0xc3, 0xf9, 0x10, 0x7e, 0x03, 0xa4, 0x33, 0xe0, 0x4e, 0x97, 0xef,
|
||||
0x66, 0x91, 0x9f, 0xce, 0x85, 0xc8, 0xca, 0x04, 0x3a, 0x8b, 0xf6, 0xc7,
|
||||
0xdf, 0xeb, 0x75, 0x31, 0xf4, 0x1a, 0x9a, 0x67, 0xc7, 0xb1, 0xd0, 0x33,
|
||||
0x97, 0xea, 0xd2, 0x52, 0xc3, 0x81, 0xdb, 0x63, 0x64, 0x31, 0x0f, 0x9e,
|
||||
0x75, 0x5f, 0xde, 0xe7, 0x46, 0x01, 0x19, 0x03, 0xe5, 0x0b, 0xf8, 0x9f,
|
||||
0xab, 0x4f, 0x1a, 0x1f, 0xe0, 0xb0, 0x75, 0x96, 0xf2, 0x15, 0x49, 0x63,
|
||||
0xa7, 0xae, 0x26, 0xe5, 0x41, 0x82, 0x1b, 0x1e, 0xd0, 0x8b, 0x2e, 0xcc,
|
||||
0xf7, 0x30, 0xb3, 0xb5, 0x1b, 0xd9, 0xe7, 0x65, 0x1e, 0x60, 0x3b, 0x74,
|
||||
0xfa, 0x52, 0x03, 0xe9, 0x0f, 0x45, 0x87, 0x8c, 0x1a, 0x4d, 0x0d, 0xb9,
|
||||
0x90, 0xec, 0xa3, 0x59, 0xad, 0xa2, 0x33, 0xfb, 0xd3, 0xac, 0xf0, 0x58,
|
||||
0x0c, 0x6f, 0x27, 0xa9, 0x1b, 0x18, 0xcb, 0x5d, 0x70, 0xcd, 0x14, 0xd9,
|
||||
0xe3, 0x9f, 0x42, 0xf7, 0x82, 0x3e, 0x47, 0x39, 0xe4, 0xa2, 0x9e, 0x03,
|
||||
0x7c, 0x2f, 0x5d, 0x18, 0x55, 0x20, 0x63, 0x68, 0x38, 0xc8, 0x0b, 0x3d,
|
||||
0xf3, 0xc7, 0x91, 0x72, 0x70, 0x4c, 0x8a, 0x0d, 0xc0, 0x80, 0x7d, 0xde,
|
||||
0xa3, 0x7f, 0x0a, 0x54, 0xb5, 0xd0, 0x49, 0x42, 0xc3, 0x27, 0x69, 0x19,
|
||||
0x1c, 0xbc, 0xf9, 0x5e, 0x16, 0x19, 0xab, 0xdb, 0x99, 0x1e, 0x90, 0x8c,
|
||||
0x6e, 0xb9, 0x17, 0x95, 0xad, 0xde, 0x70, 0x93, 0x7f, 0x5f, 0x26, 0xb0,
|
||||
0x9f, 0x86, 0xb3, 0x82, 0x9d, 0x30, 0x24, 0x19, 0x83, 0x7d, 0x20, 0x70,
|
||||
0x29, 0xe1, 0xb3, 0x22, 0x99, 0xb5, 0xef, 0x8f, 0x7a, 0x66, 0xbc, 0x86,
|
||||
0x18, 0x85, 0x39, 0x56, 0x9b, 0x5f, 0xf6, 0x63, 0xc8, 0x24, 0xbc, 0x54,
|
||||
0xc3, 0xc3, 0xa3, 0x27, 0xad, 0x80, 0xa9, 0x8f, 0x3b, 0x4b, 0xa0, 0x08,
|
||||
0xcc, 0xf9, 0xde, 0x0b, 0x92, 0xa3, 0x26, 0x79, 0x42, 0xa2, 0xd0, 0x7c,
|
||||
0xd4, 0x2e, 0x8f, 0x63, 0x4b, 0xaf, 0x6b, 0x7a, 0x58, 0x99, 0xb2, 0xb4,
|
||||
0x01, 0x55, 0x75, 0x4a, 0xca, 0x9d, 0xd7, 0x85, 0xa8, 0x28, 0x97, 0x3d,
|
||||
0xa6, 0x3c, 0xd1, 0xf6, 0x97, 0xd4, 0x15, 0x45, 0xc4, 0x25, 0x48, 0xd5,
|
||||
0xa6, 0x10, 0x00, 0xa4, 0x3e, 0xc4, 0xb4, 0x1d, 0x08, 0xf0, 0xf7, 0x6d,
|
||||
0x91, 0xc9, 0xc4, 0x4e, 0xb5, 0xd5, 0x45, 0x07, 0x3e, 0x05, 0x34, 0x44,
|
||||
0x14, 0xe1, 0x11, 0x1e, 0xa2, 0xba, 0x37, 0x18, 0xea, 0x16, 0x78, 0x58,
|
||||
0x83, 0xfd, 0x98, 0x42, 0xd3, 0x83, 0xac, 0x77, 0x65, 0xc9, 0x5b, 0x36,
|
||||
0x8b, 0x9d, 0x76, 0x25, 0x5d, 0xfc, 0x80, 0x21, 0x0e, 0xd8, 0xcb, 0xc4,
|
||||
0xcc, 0x59, 0x4e, 0x85, 0x51, 0x3b, 0xc0, 0xa8, 0x0b, 0x5d, 0x60, 0xa2,
|
||||
0xc3, 0x2f, 0x2e, 0x8a, 0x18, 0x3c, 0x9d, 0x18, 0x0d, 0xd5, 0xa7, 0x32,
|
||||
0x72, 0xf0, 0xef, 0xdf, 0xa4, 0x35, 0x09, 0x75, 0x2f, 0xb0, 0xe0, 0xec,
|
||||
0xb2, 0x2d, 0x54, 0xeb, 0x22, 0x01, 0x67, 0x73, 0x61, 0x2d, 0x00, 0x8e,
|
||||
0x2a, 0x59, 0xc5, 0xa0, 0xf1, 0xb4, 0x20, 0x15, 0xeb, 0xe5, 0x0b, 0x7d,
|
||||
0x6b, 0x70, 0x45, 0x64, 0x3a, 0xc6, 0xbf, 0x34, 0x6a, 0x33, 0x35, 0xf2,
|
||||
0x88, 0x47, 0x4d, 0x95, 0x3d, 0x76, 0x7c, 0x56, 0x7a, 0x6a, 0x72, 0x48,
|
||||
0xa9, 0x28, 0x32, 0xf6, 0x25, 0xf5, 0x2a, 0x52, 0x40, 0x70, 0x46, 0x93,
|
||||
0x4e, 0x86, 0x58, 0xde, 0x11, 0x66, 0x2f, 0xa6, 0x75, 0xbd, 0x24, 0x05,
|
||||
0x3c, 0x5e, 0xf4, 0xbc, 0x88, 0xda, 0x69, 0xd0, 0x9d, 0x7f, 0xfa, 0x6b,
|
||||
0xf4, 0x50, 0x51, 0x03, 0x26, 0xf6, 0xaa, 0x11, 0xa6, 0x3d, 0x2a, 0xa3,
|
||||
0x18, 0x0e, 0xb1, 0x0b, 0x8c, 0x5a, 0x3a, 0xc4, 0x14, 0xd3, 0x9b, 0xea,
|
||||
0x2f, 0xf9, 0x5f, 0xbc, 0x9a, 0x94, 0x92, 0x2b, 0xaa, 0xf7, 0x62, 0x0c,
|
||||
0xf0, 0xf9, 0xcc, 0x20, 0x1b, 0x5b, 0x56, 0xed, 0xe4, 0x5f, 0xef, 0xa0,
|
||||
0x5d, 0xe2, 0xe7, 0x50, 0x0d, 0x13, 0x92, 0x7f, 0x70, 0x68, 0x81, 0x3c,
|
||||
0x5d, 0x71, 0x12, 0x14, 0xba, 0xe9, 0xf1, 0x24, 0x70, 0xc3, 0xea, 0x3a,
|
||||
0x8e, 0x19, 0xab, 0x4f, 0x5f, 0x20, 0x38, 0xcb, 0xd8, 0x91, 0x3d, 0x47,
|
||||
0x8a, 0xb8, 0xe0, 0x81, 0x73, 0x57, 0x19, 0xc4, 0xb6, 0xd7, 0x6e, 0x01,
|
||||
0xad, 0xb7, 0x80, 0xb2, 0x44, 0xe7, 0x77, 0x3a, 0x55, 0x9f, 0x36, 0x77,
|
||||
0x4c, 0x88, 0x69, 0x6b, 0xc6, 0x67, 0x2f, 0xbd, 0x37, 0x0c, 0xf2, 0x9f,
|
||||
0x88, 0x6e, 0xa6, 0xa0, 0xd7, 0x5a, 0x53, 0xf3, 0xc0, 0xaa, 0x7b, 0xca,
|
||||
0xc3, 0x07, 0xf4, 0x08, 0xc9, 0x84, 0x0c, 0x36, 0x49, 0x15, 0x71, 0x8c,
|
||||
0x60, 0x6f, 0xd5, 0x91, 0xc5, 0x3a, 0x33, 0x3b, 0xde, 0x8c, 0xe0, 0xf4,
|
||||
0x08, 0x42, 0x6d, 0xf7, 0x3b, 0xae, 0xd0, 0x06, 0xe5, 0x1b, 0x60, 0x24,
|
||||
0xc4, 0xaa, 0xcf, 0x54, 0x0e, 0x78, 0xa6, 0xf9, 0x40, 0x3b, 0xca, 0xed,
|
||||
0x5f, 0xa4, 0xd3, 0x13, 0x6e, 0x0a, 0x59, 0x3c, 0xda, 0xdb, 0xc6, 0x6f,
|
||||
0x8f, 0x89, 0x31, 0x8c, 0x87, 0x1e, 0xfe, 0x01, 0x16, 0x5b, 0xac, 0x1a,
|
||||
0x62, 0x85, 0x39, 0x61, 0xe1, 0x4c, 0xae, 0xae, 0x85, 0xd9, 0x5d, 0x9c,
|
||||
0x2a, 0x6e, 0x6b, 0xec, 0xef, 0x2b, 0xc6, 0x32, 0xd6, 0x62, 0x7e, 0x46,
|
||||
0x67, 0xe8, 0x6f, 0x4a, 0x50, 0x05, 0x75, 0xda, 0xe0, 0x6b, 0x47, 0xb6,
|
||||
0x2a, 0x48, 0x56, 0x3e, 0x22, 0x18, 0xfb, 0xf5, 0x66, 0xf1, 0x42, 0xd6,
|
||||
0xf3, 0x3d, 0x26, 0xc8, 0x44, 0xea, 0xa7, 0x9f, 0x90, 0xd8, 0x8f, 0xeb,
|
||||
0x45, 0x50, 0x99, 0xf8, 0x86, 0x5f, 0x70, 0x03, 0x89, 0x06, 0x08, 0x92,
|
||||
0x02, 0x6a, 0x93, 0x90, 0xce, 0xf2, 0xb5, 0x06, 0x78, 0x1e, 0x96, 0x1d,
|
||||
0xa2, 0x20, 0x27, 0x90, 0xfc, 0x07, 0x50, 0x84, 0xf8, 0x19, 0xd0, 0xb1,
|
||||
0x0c, 0x75, 0xb6, 0x3b, 0xb2, 0xaa, 0x73, 0x34, 0x49, 0xc9, 0xb2, 0xc2,
|
||||
0x58, 0x7e, 0x40, 0x19, 0xa6, 0x08, 0x6b, 0x9e, 0x87, 0xce, 0x7a, 0x27,
|
||||
0x3d, 0x7e, 0xe3, 0xe4, 0x12, 0x7c, 0x39, 0x24, 0x16, 0x80, 0x97, 0xbb,
|
||||
0x94, 0x9e, 0xa6, 0x0f, 0x5f, 0x42, 0xa1, 0xca, 0x37, 0xa0, 0xbe, 0x1c,
|
||||
0x4f, 0x62, 0x68, 0x6a, 0x50, 0x1e, 0x77, 0xe2, 0xb6, 0xdf, 0xa8, 0x89,
|
||||
0xdf, 0x98, 0x9b, 0x80, 0xc2, 0x00, 0x21, 0x6a, 0xf6, 0x82, 0xb3, 0x5f,
|
||||
0x8b, 0x98, 0x68, 0xe1, 0x76, 0xef, 0x06, 0x8c, 0x24, 0x07, 0xd2, 0xe5,
|
||||
0x86, 0xc1, 0xc0, 0x26, 0x94, 0x2d, 0x96, 0xb1, 0xa4, 0x77, 0x11, 0xcb,
|
||||
0xa9, 0xf9, 0x46, 0xe8, 0xfd, 0x91, 0x61, 0x9d, 0xce, 0xd1, 0x24, 0x27,
|
||||
0xbb, 0xae, 0x68, 0x04, 0x44, 0xc9, 0x44, 0x69, 0x52, 0x05, 0x10, 0x4d,
|
||||
0x96, 0x56, 0x98, 0x69, 0x46, 0x49, 0xc2, 0x75, 0xb9, 0xd8, 0x1c, 0x46,
|
||||
0xdc, 0x71, 0x86, 0x71, 0x07, 0xea, 0x18, 0x5d, 0x7c, 0x3f, 0x81, 0x97,
|
||||
0xfc, 0xc8, 0x88, 0xe4, 0xe7, 0x5e, 0xb2, 0xf8, 0x04, 0x17, 0x14, 0xcf,
|
||||
0x24, 0x4c, 0x35, 0x1e, 0x0d, 0xba, 0xf6, 0x0d, 0x29, 0x1c, 0x3c, 0x5a,
|
||||
0x0f, 0xd0, 0xf8, 0xf8, 0xdb, 0xa6, 0xa5, 0xf2, 0x83, 0x3d, 0xa0, 0x16,
|
||||
0x5d, 0xf4, 0xb7, 0xc0, 0xc5, 0xf1, 0x0f, 0x09, 0x7d, 0x6a, 0x24, 0xf0,
|
||||
0x94, 0x03, 0x7d, 0xc0, 0x96, 0x61, 0xa7, 0x44, 0xe2, 0xa3, 0x40, 0xa5,
|
||||
0x00, 0x06, 0x13, 0x45, 0xba, 0x60, 0xc3, 0x15, 0x75, 0x6a, 0xe6, 0xd9,
|
||||
0x21, 0x37, 0x15, 0x80, 0xfd, 0x68, 0xdf, 0xab, 0x9f, 0xde, 0xcf, 0x4a,
|
||||
0x98, 0xf8, 0xa9, 0x27, 0xd3, 0x2d, 0x3d, 0x5c, 0xdc, 0xff, 0x8c, 0x61,
|
||||
0x4d, 0x25, 0xc8, 0xdf, 0x66, 0xf6, 0xde, 0xf0, 0x21, 0x5a, 0x27, 0x36,
|
||||
0x38, 0x1f, 0xfe, 0x89, 0x33, 0x52, 0x4e, 0x99, 0x55, 0x9b, 0xd0, 0x4f,
|
||||
0x15, 0xba, 0x91, 0xdd, 0x95, 0xeb, 0x57, 0x18, 0xc4, 0x21, 0x86, 0x24,
|
||||
0x67, 0x38, 0xf0, 0x2f, 0xd2, 0x66, 0x0b, 0x92, 0xb9, 0xc3, 0xcb, 0x8e,
|
||||
0x7f, 0x6c, 0x44, 0xbc, 0xcb, 0x45, 0x71, 0x51, 0x61, 0x35, 0xf2, 0x9f,
|
||||
0xbf, 0xf2, 0x8f, 0x5a, 0xdb, 0xaa, 0x54, 0x20, 0x1d, 0x52, 0xce, 0x89,
|
||||
0xd4, 0xe7, 0x79, 0x75, 0xa7, 0xff, 0x1f, 0x6a, 0xfd, 0xb9, 0x56, 0xee,
|
||||
0xca, 0x2c, 0x9f, 0xf3, 0x6d, 0xdf, 0xce, 0x96, 0x0c, 0xaf, 0x2c, 0x2c,
|
||||
0x7d, 0x35, 0x79, 0x5d, 0x43, 0xbb, 0x27, 0xaf, 0x07, 0x17, 0x9a, 0x67,
|
||||
0xde, 0x3b, 0x35, 0xf1, 0xd9, 0x98, 0x92, 0xf8, 0x3d, 0x35, 0xf1, 0x25,
|
||||
0xf8, 0x15, 0xcc, 0x6f, 0x49, 0x9e, 0xba, 0x52, 0xd8, 0x76, 0x71, 0x8d,
|
||||
0x90, 0x2c, 0x73, 0x3f, 0xef, 0xa2, 0xef, 0x43, 0x19, 0x2d, 0x83, 0xb9,
|
||||
0xde, 0xc6, 0x33, 0x00, 0xd9, 0x9d, 0x50, 0x58, 0xa7, 0xaa, 0x07, 0xa6,
|
||||
0x81, 0x8c, 0x1b, 0xe7, 0x9a, 0x3f, 0x11, 0x4c, 0xef, 0x96, 0x07, 0xb3,
|
||||
0x48, 0x3e, 0x95, 0x2e, 0xb1, 0x27, 0x2d, 0xf9, 0x50, 0x49, 0x91, 0x7e,
|
||||
0x91, 0xd2, 0xcc, 0xf0, 0x36, 0xe8, 0xcd, 0x69, 0x05, 0x68, 0x50, 0xe6,
|
||||
0x4d, 0xbe, 0xd7, 0x55, 0xd5, 0xd2, 0xe4, 0x96, 0xd0, 0xa8, 0x1b, 0x4b,
|
||||
0x28, 0x54, 0xcb, 0x95, 0x4c, 0xb5, 0xe7, 0x1c, 0x95, 0x2e, 0x11, 0xda,
|
||||
0x30, 0x0e, 0x87, 0xfe, 0x5e, 0x34, 0x80, 0x59, 0x9d, 0x70, 0x09, 0x48,
|
||||
0x9e, 0xe8, 0x31, 0x12, 0x3f, 0xe2, 0x07, 0x35, 0x74, 0x79, 0x43, 0x68,
|
||||
0x42, 0x85, 0x09, 0x85, 0x42, 0x99, 0x5a, 0x92, 0x8c, 0xe9, 0x14, 0x6c,
|
||||
0xf3, 0x06, 0x50, 0x2a, 0x6d, 0xd8, 0xd5, 0x06, 0xdc, 0x8c, 0x4d, 0x60,
|
||||
0x84, 0x98, 0x6a, 0xf6, 0x30, 0xb9, 0x06, 0xe3, 0xcd, 0x75, 0xd7, 0xaa,
|
||||
0xbc, 0x56, 0x8d, 0x2f, 0x6b, 0x0d, 0x2e, 0x26, 0x40, 0x86, 0x08, 0xf5,
|
||||
0xc6, 0xee, 0x12, 0xd6, 0x06, 0x59, 0x7f, 0xa6, 0xac, 0x3f, 0xef, 0x15,
|
||||
0xd6, 0x20, 0x55, 0x21, 0xa9, 0x29, 0xdb, 0xf4, 0x1f, 0xa6, 0x79, 0x3c,
|
||||
0x13, 0xf0, 0x32, 0x7f, 0x25, 0x27, 0x7a, 0x64, 0xe1, 0x64, 0x3b, 0x86,
|
||||
0x14, 0x4e, 0xfd, 0x29, 0xbc, 0x6e, 0x9f, 0x1b, 0xaa, 0xdf, 0xe3, 0x77,
|
||||
0xd7, 0xb8, 0x7f, 0x61, 0x2f, 0xbc, 0xea, 0xfe, 0x18, 0xc6, 0x54, 0x91,
|
||||
0x85, 0xaa, 0x55, 0xa7, 0xca, 0x00, 0x8f, 0x56, 0xaf, 0xa8, 0x49, 0x02,
|
||||
0xcb, 0xbe, 0x20, 0x5a
|
||||
};
|
@ -29,20 +29,49 @@
|
||||
#include "cheat_engine.h"
|
||||
#include "crc.h"
|
||||
#include "version.h"
|
||||
#include "read_card.h"
|
||||
|
||||
const char TITLE_STRING[] = "Nitro Hax " VERSION_STRING "\nWritten by Chishm";
|
||||
const char* defaultFiles[] = {"cheats.xml", "/DS/NitroHax/cheats.xml", "/NitroHax/cheats.xml", "/data/NitroHax/cheats.xml", "/cheats.xml"};
|
||||
|
||||
const char* defaultFiles[] = {
|
||||
"cheats.xml",
|
||||
"/DS/NitroHax/cheats.xml",
|
||||
"/NitroHax/cheats.xml",
|
||||
"/NDS/NitroHax/cheats.xml",
|
||||
"/data/NitroHax/cheats.xml",
|
||||
"/_nds/NitroHax/cheats.xml",
|
||||
"/cheats.xml"};
|
||||
|
||||
static bool ROMisDSiExclusive(const tNDSHeader* ndsHeader) { return (ndsHeader->unitCode == 0x03); }
|
||||
static bool ROMisDSiEnhanced(const tNDSHeader* ndsHeader) { return (ndsHeader->unitCode == 0x02); }
|
||||
|
||||
static inline void ensure (bool condition, const char* errorMsg) {
|
||||
if (false == condition) {
|
||||
if (!condition) {
|
||||
ui.showMessage (errorMsg);
|
||||
while(1) swiWaitForVBlank();
|
||||
while(1)swiWaitForVBlank();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void DoWait(int waitTime = 30){
|
||||
for (int i = 0; i < waitTime; i++) swiWaitForVBlank();
|
||||
};
|
||||
|
||||
void ResetSlot1() {
|
||||
if (REG_SCFG_MC == 0x11) return;
|
||||
disableSlot1();
|
||||
DoWait();
|
||||
enableSlot1();
|
||||
}
|
||||
|
||||
void DoCartCheck() {
|
||||
if (REG_SCFG_MC == 0x11) {
|
||||
do { swiWaitForVBlank(); } while (REG_SCFG_MC != 0x10);
|
||||
enableSlot1();
|
||||
DoWait(60);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
int main(int argc, const char* argv[])
|
||||
{
|
||||
@ -57,7 +86,8 @@ int main(int argc, const char* argv[])
|
||||
std::string filename;
|
||||
int c;
|
||||
FILE* cheatFile;
|
||||
|
||||
bool isTWLCart = false;
|
||||
|
||||
ui.showMessage (UserInterface::TEXT_TITLE, TITLE_STRING);
|
||||
|
||||
#ifdef DEMO
|
||||
@ -68,15 +98,16 @@ int main(int argc, const char* argv[])
|
||||
ensure (fatInitDefault(), "FAT init failed");
|
||||
|
||||
// Read cheat file
|
||||
for (u32 i = 0; i < sizeof(defaultFiles)/sizeof(const char*); i++) {
|
||||
cheatFile = fopen (defaultFiles[i], "rb");
|
||||
if (NULL != cheatFile) break;
|
||||
for (const char* FileName : defaultFiles) {
|
||||
cheatFile = fopen(FileName, "rb");
|
||||
if (cheatFile)break;
|
||||
}
|
||||
if (NULL == cheatFile) {
|
||||
|
||||
if (!cheatFile) {
|
||||
filename = ui.fileBrowser (".xml");
|
||||
ensure (filename.size() > 0, "No file specified");
|
||||
cheatFile = fopen (filename.c_str(), "rb");
|
||||
ensure (cheatFile != NULL, "Couldn't load cheats");
|
||||
ensure (cheatFile, "Couldn't load cheats");
|
||||
}
|
||||
|
||||
ui.showMessage (UserInterface::TEXT_TITLE, TITLE_STRING);
|
||||
@ -93,24 +124,29 @@ int main(int argc, const char* argv[])
|
||||
ui.showMessage (UserInterface::TEXT_TITLE, TITLE_STRING);
|
||||
|
||||
sysSetCardOwner (BUS_OWNER_ARM9);
|
||||
|
||||
ui.showMessage ("Loaded codes\nYou can remove your flash card\nRemove DS Card");
|
||||
do {
|
||||
swiWaitForVBlank();
|
||||
getHeader (ndsHeader);
|
||||
} while (ndsHeader[0] != 0xffffffff);
|
||||
|
||||
ui.showMessage ("Insert Game");
|
||||
do {
|
||||
swiWaitForVBlank();
|
||||
getHeader (ndsHeader);
|
||||
} while (ndsHeader[0] == 0xffffffff);
|
||||
|
||||
// Delay half a second for the DS card to stabilise
|
||||
for (int i = 0; i < 30; i++) {
|
||||
swiWaitForVBlank();
|
||||
// Check if on DSi with unlocked SCFG, if not, then assume standard NTR precedure.
|
||||
if ((REG_SCFG_EXT & BIT(31))) {
|
||||
ui.showMessage ("Loaded codes\nChecking if a cart is inserted");
|
||||
if (REG_SCFG_MC != 0x18)ui.showMessage ("Insert Game");
|
||||
while (REG_SCFG_MC != 0x18)DoCartCheck();
|
||||
CardInit();
|
||||
} else {
|
||||
ui.showMessage ("Loaded codes\nYou can remove your flash card\nRemove DS Card");
|
||||
do {
|
||||
swiWaitForVBlank();
|
||||
getHeader (ndsHeader);
|
||||
} while (ndsHeader[0] != 0xffffffff);
|
||||
|
||||
ui.showMessage ("Insert Game");
|
||||
do {
|
||||
swiWaitForVBlank();
|
||||
getHeader (ndsHeader);
|
||||
} while (ndsHeader[0] == 0xffffffff);
|
||||
}
|
||||
|
||||
// Delay half a second for the DS card to stabilise
|
||||
DoWait();
|
||||
|
||||
getHeader (ndsHeader);
|
||||
|
||||
ui.showMessage ("Finding game");
|
||||
@ -119,13 +155,14 @@ int main(int argc, const char* argv[])
|
||||
headerCRC = crc32((const char*)ndsHeader, sizeof(ndsHeader));
|
||||
CheatFolder *gameCodes = codelist->getGame (gameid, headerCRC);
|
||||
|
||||
if (!gameCodes) {
|
||||
gameCodes = codelist;
|
||||
}
|
||||
if (!gameCodes)gameCodes = codelist;
|
||||
|
||||
ensure(!ROMisDSiExclusive((const tNDSHeader*)ndsHeader), "TWL exclusive games are not supported!");
|
||||
isTWLCart = ROMisDSiEnhanced((const tNDSHeader*)ndsHeader);
|
||||
|
||||
|
||||
ui.cheatMenu (gameCodes, gameCodes);
|
||||
|
||||
|
||||
cheatDest = (u32*) malloc(CHEAT_MAX_DATA_SIZE);
|
||||
ensure (cheatDest != NULL, "Bad malloc\n");
|
||||
|
||||
@ -138,11 +175,10 @@ int main(int argc, const char* argv[])
|
||||
ui.showMessage (UserInterface::TEXT_TITLE, TITLE_STRING);
|
||||
ui.showMessage ("Running game");
|
||||
|
||||
runCheatEngine (cheatDest, curCheat * sizeof(u32));
|
||||
runCheatEngine (cheatDest, curCheat * sizeof(u32), isTWLCart);
|
||||
|
||||
while(1) {
|
||||
|
||||
}
|
||||
while(1)swiWaitForVBlank();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -21,12 +21,7 @@
|
||||
#include "nds_card.h"
|
||||
|
||||
void getHeader (u32* ndsHeader) {
|
||||
cardParamCommand (CARD_CMD_DUMMY, 0,
|
||||
CARD_ACTIVATE | CARD_CLK_SLOW | CARD_BLK_SIZE(1) | CARD_DELAY1(0x1FFF) | CARD_DELAY2(0x3F),
|
||||
NULL, 0);
|
||||
|
||||
cardParamCommand(CARD_CMD_HEADER_READ, 0,
|
||||
CARD_ACTIVATE | CARD_nRESET | CARD_CLK_SLOW | CARD_BLK_SIZE(1) | CARD_DELAY1(0x1FFF) | CARD_DELAY2(0x3F),
|
||||
ndsHeader, 512);
|
||||
|
||||
cardParamCommand (CARD_CMD_DUMMY, 0, CARD_ACTIVATE | CARD_CLK_SLOW | CARD_BLK_SIZE(1) | CARD_DELAY1(0x1FFF) | CARD_DELAY2(0x3F), NULL, 0);
|
||||
cardParamCommand(CARD_CMD_HEADER_READ, 0, CARD_ACTIVATE | CARD_nRESET | CARD_CLK_SLOW | CARD_BLK_SIZE(1) | CARD_DELAY1(0x1FFF) | CARD_DELAY2(0x3F), ndsHeader, 512);
|
||||
}
|
||||
|
||||
|
141
arm9/source/ndsheaderbanner.h
Normal file
141
arm9/source/ndsheaderbanner.h
Normal file
@ -0,0 +1,141 @@
|
||||
/*---------------------------------------------------------------------------------
|
||||
|
||||
memory.h -- Declaration of memory regions
|
||||
|
||||
|
||||
Copyright (C) 2005 Michael Noland (joat) and Jason Rogers (dovoto)
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any
|
||||
purpose, including commercial applications, and to alter it and
|
||||
redistribute it freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you
|
||||
must not claim that you wrote the original software. If you use
|
||||
this software in a product, an acknowledgment in the product
|
||||
documentation would be appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and
|
||||
must not be misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
|
||||
---------------------------------------------------------------------------------*/
|
||||
/*! \file ndsheaderbanner.h
|
||||
\brief Defines the Nintendo DS file header and icon/title structs.
|
||||
*/
|
||||
|
||||
#ifndef NDS_HEADER2
|
||||
#define NDS_HEADER2
|
||||
|
||||
#include <nds.h>
|
||||
|
||||
/*!
|
||||
\brief the NDS file header format
|
||||
See gbatek for more info.
|
||||
*/
|
||||
typedef struct {
|
||||
char gameTitle[12]; //!< 12 characters for the game title.
|
||||
char gameCode[4]; //!< 4 characters for the game code.
|
||||
char makercode[2]; //!< identifies the (commercial) developer.
|
||||
u8 unitCode; //!< identifies the required hardware.
|
||||
u8 deviceType; //!< type of device in the game card
|
||||
u8 deviceSize; //!< capacity of the device (1 << n Mbit)
|
||||
u8 reserved1[9];
|
||||
u8 romversion; //!< version of the ROM.
|
||||
u8 flags; //!< bit 2: auto-boot flag.
|
||||
|
||||
u32 arm9romOffset; //!< offset of the arm9 binary in the nds file.
|
||||
u32 arm9executeAddress; //!< adress that should be executed after the binary has been copied.
|
||||
u32 arm9destination; //!< destination address to where the arm9 binary should be copied.
|
||||
u32 arm9binarySize; //!< size of the arm9 binary.
|
||||
|
||||
u32 arm7romOffset; //!< offset of the arm7 binary in the nds file.
|
||||
u32 arm7executeAddress; //!< adress that should be executed after the binary has been copied.
|
||||
u32 arm7destination; //!< destination address to where the arm7 binary should be copied.
|
||||
u32 arm7binarySize; //!< size of the arm7 binary.
|
||||
|
||||
u32 filenameOffset; //!< File Name Table (FNT) offset.
|
||||
u32 filenameSize; //!< File Name Table (FNT) size.
|
||||
u32 fatOffset; //!< File Allocation Table (FAT) offset.
|
||||
u32 fatSize; //!< File Allocation Table (FAT) size.
|
||||
|
||||
u32 arm9overlaySource; //!< File arm9 overlay offset.
|
||||
u32 arm9overlaySize; //!< File arm9 overlay size.
|
||||
u32 arm7overlaySource; //!< File arm7 overlay offset.
|
||||
u32 arm7overlaySize; //!< File arm7 overlay size.
|
||||
|
||||
u32 cardControl13; //!< Port 40001A4h setting for normal commands (used in modes 1 and 3)
|
||||
u32 cardControlBF; //!< Port 40001A4h setting for KEY1 commands (used in mode 2)
|
||||
u32 bannerOffset; //!< offset to the banner with icon and titles etc.
|
||||
|
||||
u16 secureCRC16; //!< Secure Area Checksum, CRC-16.
|
||||
|
||||
u16 readTimeout; //!< Secure Area Loading Timeout.
|
||||
|
||||
u32 unknownRAM1; //!< ARM9 Auto Load List RAM Address (?)
|
||||
u32 unknownRAM2; //!< ARM7 Auto Load List RAM Address (?)
|
||||
|
||||
u32 bfPrime1; //!< Secure Area Disable part 1.
|
||||
u32 bfPrime2; //!< Secure Area Disable part 2.
|
||||
u32 romSize; //!< total size of the ROM.
|
||||
|
||||
u32 headerSize; //!< ROM header size.
|
||||
u32 zeros88[3];
|
||||
u16 nandRomEnd; //!< ROM region end for NAND games.
|
||||
u16 nandRwStart; //!< RW region start for NAND games.
|
||||
u32 zeros98[10];
|
||||
u8 gbaLogo[156]; //!< Nintendo logo needed for booting the game.
|
||||
u16 logoCRC16; //!< Nintendo Logo Checksum, CRC-16.
|
||||
u16 headerCRC16; //!< header checksum, CRC-16.
|
||||
|
||||
u32 debugRomSource; //!< debug ROM offset.
|
||||
u32 debugRomSize; //!< debug size.
|
||||
u32 debugRomDestination; //!< debug RAM destination.
|
||||
u32 offset_0x16C; //reserved?
|
||||
|
||||
u8 zero[0x40];
|
||||
u32 region;
|
||||
u32 accessControl;
|
||||
u32 arm7SCFGSettings;
|
||||
u16 dsi_unk1;
|
||||
u8 dsi_unk2;
|
||||
u8 dsi_flags;
|
||||
|
||||
u32 arm9iromOffset; //!< offset of the arm9 binary in the nds file.
|
||||
u32 arm9iexecuteAddress;
|
||||
u32 arm9idestination; //!< destination address to where the arm9 binary should be copied.
|
||||
u32 arm9ibinarySize; //!< size of the arm9 binary.
|
||||
|
||||
u32 arm7iromOffset; //!< offset of the arm7 binary in the nds file.
|
||||
u32 deviceListDestination;
|
||||
u32 arm7idestination; //!< destination address to where the arm7 binary should be copied.
|
||||
u32 arm7ibinarySize; //!< size of the arm7 binary.
|
||||
|
||||
u8 zero2[0x20];
|
||||
|
||||
// 0x200
|
||||
// TODO: More DSi-specific fields.
|
||||
u32 dsi1[0x10/4];
|
||||
u32 twlRomSize;
|
||||
u32 dsi_unk3;
|
||||
u32 dsi_unk4;
|
||||
u32 dsi_unk5;
|
||||
u8 dsi2[0x10];
|
||||
u32 dsi_tid;
|
||||
u32 dsi_tid2;
|
||||
u32 pubSavSize;
|
||||
u32 prvSavSize;
|
||||
u8 dsi3[0x174];
|
||||
} sNDSHeaderExt;
|
||||
|
||||
//#define __NDSHeader ((tNDSHeader *)0x02FFFE00)
|
||||
|
||||
// Make sure the header size is correct.
|
||||
//static_assert(sizeof(sNDSHeaderExt) == 0x3B4, "sizeof(sNDSHeaderExt) is not 0x3B4 bytes");
|
||||
|
||||
#endif // NDS_HEADER2
|
785
arm9/source/read_card.c
Normal file
785
arm9/source/read_card.c
Normal file
@ -0,0 +1,785 @@
|
||||
/*
|
||||
NitroHax -- Cheat tool for the Nintendo DS
|
||||
Copyright (C) 2008 Michael "Chishm" Chisholm
|
||||
|
||||
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 "read_card.h"
|
||||
|
||||
#include <nds.h>
|
||||
#include <nds/arm9/cache.h>
|
||||
#include <nds/dma.h>
|
||||
#include <nds/card.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "encryption.h"
|
||||
#include "tonccpy.h"
|
||||
|
||||
enum {
|
||||
ERR_NONE = 0x00,
|
||||
ERR_STS_CLR_MEM = 0x01,
|
||||
ERR_STS_LOAD_BIN = 0x02,
|
||||
ERR_STS_HOOK_BIN = 0x03,
|
||||
ERR_STS_START = 0x04,
|
||||
// initCard error codes:
|
||||
ERR_LOAD_NORM = 0x11,
|
||||
ERR_LOAD_OTHR = 0x12,
|
||||
ERR_SEC_NORM = 0x13,
|
||||
ERR_SEC_OTHR = 0x14,
|
||||
ERR_LOGO_CRC = 0x15,
|
||||
ERR_HEAD_CRC = 0x16,
|
||||
} ERROR_CODES;
|
||||
|
||||
// NAND Card commands
|
||||
// https://problemkaputt.de/gbatek-ds-cartridge-nand.htm
|
||||
#define CARD_CMD_NAND_WRITE_BUFFER 0x81
|
||||
#define CARD_CMD_NAND_COMMIT_BUFFER 0x82
|
||||
#define CARD_CMD_NAND_DISCARD_BUFFER 0x84
|
||||
#define CARD_CMD_NAND_WRITE_ENABLE 0x85
|
||||
#define CARD_CMD_NAND_ROM_MODE 0x8B
|
||||
#define CARD_CMD_NAND_RW_MODE 0xB2
|
||||
#define CARD_CMD_NAND_READ_STATUS 0xD6
|
||||
#define CARD_CMD_NAND_UNKNOWN 0xBB
|
||||
#define CARD_CMD_NAND_READ_ID 0x94
|
||||
|
||||
typedef union
|
||||
{
|
||||
char title[4];
|
||||
u32 key;
|
||||
} GameCode;
|
||||
|
||||
static bool twlBlowfish = false;
|
||||
|
||||
static bool normalChip = false; // As defined by GBAtek, normal chip secure area is accessed in blocks of 0x200, other chip in blocks of 0x1000
|
||||
static u32 portFlags = 0;
|
||||
static u32 headerData[0x1000/sizeof(u32)] = {0};
|
||||
static u32 secureArea[CARD_SECURE_AREA_SIZE/sizeof(u32)] = {0};
|
||||
static u32 iCardId;
|
||||
|
||||
static bool nandChip = false;
|
||||
static int nandSection = -1; // -1 = ROM, above that is the current 128 KiB section in RW
|
||||
u32 cardNandRomEnd = 0;
|
||||
u32 cardNandRwStart = 0;
|
||||
|
||||
static const u8 cardSeedBytes[] = {0xE8, 0x4D, 0x5A, 0xB1, 0x17, 0x8F, 0x99, 0xD5};
|
||||
|
||||
static u32 getRandomNumber(void) {
|
||||
return rand();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
// https://github.com/devkitPro/libnds/blob/105d4943dbac8f2bd99a47b22cd3ed48f96af083/source/common/card.c#L47-L62
|
||||
// but modified to write if CARD_WR is set.
|
||||
static void cardPolledTransferWrite(u32 flags, u32 *buffer, u32 length, const u8 *command) {
|
||||
//---------------------------------------------------------------------------------
|
||||
cardWriteCommand(command);
|
||||
REG_ROMCTRL = flags | CARD_BUSY;
|
||||
u32 * target = buffer + length;
|
||||
do {
|
||||
// Read/write data if available
|
||||
if (REG_ROMCTRL & CARD_DATA_READY) {
|
||||
if (flags & CARD_WR) { // Write
|
||||
if (NULL != buffer && buffer < target)
|
||||
REG_CARD_DATA_RD = *buffer++;
|
||||
else
|
||||
REG_CARD_DATA_RD = 0;
|
||||
} else { // Read
|
||||
u32 data = REG_CARD_DATA_RD;
|
||||
if (NULL != buffer && buffer < target)
|
||||
*buffer++ = REG_CARD_DATA_RD;
|
||||
else
|
||||
(void)data;
|
||||
}
|
||||
}
|
||||
} while (REG_ROMCTRL & CARD_BUSY);
|
||||
}
|
||||
|
||||
static void decryptSecureArea (u32 gameCode, u32* secureArea, int iCardDevice)
|
||||
{
|
||||
init_keycode (gameCode, 2, 8, iCardDevice);
|
||||
crypt_64bit_down (secureArea);
|
||||
|
||||
init_keycode (gameCode, 3, 8, iCardDevice);
|
||||
|
||||
for (int i = 0; i < 0x200; i+= 2) {
|
||||
crypt_64bit_down (secureArea + i);
|
||||
}
|
||||
}
|
||||
|
||||
static struct {
|
||||
unsigned int iii;
|
||||
unsigned int jjj;
|
||||
unsigned int kkkkk;
|
||||
unsigned int llll;
|
||||
unsigned int mmm;
|
||||
unsigned int nnn;
|
||||
} key1data;
|
||||
|
||||
|
||||
static void initKey1Encryption (u8* cmdData, int iCardDevice) {
|
||||
key1data.iii = getRandomNumber() & 0x00000fff;
|
||||
key1data.jjj = getRandomNumber() & 0x00000fff;
|
||||
key1data.kkkkk = getRandomNumber() & 0x000fffff;
|
||||
key1data.llll = getRandomNumber() & 0x0000ffff;
|
||||
key1data.mmm = getRandomNumber() & 0x00000fff;
|
||||
key1data.nnn = getRandomNumber() & 0x00000fff;
|
||||
|
||||
if(iCardDevice) //DSi
|
||||
cmdData[7]=0x3D; // CARD_CMD_ACTIVATE_BF2
|
||||
else
|
||||
cmdData[7]=CARD_CMD_ACTIVATE_BF;
|
||||
|
||||
cmdData[6] = (u8) (key1data.iii >> 4);
|
||||
cmdData[5] = (u8) ((key1data.iii << 4) | (key1data.jjj >> 8));
|
||||
cmdData[4] = (u8) key1data.jjj;
|
||||
cmdData[3] = (u8) (key1data.kkkkk >> 16);
|
||||
cmdData[2] = (u8) (key1data.kkkkk >> 8);
|
||||
cmdData[1] = (u8) key1data.kkkkk;
|
||||
cmdData[0] = (u8) getRandomNumber();
|
||||
}
|
||||
|
||||
// Note: cmdData must be aligned on a word boundary
|
||||
static void createEncryptedCommand (u8 command, u8* cmdData, u32 block)
|
||||
{
|
||||
unsigned long iii, jjj;
|
||||
|
||||
if (command != CARD_CMD_SECURE_READ) {
|
||||
block = key1data.llll;
|
||||
}
|
||||
|
||||
if (command == CARD_CMD_ACTIVATE_SEC) {
|
||||
iii = key1data.mmm;
|
||||
jjj = key1data.nnn;
|
||||
} else {
|
||||
iii = key1data.iii;
|
||||
jjj = key1data.jjj;
|
||||
}
|
||||
|
||||
cmdData[7] = (u8) (command | (block >> 12));
|
||||
cmdData[6] = (u8) (block >> 4);
|
||||
cmdData[5] = (u8) ((block << 4) | (iii >> 8));
|
||||
cmdData[4] = (u8) iii;
|
||||
cmdData[3] = (u8) (jjj >> 4);
|
||||
cmdData[2] = (u8) ((jjj << 4) | (key1data.kkkkk >> 16));
|
||||
cmdData[1] = (u8) (key1data.kkkkk >> 8);
|
||||
cmdData[0] = (u8) key1data.kkkkk;
|
||||
|
||||
crypt_64bit_up ((u32*)cmdData);
|
||||
|
||||
key1data.kkkkk += 1;
|
||||
}
|
||||
|
||||
static void cardDelay (u16 readTimeout) {
|
||||
/* Using a while loop to check the timeout,
|
||||
so we have to wait until one before overflow.
|
||||
This also requires an extra 1 for the timer data.
|
||||
See GBATek for the normal formula used for card timeout.
|
||||
*/
|
||||
TIMER_DATA(0) = 0 - (((readTimeout & 0x3FFF) + 3));
|
||||
TIMER_CR(0) = TIMER_DIV_256 | TIMER_ENABLE;
|
||||
while (TIMER_DATA(0) != 0xFFFF);
|
||||
|
||||
// Clear out the timer registers
|
||||
TIMER_CR(0) = 0;
|
||||
TIMER_DATA(0) = 0;
|
||||
}
|
||||
|
||||
static void switchToTwlBlowfish(sNDSHeaderExt* ndsHeader) {
|
||||
if (twlBlowfish || ndsHeader->unitCode == 0) return;
|
||||
|
||||
// Used for dumping the DSi arm9i/7i binaries
|
||||
|
||||
u32 portFlagsKey1, portFlagsSecRead;
|
||||
int secureBlockNumber;
|
||||
int i;
|
||||
u8 cmdData[8] __attribute__ ((aligned));
|
||||
GameCode* gameCode;
|
||||
|
||||
if (isDSiMode()) {
|
||||
// Reset card slot
|
||||
disableSlot1();
|
||||
for(int i = 0; i < 25; i++) { swiWaitForVBlank(); }
|
||||
enableSlot1();
|
||||
for(int i = 0; i < 15; i++) { swiWaitForVBlank(); }
|
||||
|
||||
// Dummy command sent after card reset
|
||||
cardParamCommand (CARD_CMD_DUMMY, 0,
|
||||
CARD_ACTIVATE | CARD_nRESET | CARD_CLK_SLOW | CARD_BLK_SIZE(1) | CARD_DELAY1(0x1FFF) | CARD_DELAY2(0x3F),
|
||||
NULL, 0);
|
||||
} else {
|
||||
REG_ROMCTRL=0;
|
||||
REG_AUXSPICNT=0;
|
||||
//ioDelay2(167550);
|
||||
for(i = 0; i < 25; i++) { swiWaitForVBlank(); }
|
||||
REG_AUXSPICNT=CARD_CR1_ENABLE|CARD_CR1_IRQ;
|
||||
REG_ROMCTRL=CARD_nRESET|CARD_SEC_SEED;
|
||||
while(REG_ROMCTRL&CARD_BUSY) ;
|
||||
cardReset();
|
||||
while(REG_ROMCTRL&CARD_BUSY) ;
|
||||
}
|
||||
|
||||
//int iCardDevice = 1;
|
||||
|
||||
// Initialise blowfish encryption for KEY1 commands and decrypting the secure area
|
||||
gameCode = (GameCode*)ndsHeader->gameCode;
|
||||
init_keycode (gameCode->key, 1, 8, 1);
|
||||
|
||||
// Port 40001A4h setting for normal reads (command B7)
|
||||
portFlags = ndsHeader->cardControl13 & ~CARD_BLK_SIZE(7);
|
||||
// Port 40001A4h setting for KEY1 commands (usually 001808F8h)
|
||||
portFlagsKey1 = CARD_ACTIVATE | CARD_nRESET | (ndsHeader->cardControl13 & (CARD_WR|CARD_CLK_SLOW)) |
|
||||
((ndsHeader->cardControlBF & (CARD_CLK_SLOW|CARD_DELAY1(0x1FFF))) + ((ndsHeader->cardControlBF & CARD_DELAY2(0x3F)) >> 16));
|
||||
|
||||
// Adjust card transfer method depending on the most significant bit of the chip ID
|
||||
if (!normalChip) {
|
||||
portFlagsKey1 |= CARD_SEC_LARGE;
|
||||
}
|
||||
|
||||
// 3Ciiijjj xkkkkkxx - Activate KEY1 Encryption Mode
|
||||
initKey1Encryption (cmdData, 1);
|
||||
cardPolledTransfer((ndsHeader->cardControl13 & (CARD_WR|CARD_nRESET|CARD_CLK_SLOW)) | CARD_ACTIVATE, NULL, 0, cmdData);
|
||||
|
||||
// 4llllmmm nnnkkkkk - Activate KEY2 Encryption Mode
|
||||
createEncryptedCommand (CARD_CMD_ACTIVATE_SEC, cmdData, 0);
|
||||
|
||||
if (normalChip) {
|
||||
cardPolledTransfer(portFlagsKey1, NULL, 0, cmdData);
|
||||
cardDelay(ndsHeader->readTimeout);
|
||||
}
|
||||
cardPolledTransfer(portFlagsKey1, NULL, 0, cmdData);
|
||||
|
||||
// Set the KEY2 encryption registers
|
||||
REG_ROMCTRL = 0;
|
||||
REG_CARD_1B0 = cardSeedBytes[ndsHeader->deviceType & 0x07] | (key1data.nnn << 15) | (key1data.mmm << 27) | 0x6000;
|
||||
REG_CARD_1B4 = 0x879b9b05;
|
||||
REG_CARD_1B8 = key1data.mmm >> 5;
|
||||
REG_CARD_1BA = 0x5c;
|
||||
REG_ROMCTRL = CARD_nRESET | CARD_SEC_SEED | CARD_SEC_EN | CARD_SEC_DAT;
|
||||
|
||||
// Update the DS card flags to suit KEY2 encryption
|
||||
portFlagsKey1 |= CARD_SEC_EN | CARD_SEC_DAT;
|
||||
|
||||
// 1lllliii jjjkkkkk - 2nd Get ROM Chip ID / Get KEY2 Stream
|
||||
createEncryptedCommand (CARD_CMD_SECURE_CHIPID, cmdData, 0);
|
||||
|
||||
if (normalChip) {
|
||||
cardPolledTransfer(portFlagsKey1, NULL, 0, cmdData);
|
||||
cardDelay(ndsHeader->readTimeout);
|
||||
}
|
||||
cardPolledTransfer(portFlagsKey1 | CARD_BLK_SIZE(7), NULL, 0, cmdData);
|
||||
|
||||
// 2bbbbiii jjjkkkkk - Get Secure Area Block
|
||||
portFlagsSecRead = (ndsHeader->cardControlBF & (CARD_CLK_SLOW|CARD_DELAY1(0x1FFF)|CARD_DELAY2(0x3F)))
|
||||
| CARD_ACTIVATE | CARD_nRESET | CARD_SEC_EN | CARD_SEC_DAT;
|
||||
|
||||
int secureAreaOffset = 0;
|
||||
for (secureBlockNumber = 4; secureBlockNumber < 8; secureBlockNumber++) {
|
||||
createEncryptedCommand (CARD_CMD_SECURE_READ, cmdData, secureBlockNumber);
|
||||
|
||||
if (normalChip) {
|
||||
cardPolledTransfer(portFlagsSecRead, NULL, 0, cmdData);
|
||||
cardDelay(ndsHeader->readTimeout);
|
||||
for (i = 8; i > 0; i--) {
|
||||
cardPolledTransfer(portFlagsSecRead | CARD_BLK_SIZE(1), secureArea + secureAreaOffset, 0x200, cmdData);
|
||||
secureAreaOffset += 0x200/sizeof(u32);
|
||||
}
|
||||
} else {
|
||||
cardPolledTransfer(portFlagsSecRead | CARD_BLK_SIZE(4) | CARD_SEC_LARGE, secureArea + secureAreaOffset, 0x1000, cmdData);
|
||||
secureAreaOffset += 0x1000/sizeof(u32);
|
||||
}
|
||||
}
|
||||
|
||||
// Alllliii jjjkkkkk - Enter Main Data Mode
|
||||
createEncryptedCommand (CARD_CMD_DATA_MODE, cmdData, 0);
|
||||
|
||||
if (normalChip) {
|
||||
cardPolledTransfer(portFlagsKey1, NULL, 0, cmdData);
|
||||
cardDelay(ndsHeader->readTimeout);
|
||||
}
|
||||
cardPolledTransfer(portFlagsKey1, NULL, 0, cmdData);
|
||||
|
||||
// The 0x800 bytes are modcrypted, so this function isn't ran
|
||||
//decryptSecureArea (gameCode->key, secureArea, 1);
|
||||
|
||||
twlBlowfish = true;
|
||||
}
|
||||
|
||||
|
||||
int cardInit (sNDSHeaderExt* ndsHeader)
|
||||
{
|
||||
u32 portFlagsKey1, portFlagsSecRead;
|
||||
normalChip = false; // As defined by GBAtek, normal chip secure area and header are accessed in blocks of 0x200, other chip in blocks of 0x1000
|
||||
nandChip = false;
|
||||
nandSection = -1;
|
||||
int secureBlockNumber;
|
||||
int i;
|
||||
u8 cmdData[8] __attribute__ ((aligned));
|
||||
GameCode* gameCode;
|
||||
|
||||
twlBlowfish = false;
|
||||
|
||||
sysSetCardOwner (BUS_OWNER_ARM9); // Allow arm9 to access NDS cart
|
||||
if (isDSiMode()) {
|
||||
// Reset card slot
|
||||
if(REG_SCFG_MC != 0x11){
|
||||
disableSlot1();
|
||||
for(i = 0; i < 30; i++) { swiWaitForVBlank(); }
|
||||
}
|
||||
enableSlot1();
|
||||
for(i = 0; i < 15; i++) { swiWaitForVBlank(); }
|
||||
// Dummy command sent after card reset
|
||||
cardParamCommand (CARD_CMD_DUMMY, 0, CARD_ACTIVATE | CARD_nRESET | CARD_CLK_SLOW | CARD_BLK_SIZE(1) | CARD_DELAY1(0x1FFF) | CARD_DELAY2(0x3F), NULL, 0);
|
||||
}
|
||||
|
||||
REG_ROMCTRL=0;
|
||||
REG_AUXSPICNT=0;
|
||||
//ioDelay2(167550);
|
||||
for(i = 0; i < 25; i++) { swiWaitForVBlank(); }
|
||||
REG_AUXSPICNT=CARD_CR1_ENABLE|CARD_CR1_IRQ;
|
||||
REG_ROMCTRL=CARD_nRESET|CARD_SEC_SEED;
|
||||
while(REG_ROMCTRL&CARD_BUSY) ;
|
||||
cardReset();
|
||||
while(REG_ROMCTRL&CARD_BUSY) ;
|
||||
|
||||
toncset(headerData, 0, 0x1000);
|
||||
|
||||
iCardId=cardReadID(CARD_CLK_SLOW);
|
||||
while(REG_ROMCTRL & CARD_BUSY);
|
||||
|
||||
normalChip = (iCardId & BIT(31)) != 0; // ROM chip ID MSB
|
||||
nandChip = (iCardId & BIT(27)) != 0; // Card has a NAND chip
|
||||
|
||||
// Read the header
|
||||
cardParamCommand (CARD_CMD_HEADER_READ, 0,
|
||||
CARD_ACTIVATE | CARD_nRESET | CARD_CLK_SLOW | CARD_BLK_SIZE(1) | CARD_DELAY1(0x1FFF) | CARD_DELAY2(0x3F),
|
||||
(void*)headerData, 0x200/sizeof(u32));
|
||||
|
||||
tonccpy(ndsHeader, headerData, 0x200);
|
||||
|
||||
if ((ndsHeader->unitCode != 0) || (ndsHeader->dsi_flags != 0))
|
||||
{
|
||||
// Extended header found
|
||||
if(normalChip) {
|
||||
for(int i = 0; i < 8; i++) {
|
||||
cardParamCommand (CARD_CMD_HEADER_READ, i * 0x200,
|
||||
CARD_ACTIVATE | CARD_nRESET | CARD_CLK_SLOW | CARD_BLK_SIZE(1) | CARD_DELAY1(0x1FFF) | CARD_DELAY2(0x3F),
|
||||
headerData + i * 0x200 / sizeof(u32), 0x200/sizeof(u32));
|
||||
}
|
||||
} else {
|
||||
cardParamCommand (CARD_CMD_HEADER_READ, 0,
|
||||
CARD_ACTIVATE | CARD_nRESET | CARD_CLK_SLOW | CARD_BLK_SIZE(4) | CARD_DELAY1(0x1FFF) | CARD_DELAY2(0x3F),
|
||||
(void*)headerData, 0x1000/sizeof(u32));
|
||||
}
|
||||
if (ndsHeader->dsi1[0]==0xFFFFFFFF && ndsHeader->dsi1[1]==0xFFFFFFFF
|
||||
&& ndsHeader->dsi1[2]==0xFFFFFFFF && ndsHeader->dsi1[3]==0xFFFFFFFF)
|
||||
{
|
||||
toncset((u8*)headerData+0x200, 0, 0xE00); // Clear out FFs
|
||||
}
|
||||
tonccpy(ndsHeader, headerData, sizeof(sNDSHeaderExt));
|
||||
}
|
||||
|
||||
// Check header CRC
|
||||
if (ndsHeader->headerCRC16 != swiCRC16(0xFFFF, (void*)ndsHeader, 0x15E)) {
|
||||
return ERR_HEAD_CRC;
|
||||
}
|
||||
|
||||
/*
|
||||
// Check logo CRC
|
||||
if (ndsHeader->logoCRC16 != 0xCF56) {
|
||||
return ERR_LOGO_CRC;
|
||||
}
|
||||
*/
|
||||
|
||||
// Initialise blowfish encryption for KEY1 commands and decrypting the secure area
|
||||
gameCode = (GameCode*)ndsHeader->gameCode;
|
||||
init_keycode (gameCode->key, 2, 8, 0);
|
||||
|
||||
// Port 40001A4h setting for normal reads (command B7)
|
||||
portFlags = ndsHeader->cardControl13 & ~CARD_BLK_SIZE(7);
|
||||
// Port 40001A4h setting for KEY1 commands (usually 001808F8h)
|
||||
portFlagsKey1 = CARD_ACTIVATE | CARD_nRESET | (ndsHeader->cardControl13 & (CARD_WR|CARD_CLK_SLOW)) |
|
||||
((ndsHeader->cardControlBF & (CARD_CLK_SLOW|CARD_DELAY1(0x1FFF))) + ((ndsHeader->cardControlBF & CARD_DELAY2(0x3F)) >> 16));
|
||||
|
||||
// Adjust card transfer method depending on the most significant bit of the chip ID
|
||||
if (!normalChip) {
|
||||
portFlagsKey1 |= CARD_SEC_LARGE;
|
||||
}
|
||||
|
||||
// 3Ciiijjj xkkkkkxx - Activate KEY1 Encryption Mode
|
||||
initKey1Encryption (cmdData, 0);
|
||||
cardPolledTransfer((ndsHeader->cardControl13 & (CARD_WR|CARD_nRESET|CARD_CLK_SLOW)) | CARD_ACTIVATE, NULL, 0, cmdData);
|
||||
|
||||
// 4llllmmm nnnkkkkk - Activate KEY2 Encryption Mode
|
||||
createEncryptedCommand (CARD_CMD_ACTIVATE_SEC, cmdData, 0);
|
||||
|
||||
if (normalChip) {
|
||||
cardPolledTransfer(portFlagsKey1, NULL, 0, cmdData);
|
||||
cardDelay(ndsHeader->readTimeout);
|
||||
}
|
||||
cardPolledTransfer(portFlagsKey1, NULL, 0, cmdData);
|
||||
|
||||
// Set the KEY2 encryption registers
|
||||
REG_ROMCTRL = 0;
|
||||
REG_CARD_1B0 = cardSeedBytes[ndsHeader->deviceType & 0x07] | (key1data.nnn << 15) | (key1data.mmm << 27) | 0x6000;
|
||||
REG_CARD_1B4 = 0x879b9b05;
|
||||
REG_CARD_1B8 = key1data.mmm >> 5;
|
||||
REG_CARD_1BA = 0x5c;
|
||||
REG_ROMCTRL = CARD_nRESET | CARD_SEC_SEED | CARD_SEC_EN | CARD_SEC_DAT;
|
||||
|
||||
// Update the DS card flags to suit KEY2 encryption
|
||||
portFlagsKey1 |= CARD_SEC_EN | CARD_SEC_DAT;
|
||||
|
||||
// 1lllliii jjjkkkkk - 2nd Get ROM Chip ID / Get KEY2 Stream
|
||||
createEncryptedCommand (CARD_CMD_SECURE_CHIPID, cmdData, 0);
|
||||
|
||||
if (normalChip) {
|
||||
cardPolledTransfer(portFlagsKey1, NULL, 0, cmdData);
|
||||
cardDelay(ndsHeader->readTimeout);
|
||||
}
|
||||
cardPolledTransfer(portFlagsKey1 | CARD_BLK_SIZE(7), NULL, 0, cmdData);
|
||||
|
||||
// 2bbbbiii jjjkkkkk - Get Secure Area Block
|
||||
portFlagsSecRead = (ndsHeader->cardControlBF & (CARD_CLK_SLOW|CARD_DELAY1(0x1FFF)|CARD_DELAY2(0x3F)))
|
||||
| CARD_ACTIVATE | CARD_nRESET | CARD_SEC_EN | CARD_SEC_DAT;
|
||||
|
||||
int secureAreaOffset = 0;
|
||||
for (secureBlockNumber = 4; secureBlockNumber < 8; secureBlockNumber++) {
|
||||
createEncryptedCommand (CARD_CMD_SECURE_READ, cmdData, secureBlockNumber);
|
||||
|
||||
if (normalChip) {
|
||||
cardPolledTransfer(portFlagsSecRead, NULL, 0, cmdData);
|
||||
cardDelay(ndsHeader->readTimeout);
|
||||
for (i = 8; i > 0; i--) {
|
||||
cardPolledTransfer(portFlagsSecRead | CARD_BLK_SIZE(1), secureArea + secureAreaOffset, 0x200, cmdData);
|
||||
secureAreaOffset += 0x200/sizeof(u32);
|
||||
}
|
||||
} else {
|
||||
cardPolledTransfer(portFlagsSecRead | CARD_BLK_SIZE(4) | CARD_SEC_LARGE, secureArea + secureAreaOffset, 0x1000, cmdData);
|
||||
secureAreaOffset += 0x1000/sizeof(u32);
|
||||
}
|
||||
}
|
||||
|
||||
// Alllliii jjjkkkkk - Enter Main Data Mode
|
||||
createEncryptedCommand (CARD_CMD_DATA_MODE, cmdData, 0);
|
||||
|
||||
if (normalChip) {
|
||||
cardPolledTransfer(portFlagsKey1, NULL, 0, cmdData);
|
||||
cardDelay(ndsHeader->readTimeout);
|
||||
}
|
||||
cardPolledTransfer(portFlagsKey1, NULL, 0, cmdData);
|
||||
|
||||
//CycloDS doesn't like the dsi secure area being decrypted
|
||||
if((ndsHeader->arm9romOffset != 0x4000) || secureArea[0] || secureArea[1])
|
||||
{
|
||||
decryptSecureArea (gameCode->key, secureArea, 0);
|
||||
}
|
||||
|
||||
if (secureArea[0] == 0x72636e65 /*'encr'*/ && secureArea[1] == 0x6a624f79 /*'yObj'*/) {
|
||||
// Secure area exists, so just clear the tag
|
||||
secureArea[0] = 0xe7ffdeff;
|
||||
secureArea[1] = 0xe7ffdeff;
|
||||
} else {
|
||||
//return normalChip ? ERR_SEC_NORM : ERR_SEC_OTHR;
|
||||
}
|
||||
|
||||
// Set NAND card section location variables
|
||||
if (nandChip) {
|
||||
if(ndsHeader->nandRomEnd != 0) {
|
||||
// TWL cards (Face Training) multiply by 0x80000 instead of 0x20000
|
||||
cardNandRomEnd = ndsHeader->nandRomEnd * (ndsHeader->unitCode == 0 ? 0x20000 : 0x80000);
|
||||
cardNandRwStart = ndsHeader->nandRwStart * (ndsHeader->unitCode == 0 ? 0x20000 : 0x80000);
|
||||
} else {
|
||||
// Jam with the Band (J) (大合奏!バンドブラザーズ) doesn't have the RW section in the header
|
||||
cardNandRomEnd = 0x7200000;
|
||||
cardNandRwStart = 0x7200000;
|
||||
}
|
||||
}
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
int CardInit ()
|
||||
{
|
||||
if (!isDSiMode())return ERR_NONE;
|
||||
if (!(REG_SCFG_EXT & BIT(31)))return ERR_NONE;
|
||||
|
||||
sNDSHeaderExt* ndsHeader;
|
||||
u32 portFlagsKey1, portFlagsSecRead;
|
||||
normalChip = false; // As defined by GBAtek, normal chip secure area and header are accessed in blocks of 0x200, other chip in blocks of 0x1000
|
||||
nandChip = false;
|
||||
nandSection = -1;
|
||||
int secureBlockNumber;
|
||||
int i;
|
||||
u8 cmdData[8] __attribute__ ((aligned));
|
||||
GameCode* gameCode;
|
||||
|
||||
twlBlowfish = false;
|
||||
|
||||
sysSetCardOwner (BUS_OWNER_ARM9); // Allow arm9 to access NDS cart
|
||||
|
||||
// Reset card slot
|
||||
if(REG_SCFG_MC != 0x11){
|
||||
disableSlot1();
|
||||
for(i = 0; i < 30; i++) { swiWaitForVBlank(); }
|
||||
}
|
||||
enableSlot1();
|
||||
for(i = 0; i < 15; i++) { swiWaitForVBlank(); }
|
||||
// Dummy command sent after card reset
|
||||
cardParamCommand (CARD_CMD_DUMMY, 0, CARD_ACTIVATE | CARD_nRESET | CARD_CLK_SLOW | CARD_BLK_SIZE(1) | CARD_DELAY1(0x1FFF) | CARD_DELAY2(0x3F), NULL, 0);
|
||||
|
||||
|
||||
REG_ROMCTRL=0;
|
||||
REG_AUXSPICNT=0;
|
||||
//ioDelay2(167550);
|
||||
for(i = 0; i < 25; i++) { swiWaitForVBlank(); }
|
||||
REG_AUXSPICNT=CARD_CR1_ENABLE|CARD_CR1_IRQ;
|
||||
REG_ROMCTRL=CARD_nRESET|CARD_SEC_SEED;
|
||||
while(REG_ROMCTRL&CARD_BUSY) ;
|
||||
cardReset();
|
||||
while(REG_ROMCTRL&CARD_BUSY) ;
|
||||
|
||||
toncset(headerData, 0, 0x1000);
|
||||
|
||||
iCardId=cardReadID(CARD_CLK_SLOW);
|
||||
while(REG_ROMCTRL & CARD_BUSY);
|
||||
|
||||
normalChip = (iCardId & BIT(31)) != 0; // ROM chip ID MSB
|
||||
nandChip = (iCardId & BIT(27)) != 0; // Card has a NAND chip
|
||||
|
||||
// Read the header
|
||||
cardParamCommand (CARD_CMD_HEADER_READ, 0,
|
||||
CARD_ACTIVATE | CARD_nRESET | CARD_CLK_SLOW | CARD_BLK_SIZE(1) | CARD_DELAY1(0x1FFF) | CARD_DELAY2(0x3F),
|
||||
(void*)headerData, 0x200/sizeof(u32));
|
||||
|
||||
tonccpy(ndsHeader, headerData, 0x200);
|
||||
|
||||
if ((ndsHeader->unitCode != 0) || (ndsHeader->dsi_flags != 0))
|
||||
{
|
||||
// Extended header found
|
||||
if(normalChip) {
|
||||
for(int i = 0; i < 8; i++) {
|
||||
cardParamCommand (CARD_CMD_HEADER_READ, i * 0x200,
|
||||
CARD_ACTIVATE | CARD_nRESET | CARD_CLK_SLOW | CARD_BLK_SIZE(1) | CARD_DELAY1(0x1FFF) | CARD_DELAY2(0x3F),
|
||||
headerData + i * 0x200 / sizeof(u32), 0x200/sizeof(u32));
|
||||
}
|
||||
} else {
|
||||
cardParamCommand (CARD_CMD_HEADER_READ, 0,
|
||||
CARD_ACTIVATE | CARD_nRESET | CARD_CLK_SLOW | CARD_BLK_SIZE(4) | CARD_DELAY1(0x1FFF) | CARD_DELAY2(0x3F),
|
||||
(void*)headerData, 0x1000/sizeof(u32));
|
||||
}
|
||||
if (ndsHeader->dsi1[0]==0xFFFFFFFF && ndsHeader->dsi1[1]==0xFFFFFFFF
|
||||
&& ndsHeader->dsi1[2]==0xFFFFFFFF && ndsHeader->dsi1[3]==0xFFFFFFFF)
|
||||
{
|
||||
toncset((u8*)headerData+0x200, 0, 0xE00); // Clear out FFs
|
||||
}
|
||||
tonccpy(ndsHeader, headerData, sizeof(sNDSHeaderExt));
|
||||
}
|
||||
|
||||
// Check header CRC
|
||||
if (ndsHeader->headerCRC16 != swiCRC16(0xFFFF, (void*)ndsHeader, 0x15E)) {
|
||||
return ERR_HEAD_CRC;
|
||||
}
|
||||
|
||||
/*
|
||||
// Check logo CRC
|
||||
if (ndsHeader->logoCRC16 != 0xCF56) {
|
||||
return ERR_LOGO_CRC;
|
||||
}
|
||||
*/
|
||||
|
||||
// Initialise blowfish encryption for KEY1 commands and decrypting the secure area
|
||||
gameCode = (GameCode*)ndsHeader->gameCode;
|
||||
init_keycode (gameCode->key, 2, 8, 0);
|
||||
|
||||
// Port 40001A4h setting for normal reads (command B7)
|
||||
portFlags = ndsHeader->cardControl13 & ~CARD_BLK_SIZE(7);
|
||||
// Port 40001A4h setting for KEY1 commands (usually 001808F8h)
|
||||
portFlagsKey1 = CARD_ACTIVATE | CARD_nRESET | (ndsHeader->cardControl13 & (CARD_WR|CARD_CLK_SLOW)) |
|
||||
((ndsHeader->cardControlBF & (CARD_CLK_SLOW|CARD_DELAY1(0x1FFF))) + ((ndsHeader->cardControlBF & CARD_DELAY2(0x3F)) >> 16));
|
||||
|
||||
// Adjust card transfer method depending on the most significant bit of the chip ID
|
||||
if (!normalChip) {
|
||||
portFlagsKey1 |= CARD_SEC_LARGE;
|
||||
}
|
||||
|
||||
// 3Ciiijjj xkkkkkxx - Activate KEY1 Encryption Mode
|
||||
initKey1Encryption (cmdData, 0);
|
||||
cardPolledTransfer((ndsHeader->cardControl13 & (CARD_WR|CARD_nRESET|CARD_CLK_SLOW)) | CARD_ACTIVATE, NULL, 0, cmdData);
|
||||
|
||||
// 4llllmmm nnnkkkkk - Activate KEY2 Encryption Mode
|
||||
createEncryptedCommand (CARD_CMD_ACTIVATE_SEC, cmdData, 0);
|
||||
|
||||
if (normalChip) {
|
||||
cardPolledTransfer(portFlagsKey1, NULL, 0, cmdData);
|
||||
cardDelay(ndsHeader->readTimeout);
|
||||
}
|
||||
cardPolledTransfer(portFlagsKey1, NULL, 0, cmdData);
|
||||
|
||||
// Set the KEY2 encryption registers
|
||||
REG_ROMCTRL = 0;
|
||||
REG_CARD_1B0 = cardSeedBytes[ndsHeader->deviceType & 0x07] | (key1data.nnn << 15) | (key1data.mmm << 27) | 0x6000;
|
||||
REG_CARD_1B4 = 0x879b9b05;
|
||||
REG_CARD_1B8 = key1data.mmm >> 5;
|
||||
REG_CARD_1BA = 0x5c;
|
||||
REG_ROMCTRL = CARD_nRESET | CARD_SEC_SEED | CARD_SEC_EN | CARD_SEC_DAT;
|
||||
|
||||
// Update the DS card flags to suit KEY2 encryption
|
||||
portFlagsKey1 |= CARD_SEC_EN | CARD_SEC_DAT;
|
||||
|
||||
// 1lllliii jjjkkkkk - 2nd Get ROM Chip ID / Get KEY2 Stream
|
||||
createEncryptedCommand (CARD_CMD_SECURE_CHIPID, cmdData, 0);
|
||||
|
||||
if (normalChip) {
|
||||
cardPolledTransfer(portFlagsKey1, NULL, 0, cmdData);
|
||||
cardDelay(ndsHeader->readTimeout);
|
||||
}
|
||||
cardPolledTransfer(portFlagsKey1 | CARD_BLK_SIZE(7), NULL, 0, cmdData);
|
||||
|
||||
// 2bbbbiii jjjkkkkk - Get Secure Area Block
|
||||
portFlagsSecRead = (ndsHeader->cardControlBF & (CARD_CLK_SLOW|CARD_DELAY1(0x1FFF)|CARD_DELAY2(0x3F)))
|
||||
| CARD_ACTIVATE | CARD_nRESET | CARD_SEC_EN | CARD_SEC_DAT;
|
||||
|
||||
int secureAreaOffset = 0;
|
||||
for (secureBlockNumber = 4; secureBlockNumber < 8; secureBlockNumber++) {
|
||||
createEncryptedCommand (CARD_CMD_SECURE_READ, cmdData, secureBlockNumber);
|
||||
|
||||
if (normalChip) {
|
||||
cardPolledTransfer(portFlagsSecRead, NULL, 0, cmdData);
|
||||
cardDelay(ndsHeader->readTimeout);
|
||||
for (i = 8; i > 0; i--) {
|
||||
cardPolledTransfer(portFlagsSecRead | CARD_BLK_SIZE(1), secureArea + secureAreaOffset, 0x200, cmdData);
|
||||
secureAreaOffset += 0x200/sizeof(u32);
|
||||
}
|
||||
} else {
|
||||
cardPolledTransfer(portFlagsSecRead | CARD_BLK_SIZE(4) | CARD_SEC_LARGE, secureArea + secureAreaOffset, 0x1000, cmdData);
|
||||
secureAreaOffset += 0x1000/sizeof(u32);
|
||||
}
|
||||
}
|
||||
|
||||
// Alllliii jjjkkkkk - Enter Main Data Mode
|
||||
createEncryptedCommand (CARD_CMD_DATA_MODE, cmdData, 0);
|
||||
|
||||
if (normalChip) {
|
||||
cardPolledTransfer(portFlagsKey1, NULL, 0, cmdData);
|
||||
cardDelay(ndsHeader->readTimeout);
|
||||
}
|
||||
cardPolledTransfer(portFlagsKey1, NULL, 0, cmdData);
|
||||
|
||||
//CycloDS doesn't like the dsi secure area being decrypted
|
||||
if((ndsHeader->arm9romOffset != 0x4000) || secureArea[0] || secureArea[1])
|
||||
{
|
||||
decryptSecureArea (gameCode->key, secureArea, 0);
|
||||
}
|
||||
|
||||
if (secureArea[0] == 0x72636e65 /*'encr'*/ && secureArea[1] == 0x6a624f79 /*'yObj'*/) {
|
||||
// Secure area exists, so just clear the tag
|
||||
secureArea[0] = 0xe7ffdeff;
|
||||
secureArea[1] = 0xe7ffdeff;
|
||||
} else {
|
||||
//return normalChip ? ERR_SEC_NORM : ERR_SEC_OTHR;
|
||||
}
|
||||
|
||||
// Set NAND card section location variables
|
||||
if (nandChip) {
|
||||
if(ndsHeader->nandRomEnd != 0) {
|
||||
// TWL cards (Face Training) multiply by 0x80000 instead of 0x20000
|
||||
cardNandRomEnd = ndsHeader->nandRomEnd * (ndsHeader->unitCode == 0 ? 0x20000 : 0x80000);
|
||||
cardNandRwStart = ndsHeader->nandRwStart * (ndsHeader->unitCode == 0 ? 0x20000 : 0x80000);
|
||||
} else {
|
||||
// Jam with the Band (J) (大合奏!バンドブラザーズ) doesn't have the RW section in the header
|
||||
cardNandRomEnd = 0x7200000;
|
||||
cardNandRwStart = 0x7200000;
|
||||
}
|
||||
}
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
|
||||
u32 cardGetId() {
|
||||
return iCardId;
|
||||
}
|
||||
|
||||
void cardRead (u32 src, void* dest, bool nandSave)
|
||||
{
|
||||
sNDSHeaderExt* ndsHeader = (sNDSHeaderExt*)headerData;
|
||||
|
||||
if (src >= 0 && src < 0x1000) {
|
||||
// Read header
|
||||
tonccpy (dest, (u8*)headerData + src, 0x200);
|
||||
return;
|
||||
} else if (src < CARD_SECURE_AREA_OFFSET) {
|
||||
toncset (dest, 0, 0x200);
|
||||
return;
|
||||
} else if (src < CARD_DATA_OFFSET) {
|
||||
// Read data from secure area
|
||||
tonccpy (dest, (u8*)secureArea + src - CARD_SECURE_AREA_OFFSET, 0x200);
|
||||
return;
|
||||
} else if ((ndsHeader->unitCode != 0) && (src >= ndsHeader->arm9iromOffset) && (src < ndsHeader->arm9iromOffset+CARD_SECURE_AREA_SIZE)) {
|
||||
// Read data from secure area
|
||||
tonccpy (dest, (u8*)secureArea + src - ndsHeader->arm9iromOffset, 0x200);
|
||||
return;
|
||||
}
|
||||
|
||||
if (nandChip) {
|
||||
if ((src < cardNandRomEnd || !nandSave) && nandSection != -1) {
|
||||
cardParamCommand(CARD_CMD_NAND_ROM_MODE, 0, portFlags | CARD_ACTIVATE | CARD_nRESET, NULL, 0);
|
||||
nandSection = -1;
|
||||
} else if (src >= cardNandRwStart && nandSection != (src - cardNandRwStart) / (128 << 10) && nandSave) {
|
||||
if(nandSection != -1) // Need to switch back to ROM mode before switching to another RW section
|
||||
cardParamCommand(CARD_CMD_NAND_ROM_MODE, 0, portFlags | CARD_ACTIVATE | CARD_nRESET, NULL, 0);
|
||||
cardParamCommand(CARD_CMD_NAND_RW_MODE, src, portFlags | CARD_ACTIVATE | CARD_nRESET, NULL, 0);
|
||||
nandSection = (src - cardNandRwStart) / (128 << 10);
|
||||
}
|
||||
}
|
||||
|
||||
cardParamCommand (CARD_CMD_DATA_READ, src,
|
||||
portFlags | CARD_ACTIVATE | CARD_nRESET | CARD_BLK_SIZE(1),
|
||||
dest, 0x200/sizeof(u32));
|
||||
|
||||
if (src > ndsHeader->romSize && !(nandSave && src >= cardNandRwStart)) {
|
||||
switchToTwlBlowfish(ndsHeader);
|
||||
}
|
||||
}
|
||||
|
||||
// src must be a 0x800 byte array
|
||||
void cardWriteNand (void* src, u32 dest)
|
||||
{
|
||||
if (dest < cardNandRwStart || !nandChip)
|
||||
return;
|
||||
|
||||
if (nandSection != (dest - cardNandRwStart) / (128 << 10)) {
|
||||
if(nandSection != -1) // Need to switch back to ROM mode before switching to another RW section
|
||||
cardParamCommand(CARD_CMD_NAND_ROM_MODE, 0, portFlags | CARD_ACTIVATE | CARD_nRESET, NULL, 0);
|
||||
cardParamCommand(CARD_CMD_NAND_RW_MODE, dest, portFlags | CARD_ACTIVATE | CARD_nRESET, NULL, 0);
|
||||
nandSection = (dest - cardNandRwStart) / (128 << 10);
|
||||
}
|
||||
|
||||
cardParamCommand(CARD_CMD_NAND_WRITE_ENABLE, 0, portFlags | CARD_ACTIVATE | CARD_nRESET, NULL, 0);
|
||||
|
||||
const u8 cmdData[8] = {0, 0, 0, dest, dest >> 8, dest >> 16, dest >> 24, CARD_CMD_NAND_WRITE_BUFFER};
|
||||
for (int i = 0; i < 4; i++) {
|
||||
cardPolledTransferWrite(portFlags | CARD_ACTIVATE | CARD_WR | CARD_nRESET | CARD_BLK_SIZE(1), src + (i * 0x200), 0x200 / sizeof(u32), cmdData);
|
||||
}
|
||||
|
||||
cardParamCommand(CARD_CMD_NAND_COMMIT_BUFFER, 0, portFlags | CARD_ACTIVATE | CARD_nRESET, NULL, 0);
|
||||
|
||||
u32 status;
|
||||
do {
|
||||
cardParamCommand(CARD_CMD_NAND_READ_STATUS, 0, portFlags | CARD_ACTIVATE | CARD_nRESET | CARD_BLK_SIZE(7), &status, 1);
|
||||
} while((status & BIT(5)) == 0);
|
||||
|
||||
cardParamCommand(CARD_CMD_NAND_DISCARD_BUFFER, 0, portFlags | CARD_ACTIVATE | CARD_nRESET, NULL, 0);
|
||||
}
|
56
arm9/source/read_card.h
Normal file
56
arm9/source/read_card.h
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
NitroHax -- Cheat tool for the Nintendo DS
|
||||
Copyright (C) 2008 Michael "Chishm" Chisholm
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
#ifndef READ_CARD_H
|
||||
#define READ_CARD_H
|
||||
|
||||
#include <nds/ndstypes.h>
|
||||
#include <nds/memory.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "ndsheaderbanner.h"
|
||||
|
||||
#define CARD_NDS_HEADER_SIZE (0x200)
|
||||
#define CARD_SECURE_AREA_OFFSET (0x4000)
|
||||
#define CARD_SECURE_AREA_SIZE (0x4000)
|
||||
#define CARD_DATA_OFFSET (0x8000)
|
||||
#define CARD_DATA_BLOCK_SIZE (0x200)
|
||||
#define MODC_AREA_SIZE 0x4000
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern u32 cardNandRomEnd;
|
||||
extern u32 cardNandRwStart;
|
||||
|
||||
int cardInit (sNDSHeaderExt* ndsHeader);
|
||||
int CardInit (void);
|
||||
|
||||
void cardRead (u32 src, void* dest, bool nandSave);
|
||||
|
||||
u32 cardGetId (void);
|
||||
|
||||
void cardWriteNand (void* src, u32 dest);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // READ_CARD_H
|
||||
|
136
arm9/source/tonccpy.c
Normal file
136
arm9/source/tonccpy.c
Normal file
@ -0,0 +1,136 @@
|
||||
#include "tonccpy.h"
|
||||
//# tonccpy.c
|
||||
|
||||
//! VRAM-safe cpy.
|
||||
/*! This version mimics memcpy in functionality, with
|
||||
the benefit of working for VRAM as well. It is also
|
||||
slightly faster than the original memcpy, but faster
|
||||
implementations can be made.
|
||||
\param dst Destination pointer.
|
||||
\param src Source pointer.
|
||||
\param size Fill-length in bytes.
|
||||
\note The pointers and size need not be word-aligned.
|
||||
*/
|
||||
void tonccpy(void *dst, const void *src, uint size)
|
||||
{
|
||||
if(size==0 || dst==0 || src==0)
|
||||
return;
|
||||
|
||||
uint count;
|
||||
u16 *dst16; // hword destination
|
||||
u8 *src8; // byte source
|
||||
|
||||
// Ideal case: copy by 4x words. Leaves tail for later.
|
||||
if( ((u32)src|(u32)dst)%4==0 && size>=4)
|
||||
{
|
||||
u32 *src32= (u32*)src, *dst32= (u32*)dst;
|
||||
|
||||
count= size/4;
|
||||
uint tmp= count&3;
|
||||
count /= 4;
|
||||
|
||||
// Duff's Device, good friend!
|
||||
switch(tmp) {
|
||||
do { *dst32++ = *src32++;
|
||||
case 3: *dst32++ = *src32++;
|
||||
case 2: *dst32++ = *src32++;
|
||||
case 1: *dst32++ = *src32++;
|
||||
case 0: ; } while(count--);
|
||||
}
|
||||
|
||||
// Check for tail
|
||||
size &= 3;
|
||||
if(size == 0)
|
||||
return;
|
||||
|
||||
src8= (u8*)src32;
|
||||
dst16= (u16*)dst32;
|
||||
}
|
||||
else // Unaligned.
|
||||
{
|
||||
uint dstOfs= (u32)dst&1;
|
||||
src8= (u8*)src;
|
||||
dst16= (u16*)(dst-dstOfs);
|
||||
|
||||
// Head: 1 byte.
|
||||
if(dstOfs != 0)
|
||||
{
|
||||
*dst16= (*dst16 & 0xFF) | *src8++<<8;
|
||||
dst16++;
|
||||
if(--size==0)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Unaligned main: copy by 2x byte.
|
||||
count= size/2;
|
||||
while(count--)
|
||||
{
|
||||
*dst16++ = src8[0] | src8[1]<<8;
|
||||
src8 += 2;
|
||||
}
|
||||
|
||||
// Tail: 1 byte.
|
||||
if(size&1)
|
||||
*dst16= (*dst16 &~ 0xFF) | *src8;
|
||||
}
|
||||
//# toncset.c
|
||||
|
||||
//! VRAM-safe memset, internal routine.
|
||||
/*! This version mimics memset in functionality, with
|
||||
the benefit of working for VRAM as well. It is also
|
||||
slightly faster than the original memset.
|
||||
\param dst Destination pointer.
|
||||
\param fill Word to fill with.
|
||||
\param size Fill-length in bytes.
|
||||
\note The \a dst pointer and \a size need not be
|
||||
word-aligned. In the case of unaligned fills, \a fill
|
||||
will be masked off to match the situation.
|
||||
*/
|
||||
void __toncset(void *dst, u32 fill, uint size)
|
||||
{
|
||||
if(size==0 || dst==0)
|
||||
return;
|
||||
|
||||
uint left= (u32)dst&3;
|
||||
u32 *dst32= (u32*)(dst-left);
|
||||
u32 count, mask;
|
||||
|
||||
// Unaligned head.
|
||||
if(left != 0)
|
||||
{
|
||||
// Adjust for very small stint.
|
||||
if(left+size<4)
|
||||
{
|
||||
mask= BIT_MASK(size*8)<<(left*8);
|
||||
*dst32= (*dst32 &~ mask) | (fill & mask);
|
||||
return;
|
||||
}
|
||||
|
||||
mask= BIT_MASK(left*8);
|
||||
*dst32= (*dst32 & mask) | (fill&~mask);
|
||||
dst32++;
|
||||
size -= 4-left;
|
||||
}
|
||||
|
||||
// Main stint.
|
||||
count= size/4;
|
||||
uint tmp= count&3;
|
||||
count /= 4;
|
||||
|
||||
switch(tmp) {
|
||||
do { *dst32++ = fill;
|
||||
case 3: *dst32++ = fill;
|
||||
case 2: *dst32++ = fill;
|
||||
case 1: *dst32++ = fill;
|
||||
case 0: ; } while(count--);
|
||||
}
|
||||
|
||||
// Tail
|
||||
size &= 3;
|
||||
if(size)
|
||||
{
|
||||
mask= BIT_MASK(size*8);
|
||||
*dst32= (*dst32 &~ mask) | (fill & mask);
|
||||
}
|
||||
}
|
43
arm9/source/tonccpy.h
Normal file
43
arm9/source/tonccpy.h
Normal file
@ -0,0 +1,43 @@
|
||||
//# Stuff you may not have yet.
|
||||
|
||||
#ifndef TONCCPY_H
|
||||
#define TONCCPY_H
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <nds/ndstypes.h>
|
||||
|
||||
typedef unsigned int uint;
|
||||
#define BIT_MASK(len) ( (1<<(len))-1 )
|
||||
static inline u32 quad8(u16 x) { x |= x<<8; return x | x<<16; }
|
||||
|
||||
|
||||
//# Declarations and inlines.
|
||||
|
||||
void tonccpy(void *dst, const void *src, uint size);
|
||||
|
||||
void __toncset(void *dst, u32 fill, uint size);
|
||||
static inline void toncset(void *dst, u8 src, uint size);
|
||||
static inline void toncset16(void *dst, u16 src, uint size);
|
||||
static inline void toncset32(void *dst, u32 src, uint size);
|
||||
|
||||
|
||||
//! VRAM-safe memset, byte version. Size in bytes.
|
||||
static inline void toncset(void *dst, u8 src, uint size)
|
||||
{ __toncset(dst, quad8(src), size); }
|
||||
|
||||
//! VRAM-safe memset, halfword version. Size in hwords.
|
||||
static inline void toncset16(void *dst, u16 src, uint size)
|
||||
{ __toncset(dst, src|src<<16, size*2); }
|
||||
|
||||
//! VRAM-safe memset, word version. Size in words.
|
||||
static inline void toncset32(void *dst, u32 src, uint size)
|
||||
{ __toncset(dst, src, size*4); }
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
@ -31,6 +31,8 @@
|
||||
#include "font.h"
|
||||
#include "bgtop.h"
|
||||
#include "bgsub.h"
|
||||
#include "bgtopTWL.h"
|
||||
#include "bgsubTWL.h"
|
||||
#include "scrollbar.h"
|
||||
#include "cursor.h"
|
||||
#include "textbox.h"
|
||||
@ -135,10 +137,17 @@ UserInterface::UserInterface (void)
|
||||
REG_BG2CNT_SUB = BG_MAP_BASE(4) | BG_COLOR_16 | BG_TILE_BASE(6) | BG_PRIORITY(0);
|
||||
|
||||
// Set up background image
|
||||
swiDecompressLZSSVram ((void*)bgtopTiles, (void*)CHAR_BASE_BLOCK(2), 0, &decompressBiosCallback);
|
||||
swiDecompressLZSSVram ((void*)bgsubTiles, (void*)CHAR_BASE_BLOCK_SUB(2), 0, &decompressBiosCallback);
|
||||
vramcpy (&BG_PALETTE[0], bgtopPal, bgtopPalLen);
|
||||
vramcpy (&BG_PALETTE_SUB[0], bgsubPal, bgsubPalLen);
|
||||
if ((REG_SCFG_EXT & BIT(31))) {
|
||||
swiDecompressLZSSVram ((void*)bgtopTWLTiles, (void*)CHAR_BASE_BLOCK(2), 0, &decompressBiosCallback);
|
||||
swiDecompressLZSSVram ((void*)bgsubTWLTiles, (void*)CHAR_BASE_BLOCK_SUB(2), 0, &decompressBiosCallback);
|
||||
vramcpy (&BG_PALETTE[0], bgtopTWLPal, bgtopTWLPalLen);
|
||||
vramcpy (&BG_PALETTE_SUB[0], bgsubTWLPal, bgsubTWLPalLen);
|
||||
} else {
|
||||
swiDecompressLZSSVram ((void*)bgtopTiles, (void*)CHAR_BASE_BLOCK(2), 0, &decompressBiosCallback);
|
||||
swiDecompressLZSSVram ((void*)bgsubTiles, (void*)CHAR_BASE_BLOCK_SUB(2), 0, &decompressBiosCallback);
|
||||
vramcpy (&BG_PALETTE[0], bgtopPal, bgtopPalLen);
|
||||
vramcpy (&BG_PALETTE_SUB[0], bgsubPal, bgsubPalLen);
|
||||
}
|
||||
u16* bgMapTop = (u16*)SCREEN_BASE_BLOCK(0);
|
||||
u16* bgMapSub = (u16*)SCREEN_BASE_BLOCK_SUB(0);
|
||||
for (int i = 0; i < CONSOLE_SCREEN_WIDTH*CONSOLE_SCREEN_HEIGHT; i++) {
|
||||
|
Loading…
Reference in New Issue
Block a user