From cd59bcdbfbb278942e3c17142af40933369482ff Mon Sep 17 00:00:00 2001 From: kamikawa Date: Wed, 1 Oct 2008 05:03:34 +0000 Subject: [PATCH] =?UTF-8?q?SystemUpdaterRegionSelect=E3=81=AE=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/TwlIPL/trunk@2562 b08762b0-b915-fc4b-9d8c-17b2551a87ff --- .../ARM7.TWL/Makefile | 74 ++ .../ARM7.TWL/armadillo.lsf | 86 ++ .../ARM7.TWL/include/kami_pxi.h | 44 ++ .../ARM7.TWL/src/kami_pxi.c | 262 +++++++ .../ARM7.TWL/src/main.c | 576 ++++++++++++++ .../ARM9.TWL/ARM9-TS.lsf | 57 ++ .../ARM9.TWL/Makefile | 140 ++++ .../ARM9.TWL/include/font.h | 100 +++ .../ARM9.TWL/include/graphics.h | 49 ++ .../ARM9.TWL/include/hw_info.h | 71 ++ .../ARM9.TWL/include/kami_copy_file.h | 44 ++ .../ARM9.TWL/include/kami_font.h | 94 +++ .../ARM9.TWL/include/kami_global.h | 95 +++ .../ARM9.TWL/include/kami_pxi.h | 89 +++ .../ARM9.TWL/include/kami_write_nandfirm.h | 52 ++ .../ARM9.TWL/include/keypad.h | 48 ++ .../ARM9.TWL/main.rsf | 232 ++++++ .../ARM9.TWL/src/fade.c | 77 ++ .../ARM9.TWL/src/font.c | 322 ++++++++ .../ARM9.TWL/src/font_data.c | 734 ++++++++++++++++++ .../ARM9.TWL/src/graphics.c | 292 +++++++ .../ARM9.TWL/src/hw_info.c | 147 ++++ .../ARM9.TWL/src/kami_copy_file.c | 135 ++++ .../ARM9.TWL/src/kami_font.c | 407 ++++++++++ .../ARM9.TWL/src/kami_pxi.c | 370 +++++++++ .../ARM9.TWL/src/kami_write_nandfirm.c | 332 ++++++++ .../ARM9.TWL/src/keypad.c | 85 ++ .../ARM9.TWL/src/main.c | 243 ++++++ .../ARM9.TWL/src/process_cancel.c | 81 ++ .../ARM9.TWL/src/process_check_console.c | 198 +++++ .../ARM9.TWL/src/process_check_log.c | 136 ++++ .../ARM9.TWL/src/process_finish.c | 104 +++ .../ARM9.TWL/src/process_format.c | 124 +++ .../ARM9.TWL/src/process_hwinfo.c | 89 +++ .../ARM9.TWL/src/process_import.c | 321 ++++++++ .../ARM9.TWL/src/process_log.c | 83 ++ .../ARM9.TWL/src/process_nandfirm.c | 124 +++ .../ARM9.TWL/src/process_note.c | 132 ++++ .../ARM9.TWL/src/process_select_region.c | 162 ++++ .../ARM9.TWL/src/process_write_files.c | 136 ++++ .../SystemUpdaterRegionSelect/Makefile | 33 + .../SystemUpdaterRegionSelect/banner/Makefile | 47 ++ .../banner/banner_v3.bsf | Bin 0 -> 852 bytes .../banner/icon/gameIcon.bmp | Bin 0 -> 592 bytes .../common/include/fifo.h | 90 +++ .../data/tbf_ww_s.NFTR | Bin 0 -> 270572 bytes .../SystemUpdaterRegionSelect/readme.txt | 20 + 47 files changed, 7137 insertions(+) create mode 100644 build/systemMenu_tools/SystemUpdaterRegionSelect/ARM7.TWL/Makefile create mode 100644 build/systemMenu_tools/SystemUpdaterRegionSelect/ARM7.TWL/armadillo.lsf create mode 100644 build/systemMenu_tools/SystemUpdaterRegionSelect/ARM7.TWL/include/kami_pxi.h create mode 100644 build/systemMenu_tools/SystemUpdaterRegionSelect/ARM7.TWL/src/kami_pxi.c create mode 100644 build/systemMenu_tools/SystemUpdaterRegionSelect/ARM7.TWL/src/main.c create mode 100644 build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/ARM9-TS.lsf create mode 100644 build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/Makefile create mode 100644 build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/include/font.h create mode 100644 build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/include/graphics.h create mode 100644 build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/include/hw_info.h create mode 100644 build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/include/kami_copy_file.h create mode 100644 build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/include/kami_font.h create mode 100644 build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/include/kami_global.h create mode 100644 build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/include/kami_pxi.h create mode 100644 build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/include/kami_write_nandfirm.h create mode 100644 build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/include/keypad.h create mode 100644 build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/main.rsf create mode 100644 build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/fade.c create mode 100644 build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/font.c create mode 100644 build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/font_data.c create mode 100644 build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/graphics.c create mode 100644 build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/hw_info.c create mode 100644 build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/kami_copy_file.c create mode 100644 build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/kami_font.c create mode 100644 build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/kami_pxi.c create mode 100644 build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/kami_write_nandfirm.c create mode 100644 build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/keypad.c create mode 100644 build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/main.c create mode 100644 build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/process_cancel.c create mode 100644 build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/process_check_console.c create mode 100644 build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/process_check_log.c create mode 100644 build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/process_finish.c create mode 100644 build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/process_format.c create mode 100644 build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/process_hwinfo.c create mode 100644 build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/process_import.c create mode 100644 build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/process_log.c create mode 100644 build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/process_nandfirm.c create mode 100644 build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/process_note.c create mode 100644 build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/process_select_region.c create mode 100644 build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/process_write_files.c create mode 100644 build/systemMenu_tools/SystemUpdaterRegionSelect/Makefile create mode 100644 build/systemMenu_tools/SystemUpdaterRegionSelect/banner/Makefile create mode 100644 build/systemMenu_tools/SystemUpdaterRegionSelect/banner/banner_v3.bsf create mode 100644 build/systemMenu_tools/SystemUpdaterRegionSelect/banner/icon/gameIcon.bmp create mode 100644 build/systemMenu_tools/SystemUpdaterRegionSelect/common/include/fifo.h create mode 100644 build/systemMenu_tools/SystemUpdaterRegionSelect/data/tbf_ww_s.NFTR create mode 100644 build/systemMenu_tools/SystemUpdaterRegionSelect/readme.txt diff --git a/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM7.TWL/Makefile b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM7.TWL/Makefile new file mode 100644 index 00000000..e333b1fc --- /dev/null +++ b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM7.TWL/Makefile @@ -0,0 +1,74 @@ +#! make -f +#---------------------------------------------------------------------------- +# Project: TwlSDK - components - armadillo.TWL +# File: Makefile +# +# Copyright 2008 Nintendo. All rights reserved. +# +# These coded instructions, statements, and computer programs contain +# proprietary information of Nintendo of America Inc. and/or Nintendo +# Company Ltd., and are protected by Federal copyright law. They may +# not be disclosed to third parties or copied or duplicated in any form, +# in whole or in part, without the prior written consent of Nintendo. +# +# $Date:: $ +# $Rev$ +# $Author$ +#---------------------------------------------------------------------------- + +override TARGET_PLATFORM = TWL +override TWL_PROC = ARM7 +override TWL_ARCHGEN = LIMITED +##override TWL_PLATFORM = TS +TWL_NO_STD_PCHDR = True +override TARGET_CODEGEN = ARM + +ifndef TWLSDK_NOCRYPTO +#---------------------------------------------------------------------------- + +SRCS = main.c \ + kami_pxi.c \ + formatter.c + +TARGET_NAME = armadillo + +TARGET_NEF = $(TARGET_NAME).tef +LCFILE_SPEC = $(TARGET_NAME).lsf +LCFILE_TEMPLATE = $(ROOT)/build/components/$(TARGET_NAME).TWL/$(TARGET_NAME).lcf.template +LDRES_TEMPLATE = $(ROOT)/build/components/$(TARGET_NAME).TWL/$(TARGET_NAME).response.template + +CRT0_O = crt0.SCR.TWL.o + +# スタック不足防止の為、インライン展開せずにコンパイルする +CCFLAGS_OPT = -O4 -inline off + +#---------------------------------------------------------------------------- +include $(TWLSDK_ROOT)/build/buildtools/commondefs + +MACRO_FLAGS += -DSDK_ARM7COMP_LTD -DSDK_SEA + +MAKELCF_FLAGS += -DISDBG_LIBS_TWL='$(if $(ISDBG_LIBS_TWL),$(ISDBG_LIBS_TWL),libstubsistd_sp$(TWL_LIBSUFFIX).a)' \ + -DISDBG_LIBS_NITRO='libstubsisd_sp$(TWL_LIBSUFFIX).a' + +LINCLUDES = $(ROOT)/build/libraries/spi/ARM7/include \ + ../common/include \ + ../../common/ARM7/include + +SRCDIR += ../../common/ARM7/src + +LLIBRARIES += libwl_sp$(TWL_LIBSUFFIX).a \ + libsdio_sp$(TWL_LIBSUFFIX).a \ + libathdrv_sp$(TWL_LIBSUFFIX).a \ + libwpa_sp$(TWL_LIBSUFFIX).a \ + +LDEPENDS_NEF = $(TWL_LIBS) $(LLIBRARIES) + +do-build: $(TARGETS) + +#---------------------------------------------------------------------------- +include $(TWLSDK_ROOT)/build/buildtools/modulerules + +#---------------------------------------------------------------------------- +endif #ifndef TWLSDK_NOCRYPTO + +#===== End of Makefile ===== diff --git a/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM7.TWL/armadillo.lsf b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM7.TWL/armadillo.lsf new file mode 100644 index 00000000..177f5206 --- /dev/null +++ b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM7.TWL/armadillo.lsf @@ -0,0 +1,86 @@ +#---------------------------------------------------------------------------- +# Project: TwlSDK - components - armadillo.TWL +# File: armadillo.lsf +# +# Copyright 2008 Nintendo. All rights reserved. +# +# These coded insructions, statements, and computer programs contain +# proprietary information of Nintendo of America Inc. and/or Nintendo +# Company Ltd., and are protected by Federal copyright law. They may +# not be disclosed to third parties or copied or duplicated in any form, +# in whole or in part, without the prior written consent of Nintendo. +# +# $Date:: $ +# $Rev$ +# $Author$ +#---------------------------------------------------------------------------- +# +# Nitro LCF SPEC FILE +# +#-------- +Static $(TARGET_NAME) +{ + Address 0x02380000 + StackSize 1024 1024 + + Library $(CRT0_O) +} + +#-------- +Ltdautoload SCRWRAM +{ + Address 0x03740000 + + Library libsubpsyscall.a + Library libsyscall_sp.twl.a + Library $(CW_LIBS) + Library $(ISDBG_LIBS_TWL) + Library $(ISDBG_LIBS_NITRO) + + Object * (.etable) + Object $(OBJDIR)/main.o + Object $(OBJDIR)/kami_pxi.o + Object $(OBJDIR)/formatter.o + + Library libsea_sp$(LIBSUFFIX).a + Library libcrypto_sp$(LIBSUFFIX).a + + Library libos_sp$(LIBSUFFIX).a + Library libmi_sp$(LIBSUFFIX).a + Library libstd_sp$(LIBSUFFIX).a + Library libmath_sp$(LIBSUFFIX).a + Library libpxi_sp$(LIBSUFFIX).a + Library libexi_sp$(LIBSUFFIX).a + Library libi2c_sp$(LIBSUFFIX).a + Library libsdio_sp$(LIBSUFFIX).a + Library libpad_sp$(LIBSUFFIX).a + Library libscfg_sp$(LIBSUFFIX).a + Library libmcu_sp$(LIBSUFFIX).a + Library libcdc_sp$(LIBSUFFIX).a + Library libsnd_sp$(LIBSUFFIX).a + Library libsndex_sp$(LIBSUFFIX).a + Library libspi_sp$(LIBSUFFIX).a + Library libpm_sp$(LIBSUFFIX).a + Library libtp_sp$(LIBSUFFIX).a + Library libtpex_sp$(LIBSUFFIX).a + Library libmic_sp$(LIBSUFFIX).a + Library libmicex_sp$(LIBSUFFIX).a + Library libnvram_sp$(LIBSUFFIX).a + Library librtc_sp$(LIBSUFFIX).a + Library libfatfs_sp$(LIBSUFFIX).a +# Library libwm_sp$(LIBSUFFIX).a +# Library libnwm_sp$(LIBSUFFIX).a + Library libwvr_sp$(LIBSUFFIX).a + Library libwl_sp$(LIBSUFFIX).a + Library libwpa_sp$(LIBSUFFIX).a + Library libathdrv_sp$(LIBSUFFIX).a + Library libfs_sp$(LIBSUFFIX).a + Library libcard_sp$(LIBSUFFIX).a + Library libcamera_sp$(LIBSUFFIX).a + + Object * (.wram) + Object * (.ltdwram) + Object * (.rsvwram) + Object * (.main) + Object * (.ltdmain) +} diff --git a/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM7.TWL/include/kami_pxi.h b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM7.TWL/include/kami_pxi.h new file mode 100644 index 00000000..cbce8090 --- /dev/null +++ b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM7.TWL/include/kami_pxi.h @@ -0,0 +1,44 @@ +/*---------------------------------------------------------------------------* + Project: TwlSDK - NandInitializer + File: kami_pxi.h + + Copyright 2008 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + $Date:: $ + $Rev$ + $Author$ + *---------------------------------------------------------------------------*/ + +#ifndef TWL_CAMERA_TEST_CAMERATEST_H_ +#define TWL_CAMERA_TEST_CAMERATEST_H_ + +/*---------------------------------------------------------------------------* + 定数定義 + *---------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*===========================================================================*/ + +void KamiPxiInit( void ); + +/*===========================================================================*/ + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* TWL_CAMERA_TEST_CAMERATEST_H_ */ + +/*---------------------------------------------------------------------------* + End of file + *---------------------------------------------------------------------------*/ diff --git a/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM7.TWL/src/kami_pxi.c b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM7.TWL/src/kami_pxi.c new file mode 100644 index 00000000..c3caa3f1 --- /dev/null +++ b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM7.TWL/src/kami_pxi.c @@ -0,0 +1,262 @@ +/*---------------------------------------------------------------------------* + Project: TwlSDK - NandInitializer + File: kami_pxi.c + + Copyright 2008 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + $Date:: $ + $Rev$ + $Author$ + *---------------------------------------------------------------------------*/ + +#include +#include +#include "kami_pxi.h" +#include "fifo.h" +#include "twl/cdc.h" +#include "formatter.h" +#include +#include +#include +#include +#include + +typedef unsigned char byte; /* Don't change */ +typedef unsigned short word; /* Don't change */ +typedef unsigned long dword; /* Don't change */ +#define BOOLEAN int + +extern BOOL FATFSi_nandRtfsIo( int driveno, dword block, void* buffer, word count, BOOLEAN reading); +extern BOOL sdmcFormatNandLog( BOOL verify_flag); + +/*---------------------------------------------------------------------------* + 定数定義 + *---------------------------------------------------------------------------*/ +#define KAMITEST_MESSAGE_ARRAY_MAX 4 // スレッド同期用メッセージキューのサイズ +#define KAMITEST_THREAD_STACK_SIZE 2048 // スレッドのスタックサイズ + +#define KAMITEST_THREAD_PRIORITY 6 + +// アライメント調整してコピーする +#define KAMI_UNPACK_U16(d, s) \ + (*(d) = (u16)((((u8*)s)[0] << 0) | (((u8*)s)[1] << 8))) +#define KAMI_UNPACK_U32(d, s) \ + (*(d) = (u32)((((u8*)s)[0] << 0) | (((u8*)s)[1] << 8) | (((u8*)s)[2] << 16) | (((u8*)s)[3] << 24))) + +/*---------------------------------------------------------------------------* + 型定義 + *---------------------------------------------------------------------------*/ +typedef struct KamiWork +{ + BOOL result; + u32 total; + u32 current; + KamiCommand command; + u8 data[KAMITEST_PXI_DATA_SIZE_MAX]; // 後続データ格納用 + + OSMessageQueue msgQ; // スレッド同期用メッセージキュー + OSMessage msgArray[KAMITEST_MESSAGE_ARRAY_MAX]; + // メッセージを格納するバッファ + OSThread thread; // KAMI用スレッド + u64 stack[KAMITEST_THREAD_STACK_SIZE / sizeof(u64)]; + // KAMI用スレッドのスタック +} +KamiWork; + +/*---------------------------------------------------------------------------* + 静的変数定義 + *---------------------------------------------------------------------------*/ +static BOOL kamiInitialized; +static KamiWork kamiWork; + +/*---------------------------------------------------------------------------* + 内部関数定義 + *---------------------------------------------------------------------------*/ +static void KamiPxiCallback(PXIFifoTag tag, u32 data, BOOL err); +static void KamiReturnResult(KamiCommand command, KAMIPxiResult result); +static void KamiReturnResultEx(KamiCommand command, KAMIPxiResult result, u8 size, u8* data); +static void KamiThread(void *arg); + +void KamiPxiInit(void) +{ + if (kamiInitialized) + { + return; + } + kamiInitialized = TRUE; + + PXI_Init(); + PXI_SetFifoRecvCallback(PXI_FIFO_TAG_KAMITEST, KamiPxiCallback); + + OS_InitMessageQueue(&kamiWork.msgQ, kamiWork.msgArray, KAMITEST_MESSAGE_ARRAY_MAX); + OS_CreateThread(&kamiWork.thread, KamiThread, 0, + (void *)(kamiWork.stack + (KAMITEST_THREAD_STACK_SIZE / sizeof(u64))), + KAMITEST_THREAD_STACK_SIZE, KAMITEST_THREAD_PRIORITY); + OS_WakeupThreadDirect(&kamiWork.thread); +} + +static void KamiPxiCallback(PXIFifoTag tag, u32 data, BOOL err) +{ +#pragma unused( tag ) + if (err) + { + return; + } + if (data & KAMITEST_PXI_START_BIT) // 先頭データ + { + kamiWork.total = (u8)((data & KAMITEST_PXI_DATA_NUMS_MASK) >> KAMITEST_PXI_DATA_NUMS_SHIFT); + kamiWork.current = 0; + kamiWork.command = (KamiCommand)((data & KAMITEST_PXI_COMMAND_MASK) >> KAMITEST_PXI_COMMAND_SHIFT); + kamiWork.data[kamiWork.current++] = (u8)((data & KAMITEST_PXI_1ST_DATA_MASK) >> KAMITEST_PXI_1ST_DATA_SHIFT); + } + else // 後続データ + { + kamiWork.data[kamiWork.current++] = (u8)((data & 0xFF0000) >> 16); + kamiWork.data[kamiWork.current++] = (u8)((data & 0x00FF00) >> 8); + kamiWork.data[kamiWork.current++] = (u8)((data & 0x0000FF) >> 0); + } + if (kamiWork.current >= kamiWork.total) + { + switch (kamiWork.command) + { + case KAMI_EXE_FORMAT: + case KAMI_NAND_IO: + case KAMI_CLEAR_NAND_ERRORLOG: + case KAMI_GET_IS_TOOL_TYPE: + if (!OS_SendMessage(&kamiWork.msgQ, NULL, OS_MESSAGE_NOBLOCK)) + { + KamiReturnResult(kamiWork.command, KAMI_PXI_RESULT_FATAL_ERROR); + } + break; + + default: + KamiReturnResult(kamiWork.command, KAMI_PXI_RESULT_INVALID_COMMAND); + } + } +} + +static void KamiReturnResult(KamiCommand command, KAMIPxiResult result) +{ + u32 pxiData = (u32)(KAMITEST_PXI_START_BIT | KAMITEST_PXI_RESULT_BIT | + ((command << KAMITEST_PXI_COMMAND_SHIFT) & KAMITEST_PXI_COMMAND_MASK) | + ((1 << KAMITEST_PXI_DATA_NUMS_SHIFT) & KAMITEST_PXI_DATA_NUMS_MASK) | + ((result << KAMITEST_PXI_1ST_DATA_SHIFT) & KAMITEST_PXI_1ST_DATA_MASK)); + while (0 > PXI_SendWordByFifo(PXI_FIFO_TAG_KAMITEST, pxiData, 0)) + { + } +} + +static void KamiReturnResultEx(KamiCommand command, KAMIPxiResult result, u8 size, u8* data) +{ + u32 pxiData = (u32)(KAMITEST_PXI_START_BIT | KAMITEST_PXI_RESULT_BIT | + ((command << KAMITEST_PXI_COMMAND_SHIFT) & KAMITEST_PXI_COMMAND_MASK) | + (((size+1) << KAMITEST_PXI_DATA_NUMS_SHIFT) & KAMITEST_PXI_DATA_NUMS_MASK) | + ((result << KAMITEST_PXI_1ST_DATA_SHIFT) & KAMITEST_PXI_1ST_DATA_MASK)); + int i; + while (0 > PXI_SendWordByFifo(PXI_FIFO_TAG_KAMITEST, pxiData, 0)) + { + } + for (i = 0; i < size; i+= 3) + { + pxiData = (u32)((data[i] << 16) | (data[i+1] << 8) | data[i+2]); + while (0 > PXI_SendWordByFifo(PXI_FIFO_TAG_KAMITEST, pxiData, 0)) + { + } + } +} + +static void KamiThread(void *arg) +{ +#pragma unused( arg ) + OSMessage msg; + BOOL result; + + while (TRUE) + { + (void)OS_ReceiveMessage(&kamiWork.msgQ, &msg, OS_MESSAGE_BLOCK); + switch (kamiWork.command) + { + case KAMI_EXE_FORMAT: + { + result = ExeFormat((FormatMode)kamiWork.data[0]); // Quick or Full + if (result) + { + KamiReturnResult(kamiWork.command, KAMI_PXI_RESULT_SUCCESS_TRUE); + } + else + { + KamiReturnResult(kamiWork.command, KAMI_PXI_RESULT_SUCCESS_FALSE); + } + } + break; + + case KAMI_NAND_IO: + { + BOOL is_read; + u32 block; + void* buffer; + u32 count; + + is_read = (BOOL)kamiWork.data[0]; + KAMI_UNPACK_U32(&block, &kamiWork.data[1]); + KAMI_UNPACK_U32((u32 *)(&buffer), &kamiWork.data[5]); + KAMI_UNPACK_U32(&count, &kamiWork.data[9]); + + result = FATFSi_nandRtfsIo( 0, block, buffer, (u16)count, is_read ); + if (result) + { + KamiReturnResult(kamiWork.command, KAMI_PXI_RESULT_SUCCESS_TRUE); + } + else + { + KamiReturnResult(kamiWork.command, KAMI_PXI_RESULT_SUCCESS_FALSE); + } + } + break; + + case KAMI_CLEAR_NAND_ERRORLOG: + { + if (sdmcFormatNandLog(TRUE)) + { + KamiReturnResult(kamiWork.command, KAMI_PXI_RESULT_SUCCESS); + } + else + { + KamiReturnResult(kamiWork.command, KAMI_PXI_RESULT_SUCCESS_FALSE); + } + } + break; + + case KAMI_GET_IS_TOOL_TYPE: + { + IsToolType type = IS_TOOL_TYPE_ERROR; + u8 temp = I2C_ReadRegister( I2C_SLAVE_DEBUGGER, 0); + if (temp != (u8)(-1)) // 赤箱、キャプチャ以外は通信エラー + { + if (temp == 0x44) + { + type = IS_TOOL_TYPE_DEBUGGER; + } + else if (temp == 0x43) + { + type = IS_TOOL_TYPE_CAPTURE; + } + } + + KamiReturnResultEx(kamiWork.command, KAMI_PXI_RESULT_SUCCESS, sizeof(IsToolType), (u8*)&type); + } + break; + + default: + KamiReturnResult(kamiWork.command, KAMI_PXI_RESULT_INVALID_COMMAND); + } + } +} + +#include diff --git a/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM7.TWL/src/main.c b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM7.TWL/src/main.c new file mode 100644 index 00000000..a68e6750 --- /dev/null +++ b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM7.TWL/src/main.c @@ -0,0 +1,576 @@ +/*---------------------------------------------------------------------------* + Project: TwlSDK - components - armadillo.TWL + File: main.c + + Copyright 2008 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + $Date:: $ + $Rev$ + $Author$ + *---------------------------------------------------------------------------*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "nvram_sp.h" +#include "kami_pxi.h" + +/*---------------------------------------------------------------------------* + 定数定義 + *---------------------------------------------------------------------------*/ +/* 各スレッド優先度 */ +#define THREAD_PRIO_SPI 2 +#define THREAD_PRIO_MCU 4 // 暫定 +#define THREAD_PRIO_SND 6 +#define THREAD_PRIO_NWM_EVENT 7 +#define THREAD_PRIO_NWM_SDIO 8 +#define THREAD_PRIO_FATFS 8 +#define THREAD_PRIO_NWM_COMMAND 9 +#define THREAD_PRIO_NWM_WPA 10 +#define THREAD_PRIO_HOTSW 11 +#define THREAD_PRIO_AES 12 +#define THREAD_PRIO_SEA 12 +#define THREAD_PRIO_RTC 12 +#define THREAD_PRIO_SNDEX 14 +#define THREAD_PRIO_FS 15 +/* OS_THREAD_LAUNCHER_PRIORITY 16 */ + +/* ROM 内登録エリアの拡張言語コード */ +#define ROMHEADER_FOR_CHINA_BIT 0x80 +#define ROMHEADER_FOR_KOREA_BIT 0x40 + +/* 使用 DMA 番号 */ +#define DMA_NO_FATFS FATFS_DMA_4 // = 0 +#define DMA_NO_NWM 3 + +/* カードチャタリングカウンタ */ +#define CHATTERING_COUNTER 0x1988 // 100ms分 (0x1988 * 15.3us = 100000us) + +/*---------------------------------------------------------------------------* + 内部関数定義 + *---------------------------------------------------------------------------*/ +static void PrintDebugInfo(void); +static OSHeapHandle InitializeAllocateSystem(void); +static void InitializeFatfs(void); + +static void ReadUserInfo(void); +#ifdef NVRAM_CONFIG_DATA_EX_VERSION +static BOOL IsValidConfigEx(void); +static u16 GetRomValidLanguage(void); +static s32 CheckCorrectNCDEx(NVRAMConfigEx* ncdsp); +#else +static s32 CheckCorrectNCD(NVRAMConfig* ncdsp); +#endif +static void VBlankIntr(void); + +/*---------------------------------------------------------------------------* + Name: TwlSpMain + Description: 起動ベクタ。 + Arguments: None. + Returns: None. + *---------------------------------------------------------------------------*/ +void +TwlSpMain(void) +{ + OSHeapHandle heapHandle; + + /* OS 初期化 */ + OS_Init(); + PrintDebugInfo(); + + /* NVRAM からユーザー情報読み出し */ + ReadUserInfo(); + + /* ヒープ領域設定 */ + heapHandle = InitializeAllocateSystem(); + + /* ボタン入力サーチ初期化 */ + (void)PAD_InitXYButton(); + + /* 割込み許可 */ + (void)OS_SetIrqFunction(OS_IE_V_BLANK, VBlankIntr); + (void)OS_EnableIrqMask(OS_IE_V_BLANK); + (void)GX_VBlankIntr(TRUE); + (void)OS_EnableIrq(); + (void)OS_EnableInterrupts(); + + /* 各ライブラリ初期化 */ + AES_Init(THREAD_PRIO_AES); // AES + SEA_Init(THREAD_PRIO_SEA); // SEA + FS_Init(FS_DMA_NOT_USE); // FS for CARD + FS_CreateReadServerThread(THREAD_PRIO_FS); // FS for CARD + InitializeFatfs(); // FAT-FS +// InitializeNwm(heapHandle); // TWL 無線 + MCU_InitIrq(THREAD_PRIO_MCU); // マイコン + CDC_InitLib(); // CODECライブラリ初期化 + CAMERA_Init(); // カメラ + + SND_Init(THREAD_PRIO_SND); // サウンド + SNDEX_Init(THREAD_PRIO_SNDEX); // サウンド拡張 + RTC_Init(THREAD_PRIO_RTC); // RTC +// WVR_Begin(heapHandle); // NITRO 無線 + SPI_Init(THREAD_PRIO_SPI); + +/////////////// +#ifndef NAND_INITIALIZER_LIMITED_MODE + KamiPxiInit(); +#endif +/////////////// + + while (TRUE) + { + OS_Halt(); + + /* ソフトウェアリセット要求は監視しない */ + /* AGB カートリッジの挿抜チェックは行わない */ + /* DS カードの挿抜チェックは行わない */ + } +} + +/*---------------------------------------------------------------------------* + Name: PrintDebugInfo + Description: ARM7 コンポーネントの情報をデバッグ出力する。 + Arguments: None. + Returns: None. + *---------------------------------------------------------------------------*/ +static void +PrintDebugInfo(void) +{ + OS_TPrintf("ARM7: This component is running on TWL.\n"); + OS_TPrintf("ARM7: This component is \"armadillo.TWL\".\n"); +} + +/*---------------------------------------------------------------------------* + Name: InitializeAllocateSystem + Description: メモリ割当てシステムを初期化する。 + Arguments: None. + Returns: OSHeapHandle - WRAM アリーナ上に確保されたヒープのハンドルを返す。 + *---------------------------------------------------------------------------*/ +static OSHeapHandle +InitializeAllocateSystem(void) +{ + OSHeapHandle hh; + void* subLo = (void*)OS_GetWramSubArenaLo(); + void* subHi = (void*)OS_GetWramSubArenaHi(); + void* privLo = (void*)OS_GetWramSubPrivArenaLo(); + void* privHi = (void*)OS_GetWramSubPrivArenaHi(); + + if (((u32)privLo == HW_PRV_WRAM) && ((u32)subHi == HW_PRV_WRAM) && ((u32)subLo < HW_PRV_WRAM)) + { + /* SUB アリーナを SUBPRIV アリーナに吸収 */ + OS_SetWramSubArenaHi(subLo); + OS_SetWramSubPrivArenaLo(subLo); + privLo = subLo; + } + + /* アリーナを 0 クリア */ + MI_CpuClear8(privLo, (u32)privHi - (u32)privLo); + + /* ヒープ作成初期化 */ + privLo = OS_InitAlloc(OS_ARENA_WRAM_SUBPRIV, privLo, privHi, 1); + hh = OS_CreateHeap(OS_ARENA_WRAM_SUBPRIV, privLo, privHi); + if (hh < 0) + { + OS_Panic("ARM7: Failed to create heap.\n"); + } + + /* カレントヒープに設定 */ + (void)OS_SetCurrentHeap(OS_ARENA_WRAM_SUBPRIV, hh); + + /* ヒープサイズの確認 */ + { + u32 heapSize; + + heapSize = (u32)OS_CheckHeap(OS_ARENA_WRAM_SUBPRIV, hh); + + if (heapSize <= 0) + { + OS_Panic("ARM7: Failed to create heap.\n"); + } + OS_TPrintf("ARM7: heap size [%d]\n", heapSize); + } + + return hh; +} + +/*---------------------------------------------------------------------------* + Name: InitializeFatfs + Description: FATFSライブラリを初期化する。FATFS初期化関数内でスレッド休止 + する為、休止中動作するダミーのスレッドを立てる。 + Arguments: None. + Returns: None. + *---------------------------------------------------------------------------*/ +static void +InitializeFatfs(void) +{ + // FATFSライブラリの初期化 + if(!FATFS_Init( FATFS_DMA_4, FATFS_DMA_5, THREAD_PRIO_FATFS)) + { + // do nothing + } +} + +//#ifdef WM_PRECALC_ALLOWEDCHANNEL +//extern u16 WMSP_GetAllowedChannel(u16 bitField); +//#endif +/*---------------------------------------------------------------------------* + Name: ReadUserInfo + + Description: NVRAMからユーザー情報を読み出し、共有領域に展開する。 + ミラーリングされているバッファが両方壊れている場合は、 + 共有領域のユーザー情報格納場所をクリアする。 + + Arguments: None. + + Returns: None. + *---------------------------------------------------------------------------*/ +static void ReadUserInfo(void) +{ + s32 offset; +#ifdef NVRAM_CONFIG_DATA_EX_VERSION + NVRAMConfigEx temp[2]; +#else + NVRAMConfig temp[2]; +#endif + s32 check; + u8 *p = OS_GetSystemWork()->nvramUserInfo; + + // オフセット読み出し +#ifdef NVRAM_CONFIG_CONST_ADDRESS + offset = NVRAM_CONFIG_DATA_ADDRESS_DUMMY; +#else + NVRAM_ReadDataBytes(NVRAM_CONFIG_DATA_OFFSET_ADDRESS, NVRAM_CONFIG_DATA_OFFSET_SIZE, + (u8 *)(&offset)); + offset <<= NVRAM_CONFIG_DATA_OFFSET_SHIFT; +#endif + +#ifdef NVRAM_CONFIG_DATA_EX_VERSION + // ミラーされた2つのデータを読み出し + NVRAM_ReadDataBytes((u32)offset, sizeof(NVRAMConfigEx), (u8 *)(&temp[0])); + NVRAM_ReadDataBytes((u32)(offset + SPI_NVRAM_PAGE_SIZE), sizeof(NVRAMConfigEx), + (u8 *)(&temp[1])); + // 2つの内どちらを使うか判断 + check = CheckCorrectNCDEx(temp); +#else + // ミラーされた2つのデータを読み出し + NVRAM_ReadDataBytes((u32)offset, sizeof(NVRAMConfig), (u8 *)(&temp[0])); + NVRAM_ReadDataBytes((u32)(offset + SPI_NVRAM_PAGE_SIZE), sizeof(NVRAMConfig), (u8 *)(&temp[1])); + // 2つの内どちらを使うか判断 + check = CheckCorrectNCD(temp); +#endif + + if (check >= 3) + { + // アプリケーションの起動を抑制 + MI_CpuFill32(p, 0xffffffff, sizeof(NVRAMConfig)); + } + else if (check) + { + s32 i; + + // ニックネームを補正 + if (temp[check - 1].ncd.owner.nickname.length < NVRAM_CONFIG_NICKNAME_LENGTH) + { + for (i = NVRAM_CONFIG_NICKNAME_LENGTH; + i > temp[check - 1].ncd.owner.nickname.length; i--) + { + temp[check - 1].ncd.owner.nickname.str[i - 1] = 0x0000; + } + } + // コメントを補正 + if (temp[check - 1].ncd.owner.comment.length < NVRAM_CONFIG_COMMENT_LENGTH) + { + for (i = NVRAM_CONFIG_COMMENT_LENGTH; i > temp[check - 1].ncd.owner.comment.length; + i--) + { + temp[check - 1].ncd.owner.comment.str[i - 1] = 0x0000; + } + } + // 共有領域にストア + MI_CpuCopy32(&temp[check - 1], p, sizeof(NVRAMConfig)); + } + else + { + // 共有領域をクリア + MI_CpuClear32(p, sizeof(NVRAMConfig)); + } + + // 無線MACアドレスをユーザー情報の後ろに展開 + { + u8 wMac[6]; + + // NVRAMからMACアドレスを読み出し + NVRAM_ReadDataBytes(NVRAM_CONFIG_MACADDRESS_ADDRESS, 6, wMac); + // 展開先アドレスを計算 + p = (u8 *)((u32)p + ((sizeof(NVRAMConfig) + 3) & ~0x00000003)); + // 共有領域に展開 + MI_CpuCopy8(wMac, p, 6); + } +/* +#ifdef WM_PRECALC_ALLOWEDCHANNEL + // 使用可能チャンネルから使用許可チャンネルを計算 + { + u16 enableChannel; + u16 allowedChannel; + + // 使用可能チャンネルを読み出し + NVRAM_ReadDataBytes(NVRAM_CONFIG_ENABLECHANNEL_ADDRESS, 2, (u8 *)(&enableChannel)); + // 使用許可チャンネルを計算 + allowedChannel = WMSP_GetAllowedChannel((u16)(enableChannel >> 1)); + // 展開先アドレスを計算(MACアドレスの後ろの2バイト) + p = (u8 *)((u32)p + 6); + // 共有領域に展開 + *((u16 *)p) = allowedChannel; + } +#endif +*/ +} + +#ifdef NVRAM_CONFIG_DATA_EX_VERSION +/*---------------------------------------------------------------------------* + Name: IsValidConfigEx + + Description: ユーザー情報が拡張コンフィグに対応しているかどうかを調査する。 + + Arguments: None. + + Returns: BOOL - 拡張ユーザー情報が有効な場合にTRUEを返す。 + 無効である場合はFALSEを返す。 + *---------------------------------------------------------------------------*/ +static BOOL IsValidConfigEx(void) +{ + u8 ipl2_type; + + NVRAM_ReadDataBytes(NVRAM_CONFIG_IPL2_TYPE_ADDRESS, NVRAM_CONFIG_IPL2_TYPE_SIZE, &ipl2_type); + if (ipl2_type == NVRAM_CONFIG_IPL2_TYPE_NORMAL) + { + return FALSE; + } + if (ipl2_type & NVRAM_CONFIG_IPL2_TYPE_EX_MASK) + { + return TRUE; + } + return FALSE; +} + +/*---------------------------------------------------------------------------* + Name: GetRomValidLanguage + + Description: ROM内登録エリアの情報から、拡張言語コードの対応言語ビットマップ + に関する情報を抽出する。 + + Arguments: None. + + Returns: u16 - DSカード、もしくは マルチブートバイナリが対応している + 言語コードのビットマップを返す。DSカードが拡張言語 + コードに対応していない場合は 0 を返す。 + *---------------------------------------------------------------------------*/ +static u16 GetRomValidLanguage(void) +{ + u16 ret = 0x0000; + u8 langBit = OS_GetSystemWork()->rom_header[0x1d]; + + // ROM内登録エリアの拡張言語コードを確認 + if (langBit == ROMHEADER_FOR_CHINA_BIT) + { + // for CHINA + ret |= (0x0001 << NVRAM_CONFIG_LANG_CHINESE); + } + else if (langBit == ROMHEADER_FOR_KOREA_BIT) + { + // for KOREA + ret |= (0x0001 << NVRAM_CONFIG_LANG_HANGUL); + } + return ret; +} + +/*---------------------------------------------------------------------------* + Name: CheckCorrectNCDEx + + Description: ミラーリングされているユーザー情報のどちらを使うべきか判定する。 + + Arguments: nvdsp - 比較するコンフィグデータ2つの配列。 + + Returns: s32 - 0: 両方不適切。 + 1: 配列[ 0 ]が適切。 + 2: 配列[ 1 ]が適切。 + 3: アプリの起動を抑制すべき。 + *---------------------------------------------------------------------------*/ +static s32 CheckCorrectNCDEx(NVRAMConfigEx * ncdsp) +{ + u16 i; + u16 calc_crc; + s32 crc_flag = 0; + u16 saveCount; + + // IPLが拡張言語コードに対応しているか + if (IsValidConfigEx()) + { + // IPLが拡張言語コードに対応している場合 + u16 rom_valid_language = GetRomValidLanguage(); + + for (i = 0; i < 2; i++) + { + calc_crc = SVC_GetCRC16(0xffff, (void *)(&ncdsp[i].ncd), sizeof(NVRAMConfigData)); + if ((ncdsp[i].crc16 == calc_crc) && (ncdsp[i].saveCount < NVRAM_CONFIG_SAVE_COUNT_MAX)) + { + // CRC が正しく saveCount 値が 0x80 未満のデータを正当と判断 + calc_crc = + SVC_GetCRC16(0xffff, (void *)(&ncdsp[i].ncd_ex), sizeof(NVRAMConfigDataEx)); + if ((ncdsp[i].crc16_ex == calc_crc) + && ((0x0001 << ncdsp[i].ncd_ex.language) & + (ncdsp[i].ncd_ex.valid_language_bitmap))) + { + // 拡張データ用 CRC が正しく、設定言語コードが対応言語コードに含まれる場合に正当と判断 + if (rom_valid_language & ncdsp[i].ncd_ex.valid_language_bitmap) + { + // 拡張言語コードで通常言語コードを上書き + ncdsp[i].ncd.option.language = ncdsp[i].ncd_ex.language; + } + if (rom_valid_language & (0x0001 << NVRAM_CONFIG_LANG_CHINESE) & ~ncdsp[i]. + ncd_ex.valid_language_bitmap) + { + // ROM 内登録エリアに"中国語"拡張言語コードが設定されているが、 + // IPL2の対応言語コードに"中国語"拡張言語コードが含まれない場合は起動を抑制 + return 3; + } + crc_flag |= (1 << i); + } + } + } + } + else + { + // IPLが拡張言語コードに対応していない場合 + u16 rom_valid_language = GetRomValidLanguage(); + + if (rom_valid_language & (0x0001 << NVRAM_CONFIG_LANG_CHINESE)) + { + // ROM 内登録エリアに"中国語"拡張言語コードが設定されている場合は起動を抑制 + return 3; + } + for (i = 0; i < 2; i++) + { + calc_crc = SVC_GetCRC16(0xffff, (void *)(&ncdsp[i].ncd), sizeof(NVRAMConfigData)); + if ((ncdsp[i].crc16 == calc_crc) && (ncdsp[i].saveCount < NVRAM_CONFIG_SAVE_COUNT_MAX)) + { + // CRC が正しく saveCount 値が 0x80 未満のデータを正当と判断 + crc_flag |= (1 << i); + } + } + } + + // 正当なデータのうちどのデータが有効かを判定する。 + switch (crc_flag) + { + case 1: + case 2: + // 片方のCRCだけ正常 + return crc_flag; + + case 3: + // 両方ともCRCが正しければどちらが最新のデータか判断する。 + saveCount = (u8)((ncdsp[0].saveCount + 1) & NVRAM_CONFIG_SAVE_COUNT_MASK); + if (saveCount == ncdsp[1].saveCount) + { + return 2; + } + return 1; + } + + // 両方ともCRCが不正 + return 0; +} + +#else +/*---------------------------------------------------------------------------* + Name: CheckCorrectNCD + + Description: ミラーリングされているユーザー情報のどちらを使うべきか判定する。 + + Arguments: nvdsp - 比較するコンフィグデータ2つの配列。 + + Returns: s32 - 0: 両方不適切。 + 1: 配列[ 0 ]が適切。 + 2: 配列[ 1 ]が適切。 + *---------------------------------------------------------------------------*/ +static s32 CheckCorrectNCD(NVRAMConfig *ncdsp) +{ + u16 i; + u16 calc_crc; + s32 crc_flag = 0; + u16 saveCount; + + // 各ミラーデータのCRC & saveCount正当性チェック + for (i = 0; i < 2; i++) + { + calc_crc = SVC_GetCRC16(0xffff, (void *)(&ncdsp[i].ncd), sizeof(NVRAMConfigData)); + + if ((ncdsp[i].crc16 == calc_crc) && (ncdsp[i].saveCount < NVRAM_CONFIG_SAVE_COUNT_MAX)) + { + // CRCが正しく、saveCount値が0x80未満のデータを正当と判断。 + crc_flag |= (1 << i); + } + } + + // 正当なデータのうちどのデータが有効かを判定する。 + switch (crc_flag) + { + case 1: + case 2: + // 片方のCRCだけ正常 + return crc_flag; + + case 3: + // 両方ともCRCが正しければどちらが最新のデータか判断する。 + saveCount = (u8)((ncdsp[0].saveCount + 1) & NVRAM_CONFIG_SAVE_COUNT_MASK); + if (saveCount == ncdsp[1].saveCount) + { + return 2; + } + return 1; + } + + // 両方ともCRCが不正 + return 0; +} +#endif + +/*---------------------------------------------------------------------------* + Name: VBlankIntr + Description: V ブランク割り込みベクタ。 + Arguments: None. + Returns: None. + *---------------------------------------------------------------------------*/ +extern BOOL PMi_Initialized; +extern void PM_SelfBlinkProc(void); + +static void +VBlankIntr(void) +{ + if (PMi_Initialized) + { + PM_SelfBlinkProc(); + } +} diff --git a/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/ARM9-TS.lsf b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/ARM9-TS.lsf new file mode 100644 index 00000000..35e3fba0 --- /dev/null +++ b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/ARM9-TS.lsf @@ -0,0 +1,57 @@ +#---------------------------------------------------------------------------- +# Project: SystemUpdater +# File: ARM9-TS.lsf +# +# Copyright 2007 Nintendo. All rights reserved. +# +# These coded insructions, statements, and computer programs contain +# proprietary information of Nintendo of America Inc. and/or Nintendo +# Company Ltd., and are protected by Federal copyright law. They may +# not be disclosed to third parties or copied or duplicated in any form, +# in whole or in part, without the prior written consent of Nintendo. +# +# $Date:: $ +# $Rev$ +# $Author$ +#---------------------------------------------------------------------------- +# +# TWL LCF SPEC FILE +# + +Static $(TARGET_NAME) +{ + Address $(ADDRESS_STATIC) + Object $(OBJS_STATIC) + Library $(LLIBS) $(GLIBS) $(CW_LIBS) + StackSize 4096 4096 +} + +Autoload ITCM +{ + Address $(ADDRESS_ITCM) + Object * (.itcm) + Object $(OBJS_AUTOLOAD) (.text) + Object $(OBJS_AUTOLOAD) (.rodata) + Object $(OBJS_AUTOLOAD) (.init) + Object $(OBJS_AUTOLOAD) (.ctor) + Object $(OBJS_AUTOLOAD) (.sinit) +} + +Autoload DTCM +{ + Address $(ADDRESS_DTCM) + Object * (.dtcm) + Object $(OBJS_AUTOLOAD) (.data) + Object $(OBJS_AUTOLOAD) (.sdata) + Object $(OBJS_AUTOLOAD) (.bss) + Object $(OBJS_AUTOLOAD) (.sbss) +} + +Ltdautoload LTDMAIN +{ + # NITRO/TWL 共有のオーバーレイが在る場合は、さらにその後ろに配置する必要があります。 + After $(TARGET_NAME) + Object * (.ltdmain) + Object $(OBJS_LTDAUTOLOAD) + Library $(LLIBS_EX) $(GLIBS_EX) +} diff --git a/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/Makefile b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/Makefile new file mode 100644 index 00000000..c9f78ee8 --- /dev/null +++ b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/Makefile @@ -0,0 +1,140 @@ +#! make -f +#---------------------------------------------------------------------------- +# Project: SystemUpdater +# File: Makefile +# +# Copyright 2007 Nintendo. All rights reserved. +# +# These coded instructions, statements, and computer programs contain +# proprietary information of Nintendo of America Inc. and/or Nintendo +# Company Ltd., and are protected by Federal copyright law. They may +# not be disclosed to third parties or copied or duplicated in any form, +# in whole or in part, without the prior written consent of Nintendo. +# +# $Date:: $ +# $Rev$ +# $Author$ +#---------------------------------------------------------------------------- + +#============================================================================ +#製品鍵を使った書き込みを行う場合は、TwlIPL/build/buildtools/commondefsの"FIRM_USE_PRODUCT_KEYS=TRUE"を有効にしてください。 +#============================================================================ + +# SystemMenuファイルの置かれているフォルダを指定(相対もしくは絶対) +UPDATER_HOST_ROOT_DIR = ../data_sysmenu + +# COMPILE SWITCH for build SystemUpdater +IGNORE_VERSION_CHECK ?= FALSE + +# MAKEROM SWITCH for build SystemUpdater +SYSM_DISABLE_DEBUG ?= FALSE + +TARGET_FIRM = SYSTEMMENU +TARGET_PLATFORM = TWL +TWL_ARCHGEN = LIMITED + +#TARGET_CODEGEN = THUMB + +TITLEID_LO = 0SUA +#TARGET_TAD = + +TARGET_BIN = SystemUpdater.srl +LCFILE_SPEC = ARM9-TS.lsf +ROM_SPEC = main.rsf + +MAKEROM_ARM7_BASE = ../ARM7.TWL/bin/$(TWL_BUILDTYPE_ARM7)/armadillo +MAKEROM_ARM7 = $(MAKEROM_ARM7_BASE).$(TWL_ELF_EXT) + +SRCS = main.c \ + font.c \ + font_data.c \ + graphics.c \ + kami_font.c \ + hwi.c \ + kami_pxi.c \ + kami_write_nandfirm.c \ + hw_info.c \ + keypad.c \ + kami_copy_file.c \ + debugger_hw_reset_control.c \ + debugger_card_rom.c \ + process_select_region.c \ + process_cancel.c \ + process_check_log.c \ + process_note.c \ + process_check_console.c \ + process_format.c \ + process_hwinfo.c \ + process_log.c \ + process_finish.c \ + process_import.c \ + process_write_files.c \ + process_nandfirm.c \ + fade.c + +LINCLUDES = include \ + ../common/include \ + $(ROOT)/build/libraries/lcfg/ARM9.TWL/include \ + $(ROOT)/build/libraries/fs/common/include \ + ../../common/ARM9/include + +SRCDIR = src \ + ../../HWInfoWriter/ARM9/src \ + ../../common/ARM9/src + +#LCFILE = # using default + +#---------------------------------------------------------------------------- + +include $(TWL_IPL_RED_ROOT)/build/buildtools/commondefs + +ifneq ($(TWL_IPL_RED_PRIVATE_ROOT),) +ifdef FIRM_USE_PRODUCT_KEYS +MAKEROM_FLAGS += -DHWINFO_PRIVKEY='private_HWInfo.der' \ + -DHWID_PRIVKEY='private_HWID.der' +else +MAKEROM_FLAGS += -DHWINFO_PRIVKEY='private_HWInfo_dev.der' \ + -DHWID_PRIVKEY='private_HWID_dev.der' +endif +endif + +ifeq ($(IGNORE_VERSION_CHECK),TRUE) +MACRO_FLAGS += -DIGNORE_VERSION_CHECK +endif + +MAKEROM_FLAGS += -DTITLEID_LO='$(TITLEID_LO)' \ + -DPRIVKEY_PATH='$(TWL_KEYSDIR)/rsa' \ + -DCARD_REGION='$(CARD_REGION)' \ + -DDISABLE_DEBUG='$(SYSM_DISABLE_DEBUG)' \ + -DUPDATER_HOST_ROOT_DIR='$(UPDATER_HOST_ROOT_DIR)' + +MAKETAD_FLAGS += -s + +SYSMENU_LIBS = \ + libnamut$(TWL_LIBSUFFIX).a \ + libsysmenu$(TWL_LIBSUFFIX).a + +SDK_APPEND_LIBS = \ + libes$(TWL_LIBSUFFIX).a \ + libboc$(TWL_LIBSUFFIX).a \ + libsfs$(TWL_LIBSUFFIX).a \ + libnam$(TWL_LIBSUFFIX).a \ + libsea$(TWL_LIBSUFFIX).a \ + liblcfg$(TWL_LIBSUFFIX).a + +LLIBRARIES += $(SYSMENU_LIBS) $(SDK_APPEND_LIBS) + +MAKEROM = $(TWL_TOOLSDIR)/bin/makerom.TWL.secure.exe + +#LDIRT_CLEAN = +#INSTALL_TARGETS = +INSTALL_DIR = $(SDK_NMENU_DATADIR) + +#---------------------------------------------------------------------------- + +do-build: $(TARGETS) + +#include $(TWLSDK_ROOT)/build/buildtools/modulerules +include $(TWL_IPL_RED_ROOT)/build/buildtools/modulerules + +#===== End of Makefile ===== diff --git a/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/include/font.h b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/include/font.h new file mode 100644 index 00000000..1bf23fb5 --- /dev/null +++ b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/include/font.h @@ -0,0 +1,100 @@ +/*---------------------------------------------------------------------------* + Project: TwlSDK - NandInitializer + File: keypad.h + + Copyright 2008 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + $Date:: $ + $Rev$ + $Author$ + *---------------------------------------------------------------------------*/ + +#ifndef KAMI_NNS_FONT_H_ +#define KAMI_NNS_FONT_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/*===========================================================================*/ + +#include +#include +#include +#include +#include + +/*---------------------------------------------------------------------------* + 定数定義 + *---------------------------------------------------------------------------*/ + +// 文字列描画関数が扱う文字をUnicodeにする +#define NNS_G2D_UNICODE + +#define CANVAS_WIDTH 32 // 文字描画域の幅 (キャラクタ単位) +#define CANVAS_HEIGHT 24 // 文字描画域の高さ (キャラクタ単位) +#define CANVAS_LEFT 0 // 文字描画域の位置X (キャラクタ単位) +#define CANVAS_TOP 0 // 文字描画域の位置Y (キャラクタ単位) + +#define TEXT_HSPACE 1 // 文字列描画時の文字間 (ピクセル単位) +#define TEXT_VSPACE 1 // 文字列描画時の行間 (ピクセル単位) + +#define CHARACTER_OFFSET 1 // 使用するキャラクタ列の開始番号 + +// DrawText での左上寄せ +#define TXT_DRAWTEXT_FLAG_DEFAULT (NNS_G2D_VERTICALORIGIN_TOP | NNS_G2D_HORIZONTALORIGIN_LEFT | NNS_G2D_HORIZONTALALIGN_LEFT) + +/*---------------------------------------------------------------------------* + 型定義 + *---------------------------------------------------------------------------*/ + +// TXTColorPalette の色名 16色パレットへのロードを想定 +enum +{ + // パレット0 TXT_CPALETTE_MAIN + TXT_COLOR_WHITE=0, // 0 + TXT_COLOR_BLACK, // 1 + TXT_COLOR_GREEN, // 2 + TXT_COLOR_RED, // 3 + TXT_COLOR_WHITE_BASE_START, // 4 + TXT_COLOR_WHITE_BASE, // 5 + TXT_COLOR_BLACK_BASE_START = TXT_COLOR_WHITE_BASE_START+4, // 8 + TXT_COLOR_BLACK_BASE = TXT_COLOR_WHITE_BASE+4, // 9 + TXT_COLOR_FREE_BASE_START = TXT_COLOR_BLACK_BASE_START+4, // 12 + TXT_COLOR_FREE_BASE = TXT_COLOR_BLACK_BASE+4 // 13 +}; + +/*---------------------------------------------------------------------------* + 外部変数宣言 + *---------------------------------------------------------------------------*/ + +extern NNSG2dFont gFont; // フォント +extern NNSG2dCharCanvas gCanvas; // CharCanvas +extern NNSG2dTextCanvas gTextCanvas; // TextCanvas +extern NNSG2dCharCanvas gCanvas2; // CharCanvas +extern NNSG2dTextCanvas gTextCanvas2; // TextCanvas + +/*---------------------------------------------------------------------------* + 関数定義 + *---------------------------------------------------------------------------*/ + +void InitFont(void); +void UpdateFreePltt(u16 color); + +/*===========================================================================*/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* KAMI_NNS_FONT_H_ */ + +/*---------------------------------------------------------------------------* + End of file + *---------------------------------------------------------------------------*/ diff --git a/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/include/graphics.h b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/include/graphics.h new file mode 100644 index 00000000..c7fe3eef --- /dev/null +++ b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/include/graphics.h @@ -0,0 +1,49 @@ +/*---------------------------------------------------------------------------* + Project: SystemUpdater + File: graphics.h + + Copyright 2008 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + $Date:: $ + $Rev$ + $Author$ + *---------------------------------------------------------------------------*/ + +#ifndef GRAPHICS_H_ +#define GRAPHICS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/*===========================================================================*/ + +#include + +/*---------------------------------------------------------------------------* + 関数定義 + *---------------------------------------------------------------------------*/ + +void InitGraphics(void); +void DrawLine(s16 sx, s16 sy, s16 ex, s16 ey, GXRgb color); +void DrawQuad(s16 sx, s16 sy, s16 ex, s16 ey, GXRgb color); +void DrawQuadWithColors(s16 sx, s16 sy, s16 ex, s16 ey, GXRgb color1, GXRgb color2); +void DrawQuadWithAlpha(s16 sx, s16 sy, s16 ex, s16 ey, GXRgb color, s16 alpha); + +/*===========================================================================*/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* GRAPHICS_H_ */ + +/*---------------------------------------------------------------------------* + End of file + *---------------------------------------------------------------------------*/ diff --git a/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/include/hw_info.h b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/include/hw_info.h new file mode 100644 index 00000000..1c43c56e --- /dev/null +++ b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/include/hw_info.h @@ -0,0 +1,71 @@ +/*---------------------------------------------------------------------------* + Project: TwlSDK - NandInitializer + File: process_hw_info.h + + Copyright 2008 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + $Date:: $ + $Rev$ + $Author$ + *---------------------------------------------------------------------------*/ + +#ifndef HW_INFO_H_ +#define HW_INFO_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/*===========================================================================*/ + +#include + +/*---------------------------------------------------------------------------* + 型定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + 関数定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + Name: HW情報全体のライト + + Description: + + Arguments: region : + wirelessForceOff : 無線強制OFFならTRUEを指定 + + Returns: None. + *---------------------------------------------------------------------------*/ +BOOL WriteHWInfoFile( u8 region, BOOL wirelessForceOff ); + + +/*---------------------------------------------------------------------------* + Name: HWInfoファイルの削除 + + Description: + + Arguments: None. + + Returns: None. + *---------------------------------------------------------------------------*/ +BOOL DeleteHWInfoFile( void ); + +/*===========================================================================*/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* HW_INFO_H_ */ + +/*---------------------------------------------------------------------------* + End of file + *---------------------------------------------------------------------------*/ diff --git a/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/include/kami_copy_file.h b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/include/kami_copy_file.h new file mode 100644 index 00000000..73d3cc67 --- /dev/null +++ b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/include/kami_copy_file.h @@ -0,0 +1,44 @@ +/*---------------------------------------------------------------------------* + Project: TwlSDK - SystemUpdater + File: kami_copy_file.h + + Copyright 2008 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + $Date:: $ + $Rev$ + $Author$ + *---------------------------------------------------------------------------*/ + +#ifndef KAMI_COPY_FILE_H_ +#define KAMI_COPY_FILE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/*===========================================================================*/ + +#include + +#define WRAP_DATA_FILE_PATH_IN_NAND "nand:/shared2/launcher/wrap.bin" + +BOOL kamiCopyFile(char* srcPath, char* dstPath); +BOOL kamiWriteWrapData(void); + +/*===========================================================================*/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* KAMI_COPY_FILE_H_ */ + +/*---------------------------------------------------------------------------* + End of file + *---------------------------------------------------------------------------*/ diff --git a/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/include/kami_font.h b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/include/kami_font.h new file mode 100644 index 00000000..ad5095e2 --- /dev/null +++ b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/include/kami_font.h @@ -0,0 +1,94 @@ +/*---------------------------------------------------------------------------* + Project: TwlSDK - NandInitializer + File: kami_font.h + + Copyright 2008 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + $Date:: $ + $Rev$ + $Author$ + *---------------------------------------------------------------------------*/ + +#ifndef KAMI_FONT_H_ +#define KAMI_FONT_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/*===========================================================================*/ + +#include + +extern u8 prog_state; +enum +{ STATE_NONE, STATE_SELECT, STATE_KS_PARENTINIT, STATE_KS_PARENT, STATE_KS_CHILDINIT, + STATE_KS_CHILDSCAN, STATE_KS_CHILD +}; +extern OSHeapHandle heapHandle; // Heapハンドル; + +extern const u16 BgScDataMain[32 * 24]; +extern const u16 BgScDataSub[32 * 24]; +extern const u32 sampleCharData[8 * 0x100]; +extern const u16 PlttDataObj[16][16]; +extern const u16 PlttDataMain[16][16]; +extern const u16 PlttDataSub[16][16]; + +void kamiFontInit(void); +void kamiFontClear(void); +void kamiFontClearMain(void); +void kamiFontPut(u16 x, u16 y, u16 color, u16 no); +void kamiFontPrintf(s16 x, s16 y, u8 color, char *text, ...); +void kamiFontPrintfMain(s16 x, s16 y, u8 color, char *text, ...); +void kamiFontFill(s16 x, s16 y, u8 color, s16 value, s32 length); +void kamiFontFillChar(int lineNo, u8 color1, u8 color2); +void kamiFontLoadScreenData(void); +void kamiFontPrintfConsole(u8 color, const char *text, ...); +void kamiFontPrintfConsoleEx(u8 color, const char *text, ...); + +// 上画面コンソール文字列用パレット +#define CONSOLE_ORANGE 0 +#define CONSOLE_RED 1 +#define CONSOLE_GREEN 2 + +// 下画面フォント用パレット +#define FONT_COLOR_BLACK 0 +#define FONT_COLOR_RED 1 +#define FONT_COLOR_GREEN 2 +#define FONT_COLOR_BLUE 3 +#define FONT_COLOR_YELLOW 4 +#define FONT_COLOR_CYAN 5 +#define FONT_COLOR_PURPLE 6 + +// 下画面背景用パレット +#define BG_COLOR_TRANS 0 +#define BG_COLOR_WHITE 1 +#define BG_COLOR_BLACK 2 +#define BG_COLOR_GRAY 3 +#define BG_COLOR_PURPLE 4 +#define BG_COLOR_PINK 5 +#define BG_COLOR_BLUE 6 +#define BG_COLOR_GREEN 7 +#define BG_COLOR_VIOLET 8 +#define BG_COLOR_RED 9 +#define BG_COLOR_YELLOW 10 + +#define BG_COLOR_NONE 0xff + +/*===========================================================================*/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* KAMI_FONT_H_ */ + +/*---------------------------------------------------------------------------* + End of file + *---------------------------------------------------------------------------*/ diff --git a/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/include/kami_global.h b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/include/kami_global.h new file mode 100644 index 00000000..e2eeb324 --- /dev/null +++ b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/include/kami_global.h @@ -0,0 +1,95 @@ +/*---------------------------------------------------------------------------* + Project: TwlSDK - NandInitializer + File: kami_global.h + + Copyright 2008 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + $Date:: $ + $Rev$ + $Author$ + *---------------------------------------------------------------------------*/ + +#ifndef KAMI_GROBAL_H_ +#define KAMI_GROBAL_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/*===========================================================================*/ + +#include + +/*---------------------------------------------------------------------------* + 型定義 + *---------------------------------------------------------------------------*/ + +typedef struct _SystemUpdaterLog +{ + int magic_code; + int sdk_version; + int ipl_version; + int reserve[5]; +} SystemUpdaterLog; + +typedef enum +{ + IS_TWL_DEBUGGER=0, IS_TWL_CAPTURE, TWL, UNKNOWN +} RunningConsole; + +/*---------------------------------------------------------------------------* + 定数定義 + *---------------------------------------------------------------------------*/ + +#define SYSTEM_UPDATER_LOG_PATH "nand:/sys/log/updater.log" +#define SYSTEM_UPDATER_MAGIC_CODE 44001111 + +/*---------------------------------------------------------------------------* + グローバル変数宣言 + *---------------------------------------------------------------------------*/ + +extern const char *g_strIPLSvnRevision; +extern const char *g_strSDKSvnRevision; +extern s32 gLockId; +extern const u16* sRegionStringArray[4]; +extern OSTWLRegion gRegion; +extern const char* gDirectoryNameConsole[]; +extern const char* gDirectoryNameRegion[]; + +/*---------------------------------------------------------------------------* + 関数宣言 + *---------------------------------------------------------------------------*/ +extern void ProcessSelectRegion(void); +extern void ProcessCancel(const char* string); +extern void ProcessCheckLog(void); +extern void ProcessNote(void); +extern void ProcessCheckConsole(void); +extern BOOL ProcessFormat(void); +extern BOOL ProcessHwinfo(void); +extern void ProcessLog(void); +extern void ProcessFinish(BOOL result); +extern BOOL ProcessImport(void); +extern BOOL ProcessWriteFiles(void); +extern BOOL FadeOutTick(void); +extern BOOL FadeInTick(void); +extern BOOL FadeInMaster(void); +extern RunningConsole GetConsole(void); +extern BOOL ProcessNandfirm(void); + +/*===========================================================================*/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* KAMI_GROBAL_H_ */ + +/*---------------------------------------------------------------------------* + End of file + *---------------------------------------------------------------------------*/ diff --git a/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/include/kami_pxi.h b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/include/kami_pxi.h new file mode 100644 index 00000000..c05de9d4 --- /dev/null +++ b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/include/kami_pxi.h @@ -0,0 +1,89 @@ +/*---------------------------------------------------------------------------* + Project: TwlSDK - NandInitializer + File: kami_pxi.h + + Copyright 2008 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + $Date:: $ + $Rev$ + $Author$ + *---------------------------------------------------------------------------*/ + +#ifndef TWL_KAMI_TEST_KAMITEST_H_ +#define TWL_KAMI_TEST_KAMITEST_H_ + +#include "fifo.h" + +/*---------------------------------------------------------------------------* + 定数定義 + *---------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*===========================================================================*/ + +// 処理結果定義 +typedef enum KAMIResult +{ + KAMI_RESULT_SUCCESS = 0, + KAMI_RESULT_SUCCESS_TRUE = 0, + KAMI_RESULT_SUCCESS_FALSE, + KAMI_RESULT_INVALID_COMMAND, + KAMI_RESULT_INVALID_PARAMETER, + KAMI_RESULT_ILLEGAL_STATUS, + KAMI_RESULT_BUSY, + KAMI_RESULT_FATAL_ERROR, + KAMI_RESULT_SEND_ERROR, + KAMI_RESULT_MAX +} +KAMIResult; + + +typedef enum { + FORMAT_MODE_QUICK, // Quickフォーマット + FORMAT_MODE_FULL // Fullフォーマット(各パーティション内を0xFFで埋める) +} FormatMode; + +// コールバック +typedef void (*KAMICallback)(KAMIResult result, void *arg); + + +void KamiPxiInit( void ); + +KAMIResult ExeFormatAsync(FormatMode format_mode, KAMICallback callback); +KAMIResult kamiNandIo(u32 block, void* buffer, u32 count, BOOL is_read); +KAMIResult kamiClearNandErrorLog( void ); +KAMIResult kamiGetIsToolType( IsToolType *pType ); + +// (重要) +// ARM7が読み書きするためリード前はInvalidate、ライト前はフラッシュしてください。 +// +static KAMIResult kamiNandRead(u32 block, void* buffer, u32 count) +{ + return kamiNandIo(block, buffer, count, TRUE); +} +static KAMIResult kamiNandWrite(u32 block, void* buffer, u32 count) +{ + return kamiNandIo(block, buffer, count, FALSE); +} + +/*===========================================================================*/ + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* TWL_KAMI_TEST_KAMITEST_H_ */ + +/*---------------------------------------------------------------------------* + End of file + *---------------------------------------------------------------------------*/ diff --git a/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/include/kami_write_nandfirm.h b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/include/kami_write_nandfirm.h new file mode 100644 index 00000000..90fe68bd --- /dev/null +++ b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/include/kami_write_nandfirm.h @@ -0,0 +1,52 @@ +/*---------------------------------------------------------------------------* + Project: TwlSDK - NandInitializer + File: kami_write_nandfirm.h + + Copyright 2008 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + $Date:: $ + $Rev$ + $Author$ + *---------------------------------------------------------------------------*/ + +#ifndef KAMI_WRITE_NAND_FIRM +#define KAMI_WRITE_NAND_FIRM + +#ifdef __cplusplus +extern "C" { +#endif + +/*===========================================================================*/ + +#include + +/*---------------------------------------------------------------------------* + 型定義 + *---------------------------------------------------------------------------*/ + +typedef void* (*KAMIAlloc)(u32 size); +typedef void (*KAMIFree)(void* ptr); + +/*---------------------------------------------------------------------------* + 関数定義 + *---------------------------------------------------------------------------*/ + +BOOL kamiWriteNandfirm(const char* pFullPath, NAMAlloc allocFunc, NAMFree freeFunc); + +/*===========================================================================*/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* KAMI_WRITE_NAND_FIRM */ + +/*---------------------------------------------------------------------------* + End of file + *---------------------------------------------------------------------------*/ diff --git a/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/include/keypad.h b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/include/keypad.h new file mode 100644 index 00000000..2f5a1602 --- /dev/null +++ b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/include/keypad.h @@ -0,0 +1,48 @@ +/*---------------------------------------------------------------------------* + Project: TwlSDK - NandInitializer + File: keypad.h + + Copyright 2008 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + $Date:: $ + $Rev$ + $Author$ + *---------------------------------------------------------------------------*/ + +#ifndef KAMI_KEY_PAD_H_ +#define KAMI_KEY_PAD_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/*===========================================================================*/ + +#include + +/*---------------------------------------------------------------------------* + 関数定義 + *---------------------------------------------------------------------------*/ + +void kamiPadRead(void); +BOOL kamiPadIsTrigger(u16 key); +BOOL kamiPadIsRepeatTrigger(u16 key); +BOOL kamiPadIsPress(u16 key); + +/*===========================================================================*/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* KAMI_KEY_PAD_H_ */ + +/*---------------------------------------------------------------------------* + End of file + *---------------------------------------------------------------------------*/ diff --git a/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/main.rsf b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/main.rsf new file mode 100644 index 00000000..c01d374d --- /dev/null +++ b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/main.rsf @@ -0,0 +1,232 @@ +#---------------------------------------------------------------------------- +# Project: SystemUpdater +# File: main.rsf +# +# Copyright 2007 Nintendo. All rights reserved. +# +# These coded insructions, statements, and computer programs contain +# proprietary information of Nintendo of America Inc. and/or Nintendo +# Company Ltd., and are protected by Federal copyright law. They may +# not be disclosed to third parties or copied or duplicated in any form, +# in whole or in part, without the prior written consent of Nintendo. +# +# $Date:: $ +# $Rev$ +# $Author$ +#---------------------------------------------------------------------------- +# +# TWL ROM SPEC FILE +# + +Arm9 +{ + Static "$(MAKEROM_ARM9:r).TWL.FLX.sbin$(COMPSUFFIX9)" + OverlayDefs "$(MAKEROM_ARM9:r)_defs.TWL.FLX.sbin$(COMPSUFFIX9)" + OverlayTable "$(MAKEROM_ARM9:r)_table.TWL.FLX.sbin$(COMPSUFFIX9)" + Elf "$(MAKEROM_ARM9:r).tef" +} + +Arm7 +{ + Static "$(MAKEROM_ARM7_BASE:r).TWL.FLX.sbin$(COMPSUFFIX7)" + OverlayDefs "$(MAKEROM_ARM7_BASE:r)_defs.TWL.FLX.sbin$(COMPSUFFIX7)" + OverlayTable "$(MAKEROM_ARM7_BASE:r)_table.TWL.FLX.sbin$(COMPSUFFIX7)" + Elf "$(MAKEROM_ARM7_BASE:r).tef" +} + +Arm9.Ltd +{ + Static "$(MAKEROM_ARM9:r).TWL.LTD.sbin$(COMPSUFFIX9)" + OverlayDefs "$(MAKEROM_ARM9:r)_defs.TWL.LTD.sbin$(COMPSUFFIX9)" + OverlayTable "$(MAKEROM_ARM9:r)_table.TWL.LTD.sbin$(COMPSUFFIX9)" +} + +Arm7.Ltd +{ + Static "$(MAKEROM_ARM7_BASE:r).TWL.LTD.sbin$(COMPSUFFIX7)" + OverlayDefs "$(MAKEROM_ARM7_BASE:r)_defs.TWL.LTD.sbin$(COMPSUFFIX7)" + OverlayTable "$(MAKEROM_ARM7_BASE:r)_table.TWL.LTD.sbin$(COMPSUFFIX7)" +} + +Property +{ + ### + ### Settings for FinalROM + ### + #### BEGIN + # + # TITLE NAME: Your product name within 12bytes + # + #TitleName "YourAppName" + + # + # MAKER CODE: Your company ID# in 2 ascii words + # issued by NINTENDO + # + #MakerCode "00" + + # + # REMASTER VERSION: Mastering version + # + #RomVersion 0 + + # + # ROM SPEED TYPE: [MROM/1TROM/UNDEFINED] + # + RomSpeedType $(MAKEROM_ROMSPEED) + + # + # ROM SIZE: in bit [64M/128M/256M/512M/1G/2G] + # + #RomSize 64M + + # + # ROM PADDING: TRUE if finalrom + # + #RomFootPadding TRUE + + # + # ROM HEADER TEMPLATE: Provided to every product by NINTENDO + # + #RomHeaderTemplate ./etc/rom_header.template.sbin + + # + # BANNER FILE: generated from Banner Spec File + # + BannerFile ../banner/banner.bnr + + ### + ### Setting for TWL + ### + + # + # ROM HEADER Ltd: Provided to every product by NINTENDO + # + RomHeaderLtd $(TWLSDK_ROOT)/tools/bin/rom_header.LTD.sbin + + # + # Digest parameters: + # + DigestParam 1024 32 + + # + # WRAM mapping: [MAP_BB_HYB/MAP_BB_LTD/MAP_TS_HYB/MAP_TS_LTD] + # don't have to edit + # + WramMapping MAP_TS_SCR + + # + # CardRegion: card region [Japan/America/Europe/Australia/China/Korea] + # + CardRegion ALL + + # + # CommonClientKey: launcher deliver common client Key [TRUE/FALSE] + # + # ========= SystemUpdaterは特別な鍵を使う ========= + #CommonClientKey TRUE + CommonClientKeyForDebugger TRUE + + # + # HwAESSlotB: launcher deliver HW AES slot B setting [TRUE/FALSE] + # + HwAESSlotB TRUE + + # + # HwAESSlotC: launcher deliver HW AES slot C setting [TRUE/FALSE] + # + HwAESSlotC TRUE + + # + # SDCardAccess: sd card access control [TRUE/FALSE] + # + SDCardAccess TRUE + + # + # NANDAccess: NAND access control [TRUE/FALSE] + # + NANDAccess TRUE + + # + # Codec mode: + # don't have to edit + # + CodecMode $(MAKEROM_CODEC_MODE) + + # + # DisableDebug :最終ROMでは、実行時にデバッグできないようにTRUEにする必要があります。 + # + DisableDebug $(DISABLE_DEBUG) + + ### + #### END +} + + +AppendProperty +{ + # + # Publisher : "Nintendo" + # don't have to edit + Publisher Nintendo + + # + # Application type : [USER/SYSTEM] + # don't have to edit + AppType System + + # + # launch title on the launcher : [TRUE/FALSE] + # don't have to edit + Launch TRUE + + # + # Data only title : [TRUE/FALSE] + # don't have to edit + DataOnly FALSE + + # + # Secure title : [TRUE/FALSE] + # don't have to edit + Secure TRUE + + # + # Boot allowed Media: [GameCard/NAND] + # + Media GameCard + + # + # GameCode for TitleID : Your GameCode in 4 ascii words + # + GameCode $(TITLEID_LO) + + # + # Public save data size: [16K/32K/64K/128K/256K/512K/1M/2M/4M/8M] + # + #PublicSaveDataSize 32K + + # + # Private save data size: [16K/32K/64K/128K/256K/512K/1M/2M/4M/8M] + # + #PrivateSaveDataSize 16K + + # + # Enable SubBannerFile + #SubBannerFile TRUE +} + + +RomSpec +{ + Offset 0x00000000 + Segment ALL + HostRoot $(UPDATER_HOST_ROOT_DIR) + Root /data + File * + HostRoot ../data + Root /font + File tbf_ww_s.NFTR + HostRoot $(PRIVKEY_PATH) + Root /key + File $(HWINFO_PRIVKEY) $(HWID_PRIVKEY) +} diff --git a/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/fade.c b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/fade.c new file mode 100644 index 00000000..6c397505 --- /dev/null +++ b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/fade.c @@ -0,0 +1,77 @@ +/*---------------------------------------------------------------------------* + Project: TwlSDK - NandInitializer + File: fade.c + + Copyright 2008 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + $Date:: $ + $Rev$ + $Author$ + *---------------------------------------------------------------------------*/ + +#include +#include "kami_global.h" + +/*---------------------------------------------------------------------------* + 定数定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + 内部変数定義 + *---------------------------------------------------------------------------*/ + +static int brightness = 0; +static int master_brightness = -16; +static int counter; + +/*---------------------------------------------------------------------------* + 内部関数定義 + *---------------------------------------------------------------------------*/ +BOOL FadeOutTick(void) +{ + if ( brightness < 16) + { +// if (++counter == 2) +// { + counter = 0; + G2_SetBlendBrightness( GX_BLEND_PLANEMASK_BG0 | GX_BLEND_PLANEMASK_BG1, ++brightness ); +// } + return FALSE; + } + return TRUE; +} + +BOOL FadeInTick(void) +{ + if ( brightness > 0) + { +// if (++counter == 2) +// { + counter = 0; + G2_SetBlendBrightness( GX_BLEND_PLANEMASK_BG0 | GX_BLEND_PLANEMASK_BG1, --brightness ); +// } + return FALSE; + } + return TRUE; +} + +BOOL FadeInMaster(void) +{ + if ( master_brightness < 0) + { + if (++counter == 2) + { + counter = 0; + GX_SetMasterBrightness( ++master_brightness ); + } + return FALSE; + } + return TRUE; +} + diff --git a/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/font.c b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/font.c new file mode 100644 index 00000000..83546fe1 --- /dev/null +++ b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/font.c @@ -0,0 +1,322 @@ +/*---------------------------------------------------------------------------* + Project: SystemUpdater + File: main.c + + Copyright 2008 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + $Date:: $ + $Rev$ + $Author$ + *---------------------------------------------------------------------------*/ + +#include +#include +#include +#include +#include +#include "font.h" +#include "kami_global.h" + +// 文字列描画関数が扱う文字をUnicodeにする +#define NNS_G2D_UNICODE + +#define CANVAS_WIDTH 32 // 文字描画域の幅 (キャラクタ単位) +#define CANVAS_HEIGHT 24 // 文字描画域の高さ (キャラクタ単位) +#define CANVAS_LEFT 0 // 文字描画域の位置X (キャラクタ単位) +#define CANVAS_TOP 0 // 文字描画域の位置Y (キャラクタ単位) + +#define TEXT_HSPACE 1 // 文字列描画時の文字間 (ピクセル単位) +#define TEXT_VSPACE 1 // 文字列描画時の行間 (ピクセル単位) + +#define CHARACTER_OFFSET 1 // 使用するキャラクタ列の開始番号 + +// DrawText での左上寄せ +#define TXT_DRAWTEXT_FLAG_DEFAULT (NNS_G2D_VERTICALORIGIN_TOP | NNS_G2D_HORIZONTALORIGIN_LEFT | NNS_G2D_HORIZONTALALIGN_LEFT) + +/*---------------------------------------------------------------------------* + 型定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + グローバル変数定義 + *---------------------------------------------------------------------------*/ + +NNSG2dFont gFont; // フォント +NNSG2dCharCanvas gCanvas; // CharCanvas +NNSG2dCharCanvas gCanvas2; // CharCanvas +NNSG2dTextCanvas gTextCanvas; // TextCanvas +NNSG2dTextCanvas gTextCanvas2; // TextCanvas + +/*---------------------------------------------------------------------------* + 内部定数定義 + *---------------------------------------------------------------------------*/ +const int max_colors = 32; + +/*---------------------------------------------------------------------------* + 内部変数定義 + *---------------------------------------------------------------------------*/ + +// バックドロップ色(白) + 黒 + 緑 + 赤 + 最大フォント階調数 (32階調まで) +static u16 colorPalette[1 + 1 + 1 + 1 + max_colors*5] = +{ + GX_RGB(31, 31, 31), GX_RGB(0, 0, 0), GX_RGB(0, 31, 0), GX_RGB(31, 0, 0) +}; + +/*---------------------------------------------------------------------------* + 内部関数定義 + *---------------------------------------------------------------------------*/ + +static u32 LoadFile(void** ppFile, const char* fpath); + +/*---------------------------------------------------------------------------* + Name: LoadFile + + Description: ファイルをメモリにロードします。 + ファイルデータが不要になった場合は + CMN_UnloadFile( *ppFile, pAlloc ) でファイルデータを + 解放します。 + + Arguments: ppFile: ファイルをロードしたメモリアドレスを受け取る + バッファへのポインタ。 + fpath: ロードするファイルのパス + pAlloc: アロケータへのポインタ + + Returns: ロードしたファイルのファイルサイズを返します。 + 0 の場合はファイルロードに失敗した事を表します。 + この場合 *ppFile の値は無効です。 + *---------------------------------------------------------------------------*/ +static u32 LoadFile(void** ppFile, const char* fpath) +{ + BOOL bSuccess; + FSFile f; + u32 length; + u32 read; + + SDK_NULL_ASSERT( ppFile ); + SDK_NULL_ASSERT( fpath ); + + FS_InitFile(&f); + + bSuccess = FS_OpenFile(&f, fpath); + if( ! bSuccess ) + { + OS_Warning("file (%s) not found", fpath); + return 0; + } + + length = FS_GetLength(&f); + *ppFile = OS_AllocFromMain(length); + if( *ppFile == NULL ) + { + OS_Warning("cant allocate memory for file: %s", fpath); + return 0; + } + + read = (u32)FS_ReadFile(&f, *ppFile, (s32)length); + if( read != length ) + { + OS_Warning("fail to load file: %s", fpath); + OS_FreeToMain(*ppFile); + return 0; + } + + bSuccess = FS_CloseFile(&f); + if( ! bSuccess ) + { + OS_Warning("fail to close file: %s", fpath); + } + + return length; +} + +/*---------------------------------------------------------------------------* + Name: InitCanvas + + Description: 文字列描画の初期化をします。 + + Arguments: なし。 + + Returns: なし。 + *---------------------------------------------------------------------------*/ +static void InitCanvas(void) +{ + GXCharFmt16* pCharBase = (GXCharFmt16*)G2_GetBG1CharPtr(); + GXCharFmt16* pCharBase2 = (GXCharFmt16*)G2_GetBG2CharPtr(); + int cOffset = CHARACTER_OFFSET; + + // フォントを読み込みます + { +// 他のデモと同じように TXT_LoadFont を使ってもフォントを読み込めます。 +// このデモでは NNS_G2dFontInitUTF16 を使う場合を示しています。 +// TXT_LoadFont( &gFont, "/data/fontu16.NFTR" ); + + void* pFontFile; + u32 size; + + size = LoadFile( &pFontFile, "/font/tbf_ww_s.NFTR" ); + NNS_G2D_ASSERT( size > 0 ); + + NNS_G2dFontInitUTF16(&gFont, pFontFile); + NNS_G2dPrintFont(&gFont); + } + + // CharCanvas の初期化 + NNS_G2dCharCanvasInitForBG( + &gCanvas, + pCharBase + cOffset, + CANVAS_WIDTH, + CANVAS_HEIGHT, + NNS_G2D_CHARA_COLORMODE_16 + ); + NNS_G2dCharCanvasInitForBG( + &gCanvas2, + pCharBase2 + cOffset, + CANVAS_WIDTH, + CANVAS_HEIGHT, + NNS_G2D_CHARA_COLORMODE_16 + ); + + // TextCanvasの初期化 + NNS_G2dTextCanvasInit( + &gTextCanvas, + &gCanvas, + &gFont, + TEXT_HSPACE, + TEXT_VSPACE + ); + NNS_G2dTextCanvasInit( + &gTextCanvas2, + &gCanvas2, + &gFont, + TEXT_HSPACE, + TEXT_VSPACE + ); + + // スクリーンを設定 + NNS_G2dMapScrToCharText( + G2_GetBG1ScrPtr(), + CANVAS_WIDTH, + CANVAS_HEIGHT, + CANVAS_LEFT, + CANVAS_TOP, + NNS_G2D_TEXT_BG_WIDTH_256, + CHARACTER_OFFSET, + 0 + ); + NNS_G2dMapScrToCharText( + G2_GetBG2ScrPtr(), + CANVAS_WIDTH, + CANVAS_HEIGHT, + CANVAS_LEFT, + CANVAS_TOP, + NNS_G2D_TEXT_BG_WIDTH_256, + CHARACTER_OFFSET, + 0 + ); + + // パレットをロード + { + // ロードしたフォントに応じてカラーパレットを作成 + { + const int nColors = MATH_IMin((1 << NNS_G2dFontGetBpp(&gFont)), max_colors); + int i; + + // 白地用パレット 31,20,10, 0 + for( i = 0; i < nColors; ++i ) + { + int level = ((nColors - 1 - i) * (max_colors - 1) / (nColors - 1)); + + colorPalette[i+TXT_COLOR_WHITE_BASE_START] = GX_RGB(level, level, level); + } + + // 黒地用パレット 0, 10, 20, 31 + for( i = 0; i < nColors; ++i ) + { + int level = ((i) * (max_colors - 1) / (nColors - 1)); + + colorPalette[i+TXT_COLOR_BLACK_BASE_START] = GX_RGB(level, level, level); + } + + // 水色地用パレット + for( i = 0; i < nColors; ++i ) + { + int level = ((nColors - 1 - i) * (max_colors - 1) / (nColors - 1)); + + colorPalette[i+TXT_COLOR_FREE_BASE_START] = GX_RGB((int)(level*0.7), (int)(level*0.9), level); + } + } + + // カラーパレットをロード + GX_LoadBGPltt(colorPalette, 0, sizeof(colorPalette)); + } +} + +/*---------------------------------------------------------------------------* + Name: UpdateFreePltt + + Description: + + Arguments: なし。 + + Returns: なし。 + *---------------------------------------------------------------------------*/ +void UpdateFreePltt(u16 color) +{ + const int nColors = MATH_IMin((1 << NNS_G2dFontGetBpp(&gFont)), max_colors); + s32 i; + + // フリーパレット + for( i = 0; i < nColors; ++i ) + { + int level = ((nColors - 1 - i) * (max_colors - 1) / (nColors - 1)); + + colorPalette[i+TXT_COLOR_FREE_BASE_START] = + GX_RGB( (int)(level*((color & GX_RGBA_R_MASK)>>GX_RGBA_R_SHIFT)/32.0), + (int)(level*((color & GX_RGBA_G_MASK)>>GX_RGBA_G_SHIFT)/32.0), + (int)(level*((color & GX_RGBA_B_MASK)>>GX_RGBA_B_SHIFT)/32.0)); + } + + // カラーパレットをロード + GX_LoadBGPltt(colorPalette, 0, sizeof(colorPalette)); +} + +/*---------------------------------------------------------------------------* + Name: InitFont + + Description: + + Arguments: なし。 + + Returns: なし。 + *---------------------------------------------------------------------------*/ +void InitFont(void) +{ + char string1[256]; + u16 string2[256]; + + InitCanvas(); + + MI_CpuClear8(string1, sizeof(string1)); + MI_CpuClear8(string2, sizeof(string2)); + + OS_WaitVBlankIntr(); + NNS_G2dCharCanvasClear(&gCanvas, TXT_COLOR_WHITE); + OS_WaitVBlankIntr(); + NNS_G2dCharCanvasClear(&gCanvas2, TXT_COLOR_WHITE); + OS_WaitVBlankIntr(); + NNS_G2dCharCanvasClearArea(&gCanvas2, TXT_COLOR_BLACK, 0, 0, 256, 30); + + STD_TSPrintf(string1, "System Updater rev.%s-%s", g_strSDKSvnRevision, g_strIPLSvnRevision); + STD_ConvertStringSjisToUnicode(string2, NULL, string1, NULL, NULL); + + NNS_G2dTextCanvasDrawText(&gTextCanvas2, 30, 6, + TXT_COLOR_BLACK_BASE, TXT_DRAWTEXT_FLAG_DEFAULT, + (const char *)string2 + ); +} diff --git a/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/font_data.c b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/font_data.c new file mode 100644 index 00000000..67d1cff4 --- /dev/null +++ b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/font_data.c @@ -0,0 +1,734 @@ +/*---------------------------------------------------------------------------* + Project: SystemUpdater + File: font_data.c + + Copyright 2008 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + $Date:: $ + $Rev$ + $Author$ + *---------------------------------------------------------------------------*/ + +#include + +/*---------------------- BGスクリーン ---------------------------*/ + +const u16 BgScDataMain[32 * 24] = { + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +}; + +const u16 BgScDataSub[32 * 24] = { + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +}; + +/*---------------------- パレットデータ ---------------------------*/ +#define RGB555(r,g,b) (b<<10|g<<5|r) + +const u16 PlttDataObj[16][16] = { + {RGB555( 0, 0, 0), RGB555(31, 10, 0), RGB555(31, 0, 0), RGB555(5, 5, 20),}, // Black + {RGB555(31, 31, 31), RGB555(31, 0, 0), RGB555(31, 0, 0), RGB555(31, 0, 0),}, // Red + {RGB555(31, 31, 31), RGB555(0, 31, 0), RGB555(0, 31, 0), RGB555(0, 31, 0),}, // Green + {RGB555(31, 31, 31), RGB555(0, 0, 31), RGB555(0, 0, 31), RGB555(0, 0, 31),}, // Blue + {RGB555(31, 31, 31), RGB555(31, 31, 0), RGB555(31, 31, 0), RGB555(31, 31, 0),}, // Yellow + {RGB555(31, 31, 31), RGB555(0, 31, 31), RGB555(0, 31, 31), RGB555(0, 31, 31),}, // Cyan + {RGB555(31, 31, 31), RGB555(31, 0, 31), RGB555(31, 0, 31), RGB555(31, 0, 31),}, // Purple + {RGB555(31, 31, 31), RGB555(31, 31, 31), RGB555(31, 31, 31), RGB555(31, 31, 31),}, // White +}; + +// 上画面コンソール文字列パレット +const u16 PlttDataMain[16][16] = { + {RGB555(31, 31, 31), RGB555(31, 10, 0), RGB555(0, 0, 0), RGB555(0, 0, 0),}, // Orange + {RGB555(31, 31, 31), RGB555(31, 0, 0), RGB555(31, 0, 0), RGB555(31, 0, 0),}, // Red + {RGB555(31, 31, 31), RGB555(0, 31, 0), RGB555(0, 31, 0), RGB555(0, 31, 0),}, // Green + {RGB555(31, 31, 31), RGB555(0, 0, 31), RGB555(0, 0, 31), RGB555(0, 0, 31),}, // Blue + {RGB555(31, 31, 31), RGB555(31, 31, 0), RGB555(31, 31, 0), RGB555(31, 31, 0),}, // Yellow + {RGB555(31, 31, 31), RGB555(0, 31, 31), RGB555(0, 31, 31), RGB555(0, 31, 31),}, // Cyan + {RGB555(31, 31, 31), RGB555(31, 0, 31), RGB555(31, 0, 31), RGB555(31, 0, 31),}, // Purple + {RGB555(31, 31, 31), RGB555(31, 31, 31), RGB555(31, 31, 31), RGB555(31, 31, 31),}, // White + {RGB555( 5, 5, 5), RGB555( 5, 5, 5), RGB555( 5, 5, 5), RGB555(31, 31, 31),}, // Black +}; + +// 下画面コンソール文字列パレット +const u16 PlttDataSub[16][16] = { + {RGB555( 0, 0, 0), RGB555( 0, 0, 0), RGB555(25, 25, 25), RGB555(31, 31, 31),}, // Black + {RGB555(31, 31, 31), RGB555(21, 0, 0), RGB555(31, 0, 0), RGB555(31, 0, 0),}, // Red + {RGB555(31, 31, 31), RGB555( 0, 21, 0), RGB555(0, 31, 0), RGB555(0, 31, 0),}, // Green + {RGB555(31, 31, 31), RGB555( 0, 0, 21), RGB555(0, 0, 31), RGB555(0, 0, 31),}, // Blue + {RGB555(31, 31, 31), RGB555(21, 21, 0), RGB555(31, 31, 0), RGB555(31, 31, 0),}, // Yellow + {RGB555(31, 31, 31), RGB555(0, 21, 21), RGB555(0, 31, 31), RGB555(0, 31, 31),}, // Cyan + {RGB555(31, 31, 31), RGB555(21, 0, 21), RGB555(31, 0, 31), RGB555(31, 0, 31),}, // Purple + {RGB555(31, 31, 31), RGB555(31, 31, 31), RGB555(31, 31, 31), RGB555(31, 31, 31),}, // White + {RGB555(31, 31, 31), RGB555(20, 20, 20), RGB555(20, 20, 20), RGB555(20, 20, 20),}, // Gray + {RGB555(31, 31, 31), RGB555(31, 31, 31), RGB555(31, 31, 31), RGB555(31, 31, 31),}, // White + {RGB555(31, 31, 31), RGB555(31, 31, 31), RGB555(31, 31, 31), RGB555(31, 31, 31),}, // White + {RGB555(31, 31, 31), RGB555(31, 31, 31), RGB555(31, 31, 31), RGB555(31, 31, 31),}, // White + {RGB555(31, 31, 31), RGB555(31, 31, 31), RGB555(31, 31, 31), RGB555(31, 31, 31),}, // White + {RGB555(31, 31, 31), RGB555(31, 31, 31), RGB555(31, 31, 31), RGB555(31, 31, 31),}, // White + {RGB555(31, 31, 31), RGB555(31, 31, 31), RGB555(31, 31, 31), RGB555(31, 31, 31),}, // White + + // 背景カラーはこの16番パレット + // 白 黒 灰 むらさき ピンク みずいろ 緑 青紫 赤 黄 + {RGB555(31, 31, 31), RGB555(31, 31, 31), RGB555( 0, 0, 0), RGB555(20, 20, 20), RGB555(31, 15, 31), RGB555(31, 20, 20), RGB555(20, 29, 31), RGB555(20, 31, 20), RGB555(21, 21, 31), RGB555(31, 0, 0), RGB555(31, 31, 10), RGB555(31, 31, 31), RGB555(31, 31, 31), RGB555(31, 31, 31), } // White +}; + +/*---------------------- キャラクタデータ -------------------------*/ + +const u32 sampleCharData[8 * 0x100] = { + 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 0000h + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x11111111, 0x11111111, // 0001h use for import progress bar + 0x11111111, 0x11111111, 0x00000000, 0x00000000, + 0x00000000, 0x01011010, 0x01010010, 0x00010010, // 0002h + 0x00100010, 0x00100010, 0x00100001, 0x00100001, + 0x00000000, 0x01010001, 0x01010001, 0x01111111, // 0003h + 0x00000001, 0x00000001, 0x00000001, 0x01111110, + 0x00000000, 0x01010000, 0x01111111, 0x00100000, // 0004h + 0x00100000, 0x00010000, 0x00001000, 0x00000110, + 0x00000000, 0x01010000, 0x01010100, 0x00001010, // 0005h + 0x00010001, 0x00100001, 0x01000000, 0x00000000, + 0x00000000, 0x01011000, 0x01011000, 0x01111111, // 0006h + 0x00001000, 0x00101010, 0x01001010, 0x01001001, + 0x00000000, 0x01010010, 0x01101111, 0x01010010, // 0007h + 0x00010010, 0x00010010, 0x00010010, 0x00001001, + 0x00000000, 0x01010010, 0x01011111, 0x00000100, // 0008h + 0x00011111, 0x00001000, 0x00000001, 0x00011110, + 0x00000000, 0x01010000, 0x01011000, 0x00000110, // 0009h + 0x00000001, 0x00000110, 0x00011000, 0x00100000, + 0x00000000, 0x01010000, 0x01111101, 0x00010001, // 000ah + 0x00010001, 0x00010001, 0x00010001, 0x00001010, + 0x00000000, 0x01010000, 0x01011110, 0x00100000, // 000bh + 0x00000000, 0x00000001, 0x00000001, 0x00111110, + 0x00000000, 0x01010100, 0x01011111, 0x00001000, // 000ch + 0x00010000, 0x00000001, 0x00000001, 0x00011110, + 0x00000000, 0x01010001, 0x01010001, 0x00000001, // 000dh + 0x01000001, 0x01000001, 0x00100010, 0x00011100, + 0x00000000, 0x01010000, 0x01111111, 0x00011000, // 000eh + 0x00010100, 0x00010100, 0x00011000, 0x00001100, + 0x00000000, 0x01010010, 0x01111111, 0x00010010, // 000fh + 0x00010010, 0x00000010, 0x00000010, 0x00111100, + 0x00000000, 0x00001110, 0x01010100, 0x01010010, // 0010h + 0x00111111, 0x00000100, 0x00000100, 0x00011000, + 0x00000000, 0x01010100, 0x01011111, 0x00000100, // 0011h + 0x01110100, 0x00000010, 0x00001010, 0x01110010, + 0x00000000, 0x01010100, 0x01011111, 0x00000010, // 0012h + 0x00011110, 0x00100001, 0x00100000, 0x00011110, + 0x00000000, 0x01010000, 0x01011100, 0x00100011, // 0013h + 0x01000000, 0x01000000, 0x00100000, 0x00011100, + 0x00000000, 0x01010000, 0x01111111, 0x00010000, // 0014h + 0x00001000, 0x00001000, 0x00001000, 0x00110000, + 0x00000000, 0x01010010, 0x01010010, 0x00001100, // 0015h + 0x00000010, 0x00000001, 0x00000001, 0x00111110, + 0x00000000, 0x01010001, 0x01111101, 0x00010001, // 0016h + 0x00010001, 0x00111001, 0x01010101, 0x00011001, + 0x00000000, 0x01010100, 0x01010011, 0x01110010, // 0017h + 0x00010001, 0x00010001, 0x00001010, 0x00000100, + 0x00000000, 0x01011110, 0x01011000, 0x00000100, // 0018h + 0x00101001, 0x01010001, 0x01010001, 0x00001100, + 0x00000000, 0x01010000, 0x01011100, 0x00010010, // 0019h + 0x00010010, 0x00100001, 0x01000000, 0x00000000, + 0x00000000, 0x01011101, 0x01010001, 0x00111101, // 001ah + 0x00010001, 0x00011001, 0x00110101, 0x00001001, + 0x00000000, 0x01110001, 0x01011101, 0x00110001, // 001bh + 0x00010001, 0x00111001, 0x01010101, 0x00011001, + 0x00000000, 0x01110100, 0x01010011, 0x00110010, // 001ch + 0x00010001, 0x00010001, 0x00001010, 0x00000100, + 0x00000000, 0x01101110, 0x01011000, 0x00100100, // 001dh + 0x00101001, 0x01010001, 0x01010001, 0x00001100, + 0x00000000, 0x01110000, 0x01011100, 0x00110010, // 001eh + 0x00010010, 0x00100001, 0x01000000, 0x00000000, + 0x00000000, 0x01111101, 0x01010001, 0x00111101, // 001fh + 0x00010001, 0x00011001, 0x00110101, 0x00001001, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 0020h + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00001000, 0x00001000, 0x00001000, // 0021h + 0x00001000, 0x00001000, 0x00000000, 0x00001000, + 0x00000000, 0x01101100, 0x01001000, 0x00100100, // 0022h + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00100100, 0x01111111, 0x00100100, // 0023h + 0x00100100, 0x01111111, 0x00010010, 0x00010010, + 0x00000000, 0x00001000, 0x01111110, 0x00001001, // 0024h + 0x00111110, 0x01001000, 0x00111111, 0x00001000, + 0x00000000, 0x01000010, 0x00100101, 0x00010010, // 0025h + 0x00001000, 0x00100100, 0x01010010, 0x00100001, + 0x00000000, 0x00001110, 0x00010001, 0x00001001, // 0026h + 0x01000110, 0x00101001, 0x00110001, 0x01001110, + 0x00000000, 0x00011000, 0x00010000, 0x00001000, // 0027h + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x01110000, 0x00001000, 0x00000100, // 0028h + 0x00000100, 0x00000100, 0x00001000, 0x01110000, + 0x00000000, 0x00000111, 0x00001000, 0x00010000, // 0029h + 0x00010000, 0x00010000, 0x00001000, 0x00000111, + 0x00000000, 0x00001000, 0x01001001, 0x00101010, // 002ah + 0x00011100, 0x00101010, 0x01001001, 0x00001000, + 0x00000000, 0x00001000, 0x00001000, 0x00001000, // 002bh + 0x01111111, 0x00001000, 0x00001000, 0x00001000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 002ch + 0x00000000, 0x00001100, 0x00001000, 0x00000100, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 002dh + 0x01111111, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 002eh + 0x00000000, 0x00000000, 0x00000000, 0x00001100, + 0x00000000, 0x01000000, 0x00100000, 0x00010000, // 002fh + 0x00001000, 0x00000100, 0x00000010, 0x00000001, + 0x00000000, 0x00111110, 0x01000001, 0x01000001, // 0030h + 0x01000001, 0x01000001, 0x01000001, 0x00111110, + 0x00000000, 0x00011100, 0x00010000, 0x00010000, // 0031h + 0x00010000, 0x00010000, 0x00010000, 0x00010000, + 0x00000000, 0x00111110, 0x01000001, 0x01000000, // 0032h + 0x00111110, 0x00000001, 0x00000001, 0x01111111, + 0x00000000, 0x00111110, 0x01000001, 0x01000000, // 0033h + 0x00111110, 0x01000000, 0x01000001, 0x00111110, + 0x00000000, 0x00100000, 0x00110000, 0x00101000, // 0034h + 0x00100100, 0x00100010, 0x01111111, 0x00100000, + 0x00000000, 0x01111111, 0x00000001, 0x00111111, // 0035h + 0x01000000, 0x01000000, 0x01000001, 0x00111110, + 0x00000000, 0x00111110, 0x00000001, 0x00111111, // 0036h + 0x01000001, 0x01000001, 0x01000001, 0x00111110, + 0x00000000, 0x01111111, 0x00100000, 0x00100000, // 0037h + 0x00010000, 0x00010000, 0x00001000, 0x00001000, + 0x00000000, 0x00111110, 0x01000001, 0x01000001, // 0038h + 0x00111110, 0x01000001, 0x01000001, 0x00111110, + 0x00000000, 0x00111110, 0x01000001, 0x01000001, // 0039h + 0x01000001, 0x01111110, 0x01000000, 0x00111110, + 0x00000000, 0x00000000, 0x00001100, 0x00000000, // 003ah + 0x00000000, 0x00000000, 0x00001100, 0x00000000, + 0x00000000, 0x00000000, 0x00001100, 0x00000000, // 003bh + 0x00000000, 0x00001100, 0x00001000, 0x00000100, + 0x00000000, 0x01100000, 0x00011000, 0x00000110, // 003ch + 0x00000001, 0x00000110, 0x00011000, 0x01100000, + 0x00000000, 0x00000000, 0x01111111, 0x00000000, // 003dh + 0x00000000, 0x00000000, 0x01111111, 0x00000000, + 0x00000000, 0x00000011, 0x00001100, 0x00110000, // 003eh + 0x01000000, 0x00110000, 0x00001100, 0x00000011, + 0x00000000, 0x00111110, 0x01000001, 0x01000001, // 003fh + 0x00110000, 0x00001000, 0x00000000, 0x00001000, + 0x00000000, 0x00011100, 0x00100010, 0x01001001, // 0040h + 0x01010101, 0x01010101, 0x01010101, 0x00111010, + 0x00000000, 0x00001000, 0x00010100, 0x00010100, // 0041h + 0x00100010, 0x00111110, 0x01000001, 0x01000001, + 0x00000000, 0x00111111, 0x01000001, 0x01000001, // 0042h + 0x00111111, 0x01000001, 0x01000001, 0x00111111, + 0x00000000, 0x00111100, 0x01000010, 0x00000001, // 0043h + 0x00000001, 0x00000001, 0x01000010, 0x00111100, + 0x00000000, 0x00011111, 0x00100001, 0x01000001, // 0044h + 0x01000001, 0x01000001, 0x00100001, 0x00011111, + 0x00000000, 0x01111111, 0x00000001, 0x00000001, // 0045h + 0x01111111, 0x00000001, 0x00000001, 0x01111111, + 0x00000000, 0x01111111, 0x00000001, 0x00000001, // 0046h + 0x00111111, 0x00000001, 0x00000001, 0x00000001, + 0x00000000, 0x00111100, 0x01000010, 0x00000001, // 0047h + 0x01111001, 0x01000001, 0x01000010, 0x00111100, + 0x00000000, 0x01000001, 0x01000001, 0x01000001, // 0048h + 0x01111111, 0x01000001, 0x01000001, 0x01000001, + 0x00000000, 0x00111110, 0x00001000, 0x00001000, // 0049h + 0x00001000, 0x00001000, 0x00001000, 0x00111110, + 0x00000000, 0x01000000, 0x01000000, 0x01000000, // 004ah + 0x01000001, 0x01000001, 0x00100010, 0x00011100, + 0x00000000, 0x01100001, 0x00011001, 0x00000101, // 004bh + 0x00000011, 0x00000101, 0x00011001, 0x01100001, + 0x00000000, 0x00000001, 0x00000001, 0x00000001, // 004ch + 0x00000001, 0x00000001, 0x00000001, 0x01111111, + 0x00000000, 0x01000001, 0x01100011, 0x01010101, // 004dh + 0x01001001, 0x01000001, 0x01000001, 0x01000001, + 0x00000000, 0x01000001, 0x01000011, 0x01000101, // 004eh + 0x01001001, 0x01010001, 0x01100001, 0x01000001, + 0x00000000, 0x00011100, 0x00100010, 0x01000001, // 004fh + 0x01000001, 0x01000001, 0x00100010, 0x00011100, + 0x00000000, 0x00111111, 0x01000001, 0x01000001, // 0050h + 0x00111111, 0x00000001, 0x00000001, 0x00000001, + 0x00000000, 0x00011100, 0x00100010, 0x01000001, // 0051h + 0x01000001, 0x01011001, 0x00100010, 0x01011100, + 0x00000000, 0x00111111, 0x01000001, 0x01000001, // 0052h + 0x00111111, 0x01000001, 0x01000001, 0x01000001, + 0x00000000, 0x00111110, 0x01000001, 0x00000001, // 0053h + 0x00111110, 0x01000000, 0x01000001, 0x00111110, + 0x00000000, 0x01111111, 0x00001000, 0x00001000, // 0054h + 0x00001000, 0x00001000, 0x00001000, 0x00001000, + 0x00000000, 0x01000001, 0x01000001, 0x01000001, // 0055h + 0x01000001, 0x01000001, 0x00100010, 0x00011100, + 0x00000000, 0x01000001, 0x01000001, 0x00100010, // 0056h + 0x00100010, 0x00010100, 0x00010100, 0x00001000, + 0x00000000, 0x01000001, 0x01000001, 0x01000001, // 0057h + 0x01001001, 0x01010101, 0x01100011, 0x01000001, + 0x00000000, 0x01000001, 0x00100010, 0x00010100, // 0058h + 0x00001000, 0x00010100, 0x00100010, 0x01000001, + 0x00000000, 0x01000001, 0x00100010, 0x00010100, // 0059h + 0x00001000, 0x00001000, 0x00001000, 0x00001000, + 0x00000000, 0x01111111, 0x00100000, 0x00010000, // 005ah + 0x00001000, 0x00000100, 0x00000010, 0x01111111, + 0x00000000, 0x01111100, 0x00000100, 0x00000100, // 005bh + 0x00000100, 0x00000100, 0x00000100, 0x01111100, + 0x00000000, 0x00100010, 0x00010100, 0x00111110, // 005ch + 0x00001000, 0x00111110, 0x00001000, 0x00001000, + 0x00000000, 0x00011111, 0x00010000, 0x00010000, // 005dh + 0x00010000, 0x00010000, 0x00010000, 0x00011111, + 0x00000000, 0x00001000, 0x00010100, 0x00100010, // 005eh + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 005fh + 0x00000000, 0x00000000, 0x00000000, 0x01111111, + 0x00000000, 0x00010000, 0x00001000, 0x00011000, // 0060h + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00011110, 0x00100001, // 0061h + 0x00111110, 0x00100001, 0x00100001, 0x01011110, + 0x00000000, 0x00000001, 0x00000001, 0x00111111, // 0062h + 0x01000001, 0x01000001, 0x01000001, 0x00111111, + 0x00000000, 0x00000000, 0x00111100, 0x01000010, // 0063h + 0x00000001, 0x00000001, 0x01000010, 0x00111100, + 0x00000000, 0x01000000, 0x01000000, 0x01111110, // 0064h + 0x01000001, 0x01000001, 0x01000001, 0x01111110, + 0x00000000, 0x00000000, 0x00111110, 0x01000001, // 0065h + 0x01111111, 0x00000001, 0x01000001, 0x00111110, + 0x00000000, 0x00110000, 0x00001000, 0x00001000, // 0066h + 0x01111111, 0x00001000, 0x00001000, 0x00001000, + 0x00000000, 0x00000000, 0x01111110, 0x01000001, // 0067h + 0x01000001, 0x01111110, 0x01000000, 0x00111110, + 0x00000000, 0x00000001, 0x00000001, 0x00000001, // 0068h + 0x00111111, 0x01000001, 0x01000001, 0x01000001, + 0x00000000, 0x00001000, 0x00000000, 0x00001000, // 0069h + 0x00001000, 0x00001000, 0x00001000, 0x00001000, + 0x00000000, 0x00100000, 0x00000000, 0x00100000, // 006ah + 0x00100000, 0x00100001, 0x00100001, 0x00011110, + 0x00000000, 0x00000001, 0x00000001, 0x01100001, // 006bh + 0x00011001, 0x00000111, 0x00011001, 0x01100001, + 0x00000000, 0x00001000, 0x00001000, 0x00001000, // 006ch + 0x00001000, 0x00001000, 0x00001000, 0x00001000, + 0x00000000, 0x00000000, 0x00110111, 0x01001001, // 006dh + 0x01001001, 0x01001001, 0x01001001, 0x01001001, + 0x00000000, 0x00000000, 0x00111111, 0x01000001, // 006eh + 0x01000001, 0x01000001, 0x01000001, 0x01000001, + 0x00000000, 0x00000000, 0x00011100, 0x00100010, // 006fh + 0x01000001, 0x01000001, 0x00100010, 0x00011100, + 0x00000000, 0x00000000, 0x00111101, 0x01000011, // 0070h + 0x01000001, 0x01000011, 0x00111101, 0x00000001, + 0x00000000, 0x00000000, 0x01011110, 0x01100001, // 0071h + 0x01000001, 0x01100001, 0x01011110, 0x01000000, + 0x00000000, 0x00000000, 0x00110001, 0x00001101, // 0072h + 0x00000011, 0x00000001, 0x00000001, 0x00000001, + 0x00000000, 0x00000000, 0x00111110, 0x01000001, // 0073h + 0x00001110, 0x00110000, 0x01000001, 0x00111110, + 0x00000000, 0x00000100, 0x00000100, 0x01111111, // 0074h + 0x00000100, 0x00000100, 0x00000100, 0x01111000, + 0x00000000, 0x00000000, 0x01000001, 0x01000001, // 0075h + 0x01000001, 0x01000001, 0x01000001, 0x01111110, + 0x00000000, 0x00000000, 0x01000001, 0x01000001, // 0076h + 0x00100010, 0x00100010, 0x00010100, 0x00001000, + 0x00000000, 0x00000000, 0x01000001, 0x01000001, // 0077h + 0x01001001, 0x00101010, 0x00101010, 0x00010100, + 0x00000000, 0x00000000, 0x00100001, 0x00010010, // 0078h + 0x00001100, 0x00001100, 0x00010010, 0x00100001, + 0x00000000, 0x00000000, 0x01000001, 0x01000001, // 0079h + 0x00100010, 0x00011100, 0x00001000, 0x00000110, + 0x00000000, 0x00000000, 0x00111111, 0x00010000, // 007ah + 0x00001000, 0x00000100, 0x00000010, 0x00111111, + 0x00000000, 0x00001000, 0x00011110, 0x01100100, // 007bh + 0x00011000, 0x00100100, 0x00000100, 0x01111000, + 0x00000000, 0x00000000, 0x00011110, 0x00000100, // 007ch + 0x00011110, 0x00110101, 0x00101101, 0x00010010, + 0x00000000, 0x00000000, 0x00000000, 0x00010001, // 007dh + 0x00100001, 0x00100001, 0x00000001, 0x00000010, + 0x00000000, 0x00000000, 0x00011100, 0x00000000, // 007eh + 0x00011110, 0x00100000, 0x00100000, 0x00011100, + 0x00000000, 0x00000000, 0x00011100, 0x00000000, // 007fh + 0x00111110, 0x00010000, 0x00001100, 0x00110010, + 0x00000000, 0x00000000, 0x00000100, 0x00101111, // 0080h + 0x01000100, 0x00011110, 0x00100101, 0x00010110, + 0x00000000, 0x00000000, 0x00001010, 0x00011110, // 0081h + 0x00101011, 0x00100010, 0x00010100, 0x00000100, + 0x00000000, 0x00000000, 0x00001000, 0x00011101, // 0082h + 0x00101011, 0x00101001, 0x00011001, 0x00000100, + 0x00000000, 0x00000000, 0x00001000, 0x00111000, // 0083h + 0x00001000, 0x00011110, 0x00101001, 0x00000110, + 0x00000000, 0x00000000, 0x00000000, 0x00011100, // 0084h + 0x00100011, 0x00100000, 0x00100000, 0x00011100, + 0x00000000, 0x00000110, 0x01001001, 0x00110000, // 0085h + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000100, 0x00111111, 0x00000100, // 0086h + 0x00111110, 0x01010101, 0x01001101, 0x00100110, + 0x00000000, 0x00000000, 0x00100001, 0x01000001, // 0087h + 0x01000001, 0x01000001, 0x00000001, 0x00000010, + 0x00000000, 0x00111100, 0x00000000, 0x00111110, // 0088h + 0x01000000, 0x01000000, 0x00100000, 0x00011100, + 0x00000000, 0x00011100, 0x00000000, 0x00111110, // 0089h + 0x00010000, 0x00001000, 0x00010100, 0x01100010, + 0x00000000, 0x00100100, 0x01011111, 0x00000100, // 008ah + 0x00111110, 0x01000101, 0x01000101, 0x00100010, + 0x00000000, 0x00100010, 0x01001111, 0x01010010, // 008bh + 0x01010010, 0x00010010, 0x00010010, 0x00001001, + 0x00000000, 0x00000100, 0x00111110, 0x00001000, // 008ch + 0x00111110, 0x00010000, 0x00000010, 0x00111100, + 0x00000000, 0x00100000, 0x00011000, 0x00000110, // 008dh + 0x00000001, 0x00000110, 0x00011000, 0x00100000, + 0x00000000, 0x00100000, 0x01111101, 0x00100001, // 008eh + 0x00100001, 0x00100001, 0x00100001, 0x00010010, + 0x00000000, 0x00011110, 0x00100000, 0x00000000, // 008fh + 0x00000000, 0x00000001, 0x00000001, 0x00111110, + 0x00000000, 0x00001000, 0x01111111, 0x00010000, // 0090h + 0x00100000, 0x00000010, 0x00000010, 0x00111100, + 0x00000000, 0x00000001, 0x00000001, 0x00000001, // 0091h + 0x01000001, 0x01000001, 0x00100010, 0x00011100, + 0x00000000, 0x00010000, 0x01111111, 0x00011000, // 0092h + 0x00010100, 0x00010100, 0x00011000, 0x00001100, + 0x00000000, 0x00100010, 0x01111111, 0x00100010, // 0093h + 0x00100010, 0x00000010, 0x00000010, 0x01111100, + 0x00000000, 0x00111100, 0x00010000, 0x00001100, // 0094h + 0x01111111, 0x00001000, 0x00001000, 0x00110000, + 0x00000000, 0x00000100, 0x00011111, 0x00000100, // 0095h + 0x01110100, 0x00000010, 0x00001010, 0x01110010, + 0x00000000, 0x00001000, 0x01111111, 0x00000100, // 0096h + 0x00111100, 0x01000010, 0x01000000, 0x00111100, + 0x00000000, 0x00000000, 0x00011100, 0x00100011, // 0097h + 0x01000000, 0x01000000, 0x00100000, 0x00011100, + 0x00000000, 0x01111111, 0x00010000, 0x00001000, // 0098h + 0x00001000, 0x00001000, 0x00001000, 0x00110000, + 0x00000000, 0x00000010, 0x00110010, 0x00001100, // 0099h + 0x00000010, 0x00000001, 0x00000001, 0x00111110, + 0x00000000, 0x00100100, 0x01001111, 0x01000010, // 009ah + 0x00010001, 0x00111100, 0x00010010, 0x00001100, + 0x00000000, 0x00000010, 0x01111010, 0x01000010, // 009bh + 0x00000010, 0x00000010, 0x00001010, 0x01110010, + 0x00000000, 0x00100010, 0x00111110, 0x01010010, // 009ch + 0x01001011, 0x01101101, 0x01010101, 0x00110010, + 0x00000000, 0x00110010, 0x01001011, 0x01000110, // 009dh + 0x01000110, 0x01110010, 0x01001011, 0x00110010, + 0x00000000, 0x00011100, 0x00101010, 0x01001001, // 009eh + 0x01001001, 0x01000101, 0x01000101, 0x00110010, + 0x00000000, 0x00100001, 0x01111101, 0x00100001, // 009fh + 0x00100001, 0x00111001, 0x01100101, 0x00011001, + 0x00000000, 0x00000100, 0x00100011, 0x01100010, // 00a0h + 0x00100001, 0x00100001, 0x00010010, 0x00001100, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 00a1h + 0x00000000, 0x00000100, 0x00001010, 0x00000100, + 0x00000000, 0x01110000, 0x00010000, 0x00010000, // 00a2h + 0x00010000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 00a3h + 0x00001000, 0x00001000, 0x00001000, 0x00001110, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 00a4h + 0x00000000, 0x00000010, 0x00000100, 0x00000100, + 0x00000000, 0x00000000, 0x00000000, 0x00011000, // 00a5h + 0x00011000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x01111111, 0x01000000, 0x01111111, // 00a6h + 0x01000000, 0x01000000, 0x00100000, 0x00011100, + 0x00000000, 0x00000000, 0x00111111, 0x00100000, // 00a7h + 0x00010100, 0x00001100, 0x00000100, 0x00000010, + 0x00000000, 0x00000000, 0x00100000, 0x00100000, // 00a8h + 0x00010000, 0x00001111, 0x00001000, 0x00001000, + 0x00000000, 0x00000000, 0x00000100, 0x00111111, // 00a9h + 0x00100001, 0x00100000, 0x00010000, 0x00001100, + 0x00000000, 0x00000000, 0x00000000, 0x00111110, // 00aah + 0x00001000, 0x00001000, 0x00001000, 0x01111111, + 0x00000000, 0x00000000, 0x00010000, 0x00111111, // 00abh + 0x00011000, 0x00010100, 0x00010010, 0x00011001, + 0x00000000, 0x00000000, 0x00000010, 0x00111111, // 00ach + 0x00100010, 0x00010010, 0x00000100, 0x00000100, + 0x00000000, 0x00000000, 0x00000000, 0x00111110, // 00adh + 0x00100000, 0x00100000, 0x00100000, 0x01111111, + 0x00000000, 0x00000000, 0x00111110, 0x00100000, // 00aeh + 0x00111110, 0x00100000, 0x00100000, 0x00111110, + 0x00000000, 0x00000000, 0x00100101, 0x00101010, // 00afh + 0x00101010, 0x00100000, 0x00010000, 0x00001110, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 00b0h + 0x01111111, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x01111111, 0x01000000, 0x00101000, // 00b1h + 0x00011000, 0x00001000, 0x00001000, 0x00000100, + 0x00000000, 0x01000000, 0x00100000, 0x00011000, // 00b2h + 0x00010111, 0x00010000, 0x00010000, 0x00010000, + 0x00000000, 0x00001000, 0x01111111, 0x01000001, // 00b3h + 0x01000001, 0x01000000, 0x00100000, 0x00011000, + 0x00000000, 0x00000000, 0x00111110, 0x00001000, // 00b4h + 0x00001000, 0x00001000, 0x00001000, 0x01111111, + 0x00000000, 0x00100000, 0x01111111, 0x00110000, // 00b5h + 0x00101000, 0x00100100, 0x00100010, 0x00110001, + 0x00000000, 0x00000100, 0x01111111, 0x01000100, // 00b6h + 0x01000100, 0x01000100, 0x01000010, 0x00100001, + 0x00000000, 0x00000100, 0x00111111, 0x00001000, // 00b7h + 0x01111111, 0x00010000, 0x00010000, 0x00010000, + 0x00000000, 0x01111100, 0x01000100, 0x01000100, // 00b8h + 0x01000010, 0x01000000, 0x00100000, 0x00011000, + 0x00000000, 0x00000010, 0x01111110, 0x00100010, // 00b9h + 0x00100001, 0x00100000, 0x00010000, 0x00001100, + 0x00000000, 0x01111110, 0x01000000, 0x01000000, // 00bah + 0x01000000, 0x01000000, 0x01000000, 0x01111110, + 0x00000000, 0x00100010, 0x01111111, 0x00100010, // 00bbh + 0x00100010, 0x00100000, 0x00010000, 0x00001100, + 0x00000000, 0x00000011, 0x00000100, 0x01000011, // 00bch + 0x01000100, 0x00100000, 0x00011000, 0x00000111, + 0x00000000, 0x01111111, 0x01000000, 0x00100000, // 00bdh + 0x00010000, 0x00011000, 0x00100100, 0x01000011, + 0x00000000, 0x00000010, 0x01111111, 0x01000010, // 00beh + 0x00100010, 0x00000010, 0x00000010, 0x01111100, + 0x00000000, 0x01000001, 0x01000010, 0x01000000, // 00bfh + 0x00100000, 0x00100000, 0x00011000, 0x00000110, + 0x00000000, 0x01111110, 0x01000010, 0x01001110, // 00c0h + 0x01110001, 0x01000000, 0x00100000, 0x00011000, + 0x00000000, 0x01100000, 0x00011110, 0x00010000, // 00c1h + 0x01111111, 0x00010000, 0x00010000, 0x00001100, + 0x00000000, 0x01000101, 0x01001010, 0x01001010, // 00c2h + 0x01000000, 0x00100000, 0x00010000, 0x00001110, + 0x00000000, 0x00111110, 0x00000000, 0x01111111, // 00c3h + 0x00010000, 0x00010000, 0x00001000, 0x00000110, + 0x00000000, 0x00000010, 0x00000010, 0x00000110, // 00c4h + 0x00011010, 0x01100010, 0x00000010, 0x00000010, + 0x00000000, 0x00010000, 0x00010000, 0x01111111, // 00c5h + 0x00010000, 0x00010000, 0x00001000, 0x00000110, + 0x00000000, 0x00000000, 0x00111110, 0x00000000, // 00c6h + 0x00000000, 0x00000000, 0x00000000, 0x01111111, + 0x00000000, 0x01111110, 0x01000000, 0x01000100, // 00c7h + 0x00101000, 0x00010000, 0x00101000, 0x01000110, + 0x00000000, 0x00001000, 0x01111111, 0x00100000, // 00c8h + 0x00010000, 0x00011100, 0x01101011, 0x00001000, + 0x00000000, 0x01000000, 0x01000000, 0x01000000, // 00c9h + 0x00100000, 0x00100000, 0x00011000, 0x00000111, + 0x00000000, 0x00010010, 0x00100010, 0x00100010, // 00cah + 0x01000010, 0x01000010, 0x01000001, 0x01000001, + 0x00000000, 0x00000001, 0x00000001, 0x01111111, // 00cbh + 0x00000001, 0x00000001, 0x00000001, 0x01111110, + 0x00000000, 0x01111111, 0x01000000, 0x01000000, // 00cch + 0x01000000, 0x00100000, 0x00010000, 0x00001110, + 0x00000000, 0x00000000, 0x00000100, 0x00001010, // 00cdh + 0x00010001, 0x00100001, 0x01000000, 0x00000000, + 0x00000000, 0x00001000, 0x00001000, 0x01111111, // 00ceh + 0x00001000, 0x00101010, 0x01001010, 0x01001001, + 0x00000000, 0x01111111, 0x01000000, 0x01000000, // 00cfh + 0x00100010, 0x00010100, 0x00001000, 0x00010000, + 0x00000000, 0x00001110, 0x01110000, 0x00001110, // 00d0h + 0x01110000, 0x00000110, 0x00011000, 0x01100000, + 0x00000000, 0x00001000, 0x00001000, 0x00000100, // 00d1h + 0x00000100, 0x00100010, 0x01000010, 0x01111111, + 0x00000000, 0x01000000, 0x01000000, 0x00100100, // 00d2h + 0x00101000, 0x00010000, 0x00101100, 0x01000011, + 0x00000000, 0x01111111, 0x00000100, 0x01111111, // 00d3h + 0x00000100, 0x00000100, 0x00000100, 0x01111000, + 0x00000000, 0x00000010, 0x01111111, 0x01000010, // 00d4h + 0x00100010, 0x00010100, 0x00000100, 0x00000100, + 0x00000000, 0x00000000, 0x00111110, 0x00100000, // 00d5h + 0x00100000, 0x00100000, 0x00100000, 0x01111111, + 0x00000000, 0x01111110, 0x01000000, 0x01000000, // 00d6h + 0x01111110, 0x01000000, 0x01000000, 0x01111110, + 0x00000000, 0x00111110, 0x00000000, 0x01111111, // 00d7h + 0x01000000, 0x01000000, 0x00100000, 0x00011100, + 0x00000000, 0x01000010, 0x01000010, 0x01000010, // 00d8h + 0x01000010, 0x01000000, 0x00100000, 0x00011000, + 0x00000000, 0x00001010, 0x00001010, 0x00001010, // 00d9h + 0x01001010, 0x01001010, 0x00101010, 0x00011001, + 0x00000000, 0x00000010, 0x00000010, 0x01000010, // 00dah + 0x01000010, 0x00100010, 0x00010010, 0x00001110, + 0x00000000, 0x01111111, 0x01000001, 0x01000001, // 00dbh + 0x01000001, 0x01000001, 0x01000001, 0x01111111, + 0x00000000, 0x01111111, 0x01000001, 0x01000001, // 00dch + 0x01000000, 0x01000000, 0x00100000, 0x00011100, + 0x00000000, 0x01000011, 0x01000100, 0x01000000, // 00ddh + 0x01000000, 0x00100000, 0x00010000, 0x00001111, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 00deh 0 + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, // 00dfh 1 + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00011110, 0x00001000, 0x00000100, // 00e0h 2 + 0x00101001, 0x01010001, 0x01010001, 0x00001100, + 0x00000000, 0x00000000, 0x00001100, 0x00010010, // 00e1h 3 + 0x00010010, 0x00100001, 0x01000000, 0x00000000, + 0x00000000, 0x01111101, 0x00100001, 0x01111101, // 00e2h 4 + 0x00100001, 0x00111001, 0x01100101, 0x00011001, + 0x00000000, 0x00111100, 0x00010000, 0x00111100, // 00e3h 5 + 0x00010000, 0x00011100, 0x00110010, 0x00001100, + 0x00000000, 0x00001110, 0x00101000, 0x00101000, // 00e4h 6 + 0x00111110, 0x01100101, 0x00100101, 0x00010010, + 0x00000000, 0x00000100, 0x00101111, 0x01000100, // 00e5h 7 + 0x00000110, 0x01000101, 0x01000101, 0x00111110, + 0x00000000, 0x00100010, 0x00100010, 0x00111110, // 00e6h 8 + 0x01010010, 0x01010101, 0x01001101, 0x00100110, + 0x00000000, 0x00000100, 0x00011111, 0x00000010, // 00e7h 9 + 0x00011111, 0x01000010, 0x01000010, 0x00111100, + 0x00000000, 0x00010010, 0x00111110, 0x01010011, // 00e8h 10 + 0x01000010, 0x00100100, 0x00000100, 0x00000100, + 0x00000000, 0x00001000, 0x00111101, 0x01001011, // 00e9h 11 + 0x01001001, 0x01001001, 0x00111000, 0x00000100, + 0x00000000, 0x00001000, 0x00111000, 0x00001000, // 00eah 12 + 0x00001000, 0x00011110, 0x00101001, 0x00000110, + 0x00000000, 0x00011000, 0x00100000, 0x00000100, // 00ebh 13 + 0x00111010, 0x01000110, 0x01000000, 0x00111000, + 0x00000000, 0x01000010, 0x01000010, 0x01000010, // 00ech 14 + 0x01000110, 0x01000000, 0x00100000, 0x00011000, + 0x00000000, 0x00111110, 0x00010000, 0x00111100, // 00edh 15 + 0x01000011, 0x01001100, 0x01010010, 0x00111100, + 0x00000000, 0x00100010, 0x00110011, 0x00101010, // 00eeh 16 + 0x00100110, 0x00100010, 0x00100011, 0x01000010, + 0x00000000, 0x00111110, 0x00010000, 0x00111100, // 00efh 17 + 0x01000011, 0x01000000, 0x01000010, 0x00111100, + 0x00000000, 0x00000010, 0x00111011, 0x01000110, // 00f0h 18 + 0x01000010, 0x01000011, 0x01000010, 0x00110010, + 0x00000000, 0x00000100, 0x00000100, 0x00000010, // 00f1h 19 + 0x01000110, 0x01000101, 0x01000101, 0x00111001, + 0x00000000, 0x01010100, 0x01111111, 0x00100100, // 00f2h 20 + 0x00100100, 0x00100100, 0x00100010, 0x00010001, + 0x00000000, 0x01010100, 0x01011111, 0x00000100, // 00f3h 21 + 0x00111111, 0x00001000, 0x00001000, 0x00001000, + 0x00000000, 0x01011110, 0x01100010, 0x00100010, // 00f4h 22 + 0x00100001, 0x00100000, 0x00010000, 0x00001100, + 0x00000000, 0x01010010, 0x01111110, 0x00100010, // 00f5h 23 + 0x00100001, 0x00100000, 0x00010000, 0x00001100, + + 0x33330000, + 0x33330000, + 0x33000000, + 0x33000000, // 00f6h + 0x33000000, + 0x33000000, + 0x33330000, + 0x33330000, + + + 0x00020000, // 00f7h + 0x00020000, + 0x00020000, + 0x22222222, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + + 0x00000000, // 00f8h + 0x00000000, + 0x00000000, + 0x00000000, + 0x11111111, + 0x11111111, + 0x11111111, + 0x11111111, + + 0x11111111, // 00f9h + 0x11111111, + 0x11111111, + 0x11111111, + 0x11111111, + 0x11111111, + 0x11111111, + 0x11111111, + + 0x11111111, // 00fah + 0x11111111, + 0x11111111, + 0x11111111, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + + 0x00000000, // 00fbh + 0x00000000, + 0x00000000, + 0x22222222, + 0x00020000, + 0x00020000, + 0x00020000, + 0x00020000, + + 0x00020000, // 00fch + 0x00020000, + 0x00020000, + 0x22222222, + 0x00020000, + 0x00020000, + 0x00020000, + 0x00020000, + + 0x00020000, // 00fdh + 0x00020000, + 0x00020000, + 0x00020000, + 0x00020000, + 0x00020000, + 0x00020000, + 0x00020000, + + 0x00000000, // 00feh + 0x00000000, + 0x00000000, + 0x22222222, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + + 0x00020000, + 0x00220000, + 0x02122222, + 0x21111112, + 0x21111112, + 0x02122222, + 0x00220000, + 0x00020000, + + + +/* + 0x00022222, + 0x00002112, + 0x00021112, + 0x00211122, + 0x02111202, + 0x21112000, + 0x02120000, + 0x00200000, +*/ + +/* + 0x00000000, 0x01011110, 0x01010000, 0x00111111, // 00ffh + 0x00001000, 0x00001000, 0x00001000, 0x00000110 +*/ +}; + +/*---------------------------------------------------------------------------* + End of file + *---------------------------------------------------------------------------*/ diff --git a/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/graphics.c b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/graphics.c new file mode 100644 index 00000000..a6ecba8c --- /dev/null +++ b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/graphics.c @@ -0,0 +1,292 @@ +/*---------------------------------------------------------------------------* + Project: SystemUpdater + File: praphics.c + + Copyright 2008 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + $Date:: $ + $Rev$ + $Author$ + *---------------------------------------------------------------------------*/ + +#include +//#include +#include +#include "kami_font.h" +#include "graphics.h" + +/*---------------------------------------------------------------------------* + 関数定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + Name: InitGraphics + + Description: 表示の初期化処理 + + Arguments: None. + + Returns: None. + *---------------------------------------------------------------------------*/ +void +InitGraphics(void) +{ + GX_DispOff(); + GXS_DispOff(); + + //---- VRAM クリア + GX_SetBankForLCDC(GX_VRAM_LCDC_ALL); + MI_CpuClearFast((void *)HW_LCDC_VRAM, HW_LCDC_VRAM_SIZE); + + //---- OAMとパレットクリア + MI_CpuFillFast((void *)HW_OAM, 192, HW_OAM_SIZE); + MI_CpuClearFast((void *)HW_PLTT, HW_PLTT_SIZE); + MI_CpuFillFast((void *)HW_DB_OAM, 192, HW_DB_OAM_SIZE); + MI_CpuClearFast((void *)HW_DB_PLTT, HW_DB_PLTT_SIZE); + + //---- OBJバンクの設定 + GX_SetBankForOBJ(GX_VRAM_OBJ_128_A); + GX_SetBankForSubOBJ(GX_VRAM_SUB_OBJ_128_D); + + //---- BGバンクの設定 + GX_SetBankForBG(GX_VRAM_BG_128_B); + GX_SetBankForSubBG(GX_VRAM_SUB_BG_128_C); + + //---- 表示モード設定 + GX_SetGraphicsMode (GX_DISPMODE_GRAPHICS, GX_BGMODE_0, GX_BG0_AS_3D); + GX_SetVisiblePlane (GX_PLANEMASK_BG0 | GX_PLANEMASK_BG1 | GX_PLANEMASK_BG2 | GX_PLANEMASK_OBJ); + GXS_SetVisiblePlane(GX_PLANEMASK_BG0 | GX_PLANEMASK_OBJ); + + //---- 3D初期化 + G3X_Init(); + G3X_InitMtxStack(); + G2_SetBG0Priority(3); + G2_SetBG1Priority(2); + G2_SetBG2Priority(1); + G2_SetBG3Priority(0); + G3X_AlphaTest(FALSE, 0); + G3X_AntiAlias(TRUE); + G3X_EdgeMarking(FALSE); + G3X_SetFog(FALSE, (GXFogBlend)0, (GXFogSlope)0, 0); + G3X_SetClearColor(0, 0, 0x7fff, 63, FALSE); + G3_ViewPort(0, 0, 255, 191); + G3_MtxMode(GX_MTXMODE_POSITION_VECTOR); + + G3X_Reset(); + G3_Identity(); + G3_PolygonAttr(GX_LIGHTMASK_NONE, GX_POLYGONMODE_DECAL, GX_CULL_NONE, 0, 31, 0); + + //---- 32KバイトのOBJで2Dマップモードで使用 + GX_SetOBJVRamModeChar(GX_OBJVRAMMODE_CHAR_2D); + + // スクリーンオフセット及びキャラクターオフセットの設定 + GX_SetBGScrOffset(GX_BGSCROFFSET_0x00000); + GX_SetBGCharOffset(GX_BGCHAROFFSET_0x10000); + + G2_SetBG1Control( + GX_BG_SCRSIZE_TEXT_256x256, + GX_BG_COLORMODE_16, + GX_BG_SCRBASE_0x0000 , + GX_BG_CHARBASE_0x00000, + GX_BG_EXTPLTT_01 + ); + + G2_SetBG2ControlText( + GX_BG_SCRSIZE_TEXT_256x256, + GX_BG_COLORMODE_16, + GX_BG_SCRBASE_0x4000 , + GX_BG_CHARBASE_0x08000 + ); + + G2S_SetBG0Control( + GX_BG_SCRSIZE_TEXT_256x256, + GX_BG_COLORMODE_16, + GX_BG_SCRBASE_0x0000 , + GX_BG_CHARBASE_0x04000, + GX_BG_EXTPLTT_01 + ); + + G2S_SetBG1Control( + GX_BG_SCRSIZE_TEXT_256x256, + GX_BG_COLORMODE_16, + GX_BG_SCRBASE_0x2000 , + GX_BG_CHARBASE_0x04000, + GX_BG_EXTPLTT_01 + ); + + G2_BG1Mosaic(FALSE); + G2S_BG1Mosaic(FALSE); + + //---- データロード +// GX_LoadOBJ ( sampleCharData, 0, sizeof(sampleCharData)); +// GX_LoadBG1Char( sampleCharData, 0, sizeof(sampleCharData)); +// GX_LoadBGPltt ( PlttDataMain, 0, sizeof(PlttDataMain)); +// GX_LoadBG1Scr ( BgScDataMain, 0, sizeof(BgScDataMain)); +// GX_LoadOBJPltt( PlttDataObj, 0, sizeof(PlttDataObj)); + +// GXS_LoadOBJ ( sampleCharData, 0, sizeof(sampleCharData)); + GXS_LoadBG0Char( sampleCharData, 0, sizeof(sampleCharData)); + GXS_LoadBGPltt ( PlttDataSub, 0, sizeof(PlttDataSub)); +// GXS_LoadBG0Scr ( BgScDataSub, 0, sizeof(BgScDataSub)); + GXS_LoadOBJPltt( PlttDataObj, 0, sizeof(PlttDataObj)); + + GX_SetMasterBrightness(-16); + + GX_DispOn(); + GXS_DispOn(); +} + +/*---------------------------------------------------------------------------* + Name: DrawLine + + Description: 三角ポリゴンで線を描画 + + Arguments: sx - 描画する線の開始点のx座標 + sy - 描画する線の開始点のy座標 + ex - 描画する線の終点のx座標 + ey - 描画する線の終点のy座標 + color - 描画する線の色 + + Returns: None. + *---------------------------------------------------------------------------*/ +void +DrawLine(s16 sx, s16 sy, s16 ex, s16 ey, GXRgb color) +{ + fx16 fsx = (fx16)(((sx - 128) * 0x1000) / 128); + fx16 fsy = (fx16)(((96 - sy) * 0x1000) / 96); + fx16 fex = (fx16)(((ex - 128) * 0x1000) / 128); + fx16 fey = (fx16)(((96 - ey) * 0x1000) / 96); + + G3_Begin(GX_BEGIN_TRIANGLES); + { + G3_Color( color ); + G3_Vtx(fsx, fsy, 0); + G3_Color( color ); + G3_Vtx(fex, fey, 0); + G3_Color( color ); + G3_Vtx(fsx, fsy, 1); + } + G3_End(); +} + +/*---------------------------------------------------------------------------* + Name: DrawQuad + + Description: 四角ポリゴンを描画 + + Arguments: sx - 描画する線の開始点のx座標 + sy - 描画する線の開始点のy座標 + ex - 描画する線の終点のx座標 + ey - 描画する線の終点のy座標 + color - 描画する線の色 + + Returns: None. + *---------------------------------------------------------------------------*/ +void +DrawQuad(s16 sx, s16 sy, s16 ex, s16 ey, GXRgb color) +{ + fx16 fsx = (fx16)(((sx - 128) * 0x1000) / 128); + fx16 fsy = (fx16)(((96 - sy) * 0x1000) / 96); + fx16 fex = (fx16)(((ex - 128) * 0x1000) / 128); + fx16 fey = (fx16)(((96 - ey) * 0x1000) / 96); + + G3_Begin(GX_BEGIN_QUADS); + { + G3_Color( color ); + G3_Vtx(fsx, fsy, 0); + + G3_Color( color ); + G3_Vtx(fex, fsy, 0); + + G3_Color( color ); + G3_Vtx(fex, fey, 0); + + G3_Color( color ); + G3_Vtx(fsx, fey, 0); + } + G3_End(); +} + +/*---------------------------------------------------------------------------* + Name: DrawQuadWithColors + + Description: 四角ポリゴンを描画 + + Arguments: sx - 描画する線の開始点のx座標 + sy - 描画する線の開始点のy座標 + ex - 描画する線の終点のx座標 + ey - 描画する線の終点のy座標 + color - 描画する線の色 + + Returns: None. + *---------------------------------------------------------------------------*/ +void +DrawQuadWithColors(s16 sx, s16 sy, s16 ex, s16 ey, GXRgb color1, GXRgb color2) +{ + fx16 fsx = (fx16)(((sx - 128) * 0x1000) / 128); + fx16 fsy = (fx16)(((96 - sy) * 0x1000) / 96); + fx16 fex = (fx16)(((ex - 128) * 0x1000) / 128); + fx16 fey = (fx16)(((96 - ey) * 0x1000) / 96); + + G3_Begin(GX_BEGIN_QUADS); + { + G3_Color( color1 ); + G3_Vtx(fsx, fsy, 0); + + G3_Color( color2 ); + G3_Vtx(fex, fsy, 0); + + G3_Color( color2 ); + G3_Vtx(fex, fey, 0); + + G3_Color( color1 ); + G3_Vtx(fsx, fey, 0); + } + G3_End(); +} + +/*---------------------------------------------------------------------------* + Name: DrawQuad + + Description: 四角ポリゴンを描画 + + Arguments: sx - 描画する線の開始点のx座標 + sy - 描画する線の開始点のy座標 + ex - 描画する線の終点のx座標 + ey - 描画する線の終点のy座標 + color - 描画する線の色 + + Returns: None. + *---------------------------------------------------------------------------*/ +void +DrawQuadWithAlpha(s16 sx, s16 sy, s16 ex, s16 ey, GXRgb color, s16 alpha) +{ + fx16 fsx = (fx16)(((sx - 128) * 0x1000) / 128); + fx16 fsy = (fx16)(((96 - sy) * 0x1000) / 96); + fx16 fex = (fx16)(((ex - 128) * 0x1000) / 128); + fx16 fey = (fx16)(((96 - ey) * 0x1000) / 96); + + G3_PolygonAttr(GX_LIGHTMASK_NONE, GX_POLYGONMODE_DECAL, GX_CULL_NONE, 0, alpha, 0); + + G3_Begin(GX_BEGIN_QUADS); + { + G3_Color( color ); + G3_Vtx(fsx, fsy, 0); + + G3_Color( color ); + G3_Vtx(fex, fsy, 0); + + G3_Color( color ); + G3_Vtx(fex, fey, 0); + + G3_Color( color ); + G3_Vtx(fsx, fey, 0); + } + G3_End(); +} diff --git a/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/hw_info.c b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/hw_info.c new file mode 100644 index 00000000..4e7dea2a --- /dev/null +++ b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/hw_info.c @@ -0,0 +1,147 @@ +/*---------------------------------------------------------------------------* + Project: TwlSDK - SystemUpdater + File: hw_info.c + + Copyright 2008 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + $Date:: $ + $Rev$ + $Author$ + *---------------------------------------------------------------------------*/ + +#include +#include +#include +#include +#include +#include +#include "kami_font.h" +#include "kami_pxi.h" +#include "hwi.h" +#include "hw_info.h" +// +#include "TWLHWInfo_api.h" +#include "TWLSettings_api.h" +// +/*---------------------------------------------------------------------------* + 型定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + 定数定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + 内部変数定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + 内部関数宣言 + *---------------------------------------------------------------------------*/ + +BOOL WriteHWNormalInfoFile( void ); +BOOL WriteHWSecureInfoFile( u8 region ); +BOOL DeleteHWInfoFile( void ); + +/*---------------------------------------------------------------------------* + Name: HW情報全体のライト + + Description: + + Arguments: region : + + Returns: None. + *---------------------------------------------------------------------------*/ + +BOOL WriteHWInfoFile( u8 region, BOOL wirelessForceOff ) +{ + static const char *pMsgSecureWriting = "Writing Secure File...\n"; + static const char *pMsgNormalWriting = "Writing Normal File...\n"; + static const char *pMsgSignWriting = "Writing Sign File...\n"; + static const char *pMsgSucceeded = "Success!\n"; + static const char *pMsgFailed = "Failed!\n"; + u32 installedSoftBoxCount = 0; + BOOL result = TRUE; + + // セキュアファイルのライト + if( HWI_WriteHWSecureInfoFile( region, NULL, wirelessForceOff ) ) { // とりあえず無線は有効で。 +// kamiFontPrintfConsoleEx(CONSOLE_ORANGE, pMsgSucceeded ); + }else { + kamiFontPrintfConsoleEx(CONSOLE_RED, pMsgFailed ); + result = FALSE; + } + + // ノーマルファイルのライト(移行可能なユニークIDのためにセキュアファイルの後で書き込む) + if( HWI_WriteHWNormalInfoFile() ) { +// kamiFontPrintfConsoleEx(CONSOLE_ORANGE, pMsgSucceeded ); + }else { + kamiFontPrintfConsoleEx(CONSOLE_RED, pMsgFailed ); + result = FALSE; + } + + // HWID署名ファイルのライト + if( HWI_WriteHWIDSignFile() ) { +// kamiFontPrintfConsoleEx(CONSOLE_ORANGE, pMsgSucceeded ); + }else { + kamiFontPrintfConsoleEx(CONSOLE_RED, pMsgFailed ); + result = FALSE; + } + + // CFGデータの修正 + if (!HWI_ModifyLanguage( region )) + { + kamiFontPrintfConsoleEx(CONSOLE_RED, "Fail! Write TWLSettings\n" ); + result = FALSE; + } + + return result; +} + +/*---------------------------------------------------------------------------* + Name: HWInfoファイルの削除 + + Description: + + Arguments: None. + + Returns: None. + *---------------------------------------------------------------------------*/ + +BOOL DeleteHWInfoFile( void ) +{ + static const char *pMsgNormalDeleting = "Deleting Normal File...\n"; + static const char *pMsgSecureDeleting = "Deteting Secure File...\n"; + static const char *pMsgSucceeded = "Success!\n"; + static const char *pMsgFailed = "Failed!\n"; + BOOL result = TRUE; + + // ノーマルファイル + kamiFontPrintfConsoleEx(CONSOLE_ORANGE, pMsgNormalDeleting ); + if( HWI_DeleteHWNormalInfoFile() ) { + OS_TPrintf( "%s delete succeeded.\n", (char *)LCFG_TWL_HWINFO_NORMAL_PATH ); + kamiFontPrintfConsoleEx(CONSOLE_ORANGE, pMsgSucceeded ); + }else { + OS_TPrintf( "%s delete failed.\n", (char *)LCFG_TWL_HWINFO_NORMAL_PATH ); + kamiFontPrintfConsoleEx(CONSOLE_RED, pMsgFailed ); + result = FALSE; + } + + // セキュアファイル + kamiFontPrintfConsoleEx(CONSOLE_ORANGE, pMsgSecureDeleting ); + if( HWI_DeleteHWSecureInfoFile() ) { + OS_TPrintf( "%s delete succeeded.\n", (char *)LCFG_TWL_HWINFO_SECURE_PATH ); + kamiFontPrintfConsoleEx(CONSOLE_ORANGE, pMsgSucceeded ); + }else { + OS_TPrintf( "%s delete failed.\n", (char *)LCFG_TWL_HWINFO_SECURE_PATH ); + kamiFontPrintfConsoleEx(CONSOLE_RED, pMsgFailed ); + result = FALSE; + } + + return result; +} diff --git a/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/kami_copy_file.c b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/kami_copy_file.c new file mode 100644 index 00000000..3bd2dee7 --- /dev/null +++ b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/kami_copy_file.c @@ -0,0 +1,135 @@ +/*---------------------------------------------------------------------------* + Project: TwlSDK - NandInitializer + File: kami_copy_file.c + + Copyright 2008 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + $Date:: $ + $Rev$ + $Author$ + *---------------------------------------------------------------------------*/ + +#include +#include +#include +#include +#include "kami_font.h" +#include "kami_copy_file.h" + +/*---------------------------------------------------------------------------* + マクロ + *---------------------------------------------------------------------------*/ + +#define ROUND_UP(value, alignment) \ + (((u32)(value) + (alignment-1)) & ~(alignment-1)) + +/*---------------------------------------------------------------------------* + 処理関数定義 + *---------------------------------------------------------------------------*/ + +BOOL kamiCopyFile(char* srcPath, char* dstPath) +{ + FSFile file; + BOOL open_is_ok; + BOOL read_is_ok; + void* pTempBuf; + u32 file_size; + u32 alloc_size; + BOOL result = TRUE; + + // ROMファイルオープン + FS_InitFile(&file); + open_is_ok = FS_OpenFile(&file, srcPath); + if (!open_is_ok) + { + OS_Printf("FS_OpenFile(\"%s\") ... ERROR!\n", srcPath); + return FALSE; + } + + // ROMファイルリード + file_size = FS_GetFileLength(&file) ; + alloc_size = ROUND_UP(file_size, 32) ; + pTempBuf = OS_Alloc( alloc_size ); + SDK_NULL_ASSERT(pTempBuf); + DC_InvalidateRange(pTempBuf, alloc_size); + read_is_ok = FS_ReadFile( &file, pTempBuf, (s32)file_size ); + if (!read_is_ok) + { + kamiFontPrintfConsoleEx(CONSOLE_RED, "FS_ReadFile(\"%s\") ... ERROR!\n", srcPath); + FS_CloseFile(&file); + OS_Free(pTempBuf); + return FALSE; + } + + // ROMファイルクローズ + FS_CloseFile(&file); + + // 一旦対象データを削除する + (void)FS_DeleteFile(dstPath); + + // ターゲットファイル作成 + if (!FS_CreateFileAuto(dstPath, FS_PERMIT_R | FS_PERMIT_W)) + { + kamiFontPrintfConsoleEx(CONSOLE_RED, "FS_CreateFile(%s) failed.\n", dstPath); + result = FALSE; + } + else + { + // ターゲットファイルオープン + FS_InitFile(&file); + open_is_ok = FS_OpenFileEx(&file, dstPath, FS_FILEMODE_W); + if (!open_is_ok) + { + kamiFontPrintfConsoleEx(CONSOLE_RED, "FS_OpenFile(%s) failed.\n", dstPath); + result = FALSE; + } + // ターゲットファイルへ書き込み + else if (FS_WriteFile(&file, pTempBuf, (s32)file_size) == -1) + { + kamiFontPrintfConsoleEx(CONSOLE_RED, "FS_WritFile() failed.\n"); + result = FALSE; + } + (void)FS_CloseFile(&file); + } + + OS_Free(pTempBuf); + + return result; +} + +// ダミーのDSメニューラッピング用ファイル作成(UIGランチャーが作っているもの) +BOOL kamiWriteWrapData(void) +{ + FSFile file; + BOOL open_is_ok; + const int FATFS_CLUSTER_SIZE = 16 * 1024; + + // 既に存在するなら何もしない + FS_InitFile(&file); + open_is_ok = FS_OpenFile(&file, WRAP_DATA_FILE_PATH_IN_NAND); + if (open_is_ok) + { + FS_CloseFile(&file); + OS_Printf("%s is already exist.\n", WRAP_DATA_FILE_PATH_IN_NAND); + return TRUE; + } + + if( FS_CreateFileAuto( WRAP_DATA_FILE_PATH_IN_NAND, FS_PERMIT_R | FS_PERMIT_W ) ) + { + FSFile file; + if( FS_OpenFileEx( &file, WRAP_DATA_FILE_PATH_IN_NAND, FS_FILEMODE_RW ) ) + { + (void)FS_SetFileLength( &file, FATFS_CLUSTER_SIZE ); + FS_CloseFile( &file ); + return TRUE; + } + } + + return FALSE; +} diff --git a/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/kami_font.c b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/kami_font.c new file mode 100644 index 00000000..cfb7262c --- /dev/null +++ b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/kami_font.c @@ -0,0 +1,407 @@ +/*---------------------------------------------------------------------------* + Project: TwlSDK - NandInitializer + File: kami_font.c + + Copyright 2008 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + $Date:: $ + $Rev$ + $Author$ + *---------------------------------------------------------------------------*/ + +#include +#include "kami_font.h" + +/*---------------------------------------------------------------------------* + 型定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + 定数定義 + *---------------------------------------------------------------------------*/ + +#define SCREEN_DATA_COLOR_PLTT_SHIFT 12 +#define NUM_OF_PRINT_TARGET 2 + +/*---------------------------------------------------------------------------* + 内部変数定義 + *---------------------------------------------------------------------------*/ + +static u8 sXPos; +static u8 sYPos; + +static u32 sBackColorCharData[24*8]; + +static u16 sFontScreenDataMain[32 * 24] = { + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +}; + +static u16 sFontScreenDataSub[24*32] = { + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +}; + +static u16 sBackColorScreenData[32 * 24] = { + 0xf0de,0xf0de,0xf0de,0xf0de,0xf0de,0xf0de,0xf0de,0xf0de,0xf0de,0xf0de,0xf0de,0xf0de,0xf0de,0xf0de,0xf0de,0xf0de,0xf0de,0xf0de,0xf0de,0xf0de,0xf0de,0xf0de,0xf0de,0xf0de,0xf0de,0xf0de,0xf0de,0xf0de,0xf0de,0xf0de,0xf0de,0xf0de, + 0xf0df,0xf0df,0xf0df,0xf0df,0xf0df,0xf0df,0xf0df,0xf0df,0xf0df,0xf0df,0xf0df,0xf0df,0xf0df,0xf0df,0xf0df,0xf0df,0xf0df,0xf0df,0xf0df,0xf0df,0xf0df,0xf0df,0xf0df,0xf0df,0xf0df,0xf0df,0xf0df,0xf0df,0xf0df,0xf0df,0xf0df,0xf0df, + 0xf0e0,0xf0e0,0xf0e0,0xf0e0,0xf0e0,0xf0e0,0xf0e0,0xf0e0,0xf0e0,0xf0e0,0xf0e0,0xf0e0,0xf0e0,0xf0e0,0xf0e0,0xf0e0,0xf0e0,0xf0e0,0xf0e0,0xf0e0,0xf0e0,0xf0e0,0xf0e0,0xf0e0,0xf0e0,0xf0e0,0xf0e0,0xf0e0,0xf0e0,0xf0e0,0xf0e0,0xf0e0, + 0xf0e1,0xf0e1,0xf0e1,0xf0e1,0xf0e1,0xf0e1,0xf0e1,0xf0e1,0xf0e1,0xf0e1,0xf0e1,0xf0e1,0xf0e1,0xf0e1,0xf0e1,0xf0e1,0xf0e1,0xf0e1,0xf0e1,0xf0e1,0xf0e1,0xf0e1,0xf0e1,0xf0e1,0xf0e1,0xf0e1,0xf0e1,0xf0e1,0xf0e1,0xf0e1,0xf0e1,0xf0e1, + 0xf0e2,0xf0e2,0xf0e2,0xf0e2,0xf0e2,0xf0e2,0xf0e2,0xf0e2,0xf0e2,0xf0e2,0xf0e2,0xf0e2,0xf0e2,0xf0e2,0xf0e2,0xf0e2,0xf0e2,0xf0e2,0xf0e2,0xf0e2,0xf0e2,0xf0e2,0xf0e2,0xf0e2,0xf0e2,0xf0e2,0xf0e2,0xf0e2,0xf0e2,0xf0e2,0xf0e2,0xf0e2, + 0xf0e3,0xf0e3,0xf0e3,0xf0e3,0xf0e3,0xf0e3,0xf0e3,0xf0e3,0xf0e3,0xf0e3,0xf0e3,0xf0e3,0xf0e3,0xf0e3,0xf0e3,0xf0e3,0xf0e3,0xf0e3,0xf0e3,0xf0e3,0xf0e3,0xf0e3,0xf0e3,0xf0e3,0xf0e3,0xf0e3,0xf0e3,0xf0e3,0xf0e3,0xf0e3,0xf0e3,0xf0e3, + 0xf0e4,0xf0e4,0xf0e4,0xf0e4,0xf0e4,0xf0e4,0xf0e4,0xf0e4,0xf0e4,0xf0e4,0xf0e4,0xf0e4,0xf0e4,0xf0e4,0xf0e4,0xf0e4,0xf0e4,0xf0e4,0xf0e4,0xf0e4,0xf0e4,0xf0e4,0xf0e4,0xf0e4,0xf0e4,0xf0e4,0xf0e4,0xf0e4,0xf0e4,0xf0e4,0xf0e4,0xf0e4, + 0xf0e5,0xf0e5,0xf0e5,0xf0e5,0xf0e5,0xf0e5,0xf0e5,0xf0e5,0xf0e5,0xf0e5,0xf0e5,0xf0e5,0xf0e5,0xf0e5,0xf0e5,0xf0e5,0xf0e5,0xf0e5,0xf0e5,0xf0e5,0xf0e5,0xf0e5,0xf0e5,0xf0e5,0xf0e5,0xf0e5,0xf0e5,0xf0e5,0xf0e5,0xf0e5,0xf0e5,0xf0e5, + 0xf0e6,0xf0e6,0xf0e6,0xf0e6,0xf0e6,0xf0e6,0xf0e6,0xf0e6,0xf0e6,0xf0e6,0xf0e6,0xf0e6,0xf0e6,0xf0e6,0xf0e6,0xf0e6,0xf0e6,0xf0e6,0xf0e6,0xf0e6,0xf0e6,0xf0e6,0xf0e6,0xf0e6,0xf0e6,0xf0e6,0xf0e6,0xf0e6,0xf0e6,0xf0e6,0xf0e6,0xf0e6, + 0xf0e7,0xf0e7,0xf0e7,0xf0e7,0xf0e7,0xf0e7,0xf0e7,0xf0e7,0xf0e7,0xf0e7,0xf0e7,0xf0e7,0xf0e7,0xf0e7,0xf0e7,0xf0e7,0xf0e7,0xf0e7,0xf0e7,0xf0e7,0xf0e7,0xf0e7,0xf0e7,0xf0e7,0xf0e7,0xf0e7,0xf0e7,0xf0e7,0xf0e7,0xf0e7,0xf0e7,0xf0e7, + 0xf0e8,0xf0e8,0xf0e8,0xf0e8,0xf0e8,0xf0e8,0xf0e8,0xf0e8,0xf0e8,0xf0e8,0xf0e8,0xf0e8,0xf0e8,0xf0e8,0xf0e8,0xf0e8,0xf0e8,0xf0e8,0xf0e8,0xf0e8,0xf0e8,0xf0e8,0xf0e8,0xf0e8,0xf0e8,0xf0e8,0xf0e8,0xf0e8,0xf0e8,0xf0e8,0xf0e8,0xf0e8, + 0xf0e9,0xf0e9,0xf0e9,0xf0e9,0xf0e9,0xf0e9,0xf0e9,0xf0e9,0xf0e9,0xf0e9,0xf0e9,0xf0e9,0xf0e9,0xf0e9,0xf0e9,0xf0e9,0xf0e9,0xf0e9,0xf0e9,0xf0e9,0xf0e9,0xf0e9,0xf0e9,0xf0e9,0xf0e9,0xf0e9,0xf0e9,0xf0e9,0xf0e9,0xf0e9,0xf0e9,0xf0e9, + 0xf0ea,0xf0ea,0xf0ea,0xf0ea,0xf0ea,0xf0ea,0xf0ea,0xf0ea,0xf0ea,0xf0ea,0xf0ea,0xf0ea,0xf0ea,0xf0ea,0xf0ea,0xf0ea,0xf0ea,0xf0ea,0xf0ea,0xf0ea,0xf0ea,0xf0ea,0xf0ea,0xf0ea,0xf0ea,0xf0ea,0xf0ea,0xf0ea,0xf0ea,0xf0ea,0xf0ea,0xf0ea, + 0xf0eb,0xf0eb,0xf0eb,0xf0eb,0xf0eb,0xf0eb,0xf0eb,0xf0eb,0xf0eb,0xf0eb,0xf0eb,0xf0eb,0xf0eb,0xf0eb,0xf0eb,0xf0eb,0xf0eb,0xf0eb,0xf0eb,0xf0eb,0xf0eb,0xf0eb,0xf0eb,0xf0eb,0xf0eb,0xf0eb,0xf0eb,0xf0eb,0xf0eb,0xf0eb,0xf0eb,0xf0eb, + 0xf0ec,0xf0ec,0xf0ec,0xf0ec,0xf0ec,0xf0ec,0xf0ec,0xf0ec,0xf0ec,0xf0ec,0xf0ec,0xf0ec,0xf0ec,0xf0ec,0xf0ec,0xf0ec,0xf0ec,0xf0ec,0xf0ec,0xf0ec,0xf0ec,0xf0ec,0xf0ec,0xf0ec,0xf0ec,0xf0ec,0xf0ec,0xf0ec,0xf0ec,0xf0ec,0xf0ec,0xf0ec, + 0xf0ed,0xf0ed,0xf0ed,0xf0ed,0xf0ed,0xf0ed,0xf0ed,0xf0ed,0xf0ed,0xf0ed,0xf0ed,0xf0ed,0xf0ed,0xf0ed,0xf0ed,0xf0ed,0xf0ed,0xf0ed,0xf0ed,0xf0ed,0xf0ed,0xf0ed,0xf0ed,0xf0ed,0xf0ed,0xf0ed,0xf0ed,0xf0ed,0xf0ed,0xf0ed,0xf0ed,0xf0ed, + 0xf0ee,0xf0ee,0xf0ee,0xf0ee,0xf0ee,0xf0ee,0xf0ee,0xf0ee,0xf0ee,0xf0ee,0xf0ee,0xf0ee,0xf0ee,0xf0ee,0xf0ee,0xf0ee,0xf0ee,0xf0ee,0xf0ee,0xf0ee,0xf0ee,0xf0ee,0xf0ee,0xf0ee,0xf0ee,0xf0ee,0xf0ee,0xf0ee,0xf0ee,0xf0ee,0xf0ee,0xf0ee, + 0xf0ef,0xf0ef,0xf0ef,0xf0ef,0xf0ef,0xf0ef,0xf0ef,0xf0ef,0xf0ef,0xf0ef,0xf0ef,0xf0ef,0xf0ef,0xf0ef,0xf0ef,0xf0ef,0xf0ef,0xf0ef,0xf0ef,0xf0ef,0xf0ef,0xf0ef,0xf0ef,0xf0ef,0xf0ef,0xf0ef,0xf0ef,0xf0ef,0xf0ef,0xf0ef,0xf0ef,0xf0ef, + 0xf0f0,0xf0f0,0xf0f0,0xf0f0,0xf0f0,0xf0f0,0xf0f0,0xf0f0,0xf0f0,0xf0f0,0xf0f0,0xf0f0,0xf0f0,0xf0f0,0xf0f0,0xf0f0,0xf0f0,0xf0f0,0xf0f0,0xf0f0,0xf0f0,0xf0f0,0xf0f0,0xf0f0,0xf0f0,0xf0f0,0xf0f0,0xf0f0,0xf0f0,0xf0f0,0xf0f0,0xf0f0, + 0xf0f1,0xf0f1,0xf0f1,0xf0f1,0xf0f1,0xf0f1,0xf0f1,0xf0f1,0xf0f1,0xf0f1,0xf0f1,0xf0f1,0xf0f1,0xf0f1,0xf0f1,0xf0f1,0xf0f1,0xf0f1,0xf0f1,0xf0f1,0xf0f1,0xf0f1,0xf0f1,0xf0f1,0xf0f1,0xf0f1,0xf0f1,0xf0f1,0xf0f1,0xf0f1,0xf0f1,0xf0f1, + 0xf0f2,0xf0f2,0xf0f2,0xf0f2,0xf0f2,0xf0f2,0xf0f2,0xf0f2,0xf0f2,0xf0f2,0xf0f2,0xf0f2,0xf0f2,0xf0f2,0xf0f2,0xf0f2,0xf0f2,0xf0f2,0xf0f2,0xf0f2,0xf0f2,0xf0f2,0xf0f2,0xf0f2,0xf0f2,0xf0f2,0xf0f2,0xf0f2,0xf0f2,0xf0f2,0xf0f2,0xf0f2, + 0xf0f3,0xf0f3,0xf0f3,0xf0f3,0xf0f3,0xf0f3,0xf0f3,0xf0f3,0xf0f3,0xf0f3,0xf0f3,0xf0f3,0xf0f3,0xf0f3,0xf0f3,0xf0f3,0xf0f3,0xf0f3,0xf0f3,0xf0f3,0xf0f3,0xf0f3,0xf0f3,0xf0f3,0xf0f3,0xf0f3,0xf0f3,0xf0f3,0xf0f3,0xf0f3,0xf0f3,0xf0f3, + 0xf0f4,0xf0f4,0xf0f4,0xf0f4,0xf0f4,0xf0f4,0xf0f4,0xf0f4,0xf0f4,0xf0f4,0xf0f4,0xf0f4,0xf0f4,0xf0f4,0xf0f4,0xf0f4,0xf0f4,0xf0f4,0xf0f4,0xf0f4,0xf0f4,0xf0f4,0xf0f4,0xf0f4,0xf0f4,0xf0f4,0xf0f4,0xf0f4,0xf0f4,0xf0f4,0xf0f4,0xf0f4, + 0xf0f5,0xf0f5,0xf0f5,0xf0f5,0xf0f5,0xf0f5,0xf0f5,0xf0f5,0xf0f5,0xf0f5,0xf0f5,0xf0f5,0xf0f5,0xf0f5,0xf0f5,0xf0f5,0xf0f5,0xf0f5,0xf0f5,0xf0f5,0xf0f5,0xf0f5,0xf0f5,0xf0f5,0xf0f5,0xf0f5,0xf0f5,0xf0f5,0xf0f5,0xf0f5,0xf0f5,0xf0f5, +}; + +/*---------------------------------------------------------------------------* + 内部関数宣言 + *---------------------------------------------------------------------------*/ + +static void kamiFontReturnConsole( void ); + +/*---------------------------------------------------------------------------* + 関数定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + Name: + + Description: + + Arguments: None + + Returns: None. + *---------------------------------------------------------------------------*/ +void +kamiFontInit(void) +{ + // 背景用キャラクタデータ + MI_CpuCopy32( &sampleCharData[8 * 0xde], sBackColorCharData, sizeof(sBackColorCharData) ); + + // 背景用スクリーンデータセット + DC_FlushRange ( sBackColorScreenData, sizeof(sBackColorScreenData) ); + GXS_LoadBG1Scr ( sBackColorScreenData, 0, sizeof(sBackColorScreenData) ); +} + +/*---------------------------------------------------------------------------* + Name: + + Description: + + Arguments: None + + Returns: None. + *---------------------------------------------------------------------------*/ +void +kamiFontLoadScreenData(void) +{ +// DC_FlushRange ( sFontScreenDataMain, sizeof(sFontScreenDataMain) ); +// GX_LoadBG0Scr ( sFontScreenDataMain, 0, sizeof(sFontScreenDataMain) ); + + DC_FlushRange ( sFontScreenDataSub, sizeof(sFontScreenDataSub) ); + GXS_LoadBG0Scr ( sFontScreenDataSub, 0, sizeof(sFontScreenDataSub) ); + + // 背景キャラクタデータ書き換え + DC_FlushRange( sBackColorCharData, sizeof(sBackColorCharData) ); + GXS_LoadBG0Char( sBackColorCharData, 0xde*32, sizeof(sBackColorCharData) ); +} + +/*---------------------------------------------------------------------------* + Name: kamiFontClear + + Description: 仮想スクリーンをクリアする + + Arguments: None + + Returns: None. + *---------------------------------------------------------------------------*/ +void +kamiFontClear(void) +{ + MI_CpuClear8( sFontScreenDataSub, sizeof(sFontScreenDataSub) ); +} + +/*---------------------------------------------------------------------------* + Name: kamiFontClearMain + + Description: 仮想スクリーンをクリアする + + Arguments: None + + Returns: None. + *---------------------------------------------------------------------------*/ +void +kamiFontClearMain(void) +{ + MI_CpuClear8( sFontScreenDataMain, sizeof(sFontScreenDataMain) ); +} + +/*---------------------------------------------------------------------------* + Name: kamiFontPrintf + + Description: 仮想スクリーンに文字列を配置する。文字列は32文字まで。 + + Arguments: x - 文字列の先頭を配置する x 座標( × 8 ドット )。 + y - 文字列の先頭を配置する y 座標( × 8 ドット )。 + color - 文字の色をパレット番号で指定。 + text - 配置する文字列。終端文字はNULL。 + ... - 仮想引数。 + + Returns: None. + *---------------------------------------------------------------------------*/ +void +kamiFontPrintf(s16 x, s16 y, u8 color, char *text, ...) +{ + va_list vlist; + char temp[32 + 2]; + s32 i; + + va_start(vlist, text); + (void)vsnprintf(temp, 33, text, vlist); + va_end(vlist); + + *(u16 *)(&temp[32]) = 0x0000; + for (i = 0;temp[i] != 0x00; i++) + { + sFontScreenDataSub[((y * 32) + x + i) % (24 * 32)] = + (u16)((color << SCREEN_DATA_COLOR_PLTT_SHIFT) | temp[i]); + } +} + +/*---------------------------------------------------------------------------* + Name: kamiFontPrintf + + Description: 仮想スクリーンに文字列を配置する。文字列は32文字まで。 + + Arguments: x - 文字列の先頭を配置する x 座標( × 8 ドット )。 + y - 文字列の先頭を配置する y 座標( × 8 ドット )。 + color - 文字の色をパレット番号で指定。 + text - 配置する文字列。終端文字はNULL。 + ... - 仮想引数。 + + Returns: None. + *---------------------------------------------------------------------------*/ +void +kamiFontPrintfMain(s16 x, s16 y, u8 color, char *text, ...) +{ + va_list vlist; + char temp[32 + 2]; + s32 i; + + va_start(vlist, text); + (void)vsnprintf(temp, 33, text, vlist); + va_end(vlist); + + *(u16 *)(&temp[32]) = 0x0000; + for (i = 0;temp[i] != 0x00; i++) + { + sFontScreenDataMain[((y * 32) + x + i) % (24 * 32)] = + (u16)((color << SCREEN_DATA_COLOR_PLTT_SHIFT) | temp[i]); + } +} + +/*---------------------------------------------------------------------------* + Name: kamiFontFillChar + + Description: 仮想スクリーンに + + Arguments: x - 文字列の先頭を配置する x 座標( × 8 ドット )。 + y - 文字列の先頭を配置する y 座標( × 8 ドット )。 + color - 文字の色をパレット番号で指定。 + value + + Returns: None. + *---------------------------------------------------------------------------*/ +void +kamiFontFillChar(int lineNo, u8 color1, u8 color2) +{ + s32 i; + u32 line; + int charNo = 0xde + lineNo; + + if (color1 < 0x10) + { + line = (u32)(0x11111111 * color1); + + for (i = 0;i<4; i++) + { + sBackColorCharData[8 * lineNo + i] = line; + } + } + + if (color2 < 0x10) + { + line = (u32)(0x11111111 * color2); + + for (i = 4;i<8; i++) + { + sBackColorCharData[8 * lineNo + i] = line; + } + } +} + +/*---------------------------------------------------------------------------* + Name: kamiFontPrintfConsole + + Description: 仮想コンソールに文字列を配置する。文字列は256文字まで。 + + Arguments: color - 文字の色をパレット番号で指定。 + text - 配置する文字列。終端文字はNULL。 + ... - 仮想引数。 + + Returns: None. + *---------------------------------------------------------------------------*/ +void +kamiFontPrintfConsole(u8 color, const char *text, ...) +{ + va_list vlist; + char temp[256 + 2]; + s32 i; + + va_start(vlist, text); + (void)vsnprintf(temp, 256, text, vlist); + va_end(vlist); + + // 終端追加 + *(u16 *)(&temp[256]) = 0x0000; + + for(i=0; temp[i] != 0x00; i++) + { + if (temp[i] == 0x0A) + { + // 改行コード + kamiFontReturnConsole(); + } + else + { + // 一文字ずつ書き込み + sFontScreenDataSub[((sYPos * 32) + sXPos) % (24 * 32)] = + (u16)((color << SCREEN_DATA_COLOR_PLTT_SHIFT) | temp[i]); + + // X座標が右端に到達した場合は改行処理 + if (++sXPos >= 32) + { + kamiFontReturnConsole(); + } + } + } +} + +/*---------------------------------------------------------------------------* + Name: kamiFontPrintfConsoleEx + + Description: 仮想コンソールに文字列を配置する。文字列は256文字まで。 + OS_Printfもついでに実行する。 + + Arguments: color - 文字の色をパレット番号で指定。 + text - 配置する文字列。終端文字はNULL。 + ... - 仮想引数。 + + Returns: None. + *---------------------------------------------------------------------------*/ +void +kamiFontPrintfConsoleEx(u8 color, const char *text, ...) +{ + va_list vlist; + char temp[256 + 2]; + + va_start(vlist, text); + (void)vsnprintf(temp, 256, text, vlist); + va_end(vlist); + + kamiFontPrintfConsole(color, temp); + OS_TPrintf(temp); +} + +/*---------------------------------------------------------------------------* + Name: kamiFontReturnConsole + + Description: 仮想コンソールにおける改行処理を行う + + Arguments: None. + + Returns: None. + *---------------------------------------------------------------------------*/ +static void +kamiFontReturnConsole( void ) +{ + sXPos = 0; + if (sYPos < 23) + { + // 次の行へ + sYPos++; + } + else + { + // 既に最終行に到達している場合シフトを行う + MI_CpuCopy32( &sFontScreenDataSub[32], sFontScreenDataSub, sizeof(u16)*32*23 ); + MI_CpuClear32( &sFontScreenDataSub[32*23], sizeof(u16)*32); + } +} + diff --git a/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/kami_pxi.c b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/kami_pxi.c new file mode 100644 index 00000000..f3ce7f2a --- /dev/null +++ b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/kami_pxi.c @@ -0,0 +1,370 @@ +/*---------------------------------------------------------------------------* + Project: TwlSDK - NandInitializer + File: kami_pxi.c + + Copyright 2008 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + $Date:: $ + $Rev$ + $Author$ + *---------------------------------------------------------------------------*/ + +#include +#include "kami_pxi.h" +#include "fifo.h" + +/*---------------------------------------------------------------------------* + 定数定義 + *---------------------------------------------------------------------------*/ +// 詰めてコピーする +#define KAMI_PACK_U16(d, s) \ + ((d)[0] = (u8)((*((u16*)s) >> 0) & 0xFF), \ + (d)[1] = (u8)((*((u16*)s) >> 8) & 0xFF)) + +#define KAMI_PACK_U32(d, s) \ + ((d)[0] = (u8)((*((u32*)s) >> 0) & 0xFF), \ + (d)[1] = (u8)((*((u32*)s) >> 8) & 0xFF), \ + (d)[2] = (u8)((*((u32*)s) >> 16) & 0xFF), \ + (d)[3] = (u8)((*((u32*)s) >> 24) & 0xFF)) + + +/*---------------------------------------------------------------------------* + 型定義 + *---------------------------------------------------------------------------*/ +typedef struct KamiWork +{ + BOOL lock; + + KamiCommand command; + KAMIPxiResult result; + KAMICallback callback; + void* arg; + + u32 total; + u32 current; + u8* data; +} +KamiWork; + +/*---------------------------------------------------------------------------* + 静的変数定義 + *---------------------------------------------------------------------------*/ +static BOOL kamiInitialized; +static KamiWork kamiWork; + +/*---------------------------------------------------------------------------* + 内部関数定義 + *---------------------------------------------------------------------------*/ +static BOOL KamiSendPxiCommand(KamiCommand command, u8 size, u8 data); +static void KamiSendPxiData(u8 *pData); +static void KamiPxiCallback(PXIFifoTag tag, u32 data, BOOL err); +static void KamiDone(KAMIResult result); +static void KamiWaitBusy(void); + + +void KamiPxiInit( void ) +{ + kamiWork.lock = FALSE; + + PXI_Init(); + while ( !PXI_IsCallbackReady(PXI_FIFO_TAG_KAMITEST, PXI_PROC_ARM7 )) + { + } + PXI_SetFifoRecvCallback(PXI_FIFO_TAG_KAMITEST, KamiPxiCallback); + if ( 0 > PXI_SendWordByFifo(PXI_FIFO_TAG_KAMITEST, KAMITEST_PXI_START_BIT | (KAMI_TEST_COMMAND << KAMITEST_PXI_COMMAND_SHIFT), 0)) + { + return; + } +} + +/*---------------------------------------------------------------------------* + Name: フォーマット実行関数 + + Description: + + Arguments: FormatMode + + Returns: + *---------------------------------------------------------------------------*/ + +KAMIResult ExeFormatAsync(FormatMode format_mode, KAMICallback callback) +{ + OSIntrMode enabled; + + // ロック + enabled = OS_DisableInterrupts(); + if (kamiWork.lock) + { + (void)OS_RestoreInterrupts(enabled); + return KAMI_RESULT_BUSY; + } + kamiWork.lock = TRUE; + (void)OS_RestoreInterrupts(enabled); + + kamiWork.callback = callback; + kamiWork.arg = 0; + kamiWork.data = 0; + + if (KamiSendPxiCommand(KAMI_EXE_FORMAT, 1, format_mode) == FALSE) + { + return KAMI_RESULT_SEND_ERROR; + } + return KAMI_RESULT_SUCCESS; +} + +/*---------------------------------------------------------------------------* + Name: NANDアクセス関数 + + Description: + + Arguments: None. + + Returns: + *---------------------------------------------------------------------------*/ + +KAMIResult kamiNandIo(u32 block, void* buffer, u32 count, BOOL is_read) +{ + OSIntrMode enabled; + u8 data[12]; + int i; + + // ロック + enabled = OS_DisableInterrupts(); + if (kamiWork.lock) + { + (void)OS_RestoreInterrupts(enabled); + return KAMI_RESULT_BUSY; + } + kamiWork.lock = TRUE; + (void)OS_RestoreInterrupts(enabled); + + kamiWork.callback = NULL; + kamiWork.arg = 0; + kamiWork.data = 0; + + // データ作成 + KAMI_PACK_U32(&data[0], &block); + KAMI_PACK_U32(&data[4], &buffer); + KAMI_PACK_U32(&data[8], &count); + + if (KamiSendPxiCommand(KAMI_NAND_IO, 12, (u8)is_read)) + { + for (i = 0; i < 12; i+=3) + { + KamiSendPxiData(&data[i]); + } + KamiWaitBusy(); + return (KAMIResult)kamiWork.result; + } + return KAMI_RESULT_SEND_ERROR; +} + +/*---------------------------------------------------------------------------* + Name: kamiClearNandErrorLog + + Description: NVRAMのNANDエラー情報をクリアします。 + + Arguments: None. + + Returns: + *---------------------------------------------------------------------------*/ + +KAMIResult kamiClearNandErrorLog( void ) +{ + OSIntrMode enabled; + + // ロック + enabled = OS_DisableInterrupts(); + if (kamiWork.lock) + { + (void)OS_RestoreInterrupts(enabled); + return KAMI_RESULT_BUSY; + } + kamiWork.lock = TRUE; + (void)OS_RestoreInterrupts(enabled); + + kamiWork.callback = NULL; + kamiWork.arg = 0; + kamiWork.data = 0; + + if (KamiSendPxiCommand(KAMI_CLEAR_NAND_ERRORLOG, 0, (u8)0)) + { + KamiWaitBusy(); + return (KAMIResult)kamiWork.result; + } + return KAMI_RESULT_SEND_ERROR; +} + +/*---------------------------------------------------------------------------* + Name: kamiGetIsToolType + + Description: IS-TWL-DEBUGGER or CAPTURE を取得します(同期版) + + Arguments: None. + + Returns: + *---------------------------------------------------------------------------*/ + +KAMIResult kamiGetIsToolType( IsToolType *pType ) +{ + OSIntrMode enabled; + + if (pType == NULL) + { + return KAMI_RESULT_INVALID_PARAMETER; + } + + enabled = OS_DisableInterrupts(); + if (kamiWork.lock) + { + (void)OS_RestoreInterrupts(enabled); + return KAMI_RESULT_BUSY; + } + kamiWork.lock = TRUE; + kamiWork.callback = NULL; + kamiWork.arg = 0; + kamiWork.data = (u8*)pType; + (void)OS_RestoreInterrupts(enabled); + + if (KamiSendPxiCommand(KAMI_GET_IS_TOOL_TYPE, 0, 0)) + { + KamiWaitBusy(); + return (KAMIResult)kamiWork.result; + } + return KAMI_RESULT_SEND_ERROR; +} + +/*---------------------------------------------------------------------------* + PXI関連 + *---------------------------------------------------------------------------*/ + +static BOOL KamiSendPxiCommand(KamiCommand command, u8 size, u8 data) +{ + u32 pxiData = (u32)(KAMITEST_PXI_START_BIT | + ((command << KAMITEST_PXI_COMMAND_SHIFT) & KAMITEST_PXI_COMMAND_MASK) | + ((size << KAMITEST_PXI_DATA_NUMS_SHIFT) & KAMITEST_PXI_DATA_NUMS_MASK) | + ((data << KAMITEST_PXI_1ST_DATA_SHIFT) & KAMITEST_PXI_1ST_DATA_MASK)); + if (0 > PXI_SendWordByFifo(PXI_FIFO_TAG_KAMITEST, pxiData, 0)) + { + return FALSE; + } + return TRUE; +} + +static void KamiSendPxiData(u8 *pData) +{ + u32 pxiData = (u32)((pData[0] << 16) | (pData[1] << 8) | pData[2]); + while (0 > PXI_SendWordByFifo(PXI_FIFO_TAG_KAMITEST, pxiData, 0)) + { + } +} + +static void KamiPxiCallback(PXIFifoTag tag, u32 data, BOOL err) +{ +#pragma unused( tag ) + if (err) + { + KamiDone(KAMI_RESULT_FATAL_ERROR); + return; + } + if (data & KAMITEST_PXI_START_BIT) // 先頭データ + { + if (data & KAMITEST_PXI_RESULT_BIT) + { + kamiWork.total = (u8)((data & KAMITEST_PXI_DATA_NUMS_MASK) >> KAMITEST_PXI_DATA_NUMS_SHIFT); + kamiWork.current = 0; + kamiWork.command = (KamiCommand)((data & KAMITEST_PXI_COMMAND_MASK) >> KAMITEST_PXI_COMMAND_SHIFT); + kamiWork.result = (KAMIPxiResult)((data & KAMITEST_PXI_1ST_DATA_MASK) >> KAMITEST_PXI_1ST_DATA_SHIFT); + } + else // 未知のデータ + { + KamiDone(KAMI_RESULT_FATAL_ERROR); + return; + } + } + else // 後続データ + { + if (kamiWork.data == NULL) + { + KamiDone(KAMI_RESULT_FATAL_ERROR); + return; + } + if (kamiWork.current < kamiWork.total-1) + { + kamiWork.data[kamiWork.current++] = (u8)((data & 0xFF0000) >> 16); + } + if (kamiWork.current < kamiWork.total-1) + { + kamiWork.data[kamiWork.current++] = (u8)((data & 0x00FF00) >> 8); + } + if (kamiWork.current < kamiWork.total-1) + { + kamiWork.data[kamiWork.current++] = (u8)((data & 0x0000FF) >> 0); + } + } + if (kamiWork.current == kamiWork.total-1) + { + KAMIResult result; + switch (kamiWork.result) + { + case KAMI_PXI_RESULT_SUCCESS: // alias KAMI_PXI_RESULT_SUCCESS_TRUE + result = KAMI_RESULT_SUCCESS; // alias KAMI_RESULT_SUCCESS_TRUE + break; + case KAMI_PXI_RESULT_SUCCESS_FALSE: + result = KAMI_RESULT_SUCCESS_FALSE; + break; + case KAMI_PXI_RESULT_INVALID_COMMAND: + result = KAMI_RESULT_INVALID_COMMAND; + break; + case KAMI_PXI_RESULT_INVALID_PARAMETER: + result = KAMI_RESULT_INVALID_PARAMETER; + break; + case KAMI_PXI_RESULT_ILLEGAL_STATUS: + result = KAMI_RESULT_ILLEGAL_STATUS; + break; + case KAMI_PXI_RESULT_BUSY: + result = KAMI_RESULT_BUSY; + break; + default: + result = KAMI_RESULT_FATAL_ERROR; + } + KamiDone(result); + return; + } +} + +extern void PXIi_HandlerRecvFifoNotEmpty(void); +static void KamiWaitBusy(void) +{ + volatile BOOL *p = &kamiWork.lock; + + while (*p) + { + if (OS_GetCpsrIrq() == OS_INTRMODE_IRQ_DISABLE) + { + PXIi_HandlerRecvFifoNotEmpty(); + } + } +} + +static void KamiDone(KAMIResult result) +{ + KAMICallback callback = kamiWork.callback; + void* arg = kamiWork.arg; + kamiWork.callback = NULL; + kamiWork.arg = NULL; + if (kamiWork.lock) + { + kamiWork.lock = FALSE; + } + if (callback) + { + callback(result, arg); + } +} diff --git a/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/kami_write_nandfirm.c b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/kami_write_nandfirm.c new file mode 100644 index 00000000..cac9c5ee --- /dev/null +++ b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/kami_write_nandfirm.c @@ -0,0 +1,332 @@ +/*---------------------------------------------------------------------------* + Project: TwlSDK - NandInitializer + File: kami_write_nandfirm.c + + Copyright 2008 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + $Date:: $ + $Rev$ + $Author$ + *---------------------------------------------------------------------------*/ + +#include +#include +#include +#include +#include +#include "kami_font.h" +#include "kami_pxi.h" + +#include +#include "kami_write_nandfirm.h" + +/*---------------------------------------------------------------------------* + マクロ定義 + *---------------------------------------------------------------------------*/ + +// NANDファーム書き込みの際にNVRAMの未割り当て領域+予約領域を0クリアする場合は定義します(開発用) +//#define CLEAR_NON_ASIGNED_AREA_AND_RESERVED_AREA_ALL + +/*---------------------------------------------------------------------------* + 定数定義 + *---------------------------------------------------------------------------*/ + +#define NAND_BLOCK_BYTE 0x200 +#define NAND_FIRM_START_OFFSET 0x200 +#define NAND_FIRM_START_OFFSET_IN_FILE 0x200 + +#define NVRAM_PAGE_SIZE 0x100 +#define NVRAM_NORFIRM_RESERVED_ADDRESS 0x200 +#define NVRAM_NORFIRM_NANDBOOT_FLAG_OFFSET 0xff +#define NVRAM_NORFIRM_NANDBOOT_FLAG 0x80 + +#define NVRAM_NON_ASIGNED_AREA_ADDRESS 0x300 + +/*---------------------------------------------------------------------------* + 内部変数定義 + *---------------------------------------------------------------------------*/ + +static u8 sNvramPageSizeBuffer[NVRAM_PAGE_SIZE] ATTRIBUTE_ALIGN(32); // ARM7からアクセスするためスタックでは駄目 +static u32 sReservedAreaEndAddress; + +/*---------------------------------------------------------------------------* + 内部関数定義 + *---------------------------------------------------------------------------*/ + +void kamiEraseNandfirmVersion( u32 nandfirmsize ); + +/*---------------------------------------------------------------------------* + Name: kamiWriteNandfirm + + Description: + + Arguments: no + + Returns: None. + *---------------------------------------------------------------------------*/ +BOOL kamiWriteNandfirm(const char* pFullPath, NAMAlloc allocFunc, NAMFree freeFunc) +{ + FSFile file; + + BOOL open_is_ok; + BOOL read_is_ok; + u8* pTempBuf; + u32 file_size; + u32 nandfirm_size; + u32 alloc_size; + u32 write_block; + BOOL result = TRUE; + u16 crc_w1, crc_w2; + u16 crc_r1, crc_r2; + u16 crc_norfirm_reserved_area_w, crc_norfirm_reserved_area_r; +#ifdef CLEAR_NON_ASIGNED_AREA_AND_RESERVED_AREA_ALL + u32 write_offset; +#endif // CLEAR_NON_ASIGNED_AREA_AND_RESERVED_AREA_ALL + + // .nandファイルオープン + FS_InitFile(&file); + open_is_ok = FS_OpenFile(&file, pFullPath); + if (!open_is_ok) + { + OS_Warning("Failure! FS_OpenFile"); + return FALSE; + } + + // サイズチェック + file_size = FS_GetFileLength(&file) ; + if (file_size > (800*1024)) + { + kamiFontPrintfConsoleEx(1, "too big file size!\n"); + FS_CloseFile(&file); + return FALSE; + } + + nandfirm_size = file_size - NAND_FIRM_START_OFFSET_IN_FILE; + + // バッファ確保 + // 書き込みがブロック単位(512byte)であることを考慮し512アライメントを確保 + alloc_size = MATH_ROUNDUP(file_size, 512); + pTempBuf = allocFunc( alloc_size ); + if (pTempBuf == NULL) + { + kamiFontPrintfConsoleEx(1, "Fail Alloc()!\n"); + FS_CloseFile(&file); + return FALSE; + } + + MI_CpuClear8( pTempBuf, alloc_size ); + + // .nandファイルリード + DC_FlushRange(pTempBuf, alloc_size); + read_is_ok = FS_ReadFile( &file, pTempBuf, (s32)file_size ); + DC_FlushRange(pTempBuf, file_size); + if (!read_is_ok) + { + kamiFontPrintfConsoleEx(1, "Fail FS_ReadFile!\n"); + FS_CloseFile(&file); + freeFunc(pTempBuf); + return FALSE; + } + + // ファイルクローズ + FS_CloseFile(&file); + + // 書き込み前のCRCを計算 + crc_w1 = SVC_GetCRC16( 0xffff, pTempBuf, sizeof(NORHeaderDS) ); + crc_w2 = SVC_GetCRC16( 0xffff, pTempBuf+NAND_FIRM_START_OFFSET_IN_FILE, nandfirm_size ); + + // まずNORHeaderDS領域を書き込む(40byte?) + if (NVRAMi_Write(0, sizeof(NORHeaderDS), (void*)pTempBuf) != NVRAM_RESULT_SUCCESS) + { + kamiFontPrintfConsoleEx(1, "Fail NVRAMi_Write()\n"); + result = FALSE; + } + + // CRCを計算するので念のためにクリアしてからリードする + MI_CpuClear8( pTempBuf, sizeof(NORHeaderDS) ); + DC_FlushRange(pTempBuf, sizeof(NORHeaderDS)); + + // CRCチェックのためNvramからリード + if (NVRAMi_Read(0, sizeof(NORHeaderDS), pTempBuf) != NVRAM_RESULT_SUCCESS) + { + kamiFontPrintfConsoleEx(1, "Fail NVRAMi_Read()!\n"); + } + DC_FlushRange(pTempBuf, sizeof(NORHeaderDS)); + + // 書き込み後のCRCを計算 + crc_r1 = SVC_GetCRC16( 0xffff, pTempBuf, sizeof(NORHeaderDS) ); + + // NVRAM先頭部分のCRC比較 + if ( crc_w1 != crc_r1 ) + { + freeFunc(pTempBuf); + kamiFontPrintfConsoleEx(1, "Fail! CRC check %x!=%x\n", crc_w1, crc_r1); + return FALSE; + } + + // nandfirm 起動フラグを立てる + MI_CpuClear8( sNvramPageSizeBuffer, NVRAM_PAGE_SIZE ); + sNvramPageSizeBuffer[NVRAM_NORFIRM_NANDBOOT_FLAG_OFFSET] = NVRAM_NORFIRM_NANDBOOT_FLAG; + DC_FlushRange( sNvramPageSizeBuffer, NVRAM_PAGE_SIZE); + + // NORファームリザーブ領域の書き込みデータのCRCを計算 + crc_norfirm_reserved_area_w = SVC_GetCRC16( 0xffff, sNvramPageSizeBuffer, NVRAM_PAGE_SIZE ); + + if (NVRAMi_Write(NVRAM_NORFIRM_RESERVED_ADDRESS, NVRAM_PAGE_SIZE, sNvramPageSizeBuffer) != NVRAM_RESULT_SUCCESS) + { + kamiFontPrintfConsoleEx(1, "Fail NVRAMi_Write()\n"); + result = FALSE; + } + + // CRCを計算するので念のためにクリアしてからリードする + MI_CpuClear8( sNvramPageSizeBuffer, NVRAM_PAGE_SIZE ); + + // 読み込みはARM7が直接メモリに書き出すため + DC_FlushRange(sNvramPageSizeBuffer, NVRAM_PAGE_SIZE); + + if (NVRAMi_Read(NVRAM_NORFIRM_RESERVED_ADDRESS, NVRAM_PAGE_SIZE, sNvramPageSizeBuffer) != NVRAM_RESULT_SUCCESS) + { + kamiFontPrintfConsoleEx(1, "Fail NVRAMi_Read()\n"); + result = FALSE; + } + + // 書き込み後のCRCを計算 + DC_FlushRange(sNvramPageSizeBuffer, NVRAM_PAGE_SIZE); + crc_norfirm_reserved_area_r = SVC_GetCRC16( 0xffff, sNvramPageSizeBuffer, NVRAM_PAGE_SIZE ); + + // NORファームリザーブ領域のCRC比較 + if ( crc_norfirm_reserved_area_w != crc_norfirm_reserved_area_r ) + { + kamiFontPrintfConsoleEx(1, "Fail! Norfirm Reserved Area CRC check %x!=%x\n", crc_norfirm_reserved_area_w, crc_norfirm_reserved_area_r); + result = FALSE; + } + +#ifdef CLEAR_NON_ASIGNED_AREA_AND_RESERVED_AREA_ALL + DC_InvalidateRange( sNvramPageSizeBuffer, NVRAM_PAGE_SIZE ); + // 未割り当て領域+予約領域を0クリアします(開発用) + if (NVRAMi_Read(NVRAM_CONFIG_DATA_OFFSET_ADDRESS, NVRAM_PAGE_SIZE, &sNvramPageSizeBuffer) != NVRAM_RESULT_SUCCESS) + { + kamiFontPrintfConsoleEx(1, "Fail NVRAMi_Read()\n"); + result = FALSE; + } + sReservedAreaEndAddress = (u32)(*(u16 *)sNvramPageSizeBuffer << NVRAM_CONFIG_DATA_OFFSET_SHIFT) - 0xA00;// TWL WiFi設定 + NTR WiFi設定 を差し引く + //OS_Printf("end = %x\n", sReservedAreaEndAddress); + + MI_CpuFill8( sNvramPageSizeBuffer, 0x00, NVRAM_PAGE_SIZE ); + DC_FlushRange( sNvramPageSizeBuffer, NVRAM_PAGE_SIZE ); + + for (write_offset=NVRAM_NON_ASIGNED_AREA_ADDRESS; write_offset < sReservedAreaEndAddress; write_offset += NVRAM_PAGE_SIZE) + { + if (NVRAMi_Write(write_offset, NVRAM_PAGE_SIZE, sNvramPageSizeBuffer) != NVRAM_RESULT_SUCCESS) + { + kamiFontPrintfConsoleEx(1, "Fail NVRAMi_Write()\n"); + result = FALSE; + } + } + //OS_Printf("write_offset = %x\n", write_offset); +#else + // 未割り当て領域先頭256byte+予約領域を0クリアします + + MI_CpuFill8( sNvramPageSizeBuffer, 0x00, NVRAM_PAGE_SIZE ); + DC_FlushRange( sNvramPageSizeBuffer, NVRAM_PAGE_SIZE ); + + if (NVRAMi_Write(NVRAM_NON_ASIGNED_AREA_ADDRESS, NVRAM_PAGE_SIZE, sNvramPageSizeBuffer) != NVRAM_RESULT_SUCCESS) + { + kamiFontPrintfConsoleEx(1, "Fail NVRAMi_Write()\n"); + result = FALSE; + } + + DC_InvalidateRange( sNvramPageSizeBuffer, NVRAM_PAGE_SIZE ); + if (NVRAMi_Read(NVRAM_CONFIG_DATA_OFFSET_ADDRESS, NVRAM_PAGE_SIZE, &sNvramPageSizeBuffer) != NVRAM_RESULT_SUCCESS) + { + kamiFontPrintfConsoleEx(1, "Fail NVRAMi_Read()\n"); + result = FALSE; + } + sReservedAreaEndAddress = (u32)(*(u16 *)sNvramPageSizeBuffer << NVRAM_CONFIG_DATA_OFFSET_SHIFT) - 0xA00;// TWL WiFi設定 + NTR WiFi設定 を差し引く + + MI_CpuFill8( sNvramPageSizeBuffer, 0x00, NVRAM_PAGE_SIZE ); + DC_FlushRange( sNvramPageSizeBuffer, NVRAM_PAGE_SIZE ); + + if (NVRAMi_Write(sReservedAreaEndAddress - 0x100, NVRAM_PAGE_SIZE, sNvramPageSizeBuffer) != NVRAM_RESULT_SUCCESS) + { + kamiFontPrintfConsoleEx(1, "Fail NVRAMi_Write()\n"); + result = FALSE; + } +#endif + + // NANDログ情報のクリア + if (kamiClearNandErrorLog() != KAMI_RESULT_SUCCESS) + { + kamiFontPrintfConsoleEx(1, "Fail kamiClearNandErrorLog()\n"); + result = FALSE; + } + + // nandfirmバージョンの消去(デバッグ用) + kamiEraseNandfirmVersion(nandfirm_size); + +// kamiFontPrintfConsoleEx(0, "NAND Firm Import Start!\n"); + + // NAND書き込み + write_block = nandfirm_size/NAND_BLOCK_BYTE + (nandfirm_size % NAND_BLOCK_BYTE != 0); + kamiNandWrite( NAND_FIRM_START_OFFSET/NAND_BLOCK_BYTE, pTempBuf+NAND_FIRM_START_OFFSET, write_block ); // ブロック単位、バイト単位、ブロック単位 + kamiFontLoadScreenData(); + + // CRCを計算するので念のためにクリアしてからリードする + MI_CpuClear8( pTempBuf, nandfirm_size ); + DC_FlushRange(pTempBuf, nandfirm_size); + + // CRCチェックのためNandからリード + if (kamiNandRead(NAND_FIRM_START_OFFSET/NAND_BLOCK_BYTE, pTempBuf, write_block ) == KAMI_RESULT_SEND_ERROR) + { + kamiFontPrintfConsoleEx(1, "kamiNandRead ... %s!\n", "ERROR"); + } + DC_FlushRange(pTempBuf, nandfirm_size); + + // 書き込み後のCRCを計算 + crc_r2 = SVC_GetCRC16( 0xffff, pTempBuf, nandfirm_size ); + + // NAND部分についてのCRCチェック + if (crc_w2 == crc_r2) + { +// kamiFontPrintfConsoleEx(0, "Success! CRC check %x==%x\n", crc_w2, crc_r2); + } + else + { + result = FALSE; + kamiFontPrintfConsoleEx(1, "Fail! CRC check %x!=%x\n", crc_w2, crc_r2); + } + + // メモリ解放 + freeFunc(pTempBuf); + + return result; +} + +/*---------------------------------------------------------------------------* + Name: kamiEraseNandfirmVersion + + Description: nandfirmのバージョン情報を消去します。(デバッグ用) + + Arguments: no + + Returns: None. + *---------------------------------------------------------------------------*/ +void kamiEraseNandfirmVersion( u32 nandfirmsize ) +{ + u8 buffer[NAND_BLOCK_BYTE]; + u32 blockNo; + + if ((nandfirmsize % NAND_BLOCK_BYTE)==0) + { + blockNo = NAND_FIRM_START_OFFSET/NAND_BLOCK_BYTE + nandfirmsize/NAND_BLOCK_BYTE; + MI_CpuClear8( buffer, NAND_BLOCK_BYTE ); + DC_FlushRange(buffer, NAND_BLOCK_BYTE); + kamiNandWrite( blockNo, buffer, 1 ); // ブロック単位、バイト単位、ブロック単位 + } +} diff --git a/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/keypad.c b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/keypad.c new file mode 100644 index 00000000..155c4bc2 --- /dev/null +++ b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/keypad.c @@ -0,0 +1,85 @@ +/*---------------------------------------------------------------------------* + Project: TwlSDK - NandInitializer + File: keypad.c + + Copyright 2008 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + $Date:: $ + $Rev$ + $Author$ + *---------------------------------------------------------------------------*/ + +#include +#include "keypad.h" + +/*---------------------------------------------------------------------------* + 定数定義 + *---------------------------------------------------------------------------*/ + +#define KEY_REPEAT_TRIGGER_START 20 +#define KEY_REPEAT_TRIGGER_TERM 5 + +/*---------------------------------------------------------------------------* + 内部変数定義 + *---------------------------------------------------------------------------*/ + +static u16 Cont; +static u16 Trg; +static u16 Release; +static u16 RepeatTrg; +static u8 key = 60; + +static int repeat_counter; + +/*---------------------------------------------------------------------------* + 内部関数定義 + *---------------------------------------------------------------------------*/ +void +kamiPadRead(void) +{ + u16 ReadData; + + ReadData = PAD_Read(); + Trg = (u16)(ReadData & (ReadData ^ Cont)); + Release = (u16)(Cont & (ReadData ^ Cont)); + Cont = ReadData; + + RepeatTrg = Trg; + if (++repeat_counter > (KEY_REPEAT_TRIGGER_START + KEY_REPEAT_TRIGGER_TERM)) + { + repeat_counter = KEY_REPEAT_TRIGGER_START; + } + if (repeat_counter == KEY_REPEAT_TRIGGER_START) + { + RepeatTrg = ReadData; + } + if (!ReadData) + { + repeat_counter = 0; + } +} + +BOOL +kamiPadIsTrigger(u16 key) +{ + return (Trg & key)? TRUE : FALSE; +} + +BOOL +kamiPadIsRepeatTrigger(u16 key) +{ + return (RepeatTrg & key)? TRUE : FALSE; +} + +BOOL +kamiPadIsPress(u16 key) +{ + return (Cont & key)? TRUE : FALSE; +} + diff --git a/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/main.c b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/main.c new file mode 100644 index 00000000..9729f919 --- /dev/null +++ b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/main.c @@ -0,0 +1,243 @@ +/*---------------------------------------------------------------------------* + Project: SystemUpdater + File: main.c + + Copyright 2008 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + $Date:: $ + $Rev$ + $Author$ + *---------------------------------------------------------------------------*/ + +#include +#include +#include +#include +#include +#include +#include "kami_pxi.h" +#include "kami_font.h" +#include "kami_copy_file.h" +#include "graphics.h" +#include "hwi.h" +#include "keypad.h" +#include "debugger_hw_reset_control.h" +#include "debugger_card_rom.h" +#include "font.h" +#include "kami_global.h" + +#define SCRAMBLE_MASK 0x00406000 + +extern void InitFont(void); + +/*---------------------------------------------------------------------------* + 型定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + 内部定数定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + 内部変数定義 + *---------------------------------------------------------------------------*/ + +s32 gLockId; + +/*---------------------------------------------------------------------------* + 内部関数定義 + *---------------------------------------------------------------------------*/ +static void VBlankIntr(void); +static void InitAllocation(void); +static BOOL IgnoreRemoval(void); + +/*---------------------------------------------------------------------------* + Name: TwlMain + + Description: main + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void +TwlMain() +{ + BOOL result; + + // 製品ビルドランチャー&デバッガ上での起動対応 + if ( OS_GetRunningConsoleType() & OS_CONSOLE_TWLDEBUGGER ) + { + ROM_Header *dh = (void *)HW_ROM_HEADER_BUF; + dh->s.game_cmd_param &= ~SCRAMBLE_MASK; + } + + OS_Init(); + OS_InitThread(); + OS_InitTick(); + OS_InitAlarm(); + OS_InitArena(); + PXI_Init(); + OS_InitLock(); + OS_InitArenaEx(); + OS_InitIrqTable(); + OS_SetIrqStackChecker(); + MI_Init(); + OS_InitVAlarm(); + OSi_InitVramExclusive(); + OS_InitThread(); + OS_InitReset(); + GX_Init(); + FX_Init(); + SND_Init(); + TP_Init(); + RTC_Init(); + + KamiPxiInit(); /* 独自PXI初期化 */ + + // Vブランク割り込み設定 + OS_SetIrqFunction(OS_IE_V_BLANK, VBlankIntr); + (void)OS_EnableIrqMask(OS_IE_V_BLANK); + (void)OS_EnableIrqMask(OS_IE_FIFO_RECV); + (void)OS_EnableIrq(); + (void)GX_VBlankIntr(TRUE); + + // initialize file-system + FS_Init(FS_DMA_NOT_USE); + + InitAllocation(); + + // NAMライブラリ初期化 + NAM_Init( OS_AllocFromMain, OS_FreeToMain ); + NAMUT_Init( OS_AllocFromMain, OS_FreeToMain ); // SoftBoxCountの計算に必要 + + // 表示関連初期化 + InitGraphics(); + kamiFontInit(); + kamiFontPrintfConsole(FONT_COLOR_GREEN, "Log Window:\n"); + + // メインスレッドのカードロックID取得 + gLockId = OS_GetLockID(); + + /* always preload FS table for faster directory access. */ + { + u32 need_size = FS_GetTableSize(); + void *p_table = OS_Alloc(need_size); + SDK_ASSERT(p_table != NULL); + (void)FS_LoadTable(p_table, need_size); + } + + // フォント初期化 + InitFont(); + + // コンソールチェック + ProcessCheckConsole(); + + // ログ情報確認 + ProcessCheckLog(); + + // リージョン選択 + ProcessSelectRegion(); + + // Note表示 + ProcessNote(); + + // TWLの更新処理を実行中です + CARD_LockRom((u16)gLockId); + (void)CARDi_ReadRomIDCoreEx(DEBUGGER_COMMAND_NOW_UPDATE); + CARD_UnlockRom((u16)gLockId); + + // ISデバッガのハードウェアリセットを禁止する + DEBUGGER_HwResetDisable(); + + // HWInfo関連の前準備 + switch (HWI_Init( OS_AllocFromMain, OS_FreeToMain )) + { + case HWI_INIT_FAILURE: + kamiFontPrintfConsole(FONT_COLOR_RED, " Fail! : HWI_INIT()\n"); + break; + case HWI_INIT_SUCCESS_PRO_SIGNATURE_MODE: + break; + case HWI_INIT_SUCCESS_DEV_SIGNATURE_MODE: + break; + case HWI_INIT_SUCCESS_NO_SIGNATRUE_MODE: + break; + } + + result = TRUE; + + // フォーマット +// result &= ProcessFormat(); + + // 全ハードウェア情報の更新 + result &= ProcessHwinfo(); + + // 必要なファイルの書き込み + result &= ProcessWriteFiles(); + + // ダミーのラッピングデータ書き込み +// result &= kamiWriteWrapData(); + + // TADのインポート開始 + result &= ProcessImport(); + + // NANDファームのインストール開始 + result &= ProcessNandfirm(); + + // 更新ログを作成してVersionDownを防ぐ + if (result) + { + ProcessLog(); + } + + // ISデバッガのハードウェアリセットを許可する + DEBUGGER_HwResetEnable(); + + // 結果表示 + ProcessFinish( result ); +} + +/*---------------------------------------------------------------------------* + Name: VBlankIntr + + Description: VBlank割り込み処理 + + Arguments: None. + + Returns: None. + *---------------------------------------------------------------------------*/ +static void +VBlankIntr(void) +{ +// kamiFontLoadScreenData(); + OS_SetIrqCheckFlag(OS_IE_V_BLANK); // checking VBlank interrupt +} + +/*---------------------------------------------------------------------------* + Name: InitAllocation + + Description: ヒープの初期化. + + Arguments: None. + + Returns: None. + *---------------------------------------------------------------------------*/ +static void InitAllocation(void) +{ + void *tmp; + OSHeapHandle hh; + + /* アリーナの初期化 */ + tmp = OS_InitAlloc(OS_ARENA_MAIN, OS_GetMainArenaLo(), OS_GetMainArenaHi(), 1); + OS_SetArenaLo(OS_ARENA_MAIN, tmp); + hh = OS_CreateHeap(OS_ARENA_MAIN, OS_GetMainArenaLo(), OS_GetMainArenaHi()); + if (hh < 0) + OS_Panic("ARM9: Fail to create heap...\n"); + hh = OS_SetCurrentHeap(OS_ARENA_MAIN, hh); +} diff --git a/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/process_cancel.c b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/process_cancel.c new file mode 100644 index 00000000..fcad5dec --- /dev/null +++ b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/process_cancel.c @@ -0,0 +1,81 @@ +/*---------------------------------------------------------------------------* + Project: SystemUpdater + File: process_cancel.c + + Copyright 2008 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + $Date:: $ + $Rev$ + $Author$ + *---------------------------------------------------------------------------*/ + +#include +#include "font.h" +#include "graphics.h" +#include "keypad.h" +#include "debugger_hw_reset_control.h" +#include "debugger_card_rom.h" +#include "kami_global.h" + +/*---------------------------------------------------------------------------* + 型定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + グローバル変数定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + 内部定数定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + 内部変数定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + 内部関数定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + Name: ProcessCancel + + Description: + + Arguments: なし。 + + Returns: なし。 + *---------------------------------------------------------------------------*/ +void ProcessCancel(const char* string) +{ + // キャンセルされました + CARD_LockRom((u16)gLockId); + (void)CARDi_ReadRomIDCoreEx(DEBUGGER_COMMAND_CANCELED); + CARD_UnlockRom((u16)gLockId); + + OS_WaitVBlankIntr(); + NNS_G2dCharCanvasClearArea(&gCanvas, TXT_COLOR_WHITE, 0, 30, 256, 100); + OS_WaitVBlankIntr(); + NNS_G2dCharCanvasClearArea(&gCanvas2, TXT_COLOR_BLACK, 0, 130, 256, 62); + OS_WaitVBlankIntr(); + + NNS_G2dTextCanvasDrawText(&gTextCanvas, 40, 60, + TXT_COLOR_WHITE_BASE, TXT_DRAWTEXT_FLAG_DEFAULT, string); + + while(1) + { + G3X_Reset(); + G3_Identity(); + G3_PolygonAttr(GX_LIGHTMASK_NONE, GX_POLYGONMODE_DECAL, GX_CULL_NONE, 0, 31, 0); + G3_SwapBuffers(GX_SORTMODE_AUTO, GX_BUFFERMODE_W); + OS_WaitVBlankIntr(); + FadeInTick(); + FadeInMaster(); + } +} diff --git a/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/process_check_console.c b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/process_check_console.c new file mode 100644 index 00000000..afe9a391 --- /dev/null +++ b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/process_check_console.c @@ -0,0 +1,198 @@ +/*---------------------------------------------------------------------------* + Project: SystemUpdater + File: check_console.c + + Copyright 2008 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + $Date:: $ + $Rev$ + $Author$ + *---------------------------------------------------------------------------*/ + +#include +#include "kami_global.h" +#include "kami_font.h" +#include "kami_pxi.h" + +/*---------------------------------------------------------------------------* + 型定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + 内部定数定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + 内部変数定義 + *---------------------------------------------------------------------------*/ +static RunningConsole sRunning = UNKNOWN; + +/*---------------------------------------------------------------------------* + 内部関数宣言 + *---------------------------------------------------------------------------*/ +static RunningConsole CheckConsole(void); + +/*---------------------------------------------------------------------------* + 関数定義 + *---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------* + Name: ProcessCheckConsole + + Description: + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void ProcessCheckConsole(void) +{ + BOOL isAdapter; + u16 batLevel; + + sRunning = CheckConsole(); + + switch (sRunning) + { + case IS_TWL_DEBUGGER: + kamiFontPrintfConsole( FONT_COLOR_GREEN, "Running on IS_TWL_DEBUGGER.\n"); + break; + case IS_TWL_CAPTURE: + kamiFontPrintfConsole( FONT_COLOR_GREEN, "Running on IS_TWL_CAPTURE.\n"); + break; + case TWL: + kamiFontPrintfConsole( FONT_COLOR_GREEN, "Running on TWL CONSOLE.\n"); + break; + case UNKNOWN: + kamiFontPrintfConsole( FONT_COLOR_GREEN, "Running on UNKNOWN.\n"); + break; + } +/* +#ifdef SYSM_BUILD_FOR_DEBUGGER + // デバッガ向けSystemUpdaterは実機とキャプチャでは動作させない + if (sRunning != IS_TWL_DEBUGGER) + { + ProcessCancel((const char *) + L" Sorry,\n" + L" This SystemUpdater can not\n" + L" execute on TWL-CONSOLE. " + ); + } +#else + // 実機向けSystemUpdaterはデバッガでは動作させない + if (sRunning == IS_TWL_DEBUGGER) + { + ProcessCancel((const char *) + L" Sorry,\n" + L" This SystemUpdater can not\n" + L" execute on IS-TWL-DEBUGGER. " + ); + } +#endif // SYSM_BUILD_FOR_DEBUGGER +*/ + // UNKNOWNは動作させない + if (sRunning == UNKNOWN) + { + ProcessCancel((const char *) + L" Sorry,\n" + L" This SystemUpdater can not\n" + L" execute on UNKNOWN CONSOLE. " + ); + } + + // 電池残量が少なければ動作させない + while (PM_GetBatteryLevel( &batLevel ) != PM_RESULT_SUCCESS) + { + OS_Sleep(1); + } + while (PM_GetACAdapter( &isAdapter ) != PM_RESULT_SUCCESS) + { + OS_Sleep(1); + } + if (((batLevel <= 2) && ! isAdapter) || + (batLevel <= 1)) + { + ProcessCancel((const char *) + L" Sorry,\n" + L" This SystemUpdater can not\n" + L" execute if battery is low. " + ); + } + + kamiFontLoadScreenData(); +} + +/*---------------------------------------------------------------------------* + Name: CheckConsole + + Description: + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +static RunningConsole CheckConsole(void) +{ + u32 console = OS_GetRunningConsoleType(); + RunningConsole running = UNKNOWN; + + // SystemUpdaterはデバッグ不可で作成されるためOS_CONSOLE_TWLが取得される + // 赤箱にカードを挿してSystemUpdaterを実行した場合も同様(但しOS_CONSOLE_TWLTYPE_RETAILにはならない) + // デバッガかどうかの判定はメモリサイズチェックにより行う + // 念のためOS_CONSOLE_TWLTYPE_RETAILでないことも確認する + + if ((console & OS_CONSOLE_SIZE_MASK) == OS_CONSOLE_SIZE_32MB) + { + if ((console & OS_CONSOLE_TWLTYPE_MASK) != OS_CONSOLE_TWLTYPE_RETAIL) + { + IsToolType type; + kamiGetIsToolType(&type); + if (type == IS_TOOL_TYPE_DEBUGGER) + { + running = IS_TWL_DEBUGGER; + } + else if (type == IS_TOOL_TYPE_ERROR) // TSボードプラス + 旧仕様デバッガ + { + running = IS_TWL_DEBUGGER; + } + else if (type == IS_TOOL_TYPE_CAPTURE) + { + running = IS_TWL_CAPTURE; + } + } + } + else if ((console & OS_CONSOLE_MASK) == OS_CONSOLE_TWL) + { + IsToolType type; + kamiGetIsToolType(&type); + if (type == IS_TOOL_TYPE_CAPTURE) + { + running = IS_TWL_CAPTURE; + } + else + { + running = TWL; + } + } + + return running; +} + +/*---------------------------------------------------------------------------* + Name: GetConsole + + Description: + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +RunningConsole GetConsole(void) +{ + return sRunning; +} diff --git a/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/process_check_log.c b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/process_check_log.c new file mode 100644 index 00000000..ab81d100 --- /dev/null +++ b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/process_check_log.c @@ -0,0 +1,136 @@ +/*---------------------------------------------------------------------------* + Project: SystemUpdater + File: process_check_log.c + + Copyright 2008 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + $Date:: $ + $Rev$ + $Author$ + *---------------------------------------------------------------------------*/ + +#include // atoi +#include +#include "font.h" +#include "graphics.h" +#include "keypad.h" +#include "debugger_hw_reset_control.h" +#include "debugger_card_rom.h" +#include "kami_global.h" + +/*---------------------------------------------------------------------------* + 型定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + グローバル変数定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + 内部定数定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + 内部変数定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + 内部関数定義 + *---------------------------------------------------------------------------*/ +static void DrawAlready(SystemUpdaterLog* log); + +/*---------------------------------------------------------------------------* + Name: ProcessCheckLog + + Description: + + Arguments: なし。 + + Returns: なし。 + *---------------------------------------------------------------------------*/ +void ProcessCheckLog(void) +{ + // (更新可能条件) + // 1.ログが存在しない + // 2.ログが存在し、ログに記載のマジックコードが不正(初版SystemUpdater実行後の状態) + // 2.ログが存在し、ログに記載のマジックコードが正しくかつログに記載の + // SDK & IPL のバージョンが SystemUpdater のそれ以下である + +#ifdef IGNORE_VERSION_CHECK + if( 0 ) +#endif // IGNORE_VERSION_CHECK + { + SystemUpdaterLog log; + FSFile file; + FS_InitFile( &file ); + + if (FS_OpenFileEx(&file, SYSTEM_UPDATER_LOG_PATH, FS_FILEMODE_R) == TRUE) + { + DC_InvalidateRange(&log, sizeof(log)); + + if (FS_ReadFile(&file, &log, sizeof(log)) == sizeof(log)) + { + // ログリード成功 + OS_Printf("[%d, %d]\n", log.sdk_version, log.ipl_version); + + // 初版SystemUpdater実行状態でないことをマジックコードで判別する + if (log.magic_code == SYSTEM_UPDATER_MAGIC_CODE) + { + // マジックコード、SDKバージョン、IPLバージョンの確認 + if (log.sdk_version > atoi(g_strSDKSvnRevision) || + log.ipl_version > atoi(g_strIPLSvnRevision)) + { + // 更新不可 + DrawAlready(&log); + } + } + } + else + { + // ログリード失敗 + OS_Warning("Failure! FS_ReadFile"); + } + + FS_CloseFile(&file); + } + } +} + +/*---------------------------------------------------------------------------* + Name: DrawAlready + + Description: Alreadyを表示します + + Arguments: + + Returns: None. + *---------------------------------------------------------------------------*/ +static void DrawAlready(SystemUpdaterLog* log) +{ + char string1[256]; + u16 string2[256]; + + MI_CpuClear8(string1, sizeof(string1)); + MI_CpuClear8(string2, sizeof(string2)); + + // 既にアップデート済み + CARD_LockRom((u16)gLockId); + (void)CARDi_ReadRomIDCoreEx(DEBUGGER_COMMAND_ALREADY); + CARD_UnlockRom((u16)gLockId); + + STD_TSPrintf(string1, "This machine has already\nbeen updated.\n\n ver: %d %d", log->sdk_version, log->ipl_version); + STD_ConvertStringSjisToUnicode(string2, NULL, string1, NULL, NULL); + + NNS_G2dTextCanvasDrawText(&gTextCanvas, 48, 58, + TXT_COLOR_WHITE_BASE, TXT_DRAWTEXT_FLAG_DEFAULT, (const char *)string2); + + while(1) + { + } +} diff --git a/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/process_finish.c b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/process_finish.c new file mode 100644 index 00000000..e7ee0b33 --- /dev/null +++ b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/process_finish.c @@ -0,0 +1,104 @@ +/*---------------------------------------------------------------------------* + Project: SystemUpdater + File: process_finish.c + + Copyright 2008 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + $Date:: $ + $Rev$ + $Author$ + *---------------------------------------------------------------------------*/ + +#include +#include "font.h" +#include "graphics.h" +#include "keypad.h" +#include "debugger_hw_reset_control.h" +#include "debugger_card_rom.h" +#include "kami_global.h" + +/*---------------------------------------------------------------------------* + 型定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + グローバル変数定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + 内部定数定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + 内部変数定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + 内部関数定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + Name: ProcessNote + + Description: + + Arguments: なし。 + + Returns: なし。 + *---------------------------------------------------------------------------*/ +void ProcessFinish(BOOL result) +{ + // TWLの更新処理が完了しました + CARD_LockRom((u16)gLockId); + (void)CARDi_ReadRomIDCoreEx(DEBUGGER_COMMAND_FINISHED); + CARD_UnlockRom((u16)gLockId); + + OS_WaitVBlankIntr(); + NNS_G2dCharCanvasClearArea(&gCanvas, TXT_COLOR_WHITE, 0, 30, 256, 100); + OS_WaitVBlankIntr(); + NNS_G2dCharCanvasClearArea(&gCanvas2, TXT_COLOR_BLACK, 0, 130, 256, 62); + OS_WaitVBlankIntr(); + + if (result) + { + UpdateFreePltt(GX_RGB(0, 21, 0)); + NNS_G2dTextCanvasDrawText(&gTextCanvas, 78, 72, + TXT_COLOR_FREE_BASE, TXT_DRAWTEXT_FLAG_DEFAULT, (const char*) + L"Update Success!"); + } + else + { + UpdateFreePltt(GX_RGB(31, 0, 0)); + NNS_G2dTextCanvasDrawText(&gTextCanvas, 78, 72, + TXT_COLOR_FREE_BASE, TXT_DRAWTEXT_FLAG_DEFAULT, (const char*) + L"Update Failure!"); + } + + while(1) + { + if (result) + { + DrawQuad( 0, 30, 256, 131, GX_RGB(0, 21, 0)); + } + else + { + DrawQuad( 0, 30, 256, 131, GX_RGB(31, 0, 0)); + } + + G3_SwapBuffers(GX_SORTMODE_AUTO, GX_BUFFERMODE_W); + OS_WaitVBlankIntr(); + + G3X_Reset(); + G3_Identity(); + G3_PolygonAttr(GX_LIGHTMASK_NONE, GX_POLYGONMODE_DECAL, GX_CULL_NONE, 0, 31, 0); + + FadeInTick(); + } +} + diff --git a/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/process_format.c b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/process_format.c new file mode 100644 index 00000000..b55caef8 --- /dev/null +++ b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/process_format.c @@ -0,0 +1,124 @@ +/*---------------------------------------------------------------------------* + Project: SystemUpdater + File: process_format.c + + Copyright 2008 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + $Date:: $ + $Rev$ + $Author$ + *---------------------------------------------------------------------------*/ + +#include // atoi +#include +#include +#include "font.h" +#include "graphics.h" +#include "keypad.h" +#include "debugger_hw_reset_control.h" +#include "debugger_card_rom.h" +#include "kami_global.h" +#include "kami_pxi.h" +#include "kami_font.h" + +/*---------------------------------------------------------------------------* + 型定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + グローバル変数定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + 内部定数定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + 内部変数定義 + *---------------------------------------------------------------------------*/ +static vu8 sIsFormatFinish; +static u8 sFormatResult; + +/*---------------------------------------------------------------------------* + 内部関数定義 + *---------------------------------------------------------------------------*/ +static void FormatCallback(KAMIResult result, void* arg); + +/*---------------------------------------------------------------------------* + Name: ProcessFormat + + Description: + + Arguments: なし。 + + Returns: なし。 + *---------------------------------------------------------------------------*/ +BOOL ProcessFormat(void) +{ + NNS_G2dCharCanvasClear(&gCanvas, TXT_COLOR_BLACK); + NNS_G2dCharCanvasClearArea(&gCanvas, TXT_COLOR_WHITE, 0, 30, 256, 100); + + NNS_G2dTextCanvasDrawText(&gTextCanvas, 40, 60, + TXT_COLOR_WHITE_BASE, TXT_DRAWTEXT_FLAG_DEFAULT, "Now Format"); + + // フォーマット実行 + sIsFormatFinish = FALSE; + ExeFormatAsync(FORMAT_MODE_QUICK, FormatCallback); + + while(1) + { + G3X_Reset(); + G3_Identity(); + G3_PolygonAttr(GX_LIGHTMASK_NONE, GX_POLYGONMODE_DECAL, GX_CULL_NONE, 0, 31, 0); + G3_SwapBuffers(GX_SORTMODE_AUTO, GX_BUFFERMODE_W); + OS_WaitVBlankIntr(); + + if (sIsFormatFinish) break; + } + + if (sFormatResult) + { + kamiFontPrintfConsole(FONT_COLOR_GREEN, "NAND Format Success.\n"); + } + else + { + kamiFontPrintfConsole(FONT_COLOR_RED, "NAND Format Failure!\n"); + } + + // フォーマット後はESに必要なファイルがなくなっているため + // ES_InitLibを呼び出すことで作成しておく + NAM_End( NULL, NULL ); + NAM_Init( OS_AllocFromMain, OS_FreeToMain ); + + return sFormatResult; +} + + +/*---------------------------------------------------------------------------* + Name: FormatCallback + + Description: フォーマットコールバック + + Arguments: + + Returns: None. + *---------------------------------------------------------------------------*/ +static void FormatCallback(KAMIResult result, void* /*arg*/) +{ + if ( result == KAMI_RESULT_SUCCESS_TRUE ) + { + sFormatResult = TRUE; + } + else + { + sFormatResult = FALSE; + } + + sIsFormatFinish = TRUE; +} diff --git a/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/process_hwinfo.c b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/process_hwinfo.c new file mode 100644 index 00000000..d5696f18 --- /dev/null +++ b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/process_hwinfo.c @@ -0,0 +1,89 @@ +/*---------------------------------------------------------------------------* + Project: SystemUpdater + File: process_hwinfo.c + + Copyright 2008 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + $Date:: $ + $Rev$ + $Author$ + *---------------------------------------------------------------------------*/ + +#include // atoi +#include +#include +#include "font.h" +#include "graphics.h" +#include "keypad.h" +#include "debugger_hw_reset_control.h" +#include "debugger_card_rom.h" +#include "kami_global.h" +#include "kami_pxi.h" +#include "kami_font.h" +#include "hw_info.h" + +/*---------------------------------------------------------------------------* + 型定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + グローバル変数定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + 内部定数定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + 内部変数定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + 内部関数定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + Name: ProcessHwinfo + + Description: + + Arguments: なし。 + + Returns: なし。 + *---------------------------------------------------------------------------*/ +BOOL ProcessHwinfo(void) +{ + const int MAX_RETRY_COUNT = 2; + BOOL hw_info_result; + int i; + + // 全ハードウェア情報の更新 + for (i=0;i +#include +#include +#include +#include +#include +#include +#include "kami_font.h" +#include "hw_info.h" +#include "TWLHWInfo_api.h" +#include "graphics.h" +#include "kami_global.h" +#include "font.h" + +/*---------------------------------------------------------------------------* + 型定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + 定数定義 + *---------------------------------------------------------------------------*/ + +#define THREAD_STACK_SIZE (16*1024) + +const char* gDirectoryNameRegion[] = +{ + "japan", + "america", + "europe", + "australia" +}; + +const char* gDirectoryNameConsole[] = +{ + "debugger", // IS_TWL_DEBUGGER + "standalone", // IS_TWL_CAPTURE + "standalone", // TWL + "" // UNKNOWN +}; + +/*---------------------------------------------------------------------------* + 内部変数定義 + *---------------------------------------------------------------------------*/ + +static u32 sCurrentProgress; +static vu8 sNowImport = FALSE; +static vu8 sProgress = FALSE; +static u8 sStack[THREAD_STACK_SIZE]; + +/*---------------------------------------------------------------------------* + 内部関数宣言 + *---------------------------------------------------------------------------*/ + +static s32 kamiImportTad(const char* path); +static void ProgressThread(void* arg); +static void Destructor(void* arg); +void ProgressDraw(f32 ratio); + +/*---------------------------------------------------------------------------* + 処理関数定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + Name: ProcessImport + + Description: + + Arguments: なし。 + + Returns: なし。 + *---------------------------------------------------------------------------*/ +BOOL ProcessImport(void) +{ + FSFile dir; + FSDirectoryEntryInfo info[1]; + const s32 MAX_RETRY_COUNT = 2; + BOOL result = TRUE; + char full_path[FS_ENTRY_LONGNAME_MAX+6]; + s32 i=0; + s32 j=0; + + OS_WaitVBlankIntr(); + NNS_G2dCharCanvasClearArea(&gCanvas, TXT_COLOR_WHITE, 0, 30, 256, 100); + OS_WaitVBlankIntr(); + NNS_G2dCharCanvasClearArea(&gCanvas2, TXT_COLOR_BLACK, 0, 130, 256, 62); + OS_WaitVBlankIntr(); + + while(!FadeInTick()) + { + G3X_Reset(); + G3_Identity(); + G3_PolygonAttr(GX_LIGHTMASK_NONE, GX_POLYGONMODE_DECAL, GX_CULL_NONE, 0, 31, 0); + G3_SwapBuffers(GX_SORTMODE_AUTO, GX_BUFFERMODE_W); + OS_WaitVBlankIntr(); + } + + // 適切なディレクトリを開く + STD_TSNPrintf(full_path, sizeof(full_path), "rom:/data/%s/%s/", gDirectoryNameConsole[GetConsole()], gDirectoryNameRegion[gRegion]); + + FS_InitFile(&dir); + if (!FS_OpenDirectory(&dir, full_path, FS_FILEMODE_R)) + { + kamiFontPrintfConsole(CONSOLE_RED, "Error FS_OpenDirectory()\n"); + return FALSE; + } + + // tadファイルを検索してインポート + while (FS_ReadDirectory(&dir, info)) + { + s32 nam_result; + char string1[256]; + u16 string2[256]; + + MI_CpuClear8(string2, sizeof(string2)); + + if ((info->attributes & (FS_ATTRIBUTE_DOS_DIRECTORY | FS_ATTRIBUTE_IS_DIRECTORY)) == 0) + { + char* pExtension; + + // 拡張子のチェック + pExtension = STD_SearchCharReverse( info->longname, '.'); + if (pExtension) + { + if (!STD_CompareString( pExtension, ".tad") || !STD_CompareString( pExtension, ".TAD") ) + { + + STD_TSPrintf(string1, "List %d ", ++i); + STD_ConvertStringSjisToUnicode(string2, NULL, string1, NULL, NULL); + + NNS_G2dCharCanvasClearArea(&gCanvas, TXT_COLOR_WHITE, 0, 60, 256, 20); + NNS_G2dTextCanvasDrawText(&gTextCanvas, 40, 60, + TXT_COLOR_WHITE_BASE, TXT_DRAWTEXT_FLAG_DEFAULT, (const char*)L"Now Import.."); + NNS_G2dTextCanvasDrawText(&gTextCanvas, 135, 60, + TXT_COLOR_WHITE_BASE, TXT_DRAWTEXT_FLAG_DEFAULT, (const char*)string2); + + STD_TSNPrintf(full_path, sizeof(full_path), "rom:/data/%s/%s/%s", gDirectoryNameConsole[GetConsole()], gDirectoryNameRegion[gRegion], info->longname); +// kamiFontPrintfConsole(CONSOLE_GREEN, " %s\n", full_path); + + // MAX_RETRY_COUNTまでリトライする + for (j=0; jpriority - 1); + OS_WakeupThreadDirect(&thread); + + // Import開始 + nam_result = NAM_ImportTad( path ); + + // インポート開始フラグを下げる + sNowImport = FALSE; + + // 進捗スレッドの自力終了を待つ + while (sProgress){}; + + // きちんと表示する + G3_SwapBuffers(GX_SORTMODE_AUTO, GX_BUFFERMODE_W); + OS_WaitVBlankIntr(); + + // InstalledSoftBoxCount, FreeSoftBoxCount の値を現在のNANDの状態に合わせて更新します。 + (void)NAMUT_UpdateSoftBoxCount(); + + return nam_result; +} + +/*---------------------------------------------------------------------------* + Name: ProgressThread + + Description: .tad ファイルインポートの進捗を表示するスレッド。 + 進捗が100%に達すると処理を抜ける。 + + Arguments: arg - 使用しない。 + + Returns: None. + *---------------------------------------------------------------------------*/ + +static void ProgressThread(void* /*arg*/) +{ + u32 currentSize; + u32 totalSize = 0; + u32 totalSizeBk = 0; + + sProgress = TRUE; + + while (sNowImport) + { + NAM_GetProgress(¤tSize, &totalSize); + + if ((totalSize > 0 && totalSize == currentSize) || totalSizeBk > totalSize) + { + // 既にインポートが終了 + ProgressDraw((f32)1.0); + break; + } + else if (totalSize > 0) + { + ProgressDraw((f32)currentSize/totalSize); + } + + totalSizeBk = totalSize; + + // Vブランク待ち + G3_SwapBuffers(GX_SORTMODE_AUTO, GX_BUFFERMODE_W); + OS_WaitVBlankIntr(); + + // 3D初期化 + G3X_Reset(); + G3_Identity(); + G3_PolygonAttr(GX_LIGHTMASK_NONE, GX_POLYGONMODE_DECAL, GX_CULL_NONE, 0, 31, 0); + } + + sProgress = FALSE; +} + +/*---------------------------------------------------------------------------* + Name: ProgressDraw + + Description: インポートの進捗を表示します + + Arguments: + + Returns: None. + *---------------------------------------------------------------------------*/ + +void ProgressDraw(f32 ratio) +{ + s16 x = (s16)(30 + (226 - 30)*ratio); + + // グリーンバー + DrawQuadWithColors( 30, 86, x, 95, GX_RGB(22, 31, 22), GX_RGB(12, 25, 12)); + + // グレーバー + DrawQuad( 30, 86, 226, 95, GX_RGB(28, 28, 28)); +} diff --git a/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/process_log.c b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/process_log.c new file mode 100644 index 00000000..6db3f294 --- /dev/null +++ b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/process_log.c @@ -0,0 +1,83 @@ +/*---------------------------------------------------------------------------* + Project: SystemUpdater + File: process_log.c + + Copyright 2008 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + $Date:: $ + $Rev$ + $Author$ + *---------------------------------------------------------------------------*/ + +#include // atoi +#include +#include "font.h" +#include "kami_font.h" +#include "kami_global.h" + +/*---------------------------------------------------------------------------* + 型定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + グローバル変数定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + 内部定数定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + 内部変数定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + 内部関数定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + Name: ProcessLog + + Description: + + Arguments: なし。 + + Returns: なし。 + *---------------------------------------------------------------------------*/ +void ProcessLog(void) +{ + SystemUpdaterLog log; + + (void)FS_DeleteFile(SYSTEM_UPDATER_LOG_PATH); + + if (FS_CreateFileAuto(SYSTEM_UPDATER_LOG_PATH, FS_PERMIT_R | FS_PERMIT_W)) + { + FSFile file; + FS_InitFile( &file ); + if (FS_OpenFileEx(&file, SYSTEM_UPDATER_LOG_PATH, FS_FILEMODE_W)) + { + log.magic_code = SYSTEM_UPDATER_MAGIC_CODE; + log.sdk_version = atoi(g_strSDKSvnRevision); + log.ipl_version = atoi(g_strIPLSvnRevision); + + DC_FlushRange(&log, sizeof(log)); + + if (FS_WriteFile(&file, (void*)&log, sizeof(log) ) == -1) + { + kamiFontPrintfConsole(FONT_COLOR_RED, "Failure : FS_WriteFile\n"); + } + FS_CloseFile(&file); + } + } + else + { + kamiFontPrintfConsole(FONT_COLOR_RED, "Failure : FS_CreateFileAuto\n"); + } +} + diff --git a/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/process_nandfirm.c b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/process_nandfirm.c new file mode 100644 index 00000000..b2382583 --- /dev/null +++ b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/process_nandfirm.c @@ -0,0 +1,124 @@ +/*---------------------------------------------------------------------------* + Project: SystemUpdater + File: process_nandfirm.c + + Copyright 2008 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + $Date:: $ + $Rev$ + $Author$ + *---------------------------------------------------------------------------*/ + +#include // atoi +#include +#include +#include "font.h" +#include "graphics.h" +#include "keypad.h" +#include "debugger_hw_reset_control.h" +#include "debugger_card_rom.h" +#include "kami_global.h" +#include "kami_pxi.h" +#include "kami_font.h" +#include "hw_info.h" +#include "kami_write_nandfirm.h" + +/*---------------------------------------------------------------------------* + 型定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + グローバル変数定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + 内部定数定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + 内部変数定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + 内部関数定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + Name: ProcessNandfirm + + Description: + + Arguments: なし。 + + Returns: なし。 + *---------------------------------------------------------------------------*/ +BOOL ProcessNandfirm(void) +{ + FSFile dir; + FSDirectoryEntryInfo info[1]; + char full_path[FS_ENTRY_LONGNAME_MAX+6]; + const int MAX_RETRY_COUNT = 2; + BOOL result = FALSE; + BOOL find = FALSE; + int i; + + // 適切なディレクトリを開く + STD_TSNPrintf(full_path, sizeof(full_path), "rom:/data/%s/%s/", gDirectoryNameConsole[GetConsole()], gDirectoryNameRegion[gRegion]); + + FS_InitFile(&dir); + if (!FS_OpenDirectory(&dir, full_path, FS_FILEMODE_R)) + { + kamiFontPrintfConsole(CONSOLE_RED, "Error FS_OpenDirectory()\n"); + return FALSE; + } + + // .nandファイルを検索してインポート + while (FS_ReadDirectory(&dir, info)) + { + if ((info->attributes & (FS_ATTRIBUTE_DOS_DIRECTORY | FS_ATTRIBUTE_IS_DIRECTORY)) == 0) + { + char* pExtension; + + // 拡張子のチェック + pExtension = STD_SearchCharReverse( info->longname, '.'); + if (pExtension) + { + if (!STD_CompareString( pExtension, ".nand") || !STD_CompareString( pExtension, ".NAND") ) + { + STD_TSNPrintf(full_path, sizeof(full_path), "rom:/data/%s/%s/%s", gDirectoryNameConsole[GetConsole()], gDirectoryNameRegion[gRegion], info->longname); + find = TRUE; + break; + } + } + } + } + + if (find) + { + for (i=0;i +#include "font.h" +#include "graphics.h" +#include "keypad.h" +#include "debugger_hw_reset_control.h" +#include "debugger_card_rom.h" +#include "kami_global.h" + +/*---------------------------------------------------------------------------* + 型定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + グローバル変数定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + 内部定数定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + 内部変数定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + 内部関数定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + Name: ProcessNote + + Description: + + Arguments: なし。 + + Returns: なし。 + *---------------------------------------------------------------------------*/ +void ProcessNote(void) +{ + OS_WaitVBlankIntr(); + NNS_G2dCharCanvasClearArea(&gCanvas, TXT_COLOR_WHITE, 0, 30, 256, 100); + OS_WaitVBlankIntr(); + NNS_G2dCharCanvasClearArea(&gCanvas2, TXT_COLOR_BLACK, 0, 130, 256, 62); + OS_WaitVBlankIntr(); + +// NNS_G2dTextCanvasDrawText(&gTextCanvas, 20, 40, +// TXT_COLOR_WHITE_BASE, TXT_DRAWTEXT_FLAG_DEFAULT, +// (const char *)L"Please Select System Menu Region." +// ); + + NNS_G2dTextCanvasDrawText(&gTextCanvas2, 60, 140, + TXT_COLOR_BLACK_BASE, TXT_DRAWTEXT_FLAG_DEFAULT, + (const char *) + L"\xe000 ok! start update.\n" + L"\xe001 cancel.\n" + ); +/* + NNS_G2dTextCanvasDrawText(&gTextCanvas, 50, 40, + TXT_COLOR_WHITE_BASE, TXT_DRAWTEXT_FLAG_DEFAULT, (const char*) + L" -- Note --" + ); + + NNS_G2dTextCanvasDrawText(&gTextCanvas, 44, 60, + TXT_COLOR_WHITE_BASE, TXT_DRAWTEXT_FLAG_DEFAULT, (const char*) + L"・All data in nand flash \n" + L" memory will be lost." + ); +*/ + + NNS_G2dTextCanvasDrawText(&gTextCanvas, 80, 50, + TXT_COLOR_FREE_BASE, TXT_DRAWTEXT_FLAG_DEFAULT, (const char*) + sRegionStringArray[gRegion] + ); + + NNS_G2dTextCanvasDrawText(&gTextCanvas, 44, 80, + TXT_COLOR_WHITE_BASE, TXT_DRAWTEXT_FLAG_DEFAULT, (const char*) + L"・Do not shut down while\n" + L" update is processing." + ); + + while(1) + { + G3X_Reset(); + G3_Identity(); + G3_PolygonAttr(GX_LIGHTMASK_NONE, GX_POLYGONMODE_DECAL, GX_CULL_NONE, 0, 31, 0); + + kamiPadRead(); + + if (FadeInTick()) + { + if (kamiPadIsTrigger(PAD_BUTTON_B)) + { + while (!FadeOutTick()) + { + OS_WaitVBlankIntr(); + } + ProcessCancel((const char *)L"\n Update was Canceld."); + } + else if (kamiPadIsTrigger(PAD_BUTTON_A)) + { + while (!FadeOutTick()) + { + OS_WaitVBlankIntr(); + } + NNS_G2dCharCanvasClearArea(&gCanvas2, TXT_COLOR_BLACK, 0, 130, 256, 62); + return; + } + } + DrawQuadWithColors( 0, 50, 128, 62, GX_RGB(31, 31, 31), GX_RGB(22, 28, 31)); + DrawQuadWithColors( 128, 50, 256, 62, GX_RGB(22, 28, 31), GX_RGB(31, 31, 31)); + + G3_SwapBuffers(GX_SORTMODE_AUTO, GX_BUFFERMODE_W); + OS_WaitVBlankIntr(); + } +} diff --git a/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/process_select_region.c b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/process_select_region.c new file mode 100644 index 00000000..e3a76366 --- /dev/null +++ b/build/systemMenu_tools/SystemUpdaterRegionSelect/ARM9.TWL/src/process_select_region.c @@ -0,0 +1,162 @@ +/*---------------------------------------------------------------------------* + Project: SystemUpdater + File: process_select_region.c + + Copyright 2008 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + $Date:: $ + $Rev$ + $Author$ + *---------------------------------------------------------------------------*/ + +#include +#include "font.h" +#include "graphics.h" +#include "keypad.h" +#include "kami_global.h" +#include "debugger_hw_reset_control.h" +#include "debugger_card_rom.h" + +/*---------------------------------------------------------------------------* + 型定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + グローバル変数定義 + *---------------------------------------------------------------------------*/ + +OSTWLRegion gRegion = OS_TWL_REGION_JAPAN; + +/*---------------------------------------------------------------------------* + 内部定数定義 + *---------------------------------------------------------------------------*/ + +static const u16 POS_Y_JAPAN = 52; +static const u16 POS_Y_AMERICA = 66; +static const u16 POS_Y_EUROPE = 80; +static const u16 POS_Y_AUSTRALIA = 94; + +/*---------------------------------------------------------------------------* + 内部変数定義 + *---------------------------------------------------------------------------*/ + +static const u16 sPosArray[4] = +{ + POS_Y_JAPAN, + POS_Y_AMERICA, + POS_Y_EUROPE, + POS_Y_AUSTRALIA +}; + +const u16* sRegionStringArray[4] = +{ + L"region Japan", + L"region America", + L"region Europe", + L"region Australia" +}; + +/*---------------------------------------------------------------------------* + 内部関数定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + Name: ProcessSelectRegion + + Description: + + Arguments: なし。 + + Returns: なし。 + *---------------------------------------------------------------------------*/ +void ProcessSelectRegion(void) +{ + OS_WaitVBlankIntr(); + NNS_G2dCharCanvasClearArea(&gCanvas, TXT_COLOR_WHITE, 0, 30, 256, 100); + OS_WaitVBlankIntr(); + NNS_G2dCharCanvasClearArea(&gCanvas2, TXT_COLOR_BLACK, 0, 130, 256, 62); + OS_WaitVBlankIntr(); + + NNS_G2dTextCanvasDrawText(&gTextCanvas2, 60, 140, + TXT_COLOR_BLACK_BASE, TXT_DRAWTEXT_FLAG_DEFAULT, + (const char *) + L"\xe006 change region.\n" + L"\xe000 choice.\n" + L"\xe001 cancel.\n" + ); + + // 液晶を見てください。 + CARD_LockRom((u16)gLockId); + (void)CARDi_ReadRomIDCoreEx(DEBUGGER_COMMAND_LOOK_SCREEN); + CARD_UnlockRom((u16)gLockId); + + gRegion = OS_GetRegion(); + + while(1) + { + s32 i; + G3X_Reset(); + G3_Identity(); + G3_PolygonAttr(GX_LIGHTMASK_NONE, GX_POLYGONMODE_DECAL, GX_CULL_NONE, 0, 31, 0); + + kamiPadRead(); + + if (FadeInMaster()) + { + if (kamiPadIsRepeatTrigger(PAD_KEY_DOWN)) + { + if (++gRegion > OS_TWL_REGION_AUSTRALIA) + { + gRegion = OS_TWL_REGION_JAPAN; + } + } + else if (kamiPadIsRepeatTrigger(PAD_KEY_UP)) + { + if (--gRegion < OS_TWL_REGION_JAPAN) + { + gRegion = OS_TWL_REGION_AUSTRALIA; + } + } + + if (kamiPadIsTrigger(PAD_BUTTON_B)) + { + ProcessCancel((const char *)L"\n Update was Canceld."); + } + else if (kamiPadIsTrigger(PAD_BUTTON_A)) + { + break; + } + } + + for (i=0;i +#include "font.h" +#include "graphics.h" +#include "keypad.h" +#include "debugger_hw_reset_control.h" +#include "debugger_card_rom.h" +#include "kami_global.h" +#include "kami_copy_file.h" +#include "kami_font.h" + +/*---------------------------------------------------------------------------* + 型定義 + *---------------------------------------------------------------------------*/ + +typedef struct _CopyFileList +{ + char* srcPath; + char* dstPath; +} CopyFileList; + +/*---------------------------------------------------------------------------* + グローバル変数定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + 内部定数定義 + *---------------------------------------------------------------------------*/ +/* +static const CopyFileList sCopyFileList[] = +{ + { "rom:/data/TWLFontTable.dat", "nand:sys/TWLFontTable.dat" }, + { "rom:/data/cert.sys", "nand:/sys/cert.sys" } +}; +*/ +/*---------------------------------------------------------------------------* + 内部変数定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + 内部関数定義 + *---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------* + Name: ProcessWriteFiles + + Description: + + Arguments: なし。 + + Returns: なし。 + *---------------------------------------------------------------------------*/ +BOOL ProcessWriteFiles(void) +{ + FSFile dir; + FSDirectoryEntryInfo info[1]; + char full_path[FS_ENTRY_LONGNAME_MAX+6]; + BOOL find = FALSE; + BOOL result = TRUE; + +/* + OS_WaitVBlankIntr(); + NNS_G2dCharCanvasClearArea(&gCanvas, TXT_COLOR_WHITE, 0, 30, 256, 100); + OS_WaitVBlankIntr(); + NNS_G2dCharCanvasClearArea(&gCanvas2, TXT_COLOR_BLACK, 0, 130, 256, 62); + OS_WaitVBlankIntr(); + + NNS_G2dTextCanvasDrawText(&gTextCanvas, 84, 60, + TXT_COLOR_WHITE_BASE, TXT_DRAWTEXT_FLAG_DEFAULT, (const char*) + L"Write Files.." + ); +*/ + + // 適切なディレクトリを開く + STD_TSNPrintf(full_path, sizeof(full_path), "rom:/data/%s/%s/", gDirectoryNameConsole[GetConsole()], gDirectoryNameRegion[gRegion]); + + FS_InitFile(&dir); + if (!FS_OpenDirectory(&dir, full_path, FS_FILEMODE_R)) + { + kamiFontPrintfConsole(CONSOLE_RED, "Error FS_OpenDirectory()\n"); + return FALSE; + } + + // .datファイルを検索 + while (FS_ReadDirectory(&dir, info)) + { + if ((info->attributes & (FS_ATTRIBUTE_DOS_DIRECTORY | FS_ATTRIBUTE_IS_DIRECTORY)) == 0) + { + char* pExtension; + + // 拡張子のチェック + pExtension = STD_SearchCharReverse( info->longname, '.'); + if (pExtension) + { + if (!STD_CompareString( pExtension, ".dat") || !STD_CompareString( pExtension, ".DAT") ) + { + STD_TSNPrintf(full_path, sizeof(full_path), "rom:/data/%s/%s/%s", gDirectoryNameConsole[GetConsole()], gDirectoryNameRegion[gRegion], info->longname); + find = TRUE; + break; + } + } + } + } + + if (find) + { + if (kamiCopyFile(full_path, "nand:sys/TWLFontTable.dat")) + { + kamiFontPrintfConsole(FONT_COLOR_GREEN, "Write Font Data Success.\n"); + } + else + { + result = FALSE; + kamiFontPrintfConsole(FONT_COLOR_RED, "Write Font Data Failure!\n"); + } + } + + return result; +} + diff --git a/build/systemMenu_tools/SystemUpdaterRegionSelect/Makefile b/build/systemMenu_tools/SystemUpdaterRegionSelect/Makefile new file mode 100644 index 00000000..589dbbb3 --- /dev/null +++ b/build/systemMenu_tools/SystemUpdaterRegionSelect/Makefile @@ -0,0 +1,33 @@ +#! make -f +#---------------------------------------------------------------------------- +# Project: SystemUpdater +# File: Makefile +# +# Copyright 2007 Nintendo. All rights reserved. +# +# These coded instructions, statements, and computer programs contain +# proprietary information of Nintendo of America Inc. and/or Nintendo +# Company Ltd., and are protected by Federal copyright law. They may +# not be disclosed to third parties or copied or duplicated in any form, +# in whole or in part, without the prior written consent of Nintendo. +# +# $Date:: $ +# $Rev$ +# $Author$ +#---------------------------------------------------------------------------- + +TARGET_FIRM = SYSTEMMENU + +include $(TWL_IPL_RED_ROOT)/build/buildtools/commondefs + +#---------------------------------------------------------------------------- + +SUBDIRS = banner \ + ARM7.TWL \ + ARM9.TWL + +#---------------------------------------------------------------------------- + +include $(TWL_IPL_RED_ROOT)/build/buildtools/modulerules + +#===== End of Makefile ===== diff --git a/build/systemMenu_tools/SystemUpdaterRegionSelect/banner/Makefile b/build/systemMenu_tools/SystemUpdaterRegionSelect/banner/Makefile new file mode 100644 index 00000000..e373c033 --- /dev/null +++ b/build/systemMenu_tools/SystemUpdaterRegionSelect/banner/Makefile @@ -0,0 +1,47 @@ +#! make -f +#---------------------------------------------------------------------------- +# Project: TwlIPL +# File: Makefile +# +# Copyright 2007 Nintendo. All rights reserved. +# +# These coded instructions, statements, and computer programs contain +# proprietary information of Nintendo of America Inc. and/or Nintendo +# Company Ltd., and are protected by Federal copyright law. They may +# not be disclosed to third parties or copied or duplicated in any form, +# in whole or in part, without the prior written consent of Nintendo. +# +# $Date:: $ +# $Rev$ +# $Author$ +#---------------------------------------------------------------------------- + +include $(TWL_IPL_RED_ROOT)/build/buildtools/commondefs + +ICON_DIR = ./icon + +BANNER_ICON = $(ICON_DIR)/gameIcon.bmp +BANNER_SPEC = banner_v3.bsf + +TARGETS = banner.bnr +INSTALL_DIR = ./ +INSTALL_TARGETS = $(TARGETS) + +BANNER_ICON_NAME = $(basename $(BANNER_ICON)) +BANNER_ICON_MIDDLE = $(addprefix $(BANNER_ICON_NAME), .nbfs .nbfc .nbfp) + +LDIRT_CLEAN = $(TARGETS) \ + $(BANNER_ICON_MIDDLE) \ + $(TARGETS:.bnr=.srl) + +include $(TWL_IPL_RED_ROOT)/build/buildtools/modulerules + +#---------------------------------------------------------------------------- +# build +#---------------------------------------------------------------------------- +do-build: $(TARGETS) + +$(TARGETS): $(BANNER_SPEC) $(BANNER_ICON) $(BANNER_ICON_MIDDLE) + $(MAKEBANNER) -N $(BANNER_ICON_NAME) $(BANNER_SPEC) $(TARGETS) + +# diff --git a/build/systemMenu_tools/SystemUpdaterRegionSelect/banner/banner_v3.bsf b/build/systemMenu_tools/SystemUpdaterRegionSelect/banner/banner_v3.bsf new file mode 100644 index 0000000000000000000000000000000000000000..d1c485801c9aba3a93da770066c8f21e77c6a1f3 GIT binary patch literal 852 zcmc(dPiq1(5XIlMg5M$F*-9z&&|}3_i%98O@9VD81^+C&tI{vu`kO@WIaLB7GxIWe zZ}R?rdwNrHUD4sr|Loyir-i;@(!gkQW#qKe zkxWZ&1w*GZ+)Lt?Xir@FJ?Cadr6FtBFM1^?dD4q!8r@ZysawL!*p)iK_Z5cEo|Dzy z^+D!=|M>Ar*Jw5cl?pVO&e~%~nn&RheMaHN%q8aCDYJ~hrI9*@kvb-kxZs|fhgzm( vE^lyjm|np&SIpMo5%W!jngQ#~U(}!qJ%Zd)$#mj}%xxLDoca!&bqw7vygzmU literal 0 HcmV?d00001 diff --git a/build/systemMenu_tools/SystemUpdaterRegionSelect/banner/icon/gameIcon.bmp b/build/systemMenu_tools/SystemUpdaterRegionSelect/banner/icon/gameIcon.bmp new file mode 100644 index 0000000000000000000000000000000000000000..7bba61036fe91c0e06697a5beecef5ddd405a6c2 GIT binary patch literal 592 zcmb`EK?=e!5Jkr#-ME^r1vOA`<0afHQkXk<5KrQXJc(C`e}0 + +/*---------------------------------------------------------------------------* + 定数定義 + *---------------------------------------------------------------------------*/ +#define PXI_FIFO_TAG_KAMITEST PXI_FIFO_TAG_USER_1 + +#define KAMI_PXI_CONTINUOUS_PACKET_MAX 10 +#define KAMITEST_PXI_DATA_SIZE_MAX ((KAMI_PXI_CONTINUOUS_PACKET_MAX-1)*3+1) // 最大データ数 + +#define KAMITEST_PXI_START_BIT 0x02000000 // 先頭パケットを意味する +#define KAMITEST_PXI_RESULT_BIT 0x00008000 // PXIの応答を示す + +#define KAMITEST_PXI_COMMAND_SHIFT 8 // コマンド格納部分の位置 +#define KAMITEST_PXI_COMMAND_MASK 0x00007f00 // コマンド格納部分のマスク +#define KAMITEST_PXI_DATA_NUMS_MASK 0x00ff0000 // データ数領域 +#define KAMITEST_PXI_DATA_NUMS_SHIFT 16 // データ数位置 +#define KAMITEST_PXI_1ST_DATA_MASK 0x000000ff // 先頭パケットのデータ領域 +#define KAMITEST_PXI_1ST_DATA_SHIFT 0 // 先頭パケットのデータ位置 + +#ifdef __cplusplus +extern "C" { +#endif + +/*===========================================================================*/ + +typedef enum KAMIPxiResult +{ + KAMI_PXI_RESULT_SUCCESS = 0, // 処理成功 (void/void*型) // 場合により後続パケットあり + KAMI_PXI_RESULT_SUCCESS_TRUE = 0, // 処理成功 (BOOL型) + KAMI_PXI_RESULT_SUCCESS_FALSE, // 処理成功 (BOOL型) + KAMI_PXI_RESULT_INVALID_COMMAND, // 不正なPXIコマンド + KAMI_PXI_RESULT_INVALID_PARAMETER, // 不正なパラメータ + KAMI_PXI_RESULT_ILLEGAL_STATUS, // KAMIの状態により処理を実行不可 + KAMI_PXI_RESULT_BUSY, // 他のリクエストを実行中 + KAMI_PXI_RESULT_FATAL_ERROR, // その他何らかの原因で処理に失敗 + KAMI_PXI_RESULT_MAX +} +KAMIPxiResult; + + +typedef enum KamiCommand +{ + KAMI_TEST_COMMAND, + KAMI_EXE_FORMAT, + KAMI_NAND_IO, + KAMI_CLEAR_NAND_ERRORLOG, + KAMI_GET_IS_TOOL_TYPE +} +KamiCommand; + +typedef enum _IsToolType +{ + IS_TOOL_TYPE_ERROR, + IS_TOOL_TYPE_DEBUGGER, + IS_TOOL_TYPE_CAPTURE +} +IsToolType; + +/*===========================================================================*/ + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* TWL_KAMI_TEST_FIFO_H_ */ + +/*---------------------------------------------------------------------------* + End of file + *---------------------------------------------------------------------------*/ diff --git a/build/systemMenu_tools/SystemUpdaterRegionSelect/data/tbf_ww_s.NFTR b/build/systemMenu_tools/SystemUpdaterRegionSelect/data/tbf_ww_s.NFTR new file mode 100644 index 0000000000000000000000000000000000000000..f4054938340b6e2728ebf7dec389b9d95427a50e GIT binary patch literal 270572 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 literal 0 HcmV?d00001 diff --git a/build/systemMenu_tools/SystemUpdaterRegionSelect/readme.txt b/build/systemMenu_tools/SystemUpdaterRegionSelect/readme.txt new file mode 100644 index 00000000..d03e2d5b --- /dev/null +++ b/build/systemMenu_tools/SystemUpdaterRegionSelect/readme.txt @@ -0,0 +1,20 @@ +以下のディレクトリ構成でsystemMenuを用意して +ARM9/Makefileの UPDATER_HOST_ROOT_DIR変数で指定してください。 + +xxxxx + +debugger + l +america/* + l +australia/* + l +europe/* + l +japan/* + l + +standalone + +america/* + +australia/* + +europe/* + +japan/* + + +上記の*には、 +全tadとnandファームとフォントデータを置いてください。 +